diff --git a/.gitignore b/.gitignore index baccec46..b8462550 100644 --- a/.gitignore +++ b/.gitignore @@ -39,8 +39,7 @@ JLink*.* html/ latex/ -cert-pack/ -cert-latex/ +doxygen/gen/ test_priv/ dbg/ rel/ diff --git a/3rd_party b/3rd_party index fa069699..de077b86 160000 --- a/3rd_party +++ b/3rd_party @@ -1 +1 @@ -Subproject commit fa06969955bfa96cbdb5b9ff8b05b66f49fad890 +Subproject commit de077b869b8980d124d9df3e5f7327500e28f178 diff --git a/LICENSES/LicenseRef-QL-dual.qlc b/LICENSES/LicenseRef-QL-dual.qlc index a5df1c2b..06ced4a5 100644 --- a/LICENSES/LicenseRef-QL-dual.qlc +++ b/LICENSES/LicenseRef-QL-dual.qlc @@ -1,9 +1,13 @@ Any user of the QP/C real-time embedded framework qpc -2023-12-31 +2024-12-31 Copyright (C) 2005 Quantum Leaps, LLC . + Q u a n t u m L e a P s + ------------------------ + Modern Embedded Software + SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial This software is dual-licensed under the terms of the open source GNU @@ -23,4 +27,4 @@ Plagiarizing this software to sidestep the license obligations is illegal. Contact information: -#F04C7A28E6F84BAFDD11A028A9B7CFE2F4DE1FD7 \ No newline at end of file +#5B2B82CE252E0FB7975E7196F9141A16DD356860 \ No newline at end of file diff --git a/README.md b/README.md index 77d41603..586144c4 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,9 @@ -![QP Framework](doxygen/images/qp_banner.jpg) +![QP Framework](https://www.state-machine.com/img/qp_banner.jpg) # What's New? + +[![GitHub release (latest by date)](https://img.shields.io/github/v/release/QuantumLeaps/qpc)](https://github.com/QuantumLeaps/qpc/releases/latest) + View QP/C Revision History at: https://www.state-machine.com/qpc/history.html > **NOTE:** If you're interested in the latest QP/C version from GitHub, @@ -121,7 +124,7 @@ open the file [html/index.html](html/index.html) in your web browser. # How to Help this Project? If you like this project, please give it a star (in the upper-right corner of your browser window): -![GitHub star](doxygen/images/github-star.jpg) +![GitHub star](https://www.state-machine.com/img/github-star.jpg) [RTEF]: diff --git a/doxygen/Doxyfile b/doxygen/Doxyfile deleted file mode 100644 index 536735bf..00000000 --- a/doxygen/Doxyfile +++ /dev/null @@ -1,309 +0,0 @@ -# Doxyfile 1.9.5 - -@INCLUDE = ../../ql-doxygen/ql-doxyfile - -#--------------------------------------------------------------------------- -# Project related configuration options -#--------------------------------------------------------------------------- -DOXYFILE_ENCODING = UTF-8 -PROJECT_NAME = QP/C -PROJECT_NUMBER = 7.2.1 -PROJECT_BRIEF = "Real-Time Embedded Framework" -PROJECT_LOGO = ../../ql-doxygen/images/logo_ql.png -OUTPUT_DIRECTORY = -CREATE_SUBDIRS = NO -CREATE_SUBDIRS_LEVEL = 6 -ALLOW_UNICODE_NAMES = NO -OUTPUT_LANGUAGE = English -BRIEF_MEMBER_DESC = YES -REPEAT_BRIEF = NO -ABBREVIATE_BRIEF = "The $name class" \ - "The $name widget" \ - "The $name file" \ - is \ - provides \ - specifies \ - contains \ - represents \ - a \ - an \ - the -ALWAYS_DETAILED_SEC = NO -INLINE_INHERITED_MEMB = NO -FULL_PATH_NAMES = NO -STRIP_FROM_PATH = -STRIP_FROM_INC_PATH = -SHORT_NAMES = NO -JAVADOC_AUTOBRIEF = YES -JAVADOC_BANNER = NO -QT_AUTOBRIEF = NO -MULTILINE_CPP_IS_BRIEF = NO -PYTHON_DOCSTRING = YES -INHERIT_DOCS = YES -SEPARATE_MEMBER_PAGES = NO -TAB_SIZE = 4 -OPTIMIZE_OUTPUT_FOR_C = NO -OPTIMIZE_OUTPUT_JAVA = NO -OPTIMIZE_FOR_FORTRAN = NO -OPTIMIZE_OUTPUT_VHDL = NO -OPTIMIZE_OUTPUT_SLICE = NO -EXTENSION_MAPPING = lnt=Objective-C -MARKDOWN_SUPPORT = YES -TOC_INCLUDE_HEADINGS = 4 -AUTOLINK_SUPPORT = YES -BUILTIN_STL_SUPPORT = NO -CPP_CLI_SUPPORT = NO -SIP_SUPPORT = NO -IDL_PROPERTY_SUPPORT = YES -DISTRIBUTE_GROUP_DOC = NO -GROUP_NESTED_COMPOUNDS = NO -SUBGROUPING = YES -INLINE_GROUPED_CLASSES = YES -INLINE_SIMPLE_STRUCTS = YES -TYPEDEF_HIDES_STRUCT = YES -LOOKUP_CACHE_SIZE = 0 -NUM_PROC_THREADS = 1 -#--------------------------------------------------------------------------- -# Build related configuration options -#--------------------------------------------------------------------------- -EXTRACT_ALL = YES -EXTRACT_PRIVATE = YES -EXTRACT_PRIV_VIRTUAL = NO -EXTRACT_PACKAGE = YES -EXTRACT_STATIC = YES -EXTRACT_LOCAL_CLASSES = YES -EXTRACT_LOCAL_METHODS = NO -EXTRACT_ANON_NSPACES = NO -RESOLVE_UNNAMED_PARAMS = YES -HIDE_UNDOC_MEMBERS = NO -HIDE_UNDOC_CLASSES = NO -HIDE_FRIEND_COMPOUNDS = NO -HIDE_IN_BODY_DOCS = NO -INTERNAL_DOCS = NO -CASE_SENSE_NAMES = NO -HIDE_SCOPE_NAMES = YES -HIDE_COMPOUND_REFERENCE= NO -SHOW_HEADERFILE = YES -SHOW_INCLUDE_FILES = YES -SHOW_GROUPED_MEMB_INC = NO -FORCE_LOCAL_INCLUDES = NO -INLINE_INFO = YES -SORT_MEMBER_DOCS = NO -SORT_BRIEF_DOCS = NO -SORT_MEMBERS_CTORS_1ST = NO -SORT_GROUP_NAMES = NO -SORT_BY_SCOPE_NAME = NO -STRICT_PROTO_MATCHING = NO -GENERATE_TODOLIST = YES -GENERATE_TESTLIST = YES -GENERATE_BUGLIST = YES -GENERATE_DEPRECATEDLIST= YES -ENABLED_SECTIONS = QPC -MAX_INITIALIZER_LINES = 30 -SHOW_USED_FILES = YES -SHOW_FILES = YES -SHOW_NAMESPACES = YES -FILE_VERSION_FILTER = -LAYOUT_FILE = -CITE_BIB_FILES = -#--------------------------------------------------------------------------- -# Configuration options related to warning and progress messages -#--------------------------------------------------------------------------- -QUIET = NO -WARNINGS = YES -WARN_IF_UNDOCUMENTED = YES -WARN_IF_DOC_ERROR = YES -WARN_IF_INCOMPLETE_DOC = YES -WARN_NO_PARAMDOC = NO -WARN_AS_ERROR = NO -WARN_FORMAT = "$file:$line: $text" -WARN_LINE_FORMAT = "at line $line of file $file" -WARN_LOGFILE = -#--------------------------------------------------------------------------- -# Configuration options related to the input files -#--------------------------------------------------------------------------- -INPUT = main.dox \ - gs.dox \ - ../../cert-pack/cert-pack.dox \ - ../../cert-pack/srs.dox \ - ../../cert-pack/sas.dox \ - ../../cert-pack/sds.dox \ - ../../cert-pack/sds_sm-c.dox \ - ../../cert-pack/misra.dox \ - ../../cert-pack/metrics.dox \ - history.dox \ - exa.dox \ - exa_native.dox \ - exa_rtos.dox \ - exa_os.dox \ - exa_qutest.dox \ - exa_mware.dox \ - ports.dox \ - ports_native.dox \ - ports_arm-cm.dox \ - ports_rtos.dox \ - ports_os.dox \ - api.dox \ - ../../ql-doxygen/help.dox \ - dir.dox \ - config.h \ - ../include \ - ../src \ - ../ports/sample \ - ../ports/lint-plus/std.lnt \ - ../ports/lint-plus/qpc.lnt \ - ../ports/lint-plus/options.lnt -INPUT_ENCODING = UTF-8 -INPUT_FILE_ENCODING = -FILE_PATTERNS = *.dox \ - *.h \ - *.hpp \ - *.c \ - *.cpp \ - *.s \ - *.asm \ - *.lnt -RECURSIVE = YES -EXCLUDE = ../include/qs_dummy.h -EXCLUDE_SYMLINKS = NO -EXCLUDE_PATTERNS = -EXCLUDE_SYMBOLS = QP_IMPL -EXAMPLE_PATH = gen \ - snippets \ - ../include \ - ../src \ - ../ports \ - ../ports/lint-plus \ - ../examples -EXAMPLE_PATTERNS = * -EXAMPLE_RECURSIVE = NO -IMAGE_PATH = images \ - ../../ql-doxygen/images \ - ../../cert-pack/images -INPUT_FILTER = -FILTER_PATTERNS = -FILTER_SOURCE_FILES = NO -FILTER_SOURCE_PATTERNS = -USE_MDFILE_AS_MAINPAGE = -FORTRAN_COMMENT_AFTER = 72 -#--------------------------------------------------------------------------- -# Configuration options related to source browsing -#--------------------------------------------------------------------------- -SOURCE_BROWSER = YES -INLINE_SOURCES = NO -STRIP_CODE_COMMENTS = NO -REFERENCED_BY_RELATION = NO -REFERENCES_RELATION = NO -REFERENCES_LINK_SOURCE = YES -SOURCE_TOOLTIPS = YES -USE_HTAGS = NO -VERBATIM_HEADERS = YES -CLANG_ASSISTED_PARSING = NO -CLANG_ADD_INC_PATHS = YES -CLANG_OPTIONS = -CLANG_DATABASE_PATH = -#--------------------------------------------------------------------------- -# Configuration options related to the alphabetical class index -#--------------------------------------------------------------------------- -ALPHABETICAL_INDEX = YES -IGNORE_PREFIX = -#--------------------------------------------------------------------------- -# Configuration options related to the HTML output -#--------------------------------------------------------------------------- -GENERATE_HTML = YES -HTML_OUTPUT = ../html -HTML_FILE_EXTENSION = .html -HTML_HEADER = ../../ql-doxygen/ql-header-awesome.html -HTML_FOOTER = ../../ql-doxygen/ql-footer-awesome.html -HTML_STYLESHEET = -HTML_EXTRA_STYLESHEET = ../../ql-doxygen/doxygen-awesome.css \ - ../../ql-doxygen/doxygen-awesome-sidebar-only.css \ - ../../ql-doxygen/doxygen-awesome-sidebar-only-darkmode-toggle.css \ - ../../ql-doxygen/ql-awesome.css -HTML_EXTRA_FILES = ../../ql-doxygen/doxygen-awesome-darkmode-toggle.js \ - ../../ql-doxygen/doxygen-awesome-fragment-copy-button.js \ - ../../ql-doxygen/doxygen-awesome-paragraph-link.js \ - ../../ql-doxygen/ql-preview.js -HTML_COLORSTYLE = AUTO_LIGHT -HTML_COLORSTYLE_HUE = 209 -HTML_COLORSTYLE_SAT = 255 -HTML_COLORSTYLE_GAMMA = 113 -HTML_TIMESTAMP = NO -HTML_DYNAMIC_MENUS = YES -HTML_DYNAMIC_SECTIONS = NO -HTML_INDEX_NUM_ENTRIES = 100 -GENERATE_DOCSET = NO -DOCSET_FEEDNAME = "Doxygen generated docs" -DOCSET_FEEDURL = -DOCSET_BUNDLE_ID = com.state-machine.doc -DOCSET_PUBLISHER_ID = com.state-machine.doc -DOCSET_PUBLISHER_NAME = QuantumLeaps -GENERATE_HTMLHELP = NO -CHM_FILE = ../qpc.chm -HHC_LOCATION = -GENERATE_CHI = NO -CHM_INDEX_ENCODING = -BINARY_TOC = YES -TOC_EXPAND = NO -GENERATE_QHP = NO -QCH_FILE = -QHP_NAMESPACE = com.state-machine.qp -QHP_VIRTUAL_FOLDER = doc -QHP_CUST_FILTER_NAME = -QHP_CUST_FILTER_ATTRS = -QHP_SECT_FILTER_ATTRS = -QHG_LOCATION = -GENERATE_ECLIPSEHELP = NO -ECLIPSE_DOC_ID = com.state-machine.qp -DISABLE_INDEX = NO -GENERATE_TREEVIEW = YES -FULL_SIDEBAR = NO -ENUM_VALUES_PER_LINE = 4 -TREEVIEW_WIDTH = 335 -EXT_LINKS_IN_WINDOW = NO -OBFUSCATE_EMAILS = NO -HTML_FORMULA_FORMAT = png -FORMULA_FONTSIZE = 10 -FORMULA_MACROFILE = -USE_MATHJAX = NO -MATHJAX_VERSION = MathJax_2 -MATHJAX_FORMAT = HTML-CSS -MATHJAX_RELPATH = https://cdn.jsdelivr.net/npm/mathjax@2 -MATHJAX_EXTENSIONS = -MATHJAX_CODEFILE = -SEARCHENGINE = YES -SERVER_BASED_SEARCH = NO -EXTERNAL_SEARCH = NO -SEARCHENGINE_URL = -SEARCHDATA_FILE = searchdata.xml -EXTERNAL_SEARCH_ID = QPC -EXTRA_SEARCH_MAPPINGS = -#--------------------------------------------------------------------------- -# Configuration options related to the preprocessor -#--------------------------------------------------------------------------- -ENABLE_PREPROCESSING = YES -MACRO_EXPANSION = NO -EXPAND_ONLY_PREDEF = NO -SEARCH_INCLUDES = YES -INCLUDE_PATH = . -INCLUDE_FILE_PATTERNS = *.h -PREDEFINED = Q_SPY \ - Q_UTEST \ - QP_IMPL \ - Q_EVT_CTOR \ - QF_MAX_ACTIVE=32 \ - QF_MAX_TICK_RATE=2 \ - QF_MAX_EPOOL=3 \ - QF_EVENT_SIZ_SIZE=2 \ - QF_EQUEUE_CTR_SIZE=2 \ - QF_MPOOL_SIZ_SIZE=2 \ - QF_MPOOL_CTR_SIZE=2 \ - QF_TIMEEVT_CTR_SIZE=4 \ - QF_ACTIVE_STOP=0 \ - QF_ON_CONTEXT_SW \ - QS_TIME_SIZE=4 \ - QF_EQUEUE_TYPE=QEQueue \ - QF_OS_OBJECT_TYPE=void* \ - QF_THREAD_TYPE=void* -EXPAND_AS_DEFINED = -SKIP_FUNCTION_MACROS = NO diff --git a/doxygen/Doxyfile-CHM b/doxygen/Doxyfile-CHM deleted file mode 100644 index 75b01496..00000000 --- a/doxygen/Doxyfile-CHM +++ /dev/null @@ -1,12 +0,0 @@ -# Doxyfile 1.9.5 - -@INCLUDE = Doxyfile - -PROJECT_LOGO = images/logo_ql-comp.png - -HTML_OUTPUT = tmp -HTML_HEADER = ../../ql-doxygen/ql-header.html -HTML_FOOTER = ../../ql-doxygen/ql-footer.html -HTML_EXTRA_STYLESHEET = ../../ql-doxygen/ql.css -HTML_EXTRA_FILES = ../../ql-doxygen/ql-preview.js -GENERATE_HTMLHELP = YES diff --git a/doxygen/Doxyfile-LATEX b/doxygen/Doxyfile-LATEX deleted file mode 100644 index 587e58df..00000000 --- a/doxygen/Doxyfile-LATEX +++ /dev/null @@ -1,43 +0,0 @@ -# Doxyfile 1.9.5 - -@INCLUDE = Doxyfile - -#--------------------------------------------------------------------------- -# Configuration options related to the input files -#--------------------------------------------------------------------------- -INPUT = main.dox \ - gs.dox \ - ../../cert-pack/cert-pack.dox \ - ../../cert-pack/srs.dox \ - ../../cert-pack/sas.dox \ - ../../cert-pack/sds.dox \ - ../../cert-pack/sds_sm-c.dox \ - ../../cert-pack/misra.dox \ - ../../cert-pack/metrics.dox \ - history.dox \ - exa.dox \ - exa_native.dox \ - exa_rtos.dox \ - exa_os.dox \ - exa_qutest.dox \ - exa_mware.dox \ - ports.dox \ - ports_native.dox \ - ports_arm-cm.dox \ - ports_rtos.dox \ - ports_os.dox \ - api.dox \ - dir.dox \ - config.h \ - ../include \ - ../src \ - ../ports/lint-plus/std.lnt \ - ../ports/lint-plus/qpc.lnt \ - ../ports/lint-plus/options.lnt - -GENERATE_LATEX = YES -ENABLED_SECTIONS += LATEX - -# no source code in latex -SOURCE_BROWSER = NO -VERBATIM_HEADERS = NO diff --git a/doxygen/api.dox b/doxygen/api.dox deleted file mode 100644 index e4845600..00000000 --- a/doxygen/api.dox +++ /dev/null @@ -1,245 +0,0 @@ -/*! @page api API Reference -@ifnot LATEX -@nav_next{deprecated} -@endif - -@section api_qep QEP (Hierarchical State Machines) -QEP is a universal, UML-compliant event processor that enables developers to code UML state machines in highly readable ANSI-C, in which every state machine element is mapped to code precisely, unambiguously, and exactly once (traceability). QEP fully supports hierarchical state nesting, which is the fundamental mechanism for reusing behavior across many states instead of repeating the same actions and transitions over and over again. - - -@subsection api_qep_hsm Hierarchical State Machines -- ::QHsm class -- QHsm_ctor() -- QHSM_INIT() -- QHSM_DISPATCH() -- QHsm_isIn() -- QHsm_state() -- QHsm_top() -- ::QMsm class -- QMsm_ctor() -- QMsm_isInState() -- QMsm_stateObj() -- Q_STATE_CAST() - - -@section api_qf QF (Active Object Framework) -QF is a portable, event-driven, real-time framework for execution of active objects (concurrent state machines) specifically designed for real-time embedded (RTE) systems. - - -@subsection api_qf_act Active Objects -- ::QActive class -- QActive_ctor() -- QACTIVE_START() -- QACTIVE_POST() -- QACTIVE_POST_X() -- QACTIVE_POST_LIFO() -- QActive_defer() -- QActive_recall() -- QActive_flushDeferred() -- QActive_stop() -- ::QMActive class -- QMActive_ctor() - - -@subsection api_qf_ps Publish-Subscribe -- ::QSubscrList (Subscriber List struct) -- QF_psInit() -- QF_PUBLISH() -- QActive_subscribe() -- QActive_unsubscribe() -- QActive_unsubscribeAll() - - -@subsection api_qf_evt Event Management -- ::QEvt class -- QF_poolInit() -- Q_NEW() -- Q_NEW_X() -- Q_NEW_REF() -- Q_DELETE_REF() -- QF_gc() -- Q_EVT_CAST() - - -@subsection api_qf_time Time Events -- ::QTimeEvt class -- QF_TICK_X() -- QTimeEvt_ctorX() -- QTimeEvt_armX() -- QTimeEvt_disarm() -- QTimeEvt_rearm() -- QTimeEvt_currCtr() -- ::QTicker active object - - -@subsection api_qf_queue Event Queues (raw thread-safe) -- ::QEQueue class -- QEQueue_init() -- QEQueue_post() -- QEQueue_postLIFO() -- QEQueue_get() -- QEQueue_getNFree() -- QEQueue_getNMin() -- QEQueue_isEmpty() -- QEQueueCtr() - - -@subsection api_qf_mem Memory Pools -- ::QMPool class -- QMPool_init() -- QMPool_get() -- QMPool_put() - - -@section api_qs QS (Software Tracing) -QS is a software tracing system that enables developers to monitor live event-driven QP applications with minimal target system resources and without stopping or significantly slowing down the code. QS is an ideal tool for testing, troubleshooting, and optimizing QP applications. QS can even be used to support acceptance testing in product manufacturing. - - -@subsection api_qs_ini QS Initialization and Control -- QS_INIT() -- QS_initBuf() -- QS_getByte() -- QS_getBlock() -- QS_onStartup() -- QS_onCleanup() -- QS_onFlush() -- QS_onGetTime() - - -@subsection api_qs_rx QS Receive-Channel (QS-RX) -- QS_rxInitBuf() -- QS_RX_PUT() -- QS_rxParse() -- QS_onCommand() - - -@subsection api_qs_filter QS Filters -- QS_GLB_FILTER() -- QS_LOC_FILTER() -- QS_FILTER_AP_OBJ() - - -@subsection api_qs_dict QS Dictionaries -- QS_SIG_DICTIONARY() -- QS_OBJ_DICTIONARY() -- QS_OBJ_ARR_DICTIONARY() -- QS_FUN_DICTIONARY() -- QS_USR_DICTIONARY() -- QS_ENUM_DICTIONARY() - - -@subsection api_qs_user QS Application-Specific Records -- ::QS_USER enumeration -- QS_BEGIN_ID() -- QS_END() -- QS_U8() / QS_I8() -- QS_U16() / QS_I16() -- QS_U32() / QS_I32() -- QS_STR() -- QS_MEM() -- QS_ENUM() - - -@section api_qv QV (Cooperative Kernel) -QV is a simple **cooperative** kernel (previously called "Vanilla" kernel). This kernel executes active objects one at a time, with priority-based scheduling performed before processing of each event. Due to naturally short duration of event processing in state machines, the simple QV kernel is often adequate for many real-time systems. - -The QV scheduler is engaged after every RTC step of any active object to choose the next active object to execute. The QV scheduler always chooses the highest-priority active object that has any events in its event queue. The QV scheduler then extracts the next event from this queue and dispatches it to the state machine associated with the active object. The state machine runs to completion, after which the QV scheduler runs and the cycle repeats. - -Please note that because the state machines always return to the QV scheduler after each RTC step, a single stack can be used to process all state machines (memory-friendly architecture). - -The QV scheduler can also very easily detect when all event queues are empty, at which point it can call the idle callback to let the application put the CPU and peripherals to a low-power sleep mode (power-friendly architecture). - -Given the simplicity, portability, and low-resource consumption, the QV scheduler is very attractive. It allows you to partition the problem into active objects and execute these active objects orderly. The task-level response of this scheduler is the longest RTC step in the whole system, but because event-driven active objects don’t block, the RTC steps tend to be very short (typically just a few microseconds). Also, often you can break up longer RTC steps into shorter pieces, by posting an event to self and returning (“Reminder” state pattern). The self-posted event then triggers the continuation of longer processing. - - -@subsection api_qv_init Kernel Initialization and Control -- QV_INIT() -- QF_run() -- QV_onIdle() -- QV_CPU_SLEEP() - - -@section api_qk QK (Preemptive RTC Kernel) -QK is a tiny **preemptive**, run-to-completion (RTC) kernel designed specifically for executing active objects. QK runs active objects in the same way as prioritized interrupt controller (such as NVIC in ARM Cortex-M) runs interrupts using the single stack. Active objects process their events in run-to-completion (RTC) fashion and remove themselves from the call stack, the same way as nested interrupts remove themselves from the stack upon completion. At the same time high-priority active objects can preempt lower-priority active objects, just like interrupts can preempt each other under a prioritized interrupt controller. QK meets all the requirement of the Rate Monotonic Scheduling (a.k.a. Rate Monotonic Analysis RMA) and can be used in hard real-time systems. - - -@subsection api_qk_ctrl Kernel Initialization and Control -- QK_INIT() -- QF_run() -- QK_onIdle() -- QK_schedLock() -- QK_schedUnlock() - - -@subsection api_qk_isr Interrupt Management -- QK_ISR_ENTRY() -- QK_ISR_EXIT() - - -@section api_qxk QXK (Dual-Mode Kernel) -QXK is a small, preemptive, priority-based, dual-mode (run-to-completion/blocking) kernel that executes active objects like the @ref srs_qk "QK kernel", but can also execute traditional __blocking__ threads (extended threads). In this respect, QXK behaves exactly as a conventional __RTOS__ (Real-Time Operating System). QXK has been designed specifically for mixing event-driven active objects with traditional blocking code, such as commercial middleware (TCP/IP stacks, UDP stacks, embedded file systems, etc.) or legacy software. - - -@subsection api_qxk_ctrl Kernel Initialization and Control -- QXK_INIT() -- QF_run() -- QXK_onIdle() -- QXK_schedLock() -- QXK_schedUnlock() - - -@subsection api_qxk_isr Interrupt Management -- QXK_ISR_ENTRY() -- QXK_ISR_EXIT() - - -@subsection api_qxk_xthr Extended Thread Management -- ::QXThread class -- QXThread_ctor() -- QXTHREAD_START() -- QXTHREAD_POST_X() -- Q_XTHREAD_CAST() -- QXThread_delay() -- QXThread_delayCancel() -- QXThread_queueGet() -- QXK_current() -- QXK_TLS() - -@subsection api_qxk_sema Semaphores -- ::QXSemaphore class (Semaphore Control Block) -- QXSemaphore_init() -- QXSemaphore_wait() -- QXSemaphore_tryWait() -- QXSemaphore_signal() - - -@subsection api_qxk_mutex Mutexes -- ::QXMutex class (Mutex Control Block) -- QXMutex_init() -- QXMutex_lock() -- QXMutex_tryLock() -- QXMutex_unlock() - - -@subsection api_qxk_queue Message Queues -- QXTHREAD_POST_X() - posting messages to blocking threads -- QACTIVE_POST_X() - posting events to Active Objects -- QXThread_queueGet() - waiting (blocking) on message queue - - -@subsection api_qxk_mem Memory Pools -- ::QMPool class -- QMPool_init() -- QMPool_get() -- QMPool_put() - -@ifnot LATEX -@nav_next{deprecated} -@endif -*/ -############################################################################## -/*! @page deprecated Deprecated APIs - -**The following QP/C APIs are now deprecated:** - -*/ diff --git a/doxygen/config.h b/doxygen/config.h deleted file mode 100644 index 615cd089..00000000 --- a/doxygen/config.h +++ /dev/null @@ -1,65 +0,0 @@ -/** -* @file -* @brief Various macros for configuring QP/C (typically used as -* command-line options) -*/ - -/*! The preprocessor switch to disable checking assertions -* -* @description -* When defined, Q_NASSERT disables the following macros #Q_ASSERT, -* #Q_REQUIRE, #Q_ENSURE, #Q_INVARIANT, #Q_ERROR as well as -* #Q_ASSERT_ID, #Q_REQUIRE_ID, #Q_ENSURE_ID, #Q_INVARIANT_ID, and -* #Q_ERROR_ID do _not_ evaluate the test condition passed as the -* argument to these macros. -* -* @note The notable exceptions are the macros #Q_ALLEGE and -* #Q_ALLEGE_ID, that still evaluate the test condition, but do not -* report assertion failures when the switch #Q_NASSERT is defined. -*/ -#define Q_NASSERT - -/*! Enable the QActive_stop() API in the QF port. -* -* @description -* Defining this macro enables the QActive_stop() API in a given port. -* This feature should be used with caution, as stopping and re-starting -* active objects **cleanly** can be tricky. -*/ -#define QF_ACTIVE_STOP - -/*! The preprocessor switch to activate the QS software tracing -* instrumentation in the code -* -* @description -* When defined, Q_SPY activates the QS software tracing instrumentation. -* When Q_SPY is not defined, the QS instrumentation in the code does -* not generate any code. -*/ -#define Q_SPY - -/*! The preprocessor switch to activate the QUTest unit testing -* instrumentation in the code -* -* @note -* This macro requires that #Q_SPY be defined as well. -*/ -#define Q_UTEST - -/*! The preprocessor switch to enable constructor in the ::QEvt class -* instrumentation in the code -* -* @tr{RQP005} -*/ -#define Q_EVT_CTOR - -/*! This macro enables calling the context-switch callback -* QF_onContextSw() in all build-in kernels (QV, QK, QXK) -*/ -#define QF_ON_CONTEXT_SW - -/*! Macro defined only for the internal QP implementation. It should -* be not defined for the application-level code -*/ -#define QP_IMPL - diff --git a/doxygen/dir.dox b/doxygen/dir.dox deleted file mode 100644 index 83ae9dc2..00000000 --- a/doxygen/dir.dox +++ /dev/null @@ -1,48 +0,0 @@ -/*##########################################################################*/ -/*! @dir include -@brief Platform-independent QP™/C API - -@attention -The QP™/C include directory needs to be added to the compiler's include path in the applications using QP™/C. -*/ -/*##########################################################################*/ -/*! @dir src -@brief Platform-independent QP™/C source code - -Files from this directory need to be added to the project, to build the QP™/C framework from source code. - -@attention -The QP™/C src directory needs to be added to the compiler's include path in the applications that build QP™/C framework from sources (as opposed to using QP as a pre-built library). -*/ -/*##########################################################################*/ -/*! @dir src/qf -@brief Platform-independent implementation of the QEP and QF components. - -@note -Typically, files in this directory need to be added to the application build, but some QP ports might not need all the files in this directory. For example, a QP port to a 3rd-party RTOS kernel might be using a message queue of the RTOS instead of the native QP event queue, in which case the file qf_actq.c would not be needed and should be excluded from the build. -*/ -/*##########################################################################*/ -/*! @dir src/qv -@brief Platform-independent implementation of the @ref srs_qv built-in kernel. - -@attention -Files in this directory need to be included in the QP application build only if the application uses the @ref srs_qv kernel. -*/ -/*##########################################################################*/ -/*! @dir src/qk -@brief Platform-independent implementation of the @ref srs_qk built-in kernel. - -@attention -Files in this directory need to be included in the QP application build only if the application uses the @ref srs_qk kernel. -*/ -/*##########################################################################*/ -/*! @dir src/qxk -@brief Platform-independent implementation of the @ref srs_qxk built-in kernel. - -@attention -Files in this directory need to be included in the QP application build only if the application uses the @ref srs_qxk kernel. -*/ -/*##########################################################################*/ -/*! @dir src/qs -@brief Platform-independent implementation of the QS component (software tracing). -*/ diff --git a/doxygen/exa.dox b/doxygen/exa.dox deleted file mode 100644 index dfb3c23b..00000000 --- a/doxygen/exa.dox +++ /dev/null @@ -1,425 +0,0 @@ -/*! @page exa Examples - -@section exa_gen General Comments -The QP/C distribution contains many @subpage exa_ref "example projects" to demonstrate various QP/C features. Each example project is described on its own dedicated page that you can find using several criteria (see @ref exa_ref). The example projects have the following main goals: - -- to help you learn how to use QP/C — the examples show the intended way of using QP/C features and structuring QP/C applications. - -- to provide you with a starting point for your own projects — the examples are complete working projects, with correctly pre-configured tools, such as compiler options, linker script, debugger setup, etc. - -- to provide you with unit testing support — the [QUTest](/qtools/qutest.html) examples illustrate unit testing techniques both for the development worksations and for embedded targets. - -@note -It is highly recommended that you create your own projects by **copying and modifying** existing example projects rather than starting your QP/C projects from scratch. - - -@subsection exa_code Example Code Structure -QP/C examples are located in sub-directories of the examples top-level folder, with the hierarchical organization outlined below: - -
-@code{.c} -qpc/ // QP/C installation directory -+---examples/ // examples directory (applications) -| | -| [1]--arm-cm/ // examples for ARM Cortex-M -| | +---dpp_ek-tm4c123gxl/ // DPP example on the EK-TM4C123GLX board -| | | +---qk/ // version for preemptive QK kernel -| | | | +---armclang/ // build with ARM-Clang (Compiler Version 6) toolchain -| | | | | +---dbg/ // debug build configuration -| | | | | +---rel/ // release build configuration -| | | | | +---spy/ // spy build configuration (QP/Spy tracing enabled) -| | | | +---gnu/ // build with GNU-ARM toolchain -| | | | +---iar/ // build with IAR toolchain -| | | | ~ ~ ~ // source files independent from the toolchain -| | | +---qv/ // version for cooperative QV kernel -| | | \---qxk/ // version for dual-mode QXK kernel -| | -| [2]--freertos/ // examples for FreeRTOS (3rd-party RTOS) -| | +---arm-cm/ // examples for ARM Cortex-M -| | | +---dpp_ek-tm4c123gxl/ // DPP example on the EK-TM4C123GLX board -| | | | +---gnu/ // build with GNU-ARM toolchain -| | -| [3]--lwip/ // examples for lwIP (3rd-party middleware) -| | +---arm-cm/ // examples for ARM Cortex-M -| | | +---qk/ // version for preemptive QK kernel -| | | +---qv/ // version for cooperative QV kernel -| | | \---qxk/ // version for dual-mode QXK kernel -| | -| [4]--qutest/ // examples for QUTest unit testing harness -| | +---blinky/ // simple Blinky example -| | | +---src/ // source code under test -| | | | blinky.h // header file -| | | | blinky.c // source file -| | | +---test/ // code for unit testing -| | | | Makefile // makefile for testing on the host -| | | | make_nucleo-l053r8 // makefile for testing on NUCLEO board -| | | | make_tm4c123 // makefile for testing on NUCLEO board -| | | | test_blinky.c // test fixture -| | | | test_blinky.py // test script -| | -| [5]--workstation/ // examples for workstations (Windows, Linux, macOS) -| | +---blinky/ // simple Blinky example -| | +---calc/ // calculator example -| | +---comp/ // "Orthogonal Component" example -| | +--- ~ ~ ~ // other examples from the PSiCC2 book -@endcode - -`[1]` @subpage exa_native "Native examples" -are located in sub-directories named after the CPU architecture, such as arm-cm for ARM Cortex-M. Under that directory, the sub-directories blinky_ek-tm4c123gxl contain the specific example on the specified board, such as "Blinky" on the EK-TM4C123GXL board here. In the specific example folder, you find sub-folders for the @ref comp_qv "QV", @ref comp_qk "QK" and @ref comp_qxk "QXK" kernels, respectively. - -`[2]` @subpage exa_rtos "Examples for 3rd-party RTOS" -are located in sub-directories named after the RTOS/OS, such as freertos for uc-os2 RTOS. Under that directory, the sub-directories, such as arm-cm, contain examples for the specified CPU architecture, such as ARM Cortex-M here. - -`[3]` @subpage exa_mware "Examples for 3rd-party Middleware" -are located in sub-directories named after the middleware, such as lwIP for the lwIP TCP/IP stack. Under that directory, the sub-directories, such as arm-cm, contain examples for the specified CPU architecture, such as ARM Cortex-M here. - -`[4]` @subpage exa_qutest "Examples for QUTest" -illustrate unit testing of embedded event-driven code. NOTE: Examples in this directory can run on all types of workstations (Windows, Linux, MacOS), as well as embedded targets. - -`[5]` @subpage exa_os "Examples for Workstations" -General-Purpose OS (GPOS) examples described in the [PSiCC2](/psicc2) book, which you can try directly on your workstation without any embedded hardware. NOTE: Examples in this directory can also be used on the embedded versions of the desktop operating systems, such as embedded-Linux and Windows-embedded. - - -@note -Because the QP distribution contains *all* examples, the number of sub-directories and files in the examples folder may seem daunting. However, knowing the structure of the examples folder, you can simply ignore or even delete the sub-directories that are not interesting to you. - - -@subsection exa_sec_apps Example Applications -To demonstrate QP/C features on an embedded board, you need to create an application that does "something interesting". Instead of inventing this "something interesting" for each and every example, the example projects implement one of the three "example applications", which are described on the @ref gs_tut "QP™/C Tutorial": - -- @ref tut_blinky -- @ref tut_dpp -- @ref tut_game - -With the exception of the game application, all other example applications can be implemented on a board with just a couple of LEDs. The @ref game application is a bit more involved and requires a small graphic display on the board. - -Beyond these basic applications for demonstrating and testing the various @ref ports "QP/C ports", the QP/C distribution contains all examples described in the book Practical UML Statecharts in C/C++, 2nd Edition. -@sa @ref exa_os - - -@subsection exa_sec_boards Development Boards -While some provided examples can run on your @ref exa_os "desktop computer", most embedded example projects require special hardware in form of @ref exa_sec_boards, which you need to acquire to be able to run the examples. The boards chosen for the examples are generally inexpensive and self-contained with no need for external hardware (such as external JTAG debuggers or power supplies). - - -@subsection exa_sec_tools Development Tools -Most provided examples require special embedded cross-development tools, such as embedded compilers, linkers, debuggers and IDEs, which you need to acquire independently from the QP/C distribution. Generally, the examples work with the free (size limited) evaluation versions of the commercial tools. The examples list the versions of tools they were developed and tested with. Please refer to the @ref exa_ref "cross-reference section" @ref exa_sec_tools to see which embedded toolchains are used. - - -@subsection exa_sec_conf Build Configurations -QP examples @ref ports "QP ports" are provided in the following three **build configurations**: - -- **Debug** — this configuration is built with full debugging information and minimal optimization. When the QP framework finds no events to process, the framework busy-idles until there are new events to process. The @ref comp_qs "QS trace instrumentation" is **disabled**. - -- **Release** — this configuration is built with no debugging information and high optimization. Single-stepping and debugging at the source-code level is effectively impossible due to the lack of debugging information and optimized code, but the debugger can be used to download and start the executable. When the QP framework finds no events to process, the framework puts the CPU to sleep until there are new events to process. The @ref comp_qs "QS trace instrumentation" is **disabled**. - -- **Spy** — like the debug variant, this variant is built with full debugging information and minimal optimization. Additionally, it is build with the @ref comp_qs "QS trace instrumentation" enabled. The on-board serial port and the Q-Spy host application are used for sending and viewing trace data. Like the Debug configuration, the QP framework busy-idles until there are new events to process. - - -@remark -Why do you need multiple build configurations?@n -The different phases of embedded software life cycle pose different challenges. During the development and maintenance phase, for example, the emphasis is on the ease of debugging and verifying the correctness of the code, which require lower levels of optimization and special scaffolding code. In contrast, for releasing the code in the final product, the emphasis is on small memory footprint and CPU time efficiency, which require high-level of optimization and removal of any scaffolding code. To address these conflicting needs, the same source code is compiled into multiple **build configurations** that differ in the use of compiler options and activation of the scaffolding code. - - -@subsection exa_sec_qm QM Models -Many example projects contain code auto-generated by the QM modeling tool. Such projects always contain the corresponding **QM model** file, which you can open in QM, modify, and re-generate the code. - -@note -The auto-generated files are saved as **read-only**. This protects them from inadvertent modifications, which will get lost when the files are re-generated by QM (or QMC). All modifications to the auto-generated code should be done in the QM model, not in the code. - - -@subsection exa_sec_3rd Third-Party Code -The QP/C example projects often need to use various additional code, such as MCU register definition files, startup code, device drivers, etc., which are provided by Third-Party vendors. All such code is located in the 3rd_party top-level folder. - -@note -As far as possible, the code in the 3rd_party folder has been left unchanged from the original source. (Any modified code is clearly identified by top-level comments that detail the applied changes.) For that reason, the Third-Party code might produce **compilation warnings** in your builds. - -The code in the 3rd_party folder comes from various sources, and Quantum -Leaps, LLC expressly makes **no claims of ownership** to any of this code, even though some of the code might be customized or modified by Quantum Leaps. - -@attention -The Third-Party software components included in the 3rd_party folder are licensed under a variety of different licensing terms that are defined by the respective owners of this software and are spelled out in the `README.txt` or `LICENSE.txt` files included in the respective -sub-folders. - - -@subsection exa_own Creating your Own QP/C Projects -Perhaps the most important fact of life to remember is that in embedded systems nothing works until everything works. This means that you should always start with a working system and gradually evolve it, changing one thing at a time and making sure that it keeps working every step of the way. - -Keeping this in mind, the provided QP/C application examples, such as the super-simple Blinky, or a bit more advanced @ref dpp or @ref game, allow you to get started with a working project rather than starting from scratch. You should also always try one of the provided example projects on the same evaluation board that it was designed for, before making any changes. - -@note -The evaluation boards used in the examples are all very **inexpensive** and available from major electronic distributors (e.g., [Arrow](https://www.arrow.com/), [DigiKey](https://www.digikey.com/), [Mouser](https://www.mouser.com/), [Avnet](https://www.avnet.com)), as well as directly from the silicon vendors (e.g., a TI board is also available from TI.com). - -@remark -Even before you acquire a specific evaluation board, you can always at least **build** a project that interests you on your workstation. - - -Only after convincing yourself that the example project works "as is", you can think about creating your own projects. At this point, the easiest and recommended way is to copy the existing working example project folder (such as the Blinky example) and rename it. - -After copying the project folder, you still need to change the name of the project/workspace. The easiest and safest way to do this is to open the project/workspace in the corresponding IDE and use the Save As~~~ option to save the project under a different name. You can do this also with the QM model file, which you can open in QM and "Save As" a different model. - -@note -By copying and re-naming an existing, working project, as opposed to creating a new one from scratch, you inherit the correct compiler and linker options an other project settings, which will help you get started much faster. - - -@subsection exa_doc Next Steps and Further Reading About QP and QM - -To work with QP/C effectively, you need to learn a bit more about active objects and state machines. Below is a list of links to enable you to further your knowledge: - -1. The book “Practical UML Statecharts in C/C++, 2nd Edition” [PSiCC2] and the companion web-page to the book (https://www.state-machine.com/psicc2/ -2. Free Support Forum for QP/QM (https://sourceforge.net/p/qpc/discussion/668726 ) -3. QP Code Downloads summary (https://www.state-machine.com/#Downloads ) -4. QP Application Notes (https://www.state-machine.com/an/ ) -5. "State Space" Blog (https://www.state-machine.com/category/blog/ ) - -@ifnot LATEX -@nav_next{exa_ref} -@endif -*/ - -/*##########################################################################*/ -/*! @page exa_ref Cross-Reference - -@section exa_ref_kernel Native Examples (by Built-in Kernel) -- @ref exa_qv -- @ref exa_qk -- @ref exa_qxk - - -@section exa_ref_tool Native Examples (by Development Toolchain) - - -@subsection exa_ref_arm-clang ARM-Clang Toolchain (ARM Compiler 6) -- @ref arm-cm_blinky_efm32-slstk3401a   (Cortex-M4) -- @ref arm-cm_dpp_ek-tm4c123gxl   (Cortex-M4) -- @ref arm-cm_dpp_efm32-slstk3401a   (Cortex-M4) -- @ref arm-cm_dpp_mbed-lpc1768   (Cortex-M4) -- @ref arm-cm_dpp_nucleo-l053r8   (Cortex-M0+) -- @ref arm-cm_dpp_nucleo-l152re   (Cortex-M3) -- @ref arm-cm_game_efm32-slstk3401a   (Cortex-M4) -- @ref arm-cm_dpp_stm32f4-discovery -- @ref arm-cm_dpp_nucleo-l053r8   (Cortex-M0+) -- @ref arm-cm_dpp_efm32-slstk3401a   (Cortex-M4) -- @ref arm-cm_dpp_nucleo-h743zi   (Cortex-M7) - - -@subsection exa_ref_gnu-arm GNU-ARM (command-line with Makefile, importable to Eclipse) -- @ref arm-cm_blinky_ek-tm4c123gxl   (Cortex-M4) -- @ref arm-cm_blinky_efm32-slstk3401a   (Cortex-M4) -- @ref arm-cm_dpp_ek-tm4c123gxl   (Cortex-M4) -- @ref arm-cm_dpp_efm32-slstk3401a   (Cortex-M4) -- @ref arm-cm_dpp_mbed-lpc1768   (Cortex-M4) -- @ref arm-cm_dpp_nucleo-l053r8   (Cortex-M0+) -- @ref arm-cm_dpp_nucleo-l152re   (Cortex-M3) -- @ref arm-cm_game_efm32-slstk3401a   (Cortex-M4) -- @ref arm-cm_dpp_stm32f4-discovery -- @ref lwip_ek-lm3s6965   (Cortex-M3) - - -@subsection exa_ref_gnu-ccs GNU-ARM with TI CCS IDE -- @ref arm-cm_dpp_ek-tm4c123gxl   (Cortex-M4) - - -@subsection exa_ref_iar-arm IAR EWARM -- @ref arm-cm_blinky_ek-tm4c123gxl   (Cortex-M4) -- @ref arm-cm_blinky_efm32-slstk3401a   (Cortex-M4) -- @ref arm-cm_dpp_ek-tm4c123gxl   (Cortex-M4) -- @ref arm-cm_dpp_efm32-slstk3401a   (Cortex-M4) -- @ref arm-cm_dpp_mbed-lpc1768   (Cortex-M4) -- @ref arm-cm_dpp_nucleo-l053r8   (Cortex-M0+) -- @ref arm-cm_dpp_nucleo-l152re   (Cortex-M3) -- @ref arm-cm_game_efm32-slstk3401a   (Cortex-M4) -- @ref arm-cr_blinky_launchxl2-tms57012   (Cortex-R4) -- @ref arm-cr_dpp_launchxl2-tms57012   (Cortex-R4) -- @ref lwip_ek-lm3s6965   (Cortex-M3) - - -@subsection exa_ref_ccs-430 CCS for MSP430 -- @ref msp430_blinky_msp-exp430f5529lp -- @ref msp430_dpp_msp-exp430f5529lp - - -@subsection exa_ref_iar-430 IAR EW430 -- @ref msp430_blinky_msp-exp430f5529lp -- @ref msp430_dpp_msp-exp430f5529lp - - -@section exa_ref_native Native Examples (by Processor) -- @ref exa_arm-cm -- @ref exa_arm-cr -- @ref exa_msp430 ("classic" MSP430 and "extended" MSP430x) - - -@section exa_ref_rtos Examples for Third-Party RTOS -- @ref exa_embos (SEGGER) -- @ref exa_freertos (Amazon Web Services) -- @ref exa_threadx (Express Logic) -- @ref exa_uc-os2 (Micrium/SiLabs) - - -@section exa_ref_os Examples for Workstations (Windows, Linux, MacOS) -The examples in the "workstation" directory are designed for workstations (running Windows, Linux, or MacOS), but they can also be used for projects intended for the **embedded** versions of the "big" operating systems (e.g., embedded-Linux or Windows-embedded). These examples are based on the following QP ports: - -- @ref exa_os "POSIX-QV" — single-threaded examples for POSIX-QV (Linux, MacOS) -- @ref exa_os "POSIX" — multi-threaded examples for POSIX (Linux, MacOS, QNX, etc.) -- @ref exa_os "Windows-QV" — single-threaded examples for Windows -- @ref exa_os "Windows" — multi-threaded examples for Windows - - - -@section exa_ref_mware Examples for Third-Party Middleware -- @ref exa_lwip (open source, see http://lwip.wikia.com/wiki/LwIP_Wiki ) -- @ref exa_emwin (SEGGER, a.k.a. uC/GUI by Micrium) - - -@section exa_ref_boards Examples by Development Board -The boards chosen for the examples are generally inexpensive and self-contained with minimal need for external hardware (such as external JTAG debuggers or power supplies). Also, all the selected boards provide a virtual COM port (ideally) or can be easily connected to a TTL-to-USB serial converter cable for @ref comp_qs "QS software tracing" output. - -@note -You can hover the mouse cursor over the    icon in the list below to see the picture of the board. - - -@subsection exa_ref_arm-cm ARM Cortex-M Boards - -@anchor EK-TM4C123GXL -@image html bd_EK-TM4C123GXL.jpg -@image latex bd_EK-TM4C123GXL.jpg width=2.5in -@caption{EK-TM4C123GXL (TivaC LaunchPad)} - -- @ref arm-cm_blinky_ek-tm4c123gxl (QV, QK kernels; ARM-KEIL, GNU-ARM, IAR-EWARM toolchains) -- @ref arm-cm_dpp_ek-tm4c123gxl (QV, QK, QXK kernels; ARM-KEIL, GNU-ARM, IAR-EWARM toolchains) -- @ref freertos_dpp_ek-tm4c123gxl (FreeRTOS kernel; ARM-KEIL, GNU-ARM, IAR-EWARM toolchains) -- @ref freertos_dpp_nucleo-h743zi (FreeRTOS kernel; ARM-KEIL, GNU-ARM, IAR-EWARM toolchains) -- @ref threadx_dpp_ek-tm4c123gxl (ThreadX kernel; IAR-EWARM toolchain) -- @ref uc-os2_dpp_ek-tm4c123gxl (uC/OS-II kernel; ARM-KEIL, GNU-ARM, IAR-EWARM toolchains) - - -@anchor EFM32-SLSTK3401A -@image html bd_EFM32-SLSTK3401A.jpg -@image latex bd_EFM32-SLSTK3401A.jpg width=4.5in -@caption{EFM32-SLSTK3401A (Pearl-Gecko)} - -- @ref arm-cm_blinky_efm32-slstk3401a (QV, QK kernels; ARM-KEIL, GNU-ARM, IAR-EWARM toolchains) -- @ref arm-cm_dpp_efm32-slstk3401a (QV, QK, QXK kernels; ARM-KEIL, GNU-ARM, IAR-EWARM toolchains) -- @ref arm-cm_game_efm32-slstk3401a (QV, QK kernels; ARM-KEIL, GNU-ARM, IAR-EWARM toolchains; QWin-GUI emulation) - - -@anchor mbed-LPC1768 -@image html bd_mbed-LPC1768.jpg -@image latex bd_mbed-LPC1768.jpg width=2.5in -@caption{mbed-LPC1768} -- @ref arm-cm_dpp_mbed-lpc1768 (QV, QK kernels; ARM-KEIL, GNU-ARM, IAR-EWARM toolchains) - -@anchor NUCLEO-L053R8 -@image html bd_NUCLEO-L053R8.jpg -@image latex bd_NUCLEO-L053R8.jpg width=2.5in -@caption{NUCLEO-L053R8} -- @ref arm-cm_dpp_nucleo-l053r8 (QV, QK, QXK kernels; ARM-KEIL, GNU-ARM, IAR-EWARM toolchains) - -@anchor NUCLEO-L152RE -@image html bd_NUCLEO-L152RE.jpg -@image latex bd_NUCLEO-L152RE.jpg width=2.4in -@caption{NUCLEO-L152RE} -- @ref arm-cm_dpp_nucleo-l152re (QV, QK kernels; ARM-KEIL, GNU-ARM, IAR-EWARM toolchains) -- @ref uc-os2_dpp_nucleo-l053r8 (uC/OS-II kernel; ARM-KEIL, IAR-EWARM toolchains) - -@anchor EK-LM3S6965 -@image html bd_EK-LM3S6965.jpg -@image latex bd_EK-LM3S6965.jpg width=2.0in -@caption{EK-LM3S6965} -- @ref lwip_ek-lm3s6965 (**LwIP TCP/IP**; QV, QK kernels; ARM-KEIL, GNU-ARM, IAR-EWARM toolchains) - -@anchor NUCLEO-H743ZI -@image html bd_NUCLEO-H743ZI.jpg -@image latex bd_NUCLEO-H743ZI.jpg width=4.5in -@caption{NUCLEO-H743ZI} -- @ref arm-cm_dpp_nucleo-h743zi (QV, QK, QXK kernels; ARM-KEIL, GNU-ARM, IAR-EWARM toolchains) -- @ref freertos_dpp_nucleo-h743zi (FreeRTOS kernel; ARM-KEIL, GNU-ARM, IAR-EWARM toolchains) - - -@anchor STM32F4-Discovery -@image html bd_STM32F4-Disco.jpg -@image latex bd_STM32F4-Disco.jpg width=2.8in -@caption{STM32F4-Discovery} -- @ref arm-cm_dpp_stm32f4-discovery (QV, QK, QXK kernels; ARM-KEIL, GNU-ARM, IAR-EWARM toolchains) -- @ref embos_dpp_stm32f429-discovery (embOS kernel; IAR-EWARM toolchain) -- @ref threadx_dpp_stm32f429-discovery (ThreadX kernel; IAR-EWARM toolchain) - - -@anchor STM32F746G-Discovery -@image html bd_STM32F746G-Disco.jpg -@image latex bd_STM32F746G-Disco.jpg width=4.75in -@caption{STM32F746G-Discovery} -- @ref arm-cm_dpp_stm32f746g-disco (QV, QK, QXK kernels; ARM-KEIL, GNU-ARM, IAR-EWARM toolchains) -- @ref freertos_dpp_stm32f746g-disco (FreeRTOS kernel; ARM-KEIL, GNU-ARM, IAR-EWARM toolchains) - - -@subsection exa_ref_arm-cr ARM Cortex-R Boards: - -@anchor LAUNCHXL2-TMS57012 -@image html bd_LAUNCHXL2-TMS57012.jpg -@image latex bd_LAUNCHXL2-TMS57012.jpg width=4.0in -@caption{LAUNCHXL2-TMS57012} -- @ref arm-cr_blinky_launchxl2-tms57012 (QV, QK kernels; CCS-TI-ARM, IAR-EWARM toolchains) -- @ref arm-cr_dpp_launchxl2-tms57012 (QV, QK kernels; CCS-TI-ARM, IAR-EWARM toolchains) - - -@subsection exa_ref_msp430 MSP430 Boards: - -@anchor MSP-EXP430F5529LP -@image html bd_MSP-EXP430F5529LP.jpg -@image latex bd_MSP-EXP430F5529LP.jpg width=3.5in -@caption{MSP-EXP430F5529LP} -- @ref msp430_blinky_msp-exp430f5529lp (QV, QK kernels; CCS=430, IAR-EW430 toolchains) -- @ref msp430_dpp_msp-exp430f5529lp (QV, QK kernels; CCS=430, IAR-EW430 toolchains) - - -@section exa_ref_mcu Examples by MCU Architecture -- ARM Cortex-M0/M0+ - - @ref arm-cm_dpp_nucleo-l053r8 -- ARM Cortex-M3 - - @ref arm-cm_dpp_nucleo-l152re - - @ref arm-cm_dpp_mbed-lpc1768 - - @ref lwip_ek-lm3s6965 -- ARM Cortex-M4 (with hardware FPU) - - @ref arm-cm_blinky_ek-tm4c123gxl - - @ref arm-cm_blinky_efm32-slstk3401a - - @ref arm-cm_dpp_ek-tm4c123gxl - - @ref arm-cm_dpp_efm32-slstk3401a - - @ref arm-cm_game_efm32-slstk3401a - - @ref arm-cm_dpp_stm32f4-discovery -- ARM Cortex-M7 (with hardware single-precision FPU) - - @ref arm-cm_dpp_stm32f746g-disco -- ARM Cortex-M7 (with hardware double-precision FPU) - - @ref arm-cm_dpp_nucleo-h743zi -- ARM Cortex-R - - @ref arm-cr_blinky_launchxl2-tms57012 - - @ref arm-cr_dpp_launchxl2-tms57012 - -- MSP430 - - @ref msp430_blinky_msp-exp430f5529lp - - @ref msp430_dpp_msp-exp430f5529lp - -@section exa_ref_vendor Examples by MCU Vendor -- NXP - - @ref arm-cm_dpp_mbed-lpc1768 -- Silicon Labs - - @ref arm-cm_blinky_efm32-slstk3401a - - @ref arm-cm_dpp_efm32-slstk3401a - - @ref arm-cm_game_efm32-slstk3401a -- ST Microelectronics - - @ref arm-cm_dpp_nucleo-l053r8 - - @ref arm-cm_dpp_nucleo-l152re - - @ref arm-cm_dpp_stm32f4-discovery - - @ref arm-cm_dpp_stm32f746g-disco -- Texas Instruments - - @ref arm-cm_blinky_ek-tm4c123gxl - - @ref arm-cm_dpp_ek-tm4c123gxl - - @ref arm-cm_game_efm32-slstk3401a - - @ref arm-cr_blinky_launchxl2-tms57012 - - @ref arm-cr_dpp_launchxl2-tms57012 - - @ref lwip_ek-lm3s6965 - -@ifnot LATEX -@nav_next{exa_native} -@endif -*/ diff --git a/doxygen/exa_mware.dox b/doxygen/exa_mware.dox deleted file mode 100644 index ae85e250..00000000 --- a/doxygen/exa_mware.dox +++ /dev/null @@ -1,52 +0,0 @@ -/*! @page exa_mware Examples for Third-Party Middleware - -- @subpage exa_lwip -- @subpage exa_emwin - -*/ -/*##########################################################################*/ -/*! @page exa_lwip lwIP TCP/IP - -- @subpage lwip_ek-lm3s6965 - -*/ -/*##########################################################################*/ -/*! @page lwip_ek-lm3s6965 lwIP on EK-LM3S6965 - -@image html bd_EK-LM3S6965.jpg -@image latex bd_EK-LM3S6965.jpg width=2.0in -@caption{EK-LM3S6965} - -lwIP example for Texas Instruments EK-LM3S6965 (Cortex-M3) with GNU-ARM and IAR-ARM toolsets. - -@image html bd_EK-LM3S6965_lwip.jpg -@image latex bd_EK-LM3S6965_lwip.jpg width=2.0in -@caption{QP-lwIP on EK-LM3S6965} -
- -@section lwip_AN Application Note: QP and lwIP TCP/IP Stack -The [Application Note](https://www.state-machine.com/doc/AN_QP_and_lwIP.pdf) describes how to use the lightweight TCP/IP stack called lwIP with the QP real-time embedded frameworks. - -@image html AN-QL.png -@image latex AN-QL.png width=2in -@caption{Application Note: QP and lwIP TCP/IP} - -@ifnot LATEX -@nav_next{exa_emwin} -@endif -*/ - -/*##########################################################################*/ -/*! @page exa_emwin emWin Embedded GUI - -The Application Note "QP and emWin Embedded GUI" describes how to use QP™ with the emWin™ Embedded GUI from SEGGER and also µC/GUI from Micrium, which technically are the same products. - -@image html emWin_demo.jpg -@image latex emWin_demo.jpg width=4.0in -@caption{QP-emWin demo (DPP) running on Windows} - -To demonstrate the working examples, this Application Note uses the emWin Simulation on Windows, which is available for a free download from the SEGGER (requires registration). You need only a Windows-based PC to execute the examples provided in this Application Note. Additionally, you'd need Microsoft Visual Studio 2013 (could be the free Express Edition) or higher to re-build and debug the provided examples. - -@note -Although the QP-emWin (µC/GUI) integration runs on Windows, the application-level code uses exclusively the embedded emWin™ API and is designed to run without any modifications on embedded targets. -*/ diff --git a/doxygen/exa_native.dox b/doxygen/exa_native.dox deleted file mode 100644 index 8f1294b2..00000000 --- a/doxygen/exa_native.dox +++ /dev/null @@ -1,680 +0,0 @@ -/*##########################################################################*/ -/*! @page exa_native Native Examples (Built-in Kernels) - -The QP/C framework contains real-time kernels (@ref comp_qv and @ref comp_qk), so it can run natively ("bare-metal") on single-chip microcontrollers, completely replacing a traditional RTOS. Click on the following links to see examples for the specified built-in kernels: - -- @subpage exa_qv -- @subpage exa_qk -- @subpage exa_qxk - - -Click on the following links to see examples for the specified CPU architectures: - -- @subpage exa_arm-cm -- @subpage exa_arm-cr -- @subpage exa_arm7-9 -- @subpage exa_msp430 - -*/ -/*##########################################################################*/ -/*! @page exa_qv QV Kernel (Non-Preemptive, Priority-Based, Non-Blocking) - -@ifnot LATEX -@remark -You can hover the mouse cursor over the    icon in the list below to see the picture of the board. -@endif - -- @ref arm-cm_blinky_ek-tm4c123gxl -- @ref arm-cm_blinky_efm32-slstk3401a -- @ref arm-cm_dpp_ek-tm4c123gxl -- @ref arm-cm_dpp_efm32-slstk3401a -- @ref arm-cm_dpp_mbed-lpc1768 -- @ref arm-cm_dpp_nucleo-l053r8 -- @ref arm-cm_dpp_nucleo-l152re -- @ref arm-cm_dpp_stm32f4-discovery -- @ref arm-cm_dpp_nucleo-h743zi -- @ref arm-cm_dpp_nucleo-l552ze -- @ref arm-cm_game_efm32-slstk3401a -- @ref tut_low -- @ref arm-cr_blinky_launchxl2-tms57012 -- @ref arm-cr_dpp_launchxl2-tms57012 -- @ref msp430_blinky_msp-exp430f5529lp -- @ref msp430_dpp_msp-exp430f5529lp -*/ -/*##########################################################################*/ -/*! @page exa_qk QK Kernel (Preemptive, Run-To-Completion/Non-Blocking) - -@ifnot LATEX -@remark -You can hover the mouse cursor over the    icon in the list below to see the picture of the board. -@endif - -- @ref arm-cm_blinky_ek-tm4c123gxl -- @ref arm-cm_blinky_efm32-slstk3401a -- @ref arm-cm_dpp_ek-tm4c123gxl -- @ref arm-cm_dpp_efm32-slstk3401a -- @ref arm-cm_dpp_mbed-lpc1768 -- @ref arm-cm_dpp_nucleo-l053r8 -- @ref arm-cm_dpp_nucleo-l152re -- @ref arm-cm_game_efm32-slstk3401a -- @ref arm-cm_dpp_stm32f4-discovery -- @ref arm-cm_dpp_nucleo-h743zi -- @ref arm-cm_dpp_nucleo-l552ze -- @ref tut_low -- @ref arm-cr_blinky_launchxl2-tms57012 -- @ref arm-cr_dpp_launchxl2-tms57012 -- @ref msp430_blinky_msp-exp430f5529lp -- @ref msp430_dpp_msp-exp430f5529lp - -*/ -/*##########################################################################*/ -/*! @page exa_qxk QXK Kernel (Preemptive, Run-To-Completion/Blocking) - -@ifnot LATEX -@remark -You can hover the mouse cursor over the    icon in the list below to see the picture of the board. -@endif - -- @ref arm-cm_dpp_ek-tm4c123gxl -- @ref arm-cm_dpp_efm32-slstk3401a -- @ref arm-cm_dpp_stm32f4-discovery -- @ref arm-cm_dpp_nucleo-l552ze -- @ref arm-cm_dpp_nucleo-h743zi -- @ref tut_low - -*/ -/*##########################################################################*/ -/*! @page exa_arm-cm ARM Cortex-M (Cortex-M0/M0+/M3/M4/M7/M33) - -@ifnot LATEX -@remark -You can hover the mouse cursor over the    icon in the list below to see the picture of the board. -@endif - -- @subpage arm-cm_blinky_ek-tm4c123gxl -- @subpage arm-cm_blinky_efm32-slstk3401a -- @subpage arm-cm_dpp_ek-tm4c123gxl -- @subpage arm-cm_dpp_efm32-slstk3401a -- @subpage arm-cm_dpp_mbed-lpc1768 -- @subpage arm-cm_dpp_nucleo-l053r8 -- @subpage arm-cm_dpp_nucleo-l152re -- @subpage arm-cm_dpp_stm32f4-discovery -- @subpage arm-cm_dpp_nucleo-h743zi -- @subpage arm-cm_dpp_nucleo-l552ze -- @subpage arm-cm_game_efm32-slstk3401a -- @ref tut_low -*/ -/*##########################################################################*/ -/*! @page exa_arm-cr ARM Cortex-R - -@ifnot LATEX -@remark -You can hover the mouse cursor over the    icon in the list below to see the picture of the board. -@endif - -- @subpage arm-cr_blinky_launchxl2-tms57012 -- @subpage arm-cr_dpp_launchxl2-tms57012 -*/ -/*##########################################################################*/ -/*! @page exa_msp430 MSP430 ("classic" MSP430 and "extended" MSP430x) - -@ifnot LATEX -@remark -You can hover the mouse cursor over the    icon in the list below to see the picture of the board. -@endif - - -- @subpage msp430_blinky_msp-exp430f5529lp -- @subpage msp430_dpp_msp-exp430f5529lp -*/ - -/*##########################################################################*/ -/*! @page arm-cm_blinky_ek-tm4c123gxl Blinky on EK-TM4C123GXL - -This example implements the @ref blinky "Blinky sample application" on the EK-TM4C123GLX board (ARM Cortex-M4F). - -@image html bd_EK-TM4C123GXL.jpg -@image latex bd_EK-TM4C123GXL.jpg width=2.5in -@caption{EK-TM4C123GXL (TivaC LaunchPad)} - -The Blinky example is located in the directory qpc/examples/arm-cm/blinky_ek-tm4c123gxl, which is organized as follows: - -
-@code{.c} - qpc/ // QP/C installation directory - +-examples/ // QP/C examples directory (application) - | +-arm-cm/ // QP/C examples for ARM Cortex-M - | | +-blinky_ek-tm4c123gxl/ // Blinky example on the EK-TM4C123GLX board - | | | +-qk/ // QK version - | | | | +-armclang/ // ARM-KEIL with arm-clang (compiler 6) - | | | | | +-blinky-qk.uvprojx // uVision project - | | | | +-gnu/ // GNU-ARM toolchain - | | | | | +-Makefile // Makefile for building the project - | | | | +-iar/ // IAR-ARM toolchain - | | | | | +-blinky-qk.eww // IAR EW-ARM workspace - | | | | +-bsp.c // BSP for the QK kernel - | | | +-qv/ // QV version - | | | | +-armclang/ // ARM-KEIL with arm-clang (compiler 6) - | | | | | +-blinky-qk.uvprojx // uVision project - | | | | +-gnu/ // GNU-ARM toolchain - | | | | | +-Makefile // Makefile for building the project with GNU-ARM - | | | | +-iar/ // IAR-ARM toolchain - | | | | | +-blinky-qk.eww // IAR EW-ARM workspace - | | | | +-bsp.c // BSP for the QV kernel -@endcode - - -@section arm-cm_blinky_ek-tm4c123gxl_feat Features Demonstrated -- cooperative QV kernel - + with ARM-KEIL toolchain - + with GNU-ARM toolchain - + with IAR-ARM toolchain -- preemptive run-to-completion QK kernel - + with ARM-KEIL toolchain - + with GNU-ARM toolchain - + with IAR-ARM toolchain -- Windows emulation (console multithreaded) -- Windows emulation (console, single threaded: win32-qv) - - -@section arm-cm_blinky_ek-tm4c123gxl_run Running the Example -Once programmed into the board, the example blinks the on-board LED about once a second. - -@image html bd_EK-TM4C123GXL.jpg -@image latex bd_EK-TM4C123GXL.jpg width=2.5in -@caption{EK-TM4C123GXL (TivaC LaunchPad)} - - -@section arm-cm_blinky_ek-tm4c123gxl_win Windows Emulation -The Windows emulation is a simple console application that produces the following output: - -@image html blinky_win32.png -@image latex blinky_win32.png width=4.5in -@caption{Blinky emulation running in a Windows console} - -@ifnot LATEX -@nav_next{arm-cm_blinky_efm32-slstk3401a} -@endif -*/ -/*##########################################################################*/ -/*! @page arm-cm_blinky_efm32-slstk3401a Blinky on EFM32-SLSTK3401A - -This example implements the @ref blinky "Blinky sample application" on the EFM32-SLSTK3401A board (ARM Cortex-M4F). - -@image html bd_EFM32-SLSTK3401A.jpg -@image latex bd_EFM32-SLSTK3401A.jpg width=4.5in -@caption{EFM32-SLSTK3401A (Pearl-Gecko)} - -The Blinky example is located in the directory qpc/examples/arm-cm/blinky_efm32-slstk3401a, which is organized as follows: - -@code{c} - qpc/ // QP/C installation directory - +-examples/ // QP/C examples directory (application) - | +-arm-cm/ // QP/C examples for ARM Cortex-M - | | +-blinky_efm32-slstk3401a/ // Blinky example on the EFM32-SLSTK3401A board - | | | +-qk/ // QK version - | | | | +-armclang/ // ARM-KEIL with arm-clang (compiler 6) - | | | | | +-blinky-qk.uvprojx // uVision project - | | | | +-gnu/ // GNU-ARM toolchain - | | | | | +-Makefile // Makefile for building the project - | | | | +-iar/ // IAR-ARM toolchain - | | | | | +-blinky-qk.eww // IAR EW-ARM workspace - | | | | +-bsp.c // BSP for the QK kernel - | | | +-qv/ // QV version - | | | | +-armclang/ // ARM-KEIL with arm-clang (compiler 6) - | | | | | +-blinky-qk.uvprojx // uVision project - | | | | +-gnu/ // GNU-ARM toolchain - | | | | | +-Makefile // Makefile for building the project with GNU-ARM - | | | | +-iar/ // IAR-ARM toolchain - | | | | | +-blinky-qk.eww // IAR EW-ARM workspace - | | | | +-bsp.c // BSP for the QV kernel - | | | +-win32/ // Windows emulation (multithreaded) - | | | | +-Makefile // Makefile for building the project with MinGW - | | | | +-bsp.c // BSP for the Win32 - | | | +-win32-qv/ // Windows emulation (single thread) - | | | | +-Makefile // Makefile for building the project with MinGW - | | | | +-bsp.c // BSP for the Win32-QV -@endcode - - -@section arm-cm_blinky_efm32-slstk3401a_feat Features Demonstrated -- cooperative QV kernel - + with ARM-KEIL toolchain - + with GNU-ARM toolchain - + with IAR-ARM toolchain -- preemptive run-to-completion QK kernel - + with ARM-KEIL toolchain - + with GNU-ARM toolchain - + with IAR-ARM toolchain -- Windows emulation (console multithreaded) -- Windows emulation (console, single threaded: win32-qv) - - -@section arm-cm_blinky_efm32-slstk3401a_run Running the Example -Once programmed into the board, the example blinks the on-board LED about once a second. - - -@section arm-cm_blinky_efm32-slstk3401a_win Windows Emulation -The Windows emulation is a simple console application that produces the following output: - -@image html blinky_win32.png -@image latex blinky_win32.png width=4.5in -@caption{Blinky emulation running in a Windows console} - -@ifnot LATEX -@nav_next{arm-cm_dpp_ek-tm4c123gxl} -@endif -*/ -/*##########################################################################*/ -/*! @page arm-cm_dpp_ek-tm4c123gxl DPP on EK-TM4C123GXL - -This example implements the @ref dpp "Dining Philosophers Problem" sample application on the EK-TM4C123GLX board (ARM Cortex-M4F). - -@image html bd_EK-TM4C123GXL.jpg -@image latex bd_EK-TM4C123GXL.jpg width=2.5in -@caption{EK-TM4C123GXL (TivaC LaunchPad)} - -The DPP example is located in the directory qpc/examples/arm-cm/dpp_ek-tm4c123gxl, which is organized as follows: - -
-@code{.c} - qpc/ // QP/C installation directory - +-examples/ // QP/C examples directory (applications) - | +-arm-cm/ // QP/C examples for ARM Cortex-M - | | +-dpp_ek-tm4c123gxl/ // DPP example on the EK-TM4C123GLX board - | | | +-lint/ // PC-Lint version (static analysis of the application code) - | | | | +-lin.bat // batch file for running the PC-Lint - | | | | +-options.lnt // PC-Lint options file for the DPP application code - | | | +-qk/ // QK version - | | | | +-armclang/ // ARM-KEIL with arm-clang (compiler 6) - | | | | | +-dpp-qk.uvprojx // uVision project - | | | | +-gnu/ // GNU-ARM toolchain - | | | | | +-Makefile // Makefile for building the project - | | | | +-iar/ // IAR-ARM toolchain - | | | | | +-dpp-qk.eww // IAR EW-ARM workspace - | | | | +-ti/ // TI-ARM toolchain (CCS) - | | | | | +-.ccsproject // CCS project - | | | | | +-.cproject // C Eclipse project - | | | | | +-.project // Eclipse project - | | | | +-bsp.c // BSP for the QK kernel - | | | | +-main.c // main() for the QK kernel - | | | +-qv/ // QV version - | | | | +-armclang/ // ARM-KEIL with arm-clang (compiler 6) - | | | | | +-dpp-qk.uvprojx // uVision project - | | | | +-gnu/ // GNU-ARM toolchain - | | | | | +-Makefile // Makefile for building the project with GNU-ARM - | | | | +-iar/ // IAR-ARM toolchain - | | | | | +-blinky-qk.eww // IAR EW-ARM workspace - | | | | +-bsp.c // BSP for the QV kernel - | | | | +-main.c // main() for the QV kernel - | | | +-qxk/ // QXK version - | | | | +-armclang/ // ARM-KEIL with arm-clang (compiler 6) - | | | | | +-dpp-qk.uvprojx // uVision project - | | | | +-gnu/ // GNU-ARM toolchain - | | | | | +-Makefile // Makefile for building the project - | | | | +-iar/ // IAR-ARM toolchain - | | | | | +-dpp-qk.eww // IAR EW-ARM workspace - | | | | +-ti/ // TI-ARM toolchain (CCS) - | | | | | +-.ccsproject // CCS project - | | | | | +-.cproject // C Eclipse project - | | | | | +-.project // Eclipse project - | | | | +-bsp.c // BSP for the QXK kernel - | | | | +-main.c // main() for the QXK kernel - | | | | +-test.c // extended (blocking) test threads - | | | +-qspyview/ // visualization and monitoring for the DPP example - | | | | +-dpp.py // QSpyView specialization for the DPP - | | | | +-qspyview.bat // batch file for launching QSpyView for DPP -@endcode - - -@section arm-cm_dpp_ek-tm4c123gxl_feat Features Demonstrated -- cooperative QV kernel - + with ARM-KEIL toolchain (arm-clang/compiler 6) - + with GNU-ARM toolchain - + with IAR-ARM toolchain - + with TI-ARM toolchain (CCS) -- preemptive run-to-completion QK kernel - + with ARM-KEIL toolchain (arm-clang/compiler 6) - + with GNU-ARM toolchain - + with IAR-ARM toolchain - + with TI-ARM toolchain (CCS) -- preemptive dual-mode QXK kernel - + with ARM-KEIL toolchain (arm-clang/compiler 6) - + with GNU-ARM toolchain - + with IAR-ARM toolchain - + with TI-ARM toolchain (CCS) -- QP/Spy software tracing (output) -- QP/Spy software tracing (input QS-RX) -- Unit Testing with QUTest -- Windows emulation with GUI (multithreaded) -- Windows emulation with GUI (single threaded, win32-qv) - - -@section arm-cm_dpp_ek-tm4c123gxl_run Running the Example -Once programmed into the board, the example rapidly toggles the Blue LED from the idle loop (blue LED glows) and toggles the Red and Green LEDs as the Philosophers change their state. Additionally, you can depress and hold the SW1 button (left) to PAUSE the application (Table transitions into the "paused" state). Releasing the SW1 button causes transition back to the "serving" state. - - -@section arm-cm_dpp_ek-tm4c123gxl_qutest Unit Testing -The examples demonstrates the QUTest unit tests for the application. - - -@section arm-cm_dpp_ek-tm4c123gxl_spy QP/Spy Software Tracing -The application also demonstrates QP/Spy software tracing output and input. To exercise this feature, you need to build and upload the Spy build configuration into the board. - -*/ -/*##########################################################################*/ -/*! @page arm-cm_dpp_efm32-slstk3401a DPP on EFM32-SLSTK3401A - -

This example implements the @ref dpp "Dining Philosophers Problem" sample application on the EFM32-SLSTK3401A board (ARM Cortex-M4F). -

- -@image html bd_EFM32-SLSTK3401A.jpg -@image latex bd_EFM32-SLSTK3401A.jpg width=4.5in -@caption{EFM32-SLSTK3401A (Pearl-Gecko)} - -The DPP example is located in the directory qpc/examples/arm-cm/dpp_efm32-slstk3401a and includes versions for @ref srs_qv "cooperative QV kernel", the @ref srs_qk "preemptive QK kernel", and the @ref srs_qxk "preemptive dual mode QXK RTOS kernel" each provided for the ARM-KEIL, GNU-ARM, and IAR-ARM. The following annotated directory listing describes the contents of the example folder: - -
-@code{.c} - qpc/ // QP/C installation directory - +-examples/ // QP/C examples directory (application) - | +-arm-cm/ // QP/C examples for ARM Cortex-M - | | +-dpp_efm32-slstk3401a/ // DPP example on the EK-TM4C123GLX board - | | | +-lint/ // PC-Lint version (static analysis of the application code) - | | | | +-lin.bat // batch file for running the PC-Lint - | | | | +-options.lnt // PC-Lint options file for the DPP application code - | | | +-qk/ // QK version - | | | | +-armclang/ // ARM-KEIL with arm-clang (compiler 6) - | | | | | +-dpp-qk.uvprojx // uVision project - | | | | +-gnu/ // GNU-ARM toolchain - | | | | | +-Makefile // Makefile for building the project - | | | | +-iar/ // IAR-ARM toolchain - | | | | | +-dpp-qk.eww // IAR EW-ARM workspace - | | | | +-bsp.c // BSP for the QK kernel - | | | | +-main.c // main() for the QK kernel - | | | +-qv/ // QV version - | | | | +-armclang/ // ARM-KEIL with arm-clang (compiler 6) - | | | | | +-dpp-qk.uvprojx // uVision project - | | | | +-gnu/ // GNU-ARM toolchain - | | | | | +-Makefile // Makefile for building the project with GNU-ARM - | | | | +-iar/ // IAR-ARM toolchain - | | | | | +-blinky-qk.eww // IAR EW-ARM workspace - | | | | +-bsp.c // BSP for the QV kernel - | | | | +-main.c // main() for the QV kernel - | | | +-qxk/ // QXK version - | | | | +-armclang/ // ARM-KEIL with arm-clang (compiler 6) - | | | | | +-dpp-qk.uvprojx // uVision project - | | | | +-gnu/ // GNU-ARM toolchain - | | | | | +-Makefile // Makefile for building the project - | | | | +-iar/ // IAR-ARM toolchain - | | | | | +-dpp-qk.eww // IAR EW-ARM workspace - | | | | +-bsp.c // BSP for the QXK kernel - | | | | +-main.c // main() for the QXK kernel - | | | | +-test.c // extended (blocking) test threads - | | | +-qspyview/ // visualization and monitoring for the DPP example - | | | | +-dpp.py // QSpyView specialization for the DPP - | | | | +-qspyview.bat // batch file for launching QSpyView for DPP -@endcode - - -@section arm-cm_dpp_efm32-slstk3401a_feat Features Demonstrated -- cooperative QV kernel - + with ARM-KEIL toolchain - + with GNU-ARM toolchain - + with IAR-ARM toolchain -- preemptive run-to-completion QK kernel - + with ARM-KEIL toolchain - + with GNU-ARM toolchain - + with IAR-ARM toolchain -- preemptive dual-mode QXK kernel - + with ARM-KEIL toolchain - + with GNU-ARM toolchain - + with IAR-ARM toolchain -- QP/Spy software tracing (output) -- QP/Spy software tracing (input QS-RX) -- Unit Testing with QUTest -- Windows emulation with GUI (multithreaded) -- Windows emulation with GUI (single threaded, win32-qv) - - -@section arm-cm_dpp_efm32-slstk3401a_run Running the Example -Once programmed into the board, the example rapidly toggles the LED1 from the idle loop (LED1 glows) and toggles LED0 as the Philosophers change their state. Additionally, you can depress and hold the BTN0 button (left) to PAUSE the application (Table transitions into the "paused" state). Releasing the BTN0 button causes transition back to the "serving" state. - - -@section arm-cm_dpp_efm32-slstk3401a_spy QP/Spy Software Tracing -The application also demonstrates QP/Spy software tracing output and input. To exercise this feature, you need to build and upload the Spy build configuration into the board. - -*/ -/*##########################################################################*/ -/*! @page arm-cm_dpp_mbed-lpc1768 DPP on mbed-LPC1768 - -@image html bd_mbed-LPC1768.jpg -@image latex bd_mbed-LPC1768.jpg width=2.5in -@caption{mbed-LPC1768} - -Dining Philosophers Problem (DPP) example for NXP LPC1768 MCU (Cortex-M3) with GNU-ARM toolchain. - -@image html mbed-LPC1768_button.jpg -@image latex mbed-LPC1768_button.jpg width=3.0in -@captionAdding External Button to mbed-LPC1768{} - -@image html under-constr.png -@image latex under-constr.png width=1in -*/ - -/*##########################################################################*/ -/*! @page arm-cm_dpp_nucleo-l053r8 DPP on STM32 NUCLEO-L053R8 - -@image html bd_NUCLEO-L053R8.jpg -@image latex bd_NUCLEO-L053R8.jpg width=2.5in -@caption{NUCLEO-L053R8} - -@ref dpp "Dining Philosophers Problem (DPP)" example for STM32 NUCLEO-L053R8 MCU (Cortex-M0+). - -Demonstrated built-in kernels: -- cooperative @ref srs_qv with ARM-Clang, ARM-Keil, GNU-ARM (Makefile and Atollic TRUEstudio), and IAR-ARM toolchains -- preemptive, run-to-completion @ref srs_qk with ARM-Clang, ARM-Keil, GNU-ARM, and IAR-ARM toolchains -- dual-mode (run-to-completion/blocking) @ref srs_qxk with ARM-Clang, ARM-Keil, GNU-ARM, and IAR-ARM toolchains - - -Features: -- multiple active objects, including 5 instances of the same AO class (Philo) -- extended threads (the QXK version) -- [QP/Spy software tracing](https://www.state-machine.com/qtools/qpspy.html) using the virtual COM-port - -*/ -/*##########################################################################*/ -/*! @page arm-cm_dpp_nucleo-l152re DPP on STM32 NUCLEO-L152RE - -@image html bd_NUCLEO-L152RE.jpg -@image latex bd_NUCLEO-L152RE.jpg width=2.4in -@caption{NUCLEO-L152RE} - -@ref dpp "Dining Philosophers Problem (DPP)" example for STM32 NUCLEO-L152RE MCU (Cortex-M3). - -Demonstrated built-in kernels: -- cooperative @ref srs_qv with ARM-Clang, ARM-Keil, GNU-ARM, and IAR-ARM toolchains -- preemptive, run-to-completion @ref srs_qk with ARM-Clang, ARM-Keil, GNU-ARM, and IAR-ARM toolchains - - -Features: -- multiple active objects, including 5 instances of the same AO class (Philo) -- [QP/Spy software tracing](https://www.state-machine.com/qtools/qpspy.html) using the virtual COM-port - -*/ - -/*##########################################################################*/ -/*! @page arm-cm_dpp_stm32f4-discovery DPP on STM32F4-Discovery - -The @ref dpp "DPP example" for STM32F4-Discovery board is located directory examples/arm-cm/dpp_stm32f4-discovery. - -@image html bd_STM32F4-Disco.jpg -@image latex bd_STM32F4-Disco.jpg width=2.8in -@caption{STM32F4-Discovery} - -Demonstrated built-in kernels: -- cooperative @ref srs_qv with ARM-Keil, GNU-ARM, and IAR-ARM toolchains -- preemptive, run-to-completion @ref srs_qk with ARM-Keil, GNU-ARM, and IAR-ARM toolchains -- dual-mode (run-to-completion/blocking) @ref srs_qxk with ARM-Keil, GNU-ARM, and IAR-ARM toolchains - - -Features: -- multiple active objects, including 5 instances of the same AO class (Philo) -- extended threads (the QXK version) -- [QP/Spy software tracing](https://www.state-machine.com/qtools/qpspy.html) using the virtual COM-port -- bi-directional [QP/Spy](https://www.state-machine.com/qtools/qs.html#qs_rx) (sending commands to the target) - - -After you load the DPP example into the STM32F4-Discovery board, the application should start blinking the 4 on-board LEDs. You can press the User button (blue) to PAUSE the philosophers for as long as the button is depressed. The philosophers resume dining when you release the User button. (In the PAUSED state the Table active object stops granting permissions to eat, so eventually all philosophers end in the "hungry" state.) - - -@section arm-cm_dpp_stm32f4-discovery_qs QS Software Tracing -The DPP example for embOS on STM32F4-Discovery board provides the "Spy" build configuration, which outputs the QS (Quantum Spy) software tracing data through USART2. To get the data out of the board, you need to connect the TTL/RS232 converter as follows: - -
-STM32F4-Discovery | TTL/RS232 Converter --------------------|:------------------------ -PA2 | TX -PA3 | RX (currently not used) -VDD | VCC -GND | GND -
- -@image html bd_STM32F4-Disco_RS232.jpg -@image latex bd_STM32F4-Disco_RS232.jpg width=3.5in -@caption{STM32F4-Discovery board connected to RS232 level shifter} - -The output is generated at 115200 baud rate. - -Here is an example invocation of the QSPY host application to receive the QS data from STM32F4-Discovery: - -@verbatim -qspy -cCOM1 -@endverbatim - -The actual COM port number might be different on your Windows machine. Please check the Device Manager to find the COM port number. - -@ifnot LATEX -@nav_next{arm-cm_dpp_nucleo-l552ze} -@endif -*/ - -/*##########################################################################*/ -/*! @page arm-cm_dpp_nucleo-h743zi DPP on STM32 NUCLEO-H743ZI - -@image html bd_NUCLEO-H743ZI.jpg -@image latex bd_NUCLEO-H743ZI.jpg width=4.5in -@caption{NUCLEO-H743ZI} - -@ref dpp "Dining Philosophers Problem (DPP)" example for STM32 NUCLEO-H743ZI MCU (Cortex-M7). - -Demonstrated built-in kernels: -- cooperative @ref srs_qv with ARM-Clang, ARM-Keil, GNU-ARM (Makefile and Atollic TRUEstudio), and IAR-ARM toolchains -- preemptive, run-to-completion @ref srs_qk with ARM-Clang, ARM-Keil, GNU-ARM, and IAR-ARM toolchains -- dual-mode (run-to-completion/blocking) @ref srs_qxk with ARM-Clang, ARM-Keil, GNU-ARM, and IAR-ARM toolchains - -Features: -- multiple active objects, including 5 instances of the same AO class (Philo) -- extended threads (the QXK version) -- [QP/Spy software tracing](https://www.state-machine.com/qtools/qpspy.html) using the virtual COM-port -- bi-directional [QP/Spy](https://www.state-machine.com/qtools/qs.html#qs_rx) (sending commands to the target) - -*/ - -/*##########################################################################*/ -/*! @page arm-cm_dpp_nucleo-l552ze DPP on STM32 NUCLEO-L552ZE Q - -@image html bd_NUCLEO-L552ZE.jpg -@image latex bd_NUCLEO-L552ZE.jpg width=3.5in -@caption{STM32 NUCLEO-L552ZE Q} - -@ref dpp "Dining Philosophers Problem (DPP)" example for STM32 NUCLEO-L552ZE Q (Cortex-M33). - -Demonstrated built-in kernels: -- cooperative @ref srs_qv with ARM-Clang, ARM-Keil, GNU-ARM (Makefile and Atollic TRUEstudio), and IAR-ARM toolchains -- preemptive, run-to-completion @ref srs_qk with ARM-Clang, ARM-Keil, GNU-ARM, and IAR-ARM toolchains -- dual-mode (run-to-completion/blocking) @ref srs_qxk with ARM-Clang, ARM-Keil, GNU-ARM, and IAR-ARM toolchains - -Features: -- multiple active objects, including 5 instances of the same AO class (Philo) -- extended threads (the QXK version) -- [QP/Spy software tracing](https://www.state-machine.com/qtools/qpspy.html) using the virtual COM-port -- bi-directional [QP/Spy](https://www.state-machine.com/qtools/qs.html#qs_rx) (sending commands to the target) - -*/ - -/*##########################################################################*/ -/*! @page arm-cm_game_efm32-slstk3401a "Fly 'n' Shoot" Game on EFM32-SLSTK3401A - -@image html bd_EFM32-SLSTK3401A.jpg -@image latex bd_EFM32-SLSTK3401A.jpg width=4.5in -@caption{EFM32-SLSTK3401A (Pearl-Gecko)} - -"Fly 'n' Shoot" game example for Silicon Labs Pearl Gecko MCU (Cortex-M4F), ARM (MDK-ARM), GNU-ARM, IAR EWARM toolchains. - -@image html qwin_ani.gif "Fly 'n' Shoot game running on Windows" -@image latex qwin_static.jpg "Fly 'n' Shoot game running on Windows" - -@image html under-constr.png -@image latex under-constr.png width=0.93in -*/ - -/*##########################################################################*/ -/*! @page arm-cr_blinky_launchxl2-tms57012 Blinky on LAUNCHXL2-TMS57012 - -@image html bd_LAUNCHXL2-TMS57012.jpg -@image latex bd_LAUNCHXL2-TMS57012.jpg width=4.0in -@caption{LAUNCHXL2-TMS57012} - -@ref blinky "Blinky" example for LAUNCHXL2-TMS57012 MCU (Cortex-R, Hercules) with IAR-ARM and TI toolchains. - -@image html under-constr.png -@image latex under-constr.png width=0.93in -*/ -/*##########################################################################*/ -/*! @page arm-cr_dpp_launchxl2-tms57012 DPP on LAUNCHXL2-TMS57012 - -@image html bd_LAUNCHXL2-TMS57012.jpg -@image latex bd_LAUNCHXL2-TMS57012.jpg width=4.0in -@caption{LAUNCHXL2-TMS57012} - -Dining Philosophers Problem (DPP) example for LAUNCHXL2-TMS57012 MCU (Cortex-R, Hercules) with IAR-ARM and TI toolchains. - -@image html under-constr.png -@image latex under-constr.png width=0.93in -*/ - -/*##########################################################################*/ -/*! @page msp430_blinky_msp-exp430f5529lp Blinky on MSP-EXP430F5529LP - -@image html bd_MSP-EXP430F5529LP.jpg -@image latex bd_MSP-EXP430F5529LP.jpg width=2.5in -@caption{MSP-EXP430F5529LP} - -Simple Blinky example for MSP-EXP430F5529LP with CCS-430 and IAR-430 toolchains. The application blinks the LED1 (P1.0) once per second. The LED2 is rapidly toggled from the idle callback, which results in a "glow" with intensity proportional to the frequency of calling the idle callback. - -@note -The simple Blinky application does NOT support the Spy build configuration. Please see the @ref msp430_dpp_msp-exp430f5529lp "DPP example" for QS output. - - -*/ -/*##########################################################################*/ -/*! @page msp430_dpp_msp-exp430f5529lp DPP on MSP-EXP430F5529LP - -@image html bd_MSP-EXP430F5529LP.jpg -@image latex bd_MSP-EXP430F5529LP.jpg width=2.5in -@caption{MSP-EXP430F5529LP} - -DPP example for MSP-EXP430F5529LP with CCS-430 and IAR-430 toolchains. The application blinks the LED1 (P1.0) when a Philosopher gets a permission to "eat". The LED2 is rapidly toggled from the idle callback, which results in a "glow" with intensity proportional to the frequency of calling the idle callback. - -@section msp430_dpp_msp-exp430f5529lp_qs QS Output -This example demonstrates the QS software tracing output in the Spy build configuration. QS uses the hardware UART1 of the MSP-EXP430F5529LP board connected to the Virtual COM Port on the debugger. This means that you don't need any additional wiring to receive the QS output on your development workstation. - -The QS trace date requires the following setting of the QSPY host utility - -@verbatim -qspy -c -O2 -F2 -E1 -P1 -B1 -@endverbatim - -where `` denotes the Virtual COM port, which you can find out in the Device Manager. -*/ diff --git a/doxygen/exa_os.dox b/doxygen/exa_os.dox deleted file mode 100644 index 308e2fff..00000000 --- a/doxygen/exa_os.dox +++ /dev/null @@ -1,142 +0,0 @@ -/*! @page exa_os Examples for Workstations (Windows/POSIX) - -

The examples in the qpc/examples/workstation directory are designed for workstations (running Windows, Linux, or MacOS). Currently, the following examples are provided: -

- -- blinky — Simple "Blinky" active object (command-line) -- calc — Calculator example from Chapter 2 of [PSiCC2](https://www.state-machine.com/psicc2) -- calc1 — Improved Calculator example from Chapter 2 of [PSiCC2](https://www.state-machine.com/psicc2) -- calc1_sub — Calculator example with sub-machines -- comp — Orthogonal Component design pattern -- defer — Deferred Event design pattern -- dpp — DPP application from Chapter 9 of [PSiCC2](https://www.state-machine.com/psicc2) (**Spy**) -- dpp_comp — DPP with Orthogonal-Component pattern (**Spy**) -- dpp-gui — DPP (with GUI on Windows) (**Spy**) -- game-gui — "Fly 'n' Shoot" game from Chapter 1 of [PSiCC2](https://www.state-machine.com/psicc2) (**Spy**) -- history_qhsm — Transition-to-History (with ::QHsm class) -- history_qmsm — Transition-to-History (with ::QMsm class) -- qhsmtst — Test State Machine based on ::QHsm from Chapter 2 of [PSiCC2](https://www.state-machine.com/psicc2) (**Spy**) -- qmsmtst — Test State Machine based on ::QMsm (**Spy**) -- reminder — Reminder design pattern from Chapter 5 of PSiCC2 -- reminder2 — Reminder design pattern different version - -@remark -The examples marked with (**Spy**) provide the @ref exa_os-spy "Spy Configuration". - - - -@section exa_win_posix Windows and POSIX Workstations -All examples in the qpc/examples/workstation directory work both on Windows as well as on POSIX (Linux, MacOS). On each of these operating systems you use the same cross-platform `Makefile` co-located with each example. The provided cross-platform `Makefiles` assume the **GNU GCC toolchain**. The `Makefile` discovers the host operating system and chooses the appropriate QP port version: - -- On Windows — @ref win32 "win32" or @ref win32-qv "win32-qv"; and -- On POSIX — @ref posix "posix" or @ref posix-qv "posix-qv" (Linux, MacOS, etc.) - -@note -On Windows, the **make** utility and the GNU GCC toolchain (**MinGW**) are provided in the [QTools collection](https://www.state-machine.com/qtools), which is available for a separate download. The code can be also built with other tools as well, such as the Microsoft Visual Studio 2013 and newer. - - -@image html blinky_win32.png -@image latex blinky_win32.png width=4.0in -@caption{Blinky example on Windows} - -
-@image html blinky_posix.png -@image latex blinky_posix.png width=4.0in -@caption{Blinky example on Linux} - - -@section exa_os-qv Single-Threaded and Multi-Threaded QP/C Ports -Each of the examples can be linked to either the single-threaded QP/C ports (@ref win32-qv or @ref posix-qv) or multi-threaded ports (@ref win32 or @ref posix). The choice is made in the `Makefiles`, by editing the line, which defines the `QP_PORT_DIR` symbol. For instance, the following lines select the @ref win32-qv port and leave the @ref win32 port commented-out: - -
-@verbatim -QP_PORT_DIR := $(QPC)/ports/win32-qv -#QP_PORT_DIR := $(QPC)/ports/win32 -@endverbatim - -To reverse the selection, you need to move the comment `#` character. - -@remarks -The single-threaded QP/C ports (@ref win32-qv "win32-qv" and @ref posix-qv "posix-qv") are recommended for **emulating** software intended for deeply-embedded targets ("dual-targeting" the embedded software development).@n - - -@attention -Examples in the workstation directory can also be used on the **embedded versions** of the desktop operating systems, such as **Embedded Linux** and **Windows Embedded**. For the embedded applications, the **multi-threaded** @ref ports_os "QP ports" ( @ref posix "posix" and @ref win32 "win32", respectively) are recommended. - - - -@section exa_os_conf Debug, Release, and Spy Build Configurations -The `Makefiles` for the examples generally support the following three build configurations. - - - -@subsection exa_os-dbg Debug Configuration -This is the default build configuration, with full debugging information and minimal optimization. To build this configuration, type: - -
-@verbatim -make -@endverbatim - -To clean this build, type - -@verbatim -make clean -@endverbatim - -The object files and the executable is located in the build sub-directory. - - - -@subsection exa_os-rel Release Configuration -This configuration is built with no debugging information and high optimization. Single-stepping and debugging might be difficult due -to the lack of debugging information and optimized code. To build this configuration, type: - -@verbatim -make CONF=rel -@endverbatim - -To clean this build, type - -@verbatim -make CONF=rel clean -@endverbatim - -The object files and the executable is located in the build_rel directory. - - -@subsection exa_os-spy Spy Configuration -This configuration is built with the QP's Q-SPY trace functionality. The QP/Spy output is performed by a TCP/IP socket and requires launching the QSPY host application with the -t option. To build this configuration, type: - -@verbatim -make CONF=spy -@endverbatim - -To clean this build, type - -@verbatim -make CONF=spy clean -@endverbatim - -The object files and the executable are located in the build_spy sub-directory. - -@note -The Spy build configuration requires launching the [QSPY host utility](https://www.state-machine.com/qtools/qspy.html) with the `-t` command-line option **before** running the example. This is so that the example code can output the QS software tracing to the TCP/IP socket of QSPY. - - -@remark -Only specific examples support the Spy build configuration. The examples that don't support it, will report an error or will fail the linking stage. - -@image html dpp_win.png -@image latex dpp_win.png width=5.0in -@caption{DPP with QSPY example on Windows (QSPY running in a separate command-prompt)} - -
-@image html dpp_posix.png -@image latex dpp_posix.png width=6.0in -@caption{DPP with QSPY example on Linux (QSPY running in a separate command-prompt)} - -@ifnot LATEX -@nav_next{exa_mware} -@endif -*/ diff --git a/doxygen/exa_qutest.dox b/doxygen/exa_qutest.dox deleted file mode 100644 index 08238252..00000000 --- a/doxygen/exa_qutest.dox +++ /dev/null @@ -1,140 +0,0 @@ -/*! @page exa_qutest Examples for QUTest Unit Testing Harness - -

The examples in the qpc/examples/qutest directory demonstrate how to test embedded code with the [QUTest](https://www.state-machine.com/qtools/qutest.html) unit testing harness. Currently, the following examples are provided: -

- -- blinky — Simple "Blinky" single-active-object application -- dpp — DPP application from Chapter 9 of PSiCC2 -- evt-par — testing events with parameters -- qhsmtst — Test State Machine based on ::QHsm with QM model -- qmsmtst — Test State Machine based on ::QMsm with QM model -- unity_basic — Comparison of a basic testing with Unity and QUTest -- unity_mock — Comparison of a advanced testing (mocking) with Unity and QUTest - - -@section exa_qutest-dir General Code Organization -The projects within the examples/qutest directory have the customary structure used for testing. The production code to be tested is located in the src sub-directory. The testing code is located in the test_~~~ sub-folder(s). The following directory tree illustrates the structure for the `dpp` example: - -
    -
  • examples/ -
  • -
      -
    • qutest/ — Examples for QUTest unit testing harness -
    • -
        -
      • dpp/ — The simple Blinky example -
      • -
          -
        • src/ — source code under test       A -
        • -
            -
          • bsp.h — BSP header -
          • -
          • dpp.h — DPP header -
          • -
          • dpp.qm — DPP model -
          • -
          • philo.c — `Philo` active object -
          • -
          • table.c — `Table` active object -
          • -
          -
        -
          -
        • test_philo/ — code for unit testing of `Philo` AO        B -
        • -
            -
          • Makefile — cross-platform makefile (host) -
          • -
          • test_philo.c — test fixture for `Philo` AO -
          • -
          • test_philo.py — test script for `Philo` (Python) -
          • -
          -
        -
          -
        • test_table/ — code for unit testing of `Table` AO        B -
        • -
            -
          • Makefile — cross-platform makefile (host) -
          • -
          • test_philo.c — test fixture for `Table` AO -
          • -
          • test_philo.py — test script for `Table` (Python) -
          • -
          -
        -
          -
        • test_dpp/ — code for unit testing of DPP application        C -
        • -
            -
          • Makefile — cross-platform makefile (host) -
          • -
          • make_efm32 — makefile for the EFM32 **embedded board** -
          • -
          • make_tm4c123 — makefile for the TM4C123 **embedded board** -
          • -
          • main.c — `main()` function for DPP application -
          • -
          • test_dpp.c — test fixture for DPP application -
          • -
          • test_init.py — test script for DPP initialization (Python) -
          • -
          • test_tick.py — test script for DPP tick processing (Python) -
          • -
          -
        -
      • ~~~/ — Other QUTest examples~~~ -
      • -
      • target_efm32/ — Code for the **embedded target** (EFM32)         D -
      • -
      • target_tm4c123/ — Code for the **embedded target** (TM4C123)        D -
      • -
      -
    -
- -
    -
  • A The src sub-directory contains the production code to be tested. This directory contains the .qm model file as well as the generated code from the model. -
  • - -
  • B The test_philo sub-directory contains the unit test code for a component, such as `Philo` in this case. Here, you can find the test_*.c **test fixture**, the test scripts test_*.py (Python) as well as the cross-platform Makefile to build the code and *run* the tests on the host. -
  • - -
  • C The test_dpp sub-directory contains integration-test code for the application, such as `DPP` in this case. The objective is to test the initialization and interactions *among* components. Here, you can find the main.c `main()` function as well as the test_dpp.c *test fixture*. This directory also contains make_* *makefiles* to build and run the code on the **embedded targets**. -
  • - -
  • D The target_efm32 sub-directory contains the Code needed to build and run the test code on the **embedded target**, like EFM32 in this case. -
  • -
- - -@section exa_qutest-test Building and Running the Tests -As usual in Test-Driven Development (TDD), the provided Makefiles both *build* the code and *run* the tests. - - -@subsection exa_qutest_host Host Computers -Typically, you start testing on your host computer. Before building/running the code, you need to open a terminal window and launch the [QSPY host application](https://www.state-machine.com/qtools/qspy.html) with the `-t` [command-line option](https://www.state-machine.com/qtools/qspy.html#qspy_command). - -Next, you open another terminal window, change directory to the test_~~~ folder of interest, and type `make`. This will build the application and run the tests (Python), as shown in the screen shot below: - -@image html qutest_py.png -@image latex qutest_py.png width=6.5in -@caption{Testing on the host (Python)} - - -@subsection exa_qutest_target Embedded Targets -The QUTest testing system allows you also to easily test the code directly on the embedded target board. The dpp/test_dpp/ directory illustrates this option by providing the `makefiles` for embedded boards, such as the TM4C123 (Tiva LaunchPad) make_tm4c123. - -To test the code on an embedded board, you need to connect the board to the host computer and launch the and launch the [QSPY host application](https://www.state-machine.com/qtools/qspy.html) with the `-c COM` [command-line option](https://www.state-machine.com/qtools/qspy.html#qspy_command), where `` is the specific COM port number on your host that the board is using. - -Next, you open another terminal window, change directory to the test_~~~ folder of interest, and type `make -f make_tm4c123`. This will build the application and run the tests (Python), as shown in the screen shot below: - -@image html qutest_tm4c123_py.png -@image latex qutest_tm4c123_py.png width=6.5in -@caption{Testing on the TM4C123 embedded target (Python)} - -@ifnot LATEX -@nav_next{exa_os} -@endif -*/ diff --git a/doxygen/exa_rtos.dox b/doxygen/exa_rtos.dox deleted file mode 100644 index 66ef2114..00000000 --- a/doxygen/exa_rtos.dox +++ /dev/null @@ -1,684 +0,0 @@ -/*##########################################################################*/ -/*! @page exa_rtos Examples for Third-Party RTOS - -The main purpose of integrating QP/C with conventional RTOSes is to enable you to incorporate various communication stacks (TCP/IP, USB, CAN, etc.) as well as other middleware, which requires the ability to **block** the task code. Currently the following 3rd-party RTOSes are supported: - -- @subpage exa_embos (directory examples/embos/) -- @subpage exa_freertos (directory examples/freertos/) -- @subpage exa_threadx (directory examples/threadx/) -- @subpage exa_uc-os2 (directory examples/uc-os2/) -- @subpage exa_zephyr (directory examples/zephyr/) - -@note -You do **not** need to use a third-party RTOS just to achieve preemptive multitasking with QP/C. The framework contains a selection of built-in real-time kernels, such as the cooperative @ref srs_qv "QV kernel", the preemptive non-blocking @ref srs_qk "QK kernel", and the preemptive, dual-mode, blocking @ref srs_qxk "QXK kernel". Specifically, the QXK kernel has been designed specifically for mixing event-driven active objects with traditional **blocking code**, such as commercial middleware (TCP/IP stacks, UDP stacks, embedded file systems, etc.) or legacy software. - -@ifnot LATEX -@nav_next{exa_embos} -@endif -*/ - -/*##########################################################################*/ -/*! @page exa_embos embOS - -The QP/C examples for SEGGER embOS are as follows: - -- ARM Cortex-M - - @subpage embos_dpp_nucleo-h743zi (Cortex-M7)
(GNU-ARM and IAR EWARM toolsets) - -@note -You can hover the mouse cursor over the    icon in the list below to see the picture of the board. - -@ifnot LATEX -@nav_next{embos_dpp_nucleo-h743zi} -@endif -*/ -/*##########################################################################*/ -/*! @page embos_dpp_nucleo-h743zi DPP on NUCLEO-H743ZI - -The @ref dpp "DPP example" for embOS on NUCLEO-H743ZI board is located directory examples/embos/arm-cm/dpp_nucleo-h743zi. - -@image html bd_NUCLEO-H743ZI.jpg -@image latex bd_NUCLEO-H743ZI.jpg width=4.5in -@caption{NUCLEO-H743ZI} - -@ref dpp "Dining Philosophers Problem (DPP)" example for NUCLEO-H743ZI MCU (Cortex-M7). - - -Toolsets: -- GNU-ARM in directory examples/embos/arm-cm/dpp_nucleo-h743zi/gnu. Makefile provided. - -@verbatim -make -make CONF=rel -make CONF=spy -@endverbatim - -- IAR EWARM in directory examples/embos/arm-cm/dpp_nucleo-h743zi/iar. Workspace `dpp.eww` provided. - -Features: -- embOS RTOS kernel -- BSP with embOS-specific: OS_TICK_HOOK, OS_Idle(), "kernel unaware" ISRs -- multiple active objects, including 5 instances of the same AO class (Philo) -- [QP/Spy software tracing](https://www.state-machine.com/qtools/qpspy.html) using the virtual COM-port -- bi-directional [QP/Spy](https://www.state-machine.com/qtools/qs.html#qs_rx) (sending commands to the target) - -The output is generated at 115200 baud rate. - -Here is an example invocation of the QSPY host application to receive the QS data from NUCLEO-H743ZI: - -@verbatim -qspy -c COM4 -@endverbatim - -The actual COM port number might be different on your Windows machine. Please check the Device Manager to find the COM port number. - -@ifnot LATEX -@nav_next{exa_freertos} -@endif -*/ - -/*##########################################################################*/ -/*! @page exa_freertos FreeRTOS - -The QP/C examples for FreeRTOS are as follows: - -- ARM Cortex-M - - @subpage freertos_dpp_ek-tm4c123gxl (Cortex-M4F)
(ARM-KEIL, GNU-ARM and IAR EWARM toolchains) - - @subpage freertos_dpp_stm32f746g-disco (Cortex-M7)
(ARM-KEIL, GNU-ARM and IAR EWARM toolchains) - - @subpage freertos_dpp_nucleo-h743zi (Cortex-M7)
(ARM-KEIL, GNU-ARM and IAR EWARM toolchains) - - @subpage freertos_start-stop_nucleo-h743zi (Cortex-M7)
(ARM-KEIL, GNU-ARM and IAR EWARM toolchains) - -@note -You can hover the mouse cursor over the    icon in the list below to see the picture of the board. - -@ifnot LATEX -@nav_next{exa_os} -@endif -*/ -/*##########################################################################*/ -/*! @page freertos_dpp_ek-tm4c123gxl DPP on EK-TM4C123GXL - -@image html bd_EK-TM4C123GXL.jpg -@image latex bd_EK-TM4C123GXL.jpg width=2.5in -@caption{EK-TM4C123GXL (TivaC LaunchPad)} - -@ref dpp "DPP example" for @ref freertos "FreeRTOS" on Texas Instruments TivaC123GXL MCU (Cortex-M4F) with the following toolchains: -- ARM-Keil -- GNU-ARM -- IAR-ARM - -Demonstrated features: -- Multiple Active Objects -- Regular "kernel-aware" ISR with "FromISR" APIs - + `QF_TICK_X_FROM_ISR()` - + `QF_PUBLISH_FROM_ISR()` - + `Q_NEW_FROM_ISR()` - + `QACTIVE_POST_FROM_ISR()` -- Hi-priority "kernel-unaware" ISR -- `vApplicationTickHook()` -- QP/Spy output over the virtual COM port (Spy build configuration) -- QP/Spy input over the virtual COM port (bi-directional Spy) (Spy build configuration) - - -@ifnot LATEX -@nav_next{freertos_dpp_stm32f746g-disco} -@endif -*/ -/*##########################################################################*/ -/*! @page freertos_dpp_stm32f746g-disco DPP on STM32F746G-Discovery - -@image html bd_STM32F746G-Disco.jpg -@image latex bd_STM32F746G-Disco.jpg width=4.75in -@caption{STM32F746G-Discovery} - -@ref dpp "DPP example" for @ref freertos "FreeRTOS" on STM32F746G-Discovery MCU (Cortex-M7) with the following toolchains: -- ARM-Keil -- GNU-ARM -- IAR-ARM - -Demonstrated features: -- Multiple Active Objects -- Regular "kernel-aware" ISR with "FromISR" APIs - + `QF_TICK_X_FROM_ISR()` - + `QF_PUBLISH_FROM_ISR()` - + `Q_NEW_FROM_ISR()` - + `QACTIVE_POST_FROM_ISR()` -- Hi-priority "kernel-unaware" ISR -- `vApplicationTickHook()` -- QP/Spy output over the virtual COM port (Spy build configuration) -- QP/Spy input over the virtual COM port (bi-directional Spy) (Spy build configuration) - -@ifnot LATEX -@nav_next{freertos_dpp_nucleo-h743zi} -@endif -*/ -/*##########################################################################*/ -/*! @page freertos_dpp_nucleo-h743zi DPP on NUCLEO-H743ZI - -@image html bd_NUCLEO-H743ZI.jpg -@image latex bd_NUCLEO-H743ZI.jpg width=4.5in -@caption{NUCLEO-H743ZI} - -@ref dpp "Dining Philosophers Problem (DPP)" example for NUCLEO-H743ZI MCU (Cortex-M7). - -Features: -- multiple active objects, including 5 instances of the same AO class (Philo) -- [QP/Spy software tracing](https://www.state-machine.com/qtools/qpspy.html) using the virtual COM-port -- bi-directional [QP/Spy](https://www.state-machine.com/qtools/qs.html#qs_rx) (sending commands to the target) - -@ifnot LATEX -@nav_next{freertos_start-stop_nucleo-h743zi} -@endif -*/ -/*##########################################################################*/ -/*! @page freertos_start-stop_nucleo-h743zi Start-Stop on NUCLEO-H743ZI - -@image html bd_NUCLEO-H743ZI.jpg -@image latex bd_NUCLEO-H743ZI.jpg width=4.5in -@caption{NUCLEO-H743ZI} - -Start-Stop example for NUCLEO-H743ZI MCU (Cortex-M7) demonstrates staring and stopping active objects multiple times -during the runtime, as opposed to starting AOs only at the beginning. - -The code for the example is generated automatically by the [QM Model-Based Design tool](https://www.state-machine.com/products/qm/) (QM version 4.5.0 or higher). - -The start-stop application consists of two AOs: - -- the Launcher AO is started at the beginning and its job is to periodically (re)start another AO - -- the Worker AO is NOT started at the beginning, but instead it is instantiated and started by the Launcher AO. - - -@image html start-stop.png -@image latex start-stop.png width=5.0in -@caption{Launcher and Worker state machines} - - -The actual visible work is performed by the Worker AO, which blinks the yellow LED (LD1) on the NUCLEO-H743ZI board. After blinking the LED five times, the Worker AO publishes turns the blue LED (LD2), publishes the DONE event and stops itself (by calling QP::QActive::stop() on itself). - -The Launcher AO subscribes to the DONE event. Upon reception of this event, The Launcher AO gives the Worker a bit of time (at least one clock tick) to cleanly terminate and then it explicitly destroys the Worker. The Worker destructor turns the blue LED (LD2) off. - -Next the Launcher instantiates the Worker AO by means of the placement new operator and then it starts it again to repeat the cycle, which goes no forever. - - -@remarks -Because this application is intended for embedded real-time systems, it does not use the dynamic memory (heap). Instead it uses statically allocated memory (static mode of FreeRTOS) as well as **placement-new** and explicit destructor call. - - -It is possible to use the standard **new** and **delete** operators with the standard heap, or some customized memory allocation (overloaded new/delete). This goes beyond the scope of this example. - - -**Supported Toolchains**
-This example contains sub-directories for building it with various toolchains. The following toolchains are supported: - -- ARM-Keil MDK -- GNU-ARM -- IAR EWARM - -Please refer to the README.txt files in these sub-directories for more information about building and running the examples. - - -**QP/Spy Support**
-This example demonstrates the [QP/Spy software tracing](https://www.state-machine.com/qtools/qpspy.html) in the **Spy build configuration**. The QP/Spy uses the virtual COM port provided by the NUCLEO-H743ZI board. To see the QP/Spy output, you need to launch the qspy host utility, as follows (Windows command prompt): - -@verbatim -qspy -u -c COM4 -@endverbatim - -where COM4 is the particular virtual serial port registered by your NUCLEO board. You need to adjust the COM port number for your machine. - - -**Programming the NUCLEO Board**
-The NUCLEO boards appear as a USB-flash drive in the file system. Programming of the board is done by simply copying the binary into -thy flash drive letter. - -For example, assuming that the NUCLEO board appears as drive E:, you program it with the following command: - -@verbatim -copy dbg\start-stop.bin E: -@endverbatim - - -**Demonstrated Features** @n -- multiple active objects (Launcher and Worker) -- instantiating, starting and stopping active objects multiple times -- [QP/Spy software tracing](https://www.state-machine.com/qtools/qpspy.html) using the virtual COM-port -- bi-directional [QP/Spy](https://www.state-machine.com/qtools/qs.html#qs_rx) (sending commands to the target) - -@ifnot LATEX -@nav_next{exa_threadx} -@endif -*/ - -/*##########################################################################*/ -/*! @page exa_threadx ThreadX - -The QP/C examples for ThreadX (Express Logic) are as follows: - -- @subpage threadx_dpp_ek-tm4c123gxl (Cortex-M4F)
(IAR EWARM toolchain) -- @subpage threadx_dpp_stm32f429-discovery
(IAR EWARM toolchain) - -@note -You can hover the mouse cursor over the    icon in the list below to see the picture of the board. - -@ifnot LATEX -@nav_next{exa_uc-os2} -@endif -*/ -/*##########################################################################*/ -/*! @page threadx_dpp_ek-tm4c123gxl DPP on EK-TM4C123GXL - -@image html bd_EK-TM4C123GXL.jpg -@image latex bd_EK-TM4C123GXL.jpg width=2.5in -@caption{EK-TM4C123GXL (TivaC LaunchPad)} - -@ref dpp "DPP example" for ThreadX on Texas Instruments TivaC123GXL MCU (Cortex-M4F) with the following toolchain: -- IAR-ARM - -Demonstrated features: -- Multiple Active Objects -- QP/Spy output over the virtual COM port (Spy build configuration) -- QP/Spy input over the virtual COM port (bi-directional Spy) (Spy build configuration) - -@ifnot LATEX -@nav_next{threadx_dpp_stm32f429-discovery} -@endif -*/ -/*##########################################################################*/ -/*! @page threadx_dpp_stm32f429-discovery DPP on STM32F4-Discovery - -The @ref dpp "DPP example" for ThreadX on STM32F4-Discovery board is located directory examples/threadx/arm-cm/dpp_stm32f429-discovery. - -@image html bd_STM32F4-Disco.jpg -@image latex bd_STM32F4-Disco.jpg width=2.8in -@caption{STM32F4-Discovery} - -The sub-directory iar contains the workspace and project file that you can open in IAR EWARM IDE. - -After you load the DPP example into the STM32F4-Discovery board, the application should start blinking the 4 on-board LEDs. You can press the User button (blue) to PAUSE the philosophers for as long as the button is depressed. The philosophers resume dining when you release the User button. (In the PAUSED state the Table active object stops granting permissions to eat, so eventually all philosophers end in the "hungry" state.) - - -@section threadx_dpp_stm32f429-discovery_qs QS Software Tracing - -The DPP example for ThreadX on STM32F4-Discovery board provides the "Spy" build configuration, which outputs the QS (Quantum Spy) software tracing data through USART2. To get the data out of the board, you need to connect the TTL/RS232 converter as follows: - -
-STM32F4-Discovery | TTL/RS232 Converter --------------------|:------------------------ -PA2 | TX -PA3 | RX (currently not used) -VDD | VCC -GND | GND -
- -@image html bd_STM32F4-Disco.jpg -@image latex bd_STM32F4-Disco.jpg width=2.8in -@caption{STM32F4-Discovery} - -The output is generated at 115200 baud rate. - -Here is an example invocation of the QSPY host application to receive the QS data from STM32F4-Discovery: - -@verbatim -qspy -cCOM1 -@endverbatim - -The actual COM port number might be different on your Windows machine. Please check the Device Manager to find the COM port number. - -@ifnot LATEX -@nav_next{exa_uc-os2} -@endif -*/ - -/*##########################################################################*/ -/*! @page exa_uc-os2 uC-OS2 - -The QP/C examples for uC-OS2 are as follows: - -- ARM Cortex-M - - @subpage uc-os2_dpp_ek-tm4c123gxl (Cortex-M4F)
(ARM-CLANG, GNU-ARM and IAR EWARM toolsets) - - @subpage uc-os2_dpp_nucleo-l053r8 (Cortex-M0+)
(ARM-CLANG, GNU-ARM, and IAR EWARM toolsets) - -@note -You can hover the mouse cursor over the    icon in the list below to see the picture of the board. - -@ifnot LATEX -@nav_next{exa_os} -@endif -*/ -/*##########################################################################*/ -/*! @page uc-os2_dpp_ek-tm4c123gxl DPP on EK-TM4C123GXL - -@image html bd_EK-TM4C123GXL.jpg -@image latex bd_EK-TM4C123GXL.jpg width=2.5in -@caption{EK-TM4C123GXL (TivaC LaunchPad)} - -DPP example for Texas Instruments TivaC123GXL MCU (Cortex-M4F) and ARM-CLANG, GNU-ARM and IAR EWARM toolsets. - -@image html under-constr.png -@image latex under-constr.png width=1in - -@ifnot LATEX -@nav_next{uc-os2_dpp_nucleo-l053r8} -@endif -*/ -/*##########################################################################*/ -/*! @page uc-os2_dpp_nucleo-l053r8 DPP on STM32-NUCLEO-L053R8 - -@image html bd_NUCLEO-L053R8.jpg -@image latex bd_NUCLEO-L053R8.jpg width=2.5in -@caption{NUCLEO-L053R8} - -DPP example for STM32 L053R8 MCU (Cortex-M0+) and ARM-CLANG, GNU-ARM and IAR EWARM toolsets. - -@image html under-constr.png -@image latex under-constr.png width=1in - -@ifnot LATEX -@nav_next{exa_zephyr} -@endif -*/ - -/*##########################################################################*/ -/*! @page exa_zephyr Zephyr - -The QP/C examples for Zephyr are as follows: - -- @subpage zephyr_blinky -- @subpage zephyr_dpp - -@ifnot LATEX -@nav_next{zephyr_blinky} -@endif -*/ -/*##########################################################################*/ -/*! @page zephyr_blinky Blinky - -The "Blinky" example blinks an on-board LED once per second. The blinking is done by an Active Object (Blinky) with a state machine. The example directory contains the following files: - -@verbatim -/examples/zephyr/blinky - | - +-src/ - project sources - | | - | +-bsp.h - | +-bsp.c - | +-blinky.h - | +-blinky.c - | +-main.c - | - +-CMakeLists.txt - project files - +-prj.conf - project config - +-README.md -@endverbatim - - -@section zephyr_blinky-build Building and Running - -- Linux: - -@verbatim -[1] cd /examples/zephyr/blinky - -[2] source ~/zephyrproject/zephyr/zephyr-env.sh - -[3] west build -b -[3a] west build -b nucleo_h743zi -[3b] west build -b nucleo_l053r8 -... - -[4] west flush -@endverbatim - -`[1]` Open a terminal in the Blinky example directory.
-`[2]` If Zephyr project is not in your path, you might need to source the `zephyr-env.sh` shell script.
-`[3]` build the example project, where `` is any of the boards supported by Zepyr. The example has been tested with the following boards:
-`[3a]` nucleo_h743zi (ARM Cortex-M7)
-`[3b]` nucleo_l053r8 (ARM Cortex-M0+)
-`[4]` flash the board - -@remark -The example has been tested with the following boards: - -@image html bd_NUCLEO-L053R8.jpg -@image latex bd_NUCLEO-L053R8.jpg width=2.5in -@caption{NUCLEO-L053R8} - -
- -@image html bd_NUCLEO-H743ZI.jpg -@image latex bd_NUCLEO-H743ZI.jpg width=4.5in -@caption{NUCLEO-H743ZI} - -@note -The example should also work with most boards supported by Zephyr. - - -@section zephyr_blinky-output Sample Output -Once flashed to the board, the application also produces ASCII output to the serial terminal (if supported by the board): - -@verbatim -*** Booting Zephyr OS build v2.6.0-rc2-88-g3d39f72a88b3 *** -BSP_ledOff -QF_onStartup -BSP_ledOn -BSP_ledOff -BSP_ledOn -BSP_ledOff -@endverbatim - -@section zephyr_blinky-limits Limitations -The simple Blinky example does not support the QS software tracing. - -@ifnot LATEX -@nav_next{zephyr_dpp} -@endif -*/ -/*##########################################################################*/ -/*! @page zephyr_dpp DPP - -DPP example with multiple active objects. - -@verbatim -/examples/zephyr/dpp - | - +-src/ - project sources - | | - | +-bsp.h - | +-bsp.c - | +-dpp.h - | +-philo.c - | +-table.c - | +-main.c - | - +-CMakeLists.txt - project files - +-prj.conf - project config - +-README.md -@endverbatim - -@section zephyr_dpp-build Building and Running - -- Linux: - -@verbatim -[1] cd /examples/zephyr/dpp - -[2] source ~/zephyrproject/zephyr/zephyr-env.sh - -[3] west build -b -[3a] west build -b nucleo_h743zi -[3b] west build -b nucleo_l053r8 -... - -[4] west flush -@endverbatim - -`[1]` Open a terminal in the DPP example directory.
-`[2]` If Zephyr project is not in your path, you might need to source the `zephyr-env.sh` shell script.
-`[3]` build the example project, where `` is any of the boards supported by Zepyr. The example has been tested with the following boards:
-`[3a]` nucleo_h743zi (ARM Cortex-M7)
-`[3b]` nucleo_l053r8 (ARM Cortex-M0+)
-`[4]` flash the board - -@remark -The example has been tested with the following boards: - -@image html bd_NUCLEO-L053R8.jpg -@image latex bd_NUCLEO-L053R8.jpg width=2.5in -@caption{NUCLEO-L053R8} - -
- -@image html bd_NUCLEO-H743ZI.jpg -@image latex bd_NUCLEO-H743ZI.jpg width=4.5in -@caption{NUCLEO-H743ZI} - -@note -The example should also work with most boards supported by Zephyr. - - -@section zephyr_dpp-output Sample Output -Once flashed to the board, the application also produces ASCII output to the serial terminal (if supported by the board): - -@verbatim -*** Booting Zephyr OS build v2.6.0-rc2-88-g3d39f72a88b3 *** -Philo[4]->thinking -Philo[3]->eating -Philo[1]->thinking -Philo[0]->eating -Philo[4]->hungry -Philo[3]->thinking -Philo[2]->eating -Philo[1]->hungry -Philo[0]->thinking -Philo[4]->eating -Philo[3]->hungry -Philo[0]->hungry -Philo[4]->thinking -Philo[0]->eating -Philo[2]->thinking -Philo[3]->eating -Philo[4]->hungry -Philo[2]->hungry -Philo[3]->thinking -Philo[2]->eating -Philo[0]->thinking -@endverbatim - - -@section zephyr_dpp-qpspy Using the QP/SPY Software Tracing -The @ref zephyr "QP/C Zephyr port" supports the -[QSPY Software Tracing](https://www.state-machine.com/qtools/qpspy.html) -option and will add the appropriate macros and files to build the "QSPY" -configuration. - -If you wish to enable "QSPY" you can provide the option "QSPY" -in the command-line for the build. For example: - -@verbatim -west build -b nucleo_h743zi -- -DQSPY=ON -@endverbatim - -@note -The QP/Spy software tracing uses the Zephyr's console UART. This means that the Zephyr `printk()` facility cannot be used while QP/Spy is configured. - - -If yo have built the example with QP/Spy, you might want to watch the QP/Spy output. - - -@section zephyr_dpp-qspy The QSPY Host Utility -To receive the QP/Spy software tracing output you need to run a special [qspy host application](https://www.state-machine.com/qtools/qspy.html). - -@note -You might need to build the `qspy` host utility on your Linux machine. The QSPY utility is available in -[QTools collection](https://github.com/QuantumLeaps/qtools/tree/master/qspy). - - -To launch the `qspy` host utility, open a separate terminal and run -@verbatim -qspy -c -``` -specific example: -``` -qspy -c /dev/ttyACM0 -@endverbatim - - -@subsection zephyr_dpp-qs-output QSPY Output Example -After resetting the board, you should see output similar to the following: -@verbatim -########## Trg-RST QP-Ver=701,Build=220810_150847 - Obj-Dict 0x20003154->QS_RX - Obj-Dict 0x20000680->AO_Table - Obj-Dict 0x20000180->AO_Philo[0] - Obj-Dict 0x20000280->AO_Philo[1] - Obj-Dict 0x20000380->AO_Philo[2] - Obj-Dict 0x20000480->AO_Philo[3] - Obj-Dict 0x20000580->AO_Philo[4] - Obj-Dict 0x0000A52C->timerID - Usr-Dict 00000100->PHILO_STAT - Usr-Dict 00000101->PAUSED_STAT - Usr-Dict 00000102->COMMAND_STAT - Usr-Dict 00000103->CONTEXT_SW - Obj-Dict 0x20003054->EvtPool1 - Obj-Dict 0x20000180->Philo_inst[0] - Obj-Dict 0x2000026C->Philo_inst[0].m_timeEvt - Obj-Dict 0x20000280->Philo_inst[1] - Obj-Dict 0x2000036C->Philo_inst[1].m_timeEvt - Obj-Dict 0x20000380->Philo_inst[2] - Obj-Dict 0x2000046C->Philo_inst[2].m_timeEvt - Obj-Dict 0x20000480->Philo_inst[3] - Obj-Dict 0x2000056C->Philo_inst[3].m_timeEvt - Obj-Dict 0x20000580->Philo_inst[4] - Obj-Dict 0x2000066C->Philo_inst[4].m_timeEvt - Fun-Dict 0x00008929->Philo_initial - Fun-Dict 0x0000890F->Philo_thinking - Fun-Dict 0x00008917->Philo_hungry - Fun-Dict 0x0000891F->Philo_eating - Sig-Dict 00000004,Obj=0x00000000->TIMEOUT_SIG -0000000327 AO-Subsc Obj=Philo_inst[0],Sig=00000005,Obj=0x20000180 -0000000327 AO-Subsc Obj=Philo_inst[0],Sig=00000009,Obj=0x20000180 -===RTC===> St-Init Obj=Philo_inst[0],State=0x00009B1B->Philo_thinking -===RTC===> St-Entry Obj=Philo_inst[0],State=Philo_thinking -0000000328 Init===> Obj=Philo_inst[0],State=Philo_thinking -0000000334 AO-Subsc Obj=Philo_inst[1],Sig=00000005,Obj=0x20000280 -0000000334 AO-Subsc Obj=Philo_inst[1],Sig=00000009,Obj=0x20000280 -===RTC===> St-Init Obj=Philo_inst[1],State=0x00009B1B->Philo_thinking -===RTC===> St-Entry Obj=Philo_inst[1],State=Philo_thinking -0000000334 Init===> Obj=Philo_inst[1],State=Philo_thinking -0000000340 AO-Subsc Obj=Philo_inst[2],Sig=00000005,Obj=0x20000380 -0000000340 AO-Subsc Obj=Philo_inst[2],Sig=00000009,Obj=0x20000380 -===RTC===> St-Init Obj=Philo_inst[2],State=0x00009B1B->Philo_thinking -===RTC===> St-Entry Obj=Philo_inst[2],State=Philo_thinking -0000000340 Init===> Obj=Philo_inst[2],State=Philo_thinking -0000000346 AO-Subsc Obj=Philo_inst[3],Sig=00000005,Obj=0x20000480 -0000000346 AO-Subsc Obj=Philo_inst[3],Sig=00000009,Obj=0x20000480 -===RTC===> St-Init Obj=Philo_inst[3],State=0x00009B1B->Philo_thinking -===RTC===> St-Entry Obj=Philo_inst[3],State=Philo_thinking -0000000346 Init===> Obj=Philo_inst[3],State=Philo_thinking -0000000352 AO-Subsc Obj=Philo_inst[4],Sig=00000005,Obj=0x20000580 -0000000352 AO-Subsc Obj=Philo_inst[4],Sig=00000009,Obj=0x20000580 -===RTC===> St-Init Obj=Philo_inst[4],State=0x00009B1B->Philo_thinking -===RTC===> St-Entry Obj=Philo_inst[4],State=Philo_thinking -0000000352 Init===> Obj=Philo_inst[4],State=Philo_thinking - Obj-Dict 0x20000680->Table::inst - Sig-Dict 00000006,Obj=0x00000000->DONE_SIG - Sig-Dict 00000005,Obj=0x00000000->EAT_SIG - Sig-Dict 00000007,Obj=0x00000000->PAUSE_SIG - Sig-Dict 00000008,Obj=0x00000000->SERVE_SIG - Sig-Dict 00000009,Obj=0x00000000->TEST_SIG - Sig-Dict 00000011,Obj=0x20000680->HUNGRY_SIG -0000000370 AO-Subsc Obj=Table::inst,Sig=DONE_SIG -0000000370 AO-Subsc Obj=Table::inst,Sig=PAUSE_SIG -0000000370 AO-Subsc Obj=Table::inst,Sig=SERVE_SIG -0000000371 AO-Subsc Obj=Table::inst,Sig=TEST_SIG -0000000371 PHILO_STAT 0 thinking -0000000371 PHILO_STAT 1 thinking -0000000371 PHILO_STAT 2 thinking -0000000371 PHILO_STAT 3 thinking -@endverbatim - -@ifnot LATEX -@nav_next{exa_os} -@endif -*/ diff --git a/doxygen/gen/metrics.txt b/doxygen/gen/metrics.txt deleted file mode 100644 index 8955a3e9..00000000 --- a/doxygen/gen/metrics.txt +++ /dev/null @@ -1,174 +0,0 @@ -@code{.c} -================================================ - NLOC CCN token PARAM length location ------------------------------------------------- - 3 1 16 1 3 QHsm_state@410-412@..\include\qep.h - 3 1 15 1 3 QEQueue_getNFree@306-308@..\include\qequeue.h - 3 1 15 1 3 QEQueue_getNMin@323-325@..\include\qequeue.h - 3 1 21 1 3 QEQueue_isEmpty@342-344@..\include\qequeue.h - 5 2 33 1 8 QPSet_setEmpty@245-252@..\include\qf.h - 4 3 44 1 7 QPSet_isEmpty@255-261@..\include\qf.h - 4 3 44 1 7 QPSet_notEmpty@264-270@..\include\qf.h - 8 3 95 2 11 QPSet_hasElement@273-283@..\include\qf.h - 11 3 105 2 14 QPSet_insert@286-299@..\include\qf.h - 12 3 117 2 15 QPSet_remove@302-316@..\include\qf.h - 6 3 56 1 9 QPSet_findMax@319-327@..\include\qf.h - 6 1 20 2 6 QF_psInit@1405-1410@..\include\qf.h - 3 1 20 1 3 QEvt_refCtr_inc_@180-182@..\include\qf_pkg.h - 3 1 20 1 3 QEvt_refCtr_dec_@189-191@..\include\qf_pkg.h - 14 3 67 1 14 QS_rxPut@892-905@..\include\qs.h - 7 1 33 3 7 QHsm_reservedEvt_@90-96@..\src\qf\qep_hsm.c - 18 3 101 2 24 QHsm_isIn@103-126@..\src\qf\qep_hsm.c - 22 4 125 2 31 QHsm_childState@129-159@..\src\qf\qep_hsm.c - 12 2 57 2 14 QHsm_ctor@162-175@..\src\qf\qep_hsm.c - 7 1 29 2 7 QHsm_top@178-184@..\src\qf\qep_hsm.c - 55 10 386 3 82 QHsm_init_@187-268@..\src\qf\qep_hsm.c - 101 15 631 3 154 QHsm_dispatch_@271-424@..\src\qf\qep_hsm.c - 3 1 16 1 3 QHsm_getStateHandler_@428-430@..\src\qf\qep_hsm.c - 91 15 480 3 132 QHsm_tran_@434-565@..\src\qf\qep_hsm.c - 14 3 79 3 17 QHsm_state_entry_@568-584@..\src\qf\qep_hsm.c - 20 3 96 3 23 QHsm_state_exit_@587-609@..\src\qf\qep_hsm.c - 15 3 69 2 16 QMsm_isInState@81-96@..\src\qf\qep_msm.c - 3 1 17 1 3 QMsm_stateObj@99-101@..\src\qf\qep_msm.c - 31 7 153 2 38 QMsm_childStateObj@104-141@..\src\qf\qep_msm.c - 12 2 60 2 15 QMsm_ctor@144-158@..\src\qf\qep_msm.c - 27 4 202 3 45 QMsm_init_@161-205@..\src\qf\qep_msm.c - 118 19 740 3 169 QMsm_dispatch_@208-376@..\src\qf\qep_msm.c - 3 1 18 1 3 QMsm_getStateHandler_@380-382@..\src\qf\qep_msm.c - 55 9 317 3 70 QMsm_execTatbl_@386-455@..\src\qf\qep_msm.c - 24 4 132 4 33 QMsm_exitToTranSource_@458-490@..\src\qf\qep_msm.c - 45 6 243 3 56 QMsm_enterHistory_@493-548@..\src\qf\qep_msm.c - 82 14 431 4 122 QActive_post_@70-191@..\src\qf\qf_actq.c - 44 7 266 2 66 QActive_postLIFO_@196-261@..\src\qf\qf_actq.c - 34 3 233 1 44 QActive_get_@266-309@..\src\qf\qf_actq.c - 10 2 60 1 11 QF_getQueueMin@315-325@..\src\qf\qf_actq.c - 16 2 79 2 20 QTicker_ctor@344-363@..\src\qf\qf_actq.c - 10 1 45 3 11 QTicker_init_@366-376@..\src\qf\qf_actq.c - 16 2 90 3 18 QTicker_dispatch_@379-396@..\src\qf\qf_actq.c - 30 2 156 4 39 QTicker_post_@399-437@..\src\qf\qf_actq.c - 8 1 30 2 9 QTicker_postLIFO_@440-448@..\src\qf\qf_actq.c - 15 1 84 3 17 QActive_defer@65-81@..\src\qf\qf_defer.c - 34 3 169 2 54 QActive_recall@86-139@..\src\qf\qf_defer.c - 13 3 68 2 15 QActive_flushDeferred@144-158@..\src\qf\qf_defer.c - 17 3 116 3 26 QF_poolInit@86-111@..\src\qf\qf_dyn.c - 3 1 17 1 3 QF_poolGetMaxBlockSize@114-116@..\src\qf\qf_dyn.c - 9 3 59 1 12 QF_getPoolMin@119-130@..\src\qf\qf_dyn.c - 39 7 234 3 57 QF_newX_@133-189@..\src\qf\qf_dyn.c - 30 4 188 1 46 QF_gc@192-237@..\src\qf\qf_dyn.c - 20 3 99 2 30 QF_newRef_@240-269@..\src\qf\qf_dyn.c - 11 2 67 1 15 QF_deleteRef_@272-286@..\src\qf\qf_dyn.c - 32 5 233 4 50 QMPool_init@67-116@..\src\qf\qf_mem.c - 45 5 241 3 74 QMPool_get@119-192@..\src\qf\qf_mem.c - 19 3 117 3 28 QMPool_put@195-222@..\src\qf\qf_mem.c - 8 1 35 2 13 QActive_psInit@73-85@..\src\qf\qf_ps.c - 42 6 231 3 75 QActive_publish_@90-164@..\src\qf\qf_ps.c - 18 5 111 2 24 QActive_subscribe@169-192@..\src\qf\qf_ps.c - 18 5 111 2 27 QActive_unsubscribe@197-223@..\src\qf\qf_ps.c - 19 5 130 1 24 QActive_unsubscribeAll@228-251@..\src\qf\qf_ps.c - 10 2 46 2 10 QF_bzero@85-94@..\src\qf\qf_qact.c - 16 2 72 2 23 QActive_ctor@101-123@..\src\qf\qf_qact.c - 28 10 225 1 47 QActive_register_@128-174@..\src\qf\qf_qact.c - 10 3 79 1 15 QActive_unregister_@179-193@..\src\qf\qf_qact.c - 24 6 143 1 29 QF_LOG2@201-229@..\src\qf\qf_qact.c - 14 2 84 3 14 QEQueue_init@67-80@..\src\qf\qf_qeq.c - 57 8 301 4 78 QEQueue_post@83-160@..\src\qf\qf_qeq.c - 36 5 199 3 48 QEQueue_postLIFO@163-210@..\src\qf\qf_qeq.c - 38 4 219 2 50 QEQueue_get@213-262@..\src\qf\qf_qeq.c - 16 2 79 2 35 QMActive_ctor@74-108@..\src\qf\qf_qmact.c - 15 2 96 4 32 QTimeEvt_ctorX@78-109@..\src\qf\qf_time.c - 33 8 225 3 59 QTimeEvt_armX@112-170@..\src\qf\qf_time.c - 31 3 173 1 41 QTimeEvt_disarm@173-213@..\src\qf\qf_time.c - 36 8 230 2 64 QTimeEvt_rearm@216-279@..\src\qf\qf_time.c - 5 1 36 1 5 QTimeEvt_wasDisarmed@282-286@..\src\qf\qf_time.c - 7 1 30 1 8 QTimeEvt_currCtr@289-296@..\src\qf\qf_time.c - 69 7 380 2 112 QTimeEvt_tick_@299-410@..\src\qf\qf_time.c - 14 3 75 1 16 QTimeEvt_noActive@413-428@..\src\qf\qf_time.c - 21 2 112 1 31 QK_schedLock@74-104@..\src\qk\qk.c - 20 4 118 1 33 QK_schedUnlock@107-139@..\src\qk\qk.c - 11 3 101 1 23 QF_init@144-166@..\src\qk\qk.c - 3 1 10 1 4 QF_stop@169-172@..\src\qk\qk.c - 18 6 76 1 33 QF_run@175-207@..\src\qk\qk.c - 25 3 156 7 34 QActive_start_@214-247@..\src\qk\qk.c - 19 4 78 1 24 QK_sched_@252-275@..\src\qk\qk.c - 66 17 382 1 113 QK_activate_@278-390@..\src\qk\qk.c - 7 3 52 1 13 QF_init@73-85@..\src\qv\qv.c - 3 1 10 1 4 QF_stop@88-91@..\src\qv\qv.c - 46 15 251 1 97 QF_run@94-190@..\src\qv\qv.c - 18 1 124 7 25 QActive_start_@197-221@..\src\qv\qv.c - 23 3 131 1 34 QXK_schedLock@71-104@..\src\qxk\qxk.c - 20 4 118 1 33 QXK_schedUnlock@107-139@..\src\qxk\qxk.c - 12 3 110 1 24 QF_init@144-167@..\src\qxk\qxk.c - 3 1 10 1 4 QF_stop@170-173@..\src\qxk\qxk.c - 20 6 98 1 35 QF_run@176-210@..\src\qxk\qxk.c - 29 5 178 7 42 QActive_start_@217-258@..\src\qxk\qxk.c - 42 8 220 1 53 QXK_sched_@266-318@..\src\qxk\qxk.c - 59 16 377 1 96 QXK_activate_@321-416@..\src\qxk\qxk.c - 12 2 72 1 18 QXK_current@419-436@..\src\qxk\qxk.c - 19 5 105 1 26 QXK_contextSw@440-465@..\src\qxk\qxk.c - 13 2 104 1 23 QXK_threadExit_@472-494@..\src\qxk\qxk.c - 10 2 64 2 13 QXMutex_init@74-86@..\src\qxk\qxk_mutex.c - 79 11 701 2 136 QXMutex_lock@89-224@..\src\qxk\qxk_mutex.c - 57 9 483 1 95 QXMutex_tryLock@227-321@..\src\qxk\qxk_mutex.c - 74 12 622 1 129 QXMutex_unlock@324-452@..\src\qxk\qxk_mutex.c - 9 1 51 3 11 QXSemaphore_init@73-83@..\src\qxk\qxk_sema.c - 57 7 389 2 84 QXSemaphore_wait@86-169@..\src\qxk\qxk_sema.c - 28 3 139 1 39 QXSemaphore_tryWait@172-210@..\src\qxk\qxk_sema.c - 42 7 275 1 66 QXSemaphore_signal@213-278@..\src\qxk\qxk_sema.c - 21 2 113 3 26 QXThread_ctor@74-99@..\src\qxk\qxk_xthr.c - 21 4 195 1 38 QXThread_delay@102-139@..\src\qxk\qxk_xthr.c - 14 2 68 1 16 QXThread_delayCancel@142-157@..\src\qxk\qxk_xthr.c - 58 7 493 1 85 QXThread_queueGet@160-244@..\src\qxk\qxk_xthr.c - 10 1 39 3 11 QXThread_init_@247-257@..\src\qxk\qxk_xthr.c - 10 1 39 3 11 QXThread_dispatch_@260-270@..\src\qxk\qxk_xthr.c - 31 7 216 7 52 QXThread_start_@273-324@..\src\qxk\qxk_xthr.c - 100 15 527 4 140 QXThread_post_@327-466@..\src\qxk\qxk_xthr.c - 8 1 30 2 9 QXThread_postLIFO_@469-477@..\src\qxk\qxk_xthr.c - 5 1 49 1 7 QXThread_block_@480-486@..\src\qxk\qxk_xthr.c - 8 3 56 1 8 QXThread_unblock_@489-496@..\src\qxk\qxk_xthr.c - 20 3 157 3 39 QXThread_teArm_@499-537@..\src\qxk\qxk_xthr.c - 11 2 46 1 13 QXThread_teDisarm_@540-552@..\src\qxk\qxk_xthr.c -33 file analyzed. -============================================================== -NLOC Avg.NLOC AvgCCN Avg.token function_cnt file --------------------------------------------------------------- - 6 0.0 0.0 0.0 0 ..\include\qassert.h - 133 3.0 1.0 16.0 1 ..\include\qep.h - 33 3.0 1.0 17.0 3 ..\include\qequeue.h - 226 7.0 2.6 64.2 8 ..\include\qf.h - 15 3.0 1.0 20.0 2 ..\include\qf_pkg.h - 16 0.0 0.0 0.0 0 ..\include\qk.h - 25 0.0 0.0 0.0 0 ..\include\qmpool.h - 7 0.0 0.0 0.0 0 ..\include\qpc.h - 361 14.0 3.0 67.0 1 ..\include\qs.h - 3 0.0 0.0 0.0 0 ..\include\qstamp.c - 2 0.0 0.0 0.0 0 ..\include\qstamp.h - 0 0.0 0.0 0.0 0 ..\include\qs_dummy.h - 19 0.0 0.0 0.0 0 ..\include\qs_pkg.h - 7 0.0 0.0 0.0 0 ..\include\qv.h - 93 0.0 0.0 0.0 0 ..\include\qxk.h - 363 31.8 5.3 184.8 11 ..\src\qf\qep_hsm.c - 346 33.3 5.6 195.1 10 ..\src\qf\qep_msm.c - 2 0.0 0.0 0.0 0 ..\src\qf\qf_act.c - 257 27.8 3.8 154.4 9 ..\src\qf\qf_actq.c - 69 20.7 2.3 107.0 3 ..\src\qf\qf_defer.c - 138 18.4 3.3 111.4 7 ..\src\qf\qf_dyn.c - 103 32.0 4.3 197.0 3 ..\src\qf\qf_mem.c - 114 21.0 4.4 123.6 5 ..\src\qf\qf_ps.c - 96 17.6 4.6 113.0 5 ..\src\qf\qf_qact.c - 152 36.2 4.8 200.8 4 ..\src\qf\qf_qeq.c - 18 16.0 2.0 79.0 1 ..\src\qf\qf_qmact.c - 218 26.2 4.1 155.6 8 ..\src\qf\qf_time.c - 191 22.9 5.0 129.1 8 ..\src\qk\qk.c - 81 18.5 5.0 109.2 4 ..\src\qv\qv.c - 260 22.9 5.0 138.5 11 ..\src\qxk\qxk.c - 227 55.0 8.5 467.5 4 ..\src\qxk\qxk_mutex.c - 143 34.0 4.5 213.5 4 ..\src\qxk\qxk_sema.c - 325 24.4 3.8 156.0 13 ..\src\qxk\qxk_xthr.c - -============================================================================================================= -No thresholds exceeded (cyclomatic_complexity > 20 or length > 500 or nloc > 1000000 or parameter_count > 10) -========================================================================================== -Total nloc Avg.NLOC AvgCCN Avg.token Fun Cnt Warning cnt Fun Rt nloc Rt ------------------------------------------------------------------------------------------- - 4049 24.4 4.3 150.5 125 0 0.00 0.00 -@endcode diff --git a/doxygen/gs.dox b/doxygen/gs.dox deleted file mode 100644 index 0da6a10d..00000000 --- a/doxygen/gs.dox +++ /dev/null @@ -1,538 +0,0 @@ -/*! @page gs Getting Started - -The following sections describe how to get started with QP™/C quickly: -- @subpage gs_get -- @subpage gs_tut - -The YouTube Video Getting Started with QP™ Frameworks provides instructions on how to download, install and get started with QP quickly. - -@image html gs-video.jpg -@image latex gs-video.jpg width=4.5in -@caption{[Video: Getting Started with QP™ Real-Time Embedded Framework](https://youtu.be/O7ER6_VqIH0)} -
- -@note -@htmlonly - -@endhtmlonly -Information about the QP/C functionality, architecture, design, and other aspects is provided in the [Certification Package](modules.html): -- @ref srs — QP/C functionality -- @ref sas — QP/C architecture -- @ref sds — QP/C design -- @ref misra — QP/C compliance with MISRA-C - -@ifnot LATEX -@nav{index,gs_get} -@endif -*/ -/*##########################################################################*/ -/*! @page gs_get Downloading & Installing QP™/C -@ifnot LATEX -@nav{gs,gs_tut} -@endif - -@section gs_bundle Downloading QP™/C in QP™-Bundle -The most recommended way of obtaining QP™/C™ is by downloading the @webref{#Downloads, QP-bundle™}, which includes QP™/C as well as other QP™ frameworks and also the @webref{products/qm, QM™ modeling tool} and the @webref{products/qtools, QTools™ collection}. The main advantage of obtaining QP™/C bundled together like that is that you get all components, tools and examples ready to go. - -@image html qp-bundle.png -@image latex qp-bundle.png width=1.5in -@caption{@webref{#Downloads, QP-bundle™ downloads}} -
- -@note -@htmlonly - -@endhtmlonly -If you are allergic to installers and GUIs or don't have administrator privileges you can also **download and install QP™/C separately** from the QP™/C GitHub repository, as described in the next section. - - -@section gs_gh Downloading QP™/C from GitHub -Go to the QP™/C release page on GitHub, and choose the QP™/C version number you wish to download. You should select the latest QP™/C version, unless you have a very specific reason to go with an older release. - -@image html qpc_gh.jpg -@image latex qpc_gh.jpg width=5.0in -@caption{QP™/C downloads from GitHub} - -@section gs_dir QP™/C Installation Folder -The following annotated directory tree lists the top-level directories provided in the standard QP™/C distribution. - -
    -
  • qpc/ -
  • -
      -
    • 3rd_party/ — 3rd-Party code used in the @ref exa "QP™/C Examples" -
    • -
    • examples/ — @ref exa "QP™/C Examples" -
    • -
    • ports/ — @ref ports "QP™/C Ports" -
    • -
    • @ref /qp-dev/qpc/include "include/" — Platform-independent QP™/C API, see also @ref api -
    • -
    • @ref /qp-dev/qpc/src "src/" — Platform-independent QP™/C source code -
    • -
    -
- -@attention -The QP/C GitHub repository does not contain the `3rd_party` folder, which is needed to build the @ref exa "QP™/C Examples". Therefore, it is highly **recommended** to download the latest [QP/C Release](https://github.com/QuantumLeaps/qpc/releases) as opposed to cloning the repo directly. - -@remark -The standard QP™/C distribution contains the `examples` folder with many @ref exa "Example Projects", which are specifically designed to help you learn to use QP™/C and to serve you as starting points for your own projects. - -@ifnot LATEX -@nav{gs,gs_tut} -@endif -*/ -/*##########################################################################*/ -/*! @page gs_tut QP™/C Tutorial -@ifnot LATEX -@nav{gs_get,tut_blinky} -@endif - -This Tutorial describes how to use the QP/C™ real-time embedded framework in a series of progressively advancing examples. The first example ("Blinky") uses only one Active Object with a simple non-hierarchical state machine. The following example ("DPP") demonstrates multiple, communicating Active Objects. Finally, the last example ("Fly'n'Shoot" game) demonstrates all features the QP™ framework. It is highly recommended to study the simpler examples before the more advanced ones, as the basic information won't be repeated in the later examples. - -This Tutorial consists of the following lessons: -- @subpage tut_blinky -- @subpage tut_dpp -- @subpage tut_game -- @subpage tut_low - -@remark -Perhaps the most important fact of life to remember is that in embedded systems nothing works until everything works. This means that you should always start with a *working* system and *gradually* evolve it, changing one thing at a time and making sure that it keeps *working* every step of the way.
-
-Keeping this in mind, the provided @ref exa "QP™/C application examples", such as the super-simple Blinky, or a bit more advanced DPP or “Fly 'n' Shoot” game, allow you to get started with a working project rather than starting from scratch. You should also always try one of the provided example projects on the same evaluation board that it was designed for, before making any changes. - - -Only after convincing yourself that the example project works "as is", you can think about creating your own projects. At this point, the easiest and recommended way is to copy the existing working example project folder (such as the Blinky example) and rename it. - -After copying the project folder, you still need to change the name of the project/workspace. The easiest and safest way to do this is to open the project/workspace in the corresponding IDE and use the Save As~~~ option to save the project under a different name. (You can do this also with the @webref{products/qm, QM model file}, which you can open in QM and "Save As" a different model.) - -@note -By copying and re-naming an existing, working project, as opposed to creating a new one -from scratch, you inherit the correct compiler and linker options an other project settings, which will help you get started much faster. - -@ifnot LATEX -@nav{gs_get,tut_blinky} -@endif -*/ -/*##########################################################################*/ -/*! @page tut_blinky Simple Blinky Application -@ifnot LATEX -@nav{gs_tut,tut_dpp} -@endif - -The ultra-simple Blinky example is the embedded systems' equivalent of the venerable "Hello World!" program, that is, the simplest possible working QP™ application that does "something". In the case of Blinky, this "something" is blinking an LED at the rate of 1Hz, where an LED turns on and remains on for 0.5 seconds on then turns off and remains off for 0.5 seconds. - -@image html blinky_ek-tm4c123gxl.gif -@image latex blinky_ek-tm4c123gxl.jpg width=2.0in -@caption{Blinky on EK-TM4C123GLX (TivaC LaunchPad)} - -@note -The Blinky example is provided for other supported boards as well, not just TivaC LaunchPad. Please look for examples named dpp_ in the @ref exa "qpc/examples/examples" directory (e.g., `qpc/examples/arm-cm/blinky_ek-tm4c123gxl` for the EK-TM4C123GXL board (TivaC LaunchPad)). - - -The ultra-simple Blinky application, which consists of just one active object named `Blinky`, is intentionally kept small and illustrates only the most basic QP features, such as: - -- a simple Blinky active object (AO) @ref oop "class"; -- hand-coding the simple state machine of the Blinky AO; -- using a periodic time event; -- initializing the QP™ framework; -- starting an active object; and -- transferring control to QP™ to run the application. - -The details of the Blinky application are describe in the Quantum Leaps Application Note @webref{doc/AN_Getting_Started_with_QP.pdf, Getting Started with QP™ Real-Time Embedded Frameworks}. - -@image html AN-getting_started.jpg -@image latex AN-getting_started.jpg width=2.0in -@caption{@webref{doc/AN_Getting_Started_with_QP.pdf, Getting Started with QP™ Real-Time Embedded Frameworks}} - -@ifnot LATEX -@nav{gs_tut,tut_dpp} -@endif -*/ -/*##########################################################################*/ -/*! @page tut_dpp Dining Philosophers Problem (DPP) -@ifnot LATEX -@nav{tut_blinky,tut_game} -@endif - -The Dining Philosophers Problem (DPP) example is an intermediate-level application with *multiple* active objects. It illustrates the following QP™ features, such as: - -- multiple active objects, including an array of active objects; -- designing the simple state machines in the QM tool and generating the code automatically (can be also done manually); -- using multiple periodic time events; -- using mutable events with parameters; -- direct event posting to active objects; -- publish-subscribe event delivery; -- initializing the QP™ framework; -- starting multiple active objects; and -- transferring control to QP™ to run the application. - -@note -The DPP example is provided for most supported boards as well as in the command-line version (on the host). Please look for examples named dpp_ in the @ref exa "qpc/examples/examples" directory (e.g., `qpc/examples/arm-cm/dpp_ek-tm4c123gxl` for the EK-TM4C123GXL board (TivaC LaunchPad)). - -The Dining Philosophers Problem (DPP) example is described in the @webref{doc/AN_DPP.pdf, Application Note: Dining Philosophers Problem (DPP) Example}. - -@image html AN_DPP.jpg -@image latex AN_DPP.jpg width=2.0in -@caption{@webref{doc/AN_DPP.pdf, Application Note: Dining Philosophers Problem (DPP) Example}} - -@note -There is also a DPP variant that implements the "Philosophers" as passive "Orthogonal Components" of the "Table" active object. That DPP version is located in qpc/examples/examples/workstation/dpp-comp/ - -@ifnot LATEX -@nav{tut_blinky,tut_game} -@endif -*/ -/*##########################################################################*/ -/*! @page tut_game "Fly 'n' Shoot" Game -@ifnot LATEX -@nav{tut_dpp,tut_low} -@endif - -The "Fly 'n' shoot" game example is a moderately advanced application of a vintage computer game. It requires a LCD screen and push-buttons on the board. - -@image html bd_EFM32-SLSTK3401A.jpg -@image latex bd_EFM32-SLSTK3401A.jpg width=4.5in -@caption{EFM32 Pearl-Geckob} - -"Fly 'n' shoot" game and illustrates the following QP™ features, such as: - -- multiple active objects; -- multiple passive state machines ("Orthogonal Components"); -- multiple periodic time events; -- mutable events with parameters; -- direct event posting to active objects; -- publish-subscribe event delivery; -- developing of embedded software on Windows (see also @webref{qtools/qwin.html,QWin™ GUI Prototyping Toolkit}) - -@image html qwin_ani.gif "Fly 'n' Shoot game running on Windows" -@image latex qwin_static.jpg "Fly 'n' Shoot game running on Windows" width=6in - -The "Fly 'n' Shoot" game example is described in the @webref{doc/AN_Fly-n-Shoot.pdf,Application Note: Fly 'n' Shoot Game Example}. - - -@image html AN-game.jpg "Application Note: Fly 'n' Shoot Game Example" -@image latex AN-game.jpg "Application Note: Fly 'n' Shoot Game Example" width=2in -
- -@image html game-video.jpg -@image latex game-video.jpg width=5in -@caption{Fly'n'Shoot game tutorial video} - -@ifnot LATEX -@nav{tut_dpp,tut_low} -@endif -*/ -/*##########################################################################*/ -/*! @page tut_low Low-Power Example -@ifnot LATEX -@nav{tut_game,exa} -@endif - -The main principle of low-power design for software is to keep the hardware in the most appropriate low-power sleep mode for as long as possible. Most commonly, the software enters a low-power sleep mode from the **idle callback** (a.k.a. "idle hook"), which is called when the software has nothing left to do and is waiting for an interrupt to deliver more work. The QP/C and QP/C++ Real-Time Embedded Frameworks (RTEFs) support the *idle callback* in all of the built-in real-time kernels, such as the cooperative @ref srs_qv "QV kernel", the preemptive non-blocking @ref srs_qk "QK kernel" and the preemptive blocking @ref srs_qxk "QXK kernel". Also, such an *idle callback* is provided in all 3rd-party traditional RTOS kernels that QP/C/C++ have been @ref ports_rtos "ported to". - -@remark -Design for low-power is a broad subject that requires a holistic system approach to achieve a really long battery-powered operation. This example covers only certain *software-related* aspects of the problem. - - -@section arm-cm_low_power_tick The System Clock Tick -Most real-time systems, including traditional RTOSes and RTEFs, require a periodic time -source called the **system clock tick** to keep track of time delays, timeouts, and QP::QTimeEvt "time events" in case of the event-driven QP frameworks. The system clock tick is typically a periodic -interrupt that occurs at a predetermined rate, typically between 10Hz and 1000Hz. - -While the system clock tick is very useful, it also has the unfortunate side effect of taking the processor out of a low power state as many as 1000 times per second regardless if real work needs to be done or not. This effect can have a significant negative impact on the power efficiency of the system. - - -@image html exa_low-power_tick.png -@image latex exa_low-power_tick.png width=5.5in -@caption{Additional power dissipation caused by the system clock tick} - -@subsection arm-cm_low_power_tickless The "Tickless Mode" - -Some real-time kernels use the low-power optimization called the "tickless mode" (a.k.a. "tick supression" or "dynamic tick"). In this mode, instead of indiscriminately making the clock tick fire with a fixed period, the kernel adjusts the clock ticks *dynamically*, as needed. Specifically, after each clock tick the kernel re-calculates the time for the next clock tick and then sets the clock tick interrupt for the earliest timeout it has to wait for. So for example, if the shortest wait the kernel has to attend to is 300 milliseconds into the future, then the clock interrupt will be set for 300 milliseconds. - -This approach maximizes the amount of time the processor can remain asleep, but requires the kernel to perform the additional work to calculate the dynamic tick intervals and to program them into the hardware. This additional bookkeeping adds complexity to the kernel, is often non-deterministic and, most importantly, extends the time CPU spends in the high-power active mode and thus eliminates some of the power gains the "tickless mode" was supposed to bring. - -Also, the "tickless mode" requires a more capable hardware timer that must be able of being reprogrammed for every interrupt in a wide dynamic range and also must accurately keep track of the elapsed time to correct for the irregular (dynamic) tick intervals. Still, "tickless mode" often causes a drift in the timing of the clock tick. - - -@subsection arm-cm_low_power_multiple Multiple Tick Rates - -For the reasons just mentioned, the QP™ Real-Time Embedded Frameworks don't provide the "tickless mode". Instead, the QP™ frameworks support **multiple clock tick rates**, which can be turned on and off, as needed. The QP™ frameworks also provide methods for finding out *when* a given clock tick rate is not used, which allows the idle callback inside the application to shut down the given clock tick rate and also to decide which sleep mode to use for the CPU and the peripherals. - -The support for multiple static clock tick rates is much *simpler* than the "dynamic tick", and essentially does not increase the complexity of the kernel (because the same code for the single tick rate can handle other tick rates the same way). Also, multiple static tick rates require much simpler hardware timers, which can be clocked specifically to the desired frequency and don't need particularly wide dynamic range. For example, 16-bit timers or even 8-bit timers are completely adequate. - -Yet the *multiple clock rates* can deliver similar low-power operation for the system, while keeping the QP framework much simpler and easier to certify than "tickless" kernels. The rest of this example explains how to use the multiple static clock rates in QP/C/C++ and shows how to leverage this feature to achieve low-power software design. - - -@section arm-cm_low_power_app The Low-Power Example Application -The low-power example is located in QP/C and QP/C++ distributions, in the directory with the following structure: - -
-@code{.c} - qpc|qpcpp/ // QP/C/C++ installation directory - +-examples/ // QP/C/C++ examples directory (application) - | +-arm-cm/ // QP/C/C++ examples for ARM Cortex-M - | | +-low-power_ek-tm4c123gxl/ // Low-Power example on the EK-TM4C123GLX board - | | | +-qk/ //----------- Projects for the preemptive QK kernel - | | | | +-arm/ // ARM-KEIL toolchain - | | | | | +-low-power-qk.uvprojx // uVision project - | | | | +-gnu/ // GNU-ARM toolchain - | | | | | +-Makefile // Makefile for building the project - | | | | +-iar/ // IAR-ARM toolchain - | | | | | +-low-power-qk.eww // IAR EW-ARM workspace - | | | | +-bsp.c // BSP for the QK kernel - | | | +-qv/ //----------- Projects for the cooperative QV kernel - | | | | +-arm/ // ARM-KEIL toolchain - | | | | | +-low-power-qv.uvprojx // uVision project - | | | | +-gnu/ // GNU-ARM toolchain - | | | | | +-Makefile // Makefile for building the project with GNU-ARM - | | | | +-iar/ // IAR-ARM toolchain - | | | | | +-low-power-qk.eww // IAR EW-ARM workspace - | | | | +-bsp.c|.cpp // BSP for the QV kernel - | | | +-qxk/ //----------- Projects for the dual-mode QXK kernel - | | | | +-arm/ // ARM-KEIL toolchain - | | | | | +-low-power-qxk.uvprojx // uVision project - | | | | +-gnu/ // GNU-ARM toolchain - | | | | | +-Makefile // Makefile for building the project - | | | | +-iar/ // IAR-ARM toolchain - | | | | | +-low-power-qxk.eww // IAR EW-ARM workspace - | | | | +-bsp.c|.cpp // BSP for the QxK kernel - | | | | +-xblinky1.c|.cpp // eXtended thread for the QXK kernel -@endcode - - -@note -To focus the discussion, this example uses the **EK-TM4C123GXL** evaluation board (a.k.a. TivaC LaunchPad) with Cortex-M4 MCU. However, the general demonstrated principles apply to most modern microcontrollers. - -@image html bd_EK-TM4C123GXL.jpg -@image latex bd_EK-TM4C123GXL.jpg width=2.5in -@caption{EK-TM4C123GXL (TivaC LaunchPad} - -@subsection arm-cm_low_power_behave Behavior -The the low-power example illustrates the use of two clock tick rates to toggle the LEDs available on the EK-TM4C123GXL board. After the application code is loaded to the board, the **Green-LED** starts blinking once per two seconds (a second on and a second off), while the **Red-LED** lights up and stays on. If no buttons on the board are pressed, the **Green-LED** stops blinking after 4 times. The **Red-LED** shows the **idle** condition, where the system is in a sleep mode. - -When your press the **SW1-Button**, the **Green-LED** starts blinking as before, but additionally, the **Blue-LED** starts blinking rapidly for 13 times (1/10 of a second on and 1/10 off). - -So, depending when the SW1 switch is pressed, you can have only **Green-LED** blinking, or both green and blue blinking at different rates. The **Red-LED** appears to be on all the time. - -@note -Actually, the **Red-LED** is also turned off for very brief moments, but this is imperceptible to the human eye. Instead, the **Red-LED** appears to be on all the time, which corresponds to the application being mostly idle. - - -The behavior just described is designed for the slow human interaction with the application. However, for more precise measurements with a logic analyzer, it is more convenient to speed up the application by factor of 100. This speed up can be achieved by editing the `bsp.h` header file: - -
-@code{.c} -/* The following ticks-per-second constants determine the speed of the app. -* The default (#if 1) is the SLOW speed for humans to see the blinking. -* Change the #if 1 into #if 0 for FAST speed appropriate for logic analyzers. -*/ -#if 0 - #define BSP_TICKS0_PER_SEC 2U - #define BSP_TICKS1_PER_SEC 20U -#else - #define BSP_TICKS0_PER_SEC 200U - #define BSP_TICKS1_PER_SEC 2000U -#endif - -. . . -@endcode - -The following logic analyzer trace shows the behavior of the low-power application at the faster time scale. The explanation section immediately following the tarce explains the most interesting points: - -@image html exa_low-power_sig.png "low-power application after pressing the SW1 button" -@image latex exa_low-power_sig.png "low-power application after pressing the SW1 button" - -`[0]` The plot shows the logic-analyzer traces of the following signals (from the top): **SW1** button (active low), **Blinky1** (Blue-LED), **Blinky0** (Green-LED) and **Idle** (Red-LED). The Idle callback turns the **Red-LED** on when the system enters the low-power sleep mode and it turns the **Red-LED** off when the system is active. - -`[1]` At this time the **SW1** button is depressed, which triggers an interrupt that activates both the slow and the fast clock tick rates. The clock tick interrupts trigger toggling of the **Blinky0** (Green-LED) at the slower tick rate-0 and **Blinky1** (Blue-LED) at the faster tick rate-1. - -`[2]` The **Blinky1** (Blue-LED) stops toggling after 13 cycles. At this point also the **Idle** callback turns the **fast tick rate-1** off. - -`[3]` The **Blinky0** (Green-LED) stops toggling after 4 cycles. - -`[4]` The **Idle** callback turns the **slow tick rate-0** off. The system enters the low-power sleep mode without any clock ticks running and remains in this state until the **SW1** button is pressed again. - -@remark -The **Idle** line (Red-LED) goes down twice as fast as the changes in the state of the **Green-LED** or the **Blue-LED**. This is because the application uses timeouts of **2 clock ticks** for toggling these lines instead of just one clock tick, which then could be slower. This is not quite optimal for the energy dissipation (as the CPU is woken up twice as often as it needs to be), but it illustrates more accurately how the fixed clock rates work as well as the one-tick delay to enter the low-power sleep mode from the idle callback. - - -@subsection arm-cm_low_power_sm State Machines -The versions of this low-power example for the **QK** and **QV** kernels use two active objects **Blinky0** and **Blinky1**, which toggle the **Green-LED** at the slow tick rate 0, and the **Blue-LED** at the fast tick rate 1, respectively. The state machines of the Blinky0 and Blinky1 active objects are shown below: - -@image html exa_low-power_sm.png -@image latex exa_low-power_sm.png width=4.0in -@caption{state machines Blinky0 and Blinky1 active objects} - - -`[0]` The **Blinky0** state machine, in the entry action to the "active" state, calls `BSP_tickRate0_on()` to turn the tick rate-0 on. This is done *before* arming the time event `me->timeEvt0` that uses the clock rate-0. - -`[1]` Similarly, the **Blinky1** state machine, in the entry action to the "active" state, calls `BSP_tickRate1_on()` to turn the tick rate-1 on. This is done *before* arming the time event `me->timeEvt1` that uses the clock rate-1. - - -@subsection arm-cm_low_power_xt Extended Thread (QXK) -The version of this low-power example for the **QXK** kernel uses one active object **Blinky0** (with the state machine shown above), but instead of the Blinky1 active object, the QXK version uses an eXtended thread (::QXThread) called **XBlinky1**, with the code shown below: - -
-@code{.c} - #include "qpc.h" - #include "low_power.h" - #include "bsp.h" - - /* local objects -----------------------------------------------------------*/ - static void XBlinky1_run(QXThread * const me); - - /* global objects ----------------------------------------------------------*/ - QXThread XT_Blinky1; - QXSemaphore XSEM_sw1; - - /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~..*/ - void XBlinky1_ctor(void) { - QXThread_ctor(&XT_Blinky1, - &XBlinky1_run, /* thread routine */ - 1U); /* associate the thread with tick rate-1 */ - } - - /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~..*/ - static void XBlinky1_run(QXThread * const me) { - bool isActive = false; - - (void)me; /* unused parameter */ - for (;;) { - if (!isActive) { -[0] QXSemaphore_wait(&XSEM_sw1, QXTHREAD_NO_TIMEOUT); - isActive = true; - } - else { - uint8_t count; -[1] BSP_tickRate1_on(); - for (count = 13U; count > 0U; --count) { - BSP_led1_on(); - QXThread_delay(1U); - BSP_led1_off(); - QXThread_delay(1U); - } - isActive = false; - } - } - } -@endcode - - -`[0]` The **XBlinky1** extended thread emulates the states with the `isActive` flag. When the flag is not set (meaning that the system is not active), the thread waits (and blocks) on the global semaphore `XSEM_sw1`. - -`[1]` After the semaphore is signalled (from the GPIO interrupt in the BSP), the **XBlinky1** extened thread calls `BSP_tickRate1_on()` to turn the tick rate-1 on. This is done *before* later calling QXThread_delay() function, which in case uses the clock rate-1. - - -@subsection arm-cm_low_power_idle The Idle Callback (QK/QXK) -The most important functionality in this low-power example is implemented in the **idle callback** located in the BSP (Board Support Package). The idle callback QK_onIdle() for the preemptive QK kernel and the idle callback QXK_onIdle() for the QXK kernel are almost identical and are explained in this section. - -
-@code{.c} -[0] void QXK_onIdle(void) { - -[1] QF_INT_DISABLE(); -[2] if (((l_activeSet & (1U << SYSTICK_ACTIVE)) != 0U) /* rate-0 enabled? */ -[3] && QF_noTimeEvtsActiveX(0U)) /* no time events at rate-0? */ - { - /* safe to disable SysTick and interrupt */ -[4] SysTick->CTRL &= ~(SysTick_CTRL_TICKINT_Msk | SysTick_CTRL_ENABLE_Msk); -[5] l_activeSet &= ~(1U << SYSTICK_ACTIVE); /* mark rate-0 as disabled */ - } -[6] if (((l_activeSet & (1U << TIMER0_ACTIVE)) != 0U) /* rate-1 enabled? */ -[7] && QF_noTimeEvtsActiveX(1U)) /* no time events at rate-1? */ - { - /* safe to disable Timer0 and interrupt */ -[8] TIMER0->CTL &= ~(1U << 0); /* disable Timer0 */ -[9] TIMER0->IMR &= ~(1U << 0); /* disable timer interrupt */ -[10] l_activeSet &= ~(1U << TIMER0_ACTIVE); /* mark rate-1 as disabled */ - } -[11] QF_INT_ENABLE(); - -[12] GPIOF->DATA_Bits[LED_RED] = 0xFFU; /* turn LED on, see NOTE2 */ -[13] __WFI(); // wait for interrupt */ -[14] GPIOF->DATA_Bits[LED_RED] = 0x00U; /* turn LED off, see NOTE2 */ - } -@endcode - - -`[0]` The idle callback for QK and QXK are called from the idle loop with interrupts enabled. - -`[1]` Interrupts are disabled to access the shared bitmask `l_activeSet`, which stores the information about active clock rates and peripherals. This bitmask is shared between the idle callback and the application-level threads. - -`[2]` If the SYSTICK timer is active (source of the tick-0 rate)~~~ - -`[3]` The `QF_noTimeEvtsActiveX(0)` function is called to check whether no time events are active at the clock rate-0. - -@remark -The QF_noTimeEvtsActiveX() function is designed to be called from a critical section, which is the case here. - - -`[4]` If both of these conditions hold, it is safe to turn the clock rate-0 off, which is done here. - -`[5]` The bit indicating that SYSTICK timer is active is cleared in the `l_activeSet` bitmask. - -`[6]` Simliarly, the bit corresponding to TIMER0 is checked in the `l_activeSet` bitmask. - -`[7]` The `QF_noTimeEvtsActiveX(1)` function is called to check whether no time events are active at the clock rate-1. - -`[8-9]` If both of these conditions hold, it is safe to turn the clock rate-1 off, which is done here. - -`[10]` The bit indicating that TIMER0 timer is active is cleared in the `l_activeSet` bitmask. - -`[11]` Interrupts are enabled, so the following code is no logner inside critical section - -`[12]` The **Red-LED** is turned ON right before entering the low-power sleep mode - -`[13]` The `__WFI()` instruction stops the CPU and enters the **low-power sleep mode** - -`[14]` The **Red-LED** is turned off after waking up from the sleep mode - - -@subsection arm-cm_low_power_idle-qv The Idle Callback (QV) -The idle callback QV_onIdle() for the cooperative QV kernel is slightly different, because it is called with interrupts **disabled**. The following listing shows the complete QV_onIdle() callback, with the most important points explained in the section below: - -
-@code{.c} -[0] void QV_onIdle(void) { /* NOTE: called with interrupts DISABLED */ - -[1] if (((l_activeSet & (1U << SYSTICK_ACTIVE)) != 0U) /* rate-0 enabled? */ -[2] && QF_noTimeEvtsActiveX(0U)) /* no time events at rate-0? */ - { - /* safe to disable SysTick and interrupt */ - SysTick->CTRL &= ~(SysTick_CTRL_TICKINT_Msk | SysTick_CTRL_ENABLE_Msk); - l_activeSet &= ~(1U << SYSTICK_ACTIVE); /* mark rate-0 as disabled */ - } - if (((l_activeSet & (1U << TIMER0_ACTIVE)) != 0U) /* rate-1 enabled? */ - && QF_noTimeEvtsActiveX(1U)) /* no time events at rate-1? */ - { - /* safe to disable Timer0 and interrupt */ - TIMER0->CTL &= ~(1U << 0); /* disable Timer0 */ - TIMER0->IMR &= ~(1U << 0); /* disable timer interrupt */ - l_activeSet &= ~(1U << TIMER0_ACTIVE); /* mark rate-1 as disabled */ - } - - GPIOF->DATA_Bits[LED_RED] = 0xFFU; /* turn LED on, see NOTE2 */ -[3] QV_CPU_SLEEP(); /* atomically go to sleep and enable interrupts */ - GPIOF->DATA_Bits[LED_RED] = 0x00U; /* turn LED off, see NOTE2 */ - } -@endcode - -`[0]` The idle callback for QV is called from the QV event-loop with interrupts **disabled**. - -`[1]` The `l_activeSet` bitmask is tested right away, because interrupts are already disabled - -`[2]` The `QF_noTimeEvtsActiveX(0)` function is called to check whether no time events are active at the clock rate-0. - -@remark -The QF_noTimeEvtsActiveX() function is designed to be called from a critical section, which is the case here. - - -`[3]` The QV_CPU_SLEEP() macro enters **low-power sleep mode** with interrupts still disabled. This port-specific macro is designed to re-anable interrupts **atomically** with entering the sleep mode. - -@ifnot LATEX -@nav{tut_game,exa} -@endif -*/ diff --git a/doxygen/help.dox b/doxygen/help.dox deleted file mode 100644 index 07730c2c..00000000 --- a/doxygen/help.dox +++ /dev/null @@ -1,35 +0,0 @@ -/*! @page help Using Online Help - -

You can use this online help in various ways: either sequentially from beginning to end or just by quickly locating the interesting topic. -

- -![Online Help Features](help_using.png) - - - -@section help_seq Reading Online Help Sequentially -You can move from topic to topic by means of the Next: link at the bottom of each page. - - - -@section help_random Quickly Locating a Topic of Interest -You can use the following elements: - -- the @ref help_tree_view "Tree View" pane on the left-hand side of the browser; - -- the **Table of Contents** box in the top-right corner of the page; - -- the **Search** box in the upper-right corner of the browser window - - - -@section help_tree_view Using the Tree View -The *Tree View* pane on the left-hand side of the browser displays the hierarchical Table of Contents, which can be either **linked-to** or **unlinked-from** the *Current Topic* displayed on the right-hand side. You can toggle between the two modes by pressing the **Link/Unlink Current Topic** icon at the top of the *Tree View* pane. - - -When the *Tree View* is **linked** to the Current Topic, the *Tree View* will always follow the currently viewed topic, by expanding and highlighting the pertinent section of the hierarchical Table of Contents. - -
- -When the *Tree View* is **unlinked** from the Current Topic, the *Tree View* will show only the explicitly selected section of the hierarchical Table of Contents and will **not** follow the topics activated by internal documentation links. -*/ diff --git a/doxygen/history.dox b/doxygen/history.dox deleted file mode 100644 index 15530d76..00000000 --- a/doxygen/history.dox +++ /dev/null @@ -1,2970 +0,0 @@ -/*! @page history Design History File (DHF) - -@image html qcp_banner.jpg -@image latex qcp_banner.jpg width=6.5in - -@remark -This document is part of the @webref{products/qp#CERT,QP Certification Pack}, which has been specifically designed to aid companies in **safety certification** of their software based on the QP real-time embedded frameworks. - -@section qpc_7_2_1 Version 7.2.1, 2023-01-15 -__QP/C Source Code:__ -- Changed the design of the ::QXMutex class to include ::QActive by composition rather than inheritance. - -__Ports:__ -- Fixed problems in QK ports for ARM Cortex-M: in case a regular IRQ is used for returning to the thread context. The port didn't handle correctly #QK_USE_IRQ_NUM above 32. -- Fixed problems in QXK ports for ARM Cortex-M: in case a regular IRQ is used for returning to the thread context. The port didn't handle correctly #QK_USE_IRQ_NUM above 32. - -__Bug Fixes:__ -- [bug#328 Assertion qxk:720 in QP/​C/​C++ 7.2.0](https://sourceforge.net/p/qpc/bugs/328) - -@attention -This bug in QXK affects releases QP/C @ref qpc_7_1_0 "7.1.0" through @ref qpc_7_2_0 "7.2.0" - - -@section qpc_7_2_0 Version 7.2.0, 2023-01-06 -__QP/C Source Code:__ -- Added "enumeration dictionaries" for QS software tracing (see QS_ENUM_DICTIONARY()) -- Introduced common callback `QF_onContextSw()` used in all built-in kernels (QV, QK, QXK). This callback is enabled by the macro #QF_ON_CONTEXT_SW. -- Removed callback `QK_onContextSW()` and macro QK_ON_CONTEXT_SW and replaced with `QF_onContextSw()`/#QF_ON_CONTEXT_SW. -- Removed callback `QXK_onContextSW()` and macro QXK_ON_CONTEXT_SW and replaced with `QF_onContextSw()`/#QF_ON_CONTEXT_SW. -- Added callback `QF_onContextSW()` and macro #QF_ON_CONTEXT_SW to the QV kernel. -- added configuration macro #QS_CTR_SIZE to determine the size of the type ::QSCtr (see also [feature#195](https://sourceforge.net/p/qpc/feature-requests/195)) -- Removed backwards-compatibility with QP 5.4.0 or older. This includes removing workarounds for `QFsm`, `QFsm_ctor()`, `Q_IGNORED()`. -- Modified QMsm_childStateObj() implementation to correctly handle submachine states (see also [bug#316](https://sourceforge.net/p/qpc/bugs/316)) -- Added automatic generation of the QS function dictionary for the QHsm_top() state handler function. This happens only once on the first call to QHSM_INIT(). - -@note -It is no longer necessary to generate QS function dictionary for QHsm_top() in the application (although it is still allowed, but wasteful). - -__Ports:__ -- `ports/arm-cm` added setup of the FPU (if configured) to all build-in kernels (QV, QK, QXK) and toolchains (ARMCLANG, GNU-ARM, IAR). -- `ports/arm-cm` all ports now clear the FPCA bit in the CONTROL register (if FPU configured) right before starting the interrupts. That potentially saves the stack space (MSP) for the automatically reserved FPU context. - -@note -This change means that the applications no longer need to setup the FPU, which was done typically in the BSP. - -- `ports/posix` added configuration macro #QS_CTR_SIZE 4U, to allow QS trace buffers > 64KB (see also [feature#195](https://sourceforge.net/p/qpc/feature-requests/195)) -- `ports/win32` added configuration macro #QS_CTR_SIZE 4U, to allow QS trace buffers > 64KB (see also [feature#195](https://sourceforge.net/p/qpc/feature-requests/195)) -- `ports/esp-idf` fixed compilation error caused by obsolete macro `QF_PTR_RANGE_()` -- `ports/sample` added a sample QP/C port for reference and documentation of all available configuration options. -- `zephyr` updated `qf_port.h` to include `` rather than `` (see also [bug#321](https://sourceforge.net/p/qpc/bugs/321)) - - -__Examples:__ -- examples for QV: added callback `QF_onContextSw()` -- exampels for QK, QXK: replaced callbacks `QK_onContextSw()/QXK_onContextSw()` with `QF_onContextSw()` -- `examples/arm-cm` removed setting up the FPU from the BSPs (the FPU is now setup in the ports). -- `examples/arm-cm` added setting up the MPU (Memory Protection Unit) to catch [NULL-pointer dereferencing](https://www.state-machine.com/null-pointer-protection-with-arm-cortex-m-mpu) and other incorrect memory access. - - -__Testing:__ -- changed the QUTest assertion handler Q_onAssert() to reset the target rather than wait for user commands. This allows proper assertion handling even inside exception handlers, where the target really cannot handle interrupts (which were needed for reception of commands). This change matches the updated policy of **assertion failures** in [QUTest 7.2.0](https://www.state-machine.com/qtools/history.html#qtools_7_2_0). -- examples for QUTest (`examples/qutest` and `test` directories): adjusted makefiels to invoke the `qutest.py` utility with the new [command-line parameters](https://www.state-machine.com/qtools/qutest_use.html#qutest_command). -- modified the test fixtures to use "enum dictionaries" for commands -- added example `examples/qutest/start_seq` that demonstrates testing of start sequences. - - -__Bug Fixes:__ -- [bug#315 QSignal defined incorrectly when #Q_SIGNAL_SIZE==4U](https://sourceforge.net/p/qpc/bugs/315) -- [bug#316 Using History with Submachines does not work](https://sourceforge.net/p/qpc/bugs/316) -- [bug#321 zephyr port build error](https://sourceforge.net/p/qpc/bugs/321) - -- [bug#325 QSpy shows Sig=NULL if #Q_EVT_CTOR is used](https://sourceforge.net/p/qpc/bugs/325) - -__Feature Requests:__ -- [feature#195 allow > 64K QS trace buffer on target](https://sourceforge.net/p/qpc/feature-requests/195). This is configurable by setting the macro #QS_CTR_SIZE. - - -@section qpc_7_1_3 Version 7.1.3, 2022-11-18 -__Bug Fixes:__ -- [bug#317 QK works incorrectly in QP/C/C++ 7.1.2](https://sourceforge.net/p/qpc/bugs/317) - -__Source__ -- The file `qstamp.c` has been copied from the `include/` folder to `src/qs/`. This makes it easier to build SPY configuration. (The file `qstamp.c` has been left in the `include/` folder for backwards compatibility). - -__Ports__ -- This release removes the QP libraries from the **Windows** ports -- `CMakeLists.txt` file in the zephyr port has been modified to use `zephyr_library_named(qpc)` instead of `zephyr_library()` - -__Examples__ -- This release changes all examples for **Windows** (Makefiles for GCC and project files for Visual Studio) to build the QP framework from sources rather than using QP libraries. This slightly extends the first build of the application, but avoids any problems with library incompatibilities (e.g., 32-bit/64-bit compilers used to build the application vs. the QP libraries). -- updated examples for emWin Embedded GUI (for emWin v6.28) -- updated examples for MSP430 - -__Documentation__ -- Modified the `doxygen/` folder for generation of QM Manual in LaTeX (enables generation of PDF) - -__Licensing__ -- This release removes the `QM-EVAL-QPC.qlc` file from the `LICENSES` folder. This "QM License Certificate" is no longer needed for QM 5.2.3, where "QM License Certificates" are no longer needed for generating QMsm-style state machines. - - -@section qpc_7_1_2 Version 7.1.2, 2022-10-07 -This release improves preemption-threshold scheduling (PTS) in @ref srs_qk "QK" kernel, especially the generation of the software tracing information about the scheduler activity. Also, PTS has been removed from the @ref srs_qxk "QXK" kernel because of the inherent complexity of that kernel. - -Additionally, the default for #QF_TIMEEVT_CTR_SIZE has been increased from 2 to 4 bytes. This increases the default dynamic range for QTimeEvt counters to 32-bits. - -__Source__ -- Modified QK_sched_() and QK_activate_() -- Modified QXK_sched_() and QXK_activate_() -- Added QXK_contextSw() to handle context switching (generation of software tracing information and invoking of the QXK_onContextSw() callback, if configured -- increased default for #QF_TIMEEVT_CTR_SIZE 4 -- changed inclusion guards in the QP/C header files (e.g. `QF_H` -> `QP_INC_QF_H_`) for compliance with the updated Quantum Leaps coding standard and to make the names more unique. - -__Ports__ -- Modified QXK ports (assembly) to call QXK_contextSw() -- Added port to RISC-V with the cooperative @ref srs_qvk "QV" kernel - -__Testing__ -- Added new directory `qpc/test/` for **system**-level testing of QP/C itself. -- Added new tests for QK: `qpc/test/qk` -- Added new tests for QXK: `qpc/test/qutest/qxk` - -@note -The `qpc/test/` directory is planned to contain a growing number of system-level tests, which are based on QUTest, but *without* the QP-stub. The tests take advantage of the new QUTest configuration, where the QP-stub is NOT included (because the actual QP framework is linked). This configuration is activated by defining macro `Q_UTEST=0`. - -@attention -Most tests provided in the `qpc/test/` directory run only on embedded targets and cannot run on the host machine. - - -@section qpc_7_1_0 Version 7.1.0, 2022-08-30 -This QP/C release introduces [preemption-threshold scheduling (PTS)](https://www.state-machine.com/doc/Ghattas07.pdf) for the preemptive QK and QXK kernels. Specifically, it is now possible to limit preemption of a given QActive/QXThread by giving it both the QF-priority and preemption-threshold. - -The following diagram shows the relationship between the "QF-priority" and "preemption-threshold" (see also ::QPrioSpec): - -![QF-priority and preemption-threshold relations](qp-prio.png) - -@note -For backwards-compatibility, ::QPrioSpec data type might contain only the "QF-priority" component (and the "preemption-threshold" component left at zero). In that case, the "preemption-threshold" will be assumed to be the same as the "QF-priority". This corresponds exactly to the previous semantics of AO priority. - -__Source__ -- modified the QP/C code for preemption-threshold -- improved QS tracing of Scheduler activities in QK and QXK -- improved implementation of QXSemaphore and QXMutex in QXK - -__Ports__ -- Modified QK and QXK ports to ARM Cortex-M for preemption-threshold and for handling the context-switch callback -- Updated Zephyr port and examples for Zephyr 3.1.99 - -__Examples__ -- Added Q_PRIO() macro for setting QF-priority and preemption-threshold to various examples (in calls to QACTIVE_START()) -- increased size of the main stack in most examples from 1024 to 2048 bytes. This is to prevent stack overflow that was observed with the lower limit. - -__Testing__ -- modified QUTest to also allow testing of the QP framework itself. - - -@section qpc_7_0_2 Version 7.0.2, 2022-08-12 -__Bug Fixes:__ -- [bug#312 "Bug in QK and QXK 7.0.1"](https://sourceforge.net/p/qpc/bugs/312) - -__Ports__ -Modified QK and QXK ports to ARM Cortex-M -- `qpc/ports/arm-cm/qk` -- `qpc/ports/arm-cm/qxk` - -Modified Zephyr port -- moved the port from the usual location in `qpc/ports/zephyr` up a level to `qpc/zephyr`. This was done to make QPC into an external [Zephyr module](https://docs.zephyrproject.org/latest/develop/modules.html), which has to comply with the Zephyr specification. - - -__Examples (ARM Cortex-M):__ -- `qpc/examples/arm-cm/dpp_efm32-slstk3401a/qk` provided examples of configuring either NMI or IRQ for Cortex-M4 (ARMv7m) -- `qpc/examples/arm-cm/dpp_efm32-slstk3401a/qxk` provided examples of configuring either NMI or IRQ for Cortex-M4 (ARMv7m) -- `qpc/examples/arm-cm/dpp_nucleo-l053r8/qk` provided examples of configuring either NMI or IRQ for Cortex-M0+ (ARMv6m) -- `qpc/examples/arm-cm/dpp_nucleo-l053r8/qk` provided examples of configuring either NMI or IRQ for Cortex-M0+ (ARMv6m) - -__Examples (Zephyr):__ -- `qpc/examples/zephyr/blinky` - modified to use the new Zephyr port -- `qpc/examples/zephyr/dpp` - modified to use the new Zephyr port and to demonstrate QSPY software tracing. - - -@section qpc_7_0_1 Version 7.0.1, 2022-07-31 -This release is the first one that contains the complete [QM model](https://www.state-machine.com/products/qm) of the QP/C framework (in the file `qpc/qpc.qm`). This model is then used to **generate all QP/C source code**: -- `qpc/` - + @ref C:/qp-dev/qpc/include "include" - + @ref C:/qp-dev/qpc/src "src" - -The QM model of QP/C explicitly captures the *logical design* of the framework, which is then mapped to the preexisting [physical design](https://www.state-machine.com/qm/ce.html#ce_phys). The *logical design*, which consists of packages (some associated with namespaces), classes, types, and macros traces explicitly to the @ref sas "Software Architecture Specification (SAS)" and is easier to manipulate and refactor. - -__Source Code Changes:__ -- The whole QP/C source code is now generated from the `qpc.qm` model. -- Refactored classes with only static members (QF, QV, QK, QXK, QS) into "namespaces". -- Refactored: - + QF_TICK_X() -> QTIMEEVT_TICK() (see also QTimeEvt_tick_()) - + QF_PUBLISH() -> QACTIVE_PUBLISH() (see also QActive_publish_()) - + QF_psInit() -> QActive_psInit() - -@note -The old APIs (QF_PUBLISH(), QF_TICK_X(), QF_psInit()) are still provided, but are tagged as [deprecated](deprecated.html). - -- Moved package-scope header files qf_pkg.h and qs_pkg.h from the `qpc/src` directory to `qpc/include`. This allows the build process to specify only the `qpc/include` directory to build applications and QP/C source code. Previously, the build process had to specify additionally `qpc/src`, but this is no longer needed. - -@note -This change allowed all provided examples to be simplified by removing the `qpc/src` include directory from the various project files. - -__Ports/Examples:__ -- Removed port and examples for the older ARM7/ARM9 -- Added port to the @ref zephyr "Zephyr RTOS" -- Added examples for the @ref exa_zephyr "Zephyr RTOS" -- redesigned QP/C @ref freertos "port to FreeRTOS", see `qpc/ports/freertos` -- slightly improved QP/C @ref threadx "port to ThreadX", see `qpc/ports/threadx` - -__Improved Documentation:__ -The Doxygen documentation has been re-structured and improved. Also the more attractive styling of the HTML has been applied. - - -@section qpc_7_0_0 Version 7.0.0, 2022-04-30 -This QP/C release changes the QP/C implementation from C89 to C99 and also improves compliance of the QP/C source code with MISRA:C-2012 (a.k.a. MISRA3). Also, major focus of this release is the adaptation of the code and documentation to better support safety certification (see [QP Certification Pack](modules.html)) - -__Modified QP/C source code:__ -- updated QP/C source code for C99 - -@note -The QP/C source code requires C99 minimum and no longer compiles as C89. - -- made the QP/C source code compliant with MISRA:C-2012, C99 variant -- made the compliant with the updated [Quantum Leaps Embedded C/C++ Coding Style (QL-C/C++:2022)](https://github.com/QuantumLeaps/embedded-coding-style) -- added traceability links between QP/C source code and requirements, architecture, design, and MISRA deviation permits. -- modified the top-level file comments now have standard-compliant license specification (SPDX-License-Identifiers). This allows QP/C to be included in automatic generation of Software Bill Of Materials (SBOM). - -__Modified QP/C ports:__ -- modified the QK and QXK ports to ARM Cortex-M to allow compile-time selection between using either NMI or an unused IRQ (via macro QK_USE_IRQ_HANDLER) as a mechanism to return to the thread mode -- removed unused `ARM_ARCH` symbol from Makefiles for GNU-ARM -- fixed the following bugs in QXK port to ARM Cortex-M - + [bug#305 Floating-point context corruption in QXK](https://sourceforge.net/p/qpc/bugs/305) - + [bug#306 #QF_ON_CONTEXT_SW option is not compatible with soft-float](https://sourceforge.net/p/qpc/bugs/306) - -__Removed QP/C ports:__ -- removed QP/C port to PIC24/dsPIC with XC16 (not compatible with C99) - -__Modified GitHub repository:__ -- removed the `3rd_party` directory from the [qpc GitHub repository](https://github.com/QuantumLeaps/qpc) to avoid tracking changes caused by updates to the 3rd-party components. (The QP/C releases still have the `3rd_party` directory, because it is needed for building the examples). - -__Added/Modified examples:__ -- modified examples for ARM Cortex-M7 (to integrate better with STM32CubeH7) -- added examples for ARM Cortex-M33 (for STM32 NUCLEO-L552ZE and STM32CubeL5) -- added `qutest` examples for Unity (comparison between Unity and QUTest) - -__Modified QP/C documentation:__ -- restructured the Doxygen documentation for traceability -- added the @ref gs_tut "QP/C Tutorial" -- added the @ref srs "QP Certification Pack" - -@remark -The [QP Certification Pack](https://www.state-machine.com/products/qp#CERT) is still work in progress in this release, but the remaining work is limited to documentation only and no code restructuring is anticipated for that. - - -@section qpc_6_9_3 Version 6.9.3, 2021-04-12 -__Feature Requests:__ -- [feature#191 "Add QS local filtering to QF_PUBLISH()"](https://sourceforge.net/p/qpc/feature-requests/191) - -The feature has been implemented by means of the "sender" parameter of the `QF_PUBLISH()` macro, which must now be a pointer to a struct that has the `prio` member. This design enables applying QS local filter to the `prio` as the QS-Id. This works for publishing events from active objects. For publishing events outside active objects (e.g., from ISRs), the header file `qs.h` provides a type `QSpyId`, which should be used to define QS ID variables to be used as "sender" in `QF_PUBLISH()`. - -@note -This change only affects the Spy build configuration, where the QS software tracing instrumentation is enabled. The existing code could require modifications to provide "sender" pointer that can access `prio` directly. For example, AOs would need to call `QF_PUBLISH(e, &me->super)` instead of `QF_PUBLISH(e, me)`. - - -- [feature#185 "Add possibility of assigning name to AO threads in QP-RTOS ports"](https://sourceforge.net/p/qpc/feature-requests/185) - -This feature request is now implemented uniformly in all QP-ports to 3rd-party RTOSes by means of the generic QP API QActive_setAttr(). Specifically, the QP port will allow you to set the thread name by calling QActive_setAttr() before calling QACTIVE_START(). - - -__Bug Fixes:__ -- [bug#292 "QP-C-C++ on 64 Bit Linux - Setting of Current-Obj - AO_Obj from QView raises segmentation fault"](https://sourceforge.net/p/qpc/bugs/292) -- [bug#293 "[Qpccp 6.9.2] test of assertion fail now"](https://sourceforge.net/p/qpc/bugs/293) -- [bug#298 "ARM Cortex-M Erratum 838869 Handled Inconsistently in Ports"](https://sourceforge.net/p/qpc/bugs/298) - - -__Source code changes:__ -- `qpc/include/qf.h` - feature#191 -- `qpc/include/qs.h` - feature#191 -- `qpc/src/qf/qf_ps.c` - feature#191 -- `qpc/src/qs/qs_rx.c` - feature#191 and bug#292 - - -__Modified QP/C ports:__ -- `qpc/ports/arm-cm/` - fixed [bug#298](https://sourceforge.net/p/qpc/bugs/298) -- `qpc/ports/embos/` - implemented [feature#185](https://sourceforge.net/p/qpc/feature-requests/185) -- `qpc/ports/threadx/` - implemented [feature#185](https://sourceforge.net/p/qpc/feature-requests/185) -- `qpc/ports/ucos2/` - implemented [feature#185](https://sourceforge.net/p/qpc/feature-requests/185) -- `qpc/ports/win32/` - added QSpy64 (64-bit) build configuration to the Visual Studio project -- `qpc/ports/win32-qv/` - added QSpy64 (64-bit) build configuration to the Visual Studio project -- `qpc/ports/win32-quit/` - added "port" used for "QP Unit Internal Testing" (QUIT) - - -__Updated examples:__ -- all examples using `QF_PUBLISH()` - adjusted the `sender` parameter of the macro to have the `prio` member -- `qpc/examples/arm-cm/` - fixed [bug#298](https://sourceforge.net/p/qpc/bugs/298) (added calls to `QV|QK|QXK_ARM_ERRATUM_838869()`) -- `qpc/examples/qutest/self_test/test/` - added examples of the Python include files (`*.pyi`) for the new [include command](https://www.state-machine.com/qtools/namespacequtest__dsl.html). -- `qpc/examples/arm-cm/dpp_efm32-slstk3401a/win32-gui/` - corrected handling of user-drawn buttons in `bsp.c` -- `qpc/examples/arm-cm/game_efm32-slstk3401a/win32-gui/` - corrected handling of user-drawn buttons in `bsp.c` - - -__Updated 3rd-Party Components:__ -- `qpc/3rd_party/threadx` to version 6.1.6 (latest open source version from [GitHub](https://github.com/azure-rtos/threadx) ) - - -@section qpc_6_9_2 Version 6.9.2, 2021-01-18 -The main purpose of this release is a redesign of the QS-RX (software tracing input) to implement the feature request #187: - -- [feature#187 "Make the byte order in QS-RX buffer compatible with DMA"](https://sourceforge.net/p/qpc/feature-requests/187) - -Additionally, as part of the re-design of the internal QS-RX implementation, this release fixes the bug #287 ("QS_rxGetNfree() returns too low value", see the "Bug Fixes" section) - -Additionally, this release introduces a new "virtual" function `getStateHandler()` in the `QHsm` base class. This is part of the fix for bug #290 ("QView query object state reports wrong state with QMsm strategy", see the "Bug Fixes" section) - -__Source code changes:__ - -The introduction of the `getStateHandler()` virtual function involves the following code changes: -- `qpc/include/qep.h` -- `qpc/src/qf/qep_hsm.c` -- `qpc/src/qf/qep_msm.c` -- `qpc/src/qf/qf_actq.c` -- `qpc/src/qf/qf_qact.c` -- `qpc/src/qf/qf_qmact.c` -- `qpc/src/qs/qs_rx.c` -- `qpc/src/qs/qutest.c` -- `qpc/src/qxk/qxk_xthr.c` -- `qpc/include/qs.h` file -- added new API QS_queryCurrObj() - -The redesign of QS-RX implementation involves the following code changes: -- `qpc/include/qs.h` -- macro `QS_RX_PUT()` now returns `bool` (true if the byte was inserted into the QS-RX buffer and false otherwise) -- `qpc/src/qs/qs_rx.c` - changed several functions -- `qpc/src/qs/qs_fp.c` - improved implementation - - -__Modified QP/C ports:__ -- `qpc/ports/posix/` - modified to take advantage of the QS-RX direct byte ordering -- `qpc/ports/posix-qutest/` - modified to take advantage of the QS-RX direct byte ordering -- `qpc/ports/posix-qv/` - modified to take advantage of the QS-RX direct byte ordering -- `qpc/ports/win32/` - modified to take advantage of the QS-RX direct byte ordering -- `qpc/ports/win32-qutest/` - modified to take advantage of the QS-RX direct byte ordering -- `qpc/ports/win32-qv/` - modified to take advantage of the QS-RX direct byte ordering - - -__Added QP/C ports:__ -- `qpc/ports/freertos-esp32/` - added new *experimental* port to FreeRTOS-ESP32 - - -__Updated examples:__ -- `qpc/examples/workstation/calc` fixed minor bug in the calculator - - -__Bug Fixes:__ -- [bug#289 "QS_OBJ_PTR() macro does not compile on 64-bit machine"](https://sourceforge.net/p/qpc/bugs/289) -- [bug#288 "POSIX port does not compile in Spy build configuration"](https://sourceforge.net/p/qpc/bugs/288) -- [bug#287 "QS_rxGetNfree() returns too low value"](https://sourceforge.net/p/qpc/bugs/287) -- [bug#285 "QView bug with querying the state of QMsm-type state machines"](https://sourceforge.net/p/qpc/bugs/285) -- [bug#284 "Typo in QM generated headers"](https://sourceforge.net/p/qpc/bugs/284) - - -__Updated 3rd-Party Components:__ -- `qpc/3rd_party/CMSIS` to version 5.7.0 -- `qpc/3rd_party/FreeRTOS` to version 10.4.3 (202012LTS released December 2020) - - -@section qpc_6_9_1 Version 6.9.1, 2020-09-28 -The main purpose of this release is a redesign of the [QS Local Filter](https://www.state-machine.com/qtools/qs.html#qs_local) (see also [feature request #127](https://sourceforge.net/p/qpc/feature-requests/127)). This new design supports filtering on __multiple__ active objects (as well as other objects in the Target memory), as opposed to filtering just one such object at a time. The main use case for this redesign of QS Local Filter is an application, where some active objects are very "noisy", and would overwhelm your trace. The new QS Local Filter allows you to selectively silence the "noisy" active objects and let all the others through. - -The new QS Local Filter is based on "QS-IDs" associated with various objects in the Target memory. The QS-IDs are small integer numbers, such as the unique priorities assigned to QP Active Objects, but there are more such QS-IDs, which you can assign to various other objects through the macro QS_BEGIN_ID(). Then, you can setup the QS Local Filter to trace only a specific QS-IDs or whole groups of QS-IDs by means of the macro QS_LOC_FILTER() or remotely via the QS-RX channel. - - -__Source code changes:__ - -The redesign of the QS Local Filter impacts the QS trace instrumentation in QP/C: both the [pre-defined QS trace records](https://www.state-machine.com/qtools/qs.html#qs_pre) and the [application-specific trace records](https://www.state-machine.com/qtools/qs.html#qs_app). The changes to the pre-defined records are confided to the QP/C source code and are transparent to the application developers. However, the changes to the application-specific trace records require adjusting existing applications as follows: - -- use the new macro QS_LOC_FILTER() to set/clear the QS Local Filter -- use the new macro QS_BEGIN_ID() to define [application-specific trace records](https://www.state-machine.com/qtools/qs.html#qs_app). - - -@note -The macro QS_BEGIN_ID() assigns the specified QS-ID number to the app-specific record, which can be subsequently filtered by the new QS Local Filter. The old macro QS_BEGIN(), with the old Local Filter interface, is still available, but is @ref deprecated "deprecated" and not recommended. - - -The following macros are __deprecated__: - -- macro QS_FILTER_SM_OBJ() does nothing in QP/C 6.9.1 -- macro QS_FILTER_AO_OBJ() does nothing in QP/C 6.9.1 -- macro QS_FILTER_MP_OBJ() does nothing in QP/C 6.9.1 -- macro QS_FILTER_EQ_OBJ() does nothing in QP/C 6.9.1 -- macro QS_FILTER_TE_OBJ() does nothing in QP/C 6.9.1 -- macro QS_FILTER_AP_OBJ() still works for QS_BEGIN() -- macro QS_FILTER_ON() still works, but uses QS_GLB_FILTER() internally -- macro QS_FILTER_OFF() still works, but uses QS_GLB_FILTER() internally -- macro QS_BEGIN() still works, but uses the old "AP-OBJ" pointer - - -The following APIs have been __changed__: - -- QHSM_INIT() now takes extra `qs_id` parameter -- QHSM_DISPATCH() now takes extra `qs_id` parameter -- QMPool_get() now takes extra `qs_id` parameter -- QMPool_put() now takes extra `qs_id` parameter -- QEQueue_post() now takes extra `qs_id` parameter -- QEQueue_postLIFO() now takes extra `qs_id` parameter -- QEQueue_get() now takes extra `qs_id` parameter - -@note -The API changes are __not backwards-compatible__ and require adjusting existing QP/C applications. - - -Additionally, this release introduces the new pre-defined QS record #QS_QF_NEW_ATTEMPT, which is generated when Q_NEW_X() fails to allocate a dynamic event. Also, this release __reverses the order__ of the pre-defined QS records #QS_QF_NEW and #QS_QF_MPOOL_GET. This was necessary if the dynamic allocation is allowed to fail, because only _after_ attempting to allocate a memory block, the QF_newX_() function can generate either #QS_QF_NEW or #QS_QF_NEW_ATTEMPT. - -@note -The reversal of #QS_QF_NEW and #QS_QF_MPOOL_GET trace records has implications for the existing [QUTest test scripts](https://www.state-machine.com/qtools/qutest_script.html), where the order of expectations for "QF-New" and "MP-Get" needs to be reversed as well. - - -Additionally, this release modifies the @ref srs_qxk "QXK" source code, so that the `QActive.prio` attribute is the fixed priority assigned in QActive_start(), while `QActive.dynPrio` is the "dynamic" priority that can be changed when a @ref srs_qxk_extended "QXK extended thread" acquires a @ref ::QXMutex "mutex". - - -__Updated Ports:__ - -- all ARM Cortex-M ports (added workaround for the [ARM Erratum 838869](https://www.state-machine.com/doc/Cortex-M4_Software_Developers_Errata_Notice_v3.pdf)) -- all QK ports (because of the changed QMPool_get() / QMPool_put() interface) -- all QXK ports (because of the changed QMPool_get() / QMPool_put() interface) -- embOS port (because of the changed QMPool_get() / QMPool_put() interface) -- FreeRTOS port (because of the changed QMPool_get() / QMPool_put() interface) -- ThreadX port (because of the changed QMPool_get() / QMPool_put() interface) -- uC/OS-II port (because of the changed QMPool_get() / QMPool_put() interface) -- posix, posix-qv (because of the changed QMPool_get() / QMPool_put() interface) -- win32, win32-qv (because of the changed QMPool_get() / QMPool_put() interface) - - -__Feature Requests:__ - -- [feature#181 "Use of QS_U64()) on 32 bit machine"](https://sourceforge.net/p/qpc/feature-requests/181) - -__Bug Fixes:__ - -- [bug#279 "Confusing documentation of QF_newX_()"](https://sourceforge.net/p/qpc/bugs/279) -- [bug#280 "QXK_onContextSw() not called at the end of QXK_activate_()"](https://sourceforge.net/p/qpc/bugs/280) - - -@section qpc_6_9_0 Version 6.9.0, 2020-08-21 -The main purpose of this release is to adjust the QP/C RTEF to the changes and improvements introduced in [QTools 6.9.0](https://www.state-machine.com/qtools/history.html). Specifically, QP/C now includes examples for the new [QView Visualization & Monitoring](https://www.state-machine.com/qtools/qview.html) as well as adjustments for the new version of [QUTest Unit Testing](https://www.state-machine.com/qtools/qutest.html). - - -__Source code changes:__ - -Added new #QS_QF_RUN trace record to [QS software tracing](https://www.state-machine.com/qtools/qs.html), which is now generated in all QP/C ports upon the entry to QF_run(). This trace record marks the end of the application startup, at which time all the [QS dictionaries](https://www.state-machine.com/qtools/qs.html#qs_dict) are typically produced. - -Also, added the information about the target **endianness** to the #QS_TARGET_INFO QS trace record. - - -@note -The addition of the #QS_QF_RUN trace record affects only the [Spy build configuration](https://www.state-machine.com/qpc/struct.html#comp_qs) and is has **no impact** on the Release or Debug build configurations. - - -__Updated Ports:__ - - + All QP/C ports to 3rd-party RTOSes (embOS, FreeRTOS, ThreadX, uC/OS-II) and OSes (POSIX, POSIX-QV, WIN32, WIN32-QV) have been updated to generate the #QS_QF_RUN trace record. - - + The POSIX and POSIX-QV ports have been updated to add the call to `pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED)` (see also [bug#276](https://sourceforge.net/p/qpc/bugs/276)) - - + The MSP430 ports have been extended for the GNU-MSP430 compiler, so that they now work with IAR-MSP40, TI-MSP40 and GNU-MSP430 toolchains. - - -__Updated Examples:__ - - + All [QUTest](https://www.state-machine.com/qtools/qutest.html) examples (`qpc\examples\qutest` directory) have been modified to use the new location of the `qutest.py` Python module. Also, all QUTest examples that use the `on_reset()` callback have been modified to call `expect_run()`. - -@note -The #QS_QF_RUN record is now generated in [QUTest unit testing](https://www.state-machine.com/qtools/qutest.html), which requires adjustments in the existing [test scripts](https://www.state-machine.com/qtools/qutest_script.html). Specifically, the test scripts that provide their own [on_reset() callback](https://www.state-machine.com/qtools/namespacequtest__dsl.html#aa40735b0e2865f928331d30798090ee2) must now also call [expect_run()](https://www.state-machine.com/qtools/namespacequtest__dsl.html#a6a958064a793bd7edd6ecc39e03c356a). - - - + ARM Cortex-M examples for STM32 NUCLEO-L053RE (`qpc\examples\arm-cm\dpp_nucleo-l053r8`) and NUCLEO-L152RE (`qpc\examples\arm-cm\dpp_nucleo-l152re`) have been modified to support bi-directional QSPY communication. These examples now include the QView demos. - + Added examples of new [Sequence Diagram Generation](https://www.state-machine.com/qtools/html/qspy_seq.html) in QSPY 6.9.0 - - + The example projects for MSP430 now contain the `ccs-ti` and `ccs-gnu` directories, for the TI-MSP430 and GNU-MSP430 toolchains, respectively. - - -__Bug Fixes:__ - - + [bug#276 "QP/C/C++ POSIX port doesn't set thread priorities correctly"](https://sourceforge.net/p/qpc/bugs/276) - - -@section qpc_6_8_2 Version 6.8.2, 2020-07-17 -__Source code changes:__ - -- Changed definitions of ::QMsm, ::QMActive, and ::QTicker "classes" from using typedef's to using struct's. This means that ::QMsm, ::QMActive, and ::QTicker are now **distinct types** different from the respective base classes: ::QHsm, ::QActive, and ::QActive. Consequently, implicit conversions to the base class are *no longer performed*, which improves the type safety. - -@note -This change might cause compiler warning in code that assumes equivalence between ::QHsm and ::QMsm or ::QActive and ::QMActive. Specifically, any "opaque" pointers to the state machine base class should be of type `QHsm *` (and *not* `QMsm *`). Similarly, any "opaque" pointers to the active object base class should be of type `QActive *` (and *not* `QMActive *`) - - -- Applied the [Doxygen @extends command](https://www.doxygen.nl/manual/commands.html#cmdextends) to indicate **inheritance** and to explicitly specify base classes for all derived classes (e.g., ::QTimeEvt __extends__ ::QEvt). -- Fixed errors in the Doxygen documentation, such as: missing documentation for parameters, wrong parameter names, unresolved references, etc. -- Applied new, clearer styling to the Doxygen documentation. -- Changed the QS trace record name QS_QF_ACTIVE_POST_FIFO to ::QS_QF_ACTIVE_POST and QS_QF_EQUEUE_POST_FIFO to ::QS_QF_EQUEUE_POST. This refactoring now better matches the QP/C API QACTIVE_POST() and QEQueue_post(). - - -__Updated Ports:__ - + enabled #QF_ACTIVE_STOP in the ports: Win32, Win32-QV, Win32-QUTEST, POSIX, POSIX-QV, and POSIX-QUTEST. - + @ref uc-os2 "port to uC/OS-II" has been adapted to the new uC/OS-II v2.93.00 (recently released by Silicon Labs under the open source Apache 2.0 license). - - -__Updated Examples:__ - - + Modified `Makefile`s for the GNU-ARM projects to use `gcc` as the linker instead of `g++` - + Modidfied `Makefile`s for the workstation examples to add the `-no-pie` linker option only when `GCC_OLD` environment variable is NOT defined. This is to accommodates older POSIX platforms with older GCC distribution. - + Modified all ARM-KEIL uVision projects for ARM-CLANG to use the startup code in the ARM-ASM syntax. - + New uC/OS-II example @ref uc-os2_dpp_nucleo-l053r8 (Cortex-M0+) - + Removed uC/OS-II example for the STM32-NUCLEO-L152RE (Cortex-M3) - + Added QM model files: `workstation/defer/defer.qm` and `workstation/reminder2/reminder2.qm` - -__Updated QUTest examples to generate code-coverage information:__ - + Modified `Makefile`s in QUTest examples (directory `examples\qutest`) to generate **code-coverage information**. Specifically, when the `GCOV` environment variable is defined, the `Makefile`s generate code-coverage information for [GCOV](https://en.wikipedia.org/wiki/Gcov). - -@note -The GCOV code-coverage generation is currently available only on the hosts. - - -__Updated 3rd-Party Components:__ - - + CMSIS from 5.6.0 to 5.7.0 - + uC/OS-II from 2.92.10 to 2.93.00 (open source Apache 2.0 license) - -__Bug Fixes:__ - - + [bug#267 "QP/C Spy build configuration fails on 64-bit target"](https://sourceforge.net/p/qpc/bugs/267) - - -@section qpc_6_8_1 Version 6.8.1, 2020-04-04 -__Source code changes:__ - -Improved comments in the QF_stop() function. The comments now make it very clear that after calling QF_stop() the application must terminate and cannot continue. In particular, QF_stop() is **not** intended to be followed by a call to QF_init() to "resurrect" the application. The previous comments apparently were confusing and some developers attempted to "restart" a running application, which led to system crashes. - -__Bug Fixes:__ - -- [bug#261 QTime_disarm() clears the wrong flag](https://sourceforge.net/p/qpc/bugs/261) -- [bug#262 Ticker0 does not work in QPC 6.8.0](https://sourceforge.net/p/qpc/bugs/262) - -Also, this release updates the QP/C ports and examples for workstations (Windows and POSIX) by consistently applying the "safe" versions of services from `` and ``. The "portable" versions of these services are defined as macros in the `safe_std.h` header file and include the following services: - -- `MEMMOVE_S()` -> `memmove_s()` -- `STRCPY_S()` -> `strcpy_s()` -- `STRCPY_S()` -> `strcpy_s()` -- `STRCAT_S()` -> `strcat_s()` -- `SNPRINTF_S()` -> `_snprintf_s()` -- `PRINTF_S()` -> `printf_s()` -- `FPRINTF_S()` ->`fprintf_s()` -- `FREAD_S()` -> `fread_s()` -- `FOPEN_S()` -> `fopen_s()` -- `LOCALTIME_S()` -> `localtime_s()` - -These "safe" functions are mapped to the best approximation of these services available on a given platform. For example, `STRCPY_S()` is mapped to `strcpy_s()` on Windows and `strcpy()` on POSIX (Linux/MacOS/etc.). - - -@section qpc_6_8_0 Version 6.8.0, 2020-03-21 -__Source code changes:__ - -- Fixed inconsistencies between QP API declarations in the `.h` files and definitions in the `.c` files, such as different parameter names in declarations and definitions (MISRA-C:2012). - -- Removed a lot of excessive type casting of compile-time constants, such as `(uint8_t)0`, which is now coded simply as `0U` - -- Introduced #Q_NORETURN macro for Q_onAssert(), which can (if defined) inform the compiler that Q_onAssert() does not return. This can potentially improve the code generation and can improve diagnostics generated by the compiler as well as static code analysis tools. - -- Moved many @ref qs facilities for internal use (only inside the QP/C source code) from qs.h to qs_pkg.h. These are mostly facilities related to internal QS implementation as well as pre-defined QS trace records, which are only used inside QP and are not needed in the QP applications. - -- Removed all pre-conditions from QActiveDummy_start_() function in qutest.c. This is to allow starting dummy AOs the exact same way as the real counterparts (e.g., with stack storage, which QActiveDummy does not really need). - - -__Updated 3rd-Party Components:__ - - + FreeRTOS from 10.2.1 to 10.3.0 - + SEGGER embOS from 4.34.1 to 5.06.1 - + SEGGER emWin from 5.32 to 6.10 - + Removed TI-RTOS (both port and examples) - - -__Updated Examples:__ - -Converted most of the examples for ARM-MDK from the no-longer maintained compiler-5 (RVDS) to the new ARM Compiler-6 (ARM-clang). The examples for ARM Compiler-6 are located in the `armclang` sub-directories. - -@note -The older ARM Compiler-5 is still supported, but will be phased out in the future. The only examples for ARM Compiler-5 are for the EK-TM4C123GXL (TivaC LanuchPad) board. These examples are located in the `arm` sub-directories. - - -@section qpc_6_7_0 Version 6.7.0, 2019-12-30 -The main purpose of this release is providing improved compliance with MISRA-C:2012 (including MISRA-C:2012-Amendment-1) and also to provide support for the [PC-Lint-Plus](https://www.gimpel.com) static analysis tool (see also feature request [#169](https://sourceforge.net/p/qpc/feature-requests/169)). Specifically, the QP/C source code and some examples have been adjusted to comply with MISRA-C:2012-Amendment-1 rules, with all deviations captured in the PC-Lint-Plus configuration files. These PC-Lint-Plus configuration files have been provided in the new "port" to PC-Lint-Plus in the directory qpc/ports/lint-plus/. - -@note -The support for the older PC-Lint 9.x and the older MISRA-C:2004 has been dropped to avoid confusion and conflicts with the newer MISRA-C:2012 and the newer PC-Lint-Plus. - - -This release also includes the offline documentation for **this** particular version of QP/C (in the `html/` folder). To view the offline documentation, open the file `html/index.html` in your web browser. (The online HTML documentation for the **latest** version of QP/C remains located at: https://www.state-machine.com/qpc/ ) - -The backwards-compatiblity layer for QP 4.x has been removed. Among others, the macros Q_ROM and Q_ROM_VAR are no longer defined. - -Also, this release updates the Windows-GUI examples with the QWIN Prototyping Toolkit to work with the latest Visual Studio 2019 and specifically with the Resource Editor now available. Specifically here, the Game-GUI example (`qpc\examples\arm-cm\game_efm32-slstk3401a\win32-gui`) and the DPP-GUI example (`qpc\examples\arm-cm\dpp_efm32-slstk3401a\win32-gui`) have been updated to build with the Visual Studio 2019. - -__Bug Fixes:__ - -- [bug#254 "Q_NEW_X_FROM_ISR for FreeRTOS port"](https://sourceforge.net/p/qpc/bugs/254) -- [bug#255 "IAR-ARM "Multi-file Compilation" fails for QK and QXK applications"](https://sourceforge.net/p/qpc/bugs/255) - - -@section qpc_6_6_0 Version 6.6.0, 2019-10-31 -The main purpose of this release is the change in distribution of the QP/C framework, which is now bundled together with the other QP frameworks (QP/C++ and QP-nano) as well as QM, and the QTools collection into "QP-bundle". This "QP-bundle" provides a single, streamlined and simplified download and installation of all QP frameworks and all the accompanying tools. - -This release brings also the following changes: - -- removed "//" (double slash) from all comments for compliance with - the MISRA-C:2012 required Rule 3.1. (The "//" sequence was used in the URLs, such as - "http://~~~"). -- converted inclusion guards in header files to uppercase as per coding convention for macros. -- replaced "vtbl" with "vtable" in QP/C source code -- changed the type of the last parameter in QHsm_init_() and QHSM_INIT() from "QEvt const *" - to "void const *" to allow passing arbitrary data during initialization. -- increased #QS_USER from 70 to 100 and made the freed-up records reserved -- changed the QS_Ux_RECORDS groups to partition user trace records 100-124 - into 5 groups of 5 records each. -- removed Tcl test scripts from QUTest examples - - -@section qpc_6_5_1 Version 6.5.1, 2019-05-24 -__Bug Fixes:__ - -- [bug#241 "QUTest produces superfluous Trg-Done QS_RX_EVENT after publish"](https://sourceforge.net/p/qpc/bugs/241). -- [bug#242 "QUTest fails to process events posted/published from user commands"](https://sourceforge.net/p/qpc/bugs/242). - -Also, this release extends the `Makefiles` in the `qpc\examples\qutest` directory to provide the `debug` target. Specificall, the `qpc\examples\qutest\blinky` example has been extended with projects to `build/debug` this example with Visual C++ (on the host) and with ARM-KEIL on embedded target (EK-TM4C123). - -Finally, this release adds ports and examples for PIC24/dsPIC 16-bit MCUs with MPLAB-X/XC16 and PIC32 with MPLAB-X/XC32 toolchains. - - -@section qpc_6_5_0 Version 6.5.0, 2019-03-30 -This QP/C release matches the [QM release 4.5.0](https://www.state-machine.com/qm/history.html#qm_4_5_0), which introduced new implementation for QP/C++. Even though this has no impact on the QP/C state machine implementation with QM, this release is needed for compatibility checking between QP and QM. - -For commonality with the new QP/C++ implementation, this release adds macros #Q_ACTION_NULL and #QM_STATE_NULL, which are used in the code generated from QM 4.5.0. Also, this release comes with several models for **QM 4.5.0**. - -Additionally, this release changes the API QTimeEvt_ctr() to QTimeEvt_currCtr(). This is to avoid name shadowing with the `ctr` variables, which is not compliant with MISRA. - -Additionally, the examples for `calc1` and `calc1_sub` (with QM 4.5.0 models) have been extended to properly handle the operator precedence (multiplication and division have higher precedence than addition and subtraction). - - - -@section qpc_6_4_0 Version 6.4.0, 2019-02-10 -This release brings the following changes: - -- removed QActive_stop() -- added assertions to QHSM_INIT(), QACTIVE_START() and QXTHREAD_START() to make sure the the virtual-pinter (vptr) is initialized - -@note -These additional assertions require #Q_DEFINE_THIS_FILE or #Q_DEFINE_THIS_MODULE at the top of the .c file that calls QHSM_INIT(), QACTIVE_START() or QXTHREAD_START(). - -- modified examples for ThreadX to define BSP_TICKS_PER_SEC as TX_TIMER_TICKS_PER_SECOND instead of a hard-coded value -- modified examples for uC/OS-II to define BSP_TICKS_PER_SEC as OS_TICKS_PER_SEC instead of a hard-coded value -- modified qassert.h to work correctly when assertions are disabled with #Q_NASSERT and also updated the QP/C source code to build correctly without assertions -- improved the QXK semaphores to handle correctly the maximum number of tokens -- reduced the size of QPSet in case #QF_MAX_ACTIVE does not exceed 8 or 16. -- improved performance of the QF_qlog2() algorithm when #QF_MAX_ACTIVE does not exceed 8 or 16. -- modified Makefiles for workstations (Windows and POSIX) to use compiler options -std=c99 for C and -std=c++11 for C++ as well as -pedantic option. -- fixed examples for MSP430 with CCS and added QUTest support for MSP430. - - -@section qpc_6_3_8 Version 6.3.8, 2018-12-31 -The main purpose of this release is the update the `Makefiles` that use the [GNU-ARM Embedded Toolchain](https://developer.arm.com/open-source/gnu-toolchain/gnu-rm) to match the recent update in [QTools for Windows 6.3.8](https://sourceforge.net/projects/qpc/files/QTools). Specifically, all `Makefiles` in the `examples` directory have been updated to use the GNU-ARM toolchain located in `qtools\gnu_arm-none-eabi` and use the tools prefix **arm-none-eabi-**. - -@note -The `Makefiles` that use the GNU-ARM included in this release require [QTools for Windows version 6.3.8 or newer](https://sourceforge.net/projects/qpc/files/QTools) and will **NOT** work with the older QTools collection. - - -@section qpc_6_3_7 Version 6.3.7, 2018-11-20 -The main goal of this release is to provide Python test scripts that match the newly re-designed Python support for the [QUTest unit testing harness](https://www.state-machine.com/qtools/qutest.html) (see QTools **6.3.7**). Specifically, the Python tests scripts (*.py files) in the `qpc/examples/qutest` directory) have been all upgraded to the new syntax and format. Also, all the makefiles in that directory have been modified to execute Python test scripts by default, and Tcl test scripts only when the argument `SCRIPTS=tcl` is specified. - -@note -The new scripting interface [qutest.py](https://www.state-machine.com/qtools/qutest_script.html) is now the primary supported QUTest scripting interface. The older interfaces, such as TCL ("qutest.tcl") and "qspypy" are considered *obsolete* and are **not recommended** for writing new test scripts. - -The second change in this release is updating the QP ports to Win32 and POSIX to eliminate the obsolete function `gethostbyname()` and replacing it with `getaddrinfo()`. This change has ripple effects on Windows, because it requires linking with "ws2_32" library, instead of "wsock2". All affected `Makefiles` in the `qpc\examples\` directory have been updated to link the newer "ws2_32" library. - -Also, in this release, the prototypes of the internal functions `QActive_start_()`, `QActive_get_()`, `QActive_post_()` and `QActive_postLIFO_()` have been removed from the public QF interface (in qf.h) and moved to the QF-implementation. This is to prevent calling these internal functions directly in the application-level code. The only allowed use of these functions is through the macros QACTIVE_START(), QACTIVE_POST(), QACTIVE_POST_X() and QACTIVE_POST_LIFO(). - -Finally, this release updates the internal implementation of QXK function `QXThread_post_()` for software tracing and testing with QUTest. - - -@section qpc_6_3_6 Version 6.3.6, 2018-10-20 -This release brings important changes and improvements to the unit-testing support for [QUTest](https://www.state-machine.com/qtools/qutest.html). Specifically, a new "dummy" active object class ::QActiveDummy for testing has been added. Instances of this "dummy" AO can be now used as test-doubles for active objects that are recipients of events directly posted by the active object under test (AOUT). This, in turn, eliminates the need to alter the existing event-posting implementation, so that more of the actual QP code can be used in the QP test-stub (qutest.c). - -@note -The QUTest projects that build QP from sources need to include the qf_time.c file. - - -As a consequence of the changes in the [QUTest](https://www.state-machine.com/qtools/qutest.html) support, the @ref exa_qutest "QUTest examples" have been re-designed and improved. Here, the most important changes include the new code organization, which reflects the customary separation of the code-under-test (CUT) from the code for testing. Also, the tests based on the ["TDD book" by James Grenning](https://www.amazon.com/Driven-Development-Embedded-Pragmatic-Programmers/dp/193435662X) have been replaced with fully functional tests based on the [Unity testing framework](http://www.throwtheswitch.org/unity). This is to directly compare the traditional approach (Unity) with QUTest. - -The next change related to unit testing is adding ::QS_RX_QUERY_CURR facility to QS-RX (software tracing input channel) and the reply ::QS_QUERY_DATA to the QS output channel. These two extensions allow you to query the status of the "current object" inside the target. The most important example is querying the current state-machine object (::SM_OBJ), which returns the **current state**. - -@note -The new "query" facilities in QP/C match the latest additions to the [QSPY host application](https://www.state-machine.com/qtools/qspy.html). - -Also this release adds [QS dictionary](https://www.state-machine.com/qtools/qs.html#qs_dict) generation for all registered event pools. The generated object dictionaries are `EvtPool1` for pool-1, `EvtPool2` for pool-2, etc. - -@note -Applications no longer need to generate QS object dictionaries for the event pool storage buffers, such as `smlPoolSto[]`, etc. - - -Another big change in this release is re-designing of the @ref exa_os "examples for workstations" (previously `win32`, `win32-qv`, `posix` and `posix-qv`). All these types of examples have been consolidated in the @ref exa_os "exampes/workstation" folder, where the provided `Makefiles` have been extended to be cross-platform so that they work on Windows, Linux, and MacOS without changes. - -To facilitate the creation of truly portable, cross-platform examples, the existing @ref ports_os "QP ports to Windows/POSIX" have been augmented with abstractions for portable console access. Also, the [QS software tracing](https://www.state-machine.com/qtools/qs.html) support via TCP/IP has been now added to the ports themselves. This means that applications no longer need to repeat the code for QS callbacks in the BSP implementation. - -Finally, this release fixes a bug in the @ref posix-qv "POSIX-QV port", where the internal condition variable `QV_condVar_` has not been initialized. - - -@section qpc_6_3_4 Version 6.3.4, 2018-08-10 -This release adds new API QTimeEvt_wasDisarmed() for checking the status of a ::QTimeEvt object after it has been disarmed. Specifically, the status of the last call to QTimeEvt_disarm() is kept inside the time event object and can be subsequently checked with the QTimeEvt_wasDisarmed() API. This new function is designed to be used directly as a guard condition on the timeout event, as described in the [PSiCC2 book](/psicc2), Section 7.7.3 "Arming and Disarming a Time Event" on page 359. The QTimeEvt_wasDisarmed() has a side effect of setting the "was disabled" status, so the guard evaluates to 'true' the next time it is checked. - - -@section qpc_6_3_3a Version 6.3.3a, 2018-07-16 -This release adds Python test scripts to the QUTest examples (folder `qpc/examples/qutest`). Specifically, the makefiles have been augmented to accept symbol `SCRIPT=py`, in which case the Python test scripts (`*.py`) are used instead of the default Tcl test scripts (`*.tcl`). - -@remark -This release does not change any QP/C APIs, QP/C implementation, ports, or other examples. - - -@section qpc_6_3_3 Version 6.3.3, 2018-06-22 -This release fixes the following bugs: - -- [bug#216 "Generated code for QP version check violates MISRA-C Rule 10.1"](https://sourceforge.net/p/qpc/bugs/216). - -- [bug#217 "GNU-ARM -fstack-protector incompatible with the QP ports to GNU-ARM"](https://sourceforge.net/p/qpc/bugs/217). - -Also, this release demonstrates the new features of QM 4.3.0 in several example models (qpc/examples/ directory). - -Finally, this release updates `3rd_party/CMSIS/Include` to the latest version from GitHub. - - -@section qpc_6_3_2 Version 6.3.2, 2018-06-20 -This release fixes the following bugs: - -- [bug#215 "QP is internally inconsistent in calling assertion macros"](https://sourceforge.net/p/qpc/bugs/215). - - -Also, this release improves the QUTest DPP example (directory `qpc/examples/qutest/dpp`) by demonstrating the proper use of QS_TEST_PAUSE() and the corresponding test scripts. This example now matches the [QUTest documentation of this feature](https://www.state-machine.com/qtools/qutest_rtc.html#qutest_pause). - -Finally, this release modifies the QP/C ports to POSIX and POSIX-QV by allowing to configure the p-thread priority of the ticker thread. This is achieved by adding a `tickPrio` parameter to the `QF_setTickRate()` function. (**NOTE** this modification will require changing existing QP applications for POSIX or POSIX-QV that call `QF_setTickRate()`. - - -@section qpc_6_3_1 Version 6.3.1, 2018-05-24 -This release migrates the [QUTest](https://www.state-machine.com/qtools/qutest.html) examples to [QM 4.2.1](https://www.state-machine.com/qm/history.html#qm_4_2_1), which now can generate QS_FUN_DICTIONARY() records automatically. This release also adds a generic, simple blinky example for QUTest located in `examples/qutest/blinky`. Also, this release fixes a bug in the example `qutest/TDDbook_LedDriver` so that the code compiles cleanly with the updated header file "qassert.h". - - -@section qpc_6_3_0 Version 6.3.0, 2018-05-10 -The main purpose of this release is fixing the sub-machine support in the QP/Spy build configuration. Specifically, this release fixes the following bug: - -- [bug#213 "QP/C/C++ applications with submachines occasionally crash in Spy build configuration"](https://sourceforge.net/p/qpc/bugs/213) - -@attention -This release matches [QM 4.2.0](https://www.state-machine.com/qm/history.html#qm_4_2_0). - -Additionally, the release contains some re-factoring of the QS-RX input channel. - - -@section qpc_6_2_0 Version 6.2.0, 2018-03-16 -The main purpose of this release is extednding the functionality of the [QUTest unit testing](https://www.state-machine.com/qtools/qutest.html) for QP/C applications. Specifically, this release adds support for testing of **self-posting** of events in active objects, which is an essential element in the [Reminder](https://www.state-machine.com/doc/Pattern_Reminder.pdf) and [Deferred Event](https://www.state-machine.com/doc/Pattern_DeferredEvent.pdf) design patterns. To implement this new feature, the QS-RX (QS receive channel) has been extened by a small scheduler that processes all secondary events gnenerated by dispatching, posting, or publishing events (only active when the #Q_UTEST macro is defined). Also, the implementation of the target resident QUTest components (files `src/qs/qutest.c` and `src/qf/qf_actq.c`) have been modified to allow posting of events during unit testing. - -Additionally, the release adds standard QS trace records (the `qs.h` header file) for event deferring and recalling (::QS_QF_ACTIVE_DEFER and ::QS_QF_ACTIVE_RECALL) as well as recall-attempt (::QS_QF_ACTIVE_RECALL_ATTEMPT). Also standard QS trace records have been added for creating/deleting new event references (::QS_QF_NEW_REF and ::QS_QF_DELETE_REF, respectively). To make room for these new records, the following rarely-used records have been removed: QS_QF_ACTIVE_ADD, QS_QF_ACTIVE_REMOVE, QS_QF_EQUEUE_INIT, and QS_QF_MPOOL_INIT. The global filter settings in the QS_filterOn() and QS_filterOff() functions have been updated to the re-organized QS trace records. - -@note -Because of the changes in the standard QS trace recods, this release requires the matching **QSPY 6.2.0** or later. Also, because of the changes this release might break some existing QUTest unit test scripts, which need to be re-adjusted to the new trace records. - - -Additionally, this release improves support for tracing and unit-testing embedded POSIX targets, such as embedded Linux, or OSes/RTOSes with the POSIX compatiblity layer. Specifically, the POSIX ports (`qpc/ports/posix/` and `qpc/ports/posix-qutest/`) no longer produce libraries. Instead all examples for POSIX (`qpc/examples/posix/` and `qpc/examples/qutest`) build the QP/C framework directly from the sources, which promotes consisentcy in the toolchain and options used. For unit testing, the makefiles `posix.mak` have been added for projects `qpc/examples/qutest/dpp/` and `qpc/examples/qutest/self_test/`. These makefiles support remote unit testing of embedded POSIX targets over TCP/IP, where the POSIX target runs only the [test fixture](https://www.state-machine.com/qtools/qutest.html#qutest_struct), but the host (e.g., Windows host) executes both the QSPY host application and runs the [QUTest scripts](https://www.state-machine.com/qtools/qutest.html#qutest_struct). The previous makefiles for POSIX have been renamed to `posix_host.mak`, because they are intended to use POSIX as a *host*, as opposed to a *target*. - -Also, this release adds new QUTest exampes, which illustrate: -- event deferral (`qpc/examples/qutest/defer/`) -- dispatching/posting events with parameters (`qpc/examples/qutest/evt_par/`). - -Additionally, this release updates the QP/C ports to win32-qv and posix-qv to allow a "tickless" mode, where the "tickerThread" is not created. This mode is set by configuring the system clock tick rate to 0 (QF_setTickRate(0)). - -Finally, this release phases out the `qp_port.h` header file. If any of your projects still includes this file, please replace it with the qpc.h heder file. - - -@section qpc_6_1_1 Version 6.1.1, 2018-02-18 -The main purpose of this release is adding the context-switch callbacks to the preemptive @ref srs_qk "QK" and @ref srs_qxk "QXK" kernels. The QK_onContextSw() and QXK_onContextSw() callback functions provide a mechanism to perform additional custom operations when QK/QXK switches context from one thread to another. To avoid extra overhead when this functionality is not needed and for backwards-compatiblity with the existing applications, the callbacks are enabled only when the macros #QK_ON_CONTEXT_SW (for QK) and #QXK_ON_CONTEXT_SW (for QXK) are defined. These macros can be defined either directly in command-line for the compiler, or in the QK/QXK port files (qk_port.c for QK and qxk_port.c for QXK). Examples for the context-switch callbacks have been provided for for the @ref arm-cm_dpp_nucleo-l053r8 "NUCLEO-L053R8" (Cortex-M0+) and the @ref arm-cm_dpp_nucleo-h743zi "NUCLEO-H743ZI" (Cortex-M7). - -Also, this release changes the ARM Cortex-M ports for the IAR-ARM toolchain in that it replaces the assembly modules with the equivalent C implementation. This change enables using the configuration macros #QK_ON_CONTEXT_SW (for QK) and #QXK_ON_CONTEXT_SW (for QXK) in the ports. All existing example projects for IAR-ARM have been updated to use the `q(x)k_port.c` files instead of `q(x)k_port.s` files. - -Also, this release adds new project files for the Atollic TRUEstudio for STM32. The TRUEstudio projects (Eclipse) have been added for the @ref arm-cm_dpp_nucleo-l053r8 "NUCLEO-L053R8" (Cortex-M0+) and the @ref arm-cm_dpp_nucleo-h743zi "NUCLEO-H743ZI" (Cortex-M7). - -Finally, this relese updates the CMSIS to version 5.3.0 (see `qpc/3rd_party/CMSIS`) - - -@section qpc_6_1_0 Version 6.1.0, 2018-02-04 -The main purpose of this release is adding the support for the [ARM Compiler 6 (ARM-Clang)](https://developer.arm.com/products/software-development-tools/compilers/arm-compiler), which is a C/C++ toolchain for ARM processors based on the modern [Clang frontend](https://clang.llvm.org) and the [LLVM framework](https://llvm.org). This release adds the ARM-Clang ports and examples for all built-in kernels (QV, QK, and QXK) for the ARM Cortex-M CPU cores. - -This release also adds support for the STM32H7 high-performance Cortex-M7 with the **double-precision FPU** (FPv5-DP-D16-M). Specifically, this release provides examples for the [NUCLEO-H743ZI board](http://www.st.com/en/evaluation-tools/nucleo-h743zi.html) (Cortex-M7 with FPv5-DP-D16-M). The @ref arm-cm_dpp_nucleo-h743zi "examples for NUCLEO-H743ZI board" include all built-in kernels with ARM-CLANG, ARM-KEIL, GNU-ARM, and IAR-ARM. Additionally the NUCLEO-H743ZI examples also include the QP FreeRTOS with ARM-KEIL, GNU-ARM, and IAR-ARM. - -Also, this release changes the ARM Cortex-M ports for the GNU-ARM toolchain in that it replaces the assembly modules with the equivalent C implementation. This change enables using wider range of GNU-ARM toolchain distributions, such as GNU-ARM Linaro, which had trouble with the assembly modules, but compiles correctly the C modules. All related GNU-ARM example projects have been modifed to use the new C-ports. - -Also, this release updates the existing projects for the Code Composer Studio (CCS) to CCSv7. All existing CCS projects for the EK-TM4C123GXL (TivaC LauchPad) and LaunchXL2-TMS57012 (Hercules) boards have been upgraded and tested. - -Also, all examples for MSP430 with CCS have been updated to CCSv7 and re-tested on the supported boards. - - -@section qpc_6_0_4 Version 6.0.4, 2018-01-10 -The main purpose of this release is the provision of the official @ref freertos "QP/C port to FreeRTOS" (version 10). The QP/C port to FreeRTOS is completely generic and should work on any CPU supported by FreeRTOS. The port comes with the following examples (see examples/freertos): -- @ref freertos_dpp_ek-tm4c123gxl "DPP on EK-TM4C123GXL (ARM Cortex-M4F)" with ARM-KEIL, GNU-ARM and IAR-ARM toolchains. -- @ref freertos_dpp_stm32f746g-disco "DPP on STM32F746G-Discovery (ARM Cortex-M7)" with ARM-KEIL, GNU-ARM and IAR-ARM toolchains. - -This release also replaces assembly with C implementation in the ARM-KEIL ports or the QK and QXK kernels to Cortex-M to take advantage of the `__asm` functions. (NOTE: this change has impact on the existing QP/C applications that use the ARM-KEIL toolchain and the QK or QXK kernels.) - -Additionally, this release fixes some problems with the native examples for STM32F4 and STM32F7 boards. - -Additionally, this release adds a generic function QActive_setAttr() to set thread attributes in various QP ports to 3rd-party RTOSes. This function is then used in the @ref embos "embOS port" and the @ref uc-os2 "uC/OS-II port". - -Finally, this release fixes the following bug in the @ref threadx "ThreadX port": - -- [bug#197 "Problems with scheduler locking in QP/C/C++ ports to ThreadX"](https://sourceforge.net/p/qpc/bugs/197) - - -@section qpc_6_0_3 Version 6.0.3, 2017-12-12 -Changes since version 6.0.1: - -- fixed [bug#193 "QXK: context switch from extended to basic thread fails"](https://sourceforge.net/p/qpc/bugs/193) - -- replaced attributes of ::QActive and ::QEQueue classes from type `uint_fastX_t` to `uintX_t`. For the ARM Cortex-M port, these changes reduce the memory footprint of each ::QActive instance from 50 to 38 bytes (25% improvement). - -- improved the performance of the ARM Cortex-M0/M0+ ports, which do not supprt the CLZ (count leading zeros) instruction. All QP ports to Cortex-M0/M0+ (qv, qk and qxk) now contain hand-optimized assembly implementation of the LOG2 (log-base-2) function. The implementation executes only in 14 machine instructions and uses only 16-byte look-up-table (LUT). This replaces LOG2 implementation based on a 256-byte LUT. - -- changed the interrupt disabling policy in ARM Cortex-M ports back to "unconditional interrupt disabling", which is simpler and faster than "saving-and-restoring interrupt status". - -- added a port to ARM Cortex-M with the LLVM compiler (currently only for the dual-mode QXK kernel). Unlike the other ARM Cortex-M ports, the port to LLVM uses the "saving-and-restoring interrupt status" interrupt disabling policy (explicit request from a commercial customer). - -- removed ARM Cortex-M port and examples for the TI-ARM compiler. (Projects for the TI CCS can use the GNU-ARM toolchain and the existing GNU-ARM ports). - -- Added the DPP-COMP example (Dining Philosophers Problem) with the "Orthogonal Component" state pattern located in `qpc/examples/win32/dpp-comp`. This example demonstrates also a partitioned QM model into external packages for the Container (Table active object) and the Components (Philo active objects). - -@note -This release does not change any of the QP/C APIs. - - -@section qpc_6_0_1 Version 6.0.1, 2017-11-10 -The main focus of this release is to fix the remaining problems with transitions out of eXit-Points in sub-machines. Specifically, this release modifies the QMsm-based state machine implementation strategy (file src/qf/qep_msm.c to properly handle transitions from eXit-Points to Entry-Points and from eXit-Points to History connectors in sub-machines. These changes are part of fixing the following bugs reported for QM: - -- [bug#190 "Exit-Point segment targeting History doesn't work"](https://sourceforge.net/p/qpc/bugs/190) - -- [bug#189 "Exit-Point segment targeting an Entry-Point to sub-machine state doesn't work"](https://sourceforge.net/p/qpc/bugs/189) - -Additionally, this release fixes the following bug in transitions to "shallow history": -- [bug#191 "Transition to shallow history in QMsm causes assertion qep_msm#810"](https://sourceforge.net/p/qpc/bugs/191) - -The bug#191 is fixed by modifying the function QMsm_childStateObj_() in qep_msm.c to return the parent state in the corner case when the current state is the parent state. - - -@note -This QP/C 6.0.1 release is the minium version required in QM 4.1.0. This is because QM 4.1.0 assumes the modified QMsm-state machine implementation strategy in order to properly handle the various transitions out of eXit-Points in sub-machine states. - - -Additionally, this release changes the QXK implementation related to the [bug#186 "QXK: Extended thread context switch causes assertion in PendSV_Handler"](https://sourceforge.net/p/qpc/bugs/186). Specifically, the case of context switching away and back to the same thread (which can arise under specific interrupt preemption scenarios) is now handled as a simple return from PendSV. The QXK scheduler has been modified to set the "next" thread pointer to NULL when it detects switching back to the "current" thread. - - -@section qpc_6_0_0 Version 6.0.0, 2017-10-13 -This release fixes two bugs found in the QXK kernel: -- [bug#185](https://sourceforge.net/p/qpc/bugs/185) "QXK: PendSV_Handler uses inconsistent stack frames for saving and restoring AO for Cortex-M0(+)" -- [bug#186](https://sourceforge.net/p/qpc/bugs/186) "QXK: Extended thread context switch causes assertion in PendSV_Handler" - -Additionally, this release includes a fix for the bug found in ARM Cortex-M0 port with the GNU-ARM compiler: -- [bug#189](https://sourceforge.net/p/qpc/bugs/184) "QS_END() leaves all interrupts disabled with GNU-ARM" - -This specific problem observed in QSpy turned out to be caused by a bug in the GNU-ARM compiler itself. This problem affected the ARMv6-M architecture (Cortex-M0/M0+/M1) and manifested itself in generation of incorrect code for the QP critical section at certain gcc optimization levels (such as -O). This bug was first discovered and filed as [bug#184](https://sourceforge.net/p/qpc/bugs/184). The bug affected the GNU-ARM ports to all built-in kernels @ref srs_qv "QV", @ref srs_qk "QK", and @ref srs_qxk "QXK". - -@attention -This release no longer contains the directory `qpc/source`, which was scheduled to be phased out in QP5. In QP6 the source code is found only in the `qpc/src` directory. - - -@section qpc_5_9_9 Version 5.9.9, 2017-09-29 -This release implements the feature request [#132 "Extend the QXK mutex to support also simple operation without the priority-ceiling protocol"](https://sourceforge.net/p/qpc/feature-requests/132). - -@note -This release is completely backwards-compatible with the @ref qpc_5_9_8 "previous QP/C release 5.9.8". - -Specifically, the ::QXMutex class has been extended as follows: -- a mutex initialized with ceiling==0 (QXMutex_init(0)) means "no ceiling", so such mutex will NOT use the priority-ceiling protocol. -- in this case the mutex will NOT require a unique priority level -- in this case the mutex will not change (boost) the priority of the holding thread in the QXMutex_lock() operation. -- in this case the mutex will still support nesting of locks (as before), up to 255 levels of nesting. -- when initialized with `ceiling>0`, ::QXMutex WILL use the priority-ceiling protocol, as before. It will require that the ceiling priority be unique and not used by any other thread or mutex. In other words, the previous functionality remains unchanged. - - -@section qpc_5_9_8 Version 5.9.8, 2017-09-15 -This release fixes the QXK kernel [bug#182 " Inconsistent QXThread_post_() behavior with respect to the 'margin' parameter"](https://sourceforge.net/p/qpc/bugs/182). - -Also, the pre-condition assertion in the function QF_newRef_() (file `src/qf/qf_dyn.c`) has been modified to allow creating event references only for dynamic events `(e->poolId_ == 0)`. - -Improved comments in the soruce code. - -Modifed ARM Cortex-M examples with the GNU-ARM toolset to be consistent with QP/C++ (support for RTTI and C++ Exception handling), as follows: - -- removed definitions of `_init()` and `_fini()` from the GNU-ARM startup code for all supported boards in the `3rd_party` directory - -- commented out the call to `__libc_init_array()` in the GNU-ARM startup code for all supported boards in the `3rd_party` directory (because it requires `_init()`) - -- Modified all GNU-ARM linker scripts (.ld files) to add the following symbols: - -@verbatim - __exidx_start = .; - .ARM.exidx : { *(.ARM.exidx* .gnu.linkonce.armexidx.*) } >RAM - __exidx_end = .; -@endverbatim - - -@section qpc_5_9_7 Version 5.9.7, 2017-08-18 -The main focus of this release are new requested features for the @ref srs_qxk "dual-mode QXK kernel": -- feature#129 "Allow blocking while holding a mutex in QXK"; and -- feature#130 "Allow QXK mutex locks to nest while acquired by the same thread"; and -- feature#131 "Add a non-blocking "tryLock()" operation to the QXK mutex". - -Additionally, this release adds also the non-blocking QXSemaphore_tryWait() operation. - -In the process of re-implementing the ::QXMutex class, the previouis non-blocking priority ceiling mutex has been replaced with an equivalent selective QXK scheduler locking up to the specified ceiling priority. Specifically, this feature has been implemented with two new operations QXK_schedLock() and QXK_schedUnlock(). - -For consistency, the non-blocking mutex of the @ref srs_qk "QK kernel" has been also replaced by the operations QK_schedLock() and QK_schedUnlock(). - -All related QXK and QK examples have been updated to use the selective scheduler locking instead of the mutex. The new blocking QXK mutex has been demonstrated in the following updated examples: -- @ref arm-cm_dpp_efm32-slstk3401a -- @ref arm-cm_dpp_ek-tm4c123gxl - -@attention -The changes to ::QXMutex in QXK and the now obsolete QMutex in QK **break backwards-compatiblity** with the exising code that relies these features. In the exising code, the mutexes should be replaced with selective scheduler locking. - -@attention -Also, the blocking APIs with timeouts, such as QXMutex_lock(), QXSemaphore_wait(), QXThread_delay(), and QXThread_queueGet() no longer require the last `tickRate` parameter. This also **breaks backward-compatiblity** with the exising code that uses these operations. - -This release also updates CMSIS to version 5.1.0 (3rd_party/CMSIS). - -This release also adds the @ref api "API Reference" section to the QP/C documentation. - -Finally, this release fixes the following bug: -- bug#181 "Win32-qv port and QF_run "idle" time" - - -@section qpc_5_9_6 Version 5.9.6, 2017-08-04 -The main focus of this release are improvements to the "dual-mode" QXK kernel. Specifically, this release implements the featrue request #128 "QP Semaphore Max Value Setting" for QXK. This feature changes the QXK function QXSemaphore_init(), which now takes additional parameter `count`. This parameter specifies the maximum allowed count for the semaphore (e.g., count of 1 makes the semaphore a binary-semaphore). - -@note -This change breaks backwards-compatibility with the existing code that uses the QXSemaphore_init() function. - -This release also fixes a bug inside the assertions in QXSemaphore_signal(), where the check for the extended-thread is performed. - -Also, this release adds assertions to the QXK code, which ensure that any available blocking calls can only be made from extended-threads and not from basic-threads (active objects) or ISRs. - -Also, this release adds protection in the IRQ priorities initialization in QK/QV/QXK for ARM Cortex-M3/M4/M7, so that the number of IRQs is extracted from bits 0-2 of the ICTR register (INTLINESNUM). - -Finally, this release consistently changes all example projects (for all toolchains) to use the **src** directory for QP/C source code, instead of the **source** directory. The source/ directory is now truly obsolete, but is still provided in this release for backwards compatibility with user projects. - - -@section qpc_5_9_5 Version 5.9.5, 2017-07-20 -This release changes the macro QXTHREAD_START() in the QXK kernel so that -it can be used only with ::QXThread pointers and not ::QActive pointers. - -@note -The change of QXTHREAD_START() has impact on existing QXK applications, -because the calls like `QXTHREAD_START(&XT_Test1->super ~~~)` need to be -changed to `QXTHREAD_START(XT_Test1 ~~~)`, where XT_Test1 is a pointer -to `::QXThread *`. - -This release fixes the following bugs: -- bug#178 "GNU-ARM compiler reports "Error: unaligned opcodes~~~" in startup code for QP/C/C++/nano examples". The bug fix entails modifying the startup code for the GNU-ARM compiler in the `3rd_party` directory. Specifically, the proper alignment directives have been added to the inline assembly in the exception handlers. -- bug#179 "Assertion ID 210 fires when signaling on a QXK semaphore" - -This release fixes the naming problem of the startup code for the -STM32F7-Discovery board (in the `3rd_party/stm32f7-discovery/gnu/ and arm/` -directories), where the startup code was renamed from `startup_stm32f4xx.c/s` -to `startup_stm32f746xx.c/s`. The change has been also made in the example -projects for the STM32F7-Discovery board (for ARM-KEIL and GNU-ARM toolsets). - - -@section qpc_5_9_4 Version 5.9.4, 2017-07-07 -This release adds Thread-Local Storage (TLS) feature for the dual-mode -QXK kernel (see @ref srs_qxk_tls). - - -@section qpc_5_9_3 Version 5.9.3, 2017-06-19 -This release implements the feature request -#126 "Allow non-asserting -event allocation for zero-margin allocations". Specifically, calling -Q_NEW_X() or QACTIVE_POST_X() with the margin argument of zero will no -longer assert if the allocation/posting fails. - - -@section qpc_5_9_2 Version 5.9.2, 2017-06-05 -This release adapts the Makefiles for GNU-ARM to the new location of the -GNU-ARM toolset, which is now included in the QTools Collection (v 5.9.1) -for Windows. - -Also, this release improves the flash loading scripts for the JLink -hardware debugger (for GNU-ARM projects for the EFM32-SLSTK3401A board). -Specifically, the JLink configuration file for flash download is -generated by the flash batch script based on the command-line paramter -(the binary file to load into the flash). This eliminates the need to -manually maintain JLink configuration files. - -Also, this release adds bi-directional QP/Spy to the embOS example -project for the STM32F4-Discovery board. - -Also, this release adds GNU-ARM port to uC/OS-II and adds GNU-ARM example -project for the EK-TM4C123GXL board. - -Finally, this release implements the feature request #125 "Include QPC -Demo application for STM32F4 processor without RTOS" (see -https://sourceforge.net/p/qpc/feature-requests/125/ ). The DPP demo for -the STM32F4-Discovery board has been added in the directory: -qpc/examples/arm-cm/dpp_stm32f4-discovery . This demo includes QV, QK and -QXK kernels and ARM-Keil, GNU-ARM, and IAR-ARM toolsets. The demos support -bi-directional QP/Spy. - - -@section qpc_5_9_1 Version 5.9.1, 2017-05-26 -This release fixes the following bug: -- bug#169 "Submachine-state eXit Point does not work correctly" - -@note -The bug only affects sub-machines and does not affect any other -aspects of QMsm-style state machines. - -Also, this release changes the organization of the QP/C source code to -make it more friendly for the Eclipse CDT, as proposed in the feature -request #123 "Eclipse-friendly source directory structure for QP/C/C++". -Specifically, the QP/C source code is now provided in the -`qpc/src/` directory with the following structure: - -@verbatim -qpc/ - +-source/ - exitsting source directory with "flat" structure - | (for backwards-compatibility) - +-src/ - new source directory grouped by functionality - +-qf/ - core framework (QEP + QF) - +-qk/ - QK kernel - +-qv/ - QV kernel (only one file qv.c) - +-qxk/ - QXK kernel - +-qs/ - QS software tracing - +-qf_pkg.h - +-qs_pkg.h - +-qxk_pkg.h -@endverbatim - -@note The original `qpc/source` directory is still provided for backwards -compatibility with the existing QP/C projects. This directory will be -phased out in the future QP/C releases. Please use the new source code -structure provided in the `qpc/src` directory. - - -@section qpc_5_9_0 Version 5.9.0, 2017-05-19 -The main purpose of this milestone QP/C release is to provide support for the powerful **Unit Testing Framework** called -QUTest™ (pronounced *cutest*). -QUTest™ is the fundamental tooling for Test-Driven Development (TDD) of QP/C applications, which is a highly recommended best-practice. This release introduces changes in the QS-RX (receive) channel and adds several new callbacks. - -@note The signature of the QS_onCommand() has changed and the function now takes 3 arbitrary 32-bit parameters instead of one. This introduces backwards-incompatibility with previous code that used QS_onCommand(). - - -This release also changes the critical section for QP/C ports to ARM Cortex-M -in that the policy of "save and restore interrupt status" is used. This policy -permits nesting of critical sections, which was requested by customers. - -Additionally, this release changes the selective interrupt disabling for -ARM Cortex-M3/4/7 (with the BASEPRI register) to address the hardware problem -on ARM Cortex-M7 core r0p1 ([SDEN-1068427, erratum 837070](https://www.state-machine.com/doc/Cortex-M7_Software_Developers_Errata_Notice_v8.pdf)). The QP ports to -ARM Cortex-M3/4/7 now implement the workaround recommended by ARM, which is -to surround MSR BASEPRI with the "CPSID i"/"CPSIE i" pair. This workaround -works also for Cortex-M3/M4 cores. - -New ports: -- ports/win32-qutest folder contains port to QUTest for Windows -- ports/posix-qutest folder contains port to QUTest for POSIX (Linux) -- ports/arm-cm/qutest folder contains port to QUTest for ARM Cortex-M - -New examples: -- examples/qutest/dpp folder contains the QUTest DPP test for various - platforms (Win32, EFM32-SLSTK3401A and EK-TM4C123GXL) -- examples/qutest/qhsmtst folder contains the QUTest test for - the QHsmTst state machine (structural test) -- examples/qutest/qmsmtst folder contains the QUTest test for - the QMsmTst state machine (structural test) -- examples/qutest/self_test folder contains the QUTest self-test for - various features of QUTest -- examples/qutest/TDDbook_Flash folder contains the QUTest - of a flash memory driver from Chapter 10 of the "TDD-book" by James - Grenning. -- examples/qutest/TDDbook_LedDriver folder contains the QUTest - of a flash memory driver from Chapters 3&4 of the "TDD-book" by James - Grenning. -- examples/qutest/TDDbook_Sprintf folder contains the QUTest - of a flash memory driver from Chapter 1 of the "TDD-book" by James - Grenning. - -Updates of 3rd_party software: -- the 3rd_party/CMSIS folder has been updated to CMSIS 5.0.2. -- the 3rd_party/embOS folder has been updated to embOS 4.34.1 - -Finally, this release fixes the following bugs: -- bug#162 "QF critical sections require modification for M7 core" - - -@section qpc_5_8_2 Version 5.8.2, 2017-02-08 -This release adds examples for the ARM Cortex-M7 CPU. Specifically, -the release contains the standard @ref dpp "Dining Philosophers Problem (DPP)" -examples for the @ref arm-cm_dpp_stm32f746g-disco "STM32F746G-Discovery board", -all build-in kernels (QV, QK, and QXK), and ARM-KEIL, IAR EWARM, GNU-ARM toolsets. - -To provide examples for STM32F746G-Discovery board, the release now -provides the folder `3rd_party/stm32f7-discovery` with the support code -for the STM32F7xx MCUs, which contains parts of STM32CubeF7 library. - -Also, the `3rd_party/CMSIS` folder now provides the new CMSIS V5.0.1. - -Finally, this release fixes the following bugs: -- bug#159 QP/C/C++ Win32 ports don't work on all x86 CPUs -- bug#157 In QPC ucosii port, conversion of AO's priority to OS task - priority is incorrect. -- bug#152 Typo (qpc/ports/arm7-9/qk/gnu/qk_port.s:42) prevents - compilation - - -@section qpc_5_8_1 Version 5.8.1, 2016-12-16 -This release is in response to a recent finding that many QP users of the -ports to ARM Cortex-M3/M4 forget to explicitly set their interrupt priorities, -as described in the AppNote "Setting ARM Cortex-M Interrupt Priorities in QP 5.x". - -Specifically, this release improves safety of QP ports to ARM Cortex-M3/M4, -by initializing the interrupt priorities to a safe default in a generic, -portable way. This QP port includes such a fix for QV/QK/QXK ports to ARM Cortex-M3/M4. - -Additionally, this release introduces the new ::QTicker class, which is an -efficient active object specialized to process QF system clock tick at a -specified tick frequency [0..(#QF_MAX_TICK_RATE - 1)]. Placing system clock tick -processing in an active object allows you to remove the non-deterministic -QF_TICK_X() processing from the interrupt level and move it into the thread-level, -where you can prioritize it as low as you wish. - -Changes in detail: -- modified the QV, QK, and QXK source code to call QV_init(), QK_init(), and - QXK_init(), respectively. -- modified the ARM Cortex-M ports of QV, QK, and QXK to initialize - priorities all exceptions and IRQs to the safe value #QF_BASEPRI. - -@note The QV port now has a new **qv_port.c** module that needs to - be added to the build. - -- added declaration of the ::QTicker class to qf.h -- added implementation of the ::QTicker class to qf_actq.c -- modified the following examples to demonstrate the use of the ::QTicker: - + qpc/examples/arm-cm/dpp_efm32-slstk3401a/qk - + qpc/examples/arm-cm/game_efm32-slstk3401a/qv - + qpc/examples/arm-cm/game_efm32-slstk3401a/qk -- added the header file **cmsis_ccs.h** to qpc/3rd_party/CMSIS/Include directory - (used in the examples for the Code Composer Studio). The file has been - dropped during the upgrade to CMSIS 5.0.1, because it is not part of the - standard distribution. - - -@section qpc_5_8_0 Version 5.8.0, 2016-11-30 -The main purpose of this milestone QP/C release is to finally provide -the baseline framework fully compatible with the upcoming QM 4.0.0. - -This release changes the class hierarchy so that QHsm becomes the base -class of ::QMsm and ::QActive. Also, ::QActive becomes the base class of -::QMActive, which reverses the changes introduced in version 4.1. - -The modified @ref classes "class hierarchy" better reflects the fact that ::QHsm state -machine implementation strategy is simpler and supports less functionality -than the more advanced ::QMsm strategy. For example, only the ::QMsm class -fully supports sub-machines and sub-machine states that are the main -feature of QM 4.x. This clean progression of supported functionality from -subclasses to superclasses allows QM to easier check and enforce that -advanced features are not generated for subclasses that don't have the -required capabilities. (With previous class hierarchy with ::QMsm as the -base class all subclasses, including QHsm, would technically inherit the -advanced functionality, which is not the case). - -@note -All changes in QP/C 5.8.0 remain transparent for the existing QP/C applications, -because of the provided backwards compatibility layer in qpc.h. - -Also, this release changes the implementation of the QV, QK, and QXK kernels -in that the ready-set representing active threads is cleared only *after* -completion of the RTC-step, not when the last event is removed from the -corresponding event queue. In case of the QXK kernel this change fixes the -high-priority bug#147. -But even in case of the QV and QK kernels, where this behavior didn't lead -to any bugs, the policy better reflects the semantics of the ready-set. - -This release also updates the CMSIS interface included in the 3rd_party/CMSIS -folder to the latest CMSIS-5. - -All examples and QM models have been updated to the new upcoming QM 4.0.0. -All these models require QM 4.x. - -Finally, the complete list of bugs fixed in this release is as follows: - -- bug#147 "QXK: PendSV_error is triggered on special conditions" -- bug#146 "Misra-C 2004 warning for rule 8.3 in qxk.c" -- bug#144 "Obsolete Win32 API in qwin_gui.c" -- bug#143 "QACTIVE_POST_LIFO() on initial transition asserts on QXK" -- bug#124 "Windows port now cause memory leakage" - - -@section qpc_5_7_4 Version 5.7.4, 2016-11-04 -This release fixes the following bugs: -- bug#145 QF_PUBLISH() leaks events that have no subscribers -- bug#144 Obsolete Win32 API in qwin_gui.c -- bug#143 QACTIVE_POST_LIFO() on initial transition asserts on QXK - - -@section qpc_5_7_3 Version 5.7.3, 2016-10-07 -This release adds QP ports to the TI-RTOS kernel (SYS/BIOS) with TI-CCS -and IAR EWARM toolsets. Examples are provided for the EK-TM4C123GXL -(TivaC LaunchPad) in the directory: - -qpc/examples/ti-rtos/arm-cm/dpp_ek-tm4c123gxl - -NOTE: The examples require a separate installation of the TI-RTOS -(file tirtos_tivac_setupwin32_2_16_01_14.exe) - -Also, this release fixes the following bugs: -- bug#140 (PendSV_Handler() exception stacked PC not halfword aligned). -- bug#142 (PendSV_restore_ex may not be able to enable interrupt before - returning to task). - - -@section qpc_5_7_2 Version 5.7.2, 2016-09-30 -This is the first production release of the "dual-mode" QXK kernel. -"Dual-mode" QXK means that QXK supports both basic-threads (BC1 class -from the OSEK/VDX RTOS specification) as well as extended-threads -(EC1 class from the OSEK/VDX RTOS specification. In other words, -QXK executes active objects (basic threads) like the QK kernel using the -single stack (Main Stack on ARM Cortex-M), but can also execute -traditional *blocking* threads (extended threads). - -Only the extended threads (::QXThread class) need their private stack -spaces and the overhead of the full context switch. The basic threads -(::QMActive and ::QActive classes) run efficiently using the main stack with -much lower context switch overhead. - -The QXK examples have been updated for more thorough demonstration of -the QXK features. The QXK examples are available in the following -directories: dpp_efm32-slstk3401a, dpp_ek-tm4c123gxl, and dpp_nucleo-l053r8. - -This release fixes several issues in QXK 5.7.1-beta with handling -timeouts while blocking in extended-threads, such as timed blocking on -event queues and semaphores. - -This release also changes the internal QK implementation to match the -terminology applied in the QXK kernel (e.g., QK_sched_() has been renamed -to QK_activate_() and QK_schedPrio_() to QK_sched_()). These changes fall -into the category of refactoring and have no impact on the API or -performance. - -Finally, this release improves the implementation of scheduler locking -in publish-subscribe event delivery. - - -@section qpc_5_7_0 Version 5.7.0, 2016-08-31 -This release adds support for sub-machines and sub-machine states for reusing pieces of state machines (an advanced UML concept) to the QMsm-state machine implementation strategy. This feature is to match the upcoming QM 4.0.0. - -Also, this release adds support for the ARM Cortex-R processor. Specifically, the release contains a generic port to ARM Cortex-R with the IAR and TI-CCS toolsets and examples for the TI Hercules TMS570LS12x safety MCU (LAUNCHPADXL2-TMS57012). - -Also, this release changes once more the QK port to ARM Cortex-M, to reduce the interrupt latecy. This has been achieved by shortening the critical section in the PendSV exception. - -Also, this release changes slightly the QXK port to ARM Cortex-M, where again the critical section in PendSV has been slighly shortened. - -Finally, this release replaces all absolute paths with relative paths in all CCS-Eclipse project files (for TivaC, Hercules, and MSP430). - -Changes in detail: - -1. Modified qep_msm.c to correct the support for sub-machines and sub-machine states -2. Added new port to ARM Cortex-R in the directory ports/arm-cr -3. Added examples for ARM Cortex-R in the directory examples/arm-cr -4. Modified the ARM Cortex-M QK ports (ARM-KEIL, GNU, IAR, and TI) -5. Modified the ARM Cortex-M QXK ports (ARM-KEIL, GNU, IAR, and TI) - - -@section qpc_5_6_5 Version 5.6.5, 2016-06-06 -This release adds support for the new board: EFM32-SLSTK3401A (Pearl Gecko Starter Kit from Silicon Labs). This board replaces the Stellaris EK-LM3S811 board, which has been discontinued. (The Stellaris EK-LM3S811 board had been used in the "Fly 'n' Shoot" game example accompanying the PSiCC2 book). - -This release also introduces a new version of the QWIN GUI Toolkit in the Windows prototypes for the "Fly 'n' Shoot" game and the DPP-GUI -version (see https://www.state-machine.com/products/qtools/#QWin). - -Additionally, this release also includes the QP/C integration with the emWin emgedded GUI from SEGGER, which is also the same product as -uC/GUI distributed by Micrium (@ref exa_emwin). - -Finally, this relase comes with updated project files for TI Code Composer Studio (both for ARM Cortex-M and for MSP430). - -This release fixes the following bugs: -- bug#130 (POSIX port stop->start leads to reuse of sestroyed mutex). -- bug#131 (QF_newRef_ increments reference counter without QF_CRIT_ENTRY_()). - - -@section qpc_5_6_4 Version 5.6.4, 2016-04-25 -This release fixes a serious Bug #128 (https://sourceforge.net/p/qpc/bugs/128 ) in the QK port to ARM Cortex-M introduced back in QP 5.6.1 - - -@section qpc_5_6_3 Version 5.6.3, 2016-04-12 -This release fixes a serious Bug #126 (https://sourceforge.net/p/qpc/bugs/126 ) in the QK preemptive scheduler introduced in QP 5.6.2. - - -@section qpc_5_6_2 Version 5.6.2, 2016-03-31 -The main purpose of this release is to introduce _atomic event multicasting_, meaning that event publishing to all subscribers is now protected from preemption. This eliminates potential for re-ordering of events under preemptive kernels (such as QK, QXK, or 3rd-party RTOSes), when events are published from low-priority AOs and some higher-priority subscribers can preempt multicasting and post/publish events of their own (before the original event is posted to all subscribers). - -The atomic event multicasting is implemented by means of selective scheduler locking--very much like a priory-ceiling mutex. During event multicasting the scheduler gets locked, but only up to the highest-priority subscriber to a given event. The whole point here is that active objects with priorities above such "priority ceiling" are _not_ affected. Please see the discussion thread: - -https://sourceforge.net/p/qpc/discussion/668726/thread/c186bf45 - -This release also changes the implementation of the priority-ceiling mutex in the preemptive built-in kernels: QK and QXK. Specifically, the implementation now re-uses the selective scheduler locking mechanism. In this new implementation, the QXMutex of the QXK kernel is much more efficient and lightweight, but it _cannot block_ while holding a mutex. - -Finally, this release changes the QP ports to 3rd-party RTOSes by performing any RTOS operations (like posting events to message queues) outside critical sections. Also the ports have been augmented to support scheduler locking (this feature depends on what's available in the specific RTOSes). - -Changes in detail: - -1. Added scheduler locking to QF_publish_() in qf_ps.c. This feature is added in a portable way, via macros #QF_SCHED_STAT_TYPE_, QF_SCHED_LOCK_() and QF_SCHED_UNLOCK_(), which need to be implemented in every QP port. - -2. Modified QV kernel to provide (dummy) implementation of selective scheduler locking. - -3. Modified QK kernel to implement selective scheduler locking via modified priority-ceiling mutex QMutex. - -4. Modified QXK kernel to implement selective scheduler locking via modified priority-ceiling mutex QXMutex. - -5. Modified embOS port to provide (global) scheduler locking, which affects all priorities, because that's all embOS supports. Also, modified the embOS port to perform event posting outside the QF critical section. - -6. Modified uC/OS-II port to provide (global) scheduler locking, which affects all priorities, because that's all uC/OS-II supports. Also, modified the uC/OS-II port to perform event posting outside the QF critical section. - -7. Modified ThreadX port to provide selective scheduler locking, by means of "priority-threshold" available in ThreadX. Also, modified the ThreadX port to perform event posting outside the QF critical section. - -8. Changed the ThreadX example to run on ARM Cortex-M4 board (STM32DiscoveryF4), instead of Win32 emulation (see qpc/examples/threadx/arm-cm/dpp_stm32f429-discovery). - -9. Modified the Win32 port to provide (global) scheduler locking, which is implemented by Win32 critical section. - -10. Fixed Bug#122 (QP didn't initiate some internal variables) https://sourceforge.net/p/qpc/bugs/122/ by adding explicit clearing of all QP variables in QF_init(). - -11. Modified the POSIX port to dummy-out scheduler locking. This means that this port currently does NOT lock scheduler around event publishing. (At this point it is not clear how to implement POSIX scheduler locking in a portable way.) - -12. Modified QK and QXK examples in qpc/examples/arm-cm/dpp_ek-tm4c123gxl to demonstrate the usage of the new priority-ceiling mutexes. - -13. Fixed the 3rd-party file startup_stm32l32l1xx.c to include exceptions for Cortex-M3 (MemManage_Handler, BusFault_Handler, and UsageFault_Handler). - -14. Updated the 3rd-party files for the EK-TM4C123GXL board (TivaC LaunchPad). - -15. Modified Makefiles for the EK-TM4C123GXL board with GNU-ARM toolset to define the symbol TARGET_IS_TM4C123_RB1 for compatibility with the updated 3rd-party files. - -16. Implemented Feature Request #110 as well as the duplicate Request #62 by adding function QActive_flushDeferred() - - -@section qpc_5_6_1 Version 5.6.1, 2016-01-01 -This release is the first official (production) release of the new blocking @ref srs_qxk "QXK" kernel. - -Changes in detail: - -1. Added error directives to source files from different built-in kernels (QV, QK, and QXK) to generate meaningful error messages when these files are mixed in one project. For example, a project based on QK will report errors when source files for QV or QXK are included in it. - -2. Corrected example projects for the ARM Cortex-M with TI/CCS toolset - - -@section qpc_5_6_0 Version 5.6.0-beta, 2015-12-24 -The main purpose of this *beta* release is to introduce a new component of the QP/C framework called @ref srs_qxk "QXK" ("eXtended Quantum Kernel"). QXK is a small, preemptive, priority-based, **blocking** kernel that provides most features you might expect of a traditional blocking RTOS kernel. - -QXK has been designed specifically for applications that need to mix event-driven active objects with traditional blocking code, such as commercial middleware (TCP/IP stacks, UDP stacks, embedded file systems, etc.) or legacy software. The QXK kernel is integrated tightly and optimally with the rest of the QP. It reuses all mechanisms already provided in QP, thus avoiding any code duplication, inefficient layers of indirection, and additional licensing costs, which are inevitable when using 3rd-party RTOS kernels to run QP/C applications. - -@note -The QXK documentation is available in the QP/C Reference Manual at @ref srs_qxk - - -Additionally, this release removes the macros Q_ROM, Q_ROM_BYTE, and Q_ROM_VAR from the QP/C code. These macros have been necessary for odd Harvard-architecture 8-bit CPUs (such as AVR, 8051) to place constant data in ROM. As QP/C stopped supporting those CPUs, the non-standard extensions could be removed from the QP/C code base. - -Additionally, this release re-designs the priority-ceiling mutex in the QK kernel, which now works the same as the mutex of the new QXK kernel. Also, the QK ports to ARM Cortex-M no longer need or use the SVC_Handler (Supervisor Call). This is done to make the QK ports compatible with various "hypervisors" (such as mbed uVisor or Nordic SoftDevice), which use the SVC exception. - -Finally, this release modifies the GNU-ARM ports of QK for ARM Cortex-M, to use the __ARM_ARCH macro to distinguish among different architectures (ARCHv6 vs ARCHv7). - -Changes in detail: - -1. Added new header files for QXK: qxk.h, and qxthread.h. - -2. Added new source files for QXK: qxk.c, qxk_mutex.c, qxk_pkg.h, qxk_sema.c, qxk_xthr.c. - -3. Added QXK ports to ARM Cortex-M for ARM-KEIL, GNU-ARM, IAR, and TI-ARM toolsets (see @ref arm-cm_qxk) - -4. Added QXK examples for ARM Cortex-M (in @ref arm-cm_dpp_ek-tm4c123gxl and @ref arm-cm_dpp_nucleo-l053r8) for all supported toolsets. - -5. Removed Q_ROM, Q_ROM_BYTE, and Q_ROM_VAR from the QP/C code. - -6. Added Q_ROM, Q_ROM_BYTE to the compatibility-layer in qpc.h. - -7. Removed ports and examples for the following 3rd-party RTOSes: CMSIS-RTX and FreeRTOS, as QXK provided all the features found in those kernels and is recommended over those kernels. - -8. Removed AVR ports and examples. - -9. Re-designed the QK priority-mutex in files qk.h and qk_mutex.c. - -10. Provided QK mutex examples in @ref arm-cm_dpp_ek-tm4c123gxl and @ref arm-cm_dpp_nucleo-l053r8. - -11. Updated Makefiles for GNU-ARM to use the __ARM_ARCH macro for defining the ARM architecture. - -12. Updated CMSIS from 4.2 to 4.3 in qpc/3rd-party/CMSIS - - -@section qpc_5_5_1 Version 5.5.1, 2015-10-05 -The main focus of this release is to improve the AAPCS compliance of the -ARM Cortex-M port to the QK preemptive kernel. Specifically, the PendSV -handler in assembly did not always maintain the 8-byte stack alignment, -which is required by AAPCS. This version corrects the stack misalignment -in the qk_port.s files for all supported ARM compilers (ARM-Keil, GNU, -IAR, and TI CCS). All these ports should also be ready for ARM Cortex-M7. - -Also, this release adds support for the TI CCS ARM compiler. -Specifically, a new ARM Cortex-M ports have been added (in directories -`qpc/ports/arm-cm/qk/ti/` and `qpc/ports/arm-cm/qk/ti/`) and TI CCS -example projects have been provided (in directories -`qpc/examples/arm-cm/dpp_ek-tm4c123gxl/qk/ti/` and -`qpc/examples/arm-cm/dpp_ek-tm4c123gxl/qv/ti/`). - -Finally, this release corrects a bug in the DPP example for -EK-TM4C123GXL with the QV (Vanilla) cooperative kernel. Specifically, -the file `qpc/examples/arm-cm/dpp_ek-tm4c123gxl/qv/bsp.c` did not -re-enable interrupts in the QV_onIdle() callback. - - -@section qpc_5_5_0 Version 5.5.0, 2015-09-04 -The main purpose of this release is the extension of the QS software tracing system to bi-directional communication with embedded Targets. Specifically, the QS-RX (receive channel for QS) has been added with the following capabilities: - -1. Set global QS filters inside the Target - -2. Set local QS filters inside the Target - -3. Inject an arbitrary event to the Target (direct post or publish) - -4. Execute a user-defined callback function inside the Target with arguments supplied from QSPY - -5. Peek data inside the Target and send to QSPY - -6. Poke data (supplied from QSPY) into the Target - -7. Execute clock tick inside the Target - -8. Request target information (version, all sizes of objects, build time-stamp) - -9. Remotely reset of the Target - - -This QP/C version complements the recent release of Qtools 5.5.0, where the QSPY host application has been extended with a UDP socket, which is open for communication with various Front-Ends (GUI-based or headless). An example Front-End written in Tcl/Tk called "QspyView" has been developed to demonstrate all the features. The example application located in the directory qpc/examples/arm-cm/dpp_ek-tm4c123gxl/qspy contains customization of the "qspyview" script for the DPP application. Please refer to the documentation of this example (@ref arm-cm_dpp_ek-tm4c123gxl) for more information. - -Finally, this release adds a state machine operation for implementing -the shallow history mechanism. The operation is called "childState", -because it computes a child state of a given parent, such that the child -belongs to the same state hierarchy as the current state. - -Changes in detail: - -1. Modified the QS software tracing component to add new functionality, -such as the QS-RX input channel. Also added new trace records. - -2. Added file "qstamp.c" (in the qpc/include/ folder) to provide -time-stamp of the application build. - -3. Added function QMsm_childStateObj() to the QMsm class and -QHsm_childState() to the QHsm class. These functions have been added to -support the shallow-history mechanism. - -4. Modified all example projects (qpc/examples/ folder) to include the -"qstamp.c" file and force its re-compilation for each new build, so that -every build has an up-to-date and unique time stamp. - -5. Extended the DPP on TivaC LauchPad example (directory -`qpc/examples/arm-cm/dpp_ek-tm4c123gxl/`) to demonstrate QS-RX (QS receive -channel). - -6. Provided example of customizing the "QspyView" Tcl/Tk script for the -DPP application in the directory qpc/examples/arm-cm/dpp_ek-tm4c123gxl/qspy/ - -7. Modified all examples (qpc/examples/ folder) to call the -QS_ASSERTION() macro to the Q_onAssert() callback function. - -8. Modified the startup code (in the qpc/3rd_party/ folder) for ARM -Cortex-M to invoke the Q_onAssert() callback from the assert_failure() -exception handler. This is to allow application-level code to define -Q_onAssert() for each specific project. - -9. Replaced deprecated registers in TM4C (TivaC) projects -(SYSCTL->RCGCGPIO rather than the deprecated SYSCTL->RCGC2). - - -@section qpc_5_4_2 Version 5.4.2, 2015-06-04 -The main focus of this release is to improve the support for "dual targeting" of QP/C applications, which is developing of deeply embedded code as much as possible on the desktop OS, such as Windows. Experience shows that "dual targeting" dramatically improves productivity of embedded systems developers, perhaps more than any other technique. - -This release makes it possible to use exactly the **same** application code, main function, and the Board Support Package interface (bsp.h) on both deeply embedded target and on Windows. The only differences between these targets can be completely encapsulated in the Board Support Package implementation (bsp.c). - -The support for "dual targeting" in this QP/C release works both for Win32 console and Win32 GUI applications. The Win32-GUI support enables developers to easily emulate the front-panels of the embedded devices, with LCD-screens (graphical and segmented), LEDs, buttons, switches, sliders, etc. - -Changes in detail: - -1. Modified the QP/C ports to Windows (both @ref win32 and @ref win32-qv) so that they support both Win32 console and Win32-GUI applications. The newly introduced pre-processor #WIN32_GUI macro is now required to use the Win32-GUI facilities. - -2. Added portable "safe" macros from `` and `` to the QP/C ports to Windows. These macros encapsulate the differences between Microsoft Visual C++ and other compilers (such as MinGW). - -3. Simplified the structure of the QP/C Windows ports by eliminating one level of directories for the compilers used. Both VC++ and MinGW builds can now be run in the same port directory. - -4. Modified the QF_stop() function in the QP/C port to @ref win32-qv, so that it unblocks the QV event-loop and thus lets the application terminate. - -5. Modified all examples for Windows to use the new port structure. - -6. Improved all Makefiles (for the MinGW toolset) in all Windows examples, to make them easier to adapt to custom applications, both Win32 console and Win32 GUI. - -7. Moved several examples from the `examples/win32/` and examples/win32-qv directories to `examples/arm-cm/` directory with native embedded examples for ARM Cortex-M. This co-location of the Win32 emulation with the embedded code running on the actual board demonstrates better the "dual targeting" development approach. - -8. Updated all Windows examples to the latest QP API by compiling the code with the macro #QP_API_VERSION set to 9999 (latest API without backwards compatibility) - -9. Improved the PC-Lint support for checking the application-level code located in in `examples/arm-cm/dpp_ek-tm4c123gxl/lint` - - -@section qpc_5_4_1 Version 5.4.1, 2015-05-14 -This release changes the active object class hierarchy so that ::QMActive is now more fundamental and is the base class for ::QActive. (Previously ::QMActive was a subclass of ::QActive). The newly added documentation section about @ref classes "QP/C Design" shows the current class hierarchy. - -@note -Because the types ::QMActive and ::QActive are equivalent in QP/C, this change has minimal impact on the applications, but it is now more correct to use ::QMActive as the base class for all "opaque" active object pointers. - -Also, this release brings several cosmetic improvements: - -1. All QM models included in examples have been modified to use the ::QMActive "opaque" pointers. - -2. All QM models have been saved with QM 3.3.0, which means that they will not open with QM 3.2.x or earlier QM versions. - -3. The ROM-able QP version string QP_versionStr[] has been added and used consistently in the macros QEP_getVersion(), QF_getVersion(), QK_getVersion(), QV_getVersion(), and QS_getVersion() macros. - -4. The `qpc/ports/arm-cm/qk/gnu/qk_port.s` ARM Cortex-M port to QK with GNU has been modified to use the CMSIS-compliant symbol __FPU_PRESENT instead of the FPU_VFP_V4_SP_D16 symbol. - -5. All Makefiles for the GNU toolset have been cleaned up, whereas any `/` (back-slash) characters in the paths have been repalced with `/` (forward-slash) characters. Also all these Makefiles have been updated to provide the __FPU_PRESENT to C and assembler when the hardware FPU is used. - -6. The file display drver for the EK-LM2S811 board locate at `qpc/3rd_party/ek-lm3s811/display96x16x1.c` has been modified to fix the problem with incorrect hardware delay with the GNU compiler at higher levels of optimization. The in-line assembly for the GNU compiler has been updated such that the delay loop cannot be "optimized away". - -7. Several README files have been updated. - - -@section qpc_5_4_0 Version 5.4.0, 2015-04-26 -This release changes the basic philosophy of distributing the QP frameworks by **combining** the "QP/C Baseline Code" with all currently available "QP/C Development Kits" (QDK/C). This is done to eliminate any potential mistakes in downloading and installing separate pieces of code. - -Additionally, this release changes the basic philosophy of building your embedded applications with the QP/C framework. Starting with this release, all @ref exa "examples" for embedded boards include the QP/C framework as **source code** within the projects, instead of statically linking with a QP/C library. (**NOTE:** It is still possible to use QP/C as a library, but you need to build such libraries yourself, as they are no longer provided in the QP/C distribution.) - -The move to building QP/C from sources ensures the consistent toolset version and compiler options applied to the application code as well as the QP/C framework code. (**NOTE:** The QP/C examples for "big operating systems", like @ref exa_os "Windows/POSIX", still use QP/C as a pre-compiled library that is statically linked with the application code.) - -@note -Even though the QP/C source has been re-packaged in this release, there are no API changes to the code, so it remains **backwards compatible** with the existing applications. (Except the build process, which builds QP/C from sources rather than linking to the QP/C library.) - -The two changes in basic approach to distributing and building the framework have also the following ripple effects: - -1. The QP/C source code has been simplified and has been re-packaged into a much smaller number of source files. The whole QP/C source code now resides in the single source folder. Additionally, the source code files have now the **read-only** protection to prevent inadvertent changes to the QP/C soruce code that is part of your projects. - -2. It is no longer necessary to define the **QPC environment variable** to build the QP/C examples. All directories and files referenced by example projects are **relative** to the project folder. This change reflects the fact that most development tools add source files to the project using relative paths (and now the projects contain QP/C source code, not just the QP library). - -3. The QP/C @ref ports folder has been reorganized to contain all currently available QP/C ports. The ports are organized into three categories: @ref ports_native "native QP/C ports" ("bare-metal"), @ref ports_rtos "ports to 3rd-party RTOSes", and @ref ports_os "ports to big operating systems" (Windows and Linux).(**NOTE**: the ports are now documented in the this QP/C Reference Manual. Each port sub-directory contains a README link to the corresponding page in the online documentation) - -5. The QP/C @ref exa folder has been reorganized to reduce the repetitions and contains all currently available QP/C examples. The folder includes four categories of examples: @ref exa_native "native QP/C examples" ("bare-metal"), @ref exa_rtos "examples for 3rd-party RTOSes", @ref exa_os "examples for big operating systems" (Windows and Linux), and @ref exa_mware "examples for 3rd-party Middleware". As mentioned before, all example projects for embedded systems use QP/C as source code and not as a library. The examples folder has been expanded to contain all currently available QP/C examples, many of them are new in this release. (**NOTE**: the currently available examples are now documented in the QP/C Reference Manual. Each example sub-directory contains a README link to the corresponding page in the online documentation) - -6. A new 3rd_party folder created to contain the Third-Party code used in the QP/C ports and examples, such as MCU register files, low-level startup code, device drivers, etc. The 3rd_party folder avoids the need to repeat such code in every project. Also, the separation of the Third-Party components helps to clearly indicate code that comes from various sources, and to which Quantum Leaps, LLC expressly makes **no claims of ownership**. The Third-Party software components included in this "3rd_party" folder are licensed under a variety of different licensing terms that are defined by the respective owners of this software and are spelled out in the README.txt or LICENSE.txt files included in the respective sub-folders. - -7. This release also comes with the much expanded online QP/C Reference Manual, which is cross-linked with the ports and examples. - - -Changes in detail: - -1. Renamed the "Vanilla" scheduler to the @ref comp_qv "QV cooperative kernel" for symmetry with the @ref comp_qk "QK preemptive kernel". Renamed QF_onIdle() callback to QV_onIdle(). - -2. Removed class QFsm (which is now deprecated). Legacy state machines coded in the "QFsm-style" will continue to work, but will use the ::QHsm implementation internally. There is no longer any efficiency advantage in using the "QFsm-style" state machines. - -3. Applied a slight performance improvement to the ARM Cortex-M port to the QK preemptive kernel. The QK port now checks for ISR context by looking at the IPSR register, instead of incrementing and decrementing the `QF_intNest_` up-down counter. - -4. Updated @ref exa_arm-cm "ARM Cortex-M examples" and provided new examples for NXP mbed-LPC1768, and STM32 NUCLEO-L053R8, and NUCLEO-L152RE boards. All examples now use the latest CMSIS (V4.3.0). All ARM Cortex-M exampels are provided for the ARM-KEIL, GNU-ARM, and IAR-ARM toolsets. - -5. Added the native @ref arm7-9 "port" and @ref exa_arm7-9 "examples" to the @ref arm7-9 "classic ARM7/9" with AT91SAM7S-EK board and the IAR-ARM toolset. - -6. Added the native @ref avr "port" and @ref exa_avr "examples" to the AVR (AVRmega) with GNU-AVR and IAR-AVR toolsets. The @ref exa_avr "examples" are provided for the Arduino-UNO board. - -7. Added the native @ref msp430 "port" and @ref exa_msp430 "examples" to MSP430 with TI CCS-430 and IAR-430 toolsets. The @ref exa_msp430 "examples" are provided for the MSP430 LauchPad board (MSP-EXP430F5529LP for the "classic" MSP430 and "extened" MSP430X, respectively). - -8. Added port to @ref cmsis-rtx "CMSIS-RTOS RTX". Examples are available for TI EK-TM4C123GLX, STM32 NUCLEO-L053R8, and NUCLEO-L152RE boards with ARM-KEIL, GNU-ARM, and IAR-ARM toolsets. - -9. Updated port to @ref embos "embOS". Examples are available for STM32 STM32F4-Discovery board with IAR-ARM toolset. - -10. Updated port to @ref freertos "FreeRTOS" for the latest version 8.2.1. Examples are available for TI EK-TM4C123GLX board with GNU-ARM and IAR-ARM toolsets. - -11. Added @ref threadx "port to Thread-X". Example is available for the Thread-X demo with Visual Studio on Windows. - -12. Updated port to @ref uc-os2 "uC/OS-II" for the latest version v2.92. Examples are available for TI EK-TM4C123GLX and STM32 NUCLEO-L152RE boards with ARM-KEIL and IAR-ARM toolsets. - -13. Updated @win32 "port to Win32" (Windows). Modified the port to apply a generous "fudge factor" in over-sizing QP event queues and event pools, to minimize the risk of overflowing queues/pools due to non-deterministic Windows behavior. - -14. Added new @ref win32-qv "port to Win32-QV" (Windows with cooperative "Vanilla" scheduler, previously known as Win32-1T). - -15. Updated the @ref lwip_ek-lm3s6965 "lwIP-QP example for EK-LM3S6965 board". - - -@section qpc_5_3_1 Version 5.3.1, 2014-09-19 -@note QP/C 5.3.1 remains backwards-compatible with all QP/C ports and -applications - -This release fixes the following bugs: - -1. QMsm_isInState() returns invalid result (bug #105) - -2. QP/C syntax error in qf_pkg.h (bug #104) - -3. QF_gc() doc typo (bug #102) - -4. POSIX-port Makefile error (bug #65) - - -Additionally, this release improves the uC/OS-II port in that it is now generic and applicable for any CPU, for which uC/OS-II port exists. Specifically, all references to DOS or x86 have been removed from the QP port and any CPU-specific dependencies have been placed in the separate part of the port. - -Finally, this release improves the "QP/C Reference Manual" generated by Doxygen and available both inside the QP/C baseline distribution (qpc.chm file) and online at: https://www.state-machine.com/qpc - - -@section qpc_5_3_0 Version 5.3.0, 2014-03-31 -This release adds the "transition to history" (deep history) feature to -both QHsm and QMsm state machines and their subclasses. This QP/C -release matches the new QM modeling tool version 3.1.0, which now -supports the "transition to history" connector and the corresponding -code generation for transitions to history. - -@note QP/C 5.3.0 remains backwards-compatible with QP/C applications -developed for QP/C 4.x and QP/5.x. However, any QM models created for -the previous QP/C versions require re-generating the code with QM 3.1.0. - -This release adds new QS (Quantum Spy) instrumentation for tracing -transitions to history as well as entry and exit points in submachines. -All these features require the matching QSPY host application included -in Qtools 5.3.0. - -Additionally, the QMsm state machine has been extended to add -implementation of the reusable submachine states and submachines with -entry points and exit points. The reusable submachines in QP/C 5.3.0 lay -the groundwork for providing reusable submachine states and submachine -diagrams in the next upcoming QM version. - -This release also goes several steps towards compliance with the new -MISRA-C:2012 rules. For example, unused tag declarations have been -removed (MISRA-C:2012 Rule 2.4), the C99 standard Boolean data type in - has been added instead of uint8_t for stricter type -analysis, and the C99 data types uint_fast8_t and uint_fast16_t are used -instead of the non-standard uint_t. - -Finally, this QP/C release brings deep changes in the source code -comments and the doxygen documentation generated from the source code. -All comments have now more consistent structure, and every function is -now documented in the implementation file (.c file), whereas the -interface (.h files) contain only the brief descriptions of the -functions. This re-structuring of documentation is performed as part of -the validation and verification effort that has begun to provide a -certification package for QP/C for safety standards, such as IEC 61508 -and ISO 62304 (FDA 510(k)). - - -Changes in detail: - -1. Moved detailed documentation of functions from the header files (.h) -to implementation files (.c). - -2. Removed the header file "qevt.h" and merged its contents into "qep.h" - -3. Added macros: trace records QS_QEP_TRAN_HIST, QS_QEP_TRAN_EP, and -QS_QEP_TRAN_XP to "qs.h" - -4. Added macros: Q_TRAN_HIST(), QM_TRAN_HIST(), QM_TRAN_EP(), -QM_TRAN_XP(), and QM_SUPER_SUB() to "qep.h" - -5. Added attributes entryAction and initAction to the QMState struct in -"qep.h" (needed for transition to history). - -6. Added attribute act to the QMAttr union in "qep.h" (needed for -transitions to entry point in submachine states). - -7. Changed return type to bool in functions QHsm_isIn(), -QMsmVtbl.post(), QActive_post_(), QEQueue_post(), QActive_defer(), -QTimeEvt_rearm(), QTimeEvt_disarm(), QF_noTimeEvtsActiveX(). - -8. Changed the QState return type from action/state handler functions to -uint_fast8_t. - -9. Changed the prio attribute of QActive to uint_fast8_t. - -10. Changed the type of prio argument to uint_fast8_t and qlen/stkSize -to uint_fast16_t in the signature of QActiveVtbl.start function pointer -and QActive_start_() implementation. - -11. Changed the type of the tickRate argument in QTimeEvt_ctorX() and -QF_tickX_(), and QF_noTimeEvtsActiveX() to uint_fast8_t. - -12. Changed the type of the poolSize argument in QF_poolInit() to -uint_fast16_t. - -13. Changed arguments evtSize and margin in QF_newX_() to uint_fast16_t. - -14. Changed attribute bits in QPSet8 as well as bytes and bits[] in -QPSet64 to uint_fast8_t. - -15. Changed the QEQueueCtr event queue counter type to uint_fast8_t. - -16. Changed type of arguments qLen and margin in QEQueue_init() and -QEQueue/QActive_post() to uint_fast16_t. - -17. Changed the return type from QK_schedPrio_() (priority) as well as -the p argument in QK_sched_() and QK_schedExt_() to uint_fast8_t - -18. Added function QMsm_isInState() to "qep.h" and its implementation -file qmsm_in.c. This function tests whether the QMsm state machine (or -its subclasses like QMActive) "is in" the given state. - -19. Updated all make scripts for QP/C ports to include the new qmsm_in.c -in the QP/C library builds. - - -@section qpc_5_2_1 Version 5.2.1, 2014-01-06 -This release fixes two bugs. - -1. In file qmsm_dis.c added saving of the action-table into a temporary -variable *before* exiting the current state to the transition source. -Also, changed the signature of the QMsm_tran_() helper function to take -the action table as parameter. NOTE: This bug only affected the Spy -configuration and because of this escaped regression testing. The -internal testing process have been updated to test all build -configurations: Debug, Release, and Spy. - -2. In file qs_mem.c fixed an error in accounting used bytes in the QS -trace buffer. - - -@section qpc_5_2_0 Version 5.2.0, 2013-12-26 -This release matches the new QM 3.0.0, for which it provides model -examples based on the new QMsm/QMActive classes. This, in turn -demonstrates the new state machine code generation that QM3 was -specifically designed to do. - -This release also provides consistent API for late-binding ("virtual" -functions) introduced in QP 5.0.0, as opposed to using regular linking -(early-binding) for direct function calls, such as QHsm_dispatch(). A -clearly separated API compatibility layer is provided, whereas you can -configure a level of backwards compatibility by means of the -#QP_API_VERSION macro. This facilitates migrating existing QP -applications to the newer API. - -An cyclomatic complexity (McCabe V(G)) analysis of this version has been -performed and the maximum V(G) complexity per function has been reduced -to 15 by breaking up the QHsm_dispatch_() function. The code metrics -report, including cyclomatic complexity by function as well as other -standard code metrics (e.g., lines of code), is now included in the -"QP/C Reference Manual", see -https://www.state-machine.com/qpc/metrics.html - -Also, in this release all internal QP data that were previously -uninitialized are now explicitly initialized to zero. In other words, -this release no longer assumes that all uninitialized data (global and -static inside functions) is implicitly initialized to zero before the -control is transferred to main(). This is a requirement of the C -Standard, but some embedded startup code fails to do this. - -Finally, this release demonstrates safer stack allocation and safer -exception handlers in all ARM Cortex-M examples. The techniques are -described in the Embedded.com article "Are We Shooting Ourselves in the -Foot with Stack Overflow?". - - -Changes in detail: - -1. In file qep.h renamed the implementation functions, such as -QHsm_init() and QHsm_dispatch() to QHsm_init_() and QHsm_dispatch_() -(note the underscore, which means that the functions should not be -called directly by the application code). The only correct way of -calling the functions is through the macros QMSM_INIT() and -QMSM_DISPATCH(), respectively. The latter macros implement late-binding -("virtual" functions in C). - -2. In file qf.h renamed the implementation functions, such as -QActive_start(), QActive_post() and QActive_postLIFO() to -QActive_start_(), QActive_post_(), and QActive_postLIFO_, respectively -(note the underscore, which means that the functions should not be -called directly by the application code). The only correct way of -calling the functions is through the macros QACTIVE_START(), -QACTIVE_POST(), and QACTIVE_POST_LIFO(), respectively. The latter macros -implement late-binding ("virtual" functions in C). - -3. for backwards compatibility, in file qp_port.h defined "API -Compatibility Layer", which is controlled by the macro #QP_API_VERSION. -For example, specifying QP_API_VERSION=500 chooses API compatible with -QP version 5.0.0 or newer, but excludes APIs that became deprecated in -the earlier versions. If the macro #QP_API_VERSION is not defined by the -user (typically on the command line for the compiler), the default value -of 0 is assumed. This default means maximum backwards compatibility -(from version 0.0.0). On the other hand, higher values of -#QP_API_VERSION mean less backwards compatibility. For example -QP_API_VERSION=9999 will specify compatibility only with the latest -version of QP. The API Compatibility Layer for QP_API_VERSION < 500 -provides macros: QHsm_init(), QHsm_dispatch(), QActive_start(), -QActive_post() and QActive_postLIFO(). These macros resolve to -QMSM_INIT() and QMSM_DISPATCH(), QACTIVE_START(), QACTIVE_POST() and -QACTIVE_POST_LIFO() respectively, so that calls based on the older API -also use late-binging. - -4. In file qhsm_dis.c, broken up the function QHsm_dispatch() into two -functions QHsm_dispatch_() and QHsm_tran_(). This has reduced the -cyclomatic complexity from 25 for the original function, to 11 and 15 -for QHsm_dispatch_() and QHsm_tran_(), respectively. - -5. In file qmsm_dis.c, broken up the function QMsm_dispatch() into two -functions QMsm_dispatch_() and QMsm_tran_(). This has reduced the -cyclomatic complexity from 15 for the original function, to 9 and 7 for -QMsm_dispatch_() and QMsm_tran_(), respectively. - -6. In file qf_act.c added the function QF_bzero(), and in files -qvanilla.c and qk.c added calls to QF_bzero() to explicitly clear the -uninitialized data. Also added calls to QF_bzero() inside qf_psini.c. - -7. Updated all examples for ARM Cortex-M to use safer stack allocation -and safer exception handlers in all ARM Cortex-M examples, as described -in the Embedded.com article "Are We Shooting Ourselves in the Foot with -Stack Overflow?". - - -@section qpc_5_1_1 Version 5.1.1, 2013-10-10 -This release fixes reversal of logic in the QF_noTimeEvtsActiveX() -function as well as sleep mode transition in the ARM Cortex-M3/M4 ports -to the cooperative Vanilla kernel. Also, the native QP event queue -implementation has been changed to count the extra "front-event" -location into the number of free entries, which fixes the problem of -defer queues of depth 1. Finally, the release restores the support for -linting (with PC-Lint) of the QP/C applications for ARM Cortex-M (with -IAR and GNU compilers). - -Changes in detail: - -1. In file qf_tick.c reversed the logic inside QF_noTimeEvtsActiveX() - -2. Modified free entry accounting (nFree) in the files: qeq_init.c, -qeq_fifo.c, qeq_get.c, and qeq_lifo.c. - -3. Modified free entry accounting (nFree) in the files: qa_init.c, -qa_fifo.c, qa_get_.c, and qa_lifo.c. - -4. Introduced new macro QF_CPU_SLEEP() in the ARM Cortex-M Vanilla ports. - -5. Changed Board Support Package files (bsp.c) in the ARM Cortex-M -Vanilla examples. - -6. Modified the CMSIS-compliant startup code in all ARM Cortex-M Vanilla -examples. - -7. Modified the application examples with PC-Lint -(qpc/examples/arm-cm/qk/gnu/dpp-qk_ek-lm3s811-lint and -qpc/examples/arm-cm/qk/iar/dpp-qk_ek-lm3s811-lint). Updated lint files -for the latest PC-Lint - - -@section qpc_5_1_0 Version 5.1.0, 2013-09-23 -This release brings significant improvements to the QS software tracing -implementation and also brings important changes the ARM Cortex-M port. - -@note QP/C 5.1.0 requires changing the interrupt priority setting in the -existing ARM Cortex-M applications. Specifically, you need to set the -interrupt priorities equal or lower than QF_AWARE_ISR_CMSIS_PRI constant -provided in the qf_port.h header file. - -Changes to the QS software tracing component in detail: - -1. Optimized the internal QS implementation of all functions that insert -trace data into the trace buffer. The general idea of the optimization -is to extensively use automatic variables instead of global variables -(such as buffer head and tail indexes, the running checksum, etc.). For -the modern CPUs (such as ARM) this resulting machine code performs most -operations in registers, instead of constantly updating the memory -through the expensive load/store instructions. The time savings through -avoiding load/store instructions are significant, even after taking the -performance hit from loading the registers from the globals in the -beginning of each function and storing the final register values into -the globals at the end. - -2. Reduced the QS code size by using loops instead of unrolled-loops as -before. This reduced the QS component size from over 4KB to 1.7KB (for -ARM Cortex-M3/M4, IAR compiler). - -3. Modified the make scripts for building QP libraries to use -higher-level optimization for the QS software tracing functions in the -SPY build configuration. This brings additional 20-50% speed -improvement, depending on the compiler and optimization options used. -Please note that only the QS component is built with high-optimization. -The QEP, QF, and QK components in the SPY configuration are still built -with low-optimization level, so that the application can be conveniently -debugged. - -4. Reduced the number of QS global filters from 256 to 124 (0x7C). This -enables the code to avoid escaping the trace record numbers (because -they cannot overlap the special flag byte 0x7E or the escape byte 0x7D) -and also speeds up the QS_filterOff(QS_ALL_RECORDS) function, which is -useful for stopping the trace quickly to avoid overwriting some -interesting data with the new data. - -5. An empty QS record and the QS_RESET record are now inserted -automatically into the trace buffer in the function QS_initBuf(). The -empty QS record/QS_RESET pair provides a clean start of a session and -allows the QSPY host application to re-synch with the data stream, even -if the last QS record of a previous session is incomplete. This ability -is very helpful for re-setting the target while collecting a trace. - -Overall, lab tests for ARM Cortex-M4 with the IAR compiler show that the -processing time of the QS_u32_() function (the one frequently used to -store pointers and timestamps) dropped from 233 CPU cycles for QP 5.0 -with low-level optimization to just 76 cycles for QP 5.1 with high-level -of optimization. At the same time, the code size of this function dropped -from 876 bytes to 274 bytes. - - -Changes to the QP ports to ARM Cortex-M in detail: - -QP 5.1.0 never completely disables interrupts in the ARM Cortex-M3/M4 -cores, even inside the critical sections. On Cortex-M3/M4 (ARMv7-M -architectures), the QP port disables interrupts selectively using the -BASEPRI register. (NOTE: The BASEPRI register is not implemented in the -ARMv6-M architecture (Cortex-M0/M0+), so Cortex-M0/M0+ need to use the -PRIMASK register to disable interrupts globally). - -This new policy of disabling interrupts divides interrupts into -"kernel-unaware" interrupts, which are never disabled, and -"kernel-aware" interrupts, which are disabled in the QP critical -sections. Only "kernel-aware" interrupts are allowed to call QP -services. "Kernel-unaware" interrupts are *NOT* allowed to call any QP -services and they can communicate with QP only by triggering a -"kernel-aware" interrupt (which can post or publish events). - -As mentioned above, all QP ports to ARM Cortex-M included in the QP -5.1.0 Baseline Code provide the constant QF_AWARE_ISR_CMSIS_PRI, which -must be used to offset the "kernel-aware" interrupt priorities. - -All example projects for ARM Cortex-M included in the QP 5.1.0 Baseline -Code demonstrate the recommended way of assigning interrupt priorities -in your applications. The initialization consist of two steps: - -1. you enumerate the "kernel-unaware" and "kernel-aware" interrupt -priorities (whereas you offset the "kernel-aware" priorities by the -constant QF_AWARE_ISR_CMSIS_PRI) and - -2. you assign the priorities to *ALL* interrupts by calling the -NVIC_SetPriority() CMSIS function. - -@note Leaving the interrupt priority at the default value of zero -(the highest priority) is most likely incorrect, because the -"kernel-unaware" interrupts cannot call any QP services. - -For more information, please read the short Application Note "Setting -ARM Cortex-M Interrupt Priorities in QP 5.1" available at: -https://www.state-machine.com/doc/AN_ARM-Cortex-M_Interrupt-Priorities.pdf - - -@section qpc_5_0_0 Version 5.0.0, 2013-09-10 -@note QP/C 5.0.0 remains backwards-compatible with the existing QP/C 4.x -applications. - -The main purpose of this milestone QP/C release is to enable the QM -modeling tool to generate a new type of state machine code (requires QM -version 3.0.0, which is still in development as of this writing). - -This new type of state machine implementation in QP/C 5 is based on the -new QMsm class, which takes advantage of the QM tool as an advanced -"state machine compiler". QM can perform optimizations that were not -possible with the C pre-processor alone. Specifically, the QM can easily -determine the LCA (Least-Common-Ancestor) state for every transition and -it can generate the complete transition-sequences (sequences of -exit/entry/initial actions) at code-generation time. The resulting code -can be still highly human-readable, but it will no longer be -human-maintainable. The lab tests indicate that the new "housekeeping" -code for executing hierarchical state machines can be about twice as -fast as the previous code based on the QHsm class. Additionally, the new -code requires less run-time support (smaller event processor) and uses -70% less of stack space in the call to the QMsm_dispatch() operation -than QHsm_dispatch(). - -The next big feature introduced in QP/C 5 is polymorphism ("virtual" -functions) for basic operations, such as state machine init() and -dispatch() and active object start(), post(), and postLIFO() perations. -Making theses functions "virtual" means that all these operations can be -re-defined in sub-classes of state machines and active objects. This, in -turn, allows a single application to use a mix of state machine classes -derived from the new QMsm base class with state machines derived from -the QHsm base class, each one using a different state machine -implementation strategy. Additionally, the virtual post() operation -could be very useful for implementing various Proxy active objects -(e.g., for active object event posting across networks). - -Another big feature introduced in QP/C 5 are the multiple, independent -system clock tick rates for time events. The number of system tick rates -can be now configured in the QP/C ports. For example, a digital watch -can use a "fast" clock tick rate of 100Hz and a "slow" clock tick rate -of only 1Hz. These clock tick rates can be managed independently, so for -example, the fast clock tick rate can be shut down in the absence of -time events assigned to this rate. This feature allows the applications -to implement sophisticated power-saving policies. - -As yet another important feature, QP/C adds a new "extended" API for -non-asserting event allocation and posting. This feature is intended for -situations, where an application is hammered with external events that -at times arrive too fast for processing, but that can be ignored under -the overload conditions. In those cases firing an assertion inside the -framework is undesirable. The non-asserting API allows a designer to -request a safety-margin when allocating or posting an event. The event -is not allocated/posted if the safety margin cannot be satisfied at the -time of the call. On the other hand, the safety margin allows the -application to still use the regular (asserting) event allocation and -posting, because the event pools and event queues are guaranteed to -maintain a minimal margin for safe operation. - -Finally, QP/C adds a number of smaller features and improvements, -summarized in the following detailed list of changes: - -1. Added the new QMsm "class" to qep.h. Changed the inheritance tree by -deriving QHsm and QFsm from the QMsm base class. Added virtual table -structures for QMsm, QHsm, and QFsm (polymorphism). - - added macro QMSM_INIT() to polymorphically call the state - machine initialization implementation in the QMsm base class and - all subclasses. - - added macro QMSM_DISPATCH() to polymorphically call the state - machine event dispatching implementation in the QMsm base class - and all subclasses. - -2. Added new source files qmsm_ini.c and qmsm_dis.c to the QEP. These -files implement the QMsm_init() and QMsm_dispatch() functions, respectively. - -3. Added the new "QMActive" "class" to qf.h. Extended the inheritance -tree to derive QMActive from QActive. Added virtual table structures for -QMActive and QActvie (polymorphism). - - modified macro QACTIVE_POST() to polymorphically call the direct - event posting to an active object. - - modified macro QACTIVE_POST_LIFO() to polymorphically call the - post-LIFO (self-posting) to an active object. - - modified macro QACTIVE_START() to polymorphically call the - starting of an active object. - -4. Added the multiple system clock tick rates feature in qf.h: - - added new configuration macro #QF_MAX_TICK_RATE, which specifies - the number of clock tick rates. This macro is to be defined in - the QF ports (in the qf_port.h header file). If the macro is - undefined, the default value is 1 (one clock tick rate). - - renamed and re-implemented the QF_tick() function as the - "extended" QF_tickX() function with the argument 'tickRate' for - processing time events allocated to different clock rates. The - application must call QF_tickX(0), QF_tickX(1), ~~~ at the - specified tick rates from ISRs or *tasks*. - - added an "extended" time event constructor QTimeEvt_ctorX(), which - assigns a time event to a specific tick rate as well as specific - active object. - - renamed and re-implemented the internal function QTimeEvt_arm_() - to a public function QTimeEvt_armX() for arming time events - initialized with the "extended" constructor. The QTimeEvt_armX() - function is the new recommended API for arming time events, both - one-shot and periodic. - - re-implemented QTimeEvt_disarm() and QTimeEvt_rarm(). - - renamed QF_noTimeEvtsActive() to the "extended" version - QF_noTimeEvtsActiveX(), which checks time events assigned to the - given tick rate. - -5. Added the new non-asserting API to qf.h: - - renamed internal function QF_new_() to QF_newX_(), the latter one - taking the argument 'margin' for allocating events. The function - returns NULL if the event pool has less free events than the - specified margin. The function asserts if the margin is zero and - the event can't be allocated. - - added function QActive_post() to post an event to the given - active object. The function does not post the event if the target - event queue has less free slots than the specified margin. The - function asserts if the margin is zero and the event can't be - posted. - - added "extended" macro QF_NEW_X() for allocating events with a - margin. - - added "extended" macro QACTIVE_POST_X() for posting events with a - margin. - -6. Modified the QActive_defer() function to return the status of the - defer operation (true==success), instead of asserting when the defer - queue overflows. - -7. Modified QS (Quantum Spy) software tracing implementation: - - added additional tick rate byte to the trace records QS_QF_TICK - and QS_QFF_TIMEEVT_*. - - added new trace records QS_QF_ACTIVE_POST_ATTEMPT, - QS_QF_EQUEUE_POST_ATTEMPT, and QS_QF_MPOOL_GET_ATTEMPT for the - "extened" non-asserting event allocation and posting. - - added new trace records QS_TEST_RUN and QS_TEST_FAIL for future - support for unit testing. - - added new QS source file qs_dict.c with functions QS_*_dict() to - generate various dictionary entries. Changed the macros - QS_*_DICTIONARY() to call these functions. This was done to - significantly reduce the amount of tracing code needed to send the - dictionaries from applications. - - grouped together the various QS variables (such as filters, trace - buffer indexes, etc.) in a single struct, which results in a more - efficient code for various QS operations. - -8. Changed the structure of the ARM Cortex-M ports - - renamed the sub-directory for ARM Cortex-M ports and examples - from "arm-cortex" to "arm-cm". This is done to avoid confusion - with other ARM Cortex variants, such as Cortex-A/R, which very - different from Cortex-M. - - removed the CMSIS (Cortex Microcontroller Software Interface - Standard) directories from the Cortex-M examples and moved it to - the common location in the %QPC%/ports/arm-cm/cmsis/ directory. - Upgraded the CMSIS to the latest version 3.20. - - added the ARM Cortex-M ports and examples with Keil/ARM MDK to - the QP Baseline Code. - - upgraded ARM Cortex-M ports with IAR to the latest IAR EWARM 6.60 - - upgraded ARM Cortex-M ports with Sourcery CodeBench to the latest - version 2013.05-53. - -9. Added the requested simple "Blinky" example for Windows and ARM -Cortex-M (with the GNU, IAR, and Keil toolsets). - - Added "Getting Started with QP/C" guide based on the Blinky - example. - -10. Updated the Doxygen documentation (QP/C Reference Manual) - - updated the QP/C tutorial - - updated and added documentation and code samples - - added search box and tree-view panel to the HTML documentation - - -@section qpc_4_5_04 Version 4.5.04, Feb 08, 2013 -The main purpose of this release is adding support for the ARM Cortex-M4F -processors with the hardware Floating-Point Unit (FPU). The QP/C ports -to Cortex-M4F take full advantage of the "lazy stacking" feature of the -FPU registers, and by doing so offer the most efficient preemptive -multitasking on this processor. - -@note QP/C Version 4.5.04 preserves full compatibility with QM 2.2.03 -and all existing QDKs for QP/C 4.5.xx. - -Changes in detail: - -1. Added ports and examples for ARM Cortex-M4F with the EK-LM4F120XL -board (Stellaris Launchpad). - -2. Added the macro QF_LOG2(), which can be re-implemented in the QP ports, -if the CPU supports special instructions, such as CLZ (count leading zeros -in Cortex-M3/M4). If the macro is not defined in the QP port, the default -implementation uses a lookup table. - -3. Updated all ARM Cortex-M ports and examples to the latest IAR EWARM -6.50 and Sourcery CodeBench 2012.09-85. - -4. Updated App Notes "QP and ARM Cortex-M with IAR" and "QP and ARM -Cortex-M with GNU". - -5. Updated the PC-Lint support files (include/lib-qpc.lnt, au-misra2.lnt) -to the latest PC-Lint 9.00j. - -6. Updated the Application Note: "QP/C MISRA-C:2004 Compliance Matrix". - -7. Spell-checked the comments in all QP/C source files and removed -several typos. - -8. Removed the Qt ports and examples from the QP/C Baseline Code and -moved them to the separate QDK/C-Qt. - - -@section qpc_4_5_03 Version 4.5.03, Nov 27, 2012 -This release changes the directory structure of QP ports to various -operating systems, such as POSIX (Linux, BSD, etc.), Win32 (Windows), -Qt, etc. The OS ports are moved from the ports/80x86/ directory one -level up to ports/. Also, the OS examples are moved from the -examples/80x86/ directory one level up to examples/. - - -@section qpc_4_5_02 Version 4.5.02, Aug 04, 2012 -The main purpose of this release is better, more comprehensive -support for (rapid) prototyping of embedded QP applications on -the desktop with the Win32 API and with Qt. Among others, this -release adds a complete toolkit for creating realistic embedded -front panels with pure Win32-GUI API and free Visual C++ Express -and ResEdit. An extensive Application Note "QP and Win32" is -included in this release. - -This release simplifies the QP ports to desktop OSs, such as -Windows (Win32), Linux, BSD, Mac OSX (POSIX) and combines 32-bit -and 64-bit ports in one with conditional compilation. - -This release also adds an option for using constructors for -dynamically allocated events. When the configuration macro -Q_EVT_CTOR is defined, the Q_NEW() macro becomes variadic and -takes the arguments for the event constructor. This generally -allows creating dynamic events "on-the-fly" without a temporary -pointer to the event. This QP configuration is demonstrated only -in the QP port to Qt, but can be used in any other port. - -@note The event constructor feature is NOT backward-compatible -with the existing applications. - -This release also adds a new macro QF_MPOOL_EL, which is -intended for allocating properly aligned storage for memory pools -and event pools. - -All QP ports included in this release use only a single QP library, -rather than separate libraries for QEP, QF, QK, and QS. - -Finally, this release adds QM models, created with the new QM 2.2.00 -to most of the examples. The code generated by this new QM version -complies with MISRA-C:2004 rules. - -Changes in detail: - -1. Modified QP port to Win32 and used the free Visual C++ Express -2010 with Platform SDK rather than Visual C++ Pro 2008. Renamed -the port directory from vc2008/ to vc/. Provided a completely -revised App Note "QP and Win32". - -2. Eliminated QP port to Win32 with one thread (Win32-1T). - -3. Consolidated all QP ports to POSIX OSs (Linux, Linux64, Mac_OSX) -into a single port to POSIX and placed it in the directory posix/. - -4. Renamed the port directory qt_1t/ to qt/. - -5. Added event constructor to qevt.h (controlled by the configuration -macro Q_EVT_CTOR). - -6. Added new variadic version of the Q_NEW() macro in qf.h when -Q_EVT_CTOR is defined. - -7. Added macro QF_MPOOL_EL to qmpool.h. Modified all examples to -demonstrate the use of this macro to allocate properly aligned -storage for event pools. - -8. Added new typedef 'enum_t' and modified signatures of functions -taking event signals from QSignal to enum_t. This was done to -significantly reduce the number of casts necessary when enumerated -signals were passed to QP functions. - -9. Modified all QP ports distributed in the QP/C baseline code -to generate only a single QP library, rather than separate -libraries for QEP, QF, QK, and QS. This includes all QP ports -to the desktop (ports/80x86/ directory) and ARM Cortex-M ports -(ports/arm-cortex/ directory). - -10. Modified all examples to link only one QP library. - -11. Added QM models to most examples and used the automatically -generated code from the models instead of the hand-written code. - -12. Modified Qt ports to use the new "event constructors" and -modified examples for Qt to demonstrate this feature. - -13. Added .ui files to the Qt examples for generating UIs -graphically with the Qt Designer tool. Revised and updated the -App Note "QP and Qt". - -14. Added new macro QS_USR_DICTIONARY() to QS for providing symbolic -names for user-defined trace records - -15. Added new macro QS_RESET() to QS for telling the QSPY application -when the target resets. This allows QSPY to reset its internal state. - - -@section qpc_4_5_01 Version 4.5.01, Jun 14, 2012 -The main purpose of this minor release is providing improved -MISRA-compliant state machine implementation. Specifically, a new -macro Q_UNHANDLED() has been added for a situation when a guard -condition evaluates to FALSE, but the state model does not prescribe -the explicit [else] case for this guard. In this case, the state -handler can return Q_UNHANDLED(), which will cause the QEP event -processor to propagate the event to the superstate, which is what -UML semantics prescribes. - -@note These change to the QEP event processor is completely -backwards-compatible. All state handler functions coded the old -way will continue to handle the guard conditions correctly and -in accordance with the UML specification. The new Q_UNHANDLED() -macro is necessary only for MISRA-compliant state handler coding, -which will be applied in the upcoming release of the QM modeling -and code generation tool. - -Changes in detail: - -1. Added macro Q_UNHANDLED() and return value Q_RET_UNHANDLED in -qep.h. - -2. Modified qhsm_dis.c to handle the Q_RET_UNHANDLED return value. - -3. Updated the QP/C MISRA-C:2004 compliance matrix to -include the new MISRA-compliant way of coding guard conditions. - -4. Modified qs.h and qs_dummy.h to add new trace record type -QS_QEP_UNHANDLED, which is generated when the state handler returns -Q_RET_UNHANDLED. - -5. Modified qs.h and qs_dummy.h to add the User record dictionary -trace record and macro QS_USR_DICTIONARY(). - -@note This new trace record requires the updated QSPY 4.5.01. - -6. Corrected qfsm_dis.c, which did not generate QS trace records -for entry and exit from non-hierarchical states. - -7. Updated the IAR ARM compiler used in the ARM Cortex-M examples -to the latest version IAR EWARM 6.40. - -8. Modified the Qt port not to define the QPApp::onClockTick() -slot function, but instead to allow defining this slot function in -the BSP of the application. - - -@section qpc_4_5_00 Version 4.5.00, May 29, 2012 -The main pupose of this relase is to improve host-based development of QP -applications, which is critical for Test-Driven Development (TDD). Among -others, this release provides integration between QP and the popular -Qt GUI framework, which allows developers to easily build host-based -simulations of the embedded systems with the realistic user interfaces. - -This realase also simplifies implementing transitions to history, which -is a preparation to providing this feature in the QM modeling tool. - -Changes in detail: - -1. Renamed the event class from QEvent to QEvt to avoid a name conflict -with the Qt framework. Also, for consistency, renamed the file qevent.h -to qevt.h and the macro Q_EVENT_CAST() to Q_EVT_CAST(). - -@note To minimize impact of this change on the existing QP ports and -applications, the name QEvent is provided as well, but this can be -suppressed by defining the configuration macro Q_NQEVENT in qep_port.h. - -2. Changed the design of QF_tick() (file qf_tick.c) to better support -calling this function from low-priority tasks (as opposed to interrupts -and highest-priority tasks), which often happens when QP is executed on -the desktop operating systems. In this design only QF_tick() can remove -time events from the active linked list, so no unexpected changes to the -list structure are eliminated. - -3. Simplified the QTimeEvt class by removing the 'prev' link pointer, -as the new design no longer needs a bi-directional list. These changes -impact the files: qte_*.c. - -4. Added return value to QF_run() to allow transfer of the exit -status to the destop operating systems. - -@note This modification haves impact on most QP/C ports, because -the QF_run() function must now return a int16_t value. - -5. Eliminated the 'running' member of the QActive class, which -has been used only in the QP ports to "big" OSes such as Linux -or Windows. - -6. Added member 'temp' to the QHsm and QFsm base classes to prevent -clobbering the current state (the 'state' member) during transitons. -This change allows keeping the current state unchanged during the -entire transition chain, which in turn allows easy and generic access -to the state information to store the state history in the exit -actions from states. Additional bonus of this re-design is the -opportunity of testing for stable state configuration in assertions -added to the qhsm_*.c and qfsm_*.c files. - -7. Added the QHsm_state() and QFsm_state() accessor macros. - -8. Modified the "Transition to History" pattern implementation to -use the simplified technique of obtaining the current state in the -exit action from the superstate rather than all the exit actions from -the substates. Modified the "State-Local Storage" (SLS) pattern as -well, because it was using the transition to history constructs. - -9. Re-designed the implementation of the QSPY host application, so -that it can be convenienty included as part of the QP library. -This allows direct QS tracing output to the screen for QP applications -running on the desktop. - -@note This change is part of the Qtools release 4.5.00. - -10. Modified the QP ports to Win32_1t (both the MinGW and VC2008) to -output QS trace data directly to the stdout via the QSPY host-application -interface. Modified the DPP examples for Win32_1T to demonstrate the -direct QS output to the screen. - -11. Added QP port to Qt_1t (Qt with one thread) and two example -applications (DPP and PELICAN crossing). - -12. Added GNU compiler option -pthread to QP ports for POSIX with -P-threads, including QP ports and examples for Linux and Mac OS X. - - -@section qpc_4_4_01 Version 4.4.01, Mar 23, 2012 -The relase fixes a bug in Q-SPY software tracing, which caused the -linking error: "QS_SIG_() not defined". This release also includes -a few cosmetic changes, which the Microchip C18 compiler didn't like. - - -1. Moved QS_SIG_() definition from qep.h to qs.h -2. Changed (QEvent *)0 to (QEvent const *)0 in source files - qeq_get.c, qeq_init.c, and qa_get_.c. - - -@section qpc_4_4_00 Version 4.4.00, Jan 30, 2012 -The main pupose of this relase is MISRA-C:2004 compliance, strong-type -checking compliance, update of PC-Lint option files and tests, and -general cleanup. - -1. Moved the qp_port.h header file from the port directories to -the qcp/include/ directory. Also, moved the inclusion of the -QS (Spy) header files (qs_port.h/qs_dummy.h) from qep.h, qf.h, -and qk.h headers to qp_port.h. These structural changes were made -to reduce the number of preprocessor #if nesting levels below 8, -which is the ANSI-C limit. This was done to comply with the MISRA-C -rule 1.1 (all code shall conform to ANSI/ISO C). - -@note This modifications have impact on most QP/C ports, because -the qp_port.h header file must be removed from the port. - -2. Added the PC-Lint option files std.lnt and lib-qpc.lnt to the -qcp/include/ directory. - -3. Cleaned the whole QP/C code from lint comments. All PC-Lint options -have been moved to PC-Lint option files. - -4. Modified QP assertion macro Q_DEFINE_THIS_MODULE() to avoid using -the # operator (MISRA rule 19.13). This macro now requires the argument -enclosed in doble quotes "". - -@note This modification has impact on some QP/C ports. - -4. Added typedefs for char, int_t, float32_t, and float64_t to -event.h header file for compliance with MISRA-C:2004 rules 6.1 and 6.3. - -5. Added macros Q_STATE_CAST() and Q_EVENT_CAST() to qep.h to -encapsulate deviation from MISRA-C rule 11.4. - -6. Added macro Q_UINT2PTR_CAST() to encapsulate casting unsigned -integers to pointers, which deviates from MISRA-C rule 11.3. This -macro has been added for *application-level* code. - -7. Updated ARM Cortex-M examples with the latest CMSIS v3.0, which -complies with more MISRA-C:2004 rules. - -8. Added DPP examples for MISRA-C:2004 compliant applications (for -IAR-ARM and GNU-ARM). - -9. Added testing of PC-Lint option files against the MISRA-C Exemplar -Suite. - -10. Updated ARM-Cortex-M3 port with GNU to the latest Sourcery -CodeBench 2011.09-60. - -11. Added QP/C port to Win32-1t and examples (Windows with 1 thread). -This port is useful for testing embedded QP/C applications on windows. - -12. Added documentation to QP/C distribution in the directory -qpc/doc/, with the following Application notes: -"MISRA-C:2004 Compliance Matrix", "Quantum Leaps Coding Standard", -"QP and ARM Cortex-M, and QP and Windows", - - -@section qpc_4_3_00 Version 4.3.00, Nov 01, 2011 -1. This release changes the names of critical section macros and -introduces macros for unconditional interrupt disabling/enabling. -This is done to simplify and speed up the built-in Vanilla and QK -kernels, which no longer are dependent on the interrupt locking -policy. - -@note The change in handling the critical section in the Vanilla and -QK kernels can break QP ports, which use the "save and restore -interrupt lock" policy, because all such ports must also define -unconditional interrupt disabling and enabling. - -2. This release changes the partitioning of the QK scheduler. -Specifically, the QK scheduler is now divided between two functions -QK_schedPrio_() and QK_sched_(), to calculate the highest-priority -task ready to run and to perform scheduling, respectively. The function -QK_schedPrio_() is useful to determine if scheduling is even necessary. - -3. Updated all QP ports to comply with the new critical section -names and policies. - -4. Modified the ARM Cortex-M port qk_port.s to take advantage of the -new structure of the QK scheduler. - -5. Upgraded the examples for ARM Cortex with IAR EWARM to the -latest IAR EWARM version 6.30. - -6. Upgraded the examples for ARM Cortex with GNU (CodeSourcery) to the -latest Sourcery CodeBench 2011.07-60. - - -@section qpc_4_2_04 Version 4.2.04, Sep 24, 2011 -The main pupose of this relase is to provide a bug fix for the QK port -to ARM Cortex processors. The bug fix addresses a very rare and -undocumented behavior of late-arrival of an interrupt while entering -the PendSV exception. In this case the PENDSVSET bit in the NVIC-ICSR -register is *not* cleared when finally PendSV is entered, so the -PendSV exception is entered in a *different* state when it is entered -via the late-arrival mechanism versus the normal activation of the -exception through tail-chaining. The consequence of this undocumented -and inconsistent hardware behavior, PendSV could be re-entered again -before the SVCall exception cleans up the stack. The bug fix is -implemented in the qk_port.s file and consists of clearing the -PENDSVSET bit programmatically inside PendSV_Handler. - - -@section qpc_4_2_02 Version 4.2.02, Sep 08, 2011 -1. The main pupose of this relase is to repackage the default QP/C -distribution to contain the single root directory `qpc/` in the -archive. That way, unziping the archive will produce only one -directory (`qpc/`), which can be then changed by the user. - -2. This release also changes the ARM Cortex QP ports with GNU. The -suffix "_cs" has been added to all QP libraries generated by the -Code Sourcery toolset (now Mentor Sourcery CodeBench). This is to -distinguish libraries generated by different GNU-toolchains (such -as CodeRed, Attolic, DevKit ARM, etc.) - - -@section qpc_4_2_01 Version 4.2.01, Aug 13, 2011 -1. Modified file qassert.h to add assertion macros #Q_ASSERT_ID, -#Q_REQUIRE_ID, #Q_ENSURE_ID, #Q_INVARIANT_ID, and #Q_ERROR_ID, -which are better suited for unit testig, because they avoid the -volatility of line numbers for indentifying assertions. - -2. Added QP port and examples for Mac OS X on 80x86. - - -@section qpc_4_2_00 Version 4.2.00, Jul 14, 2011 -The goal of this milestone release is to extend the number of event -pools (theoretically up to 255 pools) instead of just three event -pools available up til now. Also, this release adds several -improvements to the QS/QSPY software tracing, such as adding sender -information to event posting so that sequence diagrams could be easily -and automatically reconstructed from tracing data. Also, the tracing -now supports 64-bit targets, such as embedded Linux 64-bit. Finally, -this milestone release migrates the examples to use the environment -variable QPC instead of relying on the relative path to the QP/C -framework. This allows easier adaptation of the examples for real -projects, which don't really belong to the examples directory. - -The changes in detail are: - -1. Changed the QEvent base struct (file qevent.h). The private member -'dynamic_' has been replaced by two members 'poolId_' and 'refCtr_'. - -2. Added configuration macro QF_MAX_EPOOL (file qf.h) to define the -maximum number of event pools in the QP application (default to 3). -The maximum theoretical number of this macro is 255. - -3. Made algorithmic changes in the QF source code related to the change -of storing the event pool-IDs and reference counters inside QEvent. - -4. Changed the default signal size (macro Q_SIGNAL_SIZE in the file -qevent.h) from 1 to 2 bytes. - -5. Changed the signature of QActive_recall() to return uint8_t instead -of QEvent*, which this could encourage incorrect usage (processing of -the event at the point of recalling it). Now, the function only returns -1 (TRUE) if the event was recalled and 0 (FALSE) if the event was not -recalled. - -6. Added the function QTimeEvt_ctr() and new source file qte_ctr.c. -The function returns the counter of a time event, which allows -using a time event for measuring the time. - -7. Added new QF macros #QF_TICK, #QF_PUBLISH, and #QACTIVE_POST in -file qf.h to provide sender of the events for software tracing. - -8. Added new QS macros (files qs.h and qs_dummy.h) for handling 64-bit -integers. - -9. Added the functions QS_u64() and QS_u64_() and new source file -qs_u64.c. - -10. Added the QS macro #QS_U32_HEX_T for hexadecimal formatting of -integer numbers in the user-defined trace records. - -11. Added the new port linux64 for 64-bit Linux. Also added the -corresponding examples for 64-bit Linux. - -12. Adapted the QSPY host application for 64-bit pointer sizes and -the changed layout of trace records that contain event information -(such as PoolID and RefCtr). Also added the backwards-compatibility -option (-v) for switching the tool to the previous data format. - -13. Removed the tools directory from the QPC distribution and moved -the QSPY host application to the QTOOLS distribution, which now also -contains the GNU make tools for Windows. - -14. Modified the make files and project files to use the environment -variable QPC instead of relying on the relative path to the QP/C -framework. - -15. Upgraded the examples for ARM Cortex with IAR EWARM to the -latest IAR EWARM 6.20. - - -@section qpc_4_1_07 Version 4.1.07, Feb 28, 2011 -The goal of this release is to improve the ease of experimenting with -QP/C on the desktop. This release adds support for Windows (Win32) to -the baseline code. Two most popular compilers for Windows are supported: -Microsoft Visual Studio and MinGW (GNU). The support for Linux has been -improved by including pre-built QP/C libraries and improving makefiles -for Eclipse compatibility. - -The changes in detail are: - -1. Added Win32 port with the Visual C++ 2008 (ports/80x86/win32/vc2008). -This directory contains the Visual Studio solution all_qp.sln for -building all QP/C libraries from the IDE. Three build configurations -(Debug, Release, and Spy) are supported. - -2. Added Win32 port with the MinGW comiler (ports/80x86/win32/mingw). -This directory contains the Makefile for building all QP/C libraries. -Three build configurations (dbg, rel, and spy) are supported. - -@note the Makefile assumes that the MinGW/bin directory is added -to the PATH. - -3. Added Win32 examples for Visual C++ 2008 (examples/80x86/win32/ -vc2008/dpp and examples/80x86/win32/vc2008/qhsmtst). Visual Studio -soultions are provides for all build configurations. - -4. Added Win32 examples for MinGW (examples/80x86/win32/mingw/dpp -and examples/80x86/win32/mingw/qhsmtst). Eclipse-compatible makefiles -are provided for all build configurations. NOTE: the Makefiles assume -that the MinGW/bin directory is added to the PATH. - -5. Removed memory alignment correction in the file qmp_init.c. This -correction required casting of pointers to integers and was problematic -on 64-bit targets (such as 64-bit Linux). - -6. Upgraded the examples for ARM Cortex with CodeSourcery to the -latest Sourcery G++ 2011.02-2. - - -@section qpc_4_1_06 Version 4.1.06, Jan 07, 2011 -1. Made cosmetic improvements to the example QM models of the -"Fly 'n' Shoot" game. - -2. Made improvements in make.bat files for building the examples for -DOS/Open Watcom to run better in DosBox on Linux. - -3. Upgraded the examples for ARM Cortex with IAR to the latest -IAR EWARM version 6.10. - -4. Upgraded the examples for ARM Cortex with CodeSourcery to the -latest Sourcery G++ 2010.09-66. - - -@section qpc_4_1_05 Version 4.1.05, Nov 01, 2010 -This release is adds examples for the QM (QP Modeler) graphical modeling -and code generation tool. The examples are based on the "Fly 'n' Shoot" -game described in the QP/C Tutorial and in Chapter 1 of the PSiCC2 book. - -Specifically, the directory /examples/80x86/dos/watcom/l/game-qm/ -contains the "Fly 'n' Shoot" game model file "game.qm". This model, when -opened in the QM tool contains all state machine diagrams and generates -code into the subdirectory qm_code/. This code can then be built and -executed on any 80x86 machine (newer versions of Windows or Linux require -the DOSbox application, see http://www.dosbox.com). - -The directory /examples/arm-cortex/vanilla/iar/game-ev-lm3s811-qm/ -contains the version of the game for the EV-LM3S811 ARM Cortex-M3 board. -This directory contains the model file "game.qm", which is actually -identical as the model in the DOS version. The LM3S811 version needs to -be compiled with the IAR compiler and executed on the EV-LM3S811 board. - -Additionally, the QP/C baseline code has been slighlty modified for -better conformance to the MISRA C 2004 rules and the latest PC-Lint 9.x. - - -@section qpc_4_1_04 Version 4.1.04, Mar 16, 2010 -This release is adds compatibility of all examples for DOS with the DOSBox -emulator (http://www.dosbox.com) that recreates a MS-DOS compatible -environment on all versions of Windows, including 64-bit Windows that don't -run 16-bit DOS applications anymore. - -Also, this release includes QP ports and examples for EV-LM3S811 board with -the GNU-based Code Sourcery G++ toolset. Support for Sourcery G++ provides -a very cost-effective option for developing QP applications for ARM Cortex -MCUs. - -Finally, this release improves the Cortex Microcontroller Software Interface -Standard (CMSIS) for the whole family of the Stellaris LM3Sxxx MCUs. The -improvement extends the CMSIS from Sandstorm to Fury, DustDevil, and Tempest -Stellaris families. - - -@section qpc_4_1_03 Version 4.1.03, Jan 21, 2010 -This release is concerned with the ARM Cortex ports and examples. -Specifically, this release contains the following improvements: - -1. Unified source code for ARM Cortex-M3 and the new ARM Cortex-M0 cores, -including the code for the preemptive QK kernel. - -2. Compliance with the Cortex Microcontroller Software Interface Standard -(CMSIS) in all ARM Cortex examples. - -3. Backward-compatible support for the new LM3S811 EVAL Rev C board with -different OLED display than previous revisions. (NOTE: The OSRAM 96x16x1 OLED -used in REV A-B boards has been replaced RITEK 96x16x1 OLED used in Rev C.) - -In the process of making the examples CMSIS-compliant, the dependency on the -Luminary Micro driver library (driverlib.a) has been completely removed. - -Additionally, the screen saver of the "Fly 'n' Shoot" game has been improved -to periodically switch off the power of the OLED display, which better -protects the display from burn-in. The affected file is tunnel.c. - -Finally, this release introduces the QP_VERSION macro, which identifies the QP -version. Otherwise, this maintenance release does not change the QP/C API in -any way, so the release has NO IMPACT on the QP/C applications except for the -ARM Cortex ports and applications. - - -@section qpc_4_1_02 Version 4.1.02, Jan 14, 2010 -The purpose of this minor maintenance release is the change in the directory -structure for the ARM Cortex ports and examples. As new ARM Cortex cores are -becoming available, the old port name "cortex-m3" could be misleading, because -it actually applies to wider range of ARM Cortex cores. Consequently, all ARM -Cortex ports and examples are hosted in the directory tree called -"arm-cortex". - -This maintenance release does not change the QP/C API in any way, so the -release has NO IMPACT on the QP/C applications except for the ARM Cortex -ports and applications. - - -@section qpc_4_1_01 Version 4.1.01, Nov 05, 2009 -The main purpose of this release is to replace the Turbo C++ 1.01 toolset -with the Open Watcom C/C++ toolset, because Turbo C++ 1.01 is no longer -available for a free download. In contrast, Open Watcom is distributed under -an OSI-certified open source license, which permits free commercial and -non-commercial use. Open Watcom can be downloaded from www.openwatcom.org. - -All 80x86/DOS, 80x86/qk, and 80x86/ucos2 ports and examples for Turbo C++ 1.01 -have been replaced with ports and examples for Open Watcom. The make.bat -scripts are provided to build the QP/C libraries and examples. - -In the process of converting the examples to Open Watcom two new examples -have been added to the standard QP/C distribution. The Calc2 example -located in <qpc>/examples/80x86/dos/watcom/l/calc2 shows how to derive -state machine classes with QP 4.x. The SLS example located in -<qpc>/examples/80x86/dos/watcom/l/sls shows the implemenation of the -new State-Local Storage state design pattern. - - -@section qpc_4_1_00 Version 4.1.00, Oct 09, 2009 -The release brings a number of improvements to QP/C and updates the QP/C ARM -Cortex-M3 examples for the EK-LM3S811 board to the latest IAR EWARM 5.40. - -This maintenance release does not change the QP/C API in any way, so the -release has NO IMPACT on the QP/C applications. - -The main changes in QP v4.1.00 with respect to earlier versions are as -follows: - -- in qs.h added a new trace record QS_QEP_DISPATCH logged when an event is -dispatched to a state machine. This timestamped trace record marks the -beginning of an RTC step. The end of the RTC step is marked by the existing -timestamped trace records QS_QEP_INTERN_TRAN, QS_QEP_INIT_TRAN, and -QS_QEP_IGNORED, depending on how the event is handled. The new QS_QEP_DISPATCH -record facilitates measurement of the RTC step lengths. -- in qhsm_dis.c added generation of the QS_QEP_DISPATCH trace record. -- in the tools/qspy/ sub-directory added output of the new trace record to the -Q-SPY host application. -- in the tools/qspy/matlab/ sub-directory added processing of the new trace -record to the qspy.m script. -- in qpset.h changed the implementation of the Priority Set. In particular, -the QPSet64 now derives from QPSet8, which enables a common way of testing for -non-empty set (e.g., useful in assembly). Also, the findMax() functions in -QPSet8 and QPSet64 now can work with an empty set, in which case they return -0. -- in qk_sched.c simplified the QK_schedule_() function to skip the testing -of the ready-set for non-empty condition. Such test is no longer necessary. -The test can still be performed outside the QK_schedule_() function (e.g., in -assembly) to avoid calling the scheduler if the ready set is empty. -- in qk_ext.c simplified the QK_scheduleExt_() function in the same way as -QK_schedule_(). -- modified make.bat files for building QP libraries in the ports/ directory -to use the externally defined environment variables for the location of the -toolchains. The defaults are applied only when the environment variable is -not defined. This enables greater flexibility in installing the development -tools in different directories than those chosen by Quantum Leaps. -- modified the ARM Cortex-M3 examples for the new IAR EWARM 5.40. -- modified slighlty the Calculator example to allow extensibility. -- in the ARM Cortex-M3 port file qk_port.s added explicit testing of the -QF_readySet_ set for empty condition. This test allows avoiding calling the QK -scheduler and two contex-switches if the ready-set is empty. -- in the game example moved setting up the QS filters from main.c to bsp.c. - - -@section qpc_4_0_04 Version 4.0.04, Apr 09, 2009 -The maintenance release provides a fix for the compile-time assertions, -which did not work correctly for the GNU compiler family. Also, the ARM -Cortex-M3 examples have been recompiled with the newer IAR EWARM v5.30. - -This maintenance release does not change the QP/C API in any way, so the -release has NO IMPACT on the QP/C applications. - -The main changes in QP v4.0.04 with respect to earlier version are as follows: - -- in qassert.h file the #Q_ASSERT_COMPILE macro has been modified to render -a negative array dimension when the asserted condition is not TRUE. - - -@section qpc_4_0_03 Version 4.0.03, Dec 27, 2008 -The main purpose of this release is to fix a bug in the QK preemptive kernel, -which occurs only when the advanced QK features are used. Specifically, the QK -priority-ceiling mutex could interfere with QK thread-local storage (TLS) or -QK extended context switch. When the QK mutex is in use, the TLS or the -extended context for this task could get saved to an incorrect priority level. - -The release 4.0.03 fixes the bug by strictly preserving the semantics of -QK_currPrio_ variable. The mutex locking now uses a different variable -QK_ceilingPrio_, which represents the ceiling-priority locked by the mutex. -The QK scheduler and extended scheduler now perform an additional check to -make sure that only tasks with priorities above the ceiling can run. To avoid -that additional overhead, the user can define the macro QK_NO_MUTEX, which -eliminates the QK mutex API and eliminates the additional tests in the QK -schedulers. - -This maintenance release does not change the QP/C API in any way, so the -release has NO IMPACT on the QP/C applications. - -The main changes in QP v4.0.03 with respect to earlier version are as follows: - -- in qk.h file made the QK mutex API only visible when the macro QK_NO_MUTEX -is *not* defined. -- in qk_pkg.h file, added the QK_ceilingPrio_ external declaration when the -macro QK_NO_MUTEX is not defined. -- in qk_mutex.c file, changed priority-ceiling mutex implementation to use -the QK_ceilingPrio_ instead of QK_currPrio_. Also, added compiler error when -the macro QK_NO_MUTEX is definedthis and this file is included in the build. -- in qk_sched.c file added testing priority against the QK_ceilingPrio_, -when the macro QK_NO_MUTEX is not defined. -- in qk_ext.c file added testing priority against the QK_ceilingPrio_, -when the macro QK_NO_MUTEX is not defined. - - -@section qpc_4_0_02 Version 4.0.02, Nov 15, 2008 -This maintenance release does not change the QP/C API in any way, so the -release has NO IMPACT on the QP/C applications. - -The main changes in QP v4.0.02 with respect to earlier version are as follows: - -- in qep.h file, added comments to macros Q_TRAN() and Q_SUPER() to suppress -the PC-lint warining about using the comma-operator (MISRA rule 42). -- in qhsm_in.c file, fixed a bug in the QHsm_isIn() function. -- fixed a bug in tunnel.c file ("Fly 'n' Shoot" game). The constant event -HIT_WALL was not declared static. - - -@section qpc_4_0_01 Version 4.0.01, June 09, 2008 -This maintenace release is made to allow using QS software tracing with -the GNU compiler for AVR (WinAVR). Specifically, the output of the strings -residing in ROM has been fixed. - -This maintenance release does not change the QP/C API in any way, so the -release has NO IMPACT on the QP/C applications. - -The main changes in QP v4.0.01 with respect to earlier version are as follows: - -- in qs_.c file, updated the function QS_str_ROM_(). -- in qs_str.c file, updated the function QS_str_ROM(). -- in qvanilla.c file, funciton QF_run(), declared the temporary variables -as static to save stack space, because QF_run() never returns and is not -reentrant. - - -@section qpc_4_0_00 Version 4.0.00, Apr 07, 2008 -This milestone release is made for the book /ref PSiCC2. The book describes in -great detail this new release. The older "QP Programmer's Manual" is now -phased out and is replaced with this hyper-linked -/ref main_page "QP/C Reference Manual", which provides very detailed, easily -searchable reference to the software. The book /ref PSiCC2 provies in-depth -discussion of the relevant concepts as well as the design study of QP v4.0. - -The main changes in QP v4.0 with respect to earlier versions are as follows: - -- the coding techniques for hierarchical state machines (HSMs) and the simpler -finite state machines (FSMs) have changed. While the changes are quite simple, -the backward compatibility with QEP 3.x has been broken, meaning that some -manual changes to the state machines implemented with earlier versions are -necessary. Please refer to the "QP/C Tutorial" Section /ref coding_hsm for -more information about coding state machines with QEP 4.x. - - The main change is the signature of a state-handler function, which now - returns simply a byte. This return type (typedef'ed as QState) is the - status of the event-handling that the state handler conveys to the QEP - event processor. - - The macro #Q_TRAN() must now always follow the return statement. - - The new macro #Q_SUPER() designates the superstate of the given state. - Again, this macro must follow the return statement. - - Then two new macros #Q_HANDLED() and #Q_IGNORED() have been added to - return the status of event handled and event ignored, respectively. - -- all callback functions are now consistently called /c #XXX_onYYY(): - - Q_assert_handler() is now Q_onAssert() - - QF_start() is now QF_onStartup() - - QF_cleanup() is now QF_onCleanup() - -- the new header file qevent.h has been broken off the qep.h header file. -qevent.h contains the QEvent class and other basic facilities used in the -whole QP. This new file allows easier replacement of the entire QEP event -processor with custom event processors, if you wish do so. -- the macro QEP_SIGNAL_SIZE is renamed to #Q_SIGNAL_SIZE. -- the data type QSTATE is now deprecated. Please use QState. -- the "protected" in C don't no longer have the trailing underscore. For -example, QHsm_ctor_() is replaced with #QHsm_ctor(), etc. -- the QF_FSM_ACTIVE macro is now deprecated. Instead, you have the family of -macros QF_ACTIVE_SUPER_, QF_ACTIVE_CTOR_, QF_ACTIVE_INIT_, -QF_ACTIVE_DISPATCH_, QF_ACTIVE_STATE_, which allow replacing the base class -for active objects in QF. By default, these macros are defined to use the QHsm -class from the QEP hierarchical event processor, but you can replace the event -processor, if you wish. -- the internal macro QACTIVE_OSOBJECT_WAIT_() is now QACTIVE_EQUEUE_WAIT_(). -- the internal macro QACTIVE_OSOBJECT_SIGNAL_() is now -QACTIVE_EQUEUE_SIGNAL_(). -- the internal macro QACTIVE_OSOBJECT_ONIDLE_() is now -QACTIVE_EQUEUE_ONEMPTY_(). -- the data mebers QActive.osObject and QActive.thread are now present only if -the macros #QF_OS_OBJECT_TYPE and #QF_THREAD_TYPE are defined. -- the QPSet class has been renamed to QPSet64. -- the QPSet_hasElements() has been renamed QPSet64_notEmpty() -- the QS software tracing is now better integrated with all QP components. You -no longer need to explicitly include qs_port.h, because it is automatically -included when you define the macro #Q_SPY. Also the file qs_dummy.h is -included automatically when the macro #Q_SPY is not defined. -- the new header file qvanilla.h now replaces the file qsched.h. -- the file qa_ctor.c is now obsolete. -- the macros QF_SCHED_LOCK() and QF_SCHED_UNLOCK() are now obsolete. -- the native QF event queues (both the active object event queues and the -"raw" thread-safe queues) are slightly more efficient by counting down the -head and tail pointers rather than up. This leads to wrap-around at zero, -which is easier (faster) to test than any other wrap-around point. Also the -native QF event queues maintain the minimum of the free events in the queue -rather the maximum of used events. -- the data member of QEQueue.nTot class is removed. -- the QF_publish() function has been re-written so that QF no does not -need to lock the scheduler. The QF_publish() function posts events -to active objects with scheduler unlocked starting from the highest-priority -active objects. However, the event is protected from inadvertent recycling by -incrementing its reference counter before the publish operation. After the -event is posted to all subscribers, the garbage collector QF_gc() is called -to decrement the reference counter and recycle the event, if necessary. -- the qf_run.c file is obsolete. The QF_run() function for the cooperative -"vanilla" kernel is now implemented in the file qvanilla.c. -- the QF_tick() function has been rewritten to allow calling QF_tick() from -the task context as well as from the interrupt context. The nested critical -section around QF_tick() is no longer needed when it is called from the task -level. Among others, this re-design eliminates the need for the -recursive mutex in the POSIX QF port. -- the QMPool_init() function has been re-designed to optimally align the -memory buffer in a portable and platform-independent way. This should bring -some performance improvements on some CPUs (e.g., 80x86). -- the extended QK scheduler has been re-designed to save stack space. The -extended context (e.g., coprocessor registers) are no longer saved on the -precious stack, but rather in the active object. -- a bug has been fixed in handling of Thread-Local Storage (TLS) in the QK -scheduler and extended scheduler. - -- the -q (quiet) flag has been added to the QSPY host application. -- the support for two new compilers for Windows has been added for the QSPY -host application. The application can now be build with the MinGW GNU compiler -for Windows as well as the Microsoft Visual C++ 2005. - -- the QP port to Linux has been improved by eliminating the need for recursive -P-Thread mutex. - -- the QP port to MicroC/OS-II has been upgraded to the latest version 2.86. - -- all examples in the standard QP distribution have been cleaned up and -updated to the latest QP API changes. -- all examples that use QF now contain the QS software tracing support. - -*/ diff --git a/doxygen/images/AN-QL.png b/doxygen/images/AN-QL.png deleted file mode 100644 index 1cbeddfc..00000000 Binary files a/doxygen/images/AN-QL.png and /dev/null differ diff --git a/doxygen/images/AN-game.jpg b/doxygen/images/AN-game.jpg deleted file mode 100644 index 6ed6df01..00000000 Binary files a/doxygen/images/AN-game.jpg and /dev/null differ diff --git a/doxygen/images/AN-getting_started.jpg b/doxygen/images/AN-getting_started.jpg deleted file mode 100644 index 3f5b7b5b..00000000 Binary files a/doxygen/images/AN-getting_started.jpg and /dev/null differ diff --git a/doxygen/images/AN_DPP.jpg b/doxygen/images/AN_DPP.jpg deleted file mode 100644 index 4176fea7..00000000 Binary files a/doxygen/images/AN_DPP.jpg and /dev/null differ diff --git a/doxygen/images/AN_Getting-Started.png b/doxygen/images/AN_Getting-Started.png deleted file mode 100644 index 301ade98..00000000 Binary files a/doxygen/images/AN_Getting-Started.png and /dev/null differ diff --git a/doxygen/images/AN_QP_Performance.jpg b/doxygen/images/AN_QP_Performance.jpg deleted file mode 100644 index e8ce4f2c..00000000 Binary files a/doxygen/images/AN_QP_Performance.jpg and /dev/null differ diff --git a/doxygen/images/Arduino-UNO_button.jpg b/doxygen/images/Arduino-UNO_button.jpg deleted file mode 100644 index 8ef02e72..00000000 Binary files a/doxygen/images/Arduino-UNO_button.jpg and /dev/null differ diff --git a/doxygen/images/Arduino-UNO_button_schem.jpg b/doxygen/images/Arduino-UNO_button_schem.jpg deleted file mode 100644 index d1f7517c..00000000 Binary files a/doxygen/images/Arduino-UNO_button_schem.jpg and /dev/null differ diff --git a/doxygen/images/PSiCC2_250x200.jpg b/doxygen/images/PSiCC2_250x200.jpg deleted file mode 100644 index 19083655..00000000 Binary files a/doxygen/images/PSiCC2_250x200.jpg and /dev/null differ diff --git a/doxygen/images/SM_blinky.png b/doxygen/images/SM_blinky.png deleted file mode 100644 index 9c9594e4..00000000 Binary files a/doxygen/images/SM_blinky.png and /dev/null differ diff --git a/doxygen/images/SM_of_Blinky.png b/doxygen/images/SM_of_Blinky.png deleted file mode 100644 index 5e2946e5..00000000 Binary files a/doxygen/images/SM_of_Blinky.png and /dev/null differ diff --git a/doxygen/images/an-oop_in_c.jpg b/doxygen/images/an-oop_in_c.jpg deleted file mode 100644 index 458ccc2e..00000000 Binary files a/doxygen/images/an-oop_in_c.jpg and /dev/null differ diff --git a/doxygen/images/an-qp_performance.png b/doxygen/images/an-qp_performance.png deleted file mode 100644 index de6add8b..00000000 Binary files a/doxygen/images/an-qp_performance.png and /dev/null differ diff --git a/doxygen/images/arm-cm_qk_test-ccs.png b/doxygen/images/arm-cm_qk_test-ccs.png deleted file mode 100644 index 650be55b..00000000 Binary files a/doxygen/images/arm-cm_qk_test-ccs.png and /dev/null differ diff --git a/doxygen/images/bd_AT91SAM7S-EK.jpg b/doxygen/images/bd_AT91SAM7S-EK.jpg deleted file mode 100644 index b25bf57b..00000000 Binary files a/doxygen/images/bd_AT91SAM7S-EK.jpg and /dev/null differ diff --git a/doxygen/images/bd_AT91SAM7S-EK_J-Link.jpg b/doxygen/images/bd_AT91SAM7S-EK_J-Link.jpg deleted file mode 100644 index 3657a646..00000000 Binary files a/doxygen/images/bd_AT91SAM7S-EK_J-Link.jpg and /dev/null differ diff --git a/doxygen/images/bd_Arduino-UNO.jpg b/doxygen/images/bd_Arduino-UNO.jpg deleted file mode 100644 index 4463bb82..00000000 Binary files a/doxygen/images/bd_Arduino-UNO.jpg and /dev/null differ diff --git a/doxygen/images/bd_EFM32-SLSTK3401A.jpg b/doxygen/images/bd_EFM32-SLSTK3401A.jpg deleted file mode 100644 index 1a0905a0..00000000 Binary files a/doxygen/images/bd_EFM32-SLSTK3401A.jpg and /dev/null differ diff --git a/doxygen/images/bd_EK-LM3S6965.jpg b/doxygen/images/bd_EK-LM3S6965.jpg deleted file mode 100644 index de0d5580..00000000 Binary files a/doxygen/images/bd_EK-LM3S6965.jpg and /dev/null differ diff --git a/doxygen/images/bd_EK-LM3S6965_lwip.jpg b/doxygen/images/bd_EK-LM3S6965_lwip.jpg deleted file mode 100644 index 7f297db9..00000000 Binary files a/doxygen/images/bd_EK-LM3S6965_lwip.jpg and /dev/null differ diff --git a/doxygen/images/bd_EK-LM3S811.jpg b/doxygen/images/bd_EK-LM3S811.jpg deleted file mode 100644 index 68c4f7e8..00000000 Binary files a/doxygen/images/bd_EK-LM3S811.jpg and /dev/null differ diff --git a/doxygen/images/bd_EK-LM3S811_game.jpg b/doxygen/images/bd_EK-LM3S811_game.jpg deleted file mode 100644 index 6c780aa7..00000000 Binary files a/doxygen/images/bd_EK-LM3S811_game.jpg and /dev/null differ diff --git a/doxygen/images/bd_EK-TM4C123GXL.jpg b/doxygen/images/bd_EK-TM4C123GXL.jpg deleted file mode 100644 index 28aa3568..00000000 Binary files a/doxygen/images/bd_EK-TM4C123GXL.jpg and /dev/null differ diff --git a/doxygen/images/bd_LAUNCHXL2-TMS57012.jpg b/doxygen/images/bd_LAUNCHXL2-TMS57012.jpg deleted file mode 100644 index e4bde203..00000000 Binary files a/doxygen/images/bd_LAUNCHXL2-TMS57012.jpg and /dev/null differ diff --git a/doxygen/images/bd_MSP-EXP430F5529LP.jpg b/doxygen/images/bd_MSP-EXP430F5529LP.jpg deleted file mode 100644 index b912a069..00000000 Binary files a/doxygen/images/bd_MSP-EXP430F5529LP.jpg and /dev/null differ diff --git a/doxygen/images/bd_MSP-EXP430G2.jpg b/doxygen/images/bd_MSP-EXP430G2.jpg deleted file mode 100644 index c557c8fb..00000000 Binary files a/doxygen/images/bd_MSP-EXP430G2.jpg and /dev/null differ diff --git a/doxygen/images/bd_NUCLEO-H743ZI.jpg b/doxygen/images/bd_NUCLEO-H743ZI.jpg deleted file mode 100644 index 882a34e1..00000000 Binary files a/doxygen/images/bd_NUCLEO-H743ZI.jpg and /dev/null differ diff --git a/doxygen/images/bd_NUCLEO-L053R8.jpg b/doxygen/images/bd_NUCLEO-L053R8.jpg deleted file mode 100644 index 3e18a553..00000000 Binary files a/doxygen/images/bd_NUCLEO-L053R8.jpg and /dev/null differ diff --git a/doxygen/images/bd_NUCLEO-L152RE.jpg b/doxygen/images/bd_NUCLEO-L152RE.jpg deleted file mode 100644 index ba76a3a0..00000000 Binary files a/doxygen/images/bd_NUCLEO-L152RE.jpg and /dev/null differ diff --git a/doxygen/images/bd_NUCLEO-L552ZE.jpg b/doxygen/images/bd_NUCLEO-L552ZE.jpg deleted file mode 100644 index 2f942351..00000000 Binary files a/doxygen/images/bd_NUCLEO-L552ZE.jpg and /dev/null differ diff --git a/doxygen/images/bd_STM32F4-Disco.jpg b/doxygen/images/bd_STM32F4-Disco.jpg deleted file mode 100644 index ed69bf4d..00000000 Binary files a/doxygen/images/bd_STM32F4-Disco.jpg and /dev/null differ diff --git a/doxygen/images/bd_STM32F4-Disco_RS232.jpg b/doxygen/images/bd_STM32F4-Disco_RS232.jpg deleted file mode 100644 index 745bcf1d..00000000 Binary files a/doxygen/images/bd_STM32F4-Disco_RS232.jpg and /dev/null differ diff --git a/doxygen/images/bd_STM32F746G-Disco.jpg b/doxygen/images/bd_STM32F746G-Disco.jpg deleted file mode 100644 index 029092f4..00000000 Binary files a/doxygen/images/bd_STM32F746G-Disco.jpg and /dev/null differ diff --git a/doxygen/images/bd_mbed-LPC1768.jpg b/doxygen/images/bd_mbed-LPC1768.jpg deleted file mode 100644 index e39cb054..00000000 Binary files a/doxygen/images/bd_mbed-LPC1768.jpg and /dev/null differ diff --git a/doxygen/images/blinky_ek-tm4c123gxl.gif b/doxygen/images/blinky_ek-tm4c123gxl.gif deleted file mode 100644 index 9bed81a5..00000000 Binary files a/doxygen/images/blinky_ek-tm4c123gxl.gif and /dev/null differ diff --git a/doxygen/images/blinky_ek-tm4c123gxl.jpg b/doxygen/images/blinky_ek-tm4c123gxl.jpg deleted file mode 100644 index eef8c638..00000000 Binary files a/doxygen/images/blinky_ek-tm4c123gxl.jpg and /dev/null differ diff --git a/doxygen/images/blinky_posix.png b/doxygen/images/blinky_posix.png deleted file mode 100644 index 48cc3793..00000000 Binary files a/doxygen/images/blinky_posix.png and /dev/null differ diff --git a/doxygen/images/blinky_win32.png b/doxygen/images/blinky_win32.png deleted file mode 100644 index 75b5d9a0..00000000 Binary files a/doxygen/images/blinky_win32.png and /dev/null differ diff --git a/doxygen/images/car_mud.jpg b/doxygen/images/car_mud.jpg deleted file mode 100644 index ed18484f..00000000 Binary files a/doxygen/images/car_mud.jpg and /dev/null differ diff --git a/doxygen/images/com_msp-exp430g2.png b/doxygen/images/com_msp-exp430g2.png deleted file mode 100644 index f5a01551..00000000 Binary files a/doxygen/images/com_msp-exp430g2.png and /dev/null differ diff --git a/doxygen/images/dpp_posix.png b/doxygen/images/dpp_posix.png deleted file mode 100644 index ae6d6c31..00000000 Binary files a/doxygen/images/dpp_posix.png and /dev/null differ diff --git a/doxygen/images/dpp_win.png b/doxygen/images/dpp_win.png deleted file mode 100644 index 14896b6a..00000000 Binary files a/doxygen/images/dpp_win.png and /dev/null differ diff --git a/doxygen/images/dpp_win32.jpg b/doxygen/images/dpp_win32.jpg deleted file mode 100644 index 21ef7141..00000000 Binary files a/doxygen/images/dpp_win32.jpg and /dev/null differ diff --git a/doxygen/images/dpp_win32.png b/doxygen/images/dpp_win32.png deleted file mode 100644 index f1bf6860..00000000 Binary files a/doxygen/images/dpp_win32.png and /dev/null differ diff --git a/doxygen/images/emWin_demo.jpg b/doxygen/images/emWin_demo.jpg deleted file mode 100644 index 075bcc6e..00000000 Binary files a/doxygen/images/emWin_demo.jpg and /dev/null differ diff --git a/doxygen/images/exa_low-power_sig-zoom.png b/doxygen/images/exa_low-power_sig-zoom.png deleted file mode 100644 index 20af7d69..00000000 Binary files a/doxygen/images/exa_low-power_sig-zoom.png and /dev/null differ diff --git a/doxygen/images/exa_low-power_sm.png b/doxygen/images/exa_low-power_sm.png deleted file mode 100644 index bbdd1acc..00000000 Binary files a/doxygen/images/exa_low-power_sm.png and /dev/null differ diff --git a/doxygen/images/game-video.jpg b/doxygen/images/game-video.jpg deleted file mode 100644 index e88cae43..00000000 Binary files a/doxygen/images/game-video.jpg and /dev/null differ diff --git a/doxygen/images/getting-started-with-qp.jpg b/doxygen/images/getting-started-with-qp.jpg deleted file mode 100644 index f1793632..00000000 Binary files a/doxygen/images/getting-started-with-qp.jpg and /dev/null differ diff --git a/doxygen/images/github-star.jpg b/doxygen/images/github-star.jpg deleted file mode 100644 index c230ace5..00000000 Binary files a/doxygen/images/github-star.jpg and /dev/null differ diff --git a/doxygen/images/gs-video.jpg b/doxygen/images/gs-video.jpg deleted file mode 100644 index 373c721c..00000000 Binary files a/doxygen/images/gs-video.jpg and /dev/null differ diff --git a/doxygen/images/header_logo_bg.png b/doxygen/images/header_logo_bg.png deleted file mode 100644 index b6b9df7c..00000000 Binary files a/doxygen/images/header_logo_bg.png and /dev/null differ diff --git a/doxygen/images/header_logo_ql.png b/doxygen/images/header_logo_ql.png deleted file mode 100644 index 987822a8..00000000 Binary files a/doxygen/images/header_logo_ql.png and /dev/null differ diff --git a/doxygen/images/logo_embos.png b/doxygen/images/logo_embos.png deleted file mode 100644 index 751132d1..00000000 Binary files a/doxygen/images/logo_embos.png and /dev/null differ diff --git a/doxygen/images/logo_freertos.png b/doxygen/images/logo_freertos.png deleted file mode 100644 index 8facff63..00000000 Binary files a/doxygen/images/logo_freertos.png and /dev/null differ diff --git a/doxygen/images/logo_pclintplus.jpg b/doxygen/images/logo_pclintplus.jpg deleted file mode 100644 index 9abfd51b..00000000 Binary files a/doxygen/images/logo_pclintplus.jpg and /dev/null differ diff --git a/doxygen/images/logo_ql-comp.png b/doxygen/images/logo_ql-comp.png deleted file mode 100644 index 77d4e4e5..00000000 Binary files a/doxygen/images/logo_ql-comp.png and /dev/null differ diff --git a/doxygen/images/logo_ql-icon.png b/doxygen/images/logo_ql-icon.png deleted file mode 100644 index 8d539d6e..00000000 Binary files a/doxygen/images/logo_ql-icon.png and /dev/null differ diff --git a/doxygen/images/logo_ql.png b/doxygen/images/logo_ql.png deleted file mode 100644 index dab80d0b..00000000 Binary files a/doxygen/images/logo_ql.png and /dev/null differ diff --git a/doxygen/images/logo_ql_TM.jpg b/doxygen/images/logo_ql_TM.jpg deleted file mode 100644 index 9963117e..00000000 Binary files a/doxygen/images/logo_ql_TM.jpg and /dev/null differ diff --git a/doxygen/images/logo_qp.jpg b/doxygen/images/logo_qp.jpg deleted file mode 100644 index defb3abb..00000000 Binary files a/doxygen/images/logo_qp.jpg and /dev/null differ diff --git a/doxygen/images/logo_qp_200x55.png b/doxygen/images/logo_qp_200x55.png deleted file mode 100644 index 95177551..00000000 Binary files a/doxygen/images/logo_qp_200x55.png and /dev/null differ diff --git a/doxygen/images/logo_qp_60x55.jpg b/doxygen/images/logo_qp_60x55.jpg deleted file mode 100644 index 318d4a97..00000000 Binary files a/doxygen/images/logo_qp_60x55.jpg and /dev/null differ diff --git a/doxygen/images/logo_qspy.png b/doxygen/images/logo_qspy.png deleted file mode 100644 index f184f96b..00000000 Binary files a/doxygen/images/logo_qspy.png and /dev/null differ diff --git a/doxygen/images/logo_threadx.jpg b/doxygen/images/logo_threadx.jpg deleted file mode 100644 index 1fd0ff90..00000000 Binary files a/doxygen/images/logo_threadx.jpg and /dev/null differ diff --git a/doxygen/images/logo_uc-os2.jpg b/doxygen/images/logo_uc-os2.jpg deleted file mode 100644 index c9ef0274..00000000 Binary files a/doxygen/images/logo_uc-os2.jpg and /dev/null differ diff --git a/doxygen/images/logo_zephyr.jpg b/doxygen/images/logo_zephyr.jpg deleted file mode 100644 index ef2af6e6..00000000 Binary files a/doxygen/images/logo_zephyr.jpg and /dev/null differ diff --git a/doxygen/images/mbed-LPC1768_button.jpg b/doxygen/images/mbed-LPC1768_button.jpg deleted file mode 100644 index dd0418cd..00000000 Binary files a/doxygen/images/mbed-LPC1768_button.jpg and /dev/null differ diff --git a/doxygen/images/oop-in-C.jpg b/doxygen/images/oop-in-C.jpg deleted file mode 100644 index 58c43868..00000000 Binary files a/doxygen/images/oop-in-C.jpg and /dev/null differ diff --git a/doxygen/images/psicc1.jpg b/doxygen/images/psicc1.jpg deleted file mode 100644 index 8528061c..00000000 Binary files a/doxygen/images/psicc1.jpg and /dev/null differ diff --git a/doxygen/images/psicc2.jpg b/doxygen/images/psicc2.jpg deleted file mode 100644 index e5d19275..00000000 Binary files a/doxygen/images/psicc2.jpg and /dev/null differ diff --git a/doxygen/images/qk_preempt.png b/doxygen/images/qk_preempt.png deleted file mode 100644 index d04b01a1..00000000 Binary files a/doxygen/images/qk_preempt.png and /dev/null differ diff --git a/doxygen/images/qp-bundle.png b/doxygen/images/qp-bundle.png deleted file mode 100644 index 3ac2687b..00000000 Binary files a/doxygen/images/qp-bundle.png and /dev/null differ diff --git a/doxygen/images/qp-prio.png b/doxygen/images/qp-prio.png deleted file mode 100644 index 059896ec..00000000 Binary files a/doxygen/images/qp-prio.png and /dev/null differ diff --git a/doxygen/images/qp-zephyr.jpg b/doxygen/images/qp-zephyr.jpg deleted file mode 100644 index 16ef9346..00000000 Binary files a/doxygen/images/qp-zephyr.jpg and /dev/null differ diff --git a/doxygen/images/qp_banner.jpg b/doxygen/images/qp_banner.jpg deleted file mode 100644 index e372bd9c..00000000 Binary files a/doxygen/images/qp_banner.jpg and /dev/null differ diff --git a/doxygen/images/qp_classes.png b/doxygen/images/qp_classes.png deleted file mode 100644 index 9da1ada6..00000000 Binary files a/doxygen/images/qp_classes.png and /dev/null differ diff --git a/doxygen/images/qp_components.jpg b/doxygen/images/qp_components.jpg deleted file mode 100644 index e38cc52c..00000000 Binary files a/doxygen/images/qp_components.jpg and /dev/null differ diff --git a/doxygen/images/qpc_gh.jpg b/doxygen/images/qpc_gh.jpg deleted file mode 100644 index f22c00e2..00000000 Binary files a/doxygen/images/qpc_gh.jpg and /dev/null differ diff --git a/doxygen/images/qutest_philo.png b/doxygen/images/qutest_philo.png deleted file mode 100644 index 7257fd85..00000000 Binary files a/doxygen/images/qutest_philo.png and /dev/null differ diff --git a/doxygen/images/qutest_py.png b/doxygen/images/qutest_py.png deleted file mode 100644 index 297a8e17..00000000 Binary files a/doxygen/images/qutest_py.png and /dev/null differ diff --git a/doxygen/images/qutest_tcl.png b/doxygen/images/qutest_tcl.png deleted file mode 100644 index 5c13826a..00000000 Binary files a/doxygen/images/qutest_tcl.png and /dev/null differ diff --git a/doxygen/images/qutest_tm4c123_py.png b/doxygen/images/qutest_tm4c123_py.png deleted file mode 100644 index c07b3809..00000000 Binary files a/doxygen/images/qutest_tm4c123_py.png and /dev/null differ diff --git a/doxygen/images/qutest_tm4c123_tcl.png b/doxygen/images/qutest_tm4c123_tcl.png deleted file mode 100644 index 7f5c02ea..00000000 Binary files a/doxygen/images/qutest_tm4c123_tcl.png and /dev/null differ diff --git a/doxygen/images/qv.png b/doxygen/images/qv.png deleted file mode 100644 index c8deeae4..00000000 Binary files a/doxygen/images/qv.png and /dev/null differ diff --git a/doxygen/images/qwin_ani.gif b/doxygen/images/qwin_ani.gif deleted file mode 100644 index 68d72654..00000000 Binary files a/doxygen/images/qwin_ani.gif and /dev/null differ diff --git a/doxygen/images/qwin_static.jpg b/doxygen/images/qwin_static.jpg deleted file mode 100644 index b2a8de44..00000000 Binary files a/doxygen/images/qwin_static.jpg and /dev/null differ diff --git a/doxygen/images/qxk_classes.png b/doxygen/images/qxk_classes.png deleted file mode 100644 index 7fa725dd..00000000 Binary files a/doxygen/images/qxk_classes.png and /dev/null differ diff --git a/doxygen/images/qxk_ctx-switch.png b/doxygen/images/qxk_ctx-switch.png deleted file mode 100644 index 07c78afd..00000000 Binary files a/doxygen/images/qxk_ctx-switch.png and /dev/null differ diff --git a/doxygen/images/start-stop.png b/doxygen/images/start-stop.png deleted file mode 100644 index 1841dfa3..00000000 Binary files a/doxygen/images/start-stop.png and /dev/null differ diff --git a/doxygen/images/threadx_dpp.jpg b/doxygen/images/threadx_dpp.jpg deleted file mode 100644 index 2c3c4e2c..00000000 Binary files a/doxygen/images/threadx_dpp.jpg and /dev/null differ diff --git a/doxygen/images/v-model.png b/doxygen/images/v-model.png deleted file mode 100644 index 2239a71f..00000000 Binary files a/doxygen/images/v-model.png and /dev/null differ diff --git a/doxygen/img/AN.jpg b/doxygen/img/AN.jpg deleted file mode 100644 index 7b99c486..00000000 Binary files a/doxygen/img/AN.jpg and /dev/null differ diff --git a/doxygen/img/AN_Active_Objects_for_Embedded.jpg b/doxygen/img/AN_Active_Objects_for_Embedded.jpg deleted file mode 100644 index 53b661c8..00000000 Binary files a/doxygen/img/AN_Active_Objects_for_Embedded.jpg and /dev/null differ diff --git a/doxygen/img/AN_Coding_Standard.jpg b/doxygen/img/AN_Coding_Standard.jpg deleted file mode 100644 index 28444979..00000000 Binary files a/doxygen/img/AN_Coding_Standard.jpg and /dev/null differ diff --git a/doxygen/img/AN_Crash_Course_in_UML_State_Machines.gif b/doxygen/img/AN_Crash_Course_in_UML_State_Machines.gif deleted file mode 100644 index a345e966..00000000 Binary files a/doxygen/img/AN_Crash_Course_in_UML_State_Machines.gif and /dev/null differ diff --git a/doxygen/img/AN_MISRA-QPC.jpg b/doxygen/img/AN_MISRA-QPC.jpg deleted file mode 100644 index 8a3b09f2..00000000 Binary files a/doxygen/img/AN_MISRA-QPC.jpg and /dev/null differ diff --git a/doxygen/img/AN_OOP_in_C.gif b/doxygen/img/AN_OOP_in_C.gif deleted file mode 100644 index fdc61576..00000000 Binary files a/doxygen/img/AN_OOP_in_C.gif and /dev/null differ diff --git a/doxygen/img/board.png b/doxygen/img/board.png deleted file mode 100644 index ea9d1832..00000000 Binary files a/doxygen/img/board.png and /dev/null differ diff --git a/doxygen/img/cert-pack.png b/doxygen/img/cert-pack.png deleted file mode 100644 index 39e2ad84..00000000 Binary files a/doxygen/img/cert-pack.png and /dev/null differ diff --git a/doxygen/img/checkboxoff.png b/doxygen/img/checkboxoff.png deleted file mode 100644 index a68a3218..00000000 Binary files a/doxygen/img/checkboxoff.png and /dev/null differ diff --git a/doxygen/img/checkboxon.png b/doxygen/img/checkboxon.png deleted file mode 100644 index be666df9..00000000 Binary files a/doxygen/img/checkboxon.png and /dev/null differ diff --git a/doxygen/img/extern.png b/doxygen/img/extern.png deleted file mode 100644 index acf260fc..00000000 Binary files a/doxygen/img/extern.png and /dev/null differ diff --git a/doxygen/img/favicon.ico b/doxygen/img/favicon.ico deleted file mode 100644 index 7f82052b..00000000 Binary files a/doxygen/img/favicon.ico and /dev/null differ diff --git a/doxygen/img/file.png b/doxygen/img/file.png deleted file mode 100644 index d2ce7ddd..00000000 Binary files a/doxygen/img/file.png and /dev/null differ diff --git a/doxygen/img/file_c.png b/doxygen/img/file_c.png deleted file mode 100644 index 15aaa86b..00000000 Binary files a/doxygen/img/file_c.png and /dev/null differ diff --git a/doxygen/img/file_cpp.png b/doxygen/img/file_cpp.png deleted file mode 100644 index a3241962..00000000 Binary files a/doxygen/img/file_cpp.png and /dev/null differ diff --git a/doxygen/img/file_doc.png b/doxygen/img/file_doc.png deleted file mode 100644 index 803bd089..00000000 Binary files a/doxygen/img/file_doc.png and /dev/null differ diff --git a/doxygen/img/file_h.png b/doxygen/img/file_h.png deleted file mode 100644 index 6fe57c84..00000000 Binary files a/doxygen/img/file_h.png and /dev/null differ diff --git a/doxygen/img/file_mak.png b/doxygen/img/file_mak.png deleted file mode 100644 index be860ebd..00000000 Binary files a/doxygen/img/file_mak.png and /dev/null differ diff --git a/doxygen/img/file_pdf.png b/doxygen/img/file_pdf.png deleted file mode 100644 index 44d3acdc..00000000 Binary files a/doxygen/img/file_pdf.png and /dev/null differ diff --git a/doxygen/img/file_py.png b/doxygen/img/file_py.png deleted file mode 100644 index 6e01e7fa..00000000 Binary files a/doxygen/img/file_py.png and /dev/null differ diff --git a/doxygen/img/file_qm.png b/doxygen/img/file_qm.png deleted file mode 100644 index d1e90ae2..00000000 Binary files a/doxygen/img/file_qm.png and /dev/null differ diff --git a/doxygen/img/file_qmp.png b/doxygen/img/file_qmp.png deleted file mode 100644 index 5cffd8fa..00000000 Binary files a/doxygen/img/file_qmp.png and /dev/null differ diff --git a/doxygen/img/file_tcl.png b/doxygen/img/file_tcl.png deleted file mode 100644 index 8f5e3375..00000000 Binary files a/doxygen/img/file_tcl.png and /dev/null differ diff --git a/doxygen/img/file_wish.png b/doxygen/img/file_wish.png deleted file mode 100644 index 54630ce5..00000000 Binary files a/doxygen/img/file_wish.png and /dev/null differ diff --git a/doxygen/img/folder.png b/doxygen/img/folder.png deleted file mode 100644 index 78ad6cd4..00000000 Binary files a/doxygen/img/folder.png and /dev/null differ diff --git a/doxygen/img/forbidden.png b/doxygen/img/forbidden.png deleted file mode 100644 index c00505dd..00000000 Binary files a/doxygen/img/forbidden.png and /dev/null differ diff --git a/doxygen/img/header_bg.png b/doxygen/img/header_bg.png deleted file mode 100644 index 6d266d9c..00000000 Binary files a/doxygen/img/header_bg.png and /dev/null differ diff --git a/doxygen/img/help_dark.png b/doxygen/img/help_dark.png deleted file mode 100644 index aa30b97d..00000000 Binary files a/doxygen/img/help_dark.png and /dev/null differ diff --git a/doxygen/img/help_light.png b/doxygen/img/help_light.png deleted file mode 100644 index 85e8f4b7..00000000 Binary files a/doxygen/img/help_light.png and /dev/null differ diff --git a/doxygen/img/img.htm b/doxygen/img/img.htm deleted file mode 100644 index 70af24d3..00000000 --- a/doxygen/img/img.htm +++ /dev/null @@ -1,51 +0,0 @@ - - - - - -QP built-in images - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/doxygen/img/logo_github.png b/doxygen/img/logo_github.png deleted file mode 100644 index 99b38392..00000000 Binary files a/doxygen/img/logo_github.png and /dev/null differ diff --git a/doxygen/img/logo_ql.png b/doxygen/img/logo_ql.png deleted file mode 100644 index dab80d0b..00000000 Binary files a/doxygen/img/logo_ql.png and /dev/null differ diff --git a/doxygen/img/logo_qp.gif b/doxygen/img/logo_qp.gif deleted file mode 100644 index 4c6daba5..00000000 Binary files a/doxygen/img/logo_qp.gif and /dev/null differ diff --git a/doxygen/img/logo_qp.jpg b/doxygen/img/logo_qp.jpg deleted file mode 100644 index defb3abb..00000000 Binary files a/doxygen/img/logo_qp.jpg and /dev/null differ diff --git a/doxygen/img/logo_qwin.jpg b/doxygen/img/logo_qwin.jpg deleted file mode 100644 index c864ddd6..00000000 Binary files a/doxygen/img/logo_qwin.jpg and /dev/null differ diff --git a/doxygen/img/logo_win.png b/doxygen/img/logo_win.png deleted file mode 100644 index e761ad39..00000000 Binary files a/doxygen/img/logo_win.png and /dev/null differ diff --git a/doxygen/img/minus.png b/doxygen/img/minus.png deleted file mode 100644 index cd44ccc0..00000000 Binary files a/doxygen/img/minus.png and /dev/null differ diff --git a/doxygen/img/model.png b/doxygen/img/model.png deleted file mode 100644 index d1e90ae2..00000000 Binary files a/doxygen/img/model.png and /dev/null differ diff --git a/doxygen/img/movie.png b/doxygen/img/movie.png deleted file mode 100644 index 34681065..00000000 Binary files a/doxygen/img/movie.png and /dev/null differ diff --git a/doxygen/img/qp_link.png b/doxygen/img/qp_link.png deleted file mode 100644 index 2c4ff760..00000000 Binary files a/doxygen/img/qp_link.png and /dev/null differ diff --git a/doxygen/img/radiooff.png b/doxygen/img/radiooff.png deleted file mode 100644 index 41921e3d..00000000 Binary files a/doxygen/img/radiooff.png and /dev/null differ diff --git a/doxygen/img/radioon.png b/doxygen/img/radioon.png deleted file mode 100644 index bf6c784a..00000000 Binary files a/doxygen/img/radioon.png and /dev/null differ diff --git a/doxygen/img/splitbar.png b/doxygen/img/splitbar.png deleted file mode 100644 index 1b9ea10a..00000000 Binary files a/doxygen/img/splitbar.png and /dev/null differ diff --git a/doxygen/img/tree-view_linked.png b/doxygen/img/tree-view_linked.png deleted file mode 100644 index 870c50a1..00000000 Binary files a/doxygen/img/tree-view_linked.png and /dev/null differ diff --git a/doxygen/img/tree-view_unlinked.png b/doxygen/img/tree-view_unlinked.png deleted file mode 100644 index 8c8a653f..00000000 Binary files a/doxygen/img/tree-view_unlinked.png and /dev/null differ diff --git a/doxygen/lint.dox b/doxygen/lint.dox deleted file mode 100644 index 11a4ee4b..00000000 --- a/doxygen/lint.dox +++ /dev/null @@ -1,6 +0,0 @@ -/*! @page lint PC-Lint -The QP/C framework comes with extensive support for automatic rule checking by means of PC-Lint, which is designed not just for proving compliance of the Q/CP framework code, but more importantly, to aid in checking compliance of the application-level code. Any organization engaged in designing safety-related embedded software could benefit from the unprecedented quality infrastructure built around the QP/C framework. - -@sa ports_lint - -*/ diff --git a/doxygen/main.dox b/doxygen/main.dox deleted file mode 100644 index 249d30b1..00000000 --- a/doxygen/main.dox +++ /dev/null @@ -1,138 +0,0 @@ -/*! @mainpage Overview - -@image html qp_banner.jpg -@image latex qp_banner.jpg width=6.5in - -@ifnot LATEX -@remark - -@endif -@image{inline} latex logo_github.png width=1in -To check what's new in QP™/C, please see @ref history "Design History File". You can also get the latest **QP™/C code**, with the recent enhancements and bug fixes, from the GitHub QP™/C repository. -
- - -@section over_about What is it? -QP™/C Real-Time Embedded Framework (RTEF) is a lightweight implementation of the @webref{active-object, Active Object model of computation} specifically tailored for real-time embedded (RTE) systems. QP is both a *software infrastructure* for building applications consisting of active objects (actors) and a *runtime environment* for executing the active objects in a deterministic fashion. Additionally, QP Framework supports @webref{fsm#HSM, Hierarchical State Machines} with which to specify the behavior of Active Objects @ref srs_ref "[ROOM:94], [UML 2.5],[Sutter:10]". You can think of the QP/C RTEF as a modern, truly *event-driven* real-time operating system (RTOS). - - -@section over_goals What does it do? -The main objectives of the QP/C RTEF are: - -- to provide a modern, event-driven model of concurrency based on the best practices of concurrent programming collectively known as the @webref{active-object, Active Object (Actor) model of computation}, which is inherently *safer* than the traditional "shared-state concurrency, mutual-exclusion, and blocking" approach based on a conventional Real-Time Operating System (RTOS); - -- to provide an efficient, @ref cert_tr "bidirectionally traceable" implementation of @webref{fsm#HSM, Hierarchical State Machines} for specifying the internal behavior of Active Objects; - -- to provide a *higher-level of abstraction* closer to the problem domain than the "naked" RTOS threads; - -- to provide the *right* abstractions for applying modern techniques like visual modeling, hierarchical state machines, and automatic code generation; - -- to bridge the semantic gap between the higher level modeling concepts (such as UML) and the traditional programming languages like C or C++. - - -@section over_special What's special about it? -The QP™/C Real-Time Embedded Framework (RTEF) provides a modern, reusable **architecture** of embedded applications, which combines the model of concurrency, known as @webref{active-object, active objects} (actors) with @webref{fsm#HSM, Hierarchical State Machines}. This architecture is generally **safer**, more responsive and easier to understand than "free threading" with a traditional Real-Time Operating System (RTOS). It also provides sufficiently high level of abstraction and the *right* abstractions to effectively apply modeling and code generation to deeply embedded systems. - -@note -The most unique aspect of the QP™/C RTEF is its @ref over_eff "tiny size and efficiency" suitable for embedded microcontrollers, such as MCUs based on ARM Cortex-M. - - -@subsection over_oop Object Orientation -Even though it is written in @ref misra "MISRA-compliant" ISO-C99, QP™/C is fundamentally an **object-oriented** framework, which means that the framework itself and your applications derived from the framework are fundamentally composed of @ref sas_core "classes" and only classes can have @ref srs_sm "state machines" associated with them. - -@anchor oop -@remark -If you program in C and object-oriented programming is new to you, please refer to the article and set of videos @webref{oop, "Object-Oriented Programming"}, which among others describes how you can implement the concepts of *classes*, *inheritance*, and *polymorphism* to portable ISO-C.
-
-@ifnot LATEX -[![](oop-in-C.jpg)](https://www.state-machine.com/oop) -@endif -@image latex oop-in-C.jpg width=3.00in -@caption{Application Note: Object-Oriented Programming in C} - - -@subsection over_hsms Hierarchical State Machines -The behavior of active objects is specified in QP™/C by means of @webref{fsm/#HSM, hierarchical state machines (UML statecharts)}. The framework supports manual coding of UML state machines in C as well as fully **automatic code generation** by means of the free graphical @webref{products/qm, QM™ model-based design (MBD) tool}. - - -@subsection over_kernels Built-in Kernels -The QP™/C framework can run on @ref exa_native "bare-metal single-chip microcontrollers", completely replacing a traditional RTOS. The framework contains a selection of built-in real-time kernels, such as the cooperative @ref srs_qv "QV kernel", the preemptive non-blocking @ref srs_qk "QK kernel", and the preemptive, dual-mode, blocking @ref srs_qxk "QXK kernel". The QXK kernel provides all the features you might expect from a traditional RTOS kernel and has been specifically designed for mixing event-driven active objects with traditional blocking code, such as commercial middleware (TCP/IP stacks, UDP stacks, embedded file systems, etc.) or legacy software. @ref ports_native "Native QP ports" and ready-to-use @ref exa_native "examples" are provided for major @ref exa_ref_mcu "CPU families". - - -@subsection over_eff Size and Efficiency -Even though QP™/C offers much higher level of abstraction than a traditional RTOS, it typically outperforms equivalent traditional RTOS applications both in RAM/ROM footprint and in CPU efficiency. The specific measurements and results are reported in the following @webref{doc/AN_QP_Performance.pdf, Application Note: "QP Performance Tests and Results"}: - -@ifnot LATEX -[![](an-qp_performance.png)](https://www.state-machine.com/doc/AN_QP_Performance.pdf) -@endif -@image latex an-qp_performance.png width=1.5in -@caption{QP Performance Tests and Results} - -@subsection over_inter Interoperability -QP/C can also work with many traditional @ref exa_rtos "Real-Time Operating Systems (RTOSes)" and @ref exa_os "general-purpose operating systems (GPOSes)" (such as Linux (POSIX) and Windows). - - -@subsection over_trace Traceability -QP™/C offers unprecedented, bidirectional @ref cert_tr "traceability" among all work artifacts, which gives teams full visibility from requirements through architecture, design, source code, tests, and back again. - - -@subsection over_popular Popularity & Maturity -With 20 years of continuous development, over @webref{customers#Customers, 350 commercial licensees}, and many times more open source users worldwide, the QP™ frameworks are the most popular such offering on the market. They power countless electronic products ranging from implantable medical devices to complex weapon systems. - - -@subsection over_use Widespread Use -The QP™ real-time embedded frameworks address high-reliability applications across a @webref{customers#Markets, wide variety of markets}, such as medical, consumer, IoT, defense, robotics, industrial, communication, transportation, semiconductor IP, and many others. In each of these application areas, the elegant software architecture and modern design philosophy of QP™ have distinct advantages. - - -@subsection over_psicc2 Books -The two editions of the book, @webref{psicc2, Practical Statecharts in C/C++} provide a detailed design study of the QP™ frameworks and explain the related concepts. - -@ifnot LATEX -[![](psicc2.jpg)](https://www.state-machine.com/psicc2) -@endif -@image latex psicc2.jpg width=3.1in -@caption{Practical UML Statecharts in C/C++, 2nd Edition} - -@ifnot LATEX -[![](psicc1.jpg)](https://www.state-machine.com/psicc) -@endif -@image latex psicc1.jpg width=4.5in -@caption{Practical Statecharts in C/C++, 1nd Edition} - - -@section over_licensing How is it licensed? -QP™/C is licensed under the sustainable @webref{licensing, dual licensing model}, in which both the open source software distribution mechanism and traditional closed source software distribution models are combined. - -@note -If your company has a policy forbidding open source in your product, all QP frameworks can be @webref{licensing#Commercial, licensed commercially}, in which case you don't use any open source license and you do not violate your policy. - - -@subsection over_open-source Open Source Projects -If you are developing and distributing **open source** applications under the GNU General Public License (GPL), as published by the Free Software Foundation, then you are free to use the Quantum Leaps software under the GPL version 3 of the License, or (at your option) any later version. Please note that GPL requires that all modifications to the original code as well as your application code (Derivative Works as defined in the Copyright Law) must also be released under the terms of the GPL open source license. - - -@subsection over_closed-source Closed Source Projects -If you are developing and distributing traditional **closed source** applications, you can purchase one of @webref{licensing/#Commercial, Quantum Leaps commercial licenses}, which are specifically designed for users interested in retaining the proprietary status of their code. All Quantum Leaps commercial licenses expressly supersede the GPL open source license. This means that when you license Quantum Leaps software under a commercial license, you specifically do not use the software under the open source license and therefore you are not subject to any of its terms. - - -@section over_support How to get help? -Please post any **technical questions** to the Free Support Forum hosted on SourceForge.net. Posts to this forum benefit the whole community and are typically answered the same day. - -Direct **Commercial Support** is available to the commercial licensees. Every commercial license includes one year of Technical Support for the licensed software. The support term can be extended annually. - -Training and consulting services are also available from Quantum Leaps. Please refer to the @webref{contact, Contact web-page} for more information. - -@note -The features of this online help and tips for using it are described in Section @ref help. - - -@section over_contact Contact Information -- Quantum Leaps Web site: @webref{,state-machine.com} -- Quantum Leaps licensing: @webref{licensing, state-machine.com/licensing} -- Quantum Leaps on GitHub: github.com/QuantumLeaps -- e-mail: info@state-machine.com - -@ifnot LATEX -@nav_next{gs} -@endif -*/ diff --git a/doxygen/make.bat b/doxygen/make.bat deleted file mode 100644 index 33350505..00000000 --- a/doxygen/make.bat +++ /dev/null @@ -1,109 +0,0 @@ -@echo off -:: ========================================================================== -:: Product: batch script for generating Doxygen documentation -:: Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -:: -:: SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -:: -:: This software is dual-licensed under the terms of the open source GNU -:: General Public License version 3 (or any later version), or alternatively, -:: under the terms of one of the closed source Quantum Leaps commercial -:: licenses. -:: -:: The terms of the open source GNU General Public License version 3 -:: can be found at: -:: -:: The terms of the closed source Quantum Leaps commercial licenses -:: can be found at: -:: -:: Redistributions in source code must retain this top-level comment block. -:: Plagiarizing this software to sidestep the license obligations is illegal. -:: -:: Contact information: -:: -:: -:: ========================================================================== -@setlocal - -@echo usage: -@echo make -@echo make -CHM -@echo make -LATEX - -:: tools (adjust to your system)--------------------------------------------- -:: Doxygen tool -@set DOXYGEN=doxygen - -:: Simple complexity metrics tool (adjust to your system) -@set METRICS=lizard -m -L500 -a10 -C20 -V - -:: HTML Help tool (needed only with the -CHM option) . -@set HHC="C:\tools\HTML Help Workshop\hhc.exe" - -:: QP directory ............................................................. -@set QP=.. - -:: Outut directories ........................................................ -@set HTML_OUT=%QP%\html -IF "%1"=="-CERT" ( - @set HTML_OUT=%QP%\cert-pack -) -@set LATEX_OUT=%QP%\latex - -:: Generate metrics.dox file------------------------------------------------- -@set METRICS_INP=%QP%\include %QP%\src -x %QP%\src\qs\* -@set METRICS_OUT=gen\metrics.txt - -@echo @code{.c}> %METRICS_OUT% -%METRICS% %METRICS_INP% >> %METRICS_OUT% -@echo @endcode>> %METRICS_OUT% - -:: Generate Doxygen Documentation ------------------------------------------- -if "%1"=="-CHM" ( - - @echo Generating HTML... - %DOXYGEN% Doxyfile-CHM - - @echo Adding custom images... - xcopy img tmp\img\ - @echo img\img.htm >> tmp\index.hhp - - @echo Generating CHM... - %HHC% tmp\index.hhp - - @echo. - @echo Cleanup... - @rmdir /S /Q tmp - @echo CHM file generated - -) else if "%1"=="-LATEX" ( - - @echo. - @echo Cleanup... - rmdir /S /Q %LATEX_OUT% - - @echo Generating LATEX... - %DOXYGEN% Doxyfile-LATEX - - @echo Adding custom files... - xcopy img %LATEX_OUT%\img\ - - @cd %LATEX_OUT% - @call make.bat - -) else ( - - @echo. - @echo Cleanup... - rmdir /S /Q %HTML_OUT% - - @echo Generating HTML... - %DOXYGEN% Doxyfile%1 - - @echo Adding custom files... - xcopy img %HTML_OUT%\img\ - xcopy /Y ..\..\ql-doxygen\jquery.js %HTML_OUT% - rem @qclean %HTML_OUT% -) - -@endlocal diff --git a/doxygen/modules-unused.dox b/doxygen/modules-unused.dox deleted file mode 100644 index 7d2357a8..00000000 --- a/doxygen/modules-unused.dox +++ /dev/null @@ -1,275 +0,0 @@ -/*! @defgroup qp QP - -@brief -QP Framework -*/ -/*##########################################################################*/ -/*! @defgroup qep QEP - -@brief -Hierarchical Event Processor - -QEP is a universal, UML-compliant event processor that enables developers to code UML state machines in highly readable ANSI-C, in which every state machine element is mapped to code precisely, unambiguously, and exactly once (traceability). QEP fully supports hierarchical state nesting, which is the fundamental mechanism for reusing behavior across many states instead of repeating the same actions and transitions over and over again. -*/ -/*##########################################################################*/ -/*! @defgroup qf QF - -@brief -Active Object (Actor) Framework - -QF is a portable, event-driven, real-time framework for execution of active objects (concurrent state machines) specifically designed for real-time embedded (RTE) systems. -*/ -/*##########################################################################*/ -/*! @defgroup qs QS - -@brief -Software Tracing Instrumentation - -QS is software tracing system that enables developers to monitor live QP applications with minimal target system resources and without stopping or significantly slowing down the code. QS is an ideal tool for testing, troubleshooting, and optimizing QP applications. QS can even be used to support acceptance testing in product manufacturing. Please see QS Manual inside the QTools collection for more information. -*/ -/*##########################################################################*/ -/*! @defgroup qv QV - -@brief -Cooperative Kernel - -@description -QV is a simple **cooperative** kernel (previously called "Vanilla" kernel). This kernel executes active objects one at a time, with priority-based scheduling performed before processing of each event. Due to naturally short duration of event processing in state machines, the simple QV kernel is often adequate for many real-time systems. - -@note -The QV scheduler is described in Section 6.3.7 of the book ["Practical UML Statecharts in C/C++, 2nd Ed" (PSiCC2)](https://www.state-machine.com/psicc2/). - - -@section qv_overview QV Overview -The QV scheduler is engaged after every RTC step of any active object to choose the next active object to execute. The QV scheduler always chooses the highest-priority active object that has any events in its event queue. The QV scheduler then extracts the next event from this queue and dispatches it to the state machine associated with the active object. The state machine runs to completion, after which the QV scheduler runs and the cycle repeats. - -@image html qv.png "QV scheduler operation" -@image latex qv.png "QV scheduler operation" - -Please note that because the state machines always return to the QV scheduler after each RTC step, a single stack can be used to process all state machines (memory-friendly architecture). - -The QV scheduler can also very easily detect when all event queues are empty, at which point it can call the idle callback to let the application put the CPU and peripherals to a **low-power sleep mode** (power-friendly architecture). - -Given the simplicity, portability, and low-resource consumption, the QV scheduler is very attractive. It allows you to partition the problem into active objects and execute these active objects orderly. The thread-level response of this scheduler is the longest RTC step in the whole system, but because event-driven active objects don’t block, the RTC steps tend to be very short (typically just a few microseconds). Also, often you can break up longer RTC steps into shorter pieces, by posting an event to self and returning (“Reminder” state pattern). The self-posted event then triggers the continuation of longer processing. - -@remarks -Sometimes it is not practical to break up long RTC steps, and consequently the thread-level response of the simple @ref srs_qv "QV kernel" might be too slow. In this cases you need to use a *preemptive* kernel. The big advantage of preemptive kernel is that it effectively decouples high-priority thread from low-priority threads in the time domain. The timeliness of execution of high-priority thread is almost independent on the low-priority threads. But of course there is no such thing as a free lunch. Preemptive kernels open the whole new class of problems related to race conditions. So you need to be very careful about sharing any resources. - -@ifnot LATEX -@nav_next{qk} -@endif -*/ -/*##########################################################################*/ -/*! @defgroup qk QK - -@brief -Preemptive Run-To-Completion (Non-Blocking) Kernel - -The preemptive, non-blocking QK kernel is specifically designed to execute non-blocking active objects (see also [[PSiCC2](https://www.state-machine.com/psicc2/), Chapter 10]). QK runs active objects in the same way as prioritized interrupt controller (such as NVIC in ARM Cortex-M) runs interrupts using **single stack**. Active objects process their events in run-to-completion (RTC) fashion and remove themselves from the call stack, the same way as nested interrupts remove themselves from the stack upon completion. At the same time high-priority active objects can **preempt** lower-priority active objects, just like interrupts can preempt each other under a prioritized interrupt controller. QK meets all the requirement of the Rate Monotonic Scheduling (a.k.a. Rate Monotonic Analysis RMA) and can be used in hard real-time systems. - -@note -The non-blocking, run-to-completion, preemptive threads are known in the literature as "basic threads" (OSEK/AUTOSAR terminology), sometimes also called "fibers" (e.g., Q-Kernel) or "software interrupts" (e.g., TI-RTOS). - - -@section qk_overview QK Overview -The preemptive, run-to-completion (RTC) QK kernel breaks entirely with the endless-loop structure of the thread routines and instead uses threads structured as one-shot, discrete, run-to-completion functions, very much like ISRs [[PSiCC2](https://www.state-machine.com/psicc2/), Chapter 10]. In fact, the QK kernel views interrupts very much like threads of a “super-high” priority, except that interrupts are prioritized in hardware by the interrupt controller, whereas threads are prioritized in software by the RTC kernel. - -As a fully preemptive multithreading kernel, QK must ensure that at all times the CPU executes the highest-priority thread (active object) that is ready to run. Fortunately, only two scenarios can lead to readying a higher-priority thread: - -`[1]` When a lower-priority thread posts an event to a higher-priority thread, the kernel must immediately suspend the execution of the lower-priority thread and start the higher-priority thread. This type of preemption is called synchronous preemption because it happens synchronously with posting an event to the thread's event queue. - -@note -The stack usage shown in the bottom panel displays stack growing down (towards lower addresses), as it is the case in ARM Cortex-M. - -@anchor qk-synch-fig -@image html qk_synch.png -@image latex qk_synch.png width=5.0in -@caption{Synchronous Preemption in QK} - -`[2]` When an interrupt posts an event to a higher-priority thread than the interrupted thread, upon completion of the ISR the kernel must start execution of the higher-priority thread instead of resuming the lower-priority thread. This type of preemption is called asynchronous preemption because it can happen asynchronously, any time interrupts are not explicitly disabled. - -@note -The stack usage during asynchronous preemption on ARM Cortex-M is slightly simplified in the diagram below. A more detailed stack usage diagram is discussed later in the section explaining the @ref arm-cm_qk_port-asm_pendsv "Detailed stack allocation in QK for ARM Cortex-M". - - -@anchor qk-asynch-fig -@image html qk_asynch.png -@image latex qk_asynch.png width=5.0in -@caption{Asynchronous Preemption in QK} - - -@note -A traditional RTOS kernel does not distinguish between the synchronous and asynchronous preemptions and makes all preemptions look like the more stack-intensive asynchronous preemptions. In contrast, a RTC kernel can implement synchronous preemption as a simple function call (to QK_activate_()), which is much more efficient than a full context-switch. - -@ifnot LATEX -@nav_next{qxk} -@endif -*/ -/*##########################################################################*/ -/*! @defgroup qxk QXK - -@brief -Preemptive Dual-Mode (Run-to-Completion/Blocking) RTOS Kernel - -QXK is a small, preemptive, priority-based, dual-mode **blocking** kernel that executes active objects like the @ref srs_qk "QK kernel" (@ref srs_qxk_basic "basic threads"), but can also execute traditional __blocking__ threads (@ref srs_qxk_extended "extended threads"). In this respect, QXK behaves exactly like a __conventional RTOS__ (Real-Time Operating System). - -QXK has been designed specifically for mixing event-driven active objects with traditional blocking code, such as commercial middleware (TCP/IP stacks, UDP stacks, embedded file systems, etc.) or legacy software. To this end, QXK is not only more efficient than running QP on top of a @ref ports_rtos "traditional 3rd-party RTOS" (because non-blocking @ref srs_qxk_basic "basic threads" take far less stack space and CPU cycles for context switch than the much heavier @ref srs_qxk_extended "extended threads"). But the biggest advantage of QXK is that it __protects__ the application-level code from inadvertent mixing of blocking calls inside the event-driven active objects. Specifically, QXK "knows" the type of the thread context (extended/basic) and asserts internally if a blocking call (e.g., semaphore-wait or a time-delay) is attempted in a basic thread (active object). This is something that a QP port to a @ref ports_rtos "conventional 3rd-party RTOS" cannot do, because such an RTOS runs all code (including active objects) in the context of havyweight extended threads. - -Currently, the QXK kernel has been ported to the following CPUs: - -- @ref arm-cm_qxk "Cortex-M (M0/M0+/M1/M3/M4/M4F/M7)"@n -Supported toolchains include: ARM-KEIL MDK, IAR-ARM, GNU-ARM, TI-ARM. - -Currently, the QXK kernel is illustrated by the following examples: - -- @ref arm-cm_dpp_efm32-slstk3401a (ARM Cortex-M4F)@n -Example illustrates: 6 active objects plus two extended threads, QXK blocking delay, QXK semaphore, QXK mutex, QXK blocking message queue. - -- @ref arm-cm_dpp_ek-tm4c123gxl (ARM Cortex-M4F)@n -Example illustrates: 6 active objects plus two extended threads, QXK blocking delay, QXK semaphore, QXK mutex, QXK blocking message queue. - -- @ref arm-cm_dpp_nucleo-l053r8 (ARM Cortex-M0+)@n -Example illustrates: 6 active objects plus two extended threads, QXK blocking delay, QXK semaphore, QXK mutex, QXK blocking message queue. - - -@section qxk_basic Basic Threads -QXK supports **basic**-threads (non-blocking, run-to-completion activations). The basic-threads all nest on the same stack (Main Stack Pointer in ARM Cortex-M), so the stack usage is reduced. The additional advantage of basic-threads is that switching from basic-thread to another basic-thread requires only @ref srs_qxk_activate_() "activation" of the basic-thread, which is much simpler and faster than full context-switch required for @ref srs_qxk_extended "extended"-threads that QXK also supports (see below). - -@remarks -QXK adopts the "basic/exteded thread" terms from the OSEK/AUTOSAR Operating System specification. Other real-time kernels might use different terminology for similar concepts. For example, the Q-Kernel uses the term "fibers", while TI-RTOS uses the term "software interrupts" for concepts closely related to "basic threads". - - -@section qxk_extended Extended Threads -QXK supports **extended**-threads (blocking, typically structrued as endless loops). The extended-threads use private per-thread stacks, as in conventional RTOS kernels. Any switching from basic-to-extended thread or extended-to-extended thread requires full context switch. - -@remarks -QXK is a unique dual-mode kernel on the market that supports interleaving the priorities of basic threads and extended threads. Other dual-mode kernels typically limit the priorities of basic threads to be always higher (more urgent) than any of the extended threads. - -@sa ::QXThread - - -@section qxk_classes Classes in QXK -The figure below shows the main classes introduced in the QXK kernel and their relation to the classes of the QP framework. - -@image html qxk_classes.png "Classes of the QXK dual-mode kernel" -@image latex qxk_classes.png "Classes of the QXK dual-mode kernel" - -`[0]` The abstract ::QActive class represents active objects in QP. This class contains the @c thread object of the underlying kernel (QXK thread-control-block in this case) as well as the event queue and the unique priority of the active object. - -`[1]` The ::QXThread class represents the extended (blocking) threads of the QXK kernel. It inherits ::QActive, so that extended-threads can be treated as active objects internally in the framework. However, the extended-threads **do not implement state machines**. Instead, the data fields used for storing the current state in active objects are re-used to store the private stack of the extended-thread. The ::QXThread class also contains the @c timeEvt object (see ::QTimeEvt) for generating timeouts when the extended-thread is blocked. - -`[2]` The ::QXMutex class represents the **priority-ceiling mutex** of the QXK kernel. The mutex can block and can be used only in the extended-threads (in case they share resources that need to be protected). The mutex is recursive, meaning that it can be locked multiple times from the same extended thread (but it needs to be unlocked equal number of times). - -`[3]` The ::QXSemaphore class represents the **counting semaphore** of the QXK kernel. The semaphore can be waited on only in the extended-threads and the QXK kernel would assert if an active object thread would attempt to wait on a semaphore. On the other hand, a semaphore can be signaled from anywhere in the code, including active objects and ISRs. - -@note -The main takeaway from the QXK class diagram is QXK's **optimal, tight integration** with the QP framework. The QXK kernel reuses all mechanisms already provided in QP, thus avoiding any code duplication, inefficient layers of indirection, and additional licensing costs, which are inevitable when using @ref ports_rtos "3rd-party RTOS kernels" to run QP applications. - - -@section qxk_features QXK Feature Summary -As you can see in the list below, QXK provides most features you might expect of a traditional blocking **RTOS** kernel and is recommended as the preferred RTOS kernel for QP applications that need to mix active objects with traditional blocking code. - -
    - -
  • >Preemptive, priority-based scheduling of up to 64 threads. Each thread must be assigned its own unique priority (1 .. #QF_MAX_ACTIVE); -
  • - -> NOTE: QXK always executes the highest-priority thread that is ready to run (is not blocked). The scheduling algorithm used in QXK meets all the requirement of the Rate Monotonic Scheduling (a.k.a. Rate Monotonic Analysis — RMA) and can be used in hard real-time systems. - -
  • >QXK distinguishes between two types of threads: -
  • - -- **basic threads** of active objects that are made ready-to-run by events posted to the active objects. Such basic threads are non-blocking, run-to-completion activations that cannot block in the middle of the RTC step. QXK asserts when a basic thread attempts to use a blocking mechanism, such as a time-delay or a semaphore-wait. All basic threads share the common stack. - -- **extended threads** that can block anywhere in their thread-handler function, whereas QXK provides a typical assortments of blocking primitives for extended-threads, such as time-delay, blocking message queue, counting semaphore, or a mutex. Each extended thread must be provided with its own private stack. - -
  • >Tightly integrated mechanisms for communication between event-driven active objects and extended blocking threads: -
  • - -- Basic threads (Active Objects) can signal semaphores and send messages to extended threads. - -- Extended threads can post or publish events to active objects or other extended threads; - -- Extended threads can subscribe to events and thus can receive events published in the system. - - -
  • >Priority-Ceiling, recursive Mutexes with optional timeout; -
  • - -> **NOTE:** Priority-ceiling protocol implemented in QXK is immune to priority-inversions, but requires a unique QP thread priority level (the ceiling priority) to be assigned to the mutex. This ceiling priority is unavailable to QP threads.@n - -> **NOTE:** A QXK mutex can be configured not to use the priority-ceiling protocol (when initialized with a zero priority-ceiling). In that case, the mutex does not require a separate priority level. - -
  • >Counting Semaphores with optional timeout that can block multiple extended-threads; -
  • - -
  • >Blocking "zero-copy" message queue with optional timeout bound to each extended-thread; -
  • - -
  • >Deterministic fixed-size memory pools for dynamic memory management available both to extended-threads and active objects; -
  • - -
  • >Interrupt management, including "zero-latency", kernel-unaware interrupts that are never disabled; -
  • - -> NOTE: This feature is only supported on CPUs that allow selective interrupt disabling, such as ARM Cortex-M3/M4 (but not ARM Cortex-M0/M0+); - -
  • > @ref srs_qxk_tls "Thread-Local Storage" for all threads (basic threads and extended threads). -
  • -
- - -@subsection qxk_tls Thread Local Storage -Thread-local storage (TLS) is a programming method that uses static or global memory local to a thread. TLS is specifically useful for writing library-type code, which is used in a multithreaded environment and needs to access per-thread data in an independent way. - -TLS is used in some places where ordinary, single-threaded programs would use static or global variables, but where this would be inappropriate in multithreaded cases. An example of such situations is where library-type functions use a global variable to set an error condition (for example the global variable errno used by many functions of the C library). If errno were simply a global variable, a call of a system function on one thread may overwrite the value previously set by a call of a system function on a different thread, possibly before following code on that different thread could check for the error condition. The solution is to have errno be a variable that looks like it is global, but in fact exists once per thread—i.e., it lives in *thread-local storage*. A second use case would be multiple threads accumulating information into a global variable. To avoid a race condition, every access to this global variable would have to be protected by a mutual-exclusion mechanism. Alternatively, each thread might accumulate into a thread-local variable (that, by definition, cannot be read from or written to from other threads, implying that there can be no race conditions). Threads then only have to synchronize a final accumulation from their own thread-local variable into a single, truly global variable. - -The TLS implementations vary, but many systems, including QXK, implement TLS by providing a pointer-sized variable thread-local. This pointer can be set to arbitrarily sized memory blocks in a thread-local manner, by allocating such a memory block (statically or dynamically) and storing the memory address of that block in the thread-local variable. - -Typical usage of TLS in QXK is illustrated in the example qpc/examples/arm-cm/dpp_efm32-slstk3401a/qxk/, test.c, and consists: - -- define the TLS structure - -
-@code{.c} -typedef struct { - uint32_t foo; - uint8_t bar[10]; -} TLS_test; -@endcode - -- allocate the TLS storage for all participating threads (extended or basic threads) - -
-@code{.c} -static TLS_test l_tls1; -static TLS_test l_tls2; -@endcode - -- initialize the TLS per-thread pointer in each thread routine (for extended threads) or the top-most initial transition (for basic threads of active objects): -@code{c} -static void Thread1_run(QXThread * const me) { - me->super.thread = &l_tls1; /* initialize the TLS for Thread1 */ - . . . -} -. . . -static void Thread2_run(QXThread * const me) { - me->super.thread = &l_tls2; /* initialize the TLS for Thread2 */ - . . . -} -@endcode - -- access the TLS from your code: - -
-@code{.c} -void lib_fun(uint32_t x) { - QXK_TLS(TLS_test *)->foo = x; -} -@endcode - -@sa -- QXK_current() -- QXK_TLS() - -*/ diff --git a/doxygen/notes.txt b/doxygen/notes.txt deleted file mode 100644 index 05f2dbbd..00000000 --- a/doxygen/notes.txt +++ /dev/null @@ -1,8 +0,0 @@ -main.dox - -@note - -The @webref{products/qp#CERT,QP Certification Pack} provides: -- @ref srs "Software Requirements Specification" with a good @ref srs_over "overview" of the QP/C Framework -- @ref sas "Software Architecture Specification" with concise description of QP/C @ref sas_core "architecture" -- @ref sds "Software Design Specification" with detailed description of the QP/C @ref sds "design". diff --git a/doxygen/ports.dox b/doxygen/ports.dox deleted file mode 100644 index 614c5647..00000000 --- a/doxygen/ports.dox +++ /dev/null @@ -1,175 +0,0 @@ -/*! @page ports Ports - -@section ports_gen General Comments -The QP/C framework can be easily adapted to various operating systems, processor architectures, and compilers. Adapting the QP/C software is called porting and the QP/C framework has been designed from the ground up to make porting easy. - -The QP/C distribution contains many QP/C ports, which are organized into the three categories: - -- @subpage ports_lint (generic C compiler) QP/C "port" to the PC-Lint Plus static analysis tool (a "compiler") - -- @subpage ports_native "Native Ports" adapt QP/C to run on bare-metal processors "natively", using one of the built-in kernels (@ref srs_qv "QV", @ref srs_qk "QK", or @ref srs_qxk "QXK") - -- @subpage ports_rtos "3rd-Party RTOS Ports" adapt QP/C to run on top of a 3rd-Party Real-Time Operating System (RTOS) - -- @subpage ports_os "3rd-Party OS Ports" adapt QP/C to run on top of a 3rd-Party Operating System (OS), such as @ref win32 "Windows" or @ref posix "Linux". - - -@section ports_code Port Code Structure -Starting with QP/C release 5.4.0, **all** available ports are bundled into the QP/C download, as opposed to being distributed as separate QP Development Kits (QDKs). The main benefit is of this approach is that it greatly reduces chances of mistakes in combining the mainline QP/C code with various QDKs. The downside is that the QP/C distribution becomes quite large and that ports cannot be added or updated independently from the QP/C baseline code. - -All ports are located in sub-directories of the ports top-level folder, with the hierarchical organization outlined below: - -
-@code{.c} -qpc/ // QP/C installation directory -+---ports/ // ports directory -| | -| [1]--arm-cm/ // ports for ARM Cortex-M -| | +---qk/ // ports for preemptive QK kernel -| | | +---armclang/ // port with ARM-Clang (Compiler Version 6) toolchain -| | | +---gnu/ // port with GNU-ARM toolchain -| | | +---iar/ // port with IAR toolchain -| | +---qv/ // ports for cooperative QV kernel -| | \---qxk/ // ports for dual-mode QXK kernel -| | -| [2]--freertos/ // ports for FreeRTOS (3rd-party RTOS) -| | -| [3]--win32/ // port to Win32 (multithreaded) -| | +---Debug/ // Debug build configuration for VC++ toolset -| | +---Release/ // Release build configuration for VC++ toolset -| | +---QSpy/ // Spy build configuration for VC++ toolset -| | +---dbg/ // Debug build configuration for GNU toolset -| | +---rel/ // Release build configuration for GNU toolset -| | \---spy/ // Spy build configuration for GNU toolset -| | -| [4]--win32-qv/ // port to Win32 (single-threaded) -| | -| [5]--posix/ // port to POSIX (multithreaded) -| | -| [6]--posix-qv/ // port to POSIX (single-threaded) -@endcode - -`[1]` **Native Ports** are located in sub-directories named after the CPU architecture, such as arm-cm for ARM Cortex-M. Under that directory, the sub-directories qk and qv contain ports for the @ref comp_qk "QK" and @ref comp_qv "QV" kernels, respectively. - -`[2]` **Ports for 3rd-party RTOS** are located in sub-directories named after the RTOS, such as uc-os2 for uc-os2 RTOS. Under that directory, the sub-directories, such as arm-cm, contain examples for the specified CPU architecture, such as ARM Cortex-M here. - -`[3]` **Ports for 3rd-party OS** are located in sub-directories named after the OS, such as win32 for the Win32 API (Windows OS). (NOTE: The builds for desktop operating systems, such as Windows or Linux contain the pre-build QP libraries for the Debug, Release, and Spy build configurations). - - -@note -Because the QP distribution contains *all* ports, the number of sub-directories and files in the ports folder may seem daunting. However, knowing the structure of the ports folder, you can simply **delete** the sub-directories that are not interesting to you. - -@ifnot LATEX -@nav_next{ports_lint} -@endif -*/ -/*##########################################################################*/ -/*! @page ports_lint PC-Lint-Plus - -@image html pc-lint-plus.png "PC-Lint Plus" -@image latex pc-lint-plus.png "PC-Lint Plus" width=2in - -The QP/C distribution contains a "port" to PC-Lint-Plus static analysis tool from Vector, which is a static analysis tool for C and C++ with one of the longest track records and best value of the money in the industry. The "PC-Lint-Plus port" allows you to statically analyze the QP/C source code and facilitates static analysis of your **application code** based on QP/C. - -The QP/C "port" to PC-Lint-Plus is located in the directory qpc/ports/lint-plus and includes also lint configuration files, as well as an example of "linting" application code in the directory qpc/examples/arm-cm/dpp_ek-tm4c123gxl/lint-plus. The following listing describes the most important files in these three directories. - -
-@code{.c} -qpc/ // QP/C installation directory -+---ports/ // ports directory -| +---lint-plus/ // "port" to PC-Lint-Plus -| | +---16bit/ // "port" to 16-bit CPUs -| | | +-cpu.lnt // Lint options for a 16-bit CPU -| | | \-stdint.h // Standard exact-width integers for a 16-bit CPU -| | +---32bit/ // "port" to 16-bit CPUs -| | | +-cpu.lnt // Lint options for a 32-bit CPU -| | | \-stdint.h // Standard exact-width integers for a 32-bit CPU -| | +---qk/ // port with the QK kernel -| | +---qv/ // port with the QV kernel -| | +---qxk/ // port with the QXK kernel -| | -| | au-ds.lnt // Dan Saks recommendations -| | au-misra3.lnt // MISRA-C:2012 compliance checks -| | au-misra3-amd1.lnt // MISRA-C:2012-Amendment-1 additional checks -| | au-misra3-amd2.lnt // MISRA-C:2012-Amendment-2 additional checks -| | qpc.lnt // PC-Lint-Plus options for applications -| | std.lnt // Standard PC-Lint-Plus settings recommended by Quantum Leaps -| | lin.bat // Batch file to invoke PC-Lint-Plus to run analysis of QP/C code -| | options.lnt // PC/Lint-Plus options for "linting" QP/C source code -| | lint_qf.log // PC/Lint-Plus output for the QEP/QF components of QP/C -| | lint_qs.log // PC/Lint-Plus output for the QS component of QP/C -| | lint_qv.log // PC/Lint-Plus output for the QV component of QP/C -| | lint_qk.log // PC/Lint-Plus output for the QK component of QP/C -| | lint_qxk.log // PC/Lint-Plus output for the QXK component of QP/C -| | qep_port.h // QEP component "port" to a "generic C compiler" -| | stdbool.h // Standard Boolean type and constants for a "generic C compiler" -| -+---examples/ // examples directory (application) -| +---arm-cm/ // examples for ARM Cortex-M -| | +---dpp_ek-tm4c123gxl/ // DPP example on the EK-TM4C123GLX board -| | | +---lint-plus/ // directory for linting the application -| | | -| | | lin.bat // Batch to run PC-Lint-Plus analysis of application code -| | | options.lnt // PC-Lint-Plus options for "linting" of application code -@endcode - - -@section lint_qpc Linting the QP/C Source Code -The directory qpc/ports/lint-plus (see listing above) contains also the **lin.bat** batch file for "linting" the QP/C source code. The `lin.bat` batch file invokes PC-Lint-Plus and generates the lint output files. As shown in the listing above, the lint output is collected into four text files `lint_qf.log`, `lint_qs.log`, `lint_qk.log`, `lint_qv.log`, and `lint_qs.log`, for QEP/QF, QK, QV, QXK and QS components of the QP/C framework, respectively. - -@note -In order to execute the `lin.bat` file on your system, you might need to adjust the symbol `PCLP_DIR` at the top of the batch file, to the PC-Lint-Plus installation directory on your computer. - -@remarks -The `lin.bat` batch file invoked without any command-line options checks the QP/C code in the ::Q_SPY build configuration with software tracing enabled. However, by the nature of software tracing, the ::Q_SPY configuration transgresses many more MISRA-C rules than the standard configuration. However, the ::Q_SPY configuration is never used for production code, so the MISRA-C compliance of the QP/C framework should not be judged by the deviations that happen only in the ::Q_SPY configuration. - - -According to the PC-Lint-Plus guidelines, the `lin.bat` uses two option files: the `qpc.lnt` configuration file discussed before and the `options.lnt` configuration file that covers all deviations from the MISRA-C rules **within the QP/C source code**. These deviations are intentionally localized to QP/C code and are independent from your **application-level** code. In other words, a MISRA-C deviation present in the QP/C code does **not** mean that such deviation is somehow allowed or its detection is somehow suppressed in the **application-level** code. This is because the the `options.lnt` configuration file for internals of QP/C is **not** used to "lint" the application-level code. - - -@section lint_app Linting QP/C Application Code -The QP/C baseline code contains an example of MISRA-C compliance checking with PC-Lint-Plus: the DPP example for the EK-TM4C123GLX Cortex-M4F board, located in the directory qpc/examples/arm-cm/dpp_ek-tm4c123gxl/lint-plus. The PC-Lint-Plus analysis is very simple and requires invoking the **lin.bat** file. - -@note -In order to execute the **lin.bat** file on your system, you might need to adjust the symbol `PCLP_DIR` at the top of the batch file, to the PC-Lint-Plus installation directory on your computer. You - - -The `lint-plus` subdirectory contains also the local version of the `options.lnt` configuration file with the PC-Lint-Plus options specific to linting the application. Here, you might include linting options for your specific compiler, as described in the "PC-Lint-Plus Manual", Chapter 2 "Installation and Configuration". - - -@section lint_options Structure of PC-Lint-Plus Options for QP/C -PC-Lint-Plus has several places where it reads its currently valid options: -- From special PC-Lint-Plus option files (usually called `*.lnt`) -- From the command line -- From within the special lint-comments in the source code modules (not recommended) - -The QP/C source code and example application code has been "linted" only by means of the first alternative (option files) with possibility of adding options via command line. The third alternative--lint comments--is not used and Quantum Leaps does not recommend this alternative. - -@note -The QP/C source code is completely free of lint comments, which are viewed as a contamination of the source code. - -The structure of the PC-Lint-Plus option files used for "linting" QP/C follows the Gimpel Software guidelines for configuring PC-Lint-Plus (See Section 2 "Configuration" in the *PC-Lint-Plus Manual*). The design and grouping of the lint options also reflects the fact that static code analysis of a software framework, such as QP/C, has really two major aspects. First, the source code of the framework itself has to be analyzed. But even more important and helpful to the users of the framework is providing the infrastructure to effectively analyze the application-level code based on the framework. With this in mind, the PC-Lint-Plus options for static analysis of QP/C are divided into two groups, located in directories qpc/include and qpc/ports/lint. These two groups are for analyzing QP/C **applications** and QP/C **source code**, respectively. - -As shown in the PC-Lint-Plus "port" files description, the directory qpc/include, contains the PC-Lint-Plus options for "linting" the application code along with all platform-independent QP/C header files required by the applications. This collocation of lint options with header files simplifies "linting", because specifying just `-iqpc/include` include directory to PC-Lint-Plus accomplishes both inclusion of QP/C header files and PC-Lint-Plus options. -Note that the `qpc/include` directory contains all PC-Lint-Plus option files used in "linting" the code, including the standard MISRA-C:2012 `au-misr3.lnt` option file as well as Dan Saks' recommendations `au-ds.lnt`, which are copied from the PC-Lint-Plus distribution. This design freezes the lint options for which the compliance has been checked. - - -@subsection lint_std_lnt The std.lnt option file -According to the Gimpel Software *PC-Lint-Plus Configuration Guidelines*, the file `qpc/include/std.lnt` file, contains the top-level options, which Quantum Leaps recommends for all projects. These options include the formatting of the PC-Lint-Plus messages and making two passes to perform better cross-module analysis. However, the most important option is `-restore_at_end`, which has the effect of surrounding each source file with options `-save` and `-restore`. This precaution prevents options from "bleeding" from one file to another. - -Top-level option file std.lnt -@include std.lnt - - -@subsection lint_qpc_lnt The qpc.lnt option file -The most important file for "linting" QP/C applications is the **qpc.lnt** option file. This file handles all deviations from the MISRA-C:2012 rules, which might arise at the application-level code from the use of the QP/C framework. In other words, the **qpc.lnt** option file allows completely clean "linting" of the application-level code, as long as the application code does not violate any of the MISRA-C:2012 rules. - -At the same time, the **qpc.lnt** option file has been very carefully designed not to suppress any MISRA-C:2012 rule checking outside the very specific context of the QP/C API. In other words, the qpc.lnt option file still supports 100% of the MISRA-C:2012 rule checks that PC-Lint-Plus is capable of performing. - -@remarks -For example, for reasons explained in Section 5.10 of the "QP/C MISRA Compliance Matrix", QP/C extensively uses function-like macros, which deviates from the MISRA-C:2012 advisory Rule 4.9 and which PC-Lint-Plus checks with the warning 9026. However, instead of suppressing this warning globally (with the -e9096 directive), the qpc.lnt option file suppresses warning 9096 only for the specific QP function-like macros that are visible to the application level. So specifically, the qpc.lnt file contains directives `-esym(9026, Q_TRAN, Q_SUPER, ...)`, which suppresses the warning only for the specified macros, but does not disable checking of any other macros in the application-level code. - -@ifnot LATEX -@nav_next{ports_native} -@endif -*/ diff --git a/doxygen/ports_arm-cm.dox b/doxygen/ports_arm-cm.dox deleted file mode 100644 index a5916bdb..00000000 --- a/doxygen/ports_arm-cm.dox +++ /dev/null @@ -1,1283 +0,0 @@ -/*##########################################################################*/ -/*! @page arm-cm ARM Cortex-M - -This section describes the QP™ ports to the ARM Cortex-M processor family (Cortex M0/M0+/M3/M4/M7/M33). Three main implementation options are covered: the @subpage arm-cm_qv "cooperative, priority-based QV kernel", the @subpage arm-cm_qk "preemptive, run-to-completion QK kernel", and the @subpage arm-cm_qxk "preemptive, dual-mode blocking QXK kernel". Additionally, the use of the VFP (floating point coprocessor) in the M4F/M7/M33 CPUs is explained as well. This document assumes QP version 7.x or higher. - -@note -To focus the discussion, this section references the **GNU-ARM toolchain**, the EK-TM4C123GXL (ARM Cortex-M4F) and the Eclipse-based IDE (CCS from Texas Instruments). However, the general implementation strategy applies equally to all toolchains for ARM Cortex-M, such as **ARM-KEIL**, **IAR EWARM**, **GNU-ARM** and **TI-ARM**, which are all supported as well. The QP code downloads contain also examples for other boards, such as STM32 Nucleo, NXP mbed-1768, SilLabs Gecko and others. - - -@section arm-cm_files Directories and Files -The QP ports to ARM Cortex-M are available in the standard QP distribution. Specifically, the ARM Cortex-M ports are placed in the following directories: - -
-@code{.c} -qpc/ports/arm-cm // QP/C ports to ARM Cortex-M -+---qk // QP/C ports to QK preemptive kernel -| +---armclang // ports for ARM-CLANG (LLVM) -| | qep_port.h // QEP port -| | qf_port.h // QF ports -| | qk_port.h // QK ports -| | qk_port.c // QK port implementation -| +---gnu // ports for GNU-ARM -| | ~ ~ ~ -| +---iar // ports for IAR EWARM -| | ~ ~ ~ -+---qv // QP/C ports to QV cooperative kernel -| +---armclang // ports for ARM-CLANG (LLVM) -| | qep_port.h // QEP port -| | qf_port.h // QF ports -| | qk_port.h // QK ports -| | qk_port.c // QK port implementation -| +---gnu // ports for GNU-ARM -| | ~ ~ ~ -| +---iar // ports for IAR EWARM -| | ~ ~ ~ -+---qxk -| +---armclang // ports for ARM-CLANG (LLVM) -| | qep_port.h // QEP port -| | qf_port.h // QF ports -| | qk_port.h // QK ports -| | qk_port.c // QK port implementation -| +---gnu // ports for GNU-ARM -| | ~ ~ ~ -| +---iar // ports for IAR EWARM -| | ~ ~ ~ -@endcode - - -@section arm-cm_int Interrupts in the QP Ports to ARM Cortex-M -The QP real-time framework, like any real-time kernel, needs to disable interrupts in order to access critical sections of code and re-enable interrupts when done. This section describes the general policy used in the ARM Cortex-M ports of all built-in real time kernels in QP, such as QV, QK, and QXK. - - -@subsection arm-cm_kernel-aware "Kernel-Aware" and "Kernel-Unaware" Interrupts -The QP ports to ARMv7M or higher architectures **never completely disables interrupts**, even inside the critical sections. On ARMv7M or higher architectures, the QP port disables interrupts **selectively** using the BASEPRI register. This policy divides interrupts into "kernel-unaware" interrupts, which are never disabled, and "kernel-aware" interrupts, which are disabled in the QP critical sections. - -@note -The BASEPRI register is not implemented in the ARMv6-M architecture (Cortex-M0/M0+), so Cortex-M0/M0+ CPUs need to use the PRIMASK register to disable interrupts globally. In other words, in the QP ports to Cortex-M0/M0+, all interrupts are "kernel-aware". - - -@attention -Only "kernel-aware" interrupts are allowed to call QP services. "Kernel-unaware" interrupts are **not** allowed to call any QP services and they can communicate with QP only by triggering a "kernel-aware" interrupt (which can post or publish events). - - -As illustrated in the figures below, the number of interrupt priority bits actually available is implementation dependent, meaning that the various ARM Cortex-M silicon vendors can provide different number of priority bits, varying from just 3 bits (which is the minimum for ARMv7-M architecture) up to 8 bits. For example, the TI Tiva-C microcontrollers implement only 3 priority bits (see figure below). - - -@image html arm-cm_int3bit.png -@image latex arm-cm_int3bit.png width=5.0in -@caption{Kernel-aware and Kernel-unaware interrupts with 3 priority bits)} - - -On the other hand, the STM32 MCUs implement 4 priority bits (see figure below). The CMSIS standard provides the macro **NVIC_PRIO_BITS**, which specifies the number of NVIC priority bits defined in a given ARM Cortex-M implementation. - -@image html arm-cm_int4bit.png -@image latex arm-cm_int4bit.png width=5.0in -@caption{Kernel-aware and Kernel-unaware interrupts with 4 priority bits](arm-cm_int4bit.png} - - -Another important fact to note is that the ARM Cortex-M core stores the interrupt priority values in the *most significant bits* of its eight bit interrupt priority registers inside the NVIC (Nested Vectored Interrupt Controller). For example, if an implementation of a ARM Cortex-M microcontroller only implements three priority bits, then these three bits are shifted to occupy bits five, six and seven respectively. The unimplemented bits can be written as zero or one and always read as zero. - -And finally, the NVIC uses an inverted priority numbering scheme for interrupts, in which priority zero (0) is the highest possible priority (highest urgency) and larger priority numbers denote actually lower-priority interrupts. So for example, interrupt of priority 2 can preempt an interrupt with priority 3, but interrupt of priority 3 cannot preempt interrupt of priority 3. The default value of priority of all interrupts out of reset is zero (0). - -@note -Starting with QP 5.9.x, the QF_init() call sets interrupt priority of all IRQs to the "kernel aware" value QF_BASEPRI. Still, it is highly recommended to set the priority of all interrupts used by an application **explicitly**, preferably in the `QF_onStartup()`. - -@attention -Some 3rd-party libraries (e.g., STM32Cube) change the interrupt priorities and sometimes priority grouping internally and unexpectedly, so care must be taken to change the priorities back to the appropriate values right before running the application. - -The CMSIS provides the function `NVIC_SetPriority()` which you should use to set priority of every interrupt. - -@note -The priority scheme passed to `NVIC_SetPriority()` is different again than the values stored in the NVIC registers, as shown in the figures above as "CMSIS priorities" - - -@subsection arm-cm_int-assign Assigning Interrupt Priorities -The @ref exa_arm-cm "example projects" included in the QP distribution the recommended way of assigning interrupt priorities in your applications. The initialization consist of two steps: (1) you enumerate the "kernel-unaware" and "kernel-aware" interrupt priorities, and (2) you assign the priorities by calling the `NVIC_SetPriority()` CMSIS function. The following snippet of code illustrates these steps with the explanation section following immediately after the code. - -@caption{Listing: Assigning the interrupt priorities (see file bsp.c in the example projects)} -@code{.c} - /*!!!!!!!!!!!!!!!!!!!!!!!!!!!!! CAUTION !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - * Assign a priority to EVERY ISR explicitly by calling NVIC_SetPriority(). - * DO NOT LEAVE THE ISR PRIORITIES AT THE DEFAULT VALUE! - */ -[1] enum KernelUnawareISRs { /* see NOTE0 */ - /* ... */ -[2] MAX_KERNEL_UNAWARE_CMSIS_PRI /* keep always last */ - }; - /* "kernel-unaware" interrupts can't overlap "kernel-aware" interrupts */ -[3] Q_ASSERT_COMPILE(MAX_KERNEL_UNAWARE_CMSIS_PRI <= QF_AWARE_ISR_CMSIS_PRI); - -[4] enum KernelAwareISRs { -[5] GPIOPORTA_PRI = QF_AWARE_ISR_CMSIS_PRI, /* see NOTE00 */ - SYSTICK_PRIO, - /* ... */ -[6] MAX_KERNEL_AWARE_CMSIS_PRI /* keep always last */ - }; - /* "kernel-aware" interrupts should not overlap the PendSV priority */ -[7] Q_ASSERT_COMPILE(MAX_KERNEL_AWARE_CMSIS_PRI <= (0xFF>>(8-__NVIC_PRIO_BITS))); - - ~ ~ ~ - -[8] void QF_onStartup(void) { - /* set up the SysTick timer to fire at BSP_TICKS_PER_SEC rate */ - SysTick_Config(ROM_SysCtlClockGet() / BSP_TICKS_PER_SEC); - - /* assing all priority bits for preemption-prio. and none to sub-prio. */ -[9] NVIC_SetPriorityGrouping(0U); - - /* set priorities of ALL ISRs used in the system, see NOTE00 - * - * !!!!!!!!!!!!!!!!!!!!!!!!!!!! CAUTION !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - * Assign a priority to EVERY ISR explicitly by calling NVIC_SetPriority(). - * DO NOT LEAVE THE ISR PRIORITIES AT THE DEFAULT VALUE! - */ -[10] NVIC_SetPriority(SysTick_IRQn, SYSTICK_PRIO); -[11] NVIC_SetPriority(GPIOPortA_IRQn, GPIOPORTA_PRIO); - ~ ~ ~ - /* enable IRQs... */ -[12] NVIC_EnableIRQ(GPIOPortA_IRQn); - } -@endcode - -`[1]` The enumeration @c KernelUnawareISRs lists the priority numbers for the "kernel-unaware" interrupts. These priorities start with zero (highest possible). The priorities are suitable as the argument for the @c NVC_SetPriority() CMSIS function. - -@note -The NVIC allows you to assign the same priority level to multiple interrupts, so you can have more ISRs than priority levels running as "kernel-unaware" or "kernel-aware" interrupts. - - -`[2]` The last value in the enumeration MAX_KERNEL_UNAWARE_CMSIS_PRI keeps track of the maximum priority used for a "kernel-unaware" interrupt. - -`[3]` The compile-time assertion ensures that the "kernel-unaware" interrupt priorities do not overlap the "kernel-aware" interrupts, which start at QF_AWARE_ISR_CMSIS_PRI. - -`[4]` The enumeration KernelAwareISRs lists the priority numbers for the "kernel-aware" interrupts. - -`[5]` The "kernel-aware" interrupt priorities start with the QF_AWARE_ISR_CMSIS_PRI offset, which is provided in the qf_port.h header file. - -`[6]` The last value in the enumeration MAX_KERNEL_AWARE_CMSIS_PRI keeps track of the maximum priority used for a "kernel-aware" interrupt. - -`[7]` The compile-time assertion ensures that the "kernel-aware" interrupt priorities do not overlap the lowest priority level reserved for the PendSV exception. - -`[8]` The QF_onStartup() callback function is where you set up the interrupts. - -`[9]` This call to the CMIS function `NVIC_SetPriorityGrouping()` assigns all the priority bits to be preempt priority bits, leaving no priority bits as subpriority bits to preserve the direct relationship between the interrupt priorities and the ISR preemption rules. This is the default configuration out of reset for the ARM Cortex-M3/M4 cores, but it can be changed by some vendor-supplied startup code. To avoid any surprises, the call to `NVIC_SetPriorityGrouping(0U)` is recommended. - -`[10]` The interrupt priories fall all interrupts ("kernel-unaware" and "kernel-aware" alike) are set explicitly by calls to the CMSIS function `NVIC_SetPriority()`. - -`[11]` All used IRQ interrupts need to be explicitly enabled by calling the CMSIS function. - - -@subsection arm-cm_int-fpu Interrupts and the FPU (ARMv7M or higher architectures) -The QP ports described in this section support also the ARMv7M or higher architectures. Compared to all other members of the Cortex-M family, these cores includes the single precision variant of the ARMv7-M Floating-Point Unit (Fpv4-SP). The hardware FPU implementation adds an extra floating-point register bank consisting of S0-S31 and some other FPU registers. This FPU register set represents additional context that need to be preserved across interrupts and thread switching (e.g., in the preemptive QK kernel). - -The ARM VFP has a very interesting feature called **lazy stacking** [@ref ARM-AN298]. This feature avoids an increase of interrupt latency by skipping the stacking of floating-point registers, if not required, that is: - -- if the interrupt handler does not use the FPU, or -- if the interrupted program does not use the FPU. - -If the interrupt handler has to use the FPU and the interrupted context has also previously used by the FPU, then the stacking of floating-point registers takes place at the point in the program where the interrupt handler first uses the FPU. The lazy stacking feature is programmable and by default it is turned ON. - -@note -All built-in kernels in QP are designed to take advantage of the lazy stacking feature [@ref ARM-AN298]. - - -@section arm-cm_ref References -@anchor ARM-AN298 -- **[ARM AN298]** ARM Application Note 298 "Cortex-M4(F) Lazy Stacking and Context Switching", ARM 2012 - -@anchor ARM-EPM-064408 -- **[ARM-EPM-064408]** "ARM Processor Cortex-M7 (AT610) and Cortex-M7 with FPU (AT611) Software Developers Errata Notice" - -@anchor Reminder -- **[Reminder]** "Reminder State Pattern" - -@ifnot LATEX -@nav_next{arm-cm_qv} -@endif -*/ -/*##########################################################################*/ -/*! @page arm-cm_qv Cooperative QV Kernel - -The non-preemptive, cooperative QV kernel executes active objects one at a time, with priority-based scheduling performed after run-to-completion (RTC) processing of each event. Due to naturally short duration of event processing in state machines, the simple QV kernel is often adequate for many real-time systems. (NOTE: Long RTC steps can be often broken into shorter pieces by means of the "Reminder" state pattern [@ref Reminder]) - - -@remarks -In the QV port, the only components requiring platform-specific porting are QF and QV itself. The other two components: QEP and QS require merely recompilation and will not be discussed here. With the QV port you're not using the QK or QXK kernels. The QV port to ARM Cortex-M is located in the folder /ports/arm-cm/qv/. - - -@section arm-cm_qv-synopsis Synopsis of the QV Port on ARM Cortex-M -The cooperative QV kernel works essentially as the traditional foreground-background system (a.k.a. "superloop") in that all active objects are executed in the main loop and interrupts always return back to the point of preemption. To avoid race conditions between the main loop and the interrupts, QV briefly disables interrupts. - -1. The ARM Cortex-M processor executes application code (the main loop) in the Privileged Thread mode, which is exactly the mode entered out of reset. - -2. The exceptions (including all interrupts) are always processed in the Privileged Handler mode. - -3. QV uses only the Main Stack Pointer. The Process Stack Pointer is not used and is not initialized. - -4. ARM Cortex-M enters interrupt context without disabling interrupts (without setting the PRIMASK bit or the BASEPRI register). Generally, you should not disable interrupts inside your ISRs. In particular, the QP services QF_PUBLISH(), QF_TICK_X(), and QACTIVE_POST() should be called with **interrupts enabled**, to avoid nesting of critical sections. - -@note -If you don't wish an interrupt to be preempted by another interrupt, you can always prioritize that interrupt in the NVIC to a higher level (use a lower numerical value of priority). - -5. The `QF_init()` function calls the function `QV_init()` to set the interrupt priority of all IRQs available in the MCU to the safe value of @ref QF_BASEPRI "QF_BASEPRI" (for ARM-v7 architecture). - - -@section arm-cm_qv-qep_port The qep_port.h Header File -The QEP header file for the ARM Cortex-M port is located in `/ports/arm-cm/qv/gnu/qep_port.h`. The following shows the @c qep_port.h header file for ARM Cortex-M/GNU. The GNU-ARM compiler is a standard C99 compiler, so it simply includes the @c header file that defines the platform-specific exact-with integer types. - -@anchor arm-cm_qv_qep_port-code -@caption{Listing: The qep_port.h header file for ARM Cortex-M} -@code{.c} - #include /* Exact-width types. WG14/N843 C99 Standard */ - #include /* Boolean type. WG14/N843 C99 Standard */ - #include "qep.h" /* QEP platform-independent public interface */ -@endcode - -@remark -If you use a pre-C99 compiler (e.g., a C89 compiler), you can provide the @c stdint.h and `stdbool.h` header files yourself, or you can define the standard integer types and Boolean types directly in the `qep_port.h` header file. - - -@section arm-cm_qv-qf_port The qf_port.h Header File -The QF header file for the ARM Cortex-M port is located in `/ports/arm-cm/qv/gnu/qf_port.h`. This file specifies the interrupt disabling policy (QF critical section) as well as the configuration constants for QF (see Chapter 8 in [PSiCC2]). - -@note -The ARM Cortex-M allows you to use the simplest "unconditional interrupt disabling"� policy (see Section 7.3.2 in [PSiCC2]), because ARM Cortex-M is equipped with the standard nested vectored interrupt controller (NVIC) and generally runs ISRs with interrupts enabled (so the body of an ISR is not a critical section). - -The following listing shows the `qf_port.h` header file for ARM Cortex-M with the GNU-ARM toolchain. Other toolchains use slightly different conditional compilation macros to select the Cortex-M variants, but implement the same policies. - -@anchor arm-cm_qf_port_h-code -@caption{Listing: The qf_port.h header file for ARM Cortex-M} -@code{.c} - /* The maximum number of active objects in the application, see NOTE1 */ - [1] #define QF_MAX_ACTIVE 32 - - /* The maximum number of system clock tick rates */ - [2] #define QF_MAX_TICK_RATE 2 - - /* QF interrupt disable/enable and log2()... */ - [3] #if (__ARM_ARCH == 6) /* Cortex-M0/M0+/M1(v6-M, v6S-M)? */ - - /* Cortex-M0/M0+/M1(v6-M, v6S-M) interrupt disabling policy, see NOTE2 */ - [4] #define QF_INT_DISABLE() __asm volatile ("cpsid i") - [5] #define QF_INT_ENABLE() __asm volatile ("cpsie i") - - /* QF critical section entry/exit (unconditional interrupt disabling) */ - [6] /*#define QF_CRIT_STAT_TYPE not defined */ - [7] #define QF_CRIT_ENTRY(dummy) QF_INT_DISABLE() - [8] #define QF_CRIT_EXIT(dummy) QF_INT_ENABLE() - - /* CMSIS threshold for "QF-aware" interrupts, see NOTE2 and NOTE5 */ - [9] #define QF_AWARE_ISR_CMSIS_PRI 0 - - /* hand-optimized LOG2 in assembly for Cortex-M0/M0+/M1(v6-M, v6S-M) */ -[10] #define QF_LOG2(n_) QF_qlog2((n_)) - -[11] #else /* Cortex-M3/M4/M7 */ - - /* Cortex-M3/M4/M7 alternative interrupt disabling with PRIMASK */ -[12] #define QF_PRIMASK_DISABLE() __asm volatile ("cpsid i") -[13] #define QF_PRIMASK_ENABLE() __asm volatile ("cpsie i") - - /* Cortex-M3/M4/M7 interrupt disabling policy, see NOTE3 and NOTE4 */ -[14] #define QF_INT_DISABLE() __asm volatile (\ - "cpsid i\n" "msr BASEPRI,%0\n" "cpsie i" :: "r" (QF_BASEPRI) : ) -[15] #define QF_INT_ENABLE() __asm volatile (\ - "msr BASEPRI,%0" :: "r" (0) : ) - - /* QF critical section entry/exit (unconditional interrupt disabling) */ -[16] /*#define QF_CRIT_STAT_TYPE not defined */ -[17] #define QF_CRIT_ENTRY(dummy) QF_INT_DISABLE() -[18] #define QF_CRIT_EXIT(dummy) QF_INT_ENABLE() - - /* BASEPRI threshold for "QF-aware" interrupts, see NOTE3 */ -[19] #define QF_BASEPRI 0x3F - - /* CMSIS threshold for "QF-aware" interrupts, see NOTE5 */ -[20] #define QF_AWARE_ISR_CMSIS_PRI (QF_BASEPRI >> (8 - __NVIC_PRIO_BITS)) - - /* Cortex-M3/M4/M7 provide the CLZ instruction for fast LOG2 */ -[21] #define QF_LOG2(n_) ((uint_fast8_t)(32U - __builtin_clz(n_))) - - #endif - -[22] #define QF_CRIT_EXIT_NOP() __asm volatile ("isb") - - #include "qep_port.h" /* QEP port */ - - #if (__ARM_ARCH == 6) /* Cortex-M0/M0+/M1(v6-M, v6S-M)? */ - /* hand-optimized quick LOG2 in assembly */ -[23] uint_fast8_t QF_qlog2(uint32_t x); - #endif /* Cortex-M0/M0+/M1(v6-M, v6S-M) */ - - #include "qv_port.h" /* QV port cooperative kernel port */ - #include "qf.h" /* QF platform-independent public interface */ -@endcode - - -`[1]` The #QF_MAX_ACTIVE specifies the maximum number of active object priorities in the application. You always need to provide this constant. Here, #QF_MAX_ACTIVE is set to 32, but it can be increased up to the maximum limit of 63 active object priorities in the system. - -@note -The `qf_port.h` header file does not change the default settings for all the rest of various object sizes inside QF. Please refer to Chapter 8 of [PSiCC2] for discussion of all configurable QF parameters. - - -`[2]` The macro `QF_MAX_TICK_RATE` specifies the maximum number of clock tick rates for QP time events. If you do not need to specify this limit, in which case the default of a single clock rate will be chosen. - -`[3]` As described in the previous @ref arm-cm_int "Section", the interrupt disabling policy for the ARMv6-M architecture (Cortex-M0/M0+) is different than the policy for the ARMv7-M. In GNU-ARM, the macro `__ARM_ARCH` is defined as 6 for the ARMv6-M architecture (Cortex-M0/M0+), and 7 for ARMv7-M (Cortex-M3/M4/M4F). - -@note -The `__ARM_ARCH` macro is specific to the GNU-ARM compiler. Other compilers for ARM Cortex-M provide different macros to detect the CPU type. - - -`[4-5]` For the ARMv6-M architecture, the interrupt disabling policy uses the PRIMASK register to disable interrupts globally. The @c QF_INT_DISABLE() macro resolves in this case to the inline assembly instruction "CPSD i", which sets the PRIMASK. The @c QF_INT_ENABLE() macro resolves to the inline assembly instruction "CPSE i", which clears the PRIMASK. - -`[6]` The #QF_CRIT_STAT_TYPE is **NOT** defined, meaning that the critical section uses the simple policy of "unconditional interrupt disablin". - -@note -The "unconditional interrupt disabling" policy precludes nesting of critical sections, but this is not needed for ARM Cortex-M, because this CPU never disables interrupts, even when handling exceptions/interrupts. - - -`[7]` The QF_CRIT_ENTRY() enters a critical section. Interrupts are disabled by setting the PRIMASK register. - -`[8]` The QF_CRIT_EXIT() macro leaves the critical section. Interrupts are unconditionally re-enabled by clearing the PRIMASK register. - -`[9]` For the ARMv6-M architecture, the `QF_AWARE_ISR_CMSIS_PRI` priority level is defined as zero, meaning that all interrupts are "kernel-aware", because all interrupt priorities are disabled by the kernel. - -`[10]` The `QF_LOG2()` macro is defined as a call to the function `QF_qlog2()` ("quick log-base-2 logarithm"). This function is coded in hand-optimized assembly, which always takes only 14 CPU cycles to execute (see also label [23]). - -@note -ARM Cortex-M0/M0+ does NOT implement the `CLZ` instruction. Therefore the log-base-2 calculation cannot be accelerated in hardware, as it is for ARM Cortex-M3 and higher. - - -`[11]` For the ARMv7-M (Cortex-M3/M4/M4F) architecture... - -`[12]` The `QF_PRIMASK_DISABLE()` macro resolves to the inline assembly instruction `CPSD i`, which sets the PRIMASK. - -`[13]` The `QF_PRIMASK_ENABLE()` macro resolves to the inline assembly instruction `CPSE i`, which clears the PRIMASK. - -`[14]` Interrupts are disabled by setting the BASEPRI register to the value defined in the `QF_BASEPRI` macro (see label `[19]`). This setting of the BASEPRI instruction `msr BASEPRI,...` is surrounded by setting and clearing the PRIMASK register, as a workaround a hardware problem in ARMv7M or higher architectures core r0p1: - -@note -The selective disabling of "QF-aware" interrupts with the BASEPRI register has a problem on ARMv7M or higher architectures core r0p1 (see [@ref ARM-EPM-064408], Erratum 837070). The workaround recommended by ARM is to surround `MSR BASEPRI,...` with the `CPSID i`/`CPSIE i` pair, which is implemented in the QF_INT_DISABLE() macro. This workaround works also for Cortex-M3/M4 cores. - - -`[15]` The `QF_INT_ENABLE()` macro sets the BASEPRI register to zero, which disables BASEPRI interrupt masking. - -@note -This method can never disable interrupt of priority 0 (highest). - - -`[16]` The #QF_CRIT_STAT_TYPE is **NOT** defined, meaning that the critical section uses the simple policy of "unconditional interrupt disabling". - -@note -The "unconditional interrupt disabling" policy precludes nesting of critical sections, but this is not needed for ARM Cortex-M, because this CPU never disables interrupts, even when handling exceptions/interrupts. - - -`[17]` The QF_CRIT_ENTRY() enters a critical section. Interrupts are disabled with the macro `QF_INT_DISABLE()` defined at label [12]. - -`[18]` The QF_CRIT_EXIT() macro leaves the critical section. Interrupts are unconditionally re-enabled with the macro `QF_INT_ENABLE()` defined at label [13]. - - @anchor QF_BASEPRI -`[19]` -The `QF_BASEPRI` value is defined such that it is the lowest priority for the minimum number of 3 priority-bits that the ARMv7M or higher architectures architecture must provide. This partitions the interrupts as "kernel-unaware" and "kernel-aware" interrupts, as shown in section @ref arm-cm_int-assign. - -`[20]` For the ARMv7-M architecture, the `QF_AWARE_ISR_CMSIS_PRI` priority level suitable for the CMSIS function `NVIC_SetPriority()` is determined by the `QF_BASEPRI` value. - -`[21]` The macro `QF_LOG2()` is defined to take advantage of the CLZ instruction (Count Leading Zeroes), which is available in the ARMv7-M architecture. - -@note -The `__builtin_cls()` intrinsic function is specific to the GNU-ARM compiler. Other compilers for ARM Cortex-M use different function names for this intrinsic function. - - -`[22]` The macro @c QF_CRIT_EXIT_NOP() provides the protection against merging two critical sections occurring back-to-back in the QP code. - -`[23]` For ARMv6 architecture, the prototype of the quick, hand-optimized log-base-2 function is provided (see also label [10]). - - -@section arm-cm_qv_port_h The qv_port.h Header File -The QV header file for the ARM Cortex-M port is located in /ports/arm-cm/qv/gnu/qv_port.h. This file provides the macro QV_CPU_SLEEP(), which specifies how to enter the CPU sleep mode safely in the cooperative QV kernel (see also Section 4.7) and [Samek 07]). - -@note -To avoid race conditions between interrupts waking up active objects and going to sleep, the cooperative QV kernel calls the QV_CPU_SLEEP() callback with interrupts disabled. - - -@anchor arm-cm_qv_port_h-code -@caption{Listing: The qv_port.h header file for ARM Cortex-M} -@code{.c} - #ifdef ARM_ARCH_V6M /* Cortex-M0/M0+/M1 ? */ - - [1] #define QV_CPU_SLEEP() do { \ - __asm volatile ("wfi"); \ - QF_INT_ENABLE(); \ - } while (0) - - #else /* Cortex-M3/M4/M7 */ - - [2] #define QV_CPU_SLEEP() do { \ - QF_PRIMASK_DISABLE(); \ - QF_INT_ENABLE(); \ - __asm volatile ("wfi"); \ - QF_RIMASK_ENABLE(); \ - } while (0) - - #endif - - [3] #define QV_INIT() QV_init() - void QV_init(); - - #include "qv.h" /* QV platform-independent public interface */ -@endcode - - -`[1]` For the ARMv6-M architecture, the macro `QV_CPU_SLEEP()` stops the CPU with the WFI instruction (Wait For Interrupt). After the CPU is woken up by an interrupt, interrupts are re-enabled with the PRIMASK. - -`[2]` For the ARMv7-M architecture, the macro `QV_CPU_SLEEP()` first disables interrupts by setting the PRIMASK, then clears the BASEPRI to enable all "kernel-aware" interrupts and only then stops the CPU with the WFI instruction (Wait For Interrupt). After the CPU is woken up by an interrupt, interrupts are re-enabled with the PRIMASK. This sequence is necessary, because the ARMv7M or higher architectures cannot be woken up by any interrupt blocked by the BASEPRI register. - -`[3]` The macro `QV_INIT()` is defined as a call to the `QV_init()` function, which means that this function will be called from `QF_init()`. The `QV_init()` function initializes all available IRQ priorities in the MCU to the safe value of @ref QF_BASEPRI "QF_BASEPRI". - - -@section arm-cm_qv_port_c The qv_port.c Implementation File -The QV implementation file for the ARM Cortex-M port is located in /ports/arm-cm/qv/gnu/qf_port.c. This file defines the function `QV_init()`, which for the ARMv7-M architecture sets the interrupt priorities of all IRQs to the safe value @ref QF_BASEPRI "QF_BASEPRI". - -@anchor arm-cm_qv_port_c-code -@caption{Listing: The qv_port.c header file for ARM Cortex-M} -@code{.c} - #include "qf_port.h" - - [1] #if (__ARM_ARCH != 6) /* NOT Cortex-M0/M0+/M1 ? */ - - #define SCnSCB_ICTR ((uint32_t volatile *)0xE000E004) - #define SCB_SYSPRI ((uint32_t volatile *)0xE000ED14) - #define NVIC_IP ((uint32_t volatile *)0xE000E400) - - void QV_init(void) { - uint32_t n; - - /* set exception priorities to QF_BASEPRI... - * SCB_SYSPRI1: Usage-fault, Bus-fault, Memory-fault - */ - [2] SCB_SYSPRI[1] |= (QF_BASEPRI << 16) | (QF_BASEPRI << 8) | QF_BASEPRI; - - /* SCB_SYSPRI2: SVCall */ - [3] SCB_SYSPRI[2] |= (QF_BASEPRI << 24); - - /* SCB_SYSPRI3: SysTick, PendSV, Debug */ - [4] SCB_SYSPRI[3] |= (QF_BASEPRI << 24) | (QF_BASEPRI << 16) | QF_BASEPRI; - - /* set all implemented IRQ priories to QF_BASEPRI... */ - [5] n = 8 + (*SCnSCB_ICTR << 3); /* # interrupt priority registers */ - do { - --n; - [6] NVIC_IP[n] = (QF_BASEPRI << 24) | (QF_BASEPRI << 16) - | (QF_BASEPRI << 8) | QF_BASEPRI; - } while (n != 0); - } - - #endif /* NOT Cortex-M0/M0+/M1 */ -@endcode - - -`[1]` For the ARMv7-M architecture (Cortex-M3/M4/M7)... - -`[2]` The exception priorities for User-Fault, Bus-Fault, and Mem-Fault are set to the value @ref QF_BASEPRI "QF_BASEPRI". - -`[3]` The exception priority for SVCCall is set to the value @ref QF_BASEPRI "QF_BASEPRI". - -`[4]` The exception priority for SysTick, PendSV, and Debug is set to the value @ref QF_BASEPRI "QF_BASEPRI". - -`[5]` The number of implemented IRQs is read from the @c SCnSCB_ICTR register - -`[6]` The interrupt priority of all implemented IRQs is set to the safe value @ref QF_BASEPRI "QF_BASEPRI" in a loop. - - -@section arm-cm_qv-isr Writing ISRs for QV -The ARM Cortex-M CPU is designed to use regular C functions as exception and interrupt service routines (ISRs). - -@note -The ARM EABI (Embedded Application Binary Interface) requires the stack be 8-byte aligned, whereas some compilers guarantee only 4-byte alignment. For that reason, some compilers (e.g., GNU-ARM) provide a way to designate ISR functions as interrupts. For example, the GNU-ARM compiler provides the __attribute__((__interrupt__)) designation that will guarantee the 8-byte stack alignment. - - -Typically, ISRs are application-specific (with the main purpose to produce events for active objects). Therefore, ISRs are not part of the generic QP port, but rather part of the BSP (Board Support Package). - -The following listing shows an example of the SysTick_Handler() ISR (from the DPP example application). This ISR calls the QF_TICK_X() macro to perform QF time-event management. - -@anchor arm-cm_qv-isr-code -@caption{Listing: An ISR header for QV} -@code{.c} - void SysTick_Handler(void) __attribute__((__interrupt__)); - void SysTick_Handler(void) { - ~ ~ ~ - QF_TICK_X(0U, &l_SysTick_Handler); /* process all armed time events */ - } -@endcode - -@note -The QP port to ARM Cortex-M complies with the CMSIS standard, which dictates the names of all exception handlers and IRQ handlers. - - -@section arm-cm_qv-fpu Using the FPU in the QV Port - -If you use ARMv7M or higher CPU and your application uses the hardware FPU, it should be enabled because it is turned off out of reset. The CMSIS-compliant way of turning the FPU on looks as follows: - -@verbatim - SCB->CPACR |= (0xFU << 20); -@endverbatim - -@note -The FPU must be enabled before executing any floating point instruction. An attempt to execute a floating point instruction will fault if the FPU is not enabled. - -@note -If the FPU is configured in the project, the QV kernel initializes the FPU to use the automatic state preservation and the lazy stacking feature as follows: -@verbatim - FPU->FPCCR |= (1U << FPU_FPCCR_ASPEN_Pos) | (1U << FPU_FPCCR_LSPEN_Pos); -@endverbatim - - -@subsection arm-cm_qv-fpu_noisr FPU NOT used in the ISRs -If you use the FPU only at the thread-level (inside active objects) and none of your ISRs use the FPU, you can setup the FPU not to use the automatic state preservation and not to use the lazy stacking feature as follows: - -@verbatim - FPU->FPCCR &= ~((1U << FPU_FPCCR_ASPEN_Pos) | (1U << FPU_FPCCR_LSPEN_Pos)); -@endverbatim - -With this setting, the processor uses only the standard 8-register interrupt stack frame with R0-R3,R12,LR,PC,xPSR. This scheme is the fastest and incurs no additional CPU cycles to save and restore the FPU registers. - -@attention -This FPU setting will lead to FPU errors, if any of the ISRs indeed starts to use the FPU - - -@section arm-cm_qv-idle QV Idle Processing Customization in QV_onIdle() -When no events are available, the non-preemptive QV kernel invokes the platform-specific callback function QV_onIdle(), which you can use to save CPU power, or perform any other "idle" processing (such as Quantum Spy software trace output). - -@note -The idle callback QV_onIdle() must be invoked with interrupts disabled, because the idle condition can be changed by any interrupt that posts events to event queues. QV_onIdle() must internally enable interrupts, ideally atomically with putting the CPU to the power-saving mode (see also [Samek 07] and Chapter 7 in [PSiCC2]). - - -Because QV_onIdle() must enable interrupts internally, the signature of the function depends on the interrupt locking policy. In case of the simple "unconditional interrupt locking and unlocking" policy, which is used in this ARM Cortex-M port, the QV_onIdle() takes no parameters. Listing 6 shows an example implementation of QV_onIdle() for the TM4C MCU. Other ARM Cortex-M embedded microcontrollers (e.g., NXP’s LPC1114/1343) handle the power-saving mode very similarly. - -@anchor arm-cm_qv_onidle-code -@caption{Listing: QV_onIdle() for ARM Cortex-M} -@code{.c} - [1] void QV_onIdle(void) { /* entered with interrupts DISABLED, see NOTE01 */ - ~ ~ ~ - [2] #if defined NDEBUG - /* Put the CPU and peripherals to the low-power mode */ - [3] QV_CPU_SLEEP(); /* atomically go to sleep and enable interrupts */ - #else - [4] QF_INT_ENABLE(); /* just enable interrupts */ - #endif - } -@endcode - -`[1]` The cooperative QV kernel calls the QV_onIdle() callback with interrupts disabled, to avoid race condition with interrupts that can post events to active objects and thus invalidate the idle condition. - -`[2]` The sleep mode is used only in the non-debug configuration, because sleep mode stops CPU clock, which can interfere with debugging. - -`[3]` The macro QV_CPU_SLEEP() is used to put the CPU to the low-power sleep mode safely. The macro QV_CPU_SLEEP() is defined in the qv_port.h header file for the QV kernel and depends on the interrupt disabling policy used. - -`[4]` When a sleep mode is not used, the QV_onIdle() callback simply re-enables interrupts. - - -@ifnot LATEX -@nav_next{arm-cm_qk} -@endif -*/ -/*##########################################################################*/ -/*! @page arm-cm_qk Preemptive Non-Blocking QK Kernel - -

The @ref srs_qk "preemptive, non-blocking QK kernel" is specifically designed to execute non-blocking active objects. QK runs active objects in the same way as prioritized interrupt controller (such as NVIC in ARM Cortex-M) runs interrupts using the **single stack** (MSP on Cortex-M). This section explains how the @ref srs_qk "preemptive non-blocking QK kernel" works on ARM Cortex-M. -

- -@remarks -In a QK port, the only components requiring platform-specific porting are QF and QV itself. The other two components: QEP and QS require merely recompilation and will not be discussed here. With the QV port you're not using the QV or QXK kernels. The QK port to ARM Cortex-M is located in the folder /ports/arm-cm/qk/. - - -@section arm-cm_qk-synopsis Synopsis of the QK Port on ARM Cortex-M -The ARM Cortex-M architecture is designed primarily for the traditional real-time kernels that use multiple per-thread stacks. Therefore, implementation of the non-blocking, single-stack kernel like QK is a bit more involved on Cortex-M than other CPUs and works as follows: - -- The ARM Cortex-M processor executes the QK application code (active objects) in the Privileged Thread mode, which is exactly the mode entered out of reset. The exceptions (including all interrupts) are always processed in the Privileged Handler mode. - -- QK uses only the Main Stack Pointer (QK is a single stack kernel). The Process Stack Pointer is not used and is not initialized. - -- ARM Cortex-M enters interrupt context without disabling interrupts (without setting the PRIMASK bit or the BASEPRI register). Generally, you should not disable interrupts inside your ISRs. In particular, the QP services QF_PUBLISH(), QF_TICK_X(), and QACTIVE_POST() should be called with interrupts enabled, to avoid nesting of critical sections. (NOTE: If you don’t wish an interrupt to be preempted by another interrupt, you can always prioritize that interrupt in the NVIC to a higher level -- use a lower numerical value of priority). - -- The QK port uses the PendSV exception (number 14) to perform asynchronous preemption (see Chapter 10 in @webref{psicc2, PSiCC2}). The startup code must initialize the Interrupt Vector Table with the addresses of @c PendSV_Handler() exception handler. - -@note -QK uses only the CMSIS-compliant exception and interrupt names, such as `PendSV_Handler` - -- The QK port uses the NMI exception (number 2) or any unused IRQ interrupt to *return* to the preempted thread (see Chapter 10 in @webref{psicc2, PSiCC2}). The startup code must initialize the Interrupt Vector Table with the addresses of `NMI_Handler()` and `__IRQHandler()` exception handlers. - -@note -In case the NMI exception is needed for something else, the QK allows the developers to configure any otherwise unused IRQ to be used instead. This is accomplished by the pair of macros: `QK_USE_IRQ_NUM` and `QK_USE_IRQ_HANDLER`. - -@note -The QK port specifically does **not** use the SVC exception (Supervisor Call). This makes the QK ports compatible with various "hypervisors" (such as mbed uVisor or Nordic SoftDevice), which use the SVC exception. - -- The QF_init() function calls the function QK_init() to set the priority of the PendSV exception to the lowest level in the whole system (0xFF). The function QK_init() additionally sets the interrupt priority of all IRQs available in the MCU to the safe value of @ref QF_BASEPRI "QF_BASEPRI" (for ARM-v7 architecture). - -- It is strongly recommended that you do not assign the lowest priority (0xFF) to any interrupt in your application. With 3 MSB-bits of priority, this leaves the following 7 priority levels for you (listed from the lowest to the highest urgency): 0xC0, 0xA0, 0x80, 0x60, 0x40, 0x20, and 0x00 (the highest priority). - -- Before returning, every "kernel aware" ISR must check whether an active object has been activated that has a higher priority than the currently running active object. If this is the case, the ISR must set the PensSV pending flag in the NVIC. All this is accomplished in the macro QK_ISR_EXIT(), which must be called just before exiting every ISRs. - -- In ARM Cortex-M the whole prioritization of interrupts, including the PendSV exception, is performed entirely by the NVIC. Because the PendSV has the lowest priority in the system, the NVIC tail-chains to the PendSV exception only after exiting the last nested interrupt. - -- The pushing of the 8 registers comprising the ARM Cortex-M interrupt stack frame upon entry to the to the preempted thread (NMI or IRQ) is wasteful in a single-stack kernel, but is necessary to perform full interrupt return to the preempted context through the exception return. - - -@subsection arm-cm_qk-preempt Preemption Scenarios in QK on ARM Cortex-M - -@anchor arm-cm_qk-arm-cm-fig - -@image html qk_arm-cm.png -@image latex qk_arm-cm.png width=5.0in -@caption{Several preemption scenarios in QK} - -`[0]` The timeline begins with the QK executing the idle loop. - -`[1]` At some point an interrupt occurs and the CPU immediately suspends the idle loop, pushes the interrupt stack frame to the Main Stack and starts executing the ISR. - -`[2]` The ISR performs its work, and in QK always must call the QK_ISR_EXIT() macro, which calls the QK scheduler (QK_sched()) to determine if there is a higher-priority AO to run. If so, the macro sets the pending flag for the PendSV exception in the NVIC. The priority of the PendSV exception is configured to be the lowest of all exceptions (0xFF), so the ISR continues executing and PendSV exception remains pending. At the ISR return, the ARM Cortex-M CPU performs tail-chaining to the pending PendSV exception. - -`[3]` The PendSV exception synthesize an exception stack frame to return to the QK "activator" (QK_activate_()) to run this new thread. - -@note -The QK activator must run in the thread context, while PendSV executes in the exception context. The change of the context is accomplished by returning from the PendSV exception directly to the QK "activator". - -To return directly to the QK activator, PendSV synthesizes an exception stack frame, which contains the exception return address set to QK_activate_(). The QK activator activates the Low-priority thread (discovered by the QK scheduler QK_sched()). The QK activator enables interrupts and launches the Low-priority thread, which is simply a C-function call in QK. The Low-priority thread (active object) starts running. - -`[4]` Some time later a low-priority interrupt occurs. The Low-priority thread is suspended and the CPU pushes the interrupt stack frame to the Main Stack and starts executing the ISR. - -`[5]` Before the Low-priority ISR completes, it too gets preempted by a High-priority ISR. The CPU pushes another interrupt stack frame and starts executing the High-priority ISR. - -`[6]` The High-priority ISR sets the pending flag for the PendSV exception by means of the QK_ISR_EXIT() macro. When the High-priority ISR returns, the NVIC does not tail-chain to the PendSV exception, because a higher-priority ISR than PendSV is still active. The NVIC performs an exception return to the preempted Low-priority interrupt, which finally completes. - -`[7]` Upon the exit from the Low-priority ISR, it too sets the pending flag for the PendSV exception by means of the QK_ISR_EXIT() macro. The PendSV is already pended from the High-priority interrupt, so pending is again is redundant, but it is not an error. At the ISR return, the ARM Cortex-M CPU performs tail-chaining to the pending PendSV exception. - -`[8]` The PendSV exception synthesizes an interrupt stack frame to return to the QK activator. The QK activator detects that the High-priority thread is ready to run and launches the High-priority thread (normal C-function call). The High-priority thread runs to completion and returns to the activator. - -`[9]` The QK activator does not find any more higher-priority threads to execute and needs to return to the preempted thread. The only way to restore the interrupted context in ARM Cortex-M is through the interrupt return, but the thread is executing outside of the interrupt context (in fact, threads are executing in the Privileged Thread mode). The thread enters the Handler mode by pending the NMI or IRQ exception. - -`[10]` The only job of the NMI or IRQ exception is to discard its own interrupt stack frame, re-enable interrupts, and return using the interrupt stack frame that has been on the stack from the moment of thread preemption. - -`[11]` The Low-priority thread, which has been preempted all that time, resumes and finally runs to completion and returns to the QK activator. The QK activaotr does not find any more threads to launch and causes the NMI or IRQ exception to return to the preempted thread. - -`[12]` The NMI or IRQ exception discards its own interrupt stack frame and returns using the interrupt stack frame from the preempted thread context - - -@section arm-cm_qk-qf_port The qf_port.h Header File -The QF header file for the ARM Cortex-M port is located in /ports/arm-cm/qk/gnu/qf_port.h. This file is almost identical to the @ref arm-cm_qv-qf_port "QV port", except the header file in the QK port includes `qk_port.h` header file instead of `qv_porth`. The most important function of qk_port.h is specifying interrupt entry and exit. - -@note -As any preemptive kernel, QK needs to be notified about entering the interrupt context and about exiting an interrupt context in order to perform a context switch, if necessary. - - -@anchor arm-cm_qk_port-code -@caption{Listing: qk_port.h header file for ARM Cortex-M} -@code{.c} - /* determination if the code executes in the ISR context */ - [1] #define QK_ISR_CONTEXT_() (QK_get_IPSR() != (uint32_t)0) - - __attribute__((always_inline)) - [2] static inline uint32_t QK_get_IPSR(void) { - uint32_t regIPSR; - __asm volatile ("mrs %0,ipsr" : "=r" (regIPSR)); - return regIPSR; - } - - /* QK interrupt entry and exit */ - [3] #define QK_ISR_ENTRY() ((void)0) - - [4] #define QK_ISR_EXIT() do { \ - [5] QF_INT_DISABLE(); \ - [6] if (QK_sched_() != (uint_fast8_t)0) { \ - [7] (*Q_UINT2PTR_CAST(uint32_t, 0xE000ED04U) = (uint32_t)(1U << 28)); \ - } \ - [8] QF_INT_ENABLE(); \ - } while (0) - - /* initialization of the QK kernel */ - [9] #define QK_INIT() QK_init() - void QK_init(void); - - #include "qk.h" /* QK platform-independent public interface */ -@endcode - -`[1]` The macro @c QK_ISR_CONTEXT() returns true when the code executes in the ISR context and false otherwise. The macro takes advantage of the ARM Cortex-M register IPSR, which is non-zero when the CPU executes an exception (or interrupt) and is zero when the CPU is executing thread code. - -@note -QK needs to distinguish between ISR and thread contexts, because threads need to perform synchronous context switch (when a higher-priority thread becomes ready to run), while ISRs should not do that. - -`[2]` The inline function @c QK_get_IPSR() obtains the IPSR register and returns it to the caller. This function is defined explicitly for the GNU-ARM toolchain, but many other toolchains provide this function as an intrinsic, built-in facility. - -`[3]` The @c QK_ISR_ENTRY() macro notifies QK about entering an ISR. The macro is empty, because the determination of the ISR vs thread context is performed independently in the @c QK_ISR_CONTEXT() macro (see above). - -`[4]` The QK_ISR_EXIT() macro notifies QK about exiting an ISR. - -`[5]` Interrupts are disabled before calling QK scheduler. - -`[6]` The QK scheduler is called to find out whether an active object of a higher priority than the current one needs activation. The QK_sched_() function returns non zero value if this is the case. - -`[7]` If asynchronous preemption becomes necessary, the code sets the PENDSV Pend bit(28) in the ICSR register (Interrupt Control and State Register). The register is mapped at address 0xE000ED04 in all ARM Cortex-M cores. - -`[8]` The interrupts are re-enabled after they have been disabled in step `[5]`. - -@note -Because the priority of the PendSV exception is the lowest of all interrupts, it is actually triggered only after all nested interrupts exit. The PendSV exception is then entered through the efficient **tail-chaining** process, which eliminates the restoring and re-entering the interrupt context. - - -@section arm-cm_qk-qk_impl QK Port Implementation for ARM Cortex-M -The QK port to ARM Cortex-M requires coding the PendSV and NMI or IRQ exceptions in assembly. This ARM Cortex-M-specific code, as well as QK initialization (@c QK_init()) is located in the file ­ports/arm-cm/­qk/­gnu/qk_port.c - -@note -The single assembly module `qk_port.s` contains common code for all Cortex-M variants (Architecture v6M and v7M) as well as options with and without the VFP. The CPU variants are distinguished by conditional compilation, when necessary. - - -@subsection arm-cm_qk_port-asm_init QK_init() Implementation -@caption{Listing: QK_init() function in qk_port.c file} -@code{.c} - [1] void QK_init(void) { - [2] #if (__ARM_ARCH != 6) /* NOT Cortex-M0/M0+/M1 (v6-M, v6S-M)? */ - /* set exception priorities to QF_BASEPRI... - * SCB_SYSPRI1: Usage-fault, Bus-fault, Memory-fault - */ - [3] SCB_SYSPRI[1] |= (QF_BASEPRI << 16) | (QF_BASEPRI << 8) | QF_BASEPRI; - - /* SCB_SYSPRI2: SVCall */ - [4] SCB_SYSPRI[2] |= (QF_BASEPRI << 24); - - /* SCB_SYSPRI3: SysTick, PendSV, Debug */ - [5] SCB_SYSPRI[3] |= (QF_BASEPRI << 24) | (QF_BASEPRI << 16) | QF_BASEPRI; - - /* set all implemented IRQ priories to QF_BASEPRI... */ - [6] uint8_t nprio = (8U + ((*SCnSCB_ICTR & 0x7U) << 3U))*4; - for (uint8_t n = 0U; n < nprio; ++n) { - [7] NVIC_IP[n] = QF_BASEPRI; - } - - #endif /* NOT Cortex-M0/M0+/M1(v6-M, v6S-M) */ - - /* SCB_SYSPRI3: PendSV set to the lowest priority 0xFF */ - [8] SCB_SYSPRI[3] |= (0xFFU << 16); - - #ifdef QK_USE_IRQ_NUM - /* The QK port is configured to use a given ARM Cortex-M IRQ # - * to return to thread mode (default is to use the NMI exception) - */ - [9] NVIC_IP[QK_USE_IRQ_NUM] = 0U; /* priority 0 (highest) */ -[10] NVIC_EN[QK_USE_IRQ_NUM / 32U] = (1U << (QK_USE_IRQ_NUM % 32U)); - #endif - } -@endcode - - -`[1]` The QK_init() function is called from QF_init() to perform initialization specific to the QK kernel. - -`[2]` If the ARM Architecture is NOT v6 (Cortex-M0/M0+), that is for ARMv7M or higher architectures, the function initializes the exception priorities of PendSV and NMI as well as interrupt priorities of all IRQs available in a given MCU. (NOTE: for Cortex-M0/M0+, this initialization is not needed, as the CPU does not support the BASEPRI register and the only way to disable interrupts is via the PRIMASK register. In this case, all interrupts are "kernel-aware" and there is no need to initialize interrupt priorities to a safe value. - -`[3]` Exception priorities of Usage-fault, Bus-fault, and Memory-fault are set to @ref QF_BASEPRI "QF_BASEPRI". - -`[4]` Exception priorities of SVCall is set to @ref QF_BASEPRI "QF_BASEPRI". - -`[5]` Exception priorities of SysTick, PendSV and Debug are set to @ref QF_BASEPRI "QF_BASEPRI". - -@note -The exception priority of PedSV is later changed to 0xFF in step [8] - - -`[6]` The number of implemented interrupts is extraced fom SCnSCB_ICTR register. - -`[7]` Exception priorities of all implemented interrupts are set to @ref QF_BASEPRI "QF_BASEPRI". - -`[8]` Exception priority of PendSV is set to 0xFF, which is the lowest interrupt priority in the system. - -`[9]` In case a regular IRQ is configured for returning to the thread mode, the priority of the IRQ is set to zero (highest). - -`[10]` In case a regular IRQ is configured for returning to the thread mode, the IRQ is enabled in the NVIC. - - -@subsection arm-cm_qk_port-asm_pendsv PendSV_Handler() Implementation -@caption{Listing: PendSV_Handler() and Thread_ret() functions in qk_port.c file} -@code{.c} - [1] __attribute__ ((naked)) - [2] void PendSV_Handler(void) { - [3] __asm volatile ( - - /* Prepare constants in registers before entering critical section */ - [4] " LDR r3,=" STRINGIFY(NVIC_ICSR) "\n" /* Interrupt Control and State */ - [5] " MOV r1,#1 \n" - [6] " LSL r1,r1,#27 \n" /* r0 := (1 << 27) (UNPENDSVSET bit) */ - - /*<<<<<<<<<<<<<<<<<<<<<<< CRITICAL SECTION BEGIN <<<<<<<<<<<<<<<<<<<<<<<<*/ - #if (__ARM_ARCH == 6) /* Cortex-M0/M0+/M1 (v6-M, v6S-M)? */ - [7] " CPSID i \n" /* disable interrupts (set PRIMASK) */ - #else /* M3/M4/M7 */ - #if (__ARM_FP != 0) /* if VFP available... */ - [8] " PUSH {r0,lr} \n" /* ... push lr plus stack-aligner */ - #endif /* VFP available */ - [9] " MOV r0,#" STRINGIFY(QF_BASEPRI) "\n" -[10] " CPSID i \n" /* disable interrutps with BASEPRI */ -[11] " MSR BASEPRI,r0 \n" /* apply the Cortex-M7 erraturm */ -[12] " CPSIE i \n" /* 837070, see ARM-EPM-064408. */ - #endif /* M3/M4/M7 */ - - /* The PendSV exception handler can be preempted by an interrupt, - * which might pend PendSV exception again. The following write to - * ICSR[27] un-pends any such spurious instance of PendSV. - */ -[13] " STR r1,[r3] \n" /* ICSR[27] := 1 (unpend PendSV) */ - - /* The QK activator must be called in a Thread mode, while this code - * executes in the Handler mode of the PendSV exception. The switch - * to the Thread mode is accomplished by returning from PendSV using - * a fabricated exception stack frame, where the return address is - * QK_activate_(). - * - * returns with interrupts DISABLED. - * NOTE: the QK activator is called with interrupts DISABLED and also - */ -[14] " LSR r3,r1,#3 \n" /* r3 := (r1 >> 3), set the T bit (new xpsr) */ -[15] " LDR r2,=QK_activate_ \n" /* address of QK_activate_ */ -[16] " SUB r2,r2,#1 \n" /* align Thumb-address at halfword (new pc) */ - -[17] " LDR r1,=Thread_ret \n" /* return address after the call (new lr) */ -[18] " SUB sp,sp,#8*4 \n" /* reserve space for exception stack frame */ -[19] " ADD r0,sp,#5*4 \n" /* r0 := 5 registers below the SP */ -[20] " STM r0!,{r1-r3} \n" /* save xpsr,pc,lr */ - -[21] " MOV r0,#6 \n" -[22] " MVN r0,r0 \n" /* r0 := ~6 == 0xFFFFFFF9 */ -[23] " BX r0 \n" /* exception-return to the QK activator */ - ); - } - - /****************************************************************************/ - __attribute__ ((naked)) -[24] void Thread_ret(void) { - __asm volatile ( - - /* After the QK activator returns, we need to resume the preempted - * thread. However, this must be accomplished by a return-from-exception, - * while we are still in the thread context. The switch to the exception - * context is accomplished by triggering the NMI exception. - * NOTE: The NMI exception is triggered with nterrupts DISABLED, - * because QK activator disables interrutps before return. - */ - - /* before triggering the NMI exception, make sure that the - * VFP stack frame will NOT be used... - */ - #if (__ARM_FP != 0) /* if VFP available... */ -[25] " MRS r0,CONTROL \n" /* r0 := CONTROL */ -[26] " BICS r0,r0,#4 \n" /* r0 := r0 & ~4 (FPCA bit) */ -[27] " MSR CONTROL,r0 \n" /* CONTROL := r0 (clear CONTROL[2] FPCA bit) */ -[28] " ISB \n" /* ISB after MSR CONTROL (ARM AN321,Sect.4.16) */ - #endif /* VFP available */ - - /* trigger NMI to return to preempted task... - * NOTE: The NMI exception is triggered with nterrupts DISABLED - */ -[29] " LDR r0,=0xE000ED04 \n" /* Interrupt Control and State Register */ -[30] " MOV r1,#1 \n" -[31] " LSL r1,r1,#31 \n" /* r1 := (1 << 31) (NMI bit) */ -[32] " STR r1,[r0] \n" /* ICSR[31] := 1 (pend NMI) */ -[33] " B . \n" /* wait for preemption by NMI */ - ); - } -@endcode - - -`[1]` Attribute `naked` means that the GNU-ARM compiler won't generate any entry/exit code for this function. - -`[2]` `PendSV_Handler` is a CMSIS-complinat name of the PendSV exception handler. The `PendSV_Handler` exception is always entered via tail-chaining from the last nested interrupt. - -`[3]` Entire body of this function will be defined in this one inline-assembly instruction. - -`[4-5]` Before interrupts are disabled, the following constants are loaded into registers: address of ICSR into r3 and (1<<27) into r1. - -For the ARMv6-M architecture (Cortex-M0/M0+)... - -`[7]` Interrupts are globally disabled by setting PRIMASK (see Section 3) - -Otherwise, for the ARMv7-M architecture (Cortex-M3/4/7) and when the `__ARM_FP` macro is defined... - -@note -The symbol `__ARM_FP` is defined by the GNU-ARM compiler when the compile options indicate that the ARM FPU is used. - - -`[8]` The lr register (EXC_RETURN) is pushed to the stack along with r0, to keep the stack aligned at 8-byte boundary. - -@note -In the presence of the FPU (ARMv7M or higher architectures), the EXC_RETURN[4] bit carries the information about the stack frame format used, whereas EXC_RETURN[4] ==0 means that the stack contains room for the S0-S15 and FPSCR registers in addition to the usual R0-R3,R12,LR,PC,xPSR registers. This information must be preserved, in order to properly return from the exception at the end. - - -`[9]` For the ARMv7-M architecture (Cortex-M3/M4), interrupts are selectively disabled by setting the BASEPRI register. - -@note -The value moved to BASEPRI must be identical to the @ref QF_BASEPRI "QF_BASEPRI" macro defined in `qf_port.h`. - - -`[10]` Before setting the BASEPRI register, interrupts are disabled with the PRIMASK register, which is the recommended workaround for the Cortex-M7 r0p1 hardware bug, as described in the ARM Ltd. [@ref ARM-EPM-064408], Erratum 837070. - -`[11]` The BASEPRI register is set to the @ref QF_BASEPRI "QF_BASEPRI" value. - -`[12]` After setting the BASEPRI register, interrupts are re-anabed with the PRIMASK register, which is the recommended workaround for the Cortex-M7 r0p1 hardware bug, as described in the ARM Ltd. [@ref ARM-EPM-064408], Erratum 837070. - -`[13]` The PendSV exception is **explicitly** un-pended. - -@note -The PendSV exception handler can be preempted by an interrupt, which might pend PendSV exception again. This would trigger PendSV incorrectly again immediately after calling QK activator without destroying the original exception stack frame of the PendSV exception. This is necessary to preserve the context of the preempted code. - -`[14]` The value (1 << 24) is synthesized in r3 from the value (1 << 27) already available in r1. This value is going to be stacked and later restored to xPSR register (only the T bit set). - -`[15]` The address of the QK activator function `QK_activate_()` is loaded into r2. This will be pushed to the stack as the PC register value. - -`[16]` The address of the QK activator function `QK_activate_()` in r2 is adjusted to be half-word aligned instead of being an odd THUMB address. - -@note -This is necessary, because the value will be loaded directly to the PC, which cannot accept odd values. - - -`[17]` The address of the `Thread_ret()` function is loaded into r1. This will be pushed to the stack as the lr register value. - -@note -The address of the @c Thread_ret label must be a THUMB address, that is, the least-significant bit of this address must be set (this address must be odd number). This is essential for the correct return of the QK activator with setting the THUMB bit in the PSR. Without the LS-bit set, the ARM Cortex-M CPU will clear the T bit in the PSR and cause the Hard Fault. The GNU-ARM assembler/linker will synthesize the correct THUMB address of the svc_ret label only if this label is declared with the `.type Thread_ret , %function` attribute (see step [23]). - - -`[18]` The stack pointer is adjusted to leave room for 8 registers. - -`[19]` The top of stack, adjusted by 5 registers, (r0, r1, r2, r3, and r12) is stored to r0. - -`[20]` The values of xpsr, pc, and lr prepared in r3, r2, and r1, respectively, are pushed on the top of stack (now in r0). This operation completes the synthesis of the exception stack frame. After this step the stack looks as follows: -
-Hi memory
-           (optionally S0-S15, FPSCR), if EXC_RETURN[4]==0
-           xPSR
-           pc (interrupt return address)
-           lr
-           r12
-           r3
-           r2
-           r1
-           r0
-           EXC_RETURN (pushed in step [7] if FPU is present)
-old SP --> "aligner"  (pushed in step [7] if FPU is present)
-           xPSR == 0x01000000
-           PC == QK_activate_
-           lr == Thread_ret
-           r12  don't care
-           r3   don't care
-           r2   don't care
-           r1   don't care
-    SP --> r0   don't care
-Low memory
-
- -`[21]` The special exception-return value 0xFFFFFFF9 is synthesized in r0 (two instructions are used to make the code compatible with Cortex-M0, which has no barrel shifter). - -@note -the r0 register is used instead of lr because the Cortex-M0 instruction set cannot manipulate the higher-registers (r9-r15). - -@note -The exception-return value is consistent with the synthesized stack-frame with the lr[4] bit set to 1, which means that the FPU registers are not included in this stack frame. - - -`[23]` PendSV exception returns using the special value of the r0 register of 0xFFFFFFF9 (return to Privileged Thread mode using the Main Stack pointer). The synthesized stack frame causes actually a function call to QK_sched_ function in C. - -@note -The return from the PendSV exception just executed switches the ARM Cortex-M core to the Privileged Thread mode. The QK_sched_ function internally re-enables interrupts before launching any thread, so the threads always run in the Thread mode with interrupts enabled and can be preempted by interrupts of any priority. - -@note -In the presence of the FPU, the exception-return to the QK activator does not change any of the FPU status bit, such as CONTROL.FPCA or LSPACT. - - -`[24]` The @c Thread_ret function is the place, where the QK activator `QK_activate_()` returns to, because this return address is pushed to the stack in step [16]. Please note that the address of the @c Thread_ret label must be a THUMB address. - -`[25]` If the FPU is present, the read-modify-write code clears the CONTROL[2] bit [2]. This bit, called CONTROL.FPCA (Floating Point Active), would cause generating the FPU-type stack frame, which you want to avoid in this case (because the NMI exception will certainly not use the FPU). - -@note -Clearing the CONTROL.FPCA bit occurs with interrupts disabled, so it is protected from a context switch. - - -`[28-32]` The asynchronous NMI exception is triggered by setting ICSR[31]. The job of this exception is to put the CPU into the exception mode and correctly return to the thread level. - -`[33]` This endless loop should not be reached, because the NMI exception should preempt the code immediately after step `[31]` - - -@subsection arm-cm_qk_port-asm_nmi NMI_Handler() Implementation - -@caption{Listing: NMI_Handler() function in qk_port.c file} -@code{.c} - __attribute__ ((naked)) - [1] void NMI_Handler(void) { - __asm volatile ( - - [2] " ADD sp,sp,#(8*4) \n" /* remove one 8-register exception frame */ - - #if (__ARM_ARCH == 6) /* Cortex-M0/M0+/M1 (v6-M, v6S-M)? */ - [3] " CPSIE i \n" /* enable interrupts (clear PRIMASK) */ - [4] " BX lr \n" /* return to the preempted task */ - #else /* M3/M4/M7 */ - [5] " MOV r0,#0 \n" - [6] " MSR BASEPRI,r0 \n" /* enable interrupts (clear BASEPRI) */ - #if (__ARM_FP != 0) /* if VFP available... */ - [7] " POP {r0,pc} \n" /* pop stack aligner and EXC_RETURN to PC */ - #else /* no VFP */ - [8] " BX lr \n" /* return to the preempted task */ - #endif /* no VFP */ - #endif /* M3/M4/M7 */ - ); - } -@endcode - - -`[1]` The @c NMI_Handler is the CMSIS-compliant name of the NMI exception handler. This exception is triggered after returning from the QK activator in step [31] of the previous listing. The job of NMI is to discard its own stack frame and cause the exception-return to the original preempted thread context. The stack contents just after entering NMI is shown below: -
-Hi memory
-           (optionally S0-S15, FPSCR), if EXC_RETURN[4]==0
-           xPSR
-           pc (interrupt return address)
-           lr
-           r12
-           r3
-           r2
-           r1
-           r0
-old SP --> EXC_RETURN (pushed in PendSV [7] if FPU is present)
-           "aligner"  (pushed in PendSV [7] if FPU is present)
-           xPSR don't care
-           PC   don't care
-           lr   don't care
-           r12  don't care
-           r3   don't care
-           r2   don't care
-           r1   don't care
-    SP --> r0   don't care
-Low memory
-
- -`[2]` The stack pointer is adjusted to un-stack the 8 registers of the interrupt stack frame corresponding to the NMI exception itself. This moves the stack pointer from the "old SP" to "SP" in the picture above, which "uncovers" the original exception stack frame left by the PendSV exception. - -`[3]` For ARMv6-M, interrupts are enabled by clearing the PRIMASK. - -`[4]` For ARMv6-M, The NMI exception returns to the preempted thread using the standard EXC_RETURN, which is in lr. - -`[5-6]` For the ARMv7-M, interrupts are enabled by writing 0 into the BASEPRI register. - -`[7]` If the FPU is used, the EXC_RETURN and the "stack aligner" saved in PendSV step [7] are popped from the stack into r0 and pc, respectively. Updating the pc causes the return from PendSV. - -`[8]` Otherwise, NMI returns to the preempted thread using the standard EXC_RETURN, which is in lr. - -@anchor qk_stack-detail - -@image html qk_stack-detail.png -@image latex qk_stack-detail.png width=6.0in -@caption{Detailed stack allocation in QK for ARM Cortex-M} - - -@section arm-cm_qk-isr Writing ISRs for QK -The ARM Cortex-M CPU is designed to use regular C functions as exception and interrupt service routines (ISRs). - -@note -The ARM EABI (Embedded Application Binary Interface) requires the stack be 8-byte aligned, whereas some compilers guarantee only 4-byte alignment. For that reason, some compilers (e.g., GNU-ARM) provide a way to designate ISR functions as interrupts. For example, the GNU-ARM compiler provides the `__attribute__((__interrupt__))` designation that will guarantee the 8-byte stack alignment. - - -Typically, ISRs are application-specific (with the main purpose to produce events for active objects). Therefore, ISRs are not part of the generic QP port, but rather part of the BSP (Board Support Package). - -The following listing shows an example of the `SysTick_Handler()` ISR (from the DPP example application). This ISR calls the `QF_TICK_X()` macro to perform QF time-event management. - -@anchor arm-cm_qk-isr-code -@caption{Listing: An ISR header for QK} -@code{.c} - void SysTick_Handler(void) __attribute__((__interrupt__)); - void SysTick_Handler(void) { - ~ ~ ~ - [1] QK_ISR_ENTRY(); /* inform QK about entering an ISR */ - ~ ~ ~ - QF_TICK_X(0U, &l_SysTick_Handler); /* process all armed time events */ - ~ ~ ~ - [2] QK_ISR_EXIT(); /* inform QK about exiting an ISR */ - } -@endcode - - -`[1]` Every ISR for QK must call `QK_ISR_ENTRY()` before calling any QP API - -`[2]` Every ISR for QK must call `QK_ISR_EXIT()` right before exiting to let the QK kernel schedule an asynchronous preemption, if necessary. - -@note -The QK port to ARM Cortex-M complies with the requirement of the ARM-EABI to preserve stack pointer alignment at **8-byte boundary**. Also, all QP examples for ARM Cortex-M comply with the CMSIS naming convention for all exception handlers and IRQ handlers. - - -@section arm-cm_qk-fpu Using the FPU in the QK Port (ARMv7M or higher architectures) -If you have the Cortex-M4F CPU and your application uses the hardware FPU, it should be enabled because it is turned off out of reset. The CMSIS-compliant way of turning the FPU on looks as follows: - -@verbatim - SCB->CPACR |= (0xFU << 20); -@endverbatim - -@note -If the FPU is configured in the project, the QK kernel initializes the FPU to use the automatic state preservation and the lazy stacking feature as follows: -@verbatim - FPU->FPCCR |= (1U << FPU_FPCCR_ASPEN_Pos) | (1U << FPU_FPCCR_LSPEN_Pos); -@endverbatim - -@note -As described in the ARM Application Note "Cortex-M4(F) Lazy Stacking and Context Switching" [@ref ARM-AN298], the FPU automatic state saving requires more stack plus additional CPU time to save the FPU registers, but only when the FPU is actually used. - - -@section arm-cm_qk-idle QK Idle Processing Customization in QK_onIdle() -QK can very easily detect the situation when no events are available, in which case QK calls the `QK_onIdle()` callback. You can use `QK_onIdle()` to suspended the CPU to save power, if your CPU supports such a power-saving mode. Please note that `QK_onIdle()` is called repetitively from an endless loop, which is the QK idle-thread. The `QK_onIdle()` callback is called with interrupts **enabled** (which is in contrast to the @ref arm-cm_qv-idle "QV_onIdle() callback" used in the non-preemptive configuration). - -The THUMB-2 instruction set used exclusively in ARM Cortex-M provides a special instruction WFI (Wait-for-Interrupt) for stopping the CPU clock, as described in the "ARMv7-M Reference Manual" [ARM 06a]. The following listing shows the `QK_onIdle()` callback that puts ARM Cortex-M into a low-power mode. - -@anchor arm-cm_qk_onidle-code -@caption{Listing: QV_onIdle() for ARM Cortex-M} -@code{.c} - - [1] void QK_onIdle(void) { - ~ ~ ~ - [2] #if defined NDEBUG - /* Put the CPU and peripherals to the low-power mode. - * you might need to customize the clock management for your application, - * see the datasheet for your particular Cortex-M3 MCU. - */ - [3] __WFI(); /* Wait-For-Interrupt */ - #endif - } -@endcode - -`[1]` The preemptive QK kernel calls the `QK_onIdle()` callback with interrupts enabled. - -`[2]` The sleep mode is used only in the non-debug configuration, because sleep mode stops CPU clock, which can interfere with debugging. - -`[3]` The `WFI` instruction is generated using inline assembly. - - -@section arm-cm_qk-testing Testing QK Preemption Scenarios -The `bsp.c` file included in the examples/arm-cm/dpp_ek-tm4c123gxl/qk directory contains special instrumentation (an ISR designed for testing) for convenient testing of @ref arm-cm_qk-arm-cm-fig "various preemption scenarios in QK". - -The technique described in this section will allow you to trigger an interrupt at any machine instruction and observe the preemption it causes. The interrupt used for the testing purposes is the GPIOA interrupt (INTID == 0). The ISR for this interrupt is shown below: - -
-@code{.c} -void GPIOPortA_IRQHandler(void) { - QK_ISR_ENTRY(); /* inform QK about entering an ISR */ - QACTIVE_POST(AO_Table, Q_NEW(QEvt, MAX_PUB_SIG), /* for testing... */ - &l_GPIOPortA_IRQHandler); - QK_ISR_EXIT(); /* inform QK about exiting an ISR */ -} -@endcode - - -`GPIOPortA_IRQHandler()`, as all interrupts in the system, invokes the macros QK_ISR_ENTRY() and QK_ISR_EXIT(), and also posts an event to the Table active object, which has higher priority than any of the Philo active object. - -The figure below hows how to trigger the GPIOA interrupt from the CCS debugger. From the debugger you need to first open the register window and select NVIC registers from the drop-down list (see right-bottom corner of Figure 6).You scroll to the NVIC_SW_TRIG register, which denotes the Software Trigger Interrupt Register in the NVIC. This write-only register is useful for software-triggering various interrupts by writing various masks to it. To trigger the GPIOA interrupt you need to write 0x00 to the NVIC_SW_TRIG by clicking on this field, entering the value, and pressing the Enter key. - -@image html arm-cm_qk_test-ccs.png "Triggering the GPIOA interrupt from Eclipse debugger" - -The general testing strategy is to break into the application at an interesting place for preemption, set breakpoints to verify which path through the code is taken, and trigger the GPIO interrupt. Next, you need to free-run the code (don’t use single stepping) so that the NVIC can perform prioritization. You observe the order in which the breakpoints are hit. This procedure will become clearer after a few examples. - - -@subsection arm-cm_qk-test-isr Interrupt Nesting Test -The first interesting test is verifying the correct tail-chaining to the PendSV exception after the interrupt nesting occurs, as shown in @ref arm-cm_qk-synch-fig "Synchronous Preemption in QK". To test this scenario, you place a breakpoint inside the `GPIOPortA_IRQHandler()` and also inside the `SysTick_Handler()` ISR. When the breakpoint is hit, you remove the original breakpoint and place another breakpoint at the very next machine instruction (use the Disassembly window) and also another breakpoint on the first instruction of the `QK_PendSV` handler. Next you trigger the PIOINT0 interrupt per the instructions given in the previous section. You hit the Run button. - -The pass criteria of this test are as follows: - -1. The first breakpoint hit is the one inside the `GPIOPortA_IRQHandler()` function, which means that GPIO ISR preempted the SysTick ISR. - -2. The second breakpoint hit is the one in the `SysTick_Handler()`, which means that the SysTick ISR continues after the PIOINT0 ISR completes. - -3. The last breakpoint hit is the one in `PendSV_Handler()` exception handler, which means that the PendSV exception is tail-chained only after all interrupts are processed. You need to remove all breakpoints before proceeding to the next test. - - -@subsection arm-cm_qk-test-thread Thread Preemption Test -The next interesting test is verifying that threads can preempt each other. You set a breakpoint anywhere in the Philosopher state machine code. You run the application until the breakpoint is hit. After this happens, you remove the original breakpoint and place another breakpoint at the very next machine instruction (use the Disassembly window). You also place a breakpoint inside the `GPIOPortA_IRQHandler()` interrupt handler and on the first instruction of the `PendSV_Handler()` handler. Next you trigger the GPIOA interrupt per the instructions given in the previous section. You hit the Run button. - -The pass criteria of this test are as follows: - -1. The first breakpoint hit is the one inside the `GPIOPortA_IRQHandler()` function, which means that GPIO ISR preempted the Philo thread. - -2. The second breakpoint hit is the one in `PendSV_Handler()` exception handler, which means that the PendSV exception is activated before the control returns to the preempted Philosopher thread. - -3. After hitting the breakpoint in `PendSV_Handler()`, you single step into `QK_activate_()`. You verify that the activator invokes a state handler from the Table state machine. This proves that the Table thread preempts the Philo thread. - -4. After this you free-run the application and verify that the next breakpoint hit is the one inside the Philosopher state machine. This validates that the preempted thread continues executing only after the preempting thread (the Table state machine) completes. - - -@subsection arm-cm_qk-test-fpu Testing the FPU -In order to test the FPU (ARMv7M or higher architectures), the Board Support Package (BSP) for the Cortex-M4F EK-TM4C123GXL board uses the FPU in the following contexts: - -- In the idle loop via the `QK_onIdle()` callback (QP priority 0) -- In the thread level via the `BSP_random()` function called from all five Philo active objects (QP priorities 1-5). -- In the thread level via the `BSP_displayPhiloStat()` function called from the Table active object (QP priorty 6) -- In the ISR level via the `SysTick_Handler()` ISR (priority above all threads) - -To test the FPU, you could step through the code in the debugger and verify that the expected FPU-type exception stack frame is used and that the FPU registers are saved and restored by the "lazy stacking feature" when the FPU is actually used. - -Next, you can selectively comment out the FPU code at various levels of priority and verify that the QK context switching works as expected with both types of exception stak frames (with and without the FPU). - - -@subsection arm-cm_qk-test-other Other Tests -Other interesting tests that you can perform include changing priority of the GPIOA interrupt to be lower than the priority of SysTick to verify that the PendSV is still activated only after all interrupts complete. - -In yet another test you could post an event to Philosopher active object rather than Table active object from the `GPIOPortA_IRQHandler()` function to verify that the QK activator will not preempt the Philosopher thread by itself. Rather the next event will be queued and the Philosopher thread will process the queued event only after completing the current event processing. - -@ifnot LATEX -@nav_next{arm-cm_qxk} -@endif -*/ -/*##########################################################################*/ -/*! @page arm-cm_qxk Preemptive "Dual-Mode" QXK Kernel - -This section describes how to use QP on ARM Cortex-M with the @ref srs_qxk "preemptive, dual-mode QXK real-time kernel", which combines the lightweight non-blocking @ref srs_qxk_basic "basic threads" of QK with traditional blocking @ref srs_qxk_extended "extended threads" found in conventional RTOS kernels. QXK provides all typical services of a conventional blocking RTOS, such as blocking time-delays, semaphores, mutextes, and message queues. - -QXK has been designed specifically for mixing event-driven active objects with traditional blocking code, such as commercial middleware (TCP/IP stacks, UDP stacks, embedded file systems, etc.) or legacy software. - -@note -If you are currently using QP on top of a conventional 3rd-party RTOS, consider moving your application to the QXK kernel. QXK is not only more efficient than running QP on top of a @ref ports_rtos "traditional 3rd-party RTOS" (because non-blocking @ref srs_qxk_basic "basic threads" take far less stack space and CPU cycles for context switch than the much heavier @ref srs_qxk_extended "extended threads"). But the biggest advantage of QXK is that it __protects__ the application-level code from inadvertent mixing of blocking calls inside the event-driven active objects. Specifically, QXK "knows" the type of the thread context (extended/basic) and asserts internally if a blocking call (e.g., semaphore-wait or a time-delay) is attempted in a basic thread (active object). This is something that a QP port to a @ref ports_rtos "conventional 3rd-party RTOS" cannot do, because such an RTOS runs all code (including active objects) in the context of heavyweight extended threads. - - -@section arm-cm_qxk-synopsis Synopsis of the QXK Port on ARM Cortex-M -The preemptive, blocking QXK kernel works on ARM Cortex-M as follows: - -- The ARM Cortex-M processor executes application code in the Privileged Thread mode, which is exactly the mode entered out of reset. The exceptions (including all interrupts) are always processed in the Privileged Handler mode. - -- QXK uses the Main Stack Pointer (MSP) for @ref srs_qxk_basic "basic threads", interrupts and exceptions (such as the PendSV exception). The MSP is also used for the QXK idle thread (which is a non-blocking basic thread). - -- QXK uses the Process Stack Pointer (PSP) for handling @ref srs_qxk_extended "extended threads". Each extended thread must provide a private stack space to be associated with the PSP. - -- The QXK port uses the @c PendSV (exception number 14) and the NMI or the IRQ exception (number 2) to perform context switch. The application code (your code) must initialize the Interrupt Vector Table with the addresses of the `PendSV_Handler` and `NMI_Handler` exception handlers. - -@note -QXK uses only the CMSIS-compliant exception and interrupt names, such as `PendSV_Handler`, `NMI_Handler`, etc.@n - -@note -The QXK port specifically does **not** use the SVC exception (Supervisor Call). This makes the QXK ports compatible with various "hypervisors" (such as mbed uVisor or Nordic SoftDevice), which use the SVC exception. - -- You need to explicitly **assign priorities of the all interrupts** used in your application, as described in @ref arm-cm_int. - -@note -For ARMv7M or higher architectures (M3/M4/M7/M33...), the QXK initialization code (executed from the QF initialization) initializes all interrupt priorities to the safe value maskable with the BASEPRI register. However, this is just a safety precaution not to leave the interrupts kernel-unaware, which they are out of reset. It is highly recommended to set the priorities of all interrupts explicitly in the application-level code. - -- It is strongly recommended that you do not assign the lowest NVIC priority (0xFF) to any interrupt in your application, because it is used by the PendSV handler. For example, with 3 bits of priority implemented in the NVIC, this leaves the following 7 priority levels for you (listed from the lowest to the highest urgency): 0xC0, 0xA0, 0x80, 0x60, 0x40, 0x20, and 0x00 (the highest priority). - -@note -The prioritization of interrupts, including the PendSV exception, is performed entirely by the NVIC. Because the PendSV has the lowest priority in the system, the NVIC tail-chains to the PendSV exception only after exiting the last nested interrupt. - -- ISRs are written as regular C functions, but they need to call QXK_ISR_ENTRY() before using any QF services, and they must call QXK_ISR_EXIT() after using any of the QF services. - -- ARM Cortex-M enters interrupt context without disabling interrupts. Generally, you should not disable interrupts inside your ISRs. In particular, the QF services (such as QF_PUBLISH(), QF_TICK_X(), and QACTIVE_POST()) should be called with interrupts enabled, to avoid nesting of critical sections. - -@note -If you don't wish an interrupt to be preempted by another interrupt, you can always prioritize that interrupt in the NVIC to a higher or equal level as other interrupts (use a lower numerical value of priority). - -- In compliance with the ARM Application Procedure Call Standard (AAPCS), the QXK kernel always preserves the 8-byte alignment of the stack (both MSP and PSP). - - -@subsection arm-com_qxk_vfp Using the VFP -If you have the ARMv7M or higher architectures (ARMv7M or higher architectures) and your application is compiled with the VFP present, the QXK kernel will enable the VFP along with the VFP automatic state preservation and lazy stacking features. This will cause the NVIC to automatically use the VFP-exception stack frame (with additional 18 VFP registers S0-S15 plus VFP status and stack "aligner"). The QXK context switch will add to this the rest of the VFP registers (S16-S31) on context switches to and from extended threads. - -@note -With VFP enabled, any QXK thread (both a basic and an extended thread) will use 136 more bytes of its stack space, regardless if VFP is actually used by this thread. However, due to the "lazy-stacking" hardware feature, only a thread that actually uses the VFP will save and restore the VFP registers on the stack (which will cost some additional CPU cycles to perform a context switch). - -*/ diff --git a/doxygen/ports_native.dox b/doxygen/ports_native.dox deleted file mode 100644 index b5acaa02..00000000 --- a/doxygen/ports_native.dox +++ /dev/null @@ -1,60 +0,0 @@ -/*##########################################################################*/ -/*! @page ports_native Native (Bare-Metal) Ports - -- @subpage arm-cm (Cortex-M0/M0+/M3/M4/M4/M7) - - @ref arm-cm_qv (ARM-CLANG, ARM-KEIL, GNU-ARM, IAR-ARM ) - - @ref arm-cm_qk (ARM-CLANG, ARM-KEIL, GNU-ARM, IAR-ARM) - - @ref arm-cm_qxk (ARM-CLANG, ARM-KEIL, GNU-ARM, IAR-ARM) -- @subpage arm-cr (Cortex-R) - - @ref arm-cr_qv (GNU-ARM, IAR-ARM, TI-CCS toolchains) - - @ref arm-cr_qk (GNU-ARM, IAR-ARM, TI-CCS toolchains) -- @subpage arm7-9 ("classic" ARM) - - @ref arm7-9_qv (GNU-ARM, IAR-ARM toolchains) - - @ref arm7-9_qk (GNU-ARM, IAR-ARM toolchains) -- @subpage msp430 ("classic" MSP430 and "extended" MSP430X) - - @ref msp430_qv (TI-CCS, IAR toolchains) - - @ref msp430_qk (TI-CCS, IAR toolchains) - -@ifnot LATEX -@nav_next{arm-cm} -@endif -*/ -/*##########################################################################*/ -/*! @page arm-cr ARM Cortex-R - -The QP/C/C++ ports and examples for ARM Cortex-R are described in the Quantum Leaps Application Note @webref{doc/AN_QP_and_ARM-Cortex-R.pdf, QP and ARM Cortex-R}. - -@image html AN-QL.png -@image latex AN-QL.png width=2.0in -@caption{[Application Note: "QP and ARM Cortex-R"](https://www.state-machine.com/doc/AN_QP_and_ARM-Cortex-R.pdf)} - -@ifnot LATEX -@nav_next{arm7-9} -@endif -*/ -/*##########################################################################*/ -/*! @page arm7-9 ARM7/ARM9 - -The QP/C/C++ ports and examples for ARM7/ARM9 are described in the Quantum Leaps Application Note @webref{doc/AN_QP_and_ARM-Cortex-R.pdf, QP and ARM7/ARM9}. - -@image html AN-QL.png -@image latex AN-QL.png width=2.0in -@caption{[Application Note: "QP and ARM7/ARM9"](https://www.state-machine.com/doc/AN_QP_and_ARM7_ARM9-GNU.pdf)} - -@ifnot LATEX -@nav_next{msp430} -@endif -*/ -/*##########################################################################*/ -/*! @page msp430 MSP430 - -The QP/C/C++ ports and examples for MSP430 are described in the Quantum Leaps Development Kit @webref{doc/QDK_MSP430-CCS.pdf, QP and MSP430 with CCS} and @webref{doc/QDK_MSP430-IAR.pdf, QP and MSP430 with IAR}. - -@image html AN-QL.png -@image latex AN-QL.png width=2.0in -@caption{[Application Note: "QP and MSP430-CCS"](https://www.state-machine.com/doc/QDK_MSP430-CCS.pdf)} - -@image html AN-QL.png -@image latex AN-QL.png width=2.0in -@caption{[Application Note: "QP and MSP430-IAR"](https://www.state-machine.com/doc/QDK_MSP430-IAR.pdf)} -*/ diff --git a/doxygen/ports_os.dox b/doxygen/ports_os.dox deleted file mode 100644 index 5fad50d8..00000000 --- a/doxygen/ports_os.dox +++ /dev/null @@ -1,84 +0,0 @@ -/*##########################################################################*/ -/*! @page ports_os Ports to Third-Party OS - -- @subpage posix-qv (single-threadedLinux, embedded-Linux, BSD, etc.) -- @subpage posix (multi-threaded Linux, embedded-Linux, BSD, etc.) -- @subpage win32-qv (single-threaded Windows, like the QV kernel) -- @subpage win32 API (multi-threaded Windows, Windows embedded) - -*/ - -/*##########################################################################*/ -/*! @page posix-qv POSIX-QV - -

The QP/C/C++ ports and examples for POSIX-QV (e.g., Embedded Linux, BSD, VxWorks, QNX, etc.) are described in the Quantum Leaps Application Note QP and POSIX. -

- -@htmlonly -
- -
-Application Note: QP and POSIX -
-
-@endhtmlonly - -The standard QP/C distribution contains the POSIX-QV port and @ref exa_os. - -*/ - -/*##########################################################################*/ -/*! @page posix POSIX - -

The QP/C/C++ ports and examples for POSIX (e.g., Embedded Linux, BSD, VxWorks, QNX, etc.) are described in the Quantum Leaps Application Note QP and POSIX. -

- -@htmlonly -
- -
-Application Note: QP and POSIX -
-
-@endhtmlonly - -The standard QP/C distribution contains the POSIX port and @ref exa_os. - -*/ - -/*##########################################################################*/ -/*! @page win32-qv Win32-QV (Windows with QV) - -

The QP/C/C++ ports and examples for Windows with single-thread (like the @ref srs_qv "QV cooperative kernel") are described in the Quantum Leaps Application Note QP and Win32 (Windows). -

- -@htmlonly -
- -
-Application Note: QP and Win32 (Windows) -
-
-@endhtmlonly - -The standard QP/C distribution contains the Win32-QV port and @ref exa_os. - -*/ -/*##########################################################################*/ -/*! @page win32 Win32 API (Windows) - -

The QP/C/C++ ports and examples for Windows (e.g., Windows Embedded, WindowsCE etc.) are described in the Quantum Leaps Application Note QP and Win32 (Windows). -

- -@htmlonly -
- -
-Application Note: QP and Win32 (Windows) -
-
-@endhtmlonly - -The standard QP/C distribution contains the Win32 (Windows) port and @ref exa_os. - -*/ diff --git a/doxygen/ports_rtos.dox b/doxygen/ports_rtos.dox deleted file mode 100644 index 57d746dc..00000000 --- a/doxygen/ports_rtos.dox +++ /dev/null @@ -1,355 +0,0 @@ -/*##########################################################################*/ -/*! @page ports_rtos Ports to Third-Party RTOS - -

The most important reason why you might consider using a traditional RTOS kernel for executing event-driven QP/C applications is compatibility with the existing software. For example, most communication stacks (TCP/IP, USB, CAN, etc.) are designed for a traditional **blocking** kernel. In addition, a lot of legacy code requires blocking mechanisms, such as semaphores or time-delays. A conventional RTOS allows you to run the existing software components as regular "blocking" tasks in parallel to the event-driven QP/C application. -

- -Another reason you might be interested in running QP/C on top of a conventional RTOS is **safety certification**, which your RTOS kernel might have but the built-in QP kernels currently don't provide. - -@note -You do **not** need to use a traditional RTOS just to achieve preemptive multitasking with QP. The @ref comp_qk "preemptive QK kernel", available as part of the QP package, supports preemptive priority-based multitasking and is fully compatible with Rate Monotonic Scheduling to achieve guaranteed, hard real-time performance. The preemptive, run-to-completion QK kernel perfectly matches the run-to-completion execution semantics of active objects, yet it is simpler, faster, and more efficient than any traditional blocking kernel. - -@attention -QP/C 6.x includes a small, preemptive, priority-based, @ref srs_qxk "dual-mode blocking QXK kernel" that executes active objects like the QK kernel (@ref srs_qxk_basic "basic threads"), but can also execute traditional blocking threads (@ref srs_qxk_extended "extended threads"). In this respect, QXK behaves exactly like a conventional RTOS. The QXK kernel is recommended as the preferred RTOS kernel for applications that need to mix active objects with traditional blocking code. Due to the tight and optimal integration between QXK and the rest of QP, QXK offers better performance and smaller memory footprint than any @ref ports_rtos "QP port to a 3rd-party RTOS". Additionally, QXK is already included in QP, so you avoid additional licensing costs of 3rd-party kernels. - - -The QP/C framework can work with virtually any traditional real-time operating -system (RTOS). The currently supported 3rd-party RTOS kernels are: - -- @subpage embos -- @subpage freertos -- @subpage threadx -- @subpage uc-os2 -- @subpage zephyr -- OSEK/VDX RTOS ERIKA Enterprise - -Combined with a conventional RTOS, QP/C takes full advantage of the multitasking capabilities of the RTOS by executing each active object in a separate RTOS task. The QP/C Platform Abstraction Layer (PAL) includes an abstract RTOS interface to enable integration between QP/C and the underlying RTOS. Specifically, the PAL allows adapting most message queue variants as event queues of active objects as well as most memory partitions as QP/C event pools. - -@ifnot LATEX -@nav_next{embos} -@endif -*/ - -/*##########################################################################*/ -/*! @page embos embOS - -@image html logo_embos.png -@image latex logo_embos.png width=1.5in -@caption{SEGGER embOS} - -The QP/C/C++ ports and examples for embOS are described in the Quantum Leaps Application Note @webref{doc/AN_RTOS-embOS.pdf, QP and embOS}. - -@image html AN-QL.png -@image latex AN-QL.png width=2.0in -@caption{[Application Note: "QP and embOS"](https://www.state-machine.com/doc/AN_RTOS-embOS.pdf)} - -@ifnot LATEX -@nav_next{freertos} -@endif -*/ - -/*##########################################################################*/ -/*! @page freertos FreeRTOS - -@image html logo_freertos.png -@image latex logo_freertos.png width=2.5in -@caption{FreeRTOS} - -@section freertos_about About the QP Port to FreeRTOS -The ports/freertos/ directory contains a generic platform-independent QP/C port to FreeRTOS kernel (version 10). The provided QP port to FreeRTOS has been designed *generically* to rely exclusively on the existing FreeRTOS API. This means that the port should run without changes on any CPU/compiler platform supported by FreeRTOS. - -The QP-FreeRTOS port works as follows: - -- The QP port uses the [static memory allocation of FreeRTOS](https://freertos.org/Static_Vs_Dynamic_Memory_Allocation.html). This requires the FreeRTOS configuration to define the [configSUPPORT_STATIC_ALLOCATION](https://freertos.org/a00110.html#configSUPPORT_STATIC_ALLOCATION) - -- Each QP active object executes in a separate FreeRTOS task (`StaticTask_t`) and requires a private stack space. - -- The task-level critical section used in QF and QS is based on the FreeRTOS APIs `taskENTER_CRITICAL()`/`taskEXIT_CRITICAL()`. - -- The ISR-level critical section used in QF and QS is based on the FreeRTOS APIs `taskENTER_CRITICAL_FROM_ISR()`/`taskEXIT_CRITICAL_FROM_ISR()`. - -- The QP port to FreeRTOS provides new "FromISR" APIs, which must be used in the ISRs (but cannot be used at the task-level) - -@attention -The design of FreeRTOS requires the use of special "FromISR" API inside ISRs, which imposes the requirement to also provide the "FromISR" variants of the QP APIs, such as `QACTIVE_POST_FROM_ISR()`, `QF_PUBLISH_FROM_ISR()`, etc. These "FromISR" QP APIs must be used inside ISRs instead of the task-level APIs (`QACTIVE_POST()`, `QF_PUBLISH()`, etc.) and conversely, they cannot be used inside tasks and active objects. Unfortunately, FreeRTOS provides no generic way to enforce the proper API use via assertions. - - -- The QP port uses the FreeRTOS message queue (`StaticQueue_t`) for active object event queues. - -- The QP port uses the native QF memory pool (::QMPool) to implement event pools. - -- The QP port does not mandate any specific method to manage the QP time events, but the provided examples use the FreeRTOS "hook" `vApplicationTickHook()` to periodically invoke the QP clock tick QF_TICK_X_FROM_ISR(). (NOTE: the `vApplicationTickHook()` executes in the ISR context and therefore mandates the use of the "FromISR" APIs). - - -@section freertos_examples Example Code -The QP port to FreeRTOS comes with examples located in the directory `qpc/examples/freertos`. Currently, the examples are provided for the following boards and development toolchains: - -- EK-TM4C123GXL (ARM Cortex-M4F), ARM-KEIL, GNU-ARM, IAR-ARM -- STM32F746G-Discovery (ARM Cortex-M7), ARM-KEIL, GNU-ARM, IAR-ARM - - -@subsection freertos_isr Writing ISRs for QP/FreeRTOS -The provided examples show how to write regular "kernel-aware" ISRs as well as "kernel-unaware" ISRs for QP/FreeRTOS. (See also the FreeRTOS documentation for [configMAX_SYSCALL_INTERRUPT_PRIORITY](https://www.freertos.org/a00110.html#kernel_priority). - -Here is an example of a regular "kernel-aware" ISR (note the use of the `FromISR` suffix in the QP APIs): - -
-@code{.c} -/* NOTE: only the "FromISR" API variants are allowed in the ISRs! */ -void GPIOPortA_IRQHandler(void) { - BaseType_t xHigherPriorityTaskWoken = pdFALSE; - - /* for testing~~~ */ - QACTIVE_POST_FROM_ISR(AO_Table, - Q_NEW_FROM_ISR(QEvt, MAX_PUB_SIG), - &xHigherPriorityTaskWoken, - &l_GPIOPortA_IRQHandler); - - /* the usual end of FreeRTOS ISR~~~ */ - portEND_SWITCHING_ISR(xHigherPriorityTaskWoken); -} -@endcode - -Here is an example of a "kernel-unaware" ISR (See also the FreeRTOS documentation for [configMAX_SYSCALL_INTERRUPT_PRIORITY](https://www.freertos.org/a00110.html#kernel_priority) ): - -
-@code{.c} -/* -* ISR for receiving bytes from the QSPY Back-End -* NOTE: This ISR is "kernel-unaware" meaning that it does not interact with -* the FreeRTOS or QP and is not disabled. Such ISRs don't need to call -* portEND_SWITCHING_ISR(() at the end, but they also cannot call any -* FreeRTOS or QP APIs. -*/ -void UART0_IRQHandler(void) { - uint32_t status = UART0->RIS; /* get the raw interrupt status */ - UART0->ICR = status; /* clear the asserted interrupts */ - - while ((UART0->FR & UART_FR_RXFE) == 0) { /* while RX FIFO NOT empty */ - uint32_t b = UART0->DR; - QS_RX_PUT(b); - } -} -@endcode - - -@subsection freertos_hook Writing FreeRTOS Hooks Running in ISR Context -FreeRTOS provides "hooks" that are user functions that execute in the ISR context (e.g., `vApplicationTickHook()`). Such ISR-level functions are closely related to ISRs and should also use exclusively only the "FromISR" APIs. Here is an example of the `vApplicationTickHook()`: - -
-@code{.c} -/* NOTE: only the "FromISR" API variants are allowed in vApplicationTickHook */ -void vApplicationTickHook(void) { - BaseType_t xHigherPriorityTaskWoken = pdFALSE; - . . . - /* process time events for rate 0 */ - QF_TICK_X_FROM_ISR(0U, &xHigherPriorityTaskWoken, &l_TickHook); - . . . - /* notify FreeRTOS to perform context switch from ISR, if needed */ - portEND_SWITCHING_ISR(xHigherPriorityTaskWoken); -} -@endcode - - -@subsection freertos_ao Starting Active Objects in QP/FreeRTOS -As mentioned in the @ref freertos_about "FreeRTOS port summary", the QP port to FreeRTOS uses the [static memory allocation of FreeRTOS](https://freertos.org/Static_Vs_Dynamic_Memory_Allocation.html). This means that all memory for an active object, including the private queue buffer and the private **stack** for the the associated FreeRTOS task must be allocated by the user. Here is an example code that starts an active object: - -
-@code{.c} -int main() { - . . . - static QEvt const *tableQueueSto[N_PHILO]; - static StackType_t tableStack[configMINIMAL_STACK_SIZE]; - . . . - Table_ctor(); /* instantiate the Table active object */ - . . . - QActive_setAttr(AO_Table, TASK_NAME_ATTR, "Table"); - QACTIVE_START(AO_Table, /* AO to start */ - N_PHILO + 1U, /* QP priority of the AO */ - tableQueueSto, /* event queue storage */ - Q_DIM(tableQueueSto), /* queue length [events] */ - tableStack, /* stack storage */ - sizeof(tableStack), /* stack size [bytes] */ - (void *)0); /* initialization param (not used) */ - . . . - return QF_run(); /* run the QF application */ -} -@endcode - -@ifnot LATEX -@nav_next{threadx} -@endif -*/ -/*##########################################################################*/ -/*! @page threadx ThreadX - -@image html logo_threadx.jpg -@image latex logo_threadx.jpg width=3.0in -@caption{ThreadX (Azure RTOS)} - -The QP/C/C++ ports and examples for ThreadX (now Azure RTOS) are described in the Quantum Leaps Application Note @webref{doc/AN_RTOS-ThreadX.pdf, QP and ThreadX}. - -@image html AN-QL.png -@image latex AN-QL.png width=2.0in -@caption{[Application Note: "QP and ThreadX"](https://www.state-machine.com/doc/AN_RTOS-ThreadX.pdf)} - -@ifnot LATEX -@nav_next{uc-os2} -@endif -*/ - -/*##########################################################################*/ -/*! @page uc-os2 uC-OS2 - -@image html logo_uc-os2.jpg -@image latex logo_uc-os2.jpg width=2.0in -@caption{uC-OS2} - -@section uc-os2_about About the QP Port to uC-OS2 -This directory contains a generic platform-independent QP/C port to uC-OS2 V2.92. - -Typically, you should not need to change the files in this directory to adapt the QP-uC-OS2 port on any CPU/Compiler to which uC-OS2 has been ported, because all the CPU and compiler specifics are handled by the uC-OS2 RTOS. - - -@section uc-os2_source uC-OS2 Source and ARM Cortex-M3/M4 Ports -The uC-OS2 V2.92 source code and ports are located in `3rd_party/uc-os2`. Please make sure to read about uC-OS2 licensing in the README file found in this directory. - -@note -The official Micrium ARM-Cortex-M ports have been modified by Quantum Leaps to remove the dependencies on the Micrium's uC-CPU and uC-LIB components, and instead to inter-operate with the Cortex Microcontroller Software Interface Standard (CMSIS). - - -@section uc-os2_using Using this QP Port to uC-OS2 -The example projects for this port are located in @ref exa_uc-os2 "examples/uc-os2/arm-cm/dpp_ek-tm4c123gxl". - -Currently, ARM-KEIL and IAR-ARM toolsets are supported (in the arm and iar sub-directories within this example project). - -The example projects use this port by directly including the QP source code (and this port) in the application projects. There is no QP library to build. - -However, this port can also be used as a library, in which case you need to build the QP library yourself and include in your project. - - -@subsection uc-os2_build QP Source Files Needed in this QP Port -Whether you use this QP port as source files or as a library, it is important to note that not all QP source files should be included. Here is the list of QP source files needed: - -
-@code{.c} -qpc/ -+-src/ -| | +-qf/ -| | | +-qep_hsm.c -| | | +-qep_msm.c -| | | +-qf_act.c -| | | +-qf_actq.c // NOT included (implemented in uC-OS2) -| | | +-qf_defer.c -| | | +-qf_dyn.c -| | | +-qf_mem.c // NOT included (implemented in uC-OS2) -| | | +-qf_ps.c -| | | +-qf_qeq.c -| | | +-qf_qmact.c -| | | +-qf_time.c -| | -| | +-qs/ -| | | +-qs.c // included only in the Spy build configuration -| | | +-qs_fp.c // included only in the Spy build configuration -| -+-ports -| +-uc-os2 -| | +-qf_port.c -| -@endcode - -@note -Specifically, the QP source files qf_actq.c and qf_mem.c must **NOT** be included in the build, because this functionality is taken from uC-OS2. - -The QP/C/C++ ports and examples for uC-OS2 are described in the Quantum Leaps Application Note @webref{doc/AN_RTOS-uCOS2.pdf, QP and uC-OS2}. - -@image html AN-QL.png -@image latex AN-QL.png width=2.0in -@caption{[Application Note: QP and uC-OS2](https://www.state-machine.com/doc/AN_RTOS-uCOS2.pdf)} - -@ifnot LATEX -@nav_next{zephyr} -@endif -*/ - -/*##########################################################################*/ -/*! @page zephyr Zephyr - -@image html logo_zephyr.jpg -@image latex logo_zephyr.jpg width=2.0in -@caption{Zephyr Project} - - -@section zephyr_about About the QP Port to Zephyr -This directory contains a generic platform-independent QP/C port to the [Zephyr RTOS](https://zephyrproject.org). - -Typically, you should not need to change the files in this directory to adapt the QP-Zephyr port on any CPU/Compiler to which Zephyr has been ported, because all the CPU and compiler specifics are handled by the Zephyr RTOS. - - -The QP-Zephyr port works as follows: - -- The critical section used in this port is based on `k_spin_lock()/k_spin_unlock()` Zephyr API. This is the modern Zephyr critical section API, which is ready for SMP (symmetric multiprocessing). - -- Each QP active object executes in a separate Zephyr thread (`struct k_thread`) and requires a private stack space. - -@note -As demonstrated in the @ref exa_zephyr "provided examples", the private stacks for active objects in this port must be allocated with the Zephyr `K_THREAD_STACK_DEFINE()` macro. Also, the stack size passed to QACTIVE_START() must be calculated with the Zephyr `K_THREAD_STACK_SIZEOF()` macro. Failure to use these macros can lead to memory corruption in the application. - - -- The active object event queue is implemented with the Zephyr message queue (`struct k_msgq`). - -@note -The Zephyr message queue currently supports only the FIFO policy and does NOT support the LIFO policy. For that reason, the QActive_postLIFO_() implementation in this port uses the FIFO policy. A feature request has been filed in the Zephyr project for adding the LIFO policy, so perhaps this can be improved, if the feature is added. - - -- The QP port uses Zephyr scheduler locking (`k_sched_lock()/k_sched_unlock()`), which locks all threads indiscriminately. Currently Zephyr does not provide a selective scheduler locking. - -- The QP port uses the native QF memory pool (::QMPool) to implement event pools. - -- The QP port does not mandate any specific method to manage the QP time events, but the provided examples use the Zephyr timer (`struct k_timer`) to tick periodically and invoke QF_TICK_X(). - - -@subsection zephyr_build QP Source Files Needed in this QP Port -It is important to note that **NOT** all QP source files should be included. Here is the list of QP source files needed: - -
-@code{.c} -qpc/ -+--src/ -| +--qf/ -| | qep_hsm.c -| | qep_msm.c -| | qf_act.c -| | qf_actq.c // NOT included (implemented in Zephyr) -| | qf_defer.c -| | qf_dyn.c -| | qf_mem.c -| | qf_ps.c -| | qf_qeq.c -| | qf_qmact.c -| | qf_time.c -| | -| +--qs/ -| | qs.c // included only in the Spy build configuration -| | qs_fp.c // included only in the Spy build configuration -| -+--ports/ -| +--zephyr -| | qep_port.h -| | qf_port.h -| | qf_port.c // implementation of the Zephyr port -| | qs_port.h -| -@endcode - -@note -Specifically, the QP source files qf_actq.c must **NOT** be included in the build, because this functionality is taken from Zephyr. - - -@section zephyr_exa Examples for the Zephyr port -The example projects for this port are located in @ref exa_zephyr "examples/zephyr". - -@ifnot LATEX -@nav_next{ports_os} -@endif -*/ diff --git a/doxygen/rsm.bat b/doxygen/rsm.bat deleted file mode 100644 index 521e3ad8..00000000 --- a/doxygen/rsm.bat +++ /dev/null @@ -1,44 +0,0 @@ -@echo off -:: ========================================================================== -:: Product: QP/C script for running MSquared Resource Standard Metrics (RSM) -:: Last Updated for Version: 5.5.0 -:: Date of the Last Update: 2015-09-01 -:: -:: Q u a n t u m L e a P s -:: --------------------------- -:: innovating embedded systems -:: -:: Copyright (C) Quantum Leaps, LLC. All rights reserved. -:: -:: This program is open source software: you can redistribute it and/or -:: modify it under the terms of the GNU General Public License as published -:: by the Free Software Foundation, either version 3 of the License, or -:: (at your option) any later version. -:: -:: Alternatively, this program may be distributed and modified under the -:: terms of Quantum Leaps commercial licenses, which expressly supersede -:: the GNU General Public License and are specifically designed for -:: licensees interested in retaining the proprietary status of their code. -:: -:: This program is distributed in the hope that it will be useful, -:: but WITHOUT ANY WARRANTY; without even the implied warranty of -:: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -:: GNU General Public License for more details. -:: -:: You should have received a copy of the GNU General Public License -:: along with this program. If not, see . -:: -:: Contact information: -:: https://state-machine.com -:: mailto:info@state-machine.com -:: ========================================================================== -setlocal - -set RCMHOME="C:\tools\MSquared\M2 RSM" - -set RSM_OUTPUT=qpc_metrics.txt -set RSM_INPUT=..\include\*.h ..\source\*.h ..\source\*.c - -%RCMHOME%\rsm.exe -fd -n -xNOCOMMAND -xNOCONFIG -u"File cfg rsm_qpc.cfg" %RSM_INPUT% > %RSM_OUTPUT% - -endlocal diff --git a/doxygen/rsm_qpc.cfg b/doxygen/rsm_qpc.cfg deleted file mode 100644 index 313f0899..00000000 --- a/doxygen/rsm_qpc.cfg +++ /dev/null @@ -1,637 +0,0 @@ -# ========================================================================== -# Product: Configuration file for MSquared Resource Standard Metrics (RSM) -# Last Updated for Version: 5.2.0 -# Date of the Last Update: Dec 20, 2013 -# -# Q u a n t u m L e a P s -# --------------------------- -# innovating embedded systems -# -# Copyright (C) 2002-2013 Quantum Leaps, LLC. All rights reserved. -# -# This program is open source software: you can redistribute it and/or -# modify it under the terms of the GNU General Public License as published -# by the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# Alternatively, this program may be distributed and modified under the -# terms of Quantum Leaps commercial licenses, which expressly supersede -# the GNU General Public License and are specifically designed for -# licensees interested in retaining the proprietary status of their code. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . -# -# Contact information: -# Quantum Leaps Web sites: http://www.quantum-leaps.com -# http://www.state-machine.com -# e-mail: info@quantum-leaps.com -# ========================================================================== - -#################################################################### -# RSM Operational Configuration #################################### - -# Company Specific Header -# This line will appear at the top of all reports -# Typical uses include copyrights, security and project markings -# You must specify both a text version for text and csv reports -# and an HTML version. -Report Header Active : No -Report Header Text Line : Standard Metrics Report -Report Header HTML Line :           Standard Metrics Report - -# Enable user defined configuration files. -# The file rsm.cfg is read from the location of the rsm.lic file. -# This file can enable this option to allow users to override the -# operational configuration of RSM. This option is enabled by the -# end user with the -u "File cfg path\file" option -Enable user defined configuration files : Yes - -# Windows 9x and DOS are case insensitive file systems. -# Files like foo.c and foo.C are seen as C source files. -# If *.C files are C++ files under these operating systems -# or you are operating on NT or UNIX set this option to -# case sensitivity equal to Yes. -Source file names are case sensitive : No - -# Show a progress indicator when processing files and -# code differentials. -Show progress indicator : Yes -Detailed Progress Showing File Names : Yes - -# Number of files which comprise a status marker when -# status is indicated during lengthy operations. -Progress status interval number of files: 10 - -# Show file dates when displaying file metrics. -Show file date and size : No - -# RSM will process only files with the following extensions. -# The user may add to this list, but RSM is designed to process -# only the C, C++, C# and Java languages. -Validate file extensions for processing : Yes - -# Specify the extensions for each type of supported language. -# Files extensions are separated by commas and are case sensitive -# if case sensitivity is specified in this file (comma separated,no spaces). -C File Extensions : c -C Header File Extensions : h -C++ File Extensions : cc,cpp,cxx,h,hh,H,hxx -C++ Header File Extensions : h,hh,H,hxx -C# File Extensions : cs -Java File Extensions : java -# Other files are not officially supported by RSM -# but lines will be counted as LOC -Other File Extensions : - -# When analyzing *.h files, treat header files as -# both C and C++. If you use separate extensions for C++ and -# C header files, then set this option to No. -Treat C headers as C++ : Yes - -# RSM will not process files when the path/file name contains -# a pattern in the pattern list (comma separated,no spaces). -Pattern Filter Active : No -Pattern Filter : .designer.c - -# RSM Code skip strings allow the RSM parser to skip -# processing of all code between the start and stop -# tokens. This is useful for machine generated code. -# Code tokens are unique in the could base and if -# found on a code line the rsm processing will be effected. -# Start and stop tokens must match within a file and -# cannot span files. A token cannot contain spaces and -# must be alphnumeric and can contain the underscore. -# Quality skip tokens turn off just quality notice checking. -# i.e. // RSM_IGNORE_BEGIN -# some code .... -# // RSM_IGNORE_END -RSM Code Skip Start Token : RSM_IGNORE_BEGIN -RSM Code Skip End Token : RSM_IGNORE_END -RSM Code Quality Skip Start Token : RSM_IGNORE_QUALITY_BEGIN -RSM Code Quality Skip End Token : RSM_IGNORE_QUALITY_END -Activate RSM code skip tokens : Yes - -# RSM will not process files in local directories when this -# flag is set. This will prevent recursive descent into -# these directories (comma separated,no spaces). -Do not process these local directories : No -Local directory names not processed : test,sccs,cvs,rcs,svn - -# Names in reports include file, namespace or package, class -# and function names. These names can get quite long and will -# extend beyond the report right margin. This setting will -# wrap the name to the report right margin. -Wrap long names in reports : Yes - -#################################################################### -# RSM Configuration for Baseline Metrics Differentials ############# - -# The following path location specifies where work files -# are to be created. The path must be a location with write -# permissions. RSM will create work files in the current -# directory if no path is specified. -Work file location path : - -# When processing code line differentials, ignore -# blank line changes in the code. -Ignore code differential blank lines : Yes - -# When processing code line differentials, ignore -# blanks and tab changes in the code. -Ignore code differential white space : Yes - -# Maximum number of lines in a file when using Longest Common Sequence -# differential algorithm. This value establishes the line to line -# comparison matrix size. This value has been set to the maximum allowed -# under 32 bit operating systems. It is not advised to make this value > -# than 10000. If you have a machine with very low physical memory you may -# want to use a value of 6000 to 7000 where 10000 should be a maximum. -# When file lengths exceed the matrix limits, the file is segmented to fit -# the matrix size. -Maximum LCS file size, number of lines : 10000 - -# Code differential metrics determine lines that are -# different in the current baseline compared to the -# older baseline. This metric can include -# lines that are removed from the current baseline. -Add removed older lines as modified : No - -# When showing differential details for each file -# using the switch -ws -Show equal lines : Yes -Show lines removed from older file : Yes -Show lines added (mod) to newer file : Yes - -# The following parameter, when set to Yes will cause -# the files stored into work files to be relative to the -# location specified by the -w"create top_dir", baseline -# top directory. -Relative Work Files : Yes - -# User defined productivity values for determining works -# rates for baseline metric differentials. -Work Seconds per Hour : 3600 -Work Hours per Shift : 8 -Work Shifts per Day : 1 -Work Days per Week : 5 -Work Hours per Man Day : 8 -Work Hours per Man Week : 40 -Work Hours per Man Month : 160 -Work Hours per Man Year : 1960 - -##################################################################### -# Function point conversion factors for LOC metrics -# -Header File Function Points per LOC : 0 -Header File Function Points per eLOC : 0 -Header File Function Points per lLOC : 0 -C File Function Points per LOC : 128 -C File Function Points per eLOC : 128 -C File Function Points per lLOC : 128 -C++ File Function Points per LOC : 53 -C++ File Function Points per eLOC : 53 -C++ File Function Points per lLOC : 53 -Java File Function Points per LOC : 53 -Java File Function Points per eLOC : 53 -Java File Function Points per lLOC : 53 -C# File Function Points per LOC : 53 -C# File Function Points per eLOC : 53 -C# File Function Points per lLOC : 53 -Other File Function Points per LOC : 0 -Other File Function Points per eLOC : 0 -Other File Function Points per lLOC : 0 - -#################################################################### -# RSM Configuration for cyclomatic complexity ###################### -# -# McCabe Cyclomatic Complexity includes the following constructs in -# the calculation. -# function call + if + inline if + while + for + foreach -# case + goto + logical or + Logical and -# -# You may tailor the cyclomatic complexity calculation to meet your -# specific requirements. - -Include 'function call' in cyclomatic complexity: Yes -Include 'while' in cyclomatic complexity : Yes -Include 'for' in cyclomatic complexity : Yes -Include 'switch' in cyclomatic complexity : No -Include 'case' in cyclomatic complexity : Yes -Include 'if' in cyclomatic complexity : Yes -Include 'else' in cyclomatic complexity : No -Include '?' inlined if in cyclomatic complexity : Yes -Include 'goto' in cyclomatic complexity : Yes -Include '||' or 'or' in cyclomatic complexity : Yes -Include '&&' or 'and' in cyclomatic complexity : Yes - -#################################################################### -# RSM Quality Notices Configuration ################################ - -# User Defined Quality Notices UDQN -# Specify the file name which contains the UDQN definitions -# See this provided example for a tutorial on UDQN. -RSM user defined quality notice file : rsm_udqn.cfg - -# Re-order the quality notice format so that if a line number -# is emitted, the line number precedes the notice number. This -# option enables code editors to parse the notice line. -Reorder notice, line in quality notices : No - -# RSM Quality Notices For Code Style ################################### - -# Quality Notice No. 1 -# Emit a quality notice when the physical line length -# is greater than the specified number of characters. -Quality Notice 1 : Yes -Maximum Line Length : 80 - -# Quality Notice No. 2 -# Emit a quality notice when the function name length -# is greater than the specified number of characters. -Quality Notice 2 : Yes -Maximum Function Name Length : 32 - -# Quality Notice No. 21 -# Emit a quality notice when a file does not contain -# the specified key string. -Quality Notice 21 : No -RSM KEY String : - -# RSM Quality Notices For Stability and Maintainability ################ - -# Quality Notice No. 3 -# Emit a quality notice when ellipsis '...' are identified -# within a functions parameter list thus enabling variable -# arguments. -Quality Notice 3 : Yes - -# Quality Notice No. 4 -# Emit a quality notice if there exists an assignment -# operator '=' within a logical 'if' condition. -Quality Notice 4 : Yes - -# Quality Notice No. 5 -# Emit a quality notice if there exists an assignment -# operator '=' within a logical 'while' condition. -Quality Notice 5 : Yes - -# Quality Notice No. 6 -# Emit a quality notice when a pre-decrement operator '--' -# is identified within the code. -Quality Notice 6 : No - -# Quality Notice No. 7 -# Emit a quality notice when a pre-increment operator '++' -# is identified within the code. -Quality Notice 7 : No - -# Quality Notice No. 8 -# Emit a quality notice when the 'realloc' function -# is identified within the code. -Quality Notice 8 : Yes - -# Quality Notice No. 9 -# Emit a quality notice when the 'goto' function -# is identified within the code. -Quality Notice 9 : Yes - -# Quality Notice No. 10 -# Emit a quality notice when the Non-ANSI function -# prototype is identified within the code. -Quality Notice 10 : Yes - -# Quality Notice No. 11 -# Emit a quality notice when open and closed brackets -# '[ ]' are not balance within a file. -Quality Notice 11 : Yes - -# Quality Notice No. 12 -# Emit a quality notice when open and closed parenthesis -# '()' are not balance within a file. -Quality Notice 12 : Yes - -# Quality Notice No. 13 -# Emit a quality notice when a 'switch' statement does -# not have a 'default' condition. -Quality Notice 13 : Yes - -# Quality Notice No. 14 -# Emit a quality notice when there are more 'case' conditions -# than 'break' statements or 'fall through' comments. -Use default in case/break comparison : Yes -Quality Notice 14 : Yes - -# Quality Notice No. 15 -# Emit a quality notice when a friend class -# is identified within the code. -Quality Notice 15 : Yes - -# Quality Notice No. 22 -# Emit a quality notice when each if, else, for -# or while is not bound by scope. -Quality Notice 22 : Yes - -# Quality Notice No. 23 -# Emit a quality notice when the '?' or the implied -# if-then-else construct has been identified. -Quality Notice 23 : Yes - -# Quality Notice No. 24 -# Emit a quality notice when an ANSI C++ keyword -# is identified within a *.c or a *.h file. -Quality Notice 24 : Yes - -# Quality Notice No. 26 -# Emit a quality notice when a void * is identified -# within a source file. -Quality Notice 26 : No - -# Quality Notice No. 27 -# Emit a quality notice when the number of function -# return points is greater than the specified maximum. -Quality Notice 27 : Yes -Maximum functional return points : 1 -Count goto as a function return point : Yes - -# Quality Notice No. 28 -# Emit a quality notice when the cyclomatic complexity -# of a function exceeds the specified maximum. -Quality Notice 28 : Yes -Maximum functional cyclomatic complexity: 10 - -# Quality Notice No. 29 -# Emit a quality notice when the number of function -# input parameters exceeds the specified maximum. -Quality Notice 29 : Yes -Maximum functional interface complexity : 6 - -# Quality Notice No. 49 -# Emit a quality notice when function parameters -# are blank or not specified, thus requiring void. -Quality Notice 49 : Yes - -# Quality Notice No. 30 -# Emit a quality notice when a TAB character is identified -# within the source code. Indentation with TAB will create -# editor and device dependent formatting. -Quality Notice 30 : Yes - -# Quality Notice No. 32 -# Emit a quality notice when 'using namespace' -# has been identified in a C++ source file. -Quality Notice 32 : Yes - -# Quality Notice No. 33 -# Emit a quality notice when a class/struct definition -# is identified within a function definition. -Quality Notice 33 : Yes - -# Quality Notice No. 34 -# Emit a quality notice when a class definition -# contains a pointer to a data item. -Quality Notice 34 : Yes - -# Quality Notice No. 35 -# Emit a quality notice when a class definition -# contains public data. -Quality Notice 35 : Yes - -# Reference Quality Notice No. 35 -# Ignore public data for specific types of data -Ignore public event data : Yes -Ignore public const data : Yes -Ignore public delegate data : Yes - -# Quality Notice No. 36 -# Emit a quality notice when a class definition -# contains protected data. -Quality Notice 36 : Yes - -# Quality Notice No. 37 -# Emit a quality notice when a base class, with virtual -# functions, does not contain a virtual destructor. -Quality Notice 37 : Yes - -# Quality Notice No. 38 -# Emit a quality notice when exception handling is -# present within a function. -Quality Notice 38 : Yes - -# Quality Notice No. 39 -# Emit a quality notice when the number of class/struct methods -# exceed the specified maximum (public, protected and private). -Quality Notice 39 : Yes -Maximum number of methods per class : 100 - -# Quality Notice No. 40 -# Emit a quality notice when the depth of the inheritance -# tree exceeds the specified maximum value. -Quality Notice 40 : Yes -Maximum depth of inheritance tree : 4 - -# Quality Notice No. 41 -# Emit a quality notice when the number of direct derived -# classes exceeds the specified maximum value. -Quality Notice 41 : Yes -Maximum number of derived child classes : 10 - -# Quality Notice No. 42 -# Emit a quality notice when the multiple inheritance -# has been identified. -Quality Notice 42 : Yes - -# Quality Notice No. 43 -# Emit a quality notice when the keyword 'continue' -# has been identified. -Quality Notice 43 : Yes - -# Quality Notice No. 44 -# Emit a quality notice when the keyword 'break' -# has been identified outside a 'switch' logic -# control structure. -Quality Notice 44 : Yes - -# Quality Notice No. 45 -# Emit a quality notice when a file does not -# have equal counts of new and delete. -Quality Notice 45 : Yes - -# Quality Notice No. 50 -# Emit a quality notice when a variable is assigned -# to a literal number and not a symbolic constant. -Quality Notice 50 : No -Include zero (0) as literal assignment : No - -# Quality Notice No. 55 -# Emit a quality notice when the depth of scope -# exceeds the specified maximum value. This condition -# indicates complex logic and/or a maintenance concern. -Quality Notice 55 : Yes -Maximum depth of scope : 6 - -# Quality Notice No. 56 -# Emit a quality notice when sequential breaks are -# identified without a respective case statement. -Quality Notice 56 : Yes - -# RSM Quality Notices for Functional/Struct and Class Content ########## - -# Minimum LOC for content analysis for blank lines -# comments, and white space. -Min. Function LOC for content analysis : 5 -Min. Class/Struct LOC content analysis : 10 - -# Quality Notice No. 16 -# Emit a quality notice when function, struct, class -# or interface white space percentage is less than -# the specified minimum. -Quality Notice 16 : Yes -Minimum Function Whitespace Percent : 10.00 - -# Quality Notice No. 17 -# Emit a quality notice when function comment line -# percentage is less than the specified minimum. -Quality Notice 17 : No -Minimum Function Comment Line Percent : 10.00 - -# Quality Notice No. 18 -# Emit a quality notice when the eLOC within a -# function exceeds the specified maximum. -Quality Notice 18 : Yes -Maximum Function eLOC : 200 - -# Quality Notice No. 48 -# Emit a quality notice when the lLOC within a -# function does not meet the specified minimum. -# This notice serves to find nop functions. -Quality Notice 48 : Yes -Minimum Function lLOC : 0 - -# Quality Notice No. 31 -# Emit a quality notice when class/struct comment line -# percentage is less than the specified minimum. -Quality Notice 31 : Yes -Minimum Class/Struct Comment Percent : 10.00 - -# Quality Notice No. 46 -# Emit a quality notice when function, struct, class -# or interface blank line percentage is less than the -# specified minimum. -Quality Notice 46 : No -Minimum Function Blank Line Percent : 10.00 - -# Quality Notice No. 51 -# Emit a quality notice when a function -# does not have a preceding comment. -Quality Notice 51 : Yes - -# Quality Notice No. 52 -# Emit a quality notice when a class -# does not have a preceding comment. -Quality Notice 52 : Yes - -# Quality Notice No. 53 -# Emit a quality notice when a struct -# does not have a preceding comment. -Quality Notice 53 : Yes - -# Quality Notice No. 54 -# Emit a quality notice when a interface -# does not have a preceding comment. -Quality Notice 54 : Yes - -# RSM Quality Notices for File Content # - -# Quality Notice No. 19 -# Emit a quality notice when file white space -# percentage is less than the specified minimum. -# Consider setting Notice 30 to No. -Quality Notice 19 : Yes -Minimum File Whitespace Percent : 10.00 -A TAB is equivalent to n space : 2 - -# Quality Notice No. 20 -# Emit a quality notice when file comment line -# percentage is less than the specified minimum. -Quality Notice 20 : Yes -Minimum File Comment Line Percent : 10.00 - -# Quality Notice No. 47 -# Emit a quality notice when file blank line -# percentage is less than the specified minimum. -Quality Notice 47 : No -Minimum File Blank Line Percent : 10.00 - -# Quality Notice No. 57 -# Emit a quality notice when RSM skip lines conditions -# are met by a matching token. -Quality Notice 57 : No - -# Quality Notice No. 58 -# Emit a quality notice when RSM skip quality notice conditions -# are met by a matching token. -Quality Notice 58 : No - -# RSM Quality Notices Miscellaneous #################################### - -# Quality Notice No. 25 -# Deprecated in Version 6.70 -# See settings under language extensions. - -#################################################################### -# Code Listing Report Configuration ################################ - -# The following parameters setup source code printing. -# These values become the default settings. -Printed Line Length : 80 -Printed Page Length : 55 -Printed Left Margin : 5 -Printed Top Margin : 1 -Printed Page Header : RSM Code Listing -Page breaks in code print format : No - -#################################################################### -# HTML Report and Color Configuration ############################## - -# The following parameters setup HTML report output. The hyperlinks -# for source code can be either absolute or relative. -Relative HTML Links : No - -# The following color parameters modify the HTML report -# output. Colors can be specified as Hex or Name. -# Blank color parameters will result to the browser default. -HTML RSM Color : #0000FF -HTML Date Color : #0000FF -HTML Text Color : #000000 -HTML VLink Color : #660099 -HTML Link Color : #0000EE -HTML Background Color : #F8F8F8 -HTML Error Color : #FF0000 -HTML Line Color : #003399 -HTML Old File Differential Color : #CC0033 -HTML New File Differential Color : #336666 -HTML File Name Color : #0000FF -HTML Function Color : #0000FF -HTML Function Parameter Color : #006600 -HTML Template Color : #006699 -HTML Macro Color : #33CCFF -HTML Class Color : #663300 -HTML Inheritance Color : #FF3300 -HTML Struct Color : #990000 -HTML Notice Color : #CC0000 -HTML Header Color : #993300 -HTML New Code Differential Color : #3366CC -HTML Removed Code Differential Color : #FF0000 -HTML Modified Code Differential Color : #993300 -HTML Equal Code Differential Color : #00CC00 -HTML Total Color : #993300 -HTML Inheritance Depth Color : #333300 -HTML Inheritance Child Color : #CC6600 -#################################################################### -# end of rsm.cfg diff --git a/doxygen/snippets/qa_run.c b/doxygen/snippets/qa_run.c deleted file mode 100644 index ae88fee1..00000000 --- a/doxygen/snippets/qa_run.c +++ /dev/null @@ -1,16 +0,0 @@ -/* thread routine for Win32 _beginthread() */ -static void __cdecl run(void *me) { /* the exact signature for _beginthread */ - do { - QEvt const *e; - - QACTIVE_GET_((QActive *)me, e); /* wait for the event */ - QF_ACTIVE_DISPATCH_(me, e); /* dispatch to the active object's SM */ - QF_gc(e); /* check if the event is garbage, and collect it if so */ - - } while (((QActive *)me)->prio > (uint8_t)0); - - QActive_unsubscribeAll((QActive *)me); /* unsubscribe from all signals */ - QActive_unregister_((QActive *)me); /* un-register this active object */ - - _endthread(); /* cleanup after the thead and close the thread handle */ -} diff --git a/doxygen/snippets/qep_qevt.c b/doxygen/snippets/qep_qevt.c deleted file mode 100644 index 06c42913..00000000 --- a/doxygen/snippets/qep_qevt.c +++ /dev/null @@ -1,4 +0,0 @@ -typedef struct { - QEvt super; /* inherits QEvt */ - uint8_t keyId; /* ID of the key depressed */ -} CalcEvt; diff --git a/doxygen/snippets/qep_qfsm_ctor.c b/doxygen/snippets/qep_qfsm_ctor.c deleted file mode 100644 index 1d3c81d9..00000000 --- a/doxygen/snippets/qep_qfsm_ctor.c +++ /dev/null @@ -1,8 +0,0 @@ -void Bomb_ctor(Bomb * const me) { - /* superclass' ctor */ - QFsm_ctor(&me->super, Q_STATE_CAST(&Bomb_initial)); - - me->timeout = 0U; - me->defuse = 0U; - me->code = 0U; -} diff --git a/doxygen/snippets/qep_qfsm_use.c b/doxygen/snippets/qep_qfsm_use.c deleted file mode 100644 index 277f6983..00000000 --- a/doxygen/snippets/qep_qfsm_use.c +++ /dev/null @@ -1,21 +0,0 @@ -#include "qpc.h" /* QP/C public interface */ -#include "bomb.h" /* Bomb derived from QHsm */ - -Q_DEFINE_THIS_FILE - -static Bomb l_bomb; /* an instance of Bomb HSM */ - -int main() { - Bomb_ctor(&l_bomb); /* Bomb "constructor" invokes QFsm_ctor() */ - - QHSM_INIT(&l_bomb.super, (QEvt *)0); /* trigger initial transition */ - - for (;;) { /* event loop */ - QEvt e; - . . . - /* wait for the next event and assign it to the event object e */ - . . . - QHSM_DISPATCH(&l_bomb.super, &e); /* dispatch e */ - } - return 0; /* never reached, needed for some compilers */ -} diff --git a/doxygen/snippets/qep_qhist.c b/doxygen/snippets/qep_qhist.c deleted file mode 100644 index c9e6d246..00000000 --- a/doxygen/snippets/qep_qhist.c +++ /dev/null @@ -1,39 +0,0 @@ -typedef struct { - QHsm super; /* inherit QHsm */ - - QStateHandler hist_doorClosed; /* history of doorClosed */ -} ToastOven; - -/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~.*/ -static QState ToastOven_doorClosed(ToastOven * const me, - QEvt const * const e) -{ - QState status; - switch (e->sig) { - ~ ~ ~ - case Q_EXIT_SIG: { - me->hist_doorClosed = QHsm_state(&me->super); - status = Q_HANDLED(); - break; - } - } - return status; -} -/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~.*/ -static QState ToastOven_doorOpen(ToastOven * const me, - QEvt const * const e) -{ - QState status; - switch (e->sig) { - ~ ~ ~ - case CLOSE_SIG: { - status = Q_TRAN_HIST(hist_doorClosed); /*<--- */ - break; - } - default: { - status = Q_SUPER(&QHsm_top); - break; - } - } - return status; -} diff --git a/doxygen/snippets/qep_qhsm.c b/doxygen/snippets/qep_qhsm.c deleted file mode 100644 index 9c34f851..00000000 --- a/doxygen/snippets/qep_qhsm.c +++ /dev/null @@ -1,9 +0,0 @@ -typedef struct { - QHsm super; /* inhertits QHsm */ - - double operand1; - double operand2; - char display[DISP_WIDTH + 1]; - uint8_t len; - uint8_t opKey; -} Calc; diff --git a/doxygen/snippets/qep_qhsm_ctor.c b/doxygen/snippets/qep_qhsm_ctor.c deleted file mode 100644 index 63681bd8..00000000 --- a/doxygen/snippets/qep_qhsm_ctor.c +++ /dev/null @@ -1,9 +0,0 @@ -void Calc_ctor(Calc * const me) { - /* superclass' ctor */ - QHsm_ctor(&me->super, Q_STATE_CAST(&Calc_initial)); - - me->operand1 = 0.0; - me->operand2 = 0.0; - me->len = 0U; - me->opKey = 0U; -} diff --git a/doxygen/snippets/qep_qhsm_use.c b/doxygen/snippets/qep_qhsm_use.c deleted file mode 100644 index 569f02a6..00000000 --- a/doxygen/snippets/qep_qhsm_use.c +++ /dev/null @@ -1,21 +0,0 @@ -#include "qpc.h" /* QP/C public interface */ -#include "calc.h" /* Calc derived from QHsm */ - -Q_DEFINE_THIS_FILE - -static Calc Calc_inst; /* an instance of Calc SM */ - -int main() { - Calc_ctor(&Calc_inst); /* Calc "constructor" invokes QHsm_ctor() */ - - QHSM_INIT(&Calc_inst.super, (QEvt *)0); /* trigger initial transition */ - - for (;;) { /* event loop */ - QEvt e; - . . . - /* wait for the next event and assign it to the event object e */ - . . . - QHSM_DISPATCH(&Calc_inst.super, &e); /* dispatch e */ - } - return 0; -} diff --git a/doxygen/snippets/qep_qinit.c b/doxygen/snippets/qep_qinit.c deleted file mode 100644 index 533045f9..00000000 --- a/doxygen/snippets/qep_qinit.c +++ /dev/null @@ -1,29 +0,0 @@ -/* initial pseudostate of the Bomb FSM ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ -QState Bomb_initial(Bomb * const me, QEvt const * const e) { - Q_REQUIRE(e != (QEvt *)0); /* initialization event expected */ - Bomb_updateState(me, "top-INIT"); - me->timeout = INIT_TIMEOUT; - me->defuse = Q_EVT_CAST(BombInitEvt)->defuse; - - return Q_TRAN(&Bomb_setting); /* <--- initial transition */ -} - -/* state handler function for the Calc HSM ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~..*/ -QState Calc_on(Calc * const me, QEvt const * const e) { - QState status; - switch (e->sig) { - . . . - case Q_INIT_SIG: { - QCalc_updateState(me, "on-INIT"); - status = Q_TRAN(&Calc_ready); /* initial transition */ - break; - } - . . . - default: { - status = Q_SUPER(&QHsm_top); - break; - } - } - return status; -} - diff --git a/doxygen/snippets/qep_qmsm.c b/doxygen/snippets/qep_qmsm.c deleted file mode 100644 index 77610c0a..00000000 --- a/doxygen/snippets/qep_qmsm.c +++ /dev/null @@ -1,9 +0,0 @@ -typedef struct { - QMsm super; /* inherits QMsm */ - - double operand1; - double operand2; - char display[DISP_WIDTH + 1]; - uint8_t len; - uint8_t opKey; -} Calc; diff --git a/doxygen/snippets/qep_qmsm_ctor.c b/doxygen/snippets/qep_qmsm_ctor.c deleted file mode 100644 index 1a37de9a..00000000 --- a/doxygen/snippets/qep_qmsm_ctor.c +++ /dev/null @@ -1,9 +0,0 @@ -void Calc_ctor(Calc * const me) { - /* superclass' ctor */ - QMsm_ctor(&me->super, Q_STATE_CAST(&Calc_initial)); - - me->operand1 = 0.0; - me->operand2 = 0.0; - me->len = 0U; - me->opKey = 0U; -} diff --git a/doxygen/snippets/qep_qmsm_use.c b/doxygen/snippets/qep_qmsm_use.c deleted file mode 100644 index a32d619b..00000000 --- a/doxygen/snippets/qep_qmsm_use.c +++ /dev/null @@ -1,21 +0,0 @@ -#include "qpc.h" /* QP/C public interface */ -#include "calc.h" /* Calc derived from QMsm */ - -Q_DEFINE_THIS_FILE - -static Calc Calc_inst; /* an instance of Calc SM */ - -int main() { - Calc_ctor(&Calc_inst); /* Calc "constructor" invokes QMsm_ctor() */ - - QHSM_INIT(&Calc_inst.super, (void *)0, 0U); /* trigger initial transition */ - - for (;;) { /* event loop */ - QEvt e; - . . . - /* wait for the next event and assign it to the event object e */ - . . . - QHSM_DISPATCH(&Calc_inst.super, &e, 0U); /* dispatch e */ - } - return 0; /* never reached, needed for some compilers */ -} diff --git a/doxygen/snippets/qep_qsuper.c b/doxygen/snippets/qep_qsuper.c deleted file mode 100644 index 7c7d4549..00000000 --- a/doxygen/snippets/qep_qsuper.c +++ /dev/null @@ -1,20 +0,0 @@ -QState Blinky_off(Blinky * const me, QEvt const * const e) { - QState status; - switch (e->sig) { - case Q_ENTRY_SIG: { - BSP_ledOff(); - status = Q_HANDLED(); - break; - } - case TIMEOUT_SIG: { - status = Q_TRAN(&Blinky_on); - break; - } - default: { - status = Q_SUPER(&QHsm_top); /*<--- */ - break; - } - } - return status; -} - diff --git a/doxygen/snippets/qep_qtran.c b/doxygen/snippets/qep_qtran.c deleted file mode 100644 index 4b3974e4..00000000 --- a/doxygen/snippets/qep_qtran.c +++ /dev/null @@ -1,20 +0,0 @@ -QState Blinky_off(Blinky * const me, QEvt const * const e) { - QState status; - switch (e->sig) { - case Q_ENTRY_SIG: { - BSP_ledOff(); - status = Q_HANDLED(); - break; - } - case TIMEOUT_SIG: { - status = Q_TRAN(&Blinky_on); /*<--- */ - break; - } - default: { - status = Q_SUPER(&QHsm_top); - break; - } - } - return status; -} - diff --git a/doxygen/snippets/qf_ctor.c b/doxygen/snippets/qf_ctor.c deleted file mode 100644 index fec597f1..00000000 --- a/doxygen/snippets/qf_ctor.c +++ /dev/null @@ -1,4 +0,0 @@ -void Philo_ctor(Philo * const me) { - QActive_ctor(&me->super, Q_STATE_CAST(&Philo_initial)); - QTimeEvt_ctorX(&me->timeEvt, me, (enum_t)TIMEOUT_SIG, 0U); -} diff --git a/doxygen/snippets/qf_main.c b/doxygen/snippets/qf_main.c deleted file mode 100644 index b4518fc7..00000000 --- a/doxygen/snippets/qf_main.c +++ /dev/null @@ -1,44 +0,0 @@ -#include "qpc.h" -#include "dpp.h" -#include "bsp.h" - -Q_DEFINE_THIS_FILE - -int main(void) { - - QF_init(); /* initialize the framework and the underlying RT kernel */ - BSP_init(); /* initialize the BSP */ - - /* initialize publish-subscribe~~~ */ - static QSubscrList l_subscrSto[MAX_PUB_SIG]; - QF_psInit(l_subscrSto, Q_DIM(l_subscrSto)); - - /* initialize event pools~~~ */ - static QF_MPOOL_EL(TableEvt) l_smlPoolSto[2*N_PHILO]; /* small pool */ - QF_poolInit(l_smlPoolSto, sizeof(l_smlPoolSto), sizeof(l_smlPoolSto[0])); - - /* start the active objects~~~ */ - Philo_ctor(); /* instantiate all Philosopher active objects */ - - static QEvt const *l_philoQueueSto[N_PHILO][N_PHILO]; - for (uint8_t n = 0U; n < N_PHILO; ++n) { - QACTIVE_START(AO_Philo[n], - Q_PRIO(n + 1U, N_PHILO), /* QF-priority/preemption-threshold */ - l_philoQueueSto[n], /* event queue storage */ - Q_DIM(l_philoQueueSto[n]),/* event queue length [events] */ - (void *)0, /* stack storage (not used) */ - 0U, /* stack size [bytes] (not used) */ - (void *)0); /* initialization parameter (not used) */ - } - - Table_ctor(); /* instantiate the Table active object */ - - static QEvt const *l_tableQueueSto[N_PHILO]; - QACTIVE_START(AO_Table, - N_PHILO + 1U , /* QF-priority/preemption-threshold */ - l_tableQueueSto, Q_DIM(l_tableQueueSto), - (void *)0, 0U, - (void *)0); - - return QF_run(); /* run the QF application, QF_run() does not return */ -} diff --git a/doxygen/snippets/qf_oncontextsw.c b/doxygen/snippets/qf_oncontextsw.c deleted file mode 100644 index 9a0eab9a..00000000 --- a/doxygen/snippets/qf_oncontextsw.c +++ /dev/null @@ -1,17 +0,0 @@ -#ifdef QF_ON_CONTEXT_SW - -/* NOTE: the context-switch callback is called with interrupts DISABLED */ -void QF_onContextSw(QActive *prev, QActive *next) { - (void)prev; - if (next != (QActive *)0) { /* next is not the idle thread? */ - _impure_ptr = next->thread; /* switch to next TLS */ - } - - /* If you use QS software tracing, use the _NOCRIT() begin/end */ - QS_BEGIN_NOCRIT(CONTEXT_SW, 0U) - QS_OBJ(prev); - QS_OBJ(next); - QS_END_NOCRIT() -} - -#endif /* QF_ON_CONTEXT_SW */ diff --git a/doxygen/snippets/qf_post.c b/doxygen/snippets/qf_post.c deleted file mode 100644 index b953da2a..00000000 --- a/doxygen/snippets/qf_post.c +++ /dev/null @@ -1,20 +0,0 @@ -extern QActive * const AO_Table; - -QState Philoso_hungry(Philo * const me, QEvt const * const e) { - QState status; - switch (e->sig) { - case Q_ENTRY_SIG: { - TableEvt *pe = Q_NEW(TableEvt, HUNGRY_SIG); /* dynamic alloc */ - pe->philNum = me->num; - QACTIVE_POST(AO_Table, &pe->super, me); /* <--- */ - status = Q_HANDLED(); - break; - } - . . . - default: { - status = Q_SUPER(&QHsm_top); - break; - } - } - return status; -} diff --git a/doxygen/snippets/qf_postx.c b/doxygen/snippets/qf_postx.c deleted file mode 100644 index c70ca3b3..00000000 --- a/doxygen/snippets/qf_postx.c +++ /dev/null @@ -1,11 +0,0 @@ -extern QActive * const AO_Table; - - . . . - /* typically inside a state machine action */ - TableEvt *pe; - Q_NEW_X(pe, TableEvt, 5U, HUNGRY_SIG); /* dynamic alloc, margin==5 */ - if (pe != (TableEvt *)0) { - pe->philNum = me->num; - QACTIVE_POST_X(AO_Table, &pe->super, 3U, me); /* <--- */ - } - . . . diff --git a/doxygen/snippets/qf_qactive.c b/doxygen/snippets/qf_qactive.c deleted file mode 100644 index b4369e38..00000000 --- a/doxygen/snippets/qf_qactive.c +++ /dev/null @@ -1,14 +0,0 @@ -typedef struct { - QActive super; /* inherits QActive */ - - QTimeEvt timeEvt; /* to timeout the blinking */ -} Blinky; -. . . - -void Blinky_ctor(Blinky * const me) { - /* constructor of the superclass <--- */ - QActive_ctor(&me->super, Q_STATE_CAST(&Blinky_initial)); - - /* constructor(s) of the members */ - QTimeEvt_ctorX(&me->timeEvt, &me->super, TIMEOUT_SIG, 0U); -} diff --git a/doxygen/snippets/qf_qmactive.c b/doxygen/snippets/qf_qmactive.c deleted file mode 100644 index c61f6d68..00000000 --- a/doxygen/snippets/qf_qmactive.c +++ /dev/null @@ -1,14 +0,0 @@ -typedef struct { - QMActive super; /* inherits QMActive */ - - QTimeEvt timeEvt; /* to timeout the blinking */ -} Blinky; -. . . - -void Blinky_ctor(Blinky * const me) { - /* constructor of the superclass <--- */ - QMActive_ctor(&me->super, Q_STATE_CAST(&Blinky_initial)); - - /* constructor(s) of the members */ - QTimeEvt_ctorX(&me->timeEvt, &me->super, TIMEOUT_SIG, 0U); -} diff --git a/doxygen/snippets/qf_start.c b/doxygen/snippets/qf_start.c deleted file mode 100644 index 49f0f06f..00000000 --- a/doxygen/snippets/qf_start.c +++ /dev/null @@ -1,25 +0,0 @@ -#include "qpc.h" - -Q_DEFINE_THIS_FILE - -int main() { - - QF_init(); /* initialize the framework and the underlying RT kernel */ - BSP_init(); /* initialize the Board Support Package */ - - . . . - - /* instantiate and start the active objects~~~ */ - Blinky_ctor(); - static QEvt const *l_blinkyQSto[10]; /* Event queue storage for Blinky */ - QACTIVE_START(AO_Blinky, /* AO pointer to start */ - 1U, /* unique QP priority of the AO */ - l_blinkyQSto, /* storage for the AO's queue */ - Q_DIM(l_blinkyQSto), /* lenght of the queue [entries] */ - (void *)0, /* stack storage (not used in QK) */ - 0U, /* stack size [bytes] (not used in QK) */ - (void *)0); /* initialization parameter (or 0) */ - . . . - return QF_run(); /* run the QF application */ -} - \ No newline at end of file diff --git a/doxygen/snippets/qf_state.c b/doxygen/snippets/qf_state.c deleted file mode 100644 index be2e75ef..00000000 --- a/doxygen/snippets/qf_state.c +++ /dev/null @@ -1,19 +0,0 @@ -QState Blinky_off(Blinky * const me, QEvt const * const e) { - QState status; - switch (e->sig) { - case Q_ENTRY_SIG: { - BSP_ledOff(); - status = Q_HANDLED(); - break; - } - case TIMEOUT_SIG: { - status = Q_TRAN(&Blinky_on); - break; - } - default: { - status = Q_SUPER(&QHsm_top); - break; - } - } - return status; -} diff --git a/doxygen/snippets/qf_subscribe.c b/doxygen/snippets/qf_subscribe.c deleted file mode 100644 index 1b6ee9f3..00000000 --- a/doxygen/snippets/qf_subscribe.c +++ /dev/null @@ -1,14 +0,0 @@ -QState Table_initial(Table * const me, QEvt const * const e) { - (void)e; /* unused parameter */ - - /* subscribe to event signals~~~ */ - QActive_subscribe(&me->super, (enum_t)HUNGRY_SIG); - QActive_subscribe(&me->super, (enum_t)DONE_SIG); - QActive_subscribe(&me->super, (enum_t)TERMINATE_SIG); - - for (uint8_t n = 0U; n < N; ++n) { - me->fork[n] = FREE; - me->isHungry[n] = false; - } - return Q_TRAN(&Table_serving); -} diff --git a/doxygen/snippets/qf_tevt.c b/doxygen/snippets/qf_tevt.c deleted file mode 100644 index e3dca72c..00000000 --- a/doxygen/snippets/qf_tevt.c +++ /dev/null @@ -1,18 +0,0 @@ -static QState Game_show_logo(Tunnel * const me, QEvt const * const e) { - QState status_; - switch (e->sig) { - /*.${AOs::Tunnel::SM::active::show_logo} */ - case Q_ENTRY_SIG: { - /* arm periodic time event */ - QTimeEvt_armX(&me->blinkTimeEvt, - BSP_TICKS_PER_SEC/2U, /* one-time delay */ - BSP_TICKS_PER_SEC/2U); /* interval */ - /* arm a one-shot time event */ - QTimeEvt_armX(&me->screenTimeEvt, - BSP_TICKS_PER_SEC*5U, /* one-time delay */ - 0U); /* interval (0 == no interval) */ - . . . - status_ = Q_HANDLED(); - break; - } - . . . diff --git a/doxygen/snippets/qf_tick.c b/doxygen/snippets/qf_tick.c deleted file mode 100644 index a33ff812..00000000 --- a/doxygen/snippets/qf_tick.c +++ /dev/null @@ -1,25 +0,0 @@ -#ifdef Q_SPY - /* QS-ID for local filtering */ - static QSpyId const l_ISR_timer = { QS_AP_ID + 5 }; -#endif - -/* case 1: Interrupt Controller available, -* "unconditional interrupt unlocking" critical section policy -* (nesting of critical sections _not_ allowed) -*/ -interrupt void ISR_timer() { /* entered with interrupts disabled in hardware */ - QF_INT_ENABLE(); /* enable interrupts */ - - QTIMEEVT_TICK_X(0U, &l_ISR_timer); /* <--- call the QF tick processing */ - - QF_INT_DISABLE(); /* disable interrupts again */ - /* send the EOI instruction to the Interrupt Controller */ -} - -/* case 2: Interrupt Controller not used, -* "saving and restoring interrupt status" critical section policy -* (nesting of critical sections allowed) -*/ -interrupt void ISR_timer() { - QTIMEEVT_TICK_X(0U, &l_ISR_timer); /* <--- call the QF tick processing */ -} diff --git a/doxygen/snippets/qf_ticker.c b/doxygen/snippets/qf_ticker.c deleted file mode 100644 index 98b8bc10..00000000 --- a/doxygen/snippets/qf_ticker.c +++ /dev/null @@ -1,36 +0,0 @@ -/* bsp.h ----------------- */ -extern QTicker ticker0; /* "ticker" AO for clock rate 0 */ -extern QTicker ticker1; /* "ticker" AO for clock rate 1 */ - - -/* bsp.c ----------------- */ -QTicker ticker0; /* "ticker" AO for clock rate 0 */ -QTicker ticker1; /* "ticker" AO for clock rate 1 */ - -/* system clock tick ISR for clock rate 0 */ -void SysTick_Handler(void) { - . . . - QACTIVE_POST(&ticker0.super, (QEvt *)0, &qs_tick0_id); - . . . -} - -/* system clock tick ISR for clock rate 1 */ -void Timer0A_IRQHandler(void) { - . . . - QACTIVE_POST(&ticker1.super, (QEvt *)0, &qs_tick1_id); - . . . -} - - -/* main.c --------------- */ -main () { - . . . - QACTIVE_START(&ticker0.super, - 1U, /* priority */ - 0, 0, 0, 0, 0); /* not used */ - - QACTIVE_START(&ticker1.super, - 2U, /* priority */ - 0, 0, 0, 0, 0); /* not used */ - . . . -} diff --git a/doxygen/snippets/qf_tickx.c b/doxygen/snippets/qf_tickx.c deleted file mode 100644 index 8eecbd26..00000000 --- a/doxygen/snippets/qf_tickx.c +++ /dev/null @@ -1,25 +0,0 @@ -#ifdef Q_SPY - /* QS-ID for local filtering */ - static QSpyId const l_ISR_timer = { QS_AP_ID + 5 }; -#endif - -/* case 1: Interrupt Controller available, -* "unconditional interrupt unlocking" critical section policy -* (nesting of critical sections _not_ allowed) -*/ -interrupt void ISR_timer() { /* entered with interrupts disabled in hardware */ - QF_INT_ENABLE(); /* enable interrupts */ - - QTIMEEVT_TICK_X(0U, &l_ISR_timer); /* <--- call the QF tick processing */ - - QF_INT_DISABLE(); /* disable interrupts again */ - /* send the EOI instruction to the Interrupt Controller */ -} - -/* case 2: Interrupt Controller not used, -* "saving and restoring interrupt status" critical section policy -* (nesting of critical sections allowed) -*/ -interrupt void ISR_timer() { - QTIMEEVT_TICK_X(1U, &l_ISR_timer); /* <--- call the QF tick processing */ -} diff --git a/doxygen/snippets/qf_version.c b/doxygen/snippets/qf_version.c deleted file mode 100644 index 2cbd5962..00000000 --- a/doxygen/snippets/qf_version.c +++ /dev/null @@ -1 +0,0 @@ -printf("My project\nQP version %s\n", QP_VERSION_STR); diff --git a/doxygen/snippets/qk_lock.c b/doxygen/snippets/qk_lock.c deleted file mode 100644 index ef02e3ea..00000000 --- a/doxygen/snippets/qk_lock.c +++ /dev/null @@ -1,14 +0,0 @@ -uint32_t BSP_random(void) { /* a very cheap pseudo-random-number generator */ - uint32_t rnd; - QSchedStatus lockStat; /* <=== QK scheduler lock status */ - - lockStat = QK_schedLock(N_PHILO); /* <--- lock scheduler up to N_PHILO prio */ - /* "Super-Duper" Linear Congruential Generator (LCG) - * LCG(2^32, 3*7*11*13*23, 0, seed) - */ - rnd = l_rnd * (3U*7U*11U*13U*23U); - l_rnd = rnd; /* set for the next time */ - QK_schedUnlock(lockStat); /* <--- unlock the scheduler */ - - return (rnd >> 8); -} diff --git a/doxygen/snippets/qmp_init.c b/doxygen/snippets/qmp_init.c deleted file mode 100644 index 224b8edf..00000000 --- a/doxygen/snippets/qmp_init.c +++ /dev/null @@ -1,13 +0,0 @@ -QMPool myMemPool1; /* memory pool object #1 (global) */ -static uint8_t memPoolSto1[512]; /* storage for a memory pool #1 */ -QMPool_init(&myMemPool1, - memPoolSto1, - sizeof(memPoolSto1), - 10U); /* memory blocks of 10 bytes each */ - -QMPool myMemPool2; /* memory pool object #2 (global) */ -static uint8_t memPoolSto2[1024]; /* storage for a memory pool #2 */ -QMPool_init(&myMemPool2, - memPoolSto2, - sizeof(memPoolSto2), - 25U); /* memory blocks of 25 bytes each */ diff --git a/doxygen/snippets/qmp_use.c b/doxygen/snippets/qmp_use.c deleted file mode 100644 index ff75f96a..00000000 --- a/doxygen/snippets/qmp_use.c +++ /dev/null @@ -1,7 +0,0 @@ -void *block = QMpool_get(&myMemPool2, 5U); /* non-asserting version */ -if (block != (void *)0) { /* allocation succeeded? */ - ~ ~ ~ -} - -~ ~ ~ -QMPool_put(&myMemPool2, block); \ No newline at end of file diff --git a/doxygen/snippets/qs_ap.c b/doxygen/snippets/qs_ap.c deleted file mode 100644 index 7ef33e5f..00000000 --- a/doxygen/snippets/qs_ap.c +++ /dev/null @@ -1,15 +0,0 @@ -enum UserSpyRecords { - . . . - PHILO_STAT = QS_USER, /* define a user QS record types */ - . . . -}; - -void displyPhilStat(uint8_t n, char const *stat) { - . . . - - /* application-specific record */ - QS_BEGIN_ID(PHILO_STAT, AO_Philo[n]->prio); - QS_U8(1, n); /* Philosopher number */ - QS_STR(stat); /* Philosopher status */ - QS_END(); -} diff --git a/doxygen/snippets/qs_filter.c b/doxygen/snippets/qs_filter.c deleted file mode 100644 index 706690e6..00000000 --- a/doxygen/snippets/qs_filter.c +++ /dev/null @@ -1,25 +0,0 @@ -int main(int arc, char *argv[]) { - . . . - - if (!QS_INIT(argv)) { /* Initialize QS target component */ - return -1; /* unable to initialize QSpy */ - } - - /* apply the global QS filters~~~ */ - /* NOTE: global filters start as being all OFF */ - QS_GLB_FILTER(QS_QF_RECORDS); /* turn QF-group ON */ - QS_GLB_FILTER(-QS_QF_TICK); /* turn #QS_QF_TICK OFF */ - - /* apply the local QS filters~~~ */ - /* NOTE: local filters start as being all ON */ - QS_LOC_FILTER(-QS_EP_IDS); /* turn EP (Event-Pool) group OFF */ - QS_LOC_FILTER(3); /* turn AO with prioity 3 ON */ - - /* start the active objects~~~ */ - . . . - - /* NOTE: the following will work only after AO_Table has been started */ - QS_LOC_FILTER(-AO_Table->prio); /* turn AO_Table OFF */ - - . . . -} diff --git a/doxygen/snippets/qs_objArrDic.c b/doxygen/snippets/qs_objArrDic.c deleted file mode 100644 index 1d465f4f..00000000 --- a/doxygen/snippets/qs_objArrDic.c +++ /dev/null @@ -1,6 +0,0 @@ -Philo Philo_inst[N_PHILO]; -. . . -for (uint8_t n = 0U; n < N_PHILO; ++n) { - QS_OBJ_ARR_DICTIONARY(&Philo_inst[n], n); - QS_OBJ_ARR_DICTIONARY(&Philo_inst[n].timeEvt, n); -} diff --git a/doxygen/snippets/qs_objDic.c b/doxygen/snippets/qs_objDic.c deleted file mode 100644 index 32bb7803..00000000 --- a/doxygen/snippets/qs_objDic.c +++ /dev/null @@ -1,9 +0,0 @@ -Table Table_inst; /* the instance of the Table Active Object */ - -/* top-most initial transition */ -static QState Table_initial(Table * const me, QEvt const * const e) { - . . . - /* provide object dictionary for Table */ - QS_OBJ_DICTIONARY(&Table_inst); /* <--- */ - . . . -} diff --git a/doxygen/snippets/qs_onGetTime.c b/doxygen/snippets/qs_onGetTime.c deleted file mode 100644 index 73006e6c..00000000 --- a/doxygen/snippets/qs_onGetTime.c +++ /dev/null @@ -1,9 +0,0 @@ -#ifdef Q_SPY - -QSTimeCtr QS_onGetTime(void) { /* <--- callback */ - return (QSTimeCtr)clock(); -} - -. . . - -#endif /* Q_SPY */ diff --git a/doxygen/snippets/qs_sigDic.c b/doxygen/snippets/qs_sigDic.c deleted file mode 100644 index 3d357a5c..00000000 --- a/doxygen/snippets/qs_sigDic.c +++ /dev/null @@ -1,14 +0,0 @@ -QState Table_initial(Table * const me, QEvt const *) { - - /* signals for all state machines~~~ */ - QS_SIG_DICTIONARY(EAT_SIG, (void *)0); - . . . - - - /* signals for this specific state machine "me"~~~ */ - QS_SIG_DICTIONARY(HUNGRY_SIG, me); - QS_SIG_DICTIONARY(DONE_SIG, me); - . . . - - return Q_TRAN(&Table_serving); -} diff --git a/doxygen/snippets/qs_sigLog.txt b/doxygen/snippets/qs_sigLog.txt deleted file mode 100644 index f94a305e..00000000 --- a/doxygen/snippets/qs_sigLog.txt +++ /dev/null @@ -1,78 +0,0 @@ -qspy -fqs.bin -S2 -Q2 -P4 -p4 -T4 -QSpy 1.1.03 -Thu Nov 17 09:56:10 2005 --f qs.bin --S 2 --Q 2 --P 4 --p 4 --T 4 -. . . . . . - Obj Dic: 00419048->table - EQ.INIT: Obj=00419050 Len= 5 -0000000000 AO.ADD : Active=table Prio=51 - Fun Dic: 00401CEE->Table_serving - Sig Dic: 00000004,Obj=00419048 ->HUNGRY_SIG - Sig Dic: 00000005,Obj=00419048 ->DONE_SIG - Sig Dic: 00000006,Obj=00000000 ->EAT_SIG -0000000000 AO.SUB : Active=table Sig=HUNGRY_SIG -0000000000 AO.SUB : Active=table Sig=DONE_SIG -0000000000 AO.SUB : Active=table Sig=00000007,Obj=00419048 - Q_INIT : Obj=table Source=00403CE0 Target=Table_serving -0000000000 ==>Init: Obj=table New=Table_serving -. . . . . . - -// the Philosophers become hungry... - - -0000000007 AO.FIFO: Obj=table Evt(Sig=HUNGRY_SIG, Pool=1, Ref= 1) - Queue(nUsed= 0, nMax= 0) -0000000007 AO.FIFO: Obj=table Evt(Sig=HUNGRY_SIG, Pool=1, Ref= 1) - Queue(nUsed= 0, nMax= 0) -0000000007 AO.FIFO: Obj=table Evt(Sig=HUNGRY_SIG, Pool=1, Ref= 1) - Queue(nUsed= 1, nMax= 1) -0000000007 AO.FIFO: Obj=table Evt(Sig=HUNGRY_SIG, Pool=1, Ref= 1) - Queue(nUsed= 2, nMax= 2) - Q_ENTRY: Obj=philo[2] State=Philosopher_hungry -0000000007 AO.GET : Active= table Evt(Sig=HUNGRY_SIG, Pool=1, Ref= 1) - Queue(nUsed= 2) -0000000007 AO.FIFO: Obj=table Evt(Sig=HUNGRY_SIG, Pool=1, Ref= 1) - Queue(nUsed= 2, nMax= 3) - Q_ENTRY: Obj=philo[4] State=Philosopher_hungry - Q_ENTRY: Obj=philo[1] State=Philosopher_hungry - Q_ENTRY: Obj=philo[3] State=Philosopher_hungry -0000000007 ==>Tran: Obj=philo[2] Sig=TIMEOUT_SIG Source=Philosopher_thinking - New=Philosopher_hungry -0000000007 ==>Tran: Obj=philo[4] Sig=TIMEOUT_SIG Source=Philosopher_thinking - New=Philosopher_hungry -0000000007 ==>Tran: Obj=philo[3] Sig=TIMEOUT_SIG Source=Philosopher_thinking - New=Philosopher_hungry -0000000007 ==>Tran: Obj=philo[1] Sig=TIMEOUT_SIG Source=Philosopher_thinking - New=Philosopher_hungry - Q_ENTRY: Obj=philo[0] State=Philosopher_hungry -0000000007 ==>Tran: Obj=philo[0] Sig=TIMEOUT_SIG Source=Philosopher_thinking - New=Philosopher_hungry - -// user record output -0000000007 User070: 2 hungry - -// Table grants permissions to eat -0000000007 NEW : Evt(Sig=EAT_SIG, size= 6) -0000000007 MP.GET : Obj=00418E18 nFree= 5 nMin= 5 -0000000007 AO.FIFO: Obj=philo[4] Evt(Sig=EAT_SIG, Pool=1, Ref= 0) - Queue(nUsed= 0, nMax= 0) -0000000007 AO.FIFO: Obj=philo[3] Evt(Sig=EAT_SIG, Pool=1, Ref= 0) - Queue(nUsed= 0, nMax= 0) -0000000007 AO.FIFO: Obj=philo[2] Evt(Sig=EAT_SIG, Pool=1, Ref= 0) - Queue(nUsed= 0, nMax= 0) -0000000007 AO.FIFO: Obj=philo[1] Evt(Sig=EAT_SIG, Pool=1, Ref= 0) - Queue(nUsed= 0, nMax= 0) -0000000007 AO.FIFO: Obj=philo[0] Evt(Sig=EAT_SIG, Pool=1, Ref= 0) - Queue(nUsed= 0, nMax= 0) -0000000007 PUBLISH: Evt(Sig=EAT_SIG, Pool=1, Ref= 5) nSubsr= 5 -0000000007 AO.GETL: Active= philo[4] Evt(Sig=EAT_SIG, Pool=1, Ref= 5) -0000000007 AO.GETL: Active= philo[2] Evt(Sig=EAT_SIG, Pool=1, Ref= 5) -0000000007 AO.GETL: Active= philo[3] Evt(Sig=EAT_SIG, Pool=1, Ref= 5) -0000000007 AO.GETL: Active= philo[1] Evt(Sig=EAT_SIG, Pool=1, Ref= 5) -0000000007 AO.GETL: Active= philo[0] Evt(Sig=EAT_SIG, Pool=1, Ref= 5) -. . . . . . diff --git a/doxygen/snippets/qs_sigLog0.txt b/doxygen/snippets/qs_sigLog0.txt deleted file mode 100644 index d2c9f374..00000000 --- a/doxygen/snippets/qs_sigLog0.txt +++ /dev/null @@ -1,78 +0,0 @@ -qspy -fqs0.bin -S2 -Q2 -P4 -p4 -T4 -QSpy 1.1.03 -Thu Nov 17 10:10:22 2005 --f qs0.bin --S 2 --Q 2 --P 4 --p 4 --T 4 -. . . . . . - Obj Dic: 00419048->table - EQ.INIT: Obj=00419050 Len= 5 -0000000000 AO.ADD : Active=table Prio=51 - -// the signal dictionary entries removed from the binary QS log -*** Dropped 4 records - -0000000000 AO.SUB : Active=table Sig=00000004,Obj=00419048 -0000000000 AO.SUB : Active=table Sig=00000005,Obj=00419048 -0000000000 AO.SUB : Active=table Sig=00000007,Obj=00419048 - Q_INIT : Obj=table Source=00403CE0 Target=00403CE0 -0000000000 ==>Init: Obj=table New=00401CEE -. . . . . . - -// the Philosophers become hungry... - - -0000000007 AO.FIFO: Obj=table Evt(Sig=00000004,Obj=00419048, Pool=1, Ref= 1) - Queue(nUsed= 0, nMax= 0) -0000000007 AO.FIFO: Obj=table Evt(Sig=00000004,Obj=00419048, Pool=1, Ref= 1) - Queue(nUsed= 0, nMax= 0) -0000000007 AO.FIFO: Obj=table Evt(Sig=00000004,Obj=00419048, Pool=1, Ref= 1) - Queue(nUsed= 1, nMax= 1) -0000000007 AO.FIFO: Obj=table Evt(Sig=00000004,Obj=00419048, Pool=1, Ref= 1) - Queue(nUsed= 2, nMax= 2) - Q_ENTRY: Obj=philo[2] State=Philosopher_hungry -0000000007 AO.GET : Active= table Evt(Sig=00000004,Obj=00419048, Pool=1, Ref= 1) - Queue(nUsed= 2) -0000000007 AO.FIFO: Obj=table Evt(Sig=00000004,Obj=00419048, Pool=1, Ref= 1) - Queue(nUsed= 2, nMax= 3) - Q_ENTRY: Obj=philo[4] State=Philosopher_hungry - Q_ENTRY: Obj=philo[1] State=Philosopher_hungry - Q_ENTRY: Obj=philo[3] State=Philosopher_hungry -0000000007 ==>Tran: Obj=philo[2] Sig=TIMEOUT_SIG Source=Philosopher_thinking - New=Philosopher_hungry -0000000007 ==>Tran: Obj=philo[4] Sig=TIMEOUT_SIG Source=Philosopher_thinking - New=Philosopher_hungry -0000000007 ==>Tran: Obj=philo[3] Sig=TIMEOUT_SIG Source=Philosopher_thinking - New=Philosopher_hungry -0000000007 ==>Tran: Obj=philo[1] Sig=TIMEOUT_SIG Source=Philosopher_thinking - New=Philosopher_hungry - Q_ENTRY: Obj=philo[0] State=Philosopher_hungry -0000000007 ==>Tran: Obj=philo[0] Sig=TIMEOUT_SIG Source=Philosopher_thinking - New=Philosopher_hungry - -// user record output -0000000007 User070: 2 hungry - -// Table grants permissions to eat -0000000007 NEW : Evt(Sig=00000006,Obj=00000000, size= 6) -0000000007 MP.GET : Obj=00418E18 nFree= 5 nMin= 5 -0000000007 AO.FIFO: Obj=philo[4] Evt(Sig=00000006,Obj=00419000, Pool=1, Ref= 0) - Queue(nUsed= 0, nMax= 0) -0000000007 AO.FIFO: Obj=philo[3] Evt(Sig=00000006,Obj=00418FBC, Pool=1, Ref= 0) - Queue(nUsed= 0, nMax= 0) -0000000007 AO.FIFO: Obj=philo[2] Evt(Sig=00000006,Obj=00418F78, Pool=1, Ref= 0) - Queue(nUsed= 0, nMax= 0) -0000000007 AO.FIFO: Obj=philo[1] Evt(Sig=00000006,Obj=00418F34, Pool=1, Ref= 0) - Queue(nUsed= 0, nMax= 0) -0000000007 AO.FIFO: Obj=philo[0] Evt(Sig=00000006,Obj=00418EF0, Pool=1, Ref= 0) - Queue(nUsed= 0, nMax= 0) -0000000007 PUBLISH: Evt(Sig=00000006,Obj=00000000, Pool=1, Ref= 5) nSubsr= 5 -0000000007 AO.GETL: Active= philo[4] Evt(Sig=00000006,Obj=00419000, Pool=1, Ref= 5) -0000000007 AO.GETL: Active= philo[2] Evt(Sig=00000006,Obj=00418F78, Pool=1, Ref= 5) -0000000007 AO.GETL: Active= philo[3] Evt(Sig=00000006,Obj=00418FBC, Pool=1, Ref= 5) -0000000007 AO.GETL: Active= philo[1] Evt(Sig=00000006,Obj=00418F34, Pool=1, Ref= 5) -0000000007 AO.GETL: Active= philo[0] Evt(Sig=00000006,Obj=00418EF0, Pool=1, Ref= 5) -. . . . . . diff --git a/doxygen/snippets/qs_startup.c b/doxygen/snippets/qs_startup.c deleted file mode 100644 index 816bbd14..00000000 --- a/doxygen/snippets/qs_startup.c +++ /dev/null @@ -1,23 +0,0 @@ -#ifdef Q_SPY - -uint8_t QS_onStartup(void const *arg) { - static uint8_t qsBuf[4*1024]; /* buffer for Quantum Spy */ - - QS_initBuf(qsBuf, sizeof(qsBuf)); /* configure the Q-Spy buffer */ - - /* configure UART 0/1 for QSPY output ~~~ */ - if (*(char const *)arg == '0') { /* use UART 0 */ - /* configure UART 0 for QSPY output ~~~ */ - . . . - return (uint8_t)1; /* UART 0 successfully opened */ - } - else { /* use UART 1 */ - /* configure UART 1 for QSPY output ~~~ */ - . . . - return (uint8_t)1; /* UART 1 successfully opened */ - } -} - -. . . - -#endif /* Q_SPY */ diff --git a/doxygen/snippets/qxk_lock.c b/doxygen/snippets/qxk_lock.c deleted file mode 100644 index e6415fd4..00000000 --- a/doxygen/snippets/qxk_lock.c +++ /dev/null @@ -1,14 +0,0 @@ -uint32_t BSP_random(void) { /* a very cheap pseudo-random-number generator */ - uint32_t rnd; - QSchedStatus lockStat; - - lockStat = QXK_schedLock(N_PHILO); /* <--- lock scheduler around shared seed */ - - /* "Super-Duper" Linear Congruential Generator (LCG) */ - rnd = l_rnd * (3U*7U*11U*13U*23U); - l_rnd = rnd; /* set for the next time */ - - QXK_schedLock(lockStat); /* <--- unlock the scheduler */ - - return rnd; -} diff --git a/doxygen/snippets/qxk_mutex.c b/doxygen/snippets/qxk_mutex.c deleted file mode 100644 index ca127fe4..00000000 --- a/doxygen/snippets/qxk_mutex.c +++ /dev/null @@ -1,21 +0,0 @@ -QXMutex l_rndMutex; /* mutex to protect the random number generator */ - - -void BSP_randomSeed(uint32_t seed) { - QXMutex_init(&l_rndMutex, N_PHILO); /* <== initialize the mutex */ - l_rnd = seed; -} - -uint32_t BSP_random(void) { /* a very cheap pseudo-random-number generator */ - uint32_t rnd; - - QXMutex_lock(&l_rndMutex); /* <--- lock the shared random seed */ - - /* "Super-Duper" Linear Congruential Generator (LCG) */ - rnd = l_rnd * (3U*7U*11U*13U*23U); - l_rnd = rnd; /* set for the next time */ - - QXMutex_unlock(&l_rndMutex); /* <--- unlock the shared random seed */ - - return rnd; -} diff --git a/doxygen/snippets/qxk_sema.c b/doxygen/snippets/qxk_sema.c deleted file mode 100644 index 68e0fed3..00000000 --- a/doxygen/snippets/qxk_sema.c +++ /dev/null @@ -1,25 +0,0 @@ -QXSemaphore BTN_sema; /* semaphore to signal a button press */ - -int main() { - . . . - /* initialize the BTN_sema semaphore as binary, signaling semaphore */ - QXSemaphore_init(&BTN_sema, /* pointer to semaphore to initialize */ - 0U, /* initial semaphore count (singaling semaphore) */ - 1U); /* maximum semaphore count (binary semaphore) */ - . . . -} - -void main_threadXYZ(QXThread * const me) { - while (1) { - . . . - QXSemaphore_wait(&BTN_sema, /* <--- pointer to semaphore to wait on */ - QXTHREAD_NO_TIMEOUT); /* timeout for waiting */ - . . . - } -} - -void GPIO_Handler(void) { - . . . - QXSemaphore_signal(&BTN_sema); /* <--- pointer to semaphore to signal */ - . . . -} diff --git a/doxygen/snippets/qxk_start.c b/doxygen/snippets/qxk_start.c deleted file mode 100644 index 7e0bb946..00000000 --- a/doxygen/snippets/qxk_start.c +++ /dev/null @@ -1,38 +0,0 @@ -#include "qpc.h" - -Q_DEFINE_THIS_FILE - -int main() { - . . . - QF_init(); /* initialize the framework */ - BSP_init(); /* initialize the Board Support Package */ - - /* initialize publish-subscribe~~~ */ - QF_psInit(subscrSto, Q_DIM(subscrSto)); - - /* initialize event pools~~~ */ - QF_poolInit(smlPoolSto, sizeof(smlPoolSto), sizeof(smlPoolSto[0])); - - /* start the active objects (basic threads)~~~ */ - Table_ctor(); /* instantiate the Table AO */ - QACTIVE_START(AO_Table, /* AO to start */ - n + 1U, /* QF-priority */ - tableQueueSto, /* event queue storage */ - Q_DIM(tableQueueSto), /* queue length [events] */ - tableStackSto, /* stack storage */ - sizeof(tableStackSto), /* stack size [bytes] */ - (void *)0); /* initialization param */ - . . . - - /* start the extended-threads~~~ */ - Test_ctor(); /* instantiate the Test extended thread */ - QXTHREAD_START(XT_Test, /* Thread to start */ - 10U, /* QF-priority */ - testQueueSto, /* message queue storage */ - Q_DIM(testQueueSto), /* message length [events] */ - testStackSto, /* stack storage */ - sizeof(testStackSto), /* stack size [bytes] */ - (void *)0); /* initialization param */ - - return QF_run(); /* run the QF application */ -} diff --git a/doxygen/snippets/qxk_thread.c b/doxygen/snippets/qxk_thread.c deleted file mode 100644 index 2250b627..00000000 --- a/doxygen/snippets/qxk_thread.c +++ /dev/null @@ -1,29 +0,0 @@ -#include "qpc.h" - -Q_DEFINE_THIS_FILE - -QXThread blinky; /* QXK extended-thread object */ - -void main_blinky(QXThread * const me) { /* thread function */ - while (1) { - BSP_ledOn(); - QXThread_delay(100U); /* BLOCK */ - BSP_ledOff(); - QXThread_delay(200U); /* BLOCK */ - } -} - -int main() { - . . . - /* initialize and start blinky thread */ - QXThread_ctor(&blinky, &main_blinky, 0); - - static uint64_t stack_blinky[40]; /* stack for the thread */ - QXTHREAD_START(&blinky, - 5U, /* priority */ - (void *)0, 0, /* message queue (not used) */ - stack_blinky, sizeof(stack_blinky), /* stack */ - (void *)0); /* extra parameter (not used) */ - . . . - return QF_run(); /* run the application */ -} diff --git a/doxygen/snippets/qxk_thread_ctor.c b/doxygen/snippets/qxk_thread_ctor.c deleted file mode 100644 index 2cf0dbbe..00000000 --- a/doxygen/snippets/qxk_thread_ctor.c +++ /dev/null @@ -1,26 +0,0 @@ -#include "qpc.h" - -Q_DEFINE_THIS_FILE - -QXThread blinky; /* QXK extended-thread object */ - -void main_blinky(QXThread * const me) { /* thread function */ - while (1) { - . . . - } -} - -int main() { - . . . - /* instantiate and start blinky thread */ - QXThread_ctor(&blinky, &main_blinky, 0); /* <--- ctor */ - - static uint32_t stack_blinky[80]; /* stack for the extended thread */ - QXTHREAD_START(&blinky, - 5U, /* priority */ - (void *)0, 0, /* message queue (not used) */ - stack_blinky, sizeof(stack_blinky), /* stack */ - (void *)0); /* extra parameter (not used) */ - . . . - return QF_run(); /* run the application */ -} diff --git a/examples/arm-cm/blinky_button_nucleo-l053r8/README.md b/examples/arm-cm/blinky_button_nucleo-l053r8/README.md new file mode 100644 index 00000000..d5f81f31 --- /dev/null +++ b/examples/arm-cm/blinky_button_nucleo-l053r8/README.md @@ -0,0 +1,53 @@ +> **NOTE** +This file is best viewed in a **markdown viewer**, such as the one built into GitHub. Markdown viewers are also available as plug-ins to popular Internet browsers. + +# Blinky-Button on NUCLEO-L053R8 +This example implements the "Blinky-Button" application on the STM32 NUCLEO-L053R8 board (ARM Cortex-M0+). The example demonstrates various preemption scenarios (after pressing the User Button) in the preemptive **QK kernel**. The example requires a *logic analyzer*. + +

+
+STM32 NUCLEO-L053R8 +

+ +## Features Demonstrated + +

+
+Logic analyzer trace after pressing the button +

+ +- preemptive run-to-completion QK kernel + + with ARM-KEIL toolchain + +## Build Configurations +- Debug +- Release +- Spy - NOT provided + +# Code Organization +``` +examples\arm-cm\blinky_button_nucleo-l053r8 +| ++---qk // preemptive QK kernel +| +---armclang // ARM/KEIL toolchain with Compiler 6 (ARM/CLANG) +| | bb-qk.uvprojx // uVision project +| +``` + +# Builing the example + +### ARM/KEIL MDK +- Open the provided KEIL uVision project (`bb-qk.uvprojx`) +in Keil uVision IDE. Build/Debug/Download to the board from the IDE. + +# Connecting a Logic Analyzer +The NUCLEO-L053R8 needs to be conntected to a logic analyzer as shown in the following picture: + +

+
+Connecting the NUCLEO-L053R8 to a logic analyzer +

+ + + + diff --git a/examples/arm-cm/blinky_button_nucleo-l053r8/blinky-button_conn.png b/examples/arm-cm/blinky_button_nucleo-l053r8/blinky-button_conn.png new file mode 100644 index 00000000..ddc6ffe7 Binary files /dev/null and b/examples/arm-cm/blinky_button_nucleo-l053r8/blinky-button_conn.png differ diff --git a/examples/arm-cm/blinky_button_nucleo-l053r8/blinky-button_trace.png b/examples/arm-cm/blinky_button_nucleo-l053r8/blinky-button_trace.png new file mode 100644 index 00000000..749dbad6 Binary files /dev/null and b/examples/arm-cm/blinky_button_nucleo-l053r8/blinky-button_trace.png differ diff --git a/examples/arm-cm/blinky_button_nucleo-l053r8/blinky1.c b/examples/arm-cm/blinky_button_nucleo-l053r8/blinky1.c new file mode 100644 index 00000000..1c995ab6 --- /dev/null +++ b/examples/arm-cm/blinky_button_nucleo-l053r8/blinky1.c @@ -0,0 +1,103 @@ +//============================================================================ +// QP/C Example +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +//============================================================================ +#include "qpc.h" // QP/C API +#include "bsp.h" // Board Support Package interface +#include "blinky_button.h" // application shared interface + +Q_DEFINE_THIS_MODULE("blinky1") // for DBC assertions in this module + +//............................................................................ +typedef struct { // Blinky task + QActive super; // inherit QActive + QTimeEvt te; // time event for generating TIMEOUT events + uint16_t toggles; // number of toggles to perform for TIMEOUT event +} Blinky1; + +static void Blinky1_ctor(Blinky1 * const me); +static QState Blinky1_initial(Blinky1 * const me, QEvt const * const ie); +static QState Blinky1_active(Blinky1 * const me, QEvt const * const e); + +//............................................................................ +static Blinky1 Blinky1_inst; // the Blinky instance +QActive * const AO_Blinky1 = &Blinky1_inst.super; // opaque AO pointer + +void Blinky1_instantiate(void) { + Blinky1_ctor(&Blinky1_inst); +} + +//............................................................................ +static void Blinky1_ctor(Blinky1 * const me) { + QActive_ctor( + &me->super, + Q_STATE_CAST(&Blinky1_initial)); + QTimeEvt_ctorX(&me->te, &me->super, TIMEOUT_SIG, 0U); +} +//............................................................................ +static QState Blinky1_initial(Blinky1 * const me, QEvt const * const e) { + // the initial event must be provided and must be WORKLOAD_SIG + Q_REQUIRE_ID(300, + (e != (QEvt const *)0) && (e->sig == BLINKY_WORK_SIG)); + + QTimeEvt_armX(&me->te, + Q_EVT_CAST(BlinkyWorkEvt)->ticks, + Q_EVT_CAST(BlinkyWorkEvt)->ticks); + me->toggles = Q_EVT_CAST(BlinkyWorkEvt)->toggles; + return Q_TRAN(&Blinky1_active); +} +//............................................................................ +static QState Blinky1_active(Blinky1 * const me, QEvt const * const e) { + QState status_; + switch (e->sig) { + case TIMEOUT_SIG: { + for (uint16_t i = me->toggles; i > 0U; --i) { + BSP_d5on(); + BSP_d5off(); + } + status_ = Q_HANDLED(); + break; + } + case BLINKY_WORK_SIG: { + BSP_d5on(); + QTimeEvt_disarm(&me->te); + QTimeEvt_armX(&me->te, + Q_EVT_CAST(BlinkyWorkEvt)->ticks, + Q_EVT_CAST(BlinkyWorkEvt)->ticks); + me->toggles = Q_EVT_CAST(BlinkyWorkEvt)->toggles; + status_ = Q_HANDLED(); + BSP_d5off(); + break; + } + default: { + status_ = Q_SUPER(&QHsm_top); + break; + } + } + return status_; +} diff --git a/examples/arm-cm/blinky_button_nucleo-l053r8/blinky3.c b/examples/arm-cm/blinky_button_nucleo-l053r8/blinky3.c new file mode 100644 index 00000000..eadadd78 --- /dev/null +++ b/examples/arm-cm/blinky_button_nucleo-l053r8/blinky3.c @@ -0,0 +1,103 @@ +//============================================================================ +// QP/C Example +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +//============================================================================ +#include "qpc.h" // QP/C API +#include "bsp.h" // Board Support Package interface +#include "blinky_button.h" // application shared interface + +Q_DEFINE_THIS_MODULE("blinky3") // for DBC assertions in this module + +//............................................................................ +typedef struct { // Blinky3 task + QActive super; // inherit QActive + QTimeEvt te; // time event for generating TIMEOUT events + uint16_t toggles; // number of toggles to perform for TIMEOUT event +} Blinky3; + +static void Blinky3_ctor(Blinky3 * const me); +static QState Blinky3_initial(Blinky3 * const me, QEvt const * const ie); +static QState Blinky3_active(Blinky3 * const me, QEvt const * const e); + +//............................................................................ +static Blinky3 Blinky3_inst; // the Blinky3 instance +QActive * const AO_Blinky3 = &Blinky3_inst.super; // opaque AO pointer + +void Blinky3_instantiate(void) { + Blinky3_ctor(&Blinky3_inst); +} + +//............................................................................ +static void Blinky3_ctor(Blinky3 * const me) { + QActive_ctor( + &me->super, + Q_STATE_CAST(&Blinky3_initial)); + QTimeEvt_ctorX(&me->te, &me->super, TIMEOUT_SIG, 0U); +} +//............................................................................ +static QState Blinky3_initial(Blinky3 * const me, QEvt const * const e) { + // the initial event must be provided and must be WORKLOAD_SIG + Q_REQUIRE_ID(300, + (e != (QEvt const *)0) && (e->sig == BLINKY_WORK_SIG)); + + QTimeEvt_armX(&me->te, + Q_EVT_CAST(BlinkyWorkEvt)->ticks, + Q_EVT_CAST(BlinkyWorkEvt)->ticks); + me->toggles = Q_EVT_CAST(BlinkyWorkEvt)->toggles; + return Q_TRAN(&Blinky3_active); +} +//............................................................................ +static QState Blinky3_active(Blinky3 * const me, QEvt const * const e) { + QState status_; + switch (e->sig) { + case TIMEOUT_SIG: { + for (uint16_t i = me->toggles; i > 0U; --i) { + BSP_d2on(); + BSP_d2off(); + } + status_ = Q_HANDLED(); + break; + } + case BLINKY_WORK_SIG: { + BSP_d2on(); + QTimeEvt_disarm(&me->te); + QTimeEvt_armX(&me->te, + Q_EVT_CAST(BlinkyWorkEvt)->ticks, + Q_EVT_CAST(BlinkyWorkEvt)->ticks); + me->toggles = Q_EVT_CAST(BlinkyWorkEvt)->toggles; + status_ = Q_HANDLED(); + BSP_d2off(); + break; + } + default: { + status_ = Q_SUPER(&QHsm_top); + break; + } + } + return status_; +} diff --git a/examples/arm-cm/blinky_button_nucleo-l053r8/blinky_button.h b/examples/arm-cm/blinky_button_nucleo-l053r8/blinky_button.h new file mode 100644 index 00000000..07ca1957 --- /dev/null +++ b/examples/arm-cm/blinky_button_nucleo-l053r8/blinky_button.h @@ -0,0 +1,67 @@ +//============================================================================ +// QP/C Example +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +//============================================================================ +#ifndef BLINKY_BUTTON_H_ +#define BLINKY_BUTTON_H_ + +enum Signals { + TIMEOUT_SIG = Q_USER_SIG, + BUTTON_PRESSED_SIG, + BUTTON_RELEASED_SIG, + BLINKY_WORK_SIG, + FORWARD_PRESSED_SIG, + FORWARD_RELEASED_SIG, + // ... + MAX_SIG // the last signal +}; + +typedef struct { + QEvt super; // inherit QEvt + uint16_t toggles; // number of toggles of the signal + uint8_t ticks; // number of clock ticks between +} BlinkyWorkEvt; + +typedef struct { + QEvt super; // inherit QEvt + uint16_t toggles; // number of toggles of the signal +} ButtonWorkEvt; + +void Blinky1_instantiate(void); +extern QActive * const AO_Blinky1; // opaque active object pointer + +void Blinky3_instantiate(void); +extern QActive * const AO_Blinky3; // opaque active object pointer + +void Button2a_instantiate(void); +extern QActive * const AO_Button2a; // opaque active object pointer + +void Button2b_instantiate(void); +extern QActive * const AO_Button2b; // opaque active object pointer + +#endif // BLINKY_BUTTON_H_ diff --git a/examples/arm-cm/blinky_button_nucleo-l053r8/bsp.h b/examples/arm-cm/blinky_button_nucleo-l053r8/bsp.h new file mode 100644 index 00000000..ed1d2a3a --- /dev/null +++ b/examples/arm-cm/blinky_button_nucleo-l053r8/bsp.h @@ -0,0 +1,59 @@ +//============================================================================ +// QP/C Example +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +//============================================================================ +#ifndef BSP_H_ +#define BSP_H_ + +#define BSP_TICKS_PER_SEC 1000U + +void BSP_init(void); + +void BSP_d1on(void); +void BSP_d1off(void); + +void BSP_d2on(void); +void BSP_d2off(void); + +void BSP_d3on(void); +void BSP_d3off(void); + +void BSP_d4on(void); +void BSP_d4off(void); + +void BSP_d5on(void); +void BSP_d5off(void); + +void BSP_d6on(void); +void BSP_d6off(void); + +// immutable events for Blinky active objects +QEvt const *BSP_getWorkEvtBlinky1(uint8_t num); +QEvt const *BSP_getWorkEvtBlinky3(uint8_t num); + +#endif // BSP_H_ diff --git a/examples/arm-cm/blinky_button_nucleo-l053r8/button2a.c b/examples/arm-cm/blinky_button_nucleo-l053r8/button2a.c new file mode 100644 index 00000000..5f0fd07a --- /dev/null +++ b/examples/arm-cm/blinky_button_nucleo-l053r8/button2a.c @@ -0,0 +1,123 @@ +//============================================================================ +// QP/C Example +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +//============================================================================ +#include "qpc.h" // QP/C API +#include "bsp.h" // Board Support Package interface +#include "blinky_button.h" // application shared interface + +Q_DEFINE_THIS_MODULE("button2a") // for DBC assertions in this module + +//............................................................................ +typedef struct { // Button2a task + QActive super; // inherit QActive + // add internal variables for this AO... +} Button2a; + +static void Button2a_ctor(Button2a * const me); +static QState Button2a_initial(Button2a * const me, QEvt const * const ie); +static QState Button2a_active(Button2a * const me, QEvt const * const e); + +//............................................................................ +static Button2a Button2a_inst; // the Button2a instance +QActive * const AO_Button2a = &Button2a_inst.super; // opaque AO pointer + +void Button2a_instantiate(void) { + Button2a_ctor(&Button2a_inst); +} + +//............................................................................ +static void Button2a_ctor(Button2a * const me) { + QActive_ctor( + &me->super, + Q_STATE_CAST(&Button2a_initial)); +} +//............................................................................ +static QState Button2a_initial(Button2a * const me, QEvt const * const ie) { + (void)me; + (void)ie; + return Q_TRAN(&Button2a_active); +} +//............................................................................ +static QState Button2a_active(Button2a * const me, QEvt const * const e) { + (void)me; + QState status_; + switch (e->sig) { + case BUTTON_PRESSED_SIG: { + BSP_d4on(); + // Button2a --> Blinky1 + QACTIVE_POST(AO_Blinky1, BSP_getWorkEvtBlinky1(1U), me); + BSP_d4off(); + + for (uint16_t i = Q_EVT_CAST(ButtonWorkEvt)->toggles; + i > 0U; --i) + { + BSP_d4on(); + BSP_d4off(); + } + status_ = Q_HANDLED(); + break; + } + case FORWARD_PRESSED_SIG: { + BSP_d4on(); + // immutable event can be forwarded to another Task + QACTIVE_POST(AO_Button2b, e, me); // Button2a --> Button2b + status_ = Q_HANDLED(); + BSP_d4off(); + break; + } + case BUTTON_RELEASED_SIG: { + BSP_d4on(); + // Button2a --> Blinky1 + QACTIVE_POST(AO_Blinky1, BSP_getWorkEvtBlinky1(0U), me); + BSP_d4off(); + + for (uint16_t i = Q_EVT_CAST(ButtonWorkEvt)->toggles; + i > 0U; --i) + { + BSP_d4on(); + BSP_d4off(); + } + status_ = Q_HANDLED(); + break; + } + case FORWARD_RELEASED_SIG: { + BSP_d4on(); + // immutable event can be forwarded to another Task + QACTIVE_POST(AO_Button2b, e, me); // Button2a --> Button2b + status_ = Q_HANDLED(); + BSP_d4off(); + break; + } + default: { + status_ = Q_SUPER(&QHsm_top); + break; + } + } + return status_; +} diff --git a/examples/arm-cm/blinky_button_nucleo-l053r8/button2b.c b/examples/arm-cm/blinky_button_nucleo-l053r8/button2b.c new file mode 100644 index 00000000..0456791c --- /dev/null +++ b/examples/arm-cm/blinky_button_nucleo-l053r8/button2b.c @@ -0,0 +1,107 @@ +//============================================================================ +// QP/C Example +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +//============================================================================ +#include "qpc.h" // QP/C API +#include "bsp.h" // Board Support Package interface +#include "blinky_button.h" // application shared interface + +Q_DEFINE_THIS_MODULE("button2b") // for DBC assertions in this module + +//............................................................................ +typedef struct { // Button2b task + QActive super; // inherit QActive + // add internal variables for this AO... +} Button2b; + +static void Button2b_ctor(Button2b * const me); +static QState Button2b_initial(Button2b * const me, QEvt const * const e); +static QState Button2b_active(Button2b * const me, QEvt const * const e); + +//............................................................................ +static Button2b Button2b_inst; // the Button2b instance +QActive * const AO_Button2b = &Button2b_inst.super; // opaque AO pointer + +void Button2b_instantiate(void) { + Button2b_ctor(&Button2b_inst); +} + +//............................................................................ +static void Button2b_ctor(Button2b * const me) { + QActive_ctor( + &me->super, + Q_STATE_CAST(&Button2b_initial)); +} +//............................................................................ +static QState Button2b_initial(Button2b * const me, QEvt const * const ie) { + (void)me; + (void)ie; + return Q_TRAN(&Button2b_active); +} +//............................................................................ +static QState Button2b_active(Button2b * const me, QEvt const * const e) { + (void)me; + QState status_; + switch (e->sig) { + case FORWARD_PRESSED_SIG: { + BSP_d3on(); + // Button2b --> Blinky3 + QACTIVE_POST(AO_Blinky3, BSP_getWorkEvtBlinky3(1U), me); + BSP_d3off(); + + for (uint16_t i = Q_EVT_CAST(ButtonWorkEvt)->toggles; + i > 0U; --i) + { + BSP_d3on(); + BSP_d3off(); + } + status_ = Q_HANDLED(); + break; + } + case FORWARD_RELEASED_SIG: { + BSP_d3on(); + // Button2b --> Blinky3 + QACTIVE_POST(AO_Blinky3, BSP_getWorkEvtBlinky3(0U), me); + BSP_d3off(); + + for (uint16_t i = Q_EVT_CAST(ButtonWorkEvt)->toggles; + i > 0U; --i) + { + BSP_d3on(); + BSP_d3off(); + } + status_ = Q_HANDLED(); + break; + } + default: { + status_ = Q_SUPER(&QHsm_top); + break; + } + } + return status_; +} diff --git a/examples/arm-cm/blinky_button_nucleo-l053r8/qk/armclang/bb-qk.uvoptx b/examples/arm-cm/blinky_button_nucleo-l053r8/qk/armclang/bb-qk.uvoptx new file mode 100644 index 00000000..a4dd95dc --- /dev/null +++ b/examples/arm-cm/blinky_button_nucleo-l053r8/qk/armclang/bb-qk.uvoptx @@ -0,0 +1,1113 @@ + + + + 1.0 + +
### uVision Project, (C) Keil Software
+ + + *.c + *.s*; *.src; *.a* + *.obj; *.o + *.lib + *.txt; *.h; *.inc; *.md + *.plm + *.cpp + 0 + + + + 0 + 0 + + + + bb-dbg + 0x4 + ARM-ADS + + 12000000 + + 1 + 1 + 0 + 1 + 0 + + + 1 + 65535 + 0 + 0 + 0 + + + 79 + 66 + 8 + .\dbg\ + + + 1 + 1 + 1 + 0 + 1 + 1 + 0 + 1 + 0 + 0 + 0 + 0 + + + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + + + 1 + 0 + 1 + + 18 + + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + 0 + 1 + 1 + 0 + 0 + 1 + 0 + 0 + 6 + + + + + + + + + + + STLink\ST-LINKIII-KEIL_SWO.dll + + + + 0 + UL2CM3 + UL2CM3(-S0 -C0 -P0 -FD20000000 -FC1000 -FN1 -FF0STM32L0xx_64 -FS08000000 -FL010000 -FP0($$Device:STM32L053R8Tx$CMSIS\Flash\STM32L0xx_64.FLM)) + + + 0 + ST-LINKIII-KEIL_SWO + -U066CFF484951775087074312 -O8431 -SF10000 -C0 -A0 -I0 -HNlocalhost -HP7184 -P2 -N00("ARM CoreSight SW-DP (ARM Core") -D00(0BC11477) -L00(0) -TO131090 -TC10000000 -TT10000000 -TP21 -TDS8004 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -FO15 -FD20000000 -FC800 -FN1 -FF0STM32L0xx_64.FLM -FS08000000 -FL010000 -FP0($$Device:STM32L053R8Tx$CMSIS\Flash\STM32L0xx_64.FLM) + + + 0 + DLGUARM + (105=-1,-1,-1,-1,0) + + + 0 + ARMRTXEVENTFLAGS + -L70 -Z18 -C0 -M0 -T1 + + + 0 + DLGTARM + (1010=979,559,1390,1061,0)(1007=2082,245,2289,466,0)(1008=-1,-1,-1,-1,0)(1009=-1,-1,-1,-1,0) + + + 0 + ARMDBGFLAGS + + + + + + 0 + 0 + 248 + 1 +
134222440
+ 0 + 0 + 0 + 0 + 0 + 1 + ..\bsp.c + + \\bb_qk\../bsp.c\248 +
+
+ + + 0 + 1 + QK_attr_ + + + 1 + 1 + QF_readySet_ + + + + + 1 + 2 + 0x2000020C + 0 + + + + + 2 + 0 + 0x400 + 0 + + + + 0 + + + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + + + + 0 + 0 + 0 + + + + + + + + + + 1 + 0 + 0 + 2 + 10000000 + +
+
+ + + bb-rel + 0x4 + ARM-ADS + + 12000000 + + 1 + 1 + 0 + 1 + 0 + + + 1 + 65535 + 0 + 0 + 0 + + + 79 + 66 + 8 + .\rel\ + + + 1 + 1 + 1 + 0 + 1 + 1 + 0 + 1 + 0 + 0 + 0 + 0 + + + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + + + 1 + 0 + 0 + + 18 + + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + 0 + 1 + 1 + 0 + 0 + 1 + 0 + 0 + 5 + + + + + + + + + + + STLink\ST-LINKIII-KEIL_SWO.dll + + + + 0 + UL2CM3 + UL2CM3(-S0 -C0 -P0 -FD20000000 -FC1000 -FN1 -FF0STM32L0xx_64 -FS08000000 -FL010000 -FP0($$Device:STM32L053R8Tx$CMSIS\Flash\STM32L0xx_64.FLM)) + + + 0 + ST-LINKIII-KEIL_SWO + -U066CFF484951775087074312 -I0 -O8431 -S0 -C0 -A0 -N00("ARM CoreSight SW-DP") -D00(0BC11477) -L00(0) -TO18 -TC10000000 -TP21 -TDS8007 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -FO7 -FD20000000 -FC1000 -FN1 -FF0STM32L0xx_64.FLM -FS08000000 -FL010000 -FP0($$Device:STM32L053R8Tx$CMSIS\Flash\STM32L0xx_64.FLM) + + + 0 + DLGUARM + (105=-1,-1,-1,-1,0) + + + 0 + ARMRTXEVENTFLAGS + -L70 -Z18 -C0 -M0 -T1 + + + 0 + DLGTARM + (1010=-1,-1,-1,-1,0)(1007=-1,-1,-1,-1,0)(1008=-1,-1,-1,-1,0)(1009=-1,-1,-1,-1,0) + + + 0 + ARMDBGFLAGS + + + + + + + 1 + 2 + 0x20000200 + 0 + + + + + 2 + 0 + 0x400 + 0 + + + + 0 + + + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + + + + 0 + 0 + 0 + + + + + + + + + + 1 + 1 + 0 + 2 + 10000000 + + + + + + bb-spy + 0x4 + ARM-ADS + + 12000000 + + 1 + 1 + 1 + 0 + 0 + + + 1 + 65535 + 0 + 0 + 0 + + + 79 + 66 + 8 + .\spy\ + + + 1 + 1 + 1 + 0 + 1 + 1 + 0 + 1 + 0 + 0 + 0 + 0 + + + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + + + 1 + 0 + 0 + + 18 + + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + 0 + 1 + 1 + 0 + 0 + 1 + 0 + 0 + 6 + + + + + + + + + + + STLink\ST-LINKIII-KEIL_SWO.dll + + + + 0 + UL2CM3 + -O207 -S0 -C0 -FO7 -FN1 -FC1000 -FD20000000 -FF0STM32L0xx_64 -FL010000 -FS08000000 -FP0($$Device:STM32L053R8Tx$CMSIS\Flash\STM32L0xx_64.FLM) + + + 0 + ST-LINKIII-KEIL_SWO + -U066CFF484951775087074312 -O8431 -SF4000 -C0 -A0 -I0 -HNlocalhost -HP7184 -P2 -N00("ARM CoreSight SW-DP") -D00(0BC11477) -L00(0) -TO18 -TC10000000 -TP21 -TDS8004 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -FO7 -FD20000000 -FC1000 -FN1 -FF0STM32L0xx_64.FLM -FS08000000 -FL010000 -FP0($$Device:STM32L053R8Tx$CMSIS\Flash\STM32L0xx_64.FLM) + + + 0 + DLGUARM + (105=-1,-1,-1,-1,0) + + + 0 + ARMRTXEVENTFLAGS + -L70 -Z18 -C0 -M0 -T1 + + + 0 + DLGTARM + (1010=-1,-1,-1,-1,0)(1007=-1,-1,-1,-1,0)(1008=-1,-1,-1,-1,0)(1009=-1,-1,-1,-1,0) + + + 0 + ARMDBGFLAGS + + + + + + + 1 + 2 + 0x20000200 + 0 + + + + + 2 + 0 + 0x400 + 0 + + + + 0 + + + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + + + + 0 + 0 + 0 + + + + + + + + + + 1 + 0 + 0 + 2 + 10000000 + + + + + + Source Code + 1 + 0 + 0 + 0 + + 1 + 1 + 1 + 0 + 0 + 0 + ..\bsp.c + bsp.c + 0 + 0 + + + 1 + 2 + 5 + 0 + 0 + 0 + ..\..\bsp.h + bsp.h + 0 + 0 + + + 1 + 3 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qs\qstamp.c + qstamp.c + 0 + 0 + + + 1 + 4 + 1 + 0 + 0 + 0 + ..\main.c + main.c + 0 + 0 + + + 1 + 5 + 5 + 0 + 0 + 0 + ..\..\blinky_button.h + blinky_button.h + 0 + 0 + + + 1 + 6 + 1 + 0 + 0 + 0 + ..\..\blinky1.c + blinky1.c + 0 + 0 + + + 1 + 7 + 1 + 0 + 0 + 0 + ..\..\blinky3.c + blinky3.c + 0 + 0 + + + 1 + 8 + 1 + 0 + 0 + 0 + ..\..\button2a.c + button2a.c + 0 + 0 + + + 1 + 9 + 1 + 0 + 0 + 0 + ..\..\button2b.c + button2b.c + 0 + 0 + + + + + nucleo-l053r8 + 1 + 0 + 0 + 0 + + 2 + 10 + 5 + 0 + 0 + 0 + ..\..\..\..\..\3rd_party\nucleo-l053r8\stm32l0xx.h + stm32l0xx.h + 0 + 0 + + + 2 + 11 + 5 + 0 + 0 + 0 + ..\..\..\..\..\3rd_party\nucleo-l053r8\stm32l053xx.h + stm32l053xx.h + 0 + 0 + + + 2 + 12 + 1 + 0 + 0 + 0 + ..\..\..\..\..\3rd_party\nucleo-l053r8\system_stm32l0xx.c + system_stm32l0xx.c + 0 + 0 + + + 2 + 13 + 5 + 0 + 0 + 0 + ..\..\..\..\..\3rd_party\nucleo-l053r8\system_stm32l0xx.h + system_stm32l0xx.h + 0 + 0 + + + 2 + 14 + 2 + 0 + 0 + 0 + ..\..\..\..\..\3rd_party\nucleo-l053r8\arm\startup_stm32l053xx.s + startup_stm32l053xx.s + 0 + 0 + + + + + QP + 1 + 0 + 0 + 0 + + 3 + 15 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qf\qep_hsm.c + qep_hsm.c + 0 + 0 + + + 3 + 16 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qf\qep_msm.c + qep_msm.c + 0 + 0 + + + 3 + 17 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qf\qf_act.c + qf_act.c + 0 + 0 + + + 3 + 18 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qf\qf_actq.c + qf_actq.c + 0 + 0 + + + 3 + 19 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qf\qf_defer.c + qf_defer.c + 0 + 0 + + + 3 + 20 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qf\qf_dyn.c + qf_dyn.c + 0 + 0 + + + 3 + 21 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qf\qf_mem.c + qf_mem.c + 0 + 0 + + + 3 + 22 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qf\qf_ps.c + qf_ps.c + 0 + 0 + + + 3 + 23 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qf\qf_qact.c + qf_qact.c + 0 + 0 + + + 3 + 24 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qf\qf_qeq.c + qf_qeq.c + 0 + 0 + + + 3 + 25 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qf\qf_qmact.c + qf_qmact.c + 0 + 0 + + + 3 + 26 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qf\qf_time.c + qf_time.c + 0 + 0 + + + 3 + 27 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qk\qk.c + qk.c + 0 + 0 + + + + + QP_port + 1 + 0 + 0 + 0 + + 4 + 28 + 5 + 0 + 0 + 0 + ..\..\..\..\..\ports\arm-cm\qk\armclang\qep_port.h + qep_port.h + 0 + 0 + + + 4 + 29 + 5 + 0 + 0 + 0 + ..\..\..\..\..\ports\arm-cm\qk\armclang\qf_port.h + qf_port.h + 0 + 0 + + + 4 + 30 + 5 + 0 + 0 + 0 + ..\..\..\..\..\ports\arm-cm\qk\armclang\qk_port.h + qk_port.h + 0 + 0 + + + 4 + 31 + 5 + 0 + 0 + 0 + ..\..\..\..\..\ports\arm-cm\qk\armclang\qs_port.h + qs_port.h + 0 + 0 + + + 4 + 32 + 1 + 0 + 0 + 0 + ..\..\..\..\..\ports\arm-cm\qk\armclang\qk_port.c + qk_port.c + 0 + 0 + + + + + QS + 1 + 0 + 0 + 0 + + 5 + 33 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qs\qs.c + qs.c + 0 + 0 + + + 5 + 34 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qs\qs_64bit.c + qs_64bit.c + 0 + 0 + + + 5 + 35 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qs\qs_fp.c + qs_fp.c + 0 + 0 + + + 5 + 36 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qs\qs_rx.c + qs_rx.c + 0 + 0 + + + +
diff --git a/examples/arm-cm/blinky_button_nucleo-l053r8/qk/armclang/bb-qk.uvprojx b/examples/arm-cm/blinky_button_nucleo-l053r8/qk/armclang/bb-qk.uvprojx new file mode 100644 index 00000000..edf046c7 --- /dev/null +++ b/examples/arm-cm/blinky_button_nucleo-l053r8/qk/armclang/bb-qk.uvprojx @@ -0,0 +1,1898 @@ + + + + 2.1 + +
### uVision Project, (C) Keil Software
+ + + + bb-dbg + 0x4 + ARM-ADS + 6160000::V6.16::ARMCLANG + 1 + + + STM32L053R8Tx + STMicroelectronics + Keil.STM32L0xx_DFP.2.2.0 + http://www.keil.com/pack/ + IRAM(0x20000000,0x00002000) IROM(0x08000000,0x00010000) CPUTYPE("Cortex-M0+") CLOCK(12000000) ELITTLE + + + UL2CM3(-S0 -C0 -P0 -FD20000000 -FC1000 -FN1 -FF0STM32L0xx_64 -FS08000000 -FL010000 -FP0($$Device:STM32L053R8Tx$Flash\STM32L0xx_64.FLM)) + 0 + $$Device:STM32L053R8Tx$Device\Include\stm32l0xx.h + + + + + + + + + + $$Device:STM32L053R8Tx$SVD\STM32L053x.svd + 0 + 0 + + + + + + + 0 + 0 + 0 + 0 + 1 + + .\dbg\ + bb-qk + 1 + 0 + 0 + 1 + 1 + .\dbg\ + 1 + 0 + 0 + + 0 + 0 + + + 0 + 0 + 0 + 0 + + + 1 + 0 + cmd /c "del .\dbg\qstamp.o" + + 0 + 0 + 0 + 0 + + + 1 + 0 + fromelf --bin --output .\dbg\bb-qk.bin .\dbg\bb-qk.axf + + 0 + 0 + 0 + 0 + + 0 + + + + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 3 + + + 1 + + + SARMCM3.DLL + -REMAP + DARMCM1.DLL + -pCM0+ + SARMCM3.DLL + + TARMCM1.DLL + -pCM0+ + + + + 1 + 0 + 0 + 0 + 16 + + + + + 1 + 0 + 0 + 1 + 1 + 4096 + + 1 + BIN\UL2CM3.DLL + + + + + + 0 + + + + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + 1 + 0 + 0 + 0 + 0 + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + "Cortex-M0+" + + 0 + 0 + 0 + 1 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 8 + 0 + 0 + 0 + 0 + 3 + 3 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 1 + 0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x20000000 + 0x2000 + + + 1 + 0x8000000 + 0x10000 + + + 0 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x8000000 + 0x10000 + + + 1 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x20000000 + 0x2000 + + + 0 + 0x0 + 0x0 + + + + + + 0 + 5 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 3 + 0 + 1 + 0 + 0 + 0 + 3 + 3 + 0 + 0 + 0 + 0 + 0 + + + QK_USE_IRQ_HANDLER=WWDG_IRQHandler QK_USE_IRQ_NUM=0 + + ..\..;..\..\..\..\..\include;..\..\..\..\..\ports\arm-cm\qk\armclang;..\..\..\..\..\3rd_party\CMSIS\Include;..\..\..\..\..\3rd_party\nucleo-l053r8 + + + + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 4 + + + Stack_Size=2048 Heap_Size=16 + + + + + + 1 + 0 + 0 + 0 + 1 + 0 + 0x00000000 + 0x20000000 + + + + + --entry Reset_Handler + + + + + + + + Source Code + + + bsp.c + 1 + ..\bsp.c + + + bsp.h + 5 + ..\..\bsp.h + + + qstamp.c + 1 + ..\..\..\..\..\src\qs\qstamp.c + + + main.c + 1 + ..\main.c + + + blinky_button.h + 5 + ..\..\blinky_button.h + + + blinky1.c + 1 + ..\..\blinky1.c + + + blinky3.c + 1 + ..\..\blinky3.c + + + button2a.c + 1 + ..\..\button2a.c + + + button2b.c + 1 + ..\..\button2b.c + + + + + nucleo-l053r8 + + + stm32l0xx.h + 5 + ..\..\..\..\..\3rd_party\nucleo-l053r8\stm32l0xx.h + + + stm32l053xx.h + 5 + ..\..\..\..\..\3rd_party\nucleo-l053r8\stm32l053xx.h + + + system_stm32l0xx.c + 1 + ..\..\..\..\..\3rd_party\nucleo-l053r8\system_stm32l0xx.c + + + system_stm32l0xx.h + 5 + ..\..\..\..\..\3rd_party\nucleo-l053r8\system_stm32l0xx.h + + + startup_stm32l053xx.s + 2 + ..\..\..\..\..\3rd_party\nucleo-l053r8\arm\startup_stm32l053xx.s + + + + + QP + + + qep_hsm.c + 1 + ..\..\..\..\..\src\qf\qep_hsm.c + + + qep_msm.c + 1 + ..\..\..\..\..\src\qf\qep_msm.c + + + qf_act.c + 1 + ..\..\..\..\..\src\qf\qf_act.c + + + qf_actq.c + 1 + ..\..\..\..\..\src\qf\qf_actq.c + + + qf_defer.c + 1 + ..\..\..\..\..\src\qf\qf_defer.c + + + qf_dyn.c + 1 + ..\..\..\..\..\src\qf\qf_dyn.c + + + qf_mem.c + 1 + ..\..\..\..\..\src\qf\qf_mem.c + + + qf_ps.c + 1 + ..\..\..\..\..\src\qf\qf_ps.c + + + qf_qact.c + 1 + ..\..\..\..\..\src\qf\qf_qact.c + + + qf_qeq.c + 1 + ..\..\..\..\..\src\qf\qf_qeq.c + + + qf_qmact.c + 1 + ..\..\..\..\..\src\qf\qf_qmact.c + + + qf_time.c + 1 + ..\..\..\..\..\src\qf\qf_time.c + + + qk.c + 1 + ..\..\..\..\..\src\qk\qk.c + + + + + QP_port + + + qep_port.h + 5 + ..\..\..\..\..\ports\arm-cm\qk\armclang\qep_port.h + + + qf_port.h + 5 + ..\..\..\..\..\ports\arm-cm\qk\armclang\qf_port.h + + + qk_port.h + 5 + ..\..\..\..\..\ports\arm-cm\qk\armclang\qk_port.h + + + qs_port.h + 5 + ..\..\..\..\..\ports\arm-cm\qk\armclang\qs_port.h + + + qk_port.c + 1 + ..\..\..\..\..\ports\arm-cm\qk\armclang\qk_port.c + + + + + QS + + + 0 + 0 + 0 + 0 + 0 + 0 + 2 + 2 + 2 + 2 + 11 + + + 1 + + + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 0 + 0 + 0 + 0 + 2 + + + + + + + + + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + + + + + + + + + + + + qs.c + 1 + ..\..\..\..\..\src\qs\qs.c + + + qs_64bit.c + 1 + ..\..\..\..\..\src\qs\qs_64bit.c + + + qs_fp.c + 1 + ..\..\..\..\..\src\qs\qs_fp.c + + + qs_rx.c + 1 + ..\..\..\..\..\src\qs\qs_rx.c + + + + + + + bb-rel + 0x4 + ARM-ADS + 6130001::V6.13.1::.\ARMCLANG + 1 + + + STM32L053R8Tx + STMicroelectronics + Keil.STM32L0xx_DFP.2.2.0 + http://www.keil.com/pack/ + IRAM(0x20000000,0x00002000) IROM(0x08000000,0x00010000) CPUTYPE("Cortex-M0+") CLOCK(12000000) ELITTLE + + + UL2CM3(-S0 -C0 -P0 -FD20000000 -FC1000 -FN1 -FF0STM32L0xx_64 -FS08000000 -FL010000 -FP0($$Device:STM32L053R8Tx$Flash\STM32L0xx_64.FLM)) + 0 + $$Device:STM32L053R8Tx$Device\Include\stm32l0xx.h + + + + + + + + + + $$Device:STM32L053R8Tx$SVD\STM32L053x.svd + 0 + 0 + + + + + + + 0 + 0 + 0 + 0 + 1 + + .\rel\ + bb-qk + 1 + 0 + 0 + 0 + 0 + .\rel\ + 1 + 0 + 0 + + 0 + 0 + + + 0 + 0 + 0 + 0 + + + 1 + 0 + cmd /c "del .\rel\qstamp.o" + + 0 + 0 + 0 + 0 + + + 1 + 0 + fromelf --bin --output .\rel\bb-qk.bin .\rel\bb-qk.axf + + 0 + 0 + 0 + 0 + + 0 + + + + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 3 + + + 1 + + + SARMCM3.DLL + -REMAP + DARMCM1.DLL + -pCM0+ + SARMCM3.DLL + + TARMCM1.DLL + -pCM0+ + + + + 1 + 0 + 0 + 0 + 16 + + + + + 1 + 0 + 0 + 1 + 1 + 4097 + + 1 + BIN\UL2CM3.DLL + + + + + + 0 + + + + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + 1 + 0 + 0 + 0 + 0 + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + "Cortex-M0+" + + 0 + 0 + 0 + 1 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 8 + 0 + 0 + 0 + 0 + 3 + 3 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 1 + 0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x20000000 + 0x2000 + + + 1 + 0x8000000 + 0x10000 + + + 0 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x8000000 + 0x10000 + + + 1 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x20000000 + 0x2000 + + + 0 + 0x0 + 0x0 + + + + + + 0 + 7 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 3 + 0 + 1 + 0 + 0 + 0 + 3 + 3 + 0 + 0 + 0 + 0 + 0 + + + NDEBUG + + ..\..;..\..\..\..\..\include;..\..\..\..\..\ports\arm-cm\qk\armclang;..\..\..\..\..\3rd_party\CMSIS\Include;..\..\..\..\..\3rd_party\nucleo-l053r8 + + + + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 4 + + + Stack_Size=2048 Heap_Size=16 + + + + + + 1 + 0 + 0 + 0 + 1 + 0 + 0x00000000 + 0x20000000 + + bb-qk.sct + + + --entry Reset_Handler + + + + + + + + Source Code + + + bsp.c + 1 + ..\bsp.c + + + bsp.h + 5 + ..\..\bsp.h + + + qstamp.c + 1 + ..\..\..\..\..\src\qs\qstamp.c + + + main.c + 1 + ..\main.c + + + blinky_button.h + 5 + ..\..\blinky_button.h + + + blinky1.c + 1 + ..\..\blinky1.c + + + blinky3.c + 1 + ..\..\blinky3.c + + + button2a.c + 1 + ..\..\button2a.c + + + button2b.c + 1 + ..\..\button2b.c + + + + + nucleo-l053r8 + + + stm32l0xx.h + 5 + ..\..\..\..\..\3rd_party\nucleo-l053r8\stm32l0xx.h + + + stm32l053xx.h + 5 + ..\..\..\..\..\3rd_party\nucleo-l053r8\stm32l053xx.h + + + system_stm32l0xx.c + 1 + ..\..\..\..\..\3rd_party\nucleo-l053r8\system_stm32l0xx.c + + + system_stm32l0xx.h + 5 + ..\..\..\..\..\3rd_party\nucleo-l053r8\system_stm32l0xx.h + + + startup_stm32l053xx.s + 2 + ..\..\..\..\..\3rd_party\nucleo-l053r8\arm\startup_stm32l053xx.s + + + + + QP + + + qep_hsm.c + 1 + ..\..\..\..\..\src\qf\qep_hsm.c + + + qep_msm.c + 1 + ..\..\..\..\..\src\qf\qep_msm.c + + + qf_act.c + 1 + ..\..\..\..\..\src\qf\qf_act.c + + + qf_actq.c + 1 + ..\..\..\..\..\src\qf\qf_actq.c + + + qf_defer.c + 1 + ..\..\..\..\..\src\qf\qf_defer.c + + + qf_dyn.c + 1 + ..\..\..\..\..\src\qf\qf_dyn.c + + + qf_mem.c + 1 + ..\..\..\..\..\src\qf\qf_mem.c + + + qf_ps.c + 1 + ..\..\..\..\..\src\qf\qf_ps.c + + + qf_qact.c + 1 + ..\..\..\..\..\src\qf\qf_qact.c + + + qf_qeq.c + 1 + ..\..\..\..\..\src\qf\qf_qeq.c + + + qf_qmact.c + 1 + ..\..\..\..\..\src\qf\qf_qmact.c + + + qf_time.c + 1 + ..\..\..\..\..\src\qf\qf_time.c + + + qk.c + 1 + ..\..\..\..\..\src\qk\qk.c + + + + + QP_port + + + qep_port.h + 5 + ..\..\..\..\..\ports\arm-cm\qk\armclang\qep_port.h + + + qf_port.h + 5 + ..\..\..\..\..\ports\arm-cm\qk\armclang\qf_port.h + + + qk_port.h + 5 + ..\..\..\..\..\ports\arm-cm\qk\armclang\qk_port.h + + + qs_port.h + 5 + ..\..\..\..\..\ports\arm-cm\qk\armclang\qs_port.h + + + qk_port.c + 1 + ..\..\..\..\..\ports\arm-cm\qk\armclang\qk_port.c + + + + + QS + + + 0 + 0 + 0 + 0 + 0 + 0 + 2 + 2 + 2 + 2 + 11 + + + 1 + + + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 0 + 0 + 0 + 0 + 2 + + + + + + + + + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + + + + + + + + + + + + qs.c + 1 + ..\..\..\..\..\src\qs\qs.c + + + qs_64bit.c + 1 + ..\..\..\..\..\src\qs\qs_64bit.c + + + qs_fp.c + 1 + ..\..\..\..\..\src\qs\qs_fp.c + + + qs_rx.c + 1 + ..\..\..\..\..\src\qs\qs_rx.c + + + + + + + bb-spy + 0x4 + ARM-ADS + 6160000::V6.16::ARMCLANG + 1 + + + STM32L053R8Tx + STMicroelectronics + Keil.STM32L0xx_DFP.2.2.0 + http://www.keil.com/pack/ + IRAM(0x20000000,0x00002000) IROM(0x08000000,0x00010000) CPUTYPE("Cortex-M0+") CLOCK(12000000) ELITTLE + + + UL2CM3(-S0 -C0 -P0 -FD20000000 -FC1000 -FN1 -FF0STM32L0xx_64 -FS08000000 -FL010000 -FP0($$Device:STM32L053R8Tx$Flash\STM32L0xx_64.FLM)) + 0 + $$Device:STM32L053R8Tx$Device\Include\stm32l0xx.h + + + + + + + + + + $$Device:STM32L053R8Tx$SVD\STM32L053x.svd + 0 + 0 + + + + + + + 0 + 0 + 0 + 0 + 1 + + .\spy\ + bb-qk + 1 + 0 + 0 + 1 + 1 + .\spy\ + 1 + 0 + 0 + + 0 + 0 + + + 0 + 0 + 0 + 0 + + + 1 + 0 + cmd /c "del .\spy\qstamp.o" + + 0 + 0 + 0 + 0 + + + 1 + 0 + fromelf --bin --output .\spy\bb-qk.bin .\spy\bb-qk.axf + + 0 + 0 + 0 + 0 + + 0 + + + + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 3 + + + 1 + + + SARMCM3.DLL + -REMAP + DARMCM1.DLL + -pCM0+ + SARMCM3.DLL + + TARMCM1.DLL + -pCM0+ + + + + 1 + 0 + 0 + 0 + 16 + + + + + 1 + 0 + 0 + 1 + 1 + 4096 + + 1 + BIN\UL2CM3.DLL + + + + + + 0 + + + + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + 1 + 0 + 0 + 0 + 0 + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + "Cortex-M0+" + + 0 + 0 + 0 + 1 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 8 + 0 + 0 + 0 + 0 + 3 + 3 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 1 + 0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x20000000 + 0x2000 + + + 1 + 0x8000000 + 0x10000 + + + 0 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x8000000 + 0x10000 + + + 1 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x20000000 + 0x2000 + + + 0 + 0x0 + 0x0 + + + + + + 0 + 7 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 3 + 0 + 1 + 0 + 0 + 0 + 3 + 3 + 0 + 0 + 0 + 0 + 0 + + + Q_SPY QK_USE_IRQ_HANDLER=LCD_IRQHandler QK_USE_IRQ_NUM=30 + + ..\..;..\..\..\..\..\include;..\..\..\..\..\ports\arm-cm\qk\armclang;..\..\..\..\..\3rd_party\CMSIS\Include;..\..\..\..\..\3rd_party\nucleo-l053r8 + + + + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 4 + + + Stack_Size=2048 Heap_Size=16 + + + + + + 1 + 0 + 0 + 0 + 1 + 0 + 0x00000000 + 0x20000000 + + bb-qk.sct + + + --entry Reset_Handler + + + + + + + + Source Code + + + bsp.c + 1 + ..\bsp.c + + + bsp.h + 5 + ..\..\bsp.h + + + qstamp.c + 1 + ..\..\..\..\..\src\qs\qstamp.c + + + main.c + 1 + ..\main.c + + + blinky_button.h + 5 + ..\..\blinky_button.h + + + blinky1.c + 1 + ..\..\blinky1.c + + + blinky3.c + 1 + ..\..\blinky3.c + + + button2a.c + 1 + ..\..\button2a.c + + + button2b.c + 1 + ..\..\button2b.c + + + + + nucleo-l053r8 + + + stm32l0xx.h + 5 + ..\..\..\..\..\3rd_party\nucleo-l053r8\stm32l0xx.h + + + stm32l053xx.h + 5 + ..\..\..\..\..\3rd_party\nucleo-l053r8\stm32l053xx.h + + + system_stm32l0xx.c + 1 + ..\..\..\..\..\3rd_party\nucleo-l053r8\system_stm32l0xx.c + + + system_stm32l0xx.h + 5 + ..\..\..\..\..\3rd_party\nucleo-l053r8\system_stm32l0xx.h + + + startup_stm32l053xx.s + 2 + ..\..\..\..\..\3rd_party\nucleo-l053r8\arm\startup_stm32l053xx.s + + + + + QP + + + qep_hsm.c + 1 + ..\..\..\..\..\src\qf\qep_hsm.c + + + qep_msm.c + 1 + ..\..\..\..\..\src\qf\qep_msm.c + + + qf_act.c + 1 + ..\..\..\..\..\src\qf\qf_act.c + + + qf_actq.c + 1 + ..\..\..\..\..\src\qf\qf_actq.c + + + qf_defer.c + 1 + ..\..\..\..\..\src\qf\qf_defer.c + + + qf_dyn.c + 1 + ..\..\..\..\..\src\qf\qf_dyn.c + + + qf_mem.c + 1 + ..\..\..\..\..\src\qf\qf_mem.c + + + qf_ps.c + 1 + ..\..\..\..\..\src\qf\qf_ps.c + + + qf_qact.c + 1 + ..\..\..\..\..\src\qf\qf_qact.c + + + qf_qeq.c + 1 + ..\..\..\..\..\src\qf\qf_qeq.c + + + qf_qmact.c + 1 + ..\..\..\..\..\src\qf\qf_qmact.c + + + qf_time.c + 1 + ..\..\..\..\..\src\qf\qf_time.c + + + qk.c + 1 + ..\..\..\..\..\src\qk\qk.c + + + + + QP_port + + + qep_port.h + 5 + ..\..\..\..\..\ports\arm-cm\qk\armclang\qep_port.h + + + qf_port.h + 5 + ..\..\..\..\..\ports\arm-cm\qk\armclang\qf_port.h + + + qk_port.h + 5 + ..\..\..\..\..\ports\arm-cm\qk\armclang\qk_port.h + + + qs_port.h + 5 + ..\..\..\..\..\ports\arm-cm\qk\armclang\qs_port.h + + + qk_port.c + 1 + ..\..\..\..\..\ports\arm-cm\qk\armclang\qk_port.c + + + + + QS + + + qs.c + 1 + ..\..\..\..\..\src\qs\qs.c + + + qs_64bit.c + 1 + ..\..\..\..\..\src\qs\qs_64bit.c + + + qs_fp.c + 1 + ..\..\..\..\..\src\qs\qs_fp.c + + + qs_rx.c + 1 + ..\..\..\..\..\src\qs\qs_rx.c + + + + + + + + + + + + + +
diff --git a/examples/arm-cm/blinky_button_nucleo-l053r8/qk/bsp.c b/examples/arm-cm/blinky_button_nucleo-l053r8/qk/bsp.c new file mode 100644 index 00000000..634be35f --- /dev/null +++ b/examples/arm-cm/blinky_button_nucleo-l053r8/qk/bsp.c @@ -0,0 +1,268 @@ +//============================================================================ +// QP/C Example +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +//============================================================================ +#include "qpc.h" // QP/C API +#include "bsp.h" // Board Support Package interface +#include "blinky_button.h" // application shared interface + +#include "stm32l0xx.h" // CMSIS-compliant header file for the MCU used +// add other drivers if necessary... + +Q_DEFINE_THIS_MODULE("bsp_nucleo-l053r8") // for DBC assertions + +// Local-scope defines ----------------------------------------------------- + +// test pins on GPIO PA +#define TST1_PIN 7U +#define TST2_PIN 6U +#define TST3_PIN 4U +#define TST4_PIN 1U +#define TST5_PIN 0U +#define TST6_PIN 5U // LED LD2-Green + +// buttons on GPIO PC +#define B1_PIN 13U + +#ifdef Q_SPY + // QSpy source IDs + static QSpyId const l_SysTick_Handler = { 100U }; + +#endif + +// ISRs used in the application ============================================ +void SysTick_Handler(void); // prototype + +void SysTick_Handler(void) { // system clock tick ISR + BSP_d1on(); + + QK_ISR_ENTRY(); // inform QK about entering an ISR + + + // process time events for rate 0 + QTIMEEVT_TICK_X(0U, &l_SysTick_Handler); + + // Perform the debouncing of buttons. The algorithm for debouncing + // adapted from the book "Embedded Systems Dictionary" by Jack Ganssle + // and Michael Barr, page 71. + // + static struct ButtonsDebouncing { + uint32_t depressed; + uint32_t previous; + } buttons = { 0U, 0U }; + uint32_t current = ~GPIOC->IDR; // read GPIO PortC + uint32_t tmp = buttons.depressed; // save the debounced depressed + buttons.depressed |= (buttons.previous & current); // set depressed + buttons.depressed &= (buttons.previous | current); // clear released + buttons.previous = current; // update the history + tmp ^= buttons.depressed; // changed debounced depressed + if ((tmp & (1U << B1_PIN)) != 0U) { // debounced B1 state changed? + if ((buttons.depressed & (1U << B1_PIN)) != 0U) { // depressed? + // immutable button-press event + static ButtonWorkEvt const pressEvt = { + QEVT_INITIALIZER(BUTTON_PRESSED_SIG), + .toggles = 60U + }; + // immutable forward-press event + static ButtonWorkEvt const fPressEvt = { + QEVT_INITIALIZER(FORWARD_PRESSED_SIG), + .toggles = 60U + }; + QACTIVE_POST(AO_Button2a, &fPressEvt.super, &l_SysTick_Handler); + QACTIVE_POST(AO_Button2a, &pressEvt.super, &l_SysTick_Handler); + } + else { // B1 is released + // immutable button-release event + static ButtonWorkEvt const releaseEvt = { + QEVT_INITIALIZER(BUTTON_RELEASED_SIG), + .toggles = 80U + }; + // immutable forward-release event + static ButtonWorkEvt const fReleaseEvt = { + QEVT_INITIALIZER(FORWARD_RELEASED_SIG), + .toggles = 80U + }; + QACTIVE_POST(AO_Button2a, &fReleaseEvt.super, &l_SysTick_Handler); + QACTIVE_POST(AO_Button2a, &releaseEvt.super, &l_SysTick_Handler); + } + } + + QK_ISR_EXIT(); // inform QK about exiting an ISR + + BSP_d1off(); +} + +// BSP functions =========================================================== +void BSP_init(void) { + // Configure the MPU to prevent NULL-pointer dereferencing + // see: www.state-machine.com/null-pointer-protection-with-arm-cortex-m-mpu + // + MPU->RBAR = 0x0U // base address (NULL) + | MPU_RBAR_VALID_Msk // valid region + | (MPU_RBAR_REGION_Msk & 7U); // region #7 + MPU->RASR = (7U << MPU_RASR_SIZE_Pos) // 2^(7+1) region + | (0x0U << MPU_RASR_AP_Pos) // no-access region + | MPU_RASR_ENABLE_Msk; // region enable + + MPU->CTRL = MPU_CTRL_PRIVDEFENA_Msk // enable background region + | MPU_CTRL_ENABLE_Msk; // enable the MPU + __ISB(); + __DSB(); + + // enable GPIO port PA clock + RCC->IOPENR |= (1U << 0U); + + // set all used GPIOA pins as push-pull output, no pull-up, pull-down + GPIOA->MODER &= + ~((3U << 2U*TST1_PIN) | (3U << 2U*TST2_PIN) | (3U << 2U*TST3_PIN) | + (3U << 2U*TST4_PIN) | (3U << 2U*TST5_PIN) | (3U << 2U*TST6_PIN)); + GPIOA->MODER |= + ((1U << 2U*TST1_PIN) | (1U << 2U*TST2_PIN) | (1U << 2U*TST3_PIN) | + (1U << 2U*TST4_PIN) | (1U << 2U*TST5_PIN) | (1U << 2U*TST6_PIN)); + GPIOA->OTYPER &= + ~((1U << TST1_PIN) | (1U << TST2_PIN) | (1U << TST3_PIN) | + (1U << TST4_PIN) | (1U << TST5_PIN) | (1U << TST6_PIN)); + GPIOA->PUPDR &= + ~((3U << 2U*TST1_PIN) | (3U << 2U*TST2_PIN) | (3U << 2U*TST3_PIN) | + (3U << 2U*TST4_PIN) | (3U << 2U*TST5_PIN) | (3U << 2U*TST6_PIN)); + + // enable GPIOC clock port for the Button B1 + RCC->IOPENR |= (1U << 2U); + + // configure Button B1 pin on GPIOC as input, no pull-up, pull-down + GPIOC->MODER &= ~(3U << 2U*B1_PIN); + GPIOC->PUPDR &= ~(3U << 2U*B1_PIN); +} + +//............................................................................ +void BSP_d1on(void) { GPIOA->BSRR = (1U << TST1_PIN); } +void BSP_d1off(void) { GPIOA->BSRR = (1U << (TST1_PIN + 16U)); } +//............................................................................ +void BSP_d2on(void) { GPIOA->BSRR = (1U << TST2_PIN); } +void BSP_d2off(void) { GPIOA->BSRR = (1U << (TST2_PIN + 16U)); } +//............................................................................ +void BSP_d3on(void) { GPIOA->BSRR = (1U << TST3_PIN); } +void BSP_d3off(void) { GPIOA->BSRR = (1U << (TST3_PIN + 16U)); } +//............................................................................ +void BSP_d4on(void) { GPIOA->BSRR = (1U << TST4_PIN); } +void BSP_d4off(void) { GPIOA->BSRR = (1U << (TST4_PIN + 16U)); } +//............................................................................ +void BSP_d5on(void) { GPIOA->BSRR = (1U << TST5_PIN); } +void BSP_d5off(void) { GPIOA->BSRR = (1U << (TST5_PIN + 16U)); } +//............................................................................ +void BSP_d6on(void) { GPIOA->BSRR = (1U << TST6_PIN); } // LED2 +void BSP_d6off(void) { GPIOA->BSRR = (1U << (TST6_PIN + 16U)); } + +//............................................................................ +QEvt const *BSP_getWorkEvtBlinky1(uint8_t num) { + // immutable work events for Blinky1 + static BlinkyWorkEvt const workBlinky1[] = { + { + QEVT_INITIALIZER(BLINKY_WORK_SIG), + .toggles = 40U, + .ticks = 5U, + }, + { + QEVT_INITIALIZER(BLINKY_WORK_SIG), + .toggles = 30U, + .ticks = 7U, + } + }; + Q_REQUIRE_ID(500, num < Q_DIM(workBlinky1)); // must be in range + return &workBlinky1[num].super; +} +//............................................................................ +QEvt const *BSP_getWorkEvtBlinky3(uint8_t num) { + // immutable work events for Blinky3 + static BlinkyWorkEvt const workBlinky3[] = { + { + QEVT_INITIALIZER(BLINKY_WORK_SIG), + .toggles = 20U, + .ticks = 5U, + }, + { + QEVT_INITIALIZER(BLINKY_WORK_SIG), + .toggles = 10U, + .ticks = 3U, + } + }; + Q_REQUIRE_ID(600, num < Q_DIM(workBlinky3)); // must be in range + return &workBlinky3[num].super; +} + +// QF callbacks ============================================================ +void QF_onStartup(void) { + SystemCoreClockUpdate(); + + // set up the SysTick timer to fire at BSP_TICKS_PER_SEC rate + SysTick_Config((SystemCoreClock / BSP_TICKS_PER_SEC) + 1U); + + // set priorities of ISRs used in the system + NVIC_SetPriority(SysTick_IRQn, 0U); + // ... +} +//............................................................................ +void QF_onCleanup(void) { +} +//............................................................................ +void QK_onIdle(void) { + BSP_d6on(); // turn LED2 on +#ifdef NDEBUG + // Put the CPU and peripherals to the low-power mode. + // you might need to customize the clock management for your application, + // see the datasheet for your particular Cortex-M MCU. + // + BSP_d6off(); // turn LED2 off + __WFI(); // Wait-For-Interrupt + BSP_d6on(); // turn LED2 on +#endif + BSP_d6off(); // turn LED2 off +} + +//............................................................................ +Q_NORETURN Q_onError(char const * const module, int_t const id) { + // + // NOTE: add here your application-specific error handling + // + Q_UNUSED_PAR(module); + Q_UNUSED_PAR(id); + + QS_ASSERTION(module, id, 10000U); // report assertion to QS + +#ifndef NDEBUG + for (;;) { + } +#endif + NVIC_SystemReset(); +} +//............................................................................ +void assert_failed(char const * const module, int_t const id); // prototype +void assert_failed(char const * const module, int_t const id) { + Q_onError(module, id); +} + diff --git a/examples/arm-cm/blinky_button_nucleo-l053r8/qk/main.c b/examples/arm-cm/blinky_button_nucleo-l053r8/qk/main.c new file mode 100644 index 00000000..58ea3118 --- /dev/null +++ b/examples/arm-cm/blinky_button_nucleo-l053r8/qk/main.c @@ -0,0 +1,88 @@ +//============================================================================ +// QP/C Example +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +//============================================================================ +#include "qpc.h" // QP/C API +#include "bsp.h" // Board Support Package interface +#include "blinky_button.h" // application shared interface + +Q_DEFINE_THIS_MODULE("main") + +//............................................................................ +int main() { + QF_init(); // initialize the QF framework + BSP_init(); // initialize the Board Support Package + + // instantiate and start QP/C active objects... + Blinky1_instantiate(); + static QEvt const *blinky1QSto[10]; // Event queue storage + QACTIVE_START( + AO_Blinky1, // AO pointer to start + Q_PRIO(1U, 1U), // QF-prio/pre-thre. + blinky1QSto, // storage for the AO's queue + Q_DIM(blinky1QSto), // queue length + (void *)0, // stack storage (not used) + 0U, // size of the stack [bytes] + BSP_getWorkEvtBlinky1(0U)); // initialization event + + Button2a_instantiate(); + static QEvt const *button2aQSto[8]; // Event queue storage + QACTIVE_START( + AO_Button2a, // AO pointer to start + Q_PRIO(2U, 3U), // QF-prio/pre-thre. + button2aQSto, // storage for the AO's queue + Q_DIM(button2aQSto), // queue length + (void *)0, // stack storage (not used) + 0U, // size of the stack [bytes] + (QEvt const *)0); // initialization event -- not used + + Button2b_instantiate(); + static QEvt const *button2bQSto[8]; // Event queue storage + QACTIVE_START( + AO_Button2b, // AO pointer to start + Q_PRIO(3U, 3U), // QF-prio/pre-thre. + button2bQSto, // storage for the AO's queue + Q_DIM(button2bQSto), // queue length + (void *)0, // stack storage (not used) + 0U, // size of the stack [bytes] + (QEvt const *)0); // initialization event -- not used + + Blinky3_instantiate(); + static QEvt const *blinky3QSto[8]; // Event queue storage + QACTIVE_START( + AO_Blinky3, // AO pointer to start + Q_PRIO(4U, 4U), // QF-prio/pre-thre. + blinky3QSto, // storage for the AO's queue + Q_DIM(blinky3QSto), // queue length + (void *)0, // stack storage (not used) + 0U, // size of the stack [bytes] + BSP_getWorkEvtBlinky3(0U)); // initialization event + + return QF_run(); // run the QF application + // NOTE: in embedded systems QF_run() should not return +} diff --git a/examples/arm-cm/blinky_button_nucleo-l053r8/qk/test_pulseview/blinky_button-freertos.pvs b/examples/arm-cm/blinky_button_nucleo-l053r8/qk/test_pulseview/blinky_button-freertos.pvs new file mode 100644 index 00000000..976c9097 --- /dev/null +++ b/examples/arm-cm/blinky_button_nucleo-l053r8/qk/test_pulseview/blinky_button-freertos.pvs @@ -0,0 +1,139 @@ +[General] +decode_signals=0 +generated_signals=0 +views=1 +meta_objs=0 + +[D0] +name=Button +enabled=true +color=4279638298 +conversion_type=0 +conv_options=0 + +[D1] +name=SysTick +enabled=true +color=4287582722 +conversion_type=0 +conv_options=0 + +[D2] +name=Blinky3 +enabled=true +color=4291559424 +conversion_type=0 +conv_options=0 + +[D3] +name=Button2b +enabled=true +color=4294277376 +conversion_type=0 +conv_options=0 + +[D4] +name=Button2a +enabled=true +color=4293776384 +conversion_type=0 +conv_options=0 + +[D5] +name=Blinky1 +enabled=true +color=4285780502 +conversion_type=0 +conv_options=0 + +[D6] +name=Idle0 +enabled=true +color=4281623972 +conversion_type=0 +conv_options=0 + +[D7] +name=D7 +enabled=true +color=4285878395 +conversion_type=0 +conv_options=0 + +[view0] +scale=3.7605294825511427e-5 +v_offset=-3 +splitter_state=@ByteArray(\0\0\0\xff\0\0\0\x1\0\0\0\x2\0\0\0^\0\0\x4\x65\x1\0\0\0\x1\x1\0\0\0\x1\0) +segment_display_mode=1 +offset=22 serialization::archive 14 0 0 0 0 0 0 0 0 0 0 0 0 0 6 +zero_offset=22 serialization::archive 14 0 0 0 0 0 0 0 0 0 0 0 0 0 6 +D0\trace_height=40 +D1\trace_height=40 +D2\trace_height=40 +D3\trace_height=40 +D4\trace_height=40 +D5\trace_height=40 +D6\trace_height=40 +D7\trace_height=40 +Button\trace_height=40 +SysTick\trace_height=40 +Blinky3\trace_height=40 +Button2b\trace_height=40 +Button2a\trace_height=40 +Blinky1\trace_height=40 +Idle0\trace_height=40 + +[meta_obj0] +type=selection +assoc_view=0 +start_time=22 serialization::archive 14 0 0 0 0 1944566 17002629 27007454 29442577 582965 36027668 -8 0 0 6 +end_time=22 serialization::archive 14 0 0 0 0 2901329 24335378 30189438 36680136 88293285 53794622 -8 0 0 6 + +[Button] +name=Button +enabled=true +color=4279638298 +conversion_type=0 +conv_options=0 + +[SysTick] +name=SysTick +enabled=true +color=4287582722 +conversion_type=0 +conv_options=0 + +[Blinky3] +name=Blinky3 +enabled=true +color=4291559424 +conversion_type=0 +conv_options=0 + +[Button2b] +name=Button2b +enabled=true +color=4294277376 +conversion_type=0 +conv_options=0 + +[Button2a] +name=Button2a +enabled=true +color=4293776384 +conversion_type=0 +conv_options=0 + +[Blinky1] +name=Blinky1 +enabled=true +color=4285780502 +conversion_type=0 +conv_options=0 + +[Idle0] +name=Idle0 +enabled=true +color=4281623972 +conversion_type=0 +conv_options=0 diff --git a/examples/arm-cm/blinky_button_nucleo-l053r8/qk/test_pulseview/blinky_button-freertos.sr b/examples/arm-cm/blinky_button_nucleo-l053r8/qk/test_pulseview/blinky_button-freertos.sr new file mode 100644 index 00000000..febc6da4 Binary files /dev/null and b/examples/arm-cm/blinky_button_nucleo-l053r8/qk/test_pulseview/blinky_button-freertos.sr differ diff --git a/examples/arm-cm/blinky_button_nucleo-l053r8/qk/test_pulseview/blinky_button-qk.pvs b/examples/arm-cm/blinky_button_nucleo-l053r8/qk/test_pulseview/blinky_button-qk.pvs new file mode 100644 index 00000000..050f816c --- /dev/null +++ b/examples/arm-cm/blinky_button_nucleo-l053r8/qk/test_pulseview/blinky_button-qk.pvs @@ -0,0 +1,83 @@ +[General] +decode_signals=0 +generated_signals=0 +views=1 +meta_objs=1 + +[D0] +name=Button +enabled=true +color=4279638298 +conversion_type=0 +conv_options=0 + +[D1] +name=SysTick +enabled=true +color=4287582722 +conversion_type=0 +conv_options=0 + +[D2] +name=Blinky3 +enabled=true +color=4291559424 +conversion_type=0 +conv_options=0 + +[D3] +name=Button2b +enabled=true +color=4294277376 +conversion_type=0 +conv_options=0 + +[D4] +name=Button2a +enabled=true +color=4293776384 +conversion_type=0 +conv_options=0 + +[D5] +name=Blinky1 +enabled=true +color=4285780502 +conversion_type=0 +conv_options=0 + +[D6] +name=Idle0 +enabled=true +color=4281623972 +conversion_type=0 +conv_options=0 + +[D7] +name=D7 +enabled=false +color=4285878395 +conversion_type=0 +conv_options=0 + +[view0] +scale=3.2087534794920533e-6 +v_offset=0 +splitter_state=@ByteArray(\0\0\0\xff\0\0\0\x1\0\0\0\x2\0\0\0^\0\0\x5\x8a\x1\0\0\0\x1\x1\0\0\0\x1\0) +segment_display_mode=3 +offset=22 serialization::archive 14 0 0 0 0 1362025 60585276 64363806 88139934 35846573 28985670 -8 0 0 6 +zero_offset=22 serialization::archive 14 0 0 0 0 0 0 0 0 0 0 0 0 0 6 +D0\trace_height=40 +D1\trace_height=40 +D2\trace_height=40 +D3\trace_height=40 +D4\trace_height=40 +D5\trace_height=40 +D6\trace_height=40 +D7\trace_height=40 + +[meta_obj0] +type=selection +assoc_view=0 +start_time=22 serialization::archive 14 0 0 0 0 1534066 66666666 67380947 15327633 82128904 74769012 -8 0 0 6 +end_time=22 serialization::archive 14 0 0 0 0 1628066 66666666 65509666 24527063 68640064 41728332 -8 0 0 6 diff --git a/examples/arm-cm/blinky_button_nucleo-l053r8/qk/test_pulseview/blinky_button-qk.sr b/examples/arm-cm/blinky_button_nucleo-l053r8/qk/test_pulseview/blinky_button-qk.sr new file mode 100644 index 00000000..c5ee7ccf Binary files /dev/null and b/examples/arm-cm/blinky_button_nucleo-l053r8/qk/test_pulseview/blinky_button-qk.sr differ diff --git a/examples/arm-cm/blinky_button_nucleo-l053r8/qk/test_pulseview/blinky_button-qk2.sr b/examples/arm-cm/blinky_button_nucleo-l053r8/qk/test_pulseview/blinky_button-qk2.sr new file mode 100644 index 00000000..5d73ef56 Binary files /dev/null and b/examples/arm-cm/blinky_button_nucleo-l053r8/qk/test_pulseview/blinky_button-qk2.sr differ diff --git a/examples/arm-cm/blinky_button_nucleo-l053r8/qk/test_pulseview/blinky_button-sst.pvs b/examples/arm-cm/blinky_button_nucleo-l053r8/qk/test_pulseview/blinky_button-sst.pvs new file mode 100644 index 00000000..d034076b --- /dev/null +++ b/examples/arm-cm/blinky_button_nucleo-l053r8/qk/test_pulseview/blinky_button-sst.pvs @@ -0,0 +1,77 @@ +[General] +decode_signals=0 +generated_signals=0 +views=1 +meta_objs=0 + +[D0] +name=Button +enabled=true +color=4279638298 +conversion_type=0 +conv_options=0 + +[D1] +name=SysTick +enabled=true +color=4287582722 +conversion_type=0 +conv_options=0 + +[D2] +name=Blinky3 +enabled=true +color=4291559424 +conversion_type=0 +conv_options=0 + +[D3] +name=Button2b +enabled=true +color=4294277376 +conversion_type=0 +conv_options=0 + +[D4] +name=Button2a +enabled=true +color=4293776384 +conversion_type=0 +conv_options=0 + +[D5] +name=Blinky1 +enabled=true +color=4285780502 +conversion_type=0 +conv_options=0 + +[D6] +name=Idle0 +enabled=true +color=4281623972 +conversion_type=0 +conv_options=0 + +[D7] +name=D7 +enabled=false +color=4285878395 +conversion_type=0 +conv_options=0 + +[view0] +scale=4.943214819758028e-6 +v_offset=-7 +splitter_state=@ByteArray(\0\0\0\xff\0\0\0\x1\0\0\0\x2\0\0\0^\0\0\x4g\x1\0\0\0\x1\x1\0\0\0\x1\0) +segment_display_mode=1 +offset=22 serialization::archive 14 0 0 0 0 1193770 93142525 24953095 35642233 6752429 22158737 -8 0 0 6 +zero_offset=22 serialization::archive 14 0 0 0 0 0 0 0 0 0 0 0 0 0 6 +D0\trace_height=40 +D1\trace_height=40 +D2\trace_height=40 +D3\trace_height=40 +D4\trace_height=40 +D5\trace_height=40 +D6\trace_height=40 +D7\trace_height=40 diff --git a/examples/arm-cm/blinky_button_nucleo-l053r8/qk/test_pulseview/blinky_button-sst.sr b/examples/arm-cm/blinky_button_nucleo-l053r8/qk/test_pulseview/blinky_button-sst.sr new file mode 100644 index 00000000..936c04c7 Binary files /dev/null and b/examples/arm-cm/blinky_button_nucleo-l053r8/qk/test_pulseview/blinky_button-sst.sr differ diff --git a/examples/arm-cm/blinky_button_nucleo-l053r8/stm32-nucleo-l053r8.jpg b/examples/arm-cm/blinky_button_nucleo-l053r8/stm32-nucleo-l053r8.jpg new file mode 100644 index 00000000..1c7c4159 Binary files /dev/null and b/examples/arm-cm/blinky_button_nucleo-l053r8/stm32-nucleo-l053r8.jpg differ diff --git a/examples/arm-cm/blinky_efm32-slstk3401a/README.md b/examples/arm-cm/blinky_efm32-slstk3401a/README.md deleted file mode 100644 index 0502853f..00000000 --- a/examples/arm-cm/blinky_efm32-slstk3401a/README.md +++ /dev/null @@ -1,5 +0,0 @@ -![STM32 EFM32-SLSTK3401A](../../../doxygen/images/bd_EFM32-SLSTK3401A.jpg) - -Documentation for this example is available in the QP/C Manual at: - -- https://www.state-machine.com/qpc/arm-cm_blinky_efm32-slstk3401a.html diff --git a/examples/arm-cm/blinky_efm32-slstk3401a/blinky.c b/examples/arm-cm/blinky_efm32-slstk3401a/blinky.c deleted file mode 100644 index 0f92891b..00000000 --- a/examples/arm-cm/blinky_efm32-slstk3401a/blinky.c +++ /dev/null @@ -1,111 +0,0 @@ -/***************************************************************************** -* Product: Simple Blinky example -* Last Updated for Version: 5.6.4 -* Date of the Last Update: 2016-05-07 -* -* Q u a n t u m L e a P s -* --------------------------- -* innovating embedded systems -* -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* Web: www.state-machine.com -* -*****************************************************************************/ -#include "qpc.h" -#include "blinky.h" -#include "bsp.h" - -//Q_DEFINE_THIS_FILE - -/*..........................................................................*/ -typedef struct { /* the Blinky active object */ - QActive super; /* inherit QActive */ - - QTimeEvt timeEvt; /* private time event generator */ -} Blinky; - -static Blinky l_blinky; /* the Blinky active object */ - -QActive * const AO_Blinky = &l_blinky.super; - -/* hierarchical state machine ... */ -static QState Blinky_initial(Blinky * const me, QEvt const * const e); -static QState Blinky_off (Blinky * const me, QEvt const * const e); -static QState Blinky_on (Blinky * const me, QEvt const * const e); - -/*..........................................................................*/ -void Blinky_ctor(void) { - Blinky * const me = &l_blinky; - QActive_ctor(&me->super, Q_STATE_CAST(&Blinky_initial)); - QTimeEvt_ctorX(&me->timeEvt, &me->super, TIMEOUT_SIG, 0U); -} - -/* HSM definition ----------------------------------------------------------*/ -QState Blinky_initial(Blinky * const me, QEvt const * const e) { - (void)e; /* avoid compiler warning about unused parameter */ - - /* arm the time event to expire in half a second and every half second */ - QTimeEvt_armX(&me->timeEvt, BSP_TICKS_PER_SEC/2U, BSP_TICKS_PER_SEC/2U); - return Q_TRAN(&Blinky_off); -} -/*..........................................................................*/ -QState Blinky_off(Blinky * const me, QEvt const * const e) { - QState status; - switch (e->sig) { - case Q_ENTRY_SIG: { - BSP_ledOff(); - status = Q_HANDLED(); - break; - } - case TIMEOUT_SIG: { - status = Q_TRAN(&Blinky_on); - break; - } - default: { - status = Q_SUPER(&QHsm_top); - break; - } - } - return status; -} -/*..........................................................................*/ -QState Blinky_on(Blinky * const me, QEvt const * const e) { - QState status; - switch (e->sig) { - case Q_ENTRY_SIG: { - BSP_ledOn(); - status = Q_HANDLED(); - break; - } - case TIMEOUT_SIG: { - status = Q_TRAN(&Blinky_off); - break; - } - default: { - status = Q_SUPER(&QHsm_top); - break; - } - } - return status; -} - diff --git a/examples/arm-cm/blinky_efm32-slstk3401a/blinky.h b/examples/arm-cm/blinky_efm32-slstk3401a/blinky.h deleted file mode 100644 index 5568238a..00000000 --- a/examples/arm-cm/blinky_efm32-slstk3401a/blinky.h +++ /dev/null @@ -1,48 +0,0 @@ -/***************************************************************************** -* Product: simple "Blinky" example -* Last Updated for Version: 5.4.0 -* Date of the Last Update: 2015-03-07 -* -* Q u a n t u m L e a P s -* --------------------------- -* innovating embedded systems -* -* Copyright (C) 2005 Quantum Leaps, LLC. state-machine.com. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* -* -*****************************************************************************/ -#ifndef BLINKY_H -#define BLINKY_H - -enum BlinkySignals { - DUMMY_SIG = Q_USER_SIG, - MAX_PUB_SIG, /* the last published signal */ - - TIMEOUT_SIG, - MAX_SIG /* the last signal */ -}; - -void Blinky_ctor(void); -extern QActive * const AO_Blinky; /* opaque pointer */ - -#endif /* BLINKY_H */ diff --git a/examples/arm-cm/blinky_efm32-slstk3401a/bsp.h b/examples/arm-cm/blinky_efm32-slstk3401a/bsp.h deleted file mode 100644 index 6bdf810d..00000000 --- a/examples/arm-cm/blinky_efm32-slstk3401a/bsp.h +++ /dev/null @@ -1,43 +0,0 @@ -/***************************************************************************** -* Product: "Blinky" example -* Last Updated for Version: 5.8.2 -* Date of the Last Update: 2017-01-27 -* -* Q u a n t u m L e a P s -* --------------------------- -* innovating embedded systems -* -* Copyright (C) 2005 Quantum Leaps, LLC. state-machine.com. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* -* -*****************************************************************************/ -#ifndef BSP_H -#define BSP_H - -#define BSP_TICKS_PER_SEC 1000U - -void BSP_init(void); -void BSP_ledOff(void); -void BSP_ledOn(void); - -#endif /* BSP_H */ diff --git a/examples/arm-cm/blinky_efm32-slstk3401a/main.c b/examples/arm-cm/blinky_efm32-slstk3401a/main.c deleted file mode 100644 index aac1a812..00000000 --- a/examples/arm-cm/blinky_efm32-slstk3401a/main.c +++ /dev/null @@ -1,60 +0,0 @@ -/***************************************************************************** -* Product: "Blinky" example -* Last updated for version 7.1.1 -* Last updated on 2022-09-22 -* -* Q u a n t u m L e a P s -* ------------------------ -* Modern Embedded Software -* -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* -* -*****************************************************************************/ -#include "qpc.h" -#include "blinky.h" -#include "bsp.h" - -Q_DEFINE_THIS_FILE - -/*..........................................................................*/ -int main() { - QF_init(); /* initialize the framework and the underlying RT kernel */ - BSP_init(); /* initialize the Board Support Package */ - - /* publish-subscribe not used, no call to QF_psInit() */ - /* dynamic event allocation not used, no call to QF_poolInit() */ - - /* instantiate and start the active objects... */ - Blinky_ctor(); - static QEvt const *l_blinkyQSto[10]; /* Event queue storage for Blinky */ - QACTIVE_START(AO_Blinky, /* AO pointer to start */ - 2U, /* QF-priority/preemption-threshold */ - l_blinkyQSto, /* storage for the AO's queue */ - Q_DIM(l_blinkyQSto), /* length of the queue [entries] */ - (void *)0, /* stack storage (not used in QK) */ - 0U, /* stack size [bytes] (not used in QK) */ - (QEvt *)0); /* initial event (or 0) */ - - return QF_run(); /* run the QF application */ -} diff --git a/examples/arm-cm/blinky_efm32-slstk3401a/qk/armclang/README.txt b/examples/arm-cm/blinky_efm32-slstk3401a/qk/armclang/README.txt deleted file mode 100644 index 17af30f2..00000000 --- a/examples/arm-cm/blinky_efm32-slstk3401a/qk/armclang/README.txt +++ /dev/null @@ -1,50 +0,0 @@ -About this Example -================== -This example demonstrates how to use the uVision IDE together with -the MDK-ARM toolchain. - -uVision Project File -==================== -The MDK-ARM uVision project file provided with this example uses -relative paths to the QP framework location (includes, port, and -libraries. These relative paths must be modified when the project -is moved to different relative location. - - -Adjusting Stack and Heap Sizes -============================== -The stack and heap sizes are determined in this project by the -command-line options for the ARM assembler (see the Asm tab in -the "Options for Target" dialog box in uVision). Specifically, -you should define symbols: Stack_Size=xxx Heap_Size=yyy, where -xxx represents a numerical value of stack size and yyy the -numerical value of the heap size (for most embedded projects -yyy should be 0, as the using the heap is not recommended). - - -Startup Code -============ -The startup code for the TM4C123GH6PM MCU used in this project is -located in the "3rd_party" folder in the following location: - -3rd_party\efm32pg1b\arm\startup_efm32pg1b.s - -The file startup_efm32pg1b.s provides a template of the recommended -startup for QP applications and should be easily customizable for other -ARM Cortex-M microcontrollers. - -The startup file typically does not need to be modified or adapted for -applications. It provides only weak definitions of all exception and -interrupt handlers, as well as the assert_failed() function. - -The weak function assert_failed() defined in this file might be re-defined -in the application to customize it for the application-specific error- -handling policy. - -*** -NOTE: The function assert_failed() typically should NOT use the stack, -because stack might be corrupted by the time this function is called. -Also, assert_failed() is intended to handle catastrophic errors and -should NOT return. -*** - \ No newline at end of file diff --git a/examples/arm-cm/blinky_efm32-slstk3401a/qk/bsp.c b/examples/arm-cm/blinky_efm32-slstk3401a/qk/bsp.c deleted file mode 100644 index e7b5178d..00000000 --- a/examples/arm-cm/blinky_efm32-slstk3401a/qk/bsp.c +++ /dev/null @@ -1,185 +0,0 @@ -/***************************************************************************** -* Product: "Blinky" on EFM32-SLSTK3401A board, preemptive QK kernel -* Last updated for version 6.9.1 -* Last updated on 2020-09-22 -* -* Q u a n t u m L e a P s -* ------------------------ -* Modern Embedded Software -* -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* -* -*****************************************************************************/ -#include "qpc.h" -#include "blinky.h" -#include "bsp.h" - -#include "em_device.h" /* the device specific header (SiLabs) */ -#include "em_cmu.h" /* Clock Management Unit (SiLabs) */ -#include "em_gpio.h" /* GPIO (SiLabs) */ -/* add other drivers if necessary... */ - -//Q_DEFINE_THIS_FILE - -#ifdef Q_SPY - #error Simple Blinky Application does not provide Spy build configuration -#endif - -/* ISRs defined in this BSP ------------------------------------------------*/ -void SysTick_Handler(void); - -/* Local-scope objects -----------------------------------------------------*/ -#define LED0_PIN 4 -#define LED0_PORT gpioPortF - -#define LED1_PIN 5 -#define LED1_PORT gpioPortF - -#define BTN_SW1 (1U << 4) -#define BTN_SW2 (1U << 0) - -/* ISRs used in this project ===============================================*/ -void SysTick_Handler(void) { - QK_ISR_ENTRY(); /* inform QK about entering an ISR */ - QTIMEEVT_TICK_X(0U, (void *)0); /* process time events for rate 0 */ - QK_ISR_EXIT(); /* inform QK about exiting an ISR */ -} - - -/* BSP functions ===========================================================*/ -void BSP_init(void) { - /* NOTE: SystemInit() already called from the startup code - * but SystemCoreClock needs to be updated - */ - SystemCoreClockUpdate(); - - /* NOTE The VFP (hardware Floating Point) unit is configured by QK-port */ - - /* enable clock for to the peripherals used by this application... */ - CMU_ClockEnable(cmuClock_HFPER, true); - CMU_ClockEnable(cmuClock_GPIO, true); - CMU_ClockEnable(cmuClock_HFPER, true); - CMU_ClockEnable(cmuClock_GPIO, true); - - /* configure the LEDs */ - GPIO_PinModeSet(LED0_PORT, LED0_PIN, gpioModePushPull, 0); - GPIO_PinModeSet(LED1_PORT, LED1_PIN, gpioModePushPull, 0); - GPIO_PinOutClear(LED0_PORT, LED0_PIN); - GPIO_PinOutClear(LED1_PORT, LED1_PIN); - - /* configure the Buttons */ - //... -} - -/*..........................................................................*/ -void BSP_ledOff(void) { - //GPIO_PinOutClear(LED0_PORT, LED0_PIN); - GPIO->P[LED0_PORT].DOUT &= ~(1U << LED0_PIN); -} -/*..........................................................................*/ -void BSP_ledOn(void) { - /* exercise the FPU with some floating point computations */ - float volatile x = 3.1415926F; - x = x + 2.7182818F; - - //GPIO_PinOutSet(LED0_PORT, LED0_PIN); - GPIO->P[LED0_PORT].DOUT |= (1U << LED0_PIN); -} - - -/* QF callbacks ============================================================*/ -void QF_onStartup(void) { - /* set up the SysTick timer to fire at BSP_TICKS_PER_SEC rate */ - SysTick_Config(SystemCoreClock / BSP_TICKS_PER_SEC); - - /* assing all priority bits for preemption-prio. and none to sub-prio. */ - NVIC_SetPriorityGrouping(0U); - - /* set priorities of ALL ISRs used in the system, see NOTE1 - * - * !!!!!!!!!!!!!!!!!!!!!!!!!!!! CAUTION !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - * Assign a priority to EVERY ISR explicitly by calling NVIC_SetPriority(). - * DO NOT LEAVE THE ISR PRIORITIES AT THE DEFAULT VALUE! - */ - NVIC_SetPriority(SysTick_IRQn, QF_AWARE_ISR_CMSIS_PRI); - /* ... */ - - /* enable IRQs... */ -} -/*..........................................................................*/ -void QF_onCleanup(void) { -} -/*..........................................................................*/ -void QK_onIdle(void) { - /* toggle LED1 on and then off, see NOTE01 */ - QF_INT_DISABLE(); - GPIO->P[LED1_PORT].DOUT |= (1U << LED1_PIN); - GPIO->P[LED1_PORT].DOUT &= ~(1U << LED1_PIN); - QF_INT_ENABLE(); - -#ifdef NDEBUG - /* Put the CPU and peripherals to the low-power mode. - * you might need to customize the clock management for your application, - * see the datasheet for your particular Cortex-M3 MCU. - */ - __WFI(); /* Wait-For-Interrupt */ -#endif -} - -/*..........................................................................*/ -Q_NORETURN Q_onAssert(char const * const module, int_t const loc) { - /* - * NOTE: add here your application-specific error handling - */ - (void)module; - (void)loc; - QS_ASSERTION(module, loc, 10000U); /* report assertion to QS */ - NVIC_SystemReset(); -} - - -/***************************************************************************** -* NOTE1: -* The QF_AWARE_ISR_CMSIS_PRI constant from the QF port specifies the highest -* ISR priority that is disabled by the QF framework. The value is suitable -* for the NVIC_SetPriority() CMSIS function. -* -* Only ISRs prioritized at or below the QF_AWARE_ISR_CMSIS_PRI level (i.e., -* with the numerical values of priorities equal or higher than -* QF_AWARE_ISR_CMSIS_PRI) are allowed to call any QF services. These ISRs -* are "QF-aware". -* -* Conversely, any ISRs prioritized above the QF_AWARE_ISR_CMSIS_PRI priority -* level (i.e., with the numerical values of priorities less than -* QF_AWARE_ISR_CMSIS_PRI) are never disabled and are not aware of the kernel. -* Such "QF-unaware" ISRs cannot call any QF services. The only mechanism -* by which a "QF-unaware" ISR can communicate with the QF framework is by -* triggering a "QF-aware" ISR, which can post/publish events. -* -* NOTE2: -* One of the LEDs is used to visualize the idle loop activity. The brightness -* of the LED is proportional to the frequency of invcations of the idle loop. -* Please note that the LED is toggled with interrupts locked, so no interrupt -* execution time contributes to the brightness of the User LED. -*/ diff --git a/examples/arm-cm/blinky_efm32-slstk3401a/qk/gnu/README.txt b/examples/arm-cm/blinky_efm32-slstk3401a/qk/gnu/README.txt deleted file mode 100644 index a578042c..00000000 --- a/examples/arm-cm/blinky_efm32-slstk3401a/qk/gnu/README.txt +++ /dev/null @@ -1,71 +0,0 @@ -About this Example -================== -This example can be built from the command prompt with the provided -Makefile. The example can also be imported as a Makefile-based -project into Eclipse-based IDEs. - - -The Makefile -============ -The provided Makefile should be easy to adapt for your own projects. -It contains three build configurations: Debug (default), Release, and -Spy. - -Also, the Makefile has been specifically designed to work as an external -Makefile with the Eclipse CDT. - -The various build configurations are built as follows: - -make -make CONF=rel -make CONF=spy - -make clean -make CONF=rel clean -make CONF=spy clean - -*** -NOTE: -The installation folder of the GNU-ARM toolset on YOUR machine needs -to be adjusted in the provided Makefile, by editing the symbol: GNU_ARM. -As described in the comment for this symbol, the GNU-ARM toolset is taken -from: http://gnutoolchains.com/arm-eabi - -It is highly recommened to use the same GNU-ARM distribution, especially -for ARM Cortex-M4F projects, due to the support for the hardware FPU -(float-abi=hard). -*** - - -Adjusting Stack and Heap Sizes -============================== -The stack and heap sizes are determined in this project by the GCC linker -script (.ld file), which provides a template of the recommended GCC linker -script for QP applications. - - -Startup Code -============ -The startup code for the EFM32PG1B200F256GM48 MCU used in this project -is located in the "3rd_party" folder in the following location: - -qpc\3rd_party\efm32pg1b\gnu\startup_efm32pg1b.c - -The file startup_efm32pg1b.c provides a template of the recommended -startup for QP applications and should be easily customizable for other -ARM Cortex-M microcontrollers. - -The startup file typically does not need to be modified or adapted for -applications. It provides only weak definitions of all exception and -interrupt handlers, as well as the assert_failed() function. - -The weak function assert_failed() defined in this file might be re-defined -in the application to customize it for the application-specific error- -handling policy. - -*** -NOTE: The function assert_failed() typically should NOT use the stack, -because stack might be corrupted by the time this function is called. -Also, assert_failed() is intended to handle catastrophic errors and -should NOT return. -*** diff --git a/examples/arm-cm/blinky_efm32-slstk3401a/qk/gnu/flash.bat b/examples/arm-cm/blinky_efm32-slstk3401a/qk/gnu/flash.bat deleted file mode 100644 index 23215d0b..00000000 --- a/examples/arm-cm/blinky_efm32-slstk3401a/qk/gnu/flash.bat +++ /dev/null @@ -1,49 +0,0 @@ -::============================================================================ -:: Batch file to program the flash of EFM32-SLSTK3401A board -:: -:: NOTE: requires the J-Link commander (JLink.exe) from SEGGER, see: -:: https://www.segger.com/j-link-commander.html -:: -setlocal - -@echo off -@echo Load a given binary file to the flash of EFM32-SLSTK3401A -@echo usage: flash bin-file -@echo example: flash dbg\blinky-qk.bin - -::---------------------------------------------------------------------------- -:: NOTE: Adjust the following symbol to the location of the -:: JLink utility on your machine -:: -if [%JLINK%] EQU [] set JLINK=%QTOOLS%\..\JLink -if not exist "%JLINK%\JLink.exe" ( - @echo The JLink tool not found. Please adjust flash.bat - @goto end -) - -if ["%~1"]==[""] ( - @echo The binary file missing - @goto end -) -if not exist %~s1 ( - @echo The binary file '%1' does not exist - @goto end -) - -:: generate the Jlink command file depending on the first parameter %1 -@echo si 1 >flash.jlink -@echo speed 4000 >>flash.jlink -@echo r >>flash.jlink -@echo h >>flash.jlink -@echo loadbin %1, 0 >>flash.jlink -@echo exit >>flash.jlink - -@echo on -%JLINK%\JLink.exe -device EFM32PG1B200F256GM48 flash.jlink -@echo off - -@del flash.jlink - -:end - -endlocal \ No newline at end of file diff --git a/examples/arm-cm/blinky_efm32-slstk3401a/qk/iar/README.txt b/examples/arm-cm/blinky_efm32-slstk3401a/qk/iar/README.txt deleted file mode 100644 index 6b410bed..00000000 --- a/examples/arm-cm/blinky_efm32-slstk3401a/qk/iar/README.txt +++ /dev/null @@ -1,53 +0,0 @@ -About this Example -================== -This example demonstrates how to use the IAR EWARM IDE to build -a QP application. - - -IAR Project File ----------------- -The IAR EWARM project file provided with this example uses relative paths -to the QP/C framework location (includes, port, and libraries. These -relative paths must be modified when the project is moved to different -relative location. - - -Stack Size and Heap Size ------------------------- -In this project, the size of the C stack and heap are determined in -the linker script blinky-qk.icf (see the next section). - - -Linker Script -------------- -The IAR linker script provides a template of the recommended linker script -for QP applications. This file needs to be customized to set the -application-specific sizes of the Stack and Heap. This file can be edited -from the IAR EWARM IDE via the Project Options/Linker settings. - - -Startup Code -============ -The startup code for the TM4C123GH6PM MCU used in this project is -located in the "3rd_party" folder in the following location: - -3rd_party\efm32pg1b\iar\startup_efm32pg1b.s - -The file startup_efm32pg1b.s provides a template of the recommended -startup for QP applications and should be easily customizable for other -ARM Cortex-M microcontrollers. - -The startup file typically does not need to be modified or adapted for -applications. It provides only weak definitions of all exception and -interrupt handlers, as well as the assert_failed() function. - -The weak function assert_failed() defined in this file might be re-defined -in the application to customize it for the application-specific error- -handling policy. - -*** -NOTE: The function assert_failed() typically should NOT use the stack, -because stack might be corrupted by the time this function is called. -Also, assert_failed() is intended to handle catastrophic errors and -should NOT return. -*** diff --git a/examples/arm-cm/blinky_efm32-slstk3401a/qv/armclang/README.txt b/examples/arm-cm/blinky_efm32-slstk3401a/qv/armclang/README.txt deleted file mode 100644 index 17af30f2..00000000 --- a/examples/arm-cm/blinky_efm32-slstk3401a/qv/armclang/README.txt +++ /dev/null @@ -1,50 +0,0 @@ -About this Example -================== -This example demonstrates how to use the uVision IDE together with -the MDK-ARM toolchain. - -uVision Project File -==================== -The MDK-ARM uVision project file provided with this example uses -relative paths to the QP framework location (includes, port, and -libraries. These relative paths must be modified when the project -is moved to different relative location. - - -Adjusting Stack and Heap Sizes -============================== -The stack and heap sizes are determined in this project by the -command-line options for the ARM assembler (see the Asm tab in -the "Options for Target" dialog box in uVision). Specifically, -you should define symbols: Stack_Size=xxx Heap_Size=yyy, where -xxx represents a numerical value of stack size and yyy the -numerical value of the heap size (for most embedded projects -yyy should be 0, as the using the heap is not recommended). - - -Startup Code -============ -The startup code for the TM4C123GH6PM MCU used in this project is -located in the "3rd_party" folder in the following location: - -3rd_party\efm32pg1b\arm\startup_efm32pg1b.s - -The file startup_efm32pg1b.s provides a template of the recommended -startup for QP applications and should be easily customizable for other -ARM Cortex-M microcontrollers. - -The startup file typically does not need to be modified or adapted for -applications. It provides only weak definitions of all exception and -interrupt handlers, as well as the assert_failed() function. - -The weak function assert_failed() defined in this file might be re-defined -in the application to customize it for the application-specific error- -handling policy. - -*** -NOTE: The function assert_failed() typically should NOT use the stack, -because stack might be corrupted by the time this function is called. -Also, assert_failed() is intended to handle catastrophic errors and -should NOT return. -*** - \ No newline at end of file diff --git a/examples/arm-cm/blinky_efm32-slstk3401a/qv/bsp.c b/examples/arm-cm/blinky_efm32-slstk3401a/qv/bsp.c deleted file mode 100644 index 3b056326..00000000 --- a/examples/arm-cm/blinky_efm32-slstk3401a/qv/bsp.c +++ /dev/null @@ -1,191 +0,0 @@ -/***************************************************************************** -* Product: "Blinky" on EFM32-SLSTK3401A board, cooperative QV kernel -* Last updated for version 6.9.1 -* Last updated on 2020-09-23 -* -* Q u a n t u m L e a P s -* ------------------------ -* Modern Embedded Software -* -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* -* -*****************************************************************************/ -#include "qpc.h" -#include "blinky.h" -#include "bsp.h" - -#include "em_device.h" /* the device specific header (SiLabs) */ -#include "em_cmu.h" /* Clock Management Unit (SiLabs) */ -#include "em_gpio.h" /* GPIO (SiLabs) */ -/* add other drivers if necessary... */ - -//Q_DEFINE_THIS_FILE - -#ifdef Q_SPY - #error Simple Blinky Application does not provide Spy build configuration -#endif - -/* ISRs defined in this BSP ------------------------------------------------*/ -void SysTick_Handler(void); - -/* Local-scope objects -----------------------------------------------------*/ -#define LED0_PIN 4 -#define LED0_PORT gpioPortF - -#define LED1_PIN 5 -#define LED1_PORT gpioPortF - -#define BTN_SW1 (1U << 4) -#define BTN_SW2 (1U << 0) - -/* ISRs used in this project ===============================================*/ -void SysTick_Handler(void) { - QTIMEEVT_TICK_X(0U, (void *)0); /* process time events for rate 0 */ - QV_ARM_ERRATUM_838869(); -} - - -/* BSP functions ===========================================================*/ -void BSP_init(void) { - /* NOTE: SystemInit() already called from the startup code - * but SystemCoreClock needs to be updated - */ - SystemCoreClockUpdate(); - - /* NOTE The VFP (hardware Floating Point) unit is configured by QV-port */ - - /* enable clock for to the peripherals used by this application... */ - CMU_ClockEnable(cmuClock_HFPER, true); - CMU_ClockEnable(cmuClock_GPIO, true); - CMU_ClockEnable(cmuClock_HFPER, true); - CMU_ClockEnable(cmuClock_GPIO, true); - - /* configure the LEDs */ - GPIO_PinModeSet(LED0_PORT, LED0_PIN, gpioModePushPull, 0); - GPIO_PinModeSet(LED1_PORT, LED1_PIN, gpioModePushPull, 0); - GPIO_PinOutClear(LED0_PORT, LED0_PIN); - GPIO_PinOutClear(LED1_PORT, LED1_PIN); - - /* configure the Buttons */ - //... -} -/*..........................................................................*/ -void BSP_ledOff(void) { - //GPIO_PinOutClear(LED0_PORT, LED0_PIN); - GPIO->P[LED0_PORT].DOUT &= ~(1U << LED0_PIN); -} -/*..........................................................................*/ -void BSP_ledOn(void) { - /* exercise the FPU with some floating point computations */ - float volatile x = 3.1415926F; - x = x + 2.7182818F; - - //GPIO_PinOutSet(LED0_PORT, LED0_PIN); - GPIO->P[LED0_PORT].DOUT |= (1U << LED0_PIN); -} - - -/* QF callbacks ============================================================*/ -void QF_onStartup(void) { - /* set up the SysTick timer to fire at BSP_TICKS_PER_SEC rate */ - SysTick_Config(SystemCoreClock / BSP_TICKS_PER_SEC); - - /* assing all priority bits for preemption-prio. and none to sub-prio. */ - NVIC_SetPriorityGrouping(0U); - - /* set priorities of ALL ISRs used in the system, see NOTE00 - * - * !!!!!!!!!!!!!!!!!!!!!!!!!!!! CAUTION !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - * Assign a priority to EVERY ISR explicitly by calling NVIC_SetPriority(). - * DO NOT LEAVE THE ISR PRIORITIES AT THE DEFAULT VALUE! - */ - NVIC_SetPriority(SysTick_IRQn, QF_AWARE_ISR_CMSIS_PRI); - /* ... */ - - /* enable IRQs... */ -} -/*..........................................................................*/ -void QF_onCleanup(void) { -} -/*..........................................................................*/ -void QV_onIdle(void) { /* CATION: called with interrupts DISABLED, NOTE01 */ - /* toggle LED1 on and then off, see NOTE02 */ - GPIO_PinOutSet(LED1_PORT, LED1_PIN); - //GPIO->P[LED1_PORT].DOUT |= (1U << LED1_PIN); - GPIO_PinOutClear(LED1_PORT, LED1_PIN); - //GPIO->P[LED1_PORT].DOUT &= ~(1U << LED1_PIN); - -#ifdef NDEBUG - /* Put the CPU and peripherals to the low-power mode. - * you might need to customize the clock management for your application, - * see the datasheet for your particular Cortex-M MCU. - */ - QV_CPU_SLEEP(); /* atomically go to sleep and enable interrupts */ -#else - QF_INT_ENABLE(); /* just enable interrupts */ -#endif -} - -/*..........................................................................*/ -Q_NORETURN Q_onAssert(char const * const module, int_t const loc) { - /* - * NOTE: add here your application-specific error handling - */ - (void)module; - (void)loc; - QS_ASSERTION(module, loc, 10000U); /* report assertion to QS */ - NVIC_SystemReset(); -} - - -/***************************************************************************** -* NOTE00: -* The QF_AWARE_ISR_CMSIS_PRI constant from the QF port specifies the highest -* ISR priority that is disabled by the QF framework. The value is suitable -* for the NVIC_SetPriority() CMSIS function. -* -* Only ISRs prioritized at or below the QF_AWARE_ISR_CMSIS_PRI level (i.e., -* with the numerical values of priorities equal or higher than -* QF_AWARE_ISR_CMSIS_PRI) are allowed to call any QF services. These ISRs -* are "QF-aware". -* -* Conversely, any ISRs prioritized above the QF_AWARE_ISR_CMSIS_PRI priority -* level (i.e., with the numerical values of priorities less than -* QF_AWARE_ISR_CMSIS_PRI) are never disabled and are not aware of the kernel. -* Such "QF-unaware" ISRs cannot call any QF services. The only mechanism -* by which a "QF-unaware" ISR can communicate with the QF framework is by -* triggering a "QF-aware" ISR, which can post/publish events. -* -* NOTE01: -* The QV_onIdle() callback is called with interrupts disabled, because the -* determination of the idle condition might change by any interrupt posting -* an event. QV_onIdle() must internally enable interrupts, ideally -* atomically with putting the CPU to the power-saving mode. -* -* NOTE02: -* One of the LEDs is used to visualize the idle loop activity. The brightness -* of the LED is proportional to the frequency of invcations of the idle loop. -* Please note that the LED is toggled with interrupts locked, so no interrupt -* execution time contributes to the brightness of the User LED. -*/ diff --git a/examples/arm-cm/blinky_efm32-slstk3401a/qv/gnu/README.txt b/examples/arm-cm/blinky_efm32-slstk3401a/qv/gnu/README.txt deleted file mode 100644 index a578042c..00000000 --- a/examples/arm-cm/blinky_efm32-slstk3401a/qv/gnu/README.txt +++ /dev/null @@ -1,71 +0,0 @@ -About this Example -================== -This example can be built from the command prompt with the provided -Makefile. The example can also be imported as a Makefile-based -project into Eclipse-based IDEs. - - -The Makefile -============ -The provided Makefile should be easy to adapt for your own projects. -It contains three build configurations: Debug (default), Release, and -Spy. - -Also, the Makefile has been specifically designed to work as an external -Makefile with the Eclipse CDT. - -The various build configurations are built as follows: - -make -make CONF=rel -make CONF=spy - -make clean -make CONF=rel clean -make CONF=spy clean - -*** -NOTE: -The installation folder of the GNU-ARM toolset on YOUR machine needs -to be adjusted in the provided Makefile, by editing the symbol: GNU_ARM. -As described in the comment for this symbol, the GNU-ARM toolset is taken -from: http://gnutoolchains.com/arm-eabi - -It is highly recommened to use the same GNU-ARM distribution, especially -for ARM Cortex-M4F projects, due to the support for the hardware FPU -(float-abi=hard). -*** - - -Adjusting Stack and Heap Sizes -============================== -The stack and heap sizes are determined in this project by the GCC linker -script (.ld file), which provides a template of the recommended GCC linker -script for QP applications. - - -Startup Code -============ -The startup code for the EFM32PG1B200F256GM48 MCU used in this project -is located in the "3rd_party" folder in the following location: - -qpc\3rd_party\efm32pg1b\gnu\startup_efm32pg1b.c - -The file startup_efm32pg1b.c provides a template of the recommended -startup for QP applications and should be easily customizable for other -ARM Cortex-M microcontrollers. - -The startup file typically does not need to be modified or adapted for -applications. It provides only weak definitions of all exception and -interrupt handlers, as well as the assert_failed() function. - -The weak function assert_failed() defined in this file might be re-defined -in the application to customize it for the application-specific error- -handling policy. - -*** -NOTE: The function assert_failed() typically should NOT use the stack, -because stack might be corrupted by the time this function is called. -Also, assert_failed() is intended to handle catastrophic errors and -should NOT return. -*** diff --git a/examples/arm-cm/blinky_efm32-slstk3401a/qv/gnu/flash.bat b/examples/arm-cm/blinky_efm32-slstk3401a/qv/gnu/flash.bat deleted file mode 100644 index 23215d0b..00000000 --- a/examples/arm-cm/blinky_efm32-slstk3401a/qv/gnu/flash.bat +++ /dev/null @@ -1,49 +0,0 @@ -::============================================================================ -:: Batch file to program the flash of EFM32-SLSTK3401A board -:: -:: NOTE: requires the J-Link commander (JLink.exe) from SEGGER, see: -:: https://www.segger.com/j-link-commander.html -:: -setlocal - -@echo off -@echo Load a given binary file to the flash of EFM32-SLSTK3401A -@echo usage: flash bin-file -@echo example: flash dbg\blinky-qk.bin - -::---------------------------------------------------------------------------- -:: NOTE: Adjust the following symbol to the location of the -:: JLink utility on your machine -:: -if [%JLINK%] EQU [] set JLINK=%QTOOLS%\..\JLink -if not exist "%JLINK%\JLink.exe" ( - @echo The JLink tool not found. Please adjust flash.bat - @goto end -) - -if ["%~1"]==[""] ( - @echo The binary file missing - @goto end -) -if not exist %~s1 ( - @echo The binary file '%1' does not exist - @goto end -) - -:: generate the Jlink command file depending on the first parameter %1 -@echo si 1 >flash.jlink -@echo speed 4000 >>flash.jlink -@echo r >>flash.jlink -@echo h >>flash.jlink -@echo loadbin %1, 0 >>flash.jlink -@echo exit >>flash.jlink - -@echo on -%JLINK%\JLink.exe -device EFM32PG1B200F256GM48 flash.jlink -@echo off - -@del flash.jlink - -:end - -endlocal \ No newline at end of file diff --git a/examples/arm-cm/blinky_efm32-slstk3401a/qv/iar/README.txt b/examples/arm-cm/blinky_efm32-slstk3401a/qv/iar/README.txt deleted file mode 100644 index 6b410bed..00000000 --- a/examples/arm-cm/blinky_efm32-slstk3401a/qv/iar/README.txt +++ /dev/null @@ -1,53 +0,0 @@ -About this Example -================== -This example demonstrates how to use the IAR EWARM IDE to build -a QP application. - - -IAR Project File ----------------- -The IAR EWARM project file provided with this example uses relative paths -to the QP/C framework location (includes, port, and libraries. These -relative paths must be modified when the project is moved to different -relative location. - - -Stack Size and Heap Size ------------------------- -In this project, the size of the C stack and heap are determined in -the linker script blinky-qk.icf (see the next section). - - -Linker Script -------------- -The IAR linker script provides a template of the recommended linker script -for QP applications. This file needs to be customized to set the -application-specific sizes of the Stack and Heap. This file can be edited -from the IAR EWARM IDE via the Project Options/Linker settings. - - -Startup Code -============ -The startup code for the TM4C123GH6PM MCU used in this project is -located in the "3rd_party" folder in the following location: - -3rd_party\efm32pg1b\iar\startup_efm32pg1b.s - -The file startup_efm32pg1b.s provides a template of the recommended -startup for QP applications and should be easily customizable for other -ARM Cortex-M microcontrollers. - -The startup file typically does not need to be modified or adapted for -applications. It provides only weak definitions of all exception and -interrupt handlers, as well as the assert_failed() function. - -The weak function assert_failed() defined in this file might be re-defined -in the application to customize it for the application-specific error- -handling policy. - -*** -NOTE: The function assert_failed() typically should NOT use the stack, -because stack might be corrupted by the time this function is called. -Also, assert_failed() is intended to handle catastrophic errors and -should NOT return. -*** diff --git a/examples/arm-cm/blinky_ek-tm4c123gxl/README.md b/examples/arm-cm/blinky_ek-tm4c123gxl/README.md index 9409465a..731ed6c3 100644 --- a/examples/arm-cm/blinky_ek-tm4c123gxl/README.md +++ b/examples/arm-cm/blinky_ek-tm4c123gxl/README.md @@ -1,5 +1,83 @@ -![STM32 EFM32-SLSTK3401A](../../../doxygen/images/bd_EK-TM4C123GXL.jpg) +> **NOTE** +This file is best viewed in a **markdown viewer**, such as the one built into GitHub. Markdown viewers are also available as plug-ins to popular Internet browsers. -Documentation for this example is available in the QP/C Manual at: +# Blinky on EK-TM4C123GXL +This example implements the simple [Blinky application](https://www.state-machine.com/qpc/tut_blinky.html) on the EK-TM4C123GLX board (ARM Cortex-M4F). The example blinks the LED +on the EK-TM4C123GXL board at 1Hz (0.5 seconds on, 0.5 seconds off). + +

+
+EK-TM4C123GXL (TivaC LaunchPad) +

+ +## Features Demonstrated +- cooperative QV kernel + + with ARM-KEIL toolchain + + with GNU-ARM toolchain + + with IAR-ARM toolchain +- preemptive run-to-completion QK kernel + + with ARM-KEIL toolchain + + with GNU-ARM toolchain + + with IAR-ARM toolchain + +## Build Configurations +- Debug +- Release +- Spy - NOT supported for the simple Blinky example + +# Code Organization +``` +examples\arm-cm\blinky_ek-tm4c123gxl +| ++---qk // preemptive QK kernel +| +---gnu // GNU-ARM toolchain +| | \---targetConfigs +| | Makefile // Makefile for GNU-ARM +| +---armclang // ARM/KEIL toolchain with Compiler 6 (ARM/CLANG) +| | blinky-qk.uvprojx // uVision project +| \---iar // IAR EWARM +| blinky-qk.eww // IAR EW-ARM workspace +| +\---qv // cooperative QK kernel +| +---gnu // GNU-ARM toolchain +| | \---targetConfigs +| | Makefile // Makefile for GNU-ARM +| +---armclang // ARM/KEIL toolchain with Compiler 6 (ARM/CLANG) +| | blinky-qv.uvprojx // uVision project +| \---iar // IAR EWARM +| blinky-qv.eww // IAR EW-ARM workspace +``` + +# Builing the example + +### GNU/ARM +- open terminal window +- change to the desired directory (either `examples\arm-cm\blinky_ek-tm4c123gxl\qk\gnu` +or `examples\arm-cm\blinky_ek-tm4c123gxl\qv\gnu`) +- to build the default Debug configuration, type: + +``` +make +``` + +> **NOTE** +The `make` utility for Windows is provided in the QTools collection for Windows. + +- to build the Release configuration, type: + +``` +make CONF=rel +``` + + +### ARM/KEIL MDK +- Open the provided KEIL uVision project (either `blinky-qk.uvprojx` or `blinky-qv.uvprojx`) +in Keil uVision IDE. Build/Debug/Download to the board from the IDE. +- Change the build configuration in the "Project Target" drop-down menu. + + +### IAR EWARM +- Open the provided IAR EWARM workspace (either `blinky-qk.eww` or `blinky-qv.eww`) +in IAR EWARM IDE. Build/Debug/Download to the board from the IDE. +- Change the build configuration in the "Project Configuration" drop-down menu. -- https://www.state-machine.com/qpc/arm-cm_blinky_ek-tm4c123gxl.html diff --git a/examples/arm-cm/blinky_ek-tm4c123gxl/blinky.c b/examples/arm-cm/blinky_ek-tm4c123gxl/blinky.c index ffcfa781..43ad9df4 100644 --- a/examples/arm-cm/blinky_ek-tm4c123gxl/blinky.c +++ b/examples/arm-cm/blinky_ek-tm4c123gxl/blinky.c @@ -1,80 +1,83 @@ -/*============================================================================ -* Product: "Blinky" example -* Last updated for version 7.2.0 -* Last updated on 2023-01-08 -* -* Q u a n t u m L e a P s -* ------------------------ -* Modern Embedded Software -* -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* -* -============================================================================*/ -#include "qpc.h" -#include "bsp.h" -#include "blinky.h" +//============================================================================ +// Product: "Blinky" example +// Last updated for version 7.3.0 +// Last updated on 2023-08-15 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// This program is open source software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Alternatively, this program may be distributed and modified under the +// terms of Quantum Leaps commercial licenses, which expressly supersede +// the GNU General Public License and are specifically designed for +// licensees interested in retaining the proprietary status of their code. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Contact information: +// +// +//============================================================================ +#include "qpc.h" // QP/C real-time embedded framework +#include "blinky.h" // Blinky Application interface +#include "bsp.h" // Board Support Package + +#ifdef Q_SPY +#error The Simple Blinky Application does not support Spy build configuration +#endif //Q_DEFINE_THIS_FILE -/*..........................................................................*/ -typedef struct { /* the Blinky active object */ - QActive super; /* inherit QActive */ - QTimeEvt timeEvt; /* private time event generator */ +//............................................................................ +// Blinky class... +typedef struct { +// protected: + QActive super; // inherit QActive + +// private: + QTimeEvt timeEvt; // private time event generator } Blinky; +extern Blinky Blinky_inst; // the Blinky active object -static Blinky Blinky_inst; /* the Blinky active object */ - -QActive * const AO_Blinky = &Blinky_inst.super; - -/* hierarchical state machine ... */ +// protected: static QState Blinky_initial(Blinky * const me, void const * const par); static QState Blinky_off(Blinky * const me, QEvt const * const e); static QState Blinky_on(Blinky * const me, QEvt const * const e); -/*..........................................................................*/ +//---------------------------------------------------------------------------- +Blinky Blinky_inst; +QActive * const AO_Blinky = &Blinky_inst.super; + +//............................................................................ void Blinky_ctor(void) { Blinky * const me = &Blinky_inst; QActive_ctor(&me->super, Q_STATE_CAST(&Blinky_initial)); QTimeEvt_ctorX(&me->timeEvt, &me->super, TIMEOUT_SIG, 0U); } -/* HSM definition ----------------------------------------------------------*/ +// HSM definition ---------------------------------------------------------- QState Blinky_initial(Blinky * const me, void const * const par) { Q_UNUSED_PAR(par); - QS_OBJ_DICTIONARY(&Blinky_inst); - QS_OBJ_DICTIONARY(&Blinky_inst.timeEvt); - - QS_FUN_DICTIONARY(&Blinky_initial); - QS_FUN_DICTIONARY(&Blinky_off); - QS_FUN_DICTIONARY(&Blinky_on); - - /* arm the time event to expire in half a second and every half second */ + // arm the time event to expire in half a second and every half second QTimeEvt_armX(&me->timeEvt, BSP_TICKS_PER_SEC/2U, BSP_TICKS_PER_SEC/2U); + return Q_TRAN(&Blinky_off); } -/*..........................................................................*/ +//............................................................................ QState Blinky_off(Blinky * const me, QEvt const * const e) { QState status; switch (e->sig) { @@ -94,7 +97,7 @@ QState Blinky_off(Blinky * const me, QEvt const * const e) { } return status; } -/*..........................................................................*/ +//............................................................................ QState Blinky_on(Blinky * const me, QEvt const * const e) { QState status; switch (e->sig) { diff --git a/examples/arm-cm/blinky_ek-tm4c123gxl/blinky.h b/examples/arm-cm/blinky_ek-tm4c123gxl/blinky.h index 43c61a72..c50ddd72 100644 --- a/examples/arm-cm/blinky_ek-tm4c123gxl/blinky.h +++ b/examples/arm-cm/blinky_ek-tm4c123gxl/blinky.h @@ -1,48 +1,48 @@ -/*============================================================================ -* Product: "Blinky" example -* Last updated for version 7.2.0 -* Last updated on 2023-01-08 -* -* Q u a n t u m L e a P s -* ------------------------ -* Modern Embedded Software -* -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* -* -============================================================================*/ +//============================================================================ +// Product: "Blinky" example +// Last updated for version 7.2.0 +// Last updated on 2023-01-08 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// This program is open source software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Alternatively, this program may be distributed and modified under the +// terms of Quantum Leaps commercial licenses, which expressly supersede +// the GNU General Public License and are specifically designed for +// licensees interested in retaining the proprietary status of their code. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Contact information: +// +// +//============================================================================ #ifndef BLINKY_H_ #define BLINKY_H_ enum BlinkySignals { DUMMY_SIG = Q_USER_SIG, - MAX_PUB_SIG, /* the last published signal */ + MAX_PUB_SIG, // the last published signal TIMEOUT_SIG, - MAX_SIG /* the last signal */ + MAX_SIG // the last signal }; void Blinky_ctor(void); -extern QActive * const AO_Blinky; /* opaque pointer */ +extern QActive * const AO_Blinky; // opaque pointer -#endif /* BLINKY_H_ */ +#endif // BLINKY_H_ diff --git a/examples/arm-cm/blinky_ek-tm4c123gxl/bsp.h b/examples/arm-cm/blinky_ek-tm4c123gxl/bsp.h index 7c171cce..da73dbfd 100644 --- a/examples/arm-cm/blinky_ek-tm4c123gxl/bsp.h +++ b/examples/arm-cm/blinky_ek-tm4c123gxl/bsp.h @@ -1,52 +1,49 @@ -/***************************************************************************** -* Product: DPP example -* Last Updated for Version: 5.6.0 -* Date of the Last Update: 2015-11-22 -* -* Q u a n t u m L e a P s -* --------------------------- -* innovating embedded systems -* -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* -* -*****************************************************************************/ -#ifndef BSP_H -#define BSP_H +//============================================================================ +// Product: Board Support Package example +// Last Updated for Version: 7.3.0 +// Date of the Last Update: 2023-08-12 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +//============================================================================ +#ifndef BSP_H_ +#define BSP_H_ #define BSP_TICKS_PER_SEC 100U void BSP_init(void); +void BSP_start(void); void BSP_displayPaused(uint8_t paused); void BSP_displayPhilStat(uint8_t n, char const *stat); void BSP_terminate(int16_t result); -void BSP_randomSeed(uint32_t seed); /* random seed */ -uint32_t BSP_random(void); /* pseudo-random generator */ +void BSP_randomSeed(uint32_t seed); // random seed +uint32_t BSP_random(void); // pseudo-random generator -/* for testing... */ -void BSP_wait4SW1(void); void BSP_ledOn(void); void BSP_ledOff(void); -#endif /* BSP_H */ +#endif // BSP_H_ diff --git a/examples/arm-cm/blinky_ek-tm4c123gxl/ek-tm4c123gxl.jpg b/examples/arm-cm/blinky_ek-tm4c123gxl/ek-tm4c123gxl.jpg new file mode 100644 index 00000000..5ed6188c Binary files /dev/null and b/examples/arm-cm/blinky_ek-tm4c123gxl/ek-tm4c123gxl.jpg differ diff --git a/examples/arm-cm/blinky_ek-tm4c123gxl/main.c b/examples/arm-cm/blinky_ek-tm4c123gxl/main.c index aac1a812..185ed8dc 100644 --- a/examples/arm-cm/blinky_ek-tm4c123gxl/main.c +++ b/examples/arm-cm/blinky_ek-tm4c123gxl/main.c @@ -1,60 +1,44 @@ -/***************************************************************************** -* Product: "Blinky" example -* Last updated for version 7.1.1 -* Last updated on 2022-09-22 -* -* Q u a n t u m L e a P s -* ------------------------ -* Modern Embedded Software -* -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* -* -*****************************************************************************/ -#include "qpc.h" -#include "blinky.h" -#include "bsp.h" +//============================================================================ +// APP example +// Last updated for version 7.3.0 +// Last updated on 2023-08-09 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. +// +// This program is open source software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Alternatively, this program may be distributed and modified under the +// terms of Quantum Leaps commercial licenses, which expressly supersede +// the GNU General Public License and are specifically designed for +// licensees interested in retaining the proprietary status of their code. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Contact information: +// +// +//============================================================================ +#include "qpc.h" // QP/C real-time embedded framework +#include "blinky.h" // Blinky Application interface +#include "bsp.h" // Board Support Package -Q_DEFINE_THIS_FILE - -/*..........................................................................*/ +//............................................................................ int main() { - QF_init(); /* initialize the framework and the underlying RT kernel */ - BSP_init(); /* initialize the Board Support Package */ - - /* publish-subscribe not used, no call to QF_psInit() */ - /* dynamic event allocation not used, no call to QF_poolInit() */ - - /* instantiate and start the active objects... */ - Blinky_ctor(); - static QEvt const *l_blinkyQSto[10]; /* Event queue storage for Blinky */ - QACTIVE_START(AO_Blinky, /* AO pointer to start */ - 2U, /* QF-priority/preemption-threshold */ - l_blinkyQSto, /* storage for the AO's queue */ - Q_DIM(l_blinkyQSto), /* length of the queue [entries] */ - (void *)0, /* stack storage (not used in QK) */ - 0U, /* stack size [bytes] (not used in QK) */ - (QEvt *)0); /* initial event (or 0) */ - - return QF_run(); /* run the QF application */ + QF_init(); // initialize the framework and the underlying RT kernel + BSP_init(); // initialize the BSP + BSP_start(); // start the AOs/Threads + return QF_run(); // run the QF application } diff --git a/examples/arm-cm/blinky_ek-tm4c123gxl/qk/armclang/blinky-qk.sct b/examples/arm-cm/blinky_ek-tm4c123gxl/qk/armclang/blinky-qk.sct new file mode 100644 index 00000000..e78acfe0 --- /dev/null +++ b/examples/arm-cm/blinky_ek-tm4c123gxl/qk/armclang/blinky-qk.sct @@ -0,0 +1,23 @@ +; ************************************************************* +; *** Scatter-Loading Description File generated by uVision *** +; +; Modified by Quantum Leaps: +; added STACK as the first section in RW_STACK +; ************************************************************* + +LR_IROM1 0x00000000 0x00040000 { ; load region size_region + ER_IROM1 0x00000000 0x00040000 { ; load address = execution address + *.o (RESET, +First) + *(InRoot$$Sections) + .ANY (+RO) + .ANY (+XO) + } + + RW_STACK 0x20000000 { ; <== Quantum Leaps + * (STACK, +First) + } + RW_IRAM1 +0 (0x00008000 - 2048) { ; NOTE: assume STACK size 2048! + .ANY (+RW +ZI) + } +} + diff --git a/examples/arm-cm/blinky_ek-tm4c123gxl/qk/armclang/blinky-qk.uvoptx b/examples/arm-cm/blinky_ek-tm4c123gxl/qk/armclang/blinky-qk.uvoptx index a3612b9a..c85d559d 100644 --- a/examples/arm-cm/blinky_ek-tm4c123gxl/qk/armclang/blinky-qk.uvoptx +++ b/examples/arm-cm/blinky_ek-tm4c123gxl/qk/armclang/blinky-qk.uvoptx @@ -8,9 +8,9 @@ *.c *.s*; *.src; *.a* - *.obj + *.obj; *.o *.lib - *.txt; *.h; *.inc + *.txt; *.h; *.inc; *.md *.plm *.cpp 0 @@ -103,7 +103,7 @@ 1 0 0 - 8 + 19 @@ -117,10 +117,6 @@ BIN\lmidk-agdi.dll - - 0 - DLGUARM - 0 ARMRTXEVENTFLAGS @@ -637,18 +633,6 @@ 0 0 - - 1 - 5 - 1 - 0 - 0 - 0 - ..\..\..\..\..\include\qstamp.c - qstamp.c - 0 - 0 - @@ -659,7 +643,7 @@ 0 2 - 6 + 5 1 0 0 @@ -671,7 +655,7 @@ 2 - 7 + 6 5 0 0 @@ -683,7 +667,7 @@ 2 - 8 + 7 2 0 0 @@ -695,7 +679,7 @@ 2 - 9 + 8 5 0 0 @@ -707,7 +691,7 @@ 2 - 10 + 9 5 0 0 @@ -719,7 +703,7 @@ 2 - 11 + 10 5 0 0 @@ -731,7 +715,7 @@ 2 - 12 + 11 5 0 0 @@ -751,7 +735,7 @@ 0 3 - 13 + 12 1 0 0 @@ -763,7 +747,7 @@ 3 - 14 + 13 1 0 0 @@ -775,7 +759,7 @@ 3 - 15 + 14 1 0 0 @@ -787,7 +771,7 @@ 3 - 16 + 15 1 0 0 @@ -799,7 +783,7 @@ 3 - 17 + 16 1 0 0 @@ -811,7 +795,7 @@ 3 - 18 + 17 1 0 0 @@ -823,7 +807,7 @@ 3 - 19 + 18 1 0 0 @@ -835,7 +819,7 @@ 3 - 20 + 19 1 0 0 @@ -847,7 +831,7 @@ 3 - 21 + 20 1 0 0 @@ -859,7 +843,7 @@ 3 - 22 + 21 1 0 0 @@ -871,7 +855,7 @@ 3 - 23 + 22 1 0 0 @@ -883,7 +867,7 @@ 3 - 24 + 23 1 0 0 @@ -895,7 +879,7 @@ 3 - 25 + 24 1 0 0 @@ -915,7 +899,7 @@ 0 4 - 26 + 25 1 0 0 @@ -935,7 +919,7 @@ 0 5 - 27 + 26 1 0 0 @@ -947,7 +931,7 @@ 5 - 28 + 27 1 0 0 @@ -959,7 +943,7 @@ 5 - 29 + 28 1 0 0 @@ -971,7 +955,7 @@ 5 - 30 + 29 1 0 0 @@ -981,6 +965,18 @@ 0 0 + + 5 + 30 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qs\qstamp.c + qstamp.c + 0 + 0 + diff --git a/examples/arm-cm/blinky_ek-tm4c123gxl/qk/armclang/blinky-qk.uvprojx b/examples/arm-cm/blinky_ek-tm4c123gxl/qk/armclang/blinky-qk.uvprojx index e5641211..6762b0ec 100644 --- a/examples/arm-cm/blinky_ek-tm4c123gxl/qk/armclang/blinky-qk.uvprojx +++ b/examples/arm-cm/blinky_ek-tm4c123gxl/qk/armclang/blinky-qk.uvprojx @@ -10,7 +10,7 @@ blinky-dbg 0x4 ARM-ADS - 6130001::V6.13.1::.\ARMCLANG + 6160000::V6.16::ARMCLANG 1 @@ -185,6 +185,7 @@ 0 2 0 + 0 0 0 8 @@ -336,7 +337,7 @@ 0 - __FPU_PRESENT + ..\..;..\..\..\..\..\include;..\..\..\..\..\ports\arm-cm\qk\armclang;..\..\..\..\..\3rd_party\CMSIS\Include;..\..\..\..\..\3rd_party\ek-tm4c123gxl @@ -351,7 +352,7 @@ 0 1 0 - 0 + 4 Stack_Size=2048 Heap_Size=16 @@ -360,7 +361,7 @@ - 1 + 0 0 0 0 @@ -369,7 +370,7 @@ 0x00000000 0x20000000 - + .\blinky-qk.sct --entry Reset_Handler @@ -402,11 +403,6 @@ 5 ..\..\blinky.h - - qstamp.c - 1 - ..\..\..\..\..\include\qstamp.c - @@ -590,7 +586,7 @@ 2 2 2 - 2 + 0 @@ -621,6 +617,11 @@ 1 ..\..\..\..\..\src\qs\qs_rx.c + + qstamp.c + 1 + ..\..\..\..\..\src\qs\qstamp.c + @@ -804,6 +805,7 @@ 0 2 0 + 0 0 0 8 @@ -955,7 +957,7 @@ 0 - NDEBUG __FPU_PRESENT + NDEBUG ..\..;..\..\..\..\..\include;..\..\..\..\..\ports\arm-cm\qk\armclang;..\..\..\..\..\3rd_party\CMSIS\Include;..\..\..\..\..\3rd_party\ek-tm4c123gxl @@ -970,7 +972,7 @@ 0 1 0 - 0 + 4 Stack_Size=2048 Heap_Size=16 @@ -1021,11 +1023,6 @@ 5 ..\..\blinky.h - - qstamp.c - 1 - ..\..\..\..\..\include\qstamp.c - @@ -1209,7 +1206,7 @@ 2 2 2 - 2 + 0 @@ -1240,6 +1237,11 @@ 1 ..\..\..\..\..\src\qs\qs_rx.c + + qstamp.c + 1 + ..\..\..\..\..\src\qs\qstamp.c + @@ -1423,6 +1425,7 @@ 0 2 0 + 0 0 0 8 @@ -1574,7 +1577,7 @@ 0 - Q_SPY __FPU_PRESENT + Q_SPY ..\..;..\..\..\..\..\include;..\..\..\..\..\ports\arm-cm\qk\armclang;..\..\..\..\..\3rd_party\CMSIS\Include;..\..\..\..\..\3rd_party\ek-tm4c123gxl @@ -1589,7 +1592,7 @@ 0 1 0 - 0 + 4 Stack_Size=2048 Heap_Size=16 @@ -1640,11 +1643,6 @@ 5 ..\..\blinky.h - - qstamp.c - 1 - ..\..\..\..\..\include\qstamp.c - @@ -1790,6 +1788,11 @@ 1 ..\..\..\..\..\src\qs\qs_rx.c + + qstamp.c + 1 + ..\..\..\..\..\src\qs\qstamp.c + @@ -1802,4 +1805,13 @@ + + + + blinky-qk + 1 + + + + diff --git a/examples/arm-cm/blinky_ek-tm4c123gxl/qk/bsp.c b/examples/arm-cm/blinky_ek-tm4c123gxl/qk/bsp.c index 8b7b54d4..a2b19429 100644 --- a/examples/arm-cm/blinky_ek-tm4c123gxl/qk/bsp.c +++ b/examples/arm-cm/blinky_ek-tm4c123gxl/qk/bsp.c @@ -1,313 +1,240 @@ -/***************************************************************************** -* Product: "Blinky" example, EK-TM4C123GXL board, preemptive QK kernel -* Last updated for version 7.2.0 -* Last updated on 2022-12-17 -* -* Q u a n t u m L e a P s -* ------------------------ -* Modern Embedded Software -* -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* -* -*****************************************************************************/ -#include "qpc.h" -#include "blinky.h" -#include "bsp.h" +//============================================================================ +// Product: Blinky example, EK-TM4C123GXL board, QK kernel +// Last updated for version 7.3.0 +// Last updated on 2023-08-15 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. +// +// This program is open source software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Alternatively, this program may be distributed and modified under the +// terms of Quantum Leaps commercial licenses, which expressly supersede +// the GNU General Public License and are specifically designed for +// licensees interested in retaining the proprietary status of their code. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Contact information: +// +// +//============================================================================ +#include "qpc.h" // QP/C real-time embedded framework +#include "blinky.h" // Blinky Application interface +#include "bsp.h" // Board Support Package -#include "TM4C123GH6PM.h" /* the device specific header (TI) */ -#include "rom.h" /* the built-in ROM functions (TI) */ -#include "sysctl.h" /* system control driver (TI) */ -#include "gpio.h" /* GPIO driver (TI) */ -/* add other drivers if necessary... */ +#include "TM4C123GH6PM.h" // the device specific header (TI) +#include "rom.h" // the built-in ROM functions (TI) +#include "sysctl.h" // system control driver (TI) +#include "gpio.h" // GPIO driver (TI) +// add other drivers if necessary... -//Q_DEFINE_THIS_FILE +//Q_DEFINE_THIS_FILE // define the name of this file for assertions + +// Local-scope objects ----------------------------------------------------- +#define LED_RED (1U << 1U) +#define LED_GREEN (1U << 3U) +#define LED_BLUE (1U << 2U) + +#define BTN_SW1 (1U << 4U) +#define BTN_SW2 (1U << 0U) #ifdef Q_SPY - #error Simple Blinky Application does not provide Spy build configuration +#error The Simple Blinky Application does not support Spy build configuration #endif -/* ISRs defined in this BSP ------------------------------------------------*/ -void SysTick_Handler(void); -void GPIOPortA_IRQHandler(void); +//============================================================================ +// Error handler and ISRs... -/* Local-scope objects -----------------------------------------------------*/ -#define LED_RED (1U << 1) -#define LED_GREEN (1U << 3) -#define LED_BLUE (1U << 2) +Q_NORETURN Q_onError(char const *module, int_t const id) { + // NOTE: this implementation of the assertion handler is intended only + // for debugging and MUST be changed for deployment of the application + // (assuming that you ship your production code with assertions enabled). + Q_UNUSED_PAR(module); + Q_UNUSED_PAR(id); + QS_ASSERTION(module, id, (uint32_t)10000U); -#define BTN_SW1 (1U << 4) -#define BTN_SW2 (1U << 0) +#ifndef NDEBUG + // light up all LEDs + GPIOF_AHB->DATA_Bits[LED_GREEN | LED_RED | LED_BLUE] = 0xFFU; + // for debugging, hang on in an endless loop... + for (;;) { + } +#endif -/* ISRs used in this project ===============================================*/ -void SysTick_Handler(void) { - QK_ISR_ENTRY(); /* inform QK about entering an ISR */ - QTIMEEVT_TICK_X(0U, (void *)0); /* process time events for rate 0 */ - QK_ISR_EXIT(); /* inform QK about exiting an ISR */ + NVIC_SystemReset(); +} +//............................................................................ +void assert_failed(char const * const module, int_t const id); // prototype +void assert_failed(char const * const module, int_t const id) { + Q_onError(module, id); } +//............................................................................ +void SysTick_Handler(void); // prototype +void SysTick_Handler(void) { + QK_ISR_ENTRY(); // inform QK about entering an ISR -/* BSP functions ===========================================================*/ -/* MPU setup for TM4C123GXL MCU */ -static void TM4C123GXL_MPU_setup(void) { - /* The following MPU configuration contains the general TM4C memory map. - * - * Please note that the actual TM4C MCUs provide much less Flash and SRAM - * than the maximums configured here. This means that actual MCUs have - * unmapped memory regions (e.g., beyond the actual SRAM). Attempts to - * access these regions causes the HardFault exception, which is the - * desired behavior. - */ - static struct { - uint32_t rbar; - uint32_t rasr; - } const mpu_setup[] = { - { /* region #0: Flash: base=0x0000'0000, size=512M=2^(28+1) */ - 0x00000000U /* base address */ - | MPU_RBAR_VALID_Msk /* valid region */ - | (MPU_RBAR_REGION_Msk & 0U), /* region #0 */ - (28U << MPU_RASR_SIZE_Pos) /* 2^(18+1) region */ - | (0x6U << MPU_RASR_AP_Pos) /* PA:ro/UA:ro */ - | (1U << MPU_RASR_C_Pos) /* C=1 */ - | MPU_RASR_ENABLE_Msk /* region enable */ - }, + QTIMEEVT_TICK_X(0U, &l_SysTick_Handler); // time events at rate 0 - { /* region #1: SRAM: base=0x2000'0000, size=512M=2^(28+1) */ - 0x20000000U /* base address */ - | MPU_RBAR_VALID_Msk /* valid region */ - | (MPU_RBAR_REGION_Msk & 1U), /* region #1 */ - (28U << MPU_RASR_SIZE_Pos) /* 2^(28+1) region */ - | (0x3U << MPU_RASR_AP_Pos) /* PA:rw/UA:rw */ - | (1U << MPU_RASR_XN_Pos) /* XN=1 */ - | (1U << MPU_RASR_S_Pos) /* S=1 */ - | (1U << MPU_RASR_C_Pos) /* C=1 */ - | MPU_RASR_ENABLE_Msk /* region enable */ - }, + QK_ISR_EXIT(); // inform QK about exiting an ISR +} - /* region #3: (not configured) */ - { MPU_RBAR_VALID_Msk | (MPU_RBAR_REGION_Msk & 2U), 0U }, +//============================================================================ +// BSP functions... - { /* region #3: Peripherals: base=0x4000'0000, size=512M=2^(28+1) */ - 0x40000000U /* base address */ - | MPU_RBAR_VALID_Msk /* valid region */ - | (MPU_RBAR_REGION_Msk & 3U), /* region #3 */ - (28U << MPU_RASR_SIZE_Pos) /* 2^(28+1) region */ - | (0x3U << MPU_RASR_AP_Pos) /* PA:rw/UA:rw */ - | (1U << MPU_RASR_XN_Pos) /* XN=1 */ - | (1U << MPU_RASR_S_Pos) /* S=1 */ - | (1U << MPU_RASR_B_Pos) /* B=1 */ - | MPU_RASR_ENABLE_Msk /* region enable */ - }, +void BSP_init(void) { + // Configure the MPU to prevent NULL-pointer dereferencing ... + MPU->RBAR = 0x0U // base address (NULL) + | MPU_RBAR_VALID_Msk // valid region + | (MPU_RBAR_REGION_Msk & 7U); // region #7 + MPU->RASR = (7U << MPU_RASR_SIZE_Pos) // 2^(7+1) region + | (0x0U << MPU_RASR_AP_Pos) // no-access region + | MPU_RASR_ENABLE_Msk; // region enable + MPU->CTRL = MPU_CTRL_PRIVDEFENA_Msk // enable background region + | MPU_CTRL_ENABLE_Msk; // enable the MPU + __ISB(); + __DSB(); - { /* region #4: Priv. Periph: base=0xE000'0000, size=512M=2^(28+1) */ - 0xE0000000U /* base address */ - | MPU_RBAR_VALID_Msk /* valid region */ - | (MPU_RBAR_REGION_Msk & 4U), /* region #4 */ - (28U << MPU_RASR_SIZE_Pos) /* 2^(28+1) region */ - | (0x3U << MPU_RASR_AP_Pos) /* PA:rw/UA:rw */ - | (1U << MPU_RASR_XN_Pos) /* XN=1 */ - | (1U << MPU_RASR_S_Pos) /* S=1 */ - | (1U << MPU_RASR_B_Pos) /* B=1 */ - | MPU_RASR_ENABLE_Msk /* region enable */ - }, - - { /* region #5: Ext RAM: base=0x6000'0000, size=1G=2^(29+1) */ - 0x60000000U /* base address */ - | MPU_RBAR_VALID_Msk /* valid region */ - | (MPU_RBAR_REGION_Msk & 5U), /* region #5 */ - (29U << MPU_RASR_SIZE_Pos) /* 2^(28+1) region */ - | (0x3U << MPU_RASR_AP_Pos) /* PA:rw/UA:rw */ - | (1U << MPU_RASR_XN_Pos) /* XN=1 */ - | (1U << MPU_RASR_S_Pos) /* S=1 */ - | (1U << MPU_RASR_B_Pos) /* B=1 */ - | MPU_RASR_ENABLE_Msk /* region enable */ - }, - - { /* region #6: Ext Dev: base=0xA000'0000, size=1G=2^(29+1) */ - 0xA0000000U /* base address */ - | MPU_RBAR_VALID_Msk /* valid region */ - | (MPU_RBAR_REGION_Msk & 6U), /* region #6 */ - (29U << MPU_RASR_SIZE_Pos) /* 2^(28+1) region */ - | (0x3U << MPU_RASR_AP_Pos) /* PA:rw/UA:rw */ - | (1U << MPU_RASR_XN_Pos) /* XN=1 */ - | (1U << MPU_RASR_S_Pos) /* S=1 */ - | (1U << MPU_RASR_B_Pos) /* B=1 */ - | MPU_RASR_ENABLE_Msk /* region enable */ - }, - - { /* region #7: NULL-pointer: base=0x000'0000, size=256B */ - 0x00000000U /* base address */ - | MPU_RBAR_VALID_Msk /* valid region */ - | (MPU_RBAR_REGION_Msk & 7U), /* region #7 */ - (7U << MPU_RASR_SIZE_Pos) /* 2^(7+1)=256B region */ - | (0x0U << MPU_RASR_AP_Pos) /* PA:na/UA:na */ - | (1U << MPU_RASR_XN_Pos) /* XN=1 */ - | MPU_RASR_ENABLE_Msk /* region enable */ - }, - }; - - /* enable the MemManage_Handler for MPU exception */ + // enable the MemManage_Handler for MPU exception SCB->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk; - __DSB(); - MPU->CTRL = 0U; /* disable the MPU */ - for (uint_fast8_t n = 0U; n < Q_DIM(mpu_setup); ++n) { - MPU->RBAR = mpu_setup[n].rbar; - MPU->RASR = mpu_setup[n].rasr; - } - MPU->CTRL = MPU_CTRL_ENABLE_Msk; /* enable the MPU */ - __ISB(); - __DSB(); -} - -/*..........................................................................*/ -void BSP_init(void) { - /* setup the MPU... */ - TM4C123GXL_MPU_setup(); - - /* NOTE: SystemInit() already called from the startup code - * but SystemCoreClock needs to be updated - */ + // NOTE: SystemInit() has been already called from the startup code + // but SystemCoreClock needs to be updated SystemCoreClockUpdate(); - /* NOTE: The VFP (hardware Floating Point) unit is configured by QK */ + // NOTE: The VFP (hardware Floating Point) unit is configured by QK - /* enable clock for to the peripherals used by this application... */ - SYSCTL->RCGCGPIO |= (1U << 5); /* enable Run mode for GPIOF */ - SYSCTL->GPIOHBCTL |= (1U << 5); /* enable AHB for GPIOF */ + // enable clock for to the peripherals used by this application... + SYSCTL->RCGCGPIO |= (1U << 5U); // enable Run mode for GPIOF + SYSCTL->GPIOHBCTL |= (1U << 5U); // enable AHB for GPIOF __ISB(); __DSB(); - /* configure LEDs (digital output) */ + // configure LEDs (digital output) GPIOF_AHB->DIR |= (LED_RED | LED_BLUE | LED_GREEN); GPIOF_AHB->DEN |= (LED_RED | LED_BLUE | LED_GREEN); GPIOF_AHB->DATA_Bits[LED_RED | LED_BLUE | LED_GREEN] = 0U; - /* configure switches... */ + // configure switches... - /* unlock access to the SW2 pin because it is PROTECTED */ - GPIOF_AHB->LOCK = 0x4C4F434BU; /* unlock GPIOCR register for SW2 */ - /* commit the write (cast const away) */ + // unlock access to the SW2 pin because it is PROTECTED + GPIOF_AHB->LOCK = 0x4C4F434BU; // unlock GPIOCR register for SW2 + // commit the write (cast const away) *(uint32_t volatile *)&GPIOF_AHB->CR = 0x01U; - GPIOF_AHB->DIR &= ~(BTN_SW1 | BTN_SW2); /* input */ - GPIOF_AHB->DEN |= (BTN_SW1 | BTN_SW2); /* digital enable */ - GPIOF_AHB->PUR |= (BTN_SW1 | BTN_SW2); /* pull-up resistor enable */ + GPIOF_AHB->DIR &= ~(BTN_SW1 | BTN_SW2); // input + GPIOF_AHB->DEN |= (BTN_SW1 | BTN_SW2); // digital enable + GPIOF_AHB->PUR |= (BTN_SW1 | BTN_SW2); // pull-up resistor enable *(uint32_t volatile *)&GPIOF_AHB->CR = 0x00U; - GPIOF_AHB->LOCK = 0x0; /* lock GPIOCR register for SW2 */ + GPIOF_AHB->LOCK = 0x0; // lock GPIOCR register for SW2 } -/*..........................................................................*/ -void BSP_ledOn(void) { +//............................................................................ +void BSP_start(void) { + // initialize event pools + static QF_MPOOL_EL(QEvt) smlPoolSto[10]; + QF_poolInit(smlPoolSto, sizeof(smlPoolSto), sizeof(smlPoolSto[0])); + + // initialize publish-subscribe + static QSubscrList subscrSto[MAX_PUB_SIG]; + QActive_psInit(subscrSto, Q_DIM(subscrSto)); + + // instantiate and start AOs/threads... + + static QEvt const *blinkyQueueSto[10]; + Blinky_ctor(); + QACTIVE_START(AO_Blinky, + 1U, // QP prio. of the AO + blinkyQueueSto, // event queue storage + Q_DIM(blinkyQueueSto), // queue length [events] + (void *)0, 0U, // no stack storage + (void *)0); // no initialization param +} +//............................................................................ +void BSP_ledOn() { GPIOF_AHB->DATA_Bits[LED_RED] = 0xFFU; } -/*..........................................................................*/ -void BSP_ledOff(void) { - /* exercise the FPU with some floating point computations */ - float volatile x = 3.1415926F; - x = x + 2.7182818F; - +//............................................................................ +void BSP_ledOff() { GPIOF_AHB->DATA_Bits[LED_RED] = 0x00U; } -/* QF callbacks ============================================================*/ +//============================================================================ +// QF callbacks... void QF_onStartup(void) { - /* set up the SysTick timer to fire at BSP_TICKS_PER_SEC rate */ + // set up the SysTick timer to fire at BSP_TICKS_PER_SEC rate SysTick_Config(SystemCoreClock / BSP_TICKS_PER_SEC); - /* assing all priority bits for preemption-prio. and none to sub-prio. */ + // assign all priority bits for preemption-prio. and none to sub-prio. NVIC_SetPriorityGrouping(0U); - /* set priorities of ALL ISRs used in the system, see NOTE1 - * - * !!!!!!!!!!!!!!!!!!!!!!!!!!!! CAUTION !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - * Assign a priority to EVERY ISR explicitly by calling NVIC_SetPriority(). - * DO NOT LEAVE THE ISR PRIORITIES AT THE DEFAULT VALUE! - */ + // set priorities of ALL ISRs used in the system, see NOTE1 NVIC_SetPriority(SysTick_IRQn, QF_AWARE_ISR_CMSIS_PRI); - /* ... */ + // ... - /* enable IRQs... */ + // enable IRQs... } -/*..........................................................................*/ +//............................................................................ void QF_onCleanup(void) { } -/*..........................................................................*/ +//............................................................................ #ifdef QF_ON_CONTEXT_SW -/* NOTE: the context-switch callback is called with interrupts DISABLED */ +// NOTE: the context-switch callback is called with interrupts DISABLED void QF_onContextSw(QActive *prev, QActive *next) { } -#endif /* QF_ON_CONTEXT_SW */ -/*..........................................................................*/ +#endif // QF_ON_CONTEXT_SW +//............................................................................ void QK_onIdle(void) { - /* toggle the User LED on and then off, see NOTE2 */ + // toggle the User LED on and then off, see NOTE2 QF_INT_DISABLE(); - GPIOF_AHB->DATA_Bits[LED_BLUE] = 0xFFU; /* turn the Blue LED on */ - GPIOF_AHB->DATA_Bits[LED_BLUE] = 0U; /* turn the Blue LED off */ + GPIOF_AHB->DATA_Bits[LED_BLUE] = 0xFFU; // turn the Blue LED on + GPIOF_AHB->DATA_Bits[LED_BLUE] = 0U; // turn the Blue LED off QF_INT_ENABLE(); #ifdef NDEBUG - /* Put the CPU and peripherals to the low-power mode. - * you might need to customize the clock management for your application, - * see the datasheet for your particular Cortex-M MCU. - */ - __WFI(); /* Wait-For-Interrupt */ + // Put the CPU and peripherals to the low-power mode. + // you might need to customize the clock management for your application, + // see the datasheet for your particular Cortex-M MCU. + // + __WFI(); // Wait-For-Interrupt #endif } -/*..........................................................................*/ -Q_NORETURN Q_onAssert(char const * const module, int_t const loc) { - /* - * NOTE: add here your application-specific error handling - */ - (void)module; - (void)loc; - QS_ASSERTION(module, loc, 10000U); /* report assertion to QS */ - NVIC_SystemReset(); -} - -/*============================================================================ -* NOTE1: -* The QF_AWARE_ISR_CMSIS_PRI constant from the QF port specifies the highest -* ISR priority that is disabled by the QF framework. The value is suitable -* for the NVIC_SetPriority() CMSIS function. -* -* Only ISRs prioritized at or below the QF_AWARE_ISR_CMSIS_PRI level (i.e., -* with the numerical values of priorities equal or higher than -* QF_AWARE_ISR_CMSIS_PRI) are allowed to call the QXK_ISR_ENTRY/QXK_ISR_EXIT -* macros or any other QF/QXK services. These ISRs are "QF-aware". -* -* Conversely, any ISRs prioritized above the QF_AWARE_ISR_CMSIS_PRI priority -* level (i.e., with the numerical values of priorities less than -* QF_AWARE_ISR_CMSIS_PRI) are never disabled and are not aware of the kernel. -* Such "QF-unaware" ISRs cannot call any QF/QXK services. In particular they -* can NOT call the macros QXK_ISR_ENTRY/QXK_ISR_ENTRY. The only mechanism -* by which a "QF-unaware" ISR can communicate with the QF framework is by -* triggering a "QF-aware" ISR, which can post/publish events. -* -* NOTE2: -* The User LED is used to visualize the idle loop activity. The brightness -* of the LED is proportional to the frequency of invcations of the idle loop. -* Please note that the LED is toggled with interrupts locked, so no interrupt -* execution time contributes to the brightness of the User LED. -*/ +//============================================================================ +// NOTE1: +// The QF_AWARE_ISR_CMSIS_PRI constant from the QF port specifies the highest +// ISR priority that is disabled by the QF framework. The value is suitable +// for the NVIC_SetPriority() CMSIS function. +// +// Only ISRs prioritized at or below the QF_AWARE_ISR_CMSIS_PRI level (i.e., +// with the numerical values of priorities equal or higher than +// QF_AWARE_ISR_CMSIS_PRI) are allowed to call QF/QK services. These ISRs are +// "QF-aware". +// +// Conversely, any ISRs prioritized above the QF_AWARE_ISR_CMSIS_PRI priority +// level (i.e., with the numerical values of priorities less than +// QF_AWARE_ISR_CMSIS_PRI) are never disabled and are not aware of the kernel. +// Such "QF-unaware" ISRs cannot call any QF/QK services. In particular they +// can NOT post/publish events. The only mechanism by which a "QF-unaware" ISR +// can communicate with the QF framework is by triggering a "QF-aware" ISR, +// which can post/publish events. +// +// NOTE2: +// The User LED is used to visualize the idle loop activity. The brightness +// of the LED is proportional to the frequency of invcations of the idle loop. +// Please note that the LED is toggled with interrupts locked, so no interrupt +// execution time contributes to the brightness of the User LED. +// diff --git a/examples/arm-cm/blinky_ek-tm4c123gxl/qk/gnu/.ccsproject b/examples/arm-cm/blinky_ek-tm4c123gxl/qk/gnu/.ccsproject new file mode 100644 index 00000000..0c19207c --- /dev/null +++ b/examples/arm-cm/blinky_ek-tm4c123gxl/qk/gnu/.ccsproject @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/examples/arm-cm/blinky_ek-tm4c123gxl/qk/gnu/.cproject b/examples/arm-cm/blinky_ek-tm4c123gxl/qk/gnu/.cproject new file mode 100644 index 00000000..2b78bfa0 --- /dev/null +++ b/examples/arm-cm/blinky_ek-tm4c123gxl/qk/gnu/.cproject @@ -0,0 +1,277 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/arm-cm/blinky_ek-tm4c123gxl/qk/gnu/.project b/examples/arm-cm/blinky_ek-tm4c123gxl/qk/gnu/.project new file mode 100644 index 00000000..131a6a82 --- /dev/null +++ b/examples/arm-cm/blinky_ek-tm4c123gxl/qk/gnu/.project @@ -0,0 +1,114 @@ + + + blinky-qk + + + + + + org.eclipse.cdt.managedbuilder.core.genmakebuilder + + + + + org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder + full,incremental, + + + + + + com.ti.ccstudio.core.ccsNature + org.eclipse.cdt.core.cnature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + org.eclipse.cdt.core.ccnature + org.eclipse.cdt.managedbuilder.core.ScannerConfigNature + + + + QK + 2 + PARENT-5-PROJECT_LOC/src/qk + + + QP + 2 + PARENT-5-PROJECT_LOC/src/qf + + + QP_port + 2 + PARENT-5-PROJECT_LOC/ports/arm-cm/qk/gnu + + + QS + 2 + PARENT-5-PROJECT_LOC/src/qs + + + TM4C123GH6PM.h + 1 + PARENT-5-PROJECT_LOC/3rd_party/ek-tm4c123gxl/TM4C123GH6PM.h + + + blinky.c + 1 + PARENT-2-PROJECT_LOC/blinky.c + + + blinky.h + 1 + PARENT-2-PROJECT_LOC/blinky.h + + + bsp.c + 1 + PARENT-1-PROJECT_LOC/bsp.c + + + bsp.h + 1 + PARENT-2-PROJECT_LOC/bsp.h + + + gpio.h + 1 + PARENT-5-PROJECT_LOC/3rd_party/ek-tm4c123gxl/gpio.h + + + main.c + 1 + PARENT-2-PROJECT_LOC/main.c + + + qstamp.c + 1 + PARENT-5-PROJECT_LOC/include/qstamp.c + + + rom.h + 1 + PARENT-5-PROJECT_LOC/3rd_party/ek-tm4c123gxl/rom.h + + + startup_TM4C123GH6PM.c + 1 + PARENT-5-PROJECT_LOC/3rd_party/ek-tm4c123gxl/gnu/startup_TM4C123GH6PM.c + + + sysctl.h + 1 + PARENT-5-PROJECT_LOC/3rd_party/ek-tm4c123gxl/sysctl.h + + + system_TM4C123GH6PM.c + 1 + PARENT-5-PROJECT_LOC/3rd_party/ek-tm4c123gxl/system_TM4C123GH6PM.c + + + system_TM4C123GH6PM.h + 1 + PARENT-5-PROJECT_LOC/3rd_party/ek-tm4c123gxl/system_TM4C123GH6PM.h + + + diff --git a/examples/arm-cm/blinky_ek-tm4c123gxl/qk/gnu/Makefile b/examples/arm-cm/blinky_ek-tm4c123gxl/qk/gnu/Makefile index cdab6888..c3ada1b2 100644 --- a/examples/arm-cm/blinky_ek-tm4c123gxl/qk/gnu/Makefile +++ b/examples/arm-cm/blinky_ek-tm4c123gxl/qk/gnu/Makefile @@ -260,7 +260,7 @@ $(TARGET_BIN): $(TARGET_ELF) $(BIN) -O binary $< $@ $(TARGET_ELF) : $(ASM_OBJS_EXT) $(C_OBJS_EXT) $(CPP_OBJS_EXT) - $(CC) $(CFLAGS) $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o + $(CC) $(CFLAGS) $(QPC)/src/qs/qstamp.c -o $(BIN_DIR)/qstamp.o $(LINK) $(LINKFLAGS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) $(BIN_DIR)/%.d : %.c diff --git a/examples/arm-cm/blinky_ek-tm4c123gxl/qk/iar/blinky-qk.ewd b/examples/arm-cm/blinky_ek-tm4c123gxl/qk/iar/blinky-qk.ewd index 3566d6b2..13d732d4 100644 --- a/examples/arm-cm/blinky_ek-tm4c123gxl/qk/iar/blinky-qk.ewd +++ b/examples/arm-cm/blinky_ek-tm4c123gxl/qk/iar/blinky-qk.ewd @@ -11,7 +11,7 @@ C-SPY 2 - 28 + 32 1 1 - - + + + + + @@ -486,7 +498,7 @@ IJET_ID 2 - 8 + 9 1 1 + + + + + + + + + + + + + @@ -916,7 +980,7 @@ LMIFTDI_ID 2 - 2 + 3 1 1 + + + + + + + NULINK_ID + 2 + + 0 + 1 + 1 + + + @@ -974,7 +1072,7 @@ STLINK_ID 2 - 4 + 8 1 1 + + + + @@ -1185,7 +1300,7 @@ XDS100_ID 2 - 6 + 9 1 1 + + + + @@ -1362,6 +1493,18 @@ $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin 0 + + $TOOLKIT_DIR$\plugins\rtos\FreeRtos\FreeRtosArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin2.ENU.ewplugin + 0 + $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin 0 @@ -1371,11 +1514,15 @@ 0 - $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9.ewplugin 0 - $TOOLKIT_DIR$\plugins\rtos\TI-RTOS\tirtosplugin.ewplugin + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9BE.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin 0 @@ -1391,11 +1538,11 @@ 0 - $EW_DIR$\common\plugins\CodeCoverage\CodeCoverage.ENU.ewplugin - 1 + $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + 0 - $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + $EW_DIR$\common\plugins\TargetAccessServer\TargetAccessServer.ENU.ewplugin 0 @@ -1414,7 +1561,7 @@ C-SPY 2 - 28 + 32 1 0 - - + + + + + @@ -1889,7 +2048,7 @@ IJET_ID 2 - 8 + 9 1 0 + + + + + + + + + + + + + @@ -2319,7 +2530,7 @@ LMIFTDI_ID 2 - 2 + 3 1 0 + + + + + + + NULINK_ID + 2 + + 0 + 1 + 0 + + + @@ -2377,7 +2622,7 @@ STLINK_ID 2 - 4 + 8 1 0 + + + + @@ -2588,7 +2850,7 @@ XDS100_ID 2 - 6 + 9 1 0 + + + + @@ -2765,6 +3043,18 @@ $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin 0 + + $TOOLKIT_DIR$\plugins\rtos\FreeRtos\FreeRtosArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin2.ENU.ewplugin + 0 + $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin 0 @@ -2774,11 +3064,15 @@ 0 - $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9.ewplugin 0 - $TOOLKIT_DIR$\plugins\rtos\TI-RTOS\tirtosplugin.ewplugin + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9BE.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin 0 @@ -2794,11 +3088,11 @@ 0 - $EW_DIR$\common\plugins\CodeCoverage\CodeCoverage.ENU.ewplugin - 1 + $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + 0 - $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + $EW_DIR$\common\plugins\TargetAccessServer\TargetAccessServer.ENU.ewplugin 0 @@ -2817,7 +3111,7 @@ C-SPY 2 - 28 + 32 1 1 - - + + + + + @@ -3292,7 +3598,7 @@ IJET_ID 2 - 8 + 9 1 1 + + + + + + + + + + + + + @@ -3722,7 +4080,7 @@ LMIFTDI_ID 2 - 2 + 3 1 1 + + + + + + + NULINK_ID + 2 + + 0 + 1 + 1 + + + @@ -3780,7 +4172,7 @@ STLINK_ID 2 - 4 + 8 1 1 + + + + @@ -3991,7 +4400,7 @@ XDS100_ID 2 - 6 + 9 1 1 + + + + @@ -4168,6 +4593,18 @@ $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin 0 + + $TOOLKIT_DIR$\plugins\rtos\FreeRtos\FreeRtosArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin2.ENU.ewplugin + 0 + $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin 0 @@ -4177,11 +4614,15 @@ 0 - $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9.ewplugin 0 - $TOOLKIT_DIR$\plugins\rtos\TI-RTOS\tirtosplugin.ewplugin + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9BE.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin 0 @@ -4197,11 +4638,11 @@ 0 - $EW_DIR$\common\plugins\CodeCoverage\CodeCoverage.ENU.ewplugin - 1 + $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + 0 - $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + $EW_DIR$\common\plugins\TargetAccessServer\TargetAccessServer.ENU.ewplugin 0 diff --git a/examples/arm-cm/blinky_ek-tm4c123gxl/qk/iar/blinky-qk.ewp b/examples/arm-cm/blinky_ek-tm4c123gxl/qk/iar/blinky-qk.ewp index 3d75eebb..5654a636 100644 --- a/examples/arm-cm/blinky_ek-tm4c123gxl/qk/iar/blinky-qk.ewp +++ b/examples/arm-cm/blinky_ek-tm4c123gxl/qk/iar/blinky-qk.ewp @@ -11,9 +11,13 @@ General 3 - 28 + 35 1 1 + - - - - - + + + + + + + + ICCARM 2 - 34 + 37 1 1 - - - + + AARM 2 - 10 + 11 1 1 + @@ -656,13 +669,9 @@ 0 + inputOutputBased - - BICOMP - 0 - - BUILDACTION 1 @@ -675,17 +684,13 @@ ILINK 0 - 20 + 27 1 1 - + + + + + + + + + + + + + + + @@ -1010,11 +1075,6 @@ - - BILINK - 0 - - Coder 0 @@ -1031,9 +1091,13 @@ General 3 - 28 + 35 1 0 + - - - - - + + + + + + + + ICCARM 2 - 34 + 37 1 0 - - - + + AARM 2 - 10 + 11 1 0 + @@ -1676,13 +1749,9 @@ 0 + inputOutputBased - - BICOMP - 0 - - BUILDACTION 1 @@ -1695,17 +1764,13 @@ ILINK 0 - 20 + 27 1 0 - + + + + + + + + + + + + + + + @@ -2030,11 +2155,6 @@ - - BILINK - 0 - - Coder 0 @@ -2051,9 +2171,13 @@ General 3 - 28 + 35 1 1 + - - - - - + + + + + + + + ICCARM 2 - 34 + 37 1 1 - - - + + AARM 2 - 10 + 11 1 1 + @@ -2696,13 +2829,9 @@ 0 + inputOutputBased - - BICOMP - 0 - - BUILDACTION 1 @@ -2715,17 +2844,13 @@ ILINK 0 - 20 + 27 1 1 - + + + + + + + + + + + + + + + @@ -3050,17 +3235,15 @@ - - BILINK - 0 - - Coder 0 + + Release + Application @@ -3078,9 +3261,6 @@ $PROJ_DIR$\..\..\main.c - - $PROJ_DIR$\..\..\..\..\..\include\qstamp.c - ek-tm4c123gxl @@ -3169,5 +3349,8 @@ $PROJ_DIR$\..\..\..\..\..\src\qs\qs_rx.c + + $PROJ_DIR$\..\..\..\..\..\src\qs\qstamp.c + diff --git a/examples/arm-cm/blinky_ek-tm4c123gxl/qube/bsp_qube.c b/examples/arm-cm/blinky_ek-tm4c123gxl/qube/bsp_qube.c deleted file mode 100644 index 5028d06f..00000000 --- a/examples/arm-cm/blinky_ek-tm4c123gxl/qube/bsp_qube.c +++ /dev/null @@ -1,38 +0,0 @@ -#include "qpc.h" -#include "bsp.h" -#include "blinky.h" - -Q_DEFINE_THIS_FILE - -/*..........................................................................*/ -void BSP_init(void) { - /* QS dictionaries... */ - QS_SIG_DICTIONARY(TIMEOUT_SIG, (void*)0); - /* QS filters... */ - QS_GLB_FILTER(QS_ALL_RECORDS); -} -/*..........................................................................*/ -void BSP_exit(void) { - QF_stop(); -} -/*..........................................................................*/ -void BSP_ledOff(void) { - QS_BEGIN_ID(QS_USER, 0U) - QS_STR("OFF"); - QS_END() -} -/*..........................................................................*/ -void BSP_ledOn(void) { - QS_BEGIN_ID(QS_USER, 0U) - QS_STR("ON"); - QS_END() -} -/*..........................................................................*/ -/*! callback function to generate an event for this application */ -QEvt const* Qube_onGenEvt(QSignal sig, char const* params) { - Q_UNUSED_PAR(params); /* QHsmTst does not use params */ - - static QEvt evt = { 0U, 0U, 0U }; - evt.sig = sig; - return &evt; -} diff --git a/examples/arm-cm/blinky_ek-tm4c123gxl/qv/armclang/blinky-qv.sct b/examples/arm-cm/blinky_ek-tm4c123gxl/qv/armclang/blinky-qv.sct new file mode 100644 index 00000000..e78acfe0 --- /dev/null +++ b/examples/arm-cm/blinky_ek-tm4c123gxl/qv/armclang/blinky-qv.sct @@ -0,0 +1,23 @@ +; ************************************************************* +; *** Scatter-Loading Description File generated by uVision *** +; +; Modified by Quantum Leaps: +; added STACK as the first section in RW_STACK +; ************************************************************* + +LR_IROM1 0x00000000 0x00040000 { ; load region size_region + ER_IROM1 0x00000000 0x00040000 { ; load address = execution address + *.o (RESET, +First) + *(InRoot$$Sections) + .ANY (+RO) + .ANY (+XO) + } + + RW_STACK 0x20000000 { ; <== Quantum Leaps + * (STACK, +First) + } + RW_IRAM1 +0 (0x00008000 - 2048) { ; NOTE: assume STACK size 2048! + .ANY (+RW +ZI) + } +} + diff --git a/examples/arm-cm/blinky_ek-tm4c123gxl/qv/armclang/blinky-qv.uvoptx b/examples/arm-cm/blinky_ek-tm4c123gxl/qv/armclang/blinky-qv.uvoptx index e9ad2241..7deb48e2 100644 --- a/examples/arm-cm/blinky_ek-tm4c123gxl/qv/armclang/blinky-qv.uvoptx +++ b/examples/arm-cm/blinky_ek-tm4c123gxl/qv/armclang/blinky-qv.uvoptx @@ -8,7 +8,7 @@ *.c *.s*; *.src; *.a* - *.obj + *.obj; *.o *.lib *.txt; *.h; *.inc; *.md *.plm @@ -75,7 +75,7 @@ 1 0 - 0 + 1 4 @@ -103,7 +103,7 @@ 1 0 0 - 8 + 19 @@ -259,7 +259,7 @@ 1 0 - 1 + 0 4 @@ -287,7 +287,7 @@ 1 0 0 - 8 + 19 @@ -477,7 +477,7 @@ 1 0 0 - 8 + 19 @@ -633,18 +633,6 @@ 0 0 - - 1 - 5 - 1 - 0 - 0 - 0 - ..\..\..\..\..\include\qstamp.c - qstamp.c - 0 - 0 - @@ -655,7 +643,7 @@ 0 2 - 6 + 5 1 0 0 @@ -667,7 +655,7 @@ 2 - 7 + 6 5 0 0 @@ -679,7 +667,7 @@ 2 - 8 + 7 2 0 0 @@ -691,7 +679,7 @@ 2 - 9 + 8 5 0 0 @@ -703,7 +691,7 @@ 2 - 10 + 9 5 0 0 @@ -715,7 +703,7 @@ 2 - 11 + 10 5 0 0 @@ -727,7 +715,7 @@ 2 - 12 + 11 5 0 0 @@ -747,7 +735,7 @@ 0 3 - 13 + 12 1 0 0 @@ -759,7 +747,7 @@ 3 - 14 + 13 1 0 0 @@ -771,7 +759,7 @@ 3 - 15 + 14 1 0 0 @@ -783,7 +771,7 @@ 3 - 16 + 15 1 0 0 @@ -795,7 +783,7 @@ 3 - 17 + 16 1 0 0 @@ -807,7 +795,7 @@ 3 - 18 + 17 1 0 0 @@ -819,7 +807,7 @@ 3 - 19 + 18 1 0 0 @@ -831,7 +819,7 @@ 3 - 20 + 19 1 0 0 @@ -843,7 +831,7 @@ 3 - 21 + 20 1 0 0 @@ -855,7 +843,7 @@ 3 - 22 + 21 1 0 0 @@ -867,7 +855,7 @@ 3 - 23 + 22 1 0 0 @@ -879,7 +867,7 @@ 3 - 24 + 23 1 0 0 @@ -891,7 +879,7 @@ 3 - 25 + 24 1 0 0 @@ -911,7 +899,7 @@ 0 4 - 26 + 25 1 0 0 @@ -931,7 +919,7 @@ 0 5 - 27 + 26 1 0 0 @@ -943,7 +931,7 @@ 5 - 28 + 27 1 0 0 @@ -955,7 +943,7 @@ 5 - 29 + 28 1 0 0 @@ -967,7 +955,7 @@ 5 - 30 + 29 1 0 0 @@ -977,6 +965,18 @@ 0 0 + + 5 + 30 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qs\qstamp.c + qstamp.c + 0 + 0 + diff --git a/examples/arm-cm/blinky_ek-tm4c123gxl/qv/armclang/blinky-qv.uvprojx b/examples/arm-cm/blinky_ek-tm4c123gxl/qv/armclang/blinky-qv.uvprojx index b702e9fa..a25440d5 100644 --- a/examples/arm-cm/blinky_ek-tm4c123gxl/qv/armclang/blinky-qv.uvprojx +++ b/examples/arm-cm/blinky_ek-tm4c123gxl/qv/armclang/blinky-qv.uvprojx @@ -10,7 +10,7 @@ blinky-dbg 0x4 ARM-ADS - 6130001::V6.13.1::.\ARMCLANG + 6160000::V6.16::ARMCLANG 1 @@ -337,7 +337,7 @@ 0 - __FPU_PRESENT + ..\..;..\..\..\..\..\include;..\..\..\..\..\ports\arm-cm\qv\armclang;..\..\..\..\..\3rd_party\CMSIS\Include;..\..\..\..\..\3rd_party\ek-tm4c123gxl @@ -361,7 +361,7 @@ - 1 + 0 0 0 0 @@ -370,7 +370,7 @@ 0x00000000 0x20000000 - + .\blinky-qv.sct --entry Reset_Handler @@ -403,11 +403,6 @@ 5 ..\..\blinky.h - - qstamp.c - 1 - ..\..\..\..\..\include\qstamp.c - @@ -622,6 +617,11 @@ 1 ..\..\..\..\..\src\qs\qs_rx.c + + qstamp.c + 1 + ..\..\..\..\..\src\qs\qstamp.c + @@ -957,7 +957,7 @@ 0 - NDEBUG __FPU_PRESENT + NDEBUG ..\..;..\..\..\..\..\include;..\..\..\..\..\ports\arm-cm\qv\armclang;..\..\..\..\..\3rd_party\CMSIS\Include;..\..\..\..\..\3rd_party\ek-tm4c123gxl @@ -981,7 +981,7 @@ - 1 + 0 0 0 0 @@ -990,7 +990,7 @@ 0x00000000 0x20000000 - blinky-qv.sct + ,\blinky-qv.sct --entry Reset_Handler @@ -1023,11 +1023,6 @@ 5 ..\..\blinky.h - - qstamp.c - 1 - ..\..\..\..\..\include\qstamp.c - @@ -1242,6 +1237,11 @@ 1 ..\..\..\..\..\src\qs\qs_rx.c + + qstamp.c + 1 + ..\..\..\..\..\src\qs\qstamp.c + @@ -1250,7 +1250,7 @@ blinky-spy 0x4 ARM-ADS - 5060750::V5.06 update 6 (build 750)::ARMCC + 6160000::V6.16::ARMCLANG 1 @@ -1577,7 +1577,7 @@ 0 - Q_SPY __FPU_PRESENT + Q_SPY ..\..;..\..\..\..\..\include;..\..\..\..\..\ports\arm-cm\qv\armclang;..\..\..\..\..\3rd_party\CMSIS\Include;..\..\..\..\..\3rd_party\ek-tm4c123gxl @@ -1601,7 +1601,7 @@ - 1 + 0 0 0 0 @@ -1610,7 +1610,7 @@ 0x00000000 0x20000000 - + .\blinky-qv.sct --entry Reset_Handler @@ -1643,11 +1643,6 @@ 5 ..\..\blinky.h - - qstamp.c - 1 - ..\..\..\..\..\include\qstamp.c - @@ -1793,6 +1788,11 @@ 1 ..\..\..\..\..\src\qs\qs_rx.c + + qstamp.c + 1 + ..\..\..\..\..\src\qs\qstamp.c + diff --git a/examples/arm-cm/blinky_ek-tm4c123gxl/qv/bsp.c b/examples/arm-cm/blinky_ek-tm4c123gxl/qv/bsp.c index be819aa3..8927d853 100644 --- a/examples/arm-cm/blinky_ek-tm4c123gxl/qv/bsp.c +++ b/examples/arm-cm/blinky_ek-tm4c123gxl/qv/bsp.c @@ -1,317 +1,243 @@ -/***************************************************************************** -* Product: "Blinky" on EK-TM4C123GXL board, cooperative Vanilla kernel -* Last updated for version 7.2.0 -* Last updated on 2022-12-17 -* -* Q u a n t u m L e a P s -* ------------------------ -* Modern Embedded Software -* -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* -* -*****************************************************************************/ -#include "qpc.h" -#include "blinky.h" -#include "bsp.h" +//============================================================================ +// Product: Blinky example, EK-TM4C123GXL board, QV kernel +// Last updated for version 7.3.0 +// Last updated on 2023-08-15 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. +// +// This program is open source software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Alternatively, this program may be distributed and modified under the +// terms of Quantum Leaps commercial licenses, which expressly supersede +// the GNU General Public License and are specifically designed for +// licensees interested in retaining the proprietary status of their code. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Contact information: +// +// +//============================================================================ +#include "qpc.h" // QP/C real-time embedded framework +#include "blinky.h" // Blinky Application interface +#include "bsp.h" // Board Support Package -#include "TM4C123GH6PM.h" /* the device specific header (TI) */ -#include "rom.h" /* the built-in ROM functions (TI) */ -#include "sysctl.h" /* system control driver (TI) */ -#include "gpio.h" /* GPIO driver (TI) */ -/* add other drivers if necessary... */ +#include "TM4C123GH6PM.h" // the device specific header (TI) +#include "rom.h" // the built-in ROM functions (TI) +#include "sysctl.h" // system control driver (TI) +#include "gpio.h" // GPIO driver (TI) +// add other drivers if necessary... -//Q_DEFINE_THIS_FILE +//Q_DEFINE_THIS_FILE // define the name of this file for assertions + +// Local-scope objects ----------------------------------------------------- +#define LED_RED (1U << 1U) +#define LED_GREEN (1U << 3U) +#define LED_BLUE (1U << 2U) + +#define BTN_SW1 (1U << 4U) +#define BTN_SW2 (1U << 0U) #ifdef Q_SPY - #error Simple Blinky Application does not provide Spy build configuration +#error The Simple Blinky Application does not support Spy build configuration #endif -/* ISRs defined in this BSP ------------------------------------------------*/ -void SysTick_Handler(void); -void GPIOPortA_IRQHandler(void); +//============================================================================ +// Error handler and ISRs... -/* Local-scope objects -----------------------------------------------------*/ -#define LED_RED (1U << 1) -#define LED_GREEN (1U << 3) -#define LED_BLUE (1U << 2) +Q_NORETURN Q_onError(char const *module, int_t const id) { + // NOTE: this implementation of the assertion handler is intended only + // for debugging and MUST be changed for deployment of the application + // (assuming that you ship your production code with assertions enabled). + Q_UNUSED_PAR(module); + Q_UNUSED_PAR(id); + QS_ASSERTION(module, id, (uint32_t)10000U); -#define BTN_SW1 (1U << 4) -#define BTN_SW2 (1U << 0) +#ifndef NDEBUG + // light up all LEDs + GPIOF_AHB->DATA_Bits[LED_GREEN | LED_RED | LED_BLUE] = 0xFFU; + // for debugging, hang on in an endless loop... + for (;;) { + } +#endif -/* ISRs used in this project ===============================================*/ + NVIC_SystemReset(); +} +//............................................................................ +void assert_failed(char const * const module, int_t const id); // prototype +void assert_failed(char const * const module, int_t const id) { + Q_onError(module, id); +} + +//............................................................................ +void SysTick_Handler(void); // prototype void SysTick_Handler(void) { - QTIMEEVT_TICK_X(0U, (void *)0); /* process time events for rate 0 */ + QTIMEEVT_TICK_X(0U, &l_SysTick_Handler); // time events at rate 0 QV_ARM_ERRATUM_838869(); } -/* BSP functions ===========================================================*/ -/* MPU setup for TM4C123GXL MCU */ -static void TM4C123GXL_MPU_setup(void) { - /* The following MPU configuration contains the general TM4C memory map. - * - * Please note that the actual TM4C MCUs provide much less Flash and SRAM - * than the maximums configured here. This means that actual MCUs have - * unmapped memory regions (e.g., beyond the actual SRAM). Attempts to - * access these regions causes the HardFault exception, which is the - * desired behavior. - */ - static struct { - uint32_t rbar; - uint32_t rasr; - } const mpu_setup[] = { - { /* region #0: Flash: base=0x0000'0000, size=512M=2^(28+1) */ - 0x00000000U /* base address */ - | MPU_RBAR_VALID_Msk /* valid region */ - | (MPU_RBAR_REGION_Msk & 0U), /* region #0 */ - (28U << MPU_RASR_SIZE_Pos) /* 2^(18+1) region */ - | (0x6U << MPU_RASR_AP_Pos) /* PA:ro/UA:ro */ - | (1U << MPU_RASR_C_Pos) /* C=1 */ - | MPU_RASR_ENABLE_Msk /* region enable */ - }, +//============================================================================ +// BSP functions... - { /* region #1: SRAM: base=0x2000'0000, size=512M=2^(28+1) */ - 0x20000000U /* base address */ - | MPU_RBAR_VALID_Msk /* valid region */ - | (MPU_RBAR_REGION_Msk & 1U), /* region #1 */ - (28U << MPU_RASR_SIZE_Pos) /* 2^(28+1) region */ - | (0x3U << MPU_RASR_AP_Pos) /* PA:rw/UA:rw */ - | (1U << MPU_RASR_XN_Pos) /* XN=1 */ - | (1U << MPU_RASR_S_Pos) /* S=1 */ - | (1U << MPU_RASR_C_Pos) /* C=1 */ - | MPU_RASR_ENABLE_Msk /* region enable */ - }, +void BSP_init(void) { + // Configure the MPU to prevent NULL-pointer dereferencing ... + MPU->RBAR = 0x0U // base address (NULL) + | MPU_RBAR_VALID_Msk // valid region + | (MPU_RBAR_REGION_Msk & 7U); // region #7 + MPU->RASR = (7U << MPU_RASR_SIZE_Pos) // 2^(7+1) region + | (0x0U << MPU_RASR_AP_Pos) // no-access region + | MPU_RASR_ENABLE_Msk; // region enable + MPU->CTRL = MPU_CTRL_PRIVDEFENA_Msk // enable background region + | MPU_CTRL_ENABLE_Msk; // enable the MPU + __ISB(); + __DSB(); - /* region #3: (not configured) */ - { MPU_RBAR_VALID_Msk | (MPU_RBAR_REGION_Msk & 2U), 0U }, - - { /* region #3: Peripherals: base=0x4000'0000, size=512M=2^(28+1) */ - 0x40000000U /* base address */ - | MPU_RBAR_VALID_Msk /* valid region */ - | (MPU_RBAR_REGION_Msk & 3U), /* region #3 */ - (28U << MPU_RASR_SIZE_Pos) /* 2^(28+1) region */ - | (0x3U << MPU_RASR_AP_Pos) /* PA:rw/UA:rw */ - | (1U << MPU_RASR_XN_Pos) /* XN=1 */ - | (1U << MPU_RASR_S_Pos) /* S=1 */ - | (1U << MPU_RASR_B_Pos) /* B=1 */ - | MPU_RASR_ENABLE_Msk /* region enable */ - }, - - { /* region #4: Priv. Periph: base=0xE000'0000, size=512M=2^(28+1) */ - 0xE0000000U /* base address */ - | MPU_RBAR_VALID_Msk /* valid region */ - | (MPU_RBAR_REGION_Msk & 4U), /* region #4 */ - (28U << MPU_RASR_SIZE_Pos) /* 2^(28+1) region */ - | (0x3U << MPU_RASR_AP_Pos) /* PA:rw/UA:rw */ - | (1U << MPU_RASR_XN_Pos) /* XN=1 */ - | (1U << MPU_RASR_S_Pos) /* S=1 */ - | (1U << MPU_RASR_B_Pos) /* B=1 */ - | MPU_RASR_ENABLE_Msk /* region enable */ - }, - - { /* region #5: Ext RAM: base=0x6000'0000, size=1G=2^(29+1) */ - 0x60000000U /* base address */ - | MPU_RBAR_VALID_Msk /* valid region */ - | (MPU_RBAR_REGION_Msk & 5U), /* region #5 */ - (29U << MPU_RASR_SIZE_Pos) /* 2^(28+1) region */ - | (0x3U << MPU_RASR_AP_Pos) /* PA:rw/UA:rw */ - | (1U << MPU_RASR_XN_Pos) /* XN=1 */ - | (1U << MPU_RASR_S_Pos) /* S=1 */ - | (1U << MPU_RASR_B_Pos) /* B=1 */ - | MPU_RASR_ENABLE_Msk /* region enable */ - }, - - { /* region #6: Ext Dev: base=0xA000'0000, size=1G=2^(29+1) */ - 0xA0000000U /* base address */ - | MPU_RBAR_VALID_Msk /* valid region */ - | (MPU_RBAR_REGION_Msk & 6U), /* region #6 */ - (29U << MPU_RASR_SIZE_Pos) /* 2^(28+1) region */ - | (0x3U << MPU_RASR_AP_Pos) /* PA:rw/UA:rw */ - | (1U << MPU_RASR_XN_Pos) /* XN=1 */ - | (1U << MPU_RASR_S_Pos) /* S=1 */ - | (1U << MPU_RASR_B_Pos) /* B=1 */ - | MPU_RASR_ENABLE_Msk /* region enable */ - }, - - { /* region #7: NULL-pointer: base=0x000'0000, size=256B */ - 0x00000000U /* base address */ - | MPU_RBAR_VALID_Msk /* valid region */ - | (MPU_RBAR_REGION_Msk & 7U), /* region #7 */ - (7U << MPU_RASR_SIZE_Pos) /* 2^(7+1)=256B region */ - | (0x0U << MPU_RASR_AP_Pos) /* PA:na/UA:na */ - | (1U << MPU_RASR_XN_Pos) /* XN=1 */ - | MPU_RASR_ENABLE_Msk /* region enable */ - }, - }; - - /* enable the MemManage_Handler for MPU exception */ + // enable the MemManage_Handler for MPU exception SCB->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk; - __DSB(); - MPU->CTRL = 0U; /* disable the MPU */ - for (uint_fast8_t n = 0U; n < Q_DIM(mpu_setup); ++n) { - MPU->RBAR = mpu_setup[n].rbar; - MPU->RASR = mpu_setup[n].rasr; - } - MPU->CTRL = MPU_CTRL_ENABLE_Msk; /* enable the MPU */ - __ISB(); - __DSB(); -} - -/*..........................................................................*/ -void BSP_init(void) { - /* setup the MPU... */ - TM4C123GXL_MPU_setup(); - - /* NOTE: SystemInit() already called from the startup code - * but SystemCoreClock needs to be updated - */ + // NOTE: SystemInit() has been already called from the startup code + // but SystemCoreClock needs to be updated SystemCoreClockUpdate(); - /* NOTE: The VFP (hardware Floating Point) unit is configured by QV */ + // NOTE: The VFP (hardware Floating Point) unit is configured by QK - /* enable clock for to the peripherals used by this application... */ - SYSCTL->RCGCGPIO |= (1U << 5); /* enable Run mode for GPIOF */ - SYSCTL->GPIOHBCTL |= (1U << 5); /* enable AHB for GPIOF */ + // enable clock for to the peripherals used by this application... + SYSCTL->RCGCGPIO |= (1U << 5U); // enable Run mode for GPIOF + SYSCTL->GPIOHBCTL |= (1U << 5U); // enable AHB for GPIOF __ISB(); __DSB(); - /* configure LEDs (digital output) */ + // configure LEDs (digital output) GPIOF_AHB->DIR |= (LED_RED | LED_BLUE | LED_GREEN); GPIOF_AHB->DEN |= (LED_RED | LED_BLUE | LED_GREEN); GPIOF_AHB->DATA_Bits[LED_RED | LED_BLUE | LED_GREEN] = 0U; - /* configure switches... */ + // configure switches... - /* unlock access to the SW2 pin because it is PROTECTED */ - GPIOF_AHB->LOCK = 0x4C4F434BU; /* unlock GPIOCR register for SW2 */ - /* commit the write (cast const away) */ + // unlock access to the SW2 pin because it is PROTECTED + GPIOF_AHB->LOCK = 0x4C4F434BU; // unlock GPIOCR register for SW2 + // commit the write (cast const away) *(uint32_t volatile *)&GPIOF_AHB->CR = 0x01U; - GPIOF_AHB->DIR &= ~(BTN_SW1 | BTN_SW2); /* input */ - GPIOF_AHB->DEN |= (BTN_SW1 | BTN_SW2); /* digital enable */ - GPIOF_AHB->PUR |= (BTN_SW1 | BTN_SW2); /* pull-up resistor enable */ + GPIOF_AHB->DIR &= ~(BTN_SW1 | BTN_SW2); // input + GPIOF_AHB->DEN |= (BTN_SW1 | BTN_SW2); // digital enable + GPIOF_AHB->PUR |= (BTN_SW1 | BTN_SW2); // pull-up resistor enable *(uint32_t volatile *)&GPIOF_AHB->CR = 0x00U; - GPIOF_AHB->LOCK = 0x0; /* lock GPIOCR register for SW2 */ + GPIOF_AHB->LOCK = 0x0; // lock GPIOCR register for SW2 } -/*..........................................................................*/ -void BSP_ledOn(void) { +//............................................................................ +void BSP_start(void) { + // initialize event pools + static QF_MPOOL_EL(QEvt) smlPoolSto[10]; + QF_poolInit(smlPoolSto, sizeof(smlPoolSto), sizeof(smlPoolSto[0])); + + // initialize publish-subscribe + static QSubscrList subscrSto[MAX_PUB_SIG]; + QActive_psInit(subscrSto, Q_DIM(subscrSto)); + + // instantiate and start AOs/threads... + + static QEvt const *blinkyQueueSto[10]; + Blinky_ctor(); + QACTIVE_START(AO_Blinky, + 1U, // QP prio. of the AO + blinkyQueueSto, // event queue storage + Q_DIM(blinkyQueueSto), // queue length [events] + (void *)0, 0U, // no stack storage + (void *)0); // no initialization param +} +//............................................................................ +void BSP_ledOn() { GPIOF_AHB->DATA_Bits[LED_RED] = 0xFFU; } -/*..........................................................................*/ -void BSP_ledOff(void) { - /* exercise the FPU with some floating point computations */ - float volatile x = 3.1415926F; - x = x + 2.7182818F; - +//............................................................................ +void BSP_ledOff() { GPIOF_AHB->DATA_Bits[LED_RED] = 0x00U; } -/* QF callbacks ============================================================*/ +//============================================================================ +// QF callbacks... void QF_onStartup(void) { - /* set up the SysTick timer to fire at BSP_TICKS_PER_SEC rate */ + // set up the SysTick timer to fire at BSP_TICKS_PER_SEC rate SysTick_Config(SystemCoreClock / BSP_TICKS_PER_SEC); - /* assing all priority bits for preemption-prio. and none to sub-prio. */ + // assign all priority bits for preemption-prio. and none to sub-prio. NVIC_SetPriorityGrouping(0U); - /* set priorities of ALL ISRs used in the system, see NOTE1 - * - * !!!!!!!!!!!!!!!!!!!!!!!!!!!! CAUTION !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - * Assign a priority to EVERY ISR explicitly by calling NVIC_SetPriority(). - * DO NOT LEAVE THE ISR PRIORITIES AT THE DEFAULT VALUE! - */ + // set priorities of ALL ISRs used in the system, see NOTE1 NVIC_SetPriority(SysTick_IRQn, QF_AWARE_ISR_CMSIS_PRI); - /* ... */ + // ... - /* enable IRQs... */ + // enable IRQs... } -/*..........................................................................*/ +//............................................................................ void QF_onCleanup(void) { } -/*..........................................................................*/ +//............................................................................ #ifdef QF_ON_CONTEXT_SW -/* NOTE: the context-switch callback is called with interrupts DISABLED */ +// NOTE: the context-switch callback is called with interrupts DISABLED void QF_onContextSw(QActive *prev, QActive *next) { } -#endif /* QF_ON_CONTEXT_SW */ -/*..........................................................................*/ -void QV_onIdle(void) { /* CATION: called with interrupts DISABLED, NOTE2 */ - /* toggle the User LED on and then off, see NOTE2 */ - GPIOF_AHB->DATA_Bits[LED_BLUE] = 0xFFU; /* turn the Blue LED on */ - GPIOF_AHB->DATA_Bits[LED_BLUE] = 0U; /* turn the Blue LED off */ +#endif // QF_ON_CONTEXT_SW +//............................................................................ +void QV_onIdle(void) { // CATION: called with interrupts DISABLED, NOTE2 + // toggle the User LED on and then off, see NOTE2 + GPIOF_AHB->DATA_Bits[LED_BLUE] = 0xFFU; // turn the Blue LED on + GPIOF_AHB->DATA_Bits[LED_BLUE] = 0U; // turn the Blue LED off #ifdef NDEBUG - /* Put the CPU and peripherals to the low-power mode. - * you might need to customize the clock management for your application, - * see the datasheet for your particular Cortex-M MCU. - */ - QV_CPU_SLEEP(); /* atomically go to sleep and enable interrupts */ + // Put the CPU and peripherals to the low-power mode. + // you might need to customize the clock management for your application, + // see the datasheet for your particular Cortex-M MCU. + // + QV_CPU_SLEEP(); // atomically go to sleep and enable interrupts #else - QF_INT_ENABLE(); /* just enable interrupts */ + QF_INT_ENABLE(); // just enable interrupts #endif } -/*..........................................................................*/ -Q_NORETURN Q_onAssert(char const * const module, int_t const loc) { - /* - * NOTE: add here your application-specific error handling - */ - (void)module; - (void)loc; - QS_ASSERTION(module, loc, 10000U); /* report assertion to QS */ - NVIC_SystemReset(); -} - -/*============================================================================ -* NOTE1: -* The QF_AWARE_ISR_CMSIS_PRI constant from the QF port specifies the highest -* ISR priority that is disabled by the QF framework. The value is suitable -* for the NVIC_SetPriority() CMSIS function. -* -* Only ISRs prioritized at or below the QF_AWARE_ISR_CMSIS_PRI level (i.e., -* with the numerical values of priorities equal or higher than -* QF_AWARE_ISR_CMSIS_PRI) are allowed to call the QXK_ISR_ENTRY/QXK_ISR_EXIT -* macros or any other QF/QXK services. These ISRs are "QF-aware". -* -* Conversely, any ISRs prioritized above the QF_AWARE_ISR_CMSIS_PRI priority -* level (i.e., with the numerical values of priorities less than -* QF_AWARE_ISR_CMSIS_PRI) are never disabled and are not aware of the kernel. -* Such "QF-unaware" ISRs cannot call any QF/QXK services. In particular they -* can NOT call the macros QXK_ISR_ENTRY/QXK_ISR_ENTRY. The only mechanism -* by which a "QF-unaware" ISR can communicate with the QF framework is by -* triggering a "QF-aware" ISR, which can post/publish events. -* -* NOTE2: -* The QV_onIdle() callback is called with interrupts disabled, because the -* determination of the idle condition might change by any interrupt posting -* an event. QV_onIdle() must internally enable interrupts, ideally -* atomically with putting the CPU to the power-saving mode. -* -* NOTE3: -* One of the LEDs is used to visualize the idle loop activity. The brightness -* of the LED is proportional to the frequency of invcations of the idle loop. -* Please note that the LED is toggled with interrupts locked, so no interrupt -* execution time contributes to the brightness of the User LED. -*/ +//============================================================================ +// NOTE1: +// The QF_AWARE_ISR_CMSIS_PRI constant from the QF port specifies the highest +// ISR priority that is disabled by the QF framework. The value is suitable +// for the NVIC_SetPriority() CMSIS function. +// +// Only ISRs prioritized at or below the QF_AWARE_ISR_CMSIS_PRI level (i.e., +// with the numerical values of priorities equal or higher than +// QF_AWARE_ISR_CMSIS_PRI) are allowed to call QF/QV services. These ISRs are +// "QF-aware". +// +// Conversely, any ISRs prioritized above the QF_AWARE_ISR_CMSIS_PRI priority +// level (i.e., with the numerical values of priorities less than +// QF_AWARE_ISR_CMSIS_PRI) are never disabled and are not aware of the kernel. +// Such "QF-unaware" ISRs cannot call any QF/QXK services. In particular they +// can NOT post/publish events. The only mechanism by which a "QF-unaware" ISR +// can communicate with the QF framework is by triggering a "QF-aware" ISR, +// which can post/publish events. +// +// NOTE2: +// The QV_onIdle() callback is called with interrupts disabled, because the +// determination of the idle condition might change by any interrupt posting +// an event. QV_onIdle() must internally enable interrupts, ideally +// atomically with putting the CPU to the power-saving mode. +// +// NOTE3: +// One of the LEDs is used to visualize the idle loop activity. The brightness +// of the LED is proportional to the frequency of invcations of the idle loop. +// Please note that the LED is toggled with interrupts locked, so no interrupt +// execution time contributes to the brightness of the User LED. +// diff --git a/examples/arm-cm/blinky_ek-tm4c123gxl/qv/gnu/.ccsproject b/examples/arm-cm/blinky_ek-tm4c123gxl/qv/gnu/.ccsproject new file mode 100644 index 00000000..0c19207c --- /dev/null +++ b/examples/arm-cm/blinky_ek-tm4c123gxl/qv/gnu/.ccsproject @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/examples/arm-cm/blinky_ek-tm4c123gxl/qv/gnu/.cproject b/examples/arm-cm/blinky_ek-tm4c123gxl/qv/gnu/.cproject new file mode 100644 index 00000000..82eb559c --- /dev/null +++ b/examples/arm-cm/blinky_ek-tm4c123gxl/qv/gnu/.cproject @@ -0,0 +1,277 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/arm-cm/blinky_ek-tm4c123gxl/qv/gnu/.project b/examples/arm-cm/blinky_ek-tm4c123gxl/qv/gnu/.project new file mode 100644 index 00000000..994b7a66 --- /dev/null +++ b/examples/arm-cm/blinky_ek-tm4c123gxl/qv/gnu/.project @@ -0,0 +1,114 @@ + + + blinky-qv + + + + + + org.eclipse.cdt.managedbuilder.core.genmakebuilder + + + + + org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder + full,incremental, + + + + + + com.ti.ccstudio.core.ccsNature + org.eclipse.cdt.core.cnature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + org.eclipse.cdt.core.ccnature + org.eclipse.cdt.managedbuilder.core.ScannerConfigNature + + + + QP + 2 + PARENT-5-PROJECT_LOC/src/qf + + + QP_port + 2 + PARENT-5-PROJECT_LOC/ports/arm-cm/qv/gnu + + + QS + 2 + PARENT-5-PROJECT_LOC/src/qs + + + QV + 2 + PARENT-5-PROJECT_LOC/src/qv + + + TM4C123GH6PM.h + 1 + PARENT-5-PROJECT_LOC/3rd_party/ek-tm4c123gxl/TM4C123GH6PM.h + + + blinky.c + 1 + PARENT-2-PROJECT_LOC/blinky.c + + + blinky.h + 1 + PARENT-2-PROJECT_LOC/blinky.h + + + bsp.c + 1 + PARENT-1-PROJECT_LOC/bsp.c + + + bsp.h + 1 + PARENT-2-PROJECT_LOC/bsp.h + + + gpio.h + 1 + PARENT-5-PROJECT_LOC/3rd_party/ek-tm4c123gxl/gpio.h + + + main.c + 1 + PARENT-2-PROJECT_LOC/main.c + + + qstamp.c + 1 + PARENT-5-PROJECT_LOC/include/qstamp.c + + + rom.h + 1 + PARENT-5-PROJECT_LOC/3rd_party/ek-tm4c123gxl/rom.h + + + startup_TM4C123GH6PM.c + 1 + PARENT-5-PROJECT_LOC/3rd_party/ek-tm4c123gxl/gnu/startup_TM4C123GH6PM.c + + + sysctl.h + 1 + PARENT-5-PROJECT_LOC/3rd_party/ek-tm4c123gxl/sysctl.h + + + system_TM4C123GH6PM.c + 1 + PARENT-5-PROJECT_LOC/3rd_party/ek-tm4c123gxl/system_TM4C123GH6PM.c + + + system_TM4C123GH6PM.h + 1 + PARENT-5-PROJECT_LOC/3rd_party/ek-tm4c123gxl/system_TM4C123GH6PM.h + + + diff --git a/examples/arm-cm/blinky_ek-tm4c123gxl/qv/gnu/Makefile b/examples/arm-cm/blinky_ek-tm4c123gxl/qv/gnu/Makefile index e6b31df4..7cbc2aa2 100644 --- a/examples/arm-cm/blinky_ek-tm4c123gxl/qv/gnu/Makefile +++ b/examples/arm-cm/blinky_ek-tm4c123gxl/qv/gnu/Makefile @@ -260,7 +260,7 @@ $(TARGET_BIN): $(TARGET_ELF) $(BIN) -O binary $< $@ $(TARGET_ELF) : $(ASM_OBJS_EXT) $(C_OBJS_EXT) $(CPP_OBJS_EXT) - $(CC) $(CFLAGS) $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o + $(CC) $(CFLAGS) $(QPC)/src/qs/qstamp.c -o $(BIN_DIR)/qstamp.o $(LINK) $(LINKFLAGS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) $(BIN_DIR)/%.d : %.c diff --git a/examples/arm-cm/blinky_ek-tm4c123gxl/qv/iar/blinky-qv.ewd b/examples/arm-cm/blinky_ek-tm4c123gxl/qv/iar/blinky-qv.ewd index 3c81d8df..9c506a77 100644 --- a/examples/arm-cm/blinky_ek-tm4c123gxl/qv/iar/blinky-qv.ewd +++ b/examples/arm-cm/blinky_ek-tm4c123gxl/qv/iar/blinky-qv.ewd @@ -1,4462 +1,4654 @@ - - + - 2 - - Debug - - ARM - - 1 - - C-SPY - 2 - - 26 - 1 + 3 + + Debug + + ARM + 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ARMSIM_ID - 2 - - 1 - 1 - 1 - - - - - - - - ANGEL_ID - 2 - - 0 - 1 - 1 - - - - - - - - - - - - CMSISDAP_ID - 2 - - 2 - 1 - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - GDBSERVER_ID - 2 - - 0 - 1 - 1 - - - - - - - - - - - IARROM_ID - 2 - - 1 - 1 - 1 - - - - - - - - - IJET_ID - 2 - - 6 - 1 - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - JLINK_ID - 2 - - 15 - 1 - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - LMIFTDI_ID - 2 - - 2 - 1 - 1 - - - - - - - - - - MACRAIGOR_ID - 2 - - 3 - 1 - 1 - - - - - - - - - - - - - - - - - - - - - - - PEMICRO_ID - 2 - - 1 - 1 - 1 - - - - - - - - - - - - - - - - - - - RDI_ID - 2 - - 2 - 1 - 1 - - - - - - - - - - - - - - - - STLINK_ID - 2 - - 2 - 1 - 1 - - - - - - - - - - - THIRDPARTY_ID - 2 - - 0 - 1 - 1 - - - - - - - - XDS100_ID - 2 - - 4 - 1 - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - $TOOLKIT_DIR$\plugins\middleware\HCCWare\HCCWare.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\AVIX\AVIX.ENU.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\CMX\CmxArmPlugin.ENU.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\CMX\CmxTinyArmPlugin.ENU.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\MQX\MQXRtosPlugin.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\Quadros\Quadros_EWB7_Plugin.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\SafeRTOS\SafeRTOSPlugin.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\TI-RTOS\tirtosplugin.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-286-KA-CSpy.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-KA-CSpy.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\uCOS-III\uCOS-III-KA-CSpy.ewplugin - 0 - - - $EW_DIR$\common\plugins\CodeCoverage\CodeCoverage.ENU.ewplugin - 1 - - - $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin - 0 - - - $EW_DIR$\common\plugins\SymList\SymList.ENU.ewplugin - 1 - - - $EW_DIR$\common\plugins\uCProbe\uCProbePlugin.ENU.ewplugin - 0 - - - - - Release - - ARM - - 0 - - C-SPY - 2 - - 26 - 1 + + C-SPY + 2 + + 32 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ARMSIM_ID + 2 + + 1 + 1 + 1 + + + + + + + + CADI_ID + 2 + + 0 + 1 + 1 + + + + + + + + + CMSISDAP_ID + 2 + + 4 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + GDBSERVER_ID + 2 + + 0 + 1 + 1 + + + + + + + + + + + IJET_ID + 2 + + 9 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + JLINK_ID + 2 + + 16 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + LMIFTDI_ID + 2 + + 3 + 1 + 1 + + + + + + + + + + + + + NULINK_ID + 2 + + 0 + 1 + 1 + + + + + + + PEMICRO_ID + 2 + + 3 + 1 + 1 + + + + + + + + STLINK_ID + 2 + + 8 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + THIRDPARTY_ID + 2 + + 0 + 1 + 1 + + + + + + + + TIFET_ID + 2 + + 1 + 1 + 1 + + + + + + + + + + + + + + + + + + + XDS100_ID + 2 + + 9 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + $TOOLKIT_DIR$\plugins\rtos\CMX\CmxArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\CMX\CmxTinyArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\FreeRtos\FreeRtosArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin2.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SafeRTOS\SafeRTOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9BE.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-286-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-III\uCOS-III-KA-CSpy.ewplugin + 0 + + + $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\TargetAccessServer\TargetAccessServer.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\uCProbe\uCProbePlugin.ENU.ewplugin + 0 + + + + + Release + + ARM + 0 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ARMSIM_ID - 2 - - 1 - 1 - 0 - - - - - - - - ANGEL_ID - 2 - - 0 - 1 - 0 - - - - - - - - - - - - CMSISDAP_ID - 2 - - 2 - 1 - 0 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - GDBSERVER_ID - 2 - - 0 - 1 - 0 - - - - - - - - - - - IARROM_ID - 2 - - 1 - 1 - 0 - - - - - - - - - IJET_ID - 2 - - 6 - 1 - 0 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - JLINK_ID - 2 - - 15 - 1 - 0 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - LMIFTDI_ID - 2 - - 2 - 1 - 0 - - - - - - - - - - MACRAIGOR_ID - 2 - - 3 - 1 - 0 - - - - - - - - - - - - - - - - - - - - - - - PEMICRO_ID - 2 - - 1 - 1 - 0 - - - - - - - - - - - - - - - - - - - RDI_ID - 2 - - 2 - 1 - 0 - - - - - - - - - - - - - - - - STLINK_ID - 2 - - 2 - 1 - 0 - - - - - - - - - - - THIRDPARTY_ID - 2 - - 0 - 1 - 0 - - - - - - - - XDS100_ID - 2 - - 4 - 1 - 0 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - $TOOLKIT_DIR$\plugins\middleware\HCCWare\HCCWare.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\AVIX\AVIX.ENU.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\CMX\CmxArmPlugin.ENU.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\CMX\CmxTinyArmPlugin.ENU.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\MQX\MQXRtosPlugin.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\Quadros\Quadros_EWB7_Plugin.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\SafeRTOS\SafeRTOSPlugin.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\TI-RTOS\tirtosplugin.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-286-KA-CSpy.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-KA-CSpy.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\uCOS-III\uCOS-III-KA-CSpy.ewplugin - 0 - - - $EW_DIR$\common\plugins\CodeCoverage\CodeCoverage.ENU.ewplugin - 1 - - - $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin - 0 - - - $EW_DIR$\common\plugins\SymList\SymList.ENU.ewplugin - 1 - - - $EW_DIR$\common\plugins\uCProbe\uCProbePlugin.ENU.ewplugin - 0 - - - - - Spy - - ARM - - 1 - - C-SPY - 2 - - 26 - 1 + + C-SPY + 2 + + 32 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ARMSIM_ID + 2 + + 1 + 1 + 0 + + + + + + + + CADI_ID + 2 + + 0 + 1 + 0 + + + + + + + + + CMSISDAP_ID + 2 + + 4 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + GDBSERVER_ID + 2 + + 0 + 1 + 0 + + + + + + + + + + + IJET_ID + 2 + + 9 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + JLINK_ID + 2 + + 16 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + LMIFTDI_ID + 2 + + 3 + 1 + 0 + + + + + + + + + + + + + NULINK_ID + 2 + + 0 + 1 + 0 + + + + + + + PEMICRO_ID + 2 + + 3 + 1 + 0 + + + + + + + + STLINK_ID + 2 + + 8 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + THIRDPARTY_ID + 2 + + 0 + 1 + 0 + + + + + + + + TIFET_ID + 2 + + 1 + 1 + 0 + + + + + + + + + + + + + + + + + + + XDS100_ID + 2 + + 9 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + $TOOLKIT_DIR$\plugins\rtos\CMX\CmxArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\CMX\CmxTinyArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\FreeRtos\FreeRtosArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin2.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SafeRTOS\SafeRTOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9BE.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-286-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-III\uCOS-III-KA-CSpy.ewplugin + 0 + + + $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\TargetAccessServer\TargetAccessServer.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\uCProbe\uCProbePlugin.ENU.ewplugin + 0 + + + + + Spy + + ARM + 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ARMSIM_ID - 2 - - 1 - 1 - 1 - - - - - - - - ANGEL_ID - 2 - - 0 - 1 - 1 - - - - - - - - - - - - CMSISDAP_ID - 2 - - 2 - 1 - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - GDBSERVER_ID - 2 - - 0 - 1 - 1 - - - - - - - - - - - IARROM_ID - 2 - - 1 - 1 - 1 - - - - - - - - - IJET_ID - 2 - - 6 - 1 - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - JLINK_ID - 2 - - 15 - 1 - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - LMIFTDI_ID - 2 - - 2 - 1 - 1 - - - - - - - - - - MACRAIGOR_ID - 2 - - 3 - 1 - 1 - - - - - - - - - - - - - - - - - - - - - - - PEMICRO_ID - 2 - - 1 - 1 - 1 - - - - - - - - - - - - - - - - - - - RDI_ID - 2 - - 2 - 1 - 1 - - - - - - - - - - - - - - - - STLINK_ID - 2 - - 2 - 1 - 1 - - - - - - - - - - - THIRDPARTY_ID - 2 - - 0 - 1 - 1 - - - - - - - - XDS100_ID - 2 - - 4 - 1 - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - $TOOLKIT_DIR$\plugins\middleware\HCCWare\HCCWare.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\AVIX\AVIX.ENU.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\CMX\CmxArmPlugin.ENU.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\CMX\CmxTinyArmPlugin.ENU.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\MQX\MQXRtosPlugin.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\Quadros\Quadros_EWB7_Plugin.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\SafeRTOS\SafeRTOSPlugin.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\TI-RTOS\tirtosplugin.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-286-KA-CSpy.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-KA-CSpy.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\uCOS-III\uCOS-III-KA-CSpy.ewplugin - 0 - - - $EW_DIR$\common\plugins\CodeCoverage\CodeCoverage.ENU.ewplugin - 1 - - - $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin - 0 - - - $EW_DIR$\common\plugins\SymList\SymList.ENU.ewplugin - 1 - - - $EW_DIR$\common\plugins\uCProbe\uCProbePlugin.ENU.ewplugin - 0 - - - + + C-SPY + 2 + + 32 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ARMSIM_ID + 2 + + 1 + 1 + 1 + + + + + + + + CADI_ID + 2 + + 0 + 1 + 1 + + + + + + + + + CMSISDAP_ID + 2 + + 4 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + GDBSERVER_ID + 2 + + 0 + 1 + 1 + + + + + + + + + + + IJET_ID + 2 + + 9 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + JLINK_ID + 2 + + 16 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + LMIFTDI_ID + 2 + + 3 + 1 + 1 + + + + + + + + + + + + + NULINK_ID + 2 + + 0 + 1 + 1 + + + + + + + PEMICRO_ID + 2 + + 3 + 1 + 1 + + + + + + + + STLINK_ID + 2 + + 8 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + THIRDPARTY_ID + 2 + + 0 + 1 + 1 + + + + + + + + TIFET_ID + 2 + + 1 + 1 + 1 + + + + + + + + + + + + + + + + + + + XDS100_ID + 2 + + 9 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + $TOOLKIT_DIR$\plugins\rtos\CMX\CmxArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\CMX\CmxTinyArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\FreeRtos\FreeRtosArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin2.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SafeRTOS\SafeRTOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9BE.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-286-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-III\uCOS-III-KA-CSpy.ewplugin + 0 + + + $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\TargetAccessServer\TargetAccessServer.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\uCProbe\uCProbePlugin.ENU.ewplugin + 0 + + + - - diff --git a/examples/arm-cm/blinky_ek-tm4c123gxl/qv/iar/blinky-qv.ewp b/examples/arm-cm/blinky_ek-tm4c123gxl/qv/iar/blinky-qv.ewp index 9879444e..5bea57f1 100644 --- a/examples/arm-cm/blinky_ek-tm4c123gxl/qv/iar/blinky-qv.ewp +++ b/examples/arm-cm/blinky_ek-tm4c123gxl/qv/iar/blinky-qv.ewp @@ -1,3023 +1,3353 @@ - - + - 2 - - Debug - - ARM - - 1 - - General - 3 - - 24 - 1 + 3 + + Debug + + ARM + 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ICCARM - 2 - - 31 - 1 - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - AARM - 2 - - 9 - 1 - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - OBJCOPY - 0 - - 1 - 1 - 1 - - - - - - - - - CUSTOM - 3 - - - - 0 - - - - BICOMP - 0 - - - - BUILDACTION - 1 - - cmd /c "if exist $OBJ_DIR$\qstamp.o del $OBJ_DIR$\qstamp.o" - - - - - ILINK - 0 - - 17 - 1 - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - IARCHIVE - 0 - - 0 - 1 - 1 - - - - - - - BILINK - 0 - - - - Coder - 0 - - - - - Release - - ARM - - 0 - - General - 3 - - 24 - 1 + + General + 3 + + 35 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ICCARM + 2 + + 37 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + AARM + 2 + + 11 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + OBJCOPY + 0 + + 1 + 1 + 1 + + + + + + + + + CUSTOM + 3 + + + + 0 + inputOutputBased + + + + BUILDACTION + 1 + + cmd /c "if exist $OBJ_DIR$\qstamp.o del $OBJ_DIR$\qstamp.o" + + + + + ILINK + 0 + + 27 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + IARCHIVE + 0 + + 0 + 1 + 1 + + + + + + + Coder + 0 + + + + + Release + + ARM + 0 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ICCARM - 2 - - 31 - 1 - 0 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - AARM - 2 - - 9 - 1 - 0 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - OBJCOPY - 0 - - 1 - 1 - 0 - - - - - - - - - CUSTOM - 3 - - - - 0 - - - - BICOMP - 0 - - - - BUILDACTION - 1 - - cmd /c "if exist $OBJ_DIR$\qstamp.o del $OBJ_DIR$\qstamp.o" - - - - - ILINK - 0 - - 17 - 1 - 0 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - IARCHIVE - 0 - - 0 - 1 - 0 - - - - - - - BILINK - 0 - - - - Coder - 0 - - - - - Spy - - ARM - - 1 - - General - 3 - - 24 - 1 + + General + 3 + + 35 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ICCARM + 2 + + 37 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + AARM + 2 + + 11 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + OBJCOPY + 0 + + 1 + 1 + 0 + + + + + + + + + CUSTOM + 3 + + + + 0 + inputOutputBased + + + + BUILDACTION + 1 + + cmd /c "if exist $OBJ_DIR$\qstamp.o del $OBJ_DIR$\qstamp.o" + + + + + ILINK + 0 + + 27 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + IARCHIVE + 0 + + 0 + 1 + 0 + + + + + + + Coder + 0 + + + + + Spy + + ARM + 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ICCARM - 2 - - 31 - 1 - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - AARM - 2 - - 9 - 1 - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - OBJCOPY - 0 - - 1 - 1 - 1 - - - - - - - - - CUSTOM - 3 - - - - 0 - - - - BICOMP - 0 - - - - BUILDACTION - 1 - - cmd /c "if exist $OBJ_DIR$\qstamp.o del $OBJ_DIR$\qstamp.o" - - - - - ILINK - 0 - - 17 - 1 - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - IARCHIVE - 0 - - 0 - 1 - 1 - - - - - - - BILINK - 0 - - - - Coder - 0 - - - - - Application - - $PROJ_DIR$\..\..\blinky.c - - - $PROJ_DIR$\..\..\blinky.h - - - $PROJ_DIR$\..\bsp.c - - - $PROJ_DIR$\..\..\bsp.h - - - $PROJ_DIR$\..\..\main.c - - - $PROJ_DIR$\..\..\..\..\..\include\qstamp.c - - - - ek-tm4c123gxl - - $PROJ_DIR$\..\..\..\..\..\3rd_party\ek-tm4c123gxl\iar\startup_TM4C123GH6PM.s - - - $PROJ_DIR$\..\..\..\..\..\3rd_party\ek-tm4c123gxl\system_TM4C123GH6PM.c - - - $PROJ_DIR$\..\..\..\..\..\3rd_party\ek-tm4c123gxl\system_TM4C123GH6PM.h - - - $PROJ_DIR$\..\..\..\..\..\3rd_party\ek-tm4c123gxl\TM4C123GH6PM.h - - - - QP - - $PROJ_DIR$\..\..\..\..\..\src\qf\qep_hsm.c - - - $PROJ_DIR$\..\..\..\..\..\src\qf\qep_msm.c - - - $PROJ_DIR$\..\..\..\..\..\src\qf\qf_act.c - - - $PROJ_DIR$\..\..\..\..\..\src\qf\qf_actq.c - - - $PROJ_DIR$\..\..\..\..\..\src\qf\qf_defer.c - - - $PROJ_DIR$\..\..\..\..\..\src\qf\qf_dyn.c - - - $PROJ_DIR$\..\..\..\..\..\src\qf\qf_mem.c - - - $PROJ_DIR$\..\..\..\..\..\src\qf_pkg.h - - - $PROJ_DIR$\..\..\..\..\..\src\qf\qf_ps.c - - - $PROJ_DIR$\..\..\..\..\..\src\qf\qf_qact.c - - - $PROJ_DIR$\..\..\..\..\..\src\qf\qf_qeq.c - - - $PROJ_DIR$\..\..\..\..\..\src\qf\qf_qmact.c - - - $PROJ_DIR$\..\..\..\..\..\src\qf\qf_time.c - - - $PROJ_DIR$\..\..\..\..\..\src\qv\qv.c - - - $PROJ_DIR$\..\..\..\..\..\src\qs\qv_pkg.h - - - - QP_port - - $PROJ_DIR$\..\..\..\..\..\ports\arm-cm\qv\iar\qv_port.c - - - - QS - - Debug - Release - - - $PROJ_DIR$\..\..\..\..\..\src\qs\qs.c - - - $PROJ_DIR$\..\..\..\..\..\src\qs\qs_fp.c - - - $PROJ_DIR$\..\..\..\..\..\src\qs_pkg.h - - - $PROJ_DIR$\..\..\..\..\..\src\qs\qs_rx.c - - + + General + 3 + + 35 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ICCARM + 2 + + 37 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + AARM + 2 + + 11 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + OBJCOPY + 0 + + 1 + 1 + 1 + + + + + + + + + CUSTOM + 3 + + + + 0 + inputOutputBased + + + + BUILDACTION + 1 + + cmd /c "if exist $OBJ_DIR$\qstamp.o del $OBJ_DIR$\qstamp.o" + + + + + ILINK + 0 + + 27 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + IARCHIVE + 0 + + 0 + 1 + 1 + + + + + + + Coder + 0 + + + + + Application + + $PROJ_DIR$\..\..\blinky.c + + + $PROJ_DIR$\..\..\blinky.h + + + $PROJ_DIR$\..\bsp.c + + + $PROJ_DIR$\..\..\bsp.h + + + $PROJ_DIR$\..\..\main.c + + + + ek-tm4c123gxl + + $PROJ_DIR$\..\..\..\..\..\3rd_party\ek-tm4c123gxl\iar\startup_TM4C123GH6PM.s + + + $PROJ_DIR$\..\..\..\..\..\3rd_party\ek-tm4c123gxl\system_TM4C123GH6PM.c + + + $PROJ_DIR$\..\..\..\..\..\3rd_party\ek-tm4c123gxl\system_TM4C123GH6PM.h + + + $PROJ_DIR$\..\..\..\..\..\3rd_party\ek-tm4c123gxl\TM4C123GH6PM.h + + + + QP + + $PROJ_DIR$\..\..\..\..\..\src\qf\qep_hsm.c + + + $PROJ_DIR$\..\..\..\..\..\src\qf\qep_msm.c + + + $PROJ_DIR$\..\..\..\..\..\src\qf\qf_act.c + + + $PROJ_DIR$\..\..\..\..\..\src\qf\qf_actq.c + + + $PROJ_DIR$\..\..\..\..\..\src\qf\qf_defer.c + + + $PROJ_DIR$\..\..\..\..\..\src\qf\qf_dyn.c + + + $PROJ_DIR$\..\..\..\..\..\src\qf\qf_mem.c + + + $PROJ_DIR$\..\..\..\..\..\src\qf_pkg.h + + + $PROJ_DIR$\..\..\..\..\..\src\qf\qf_ps.c + + + $PROJ_DIR$\..\..\..\..\..\src\qf\qf_qact.c + + + $PROJ_DIR$\..\..\..\..\..\src\qf\qf_qeq.c + + + $PROJ_DIR$\..\..\..\..\..\src\qf\qf_qmact.c + + + $PROJ_DIR$\..\..\..\..\..\src\qf\qf_time.c + + + $PROJ_DIR$\..\..\..\..\..\src\qv\qv.c + + + $PROJ_DIR$\..\..\..\..\..\src\qs\qv_pkg.h + + + + QP_port + + $PROJ_DIR$\..\..\..\..\..\ports\arm-cm\qv\iar\qv_port.c + + + + QS + + Debug + Release + + + $PROJ_DIR$\..\..\..\..\..\src\qs\qs.c + + + $PROJ_DIR$\..\..\..\..\..\src\qs\qs_fp.c + + + $PROJ_DIR$\..\..\..\..\..\src\qs_pkg.h + + + $PROJ_DIR$\..\..\..\..\..\src\qs\qs_rx.c + + + $PROJ_DIR$\..\..\..\..\..\src\qs\qstamp.c + + - - diff --git a/examples/arm-cm/blinky_nucleo-c031c6/blinky.c b/examples/arm-cm/blinky_nucleo-c031c6/blinky.c new file mode 100644 index 00000000..43ad9df4 --- /dev/null +++ b/examples/arm-cm/blinky_nucleo-c031c6/blinky.c @@ -0,0 +1,120 @@ +//============================================================================ +// Product: "Blinky" example +// Last updated for version 7.3.0 +// Last updated on 2023-08-15 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// This program is open source software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Alternatively, this program may be distributed and modified under the +// terms of Quantum Leaps commercial licenses, which expressly supersede +// the GNU General Public License and are specifically designed for +// licensees interested in retaining the proprietary status of their code. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Contact information: +// +// +//============================================================================ +#include "qpc.h" // QP/C real-time embedded framework +#include "blinky.h" // Blinky Application interface +#include "bsp.h" // Board Support Package + +#ifdef Q_SPY +#error The Simple Blinky Application does not support Spy build configuration +#endif + +//Q_DEFINE_THIS_FILE + +//............................................................................ +// Blinky class... +typedef struct { +// protected: + QActive super; // inherit QActive + +// private: + QTimeEvt timeEvt; // private time event generator +} Blinky; +extern Blinky Blinky_inst; // the Blinky active object + +// protected: +static QState Blinky_initial(Blinky * const me, void const * const par); +static QState Blinky_off(Blinky * const me, QEvt const * const e); +static QState Blinky_on(Blinky * const me, QEvt const * const e); + +//---------------------------------------------------------------------------- +Blinky Blinky_inst; +QActive * const AO_Blinky = &Blinky_inst.super; + +//............................................................................ +void Blinky_ctor(void) { + Blinky * const me = &Blinky_inst; + QActive_ctor(&me->super, Q_STATE_CAST(&Blinky_initial)); + QTimeEvt_ctorX(&me->timeEvt, &me->super, TIMEOUT_SIG, 0U); +} + +// HSM definition ---------------------------------------------------------- +QState Blinky_initial(Blinky * const me, void const * const par) { + Q_UNUSED_PAR(par); + + // arm the time event to expire in half a second and every half second + QTimeEvt_armX(&me->timeEvt, BSP_TICKS_PER_SEC/2U, BSP_TICKS_PER_SEC/2U); + + return Q_TRAN(&Blinky_off); +} +//............................................................................ +QState Blinky_off(Blinky * const me, QEvt const * const e) { + QState status; + switch (e->sig) { + case Q_ENTRY_SIG: { + BSP_ledOff(); + status = Q_HANDLED(); + break; + } + case TIMEOUT_SIG: { + status = Q_TRAN(&Blinky_on); + break; + } + default: { + status = Q_SUPER(&QHsm_top); + break; + } + } + return status; +} +//............................................................................ +QState Blinky_on(Blinky * const me, QEvt const * const e) { + QState status; + switch (e->sig) { + case Q_ENTRY_SIG: { + BSP_ledOn(); + status = Q_HANDLED(); + break; + } + case TIMEOUT_SIG: { + status = Q_TRAN(&Blinky_off); + break; + } + default: { + status = Q_SUPER(&QHsm_top); + break; + } + } + return status; +} + diff --git a/examples/arm-cm/blinky_nucleo-c031c6/blinky.h b/examples/arm-cm/blinky_nucleo-c031c6/blinky.h new file mode 100644 index 00000000..c50ddd72 --- /dev/null +++ b/examples/arm-cm/blinky_nucleo-c031c6/blinky.h @@ -0,0 +1,48 @@ +//============================================================================ +// Product: "Blinky" example +// Last updated for version 7.2.0 +// Last updated on 2023-01-08 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// This program is open source software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Alternatively, this program may be distributed and modified under the +// terms of Quantum Leaps commercial licenses, which expressly supersede +// the GNU General Public License and are specifically designed for +// licensees interested in retaining the proprietary status of their code. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Contact information: +// +// +//============================================================================ +#ifndef BLINKY_H_ +#define BLINKY_H_ + +enum BlinkySignals { + DUMMY_SIG = Q_USER_SIG, + MAX_PUB_SIG, // the last published signal + + TIMEOUT_SIG, + MAX_SIG // the last signal +}; + +void Blinky_ctor(void); +extern QActive * const AO_Blinky; // opaque pointer + +#endif // BLINKY_H_ diff --git a/examples/arm-cm/blinky_nucleo-c031c6/bsp.h b/examples/arm-cm/blinky_nucleo-c031c6/bsp.h new file mode 100644 index 00000000..da73dbfd --- /dev/null +++ b/examples/arm-cm/blinky_nucleo-c031c6/bsp.h @@ -0,0 +1,49 @@ +//============================================================================ +// Product: Board Support Package example +// Last Updated for Version: 7.3.0 +// Date of the Last Update: 2023-08-12 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +//============================================================================ +#ifndef BSP_H_ +#define BSP_H_ + +#define BSP_TICKS_PER_SEC 100U + +void BSP_init(void); +void BSP_start(void); +void BSP_displayPaused(uint8_t paused); +void BSP_displayPhilStat(uint8_t n, char const *stat); +void BSP_terminate(int16_t result); + +void BSP_randomSeed(uint32_t seed); // random seed +uint32_t BSP_random(void); // pseudo-random generator + +void BSP_ledOn(void); +void BSP_ledOff(void); + +#endif // BSP_H_ diff --git a/examples/arm-cm/blinky_nucleo-c031c6/main.c b/examples/arm-cm/blinky_nucleo-c031c6/main.c new file mode 100644 index 00000000..185ed8dc --- /dev/null +++ b/examples/arm-cm/blinky_nucleo-c031c6/main.c @@ -0,0 +1,44 @@ +//============================================================================ +// APP example +// Last updated for version 7.3.0 +// Last updated on 2023-08-09 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. +// +// This program is open source software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Alternatively, this program may be distributed and modified under the +// terms of Quantum Leaps commercial licenses, which expressly supersede +// the GNU General Public License and are specifically designed for +// licensees interested in retaining the proprietary status of their code. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Contact information: +// +// +//============================================================================ +#include "qpc.h" // QP/C real-time embedded framework +#include "blinky.h" // Blinky Application interface +#include "bsp.h" // Board Support Package + +//............................................................................ +int main() { + QF_init(); // initialize the framework and the underlying RT kernel + BSP_init(); // initialize the BSP + BSP_start(); // start the AOs/Threads + return QF_run(); // run the QF application +} diff --git a/examples/arm-cm/blinky_nucleo-c031c6/qk/armclang/blinky-qk.sct b/examples/arm-cm/blinky_nucleo-c031c6/qk/armclang/blinky-qk.sct new file mode 100644 index 00000000..ba687922 --- /dev/null +++ b/examples/arm-cm/blinky_nucleo-c031c6/qk/armclang/blinky-qk.sct @@ -0,0 +1,23 @@ +; ************************************************************* +; *** Scatter-Loading Description File generated by uVision *** +; +; Adapted by Quantum Leaps: +; added STACK as the first section in RW_STACK +; ************************************************************* + +LR_IROM1 0x08000000 0x00008000 { ; load region size_region + ER_IROM1 0x08000000 0x00008000 { ; load address = execution address + *.o (RESET, +First) + *(InRoot$$Sections) + .ANY (+RO) + .ANY (+XO) + } + + RW_STACK 0x20000000 { ; STACK area + * (STACK, +First) + } + RW_IRAM1 +0 (0x00003000 - 2048) { + .ANY (+RW +ZI) + } +} + diff --git a/examples/arm-cm/blinky_efm32-slstk3401a/qk/armclang/blinky-qk.uvoptx b/examples/arm-cm/blinky_nucleo-c031c6/qk/armclang/blinky-qk.uvoptx similarity index 81% rename from examples/arm-cm/blinky_efm32-slstk3401a/qk/armclang/blinky-qk.uvoptx rename to examples/arm-cm/blinky_nucleo-c031c6/qk/armclang/blinky-qk.uvoptx index 7d914f56..9d278b3e 100644 --- a/examples/arm-cm/blinky_efm32-slstk3401a/qk/armclang/blinky-qk.uvoptx +++ b/examples/arm-cm/blinky_nucleo-c031c6/qk/armclang/blinky-qk.uvoptx @@ -30,8 +30,8 @@ 1 1 - 1 - 0 + 0 + 1 0 @@ -77,7 +77,7 @@ 0 1 - 3 + 18 0 1 @@ -103,7 +103,7 @@ 1 0 0 - 4 + 6 @@ -114,46 +114,58 @@ - Segger\JL2CM3.dll + STLink\ST-LINKIII-KEIL_SWO.dll 0 - DLGUARM - / + ST-LINKIII-KEIL_SWO + -U066BFF505153848667095842 -O206 -SF10000 -C0 -A0 -I0 -HNlocalhost -HP7184 -P1 -N00("ARM CoreSight SW-DP (ARM Core") -D00(0BC11477) -L00(0) -TO65554 -TC10000000 -TT10000000 -TP21 -TDS8007 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -FO7 -FD20000000 -FC1000 -FN1 -FF0STM32C0x_32.FLM -FS08000000 -FL08000 -FP0($$Device:STM32C031C6Tx$CMSIS\Flash\STM32C0x_32.FLM) 0 - JL2CM3 - -U440060969 -O207 -S2 -ZTIFSpeedSel5000 -A0 -C0 -JU1 -JI127.0.0.1 -JP0 -RST0 -N00("ARM CoreSight SW-DP") -D00(2BA01477) -L00(0) -TO18 -TC10000000 -TP21 -TDS8007 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -TB1 -TFE0 -FO7 -FD20000000 -FC8000 -FN1 -FF0GECKOP2.FLM -FS00 -FL040000 -FP0($$Device:EFM32PG1B200F256GM48$Flash\GECKOP2.FLM) + UL2CM3 + -U -O206 -S8 -C0 -P00 -N00("") -D00(00000000) -L00(0) -TO65554 -TC10000000 -TT10000000 -TP21 -TDS8007 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -FO7 -FD20000000 -FC1000 -FN1 -FF0STM32C0x_32.FLM -FS08000000 -FL08000 -FP0($$Device:STM32C031C6Tx$CMSIS\Flash\STM32C0x_32.FLM) + + + 0 + DLGUARM + (105=-1,-1,-1,-1,0) 0 ARMRTXEVENTFLAGS -L70 -Z18 -C0 -M0 -T1 - - 0 - UL2CM3 - UL2CM3(-O207 -S0 -C0 -FO7 -FN1 -FC8000 -FD20000000 -FF0GECKOP2 -FL020000 -FS00 -FP0($$Device:EFM32PG1B200F256GM48$Flash\GECKOP2.FLM) - 0 DLGTARM - (1010=-1,-1,-1,-1,0)(1007=-1,-1,-1,-1,0)(1008=-1,-1,-1,-1,0)(1009=-1,-1,-1,-1,0)(1012=-1,-1,-1,-1,0) + (1010=-1,-1,-1,-1,0)(1007=-1,-1,-1,-1,0)(1008=-1,-1,-1,-1,0)(1012=-1,-1,-1,-1,0)(1009=-1,-1,-1,-1,0) 0 ARMDBGFLAGS - - 0 - lmidk-agdi - -U0E2006F4 -O4622 -S4 -FO61 - - + + + 0 + 0 + 336 + 1 +
134226654
+ 0 + 0 + 0 + 0 + 0 + 1 + ..\bsp.c + + \\blinky_qk\../bsp.c\336 +
+
1 @@ -212,6 +224,13 @@ + + 1 + 0 + 0 + 2 + 10000000 +
@@ -224,8 +243,8 @@ 1 1 - 1 - 0 + 0 + 1 0 @@ -271,7 +290,7 @@ 0 0 - 3 + 18 0 1 @@ -297,7 +316,7 @@ 1 0 0 - 3 + 6 @@ -308,19 +327,23 @@ - Segger\JL2CM3.dll + STLink\ST-LINKIII-KEIL_SWO.dll 0 - JL2CM3 - -U -O207 -S2 -ZTIFSpeedSel5000 -A0 -C0 -JU1 -JI127.0.0.1 -JP0 -RST0 -TO18 -TC10000000 -TP21 -TDS8007 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -TB1 -TFE0 -FO7 -FD20000000 -FC8000 -FN1 -FF0GECKOP2.FLM -FS00 -FL020000 -FP0($$Device:EFM32PG1B200F256GM48$Flash\GECKOP2.FLM) + UL2CM3 + UL2CM3(-S0 -C0 -P0 ) -FN1 -FC1000 -FD20000000 -FF0STM32C0x_32 -FL08000 -FS08000000 -FP0($$Device:STM32C031C6Tx$CMSIS\Flash\STM32C0x_32.FLM) + + + 0 + ST-LINKIII-KEIL_SWO + UL2CM3(-S0 -C0 -P0 ) -FN1 -FC1000 -FD20000000 -FF0STM32C0x_32 -FL08000 -FS08000000 -FP0($$Device:STM32C031C6Tx$CMSIS\Flash\STM32C0x_32.FLM) 0 DLGUARM - ÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÈ`» -´­­ª¤ô + (105=-1,-1,-1,-1,0) 0 @@ -330,23 +353,13 @@ 0 DLGTARM - (1010=-1,-1,-1,-1,0)(1007=-1,-1,-1,-1,0)(1008=-1,-1,-1,-1,0)(1009=-1,-1,-1,-1,0)(1012=-1,-1,-1,-1,0) + (1010=-1,-1,-1,-1,0)(1007=-1,-1,-1,-1,0)(1008=-1,-1,-1,-1,0)(1009=-1,-1,-1,-1,0) 0 ARMDBGFLAGS - - 0 - lmidk-agdi - -U0E10259B -O4622 -S4 -FO61 - - - 0 - UL2CM3 - -O207 -S0 -C0 -FO7 -FN1 -FC8000 -FD20000000 -FF0GECKOP2 -FL020000 -FS00 -FP0($$Device:EFM32PG1B200F256GM48$Flash\GECKOP2.FLM) - @@ -407,6 +420,13 @@ + + 1 + 1 + 0 + 2 + 10000000 +
@@ -419,8 +439,8 @@ 1 1 - 1 - 0 + 0 + 1 0 @@ -466,7 +486,7 @@ 0 0 - 3 + 18 0 1 @@ -492,7 +512,7 @@ 1 0 0 - 3 + 6 @@ -503,39 +523,39 @@ - Segger\JL2CM3.dll + STLink\ST-LINKIII-KEIL_SWO.dll 0 - JL2CM3 - -U440060969 -O207 -S2 -ZTIFSpeedSel5000 -A0 -C0 -JU1 -JI127.0.0.1 -JP0 -RST0 -N00("ARM CoreSight SW-DP") -D00(2BA01477) -L00(0) -TO18 -TC10000000 -TP21 -TDS8007 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -TB1 -TFE0 -FO7 -FD20000000 -FC8000 -FN1 -FF0GECKOP2.FLM -FS00 -FL020000 -FP0($$Device:EFM32PG1B200F256GM48$Flash\GECKOP2.FLM) + UL2CM3 + UL2CM3(-S0 -C0 -P0 ) -FN1 -FC1000 -FD20000000 -FF0STM32C0x_32 -FL08000 -FS08000000 -FP0($$Device:STM32C031C6Tx$CMSIS\Flash\STM32C0x_32.FLM) + + + 0 + ST-LINKIII-KEIL_SWO + -U-O206 -O206 -SF10000 -C0 -A0 -I0 -HNlocalhost -HP7184 -P1 -N00("ARM CoreSight SW-DP (ARM Core") -D00(0BC11477) -L00(0) -TO131090 -TC10000000 -TT10000000 -TP21 -TDS8007 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -FO7 -FD20000000 -FC1000 -FN1 -FF0STM32C0x_32.FLM -FS08000000 -FL08000 -FP0($$Device:STM32C031C6Tx$CMSIS\Flash\STM32C0x_32.FLM) + + + 0 + DLGUARM + (105=-1,-1,-1,-1,0) 0 ARMRTXEVENTFLAGS -L70 -Z18 -C0 -M0 -T1 - - 0 - UL2CM3 - UL2CM3(-O207 -S0 -C0 -FO7 -FN1 -FC8000 -FD20000000 -FF0GECKOP2 -FL020000 -FS00 -FP0($$Device:EFM32PG1B200F256GM48$Flash\GECKOP2.FLM) - 0 DLGTARM - (1010=-1,-1,-1,-1,0)(1007=-1,-1,-1,-1,0)(1008=-1,-1,-1,-1,0)(1009=-1,-1,-1,-1,0)(1012=-1,-1,-1,-1,0) + (1010=-1,-1,-1,-1,0)(1007=-1,-1,-1,-1,0)(1008=-1,-1,-1,-1,0)(1012=-1,-1,-1,-1,0)(1009=-1,-1,-1,-1,0) 0 ARMDBGFLAGS - - 0 - lmidk-agdi - -U0E2006F4 -O4622 -S4 -FO61 - @@ -596,11 +616,28 @@ + + + System Viewer\GPIOA + 35904 + + + System Viewer\USART2 + 35905 + + + + 1 + 0 + 0 + 2 + 10000000 + - Applicatioin + Source Code 1 0 0 @@ -620,30 +657,18 @@ 1 2 - 1 + 5 0 0 0 - ..\..\blinky.c - blinky.c + ..\..\bsp.h + bsp.h 0 0 1 3 - 1 - 0 - 0 - 0 - ..\..\main.c - main.c - 0 - 0 - - - 1 - 4 5 0 0 @@ -653,6 +678,18 @@ 0 0 + + 1 + 4 + 1 + 0 + 0 + 0 + ..\..\main.c + main.c + 0 + 0 + 1 5 @@ -660,15 +697,15 @@ 0 0 0 - ..\..\..\..\..\include\qstamp.c - qstamp.c + ..\..\blinky.c + blinky.c 0 0 - efm32pg1b + nucleo-c031c6 1 0 0 @@ -676,24 +713,24 @@ 2 6 - 2 + 5 0 0 0 - ..\..\..\..\..\3rd_party\efm32pg1b\arm\startup_efm32pg1b.s - startup_efm32pg1b.s + ..\..\..\..\..\3rd_party\nucleo-c031c6\stm32c0xx.h + stm32c0xx.h 0 0 2 7 - 1 + 5 0 0 0 - ..\..\..\..\..\3rd_party\efm32pg1b\em_cmu.c - em_cmu.c + ..\..\..\..\..\3rd_party\nucleo-c031c6\stm32c031xx.h + stm32c031xx.h 0 0 @@ -704,68 +741,20 @@ 0 0 0 - ..\..\..\..\..\3rd_party\efm32pg1b\em_emu.c - em_emu.c + ..\..\..\..\..\3rd_party\nucleo-c031c6\system_stm32c0xx.c + system_stm32c0xx.c 0 0 2 9 - 1 + 2 0 0 0 - ..\..\..\..\..\3rd_party\efm32pg1b\em_gpio.c - em_gpio.c - 0 - 0 - - - 2 - 10 - 1 - 0 - 0 - 0 - ..\..\..\..\..\3rd_party\efm32pg1b\em_int.c - em_int.c - 0 - 0 - - - 2 - 11 - 1 - 0 - 0 - 0 - ..\..\..\..\..\3rd_party\efm32pg1b\em_rtcc.c - em_rtcc.c - 0 - 0 - - - 2 - 12 - 1 - 0 - 0 - 0 - ..\..\..\..\..\3rd_party\efm32pg1b\em_system.c - em_system.c - 0 - 0 - - - 2 - 13 - 1 - 0 - 0 - 0 - ..\..\..\..\..\3rd_party\efm32pg1b\system_efm32pg1b.c - system_efm32pg1b.c + ..\..\..\..\..\3rd_party\nucleo-c031c6\arm\startup_stm32c031xx.s + startup_stm32c031xx.s 0 0 @@ -779,7 +768,7 @@ 0 3 - 14 + 10 1 0 0 @@ -791,7 +780,7 @@ 3 - 15 + 11 1 0 0 @@ -803,7 +792,7 @@ 3 - 16 + 12 1 0 0 @@ -815,7 +804,7 @@ 3 - 17 + 13 1 0 0 @@ -827,7 +816,7 @@ 3 - 18 + 14 1 0 0 @@ -839,7 +828,7 @@ 3 - 19 + 15 1 0 0 @@ -851,7 +840,7 @@ 3 - 20 + 16 1 0 0 @@ -863,7 +852,7 @@ 3 - 21 + 17 1 0 0 @@ -875,7 +864,7 @@ 3 - 22 + 18 1 0 0 @@ -887,7 +876,7 @@ 3 - 23 + 19 1 0 0 @@ -899,7 +888,7 @@ 3 - 24 + 20 1 0 0 @@ -911,7 +900,7 @@ 3 - 25 + 21 1 0 0 @@ -923,7 +912,7 @@ 3 - 26 + 22 1 0 0 @@ -943,7 +932,43 @@ 0 4 - 27 + 23 + 5 + 0 + 0 + 0 + ..\..\..\..\..\ports\arm-cm\qk\armclang\qep_port.h + qep_port.h + 0 + 0 + + + 4 + 24 + 5 + 0 + 0 + 0 + ..\..\..\..\..\ports\arm-cm\qk\armclang\qf_port.h + qf_port.h + 0 + 0 + + + 4 + 25 + 5 + 0 + 0 + 0 + ..\..\..\..\..\ports\arm-cm\qk\armclang\qs_port.h + qs_port.h + 0 + 0 + + + 4 + 26 1 0 0 @@ -953,6 +978,18 @@ 0 0 + + 4 + 27 + 5 + 0 + 0 + 0 + ..\..\..\..\..\ports\arm-cm\qk\armclang\qk_port.h + qk_port.h + 0 + 0 + @@ -1009,6 +1046,18 @@ 0 0 + + 5 + 32 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qs\qstamp.c + qstamp.c + 0 + 0 + diff --git a/examples/arm-cm/blinky_efm32-slstk3401a/qk/armclang/blinky-qk.uvprojx b/examples/arm-cm/blinky_nucleo-c031c6/qk/armclang/blinky-qk.uvprojx similarity index 85% rename from examples/arm-cm/blinky_efm32-slstk3401a/qk/armclang/blinky-qk.uvprojx rename to examples/arm-cm/blinky_nucleo-c031c6/qk/armclang/blinky-qk.uvprojx index 444fcd8c..13db2cc9 100644 --- a/examples/arm-cm/blinky_efm32-slstk3401a/qk/armclang/blinky-qk.uvprojx +++ b/examples/arm-cm/blinky_nucleo-c031c6/qk/armclang/blinky-qk.uvprojx @@ -14,16 +14,16 @@ 1 - EFM32PG1B200F256GM48 - Silicon Labs - SiliconLabs.GeckoPlatform_EFM32PG1B_DFP.4.0.0 - https://www.silabs.com/documents/public/cmsis-packs/ - IRAM(0x20000000,0x00008000) IROM(0x00000000,0x00020000) CPUTYPE("Cortex-M4") FPU2 CLOCK(12000000) ELITTLE + STM32C031C6Tx + STMicroelectronics + Keil.STM32C0xx_DFP.1.0.0 + https://www.keil.com/pack/ + IRAM(0x20000000,0x00003000) IROM(0x08000000,0x00008000) CPUTYPE("Cortex-M0+") CLOCK(12000000) ELITTLE - UL2CM3(-S0 -C0 -P0 -FD20000000 -FC8000 -FN1 -FF0GECKOP2 -FS00 -FL020000 -FP0($$Device:EFM32PG1B200F256GM48$Flash\GECKOP2.FLM)) + UL2CM3(-S0 -C0 -P0 -FD20000000 -FC1000 -FN1 -FF0STM32C0x_32 -FS08000000 -FL08000 -FP0($$Device:STM32C031C6Tx$CMSIS\Flash\STM32C0x_32.FLM)) 0 - $$Device:EFM32PG1B200F256GM48$Device\EFM32PG1B\Include\em_device.h + $$Device:STM32C031C6Tx$Drivers\CMSIS\Device\ST\STM32C0xx\Include\stm32c0xx.h @@ -33,7 +33,7 @@ - $$Device:EFM32PG1B200F256GM48$SVD\EFM32PG1B\EFM32PG1B200F256GM48.svd + $$Device:STM32C031C6Tx$CMSIS\SVD\STM32C031.svd 0 0 @@ -89,7 +89,7 @@ 0 0 - 1 + 0 @@ -110,13 +110,13 @@ SARMCM3.DLL - -MPU - DCM.DLL - -pCM4 + -REMAP-MPU + DARMCM1.DLL + -pCM0+ SARMCM3.DLL - -MPU - TCM.DLL - -pCM4 + -MPU + TARMCM1.DLL + -pCM0+ @@ -174,7 +174,7 @@ 1 0 0 - "Cortex-M4" + "Cortex-M0+" 0 0 @@ -183,7 +183,7 @@ 1 0 0 - 2 + 0 0 0 0 @@ -246,12 +246,12 @@ 0 0x20000000 - 0x8000 + 0x3000 1 - 0x0 - 0x20000 + 0x8000000 + 0x8000 0 @@ -275,8 +275,8 @@ 1 - 0x0 - 0x20000 + 0x8000000 + 0x8000 1 @@ -301,7 +301,7 @@ 0 0x20000000 - 0x8000 + 0x3000 0 @@ -313,7 +313,7 @@ 0 - 7 + 1 0 0 1 @@ -325,7 +325,7 @@ 3 0 1 - 1 + 0 0 0 3 @@ -337,9 +337,9 @@ 0 - EFM32PG1B200F256GM48=1 __FPU_PRESENT + - ..\..;..\..\..\..\..\include;..\..\..\..\..\ports\arm-cm\qk\armclang;..\..\..\..\..\3rd_party\CMSIS\Include;..\..\..\..\..\3rd_party\efm32pg1b + ..\..;..\..\..\..\..\include;..\..\..\..\..\ports\arm-cm\qk\armclang;..\..\..\..\..\3rd_party\CMSIS\Include;..\..\..\..\..\3rd_party\nucleo-c031c6 @@ -361,7 +361,7 @@ - 1 + 0 0 0 0 @@ -370,7 +370,7 @@ 0x00000000 0x20000000 - + .\blinky-qk.sct --entry Reset_Handler @@ -381,7 +381,7 @@ - Applicatioin + Source Code bsp.c @@ -389,14 +389,9 @@ ..\bsp.c - blinky.c - 1 - ..\..\blinky.c - - - main.c - 1 - ..\..\main.c + bsp.h + 5 + ..\..\bsp.h blinky.h @@ -404,54 +399,39 @@ ..\..\blinky.h - qstamp.c + main.c 1 - ..\..\..\..\..\include\qstamp.c + ..\..\main.c + + + blinky.c + 1 + ..\..\blinky.c - efm32pg1b + nucleo-c031c6 - startup_efm32pg1b.s + stm32c0xx.h + 5 + ..\..\..\..\..\3rd_party\nucleo-c031c6\stm32c0xx.h + + + stm32c031xx.h + 5 + ..\..\..\..\..\3rd_party\nucleo-c031c6\stm32c031xx.h + + + system_stm32c0xx.c + 1 + ..\..\..\..\..\3rd_party\nucleo-c031c6\system_stm32c0xx.c + + + startup_stm32c031xx.s 2 - ..\..\..\..\..\3rd_party\efm32pg1b\arm\startup_efm32pg1b.s - - - em_cmu.c - 1 - ..\..\..\..\..\3rd_party\efm32pg1b\em_cmu.c - - - em_emu.c - 1 - ..\..\..\..\..\3rd_party\efm32pg1b\em_emu.c - - - em_gpio.c - 1 - ..\..\..\..\..\3rd_party\efm32pg1b\em_gpio.c - - - em_int.c - 1 - ..\..\..\..\..\3rd_party\efm32pg1b\em_int.c - - - em_rtcc.c - 1 - ..\..\..\..\..\3rd_party\efm32pg1b\em_rtcc.c - - - em_system.c - 1 - ..\..\..\..\..\3rd_party\efm32pg1b\em_system.c - - - system_efm32pg1b.c - 1 - ..\..\..\..\..\3rd_party\efm32pg1b\system_efm32pg1b.c + ..\..\..\..\..\3rd_party\nucleo-c031c6\arm\startup_stm32c031xx.s @@ -528,11 +508,31 @@ QP_port + + qep_port.h + 5 + ..\..\..\..\..\ports\arm-cm\qk\armclang\qep_port.h + + + qf_port.h + 5 + ..\..\..\..\..\ports\arm-cm\qk\armclang\qf_port.h + + + qs_port.h + 5 + ..\..\..\..\..\ports\arm-cm\qk\armclang\qs_port.h + qk_port.c 1 ..\..\..\..\..\ports\arm-cm\qk\armclang\qk_port.c + + qk_port.h + 5 + ..\..\..\..\..\ports\arm-cm\qk\armclang\qk_port.h + @@ -627,6 +627,11 @@ 1 ..\..\..\..\..\src\qs\qs_rx.c + + qstamp.c + 1 + ..\..\..\..\..\src\qs\qstamp.c + @@ -635,20 +640,20 @@ blinky-rel 0x4 ARM-ADS - 6130001::V6.13.1::.\ARMCLANG + 6160000::V6.16::ARMCLANG 1 - EFM32PG1B200F256GM48 - Silicon Labs - SiliconLabs.GeckoPlatform_EFM32PG1B_DFP.4.0.0 - https://www.silabs.com/documents/public/cmsis-packs/ - IRAM(0x20000000,0x00008000) IROM(0x00000000,0x00020000) CPUTYPE("Cortex-M4") FPU2 CLOCK(12000000) ELITTLE + STM32C031C6Tx + STMicroelectronics + Keil.STM32C0xx_DFP.1.0.0 + https://www.keil.com/pack/ + IRAM(0x20000000,0x00003000) IROM(0x08000000,0x00008000) CPUTYPE("Cortex-M0+") CLOCK(12000000) ELITTLE - UL2CM3(-S0 -C0 -P0 -FD20000000 -FC8000 -FN1 -FF0GECKOP2 -FS00 -FL020000 -FP0($$Device:EFM32PG1B200F256GM48$Flash\GECKOP2.FLM)) + UL2CM3(-S0 -C0 -P0 -FD20000000 -FC1000 -FN1 -FF0STM32C0x_32 -FS08000000 -FL08000 -FP0($$Device:STM32C031C6Tx$CMSIS\Flash\STM32C0x_32.FLM)) 0 - $$Device:EFM32PG1B200F256GM48$Device\EFM32PG1B\Include\em_device.h + $$Device:STM32C031C6Tx$Drivers\CMSIS\Device\ST\STM32C0xx\Include\stm32c0xx.h @@ -658,7 +663,7 @@ - $$Device:EFM32PG1B200F256GM48$SVD\EFM32PG1B\EFM32PG1B200F256GM48.svd + $$Device:STM32C031C6Tx$CMSIS\SVD\STM32C031.svd 0 0 @@ -714,7 +719,7 @@ 0 0 - 1 + 0 @@ -735,13 +740,13 @@ SARMCM3.DLL - -MPU - DCM.DLL - -pCM4 + -REMAP-MPU + DARMCM1.DLL + -pCM0+ SARMCM3.DLL - -MPU - TCM.DLL - -pCM4 + -MPU + TARMCM1.DLL + -pCM0+ @@ -759,11 +764,11 @@ 0 1 1 - 4096 + 4097 1 BIN\UL2CM3.DLL - "" () + @@ -799,7 +804,7 @@ 1 0 0 - "Cortex-M4" + "Cortex-M0+" 0 0 @@ -808,7 +813,7 @@ 1 0 0 - 2 + 0 0 0 0 @@ -871,12 +876,12 @@ 0 0x20000000 - 0x8000 + 0x3000 1 - 0x0 - 0x20000 + 0x8000000 + 0x8000 0 @@ -900,8 +905,8 @@ 1 - 0x0 - 0x20000 + 0x8000000 + 0x8000 1 @@ -926,7 +931,7 @@ 0 0x20000000 - 0x8000 + 0x3000 0 @@ -938,7 +943,7 @@ 0 - 7 + 6 0 0 1 @@ -950,21 +955,21 @@ 3 0 1 - 1 + 0 0 0 3 3 - 1 - 1 + 0 + 0 0 0 0 - NDEBUG EFM32PG1B200F256GM48=1 __FPU_PRESENT + NDEBUG - ..\..;..\..\..\..\..\include;..\..\..\..\..\ports\arm-cm\qk\armclang;..\..\..\..\..\3rd_party\CMSIS\Include;..\..\..\..\..\3rd_party\efm32pg1b + ..\..;..\..\..\..\..\include;..\..\..\..\..\ports\arm-cm\qk\armclang;..\..\..\..\..\3rd_party\CMSIS\Include;..\..\..\..\..\3rd_party\nucleo-c031c6 @@ -986,7 +991,7 @@ - 1 + 0 0 0 0 @@ -995,7 +1000,7 @@ 0x00000000 0x20000000 - blinky-qk.sct + .\blinky-qk.sct --entry Reset_Handler @@ -1006,7 +1011,7 @@ - Applicatioin + Source Code bsp.c @@ -1014,14 +1019,9 @@ ..\bsp.c - blinky.c - 1 - ..\..\blinky.c - - - main.c - 1 - ..\..\main.c + bsp.h + 5 + ..\..\bsp.h blinky.h @@ -1029,54 +1029,39 @@ ..\..\blinky.h - qstamp.c + main.c 1 - ..\..\..\..\..\include\qstamp.c + ..\..\main.c + + + blinky.c + 1 + ..\..\blinky.c - efm32pg1b + nucleo-c031c6 - startup_efm32pg1b.s + stm32c0xx.h + 5 + ..\..\..\..\..\3rd_party\nucleo-c031c6\stm32c0xx.h + + + stm32c031xx.h + 5 + ..\..\..\..\..\3rd_party\nucleo-c031c6\stm32c031xx.h + + + system_stm32c0xx.c + 1 + ..\..\..\..\..\3rd_party\nucleo-c031c6\system_stm32c0xx.c + + + startup_stm32c031xx.s 2 - ..\..\..\..\..\3rd_party\efm32pg1b\arm\startup_efm32pg1b.s - - - em_cmu.c - 1 - ..\..\..\..\..\3rd_party\efm32pg1b\em_cmu.c - - - em_emu.c - 1 - ..\..\..\..\..\3rd_party\efm32pg1b\em_emu.c - - - em_gpio.c - 1 - ..\..\..\..\..\3rd_party\efm32pg1b\em_gpio.c - - - em_int.c - 1 - ..\..\..\..\..\3rd_party\efm32pg1b\em_int.c - - - em_rtcc.c - 1 - ..\..\..\..\..\3rd_party\efm32pg1b\em_rtcc.c - - - em_system.c - 1 - ..\..\..\..\..\3rd_party\efm32pg1b\em_system.c - - - system_efm32pg1b.c - 1 - ..\..\..\..\..\3rd_party\efm32pg1b\system_efm32pg1b.c + ..\..\..\..\..\3rd_party\nucleo-c031c6\arm\startup_stm32c031xx.s @@ -1153,11 +1138,31 @@ QP_port + + qep_port.h + 5 + ..\..\..\..\..\ports\arm-cm\qk\armclang\qep_port.h + + + qf_port.h + 5 + ..\..\..\..\..\ports\arm-cm\qk\armclang\qf_port.h + + + qs_port.h + 5 + ..\..\..\..\..\ports\arm-cm\qk\armclang\qs_port.h + qk_port.c 1 ..\..\..\..\..\ports\arm-cm\qk\armclang\qk_port.c + + qk_port.h + 5 + ..\..\..\..\..\ports\arm-cm\qk\armclang\qk_port.h + @@ -1252,6 +1257,11 @@ 1 ..\..\..\..\..\src\qs\qs_rx.c + + qstamp.c + 1 + ..\..\..\..\..\src\qs\qstamp.c + @@ -1260,20 +1270,20 @@ blinky-spy 0x4 ARM-ADS - 6130001::V6.13.1::.\ARMCLANG + 6160000::V6.16::ARMCLANG 1 - EFM32PG1B200F256GM48 - Silicon Labs - SiliconLabs.GeckoPlatform_EFM32PG1B_DFP.4.0.0 - https://www.silabs.com/documents/public/cmsis-packs/ - IRAM(0x20000000,0x00008000) IROM(0x00000000,0x00020000) CPUTYPE("Cortex-M4") FPU2 CLOCK(12000000) ELITTLE + STM32C031C6Tx + STMicroelectronics + Keil.STM32C0xx_DFP.1.0.0 + https://www.keil.com/pack/ + IRAM(0x20000000,0x00003000) IROM(0x08000000,0x00008000) CPUTYPE("Cortex-M0+") CLOCK(12000000) ELITTLE - UL2CM3(-S0 -C0 -P0 -FD20000000 -FC8000 -FN1 -FF0GECKOP2 -FS00 -FL020000 -FP0($$Device:EFM32PG1B200F256GM48$Flash\GECKOP2.FLM)) + UL2CM3(-S0 -C0 -P0 -FD20000000 -FC1000 -FN1 -FF0STM32C0x_32 -FS08000000 -FL08000 -FP0($$Device:STM32C031C6Tx$CMSIS\Flash\STM32C0x_32.FLM)) 0 - $$Device:EFM32PG1B200F256GM48$Device\EFM32PG1B\Include\em_device.h + $$Device:STM32C031C6Tx$Drivers\CMSIS\Device\ST\STM32C0xx\Include\stm32c0xx.h @@ -1283,7 +1293,7 @@ - $$Device:EFM32PG1B200F256GM48$SVD\EFM32PG1B\EFM32PG1B200F256GM48.svd + $$Device:STM32C031C6Tx$CMSIS\SVD\STM32C031.svd 0 0 @@ -1339,7 +1349,7 @@ 0 0 - 1 + 0 @@ -1360,13 +1370,13 @@ SARMCM3.DLL - -MPU - DCM.DLL - -pCM4 + -REMAP-MPU + DARMCM1.DLL + -pCM0+ SARMCM3.DLL - -MPU - TCM.DLL - -pCM4 + -MPU + TARMCM1.DLL + -pCM0+ @@ -1388,7 +1398,7 @@ 1 BIN\UL2CM3.DLL - "" () + @@ -1424,7 +1434,7 @@ 1 0 0 - "Cortex-M4" + "Cortex-M0+" 0 0 @@ -1433,7 +1443,7 @@ 1 0 0 - 2 + 0 0 0 0 @@ -1496,12 +1506,12 @@ 0 0x20000000 - 0x8000 + 0x3000 1 - 0x0 - 0x20000 + 0x8000000 + 0x8000 0 @@ -1525,8 +1535,8 @@ 1 - 0x0 - 0x20000 + 0x8000000 + 0x8000 1 @@ -1551,7 +1561,7 @@ 0 0x20000000 - 0x8000 + 0x3000 0 @@ -1563,7 +1573,7 @@ 0 - 7 + 2 0 0 1 @@ -1575,7 +1585,7 @@ 3 0 1 - 1 + 0 0 0 3 @@ -1587,9 +1597,9 @@ 0 - Q_SPY EFM32PG1B200F256GM48=1 __FPU_PRESENT + Q_SPY - ..\..;..\..\..\..\..\include;..\..\..\..\..\ports\arm-cm\qk\armclang;..\..\..\..\..\3rd_party\CMSIS\Include;..\..\..\..\..\3rd_party\efm32pg1b + ..\..;..\..\..\..\..\include;..\..\..\..\..\ports\arm-cm\qk\armclang;..\..\..\..\..\3rd_party\CMSIS\Include;..\..\..\..\..\3rd_party\nucleo-c031c6 @@ -1611,7 +1621,7 @@ - 1 + 0 0 0 0 @@ -1620,7 +1630,7 @@ 0x00000000 0x20000000 - + .\blinky-qk.sct --entry Reset_Handler @@ -1631,7 +1641,7 @@ - Applicatioin + Source Code bsp.c @@ -1639,14 +1649,9 @@ ..\bsp.c - blinky.c - 1 - ..\..\blinky.c - - - main.c - 1 - ..\..\main.c + bsp.h + 5 + ..\..\bsp.h blinky.h @@ -1654,54 +1659,39 @@ ..\..\blinky.h - qstamp.c + main.c 1 - ..\..\..\..\..\include\qstamp.c + ..\..\main.c + + + blinky.c + 1 + ..\..\blinky.c - efm32pg1b + nucleo-c031c6 - startup_efm32pg1b.s + stm32c0xx.h + 5 + ..\..\..\..\..\3rd_party\nucleo-c031c6\stm32c0xx.h + + + stm32c031xx.h + 5 + ..\..\..\..\..\3rd_party\nucleo-c031c6\stm32c031xx.h + + + system_stm32c0xx.c + 1 + ..\..\..\..\..\3rd_party\nucleo-c031c6\system_stm32c0xx.c + + + startup_stm32c031xx.s 2 - ..\..\..\..\..\3rd_party\efm32pg1b\arm\startup_efm32pg1b.s - - - em_cmu.c - 1 - ..\..\..\..\..\3rd_party\efm32pg1b\em_cmu.c - - - em_emu.c - 1 - ..\..\..\..\..\3rd_party\efm32pg1b\em_emu.c - - - em_gpio.c - 1 - ..\..\..\..\..\3rd_party\efm32pg1b\em_gpio.c - - - em_int.c - 1 - ..\..\..\..\..\3rd_party\efm32pg1b\em_int.c - - - em_rtcc.c - 1 - ..\..\..\..\..\3rd_party\efm32pg1b\em_rtcc.c - - - em_system.c - 1 - ..\..\..\..\..\3rd_party\efm32pg1b\em_system.c - - - system_efm32pg1b.c - 1 - ..\..\..\..\..\3rd_party\efm32pg1b\system_efm32pg1b.c + ..\..\..\..\..\3rd_party\nucleo-c031c6\arm\startup_stm32c031xx.s @@ -1778,11 +1768,31 @@ QP_port + + qep_port.h + 5 + ..\..\..\..\..\ports\arm-cm\qk\armclang\qep_port.h + + + qf_port.h + 5 + ..\..\..\..\..\ports\arm-cm\qk\armclang\qf_port.h + + + qs_port.h + 5 + ..\..\..\..\..\ports\arm-cm\qk\armclang\qs_port.h + qk_port.c 1 ..\..\..\..\..\ports\arm-cm\qk\armclang\qk_port.c + + qk_port.h + 5 + ..\..\..\..\..\ports\arm-cm\qk\armclang\qk_port.h + @@ -1808,6 +1818,11 @@ 1 ..\..\..\..\..\src\qs\qs_rx.c + + qstamp.c + 1 + ..\..\..\..\..\src\qs\qstamp.c + @@ -1820,13 +1835,4 @@ - - - - blinky-qk - 1 - - - - diff --git a/examples/arm-cm/blinky_nucleo-c031c6/qk/bsp.c b/examples/arm-cm/blinky_nucleo-c031c6/qk/bsp.c new file mode 100644 index 00000000..b4b44593 --- /dev/null +++ b/examples/arm-cm/blinky_nucleo-c031c6/qk/bsp.c @@ -0,0 +1,243 @@ +//============================================================================ +// Product: Blinky example, NUCLEO-C031C6 board, QK kernel +// Last updated for version 7.3.0 +// Last updated on 2023-08-15 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. +// +// This program is open source software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Alternatively, this program may be distributed and modified under the +// terms of Quantum Leaps commercial licenses, which expressly supersede +// the GNU General Public License and are specifically designed for +// licensees interested in retaining the proprietary status of their code. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Contact information: +// +// +//============================================================================ +#include "qpc.h" // QP/C real-time embedded framework +#include "blinky.h" // Blinky Application interface +#include "bsp.h" // Board Support Package + +#include "stm32c0xx.h" // CMSIS-compliant header file for the MCU used +// add other drivers if necessary... + +//Q_DEFINE_THIS_FILE // define the name of this file for assertions + +// Local-scope defines ----------------------------------------------------- +// LED pins available on the board (just one user LED LD4--Green on PA.5) +#define LD4_PIN 5U + +// Button pins available on the board (just one user Button B1 on PC.13) +#define B1_PIN 13U + +#ifdef Q_SPY +#error The Simple Blinky Application does not support Spy build configuration +#endif + +//============================================================================ +// Error handler and ISRs... + +Q_NORETURN Q_onError(char const *module, int_t const id) { + // NOTE: this implementation of the assertion handler is intended only + // for debugging and MUST be changed for deployment of the application + // (assuming that you ship your production code with assertions enabled). + Q_UNUSED_PAR(module); + Q_UNUSED_PAR(id); + QS_ASSERTION(module, id, (uint32_t)10000U); + +#ifndef NDEBUG + // light up the user LED + GPIOA->BSRR = (1U << LD4_PIN); // turn LED on + // for debugging, hang on in an endless loop... + for (;;) { + } +#endif + + NVIC_SystemReset(); +} +//............................................................................ +void assert_failed(char const * const module, int_t const id); // prototype +void assert_failed(char const * const module, int_t const id) { + Q_onError(module, id); +} + +//............................................................................ +void SysTick_Handler(void); // prototype +void SysTick_Handler(void) { + QK_ISR_ENTRY(); // inform QK about entering an ISR + + QTIMEEVT_TICK_X(0U, &l_SysTick_Handler); // time events at rate 0 + + QK_ISR_EXIT(); // inform QK about exiting an ISR +} + +//============================================================================ +// BSP functions... + +void BSP_init(void) { + // Configure the MPU to prevent NULL-pointer dereferencing ... + MPU->RBAR = 0x0U // base address (NULL) + | MPU_RBAR_VALID_Msk // valid region + | (MPU_RBAR_REGION_Msk & 7U); // region #7 + MPU->RASR = (7U << MPU_RASR_SIZE_Pos) // 2^(7+1) region + | (0x0U << MPU_RASR_AP_Pos) // no-access region + | MPU_RASR_ENABLE_Msk; // region enable + MPU->CTRL = MPU_CTRL_PRIVDEFENA_Msk // enable background region + | MPU_CTRL_ENABLE_Msk; // enable the MPU + __ISB(); + __DSB(); + + // NOTE: SystemInit() has been already called from the startup code + // but SystemCoreClock needs to be updated + SystemCoreClockUpdate(); + + // enable GPIOA clock port for the LED LD4 + RCC->IOPENR |= (1U << 0U); + + // set all used GPIOA pins as push-pull output, no pull-up, pull-down + GPIOA->MODER &= ~(3U << 2U*LD4_PIN); + GPIOA->MODER |= (1U << 2U*LD4_PIN); + GPIOA->OTYPER &= ~(1U << LD4_PIN); + GPIOA->OSPEEDR &= ~(3U << 2U*LD4_PIN); + GPIOA->OSPEEDR |= (1U << 2U*LD4_PIN); + GPIOA->PUPDR &= ~(3U << 2U*LD4_PIN); + + // enable GPIOC clock port for the Button B1 + RCC->IOPENR |= (1U << 2U); + + // configure Button B1 pin on GPIOC as input, no pull-up, pull-down + GPIOC->MODER &= ~(3U << 2U*B1_PIN); + GPIOC->PUPDR &= ~(3U << 2U*B1_PIN); +} +//............................................................................ +void BSP_start(void) { + // initialize event pools + static QF_MPOOL_EL(QEvt) smlPoolSto[10]; + QF_poolInit(smlPoolSto, sizeof(smlPoolSto), sizeof(smlPoolSto[0])); + + // initialize publish-subscribe + static QSubscrList subscrSto[MAX_PUB_SIG]; + QActive_psInit(subscrSto, Q_DIM(subscrSto)); + + // instantiate and start AOs/threads... + + static QEvt const *blinkyQueueSto[10]; + Blinky_ctor(); + QACTIVE_START(AO_Blinky, + 1U, // QP prio. of the AO + blinkyQueueSto, // event queue storage + Q_DIM(blinkyQueueSto), // queue length [events] + (void *)0, 0U, // no stack storage + (void *)0); // no initialization param +} +//............................................................................ +void BSP_ledOn() { + GPIOA->BSRR = (1U << LD4_PIN); // turn LED on +} +//............................................................................ +void BSP_ledOff() { + GPIOA->BSRR = (1U << (LD4_PIN + 16U)); // turn LED off +} +//............................................................................ +void BSP_terminate(int16_t result) { + Q_UNUSED_PAR(result); +} + +//============================================================================ +// QF callbacks... +void QF_onStartup(void) { + // set up the SysTick timer to fire at BSP_TICKS_PER_SEC rate + SysTick_Config(SystemCoreClock / BSP_TICKS_PER_SEC); + + // assign all priority bits for preemption-prio. and none to sub-prio. + NVIC_SetPriorityGrouping(0U); + + // set priorities of ALL ISRs used in the system, see NOTE1 + NVIC_SetPriority(USART2_IRQn, 0); // kernel UNAWARE interrupt + NVIC_SetPriority(EXTI0_1_IRQn, QF_AWARE_ISR_CMSIS_PRI + 0U); + NVIC_SetPriority(SysTick_IRQn, QF_AWARE_ISR_CMSIS_PRI + 1U); + // ... + + // enable IRQs... + NVIC_EnableIRQ(EXTI0_1_IRQn); + +#ifdef Q_SPY + NVIC_EnableIRQ(USART2_IRQn); // UART2 interrupt used for QS-RX +#endif +} +//............................................................................ +void QF_onCleanup(void) { +} +//............................................................................ +void QK_onIdle(void) { + // toggle an LED on and then off (not enough LEDs, see NOTE02) + //QF_INT_DISABLE(); + //QF_MEM_SYS(); + //GPIOA->BSRR = (1U << LD4_PIN); // turn LED[n] on + //GPIOA->BSRR = (1U << (LD4_PIN + 16U)); // turn LED[n] off + //QF_MEM_APP(); + //QF_INT_ENABLE(); + +#ifdef Q_SPY +#elif defined NDEBUG + // Put the CPU and peripherals to the low-power mode. + // you might need to customize the clock management for your application, + // see the datasheet for your particular Cortex-M MCU. + // + // !!!CAUTION!!! + // The WFI instruction stops the CPU clock, which unfortunately disables + // the JTAG port, so the ST-Link debugger can no longer connect to the + // board. For that reason, the call to __WFI() has to be used with CAUTION. + // + // NOTE: If you find your board "frozen" like this, strap BOOT0 to VDD and + // reset the board, then connect with ST-Link Utilities and erase the part. + // The trick with BOOT(0) is it gets the part to run the System Loader + // instead of your broken code. When done disconnect BOOT0, and start over. + // + //__WFI(); // Wait-For-Interrupt +#endif +} + +//============================================================================ +// NOTE1: +// The QF_AWARE_ISR_CMSIS_PRI constant from the QF port specifies the highest +// ISR priority that is disabled by the QF framework. The value is suitable +// for the NVIC_SetPriority() CMSIS function. +// +// Only ISRs prioritized at or below the QF_AWARE_ISR_CMSIS_PRI level (i.e., +// with the numerical values of priorities equal or higher than +// QF_AWARE_ISR_CMSIS_PRI) are allowed to call the QK_ISR_ENTRY/ +// QK_ISR_ENTRY macros or any other QF/QK services. These ISRs are +// "QF-aware". +// +// Conversely, any ISRs prioritized above the QF_AWARE_ISR_CMSIS_PRI priority +// level (i.e., with the numerical values of priorities less than +// QF_AWARE_ISR_CMSIS_PRI) are never disabled and are not aware of the kernel. +// Such "QF-unaware" ISRs cannot call ANY QF/QK services. In particular they +// can NOT call the macros QK_ISR_ENTRY/QK_ISR_ENTRY. The only mechanism +// by which a "QF-unaware" ISR can communicate with the QF framework is by +// triggering a "QF-aware" ISR, which can post/publish events. +// +// NOTE2: +// The User LED is used to visualize the idle loop activity. The brightness +// of the LED is proportional to the frequency of the idle loop. +// Please note that the LED is toggled with interrupts locked, so no interrupt +// execution time contributes to the brightness of the User LED. +// diff --git a/examples/arm-cm/dpp_nucleo-l053r8/qk/gnu_with-stack-prot/Makefile b/examples/arm-cm/blinky_nucleo-c031c6/qk/gnu/Makefile similarity index 83% rename from examples/arm-cm/dpp_nucleo-l053r8/qk/gnu_with-stack-prot/Makefile rename to examples/arm-cm/blinky_nucleo-c031c6/qk/gnu/Makefile index bc86d558..378bb30c 100644 --- a/examples/arm-cm/dpp_nucleo-l053r8/qk/gnu_with-stack-prot/Makefile +++ b/examples/arm-cm/blinky_nucleo-c031c6/qk/gnu/Makefile @@ -1,13 +1,13 @@ ############################################################################## -# Product: Makefile for QP/C on NUCLEO-L053R8, QK kernel, GNU-ARM -# Last Updated for Version: 7.0.1 -# Date of the Last Update: 2022-05-23 +# Product: Makefile for QP/C on NUCLEO-C031C6, QK kernel, GNU-ARM +# Last Updated for Version: 7.3.0 +# Date of the Last Update: 2023-05-26 # # Q u a n t u m L e a P s # ------------------------ # Modern Embedded Software # -# Copyright (C) 2005-2021 Quantum Leaps, LLC. All rights reserved. +# Copyright (C) 2005 Quantum Leaps, LLC. # # This program is open source software: you can redistribute it and/or # modify it under the terms of the GNU General Public License as published @@ -45,13 +45,12 @@ # NOTE: # To use this Makefile on Windows, you will need the GNU make utility, which # is included in the Qtools collection for Windows, see: -# https://sourceforge.net/projects/qpc/files/QTools/ -# +# https://github.com/QuantumLeaps/qtools #----------------------------------------------------------------------------- # project name # -PROJECT := dpp-qk +PROJECT := blinky-qk #----------------------------------------------------------------------------- # project directories @@ -73,8 +72,8 @@ VPATH = \ $(QPC)/src/qk \ $(QPC)/src/qs \ $(QP_PORT_DIR) \ - $(QPC)/3rd_party/nucleo-l053r8 \ - $(QPC)/3rd_party/nucleo-l053r8/gnu + $(QPC)/3rd_party/nucleo-c031c6 \ + $(QPC)/3rd_party/nucleo-c031c6/gnu # list of all include directories needed by this project INCLUDES = \ @@ -82,7 +81,7 @@ INCLUDES = \ -I$(QPC)/include \ -I$(QP_PORT_DIR) \ -I$(QPC)/3rd_party/CMSIS/Include \ - -I$(QPC)/3rd_party/nucleo-l053r8 + -I$(QPC)/3rd_party/nucleo-c031c6 #----------------------------------------------------------------------------- # files @@ -93,12 +92,11 @@ ASM_SRCS := # C source files C_SRCS := \ - bsp_stack-prot.c \ + bsp.c \ main.c \ - philo.c \ - table.c \ - system_stm32l0xx.c \ - startup_stm32l053xx.c + blinky.c \ + system_stm32c0xx.c \ + startup_stm32c031xx.c # C++ source files CPP_SRCS := @@ -133,7 +131,9 @@ LIB_DIRS := LIBS := # defines -DEFINES := +DEFINES := -DSTM32C031xx + -DQK_USE_IRQ_NUM=31 \ + -DQK_USE_IRQ_HANDLER=Reserved31_IRQHandler # ARM CPU, ARCH, FPU, and Float-ABI types... # ARM_CPU: [cortex-m0 | cortex-m0plus | cortex-m1 | cortex-m3 | cortex-m4] @@ -163,18 +163,17 @@ AS := $(GNU_ARM)/bin/arm-none-eabi-as LINK := $(GNU_ARM)/bin/arm-none-eabi-gcc BIN := $(GNU_ARM)/bin/arm-none-eabi-objcopy - ############################################################################## -# Typically, you should not need to change anything below this line +# Typically you should not need to change anything below this line -# basic utilities (included in Qtools for Windows), see: -# http://sourceforge.net/projects/qpc/files/Qtools +# basic utilities (included in QTools for Windows), see: +# https://www.state-machine.com/qtools MKDIR := mkdir RM := rm #----------------------------------------------------------------------------- -# build options for various configurations for ARM Cortex-M4F +# build options for various configurations for ARM Cortex-M # # combine all the soruces... @@ -188,12 +187,11 @@ BIN_DIR := rel ASFLAGS = $(ARM_CPU) $(ARM_FPU) $(ASM_CPU) $(ASM_FPU) CFLAGS = -c $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \ - -ffunction-sections -fdata-sections -fstack-protector-all \ + -ffunction-sections -fdata-sections \ -O2 $(INCLUDES) $(DEFINES) -DNDEBUG CPPFLAGS = -c $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \ - -ffunction-sections -fdata-sections -fstack-protector-all \ - -fno-rtti -fno-exceptions \ + -ffunction-sections -fdata-sections -fno-rtti -fno-exceptions \ -O2 $(INCLUDES) $(DEFINES) -DNDEBUG else ifeq (spy, $(CONF)) # Spy configuration ................................ @@ -205,13 +203,12 @@ C_SRCS += $(QS_SRCS) ASFLAGS = -g $(ARM_CPU) $(ARM_FPU) $(ASM_CPU) $(ASM_FPU) CFLAGS = -c -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \ - -ffunction-sections -fdata-sections -fstack-protector-all \ - -O2 $(INCLUDES) $(DEFINES) -DQ_SPY + -ffunction-sections -fdata-sections \ + -O $(INCLUDES) $(DEFINES) -DQ_SPY CPPFLAGS = -c -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \ - -ffunction-sections -fdata-sections -fstack-protector-all \ - -fno-rtti -fno-exceptions \ - -O2 $(INCLUDES) $(DEFINES) -DQ_SPY + -ffunction-sections -fdata-sections -fno-rtti -fno-exceptions \ + -O $(INCLUDES) $(DEFINES) -DQ_SPY else # default Debug configuration .......................................... @@ -220,13 +217,12 @@ BIN_DIR := dbg ASFLAGS = -g $(ARM_CPU) $(ARM_FPU) $(ASM_CPU) $(ASM_FPU) CFLAGS = -c -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \ - -ffunction-sections -fdata-sections -fstack-protector-all \ - -O2 $(INCLUDES) $(DEFINES) + -ffunction-sections -fdata-sections \ + -O $(INCLUDES) $(DEFINES) CPPFLAGS = -c -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \ - -ffunction-sections -fdata-sections -fstack-protector-all \ - -fno-rtti -fno-exceptions \ - -O2 $(INCLUDES) $(DEFINES) + -ffunction-sections -fdata-sections -fno-rtti -fno-exceptions \ + -O $(INCLUDES) $(DEFINES) endif # ...................................................................... @@ -235,7 +231,6 @@ LINKFLAGS = -T$(LD_SCRIPT) $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb \ -specs=nosys.specs -specs=nano.specs \ -Wl,-Map,$(BIN_DIR)/$(OUTPUT).map,--cref,--gc-sections $(LIB_DIRS) - ASM_OBJS := $(patsubst %.s,%.o, $(notdir $(ASM_SRCS))) C_OBJS := $(patsubst %.c,%.o, $(notdir $(C_SRCS))) CPP_OBJS := $(patsubst %.cpp,%.o,$(notdir $(CPP_SRCS))) @@ -257,14 +252,20 @@ endif # rules # -all: $(TARGET_BIN) -#all: $(TARGET_ELF) +.PHONY : run norun flash + +ifeq ($(MAKECMDGOALS),norun) +all : $(TARGET_BIN) +norun : all +else +all : $(TARGET_BIN) run +endif $(TARGET_BIN): $(TARGET_ELF) $(BIN) -O binary $< $@ $(TARGET_ELF) : $(ASM_OBJS_EXT) $(C_OBJS_EXT) $(CPP_OBJS_EXT) - $(CC) $(CFLAGS) $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o + $(CC) $(CFLAGS) $(QPC)/src/qs/qstamp.c -o $(BIN_DIR)/qstamp.o $(LINK) $(LINKFLAGS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) $(BIN_DIR)/%.d : %.c @@ -282,6 +283,8 @@ $(BIN_DIR)/%.o : %.c $(BIN_DIR)/%.o : %.cpp $(CPP) $(CPPFLAGS) $< -o $@ +.PHONY : clean show + # include dependency files only if our goal depends on their existence ifneq ($(MAKECMDGOALS),clean) ifneq ($(MAKECMDGOALS),show) @@ -290,7 +293,6 @@ ifneq ($(MAKECMDGOALS),clean) endif -.PHONY : clean clean: -$(RM) $(BIN_DIR)/*.o \ $(BIN_DIR)/*.d \ diff --git a/examples/arm-cm/blinky_nucleo-c031c6/qk/gnu/README.txt b/examples/arm-cm/blinky_nucleo-c031c6/qk/gnu/README.txt new file mode 100644 index 00000000..d3fb3164 --- /dev/null +++ b/examples/arm-cm/blinky_nucleo-c031c6/qk/gnu/README.txt @@ -0,0 +1,92 @@ +About this Example +================== +This example can be built in two different ways: +- from the command prompt with the provided Makefile. +- from the Atollic TRUEStudio-ST32 with the provided project. + + +The Makefile +============ +The provided Makefile should be easy to adapt for your own projects. +It contains three build configurations: Debug (default), Release, and +Spy. + +Also, the Makefile has been specifically designed to work as an external +Makefile with the Eclipse CDT. + +The various build configurations are built as follows: + +make +make CONF=rel +make CONF=spy + +make clean +make CONF=rel clean +make CONF=spy clean + +*** +NOTE: +The installation folder of the GNU-ARM toolset on YOUR machine needs +to be adjusted in the provided Makefile, by editing the symbol: GNU_ARM. +As described in the comment for this symbol, the GNU-ARM toolset is taken +from: http://gnutoolchains.com/arm-eabi + +It is highly recommened to use the same GNU-ARM distribution, especially +for ARM Cortex-M projects, due to the support for the hardware FPU +(float-abi=hard). +*** + + +Selecting QK Exception +====================== +The QK kernel needs a dedicated exception to return to the thread +context after preemption. The default is to use the NMI exception +for that purpose. However, in case NMI is needed for some other +purpose, the QK port allows you to select a any, otherwise unused +IRQ for that purpose. To choose a given IRQ, you need to define +the macros QK_USE_IRQ_NUM and QK_USE_IRQ_HANDLER. These macros can +be provided on the command-line to the compiler. + +For example, (see the vector table), you can define the QK IRQ +as follows: + +QK_USE_IRQ_HANDLER=Reserved31_IRQHandler +QK_USE_IRQ_NUM=31 + + +Adjusting Stack and Heap Sizes +============================== +The stack and heap sizes are determined in this project by the GCC linker +script (.ld file), which provides a template of the recommended GCC linker +script for QP applications. + + +Startup Code +============ +The startup code for the STM32C0xx MCU used in this project is +located in the "3rd_party" folder in the following location: + +3rd_party\nucleo-c031c6\gnu\startup_stm32c031xx.c + +The file startup_stm32c031xx.c provides a template of the recommended +startup for QP applications and should be easily customizable for other +ARM Cortex-M microcontrollers. + +The startup file typically does not need to be modified or adapted for +applications. It calls the assert_failed() function, which must be +defined in the application to customize it for the application-specific +error-handling policy. + + +Adjusting the CPU Clock Speed +============================= +The current setting is to run at 12MHz from the MSI (internal oscillator), +but the CPU clock speed can be modified. + +*** +NOTE: +The NUCLEO boards have a wide range of possible clock selections, depending +on the solder bridge configuration. Please see Chapter 5.7 "OSC clock" in +the STM32 NUCLEO Boards User Manual (ST document UM1724) for more information. +*** + diff --git a/examples/arm-cm/blinky_nucleo-c031c6/qk/gnu/blinky-qk.ld b/examples/arm-cm/blinky_nucleo-c031c6/qk/gnu/blinky-qk.ld new file mode 100644 index 00000000..4a3ba851 --- /dev/null +++ b/examples/arm-cm/blinky_nucleo-c031c6/qk/gnu/blinky-qk.ld @@ -0,0 +1,135 @@ +/***************************************************************************** +* Linker script for for STM32C031C6, GNU-ARM linker +* +* Q u a n t u m L e a P s +* ------------------------ +* Modern Embedded Software +* +* Copyright (C) 2005 Quantum Leaps, LLC . +* +* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +* +* This software is dual-licensed under the terms of the open source GNU +* General Public License version 3 (or any later version), or alternatively, +* under the terms of one of the closed source Quantum Leaps commercial +* licenses. +* +* The terms of the open source GNU General Public License version 3 +* can be found at: +* +* The terms of the closed source Quantum Leaps commercial licenses +* can be found at: +* +* Redistributions in source code must retain this top-level comment block. +* Plagiarizing this software to sidestep the license obligations is illegal. +* +* Contact information: +* +* +*****************************************************************************/ +OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm", "elf32-littlearm") +OUTPUT_ARCH(arm) +ENTRY(Reset_Handler) /* entry Point */ + +MEMORY { /* memory map of STM32C031C6 */ + ROM (rx) : ORIGIN = 0x08000000, LENGTH = 32K + RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 12K +} + +/* The size of the stack used by the application. NOTE: you need to adjust */ +STACK_SIZE = 2048; + +/* The size of the heap used by the application. NOTE: you need to adjust */ +HEAP_SIZE = 0; + +SECTIONS { + + .isr_vector : { /* the vector table goes FIRST into ROM */ + KEEP(*(.isr_vector)) /* vector table */ + . = ALIGN(4); + } >ROM + + .text : { /* code and constants */ + . = ALIGN(4); + *(.text) /* .text sections (code) */ + *(.text*) /* .text* sections (code) */ + *(.rodata) /* .rodata sections (constants, strings, etc.) */ + *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ + + KEEP (*(.init)) + KEEP (*(.fini)) + + . = ALIGN(4); + } >ROM + + .preinit_array : { + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array*)) + PROVIDE_HIDDEN (__preinit_array_end = .); + } >ROM + + .init_array : { + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array*)) + PROVIDE_HIDDEN (__init_array_end = .); + } >ROM + + .fini_array : { + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(.fini_array*)) + KEEP (*(SORT(.fini_array.*))) + PROVIDE_HIDDEN (__fini_array_end = .); + } >ROM + + _etext = .; /* global symbols at end of code */ + + .stack : { + __stack_start__ = .; + . = . + STACK_SIZE; + . = ALIGN(4); + __stack_end__ = .; + } >RAM + + .data : AT (_etext) { + __data_load = LOADADDR (.data); + __data_start = .; + *(.data) /* .data sections */ + *(.data*) /* .data* sections */ + . = ALIGN(4); + __data_end__ = .; + _edata = __data_end__; + } >RAM + + .bss : { + __bss_start__ = .; + *(.bss) + *(.bss*) + *(COMMON) + . = ALIGN(4); + _ebss = .; /* define a global symbol at bss end */ + __bss_end__ = .; + } >RAM + + __exidx_start = .; + .ARM.exidx : { *(.ARM.exidx* .gnu.linkonce.armexidx.*) } >RAM + __exidx_end = .; + + PROVIDE ( end = _ebss ); + PROVIDE ( _end = _ebss ); + PROVIDE ( __end__ = _ebss ); + + .heap : { + __heap_start__ = .; + . = . + HEAP_SIZE; + . = ALIGN(4); + __heap_end__ = .; + } >RAM + + /* Remove information from the standard libraries */ + /DISCARD/ : { + libc.a ( * ) + libm.a ( * ) + libgcc.a ( * ) + } +} diff --git a/examples/arm-cm/blinky_efm32-slstk3401a/qk/iar/blinky-qk.ewd b/examples/arm-cm/blinky_nucleo-c031c6/qk/iar/blinky-qk.ewd similarity index 88% rename from examples/arm-cm/blinky_efm32-slstk3401a/qk/iar/blinky-qk.ewd rename to examples/arm-cm/blinky_nucleo-c031c6/qk/iar/blinky-qk.ewd index 3d290294..b3712b65 100644 --- a/examples/arm-cm/blinky_efm32-slstk3401a/qk/iar/blinky-qk.ewd +++ b/examples/arm-cm/blinky_nucleo-c031c6/qk/iar/blinky-qk.ewd @@ -11,7 +11,7 @@ C-SPY 2 - 28 + 32 1 1 - - + + + + + @@ -486,7 +498,7 @@ IJET_ID 2 - 8 + 9 1 1 - - - - JLINK_ID - 2 - - 16 - 1 - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - LMIFTDI_ID - 2 - - 2 - 1 - 1 - - - - - - - - - - PEMICRO_ID - 2 - - 3 - 1 - 1 - - - - - - - - STLINK_ID - 2 - - 4 - 1 - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - THIRDPARTY_ID - 2 - - 0 - 1 - 1 - - - - - - - - TIFET_ID - 2 - - 1 - 1 - 1 - - - - - - - - - - - - - - - - - - - XDS100_ID - 2 - - 6 - 1 - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - $TOOLKIT_DIR$\plugins\rtos\CMX\CmxArmPlugin.ENU.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\CMX\CmxTinyArmPlugin.ENU.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\SafeRTOS\SafeRTOSPlugin.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\TI-RTOS\tirtosplugin.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-286-KA-CSpy.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-KA-CSpy.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\uCOS-III\uCOS-III-KA-CSpy.ewplugin - 0 - - - $EW_DIR$\common\plugins\CodeCoverage\CodeCoverage.ENU.ewplugin - 1 - - - $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin - 0 - - - $EW_DIR$\common\plugins\uCProbe\uCProbePlugin.ENU.ewplugin - 0 - - - - - Release - - ARM - - 0 - - C-SPY - 2 - - 28 - 1 - 0 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ARMSIM_ID - 2 - - 1 - 1 - 0 - - - - - - - - CADI_ID - 2 - - 0 - 1 - 0 - - - - - - - - - CMSISDAP_ID - 2 - - 4 - 1 - 0 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - GDBSERVER_ID - 2 - - 0 - 1 - 0 - - - - - - - - - - - IJET_ID - 2 - - 8 - 1 - 0 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - JLINK_ID - 2 - - 16 - 1 - 0 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - LMIFTDI_ID - 2 - - 2 - 1 - 0 - - - - - - - - - - PEMICRO_ID - 2 - - 3 - 1 - 0 - - - - - - - - STLINK_ID - 2 - - 4 - 1 - 0 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - THIRDPARTY_ID - 2 - - 0 - 1 - 0 - - - - - - - - TIFET_ID - 2 - - 1 - 1 - 0 - - - - - - - - - - - - - - - - - - - XDS100_ID - 2 - - 6 - 1 - 0 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - $TOOLKIT_DIR$\plugins\rtos\CMX\CmxArmPlugin.ENU.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\CMX\CmxTinyArmPlugin.ENU.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\SafeRTOS\SafeRTOSPlugin.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\TI-RTOS\tirtosplugin.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-286-KA-CSpy.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-KA-CSpy.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\uCOS-III\uCOS-III-KA-CSpy.ewplugin - 0 - - - $EW_DIR$\common\plugins\CodeCoverage\CodeCoverage.ENU.ewplugin - 1 - - - $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin - 0 - - - $EW_DIR$\common\plugins\uCProbe\uCProbePlugin.ENU.ewplugin - 0 - - - - - Spy - - ARM - - 1 - - C-SPY - 2 - - 28 - 1 - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ARMSIM_ID - 2 - - 1 - 1 - 1 - - - - - - - - CADI_ID - 2 - - 0 - 1 - 1 - - - - - - - - - CMSISDAP_ID - 2 - - 4 - 1 - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - GDBSERVER_ID - 2 - - 0 - 1 - 1 - - - - - - - - - - - IJET_ID - 2 - - 8 - 1 - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -3722,7 +980,7 @@ LMIFTDI_ID 2 - 2 + 3 1 1 + + + + + + + NULINK_ID + 2 + + 0 + 1 + 1 + + + @@ -3780,24 +1072,16 @@ STLINK_ID 2 - 4 + 8 1 1 - - + + + + + + @@ -3991,7 +1300,7 @@ XDS100_ID 2 - 6 + 9 1 1 + + + + @@ -4168,6 +1493,18 @@ $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin 0 + + $TOOLKIT_DIR$\plugins\rtos\FreeRtos\FreeRtosArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin2.ENU.ewplugin + 0 + $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin 0 @@ -4177,11 +1514,15 @@ 0 - $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9.ewplugin 0 - $TOOLKIT_DIR$\plugins\rtos\TI-RTOS\tirtosplugin.ewplugin + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9BE.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin 0 @@ -4197,13 +1538,3113 @@ 0 - $EW_DIR$\common\plugins\CodeCoverage\CodeCoverage.ENU.ewplugin - 1 + $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\TargetAccessServer\TargetAccessServer.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\uCProbe\uCProbePlugin.ENU.ewplugin + 0 + + + + + Release + + ARM + + 0 + + C-SPY + 2 + + 32 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ARMSIM_ID + 2 + + 1 + 1 + 0 + + + + + + + + CADI_ID + 2 + + 0 + 1 + 0 + + + + + + + + + CMSISDAP_ID + 2 + + 4 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + GDBSERVER_ID + 2 + + 0 + 1 + 0 + + + + + + + + + + + IJET_ID + 2 + + 9 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + JLINK_ID + 2 + + 16 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + LMIFTDI_ID + 2 + + 3 + 1 + 0 + + + + + + + + + + + + + NULINK_ID + 2 + + 0 + 1 + 0 + + + + + + + PEMICRO_ID + 2 + + 3 + 1 + 0 + + + + + + + + STLINK_ID + 2 + + 8 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + THIRDPARTY_ID + 2 + + 0 + 1 + 0 + + + + + + + + TIFET_ID + 2 + + 1 + 1 + 0 + + + + + + + + + + + + + + + + + + + XDS100_ID + 2 + + 9 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + $TOOLKIT_DIR$\plugins\rtos\CMX\CmxArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\CMX\CmxTinyArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\FreeRtos\FreeRtosArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin2.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SafeRTOS\SafeRTOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9BE.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-286-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-III\uCOS-III-KA-CSpy.ewplugin + 0 $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin 0 + + $EW_DIR$\common\plugins\TargetAccessServer\TargetAccessServer.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\uCProbe\uCProbePlugin.ENU.ewplugin + 0 + + + + + Spy + + ARM + + 1 + + C-SPY + 2 + + 32 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ARMSIM_ID + 2 + + 1 + 1 + 1 + + + + + + + + CADI_ID + 2 + + 0 + 1 + 1 + + + + + + + + + CMSISDAP_ID + 2 + + 4 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + GDBSERVER_ID + 2 + + 0 + 1 + 1 + + + + + + + + + + + IJET_ID + 2 + + 9 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + JLINK_ID + 2 + + 16 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + LMIFTDI_ID + 2 + + 3 + 1 + 1 + + + + + + + + + + + + + NULINK_ID + 2 + + 0 + 1 + 1 + + + + + + + PEMICRO_ID + 2 + + 3 + 1 + 1 + + + + + + + + STLINK_ID + 2 + + 8 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + THIRDPARTY_ID + 2 + + 0 + 1 + 1 + + + + + + + + TIFET_ID + 2 + + 1 + 1 + 1 + + + + + + + + + + + + + + + + + + + XDS100_ID + 2 + + 9 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + $TOOLKIT_DIR$\plugins\rtos\CMX\CmxArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\CMX\CmxTinyArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\FreeRtos\FreeRtosArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin2.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SafeRTOS\SafeRTOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9BE.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-286-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-III\uCOS-III-KA-CSpy.ewplugin + 0 + + + $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\TargetAccessServer\TargetAccessServer.ENU.ewplugin + 0 + $EW_DIR$\common\plugins\uCProbe\uCProbePlugin.ENU.ewplugin 0 diff --git a/examples/arm-cm/blinky_efm32-slstk3401a/qk/iar/blinky-qk.ewp b/examples/arm-cm/blinky_nucleo-c031c6/qk/iar/blinky-qk.ewp similarity index 88% rename from examples/arm-cm/blinky_efm32-slstk3401a/qk/iar/blinky-qk.ewp rename to examples/arm-cm/blinky_nucleo-c031c6/qk/iar/blinky-qk.ewp index 772f3589..ed3771b6 100644 --- a/examples/arm-cm/blinky_efm32-slstk3401a/qk/iar/blinky-qk.ewp +++ b/examples/arm-cm/blinky_nucleo-c031c6/qk/iar/blinky-qk.ewp @@ -11,9 +11,13 @@ General 3 - 28 + 35 1 1 + - - - - - + + + + + + + + ICCARM 2 - 34 + 37 1 1 - - - + + AARM 2 - 10 + 11 1 1 + @@ -656,13 +668,9 @@ 0 + inputOutputBased - - BICOMP - 0 - - BUILDACTION 1 @@ -675,17 +683,13 @@ ILINK 0 - 20 + 27 1 1 - + + + + + + + + + + + + + + + @@ -1010,11 +1074,6 @@ - - BILINK - 0 - - Coder 0 @@ -1031,9 +1090,13 @@ General 3 - 28 + 35 1 0 + - - - - - + + + + + + + + ICCARM 2 - 34 + 37 1 0 - - - + + AARM 2 - 10 + 11 1 0 + @@ -1677,13 +1748,9 @@ 0 + inputOutputBased - - BICOMP - 0 - - BUILDACTION 1 @@ -1696,17 +1763,13 @@ ILINK 0 - 20 + 27 1 0 - + + + + + + + + + + + + + + + @@ -2031,11 +2154,6 @@ - - BILINK - 0 - - Coder 0 @@ -2052,9 +2170,13 @@ General 3 - 28 + 35 1 1 + - - - - - + + + + + + + + ICCARM 2 - 34 + 37 1 1 - - - + + AARM 2 - 10 + 11 1 1 + @@ -2698,13 +2828,9 @@ 0 + inputOutputBased - - BICOMP - 0 - - BUILDACTION 1 @@ -2717,17 +2843,13 @@ ILINK 0 - 20 + 27 1 1 - + + + + + + + + + + + + + + + @@ -3052,17 +3234,15 @@ - - BILINK - 0 - - Coder 0 + + Release + Application @@ -3080,32 +3260,20 @@ $PROJ_DIR$\..\..\main.c - - $PROJ_DIR$\..\..\..\..\..\include\qstamp.c - - efm32pg1b + nucleo-c031c6 - $PROJ_DIR$\..\..\..\..\..\3rd_party\efm32pg1b\em_assert.c + $PROJ_DIR$\..\..\..\..\..\3rd_party\nucleo-c031c6\iar\startup_stm32c031xx.s - $PROJ_DIR$\..\..\..\..\..\3rd_party\efm32pg1b\em_cmu.c + $PROJ_DIR$\..\..\..\..\..\3rd_party\nucleo-c031c6\stm32c031xx.h - $PROJ_DIR$\..\..\..\..\..\3rd_party\efm32pg1b\em_emu.c + $PROJ_DIR$\..\..\..\..\..\3rd_party\nucleo-c031c6\stm32c0xx.h - $PROJ_DIR$\..\..\..\..\..\3rd_party\efm32pg1b\em_gpio.c - - - $PROJ_DIR$\..\..\..\..\..\3rd_party\efm32pg1b\em_system.c - - - $PROJ_DIR$\..\..\..\..\..\3rd_party\efm32pg1b\iar\startup_efm32pg1b.s - - - $PROJ_DIR$\..\..\..\..\..\3rd_party\efm32pg1b\system_efm32pg1b.c + $PROJ_DIR$\..\..\..\..\..\3rd_party\nucleo-c031c6\system_stm32c0xx.c @@ -3152,15 +3320,24 @@ $PROJ_DIR$\..\..\..\..\..\src\qk\qk.c - - $PROJ_DIR$\..\..\..\..\..\src\qk_pkg.h - QP_port + + $PROJ_DIR$\..\..\..\..\..\ports\arm-cm\qk\iar\qep_port.h + + + $PROJ_DIR$\..\..\..\..\..\ports\arm-cm\qk\iar\qf_port.h + $PROJ_DIR$\..\..\..\..\..\ports\arm-cm\qk\iar\qk_port.c + + $PROJ_DIR$\..\..\..\..\..\ports\arm-cm\qk\iar\qk_port.h + + + $PROJ_DIR$\..\..\..\..\..\ports\arm-cm\qk\iar\qs_port.h + QS @@ -3175,10 +3352,10 @@ $PROJ_DIR$\..\..\..\..\..\src\qs\qs_fp.c - $PROJ_DIR$\..\..\..\..\..\src\qs_pkg.h + $PROJ_DIR$\..\..\..\..\..\src\qs\qs_rx.c - $PROJ_DIR$\..\..\..\..\..\src\qs\qs_rx.c + $PROJ_DIR$\..\..\..\..\..\src\qs\qstamp.c diff --git a/examples/arm-cm/blinky_efm32-slstk3401a/qk/iar/blinky-qk.eww b/examples/arm-cm/blinky_nucleo-c031c6/qk/iar/blinky-qk.eww similarity index 100% rename from examples/arm-cm/blinky_efm32-slstk3401a/qk/iar/blinky-qk.eww rename to examples/arm-cm/blinky_nucleo-c031c6/qk/iar/blinky-qk.eww diff --git a/examples/arm-cm/blinky_nucleo-c031c6/qk/iar/blinky-qk.icf b/examples/arm-cm/blinky_nucleo-c031c6/qk/iar/blinky-qk.icf new file mode 100644 index 00000000..db057b16 --- /dev/null +++ b/examples/arm-cm/blinky_nucleo-c031c6/qk/iar/blinky-qk.icf @@ -0,0 +1,165 @@ +/*###ICF### Section handled by ICF editor, don't touch! ****/ +/*-Editor annotation file-*/ +/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_4.xml" */ +/*-Specials-*/ +define symbol __ICFEDIT_intvec_start__ = 0x08000000; +/*-Memory Regions-*/ +define symbol __ICFEDIT_region_IROM1_start__ = 0x08000000; +define symbol __ICFEDIT_region_IROM1_end__ = 0x08007FFF; +define symbol __ICFEDIT_region_IROM2_start__ = 0x0; +define symbol __ICFEDIT_region_IROM2_end__ = 0x0; +define symbol __ICFEDIT_region_EROM1_start__ = 0x0; +define symbol __ICFEDIT_region_EROM1_end__ = 0x0; +define symbol __ICFEDIT_region_EROM2_start__ = 0x0; +define symbol __ICFEDIT_region_EROM2_end__ = 0x0; +define symbol __ICFEDIT_region_EROM3_start__ = 0x0; +define symbol __ICFEDIT_region_EROM3_end__ = 0x0; +define symbol __ICFEDIT_region_IRAM1_start__ = 0x20000000; +define symbol __ICFEDIT_region_IRAM1_end__ = 0x20002FFF; +define symbol __ICFEDIT_region_IRAM2_start__ = 0x0; +define symbol __ICFEDIT_region_IRAM2_end__ = 0x0; +define symbol __ICFEDIT_region_ERAM1_start__ = 0x0; +define symbol __ICFEDIT_region_ERAM1_end__ = 0x0; +define symbol __ICFEDIT_region_ERAM2_start__ = 0x0; +define symbol __ICFEDIT_region_ERAM2_end__ = 0x0; +define symbol __ICFEDIT_region_ERAM3_start__ = 0x0; +define symbol __ICFEDIT_region_ERAM3_end__ = 0x0; +/*-Sizes-*/ +define symbol __ICFEDIT_size_cstack__ = 2048; +define symbol __ICFEDIT_size_proc_stack__ = 0x0; +define symbol __ICFEDIT_size_heap__ = 0; +/**** End of ICF editor section. ###ICF###*/ + +define memory mem with size = 4G; +define symbol use_IROM1 = (__ICFEDIT_region_IROM1_start__ != 0x0 || __ICFEDIT_region_IROM1_end__ != 0x0); +define symbol use_IROM2 = (__ICFEDIT_region_IROM2_start__ != 0x0 || __ICFEDIT_region_IROM2_end__ != 0x0); +define symbol use_EROM1 = (__ICFEDIT_region_EROM1_start__ != 0x0 || __ICFEDIT_region_EROM1_end__ != 0x0); +define symbol use_EROM2 = (__ICFEDIT_region_EROM2_start__ != 0x0 || __ICFEDIT_region_EROM2_end__ != 0x0); +define symbol use_EROM3 = (__ICFEDIT_region_EROM3_start__ != 0x0 || __ICFEDIT_region_EROM3_end__ != 0x0); +define symbol use_IRAM1 = (__ICFEDIT_region_IRAM1_start__ != 0x0 || __ICFEDIT_region_IRAM1_end__ != 0x0); +define symbol use_IRAM2 = (__ICFEDIT_region_IRAM2_start__ != 0x0 || __ICFEDIT_region_IRAM2_end__ != 0x0); +define symbol use_ERAM1 = (__ICFEDIT_region_ERAM1_start__ != 0x0 || __ICFEDIT_region_ERAM1_end__ != 0x0); +define symbol use_ERAM2 = (__ICFEDIT_region_ERAM2_start__ != 0x0 || __ICFEDIT_region_ERAM2_end__ != 0x0); +define symbol use_ERAM3 = (__ICFEDIT_region_ERAM3_start__ != 0x0 || __ICFEDIT_region_ERAM3_end__ != 0x0); + +if (use_IROM1) +{ + define region IROM1_region = mem:[from __ICFEDIT_region_IROM1_start__ to __ICFEDIT_region_IROM1_end__]; +} +else +{ + define region IROM1_region = []; +} + +if (use_IROM2) +{ + define region IROM2_region = mem:[from __ICFEDIT_region_IROM2_start__ to __ICFEDIT_region_IROM2_end__]; +} +else +{ + define region IROM2_region = []; +} +define region IROM_region = IROM1_region | IROM2_region; + +if (use_EROM1) +{ + define region EROM1_region = mem:[from __ICFEDIT_region_EROM1_start__ to __ICFEDIT_region_EROM1_end__]; +} +else +{ + define region EROM1_region = []; +} +if (use_EROM2) +{ + define region EROM2_region = mem:[from __ICFEDIT_region_EROM2_start__ to __ICFEDIT_region_EROM2_end__]; +} +else +{ + define region EROM2_region = []; +} +if (use_EROM3) +{ + define region EROM3_region = mem:[from __ICFEDIT_region_EROM3_start__ to __ICFEDIT_region_EROM3_end__]; +} +else +{ + define region EROM3_region = []; +} +define region EROM_region = EROM1_region | EROM2_region | EROM3_region; + +if (use_IRAM1) +{ + define region IRAM1_region = mem:[from __ICFEDIT_region_IRAM1_start__ to __ICFEDIT_region_IRAM1_end__]; +} +else +{ + define region IRAM1_region = []; +} +if (use_IRAM2) +{ + define region IRAM2_region = mem:[from __ICFEDIT_region_IRAM2_start__ to __ICFEDIT_region_IRAM2_end__]; +} +else +{ + define region IRAM2_region = []; +} +define region IRAM_region = IRAM1_region | IRAM2_region; + +if (use_ERAM1) +{ + define region ERAM1_region = mem:[from __ICFEDIT_region_ERAM1_start__ to __ICFEDIT_region_ERAM1_end__]; +} +else +{ + define region ERAM1_region = []; +} +if (use_ERAM2) +{ + define region ERAM2_region = mem:[from __ICFEDIT_region_ERAM2_start__ to __ICFEDIT_region_ERAM2_end__]; +} +else +{ + define region ERAM2_region = []; +} +if (use_ERAM3) +{ + define region ERAM3_region = mem:[from __ICFEDIT_region_ERAM3_start__ to __ICFEDIT_region_ERAM3_end__]; +} +else +{ + define region ERAM3_region = []; +} +define region ERAM_region = ERAM1_region | ERAM2_region | ERAM3_region; + +initialize by copy { readwrite }; +if (isdefinedsymbol(__USE_DLIB_PERTHREAD)) +{ + // Required in a multi-threaded application + initialize by copy with packing = none { section __DLIB_PERTHREAD }; +} + +place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec }; + +if (!isempty(IROM_region)) +{ + place in IROM_region { readonly }; +} + +if (!isempty(EROM_region)) +{ + place in EROM_region { readonly section application_specific_ro }; +} + +if (!isempty(IRAM_region)) +{ + define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { }; + define block PROC_STACK with alignment = 8, size = __ICFEDIT_size_proc_stack__ { }; + define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { }; + place at start of IRAM_region {block CSTACK }; /* <== Quantum Leaps */ + place in IRAM_region { readwrite, block PROC_STACK, block HEAP }; +} + +if (!isempty(ERAM_region)) +{ + place in ERAM_region { readwrite section application_specific_rw }; +} \ No newline at end of file diff --git a/examples/arm-cm/blinky_nucleo-c031c6/qv/armclang/blinky-qv.sct b/examples/arm-cm/blinky_nucleo-c031c6/qv/armclang/blinky-qv.sct new file mode 100644 index 00000000..100826b8 --- /dev/null +++ b/examples/arm-cm/blinky_nucleo-c031c6/qv/armclang/blinky-qv.sct @@ -0,0 +1,23 @@ +; ************************************************************* +; *** Scatter-Loading Description File generated by uVision *** +; +; Adapted by Quantum Leaps: +; moved STACK as the first section in RW_STACK +; ************************************************************* + +LR_IROM1 0x08000000 0x00008000 { ; load region size_region + ER_IROM1 0x08000000 0x00008000 { ; load address = execution address + *.o (RESET, +First) + *(InRoot$$Sections) + .ANY (+RO) + .ANY (+XO) + } + + RW_STACK 0x20000000 { + * (STACK, +First) + } + RW_IRAM1 +0 (0x00003000 - 2048) { + .ANY (+RW +ZI) + } +} + diff --git a/examples/arm-cm/blinky_efm32-slstk3401a/qv/armclang/blinky-qv.uvoptx b/examples/arm-cm/blinky_nucleo-c031c6/qv/armclang/blinky-qv.uvoptx similarity index 79% rename from examples/arm-cm/blinky_efm32-slstk3401a/qv/armclang/blinky-qv.uvoptx rename to examples/arm-cm/blinky_nucleo-c031c6/qv/armclang/blinky-qv.uvoptx index 0dfaf2da..ff891b38 100644 --- a/examples/arm-cm/blinky_efm32-slstk3401a/qv/armclang/blinky-qv.uvoptx +++ b/examples/arm-cm/blinky_nucleo-c031c6/qv/armclang/blinky-qv.uvoptx @@ -8,9 +8,9 @@ *.c *.s*; *.src; *.a* - *.obj + *.obj; *.o *.lib - *.txt; *.h; *.inc + *.txt; *.h; *.inc; *.md *.plm *.cpp 0 @@ -30,8 +30,8 @@ 1 1 - 1 - 0 + 0 + 1 0 @@ -77,7 +77,7 @@ 0 1 - 3 + 18 0 1 @@ -103,7 +103,7 @@ 1 0 0 - 3 + 6 @@ -114,46 +114,74 @@ - Segger\JL2CM3.dll + STLink\ST-LINKIII-KEIL_SWO.dll 0 - DLGUARM - / + ST-LINKIII-KEIL_SWO + -U066BFF505153848667095842 -O206 -SF10000 -C0 -A0 -I0 -HNlocalhost -HP7184 -P1 -N00("ARM CoreSight SW-DP (ARM Core") -D00(0BC11477) -L00(0) -TO65554 -TC10000000 -TT10000000 -TP21 -TDS8007 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -FO7 -FD20000000 -FC1000 -FN1 -FF0STM32C0x_32.FLM -FS08000000 -FL08000 -FP0($$Device:STM32C031C6Tx$CMSIS\Flash\STM32C0x_32.FLM) 0 - JL2CM3 - -U440060969 -O207 -S2 -ZTIFSpeedSel5000 -A0 -C0 -JU1 -JI127.0.0.1 -JP0 -RST0 -N00("ARM CoreSight SW-DP") -D00(2BA01477) -L00(0) -TO18 -TC10000000 -TP21 -TDS8007 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -TB1 -TFE0 -FO7 -FD20000000 -FC8000 -FN1 -FF0GECKOP2.FLM -FS00 -FL040000 -FP0($$Device:EFM32PG1B200F256GM48$Flash\GECKOP2.FLM) + UL2CM3 + -U -O206 -S8 -C0 -P00 -N00("") -D00(00000000) -L00(0) -TO65554 -TC10000000 -TT10000000 -TP21 -TDS8007 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -FO7 -FD20000000 -FC1000 -FN1 -FF0STM32C0x_32.FLM -FS08000000 -FL08000 -FP0($$Device:STM32C031C6Tx$CMSIS\Flash\STM32C0x_32.FLM) + + + 0 + DLGUARM + (105=-1,-1,-1,-1,0) 0 ARMRTXEVENTFLAGS -L70 -Z18 -C0 -M0 -T1 - - 0 - UL2CM3 - UL2CM3(-O207 -S0 -C0 -FO7 -FN1 -FC8000 -FD20000000 -FF0GECKOP2 -FL020000 -FS00 -FP0($$Device:EFM32PG1B200F256GM48$Flash\GECKOP2.FLM) - 0 DLGTARM - (1010=-1,-1,-1,-1,0)(1007=-1,-1,-1,-1,0)(1008=-1,-1,-1,-1,0)(1009=-1,-1,-1,-1,0)(1012=-1,-1,-1,-1,0) + (1010=-1,-1,-1,-1,0)(1007=-1,-1,-1,-1,0)(1008=-1,-1,-1,-1,0)(1012=-1,-1,-1,-1,0)(1009=-1,-1,-1,-1,0) 0 ARMDBGFLAGS - - 0 - lmidk-agdi - -U0E2006F4 -O4622 -S4 -FO61 - - + + + 0 + 0 + 128 + 1 +
134218056
+ 0 + 0 + 0 + 0 + 0 + 1 + ..\..\..\..\..\3rd_party\nucleo-c031c6\arm\startup_stm32c031xx.s + + \\blinky_qv\../../../../../3rd_party/nucleo-c031c6/arm/startup_stm32c031xx.s\128 +
+ + 1 + 0 + 41 + 1 +
134228148
+ 0 + 0 + 0 + 0 + 0 + 1 + C:\qp-dev\qpc\examples\arm-cm\blinky_nucleo-c031c6\qv\main.c + + \\blinky_qv\../main.c\41 +
+
1 @@ -212,6 +240,13 @@ + + 1 + 0 + 0 + 2 + 10000000 + @@ -224,8 +259,8 @@ 1 1 - 1 - 0 + 0 + 1 0 @@ -271,7 +306,7 @@ 0 0 - 3 + 18 0 1 @@ -297,7 +332,7 @@ 1 0 0 - 3 + 6 @@ -308,13 +343,23 @@ - Segger\JL2CM3.dll + STLink\ST-LINKIII-KEIL_SWO.dll 0 - JL2CM3 - -U440060969 -O207 -S2 -ZTIFSpeedSel5000 -A0 -C0 -JU1 -JI127.0.0.1 -JP0 -RST0 -N00("ARM CoreSight SW-DP") -D00(2BA01477) -L00(0) -TO18 -TC10000000 -TP21 -TDS8007 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -TB1 -TFE0 -FO7 -FD20000000 -FC8000 -FN1 -FF0GECKOP2.FLM -FS00 -FL020000 -FP0($$Device:EFM32PG1B200F256GM48$Flash\GECKOP2.FLM) + UL2CM3 + UL2CM3(-S0 -C0 -P0 ) -FN1 -FC1000 -FD20000000 -FF0STM32C0x_32 -FL08000 -FS08000000 -FP0($$Device:STM32C031C6Tx$CMSIS\Flash\STM32C0x_32.FLM) + + + 0 + ST-LINKIII-KEIL_SWO + UL2CM3(-S0 -C0 -P0 ) -FN1 -FC1000 -FD20000000 -FF0STM32C0x_32 -FL08000 -FS08000000 -FP0($$Device:STM32C031C6Tx$CMSIS\Flash\STM32C0x_32.FLM) + + + 0 + DLGUARM + (105=-1,-1,-1,-1,0) 0 @@ -324,23 +369,13 @@ 0 DLGTARM - (1010=-1,-1,-1,-1,0)(1007=-1,-1,-1,-1,0)(1008=-1,-1,-1,-1,0)(1009=-1,-1,-1,-1,0)(1012=-1,-1,-1,-1,0) + (1010=-1,-1,-1,-1,0)(1007=-1,-1,-1,-1,0)(1008=-1,-1,-1,-1,0)(1009=-1,-1,-1,-1,0) 0 ARMDBGFLAGS - - 0 - lmidk-agdi - -U0E10259B -O4622 -S4 -FO61 - - - 0 - UL2CM3 - -O207 -S0 -C0 -FO7 -FN1 -FC8000 -FD20000000 -FF0GECKOP2 -FL020000 -FS00 -FP0($$Device:EFM32PG1B200F256GM48$Flash\GECKOP2.FLM) - @@ -401,6 +436,13 @@ + + 1 + 1 + 0 + 2 + 10000000 + @@ -413,8 +455,8 @@ 1 1 - 1 - 0 + 0 + 1 0 @@ -460,7 +502,7 @@ 0 0 - 3 + 18 0 1 @@ -486,7 +528,7 @@ 1 0 0 - 3 + 6 @@ -497,39 +539,39 @@ - Segger\JL2CM3.dll + STLink\ST-LINKIII-KEIL_SWO.dll 0 - JL2CM3 - -U -O207 -S2 -ZTIFSpeedSel5000 -A0 -C0 -JU1 -JI127.0.0.1 -JP0 -RST0 -TO18 -TC10000000 -TP21 -TDS8007 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -TB1 -TFE0 -FO7 -FD20000000 -FC8000 -FN1 -FF0GECKOP2.FLM -FS00 -FL020000 -FP0($$Device:EFM32PG1B200F256GM48$Flash\GECKOP2.FLM) + UL2CM3 + UL2CM3(-S0 -C0 -P0 ) -FN1 -FC1000 -FD20000000 -FF0STM32C0x_32 -FL08000 -FS08000000 -FP0($$Device:STM32C031C6Tx$CMSIS\Flash\STM32C0x_32.FLM) + + + 0 + ST-LINKIII-KEIL_SWO + -U-O206 -O206 -SF10000 -C0 -A0 -I0 -HNlocalhost -HP7184 -P1 -N00("ARM CoreSight SW-DP (ARM Core") -D00(0BC11477) -L00(0) -TO131090 -TC10000000 -TT10000000 -TP21 -TDS8007 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -FO7 -FD20000000 -FC1000 -FN1 -FF0STM32C0x_32.FLM -FS08000000 -FL08000 -FP0($$Device:STM32C031C6Tx$CMSIS\Flash\STM32C0x_32.FLM) + + + 0 + DLGUARM + (105=-1,-1,-1,-1,0) 0 ARMRTXEVENTFLAGS -L70 -Z18 -C0 -M0 -T1 - - 0 - UL2CM3 - UL2CM3(-O207 -S0 -C0 -FO7 -FN1 -FC8000 -FD20000000 -FF0GECKOP2 -FL020000 -FS00 -FP0($$Device:EFM32PG1B200F256GM48$Flash\GECKOP2.FLM) - 0 DLGTARM - (1010=-1,-1,-1,-1,0)(1007=-1,-1,-1,-1,0)(1008=-1,-1,-1,-1,0)(1009=-1,-1,-1,-1,0)(1012=-1,-1,-1,-1,0) + (1010=-1,-1,-1,-1,0)(1007=-1,-1,-1,-1,0)(1008=-1,-1,-1,-1,0)(1012=-1,-1,-1,-1,0)(1009=-1,-1,-1,-1,0) 0 ARMDBGFLAGS - - 0 - lmidk-agdi - -U0E2006F4 -O4622 -S4 -FO61 - @@ -590,11 +632,28 @@ + + + System Viewer\GPIOA + 35904 + + + System Viewer\USART2 + 35905 + + + + 1 + 0 + 0 + 2 + 10000000 + - Applicatioin + Source Code 1 0 0 @@ -614,30 +673,18 @@ 1 2 - 1 + 5 0 0 0 - ..\..\blinky.c - blinky.c + ..\..\bsp.h + bsp.h 0 0 1 3 - 1 - 0 - 0 - 0 - ..\..\main.c - main.c - 0 - 0 - - - 1 - 4 5 0 0 @@ -647,6 +694,18 @@ 0 0 + + 1 + 4 + 1 + 0 + 0 + 0 + ..\..\main.c + main.c + 0 + 0 + 1 5 @@ -654,15 +713,15 @@ 0 0 0 - ..\..\..\..\..\include\qstamp.c - qstamp.c + ..\..\blinky.c + blinky.c 0 0 - efm32pg1b + nucleo-c031c6 1 0 0 @@ -670,24 +729,24 @@ 2 6 - 2 + 5 0 0 0 - ..\..\..\..\..\3rd_party\efm32pg1b\arm\startup_efm32pg1b.s - startup_efm32pg1b.s + ..\..\..\..\..\3rd_party\nucleo-c031c6\stm32c0xx.h + stm32c0xx.h 0 0 2 7 - 1 + 5 0 0 0 - ..\..\..\..\..\3rd_party\efm32pg1b\em_cmu.c - em_cmu.c + ..\..\..\..\..\3rd_party\nucleo-c031c6\stm32c031xx.h + stm32c031xx.h 0 0 @@ -698,68 +757,20 @@ 0 0 0 - ..\..\..\..\..\3rd_party\efm32pg1b\em_emu.c - em_emu.c + ..\..\..\..\..\3rd_party\nucleo-c031c6\system_stm32c0xx.c + system_stm32c0xx.c 0 0 2 9 - 1 + 2 0 0 0 - ..\..\..\..\..\3rd_party\efm32pg1b\em_gpio.c - em_gpio.c - 0 - 0 - - - 2 - 10 - 1 - 0 - 0 - 0 - ..\..\..\..\..\3rd_party\efm32pg1b\em_int.c - em_int.c - 0 - 0 - - - 2 - 11 - 1 - 0 - 0 - 0 - ..\..\..\..\..\3rd_party\efm32pg1b\em_rtcc.c - em_rtcc.c - 0 - 0 - - - 2 - 12 - 1 - 0 - 0 - 0 - ..\..\..\..\..\3rd_party\efm32pg1b\em_system.c - em_system.c - 0 - 0 - - - 2 - 13 - 1 - 0 - 0 - 0 - ..\..\..\..\..\3rd_party\efm32pg1b\system_efm32pg1b.c - system_efm32pg1b.c + ..\..\..\..\..\3rd_party\nucleo-c031c6\arm\startup_stm32c031xx.s + startup_stm32c031xx.s 0 0 @@ -773,7 +784,7 @@ 0 3 - 14 + 10 1 0 0 @@ -785,7 +796,7 @@ 3 - 15 + 11 1 0 0 @@ -797,7 +808,7 @@ 3 - 16 + 12 1 0 0 @@ -809,7 +820,7 @@ 3 - 17 + 13 1 0 0 @@ -821,7 +832,7 @@ 3 - 18 + 14 1 0 0 @@ -833,7 +844,7 @@ 3 - 19 + 15 1 0 0 @@ -845,7 +856,7 @@ 3 - 20 + 16 1 0 0 @@ -857,7 +868,7 @@ 3 - 21 + 17 1 0 0 @@ -869,7 +880,7 @@ 3 - 22 + 18 1 0 0 @@ -881,7 +892,7 @@ 3 - 23 + 19 1 0 0 @@ -893,7 +904,7 @@ 3 - 24 + 20 1 0 0 @@ -905,7 +916,7 @@ 3 - 25 + 21 1 0 0 @@ -917,7 +928,7 @@ 3 - 26 + 22 1 0 0 @@ -937,7 +948,43 @@ 0 4 - 27 + 23 + 5 + 0 + 0 + 0 + ..\..\..\..\..\ports\arm-cm\qv\armclang\qep_port.h + qep_port.h + 0 + 0 + + + 4 + 24 + 5 + 0 + 0 + 0 + ..\..\..\..\..\ports\arm-cm\qv\armclang\qf_port.h + qf_port.h + 0 + 0 + + + 4 + 25 + 5 + 0 + 0 + 0 + ..\..\..\..\..\ports\arm-cm\qv\armclang\qs_port.h + qs_port.h + 0 + 0 + + + 4 + 26 1 0 0 @@ -947,6 +994,18 @@ 0 0 + + 4 + 27 + 5 + 0 + 0 + 0 + ..\..\..\..\..\ports\arm-cm\qv\armclang\qv_port.h + qv_port.h + 0 + 0 + @@ -1003,6 +1062,18 @@ 0 0 + + 5 + 32 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qs\qstamp.c + qstamp.c + 0 + 0 + diff --git a/examples/arm-cm/blinky_efm32-slstk3401a/qv/armclang/blinky-qv.uvprojx b/examples/arm-cm/blinky_nucleo-c031c6/qv/armclang/blinky-qv.uvprojx similarity index 84% rename from examples/arm-cm/blinky_efm32-slstk3401a/qv/armclang/blinky-qv.uvprojx rename to examples/arm-cm/blinky_nucleo-c031c6/qv/armclang/blinky-qv.uvprojx index 0777ae22..07c684aa 100644 --- a/examples/arm-cm/blinky_efm32-slstk3401a/qv/armclang/blinky-qv.uvprojx +++ b/examples/arm-cm/blinky_nucleo-c031c6/qv/armclang/blinky-qv.uvprojx @@ -10,20 +10,20 @@ blinky-dbg 0x4 ARM-ADS - 6130001::V6.13.1::.\ARMCLANG + 6160000::V6.16::ARMCLANG 1 - EFM32PG1B200F256GM48 - Silicon Labs - SiliconLabs.EFM32PG1B_DFP.5.5.0 - https://www.silabs.com/documents/public/cmsis-packs/ - IRAM(0x20000000,0x00008000) IROM(0x00000000,0x00020000) CPUTYPE("Cortex-M4") FPU2 CLOCK(12000000) ELITTLE + STM32C031C6Tx + STMicroelectronics + Keil.STM32C0xx_DFP.1.0.0 + https://www.keil.com/pack/ + IRAM(0x20000000,0x00003000) IROM(0x08000000,0x00008000) CPUTYPE("Cortex-M0+") CLOCK(12000000) ELITTLE - UL2CM3(-S0 -C0 -P0 -FD20000000 -FC8000 -FN1 -FF0GECKOP2 -FS00 -FL020000 -FP0($$Device:EFM32PG1B200F256GM48$Flash\GECKOP2.FLM)) + UL2CM3(-S0 -C0 -P0 -FD20000000 -FC1000 -FN1 -FF0STM32C0x_32 -FS08000000 -FL08000 -FP0($$Device:STM32C031C6Tx$CMSIS\Flash\STM32C0x_32.FLM)) 0 - $$Device:EFM32PG1B200F256GM48$Device\EFM32PG1B\Include\em_device.h + $$Device:STM32C031C6Tx$Drivers\CMSIS\Device\ST\STM32C0xx\Include\stm32c0xx.h @@ -33,7 +33,7 @@ - $$Device:EFM32PG1B200F256GM48$SVD\EFM32PG1B\EFM32PG1B200F256GM48.svd + $$Device:STM32C031C6Tx$CMSIS\SVD\STM32C031.svd 0 0 @@ -89,7 +89,7 @@ 0 0 - 1 + 0 @@ -110,13 +110,13 @@ SARMCM3.DLL - -MPU - DCM.DLL - -pCM4 + -REMAP-MPU + DARMCM1.DLL + -pCM0+ SARMCM3.DLL - -MPU - TCM.DLL - -pCM4 + -MPU + TARMCM1.DLL + -pCM0+ @@ -174,7 +174,7 @@ 1 0 0 - "Cortex-M4" + "Cortex-M0+" 0 0 @@ -183,8 +183,9 @@ 1 0 0 - 2 + 0 0 + 0 0 0 8 @@ -245,12 +246,12 @@ 0 0x20000000 - 0x8000 + 0x3000 1 - 0x0 - 0x20000 + 0x8000000 + 0x8000 0 @@ -274,8 +275,8 @@ 1 - 0x0 - 0x20000 + 0x8000000 + 0x8000 1 @@ -300,7 +301,7 @@ 0 0x20000000 - 0x8000 + 0x3000 0 @@ -312,7 +313,7 @@ 0 - 7 + 1 0 0 1 @@ -324,7 +325,7 @@ 3 0 1 - 1 + 0 0 0 3 @@ -336,9 +337,9 @@ 0 - EFM32PG1B200F256GM48=1 __FPU_PRESENT + - ..\..;..\..\..\..\..\include;..\..\..\..\..\ports\arm-cm\qv\armclang;..\..\..\..\..\3rd_party\CMSIS\Include;..\..\..\..\..\3rd_party\efm32pg1b + ..\..;..\..\..\..\..\include;..\..\..\..\..\ports\arm-cm\qv\armclang;..\..\..\..\..\3rd_party\CMSIS\Include;..\..\..\..\..\3rd_party\nucleo-c031c6 @@ -351,7 +352,7 @@ 0 1 0 - 0 + 4 Stack_Size=2048 Heap_Size=16 @@ -360,7 +361,7 @@ - 1 + 0 0 0 0 @@ -369,7 +370,7 @@ 0x00000000 0x20000000 - + .\blinky-qv.sct --entry Reset_Handler @@ -380,7 +381,7 @@ - Applicatioin + Source Code bsp.c @@ -388,14 +389,9 @@ ..\bsp.c - blinky.c - 1 - ..\..\blinky.c - - - main.c - 1 - ..\..\main.c + bsp.h + 5 + ..\..\bsp.h blinky.h @@ -403,54 +399,39 @@ ..\..\blinky.h - qstamp.c + main.c 1 - ..\..\..\..\..\include\qstamp.c + ..\..\main.c + + + blinky.c + 1 + ..\..\blinky.c - efm32pg1b + nucleo-c031c6 - startup_efm32pg1b.s + stm32c0xx.h + 5 + ..\..\..\..\..\3rd_party\nucleo-c031c6\stm32c0xx.h + + + stm32c031xx.h + 5 + ..\..\..\..\..\3rd_party\nucleo-c031c6\stm32c031xx.h + + + system_stm32c0xx.c + 1 + ..\..\..\..\..\3rd_party\nucleo-c031c6\system_stm32c0xx.c + + + startup_stm32c031xx.s 2 - ..\..\..\..\..\3rd_party\efm32pg1b\arm\startup_efm32pg1b.s - - - em_cmu.c - 1 - ..\..\..\..\..\3rd_party\efm32pg1b\em_cmu.c - - - em_emu.c - 1 - ..\..\..\..\..\3rd_party\efm32pg1b\em_emu.c - - - em_gpio.c - 1 - ..\..\..\..\..\3rd_party\efm32pg1b\em_gpio.c - - - em_int.c - 1 - ..\..\..\..\..\3rd_party\efm32pg1b\em_int.c - - - em_rtcc.c - 1 - ..\..\..\..\..\3rd_party\efm32pg1b\em_rtcc.c - - - em_system.c - 1 - ..\..\..\..\..\3rd_party\efm32pg1b\em_system.c - - - system_efm32pg1b.c - 1 - ..\..\..\..\..\3rd_party\efm32pg1b\system_efm32pg1b.c + ..\..\..\..\..\3rd_party\nucleo-c031c6\arm\startup_stm32c031xx.s @@ -527,11 +508,31 @@ QP_port + + qep_port.h + 5 + ..\..\..\..\..\ports\arm-cm\qv\armclang\qep_port.h + + + qf_port.h + 5 + ..\..\..\..\..\ports\arm-cm\qv\armclang\qf_port.h + + + qs_port.h + 5 + ..\..\..\..\..\ports\arm-cm\qv\armclang\qs_port.h + qv_port.c 1 ..\..\..\..\..\ports\arm-cm\qv\armclang\qv_port.c + + qv_port.h + 5 + ..\..\..\..\..\ports\arm-cm\qv\armclang\qv_port.h + @@ -595,7 +596,7 @@ 2 2 2 - 2 + 0 @@ -626,6 +627,11 @@ 1 ..\..\..\..\..\src\qs\qs_rx.c + + qstamp.c + 1 + ..\..\..\..\..\src\qs\qstamp.c +
@@ -634,20 +640,20 @@ blinky-rel 0x4 ARM-ADS - 6130001::V6.13.1::.\ARMCLANG + 6160000::V6.16::ARMCLANG 1 - EFM32PG1B200F256GM48 - Silicon Labs - SiliconLabs.EFM32PG1B_DFP.5.5.0 - https://www.silabs.com/documents/public/cmsis-packs/ - IRAM(0x20000000,0x00008000) IROM(0x00000000,0x00020000) CPUTYPE("Cortex-M4") FPU2 CLOCK(12000000) ELITTLE + STM32C031C6Tx + STMicroelectronics + Keil.STM32C0xx_DFP.1.0.0 + https://www.keil.com/pack/ + IRAM(0x20000000,0x00003000) IROM(0x08000000,0x00008000) CPUTYPE("Cortex-M0+") CLOCK(12000000) ELITTLE - UL2CM3(-S0 -C0 -P0 -FD20000000 -FC8000 -FN1 -FF0GECKOP2 -FS00 -FL020000 -FP0($$Device:EFM32PG1B200F256GM48$Flash\GECKOP2.FLM)) + UL2CM3(-S0 -C0 -P0 -FD20000000 -FC1000 -FN1 -FF0STM32C0x_32 -FS08000000 -FL08000 -FP0($$Device:STM32C031C6Tx$CMSIS\Flash\STM32C0x_32.FLM)) 0 - $$Device:EFM32PG1B200F256GM48$Device\EFM32PG1B\Include\em_device.h + $$Device:STM32C031C6Tx$Drivers\CMSIS\Device\ST\STM32C0xx\Include\stm32c0xx.h @@ -657,7 +663,7 @@ - $$Device:EFM32PG1B200F256GM48$SVD\EFM32PG1B\EFM32PG1B200F256GM48.svd + $$Device:STM32C031C6Tx$CMSIS\SVD\STM32C031.svd 0 0 @@ -713,7 +719,7 @@ 0 0 - 1 + 0 @@ -734,13 +740,13 @@ SARMCM3.DLL - -MPU - DCM.DLL - -pCM4 + -REMAP-MPU + DARMCM1.DLL + -pCM0+ SARMCM3.DLL - -MPU - TCM.DLL - -pCM4 + -MPU + TARMCM1.DLL + -pCM0+ @@ -758,11 +764,11 @@ 0 1 1 - 4096 + 4097 1 BIN\UL2CM3.DLL - "" () + @@ -798,7 +804,7 @@ 1 0 0 - "Cortex-M4" + "Cortex-M0+" 0 0 @@ -807,8 +813,9 @@ 1 0 0 - 2 + 0 0 + 0 0 0 8 @@ -869,12 +876,12 @@ 0 0x20000000 - 0x8000 + 0x3000 1 - 0x0 - 0x20000 + 0x8000000 + 0x8000 0 @@ -898,8 +905,8 @@ 1 - 0x0 - 0x20000 + 0x8000000 + 0x8000 1 @@ -924,7 +931,7 @@ 0 0x20000000 - 0x8000 + 0x3000 0 @@ -936,7 +943,7 @@ 0 - 7 + 6 0 0 1 @@ -948,21 +955,21 @@ 3 0 1 - 1 + 0 0 0 3 3 - 1 - 1 + 0 + 0 0 0 0 - NDEBUG EFM32PG1B200F256GM48=1 __FPU_PRESENT + NDEBUG - ..\..;..\..\..\..\..\include;..\..\..\..\..\ports\arm-cm\qv\armclang;..\..\..\..\..\3rd_party\CMSIS\Include;..\..\..\..\..\3rd_party\efm32pg1b + ..\..;..\..\..\..\..\include;..\..\..\..\..\ports\arm-cm\qv\armclang;..\..\..\..\..\3rd_party\CMSIS\Include;..\..\..\..\..\3rd_party\nucleo-c031c6 @@ -975,7 +982,7 @@ 0 1 0 - 0 + 4 Stack_Size=2048 Heap_Size=16 @@ -984,7 +991,7 @@ - 1 + 0 0 0 0 @@ -993,7 +1000,7 @@ 0x00000000 0x20000000 - blinky-qv.sct + .\blinky-qv.sct --entry Reset_Handler @@ -1004,7 +1011,7 @@ - Applicatioin + Source Code bsp.c @@ -1012,14 +1019,9 @@ ..\bsp.c - blinky.c - 1 - ..\..\blinky.c - - - main.c - 1 - ..\..\main.c + bsp.h + 5 + ..\..\bsp.h blinky.h @@ -1027,54 +1029,39 @@ ..\..\blinky.h - qstamp.c + main.c 1 - ..\..\..\..\..\include\qstamp.c + ..\..\main.c + + + blinky.c + 1 + ..\..\blinky.c - efm32pg1b + nucleo-c031c6 - startup_efm32pg1b.s + stm32c0xx.h + 5 + ..\..\..\..\..\3rd_party\nucleo-c031c6\stm32c0xx.h + + + stm32c031xx.h + 5 + ..\..\..\..\..\3rd_party\nucleo-c031c6\stm32c031xx.h + + + system_stm32c0xx.c + 1 + ..\..\..\..\..\3rd_party\nucleo-c031c6\system_stm32c0xx.c + + + startup_stm32c031xx.s 2 - ..\..\..\..\..\3rd_party\efm32pg1b\arm\startup_efm32pg1b.s - - - em_cmu.c - 1 - ..\..\..\..\..\3rd_party\efm32pg1b\em_cmu.c - - - em_emu.c - 1 - ..\..\..\..\..\3rd_party\efm32pg1b\em_emu.c - - - em_gpio.c - 1 - ..\..\..\..\..\3rd_party\efm32pg1b\em_gpio.c - - - em_int.c - 1 - ..\..\..\..\..\3rd_party\efm32pg1b\em_int.c - - - em_rtcc.c - 1 - ..\..\..\..\..\3rd_party\efm32pg1b\em_rtcc.c - - - em_system.c - 1 - ..\..\..\..\..\3rd_party\efm32pg1b\em_system.c - - - system_efm32pg1b.c - 1 - ..\..\..\..\..\3rd_party\efm32pg1b\system_efm32pg1b.c + ..\..\..\..\..\3rd_party\nucleo-c031c6\arm\startup_stm32c031xx.s @@ -1151,11 +1138,31 @@ QP_port + + qep_port.h + 5 + ..\..\..\..\..\ports\arm-cm\qv\armclang\qep_port.h + + + qf_port.h + 5 + ..\..\..\..\..\ports\arm-cm\qv\armclang\qf_port.h + + + qs_port.h + 5 + ..\..\..\..\..\ports\arm-cm\qv\armclang\qs_port.h + qv_port.c 1 ..\..\..\..\..\ports\arm-cm\qv\armclang\qv_port.c + + qv_port.h + 5 + ..\..\..\..\..\ports\arm-cm\qv\armclang\qv_port.h + @@ -1219,7 +1226,7 @@ 2 2 2 - 2 + 0 @@ -1250,6 +1257,11 @@ 1 ..\..\..\..\..\src\qs\qs_rx.c + + qstamp.c + 1 + ..\..\..\..\..\src\qs\qstamp.c + @@ -1258,20 +1270,20 @@ blinky-spy 0x4 ARM-ADS - 6130001::V6.13.1::.\ARMCLANG + 6160000::V6.16::ARMCLANG 1 - EFM32PG1B200F256GM48 - Silicon Labs - SiliconLabs.EFM32PG1B_DFP.5.5.0 - https://www.silabs.com/documents/public/cmsis-packs/ - IRAM(0x20000000,0x00008000) IROM(0x00000000,0x00020000) CPUTYPE("Cortex-M4") FPU2 CLOCK(12000000) ELITTLE + STM32C031C6Tx + STMicroelectronics + Keil.STM32C0xx_DFP.1.0.0 + https://www.keil.com/pack/ + IRAM(0x20000000,0x00003000) IROM(0x08000000,0x00008000) CPUTYPE("Cortex-M0+") CLOCK(12000000) ELITTLE - UL2CM3(-S0 -C0 -P0 -FD20000000 -FC8000 -FN1 -FF0GECKOP2 -FS00 -FL020000 -FP0($$Device:EFM32PG1B200F256GM48$Flash\GECKOP2.FLM)) + UL2CM3(-S0 -C0 -P0 -FD20000000 -FC1000 -FN1 -FF0STM32C0x_32 -FS08000000 -FL08000 -FP0($$Device:STM32C031C6Tx$CMSIS\Flash\STM32C0x_32.FLM)) 0 - $$Device:EFM32PG1B200F256GM48$Device\EFM32PG1B\Include\em_device.h + $$Device:STM32C031C6Tx$Drivers\CMSIS\Device\ST\STM32C0xx\Include\stm32c0xx.h @@ -1281,7 +1293,7 @@ - $$Device:EFM32PG1B200F256GM48$SVD\EFM32PG1B\EFM32PG1B200F256GM48.svd + $$Device:STM32C031C6Tx$CMSIS\SVD\STM32C031.svd 0 0 @@ -1337,7 +1349,7 @@ 0 0 - 1 + 0 @@ -1358,13 +1370,13 @@ SARMCM3.DLL - -MPU - DCM.DLL - -pCM4 + -REMAP-MPU + DARMCM1.DLL + -pCM0+ SARMCM3.DLL - -MPU - TCM.DLL - -pCM4 + -MPU + TARMCM1.DLL + -pCM0+ @@ -1386,7 +1398,7 @@ 1 BIN\UL2CM3.DLL - "" () + @@ -1422,7 +1434,7 @@ 1 0 0 - "Cortex-M4" + "Cortex-M0+" 0 0 @@ -1431,8 +1443,9 @@ 1 0 0 - 2 + 0 0 + 0 0 0 8 @@ -1493,12 +1506,12 @@ 0 0x20000000 - 0x8000 + 0x3000 1 - 0x0 - 0x20000 + 0x8000000 + 0x8000 0 @@ -1522,8 +1535,8 @@ 1 - 0x0 - 0x20000 + 0x8000000 + 0x8000 1 @@ -1548,7 +1561,7 @@ 0 0x20000000 - 0x8000 + 0x3000 0 @@ -1560,7 +1573,7 @@ 0 - 7 + 2 0 0 1 @@ -1572,7 +1585,7 @@ 3 0 1 - 1 + 0 0 0 3 @@ -1584,9 +1597,9 @@ 0 - Q_SPY EFM32PG1B200F256GM48=1 __FPU_PRESENT + Q_SPY - ..\..;..\..\..\..\..\include;..\..\..\..\..\ports\arm-cm\qv\armclang;..\..\..\..\..\3rd_party\CMSIS\Include;..\..\..\..\..\3rd_party\efm32pg1b + ..\..;..\..\..\..\..\include;..\..\..\..\..\ports\arm-cm\qv\armclang;..\..\..\..\..\3rd_party\CMSIS\Include;..\..\..\..\..\3rd_party\nucleo-c031c6 @@ -1599,7 +1612,7 @@ 0 1 0 - 0 + 4 Stack_Size=2048 Heap_Size=16 @@ -1608,7 +1621,7 @@ - 1 + 0 0 0 0 @@ -1617,7 +1630,7 @@ 0x00000000 0x20000000 - + .\blinky-qv.sct --entry Reset_Handler @@ -1628,7 +1641,7 @@ - Applicatioin + Source Code bsp.c @@ -1636,14 +1649,9 @@ ..\bsp.c - blinky.c - 1 - ..\..\blinky.c - - - main.c - 1 - ..\..\main.c + bsp.h + 5 + ..\..\bsp.h blinky.h @@ -1651,54 +1659,39 @@ ..\..\blinky.h - qstamp.c + main.c 1 - ..\..\..\..\..\include\qstamp.c + ..\..\main.c + + + blinky.c + 1 + ..\..\blinky.c - efm32pg1b + nucleo-c031c6 - startup_efm32pg1b.s + stm32c0xx.h + 5 + ..\..\..\..\..\3rd_party\nucleo-c031c6\stm32c0xx.h + + + stm32c031xx.h + 5 + ..\..\..\..\..\3rd_party\nucleo-c031c6\stm32c031xx.h + + + system_stm32c0xx.c + 1 + ..\..\..\..\..\3rd_party\nucleo-c031c6\system_stm32c0xx.c + + + startup_stm32c031xx.s 2 - ..\..\..\..\..\3rd_party\efm32pg1b\arm\startup_efm32pg1b.s - - - em_cmu.c - 1 - ..\..\..\..\..\3rd_party\efm32pg1b\em_cmu.c - - - em_emu.c - 1 - ..\..\..\..\..\3rd_party\efm32pg1b\em_emu.c - - - em_gpio.c - 1 - ..\..\..\..\..\3rd_party\efm32pg1b\em_gpio.c - - - em_int.c - 1 - ..\..\..\..\..\3rd_party\efm32pg1b\em_int.c - - - em_rtcc.c - 1 - ..\..\..\..\..\3rd_party\efm32pg1b\em_rtcc.c - - - em_system.c - 1 - ..\..\..\..\..\3rd_party\efm32pg1b\em_system.c - - - system_efm32pg1b.c - 1 - ..\..\..\..\..\3rd_party\efm32pg1b\system_efm32pg1b.c + ..\..\..\..\..\3rd_party\nucleo-c031c6\arm\startup_stm32c031xx.s @@ -1775,11 +1768,31 @@ QP_port + + qep_port.h + 5 + ..\..\..\..\..\ports\arm-cm\qv\armclang\qep_port.h + + + qf_port.h + 5 + ..\..\..\..\..\ports\arm-cm\qv\armclang\qf_port.h + + + qs_port.h + 5 + ..\..\..\..\..\ports\arm-cm\qv\armclang\qs_port.h + qv_port.c 1 ..\..\..\..\..\ports\arm-cm\qv\armclang\qv_port.c + + qv_port.h + 5 + ..\..\..\..\..\ports\arm-cm\qv\armclang\qv_port.h + @@ -1805,6 +1818,11 @@ 1 ..\..\..\..\..\src\qs\qs_rx.c + + qstamp.c + 1 + ..\..\..\..\..\src\qs\qstamp.c + diff --git a/examples/arm-cm/blinky_nucleo-c031c6/qv/bsp.c b/examples/arm-cm/blinky_nucleo-c031c6/qv/bsp.c new file mode 100644 index 00000000..d1dafe85 --- /dev/null +++ b/examples/arm-cm/blinky_nucleo-c031c6/qv/bsp.c @@ -0,0 +1,241 @@ +//============================================================================ +// Product: Blinky example, NUCLEO-C031C6 board, QV kernel +// Last updated for version 7.3.0 +// Last updated on 2023-08-15 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. +// +// This program is open source software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Alternatively, this program may be distributed and modified under the +// terms of Quantum Leaps commercial licenses, which expressly supersede +// the GNU General Public License and are specifically designed for +// licensees interested in retaining the proprietary status of their code. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Contact information: +// +// +//============================================================================ +#include "qpc.h" // QP/C real-time embedded framework +#include "blinky.h" // Blinky Application interface +#include "bsp.h" // Board Support Package + +#include "stm32c0xx.h" // CMSIS-compliant header file for the MCU used +// add other drivers if necessary... + +//Q_DEFINE_THIS_FILE // define the name of this file for assertions + +// Local-scope defines ----------------------------------------------------- +// LED pins available on the board (just one user LED LD4--Green on PA.5) +#define LD4_PIN 5U + +// Button pins available on the board (just one user Button B1 on PC.13) +#define B1_PIN 13U + +#ifdef Q_SPY +#error The Simple Blinky Application does not support Spy build configuration +#endif + +//============================================================================ +// Error handler and ISRs... + +Q_NORETURN Q_onError(char const *module, int_t const id) { + // NOTE: this implementation of the assertion handler is intended only + // for debugging and MUST be changed for deployment of the application + // (assuming that you ship your production code with assertions enabled). + Q_UNUSED_PAR(module); + Q_UNUSED_PAR(id); + QS_ASSERTION(module, id, (uint32_t)10000U); + +#ifndef NDEBUG + // light up the user LED + GPIOA->BSRR = (1U << LD4_PIN); // turn LED on + // for debugging, hang on in an endless loop... + for (;;) { + } +#endif + + NVIC_SystemReset(); +} +//............................................................................ +void assert_failed(char const * const module, int_t const id); // prototype +void assert_failed(char const * const module, int_t const id) { + Q_onError(module, id); +} + +//............................................................................ +void SysTick_Handler(void); // prototype +void SysTick_Handler(void) { + QTIMEEVT_TICK_X(0U, &l_SysTick_Handler); // time events at rate 0 + QV_ARM_ERRATUM_838869(); +} + +//============================================================================ +// BSP functions... + +void BSP_init(void) { + // Configure the MPU to prevent NULL-pointer dereferencing ... + MPU->RBAR = 0x0U // base address (NULL) + | MPU_RBAR_VALID_Msk // valid region + | (MPU_RBAR_REGION_Msk & 7U); // region #7 + MPU->RASR = (7U << MPU_RASR_SIZE_Pos) // 2^(7+1) region + | (0x0U << MPU_RASR_AP_Pos) // no-access region + | MPU_RASR_ENABLE_Msk; // region enable + MPU->CTRL = MPU_CTRL_PRIVDEFENA_Msk // enable background region + | MPU_CTRL_ENABLE_Msk; // enable the MPU + __ISB(); + __DSB(); + + // NOTE: SystemInit() has been already called from the startup code + // but SystemCoreClock needs to be updated + SystemCoreClockUpdate(); + + // enable GPIOA clock port for the LED LD4 + RCC->IOPENR |= (1U << 0U); + + // set all used GPIOA pins as push-pull output, no pull-up, pull-down + GPIOA->MODER &= ~(3U << 2U*LD4_PIN); + GPIOA->MODER |= (1U << 2U*LD4_PIN); + GPIOA->OTYPER &= ~(1U << LD4_PIN); + GPIOA->OSPEEDR &= ~(3U << 2U*LD4_PIN); + GPIOA->OSPEEDR |= (1U << 2U*LD4_PIN); + GPIOA->PUPDR &= ~(3U << 2U*LD4_PIN); + + // enable GPIOC clock port for the Button B1 + RCC->IOPENR |= (1U << 2U); + + // configure Button B1 pin on GPIOC as input, no pull-up, pull-down + GPIOC->MODER &= ~(3U << 2U*B1_PIN); + GPIOC->PUPDR &= ~(3U << 2U*B1_PIN); +} +//............................................................................ +void BSP_start(void) { + // initialize event pools + static QF_MPOOL_EL(QEvt) smlPoolSto[10]; + QF_poolInit(smlPoolSto, sizeof(smlPoolSto), sizeof(smlPoolSto[0])); + + // initialize publish-subscribe + static QSubscrList subscrSto[MAX_PUB_SIG]; + QActive_psInit(subscrSto, Q_DIM(subscrSto)); + + // instantiate and start AOs/threads... + + static QEvt const *blinkyQueueSto[10]; + Blinky_ctor(); + QACTIVE_START(AO_Blinky, + 1U, // QP prio. of the AO + blinkyQueueSto, // event queue storage + Q_DIM(blinkyQueueSto), // queue length [events] + (void *)0, 0U, // no stack storage + (void *)0); // no initialization param +} +//............................................................................ +void BSP_ledOn() { + GPIOA->BSRR = (1U << LD4_PIN); // turn LED on +} +//............................................................................ +void BSP_ledOff() { + GPIOA->BSRR = (1U << (LD4_PIN + 16U)); // turn LED off +} +//............................................................................ +void BSP_terminate(int16_t result) { + Q_UNUSED_PAR(result); +} + +//============================================================================ +// QF callbacks... +void QF_onStartup(void) { + // set up the SysTick timer to fire at BSP_TICKS_PER_SEC rate + SysTick_Config(SystemCoreClock / BSP_TICKS_PER_SEC); + + // assign all priority bits for preemption-prio. and none to sub-prio. + NVIC_SetPriorityGrouping(0U); + + // set priorities of ALL ISRs used in the system, see NOTE1 + NVIC_SetPriority(USART2_IRQn, 0); // kernel UNAWARE interrupt + NVIC_SetPriority(EXTI0_1_IRQn, QF_AWARE_ISR_CMSIS_PRI + 0U); + NVIC_SetPriority(SysTick_IRQn, QF_AWARE_ISR_CMSIS_PRI + 1U); + // ... + + // enable IRQs... + NVIC_EnableIRQ(EXTI0_1_IRQn); + +#ifdef Q_SPY + NVIC_EnableIRQ(USART2_IRQn); // UART2 interrupt used for QS-RX +#endif +} +//............................................................................ +void QF_onCleanup(void) { +} +//............................................................................ +void QV_onIdle(void) { // called with interrupts DISABLED, see NOTE01 + + // toggle an LED on and then off (not enough LEDs, see NOTE02) + //GPIOA->BSRR = (1U << LD4_PIN); // turn LED[n] on + //GPIOA->BSRR = (1U << (LD4_PIN + 16U)); // turn LED[n] off + +#ifdef Q_SPY +#elif defined NDEBUG + // Put the CPU and peripherals to the low-power mode. + // you might need to customize the clock management for your application, + // see the datasheet for your particular Cortex-M MCU. + // + // !!!CAUTION!!! + // QV_CPU_SLEEP() contains the WFI instruction, which stops the CPU + // clock, which unfortunately disables the JTAG port, so the ST-Link + // debugger can no longer connect to the board. For that reason, the call + // to QV_CPU_SLEEP() has to be used with CAUTION. + // + // NOTE: If you find your board "frozen" like this, strap BOOT0 to VDD and + // reset the board, then connect with ST-Link Utilities and erase the part. + // The trick with BOOT(0) is it gets the part to run the System Loader + // instead of your broken code. When done disconnect BOOT0, and start over. + // + //QV_CPU_SLEEP(); // atomically go to sleep and enable interrupts + QF_INT_ENABLE(); // for now, just enable interrupts +#else + QF_INT_ENABLE(); // just enable interrupts +#endif +} + +//============================================================================ +// NOTE1: +// The QF_AWARE_ISR_CMSIS_PRI constant from the QF port specifies the highest +// ISR priority that is disabled by the QF framework. The value is suitable +// for the NVIC_SetPriority() CMSIS function. +// +// Only ISRs prioritized at or below the QF_AWARE_ISR_CMSIS_PRI level (i.e., +// with the numerical values of priorities equal or higher than +// QF_AWARE_ISR_CMSIS_PRI) are allowed to call the QV_ISR_ENTRY/ +// QV_ISR_ENTRY macros or any other QF/QV services. These ISRs are +// "QF-aware". +// +// Conversely, any ISRs prioritized above the QF_AWARE_ISR_CMSIS_PRI priority +// level (i.e., with the numerical values of priorities less than +// QF_AWARE_ISR_CMSIS_PRI) are never disabled and are not aware of the kernel. +// Such "QF-unaware" ISRs cannot call ANY QF/QV services. In particular they +// can NOT call the macros QV_ISR_ENTRY/QV_ISR_ENTRY. The only mechanism +// by which a "QF-unaware" ISR can communicate with the QF framework is by +// triggering a "QF-aware" ISR, which can post/publish events. +// +// NOTE2: +// The User LED is used to visualize the idle loop activity. The brightness +// of the LED is proportional to the frequency of the idle loop. +// Please note that the LED is toggled with interrupts locked, so no interrupt +// execution time contributes to the brightness of the User LED. +// diff --git a/examples/arm-cm/blinky_nucleo-c031c6/qv/gnu/Makefile b/examples/arm-cm/blinky_nucleo-c031c6/qv/gnu/Makefile new file mode 100644 index 00000000..ca1a4332 --- /dev/null +++ b/examples/arm-cm/blinky_nucleo-c031c6/qv/gnu/Makefile @@ -0,0 +1,313 @@ +############################################################################## +# Product: Makefile for QP/C on NUCLEO-C031C6, QV kernel, GNU-ARM +# Last Updated for Version: 7.3.0 +# Date of the Last Update: 2023-05-26 +# +# Q u a n t u m L e a P s +# ------------------------ +# Modern Embedded Software +# +# Copyright (C) 2005 Quantum Leaps, LLC. +# +# This program is open source software: you can redistribute it and/or +# modify it under the terms of the GNU General Public License as published +# by the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Alternatively, this program may be distributed and modified under the +# terms of Quantum Leaps commercial licenses, which expressly supersede +# the GNU General Public License and are specifically designed for +# licensees interested in retaining the proprietary status of their code. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# +# Contact information: +# +# +############################################################################## +# examples of invoking this Makefile: +# building configurations: Debug (default), Release, and Spy +# make +# make CONF=rel +# make CONF=spy +# +# cleaning configurations: Debug (default), Release, and Spy +# make clean +# make CONF=rel clean +# make CONF=spy clean +# +# NOTE: +# To use this Makefile on Windows, you will need the GNU make utility, which +# is included in the Qtools collection for Windows, see: +# https://github.com/QuantumLeaps/qtools + +#----------------------------------------------------------------------------- +# project name +# +PROJECT := blinky-qv + +#----------------------------------------------------------------------------- +# project directories +# + +# location of the QP/C framework (if not provided in an environemnt var.) +ifeq ($(QPC),) +QPC := ../../../../.. +endif + +# QP port used in this project +QP_PORT_DIR := $(QPC)/ports/arm-cm/qv/gnu + +# list of all source directories used by this project +VPATH = \ + .. \ + ../.. \ + $(QPC)/src/qf \ + $(QPC)/src/qv \ + $(QPC)/src/qs \ + $(QP_PORT_DIR) \ + $(QPC)/3rd_party/nucleo-c031c6 \ + $(QPC)/3rd_party/nucleo-c031c6/gnu + +# list of all include directories needed by this project +INCLUDES = \ + -I../.. \ + -I$(QPC)/include \ + -I$(QP_PORT_DIR) \ + -I$(QPC)/3rd_party/CMSIS/Include \ + -I$(QPC)/3rd_party/nucleo-c031c6 + +#----------------------------------------------------------------------------- +# files +# + +# assembler source files +ASM_SRCS := + +# C source files +C_SRCS := \ + bsp.c \ + main.c \ + blinky.c \ + system_stm32c0xx.c \ + startup_stm32c031xx.c + +# C++ source files +CPP_SRCS := + +OUTPUT := $(PROJECT) +LD_SCRIPT := $(PROJECT).ld + +QP_SRCS := \ + qep_hsm.c \ + qep_msm.c \ + qf_act.c \ + qf_actq.c \ + qf_defer.c \ + qf_dyn.c \ + qf_mem.c \ + qf_ps.c \ + qf_qact.c \ + qf_qeq.c \ + qf_qmact.c \ + qf_time.c \ + qv.c \ + qv_port.c + +QP_ASMS := + +QS_SRCS := \ + qs.c \ + qs_rx.c \ + qs_fp.c + +LIB_DIRS := +LIBS := + +# defines +DEFINES := -DSTM32C031xx + +# ARM CPU, ARCH, FPU, and Float-ABI types... +# ARM_CPU: [cortex-m0 | cortex-m0plus | cortex-m1 | cortex-m3 | cortex-m4] +# ARM_FPU: [ | vfp] +# FLOAT_ABI: [ | soft | softfp | hard] +# +ARM_CPU := -mcpu=cortex-m0plus +ARM_FPU := +FLOAT_ABI := + +#----------------------------------------------------------------------------- +# GNU-ARM toolset (NOTE: You need to adjust to your machine) +# see https://developer.arm.com/open-source/gnu-toolchain/gnu-rm/downloads +# +ifeq ($(GNU_ARM),) +GNU_ARM := $(QTOOLS)/gnu_arm-none-eabi +endif + +# make sure that the GNU-ARM toolset exists... +ifeq ("$(wildcard $(GNU_ARM))","") +$(error GNU_ARM toolset not found. Please adjust the Makefile) +endif + +CC := $(GNU_ARM)/bin/arm-none-eabi-gcc +CPP := $(GNU_ARM)/bin/arm-none-eabi-g++ +AS := $(GNU_ARM)/bin/arm-none-eabi-as +LINK := $(GNU_ARM)/bin/arm-none-eabi-gcc +BIN := $(GNU_ARM)/bin/arm-none-eabi-objcopy + +############################################################################## +# Typically you should not need to change anything below this line + +# basic utilities (included in QTools for Windows), see: +# https://www.state-machine.com/qtools + +MKDIR := mkdir +RM := rm + +#----------------------------------------------------------------------------- +# build options for various configurations for ARM Cortex-M +# + +# combine all the soruces... +C_SRCS += $(QP_SRCS) +ASM_SRCS += $(QP_ASMS) + +ifeq (rel, $(CONF)) # Release configuration .................................. + +BIN_DIR := rel + +ASFLAGS = $(ARM_CPU) $(ARM_FPU) $(ASM_CPU) $(ASM_FPU) + +CFLAGS = -c $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \ + -ffunction-sections -fdata-sections \ + -O2 $(INCLUDES) $(DEFINES) -DNDEBUG + +CPPFLAGS = -c $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \ + -ffunction-sections -fdata-sections -fno-rtti -fno-exceptions \ + -O2 $(INCLUDES) $(DEFINES) -DNDEBUG + +else ifeq (spy, $(CONF)) # Spy configuration ................................ + +BIN_DIR := spy + +C_SRCS += $(QS_SRCS) + +ASFLAGS = -g $(ARM_CPU) $(ARM_FPU) $(ASM_CPU) $(ASM_FPU) + +CFLAGS = -c -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \ + -ffunction-sections -fdata-sections \ + -O $(INCLUDES) $(DEFINES) -DQ_SPY + +CPPFLAGS = -c -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \ + -ffunction-sections -fdata-sections -fno-rtti -fno-exceptions \ + -O $(INCLUDES) $(DEFINES) -DQ_SPY + +else # default Debug configuration .......................................... + +BIN_DIR := dbg + +ASFLAGS = -g $(ARM_CPU) $(ARM_FPU) $(ASM_CPU) $(ASM_FPU) + +CFLAGS = -c -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \ + -ffunction-sections -fdata-sections \ + -O $(INCLUDES) $(DEFINES) + +CPPFLAGS = -c -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \ + -ffunction-sections -fdata-sections -fno-rtti -fno-exceptions \ + -O $(INCLUDES) $(DEFINES) + +endif # ...................................................................... + + +LINKFLAGS = -T$(LD_SCRIPT) $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb \ + -specs=nosys.specs -specs=nano.specs \ + -Wl,-Map,$(BIN_DIR)/$(OUTPUT).map,--cref,--gc-sections $(LIB_DIRS) + +ASM_OBJS := $(patsubst %.s,%.o, $(notdir $(ASM_SRCS))) +C_OBJS := $(patsubst %.c,%.o, $(notdir $(C_SRCS))) +CPP_OBJS := $(patsubst %.cpp,%.o,$(notdir $(CPP_SRCS))) + +TARGET_BIN := $(BIN_DIR)/$(OUTPUT).bin +TARGET_ELF := $(BIN_DIR)/$(OUTPUT).elf +ASM_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(ASM_OBJS)) +C_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(C_OBJS)) +C_DEPS_EXT := $(patsubst %.o, %.d, $(C_OBJS_EXT)) +CPP_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(CPP_OBJS)) +CPP_DEPS_EXT := $(patsubst %.o, %.d, $(CPP_OBJS_EXT)) + +# create $(BIN_DIR) if it does not exist +ifeq ("$(wildcard $(BIN_DIR))","") +$(shell $(MKDIR) $(BIN_DIR)) +endif + +#----------------------------------------------------------------------------- +# rules +# + +.PHONY : run norun flash + +ifeq ($(MAKECMDGOALS),norun) +all : $(TARGET_BIN) +norun : all +else +all : $(TARGET_BIN) run +endif + +$(TARGET_BIN): $(TARGET_ELF) + $(BIN) -O binary $< $@ + +$(TARGET_ELF) : $(ASM_OBJS_EXT) $(C_OBJS_EXT) $(CPP_OBJS_EXT) + $(CC) $(CFLAGS) $(QPC)/src/qs/qstamp.c -o $(BIN_DIR)/qstamp.o + $(LINK) $(LINKFLAGS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) + +$(BIN_DIR)/%.d : %.c + $(CC) -MM -MT $(@:.d=.o) $(CFLAGS) $< > $@ + +$(BIN_DIR)/%.d : %.cpp + $(CPP) -MM -MT $(@:.d=.o) $(CPPFLAGS) $< > $@ + +$(BIN_DIR)/%.o : %.s + $(AS) $(ASFLAGS) $< -o $@ + +$(BIN_DIR)/%.o : %.c + $(CC) $(CFLAGS) $< -o $@ + +$(BIN_DIR)/%.o : %.cpp + $(CPP) $(CPPFLAGS) $< -o $@ + +.PHONY : clean show + +# include dependency files only if our goal depends on their existence +ifneq ($(MAKECMDGOALS),clean) + ifneq ($(MAKECMDGOALS),show) +-include $(C_DEPS_EXT) $(CPP_DEPS_EXT) + endif +endif + + +clean: + -$(RM) $(BIN_DIR)/*.o \ + $(BIN_DIR)/*.d \ + $(BIN_DIR)/*.bin \ + $(BIN_DIR)/*.elf \ + $(BIN_DIR)/*.map + +show: + @echo PROJECT = $(PROJECT) + @echo CONF = $(CONF) + @echo DEFINES = $(DEFINES) + @echo ASM_FPU = $(ASM_FPU) + @echo ASM_SRCS = $(ASM_SRCS) + @echo C_SRCS = $(C_SRCS) + @echo CPP_SRCS = $(CPP_SRCS) + @echo ASM_OBJS_EXT = $(ASM_OBJS_EXT) + @echo C_OBJS_EXT = $(C_OBJS_EXT) + @echo C_DEPS_EXT = $(C_DEPS_EXT) + @echo CPP_DEPS_EXT = $(CPP_DEPS_EXT) + @echo TARGET_ELF = $(TARGET_ELF) diff --git a/examples/arm-cm/blinky_nucleo-c031c6/qv/gnu/blinky-qv.ld b/examples/arm-cm/blinky_nucleo-c031c6/qv/gnu/blinky-qv.ld new file mode 100644 index 00000000..4a3ba851 --- /dev/null +++ b/examples/arm-cm/blinky_nucleo-c031c6/qv/gnu/blinky-qv.ld @@ -0,0 +1,135 @@ +/***************************************************************************** +* Linker script for for STM32C031C6, GNU-ARM linker +* +* Q u a n t u m L e a P s +* ------------------------ +* Modern Embedded Software +* +* Copyright (C) 2005 Quantum Leaps, LLC . +* +* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +* +* This software is dual-licensed under the terms of the open source GNU +* General Public License version 3 (or any later version), or alternatively, +* under the terms of one of the closed source Quantum Leaps commercial +* licenses. +* +* The terms of the open source GNU General Public License version 3 +* can be found at: +* +* The terms of the closed source Quantum Leaps commercial licenses +* can be found at: +* +* Redistributions in source code must retain this top-level comment block. +* Plagiarizing this software to sidestep the license obligations is illegal. +* +* Contact information: +* +* +*****************************************************************************/ +OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm", "elf32-littlearm") +OUTPUT_ARCH(arm) +ENTRY(Reset_Handler) /* entry Point */ + +MEMORY { /* memory map of STM32C031C6 */ + ROM (rx) : ORIGIN = 0x08000000, LENGTH = 32K + RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 12K +} + +/* The size of the stack used by the application. NOTE: you need to adjust */ +STACK_SIZE = 2048; + +/* The size of the heap used by the application. NOTE: you need to adjust */ +HEAP_SIZE = 0; + +SECTIONS { + + .isr_vector : { /* the vector table goes FIRST into ROM */ + KEEP(*(.isr_vector)) /* vector table */ + . = ALIGN(4); + } >ROM + + .text : { /* code and constants */ + . = ALIGN(4); + *(.text) /* .text sections (code) */ + *(.text*) /* .text* sections (code) */ + *(.rodata) /* .rodata sections (constants, strings, etc.) */ + *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ + + KEEP (*(.init)) + KEEP (*(.fini)) + + . = ALIGN(4); + } >ROM + + .preinit_array : { + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array*)) + PROVIDE_HIDDEN (__preinit_array_end = .); + } >ROM + + .init_array : { + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array*)) + PROVIDE_HIDDEN (__init_array_end = .); + } >ROM + + .fini_array : { + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(.fini_array*)) + KEEP (*(SORT(.fini_array.*))) + PROVIDE_HIDDEN (__fini_array_end = .); + } >ROM + + _etext = .; /* global symbols at end of code */ + + .stack : { + __stack_start__ = .; + . = . + STACK_SIZE; + . = ALIGN(4); + __stack_end__ = .; + } >RAM + + .data : AT (_etext) { + __data_load = LOADADDR (.data); + __data_start = .; + *(.data) /* .data sections */ + *(.data*) /* .data* sections */ + . = ALIGN(4); + __data_end__ = .; + _edata = __data_end__; + } >RAM + + .bss : { + __bss_start__ = .; + *(.bss) + *(.bss*) + *(COMMON) + . = ALIGN(4); + _ebss = .; /* define a global symbol at bss end */ + __bss_end__ = .; + } >RAM + + __exidx_start = .; + .ARM.exidx : { *(.ARM.exidx* .gnu.linkonce.armexidx.*) } >RAM + __exidx_end = .; + + PROVIDE ( end = _ebss ); + PROVIDE ( _end = _ebss ); + PROVIDE ( __end__ = _ebss ); + + .heap : { + __heap_start__ = .; + . = . + HEAP_SIZE; + . = ALIGN(4); + __heap_end__ = .; + } >RAM + + /* Remove information from the standard libraries */ + /DISCARD/ : { + libc.a ( * ) + libm.a ( * ) + libgcc.a ( * ) + } +} diff --git a/examples/arm-cm/blinky_efm32-slstk3401a/qv/iar/blinky-qv.ewd b/examples/arm-cm/blinky_nucleo-c031c6/qv/iar/blinky-qv.ewd similarity index 94% rename from examples/arm-cm/blinky_efm32-slstk3401a/qv/iar/blinky-qv.ewd rename to examples/arm-cm/blinky_nucleo-c031c6/qv/iar/blinky-qv.ewd index b3ebdf84..b3712b65 100644 --- a/examples/arm-cm/blinky_efm32-slstk3401a/qv/iar/blinky-qv.ewd +++ b/examples/arm-cm/blinky_nucleo-c031c6/qv/iar/blinky-qv.ewd @@ -44,7 +44,7 @@ - - BILINK - 0 - - Coder 0 @@ -1076,9 +1090,13 @@ General 3 - 31 + 35 1 0 + - - - - - + + + + + ICCARM 2 - 36 + 37 1 0 - - - @@ -1743,13 +1748,9 @@ 0 + inputOutputBased - - BICOMP - 0 - - BUILDACTION 1 @@ -1762,17 +1763,13 @@ ILINK 0 - 23 + 27 1 0 - + + + + + + + + + @@ -2121,11 +2154,6 @@ - - BILINK - 0 - - Coder 0 @@ -2142,9 +2170,13 @@ General 3 - 31 + 35 1 1 + - - - - - + + + + + ICCARM 2 - 36 + 37 1 1 - - - @@ -2809,13 +2828,9 @@ 0 + inputOutputBased - - BICOMP - 0 - - BUILDACTION 1 @@ -2828,17 +2843,13 @@ ILINK 0 - 23 + 27 1 1 - + + + + + + + + + @@ -3187,11 +3234,6 @@ - - BILINK - 0 - - Coder 0 @@ -3218,32 +3260,20 @@ $PROJ_DIR$\..\..\main.c - - $PROJ_DIR$\..\..\..\..\..\include\qstamp.c - - efm32pg1b + nucleo-c031c6 - $PROJ_DIR$\..\..\..\..\..\3rd_party\efm32pg1b\em_assert.c + $PROJ_DIR$\..\..\..\..\..\3rd_party\nucleo-c031c6\iar\startup_stm32c031xx.s - $PROJ_DIR$\..\..\..\..\..\3rd_party\efm32pg1b\em_cmu.c + $PROJ_DIR$\..\..\..\..\..\3rd_party\nucleo-c031c6\stm32c031xx.h - $PROJ_DIR$\..\..\..\..\..\3rd_party\efm32pg1b\em_emu.c + $PROJ_DIR$\..\..\..\..\..\3rd_party\nucleo-c031c6\stm32c0xx.h - $PROJ_DIR$\..\..\..\..\..\3rd_party\efm32pg1b\em_gpio.c - - - $PROJ_DIR$\..\..\..\..\..\3rd_party\efm32pg1b\em_system.c - - - $PROJ_DIR$\..\..\..\..\..\3rd_party\efm32pg1b\iar\startup_efm32pg1b.s - - - $PROJ_DIR$\..\..\..\..\..\3rd_party\efm32pg1b\system_efm32pg1b.c + $PROJ_DIR$\..\..\..\..\..\3rd_party\nucleo-c031c6\system_stm32c0xx.c @@ -3270,7 +3300,7 @@ $PROJ_DIR$\..\..\..\..\..\src\qf\qf_mem.c - $PROJ_DIR$\..\..\..\..\..\src\qf\qf_pkg.h + $PROJ_DIR$\..\..\..\..\..\src\qf_pkg.h $PROJ_DIR$\..\..\..\..\..\src\qf\qf_ps.c @@ -3290,15 +3320,24 @@ $PROJ_DIR$\..\..\..\..\..\src\qv\qv.c - - $PROJ_DIR$\..\..\..\..\..\src\qv_pkg.h - QP_port + + $PROJ_DIR$\..\..\..\..\..\ports\arm-cm\qv\iar\qep_port.h + + + $PROJ_DIR$\..\..\..\..\..\ports\arm-cm\qv\iar\qf_port.h + + + $PROJ_DIR$\..\..\..\..\..\ports\arm-cm\qv\iar\qs_port.h + $PROJ_DIR$\..\..\..\..\..\ports\arm-cm\qv\iar\qv_port.c + + $PROJ_DIR$\..\..\..\..\..\ports\arm-cm\qv\iar\qv_port.h + QS @@ -3313,10 +3352,10 @@ $PROJ_DIR$\..\..\..\..\..\src\qs\qs_fp.c - $PROJ_DIR$\..\..\..\..\..\src\qs_pkg.h + $PROJ_DIR$\..\..\..\..\..\src\qs\qs_rx.c - $PROJ_DIR$\..\..\..\..\..\src\qs\qs_rx.c + $PROJ_DIR$\..\..\..\..\..\src\qs\qstamp.c diff --git a/examples/arm-cm/blinky_efm32-slstk3401a/qv/iar/blinky-qv.eww b/examples/arm-cm/blinky_nucleo-c031c6/qv/iar/blinky-qv.eww similarity index 100% rename from examples/arm-cm/blinky_efm32-slstk3401a/qv/iar/blinky-qv.eww rename to examples/arm-cm/blinky_nucleo-c031c6/qv/iar/blinky-qv.eww diff --git a/examples/arm-cm/blinky_nucleo-c031c6/qv/iar/blinky-qv.icf b/examples/arm-cm/blinky_nucleo-c031c6/qv/iar/blinky-qv.icf new file mode 100644 index 00000000..db057b16 --- /dev/null +++ b/examples/arm-cm/blinky_nucleo-c031c6/qv/iar/blinky-qv.icf @@ -0,0 +1,165 @@ +/*###ICF### Section handled by ICF editor, don't touch! ****/ +/*-Editor annotation file-*/ +/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_4.xml" */ +/*-Specials-*/ +define symbol __ICFEDIT_intvec_start__ = 0x08000000; +/*-Memory Regions-*/ +define symbol __ICFEDIT_region_IROM1_start__ = 0x08000000; +define symbol __ICFEDIT_region_IROM1_end__ = 0x08007FFF; +define symbol __ICFEDIT_region_IROM2_start__ = 0x0; +define symbol __ICFEDIT_region_IROM2_end__ = 0x0; +define symbol __ICFEDIT_region_EROM1_start__ = 0x0; +define symbol __ICFEDIT_region_EROM1_end__ = 0x0; +define symbol __ICFEDIT_region_EROM2_start__ = 0x0; +define symbol __ICFEDIT_region_EROM2_end__ = 0x0; +define symbol __ICFEDIT_region_EROM3_start__ = 0x0; +define symbol __ICFEDIT_region_EROM3_end__ = 0x0; +define symbol __ICFEDIT_region_IRAM1_start__ = 0x20000000; +define symbol __ICFEDIT_region_IRAM1_end__ = 0x20002FFF; +define symbol __ICFEDIT_region_IRAM2_start__ = 0x0; +define symbol __ICFEDIT_region_IRAM2_end__ = 0x0; +define symbol __ICFEDIT_region_ERAM1_start__ = 0x0; +define symbol __ICFEDIT_region_ERAM1_end__ = 0x0; +define symbol __ICFEDIT_region_ERAM2_start__ = 0x0; +define symbol __ICFEDIT_region_ERAM2_end__ = 0x0; +define symbol __ICFEDIT_region_ERAM3_start__ = 0x0; +define symbol __ICFEDIT_region_ERAM3_end__ = 0x0; +/*-Sizes-*/ +define symbol __ICFEDIT_size_cstack__ = 2048; +define symbol __ICFEDIT_size_proc_stack__ = 0x0; +define symbol __ICFEDIT_size_heap__ = 0; +/**** End of ICF editor section. ###ICF###*/ + +define memory mem with size = 4G; +define symbol use_IROM1 = (__ICFEDIT_region_IROM1_start__ != 0x0 || __ICFEDIT_region_IROM1_end__ != 0x0); +define symbol use_IROM2 = (__ICFEDIT_region_IROM2_start__ != 0x0 || __ICFEDIT_region_IROM2_end__ != 0x0); +define symbol use_EROM1 = (__ICFEDIT_region_EROM1_start__ != 0x0 || __ICFEDIT_region_EROM1_end__ != 0x0); +define symbol use_EROM2 = (__ICFEDIT_region_EROM2_start__ != 0x0 || __ICFEDIT_region_EROM2_end__ != 0x0); +define symbol use_EROM3 = (__ICFEDIT_region_EROM3_start__ != 0x0 || __ICFEDIT_region_EROM3_end__ != 0x0); +define symbol use_IRAM1 = (__ICFEDIT_region_IRAM1_start__ != 0x0 || __ICFEDIT_region_IRAM1_end__ != 0x0); +define symbol use_IRAM2 = (__ICFEDIT_region_IRAM2_start__ != 0x0 || __ICFEDIT_region_IRAM2_end__ != 0x0); +define symbol use_ERAM1 = (__ICFEDIT_region_ERAM1_start__ != 0x0 || __ICFEDIT_region_ERAM1_end__ != 0x0); +define symbol use_ERAM2 = (__ICFEDIT_region_ERAM2_start__ != 0x0 || __ICFEDIT_region_ERAM2_end__ != 0x0); +define symbol use_ERAM3 = (__ICFEDIT_region_ERAM3_start__ != 0x0 || __ICFEDIT_region_ERAM3_end__ != 0x0); + +if (use_IROM1) +{ + define region IROM1_region = mem:[from __ICFEDIT_region_IROM1_start__ to __ICFEDIT_region_IROM1_end__]; +} +else +{ + define region IROM1_region = []; +} + +if (use_IROM2) +{ + define region IROM2_region = mem:[from __ICFEDIT_region_IROM2_start__ to __ICFEDIT_region_IROM2_end__]; +} +else +{ + define region IROM2_region = []; +} +define region IROM_region = IROM1_region | IROM2_region; + +if (use_EROM1) +{ + define region EROM1_region = mem:[from __ICFEDIT_region_EROM1_start__ to __ICFEDIT_region_EROM1_end__]; +} +else +{ + define region EROM1_region = []; +} +if (use_EROM2) +{ + define region EROM2_region = mem:[from __ICFEDIT_region_EROM2_start__ to __ICFEDIT_region_EROM2_end__]; +} +else +{ + define region EROM2_region = []; +} +if (use_EROM3) +{ + define region EROM3_region = mem:[from __ICFEDIT_region_EROM3_start__ to __ICFEDIT_region_EROM3_end__]; +} +else +{ + define region EROM3_region = []; +} +define region EROM_region = EROM1_region | EROM2_region | EROM3_region; + +if (use_IRAM1) +{ + define region IRAM1_region = mem:[from __ICFEDIT_region_IRAM1_start__ to __ICFEDIT_region_IRAM1_end__]; +} +else +{ + define region IRAM1_region = []; +} +if (use_IRAM2) +{ + define region IRAM2_region = mem:[from __ICFEDIT_region_IRAM2_start__ to __ICFEDIT_region_IRAM2_end__]; +} +else +{ + define region IRAM2_region = []; +} +define region IRAM_region = IRAM1_region | IRAM2_region; + +if (use_ERAM1) +{ + define region ERAM1_region = mem:[from __ICFEDIT_region_ERAM1_start__ to __ICFEDIT_region_ERAM1_end__]; +} +else +{ + define region ERAM1_region = []; +} +if (use_ERAM2) +{ + define region ERAM2_region = mem:[from __ICFEDIT_region_ERAM2_start__ to __ICFEDIT_region_ERAM2_end__]; +} +else +{ + define region ERAM2_region = []; +} +if (use_ERAM3) +{ + define region ERAM3_region = mem:[from __ICFEDIT_region_ERAM3_start__ to __ICFEDIT_region_ERAM3_end__]; +} +else +{ + define region ERAM3_region = []; +} +define region ERAM_region = ERAM1_region | ERAM2_region | ERAM3_region; + +initialize by copy { readwrite }; +if (isdefinedsymbol(__USE_DLIB_PERTHREAD)) +{ + // Required in a multi-threaded application + initialize by copy with packing = none { section __DLIB_PERTHREAD }; +} + +place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec }; + +if (!isempty(IROM_region)) +{ + place in IROM_region { readonly }; +} + +if (!isempty(EROM_region)) +{ + place in EROM_region { readonly section application_specific_ro }; +} + +if (!isempty(IRAM_region)) +{ + define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { }; + define block PROC_STACK with alignment = 8, size = __ICFEDIT_size_proc_stack__ { }; + define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { }; + place at start of IRAM_region {block CSTACK }; /* <== Quantum Leaps */ + place in IRAM_region { readwrite, block PROC_STACK, block HEAP }; +} + +if (!isempty(ERAM_region)) +{ + place in ERAM_region { readwrite section application_specific_rw }; +} \ No newline at end of file diff --git a/examples/arm-cm/blinky_nucleo-c031c6/stm32-nucleo-c031c6.jpg b/examples/arm-cm/blinky_nucleo-c031c6/stm32-nucleo-c031c6.jpg new file mode 100644 index 00000000..6647e2d4 Binary files /dev/null and b/examples/arm-cm/blinky_nucleo-c031c6/stm32-nucleo-c031c6.jpg differ diff --git a/examples/arm-cm/dpp_efm32-slstk3401a/README.md b/examples/arm-cm/dpp_efm32-slstk3401a/README.md index 5aa38775..6ad849a4 100644 --- a/examples/arm-cm/dpp_efm32-slstk3401a/README.md +++ b/examples/arm-cm/dpp_efm32-slstk3401a/README.md @@ -1,5 +1,131 @@ -![STM32 EFM32-SLSTK3401A](../../../doxygen/images/bd_EFM32-SLSTK3401A.jpg) +> **NOTE** +This file is best viewed in a **markdown viewer**, such as the one built into GitHub. Markdown viewers are also available as plug-ins to popular Internet browsers. -Documentation for this example is available in the QP/C Manual at: +# DPP on EFM32-SLSTK3401A +This example demonstrates the [Dining Philosophers Problem (DPP) application](https://www.state-machine.com/qpc/tut_dpp.html) on the EFM32-SLSTK3401A board (ARM Cortex-M4F). + +

+
+EFM32-SLSTK3401A (Pearl Gecko) +

+ +## Features Demonstrated +- multiple cooperating active objects +- immutable (const) events +- mutable (dynamic) events +- time events +- direct event posting +- publish-subscribe event delivery +- cooperative QV kernel + + with ARM-KEIL toolchain + + with GNU-ARM toolchain + + with IAR-ARM toolchain +- preemptive run-to-completion QK kernel + + with ARM-KEIL toolchain + + with GNU-ARM toolchain + + with IAR-ARM toolchain +- preemptive dual-mode QXK kernel + + with ARM-KEIL toolchain + + with GNU-ARM toolchain + + with IAR-ARM toolchain + +## Build Configurations +- Debug +- Release +- Spy - software tracing with the built-in virtual COM port + +# Code Organization +``` +examples\arm-cm\dpp_efm32-slstk3401a +| ++---qk // preemptive QK kernel +| +---gnu // GNU-ARM toolchain +| | \---targetConfigs +| | Makefile // Makefile for GNU-ARM +| +---armclang // ARM/KEIL toolchain with Compiler 6 (ARM/CLANG) +| | dpp-qk.uvprojx // uVision project +| \---iar // IAR EWARM +| dpp-qk.eww // IAR EW-ARM workspace +| +\---qv // cooperative QK kernel +| +---gnu // GNU-ARM toolchain +| | \---targetConfigs +| | Makefile // Makefile for GNU-ARM +| +---armclang // ARM/KEIL toolchain with Compiler 6 (ARM/CLANG) +| | dpp-qv.uvprojx // uVision project +| \---iar // IAR EWARM +| dpp-qv.eww // IAR EW-ARM workspace +| ++---qxk // preemptive, dual-mode QXK kernel +| +---gnu // GNU-ARM toolchain +| | \---targetConfigs +| | Makefile // Makefile for GNU-ARM +| +---armclang // ARM/KEIL toolchain with Compiler 6 (ARM/CLANG) +| | dpp-qk.uvprojx // uVision project +| \---iar // IAR EWARM +| dpp-qk.eww // IAR EW-ARM workspace +| +``` + +# Builing the example + +### GNU/ARM +- open terminal window +- change to the desired directory (either `examples\arm-cm\dpp_efm32-slstk3401a\qk\gnu`, `examples\arm-cm\dpp_efm32-slstk3401a\qv\gnu`, or `examples\arm-cm\dpp_efm32-slstk3401a\qxk\gnu`) +- to build the default Debug configuration, type: + +``` +make +``` + +> **NOTE** +The `make` utility for Windows is provided in the QTools collection for Windows. + +- to build the Release configuration, type: + +``` +make CONF=rel +``` + +- to build the Spy configuration, type: + +``` +make CONF=spy +``` + + +### ARM/KEIL MDK +- Open the provided KEIL uVision project (either `dpp-qk.uvprojx`, `dpp-qv.uvprojx`, or `dpp-qxk.uvprojx`) +in Keil uVision IDE. Build/Debug/Download to the board from the IDE. +- Change the build configuration in the "Project Target" drop-down menu. + + +### IAR EWARM +- Open the provided IAR EWARM workspace (either `dpp-qk.eww`, `dpp-qv.eww`, or `dpp-qxk.eww`) +in IAR EWARM IDE. Build/Debug/Download to the board from the IDE. +- Change the build configuration in the "Project Configuration" drop-down menu. + + +# Tracing with QP/Spy +When the board is flashed with the Spy build configuration, it produces the QP/Spy software tracing output to the built-in virtual COM port of the TivaC LauchPad board. The trace is binary rather than ASCII, and therefore requires a special host-based application called QSPY. + +> **NOTE** QSPY host application is available in the QTools collection. + +To launch the QSPY host application: +- open terminal window +- type: + +``` +qspy -c COM5 +``` + +where "COM5" is an example virtual COM port enumerated by the board. You need to check the specific COM port number on your host computer using the Device Manager application, Ports (COM and LPT) section. + + +The following screen shot shows a typical output from QSPY: + +

+
+Typical QSPY output produced by the Spy build configuration +

-- https://www.state-machine.com/qpc/arm-cm_dpp_efm32-slstk3401a.html diff --git a/examples/arm-cm/dpp_efm32-slstk3401a/bsp.h b/examples/arm-cm/dpp_efm32-slstk3401a/bsp.h index 03ed1e11..da73dbfd 100644 --- a/examples/arm-cm/dpp_efm32-slstk3401a/bsp.h +++ b/examples/arm-cm/dpp_efm32-slstk3401a/bsp.h @@ -1,54 +1,49 @@ -/***************************************************************************** -* Product: DPP example -* Last updated for version 6.7.0 -* Last updated on 2019-12-18 -* -* Q u a n t u m L e a P s -* ------------------------ -* Modern Embedded Software -* -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* -* -*****************************************************************************/ -#ifndef BSP_H -#define BSP_H +//============================================================================ +// Product: Board Support Package example +// Last Updated for Version: 7.3.0 +// Date of the Last Update: 2023-08-12 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +//============================================================================ +#ifndef BSP_H_ +#define BSP_H_ #define BSP_TICKS_PER_SEC 100U void BSP_init(void); +void BSP_start(void); void BSP_displayPaused(uint8_t paused); void BSP_displayPhilStat(uint8_t n, char const *stat); void BSP_terminate(int16_t result); -void BSP_randomSeed(uint32_t seed); /* random seed */ -uint32_t BSP_random(void); /* pseudo-random generator */ +void BSP_randomSeed(uint32_t seed); // random seed +uint32_t BSP_random(void); // pseudo-random generator -/* for testing... */ -void BSP_wait4PB1(void); void BSP_ledOn(void); void BSP_ledOff(void); -extern QActive *the_Ticker0; - -#endif /* BSP_H */ +#endif // BSP_H_ diff --git a/examples/arm-cm/dpp_efm32-slstk3401a/dpp.h b/examples/arm-cm/dpp_efm32-slstk3401a/dpp.h index 59d06383..e6d1557a 100644 --- a/examples/arm-cm/dpp_efm32-slstk3401a/dpp.h +++ b/examples/arm-cm/dpp_efm32-slstk3401a/dpp.h @@ -1,94 +1,117 @@ -/*$file${.::dpp.h} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* -* Model: dpp.qm -* File: ${.::dpp.h} -* -* This code has been generated by QM 5.2.4 . -* DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. -* -* SPDX-License-Identifier: GPL-3.0-or-later -* -* This generated code is open source software: you can redistribute it under -* the terms of the GNU General Public License as published by the Free -* Software Foundation. -* -* This code is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -* more details. -* -* NOTE: -* Alternatively, this generated code may be distributed under the terms -* of Quantum Leaps commercial licenses, which expressly supersede the GNU -* General Public License and are specifically designed for licensees -* interested in retaining the proprietary status of their code. -* -* Contact information: -* -* -*/ -/*$endhead${.::dpp.h} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -#ifndef DPP_H -#define DPP_H +//$file${.::dpp.h} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// +// Model: dpp.qm +// File: ${.::dpp.h} +// +// This code has been generated by QM 5.3.0 . +// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. +// +// SPDX-License-Identifier: GPL-3.0-or-later +// +// This generated code is open source software: you can redistribute it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation. +// +// This code is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// NOTE: +// Alternatively, this generated code may be distributed under the terms +// of Quantum Leaps commercial licenses, which expressly supersede the GNU +// General Public License and are specifically designed for licensees +// interested in retaining the proprietary status of their code. +// +// Contact information: +// +// +// +//$endhead${.::dpp.h} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +#ifndef DPP_H_ +#define DPP_H_ -enum DPPSignals { - EAT_SIG = Q_USER_SIG, /* published by Table to let a philosopher eat */ - DONE_SIG, /* published by Philosopher when done eating */ - PAUSE_SIG, /* published by BSP to pause serving forks */ - SERVE_SIG, /* published by BSP to serve re-start serving forks */ - TEST_SIG, /* published by BSP to test the application */ - MAX_PUB_SIG, /* the last published signal */ +//$declare${Shared} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv - HUNGRY_SIG, /* posted direclty to Table from hungry Philo */ - TIMEOUT_SIG, /* used by Philosophers for time events */ - MAX_SIG /* the last signal */ +//${Shared::AppSignals} ...................................................... +enum AppSignals { + EAT_SIG = Q_USER_SIG, // published by Table to let a Philo eat + DONE_SIG, // published by Philo when done eating + PAUSE_SIG, // published by BSP to pause the application + SERVE_SIG, // published by BSP to serve re-start serving forks + TEST_SIG, // published by BSP to test the application + MAX_PUB_SIG, // the last published signal + + TIMEOUT_SIG, // posted by time event to Philo + HUNGRY_SIG, // posted by hungry Philo to Table + MAX_SIG // the last signal }; -enum { - N_PHILO = 5 /* number of Philos */ -}; +//${Shared::produce_sig_dict} ................................................ +#ifdef Q_SPY +static inline void produce_sig_dict(void) { + QS_SIG_DICTIONARY(EAT_SIG, (void *)0); + QS_SIG_DICTIONARY(DONE_SIG, (void *)0); + QS_SIG_DICTIONARY(PAUSE_SIG, (void *)0); + QS_SIG_DICTIONARY(SERVE_SIG, (void *)0); + QS_SIG_DICTIONARY(TEST_SIG, (void *)0); -/*$declare${Events::TableEvt} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ + QS_SIG_DICTIONARY(TIMEOUT_SIG, (void *)0); + QS_SIG_DICTIONARY(HUNGRY_SIG, (void *)0); +} +#endif // def Q_SPY -/*${Events::TableEvt} ......................................................*/ +//${Shared::N_PHILO} ......................................................... +#define N_PHILO ((uint8_t)5U) + +//${Shared::TableEvt} ........................................................ typedef struct { -/* protected: */ +// protected: QEvt super; -/* public: */ - uint8_t philoNum; +// public: + uint8_t philoId; } TableEvt; -/*$enddecl${Events::TableEvt} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*$declare${AOs::Table_ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/*${AOs::Table_ctor} .......................................................*/ -void Table_ctor(void); -/*$enddecl${AOs::Table_ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*$declare${AOs::AO_Table} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +// public: -/*${AOs::AO_Table} .........................................................*/ -/* opaque pointer to the Table AO */ -extern QActive * const AO_Table; -/*$enddecl${AOs::AO_Table} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +#ifdef QEVT_DYN_CTOR +static inline TableEvt * TableEvt_ctor(TableEvt * const me, + uint8_t id) +{ + if (me != (TableEvt *)0) { + // don't call QEvt_ctor() because the initialization of all + // QEvt attributes is already done in QF_QF_newX_() + me->philoId = id; + } + return me; +} +#endif // def QEVT_DYN_CTOR -/*$declare${AOs::Philo_ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${AOs::Philo_ctor} .......................................................*/ -void Philo_ctor(uint8_t n); -/*$enddecl${AOs::Philo_ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*$declare${AOs::AO_Philo[N_PHILO]} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${AOs::AO_Philo[N_PHILO]} ................................................*/ -/* opaque pointers to the Philo AOs */ +//${Shared::AO_Philo[N_PHILO]} ............................................... extern QActive * const AO_Philo[N_PHILO]; -/*$enddecl${AOs::AO_Philo[N_PHILO]} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -#ifdef QP_INC_QXK_H_ - void Test1_ctor(void); - extern QXThread * const XT_Test1; - void Test2_ctor(void); - extern QXThread * const XT_Test2; -#endif /* QP_INC_QXK_H_ */ +//${Shared::Philo_ctor} ...................................................... +void Philo_ctor(uint_fast8_t const id); -#endif /* DPP_H */ +//${Shared::AO_Table} ........................................................ +extern QActive * const AO_Table; +//${Shared::Table_ctor} ...................................................... +void Table_ctor(void); +//$enddecl${Shared} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +#ifdef QXK_H_ + +extern QXThread * const TH_XThread1; +void XThread1_ctor(void); + +extern QXThread * const TH_XThread2; +void XThread2_ctor(void); + +extern QXSemaphore TH_sema; +extern QXMutex TH_mutex; + +#endif // QXK_H_ + +#endif // DPP_H_ diff --git a/examples/arm-cm/dpp_efm32-slstk3401a/dpp.qm b/examples/arm-cm/dpp_efm32-slstk3401a/dpp.qm index 80c3da88..ac9f2bc9 100644 --- a/examples/arm-cm/dpp_efm32-slstk3401a/dpp.qm +++ b/examples/arm-cm/dpp_efm32-slstk3401a/dpp.qm @@ -1,335 +1,58 @@ - + Dining Philosopher Problem example - - - + + + + + { + EAT_SIG = Q_USER_SIG, // published by Table to let a Philo eat + DONE_SIG, // published by Philo when done eating + PAUSE_SIG, // published by BSP to pause the application + SERVE_SIG, // published by BSP to serve re-start serving forks + TEST_SIG, // published by BSP to test the application + MAX_PUB_SIG, // the last published signal + + TIMEOUT_SIG, // posted by time event to Philo + HUNGRY_SIG, // posted by hungry Philo to Table + MAX_SIG // the last signal +}; + + + + QS_SIG_DICTIONARY(EAT_SIG, (void *)0); +QS_SIG_DICTIONARY(DONE_SIG, (void *)0); +QS_SIG_DICTIONARY(PAUSE_SIG, (void *)0); +QS_SIG_DICTIONARY(SERVE_SIG, (void *)0); +QS_SIG_DICTIONARY(TEST_SIG, (void *)0); + +QS_SIG_DICTIONARY(TIMEOUT_SIG, (void *)0); +QS_SIG_DICTIONARY(HUNGRY_SIG, (void *)0); + + + + ((uint8_t)5U) + + - - - - - - - - - - - - - - - - - Q_UNUSED_PAR(par); - -static bool registered = false; -if (!registered) { - registered = true; - - QS_FUN_DICTIONARY(&Philo_initial); - QS_FUN_DICTIONARY(&Philo_thinking); - QS_FUN_DICTIONARY(&Philo_hungry); - QS_FUN_DICTIONARY(&Philo_eating); - - for (uint8_t n = 0U; n < N_PHILO; ++n) { - QS_OBJ_ARR_DICTIONARY(&Philo_inst[n], n); - QS_OBJ_ARR_DICTIONARY(&Philo_inst[n].timeEvt, n); - } + + + + + + + if (me != (TableEvt *)0) { + // don't call QEvt_ctor() because the initialization of all + // QEvt attributes is already done in QF_QF_newX_() + me->philoId = id; } - -QActive_subscribe(&me->super, EAT_SIG); -QActive_subscribe(&me->super, TEST_SIG); - - - - - - - QTimeEvt_armX(&me->timeEvt, THINK_TIME, 0U); - QTimeEvt_disarm(&me->timeEvt); - - - - - - - - - /* EAT or DONE must be for other Philos than this one */ -Q_ASSERT_ID(10, Q_EVT_CAST(TableEvt)->philoNum != PHILO_ID(me)); - - - - - - - - - - - - TableEvt *pe = Q_NEW(TableEvt, HUNGRY_SIG); -pe->philoNum = PHILO_ID(me); -QACTIVE_POST(AO_Table, &pe->super, me); - - - - - Q_EVT_CAST(TableEvt)->philoNum == PHILO_ID(me) - - - - - - - - - - - /* DONE must be for other Philos than this one */ -Q_ASSERT_ID(20, Q_EVT_CAST(TableEvt)->philoNum != PHILO_ID(me)); - - - - - - - - - - - QTimeEvt_armX(&me->timeEvt, EAT_TIME, 0U); - TableEvt *pe = Q_NEW(TableEvt, DONE_SIG); -pe->philoNum = PHILO_ID(me); -QACTIVE_PUBLISH(&pe->super, &me->super); -QTimeEvt_disarm(&me->timeEvt); - - - - - - - - - /* EAT or DONE must be for other Philos than this one */ -Q_ASSERT_ID(30, Q_EVT_CAST(TableEvt)->philoNum != PHILO_ID(me)); - - - - - - - - - - - +return me; + - - - - - The only static instance of the Table class (Singleton pattern) - - - - - - - - - - (void)par; /* unused parameter */ - -QS_OBJ_DICTIONARY(&Table_inst); - -QActive_subscribe(&me->super, DONE_SIG); -QActive_subscribe(&me->super, PAUSE_SIG); -QActive_subscribe(&me->super, SERVE_SIG); -QActive_subscribe(&me->super, EAT_SIG); //??? -QActive_subscribe(&me->super, TEST_SIG); - -for (uint8_t n = 0U; n < N_PHILO; ++n) { - me->fork[n] = FREE; - me->isHungry[n] = 0U; - BSP_displayPhilStat(n, "thinking"); -} - - - - - - - - - //???Q_ERROR_ID(60); - - - - - - - uint8_t n; -for (n = 0U; n < N_PHILO; ++n) { /* give permissions to eat... */ - if ((me->isHungry[n] != 0U) - && (me->fork[LEFT(n)] == FREE) - && (me->fork[n] == FREE)) - { - TableEvt *te; - - me->fork[LEFT(n)] = USED; - me->fork[n] = USED; - te = Q_NEW(TableEvt, EAT_SIG); - te->philoNum = n; - QACTIVE_PUBLISH(&te->super, &me->super); - me->isHungry[n] = 0U; - BSP_displayPhilStat(n, "eating "); - } -} - - - uint8_t n, m; - -n = Q_EVT_CAST(TableEvt)->philoNum; -/* phil ID must be in range and he must be not hungry */ -Q_ASSERT_ID(40, (n < N_PHILO) && (me->isHungry[n] == 0U)); - -BSP_displayPhilStat(n, "hungry "); -m = LEFT(n); - - - (me->fork[m] == FREE) && (me->fork[n] == FREE) - TableEvt *pe; -me->fork[m] = USED; -me->fork[n] = USED; -pe = Q_NEW(TableEvt, EAT_SIG); -pe->philoNum = n; -QACTIVE_PUBLISH(&pe->super, &me->super); -BSP_displayPhilStat(n, "eating "); - - - - - - - else - me->isHungry[n] = 1U; - - - - - - - - - - - uint8_t n, m; -TableEvt *pe; - -n = Q_EVT_CAST(TableEvt)->philoNum; -/* phil ID must be in range and he must be not hungry */ -Q_ASSERT_ID(50, (n < N_PHILO) && (me->isHungry[n] == 0U)); - -BSP_displayPhilStat(n, "thinking"); -m = LEFT(n); -/* both forks of Phil[n] must be used */ -Q_ASSERT_ID(51, (me->fork[n] == USED) && (me->fork[m] == USED)); - -me->fork[m] = FREE; -me->fork[n] = FREE; -m = RIGHT(n); /* check the right neighbor */ - -if ((me->isHungry[m] != 0U) && (me->fork[m] == FREE)) { - me->fork[n] = USED; - me->fork[m] = USED; - me->isHungry[m] = 0U; - pe = Q_NEW(TableEvt, EAT_SIG); - pe->philoNum = m; - QACTIVE_PUBLISH(&pe->super, &me->super); - BSP_displayPhilStat(m, "eating "); -} -m = LEFT(n); /* check the left neighbor */ -n = LEFT(m); /* left fork of the left neighbor */ -if ((me->isHungry[m] != 0U) && (me->fork[n] == FREE)) { - me->fork[m] = USED; - me->fork[n] = USED; - me->isHungry[m] = 0U; - pe = Q_NEW(TableEvt, EAT_SIG); - pe->philoNum = m; - QACTIVE_PUBLISH(&pe->super, &me->super); - BSP_displayPhilStat(m, "eating "); -} - - - - - - - - - - - - - - - - - BSP_displayPaused(1U); - BSP_displayPaused(0U); - - - - - - - - - uint8_t n = Q_EVT_CAST(TableEvt)->philoNum; -/* philo ID must be in range and he must be not hungry */ -Q_ASSERT_ID(60, (n < N_PHILO) && (me->isHungry[n] == 0U)); -me->isHungry[n] = 1U; -BSP_displayPhilStat(n, "hungry "); - - - - - - - uint8_t n, m; - -n = Q_EVT_CAST(TableEvt)->philoNum; -/* phil ID must be in range and he must be not hungry */ -Q_ASSERT_ID(70, (n < N_PHILO) && (me->isHungry[n] == 0U)); - -BSP_displayPhilStat(n, "thinking"); -m = LEFT(n); -/* both forks of Phil[n] must be used */ -Q_ASSERT_ID(71, (me->fork[n] == USED) && (me->fork[m] == USED)); - -me->fork[m] = FREE; -me->fork[n] = FREE; - - - - - - - - - - - - - - - + - /* opaque pointers to the Philo AOs */ = { &Philo_inst[0].super, &Philo_inst[1].super, @@ -338,121 +61,465 @@ me->fork[n] = FREE; &Philo_inst[4].super }; - + + + + + Philo * const me = &Philo_inst[id]; +QActive_ctor(&me->super, Q_STATE_CAST(&Philo_initial)); +QTimeEvt_ctorX(&me->timeEvt, &me->super, TIMEOUT_SIG, 0U), +me->id = (uint8_t)id; + + - /* opaque pointer to the Table AO */ = &Table_inst.super; - - - - - Philo *me = &Philo_inst[n]; -QActive_ctor(&me->super, Q_STATE_CAST(&Philo_initial)); -QTimeEvt_ctorX(&me->timeEvt, &me->super, TIMEOUT_SIG, 0U); - - + - Table *me = &Table_inst; - + Table * const me = &Table_inst; QActive_ctor(&me->super, Q_STATE_CAST(&Table_initial)); +for (uint8_t n = 0U; n < N_PHILO; ++n) { + me->fork[n] = FREE; + me->isHungry[n] = false; +} + + + + + + + The Philo AO and the N_PHILO instances + + + + + + + + + + + Q_UNUSED_PAR(par); + +QS_OBJ_ARR_DICTIONARY(&Philo_inst[me->id], me->id); +QS_OBJ_ARR_DICTIONARY(&Philo_inst[me->id].timeEvt, me->id); + +QActive_subscribe(&me->super, EAT_SIG); +QActive_subscribe(&me->super, TEST_SIG); + + + + + + + QTimeEvt_armX(&me->timeEvt, think_time(), 0U); + (void)QTimeEvt_disarm(&me->timeEvt); + + + + + + + + + // EAT or DONE must be for other Philos than this one +Q_ASSERT(Q_EVT_CAST(TableEvt)->philoId != me->id); + + + + + + + + + + + + + + + + + + #ifdef QEVT_DYN_CTOR +TableEvt const *pe = Q_NEW(TableEvt, HUNGRY_SIG, me->id); +#else +TableEvt *pe = Q_NEW(TableEvt, HUNGRY_SIG); +pe->philoId = me->id; +#endif +QACTIVE_POST(AO_Table, &pe->super, &me->super); + + + + + Q_EVT_CAST(TableEvt)->philoId == me->id + + + + + + + + + + + // DONE must be for other Philos than this one +Q_ASSERT(Q_EVT_CAST(TableEvt)->philoId != me->id); + + + + + + + + + + + QTimeEvt_armX(&me->timeEvt, eat_time(), 0U); + (void)QTimeEvt_disarm(&me->timeEvt); + +#ifdef QEVT_DYN_CTOR +TableEvt const *pe = Q_NEW(TableEvt, DONE_SIG, me->id); +#else +TableEvt *pe = Q_NEW(TableEvt, DONE_SIG); +pe->philoId = me->id; +#endif +QACTIVE_PUBLISH(&pe->super, &me->super); + + + + + + + + + // EAT or DONE must be for other Philos than this one +Q_ASSERT(Q_EVT_CAST(TableEvt)->philoId != me->id); + + + + + + + + + + + + + + + + + + + + + + + + + Q_UNUSED_PAR(par); + +#ifdef Q_SPY +Table *Table_inst = me; +QS_OBJ_DICTIONARY(Table_inst); +#endif + +QActive_subscribe(&me->super, DONE_SIG); +QActive_subscribe(&me->super, PAUSE_SIG); +QActive_subscribe(&me->super, SERVE_SIG); +QActive_subscribe(&me->super, TEST_SIG); for (uint8_t n = 0U; n < N_PHILO; ++n) { me->fork[n] = FREE; - me->isHungry[n] = 0U; -} - + me->isHungry[n] = false; + BSP_displayPhilStat(n, THINKING); +} + + + + + + + + + + + + + + + Q_ERROR(); + + + + + + + // give permissions to eat... +for (uint8_t n = 0U; n < N_PHILO; ++n) { + if (me->isHungry[n] + && (me->fork[left(n)] == FREE) + && (me->fork[n] == FREE)) + { + me->fork[left(n)] = USED; + me->fork[n] = USED; +#ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, EAT_SIG, n); +#else + TableEvt *pe = Q_NEW(TableEvt, EAT_SIG); + pe->philoId = n; +#endif + QACTIVE_PUBLISH(&pe->super, &me->super); + me->isHungry[n] = false; + BSP_displayPhilStat(n, EATING); + } +} + + + uint8_t n = Q_EVT_CAST(TableEvt)->philoId; + +// phil ID must be in range and he must be not hungry +Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); + +BSP_displayPhilStat(n, HUNGRY); +uint8_t m = left(n); + + + (me->fork[m] == FREE) && (me->fork[n] == FREE) + me->fork[m] = USED; +me->fork[n] = USED; +#ifdef QEVT_DYN_CTOR +TableEvt const *pe = Q_NEW(TableEvt, EAT_SIG, n); +#else +TableEvt *pe = Q_NEW(TableEvt, EAT_SIG); +pe->philoId = n; +#endif +QACTIVE_PUBLISH(&pe->super, &me->super); +BSP_displayPhilStat(n, EATING); + + + + + + + else + me->isHungry[n] = true; + + + + + + + + + + + uint8_t n = Q_EVT_CAST(TableEvt)->philoId; + +// phil ID must be in range and he must be not hungry +Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); + +BSP_displayPhilStat(n, THINKING); +uint8_t m = left(n); + +// both forks of Phil[n] must be used +Q_ASSERT((me->fork[n] == USED) && (me->fork[m] == USED)); + +me->fork[m] = FREE; +me->fork[n] = FREE; +m = right(n); // check the right neighbor + +if (me->isHungry[m] && (me->fork[m] == FREE)) { + me->fork[n] = USED; + me->fork[m] = USED; + me->isHungry[m] = false; +#ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, EAT_SIG, m); +#else + TableEvt *pe = Q_NEW(TableEvt, EAT_SIG); + pe->philoId = m; +#endif + QACTIVE_PUBLISH(&pe->super, &me->super); + BSP_displayPhilStat(m, EATING); +} +m = left(n); // check the left neighbor +n = left(m); // left fork of the left neighbor +if (me->isHungry[m] && (me->fork[n] == FREE)) { + me->fork[m] = USED; + me->fork[n] = USED; + me->isHungry[m] = false; +#ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, EAT_SIG, m); +#else + TableEvt *pe = Q_NEW(TableEvt, EAT_SIG); + pe->philoId = m; +#endif + QACTIVE_PUBLISH(&pe->super, &me->super); + BSP_displayPhilStat(m, EATING); +} + + + + + + + Q_ERROR(); + + + + + + + + + + + + + + + + + BSP_displayPaused(1U); + BSP_displayPaused(0U); + + + + + + + + + uint8_t n = Q_EVT_CAST(TableEvt)->philoId; + +// philo ID must be in range and he must be not hungry +Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); + +me->isHungry[n] = true; +BSP_displayPhilStat(n, HUNGRY); + + + + + + + uint8_t n = Q_EVT_CAST(TableEvt)->philoId; + +// phil ID must be in range and he must be not hungry +Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); + +BSP_displayPhilStat(n, THINKING); +uint8_t m = left(n); + +// both forks of Phil[n] must be used +Q_ASSERT((me->fork[n] == USED) && (me->fork[m] == USED)); + +me->fork[m] = FREE; +me->fork[n] = FREE; + + + + + + + + + + + + + + - #ifndef DPP_H -#define DPP_H + #ifndef DPP_H_ +#define DPP_H_ -enum DPPSignals { - EAT_SIG = Q_USER_SIG, /* published by Table to let a philosopher eat */ - DONE_SIG, /* published by Philosopher when done eating */ - PAUSE_SIG, /* published by BSP to pause serving forks */ - SERVE_SIG, /* published by BSP to serve re-start serving forks */ - TEST_SIG, /* published by BSP to test the application */ - MAX_PUB_SIG, /* the last published signal */ +$declare ${Shared} - HUNGRY_SIG, /* posted direclty to Table from hungry Philo */ - TIMEOUT_SIG, /* used by Philosophers for time events */ - MAX_SIG /* the last signal */ -}; +#ifdef QXK_H_ -enum { - N_PHILO = 5 /* number of Philos */ -}; +extern QXThread * const TH_XThread1; +void XThread1_ctor(void); -$declare${Events::TableEvt} -$declare${AOs::Table_ctor} -$declare${AOs::AO_Table} +extern QXThread * const TH_XThread2; +void XThread2_ctor(void); -$declare${AOs::Philo_ctor} -$declare${AOs::AO_Philo[N_PHILO]} +extern QXSemaphore TH_sema; +extern QXMutex TH_mutex; -#ifdef QP_INC_QXK_H_ - void Test1_ctor(void); - extern QXThread * const XT_Test1; - void Test2_ctor(void); - extern QXThread * const XT_Test2; -#endif /* QP_INC_QXK_H_ */ +#endif // QXK_H_ -#endif /* DPP_H */ - +#endif // DPP_H_ - #include "qpc.h" -#include "dpp.h" -#include "bsp.h" + #include "qpc.h" // QP/C real-time embedded framework +#include "dpp.h" // DPP Application interface +#include "bsp.h" // Board Support Package -Q_DEFINE_THIS_MODULE("philo") - -/* Active object class -----------------------------------------------------*/ $declare ${AOs::Philo} -/* helper macros to provide a randomized think time for Philos */ -#define THINK_TIME \ - (QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + (BSP_TICKS_PER_SEC/2U)) -#define EAT_TIME \ - (QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + BSP_TICKS_PER_SEC) +//---------------------------------------------------------------------------- +Q_DEFINE_THIS_FILE -/* helper macro to provide the ID of Philo "me_" */ -#define PHILO_ID(me_) ((uint8_t)((me_) - &Philo_inst[0])) +// helper function to provide a randomized think time for Philos +static QTimeEvtCtr think_time(void); // prototype +static inline QTimeEvtCtr think_time(void) { + return (QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + + (BSP_TICKS_PER_SEC/2U)); +} -/* Global objects ----------------------------------------------------------*/ -$define${AOs::AO_Philo[N_PHILO]} +// helper function to provide a randomized eat time for Philos +static QTimeEvtCtr eat_time(void); // prototype +static inline QTimeEvtCtr eat_time(void) { + return (QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + + BSP_TICKS_PER_SEC); +} +//---------------------------------------------------------------------------- -/* Philo definition --------------------------------------------------------*/ -$define${AOs::Philo_ctor} -$define${AOs::Philo} +$define ${Shared::Philo_ctor} +$define ${Shared::AO_Philo[N_PHILO]} +$define ${AOs::Philo} - #include "qpc.h" -#include "dpp.h" -#include "bsp.h" + #include "qpc.h" // QP/C real-time embedded framework +#include "dpp.h" // DPP Application interface +#include "bsp.h" // Board Support Package -Q_DEFINE_THIS_MODULE("table") +$declare ${AOs::Table} -/* Active object class -----------------------------------------------------*/ -$declare${AOs::Table} +//---------------------------------------------------------------------------- +Q_DEFINE_THIS_FILE -#define RIGHT(n_) ((uint8_t)(((n_) + (N_PHILO - 1U)) % N_PHILO)) -#define LEFT(n_) ((uint8_t)(((n_) + 1U) % N_PHILO)) -#define FREE ((uint8_t)0) -#define USED ((uint8_t)1) +// helper function to provide the RIGHT neighbor of a Philo[n] +static inline uint8_t right(uint8_t const n) { + return (uint8_t)((n + (N_PHILO - 1U)) % N_PHILO); +} -/* Global-scope objects ----------------------------------------------------*/ -$define${AOs::AO_Table} +// helper function to provide the LEFT neighbor of a Philo[n] +static inline uint8_t left(uint8_t const n) { + return (uint8_t)((n + 1U) % N_PHILO); +} -/*..........................................................................*/ -$define${AOs::Table_ctor} -$define${AOs::Table} +#define FREE ((uint8_t)0U) +#define USED ((uint8_t)1U) + +#define THINKING "thinking" +#define HUNGRY "hungry " +#define EATING "eating " + +//---------------------------------------------------------------------------- + +$define ${Shared::Table_ctor} +$define ${Shared::AO_Table} +$define ${AOs::Table} diff --git a/examples/arm-cm/dpp_efm32-slstk3401a/efm32-slstk3401a.jpg b/examples/arm-cm/dpp_efm32-slstk3401a/efm32-slstk3401a.jpg new file mode 100644 index 00000000..384488d9 Binary files /dev/null and b/examples/arm-cm/dpp_efm32-slstk3401a/efm32-slstk3401a.jpg differ diff --git a/examples/arm-cm/dpp_efm32-slstk3401a/main.c b/examples/arm-cm/dpp_efm32-slstk3401a/main.c new file mode 100644 index 00000000..deac175a --- /dev/null +++ b/examples/arm-cm/dpp_efm32-slstk3401a/main.c @@ -0,0 +1,44 @@ +//============================================================================ +// APP example +// Last updated for version 7.3.0 +// Last updated on 2023-08-09 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. +// +// This program is open source software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Alternatively, this program may be distributed and modified under the +// terms of Quantum Leaps commercial licenses, which expressly supersede +// the GNU General Public License and are specifically designed for +// licensees interested in retaining the proprietary status of their code. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Contact information: +// +// +//============================================================================ +#include "qpc.h" // QP/C real-time embedded framework +#include "dpp.h" // DPP Application interface +#include "bsp.h" // Board Support Package + +//............................................................................ +int main() { + QF_init(); // initialize the framework and the underlying RT kernel + BSP_init(); // initialize the BSP + BSP_start(); // start the AOs/Threads + return QF_run(); // run the QF application +} diff --git a/examples/arm-cm/dpp_efm32-slstk3401a/philo.c b/examples/arm-cm/dpp_efm32-slstk3401a/philo.c index c6e46806..eb6be531 100644 --- a/examples/arm-cm/dpp_efm32-slstk3401a/philo.c +++ b/examples/arm-cm/dpp_efm32-slstk3401a/philo.c @@ -1,81 +1,98 @@ -/*$file${.::philo.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* -* Model: dpp.qm -* File: ${.::philo.c} -* -* This code has been generated by QM 5.2.4 . -* DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. -* -* SPDX-License-Identifier: GPL-3.0-or-later -* -* This generated code is open source software: you can redistribute it under -* the terms of the GNU General Public License as published by the Free -* Software Foundation. -* -* This code is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -* more details. -* -* NOTE: -* Alternatively, this generated code may be distributed under the terms -* of Quantum Leaps commercial licenses, which expressly supersede the GNU -* General Public License and are specifically designed for licensees -* interested in retaining the proprietary status of their code. -* -* Contact information: -* -* -*/ -/*$endhead${.::philo.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -#include "qpc.h" -#include "dpp.h" -#include "bsp.h" +//$file${.::philo.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// +// Model: dpp.qm +// File: ${.::philo.c} +// +// This code has been generated by QM 5.3.0 . +// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. +// +// SPDX-License-Identifier: GPL-3.0-or-later +// +// This generated code is open source software: you can redistribute it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation. +// +// This code is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// NOTE: +// Alternatively, this generated code may be distributed under the terms +// of Quantum Leaps commercial licenses, which expressly supersede the GNU +// General Public License and are specifically designed for licensees +// interested in retaining the proprietary status of their code. +// +// Contact information: +// +// +// +//$endhead${.::philo.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +#include "qpc.h" // QP/C real-time embedded framework +#include "dpp.h" // DPP Application interface +#include "bsp.h" // Board Support Package -Q_DEFINE_THIS_MODULE("philo") +//$declare${AOs::Philo} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/* Active object class -----------------------------------------------------*/ -/*$declare${AOs::Philo} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${AOs::Philo} ............................................................*/ +//${AOs::Philo} .............................................................. typedef struct Philo { -/* protected: */ +// protected: QActive super; -/* public: */ - -/* private: */ +// private: QTimeEvt timeEvt; + uint8_t id; + +// public: } Philo; + extern Philo Philo_inst[N_PHILO]; -/* protected: */ +// protected: static QState Philo_initial(Philo * const me, void const * const par); static QState Philo_thinking(Philo * const me, QEvt const * const e); static QState Philo_hungry(Philo * const me, QEvt const * const e); static QState Philo_eating(Philo * const me, QEvt const * const e); -/*$enddecl${AOs::Philo} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$enddecl${AOs::Philo} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -/* helper macros to provide a randomized think time for Philos */ -#define THINK_TIME \ - (QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + (BSP_TICKS_PER_SEC/2U)) -#define EAT_TIME \ - (QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + BSP_TICKS_PER_SEC) +//---------------------------------------------------------------------------- +Q_DEFINE_THIS_FILE -/* helper macro to provide the ID of Philo "me_" */ -#define PHILO_ID(me_) ((uint8_t)((me_) - &Philo_inst[0])) +// helper function to provide a randomized think time for Philos +static QTimeEvtCtr think_time(void); // prototype +static inline QTimeEvtCtr think_time(void) { + return (QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + + (BSP_TICKS_PER_SEC/2U)); +} -/* Global objects ----------------------------------------------------------*/ -/*$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* Check for the minimum required QP version */ -#if (QP_VERSION < 700U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) -#error qpc version 7.0.0 or higher required +// helper function to provide a randomized eat time for Philos +static QTimeEvtCtr eat_time(void); // prototype +static inline QTimeEvtCtr eat_time(void) { + return (QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + + BSP_TICKS_PER_SEC); +} +//---------------------------------------------------------------------------- + +//$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// Check for the minimum required QP version +#if (QP_VERSION < 730U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) +#error qpc version 7.3.0 or higher required #endif -/*$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -/*$define${AOs::AO_Philo[N_PHILO]} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//$define${Shared::Philo_ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/*${AOs::AO_Philo[N_PHILO]} ................................................*/ +//${Shared::Philo_ctor} ...................................................... +void Philo_ctor(uint_fast8_t const id) { + Philo * const me = &Philo_inst[id]; + QActive_ctor(&me->super, Q_STATE_CAST(&Philo_initial)); + QTimeEvt_ctorX(&me->timeEvt, &me->super, TIMEOUT_SIG, 0U), + me->id = (uint8_t)id; +} +//$enddef${Shared::Philo_ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +//$define${Shared::AO_Philo[N_PHILO]} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${Shared::AO_Philo[N_PHILO]} ............................................... QActive * const AO_Philo[N_PHILO] = { &Philo_inst[0].super, &Philo_inst[1].super, @@ -83,74 +100,61 @@ QActive * const AO_Philo[N_PHILO] = { &Philo_inst[3].super, &Philo_inst[4].super }; -/*$enddef${AOs::AO_Philo[N_PHILO]} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$enddef${Shared::AO_Philo[N_PHILO]} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +//$define${AOs::Philo} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/* Philo definition --------------------------------------------------------*/ -/*$define${AOs::Philo_ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${AOs::Philo_ctor} .......................................................*/ -void Philo_ctor(uint8_t n) { - Philo *me = &Philo_inst[n]; - QActive_ctor(&me->super, Q_STATE_CAST(&Philo_initial)); - QTimeEvt_ctorX(&me->timeEvt, &me->super, TIMEOUT_SIG, 0U); -} -/*$enddef${AOs::Philo_ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*$define${AOs::Philo} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${AOs::Philo} ............................................................*/ +//${AOs::Philo} .............................................................. Philo Philo_inst[N_PHILO]; -/*${AOs::Philo::SM} ........................................................*/ +//${AOs::Philo::SM} .......................................................... static QState Philo_initial(Philo * const me, void const * const par) { - /*${AOs::Philo::SM::initial} */ + //${AOs::Philo::SM::initial} Q_UNUSED_PAR(par); - static bool registered = false; - if (!registered) { - registered = true; - - QS_FUN_DICTIONARY(&Philo_initial); - QS_FUN_DICTIONARY(&Philo_thinking); - QS_FUN_DICTIONARY(&Philo_hungry); - QS_FUN_DICTIONARY(&Philo_eating); - - for (uint8_t n = 0U; n < N_PHILO; ++n) { - QS_OBJ_ARR_DICTIONARY(&Philo_inst[n], n); - QS_OBJ_ARR_DICTIONARY(&Philo_inst[n].timeEvt, n); - } - } + QS_OBJ_ARR_DICTIONARY(&Philo_inst[me->id], me->id); + QS_OBJ_ARR_DICTIONARY(&Philo_inst[me->id].timeEvt, me->id); QActive_subscribe(&me->super, EAT_SIG); QActive_subscribe(&me->super, TEST_SIG); + + QS_FUN_DICTIONARY(&Philo_thinking); + QS_FUN_DICTIONARY(&Philo_hungry); + QS_FUN_DICTIONARY(&Philo_eating); + return Q_TRAN(&Philo_thinking); } -/*${AOs::Philo::SM::thinking} ..............................................*/ +//${AOs::Philo::SM::thinking} ................................................ static QState Philo_thinking(Philo * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${AOs::Philo::SM::thinking} */ + //${AOs::Philo::SM::thinking} case Q_ENTRY_SIG: { - QTimeEvt_armX(&me->timeEvt, THINK_TIME, 0U); + QTimeEvt_armX(&me->timeEvt, think_time(), 0U); status_ = Q_HANDLED(); break; } - /*${AOs::Philo::SM::thinking} */ + //${AOs::Philo::SM::thinking} case Q_EXIT_SIG: { - QTimeEvt_disarm(&me->timeEvt); + (void)QTimeEvt_disarm(&me->timeEvt); status_ = Q_HANDLED(); break; } - /*${AOs::Philo::SM::thinking::TIMEOUT} */ + //${AOs::Philo::SM::thinking::TIMEOUT} case TIMEOUT_SIG: { status_ = Q_TRAN(&Philo_hungry); break; } - /*${AOs::Philo::SM::thinking::EAT, DONE} */ - case EAT_SIG: /* intentionally fall through */ + //${AOs::Philo::SM::thinking::EAT, DONE} + case EAT_SIG: // intentionally fall through case DONE_SIG: { - /* EAT or DONE must be for other Philos than this one */ - Q_ASSERT_ID(10, Q_EVT_CAST(TableEvt)->philoNum != PHILO_ID(me)); + // EAT or DONE must be for other Philos than this one + Q_ASSERT(Q_EVT_CAST(TableEvt)->philoId != me->id); + status_ = Q_HANDLED(); + break; + } + //${AOs::Philo::SM::thinking::TEST} + case TEST_SIG: { status_ = Q_HANDLED(); break; } @@ -162,22 +166,26 @@ static QState Philo_thinking(Philo * const me, QEvt const * const e) { return status_; } -/*${AOs::Philo::SM::hungry} ................................................*/ +//${AOs::Philo::SM::hungry} .................................................. static QState Philo_hungry(Philo * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${AOs::Philo::SM::hungry} */ + //${AOs::Philo::SM::hungry} case Q_ENTRY_SIG: { + #ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, HUNGRY_SIG, me->id); + #else TableEvt *pe = Q_NEW(TableEvt, HUNGRY_SIG); - pe->philoNum = PHILO_ID(me); - QACTIVE_POST(AO_Table, &pe->super, me); + pe->philoId = me->id; + #endif + QACTIVE_POST(AO_Table, &pe->super, &me->super); status_ = Q_HANDLED(); break; } - /*${AOs::Philo::SM::hungry::EAT} */ + //${AOs::Philo::SM::hungry::EAT} case EAT_SIG: { - /*${AOs::Philo::SM::hungry::EAT::[Q_EVT_CAST(TableEvt)->philoNum=~} */ - if (Q_EVT_CAST(TableEvt)->philoNum == PHILO_ID(me)) { + //${AOs::Philo::SM::hungry::EAT::[e->philoId==me->iid]} + if (Q_EVT_CAST(TableEvt)->philoId == me->id) { status_ = Q_TRAN(&Philo_eating); } else { @@ -185,10 +193,10 @@ static QState Philo_hungry(Philo * const me, QEvt const * const e) { } break; } - /*${AOs::Philo::SM::hungry::DONE} */ + //${AOs::Philo::SM::hungry::DONE} case DONE_SIG: { - /* DONE must be for other Philos than this one */ - Q_ASSERT_ID(20, Q_EVT_CAST(TableEvt)->philoNum != PHILO_ID(me)); + // DONE must be for other Philos than this one + Q_ASSERT(Q_EVT_CAST(TableEvt)->philoId != me->id); status_ = Q_HANDLED(); break; } @@ -200,35 +208,40 @@ static QState Philo_hungry(Philo * const me, QEvt const * const e) { return status_; } -/*${AOs::Philo::SM::eating} ................................................*/ +//${AOs::Philo::SM::eating} .................................................. static QState Philo_eating(Philo * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${AOs::Philo::SM::eating} */ + //${AOs::Philo::SM::eating} case Q_ENTRY_SIG: { - QTimeEvt_armX(&me->timeEvt, EAT_TIME, 0U); + QTimeEvt_armX(&me->timeEvt, eat_time(), 0U); status_ = Q_HANDLED(); break; } - /*${AOs::Philo::SM::eating} */ + //${AOs::Philo::SM::eating} case Q_EXIT_SIG: { + (void)QTimeEvt_disarm(&me->timeEvt); + + #ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, DONE_SIG, me->id); + #else TableEvt *pe = Q_NEW(TableEvt, DONE_SIG); - pe->philoNum = PHILO_ID(me); + pe->philoId = me->id; + #endif QACTIVE_PUBLISH(&pe->super, &me->super); - QTimeEvt_disarm(&me->timeEvt); status_ = Q_HANDLED(); break; } - /*${AOs::Philo::SM::eating::TIMEOUT} */ + //${AOs::Philo::SM::eating::TIMEOUT} case TIMEOUT_SIG: { status_ = Q_TRAN(&Philo_thinking); break; } - /*${AOs::Philo::SM::eating::EAT, DONE} */ - case EAT_SIG: /* intentionally fall through */ + //${AOs::Philo::SM::eating::EAT, DONE} + case EAT_SIG: // intentionally fall through case DONE_SIG: { - /* EAT or DONE must be for other Philos than this one */ - Q_ASSERT_ID(30, Q_EVT_CAST(TableEvt)->philoNum != PHILO_ID(me)); + // EAT or DONE must be for other Philos than this one + Q_ASSERT(Q_EVT_CAST(TableEvt)->philoId != me->id); status_ = Q_HANDLED(); break; } @@ -239,4 +252,4 @@ static QState Philo_eating(Philo * const me, QEvt const * const e) { } return status_; } -/*$enddef${AOs::Philo} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$enddef${AOs::Philo} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/examples/arm-cm/dpp_efm32-slstk3401a/qk/armclang/dpp-qk.sct b/examples/arm-cm/dpp_efm32-slstk3401a/qk/armclang/dpp-qk.sct new file mode 100644 index 00000000..794d15cc --- /dev/null +++ b/examples/arm-cm/dpp_efm32-slstk3401a/qk/armclang/dpp-qk.sct @@ -0,0 +1,23 @@ +; ************************************************************* +; *** Scatter-Loading Description File generated by uVision *** +; +; Modified by Quantum Leaps: +; added STACK as the first section in RW_STACK +; ************************************************************* + +LR_IROM1 0x00000000 0x00020000 { ; load region size_region + ER_IROM1 0x00000000 0x00020000 { ; load address = execution address + *.o (RESET, +First) + *(InRoot$$Sections) + .ANY (+RO) + .ANY (+XO) + } + + RW_STACK 0x20000000 { ; <== Quantum Leaps + * (STACK, +First) + } + RW_IRAM1 +0 (0x00008000 - 2048) { ; NOTE: assume STACK size 2048! + .ANY (+RW +ZI) + } +} + diff --git a/examples/arm-cm/dpp_efm32-slstk3401a/qk/armclang/dpp-qk.uvoptx b/examples/arm-cm/dpp_efm32-slstk3401a/qk/armclang/dpp-qk.uvoptx index a5f19d9d..23fb5b4d 100644 --- a/examples/arm-cm/dpp_efm32-slstk3401a/qk/armclang/dpp-qk.uvoptx +++ b/examples/arm-cm/dpp_efm32-slstk3401a/qk/armclang/dpp-qk.uvoptx @@ -117,11 +117,6 @@ Segger\JL2CM3.dll - - 0 - DLGUARM - - 0 JL2CM3 @@ -140,7 +135,7 @@ 0 DLGTARM - (1010=1913,720,2363,1277,0)(1007=1124,641,1311,916,0)(1008=-1,-1,-1,-1,0)(1009=-1,-1,-1,-1,0)(1012=2701,333,3178,648,0) + (1010=2845,673,3295,1230,0)(1007=1124,641,1311,916,0)(1008=-1,-1,-1,-1,0)(1009=-1,-1,-1,-1,0)(1012=2701,333,3178,648,0) 0 @@ -153,72 +148,7 @@ -U0E2006F4 -O4622 -S4 -FO61 - - - 0 - 0 - 377 - 1 -
0
- 0 - 0 - 0 - 0 - 0 - 0 - ..\bsp.c - - -
- - 1 - 0 - 413 - 1 -
446
- 0 - 0 - 0 - 0 - 0 - 1 - ..\..\..\..\..\3rd_party\efm32pg1b\arm\startup_efm32pg1b.s - - \\dpp_qk\../../../../../3rd_party/efm32pg1b/arm/startup_efm32pg1b.s\413 -
- - 2 - 0 - 216 - 1 -
376
- 0 - 0 - 0 - 0 - 0 - 1 - ..\..\..\..\..\3rd_party\efm32pg1b\arm\startup_efm32pg1b.s - - \\dpp_qk\../../../../../3rd_party/efm32pg1b/arm/startup_efm32pg1b.s\216 -
- - 3 - 0 - 228 - 1 -
382
- 0 - 0 - 0 - 0 - 0 - 1 - ..\..\..\..\..\3rd_party\efm32pg1b\arm\startup_efm32pg1b.s - - \\dpp_qk\../../../../../3rd_party/efm32pg1b/arm/startup_efm32pg1b.s\228 -
-
+ 1 @@ -713,30 +643,6 @@ 1 3 - 1 - 0 - 0 - 0 - ..\..\..\..\..\include\qstamp.c - qstamp.c - 0 - 0 - - - 1 - 4 - 1 - 0 - 0 - 0 - ..\main.c - main.c - 0 - 0 - - - 1 - 5 5 0 0 @@ -748,7 +654,7 @@ 1 - 6 + 4 1 0 0 @@ -760,7 +666,7 @@ 1 - 7 + 5 1 0 0 @@ -770,6 +676,18 @@ 0 0 + + 1 + 6 + 1 + 0 + 0 + 0 + ..\..\main.c + main.c + 0 + 0 + @@ -780,7 +698,7 @@ 0 2 - 8 + 7 2 0 0 @@ -792,7 +710,7 @@ 2 - 9 + 8 1 0 0 @@ -804,7 +722,7 @@ 2 - 10 + 9 1 0 0 @@ -816,7 +734,7 @@ 2 - 11 + 10 1 0 0 @@ -828,7 +746,7 @@ 2 - 12 + 11 1 0 0 @@ -840,7 +758,7 @@ 2 - 13 + 12 1 0 0 @@ -852,7 +770,7 @@ 2 - 14 + 13 1 0 0 @@ -872,7 +790,7 @@ 0 3 - 15 + 14 1 0 0 @@ -884,7 +802,7 @@ 3 - 16 + 15 1 0 0 @@ -896,7 +814,7 @@ 3 - 17 + 16 1 0 0 @@ -908,7 +826,7 @@ 3 - 18 + 17 1 0 0 @@ -920,7 +838,7 @@ 3 - 19 + 18 1 0 0 @@ -932,7 +850,7 @@ 3 - 20 + 19 1 0 0 @@ -944,7 +862,7 @@ 3 - 21 + 20 1 0 0 @@ -956,7 +874,7 @@ 3 - 22 + 21 1 0 0 @@ -968,7 +886,7 @@ 3 - 23 + 22 1 0 0 @@ -980,7 +898,7 @@ 3 - 24 + 23 1 0 0 @@ -992,7 +910,7 @@ 3 - 25 + 24 1 0 0 @@ -1004,7 +922,7 @@ 3 - 26 + 25 1 0 0 @@ -1016,7 +934,7 @@ 3 - 27 + 26 1 0 0 @@ -1036,31 +954,7 @@ 0 4 - 28 - 5 - 0 - 0 - 0 - ..\..\..\..\..\ports\arm-cm\qk\armclang\qep_port.h - qep_port.h - 0 - 0 - - - 4 - 29 - 5 - 0 - 0 - 0 - ..\..\..\..\..\ports\arm-cm\qk\armclang\qf_port.h - qf_port.h - 0 - 0 - - - 4 - 30 + 27 1 0 0 @@ -1070,30 +964,6 @@ 0 0 - - 4 - 31 - 5 - 0 - 0 - 0 - ..\..\..\..\..\ports\arm-cm\qk\armclang\qk_port.h - qk_port.h - 0 - 0 - - - 4 - 32 - 5 - 0 - 0 - 0 - ..\..\..\..\..\ports\arm-cm\qk\armclang\qs_port.h - qs_port.h - 0 - 0 - @@ -1104,7 +974,7 @@ 0 5 - 33 + 28 1 0 0 @@ -1116,7 +986,7 @@ 5 - 34 + 29 1 0 0 @@ -1128,7 +998,7 @@ 5 - 35 + 30 1 0 0 @@ -1140,7 +1010,7 @@ 5 - 36 + 31 1 0 0 @@ -1150,6 +1020,18 @@ 0 0 + + 5 + 32 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qs\qstamp.c + qstamp.c + 0 + 0 + diff --git a/examples/arm-cm/dpp_efm32-slstk3401a/qk/armclang/dpp-qk.uvprojx b/examples/arm-cm/dpp_efm32-slstk3401a/qk/armclang/dpp-qk.uvprojx index 9c9374b4..415027a0 100644 --- a/examples/arm-cm/dpp_efm32-slstk3401a/qk/armclang/dpp-qk.uvprojx +++ b/examples/arm-cm/dpp_efm32-slstk3401a/qk/armclang/dpp-qk.uvprojx @@ -183,7 +183,7 @@ 1 0 0 - 1 + 2 0 0 0 @@ -361,7 +361,7 @@ - 1 + 0 0 0 0 @@ -370,7 +370,7 @@ 0x00000000 0x20000000 - + .\dpp-qk.sct --entry Reset_Handler @@ -393,16 +393,6 @@ 5 ..\..\dpp.h - - qstamp.c - 1 - ..\..\..\..\..\include\qstamp.c - - - main.c - 1 - ..\main.c - bsp.h 5 @@ -418,6 +408,11 @@ 1 ..\..\table.c + + main.c + 1 + ..\..\main.c + @@ -533,31 +528,11 @@ QP_port - - qep_port.h - 5 - ..\..\..\..\..\ports\arm-cm\qk\armclang\qep_port.h - - - qf_port.h - 5 - ..\..\..\..\..\ports\arm-cm\qk\armclang\qf_port.h - qk_port.c 1 ..\..\..\..\..\ports\arm-cm\qk\armclang\qk_port.c - - qk_port.h - 5 - ..\..\..\..\..\ports\arm-cm\qk\armclang\qk_port.h - - - qs_port.h - 5 - ..\..\..\..\..\ports\arm-cm\qk\armclang\qs_port.h - @@ -652,6 +627,11 @@ 1 ..\..\..\..\..\src\qs\qs_rx.c + + qstamp.c + 1 + ..\..\..\..\..\src\qs\qstamp.c + @@ -1011,7 +991,7 @@ - 1 + 0 0 0 0 @@ -1020,7 +1000,7 @@ 0x00000000 0x20000000 - dpp-qk.sct + .\dpp-qk.sct --entry Reset_Handler @@ -1043,16 +1023,6 @@ 5 ..\..\dpp.h - - qstamp.c - 1 - ..\..\..\..\..\include\qstamp.c - - - main.c - 1 - ..\main.c - bsp.h 5 @@ -1068,6 +1038,11 @@ 1 ..\..\table.c + + main.c + 1 + ..\..\main.c + @@ -1183,31 +1158,11 @@ QP_port - - qep_port.h - 5 - ..\..\..\..\..\ports\arm-cm\qk\armclang\qep_port.h - - - qf_port.h - 5 - ..\..\..\..\..\ports\arm-cm\qk\armclang\qf_port.h - qk_port.c 1 ..\..\..\..\..\ports\arm-cm\qk\armclang\qk_port.c - - qk_port.h - 5 - ..\..\..\..\..\ports\arm-cm\qk\armclang\qk_port.h - - - qs_port.h - 5 - ..\..\..\..\..\ports\arm-cm\qk\armclang\qs_port.h - @@ -1302,6 +1257,11 @@ 1 ..\..\..\..\..\src\qs\qs_rx.c + + qstamp.c + 1 + ..\..\..\..\..\src\qs\qstamp.c + @@ -1637,7 +1597,7 @@ 0 - Q_SPY + Q_SPY,QF_ON_CONTEXT_SW ..\..;..\..\..\..\..\include;..\..\..\..\..\ports\arm-cm\qk\armclang;..\..\..\..\..\3rd_party\CMSIS\Include;..\..\..\..\..\3rd_party\efm32pg1b @@ -1661,7 +1621,7 @@ - 1 + 0 0 0 0 @@ -1670,7 +1630,7 @@ 0x00000000 0x20000000 - + .\dpp-qk.sct --entry Reset_Handler @@ -1693,16 +1653,6 @@ 5 ..\..\dpp.h - - qstamp.c - 1 - ..\..\..\..\..\include\qstamp.c - - - main.c - 1 - ..\main.c - bsp.h 5 @@ -1718,6 +1668,11 @@ 1 ..\..\table.c + + main.c + 1 + ..\..\main.c + @@ -1833,31 +1788,11 @@ QP_port - - qep_port.h - 5 - ..\..\..\..\..\ports\arm-cm\qk\armclang\qep_port.h - - - qf_port.h - 5 - ..\..\..\..\..\ports\arm-cm\qk\armclang\qf_port.h - qk_port.c 1 ..\..\..\..\..\ports\arm-cm\qk\armclang\qk_port.c - - qk_port.h - 5 - ..\..\..\..\..\ports\arm-cm\qk\armclang\qk_port.h - - - qs_port.h - 5 - ..\..\..\..\..\ports\arm-cm\qk\armclang\qs_port.h - @@ -1883,6 +1818,11 @@ 1 ..\..\..\..\..\src\qs\qs_rx.c + + qstamp.c + 1 + ..\..\..\..\..\src\qs\qstamp.c + diff --git a/examples/arm-cm/dpp_efm32-slstk3401a/qk/bsp.c b/examples/arm-cm/dpp_efm32-slstk3401a/qk/bsp.c index 764b408c..ec176ded 100644 --- a/examples/arm-cm/dpp_efm32-slstk3401a/qk/bsp.c +++ b/examples/arm-cm/dpp_efm32-slstk3401a/qk/bsp.c @@ -1,627 +1,556 @@ -/***************************************************************************** -* Product: DPP example, EFM32-SLSTK3401A board, preemptive QK kernel -* Last updated for version 7.2.0 -* Last updated on 2022-12-17 -* -* Q u a n t u m L e a P s -* ------------------------ -* Modern Embedded Software -* -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* -* -*****************************************************************************/ -#include "qpc.h" -#include "dpp.h" -#include "bsp.h" +//============================================================================ +// Product: DPP example, EFM32-SLSTK3401A board, QK kernel +// Last updated for version 7.3.0 +// Last updated on 2023-08-23 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. +// +// This program is open source software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Alternatively, this program may be distributed and modified under the +// terms of Quantum Leaps commercial licenses, which expressly supersede +// the GNU General Public License and are specifically designed for +// licensees interested in retaining the proprietary status of their code. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Contact information: +// +// +//============================================================================ +#include "qpc.h" // QP/C real-time embedded framework +#include "dpp.h" // DPP Application interface +#include "bsp.h" // Board Support Package -#include "em_device.h" /* the device specific header (SiLabs) */ -#include "em_cmu.h" /* Clock Management Unit (SiLabs) */ -#include "em_gpio.h" /* GPIO (SiLabs) */ -#include "em_usart.h" /* USART (SiLabs) */ -/* add other drivers if necessary... */ +#include "em_device.h" // the device specific header (SiLabs) +#include "em_cmu.h" // Clock Management Unit (SiLabs) +#include "em_gpio.h" // GPIO (SiLabs) +#include "em_usart.h" // USART (SiLabs) +// add other drivers if necessary... -Q_DEFINE_THIS_FILE +Q_DEFINE_THIS_FILE // define the name of this file for assertions -/* ISRs defined in this BSP ------------------------------------------------*/ -void SysTick_Handler(void); -void GPIO_EVEN_IRQHandler(void); -void USART0_RX_IRQHandler(void); - -/* Local-scope objects -----------------------------------------------------*/ +// Local-scope objects ----------------------------------------------------- #define LED_PORT gpioPortF -#define LED0_PIN 4 -#define LED1_PIN 5 +#define LED0_PIN 4U +#define LED1_PIN 5U #define PB_PORT gpioPortF -#define PB0_PIN 6 -#define PB1_PIN 7 +#define PB0_PIN 6U +#define PB1_PIN 7U -static uint32_t l_rnd; /* random seed */ +static uint32_t l_rndSeed; #ifdef Q_SPY QSTimeCtr QS_tickTime_; QSTimeCtr QS_tickPeriod_; - /* QSpy source IDs */ + // QSpy source IDs static QSpyId const l_SysTick_Handler = { 0U }; static QSpyId const l_GPIO_EVEN_IRQHandler = { 0U }; static USART_TypeDef * const l_USART0 = ((USART_TypeDef *)(0x40010000UL)); - enum AppRecords { /* application-specific trace records */ + enum AppRecords { // application-specific trace records PHILO_STAT = QS_USER, - COMMAND_STAT + PAUSED_STAT, + CONTEXT_SW, }; #endif -/*..........................................................................*/ -void SysTick_Handler(void) { - QK_ISR_ENTRY(); /* inform QK about entering an ISR */ +//============================================================================ +// Error handler and ISRs... - QTIMEEVT_TICK_X(0U, &l_SysTick_Handler); /* process time-evts for rate 0 */ - //QACTIVE_POST(the_Ticker0, 0, &l_SysTick_Handler); /* post to Ticker0 */ - - /* Perform the debouncing of buttons. The algorithm for debouncing - * adapted from the book "Embedded Systems Dictionary" by Jack Ganssle - * and Michael Barr, page 71. - */ - /* state of the button debouncing, see below */ - static struct ButtonsDebouncing { - uint32_t depressed; - uint32_t previous; - } buttons = { 0U, 0U }; - uint32_t current = ~GPIO->P[PB_PORT].DIN; /* read PB0 and BP1 */ - uint32_t tmp = buttons.depressed; /* the debounced depressed buttons */ - buttons.depressed |= (buttons.previous & current); /* set depressed */ - buttons.depressed &= (buttons.previous | current); /* clear released */ - buttons.previous = current; /* update the history */ - tmp ^= buttons.depressed; /* changed debounced depressed */ - if ((tmp & (1U << PB0_PIN)) != 0U) { /* debounced PB0 state changed? */ - if ((buttons.depressed & (1U << PB0_PIN)) != 0U) { /* PB0 depressed?*/ - static QEvt const pauseEvt = { PAUSE_SIG, 0U, 0U}; - QACTIVE_PUBLISH(&pauseEvt, &l_SysTick_Handler); - } - else { /* the button is released */ - static QEvt const serveEvt = { SERVE_SIG, 0U, 0U}; - QACTIVE_PUBLISH(&serveEvt, &l_SysTick_Handler); - } - } - -#ifdef Q_SPY - { - tmp = SysTick->CTRL; /* clear SysTick_CTRL_COUNTFLAG */ - QS_tickTime_ += QS_tickPeriod_; /* account for the clock rollover */ - } -#endif - - QK_ISR_EXIT(); /* inform QK about exiting an ISR */ -} -/*..........................................................................*/ -void GPIO_EVEN_IRQHandler(void) { /* for testing, NOTE3 */ - QK_ISR_ENTRY(); /* inform QK about entering an ISR */ - - QACTIVE_POST(AO_Table, Q_NEW(QEvt, MAX_PUB_SIG), /* for testing... */ - &l_GPIO_EVEN_IRQHandler); - - QK_ISR_EXIT(); /* inform QK about exiting an ISR */ -} -/*..........................................................................*/ -#ifdef Q_SPY -/* -* ISR for receiving bytes from the QSPY Back-End -* NOTE: This ISR is "QF-unaware" meaning that it does not interact with -* the QF/QK and is not disabled. Such ISRs don't need to call QK_ISR_ENTRY/ -* QK_ISR_EXIT and they cannot post or publish events. -*/ -void USART0_RX_IRQHandler(void) { - /* while RX FIFO NOT empty */ - while ((l_USART0->STATUS & USART_STATUS_RXDATAV) != 0) { - uint32_t b = l_USART0->RXDATA; - QS_RX_PUT(b); - } - QK_ARM_ERRATUM_838869(); -} -#else -void USART0_RX_IRQHandler(void) {} -#endif - - -/* BSP functions ===========================================================*/ -/* MPU setup for EFM32PG1B200F256GM48 MCU */ -static void EFM32PG182_MPU_setup(void) { - /* The following MPU configuration contains the general EFM32PG1 memory - * map described in the EFM32PG1 Data Sheet Figure 3.2. EFM32PG1 Memory Map - * - * Please note that the actual STM32 MCUs provide much less Flash and SRAM - * than the maximums configured here. This means that actual MCUs have - * unmapped memory regions (e.g., beyond the actual SRAM). Attempts to - * access these regions causes the HardFault exception, which is the - * desired behavior. - */ - static struct { - uint32_t rbar; - uint32_t rasr; - } const mpu_setup[] = { - - { /* region #0: Flash: base=0x0000'0000, size=512M=2^(28+1) */ - 0x00000000U /* base address */ - | MPU_RBAR_VALID_Msk /* valid region */ - | (MPU_RBAR_REGION_Msk & 0U), /* region #0 */ - (28U << MPU_RASR_SIZE_Pos) /* 2^(18+1) region */ - | (0x6U << MPU_RASR_AP_Pos) /* PA:ro/UA:ro */ - | (1U << MPU_RASR_C_Pos) /* C=1 */ - | MPU_RASR_ENABLE_Msk /* region enable */ - }, - - { /* region #1: SRAM: base=0x2000'0000, size=512M=2^(28+1) */ - 0x20000000U /* base address */ - | MPU_RBAR_VALID_Msk /* valid region */ - | (MPU_RBAR_REGION_Msk & 1U), /* region #1 */ - (28U << MPU_RASR_SIZE_Pos) /* 2^(28+1) region */ - | (0x3U << MPU_RASR_AP_Pos) /* PA:rw/UA:rw */ - | (1U << MPU_RASR_XN_Pos) /* XN=1 */ - | (1U << MPU_RASR_S_Pos) /* S=1 */ - | (1U << MPU_RASR_C_Pos) /* C=1 */ - | MPU_RASR_ENABLE_Msk /* region enable */ - }, - - /* region #3: (not configured) */ - { MPU_RBAR_VALID_Msk | (MPU_RBAR_REGION_Msk & 2U), 0U }, - - { /* region #3: Peripherals: base=0x4000'0000, size=512M=2^(28+1) */ - 0x40000000U /* base address */ - | MPU_RBAR_VALID_Msk /* valid region */ - | (MPU_RBAR_REGION_Msk & 3U), /* region #3 */ - (28U << MPU_RASR_SIZE_Pos) /* 2^(28+1) region */ - | (0x3U << MPU_RASR_AP_Pos) /* PA:rw/UA:rw */ - | (1U << MPU_RASR_XN_Pos) /* XN=1 */ - | (1U << MPU_RASR_S_Pos) /* S=1 */ - | (1U << MPU_RASR_B_Pos) /* B=1 */ - | MPU_RASR_ENABLE_Msk /* region enable */ - }, - - { /* region #4: Priv. Periph: base=0xE000'0000, size=512M=2^(28+1) */ - 0xE0000000U /* base address */ - | MPU_RBAR_VALID_Msk /* valid region */ - | (MPU_RBAR_REGION_Msk & 4U), /* region #4 */ - (28U << MPU_RASR_SIZE_Pos) /* 2^(28+1) region */ - | (0x3U << MPU_RASR_AP_Pos) /* PA:rw/UA:rw */ - | (1U << MPU_RASR_XN_Pos) /* XN=1 */ - | (1U << MPU_RASR_S_Pos) /* S=1 */ - | (1U << MPU_RASR_B_Pos) /* B=1 */ - | MPU_RASR_ENABLE_Msk /* region enable */ - }, - - { /* region #5: Ext RAM: base=0x6000'0000, size=1G=2^(29+1) */ - 0x60000000U /* base address */ - | MPU_RBAR_VALID_Msk /* valid region */ - | (MPU_RBAR_REGION_Msk & 5U), /* region #5 */ - (29U << MPU_RASR_SIZE_Pos) /* 2^(28+1) region */ - | (0x3U << MPU_RASR_AP_Pos) /* PA:rw/UA:rw */ - | (1U << MPU_RASR_XN_Pos) /* XN=1 */ - | (1U << MPU_RASR_S_Pos) /* S=1 */ - | (1U << MPU_RASR_B_Pos) /* B=1 */ - | MPU_RASR_ENABLE_Msk /* region enable */ - }, - - { /* region #6: Ext Dev: base=0xA000'0000, size=1G=2^(29+1) */ - 0xA0000000U /* base address */ - | MPU_RBAR_VALID_Msk /* valid region */ - | (MPU_RBAR_REGION_Msk & 6U), /* region #6 */ - (29U << MPU_RASR_SIZE_Pos) /* 2^(28+1) region */ - | (0x3U << MPU_RASR_AP_Pos) /* PA:rw/UA:rw */ - | (1U << MPU_RASR_XN_Pos) /* XN=1 */ - | (1U << MPU_RASR_S_Pos) /* S=1 */ - | (1U << MPU_RASR_B_Pos) /* B=1 */ - | MPU_RASR_ENABLE_Msk /* region enable */ - }, - - { /* region #7: NULL-pointer: base=0x000'0000, size=256B, NOTE0 */ - 0x00000000U /* base address */ - | MPU_RBAR_VALID_Msk /* valid region */ - | (MPU_RBAR_REGION_Msk & 7U), /* region #7 */ - (7U << MPU_RASR_SIZE_Pos) /* 2^(7+1)=256B region */ - | (0x0U << MPU_RASR_AP_Pos) /* PA:na/UA:na */ - | (1U << MPU_RASR_XN_Pos) /* XN=1 */ - | MPU_RASR_ENABLE_Msk /* region enable */ - }, - }; - - /* enable the MemManage_Handler for MPU exception */ - SCB->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk; - - __DSB(); - MPU->CTRL = 0U; /* disable the MPU */ - for (uint_fast8_t n = 0U; n < Q_DIM(mpu_setup); ++n) { - MPU->RBAR = mpu_setup[n].rbar; - MPU->RASR = mpu_setup[n].rasr; - } - MPU->CTRL = MPU_CTRL_ENABLE_Msk; /* enable the MPU */ - __ISB(); - __DSB(); -} - -/*..........................................................................*/ -void BSP_init(void) { - /* setup the MPU... */ - EFM32PG182_MPU_setup(); - - /* NOTE: SystemInit() already called from the startup code - * but SystemCoreClock needs to be updated - */ - SystemCoreClockUpdate(); - - /* NOTE: The VFP (hardware Floating Point) unit is configured by QK-port */ - - /* enable clock for to the peripherals used by this application... */ - CMU_ClockEnable(cmuClock_HFPER, true); - CMU_ClockEnable(cmuClock_GPIO, true); - CMU_ClockEnable(cmuClock_HFPER, true); - CMU_ClockEnable(cmuClock_GPIO, true); - - /* configure the LEDs */ - GPIO_PinModeSet(LED_PORT, LED0_PIN, gpioModePushPull, 0); - GPIO_PinModeSet(LED_PORT, LED1_PIN, gpioModePushPull, 0); - GPIO_PinOutClear(LED_PORT, LED0_PIN); - GPIO_PinOutClear(LED_PORT, LED1_PIN); - - /* configure the Buttons */ - GPIO_PinModeSet(PB_PORT, PB0_PIN, gpioModeInputPull, 1); - GPIO_PinModeSet(PB_PORT, PB1_PIN, gpioModeInputPull, 1); - - /*... */ - BSP_randomSeed(1234U); - - if (QS_INIT((void *)0) == 0) { /* initialize the QS software tracing */ - Q_ERROR(); - } - /* global signals */ - QS_SIG_DICTIONARY(DONE_SIG, (void *)0); - QS_SIG_DICTIONARY(EAT_SIG, (void *)0); - QS_SIG_DICTIONARY(PAUSE_SIG, (void *)0); - QS_SIG_DICTIONARY(SERVE_SIG, (void *)0); - QS_SIG_DICTIONARY(TEST_SIG, (void *)0); - QS_SIG_DICTIONARY(HUNGRY_SIG, (void *)0); - QS_SIG_DICTIONARY(HUNGRY_SIG, (void *)0); - QS_SIG_DICTIONARY(TIMEOUT_SIG, (void *)0); - - QS_OBJ_DICTIONARY(the_Ticker0); - QS_OBJ_DICTIONARY(&l_SysTick_Handler); - QS_OBJ_DICTIONARY(&l_GPIO_EVEN_IRQHandler); - - QS_USR_DICTIONARY(PHILO_STAT); - QS_USR_DICTIONARY(COMMAND_STAT); - - /* setup the QS filters... */ - //QS_GLB_FILTER(QS_SM_RECORDS); /* state machine records */ - //QS_GLB_FILTER(QS_AO_RECORDS); /* active object records */ - //QS_GLB_FILTER(QS_UA_RECORDS); /* all user records */ - QS_GLB_FILTER(QS_ALL_RECORDS); /* all records */ - QS_GLB_FILTER(-QS_QF_TICK); /* exclude the clock tick */ -} -/*..........................................................................*/ -void BSP_displayPhilStat(uint8_t n, char const *stat) { - QS_TEST_PROBE_DEF(&BSP_displayPhilStat) - - QS_TEST_PROBE_ID(1, - stat = "Unknown"; - ) - - if (stat[0] == 'e') { - GPIO->P[LED_PORT].DOUT |= (1U << LED0_PIN); - } - else { - GPIO->P[LED_PORT].DOUT &= ~(1U << LED0_PIN); - } - - QS_BEGIN_ID(PHILO_STAT, AO_Philo[n]->prio) /* app-specific record */ - QS_U8(1, n); /* Philosopher number */ - QS_STR(stat); /* Philosopher status */ - QS_END() /* application-specific record end */ -} -/*..........................................................................*/ -void BSP_displayPaused(uint8_t paused) { - if (paused != 0U) { - GPIO->P[LED_PORT].DOUT |= (1U << LED0_PIN); - } - else { - GPIO->P[LED_PORT].DOUT &= ~(1U << LED0_PIN); - } -} -/*..........................................................................*/ -uint32_t BSP_random(void) { /* a very cheap pseudo-random-number generator */ - uint32_t rnd; - QSchedStatus lockStat; - - /* Some flating point code is to exercise the VFP... */ - float volatile x = 3.1415926F; - x = x + 2.7182818F; - - lockStat = QK_schedLock(N_PHILO); /* lock scheduler up to N_PHILO prio */ - /* "Super-Duper" Linear Congruential Generator (LCG) - * LCG(2^32, 3*7*11*13*23, 0, seed) - */ - rnd = l_rnd * (3U*7U*11U*13U*23U); - l_rnd = rnd; /* set for the next time */ - QK_schedUnlock(lockStat); /* unlock the scheduler */ - - return (rnd >> 8); -} -/*..........................................................................*/ -void BSP_randomSeed(uint32_t seed) { - l_rnd = seed; -} -/*..........................................................................*/ -void BSP_terminate(int16_t result) { - (void)result; -} - -/* QF callbacks ============================================================*/ -void QF_onStartup(void) { - /* set up the SysTick timer to fire at BSP_TICKS_PER_SEC rate */ - SysTick_Config(SystemCoreClock / BSP_TICKS_PER_SEC); - - /* assign all priority bits for preemption-prio. and none to sub-prio. */ - NVIC_SetPriorityGrouping(0U); - - /* set priorities of ALL ISRs used in the system, see NOTE1 - * - * !!!!!!!!!!!!!!!!!!!!!!!!!!!! CAUTION !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - * Assign a priority to EVERY ISR explicitly by calling NVIC_SetPriority(). - * DO NOT LEAVE THE ISR PRIORITIES AT THE DEFAULT VALUE! - */ - NVIC_SetPriority(USART0_RX_IRQn, 0U); /* kernel unaware interrupt */ - NVIC_SetPriority(GPIO_EVEN_IRQn, QF_AWARE_ISR_CMSIS_PRI); - NVIC_SetPriority(SysTick_IRQn, QF_AWARE_ISR_CMSIS_PRI + 1U); - /* ... */ - - /* enable IRQs... */ - NVIC_EnableIRQ(GPIO_EVEN_IRQn); -#ifdef Q_SPY - NVIC_EnableIRQ(USART0_RX_IRQn); /* UART0 interrupt used for QS-RX */ -#endif -} -/*..........................................................................*/ -void QF_onCleanup(void) { -} -/*..........................................................................*/ -void QK_onIdle(void) { - /* toggle the User LED on and then off, see NOTE2 */ - QF_INT_DISABLE(); - GPIO->P[LED_PORT].DOUT |= (1U << LED1_PIN); - GPIO->P[LED_PORT].DOUT &= ~(1U << LED1_PIN); - QF_INT_ENABLE(); - -#ifdef Q_SPY - QS_rxParse(); /* parse all the received bytes */ - - if ((l_USART0->STATUS & USART_STATUS_TXBL) != 0) { /* is TXE empty? */ - uint16_t b; - - QF_INT_DISABLE(); - b = QS_getByte(); - QF_INT_ENABLE(); - - if (b != QS_EOD) { /* not End-Of-Data? */ - l_USART0->TXDATA = (b & 0xFFU); /* put into the DR register */ - } - } -#elif defined NDEBUG - /* Put the CPU and peripherals to the low-power mode. - * you might need to customize the clock management for your application, - * see the datasheet for your particular Cortex-M3 MCU. - */ - __WFI(); /* Wait-For-Interrupt */ -#endif -} - -/*..........................................................................*/ -Q_NORETURN Q_onAssert(char const * const module, int_t const loc) { - /* - * NOTE: add here your application-specific error handling - */ - (void)module; - (void)loc; - QS_ASSERTION(module, loc, 10000U); /* report assertion to QS */ +Q_NORETURN Q_onError(char const * const module, int_t const id) { + // NOTE: this implementation of the assertion handler is intended only + // for debugging and MUST be changed for deployment of the application + // (assuming that you ship your production code with assertions enabled). + Q_UNUSED_PAR(module); + Q_UNUSED_PAR(id); + QS_ASSERTION(module, id, 10000U); #ifndef NDEBUG - /* light up both LEDs */ + // light up both LEDs GPIO->P[LED_PORT].DOUT |= ((1U << LED0_PIN) | (1U << LED1_PIN)); - /* for debugging, hang on in an endless loop... */ + // for debugging, hang on in an endless loop... for (;;) { } #endif NVIC_SystemReset(); } +//............................................................................ +void assert_failed(char const * const module, int_t const id); // prototype +void assert_failed(char const * const module, int_t const id) { + Q_onError(module, id); +} + +// ISRs used in the application ============================================ + +void SysTick_Handler(void); // prototype +void SysTick_Handler(void) { + QK_ISR_ENTRY(); // inform QK about entering an ISR + + QTIMEEVT_TICK_X(0U, &l_SysTick_Handler); // time events at rate 0 + + // Perform the debouncing of buttons. The algorithm for debouncing + // adapted from the book "Embedded Systems Dictionary" by Jack Ganssle + // and Michael Barr, page 71. + // + // state of the button debouncing + static struct { + uint32_t depressed; + uint32_t previous; + } buttons = { 0U, 0U }; + + uint32_t current = ~GPIO->P[PB_PORT].DIN; // read PB0 and BP1 + uint32_t tmp = buttons.depressed; // save the depressed buttons + buttons.depressed |= (buttons.previous & current); // set depressed + buttons.depressed &= (buttons.previous | current); // clear released + buttons.previous = current; // update the history + tmp ^= buttons.depressed; // changed debounced depressed + current = buttons.depressed; + + if ((tmp & (1U << PB0_PIN)) != 0U) { // debounced PB0 state changed? + if ((current & (1U << PB0_PIN)) != 0U) { // is PB0 depressed? + static QEvt const pauseEvt = QEVT_INITIALIZER(PAUSE_SIG); + QACTIVE_PUBLISH(&pauseEvt, &l_SysTick_Handler); + } + else { // the button is released + static QEvt const serveEvt = QEVT_INITIALIZER(SERVE_SIG); + QACTIVE_PUBLISH(&serveEvt, &l_SysTick_Handler); + } + } -/* QS callbacks ============================================================*/ #ifdef Q_SPY -/*..........................................................................*/ -uint8_t QS_onStartup(void const *arg) { - static uint8_t qsTxBuf[2*1024]; /* buffer for QS transmit channel */ - static uint8_t qsRxBuf[100]; /* buffer for QS receive channel */ - static USART_InitAsync_TypeDef init = { - usartEnable, /* Enable RX/TX when init completed */ - 0, /* Use current clock for configuring baudrate */ - 115200, /* 115200 bits/s */ - usartOVS16, /* 16x oversampling */ - usartDatabits8, /* 8 databits */ - usartNoParity, /* No parity */ - usartStopbits1, /* 1 stopbit */ - 0, /* Do not disable majority vote */ - 0, /* Not USART PRS input mode */ - usartPrsRxCh0, /* PRS channel 0 */ - 0, /* Auto CS functionality enable/disable switch */ - 0, /* Auto CS Hold cycles */ - 0 /* Auto CS Setup cycles */ - }; + tmp = SysTick->CTRL; // clear CTRL_COUNTFLAG + QS_tickTime_ += QS_tickPeriod_; // account for the clock rollover +#endif - QS_initBuf (qsTxBuf, sizeof(qsTxBuf)); + QK_ISR_EXIT(); // inform QK about exiting an ISR +} +//............................................................................ +// interrupt handler for testing preemptions in QK +void GPIO_EVEN_IRQHandler(void); // prototype +void GPIO_EVEN_IRQHandler(void) { // for testing, NOTE03 + QK_ISR_ENTRY(); // inform QK about entering an ISR + +// for testing... +#ifdef QEVT_DYN_CTOR + QACTIVE_PUBLISH(Q_NEW(QEvt, TEST_SIG, QEVT_DYNAMIC), + &l_GPIO_EVEN_IRQHandler); +#else + QACTIVE_PUBLISH(Q_NEW(QEvt, TEST_SIG), &l_GPIO_EVEN_IRQHandler); +#endif + + QK_ISR_EXIT(); // inform QK about exiting an ISR +} + +//............................................................................ +#ifdef Q_SPY +// ISR for receiving bytes from the QSPY Back-End +// NOTE: This ISR is "QF-unaware" meaning that it does not interact with +// the QF/QK and is not disabled. Such ISRs don't need to call +// QK_ISR_ENTRY/QK_ISR_EXIT and they cannot post or publish events. + +void USART0_RX_IRQHandler(void); // prototype +void USART0_RX_IRQHandler(void) { + // while RX FIFO NOT empty + while ((l_USART0->STATUS & USART_STATUS_RXDATAV) != 0U) { + uint32_t b = l_USART0->RXDATA; + QS_RX_PUT(b); + } + + QK_ARM_ERRATUM_838869(); +} +#endif // Q_SPY + +//............................................................................ +#ifdef QF_ON_CONTEXT_SW +// NOTE: the context-switch callback is called with interrupts DISABLED +void QF_onContextSw(QActive *prev, QActive *next) { + QS_BEGIN_INCRIT(CONTEXT_SW, 0U) // in critical section! + QS_OBJ(prev); + QS_OBJ(next); + QS_END_INCRIT() +} +#endif // QF_ON_CONTEXT_SW + +//============================================================================ +// BSP functions... + +void BSP_init(void) { + // Configure the MPU to prevent NULL-pointer dereferencing ... + MPU->RBAR = 0x0U // base address (NULL) + | MPU_RBAR_VALID_Msk // valid region + | (MPU_RBAR_REGION_Msk & 7U); // region #7 + MPU->RASR = (7U << MPU_RASR_SIZE_Pos) // 2^(7+1) region + | (0x0U << MPU_RASR_AP_Pos) // no-access region + | MPU_RASR_ENABLE_Msk; // region enable + MPU->CTRL = MPU_CTRL_PRIVDEFENA_Msk // enable background region + | MPU_CTRL_ENABLE_Msk; // enable the MPU + __ISB(); + __DSB(); + + // enable the MemManage_Handler for MPU exception + SCB->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk; + + // NOTE: SystemInit() has been already called from the startup code + // but SystemCoreClock needs to be updated + SystemCoreClockUpdate(); + + // NOTE: The VFP (hardware Floating Point) unit is configured by QK + + // enable clock for to the peripherals used by this application... + CMU_ClockEnable(cmuClock_HFPER, true); + CMU_ClockEnable(cmuClock_GPIO, true); + CMU_ClockEnable(cmuClock_HFPER, true); + CMU_ClockEnable(cmuClock_GPIO, true); + + // configure the LEDs + GPIO_PinModeSet(LED_PORT, LED0_PIN, gpioModePushPull, 0); + GPIO_PinModeSet(LED_PORT, LED1_PIN, gpioModePushPull, 0); + GPIO_PinOutClear(LED_PORT, LED0_PIN); + GPIO_PinOutClear(LED_PORT, LED1_PIN); + + // configure the Buttons + GPIO_PinModeSet(PB_PORT, PB0_PIN, gpioModeInputPull, 1); + GPIO_PinModeSet(PB_PORT, PB1_PIN, gpioModeInputPull, 1); + + BSP_randomSeed(1234U); // seed the random number generator + + // initialize the QS software tracing... + if (!QS_INIT((void *)0)) { + Q_ERROR(); + } + + // dictionaries... + QS_OBJ_DICTIONARY(&l_SysTick_Handler); + QS_OBJ_DICTIONARY(&l_GPIO_EVEN_IRQHandler); + QS_USR_DICTIONARY(PHILO_STAT); + QS_USR_DICTIONARY(PAUSED_STAT); + QS_USR_DICTIONARY(CONTEXT_SW); + + QS_ONLY(produce_sig_dict()); + + // setup the QS filters... + QS_GLB_FILTER(QS_ALL_RECORDS); // all records + QS_GLB_FILTER(-QS_QF_TICK); // exclude the clock tick +} +//............................................................................ +void BSP_start(void) { + // initialize event pools + static QF_MPOOL_EL(TableEvt) smlPoolSto[2*N_PHILO]; + QF_poolInit(smlPoolSto, sizeof(smlPoolSto), sizeof(smlPoolSto[0])); + + // initialize publish-subscribe + static QSubscrList subscrSto[MAX_PUB_SIG]; + QActive_psInit(subscrSto, Q_DIM(subscrSto)); + + // instantiate and start AOs/threads... + + static QEvt const *philoQueueSto[N_PHILO][10]; + for (uint8_t n = 0U; n < N_PHILO; ++n) { + Philo_ctor(n); + QACTIVE_START(AO_Philo[n], + + // NOTE: set the preemption-threshold of all Philos to + // the same level, so that they cannot preempt each other. + Q_PRIO(n + 3U, N_PHILO + 2U), // QF-prio/pre-thre. + + philoQueueSto[n], // event queue storage + Q_DIM(philoQueueSto[n]), // queue length [events] + (void *)0, 0U, // no stack storage + (void *)0); // no initialization param + } + + static QEvt const *tableQueueSto[N_PHILO]; + Table_ctor(); + QACTIVE_START(AO_Table, + N_PHILO + 7U, // QP prio. of the AO + tableQueueSto, // event queue storage + Q_DIM(tableQueueSto), // queue length [events] + (void *)0, 0U, // no stack storage + (void *)0); // no initialization param +} +//............................................................................ +void BSP_displayPhilStat(uint8_t n, char const *stat) { + Q_UNUSED_PAR(n); + + if (stat[0] == 'e') { + GPIO->P[LED_PORT].DOUT |= (1U << LED0_PIN); + } + else { + GPIO->P[LED_PORT].DOUT &= ~(1U << LED0_PIN); + } + + // app-specific trace record... + QS_BEGIN_ID(PHILO_STAT, AO_Table->prio) + QS_U8(1, n); // Philosopher number + QS_STR(stat); // Philosopher status + QS_END() +} +//............................................................................ +void BSP_displayPaused(uint8_t const paused) { + if (paused != 0U) { + GPIO->P[LED_PORT].DOUT |= (1U << LED0_PIN); + } + else { + GPIO->P[LED_PORT].DOUT &= ~(1U << LED0_PIN); + } + + // application-specific trace record + QS_BEGIN_ID(PAUSED_STAT, AO_Table->prio) + QS_U8(1, paused); // Paused status + QS_END() +} +//............................................................................ +void BSP_randomSeed(uint32_t seed) { + l_rndSeed = seed; +} +//............................................................................ +uint32_t BSP_random(void) { // a very cheap pseudo-random-number generator + // Some floating point code is to exercise the VFP... + float volatile x = 3.1415926F; + x = x + 2.7182818F; + + QSchedStatus lockStat = QK_schedLock(N_PHILO); // N_PHILO prio. ceiling + // "Super-Duper" Linear Congruential Generator (LCG) + // LCG(2^32, 3*7*11*13*23, 0, seed) + uint32_t rnd = l_rndSeed * (3U*7U*11U*13U*23U); + l_rndSeed = rnd; // set for the next time + QK_schedUnlock(lockStat); + + return (rnd >> 8U); +} +//............................................................................ +void BSP_ledOn(void) { + GPIO->P[LED_PORT].DOUT |= (1U << LED1_PIN); +} +//............................................................................ +void BSP_ledOff(void) { + GPIO->P[LED_PORT].DOUT &= ~(1U << LED1_PIN); +} +//............................................................................ +void BSP_terminate(int16_t result) { + Q_UNUSED_PAR(result); +} + +//============================================================================ +// QF callbacks... +void QF_onStartup(void) { + // set up the SysTick timer to fire at BSP_TICKS_PER_SEC rate + SysTick_Config(SystemCoreClock / BSP_TICKS_PER_SEC); + + // assign all priority bits for preemption-prio. and none to sub-prio. + NVIC_SetPriorityGrouping(0U); + + // set priorities of ALL ISRs used in the system, see NOTE1 + NVIC_SetPriority(USART0_RX_IRQn, 0U); // kernel unaware interrupt + NVIC_SetPriority(GPIO_EVEN_IRQn, QF_AWARE_ISR_CMSIS_PRI + 0U); + NVIC_SetPriority(SysTick_IRQn, QF_AWARE_ISR_CMSIS_PRI + 1U); + // ... + + // enable IRQs... + NVIC_EnableIRQ(GPIO_EVEN_IRQn); + +#ifdef Q_SPY + NVIC_EnableIRQ(USART0_RX_IRQn); // UART0 interrupt used for QS-RX +#endif +} +//............................................................................ +void QF_onCleanup(void) { +} +//............................................................................ +void QK_onIdle(void) { + // toggle the User LED on and then off, see NOTE3 +// QF_INT_DISABLE(); +// GPIO->P[LED_PORT].DOUT |= (1U << LED1_PIN); +// GPIO->P[LED_PORT].DOUT &= ~(1U << LED1_PIN); +// QF_INT_ENABLE(); + +#ifdef Q_SPY + QF_INT_DISABLE(); + QS_rxParse(); // parse all the received bytes + QF_INT_ENABLE(); + + if ((l_USART0->STATUS & USART_STATUS_TXBL) != 0) { // is TXE empty? + QF_INT_DISABLE(); + uint16_t b = QS_getByte(); + QF_INT_ENABLE(); + + if (b != QS_EOD) { // not End-Of-Data? + l_USART0->TXDATA = b; // put into the DR register + } + } +#elif defined NDEBUG + // Put the CPU and peripherals to the low-power mode. + // you might need to customize the clock management for your application, + // see the datasheet for your particular Cortex-M MCU. + // + __WFI(); // Wait-For-Interrupt +#endif +} + +//============================================================================ +// QS callbacks... +#ifdef Q_SPY + +//............................................................................ +uint8_t QS_onStartup(void const *arg) { + Q_UNUSED_PAR(arg); + + static uint8_t qsTxBuf[2*1024]; // buffer for QS-TX channel + QS_initBuf(qsTxBuf, sizeof(qsTxBuf)); + + static uint8_t qsRxBuf[100]; // buffer for QS-RX channel QS_rxInitBuf(qsRxBuf, sizeof(qsRxBuf)); - /* Enable peripheral clocks */ + static USART_InitAsync_TypeDef init = { + usartEnable, // Enable RX/TX when init completed + 0, // Use current clock for configuring baudrate + 115200, // 115200 bits/s + usartOVS16, // 16x oversampling + usartDatabits8, // 8 databits + usartNoParity, // No parity + usartStopbits1, // 1 stopbit + 0, // Do not disable majority vote + 0, // Not USART PRS input mode + usartPrsRxCh0, // PRS channel 0 + 0, // Auto CS functionality enable/disable switch + 0, // Auto CS Hold cycles + 0 // Auto CS Setup cycles + }; + + // Enable peripheral clocks CMU_ClockEnable(cmuClock_HFPER, true); CMU_ClockEnable(cmuClock_GPIO, true); - /* To avoid false start, configure output as high */ + // To avoid false start, configure output as high GPIO_PinModeSet(gpioPortA, 0, gpioModePushPull, 1); // TX pin GPIO_PinModeSet(gpioPortA, 1, gpioModeInput, 0); // RX pin - /* Enable DK RS232/UART switch */ + // Enable DK RS232/UART switch GPIO_PinModeSet(gpioPortA, 5, gpioModePushPull, 1); CMU_ClockEnable(cmuClock_USART0, true); - /* configure the UART for the desired baud rate, 8-N-1 operation */ + // configure the UART for the desired baud rate, 8-N-1 operation init.enable = usartDisable; USART_InitAsync(l_USART0, &init); - /* enable pins at correct UART/USART location. */ + // enable pins at correct UART/USART location. l_USART0->ROUTEPEN = USART_ROUTEPEN_RXPEN | USART_ROUTEPEN_TXPEN; l_USART0->ROUTELOC0 = (l_USART0->ROUTELOC0 & ~(_USART_ROUTELOC0_TXLOC_MASK | _USART_ROUTELOC0_RXLOC_MASK)); - /* Clear previous RX interrupts */ + // Clear previous RX interrupts USART_IntClear(l_USART0, USART_IF_RXDATAV); NVIC_ClearPendingIRQ(USART0_RX_IRQn); - /* Enable RX interrupts */ + // Enable RX interrupts USART_IntEnable(l_USART0, USART_IF_RXDATAV); - /* NOTE: do not enable the UART0 interrupt in the NVIC yet. - * Wait till QF_onStartup() - */ + // NOTE: do not enable the UART0 interrupt in the NVIC yet. + // Wait till QF_onStartup() - /* Finally enable the UART */ + // Finally enable the UART USART_Enable(l_USART0, usartEnable); QS_tickPeriod_ = SystemCoreClock / BSP_TICKS_PER_SEC; - QS_tickTime_ = QS_tickPeriod_; /* to start the timestamp at zero */ + QS_tickTime_ = QS_tickPeriod_; // to start the timestamp at zero - return 1U; /* return success */ + return 1U; // return success } -/*..........................................................................*/ +//............................................................................ void QS_onCleanup(void) { } -/*..........................................................................*/ -QSTimeCtr QS_onGetTime(void) { /* NOTE: invoked with interrupts DISABLED */ - if ((SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk) == 0) { /* not set? */ +//............................................................................ +QSTimeCtr QS_onGetTime(void) { // NOTE: invoked with interrupts DISABLED + if ((SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk) == 0U) { // not set? return QS_tickTime_ - (QSTimeCtr)SysTick->VAL; } - else { /* the rollover occured, but the SysTick_ISR did not run yet */ + else { // the rollover occured, but the SysTick_ISR did not run yet return QS_tickTime_ + QS_tickPeriod_ - (QSTimeCtr)SysTick->VAL; } } -/*..........................................................................*/ +//............................................................................ void QS_onFlush(void) { - uint16_t b; - - QF_INT_DISABLE(); - while ((b = QS_getByte()) != QS_EOD) { /* while not End-Of-Data... */ - QF_INT_ENABLE(); - /* while TXE not empty */ - while ((l_USART0->STATUS & USART_STATUS_TXBL) == 0U) { - } - l_USART0->TXDATA = (b & 0xFFU); /* put into the DR register */ + for (;;) { QF_INT_DISABLE(); + uint16_t b = QS_getByte(); + if (b != QS_EOD) { + while ((l_USART0->STATUS & USART_STATUS_TXBL) == 0U) { + QF_INT_ENABLE(); + QF_CRIT_EXIT_NOP(); + + QF_INT_DISABLE(); + } + l_USART0->TXDATA = b; + QF_INT_ENABLE(); + } + else { + QF_INT_ENABLE(); + break; + } } - QF_INT_ENABLE(); } -/*..........................................................................*/ -/*! callback function to reset the target (to be implemented in the BSP) */ +//............................................................................ +//! callback function to reset the target (to be implemented in the BSP) void QS_onReset(void) { NVIC_SystemReset(); } -/*..........................................................................*/ -/*! callback function to execute a user command (to be implemented in BSP) */ +//............................................................................ +// callback function to execute a user command void QS_onCommand(uint8_t cmdId, uint32_t param1, uint32_t param2, uint32_t param3) { - void assert_failed(char const *module, int loc); - (void)cmdId; - (void)param1; - (void)param2; - (void)param3; - QS_BEGIN_ID(COMMAND_STAT, 0U) /* app-specific record */ - QS_U8(2, cmdId); - QS_U32(8, param1); - QS_U32(8, param2); - QS_U32(8, param3); - QS_END() - - if (cmdId == 10U) { - Q_ERROR(); - } - else if (cmdId == 11U) { - assert_failed("QS_onCommand", 123); - } + Q_UNUSED_PAR(cmdId); + Q_UNUSED_PAR(param1); + Q_UNUSED_PAR(param2); + Q_UNUSED_PAR(param3); } -#endif /* Q_SPY */ -/*--------------------------------------------------------------------------*/ +#endif // Q_SPY +//---------------------------------------------------------------------------- -/*============================================================================ -* NOTE0: -* The MPU protection against NULL-pointer dereferencing sets up a no-access -* MPU region #7 around the NULL address (0x0). This works even though the -* Vector Table also resides at address 0x0. However, the *size* of the -* no-access region should not exceed the size of the Vector Table. In this -* case, the size is set to 2**(7+1)==256 bytes, which does not contain any -* data that the CPU would legitimately read with the LDR instruction. -* -* NOTE1: -* The QF_AWARE_ISR_CMSIS_PRI constant from the QF port specifies the highest -* ISR priority that is disabled by the QF framework. The value is suitable -* for the NVIC_SetPriority() CMSIS function. -* -* Only ISRs prioritized at or below the QF_AWARE_ISR_CMSIS_PRI level (i.e., -* with the numerical values of priorities equal or higher than -* QF_AWARE_ISR_CMSIS_PRI) are allowed to call the QK_ISR_ENTRY/QK_ISR_ENTRY -* macros or any other QF/QK services. These ISRs are "QF-aware". -* -* Conversely, any ISRs prioritized above the QF_AWARE_ISR_CMSIS_PRI priority -* level (i.e., with the numerical values of priorities less than -* QF_AWARE_ISR_CMSIS_PRI) are never disabled and are not aware of the kernel. -* Such "QF-unaware" ISRs cannot call any QF/QK services. In particular they -* can NOT call the macros QK_ISR_ENTRY/QK_ISR_ENTRY. The only mechanism -* by which a "QF-unaware" ISR can communicate with the QF framework is by -* triggering a "QF-aware" ISR, which can post/publish events. -* -* NOTE2: -* The User LED is used to visualize the idle loop activity. The brightness -* of the LED is proportional to the frequency of invcations of the idle loop. -* Please note that the LED is toggled with interrupts locked, so no interrupt -* execution time contributes to the brightness of the User LED. -* -* NOTE3: -* GPIO_EVEN_IRQHandler() is for testing various preemption scenarios in QK. -* The general testing strategy is to trigger this IRQ manually from the -* debugger. To do so in IAR, you need to: -* 1. open the Register view -* 2. open NVIC registers -* 3. scroll down to NVIC_ISPR0 register -* 4. write 0x200 to NVIC_ISPR0.SETPEND register -*/ +//============================================================================ +// NOTE1: +// The QF_AWARE_ISR_CMSIS_PRI constant from the QF port specifies the highest +// ISR priority that is disabled by the QF framework. The value is suitable +// for the NVIC_SetPriority() CMSIS function. +// +// Only ISRs prioritized at or below the QF_AWARE_ISR_CMSIS_PRI level (i.e., +// with the numerical values of priorities equal or higher than +// QF_AWARE_ISR_CMSIS_PRI) are allowed to call the QK_ISR_ENTRY/ +// QK_ISR_ENTRY macros or any other QF/QK services. These ISRs are +// "QF-aware". +// +// Conversely, any ISRs prioritized above the QF_AWARE_ISR_CMSIS_PRI priority +// level (i.e., with the numerical values of priorities less than +// QF_AWARE_ISR_CMSIS_PRI) are never disabled and are not aware of the kernel. +// Such "QF-unaware" ISRs cannot call ANY QF/QK services. In particular they +// can NOT call the macros QK_ISR_ENTRY/QK_ISR_ENTRY. The only mechanism +// by which a "QF-unaware" ISR can communicate with the QF framework is by +// triggering a "QF-aware" ISR, which can post/publish events. +// +// NOTE2: +// The User LED is used to visualize the idle loop activity. The brightness +// of the LED is proportional to the frequency of the idle loop. +// Please note that the LED is toggled with interrupts locked, so no interrupt +// execution time contributes to the brightness of the User LED. +// diff --git a/examples/arm-cm/dpp_efm32-slstk3401a/qk/gnu/Makefile b/examples/arm-cm/dpp_efm32-slstk3401a/qk/gnu/Makefile index 3d08a149..6532d3ff 100644 --- a/examples/arm-cm/dpp_efm32-slstk3401a/qk/gnu/Makefile +++ b/examples/arm-cm/dpp_efm32-slstk3401a/qk/gnu/Makefile @@ -1,7 +1,7 @@ ############################################################################## # Product: Makefile for QP/C on EMF32-SLSTK3401A, QK kernel, GNU-ARM -# Last Updated for Version: 7.2.1 -# Date of the Last Update: 2023-01-14 +# Last Updated for Version: 7.3.0 +# Date of the Last Update: 2023-09-02 # # Q u a n t u m L e a P s # ------------------------ @@ -78,6 +78,7 @@ VPATH = \ # list of all include directories needed by this project INCLUDES = \ + -I.. \ -I../.. \ -I$(QPC)/include \ -I$(QP_PORT_DIR) \ @@ -138,8 +139,7 @@ LIBS := # defines DEFINES := -DEFM32PG1B200F256GM48=1 \ - -DQK_USE_IRQ_NUM=33 \ - -DQK_USE_IRQ_HANDLER=FPUEH_IRQHandler + -DQP_CONFIG # ARM CPU, ARCH, FPU, and Float-ABI types... # ARM_CPU: [cortex-m0 | cortex-m0plus | cortex-m1 | cortex-m3 | cortex-m4] @@ -193,7 +193,8 @@ BIN_DIR := rel ASFLAGS = $(ARM_CPU) $(ARM_FPU) $(ASM_CPU) $(ASM_FPU) -CFLAGS = -c $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \ +CFLAGS = -c $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb \ + -std=c11 -pedantic -Wall -Wextra -W \ -ffunction-sections -fdata-sections \ -O1 $(INCLUDES) $(DEFINES) -DNDEBUG @@ -209,7 +210,8 @@ C_SRCS += $(QS_SRCS) ASFLAGS = -g $(ARM_CPU) $(ARM_FPU) $(ASM_CPU) $(ASM_FPU) -CFLAGS = -c -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \ +CFLAGS = -c -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb \ + -std=c11 -pedantic -Wall -Wextra -W \ -ffunction-sections -fdata-sections \ -O $(INCLUDES) $(DEFINES) -DQ_SPY @@ -223,7 +225,8 @@ BIN_DIR := dbg ASFLAGS = -g $(ARM_CPU) $(ARM_FPU) $(ASM_CPU) $(ASM_FPU) -CFLAGS = -c -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \ +CFLAGS = -c -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb \ + -std=c11 -pedantic -Wall -Wextra -W \ -ffunction-sections -fdata-sections \ -O $(INCLUDES) $(DEFINES) @@ -267,7 +270,7 @@ $(TARGET_BIN): $(TARGET_ELF) $(BIN) -O binary $< $@ $(TARGET_ELF) : $(ASM_OBJS_EXT) $(C_OBJS_EXT) $(CPP_OBJS_EXT) - $(CC) $(CFLAGS) $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o + $(CC) $(CFLAGS) $(QPC)/src/qs/qstamp.c -o $(BIN_DIR)/qstamp.o $(LINK) $(LINKFLAGS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) $(BIN_DIR)/%.d : %.c diff --git a/examples/arm-cm/dpp_efm32-slstk3401a/qk/iar/dpp-qk.ewd b/examples/arm-cm/dpp_efm32-slstk3401a/qk/iar/dpp-qk.ewd index 42451eb1..cb16c888 100644 --- a/examples/arm-cm/dpp_efm32-slstk3401a/qk/iar/dpp-qk.ewd +++ b/examples/arm-cm/dpp_efm32-slstk3401a/qk/iar/dpp-qk.ewd @@ -11,7 +11,7 @@ C-SPY 2 - 28 + 32 1 1 - - + + + + +
@@ -486,7 +498,7 @@ IJET_ID 2 - 8 + 9 1 1 + + + + + + + + + + + + + @@ -916,7 +980,7 @@ LMIFTDI_ID 2 - 2 + 3 1 1 + + + + + + + NULINK_ID + 2 + + 0 + 1 + 1 + + + @@ -974,7 +1072,7 @@ STLINK_ID 2 - 4 + 8 1 1 + + + + @@ -1185,7 +1300,7 @@ XDS100_ID 2 - 6 + 9 1 1 + + + + @@ -1362,6 +1493,18 @@ $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin 0 + + $TOOLKIT_DIR$\plugins\rtos\FreeRtos\FreeRtosArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin2.ENU.ewplugin + 0 + $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin 0 @@ -1371,11 +1514,15 @@ 0 - $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9.ewplugin 0 - $TOOLKIT_DIR$\plugins\rtos\TI-RTOS\tirtosplugin.ewplugin + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9BE.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin 0 @@ -1391,11 +1538,11 @@ 0 - $EW_DIR$\common\plugins\CodeCoverage\CodeCoverage.ENU.ewplugin - 1 + $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + 0 - $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + $EW_DIR$\common\plugins\TargetAccessServer\TargetAccessServer.ENU.ewplugin 0 @@ -1414,7 +1561,7 @@ C-SPY 2 - 28 + 32 1 0 - - + + + + + @@ -1889,7 +2048,7 @@ IJET_ID 2 - 8 + 9 1 0 + + + + + + + + + + + + + @@ -2319,7 +2530,7 @@ LMIFTDI_ID 2 - 2 + 3 1 0 + + + + + + + NULINK_ID + 2 + + 0 + 1 + 0 + + + @@ -2377,7 +2622,7 @@ STLINK_ID 2 - 4 + 8 1 0 + + + + @@ -2588,7 +2850,7 @@ XDS100_ID 2 - 6 + 9 1 0 + + + + @@ -2765,6 +3043,18 @@ $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin 0 + + $TOOLKIT_DIR$\plugins\rtos\FreeRtos\FreeRtosArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin2.ENU.ewplugin + 0 + $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin 0 @@ -2774,11 +3064,15 @@ 0 - $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9.ewplugin 0 - $TOOLKIT_DIR$\plugins\rtos\TI-RTOS\tirtosplugin.ewplugin + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9BE.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin 0 @@ -2794,11 +3088,11 @@ 0 - $EW_DIR$\common\plugins\CodeCoverage\CodeCoverage.ENU.ewplugin - 1 + $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + 0 - $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + $EW_DIR$\common\plugins\TargetAccessServer\TargetAccessServer.ENU.ewplugin 0 @@ -2817,7 +3111,7 @@ C-SPY 2 - 28 + 32 1 1 - - + + + + + @@ -3292,7 +3598,7 @@ IJET_ID 2 - 8 + 9 1 1 + + + + + + + + + + + + + @@ -3722,7 +4080,7 @@ LMIFTDI_ID 2 - 2 + 3 1 1 + + + + + + + NULINK_ID + 2 + + 0 + 1 + 1 + + + @@ -3780,7 +4172,7 @@ STLINK_ID 2 - 4 + 8 1 1 + + + + @@ -3991,7 +4400,7 @@ XDS100_ID 2 - 6 + 9 1 1 + + + + @@ -4168,6 +4593,18 @@ $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin 0 + + $TOOLKIT_DIR$\plugins\rtos\FreeRtos\FreeRtosArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin2.ENU.ewplugin + 0 + $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin 0 @@ -4177,11 +4614,15 @@ 0 - $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9.ewplugin 0 - $TOOLKIT_DIR$\plugins\rtos\TI-RTOS\tirtosplugin.ewplugin + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9BE.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin 0 @@ -4197,11 +4638,11 @@ 0 - $EW_DIR$\common\plugins\CodeCoverage\CodeCoverage.ENU.ewplugin - 1 + $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + 0 - $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + $EW_DIR$\common\plugins\TargetAccessServer\TargetAccessServer.ENU.ewplugin 0 diff --git a/examples/arm-cm/dpp_efm32-slstk3401a/qk/iar/dpp-qk.ewp b/examples/arm-cm/dpp_efm32-slstk3401a/qk/iar/dpp-qk.ewp index 27f1d68a..bc6b65ba 100644 --- a/examples/arm-cm/dpp_efm32-slstk3401a/qk/iar/dpp-qk.ewp +++ b/examples/arm-cm/dpp_efm32-slstk3401a/qk/iar/dpp-qk.ewp @@ -11,7 +11,7 @@ General 3 - 33 + 35 1 1 + + + @@ -674,7 +686,7 @@ ILINK 0 - 25 + 27 1 1 + + + + @@ -1065,12 +1093,12 @@ General 3 - 33 + 35 1 0 + + + @@ -1727,7 +1767,7 @@ ILINK 0 - 25 + 27 1 0 + + + + @@ -2118,12 +2174,12 @@ General 3 - 33 + 35 1 1 + + + @@ -2322,6 +2390,7 @@ @@ -3173,14 +3258,11 @@ $PROJ_DIR$\..\..\dpp.h - $PROJ_DIR$\..\main.c + $PROJ_DIR$\..\..\main.c $PROJ_DIR$\..\..\philo.c - - $PROJ_DIR$\..\..\..\..\..\include\qstamp.c - $PROJ_DIR$\..\..\table.c @@ -3273,10 +3355,10 @@ $PROJ_DIR$\..\..\..\..\..\src\qs\qs_fp.c - $PROJ_DIR$\..\..\..\..\..\src\qs_pkg.h + $PROJ_DIR$\..\..\..\..\..\src\qs\qs_rx.c - $PROJ_DIR$\..\..\..\..\..\src\qs\qs_rx.c + $PROJ_DIR$\..\..\..\..\..\src\qs\qstamp.c diff --git a/examples/arm-cm/dpp_efm32-slstk3401a/qk/main.c b/examples/arm-cm/dpp_efm32-slstk3401a/qk/main.c deleted file mode 100644 index 9e0b1e48..00000000 --- a/examples/arm-cm/dpp_efm32-slstk3401a/qk/main.c +++ /dev/null @@ -1,84 +0,0 @@ -/***************************************************************************** -* Product: DPP example -* Last updated for version 7.1.1 -* Last updated on 2022-09-22 -* -* Q u a n t u m L e a P s -* ------------------------ -* Modern Embedded Software -* -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* -* -*****************************************************************************/ -#include "qpc.h" -#include "dpp.h" -#include "bsp.h" - -Q_DEFINE_THIS_FILE - -static QTicker l_ticker0; -QActive *the_Ticker0 = &l_ticker0.super; - -/*..........................................................................*/ -int main() { - static QEvt const *tableQueueSto[N_PHILO]; - static QEvt const *philoQueueSto[N_PHILO][N_PHILO]; - static QSubscrList subscrSto[MAX_PUB_SIG]; - static QF_MPOOL_EL(TableEvt) smlPoolSto[2*N_PHILO]; /* small pool */ - QTicker_ctor(&l_ticker0, 0U); /* ticker AO for tick rate 0 */ - - QF_init(); /* initialize the framework and the underlying RT kernel */ - BSP_init(); /* initialize the Board Support Package */ - - /* initialize publish-subscribe... */ - QF_psInit(subscrSto, Q_DIM(subscrSto)); - - /* initialize event pools... */ - QF_poolInit(smlPoolSto, sizeof(smlPoolSto), sizeof(smlPoolSto[0])); - - QACTIVE_START(the_Ticker0, 1U, 0, 0, 0, 0, 0); - - /* start the active objects... */ - for (uint8_t n = 0U; n < N_PHILO; ++n) { - Philo_ctor(n); /* instantiate Philo[n] AO */ - QACTIVE_START(AO_Philo[n], /* AO to start */ - Q_PRIO(n + 2U, N_PHILO + 1U),/* QF-prio/pre-thre. */ - philoQueueSto[n], /* event queue storage */ - Q_DIM(philoQueueSto[n]), /* queue length [events] */ - (void *)0, /* stack storage (not used) */ - 0U, /* size of the stack [bytes] */ - (QEvt *)0); /* initialization event */ - } - - Table_ctor(); /* instantiate the Table active object */ - QACTIVE_START(AO_Table, /* AO to start */ - N_PHILO + 2U, /* QF-prio/pre-thre. */ - tableQueueSto, /* event queue storage */ - Q_DIM(tableQueueSto), /* queue length [events] */ - (void *)0, /* stack storage (not used) */ - 0U, /* size of the stack [bytes] */ - (QEvt *)0); /* initialization event */ - - return QF_run(); /* run the QF application */ -} diff --git a/examples/arm-cm/dpp_efm32-slstk3401a/qk/qspy_pthre0.txt b/examples/arm-cm/dpp_efm32-slstk3401a/qk/qspy_pthre0.txt deleted file mode 100644 index 8580fdb3..00000000 --- a/examples/arm-cm/dpp_efm32-slstk3401a/qk/qspy_pthre0.txt +++ /dev/null @@ -1,79 +0,0 @@ -0045455691 Sch-Idle Pri=1->0 - TE0-ADis Obj=Philo_inst[2].timeEvt,AO=Philo_inst[2] -0053770644 TE0-Post Obj=Philo_inst[2].timeEvt,Sig=TIMEOUT_SIG,AO=Philo_inst[2] -0053771337 AO-Post Sdr=l_SysTick_Handler,Obj=Philo_inst[2],Evt,Que -0053772439 Sch-Next Pri=0->3 -0053772827 AO-GetL Obj=Philo_inst[2],Evt -0053773411 Disp===> Obj=Philo_inst[2],Sig=TIMEOUT_SIG,State=Philo_eating -0053774335 MP-Get Obj=EvtPool1,Free=9,Min=8 -0053774896 QF-New Sig=DONE_SIG,Size=6 -0053775356 QF-Pub Sdr=Philo_inst[2],Evt -0053775958 Sch-Lock Ceil=0->6 -0053776428 AO-Post Sdr=Philo_inst[2],Obj=Table_inst,Evt,Que -0053777295 Sch-Unlk Ceil=6->0 -0053777749 Sch-Next Pri=3->6 -0053778131 AO-GetL Obj=Table_inst,Evt -0053778715 Disp===> Obj=Table_inst,Sig=DONE_SIG,State=Table_serving -0053779422 PHILO_STAT 2 thinking -0053780152 MP-Get Obj=EvtPool1,Free=8,Min=8 -0053780713 QF-New Sig=EAT_SIG,Size=6 -0053781163 QF-Pub Sdr=Table_inst,Evt -0053781750 Sch-Lock Ceil=0->6 -0053782202 AO-Post Sdr=Table_inst,Obj=Table_inst,Evt,Que -0053783101 AO-Post Sdr=Table_inst,Obj=Philo_inst[4],Evt,Que -0053784001 AO-Post Sdr=Table_inst,Obj=Philo_inst[3],Evt,Que -0053784901 AO-Post Sdr=Table_inst,Obj=Philo_inst[2],Evt,Que -0053785801 AO-Post Sdr=Table_inst,Obj=Philo_inst[1],Evt,Que -0053786701 AO-Post Sdr=Table_inst,Obj=Philo_inst[0],Evt,Que -0053787560 Sch-Unlk Ceil=6->0 -0053787984 QF-gcA Evt -0053788466 PHILO_STAT 3 eating -0053789030 =>Intern Obj=Table_inst,Sig=DONE_SIG,State=Table_serving -0053789667 QF-gcA Evt -0053790128 Sch-Next Pri=6->6 -0053790504 AO-GetL Obj=Table_inst,Evt -0053791087 Disp===> Obj=Table_inst,Sig=EAT_SIG,State=Table_serving -0053791796 =>Intern Obj=Table_inst,Sig=EAT_SIG,State=Table_active -0053792427 QF-gcA Evt -0053792901 Sch-Next Pri=6->5 -0053793273 AO-GetL Obj=Philo_inst[4],Evt -0053793856 Disp===> Obj=Philo_inst[4],Sig=EAT_SIG,State=Philo_thinking -0053794533 =>Intern Obj=Philo_inst[4],Sig=EAT_SIG,State=Philo_thinking -0053795165 QF-gcA Evt -0053795639 Sch-Next Pri=5->4 -0053796011 AO-GetL Obj=Philo_inst[3],Evt -0053796594 Disp===> Obj=Philo_inst[3],Sig=EAT_SIG,State=Philo_hungry -0053797557 Sch-Lock Ceil=0->5 -0053797959 Sch-Unlk Ceil=5->0 -0053798428 TE0-Arm Obj=Philo_inst[3].timeEvt,AO=Philo_inst[3],Tim=197,Int=0 -===RTC===> St-Entry Obj=Philo_inst[3],State=Philo_eating -0053799586 ===>Tran Obj=Philo_inst[3],Sig=EAT_SIG,State=Philo_hungry->Philo_eating -0053800328 QF-gcA Evt -0053800804 Sch-Rsme Prio=4->3 -0053801202 QF-gc Evt -0053801667 MP-Put Obj=EvtPool1,Free=9 -0053802194 TE0-DisA Obj=Philo_inst[2].timeEvt,AO=Philo_inst[2] -===RTC===> St-Exit Obj=Philo_inst[2],State=Philo_eating -0053803294 Sch-Lock Ceil=0->5 -0053803694 Sch-Unlk Ceil=5->0 -0053804165 TE0-Arm Obj=Philo_inst[2].timeEvt,AO=Philo_inst[2],Tim=77,Int=0 -===RTC===> St-Entry Obj=Philo_inst[2],State=Philo_thinking -0053805318 ===>Tran Obj=Philo_inst[2],Sig=TIMEOUT_SIG,State=Philo_eating->Philo_thinking -0053806100 Sch-Next Pri=3->3 -0053806487 AO-GetL Obj=Philo_inst[2],Evt -0053807071 Disp===> Obj=Philo_inst[2],Sig=EAT_SIG,State=Philo_thinking -0053807760 =>Intern Obj=Philo_inst[2],Sig=EAT_SIG,State=Philo_thinking -0053808392 QF-gcA Evt -0053808867 Sch-Next Pri=3->2 -0053809239 AO-GetL Obj=Philo_inst[1],Evt -0053809822 Disp===> Obj=Philo_inst[1],Sig=EAT_SIG,State=Philo_hungry -===RTC===> St-Unhnd Obj=Philo_inst[1],Sig=EAT_SIG,State=Philo_hungry -0053810966 =>Ignore Obj=Philo_inst[1],Sig=EAT_SIG,State=Philo_hungry -0053811583 QF-gcA Evt -0053812054 Sch-Next Pri=2->1 -0053812427 AO-GetL Obj=Philo_inst[0],Evt -0053813010 Disp===> Obj=Philo_inst[0],Sig=EAT_SIG,State=Philo_eating -0053813685 =>Intern Obj=Philo_inst[0],Sig=EAT_SIG,State=Philo_eating -0053814318 QF-gc Evt -0053814781 MP-Put Obj=EvtPool1,Free=10 -0053815312 Sch-Idle Pri=1->0 diff --git a/examples/arm-cm/dpp_efm32-slstk3401a/qk/qspy_pthre1.txt b/examples/arm-cm/dpp_efm32-slstk3401a/qk/qspy_pthre1.txt deleted file mode 100644 index c166059d..00000000 --- a/examples/arm-cm/dpp_efm32-slstk3401a/qk/qspy_pthre1.txt +++ /dev/null @@ -1,79 +0,0 @@ -0045455658 Sch-Idle Pri=1->0 - TE0-ADis Obj=Philo_inst[2].timeEvt,AO=Philo_inst[2] -0053770644 TE0-Post Obj=Philo_inst[2].timeEvt,Sig=TIMEOUT_SIG,AO=Philo_inst[2] -0053771338 AO-Post Sdr=l_SysTick_Handler,Obj=Philo_inst[2],Evt,Que -0053772441 Sch-Next Pri=0->3 -0053772827 AO-GetL Obj=Philo_inst[2],Evt -0053773412 Disp===> Obj=Philo_inst[2],Sig=TIMEOUT_SIG,State=Philo_eating -0053774333 MP-Get Obj=EvtPool1,Free=9,Min=8 -0053774896 QF-New Sig=DONE_SIG,Size=6 -0053775356 QF-Pub Sdr=Philo_inst[2],Evt -0053775957 Sch-Lock Ceil=0->2 -0053776427 AO-Post Sdr=Philo_inst[2],Obj=Table_inst,Evt,Que -0053777293 Sch-Unlk Ceil=2->0 -0053777742 Sch-Next Pri=3->6 -0053778121 AO-GetL Obj=Table_inst,Evt -0053778706 Disp===> Obj=Table_inst,Sig=DONE_SIG,State=Table_serving -0053779419 PHILO_STAT 2 thinking -0053780149 MP-Get Obj=EvtPool1,Free=8,Min=8 -0053780712 QF-New Sig=EAT_SIG,Size=6 -0053781162 QF-Pub Sdr=Table_inst,Evt -0053781749 Sch-Lock Ceil=0->2 -0053782201 AO-Post Sdr=Table_inst,Obj=Table_inst,Evt,Que -0053783100 AO-Post Sdr=Table_inst,Obj=Philo_inst[4],Evt,Que -0053783993 AO-Post Sdr=Table_inst,Obj=Philo_inst[3],Evt,Que -0053784886 AO-Post Sdr=Table_inst,Obj=Philo_inst[2],Evt,Que -0053785779 AO-Post Sdr=Table_inst,Obj=Philo_inst[1],Evt,Que -0053786672 AO-Post Sdr=Table_inst,Obj=Philo_inst[0],Evt,Que -0053787523 Sch-Unlk Ceil=2->0 -0053787943 QF-gcA Evt -0053788426 PHILO_STAT 3 eating -0053788992 =>Intern Obj=Table_inst,Sig=DONE_SIG,State=Table_serving -0053789639 QF-gcA Evt -0053790098 Sch-Next Pri=6->6 -0053790474 AO-GetL Obj=Table_inst,Evt -0053791059 Disp===> Obj=Table_inst,Sig=EAT_SIG,State=Table_serving -0053791774 =>Intern Obj=Table_inst,Sig=EAT_SIG,State=Table_active -0053792405 QF-gcA Evt -0053792872 Sch-Rsme Prio=6->3 -0053793269 QF-gc Evt -0053793733 MP-Put Obj=EvtPool1,Free=9 -0053794259 TE0-DisA Obj=Philo_inst[2].timeEvt,AO=Philo_inst[2] -===RTC===> St-Exit Obj=Philo_inst[2],State=Philo_eating -0053795376 Sch-Lock Ceil=0->5 -0053795777 Sch-Unlk Ceil=5->0 -0053796248 TE0-Arm Obj=Philo_inst[2].timeEvt,AO=Philo_inst[2],Tim=147,Int=0 -===RTC===> St-Entry Obj=Philo_inst[2],State=Philo_thinking -0053797402 ===>Tran Obj=Philo_inst[2],Sig=TIMEOUT_SIG,State=Philo_eating->Philo_thinking -0053798185 Sch-Next Pri=3->5 -0053798573 AO-GetL Obj=Philo_inst[4],Evt -0053799158 Disp===> Obj=Philo_inst[4],Sig=EAT_SIG,State=Philo_thinking -0053799844 =>Intern Obj=Philo_inst[4],Sig=EAT_SIG,State=Philo_thinking -0053800478 QF-gcA Evt -0053800951 Sch-Next Pri=5->4 -0053801324 AO-GetL Obj=Philo_inst[3],Evt -0053801906 Disp===> Obj=Philo_inst[3],Sig=EAT_SIG,State=Philo_hungry -0053802845 Sch-Lock Ceil=0->5 -0053803248 Sch-Unlk Ceil=5->0 -0053803717 TE0-Arm Obj=Philo_inst[3].timeEvt,AO=Philo_inst[3],Tim=127,Int=0 -===RTC===> St-Entry Obj=Philo_inst[3],State=Philo_eating -0053804870 ===>Tran Obj=Philo_inst[3],Sig=EAT_SIG,State=Philo_hungry->Philo_eating -0053805615 QF-gcA Evt -0053806094 Sch-Next Pri=4->3 -0053806470 AO-GetL Obj=Philo_inst[2],Evt -0053807055 Disp===> Obj=Philo_inst[2],Sig=EAT_SIG,State=Philo_thinking -0053807741 =>Intern Obj=Philo_inst[2],Sig=EAT_SIG,State=Philo_thinking -0053808384 QF-gcA Evt -0053808855 Sch-Next Pri=3->2 -0053809228 AO-GetL Obj=Philo_inst[1],Evt -0053809810 Disp===> Obj=Philo_inst[1],Sig=EAT_SIG,State=Philo_hungry -===RTC===> St-Unhnd Obj=Philo_inst[1],Sig=EAT_SIG,State=Philo_hungry -0053810949 =>Ignore Obj=Philo_inst[1],Sig=EAT_SIG,State=Philo_hungry -0053811567 QF-gcA Evt -0053812037 Sch-Next Pri=2->1 -0053812413 AO-GetL Obj=Philo_inst[0],Evt -0053812998 Disp===> Obj=Philo_inst[0],Sig=EAT_SIG,State=Philo_eating -0053813671 =>Intern Obj=Philo_inst[0],Sig=EAT_SIG,State=Philo_eating -0053814305 QF-gc Evt -0053814766 MP-Put Obj=EvtPool1,Free=10 -0053815296 Sch-Idle Pri=1->0 diff --git a/examples/arm-cm/dpp_efm32-slstk3401a/qp_config.h b/examples/arm-cm/dpp_efm32-slstk3401a/qp_config.h new file mode 100644 index 00000000..cbfee362 --- /dev/null +++ b/examples/arm-cm/dpp_efm32-slstk3401a/qp_config.h @@ -0,0 +1,59 @@ +//============================================================================ +// QP configuration file example +// Last updated for version: 7.3.0 +// Last updated on: 2023-09-07 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +//============================================================================ +#ifndef QP_CONFIG_H_ +#define QP_CONFIG_H_ + +// NOTE: +// The QP configuration takes effect only when the macro QP_CONFIG +// is defined on the command-line to the compiler for all QP source files. + +// use event constructors for dynamic events +#define QEVT_DYN_CTOR + +// for QK kernel: +// use the FPUEH_IRQHandler() with IRQ number 33 +// for the QXK return-from-preemption handler +#define QK_USE_IRQ_HANDLER FPUEH_IRQHandler +#define QK_USE_IRQ_NUM 33 + +// for QXK kernel: +// use the FPUEH_IRQHandler() with IRQ number 33 +// for the QXK return-from-preemption handler +#define QXK_USE_IRQ_HANDLER FPUEH_IRQHandler +#define QXK_USE_IRQ_NUM 33 + +#ifdef Q_SPY +// for the Spy build configuration, enable the context-switch callback +#define QF_ON_CONTEXT_SW +#endif + +#endif // QP_CONFIG_H_ diff --git a/examples/arm-cm/dpp_efm32-slstk3401a/qspy-output.png b/examples/arm-cm/dpp_efm32-slstk3401a/qspy-output.png new file mode 100644 index 00000000..ee764450 Binary files /dev/null and b/examples/arm-cm/dpp_efm32-slstk3401a/qspy-output.png differ diff --git a/examples/arm-cm/dpp_efm32-slstk3401a/qv/armclang/dpp-qv.sct b/examples/arm-cm/dpp_efm32-slstk3401a/qv/armclang/dpp-qv.sct new file mode 100644 index 00000000..794d15cc --- /dev/null +++ b/examples/arm-cm/dpp_efm32-slstk3401a/qv/armclang/dpp-qv.sct @@ -0,0 +1,23 @@ +; ************************************************************* +; *** Scatter-Loading Description File generated by uVision *** +; +; Modified by Quantum Leaps: +; added STACK as the first section in RW_STACK +; ************************************************************* + +LR_IROM1 0x00000000 0x00020000 { ; load region size_region + ER_IROM1 0x00000000 0x00020000 { ; load address = execution address + *.o (RESET, +First) + *(InRoot$$Sections) + .ANY (+RO) + .ANY (+XO) + } + + RW_STACK 0x20000000 { ; <== Quantum Leaps + * (STACK, +First) + } + RW_IRAM1 +0 (0x00008000 - 2048) { ; NOTE: assume STACK size 2048! + .ANY (+RW +ZI) + } +} + diff --git a/examples/arm-cm/dpp_efm32-slstk3401a/qv/armclang/dpp-qv.uvoptx b/examples/arm-cm/dpp_efm32-slstk3401a/qv/armclang/dpp-qv.uvoptx index f8faded1..776b93a1 100644 --- a/examples/arm-cm/dpp_efm32-slstk3401a/qv/armclang/dpp-qv.uvoptx +++ b/examples/arm-cm/dpp_efm32-slstk3401a/qv/armclang/dpp-qv.uvoptx @@ -10,7 +10,7 @@ *.s*; *.src; *.a* *.obj; *.o *.lib - *.txt; *.h; *.inc + *.txt; *.h; *.inc; *.md *.plm *.cpp 0 @@ -103,7 +103,7 @@ 1 0 0 - 3 + 4 @@ -117,6 +117,11 @@ Segger\JL2CM3.dll + + 0 + DLGUARM + + 0 JL2CM3 @@ -135,7 +140,7 @@ 0 DLGTARM - (1010=-1,-1,-1,-1,0)(1007=-1,-1,-1,-1,0)(1008=-1,-1,-1,-1,0)(1009=-1,-1,-1,-1,0)(1012=-1,-1,-1,-1,0) + (1010=-1,-1,-1,-1,0)(1007=-1,-1,-1,-1,0)(1008=-1,-1,-1,-1,0)(1009=-1,-1,-1,-1,0)(1012=1837,174,2314,489,0) 0 @@ -148,7 +153,40 @@ -U0E2006F4 -O4622 -S4 -FO61 - + + + 0 + 0 + 157 + 1 +
5844
+ 0 + 0 + 0 + 0 + 0 + 1 + ..\..\..\..\..\src\qv\qv.c + + \\dpp_qv\../../../../../src/qv/qv.c\157 +
+ + 1 + 0 + 424 + 1 +
9240
+ 0 + 0 + 0 + 0 + 0 + 1 + ..\bsp.c + + \\dpp_qv\../bsp.c\424 +
+
1 @@ -292,7 +330,7 @@ 1 0 0 - 3 + 4 @@ -486,7 +524,7 @@ 1 0 0 - 3 + 4 @@ -600,7 +638,7 @@ Applicatioin - 0 + 1 0 0 0 @@ -631,30 +669,6 @@ 1 3 - 1 - 0 - 0 - 0 - ..\..\..\..\..\include\qstamp.c - qstamp.c - 0 - 0 - - - 1 - 4 - 1 - 0 - 0 - 0 - ..\main.c - main.c - 0 - 0 - - - 1 - 5 5 0 0 @@ -666,7 +680,7 @@ 1 - 6 + 4 1 0 0 @@ -678,7 +692,7 @@ 1 - 7 + 5 1 0 0 @@ -688,6 +702,18 @@ 0 0 + + 1 + 6 + 1 + 0 + 0 + 0 + ..\..\main.c + main.c + 0 + 0 + @@ -698,7 +724,7 @@ 0 2 - 8 + 7 2 0 0 @@ -710,7 +736,7 @@ 2 - 9 + 8 1 0 0 @@ -722,7 +748,7 @@ 2 - 10 + 9 1 0 0 @@ -734,7 +760,7 @@ 2 - 11 + 10 1 0 0 @@ -746,7 +772,7 @@ 2 - 12 + 11 1 0 0 @@ -758,7 +784,7 @@ 2 - 13 + 12 1 0 0 @@ -770,7 +796,7 @@ 2 - 14 + 13 1 0 0 @@ -790,7 +816,7 @@ 0 3 - 15 + 14 1 0 0 @@ -802,7 +828,7 @@ 3 - 16 + 15 1 0 0 @@ -814,7 +840,7 @@ 3 - 17 + 16 1 0 0 @@ -826,7 +852,7 @@ 3 - 18 + 17 1 0 0 @@ -838,7 +864,7 @@ 3 - 19 + 18 1 0 0 @@ -850,7 +876,7 @@ 3 - 20 + 19 1 0 0 @@ -862,7 +888,7 @@ 3 - 21 + 20 1 0 0 @@ -874,7 +900,7 @@ 3 - 22 + 21 1 0 0 @@ -886,7 +912,7 @@ 3 - 23 + 22 1 0 0 @@ -898,7 +924,7 @@ 3 - 24 + 23 1 0 0 @@ -910,7 +936,7 @@ 3 - 25 + 24 1 0 0 @@ -922,7 +948,7 @@ 3 - 26 + 25 1 0 0 @@ -934,7 +960,7 @@ 3 - 27 + 26 1 0 0 @@ -954,43 +980,7 @@ 0 4 - 28 - 5 - 0 - 0 - 0 - ..\..\..\..\..\ports\arm-cm\qv\armclang\qep_port.h - qep_port.h - 0 - 0 - - - 4 - 29 - 5 - 0 - 0 - 0 - ..\..\..\..\..\ports\arm-cm\qv\armclang\qf_port.h - qf_port.h - 0 - 0 - - - 4 - 30 - 5 - 0 - 0 - 0 - ..\..\..\..\..\ports\arm-cm\qv\armclang\qs_port.h - qs_port.h - 0 - 0 - - - 4 - 31 + 27 1 0 0 @@ -1000,18 +990,6 @@ 0 0 - - 4 - 32 - 5 - 0 - 0 - 0 - ..\..\..\..\..\ports\arm-cm\qv\armclang\qv_port.h - qv_port.h - 0 - 0 - @@ -1022,7 +1000,7 @@ 0 5 - 33 + 28 1 0 0 @@ -1034,7 +1012,7 @@ 5 - 34 + 29 1 0 0 @@ -1046,7 +1024,7 @@ 5 - 35 + 30 1 0 0 @@ -1058,7 +1036,7 @@ 5 - 36 + 31 1 0 0 @@ -1068,6 +1046,18 @@ 0 0 + + 5 + 32 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qs\qstamp.c + qstamp.c + 0 + 0 + diff --git a/examples/arm-cm/dpp_efm32-slstk3401a/qv/armclang/dpp-qv.uvprojx b/examples/arm-cm/dpp_efm32-slstk3401a/qv/armclang/dpp-qv.uvprojx index 11c606a9..ae1604c0 100644 --- a/examples/arm-cm/dpp_efm32-slstk3401a/qv/armclang/dpp-qv.uvprojx +++ b/examples/arm-cm/dpp_efm32-slstk3401a/qv/armclang/dpp-qv.uvprojx @@ -10,13 +10,13 @@ dpp-dbg 0x4 ARM-ADS - 6070000::V6.7::.\ARMCLANG + 6160000::V6.16::ARMCLANG 1 EFM32PG1B200F256GM48 Silicon Labs - SiliconLabs.EFM32PG1B_DFP.5.5.0 + SiliconLabs.GeckoPlatform_EFM32PG1B_DFP.4.0.0 https://www.silabs.com/documents/public/cmsis-packs/ IRAM(0x20000000,0x00008000) IROM(0x00000000,0x00020000) CPUTYPE("Cortex-M4") FPU2 CLOCK(12000000) ELITTLE @@ -185,6 +185,7 @@ 0 2 0 + 0 0 0 8 @@ -312,7 +313,7 @@ 0 - 2 + 1 0 0 1 @@ -336,7 +337,7 @@ 0 - EFM32PG1B200F256GM48=1 __FPU_PRESENT + EFM32PG1B200F256GM48=1 ..\..;..\..\..\..\..\include;..\..\..\..\..\ports\arm-cm\qv\armclang;..\..\..\..\..\3rd_party\CMSIS\Include;..\..\..\..\..\3rd_party\efm32pg1b @@ -351,7 +352,7 @@ 0 1 0 - 0 + 4 Stack_Size=2048 Heap_Size=16 @@ -360,7 +361,7 @@ - 1 + 0 0 0 0 @@ -369,7 +370,7 @@ 0x00000000 0x20000000 - + .\dpp-qv.sct --entry Reset_Handler @@ -392,16 +393,6 @@ 5 ..\..\dpp.h - - qstamp.c - 1 - ..\..\..\..\..\include\qstamp.c - - - main.c - 1 - ..\main.c - bsp.h 5 @@ -417,6 +408,11 @@ 1 ..\..\table.c + + main.c + 1 + ..\..\main.c + @@ -532,31 +528,11 @@ QP_port - - qep_port.h - 5 - ..\..\..\..\..\ports\arm-cm\qv\armclang\qep_port.h - - - qf_port.h - 5 - ..\..\..\..\..\ports\arm-cm\qv\armclang\qf_port.h - - - qs_port.h - 5 - ..\..\..\..\..\ports\arm-cm\qv\armclang\qs_port.h - qv_port.c 1 ..\..\..\..\..\ports\arm-cm\qv\armclang\qv_port.c - - qv_port.h - 5 - ..\..\..\..\..\ports\arm-cm\qv\armclang\qv_port.h - @@ -620,7 +596,7 @@ 2 2 2 - 2 + 0 @@ -651,6 +627,11 @@ 1 ..\..\..\..\..\src\qs\qs_rx.c + + qstamp.c + 1 + ..\..\..\..\..\src\qs\qstamp.c + @@ -659,13 +640,13 @@ dpp-rel 0x4 ARM-ADS - 6130001::V6.13.1::.\ARMCLANG + 6160000::V6.16::ARMCLANG 1 EFM32PG1B200F256GM48 Silicon Labs - SiliconLabs.EFM32PG1B_DFP.5.5.0 + SiliconLabs.GeckoPlatform_EFM32PG1B_DFP.4.0.0 https://www.silabs.com/documents/public/cmsis-packs/ IRAM(0x20000000,0x00008000) IROM(0x00000000,0x00020000) CPUTYPE("Cortex-M4") FPU2 CLOCK(12000000) ELITTLE @@ -834,6 +815,7 @@ 0 2 0 + 0 0 0 8 @@ -985,7 +967,7 @@ 0 - NDEBUG EFM32PG1B200F256GM48=1 __FPU_PRESENT + NDEBUG EFM32PG1B200F256GM48=1 ..\..;..\..\..\..\..\include;..\..\..\..\..\ports\arm-cm\qv\armclang;..\..\..\..\..\3rd_party\CMSIS\Include;..\..\..\..\..\3rd_party\efm32pg1b @@ -1000,7 +982,7 @@ 0 1 0 - 0 + 4 Stack_Size=2048 Heap_Size=16 @@ -1009,7 +991,7 @@ - 1 + 0 0 0 0 @@ -1018,7 +1000,7 @@ 0x00000000 0x20000000 - dpp-qv.sct + .\dpp-qv.sct --entry Reset_Handler @@ -1041,16 +1023,6 @@ 5 ..\..\dpp.h - - qstamp.c - 1 - ..\..\..\..\..\include\qstamp.c - - - main.c - 1 - ..\main.c - bsp.h 5 @@ -1066,6 +1038,11 @@ 1 ..\..\table.c + + main.c + 1 + ..\..\main.c + @@ -1181,31 +1158,11 @@ QP_port - - qep_port.h - 5 - ..\..\..\..\..\ports\arm-cm\qv\armclang\qep_port.h - - - qf_port.h - 5 - ..\..\..\..\..\ports\arm-cm\qv\armclang\qf_port.h - - - qs_port.h - 5 - ..\..\..\..\..\ports\arm-cm\qv\armclang\qs_port.h - qv_port.c 1 ..\..\..\..\..\ports\arm-cm\qv\armclang\qv_port.c - - qv_port.h - 5 - ..\..\..\..\..\ports\arm-cm\qv\armclang\qv_port.h - @@ -1269,7 +1226,7 @@ 2 2 2 - 2 + 0 @@ -1300,6 +1257,11 @@ 1 ..\..\..\..\..\src\qs\qs_rx.c + + qstamp.c + 1 + ..\..\..\..\..\src\qs\qstamp.c + @@ -1308,13 +1270,13 @@ dpp-spy 0x4 ARM-ADS - 6070000::V6.7::.\ARMCLANG + 6160000::V6.16::ARMCLANG 1 EFM32PG1B200F256GM48 Silicon Labs - SiliconLabs.EFM32PG1B_DFP.5.5.0 + SiliconLabs.GeckoPlatform_EFM32PG1B_DFP.4.0.0 https://www.silabs.com/documents/public/cmsis-packs/ IRAM(0x20000000,0x00008000) IROM(0x00000000,0x00020000) CPUTYPE("Cortex-M4") FPU2 CLOCK(12000000) ELITTLE @@ -1483,6 +1445,7 @@ 0 2 0 + 0 0 0 8 @@ -1634,7 +1597,7 @@ 0 - Q_SPY EFM32PG1B200F256GM48=1 __FPU_PRESENT + Q_SPY,QF_ON_CONTEXT_SW,EFM32PG1B200F256GM48=1 ..\..;..\..\..\..\..\include;..\..\..\..\..\ports\arm-cm\qv\armclang;..\..\..\..\..\3rd_party\CMSIS\Include;..\..\..\..\..\3rd_party\efm32pg1b @@ -1649,7 +1612,7 @@ 0 1 0 - 0 + 4 Stack_Size=2048 Heap_Size=16 @@ -1658,7 +1621,7 @@ - 1 + 0 0 0 0 @@ -1667,7 +1630,7 @@ 0x00000000 0x20000000 - + .\dpp-qv.sct --entry Reset_Handler @@ -1690,16 +1653,6 @@ 5 ..\..\dpp.h - - qstamp.c - 1 - ..\..\..\..\..\include\qstamp.c - - - main.c - 1 - ..\main.c - bsp.h 5 @@ -1715,6 +1668,11 @@ 1 ..\..\table.c + + main.c + 1 + ..\..\main.c + @@ -1830,31 +1788,11 @@ QP_port - - qep_port.h - 5 - ..\..\..\..\..\ports\arm-cm\qv\armclang\qep_port.h - - - qf_port.h - 5 - ..\..\..\..\..\ports\arm-cm\qv\armclang\qf_port.h - - - qs_port.h - 5 - ..\..\..\..\..\ports\arm-cm\qv\armclang\qs_port.h - qv_port.c 1 ..\..\..\..\..\ports\arm-cm\qv\armclang\qv_port.c - - qv_port.h - 5 - ..\..\..\..\..\ports\arm-cm\qv\armclang\qv_port.h - @@ -1880,6 +1818,11 @@ 1 ..\..\..\..\..\src\qs\qs_rx.c + + qstamp.c + 1 + ..\..\..\..\..\src\qs\qstamp.c + diff --git a/examples/arm-cm/dpp_efm32-slstk3401a/qv/bsp.c b/examples/arm-cm/dpp_efm32-slstk3401a/qv/bsp.c index e83d52e0..91c9613f 100644 --- a/examples/arm-cm/dpp_efm32-slstk3401a/qv/bsp.c +++ b/examples/arm-cm/dpp_efm32-slstk3401a/qv/bsp.c @@ -1,615 +1,556 @@ -/***************************************************************************** -* Product: DPP example, EFM32-SLSTK3401A board, cooperative QV kernel -* Last updated for version 7.2.0 -* Last updated on 2022-12-17 -* -* Q u a n t u m L e a P s -* ------------------------ -* Modern Embedded Software -* -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* -* -*****************************************************************************/ -#include "qpc.h" -#include "dpp.h" -#include "bsp.h" +//============================================================================ +// Product: DPP example, EFM32-SLSTK3401A board, QV kernel +// Last updated for version 7.3.0 +// Last updated on 2023-08-23 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. +// +// This program is open source software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Alternatively, this program may be distributed and modified under the +// terms of Quantum Leaps commercial licenses, which expressly supersede +// the GNU General Public License and are specifically designed for +// licensees interested in retaining the proprietary status of their code. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Contact information: +// +// +//============================================================================ +#include "qpc.h" // QP/C real-time embedded framework +#include "dpp.h" // DPP Application interface +#include "bsp.h" // Board Support Package -#include "em_device.h" /* the device specific header (SiLabs) */ -#include "em_cmu.h" /* Clock Management Unit (SiLabs) */ -#include "em_gpio.h" /* GPIO (SiLabs) */ -#include "em_usart.h" /* USART (SiLabs) */ -/* add other drivers if necessary... */ +#include "em_device.h" // the device specific header (SiLabs) +#include "em_cmu.h" // Clock Management Unit (SiLabs) +#include "em_gpio.h" // GPIO (SiLabs) +#include "em_usart.h" // USART (SiLabs) +// add other drivers if necessary... -Q_DEFINE_THIS_FILE +Q_DEFINE_THIS_FILE // define the name of this file for assertions -/* ISRs defined in this BSP ------------------------------------------------*/ -void SysTick_Handler(void); -void GPIO_EVEN_IRQHandler(void); -void USART0_RX_IRQHandler(void); - -/* Local-scope objects -----------------------------------------------------*/ +// Local-scope objects ----------------------------------------------------- #define LED_PORT gpioPortF -#define LED0_PIN 4 -#define LED1_PIN 5 +#define LED0_PIN 4U +#define LED1_PIN 5U #define PB_PORT gpioPortF -#define PB0_PIN 6 -#define PB1_PIN 7 +#define PB0_PIN 6U +#define PB1_PIN 7U -static uint32_t l_rnd; /* random seed */ +static uint32_t l_rndSeed; #ifdef Q_SPY QSTimeCtr QS_tickTime_; QSTimeCtr QS_tickPeriod_; - /* QSpy source IDs */ + // QSpy source IDs static QSpyId const l_SysTick_Handler = { 0U }; static QSpyId const l_GPIO_EVEN_IRQHandler = { 0U }; static USART_TypeDef * const l_USART0 = ((USART_TypeDef *)(0x40010000UL)); - enum AppRecords { /* application-specific trace records */ + enum AppRecords { // application-specific trace records PHILO_STAT = QS_USER, - COMMAND_STAT + PAUSED_STAT, + CONTEXT_SW, }; #endif -/*..........................................................................*/ -void SysTick_Handler(void) { - QTIMEEVT_TICK_X(0U, &l_SysTick_Handler); /* process time-evts for rate 0 */ - //QACTIVE_POST(the_Ticker0, 0, &l_SysTick_Handler); /* post to Ticker0 */ +//============================================================================ +// Error handler and ISRs... - /* Perform the debouncing of buttons. The algorithm for debouncing - * adapted from the book "Embedded Systems Dictionary" by Jack Ganssle - * and Michael Barr, page 71. - */ - /* state of the button debouncing, see below */ - static struct ButtonsDebouncing { +Q_NORETURN Q_onError(char const * const module, int_t const id) { + // NOTE: this implementation of the assertion handler is intended only + // for debugging and MUST be changed for deployment of the application + // (assuming that you ship your production code with assertions enabled). + Q_UNUSED_PAR(module); + Q_UNUSED_PAR(id); + QS_ASSERTION(module, id, 10000U); + +#ifndef NDEBUG + // light up both LEDs + GPIO->P[LED_PORT].DOUT |= ((1U << LED0_PIN) | (1U << LED1_PIN)); + // for debugging, hang on in an endless loop... + for (;;) { + } +#endif + + NVIC_SystemReset(); +} +//............................................................................ +void assert_failed(char const * const module, int_t const id); // prototype +void assert_failed(char const * const module, int_t const id) { + Q_onError(module, id); +} + +// ISRs used in the application ============================================ + +void SysTick_Handler(void); // prototype +void SysTick_Handler(void) { + + QTIMEEVT_TICK_X(0U, &l_SysTick_Handler); // time events at rate 0 + + // Perform the debouncing of buttons. The algorithm for debouncing + // adapted from the book "Embedded Systems Dictionary" by Jack Ganssle + // and Michael Barr, page 71. + // + // state of the button debouncing + static struct { uint32_t depressed; uint32_t previous; } buttons = { 0U, 0U }; - uint32_t current = ~GPIO->P[PB_PORT].DIN; /* read PB0 and BP1 */ - uint32_t tmp = buttons.depressed; /* the debounced depressed buttons */ - buttons.depressed |= (buttons.previous & current); /* set depressed */ - buttons.depressed &= (buttons.previous | current); /* clear released */ - buttons.previous = current; /* update the history */ - tmp ^= buttons.depressed; /* changed debounced depressed */ - if ((tmp & (1U << PB0_PIN)) != 0U) { /* debounced PB0 state changed? */ - if ((buttons.depressed & (1U << PB0_PIN)) != 0U) { /* PB0 depressed?*/ - static QEvt const pauseEvt = { PAUSE_SIG, 0U, 0U}; + + uint32_t current = ~GPIO->P[PB_PORT].DIN; // read PB0 and BP1 + uint32_t tmp = buttons.depressed; // save the depressed buttons + buttons.depressed |= (buttons.previous & current); // set depressed + buttons.depressed &= (buttons.previous | current); // clear released + buttons.previous = current; // update the history + tmp ^= buttons.depressed; // changed debounced depressed + current = buttons.depressed; + + if ((tmp & (1U << PB0_PIN)) != 0U) { // debounced PB0 state changed? + if ((current & (1U << PB0_PIN)) != 0U) { // is PB0 depressed? + static QEvt const pauseEvt = QEVT_INITIALIZER(PAUSE_SIG); QACTIVE_PUBLISH(&pauseEvt, &l_SysTick_Handler); } - else { /* the button is released */ - static QEvt const serveEvt = { SERVE_SIG, 0U, 0U}; + else { // the button is released + static QEvt const serveEvt = QEVT_INITIALIZER(SERVE_SIG); QACTIVE_PUBLISH(&serveEvt, &l_SysTick_Handler); } } #ifdef Q_SPY - { - tmp = SysTick->CTRL; /* clear SysTick_CTRL_COUNTFLAG */ - QS_tickTime_ += QS_tickPeriod_; /* account for the clock rollover */ - } + tmp = SysTick->CTRL; // clear CTRL_COUNTFLAG + QS_tickTime_ += QS_tickPeriod_; // account for the clock rollover #endif + QV_ARM_ERRATUM_838869(); } -/*..........................................................................*/ -void GPIO_EVEN_IRQHandler(void) { /* for testing, NOTE4 */ - QACTIVE_POST(AO_Table, Q_NEW(QEvt, MAX_PUB_SIG), /* for testing... */ - &l_GPIO_EVEN_IRQHandler); +//............................................................................ +// interrupt handler for testing preemptions in QK +void GPIO_EVEN_IRQHandler(void); // prototype +void GPIO_EVEN_IRQHandler(void) { // for testing, NOTE03 +// for testing... +// for testing... +#ifdef QEVT_DYN_CTOR + QACTIVE_PUBLISH(Q_NEW(QEvt, TEST_SIG, QEVT_DYNAMIC), + &l_GPIO_EVEN_IRQHandler); +#else + QACTIVE_PUBLISH(Q_NEW(QEvt, TEST_SIG), &l_GPIO_EVEN_IRQHandler); +#endif + + QV_ARM_ERRATUM_838869(); } -/*..........................................................................*/ + +//............................................................................ #ifdef Q_SPY -/* -* ISR for receiving bytes from the QSPY Back-End -* NOTE: This ISR is "QF-unaware" meaning that it does not interact with -* the QF/QK and is not disabled. Such ISRs don't need to call QK_ISR_ENTRY/ -* QK_ISR_EXIT and they cannot post or publish events. -*/ +// ISR for receiving bytes from the QSPY Back-End +// NOTE: This ISR is "QF-unaware" meaning that it does not interact with +// the QF/QV and is not disabled. Such ISRs cannot post or publish events. + +void USART0_RX_IRQHandler(void); // prototype void USART0_RX_IRQHandler(void) { - /* while RX FIFO NOT empty */ - while ((l_USART0->STATUS & USART_STATUS_RXDATAV) != 0) { + // while RX FIFO NOT empty + while ((l_USART0->STATUS & USART_STATUS_RXDATAV) != 0U) { uint32_t b = l_USART0->RXDATA; QS_RX_PUT(b); } + QV_ARM_ERRATUM_838869(); } -#else -void USART0_RX_IRQHandler(void) {} -#endif +#endif // Q_SPY +//............................................................................ +#ifdef QF_ON_CONTEXT_SW +// NOTE: the context-switch callback is called with interrupts DISABLED +void QF_onContextSw(QActive *prev, QActive *next) { + QS_BEGIN_INCRIT(CONTEXT_SW, 0U) // in critical section! + QS_OBJ(prev); + QS_OBJ(next); + QS_END_INCRIT() +} +#endif // QF_ON_CONTEXT_SW -/* BSP functions ===========================================================*/ -/* MPU setup for EFM32PG1B200F256GM48 MCU */ -static void EFM32PG182_MPU_setup(void) { - /* The following MPU configuration contains the general EFM32PG1 memory - * map described in the EFM32PG1 Data Sheet Figure 3.2. EFM32PG1 Memory Map - * - * Please note that the actual STM32 MCUs provide much less Flash and SRAM - * than the maximums configured here. This means that actual MCUs have - * unmapped memory regions (e.g., beyond the actual SRAM). Attempts to - * access these regions causes the HardFault exception, which is the - * desired behavior. - */ - static struct { - uint32_t rbar; - uint32_t rasr; - } const mpu_setup[] = { +//============================================================================ +// BSP functions... - { /* region #0: Flash: base=0x0000'0000, size=512M=2^(28+1) */ - 0x00000000U /* base address */ - | MPU_RBAR_VALID_Msk /* valid region */ - | (MPU_RBAR_REGION_Msk & 0U), /* region #0 */ - (28U << MPU_RASR_SIZE_Pos) /* 2^(18+1) region */ - | (0x6U << MPU_RASR_AP_Pos) /* PA:ro/UA:ro */ - | (1U << MPU_RASR_C_Pos) /* C=1 */ - | MPU_RASR_ENABLE_Msk /* region enable */ - }, - - { /* region #1: SRAM: base=0x2000'0000, size=512M=2^(28+1) */ - 0x20000000U /* base address */ - | MPU_RBAR_VALID_Msk /* valid region */ - | (MPU_RBAR_REGION_Msk & 1U), /* region #1 */ - (28U << MPU_RASR_SIZE_Pos) /* 2^(28+1) region */ - | (0x3U << MPU_RASR_AP_Pos) /* PA:rw/UA:rw */ - | (1U << MPU_RASR_XN_Pos) /* XN=1 */ - | (1U << MPU_RASR_S_Pos) /* S=1 */ - | (1U << MPU_RASR_C_Pos) /* C=1 */ - | MPU_RASR_ENABLE_Msk /* region enable */ - }, - - /* region #3: (not configured) */ - { MPU_RBAR_VALID_Msk | (MPU_RBAR_REGION_Msk & 2U), 0U }, - - { /* region #3: Peripherals: base=0x4000'0000, size=512M=2^(28+1) */ - 0x40000000U /* base address */ - | MPU_RBAR_VALID_Msk /* valid region */ - | (MPU_RBAR_REGION_Msk & 3U), /* region #3 */ - (28U << MPU_RASR_SIZE_Pos) /* 2^(28+1) region */ - | (0x3U << MPU_RASR_AP_Pos) /* PA:rw/UA:rw */ - | (1U << MPU_RASR_XN_Pos) /* XN=1 */ - | (1U << MPU_RASR_S_Pos) /* S=1 */ - | (1U << MPU_RASR_B_Pos) /* B=1 */ - | MPU_RASR_ENABLE_Msk /* region enable */ - }, - - { /* region #4: Priv. Periph: base=0xE000'0000, size=512M=2^(28+1) */ - 0xE0000000U /* base address */ - | MPU_RBAR_VALID_Msk /* valid region */ - | (MPU_RBAR_REGION_Msk & 4U), /* region #4 */ - (28U << MPU_RASR_SIZE_Pos) /* 2^(28+1) region */ - | (0x3U << MPU_RASR_AP_Pos) /* PA:rw/UA:rw */ - | (1U << MPU_RASR_XN_Pos) /* XN=1 */ - | (1U << MPU_RASR_S_Pos) /* S=1 */ - | (1U << MPU_RASR_B_Pos) /* B=1 */ - | MPU_RASR_ENABLE_Msk /* region enable */ - }, - - { /* region #5: Ext RAM: base=0x6000'0000, size=1G=2^(29+1) */ - 0x60000000U /* base address */ - | MPU_RBAR_VALID_Msk /* valid region */ - | (MPU_RBAR_REGION_Msk & 5U), /* region #5 */ - (29U << MPU_RASR_SIZE_Pos) /* 2^(28+1) region */ - | (0x3U << MPU_RASR_AP_Pos) /* PA:rw/UA:rw */ - | (1U << MPU_RASR_XN_Pos) /* XN=1 */ - | (1U << MPU_RASR_S_Pos) /* S=1 */ - | (1U << MPU_RASR_B_Pos) /* B=1 */ - | MPU_RASR_ENABLE_Msk /* region enable */ - }, - - { /* region #6: Ext Dev: base=0xA000'0000, size=1G=2^(29+1) */ - 0xA0000000U /* base address */ - | MPU_RBAR_VALID_Msk /* valid region */ - | (MPU_RBAR_REGION_Msk & 6U), /* region #6 */ - (29U << MPU_RASR_SIZE_Pos) /* 2^(28+1) region */ - | (0x3U << MPU_RASR_AP_Pos) /* PA:rw/UA:rw */ - | (1U << MPU_RASR_XN_Pos) /* XN=1 */ - | (1U << MPU_RASR_S_Pos) /* S=1 */ - | (1U << MPU_RASR_B_Pos) /* B=1 */ - | MPU_RASR_ENABLE_Msk /* region enable */ - }, - - { /* region #7: NULL-pointer: base=0x000'0000, size=256B, NOTE0 */ - 0x00000000U /* base address */ - | MPU_RBAR_VALID_Msk /* valid region */ - | (MPU_RBAR_REGION_Msk & 7U), /* region #7 */ - (7U << MPU_RASR_SIZE_Pos) /* 2^(7+1)=256B region */ - | (0x0U << MPU_RASR_AP_Pos) /* PA:na/UA:na */ - | (1U << MPU_RASR_XN_Pos) /* XN=1 */ - | MPU_RASR_ENABLE_Msk /* region enable */ - }, - }; - - /* enable the MemManage_Handler for MPU exception */ - SCB->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk; - - __DSB(); - MPU->CTRL = 0U; /* disable the MPU */ - for (uint_fast8_t n = 0U; n < Q_DIM(mpu_setup); ++n) { - MPU->RBAR = mpu_setup[n].rbar; - MPU->RASR = mpu_setup[n].rasr; - } - MPU->CTRL = MPU_CTRL_ENABLE_Msk; /* enable the MPU */ +void BSP_init(void) { + // Configure the MPU to prevent NULL-pointer dereferencing ... + MPU->RBAR = 0x0U // base address (NULL) + | MPU_RBAR_VALID_Msk // valid region + | (MPU_RBAR_REGION_Msk & 7U); // region #7 + MPU->RASR = (7U << MPU_RASR_SIZE_Pos) // 2^(7+1) region + | (0x0U << MPU_RASR_AP_Pos) // no-access region + | MPU_RASR_ENABLE_Msk; // region enable + MPU->CTRL = MPU_CTRL_PRIVDEFENA_Msk // enable background region + | MPU_CTRL_ENABLE_Msk; // enable the MPU __ISB(); __DSB(); -} -/*..........................................................................*/ -void BSP_init(void) { - /* setup the MPU... */ - EFM32PG182_MPU_setup(); + // enable the MemManage_Handler for MPU exception + SCB->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk; - /* NOTE: SystemInit() already called from the startup code - * but SystemCoreClock needs to be updated - */ + // NOTE: SystemInit() has been already called from the startup code + // but SystemCoreClock needs to be updated SystemCoreClockUpdate(); - /* NOTE The VFP (hardware Floating Point) unit is configured by QV-port */ + // NOTE: The VFP (hardware Floating Point) unit is configured by QK - /* enable clock for to the peripherals used by this application... */ + // enable clock for to the peripherals used by this application... CMU_ClockEnable(cmuClock_HFPER, true); CMU_ClockEnable(cmuClock_GPIO, true); CMU_ClockEnable(cmuClock_HFPER, true); CMU_ClockEnable(cmuClock_GPIO, true); - /* configure the LEDs */ + // configure the LEDs GPIO_PinModeSet(LED_PORT, LED0_PIN, gpioModePushPull, 0); GPIO_PinModeSet(LED_PORT, LED1_PIN, gpioModePushPull, 0); GPIO_PinOutClear(LED_PORT, LED0_PIN); GPIO_PinOutClear(LED_PORT, LED1_PIN); - /* configure the Buttons */ + // configure the Buttons GPIO_PinModeSet(PB_PORT, PB0_PIN, gpioModeInputPull, 1); GPIO_PinModeSet(PB_PORT, PB1_PIN, gpioModeInputPull, 1); - /*... */ - BSP_randomSeed(1234U); + BSP_randomSeed(1234U); // seed the random number generator - if (QS_INIT((void *)0) == 0) { /* initialize the QS software tracing */ + // initialize the QS software tracing... + if (!QS_INIT((void *)0)) { Q_ERROR(); } - /* global signals */ - QS_SIG_DICTIONARY(DONE_SIG, (void *)0); - QS_SIG_DICTIONARY(EAT_SIG, (void *)0); - QS_SIG_DICTIONARY(PAUSE_SIG, (void *)0); - QS_SIG_DICTIONARY(SERVE_SIG, (void *)0); - QS_SIG_DICTIONARY(TEST_SIG, (void *)0); - QS_SIG_DICTIONARY(HUNGRY_SIG, (void *)0); - QS_SIG_DICTIONARY(HUNGRY_SIG, (void *)0); - QS_SIG_DICTIONARY(TIMEOUT_SIG, (void *)0); + // dictionaries... QS_OBJ_DICTIONARY(&l_SysTick_Handler); QS_OBJ_DICTIONARY(&l_GPIO_EVEN_IRQHandler); - QS_USR_DICTIONARY(PHILO_STAT); - QS_USR_DICTIONARY(COMMAND_STAT); + QS_USR_DICTIONARY(PAUSED_STAT); + QS_USR_DICTIONARY(CONTEXT_SW); - /* setup the QS filters... */ - QS_GLB_FILTER(QS_SM_RECORDS); - //QS_GLB_FILTER(QS_AO_RECORDS); - QS_GLB_FILTER(QS_UA_RECORDS); + QS_ONLY(produce_sig_dict()); + + // setup the QS filters... + QS_GLB_FILTER(QS_ALL_RECORDS); // all records + QS_GLB_FILTER(-QS_QF_TICK); // exclude the clock tick } -/*..........................................................................*/ +//............................................................................ +void BSP_start(void) { + // initialize event pools + static QF_MPOOL_EL(TableEvt) smlPoolSto[2*N_PHILO]; + QF_poolInit(smlPoolSto, sizeof(smlPoolSto), sizeof(smlPoolSto[0])); + + // initialize publish-subscribe + static QSubscrList subscrSto[MAX_PUB_SIG]; + QActive_psInit(subscrSto, Q_DIM(subscrSto)); + + // instantiate and start AOs/threads... + + static QEvt const *philoQueueSto[N_PHILO][10]; + for (uint8_t n = 0U; n < N_PHILO; ++n) { + Philo_ctor(n); + QACTIVE_START(AO_Philo[n], + n + 3U, // QF-prio. + philoQueueSto[n], // event queue storage + Q_DIM(philoQueueSto[n]), // queue length [events] + (void *)0, 0U, // no stack storage + (void *)0); // no initialization param + } + + static QEvt const *tableQueueSto[N_PHILO]; + Table_ctor(); + QACTIVE_START(AO_Table, + N_PHILO + 7U, // QP prio. of the AO + tableQueueSto, // event queue storage + Q_DIM(tableQueueSto), // queue length [events] + (void *)0, 0U, // no stack storage + (void *)0); // no initialization param +} +//............................................................................ void BSP_displayPhilStat(uint8_t n, char const *stat) { + Q_UNUSED_PAR(n); + if (stat[0] == 'e') { GPIO->P[LED_PORT].DOUT |= (1U << LED0_PIN); } else { - GPIO->P[LED_PORT].DOUT &= ~(1U << LED0_PIN); + GPIO->P[LED_PORT].DOUT &= ~(1U << LED0_PIN); } - QS_BEGIN_ID(PHILO_STAT, AO_Philo[n]->prio) /* app-specific record */ - QS_U8(1, n); /* Philosopher number */ - QS_STR(stat); /* Philosopher status */ - QS_END() /* application-specific record end */ + // app-specific trace record... + QS_BEGIN_ID(PHILO_STAT, AO_Table->prio) + QS_U8(1, n); // Philosopher number + QS_STR(stat); // Philosopher status + QS_END() } -/*..........................................................................*/ -void BSP_displayPaused(uint8_t paused) { +//............................................................................ +void BSP_displayPaused(uint8_t const paused) { if (paused != 0U) { GPIO->P[LED_PORT].DOUT |= (1U << LED0_PIN); } else { GPIO->P[LED_PORT].DOUT &= ~(1U << LED0_PIN); } -} -/*..........................................................................*/ -uint32_t BSP_random(void) { /* a very cheap pseudo-random-number generator */ - uint32_t rnd; - /* Some flating point code is to exercise the VFP... */ + // application-specific trace record + QS_BEGIN_ID(PAUSED_STAT, AO_Table->prio) + QS_U8(1, paused); // Paused status + QS_END() +} +//............................................................................ +void BSP_randomSeed(uint32_t seed) { + l_rndSeed = seed; +} +//............................................................................ +uint32_t BSP_random(void) { // a very cheap pseudo-random-number generator + // Some floating point code is to exercise the VFP... float volatile x = 3.1415926F; x = x + 2.7182818F; - /* "Super-Duper" Linear Congruential Generator (LCG) - * LCG(2^32, 3*7*11*13*23, 0, seed) - */ - rnd = l_rnd * (3U*7U*11U*13U*23U); - l_rnd = rnd; /* set for the next time */ + // "Super-Duper" Linear Congruential Generator (LCG) + // LCG(2^32, 3*7*11*13*23, 0, seed) + // + uint32_t rnd = l_rndSeed * (3U*7U*11U*13U*23U); + l_rndSeed = rnd; // set for the next time - return (rnd >> 8); + return (rnd >> 8U); } -/*..........................................................................*/ -void BSP_randomSeed(uint32_t seed) { - l_rnd = seed; +//............................................................................ +void BSP_ledOn(void) { + GPIO->P[LED_PORT].DOUT |= (1U << LED1_PIN); } -/*..........................................................................*/ +//............................................................................ +void BSP_ledOff(void) { + GPIO->P[LED_PORT].DOUT &= ~(1U << LED1_PIN); +} +//............................................................................ void BSP_terminate(int16_t result) { - (void)result; + Q_UNUSED_PAR(result); } -/* QF callbacks ============================================================*/ +//============================================================================ +// QF callbacks... void QF_onStartup(void) { - /* set up the SysTick timer to fire at BSP_TICKS_PER_SEC rate */ + // set up the SysTick timer to fire at BSP_TICKS_PER_SEC rate SysTick_Config(SystemCoreClock / BSP_TICKS_PER_SEC); - /* assing all priority bits for preemption-prio. and none to sub-prio. */ + // assign all priority bits for preemption-prio. and none to sub-prio. NVIC_SetPriorityGrouping(0U); - /* set priorities of ALL ISRs used in the system, see NOTE1 - * - * !!!!!!!!!!!!!!!!!!!!!!!!!!!! CAUTION !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - * Assign a priority to EVERY ISR explicitly by calling NVIC_SetPriority(). - * DO NOT LEAVE THE ISR PRIORITIES AT THE DEFAULT VALUE! - */ - NVIC_SetPriority(USART0_RX_IRQn, 0U); /* kernel unaware interrupt */ - NVIC_SetPriority(GPIO_EVEN_IRQn, QF_AWARE_ISR_CMSIS_PRI); + // set priorities of ALL ISRs used in the system, see NOTE1 + NVIC_SetPriority(USART0_RX_IRQn, 0U); // kernel unaware interrupt + NVIC_SetPriority(GPIO_EVEN_IRQn, QF_AWARE_ISR_CMSIS_PRI + 0U); NVIC_SetPriority(SysTick_IRQn, QF_AWARE_ISR_CMSIS_PRI + 1U); - /* ... */ + // ... - /* enable IRQs... */ + // enable IRQs... NVIC_EnableIRQ(GPIO_EVEN_IRQn); + #ifdef Q_SPY - NVIC_EnableIRQ(USART0_RX_IRQn); /* UART0 interrupt used for QS-RX */ + NVIC_EnableIRQ(USART0_RX_IRQn); // UART0 interrupt used for QS-RX #endif } -/*..........................................................................*/ +//............................................................................ void QF_onCleanup(void) { } -/*..........................................................................*/ -void QV_onIdle(void) { /* CATION: called with interrupts DISABLED, NOTE2 */ - /* toggle the User LED on and then off, see NOTE3 */ - GPIO->P[LED_PORT].DOUT |= (1U << LED1_PIN); - GPIO->P[LED_PORT].DOUT &= ~(1U << LED1_PIN); +//............................................................................ +void QV_onIdle(void) { // CATION: called with interrupts DISABLED, see NOTE0 + + // toggle the User LED on and then off, see NOTE3 +// GPIO->P[LED_PORT].DOUT |= (1U << LED1_PIN); +// GPIO->P[LED_PORT].DOUT &= ~(1U << LED1_PIN); #ifdef Q_SPY + // interrupts still disabled + QS_rxParse(); // parse all the received bytes QF_INT_ENABLE(); - QS_rxParse(); /* parse all the received bytes */ - - if ((l_USART0->STATUS & USART_STATUS_TXBL) != 0) { /* is TXE empty? */ - uint16_t b; + if ((l_USART0->STATUS & USART_STATUS_TXBL) != 0) { // is TXE empty? QF_INT_DISABLE(); - b = QS_getByte(); + uint16_t b = QS_getByte(); QF_INT_ENABLE(); - if (b != QS_EOD) { /* not End-Of-Data? */ - l_USART0->TXDATA = (b & 0xFFU); /* put into the DR register */ + if (b != QS_EOD) { // not End-Of-Data? + l_USART0->TXDATA = (b & 0xFFU); // put into the DR register } } #elif defined NDEBUG - /* Put the CPU and peripherals to the low-power mode. - * you might need to customize the clock management for your application, - * see the datasheet for your particular Cortex-M MCU. - */ - QV_CPU_SLEEP(); /* atomically go to sleep and enable interrupts */ + // Put the CPU and peripherals to the low-power mode. + // you might need to customize the clock management for your application, + // see the datasheet for your particular Cortex-M MCU. + // + QV_CPU_SLEEP(); // atomically go to sleep and enable interrupts #else - QF_INT_ENABLE(); /* just enable interrupts */ + QF_INT_ENABLE(); // just enable interrupts #endif } -/*..........................................................................*/ -Q_NORETURN Q_onAssert(char const * const module, int_t const loc) { - /* - * NOTE: add here your application-specific error handling - */ - (void)module; - (void)loc; - QS_ASSERTION(module, loc, 10000U); /* report assertion to QS */ - -#ifndef NDEBUG - /* light up both LEDs */ - GPIO->P[LED_PORT].DOUT |= ((1U << LED0_PIN) | (1U << LED1_PIN)); - /* for debugging, hang on in an endless loop until PB1 is pressed... */ - while ((GPIO->P[PB_PORT].DIN & (1U << PB1_PIN)) != 0) { - } -#endif - - NVIC_SystemReset(); -} - -/* QS callbacks ============================================================*/ +//============================================================================ +// QS callbacks... #ifdef Q_SPY -/*..........................................................................*/ -uint8_t QS_onStartup(void const *arg) { - static uint8_t qsTxBuf[2*1024]; /* buffer for QS transmit channel */ - static uint8_t qsRxBuf[100]; /* buffer for QS receive channel */ - static USART_InitAsync_TypeDef init = { - usartEnable, /* Enable RX/TX when init completed */ - 0, /* Use current clock for configuring baudrate */ - 115200, /* 115200 bits/s */ - usartOVS16, /* 16x oversampling */ - usartDatabits8, /* 8 databits */ - usartNoParity, /* No parity */ - usartStopbits1, /* 1 stopbit */ - 0, /* Do not disable majority vote */ - 0, /* Not USART PRS input mode */ - usartPrsRxCh0, /* PRS channel 0 */ - 0, /* Auto CS functionality enable/disable switch */ - 0, /* Auto CS Hold cycles */ - 0 /* Auto CS Setup cycles */ - }; - QS_initBuf (qsTxBuf, sizeof(qsTxBuf)); +//............................................................................ +uint8_t QS_onStartup(void const *arg) { + Q_UNUSED_PAR(arg); + + static uint8_t qsTxBuf[2*1024]; // buffer for QS-TX channel + QS_initBuf(qsTxBuf, sizeof(qsTxBuf)); + + static uint8_t qsRxBuf[100]; // buffer for QS-RX channel QS_rxInitBuf(qsRxBuf, sizeof(qsRxBuf)); - /* Enable peripheral clocks */ + static USART_InitAsync_TypeDef init = { + usartEnable, // Enable RX/TX when init completed + 0, // Use current clock for configuring baudrate + 115200, // 115200 bits/s + usartOVS16, // 16x oversampling + usartDatabits8, // 8 databits + usartNoParity, // No parity + usartStopbits1, // 1 stopbit + 0, // Do not disable majority vote + 0, // Not USART PRS input mode + usartPrsRxCh0, // PRS channel 0 + 0, // Auto CS functionality enable/disable switch + 0, // Auto CS Hold cycles + 0 // Auto CS Setup cycles + }; + + // Enable peripheral clocks CMU_ClockEnable(cmuClock_HFPER, true); CMU_ClockEnable(cmuClock_GPIO, true); - /* To avoid false start, configure output as high */ + // To avoid false start, configure output as high GPIO_PinModeSet(gpioPortA, 0, gpioModePushPull, 1); // TX pin GPIO_PinModeSet(gpioPortA, 1, gpioModeInput, 0); // RX pin - /* Enable DK RS232/UART switch */ + // Enable DK RS232/UART switch GPIO_PinModeSet(gpioPortA, 5, gpioModePushPull, 1); CMU_ClockEnable(cmuClock_USART0, true); - /* configure the UART for the desired baud rate, 8-N-1 operation */ + // configure the UART for the desired baud rate, 8-N-1 operation init.enable = usartDisable; USART_InitAsync(l_USART0, &init); - /* enable pins at correct UART/USART location. */ + // enable pins at correct UART/USART location. l_USART0->ROUTEPEN = USART_ROUTEPEN_RXPEN | USART_ROUTEPEN_TXPEN; l_USART0->ROUTELOC0 = (l_USART0->ROUTELOC0 & ~(_USART_ROUTELOC0_TXLOC_MASK | _USART_ROUTELOC0_RXLOC_MASK)); - /* Clear previous RX interrupts */ + // Clear previous RX interrupts USART_IntClear(l_USART0, USART_IF_RXDATAV); NVIC_ClearPendingIRQ(USART0_RX_IRQn); - /* Enable RX interrupts */ + // Enable RX interrupts USART_IntEnable(l_USART0, USART_IF_RXDATAV); - /* NOTE: do not enable the UART0 interrupt in the NVIC yet. - * Wait till QF_onStartup() - */ + // NOTE: do not enable the UART0 interrupt in the NVIC yet. + // Wait till QF_onStartup() + // - /* Finally enable the UART */ + // Finally enable the UART USART_Enable(l_USART0, usartEnable); QS_tickPeriod_ = SystemCoreClock / BSP_TICKS_PER_SEC; - QS_tickTime_ = QS_tickPeriod_; /* to start the timestamp at zero */ + QS_tickTime_ = QS_tickPeriod_; // to start the timestamp at zero - return 1U; /* return success */ + return 1U; // return success } -/*..........................................................................*/ +//............................................................................ void QS_onCleanup(void) { } -/*..........................................................................*/ -QSTimeCtr QS_onGetTime(void) { /* NOTE: invoked with interrupts DISABLED */ - if ((SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk) == 0) { /* not set? */ +//............................................................................ +QSTimeCtr QS_onGetTime(void) { // NOTE: invoked with interrupts DISABLED + if ((SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk) == 0U) { // not set? return QS_tickTime_ - (QSTimeCtr)SysTick->VAL; } - else { /* the rollover occured, but the SysTick_ISR did not run yet */ + else { // the rollover occured, but the SysTick_ISR did not run yet return QS_tickTime_ + QS_tickPeriod_ - (QSTimeCtr)SysTick->VAL; } } -/*..........................................................................*/ +//............................................................................ void QS_onFlush(void) { - uint16_t b; - - QF_INT_DISABLE(); - while ((b = QS_getByte()) != QS_EOD) { /* while not End-Of-Data... */ - QF_INT_ENABLE(); - /* while TXE not empty */ - while ((l_USART0->STATUS & USART_STATUS_TXBL) == 0U) { - } - l_USART0->TXDATA = (b & 0xFFU); /* put into the DR register */ + for (;;) { QF_INT_DISABLE(); + uint16_t b = QS_getByte(); + if (b != QS_EOD) { + while ((l_USART0->STATUS & USART_STATUS_TXBL) == 0U) { + QF_INT_ENABLE(); + QF_CRIT_EXIT_NOP(); + + QF_INT_DISABLE(); + } + l_USART0->TXDATA = b; + QF_INT_ENABLE(); + } + else { + QF_INT_ENABLE(); + break; + } } - QF_INT_ENABLE(); } -/*..........................................................................*/ -/*! callback function to reset the target (to be implemented in the BSP) */ +//............................................................................ +//! callback function to reset the target (to be implemented in the BSP) void QS_onReset(void) { NVIC_SystemReset(); } -/*..........................................................................*/ -/*! callback function to execute a user command (to be implemented in BSP) */ +//............................................................................ +// callback function to execute a user command void QS_onCommand(uint8_t cmdId, uint32_t param1, uint32_t param2, uint32_t param3) { - void assert_failed(char const *module, int loc); - (void)cmdId; - (void)param1; - (void)param2; - (void)param3; - QS_BEGIN_ID(COMMAND_STAT, 0U) /* app-specific record */ - QS_U8(2, cmdId); - QS_U32(8, param1); - QS_U32(8, param2); - QS_U32(8, param3); - QS_END() - - if (cmdId == 10U) { - Q_ERROR(); - } - else if (cmdId == 11U) { - assert_failed("QS_onCommand", 123); - } + Q_UNUSED_PAR(cmdId); + Q_UNUSED_PAR(param1); + Q_UNUSED_PAR(param2); + Q_UNUSED_PAR(param3); } -#endif /* Q_SPY */ -/*--------------------------------------------------------------------------*/ +#endif // Q_SPY +//---------------------------------------------------------------------------- -/*============================================================================ -* NOTE0: -* The MPU protection against NULL-pointer dereferencing sets up a no-access -* MPU region #7 around the NULL address (0x0). This works even though the -* Vector Table also resides at address 0x0. However, the *size* of the -* no-access region should not exceed the size of the Vector Table. In this -* case, the size is set to 2**(7+1)==256 bytes, which does not contain any -* data that the CPU would legitimately read with the LDR instruction. -* -* NOTE1: -* The QF_AWARE_ISR_CMSIS_PRI constant from the QF port specifies the highest -* ISR priority that is disabled by the QF framework. The value is suitable -* for the NVIC_SetPriority() CMSIS function. -* -* Only ISRs prioritized at or below the QF_AWARE_ISR_CMSIS_PRI level (i.e., -* with the numerical values of priorities equal or higher than -* QF_AWARE_ISR_CMSIS_PRI) are allowed to call the QK_ISR_ENTRY/QK_ISR_ENTRY -* macros or any other QF/QK services. These ISRs are "QF-aware". -* -* Conversely, any ISRs prioritized above the QF_AWARE_ISR_CMSIS_PRI priority -* level (i.e., with the numerical values of priorities less than -* QF_AWARE_ISR_CMSIS_PRI) are never disabled and are not aware of the kernel. -* Such "QF-unaware" ISRs cannot call any QF/QK services. In particular they -* can NOT call the macros QK_ISR_ENTRY/QK_ISR_ENTRY. The only mechanism -* by which a "QF-unaware" ISR can communicate with the QF framework is by -* triggering a "QF-aware" ISR, which can post/publish events. -* -* NOTE2: -* The QV_onIdle() callback is called with interrupts disabled, because the -* determination of the idle condition might change by any interrupt posting -* an event. QV_onIdle() must internally enable interrupts, ideally -* atomically with putting the CPU to the power-saving mode. -* -* NOTE3: -* The User LED is used to visualize the idle loop activity. The brightness -* of the LED is proportional to the frequency of invcations of the idle loop. -* Please note that the LED is toggled with interrupts locked, so no interrupt -* execution time contributes to the brightness of the User LED. -* -* NOTE4: -* GPIO_EVEN_IRQHandler() is for testing various preemption scenarios in QV. -* The general testing strategy is to trigger this IRQ manually from the -* debugger. To do so in IAR, you need to: -* 1. open the Register view -* 2. open NVIC registers -* 3. scroll down to NVIC_ISPR0 register -* 4. write 0x200 to NVIC_ISPR0.SETPEND register -*/ +//============================================================================ +// NOTE0: +// The QV_onIdle() callback is called with interrupts disabled, because the +// determination of the idle condition might change by any interrupt posting +// an event. QV_onIdle() must internally enable interrupts, ideally +// atomically with putting the CPU to the power-saving mode. +// +// NOTE1: +// The QF_AWARE_ISR_CMSIS_PRI constant from the QF port specifies the highest +// ISR priority that is disabled by the QF framework. The value is suitable +// for the NVIC_SetPriority() CMSIS function. +// +// Only ISRs prioritized at or below the QF_AWARE_ISR_CMSIS_PRI level (i.e., +// with the numerical values of priorities equal or higher than +// QF_AWARE_ISR_CMSIS_PRI) are allowed to call the QV_ISR_ENTRY/ +// QV_ISR_ENTRY macros or any other QF/QV services. These ISRs are +// "QF-aware". +// +// Conversely, any ISRs prioritized above the QF_AWARE_ISR_CMSIS_PRI priority +// level (i.e., with the numerical values of priorities less than +// QF_AWARE_ISR_CMSIS_PRI) are never disabled and are not aware of the kernel. +// Such "QF-unaware" ISRs cannot call ANY QF/QV services. In particular they +// can NOT call the macros QV_ISR_ENTRY/QV_ISR_ENTRY. The only mechanism +// by which a "QF-unaware" ISR can communicate with the QF framework is by +// triggering a "QF-aware" ISR, which can post/publish events. +// +// NOTE2: +// The User LED is used to visualize the idle loop activity. The brightness +// of the LED is proportional to the frequency of the idle loop. +// Please note that the LED is toggled with interrupts locked, so no interrupt +// execution time contributes to the brightness of the User LED. +// diff --git a/examples/arm-cm/dpp_efm32-slstk3401a/qv/gnu/Makefile b/examples/arm-cm/dpp_efm32-slstk3401a/qv/gnu/Makefile index 33ee9d08..cfd5fe9e 100644 --- a/examples/arm-cm/dpp_efm32-slstk3401a/qv/gnu/Makefile +++ b/examples/arm-cm/dpp_efm32-slstk3401a/qv/gnu/Makefile @@ -1,7 +1,7 @@ ############################################################################## # Product: Makefile for QP/C on EMF32-SLSTK3401A, QV kernel, GNU-ARM -# Last Updated for Version: 7.0.1 -# Date of the Last Update: 2022-05-23 +# Last Updated for Version: 7.3.0 +# Date of the Last Update: 2023-09-02 # # Q u a n t u m L e a P s # ------------------------ @@ -78,6 +78,7 @@ VPATH = \ # list of all include directories needed by this project INCLUDES = \ + -I.. \ -I../.. \ -I$(QPC)/include \ -I$(QP_PORT_DIR) \ @@ -137,7 +138,8 @@ LIB_DIRS := LIBS := # defines -DEFINES := -DEFM32PG1B200F256GM48=1 +DEFINES := -DEFM32PG1B200F256GM48=1 \ + -DQP_CONFIG # ARM CPU, ARCH, FPU, and Float-ABI types... # ARM_CPU: [cortex-m0 | cortex-m0plus | cortex-m1 | cortex-m3 | cortex-m4] @@ -191,7 +193,8 @@ BIN_DIR := rel ASFLAGS = $(ARM_CPU) $(ARM_FPU) $(ASM_CPU) $(ASM_FPU) -CFLAGS = -c $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \ +CFLAGS = -c $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb \ + -std=c11 -pedantic -Wall -Wextra -W \ -ffunction-sections -fdata-sections \ -O1 $(INCLUDES) $(DEFINES) -DNDEBUG @@ -207,7 +210,8 @@ C_SRCS += $(QS_SRCS) ASFLAGS = -g $(ARM_CPU) $(ARM_FPU) $(ASM_CPU) $(ASM_FPU) -CFLAGS = -c -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \ +CFLAGS = -c -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb \ + -std=c11 -pedantic -Wall -Wextra -W \ -ffunction-sections -fdata-sections \ -O $(INCLUDES) $(DEFINES) -DQ_SPY @@ -221,7 +225,8 @@ BIN_DIR := dbg ASFLAGS = -g $(ARM_CPU) $(ARM_FPU) $(ASM_CPU) $(ASM_FPU) -CFLAGS = -c -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \ +CFLAGS = -c -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb \ + -std=c11 -pedantic -Wall -Wextra -W \ -ffunction-sections -fdata-sections \ -O $(INCLUDES) $(DEFINES) @@ -265,7 +270,7 @@ $(TARGET_BIN): $(TARGET_ELF) $(BIN) -O binary $< $@ $(TARGET_ELF) : $(ASM_OBJS_EXT) $(C_OBJS_EXT) $(CPP_OBJS_EXT) - $(CC) $(CFLAGS) $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o + $(CC) $(CFLAGS) $(QPC)/src/qs/qstamp.c -o $(BIN_DIR)/qstamp.o $(LINK) $(LINKFLAGS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) $(BIN_DIR)/%.d : %.c diff --git a/examples/arm-cm/dpp_efm32-slstk3401a/qv/iar/dpp-qv.ewd b/examples/arm-cm/dpp_efm32-slstk3401a/qv/iar/dpp-qv.ewd index 42451eb1..cb16c888 100644 --- a/examples/arm-cm/dpp_efm32-slstk3401a/qv/iar/dpp-qv.ewd +++ b/examples/arm-cm/dpp_efm32-slstk3401a/qv/iar/dpp-qv.ewd @@ -11,7 +11,7 @@ C-SPY 2 - 28 + 32 1 1 - - + + + + +
@@ -486,7 +498,7 @@ IJET_ID 2 - 8 + 9 1 1 + + + + + + + + + + + + + @@ -916,7 +980,7 @@ LMIFTDI_ID 2 - 2 + 3 1 1 + + + + + + + NULINK_ID + 2 + + 0 + 1 + 1 + + + @@ -974,7 +1072,7 @@ STLINK_ID 2 - 4 + 8 1 1 + + + + @@ -1185,7 +1300,7 @@ XDS100_ID 2 - 6 + 9 1 1 + + + + @@ -1362,6 +1493,18 @@ $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin 0
+ + $TOOLKIT_DIR$\plugins\rtos\FreeRtos\FreeRtosArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin2.ENU.ewplugin + 0 + $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin 0 @@ -1371,11 +1514,15 @@ 0 - $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9.ewplugin 0 - $TOOLKIT_DIR$\plugins\rtos\TI-RTOS\tirtosplugin.ewplugin + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9BE.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin 0 @@ -1391,11 +1538,11 @@ 0 - $EW_DIR$\common\plugins\CodeCoverage\CodeCoverage.ENU.ewplugin - 1 + $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + 0 - $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + $EW_DIR$\common\plugins\TargetAccessServer\TargetAccessServer.ENU.ewplugin 0 @@ -1414,7 +1561,7 @@ C-SPY 2 - 28 + 32 1 0 - - + + + + + @@ -1889,7 +2048,7 @@ IJET_ID 2 - 8 + 9 1 0 + + + + + + + + + + + + + @@ -2319,7 +2530,7 @@ LMIFTDI_ID 2 - 2 + 3 1 0 + + + + + + + NULINK_ID + 2 + + 0 + 1 + 0 + + + @@ -2377,7 +2622,7 @@ STLINK_ID 2 - 4 + 8 1 0 + + + + @@ -2588,7 +2850,7 @@ XDS100_ID 2 - 6 + 9 1 0 + + + + @@ -2765,6 +3043,18 @@ $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin 0 + + $TOOLKIT_DIR$\plugins\rtos\FreeRtos\FreeRtosArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin2.ENU.ewplugin + 0 + $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin 0 @@ -2774,11 +3064,15 @@ 0 - $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9.ewplugin 0 - $TOOLKIT_DIR$\plugins\rtos\TI-RTOS\tirtosplugin.ewplugin + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9BE.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin 0 @@ -2794,11 +3088,11 @@ 0 - $EW_DIR$\common\plugins\CodeCoverage\CodeCoverage.ENU.ewplugin - 1 + $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + 0 - $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + $EW_DIR$\common\plugins\TargetAccessServer\TargetAccessServer.ENU.ewplugin 0 @@ -2817,7 +3111,7 @@ C-SPY 2 - 28 + 32 1 1 - - + + + + + @@ -3292,7 +3598,7 @@ IJET_ID 2 - 8 + 9 1 1 + + + + + + + + + + + + + @@ -3722,7 +4080,7 @@ LMIFTDI_ID 2 - 2 + 3 1 1 + + + + + + + NULINK_ID + 2 + + 0 + 1 + 1 + + + @@ -3780,7 +4172,7 @@ STLINK_ID 2 - 4 + 8 1 1 + + + + @@ -3991,7 +4400,7 @@ XDS100_ID 2 - 6 + 9 1 1 + + + + @@ -4168,6 +4593,18 @@ $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin 0 + + $TOOLKIT_DIR$\plugins\rtos\FreeRtos\FreeRtosArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin2.ENU.ewplugin + 0 + $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin 0 @@ -4177,11 +4614,15 @@ 0 - $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9.ewplugin 0 - $TOOLKIT_DIR$\plugins\rtos\TI-RTOS\tirtosplugin.ewplugin + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9BE.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin 0 @@ -4197,11 +4638,11 @@ 0 - $EW_DIR$\common\plugins\CodeCoverage\CodeCoverage.ENU.ewplugin - 1 + $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + 0 - $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + $EW_DIR$\common\plugins\TargetAccessServer\TargetAccessServer.ENU.ewplugin 0 diff --git a/examples/arm-cm/dpp_efm32-slstk3401a/qv/iar/dpp-qv.ewp b/examples/arm-cm/dpp_efm32-slstk3401a/qv/iar/dpp-qv.ewp index 2e7dfdcf..c62e9325 100644 --- a/examples/arm-cm/dpp_efm32-slstk3401a/qv/iar/dpp-qv.ewp +++ b/examples/arm-cm/dpp_efm32-slstk3401a/qv/iar/dpp-qv.ewp @@ -11,9 +11,13 @@ General 3 - 28 + 35 1 1 + - - - - - + + + + + + + + ICCARM 2 - 34 + 37 1 1 - - - + + AARM 2 - 10 + 11 1 1 + @@ -656,13 +669,9 @@ 0 + inputOutputBased - - BICOMP - 0 - - BUILDACTION 1 @@ -675,17 +684,13 @@ ILINK 0 - 20 + 27 1 1 - + + + + + + + + + + + + + + + @@ -1010,11 +1075,6 @@ - - BILINK - 0 - - Coder 0 @@ -1031,9 +1091,13 @@ General 3 - 28 + 35 1 0 + - - - - - + + + + + + + + ICCARM 2 - 34 + 37 1 0 - - - + + AARM 2 - 10 + 11 1 0 + @@ -1677,13 +1750,9 @@ 0 + inputOutputBased - - BICOMP - 0 - - BUILDACTION 1 @@ -1696,17 +1765,13 @@ ILINK 0 - 20 + 27 1 0 - + + + + + + + + + + + + + + + @@ -2031,11 +2156,6 @@ - - BILINK - 0 - - Coder 0 @@ -2052,9 +2172,13 @@ General 3 - 28 + 35 1 1 + - - - - - + + + + + + + + ICCARM 2 - 34 + 37 1 1 - - - + + AARM 2 - 10 + 11 1 1 + @@ -2698,13 +2832,9 @@ 0 + inputOutputBased - - BICOMP - 0 - - BUILDACTION 1 @@ -2717,17 +2847,13 @@ ILINK 0 - 20 + 27 1 1 - + + + + + + + + + + + + + + + @@ -3052,11 +3238,6 @@ - - BILINK - 0 - - Coder 0 @@ -3075,14 +3256,11 @@ $PROJ_DIR$\..\..\dpp.h - $PROJ_DIR$\..\main.c + $PROJ_DIR$\..\..\main.c $PROJ_DIR$\..\..\philo.c - - $PROJ_DIR$\..\..\..\..\..\include\qstamp.c - $PROJ_DIR$\..\..\table.c @@ -3171,9 +3349,6 @@ $PROJ_DIR$\..\..\..\..\..\src\qs\qs.c - - $PROJ_DIR$\..\..\..\..\..\src\qs\qs_64bit.c - $PROJ_DIR$\..\..\..\..\..\src\qs\qs_fp.c @@ -3181,7 +3356,7 @@ $PROJ_DIR$\..\..\..\..\..\src\qs\qs_rx.c - $PROJ_DIR$\..\..\..\..\..\src\qs\qutest.c + $PROJ_DIR$\..\..\..\..\..\src\qs\qstamp.c diff --git a/examples/arm-cm/dpp_efm32-slstk3401a/qv/main.c b/examples/arm-cm/dpp_efm32-slstk3401a/qv/main.c deleted file mode 100644 index ec9a6fcf..00000000 --- a/examples/arm-cm/dpp_efm32-slstk3401a/qv/main.c +++ /dev/null @@ -1,93 +0,0 @@ -/***************************************************************************** -* Product: DPP example -* Last updated for version 7.1.2 -* Last updated on 2022-09-22 -* -* Q u a n t u m L e a P s -* ------------------------ -* Modern Embedded Software -* -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* -* -*****************************************************************************/ -#include "qpc.h" -#include "dpp.h" -#include "bsp.h" - -Q_DEFINE_THIS_FILE - -static QTicker l_ticker0; -QActive *the_Ticker0 = &l_ticker0.super; - -/*..........................................................................*/ -int main() { - static QEvt const *tableQueueSto[N_PHILO]; - static QEvt const *philoQueueSto[N_PHILO][N_PHILO]; - static QSubscrList subscrSto[MAX_PUB_SIG]; - static QF_MPOOL_EL(TableEvt) smlPoolSto[2*N_PHILO]; /* small pool */ - - QF_init(); /* initialize the framework and the underlying RT kernel */ - BSP_init(); /* initialize the Board Support Package */ - - /* object dictionaries... */ - QS_OBJ_DICTIONARY(AO_Table); - QS_OBJ_DICTIONARY(AO_Philo[0]); - QS_OBJ_DICTIONARY(AO_Philo[1]); - QS_OBJ_DICTIONARY(AO_Philo[2]); - QS_OBJ_DICTIONARY(AO_Philo[3]); - QS_OBJ_DICTIONARY(AO_Philo[4]); - - /* initialize publish-subscribe... */ - QF_psInit(subscrSto, Q_DIM(subscrSto)); - - /* initialize event pools... */ - QF_poolInit(smlPoolSto, sizeof(smlPoolSto), sizeof(smlPoolSto[0])); - - QTicker_ctor(&l_ticker0, 0U); /* ticker AO for tick rate 0 */ - QACTIVE_START(the_Ticker0, 1U, 0, 0, 0, 0, 0); - - /* start the active objects... */ - for (uint8_t n = 0U; n < N_PHILO; ++n) { - Philo_ctor(n); /* instantiate Philo[n] AO */ - QACTIVE_START(AO_Philo[n], /* AO to start */ - n + 2U, /* QF-priority */ - philoQueueSto[n], /* event queue storage */ - Q_DIM(philoQueueSto[n]), /* queue length [events] */ - (void *)0, /* stack storage (not used) */ - 0U, /* size of the stack [bytes] */ - (void *)0); /* initialization param */ - } - - Table_ctor(); /* instantiate the Table active object */ - QACTIVE_START(AO_Table, /* AO to start */ - N_PHILO + 2U, /* QF-priority */ - tableQueueSto, /* event queue storage */ - Q_DIM(tableQueueSto), /* queue length [events] */ - (void *)0, /* stack storage (not used) */ - 0U, /* size of the stack [bytes] */ - (void *)0); /* initialization param */ - - return QF_run(); /* run the QF application */ -} - diff --git a/examples/arm-cm/dpp_efm32-slstk3401a/qxk/armclang/dpp-qxk.sct b/examples/arm-cm/dpp_efm32-slstk3401a/qxk/armclang/dpp-qxk.sct new file mode 100644 index 00000000..794d15cc --- /dev/null +++ b/examples/arm-cm/dpp_efm32-slstk3401a/qxk/armclang/dpp-qxk.sct @@ -0,0 +1,23 @@ +; ************************************************************* +; *** Scatter-Loading Description File generated by uVision *** +; +; Modified by Quantum Leaps: +; added STACK as the first section in RW_STACK +; ************************************************************* + +LR_IROM1 0x00000000 0x00020000 { ; load region size_region + ER_IROM1 0x00000000 0x00020000 { ; load address = execution address + *.o (RESET, +First) + *(InRoot$$Sections) + .ANY (+RO) + .ANY (+XO) + } + + RW_STACK 0x20000000 { ; <== Quantum Leaps + * (STACK, +First) + } + RW_IRAM1 +0 (0x00008000 - 2048) { ; NOTE: assume STACK size 2048! + .ANY (+RW +ZI) + } +} + diff --git a/examples/arm-cm/dpp_efm32-slstk3401a/qxk/armclang/dpp-qxk.uvoptx b/examples/arm-cm/dpp_efm32-slstk3401a/qxk/armclang/dpp-qxk.uvoptx index cd6e2275..32ffb559 100644 --- a/examples/arm-cm/dpp_efm32-slstk3401a/qxk/armclang/dpp-qxk.uvoptx +++ b/examples/arm-cm/dpp_efm32-slstk3401a/qxk/armclang/dpp-qxk.uvoptx @@ -153,40 +153,7 @@ -U0E2006F4 -O4622 -S4 -FO61
- - - 0 - 0 - 363 - 1 -
10268
- 0 - 0 - 0 - 0 - 0 - 1 - ..\bsp.c - - \\dpp_qxk\../bsp.c\363 -
- - 1 - 0 - 361 - 1 -
6678
- 0 - 0 - 0 - 0 - 0 - 1 - ..\..\..\..\..\src\qxk\qxk.c - - \\dpp_qxk\../../../../../src/qxk/qxk.c\361 -
-
+ 0 @@ -199,11 +166,23 @@ QXK_attr_ + + + 0 + 2 + QF_readySet_ + + + 1 + 2 + QF_readySet_rmc_ + + 1 2 - 0x20000200 + 0x20000E08 0 @@ -713,30 +692,6 @@ 1 3 - 1 - 0 - 0 - 0 - ..\..\..\..\..\include\qstamp.c - qstamp.c - 0 - 0 - - - 1 - 4 - 1 - 0 - 0 - 0 - ..\main.c - main.c - 0 - 0 - - - 1 - 5 5 0 0 @@ -748,7 +703,7 @@ 1 - 6 + 4 1 0 0 @@ -760,7 +715,7 @@ 1 - 7 + 5 1 0 0 @@ -770,6 +725,30 @@ 0 0 + + 1 + 6 + 1 + 0 + 0 + 0 + ..\xthread1.c + xthread1.c + 0 + 0 + + + 1 + 7 + 1 + 0 + 0 + 0 + ..\xthread2.c + xthread2.c + 0 + 0 + 1 8 @@ -777,8 +756,8 @@ 0 0 0 - ..\test.c - test.c + ..\..\main.c + main.c 0 0 @@ -1085,42 +1064,6 @@ 4 32 - 5 - 0 - 0 - 0 - ..\..\..\..\..\ports\arm-cm\qxk\armclang\qep_port.h - qep_port.h - 0 - 0 - - - 4 - 33 - 5 - 0 - 0 - 0 - ..\..\..\..\..\ports\arm-cm\qxk\armclang\qf_port.h - qf_port.h - 0 - 0 - - - 4 - 34 - 5 - 0 - 0 - 0 - ..\..\..\..\..\ports\arm-cm\qxk\armclang\qs_port.h - qs_port.h - 0 - 0 - - - 4 - 35 1 0 0 @@ -1130,18 +1073,6 @@ 0 0 - - 4 - 36 - 5 - 0 - 0 - 0 - ..\..\..\..\..\ports\arm-cm\qxk\armclang\qxk_port.h - qxk_port.h - 0 - 0 - @@ -1152,7 +1083,7 @@ 0 5 - 37 + 33 1 0 0 @@ -1164,7 +1095,7 @@ 5 - 38 + 34 1 0 0 @@ -1176,7 +1107,7 @@ 5 - 39 + 35 1 0 0 @@ -1188,7 +1119,7 @@ 5 - 40 + 36 1 0 0 @@ -1198,6 +1129,18 @@ 0 0 + + 5 + 37 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qs\qstamp.c + qstamp.c + 0 + 0 + diff --git a/examples/arm-cm/dpp_efm32-slstk3401a/qxk/armclang/dpp-qxk.uvprojx b/examples/arm-cm/dpp_efm32-slstk3401a/qxk/armclang/dpp-qxk.uvprojx index 2d3d2f67..e460ae2b 100644 --- a/examples/arm-cm/dpp_efm32-slstk3401a/qxk/armclang/dpp-qxk.uvprojx +++ b/examples/arm-cm/dpp_efm32-slstk3401a/qxk/armclang/dpp-qxk.uvprojx @@ -313,10 +313,10 @@ 0 - 2 + 1 0 0 - 1 + 0 0 0 0 @@ -337,7 +337,7 @@ 0 - QXK_USE_IRQ_HANDLER=FPUEH_IRQHandler QXK_USE_IRQ_NUM=33 + QF_ON_CONTEXT_SW,QXK_USE_IRQ_HANDLER=FPUEH_IRQHandler,QXK_USE_IRQ_NUM=33 ..\..;..\..\..\..\..\include;..\..\..\..\..\ports\arm-cm\qxk\armclang;..\..\..\..\..\3rd_party\CMSIS\Include;..\..\..\..\..\3rd_party\efm32pg1b @@ -361,7 +361,7 @@ - 1 + 0 0 0 0 @@ -370,7 +370,7 @@ 0x00000000 0x20000000 - + .\dpp-qxk.sct --entry Reset_Handler @@ -393,16 +393,6 @@ 5 ..\..\dpp.h - - qstamp.c - 1 - ..\..\..\..\..\include\qstamp.c - - - main.c - 1 - ..\main.c - bsp.h 5 @@ -419,9 +409,19 @@ ..\..\table.c - test.c + xthread1.c 1 - ..\test.c + ..\xthread1.c + + + xthread2.c + 1 + ..\xthread2.c + + + main.c + 1 + ..\..\main.c @@ -553,31 +553,11 @@ QP_port - - qep_port.h - 5 - ..\..\..\..\..\ports\arm-cm\qxk\armclang\qep_port.h - - - qf_port.h - 5 - ..\..\..\..\..\ports\arm-cm\qxk\armclang\qf_port.h - - - qs_port.h - 5 - ..\..\..\..\..\ports\arm-cm\qxk\armclang\qs_port.h - qxk_port.c 1 ..\..\..\..\..\ports\arm-cm\qxk\armclang\qxk_port.c - - qxk_port.h - 5 - ..\..\..\..\..\ports\arm-cm\qxk\armclang\qxk_port.h - @@ -672,6 +652,11 @@ 1 ..\..\..\..\..\src\qs\qs_rx.c + + qstamp.c + 1 + ..\..\..\..\..\src\qs\qstamp.c + @@ -680,7 +665,7 @@ dpp-rel 0x4 ARM-ADS - 6070000::V6.7::.\ARMCLANG + 6160000::V6.16::ARMCLANG 1 @@ -1031,7 +1016,7 @@ - 1 + 0 0 0 0 @@ -1040,7 +1025,7 @@ 0x00000000 0x20000000 - dpp-qxk.sct + .\dpp-qxk.sct --entry Reset_Handler @@ -1063,16 +1048,6 @@ 5 ..\..\dpp.h - - qstamp.c - 1 - ..\..\..\..\..\include\qstamp.c - - - main.c - 1 - ..\main.c - bsp.h 5 @@ -1089,9 +1064,19 @@ ..\..\table.c - test.c + xthread1.c 1 - ..\test.c + ..\xthread1.c + + + xthread2.c + 1 + ..\xthread2.c + + + main.c + 1 + ..\..\main.c @@ -1223,31 +1208,11 @@ QP_port - - qep_port.h - 5 - ..\..\..\..\..\ports\arm-cm\qxk\armclang\qep_port.h - - - qf_port.h - 5 - ..\..\..\..\..\ports\arm-cm\qxk\armclang\qf_port.h - - - qs_port.h - 5 - ..\..\..\..\..\ports\arm-cm\qxk\armclang\qs_port.h - qxk_port.c 1 ..\..\..\..\..\ports\arm-cm\qxk\armclang\qxk_port.c - - qxk_port.h - 5 - ..\..\..\..\..\ports\arm-cm\qxk\armclang\qxk_port.h - @@ -1342,6 +1307,11 @@ 1 ..\..\..\..\..\src\qs\qs_rx.c + + qstamp.c + 1 + ..\..\..\..\..\src\qs\qstamp.c + @@ -1662,7 +1632,7 @@ 0 0 0 - 2 + 3 0 1 1 @@ -1677,7 +1647,7 @@ 0 -Wno-padded - Q_SPY QF_ON_CONTEXT_SW QXK_USE_IRQ_HANDLER=FPUEH_IRQHandler QXK_USE_IRQ_NUM=33 + Q_SPY,QF_ON_CONTEXT_SW,QXK_USE_IRQ_HANDLER=FPUEH_IRQHandler,QXK_USE_IRQ_NUM=33 ..\..;..\..\..\..\..\include;..\..\..\..\..\ports\arm-cm\qxk\armclang;..\..\..\..\..\3rd_party\CMSIS\Include;..\..\..\..\..\3rd_party\efm32pg1b @@ -1701,7 +1671,7 @@ - 1 + 0 0 0 0 @@ -1710,7 +1680,7 @@ 0x00000000 0x20000000 - + .\dpp-qxk.sct --entry Reset_Handler @@ -1733,16 +1703,6 @@ 5 ..\..\dpp.h - - qstamp.c - 1 - ..\..\..\..\..\include\qstamp.c - - - main.c - 1 - ..\main.c - bsp.h 5 @@ -1759,9 +1719,19 @@ ..\..\table.c - test.c + xthread1.c 1 - ..\test.c + ..\xthread1.c + + + xthread2.c + 1 + ..\xthread2.c + + + main.c + 1 + ..\..\main.c @@ -1893,31 +1863,11 @@ QP_port - - qep_port.h - 5 - ..\..\..\..\..\ports\arm-cm\qxk\armclang\qep_port.h - - - qf_port.h - 5 - ..\..\..\..\..\ports\arm-cm\qxk\armclang\qf_port.h - - - qs_port.h - 5 - ..\..\..\..\..\ports\arm-cm\qxk\armclang\qs_port.h - qxk_port.c 1 ..\..\..\..\..\ports\arm-cm\qxk\armclang\qxk_port.c - - qxk_port.h - 5 - ..\..\..\..\..\ports\arm-cm\qxk\armclang\qxk_port.h - @@ -1943,6 +1893,11 @@ 1 ..\..\..\..\..\src\qs\qs_rx.c + + qstamp.c + 1 + ..\..\..\..\..\src\qs\qstamp.c + diff --git a/examples/arm-cm/dpp_efm32-slstk3401a/qxk/bsp.c b/examples/arm-cm/dpp_efm32-slstk3401a/qxk/bsp.c index e095a229..d7225f9a 100644 --- a/examples/arm-cm/dpp_efm32-slstk3401a/qxk/bsp.c +++ b/examples/arm-cm/dpp_efm32-slstk3401a/qxk/bsp.c @@ -1,218 +1,312 @@ -/***************************************************************************** -* Product: DPP example, EFM32-SLSTK3401A board, preemptive QXK kernel -* Last updated for version 7.2.0 -* Last updated on 2022-12-22 -* -* Q u a n t u m L e a P s -* ------------------------ -* Modern Embedded Software -* -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* -* -*****************************************************************************/ -#include "qpc.h" -#include "dpp.h" -#include "bsp.h" +//============================================================================ +// Product: DPP example, EFM32-SLSTK3401A board, QXK kernel +// Last updated for version 7.3.0 +// Last updated on 2023-08-23 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. +// +// This program is open source software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Alternatively, this program may be distributed and modified under the +// terms of Quantum Leaps commercial licenses, which expressly supersede +// the GNU General Public License and are specifically designed for +// licensees interested in retaining the proprietary status of their code. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Contact information: +// +// +//============================================================================ +#include "qpc.h" // QP/C real-time embedded framework +#include "dpp.h" // DPP Application interface +#include "bsp.h" // Board Support Package -#include "em_device.h" /* the device specific header (SiLabs) */ -#include "em_cmu.h" /* Clock Management Unit (SiLabs) */ -#include "em_gpio.h" /* GPIO (SiLabs) */ -#include "em_usart.h" /* USART (SiLabs) */ -/* add other drivers if necessary... */ +#include "em_device.h" // the device specific header (SiLabs) +#include "em_cmu.h" // Clock Management Unit (SiLabs) +#include "em_gpio.h" // GPIO (SiLabs) +#include "em_usart.h" // USART (SiLabs) +// add other drivers if necessary... -Q_DEFINE_THIS_FILE +Q_DEFINE_THIS_FILE // define the name of this file for assertions -/* ISRs defined in this BSP ------------------------------------------------*/ -void SysTick_Handler(void); -void GPIO_EVEN_IRQHandler(void); -void USART0_RX_IRQHandler(void); - -/* Local-scope objects -----------------------------------------------------*/ +// Local-scope objects ----------------------------------------------------- #define LED_PORT gpioPortF -#define LED0_PIN 4 -#define LED1_PIN 5 +#define LED0_PIN 4U +#define LED1_PIN 5U #define PB_PORT gpioPortF -#define PB0_PIN 6 -#define PB1_PIN 7 +#define PB0_PIN 6U +#define PB1_PIN 7U -static uint32_t l_rnd; /* random seed */ +static uint32_t l_rndSeed; #ifdef Q_SPY - QSTimeCtr QS_tickTime_; QSTimeCtr QS_tickPeriod_; - /* QSpy source IDs */ + // QSpy source IDs static QSpyId const l_SysTick_Handler = { 0U }; static QSpyId const l_GPIO_EVEN_IRQHandler = { 0U }; static USART_TypeDef * const l_USART0 = ((USART_TypeDef *)(0x40010000UL)); - enum AppRecords { /* application-specific trace records */ + enum AppRecords { // application-specific trace records PHILO_STAT = QS_USER, PAUSED_STAT, CONTEXT_SW, - COMMAND_STAT }; #endif -/*..........................................................................*/ -void SysTick_Handler(void) { - /* state of the button debouncing, see below */ - static struct ButtonsDebouncing { - uint32_t depressed; - uint32_t previous; - } buttons = { 0U, 0U }; - uint32_t current; - uint32_t tmp; +//============================================================================ +// Error handler and ISRs... - QXK_ISR_ENTRY(); /* inform QXK about entering an ISR */ +Q_NORETURN Q_onError(char const * const module, int_t const id) { + // NOTE: this implementation of the assertion handler is intended only + // for debugging and MUST be changed for deployment of the application + // (assuming that you ship your production code with assertions enabled). + Q_UNUSED_PAR(module); + Q_UNUSED_PAR(id); + QS_ASSERTION(module, id, 10000U); -#ifdef Q_SPY - { - tmp = SysTick->CTRL; /* clear SysTick_CTRL_COUNTFLAG */ - QS_tickTime_ += QS_tickPeriod_; /* account for the clock rollover */ +#ifndef NDEBUG + // light up both LEDs + GPIO->P[LED_PORT].DOUT |= ((1U << LED0_PIN) | (1U << LED1_PIN)); + // for debugging, hang on in an endless loop... + for (;;) { } #endif - QTIMEEVT_TICK_X(0U, &l_SysTick_Handler); /* process time events for rate 0 */ - //QACTIVE_POST(the_Ticker0, 0, &l_SysTick_Handler); /* post to Ticker0 */ + NVIC_SystemReset(); +} +//............................................................................ +void assert_failed(char const * const module, int_t const id); // prototype +void assert_failed(char const * const module, int_t const id) { + Q_onError(module, id); +} - /* Perform the debouncing of buttons. The algorithm for debouncing - * adapted from the book "Embedded Systems Dictionary" by Jack Ganssle - * and Michael Barr, page 71. - */ - current = ~GPIO->P[PB_PORT].DIN; /* read PB0 and BP1 */ - tmp = buttons.depressed; /* save the debounced depressed buttons */ - buttons.depressed |= (buttons.previous & current); /* set depressed */ - buttons.depressed &= (buttons.previous | current); /* clear released */ - buttons.previous = current; /* update the history */ - tmp ^= buttons.depressed; /* changed debounced depressed */ - if ((tmp & (1U << PB0_PIN)) != 0U) { /* debounced PB0 state changed? */ - if ((buttons.depressed & (1U << PB0_PIN)) != 0U) { /* PB0 depressed?*/ - static QEvt const pauseEvt = { PAUSE_SIG, 0U, 0U}; +// ISRs used in the application ============================================ + +void SysTick_Handler(void); // prototype +void SysTick_Handler(void) { + QXK_ISR_ENTRY(); // inform QXK about entering an ISR + + QTIMEEVT_TICK_X(0U, &l_SysTick_Handler); // time events at rate 0 + + // Perform the debouncing of buttons. The algorithm for debouncing + // adapted from the book "Embedded Systems Dictionary" by Jack Ganssle + // and Michael Barr, page 71. + // + // state of the button debouncing + static struct { + uint32_t depressed; + uint32_t previous; + } buttons = { 0U, 0U }; + + uint32_t current = ~GPIO->P[PB_PORT].DIN; // read PB0 and BP1 + uint32_t tmp = buttons.depressed; // save the depressed buttons + buttons.depressed |= (buttons.previous & current); // set depressed + buttons.depressed &= (buttons.previous | current); // clear released + buttons.previous = current; // update the history + tmp ^= buttons.depressed; // changed debounced depressed + current = buttons.depressed; + + if ((tmp & (1U << PB0_PIN)) != 0U) { // debounced PB0 state changed? + if ((current & (1U << PB0_PIN)) != 0U) { // is PB0 depressed? + static QEvt const pauseEvt = QEVT_INITIALIZER(PAUSE_SIG); QACTIVE_PUBLISH(&pauseEvt, &l_SysTick_Handler); } - else { /* the button is released */ - static QEvt const serveEvt = { SERVE_SIG, 0U, 0U}; + else { // the button is released + static QEvt const serveEvt = QEVT_INITIALIZER(SERVE_SIG); QACTIVE_PUBLISH(&serveEvt, &l_SysTick_Handler); } } - QXK_ISR_EXIT(); /* inform QXK about exiting an ISR */ -} -/*..........................................................................*/ -void GPIO_EVEN_IRQHandler(void) { /* for testing, NOTE03 */ - QXK_ISR_ENTRY(); /* inform QXK about entering an ISR */ - -/* for testing... - QACTIVE_POST(AO_Table, Q_NEW(QEvt, TEST_SIG), - &l_GPIO_EVEN_IRQHandler); -*/ - QACTIVE_PUBLISH(Q_NEW(QEvt, TEST_SIG), /* for testing... */ - &l_GPIO_EVEN_IRQHandler); - - QXK_ISR_EXIT(); /* inform QXK about exiting an ISR */ -} -/*..........................................................................*/ #ifdef Q_SPY -/* -* ISR for receiving bytes from the QSPY Back-End -* NOTE: This ISR is "QF-unaware" meaning that it does not interact with -* the QF/QXK and is not disabled. Such ISRs don't need to call QXK_ISR_ENTRY/ -* QXK_ISR_EXIT and they cannot post or publish events. -*/ + tmp = SysTick->CTRL; // clear CTRL_COUNTFLAG + QS_tickTime_ += QS_tickPeriod_; // account for the clock rollover +#endif // Q_SPY + + QXK_ISR_EXIT(); // inform QXK about exiting an ISR +} +//............................................................................ +// interrupt handler for testing preemptions in QXK +void GPIO_EVEN_IRQHandler(void); // prototype +void GPIO_EVEN_IRQHandler(void) { // for testing, NOTE03 + QXK_ISR_ENTRY(); // inform QXK about entering an ISR +// for testing... +#ifdef QEVT_DYN_CTOR + QACTIVE_PUBLISH(Q_NEW(QEvt, TEST_SIG, QEVT_DYNAMIC), + &l_GPIO_EVEN_IRQHandler); +#else + QACTIVE_PUBLISH(Q_NEW(QEvt, TEST_SIG), &l_GPIO_EVEN_IRQHandler); +#endif + + QXK_ISR_EXIT(); // inform QXK about exiting an ISR +} + +//............................................................................ +#ifdef Q_SPY +// ISR for receiving bytes from the QSPY Back-End +// NOTE: This ISR is "QF-unaware" meaning that it does not interact with +// the QF/QXK and is not disabled. Such ISRs don't need to call +// QXK_ISR_ENTRY/QXK_ISR_EXIT and they cannot post or publish events. + +void USART0_RX_IRQHandler(void); // prototype void USART0_RX_IRQHandler(void) { - /* while RX FIFO NOT empty */ + // while RX FIFO NOT empty while ((l_USART0->STATUS & USART_STATUS_RXDATAV) != 0U) { uint32_t b = l_USART0->RXDATA; QS_RX_PUT(b); } QXK_ARM_ERRATUM_838869(); } -#else -void USART0_RX_IRQHandler(void) {} -#endif +#endif // Q_SPY + +//............................................................................ +#ifdef QF_ON_CONTEXT_SW +// NOTE: the context-switch callback is called with interrupts DISABLED +void QF_onContextSw(QActive *prev, QActive *next) { + QS_BEGIN_INCRIT(CONTEXT_SW, 0U) // in critical section! + QS_OBJ(prev); + QS_OBJ(next); + QS_END_INCRIT() +} +#endif // QF_ON_CONTEXT_SW + +//============================================================================ +// BSP functions... -/*..........................................................................*/ void BSP_init(void) { - /* NOTE: SystemInit() already called from the startup code - * but SystemCoreClock needs to be updated - */ + // Configure the MPU to prevent NULL-pointer dereferencing ... + MPU->RBAR = 0x0U // base address (NULL) + | MPU_RBAR_VALID_Msk // valid region + | (MPU_RBAR_REGION_Msk & 7U); // region #7 + MPU->RASR = (7U << MPU_RASR_SIZE_Pos) // 2^(7+1) region + | (0x0U << MPU_RASR_AP_Pos) // no-access region + | MPU_RASR_ENABLE_Msk; // region enable + MPU->CTRL = MPU_CTRL_PRIVDEFENA_Msk // enable background region + | MPU_CTRL_ENABLE_Msk; // enable the MPU + __ISB(); + __DSB(); + + // enable the MemManage_Handler for MPU exception + SCB->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk; + + // NOTE: SystemInit() has been already called from the startup code + // but SystemCoreClock needs to be updated SystemCoreClockUpdate(); - /* NOTE: The VFP (hardware Floating Point) unit is configured by QXK */ + // NOTE: The VFP (hardware Floating Point) unit is configured by QXK - /* enable clock for to the peripherals used by this application... */ + // enable clock for to the peripherals used by this application... CMU_ClockEnable(cmuClock_HFPER, true); CMU_ClockEnable(cmuClock_GPIO, true); CMU_ClockEnable(cmuClock_HFPER, true); CMU_ClockEnable(cmuClock_GPIO, true); - /* configure the LEDs */ + // configure the LEDs GPIO_PinModeSet(LED_PORT, LED0_PIN, gpioModePushPull, 0); GPIO_PinModeSet(LED_PORT, LED1_PIN, gpioModePushPull, 0); GPIO_PinOutClear(LED_PORT, LED0_PIN); GPIO_PinOutClear(LED_PORT, LED1_PIN); - /* configure the Buttons */ + // configure the Buttons GPIO_PinModeSet(PB_PORT, PB0_PIN, gpioModeInputPull, 1); GPIO_PinModeSet(PB_PORT, PB1_PIN, gpioModeInputPull, 1); - /*... */ - BSP_randomSeed(1234U); + BSP_randomSeed(1234U); // seed the random number generator - if (QS_INIT((void *)0) == 0) { /* initialize the QS software tracing */ + // initialize the QS software tracing... + if (!QS_INIT((void *)0)) { Q_ERROR(); } - /* global signals */ - QS_SIG_DICTIONARY(DONE_SIG, (void *)0); - QS_SIG_DICTIONARY(EAT_SIG, (void *)0); - QS_SIG_DICTIONARY(PAUSE_SIG, (void *)0); - QS_SIG_DICTIONARY(SERVE_SIG, (void *)0); - QS_SIG_DICTIONARY(TEST_SIG, (void *)0); - QS_SIG_DICTIONARY(HUNGRY_SIG, (void *)0); - QS_SIG_DICTIONARY(HUNGRY_SIG, (void *)0); - QS_SIG_DICTIONARY(TIMEOUT_SIG, (void *)0); + // dictionaries... QS_OBJ_DICTIONARY(&l_SysTick_Handler); QS_OBJ_DICTIONARY(&l_GPIO_EVEN_IRQHandler); - QS_USR_DICTIONARY(PHILO_STAT); QS_USR_DICTIONARY(PAUSED_STAT); QS_USR_DICTIONARY(CONTEXT_SW); - QS_USR_DICTIONARY(COMMAND_STAT); - /* setup the QS filters... */ - QS_GLB_FILTER(QS_ALL_RECORDS); /* all records */ - QS_GLB_FILTER(-QS_QF_TICK); /* exclude the clock tick */ + QS_ONLY(produce_sig_dict()); + + // setup the QS filters... + QS_GLB_FILTER(QS_ALL_RECORDS); // all records + QS_GLB_FILTER(-QS_QF_TICK); // exclude the clock tick + QS_LOC_FILTER(-(N_PHILO + 3U)); // exclude prio. of AO_Ticker0 } -/*..........................................................................*/ +//............................................................................ +void BSP_start(void) { + // initialize event pools + static QF_MPOOL_EL(TableEvt) smlPoolSto[2*N_PHILO]; + QF_poolInit(smlPoolSto, sizeof(smlPoolSto), sizeof(smlPoolSto[0])); + + // initialize publish-subscribe + static QSubscrList subscrSto[MAX_PUB_SIG]; + QActive_psInit(subscrSto, Q_DIM(subscrSto)); + + // instantiate and start AOs/threads... + static QEvt const *xThread1QueueSto[5]; + static uint64_t xThread1StackSto[64]; + XThread1_ctor(); + QXTHREAD_START(TH_XThread1, + 1U, // QP priority of the thread + xThread1QueueSto, // event queue storage + Q_DIM(xThread1QueueSto), // event length [events] + xThread1StackSto, // stack storage + sizeof(xThread1StackSto), // stack size [bytes] + (void *)0); // no initialization param + + static QEvt const *philoQueueSto[N_PHILO][10]; + for (uint8_t n = 0U; n < N_PHILO; ++n) { + Philo_ctor(n); + QACTIVE_START(AO_Philo[n], + n + 3U, // QF-prio/pthre. see NOTE1 + philoQueueSto[n], // event queue storage + Q_DIM(philoQueueSto[n]), // queue length [events] + (void *)0, 0U, // no stack storage + (void *)0); // no initialization param + } + + static QEvt const *xThread2QueueSto[5]; + static uint64_t xThread2StackSto[64]; + XThread2_ctor(); + QXTHREAD_START(TH_XThread2, + N_PHILO + 5U, // QP priority of the thread + xThread2QueueSto, // event queue storage + Q_DIM(xThread2QueueSto), // event length [events] + xThread2StackSto, // stack storage + sizeof(xThread2StackSto), // stack size [bytes] + (void *)0); // no initialization param + + static QEvt const *tableQueueSto[N_PHILO]; + Table_ctor(); + QACTIVE_START(AO_Table, + N_PHILO + 7U, // QP prio. of the AO + tableQueueSto, // event queue storage + Q_DIM(tableQueueSto), // queue length [events] + (void *)0, 0U, // no stack storage + (void *)0); // no initialization param +} +//............................................................................ void BSP_displayPhilStat(uint8_t n, char const *stat) { - (void)n; /* unused parameter */ + Q_UNUSED_PAR(n); + if (stat[0] == 'e') { GPIO->P[LED_PORT].DOUT |= (1U << LED0_PIN); } @@ -220,324 +314,259 @@ void BSP_displayPhilStat(uint8_t n, char const *stat) { GPIO->P[LED_PORT].DOUT &= ~(1U << LED0_PIN); } - QS_BEGIN_ID(PHILO_STAT, AO_Philo[n]->prio) /* app-specific record */ - QS_U8(1, n); /* Philosopher number */ - QS_STR(stat); /* Philosopher status */ + // app-specific trace record... + QS_BEGIN_ID(PHILO_STAT, AO_Table->prio) + QS_U8(1, n); // Philosopher number + QS_STR(stat); // Philosopher status QS_END() } -/*..........................................................................*/ -void BSP_displayPaused(uint8_t paused) { +//............................................................................ +void BSP_displayPaused(uint8_t const paused) { if (paused != 0U) { - /* for testing the extended threads... */ - static QEvt const pauseEvt = { PAUSE_SIG, 0U, 0U}; - QXThread_delayCancel(XT_Test2); /* make sure Test2 is not delayed */ - QACTIVE_POST_X(&XT_Test2->super, &pauseEvt, 1U, (void *)0); - GPIO->P[LED_PORT].DOUT |= (1U << LED0_PIN); } else { GPIO->P[LED_PORT].DOUT &= ~(1U << LED0_PIN); } - QS_BEGIN_ID(PAUSED_STAT, 0U) /* app-specific record */ - QS_U8(1, paused); /* Paused status */ + // application-specific trace record + QS_BEGIN_ID(PAUSED_STAT, AO_Table->prio) + QS_U8(1, paused); // Paused status QS_END() } -/*..........................................................................*/ -uint32_t BSP_random(void) { /* a very cheap pseudo-random-number generator */ - uint32_t rnd; - QSchedStatus lockStat; - - /* Some flating point code is to exercise the VFP... */ +//............................................................................ +void BSP_randomSeed(uint32_t seed) { + l_rndSeed = seed; +} +//............................................................................ +uint32_t BSP_random(void) { // a very cheap pseudo-random-number generator + // Some floating point code is to exercise the VFP... float volatile x = 3.1415926F; x = x + 2.7182818F; - lockStat = QXK_schedLock(N_PHILO); /* lock scheduler up to N_PHILO prio */ - /* "Super-Duper" Linear Congruential Generator (LCG) - * LCG(2^32, 3*7*11*13*23, 0, seed) - */ - rnd = l_rnd * (3U*7U*11U*13U*23U); - l_rnd = rnd; /* set for the next time */ - QXK_schedUnlock(lockStat); /* unlock the scheduler */ + QSchedStatus lockStat = QXK_schedLock(N_PHILO); // N_PHILO prio. ceiling + // "Super-Duper" Linear Congruential Generator (LCG) + // LCG(2^32, 3*7*11*13*23, 0, seed) + // + uint32_t rnd = l_rndSeed * (3U*7U*11U*13U*23U); + l_rndSeed = rnd; // set for the next time + QXK_schedUnlock(lockStat); - return (rnd >> 8); + return (rnd >> 8U); } -/*..........................................................................*/ -void BSP_randomSeed(uint32_t seed) { - l_rnd = seed; -} -/*..........................................................................*/ +//............................................................................ void BSP_ledOn(void) { GPIO->P[LED_PORT].DOUT |= (1U << LED1_PIN); } -/*..........................................................................*/ +//............................................................................ void BSP_ledOff(void) { GPIO->P[LED_PORT].DOUT &= ~(1U << LED1_PIN); } -/*..........................................................................*/ +//............................................................................ void BSP_terminate(int16_t result) { - (void)result; + Q_UNUSED_PAR(result); } -/*..........................................................................*/ +//============================================================================ +// QF callbacks... void QF_onStartup(void) { - /* set up the SysTick timer to fire at BSP_TICKS_PER_SEC rate */ + // set up the SysTick timer to fire at BSP_TICKS_PER_SEC rate SysTick_Config(SystemCoreClock / BSP_TICKS_PER_SEC); - /* assing all priority bits for preemption-prio. and none to sub-prio. */ + // assign all priority bits for preemption-prio. and none to sub-prio. NVIC_SetPriorityGrouping(0U); - /* set priorities of ALL ISRs used in the system, see NOTE1 - * - * !!!!!!!!!!!!!!!!!!!!!!!!!!!! CAUTION !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - * Assign a priority to EVERY ISR explicitly by calling NVIC_SetPriority(). - * DO NOT LEAVE THE ISR PRIORITIES AT THE DEFAULT VALUE! - */ - NVIC_SetPriority(USART0_RX_IRQn, 0U); /* kernel unaware interrupt */ - NVIC_SetPriority(GPIO_EVEN_IRQn, QF_AWARE_ISR_CMSIS_PRI); + // set priorities of ALL ISRs used in the system, see NOTE1 + NVIC_SetPriority(USART0_RX_IRQn, 0U); // kernel unaware interrupt + NVIC_SetPriority(GPIO_EVEN_IRQn, QF_AWARE_ISR_CMSIS_PRI + 0U); NVIC_SetPriority(SysTick_IRQn, QF_AWARE_ISR_CMSIS_PRI + 1U); - /* ... */ + // ... - /* enable IRQs... */ + // enable IRQs... NVIC_EnableIRQ(GPIO_EVEN_IRQn); + #ifdef Q_SPY - NVIC_EnableIRQ(USART0_RX_IRQn); /* UART0 interrupt used for QS-RX */ + NVIC_EnableIRQ(USART0_RX_IRQn); // UART0 interrupt used for QS-RX #endif } -/*..........................................................................*/ +//............................................................................ void QF_onCleanup(void) { } -/*..........................................................................*/ -#ifdef QF_ON_CONTEXT_SW -/* NOTE: the context-switch callback is called with interrupts DISABLED */ -void QF_onContextSw(QActive *prev, QActive *next) { - (void)prev; - if (next != (QActive *)0) { - //_impure_ptr = next->thread; /* switch to next TLS */ - } - QS_BEGIN_NOCRIT(CONTEXT_SW, 0U) /* no critical section! */ - QS_OBJ(prev); - QS_OBJ(next); - QS_END_NOCRIT() -} -#endif /* QF_ON_CONTEXT_SW */ -/*..........................................................................*/ +//............................................................................ void QXK_onIdle(void) { - float volatile x; - - /* toggle the User LED on and then off, see NOTE2 */ -/* - QF_INT_DISABLE(); - GPIO->P[LED_PORT].DOUT |= (1U << LED1_PIN); - GPIO->P[LED_PORT].DOUT &= ~(1U << LED1_PIN); - QF_INT_ENABLE(); -*/ - /* Some floating point code is to exercise the VFP... */ - x = 1.73205F; - x = x * 1.73205F; + // toggle the User LED on and then off, see NOTE3 +// QF_INT_DISABLE(); +// GPIO->P[LED_PORT].DOUT |= (1U << LED1_PIN); +// GPIO->P[LED_PORT].DOUT &= ~(1U << LED1_PIN); +// QF_INT_ENABLE(); #ifdef Q_SPY - QS_rxParse(); /* parse all the received bytes */ - - if ((l_USART0->STATUS & USART_STATUS_TXBL) != 0) { /* is TXE empty? */ - uint16_t b; + QF_INT_DISABLE(); + QS_rxParse(); // parse all the received bytes + QF_INT_ENABLE(); + if ((l_USART0->STATUS & USART_STATUS_TXBL) != 0) { // is TXE empty? QF_INT_DISABLE(); - b = QS_getByte(); + uint16_t b = QS_getByte(); QF_INT_ENABLE(); - if (b != QS_EOD) { /* not End-Of-Data? */ - l_USART0->TXDATA = (b & 0xFFU); /* put into the DR register */ + if (b != QS_EOD) { // not End-Of-Data? + l_USART0->TXDATA = (b & 0xFFU); // put into the DR register } } #elif defined NDEBUG - /* Put the CPU and peripherals to the low-power mode. - * you might need to customize the clock management for your application, - * see the datasheet for your particular Cortex-M3 MCU. - */ - __WFI(); /* Wait-For-Interrupt */ + // Put the CPU and peripherals to the low-power mode. + // you might need to customize the clock management for your application, + // see the datasheet for your particular Cortex-M MCU. + // + __WFI(); // Wait-For-Interrupt #endif } -/*..........................................................................*/ -Q_NORETURN Q_onAssert(char const * const module, int_t const loc) { - /* - * NOTE: add here your application-specific error handling - */ - (void)module; - (void)loc; - QS_ASSERTION(module, loc, 10000U); /* report assertion to QS */ - -#ifndef NDEBUG - /* light up both LEDs */ - GPIO->P[LED_PORT].DOUT |= ((1U << LED0_PIN) | (1U << LED1_PIN)); - /* for debugging, hang on in an endless loop until PB1 is pressed... */ - while ((GPIO->P[PB_PORT].DIN & (1U << PB1_PIN)) != 0) { - } -#endif - - NVIC_SystemReset(); -} - -/* QS callbacks ============================================================*/ +//============================================================================ +// QS callbacks... #ifdef Q_SPY -/*..........................................................................*/ + +//............................................................................ uint8_t QS_onStartup(void const *arg) { Q_UNUSED_PAR(arg); - static uint8_t qsTxBuf[2*1024]; /* buffer for QS transmit channel */ - static uint8_t qsRxBuf[100]; /* buffer for QS receive channel */ - static USART_InitAsync_TypeDef init = { - usartEnable, /* Enable RX/TX when init completed */ - 0, /* Use current clock for configuring baudrate */ - 115200, /* 115200 bits/s */ - usartOVS16, /* 16x oversampling */ - usartDatabits8, /* 8 databits */ - usartNoParity, /* No parity */ - usartStopbits1, /* 1 stopbit */ - 0, /* Do not disable majority vote */ - 0, /* Not USART PRS input mode */ - usartPrsRxCh0, /* PRS channel 0 */ - 0, /* Auto CS functionality enable/disable switch */ - 0, /* Auto CS Hold cycles */ - 0 /* Auto CS Setup cycles */ - }; + static uint8_t qsTxBuf[2*1024]; // buffer for QS-TX channel + QS_initBuf(qsTxBuf, sizeof(qsTxBuf)); - (void)arg; /* unused parameter */ - QS_initBuf (qsTxBuf, sizeof(qsTxBuf)); + static uint8_t qsRxBuf[100]; // buffer for QS-RX channel QS_rxInitBuf(qsRxBuf, sizeof(qsRxBuf)); - /* Enable peripheral clocks */ + static USART_InitAsync_TypeDef init = { + usartEnable, // Enable RX/TX when init completed + 0, // Use current clock for configuring baudrate + 115200, // 115200 bits/s + usartOVS16, // 16x oversampling + usartDatabits8, // 8 databits + usartNoParity, // No parity + usartStopbits1, // 1 stopbit + 0, // Do not disable majority vote + 0, // Not USART PRS input mode + usartPrsRxCh0, // PRS channel 0 + 0, // Auto CS functionality enable/disable switch + 0, // Auto CS Hold cycles + 0 // Auto CS Setup cycles + }; + + // Enable peripheral clocks CMU_ClockEnable(cmuClock_HFPER, true); CMU_ClockEnable(cmuClock_GPIO, true); - /* To avoid false start, configure output as high */ - GPIO_PinModeSet(gpioPortA, 0, gpioModePushPull, 1); /* TX pin */ - GPIO_PinModeSet(gpioPortA, 1, gpioModeInput, 0); /* RX pin */ + // To avoid false start, configure output as high + GPIO_PinModeSet(gpioPortA, 0, gpioModePushPull, 1); // TX pin + GPIO_PinModeSet(gpioPortA, 1, gpioModeInput, 0); // RX pin - /* Enable DK RS232/UART switch */ + // Enable DK RS232/UART switch GPIO_PinModeSet(gpioPortA, 5, gpioModePushPull, 1); CMU_ClockEnable(cmuClock_USART0, true); - /* configure the UART for the desired baud rate, 8-N-1 operation */ + // configure the UART for the desired baud rate, 8-N-1 operation init.enable = usartDisable; USART_InitAsync(l_USART0, &init); - /* enable pins at correct UART/USART location. */ + // enable pins at correct UART/USART location. l_USART0->ROUTEPEN = USART_ROUTEPEN_RXPEN | USART_ROUTEPEN_TXPEN; l_USART0->ROUTELOC0 = (l_USART0->ROUTELOC0 & ~(_USART_ROUTELOC0_TXLOC_MASK | _USART_ROUTELOC0_RXLOC_MASK)); - /* Clear previous RX interrupts */ + // Clear previous RX interrupts USART_IntClear(l_USART0, USART_IF_RXDATAV); NVIC_ClearPendingIRQ(USART0_RX_IRQn); - /* Enable RX interrupts */ + // Enable RX interrupts USART_IntEnable(l_USART0, USART_IF_RXDATAV); - /* NOTE: do not enable the UART0 interrupt in the NVIC yet. - * Wait till QF_onStartup() - */ + // NOTE: do not enable the UART0 interrupt in the NVIC yet. + // Wait till QF_onStartup() + // - /* Finally enable the UART */ + // Finally enable the UART USART_Enable(l_USART0, usartEnable); QS_tickPeriod_ = SystemCoreClock / BSP_TICKS_PER_SEC; - QS_tickTime_ = QS_tickPeriod_; /* to start the timestamp at zero */ + QS_tickTime_ = QS_tickPeriod_; // to start the timestamp at zero - return 1U; /* return success */ + return 1U; // return success } -/*..........................................................................*/ +//............................................................................ void QS_onCleanup(void) { } -/*..........................................................................*/ -QSTimeCtr QS_onGetTime(void) { /* NOTE: invoked with interrupts DISABLED */ - if ((SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk) == 0) { /* not set? */ +//............................................................................ +QSTimeCtr QS_onGetTime(void) { // NOTE: invoked with interrupts DISABLED + if ((SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk) == 0) { // not set? return QS_tickTime_ - (QSTimeCtr)SysTick->VAL; } - else { /* the rollover occured, but the SysTick_ISR did not run yet */ + else { // the rollover occured, but the SysTick_ISR did not run yet return QS_tickTime_ + QS_tickPeriod_ - (QSTimeCtr)SysTick->VAL; } } -/*..........................................................................*/ +//............................................................................ void QS_onFlush(void) { - uint16_t b; - - QF_INT_DISABLE(); - while ((b = QS_getByte()) != QS_EOD) { /* while not End-Of-Data... */ - QF_INT_ENABLE(); - /* while TXE not empty */ - while ((l_USART0->STATUS & USART_STATUS_TXBL) == 0U) { - } - l_USART0->TXDATA = (b & 0xFFU); /* put into the DR register */ + for (;;) { QF_INT_DISABLE(); + uint16_t b = QS_getByte(); + if (b != QS_EOD) { + while ((l_USART0->STATUS & USART_STATUS_TXBL) == 0U) { + QF_INT_ENABLE(); + QF_CRIT_EXIT_NOP(); + + QF_INT_DISABLE(); + } + l_USART0->TXDATA = b; // put into the DR register + QF_INT_ENABLE(); + } + else { + QF_INT_ENABLE(); + break; + } } - QF_INT_ENABLE(); } -/*..........................................................................*/ -/*! callback function to reset the target (to be implemented in the BSP) */ +//............................................................................ +//! callback function to reset the target (to be implemented in the BSP) void QS_onReset(void) { NVIC_SystemReset(); } -/*..........................................................................*/ -/*! callback function to execute a user command (to be implemented in BSP) */ +//............................................................................ +// callback function to execute a user command void QS_onCommand(uint8_t cmdId, uint32_t param1, uint32_t param2, uint32_t param3) { - void assert_failed(char const *module, int loc); - (void)cmdId; - (void)param1; - (void)param2; - (void)param3; - QS_BEGIN_ID(COMMAND_STAT, 0U) /* app-specific record */ - QS_U8(2, cmdId); - QS_U32(8, param1); - QS_U32(8, param2); - QS_U32(8, param3); - QS_END() - - if (cmdId == 10U) { - Q_ERROR(); - } - else if (cmdId == 11U) { - assert_failed("QS_onCommand", 123); - } + Q_UNUSED_PAR(cmdId); + Q_UNUSED_PAR(param1); + Q_UNUSED_PAR(param2); + Q_UNUSED_PAR(param3); } -#endif /* Q_SPY */ -/*--------------------------------------------------------------------------*/ +#endif // Q_SPY +//---------------------------------------------------------------------------- -/***************************************************************************** -* NOTE1: -* The QF_AWARE_ISR_CMSIS_PRI constant from the QF port specifies the highest -* ISR priority that is disabled by the QF framework. The value is suitable -* for the NVIC_SetPriority() CMSIS function. -* -* Only ISRs prioritized at or below the QF_AWARE_ISR_CMSIS_PRI level (i.e., -* with the numerical values of priorities equal or higher than -* QF_AWARE_ISR_CMSIS_PRI) are allowed to call the QXK_ISR_ENTRY/QXK_ISR_EXIT -* macros or any other QF/QXK services. These ISRs are "QF-aware". -* -* Conversely, any ISRs prioritized above the QF_AWARE_ISR_CMSIS_PRI priority -* level (i.e., with the numerical values of priorities less than -* QF_AWARE_ISR_CMSIS_PRI) are never disabled and are not aware of the kernel. -* Such "QF-unaware" ISRs cannot call any QF/QXK services. In particular they -* can NOT call the macros QXK_ISR_ENTRY/QXK_ISR_ENTRY. The only mechanism -* by which a "QF-unaware" ISR can communicate with the QF framework is by -* triggering a "QF-aware" ISR, which can post/publish events. -* -* NOTE2: -* The User LED is used to visualize the idle loop activity. The brightness -* of the LED is proportional to the frequency of invcations of the idle loop. -* Please note that the LED is toggled with interrupts locked, so no interrupt -* execution time contributes to the brightness of the User LED. -* -* NOTE3: -* GPIO_EVEN_IRQHandler() is for testing various preemption scenarios in QXK. -* The general testing strategy is to trigger this IRQ manually from the -* debugger. To do so in IAR, you need to: -* 1. open the Register view -* 2. open NVIC registers -* 3. scroll down to NVIC_ISPR0 register -* 4. write 0x200 to NVIC_ISPR0.SETPEND register -*/ +//============================================================================ +// NOTE1: +// The QF_AWARE_ISR_CMSIS_PRI constant from the QF port specifies the highest +// ISR priority that is disabled by the QF framework. The value is suitable +// for the NVIC_SetPriority() CMSIS function. +// +// Only ISRs prioritized at or below the QF_AWARE_ISR_CMSIS_PRI level (i.e., +// with the numerical values of priorities equal or higher than +// QF_AWARE_ISR_CMSIS_PRI) are allowed to call the QXK_ISR_ENTRY/QXK_ISR_EXIT +// macros or any other QF/QXK services. These ISRs are "QF-aware". +// +// Conversely, any ISRs prioritized above the QF_AWARE_ISR_CMSIS_PRI priority +// level (i.e., with the numerical values of priorities less than +// QF_AWARE_ISR_CMSIS_PRI) are never disabled and are not aware of the kernel. +// Such "QF-unaware" ISRs cannot call ANY QF/QXK services. In particular they +// can NOT call the macros QXK_ISR_ENTRY/QXK_ISR_ENTRY. The only mechanism +// by which a "QF-unaware" ISR can communicate with the QF framework is by +// triggering a "QF-aware" ISR, which can post/publish events. +// +// NOTE2: +// The User LED is used to visualize the idle loop activity. The brightness +// of the LED is proportional to the frequency of the idle loop. +// Please note that the LED is toggled with interrupts locked, so no interrupt +// execution time contributes to the brightness of the User LED. +// diff --git a/examples/arm-cm/dpp_efm32-slstk3401a/qxk/gnu/Makefile b/examples/arm-cm/dpp_efm32-slstk3401a/qxk/gnu/Makefile index 8099a87a..bb7d1d25 100644 --- a/examples/arm-cm/dpp_efm32-slstk3401a/qxk/gnu/Makefile +++ b/examples/arm-cm/dpp_efm32-slstk3401a/qxk/gnu/Makefile @@ -1,7 +1,7 @@ ############################################################################## # Product: Makefile for QP/C on EMF32-SLSTK3401A, QXK kernel, GNU-ARM -# Last Updated for Version: 7.2.1 -# Date of the Last Update: 2023-01-14 +# Last Updated for Version: 7.3.0 +# Date of the Last Update: 2023-09-02 # # Q u a n t u m L e a P s # ------------------------ @@ -78,6 +78,7 @@ VPATH = \ # list of all include directories needed by this project INCLUDES = \ + -I.. \ -I../.. \ -I$(QPC)/include \ -I$(QP_PORT_DIR) \ @@ -97,7 +98,8 @@ C_SRCS := \ main.c \ philo.c \ table.c \ - test.c \ + xthread1.c \ + xthread2.c \ startup_efm32pg1b.c \ system_efm32pg1b.c \ em_cmu.c \ @@ -142,9 +144,7 @@ LIBS := # defines DEFINES := -DEFM32PG1B200F256GM48=1 \ - -DQF_ON_CONTEXT_SW \ - -DQXK_USE_IRQ_NUM=33 \ - -DQXK_USE_IRQ_HANDLER=FPUEH_IRQHandler + -DQP_CONFIG # ARM CPU, ARCH, FPU, and Float-ABI types... # ARM_CPU: [cortex-m0 | cortex-m0plus | cortex-m1 | cortex-m3 | cortex-m4] @@ -199,7 +199,7 @@ BIN_DIR := rel ASFLAGS = $(ARM_CPU) $(ARM_FPU) $(ASM_CPU) $(ASM_FPU) CFLAGS = -c $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb \ - -std=c99 -pedantic -Wall -Wextra -W \ + -std=c11 -pedantic -Wall -Wextra -W \ -ffunction-sections -fdata-sections \ -O1 $(INCLUDES) $(DEFINES) -DNDEBUG @@ -216,7 +216,7 @@ C_SRCS += $(QS_SRCS) ASFLAGS = -g $(ARM_CPU) $(ARM_FPU) $(ASM_CPU) $(ASM_FPU) CFLAGS = -c -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb \ - -std=c99 -pedantic -Wall -Wextra -W \ + -std=c11 -pedantic -Wall -Wextra -W \ -ffunction-sections -fdata-sections \ -O $(INCLUDES) $(DEFINES) -DQ_SPY @@ -231,7 +231,7 @@ BIN_DIR := dbg ASFLAGS = -g $(ARM_CPU) $(ARM_FPU) $(ASM_CPU) $(ASM_FPU) CFLAGS = -c -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb \ - -std=c99 -pedantic -Wall -Wextra -W \ + -std=c11 -pedantic -Wall -Wextra -W \ -ffunction-sections -fdata-sections \ -O $(INCLUDES) $(DEFINES) @@ -275,7 +275,7 @@ $(TARGET_BIN): $(TARGET_ELF) $(BIN) -O binary $< $@ $(TARGET_ELF) : $(ASM_OBJS_EXT) $(C_OBJS_EXT) $(CPP_OBJS_EXT) - $(CC) $(CFLAGS) $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o + $(CC) $(CFLAGS) $(QPC)/src/qs/qstamp.c -o $(BIN_DIR)/qstamp.o $(LINK) $(LINKFLAGS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) $(BIN_DIR)/%.d : %.c diff --git a/examples/arm-cm/dpp_efm32-slstk3401a/qxk/iar/dpp-qxk.ewd b/examples/arm-cm/dpp_efm32-slstk3401a/qxk/iar/dpp-qxk.ewd index 42451eb1..cb16c888 100644 --- a/examples/arm-cm/dpp_efm32-slstk3401a/qxk/iar/dpp-qxk.ewd +++ b/examples/arm-cm/dpp_efm32-slstk3401a/qxk/iar/dpp-qxk.ewd @@ -11,7 +11,7 @@ C-SPY 2 - 28 + 32 1 1 - - + + + + + @@ -486,7 +498,7 @@ IJET_ID 2 - 8 + 9 1 1 + + + + + + + + + + + + + @@ -916,7 +980,7 @@ LMIFTDI_ID 2 - 2 + 3 1 1 + + + + + + + NULINK_ID + 2 + + 0 + 1 + 1 + + + @@ -974,7 +1072,7 @@ STLINK_ID 2 - 4 + 8 1 1 + + + + @@ -1185,7 +1300,7 @@ XDS100_ID 2 - 6 + 9 1 1 + + + + @@ -1362,6 +1493,18 @@ $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin 0 + + $TOOLKIT_DIR$\plugins\rtos\FreeRtos\FreeRtosArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin2.ENU.ewplugin + 0 + $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin 0 @@ -1371,11 +1514,15 @@ 0 - $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9.ewplugin 0 - $TOOLKIT_DIR$\plugins\rtos\TI-RTOS\tirtosplugin.ewplugin + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9BE.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin 0 @@ -1391,11 +1538,11 @@ 0 - $EW_DIR$\common\plugins\CodeCoverage\CodeCoverage.ENU.ewplugin - 1 + $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + 0 - $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + $EW_DIR$\common\plugins\TargetAccessServer\TargetAccessServer.ENU.ewplugin 0 @@ -1414,7 +1561,7 @@ C-SPY 2 - 28 + 32 1 0 - - + + + + + @@ -1889,7 +2048,7 @@ IJET_ID 2 - 8 + 9 1 0 + + + + + + + + + + + + + @@ -2319,7 +2530,7 @@ LMIFTDI_ID 2 - 2 + 3 1 0 + + + + + + + NULINK_ID + 2 + + 0 + 1 + 0 + + + @@ -2377,7 +2622,7 @@ STLINK_ID 2 - 4 + 8 1 0 + + + + @@ -2588,7 +2850,7 @@ XDS100_ID 2 - 6 + 9 1 0 + + + + @@ -2765,6 +3043,18 @@ $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin 0 + + $TOOLKIT_DIR$\plugins\rtos\FreeRtos\FreeRtosArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin2.ENU.ewplugin + 0 + $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin 0 @@ -2774,11 +3064,15 @@ 0 - $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9.ewplugin 0 - $TOOLKIT_DIR$\plugins\rtos\TI-RTOS\tirtosplugin.ewplugin + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9BE.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin 0 @@ -2794,11 +3088,11 @@ 0 - $EW_DIR$\common\plugins\CodeCoverage\CodeCoverage.ENU.ewplugin - 1 + $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + 0 - $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + $EW_DIR$\common\plugins\TargetAccessServer\TargetAccessServer.ENU.ewplugin 0 @@ -2817,7 +3111,7 @@ C-SPY 2 - 28 + 32 1 1 - - + + + + + @@ -3292,7 +3598,7 @@ IJET_ID 2 - 8 + 9 1 1 + + + + + + + + + + + + + @@ -3722,7 +4080,7 @@ LMIFTDI_ID 2 - 2 + 3 1 1 + + + + + + + NULINK_ID + 2 + + 0 + 1 + 1 + + + @@ -3780,7 +4172,7 @@ STLINK_ID 2 - 4 + 8 1 1 + + + + @@ -3991,7 +4400,7 @@ XDS100_ID 2 - 6 + 9 1 1 + + + + @@ -4168,6 +4593,18 @@ $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin 0 + + $TOOLKIT_DIR$\plugins\rtos\FreeRtos\FreeRtosArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin2.ENU.ewplugin + 0 + $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin 0 @@ -4177,11 +4614,15 @@ 0 - $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9.ewplugin 0 - $TOOLKIT_DIR$\plugins\rtos\TI-RTOS\tirtosplugin.ewplugin + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9BE.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin 0 @@ -4197,11 +4638,11 @@ 0 - $EW_DIR$\common\plugins\CodeCoverage\CodeCoverage.ENU.ewplugin - 1 + $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + 0 - $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + $EW_DIR$\common\plugins\TargetAccessServer\TargetAccessServer.ENU.ewplugin 0 diff --git a/examples/arm-cm/dpp_efm32-slstk3401a/qxk/iar/dpp-qxk.ewp b/examples/arm-cm/dpp_efm32-slstk3401a/qxk/iar/dpp-qxk.ewp index d0715762..96c567e9 100644 --- a/examples/arm-cm/dpp_efm32-slstk3401a/qxk/iar/dpp-qxk.ewp +++ b/examples/arm-cm/dpp_efm32-slstk3401a/qxk/iar/dpp-qxk.ewp @@ -11,12 +11,12 @@ General 3 - 33 + 35 1 1 + + + @@ -675,7 +687,7 @@ ILINK 0 - 25 + 27 1 1 + + + + @@ -1066,12 +1094,12 @@ General 3 - 33 + 35 1 0 + + + @@ -1728,7 +1768,7 @@ ILINK 0 - 25 + 27 1 0 + + + + @@ -2119,12 +2175,12 @@ General 3 - 33 + 35 1 1 + + + @@ -2323,9 +2391,10 @@ @@ -3179,19 +3264,19 @@ $PROJ_DIR$\..\..\dpp.h - $PROJ_DIR$\..\main.c + $PROJ_DIR$\..\..\main.c $PROJ_DIR$\..\..\philo.c - - $PROJ_DIR$\..\..\..\..\..\include\qstamp.c - $PROJ_DIR$\..\..\table.c - $PROJ_DIR$\..\test.c + $PROJ_DIR$\..\xthread1.c + + + $PROJ_DIR$\..\xthread2.c @@ -3296,5 +3381,8 @@ $PROJ_DIR$\..\..\..\..\..\src\qs\qs_rx.c + + $PROJ_DIR$\..\..\..\..\..\src\qs\qstamp.c + diff --git a/examples/arm-cm/dpp_efm32-slstk3401a/qxk/main.c b/examples/arm-cm/dpp_efm32-slstk3401a/qxk/main.c deleted file mode 100644 index 1737b21c..00000000 --- a/examples/arm-cm/dpp_efm32-slstk3401a/qxk/main.c +++ /dev/null @@ -1,118 +0,0 @@ -/***************************************************************************** -* Product: DPP example extened for QXK -* Last updated for version 7.1.2 -* Last updated on 2022-09-22 -* -* Q u a n t u m L e a P s -* ------------------------ -* Modern Embedded Software -* -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* -* -*****************************************************************************/ -#include "qpc.h" -#include "dpp.h" -#include "bsp.h" - -Q_DEFINE_THIS_FILE - -static QTicker l_ticker0; -QActive *the_Ticker0 = &l_ticker0.super; - -/*..........................................................................*/ -int main() { - static QEvt const *tableQueueSto[N_PHILO]; - static QEvt const *philoQueueSto[N_PHILO][N_PHILO]; - static QSubscrList subscrSto[MAX_PUB_SIG]; - static QF_MPOOL_EL(TableEvt) smlPoolSto[2*N_PHILO]; /* small pool */ - - /* stacks and queues for the extended test threads */ - static void const *test1QueueSto[5]; - static uint64_t test1StackSto[64]; - static void const *test2QueueSto[5]; - static uint64_t test2StackSto[64]; - - QF_init(); /* initialize the framework and the underlying RT kernel */ - BSP_init(); /* initialize the Board Support Package */ - - /* initialize publish-subscribe... */ - QF_psInit(subscrSto, Q_DIM(subscrSto)); - - /* initialize event pools... */ - QF_poolInit(smlPoolSto, sizeof(smlPoolSto), sizeof(smlPoolSto[0])); - - /* start the extended thread */ - Test1_ctor(); /* instantiate the Test1 extended thread */ - QXTHREAD_START(XT_Test1, /* Thread to start */ - 1U, /* QF-prio/pre-thre. */ - test1QueueSto, /* message queue storage */ - Q_DIM(test1QueueSto), /* message length [events] */ - test1StackSto, /* stack storage */ - sizeof(test1StackSto),/* stack size [bytes] */ - (void *)0); /* initialization param */ - - /* NOTE: leave priority 2 free for a mutex */ - - /* start the Philo active objects... */ - for (uint8_t n = 0U; n < N_PHILO; ++n) { - Philo_ctor(n); /* instantiate Philo[n] AO */ - QACTIVE_START(AO_Philo[n], /* AO to start */ - n + 3U, /* QF-prio/pre-thre. */ - philoQueueSto[n], /* event queue storage */ - Q_DIM(philoQueueSto[n]), /* queue length [events] */ - (void *)0, /* stack storage (not used) */ - 0U, /* size of the stack [bytes] */ - (void *)0); /* initialization param */ - } - - /* example of prioritizing the Ticker0 active object */ - QTicker_ctor(&l_ticker0, 0U); /* ticker AO for tick rate 0 */ - QACTIVE_START(the_Ticker0, - N_PHILO + 3U, /* QF-prio/pre-thre. */ - 0, 0U, 0, 0U, (void *)0); - - /* NOTE: leave priority (N_PHILO + 4) free for mutex */ - - Test2_ctor(); /* instantiate the Test2 extended thread */ - QXTHREAD_START(XT_Test2, /* Thread to start */ - N_PHILO + 5U, /* QF-prio/pre-thre. */ - test2QueueSto, /* message queue storage */ - Q_DIM(test2QueueSto), /* message length [events] */ - test2StackSto, /* stack storage */ - sizeof(test2StackSto), /* stack size [bytes] */ - (void *)0); /* initialization param */ - - /* NOTE: leave priority (N_PHILO + 6) free for mutex */ - - Table_ctor(); /* instantiate the Table active object */ - QACTIVE_START(AO_Table, /* AO to start */ - N_PHILO + 7U, /* QF-prio/pre-thre. */ - tableQueueSto, /* event queue storage */ - Q_DIM(tableQueueSto), /* queue length [events] */ - (void *)0, /* stack storage (not used) */ - 0U, /* size of the stack [bytes] */ - (void *)0); /* initialization param */ - - return QF_run(); /* run the QF application */ -} diff --git a/examples/arm-cm/dpp_efm32-slstk3401a/qxk/test.c b/examples/arm-cm/dpp_efm32-slstk3401a/qxk/test.c deleted file mode 100644 index ba2c3de0..00000000 --- a/examples/arm-cm/dpp_efm32-slstk3401a/qxk/test.c +++ /dev/null @@ -1,150 +0,0 @@ -/***************************************************************************** -* Product: DPP example -* Last updated for version 7.1.1 -* Last updated on 2022-09-22 -* -* Q u a n t u m L e a P s -* ------------------------ -* Modern Embedded Software -* -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* -* -*****************************************************************************/ -#include "qpc.h" -#include "dpp.h" -#include "bsp.h" - -/* local "extended" thread object ..........................................*/ -static QXThread l_test1; -static QXThread l_test2; -static QXSemaphore l_sema; -static QXMutex l_mutex; - -/* Thread-Local Storage for the "extended" threads .........................*/ -typedef struct { - uint32_t foo; - uint8_t bar[10]; -} TLS_test; -static TLS_test l_tls1; -static TLS_test l_tls2; - -static void lib_fun(uint32_t x) { - QXK_TLS(TLS_test *)->foo = x; -} - -/* global pointer to the test thread .......................................*/ -QXThread * const XT_Test1 = &l_test1; -QXThread * const XT_Test2 = &l_test2; - -/*..........................................................................*/ -static void Thread1_run(QXThread * const me) { - - QS_OBJ_DICTIONARY(&l_test1); - QS_OBJ_DICTIONARY(&l_test1.timeEvt); - QS_OBJ_DICTIONARY(&l_mutex); - - me->super.thread = &l_tls1; /* initialize the TLS for Thread1 */ - - for (;;) { - QXMutex_lock(&l_mutex, QXTHREAD_NO_TIMEOUT); /* lock the mutex */ - BSP_ledOn(); - - if (QXMutex_tryLock(&l_mutex)) { /* exercise the mutex */ - float volatile x; - - /* some flating point code to exercise the VFP... */ - x = 1.4142135F; - x = x * 1.4142135F; - - (void)QXSemaphore_signal(&l_sema); /* signal Thread2 */ - - QXThread_delay(10U); /* BLOCK while holding a mutex */ - - QXMutex_unlock(&l_mutex); - } - - QXMutex_unlock(&l_mutex); - BSP_ledOff(); - - QXThread_delay(BSP_TICKS_PER_SEC/7); /* BLOCK */ - - /* publish to thread2 */ - //QACTIVE_PUBLISH(Q_NEW(QEvt, TEST_SIG), &l_test1.super); - - /* test TLS */ - lib_fun(1U); - } -} - -/*..........................................................................*/ -void Test1_ctor(void) { - QXThread_ctor(&l_test1, &Thread1_run, 0U); -} - -/*..........................................................................*/ -static void Thread2_run(QXThread * const me) { - - QS_OBJ_DICTIONARY(&l_test2); - QS_OBJ_DICTIONARY(&l_test2.timeEvt); - QS_OBJ_DICTIONARY(&l_sema); - - /* initialize the semaphore before using it - * NOTE: the semaphore is initialized in the highest-priority thread - * that uses it. Alternatively, the semaphore can be initialized - * before any thread runs. - */ - QXSemaphore_init(&l_sema, - 0U, /* count==0 (signaling semaphore) */ - 1U); /* max_count==1 (binary semaphore) */ - - /* initialize the mutex before using it - * NOTE: Here the mutex is initialized in the highest-priority thread - * that uses it. Alternatively, the mutex can be initialized - * before any thread runs. - */ - //QXMutex_init(&l_mutex, 0U); /* priority-ceiling NOT used */ - QXMutex_init(&l_mutex, N_PHILO + 6U); /* QF-prio./pre-thre. */ - - me->super.thread = &l_tls2; /* initialize the TLS for Thread2 */ - - /* subscribe to the test signal */ - QActive_subscribe(&me->super, TEST_SIG); - - for (;;) { - /* wait on a semaphore (BLOCK indefinitely) */ - QXSemaphore_wait(&l_sema, QXTHREAD_NO_TIMEOUT); - - QXMutex_lock(&l_mutex, QXTHREAD_NO_TIMEOUT); /* lock the mutex */ - QXThread_delay(1U); /* wait more (BLOCK) */ - QXMutex_unlock(&l_mutex); - - /* test TLS */ - lib_fun(2U); - } -} - -/*..........................................................................*/ -void Test2_ctor(void) { - QXThread_ctor(&l_test2, &Thread2_run, 0U); -} diff --git a/examples/arm-cm/dpp_efm32-slstk3401a/qxk/xthread1.c b/examples/arm-cm/dpp_efm32-slstk3401a/qxk/xthread1.c new file mode 100644 index 00000000..066b983d --- /dev/null +++ b/examples/arm-cm/dpp_efm32-slstk3401a/qxk/xthread1.c @@ -0,0 +1,101 @@ +//============================================================================ +// QXThread example +// Last updated for version 7.3.0 +// Last updated on 2023-08-12 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. +// +// This program is open source software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Alternatively, this program may be distributed and modified under the +// terms of Quantum Leaps commercial licenses, which expressly supersede +// the GNU General Public License and are specifically designed for +// licensees interested in retaining the proprietary status of their code. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Contact information: +// +// +//============================================================================ +#include "qpc.h" // QP/C real-time embedded framework +#include "dpp.h" // DPP Application interface +#include "bsp.h" // Board Support Package + +//---------------------------------------------------------------------------- +//Q_DEFINE_THIS_FILE + +//............................................................................ +typedef struct XThread1 { +// protected: + QXThread super; + +// private: + // NOTE: data needed by this thread should be members of + // the thread class. That way they are in the memory region + // accessible from this thread. + uint8_t foo; + +// public: +} XThread1; + +// private: +static void XThread1_run(QXThread * const thr); +extern XThread1 XThread1_inst; + +//............................................................................ +QXThread * const TH_XThread1 = &XThread1_inst.super; + +//............................................................................ +void XThread1_ctor(void) { + XThread1 *me = &XThread1_inst; + QXThread_ctor(&me->super, &XThread1_run, 0U); +} + +//............................................................................ +XThread1 XThread1_inst; + +//............................................................................ +static void XThread1_run(QXThread * const thr) { + QS_OBJ_DICTIONARY(TH_XThread1); + QS_OBJ_DICTIONARY(&TH_XThread1->timeEvt); + + // downcast the generic thr pointer to the specific thread + XThread1 *me = (XThread1 *)thr; + + // subscribe to the EAT signal (from the application) + QActive_subscribe(&me->super.super, EAT_SIG); + + for (;;) { + QEvt const *e = QXThread_queueGet(BSP_TICKS_PER_SEC/4U); + if (e) { + QXSemaphore_signal(&TH_sema); // signal Thread2 + QF_gc(e); // must explicitly recycle the received event! + } + + QXMutex_lock(&TH_mutex, QXTHREAD_NO_TIMEOUT); // lock the mutex + BSP_ledOn(); + if (QXMutex_tryLock(&TH_mutex)) { // exercise the mutex + // some floating point code to exercise the VFP... + float volatile x = 1.4142135F; + x = x * 1.4142135F; + QXThread_delay(10U); // BLOCK while holding a mutex + QXMutex_unlock(&TH_mutex); + } + QXMutex_unlock(&TH_mutex); + BSP_ledOff(); + } +} diff --git a/examples/arm-cm/dpp_efm32-slstk3401a/qxk/xthread2.c b/examples/arm-cm/dpp_efm32-slstk3401a/qxk/xthread2.c new file mode 100644 index 00000000..1caad4fa --- /dev/null +++ b/examples/arm-cm/dpp_efm32-slstk3401a/qxk/xthread2.c @@ -0,0 +1,108 @@ +//============================================================================ +// QXThread example +// Last updated for version 7.3.0 +// Last updated on 2023-08-12 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. +// +// This program is open source software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Alternatively, this program may be distributed and modified under the +// terms of Quantum Leaps commercial licenses, which expressly supersede +// the GNU General Public License and are specifically designed for +// licensees interested in retaining the proprietary status of their code. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Contact information: +// +// +//============================================================================ +#include "qpc.h" // QP/C real-time embedded framework +#include "dpp.h" // DPP Application interface +#include "bsp.h" // Board Support Package + +//---------------------------------------------------------------------------- +//Q_DEFINE_THIS_FILE + +//---------------------------------------------------------------------------- +QXSemaphore TH_sema; +QXMutex TH_mutex; + +//---------------------------------------------------------------------------- +typedef struct XThread2 { +// protected: + QXThread super; + +// private: + // NOTE: data needed by this thread should be members of + // the thread class. That way they are in the memory region + // accessible from this thread. + uint8_t foo; + +// public: +} XThread2; + +// private: +static void XThread2_run(QXThread * const thr); +extern XThread2 XThread2_inst; + +//............................................................................ +QXThread * const TH_XThread2 = &XThread2_inst.super; + +//............................................................................ +void XThread2_ctor(void) { + XThread2 *me = &XThread2_inst; + QXThread_ctor(&me->super, &XThread2_run, 0U); +} + +//............................................................................ +XThread2 XThread2_inst; + +//............................................................................ +static void XThread2_run(QXThread * const thr) { + QS_OBJ_DICTIONARY(TH_XThread2); + QS_OBJ_DICTIONARY(&TH_XThread2->timeEvt); + QS_OBJ_DICTIONARY(&TH_sema); + QS_OBJ_DICTIONARY(&TH_mutex); + + // downcast the generic thr pointer to the specific thread + //XThread2 *me = (XThread2 *)thr; + + // initialize the semaphore before using it + // NOTE: Here the semaphore is initialized in the highest-priority thread + // that uses it. Alternatively, the semaphore can be initialized + // before any thread runs. + QXSemaphore_init(&TH_sema, + 0U, // count==0 (signaling semaphore) + 1U); // max_count==1 (binary semaphore) + + // initialize the mutex before using it + // NOTE: Here the mutex is initialized in the highest-priority thread + // that uses it. Alternatively, the mutex can be initialized + // before any thread runs. + QXMutex_init(&TH_mutex, N_PHILO + 6U); // priority-ceiling mutex + //QXMutex_init(&TH_mutex, 0U); // alternatively: priority-ceiling NOT used + + for (;;) { + // wait on a semaphore (BLOCK indefinitely) + QXSemaphore_wait(&TH_sema, QXTHREAD_NO_TIMEOUT); + + QXMutex_lock(&TH_mutex, QXTHREAD_NO_TIMEOUT); // lock the mutex + QXThread_delay(5U); // wait more (BLOCK) + QXMutex_unlock(&TH_mutex); + } +} diff --git a/examples/arm-cm/dpp_efm32-slstk3401a/table.c b/examples/arm-cm/dpp_efm32-slstk3401a/table.c index d40cae43..c3ae02f0 100644 --- a/examples/arm-cm/dpp_efm32-slstk3401a/table.c +++ b/examples/arm-cm/dpp_efm32-slstk3401a/table.c @@ -1,118 +1,130 @@ -/*$file${.::table.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* -* Model: dpp.qm -* File: ${.::table.c} -* -* This code has been generated by QM 5.2.4 . -* DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. -* -* SPDX-License-Identifier: GPL-3.0-or-later -* -* This generated code is open source software: you can redistribute it under -* the terms of the GNU General Public License as published by the Free -* Software Foundation. -* -* This code is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -* more details. -* -* NOTE: -* Alternatively, this generated code may be distributed under the terms -* of Quantum Leaps commercial licenses, which expressly supersede the GNU -* General Public License and are specifically designed for licensees -* interested in retaining the proprietary status of their code. -* -* Contact information: -* -* -*/ -/*$endhead${.::table.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -#include "qpc.h" -#include "dpp.h" -#include "bsp.h" +//$file${.::table.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// +// Model: dpp.qm +// File: ${.::table.c} +// +// This code has been generated by QM 5.3.0 . +// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. +// +// SPDX-License-Identifier: GPL-3.0-or-later +// +// This generated code is open source software: you can redistribute it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation. +// +// This code is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// NOTE: +// Alternatively, this generated code may be distributed under the terms +// of Quantum Leaps commercial licenses, which expressly supersede the GNU +// General Public License and are specifically designed for licensees +// interested in retaining the proprietary status of their code. +// +// Contact information: +// +// +// +//$endhead${.::table.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +#include "qpc.h" // QP/C real-time embedded framework +#include "dpp.h" // DPP Application interface +#include "bsp.h" // Board Support Package -Q_DEFINE_THIS_MODULE("table") +//$declare${AOs::Table} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/* Active object class -----------------------------------------------------*/ -/*$declare${AOs::Table} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${AOs::Table} ............................................................*/ +//${AOs::Table} .............................................................. typedef struct Table { -/* protected: */ +// protected: QActive super; -/* public: */ - -/* private: */ +// private: uint8_t fork[N_PHILO]; - uint8_t isHungry[N_PHILO]; + bool isHungry[N_PHILO]; + +// public: } Table; + extern Table Table_inst; -/* protected: */ +// protected: static QState Table_initial(Table * const me, void const * const par); static QState Table_active(Table * const me, QEvt const * const e); static QState Table_serving(Table * const me, QEvt const * const e); static QState Table_paused(Table * const me, QEvt const * const e); -/*$enddecl${AOs::Table} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$enddecl${AOs::Table} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -#define RIGHT(n_) ((uint8_t)(((n_) + (N_PHILO - 1U)) % N_PHILO)) -#define LEFT(n_) ((uint8_t)(((n_) + 1U) % N_PHILO)) -#define FREE ((uint8_t)0) -#define USED ((uint8_t)1) +//---------------------------------------------------------------------------- +Q_DEFINE_THIS_FILE -/* Global-scope objects ----------------------------------------------------*/ -/*$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* Check for the minimum required QP version */ -#if (QP_VERSION < 700U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) -#error qpc version 7.0.0 or higher required +// helper function to provide the RIGHT neighbor of a Philo[n] +static inline uint8_t right(uint8_t const n) { + return (uint8_t)((n + (N_PHILO - 1U)) % N_PHILO); +} + +// helper function to provide the LEFT neighbor of a Philo[n] +static inline uint8_t left(uint8_t const n) { + return (uint8_t)((n + 1U) % N_PHILO); +} + +#define FREE ((uint8_t)0U) +#define USED ((uint8_t)1U) + +#define THINKING "thinking" +#define HUNGRY "hungry " +#define EATING "eating " + +//---------------------------------------------------------------------------- + +//$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// Check for the minimum required QP version +#if (QP_VERSION < 730U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) +#error qpc version 7.3.0 or higher required #endif -/*$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -/*$define${AOs::AO_Table} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//$define${Shared::Table_ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/*${AOs::AO_Table} .........................................................*/ -QActive * const AO_Table = &Table_inst.super; -/*$enddef${AOs::AO_Table} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ - -/*..........................................................................*/ -/*$define${AOs::Table_ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${AOs::Table_ctor} .......................................................*/ +//${Shared::Table_ctor} ...................................................... void Table_ctor(void) { - Table *me = &Table_inst; - + Table * const me = &Table_inst; QActive_ctor(&me->super, Q_STATE_CAST(&Table_initial)); - for (uint8_t n = 0U; n < N_PHILO; ++n) { me->fork[n] = FREE; - me->isHungry[n] = 0U; + me->isHungry[n] = false; } } -/*$enddef${AOs::Table_ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*$define${AOs::Table} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//$enddef${Shared::Table_ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +//$define${Shared::AO_Table} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/*${AOs::Table} ............................................................*/ +//${Shared::AO_Table} ........................................................ +QActive * const AO_Table = &Table_inst.super; +//$enddef${Shared::AO_Table} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +//$define${AOs::Table} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${AOs::Table} .............................................................. Table Table_inst; -/*${AOs::Table::SM} ........................................................*/ +//${AOs::Table::SM} .......................................................... static QState Table_initial(Table * const me, void const * const par) { - /*${AOs::Table::SM::initial} */ - (void)par; /* unused parameter */ + //${AOs::Table::SM::initial} + Q_UNUSED_PAR(par); - QS_OBJ_DICTIONARY(&Table_inst); + #ifdef Q_SPY + Table *Table_inst = me; + QS_OBJ_DICTIONARY(Table_inst); + #endif QActive_subscribe(&me->super, DONE_SIG); QActive_subscribe(&me->super, PAUSE_SIG); QActive_subscribe(&me->super, SERVE_SIG); - QActive_subscribe(&me->super, EAT_SIG); //??? QActive_subscribe(&me->super, TEST_SIG); for (uint8_t n = 0U; n < N_PHILO; ++n) { me->fork[n] = FREE; - me->isHungry[n] = 0U; - BSP_displayPhilStat(n, "thinking"); + me->isHungry[n] = false; + BSP_displayPhilStat(n, THINKING); } QS_FUN_DICTIONARY(&Table_active); @@ -122,13 +134,18 @@ static QState Table_initial(Table * const me, void const * const par) { return Q_TRAN(&Table_serving); } -/*${AOs::Table::SM::active} ................................................*/ +//${AOs::Table::SM::active} .................................................. static QState Table_active(Table * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${AOs::Table::SM::active::EAT} */ + //${AOs::Table::SM::active::TEST} + case TEST_SIG: { + status_ = Q_HANDLED(); + break; + } + //${AOs::Table::SM::active::EAT} case EAT_SIG: { - //???Q_ERROR_ID(60); + Q_ERROR(); status_ = Q_HANDLED(); break; } @@ -140,102 +157,119 @@ static QState Table_active(Table * const me, QEvt const * const e) { return status_; } -/*${AOs::Table::SM::active::serving} .......................................*/ +//${AOs::Table::SM::active::serving} ......................................... static QState Table_serving(Table * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${AOs::Table::SM::active::serving} */ + //${AOs::Table::SM::active::serving} case Q_ENTRY_SIG: { - uint8_t n; - for (n = 0U; n < N_PHILO; ++n) { /* give permissions to eat... */ - if ((me->isHungry[n] != 0U) - && (me->fork[LEFT(n)] == FREE) + // give permissions to eat... + for (uint8_t n = 0U; n < N_PHILO; ++n) { + if (me->isHungry[n] + && (me->fork[left(n)] == FREE) && (me->fork[n] == FREE)) { - TableEvt *te; - - me->fork[LEFT(n)] = USED; + me->fork[left(n)] = USED; me->fork[n] = USED; - te = Q_NEW(TableEvt, EAT_SIG); - te->philoNum = n; - QACTIVE_PUBLISH(&te->super, &me->super); - me->isHungry[n] = 0U; - BSP_displayPhilStat(n, "eating "); + #ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, EAT_SIG, n); + #else + TableEvt *pe = Q_NEW(TableEvt, EAT_SIG); + pe->philoId = n; + #endif + QACTIVE_PUBLISH(&pe->super, &me->super); + me->isHungry[n] = false; + BSP_displayPhilStat(n, EATING); } } status_ = Q_HANDLED(); break; } - /*${AOs::Table::SM::active::serving::HUNGRY} */ + //${AOs::Table::SM::active::serving::HUNGRY} case HUNGRY_SIG: { - uint8_t n, m; + uint8_t n = Q_EVT_CAST(TableEvt)->philoId; - n = Q_EVT_CAST(TableEvt)->philoNum; - /* phil ID must be in range and he must be not hungry */ - Q_ASSERT_ID(40, (n < N_PHILO) && (me->isHungry[n] == 0U)); + // phil ID must be in range and he must be not hungry + Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); - BSP_displayPhilStat(n, "hungry "); - m = LEFT(n); - /*${AOs::Table::SM::active::serving::HUNGRY::[bothfree]} */ + BSP_displayPhilStat(n, HUNGRY); + uint8_t m = left(n); + //${AOs::Table::SM::active::serving::HUNGRY::[bothfree]} if ((me->fork[m] == FREE) && (me->fork[n] == FREE)) { - TableEvt *pe; me->fork[m] = USED; me->fork[n] = USED; - pe = Q_NEW(TableEvt, EAT_SIG); - pe->philoNum = n; + #ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, EAT_SIG, n); + #else + TableEvt *pe = Q_NEW(TableEvt, EAT_SIG); + pe->philoId = n; + #endif QACTIVE_PUBLISH(&pe->super, &me->super); - BSP_displayPhilStat(n, "eating "); + BSP_displayPhilStat(n, EATING); status_ = Q_HANDLED(); } - /*${AOs::Table::SM::active::serving::HUNGRY::[else]} */ + //${AOs::Table::SM::active::serving::HUNGRY::[else]} else { - me->isHungry[n] = 1U; + me->isHungry[n] = true; status_ = Q_HANDLED(); } break; } - /*${AOs::Table::SM::active::serving::DONE} */ + //${AOs::Table::SM::active::serving::DONE} case DONE_SIG: { - uint8_t n, m; - TableEvt *pe; + uint8_t n = Q_EVT_CAST(TableEvt)->philoId; - n = Q_EVT_CAST(TableEvt)->philoNum; - /* phil ID must be in range and he must be not hungry */ - Q_ASSERT_ID(50, (n < N_PHILO) && (me->isHungry[n] == 0U)); + // phil ID must be in range and he must be not hungry + Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); - BSP_displayPhilStat(n, "thinking"); - m = LEFT(n); - /* both forks of Phil[n] must be used */ - Q_ASSERT_ID(51, (me->fork[n] == USED) && (me->fork[m] == USED)); + BSP_displayPhilStat(n, THINKING); + uint8_t m = left(n); + + // both forks of Phil[n] must be used + Q_ASSERT((me->fork[n] == USED) && (me->fork[m] == USED)); me->fork[m] = FREE; me->fork[n] = FREE; - m = RIGHT(n); /* check the right neighbor */ + m = right(n); // check the right neighbor - if ((me->isHungry[m] != 0U) && (me->fork[m] == FREE)) { + if (me->isHungry[m] && (me->fork[m] == FREE)) { me->fork[n] = USED; me->fork[m] = USED; - me->isHungry[m] = 0U; - pe = Q_NEW(TableEvt, EAT_SIG); - pe->philoNum = m; + me->isHungry[m] = false; + #ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, EAT_SIG, m); + #else + TableEvt *pe = Q_NEW(TableEvt, EAT_SIG); + pe->philoId = m; + #endif QACTIVE_PUBLISH(&pe->super, &me->super); - BSP_displayPhilStat(m, "eating "); + BSP_displayPhilStat(m, EATING); } - m = LEFT(n); /* check the left neighbor */ - n = LEFT(m); /* left fork of the left neighbor */ - if ((me->isHungry[m] != 0U) && (me->fork[n] == FREE)) { + m = left(n); // check the left neighbor + n = left(m); // left fork of the left neighbor + if (me->isHungry[m] && (me->fork[n] == FREE)) { me->fork[m] = USED; me->fork[n] = USED; - me->isHungry[m] = 0U; - pe = Q_NEW(TableEvt, EAT_SIG); - pe->philoNum = m; + me->isHungry[m] = false; + #ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, EAT_SIG, m); + #else + TableEvt *pe = Q_NEW(TableEvt, EAT_SIG); + pe->philoId = m; + #endif QACTIVE_PUBLISH(&pe->super, &me->super); - BSP_displayPhilStat(m, "eating "); + BSP_displayPhilStat(m, EATING); } status_ = Q_HANDLED(); break; } - /*${AOs::Table::SM::active::serving::PAUSE} */ + //${AOs::Table::SM::active::serving::EAT} + case EAT_SIG: { + Q_ERROR(); + status_ = Q_HANDLED(); + break; + } + //${AOs::Table::SM::active::serving::PAUSE} case PAUSE_SIG: { status_ = Q_TRAN(&Table_paused); break; @@ -248,49 +282,51 @@ static QState Table_serving(Table * const me, QEvt const * const e) { return status_; } -/*${AOs::Table::SM::active::paused} ........................................*/ +//${AOs::Table::SM::active::paused} .......................................... static QState Table_paused(Table * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${AOs::Table::SM::active::paused} */ + //${AOs::Table::SM::active::paused} case Q_ENTRY_SIG: { BSP_displayPaused(1U); status_ = Q_HANDLED(); break; } - /*${AOs::Table::SM::active::paused} */ + //${AOs::Table::SM::active::paused} case Q_EXIT_SIG: { BSP_displayPaused(0U); status_ = Q_HANDLED(); break; } - /*${AOs::Table::SM::active::paused::SERVE} */ + //${AOs::Table::SM::active::paused::SERVE} case SERVE_SIG: { status_ = Q_TRAN(&Table_serving); break; } - /*${AOs::Table::SM::active::paused::HUNGRY} */ + //${AOs::Table::SM::active::paused::HUNGRY} case HUNGRY_SIG: { - uint8_t n = Q_EVT_CAST(TableEvt)->philoNum; - /* philo ID must be in range and he must be not hungry */ - Q_ASSERT_ID(60, (n < N_PHILO) && (me->isHungry[n] == 0U)); - me->isHungry[n] = 1U; - BSP_displayPhilStat(n, "hungry "); + uint8_t n = Q_EVT_CAST(TableEvt)->philoId; + + // philo ID must be in range and he must be not hungry + Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); + + me->isHungry[n] = true; + BSP_displayPhilStat(n, HUNGRY); status_ = Q_HANDLED(); break; } - /*${AOs::Table::SM::active::paused::DONE} */ + //${AOs::Table::SM::active::paused::DONE} case DONE_SIG: { - uint8_t n, m; + uint8_t n = Q_EVT_CAST(TableEvt)->philoId; - n = Q_EVT_CAST(TableEvt)->philoNum; - /* phil ID must be in range and he must be not hungry */ - Q_ASSERT_ID(70, (n < N_PHILO) && (me->isHungry[n] == 0U)); + // phil ID must be in range and he must be not hungry + Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); - BSP_displayPhilStat(n, "thinking"); - m = LEFT(n); - /* both forks of Phil[n] must be used */ - Q_ASSERT_ID(71, (me->fork[n] == USED) && (me->fork[m] == USED)); + BSP_displayPhilStat(n, THINKING); + uint8_t m = left(n); + + // both forks of Phil[n] must be used + Q_ASSERT((me->fork[n] == USED) && (me->fork[m] == USED)); me->fork[m] = FREE; me->fork[n] = FREE; @@ -304,4 +340,4 @@ static QState Table_paused(Table * const me, QEvt const * const e) { } return status_; } -/*$enddef${AOs::Table} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$enddef${AOs::Table} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/examples/arm-cm/dpp_efm32-slstk3401a/win32-gui/bsp.c b/examples/arm-cm/dpp_efm32-slstk3401a/win32-gui/bsp.c deleted file mode 100644 index a17410a4..00000000 --- a/examples/arm-cm/dpp_efm32-slstk3401a/win32-gui/bsp.c +++ /dev/null @@ -1,340 +0,0 @@ -/***************************************************************************** -* Product: DPP example, Win32-GUI -* Last updated for version: 6.9.3 -* Date of the Last Update: 2021-03-03 -* -* Q u a n t u m L e a P s -* ------------------------ -* Modern Embedded Software -* -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* -* -*****************************************************************************/ -#include "qpc.h" -#include "dpp.h" -#include "bsp.h" - -#include "qwin_gui.h" /* QWIN GUI */ -#include "resource.h" /* GUI resource IDs generated by the resource editior */ - -#include "safe_std.h" /* portable "safe" / facilities */ - -Q_DEFINE_THIS_FILE - -/* local variables ---------------------------------------------------------*/ -static HINSTANCE l_hInst; /* this application instance */ -static HWND l_hWnd; /* main window handle */ -static LPSTR l_cmdLine; /* the command line string */ - -static SegmentDisplay l_philos; /* SegmentDisplay to show Philo status */ -static OwnerDrawnButton l_pauseBtn; /* owner-drawn button */ - -static unsigned l_rnd; /* random seed */ - -#ifdef Q_SPY - enum { - PHILO_STAT = QS_USER - }; - static uint8_t const l_clock_tick = 0U; -#endif - -/* Local functions ---------------------------------------------------------*/ -static LRESULT CALLBACK WndProc(HWND hWnd, UINT iMsg, - WPARAM wParam, LPARAM lParam); - -/*..........................................................................*/ -/* thread function for running the application main_gui() */ -static DWORD WINAPI appThread(LPVOID par) { - (void)par; /* unused parameter */ - return (DWORD)main_gui(); /* run the QF application */ -} - -/*--------------------------------------------------------------------------*/ -int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, - LPSTR cmdLine, int iCmdShow) -{ - HWND hWnd; - MSG msg; - - (void)hPrevInst; /* unused parameter */ - - l_hInst = hInst; /* save the application instance */ - l_cmdLine = cmdLine; /* save the command line string */ - - //AllocConsole(); - - /* create the main custom dialog window */ - hWnd = CreateCustDialog(hInst, IDD_APPLICATION, NULL, - &WndProc, "MY_CLASS"); - ShowWindow(hWnd, iCmdShow); /* show the main window */ - - /* enter the message loop... */ - while (GetMessage(&msg, NULL, 0, 0)) { - TranslateMessage(&msg); - DispatchMessage(&msg); - } - - //FreeConsole(); - BSP_terminate(0); - - return msg.wParam; -} - -/*..........................................................................*/ -static LRESULT CALLBACK WndProc(HWND hWnd, UINT iMsg, - WPARAM wParam, LPARAM lParam) -{ - switch (iMsg) { - - /* Perform initialization upon cration of the main dialog window - * NOTE: Any child-windows are NOT created yet at this time, so - * the GetDlgItem() function can't be used (it will return NULL). - */ - case WM_CREATE: { - l_hWnd = hWnd; /* save the window handle */ - - /* initialize the owner-drawn buttons... - * NOTE: must be done *before* the first drawing of the buttons, - * so WM_INITDIALOG is too late. - */ - OwnerDrawnButton_init(&l_pauseBtn, IDC_PAUSE, - LoadBitmap(l_hInst, MAKEINTRESOURCE(IDB_BTN_UP)), - LoadBitmap(l_hInst, MAKEINTRESOURCE(IDB_BTN_DWN)), - LoadCursor(NULL, IDC_HAND)); - return 0; - } - - /* Perform initialization after all child windows have been created */ - case WM_INITDIALOG: { - - SegmentDisplay_init(&l_philos, - N_PHILO, /* N_PHILO "segments" for the Philos */ - 3U); /* 3 bitmaps (for thinking/hungry/eating) */ - SegmentDisplay_initSegment(&l_philos, 0U, IDC_PHILO_0); - SegmentDisplay_initSegment(&l_philos, 1U, IDC_PHILO_1); - SegmentDisplay_initSegment(&l_philos, 2U, IDC_PHILO_2); - SegmentDisplay_initSegment(&l_philos, 3U, IDC_PHILO_3); - SegmentDisplay_initSegment(&l_philos, 4U, IDC_PHILO_4); - SegmentDisplay_initBitmap(&l_philos, - 0U, LoadBitmap(l_hInst, MAKEINTRESOURCE(IDB_THINKING))); - SegmentDisplay_initBitmap(&l_philos, - 1U, LoadBitmap(l_hInst, MAKEINTRESOURCE(IDB_HUNGRY))); - SegmentDisplay_initBitmap(&l_philos, - 2U, LoadBitmap(l_hInst, MAKEINTRESOURCE(IDB_EATING))); - - /* --> QP: spawn the application thread to run main_gui() */ - Q_ALLEGE(CreateThread(NULL, 0, &appThread, NULL, 0, NULL) - != (HANDLE)0); - - SetDlgItemTextA(hWnd, IDC_EDIT1, "Edit1"); - SetDlgItemTextA(hWnd, IDC_EDIT2, "Edit2"); - return 0; - } - - case WM_DESTROY: { - PostQuitMessage(0); - return 0; - } - - /* commands from child controls and menus... */ - case WM_COMMAND: { - switch (wParam) { - case IDOK: - case IDCANCEL: { - PostQuitMessage(0); - break; - } - case IDC_PAUSE: { /* owner-drawn button(s) */ - SetFocus(hWnd); - break; - } - case IDC_BUTTON1: { /* regular button */ - char buf[32]; - GetDlgItemTextA(hWnd, IDC_EDIT1, buf, sizeof(buf)); - SetDlgItemTextA(hWnd, IDC_EDIT2, buf); - break; - } - } - return 0; - } - - /* drawing of owner-drawn buttons... */ - case WM_DRAWITEM: { - LPDRAWITEMSTRUCT pdis = (LPDRAWITEMSTRUCT)lParam; - switch (pdis->CtlID) { - case IDC_PAUSE: { /* PAUSE owner-drawn button */ - switch (OwnerDrawnButton_draw(&l_pauseBtn,pdis)) { - case BTN_DEPRESSED: { - static QEvt const pe = { PAUSE_SIG, 0U, 0U }; - QACTIVE_POST(AO_Table, &pe, (void *)0); - break; - } - case BTN_RELEASED: { - static QEvt const se = { SERVE_SIG, 0U, 0U }; - QACTIVE_POST(AO_Table, &se, (void *)0); - break; - } - default: { - break; - } - } - break; - } - } - return 0; - } - - /* mouse input... */ - case WM_MOUSEWHEEL: { - return 0; - } - - /* keyboard input... */ - case WM_KEYDOWN: { - return 0; - } - } - return DefWindowProc(hWnd, iMsg, wParam, lParam) ; -} -/*..........................................................................*/ -void QF_onStartup(void) { - QF_setTickRate(BSP_TICKS_PER_SEC, 30); /* set the desired tick rate */ -} -/*..........................................................................*/ -void QF_onCleanup(void) { -} -/*..........................................................................*/ -void QF_onClockTick(void) { - QTIMEEVT_TICK_X(0U, &l_clock_tick); /* perform the QF clock tick processing */ - - QS_RX_INPUT(); /* handle the QS-RX input */ - QS_OUTPUT(); /* handle the QS output */ -} - -/*..........................................................................*/ -Q_NORETURN Q_onAssert(char const * const module, int_t const loc) { - char message[80]; - QF_stop(); /* stop ticking */ - - QS_ASSERTION(module, loc, 10000U); /* report assertion to QS */ - SNPRINTF_S(message, Q_DIM(message) - 1U, - "Assertion failed in module %s location %d", module, loc); - MessageBox(l_hWnd, message, "!!! ASSERTION !!!", - MB_OK | MB_ICONEXCLAMATION | MB_APPLMODAL); - PostQuitMessage(-1); -} - -/*..........................................................................*/ -void BSP_init(void) { - if (QS_INIT(l_cmdLine) == 0U) { /* QS initialization failed? */ - MessageBox(l_hWnd, - "Cannot connect to QSPY via TCP/IP\n" - "Please make sure that 'qspy -t' is running", - "QS_INIT() Error", - MB_OK | MB_ICONEXCLAMATION | MB_APPLMODAL); - } - - /* send the QS dictionaries... */ - QS_OBJ_DICTIONARY(&l_clock_tick); - QS_USR_DICTIONARY(PHILO_STAT); - - /* setup the QS filters... */ - QS_GLB_FILTER(QS_ALL_RECORDS); - QS_GLB_FILTER(-QS_QF_TICK); -} -/*..........................................................................*/ -void BSP_terminate(int16_t result) { - QF_stop(); /* stop the main QF application */ - - /* cleanup all QWIN resources... */ - OwnerDrawnButton_xtor(&l_pauseBtn); /* cleanup the l_pauseBtn resources */ - SegmentDisplay_xtor(&l_philos); /* cleanup the l_philos resources */ - - /* end the main dialog */ - EndDialog(l_hWnd, result); -} -/*..........................................................................*/ -void BSP_displayPhilStat(uint8_t n, char const *stat) { - UINT bitmapNum = 0; - - Q_REQUIRE(n < N_PHILO); - - switch (stat[0]) { - case 't': bitmapNum = 0U; break; - case 'h': bitmapNum = 1U; break; - case 'e': bitmapNum = 2U; break; - default: Q_ERROR(); break; - } - /* set the "segment" # n to the bitmap # 'bitmapNum' */ - SegmentDisplay_setSegment(&l_philos, (UINT)n, bitmapNum); - - QS_BEGIN_ID(PHILO_STAT, AO_Philo[n]->prio) /* app-specific record */ - QS_U8(1, n); /* Philosopher number */ - QS_STR(stat); /* Philosopher status */ - QS_END() -} -/*..........................................................................*/ -void BSP_displayPaused(uint8_t paused) { - char buf[16]; - LoadString(l_hInst, - (paused != 0U) ? IDS_PAUSED : IDS_RUNNING, buf, Q_DIM(buf)); - SetDlgItemText(l_hWnd, IDC_PAUSED, buf); -} -/*..........................................................................*/ -uint32_t BSP_random(void) { /* a very cheap pseudo-random-number generator */ - /* "Super-Duper" Linear Congruential Generator (LCG) - * LCG(2^32, 3*7*11*13*23, 0, seed) - */ - l_rnd = l_rnd * (3U*7U*11U*13U*23U); - return l_rnd >> 8; -} -/*..........................................................................*/ -void BSP_randomSeed(uint32_t seed) { - l_rnd = seed; -} - - -/*--------------------------------------------------------------------------*/ -#ifdef Q_SPY /* define QS callbacks */ - -/*! callback function to execute user commands */ -void QS_onCommand(uint8_t cmdId, - uint32_t param1, uint32_t param2, uint32_t param3) -{ - switch (cmdId) { - case 0U: { - break; - } - default: - break; - } - - /* unused parameters */ - (void)param1; - (void)param2; - (void)param3; -} - -#endif /* Q_SPY */ -/*--------------------------------------------------------------------------*/ diff --git a/examples/arm-cm/dpp_efm32-slstk3401a/win32-gui/main.c b/examples/arm-cm/dpp_efm32-slstk3401a/win32-gui/main.c deleted file mode 100644 index 4a548c0c..00000000 --- a/examples/arm-cm/dpp_efm32-slstk3401a/win32-gui/main.c +++ /dev/null @@ -1,112 +0,0 @@ -/***************************************************************************** -* Product: DPP example for Windows -* Last updated for version 7.1.3 -* Last updated on 2022-11-14 -* -* Q u a n t u m L e a P s -* ------------------------ -* Modern Embedded Software -* -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* -* -*****************************************************************************/ -#include "qpc.h" -#include "dpp.h" -#include "bsp.h" - -Q_DEFINE_THIS_FILE - -/* "fudge factor" for Windows, see NOTE1 */ -enum { WIN_FUDGE_FACTOR = 10 }; - -/*..........................................................................*/ -int main() { - static QEvt const *tableQueueSto[N_PHILO*WIN_FUDGE_FACTOR]; - static QEvt const *philoQueueSto[N_PHILO][N_PHILO*WIN_FUDGE_FACTOR]; - static QF_MPOOL_EL(TableEvt) smlPoolSto[2*N_PHILO*WIN_FUDGE_FACTOR]; - static QSubscrList subscrSto[MAX_PUB_SIG]; - uint8_t n; - - QF_init(); /* initialize the framework and the underlying RT kernel */ - BSP_init(); /* initialize the Board Support Package */ - - /* object dictionaries... */ - QS_OBJ_DICTIONARY(AO_Table); - QS_OBJ_DICTIONARY(AO_Philo[0]); - QS_OBJ_DICTIONARY(AO_Philo[1]); - QS_OBJ_DICTIONARY(AO_Philo[2]); - QS_OBJ_DICTIONARY(AO_Philo[3]); - QS_OBJ_DICTIONARY(AO_Philo[4]); - - /* initialize publish-subscribe... */ - QF_psInit(subscrSto, Q_DIM(subscrSto)); - - /* initialize event pools... */ - QF_poolInit(smlPoolSto, sizeof(smlPoolSto), sizeof(smlPoolSto[0])); - - /* start the active objects... */ - for (n = 0U; n < N_PHILO; ++n) { - Philo_ctor(n); /* instantiate all Philosopher active object */ - QACTIVE_START(AO_Philo[n], /* AO to start */ - n + 1U, /* QF-priority */ - philoQueueSto[n], /* event queue storage */ - Q_DIM(philoQueueSto[n]), /* queue length [events] */ - (void *)0, /* stack storage (not used) */ - 0U, /* size of the stack [bytes] */ - (void *)0); /* initialization param */ - } - - Table_ctor(); /* instantiate the Table active object */ - QACTIVE_START(AO_Table, /* AO to start */ - N_PHILO + 1U, /* QF-priority */ - tableQueueSto, /* event queue storage */ - Q_DIM(tableQueueSto), /* queue length [events] */ - (void *)0, /* stack storage (not used) */ - 0U, /* size of the stack [bytes] */ - (void *)0); /* initialization param */ - - return QF_run(); /* run the QF application */ -} - -/***************************************************************************** -* NOTE1: -* Windows is not a deterministic real-time system, which means that the -* system can occasionally and unexpectedly "choke and freeze" for a number -* of seconds. The designers of Windows have dealt with these sort of issues -* by massively oversizing the resources available to the applications. For -* example, the default Windows GUI message queues size is 10,000 entries, -* which can dynamically grow to an even larger number. Also the stacks of -* Win32 threads can dynamically grow to several megabytes. -* -* In contrast, the event queues, event pools, and stack size inside the -* real-time embedded (RTE) systems can be (and must be) much smaller, -* because you typically can put an upper bound on the real-time behavior -* and the resulting delays. -* -* To be able to run the unmodified applications designed originally for -* RTE systems on Windows, and to reduce the odds of resource shortages in -* this case, the generous WIN_FUDGE_FACTOR is used to oversize the -* event queues and event pools. -*/ - diff --git a/examples/arm-cm/dpp_ek-tm4c123gxl/README.md b/examples/arm-cm/dpp_ek-tm4c123gxl/README.md index 475bd03a..a2a6a4a6 100644 --- a/examples/arm-cm/dpp_ek-tm4c123gxl/README.md +++ b/examples/arm-cm/dpp_ek-tm4c123gxl/README.md @@ -1,5 +1,131 @@ -![STM32 EFM32-SLSTK3401A](../../../doxygen/images/bd_EK-TM4C123GXL.jpg) +> **NOTE** +This file is best viewed in a **markdown viewer**, such as the one built into GitHub. Markdown viewers are also available as plug-ins to popular Internet browsers. -Documentation for this example is available in the QP/C Manual at: +# DPP on EK-TM4C123GXL +This example demonstrates the [Dining Philosophers Problem (DPP) application](https://www.state-machine.com/qpc/tut_dpp.html) on the EK-TM4C123GLX board (ARM Cortex-M4F). + +

+
+EK-TM4C123GXL (TivaC LaunchPad) +

+ +## Features Demonstrated +- multiple cooperating active objects +- immutable (const) events +- mutable (dynamic) events +- time events +- direct event posting +- publish-subscribe event delivery +- cooperative QV kernel + + with ARM-KEIL toolchain + + with GNU-ARM toolchain + + with IAR-ARM toolchain +- preemptive run-to-completion QK kernel + + with ARM-KEIL toolchain + + with GNU-ARM toolchain + + with IAR-ARM toolchain +- preemptive dual-mode QXK kernel + + with ARM-KEIL toolchain + + with GNU-ARM toolchain + + with IAR-ARM toolchain + +## Build Configurations +- Debug +- Release +- Spy - software tracing with the built-in virtual COM port + +# Code Organization +``` +examples\arm-cm\dpp_ek-tm4c123gxl +| ++---qk // preemptive QK kernel +| +---gnu // GNU-ARM toolchain +| | \---targetConfigs +| | Makefile // Makefile for GNU-ARM +| +---armclang // ARM/KEIL toolchain with Compiler 6 (ARM/CLANG) +| | dpp-qk.uvprojx // uVision project +| \---iar // IAR EWARM +| dpp-qk.eww // IAR EW-ARM workspace +| +\---qv // cooperative QK kernel +| +---gnu // GNU-ARM toolchain +| | \---targetConfigs +| | Makefile // Makefile for GNU-ARM +| +---armclang // ARM/KEIL toolchain with Compiler 6 (ARM/CLANG) +| | dpp-qv.uvprojx // uVision project +| \---iar // IAR EWARM +| dpp-qv.eww // IAR EW-ARM workspace +| ++---qxk // preemptive, dual-mode QXK kernel +| +---gnu // GNU-ARM toolchain +| | \---targetConfigs +| | Makefile // Makefile for GNU-ARM +| +---armclang // ARM/KEIL toolchain with Compiler 6 (ARM/CLANG) +| | dpp-qk.uvprojx // uVision project +| \---iar // IAR EWARM +| dpp-qk.eww // IAR EW-ARM workspace +| +``` + +# Builing the example + +### GNU/ARM +- open terminal window +- change to the desired directory (either `examples\arm-cm\dpp_ek-tm4c123gxl\qk\gnu`, `examples\arm-cm\dpp_ek-tm4c123gxl\qv\gnu`, or `examples\arm-cm\dpp_ek-tm4c123gxl\qxk\gnu`) +- to build the default Debug configuration, type: + +``` +make +``` + +> **NOTE** +The `make` utility for Windows is provided in the QTools collection for Windows. + +- to build the Release configuration, type: + +``` +make CONF=rel +``` + +- to build the Spy configuration, type: + +``` +make CONF=spy +``` + + +### ARM/KEIL MDK +- Open the provided KEIL uVision project (either `dpp-qk.uvprojx`, `dpp-qv.uvprojx`, or `dpp-qxk.uvprojx`) +in Keil uVision IDE. Build/Debug/Download to the board from the IDE. +- Change the build configuration in the "Project Target" drop-down menu. + + +### IAR EWARM +- Open the provided IAR EWARM workspace (either `dpp-qk.eww`, `dpp-qv.eww`, or `dpp-qxk.eww`) +in IAR EWARM IDE. Build/Debug/Download to the board from the IDE. +- Change the build configuration in the "Project Configuration" drop-down menu. + + +# Tracing with QP/Spy +When the board is flashed with the Spy build configuration, it produces the QP/Spy software tracing output to the built-in virtual COM port of the TivaC LauchPad board. The trace is binary rather than ASCII, and therefore requires a special host-based application called QSPY. + +> **NOTE** QSPY host application is available in the QTools collection. + +To launch the QSPY host application: +- open terminal window +- type: + +``` +qspy -c COM5 +``` + +where "COM5" is an example virtual COM port enumerated by the board. You need to check the specific COM port number on your host computer using the Device Manager application, Ports (COM and LPT) section. + + +The following screen shot shows a typical output from QSPY: + +

+
+Typical QSPY output produced by the Spy build configuration +

-- https://www.state-machine.com/qpc/arm-cm_dpp_ek-tm4c123gxl.html diff --git a/examples/arm-cm/dpp_ek-tm4c123gxl/bsp.h b/examples/arm-cm/dpp_ek-tm4c123gxl/bsp.h index 0bd60efa..da73dbfd 100644 --- a/examples/arm-cm/dpp_ek-tm4c123gxl/bsp.h +++ b/examples/arm-cm/dpp_ek-tm4c123gxl/bsp.h @@ -1,54 +1,49 @@ -/***************************************************************************** -* Product: DPP example -* Last updated for version 6.7.0 -* Last updated on 2019-12-28 -* -* Q u a n t u m L e a P s -* ------------------------ -* Modern Embedded Software -* -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* -* -*****************************************************************************/ -#ifndef BSP_H -#define BSP_H +//============================================================================ +// Product: Board Support Package example +// Last Updated for Version: 7.3.0 +// Date of the Last Update: 2023-08-12 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +//============================================================================ +#ifndef BSP_H_ +#define BSP_H_ #define BSP_TICKS_PER_SEC 100U void BSP_init(void); +void BSP_start(void); void BSP_displayPaused(uint8_t paused); void BSP_displayPhilStat(uint8_t n, char const *stat); void BSP_terminate(int16_t result); -void BSP_randomSeed(uint32_t seed); /* random seed */ -uint32_t BSP_random(void); /* pseudo-random generator */ +void BSP_randomSeed(uint32_t seed); // random seed +uint32_t BSP_random(void); // pseudo-random generator -/* for testing... */ -void BSP_wait4PB1(void); void BSP_ledOn(void); void BSP_ledOff(void); -extern QActive *the_Ticker0; - -#endif /* BSP_H */ +#endif // BSP_H_ diff --git a/examples/arm-cm/dpp_ek-tm4c123gxl/dpp.h b/examples/arm-cm/dpp_ek-tm4c123gxl/dpp.h index da094c2c..e6d1557a 100644 --- a/examples/arm-cm/dpp_ek-tm4c123gxl/dpp.h +++ b/examples/arm-cm/dpp_ek-tm4c123gxl/dpp.h @@ -1,92 +1,117 @@ -/*$file${.::dpp.h} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* -* Model: dpp.qm -* File: ${.::dpp.h} -* -* This code has been generated by QM 5.2.4 . -* DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. -* -* SPDX-License-Identifier: GPL-3.0-or-later -* -* This generated code is open source software: you can redistribute it under -* the terms of the GNU General Public License as published by the Free -* Software Foundation. -* -* This code is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -* more details. -* -* NOTE: -* Alternatively, this generated code may be distributed under the terms -* of Quantum Leaps commercial licenses, which expressly supersede the GNU -* General Public License and are specifically designed for licensees -* interested in retaining the proprietary status of their code. -* -* Contact information: -* -* -*/ -/*$endhead${.::dpp.h} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -#ifndef DPP_H -#define DPP_H +//$file${.::dpp.h} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// +// Model: dpp.qm +// File: ${.::dpp.h} +// +// This code has been generated by QM 5.3.0 . +// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. +// +// SPDX-License-Identifier: GPL-3.0-or-later +// +// This generated code is open source software: you can redistribute it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation. +// +// This code is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// NOTE: +// Alternatively, this generated code may be distributed under the terms +// of Quantum Leaps commercial licenses, which expressly supersede the GNU +// General Public License and are specifically designed for licensees +// interested in retaining the proprietary status of their code. +// +// Contact information: +// +// +// +//$endhead${.::dpp.h} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +#ifndef DPP_H_ +#define DPP_H_ -enum DPPSignals { - EAT_SIG = Q_USER_SIG, /* published by Table to let a philosopher eat */ - DONE_SIG, /* published by Philosopher when done eating */ - PAUSE_SIG, /* published by BSP to pause serving forks */ - SERVE_SIG, /* published by BSP to serve re-start serving forks */ - TEST_SIG, /* published by BSP to test the application */ - MAX_PUB_SIG, /* the last published signal */ +//$declare${Shared} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv - HUNGRY_SIG, /* posted direclty to Table from hungry Philo */ - TIMEOUT_SIG, /* used by Philosophers for time events */ - MAX_SIG /* the last signal */ +//${Shared::AppSignals} ...................................................... +enum AppSignals { + EAT_SIG = Q_USER_SIG, // published by Table to let a Philo eat + DONE_SIG, // published by Philo when done eating + PAUSE_SIG, // published by BSP to pause the application + SERVE_SIG, // published by BSP to serve re-start serving forks + TEST_SIG, // published by BSP to test the application + MAX_PUB_SIG, // the last published signal + + TIMEOUT_SIG, // posted by time event to Philo + HUNGRY_SIG, // posted by hungry Philo to Table + MAX_SIG // the last signal }; -/*$declare${Events::TableEvt} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//${Shared::produce_sig_dict} ................................................ +#ifdef Q_SPY +static inline void produce_sig_dict(void) { + QS_SIG_DICTIONARY(EAT_SIG, (void *)0); + QS_SIG_DICTIONARY(DONE_SIG, (void *)0); + QS_SIG_DICTIONARY(PAUSE_SIG, (void *)0); + QS_SIG_DICTIONARY(SERVE_SIG, (void *)0); + QS_SIG_DICTIONARY(TEST_SIG, (void *)0); -/*${Events::TableEvt} ......................................................*/ + QS_SIG_DICTIONARY(TIMEOUT_SIG, (void *)0); + QS_SIG_DICTIONARY(HUNGRY_SIG, (void *)0); +} +#endif // def Q_SPY + +//${Shared::N_PHILO} ......................................................... +#define N_PHILO ((uint8_t)5U) + +//${Shared::TableEvt} ........................................................ typedef struct { -/* protected: */ +// protected: QEvt super; -/* public: */ - uint8_t philoNum; +// public: + uint8_t philoId; } TableEvt; -/*$enddecl${Events::TableEvt} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/* number of philosophers */ -#define N_PHILO ((uint8_t)5) +// public: -/*$declare${AOs::Philo_ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +#ifdef QEVT_DYN_CTOR +static inline TableEvt * TableEvt_ctor(TableEvt * const me, + uint8_t id) +{ + if (me != (TableEvt *)0) { + // don't call QEvt_ctor() because the initialization of all + // QEvt attributes is already done in QF_QF_newX_() + me->philoId = id; + } + return me; +} +#endif // def QEVT_DYN_CTOR -/*${AOs::Philo_ctor} .......................................................*/ -void Philo_ctor(void); -/*$enddecl${AOs::Philo_ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*$declare${AOs::AO_Philo[N_PHILO]} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${AOs::AO_Philo[N_PHILO]} ................................................*/ +//${Shared::AO_Philo[N_PHILO]} ............................................... extern QActive * const AO_Philo[N_PHILO]; -/*$enddecl${AOs::AO_Philo[N_PHILO]} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*$declare${AOs::Table_ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//${Shared::Philo_ctor} ...................................................... +void Philo_ctor(uint_fast8_t const id); -/*${AOs::Table_ctor} .......................................................*/ -void Table_ctor(void); -/*$enddecl${AOs::Table_ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*$declare${AOs::AO_Table} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${AOs::AO_Table} .........................................................*/ +//${Shared::AO_Table} ........................................................ extern QActive * const AO_Table; -/*$enddecl${AOs::AO_Table} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -#ifdef QP_INC_QXK_H_ - void Test1_ctor(void); - extern QXThread * const XT_Test1; - void Test2_ctor(void); - extern QXThread * const XT_Test2; -#endif /* QP_INC_QXK_H_ */ +//${Shared::Table_ctor} ...................................................... +void Table_ctor(void); +//$enddecl${Shared} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -#endif /* DPP_H */ +#ifdef QXK_H_ +extern QXThread * const TH_XThread1; +void XThread1_ctor(void); + +extern QXThread * const TH_XThread2; +void XThread2_ctor(void); + +extern QXSemaphore TH_sema; +extern QXMutex TH_mutex; + +#endif // QXK_H_ + +#endif // DPP_H_ diff --git a/examples/arm-cm/dpp_ek-tm4c123gxl/dpp.qm b/examples/arm-cm/dpp_ek-tm4c123gxl/dpp.qm index e11cfd46..ac9f2bc9 100644 --- a/examples/arm-cm/dpp_ek-tm4c123gxl/dpp.qm +++ b/examples/arm-cm/dpp_ek-tm4c123gxl/dpp.qm @@ -1,186 +1,242 @@ - + Dining Philosopher Problem example - - - + + + + + { + EAT_SIG = Q_USER_SIG, // published by Table to let a Philo eat + DONE_SIG, // published by Philo when done eating + PAUSE_SIG, // published by BSP to pause the application + SERVE_SIG, // published by BSP to serve re-start serving forks + TEST_SIG, // published by BSP to test the application + MAX_PUB_SIG, // the last published signal + + TIMEOUT_SIG, // posted by time event to Philo + HUNGRY_SIG, // posted by hungry Philo to Table + MAX_SIG // the last signal +}; + + + + QS_SIG_DICTIONARY(EAT_SIG, (void *)0); +QS_SIG_DICTIONARY(DONE_SIG, (void *)0); +QS_SIG_DICTIONARY(PAUSE_SIG, (void *)0); +QS_SIG_DICTIONARY(SERVE_SIG, (void *)0); +QS_SIG_DICTIONARY(TEST_SIG, (void *)0); + +QS_SIG_DICTIONARY(TIMEOUT_SIG, (void *)0); +QS_SIG_DICTIONARY(HUNGRY_SIG, (void *)0); + + + + ((uint8_t)5U) + + - - + + + + + + + if (me != (TableEvt *)0) { + // don't call QEvt_ctor() because the initialization of all + // QEvt attributes is already done in QF_QF_newX_() + me->philoId = id; +} +return me; + + + + = { + &Philo_inst[0].super, + &Philo_inst[1].super, + &Philo_inst[2].super, + &Philo_inst[3].super, + &Philo_inst[4].super +}; + + + + + + Philo * const me = &Philo_inst[id]; +QActive_ctor(&me->super, Q_STATE_CAST(&Philo_initial)); +QTimeEvt_ctorX(&me->timeEvt, &me->super, TIMEOUT_SIG, 0U), +me->id = (uint8_t)id; + + + + = &Table_inst.super; + + + + Table * const me = &Table_inst; +QActive_ctor(&me->super, Q_STATE_CAST(&Table_initial)); +for (uint8_t n = 0U; n < N_PHILO; ++n) { + me->fork[n] = FREE; + me->isHungry[n] = false; +} + - - - The array of static insts of the Philo class (Singleton pattern) - + The Philo AO and the N_PHILO instances + + + + - + - (void)par; /* unused parameter */ + Q_UNUSED_PAR(par); -static bool registered = false; -if (!registered) { - registered = true; +QS_OBJ_ARR_DICTIONARY(&Philo_inst[me->id], me->id); +QS_OBJ_ARR_DICTIONARY(&Philo_inst[me->id].timeEvt, me->id); - QS_OBJ_DICTIONARY(&Philo_inst[0]); - QS_OBJ_DICTIONARY(&Philo_inst[0].timeEvt); - QS_OBJ_DICTIONARY(&Philo_inst[1]); - QS_OBJ_DICTIONARY(&Philo_inst[1].timeEvt); - QS_OBJ_DICTIONARY(&Philo_inst[2]); - QS_OBJ_DICTIONARY(&Philo_inst[2].timeEvt); - QS_OBJ_DICTIONARY(&Philo_inst[3]); - QS_OBJ_DICTIONARY(&Philo_inst[3].timeEvt); - QS_OBJ_DICTIONARY(&Philo_inst[4]); - QS_OBJ_DICTIONARY(&Philo_inst[4].timeEvt); - - QS_FUN_DICTIONARY(&Philo_initial); - QS_FUN_DICTIONARY(&Philo_thinking); - QS_FUN_DICTIONARY(&Philo_hungry); - QS_FUN_DICTIONARY(&Philo_eating); -} -QS_SIG_DICTIONARY(HUNGRY_SIG, me); /* signal for each Philos */ -QS_SIG_DICTIONARY(TIMEOUT_SIG, me); /* signal for each Philos */ - -QActive_subscribe(&me->super, (enum_t)EAT_SIG); -QActive_subscribe(&me->super, (enum_t)TEST_SIG); - +QActive_subscribe(&me->super, EAT_SIG); +QActive_subscribe(&me->super, TEST_SIG); + - QTimeEvt_armX(&me->timeEvt, THINK_TIME, 0U); + QTimeEvt_armX(&me->timeEvt, think_time(), 0U); (void)QTimeEvt_disarm(&me->timeEvt); - - + + - /* EAT or DONE must be for other Philos than this one */ -Q_ASSERT(Q_EVT_CAST(TableEvt)->philoNum != PHILO_ID(me)); - + // EAT or DONE must be for other Philos than this one +Q_ASSERT(Q_EVT_CAST(TableEvt)->philoId != me->id); + - + - + - + - TableEvt *pe = Q_NEW(TableEvt, HUNGRY_SIG); -pe->philoNum = PHILO_ID(me); -QACTIVE_POST(AO_Table, &pe->super, me); + #ifdef QEVT_DYN_CTOR +TableEvt const *pe = Q_NEW(TableEvt, HUNGRY_SIG, me->id); +#else +TableEvt *pe = Q_NEW(TableEvt, HUNGRY_SIG); +pe->philoId = me->id; +#endif +QACTIVE_POST(AO_Table, &pe->super, &me->super); - + - Q_EVT_CAST(TableEvt)->philoNum == PHILO_ID(me) - - + Q_EVT_CAST(TableEvt)->philoId == me->id + + - + - /* DONE must be for other Philos than this one */ -Q_ASSERT(Q_EVT_CAST(TableEvt)->philoNum != PHILO_ID(me)); - + // DONE must be for other Philos than this one +Q_ASSERT(Q_EVT_CAST(TableEvt)->philoId != me->id); + - + - QTimeEvt_armX(&me->timeEvt, EAT_TIME, 0U); - TableEvt *pe = Q_NEW(TableEvt, DONE_SIG); -pe->philoNum = PHILO_ID(me); + QTimeEvt_armX(&me->timeEvt, eat_time(), 0U); + (void)QTimeEvt_disarm(&me->timeEvt); + +#ifdef QEVT_DYN_CTOR +TableEvt const *pe = Q_NEW(TableEvt, DONE_SIG, me->id); +#else +TableEvt *pe = Q_NEW(TableEvt, DONE_SIG); +pe->philoId = me->id; +#endif QACTIVE_PUBLISH(&pe->super, &me->super); - - + + - /* EAT or DONE must be for other Philos than this one */ -Q_ASSERT(Q_EVT_CAST(TableEvt)->philoNum != PHILO_ID(me)); - + // EAT or DONE must be for other Philos than this one +Q_ASSERT(Q_EVT_CAST(TableEvt)->philoId != me->id); + - + - + - - - The only static inst of the Table class (Singleton pattern) - - + + + - + - uint8_t n; -(void)par; /* unused parameter */ + Q_UNUSED_PAR(par); -QS_OBJ_DICTIONARY(&Table_inst); +#ifdef Q_SPY +Table *Table_inst = me; +QS_OBJ_DICTIONARY(Table_inst); +#endif -QS_SIG_DICTIONARY(DONE_SIG, (void *)0); /* global signals */ -QS_SIG_DICTIONARY(EAT_SIG, (void *)0); -QS_SIG_DICTIONARY(PAUSE_SIG, (void *)0); -QS_SIG_DICTIONARY(SERVE_SIG, (void *)0); -QS_SIG_DICTIONARY(TEST_SIG, (void *)0); +QActive_subscribe(&me->super, DONE_SIG); +QActive_subscribe(&me->super, PAUSE_SIG); +QActive_subscribe(&me->super, SERVE_SIG); +QActive_subscribe(&me->super, TEST_SIG); -QS_SIG_DICTIONARY(HUNGRY_SIG, me); /* signal just for Table */ - -QActive_subscribe(&me->super, (enum_t)DONE_SIG); -QActive_subscribe(&me->super, (enum_t)PAUSE_SIG); -QActive_subscribe(&me->super, (enum_t)SERVE_SIG); -QActive_subscribe(&me->super, (enum_t)TEST_SIG); - -for (n = 0U; n < N_PHILO; ++n) { +for (uint8_t n = 0U; n < N_PHILO; ++n) { me->fork[n] = FREE; - me->isHungry[n] = 0U; - BSP_displayPhilStat(n, "thinking"); + me->isHungry[n] = false; + BSP_displayPhilStat(n, THINKING); } - + @@ -188,128 +244,139 @@ for (n = 0U; n < N_PHILO; ++n) { - + Q_ERROR(); - + - uint8_t n; -for (n = 0U; n < N_PHILO; ++n) { /* give permissions to eat... */ - if ((me->isHungry[n] != 0U) - && (me->fork[LEFT(n)] == FREE) + // give permissions to eat... +for (uint8_t n = 0U; n < N_PHILO; ++n) { + if (me->isHungry[n] + && (me->fork[left(n)] == FREE) && (me->fork[n] == FREE)) { - TableEvt *te; - - me->fork[LEFT(n)] = USED; + me->fork[left(n)] = USED; me->fork[n] = USED; - te = Q_NEW(TableEvt, EAT_SIG); - te->philoNum = n; - QACTIVE_PUBLISH(&te->super, &me->super); - me->isHungry[n] = 0U; - BSP_displayPhilStat(n, "eating "); +#ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, EAT_SIG, n); +#else + TableEvt *pe = Q_NEW(TableEvt, EAT_SIG); + pe->philoId = n; +#endif + QACTIVE_PUBLISH(&pe->super, &me->super); + me->isHungry[n] = false; + BSP_displayPhilStat(n, EATING); } } - uint8_t n, m; + uint8_t n = Q_EVT_CAST(TableEvt)->philoId; -n = Q_EVT_CAST(TableEvt)->philoNum; -/* phil ID must be in range and he must be not hungry */ -Q_ASSERT((n < N_PHILO) && (me->isHungry[n] == 0U)); +// phil ID must be in range and he must be not hungry +Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); -BSP_displayPhilStat(n, "hungry "); -m = LEFT(n); +BSP_displayPhilStat(n, HUNGRY); +uint8_t m = left(n); (me->fork[m] == FREE) && (me->fork[n] == FREE) - TableEvt *pe; -me->fork[m] = USED; + me->fork[m] = USED; me->fork[n] = USED; -pe = Q_NEW(TableEvt, EAT_SIG); -pe->philoNum = n; +#ifdef QEVT_DYN_CTOR +TableEvt const *pe = Q_NEW(TableEvt, EAT_SIG, n); +#else +TableEvt *pe = Q_NEW(TableEvt, EAT_SIG); +pe->philoId = n; +#endif QACTIVE_PUBLISH(&pe->super, &me->super); -BSP_displayPhilStat(n, "eating "); - +BSP_displayPhilStat(n, EATING); + else - me->isHungry[n] = 1U; - - + me->isHungry[n] = true; + + - + - uint8_t n, m; -TableEvt *pe; + uint8_t n = Q_EVT_CAST(TableEvt)->philoId; -n = Q_EVT_CAST(TableEvt)->philoNum; -/* phil ID must be in range and he must be not hungry */ -Q_ASSERT((n < N_PHILO) && (me->isHungry[n] == 0U)); +// phil ID must be in range and he must be not hungry +Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); -BSP_displayPhilStat(n, "thinking"); -m = LEFT(n); -/* both forks of Phil[n] must be used */ +BSP_displayPhilStat(n, THINKING); +uint8_t m = left(n); + +// both forks of Phil[n] must be used Q_ASSERT((me->fork[n] == USED) && (me->fork[m] == USED)); me->fork[m] = FREE; me->fork[n] = FREE; -m = RIGHT(n); /* check the right neighbor */ +m = right(n); // check the right neighbor -if ((me->isHungry[m] != 0U) && (me->fork[m] == FREE)) { +if (me->isHungry[m] && (me->fork[m] == FREE)) { me->fork[n] = USED; me->fork[m] = USED; - me->isHungry[m] = 0U; - pe = Q_NEW(TableEvt, EAT_SIG); - pe->philoNum = m; + me->isHungry[m] = false; +#ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, EAT_SIG, m); +#else + TableEvt *pe = Q_NEW(TableEvt, EAT_SIG); + pe->philoId = m; +#endif QACTIVE_PUBLISH(&pe->super, &me->super); - BSP_displayPhilStat(m, "eating "); + BSP_displayPhilStat(m, EATING); } -m = LEFT(n); /* check the left neighbor */ -n = LEFT(m); /* left fork of the left neighbor */ -if ((me->isHungry[m] != 0U) && (me->fork[n] == FREE)) { +m = left(n); // check the left neighbor +n = left(m); // left fork of the left neighbor +if (me->isHungry[m] && (me->fork[n] == FREE)) { me->fork[m] = USED; me->fork[n] = USED; - me->isHungry[m] = 0U; - pe = Q_NEW(TableEvt, EAT_SIG); - pe->philoNum = m; + me->isHungry[m] = false; +#ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, EAT_SIG, m); +#else + TableEvt *pe = Q_NEW(TableEvt, EAT_SIG); + pe->philoId = m; +#endif QACTIVE_PUBLISH(&pe->super, &me->super); - BSP_displayPhilStat(m, "eating "); + BSP_displayPhilStat(m, EATING); } - + Q_ERROR(); - + - + - + @@ -319,172 +386,140 @@ if ((me->isHungry[m] != 0U) && (me->fork[n] == FREE)) { BSP_displayPaused(0U); - + - uint8_t n = Q_EVT_CAST(TableEvt)->philoNum; -/* philo ID must be in range and he must be not hungry */ -Q_ASSERT((n < N_PHILO) && (me->isHungry[n] == 0U)); -me->isHungry[n] = 1U; -BSP_displayPhilStat(n, "hungry "); - + uint8_t n = Q_EVT_CAST(TableEvt)->philoId; + +// philo ID must be in range and he must be not hungry +Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); + +me->isHungry[n] = true; +BSP_displayPhilStat(n, HUNGRY); + - uint8_t n, m; + uint8_t n = Q_EVT_CAST(TableEvt)->philoId; -n = Q_EVT_CAST(TableEvt)->philoNum; -/* phil ID must be in range and he must be not hungry */ -Q_ASSERT((n < N_PHILO) && (me->isHungry[n] == 0U)); +// phil ID must be in range and he must be not hungry +Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); -BSP_displayPhilStat(n, "thinking"); -m = LEFT(n); -/* both forks of Phil[n] must be used */ +BSP_displayPhilStat(n, THINKING); +uint8_t m = left(n); + +// both forks of Phil[n] must be used Q_ASSERT((me->fork[n] == USED) && (me->fork[m] == USED)); me->fork[m] = FREE; me->fork[n] = FREE; - + - + - + - + - - - = { /* "opaque" pointers to Philo AO */ - &Philo_inst[0].super, - &Philo_inst[1].super, - &Philo_inst[2].super, - &Philo_inst[3].super, - &Philo_inst[4].super -}; - - - - = &Table_inst.super; /* "opaque" pointer to Table AO */ - - - - uint8_t n; -Philo *me; -for (n = 0U; n < N_PHILO; ++n) { - me = &Philo_inst[n]; - QActive_ctor(&me->super, Q_STATE_CAST(&Philo_initial)); - QTimeEvt_ctorX(&me->timeEvt, &me->super, (enum_t)TIMEOUT_SIG, 0U); -} - - - - Table *me = &Table_inst; -uint8_t n; - -QActive_ctor(&me->super, Q_STATE_CAST(&Table_initial)); - -for (n = 0U; n < N_PHILO; ++n) { - me->fork[n] = FREE; - me->isHungry[n] = 0U; -} - - #ifndef DPP_H -#define DPP_H + #ifndef DPP_H_ +#define DPP_H_ -enum DPPSignals { - EAT_SIG = Q_USER_SIG, /* published by Table to let a philosopher eat */ - DONE_SIG, /* published by Philosopher when done eating */ - PAUSE_SIG, /* published by BSP to pause serving forks */ - SERVE_SIG, /* published by BSP to serve re-start serving forks */ - TEST_SIG, /* published by BSP to test the application */ - MAX_PUB_SIG, /* the last published signal */ +$declare ${Shared} - HUNGRY_SIG, /* posted direclty to Table from hungry Philo */ - TIMEOUT_SIG, /* used by Philosophers for time events */ - MAX_SIG /* the last signal */ -}; +#ifdef QXK_H_ -$declare(Events::TableEvt) +extern QXThread * const TH_XThread1; +void XThread1_ctor(void); -/* number of philosophers */ -#define N_PHILO ((uint8_t)5) +extern QXThread * const TH_XThread2; +void XThread2_ctor(void); -$declare(AOs::Philo_ctor) -$declare(AOs::AO_Philo[N_PHILO]) +extern QXSemaphore TH_sema; +extern QXMutex TH_mutex; -$declare(AOs::Table_ctor) -$declare(AOs::AO_Table) +#endif // QXK_H_ -#ifdef QP_INC_QXK_H_ - void Test1_ctor(void); - extern QXThread * const XT_Test1; - void Test2_ctor(void); - extern QXThread * const XT_Test2; -#endif /* QP_INC_QXK_H_ */ - -#endif /* DPP_H */ - +#endif // DPP_H_ - #include "qpc.h" -#include "dpp.h" -#include "bsp.h" + #include "qpc.h" // QP/C real-time embedded framework +#include "dpp.h" // DPP Application interface +#include "bsp.h" // Board Support Package +$declare ${AOs::Philo} + +//---------------------------------------------------------------------------- Q_DEFINE_THIS_FILE -/* Active object class -----------------------------------------------------*/ -$declare${AOs::Philo} - -#define THINK_TIME \ - (QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + (BSP_TICKS_PER_SEC/2U)) -#define EAT_TIME \ - (QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + BSP_TICKS_PER_SEC) - -/* helper macro to provide the ID of Philo "me_" */ -static inline uint8_t PHILO_ID(Philo * const me) { - return (uint8_t)(me - &Philo_inst[0]); +// helper function to provide a randomized think time for Philos +static QTimeEvtCtr think_time(void); // prototype +static inline QTimeEvtCtr think_time(void) { + return (QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + + (BSP_TICKS_PER_SEC/2U)); } -$define${AOs::AO_Philo[N_PHILO]} -$define${AOs::Philo_ctor} -$define${AOs::Philo} +// helper function to provide a randomized eat time for Philos +static QTimeEvtCtr eat_time(void); // prototype +static inline QTimeEvtCtr eat_time(void) { + return (QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + + BSP_TICKS_PER_SEC); +} +//---------------------------------------------------------------------------- + +$define ${Shared::Philo_ctor} +$define ${Shared::AO_Philo[N_PHILO]} +$define ${AOs::Philo} - #include "qpc.h" -#include "dpp.h" -#include "bsp.h" + #include "qpc.h" // QP/C real-time embedded framework +#include "dpp.h" // DPP Application interface +#include "bsp.h" // Board Support Package +$declare ${AOs::Table} + +//---------------------------------------------------------------------------- Q_DEFINE_THIS_FILE -/* Active object class -----------------------------------------------------*/ -$declare${AOs::Table} +// helper function to provide the RIGHT neighbor of a Philo[n] +static inline uint8_t right(uint8_t const n) { + return (uint8_t)((n + (N_PHILO - 1U)) % N_PHILO); +} -#define RIGHT(n_) ((uint8_t)(((n_) + (N_PHILO - 1U)) % N_PHILO)) -#define LEFT(n_) ((uint8_t)(((n_) + 1U) % N_PHILO)) -#define FREE ((uint8_t)0) -#define USED ((uint8_t)1) +// helper function to provide the LEFT neighbor of a Philo[n] +static inline uint8_t left(uint8_t const n) { + return (uint8_t)((n + 1U) % N_PHILO); +} -$define${AOs::AO_Table} -$define${AOs::Table_ctor} -$define${AOs::Table} +#define FREE ((uint8_t)0U) +#define USED ((uint8_t)1U) + +#define THINKING "thinking" +#define HUNGRY "hungry " +#define EATING "eating " + +//---------------------------------------------------------------------------- + +$define ${Shared::Table_ctor} +$define ${Shared::AO_Table} +$define ${AOs::Table} diff --git a/examples/arm-cm/dpp_ek-tm4c123gxl/ek-tm4c123gxl.jpg b/examples/arm-cm/dpp_ek-tm4c123gxl/ek-tm4c123gxl.jpg new file mode 100644 index 00000000..5ed6188c Binary files /dev/null and b/examples/arm-cm/dpp_ek-tm4c123gxl/ek-tm4c123gxl.jpg differ diff --git a/examples/arm-cm/dpp_ek-tm4c123gxl/lint-plus/lin.bat b/examples/arm-cm/dpp_ek-tm4c123gxl/lint-plus/lin.bat index 0d3e52e3..3a465fa5 100644 --- a/examples/arm-cm/dpp_ek-tm4c123gxl/lint-plus/lin.bat +++ b/examples/arm-cm/dpp_ek-tm4c123gxl/lint-plus/lin.bat @@ -26,15 +26,15 @@ @setlocal :: usage of lin.bat -@echo Usage: lin [16bit] [-d...] [files...] +@echo Usage: lin [16bit] [-u...] files @echo examples: -@echo lin ..\table.c : use 32bit CPU (default) for linting ..\table.c -@echo lin 16bit -dQ_SPY ..\philo.c : use 16bit CPU and define Q_SPY for linting ..\philo.c -@echo lin ..\philo.c ..\table.c : use 32bit CPU for linting ..\philo.c and ..\table.c +@echo lin files : use 32bit CPU (default) for linting files +@echo lin 16bit -uQ_SPY files : use 16bit CPU and undefine Q_SPY for linting files @echo. :: NOTE: adjust to for your installation directory of PC-Lint-Plus -@set PCLP=C:\tools\lint-plus\windows\pclp64.exe +@set PCLP=C:\tools\lint-plus2\windows\pclp64.exe +@echo %PCLP% if NOT exist "%PCLP%" ( @echo The PC-Lint-Plus toolset not found. Please adjust lin.bat @@ -46,17 +46,16 @@ set QPC=..\..\..\.. set QPC_LINT=%QPC%\ports\lint-plus if "%1"=="16bit" ( - set LINTFLAGS=%QPC_LINT%\std.lnt -i%QPC_LINT%\16bit options.lnt %2 %3 %4 %5 %6 %7 %8 @echo 16bit CPU + set LINTFLAGS=%QPC_LINT%\std.lnt -i%QPC_LINT%\16bit options.lnt %2 %3 %4 %5 %6 %7 %8 ) else ( - set LINTFLAGS=%QPC_LINT%\std.lnt -i%QPC_LINT%\32bit options.lnt %1 %2 %3 %4 %6 %7 %8 @echo 32bit CPU (default) + set LINTFLAGS=%QPC_LINT%\std.lnt -i%QPC_LINT%\32bit options.lnt %1 %2 %3 %4 %5 %6 %7 ) :: cleanup @del *.log - :: linting ------------------------------------------------------------------- %PCLP% -os(lint_out.log) %LINTFLAGS% diff --git a/examples/arm-cm/dpp_ek-tm4c123gxl/lint-plus/options.lnt b/examples/arm-cm/dpp_ek-tm4c123gxl/lint-plus/options.lnt index f298818d..cca49829 100644 --- a/examples/arm-cm/dpp_ek-tm4c123gxl/lint-plus/options.lnt +++ b/examples/arm-cm/dpp_ek-tm4c123gxl/lint-plus/options.lnt @@ -36,19 +36,22 @@ -i%QPC_LINT%\qk // QP/C lint "port" to QK // standards -%QPC_LINT%\au-misra3.lnt // MISRA-C:2012 options -%QPC_LINT%\au-misra3-amd1.lnt // MISRA-C:2012 amendment 1 options -%QPC_LINT%\au-misra3-amd2.lnt // MISRA-C:2012 amendment 2 options -%QPC_LINT%\au-ds.lnt // Dan Saks recommendations -//-strong(AXJ) // Strong type checking +%QPC_LINT%\au-misra4.lnt // MISRA-C:2023 options +%QPC_LINT%\au-ds.lnt // Dan Saks recommendations +//-strong(AXJ) // Strong type checking // size/alignment options (included from ports/lint-plus/??bits) cpu.lnt // for the chosen CPU +// defined macros (might be undefined on command-line with -u) +-dQ_SPY +-dQ_UTEST +-dQP_API_VERSION=9999 // the latest API only + //============================================================================ // QP/C options for clients qpc.lnt // QP/C options //============================================================================ -// additional supporession rules for bulding this application +// additional suppression rules for building this application diff --git a/examples/arm-cm/dpp_ek-tm4c123gxl/main.c b/examples/arm-cm/dpp_ek-tm4c123gxl/main.c new file mode 100644 index 00000000..deac175a --- /dev/null +++ b/examples/arm-cm/dpp_ek-tm4c123gxl/main.c @@ -0,0 +1,44 @@ +//============================================================================ +// APP example +// Last updated for version 7.3.0 +// Last updated on 2023-08-09 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. +// +// This program is open source software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Alternatively, this program may be distributed and modified under the +// terms of Quantum Leaps commercial licenses, which expressly supersede +// the GNU General Public License and are specifically designed for +// licensees interested in retaining the proprietary status of their code. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Contact information: +// +// +//============================================================================ +#include "qpc.h" // QP/C real-time embedded framework +#include "dpp.h" // DPP Application interface +#include "bsp.h" // Board Support Package + +//............................................................................ +int main() { + QF_init(); // initialize the framework and the underlying RT kernel + BSP_init(); // initialize the BSP + BSP_start(); // start the AOs/Threads + return QF_run(); // run the QF application +} diff --git a/examples/arm-cm/dpp_ek-tm4c123gxl/philo.c b/examples/arm-cm/dpp_ek-tm4c123gxl/philo.c index f4f4ed4f..eb6be531 100644 --- a/examples/arm-cm/dpp_ek-tm4c123gxl/philo.c +++ b/examples/arm-cm/dpp_ek-tm4c123gxl/philo.c @@ -1,170 +1,159 @@ -/*$file${.::philo.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* -* Model: dpp.qm -* File: ${.::philo.c} -* -* This code has been generated by QM 5.2.4 . -* DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. -* -* SPDX-License-Identifier: GPL-3.0-or-later -* -* This generated code is open source software: you can redistribute it under -* the terms of the GNU General Public License as published by the Free -* Software Foundation. -* -* This code is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -* more details. -* -* NOTE: -* Alternatively, this generated code may be distributed under the terms -* of Quantum Leaps commercial licenses, which expressly supersede the GNU -* General Public License and are specifically designed for licensees -* interested in retaining the proprietary status of their code. -* -* Contact information: -* -* -*/ -/*$endhead${.::philo.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -#include "qpc.h" -#include "dpp.h" -#include "bsp.h" +//$file${.::philo.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// +// Model: dpp.qm +// File: ${.::philo.c} +// +// This code has been generated by QM 5.3.0 . +// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. +// +// SPDX-License-Identifier: GPL-3.0-or-later +// +// This generated code is open source software: you can redistribute it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation. +// +// This code is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// NOTE: +// Alternatively, this generated code may be distributed under the terms +// of Quantum Leaps commercial licenses, which expressly supersede the GNU +// General Public License and are specifically designed for licensees +// interested in retaining the proprietary status of their code. +// +// Contact information: +// +// +// +//$endhead${.::philo.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +#include "qpc.h" // QP/C real-time embedded framework +#include "dpp.h" // DPP Application interface +#include "bsp.h" // Board Support Package -Q_DEFINE_THIS_FILE +//$declare${AOs::Philo} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/* Active object class -----------------------------------------------------*/ -/*$declare${AOs::Philo} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${AOs::Philo} ............................................................*/ +//${AOs::Philo} .............................................................. typedef struct Philo { -/* protected: */ +// protected: QActive super; -/* public: */ - -/* private: */ +// private: QTimeEvt timeEvt; + uint8_t id; + +// public: } Philo; + extern Philo Philo_inst[N_PHILO]; -/* protected: */ +// protected: static QState Philo_initial(Philo * const me, void const * const par); static QState Philo_thinking(Philo * const me, QEvt const * const e); static QState Philo_hungry(Philo * const me, QEvt const * const e); static QState Philo_eating(Philo * const me, QEvt const * const e); -/*$enddecl${AOs::Philo} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$enddecl${AOs::Philo} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -#define THINK_TIME \ - (QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + (BSP_TICKS_PER_SEC/2U)) -#define EAT_TIME \ - (QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + BSP_TICKS_PER_SEC) +//---------------------------------------------------------------------------- +Q_DEFINE_THIS_FILE -/* helper macro to provide the ID of Philo "me_" */ -static inline uint8_t PHILO_ID(Philo * const me) { - return (uint8_t)(me - &Philo_inst[0]); +// helper function to provide a randomized think time for Philos +static QTimeEvtCtr think_time(void); // prototype +static inline QTimeEvtCtr think_time(void) { + return (QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + + (BSP_TICKS_PER_SEC/2U)); } -/*$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* Check for the minimum required QP version */ -#if (QP_VERSION < 700U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) -#error qpc version 7.0.0 or higher required +// helper function to provide a randomized eat time for Philos +static QTimeEvtCtr eat_time(void); // prototype +static inline QTimeEvtCtr eat_time(void) { + return (QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + + BSP_TICKS_PER_SEC); +} +//---------------------------------------------------------------------------- + +//$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// Check for the minimum required QP version +#if (QP_VERSION < 730U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) +#error qpc version 7.3.0 or higher required #endif -/*$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -/*$define${AOs::AO_Philo[N_PHILO]} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//$define${Shared::Philo_ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/*${AOs::AO_Philo[N_PHILO]} ................................................*/ -QActive * const AO_Philo[N_PHILO] = { /* "opaque" pointers to Philo AO */ +//${Shared::Philo_ctor} ...................................................... +void Philo_ctor(uint_fast8_t const id) { + Philo * const me = &Philo_inst[id]; + QActive_ctor(&me->super, Q_STATE_CAST(&Philo_initial)); + QTimeEvt_ctorX(&me->timeEvt, &me->super, TIMEOUT_SIG, 0U), + me->id = (uint8_t)id; +} +//$enddef${Shared::Philo_ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +//$define${Shared::AO_Philo[N_PHILO]} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${Shared::AO_Philo[N_PHILO]} ............................................... +QActive * const AO_Philo[N_PHILO] = { &Philo_inst[0].super, &Philo_inst[1].super, &Philo_inst[2].super, &Philo_inst[3].super, &Philo_inst[4].super }; -/*$enddef${AOs::AO_Philo[N_PHILO]} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*$define${AOs::Philo_ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//$enddef${Shared::AO_Philo[N_PHILO]} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +//$define${AOs::Philo} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/*${AOs::Philo_ctor} .......................................................*/ -void Philo_ctor(void) { - uint8_t n; - Philo *me; - for (n = 0U; n < N_PHILO; ++n) { - me = &Philo_inst[n]; - QActive_ctor(&me->super, Q_STATE_CAST(&Philo_initial)); - QTimeEvt_ctorX(&me->timeEvt, &me->super, (enum_t)TIMEOUT_SIG, 0U); - } -} -/*$enddef${AOs::Philo_ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*$define${AOs::Philo} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${AOs::Philo} ............................................................*/ +//${AOs::Philo} .............................................................. Philo Philo_inst[N_PHILO]; -/*${AOs::Philo::SM} ........................................................*/ +//${AOs::Philo::SM} .......................................................... static QState Philo_initial(Philo * const me, void const * const par) { - /*${AOs::Philo::SM::initial} */ - (void)par; /* unused parameter */ + //${AOs::Philo::SM::initial} + Q_UNUSED_PAR(par); - static bool registered = false; - if (!registered) { - registered = true; + QS_OBJ_ARR_DICTIONARY(&Philo_inst[me->id], me->id); + QS_OBJ_ARR_DICTIONARY(&Philo_inst[me->id].timeEvt, me->id); - QS_OBJ_DICTIONARY(&Philo_inst[0]); - QS_OBJ_DICTIONARY(&Philo_inst[0].timeEvt); - QS_OBJ_DICTIONARY(&Philo_inst[1]); - QS_OBJ_DICTIONARY(&Philo_inst[1].timeEvt); - QS_OBJ_DICTIONARY(&Philo_inst[2]); - QS_OBJ_DICTIONARY(&Philo_inst[2].timeEvt); - QS_OBJ_DICTIONARY(&Philo_inst[3]); - QS_OBJ_DICTIONARY(&Philo_inst[3].timeEvt); - QS_OBJ_DICTIONARY(&Philo_inst[4]); - QS_OBJ_DICTIONARY(&Philo_inst[4].timeEvt); + QActive_subscribe(&me->super, EAT_SIG); + QActive_subscribe(&me->super, TEST_SIG); - QS_FUN_DICTIONARY(&Philo_initial); - QS_FUN_DICTIONARY(&Philo_thinking); - QS_FUN_DICTIONARY(&Philo_hungry); - QS_FUN_DICTIONARY(&Philo_eating); - } - QS_SIG_DICTIONARY(HUNGRY_SIG, me); /* signal for each Philos */ - QS_SIG_DICTIONARY(TIMEOUT_SIG, me); /* signal for each Philos */ + QS_FUN_DICTIONARY(&Philo_thinking); + QS_FUN_DICTIONARY(&Philo_hungry); + QS_FUN_DICTIONARY(&Philo_eating); - QActive_subscribe(&me->super, (enum_t)EAT_SIG); - QActive_subscribe(&me->super, (enum_t)TEST_SIG); return Q_TRAN(&Philo_thinking); } -/*${AOs::Philo::SM::thinking} ..............................................*/ +//${AOs::Philo::SM::thinking} ................................................ static QState Philo_thinking(Philo * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${AOs::Philo::SM::thinking} */ + //${AOs::Philo::SM::thinking} case Q_ENTRY_SIG: { - QTimeEvt_armX(&me->timeEvt, THINK_TIME, 0U); + QTimeEvt_armX(&me->timeEvt, think_time(), 0U); status_ = Q_HANDLED(); break; } - /*${AOs::Philo::SM::thinking} */ + //${AOs::Philo::SM::thinking} case Q_EXIT_SIG: { (void)QTimeEvt_disarm(&me->timeEvt); status_ = Q_HANDLED(); break; } - /*${AOs::Philo::SM::thinking::TIMEOUT} */ + //${AOs::Philo::SM::thinking::TIMEOUT} case TIMEOUT_SIG: { status_ = Q_TRAN(&Philo_hungry); break; } - /*${AOs::Philo::SM::thinking::EAT, DONE} */ - case EAT_SIG: /* intentionally fall through */ + //${AOs::Philo::SM::thinking::EAT, DONE} + case EAT_SIG: // intentionally fall through case DONE_SIG: { - /* EAT or DONE must be for other Philos than this one */ - Q_ASSERT(Q_EVT_CAST(TableEvt)->philoNum != PHILO_ID(me)); + // EAT or DONE must be for other Philos than this one + Q_ASSERT(Q_EVT_CAST(TableEvt)->philoId != me->id); status_ = Q_HANDLED(); break; } - /*${AOs::Philo::SM::thinking::TEST} */ + //${AOs::Philo::SM::thinking::TEST} case TEST_SIG: { status_ = Q_HANDLED(); break; @@ -177,22 +166,26 @@ static QState Philo_thinking(Philo * const me, QEvt const * const e) { return status_; } -/*${AOs::Philo::SM::hungry} ................................................*/ +//${AOs::Philo::SM::hungry} .................................................. static QState Philo_hungry(Philo * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${AOs::Philo::SM::hungry} */ + //${AOs::Philo::SM::hungry} case Q_ENTRY_SIG: { + #ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, HUNGRY_SIG, me->id); + #else TableEvt *pe = Q_NEW(TableEvt, HUNGRY_SIG); - pe->philoNum = PHILO_ID(me); - QACTIVE_POST(AO_Table, &pe->super, me); + pe->philoId = me->id; + #endif + QACTIVE_POST(AO_Table, &pe->super, &me->super); status_ = Q_HANDLED(); break; } - /*${AOs::Philo::SM::hungry::EAT} */ + //${AOs::Philo::SM::hungry::EAT} case EAT_SIG: { - /*${AOs::Philo::SM::hungry::EAT::[Q_EVT_CAST(TableEvt)->philoNum=~} */ - if (Q_EVT_CAST(TableEvt)->philoNum == PHILO_ID(me)) { + //${AOs::Philo::SM::hungry::EAT::[e->philoId==me->iid]} + if (Q_EVT_CAST(TableEvt)->philoId == me->id) { status_ = Q_TRAN(&Philo_eating); } else { @@ -200,10 +193,10 @@ static QState Philo_hungry(Philo * const me, QEvt const * const e) { } break; } - /*${AOs::Philo::SM::hungry::DONE} */ + //${AOs::Philo::SM::hungry::DONE} case DONE_SIG: { - /* DONE must be for other Philos than this one */ - Q_ASSERT(Q_EVT_CAST(TableEvt)->philoNum != PHILO_ID(me)); + // DONE must be for other Philos than this one + Q_ASSERT(Q_EVT_CAST(TableEvt)->philoId != me->id); status_ = Q_HANDLED(); break; } @@ -215,34 +208,40 @@ static QState Philo_hungry(Philo * const me, QEvt const * const e) { return status_; } -/*${AOs::Philo::SM::eating} ................................................*/ +//${AOs::Philo::SM::eating} .................................................. static QState Philo_eating(Philo * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${AOs::Philo::SM::eating} */ + //${AOs::Philo::SM::eating} case Q_ENTRY_SIG: { - QTimeEvt_armX(&me->timeEvt, EAT_TIME, 0U); + QTimeEvt_armX(&me->timeEvt, eat_time(), 0U); status_ = Q_HANDLED(); break; } - /*${AOs::Philo::SM::eating} */ + //${AOs::Philo::SM::eating} case Q_EXIT_SIG: { + (void)QTimeEvt_disarm(&me->timeEvt); + + #ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, DONE_SIG, me->id); + #else TableEvt *pe = Q_NEW(TableEvt, DONE_SIG); - pe->philoNum = PHILO_ID(me); + pe->philoId = me->id; + #endif QACTIVE_PUBLISH(&pe->super, &me->super); status_ = Q_HANDLED(); break; } - /*${AOs::Philo::SM::eating::TIMEOUT} */ + //${AOs::Philo::SM::eating::TIMEOUT} case TIMEOUT_SIG: { status_ = Q_TRAN(&Philo_thinking); break; } - /*${AOs::Philo::SM::eating::EAT, DONE} */ - case EAT_SIG: /* intentionally fall through */ + //${AOs::Philo::SM::eating::EAT, DONE} + case EAT_SIG: // intentionally fall through case DONE_SIG: { - /* EAT or DONE must be for other Philos than this one */ - Q_ASSERT(Q_EVT_CAST(TableEvt)->philoNum != PHILO_ID(me)); + // EAT or DONE must be for other Philos than this one + Q_ASSERT(Q_EVT_CAST(TableEvt)->philoId != me->id); status_ = Q_HANDLED(); break; } @@ -253,4 +252,4 @@ static QState Philo_eating(Philo * const me, QEvt const * const e) { } return status_; } -/*$enddef${AOs::Philo} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$enddef${AOs::Philo} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/examples/arm-cm/dpp_ek-tm4c123gxl/qk/armclang/dpp-qk.sct b/examples/arm-cm/dpp_ek-tm4c123gxl/qk/armclang/dpp-qk.sct new file mode 100644 index 00000000..e78acfe0 --- /dev/null +++ b/examples/arm-cm/dpp_ek-tm4c123gxl/qk/armclang/dpp-qk.sct @@ -0,0 +1,23 @@ +; ************************************************************* +; *** Scatter-Loading Description File generated by uVision *** +; +; Modified by Quantum Leaps: +; added STACK as the first section in RW_STACK +; ************************************************************* + +LR_IROM1 0x00000000 0x00040000 { ; load region size_region + ER_IROM1 0x00000000 0x00040000 { ; load address = execution address + *.o (RESET, +First) + *(InRoot$$Sections) + .ANY (+RO) + .ANY (+XO) + } + + RW_STACK 0x20000000 { ; <== Quantum Leaps + * (STACK, +First) + } + RW_IRAM1 +0 (0x00008000 - 2048) { ; NOTE: assume STACK size 2048! + .ANY (+RW +ZI) + } +} + diff --git a/examples/arm-cm/dpp_ek-tm4c123gxl/qk/armclang/dpp-qk.uvoptx b/examples/arm-cm/dpp_ek-tm4c123gxl/qk/armclang/dpp-qk.uvoptx index 98fd1978..55046bb5 100644 --- a/examples/arm-cm/dpp_ek-tm4c123gxl/qk/armclang/dpp-qk.uvoptx +++ b/examples/arm-cm/dpp_ek-tm4c123gxl/qk/armclang/dpp-qk.uvoptx @@ -130,7 +130,7 @@ 0 DLGTARM - (1010=-1,-1,-1,-1,0)(1007=-1,-1,-1,-1,0)(1008=-1,-1,-1,-1,0)(1009=-1,-1,-1,-1,0)(1012=2637,758,3114,1073,1) + (1010=-1,-1,-1,-1,0)(1007=-1,-1,-1,-1,0)(1008=-1,-1,-1,-1,0)(1009=-1,-1,-1,-1,0)(1012=2637,758,3114,1073,0) 0 @@ -147,9 +147,9 @@ 0 0 - 392 + 96 1 -
1698
+
10892
0 0 0 @@ -158,30 +158,52 @@ 1 ..\bsp.c - \\dpp_qk\../bsp.c\392 + \\dpp_qk\../bsp.c\96
1 0 - 681 + 303 1 -
1270
+
0
0 0 0 0 0 - 1 + 0 ..\..\..\..\..\3rd_party\ek-tm4c123gxl\arm\startup_TM4C123GH6PM.s - \\dpp_qk\../../../../../3rd_party/ek-tm4c123gxl/arm/startup_TM4C123GH6PM.s\681 +
+ + + 0 + 1 + QK_priv_ + + + 1 + 1 + QActive_registry_ + + + 2 + 1 + Philo_inst + + + 3 + 1 + QF_priv_ + + 1 2 - 0x20000200 + 0x20000930 0 @@ -320,7 +342,7 @@ 1 0 0 - 8 + 19 @@ -583,7 +605,24 @@ -U0E2006F4 -O4622 -S4 -FO61 - + + + 0 + 0 + 92 + 1 +
0
+ 0 + 0 + 0 + 0 + 0 + 0 + ..\bsp.c + + +
+
1 @@ -718,19 +757,7 @@ 0 0 0 - ..\..\..\..\..\include\qstamp.c - qstamp.c - 0 - 0 - - - 1 - 7 - 1 - 0 - 0 - 0 - ..\main.c + ..\..\main.c main.c 0 0 @@ -745,7 +772,7 @@ 0 2 - 8 + 7 1 0 0 @@ -757,7 +784,7 @@ 2 - 9 + 8 5 0 0 @@ -769,7 +796,7 @@ 2 - 10 + 9 2 0 0 @@ -781,7 +808,7 @@ 2 - 11 + 10 5 0 0 @@ -793,7 +820,7 @@ 2 - 12 + 11 5 0 0 @@ -805,7 +832,7 @@ 2 - 13 + 12 5 0 0 @@ -817,7 +844,7 @@ 2 - 14 + 13 5 0 0 @@ -837,7 +864,7 @@ 0 3 - 15 + 14 1 0 0 @@ -849,7 +876,7 @@ 3 - 16 + 15 1 0 0 @@ -861,7 +888,7 @@ 3 - 17 + 16 1 0 0 @@ -873,7 +900,7 @@ 3 - 18 + 17 1 0 0 @@ -885,7 +912,7 @@ 3 - 19 + 18 1 0 0 @@ -897,7 +924,7 @@ 3 - 20 + 19 1 0 0 @@ -909,7 +936,7 @@ 3 - 21 + 20 1 0 0 @@ -921,7 +948,7 @@ 3 - 22 + 21 1 0 0 @@ -933,7 +960,7 @@ 3 - 23 + 22 1 0 0 @@ -945,7 +972,7 @@ 3 - 24 + 23 1 0 0 @@ -957,7 +984,7 @@ 3 - 25 + 24 1 0 0 @@ -969,7 +996,7 @@ 3 - 26 + 25 1 0 0 @@ -981,7 +1008,7 @@ 3 - 27 + 26 1 0 0 @@ -1001,7 +1028,7 @@ 0 4 - 28 + 27 1 0 0 @@ -1021,7 +1048,7 @@ 0 5 - 29 + 28 1 0 0 @@ -1033,7 +1060,7 @@ 5 - 30 + 29 1 0 0 @@ -1045,7 +1072,7 @@ 5 - 31 + 30 1 0 0 @@ -1057,7 +1084,7 @@ 5 - 32 + 31 1 0 0 @@ -1067,6 +1094,18 @@ 0 0 + + 5 + 32 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qs\qstamp.c + qstamp.c + 0 + 0 + diff --git a/examples/arm-cm/dpp_ek-tm4c123gxl/qk/armclang/dpp-qk.uvprojx b/examples/arm-cm/dpp_ek-tm4c123gxl/qk/armclang/dpp-qk.uvprojx index cb0a1607..36dd225d 100644 --- a/examples/arm-cm/dpp_ek-tm4c123gxl/qk/armclang/dpp-qk.uvprojx +++ b/examples/arm-cm/dpp_ek-tm4c123gxl/qk/armclang/dpp-qk.uvprojx @@ -337,7 +337,7 @@ 0 - __FPU_PRESENT + QP_CONFIG ..\..;..\..\..\..\..\include;..\..\..\..\..\ports\arm-cm\qk\armclang;..\..\..\..\..\3rd_party\CMSIS\Include;..\..\..\..\..\3rd_party\ek-tm4c123gxl @@ -361,7 +361,7 @@ - 1 + 0 0 0 0 @@ -370,7 +370,7 @@ 0x00000000 0x20000000 - + .\dpp-qk.sct --entry Reset_Handler @@ -408,15 +408,10 @@ 1 ..\..\table.c - - qstamp.c - 1 - ..\..\..\..\..\include\qstamp.c - main.c 1 - ..\main.c + ..\..\main.c @@ -632,6 +627,11 @@ 1 ..\..\..\..\..\src\qs\qs_rx.c + + qstamp.c + 1 + ..\..\..\..\..\src\qs\qstamp.c + @@ -640,7 +640,7 @@ dpp-rel 0x4 ARM-ADS - 6070000::V6.7::.\ARMCLANG + 6160000::V6.16::ARMCLANG 1 @@ -943,7 +943,7 @@ 0 - 7 + 6 0 0 1 @@ -962,12 +962,12 @@ 3 0 0 - 0 + 1 0 0 - NDEBUG TARGET_IS_TM4C123_RB1 + NDEBUG,QP_CONFIG ..\..;..\..\..\..\..\include;..\..\..\..\..\ports\arm-cm\qk\armclang;..\..\..\..\..\3rd_party\CMSIS\Include;..\..\..\..\..\3rd_party\ek-tm4c123gxl @@ -991,7 +991,7 @@ - 1 + 0 0 0 0 @@ -1000,7 +1000,7 @@ 0x00000000 0x20000000 - dpp-qk.sct + .\dpp-qk.sct --entry Reset_Handler @@ -1038,15 +1038,10 @@ 1 ..\..\table.c - - qstamp.c - 1 - ..\..\..\..\..\include\qstamp.c - main.c 1 - ..\main.c + ..\..\main.c @@ -1262,6 +1257,11 @@ 1 ..\..\..\..\..\src\qs\qs_rx.c + + qstamp.c + 1 + ..\..\..\..\..\src\qs\qstamp.c + @@ -1573,7 +1573,7 @@ 0 - 7 + 1 0 0 1 @@ -1597,7 +1597,7 @@ 0 - Q_SPY,QF_ON_CONTEXT_SW,TARGET_IS_TM4C123_RB1 + Q_SPY,QP_CONFIG,TARGET_IS_TM4C123_RB1 ..\..;..\..\..\..\..\include;..\..\..\..\..\ports\arm-cm\qk\armclang;..\..\..\..\..\3rd_party\CMSIS\Include;..\..\..\..\..\3rd_party\ek-tm4c123gxl @@ -1621,7 +1621,7 @@ - 1 + 0 0 0 0 @@ -1630,7 +1630,7 @@ 0x00000000 0x20000000 - + .\dpp-qk.sct --entry Reset_Handler @@ -1668,15 +1668,10 @@ 1 ..\..\table.c - - qstamp.c - 1 - ..\..\..\..\..\include\qstamp.c - main.c 1 - ..\main.c + ..\..\main.c @@ -1823,6 +1818,11 @@ 1 ..\..\..\..\..\src\qs\qs_rx.c + + qstamp.c + 1 + ..\..\..\..\..\src\qs\qstamp.c + diff --git a/examples/arm-cm/dpp_ek-tm4c123gxl/qk/bsp.c b/examples/arm-cm/dpp_ek-tm4c123gxl/qk/bsp.c index 0146bd09..a48134f1 100644 --- a/examples/arm-cm/dpp_ek-tm4c123gxl/qk/bsp.c +++ b/examples/arm-cm/dpp_ek-tm4c123gxl/qk/bsp.c @@ -1,580 +1,537 @@ -/***************************************************************************** -* Product: DPP example, EK-TM4C123GXL board, preemptive QK kernel -* Last updated for version 7.2.0 -* Last updated on 2022-12-17 -* -* Q u a n t u m L e a P s -* ------------------------ -* Modern Embedded Software -* -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* -* -*****************************************************************************/ -#include "qpc.h" -#include "dpp.h" -#include "bsp.h" +//============================================================================ +// Product: DPP example, EK-TM4C123GXL board, QK kernel +// Last updated for version 7.3.0 +// Last updated on 2023-08-15 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. +// +// This program is open source software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Alternatively, this program may be distributed and modified under the +// terms of Quantum Leaps commercial licenses, which expressly supersede +// the GNU General Public License and are specifically designed for +// licensees interested in retaining the proprietary status of their code. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Contact information: +// +// +//============================================================================ +#include "qpc.h" // QP/C real-time embedded framework +#include "dpp.h" // DPP Application interface +#include "bsp.h" // Board Support Package -#include "TM4C123GH6PM.h" /* the device specific header (TI) */ -#include "rom.h" /* the built-in ROM functions (TI) */ -#include "sysctl.h" /* system control driver (TI) */ -#include "gpio.h" /* GPIO driver (TI) */ -/* add other drivers if necessary... */ +#include "TM4C123GH6PM.h" // the device specific header (TI) +#include "rom.h" // the built-in ROM functions (TI) +#include "sysctl.h" // system control driver (TI) +#include "gpio.h" // GPIO driver (TI) +// add other drivers if necessary... -Q_DEFINE_THIS_FILE /* define the name of this file for assertions */ +Q_DEFINE_THIS_FILE // define the name of this file for assertions -/* prototypes of ISRs defined in this BSP ----------------------------------*/ -void SysTick_Handler(void); -void GPIOPortA_IRQHandler(void); -void UART0_IRQHandler(void); +// Local-scope objects ----------------------------------------------------- +// LEDs on the board +#define LED_RED (1U << 1U) +#define LED_GREEN (1U << 3U) +#define LED_BLUE (1U << 2U) -/* Local-scope objects -----------------------------------------------------*/ -#define LED_RED (1U << 1) -#define LED_GREEN (1U << 3) -#define LED_BLUE (1U << 2) +// Buttons on the board +#define BTN_SW1 (1U << 4U) +#define BTN_SW2 (1U << 0U) -#define BTN_SW1 (1U << 4) -#define BTN_SW2 (1U << 0) - -static uint32_t l_rnd; /* random seed */ +static uint32_t l_rndSeed; #ifdef Q_SPY - /* QSpy source IDs */ + // QSpy source IDs static QSpyId const l_SysTick_Handler = { 0U }; static QSpyId const l_GPIOPortA_IRQHandler = { 0U }; #define UART_BAUD_RATE 115200U - #define UART_FR_TXFE (1U << 7) - #define UART_FR_RXFE (1U << 4) + #define UART_FR_TXFE (1U << 7U) + #define UART_FR_RXFE (1U << 4U) #define UART_TXFIFO_DEPTH 16U - enum AppRecords { /* application-specific trace records */ + enum AppRecords { // application-specific trace records PHILO_STAT = QS_USER, PAUSED_STAT, CONTEXT_SW, - COMMAND_STAT }; #endif -/*..........................................................................*/ +//============================================================================ +// Error handler and ISRs... + +Q_NORETURN Q_onError(char const * const module, int_t const id) { + // NOTE: this implementation of the error handler is intended only + // for debugging and MUST be changed for deployment of the application + // (assuming that you ship your production code with assertions enabled). + Q_UNUSED_PAR(module); + Q_UNUSED_PAR(id); + QS_ASSERTION(module, id, 10000U); // report assertion to QS + +#ifndef NDEBUG + // light up all LEDs + GPIOF_AHB->DATA_Bits[LED_GREEN | LED_RED | LED_BLUE] = 0xFFU; + for (;;) { // for debugging, hang on in an endless loop... + } +#else + NVIC_SystemReset(); + for (;;) { // explicitly "no-return" + } +#endif +} +//............................................................................ +void assert_failed(char const * const module, int_t const id); // prototype +void assert_failed(char const * const module, int_t const id) { + Q_onError(module, id); +} + +// ISRs used in the application ============================================ + +void SysTick_Handler(void); // prototype void SysTick_Handler(void) { - QK_ISR_ENTRY(); /* inform QK about entering an ISR */ + QK_ISR_ENTRY(); // inform QK about entering an ISR - /* process time events for clock rate 0 */ - QTIMEEVT_TICK_X(0U, &l_SysTick_Handler); + QTIMEEVT_TICK_X(0U, &l_SysTick_Handler); // time events at rate 0 - /* Perform the debouncing of buttons. The algorithm for debouncing - * adapted from the book "Embedded Systems Dictionary" by Jack Ganssle - * and Michael Barr, page 71. - */ - /* state of the button debouncing, see below */ - static struct ButtonsDebouncing { + // Perform the debouncing of buttons. The algorithm for debouncing + // adapted from the book "Embedded Systems Dictionary" by Jack Ganssle + // and Michael Barr, page 71. + static struct { uint32_t depressed; uint32_t previous; } buttons = { 0U, 0U }; - uint32_t current = ~GPIOF_AHB->DATA_Bits[BTN_SW1 | BTN_SW2]; /* read SW1&SW2 */ - uint32_t tmp = buttons.depressed; /* save debounced depressed buttons */ - buttons.depressed |= (buttons.previous & current); /* set depressed */ - buttons.depressed &= (buttons.previous | current); /* clear released */ - buttons.previous = current; /* update the history */ - tmp ^= buttons.depressed; /* changed debounced depressed */ - if ((tmp & BTN_SW1) != 0U) { /* debounced SW1 state changed? */ - if ((buttons.depressed & BTN_SW1) != 0U) { /* is SW1 depressed? */ - static QEvt const pauseEvt = { PAUSE_SIG, 0U, 0U}; + + uint32_t current = ~GPIOF_AHB->DATA_Bits[BTN_SW1 | BTN_SW2]; + uint32_t tmp = buttons.depressed; // save debounced depressed buttons + buttons.depressed |= (buttons.previous & current); // set depressed + buttons.depressed &= (buttons.previous | current); // clear released + buttons.previous = current; // update the history + tmp ^= buttons.depressed; // changed debounced depressed + current = buttons.depressed; + + if ((tmp & BTN_SW1) != 0U) { // debounced SW1 state changed? + if ((current & BTN_SW1) != 0U) { // is SW1 depressed? + static QEvt const pauseEvt = QEVT_INITIALIZER(PAUSE_SIG); QACTIVE_PUBLISH(&pauseEvt, &l_SysTick_Handler); } - else { /* the button is released */ - static QEvt const serveEvt = { SERVE_SIG, 0U, 0U}; + else { // the button is released + static QEvt const serveEvt = QEVT_INITIALIZER(SERVE_SIG); QACTIVE_PUBLISH(&serveEvt, &l_SysTick_Handler); } } - if ((tmp & BTN_SW2) != 0U) { /* debounced SW2 state changed? */ - /* TEST: of MPU */ - uint32_t volatile foo = *(uint32_t volatile *)0x204U; // legal - *(uint32_t volatile *)0x204U = foo; // illegal - } - QK_ISR_EXIT(); /* inform QK about exiting an ISR */ + QK_ISR_EXIT(); // inform QK about exiting an ISR } -/*..........................................................................*/ +//............................................................................ +// interrupt handler for testing preemptions in QK +void GPIOPortA_IRQHandler(void); // prototype void GPIOPortA_IRQHandler(void) { - QK_ISR_ENTRY(); /* inform QK about entering an ISR */ + QK_ISR_ENTRY(); // inform QK about entering an ISR - QACTIVE_POST(AO_Table, Q_NEW(QEvt, MAX_PUB_SIG), /* for testing... */ - &l_GPIOPortA_IRQHandler); + QEvt const testEvt = QEVT_INITIALIZER(MAX_PUB_SIG); + QACTIVE_POST(AO_Table, &testEvt, + &l_GPIOPortA_IRQHandler); - QK_ISR_EXIT(); /* inform QK about exiting an ISR */ + QK_ISR_EXIT(); // inform QK about exiting an ISR } -/*..........................................................................*/ -#ifdef Q_SPY -/* -* ISR for receiving bytes from the QSPY Back-End -* NOTE: This ISR is "QF-unaware" meaning that it does not interact with -* the QF/QK and is not disabled. Such ISRs don't need to call QK_ISR_ENTRY/ -* QK_ISR_EXIT and they cannot post or publish events. -*/ -void UART0_IRQHandler(void) { - uint32_t status = UART0->RIS; /* get the raw interrupt status */ - UART0->ICR = status; /* clear the asserted interrupts */ - while ((UART0->FR & UART_FR_RXFE) == 0) { /* while RX FIFO NOT empty */ - uint32_t b = UART0->DR; - QS_RX_PUT(b); +//............................................................................ +#ifdef Q_SPY +// ISR for receiving bytes from the QSPY Back-End +// NOTE: This ISR is "QF-unaware" meaning that it does not interact with +// the QF/QK and is not disabled. Such ISRs don't need to call +// QK_ISR_ENTRY/QK_ISR_EXIT and they cannot post or publish events. + +void UART0_IRQHandler(void); // prototype +void UART0_IRQHandler(void) { + uint32_t status = UART0->RIS; // get the raw interrupt status + UART0->ICR = status; // clear the asserted interrupts + + while ((UART0->FR & UART_FR_RXFE) == 0U) { // while RX FIFO NOT empty + uint8_t b = (uint8_t)UART0->DR; + QS_rxPut(b); } + QK_ARM_ERRATUM_838869(); } -#else -void UART0_IRQHandler(void) {} -#endif +#endif // Q_SPY -/* BSP functions ===========================================================*/ -/* MPU setup for TM4C123GXL MCU */ -static void TM4C123GXL_MPU_setup(void) { - /* The following MPU configuration contains the general TM4C memory map. - * - * Please note that the actual TM4C MCUs provide much less Flash and SRAM - * than the maximums configured here. This means that actual MCUs have - * unmapped memory regions (e.g., beyond the actual SRAM). Attempts to - * access these regions causes the HardFault exception, which is the - * desired behavior. - */ - static struct { - uint32_t rbar; - uint32_t rasr; - } const mpu_setup[] = { - { /* region #0: Flash: base=0x0000'0000, size=512M=2^(28+1) */ - 0x00000000U /* base address */ - | MPU_RBAR_VALID_Msk /* valid region */ - | (MPU_RBAR_REGION_Msk & 0U), /* region #0 */ - (28U << MPU_RASR_SIZE_Pos) /* 2^(18+1) region */ - | (0x6U << MPU_RASR_AP_Pos) /* PA:ro/UA:ro */ - | (1U << MPU_RASR_C_Pos) /* C=1 */ - | MPU_RASR_ENABLE_Msk /* region enable */ - }, +//............................................................................ +#ifdef QF_ON_CONTEXT_SW +// NOTE: the context-switch callback is called with interrupts DISABLED +void QF_onContextSw(QActive *prev, QActive *next) { + QS_BEGIN_INCRIT(CONTEXT_SW, 0U) // in critical section! + QS_OBJ(prev); + QS_OBJ(next); + QS_END_INCRIT() +} +#endif // QF_ON_CONTEXT_SW - { /* region #1: SRAM: base=0x2000'0000, size=512M=2^(28+1) */ - 0x20000000U /* base address */ - | MPU_RBAR_VALID_Msk /* valid region */ - | (MPU_RBAR_REGION_Msk & 1U), /* region #1 */ - (28U << MPU_RASR_SIZE_Pos) /* 2^(28+1) region */ - | (0x3U << MPU_RASR_AP_Pos) /* PA:rw/UA:rw */ - | (1U << MPU_RASR_XN_Pos) /* XN=1 */ - | (1U << MPU_RASR_S_Pos) /* S=1 */ - | (1U << MPU_RASR_C_Pos) /* C=1 */ - | MPU_RASR_ENABLE_Msk /* region enable */ - }, +//============================================================================ +// BSP functions... - /* region #3: (not configured) */ - { MPU_RBAR_VALID_Msk | (MPU_RBAR_REGION_Msk & 2U), 0U }, +void BSP_init(void) { + // Configure the MPU to prevent NULL-pointer dereferencing ... + MPU->RBAR = 0x0U // base address (NULL) + | MPU_RBAR_VALID_Msk // valid region + | (MPU_RBAR_REGION_Msk & 7U); // region #7 + MPU->RASR = (7U << MPU_RASR_SIZE_Pos) // 2^(7+1) region + | (0x0U << MPU_RASR_AP_Pos) // no-access region + | MPU_RASR_ENABLE_Msk; // region enable + MPU->CTRL = MPU_CTRL_PRIVDEFENA_Msk // enable background region + | MPU_CTRL_ENABLE_Msk; // enable the MPU + __ISB(); + __DSB(); - { /* region #3: Peripherals: base=0x4000'0000, size=512M=2^(28+1) */ - 0x40000000U /* base address */ - | MPU_RBAR_VALID_Msk /* valid region */ - | (MPU_RBAR_REGION_Msk & 3U), /* region #3 */ - (28U << MPU_RASR_SIZE_Pos) /* 2^(28+1) region */ - | (0x3U << MPU_RASR_AP_Pos) /* PA:rw/UA:rw */ - | (1U << MPU_RASR_XN_Pos) /* XN=1 */ - | (1U << MPU_RASR_S_Pos) /* S=1 */ - | (1U << MPU_RASR_B_Pos) /* B=1 */ - | MPU_RASR_ENABLE_Msk /* region enable */ - }, - - { /* region #4: Priv. Periph: base=0xE000'0000, size=512M=2^(28+1) */ - 0xE0000000U /* base address */ - | MPU_RBAR_VALID_Msk /* valid region */ - | (MPU_RBAR_REGION_Msk & 4U), /* region #4 */ - (28U << MPU_RASR_SIZE_Pos) /* 2^(28+1) region */ - | (0x3U << MPU_RASR_AP_Pos) /* PA:rw/UA:rw */ - | (1U << MPU_RASR_XN_Pos) /* XN=1 */ - | (1U << MPU_RASR_S_Pos) /* S=1 */ - | (1U << MPU_RASR_B_Pos) /* B=1 */ - | MPU_RASR_ENABLE_Msk /* region enable */ - }, - - { /* region #5: Ext RAM: base=0x6000'0000, size=1G=2^(29+1) */ - 0x60000000U /* base address */ - | MPU_RBAR_VALID_Msk /* valid region */ - | (MPU_RBAR_REGION_Msk & 5U), /* region #5 */ - (29U << MPU_RASR_SIZE_Pos) /* 2^(28+1) region */ - | (0x3U << MPU_RASR_AP_Pos) /* PA:rw/UA:rw */ - | (1U << MPU_RASR_XN_Pos) /* XN=1 */ - | (1U << MPU_RASR_S_Pos) /* S=1 */ - | (1U << MPU_RASR_B_Pos) /* B=1 */ - | MPU_RASR_ENABLE_Msk /* region enable */ - }, - - { /* region #6: Ext Dev: base=0xA000'0000, size=1G=2^(29+1) */ - 0xA0000000U /* base address */ - | MPU_RBAR_VALID_Msk /* valid region */ - | (MPU_RBAR_REGION_Msk & 6U), /* region #6 */ - (29U << MPU_RASR_SIZE_Pos) /* 2^(28+1) region */ - | (0x3U << MPU_RASR_AP_Pos) /* PA:rw/UA:rw */ - | (1U << MPU_RASR_XN_Pos) /* XN=1 */ - | (1U << MPU_RASR_S_Pos) /* S=1 */ - | (1U << MPU_RASR_B_Pos) /* B=1 */ - | MPU_RASR_ENABLE_Msk /* region enable */ - }, - - { /* region #7: NULL-pointer: base=0x000'0000, size=256B */ - 0x00000000U /* base address */ - | MPU_RBAR_VALID_Msk /* valid region */ - | (MPU_RBAR_REGION_Msk & 7U), /* region #7 */ - (7U << MPU_RASR_SIZE_Pos) /* 2^(7+1)=256B region */ - | (0x0U << MPU_RASR_AP_Pos) /* PA:na/UA:na */ - | (1U << MPU_RASR_XN_Pos) /* XN=1 */ - | MPU_RASR_ENABLE_Msk /* region enable */ - }, - }; - - /* enable the MemManage_Handler for MPU exception */ + // enable the MemManage_Handler for MPU exception SCB->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk; - __DSB(); - MPU->CTRL = 0U; /* disable the MPU */ - for (uint_fast8_t n = 0U; n < Q_DIM(mpu_setup); ++n) { - MPU->RBAR = mpu_setup[n].rbar; - MPU->RASR = mpu_setup[n].rasr; - } - MPU->CTRL = MPU_CTRL_ENABLE_Msk; /* enable the MPU */ - __ISB(); - __DSB(); -} - -/*..........................................................................*/ -void BSP_init(void) { - /* setup the MPU... */ - TM4C123GXL_MPU_setup(); - - /* NOTE: SystemInit() already called from the startup code - * but SystemCoreClock needs to be updated - */ + // NOTE: SystemInit() has been already called from the startup code + // but SystemCoreClock needs to be updated SystemCoreClockUpdate(); - /* NOTE: The VFP (hardware Floating Point) unit is configured by QK */ + // NOTE: The VFP (hardware Floating Point) unit is configured by QK - /* enable clock for to the peripherals used by this application... */ - SYSCTL->RCGCGPIO |= (1U << 5); /* enable Run mode for GPIOF */ - SYSCTL->GPIOHBCTL |= (1U << 5); /* enable AHB for GPIOF */ + // enable clock for to the peripherals used by this application... + SYSCTL->RCGCGPIO |= (1U << 5U); // enable Run mode for GPIOF + SYSCTL->GPIOHBCTL |= (1U << 5U); // enable AHB for GPIOF __ISB(); __DSB(); - /* configure LEDs (digital output) */ + // configure LEDs (digital output) GPIOF_AHB->DIR |= (LED_RED | LED_BLUE | LED_GREEN); GPIOF_AHB->DEN |= (LED_RED | LED_BLUE | LED_GREEN); GPIOF_AHB->DATA_Bits[LED_RED | LED_BLUE | LED_GREEN] = 0U; - /* configure switches... */ + // configure switches... - /* unlock access to the SW2 pin because it is PROTECTED */ - GPIOF_AHB->LOCK = 0x4C4F434BU; /* unlock GPIOCR register for SW2 */ - /* commit the write (cast const away) */ + // unlock access to the SW2 pin because it is PROTECTED + GPIOF_AHB->LOCK = 0x4C4F434BU; // unlock GPIOCR register for SW2 + // commit the write (cast const away) *(uint32_t volatile *)&GPIOF_AHB->CR = 0x01U; - GPIOF_AHB->DIR &= ~(BTN_SW1 | BTN_SW2); /* input */ - GPIOF_AHB->DEN |= (BTN_SW1 | BTN_SW2); /* digital enable */ - GPIOF_AHB->PUR |= (BTN_SW1 | BTN_SW2); /* pull-up resistor enable */ + GPIOF_AHB->DIR &= ~(BTN_SW1 | BTN_SW2); // input + GPIOF_AHB->DEN |= (BTN_SW1 | BTN_SW2); // digital enable + GPIOF_AHB->PUR |= (BTN_SW1 | BTN_SW2); // pull-up resistor enable *(uint32_t volatile *)&GPIOF_AHB->CR = 0x00U; - GPIOF_AHB->LOCK = 0x0; /* lock GPIOCR register for SW2 */ + GPIOF_AHB->LOCK = 0x0; // lock GPIOCR register for SW2 - /* seed the random number generator */ + // seed the random number generator BSP_randomSeed(1234U); - /* initialize the QS software tracing... */ - if (QS_INIT((void *)0) == 0U) { + // initialize the QS software tracing... + if (!QS_INIT((void *)0)) { Q_ERROR(); } + + // dictionaries... QS_OBJ_DICTIONARY(&l_SysTick_Handler); QS_OBJ_DICTIONARY(&l_GPIOPortA_IRQHandler); QS_USR_DICTIONARY(PHILO_STAT); QS_USR_DICTIONARY(PAUSED_STAT); - QS_USR_DICTIONARY(COMMAND_STAT); + QS_USR_DICTIONARY(CONTEXT_SW); - /* setup the QS filters... */ - QS_GLB_FILTER(QS_ALL_RECORDS); /* all records */ - QS_GLB_FILTER(-QS_QF_TICK); /* exclude the clock tick */ + QS_ONLY(produce_sig_dict()); + + // setup the QS filters... + QS_GLB_FILTER(QS_ALL_RECORDS); // all records + QS_GLB_FILTER(-QS_QF_TICK); // exclude the clock tick } -/*..........................................................................*/ +//............................................................................ +void BSP_start(void) { + // initialize event pools + static QF_MPOOL_EL(TableEvt) smlPoolSto[2*N_PHILO]; + QF_poolInit(smlPoolSto, sizeof(smlPoolSto), sizeof(smlPoolSto[0])); + + // initialize publish-subscribe + static QSubscrList subscrSto[MAX_PUB_SIG]; + QActive_psInit(subscrSto, Q_DIM(subscrSto)); + + // instantiate and start AOs/threads... + + static QEvt const *philoQueueSto[N_PHILO][10]; + for (uint8_t n = 0U; n < N_PHILO; ++n) { + Philo_ctor(n); + QACTIVE_START(AO_Philo[n], + + // NOTE: set the preemption-threshold of all Philos to + // the same level, so that they cannot preempt each other. + Q_PRIO(n + 3U, N_PHILO + 2U), // QF-prio/pre-thre. + + philoQueueSto[n], // event queue storage + Q_DIM(philoQueueSto[n]), // queue length [events] + (void *)0, 0U, // QK needs no stack storage + (void *)0); // no initialization param + } + + static QEvt const *tableQueueSto[N_PHILO]; + Table_ctor(); + QACTIVE_START(AO_Table, + N_PHILO + 7U, // QP prio. of the AO + tableQueueSto, // event queue storage + Q_DIM(tableQueueSto), // queue length [events] + (void *)0, 0U, // no stack storage + (void *)0); // no initialization param +} +//............................................................................ void BSP_displayPhilStat(uint8_t n, char const *stat) { + Q_UNUSED_PAR(n); + GPIOF_AHB->DATA_Bits[LED_GREEN] = ((stat[0] == 'e') ? LED_GREEN : 0U); - QS_BEGIN_ID(PHILO_STAT, AO_Philo[n]->prio) /* app-specific record */ - QS_U8(1, n); /* Philosopher number */ - QS_STR(stat); /* Philosopher status */ + // app-specific trace record... + QS_BEGIN_ID(PHILO_STAT, AO_Table->prio) + QS_U8(1, n); // Philosopher number + QS_STR(stat); // Philosopher status QS_END() } -/*..........................................................................*/ -void BSP_displayPaused(uint8_t paused) { +//............................................................................ +void BSP_displayPaused(uint8_t const paused) { GPIOF_AHB->DATA_Bits[LED_BLUE] = ((paused != 0U) ? LED_BLUE : 0U); - QS_BEGIN_ID(PAUSED_STAT, 0U) /* app-specific record */ - QS_U8(1, paused); /* Paused status */ + // application-specific trace record + QS_BEGIN_ID(PAUSED_STAT, AO_Table->prio) + QS_U8(1, paused); // Paused status QS_END() } -/*..........................................................................*/ -uint32_t BSP_random(void) { /* a very cheap pseudo-random-number generator */ - /* Some flating point code is to exercise the VFP... */ +//............................................................................ +void BSP_randomSeed(uint32_t seed) { + l_rndSeed = seed; +} +//............................................................................ +uint32_t BSP_random(void) { // a very cheap pseudo-random-number generator + // Some floating point code is to exercise the VFP... float volatile x = 3.1415926F; x = x + 2.7182818F; - /* lock scheduler around shared seed */ QSchedStatus lockStat = QK_schedLock(N_PHILO); - /* "Super-Duper" Linear Congruential Generator (LCG) - * LCG(2^32, 3*7*11*13*23, 0, seed) - */ - l_rnd = l_rnd * (3U*7U*11U*13U*23U); - QK_schedUnlock(lockStat); /* unlock the scheduler */ + // "Super-Duper" Linear Congruential Generator (LCG) + // LCG(2^32, 3*7*11*13*23, 0, seed) + uint32_t rnd = l_rndSeed * (3U*7U*11U*13U*23U); + l_rndSeed = rnd; // set for the next time + QK_schedUnlock(lockStat); - return l_rnd >> 8; + return (rnd >> 8U); } -/*..........................................................................*/ -void BSP_randomSeed(uint32_t seed) { - l_rnd = seed; +//............................................................................ +void BSP_ledOn(void) { + GPIOF_AHB->DATA_Bits[LED_RED] = 0xFFU; } -/*..........................................................................*/ +//............................................................................ +void BSP_ledOff(void) { + GPIOF_AHB->DATA_Bits[LED_RED] = 0x00U; +} +//............................................................................ void BSP_terminate(int16_t result) { - (void)result; + Q_UNUSED_PAR(result); } -/* QF callbacks ============================================================*/ +//============================================================================ +// QF callbacks... void QF_onStartup(void) { - /* set up the SysTick timer to fire at BSP_TICKS_PER_SEC rate */ + // set up the SysTick timer to fire at BSP_TICKS_PER_SEC rate SysTick_Config(SystemCoreClock / BSP_TICKS_PER_SEC); - /* assing all priority bits for preemption-prio. and none to sub-prio. */ + // assign all priority bits for preemption-prio. and none to sub-prio. NVIC_SetPriorityGrouping(0U); - /* set priorities of ALL ISRs used in the system, see NOTE1 - * - * !!!!!!!!!!!!!!!!!!!!!!!!!!!! CAUTION !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - * Assign a priority to EVERY ISR explicitly by calling NVIC_SetPriority(). - * DO NOT LEAVE THE ISR PRIORITIES AT THE DEFAULT VALUE! - */ - NVIC_SetPriority(UART0_IRQn, 0U); /* kernel unaware interrupt */ - NVIC_SetPriority(GPIOA_IRQn, QF_AWARE_ISR_CMSIS_PRI); - NVIC_SetPriority(SysTick_IRQn, QF_AWARE_ISR_CMSIS_PRI + 1U); - /* ... */ + // set priorities of ALL ISRs used in the system, see NOTE1 + NVIC_SetPriority(UART0_IRQn, 0U); // kernel UNAWARE interrupt + NVIC_SetPriority(GPIOA_IRQn, QF_AWARE_ISR_CMSIS_PRI + 0U); + NVIC_SetPriority(SysTick_IRQn, QF_AWARE_ISR_CMSIS_PRI + 1U); + // ... - /* enable IRQs... */ + // enable IRQs in the NVIC... NVIC_EnableIRQ(GPIOA_IRQn); #ifdef Q_SPY - NVIC_EnableIRQ(UART0_IRQn); /* UART0 interrupt used for QS-RX */ + NVIC_EnableIRQ(UART0_IRQn); // UART interrupt used for QS-RX #endif } -/*..........................................................................*/ +//............................................................................ void QF_onCleanup(void) { } -/*..........................................................................*/ -#ifdef QF_ON_CONTEXT_SW -/* NOTE: the context-switch callback is called with interrupts DISABLED */ -void QF_onContextSw(QActive *prev, QActive *next) { - QS_BEGIN_NOCRIT(CONTEXT_SW, 0U) /* no critical section! */ - QS_OBJ(prev); - QS_OBJ(next); - QS_END_NOCRIT() -} -#endif /* QF_ON_CONTEXT_SW */ -/*..........................................................................*/ +//............................................................................ void QK_onIdle(void) { - /* toggle the User LED on and then off, see NOTE2 */ + // toggle the User LED on and then off, see NOTE2 QF_INT_DISABLE(); - GPIOF_AHB->DATA_Bits[LED_BLUE] = 0xFFU; /* turn the Blue LED on */ - GPIOF_AHB->DATA_Bits[LED_BLUE] = 0U; /* turn the Blue LED off */ + GPIOF_AHB->DATA_Bits[LED_BLUE] = 0xFFU; // turn the Blue LED on + GPIOF_AHB->DATA_Bits[LED_BLUE] = 0U; // turn the Blue LED off QF_INT_ENABLE(); -#ifdef Q_SPY - QS_rxParse(); /* parse all the received bytes */ + // Some floating point code is to exercise the VFP... + float volatile x = 1.73205F; + x = x * 1.73205F; - if ((UART0->FR & UART_FR_TXFE) != 0U) { /* TX done? */ - uint16_t fifo = UART_TXFIFO_DEPTH; /* max bytes we can accept */ +#ifdef Q_SPY + QF_INT_DISABLE(); + QS_rxParse(); // parse all the received bytes + QF_INT_ENABLE(); + + if ((UART0->FR & UART_FR_TXFE) != 0U) { // TX done? + uint16_t fifo = UART_TXFIFO_DEPTH; // max bytes we can accept QF_INT_DISABLE(); - /* try to get next contiguous block to transmit */ uint8_t const *block = QS_getBlock(&fifo); QF_INT_ENABLE(); - while (fifo-- != 0) { /* any bytes in the block? */ - UART0->DR = *block++; /* put into the FIFO */ + while (fifo-- != 0U) { // any bytes in the block? + UART0->DR = *block++; // put into the FIFO } } #elif defined NDEBUG - /* Put the CPU and peripherals to the low-power mode. - * you might need to customize the clock management for your application, - * see the datasheet for your particular Cortex-M MCU. - */ - __WFI(); /* Wait-For-Interrupt */ + // Put the CPU and peripherals to the low-power mode. + // you might need to customize the clock management for your application, + // see the datasheet for your particular Cortex-M MCU. + // + __WFI(); // Wait-For-Interrupt #endif } -/*..........................................................................*/ -Q_NORETURN Q_onAssert(char const * const module, int_t const loc) { - /* - * NOTE: add here your application-specific error handling - */ - (void)module; - (void)loc; - QS_ASSERTION(module, loc, 10000U); /* report assertion to QS */ - -#ifndef NDEBUG - /* light up all LEDs */ - GPIOF_AHB->DATA_Bits[LED_GREEN | LED_RED | LED_BLUE] = 0xFFU; - /* for debugging, hang on in an endless loop... */ - for (;;) { - } -#endif - - NVIC_SystemReset(); -} - -/* QS callbacks ============================================================*/ +//============================================================================ +// QS callbacks... #ifdef Q_SPY -/*..........................................................................*/ + +//............................................................................ uint8_t QS_onStartup(void const *arg) { Q_UNUSED_PAR(arg); - static uint8_t qsTxBuf[2*1024]; /* buffer for QS-TX channel */ - static uint8_t qsRxBuf[100]; /* buffer for QS-RX channel */ + static uint8_t qsTxBuf[2*1024]; // buffer for QS-TX channel + QS_initBuf(qsTxBuf, sizeof(qsTxBuf)); - QS_initBuf (qsTxBuf, sizeof(qsTxBuf)); + static uint8_t qsRxBuf[100]; // buffer for QS-RX channel QS_rxInitBuf(qsRxBuf, sizeof(qsRxBuf)); - /* enable clock for UART0 and GPIOA (used by UART0 pins) */ - SYSCTL->RCGCUART |= (1U << 0); /* enable Run mode for UART0 */ - SYSCTL->RCGCGPIO |= (1U << 0); /* enable Run mode for GPIOA */ + // enable clock for UART0 and GPIOA (used by UART0 pins) + SYSCTL->RCGCUART |= (1U << 0U); // enable Run mode for UART0 + SYSCTL->RCGCGPIO |= (1U << 0U); // enable Run mode for GPIOA - /* configure UART0 pins for UART operation */ - uint32_t tmp = (1U << 0) | (1U << 1); + // configure UART0 pins for UART operation + uint32_t tmp = (1U << 0U) | (1U << 1U); GPIOA->DIR &= ~tmp; GPIOA->SLR &= ~tmp; GPIOA->ODR &= ~tmp; GPIOA->PUR &= ~tmp; GPIOA->PDR &= ~tmp; - GPIOA->AMSEL &= ~tmp; /* disable analog function on the pins */ - GPIOA->AFSEL |= tmp; /* enable ALT function on the pins */ - GPIOA->DEN |= tmp; /* enable digital I/O on the pins */ + GPIOA->AMSEL &= ~tmp; // disable analog function on the pins + GPIOA->AFSEL |= tmp; // enable ALT function on the pins + GPIOA->DEN |= tmp; // enable digital I/O on the pins GPIOA->PCTL &= ~0x00U; GPIOA->PCTL |= 0x11U; - /* configure the UART for the desired baud rate, 8-N-1 operation */ + // configure the UART for the desired baud rate, 8-N-1 operation tmp = (((SystemCoreClock * 8U) / UART_BAUD_RATE) + 1U) / 2U; UART0->IBRD = tmp / 64U; UART0->FBRD = tmp % 64U; - UART0->LCRH = (0x3U << 5); /* configure 8-N-1 operation */ - UART0->LCRH |= (0x1U << 4); /* enable FIFOs */ - UART0->CTL = (1U << 0) /* UART enable */ - | (1U << 8) /* UART TX enable */ - | (1U << 9); /* UART RX enable */ + UART0->LCRH = (0x3U << 5U); // configure 8-N-1 operation + UART0->LCRH |= (0x1U << 4U); // enable FIFOs + UART0->CTL = (1U << 0U) // UART enable + | (1U << 8U) // UART TX enable + | (1U << 9U); // UART RX enable - /* configure UART interrupts (for the RX channel) */ - UART0->IM |= (1U << 4) | (1U << 6); /* enable RX and RX-TO interrupt */ - UART0->IFLS |= (0x2U << 2); /* interrupt on RX FIFO half-full */ - /* NOTE: do not enable the UART0 interrupt yet. Wait till QF_onStartup() */ + // configure UART interrupts (for the RX channel) + UART0->IM |= (1U << 4U) | (1U << 6U); // enable RX and RX-TO interrupt + UART0->IFLS |= (0x2U << 2U); // interrupt on RX FIFO half-full + // NOTE: do not enable the UART0 interrupt yet. Wait till QF_onStartup() - /* configure TIMER5 to produce QS time stamp */ - SYSCTL->RCGCTIMER |= (1U << 5); /* enable run mode for Timer5 */ - TIMER5->CTL = 0U; /* disable Timer1 output */ - TIMER5->CFG = 0x0U; /* 32-bit configuration */ - TIMER5->TAMR = (1U << 4) | 0x02; /* up-counting periodic mode */ - TIMER5->TAILR= 0xFFFFFFFFU; /* timer interval */ - TIMER5->ICR = 0x1U; /* TimerA timeout flag bit clears*/ - TIMER5->CTL |= (1U << 0); /* enable TimerA module */ + // configure TIMER5 to produce QS time stamp + SYSCTL->RCGCTIMER |= (1U << 5U); // enable run mode for Timer5 + TIMER5->CTL = 0U; // disable Timer1 output + TIMER5->CFG = 0x0U; // 32-bit configuration + TIMER5->TAMR = (1U << 4U) | 0x02U; // up-counting periodic mode + TIMER5->TAILR= 0xFFFFFFFFU; // timer interval + TIMER5->ICR = 0x1U; // TimerA timeout flag bit clears + TIMER5->CTL |= (1U << 0U); // enable TimerA module - return 1U; /* return success */ + return 1U; // return success } -/*..........................................................................*/ +//............................................................................ void QS_onCleanup(void) { } -/*..........................................................................*/ -QSTimeCtr QS_onGetTime(void) { /* NOTE: invoked with interrupts DISABLED */ +//............................................................................ +QSTimeCtr QS_onGetTime(void) { // NOTE: invoked with interrupts DISABLED return TIMER5->TAV; } -/*..........................................................................*/ +//............................................................................ void QS_onFlush(void) { - while (true) { - /* try to get next byte to transmit */ + for (;;) { QF_INT_DISABLE(); uint16_t b = QS_getByte(); - QF_INT_ENABLE(); + if (b != QS_EOD) { + while ((UART0->FR & UART_FR_TXFE) == 0U) { // while TXE not empty + QF_INT_ENABLE(); + QF_CRIT_EXIT_NOP(); - if (b != QS_EOD) { /* NOT end-of-data */ - /* busy-wait as long as TX FIFO has data to transmit */ - while ((UART0->FR & UART_FR_TXFE) == 0) { + QF_INT_DISABLE(); } - /* place the byte in the UART DR register */ - UART0->DR = b; + UART0->DR = b; // put into the DR register + QF_INT_ENABLE(); } else { - break; /* break out of the loop */ + QF_INT_ENABLE(); + break; } } } -/*..........................................................................*/ -/*! callback function to reset the target (to be implemented in the BSP) */ +//............................................................................ +//! callback function to reset the target (to be implemented in the BSP) void QS_onReset(void) { NVIC_SystemReset(); } -/*..........................................................................*/ -/*! callback function to execute a user command (to be implemented in BSP) */ +//............................................................................ void QS_onCommand(uint8_t cmdId, uint32_t param1, uint32_t param2, uint32_t param3) { - QS_BEGIN_ID(COMMAND_STAT, 0U) /* app-specific record */ - QS_U8(2, cmdId); - QS_U32(8, param1); - QS_U32(8, param2); - QS_U32(8, param3); - QS_END() + Q_UNUSED_PAR(cmdId); + Q_UNUSED_PAR(param1); + Q_UNUSED_PAR(param2); + Q_UNUSED_PAR(param3); } -#endif /* Q_SPY */ -/*--------------------------------------------------------------------------*/ - -/*============================================================================ -* NOTE1: -* The QF_AWARE_ISR_CMSIS_PRI constant from the QF port specifies the highest -* ISR priority that is disabled by the QF framework. The value is suitable -* for the NVIC_SetPriority() CMSIS function. -* -* Only ISRs prioritized at or below the QF_AWARE_ISR_CMSIS_PRI level (i.e., -* with the numerical values of priorities equal or higher than -* QF_AWARE_ISR_CMSIS_PRI) are allowed to call the QK_ISR_ENTRY/QK_ISR_ENTRY -* macros or any other QF/QK services. These ISRs are "QF-aware". -* -* Conversely, any ISRs prioritized above the QF_AWARE_ISR_CMSIS_PRI priority -* level (i.e., with the numerical values of priorities less than -* QF_AWARE_ISR_CMSIS_PRI) are never disabled and are not aware of the kernel. -* Such "QF-unaware" ISRs cannot call any QF/QK services. In particular they -* can NOT call the macros QK_ISR_ENTRY/QK_ISR_ENTRY. The only mechanism -* by which a "QF-unaware" ISR can communicate with the QF framework is by -* triggering a "QF-aware" ISR, which can post/publish events. -* -* NOTE2: -* The User LED is used to visualize the idle loop activity. The brightness -* of the LED is proportional to the frequency of invcations of the idle loop. -* Please note that the LED is toggled with interrupts locked, so no interrupt -* execution time contributes to the brightness of the User LED. -*/ +#endif // Q_SPY +//---------------------------------------------------------------------------- +//============================================================================ +// NOTE1: +// The QF_AWARE_ISR_CMSIS_PRI constant from the QF port specifies the highest +// ISR priority that is disabled by the QF framework. The value is suitable +// for the NVIC_SetPriority() CMSIS function. +// +// Only ISRs prioritized at or below the QF_AWARE_ISR_CMSIS_PRI level (i.e., +// with the numerical values of priorities equal or higher than +// QF_AWARE_ISR_CMSIS_PRI) are allowed to call the QK_ISR_ENTRY/ +// QK_ISR_ENTRY macros or any other QF/QK services. These ISRs are +// "QF-aware". +// +// Conversely, any ISRs prioritized above the QF_AWARE_ISR_CMSIS_PRI priority +// level (i.e., with the numerical values of priorities less than +// QF_AWARE_ISR_CMSIS_PRI) are never disabled and are not aware of the kernel. +// Such "QF-unaware" ISRs cannot call ANY QF/QK services. In particular they +// can NOT call the macros QK_ISR_ENTRY/QK_ISR_ENTRY. The only mechanism +// by which a "QF-unaware" ISR can communicate with the QF framework is by +// triggering a "QF-aware" ISR, which can post/publish events. +// +// NOTE2: +// The User LED is used to visualize the idle loop activity. The brightness +// of the LED is proportional to the frequency of the idle loop. +// Please note that the LED is toggled with interrupts locked, so no interrupt +// execution time contributes to the brightness of the User LED. +// diff --git a/examples/arm-cm/dpp_ek-tm4c123gxl/qk/gnu/.ccsproject b/examples/arm-cm/dpp_ek-tm4c123gxl/qk/gnu/.ccsproject new file mode 100644 index 00000000..0c19207c --- /dev/null +++ b/examples/arm-cm/dpp_ek-tm4c123gxl/qk/gnu/.ccsproject @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/examples/arm-cm/dpp_ek-tm4c123gxl/qk/gnu/.cproject b/examples/arm-cm/dpp_ek-tm4c123gxl/qk/gnu/.cproject new file mode 100644 index 00000000..69187d2a --- /dev/null +++ b/examples/arm-cm/dpp_ek-tm4c123gxl/qk/gnu/.cproject @@ -0,0 +1,277 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/arm-cm/dpp_ek-tm4c123gxl/qk/gnu/.project b/examples/arm-cm/dpp_ek-tm4c123gxl/qk/gnu/.project new file mode 100644 index 00000000..13ddf88c --- /dev/null +++ b/examples/arm-cm/dpp_ek-tm4c123gxl/qk/gnu/.project @@ -0,0 +1,119 @@ + + + dpp-qk + + + + + + org.eclipse.cdt.managedbuilder.core.genmakebuilder + + + + + org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder + full,incremental, + + + + + + com.ti.ccstudio.core.ccsNature + org.eclipse.cdt.core.cnature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + org.eclipse.cdt.core.ccnature + org.eclipse.cdt.managedbuilder.core.ScannerConfigNature + + + + QK + 2 + PARENT-5-PROJECT_LOC/src/qk + + + QP + 2 + PARENT-5-PROJECT_LOC/src/qf + + + QP_port + 2 + PARENT-5-PROJECT_LOC/ports/arm-cm/qk/gnu + + + QS + 2 + PARENT-5-PROJECT_LOC/src/qs + + + TM4C123GH6PM.h + 1 + PARENT-5-PROJECT_LOC/3rd_party/ek-tm4c123gxl/TM4C123GH6PM.h + + + bsp.c + 1 + PARENT-1-PROJECT_LOC/bsp.c + + + bsp.h + 1 + PARENT-2-PROJECT_LOC/bsp.h + + + dpp.h + 1 + PARENT-2-PROJECT_LOC/dpp.h + + + gpio.h + 1 + PARENT-5-PROJECT_LOC/3rd_party/ek-tm4c123gxl/gpio.h + + + main.c + 1 + PARENT-1-PROJECT_LOC/main.c + + + philo.c + 1 + PARENT-2-PROJECT_LOC/philo.c + + + qstamp.c + 1 + PARENT-5-PROJECT_LOC/include/qstamp.c + + + rom.h + 1 + PARENT-5-PROJECT_LOC/3rd_party/ek-tm4c123gxl/rom.h + + + startup_TM4C123GH6PM.c + 1 + PARENT-5-PROJECT_LOC/3rd_party/ek-tm4c123gxl/gnu/startup_TM4C123GH6PM.c + + + sysctl.h + 1 + PARENT-5-PROJECT_LOC/3rd_party/ek-tm4c123gxl/sysctl.h + + + system_TM4C123GH6PM.c + 1 + PARENT-5-PROJECT_LOC/3rd_party/ek-tm4c123gxl/system_TM4C123GH6PM.c + + + system_TM4C123GH6PM.h + 1 + PARENT-5-PROJECT_LOC/3rd_party/ek-tm4c123gxl/system_TM4C123GH6PM.h + + + table.c + 1 + PARENT-2-PROJECT_LOC/table.c + + + diff --git a/examples/arm-cm/dpp_ek-tm4c123gxl/qk/gnu/Makefile b/examples/arm-cm/dpp_ek-tm4c123gxl/qk/gnu/Makefile index fa5f1e61..aa3c97ea 100644 --- a/examples/arm-cm/dpp_ek-tm4c123gxl/qk/gnu/Makefile +++ b/examples/arm-cm/dpp_ek-tm4c123gxl/qk/gnu/Makefile @@ -1,13 +1,13 @@ ############################################################################## # Product: Makefile for QP/C on EK-TM4C123GXL, QK kernel, GNU-ARM -# Last Updated for Version: 7.0.1 -# Date of the Last Update: 2022-05-23 +# Last Updated for Version: 7.3.0 +# Date of the Last Update: 2023-09-02 # # Q u a n t u m L e a P s # ------------------------ # Modern Embedded Software # -# Copyright (C) 2005-2021 Quantum Leaps, LLC. All rights reserved. +# Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. # # This program is open source software: you can redistribute it and/or # modify it under the terms of the GNU General Public License as published @@ -45,8 +45,7 @@ # NOTE: # To use this Makefile on Windows, you will need the GNU make utility, which # is included in the Qtools collection for Windows, see: -# https://sourceforge.net/projects/qpc/files/QTools/ -# +# https://github.com/QuantumLeaps/qtools #----------------------------------------------------------------------------- # project name @@ -78,6 +77,7 @@ VPATH = \ # list of all include directories needed by this project INCLUDES = \ + -I.. \ -I../.. \ -I$(QPC)/include \ -I$(QP_PORT_DIR) \ @@ -133,7 +133,7 @@ LIB_DIRS := LIBS := # defines -DEFINES := -DTARGET_IS_TM4C123_RB1 +DEFINES := -DQP_CONFIG # ARM CPU, ARCH, FPU, and Float-ABI types... # ARM_CPU: [cortex-m0 | cortex-m0plus | cortex-m1 | cortex-m3 | cortex-m4] @@ -163,12 +163,11 @@ AS := $(GNU_ARM)/bin/arm-none-eabi-as LINK := $(GNU_ARM)/bin/arm-none-eabi-gcc BIN := $(GNU_ARM)/bin/arm-none-eabi-objcopy - ############################################################################## -# Typically, you should not need to change anything below this line +# Typically you should not need to change anything below this line -# basic utilities (included in Qtools for Windows), see: -# http://sourceforge.net/projects/qpc/files/Qtools +# basic utilities (included in QTools for Windows), see: +# https://www.state-machine.com/qtools MKDIR := mkdir RM := rm @@ -189,11 +188,11 @@ ASFLAGS = $(ARM_CPU) $(ARM_FPU) $(ASM_CPU) $(ASM_FPU) CFLAGS = -c $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \ -ffunction-sections -fdata-sections \ - -O1 $(INCLUDES) $(DEFINES) -DNDEBUG + -O2 $(INCLUDES) $(DEFINES) -DNDEBUG CPPFLAGS = -c $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \ -ffunction-sections -fdata-sections -fno-rtti -fno-exceptions \ - -O1 $(INCLUDES) $(DEFINES) -DNDEBUG + -O2 $(INCLUDES) $(DEFINES) -DNDEBUG else ifeq (spy, $(CONF)) # Spy configuration ................................ @@ -232,7 +231,6 @@ LINKFLAGS = -T$(LD_SCRIPT) $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb \ -specs=nosys.specs -specs=nano.specs \ -Wl,-Map,$(BIN_DIR)/$(OUTPUT).map,--cref,--gc-sections $(LIB_DIRS) - ASM_OBJS := $(patsubst %.s,%.o, $(notdir $(ASM_SRCS))) C_OBJS := $(patsubst %.c,%.o, $(notdir $(C_SRCS))) CPP_OBJS := $(patsubst %.cpp,%.o,$(notdir $(CPP_SRCS))) @@ -254,14 +252,20 @@ endif # rules # -all: $(TARGET_BIN) -#all: $(TARGET_ELF) +.PHONY : run norun flash + +ifeq ($(MAKECMDGOALS),norun) +all : $(TARGET_BIN) +norun : all +else +all : $(TARGET_BIN) run +endif $(TARGET_BIN): $(TARGET_ELF) $(BIN) -O binary $< $@ $(TARGET_ELF) : $(ASM_OBJS_EXT) $(C_OBJS_EXT) $(CPP_OBJS_EXT) - $(CC) $(CFLAGS) $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o + $(CC) $(CFLAGS) $(QPC)/src/qs/qstamp.c -o $(BIN_DIR)/qstamp.o $(LINK) $(LINKFLAGS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) $(BIN_DIR)/%.d : %.c @@ -279,6 +283,8 @@ $(BIN_DIR)/%.o : %.c $(BIN_DIR)/%.o : %.cpp $(CPP) $(CPPFLAGS) $< -o $@ +.PHONY : clean show + # include dependency files only if our goal depends on their existence ifneq ($(MAKECMDGOALS),clean) ifneq ($(MAKECMDGOALS),show) @@ -287,7 +293,6 @@ ifneq ($(MAKECMDGOALS),clean) endif -.PHONY : clean clean: -$(RM) $(BIN_DIR)/*.o \ $(BIN_DIR)/*.d \ diff --git a/examples/arm-cm/dpp_ek-tm4c123gxl/qk/gnu_with-stack-prot/bsp_stack-prot.c b/examples/arm-cm/dpp_ek-tm4c123gxl/qk/gnu_with-stack-prot/bsp_stack-prot.c deleted file mode 100644 index 7f5c9dab..00000000 --- a/examples/arm-cm/dpp_ek-tm4c123gxl/qk/gnu_with-stack-prot/bsp_stack-prot.c +++ /dev/null @@ -1,462 +0,0 @@ -/***************************************************************************** -* Product: DPP example, EK-TM4C123GXL board, preemptive QK kernel -* Last updated for version 6.9.3 -* Last updated on 2021-03-03 -* -* Q u a n t u m L e a P s -* ------------------------ -* Modern Embedded Software -* -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* -* -*****************************************************************************/ -#include "qpc.h" -#include "dpp.h" -#include "bsp.h" - -#include "TM4C123GH6PM.h" /* the device specific header (TI) */ -#include "rom.h" /* the built-in ROM functions (TI) */ -#include "sysctl.h" /* system control driver (TI) */ -#include "gpio.h" /* GPIO driver (TI) */ -/* add other drivers if necessary... */ - -Q_DEFINE_THIS_FILE - -/* ISRs defined in this BSP ------------------------------------------------*/ -void SysTick_Handler(void); -void GPIOPortA_IRQHandler(void); -void UART0_IRQHandler(void); - -/* Local-scope objects -----------------------------------------------------*/ -#define LED_RED (1U << 1) -#define LED_BLUE (1U << 2) -#define LED_GREEN (1U << 3) - -#define BTN_SW1 (1U << 4) -#define BTN_SW2 (1U << 0) - -static uint32_t l_rnd; /* random seed */ - -#ifdef Q_SPY - - - QSTimeCtr QS_tickTime_; - QSTimeCtr QS_tickPeriod_; - - /* QSpy source IDs */ - static QSpyId const l_SysTick_Handler = { 0U }; - static QSpyId const l_GPIOPortA_IRQHandler = { 0U }; - - #define UART_BAUD_RATE 115200U - #define UART_FR_TXFE (1U << 7) - #define UART_FR_RXFE (1U << 4) - #define UART_TXFIFO_DEPTH 16U - - enum AppRecords { /* application-specific trace records */ - PHILO_STAT = QS_USER, - COMMAND_STAT - }; - -#endif - -/*..........................................................................*/ -void SysTick_Handler(void) { - /* state of the button debouncing, see below */ - static struct ButtonsDebouncing { - uint32_t depressed; - uint32_t previous; - } buttons = { 0U, 0U }; - uint32_t current; - uint32_t tmp; - - QK_ISR_ENTRY(); /* inform QK about entering an ISR */ - -#ifdef Q_SPY - { - tmp = SysTick->CTRL; /* clear SysTick_CTRL_COUNTFLAG */ - QS_tickTime_ += QS_tickPeriod_; /* account for the clock rollover */ - } -#endif - - QTIMEEVT_TICK_X(0U, &l_SysTick_Handler); /* process time events for rate 0 */ - - /* Perform the debouncing of buttons. The algorithm for debouncing - * adapted from the book "Embedded Systems Dictionary" by Jack Ganssle - * and Michael Barr, page 71. - */ - current = ~GPIOF->DATA_Bits[BTN_SW1 | BTN_SW2]; /* read SW1 and SW2 */ - tmp = buttons.depressed; /* save the debounced depressed buttons */ - buttons.depressed |= (buttons.previous & current); /* set depressed */ - buttons.depressed &= (buttons.previous | current); /* clear released */ - buttons.previous = current; /* update the history */ - tmp ^= buttons.depressed; /* changed debounced depressed */ - if ((tmp & BTN_SW1) != 0U) { /* debounced SW1 state changed? */ - if ((buttons.depressed & BTN_SW1) != 0U) { /* is SW1 depressed? */ - static QEvt const pauseEvt = { PAUSE_SIG, 0U, 0U}; - QACTIVE_PUBLISH(&pauseEvt, &l_SysTick_Handler); - } - else { /* the button is released */ - static QEvt const serveEvt = { SERVE_SIG, 0U, 0U}; - QACTIVE_PUBLISH(&serveEvt, &l_SysTick_Handler); - } - } - - QK_ISR_EXIT(); /* inform QK about exiting an ISR */ -} -/*..........................................................................*/ -void GPIOPortA_IRQHandler(void) { - QK_ISR_ENTRY(); /* inform QK about entering an ISR */ - - QACTIVE_POST(AO_Table, Q_NEW(QEvt, MAX_PUB_SIG), /* for testing... */ - &l_GPIOPortA_IRQHandler); - - QK_ISR_EXIT(); /* inform QK about exiting an ISR */ -} -/*..........................................................................*/ -#ifdef Q_SPY -/* -* ISR for receiving bytes from the QSPY Back-End -* NOTE: This ISR is "QF-unaware" meaning that it does not interact with -* the QF/QK and is not disabled. Such ISRs don't need to call QK_ISR_ENTRY/ -* QK_ISR_EXIT and they cannot post or publish events. -*/ -void UART0_IRQHandler(void) { - uint32_t status = UART0->RIS; /* get the raw interrupt status */ - UART0->ICR = status; /* clear the asserted interrupts */ - - while ((UART0->FR & UART_FR_RXFE) == 0) { /* while RX FIFO NOT empty */ - uint32_t b = UART0->DR; - QS_RX_PUT(b); - } - QK_ARM_ERRATUM_838869(); -} -#else -void UART0_IRQHandler(void) {} -#endif - -/*..........................................................................*/ -void BSP_init(void) { - /* NOTE: SystemInit() already called from the startup code - * but SystemCoreClock needs to be updated - */ - SystemCoreClockUpdate(); - - /* NOTE The VFP (hardware Floating Point) unit is configured by QK-port */ - - /* enable clock for to the peripherals used by this application... */ - SYSCTL->RCGCGPIO |= (1U << 5); /* enable Run mode for GPIOF */ - - /* configure the LEDs and push buttons */ - GPIOF->DIR |= (LED_RED | LED_GREEN | LED_BLUE);/* set direction: output */ - GPIOF->DEN |= (LED_RED | LED_GREEN | LED_BLUE); /* digital enable */ - GPIOF->DATA_Bits[LED_RED] = 0U; /* turn the LED off */ - GPIOF->DATA_Bits[LED_GREEN] = 0U; /* turn the LED off */ - GPIOF->DATA_Bits[LED_BLUE] = 0U; /* turn the LED off */ - - /* configure the Buttons */ - GPIOF->DIR &= ~(BTN_SW1 | BTN_SW2); /* set direction: input */ - ROM_GPIOPadConfigSet(GPIOF_BASE, (BTN_SW1 | BTN_SW2), - GPIO_STRENGTH_2MA, GPIO_PIN_TYPE_STD_WPU); - - BSP_randomSeed(1234U); - - if (QS_INIT((void *)0) == 0) { /* initialize the QS software tracing */ - Q_ERROR(); - } - QS_OBJ_DICTIONARY(&l_SysTick_Handler); - QS_OBJ_DICTIONARY(&l_GPIOPortA_IRQHandler); - QS_USR_DICTIONARY(PHILO_STAT); - QS_USR_DICTIONARY(COMMAND_STAT); -} -/*..........................................................................*/ -void BSP_displayPhilStat(uint8_t n, char const *stat) { - GPIOF->DATA_Bits[LED_RED] = ((stat[0] == 'h') ? LED_RED : 0U); - GPIOF->DATA_Bits[LED_GREEN] = ((stat[0] == 'e') ? LED_GREEN : 0U); - - QS_BEGIN_ID(PHILO_STAT, AO_Philo[n]->prio) /* app-specific record */ - QS_U8(1, n); /* Philosopher number */ - QS_STR(stat); /* Philosopher status */ - QS_END() -} -/*..........................................................................*/ -void BSP_displayPaused(uint8_t paused) { - GPIOF->DATA_Bits[LED_RED] = ((paused != 0U) ? LED_RED : 0U); -} -/*..........................................................................*/ -uint32_t BSP_random(void) { /* a very cheap pseudo-random-number generator */ - uint32_t rnd; - QSchedStatus lockStat; - - /* Some flating point code is to exercise the VFP... */ - float volatile x = 3.1415926F; - x = x + 2.7182818F; - - lockStat = QK_schedLock(N_PHILO); /* lock scheduler up to N_PHILO prio */ - /* "Super-Duper" Linear Congruential Generator (LCG) - * LCG(2^32, 3*7*11*13*23, 0, seed) - */ - rnd = l_rnd * (3U*7U*11U*13U*23U); - l_rnd = rnd; /* set for the next time */ - QK_schedUnlock(lockStat); /* unlock the scheduler */ - - return (rnd >> 8); -} -/*..........................................................................*/ -void BSP_randomSeed(uint32_t seed) { - l_rnd = seed; -} -/*..........................................................................*/ -void BSP_terminate(int16_t result) { - (void)result; -} - -/*..........................................................................*/ -void QF_onStartup(void) { - /* set up the SysTick timer to fire at BSP_TICKS_PER_SEC rate */ - SysTick_Config(SystemCoreClock / BSP_TICKS_PER_SEC); - - /* assing all priority bits for preemption-prio. and none to sub-prio. */ - NVIC_SetPriorityGrouping(0U); - - /* set priorities of ALL ISRs used in the system, see NOTE1 - * - * !!!!!!!!!!!!!!!!!!!!!!!!!!!! CAUTION !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - * Assign a priority to EVERY ISR explicitly by calling NVIC_SetPriority(). - * DO NOT LEAVE THE ISR PRIORITIES AT THE DEFAULT VALUE! - */ - NVIC_SetPriority(UART0_IRQn, 0U); /* kernel unaware interrupt */ - NVIC_SetPriority(GPIOA_IRQn, QF_AWARE_ISR_CMSIS_PRI); - NVIC_SetPriority(SysTick_IRQn, QF_AWARE_ISR_CMSIS_PRI + 1U); - /* ... */ - - /* enable IRQs... */ - NVIC_EnableIRQ(GPIOA_IRQn); - -#ifdef Q_SPY - NVIC_EnableIRQ(UART0_IRQn); /* UART0 interrupt used for QS-RX */ -#endif -} -/*..........................................................................*/ -void QF_onCleanup(void) { -} -/*..........................................................................*/ -void QK_onIdle(void) { - /* toggle the User LED on and then off, see NOTE2 */ - QF_INT_DISABLE(); - GPIOF->DATA_Bits[LED_BLUE] = LED_BLUE; /* turn the Blue LED on */ - GPIOF->DATA_Bits[LED_BLUE] = 0U; /* turn the Blue LED off */ - QF_INT_ENABLE(); - -#ifdef Q_SPY - QS_rxParse(); /* parse all the received bytes */ - - if ((UART0->FR & UART_FR_TXFE) != 0U) { /* TX done? */ - uint16_t fifo = UART_TXFIFO_DEPTH; /* max bytes we can accept */ - uint8_t const *block; - - QF_INT_DISABLE(); - block = QS_getBlock(&fifo); /* try to get next block to transmit */ - QF_INT_ENABLE(); - - while (fifo-- != 0) { /* any bytes in the block? */ - UART0->DR = *block++; /* put into the FIFO */ - } - } -#elif defined NDEBUG - /* Put the CPU and peripherals to the low-power mode. - * you might need to customize the clock management for your application, - * see the datasheet for your particular Cortex-M3 MCU. - */ - __WFI(); /* Wait-For-Interrupt */ -#endif -} - -/*..........................................................................*/ -Q_NORETURN Q_onAssert(char const * const module, int_t const loc) { - /* - * NOTE: add here your application-specific error handling - */ - (void)module; - (void)loc; - QS_ASSERTION(module, loc, 10000U); /* report assertion to QS */ - -#ifndef NDEBUG - /* for debugging, hang on in an endless loop toggling the RED LED... */ - while (GPIOF->DATA_Bits[BTN_SW1] != 0) { - GPIOF->DATA = LED_RED; - GPIOF->DATA = 0U; - } -#endif - - NVIC_SystemReset(); -} -/*..........................................................................*/ -void *__stack_chk_guard = (void *)0xDEADBEEF; -__attribute__((noreturn)) void __stack_chk_fail(void); -__attribute__((noreturn)) void __stack_chk_fail(void) { - Q_onAssert("Stack ERROR", 0); - for (;;) {} -} - -/* QS callbacks ============================================================*/ -#ifdef Q_SPY -/*..........................................................................*/ -uint8_t QS_onStartup(void const *arg) { - static uint8_t qsTxBuf[2*1024]; /* buffer for QS transmit channel */ - static uint8_t qsRxBuf[100]; /* buffer for QS receive channel */ - uint32_t tmp; - - QS_initBuf (qsTxBuf, sizeof(qsTxBuf)); - QS_rxInitBuf(qsRxBuf, sizeof(qsRxBuf)); - - /* enable clock for UART0 and GPIOA (used by UART0 pins) */ - SYSCTL->RCGCUART |= (1U << 0); /* enable Run mode for UART0 */ - SYSCTL->RCGCGPIO |= (1U << 0); /* enable Run mode for GPIOA */ - - /* configure UART0 pins for UART operation */ - tmp = (1U << 0) | (1U << 1); - GPIOA->DIR &= ~tmp; - GPIOA->SLR &= ~tmp; - GPIOA->ODR &= ~tmp; - GPIOA->PUR &= ~tmp; - GPIOA->PDR &= ~tmp; - GPIOA->AMSEL &= ~tmp; /* disable analog function on the pins */ - GPIOA->AFSEL |= tmp; /* enable ALT function on the pins */ - GPIOA->DEN |= tmp; /* enable digital I/O on the pins */ - GPIOA->PCTL &= ~0x00U; - GPIOA->PCTL |= 0x11U; - - /* configure the UART for the desired baud rate, 8-N-1 operation */ - tmp = (((SystemCoreClock * 8U) / UART_BAUD_RATE) + 1U) / 2U; - UART0->IBRD = tmp / 64U; - UART0->FBRD = tmp % 64U; - UART0->LCRH = (0x3U << 5); /* configure 8-N-1 operation */ - UART0->LCRH |= (0x1U << 4); /* enable FIFOs */ - UART0->CTL = (1U << 0) /* UART enable */ - | (1U << 8) /* UART TX enable */ - | (1U << 9); /* UART RX enable */ - - /* configure UART interrupts (for the RX channel) */ - UART0->IM |= (1U << 4) | (1U << 6); /* enable RX and RX-TO interrupt */ - UART0->IFLS |= (0x2U << 2); /* interrupt on RX FIFO half-full */ - /* NOTE: do not enable the UART0 interrupt yet. Wait till QF_onStartup() */ - - QS_tickPeriod_ = SystemCoreClock / BSP_TICKS_PER_SEC; - QS_tickTime_ = QS_tickPeriod_; /* to start the timestamp at zero */ - - /* setup the QS filters... */ - QS_GLB_FILTER(QS_ALL_RECORDS); - QS_GLB_FILTER(-QS_QF_TICK); - - return 1U; /* return success */ -} -/*..........................................................................*/ -void QS_onCleanup(void) { -} -/*..........................................................................*/ -QSTimeCtr QS_onGetTime(void) { /* NOTE: invoked with interrupts DISABLED */ - if ((SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk) == 0) { /* not set? */ - return QS_tickTime_ - (QSTimeCtr)SysTick->VAL; - } - else { /* the rollover occured, but the SysTick_ISR did not run yet */ - return QS_tickTime_ + QS_tickPeriod_ - (QSTimeCtr)SysTick->VAL; - } -} -/*..........................................................................*/ -void QS_onFlush(void) { - uint16_t fifo = UART_TXFIFO_DEPTH; /* Tx FIFO depth */ - uint8_t const *block; - QF_INT_DISABLE(); - while ((block = QS_getBlock(&fifo)) != (uint8_t *)0) { - QF_INT_ENABLE(); - /* busy-wait as long as TX FIFO has data to transmit */ - while ((UART0->FR & UART_FR_TXFE) == 0) { - } - - while (fifo-- != 0) { /* any bytes in the block? */ - UART0->DR = *block++; /* put into the TX FIFO */ - } - fifo = UART_TXFIFO_DEPTH; /* re-load the Tx FIFO depth */ - QF_INT_DISABLE(); - } - QF_INT_ENABLE(); -} -/*..........................................................................*/ -/*! callback function to reset the target (to be implemented in the BSP) */ -void QS_onReset(void) { - NVIC_SystemReset(); -} -/*..........................................................................*/ -/*! callback function to execute a user command (to be implemented in BSP) */ -void QS_onCommand(uint8_t cmdId, - uint32_t param1, uint32_t param2, uint32_t param3) -{ - void assert_failed(char const *module, int loc); - (void)cmdId; - (void)param1; - (void)param2; - (void)param3; - QS_BEGIN_ID(COMMAND_STAT, 0U) /* app-specific record */ - QS_U8(2, cmdId); - QS_U32(8, param1); - QS_U32(8, param2); - QS_U32(8, param3); - QS_END() - - if (cmdId == 10U) { - Q_ERROR(); - } - else if (cmdId == 11U) { - assert_failed("QS_onCommand", 123); - } -} - -#endif /* Q_SPY */ -/*--------------------------------------------------------------------------*/ - -/***************************************************************************** -* NOTE1: -* The QF_AWARE_ISR_CMSIS_PRI constant from the QF port specifies the highest -* ISR priority that is disabled by the QF framework. The value is suitable -* for the NVIC_SetPriority() CMSIS function. -* -* Only ISRs prioritized at or below the QF_AWARE_ISR_CMSIS_PRI level (i.e., -* with the numerical values of priorities equal or higher than -* QF_AWARE_ISR_CMSIS_PRI) are allowed to call the QK_ISR_ENTRY/QK_ISR_ENTRY -* macros or any other QF/QK services. These ISRs are "QF-aware". -* -* Conversely, any ISRs prioritized above the QF_AWARE_ISR_CMSIS_PRI priority -* level (i.e., with the numerical values of priorities less than -* QF_AWARE_ISR_CMSIS_PRI) are never disabled and are not aware of the kernel. -* Such "QF-unaware" ISRs cannot call any QF/QK services. In particular they -* can NOT call the macros QK_ISR_ENTRY/QK_ISR_ENTRY. The only mechanism -* by which a "QF-unaware" ISR can communicate with the QF framework is by -* triggering a "QF-aware" ISR, which can post/publish events. -* -* NOTE2: -* The User LED is used to visualize the idle loop activity. The brightness -* of the LED is proportional to the frequency of invcations of the idle loop. -* Please note that the LED is toggled with interrupts locked, so no interrupt -* execution time contributes to the brightness of the User LED. -*/ diff --git a/examples/arm-cm/dpp_ek-tm4c123gxl/qk/iar/dpp-qk.ewd b/examples/arm-cm/dpp_ek-tm4c123gxl/qk/iar/dpp-qk.ewd index 1587ed94..ddd36639 100644 --- a/examples/arm-cm/dpp_ek-tm4c123gxl/qk/iar/dpp-qk.ewd +++ b/examples/arm-cm/dpp_ek-tm4c123gxl/qk/iar/dpp-qk.ewd @@ -11,7 +11,7 @@ C-SPY 2 - 28 + 32 1 1 - - + + + + + @@ -486,7 +498,7 @@ IJET_ID 2 - 8 + 9 1 1 + + + + + + + + + + + + + @@ -916,7 +980,7 @@ LMIFTDI_ID 2 - 2 + 3 1 1 + + + + + + + NULINK_ID + 2 + + 0 + 1 + 1 + + + @@ -974,7 +1072,7 @@ STLINK_ID 2 - 4 + 8 1 1 + + + + @@ -1185,7 +1300,7 @@ XDS100_ID 2 - 6 + 9 1 1 + + + + @@ -1362,6 +1493,18 @@ $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin 0 + + $TOOLKIT_DIR$\plugins\rtos\FreeRtos\FreeRtosArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin2.ENU.ewplugin + 0 + $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin 0 @@ -1371,11 +1514,15 @@ 0 - $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9.ewplugin 0 - $TOOLKIT_DIR$\plugins\rtos\TI-RTOS\tirtosplugin.ewplugin + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9BE.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin 0 @@ -1391,11 +1538,11 @@ 0 - $EW_DIR$\common\plugins\CodeCoverage\CodeCoverage.ENU.ewplugin - 1 + $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + 0 - $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + $EW_DIR$\common\plugins\TargetAccessServer\TargetAccessServer.ENU.ewplugin 0 @@ -1414,7 +1561,7 @@ C-SPY 2 - 28 + 32 1 0 - - + + + + + @@ -1889,7 +2048,7 @@ IJET_ID 2 - 8 + 9 1 0 + + + + + + + + + + + + + @@ -2319,7 +2530,7 @@ LMIFTDI_ID 2 - 2 + 3 1 0 + + + + + + + NULINK_ID + 2 + + 0 + 1 + 0 + + + @@ -2377,7 +2622,7 @@ STLINK_ID 2 - 4 + 8 1 0 + + + + @@ -2588,7 +2850,7 @@ XDS100_ID 2 - 6 + 9 1 0 + + + + @@ -2765,6 +3043,18 @@ $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin 0 + + $TOOLKIT_DIR$\plugins\rtos\FreeRtos\FreeRtosArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin2.ENU.ewplugin + 0 + $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin 0 @@ -2774,11 +3064,15 @@ 0 - $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9.ewplugin 0 - $TOOLKIT_DIR$\plugins\rtos\TI-RTOS\tirtosplugin.ewplugin + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9BE.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin 0 @@ -2794,11 +3088,11 @@ 0 - $EW_DIR$\common\plugins\CodeCoverage\CodeCoverage.ENU.ewplugin - 1 + $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + 0 - $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + $EW_DIR$\common\plugins\TargetAccessServer\TargetAccessServer.ENU.ewplugin 0 @@ -2817,7 +3111,7 @@ C-SPY 2 - 28 + 32 1 1 - - + + + + + @@ -3292,7 +3598,7 @@ IJET_ID 2 - 8 + 9 1 1 + + + + + + + + + + + + + @@ -3722,7 +4080,7 @@ LMIFTDI_ID 2 - 2 + 3 1 1 + + + + + + + NULINK_ID + 2 + + 0 + 1 + 1 + + + @@ -3780,7 +4172,7 @@ STLINK_ID 2 - 4 + 8 1 1 + + + + @@ -3991,7 +4400,7 @@ XDS100_ID 2 - 6 + 9 1 1 + + + + @@ -4168,6 +4593,18 @@ $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin 0 + + $TOOLKIT_DIR$\plugins\rtos\FreeRtos\FreeRtosArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin2.ENU.ewplugin + 0 + $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin 0 @@ -4177,11 +4614,15 @@ 0 - $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9.ewplugin 0 - $TOOLKIT_DIR$\plugins\rtos\TI-RTOS\tirtosplugin.ewplugin + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9BE.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin 0 @@ -4197,11 +4638,11 @@ 0 - $EW_DIR$\common\plugins\CodeCoverage\CodeCoverage.ENU.ewplugin - 1 + $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + 0 - $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + $EW_DIR$\common\plugins\TargetAccessServer\TargetAccessServer.ENU.ewplugin 0 diff --git a/examples/arm-cm/dpp_ek-tm4c123gxl/qk/iar/dpp-qk.ewp b/examples/arm-cm/dpp_ek-tm4c123gxl/qk/iar/dpp-qk.ewp index 7a72fbe1..98272328 100644 --- a/examples/arm-cm/dpp_ek-tm4c123gxl/qk/iar/dpp-qk.ewp +++ b/examples/arm-cm/dpp_ek-tm4c123gxl/qk/iar/dpp-qk.ewp @@ -11,9 +11,13 @@ General 3 - 31 + 35 1 1 + - - - - - + + + + + ICCARM 2 - 36 + 37 1 1 - - - @@ -677,13 +669,9 @@ 0 + inputOutputBased - - BICOMP - 0 - - BUILDACTION 1 @@ -696,17 +684,13 @@ ILINK 0 - 23 + 27 1 1 - + + + + + + + + + @@ -1055,11 +1075,6 @@ - - BILINK - 0 - - Coder 0 @@ -1076,9 +1091,13 @@ General 3 - 31 + 35 1 0 + - - - - - + + + + + ICCARM 2 - 36 + 37 1 0 - - - @@ -1742,13 +1750,9 @@ 0 + inputOutputBased - - BICOMP - 0 - - BUILDACTION 1 @@ -1761,17 +1765,13 @@ ILINK 0 - 23 + 27 1 0 - + + + + + + + + + @@ -2120,11 +2156,6 @@ - - BILINK - 0 - - Coder 0 @@ -2141,9 +2172,13 @@ General 3 - 31 + 35 1 1 + - - - - - + + + + + ICCARM 2 - 36 + 37 1 1 - - - @@ -2807,13 +2831,9 @@ 0 + inputOutputBased - - BICOMP - 0 - - BUILDACTION 1 @@ -2826,17 +2846,13 @@ ILINK 0 - 23 + 27 1 1 - + + + + + + + + + @@ -3185,11 +3237,6 @@ - - BILINK - 0 - - Coder 0 @@ -3207,15 +3254,9 @@ $PROJ_DIR$\..\..\dpp.h - - $PROJ_DIR$\..\main.c - $PROJ_DIR$\..\..\philo.c - - $PROJ_DIR$\..\..\..\..\..\include\qstamp.c - $PROJ_DIR$\..\..\table.c @@ -3319,5 +3360,11 @@ $PROJ_DIR$\..\..\..\..\..\src\qs\qs_rx.c + + $PROJ_DIR$\..\..\..\..\..\src\qs\qstamp.c + + + $PROJ_DIR$\..\..\main.c + diff --git a/examples/arm-cm/dpp_ek-tm4c123gxl/qk/iar/dpp-qk.icf b/examples/arm-cm/dpp_ek-tm4c123gxl/qk/iar/dpp-qk.icf index 0fdfc4b3..c6b24e1c 100644 --- a/examples/arm-cm/dpp_ek-tm4c123gxl/qk/iar/dpp-qk.icf +++ b/examples/arm-cm/dpp_ek-tm4c123gxl/qk/iar/dpp-qk.icf @@ -25,5 +25,5 @@ do not initialize { section .noinit }; place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec }; place in ROM_region { readonly }; -place at start of RAM_region {block CSTACK }; +place at start of RAM_region {block CSTACK }; /* <== Quantum Leaps */ place in RAM_region { readwrite, block HEAP }; \ No newline at end of file diff --git a/examples/arm-cm/dpp_ek-tm4c123gxl/qk/main.c b/examples/arm-cm/dpp_ek-tm4c123gxl/qk/main.c deleted file mode 100644 index 9f87724f..00000000 --- a/examples/arm-cm/dpp_ek-tm4c123gxl/qk/main.c +++ /dev/null @@ -1,87 +0,0 @@ -/***************************************************************************** -* Product: DPP example -* Last updated for version 7.1.2 -* Last updated on 2022-09-22 -* -* Q u a n t u m L e a P s -* ------------------------ -* Modern Embedded Software -* -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* -* -*****************************************************************************/ -#include "qpc.h" -#include "dpp.h" -#include "bsp.h" - -Q_DEFINE_THIS_FILE - -/*..........................................................................*/ -int main() { - static QEvt const *tableQueueSto[N_PHILO]; - static QEvt const *philoQueueSto[N_PHILO][N_PHILO]; - static QSubscrList subscrSto[MAX_PUB_SIG]; - static QF_MPOOL_EL(TableEvt) smlPoolSto[2*N_PHILO]; /* small pool */ - - QF_init(); /* initialize the framework and the underlying RT kernel */ - BSP_init(); /* initialize the Board Support Package */ - - /* object dictionaries... */ - QS_OBJ_DICTIONARY(AO_Table); - QS_OBJ_DICTIONARY(AO_Philo[0]); - QS_OBJ_DICTIONARY(AO_Philo[1]); - QS_OBJ_DICTIONARY(AO_Philo[2]); - QS_OBJ_DICTIONARY(AO_Philo[3]); - QS_OBJ_DICTIONARY(AO_Philo[4]); - - /* initialize publish-subscribe... */ - QF_psInit(subscrSto, Q_DIM(subscrSto)); - - /* initialize event pools... */ - QF_poolInit(smlPoolSto, sizeof(smlPoolSto), sizeof(smlPoolSto[0])); - - /* start the active objects... */ - Philo_ctor(); /* instantiate all Philosopher active objects */ - for (uint8_t n = 0U; n < N_PHILO; ++n) { - QACTIVE_START(AO_Philo[n], /* AO to start */ - Q_PRIO(n + 2U, N_PHILO + 1U), /* QF-prio/pre-thre. */ - philoQueueSto[n], /* event queue storage */ - Q_DIM(philoQueueSto[n]), /* queue length [events] */ - (void *)0, /* stack storage (not used) */ - 0U, /* size of the stack [bytes] */ - (void *)0); /* initialization param */ - } - - Table_ctor(); /* instantiate the Table active object */ - QACTIVE_START(AO_Table, /* AO to start */ - N_PHILO + 2U, /* QF-prio/pre-thre. */ - tableQueueSto, /* event queue storage */ - Q_DIM(tableQueueSto), /* queue length [events] */ - (void *)0, /* stack storage (not used) */ - 0U, /* size of the stack [bytes] */ - (void *)0); /* initialization param */ - - return QF_run(); /* run the QF application */ -} - diff --git a/examples/arm-cm/dpp_ek-tm4c123gxl/qp_config.h b/examples/arm-cm/dpp_ek-tm4c123gxl/qp_config.h new file mode 100644 index 00000000..37aee512 --- /dev/null +++ b/examples/arm-cm/dpp_ek-tm4c123gxl/qp_config.h @@ -0,0 +1,59 @@ +//============================================================================ +// QP configuration file example +// Last updated for version: 7.3.0 +// Last updated on: 2023-09-07 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +//============================================================================ +#ifndef QP_CONFIG_H_ +#define QP_CONFIG_H_ + +// NOTE: +// The QP configuration takes effect only when the macro QP_CONFIG +// is defined on the command-line to the compiler for all QP source files. + +// use event constructors for dynamic events +#define QEVT_DYN_CTOR + +// for QK kernel: +// use the QEI1_IRQHandler() with IRQ number 38 +// for the QK return-from-preemption handler +#define QK_USE_IRQ_NUM 38 +#define QK_USE_IRQ_HANDLER QEI1_IRQHandler + +// for QXK kernel: +// use the QEI1_IRQHandler() with IRQ number 38 +// for the QXK return-from-preemption handler +#define QXK_USE_IRQ_NUM 38 +#define QXK_USE_IRQ_HANDLER QEI1_IRQHandler + +#ifdef Q_SPY +// for the Spy build configuration, enable the context-switch callback +#define QF_ON_CONTEXT_SW +#endif + +#endif // QP_CONFIG_H_ diff --git a/examples/arm-cm/dpp_ek-tm4c123gxl/qspy-output.png b/examples/arm-cm/dpp_ek-tm4c123gxl/qspy-output.png new file mode 100644 index 00000000..ee764450 Binary files /dev/null and b/examples/arm-cm/dpp_ek-tm4c123gxl/qspy-output.png differ diff --git a/examples/arm-cm/dpp_ek-tm4c123gxl/qube/Makefile b/examples/arm-cm/dpp_ek-tm4c123gxl/qube/Makefile index 541278ed..b3b074fd 100644 --- a/examples/arm-cm/dpp_ek-tm4c123gxl/qube/Makefile +++ b/examples/arm-cm/dpp_ek-tm4c123gxl/qube/Makefile @@ -101,6 +101,7 @@ endif C_SRCS += \ qep_hsm.c \ qep_msm.c \ + qf_act.c \ qf_actq.c \ qf_defer.c \ qf_dyn.c \ @@ -195,7 +196,7 @@ all: $(TARGET_EXE) $(TARGET_EXE) $(TARGET_EXE) : $(C_OBJS_EXT) $(CPP_OBJS_EXT) - $(CC) $(CFLAGS) $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o + $(CC) $(CFLAGS) $(QPC)/src/qs/qstamp.c -o $(BIN_DIR)/qstamp.o $(LINK) $(LINKFLAGS) $(LIB_DIRS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) $(BIN_DIR)/%.d : %.c diff --git a/examples/arm-cm/dpp_ek-tm4c123gxl/qube/bsp.c b/examples/arm-cm/dpp_ek-tm4c123gxl/qube/bsp.c index b5f36b21..2ebb49d6 100644 --- a/examples/arm-cm/dpp_ek-tm4c123gxl/qube/bsp.c +++ b/examples/arm-cm/dpp_ek-tm4c123gxl/qube/bsp.c @@ -4,62 +4,99 @@ //Q_DEFINE_THIS_FILE -enum AppRecords { /* application-specific trace records */ +enum AppRecords { // application-specific trace records PHILO_STAT = QS_USER, PAUSED_STAT, }; -static uint32_t l_rnd; /* random seed */ +static uint32_t l_rnd; // random seed -/*..........................................................................*/ +//............................................................................ void BSP_init(void) { - /* QS dictionaries... */ + // QS dictionaries... + QS_ONLY(produce_sig_dict()); QS_USR_DICTIONARY(PHILO_STAT); QS_USR_DICTIONARY(PAUSED_STAT); - /* QS filters... */ + // QS filters... QS_GLB_FILTER(QS_ALL_RECORDS); } -/*..........................................................................*/ +//............................................................................ +void BSP_start(void) { + // initialize event pools + static QF_MPOOL_EL(TableEvt) smlPoolSto[2*N_PHILO]; + QF_poolInit(smlPoolSto, sizeof(smlPoolSto), sizeof(smlPoolSto[0])); + + // initialize publish-subscribe + static QSubscrList subscrSto[MAX_PUB_SIG]; + QActive_psInit(subscrSto, Q_DIM(subscrSto)); + + // instantiate and start AOs/threads... + + static QEvt const *philoQueueSto[N_PHILO][10]; + for (uint8_t n = 0U; n < N_PHILO; ++n) { + Philo_ctor(n); + QACTIVE_START(AO_Philo[n], + + // NOTE: set the preemption-threshold of all Philos to + // the same level, so that they cannot preempt each other. + Q_PRIO(n + 3U, N_PHILO + 2U), // QF-prio/pre-thre. + + philoQueueSto[n], // event queue storage + Q_DIM(philoQueueSto[n]), // queue length [events] + (void *)0, 0U, // no stack storage + (void *)0); // no initialization param + } + + static QEvt const *tableQueueSto[N_PHILO]; + Table_ctor(); + QACTIVE_START(AO_Table, + N_PHILO + 7U, // QP prio. of the AO + tableQueueSto, // event queue storage + Q_DIM(tableQueueSto), // queue length [events] + (void *)0, 0U, // no stack storage + (void *)0); // no initialization param +} +//............................................................................ void BSP_displayPhilStat(uint8_t n, char const *stat) { - QS_BEGIN_ID(PHILO_STAT, AO_Philo[n]->prio) /* app-specific record */ - QS_U8(1, n); /* Philosopher number */ - QS_STR(stat); /* Philosopher status */ + QS_BEGIN_ID(PHILO_STAT, AO_Philo[n]->prio) // app-specific record + QS_U8(1, n); // Philosopher number + QS_STR(stat); // Philosopher status QS_END() } -/*..........................................................................*/ +//............................................................................ void BSP_displayPaused(uint8_t paused) { - QS_BEGIN_ID(PAUSED_STAT, 0U) /* app-specific record */ - QS_U8(1, paused); /* Paused status */ + QS_BEGIN_ID(PAUSED_STAT, 0U) // app-specific record + QS_U8(1, paused); // Paused status QS_END() } -/*..........................................................................*/ -uint32_t BSP_random(void) { /* a very cheap pseudo-random-number generator */ - /* Some flating point code is to exercise the VFP... */ +//............................................................................ +uint32_t BSP_random(void) { // a very cheap pseudo-random-number generator + // Some flating point code is to exercise the VFP... float volatile x = 3.1415926F; x = x + 2.7182818F; - /* lock scheduler around shared seed */ - /* "Super-Duper" Linear Congruential Generator (LCG) - * LCG(2^32, 3*7*11*13*23, 0, seed) - */ + // lock scheduler around shared seed + // "Super-Duper" Linear Congruential Generator (LCG) + // LCG(2^32, 3*7*11*13*23, 0, seed) + // l_rnd = l_rnd * (3U*7U*11U*13U*23U); return l_rnd >> 8; } -/*..........................................................................*/ +//............................................................................ void BSP_randomSeed(uint32_t seed) { l_rnd = seed; } -/*..........................................................................*/ +//............................................................................ void BSP_terminate(int16_t result) { (void)result; } -/*..........................................................................*/ -/*! callback function to generate an event for this application */ +//............................................................................ +//! callback function to generate an event for this application QEvt const* Qube_onGenEvt(QSignal sig, char const* params) { - Q_UNUSED_PAR(params); /* QHsmTst does not use params */ + Q_UNUSED_PAR(params); // QHsmTst does not use params static QEvt evt = { 0U, 0U, 0U }; evt.sig = sig; diff --git a/examples/arm-cm/dpp_ek-tm4c123gxl/qube/main.c b/examples/arm-cm/dpp_ek-tm4c123gxl/qube/main.c deleted file mode 100644 index 9f87724f..00000000 --- a/examples/arm-cm/dpp_ek-tm4c123gxl/qube/main.c +++ /dev/null @@ -1,87 +0,0 @@ -/***************************************************************************** -* Product: DPP example -* Last updated for version 7.1.2 -* Last updated on 2022-09-22 -* -* Q u a n t u m L e a P s -* ------------------------ -* Modern Embedded Software -* -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* -* -*****************************************************************************/ -#include "qpc.h" -#include "dpp.h" -#include "bsp.h" - -Q_DEFINE_THIS_FILE - -/*..........................................................................*/ -int main() { - static QEvt const *tableQueueSto[N_PHILO]; - static QEvt const *philoQueueSto[N_PHILO][N_PHILO]; - static QSubscrList subscrSto[MAX_PUB_SIG]; - static QF_MPOOL_EL(TableEvt) smlPoolSto[2*N_PHILO]; /* small pool */ - - QF_init(); /* initialize the framework and the underlying RT kernel */ - BSP_init(); /* initialize the Board Support Package */ - - /* object dictionaries... */ - QS_OBJ_DICTIONARY(AO_Table); - QS_OBJ_DICTIONARY(AO_Philo[0]); - QS_OBJ_DICTIONARY(AO_Philo[1]); - QS_OBJ_DICTIONARY(AO_Philo[2]); - QS_OBJ_DICTIONARY(AO_Philo[3]); - QS_OBJ_DICTIONARY(AO_Philo[4]); - - /* initialize publish-subscribe... */ - QF_psInit(subscrSto, Q_DIM(subscrSto)); - - /* initialize event pools... */ - QF_poolInit(smlPoolSto, sizeof(smlPoolSto), sizeof(smlPoolSto[0])); - - /* start the active objects... */ - Philo_ctor(); /* instantiate all Philosopher active objects */ - for (uint8_t n = 0U; n < N_PHILO; ++n) { - QACTIVE_START(AO_Philo[n], /* AO to start */ - Q_PRIO(n + 2U, N_PHILO + 1U), /* QF-prio/pre-thre. */ - philoQueueSto[n], /* event queue storage */ - Q_DIM(philoQueueSto[n]), /* queue length [events] */ - (void *)0, /* stack storage (not used) */ - 0U, /* size of the stack [bytes] */ - (void *)0); /* initialization param */ - } - - Table_ctor(); /* instantiate the Table active object */ - QACTIVE_START(AO_Table, /* AO to start */ - N_PHILO + 2U, /* QF-prio/pre-thre. */ - tableQueueSto, /* event queue storage */ - Q_DIM(tableQueueSto), /* queue length [events] */ - (void *)0, /* stack storage (not used) */ - 0U, /* size of the stack [bytes] */ - (void *)0); /* initialization param */ - - return QF_run(); /* run the QF application */ -} - diff --git a/examples/arm-cm/dpp_ek-tm4c123gxl/qv/armclang/dpp-qv.sct b/examples/arm-cm/dpp_ek-tm4c123gxl/qv/armclang/dpp-qv.sct new file mode 100644 index 00000000..458d5506 --- /dev/null +++ b/examples/arm-cm/dpp_ek-tm4c123gxl/qv/armclang/dpp-qv.sct @@ -0,0 +1,23 @@ +; ************************************************************* +; *** Scatter-Loading Description File generated by uVision *** +; +; Adapted by Quantum Leaps: +; added STACK as the first section in RW_STACK +; ************************************************************* + +LR_IROM1 0x00000000 0x00040000 { ; load region size_region + ER_IROM1 0x00000000 0x00040000 { ; load address = execution address + *.o (RESET, +First) + *(InRoot$$Sections) + .ANY (+RO) + .ANY (+XO) + } + + RW_STACK 0x20000000 { ; <== Quantum Leaps + * (STACK, +First) + } + RW_IRAM1 +0 (0x00008000 - 2048) { ; NOTE: assume STACK size 2048! + .ANY (+RW +ZI) + } +} + diff --git a/examples/arm-cm/dpp_ek-tm4c123gxl/qv/armclang/dpp-qv.uvoptx b/examples/arm-cm/dpp_ek-tm4c123gxl/qv/armclang/dpp-qv.uvoptx index 5e6acc5c..8364593c 100644 --- a/examples/arm-cm/dpp_ek-tm4c123gxl/qv/armclang/dpp-qv.uvoptx +++ b/examples/arm-cm/dpp_ek-tm4c123gxl/qv/armclang/dpp-qv.uvoptx @@ -143,12 +143,29 @@ -U0E2006F4 -O4622 -S4 -FO61 - + + + 0 + 0 + 319 + 1 +
1112
+ 0 + 0 + 0 + 0 + 0 + 1 + ..\..\..\..\..\3rd_party\ek-tm4c123gxl\arm\startup_TM4C123GH6PM.s + + \\dpp_qv\../../../../../3rd_party/ek-tm4c123gxl/arm/startup_TM4C123GH6PM.s\319 +
+
1 - 2 - 0x20000200 + 8 + 0x466 0 @@ -287,7 +304,7 @@ 1 0 0 - 8 + 19 @@ -685,19 +702,7 @@ 0 0 0 - ..\..\..\..\..\include\qstamp.c - qstamp.c - 0 - 0 - - - 1 - 7 - 1 - 0 - 0 - 0 - ..\main.c + ..\..\main.c main.c 0 0 @@ -712,7 +717,7 @@ 0 2 - 8 + 7 1 0 0 @@ -724,7 +729,7 @@ 2 - 9 + 8 5 0 0 @@ -736,7 +741,7 @@ 2 - 10 + 9 2 0 0 @@ -748,7 +753,7 @@ 2 - 11 + 10 5 0 0 @@ -760,7 +765,7 @@ 2 - 12 + 11 5 0 0 @@ -772,7 +777,7 @@ 2 - 13 + 12 5 0 0 @@ -784,7 +789,7 @@ 2 - 14 + 13 5 0 0 @@ -804,7 +809,7 @@ 0 3 - 15 + 14 1 0 0 @@ -816,7 +821,7 @@ 3 - 16 + 15 1 0 0 @@ -828,7 +833,7 @@ 3 - 17 + 16 1 0 0 @@ -840,7 +845,7 @@ 3 - 18 + 17 1 0 0 @@ -852,7 +857,7 @@ 3 - 19 + 18 1 0 0 @@ -864,7 +869,7 @@ 3 - 20 + 19 1 0 0 @@ -876,7 +881,7 @@ 3 - 21 + 20 1 0 0 @@ -888,7 +893,7 @@ 3 - 22 + 21 1 0 0 @@ -900,7 +905,7 @@ 3 - 23 + 22 1 0 0 @@ -912,7 +917,7 @@ 3 - 24 + 23 1 0 0 @@ -924,7 +929,7 @@ 3 - 25 + 24 1 0 0 @@ -936,7 +941,7 @@ 3 - 26 + 25 1 0 0 @@ -948,7 +953,7 @@ 3 - 27 + 26 1 0 0 @@ -968,7 +973,7 @@ 0 4 - 28 + 27 1 0 0 @@ -988,7 +993,7 @@ 0 5 - 29 + 28 1 0 0 @@ -1000,7 +1005,7 @@ 5 - 30 + 29 1 0 0 @@ -1012,7 +1017,7 @@ 5 - 31 + 30 1 0 0 @@ -1024,7 +1029,7 @@ 5 - 32 + 31 1 0 0 @@ -1034,6 +1039,18 @@ 0 0 + + 5 + 32 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qs\qstamp.c + qstamp.c + 0 + 0 + diff --git a/examples/arm-cm/dpp_ek-tm4c123gxl/qv/armclang/dpp-qv.uvprojx b/examples/arm-cm/dpp_ek-tm4c123gxl/qv/armclang/dpp-qv.uvprojx index 1e527e2b..19cb7dbb 100644 --- a/examples/arm-cm/dpp_ek-tm4c123gxl/qv/armclang/dpp-qv.uvprojx +++ b/examples/arm-cm/dpp_ek-tm4c123gxl/qv/armclang/dpp-qv.uvprojx @@ -337,7 +337,7 @@ 0 - __FPU_PRESENT + QP_CONFIG ..\..;..\..\..\..\..\include;..\..\..\..\..\ports\arm-cm\qv\armclang;..\..\..\..\..\3rd_party\CMSIS\Include;..\..\..\..\..\3rd_party\ek-tm4c123gxl @@ -361,7 +361,7 @@ - 1 + 0 0 0 0 @@ -370,7 +370,7 @@ 0x00000000 0x20000000 - + .\dpp-qv.sct --entry Reset_Handler @@ -408,15 +408,10 @@ 1 ..\..\table.c - - qstamp.c - 1 - ..\..\..\..\..\include\qstamp.c - main.c 1 - ..\main.c + ..\..\main.c @@ -632,6 +627,11 @@ 1 ..\..\..\..\..\src\qs\qs_rx.c + + qstamp.c + 1 + ..\..\..\..\..\src\qs\qstamp.c + @@ -640,7 +640,7 @@ dpp-rel 0x4 ARM-ADS - 6070000::V6.7::.\ARMCLANG + 6160000::V6.16::ARMCLANG 1 @@ -962,12 +962,12 @@ 3 0 0 - 0 + 1 0 0 - NDEBUG __FPU_PRESENT + NDEBUG,QP_CONFIG ..\..;..\..\..\..\..\include;..\..\..\..\..\ports\arm-cm\qv\armclang;..\..\..\..\..\3rd_party\CMSIS\Include;..\..\..\..\..\3rd_party\ek-tm4c123gxl @@ -991,7 +991,7 @@ - 1 + 0 0 0 0 @@ -1000,7 +1000,7 @@ 0x00000000 0x20000000 - dpp-qv.sct + .\dpp-qv.sct --entry Reset_Handler @@ -1038,15 +1038,10 @@ 1 ..\..\table.c - - qstamp.c - 1 - ..\..\..\..\..\include\qstamp.c - main.c 1 - ..\main.c + ..\..\main.c @@ -1262,6 +1257,11 @@ 1 ..\..\..\..\..\src\qs\qs_rx.c + + qstamp.c + 1 + ..\..\..\..\..\src\qs\qstamp.c + @@ -1597,7 +1597,7 @@ 0 - Q_SPY __FPU_PRESENT + Q_SPY,QP_CONFIG ..\..;..\..\..\..\..\include;..\..\..\..\..\ports\arm-cm\qv\armclang;..\..\..\..\..\3rd_party\CMSIS\Include;..\..\..\..\..\3rd_party\ek-tm4c123gxl @@ -1621,7 +1621,7 @@ - 1 + 0 0 0 0 @@ -1630,7 +1630,7 @@ 0x00000000 0x20000000 - + .\dpp-qv.sct --entry Reset_Handler @@ -1668,15 +1668,10 @@ 1 ..\..\table.c - - qstamp.c - 1 - ..\..\..\..\..\include\qstamp.c - main.c 1 - ..\main.c + ..\..\main.c @@ -1823,6 +1818,11 @@ 1 ..\..\..\..\..\src\qs\qs_rx.c + + qstamp.c + 1 + ..\..\..\..\..\src\qs\qstamp.c + diff --git a/examples/arm-cm/dpp_ek-tm4c123gxl/qv/bsp.c b/examples/arm-cm/dpp_ek-tm4c123gxl/qv/bsp.c index b27e911d..d404652d 100644 --- a/examples/arm-cm/dpp_ek-tm4c123gxl/qv/bsp.c +++ b/examples/arm-cm/dpp_ek-tm4c123gxl/qv/bsp.c @@ -1,565 +1,527 @@ -/***************************************************************************** -* Product: DPP example, EK-TM4C123GXL board, cooperative QV kernel -* Last updated for version 7.2.0 -* Last updated on 2022-12-17 -* -* Q u a n t u m L e a P s -* ------------------------ -* Modern Embedded Software -* -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* -* -*****************************************************************************/ -#include "qpc.h" -#include "dpp.h" -#include "bsp.h" +//============================================================================ +// Product: DPP example, EK-TM4C123GXL board, QV kernel +// Last updated for version 7.3.0 +// Last updated on 2023-08-15 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. +// +// This program is open source software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Alternatively, this program may be distributed and modified under the +// terms of Quantum Leaps commercial licenses, which expressly supersede +// the GNU General Public License and are specifically designed for +// licensees interested in retaining the proprietary status of their code. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Contact information: +// +// +//============================================================================ +#include "qpc.h" // QP/C real-time embedded framework +#include "dpp.h" // DPP Application interface +#include "bsp.h" // Board Support Package -#include "TM4C123GH6PM.h" /* the device specific header (TI) */ -#include "rom.h" /* the built-in ROM functions (TI) */ -#include "sysctl.h" /* system control driver (TI) */ -#include "gpio.h" /* GPIO driver (TI) */ -/* add other drivers if necessary... */ +#include "TM4C123GH6PM.h" // the device specific header (TI) +#include "rom.h" // the built-in ROM functions (TI) +#include "sysctl.h" // system control driver (TI) +#include "gpio.h" // GPIO driver (TI) +// add other drivers if necessary... -Q_DEFINE_THIS_FILE /* define the name of this file for assertions */ +Q_DEFINE_THIS_FILE // define the name of this file for assertions -/* prototypes of ISRs defined in this BSP ----------------------------------*/ -void SysTick_Handler(void); -void GPIOPortA_IRQHandler(void); -void UART0_IRQHandler(void); +// Local-scope objects ----------------------------------------------------- +// LEDs on the board +#define LED_RED (1U << 1U) +#define LED_GREEN (1U << 3U) +#define LED_BLUE (1U << 2U) -/* Local-scope objects -----------------------------------------------------*/ -#define LED_RED (1U << 1) -#define LED_GREEN (1U << 3) -#define LED_BLUE (1U << 2) +// Buttons on the board +#define BTN_SW1 (1U << 4U) +#define BTN_SW2 (1U << 0U) -#define BTN_SW1 (1U << 4) -#define BTN_SW2 (1U << 0) - -static uint32_t l_rnd; /* random seed */ +static uint32_t l_rndSeed; #ifdef Q_SPY - /* QSpy source IDs */ + // QSpy source IDs static QSpyId const l_SysTick_Handler = { 0U }; static QSpyId const l_GPIOPortA_IRQHandler = { 0U }; #define UART_BAUD_RATE 115200U - #define UART_FR_TXFE (1U << 7) - #define UART_FR_RXFE (1U << 4) + #define UART_FR_TXFE (1U << 7U) + #define UART_FR_RXFE (1U << 4U) #define UART_TXFIFO_DEPTH 16U - enum AppRecords { /* application-specific trace records */ + enum AppRecords { // application-specific trace records PHILO_STAT = QS_USER, PAUSED_STAT, CONTEXT_SW, - COMMAND_STAT }; #endif -/*..........................................................................*/ -void SysTick_Handler(void) { - /* process time events for clock rate 0 */ - QTIMEEVT_TICK_X(0U, &l_SysTick_Handler); +//============================================================================ +// Error handler and ISRs... - /* Perform the debouncing of buttons. The algorithm for debouncing - * adapted from the book "Embedded Systems Dictionary" by Jack Ganssle - * and Michael Barr, page 71. - */ - /* state of the button debouncing, see below */ - static struct ButtonsDebouncing { +Q_NORETURN Q_onError(char const * const module, int_t const id) { + // NOTE: this implementation of the error handler is intended only + // for debugging and MUST be changed for deployment of the application + // (assuming that you ship your production code with assertions enabled). + Q_UNUSED_PAR(module); + Q_UNUSED_PAR(id); + QS_ASSERTION(module, id, 10000U); // report assertion to QS + +#ifndef NDEBUG + // light up all LEDs + GPIOF_AHB->DATA_Bits[LED_GREEN | LED_RED | LED_BLUE] = 0xFFU; + for (;;) { // for debugging, hang on in an endless loop... + } +#else + NVIC_SystemReset(); + for (;;) { // explicitly "no-return" + } +#endif +} +//............................................................................ +void assert_failed(char const * const module, int_t const id); // prototype +void assert_failed(char const * const module, int_t const id) { + Q_onError(module, id); +} + +// ISRs used in the application ============================================ + +void SysTick_Handler(void); // prototype +void SysTick_Handler(void) { + QTIMEEVT_TICK_X(0U, &l_SysTick_Handler); // time events at rate 0 + + // Perform the debouncing of buttons. The algorithm for debouncing + // adapted from the book "Embedded Systems Dictionary" by Jack Ganssle + // and Michael Barr, page 71. + static struct { uint32_t depressed; uint32_t previous; } buttons = { 0U, 0U }; - uint32_t current = ~GPIOF_AHB->DATA_Bits[BTN_SW1 | BTN_SW2]; /* read SW1&SW2 */ - uint32_t tmp = buttons.depressed; /* save debounced depressed buttons */ - buttons.depressed |= (buttons.previous & current); /* set depressed */ - buttons.depressed &= (buttons.previous | current); /* clear released */ - buttons.previous = current; /* update the history */ - tmp ^= buttons.depressed; /* changed debounced depressed */ - if ((tmp & BTN_SW1) != 0U) { /* debounced SW1 state changed? */ - if ((buttons.depressed & BTN_SW1) != 0U) { /* is SW1 depressed? */ - static QEvt const pauseEvt = { PAUSE_SIG, 0U, 0U}; + + uint32_t current = ~GPIOF_AHB->DATA_Bits[BTN_SW1 | BTN_SW2]; + uint32_t tmp = buttons.depressed; // save debounced depressed buttons + buttons.depressed |= (buttons.previous & current); // set depressed + buttons.depressed &= (buttons.previous | current); // clear released + buttons.previous = current; // update the history + tmp ^= buttons.depressed; // changed debounced depressed + current = buttons.depressed; + + if ((tmp & BTN_SW1) != 0U) { // debounced SW1 state changed? + if ((current & BTN_SW1) != 0U) { // is SW1 depressed? + static QEvt const pauseEvt = QEVT_INITIALIZER(PAUSE_SIG); QACTIVE_PUBLISH(&pauseEvt, &l_SysTick_Handler); } - else { /* the button is released */ - static QEvt const serveEvt = { SERVE_SIG, 0U, 0U}; + else { // the button is released + static QEvt const serveEvt = QEVT_INITIALIZER(SERVE_SIG); QACTIVE_PUBLISH(&serveEvt, &l_SysTick_Handler); } } - if ((tmp & BTN_SW2) != 0U) { /* debounced SW2 state changed? */ - /* TEST: of MPU */ - uint32_t volatile foo = *(uint32_t volatile *)0x204U; // legal - *(uint32_t volatile *)0x204U = foo; // illegal - } -} -/*..........................................................................*/ -void GPIOPortA_IRQHandler(void) { - QACTIVE_POST(AO_Table, Q_NEW(QEvt, MAX_PUB_SIG), /* for testing... */ - &l_GPIOPortA_IRQHandler); -} -/*..........................................................................*/ -#ifdef Q_SPY -/* -* ISR for receiving bytes from the QSPY Back-End -* NOTE: This ISR is "QF-unaware" meaning that it does not interact with -* the QF/QK and is not disabled. Such ISRs don't need to call QK_ISR_ENTRY/ -* QK_ISR_EXIT and they cannot post or publish events. -*/ -void UART0_IRQHandler(void) { - uint32_t status = UART0->RIS; /* get the raw interrupt status */ - UART0->ICR = status; /* clear the asserted interrupts */ - while ((UART0->FR & UART_FR_RXFE) == 0) { /* while RX FIFO NOT empty */ - uint32_t b = UART0->DR; - QS_RX_PUT(b); - } QV_ARM_ERRATUM_838869(); } -#else -void UART0_IRQHandler(void) {} -#endif +//............................................................................ +// interrupt handler for testing preemptions in QXK +void GPIOPortA_IRQHandler(void); // prototype +void GPIOPortA_IRQHandler(void) { + QEvt const testEvt = QEVT_INITIALIZER(MAX_PUB_SIG); + QACTIVE_POST(AO_Table, &testEvt, + &l_GPIOPortA_IRQHandler); -/* BSP functions ===========================================================*/ -/* MPU setup for TM4C123GXL MCU */ -static void TM4C123GXL_MPU_setup(void) { - /* The following MPU configuration contains the general TM4C memory map. - * - * Please note that the actual TM4C MCUs provide much less Flash and SRAM - * than the maximums configured here. This means that actual MCUs have - * unmapped memory regions (e.g., beyond the actual SRAM). Attempts to - * access these regions causes the HardFault exception, which is the - * desired behavior. - */ - static struct { - uint32_t rbar; - uint32_t rasr; - } const mpu_setup[] = { - { /* region #0: Flash: base=0x0000'0000, size=512M=2^(28+1) */ - 0x00000000U /* base address */ - | MPU_RBAR_VALID_Msk /* valid region */ - | (MPU_RBAR_REGION_Msk & 0U), /* region #0 */ - (28U << MPU_RASR_SIZE_Pos) /* 2^(18+1) region */ - | (0x6U << MPU_RASR_AP_Pos) /* PA:ro/UA:ro */ - | (1U << MPU_RASR_C_Pos) /* C=1 */ - | MPU_RASR_ENABLE_Msk /* region enable */ - }, - - { /* region #1: SRAM: base=0x2000'0000, size=512M=2^(28+1) */ - 0x20000000U /* base address */ - | MPU_RBAR_VALID_Msk /* valid region */ - | (MPU_RBAR_REGION_Msk & 1U), /* region #1 */ - (28U << MPU_RASR_SIZE_Pos) /* 2^(28+1) region */ - | (0x3U << MPU_RASR_AP_Pos) /* PA:rw/UA:rw */ - | (1U << MPU_RASR_XN_Pos) /* XN=1 */ - | (1U << MPU_RASR_S_Pos) /* S=1 */ - | (1U << MPU_RASR_C_Pos) /* C=1 */ - | MPU_RASR_ENABLE_Msk /* region enable */ - }, - - /* region #3: (not configured) */ - { MPU_RBAR_VALID_Msk | (MPU_RBAR_REGION_Msk & 2U), 0U }, - - { /* region #3: Peripherals: base=0x4000'0000, size=512M=2^(28+1) */ - 0x40000000U /* base address */ - | MPU_RBAR_VALID_Msk /* valid region */ - | (MPU_RBAR_REGION_Msk & 3U), /* region #3 */ - (28U << MPU_RASR_SIZE_Pos) /* 2^(28+1) region */ - | (0x3U << MPU_RASR_AP_Pos) /* PA:rw/UA:rw */ - | (1U << MPU_RASR_XN_Pos) /* XN=1 */ - | (1U << MPU_RASR_S_Pos) /* S=1 */ - | (1U << MPU_RASR_B_Pos) /* B=1 */ - | MPU_RASR_ENABLE_Msk /* region enable */ - }, - - { /* region #4: Priv. Periph: base=0xE000'0000, size=512M=2^(28+1) */ - 0xE0000000U /* base address */ - | MPU_RBAR_VALID_Msk /* valid region */ - | (MPU_RBAR_REGION_Msk & 4U), /* region #4 */ - (28U << MPU_RASR_SIZE_Pos) /* 2^(28+1) region */ - | (0x3U << MPU_RASR_AP_Pos) /* PA:rw/UA:rw */ - | (1U << MPU_RASR_XN_Pos) /* XN=1 */ - | (1U << MPU_RASR_S_Pos) /* S=1 */ - | (1U << MPU_RASR_B_Pos) /* B=1 */ - | MPU_RASR_ENABLE_Msk /* region enable */ - }, - - { /* region #5: Ext RAM: base=0x6000'0000, size=1G=2^(29+1) */ - 0x60000000U /* base address */ - | MPU_RBAR_VALID_Msk /* valid region */ - | (MPU_RBAR_REGION_Msk & 5U), /* region #5 */ - (29U << MPU_RASR_SIZE_Pos) /* 2^(28+1) region */ - | (0x3U << MPU_RASR_AP_Pos) /* PA:rw/UA:rw */ - | (1U << MPU_RASR_XN_Pos) /* XN=1 */ - | (1U << MPU_RASR_S_Pos) /* S=1 */ - | (1U << MPU_RASR_B_Pos) /* B=1 */ - | MPU_RASR_ENABLE_Msk /* region enable */ - }, - - { /* region #6: Ext Dev: base=0xA000'0000, size=1G=2^(29+1) */ - 0xA0000000U /* base address */ - | MPU_RBAR_VALID_Msk /* valid region */ - | (MPU_RBAR_REGION_Msk & 6U), /* region #6 */ - (29U << MPU_RASR_SIZE_Pos) /* 2^(28+1) region */ - | (0x3U << MPU_RASR_AP_Pos) /* PA:rw/UA:rw */ - | (1U << MPU_RASR_XN_Pos) /* XN=1 */ - | (1U << MPU_RASR_S_Pos) /* S=1 */ - | (1U << MPU_RASR_B_Pos) /* B=1 */ - | MPU_RASR_ENABLE_Msk /* region enable */ - }, - - { /* region #7: NULL-pointer: base=0x000'0000, size=256B */ - 0x00000000U /* base address */ - | MPU_RBAR_VALID_Msk /* valid region */ - | (MPU_RBAR_REGION_Msk & 7U), /* region #7 */ - (7U << MPU_RASR_SIZE_Pos) /* 2^(7+1)=256B region */ - | (0x0U << MPU_RASR_AP_Pos) /* PA:na/UA:na */ - | (1U << MPU_RASR_XN_Pos) /* XN=1 */ - | MPU_RASR_ENABLE_Msk /* region enable */ - }, - }; - - /* enable the MemManage_Handler for MPU exception */ - SCB->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk; - - __DSB(); - MPU->CTRL = 0U; /* disable the MPU */ - for (uint_fast8_t n = 0U; n < Q_DIM(mpu_setup); ++n) { - MPU->RBAR = mpu_setup[n].rbar; - MPU->RASR = mpu_setup[n].rasr; - } - MPU->CTRL = MPU_CTRL_ENABLE_Msk; /* enable the MPU */ - __ISB(); - __DSB(); + QV_ARM_ERRATUM_838869(); } -/*..........................................................................*/ +//............................................................................ +#ifdef Q_SPY +// ISR for receiving bytes from the QSPY Back-End +// NOTE: This ISR is "QF-unaware" meaning that it does not interact with +// the QF/QV and is not disabled. Such ISRs cannot post or publish events. + +void UART0_IRQHandler(void); // prototype +void UART0_IRQHandler(void) { + uint32_t status = UART0->RIS; // get the raw interrupt status + UART0->ICR = status; // clear the asserted interrupts + + while ((UART0->FR & UART_FR_RXFE) == 0U) { // while RX FIFO NOT empty + uint8_t b = (uint8_t)UART0->DR; + QS_rxPut(b); + } + + QV_ARM_ERRATUM_838869(); +} +#endif // Q_SPY + +//............................................................................ +#ifdef QF_ON_CONTEXT_SW +// NOTE: the context-switch callback is called with interrupts DISABLED +void QF_onContextSw(QActive *prev, QActive *next) { + QS_BEGIN_INCRIT(CONTEXT_SW, 0U) // in critical section! + QS_OBJ(prev); + QS_OBJ(next); + QS_END_INCRIT() +} +#endif // QF_ON_CONTEXT_SW + +//============================================================================ +// BSP functions... + void BSP_init(void) { - /* setup the MPU... */ - TM4C123GXL_MPU_setup(); - - /* NOTE: SystemInit() already called from the startup code - * but SystemCoreClock needs to be updated - */ - SystemCoreClockUpdate(); - - /* NOTE: The VFP (hardware Floating Point) unit is configured by QV */ - - /* enable clock for to the peripherals used by this application... */ - SYSCTL->RCGCGPIO |= (1U << 5); /* enable Run mode for GPIOF */ - SYSCTL->GPIOHBCTL |= (1U << 5); /* enable AHB for GPIOF */ + // Configure the MPU to prevent NULL-pointer dereferencing ... + MPU->RBAR = 0x0U // base address (NULL) + | MPU_RBAR_VALID_Msk // valid region + | (MPU_RBAR_REGION_Msk & 7U); // region #7 + MPU->RASR = (7U << MPU_RASR_SIZE_Pos) // 2^(7+1) region + | (0x0U << MPU_RASR_AP_Pos) // no-access region + | MPU_RASR_ENABLE_Msk; // region enable + MPU->CTRL = MPU_CTRL_PRIVDEFENA_Msk // enable background region + | MPU_CTRL_ENABLE_Msk; // enable the MPU __ISB(); __DSB(); - /* configure LEDs (digital output) */ + // enable the MemManage_Handler for MPU exception + SCB->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk; + + // NOTE: SystemInit() has been already called from the startup code + // but SystemCoreClock needs to be updated + SystemCoreClockUpdate(); + + // NOTE: The VFP (hardware Floating Point) unit is configured by QV + + // enable clock for to the peripherals used by this application... + SYSCTL->RCGCGPIO |= (1U << 5U); // enable Run mode for GPIOF + SYSCTL->GPIOHBCTL |= (1U << 5U); // enable AHB for GPIOF + __ISB(); + __DSB(); + + // configure LEDs (digital output) GPIOF_AHB->DIR |= (LED_RED | LED_BLUE | LED_GREEN); GPIOF_AHB->DEN |= (LED_RED | LED_BLUE | LED_GREEN); GPIOF_AHB->DATA_Bits[LED_RED | LED_BLUE | LED_GREEN] = 0U; - /* configure switches... */ + // configure switches... - /* unlock access to the SW2 pin because it is PROTECTED */ - GPIOF_AHB->LOCK = 0x4C4F434BU; /* unlock GPIOCR register for SW2 */ - /* commit the write (cast const away) */ + // unlock access to the SW2 pin because it is PROTECTED + GPIOF_AHB->LOCK = 0x4C4F434BU; // unlock GPIOCR register for SW2 + // commit the write (cast const away) *(uint32_t volatile *)&GPIOF_AHB->CR = 0x01U; - GPIOF_AHB->DIR &= ~(BTN_SW1 | BTN_SW2); /* input */ - GPIOF_AHB->DEN |= (BTN_SW1 | BTN_SW2); /* digital enable */ - GPIOF_AHB->PUR |= (BTN_SW1 | BTN_SW2); /* pull-up resistor enable */ + GPIOF_AHB->DIR &= ~(BTN_SW1 | BTN_SW2); // input + GPIOF_AHB->DEN |= (BTN_SW1 | BTN_SW2); // digital enable + GPIOF_AHB->PUR |= (BTN_SW1 | BTN_SW2); // pull-up resistor enable *(uint32_t volatile *)&GPIOF_AHB->CR = 0x00U; - GPIOF_AHB->LOCK = 0x0; /* lock GPIOCR register for SW2 */ + GPIOF_AHB->LOCK = 0x0; // lock GPIOCR register for SW2 - /* seed the random number generator */ + BSP_randomSeed(1234U); // seed the random number generator BSP_randomSeed(1234U); - /* initialize the QS software tracing... */ - if (QS_INIT((void *)0) == 0U) { + // initialize the QS software tracing... + if (!QS_INIT((void *)0)) { Q_ERROR(); } + + // dictionaries... QS_OBJ_DICTIONARY(&l_SysTick_Handler); QS_OBJ_DICTIONARY(&l_GPIOPortA_IRQHandler); QS_USR_DICTIONARY(PHILO_STAT); QS_USR_DICTIONARY(PAUSED_STAT); - QS_USR_DICTIONARY(COMMAND_STAT); + QS_USR_DICTIONARY(CONTEXT_SW); - /* setup the QS filters... */ - QS_GLB_FILTER(QS_ALL_RECORDS); /* all records */ - QS_GLB_FILTER(-QS_QF_TICK); /* exclude the clock tick */ + QS_ONLY(produce_sig_dict()); + + // setup the QS filters... + QS_GLB_FILTER(QS_ALL_RECORDS); // all records + QS_GLB_FILTER(-QS_QF_TICK); // exclude the clock tick } -/*..........................................................................*/ +//............................................................................ +void BSP_start(void) { + // initialize event pools + static QF_MPOOL_EL(TableEvt) smlPoolSto[2*N_PHILO]; + QF_poolInit(smlPoolSto, sizeof(smlPoolSto), sizeof(smlPoolSto[0])); + + // initialize publish-subscribe + static QSubscrList subscrSto[MAX_PUB_SIG]; + QActive_psInit(subscrSto, Q_DIM(subscrSto)); + + // instantiate and start AOs/threads... + + static QEvt const *philoQueueSto[N_PHILO][10]; + for (uint8_t n = 0U; n < N_PHILO; ++n) { + Philo_ctor(n); + QACTIVE_START(AO_Philo[n], + n + 3U, // QF-prio. + philoQueueSto[n], // event queue storage + Q_DIM(philoQueueSto[n]), // queue length [events] + (void *)0, 0U, // no stack storage + (void *)0); // no initialization param + } + + static QEvt const *tableQueueSto[N_PHILO]; + Table_ctor(); + QACTIVE_START(AO_Table, + N_PHILO + 7U, // QP prio. of the AO + tableQueueSto, // event queue storage + Q_DIM(tableQueueSto), // queue length [events] + (void *)0, 0U, // no stack storage + (void *)0); // no initialization param +} +//............................................................................ void BSP_displayPhilStat(uint8_t n, char const *stat) { + Q_UNUSED_PAR(n); + GPIOF_AHB->DATA_Bits[LED_GREEN] = ((stat[0] == 'e') ? LED_GREEN : 0U); - QS_BEGIN_ID(PHILO_STAT, AO_Philo[n]->prio) /* app-specific record */ - QS_U8(1, n); /* Philosopher number */ - QS_STR(stat); /* Philosopher status */ + // app-specific trace record... + QS_BEGIN_ID(PHILO_STAT, AO_Table->prio) + QS_U8(1, n); // Philosopher number + QS_STR(stat); // Philosopher status QS_END() } -/*..........................................................................*/ -void BSP_displayPaused(uint8_t paused) { +//............................................................................ +void BSP_displayPaused(uint8_t const paused) { GPIOF_AHB->DATA_Bits[LED_BLUE] = ((paused != 0U) ? LED_BLUE : 0U); - QS_BEGIN_ID(PAUSED_STAT, 0U) /* app-specific record */ - QS_U8(1, paused); /* Paused status */ + // application-specific trace record + QS_BEGIN_ID(PAUSED_STAT, AO_Table->prio) + QS_U8(1, paused); // Paused status QS_END() } -/*..........................................................................*/ -uint32_t BSP_random(void) { /* a very cheap pseudo-random-number generator */ - /* Some flating point code is to exercise the VFP... */ +//............................................................................ +void BSP_randomSeed(uint32_t seed) { + l_rndSeed = seed; +} +//............................................................................ +uint32_t BSP_random(void) { // a very cheap pseudo-random-number generator + // Some floating point code is to exercise the VFP... float volatile x = 3.1415926F; x = x + 2.7182818F; - /* "Super-Duper" Linear Congruential Generator (LCG) - * LCG(2^32, 3*7*11*13*23, 0, seed) - */ - l_rnd = l_rnd * (3U*7U*11U*13U*23U); + // "Super-Duper" Linear Congruential Generator (LCG) + // LCG(2^32, 3*7*11*13*23, 0, seed) + uint32_t rnd = l_rndSeed * (3U*7U*11U*13U*23U); + l_rndSeed = rnd; // set for the next time - return l_rnd >> 8; + return (rnd >> 8U); } -/*..........................................................................*/ -void BSP_randomSeed(uint32_t seed) { - l_rnd = seed; +//............................................................................ +void BSP_ledOn(void) { + GPIOF_AHB->DATA_Bits[LED_RED] = 0xFFU; } -/*..........................................................................*/ +//............................................................................ +void BSP_ledOff(void) { + GPIOF_AHB->DATA_Bits[LED_RED] = 0x00U; +} +//............................................................................ void BSP_terminate(int16_t result) { - (void)result; + Q_UNUSED_PAR(result); } -/* QF callbacks ============================================================*/ +//============================================================================ +// QF callbacks... void QF_onStartup(void) { - /* set up the SysTick timer to fire at BSP_TICKS_PER_SEC rate */ + // set up the SysTick timer to fire at BSP_TICKS_PER_SEC rate SysTick_Config(SystemCoreClock / BSP_TICKS_PER_SEC); - /* assing all priority bits for preemption-prio. and none to sub-prio. */ + // assign all priority bits for preemption-prio. and none to sub-prio. NVIC_SetPriorityGrouping(0U); - /* set priorities of ALL ISRs used in the system, see NOTE1 - * - * !!!!!!!!!!!!!!!!!!!!!!!!!!!! CAUTION !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - * Assign a priority to EVERY ISR explicitly by calling NVIC_SetPriority(). - * DO NOT LEAVE THE ISR PRIORITIES AT THE DEFAULT VALUE! - */ - NVIC_SetPriority(UART0_IRQn, 0U); /* kernel unaware interrupt */ - NVIC_SetPriority(GPIOA_IRQn, QF_AWARE_ISR_CMSIS_PRI); - NVIC_SetPriority(SysTick_IRQn, QF_AWARE_ISR_CMSIS_PRI + 1U); - /* ... */ + // set priorities of ALL ISRs used in the system, see NOTE1 + NVIC_SetPriority(UART0_IRQn, 0U); // kernel UNAWARE interrupt + NVIC_SetPriority(GPIOA_IRQn, QF_AWARE_ISR_CMSIS_PRI + 0U); + NVIC_SetPriority(SysTick_IRQn, QF_AWARE_ISR_CMSIS_PRI + 1U); + // ... - /* enable IRQs... */ + // enable IRQs in the NVIC... NVIC_EnableIRQ(GPIOA_IRQn); #ifdef Q_SPY - NVIC_EnableIRQ(UART0_IRQn); /* UART0 interrupt used for QS-RX */ + NVIC_EnableIRQ(UART0_IRQn); // UART interrupt used for QS-RX #endif } -/*..........................................................................*/ +//............................................................................ void QF_onCleanup(void) { } -/*..........................................................................*/ -void QV_onIdle(void) { /* called with interrupts disabled, see NOTE2 */ - /* toggle the User LED on and then off, see NOTE3 */ - GPIOF_AHB->DATA_Bits[LED_BLUE] = 0xFFU; /* turn the Blue LED on */ - GPIOF_AHB->DATA_Bits[LED_BLUE] = 0U; /* turn the Blue LED off */ +//............................................................................ +void QV_onIdle(void) { // called with interrupts disabled, see NOTE0 + // toggle the User LED on and then off, see NOTE2 + GPIOF_AHB->DATA_Bits[LED_BLUE] = 0xFFU; // turn the Blue LED on + GPIOF_AHB->DATA_Bits[LED_BLUE] = 0U; // turn the Blue LED off #ifdef Q_SPY + // interrupts still disabled + QS_rxParse(); // parse all the received bytes QF_INT_ENABLE(); - QS_rxParse(); /* parse all the received bytes */ - if ((UART0->FR & UART_FR_TXFE) != 0U) { /* TX done? */ - uint16_t fifo = UART_TXFIFO_DEPTH; /* max bytes we can accept */ + if ((UART0->FR & UART_FR_TXFE) != 0U) { // TX done? + uint16_t fifo = UART_TXFIFO_DEPTH; // max bytes we can accept QF_INT_DISABLE(); - /* try to get next contiguous block to transmit */ uint8_t const *block = QS_getBlock(&fifo); QF_INT_ENABLE(); - while (fifo-- != 0) { /* any bytes in the block? */ - UART0->DR = *block++; /* put into the FIFO */ + while (fifo-- != 0U) { // any bytes in the block? + UART0->DR = *block++; // put into the FIFO } } #elif defined NDEBUG - /* Put the CPU and peripherals to the low-power mode. - * you might need to customize the clock management for your application, - * see the datasheet for your particular Cortex-M MCU. - */ - QV_CPU_SLEEP(); /* atomically go to sleep and enable interrupts */ + // Put the CPU and peripherals to the low-power mode. + // you might need to customize the clock management for your application, + // see the datasheet for your particular Cortex-M MCU. + // + QV_CPU_SLEEP(); // atomically go to sleep and enable interrupts #else - QF_INT_ENABLE(); /* just enable interrupts */ + QF_INT_ENABLE(); // just enable interrupts #endif } -/*..........................................................................*/ -Q_NORETURN Q_onAssert(char const * const module, int_t const loc) { - /* - * NOTE: add here your application-specific error handling - */ - (void)module; - (void)loc; - QS_ASSERTION(module, loc, 10000U); /* report assertion to QS */ - -#ifndef NDEBUG - /* light up all LEDs */ - GPIOF_AHB->DATA_Bits[LED_GREEN | LED_RED | LED_BLUE] = 0xFFU; - /* for debugging, hang on in an endless loop... */ - for (;;) { - } -#endif - - NVIC_SystemReset(); -} - -/* QS callbacks ============================================================*/ +//============================================================================ +// QS callbacks... #ifdef Q_SPY -/*..........................................................................*/ + +//............................................................................ uint8_t QS_onStartup(void const *arg) { Q_UNUSED_PAR(arg); - static uint8_t qsTxBuf[2*1024]; /* buffer for QS-TX channel */ - static uint8_t qsRxBuf[100]; /* buffer for QS-RX channel */ + static uint8_t qsTxBuf[2*1024]; // buffer for QS-TX channel + QS_initBuf(qsTxBuf, sizeof(qsTxBuf)); - QS_initBuf (qsTxBuf, sizeof(qsTxBuf)); + static uint8_t qsRxBuf[100]; // buffer for QS-RX channel QS_rxInitBuf(qsRxBuf, sizeof(qsRxBuf)); - /* enable clock for UART0 and GPIOA (used by UART0 pins) */ - SYSCTL->RCGCUART |= (1U << 0); /* enable Run mode for UART0 */ - SYSCTL->RCGCGPIO |= (1U << 0); /* enable Run mode for GPIOA */ + // enable clock for UART0 and GPIOA (used by UART0 pins) + SYSCTL->RCGCUART |= (1U << 0U); // enable Run mode for UART0 + SYSCTL->RCGCGPIO |= (1U << 0U); // enable Run mode for GPIOA - /* configure UART0 pins for UART operation */ - uint32_t tmp = (1U << 0) | (1U << 1); + // configure UART0 pins for UART operation + uint32_t tmp = (1U << 0U) | (1U << 1U); GPIOA->DIR &= ~tmp; GPIOA->SLR &= ~tmp; GPIOA->ODR &= ~tmp; GPIOA->PUR &= ~tmp; GPIOA->PDR &= ~tmp; - GPIOA->AMSEL &= ~tmp; /* disable analog function on the pins */ - GPIOA->AFSEL |= tmp; /* enable ALT function on the pins */ - GPIOA->DEN |= tmp; /* enable digital I/O on the pins */ + GPIOA->AMSEL &= ~tmp; // disable analog function on the pins + GPIOA->AFSEL |= tmp; // enable ALT function on the pins + GPIOA->DEN |= tmp; // enable digital I/O on the pins GPIOA->PCTL &= ~0x00U; GPIOA->PCTL |= 0x11U; - /* configure the UART for the desired baud rate, 8-N-1 operation */ + // configure the UART for the desired baud rate, 8-N-1 operation tmp = (((SystemCoreClock * 8U) / UART_BAUD_RATE) + 1U) / 2U; UART0->IBRD = tmp / 64U; UART0->FBRD = tmp % 64U; - UART0->LCRH = (0x3U << 5); /* configure 8-N-1 operation */ - UART0->LCRH |= (0x1U << 4); /* enable FIFOs */ - UART0->CTL = (1U << 0) /* UART enable */ - | (1U << 8) /* UART TX enable */ - | (1U << 9); /* UART RX enable */ + UART0->LCRH = (0x3U << 5U); // configure 8-N-1 operation + UART0->LCRH |= (0x1U << 4U); // enable FIFOs + UART0->CTL = (1U << 0U) // UART enable + | (1U << 8U) // UART TX enable + | (1U << 9U); // UART RX enable - /* configure UART interrupts (for the RX channel) */ - UART0->IM |= (1U << 4) | (1U << 6); /* enable RX and RX-TO interrupt */ - UART0->IFLS |= (0x2U << 2); /* interrupt on RX FIFO half-full */ - /* NOTE: do not enable the UART0 interrupt yet. Wait till QF_onStartup() */ + // configure UART interrupts (for the RX channel) + UART0->IM |= (1U << 4U) | (1U << 6U); // enable RX and RX-TO interrupt + UART0->IFLS |= (0x2U << 2U); // interrupt on RX FIFO half-full + // NOTE: do not enable the UART0 interrupt yet. Wait till QF_onStartup() - /* configure TIMER5 to produce QS time stamp */ - SYSCTL->RCGCTIMER |= (1U << 5); /* enable run mode for Timer5 */ - TIMER5->CTL = 0U; /* disable Timer1 output */ - TIMER5->CFG = 0x0U; /* 32-bit configuration */ - TIMER5->TAMR = (1U << 4) | 0x02; /* up-counting periodic mode */ - TIMER5->TAILR= 0xFFFFFFFFU; /* timer interval */ - TIMER5->ICR = 0x1U; /* TimerA timeout flag bit clears*/ - TIMER5->CTL |= (1U << 0); /* enable TimerA module */ + // configure TIMER5 to produce QS time stamp + SYSCTL->RCGCTIMER |= (1U << 5U); // enable run mode for Timer5 + TIMER5->CTL = 0U; // disable Timer1 output + TIMER5->CFG = 0x0U; // 32-bit configuration + TIMER5->TAMR = (1U << 4U) | 0x02U; // up-counting periodic mode + TIMER5->TAILR= 0xFFFFFFFFU; // timer interval + TIMER5->ICR = 0x1U; // TimerA timeout flag bit clears + TIMER5->CTL |= (1U << 0U); // enable TimerA module - return 1U; /* return success */ + return 1U; // return success } -/*..........................................................................*/ +//............................................................................ void QS_onCleanup(void) { } -/*..........................................................................*/ -QSTimeCtr QS_onGetTime(void) { /* NOTE: invoked with interrupts DISABLED */ +//............................................................................ +QSTimeCtr QS_onGetTime(void) { // NOTE: invoked with interrupts DISABLED return TIMER5->TAV; } -/*..........................................................................*/ +//............................................................................ void QS_onFlush(void) { - while (true) { - /* try to get next byte to transmit */ + for (;;) { QF_INT_DISABLE(); uint16_t b = QS_getByte(); - QF_INT_ENABLE(); + if (b != QS_EOD) { + while ((UART0->FR & UART_FR_TXFE) == 0U) { // while TXE not empty + QF_INT_ENABLE(); + QF_CRIT_EXIT_NOP(); - if (b != QS_EOD) { /* NOT end-of-data */ - /* busy-wait as long as TX FIFO has data to transmit */ - while ((UART0->FR & UART_FR_TXFE) == 0) { + QF_INT_DISABLE(); } - /* place the byte in the UART DR register */ - UART0->DR = b; + UART0->DR = b; // put into the DR register + QF_INT_ENABLE(); } else { - break; /* break out of the loop */ + QF_INT_ENABLE(); + break; } } } -/*..........................................................................*/ -/*! callback function to reset the target (to be implemented in the BSP) */ +//............................................................................ +//! callback function to reset the target (to be implemented in the BSP) void QS_onReset(void) { NVIC_SystemReset(); } -/*..........................................................................*/ -/*! callback function to execute a user command (to be implemented in BSP) */ +//............................................................................ void QS_onCommand(uint8_t cmdId, uint32_t param1, uint32_t param2, uint32_t param3) { - QS_BEGIN_ID(COMMAND_STAT, 0U) /* app-specific record */ - QS_U8(2, cmdId); - QS_U32(8, param1); - QS_U32(8, param2); - QS_U32(8, param3); - QS_END() + Q_UNUSED_PAR(cmdId); + Q_UNUSED_PAR(param1); + Q_UNUSED_PAR(param2); + Q_UNUSED_PAR(param3); } -#endif /* Q_SPY */ -/*--------------------------------------------------------------------------*/ +#endif // Q_SPY +//---------------------------------------------------------------------------- -/*============================================================================ -* NOTE1: -* The QF_AWARE_ISR_CMSIS_PRI constant from the QF port specifies the highest -* ISR priority that is disabled by the QF framework. The value is suitable -* for the NVIC_SetPriority() CMSIS function. -* -* Only ISRs prioritized at or below the QF_AWARE_ISR_CMSIS_PRI level (i.e., -* with the numerical values of priorities equal or higher than -* QF_AWARE_ISR_CMSIS_PRI) are allowed to call the QK_ISR_ENTRY/QK_ISR_ENTRY -* macros or any other QF/QK services. These ISRs are "QF-aware". -* -* Conversely, any ISRs prioritized above the QF_AWARE_ISR_CMSIS_PRI priority -* level (i.e., with the numerical values of priorities less than -* QF_AWARE_ISR_CMSIS_PRI) are never disabled and are not aware of the kernel. -* Such "QF-unaware" ISRs cannot call any QF/QK services. In particular they -* can NOT call the macros QK_ISR_ENTRY/QK_ISR_ENTRY. The only mechanism -* by which a "QF-unaware" ISR can communicate with the QF framework is by -* triggering a "QF-aware" ISR, which can post/publish events. -* -* NOTE2: -* The QV_onIdle() callback is called with interrupts disabled, because the -* determination of the idle condition might change by any interrupt posting -* an event. QV_onIdle() must internally enable interrupts, ideally -* atomically with putting the CPU to the power-saving mode. -* -* NOTE3: -* The User LED is used to visualize the idle loop activity. The brightness -* of the LED is proportional to the frequency of invcations of the idle loop. -* Please note that the LED is toggled with interrupts locked, so no interrupt -* execution time contributes to the brightness of the User LED. -*/ +//============================================================================ +// NOTE0: +// The QV_onIdle() callback is called with interrupts disabled, because the +// determination of the idle condition might change by any interrupt posting +// an event. QV_onIdle() must internally enable interrupts, ideally +// atomically with putting the CPU to the power-saving mode. +// +// NOTE1: +// The QF_AWARE_ISR_CMSIS_PRI constant from the QF port specifies the highest +// ISR priority that is disabled by the QF framework. The value is suitable +// for the NVIC_SetPriority() CMSIS function. +// +// Only ISRs prioritized at or below the QF_AWARE_ISR_CMSIS_PRI level (i.e., +// with the numerical values of priorities equal or higher than +// QF_AWARE_ISR_CMSIS_PRI) are allowed to post/publish events or call +// any other QF/QV services. These ISRs are "QF-aware". +// +// Conversely, any ISRs prioritized above the QF_AWARE_ISR_CMSIS_PRI priority +// level (i.e., with the numerical values of priorities less than +// QF_AWARE_ISR_CMSIS_PRI) are never disabled and are not aware of the kernel. +// Such "QF-unaware" ISRs cannot call ANY QF/QV services. In particular they +// can NOT call the macros QV_ISR_ENTRY/QV_ISR_ENTRY. The only mechanism +// by which a "QF-unaware" ISR can communicate with the QF framework is by +// triggering a "QF-aware" ISR, which can post/publish events. +// +// NOTE2: +// The User LED is used to visualize the idle loop activity. The brightness +// of the LED is proportional to the frequency of the idle loop. +// Please note that the LED is toggled with interrupts locked, so no interrupt +// execution time contributes to the brightness of the User LED. +// diff --git a/examples/arm-cm/dpp_ek-tm4c123gxl/qv/gnu/.ccsproject b/examples/arm-cm/dpp_ek-tm4c123gxl/qv/gnu/.ccsproject new file mode 100644 index 00000000..0c19207c --- /dev/null +++ b/examples/arm-cm/dpp_ek-tm4c123gxl/qv/gnu/.ccsproject @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/examples/arm-cm/dpp_ek-tm4c123gxl/qv/gnu/.cproject b/examples/arm-cm/dpp_ek-tm4c123gxl/qv/gnu/.cproject new file mode 100644 index 00000000..99f99049 --- /dev/null +++ b/examples/arm-cm/dpp_ek-tm4c123gxl/qv/gnu/.cproject @@ -0,0 +1,290 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/arm-cm/dpp_ek-tm4c123gxl/qv/gnu/.project b/examples/arm-cm/dpp_ek-tm4c123gxl/qv/gnu/.project new file mode 100644 index 00000000..14714df8 --- /dev/null +++ b/examples/arm-cm/dpp_ek-tm4c123gxl/qv/gnu/.project @@ -0,0 +1,119 @@ + + + dpp-qv + + + + + + org.eclipse.cdt.managedbuilder.core.genmakebuilder + + + + + org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder + full,incremental, + + + + + + com.ti.ccstudio.core.ccsNature + org.eclipse.cdt.core.cnature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + org.eclipse.cdt.core.ccnature + org.eclipse.cdt.managedbuilder.core.ScannerConfigNature + + + + QP + 2 + PARENT-5-PROJECT_LOC/src/qf + + + QP_port + 2 + PARENT-5-PROJECT_LOC/ports/arm-cm/qv/gnu + + + QS + 2 + PARENT-5-PROJECT_LOC/src/qs + + + QV + 2 + PARENT-5-PROJECT_LOC/src/qv + + + TM4C123GH6PM.h + 1 + PARENT-5-PROJECT_LOC/3rd_party/ek-tm4c123gxl/TM4C123GH6PM.h + + + bsp.c + 1 + PARENT-1-PROJECT_LOC/bsp.c + + + bsp.h + 1 + PARENT-2-PROJECT_LOC/bsp.h + + + dpp.h + 1 + PARENT-2-PROJECT_LOC/dpp.h + + + gpio.h + 1 + PARENT-5-PROJECT_LOC/3rd_party/ek-tm4c123gxl/gpio.h + + + main.c + 1 + PARENT-1-PROJECT_LOC/main.c + + + philo.c + 1 + PARENT-2-PROJECT_LOC/philo.c + + + qstamp.c + 1 + PARENT-5-PROJECT_LOC/include/qstamp.c + + + rom.h + 1 + PARENT-5-PROJECT_LOC/3rd_party/ek-tm4c123gxl/rom.h + + + startup_TM4C123GH6PM.c + 1 + PARENT-5-PROJECT_LOC/3rd_party/ek-tm4c123gxl/gnu/startup_TM4C123GH6PM.c + + + sysctl.h + 1 + PARENT-5-PROJECT_LOC/3rd_party/ek-tm4c123gxl/sysctl.h + + + system_TM4C123GH6PM.c + 1 + PARENT-5-PROJECT_LOC/3rd_party/ek-tm4c123gxl/system_TM4C123GH6PM.c + + + system_TM4C123GH6PM.h + 1 + PARENT-5-PROJECT_LOC/3rd_party/ek-tm4c123gxl/system_TM4C123GH6PM.h + + + table.c + 1 + PARENT-2-PROJECT_LOC/table.c + + + diff --git a/examples/arm-cm/dpp_ek-tm4c123gxl/qv/gnu/Makefile b/examples/arm-cm/dpp_ek-tm4c123gxl/qv/gnu/Makefile index e3584d6b..15d7c6be 100644 --- a/examples/arm-cm/dpp_ek-tm4c123gxl/qv/gnu/Makefile +++ b/examples/arm-cm/dpp_ek-tm4c123gxl/qv/gnu/Makefile @@ -1,13 +1,13 @@ ############################################################################## # Product: Makefile for QP/C on EK-TM4C123GXL, QV kernel, GNU-ARM -# Last Updated for Version: 7.0.1 -# Date of the Last Update: 2022-05-23 +# Last Updated for Version: 7.3.0 +# Date of the Last Update: 2023-09-02 # # Q u a n t u m L e a P s # ------------------------ # Modern Embedded Software # -# Copyright (C) 2005-2021 Quantum Leaps, LLC. All rights reserved. +# Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. # # This program is open source software: you can redistribute it and/or # modify it under the terms of the GNU General Public License as published @@ -45,8 +45,7 @@ # NOTE: # To use this Makefile on Windows, you will need the GNU make utility, which # is included in the Qtools collection for Windows, see: -# https://sourceforge.net/projects/qpc/files/QTools/ -# +# https://github.com/QuantumLeaps/qtools #----------------------------------------------------------------------------- # project name @@ -78,6 +77,7 @@ VPATH = \ # list of all include directories needed by this project INCLUDES = \ + -I.. \ -I../.. \ -I$(QPC)/include \ -I$(QP_PORT_DIR) \ @@ -133,7 +133,7 @@ LIB_DIRS := LIBS := # defines -DEFINES := -DTARGET_IS_TM4C123_RB1 +DEFINES := -DQP_CONFIG # ARM CPU, ARCH, FPU, and Float-ABI types... # ARM_CPU: [cortex-m0 | cortex-m0plus | cortex-m1 | cortex-m3 | cortex-m4] @@ -163,12 +163,11 @@ AS := $(GNU_ARM)/bin/arm-none-eabi-as LINK := $(GNU_ARM)/bin/arm-none-eabi-gcc BIN := $(GNU_ARM)/bin/arm-none-eabi-objcopy - ############################################################################## -# Typically, you should not need to change anything below this line +# Typically you should not need to change anything below this line -# basic utilities (included in Qtools for Windows), see: -# http://sourceforge.net/projects/qpc/files/Qtools +# basic utilities (included in QTools for Windows), see: +# https://www.state-machine.com/qtools MKDIR := mkdir RM := rm @@ -189,11 +188,11 @@ ASFLAGS = $(ARM_CPU) $(ARM_FPU) $(ASM_CPU) $(ASM_FPU) CFLAGS = -c $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \ -ffunction-sections -fdata-sections \ - -O1 $(INCLUDES) $(DEFINES) -DNDEBUG + -O2 $(INCLUDES) $(DEFINES) -DNDEBUG CPPFLAGS = -c $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \ -ffunction-sections -fdata-sections -fno-rtti -fno-exceptions \ - -O1 $(INCLUDES) $(DEFINES) -DNDEBUG + -O2 $(INCLUDES) $(DEFINES) -DNDEBUG else ifeq (spy, $(CONF)) # Spy configuration ................................ @@ -232,7 +231,6 @@ LINKFLAGS = -T$(LD_SCRIPT) $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb \ -specs=nosys.specs -specs=nano.specs \ -Wl,-Map,$(BIN_DIR)/$(OUTPUT).map,--cref,--gc-sections $(LIB_DIRS) - ASM_OBJS := $(patsubst %.s,%.o, $(notdir $(ASM_SRCS))) C_OBJS := $(patsubst %.c,%.o, $(notdir $(C_SRCS))) CPP_OBJS := $(patsubst %.cpp,%.o,$(notdir $(CPP_SRCS))) @@ -254,14 +252,20 @@ endif # rules # -all: $(TARGET_BIN) -#all: $(TARGET_ELF) +.PHONY : run norun flash + +ifeq ($(MAKECMDGOALS),norun) +all : $(TARGET_BIN) +norun : all +else +all : $(TARGET_BIN) run +endif $(TARGET_BIN): $(TARGET_ELF) $(BIN) -O binary $< $@ $(TARGET_ELF) : $(ASM_OBJS_EXT) $(C_OBJS_EXT) $(CPP_OBJS_EXT) - $(CC) $(CFLAGS) $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o + $(CC) $(CFLAGS) $(QPC)/src/qs/qstamp.c -o $(BIN_DIR)/qstamp.o $(LINK) $(LINKFLAGS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) $(BIN_DIR)/%.d : %.c @@ -279,6 +283,8 @@ $(BIN_DIR)/%.o : %.c $(BIN_DIR)/%.o : %.cpp $(CPP) $(CPPFLAGS) $< -o $@ +.PHONY : clean show + # include dependency files only if our goal depends on their existence ifneq ($(MAKECMDGOALS),clean) ifneq ($(MAKECMDGOALS),show) @@ -287,7 +293,6 @@ ifneq ($(MAKECMDGOALS),clean) endif -.PHONY : clean clean: -$(RM) $(BIN_DIR)/*.o \ $(BIN_DIR)/*.d \ diff --git a/examples/arm-cm/dpp_ek-tm4c123gxl/qv/iar/dpp-qv.ewd b/examples/arm-cm/dpp_ek-tm4c123gxl/qv/iar/dpp-qv.ewd index 71e2f66a..7f745b03 100644 --- a/examples/arm-cm/dpp_ek-tm4c123gxl/qv/iar/dpp-qv.ewd +++ b/examples/arm-cm/dpp_ek-tm4c123gxl/qv/iar/dpp-qv.ewd @@ -11,7 +11,7 @@ C-SPY 2 - 28 + 32 1 1 - - + + + + +
@@ -486,7 +498,7 @@ IJET_ID 2 - 8 + 9 1 1 + + + + + + + + + + + + + @@ -916,7 +980,7 @@ LMIFTDI_ID 2 - 2 + 3 1 1 + + + + + + + NULINK_ID + 2 + + 0 + 1 + 1 + + + @@ -974,7 +1072,7 @@ STLINK_ID 2 - 4 + 8 1 1 + + + + @@ -1185,7 +1300,7 @@ XDS100_ID 2 - 6 + 9 1 1 + + + + @@ -1362,6 +1493,18 @@ $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin 0
+ + $TOOLKIT_DIR$\plugins\rtos\FreeRtos\FreeRtosArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin2.ENU.ewplugin + 0 + $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin 0 @@ -1371,11 +1514,15 @@ 0 - $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9.ewplugin 0 - $TOOLKIT_DIR$\plugins\rtos\TI-RTOS\tirtosplugin.ewplugin + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9BE.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin 0 @@ -1391,11 +1538,11 @@ 0 - $EW_DIR$\common\plugins\CodeCoverage\CodeCoverage.ENU.ewplugin - 1 + $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + 0 - $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + $EW_DIR$\common\plugins\TargetAccessServer\TargetAccessServer.ENU.ewplugin 0 @@ -1414,7 +1561,7 @@ C-SPY 2 - 28 + 32 1 0 - - + + + + + @@ -1889,7 +2048,7 @@ IJET_ID 2 - 8 + 9 1 0 + + + + + + + + + + + + + @@ -2319,7 +2530,7 @@ LMIFTDI_ID 2 - 2 + 3 1 0 + + + + + + + NULINK_ID + 2 + + 0 + 1 + 0 + + + @@ -2377,7 +2622,7 @@ STLINK_ID 2 - 4 + 8 1 0 + + + + @@ -2588,7 +2850,7 @@ XDS100_ID 2 - 6 + 9 1 0 + + + + @@ -2765,6 +3043,18 @@ $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin 0 + + $TOOLKIT_DIR$\plugins\rtos\FreeRtos\FreeRtosArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin2.ENU.ewplugin + 0 + $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin 0 @@ -2774,11 +3064,15 @@ 0 - $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9.ewplugin 0 - $TOOLKIT_DIR$\plugins\rtos\TI-RTOS\tirtosplugin.ewplugin + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9BE.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin 0 @@ -2794,11 +3088,11 @@ 0 - $EW_DIR$\common\plugins\CodeCoverage\CodeCoverage.ENU.ewplugin - 1 + $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + 0 - $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + $EW_DIR$\common\plugins\TargetAccessServer\TargetAccessServer.ENU.ewplugin 0 @@ -2817,7 +3111,7 @@ C-SPY 2 - 28 + 32 1 1 - - + + + + + @@ -3292,7 +3598,7 @@ IJET_ID 2 - 8 + 9 1 1 + + + + + + + + + + + + + @@ -3722,7 +4080,7 @@ LMIFTDI_ID 2 - 2 + 3 1 1 + + + + + + + NULINK_ID + 2 + + 0 + 1 + 1 + + + @@ -3780,7 +4172,7 @@ STLINK_ID 2 - 4 + 8 1 1 + + + + @@ -3991,7 +4400,7 @@ XDS100_ID 2 - 6 + 9 1 1 + + + + @@ -4168,6 +4593,18 @@ $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin 0 + + $TOOLKIT_DIR$\plugins\rtos\FreeRtos\FreeRtosArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin2.ENU.ewplugin + 0 + $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin 0 @@ -4177,11 +4614,15 @@ 0 - $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9.ewplugin 0 - $TOOLKIT_DIR$\plugins\rtos\TI-RTOS\tirtosplugin.ewplugin + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9BE.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin 0 @@ -4197,11 +4638,11 @@ 0 - $EW_DIR$\common\plugins\CodeCoverage\CodeCoverage.ENU.ewplugin - 1 + $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + 0 - $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + $EW_DIR$\common\plugins\TargetAccessServer\TargetAccessServer.ENU.ewplugin 0 diff --git a/examples/arm-cm/dpp_ek-tm4c123gxl/qv/iar/dpp-qv.ewp b/examples/arm-cm/dpp_ek-tm4c123gxl/qv/iar/dpp-qv.ewp index 9bfcccc0..09c1e6cb 100644 --- a/examples/arm-cm/dpp_ek-tm4c123gxl/qv/iar/dpp-qv.ewp +++ b/examples/arm-cm/dpp_ek-tm4c123gxl/qv/iar/dpp-qv.ewp @@ -11,9 +11,13 @@ General 3 - 28 + 35 1 1 + - - - - - + + + + + + + + ICCARM 2 - 34 + 37 1 1 - - - + + AARM 2 - 10 + 11 1 1 + @@ -656,13 +669,9 @@ 0 + inputOutputBased - - BICOMP - 0 - - BUILDACTION 1 @@ -675,17 +684,13 @@ ILINK 0 - 20 + 27 1 1 - + + + + + + + + + + + + + + + @@ -1010,11 +1075,6 @@ - - BILINK - 0 - - Coder 0 @@ -1031,9 +1091,13 @@ General 3 - 28 + 35 1 0 + - - - - - + + + + + + + + ICCARM 2 - 34 + 37 1 0 - - - + + AARM 2 - 10 + 11 1 0 + @@ -1676,13 +1750,9 @@ 0 + inputOutputBased - - BICOMP - 0 - - BUILDACTION 1 @@ -1695,17 +1765,13 @@ ILINK 0 - 20 + 27 1 0 - + + + + + + + + + + + + + + + @@ -2030,11 +2156,6 @@ - - BILINK - 0 - - Coder 0 @@ -2051,9 +2172,13 @@ General 3 - 28 + 35 1 1 + - - - - - + + + + + + + + ICCARM 2 - 34 + 37 1 1 - - - + + AARM 2 - 10 + 11 1 1 + @@ -2696,13 +2831,9 @@ 0 + inputOutputBased - - BICOMP - 0 - - BUILDACTION 1 @@ -2715,17 +2846,13 @@ ILINK 0 - 20 + 27 1 1 - + + + + + + + + + + + + + + + @@ -3050,11 +3237,6 @@ - - BILINK - 0 - - Coder 0 @@ -3073,7 +3255,7 @@ $PROJ_DIR$\..\..\dpp.h - $PROJ_DIR$\..\main.c + $PROJ_DIR$\..\..\main.c $PROJ_DIR$\..\..\philo.c @@ -3138,9 +3320,6 @@ $PROJ_DIR$\..\..\..\..\..\src\qf\qf_time.c - - $PROJ_DIR$\..\..\..\..\..\include\qstamp.c - $PROJ_DIR$\..\..\..\..\..\src\qv\qv.c @@ -3176,10 +3355,10 @@ $PROJ_DIR$\..\..\..\..\..\src\qs\qs_fp.c - $PROJ_DIR$\..\..\..\..\..\src\qs_pkg.h + $PROJ_DIR$\..\..\..\..\..\src\qs\qs_rx.c - $PROJ_DIR$\..\..\..\..\..\src\qs\qs_rx.c + $PROJ_DIR$\..\..\..\..\..\src\qs\qstamp.c diff --git a/examples/arm-cm/dpp_ek-tm4c123gxl/qv/iar/dpp-qv.icf b/examples/arm-cm/dpp_ek-tm4c123gxl/qv/iar/dpp-qv.icf index 0fdfc4b3..c6b24e1c 100644 --- a/examples/arm-cm/dpp_ek-tm4c123gxl/qv/iar/dpp-qv.icf +++ b/examples/arm-cm/dpp_ek-tm4c123gxl/qv/iar/dpp-qv.icf @@ -25,5 +25,5 @@ do not initialize { section .noinit }; place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec }; place in ROM_region { readonly }; -place at start of RAM_region {block CSTACK }; +place at start of RAM_region {block CSTACK }; /* <== Quantum Leaps */ place in RAM_region { readwrite, block HEAP }; \ No newline at end of file diff --git a/examples/arm-cm/dpp_ek-tm4c123gxl/qv/main.c b/examples/arm-cm/dpp_ek-tm4c123gxl/qv/main.c deleted file mode 100644 index 0d747dfa..00000000 --- a/examples/arm-cm/dpp_ek-tm4c123gxl/qv/main.c +++ /dev/null @@ -1,87 +0,0 @@ -/***************************************************************************** -* Product: DPP example -* Last updated for version 7.1.2 -* Last updated on 2022-10-06 -* -* Q u a n t u m L e a P s -* ------------------------ -* Modern Embedded Software -* -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* -* -*****************************************************************************/ -#include "qpc.h" -#include "dpp.h" -#include "bsp.h" - -Q_DEFINE_THIS_FILE - -/*..........................................................................*/ -int main() { - static QEvt const *tableQueueSto[N_PHILO]; - static QEvt const *philoQueueSto[N_PHILO][N_PHILO]; - static QSubscrList subscrSto[MAX_PUB_SIG]; - static QF_MPOOL_EL(TableEvt) smlPoolSto[2*N_PHILO]; /* small pool */ - - QF_init(); /* initialize the framework and the underlying RT kernel */ - BSP_init(); /* initialize the Board Support Package */ - - /* object dictionaries... */ - QS_OBJ_DICTIONARY(AO_Table); - QS_OBJ_DICTIONARY(AO_Philo[0]); - QS_OBJ_DICTIONARY(AO_Philo[1]); - QS_OBJ_DICTIONARY(AO_Philo[2]); - QS_OBJ_DICTIONARY(AO_Philo[3]); - QS_OBJ_DICTIONARY(AO_Philo[4]); - - /* initialize publish-subscribe... */ - QF_psInit(subscrSto, Q_DIM(subscrSto)); - - /* initialize event pools... */ - QF_poolInit(smlPoolSto, sizeof(smlPoolSto), sizeof(smlPoolSto[0])); - - /* start the active objects... */ - Philo_ctor(); /* instantiate all Philosopher active objects */ - for (uint8_t n = 0U; n < N_PHILO; ++n) { - QACTIVE_START(AO_Philo[n], /* AO to start */ - n + 2U, /* QF-priority */ - philoQueueSto[n], /* event queue storage */ - Q_DIM(philoQueueSto[n]), /* queue length [events] */ - (void *)0, /* stack storage (not used) */ - 0U, /* size of the stack [bytes] */ - (void *)0); /* initialization param */ - } - - Table_ctor(); /* instantiate the Table active object */ - QACTIVE_START(AO_Table, /* AO to start */ - N_PHILO + 2U, /* QF-priority */ - tableQueueSto, /* event queue storage */ - Q_DIM(tableQueueSto), /* queue length [events] */ - (void *)0, /* stack storage (not used) */ - 0U, /* size of the stack [bytes] */ - (void *)0); /* initialization param */ - - return QF_run(); /* run the QF application */ -} - diff --git a/examples/arm-cm/dpp_ek-tm4c123gxl/qxk/armclang/dpp-qxk.sct b/examples/arm-cm/dpp_ek-tm4c123gxl/qxk/armclang/dpp-qxk.sct new file mode 100644 index 00000000..458d5506 --- /dev/null +++ b/examples/arm-cm/dpp_ek-tm4c123gxl/qxk/armclang/dpp-qxk.sct @@ -0,0 +1,23 @@ +; ************************************************************* +; *** Scatter-Loading Description File generated by uVision *** +; +; Adapted by Quantum Leaps: +; added STACK as the first section in RW_STACK +; ************************************************************* + +LR_IROM1 0x00000000 0x00040000 { ; load region size_region + ER_IROM1 0x00000000 0x00040000 { ; load address = execution address + *.o (RESET, +First) + *(InRoot$$Sections) + .ANY (+RO) + .ANY (+XO) + } + + RW_STACK 0x20000000 { ; <== Quantum Leaps + * (STACK, +First) + } + RW_IRAM1 +0 (0x00008000 - 2048) { ; NOTE: assume STACK size 2048! + .ANY (+RW +ZI) + } +} + diff --git a/examples/arm-cm/dpp_ek-tm4c123gxl/qxk/armclang/dpp-qxk.uvoptx b/examples/arm-cm/dpp_ek-tm4c123gxl/qxk/armclang/dpp-qxk.uvoptx index 2ff0d8f3..07564e56 100644 --- a/examples/arm-cm/dpp_ek-tm4c123gxl/qxk/armclang/dpp-qxk.uvoptx +++ b/examples/arm-cm/dpp_ek-tm4c123gxl/qxk/armclang/dpp-qxk.uvoptx @@ -147,34 +147,18 @@ 0 0 - 333 + 452 1 -
1210
+
15900
0 0 0 0 0 1 - ..\..\..\..\..\3rd_party\ek-tm4c123gxl\arm\startup_TM4C123GH6PM.s + ..\bsp.c - \\dpp_qxk\../../../../../3rd_party/ek-tm4c123gxl/arm/startup_TM4C123GH6PM.s\333 -
- - 1 - 0 - 321 - 1 -
1204
- 0 - 0 - 0 - 0 - 0 - 1 - ..\..\..\..\..\3rd_party\ek-tm4c123gxl\arm\startup_TM4C123GH6PM.s - - \\dpp_qxk\../../../../../3rd_party/ek-tm4c123gxl/arm/startup_TM4C123GH6PM.s\321 + \\dpp_qxk\../bsp.c\452
@@ -327,7 +311,7 @@ 1 0 0 - 8 + 19 @@ -628,12 +612,12 @@ 1 1 - 1 + 5 0 0 0 - ..\bsp.c - bsp.c + ..\..\bsp.h + bsp.h 0 0 @@ -652,12 +636,12 @@ 1 3 - 5 + 1 0 0 0 - ..\..\bsp.h - bsp.h + ..\bsp.c + bsp.c 0 0 @@ -668,6 +652,18 @@ 0 0 0 + ..\..\main.c + main.c + 0 + 0 + + + 1 + 5 + 1 + 0 + 0 + 0 ..\..\philo.c philo.c 0 @@ -675,7 +671,7 @@ 1 - 5 + 6 1 0 0 @@ -685,18 +681,6 @@ 0 0 - - 1 - 6 - 1 - 0 - 0 - 0 - ..\..\..\..\..\include\qstamp.c - qstamp.c - 0 - 0 - 1 7 @@ -704,8 +688,8 @@ 0 0 0 - ..\main.c - main.c + ..\xthread1.c + xthread1.c 0 0 @@ -716,8 +700,8 @@ 0 0 0 - ..\test.c - test.c + ..\xthread2.c + xthread2.c 0 0 @@ -1089,6 +1073,18 @@ 0 0 + + 5 + 37 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qs\qstamp.c + qstamp.c + 0 + 0 + diff --git a/examples/arm-cm/dpp_ek-tm4c123gxl/qxk/armclang/dpp-qxk.uvprojx b/examples/arm-cm/dpp_ek-tm4c123gxl/qxk/armclang/dpp-qxk.uvprojx index 0e345a30..c68d359e 100644 --- a/examples/arm-cm/dpp_ek-tm4c123gxl/qxk/armclang/dpp-qxk.uvprojx +++ b/examples/arm-cm/dpp_ek-tm4c123gxl/qxk/armclang/dpp-qxk.uvprojx @@ -313,7 +313,7 @@ 0 - 2 + 1 0 0 1 @@ -337,7 +337,7 @@ 0 - TARGET_IS_TM4C123_RB1 + QP_CONFIG ..\..;..\..\..\..\..\include;..\..\..\..\..\ports\arm-cm\qxk\armclang;..\..\..\..\..\3rd_party\CMSIS\Include;..\..\..\..\..\3rd_party\ek-tm4c123gxl @@ -361,7 +361,7 @@ - 1 + 0 0 0 0 @@ -370,7 +370,7 @@ 0x00000000 0x20000000 - + .\dpp-qxk.sct --entry Reset_Handler @@ -384,9 +384,9 @@ Applicatioin - bsp.c - 1 - ..\bsp.c + bsp.h + 5 + ..\..\bsp.h dpp.h @@ -394,9 +394,14 @@ ..\..\dpp.h - bsp.h - 5 - ..\..\bsp.h + bsp.c + 1 + ..\bsp.c + + + main.c + 1 + ..\..\main.c philo.c @@ -409,19 +414,14 @@ ..\..\table.c - qstamp.c + xthread1.c 1 - ..\..\..\..\..\include\qstamp.c + ..\xthread1.c - main.c + xthread2.c 1 - ..\main.c - - - test.c - 1 - ..\test.c + ..\xthread2.c @@ -652,6 +652,11 @@ 1 ..\..\..\..\..\src\qs\qs_rx.c + + qstamp.c + 1 + ..\..\..\..\..\src\qs\qstamp.c + @@ -660,7 +665,7 @@ dpp-rel 0x4 ARM-ADS - 6070000::V6.7::.\ARMCLANG + 6160000::V6.16::ARMCLANG 1 @@ -987,7 +992,7 @@ 0 - NDEBUG TARGET_IS_TM4C123_RB1 + NDEBUG,QP_CONFIG ..\..;..\..\..\..\..\include;..\..\..\..\..\ports\arm-cm\qxk\armclang;..\..\..\..\..\3rd_party\CMSIS\Include;..\..\..\..\..\3rd_party\ek-tm4c123gxl @@ -1011,7 +1016,7 @@ - 1 + 0 0 0 0 @@ -1020,7 +1025,7 @@ 0x00000000 0x20000000 - dpp-qxk.sct + .\dpp-qxk.sct --entry Reset_Handler @@ -1034,9 +1039,9 @@ Applicatioin - bsp.c - 1 - ..\bsp.c + bsp.h + 5 + ..\..\bsp.h dpp.h @@ -1044,9 +1049,14 @@ ..\..\dpp.h - bsp.h - 5 - ..\..\bsp.h + bsp.c + 1 + ..\bsp.c + + + main.c + 1 + ..\..\main.c philo.c @@ -1059,19 +1069,14 @@ ..\..\table.c - qstamp.c + xthread1.c 1 - ..\..\..\..\..\include\qstamp.c + ..\xthread1.c - main.c + xthread2.c 1 - ..\main.c - - - test.c - 1 - ..\test.c + ..\xthread2.c @@ -1302,6 +1307,11 @@ 1 ..\..\..\..\..\src\qs\qs_rx.c + + qstamp.c + 1 + ..\..\..\..\..\src\qs\qstamp.c + @@ -1637,7 +1647,7 @@ 0 - Q_SPY,QF_ON_CONTEXT_SW,TARGET_IS_TM4C123_RB1 + Q_SPY,QP_CONFIG ..\..;..\..\..\..\..\include;..\..\..\..\..\ports\arm-cm\qxk\armclang;..\..\..\..\..\3rd_party\CMSIS\Include;..\..\..\..\..\3rd_party\ek-tm4c123gxl @@ -1661,7 +1671,7 @@ - 1 + 0 0 0 0 @@ -1670,7 +1680,7 @@ 0x00000000 0x20000000 - + .\dpp-qxk.sct --entry Reset_Handler @@ -1684,9 +1694,9 @@ Applicatioin - bsp.c - 1 - ..\bsp.c + bsp.h + 5 + ..\..\bsp.h dpp.h @@ -1694,9 +1704,14 @@ ..\..\dpp.h - bsp.h - 5 - ..\..\bsp.h + bsp.c + 1 + ..\bsp.c + + + main.c + 1 + ..\..\main.c philo.c @@ -1709,19 +1724,14 @@ ..\..\table.c - qstamp.c + xthread1.c 1 - ..\..\..\..\..\include\qstamp.c + ..\xthread1.c - main.c + xthread2.c 1 - ..\main.c - - - test.c - 1 - ..\test.c + ..\xthread2.c @@ -1883,6 +1893,11 @@ 1 ..\..\..\..\..\src\qs\qs_rx.c + + qstamp.c + 1 + ..\..\..\..\..\src\qs\qstamp.c + diff --git a/examples/arm-cm/dpp_ek-tm4c123gxl/qxk/bsp.c b/examples/arm-cm/dpp_ek-tm4c123gxl/qxk/bsp.c index e362810d..b87889f8 100644 --- a/examples/arm-cm/dpp_ek-tm4c123gxl/qxk/bsp.c +++ b/examples/arm-cm/dpp_ek-tm4c123gxl/qxk/bsp.c @@ -1,596 +1,554 @@ -/***************************************************************************** -* Product: DPP example, EK-TM4C123GXL board, dual-mode QXK kernel -* Last updated for version 7.2.0 -* Last updated on 2022-12-17 -* -* Q u a n t u m L e a P s -* ------------------------ -* Modern Embedded Software -* -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* -* -*****************************************************************************/ -#include "qpc.h" -#include "dpp.h" -#include "bsp.h" +//============================================================================ +// Product: DPP example, EK-TM4C123GXL board, QXK kernel +// Last updated for version 7.3.0 +// Last updated on 2023-08-15 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. +// +// This program is open source software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Alternatively, this program may be distributed and modified under the +// terms of Quantum Leaps commercial licenses, which expressly supersede +// the GNU General Public License and are specifically designed for +// licensees interested in retaining the proprietary status of their code. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Contact information: +// +// +//============================================================================ +#include "qpc.h" // QP/C real-time embedded framework +#include "dpp.h" // DPP Application interface +#include "bsp.h" // Board Support Package -#include "TM4C123GH6PM.h" /* the device specific header (TI) */ -#include "rom.h" /* the built-in ROM functions (TI) */ -#include "sysctl.h" /* system control driver (TI) */ -#include "gpio.h" /* GPIO driver (TI) */ -/* add other drivers if necessary... */ +#include "TM4C123GH6PM.h" // the device specific header (TI) +#include "rom.h" // the built-in ROM functions (TI) +#include "sysctl.h" // system control driver (TI) +#include "gpio.h" // GPIO driver (TI) +// add other drivers if necessary... -Q_DEFINE_THIS_FILE /* define the name of this file for assertions */ +Q_DEFINE_THIS_FILE // define the name of this file for assertions -/* prototypes of ISRs defined in this BSP ----------------------------------*/ -void SysTick_Handler(void); -void GPIOPortA_IRQHandler(void); -void UART0_IRQHandler(void); +// Local-scope objects ----------------------------------------------------- +// LEDs on the board +#define LED_RED (1U << 1U) +#define LED_GREEN (1U << 3U) +#define LED_BLUE (1U << 2U) -/* Local-scope objects -----------------------------------------------------*/ -#define LED_RED (1U << 1) -#define LED_GREEN (1U << 3) -#define LED_BLUE (1U << 2) +// Buttons on the board +#define BTN_SW1 (1U << 4U) +#define BTN_SW2 (1U << 0U) -#define BTN_SW1 (1U << 4) -#define BTN_SW2 (1U << 0) - -static uint32_t l_rnd; /* random seed */ +static uint32_t l_rndSeed; #ifdef Q_SPY - /* QSpy source IDs */ + // QSpy source IDs static QSpyId const l_SysTick_Handler = { 0U }; static QSpyId const l_GPIOPortA_IRQHandler = { 0U }; #define UART_BAUD_RATE 115200U - #define UART_FR_TXFE (1U << 7) - #define UART_FR_RXFE (1U << 4) + #define UART_FR_TXFE (1U << 7U) + #define UART_FR_RXFE (1U << 4U) #define UART_TXFIFO_DEPTH 16U - enum AppRecords { /* application-specific trace records */ + enum AppRecords { // application-specific trace records PHILO_STAT = QS_USER, PAUSED_STAT, CONTEXT_SW, - COMMAND_STAT }; #endif -/*..........................................................................*/ +//============================================================================ +// Error handler and ISRs... + +Q_NORETURN Q_onError(char const * const module, int_t const id) { + // NOTE: this implementation of the error handler is intended only + // for debugging and MUST be changed for deployment of the application + // (assuming that you ship your production code with assertions enabled). + Q_UNUSED_PAR(module); + Q_UNUSED_PAR(id); + QS_ASSERTION(module, id, 10000U); // report assertion to QS + +#ifndef NDEBUG + // light up all LEDs + GPIOF_AHB->DATA_Bits[LED_GREEN | LED_RED | LED_BLUE] = 0xFFU; + for (;;) { // for debugging, hang on in an endless loop... + } +#else + NVIC_SystemReset(); + for (;;) { // explicitly "no-return" + } +#endif +} +//............................................................................ +void assert_failed(char const * const module, int_t const id); // prototype +void assert_failed(char const * const module, int_t const id) { + Q_onError(module, id); +} + +// ISRs used in the application ============================================ + +void SysTick_Handler(void); // prototype void SysTick_Handler(void) { - QXK_ISR_ENTRY(); /* inform QXK about entering an ISR */ + QXK_ISR_ENTRY(); // inform QXK about entering an ISR - /* process time events for clock rate 0 */ - QTIMEEVT_TICK_X(0U, &l_SysTick_Handler); + QTIMEEVT_TICK_X(0U, &l_SysTick_Handler); // time events at rate 0 - /* Perform the debouncing of buttons. The algorithm for debouncing - * adapted from the book "Embedded Systems Dictionary" by Jack Ganssle - * and Michael Barr, page 71. - */ - /* state of the button debouncing, see below */ - static struct ButtonsDebouncing { + // Perform the debouncing of buttons. The algorithm for debouncing + // adapted from the book "Embedded Systems Dictionary" by Jack Ganssle + // and Michael Barr, page 71. + static struct { uint32_t depressed; uint32_t previous; } buttons = { 0U, 0U }; - uint32_t current = ~GPIOF_AHB->DATA_Bits[BTN_SW1 | BTN_SW2]; /* read SW1&SW2 */ - uint32_t tmp = buttons.depressed; /* save debounced depressed buttons */ - buttons.depressed |= (buttons.previous & current); /* set depressed */ - buttons.depressed &= (buttons.previous | current); /* clear released */ - buttons.previous = current; /* update the history */ - tmp ^= buttons.depressed; /* changed debounced depressed */ - if ((tmp & BTN_SW1) != 0U) { /* debounced SW1 state changed? */ - if ((buttons.depressed & BTN_SW1) != 0U) { /* is SW1 depressed? */ - static QEvt const pauseEvt = { PAUSE_SIG, 0U, 0U}; + + uint32_t current = ~GPIOF_AHB->DATA_Bits[BTN_SW1 | BTN_SW2]; + uint32_t tmp = buttons.depressed; // save debounced depressed buttons + buttons.depressed |= (buttons.previous & current); // set depressed + buttons.depressed &= (buttons.previous | current); // clear released + buttons.previous = current; // update the history + tmp ^= buttons.depressed; // changed debounced depressed + current = buttons.depressed; + + if ((tmp & BTN_SW1) != 0U) { // debounced SW1 state changed? + if ((current & BTN_SW1) != 0U) { // is SW1 depressed? + static QEvt const pauseEvt = QEVT_INITIALIZER(PAUSE_SIG); QACTIVE_PUBLISH(&pauseEvt, &l_SysTick_Handler); } - else { /* the button is released */ - static QEvt const serveEvt = { SERVE_SIG, 0U, 0U}; + else { // the button is released + static QEvt const serveEvt = QEVT_INITIALIZER(SERVE_SIG); QACTIVE_PUBLISH(&serveEvt, &l_SysTick_Handler); } } - if ((tmp & BTN_SW2) != 0U) { /* debounced SW2 state changed? */ - /* TEST: of MPU */ - uint32_t volatile foo = *(uint32_t volatile *)0x204U; // legal - *(uint32_t volatile *)0x204U = foo; // illegal - } - QXK_ISR_EXIT(); /* inform QXK about exiting an ISR */ + QXK_ISR_EXIT(); // inform QXK about exiting an ISR } -/*..........................................................................*/ +//............................................................................ +// interrupt handler for testing preemptions in QXK +void GPIOPortA_IRQHandler(void); // prototype void GPIOPortA_IRQHandler(void) { - QXK_ISR_ENTRY(); /* inform QXK about entering an ISR */ + QXK_ISR_ENTRY(); // inform QXK about entering an ISR - QACTIVE_PUBLISH(Q_NEW(QEvt, TEST_SIG), /* for testing... */ - &l_GPIOPortA_IRQHandler); + QEvt const testEvt = QEVT_INITIALIZER(MAX_PUB_SIG); + QACTIVE_POST(AO_Table, &testEvt, + &l_GPIOPortA_IRQHandler); - QXK_ISR_EXIT(); /* inform QXK about exiting an ISR */ + QXK_ISR_EXIT(); // inform QXK about exiting an ISR } -/*..........................................................................*/ -#ifdef Q_SPY -/* -* ISR for receiving bytes from the QSPY Back-End -* NOTE: This ISR is "QF-unaware" meaning that it does not interact with -* the QF/QXK and is not disabled. Such ISRs don't need to call QXK_ISR_ENTRY/ -* QXK_ISR_EXIT and they cannot post or publish events. -*/ -void UART0_IRQHandler(void) { - uint32_t status = UART0->RIS; /* get the raw interrupt status */ - UART0->ICR = status; /* clear the asserted interrupts */ - while ((UART0->FR & UART_FR_RXFE) == 0) { /* while RX FIFO NOT empty */ - uint32_t b = UART0->DR; - QS_RX_PUT(b); +//............................................................................ +#ifdef Q_SPY +// ISR for receiving bytes from the QSPY Back-End +// NOTE: This ISR is "QF-unaware" meaning that it does not interact with +// the QF/QXK and is not disabled. Such ISRs don't need to call +// QXK_ISR_ENTRY/QXK_ISR_EXIT and they cannot post or publish events. + +void UART0_IRQHandler(void); // prototype +void UART0_IRQHandler(void) { + uint32_t status = UART0->RIS; // get the raw interrupt status + UART0->ICR = status; // clear the asserted interrupts + + while ((UART0->FR & UART_FR_RXFE) == 0U) { // while RX FIFO NOT empty + uint8_t b = (uint8_t)UART0->DR; + QS_rxPut(b); } + QXK_ARM_ERRATUM_838869(); } -#else -void UART0_IRQHandler(void) {} -#endif +#endif // Q_SPY -/* BSP functions ===========================================================*/ -/* MPU setup for TM4C123GXL MCU */ -static void TM4C123GXL_MPU_setup(void) { - /* The following MPU configuration contains the general TM4C memory map. - * - * Please note that the actual TM4C MCUs provide much less Flash and SRAM - * than the maximums configured here. This means that actual MCUs have - * unmapped memory regions (e.g., beyond the actual SRAM). Attempts to - * access these regions causes the HardFault exception, which is the - * desired behavior. - */ - static struct { - uint32_t rbar; - uint32_t rasr; - } const mpu_setup[] = { - { /* region #0: Flash: base=0x0000'0000, size=512M=2^(28+1) */ - 0x00000000U /* base address */ - | MPU_RBAR_VALID_Msk /* valid region */ - | (MPU_RBAR_REGION_Msk & 0U), /* region #0 */ - (28U << MPU_RASR_SIZE_Pos) /* 2^(18+1) region */ - | (0x6U << MPU_RASR_AP_Pos) /* PA:ro/UA:ro */ - | (1U << MPU_RASR_C_Pos) /* C=1 */ - | MPU_RASR_ENABLE_Msk /* region enable */ - }, +//............................................................................ +#ifdef QF_ON_CONTEXT_SW +// NOTE: the context-switch callback is called with interrupts DISABLED +void QF_onContextSw(QActive *prev, QActive *next) { + QS_BEGIN_INCRIT(CONTEXT_SW, 0U) // in critical section! + QS_OBJ(prev); + QS_OBJ(next); + QS_END_INCRIT() +} +#endif // QF_ON_CONTEXT_SW - { /* region #1: SRAM: base=0x2000'0000, size=512M=2^(28+1) */ - 0x20000000U /* base address */ - | MPU_RBAR_VALID_Msk /* valid region */ - | (MPU_RBAR_REGION_Msk & 1U), /* region #1 */ - (28U << MPU_RASR_SIZE_Pos) /* 2^(28+1) region */ - | (0x3U << MPU_RASR_AP_Pos) /* PA:rw/UA:rw */ - | (1U << MPU_RASR_XN_Pos) /* XN=1 */ - | (1U << MPU_RASR_S_Pos) /* S=1 */ - | (1U << MPU_RASR_C_Pos) /* C=1 */ - | MPU_RASR_ENABLE_Msk /* region enable */ - }, +//============================================================================ +// BSP functions... - /* region #3: (not configured) */ - { MPU_RBAR_VALID_Msk | (MPU_RBAR_REGION_Msk & 2U), 0U }, +void BSP_init(void) { + // Configure the MPU to prevent NULL-pointer dereferencing ... + MPU->RBAR = 0x0U // base address (NULL) + | MPU_RBAR_VALID_Msk // valid region + | (MPU_RBAR_REGION_Msk & 7U); // region #7 + MPU->RASR = (7U << MPU_RASR_SIZE_Pos) // 2^(7+1) region + | (0x0U << MPU_RASR_AP_Pos) // no-access region + | MPU_RASR_ENABLE_Msk; // region enable + MPU->CTRL = MPU_CTRL_PRIVDEFENA_Msk // enable background region + | MPU_CTRL_ENABLE_Msk; // enable the MPU + __ISB(); + __DSB(); - { /* region #3: Peripherals: base=0x4000'0000, size=512M=2^(28+1) */ - 0x40000000U /* base address */ - | MPU_RBAR_VALID_Msk /* valid region */ - | (MPU_RBAR_REGION_Msk & 3U), /* region #3 */ - (28U << MPU_RASR_SIZE_Pos) /* 2^(28+1) region */ - | (0x3U << MPU_RASR_AP_Pos) /* PA:rw/UA:rw */ - | (1U << MPU_RASR_XN_Pos) /* XN=1 */ - | (1U << MPU_RASR_S_Pos) /* S=1 */ - | (1U << MPU_RASR_B_Pos) /* B=1 */ - | MPU_RASR_ENABLE_Msk /* region enable */ - }, - - { /* region #4: Priv. Periph: base=0xE000'0000, size=512M=2^(28+1) */ - 0xE0000000U /* base address */ - | MPU_RBAR_VALID_Msk /* valid region */ - | (MPU_RBAR_REGION_Msk & 4U), /* region #4 */ - (28U << MPU_RASR_SIZE_Pos) /* 2^(28+1) region */ - | (0x3U << MPU_RASR_AP_Pos) /* PA:rw/UA:rw */ - | (1U << MPU_RASR_XN_Pos) /* XN=1 */ - | (1U << MPU_RASR_S_Pos) /* S=1 */ - | (1U << MPU_RASR_B_Pos) /* B=1 */ - | MPU_RASR_ENABLE_Msk /* region enable */ - }, - - { /* region #5: Ext RAM: base=0x6000'0000, size=1G=2^(29+1) */ - 0x60000000U /* base address */ - | MPU_RBAR_VALID_Msk /* valid region */ - | (MPU_RBAR_REGION_Msk & 5U), /* region #5 */ - (29U << MPU_RASR_SIZE_Pos) /* 2^(28+1) region */ - | (0x3U << MPU_RASR_AP_Pos) /* PA:rw/UA:rw */ - | (1U << MPU_RASR_XN_Pos) /* XN=1 */ - | (1U << MPU_RASR_S_Pos) /* S=1 */ - | (1U << MPU_RASR_B_Pos) /* B=1 */ - | MPU_RASR_ENABLE_Msk /* region enable */ - }, - - { /* region #6: Ext Dev: base=0xA000'0000, size=1G=2^(29+1) */ - 0xA0000000U /* base address */ - | MPU_RBAR_VALID_Msk /* valid region */ - | (MPU_RBAR_REGION_Msk & 6U), /* region #6 */ - (29U << MPU_RASR_SIZE_Pos) /* 2^(28+1) region */ - | (0x3U << MPU_RASR_AP_Pos) /* PA:rw/UA:rw */ - | (1U << MPU_RASR_XN_Pos) /* XN=1 */ - | (1U << MPU_RASR_S_Pos) /* S=1 */ - | (1U << MPU_RASR_B_Pos) /* B=1 */ - | MPU_RASR_ENABLE_Msk /* region enable */ - }, - - { /* region #7: NULL-pointer: base=0x000'0000, size=256B */ - 0x00000000U /* base address */ - | MPU_RBAR_VALID_Msk /* valid region */ - | (MPU_RBAR_REGION_Msk & 7U), /* region #7 */ - (7U << MPU_RASR_SIZE_Pos) /* 2^(7+1)=256B region */ - | (0x0U << MPU_RASR_AP_Pos) /* PA:na/UA:na */ - | (1U << MPU_RASR_XN_Pos) /* XN=1 */ - | MPU_RASR_ENABLE_Msk /* region enable */ - }, - }; - - /* enable the MemManage_Handler for MPU exception */ + // enable the MemManage_Handler for MPU exception SCB->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk; - __DSB(); - MPU->CTRL = 0U; /* disable the MPU */ - for (uint_fast8_t n = 0U; n < Q_DIM(mpu_setup); ++n) { - MPU->RBAR = mpu_setup[n].rbar; - MPU->RASR = mpu_setup[n].rasr; - } - MPU->CTRL = MPU_CTRL_ENABLE_Msk; /* enable the MPU */ - __ISB(); - __DSB(); -} - -/*..........................................................................*/ -void BSP_init(void) { - /* setup the MPU... */ - TM4C123GXL_MPU_setup(); - - /* NOTE: SystemInit() already called from the startup code - * but SystemCoreClock needs to be updated - */ + // NOTE: SystemInit() has been already called from the startup code + // but SystemCoreClock needs to be updated SystemCoreClockUpdate(); - /* NOTE: The VFP (hardware Floating Point) unit is configured by QXK */ + // NOTE: The VFP (hardware Floating Point) unit is configured by QXK - /* enable clock for to the peripherals used by this application... */ - SYSCTL->RCGCGPIO |= (1U << 5); /* enable Run mode for GPIOF */ - SYSCTL->GPIOHBCTL |= (1U << 5); /* enable AHB for GPIOF */ + // enable clock for to the peripherals used by this application... + SYSCTL->RCGCGPIO |= (1U << 5U); // enable Run mode for GPIOF + SYSCTL->GPIOHBCTL |= (1U << 5U); // enable AHB for GPIOF __ISB(); __DSB(); - /* configure LEDs (digital output) */ + // configure LEDs (digital output) GPIOF_AHB->DIR |= (LED_RED | LED_BLUE | LED_GREEN); GPIOF_AHB->DEN |= (LED_RED | LED_BLUE | LED_GREEN); GPIOF_AHB->DATA_Bits[LED_RED | LED_BLUE | LED_GREEN] = 0U; - /* configure switches... */ + // configure switches... - /* unlock access to the SW2 pin because it is PROTECTED */ - GPIOF_AHB->LOCK = 0x4C4F434BU; /* unlock GPIOCR register for SW2 */ - /* commit the write (cast const away) */ + // unlock access to the SW2 pin because it is PROTECTED + GPIOF_AHB->LOCK = 0x4C4F434BU; // unlock GPIOCR register for SW2 + // commit the write (cast const away) *(uint32_t volatile *)&GPIOF_AHB->CR = 0x01U; - GPIOF_AHB->DIR &= ~(BTN_SW1 | BTN_SW2); /* input */ - GPIOF_AHB->DEN |= (BTN_SW1 | BTN_SW2); /* digital enable */ - GPIOF_AHB->PUR |= (BTN_SW1 | BTN_SW2); /* pull-up resistor enable */ + GPIOF_AHB->DIR &= ~(BTN_SW1 | BTN_SW2); // input + GPIOF_AHB->DEN |= (BTN_SW1 | BTN_SW2); // digital enable + GPIOF_AHB->PUR |= (BTN_SW1 | BTN_SW2); // pull-up resistor enable *(uint32_t volatile *)&GPIOF_AHB->CR = 0x00U; - GPIOF_AHB->LOCK = 0x0; /* lock GPIOCR register for SW2 */ + GPIOF_AHB->LOCK = 0x0; // lock GPIOCR register for SW2 - /* seed the random number generator */ + // seed the random number generator BSP_randomSeed(1234U); - /* initialize the QS software tracing... */ - if (QS_INIT((void *)0) == 0U) { + // initialize the QS software tracing... + if (!QS_INIT((void *)0)) { Q_ERROR(); } + + // dictionaries... QS_OBJ_DICTIONARY(&l_SysTick_Handler); QS_OBJ_DICTIONARY(&l_GPIOPortA_IRQHandler); QS_USR_DICTIONARY(PHILO_STAT); QS_USR_DICTIONARY(PAUSED_STAT); - QS_USR_DICTIONARY(COMMAND_STAT); + QS_USR_DICTIONARY(CONTEXT_SW); - /* setup the QS filters... */ - QS_GLB_FILTER(QS_ALL_RECORDS); /* all records */ - QS_GLB_FILTER(-QS_QF_TICK); /* exclude the clock tick */ + QS_ONLY(produce_sig_dict()); + + // setup the QS filters... + QS_GLB_FILTER(QS_ALL_RECORDS); // all records + QS_GLB_FILTER(-QS_QF_TICK); // exclude the clock tick } -/*..........................................................................*/ +//............................................................................ +void BSP_start(void) { + // initialize event pools + static QF_MPOOL_EL(TableEvt) smlPoolSto[2*N_PHILO]; + QF_poolInit(smlPoolSto, sizeof(smlPoolSto), sizeof(smlPoolSto[0])); + + // initialize publish-subscribe + static QSubscrList subscrSto[MAX_PUB_SIG]; + QActive_psInit(subscrSto, Q_DIM(subscrSto)); + + // instantiate and start AOs/threads... + static QEvt const *xThread1QueueSto[5]; + static uint64_t xThread1StackSto[64]; + XThread1_ctor(); + QXTHREAD_START(TH_XThread1, + 1U, // QP priority of the thread + xThread1QueueSto, // event queue storage + Q_DIM(xThread1QueueSto), // event length [events] + xThread1StackSto, // stack storage + sizeof(xThread1StackSto), // stack size [bytes] + (void *)0); // no initialization param + + static QEvt const *philoQueueSto[N_PHILO][10]; + for (uint8_t n = 0U; n < N_PHILO; ++n) { + Philo_ctor(n); + QACTIVE_START(AO_Philo[n], + n + 3U, // QF-prio. + philoQueueSto[n], // event queue storage + Q_DIM(philoQueueSto[n]), // queue length [events] + (void *)0, 0U, // no stack storage + (void *)0); // no initialization param + } + + static QEvt const *xThread2QueueSto[5]; + static uint64_t xThread2StackSto[64]; + XThread2_ctor(); + QXTHREAD_START(TH_XThread2, + N_PHILO + 5U, // QP priority of the thread + xThread2QueueSto, // event queue storage + Q_DIM(xThread2QueueSto), // event length [events] + xThread2StackSto, // stack storage + sizeof(xThread2StackSto), // stack size [bytes] + (void *)0); // no initialization param + + static QEvt const *tableQueueSto[N_PHILO]; + Table_ctor(); + QACTIVE_START(AO_Table, + N_PHILO + 7U, // QP prio. of the AO + tableQueueSto, // event queue storage + Q_DIM(tableQueueSto), // queue length [events] + (void *)0, 0U, // no stack storage + (void *)0); // no initialization param +} +//............................................................................ void BSP_displayPhilStat(uint8_t n, char const *stat) { + Q_UNUSED_PAR(n); + GPIOF_AHB->DATA_Bits[LED_GREEN] = ((stat[0] == 'e') ? LED_GREEN : 0U); - QS_BEGIN_ID(PHILO_STAT, AO_Philo[n]->prio) /* app-specific record */ - QS_U8(1, n); /* Philosopher number */ - QS_STR(stat); /* Philosopher status */ + // app-specific trace record... + QS_BEGIN_ID(PHILO_STAT, AO_Table->prio) + QS_U8(1, n); // Philosopher number + QS_STR(stat); // Philosopher status QS_END() } -/*..........................................................................*/ -void BSP_displayPaused(uint8_t paused) { +//............................................................................ +void BSP_displayPaused(uint8_t const paused) { GPIOF_AHB->DATA_Bits[LED_BLUE] = ((paused != 0U) ? LED_BLUE : 0U); - QS_BEGIN_ID(PAUSED_STAT, 0U) /* app-specific record */ - QS_U8(1, paused); /* Paused status */ + // application-specific trace record + QS_BEGIN_ID(PAUSED_STAT, AO_Table->prio) + QS_U8(1, paused); // Paused status QS_END() } -/*..........................................................................*/ -uint32_t BSP_random(void) { /* a very cheap pseudo-random-number generator */ - /* Some flating point code is to exercise the VFP... */ +//............................................................................ +void BSP_randomSeed(uint32_t seed) { + l_rndSeed = seed; +} +//............................................................................ +uint32_t BSP_random(void) { // a very cheap pseudo-random-number generator + // Some floating point code is to exercise the VFP... float volatile x = 3.1415926F; x = x + 2.7182818F; - /* lock scheduler around shared seed */ - QSchedStatus lockStat = QXK_schedLock(N_PHILO); - QSchedStatus lockStat1 = QXK_schedLock(N_PHILO + 1U); /* nested lock */ - /* "Super-Duper" Linear Congruential Generator (LCG) - * LCG(2^32, 3*7*11*13*23, 0, seed) - */ - l_rnd = l_rnd * (3U*7U*11U*13U*23U); - QXK_schedUnlock(lockStat1); /* unlock the scheduler */ - QXK_schedUnlock(lockStat); /* unlock the scheduler */ + QSchedStatus lockStat = QXK_schedLock(N_PHILO); // N_PHILO prio. ceiling + // "Super-Duper" Linear Congruential Generator (LCG) + // LCG(2^32, 3*7*11*13*23, 0, seed) + uint32_t rnd = l_rndSeed * (3U*7U*11U*13U*23U); + l_rndSeed = rnd; // set for the next time + QXK_schedUnlock(lockStat); - return l_rnd >> 8; + return (rnd >> 8U); } -/*..........................................................................*/ -void BSP_randomSeed(uint32_t seed) { - l_rnd = seed; -} -/*..........................................................................*/ +//............................................................................ void BSP_ledOn(void) { GPIOF_AHB->DATA_Bits[LED_RED] = 0xFFU; } -/*..........................................................................*/ +//............................................................................ void BSP_ledOff(void) { GPIOF_AHB->DATA_Bits[LED_RED] = 0x00U; } -/*..........................................................................*/ +//............................................................................ void BSP_terminate(int16_t result) { - (void)result; + Q_UNUSED_PAR(result); } -/* QF callbacks ============================================================*/ +//============================================================================ +// QF callbacks... void QF_onStartup(void) { - /* set up the SysTick timer to fire at BSP_TICKS_PER_SEC rate */ + // set up the SysTick timer to fire at BSP_TICKS_PER_SEC rate SysTick_Config(SystemCoreClock / BSP_TICKS_PER_SEC); - /* assing all priority bits for preemption-prio. and none to sub-prio. */ + // assign all priority bits for preemption-prio. and none to sub-prio. NVIC_SetPriorityGrouping(0U); - /* set priorities of ALL ISRs used in the system, see NOTE1 - * - * !!!!!!!!!!!!!!!!!!!!!!!!!!!! CAUTION !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - * Assign a priority to EVERY ISR explicitly by calling NVIC_SetPriority(). - * DO NOT LEAVE THE ISR PRIORITIES AT THE DEFAULT VALUE! - */ - NVIC_SetPriority(UART0_IRQn, 0U); /* kernel unaware interrupt */ - NVIC_SetPriority(GPIOA_IRQn, QF_AWARE_ISR_CMSIS_PRI); - NVIC_SetPriority(SysTick_IRQn, QF_AWARE_ISR_CMSIS_PRI + 1U); - /* ... */ + // set priorities of ALL ISRs used in the system, see NOTE1 + NVIC_SetPriority(UART0_IRQn, 0U); // kernel UNAWARE interrupt + NVIC_SetPriority(GPIOA_IRQn, QF_AWARE_ISR_CMSIS_PRI + 0U); + NVIC_SetPriority(SysTick_IRQn, QF_AWARE_ISR_CMSIS_PRI + 1U); + // ... - /* enable IRQs... */ + // enable IRQs in the NVIC... NVIC_EnableIRQ(GPIOA_IRQn); #ifdef Q_SPY - NVIC_EnableIRQ(UART0_IRQn); /* UART0 interrupt used for QS-RX */ + NVIC_EnableIRQ(UART0_IRQn); // UART interrupt used for QS-RX #endif } -/*..........................................................................*/ +//............................................................................ void QF_onCleanup(void) { } -/*..........................................................................*/ -#ifdef QF_ON_CONTEXT_SW -/* NOTE: the context-switch callback is called with interrupts DISABLED */ -void QF_onContextSw(QActive *prev, QActive *next) { - if (next != (QActive *)0) { - //_impure_ptr = next->thread; /* switch to next TLS */ - } - QS_BEGIN_NOCRIT(CONTEXT_SW, 0U) /* no critical section! */ - QS_OBJ(prev); - QS_OBJ(next); - QS_END_NOCRIT() -} -#endif /* QF_ON_CONTEXT_SW */ -/*..........................................................................*/ +//............................................................................ void QXK_onIdle(void) { - /* toggle the User LED on and then off, see NOTE2 */ + // toggle the User LED on and then off, see NOTE2 QF_INT_DISABLE(); - GPIOF_AHB->DATA_Bits[LED_BLUE] = 0xFFU; /* turn the Blue LED on */ - GPIOF_AHB->DATA_Bits[LED_BLUE] = 0U; /* turn the Blue LED off */ + GPIOF_AHB->DATA_Bits[LED_BLUE] = 0xFFU; // turn the Blue LED on + GPIOF_AHB->DATA_Bits[LED_BLUE] = 0U; // turn the Blue LED off QF_INT_ENABLE(); - /* Some flating point code is to exercise the VFP... */ + // Some floating point code is to exercise the VFP... float volatile x = 1.73205F; x = x * 1.73205F; #ifdef Q_SPY - QS_rxParse(); /* parse all the received bytes */ + QF_INT_DISABLE(); + QS_rxParse(); // parse all the received bytes + QF_INT_ENABLE(); - if ((UART0->FR & UART_FR_TXFE) != 0U) { /* TX done? */ - uint16_t fifo = UART_TXFIFO_DEPTH; /* max bytes we can accept */ + if ((UART0->FR & UART_FR_TXFE) != 0U) { // TX done? + uint16_t fifo = UART_TXFIFO_DEPTH; // max bytes we can accept QF_INT_DISABLE(); - /* try to get next contiguous block to transmit */ uint8_t const *block = QS_getBlock(&fifo); QF_INT_ENABLE(); - while (fifo-- != 0) { /* any bytes in the block? */ - UART0->DR = *block++; /* put into the FIFO */ + while (fifo-- != 0U) { // any bytes in the block? + UART0->DR = *block++; // put into the FIFO } } #elif defined NDEBUG - /* Put the CPU and peripherals to the low-power mode. - * you might need to customize the clock management for your application, - * see the datasheet for your particular Cortex-M MCU. - */ - __WFI(); /* Wait-For-Interrupt */ + // Put the CPU and peripherals to the low-power mode. + // you might need to customize the clock management for your application, + // see the datasheet for your particular Cortex-M MCU. + // + __WFI(); // Wait-For-Interrupt #endif } -/*..........................................................................*/ -Q_NORETURN Q_onAssert(char const * const module, int_t const loc) { - /* - * NOTE: add here your application-specific error handling - */ - (void)module; - (void)loc; - QS_ASSERTION(module, loc, 10000U); /* report assertion to QS */ - -#ifndef NDEBUG - /* light up all LEDs */ - GPIOF_AHB->DATA_Bits[LED_GREEN | LED_RED | LED_BLUE] = 0xFFU; - /* for debugging, hang on in an endless loop... */ - for (;;) { - } -#endif - - NVIC_SystemReset(); -} - -/* QS callbacks ============================================================*/ +//============================================================================ +// QS callbacks... #ifdef Q_SPY -/*..........................................................................*/ + +//............................................................................ uint8_t QS_onStartup(void const *arg) { Q_UNUSED_PAR(arg); - static uint8_t qsTxBuf[2*1024]; /* buffer for QS-TX channel */ - static uint8_t qsRxBuf[100]; /* buffer for QS-RX channel */ + static uint8_t qsTxBuf[2*1024]; // buffer for QS-TX channel + QS_initBuf(qsTxBuf, sizeof(qsTxBuf)); - QS_initBuf (qsTxBuf, sizeof(qsTxBuf)); + static uint8_t qsRxBuf[100]; // buffer for QS-RX channel QS_rxInitBuf(qsRxBuf, sizeof(qsRxBuf)); - /* enable clock for UART0 and GPIOA (used by UART0 pins) */ - SYSCTL->RCGCUART |= (1U << 0); /* enable Run mode for UART0 */ - SYSCTL->RCGCGPIO |= (1U << 0); /* enable Run mode for GPIOA */ + // enable clock for UART0 and GPIOA (used by UART0 pins) + SYSCTL->RCGCUART |= (1U << 0U); // enable Run mode for UART0 + SYSCTL->RCGCGPIO |= (1U << 0U); // enable Run mode for GPIOA - /* configure UART0 pins for UART operation */ - uint32_t tmp = (1U << 0) | (1U << 1); + // configure UART0 pins for UART operation + uint32_t tmp = (1U << 0U) | (1U << 1U); GPIOA->DIR &= ~tmp; GPIOA->SLR &= ~tmp; GPIOA->ODR &= ~tmp; GPIOA->PUR &= ~tmp; GPIOA->PDR &= ~tmp; - GPIOA->AMSEL &= ~tmp; /* disable analog function on the pins */ - GPIOA->AFSEL |= tmp; /* enable ALT function on the pins */ - GPIOA->DEN |= tmp; /* enable digital I/O on the pins */ + GPIOA->AMSEL &= ~tmp; // disable analog function on the pins + GPIOA->AFSEL |= tmp; // enable ALT function on the pins + GPIOA->DEN |= tmp; // enable digital I/O on the pins GPIOA->PCTL &= ~0x00U; GPIOA->PCTL |= 0x11U; - /* configure the UART for the desired baud rate, 8-N-1 operation */ + // configure the UART for the desired baud rate, 8-N-1 operation tmp = (((SystemCoreClock * 8U) / UART_BAUD_RATE) + 1U) / 2U; UART0->IBRD = tmp / 64U; UART0->FBRD = tmp % 64U; - UART0->LCRH = (0x3U << 5); /* configure 8-N-1 operation */ - UART0->LCRH |= (0x1U << 4); /* enable FIFOs */ - UART0->CTL = (1U << 0) /* UART enable */ - | (1U << 8) /* UART TX enable */ - | (1U << 9); /* UART RX enable */ + UART0->LCRH = (0x3U << 5U); // configure 8-N-1 operation + UART0->LCRH |= (0x1U << 4U); // enable FIFOs + UART0->CTL = (1U << 0U) // UART enable + | (1U << 8U) // UART TX enable + | (1U << 9U); // UART RX enable - /* configure UART interrupts (for the RX channel) */ - UART0->IM |= (1U << 4) | (1U << 6); /* enable RX and RX-TO interrupt */ - UART0->IFLS |= (0x2U << 2); /* interrupt on RX FIFO half-full */ - /* NOTE: do not enable the UART0 interrupt yet. Wait till QF_onStartup() */ + // configure UART interrupts (for the RX channel) + UART0->IM |= (1U << 4U) | (1U << 6U); // enable RX and RX-TO interrupt + UART0->IFLS |= (0x2U << 2U); // interrupt on RX FIFO half-full + // NOTE: do not enable the UART0 interrupt yet. Wait till QF_onStartup() - /* configure TIMER5 to produce QS time stamp */ - SYSCTL->RCGCTIMER |= (1U << 5); /* enable run mode for Timer5 */ - TIMER5->CTL = 0U; /* disable Timer1 output */ - TIMER5->CFG = 0x0U; /* 32-bit configuration */ - TIMER5->TAMR = (1U << 4) | 0x02; /* up-counting periodic mode */ - TIMER5->TAILR= 0xFFFFFFFFU; /* timer interval */ - TIMER5->ICR = 0x1U; /* TimerA timeout flag bit clears*/ - TIMER5->CTL |= (1U << 0); /* enable TimerA module */ + // configure TIMER5 to produce QS time stamp + SYSCTL->RCGCTIMER |= (1U << 5U); // enable run mode for Timer5 + TIMER5->CTL = 0U; // disable Timer1 output + TIMER5->CFG = 0x0U; // 32-bit configuration + TIMER5->TAMR = (1U << 4U) | 0x02U; // up-counting periodic mode + TIMER5->TAILR= 0xFFFFFFFFU; // timer interval + TIMER5->ICR = 0x1U; // TimerA timeout flag bit clears + TIMER5->CTL |= (1U << 0U); // enable TimerA module - return 1U; /* return success */ + return 1U; // return success } -/*..........................................................................*/ +//............................................................................ void QS_onCleanup(void) { } -/*..........................................................................*/ -QSTimeCtr QS_onGetTime(void) { /* NOTE: invoked with interrupts DISABLED */ +//............................................................................ +QSTimeCtr QS_onGetTime(void) { // NOTE: invoked with interrupts DISABLED return TIMER5->TAV; } -/*..........................................................................*/ +//............................................................................ void QS_onFlush(void) { - while (true) { - /* try to get next byte to transmit */ + for (;;) { QF_INT_DISABLE(); uint16_t b = QS_getByte(); - QF_INT_ENABLE(); + if (b != QS_EOD) { + while ((UART0->FR & UART_FR_TXFE) == 0U) { // while TXE not empty + QF_INT_ENABLE(); + QF_CRIT_EXIT_NOP(); - if (b != QS_EOD) { /* NOT end-of-data */ - /* busy-wait as long as TX FIFO has data to transmit */ - while ((UART0->FR & UART_FR_TXFE) == 0) { + QF_INT_DISABLE(); } - /* place the byte in the UART DR register */ - UART0->DR = b; + UART0->DR = b; // put into the DR register + QF_INT_ENABLE(); } else { - break; /* break out of the loop */ + QF_INT_ENABLE(); + break; } } } -/*..........................................................................*/ -/*! callback function to reset the target (to be implemented in the BSP) */ +//............................................................................ +//! callback function to reset the target (to be implemented in the BSP) void QS_onReset(void) { NVIC_SystemReset(); } -/*..........................................................................*/ -/*! callback function to execute a user command (to be implemented in BSP) */ +//............................................................................ void QS_onCommand(uint8_t cmdId, uint32_t param1, uint32_t param2, uint32_t param3) { - QS_BEGIN_ID(COMMAND_STAT, 0U) /* app-specific record */ - QS_U8(2, cmdId); - QS_U32(8, param1); - QS_U32(8, param2); - QS_U32(8, param3); - QS_END() + Q_UNUSED_PAR(cmdId); + Q_UNUSED_PAR(param1); + Q_UNUSED_PAR(param2); + Q_UNUSED_PAR(param3); } -#endif /* Q_SPY */ -/*--------------------------------------------------------------------------*/ +#endif // Q_SPY +//---------------------------------------------------------------------------- -/*============================================================================ -* NOTE1: -* The QF_AWARE_ISR_CMSIS_PRI constant from the QF port specifies the highest -* ISR priority that is disabled by the QF framework. The value is suitable -* for the NVIC_SetPriority() CMSIS function. -* -* Only ISRs prioritized at or below the QF_AWARE_ISR_CMSIS_PRI level (i.e., -* with the numerical values of priorities equal or higher than -* QF_AWARE_ISR_CMSIS_PRI) are allowed to call the QXK_ISR_ENTRY/QXK_ISR_EXIT -* macros or any other QF/QXK services. These ISRs are "QF-aware". -* -* Conversely, any ISRs prioritized above the QF_AWARE_ISR_CMSIS_PRI priority -* level (i.e., with the numerical values of priorities less than -* QF_AWARE_ISR_CMSIS_PRI) are never disabled and are not aware of the kernel. -* Such "QF-unaware" ISRs cannot call any QF/QXK services. In particular they -* can NOT call the macros QXK_ISR_ENTRY/QXK_ISR_ENTRY. The only mechanism -* by which a "QF-unaware" ISR can communicate with the QF framework is by -* triggering a "QF-aware" ISR, which can post/publish events. -* -* NOTE2: -* The User LED is used to visualize the idle loop activity. The brightness -* of the LED is proportional to the frequency of invcations of the idle loop. -* Please note that the LED is toggled with interrupts locked, so no interrupt -* execution time contributes to the brightness of the User LED. -*/ +//============================================================================ +// NOTE1: +// The QF_AWARE_ISR_CMSIS_PRI constant from the QF port specifies the highest +// ISR priority that is disabled by the QF framework. The value is suitable +// for the NVIC_SetPriority() CMSIS function. +// +// Only ISRs prioritized at or below the QF_AWARE_ISR_CMSIS_PRI level (i.e., +// with the numerical values of priorities equal or higher than +// QF_AWARE_ISR_CMSIS_PRI) are allowed to call the QK_ISR_ENTRY/ +// QXK_ISR_ENTRY macros or any other QF/QXK services. These ISRs are +// "QF-aware". +// +// Conversely, any ISRs prioritized above the QF_AWARE_ISR_CMSIS_PRI priority +// level (i.e., with the numerical values of priorities less than +// QF_AWARE_ISR_CMSIS_PRI) are never disabled and are not aware of the kernel. +// Such "QF-unaware" ISRs cannot call ANY QF/QXK services. In particular they +// can NOT call the macros QXK_ISR_ENTRY/QXK_ISR_ENTRY. The only mechanism +// by which a "QF-unaware" ISR can communicate with the QF framework is by +// triggering a "QF-aware" ISR, which can post/publish events. +// +// NOTE2: +// The User LED is used to visualize the idle loop activity. The brightness +// of the LED is proportional to the frequency of the idle loop. +// Please note that the LED is toggled with interrupts locked, so no interrupt +// execution time contributes to the brightness of the User LED. +// diff --git a/examples/arm-cm/dpp_ek-tm4c123gxl/qxk/gnu/.ccsproject b/examples/arm-cm/dpp_ek-tm4c123gxl/qxk/gnu/.ccsproject new file mode 100644 index 00000000..0c19207c --- /dev/null +++ b/examples/arm-cm/dpp_ek-tm4c123gxl/qxk/gnu/.ccsproject @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/examples/arm-cm/dpp_ek-tm4c123gxl/qxk/gnu/.cproject b/examples/arm-cm/dpp_ek-tm4c123gxl/qxk/gnu/.cproject new file mode 100644 index 00000000..05053a3a --- /dev/null +++ b/examples/arm-cm/dpp_ek-tm4c123gxl/qxk/gnu/.cproject @@ -0,0 +1,277 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/arm-cm/dpp_ek-tm4c123gxl/qxk/gnu/.project b/examples/arm-cm/dpp_ek-tm4c123gxl/qxk/gnu/.project new file mode 100644 index 00000000..32f08a01 --- /dev/null +++ b/examples/arm-cm/dpp_ek-tm4c123gxl/qxk/gnu/.project @@ -0,0 +1,124 @@ + + + dpp-qxk + + + + + + org.eclipse.cdt.managedbuilder.core.genmakebuilder + + + + + org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder + full,incremental, + + + + + + com.ti.ccstudio.core.ccsNature + org.eclipse.cdt.core.cnature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + org.eclipse.cdt.core.ccnature + org.eclipse.cdt.managedbuilder.core.ScannerConfigNature + + + + QP + 2 + PARENT-5-PROJECT_LOC/src/qf + + + QP_port + 2 + PARENT-5-PROJECT_LOC/ports/arm-cm/qxk/gnu + + + QS + 2 + PARENT-5-PROJECT_LOC/src/qs + + + QXK + 2 + PARENT-5-PROJECT_LOC/src/qxk + + + TM4C123GH6PM.h + 1 + PARENT-5-PROJECT_LOC/3rd_party/ek-tm4c123gxl/TM4C123GH6PM.h + + + bsp.c + 1 + PARENT-1-PROJECT_LOC/bsp.c + + + bsp.h + 1 + PARENT-2-PROJECT_LOC/bsp.h + + + dpp.h + 1 + PARENT-2-PROJECT_LOC/dpp.h + + + gpio.h + 1 + PARENT-5-PROJECT_LOC/3rd_party/ek-tm4c123gxl/gpio.h + + + main.c + 1 + PARENT-1-PROJECT_LOC/main.c + + + philo.c + 1 + PARENT-2-PROJECT_LOC/philo.c + + + qstamp.c + 1 + PARENT-5-PROJECT_LOC/include/qstamp.c + + + rom.h + 1 + PARENT-5-PROJECT_LOC/3rd_party/ek-tm4c123gxl/rom.h + + + startup_TM4C123GH6PM.c + 1 + PARENT-5-PROJECT_LOC/3rd_party/ek-tm4c123gxl/gnu/startup_TM4C123GH6PM.c + + + sysctl.h + 1 + PARENT-5-PROJECT_LOC/3rd_party/ek-tm4c123gxl/sysctl.h + + + system_TM4C123GH6PM.c + 1 + PARENT-5-PROJECT_LOC/3rd_party/ek-tm4c123gxl/system_TM4C123GH6PM.c + + + system_TM4C123GH6PM.h + 1 + PARENT-5-PROJECT_LOC/3rd_party/ek-tm4c123gxl/system_TM4C123GH6PM.h + + + table.c + 1 + PARENT-2-PROJECT_LOC/table.c + + + test.c + 1 + PARENT-1-PROJECT_LOC/test.c + + + diff --git a/examples/arm-cm/dpp_ek-tm4c123gxl/qxk/gnu/Makefile b/examples/arm-cm/dpp_ek-tm4c123gxl/qxk/gnu/Makefile index 7c3977e7..8cfeef08 100644 --- a/examples/arm-cm/dpp_ek-tm4c123gxl/qxk/gnu/Makefile +++ b/examples/arm-cm/dpp_ek-tm4c123gxl/qxk/gnu/Makefile @@ -1,13 +1,13 @@ ############################################################################## # Product: Makefile for QP/C on EK-TM4C123GXL, QXK kernel, GNU-ARM -# Last Updated for Version: 7.0.1 -# Date of the Last Update: 2022-05-23 +# Last Updated for Version: 7.3.0 +# Date of the Last Update: 2023-09-07 # # Q u a n t u m L e a P s # ------------------------ # Modern Embedded Software # -# Copyright (C) 2005-2021 Quantum Leaps, LLC. All rights reserved. +# Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. # # This program is open source software: you can redistribute it and/or # modify it under the terms of the GNU General Public License as published @@ -45,8 +45,7 @@ # NOTE: # To use this Makefile on Windows, you will need the GNU make utility, which # is included in the Qtools collection for Windows, see: -# https://sourceforge.net/projects/qpc/files/QTools/ -# +# https://github.com/QuantumLeaps/qtools #----------------------------------------------------------------------------- # project name @@ -78,6 +77,7 @@ VPATH = \ # list of all include directories needed by this project INCLUDES = \ + -I.. \ -I../.. \ -I$(QPC)/include \ -I$(QP_PORT_DIR) \ @@ -97,7 +97,8 @@ C_SRCS := \ main.c \ philo.c \ table.c \ - test.c \ + xthread1.c \ + xthread2.c \ system_TM4C123GH6PM.c \ startup_TM4C123GH6PM.c @@ -137,7 +138,7 @@ LIB_DIRS := LIBS := # defines -DEFINES := -DTARGET_IS_TM4C123_RB1 +DEFINES := -DQP_CONFIG # ARM CPU, ARCH, FPU, and Float-ABI types... # ARM_CPU: [cortex-m0 | cortex-m0plus | cortex-m1 | cortex-m3 | cortex-m4] @@ -167,12 +168,11 @@ AS := $(GNU_ARM)/bin/arm-none-eabi-as LINK := $(GNU_ARM)/bin/arm-none-eabi-gcc BIN := $(GNU_ARM)/bin/arm-none-eabi-objcopy - ############################################################################## -# Typically, you should not need to change anything below this line +# Typically you should not need to change anything below this line -# basic utilities (included in Qtools for Windows), see: -# http://sourceforge.net/projects/qpc/files/Qtools +# basic utilities (included in QTools for Windows), see: +# https://www.state-machine.com/qtools MKDIR := mkdir RM := rm @@ -193,11 +193,11 @@ ASFLAGS = $(ARM_CPU) $(ARM_FPU) $(ASM_CPU) $(ASM_FPU) CFLAGS = -c $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \ -ffunction-sections -fdata-sections \ - -O1 $(INCLUDES) $(DEFINES) -DNDEBUG + -O2 $(INCLUDES) $(DEFINES) -DNDEBUG CPPFLAGS = -c $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \ -ffunction-sections -fdata-sections -fno-rtti -fno-exceptions \ - -O1 $(INCLUDES) $(DEFINES) -DNDEBUG + -O2 $(INCLUDES) $(DEFINES) -DNDEBUG else ifeq (spy, $(CONF)) # Spy configuration ................................ @@ -236,7 +236,6 @@ LINKFLAGS = -T$(LD_SCRIPT) $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb \ -specs=nosys.specs -specs=nano.specs \ -Wl,-Map,$(BIN_DIR)/$(OUTPUT).map,--cref,--gc-sections $(LIB_DIRS) - ASM_OBJS := $(patsubst %.s,%.o, $(notdir $(ASM_SRCS))) C_OBJS := $(patsubst %.c,%.o, $(notdir $(C_SRCS))) CPP_OBJS := $(patsubst %.cpp,%.o,$(notdir $(CPP_SRCS))) @@ -258,14 +257,20 @@ endif # rules # -all: $(TARGET_BIN) -#all: $(TARGET_ELF) +.PHONY : run norun flash + +ifeq ($(MAKECMDGOALS),norun) +all : $(TARGET_BIN) +norun : all +else +all : $(TARGET_BIN) run +endif $(TARGET_BIN): $(TARGET_ELF) $(BIN) -O binary $< $@ $(TARGET_ELF) : $(ASM_OBJS_EXT) $(C_OBJS_EXT) $(CPP_OBJS_EXT) - $(CC) $(CFLAGS) $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o + $(CC) $(CFLAGS) $(QPC)/src/qs/qstamp.c -o $(BIN_DIR)/qstamp.o $(LINK) $(LINKFLAGS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) $(BIN_DIR)/%.d : %.c @@ -283,6 +288,8 @@ $(BIN_DIR)/%.o : %.c $(BIN_DIR)/%.o : %.cpp $(CPP) $(CPPFLAGS) $< -o $@ +.PHONY : clean show + # include dependency files only if our goal depends on their existence ifneq ($(MAKECMDGOALS),clean) ifneq ($(MAKECMDGOALS),show) @@ -291,7 +298,6 @@ ifneq ($(MAKECMDGOALS),clean) endif -.PHONY : clean clean: -$(RM) $(BIN_DIR)/*.o \ $(BIN_DIR)/*.d \ diff --git a/examples/arm-cm/dpp_ek-tm4c123gxl/qxk/gnu/Makefile-UNSAFE b/examples/arm-cm/dpp_ek-tm4c123gxl/qxk/gnu/Makefile-UNSAFE new file mode 100644 index 00000000..04cdbaa2 --- /dev/null +++ b/examples/arm-cm/dpp_ek-tm4c123gxl/qxk/gnu/Makefile-UNSAFE @@ -0,0 +1,321 @@ +############################################################################## +# Product: Makefile for QP/C on EK-TM4C123GXL, QXK kernel, GNU-ARM +# Last Updated for Version: 7.3.0 +# Date of the Last Update: 2023-09-07 +# +# Q u a n t u m L e a P s +# ------------------------ +# Modern Embedded Software +# +# Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +# +# This program is open source software: you can redistribute it and/or +# modify it under the terms of the GNU General Public License as published +# by the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Alternatively, this program may be distributed and modified under the +# terms of Quantum Leaps commercial licenses, which expressly supersede +# the GNU General Public License and are specifically designed for +# licensees interested in retaining the proprietary status of their code. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# +# Contact information: +# +# +############################################################################## +# examples of invoking this Makefile: +# building configurations: Debug (default), Release, and Spy +# make +# make CONF=rel +# make CONF=spy +# +# cleaning configurations: Debug (default), Release, and Spy +# make clean +# make CONF=rel clean +# make CONF=spy clean +# +# NOTE: +# To use this Makefile on Windows, you will need the GNU make utility, which +# is included in the Qtools collection for Windows, see: +# https://github.com/QuantumLeaps/qtools + +#----------------------------------------------------------------------------- +# project name +# +PROJECT := dpp-qxk + +#----------------------------------------------------------------------------- +# project directories +# + +# location of the QP/C framework (if not provided in an environemnt var.) +ifeq ($(QPC),) +QPC := ../../../../.. +endif + +# QP port used in this project +QP_PORT_DIR := $(QPC)/ports/arm-cm/qxk/gnu + +# list of all source directories used by this project +VPATH = \ + .. \ + ../.. \ + $(QPC)/src/qf \ + $(QPC)/src/qxk \ + $(QPC)/src/qs \ + $(QP_PORT_DIR) \ + $(QPC)/3rd_party/ek-tm4c123gxl \ + $(QPC)/3rd_party/ek-tm4c123gxl/gnu + +# list of all include directories needed by this project +INCLUDES = \ + -I.. \ + -I../.. \ + -I$(QPC)/include \ + -I$(QP_PORT_DIR) \ + -I$(QPC)/3rd_party/CMSIS/Include \ + -I$(QPC)/3rd_party/ek-tm4c123gxl + +#----------------------------------------------------------------------------- +# files +# + +# assembler source files +ASM_SRCS := + +# C source files +C_SRCS := \ + bsp.c \ + main.c \ + philo.c \ + table.c \ + xthread1.c \ + xthread2.c \ + system_TM4C123GH6PM.c \ + startup_TM4C123GH6PM.c + +# C++ source files +CPP_SRCS := + +OUTPUT := $(PROJECT) +LD_SCRIPT := $(PROJECT).ld + +QP_SRCS := \ + qep_hsm.c \ + qep_msm.c \ + qf_act.c \ + qf_actq.c \ + qf_defer.c \ + qf_dyn.c \ + qf_mem.c \ + qf_ps.c \ + qf_qact.c \ + qf_qeq.c \ + qf_qmact.c \ + qf_time.c \ + qxk.c \ + qxk_xthr.c \ + qxk_sema.c \ + qxk_mutex.c \ + qxk_port.c + +QP_ASMS := + +QS_SRCS := \ + qs.c \ + qs_rx.c \ + qs_fp.c + +LIB_DIRS := +LIBS := + +# defines +DEFINES := -DQP_CONFIG \ + -DQ_UNSAFE + +# ARM CPU, ARCH, FPU, and Float-ABI types... +# ARM_CPU: [cortex-m0 | cortex-m0plus | cortex-m1 | cortex-m3 | cortex-m4] +# ARM_FPU: [ | vfp] +# FLOAT_ABI: [ | soft | softfp | hard] +# +ARM_CPU := -mcpu=cortex-m4 +ARM_FPU := -mfpu=vfp +FLOAT_ABI := -mfloat-abi=softfp + +#----------------------------------------------------------------------------- +# GNU-ARM toolset (NOTE: You need to adjust to your machine) +# see https://developer.arm.com/open-source/gnu-toolchain/gnu-rm/downloads +# +ifeq ($(GNU_ARM),) +GNU_ARM := $(QTOOLS)/gnu_arm-none-eabi +endif + +# make sure that the GNU-ARM toolset exists... +ifeq ("$(wildcard $(GNU_ARM))","") +$(error GNU_ARM toolset not found. Please adjust the Makefile) +endif + +CC := $(GNU_ARM)/bin/arm-none-eabi-gcc +CPP := $(GNU_ARM)/bin/arm-none-eabi-g++ +AS := $(GNU_ARM)/bin/arm-none-eabi-as +LINK := $(GNU_ARM)/bin/arm-none-eabi-gcc +BIN := $(GNU_ARM)/bin/arm-none-eabi-objcopy + +############################################################################## +# Typically you should not need to change anything below this line + +# basic utilities (included in QTools for Windows), see: +# https://www.state-machine.com/qtools + +MKDIR := mkdir +RM := rm + +#----------------------------------------------------------------------------- +# build options for various configurations for ARM Cortex-M +# + +# combine all the soruces... +C_SRCS += $(QP_SRCS) +ASM_SRCS += $(QP_ASMS) + +ifeq (rel, $(CONF)) # Release configuration .................................. + +BIN_DIR := rel + +ASFLAGS = $(ARM_CPU) $(ARM_FPU) $(ASM_CPU) $(ASM_FPU) + +CFLAGS = -c $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \ + -ffunction-sections -fdata-sections \ + -O2 $(INCLUDES) $(DEFINES) -DNDEBUG + +CPPFLAGS = -c $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \ + -ffunction-sections -fdata-sections -fno-rtti -fno-exceptions \ + -O2 $(INCLUDES) $(DEFINES) -DNDEBUG + +else ifeq (spy, $(CONF)) # Spy configuration ................................ + +BIN_DIR := spy + +C_SRCS += $(QS_SRCS) + +ASFLAGS = -g $(ARM_CPU) $(ARM_FPU) $(ASM_CPU) $(ASM_FPU) + +CFLAGS = -c -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \ + -ffunction-sections -fdata-sections \ + -O $(INCLUDES) $(DEFINES) -DQ_SPY + +CPPFLAGS = -c -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \ + -ffunction-sections -fdata-sections -fno-rtti -fno-exceptions \ + -O $(INCLUDES) $(DEFINES) -DQ_SPY + +else # default Debug configuration .......................................... + +BIN_DIR := dbg + +ASFLAGS = -g $(ARM_CPU) $(ARM_FPU) $(ASM_CPU) $(ASM_FPU) + +CFLAGS = -c -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \ + -ffunction-sections -fdata-sections \ + -O $(INCLUDES) $(DEFINES) + +CPPFLAGS = -c -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \ + -ffunction-sections -fdata-sections -fno-rtti -fno-exceptions \ + -O $(INCLUDES) $(DEFINES) + +endif # ...................................................................... + + +LINKFLAGS = -T$(LD_SCRIPT) $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb \ + -specs=nosys.specs -specs=nano.specs \ + -Wl,-Map,$(BIN_DIR)/$(OUTPUT).map,--cref,--gc-sections $(LIB_DIRS) + +ASM_OBJS := $(patsubst %.s,%.o, $(notdir $(ASM_SRCS))) +C_OBJS := $(patsubst %.c,%.o, $(notdir $(C_SRCS))) +CPP_OBJS := $(patsubst %.cpp,%.o,$(notdir $(CPP_SRCS))) + +TARGET_BIN := $(BIN_DIR)/$(OUTPUT).bin +TARGET_ELF := $(BIN_DIR)/$(OUTPUT).elf +ASM_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(ASM_OBJS)) +C_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(C_OBJS)) +C_DEPS_EXT := $(patsubst %.o, %.d, $(C_OBJS_EXT)) +CPP_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(CPP_OBJS)) +CPP_DEPS_EXT := $(patsubst %.o, %.d, $(CPP_OBJS_EXT)) + +# create $(BIN_DIR) if it does not exist +ifeq ("$(wildcard $(BIN_DIR))","") +$(shell $(MKDIR) $(BIN_DIR)) +endif + +#----------------------------------------------------------------------------- +# rules +# + +.PHONY : run norun flash + +ifeq ($(MAKECMDGOALS),norun) +all : $(TARGET_BIN) +norun : all +else +all : $(TARGET_BIN) run +endif + +$(TARGET_BIN): $(TARGET_ELF) + $(BIN) -O binary $< $@ + +$(TARGET_ELF) : $(ASM_OBJS_EXT) $(C_OBJS_EXT) $(CPP_OBJS_EXT) + $(CC) $(CFLAGS) $(QPC)/src/qs/qstamp.c -o $(BIN_DIR)/qstamp.o + $(LINK) $(LINKFLAGS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) + +$(BIN_DIR)/%.d : %.c + $(CC) -MM -MT $(@:.d=.o) $(CFLAGS) $< > $@ + +$(BIN_DIR)/%.d : %.cpp + $(CPP) -MM -MT $(@:.d=.o) $(CPPFLAGS) $< > $@ + +$(BIN_DIR)/%.o : %.s + $(AS) $(ASFLAGS) $< -o $@ + +$(BIN_DIR)/%.o : %.c + $(CC) $(CFLAGS) $< -o $@ + +$(BIN_DIR)/%.o : %.cpp + $(CPP) $(CPPFLAGS) $< -o $@ + +.PHONY : clean show + +# include dependency files only if our goal depends on their existence +ifneq ($(MAKECMDGOALS),clean) + ifneq ($(MAKECMDGOALS),show) +-include $(C_DEPS_EXT) $(CPP_DEPS_EXT) + endif +endif + + +clean: + -$(RM) $(BIN_DIR)/*.o \ + $(BIN_DIR)/*.d \ + $(BIN_DIR)/*.bin \ + $(BIN_DIR)/*.elf \ + $(BIN_DIR)/*.map + +show: + @echo PROJECT = $(PROJECT) + @echo CONF = $(CONF) + @echo DEFINES = $(DEFINES) + @echo ASM_FPU = $(ASM_FPU) + @echo ASM_SRCS = $(ASM_SRCS) + @echo C_SRCS = $(C_SRCS) + @echo CPP_SRCS = $(CPP_SRCS) + @echo ASM_OBJS_EXT = $(ASM_OBJS_EXT) + @echo C_OBJS_EXT = $(C_OBJS_EXT) + @echo C_DEPS_EXT = $(C_DEPS_EXT) + @echo CPP_DEPS_EXT = $(CPP_DEPS_EXT) + @echo TARGET_ELF = $(TARGET_ELF) diff --git a/examples/arm-cm/dpp_ek-tm4c123gxl/qxk/iar/dpp-qxk.ewd b/examples/arm-cm/dpp_ek-tm4c123gxl/qxk/iar/dpp-qxk.ewd index cdc33eb5..5d3dfa37 100644 --- a/examples/arm-cm/dpp_ek-tm4c123gxl/qxk/iar/dpp-qxk.ewd +++ b/examples/arm-cm/dpp_ek-tm4c123gxl/qxk/iar/dpp-qxk.ewd @@ -11,7 +11,7 @@ C-SPY 2 - 28 + 32 1 1 - - + + + + + @@ -486,7 +498,7 @@ IJET_ID 2 - 8 + 9 1 1 + + + + + + + + + + + + + @@ -916,7 +980,7 @@ LMIFTDI_ID 2 - 2 + 3 1 1 + + + + + + + NULINK_ID + 2 + + 0 + 1 + 1 + + + @@ -974,7 +1072,7 @@ STLINK_ID 2 - 4 + 8 1 1 + + + + @@ -1185,7 +1300,7 @@ XDS100_ID 2 - 6 + 9 1 1 + + + + @@ -1362,6 +1493,18 @@ $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin 0 + + $TOOLKIT_DIR$\plugins\rtos\FreeRtos\FreeRtosArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin2.ENU.ewplugin + 0 + $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin 0 @@ -1371,11 +1514,15 @@ 0 - $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9.ewplugin 0 - $TOOLKIT_DIR$\plugins\rtos\TI-RTOS\tirtosplugin.ewplugin + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9BE.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin 0 @@ -1391,11 +1538,11 @@ 0 - $EW_DIR$\common\plugins\CodeCoverage\CodeCoverage.ENU.ewplugin - 1 + $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + 0 - $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + $EW_DIR$\common\plugins\TargetAccessServer\TargetAccessServer.ENU.ewplugin 0 @@ -1414,7 +1561,7 @@ C-SPY 2 - 28 + 32 1 0 - - + + + + + @@ -1889,7 +2048,7 @@ IJET_ID 2 - 8 + 9 1 0 + + + + + + + + + + + + + @@ -2319,7 +2530,7 @@ LMIFTDI_ID 2 - 2 + 3 1 0 + + + + + + + NULINK_ID + 2 + + 0 + 1 + 0 + + + @@ -2377,7 +2622,7 @@ STLINK_ID 2 - 4 + 8 1 0 + + + + @@ -2588,7 +2850,7 @@ XDS100_ID 2 - 6 + 9 1 0 + + + + @@ -2765,6 +3043,18 @@ $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin 0 + + $TOOLKIT_DIR$\plugins\rtos\FreeRtos\FreeRtosArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin2.ENU.ewplugin + 0 + $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin 0 @@ -2774,11 +3064,15 @@ 0 - $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9.ewplugin 0 - $TOOLKIT_DIR$\plugins\rtos\TI-RTOS\tirtosplugin.ewplugin + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9BE.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin 0 @@ -2794,11 +3088,11 @@ 0 - $EW_DIR$\common\plugins\CodeCoverage\CodeCoverage.ENU.ewplugin - 1 + $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + 0 - $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + $EW_DIR$\common\plugins\TargetAccessServer\TargetAccessServer.ENU.ewplugin 0 @@ -2817,7 +3111,7 @@ C-SPY 2 - 28 + 32 1 1 - - + + + + + @@ -3292,7 +3598,7 @@ IJET_ID 2 - 8 + 9 1 1 + + + + + + + + + + + + + @@ -3722,7 +4080,7 @@ LMIFTDI_ID 2 - 2 + 3 1 1 + + + + + + + NULINK_ID + 2 + + 0 + 1 + 1 + + + @@ -3780,7 +4172,7 @@ STLINK_ID 2 - 4 + 8 1 1 + + + + @@ -3991,7 +4400,7 @@ XDS100_ID 2 - 6 + 9 1 1 + + + + @@ -4168,6 +4593,18 @@ $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin 0 + + $TOOLKIT_DIR$\plugins\rtos\FreeRtos\FreeRtosArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin2.ENU.ewplugin + 0 + $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin 0 @@ -4177,11 +4614,15 @@ 0 - $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9.ewplugin 0 - $TOOLKIT_DIR$\plugins\rtos\TI-RTOS\tirtosplugin.ewplugin + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9BE.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin 0 @@ -4197,11 +4638,11 @@ 0 - $EW_DIR$\common\plugins\CodeCoverage\CodeCoverage.ENU.ewplugin - 1 + $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + 0 - $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + $EW_DIR$\common\plugins\TargetAccessServer\TargetAccessServer.ENU.ewplugin 0 diff --git a/examples/arm-cm/dpp_ek-tm4c123gxl/qxk/iar/dpp-qxk.ewp b/examples/arm-cm/dpp_ek-tm4c123gxl/qxk/iar/dpp-qxk.ewp index 360b142e..fb6e9961 100644 --- a/examples/arm-cm/dpp_ek-tm4c123gxl/qxk/iar/dpp-qxk.ewp +++ b/examples/arm-cm/dpp_ek-tm4c123gxl/qxk/iar/dpp-qxk.ewp @@ -11,12 +11,12 @@ General 3 - 33 + 35 1 1 + + + @@ -214,7 +226,7 @@ @@ -1063,12 +1091,12 @@ General 3 - 33 + 35 1 0 + + + @@ -1267,6 +1307,7 @@ @@ -2115,12 +2172,12 @@ General 3 - 33 + 35 1 1 + + + @@ -2319,6 +2388,7 @@ @@ -3159,7 +3245,6 @@ Release - Spy Application @@ -3173,19 +3258,19 @@ $PROJ_DIR$\..\..\dpp.h - $PROJ_DIR$\..\main.c + $PROJ_DIR$\..\..\main.c $PROJ_DIR$\..\..\philo.c - - $PROJ_DIR$\..\..\..\..\..\include\qstamp.c - $PROJ_DIR$\..\..\table.c - $PROJ_DIR$\..\test.c + $PROJ_DIR$\..\xthread1.c + + + $PROJ_DIR$\..\xthread2.c @@ -3282,10 +3367,10 @@ $PROJ_DIR$\..\..\..\..\..\src\qs\qs_fp.c - $PROJ_DIR$\..\..\..\..\..\src\qs_pkg.h + $PROJ_DIR$\..\..\..\..\..\src\qs\qs_rx.c - $PROJ_DIR$\..\..\..\..\..\src\qs\qs_rx.c + $PROJ_DIR$\..\..\..\..\..\src\qs\qstamp.c diff --git a/examples/arm-cm/dpp_ek-tm4c123gxl/qxk/iar/dpp-qxk.icf b/examples/arm-cm/dpp_ek-tm4c123gxl/qxk/iar/dpp-qxk.icf index 0fdfc4b3..c6b24e1c 100644 --- a/examples/arm-cm/dpp_ek-tm4c123gxl/qxk/iar/dpp-qxk.icf +++ b/examples/arm-cm/dpp_ek-tm4c123gxl/qxk/iar/dpp-qxk.icf @@ -25,5 +25,5 @@ do not initialize { section .noinit }; place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec }; place in ROM_region { readonly }; -place at start of RAM_region {block CSTACK }; +place at start of RAM_region {block CSTACK }; /* <== Quantum Leaps */ place in RAM_region { readwrite, block HEAP }; \ No newline at end of file diff --git a/examples/arm-cm/dpp_ek-tm4c123gxl/qxk/main.c b/examples/arm-cm/dpp_ek-tm4c123gxl/qxk/main.c deleted file mode 100644 index 7bae6327..00000000 --- a/examples/arm-cm/dpp_ek-tm4c123gxl/qxk/main.c +++ /dev/null @@ -1,118 +0,0 @@ -/***************************************************************************** -* Product: DPP example extened for QXK -* Last updated for version 7.1.2 -* Last updated on 2022-09-22 -* -* Q u a n t u m L e a P s -* ------------------------ -* Modern Embedded Software -* -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* -* -*****************************************************************************/ -#include "qpc.h" -#include "dpp.h" -#include "bsp.h" - -Q_DEFINE_THIS_FILE - -static QTicker l_ticker0; -QActive *the_Ticker0 = &l_ticker0.super; - -/*..........................................................................*/ -int main() { - static QEvt const *tableQueueSto[N_PHILO]; - static QEvt const *philoQueueSto[N_PHILO][N_PHILO]; - static QSubscrList subscrSto[MAX_PUB_SIG]; - static QF_MPOOL_EL(TableEvt) smlPoolSto[2*N_PHILO]; /* small pool */ - - /* stacks and queues for the extended test threads */ - static void const *test1QueueSto[5]; - static uint64_t test1StackSto[64]; - static void const *test2QueueSto[5]; - static uint64_t test2StackSto[64]; - - QF_init(); /* initialize the framework and the underlying RT kernel */ - BSP_init(); /* initialize the Board Support Package */ - - /* initialize publish-subscribe... */ - QF_psInit(subscrSto, Q_DIM(subscrSto)); - - /* initialize event pools... */ - QF_poolInit(smlPoolSto, sizeof(smlPoolSto), sizeof(smlPoolSto[0])); - - /* start the extended thread */ - Test1_ctor(); /* instantiate the Test1 extended thread */ - QXTHREAD_START(XT_Test1, /* Thread to start */ - 1U, /* QF-prio/pre-thre. */ - test1QueueSto, /* message queue storage */ - Q_DIM(test1QueueSto), /* message length [events] */ - test1StackSto, /* stack storage */ - sizeof(test1StackSto),/* stack size [bytes] */ - (void *)0); /* initialization param */ - - /* NOTE: leave priority 2 free for a mutex */ - - /* start the Philo active objects... */ - Philo_ctor(); /* instantiate all Philo AOs */ - for (uint8_t n = 0U; n < N_PHILO; ++n) { - QACTIVE_START(AO_Philo[n], /* AO to start */ - n + 3U, /* QF-prio/pre-thre. */ - philoQueueSto[n], /* event queue storage */ - Q_DIM(philoQueueSto[n]), /* queue length [events] */ - (void *)0, /* stack storage (not used) */ - 0U, /* size of the stack [bytes] */ - (void *)0); /* initialization param */ - } - - /* example of prioritizing the Ticker0 active object */ - QTicker_ctor(&l_ticker0, 0U); /* ticker AO for tick rate 0 */ - QACTIVE_START(the_Ticker0, - N_PHILO + 3U, /* QF-prio/pre-thre. */ - 0, 0U, 0, 0U, (void *)0); - - /* NOTE: leave priority (N_PHILO + 4) free for mutex */ - - Test2_ctor(); /* instantiate the Test2 extended thread */ - QXTHREAD_START(XT_Test2, /* Thread to start */ - N_PHILO + 5U, /* QF-prio/pre-thre. */ - test2QueueSto, /* message queue storage */ - Q_DIM(test2QueueSto), /* message length [events] */ - test2StackSto, /* stack storage */ - sizeof(test2StackSto), /* stack size [bytes] */ - (void *)0); /* initialization param */ - - /* NOTE: leave priority (N_PHILO + 6) free for mutex */ - - Table_ctor(); /* instantiate the Table active object */ - QACTIVE_START(AO_Table, /* AO to start */ - N_PHILO + 7U, /* QF-prio/pre-thre. */ - tableQueueSto, /* event queue storage */ - Q_DIM(tableQueueSto), /* queue length [events] */ - (void *)0, /* stack storage (not used) */ - 0U, /* size of the stack [bytes] */ - (void *)0); /* initialization param */ - - return QF_run(); /* run the QF application */ -} diff --git a/examples/arm-cm/dpp_ek-tm4c123gxl/qxk/test.c b/examples/arm-cm/dpp_ek-tm4c123gxl/qxk/test.c deleted file mode 100644 index 4f2e3964..00000000 --- a/examples/arm-cm/dpp_ek-tm4c123gxl/qxk/test.c +++ /dev/null @@ -1,150 +0,0 @@ -/***************************************************************************** -* Product: DPP example -* Last updated for version 7.1.1 -* Last updated on 2022-09-22 -* -* Q u a n t u m L e a P s -* ------------------------ -* Modern Embedded Software -* -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* -* -*****************************************************************************/ -#include "qpc.h" -#include "dpp.h" -#include "bsp.h" - -/* local "extended" thread object ..........................................*/ -static QXThread l_test1; -static QXThread l_test2; -static QXSemaphore l_sema; -static QXMutex l_mutex; - -/* Thread-Local Storage for the "extended" threads .........................*/ -typedef struct { - uint32_t foo; - uint8_t bar[10]; -} TLS_test; -static TLS_test l_tls1; -static TLS_test l_tls2; - -static void lib_fun(uint32_t x) { - QXK_TLS(TLS_test *)->foo = x; -} - -/* global pointer to the test thread .......................................*/ -QXThread * const XT_Test1 = &l_test1; -QXThread * const XT_Test2 = &l_test2; - -/*..........................................................................*/ -static void Thread1_run(QXThread * const me) { - - QS_OBJ_DICTIONARY(&l_test1); - QS_OBJ_DICTIONARY(&l_test1.timeEvt); - QS_OBJ_DICTIONARY(&l_mutex); - - me->super.thread = &l_tls1; /* initialize the TLS for Thread1 */ - - for (;;) { - QXMutex_lock(&l_mutex, QXTHREAD_NO_TIMEOUT); /* lock the mutex */ - BSP_ledOn(); - - if (QXMutex_tryLock(&l_mutex)) { /* exercise the mutex */ - float volatile x; - - /* some flating point code to exercise the VFP... */ - x = 1.4142135F; - x = x * 1.4142135F; - - (void)QXSemaphore_signal(&l_sema); /* signal Thread2 */ - - QXThread_delay(10U); /* BLOCK while holding a mutex */ - - QXMutex_unlock(&l_mutex); - } - - QXMutex_unlock(&l_mutex); - BSP_ledOff(); - - QXThread_delay(BSP_TICKS_PER_SEC/7); /* BLOCK */ - - /* publish to thread2 */ - //QACTIVE_PUBLISH(Q_NEW(QEvt, TEST_SIG), &l_test1.super); - - /* test TLS */ - lib_fun(1U); - } -} - -/*..........................................................................*/ -void Test1_ctor(void) { - QXThread_ctor(&l_test1, &Thread1_run, 0U); -} - -/*..........................................................................*/ -static void Thread2_run(QXThread * const me) { - - QS_OBJ_DICTIONARY(&l_test2); - QS_OBJ_DICTIONARY(&l_test2.timeEvt); - QS_OBJ_DICTIONARY(&l_sema); - - /* initialize the semaphore before using it - * NOTE: the semaphore is initialized in the highest-priority thread - * that uses it. Alternatively, the semaphore can be initialized - * before any thread runs. - */ - QXSemaphore_init(&l_sema, - 0U, /* count==0 (signaling semaphore) */ - 1U); /* max_count==1 (binary semaphore) */ - - /* initialize the mutex before using it - * NOTE: Here the mutex is initialized in the highest-priority thread - * that uses it. Alternatively, the mutex can be initialized - * before any thread runs. - */ - //QXMutex_init(&l_mutex, 0U); /* priority-ceiling NOT used */ - QXMutex_init(&l_mutex, N_PHILO + 6U); /* QF-priority/preemption-thre. */ - - me->super.thread = &l_tls2; /* initialize the TLS for Thread2 */ - - /* subscribe to the test signal */ - QActive_subscribe(&me->super, TEST_SIG); - - for (;;) { - /* wait on a semaphore (BLOCK indefinitely) */ - QXSemaphore_wait(&l_sema, QXTHREAD_NO_TIMEOUT); - - QXMutex_lock(&l_mutex, QXTHREAD_NO_TIMEOUT); /* lock the mutex */ - QXThread_delay(1U); /* wait more (BLOCK) */ - QXMutex_unlock(&l_mutex); - - /* test TLS */ - lib_fun(2U); - } -} - -/*..........................................................................*/ -void Test2_ctor(void) { - QXThread_ctor(&l_test2, &Thread2_run, 0U); -} diff --git a/examples/arm-cm/dpp_ek-tm4c123gxl/qxk/xthread1.c b/examples/arm-cm/dpp_ek-tm4c123gxl/qxk/xthread1.c new file mode 100644 index 00000000..066b983d --- /dev/null +++ b/examples/arm-cm/dpp_ek-tm4c123gxl/qxk/xthread1.c @@ -0,0 +1,101 @@ +//============================================================================ +// QXThread example +// Last updated for version 7.3.0 +// Last updated on 2023-08-12 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. +// +// This program is open source software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Alternatively, this program may be distributed and modified under the +// terms of Quantum Leaps commercial licenses, which expressly supersede +// the GNU General Public License and are specifically designed for +// licensees interested in retaining the proprietary status of their code. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Contact information: +// +// +//============================================================================ +#include "qpc.h" // QP/C real-time embedded framework +#include "dpp.h" // DPP Application interface +#include "bsp.h" // Board Support Package + +//---------------------------------------------------------------------------- +//Q_DEFINE_THIS_FILE + +//............................................................................ +typedef struct XThread1 { +// protected: + QXThread super; + +// private: + // NOTE: data needed by this thread should be members of + // the thread class. That way they are in the memory region + // accessible from this thread. + uint8_t foo; + +// public: +} XThread1; + +// private: +static void XThread1_run(QXThread * const thr); +extern XThread1 XThread1_inst; + +//............................................................................ +QXThread * const TH_XThread1 = &XThread1_inst.super; + +//............................................................................ +void XThread1_ctor(void) { + XThread1 *me = &XThread1_inst; + QXThread_ctor(&me->super, &XThread1_run, 0U); +} + +//............................................................................ +XThread1 XThread1_inst; + +//............................................................................ +static void XThread1_run(QXThread * const thr) { + QS_OBJ_DICTIONARY(TH_XThread1); + QS_OBJ_DICTIONARY(&TH_XThread1->timeEvt); + + // downcast the generic thr pointer to the specific thread + XThread1 *me = (XThread1 *)thr; + + // subscribe to the EAT signal (from the application) + QActive_subscribe(&me->super.super, EAT_SIG); + + for (;;) { + QEvt const *e = QXThread_queueGet(BSP_TICKS_PER_SEC/4U); + if (e) { + QXSemaphore_signal(&TH_sema); // signal Thread2 + QF_gc(e); // must explicitly recycle the received event! + } + + QXMutex_lock(&TH_mutex, QXTHREAD_NO_TIMEOUT); // lock the mutex + BSP_ledOn(); + if (QXMutex_tryLock(&TH_mutex)) { // exercise the mutex + // some floating point code to exercise the VFP... + float volatile x = 1.4142135F; + x = x * 1.4142135F; + QXThread_delay(10U); // BLOCK while holding a mutex + QXMutex_unlock(&TH_mutex); + } + QXMutex_unlock(&TH_mutex); + BSP_ledOff(); + } +} diff --git a/examples/arm-cm/dpp_ek-tm4c123gxl/qxk/xthread2.c b/examples/arm-cm/dpp_ek-tm4c123gxl/qxk/xthread2.c new file mode 100644 index 00000000..1caad4fa --- /dev/null +++ b/examples/arm-cm/dpp_ek-tm4c123gxl/qxk/xthread2.c @@ -0,0 +1,108 @@ +//============================================================================ +// QXThread example +// Last updated for version 7.3.0 +// Last updated on 2023-08-12 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. +// +// This program is open source software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Alternatively, this program may be distributed and modified under the +// terms of Quantum Leaps commercial licenses, which expressly supersede +// the GNU General Public License and are specifically designed for +// licensees interested in retaining the proprietary status of their code. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Contact information: +// +// +//============================================================================ +#include "qpc.h" // QP/C real-time embedded framework +#include "dpp.h" // DPP Application interface +#include "bsp.h" // Board Support Package + +//---------------------------------------------------------------------------- +//Q_DEFINE_THIS_FILE + +//---------------------------------------------------------------------------- +QXSemaphore TH_sema; +QXMutex TH_mutex; + +//---------------------------------------------------------------------------- +typedef struct XThread2 { +// protected: + QXThread super; + +// private: + // NOTE: data needed by this thread should be members of + // the thread class. That way they are in the memory region + // accessible from this thread. + uint8_t foo; + +// public: +} XThread2; + +// private: +static void XThread2_run(QXThread * const thr); +extern XThread2 XThread2_inst; + +//............................................................................ +QXThread * const TH_XThread2 = &XThread2_inst.super; + +//............................................................................ +void XThread2_ctor(void) { + XThread2 *me = &XThread2_inst; + QXThread_ctor(&me->super, &XThread2_run, 0U); +} + +//............................................................................ +XThread2 XThread2_inst; + +//............................................................................ +static void XThread2_run(QXThread * const thr) { + QS_OBJ_DICTIONARY(TH_XThread2); + QS_OBJ_DICTIONARY(&TH_XThread2->timeEvt); + QS_OBJ_DICTIONARY(&TH_sema); + QS_OBJ_DICTIONARY(&TH_mutex); + + // downcast the generic thr pointer to the specific thread + //XThread2 *me = (XThread2 *)thr; + + // initialize the semaphore before using it + // NOTE: Here the semaphore is initialized in the highest-priority thread + // that uses it. Alternatively, the semaphore can be initialized + // before any thread runs. + QXSemaphore_init(&TH_sema, + 0U, // count==0 (signaling semaphore) + 1U); // max_count==1 (binary semaphore) + + // initialize the mutex before using it + // NOTE: Here the mutex is initialized in the highest-priority thread + // that uses it. Alternatively, the mutex can be initialized + // before any thread runs. + QXMutex_init(&TH_mutex, N_PHILO + 6U); // priority-ceiling mutex + //QXMutex_init(&TH_mutex, 0U); // alternatively: priority-ceiling NOT used + + for (;;) { + // wait on a semaphore (BLOCK indefinitely) + QXSemaphore_wait(&TH_sema, QXTHREAD_NO_TIMEOUT); + + QXMutex_lock(&TH_mutex, QXTHREAD_NO_TIMEOUT); // lock the mutex + QXThread_delay(5U); // wait more (BLOCK) + QXMutex_unlock(&TH_mutex); + } +} diff --git a/examples/arm-cm/dpp_ek-tm4c123gxl/table.c b/examples/arm-cm/dpp_ek-tm4c123gxl/table.c index 1030cfe3..c3ae02f0 100644 --- a/examples/arm-cm/dpp_ek-tm4c123gxl/table.c +++ b/examples/arm-cm/dpp_ek-tm4c123gxl/table.c @@ -1,124 +1,130 @@ -/*$file${.::table.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* -* Model: dpp.qm -* File: ${.::table.c} -* -* This code has been generated by QM 5.2.4 . -* DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. -* -* SPDX-License-Identifier: GPL-3.0-or-later -* -* This generated code is open source software: you can redistribute it under -* the terms of the GNU General Public License as published by the Free -* Software Foundation. -* -* This code is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -* more details. -* -* NOTE: -* Alternatively, this generated code may be distributed under the terms -* of Quantum Leaps commercial licenses, which expressly supersede the GNU -* General Public License and are specifically designed for licensees -* interested in retaining the proprietary status of their code. -* -* Contact information: -* -* -*/ -/*$endhead${.::table.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -#include "qpc.h" -#include "dpp.h" -#include "bsp.h" +//$file${.::table.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// +// Model: dpp.qm +// File: ${.::table.c} +// +// This code has been generated by QM 5.3.0 . +// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. +// +// SPDX-License-Identifier: GPL-3.0-or-later +// +// This generated code is open source software: you can redistribute it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation. +// +// This code is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// NOTE: +// Alternatively, this generated code may be distributed under the terms +// of Quantum Leaps commercial licenses, which expressly supersede the GNU +// General Public License and are specifically designed for licensees +// interested in retaining the proprietary status of their code. +// +// Contact information: +// +// +// +//$endhead${.::table.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +#include "qpc.h" // QP/C real-time embedded framework +#include "dpp.h" // DPP Application interface +#include "bsp.h" // Board Support Package -Q_DEFINE_THIS_FILE +//$declare${AOs::Table} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/* Active object class -----------------------------------------------------*/ -/*$declare${AOs::Table} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${AOs::Table} ............................................................*/ +//${AOs::Table} .............................................................. typedef struct Table { -/* protected: */ +// protected: QActive super; -/* public: */ - -/* private: */ +// private: uint8_t fork[N_PHILO]; - uint8_t isHungry[N_PHILO]; + bool isHungry[N_PHILO]; + +// public: } Table; + extern Table Table_inst; -/* protected: */ +// protected: static QState Table_initial(Table * const me, void const * const par); static QState Table_active(Table * const me, QEvt const * const e); static QState Table_serving(Table * const me, QEvt const * const e); static QState Table_paused(Table * const me, QEvt const * const e); -/*$enddecl${AOs::Table} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$enddecl${AOs::Table} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -#define RIGHT(n_) ((uint8_t)(((n_) + (N_PHILO - 1U)) % N_PHILO)) -#define LEFT(n_) ((uint8_t)(((n_) + 1U) % N_PHILO)) -#define FREE ((uint8_t)0) -#define USED ((uint8_t)1) +//---------------------------------------------------------------------------- +Q_DEFINE_THIS_FILE -/*$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* Check for the minimum required QP version */ -#if (QP_VERSION < 700U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) -#error qpc version 7.0.0 or higher required +// helper function to provide the RIGHT neighbor of a Philo[n] +static inline uint8_t right(uint8_t const n) { + return (uint8_t)((n + (N_PHILO - 1U)) % N_PHILO); +} + +// helper function to provide the LEFT neighbor of a Philo[n] +static inline uint8_t left(uint8_t const n) { + return (uint8_t)((n + 1U) % N_PHILO); +} + +#define FREE ((uint8_t)0U) +#define USED ((uint8_t)1U) + +#define THINKING "thinking" +#define HUNGRY "hungry " +#define EATING "eating " + +//---------------------------------------------------------------------------- + +//$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// Check for the minimum required QP version +#if (QP_VERSION < 730U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) +#error qpc version 7.3.0 or higher required #endif -/*$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -/*$define${AOs::AO_Table} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//$define${Shared::Table_ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/*${AOs::AO_Table} .........................................................*/ -QActive * const AO_Table = &Table_inst.super; /* "opaque" pointer to Table AO */ -/*$enddef${AOs::AO_Table} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*$define${AOs::Table_ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${AOs::Table_ctor} .......................................................*/ +//${Shared::Table_ctor} ...................................................... void Table_ctor(void) { - Table *me = &Table_inst; - uint8_t n; - + Table * const me = &Table_inst; QActive_ctor(&me->super, Q_STATE_CAST(&Table_initial)); - - for (n = 0U; n < N_PHILO; ++n) { + for (uint8_t n = 0U; n < N_PHILO; ++n) { me->fork[n] = FREE; - me->isHungry[n] = 0U; + me->isHungry[n] = false; } } -/*$enddef${AOs::Table_ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*$define${AOs::Table} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//$enddef${Shared::Table_ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +//$define${Shared::AO_Table} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/*${AOs::Table} ............................................................*/ +//${Shared::AO_Table} ........................................................ +QActive * const AO_Table = &Table_inst.super; +//$enddef${Shared::AO_Table} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +//$define${AOs::Table} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${AOs::Table} .............................................................. Table Table_inst; -/*${AOs::Table::SM} ........................................................*/ +//${AOs::Table::SM} .......................................................... static QState Table_initial(Table * const me, void const * const par) { - /*${AOs::Table::SM::initial} */ - uint8_t n; - (void)par; /* unused parameter */ + //${AOs::Table::SM::initial} + Q_UNUSED_PAR(par); - QS_OBJ_DICTIONARY(&Table_inst); + #ifdef Q_SPY + Table *Table_inst = me; + QS_OBJ_DICTIONARY(Table_inst); + #endif - QS_SIG_DICTIONARY(DONE_SIG, (void *)0); /* global signals */ - QS_SIG_DICTIONARY(EAT_SIG, (void *)0); - QS_SIG_DICTIONARY(PAUSE_SIG, (void *)0); - QS_SIG_DICTIONARY(SERVE_SIG, (void *)0); - QS_SIG_DICTIONARY(TEST_SIG, (void *)0); + QActive_subscribe(&me->super, DONE_SIG); + QActive_subscribe(&me->super, PAUSE_SIG); + QActive_subscribe(&me->super, SERVE_SIG); + QActive_subscribe(&me->super, TEST_SIG); - QS_SIG_DICTIONARY(HUNGRY_SIG, me); /* signal just for Table */ - - QActive_subscribe(&me->super, (enum_t)DONE_SIG); - QActive_subscribe(&me->super, (enum_t)PAUSE_SIG); - QActive_subscribe(&me->super, (enum_t)SERVE_SIG); - QActive_subscribe(&me->super, (enum_t)TEST_SIG); - - for (n = 0U; n < N_PHILO; ++n) { + for (uint8_t n = 0U; n < N_PHILO; ++n) { me->fork[n] = FREE; - me->isHungry[n] = 0U; - BSP_displayPhilStat(n, "thinking"); + me->isHungry[n] = false; + BSP_displayPhilStat(n, THINKING); } QS_FUN_DICTIONARY(&Table_active); @@ -128,16 +134,16 @@ static QState Table_initial(Table * const me, void const * const par) { return Q_TRAN(&Table_serving); } -/*${AOs::Table::SM::active} ................................................*/ +//${AOs::Table::SM::active} .................................................. static QState Table_active(Table * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${AOs::Table::SM::active::TEST} */ + //${AOs::Table::SM::active::TEST} case TEST_SIG: { status_ = Q_HANDLED(); break; } - /*${AOs::Table::SM::active::EAT} */ + //${AOs::Table::SM::active::EAT} case EAT_SIG: { Q_ERROR(); status_ = Q_HANDLED(); @@ -151,108 +157,119 @@ static QState Table_active(Table * const me, QEvt const * const e) { return status_; } -/*${AOs::Table::SM::active::serving} .......................................*/ +//${AOs::Table::SM::active::serving} ......................................... static QState Table_serving(Table * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${AOs::Table::SM::active::serving} */ + //${AOs::Table::SM::active::serving} case Q_ENTRY_SIG: { - uint8_t n; - for (n = 0U; n < N_PHILO; ++n) { /* give permissions to eat... */ - if ((me->isHungry[n] != 0U) - && (me->fork[LEFT(n)] == FREE) + // give permissions to eat... + for (uint8_t n = 0U; n < N_PHILO; ++n) { + if (me->isHungry[n] + && (me->fork[left(n)] == FREE) && (me->fork[n] == FREE)) { - TableEvt *te; - - me->fork[LEFT(n)] = USED; + me->fork[left(n)] = USED; me->fork[n] = USED; - te = Q_NEW(TableEvt, EAT_SIG); - te->philoNum = n; - QACTIVE_PUBLISH(&te->super, &me->super); - me->isHungry[n] = 0U; - BSP_displayPhilStat(n, "eating "); + #ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, EAT_SIG, n); + #else + TableEvt *pe = Q_NEW(TableEvt, EAT_SIG); + pe->philoId = n; + #endif + QACTIVE_PUBLISH(&pe->super, &me->super); + me->isHungry[n] = false; + BSP_displayPhilStat(n, EATING); } } status_ = Q_HANDLED(); break; } - /*${AOs::Table::SM::active::serving::HUNGRY} */ + //${AOs::Table::SM::active::serving::HUNGRY} case HUNGRY_SIG: { - uint8_t n, m; + uint8_t n = Q_EVT_CAST(TableEvt)->philoId; - n = Q_EVT_CAST(TableEvt)->philoNum; - /* phil ID must be in range and he must be not hungry */ - Q_ASSERT((n < N_PHILO) && (me->isHungry[n] == 0U)); + // phil ID must be in range and he must be not hungry + Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); - BSP_displayPhilStat(n, "hungry "); - m = LEFT(n); - /*${AOs::Table::SM::active::serving::HUNGRY::[bothfree]} */ + BSP_displayPhilStat(n, HUNGRY); + uint8_t m = left(n); + //${AOs::Table::SM::active::serving::HUNGRY::[bothfree]} if ((me->fork[m] == FREE) && (me->fork[n] == FREE)) { - TableEvt *pe; me->fork[m] = USED; me->fork[n] = USED; - pe = Q_NEW(TableEvt, EAT_SIG); - pe->philoNum = n; + #ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, EAT_SIG, n); + #else + TableEvt *pe = Q_NEW(TableEvt, EAT_SIG); + pe->philoId = n; + #endif QACTIVE_PUBLISH(&pe->super, &me->super); - BSP_displayPhilStat(n, "eating "); + BSP_displayPhilStat(n, EATING); status_ = Q_HANDLED(); } - /*${AOs::Table::SM::active::serving::HUNGRY::[else]} */ + //${AOs::Table::SM::active::serving::HUNGRY::[else]} else { - me->isHungry[n] = 1U; + me->isHungry[n] = true; status_ = Q_HANDLED(); } break; } - /*${AOs::Table::SM::active::serving::DONE} */ + //${AOs::Table::SM::active::serving::DONE} case DONE_SIG: { - uint8_t n, m; - TableEvt *pe; + uint8_t n = Q_EVT_CAST(TableEvt)->philoId; - n = Q_EVT_CAST(TableEvt)->philoNum; - /* phil ID must be in range and he must be not hungry */ - Q_ASSERT((n < N_PHILO) && (me->isHungry[n] == 0U)); + // phil ID must be in range and he must be not hungry + Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); - BSP_displayPhilStat(n, "thinking"); - m = LEFT(n); - /* both forks of Phil[n] must be used */ + BSP_displayPhilStat(n, THINKING); + uint8_t m = left(n); + + // both forks of Phil[n] must be used Q_ASSERT((me->fork[n] == USED) && (me->fork[m] == USED)); me->fork[m] = FREE; me->fork[n] = FREE; - m = RIGHT(n); /* check the right neighbor */ + m = right(n); // check the right neighbor - if ((me->isHungry[m] != 0U) && (me->fork[m] == FREE)) { + if (me->isHungry[m] && (me->fork[m] == FREE)) { me->fork[n] = USED; me->fork[m] = USED; - me->isHungry[m] = 0U; - pe = Q_NEW(TableEvt, EAT_SIG); - pe->philoNum = m; + me->isHungry[m] = false; + #ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, EAT_SIG, m); + #else + TableEvt *pe = Q_NEW(TableEvt, EAT_SIG); + pe->philoId = m; + #endif QACTIVE_PUBLISH(&pe->super, &me->super); - BSP_displayPhilStat(m, "eating "); + BSP_displayPhilStat(m, EATING); } - m = LEFT(n); /* check the left neighbor */ - n = LEFT(m); /* left fork of the left neighbor */ - if ((me->isHungry[m] != 0U) && (me->fork[n] == FREE)) { + m = left(n); // check the left neighbor + n = left(m); // left fork of the left neighbor + if (me->isHungry[m] && (me->fork[n] == FREE)) { me->fork[m] = USED; me->fork[n] = USED; - me->isHungry[m] = 0U; - pe = Q_NEW(TableEvt, EAT_SIG); - pe->philoNum = m; + me->isHungry[m] = false; + #ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, EAT_SIG, m); + #else + TableEvt *pe = Q_NEW(TableEvt, EAT_SIG); + pe->philoId = m; + #endif QACTIVE_PUBLISH(&pe->super, &me->super); - BSP_displayPhilStat(m, "eating "); + BSP_displayPhilStat(m, EATING); } status_ = Q_HANDLED(); break; } - /*${AOs::Table::SM::active::serving::EAT} */ + //${AOs::Table::SM::active::serving::EAT} case EAT_SIG: { Q_ERROR(); status_ = Q_HANDLED(); break; } - /*${AOs::Table::SM::active::serving::PAUSE} */ + //${AOs::Table::SM::active::serving::PAUSE} case PAUSE_SIG: { status_ = Q_TRAN(&Table_paused); break; @@ -265,48 +282,50 @@ static QState Table_serving(Table * const me, QEvt const * const e) { return status_; } -/*${AOs::Table::SM::active::paused} ........................................*/ +//${AOs::Table::SM::active::paused} .......................................... static QState Table_paused(Table * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${AOs::Table::SM::active::paused} */ + //${AOs::Table::SM::active::paused} case Q_ENTRY_SIG: { BSP_displayPaused(1U); status_ = Q_HANDLED(); break; } - /*${AOs::Table::SM::active::paused} */ + //${AOs::Table::SM::active::paused} case Q_EXIT_SIG: { BSP_displayPaused(0U); status_ = Q_HANDLED(); break; } - /*${AOs::Table::SM::active::paused::SERVE} */ + //${AOs::Table::SM::active::paused::SERVE} case SERVE_SIG: { status_ = Q_TRAN(&Table_serving); break; } - /*${AOs::Table::SM::active::paused::HUNGRY} */ + //${AOs::Table::SM::active::paused::HUNGRY} case HUNGRY_SIG: { - uint8_t n = Q_EVT_CAST(TableEvt)->philoNum; - /* philo ID must be in range and he must be not hungry */ - Q_ASSERT((n < N_PHILO) && (me->isHungry[n] == 0U)); - me->isHungry[n] = 1U; - BSP_displayPhilStat(n, "hungry "); + uint8_t n = Q_EVT_CAST(TableEvt)->philoId; + + // philo ID must be in range and he must be not hungry + Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); + + me->isHungry[n] = true; + BSP_displayPhilStat(n, HUNGRY); status_ = Q_HANDLED(); break; } - /*${AOs::Table::SM::active::paused::DONE} */ + //${AOs::Table::SM::active::paused::DONE} case DONE_SIG: { - uint8_t n, m; + uint8_t n = Q_EVT_CAST(TableEvt)->philoId; - n = Q_EVT_CAST(TableEvt)->philoNum; - /* phil ID must be in range and he must be not hungry */ - Q_ASSERT((n < N_PHILO) && (me->isHungry[n] == 0U)); + // phil ID must be in range and he must be not hungry + Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); - BSP_displayPhilStat(n, "thinking"); - m = LEFT(n); - /* both forks of Phil[n] must be used */ + BSP_displayPhilStat(n, THINKING); + uint8_t m = left(n); + + // both forks of Phil[n] must be used Q_ASSERT((me->fork[n] == USED) && (me->fork[m] == USED)); me->fork[m] = FREE; @@ -321,4 +340,4 @@ static QState Table_paused(Table * const me, QEvt const * const e) { } return status_; } -/*$enddef${AOs::Table} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$enddef${AOs::Table} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/examples/arm-cm/dpp_ek-tm4c123gxl_mpu/bsp.h b/examples/arm-cm/dpp_ek-tm4c123gxl_mpu/bsp.h new file mode 100644 index 00000000..fe8149a3 --- /dev/null +++ b/examples/arm-cm/dpp_ek-tm4c123gxl_mpu/bsp.h @@ -0,0 +1,49 @@ +//============================================================================ +// Product: DPP example +// Last Updated for Version: 7.3.0 +// Date of the Last Update: 2023-06-27 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +//============================================================================ +#ifndef BSP_H_ +#define BSP_H_ + +#define BSP_TICKS_PER_SEC 100U + +void BSP_init(void); +void BSP_start(void); +void BSP_displayPaused(uint8_t paused); +void BSP_displayPhilStat(uint8_t n, char const *stat); +void BSP_terminate(int16_t result); + +void BSP_randomSeed(uint32_t seed); // random seed +uint32_t BSP_random(void); // pseudo-random generator + +void BSP_ledOn(void); +void BSP_ledOff(void); + +#endif // BSP_H_ diff --git a/examples/arm-cm/dpp_ek-tm4c123gxl_mpu/dpp.h b/examples/arm-cm/dpp_ek-tm4c123gxl_mpu/dpp.h new file mode 100644 index 00000000..4f4100c4 --- /dev/null +++ b/examples/arm-cm/dpp_ek-tm4c123gxl_mpu/dpp.h @@ -0,0 +1,144 @@ +//$file${.::dpp.h} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// +// Model: dpp_mpu.qm +// File: ${.::dpp.h} +// +// This code has been generated by QM 5.3.0 . +// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. +// +// SPDX-License-Identifier: GPL-3.0-or-later +// +// This generated code is open source software: you can redistribute it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation. +// +// This code is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// NOTE: +// Alternatively, this generated code may be distributed under the terms +// of Quantum Leaps commercial licenses, which expressly supersede the GNU +// General Public License and are specifically designed for licensees +// interested in retaining the proprietary status of their code. +// +// Contact information: +// +// +// +//$endhead${.::dpp.h} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +#ifndef DPP_H_ +#define DPP_H_ + +//$declare${Shared} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${Shared::AppSignals} ...................................................... +enum AppSignals { + EAT_SIG = Q_USER_SIG, // published by Table to let a Philo eat + DONE_SIG, // published by Philo when done eating + PAUSE_SIG, // published by BSP to pause the application + SERVE_SIG, // published by BSP to serve re-start serving forks + TEST_SIG, // published by BSP to test the application + MAX_PUB_SIG, // the last published signal + + TIMEOUT_SIG, // posted by time event to Philo + HUNGRY_SIG, // posted by hungry Philo to Table + MAX_SIG // the last signal +}; + +//${Shared::produce_sig_dict} ................................................ +#ifdef Q_SPY +static inline void produce_sig_dict(void) { + QS_SIG_DICTIONARY(EAT_SIG, (void *)0); + QS_SIG_DICTIONARY(DONE_SIG, (void *)0); + QS_SIG_DICTIONARY(PAUSE_SIG, (void *)0); + QS_SIG_DICTIONARY(SERVE_SIG, (void *)0); + QS_SIG_DICTIONARY(TEST_SIG, (void *)0); + + QS_SIG_DICTIONARY(TIMEOUT_SIG, (void *)0); + QS_SIG_DICTIONARY(HUNGRY_SIG, (void *)0); +} +#endif // def Q_SPY + +//${Shared::N_PHILO} ......................................................... +#define N_PHILO ((uint8_t)5U) + +//${Shared::TableEvt} ........................................................ +typedef struct { +// protected: + QEvt super; + +// public: + uint8_t philoId; +} TableEvt; + +// public: + +#ifdef QEVT_DYN_CTOR +static inline TableEvt * TableEvt_ctor(TableEvt * const me, + uint8_t id) +{ + if (me != (TableEvt *)0) { + // don't call QEvt_ctor() because the initialization of all + // QEvt attributes is already done in QF_QF_newX_() + me->philoId = id; + } + return me; +} +#endif // def QEVT_DYN_CTOR + +//${Shared::AO_Philo[N_PHILO]} ............................................... +extern QActive * const AO_Philo[N_PHILO]; + +//${Shared::Philo_ctor} ...................................................... +void Philo_ctor( + uint_fast8_t const id, + uint8_t * const sto, + uint32_t const size, + void const * const mpu); + +//${Shared::AO_Table} ........................................................ +extern QActive * const AO_Table; + +//${Shared::Table_ctor} ...................................................... +void Table_ctor( + uint8_t * const sto, + uint32_t const size, + void const * const mpu); +//$enddecl${Shared} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +#ifdef QXK_H_ +//$declare${Shared-TH} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${Shared-TH::TH_XThread1} .................................................. +extern QXThread * const TH_XThread1; + +//${Shared-TH::XThread1_ctor} ................................................ +void XThread1_ctor( + uint8_t * const sto, + uint32_t const size, + void const * const mpu); + +//${Shared-TH::TH_XThread2} .................................................. +extern QXThread * const TH_XThread2; + +//${Shared-TH::XThread2_ctor} ................................................ +void XThread2_ctor( + uint8_t * const sto, + uint32_t const size, + void const * const mpu); + +//${Shared-TH::TH_sema} ...................................................... +// NOTE: kernel objects can be allocated outside any memory regions +// accessible to the threads. +extern QXSemaphore TH_sema; + +//${Shared-TH::TH_mutex} ..................................................... +// NOTE: kernel objects can be allocated outside any memory regions +// accessible to the threads. +extern QXMutex TH_mutex; +//$enddecl${Shared-TH} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +#endif // QXK_H_ + +#endif // DPP_H_ diff --git a/examples/arm-cm/dpp_ek-tm4c123gxl_mpu/dpp_mpu.qm b/examples/arm-cm/dpp_ek-tm4c123gxl_mpu/dpp_mpu.qm new file mode 100644 index 00000000..7069d76f --- /dev/null +++ b/examples/arm-cm/dpp_ek-tm4c123gxl_mpu/dpp_mpu.qm @@ -0,0 +1,693 @@ + + + Dining Philosopher Problem example, including QXK and MPU isolation + + + + + + + { + EAT_SIG = Q_USER_SIG, // published by Table to let a Philo eat + DONE_SIG, // published by Philo when done eating + PAUSE_SIG, // published by BSP to pause the application + SERVE_SIG, // published by BSP to serve re-start serving forks + TEST_SIG, // published by BSP to test the application + MAX_PUB_SIG, // the last published signal + + TIMEOUT_SIG, // posted by time event to Philo + HUNGRY_SIG, // posted by hungry Philo to Table + MAX_SIG // the last signal +}; + + + + QS_SIG_DICTIONARY(EAT_SIG, (void *)0); +QS_SIG_DICTIONARY(DONE_SIG, (void *)0); +QS_SIG_DICTIONARY(PAUSE_SIG, (void *)0); +QS_SIG_DICTIONARY(SERVE_SIG, (void *)0); +QS_SIG_DICTIONARY(TEST_SIG, (void *)0); + +QS_SIG_DICTIONARY(TIMEOUT_SIG, (void *)0); +QS_SIG_DICTIONARY(HUNGRY_SIG, (void *)0); + + + + ((uint8_t)5U) + + + + + + + + + + if (me != (TableEvt *)0) { + // don't call QEvt_ctor() because the initialization of all + // QEvt attributes is already done in QF_QF_newX_() + me->philoId = id; +} +return me; + + + + + + + + + + + + + + + Q_REQUIRE(sizeof(Philo) <= size); + +Philo *me = (Philo *)sto; +QActive_ctor(&me->super, Q_STATE_CAST(&Philo_initial)); +QTimeEvt_ctorX(&me->timeEvt, &me->super, TIMEOUT_SIG, 0U), +me->id = (uint8_t)id; +me->super.thread = mpu; + + + + + + + + + + + + Q_REQUIRE(sizeof(Table) <= size); + +Table *me = (Table *)sto; +QActive_ctor(&me->super, Q_STATE_CAST(&Table_initial)); +for (uint8_t n = 0U; n < N_PHILO; ++n) { + me->fork[n] = FREE; + me->isHungry[n] = false; +} +me->super.thread = mpu; + + + + + + + + + + + + + + + Q_REQUIRE(sizeof(XThread1) <= size); + +XThread1 *me = (XThread1 *)sto; +QXThread_ctor(&me->super, &XThread1_run, 0U); +me->super.super.thread = mpu; + + + + + + + + + + + + Q_REQUIRE(sizeof(XThread2) <= size); + +XThread2 *me = (XThread2 *)sto; +QXThread_ctor(&me->super, &XThread2_run, 0U); +me->super.super.thread = mpu; + + + + // NOTE: kernel objects can be allocated outside any memory regions +// accessible to the threads. + + + + // NOTE: kernel objects can be allocated outside any memory regions +// accessible to the threads. + + + + + + + The Philo AO and the N_PHILO instances + + + + + + + + + Q_UNUSED_PAR(par); + +#ifdef Q_SPY +Philo *Philo_inst = me; +QS_OBJ_ARR_DICTIONARY(Philo_inst, me->id); +QS_OBJ_ARR_DICTIONARY(&Philo_inst->timeEvt, me->id); +#endif + +QActive_subscribe(&me->super, EAT_SIG); +QActive_subscribe(&me->super, TEST_SIG); + + + + + + + QTimeEvt_armX(&me->timeEvt, think_time(), 0U); + (void)QTimeEvt_disarm(&me->timeEvt); + + + + + + + + + // EAT or DONE must be for other Philos than this one +Q_ASSERT(Q_EVT_CAST(TableEvt)->philoId != me->id); + + + + + + + + + + + + + + + + + + #ifdef QEVT_DYN_CTOR +TableEvt const *pe = Q_NEW(TableEvt, HUNGRY_SIG, me->id); +#else +TableEvt *pe = Q_NEW(TableEvt, HUNGRY_SIG); +pe->philoId = me->id; +#endif +QACTIVE_POST(AO_Table, &pe->super, &me->super); + + + + + Q_EVT_CAST(TableEvt)->philoId == me->id + + + + + + + + + + + // DONE must be for other Philos than this one +Q_ASSERT(Q_EVT_CAST(TableEvt)->philoId != me->id); + + + + + + + + + + + QTimeEvt_armX(&me->timeEvt, eat_time(), 0U); + QTimeEvt_disarm(&me->timeEvt); + +#ifdef QEVT_DYN_CTOR +TableEvt const *pe = Q_NEW(TableEvt, DONE_SIG, me->id); +#else +TableEvt *pe = Q_NEW(TableEvt, DONE_SIG); +pe->philoId = me->id; +#endif +QACTIVE_PUBLISH(&pe->super, &me->super); + + + + + + + + + // EAT or DONE must be for other Philos than this one +Q_ASSERT(Q_EVT_CAST(TableEvt)->philoId != me->id); + + + + + + + + + + + + + + + + + + + + + + + Q_UNUSED_PAR(par); + +#ifdef Q_SPY +Table *Table_inst = me; +QS_OBJ_DICTIONARY(Table_inst); +#endif + +QActive_subscribe(&me->super, DONE_SIG); +QActive_subscribe(&me->super, PAUSE_SIG); +QActive_subscribe(&me->super, SERVE_SIG); +QActive_subscribe(&me->super, TEST_SIG); + +for (uint8_t n = 0U; n < N_PHILO; ++n) { + me->fork[n] = FREE; + me->isHungry[n] = false; + BSP_displayPhilStat(n, THINKING); +} + + + + + + + + + + + + + + + Q_ERROR(); + + + + + + + // give permissions to eat... +for (uint8_t n = 0U; n < N_PHILO; ++n) { + if (me->isHungry[n] + && (me->fork[left(n)] == FREE) + && (me->fork[n] == FREE)) + { + me->fork[left(n)] = USED; + me->fork[n] = USED; +#ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, EAT_SIG, n); +#else + TableEvt *pe = Q_NEW(TableEvt, EAT_SIG); + pe->philoId = n; +#endif + QACTIVE_PUBLISH(&pe->super, &me->super); + me->isHungry[n] = false; + BSP_displayPhilStat(n, EATING); + } +} + + + uint8_t n = Q_EVT_CAST(TableEvt)->philoId; + +// phil ID must be in range and he must be not hungry +Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); + +BSP_displayPhilStat(n, HUNGRY); +uint8_t m = left(n); + + + (me->fork[m] == FREE) && (me->fork[n] == FREE) + me->fork[m] = USED; +me->fork[n] = USED; + +#ifdef QEVT_DYN_CTOR +TableEvt const *pe = Q_NEW(TableEvt, EAT_SIG, n); +#else +TableEvt *pe = Q_NEW(TableEvt, EAT_SIG); +pe->philoId = n; +#endif +QACTIVE_PUBLISH(&pe->super, &me->super); +BSP_displayPhilStat(n, EATING); + + + + + + + else + me->isHungry[n] = true; + + + + + + + + + + + uint8_t n = Q_EVT_CAST(TableEvt)->philoId; + +// phil ID must be in range and he must be not hungry +Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); + +BSP_displayPhilStat(n, THINKING); +uint8_t m = left(n); + +// both forks of Phil[n] must be used +Q_ASSERT((me->fork[n] == USED) && (me->fork[m] == USED)); + +me->fork[m] = FREE; +me->fork[n] = FREE; +m = right(n); // check the right neighbor + +if (me->isHungry[m] && (me->fork[m] == FREE)) { + me->fork[n] = USED; + me->fork[m] = USED; + me->isHungry[m] = false; +#ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, EAT_SIG, m); +#else + TableEvt *pe = Q_NEW(TableEvt, EAT_SIG); + pe->philoId = m; +#endif + QACTIVE_PUBLISH(&pe->super, &me->super); + BSP_displayPhilStat(m, EATING); +} +m = left(n); // check the left neighbor +n = left(m); // left fork of the left neighbor +if (me->isHungry[m] && (me->fork[n] == FREE)) { + me->fork[m] = USED; + me->fork[n] = USED; + me->isHungry[m] = false; +#ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, EAT_SIG, m); +#else + TableEvt *pe = Q_NEW(TableEvt, EAT_SIG); + pe->philoId = m; +#endif + QACTIVE_PUBLISH(&pe->super, &me->super); + BSP_displayPhilStat(m, EATING); +} + + + + + + + Q_ERROR(); + + + + + + + + + + + + + + + + + BSP_displayPaused(1U); + BSP_displayPaused(0U); + + + + + + + + + uint8_t n = Q_EVT_CAST(TableEvt)->philoId; + +// philo ID must be in range and he must be not hungry +Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); + +me->isHungry[n] = true; +BSP_displayPhilStat(n, HUNGRY); + + + + + + + uint8_t n = Q_EVT_CAST(TableEvt)->philoId; + +// phil ID must be in range and he must be not hungry +Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); + +BSP_displayPhilStat(n, THINKING); +uint8_t m = left(n); + +// both forks of Phil[n] must be used +Q_ASSERT((me->fork[n] == USED) && (me->fork[m] == USED)); + +me->fork[m] = FREE; +me->fork[n] = FREE; + + + + + + + + + + + + + + + + + + + + + + // NOTE: data needed by this thread should be members of +// the thread class. That way they are in the memory region +// accessible from this thread. + + + + + + QS_OBJ_DICTIONARY(TH_XThread1); +QS_OBJ_DICTIONARY(&TH_XThread1->timeEvt); + +// downcast the generic thr pointer to the specific thread +XThread1 *me = (XThread1 *)thr; + +// subscribe to the EAT signal (from the application) +QActive_subscribe(&me->super.super, EAT_SIG); + +for (;;) { + QEvt const *e = QXThread_queueGet(BSP_TICKS_PER_SEC/4U); + if (e) { + QXSemaphore_signal(&TH_sema); // signal Thread2 + QF_gc(e); // must explicitly recycle the received event! + } + + QXMutex_lock(&TH_mutex, QXTHREAD_NO_TIMEOUT); // lock the mutex + BSP_ledOn(); + if (QXMutex_tryLock(&TH_mutex)) { // exercise the mutex + // some floating point code to exercise the VFP... + float volatile x = 1.4142135F; + x = x * 1.4142135F; + QXThread_delay(10U); // BLOCK while holding a mutex + QXMutex_unlock(&TH_mutex); + } + QXMutex_unlock(&TH_mutex); + BSP_ledOff(); +} + + + + + + + // NOTE: data needed by this thread should be members of +// the thread class. That way they are in the memory region +// accessible from this thread. + + + + + + QS_OBJ_DICTIONARY(TH_XThread2); +QS_OBJ_DICTIONARY(&TH_XThread2->timeEvt); +QS_OBJ_DICTIONARY(&TH_sema); +QS_OBJ_DICTIONARY(&TH_mutex); + +// downcast the generic thr pointer to the specific thread +//XThread2 *me = (XThread2 *)thr; + +// initialize the semaphore before using it +// NOTE: Here the semaphore is initialized in the highest-priority thread +// that uses it. Alternatively, the semaphore can be initialized +// before any thread runs. +QXSemaphore_init(&TH_sema, + 0U, // count==0 (signaling semaphore) + 1U); // max_count==1 (binary semaphore) + +// initialize the mutex before using it +// NOTE: Here the mutex is initialized in the highest-priority thread +// that uses it. Alternatively, the mutex can be initialized +// before any thread runs. +QXMutex_init(&TH_mutex, N_PHILO + 6U); // priority-ceiling mutex +//QXMutex_init(&TH_mutex, 0U); // alternatively: priority-ceiling NOT used + +for (;;) { + // wait on a semaphore (BLOCK indefinitely) + QXSemaphore_wait(&TH_sema, QXTHREAD_NO_TIMEOUT); + + QXMutex_lock(&TH_mutex, QXTHREAD_NO_TIMEOUT); // lock the mutex + QXThread_delay(5U); // wait more (BLOCK) + QXMutex_unlock(&TH_mutex); +} + + + + + + + + #ifndef DPP_H_ +#define DPP_H_ + +$declare ${Shared} + +#ifdef QXK_H_ +$declare ${Shared-TH} +#endif // QXK_H_ + +#endif // DPP_H_ + + + + #include "qpc.h" // QP/C real-time embedded framework +#include "dpp.h" // DPP Application interface +#include "bsp.h" // Board Support Package + +$declare ${AOs::Philo} + +//---------------------------------------------------------------------------- +Q_DEFINE_THIS_FILE + +// helper function to provide a randomized think time for Philos +static QTimeEvtCtr think_time(void); // prototype +static inline QTimeEvtCtr think_time(void) { + return (QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + + (BSP_TICKS_PER_SEC/2U)); +} + +// helper function to provide a randomized eat time for Philos +static QTimeEvtCtr eat_time(void); // prototype +static inline QTimeEvtCtr eat_time(void) { + return (QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + + BSP_TICKS_PER_SEC); +} +//---------------------------------------------------------------------------- + +$define ${Shared::Philo_ctor} + +$define ${AOs::Philo} + + + + #include "qpc.h" // QP/C real-time embedded framework +#include "dpp.h" // DPP Application interface +#include "bsp.h" // Board Support Package + +$declare ${AOs::Table} + +//---------------------------------------------------------------------------- +Q_DEFINE_THIS_FILE + +// helper function to provide the RIGHT neighbor of a Philo[n] +static inline uint8_t right(uint8_t const n) { + return (uint8_t)((n + (N_PHILO - 1U)) % N_PHILO); +} + +// helper function to provide the LEFT neighbor of a Philo[n] +static inline uint8_t left(uint8_t const n) { + return (uint8_t)((n + 1U) % N_PHILO); +} + +#define FREE ((uint8_t)0U) +#define USED ((uint8_t)1U) + +#define THINKING "thinking" +#define HUNGRY "hungry " +#define EATING "eating " + +//---------------------------------------------------------------------------- + +$define ${Shared::Table_ctor} + +$define ${AOs::Table} + + + + + + + #include "qpc.h" // QP/C real-time embedded framework +#include "dpp.h" // DPP Application interface +#include "bsp.h" // Board Support Package + +//---------------------------------------------------------------------------- +Q_DEFINE_THIS_FILE + +//---------------------------------------------------------------------------- +$define ${Shared-TH::TH_sema} +$define ${Shared-TH::TH_mutex} + +$declare ${XThreads::XThread1} +$define ${Shared-TH::XThread1_ctor} +$define ${XThreads::XThread1} + + + + #include "qpc.h" // QP/C real-time embedded framework +#include "dpp.h" // DPP Application interface +#include "bsp.h" // Board Support Package + +//---------------------------------------------------------------------------- +Q_DEFINE_THIS_FILE + +//---------------------------------------------------------------------------- +$declare ${XThreads::XThread2} +$define ${Shared-TH::XThread2_ctor} +$define ${XThreads::XThread2} + + + diff --git a/examples/arm-cm/dpp_ek-tm4c123gxl_mpu/ek-tm4c123gxl.jpg b/examples/arm-cm/dpp_ek-tm4c123gxl_mpu/ek-tm4c123gxl.jpg new file mode 100644 index 00000000..5ed6188c Binary files /dev/null and b/examples/arm-cm/dpp_ek-tm4c123gxl_mpu/ek-tm4c123gxl.jpg differ diff --git a/examples/arm-cm/dpp_ek-tm4c123gxl_mpu/main.c b/examples/arm-cm/dpp_ek-tm4c123gxl_mpu/main.c new file mode 100644 index 00000000..deac175a --- /dev/null +++ b/examples/arm-cm/dpp_ek-tm4c123gxl_mpu/main.c @@ -0,0 +1,44 @@ +//============================================================================ +// APP example +// Last updated for version 7.3.0 +// Last updated on 2023-08-09 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. +// +// This program is open source software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Alternatively, this program may be distributed and modified under the +// terms of Quantum Leaps commercial licenses, which expressly supersede +// the GNU General Public License and are specifically designed for +// licensees interested in retaining the proprietary status of their code. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Contact information: +// +// +//============================================================================ +#include "qpc.h" // QP/C real-time embedded framework +#include "dpp.h" // DPP Application interface +#include "bsp.h" // Board Support Package + +//............................................................................ +int main() { + QF_init(); // initialize the framework and the underlying RT kernel + BSP_init(); // initialize the BSP + BSP_start(); // start the AOs/Threads + return QF_run(); // run the QF application +} diff --git a/examples/arm-cm/dpp_ek-tm4c123gxl_mpu/philo.c b/examples/arm-cm/dpp_ek-tm4c123gxl_mpu/philo.c new file mode 100644 index 00000000..cb1f03ec --- /dev/null +++ b/examples/arm-cm/dpp_ek-tm4c123gxl_mpu/philo.c @@ -0,0 +1,251 @@ +//$file${.::philo.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// +// Model: dpp_mpu.qm +// File: ${.::philo.c} +// +// This code has been generated by QM 5.3.0 . +// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. +// +// SPDX-License-Identifier: GPL-3.0-or-later +// +// This generated code is open source software: you can redistribute it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation. +// +// This code is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// NOTE: +// Alternatively, this generated code may be distributed under the terms +// of Quantum Leaps commercial licenses, which expressly supersede the GNU +// General Public License and are specifically designed for licensees +// interested in retaining the proprietary status of their code. +// +// Contact information: +// +// +// +//$endhead${.::philo.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +#include "qpc.h" // QP/C real-time embedded framework +#include "dpp.h" // DPP Application interface +#include "bsp.h" // Board Support Package + +//$declare${AOs::Philo} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${AOs::Philo} .............................................................. +typedef struct { +// protected: + QActive super; + +// private: + QTimeEvt timeEvt; + uint8_t id; +} Philo; + +// protected: +static QState Philo_initial(Philo * const me, void const * const par); +static QState Philo_thinking(Philo * const me, QEvt const * const e); +static QState Philo_hungry(Philo * const me, QEvt const * const e); +static QState Philo_eating(Philo * const me, QEvt const * const e); +//$enddecl${AOs::Philo} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +//---------------------------------------------------------------------------- +Q_DEFINE_THIS_FILE + +// helper function to provide a randomized think time for Philos +static QTimeEvtCtr think_time(void); // prototype +static inline QTimeEvtCtr think_time(void) { + return (QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + + (BSP_TICKS_PER_SEC/2U)); +} + +// helper function to provide a randomized eat time for Philos +static QTimeEvtCtr eat_time(void); // prototype +static inline QTimeEvtCtr eat_time(void) { + return (QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + + BSP_TICKS_PER_SEC); +} +//---------------------------------------------------------------------------- + +//$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// Check for the minimum required QP version +#if (QP_VERSION < 730U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) +#error qpc version 7.3.0 or higher required +#endif +//$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +//$define${Shared::Philo_ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${Shared::Philo_ctor} ...................................................... +void Philo_ctor( + uint_fast8_t const id, + uint8_t * const sto, + uint32_t const size, + void const * const mpu) +{ + Q_REQUIRE(sizeof(Philo) <= size); + + Philo *me = (Philo *)sto; + QActive_ctor(&me->super, Q_STATE_CAST(&Philo_initial)); + QTimeEvt_ctorX(&me->timeEvt, &me->super, TIMEOUT_SIG, 0U), + me->id = (uint8_t)id; + me->super.thread = mpu; +} +//$enddef${Shared::Philo_ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +//$define${AOs::Philo} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${AOs::Philo} .............................................................. + +//${AOs::Philo::SM} .......................................................... +static QState Philo_initial(Philo * const me, void const * const par) { + //${AOs::Philo::SM::initial} + Q_UNUSED_PAR(par); + + #ifdef Q_SPY + Philo *Philo_inst = me; + QS_OBJ_ARR_DICTIONARY(Philo_inst, me->id); + QS_OBJ_ARR_DICTIONARY(&Philo_inst->timeEvt, me->id); + #endif + + QActive_subscribe(&me->super, EAT_SIG); + QActive_subscribe(&me->super, TEST_SIG); + + QS_FUN_DICTIONARY(&Philo_thinking); + QS_FUN_DICTIONARY(&Philo_hungry); + QS_FUN_DICTIONARY(&Philo_eating); + + return Q_TRAN(&Philo_thinking); +} + +//${AOs::Philo::SM::thinking} ................................................ +static QState Philo_thinking(Philo * const me, QEvt const * const e) { + QState status_; + switch (e->sig) { + //${AOs::Philo::SM::thinking} + case Q_ENTRY_SIG: { + QTimeEvt_armX(&me->timeEvt, think_time(), 0U); + status_ = Q_HANDLED(); + break; + } + //${AOs::Philo::SM::thinking} + case Q_EXIT_SIG: { + (void)QTimeEvt_disarm(&me->timeEvt); + status_ = Q_HANDLED(); + break; + } + //${AOs::Philo::SM::thinking::TIMEOUT} + case TIMEOUT_SIG: { + status_ = Q_TRAN(&Philo_hungry); + break; + } + //${AOs::Philo::SM::thinking::EAT, DONE} + case EAT_SIG: // intentionally fall through + case DONE_SIG: { + // EAT or DONE must be for other Philos than this one + Q_ASSERT(Q_EVT_CAST(TableEvt)->philoId != me->id); + status_ = Q_HANDLED(); + break; + } + //${AOs::Philo::SM::thinking::TEST} + case TEST_SIG: { + status_ = Q_HANDLED(); + break; + } + default: { + status_ = Q_SUPER(&QHsm_top); + break; + } + } + return status_; +} + +//${AOs::Philo::SM::hungry} .................................................. +static QState Philo_hungry(Philo * const me, QEvt const * const e) { + QState status_; + switch (e->sig) { + //${AOs::Philo::SM::hungry} + case Q_ENTRY_SIG: { + #ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, HUNGRY_SIG, me->id); + #else + TableEvt *pe = Q_NEW(TableEvt, HUNGRY_SIG); + pe->philoId = me->id; + #endif + QACTIVE_POST(AO_Table, &pe->super, &me->super); + status_ = Q_HANDLED(); + break; + } + //${AOs::Philo::SM::hungry::EAT} + case EAT_SIG: { + //${AOs::Philo::SM::hungry::EAT::[e->philoId==me->iid]} + if (Q_EVT_CAST(TableEvt)->philoId == me->id) { + status_ = Q_TRAN(&Philo_eating); + } + else { + status_ = Q_UNHANDLED(); + } + break; + } + //${AOs::Philo::SM::hungry::DONE} + case DONE_SIG: { + // DONE must be for other Philos than this one + Q_ASSERT(Q_EVT_CAST(TableEvt)->philoId != me->id); + status_ = Q_HANDLED(); + break; + } + default: { + status_ = Q_SUPER(&QHsm_top); + break; + } + } + return status_; +} + +//${AOs::Philo::SM::eating} .................................................. +static QState Philo_eating(Philo * const me, QEvt const * const e) { + QState status_; + switch (e->sig) { + //${AOs::Philo::SM::eating} + case Q_ENTRY_SIG: { + QTimeEvt_armX(&me->timeEvt, eat_time(), 0U); + status_ = Q_HANDLED(); + break; + } + //${AOs::Philo::SM::eating} + case Q_EXIT_SIG: { + QTimeEvt_disarm(&me->timeEvt); + + #ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, DONE_SIG, me->id); + #else + TableEvt *pe = Q_NEW(TableEvt, DONE_SIG); + pe->philoId = me->id; + #endif + QACTIVE_PUBLISH(&pe->super, &me->super); + status_ = Q_HANDLED(); + break; + } + //${AOs::Philo::SM::eating::TIMEOUT} + case TIMEOUT_SIG: { + status_ = Q_TRAN(&Philo_thinking); + break; + } + //${AOs::Philo::SM::eating::EAT, DONE} + case EAT_SIG: // intentionally fall through + case DONE_SIG: { + // EAT or DONE must be for other Philos than this one + Q_ASSERT(Q_EVT_CAST(TableEvt)->philoId != me->id); + status_ = Q_HANDLED(); + break; + } + default: { + status_ = Q_SUPER(&QHsm_top); + break; + } + } + return status_; +} +//$enddef${AOs::Philo} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/examples/arm-cm/dpp_ek-tm4c123gxl_mpu/qk/armclang/dpp-qk.sct b/examples/arm-cm/dpp_ek-tm4c123gxl_mpu/qk/armclang/dpp-qk.sct new file mode 100644 index 00000000..fda39c74 --- /dev/null +++ b/examples/arm-cm/dpp_ek-tm4c123gxl_mpu/qk/armclang/dpp-qk.sct @@ -0,0 +1,23 @@ +; ************************************************************* +; *** Scatter-Loading Description File generated by uVision *** +; +; Modified by Quantum Leaps: +; added STACK as the first section in RW_STACK +; ************************************************************* + +LR_IROM1 0x00000000 0x00040000 { ; load region size_region + ER_IROM1 0x00000000 0x00040000 { ; load address = execution address + *.o (RESET, +First) + *(InRoot$$Sections) + .ANY (+RO) + .ANY (+XO) + } + + RW_STACK 0x20000000 { ; <== Quantum Leaps + * (STACK, +First) + } + RW_IRAM1 +0 (0x00008000 - 2048) { ; NOTE: 2048 assumeed STACK size! + .ANY (+RW +ZI) + } +} + diff --git a/examples/arm-cm/dpp_ek-tm4c123gxl_mpu/qk/armclang/dpp-qk.uvoptx b/examples/arm-cm/dpp_ek-tm4c123gxl_mpu/qk/armclang/dpp-qk.uvoptx new file mode 100644 index 00000000..d2e57daa --- /dev/null +++ b/examples/arm-cm/dpp_ek-tm4c123gxl_mpu/qk/armclang/dpp-qk.uvoptx @@ -0,0 +1,1072 @@ + + + + 1.0 + +
### uVision Project, (C) Keil Software
+ + + *.c + *.s*; *.src; *.a* + *.obj; *.o + *.lib + *.txt; *.h; *.inc; *.md + *.plm + *.cpp + 0 + + + + 0 + 0 + + + + dpp-dbg + 0x4 + ARM-ADS + + 12000000 + + 1 + 1 + 1 + 0 + 0 + + + 1 + 65535 + 0 + 0 + 0 + + + 79 + 66 + 8 + .\dbg\ + + + 1 + 1 + 1 + 0 + 1 + 1 + 0 + 1 + 0 + 0 + 0 + 0 + + + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + + + 1 + 0 + 1 + + 4 + + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + 0 + 1 + 1 + 0 + 0 + 1 + 0 + 0 + 19 + + + + + + + + + + + BIN\lmidk-agdi.dll + + + + 0 + ARMRTXEVENTFLAGS + -L70 -Z18 -C0 -M0 -T1 + + + 0 + UL2CM3 + UL2CM3(-O207 -S0 -C0 -FO7 -FN1 -FC1000 -FD20000000 -FF0TM4C123_256 -FL040000 -FS00 -FP0($$Device:TM4C123GH6PM$Flash\TM4C123_256.FLM) + + + 0 + DLGTARM + (1010=-1,-1,-1,-1,0)(1007=-1,-1,-1,-1,0)(1008=-1,-1,-1,-1,0)(1009=-1,-1,-1,-1,0)(1012=2637,758,3114,1073,0) + + + 0 + ARMDBGFLAGS + + + + 0 + lmidk-agdi + -U0E10259B -O4686 -S5 -FO29 + + + + + + 1 + 2 + 0x20000200 + 0 + + + + + 2 + 0 + 0x400 + 0 + + + + 0 + + + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + + + + 0 + 0 + 0 + + + + + + + + + + + + + dpp-rel + 0x4 + ARM-ADS + + 12000000 + + 1 + 1 + 1 + 0 + 0 + + + 1 + 65535 + 0 + 0 + 0 + + + 79 + 66 + 8 + .\rel\ + + + 1 + 1 + 1 + 0 + 1 + 1 + 0 + 1 + 0 + 0 + 0 + 0 + + + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + + + 1 + 0 + 0 + + 4 + + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + 1 + 1 + 0 + 1 + 0 + 1 + 1 + 0 + 0 + 1 + 0 + 0 + 19 + + + + + + + + + + + BIN\lmidk-agdi.dll + + + + 0 + DLGUARM + ÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÈ`» +´­­ª¤ô + + + 0 + ARMRTXEVENTFLAGS + -L70 -Z18 -C0 -M0 -T1 + + + 0 + DLGTARM + (1010=-1,-1,-1,-1,0)(1007=-1,-1,-1,-1,0)(1008=-1,-1,-1,-1,0)(1009=-1,-1,-1,-1,0)(1012=-1,-1,-1,-1,0) + + + 0 + ARMDBGFLAGS + + + + 0 + lmidk-agdi + -U0E10259B -O4622 -S4 -FO61 + + + 0 + UL2CM3 + -O207 -S0 -C0 -FO7 -FN1 -FC1000 -FD20000000 -FF0TM4C123_256 -FL040000 -FS00 -FP0($$Device:TM4C123GH6PM$Flash\TM4C123_256.FLM) + + + + + 0 + 0 + 121 + 1 +
0
+ 0 + 0 + 0 + 0 + 0 + 0 + ..\bsp.c + + +
+ + 1 + 0 + 105 + 1 +
0
+ 0 + 0 + 0 + 0 + 0 + 0 + ..\bsp.c + + +
+
+ + + 1 + 2 + 0x20000200 + 0 + + + + + 2 + 0 + 0x400 + 0 + + + + 0 + + + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + + + + 0 + 0 + 0 + + + + + + + + +
+
+ + + dpp-spy + 0x4 + ARM-ADS + + 12000000 + + 1 + 1 + 1 + 0 + 0 + + + 1 + 65535 + 0 + 0 + 0 + + + 79 + 66 + 8 + .\spy\ + + + 1 + 1 + 1 + 0 + 1 + 1 + 0 + 1 + 0 + 0 + 0 + 0 + + + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + + + 1 + 0 + 0 + + 4 + + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + 1 + 1 + 0 + 1 + 0 + 1 + 1 + 0 + 0 + 1 + 0 + 0 + 19 + + + + + + + + + + + BIN\lmidk-agdi.dll + + + + 0 + ARMRTXEVENTFLAGS + -L70 -Z18 -C0 -M0 -T1 + + + 0 + UL2CM3 + UL2CM3(-O207 -S0 -C0 -FO7 -FN1 -FC1000 -FD20000000 -FF0TM4C123_256 -FL040000 -FS00 -FP0($$Device:TM4C123GH6PM$Flash\TM4C123_256.FLM) + + + 0 + DLGTARM + (1010=-1,-1,-1,-1,0)(1007=-1,-1,-1,-1,0)(1008=-1,-1,-1,-1,0)(1009=-1,-1,-1,-1,0)(1012=-1,-1,-1,-1,0) + + + 0 + ARMDBGFLAGS + + + + 0 + lmidk-agdi + -U0E2006F4 -O4622 -S4 -FO61 + + + + + 0 + 0 + 186 + 1 +
3270
+ 0 + 0 + 0 + 0 + 0 + 1 + ..\..\philo.c + + \\dpp_qk\../../philo.c\186 +
+ + 1 + 0 + 88 + 1 +
17816
+ 0 + 0 + 0 + 0 + 0 + 1 + ..\bsp.c + + \\dpp_qk\../bsp.c\88 +
+
+ + + 1 + 2 + 0x20000200 + 0 + + + + + 2 + 0 + 0x400 + 0 + + + + 0 + + + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + + + + 0 + 0 + 0 + + + + + + + + +
+
+ + + Applicatioin + 1 + 0 + 0 + 0 + + 1 + 1 + 1 + 0 + 0 + 0 + ..\bsp.c + bsp.c + 0 + 0 + + + 1 + 2 + 5 + 0 + 0 + 0 + ..\..\dpp.h + dpp.h + 0 + 0 + + + 1 + 3 + 5 + 0 + 0 + 0 + ..\..\bsp.h + bsp.h + 0 + 0 + + + 1 + 4 + 1 + 0 + 0 + 0 + ..\..\philo.c + philo.c + 0 + 0 + + + 1 + 5 + 1 + 0 + 0 + 0 + ..\..\table.c + table.c + 0 + 0 + + + 1 + 6 + 1 + 0 + 0 + 0 + ..\..\main.c + main.c + 0 + 0 + + + + + ek-tm4c123gxl + 1 + 0 + 0 + 0 + + 2 + 7 + 1 + 0 + 0 + 0 + ..\..\..\..\..\3rd_party\ek-tm4c123gxl\system_TM4C123GH6PM.c + system_TM4C123GH6PM.c + 0 + 0 + + + 2 + 8 + 5 + 0 + 0 + 0 + ..\..\..\..\..\3rd_party\ek-tm4c123gxl\TM4C123GH6PM.h + TM4C123GH6PM.h + 0 + 0 + + + 2 + 9 + 2 + 0 + 0 + 0 + ..\..\..\..\..\3rd_party\ek-tm4c123gxl\arm\startup_TM4C123GH6PM.s + startup_TM4C123GH6PM.s + 0 + 0 + + + 2 + 10 + 5 + 0 + 0 + 0 + ..\..\..\..\..\3rd_party\ek-tm4c123gxl\gpio.h + gpio.h + 0 + 0 + + + 2 + 11 + 5 + 0 + 0 + 0 + ..\..\..\..\..\3rd_party\ek-tm4c123gxl\rom.h + rom.h + 0 + 0 + + + 2 + 12 + 5 + 0 + 0 + 0 + ..\..\..\..\..\3rd_party\ek-tm4c123gxl\sysctl.h + sysctl.h + 0 + 0 + + + 2 + 13 + 5 + 0 + 0 + 0 + ..\..\..\..\..\3rd_party\ek-tm4c123gxl\system_TM4C123GH6PM.h + system_TM4C123GH6PM.h + 0 + 0 + + + + + QP + 1 + 0 + 0 + 0 + + 3 + 14 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qf\qep_hsm.c + qep_hsm.c + 0 + 0 + + + 3 + 15 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qf\qep_msm.c + qep_msm.c + 0 + 0 + + + 3 + 16 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qf\qf_act.c + qf_act.c + 0 + 0 + + + 3 + 17 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qf\qf_actq.c + qf_actq.c + 0 + 0 + + + 3 + 18 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qf\qf_defer.c + qf_defer.c + 0 + 0 + + + 3 + 19 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qf\qf_dyn.c + qf_dyn.c + 0 + 0 + + + 3 + 20 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qf\qf_mem.c + qf_mem.c + 0 + 0 + + + 3 + 21 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qf\qf_ps.c + qf_ps.c + 0 + 0 + + + 3 + 22 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qf\qf_qact.c + qf_qact.c + 0 + 0 + + + 3 + 23 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qf\qf_qeq.c + qf_qeq.c + 0 + 0 + + + 3 + 24 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qf\qf_qmact.c + qf_qmact.c + 0 + 0 + + + 3 + 25 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qf\qf_time.c + qf_time.c + 0 + 0 + + + 3 + 26 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qk\qk.c + qk.c + 0 + 0 + + + + + QP_port + 1 + 0 + 0 + 0 + + 4 + 27 + 1 + 0 + 0 + 0 + ..\..\..\..\..\ports\arm-cm\qk\armclang\qk_port.c + qk_port.c + 0 + 0 + + + + + QS + 1 + 0 + 0 + 0 + + 5 + 28 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qs\qs.c + qs.c + 0 + 0 + + + 5 + 29 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qs\qs_64bit.c + qs_64bit.c + 0 + 0 + + + 5 + 30 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qs\qs_fp.c + qs_fp.c + 0 + 0 + + + 5 + 31 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qs\qs_rx.c + qs_rx.c + 0 + 0 + + + 5 + 32 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qs\qstamp.c + qstamp.c + 0 + 0 + + + +
diff --git a/examples/arm-cm/dpp_ek-tm4c123gxl_mpu/qk/armclang/dpp-qk.uvprojx b/examples/arm-cm/dpp_ek-tm4c123gxl_mpu/qk/armclang/dpp-qk.uvprojx new file mode 100644 index 00000000..74337121 --- /dev/null +++ b/examples/arm-cm/dpp_ek-tm4c123gxl_mpu/qk/armclang/dpp-qk.uvprojx @@ -0,0 +1,1838 @@ + + + + 2.1 + +
### uVision Project, (C) Keil Software
+ + + + dpp-dbg + 0x4 + ARM-ADS + 6160000::V6.16::ARMCLANG + 1 + + + TM4C123GH6PM + Texas Instruments + Keil.TM4C_DFP.1.1.0 + http://www.keil.com/pack/ + IROM(0x00000000,0x040000) IRAM(0x20000000,0x008000) CPUTYPE("Cortex-M4") FPU2 CLOCK(12000000) ELITTLE + + + UL2CM3(-S0 -C0 -P0 -FD20000000 -FC1000 -FN1 -FF0TM4C123_256 -FS00 -FL040000 -FP0($$Device:TM4C123GH6PM$Flash\TM4C123_256.FLM)) + 0 + $$Device:TM4C123GH6PM$Device\Include\TM4C123\TM4C123.h + + + + + + + + + + $$Device:TM4C123GH6PM$SVD\TM4C123\TM4C123GH6PM.svd + 0 + 0 + + + + + + + 0 + 0 + 0 + 0 + 1 + + .\dbg\ + dpp-qk + 1 + 0 + 0 + 1 + 1 + .\dbg\ + 1 + 0 + 0 + + 0 + 0 + + + 0 + 0 + 0 + 0 + + + 1 + 0 + cmd /c "del .\dbg\qstamp.o" + + 0 + 0 + 0 + 0 + + + 1 + 0 + fromelf --bin --output .\dbg\dpp-qk.bin .\dbg\dpp-qk.axf + + 0 + 0 + 0 + 0 + + 1 + + + + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 3 + + + 1 + + + SARMCM3.DLL + -MPU + DCM.DLL + -pCM4 + SARMCM3.DLL + -MPU + TCM.DLL + -pCM4 + + + + 1 + 0 + 0 + 0 + 16 + + + + + 1 + 0 + 0 + 1 + 1 + 4096 + + 1 + BIN\UL2CM3.DLL + "" () + + + + + 0 + + + + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + 1 + 0 + 0 + 0 + 0 + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + "Cortex-M4" + + 0 + 0 + 0 + 1 + 1 + 0 + 0 + 2 + 0 + 0 + 0 + 0 + 8 + 0 + 0 + 0 + 0 + 3 + 3 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 1 + 0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x20000000 + 0x8000 + + + 1 + 0x0 + 0x40000 + + + 0 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x40000 + + + 1 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x20000000 + 0x8000 + + + 0 + 0x0 + 0x0 + + + + + + 0 + 1 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 3 + 0 + 1 + 0 + 0 + 0 + 3 + 3 + 0 + 0 + 0 + 0 + 0 + + + QP_CONFIG + + ..\..;..\..\..\..\..\include;..\..\..\..\..\ports\arm-cm\qk\armclang;..\..\..\..\..\3rd_party\CMSIS\Include;..\..\..\..\..\3rd_party\ek-tm4c123gxl + + + + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 4 + + + Stack_Size=2048 Heap_Size=16 + + + + + + 0 + 0 + 0 + 0 + 1 + 0 + 0x00000000 + 0x20000000 + + .\dpp-qk.sct + + + --entry Reset_Handler + + + + + + + + Applicatioin + + + bsp.c + 1 + ..\bsp.c + + + dpp.h + 5 + ..\..\dpp.h + + + bsp.h + 5 + ..\..\bsp.h + + + philo.c + 1 + ..\..\philo.c + + + table.c + 1 + ..\..\table.c + + + main.c + 1 + ..\..\main.c + + + + + ek-tm4c123gxl + + + system_TM4C123GH6PM.c + 1 + ..\..\..\..\..\3rd_party\ek-tm4c123gxl\system_TM4C123GH6PM.c + + + TM4C123GH6PM.h + 5 + ..\..\..\..\..\3rd_party\ek-tm4c123gxl\TM4C123GH6PM.h + + + startup_TM4C123GH6PM.s + 2 + ..\..\..\..\..\3rd_party\ek-tm4c123gxl\arm\startup_TM4C123GH6PM.s + + + gpio.h + 5 + ..\..\..\..\..\3rd_party\ek-tm4c123gxl\gpio.h + + + rom.h + 5 + ..\..\..\..\..\3rd_party\ek-tm4c123gxl\rom.h + + + sysctl.h + 5 + ..\..\..\..\..\3rd_party\ek-tm4c123gxl\sysctl.h + + + system_TM4C123GH6PM.h + 5 + ..\..\..\..\..\3rd_party\ek-tm4c123gxl\system_TM4C123GH6PM.h + + + + + QP + + + qep_hsm.c + 1 + ..\..\..\..\..\src\qf\qep_hsm.c + + + qep_msm.c + 1 + ..\..\..\..\..\src\qf\qep_msm.c + + + qf_act.c + 1 + ..\..\..\..\..\src\qf\qf_act.c + + + qf_actq.c + 1 + ..\..\..\..\..\src\qf\qf_actq.c + + + qf_defer.c + 1 + ..\..\..\..\..\src\qf\qf_defer.c + + + qf_dyn.c + 1 + ..\..\..\..\..\src\qf\qf_dyn.c + + + qf_mem.c + 1 + ..\..\..\..\..\src\qf\qf_mem.c + + + qf_ps.c + 1 + ..\..\..\..\..\src\qf\qf_ps.c + + + qf_qact.c + 1 + ..\..\..\..\..\src\qf\qf_qact.c + + + qf_qeq.c + 1 + ..\..\..\..\..\src\qf\qf_qeq.c + + + qf_qmact.c + 1 + ..\..\..\..\..\src\qf\qf_qmact.c + + + qf_time.c + 1 + ..\..\..\..\..\src\qf\qf_time.c + + + qk.c + 1 + ..\..\..\..\..\src\qk\qk.c + + + + + QP_port + + + qk_port.c + 1 + ..\..\..\..\..\ports\arm-cm\qk\armclang\qk_port.c + + + + + QS + + + 0 + 0 + 0 + 0 + 0 + 0 + 2 + 2 + 2 + 2 + 11 + + + 1 + + + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 0 + 0 + 0 + 0 + 2 + + + + + + + + + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + + + + + + + + + + + + qs.c + 1 + ..\..\..\..\..\src\qs\qs.c + + + qs_64bit.c + 1 + ..\..\..\..\..\src\qs\qs_64bit.c + + + qs_fp.c + 1 + ..\..\..\..\..\src\qs\qs_fp.c + + + qs_rx.c + 1 + ..\..\..\..\..\src\qs\qs_rx.c + + + qstamp.c + 1 + ..\..\..\..\..\src\qs\qstamp.c + + + + + + + dpp-rel + 0x4 + ARM-ADS + 6160000::V6.16::ARMCLANG + 1 + + + TM4C123GH6PM + Texas Instruments + Keil.TM4C_DFP.1.1.0 + http://www.keil.com/pack/ + IROM(0x00000000,0x040000) IRAM(0x20000000,0x008000) CPUTYPE("Cortex-M4") FPU2 CLOCK(12000000) ELITTLE + + + UL2CM3(-S0 -C0 -P0 -FD20000000 -FC1000 -FN1 -FF0TM4C123_256 -FS00 -FL040000 -FP0($$Device:TM4C123GH6PM$Flash\TM4C123_256.FLM)) + 0 + $$Device:TM4C123GH6PM$Device\Include\TM4C123\TM4C123.h + + + + + + + + + + $$Device:TM4C123GH6PM$SVD\TM4C123\TM4C123GH6PM.svd + 0 + 0 + + + + + + + 0 + 0 + 0 + 0 + 1 + + .\rel\ + dpp-qk + 1 + 0 + 0 + 0 + 0 + .\rel\ + 1 + 0 + 0 + + 0 + 0 + + + 0 + 0 + 0 + 0 + + + 1 + 0 + cmd /c "del .\rel\qstamp.o" + + 0 + 0 + 0 + 0 + + + 1 + 0 + fromelf --bin --output .\rel\dpp-qk.bin .\rel\dpp-qk.axf + + 0 + 0 + 0 + 0 + + 1 + + + + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 3 + + + 1 + + + SARMCM3.DLL + -MPU + DCM.DLL + -pCM4 + SARMCM3.DLL + -MPU + TCM.DLL + -pCM4 + + + + 1 + 0 + 0 + 0 + 16 + + + + + 1 + 0 + 0 + 1 + 1 + 4097 + + 1 + BIN\UL2CM3.DLL + + + + + + 0 + + + + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + 1 + 0 + 0 + 0 + 0 + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + "Cortex-M4" + + 0 + 0 + 0 + 1 + 1 + 0 + 0 + 2 + 0 + 0 + 0 + 0 + 8 + 0 + 0 + 0 + 0 + 3 + 3 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 1 + 0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x20000000 + 0x8000 + + + 1 + 0x0 + 0x40000 + + + 0 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x40000 + + + 1 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x20000000 + 0x8000 + + + 0 + 0x0 + 0x0 + + + + + + 0 + 6 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 3 + 0 + 1 + 0 + 0 + 0 + 3 + 3 + 0 + 0 + 1 + 0 + 0 + + + NDEBUG,QP_CONFIG + + ..\..;..\..\..\..\..\include;..\..\..\..\..\ports\arm-cm\qk\armclang;..\..\..\..\..\3rd_party\CMSIS\Include;..\..\..\..\..\3rd_party\ek-tm4c123gxl + + + + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 4 + + + Stack_Size=2048 Heap_Size=16 + + + + + + 0 + 0 + 0 + 0 + 1 + 0 + 0x00000000 + 0x20000000 + + .\dpp-qk.sct + + + --entry Reset_Handler + + + + + + + + Applicatioin + + + bsp.c + 1 + ..\bsp.c + + + dpp.h + 5 + ..\..\dpp.h + + + bsp.h + 5 + ..\..\bsp.h + + + philo.c + 1 + ..\..\philo.c + + + table.c + 1 + ..\..\table.c + + + main.c + 1 + ..\..\main.c + + + + + ek-tm4c123gxl + + + system_TM4C123GH6PM.c + 1 + ..\..\..\..\..\3rd_party\ek-tm4c123gxl\system_TM4C123GH6PM.c + + + TM4C123GH6PM.h + 5 + ..\..\..\..\..\3rd_party\ek-tm4c123gxl\TM4C123GH6PM.h + + + startup_TM4C123GH6PM.s + 2 + ..\..\..\..\..\3rd_party\ek-tm4c123gxl\arm\startup_TM4C123GH6PM.s + + + gpio.h + 5 + ..\..\..\..\..\3rd_party\ek-tm4c123gxl\gpio.h + + + rom.h + 5 + ..\..\..\..\..\3rd_party\ek-tm4c123gxl\rom.h + + + sysctl.h + 5 + ..\..\..\..\..\3rd_party\ek-tm4c123gxl\sysctl.h + + + system_TM4C123GH6PM.h + 5 + ..\..\..\..\..\3rd_party\ek-tm4c123gxl\system_TM4C123GH6PM.h + + + + + QP + + + qep_hsm.c + 1 + ..\..\..\..\..\src\qf\qep_hsm.c + + + qep_msm.c + 1 + ..\..\..\..\..\src\qf\qep_msm.c + + + qf_act.c + 1 + ..\..\..\..\..\src\qf\qf_act.c + + + qf_actq.c + 1 + ..\..\..\..\..\src\qf\qf_actq.c + + + qf_defer.c + 1 + ..\..\..\..\..\src\qf\qf_defer.c + + + qf_dyn.c + 1 + ..\..\..\..\..\src\qf\qf_dyn.c + + + qf_mem.c + 1 + ..\..\..\..\..\src\qf\qf_mem.c + + + qf_ps.c + 1 + ..\..\..\..\..\src\qf\qf_ps.c + + + qf_qact.c + 1 + ..\..\..\..\..\src\qf\qf_qact.c + + + qf_qeq.c + 1 + ..\..\..\..\..\src\qf\qf_qeq.c + + + qf_qmact.c + 1 + ..\..\..\..\..\src\qf\qf_qmact.c + + + qf_time.c + 1 + ..\..\..\..\..\src\qf\qf_time.c + + + qk.c + 1 + ..\..\..\..\..\src\qk\qk.c + + + + + QP_port + + + qk_port.c + 1 + ..\..\..\..\..\ports\arm-cm\qk\armclang\qk_port.c + + + + + QS + + + 0 + 0 + 0 + 0 + 0 + 0 + 2 + 2 + 2 + 2 + 11 + + + 1 + + + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 0 + 0 + 0 + 0 + 2 + + + + + + + + + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + + + + + + + + + + + + qs.c + 1 + ..\..\..\..\..\src\qs\qs.c + + + qs_64bit.c + 1 + ..\..\..\..\..\src\qs\qs_64bit.c + + + qs_fp.c + 1 + ..\..\..\..\..\src\qs\qs_fp.c + + + qs_rx.c + 1 + ..\..\..\..\..\src\qs\qs_rx.c + + + qstamp.c + 1 + ..\..\..\..\..\src\qs\qstamp.c + + + + + + + dpp-spy + 0x4 + ARM-ADS + 6160000::V6.16::ARMCLANG + 1 + + + TM4C123GH6PM + Texas Instruments + Keil.TM4C_DFP.1.1.0 + http://www.keil.com/pack/ + IROM(0x00000000,0x040000) IRAM(0x20000000,0x008000) CPUTYPE("Cortex-M4") FPU2 CLOCK(12000000) ELITTLE + + + UL2CM3(-S0 -C0 -P0 -FD20000000 -FC1000 -FN1 -FF0TM4C123_256 -FS00 -FL040000 -FP0($$Device:TM4C123GH6PM$Flash\TM4C123_256.FLM)) + 0 + $$Device:TM4C123GH6PM$Device\Include\TM4C123\TM4C123.h + + + + + + + + + + $$Device:TM4C123GH6PM$SVD\TM4C123\TM4C123GH6PM.svd + 0 + 0 + + + + + + + 0 + 0 + 0 + 0 + 1 + + .\spy\ + dpp-qk + 1 + 0 + 0 + 1 + 1 + .\spy\ + 1 + 0 + 0 + + 0 + 0 + + + 0 + 0 + 0 + 0 + + + 1 + 0 + cmd /c "del .\spy\qstamp.o" + + 0 + 0 + 0 + 0 + + + 1 + 0 + fromelf --bin --output .\spy\dpp-qk.bin .\spy\dpp-qk.axf + + 0 + 0 + 0 + 0 + + 1 + + + + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 3 + + + 1 + + + SARMCM3.DLL + -MPU + DCM.DLL + -pCM4 + SARMCM3.DLL + -MPU + TCM.DLL + -pCM4 + + + + 1 + 0 + 0 + 0 + 16 + + + + + 1 + 0 + 0 + 1 + 1 + 4097 + + 1 + BIN\UL2CM3.DLL + + + + + + 0 + + + + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + 1 + 0 + 0 + 0 + 0 + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + "Cortex-M4" + + 0 + 0 + 0 + 1 + 1 + 0 + 0 + 2 + 0 + 0 + 0 + 0 + 8 + 0 + 0 + 0 + 0 + 3 + 3 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 1 + 0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x20000000 + 0x8000 + + + 1 + 0x0 + 0x40000 + + + 0 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x40000 + + + 1 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x20000000 + 0x8000 + + + 0 + 0x0 + 0x0 + + + + + + 0 + 2 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 3 + 0 + 1 + 0 + 0 + 0 + 3 + 3 + 0 + 0 + 0 + 0 + 0 + + + Q_SPY,QP_CONFIG + + ..\..;..\..\..\..\..\include;..\..\..\..\..\ports\arm-cm\qk\armclang;..\..\..\..\..\3rd_party\CMSIS\Include;..\..\..\..\..\3rd_party\ek-tm4c123gxl + + + + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 4 + + + Stack_Size=2048 Heap_Size=16 + + + + + + 0 + 0 + 0 + 0 + 1 + 0 + 0x00000000 + 0x20000000 + + .\dpp-qk.sct + + + --entry Reset_Handler + + + + + + + + Applicatioin + + + bsp.c + 1 + ..\bsp.c + + + dpp.h + 5 + ..\..\dpp.h + + + bsp.h + 5 + ..\..\bsp.h + + + philo.c + 1 + ..\..\philo.c + + + table.c + 1 + ..\..\table.c + + + main.c + 1 + ..\..\main.c + + + + + ek-tm4c123gxl + + + system_TM4C123GH6PM.c + 1 + ..\..\..\..\..\3rd_party\ek-tm4c123gxl\system_TM4C123GH6PM.c + + + TM4C123GH6PM.h + 5 + ..\..\..\..\..\3rd_party\ek-tm4c123gxl\TM4C123GH6PM.h + + + startup_TM4C123GH6PM.s + 2 + ..\..\..\..\..\3rd_party\ek-tm4c123gxl\arm\startup_TM4C123GH6PM.s + + + gpio.h + 5 + ..\..\..\..\..\3rd_party\ek-tm4c123gxl\gpio.h + + + rom.h + 5 + ..\..\..\..\..\3rd_party\ek-tm4c123gxl\rom.h + + + sysctl.h + 5 + ..\..\..\..\..\3rd_party\ek-tm4c123gxl\sysctl.h + + + system_TM4C123GH6PM.h + 5 + ..\..\..\..\..\3rd_party\ek-tm4c123gxl\system_TM4C123GH6PM.h + + + + + QP + + + qep_hsm.c + 1 + ..\..\..\..\..\src\qf\qep_hsm.c + + + qep_msm.c + 1 + ..\..\..\..\..\src\qf\qep_msm.c + + + qf_act.c + 1 + ..\..\..\..\..\src\qf\qf_act.c + + + qf_actq.c + 1 + ..\..\..\..\..\src\qf\qf_actq.c + + + qf_defer.c + 1 + ..\..\..\..\..\src\qf\qf_defer.c + + + qf_dyn.c + 1 + ..\..\..\..\..\src\qf\qf_dyn.c + + + qf_mem.c + 1 + ..\..\..\..\..\src\qf\qf_mem.c + + + qf_ps.c + 1 + ..\..\..\..\..\src\qf\qf_ps.c + + + qf_qact.c + 1 + ..\..\..\..\..\src\qf\qf_qact.c + + + qf_qeq.c + 1 + ..\..\..\..\..\src\qf\qf_qeq.c + + + qf_qmact.c + 1 + ..\..\..\..\..\src\qf\qf_qmact.c + + + qf_time.c + 1 + ..\..\..\..\..\src\qf\qf_time.c + + + qk.c + 1 + ..\..\..\..\..\src\qk\qk.c + + + + + QP_port + + + qk_port.c + 1 + ..\..\..\..\..\ports\arm-cm\qk\armclang\qk_port.c + + + + + QS + + + qs.c + 1 + ..\..\..\..\..\src\qs\qs.c + + + qs_64bit.c + 1 + ..\..\..\..\..\src\qs\qs_64bit.c + + + qs_fp.c + 1 + ..\..\..\..\..\src\qs\qs_fp.c + + + qs_rx.c + 1 + ..\..\..\..\..\src\qs\qs_rx.c + + + qstamp.c + 1 + ..\..\..\..\..\src\qs\qstamp.c + + + + + + + + + + + + + +
diff --git a/examples/arm-cm/dpp_ek-tm4c123gxl_mpu/qk/bsp.c b/examples/arm-cm/dpp_ek-tm4c123gxl_mpu/qk/bsp.c new file mode 100644 index 00000000..fc8b5821 --- /dev/null +++ b/examples/arm-cm/dpp_ek-tm4c123gxl_mpu/qk/bsp.c @@ -0,0 +1,855 @@ +//============================================================================ +// Product: DPP example, EK-TM4C123GXL board, QK kernel, MPU isolation +// Last updated for version 7.3.0 +// Last updated on 2023-09-07 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. +// +// This program is open source software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Alternatively, this program may be distributed and modified under the +// terms of Quantum Leaps commercial licenses, which expressly supersede +// the GNU General Public License and are specifically designed for +// licensees interested in retaining the proprietary status of their code. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Contact information: +// +// +//============================================================================ +#include "qpc.h" // QP/C real-time embedded framework +#include "dpp.h" // DPP Application interface +#include "bsp.h" // Board Support Package + +#include "TM4C123GH6PM.h" // the device specific header (TI) +#include "rom.h" // the built-in ROM functions (TI) +#include "sysctl.h" // system control driver (TI) +#include "gpio.h" // GPIO driver (TI) +// add other drivers if necessary... + +Q_DEFINE_THIS_FILE // define the name of this file for assertions + +// Local-scope objects ----------------------------------------------------- +#define LED_RED (1U << 1U) +#define LED_GREEN (1U << 3U) +#define LED_BLUE (1U << 2U) + +#define BTN_SW1 (1U << 4U) +#define BTN_SW2 (1U << 0U) + +#ifdef Q_SPY + + // QSpy source IDs + static QSpyId const l_SysTick_Handler = { 0U }; + static QSpyId const l_GPIOPortA_IRQHandler = { 0U }; + + #define UART_BAUD_RATE 115200U + #define UART_FR_TXFE (1U << 7U) + #define UART_FR_RXFE (1U << 4U) + #define UART_TXFIFO_DEPTH 16U + + enum AppRecords { // application-specific trace records + PHILO_STAT = QS_USER, + PAUSED_STAT, + }; + +#endif + +//---------------------------------------------------------------------------- +// MPU storage and settings... +typedef struct { + uint32_t RBAR; + uint32_t RASR; +} MPU_Region; + +//============================================================================ +// Error handler and ISRs... + +Q_NORETURN Q_onError(char const *module, int_t const id) { + // NOTE: this implementation of the assertion handler is intended only + // for debugging and MUST be changed for deployment of the application + // (assuming that you ship your production code with assertions enabled). + Q_UNUSED_PAR(module); + Q_UNUSED_PAR(id); + QS_ASSERTION(module, id, (uint32_t)10000U); + +#ifndef NDEBUG + // light up all LEDs + GPIOF_AHB->DATA_Bits[LED_GREEN | LED_RED | LED_BLUE] = 0xFFU; + // for debugging, hang on in an endless loop... + for (;;) { + } +#endif + + NVIC_SystemReset(); +} +//............................................................................ +void assert_failed(char const * const module, int_t const id); // prototype +void assert_failed(char const * const module, int_t const id) { + Q_onError(module, id); +} + +//............................................................................ +void SysTick_Handler(void); // prototype +void SysTick_Handler(void) { + QK_ISR_ENTRY(); // inform QK about entering an ISR + + QTIMEEVT_TICK_X(0U, &l_SysTick_Handler); // time events at rate 0 + + // Perform the debouncing of buttons. The algorithm for debouncing + // adapted from the book "Embedded Systems Dictionary" by Jack Ganssle + // and Michael Barr, page 71. + static struct { + uint32_t depressed; + uint32_t previous; + } buttons = { 0U, 0U }; + + QF_INT_DISABLE(); + QF_MEM_SYS(); + + uint32_t current = ~GPIOF_AHB->DATA_Bits[BTN_SW1 | BTN_SW2]; + uint32_t tmp = buttons.depressed; // save the depressed buttons + buttons.depressed |= (buttons.previous & current); // set depressed + buttons.depressed &= (buttons.previous | current); // clear released + buttons.previous = current; // update the history + tmp ^= buttons.depressed; // changed debounced depressed + current = buttons.depressed; + + QF_MEM_APP(); + QF_INT_ENABLE(); + + if ((tmp & BTN_SW1) != 0U) { // debounced SW1 state changed? + if ((current & BTN_SW1) != 0U) { // is SW1 depressed? + static QEvt const pauseEvt = QEVT_INITIALIZER(PAUSE_SIG); + QACTIVE_PUBLISH(&pauseEvt, &l_SysTick_Handler); + } + else { // the button is released + static QEvt const serveEvt = QEVT_INITIALIZER(SERVE_SIG); + QACTIVE_PUBLISH(&serveEvt, &l_SysTick_Handler); + } + } + + QK_ISR_EXIT(); // inform QK about exiting an ISR +} +//............................................................................ +// interrupt handler for testing preemptions in QK +void GPIOPortA_IRQHandler(void); // prototype +void GPIOPortA_IRQHandler(void) { + QK_ISR_ENTRY(); // inform QK about entering an ISR + + // for testing.. + static QEvt const testEvt = QEVT_INITIALIZER(TEST_SIG); + QACTIVE_POST(AO_Table, &testEvt, &l_GPIOPortA_IRQHandler); + + QK_ISR_EXIT(); // inform QK about exiting an ISR +} + +//............................................................................ +#ifdef Q_SPY +// ISR for receiving bytes from the QSPY Back-End +// NOTE: This ISR is "QF-unaware" meaning that it does not interact with +// the QF/QK and is not disabled. Such ISRs don't need to call +// QK_ISR_ENTRY/QK_ISR_EXIT and they cannot post or publish events. + +void UART0_IRQHandler(void); // prototype +void UART0_IRQHandler(void) { + QF_MEM_SYS(); + + uint32_t status = UART0->RIS; // get the raw interrupt status + UART0->ICR = status; // clear the asserted interrupts + + while ((UART0->FR & UART_FR_RXFE) == 0U) { // while RX FIFO NOT empty + uint8_t b = (uint8_t)UART0->DR; + QS_rxPut(b); + } + QK_ARM_ERRATUM_838869(); +} +#endif // Q_SPY + +#ifdef QF_MEM_ISOLATE +//............................................................................ +__attribute__(( used )) +void QF_onMemSys(void) { + MPU->CTRL = MPU_CTRL_ENABLE_Msk // enable the MPU + | MPU_CTRL_PRIVDEFENA_Msk; // enable background region + __ISB(); + __DSB(); +} +//............................................................................ +__attribute__(( used )) +void QF_onMemApp() { + MPU->CTRL = MPU_CTRL_ENABLE_Msk; // enable the MPU + // but do NOT enable background region + __ISB(); + __DSB(); +} +//............................................................................ +#ifdef QF_ON_CONTEXT_SW +// NOTE: the context-switch callback is called with interrupts DISABLED +void QF_onContextSw(QActive *prev, QActive *next) { + if (next != (QActive *)0) { + MPU->CTRL = 0U; // disable the MPU + + MPU_Region const * const region = + (MPU_Region const *)(next->thread); + MPU->RBAR = region[0].RBAR; + MPU->RASR = region[0].RASR; + MPU->RBAR = region[1].RBAR; + MPU->RASR = region[1].RASR; + MPU->RBAR = region[2].RBAR; + MPU->RASR = region[2].RASR; + + MPU->CTRL = MPU_CTRL_ENABLE_Msk // enable the MPU + | MPU_CTRL_PRIVDEFENA_Msk; // enable background region + __ISB(); + __DSB(); + } +} +#endif // QF_ON_CONTEXT_SW +#endif // QF_MEM_ISOLATE + +//============================================================================ + +// Stack ..................................................................... +// NOTE +// The main stack size (provided here as power of 2), MUST match the actual +// stack size defined in the linker-script/startup-code. +#define STACK_SIZE_POW2 ((uint32_t)11U) + +// Table AO................................................................... +// size of Table instance, as power-of-2 +#define TABLE_SIZE_POW2 ((uint32_t)6U) + +__attribute__((aligned((1U << TABLE_SIZE_POW2)))) +static uint8_t Table_sto[1U << TABLE_SIZE_POW2]; + +#ifdef QF_MEM_ISOLATE +static MPU_Region const MPU_Table[3] = { + { (uint32_t)Table_sto + 0x10U, //---- region #0 + ((TABLE_SIZE_POW2 - 1U) << MPU_RASR_SIZE_Pos) // size + + (3U << MPU_RASR_AP_Pos) // PA:rw/UA:rw + + (1U << MPU_RASR_XN_Pos) // XN=1 + + (1U << MPU_RASR_S_Pos) // S=1 + + (1U << MPU_RASR_C_Pos) // C=1 + + (0U << MPU_RASR_B_Pos) // B=0 + + (0U << MPU_RASR_TEX_Pos) // TEX=0 + + MPU_RASR_ENABLE_Msk }, // region enable + { GPIOF_AHB_BASE + 0x11U, //---- region #1 + ((9U - 1U) << MPU_RASR_SIZE_Pos) // 2^9=512B size + + (3U << MPU_RASR_AP_Pos) // PA:rw/UA:rw + + (1U << MPU_RASR_XN_Pos) // XN=1 + + (1U << MPU_RASR_S_Pos) // S=1 + + (0U << MPU_RASR_C_Pos) // C=0 + + (1U << MPU_RASR_B_Pos) // B=1 + + (0U << MPU_RASR_TEX_Pos) // TEX=0 + + MPU_RASR_ENABLE_Msk }, // region enable + { 0U + 0x12U, //---- region #2 + 0U }, +}; +#endif + +// Philo AOs................................................................ +// size of Philo instance, as power-of-2 +#define PHILO_SIZE_POW2 ((uint32_t)6U) + +__attribute__((aligned((1U << PHILO_SIZE_POW2)))) +static uint8_t Philo_sto[N_PHILO][1U << PHILO_SIZE_POW2]; + +#define PHILO_SHARED_SIZE_POW2 ((uint32_t)5U) +__attribute__((aligned((1U << PHILO_SHARED_SIZE_POW2)))) +static union { + uint32_t rnd_seed; + uint8_t byteso[1U << PHILO_SHARED_SIZE_POW2]; +} Philo_shared_sto; + +#ifdef QF_MEM_ISOLATE +static MPU_Region const MPU_Philo[N_PHILO][3] = { + {{ (uint32_t)Philo_sto[0] + 0x10U, //---- region #0 + ((PHILO_SIZE_POW2 - 1U) << MPU_RASR_SIZE_Pos) // size + + (3U << MPU_RASR_AP_Pos) // PA:rw/UA:rw + + (1U << MPU_RASR_XN_Pos) // XN=1 + + (1U << MPU_RASR_S_Pos) // S=1 + + (1U << MPU_RASR_C_Pos) // C=1 + + (0U << MPU_RASR_B_Pos) // B=0 + + (0U << MPU_RASR_TEX_Pos) // TEX=0 + + MPU_RASR_ENABLE_Msk }, // region enable + { (uint32_t)&Philo_shared_sto + 0x11U, //---- region #1 + ((PHILO_SHARED_SIZE_POW2 - 1U) << MPU_RASR_SIZE_Pos) // size + + (3U << MPU_RASR_AP_Pos) // PA:rw/UA:rw + + (1U << MPU_RASR_XN_Pos) // XN=1 + + (1U << MPU_RASR_S_Pos) // S=1 + + (1U << MPU_RASR_C_Pos) // C=1 + + (0U << MPU_RASR_B_Pos) // B=0 + + (0U << MPU_RASR_TEX_Pos) // TEX=0 + + MPU_RASR_ENABLE_Msk }, // region enable + { 0U + 0x12U, //---- region #2 + 0U }}, + {{ (uint32_t)Philo_sto[1] + 0x10U, //---- region #0 + ((PHILO_SIZE_POW2 - 1U) << MPU_RASR_SIZE_Pos) // size + + (3U << MPU_RASR_AP_Pos) // PA:rw/UA:rw + + (1U << MPU_RASR_XN_Pos) // XN=1 + + (1U << MPU_RASR_S_Pos) // S=1 + + (1U << MPU_RASR_C_Pos) // C=1 + + (0U << MPU_RASR_B_Pos) // B=0 + + (0U << MPU_RASR_TEX_Pos) // TEX=0 + + MPU_RASR_ENABLE_Msk }, // region enable + { (uint32_t)&Philo_shared_sto + 0x11U, //---- region #1 + ((PHILO_SHARED_SIZE_POW2 - 1U) << MPU_RASR_SIZE_Pos) // size + + (3U << MPU_RASR_AP_Pos) // PA:rw/UA:rw + + (1U << MPU_RASR_XN_Pos) // XN=1 + + (1U << MPU_RASR_S_Pos) // S=1 + + (1U << MPU_RASR_C_Pos) // C=1 + + (0U << MPU_RASR_B_Pos) // B=0 + + (0U << MPU_RASR_TEX_Pos) // TEX=0 + + MPU_RASR_ENABLE_Msk }, // region enable + { 0U + 0x12U, //---- region #2 + 0U }}, + {{ (uint32_t)Philo_sto[2] + 0x10U, //---- region #0 + ((PHILO_SIZE_POW2 - 1U) << MPU_RASR_SIZE_Pos) // size + + (3U << MPU_RASR_AP_Pos) // PA:rw/UA:rw + + (1U << MPU_RASR_XN_Pos) // XN=1 + + (1U << MPU_RASR_S_Pos) // S=1 + + (1U << MPU_RASR_C_Pos) // C=1 + + (0U << MPU_RASR_B_Pos) // B=0 + + (0U << MPU_RASR_TEX_Pos) // TEX=0 + + MPU_RASR_ENABLE_Msk }, // region enable + { (uint32_t)&Philo_shared_sto + 0x11U, //---- region #1 + ((PHILO_SHARED_SIZE_POW2 - 1U) << MPU_RASR_SIZE_Pos) // size + + (3U << MPU_RASR_AP_Pos) // PA:rw/UA:rw + + (1U << MPU_RASR_XN_Pos) // XN=1 + + (1U << MPU_RASR_S_Pos) // S=1 + + (1U << MPU_RASR_C_Pos) // C=1 + + (0U << MPU_RASR_B_Pos) // B=0 + + (0U << MPU_RASR_TEX_Pos) // TEX=0 + + MPU_RASR_ENABLE_Msk }, // region enable + { 0U + 0x12U, //---- region #2 + 0U }}, + {{ (uint32_t)Philo_sto[3] + 0x10U, //---- region #0 + ((PHILO_SIZE_POW2 - 1U) << MPU_RASR_SIZE_Pos) // size + + (3U << MPU_RASR_AP_Pos) // PA:rw/UA:rw + + (1U << MPU_RASR_XN_Pos) // XN=1 + + (1U << MPU_RASR_S_Pos) // S=1 + + (1U << MPU_RASR_C_Pos) // C=1 + + (0U << MPU_RASR_B_Pos) // B=0 + + (0U << MPU_RASR_TEX_Pos) // TEX=0 + + MPU_RASR_ENABLE_Msk }, // region enable + { (uint32_t)&Philo_shared_sto + 0x11U, //---- region #1 + ((PHILO_SHARED_SIZE_POW2 - 1U) << MPU_RASR_SIZE_Pos) // size + + (3U << MPU_RASR_AP_Pos) // PA:rw/UA:rw + + (1U << MPU_RASR_XN_Pos) // XN=1 + + (1U << MPU_RASR_S_Pos) // S=1 + + (1U << MPU_RASR_C_Pos) // C=1 + + (0U << MPU_RASR_B_Pos) // B=0 + + (0U << MPU_RASR_TEX_Pos) // TEX=0 + + MPU_RASR_ENABLE_Msk }, // region enable + { 0U + 0x12U, //---- region #2 + 0U }}, + {{ (uint32_t)Philo_sto[4] + 0x10U, //---- region #0 + ((PHILO_SIZE_POW2 - 1U) << MPU_RASR_SIZE_Pos) // size + + (3U << MPU_RASR_AP_Pos) // PA:rw/UA:rw + + (1U << MPU_RASR_XN_Pos) // XN=1 + + (1U << MPU_RASR_S_Pos) // S=1 + + (1U << MPU_RASR_C_Pos) // C=1 + + (0U << MPU_RASR_B_Pos) // B=0 + + (0U << MPU_RASR_TEX_Pos) // TEX=0 + + MPU_RASR_ENABLE_Msk }, // region enable + { (uint32_t)&Philo_shared_sto + 0x11U, //---- region #1 + ((PHILO_SHARED_SIZE_POW2 - 1U) << MPU_RASR_SIZE_Pos) // size + + (3U << MPU_RASR_AP_Pos) // PA:rw/UA:rw + + (1U << MPU_RASR_XN_Pos) // XN=1 + + (1U << MPU_RASR_S_Pos) // S=1 + + (1U << MPU_RASR_C_Pos) // C=1 + + (0U << MPU_RASR_B_Pos) // B=0 + + (0U << MPU_RASR_TEX_Pos) // TEX=0 + + MPU_RASR_ENABLE_Msk }, // region enable + { 0U + 0x12U, //---- region #2 + 0U }}, +}; +#endif + +// Shared Event-pools...................................................... +#define EPOOLS_SIZE_POW2 ((uint32_t)8U) + +__attribute__((aligned((1U << EPOOLS_SIZE_POW2)))) +static struct EPools { + QF_MPOOL_EL(TableEvt) smlPool[2*N_PHILO]; + // ... other pools +} EPools_sto; +Q_ASSERT_STATIC(sizeof(EPools_sto) <= (1U << EPOOLS_SIZE_POW2)); + +//............................................................................ +#ifdef QF_MEM_ISOLATE +static void TM4C123GXL_MPU_setup(void) { + + SCB->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk; + + MPU->CTRL = 0U; // disable the MPU + + // region #7: NULL-pointer protection region + MPU->RBAR = 0x00000000U + 0x17U; // base address + region #7 + MPU->RASR = ((8U - 1U) << MPU_RASR_SIZE_Pos) // 2^8=256B size + + (0U << MPU_RASR_AP_Pos) // PA:na/UA:na + + (1U << MPU_RASR_XN_Pos) // XN=1 + + (0U << MPU_RASR_S_Pos) // S=0 + + (0U << MPU_RASR_C_Pos) // C=0 + + (0U << MPU_RASR_B_Pos) // B=0 + + (0U << MPU_RASR_TEX_Pos) // TEX=0 + + MPU_RASR_ENABLE_Msk; // region enable + + // region #6: stack region + MPU->RBAR = 0x20000000U + 0x16U; // base address + region #6 + MPU->RASR = ((STACK_SIZE_POW2 - 1U) << MPU_RASR_SIZE_Pos) // size + + (3U << MPU_RASR_AP_Pos) // PA:rw/UA:rw + + (1U << MPU_RASR_XN_Pos) // XN=1 + + (1U << MPU_RASR_S_Pos) // S=1 + + (1U << MPU_RASR_C_Pos) // C=1 + + (0U << MPU_RASR_B_Pos) // B=0 + + (0U << MPU_RASR_TEX_Pos) // TEX=0 + + MPU_RASR_ENABLE_Msk; // region enable + + // region #5: ROM region for TM4C123GXL, whole 256K + MPU->RBAR = 0x00000000U + 0x15U; // base address + region #5 + MPU->RASR = ((18U - 1U) << MPU_RASR_SIZE_Pos) // 2^18=256K size + + (6U << MPU_RASR_AP_Pos) // PA:ro/UA:ro + + (0U << MPU_RASR_XN_Pos) // XN=0 + + (0U << MPU_RASR_S_Pos) // S=0 + + (1U << MPU_RASR_C_Pos) // C=1 + + (0U << MPU_RASR_B_Pos) // B=0 + + (0U << MPU_RASR_TEX_Pos) // TEX=0 + + MPU_RASR_ENABLE_Msk; // region enable + + // region #4: Event-pools region + MPU->RBAR = (uint32_t)&EPools_sto + 0x14U;// base address + region #4 + MPU->RASR = ((EPOOLS_SIZE_POW2 - 1U) << MPU_RASR_SIZE_Pos) // size + + (3U << MPU_RASR_AP_Pos) // PA:rw/UA:rw + + (1U << MPU_RASR_XN_Pos) // XN=1 + + (1U << MPU_RASR_S_Pos) // S=1 + + (1U << MPU_RASR_C_Pos) // C=1 + + (0U << MPU_RASR_B_Pos) // B=0 + + (0U << MPU_RASR_TEX_Pos) // TEX=0 + + MPU_RASR_ENABLE_Msk; // region enable + +#ifdef Q_SPY + // region #3: QS-filters region + MPU->RBAR = (uint32_t)&QS_filt_ + 0x13U;// base address + region #3 + MPU->RASR = ((5U - 1U) << MPU_RASR_SIZE_Pos) // 2^5=32B size + + (3U << MPU_RASR_AP_Pos) // PA:rw/UA:rw + + (1U << MPU_RASR_XN_Pos) // XN=1 + + (1U << MPU_RASR_S_Pos) // S=1 + + (1U << MPU_RASR_C_Pos) // C=1 + + (0U << MPU_RASR_B_Pos) // B=0 + + (0U << MPU_RASR_TEX_Pos) // TEX=0 + + MPU_RASR_ENABLE_Msk; // region enable +#endif + + // region #0: temporary 4G region for initial transient + MPU->RBAR = 0x00000000U + 0x10U; // base address + region #0 + MPU->RASR = ((32U - 1U) << MPU_RASR_SIZE_Pos) // 2^32=4G size + + (3U << MPU_RASR_AP_Pos) // PA:rw/UA:rw + + (0U << MPU_RASR_XN_Pos) // XN=0 + + (1U << MPU_RASR_S_Pos) // S=1 + + (1U << MPU_RASR_C_Pos) // C=1 + + (0U << MPU_RASR_B_Pos) // B=0 + + (0U << MPU_RASR_TEX_Pos) // TEX=0 + + MPU_RASR_ENABLE_Msk; // region enable + + MPU->CTRL = MPU_CTRL_ENABLE_Msk; // enable the MPU + // but do NOT enable background region + __ISB(); + __DSB(); +} +#endif + +//============================================================================ + +// "opaque" pointer to AO +QActive * const AO_Table = (QActive *)Table_sto; + +QActive * const AO_Philo[N_PHILO] = { + (QActive *)Philo_sto[0], // "opaque" pointer + (QActive *)Philo_sto[1], // "opaque" pointer + (QActive *)Philo_sto[2], // "opaque" pointer + (QActive *)Philo_sto[3], // "opaque" pointer + (QActive *)Philo_sto[4] // "opaque" pointer +}; + +// BSP functions =========================================================== +void BSP_init(void) { +#ifdef QF_MEM_ISOLATE + // setup the MPU + TM4C123GXL_MPU_setup(); +#endif + + // NOTE: SystemInit() has been already called from the startup code + // but SystemCoreClock needs to be updated + SystemCoreClockUpdate(); + + // NOTE: The VFP (hardware Floating Point) unit is configured by QK + + // enable clock for to the peripherals used by this application... + SYSCTL->RCGCGPIO |= (1U << 5U); // enable Run mode for GPIOF + SYSCTL->GPIOHBCTL |= (1U << 5U); // enable AHB for GPIOF + __ISB(); + __DSB(); + + // configure LEDs (digital output) + GPIOF_AHB->DIR |= (LED_RED | LED_BLUE | LED_GREEN); + GPIOF_AHB->DEN |= (LED_RED | LED_BLUE | LED_GREEN); + GPIOF_AHB->DATA_Bits[LED_RED | LED_BLUE | LED_GREEN] = 0U; + + // configure switches... + + // unlock access to the SW2 pin because it is PROTECTED + GPIOF_AHB->LOCK = 0x4C4F434BU; // unlock GPIOCR register for SW2 + // commit the write (cast const away) + *(uint32_t volatile *)&GPIOF_AHB->CR = 0x01U; + + GPIOF_AHB->DIR &= ~(BTN_SW1 | BTN_SW2); // input + GPIOF_AHB->DEN |= (BTN_SW1 | BTN_SW2); // digital enable + GPIOF_AHB->PUR |= (BTN_SW1 | BTN_SW2); // pull-up resistor enable + + *(uint32_t volatile *)&GPIOF_AHB->CR = 0x00U; + GPIOF_AHB->LOCK = 0x0; // lock GPIOCR register for SW2 + + BSP_randomSeed(1234U); // seed the random number generator + + // initialize the QS software tracing... + if (!QS_INIT((void *)0)) { + Q_ERROR(); + } + + // dictionaries... + QS_OBJ_DICTIONARY(&l_SysTick_Handler); + QS_OBJ_DICTIONARY(&l_GPIOPortA_IRQHandler); + QS_USR_DICTIONARY(PHILO_STAT); + QS_USR_DICTIONARY(PAUSED_STAT); + + QS_ONLY(produce_sig_dict()); + + // setup the QS filters... + QS_GLB_FILTER(QS_ALL_RECORDS); // all records + QS_GLB_FILTER(-QS_QF_TICK); // exclude the clock tick +} +//............................................................................ +void BSP_start(void) { + // initialize event pools + QF_poolInit(EPools_sto.smlPool, + sizeof(EPools_sto.smlPool), + sizeof(EPools_sto.smlPool[0])); + + // initialize publish-subscribe + static QSubscrList subscrSto[MAX_PUB_SIG]; + QActive_psInit(subscrSto, Q_DIM(subscrSto)); + + // instantiate and start AOs/threads... + static QEvt const *philoQueueSto[N_PHILO][10]; + for (uint8_t n = 0U; n < N_PHILO; ++n) { +#ifdef QF_MEM_ISOLATE + Philo_ctor(n, Philo_sto[n], sizeof(Philo_sto[n]), MPU_Philo[n]); +#else + Philo_ctor(n, Philo_sto[n], sizeof(Philo_sto[n]), (void *)0); +#endif + QACTIVE_START(AO_Philo[n], + + // NOTE: set the preemption-threshold of all Philos to + // the same level, so that they cannot preempt each other. + Q_PRIO(n + 3U, N_PHILO + 2U), // QF-prio/pre-thre. + + philoQueueSto[n], // event queue storage + Q_DIM(philoQueueSto[n]), // queue length [events] + (void *)0, 0U, // no stack storage + (void *)0); // no initialization param + } + + static QEvt const *tableQueueSto[N_PHILO]; +#ifdef QF_MEM_ISOLATE + Table_ctor(Table_sto, sizeof(Table_sto), MPU_Table); +#else + Table_ctor(Table_sto, sizeof(Table_sto), (void *)0); +#endif + QACTIVE_START(AO_Table, + N_PHILO + 7U, // QP prio. of the AO + tableQueueSto, // event queue storage + Q_DIM(tableQueueSto), // queue length [events] + (void *)0, 0U, // no stack storage + (void *)0); // no initialization param +} +//............................................................................ +void BSP_displayPhilStat(uint8_t n, char const *stat) { + Q_UNUSED_PAR(n); + + GPIOF_AHB->DATA_Bits[LED_GREEN] = ((stat[0] == 'e') ? LED_GREEN : 0U); + + // app-specific trace record... + QS_BEGIN_ID(PHILO_STAT, AO_Table->prio) + QS_U8(1, n); // Philosopher number + QS_STR(stat); // Philosopher status + QS_END() +} +//............................................................................ +void BSP_displayPaused(uint8_t const paused) { + GPIOF_AHB->DATA_Bits[LED_BLUE] = ((paused != 0U) ? LED_BLUE : 0U); + + // application-specific trace record + QS_BEGIN_ID(PAUSED_STAT, AO_Table->prio) + QS_U8(1, paused); // Paused status + QS_END() +} +//............................................................................ +void BSP_randomSeed(uint32_t seed) { + Philo_shared_sto.rnd_seed = seed; +} +//............................................................................ +uint32_t BSP_random() { // a very cheap pseudo-random-number generator + // Some floating point code is to exercise the VFP... + float volatile x = 3.1415926F; + x = x + 2.7182818F; + + QSchedStatus lockStat = QK_schedLock(N_PHILO); + // "Super-Duper" Linear Congruential Generator (LCG) + // LCG(2^32, 3*7*11*13*23, 0, seed) + // + uint32_t rnd = Philo_shared_sto.rnd_seed * (3U*7U*11U*13U*23U); + Philo_shared_sto.rnd_seed = rnd; // set for the next time + QK_schedUnlock(lockStat); + + return (rnd >> 8U); +} +//............................................................................ +void BSP_ledOn() { + GPIOF_AHB->DATA_Bits[LED_RED] = 0xFFU; +} +//............................................................................ +void BSP_ledOff() { + GPIOF_AHB->DATA_Bits[LED_RED] = 0x00U; +} +//............................................................................ +void BSP_terminate(int16_t result) { + Q_UNUSED_PAR(result); +} + +//============================================================================ +// QF callbacks... +void QF_onStartup(void) { + // set up the SysTick timer to fire at BSP_TICKS_PER_SEC rate + SysTick_Config(SystemCoreClock / BSP_TICKS_PER_SEC); + + // assign all priority bits for preemption-prio. and none to sub-prio. + NVIC_SetPriorityGrouping(0U); + + // set priorities of ALL ISRs used in the system, see NOTE1 + NVIC_SetPriority(UART0_IRQn, 0U); // kernel unaware interrupt + NVIC_SetPriority(GPIOA_IRQn, QF_AWARE_ISR_CMSIS_PRI + 0U); + NVIC_SetPriority(SysTick_IRQn, QF_AWARE_ISR_CMSIS_PRI + 1U); + // ... + + // enable IRQs... + NVIC_EnableIRQ(GPIOA_IRQn); + +#ifdef Q_SPY + NVIC_EnableIRQ(UART0_IRQn); // UART interrupt used for QS-RX +#endif +} +//............................................................................ +void QF_onCleanup(void) { +} +//............................................................................ +void QK_onIdle(void) { + // toggle the User LED on and then off, see NOTE3 + QF_INT_DISABLE(); + QF_MEM_SYS(); + GPIOF_AHB->DATA_Bits[LED_BLUE] = 0xFFU; // turn the Blue LED on + GPIOF_AHB->DATA_Bits[LED_BLUE] = 0U; // turn the Blue LED off + QF_MEM_APP(); + QF_INT_ENABLE(); + + // Some floating point code is to exercise the VFP... + float volatile x = 1.73205F; + x = x * 1.73205F; + +#ifdef Q_SPY + QF_INT_DISABLE(); + QF_MEM_SYS(); + QS_rxParse(); // parse all the received bytes + QF_MEM_APP(); + QF_INT_ENABLE(); + QF_CRIT_EXIT_NOP(); + + QF_INT_DISABLE(); + QF_MEM_SYS(); + if ((UART0->FR & UART_FR_TXFE) != 0U) { // TX done? + uint16_t fifo = UART_TXFIFO_DEPTH; // max bytes we can accept + + // try to get next contiguous block to transmit + uint8_t const *block = QS_getBlock(&fifo); + + while (fifo-- != 0U) { // any bytes in the block? + UART0->DR = *block++; // put into the FIFO + } + } + QF_MEM_APP(); + QF_INT_ENABLE(); +#elif defined NDEBUG + // Put the CPU and peripherals to the low-power mode. + // you might need to customize the clock management for your application, + // see the datasheet for your particular Cortex-M MCU. + // + __WFI(); // Wait-For-Interrupt +#endif +} + +//============================================================================ +// QS callbacks... +#ifdef Q_SPY + +#ifdef QF_MEM_ISOLATE +// Shared QS filters... +__attribute__((aligned(32))) +QS_Filter QS_filt_; +#endif + +//............................................................................ +uint8_t QS_onStartup(void const *arg) { + Q_UNUSED_PAR(arg); + + static uint8_t qsTxBuf[2*1024]; // buffer for QS-TX channel + QS_initBuf(qsTxBuf, sizeof(qsTxBuf)); + + static uint8_t qsRxBuf[100]; // buffer for QS-RX channel + QS_rxInitBuf(qsRxBuf, sizeof(qsRxBuf)); + + // enable clock for UART0 and GPIOA (used by UART0 pins) + SYSCTL->RCGCUART |= (1U << 0U); // enable Run mode for UART0 + SYSCTL->RCGCGPIO |= (1U << 0U); // enable Run mode for GPIOA + + // configure UART0 pins for UART operation + uint32_t tmp = (1U << 0U) | (1U << 1U); + GPIOA->DIR &= ~tmp; + GPIOA->SLR &= ~tmp; + GPIOA->ODR &= ~tmp; + GPIOA->PUR &= ~tmp; + GPIOA->PDR &= ~tmp; + GPIOA->AMSEL &= ~tmp; // disable analog function on the pins + GPIOA->AFSEL |= tmp; // enable ALT function on the pins + GPIOA->DEN |= tmp; // enable digital I/O on the pins + GPIOA->PCTL &= ~0x00U; + GPIOA->PCTL |= 0x11U; + + // configure the UART for the desired baud rate, 8-N-1 operation + tmp = (((SystemCoreClock * 8U) / UART_BAUD_RATE) + 1U) / 2U; + UART0->IBRD = tmp / 64U; + UART0->FBRD = tmp % 64U; + UART0->LCRH = (0x3U << 5U); // configure 8-N-1 operation + UART0->LCRH |= (0x1U << 4U); // enable FIFOs + UART0->CTL = (1U << 0U) // UART enable + | (1U << 8U) // UART TX enable + | (1U << 9U); // UART RX enable + + // configure UART interrupts (for the RX channel) + UART0->IM |= (1U << 4U) | (1U << 6U); // enable RX and RX-TO interrupt + UART0->IFLS |= (0x2U << 2U); // interrupt on RX FIFO half-full + // NOTE: do not enable the UART0 interrupt yet. Wait till QF_onStartup() + + // configure TIMER5 to produce QS time stamp + SYSCTL->RCGCTIMER |= (1U << 5U); // enable run mode for Timer5 + TIMER5->CTL = 0U; // disable Timer1 output + TIMER5->CFG = 0x0U; // 32-bit configuration + TIMER5->TAMR = (1U << 4U) | 0x02U; // up-counting periodic mode + TIMER5->TAILR= 0xFFFFFFFFU; // timer interval + TIMER5->ICR = 0x1U; // TimerA timeout flag bit clears + TIMER5->CTL |= (1U << 0U); // enable TimerA module + + return 1U; // return success +} +//............................................................................ +void QS_onCleanup(void) { +} +//............................................................................ +QSTimeCtr QS_onGetTime(void) { // NOTE: invoked with interrupts DISABLED + return TIMER5->TAV; +} +//............................................................................ +void QS_onFlush(void) { + for (;;) { + QF_INT_DISABLE(); + QF_MEM_SYS(); + uint16_t b = QS_getByte(); + if (b != QS_EOD) { + while ((UART0->FR & UART_FR_TXFE) == 0U) { // while TXE not empty + QF_MEM_APP(); + QF_INT_ENABLE(); + QF_CRIT_EXIT_NOP(); + + QF_INT_DISABLE(); + QF_MEM_SYS(); + } + UART0->DR = b; // put into the DR register + QF_MEM_APP(); + QF_INT_ENABLE(); + } + else { + QF_MEM_APP(); + QF_INT_ENABLE(); + break; + } + } +} +//............................................................................ +//! callback function to reset the target (to be implemented in the BSP) +void QS_onReset(void) { + NVIC_SystemReset(); +} +//............................................................................ +//! callback function to execute a user command +void QS_onCommand(uint8_t cmdId, + uint32_t param1, uint32_t param2, uint32_t param3) +{ + Q_UNUSED_PAR(cmdId); + Q_UNUSED_PAR(param1); + Q_UNUSED_PAR(param2); + Q_UNUSED_PAR(param3); +} + +#endif // Q_SPY +//---------------------------------------------------------------------------- + +//============================================================================ +// NOTE1: +// The QF_AWARE_ISR_CMSIS_PRI constant from the QF port specifies the highest +// ISR priority that is disabled by the QF framework. The value is suitable +// for the NVIC_SetPriority() CMSIS function. +// +// Only ISRs prioritized at or below the QF_AWARE_ISR_CMSIS_PRI level (i.e., +// with the numerical values of priorities equal or higher than +// QF_AWARE_ISR_CMSIS_PRI) are allowed to call the QK_ISR_ENTRY/ +// QK_ISR_ENTRY macros or any other QF/QK services. These ISRs are +// "QF-aware". +// +// Conversely, any ISRs prioritized above the QF_AWARE_ISR_CMSIS_PRI priority +// level (i.e., with the numerical values of priorities less than +// QF_AWARE_ISR_CMSIS_PRI) are never disabled and are not aware of the kernel. +// Such "QF-unaware" ISRs cannot call ANY QF/QK services. In particular they +// can NOT call the macros QK_ISR_ENTRY/QK_ISR_ENTRY. The only mechanism +// by which a "QF-unaware" ISR can communicate with the QF framework is by +// triggering a "QF-aware" ISR, which can post/publish events. +// +// NOTE2: +// The User LED is used to visualize the idle loop activity. The brightness +// of the LED is proportional to the frequency of the idle loop. +// Please note that the LED is toggled with interrupts locked, so no interrupt +// execution time contributes to the brightness of the User LED. +// diff --git a/examples/arm-cm/dpp_ek-tm4c123gxl/qk/gnu_with-stack-prot/Makefile b/examples/arm-cm/dpp_ek-tm4c123gxl_mpu/qk/gnu/Makefile similarity index 92% rename from examples/arm-cm/dpp_ek-tm4c123gxl/qk/gnu_with-stack-prot/Makefile rename to examples/arm-cm/dpp_ek-tm4c123gxl_mpu/qk/gnu/Makefile index 284a109b..b1138c00 100644 --- a/examples/arm-cm/dpp_ek-tm4c123gxl/qk/gnu_with-stack-prot/Makefile +++ b/examples/arm-cm/dpp_ek-tm4c123gxl_mpu/qk/gnu/Makefile @@ -1,13 +1,13 @@ ############################################################################## # Product: Makefile for QP/C on EK-TM4C123GXL, QK kernel, GNU-ARM -# Last Updated for Version: 7.0.1 -# Date of the Last Update: 2022-05-23 +# Last Updated for Version: 7.3.0 +# Date of the Last Update: 2023-09-07 # # Q u a n t u m L e a P s # ------------------------ # Modern Embedded Software # -# Copyright (C) 2005-2021 Quantum Leaps, LLC. All rights reserved. +# Copyright (C) 2005 Quantum Leaps, LLC. # # This program is open source software: you can redistribute it and/or # modify it under the terms of the GNU General Public License as published @@ -45,8 +45,7 @@ # NOTE: # To use this Makefile on Windows, you will need the GNU make utility, which # is included in the Qtools collection for Windows, see: -# https://sourceforge.net/projects/qpc/files/QTools/ -# +# https://github.com/QuantumLeaps/qtools #----------------------------------------------------------------------------- # project name @@ -93,7 +92,7 @@ ASM_SRCS := # C source files C_SRCS := \ - bsp_stack-prot.c \ + bsp.c \ main.c \ philo.c \ table.c \ @@ -133,7 +132,9 @@ LIB_DIRS := LIBS := # defines -DEFINES := -DTARGET_IS_TM4C123_RB1 +DEFINES := \ + -DQP_CONFIG \ + -DTARGET_IS_TM4C123_RB1 # ARM CPU, ARCH, FPU, and Float-ABI types... # ARM_CPU: [cortex-m0 | cortex-m0plus | cortex-m1 | cortex-m3 | cortex-m4] @@ -163,12 +164,11 @@ AS := $(GNU_ARM)/bin/arm-none-eabi-as LINK := $(GNU_ARM)/bin/arm-none-eabi-gcc BIN := $(GNU_ARM)/bin/arm-none-eabi-objcopy - ############################################################################## -# Typically, you should not need to change anything below this line +# Typically you should not need to change anything below this line -# basic utilities (included in Qtools for Windows), see: -# http://sourceforge.net/projects/qpc/files/Qtools +# basic utilities (included in QTools for Windows), see: +# https://www.state-machine.com/qtools MKDIR := mkdir RM := rm @@ -189,11 +189,11 @@ ASFLAGS = $(ARM_CPU) $(ARM_FPU) $(ASM_CPU) $(ASM_FPU) CFLAGS = -c $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \ -ffunction-sections -fdata-sections \ - -O1 $(INCLUDES) $(DEFINES) -DNDEBUG + -O2 $(INCLUDES) $(DEFINES) -DNDEBUG CPPFLAGS = -c $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \ -ffunction-sections -fdata-sections -fno-rtti -fno-exceptions \ - -O1 $(INCLUDES) $(DEFINES) -DNDEBUG + -O2 $(INCLUDES) $(DEFINES) -DNDEBUG else ifeq (spy, $(CONF)) # Spy configuration ................................ @@ -254,14 +254,20 @@ endif # rules # -all: $(TARGET_BIN) -#all: $(TARGET_ELF) +.PHONY : run norun flash clean show + +ifeq ($(MAKECMDGOALS),norun) +all : $(TARGET_BIN) +norun : all +else +all : $(TARGET_BIN) run +endif $(TARGET_BIN): $(TARGET_ELF) $(BIN) -O binary $< $@ $(TARGET_ELF) : $(ASM_OBJS_EXT) $(C_OBJS_EXT) $(CPP_OBJS_EXT) - $(CC) $(CFLAGS) $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o + $(CC) $(CFLAGS) $(QPC)/src/qs/qstamp.c -o $(BIN_DIR)/qstamp.o $(LINK) $(LINKFLAGS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) $(BIN_DIR)/%.d : %.c @@ -287,7 +293,6 @@ ifneq ($(MAKECMDGOALS),clean) endif -.PHONY : clean clean: -$(RM) $(BIN_DIR)/*.o \ $(BIN_DIR)/*.d \ diff --git a/examples/arm-cm/dpp_ek-tm4c123gxl/qk/gnu_with-stack-prot/dpp-qk.ld b/examples/arm-cm/dpp_ek-tm4c123gxl_mpu/qk/gnu/dpp-qk.ld similarity index 100% rename from examples/arm-cm/dpp_ek-tm4c123gxl/qk/gnu_with-stack-prot/dpp-qk.ld rename to examples/arm-cm/dpp_ek-tm4c123gxl_mpu/qk/gnu/dpp-qk.ld diff --git a/examples/arm-cm/dpp_ek-tm4c123gxl/qk/gnu_with-stack-prot/flash.bat b/examples/arm-cm/dpp_ek-tm4c123gxl_mpu/qk/gnu/flash.bat similarity index 100% rename from examples/arm-cm/dpp_ek-tm4c123gxl/qk/gnu_with-stack-prot/flash.bat rename to examples/arm-cm/dpp_ek-tm4c123gxl_mpu/qk/gnu/flash.bat diff --git a/examples/arm-cm/dpp_ek-tm4c123gxl_mpu/qk/iar/dpp-qk.ewd b/examples/arm-cm/dpp_ek-tm4c123gxl_mpu/qk/iar/dpp-qk.ewd new file mode 100644 index 00000000..69698eab --- /dev/null +++ b/examples/arm-cm/dpp_ek-tm4c123gxl_mpu/qk/iar/dpp-qk.ewd @@ -0,0 +1,4654 @@ + + + 3 + + Debug + + ARM + + 1 + + C-SPY + 2 + + 32 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ARMSIM_ID + 2 + + 1 + 1 + 1 + + + + + + + + CADI_ID + 2 + + 0 + 1 + 1 + + + + + + + + + CMSISDAP_ID + 2 + + 4 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + GDBSERVER_ID + 2 + + 0 + 1 + 1 + + + + + + + + + + + IJET_ID + 2 + + 9 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + JLINK_ID + 2 + + 16 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + LMIFTDI_ID + 2 + + 3 + 1 + 1 + + + + + + + + + + + + + NULINK_ID + 2 + + 0 + 1 + 1 + + + + + + + PEMICRO_ID + 2 + + 3 + 1 + 1 + + + + + + + + STLINK_ID + 2 + + 8 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + THIRDPARTY_ID + 2 + + 0 + 1 + 1 + + + + + + + + TIFET_ID + 2 + + 1 + 1 + 1 + + + + + + + + + + + + + + + + + + + XDS100_ID + 2 + + 9 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + $TOOLKIT_DIR$\plugins\rtos\CMX\CmxArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\CMX\CmxTinyArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\FreeRtos\FreeRtosArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin2.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SafeRTOS\SafeRTOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9BE.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-286-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-III\uCOS-III-KA-CSpy.ewplugin + 0 + + + $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\TargetAccessServer\TargetAccessServer.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\uCProbe\uCProbePlugin.ENU.ewplugin + 0 + + + + + Release + + ARM + + 0 + + C-SPY + 2 + + 32 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ARMSIM_ID + 2 + + 1 + 1 + 0 + + + + + + + + CADI_ID + 2 + + 0 + 1 + 0 + + + + + + + + + CMSISDAP_ID + 2 + + 4 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + GDBSERVER_ID + 2 + + 0 + 1 + 0 + + + + + + + + + + + IJET_ID + 2 + + 9 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + JLINK_ID + 2 + + 16 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + LMIFTDI_ID + 2 + + 3 + 1 + 0 + + + + + + + + + + + + + NULINK_ID + 2 + + 0 + 1 + 0 + + + + + + + PEMICRO_ID + 2 + + 3 + 1 + 0 + + + + + + + + STLINK_ID + 2 + + 8 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + THIRDPARTY_ID + 2 + + 0 + 1 + 0 + + + + + + + + TIFET_ID + 2 + + 1 + 1 + 0 + + + + + + + + + + + + + + + + + + + XDS100_ID + 2 + + 9 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + $TOOLKIT_DIR$\plugins\rtos\CMX\CmxArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\CMX\CmxTinyArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\FreeRtos\FreeRtosArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin2.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SafeRTOS\SafeRTOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9BE.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-286-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-III\uCOS-III-KA-CSpy.ewplugin + 0 + + + $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\TargetAccessServer\TargetAccessServer.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\uCProbe\uCProbePlugin.ENU.ewplugin + 0 + + + + + Spy + + ARM + + 1 + + C-SPY + 2 + + 32 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ARMSIM_ID + 2 + + 1 + 1 + 1 + + + + + + + + CADI_ID + 2 + + 0 + 1 + 1 + + + + + + + + + CMSISDAP_ID + 2 + + 4 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + GDBSERVER_ID + 2 + + 0 + 1 + 1 + + + + + + + + + + + IJET_ID + 2 + + 9 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + JLINK_ID + 2 + + 16 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + LMIFTDI_ID + 2 + + 3 + 1 + 1 + + + + + + + + + + + + + NULINK_ID + 2 + + 0 + 1 + 1 + + + + + + + PEMICRO_ID + 2 + + 3 + 1 + 1 + + + + + + + + STLINK_ID + 2 + + 8 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + THIRDPARTY_ID + 2 + + 0 + 1 + 1 + + + + + + + + TIFET_ID + 2 + + 1 + 1 + 1 + + + + + + + + + + + + + + + + + + + XDS100_ID + 2 + + 9 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + $TOOLKIT_DIR$\plugins\rtos\CMX\CmxArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\CMX\CmxTinyArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\FreeRtos\FreeRtosArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin2.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SafeRTOS\SafeRTOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9BE.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-286-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-III\uCOS-III-KA-CSpy.ewplugin + 0 + + + $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\TargetAccessServer\TargetAccessServer.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\uCProbe\uCProbePlugin.ENU.ewplugin + 0 + + + + diff --git a/examples/arm-cm/dpp_ek-tm4c123gxl_mpu/qk/iar/dpp-qk.ewp b/examples/arm-cm/dpp_ek-tm4c123gxl_mpu/qk/iar/dpp-qk.ewp new file mode 100644 index 00000000..b0d200dd --- /dev/null +++ b/examples/arm-cm/dpp_ek-tm4c123gxl_mpu/qk/iar/dpp-qk.ewp @@ -0,0 +1,3367 @@ + + + 3 + + Debug + + ARM + + 1 + + General + 3 + + 35 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ICCARM + 2 + + 37 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + AARM + 2 + + 11 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + OBJCOPY + 0 + + 1 + 1 + 1 + + + + + + + + + CUSTOM + 3 + + + + 0 + inputOutputBased + + + + BUILDACTION + 1 + + cmd /c "if exist $OBJ_DIR$\qstamp.o del $OBJ_DIR$\qstamp.o" + + + + + ILINK + 0 + + 27 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + IARCHIVE + 0 + + 0 + 1 + 1 + + + + + + + Coder + 0 + + + + + Release + + ARM + + 0 + + General + 3 + + 35 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ICCARM + 2 + + 37 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + AARM + 2 + + 11 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + OBJCOPY + 0 + + 1 + 1 + 0 + + + + + + + + + CUSTOM + 3 + + + + 0 + inputOutputBased + + + + BUILDACTION + 1 + + cmd /c "if exist $OBJ_DIR$\qstamp.o del $OBJ_DIR$\qstamp.o" + + + + + ILINK + 0 + + 27 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + IARCHIVE + 0 + + 0 + 1 + 0 + + + + + + + Coder + 0 + + + + + Spy + + ARM + + 1 + + General + 3 + + 35 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ICCARM + 2 + + 37 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + AARM + 2 + + 11 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + OBJCOPY + 0 + + 1 + 1 + 1 + + + + + + + + + CUSTOM + 3 + + + + 0 + inputOutputBased + + + + BUILDACTION + 1 + + cmd /c "if exist $OBJ_DIR$\qstamp.o del $OBJ_DIR$\qstamp.o" + + + + + ILINK + 0 + + 27 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + IARCHIVE + 0 + + 0 + 1 + 1 + + + + + + + Coder + 0 + + + + + Application + + $PROJ_DIR$\..\bsp.c + + + $PROJ_DIR$\..\..\bsp.h + + + $PROJ_DIR$\..\..\dpp.h + + + $PROJ_DIR$\..\..\main.c + + + $PROJ_DIR$\..\..\philo.c + + + $PROJ_DIR$\..\..\table.c + + + + ek-tm4c123gxl + + $PROJ_DIR$\..\..\..\..\..\3rd_party\ek-tm4c123gxl\iar\startup_TM4C123GH6PM.s + + + $PROJ_DIR$\..\..\..\..\..\3rd_party\ek-tm4c123gxl\system_TM4C123GH6PM.c + + + $PROJ_DIR$\..\..\..\..\..\3rd_party\ek-tm4c123gxl\system_TM4C123GH6PM.h + + + $PROJ_DIR$\..\..\..\..\..\3rd_party\ek-tm4c123gxl\TM4C123GH6PM.h + + + + QP + + $PROJ_DIR$\..\..\..\..\..\src\qf\qep_hsm.c + + + $PROJ_DIR$\..\..\..\..\..\src\qf\qep_msm.c + + + $PROJ_DIR$\..\..\..\..\..\src\qf\qf_act.c + + + $PROJ_DIR$\..\..\..\..\..\src\qf\qf_actq.c + + + $PROJ_DIR$\..\..\..\..\..\src\qf\qf_defer.c + + + $PROJ_DIR$\..\..\..\..\..\src\qf\qf_dyn.c + + + $PROJ_DIR$\..\..\..\..\..\src\qf\qf_mem.c + + + $PROJ_DIR$\..\..\..\..\..\src\qf_pkg.h + + + $PROJ_DIR$\..\..\..\..\..\src\qf\qf_ps.c + + + $PROJ_DIR$\..\..\..\..\..\src\qf\qf_qact.c + + + $PROJ_DIR$\..\..\..\..\..\src\qf\qf_qeq.c + + + $PROJ_DIR$\..\..\..\..\..\src\qf\qf_qmact.c + + + $PROJ_DIR$\..\..\..\..\..\src\qf\qf_time.c + + + $PROJ_DIR$\..\..\..\..\..\src\qk\qk.c + + + $PROJ_DIR$\..\..\..\..\..\src\qk_pkg.h + + + + QP_port + + $PROJ_DIR$\..\..\..\..\..\ports\arm-cm\qk\iar\qep_port.h + + + $PROJ_DIR$\..\..\..\..\..\ports\arm-cm\qk\iar\qf_port.h + + + $PROJ_DIR$\..\..\..\..\..\ports\arm-cm\qk\iar\qk_port.c + + + $PROJ_DIR$\..\..\..\..\..\ports\arm-cm\qk\iar\qk_port.h + + + $PROJ_DIR$\..\..\..\..\..\ports\arm-cm\qk\iar\qs_port.h + + + + QS + + Debug + Release + + + $PROJ_DIR$\..\..\..\..\..\src\qs\qs.c + + + $PROJ_DIR$\..\..\..\..\..\src\qs\qs_fp.c + + + $PROJ_DIR$\..\..\..\..\..\src\qs\qs_rx.c + + + $PROJ_DIR$\..\..\..\..\..\src\qs\qstamp.c + + + diff --git a/examples/arm-cm/dpp_ek-tm4c123gxl_mpu/qk/iar/dpp-qk.eww b/examples/arm-cm/dpp_ek-tm4c123gxl_mpu/qk/iar/dpp-qk.eww new file mode 100644 index 00000000..c261124a --- /dev/null +++ b/examples/arm-cm/dpp_ek-tm4c123gxl_mpu/qk/iar/dpp-qk.eww @@ -0,0 +1,10 @@ + + + + + $WS_DIR$\dpp-qk.ewp + + + + + diff --git a/examples/arm-cm/blinky_efm32-slstk3401a/qv/iar/blinky-qv.icf b/examples/arm-cm/dpp_ek-tm4c123gxl_mpu/qk/iar/dpp-qk.icf similarity index 91% rename from examples/arm-cm/blinky_efm32-slstk3401a/qv/iar/blinky-qv.icf rename to examples/arm-cm/dpp_ek-tm4c123gxl_mpu/qk/iar/dpp-qk.icf index da0bc053..c6b24e1c 100644 --- a/examples/arm-cm/blinky_efm32-slstk3401a/qv/iar/blinky-qv.icf +++ b/examples/arm-cm/dpp_ek-tm4c123gxl_mpu/qk/iar/dpp-qk.icf @@ -9,7 +9,7 @@ define symbol __ICFEDIT_region_ROM_end__ = 0x0003FFFF; define symbol __ICFEDIT_region_RAM_start__ = 0x20000000; define symbol __ICFEDIT_region_RAM_end__ = 0x20007FFF; /*-Sizes-*/ -define symbol __ICFEDIT_size_cstack__ = 512; +define symbol __ICFEDIT_size_cstack__ = 2048; define symbol __ICFEDIT_size_heap__ = 0; /**** End of ICF editor section. ###ICF###*/ @@ -25,5 +25,5 @@ do not initialize { section .noinit }; place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec }; place in ROM_region { readonly }; -place at start of RAM_region {block CSTACK }; +place at start of RAM_region {block CSTACK }; /* <== Quantum Leaps */ place in RAM_region { readwrite, block HEAP }; \ No newline at end of file diff --git a/examples/arm-cm/dpp_ek-tm4c123gxl_mpu/qp_config.h b/examples/arm-cm/dpp_ek-tm4c123gxl_mpu/qp_config.h new file mode 100644 index 00000000..ed29444d --- /dev/null +++ b/examples/arm-cm/dpp_ek-tm4c123gxl_mpu/qp_config.h @@ -0,0 +1,57 @@ +//============================================================================ +// QP configuration file example +// Last updated for version: 7.3.0 +// Last updated on: 2023-09-09 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +//============================================================================ +#ifndef QP_CONFIG_H_ +#define QP_CONFIG_H_ + +// NOTE: +// The QP configuration takes effect only when the macro QP_CONFIG +// is defined on the command-line to the compiler for all QP source files. + +// use memory isolation (MPU) +#define QF_MEM_ISOLATE + +// use event constructors for dynamic events +//#define QEVT_DYN_CTOR + +// for QK kernel: +// use the QEI1_IRQHandler() with IRQ number 38 +// for the QK return-from-preemption handler +#define QK_USE_IRQ_NUM 38 +#define QK_USE_IRQ_HANDLER QEI1_IRQHandler + +// for QXK kernel: +// use the QEI1_IRQHandler() with IRQ number 38 +// for the QXK return-from-preemption handler +#define QXK_USE_IRQ_NUM 38 +#define QXK_USE_IRQ_HANDLER QEI1_IRQHandler + +#endif // QP_CONFIG_H_ diff --git a/examples/arm-cm/dpp_ek-tm4c123gxl_mpu/qv/armclang/dpp-qv.sct b/examples/arm-cm/dpp_ek-tm4c123gxl_mpu/qv/armclang/dpp-qv.sct new file mode 100644 index 00000000..458d5506 --- /dev/null +++ b/examples/arm-cm/dpp_ek-tm4c123gxl_mpu/qv/armclang/dpp-qv.sct @@ -0,0 +1,23 @@ +; ************************************************************* +; *** Scatter-Loading Description File generated by uVision *** +; +; Adapted by Quantum Leaps: +; added STACK as the first section in RW_STACK +; ************************************************************* + +LR_IROM1 0x00000000 0x00040000 { ; load region size_region + ER_IROM1 0x00000000 0x00040000 { ; load address = execution address + *.o (RESET, +First) + *(InRoot$$Sections) + .ANY (+RO) + .ANY (+XO) + } + + RW_STACK 0x20000000 { ; <== Quantum Leaps + * (STACK, +First) + } + RW_IRAM1 +0 (0x00008000 - 2048) { ; NOTE: assume STACK size 2048! + .ANY (+RW +ZI) + } +} + diff --git a/examples/arm-cm/dpp_ek-tm4c123gxl_mpu/qv/armclang/dpp-qv.uvoptx b/examples/arm-cm/dpp_ek-tm4c123gxl_mpu/qv/armclang/dpp-qv.uvoptx new file mode 100644 index 00000000..1d389446 --- /dev/null +++ b/examples/arm-cm/dpp_ek-tm4c123gxl_mpu/qv/armclang/dpp-qv.uvoptx @@ -0,0 +1,1059 @@ + + + + 1.0 + +
### uVision Project, (C) Keil Software
+ + + *.c + *.s*; *.src; *.a* + *.obj; *.o + *.lib + *.txt; *.h; *.inc; *.md + *.plm + *.cpp + 0 + + + + 0 + 0 + + + + dpp-dbg + 0x4 + ARM-ADS + + 12000000 + + 1 + 1 + 1 + 0 + 0 + + + 1 + 65535 + 0 + 0 + 0 + + + 79 + 66 + 8 + .\dbg\ + + + 1 + 1 + 1 + 0 + 1 + 1 + 0 + 1 + 0 + 0 + 0 + 0 + + + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + + + 1 + 0 + 1 + + 4 + + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + 1 + 1 + 0 + 1 + 0 + 1 + 1 + 0 + 0 + 1 + 0 + 0 + 19 + + + + + + + + + + + BIN\lmidk-agdi.dll + + + + 0 + ARMRTXEVENTFLAGS + -L70 -Z18 -C0 -M0 -T1 + + + 0 + UL2CM3 + UL2CM3(-O207 -S0 -C0 -FO7 -FN1 -FC1000 -FD20000000 -FF0TM4C123_256 -FL040000 -FS00 -FP0($$Device:TM4C123GH6PM$Flash\TM4C123_256.FLM) + + + 0 + DLGTARM + (1010=-1,-1,-1,-1,0)(1007=-1,-1,-1,-1,0)(1008=-1,-1,-1,-1,0)(1009=-1,-1,-1,-1,0)(1012=-1,-1,-1,-1,0) + + + 0 + ARMDBGFLAGS + + + + 0 + lmidk-agdi + -U0E2006F4 -O4622 -S4 -FO61 + + + + + 0 + 0 + 319 + 1 +
1112
+ 0 + 0 + 0 + 0 + 0 + 1 + ..\..\..\..\..\3rd_party\ek-tm4c123gxl\arm\startup_TM4C123GH6PM.s + + \\dpp_qv\../../../../../3rd_party/ek-tm4c123gxl/arm/startup_TM4C123GH6PM.s\319 +
+
+ + + 1 + 8 + 0x466 + 0 + + + + + 2 + 0 + 0x400 + 0 + + + + 0 + + + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + + + + 0 + 0 + 0 + + + + + + + + +
+
+ + + dpp-rel + 0x4 + ARM-ADS + + 12000000 + + 1 + 1 + 1 + 0 + 0 + + + 1 + 65535 + 0 + 0 + 0 + + + 79 + 66 + 8 + .\rel\ + + + 1 + 1 + 1 + 0 + 1 + 1 + 0 + 1 + 0 + 0 + 0 + 0 + + + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + + + 1 + 0 + 0 + + 4 + + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + 1 + 1 + 0 + 1 + 0 + 1 + 1 + 0 + 0 + 1 + 0 + 0 + 19 + + + + + + + + + + + BIN\lmidk-agdi.dll + + + + 0 + DLGUARM + + + 0 + ARMRTXEVENTFLAGS + -L70 -Z18 -C0 -M0 -T1 + + + 0 + DLGTARM + (1010=-1,-1,-1,-1,0)(1007=-1,-1,-1,-1,0)(1008=-1,-1,-1,-1,0)(1009=-1,-1,-1,-1,0)(1012=-1,-1,-1,-1,0) + + + 0 + ARMDBGFLAGS + + + + 0 + lmidk-agdi + -U0E10259B -O4622 -S4 -FO61 + + + 0 + UL2CM3 + -O207 -S0 -C0 -FO7 -FN1 -FC1000 -FD20000000 -FF0TM4C123_256 -FL040000 -FS00 -FP0($$Device:TM4C123GH6PM$Flash\TM4C123_256.FLM) + + + + + 0 + 0 + 319 + 1 +
1112
+ 0 + 0 + 0 + 0 + 0 + 1 + ..\..\..\..\..\3rd_party\ek-tm4c123gxl\arm\startup_TM4C123GH6PM.s + + \\dpp_qv\../../../../../3rd_party/ek-tm4c123gxl/arm/startup_TM4C123GH6PM.s\319 +
+
+ + + 1 + 2 + 0x20000200 + 0 + + + + + 2 + 0 + 0x400 + 0 + + + + 0 + + + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + + + + 0 + 0 + 0 + + + + + + + + +
+
+ + + dpp-spy + 0x4 + ARM-ADS + + 12000000 + + 1 + 1 + 1 + 0 + 0 + + + 1 + 65535 + 0 + 0 + 0 + + + 79 + 66 + 8 + .\spy\ + + + 1 + 1 + 1 + 0 + 1 + 1 + 0 + 1 + 0 + 0 + 0 + 0 + + + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + + + 1 + 0 + 0 + + 4 + + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + 1 + 1 + 0 + 1 + 0 + 1 + 1 + 0 + 0 + 1 + 0 + 0 + 19 + + + + + + + + + + + BIN\lmidk-agdi.dll + + + + 0 + DLGUARM + + + 0 + ARMRTXEVENTFLAGS + -L70 -Z18 -C0 -M0 -T1 + + + 0 + UL2CM3 + UL2CM3(-O207 -S0 -C0 -FO7 -FN1 -FC1000 -FD20000000 -FF0TM4C123_256 -FL040000 -FS00 -FP0($$Device:TM4C123GH6PM$Flash\TM4C123_256.FLM) + + + 0 + DLGTARM + (1010=-1,-1,-1,-1,0)(1007=-1,-1,-1,-1,0)(1008=-1,-1,-1,-1,0)(1009=-1,-1,-1,-1,0)(1012=2417,256,2894,571,1) + + + 0 + ARMDBGFLAGS + + + + 0 + lmidk-agdi + -U0E2006F4 -O4622 -S4 -FO61 + + + + + 0 + 0 + 319 + 1 +
1112
+ 0 + 0 + 0 + 0 + 0 + 1 + ..\..\..\..\..\3rd_party\ek-tm4c123gxl\arm\startup_TM4C123GH6PM.s + + \\dpp_qv\../../../../../3rd_party/ek-tm4c123gxl/arm/startup_TM4C123GH6PM.s\319 +
+
+ + + 1 + 2 + 0x20000748 + 0 + + + + + 2 + 0 + 0x400 + 0 + + + + 0 + + + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + + + + 0 + 0 + 0 + + + + + + + + +
+
+ + + Applicatioin + 1 + 0 + 0 + 0 + + 1 + 1 + 1 + 0 + 0 + 0 + ..\bsp.c + bsp.c + 0 + 0 + + + 1 + 2 + 5 + 0 + 0 + 0 + ..\..\dpp.h + dpp.h + 0 + 0 + + + 1 + 3 + 5 + 0 + 0 + 0 + ..\..\bsp.h + bsp.h + 0 + 0 + + + 1 + 4 + 1 + 0 + 0 + 0 + ..\..\philo.c + philo.c + 0 + 0 + + + 1 + 5 + 1 + 0 + 0 + 0 + ..\..\table.c + table.c + 0 + 0 + + + 1 + 6 + 1 + 0 + 0 + 0 + ..\..\main.c + main.c + 0 + 0 + + + + + ek-tm4c123gxl + 1 + 0 + 0 + 0 + + 2 + 7 + 1 + 0 + 0 + 0 + ..\..\..\..\..\3rd_party\ek-tm4c123gxl\system_TM4C123GH6PM.c + system_TM4C123GH6PM.c + 0 + 0 + + + 2 + 8 + 5 + 0 + 0 + 0 + ..\..\..\..\..\3rd_party\ek-tm4c123gxl\TM4C123GH6PM.h + TM4C123GH6PM.h + 0 + 0 + + + 2 + 9 + 2 + 0 + 0 + 0 + ..\..\..\..\..\3rd_party\ek-tm4c123gxl\arm\startup_TM4C123GH6PM.s + startup_TM4C123GH6PM.s + 0 + 0 + + + 2 + 10 + 5 + 0 + 0 + 0 + ..\..\..\..\..\3rd_party\ek-tm4c123gxl\gpio.h + gpio.h + 0 + 0 + + + 2 + 11 + 5 + 0 + 0 + 0 + ..\..\..\..\..\3rd_party\ek-tm4c123gxl\rom.h + rom.h + 0 + 0 + + + 2 + 12 + 5 + 0 + 0 + 0 + ..\..\..\..\..\3rd_party\ek-tm4c123gxl\sysctl.h + sysctl.h + 0 + 0 + + + 2 + 13 + 5 + 0 + 0 + 0 + ..\..\..\..\..\3rd_party\ek-tm4c123gxl\system_TM4C123GH6PM.h + system_TM4C123GH6PM.h + 0 + 0 + + + + + QP + 1 + 0 + 0 + 0 + + 3 + 14 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qf\qep_hsm.c + qep_hsm.c + 0 + 0 + + + 3 + 15 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qf\qep_msm.c + qep_msm.c + 0 + 0 + + + 3 + 16 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qf\qf_act.c + qf_act.c + 0 + 0 + + + 3 + 17 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qf\qf_actq.c + qf_actq.c + 0 + 0 + + + 3 + 18 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qf\qf_defer.c + qf_defer.c + 0 + 0 + + + 3 + 19 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qf\qf_dyn.c + qf_dyn.c + 0 + 0 + + + 3 + 20 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qf\qf_mem.c + qf_mem.c + 0 + 0 + + + 3 + 21 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qf\qf_ps.c + qf_ps.c + 0 + 0 + + + 3 + 22 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qf\qf_qact.c + qf_qact.c + 0 + 0 + + + 3 + 23 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qf\qf_qeq.c + qf_qeq.c + 0 + 0 + + + 3 + 24 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qf\qf_qmact.c + qf_qmact.c + 0 + 0 + + + 3 + 25 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qf\qf_time.c + qf_time.c + 0 + 0 + + + 3 + 26 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qv\qv.c + qv.c + 0 + 0 + + + + + QP_port + 1 + 0 + 0 + 0 + + 4 + 27 + 1 + 0 + 0 + 0 + ..\..\..\..\..\ports\arm-cm\qv\armclang\qv_port.c + qv_port.c + 0 + 0 + + + + + QS + 1 + 0 + 0 + 0 + + 5 + 28 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qs\qs.c + qs.c + 0 + 0 + + + 5 + 29 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qs\qs_64bit.c + qs_64bit.c + 0 + 0 + + + 5 + 30 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qs\qs_fp.c + qs_fp.c + 0 + 0 + + + 5 + 31 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qs\qs_rx.c + qs_rx.c + 0 + 0 + + + 5 + 32 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qs\qstamp.c + qstamp.c + 0 + 0 + + + +
diff --git a/examples/arm-cm/dpp_ek-tm4c123gxl_mpu/qv/armclang/dpp-qv.uvprojx b/examples/arm-cm/dpp_ek-tm4c123gxl_mpu/qv/armclang/dpp-qv.uvprojx new file mode 100644 index 00000000..74ee7900 --- /dev/null +++ b/examples/arm-cm/dpp_ek-tm4c123gxl_mpu/qv/armclang/dpp-qv.uvprojx @@ -0,0 +1,1838 @@ + + + + 2.1 + +
### uVision Project, (C) Keil Software
+ + + + dpp-dbg + 0x4 + ARM-ADS + 6160000::V6.16::ARMCLANG + 1 + + + TM4C123GH6PM + Texas Instruments + Keil.TM4C_DFP.1.1.0 + http://www.keil.com/pack/ + IROM(0x00000000,0x040000) IRAM(0x20000000,0x008000) CPUTYPE("Cortex-M4") FPU2 CLOCK(12000000) ELITTLE + + + UL2CM3(-S0 -C0 -P0 -FD20000000 -FC1000 -FN1 -FF0TM4C123_256 -FS00 -FL040000 -FP0($$Device:TM4C123GH6PM$Flash\TM4C123_256.FLM)) + 0 + $$Device:TM4C123GH6PM$Device\Include\TM4C123\TM4C123.h + + + + + + + + + + $$Device:TM4C123GH6PM$SVD\TM4C123\TM4C123GH6PM.svd + 0 + 0 + + + + + + + 0 + 0 + 0 + 0 + 1 + + .\dbg\ + dpp-qv + 1 + 0 + 0 + 1 + 1 + .\dbg\ + 1 + 0 + 0 + + 0 + 0 + + + 0 + 0 + 0 + 0 + + + 1 + 0 + cmd /c "del .\dbg\qstamp.o" + + 0 + 0 + 0 + 0 + + + 1 + 0 + fromelf --bin --output .\dbg\dpp-qv.bin .\dbg\dpp-qv.axf + + 0 + 0 + 0 + 0 + + 1 + + + + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 3 + + + 1 + + + SARMCM3.DLL + -MPU + DCM.DLL + -pCM4 + SARMCM3.DLL + -MPU + TCM.DLL + -pCM4 + + + + 1 + 0 + 0 + 0 + 16 + + + + + 1 + 0 + 0 + 1 + 1 + 4097 + + 1 + BIN\UL2CM3.DLL + + + + + + 0 + + + + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + 1 + 0 + 0 + 0 + 0 + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + "Cortex-M4" + + 0 + 0 + 0 + 1 + 1 + 0 + 0 + 2 + 0 + 0 + 0 + 0 + 8 + 0 + 0 + 0 + 0 + 3 + 3 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 1 + 0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x20000000 + 0x8000 + + + 1 + 0x0 + 0x40000 + + + 0 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x40000 + + + 1 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x20000000 + 0x8000 + + + 0 + 0x0 + 0x0 + + + + + + 0 + 7 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 3 + 0 + 1 + 0 + 0 + 0 + 3 + 3 + 0 + 0 + 0 + 0 + 0 + + + QP_CONFIG + + ..\..;..\..\..\..\..\include;..\..\..\..\..\ports\arm-cm\qv\armclang;..\..\..\..\..\3rd_party\CMSIS\Include;..\..\..\..\..\3rd_party\ek-tm4c123gxl + + + + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 4 + + + Stack_Size=2048 Heap_Size=16 + + + + + + 0 + 0 + 0 + 0 + 1 + 0 + 0x00000000 + 0x20000000 + + .\dpp-qv.sct + + + --entry Reset_Handler + + + + + + + + Applicatioin + + + bsp.c + 1 + ..\bsp.c + + + dpp.h + 5 + ..\..\dpp.h + + + bsp.h + 5 + ..\..\bsp.h + + + philo.c + 1 + ..\..\philo.c + + + table.c + 1 + ..\..\table.c + + + main.c + 1 + ..\..\main.c + + + + + ek-tm4c123gxl + + + system_TM4C123GH6PM.c + 1 + ..\..\..\..\..\3rd_party\ek-tm4c123gxl\system_TM4C123GH6PM.c + + + TM4C123GH6PM.h + 5 + ..\..\..\..\..\3rd_party\ek-tm4c123gxl\TM4C123GH6PM.h + + + startup_TM4C123GH6PM.s + 2 + ..\..\..\..\..\3rd_party\ek-tm4c123gxl\arm\startup_TM4C123GH6PM.s + + + gpio.h + 5 + ..\..\..\..\..\3rd_party\ek-tm4c123gxl\gpio.h + + + rom.h + 5 + ..\..\..\..\..\3rd_party\ek-tm4c123gxl\rom.h + + + sysctl.h + 5 + ..\..\..\..\..\3rd_party\ek-tm4c123gxl\sysctl.h + + + system_TM4C123GH6PM.h + 5 + ..\..\..\..\..\3rd_party\ek-tm4c123gxl\system_TM4C123GH6PM.h + + + + + QP + + + qep_hsm.c + 1 + ..\..\..\..\..\src\qf\qep_hsm.c + + + qep_msm.c + 1 + ..\..\..\..\..\src\qf\qep_msm.c + + + qf_act.c + 1 + ..\..\..\..\..\src\qf\qf_act.c + + + qf_actq.c + 1 + ..\..\..\..\..\src\qf\qf_actq.c + + + qf_defer.c + 1 + ..\..\..\..\..\src\qf\qf_defer.c + + + qf_dyn.c + 1 + ..\..\..\..\..\src\qf\qf_dyn.c + + + qf_mem.c + 1 + ..\..\..\..\..\src\qf\qf_mem.c + + + qf_ps.c + 1 + ..\..\..\..\..\src\qf\qf_ps.c + + + qf_qact.c + 1 + ..\..\..\..\..\src\qf\qf_qact.c + + + qf_qeq.c + 1 + ..\..\..\..\..\src\qf\qf_qeq.c + + + qf_qmact.c + 1 + ..\..\..\..\..\src\qf\qf_qmact.c + + + qf_time.c + 1 + ..\..\..\..\..\src\qf\qf_time.c + + + qv.c + 1 + ..\..\..\..\..\src\qv\qv.c + + + + + QP_port + + + qv_port.c + 1 + ..\..\..\..\..\ports\arm-cm\qv\armclang\qv_port.c + + + + + QS + + + 0 + 0 + 0 + 0 + 0 + 0 + 2 + 2 + 2 + 2 + 11 + + + 1 + + + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 0 + 0 + 0 + 0 + 2 + + + + + + + + + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + + + + + + + + + + + + qs.c + 1 + ..\..\..\..\..\src\qs\qs.c + + + qs_64bit.c + 1 + ..\..\..\..\..\src\qs\qs_64bit.c + + + qs_fp.c + 1 + ..\..\..\..\..\src\qs\qs_fp.c + + + qs_rx.c + 1 + ..\..\..\..\..\src\qs\qs_rx.c + + + qstamp.c + 1 + ..\..\..\..\..\src\qs\qstamp.c + + + + + + + dpp-rel + 0x4 + ARM-ADS + 6160000::V6.16::ARMCLANG + 1 + + + TM4C123GH6PM + Texas Instruments + Keil.TM4C_DFP.1.1.0 + http://www.keil.com/pack/ + IROM(0x00000000,0x040000) IRAM(0x20000000,0x008000) CPUTYPE("Cortex-M4") FPU2 CLOCK(12000000) ELITTLE + + + UL2CM3(-S0 -C0 -P0 -FD20000000 -FC1000 -FN1 -FF0TM4C123_256 -FS00 -FL040000 -FP0($$Device:TM4C123GH6PM$Flash\TM4C123_256.FLM)) + 0 + $$Device:TM4C123GH6PM$Device\Include\TM4C123\TM4C123.h + + + + + + + + + + $$Device:TM4C123GH6PM$SVD\TM4C123\TM4C123GH6PM.svd + 0 + 0 + + + + + + + 0 + 0 + 0 + 0 + 1 + + .\rel\ + dpp-qv + 1 + 0 + 0 + 1 + 0 + .\rel\ + 1 + 0 + 0 + + 0 + 0 + + + 0 + 0 + 0 + 0 + + + 1 + 0 + cmd /c "del .\rel\qstamp.o" + + 0 + 0 + 0 + 0 + + + 1 + 0 + fromelf --bin --output .\rel\dpp-qv.bin .\rel\dpp-qv.axf + + 0 + 0 + 0 + 0 + + 1 + + + + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 3 + + + 1 + + + SARMCM3.DLL + -MPU + DCM.DLL + -pCM4 + SARMCM3.DLL + -MPU + TCM.DLL + -pCM4 + + + + 1 + 0 + 0 + 0 + 16 + + + + + 1 + 0 + 0 + 1 + 1 + 4097 + + 1 + BIN\UL2CM3.DLL + + + + + + 0 + + + + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + 1 + 0 + 0 + 0 + 0 + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + "Cortex-M4" + + 0 + 0 + 0 + 1 + 1 + 0 + 0 + 2 + 0 + 0 + 0 + 0 + 8 + 0 + 0 + 0 + 0 + 3 + 3 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 1 + 0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x20000000 + 0x8000 + + + 1 + 0x0 + 0x40000 + + + 0 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x40000 + + + 1 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x20000000 + 0x8000 + + + 0 + 0x0 + 0x0 + + + + + + 0 + 5 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 3 + 0 + 1 + 0 + 0 + 0 + 3 + 3 + 0 + 0 + 1 + 0 + 0 + + + NDEBUG,QP_CONFIG + + ..\..;..\..\..\..\..\include;..\..\..\..\..\ports\arm-cm\qv\armclang;..\..\..\..\..\3rd_party\CMSIS\Include;..\..\..\..\..\3rd_party\ek-tm4c123gxl + + + + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 4 + + + Stack_Size=2048 Heap_Size=16 + + + + + + 0 + 0 + 0 + 0 + 1 + 0 + 0x00000000 + 0x20000000 + + .\dpp-qv.sct + + + --entry Reset_Handler + + + + + + + + Applicatioin + + + bsp.c + 1 + ..\bsp.c + + + dpp.h + 5 + ..\..\dpp.h + + + bsp.h + 5 + ..\..\bsp.h + + + philo.c + 1 + ..\..\philo.c + + + table.c + 1 + ..\..\table.c + + + main.c + 1 + ..\..\main.c + + + + + ek-tm4c123gxl + + + system_TM4C123GH6PM.c + 1 + ..\..\..\..\..\3rd_party\ek-tm4c123gxl\system_TM4C123GH6PM.c + + + TM4C123GH6PM.h + 5 + ..\..\..\..\..\3rd_party\ek-tm4c123gxl\TM4C123GH6PM.h + + + startup_TM4C123GH6PM.s + 2 + ..\..\..\..\..\3rd_party\ek-tm4c123gxl\arm\startup_TM4C123GH6PM.s + + + gpio.h + 5 + ..\..\..\..\..\3rd_party\ek-tm4c123gxl\gpio.h + + + rom.h + 5 + ..\..\..\..\..\3rd_party\ek-tm4c123gxl\rom.h + + + sysctl.h + 5 + ..\..\..\..\..\3rd_party\ek-tm4c123gxl\sysctl.h + + + system_TM4C123GH6PM.h + 5 + ..\..\..\..\..\3rd_party\ek-tm4c123gxl\system_TM4C123GH6PM.h + + + + + QP + + + qep_hsm.c + 1 + ..\..\..\..\..\src\qf\qep_hsm.c + + + qep_msm.c + 1 + ..\..\..\..\..\src\qf\qep_msm.c + + + qf_act.c + 1 + ..\..\..\..\..\src\qf\qf_act.c + + + qf_actq.c + 1 + ..\..\..\..\..\src\qf\qf_actq.c + + + qf_defer.c + 1 + ..\..\..\..\..\src\qf\qf_defer.c + + + qf_dyn.c + 1 + ..\..\..\..\..\src\qf\qf_dyn.c + + + qf_mem.c + 1 + ..\..\..\..\..\src\qf\qf_mem.c + + + qf_ps.c + 1 + ..\..\..\..\..\src\qf\qf_ps.c + + + qf_qact.c + 1 + ..\..\..\..\..\src\qf\qf_qact.c + + + qf_qeq.c + 1 + ..\..\..\..\..\src\qf\qf_qeq.c + + + qf_qmact.c + 1 + ..\..\..\..\..\src\qf\qf_qmact.c + + + qf_time.c + 1 + ..\..\..\..\..\src\qf\qf_time.c + + + qv.c + 1 + ..\..\..\..\..\src\qv\qv.c + + + + + QP_port + + + qv_port.c + 1 + ..\..\..\..\..\ports\arm-cm\qv\armclang\qv_port.c + + + + + QS + + + 0 + 0 + 0 + 0 + 0 + 0 + 2 + 2 + 2 + 2 + 11 + + + 1 + + + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 0 + 0 + 0 + 0 + 2 + + + + + + + + + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + + + + + + + + + + + + qs.c + 1 + ..\..\..\..\..\src\qs\qs.c + + + qs_64bit.c + 1 + ..\..\..\..\..\src\qs\qs_64bit.c + + + qs_fp.c + 1 + ..\..\..\..\..\src\qs\qs_fp.c + + + qs_rx.c + 1 + ..\..\..\..\..\src\qs\qs_rx.c + + + qstamp.c + 1 + ..\..\..\..\..\src\qs\qstamp.c + + + + + + + dpp-spy + 0x4 + ARM-ADS + 6160000::V6.16::ARMCLANG + 1 + + + TM4C123GH6PM + Texas Instruments + Keil.TM4C_DFP.1.1.0 + http://www.keil.com/pack/ + IROM(0x00000000,0x040000) IRAM(0x20000000,0x008000) CPUTYPE("Cortex-M4") FPU2 CLOCK(12000000) ELITTLE + + + UL2CM3(-S0 -C0 -P0 -FD20000000 -FC1000 -FN1 -FF0TM4C123_256 -FS00 -FL040000 -FP0($$Device:TM4C123GH6PM$Flash\TM4C123_256.FLM)) + 0 + $$Device:TM4C123GH6PM$Device\Include\TM4C123\TM4C123.h + + + + + + + + + + $$Device:TM4C123GH6PM$SVD\TM4C123\TM4C123GH6PM.svd + 0 + 0 + + + + + + + 0 + 0 + 0 + 0 + 1 + + .\spy\ + dpp-qv + 1 + 0 + 0 + 1 + 1 + .\spy\ + 1 + 0 + 0 + + 0 + 0 + + + 0 + 0 + 0 + 0 + + + 1 + 0 + cmd /c "del .\spy\qstamp.o" + + 0 + 0 + 0 + 0 + + + 1 + 0 + fromelf --bin --output .\spy\dpp-qv.bin .\spy\dpp-qv.axf + + 0 + 0 + 0 + 0 + + 1 + + + + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 3 + + + 1 + + + SARMCM3.DLL + -MPU + DCM.DLL + -pCM4 + SARMCM3.DLL + -MPU + TCM.DLL + -pCM4 + + + + 1 + 0 + 0 + 0 + 16 + + + + + 1 + 0 + 0 + 1 + 1 + 4097 + + 1 + BIN\UL2CM3.DLL + + + + + + 0 + + + + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + 1 + 0 + 0 + 0 + 0 + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + "Cortex-M4" + + 0 + 0 + 0 + 1 + 1 + 0 + 0 + 2 + 0 + 0 + 0 + 0 + 8 + 0 + 0 + 0 + 0 + 3 + 3 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 1 + 0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x20000000 + 0x8000 + + + 1 + 0x0 + 0x40000 + + + 0 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x40000 + + + 1 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x20000000 + 0x8000 + + + 0 + 0x0 + 0x0 + + + + + + 0 + 1 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 3 + 0 + 1 + 0 + 0 + 0 + 3 + 3 + 0 + 0 + 0 + 0 + 0 + + + Q_SPY,QP_CONFIG + + ..\..;..\..\..\..\..\include;..\..\..\..\..\ports\arm-cm\qv\armclang;..\..\..\..\..\3rd_party\CMSIS\Include;..\..\..\..\..\3rd_party\ek-tm4c123gxl + + + + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 4 + + + Stack_Size=2048 Heap_Size=16 + + + + + + 0 + 0 + 0 + 0 + 1 + 0 + 0x00000000 + 0x20000000 + + .\dpp-qv.sct + + + --entry Reset_Handler + + + + + + + + Applicatioin + + + bsp.c + 1 + ..\bsp.c + + + dpp.h + 5 + ..\..\dpp.h + + + bsp.h + 5 + ..\..\bsp.h + + + philo.c + 1 + ..\..\philo.c + + + table.c + 1 + ..\..\table.c + + + main.c + 1 + ..\..\main.c + + + + + ek-tm4c123gxl + + + system_TM4C123GH6PM.c + 1 + ..\..\..\..\..\3rd_party\ek-tm4c123gxl\system_TM4C123GH6PM.c + + + TM4C123GH6PM.h + 5 + ..\..\..\..\..\3rd_party\ek-tm4c123gxl\TM4C123GH6PM.h + + + startup_TM4C123GH6PM.s + 2 + ..\..\..\..\..\3rd_party\ek-tm4c123gxl\arm\startup_TM4C123GH6PM.s + + + gpio.h + 5 + ..\..\..\..\..\3rd_party\ek-tm4c123gxl\gpio.h + + + rom.h + 5 + ..\..\..\..\..\3rd_party\ek-tm4c123gxl\rom.h + + + sysctl.h + 5 + ..\..\..\..\..\3rd_party\ek-tm4c123gxl\sysctl.h + + + system_TM4C123GH6PM.h + 5 + ..\..\..\..\..\3rd_party\ek-tm4c123gxl\system_TM4C123GH6PM.h + + + + + QP + + + qep_hsm.c + 1 + ..\..\..\..\..\src\qf\qep_hsm.c + + + qep_msm.c + 1 + ..\..\..\..\..\src\qf\qep_msm.c + + + qf_act.c + 1 + ..\..\..\..\..\src\qf\qf_act.c + + + qf_actq.c + 1 + ..\..\..\..\..\src\qf\qf_actq.c + + + qf_defer.c + 1 + ..\..\..\..\..\src\qf\qf_defer.c + + + qf_dyn.c + 1 + ..\..\..\..\..\src\qf\qf_dyn.c + + + qf_mem.c + 1 + ..\..\..\..\..\src\qf\qf_mem.c + + + qf_ps.c + 1 + ..\..\..\..\..\src\qf\qf_ps.c + + + qf_qact.c + 1 + ..\..\..\..\..\src\qf\qf_qact.c + + + qf_qeq.c + 1 + ..\..\..\..\..\src\qf\qf_qeq.c + + + qf_qmact.c + 1 + ..\..\..\..\..\src\qf\qf_qmact.c + + + qf_time.c + 1 + ..\..\..\..\..\src\qf\qf_time.c + + + qv.c + 1 + ..\..\..\..\..\src\qv\qv.c + + + + + QP_port + + + qv_port.c + 1 + ..\..\..\..\..\ports\arm-cm\qv\armclang\qv_port.c + + + + + QS + + + qs.c + 1 + ..\..\..\..\..\src\qs\qs.c + + + qs_64bit.c + 1 + ..\..\..\..\..\src\qs\qs_64bit.c + + + qs_fp.c + 1 + ..\..\..\..\..\src\qs\qs_fp.c + + + qs_rx.c + 1 + ..\..\..\..\..\src\qs\qs_rx.c + + + qstamp.c + 1 + ..\..\..\..\..\src\qs\qstamp.c + + + + + + + + + + + + + +
diff --git a/examples/arm-cm/dpp_ek-tm4c123gxl_mpu/qv/bsp.c b/examples/arm-cm/dpp_ek-tm4c123gxl_mpu/qv/bsp.c new file mode 100644 index 00000000..30427520 --- /dev/null +++ b/examples/arm-cm/dpp_ek-tm4c123gxl_mpu/qv/bsp.c @@ -0,0 +1,851 @@ +//============================================================================ +// Product: DPP example, EK-TM4C123GXL board, QV kernel, MPU isolation +// Last updated for version 7.3.0 +// Last updated on 2023-09-07 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. +// +// This program is open source software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Alternatively, this program may be distributed and modified under the +// terms of Quantum Leaps commercial licenses, which expressly supersede +// the GNU General Public License and are specifically designed for +// licensees interested in retaining the proprietary status of their code. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Contact information: +// +// +//============================================================================ +#include "qpc.h" // QP/C real-time embedded framework +#include "dpp.h" // DPP Application interface +#include "bsp.h" // Board Support Package + +#include "TM4C123GH6PM.h" // the device specific header (TI) +#include "rom.h" // the built-in ROM functions (TI) +#include "sysctl.h" // system control driver (TI) +#include "gpio.h" // GPIO driver (TI) +// add other drivers if necessary... + +Q_DEFINE_THIS_FILE // define the name of this file for assertions + +// Local-scope objects ----------------------------------------------------- +#define LED_RED (1U << 1U) +#define LED_GREEN (1U << 3U) +#define LED_BLUE (1U << 2U) + +#define BTN_SW1 (1U << 4U) +#define BTN_SW2 (1U << 0U) + +#ifdef Q_SPY + + // QSpy source IDs + static QSpyId const l_SysTick_Handler = { 0U }; + static QSpyId const l_GPIOPortA_IRQHandler = { 0U }; + + #define UART_BAUD_RATE 115200U + #define UART_FR_TXFE (1U << 7U) + #define UART_FR_RXFE (1U << 4U) + #define UART_TXFIFO_DEPTH 16U + + enum AppRecords { // application-specific trace records + PHILO_STAT = QS_USER, + PAUSED_STAT, + }; + +#endif + +//---------------------------------------------------------------------------- +// MPU storage and settings... +typedef struct { + uint32_t RBAR; + uint32_t RASR; +} MPU_Region; + +//============================================================================ +// Error handler and ISRs... + +Q_NORETURN Q_onError(char const *module, int_t const id) { + // NOTE: this implementation of the assertion handler is intended only + // for debugging and MUST be changed for deployment of the application + // (assuming that you ship your production code with assertions enabled). + Q_UNUSED_PAR(module); + Q_UNUSED_PAR(id); + QS_ASSERTION(module, id, (uint32_t)10000U); + +#ifndef NDEBUG + // light up all LEDs + GPIOF_AHB->DATA_Bits[LED_GREEN | LED_RED | LED_BLUE] = 0xFFU; + // for debugging, hang on in an endless loop... + for (;;) { + } +#endif + + NVIC_SystemReset(); +} +//............................................................................ +void assert_failed(char const * const module, int_t const id); // prototype +void assert_failed(char const * const module, int_t const id) { + Q_onError(module, id); +} + +//............................................................................ +void SysTick_Handler(void); // prototype +void SysTick_Handler(void) { + + QTIMEEVT_TICK_X(0U, &l_SysTick_Handler); // time events at rate 0 + + // Perform the debouncing of buttons. The algorithm for debouncing + // adapted from the book "Embedded Systems Dictionary" by Jack Ganssle + // and Michael Barr, page 71. + static struct { + uint32_t depressed; + uint32_t previous; + } buttons = { 0U, 0U }; + + QF_INT_DISABLE(); + QF_MEM_SYS(); + + uint32_t current = ~GPIOF_AHB->DATA_Bits[BTN_SW1 | BTN_SW2]; + uint32_t tmp = buttons.depressed; // save the depressed buttons + buttons.depressed |= (buttons.previous & current); // set depressed + buttons.depressed &= (buttons.previous | current); // clear released + buttons.previous = current; // update the history + tmp ^= buttons.depressed; // changed debounced depressed + current = buttons.depressed; + + QF_MEM_APP(); + QF_INT_ENABLE(); + + if ((tmp & BTN_SW1) != 0U) { // debounced SW1 state changed? + if ((current & BTN_SW1) != 0U) { // is SW1 depressed? + static QEvt const pauseEvt = QEVT_INITIALIZER(PAUSE_SIG); + QACTIVE_PUBLISH(&pauseEvt, &l_SysTick_Handler); + } + else { // the button is released + static QEvt const serveEvt = QEVT_INITIALIZER(SERVE_SIG); + QACTIVE_PUBLISH(&serveEvt, &l_SysTick_Handler); + } + } + + QV_ARM_ERRATUM_838869(); +} +//............................................................................ +// interrupt handler for testing preemptions in QV +void GPIOPortA_IRQHandler(void); // prototype +void GPIOPortA_IRQHandler(void) { + // for testing.. + static QEvt const testEvt = QEVT_INITIALIZER(TEST_SIG); + QACTIVE_POST(AO_Table, &testEvt, &l_GPIOPortA_IRQHandler); + + QV_ARM_ERRATUM_838869(); +} + +//............................................................................ +#ifdef Q_SPY +// ISR for receiving bytes from the QSPY Back-End +// NOTE: This ISR is "QF-unaware" meaning that it does not interact with +// the QF/QV and is not disabled. Such ISRs cannot post or publish events. + +void UART0_IRQHandler(void); // prototype +void UART0_IRQHandler(void) { + QF_MEM_SYS(); + + uint32_t status = UART0->RIS; // get the raw interrupt status + UART0->ICR = status; // clear the asserted interrupts + + while ((UART0->FR & UART_FR_RXFE) == 0U) { // while RX FIFO NOT empty + uint8_t b = (uint8_t)UART0->DR; + QS_rxPut(b); + } + QV_ARM_ERRATUM_838869(); +} +#else +void UART0_IRQHandler() {} +#endif // Q_SPY + +#ifdef QF_MEM_ISOLATE +//............................................................................ +__attribute__(( used )) +void QF_onMemSys(void) { + MPU->CTRL = MPU_CTRL_ENABLE_Msk // enable the MPU + | MPU_CTRL_PRIVDEFENA_Msk; // enable background region + __ISB(); + __DSB(); +} +//............................................................................ +__attribute__(( used )) +void QF_onMemApp() { + MPU->CTRL = MPU_CTRL_ENABLE_Msk; // enable the MPU + // but do NOT enable background region + __ISB(); + __DSB(); +} +//............................................................................ +#ifdef QF_ON_CONTEXT_SW +// NOTE: the context-switch callback is called with interrupts DISABLED +void QF_onContextSw(QActive *prev, QActive *next) { + if (next != (QActive *)0) { + MPU->CTRL = 0U; // disable the MPU + + MPU_Region const * const region = + (MPU_Region const *)(next->thread); + MPU->RBAR = region[0].RBAR; + MPU->RASR = region[0].RASR; + MPU->RBAR = region[1].RBAR; + MPU->RASR = region[1].RASR; + MPU->RBAR = region[2].RBAR; + MPU->RASR = region[2].RASR; + + MPU->CTRL = MPU_CTRL_ENABLE_Msk // enable the MPU + | MPU_CTRL_PRIVDEFENA_Msk; // enable background region + __ISB(); + __DSB(); + } +} +#endif // QF_ON_CONTEXT_SW +#endif // QF_MEM_ISOLATE + +//============================================================================ + +// Stack ..................................................................... +// NOTE +// The main stack size (provided here as power of 2), MUST match the actual +// stack size defined in the linker-script/startup-code. +#define STACK_SIZE_POW2 ((uint32_t)11U) + +// Table AO................................................................... +// size of Table instance, as power-of-2 +#define TABLE_SIZE_POW2 ((uint32_t)6U) + +__attribute__((aligned((1U << TABLE_SIZE_POW2)))) +static uint8_t Table_sto[1U << TABLE_SIZE_POW2]; + +#ifdef QF_MEM_ISOLATE +static MPU_Region const MPU_Table[3] = { + { (uint32_t)Table_sto + 0x10U, //---- region #0 + ((TABLE_SIZE_POW2 - 1U) << MPU_RASR_SIZE_Pos) // size + + (3U << MPU_RASR_AP_Pos) // PA:rw/UA:rw + + (1U << MPU_RASR_XN_Pos) // XN=1 + + (1U << MPU_RASR_S_Pos) // S=1 + + (1U << MPU_RASR_C_Pos) // C=1 + + (0U << MPU_RASR_B_Pos) // B=0 + + (0U << MPU_RASR_TEX_Pos) // TEX=0 + + MPU_RASR_ENABLE_Msk }, // region enable + { GPIOF_AHB_BASE + 0x11U, //---- region #1 + ((9U - 1U) << MPU_RASR_SIZE_Pos) // 2^9=512B size + + (3U << MPU_RASR_AP_Pos) // PA:rw/UA:rw + + (1U << MPU_RASR_XN_Pos) // XN=1 + + (1U << MPU_RASR_S_Pos) // S=1 + + (0U << MPU_RASR_C_Pos) // C=0 + + (1U << MPU_RASR_B_Pos) // B=1 + + (0U << MPU_RASR_TEX_Pos) // TEX=0 + + MPU_RASR_ENABLE_Msk }, // region enable + { 0U + 0x12U, //---- region #2 + 0U }, +}; +#endif + +// Philo AOs................................................................ +// size of Philo instance, as power-of-2 +#define PHILO_SIZE_POW2 ((uint32_t)6U) + +__attribute__((aligned((1U << PHILO_SIZE_POW2)))) +static uint8_t Philo_sto[N_PHILO][1U << PHILO_SIZE_POW2]; + +#define PHILO_SHARED_SIZE_POW2 ((uint32_t)5U) +__attribute__((aligned((1U << PHILO_SHARED_SIZE_POW2)))) +static union { + uint32_t rnd_seed; + uint8_t byteso[1U << PHILO_SHARED_SIZE_POW2]; +} Philo_shared_sto; + +#ifdef QF_MEM_ISOLATE +static MPU_Region const MPU_Philo[N_PHILO][3] = { + {{ (uint32_t)Philo_sto[0] + 0x10U, //---- region #0 + ((PHILO_SIZE_POW2 - 1U) << MPU_RASR_SIZE_Pos) // size + + (3U << MPU_RASR_AP_Pos) // PA:rw/UA:rw + + (1U << MPU_RASR_XN_Pos) // XN=1 + + (1U << MPU_RASR_S_Pos) // S=1 + + (1U << MPU_RASR_C_Pos) // C=1 + + (0U << MPU_RASR_B_Pos) // B=0 + + (0U << MPU_RASR_TEX_Pos) // TEX=0 + + MPU_RASR_ENABLE_Msk }, // region enable + { (uint32_t)&Philo_shared_sto + 0x11U, //---- region #1 + ((PHILO_SHARED_SIZE_POW2 - 1U) << MPU_RASR_SIZE_Pos) // size + + (3U << MPU_RASR_AP_Pos) // PA:rw/UA:rw + + (1U << MPU_RASR_XN_Pos) // XN=1 + + (1U << MPU_RASR_S_Pos) // S=1 + + (1U << MPU_RASR_C_Pos) // C=1 + + (0U << MPU_RASR_B_Pos) // B=0 + + (0U << MPU_RASR_TEX_Pos) // TEX=0 + + MPU_RASR_ENABLE_Msk }, // region enable + { 0U + 0x12U, //---- region #2 + 0U }}, + {{ (uint32_t)Philo_sto[1] + 0x10U, //---- region #0 + ((PHILO_SIZE_POW2 - 1U) << MPU_RASR_SIZE_Pos) // size + + (3U << MPU_RASR_AP_Pos) // PA:rw/UA:rw + + (1U << MPU_RASR_XN_Pos) // XN=1 + + (1U << MPU_RASR_S_Pos) // S=1 + + (1U << MPU_RASR_C_Pos) // C=1 + + (0U << MPU_RASR_B_Pos) // B=0 + + (0U << MPU_RASR_TEX_Pos) // TEX=0 + + MPU_RASR_ENABLE_Msk }, // region enable + { (uint32_t)&Philo_shared_sto + 0x11U, //---- region #1 + ((PHILO_SHARED_SIZE_POW2 - 1U) << MPU_RASR_SIZE_Pos) // size + + (3U << MPU_RASR_AP_Pos) // PA:rw/UA:rw + + (1U << MPU_RASR_XN_Pos) // XN=1 + + (1U << MPU_RASR_S_Pos) // S=1 + + (1U << MPU_RASR_C_Pos) // C=1 + + (0U << MPU_RASR_B_Pos) // B=0 + + (0U << MPU_RASR_TEX_Pos) // TEX=0 + + MPU_RASR_ENABLE_Msk }, // region enable + { 0U + 0x12U, //---- region #2 + 0U }}, + {{ (uint32_t)Philo_sto[2] + 0x10U, //---- region #0 + ((PHILO_SIZE_POW2 - 1U) << MPU_RASR_SIZE_Pos) // size + + (3U << MPU_RASR_AP_Pos) // PA:rw/UA:rw + + (1U << MPU_RASR_XN_Pos) // XN=1 + + (1U << MPU_RASR_S_Pos) // S=1 + + (1U << MPU_RASR_C_Pos) // C=1 + + (0U << MPU_RASR_B_Pos) // B=0 + + (0U << MPU_RASR_TEX_Pos) // TEX=0 + + MPU_RASR_ENABLE_Msk }, // region enable + { (uint32_t)&Philo_shared_sto + 0x11U, //---- region #1 + ((PHILO_SHARED_SIZE_POW2 - 1U) << MPU_RASR_SIZE_Pos) // size + + (3U << MPU_RASR_AP_Pos) // PA:rw/UA:rw + + (1U << MPU_RASR_XN_Pos) // XN=1 + + (1U << MPU_RASR_S_Pos) // S=1 + + (1U << MPU_RASR_C_Pos) // C=1 + + (0U << MPU_RASR_B_Pos) // B=0 + + (0U << MPU_RASR_TEX_Pos) // TEX=0 + + MPU_RASR_ENABLE_Msk }, // region enable + { 0U + 0x12U, //---- region #2 + 0U }}, + {{ (uint32_t)Philo_sto[3] + 0x10U, //---- region #0 + ((PHILO_SIZE_POW2 - 1U) << MPU_RASR_SIZE_Pos) // size + + (3U << MPU_RASR_AP_Pos) // PA:rw/UA:rw + + (1U << MPU_RASR_XN_Pos) // XN=1 + + (1U << MPU_RASR_S_Pos) // S=1 + + (1U << MPU_RASR_C_Pos) // C=1 + + (0U << MPU_RASR_B_Pos) // B=0 + + (0U << MPU_RASR_TEX_Pos) // TEX=0 + + MPU_RASR_ENABLE_Msk }, // region enable + { (uint32_t)&Philo_shared_sto + 0x11U, //---- region #1 + ((PHILO_SHARED_SIZE_POW2 - 1U) << MPU_RASR_SIZE_Pos) // size + + (3U << MPU_RASR_AP_Pos) // PA:rw/UA:rw + + (1U << MPU_RASR_XN_Pos) // XN=1 + + (1U << MPU_RASR_S_Pos) // S=1 + + (1U << MPU_RASR_C_Pos) // C=1 + + (0U << MPU_RASR_B_Pos) // B=0 + + (0U << MPU_RASR_TEX_Pos) // TEX=0 + + MPU_RASR_ENABLE_Msk }, // region enable + { 0U + 0x12U, //---- region #2 + 0U }}, + {{ (uint32_t)Philo_sto[4] + 0x10U, //---- region #0 + ((PHILO_SIZE_POW2 - 1U) << MPU_RASR_SIZE_Pos) // size + + (3U << MPU_RASR_AP_Pos) // PA:rw/UA:rw + + (1U << MPU_RASR_XN_Pos) // XN=1 + + (1U << MPU_RASR_S_Pos) // S=1 + + (1U << MPU_RASR_C_Pos) // C=1 + + (0U << MPU_RASR_B_Pos) // B=0 + + (0U << MPU_RASR_TEX_Pos) // TEX=0 + + MPU_RASR_ENABLE_Msk }, // region enable + { (uint32_t)&Philo_shared_sto + 0x11U, //---- region #1 + ((PHILO_SHARED_SIZE_POW2 - 1U) << MPU_RASR_SIZE_Pos) // size + + (3U << MPU_RASR_AP_Pos) // PA:rw/UA:rw + + (1U << MPU_RASR_XN_Pos) // XN=1 + + (1U << MPU_RASR_S_Pos) // S=1 + + (1U << MPU_RASR_C_Pos) // C=1 + + (0U << MPU_RASR_B_Pos) // B=0 + + (0U << MPU_RASR_TEX_Pos) // TEX=0 + + MPU_RASR_ENABLE_Msk }, // region enable + { 0U + 0x12U, //---- region #2 + 0U }}, +}; +#endif + +// Shared Event-pools...................................................... +#define EPOOLS_SIZE_POW2 ((uint32_t)8U) + +__attribute__((aligned((1U << EPOOLS_SIZE_POW2)))) +static struct EPools { + QF_MPOOL_EL(TableEvt) smlPool[2*N_PHILO]; + // ... other pools +} EPools_sto; +Q_ASSERT_STATIC(sizeof(EPools_sto) <= (1U << EPOOLS_SIZE_POW2)); + +//............................................................................ +#ifdef QF_MEM_ISOLATE +static void TM4C123GXL_MPU_setup(void) { + + SCB->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk; + + MPU->CTRL = 0U; // disable the MPU + + // region #7: NULL-pointer protection region + MPU->RBAR = 0x00000000U + 0x17U; // base address + region #7 + MPU->RASR = ((8U - 1U) << MPU_RASR_SIZE_Pos) // 2^8=256B size + + (0U << MPU_RASR_AP_Pos) // PA:na/UA:na + + (1U << MPU_RASR_XN_Pos) // XN=1 + + (0U << MPU_RASR_S_Pos) // S=0 + + (0U << MPU_RASR_C_Pos) // C=0 + + (0U << MPU_RASR_B_Pos) // B=0 + + (0U << MPU_RASR_TEX_Pos) // TEX=0 + + MPU_RASR_ENABLE_Msk; // region enable + + // region #6: stack region + MPU->RBAR = 0x20000000U + 0x16U; // base address + region #6 + MPU->RASR = ((STACK_SIZE_POW2 - 1U) << MPU_RASR_SIZE_Pos) // size + + (3U << MPU_RASR_AP_Pos) // PA:rw/UA:rw + + (1U << MPU_RASR_XN_Pos) // XN=1 + + (1U << MPU_RASR_S_Pos) // S=1 + + (1U << MPU_RASR_C_Pos) // C=1 + + (0U << MPU_RASR_B_Pos) // B=0 + + (0U << MPU_RASR_TEX_Pos) // TEX=0 + + MPU_RASR_ENABLE_Msk; // region enable + + // region #5: ROM region for TM4C123GXL, whole 256K + MPU->RBAR = 0x00000000U + 0x15U; // base address + region #5 + MPU->RASR = ((18U - 1U) << MPU_RASR_SIZE_Pos) // 2^18=256K size + + (6U << MPU_RASR_AP_Pos) // PA:ro/UA:ro + + (0U << MPU_RASR_XN_Pos) // XN=0 + + (0U << MPU_RASR_S_Pos) // S=0 + + (1U << MPU_RASR_C_Pos) // C=1 + + (0U << MPU_RASR_B_Pos) // B=0 + + (0U << MPU_RASR_TEX_Pos) // TEX=0 + + MPU_RASR_ENABLE_Msk; // region enable + + // region #4: Event-pools region + MPU->RBAR = (uint32_t)&EPools_sto + 0x14U;// base address + region #4 + MPU->RASR = ((EPOOLS_SIZE_POW2 - 1U) << MPU_RASR_SIZE_Pos) // size + + (3U << MPU_RASR_AP_Pos) // PA:rw/UA:rw + + (1U << MPU_RASR_XN_Pos) // XN=1 + + (1U << MPU_RASR_S_Pos) // S=1 + + (1U << MPU_RASR_C_Pos) // C=1 + + (0U << MPU_RASR_B_Pos) // B=0 + + (0U << MPU_RASR_TEX_Pos) // TEX=0 + + MPU_RASR_ENABLE_Msk; // region enable + +#ifdef Q_SPY + // region #3: QS-filters region + MPU->RBAR = (uint32_t)&QS_filt_ + 0x13U;// base address + region #3 + MPU->RASR = ((5U - 1U) << MPU_RASR_SIZE_Pos) // 2^5=32B size + + (3U << MPU_RASR_AP_Pos) // PA:rw/UA:rw + + (1U << MPU_RASR_XN_Pos) // XN=1 + + (1U << MPU_RASR_S_Pos) // S=1 + + (1U << MPU_RASR_C_Pos) // C=1 + + (0U << MPU_RASR_B_Pos) // B=0 + + (0U << MPU_RASR_TEX_Pos) // TEX=0 + + MPU_RASR_ENABLE_Msk; // region enable +#endif + + // region #0: temporary 4G region for initial transient + MPU->RBAR = 0x00000000U + 0x10U; // base address + region #0 + MPU->RASR = ((32U - 1U) << MPU_RASR_SIZE_Pos) // 2^32=4G size + + (3U << MPU_RASR_AP_Pos) // PA:rw/UA:rw + + (0U << MPU_RASR_XN_Pos) // XN=0 + + (1U << MPU_RASR_S_Pos) // S=1 + + (1U << MPU_RASR_C_Pos) // C=1 + + (0U << MPU_RASR_B_Pos) // B=0 + + (0U << MPU_RASR_TEX_Pos) // TEX=0 + + MPU_RASR_ENABLE_Msk; // region enable + + MPU->CTRL = MPU_CTRL_ENABLE_Msk; // enable the MPU + // but do NOT enable background region + __ISB(); + __DSB(); +} +#endif + +//============================================================================ + +// "opaque" pointer to AO +QActive * const AO_Table = (QActive *)Table_sto; + +QActive * const AO_Philo[N_PHILO] = { + (QActive *)Philo_sto[0], // "opaque" pointer + (QActive *)Philo_sto[1], // "opaque" pointer + (QActive *)Philo_sto[2], // "opaque" pointer + (QActive *)Philo_sto[3], // "opaque" pointer + (QActive *)Philo_sto[4] // "opaque" pointer +}; + +// BSP functions =========================================================== +void BSP_init(void) { +#ifdef QF_MEM_ISOLATE + // setup the MPU + TM4C123GXL_MPU_setup(); +#endif + + // NOTE: SystemInit() has been already called from the startup code + // but SystemCoreClock needs to be updated + SystemCoreClockUpdate(); + + // NOTE: The VFP (hardware Floating Point) unit is configured by QV + + // enable clock for to the peripherals used by this application... + SYSCTL->RCGCGPIO |= (1U << 5U); // enable Run mode for GPIOF + SYSCTL->GPIOHBCTL |= (1U << 5U); // enable AHB for GPIOF + __ISB(); + __DSB(); + + // configure LEDs (digital output) + GPIOF_AHB->DIR |= (LED_RED | LED_BLUE | LED_GREEN); + GPIOF_AHB->DEN |= (LED_RED | LED_BLUE | LED_GREEN); + GPIOF_AHB->DATA_Bits[LED_RED | LED_BLUE | LED_GREEN] = 0U; + + // configure switches... + + // unlock access to the SW2 pin because it is PROTECTED + GPIOF_AHB->LOCK = 0x4C4F434BU; // unlock GPIOCR register for SW2 + // commit the write (cast const away) + *(uint32_t volatile *)&GPIOF_AHB->CR = 0x01U; + + GPIOF_AHB->DIR &= ~(BTN_SW1 | BTN_SW2); // input + GPIOF_AHB->DEN |= (BTN_SW1 | BTN_SW2); // digital enable + GPIOF_AHB->PUR |= (BTN_SW1 | BTN_SW2); // pull-up resistor enable + + *(uint32_t volatile *)&GPIOF_AHB->CR = 0x00U; + GPIOF_AHB->LOCK = 0x0; // lock GPIOCR register for SW2 + + BSP_randomSeed(1234U); // seed the random number generator + + // initialize the QS software tracing... + if (!QS_INIT((void *)0)) { + Q_ERROR(); + } + + // dictionaries... + QS_OBJ_DICTIONARY(&l_SysTick_Handler); + QS_OBJ_DICTIONARY(&l_GPIOPortA_IRQHandler); + QS_USR_DICTIONARY(PHILO_STAT); + QS_USR_DICTIONARY(PAUSED_STAT); + + QS_ONLY(produce_sig_dict()); + + // setup the QS filters... + QS_GLB_FILTER(QS_ALL_RECORDS); // all records + QS_GLB_FILTER(-QS_QF_TICK); // exclude the clock tick +} +//............................................................................ +void BSP_start(void) { + // initialize event pools + QF_poolInit(EPools_sto.smlPool, + sizeof(EPools_sto.smlPool), + sizeof(EPools_sto.smlPool[0])); + + // initialize publish-subscribe + static QSubscrList subscrSto[MAX_PUB_SIG]; + QActive_psInit(subscrSto, Q_DIM(subscrSto)); + + // instantiate and start AOs/threads... + + static QEvt const *philoQueueSto[N_PHILO][10]; + for (uint8_t n = 0U; n < N_PHILO; ++n) { +#ifdef QF_MEM_ISOLATE + Philo_ctor(n, Philo_sto[n], sizeof(Philo_sto[n]), MPU_Philo[n]); +#else + Philo_ctor(n, Philo_sto[n], sizeof(Philo_sto[n]), (void *)0); +#endif + QACTIVE_START(AO_Philo[n], + n + 3U, // QF-prio/pthre. see NOTE1 + philoQueueSto[n], // event queue storage + Q_DIM(philoQueueSto[n]), // queue length [events] + (void *)0, 0U, // no stack storage + (void *)0); // no initialization param + } + + static QEvt const *tableQueueSto[N_PHILO]; +#ifdef QF_MEM_ISOLATE + Table_ctor(Table_sto, sizeof(Table_sto), MPU_Table); +#else + Table_ctor(Table_sto, sizeof(Table_sto), (void *)0); +#endif + QACTIVE_START(AO_Table, + N_PHILO + 7U, // QP prio. of the AO + tableQueueSto, // event queue storage + Q_DIM(tableQueueSto), // queue length [events] + (void *)0, 0U, // no stack storage + (void *)0); // no initialization param +} +//............................................................................ +void BSP_displayPhilStat(uint8_t n, char const *stat) { + Q_UNUSED_PAR(n); + + GPIOF_AHB->DATA_Bits[LED_GREEN] = ((stat[0] == 'e') ? LED_GREEN : 0U); + + // app-specific trace record... + QS_BEGIN_ID(PHILO_STAT, AO_Table->prio) + QS_U8(1, n); // Philosopher number + QS_STR(stat); // Philosopher status + QS_END() +} +//............................................................................ +void BSP_displayPaused(uint8_t const paused) { + GPIOF_AHB->DATA_Bits[LED_BLUE] = ((paused != 0U) ? LED_BLUE : 0U); + + // application-specific trace record + QS_BEGIN_ID(PAUSED_STAT, AO_Table->prio) + QS_U8(1, paused); // Paused status + QS_END() +} +//............................................................................ +void BSP_randomSeed(uint32_t seed) { + Philo_shared_sto.rnd_seed = seed; +} +//............................................................................ +uint32_t BSP_random() { // a very cheap pseudo-random-number generator + // Some floating point code is to exercise the VFP... + float volatile x = 3.1415926F; + x = x + 2.7182818F; + + // "Super-Duper" Linear Congruential Generator (LCG) + // LCG(2^32, 3*7*11*13*23, 0, seed) + // + uint32_t rnd = Philo_shared_sto.rnd_seed * (3U*7U*11U*13U*23U); + Philo_shared_sto.rnd_seed = rnd; // set for the next time + + return (rnd >> 8U); +} +//............................................................................ +void BSP_ledOn() { + GPIOF_AHB->DATA_Bits[LED_RED] = 0xFFU; +} +//............................................................................ +void BSP_ledOff() { + GPIOF_AHB->DATA_Bits[LED_RED] = 0x00U; +} +//............................................................................ +void BSP_terminate(int16_t result) { + Q_UNUSED_PAR(result); +} + +//============================================================================ +// QF callbacks... +void QF_onStartup(void) { + // set up the SysTick timer to fire at BSP_TICKS_PER_SEC rate + SysTick_Config(SystemCoreClock / BSP_TICKS_PER_SEC); + + // assign all priority bits for preemption-prio. and none to sub-prio. + NVIC_SetPriorityGrouping(0U); + + // set priorities of ALL ISRs used in the system, see NOTE1 + NVIC_SetPriority(UART0_IRQn, 0U); // kernel unaware interrupt + NVIC_SetPriority(GPIOA_IRQn, QF_AWARE_ISR_CMSIS_PRI + 0U); + NVIC_SetPriority(SysTick_IRQn, QF_AWARE_ISR_CMSIS_PRI + 1U); + // ... + + // enable IRQs... + NVIC_EnableIRQ(GPIOA_IRQn); + +#ifdef Q_SPY + NVIC_EnableIRQ(UART0_IRQn); // UART interrupt used for QS-RX +#endif +} +//............................................................................ +void QF_onCleanup(void) { +} +//............................................................................ +void QV_onIdle(void) { // called with interrupts disabled, see NOTE3 + // toggle the User LED on and then off, see NOTE2 + QF_MEM_SYS(); + GPIOF_AHB->DATA_Bits[LED_BLUE] = 0xFFU; // turn the Blue LED on + GPIOF_AHB->DATA_Bits[LED_BLUE] = 0U; // turn the Blue LED off + + // Some floating point code is to exercise the VFP... + float volatile x = 1.73205F; + x = x * 1.73205F; + +#ifdef Q_SPY + QS_rxParse(); // parse all the received bytes + QF_MEM_APP(); + QF_INT_ENABLE(); + QF_CRIT_EXIT_NOP(); + + QF_INT_DISABLE(); + QF_MEM_SYS(); + if ((UART0->FR & UART_FR_TXFE) != 0U) { // TX done? + uint16_t fifo = UART_TXFIFO_DEPTH; // max bytes we can accept + + // try to get next contiguous block to transmit + uint8_t const *block = QS_getBlock(&fifo); + + while (fifo-- != 0U) { // any bytes in the block? + UART0->DR = *block++; // put into the FIFO + } + } + QF_MEM_APP(); + QF_INT_ENABLE(); +#elif defined NDEBUG + // Put the CPU and peripherals to the low-power mode. + // you might need to customize the clock management for your application, + // see the datasheet for your particular Cortex-M MCU. + // + QV_CPU_SLEEP(); // atomically go to sleep and enable interrupts +#else + QF_MEM_APP(); + QF_INT_ENABLE(); // just enable interrupts +#endif +} + +//============================================================================ +// QS callbacks... +#ifdef Q_SPY + +#ifdef QF_MEM_ISOLATE +// Shared QS filters... +__attribute__((aligned(32))) +QS_Filter QS_filt_; +#endif + +//............................................................................ +uint8_t QS_onStartup(void const *arg) { + Q_UNUSED_PAR(arg); + + static uint8_t qsTxBuf[2*1024]; // buffer for QS-TX channel + QS_initBuf(qsTxBuf, sizeof(qsTxBuf)); + + static uint8_t qsRxBuf[100]; // buffer for QS-RX channel + QS_rxInitBuf(qsRxBuf, sizeof(qsRxBuf)); + + // enable clock for UART0 and GPIOA (used by UART0 pins) + SYSCTL->RCGCUART |= (1U << 0U); // enable Run mode for UART0 + SYSCTL->RCGCGPIO |= (1U << 0U); // enable Run mode for GPIOA + + // configure UART0 pins for UART operation + uint32_t tmp = (1U << 0U) | (1U << 1U); + GPIOA->DIR &= ~tmp; + GPIOA->SLR &= ~tmp; + GPIOA->ODR &= ~tmp; + GPIOA->PUR &= ~tmp; + GPIOA->PDR &= ~tmp; + GPIOA->AMSEL &= ~tmp; // disable analog function on the pins + GPIOA->AFSEL |= tmp; // enable ALT function on the pins + GPIOA->DEN |= tmp; // enable digital I/O on the pins + GPIOA->PCTL &= ~0x00U; + GPIOA->PCTL |= 0x11U; + + // configure the UART for the desired baud rate, 8-N-1 operation + tmp = (((SystemCoreClock * 8U) / UART_BAUD_RATE) + 1U) / 2U; + UART0->IBRD = tmp / 64U; + UART0->FBRD = tmp % 64U; + UART0->LCRH = (0x3U << 5U); // configure 8-N-1 operation + UART0->LCRH |= (0x1U << 4U); // enable FIFOs + UART0->CTL = (1U << 0U) // UART enable + | (1U << 8U) // UART TX enable + | (1U << 9U); // UART RX enable + + // configure UART interrupts (for the RX channel) + UART0->IM |= (1U << 4U) | (1U << 6U); // enable RX and RX-TO interrupt + UART0->IFLS |= (0x2U << 2U); // interrupt on RX FIFO half-full + // NOTE: do not enable the UART0 interrupt yet. Wait till QF_onStartup() + + // configure TIMER5 to produce QS time stamp + SYSCTL->RCGCTIMER |= (1U << 5U); // enable run mode for Timer5 + TIMER5->CTL = 0U; // disable Timer1 output + TIMER5->CFG = 0x0U; // 32-bit configuration + TIMER5->TAMR = (1U << 4U) | 0x02U; // up-counting periodic mode + TIMER5->TAILR= 0xFFFFFFFFU; // timer interval + TIMER5->ICR = 0x1U; // TimerA timeout flag bit clears + TIMER5->CTL |= (1U << 0U); // enable TimerA module + + return 1U; // return success +} +//............................................................................ +void QS_onCleanup(void) { +} +//............................................................................ +QSTimeCtr QS_onGetTime(void) { // NOTE: invoked with interrupts DISABLED + return TIMER5->TAV; +} +//............................................................................ +void QS_onFlush(void) { + for (;;) { + QF_INT_DISABLE(); + QF_MEM_SYS(); + uint16_t b = QS_getByte(); + if (b != QS_EOD) { + while ((UART0->FR & UART_FR_TXFE) == 0U) { // while TXE not empty + QF_MEM_APP(); + QF_INT_ENABLE(); + QF_CRIT_EXIT_NOP(); + + QF_INT_DISABLE(); + QF_MEM_SYS(); + } + UART0->DR = b; // put into the DR register + QF_MEM_APP(); + QF_INT_ENABLE(); + } + else { + QF_MEM_APP(); + QF_INT_ENABLE(); + break; + } + } +} +//............................................................................ +//! callback function to reset the target (to be implemented in the BSP) +void QS_onReset(void) { + NVIC_SystemReset(); +} +//............................................................................ +//! callback function to execute a user command +void QS_onCommand(uint8_t cmdId, + uint32_t param1, uint32_t param2, uint32_t param3) +{ + Q_UNUSED_PAR(cmdId); + Q_UNUSED_PAR(param1); + Q_UNUSED_PAR(param2); + Q_UNUSED_PAR(param3); +} + +#endif // Q_SPY +//---------------------------------------------------------------------------- + +//============================================================================ +// NOTE1: +// The QF_AWARE_ISR_CMSIS_PRI constant from the QF port specifies the highest +// ISR priority that is disabled by the QF framework. The value is suitable +// for the NVIC_SetPriority() CMSIS function. +// +// Only ISRs prioritized at or below the QF_AWARE_ISR_CMSIS_PRI level (i.e., +// with the numerical values of priorities equal or higher than +// QF_AWARE_ISR_CMSIS_PRI) are allowed to post/publish events or call +// any other QF/QV services. These ISRs are "QF-aware". +// +// Conversely, any ISRs prioritized above the QF_AWARE_ISR_CMSIS_PRI priority +// level (i.e., with the numerical values of priorities less than +// QF_AWARE_ISR_CMSIS_PRI) are never disabled and are not aware of the kernel. +// Such "QF-unaware" ISRs cannot call ANY QF/QV services. In particular they +// can NOT call the macros QV_ISR_ENTRY/QV_ISR_ENTRY. The only mechanism +// by which a "QF-unaware" ISR can communicate with the QF framework is by +// triggering a "QF-aware" ISR, which can post/publish events. +// +// NOTE2: +// The User LED is used to visualize the idle loop activity. The brightness +// of the LED is proportional to the frequency of the idle loop. +// Please note that the LED is toggled with interrupts locked, so no interrupt +// execution time contributes to the brightness of the User LED. +// +// NOTE3: +// The QV_onIdle() callback is called with interrupts disabled, because the +// determination of the idle condition might change by any interrupt posting +// an event. QV_onIdle() must internally enable interrupts, ideally +// atomically with putting the CPU to the power-saving mode. + diff --git a/examples/arm-cm/blinky_efm32-slstk3401a/qv/gnu/Makefile b/examples/arm-cm/dpp_ek-tm4c123gxl_mpu/qv/gnu/Makefile similarity index 88% rename from examples/arm-cm/blinky_efm32-slstk3401a/qv/gnu/Makefile rename to examples/arm-cm/dpp_ek-tm4c123gxl_mpu/qv/gnu/Makefile index 24d184a6..ab3dcdd6 100644 --- a/examples/arm-cm/blinky_efm32-slstk3401a/qv/gnu/Makefile +++ b/examples/arm-cm/dpp_ek-tm4c123gxl_mpu/qv/gnu/Makefile @@ -1,13 +1,13 @@ ############################################################################## -# Product: Makefile for QP/C on EMF32-SLSTK3401A, QV kernel, GNU-ARM -# Last Updated for Version: 7.0.1 -# Date of the Last Update: 2022-05-23 +# Product: Makefile for QP/C on EK-TM4C123GXL, QV kernel, GNU-ARM +# Last Updated for Version: 7.3.0 +# Date of the Last Update: 2023-09-07 # # Q u a n t u m L e a P s # ------------------------ # Modern Embedded Software # -# Copyright (C) 2005-2021 Quantum Leaps, LLC. All rights reserved. +# Copyright (C) 2005 Quantum Leaps, LLC. # # This program is open source software: you can redistribute it and/or # modify it under the terms of the GNU General Public License as published @@ -45,13 +45,12 @@ # NOTE: # To use this Makefile on Windows, you will need the GNU make utility, which # is included in the Qtools collection for Windows, see: -# https://sourceforge.net/projects/qpc/files/QTools/ -# +# https://github.com/QuantumLeaps/qtools #----------------------------------------------------------------------------- # project name # -PROJECT := blinky-qv +PROJECT := dpp-qv #----------------------------------------------------------------------------- # project directories @@ -73,8 +72,8 @@ VPATH = \ $(QPC)/src/qv \ $(QPC)/src/qs \ $(QP_PORT_DIR) \ - $(QPC)/3rd_party/efm32pg1b \ - $(QPC)/3rd_party/efm32pg1b/gnu + $(QPC)/3rd_party/ek-tm4c123gxl \ + $(QPC)/3rd_party/ek-tm4c123gxl/gnu # list of all include directories needed by this project INCLUDES = \ @@ -82,7 +81,7 @@ INCLUDES = \ -I$(QPC)/include \ -I$(QP_PORT_DIR) \ -I$(QPC)/3rd_party/CMSIS/Include \ - -I$(QPC)/3rd_party/efm32pg1b + -I$(QPC)/3rd_party/ek-tm4c123gxl #----------------------------------------------------------------------------- # files @@ -93,14 +92,12 @@ ASM_SRCS := # C source files C_SRCS := \ - blinky.c \ bsp.c \ main.c \ - startup_efm32pg1b.c \ - system_efm32pg1b.c \ - em_cmu.c \ - em_emu.c \ - em_gpio.c + philo.c \ + table.c \ + system_TM4C123GH6PM.c \ + startup_TM4C123GH6PM.c # C++ source files CPP_SRCS := @@ -135,7 +132,9 @@ LIB_DIRS := LIBS := # defines -DEFINES := -DEFM32PG1B200F256GM48=1 +DEFINES := \ + -DQP_CONFIG \ + -DTARGET_IS_TM4C123_RB1 # ARM CPU, ARCH, FPU, and Float-ABI types... # ARM_CPU: [cortex-m0 | cortex-m0plus | cortex-m1 | cortex-m3 | cortex-m4] @@ -165,18 +164,17 @@ AS := $(GNU_ARM)/bin/arm-none-eabi-as LINK := $(GNU_ARM)/bin/arm-none-eabi-gcc BIN := $(GNU_ARM)/bin/arm-none-eabi-objcopy - ############################################################################## -# Typically, you should not need to change anything below this line +# Typically you should not need to change anything below this line -# basic utilities (included in Qtools for Windows), see: -# http://sourceforge.net/projects/qpc/files/Qtools +# basic utilities (included in QTools for Windows), see: +# https://www.state-machine.com/qtools MKDIR := mkdir RM := rm #----------------------------------------------------------------------------- -# build options for various configurations for ARM Cortex-M4F +# build options for various configurations for ARM Cortex-M # # combine all the soruces... @@ -191,11 +189,11 @@ ASFLAGS = $(ARM_CPU) $(ARM_FPU) $(ASM_CPU) $(ASM_FPU) CFLAGS = -c $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \ -ffunction-sections -fdata-sections \ - -O1 $(INCLUDES) $(DEFINES) -DNDEBUG + -O2 $(INCLUDES) $(DEFINES) -DNDEBUG CPPFLAGS = -c $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \ -ffunction-sections -fdata-sections -fno-rtti -fno-exceptions \ - -O1 $(INCLUDES) $(DEFINES) -DNDEBUG + -O2 $(INCLUDES) $(DEFINES) -DNDEBUG else ifeq (spy, $(CONF)) # Spy configuration ................................ @@ -256,14 +254,20 @@ endif # rules # -all: $(TARGET_BIN) -#all: $(TARGET_ELF) +.PHONY : run norun flash clean show + +ifeq ($(MAKECMDGOALS),norun) +all : $(TARGET_BIN) +norun : all +else +all : $(TARGET_BIN) run +endif $(TARGET_BIN): $(TARGET_ELF) $(BIN) -O binary $< $@ $(TARGET_ELF) : $(ASM_OBJS_EXT) $(C_OBJS_EXT) $(CPP_OBJS_EXT) - $(CC) $(CFLAGS) $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o + $(CC) $(CFLAGS) $(QPC)/src/qs/qstamp.c -o $(BIN_DIR)/qstamp.o $(LINK) $(LINKFLAGS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) $(BIN_DIR)/%.d : %.c @@ -289,7 +293,6 @@ ifneq ($(MAKECMDGOALS),clean) endif -.PHONY : clean clean: -$(RM) $(BIN_DIR)/*.o \ $(BIN_DIR)/*.d \ diff --git a/examples/arm-cm/blinky_efm32-slstk3401a/qv/gnu/blinky-qv.ld b/examples/arm-cm/dpp_ek-tm4c123gxl_mpu/qv/gnu/dpp-qv.ld similarity index 95% rename from examples/arm-cm/blinky_efm32-slstk3401a/qv/gnu/blinky-qv.ld rename to examples/arm-cm/dpp_ek-tm4c123gxl_mpu/qv/gnu/dpp-qv.ld index 12002fb8..5139ce62 100644 --- a/examples/arm-cm/blinky_efm32-slstk3401a/qv/gnu/blinky-qv.ld +++ b/examples/arm-cm/dpp_ek-tm4c123gxl_mpu/qv/gnu/dpp-qv.ld @@ -1,5 +1,5 @@ /***************************************************************************** -* Product: Linker script for EFM32-SLSTK3401A, GNU-ARM linker +* Product: Linker script for EK-TM4C123GXL, GNU-ARM linker * Last Updated for Version: 5.9.8 * Date of the Last Update: 2017-09-13 * @@ -28,14 +28,14 @@ * along with this program. If not, see . * * Contact information: -* http://www.state-machine.com -* mailto:info@state-machine.com +* Web : http://www.state-machine.com +* Email: info@state-machine.com *****************************************************************************/ OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm", "elf32-littlearm") OUTPUT_ARCH(arm) ENTRY(Reset_Handler) /* entry Point */ -MEMORY { /* memory map of Pearl Gecko EFM32PG1B200F256GM48 */ +MEMORY { /* memory map of Tiva TM4C123GH6PM */ ROM (rx) : ORIGIN = 0x00000000, LENGTH = 256K RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 32K } diff --git a/examples/arm-cm/dpp_ek-tm4c123gxl_mpu/qv/gnu/flash.bat b/examples/arm-cm/dpp_ek-tm4c123gxl_mpu/qv/gnu/flash.bat new file mode 100644 index 00000000..cb2a3886 --- /dev/null +++ b/examples/arm-cm/dpp_ek-tm4c123gxl_mpu/qv/gnu/flash.bat @@ -0,0 +1,33 @@ +::============================================================================ +:: Batch file to program the flash of EK-TM4C123GXL +:: +:: NOTE: requires the LMFlash programmer (included in QTools for Windows) +:: +@echo off +setlocal + +@echo Load a given binary file to the flash of EK-TM4C123GXL +@echo usage: flash binary-file +@echo example: flash dbg\blinky-qk.bin + +::---------------------------------------------------------------------------- +:: NOTE: The following symbol LMFLASH assumes that LMFlash.exe can +:: be found on the PATH. You might need to adjust this symbol to the +:: location of the LMFlash utility on your machine +:: +set LMFLASH=LMFlash.exe + +if ["%~1"]==[""] ( + @echo The binary file missing + @goto end +) +if not exist %~s1 ( + @echo The binary file '%1' does not exist + @goto end +) + +%LMFLASH% -q ek-tm4c123gxl -e -v -r %1 + +:end + +endlocal \ No newline at end of file diff --git a/examples/arm-cm/dpp_ek-tm4c123gxl_mpu/qv/iar/dpp-qv.ewd b/examples/arm-cm/dpp_ek-tm4c123gxl_mpu/qv/iar/dpp-qv.ewd new file mode 100644 index 00000000..7f745b03 --- /dev/null +++ b/examples/arm-cm/dpp_ek-tm4c123gxl_mpu/qv/iar/dpp-qv.ewd @@ -0,0 +1,4654 @@ + + + 3 + + Debug + + ARM + + 1 + + C-SPY + 2 + + 32 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ARMSIM_ID + 2 + + 1 + 1 + 1 + + + + + + + + CADI_ID + 2 + + 0 + 1 + 1 + + + + + + + + + CMSISDAP_ID + 2 + + 4 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + GDBSERVER_ID + 2 + + 0 + 1 + 1 + + + + + + + + + + + IJET_ID + 2 + + 9 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + JLINK_ID + 2 + + 16 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + LMIFTDI_ID + 2 + + 3 + 1 + 1 + + + + + + + + + + + + + NULINK_ID + 2 + + 0 + 1 + 1 + + + + + + + PEMICRO_ID + 2 + + 3 + 1 + 1 + + + + + + + + STLINK_ID + 2 + + 8 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + THIRDPARTY_ID + 2 + + 0 + 1 + 1 + + + + + + + + TIFET_ID + 2 + + 1 + 1 + 1 + + + + + + + + + + + + + + + + + + + XDS100_ID + 2 + + 9 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + $TOOLKIT_DIR$\plugins\rtos\CMX\CmxArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\CMX\CmxTinyArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\FreeRtos\FreeRtosArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin2.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SafeRTOS\SafeRTOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9BE.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-286-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-III\uCOS-III-KA-CSpy.ewplugin + 0 + + + $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\TargetAccessServer\TargetAccessServer.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\uCProbe\uCProbePlugin.ENU.ewplugin + 0 + + + + + Release + + ARM + + 0 + + C-SPY + 2 + + 32 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ARMSIM_ID + 2 + + 1 + 1 + 0 + + + + + + + + CADI_ID + 2 + + 0 + 1 + 0 + + + + + + + + + CMSISDAP_ID + 2 + + 4 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + GDBSERVER_ID + 2 + + 0 + 1 + 0 + + + + + + + + + + + IJET_ID + 2 + + 9 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + JLINK_ID + 2 + + 16 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + LMIFTDI_ID + 2 + + 3 + 1 + 0 + + + + + + + + + + + + + NULINK_ID + 2 + + 0 + 1 + 0 + + + + + + + PEMICRO_ID + 2 + + 3 + 1 + 0 + + + + + + + + STLINK_ID + 2 + + 8 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + THIRDPARTY_ID + 2 + + 0 + 1 + 0 + + + + + + + + TIFET_ID + 2 + + 1 + 1 + 0 + + + + + + + + + + + + + + + + + + + XDS100_ID + 2 + + 9 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + $TOOLKIT_DIR$\plugins\rtos\CMX\CmxArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\CMX\CmxTinyArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\FreeRtos\FreeRtosArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin2.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SafeRTOS\SafeRTOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9BE.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-286-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-III\uCOS-III-KA-CSpy.ewplugin + 0 + + + $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\TargetAccessServer\TargetAccessServer.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\uCProbe\uCProbePlugin.ENU.ewplugin + 0 + + + + + Spy + + ARM + + 1 + + C-SPY + 2 + + 32 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ARMSIM_ID + 2 + + 1 + 1 + 1 + + + + + + + + CADI_ID + 2 + + 0 + 1 + 1 + + + + + + + + + CMSISDAP_ID + 2 + + 4 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + GDBSERVER_ID + 2 + + 0 + 1 + 1 + + + + + + + + + + + IJET_ID + 2 + + 9 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + JLINK_ID + 2 + + 16 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + LMIFTDI_ID + 2 + + 3 + 1 + 1 + + + + + + + + + + + + + NULINK_ID + 2 + + 0 + 1 + 1 + + + + + + + PEMICRO_ID + 2 + + 3 + 1 + 1 + + + + + + + + STLINK_ID + 2 + + 8 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + THIRDPARTY_ID + 2 + + 0 + 1 + 1 + + + + + + + + TIFET_ID + 2 + + 1 + 1 + 1 + + + + + + + + + + + + + + + + + + + XDS100_ID + 2 + + 9 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + $TOOLKIT_DIR$\plugins\rtos\CMX\CmxArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\CMX\CmxTinyArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\FreeRtos\FreeRtosArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin2.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SafeRTOS\SafeRTOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9BE.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-286-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-III\uCOS-III-KA-CSpy.ewplugin + 0 + + + $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\TargetAccessServer\TargetAccessServer.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\uCProbe\uCProbePlugin.ENU.ewplugin + 0 + + + + diff --git a/examples/arm-cm/dpp_ek-tm4c123gxl_mpu/qv/iar/dpp-qv.ewp b/examples/arm-cm/dpp_ek-tm4c123gxl_mpu/qv/iar/dpp-qv.ewp new file mode 100644 index 00000000..51b7baef --- /dev/null +++ b/examples/arm-cm/dpp_ek-tm4c123gxl_mpu/qv/iar/dpp-qv.ewp @@ -0,0 +1,3364 @@ + + + 3 + + Debug + + ARM + + 1 + + General + 3 + + 35 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ICCARM + 2 + + 37 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + AARM + 2 + + 11 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + OBJCOPY + 0 + + 1 + 1 + 1 + + + + + + + + + CUSTOM + 3 + + + + 0 + inputOutputBased + + + + BUILDACTION + 1 + + cmd /c "if exist $OBJ_DIR$\qstamp.o del $OBJ_DIR$\qstamp.o" + + + + + ILINK + 0 + + 27 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + IARCHIVE + 0 + + 0 + 1 + 1 + + + + + + + Coder + 0 + + + + + Release + + ARM + + 0 + + General + 3 + + 35 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ICCARM + 2 + + 37 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + AARM + 2 + + 11 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + OBJCOPY + 0 + + 1 + 1 + 0 + + + + + + + + + CUSTOM + 3 + + + + 0 + inputOutputBased + + + + BUILDACTION + 1 + + cmd /c "if exist $OBJ_DIR$\qstamp.o del $OBJ_DIR$\qstamp.o" + + + + + ILINK + 0 + + 27 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + IARCHIVE + 0 + + 0 + 1 + 0 + + + + + + + Coder + 0 + + + + + Spy + + ARM + + 1 + + General + 3 + + 35 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ICCARM + 2 + + 37 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + AARM + 2 + + 11 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + OBJCOPY + 0 + + 1 + 1 + 1 + + + + + + + + + CUSTOM + 3 + + + + 0 + inputOutputBased + + + + BUILDACTION + 1 + + cmd /c "if exist $OBJ_DIR$\qstamp.o del $OBJ_DIR$\qstamp.o" + + + + + ILINK + 0 + + 27 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + IARCHIVE + 0 + + 0 + 1 + 1 + + + + + + + Coder + 0 + + + + + Application + + $PROJ_DIR$\..\bsp.c + + + $PROJ_DIR$\..\..\bsp.h + + + $PROJ_DIR$\..\..\dpp.h + + + $PROJ_DIR$\..\..\main.c + + + $PROJ_DIR$\..\..\philo.c + + + $PROJ_DIR$\..\..\table.c + + + + ek-tm4c123gxl + + $PROJ_DIR$\..\..\..\..\..\3rd_party\ek-tm4c123gxl\iar\startup_TM4C123GH6PM.s + + + $PROJ_DIR$\..\..\..\..\..\3rd_party\ek-tm4c123gxl\system_TM4C123GH6PM.c + + + $PROJ_DIR$\..\..\..\..\..\3rd_party\ek-tm4c123gxl\system_TM4C123GH6PM.h + + + $PROJ_DIR$\..\..\..\..\..\3rd_party\ek-tm4c123gxl\TM4C123GH6PM.h + + + + QP + + $PROJ_DIR$\..\..\..\..\..\src\qf\qep_hsm.c + + + $PROJ_DIR$\..\..\..\..\..\src\qf\qep_msm.c + + + $PROJ_DIR$\..\..\..\..\..\src\qf\qf_act.c + + + $PROJ_DIR$\..\..\..\..\..\src\qf\qf_actq.c + + + $PROJ_DIR$\..\..\..\..\..\src\qf\qf_defer.c + + + $PROJ_DIR$\..\..\..\..\..\src\qf\qf_dyn.c + + + $PROJ_DIR$\..\..\..\..\..\src\qf\qf_mem.c + + + $PROJ_DIR$\..\..\..\..\..\src\qf_pkg.h + + + $PROJ_DIR$\..\..\..\..\..\src\qf\qf_ps.c + + + $PROJ_DIR$\..\..\..\..\..\src\qf\qf_qact.c + + + $PROJ_DIR$\..\..\..\..\..\src\qf\qf_qeq.c + + + $PROJ_DIR$\..\..\..\..\..\src\qf\qf_qmact.c + + + $PROJ_DIR$\..\..\..\..\..\src\qf\qf_time.c + + + $PROJ_DIR$\..\..\..\..\..\src\qv\qv.c + + + + QP_port + + $PROJ_DIR$\..\..\..\..\..\ports\arm-cm\qv\iar\qep_port.h + + + $PROJ_DIR$\..\..\..\..\..\ports\arm-cm\qv\iar\qf_port.h + + + $PROJ_DIR$\..\..\..\..\..\ports\arm-cm\qv\iar\qs_port.h + + + $PROJ_DIR$\..\..\..\..\..\ports\arm-cm\qv\iar\qv_port.c + + + $PROJ_DIR$\..\..\..\..\..\ports\arm-cm\qv\iar\qv_port.h + + + + QS + + Debug + Release + + + $PROJ_DIR$\..\..\..\..\..\src\qs\qs.c + + + $PROJ_DIR$\..\..\..\..\..\src\qs\qs_fp.c + + + $PROJ_DIR$\..\..\..\..\..\src\qs\qs_rx.c + + + $PROJ_DIR$\..\..\..\..\..\src\qs\qstamp.c + + + diff --git a/examples/arm-cm/dpp_ek-tm4c123gxl_mpu/qv/iar/dpp-qv.eww b/examples/arm-cm/dpp_ek-tm4c123gxl_mpu/qv/iar/dpp-qv.eww new file mode 100644 index 00000000..b96f3f62 --- /dev/null +++ b/examples/arm-cm/dpp_ek-tm4c123gxl_mpu/qv/iar/dpp-qv.eww @@ -0,0 +1,10 @@ + + + + + $WS_DIR$\dpp-qv.ewp + + + + + diff --git a/examples/arm-cm/blinky_efm32-slstk3401a/qk/iar/blinky-qk.icf b/examples/arm-cm/dpp_ek-tm4c123gxl_mpu/qv/iar/dpp-qv.icf similarity index 91% rename from examples/arm-cm/blinky_efm32-slstk3401a/qk/iar/blinky-qk.icf rename to examples/arm-cm/dpp_ek-tm4c123gxl_mpu/qv/iar/dpp-qv.icf index d62480ce..c6b24e1c 100644 --- a/examples/arm-cm/blinky_efm32-slstk3401a/qk/iar/blinky-qk.icf +++ b/examples/arm-cm/dpp_ek-tm4c123gxl_mpu/qv/iar/dpp-qv.icf @@ -25,5 +25,5 @@ do not initialize { section .noinit }; place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec }; place in ROM_region { readonly }; -place at start of RAM_region {block CSTACK }; -place in RAM_region { readwrite, block HEAP }; +place at start of RAM_region {block CSTACK }; /* <== Quantum Leaps */ +place in RAM_region { readwrite, block HEAP }; \ No newline at end of file diff --git a/examples/arm-cm/dpp_ek-tm4c123gxl_mpu/qview/dpp.py b/examples/arm-cm/dpp_ek-tm4c123gxl_mpu/qview/dpp.py new file mode 100644 index 00000000..73c51654 --- /dev/null +++ b/examples/arm-cm/dpp_ek-tm4c123gxl_mpu/qview/dpp.py @@ -0,0 +1,103 @@ +# This is an example of QView customization for a specific application +# (DPP in this case). This example animates the Phil images on the +# QView canvas. Additionally, there is a button in the middle of the screen, +# which, when clicked once pauses the DPP ("forks" are not being served). +# A second click on the button, "un-pauses" the DPP ("forks" are served +# to all hungry Philosophers). +# +# This version of the DPP customization uses the application-specific +# trace record QS_USER_00 (PHILO_STAT) produced when the status of +# a Philo changes. + +class DPP: + def __init__(self): + + # add commands to the Custom menu... + QView.custom_menu.add_command(label="Custom command", + command=self.cust_command) + + # configure the custom QView.canvas... + QView.show_canvas() # make the canvas visible + QView.canvas.configure(width=400, height=260) + + # tuple of activity images (correspond to self._philo_state) + self._act_img = ( + PhotoImage(file=HOME_DIR + "/img/thinking.gif"), + PhotoImage(file=HOME_DIR + "/img/hungry.gif"), + PhotoImage(file=HOME_DIR + "/img/eating.gif"), + ) + # tuple of philo canvas images (correspond to self._philo_obj) + self._philo_img = (\ + QView.canvas.create_image(190, 57, image=self._act_img[0]), + QView.canvas.create_image(273, 100, image=self._act_img[0]), + QView.canvas.create_image(237, 185, image=self._act_img[0]), + QView.canvas.create_image(146, 185, image=self._act_img[0]), + QView.canvas.create_image(107, 100, image=self._act_img[0]) + ) + + # button images for UP and DOWN + self.img_UP = PhotoImage(file=HOME_DIR + "/img/BTN_UP.gif") + self.img_DWN = PhotoImage(file=HOME_DIR + "/img/BTN_DWN.gif") + + # images of a button for pause/serve + self.btn = QView.canvas.create_image(200, 120, image=self.img_UP) + QView.canvas.tag_bind(self.btn, "", self.cust_pause) + + # request target reset on startup... + # NOTE: Normally, for an embedded application you would like + # to start with resetting the Target, to start clean with + # Qs dictionaries, etc. + reset_target() + + # on_reset() callback + def on_reset(self): + # clear the lists + self._philo_obj = [0, 0, 0, 0, 0] + self._philo_state = [0, 0, 0] + + # on_run() callback + def on_run(self): + glb_filter("QS_USER_00") + + # NOTE: the names of objects for current_obj() must match + # the QS Object Dictionaries produced by the application. + current_obj(OBJ_AO, "Table_inst") + + # turn lists into tuples for better performance + self._philo_obj = tuple(self._philo_obj) + self._philo_state = tuple(self._philo_state) + + + # example of a custom command + def cust_command(self): + command(1, 12345) + + # example of a custom interaction with a canvas object (pause/serve) + def cust_pause(self, event): + if QView.canvas.itemcget(self.btn, "image") != str(self.img_UP): + QView.canvas.itemconfig(self.btn, image=self.img_UP) + post("SERVE_SIG") + QView.print_text("Table SERVING") + else: + QView.canvas.itemconfig(self.btn, image=self.img_DWN) + post("PAUSE_SIG") + QView.print_text("Table PAUSED") + + # Intercept the QS_USER_00 application-specific trace record. + # This record has the following structure (see bsp.c:displayPhilStat()): + # Seq-Num, Record-ID, Timestamp, format-byte, Philo-num, + # format-byte, Zero-terminated string (status) + def QS_USER_00(self, packet): + # unpack: Timestamp->data[0], Philo-num->data[1], status->data[3] + data = qunpack("xxTxBxZ", packet) + i = data[1] + j = ("t", "h", "e").index(data[2][0]) # the first letter + + # animate the given philo image according to its activity + QView.canvas.itemconfig(self._philo_img[i], image=self._act_img[j]) + + # print a message to the text view + QView.print_text("%010d Philo %1d is %s"%(data[0], i, data[2])) + +#============================================================================= +QView.customize(DPP()) # set the QView customization diff --git a/examples/arm-cm/dpp_ek-tm4c123gxl_mpu/qview/dpp1.py b/examples/arm-cm/dpp_ek-tm4c123gxl_mpu/qview/dpp1.py new file mode 100644 index 00000000..d93f7b6d --- /dev/null +++ b/examples/arm-cm/dpp_ek-tm4c123gxl_mpu/qview/dpp1.py @@ -0,0 +1,147 @@ +# This is an example of QView customization for a specific application +# (DPP in this case). This example animates the Phil images on the +# QView canvas. Additionally, there is a button in the middle of the screen, +# which, when clicked once pauses the DPP ("forks" are not being served). +# A second click on the button, "un-pauses" the DPP ("forks" are served +# to all hungry Philosophers). +# +# This version of the DPP customization uses the predefined QS_QEP_TRAN +# trace record, which provides information about the state transitions of +# the Dining Philosophers. The example also demonstrates how to intercept +# the QS "dictionary" records QS_OBJ_DICT and QS_FUN_DICT to extract the +# information about the addresses of the Philosopher objects and the states +# of their state machines. + +class DPP: + def __init__(self): + + # add commands to the Custom menu... + QView.custom_menu.add_command(label="Custom command", + command=self.cust_command) + + # configure the custom QView.canvas... + QView.show_canvas() # make the canvas visible + QView.canvas.configure(width=400, height=260) + + # tuple of activity images (correspond to self._philo_state) + self._act_img = ( + PhotoImage(file=HOME_DIR + "/img/thinking.gif"), + PhotoImage(file=HOME_DIR + "/img/hungry.gif"), + PhotoImage(file=HOME_DIR + "/img/eating.gif"), + ) + # tuple of philo canvas images (correspond to self._philo_obj) + self._philo_img = (\ + QView.canvas.create_image(190, 57, image=self._act_img[0]), + QView.canvas.create_image(273, 100, image=self._act_img[0]), + QView.canvas.create_image(237, 185, image=self._act_img[0]), + QView.canvas.create_image(146, 185, image=self._act_img[0]), + QView.canvas.create_image(107, 100, image=self._act_img[0]) + ) + + # button images for UP and DOWN + self.img_UP = PhotoImage(file=HOME_DIR + "/img/BTN_UP.gif") + self.img_DWN = PhotoImage(file=HOME_DIR + "/img/BTN_DWN.gif") + + # images of a button for pause/serve + self.btn = QView.canvas.create_image(200, 120, image=self.img_UP) + QView.canvas.tag_bind(self.btn, "", self.cust_pause) + + # request target reset on startup... + # NOTE: Normally, for an embedded application you would like + # to start with resetting the Target, to start clean with + # Qs dictionaries, etc. + reset_target() + + + # on_reset() callback invoked when Target-reset packet is received + # NOTE: the QS dictionaries are not known at this time yet, so + # this callback shouild generally not set filters or current objects + def on_reset(self): + # (re)set the lists + self._philo_obj = [0, 0, 0, 0, 0] + self._philo_state = [0, 0, 0] + + # on_run() callback invoked when the QF_RUN packet is received + # NOTE: the QS dictionaries are typically known at this time yet, so + # this callback can set filters or current objects + def on_run(self): + glb_filter("QS_QEP_TRAN") + + # NOTE: the names of objects for current_obj() must match + # the QS Object Dictionaries produced by the application. + current_obj(OBJ_AO, "Table_inst") + + # turn lists into tuples for better performance + self._philo_obj = tuple(self._philo_obj) + self._philo_state = tuple(self._philo_state) + + + # example of a custom command + def cust_command(self): + command(1, 12345) + + # example of a custom interaction with a canvas object (pause/serve) + def cust_pause(self, event): + if QView.canvas.itemcget(self.btn, "image") != str(self.img_UP): + QView.canvas.itemconfig(self.btn, image=self.img_UP) + post("SERVE_SIG") + QView.print_text("Table SERVING") + else: + QView.canvas.itemconfig(self.btn, image=self.img_DWN) + post("PAUSE_SIG") + QView.print_text("Table PAUSED") + + # Intercept the QS_OBJ_DICT predefined trace record. + # This record has the following structure: + # Seq-Num, Record-ID, Object-ptr, Zero-terminated string + def QS_OBJ_DICT(self, packet): + data = qunpack("xxOZ", packet) + try: + # NOTE: the names of objects must match the QS Object Dictionaries + # produced by the application. + i = ("Philo_inst[0]", + "Philo_inst[1]", + "Philo_inst[2]", + "Philo_inst[3]", + "Philo_inst[4]").index(data[1]) + self._philo_obj[i] = data[0] + except: + pass # dictionary for a different object + + # Intercept the QS_FUN_DICT predefined trace record. + # This record has the following structure: + # Seq-Num, Record-ID, Function-ptr, Zero-terminated string + def QS_FUN_DICT(self, packet): + data = qunpack("xxFZ", packet) + try: + # NOTE: the names of states must match the QS Object Dictionaries + # produced by the application. + j = ("Philo_thinking", + "Philo_hungry", + "Philo_eating").index(data[1]) + self._philo_state[j] = data[0] + except: + pass # dictionary for a different state + + # Intercept the QS_QEP_TRAN predefined trace record. + # This record has the following structure (see qep_hsm.c): + # Seq-Num, Record-ID, Timestamp, Signal, Object-ptr, + # Function-ptr (source state), Function-ptr (new active state) + def QS_QEP_TRAN(self, packet): + data = qunpack("xxTSOFF", packet) + try: + i = self._philo_obj.index(data[2]) + j = self._philo_state.index(data[4]) + + # animate the given philo image according to its activity + QView.canvas.itemconfig(self._philo_img[i], + image=self._act_img[j]) + # print a message to the text view + QView.print_text("%010d Philo %d is %s"\ + %(data[0], i, ("thinking", "hungry", "eating")[j])) + except: + pass # state-entry in a different object + +#============================================================================= +# instantiate the DPP class and set it as the QView customization +QView.customize(DPP()) diff --git a/examples/workstation/dpp/qview/img/BTN_DWN.gif b/examples/arm-cm/dpp_ek-tm4c123gxl_mpu/qview/img/BTN_DWN.gif similarity index 100% rename from examples/workstation/dpp/qview/img/BTN_DWN.gif rename to examples/arm-cm/dpp_ek-tm4c123gxl_mpu/qview/img/BTN_DWN.gif diff --git a/examples/workstation/dpp/qview/img/BTN_UP.gif b/examples/arm-cm/dpp_ek-tm4c123gxl_mpu/qview/img/BTN_UP.gif similarity index 100% rename from examples/workstation/dpp/qview/img/BTN_UP.gif rename to examples/arm-cm/dpp_ek-tm4c123gxl_mpu/qview/img/BTN_UP.gif diff --git a/examples/workstation/dpp/qview/img/eating.gif b/examples/arm-cm/dpp_ek-tm4c123gxl_mpu/qview/img/eating.gif similarity index 100% rename from examples/workstation/dpp/qview/img/eating.gif rename to examples/arm-cm/dpp_ek-tm4c123gxl_mpu/qview/img/eating.gif diff --git a/examples/workstation/dpp/qview/img/hungry.gif b/examples/arm-cm/dpp_ek-tm4c123gxl_mpu/qview/img/hungry.gif similarity index 100% rename from examples/workstation/dpp/qview/img/hungry.gif rename to examples/arm-cm/dpp_ek-tm4c123gxl_mpu/qview/img/hungry.gif diff --git a/examples/workstation/dpp/qview/img/thinking.gif b/examples/arm-cm/dpp_ek-tm4c123gxl_mpu/qview/img/thinking.gif similarity index 100% rename from examples/workstation/dpp/qview/img/thinking.gif rename to examples/arm-cm/dpp_ek-tm4c123gxl_mpu/qview/img/thinking.gif diff --git a/examples/workstation/dpp/qview/qview-dpp.bat b/examples/arm-cm/dpp_ek-tm4c123gxl_mpu/qview/qview-dpp.bat similarity index 100% rename from examples/workstation/dpp/qview/qview-dpp.bat rename to examples/arm-cm/dpp_ek-tm4c123gxl_mpu/qview/qview-dpp.bat diff --git a/examples/arm-cm/dpp_ek-tm4c123gxl_mpu/qview/qview-dpp.lnk b/examples/arm-cm/dpp_ek-tm4c123gxl_mpu/qview/qview-dpp.lnk new file mode 100644 index 00000000..4646d6e5 Binary files /dev/null and b/examples/arm-cm/dpp_ek-tm4c123gxl_mpu/qview/qview-dpp.lnk differ diff --git a/examples/workstation/dpp/qview/qview-dpp1.bat b/examples/arm-cm/dpp_ek-tm4c123gxl_mpu/qview/qview-dpp1.bat similarity index 100% rename from examples/workstation/dpp/qview/qview-dpp1.bat rename to examples/arm-cm/dpp_ek-tm4c123gxl_mpu/qview/qview-dpp1.bat diff --git a/examples/arm-cm/dpp_ek-tm4c123gxl_mpu/qview/qview-dpp1.lnk b/examples/arm-cm/dpp_ek-tm4c123gxl_mpu/qview/qview-dpp1.lnk new file mode 100644 index 00000000..2d2dc49d Binary files /dev/null and b/examples/arm-cm/dpp_ek-tm4c123gxl_mpu/qview/qview-dpp1.lnk differ diff --git a/examples/arm-cm/dpp_ek-tm4c123gxl_mpu/qxk/armclang/dpp-qxk.sct b/examples/arm-cm/dpp_ek-tm4c123gxl_mpu/qxk/armclang/dpp-qxk.sct new file mode 100644 index 00000000..fda39c74 --- /dev/null +++ b/examples/arm-cm/dpp_ek-tm4c123gxl_mpu/qxk/armclang/dpp-qxk.sct @@ -0,0 +1,23 @@ +; ************************************************************* +; *** Scatter-Loading Description File generated by uVision *** +; +; Modified by Quantum Leaps: +; added STACK as the first section in RW_STACK +; ************************************************************* + +LR_IROM1 0x00000000 0x00040000 { ; load region size_region + ER_IROM1 0x00000000 0x00040000 { ; load address = execution address + *.o (RESET, +First) + *(InRoot$$Sections) + .ANY (+RO) + .ANY (+XO) + } + + RW_STACK 0x20000000 { ; <== Quantum Leaps + * (STACK, +First) + } + RW_IRAM1 +0 (0x00008000 - 2048) { ; NOTE: 2048 assumeed STACK size! + .ANY (+RW +ZI) + } +} + diff --git a/examples/arm-cm/dpp_ek-tm4c123gxl_mpu/qxk/armclang/dpp-qxk.uvoptx b/examples/arm-cm/dpp_ek-tm4c123gxl_mpu/qxk/armclang/dpp-qxk.uvoptx new file mode 100644 index 00000000..11bcdd5e --- /dev/null +++ b/examples/arm-cm/dpp_ek-tm4c123gxl_mpu/qxk/armclang/dpp-qxk.uvoptx @@ -0,0 +1,1123 @@ + + + + 1.0 + +
### uVision Project, (C) Keil Software
+ + + *.c + *.s*; *.src; *.a* + *.obj; *.o + *.lib + *.txt; *.h; *.inc; *.md + *.plm + *.cpp + 0 + + + + 0 + 0 + + + + dpp-dbg + 0x4 + ARM-ADS + + 12000000 + + 1 + 1 + 1 + 0 + 0 + + + 1 + 65535 + 0 + 0 + 0 + + + 79 + 66 + 8 + .\dbg\ + + + 1 + 1 + 1 + 0 + 1 + 1 + 0 + 1 + 0 + 0 + 0 + 0 + + + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + + + 1 + 0 + 1 + + 4 + + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + 0 + 1 + 1 + 0 + 0 + 1 + 0 + 0 + 19 + + + + + + + + + + + BIN\lmidk-agdi.dll + + + + 0 + ARMRTXEVENTFLAGS + -L70 -Z18 -C0 -M0 -T1 + + + 0 + UL2CM3 + UL2CM3(-O207 -S0 -C0 -FO7 -FN1 -FC1000 -FD20000000 -FF0TM4C123_256 -FL040000 -FS00 -FP0($$Device:TM4C123GH6PM$Flash\TM4C123_256.FLM) + + + 0 + DLGTARM + (1010=-1,-1,-1,-1,0)(1007=-1,-1,-1,-1,0)(1008=-1,-1,-1,-1,0)(1009=-1,-1,-1,-1,0)(1012=3231,468,3708,783,1) + + + 0 + ARMDBGFLAGS + + + + 0 + lmidk-agdi + -U0E2006F4 -O4623 -S4 -FO61 + + + + + 0 + 0 + 319 + 1 +
1108
+ 0 + 0 + 0 + 0 + 0 + 1 + ..\..\..\..\..\3rd_party\ek-tm4c123gxl\arm\startup_TM4C123GH6PM.s + + \\dpp_qxk\../../../../../3rd_party/ek-tm4c123gxl/arm/startup_TM4C123GH6PM.s\319 +
+ + 1 + 0 + 304 + 1 +
1084
+ 0 + 0 + 0 + 0 + 0 + 1 + ..\..\..\..\..\3rd_party\ek-tm4c123gxl\arm\startup_TM4C123GH6PM.s + + \\dpp_qxk\../../../../../3rd_party/ek-tm4c123gxl/arm/startup_TM4C123GH6PM.s\304 +
+
+ + + 0 + 1 + MPU_Test2 + + + + + 1 + 2 + 0x20000790 + 0 + + + + + 2 + 0 + 0x400 + 0 + + + + 0 + + + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + + + + 0 + 0 + 0 + + + + + + + + +
+
+ + + dpp-rel + 0x4 + ARM-ADS + + 12000000 + + 1 + 1 + 1 + 0 + 0 + + + 1 + 65535 + 0 + 0 + 0 + + + 79 + 66 + 8 + .\rel\ + + + 1 + 1 + 1 + 0 + 1 + 1 + 0 + 1 + 0 + 0 + 0 + 0 + + + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + + + 1 + 0 + 0 + + 4 + + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + 1 + 1 + 0 + 1 + 0 + 1 + 1 + 0 + 0 + 1 + 0 + 0 + 19 + + + + + + + + + + + BIN\lmidk-agdi.dll + + + + 0 + DLGUARM + ÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÈ`» +´­­ª¤ô + + + 0 + ARMRTXEVENTFLAGS + -L70 -Z18 -C0 -M0 -T1 + + + 0 + DLGTARM + (1010=-1,-1,-1,-1,0)(1007=-1,-1,-1,-1,0)(1008=-1,-1,-1,-1,0)(1009=-1,-1,-1,-1,0)(1012=-1,-1,-1,-1,0) + + + 0 + ARMDBGFLAGS + + + + 0 + lmidk-agdi + -U0E10259B -O4622 -S4 -FO61 + + + 0 + UL2CM3 + -O207 -S0 -C0 -FO7 -FN1 -FC1000 -FD20000000 -FF0TM4C123_256 -FL040000 -FS00 -FP0($$Device:TM4C123GH6PM$Flash\TM4C123_256.FLM) + + + + + + 1 + 2 + 0x20000200 + 0 + + + + + 2 + 0 + 0x400 + 0 + + + + 0 + + + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + + + + 0 + 0 + 0 + + + + + + + + + + + + + dpp-spy + 0x4 + ARM-ADS + + 12000000 + + 1 + 1 + 1 + 0 + 0 + + + 1 + 65535 + 0 + 0 + 0 + + + 79 + 66 + 8 + .\spy\ + + + 1 + 1 + 1 + 0 + 1 + 1 + 0 + 1 + 0 + 0 + 0 + 0 + + + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + + + 1 + 0 + 0 + + 4 + + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + 1 + 1 + 0 + 1 + 0 + 1 + 1 + 0 + 0 + 1 + 0 + 0 + 19 + + + + + + + + + + + BIN\lmidk-agdi.dll + + + + 0 + ARMRTXEVENTFLAGS + -L70 -Z18 -C0 -M0 -T1 + + + 0 + UL2CM3 + UL2CM3(-O207 -S0 -C0 -FO7 -FN1 -FC1000 -FD20000000 -FF0TM4C123_256 -FL040000 -FS00 -FP0($$Device:TM4C123GH6PM$Flash\TM4C123_256.FLM) + + + 0 + DLGTARM + (1010=-1,-1,-1,-1,0)(1007=-1,-1,-1,-1,0)(1008=-1,-1,-1,-1,0)(1009=-1,-1,-1,-1,0)(1012=3213,663,3690,978,1) + + + 0 + ARMDBGFLAGS + + + + 0 + lmidk-agdi + -U0E2006F4 -O4622 -S4 -FO61 + + + + + 0 + 0 + 319 + 1 +
1112
+ 0 + 0 + 0 + 0 + 0 + 1 + ..\..\..\..\..\3rd_party\ek-tm4c123gxl\arm\startup_TM4C123GH6PM.s + + \\dpp_qxk\../../../../../3rd_party/ek-tm4c123gxl/arm/startup_TM4C123GH6PM.s\319 +
+
+ + + 1 + 2 + 0x20000200 + 0 + + + + + 2 + 0 + 0x400 + 0 + + + + 0 + + + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + + + + 0 + 0 + 0 + + + + + + + + +
+
+ + + Applicatioin + 1 + 0 + 0 + 0 + + 1 + 1 + 1 + 0 + 0 + 0 + ..\bsp.c + bsp.c + 0 + 0 + + + 1 + 2 + 5 + 0 + 0 + 0 + ..\..\dpp.h + dpp.h + 0 + 0 + + + 1 + 3 + 5 + 0 + 0 + 0 + ..\..\bsp.h + bsp.h + 0 + 0 + + + 1 + 4 + 1 + 0 + 0 + 0 + ..\..\philo.c + philo.c + 0 + 0 + + + 1 + 5 + 1 + 0 + 0 + 0 + ..\..\table.c + table.c + 0 + 0 + + + 1 + 6 + 1 + 0 + 0 + 0 + ..\xthread1.c + xthread1.c + 0 + 0 + + + 1 + 7 + 1 + 0 + 0 + 0 + ..\xthread2.c + xthread2.c + 0 + 0 + + + 1 + 8 + 1 + 0 + 0 + 0 + ..\..\main.c + main.c + 0 + 0 + + + + + ek-tm4c123gxl + 1 + 0 + 0 + 0 + + 2 + 9 + 2 + 0 + 0 + 0 + ..\..\..\..\..\3rd_party\ek-tm4c123gxl\arm\startup_TM4C123GH6PM.s + startup_TM4C123GH6PM.s + 0 + 0 + + + 2 + 10 + 1 + 0 + 0 + 0 + ..\..\..\..\..\3rd_party\ek-tm4c123gxl\system_TM4C123GH6PM.c + system_TM4C123GH6PM.c + 0 + 0 + + + 2 + 11 + 5 + 0 + 0 + 0 + ..\..\..\..\..\3rd_party\ek-tm4c123gxl\TM4C123GH6PM.h + TM4C123GH6PM.h + 0 + 0 + + + 2 + 12 + 5 + 0 + 0 + 0 + ..\..\..\..\..\3rd_party\ek-tm4c123gxl\gpio.h + gpio.h + 0 + 0 + + + 2 + 13 + 5 + 0 + 0 + 0 + ..\..\..\..\..\3rd_party\ek-tm4c123gxl\rom.h + rom.h + 0 + 0 + + + 2 + 14 + 5 + 0 + 0 + 0 + ..\..\..\..\..\3rd_party\ek-tm4c123gxl\sysctl.h + sysctl.h + 0 + 0 + + + 2 + 15 + 5 + 0 + 0 + 0 + ..\..\..\..\..\3rd_party\ek-tm4c123gxl\system_TM4C123GH6PM.h + system_TM4C123GH6PM.h + 0 + 0 + + + + + QP + 1 + 0 + 0 + 0 + + 3 + 16 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qf\qep_hsm.c + qep_hsm.c + 0 + 0 + + + 3 + 17 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qf\qep_msm.c + qep_msm.c + 0 + 0 + + + 3 + 18 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qf\qf_act.c + qf_act.c + 0 + 0 + + + 3 + 19 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qf\qf_actq.c + qf_actq.c + 0 + 0 + + + 3 + 20 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qf\qf_defer.c + qf_defer.c + 0 + 0 + + + 3 + 21 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qf\qf_dyn.c + qf_dyn.c + 0 + 0 + + + 3 + 22 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qf\qf_mem.c + qf_mem.c + 0 + 0 + + + 3 + 23 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qf\qf_ps.c + qf_ps.c + 0 + 0 + + + 3 + 24 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qf\qf_qact.c + qf_qact.c + 0 + 0 + + + 3 + 25 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qf\qf_qeq.c + qf_qeq.c + 0 + 0 + + + 3 + 26 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qf\qf_qmact.c + qf_qmact.c + 0 + 0 + + + 3 + 27 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qf\qf_time.c + qf_time.c + 0 + 0 + + + 3 + 28 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qxk\qxk.c + qxk.c + 0 + 0 + + + 3 + 29 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qxk\qxk_mutex.c + qxk_mutex.c + 0 + 0 + + + 3 + 30 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qxk\qxk_sema.c + qxk_sema.c + 0 + 0 + + + 3 + 31 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qxk\qxk_xthr.c + qxk_xthr.c + 0 + 0 + + + + + QP_port + 1 + 0 + 0 + 0 + + 4 + 32 + 1 + 0 + 0 + 0 + ..\..\..\..\..\ports\arm-cm\qxk\armclang\qxk_port.c + qxk_port.c + 0 + 0 + + + + + QS + 1 + 0 + 0 + 0 + + 5 + 33 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qs\qs.c + qs.c + 0 + 0 + + + 5 + 34 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qs\qs_64bit.c + qs_64bit.c + 0 + 0 + + + 5 + 35 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qs\qs_fp.c + qs_fp.c + 0 + 0 + + + 5 + 36 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qs\qs_rx.c + qs_rx.c + 0 + 0 + + + 5 + 37 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qs\qstamp.c + qstamp.c + 0 + 0 + + + +
diff --git a/examples/arm-cm/dpp_ek-tm4c123gxl_mpu/qxk/armclang/dpp-qxk.uvprojx b/examples/arm-cm/dpp_ek-tm4c123gxl_mpu/qxk/armclang/dpp-qxk.uvprojx new file mode 100644 index 00000000..4b8499d2 --- /dev/null +++ b/examples/arm-cm/dpp_ek-tm4c123gxl_mpu/qxk/armclang/dpp-qxk.uvprojx @@ -0,0 +1,1913 @@ + + + + 2.1 + +
### uVision Project, (C) Keil Software
+ + + + dpp-dbg + 0x4 + ARM-ADS + 6160000::V6.16::ARMCLANG + 1 + + + TM4C123GH6PM + Texas Instruments + Keil.TM4C_DFP.1.1.0 + http://www.keil.com/pack/ + IROM(0x00000000,0x040000) IRAM(0x20000000,0x008000) CPUTYPE("Cortex-M4") FPU2 CLOCK(12000000) ELITTLE + + + UL2CM3(-S0 -C0 -P0 -FD20000000 -FC1000 -FN1 -FF0TM4C123_256 -FS00 -FL040000 -FP0($$Device:TM4C123GH6PM$Flash\TM4C123_256.FLM)) + 0 + $$Device:TM4C123GH6PM$Device\Include\TM4C123\TM4C123.h + + + + + + + + + + $$Device:TM4C123GH6PM$SVD\TM4C123\TM4C123GH6PM.svd + 0 + 0 + + + + + + + 0 + 0 + 0 + 0 + 1 + + .\dbg\ + dpp-qxk + 1 + 0 + 0 + 1 + 1 + .\dbg\ + 1 + 0 + 0 + + 0 + 0 + + + 0 + 0 + 0 + 0 + + + 1 + 0 + cmd /c "del .\dbg\qstamp.o" + + 0 + 0 + 0 + 0 + + + 1 + 0 + fromelf --bin --output .\dbg\dpp-qxk.bin .\dbg\dpp-qxk.axf + + 0 + 0 + 0 + 0 + + 1 + + + + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 3 + + + 1 + + + SARMCM3.DLL + -MPU + DCM.DLL + -pCM4 + SARMCM3.DLL + -MPU + TCM.DLL + -pCM4 + + + + 1 + 0 + 0 + 0 + 16 + + + + + 1 + 0 + 0 + 1 + 1 + 4097 + + 1 + BIN\UL2CM3.DLL + + + + + + 0 + + + + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + 1 + 0 + 0 + 0 + 0 + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + "Cortex-M4" + + 0 + 0 + 0 + 1 + 1 + 0 + 0 + 2 + 0 + 0 + 0 + 0 + 8 + 0 + 0 + 0 + 0 + 3 + 3 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 1 + 0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x20000000 + 0x8000 + + + 1 + 0x0 + 0x40000 + + + 0 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x40000 + + + 1 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x20000000 + 0x8000 + + + 0 + 0x0 + 0x0 + + + + + + 0 + 1 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 3 + 0 + 1 + 0 + 0 + 0 + 3 + 3 + 0 + 0 + 0 + 0 + 0 + + + QP_CONFIG + + ..\..;..\..\..\..\..\include;..\..\..\..\..\ports\arm-cm\qxk\armclang;..\..\..\..\..\3rd_party\CMSIS\Include;..\..\..\..\..\3rd_party\ek-tm4c123gxl + + + + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 4 + + + Stack_Size=2048 Heap_Size=16 + + + + + + 0 + 0 + 0 + 0 + 1 + 0 + 0x00000000 + 0x20000000 + + .\dpp-qxk.sct + + + --entry Reset_Handler + + + + + + + + Applicatioin + + + bsp.c + 1 + ..\bsp.c + + + dpp.h + 5 + ..\..\dpp.h + + + bsp.h + 5 + ..\..\bsp.h + + + philo.c + 1 + ..\..\philo.c + + + table.c + 1 + ..\..\table.c + + + xthread1.c + 1 + ..\xthread1.c + + + xthread2.c + 1 + ..\xthread2.c + + + main.c + 1 + ..\..\main.c + + + + + ek-tm4c123gxl + + + startup_TM4C123GH6PM.s + 2 + ..\..\..\..\..\3rd_party\ek-tm4c123gxl\arm\startup_TM4C123GH6PM.s + + + system_TM4C123GH6PM.c + 1 + ..\..\..\..\..\3rd_party\ek-tm4c123gxl\system_TM4C123GH6PM.c + + + TM4C123GH6PM.h + 5 + ..\..\..\..\..\3rd_party\ek-tm4c123gxl\TM4C123GH6PM.h + + + gpio.h + 5 + ..\..\..\..\..\3rd_party\ek-tm4c123gxl\gpio.h + + + rom.h + 5 + ..\..\..\..\..\3rd_party\ek-tm4c123gxl\rom.h + + + sysctl.h + 5 + ..\..\..\..\..\3rd_party\ek-tm4c123gxl\sysctl.h + + + system_TM4C123GH6PM.h + 5 + ..\..\..\..\..\3rd_party\ek-tm4c123gxl\system_TM4C123GH6PM.h + + + + + QP + + + qep_hsm.c + 1 + ..\..\..\..\..\src\qf\qep_hsm.c + + + qep_msm.c + 1 + ..\..\..\..\..\src\qf\qep_msm.c + + + qf_act.c + 1 + ..\..\..\..\..\src\qf\qf_act.c + + + qf_actq.c + 1 + ..\..\..\..\..\src\qf\qf_actq.c + + + qf_defer.c + 1 + ..\..\..\..\..\src\qf\qf_defer.c + + + qf_dyn.c + 1 + ..\..\..\..\..\src\qf\qf_dyn.c + + + qf_mem.c + 1 + ..\..\..\..\..\src\qf\qf_mem.c + + + qf_ps.c + 1 + ..\..\..\..\..\src\qf\qf_ps.c + + + qf_qact.c + 1 + ..\..\..\..\..\src\qf\qf_qact.c + + + qf_qeq.c + 1 + ..\..\..\..\..\src\qf\qf_qeq.c + + + qf_qmact.c + 1 + ..\..\..\..\..\src\qf\qf_qmact.c + + + qf_time.c + 1 + ..\..\..\..\..\src\qf\qf_time.c + + + qxk.c + 1 + ..\..\..\..\..\src\qxk\qxk.c + + + qxk_mutex.c + 1 + ..\..\..\..\..\src\qxk\qxk_mutex.c + + + qxk_sema.c + 1 + ..\..\..\..\..\src\qxk\qxk_sema.c + + + qxk_xthr.c + 1 + ..\..\..\..\..\src\qxk\qxk_xthr.c + + + + + QP_port + + + qxk_port.c + 1 + ..\..\..\..\..\ports\arm-cm\qxk\armclang\qxk_port.c + + + + + QS + + + 0 + 0 + 0 + 0 + 0 + 0 + 2 + 2 + 2 + 2 + 11 + + + 1 + + + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 0 + 0 + 0 + 0 + 2 + + + + + + + + + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + + + + + + + + + + + + qs.c + 1 + ..\..\..\..\..\src\qs\qs.c + + + qs_64bit.c + 1 + ..\..\..\..\..\src\qs\qs_64bit.c + + + qs_fp.c + 1 + ..\..\..\..\..\src\qs\qs_fp.c + + + qs_rx.c + 1 + ..\..\..\..\..\src\qs\qs_rx.c + + + qstamp.c + 1 + ..\..\..\..\..\src\qs\qstamp.c + + + + + + + dpp-rel + 0x4 + ARM-ADS + 6160000::V6.16::ARMCLANG + 1 + + + TM4C123GH6PM + Texas Instruments + Keil.TM4C_DFP.1.1.0 + http://www.keil.com/pack/ + IROM(0x00000000,0x040000) IRAM(0x20000000,0x008000) CPUTYPE("Cortex-M4") FPU2 CLOCK(12000000) ELITTLE + + + UL2CM3(-S0 -C0 -P0 -FD20000000 -FC1000 -FN1 -FF0TM4C123_256 -FS00 -FL040000 -FP0($$Device:TM4C123GH6PM$Flash\TM4C123_256.FLM)) + 0 + $$Device:TM4C123GH6PM$Device\Include\TM4C123\TM4C123.h + + + + + + + + + + $$Device:TM4C123GH6PM$SVD\TM4C123\TM4C123GH6PM.svd + 0 + 0 + + + + + + + 0 + 0 + 0 + 0 + 1 + + .\rel\ + dpp-qxk + 1 + 0 + 0 + 0 + 0 + .\rel\ + 1 + 0 + 0 + + 0 + 0 + + + 0 + 0 + 0 + 0 + + + 1 + 0 + cmd /c "del .\rel\qstamp.o" + + 0 + 0 + 0 + 0 + + + 1 + 0 + fromelf --bin --output .\rel\dpp-qxk.bin .\rel\dpp-qxk.axf + + 0 + 0 + 0 + 0 + + 1 + + + + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 3 + + + 1 + + + SARMCM3.DLL + -MPU + DCM.DLL + -pCM4 + SARMCM3.DLL + -MPU + TCM.DLL + -pCM4 + + + + 1 + 0 + 0 + 0 + 16 + + + + + 1 + 0 + 0 + 1 + 1 + 4097 + + 1 + BIN\UL2CM3.DLL + + + + + + 0 + + + + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + 1 + 0 + 0 + 0 + 0 + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + "Cortex-M4" + + 0 + 0 + 0 + 1 + 1 + 0 + 0 + 2 + 0 + 0 + 0 + 0 + 8 + 0 + 0 + 0 + 0 + 3 + 3 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 1 + 0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x20000000 + 0x8000 + + + 1 + 0x0 + 0x40000 + + + 0 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x40000 + + + 1 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x20000000 + 0x8000 + + + 0 + 0x0 + 0x0 + + + + + + 0 + 7 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 3 + 0 + 1 + 0 + 0 + 0 + 3 + 3 + 0 + 0 + 1 + 0 + 0 + + + NDEBUG,QP_CONFIG + + ..\..;..\..\..\..\..\include;..\..\..\..\..\ports\arm-cm\qxk\armclang;..\..\..\..\..\3rd_party\CMSIS\Include;..\..\..\..\..\3rd_party\ek-tm4c123gxl + + + + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 4 + + + Stack_Size=2048 Heap_Size=16 + + + + + + 0 + 0 + 0 + 0 + 1 + 0 + 0x00000000 + 0x20000000 + + .\dpp-qxk.sct + + + --entry Reset_Handler + + + + + + + + Applicatioin + + + bsp.c + 1 + ..\bsp.c + + + dpp.h + 5 + ..\..\dpp.h + + + bsp.h + 5 + ..\..\bsp.h + + + philo.c + 1 + ..\..\philo.c + + + table.c + 1 + ..\..\table.c + + + xthread1.c + 1 + ..\xthread1.c + + + xthread2.c + 1 + ..\xthread2.c + + + main.c + 1 + ..\..\main.c + + + + + ek-tm4c123gxl + + + startup_TM4C123GH6PM.s + 2 + ..\..\..\..\..\3rd_party\ek-tm4c123gxl\arm\startup_TM4C123GH6PM.s + + + system_TM4C123GH6PM.c + 1 + ..\..\..\..\..\3rd_party\ek-tm4c123gxl\system_TM4C123GH6PM.c + + + TM4C123GH6PM.h + 5 + ..\..\..\..\..\3rd_party\ek-tm4c123gxl\TM4C123GH6PM.h + + + gpio.h + 5 + ..\..\..\..\..\3rd_party\ek-tm4c123gxl\gpio.h + + + rom.h + 5 + ..\..\..\..\..\3rd_party\ek-tm4c123gxl\rom.h + + + sysctl.h + 5 + ..\..\..\..\..\3rd_party\ek-tm4c123gxl\sysctl.h + + + system_TM4C123GH6PM.h + 5 + ..\..\..\..\..\3rd_party\ek-tm4c123gxl\system_TM4C123GH6PM.h + + + + + QP + + + qep_hsm.c + 1 + ..\..\..\..\..\src\qf\qep_hsm.c + + + qep_msm.c + 1 + ..\..\..\..\..\src\qf\qep_msm.c + + + qf_act.c + 1 + ..\..\..\..\..\src\qf\qf_act.c + + + qf_actq.c + 1 + ..\..\..\..\..\src\qf\qf_actq.c + + + qf_defer.c + 1 + ..\..\..\..\..\src\qf\qf_defer.c + + + qf_dyn.c + 1 + ..\..\..\..\..\src\qf\qf_dyn.c + + + qf_mem.c + 1 + ..\..\..\..\..\src\qf\qf_mem.c + + + qf_ps.c + 1 + ..\..\..\..\..\src\qf\qf_ps.c + + + qf_qact.c + 1 + ..\..\..\..\..\src\qf\qf_qact.c + + + qf_qeq.c + 1 + ..\..\..\..\..\src\qf\qf_qeq.c + + + qf_qmact.c + 1 + ..\..\..\..\..\src\qf\qf_qmact.c + + + qf_time.c + 1 + ..\..\..\..\..\src\qf\qf_time.c + + + qxk.c + 1 + ..\..\..\..\..\src\qxk\qxk.c + + + qxk_mutex.c + 1 + ..\..\..\..\..\src\qxk\qxk_mutex.c + + + qxk_sema.c + 1 + ..\..\..\..\..\src\qxk\qxk_sema.c + + + qxk_xthr.c + 1 + ..\..\..\..\..\src\qxk\qxk_xthr.c + + + + + QP_port + + + qxk_port.c + 1 + ..\..\..\..\..\ports\arm-cm\qxk\armclang\qxk_port.c + + + + + QS + + + 0 + 0 + 0 + 0 + 0 + 0 + 2 + 2 + 2 + 2 + 11 + + + 1 + + + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 0 + 0 + 0 + 0 + 2 + + + + + + + + + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + + + + + + + + + + + + qs.c + 1 + ..\..\..\..\..\src\qs\qs.c + + + qs_64bit.c + 1 + ..\..\..\..\..\src\qs\qs_64bit.c + + + qs_fp.c + 1 + ..\..\..\..\..\src\qs\qs_fp.c + + + qs_rx.c + 1 + ..\..\..\..\..\src\qs\qs_rx.c + + + qstamp.c + 1 + ..\..\..\..\..\src\qs\qstamp.c + + + + + + + dpp-spy + 0x4 + ARM-ADS + 6160000::V6.16::ARMCLANG + 1 + + + TM4C123GH6PM + Texas Instruments + Keil.TM4C_DFP.1.1.0 + http://www.keil.com/pack/ + IROM(0x00000000,0x040000) IRAM(0x20000000,0x008000) CPUTYPE("Cortex-M4") FPU2 CLOCK(12000000) ELITTLE + + + UL2CM3(-S0 -C0 -P0 -FD20000000 -FC1000 -FN1 -FF0TM4C123_256 -FS00 -FL040000 -FP0($$Device:TM4C123GH6PM$Flash\TM4C123_256.FLM)) + 0 + $$Device:TM4C123GH6PM$Device\Include\TM4C123\TM4C123.h + + + + + + + + + + $$Device:TM4C123GH6PM$SVD\TM4C123\TM4C123GH6PM.svd + 0 + 0 + + + + + + + 0 + 0 + 0 + 0 + 1 + + .\spy\ + dpp-qxk + 1 + 0 + 0 + 1 + 1 + .\spy\ + 1 + 0 + 0 + + 0 + 0 + + + 0 + 0 + 0 + 0 + + + 1 + 0 + cmd /c "del .\spy\qstamp.o" + + 0 + 0 + 0 + 0 + + + 1 + 0 + fromelf --bin --output .\spy\dpp-qxk.bin .\spy\dpp-qxk.axf + + 0 + 0 + 0 + 0 + + 1 + + + + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 3 + + + 1 + + + SARMCM3.DLL + -MPU + DCM.DLL + -pCM4 + SARMCM3.DLL + -MPU + TCM.DLL + -pCM4 + + + + 1 + 0 + 0 + 0 + 16 + + + + + 1 + 0 + 0 + 1 + 1 + 4097 + + 1 + BIN\UL2CM3.DLL + + + + + + 0 + + + + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + 1 + 0 + 0 + 0 + 0 + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + "Cortex-M4" + + 0 + 0 + 0 + 1 + 1 + 0 + 0 + 2 + 0 + 0 + 0 + 0 + 8 + 0 + 0 + 0 + 0 + 3 + 3 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 1 + 0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x20000000 + 0x8000 + + + 1 + 0x0 + 0x40000 + + + 0 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x40000 + + + 1 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x20000000 + 0x8000 + + + 0 + 0x0 + 0x0 + + + + + + 0 + 1 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 3 + 0 + 1 + 0 + 0 + 0 + 3 + 3 + 0 + 0 + 0 + 0 + 0 + + + Q_SPY,QP_CONFIG + + ..\..;..\..\..\..\..\include;..\..\..\..\..\ports\arm-cm\qxk\armclang;..\..\..\..\..\3rd_party\CMSIS\Include;..\..\..\..\..\3rd_party\ek-tm4c123gxl + + + + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 4 + + + Stack_Size=2048 Heap_Size=16 + + + + + + 0 + 0 + 0 + 0 + 1 + 0 + 0x00000000 + 0x20000000 + + .\dpp-qxk.sct + + + --entry Reset_Handler + + + + + + + + Applicatioin + + + bsp.c + 1 + ..\bsp.c + + + dpp.h + 5 + ..\..\dpp.h + + + bsp.h + 5 + ..\..\bsp.h + + + philo.c + 1 + ..\..\philo.c + + + table.c + 1 + ..\..\table.c + + + xthread1.c + 1 + ..\xthread1.c + + + xthread2.c + 1 + ..\xthread2.c + + + main.c + 1 + ..\..\main.c + + + + + ek-tm4c123gxl + + + startup_TM4C123GH6PM.s + 2 + ..\..\..\..\..\3rd_party\ek-tm4c123gxl\arm\startup_TM4C123GH6PM.s + + + system_TM4C123GH6PM.c + 1 + ..\..\..\..\..\3rd_party\ek-tm4c123gxl\system_TM4C123GH6PM.c + + + TM4C123GH6PM.h + 5 + ..\..\..\..\..\3rd_party\ek-tm4c123gxl\TM4C123GH6PM.h + + + gpio.h + 5 + ..\..\..\..\..\3rd_party\ek-tm4c123gxl\gpio.h + + + rom.h + 5 + ..\..\..\..\..\3rd_party\ek-tm4c123gxl\rom.h + + + sysctl.h + 5 + ..\..\..\..\..\3rd_party\ek-tm4c123gxl\sysctl.h + + + system_TM4C123GH6PM.h + 5 + ..\..\..\..\..\3rd_party\ek-tm4c123gxl\system_TM4C123GH6PM.h + + + + + QP + + + qep_hsm.c + 1 + ..\..\..\..\..\src\qf\qep_hsm.c + + + qep_msm.c + 1 + ..\..\..\..\..\src\qf\qep_msm.c + + + qf_act.c + 1 + ..\..\..\..\..\src\qf\qf_act.c + + + qf_actq.c + 1 + ..\..\..\..\..\src\qf\qf_actq.c + + + qf_defer.c + 1 + ..\..\..\..\..\src\qf\qf_defer.c + + + qf_dyn.c + 1 + ..\..\..\..\..\src\qf\qf_dyn.c + + + qf_mem.c + 1 + ..\..\..\..\..\src\qf\qf_mem.c + + + qf_ps.c + 1 + ..\..\..\..\..\src\qf\qf_ps.c + + + qf_qact.c + 1 + ..\..\..\..\..\src\qf\qf_qact.c + + + qf_qeq.c + 1 + ..\..\..\..\..\src\qf\qf_qeq.c + + + qf_qmact.c + 1 + ..\..\..\..\..\src\qf\qf_qmact.c + + + qf_time.c + 1 + ..\..\..\..\..\src\qf\qf_time.c + + + qxk.c + 1 + ..\..\..\..\..\src\qxk\qxk.c + + + qxk_mutex.c + 1 + ..\..\..\..\..\src\qxk\qxk_mutex.c + + + qxk_sema.c + 1 + ..\..\..\..\..\src\qxk\qxk_sema.c + + + qxk_xthr.c + 1 + ..\..\..\..\..\src\qxk\qxk_xthr.c + + + + + QP_port + + + qxk_port.c + 1 + ..\..\..\..\..\ports\arm-cm\qxk\armclang\qxk_port.c + + + + + QS + + + qs.c + 1 + ..\..\..\..\..\src\qs\qs.c + + + qs_64bit.c + 1 + ..\..\..\..\..\src\qs\qs_64bit.c + + + qs_fp.c + 1 + ..\..\..\..\..\src\qs\qs_fp.c + + + qs_rx.c + 1 + ..\..\..\..\..\src\qs\qs_rx.c + + + qstamp.c + 1 + ..\..\..\..\..\src\qs\qstamp.c + + + + + + + + + + + + + +
diff --git a/examples/arm-cm/dpp_ek-tm4c123gxl_mpu/qxk/armclang/flash.bat b/examples/arm-cm/dpp_ek-tm4c123gxl_mpu/qxk/armclang/flash.bat new file mode 100644 index 00000000..8f61490c --- /dev/null +++ b/examples/arm-cm/dpp_ek-tm4c123gxl_mpu/qxk/armclang/flash.bat @@ -0,0 +1,6 @@ +@setlocal +@set KEILBUILD_ARM=C:\tools\Keil_v5\UV4\UV4.exe + +%KEILBUILD_ARM% -j0 -f dpp-qxk.uvprojx -tdpp-%1 + +@endlocal diff --git a/examples/arm-cm/dpp_ek-tm4c123gxl_mpu/qxk/armclang/make.bat b/examples/arm-cm/dpp_ek-tm4c123gxl_mpu/qxk/armclang/make.bat new file mode 100644 index 00000000..57c18b77 --- /dev/null +++ b/examples/arm-cm/dpp_ek-tm4c123gxl_mpu/qxk/armclang/make.bat @@ -0,0 +1,6 @@ +@setlocal +@set KEILBUILD_ARM=C:\tools\Keil_v5\UV4\UV4.exe + +%KEILBUILD_ARM% -j0 -b dpp-qxk.uvprojx -z + +@endlocal diff --git a/examples/arm-cm/dpp_ek-tm4c123gxl_mpu/qxk/bsp.c b/examples/arm-cm/dpp_ek-tm4c123gxl_mpu/qxk/bsp.c new file mode 100644 index 00000000..c07ed59a --- /dev/null +++ b/examples/arm-cm/dpp_ek-tm4c123gxl_mpu/qxk/bsp.c @@ -0,0 +1,953 @@ +//============================================================================ +// Product: DPP example, EK-TM4C123GXL board, QXK kernel, MPU isolation +// Last updated for version 7.3.0 +// Last updated on 2023-09-07 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. +// +// This program is open source software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Alternatively, this program may be distributed and modified under the +// terms of Quantum Leaps commercial licenses, which expressly supersede +// the GNU General Public License and are specifically designed for +// licensees interested in retaining the proprietary status of their code. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Contact information: +// +// +//============================================================================ +#include "qpc.h" // QP/C real-time embedded framework +#include "dpp.h" // DPP Application interface +#include "bsp.h" // Board Support Package + +#include "TM4C123GH6PM.h" // the device specific header (TI) +#include "rom.h" // the built-in ROM functions (TI) +#include "sysctl.h" // system control driver (TI) +#include "gpio.h" // GPIO driver (TI) +// add other drivers if necessary... + +Q_DEFINE_THIS_FILE // define the name of this file for assertions + +// Local-scope objects ----------------------------------------------------- +#define LED_RED (1U << 1U) +#define LED_GREEN (1U << 3U) +#define LED_BLUE (1U << 2U) + +#define BTN_SW1 (1U << 4U) +#define BTN_SW2 (1U << 0U) + +#ifdef Q_SPY + + // QSpy source IDs + static QSpyId const l_SysTick_Handler = { 0U }; + static QSpyId const l_GPIOPortA_IRQHandler = { 0U }; + + #define UART_BAUD_RATE 115200U + #define UART_FR_TXFE (1U << 7U) + #define UART_FR_RXFE (1U << 4U) + #define UART_TXFIFO_DEPTH 16U + + enum AppRecords { // application-specific trace records + PHILO_STAT = QS_USER, + PAUSED_STAT, + }; + +#endif + +//---------------------------------------------------------------------------- +// MPU storage and settings... +typedef struct { + uint32_t RBAR; + uint32_t RASR; +} MPU_Region; + +//============================================================================ +// Error handler and ISRs... + +Q_NORETURN Q_onError(char const *module, int_t const id) { + // NOTE: this implementation of the assertion handler is intended only + // for debugging and MUST be changed for deployment of the application + // (assuming that you ship your production code with assertions enabled). + Q_UNUSED_PAR(module); + Q_UNUSED_PAR(id); + QS_ASSERTION(module, id, (uint32_t)10000U); + +#ifndef NDEBUG + // light up all LEDs + GPIOF_AHB->DATA_Bits[LED_GREEN | LED_RED | LED_BLUE] = 0xFFU; + // for debugging, hang on in an endless loop... + for (;;) { + } +#endif + + NVIC_SystemReset(); +} +//............................................................................ +void assert_failed(char const * const module, int_t const id); // prototype +void assert_failed(char const * const module, int_t const id) { + Q_onError(module, id); +} + +//............................................................................ +void SysTick_Handler(void); // prototype +void SysTick_Handler(void) { + QXK_ISR_ENTRY(); // inform QXK about entering an ISR + + QTIMEEVT_TICK_X(0U, &l_SysTick_Handler); // time events at rate 0 + + // Perform the debouncing of buttons. The algorithm for debouncing + // adapted from the book "Embedded Systems Dictionary" by Jack Ganssle + // and Michael Barr, page 71. + static struct { + uint32_t depressed; + uint32_t previous; + } buttons = { 0U, 0U }; + + QF_INT_DISABLE(); + QF_MEM_SYS(); + + uint32_t current = ~GPIOF_AHB->DATA_Bits[BTN_SW1 | BTN_SW2]; + uint32_t tmp = buttons.depressed; // save the depressed buttons + buttons.depressed |= (buttons.previous & current); // set depressed + buttons.depressed &= (buttons.previous | current); // clear released + buttons.previous = current; // update the history + tmp ^= buttons.depressed; // changed debounced depressed + current = buttons.depressed; + + QF_MEM_APP(); + QF_INT_ENABLE(); + + if ((tmp & BTN_SW1) != 0U) { // debounced SW1 state changed? + if ((current & BTN_SW1) != 0U) { // is SW1 depressed? + static QEvt const pauseEvt = QEVT_INITIALIZER(PAUSE_SIG); + QACTIVE_PUBLISH(&pauseEvt, &l_SysTick_Handler); + } + else { // the button is released + static QEvt const serveEvt = QEVT_INITIALIZER(SERVE_SIG); + QACTIVE_PUBLISH(&serveEvt, &l_SysTick_Handler); + } + } + + QXK_ISR_EXIT(); // inform QXK about exiting an ISR +} +//............................................................................ +// interrupt handler for testing preemptions in QXK +void GPIOPortA_IRQHandler(void); // prototype +void GPIOPortA_IRQHandler(void) { + QXK_ISR_ENTRY(); // inform QXK about entering an ISR + + // for testing.. + static QEvt const testEvt = QEVT_INITIALIZER(TEST_SIG); + QACTIVE_POST(AO_Table, &testEvt, &l_GPIOPortA_IRQHandler); + + QXK_ISR_EXIT(); // inform QXK about exiting an ISR +} + +//............................................................................ +#ifdef Q_SPY +// ISR for receiving bytes from the QSPY Back-End +// NOTE: This ISR is "QF-unaware" meaning that it does not interact with +// the QF/QXK and is not disabled. Such ISRs don't need to call +// QXK_ISR_ENTRY/QXK_ISR_EXIT and they cannot post or publish events. + +void UART0_IRQHandler(void); // prototype +void UART0_IRQHandler(void) { + QF_MEM_SYS(); + + uint32_t status = UART0->RIS; // get the raw interrupt status + UART0->ICR = status; // clear the asserted interrupts + + while ((UART0->FR & UART_FR_RXFE) == 0U) { // while RX FIFO NOT empty + uint8_t b = (uint8_t)UART0->DR; + QS_rxPut(b); + } + QXK_ARM_ERRATUM_838869(); +} +#endif // Q_SPY + +#ifdef QF_MEM_ISOLATE +//............................................................................ +__attribute__(( used )) +void QF_onMemSys(void) { + MPU->CTRL = MPU_CTRL_ENABLE_Msk // enable the MPU + | MPU_CTRL_PRIVDEFENA_Msk; // enable background region + __ISB(); + __DSB(); +} +//............................................................................ +__attribute__(( used )) +void QF_onMemApp() { + MPU->CTRL = MPU_CTRL_ENABLE_Msk; // enable the MPU + // but do NOT enable background region + __ISB(); + __DSB(); +} +//............................................................................ +#ifdef QF_ON_CONTEXT_SW +// NOTE: the context-switch callback is called with interrupts DISABLED +void QF_onContextSw(QActive *prev, QActive *next) { + if (next != (QActive *)0) { + MPU->CTRL = 0U; // disable the MPU + + MPU_Region const * const region = + (MPU_Region const *)(next->thread); + MPU->RBAR = region[0].RBAR; + MPU->RASR = region[0].RASR; + MPU->RBAR = region[1].RBAR; + MPU->RASR = region[1].RASR; + MPU->RBAR = region[2].RBAR; + MPU->RASR = region[2].RASR; + + MPU->CTRL = MPU_CTRL_ENABLE_Msk // enable the MPU + | MPU_CTRL_PRIVDEFENA_Msk; // enable background region + __ISB(); + __DSB(); + } +} +#endif // QF_ON_CONTEXT_SW +#endif // QF_MEM_ISOLATE + +//============================================================================ + +// Stack ..................................................................... +// NOTE +// The main stack size (provided here as power of 2), MUST match the actual +// stack size defined in the linker-script/startup-code. +#define STACK_SIZE_POW2 ((uint32_t)11U) + +// Table AO................................................................... +// size of Table instance, as power-of-2 +#define TABLE_SIZE_POW2 ((uint32_t)6U) + +__attribute__((aligned((1U << TABLE_SIZE_POW2)))) +static uint8_t Table_sto[1U << TABLE_SIZE_POW2]; + +#ifdef QF_MEM_ISOLATE +static MPU_Region const MPU_Table[3] = { + { (uint32_t)Table_sto + 0x10U, //---- region #0 + ((TABLE_SIZE_POW2 - 1U) << MPU_RASR_SIZE_Pos) // size + + (3U << MPU_RASR_AP_Pos) // PA:rw/UA:rw + + (1U << MPU_RASR_XN_Pos) // XN=1 + + (1U << MPU_RASR_S_Pos) // S=1 + + (1U << MPU_RASR_C_Pos) // C=1 + + (0U << MPU_RASR_B_Pos) // B=0 + + (0U << MPU_RASR_TEX_Pos) // TEX=0 + + MPU_RASR_ENABLE_Msk }, // region enable + { GPIOF_AHB_BASE + 0x11U, //---- region #1 + ((9U - 1U) << MPU_RASR_SIZE_Pos) // 2^9=512B size + + (3U << MPU_RASR_AP_Pos) // PA:rw/UA:rw + + (1U << MPU_RASR_XN_Pos) // XN=1 + + (1U << MPU_RASR_S_Pos) // S=1 + + (0U << MPU_RASR_C_Pos) // C=0 + + (1U << MPU_RASR_B_Pos) // B=1 + + (0U << MPU_RASR_TEX_Pos) // TEX=0 + + MPU_RASR_ENABLE_Msk }, // region enable + { 0U + 0x12U, //---- region #2 + 0U }, +}; +#endif + +// Philo AOs.................................................................. +// size of Philo instance, as power-of-2 +#define PHILO_SIZE_POW2 ((uint32_t)6U) + +__attribute__((aligned((1U << PHILO_SIZE_POW2)))) +static uint8_t Philo_sto[N_PHILO][1U << PHILO_SIZE_POW2]; + +#define PHILO_SHARED_SIZE_POW2 ((uint32_t)5U) +__attribute__((aligned((1U << PHILO_SHARED_SIZE_POW2)))) +static union { + uint32_t rnd_seed; + uint8_t byteso[1U << PHILO_SHARED_SIZE_POW2]; +} Philo_shared_sto; + +#ifdef QF_MEM_ISOLATE +static MPU_Region const MPU_Philo[N_PHILO][3] = { + {{ (uint32_t)Philo_sto[0] + 0x10U, //---- region #0 + ((PHILO_SIZE_POW2 - 1U) << MPU_RASR_SIZE_Pos) // size + + (3U << MPU_RASR_AP_Pos) // PA:rw/UA:rw + + (1U << MPU_RASR_XN_Pos) // XN=1 + + (1U << MPU_RASR_S_Pos) // S=1 + + (1U << MPU_RASR_C_Pos) // C=1 + + (0U << MPU_RASR_B_Pos) // B=0 + + (0U << MPU_RASR_TEX_Pos) // TEX=0 + + MPU_RASR_ENABLE_Msk }, // region enable + { (uint32_t)&Philo_shared_sto + 0x11U, //---- region #1 + ((PHILO_SHARED_SIZE_POW2 - 1U) << MPU_RASR_SIZE_Pos) // size + + (3U << MPU_RASR_AP_Pos) // PA:rw/UA:rw + + (1U << MPU_RASR_XN_Pos) // XN=1 + + (1U << MPU_RASR_S_Pos) // S=1 + + (1U << MPU_RASR_C_Pos) // C=1 + + (0U << MPU_RASR_B_Pos) // B=0 + + (0U << MPU_RASR_TEX_Pos) // TEX=0 + + MPU_RASR_ENABLE_Msk }, // region enable + { 0U + 0x12U, //---- region #2 + 0U }}, + {{ (uint32_t)Philo_sto[1] + 0x10U, //---- region #0 + ((PHILO_SIZE_POW2 - 1U) << MPU_RASR_SIZE_Pos) // size + + (3U << MPU_RASR_AP_Pos) // PA:rw/UA:rw + + (1U << MPU_RASR_XN_Pos) // XN=1 + + (1U << MPU_RASR_S_Pos) // S=1 + + (1U << MPU_RASR_C_Pos) // C=1 + + (0U << MPU_RASR_B_Pos) // B=0 + + (0U << MPU_RASR_TEX_Pos) // TEX=0 + + MPU_RASR_ENABLE_Msk }, // region enable + { (uint32_t)&Philo_shared_sto + 0x11U, //---- region #1 + ((PHILO_SHARED_SIZE_POW2 - 1U) << MPU_RASR_SIZE_Pos) // size + + (3U << MPU_RASR_AP_Pos) // PA:rw/UA:rw + + (1U << MPU_RASR_XN_Pos) // XN=1 + + (1U << MPU_RASR_S_Pos) // S=1 + + (1U << MPU_RASR_C_Pos) // C=1 + + (0U << MPU_RASR_B_Pos) // B=0 + + (0U << MPU_RASR_TEX_Pos) // TEX=0 + + MPU_RASR_ENABLE_Msk }, // region enable + { 0U + 0x12U, //---- region #2 + 0U }}, + {{ (uint32_t)Philo_sto[2] + 0x10U, //---- region #0 + ((PHILO_SIZE_POW2 - 1U) << MPU_RASR_SIZE_Pos) // size + + (3U << MPU_RASR_AP_Pos) // PA:rw/UA:rw + + (1U << MPU_RASR_XN_Pos) // XN=1 + + (1U << MPU_RASR_S_Pos) // S=1 + + (1U << MPU_RASR_C_Pos) // C=1 + + (0U << MPU_RASR_B_Pos) // B=0 + + (0U << MPU_RASR_TEX_Pos) // TEX=0 + + MPU_RASR_ENABLE_Msk }, // region enable + { (uint32_t)&Philo_shared_sto + 0x11U, //---- region #1 + ((PHILO_SHARED_SIZE_POW2 - 1U) << MPU_RASR_SIZE_Pos) // size + + (3U << MPU_RASR_AP_Pos) // PA:rw/UA:rw + + (1U << MPU_RASR_XN_Pos) // XN=1 + + (1U << MPU_RASR_S_Pos) // S=1 + + (1U << MPU_RASR_C_Pos) // C=1 + + (0U << MPU_RASR_B_Pos) // B=0 + + (0U << MPU_RASR_TEX_Pos) // TEX=0 + + MPU_RASR_ENABLE_Msk }, // region enable + { 0U + 0x12U, //---- region #2 + 0U }}, + {{ (uint32_t)Philo_sto[3] + 0x10U, //---- region #0 + ((PHILO_SIZE_POW2 - 1U) << MPU_RASR_SIZE_Pos) // size + + (3U << MPU_RASR_AP_Pos) // PA:rw/UA:rw + + (1U << MPU_RASR_XN_Pos) // XN=1 + + (1U << MPU_RASR_S_Pos) // S=1 + + (1U << MPU_RASR_C_Pos) // C=1 + + (0U << MPU_RASR_B_Pos) // B=0 + + (0U << MPU_RASR_TEX_Pos) // TEX=0 + + MPU_RASR_ENABLE_Msk }, // region enable + { (uint32_t)&Philo_shared_sto + 0x11U, //---- region #1 + ((PHILO_SHARED_SIZE_POW2 - 1U) << MPU_RASR_SIZE_Pos) // size + + (3U << MPU_RASR_AP_Pos) // PA:rw/UA:rw + + (1U << MPU_RASR_XN_Pos) // XN=1 + + (1U << MPU_RASR_S_Pos) // S=1 + + (1U << MPU_RASR_C_Pos) // C=1 + + (0U << MPU_RASR_B_Pos) // B=0 + + (0U << MPU_RASR_TEX_Pos) // TEX=0 + + MPU_RASR_ENABLE_Msk }, // region enable + { 0U + 0x12U, //---- region #2 + 0U }}, + {{ (uint32_t)Philo_sto[4] + 0x10U, //---- region #0 + ((PHILO_SIZE_POW2 - 1U) << MPU_RASR_SIZE_Pos) // size + + (3U << MPU_RASR_AP_Pos) // PA:rw/UA:rw + + (1U << MPU_RASR_XN_Pos) // XN=1 + + (1U << MPU_RASR_S_Pos) // S=1 + + (1U << MPU_RASR_C_Pos) // C=1 + + (0U << MPU_RASR_B_Pos) // B=0 + + (0U << MPU_RASR_TEX_Pos) // TEX=0 + + MPU_RASR_ENABLE_Msk }, // region enable + { (uint32_t)&Philo_shared_sto + 0x11U, //---- region #1 + ((PHILO_SHARED_SIZE_POW2 - 1U) << MPU_RASR_SIZE_Pos) // size + + (3U << MPU_RASR_AP_Pos) // PA:rw/UA:rw + + (1U << MPU_RASR_XN_Pos) // XN=1 + + (1U << MPU_RASR_S_Pos) // S=1 + + (1U << MPU_RASR_C_Pos) // C=1 + + (0U << MPU_RASR_B_Pos) // B=0 + + (0U << MPU_RASR_TEX_Pos) // TEX=0 + + MPU_RASR_ENABLE_Msk }, // region enable + { 0U + 0x12U, //---- region #2 + 0U }}, +}; +#endif + +// XThread1 thread............................................................ +#define XTHREAD1_SIZE_POW2 ((uint32_t)10U) // XThread1 instance + stack +#define XTHREAD1_STACK_SIZE ((uint32_t)896U) // Thread1 stack size + +__attribute__((aligned((1U << XTHREAD1_SIZE_POW2)))) +uint8_t XThread1_sto[1U << XTHREAD1_SIZE_POW2]; + +#ifdef QF_MEM_ISOLATE +static MPU_Region const MPU_XThread1[3] = { + { (uint32_t)XThread1_sto + 0x10U, //---- region #0 + ((XTHREAD1_SIZE_POW2 - 1U) << MPU_RASR_SIZE_Pos) // size + + (3U << MPU_RASR_AP_Pos) // PA:rw/UA:rw + + (1U << MPU_RASR_XN_Pos) // XN=1 + + (1U << MPU_RASR_S_Pos) // S=1 + + (1U << MPU_RASR_C_Pos) // C=1 + + (0U << MPU_RASR_B_Pos) // B=0 + + (0U << MPU_RASR_TEX_Pos) // TEX=0 + + MPU_RASR_ENABLE_Msk }, // region enable + { GPIOF_AHB_BASE + 0x11U, //---- region #1 + ((9U - 1U) << MPU_RASR_SIZE_Pos) // 2^9=512B size + + (3U << MPU_RASR_AP_Pos) // PA:rw/UA:rw + + (1U << MPU_RASR_XN_Pos) // XN=1 + + (1U << MPU_RASR_S_Pos) // S=1 + + (0U << MPU_RASR_C_Pos) // C=0 + + (1U << MPU_RASR_B_Pos) // B=1 + + (0U << MPU_RASR_TEX_Pos) // TEX=0 + + MPU_RASR_ENABLE_Msk }, // region enable + { 0U + 0x12U, //---- region #2 + 0U }, +}; +#endif + +// XThread2 thread............................................................ +#define XTHREAD2_SIZE_POW2 ((uint32_t)10U) // XThread2 instance + stack +#define XTHREAD2_STACK_SIZE ((uint32_t)896U) // Thread2 stack size + +__attribute__((aligned((1U << XTHREAD2_SIZE_POW2)))) +uint8_t XThread2_sto[1U << XTHREAD2_SIZE_POW2]; + +#ifdef QF_MEM_ISOLATE +static MPU_Region const MPU_XThread2[3] = { + { (uint32_t)XThread2_sto + 0x10U, //---- region #0 + ((XTHREAD2_SIZE_POW2 - 1U) << MPU_RASR_SIZE_Pos) // size + + (3U << MPU_RASR_AP_Pos) // PA:rw/UA:rw + + (1U << MPU_RASR_XN_Pos) // XN=1 + + (1U << MPU_RASR_S_Pos) // S=1 + + (1U << MPU_RASR_C_Pos) // C=1 + + (0U << MPU_RASR_B_Pos) // B=0 + + (0U << MPU_RASR_TEX_Pos) // TEX=0 + + MPU_RASR_ENABLE_Msk }, // region enable + { GPIOF_AHB_BASE + 0x11U, //---- region #1 + ((9U - 1U) << MPU_RASR_SIZE_Pos) // 2^9=512B size + + (3U << MPU_RASR_AP_Pos) // PA:rw/UA:rw + + (1U << MPU_RASR_XN_Pos) // XN=1 + + (1U << MPU_RASR_S_Pos) // S=1 + + (0U << MPU_RASR_C_Pos) // C=0 + + (1U << MPU_RASR_B_Pos) // B=1 + + (0U << MPU_RASR_TEX_Pos) // TEX=0 + + MPU_RASR_ENABLE_Msk }, // region enable + { 0U + 0x12U, //---- region #2 + 0U }, +}; +#endif + +// Shared Event-pools...................................................... +#define EPOOLS_SIZE_POW2 ((uint32_t)8U) + +__attribute__((aligned((1U << EPOOLS_SIZE_POW2)))) +static struct EPools { + QF_MPOOL_EL(TableEvt) smlPool[2*N_PHILO]; + // ... other pools +} EPools_sto; +Q_ASSERT_STATIC(sizeof(EPools_sto) <= (1U << EPOOLS_SIZE_POW2)); + +//............................................................................ +#ifdef QF_MEM_ISOLATE +static void TM4C123GXL_MPU_setup(void) { + + SCB->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk; + + MPU->CTRL = 0U; // disable the MPU + + // region #7: NULL-pointer protection region + MPU->RBAR = 0x00000000U + 0x17U; // base address + region #7 + MPU->RASR = ((8U - 1U) << MPU_RASR_SIZE_Pos) // 2^8=256B size + + (0U << MPU_RASR_AP_Pos) // PA:na/UA:na + + (1U << MPU_RASR_XN_Pos) // XN=1 + + (0U << MPU_RASR_S_Pos) // S=0 + + (0U << MPU_RASR_C_Pos) // C=0 + + (0U << MPU_RASR_B_Pos) // B=0 + + (0U << MPU_RASR_TEX_Pos) // TEX=0 + + MPU_RASR_ENABLE_Msk; // region enable + + // region #6: stack region + MPU->RBAR = 0x20000000U + 0x16U; // base address + region #6 + MPU->RASR = ((STACK_SIZE_POW2 - 1U) << MPU_RASR_SIZE_Pos) // size + + (3U << MPU_RASR_AP_Pos) // PA:rw/UA:rw + + (1U << MPU_RASR_XN_Pos) // XN=1 + + (1U << MPU_RASR_S_Pos) // S=1 + + (1U << MPU_RASR_C_Pos) // C=1 + + (0U << MPU_RASR_B_Pos) // B=0 + + (0U << MPU_RASR_TEX_Pos) // TEX=0 + + MPU_RASR_ENABLE_Msk; // region enable + + // region #5: ROM region for TM4C123GXL, whole 256K + MPU->RBAR = 0x00000000U + 0x15U; // base address + region #5 + MPU->RASR = ((18U - 1U) << MPU_RASR_SIZE_Pos) // 2^18=256K size + + (6U << MPU_RASR_AP_Pos) // PA:ro/UA:ro + + (0U << MPU_RASR_XN_Pos) // XN=0 + + (0U << MPU_RASR_S_Pos) // S=0 + + (1U << MPU_RASR_C_Pos) // C=1 + + (0U << MPU_RASR_B_Pos) // B=0 + + (0U << MPU_RASR_TEX_Pos) // TEX=0 + + MPU_RASR_ENABLE_Msk; // region enable + + // region #4: Event-pools region + MPU->RBAR = (uint32_t)&EPools_sto + 0x14U;// base address + region #4 + MPU->RASR = ((EPOOLS_SIZE_POW2 - 1U) << MPU_RASR_SIZE_Pos) // size + + (3U << MPU_RASR_AP_Pos) // PA:rw/UA:rw + + (1U << MPU_RASR_XN_Pos) // XN=1 + + (1U << MPU_RASR_S_Pos) // S=1 + + (1U << MPU_RASR_C_Pos) // C=1 + + (0U << MPU_RASR_B_Pos) // B=0 + + (0U << MPU_RASR_TEX_Pos) // TEX=0 + + MPU_RASR_ENABLE_Msk; // region enable + +#ifdef Q_SPY + // region #3: QS-filters region + MPU->RBAR = (uint32_t)&QS_filt_ + 0x13U;// base address + region #3 + MPU->RASR = ((5U - 1U) << MPU_RASR_SIZE_Pos) // 2^5=32B size + + (3U << MPU_RASR_AP_Pos) // PA:rw/UA:rw + + (1U << MPU_RASR_XN_Pos) // XN=1 + + (1U << MPU_RASR_S_Pos) // S=1 + + (1U << MPU_RASR_C_Pos) // C=1 + + (0U << MPU_RASR_B_Pos) // B=0 + + (0U << MPU_RASR_TEX_Pos) // TEX=0 + + MPU_RASR_ENABLE_Msk; // region enable +#endif + + // region #0: temporary 4G region for initial transient + MPU->RBAR = 0x00000000U + 0x10U; // base address + region #0 + MPU->RASR = ((32U - 1U) << MPU_RASR_SIZE_Pos) // 2^32=4G size + + (3U << MPU_RASR_AP_Pos) // PA:rw/UA:rw + + (0U << MPU_RASR_XN_Pos) // XN=0 + + (1U << MPU_RASR_S_Pos) // S=1 + + (1U << MPU_RASR_C_Pos) // C=1 + + (0U << MPU_RASR_B_Pos) // B=0 + + (0U << MPU_RASR_TEX_Pos) // TEX=0 + + MPU_RASR_ENABLE_Msk; // region enable + + MPU->CTRL = MPU_CTRL_ENABLE_Msk; // enable the MPU + // but do NOT enable background region + __ISB(); + __DSB(); +} +#endif + +//============================================================================ + +// "opaque" pointer to AO +QActive * const AO_Table = (QActive *)Table_sto; + +QActive * const AO_Philo[N_PHILO] = { + (QActive *)Philo_sto[0], // "opaque" pointer + (QActive *)Philo_sto[1], // "opaque" pointer + (QActive *)Philo_sto[2], // "opaque" pointer + (QActive *)Philo_sto[3], // "opaque" pointer + (QActive *)Philo_sto[4] // "opaque" pointer +}; + +static uint8_t * const XThread1_inst = &XThread1_sto[XTHREAD1_STACK_SIZE]; +QXThread * const TH_XThread1 = (QXThread *)&XThread1_sto[XTHREAD1_STACK_SIZE]; + +static uint8_t * const XThread2_inst = &XThread2_sto[XTHREAD2_STACK_SIZE]; +QXThread * const TH_XThread2 = (QXThread *)&XThread2_sto[XTHREAD2_STACK_SIZE]; + +// BSP functions =========================================================== +void BSP_init(void) { +#ifdef QF_MEM_ISOLATE + // setup the MPU + TM4C123GXL_MPU_setup(); +#endif + + // NOTE: SystemInit() has been already called from the startup code + // but SystemCoreClock needs to be updated + SystemCoreClockUpdate(); + + // NOTE: The VFP (hardware Floating Point) unit is configured by QXK + + // enable clock for to the peripherals used by this application... + SYSCTL->RCGCGPIO |= (1U << 5U); // enable Run mode for GPIOF + SYSCTL->GPIOHBCTL |= (1U << 5U); // enable AHB for GPIOF + __ISB(); + __DSB(); + + // configure LEDs (digital output) + GPIOF_AHB->DIR |= (LED_RED | LED_BLUE | LED_GREEN); + GPIOF_AHB->DEN |= (LED_RED | LED_BLUE | LED_GREEN); + GPIOF_AHB->DATA_Bits[LED_RED | LED_BLUE | LED_GREEN] = 0U; + + // configure switches... + + // unlock access to the SW2 pin because it is PROTECTED + GPIOF_AHB->LOCK = 0x4C4F434BU; // unlock GPIOCR register for SW2 + // commit the write (cast const away) + *(uint32_t volatile *)&GPIOF_AHB->CR = 0x01U; + + GPIOF_AHB->DIR &= ~(BTN_SW1 | BTN_SW2); // input + GPIOF_AHB->DEN |= (BTN_SW1 | BTN_SW2); // digital enable + GPIOF_AHB->PUR |= (BTN_SW1 | BTN_SW2); // pull-up resistor enable + + *(uint32_t volatile *)&GPIOF_AHB->CR = 0x00U; + GPIOF_AHB->LOCK = 0x0; // lock GPIOCR register for SW2 + + BSP_randomSeed(1234U); // seed the random number generator + + // initialize the QS software tracing... + if (!QS_INIT((void *)0)) { + Q_ERROR(); + } + + // dictionaries... + QS_OBJ_DICTIONARY(&l_SysTick_Handler); + QS_OBJ_DICTIONARY(&l_GPIOPortA_IRQHandler); + QS_USR_DICTIONARY(PHILO_STAT); + QS_USR_DICTIONARY(PAUSED_STAT); + + QS_ONLY(produce_sig_dict()); + + // setup the QS filters... + QS_GLB_FILTER(QS_ALL_RECORDS); // all records + QS_GLB_FILTER(-QS_QF_TICK); // exclude the clock tick +} +//............................................................................ +void BSP_start(void) { + // initialize event pools + QF_poolInit(EPools_sto.smlPool, + sizeof(EPools_sto.smlPool), + sizeof(EPools_sto.smlPool[0])); + + // initialize publish-subscribe + static QSubscrList subscrSto[MAX_PUB_SIG]; + QActive_psInit(subscrSto, Q_DIM(subscrSto)); + + // instantiate and start AOs/threads... + static QEvt const *xThread1QueueSto[5]; +#ifdef QF_MEM_ISOLATE + XThread1_ctor(XThread1_inst, + sizeof(XThread1_sto) - XTHREAD1_STACK_SIZE, MPU_XThread1); +#else + XThread1_ctor(XThread1_inst, + sizeof(XThread1_sto) - XTHREAD1_STACK_SIZE, (void *)0); +#endif + QXTHREAD_START(TH_XThread1, + 1U, // QP priority of the thread + xThread1QueueSto, // event queue storage + Q_DIM(xThread1QueueSto), // event length [events] + &XThread1_sto[0], // stack storage + XTHREAD1_STACK_SIZE, // stack size [bytes] + (void *)0); // no initialization param + + static QEvt const *philoQueueSto[N_PHILO][10]; + for (uint8_t n = 0U; n < N_PHILO; ++n) { +#ifdef QF_MEM_ISOLATE + Philo_ctor(n, Philo_sto[n], sizeof(Philo_sto[n]), MPU_Philo[n]); +#else + Philo_ctor(n, Philo_sto[n], sizeof(Philo_sto[n]), (void *)0); +#endif + QACTIVE_START(AO_Philo[n], + n + 3U, // QF-prio/pthre. see NOTE1 + philoQueueSto[n], // event queue storage + Q_DIM(philoQueueSto[n]), // queue length [events] + (void *)0, 0U, // no stack storage + (void *)0); // no initialization param + } + + static QEvt const *xThread2QueueSto[5]; +#ifdef QF_MEM_ISOLATE + XThread2_ctor(XThread2_inst, + sizeof(XThread2_sto) - XTHREAD2_STACK_SIZE, MPU_XThread2); +#else + XThread2_ctor(XThread2_inst, + sizeof(XThread2_sto) - XTHREAD2_STACK_SIZE, (void *)0); +#endif + QXTHREAD_START(TH_XThread2, + N_PHILO + 5U, // QP priority of the thread + xThread2QueueSto, // event queue storage + Q_DIM(xThread2QueueSto), // event length [events] + &XThread2_sto[0], // stack storage + XTHREAD2_STACK_SIZE, // stack size [bytes] + (void *)0); // no initialization param + + static QEvt const *tableQueueSto[N_PHILO]; +#ifdef QF_MEM_ISOLATE + Table_ctor(Table_sto, sizeof(Table_sto), MPU_Table); +#else + Table_ctor(Table_sto, sizeof(Table_sto), (void *)0); +#endif + QACTIVE_START(AO_Table, + N_PHILO + 7U, // QP prio. of the AO + tableQueueSto, // event queue storage + Q_DIM(tableQueueSto), // queue length [events] + (void *)0, 0U, // no stack storage + (void *)0); // no initialization param +} +//............................................................................ +void BSP_displayPhilStat(uint8_t n, char const *stat) { + Q_UNUSED_PAR(n); + + GPIOF_AHB->DATA_Bits[LED_GREEN] = ((stat[0] == 'e') ? LED_GREEN : 0U); + + // app-specific trace record... + QS_BEGIN_ID(PHILO_STAT, AO_Table->prio) + QS_U8(1, n); // Philosopher number + QS_STR(stat); // Philosopher status + QS_END() +} +//............................................................................ +void BSP_displayPaused(uint8_t const paused) { + GPIOF_AHB->DATA_Bits[LED_BLUE] = ((paused != 0U) ? LED_BLUE : 0U); + + // application-specific trace record + QS_BEGIN_ID(PAUSED_STAT, AO_Table->prio) + QS_U8(1, paused); // Paused status + QS_END() +} +//............................................................................ +void BSP_randomSeed(uint32_t seed) { + Philo_shared_sto.rnd_seed = seed; +} +//............................................................................ +uint32_t BSP_random() { // a very cheap pseudo-random-number generator + // Some floating point code is to exercise the VFP... + float volatile x = 3.1415926F; + x = x + 2.7182818F; + + QSchedStatus lockStat = QXK_schedLock(N_PHILO); + // "Super-Duper" Linear Congruential Generator (LCG) + // LCG(2^32, 3*7*11*13*23, 0, seed) + // + uint32_t rnd = Philo_shared_sto.rnd_seed * (3U*7U*11U*13U*23U); + Philo_shared_sto.rnd_seed = rnd; // set for the next time + QXK_schedUnlock(lockStat); + + return (rnd >> 8U); +} +//............................................................................ +void BSP_ledOn() { + GPIOF_AHB->DATA_Bits[LED_RED] = 0xFFU; +} +//............................................................................ +void BSP_ledOff() { + GPIOF_AHB->DATA_Bits[LED_RED] = 0x00U; +} +//............................................................................ +void BSP_terminate(int16_t result) { + Q_UNUSED_PAR(result); +} + +//============================================================================ +// QF callbacks... +void QF_onStartup(void) { + // set up the SysTick timer to fire at BSP_TICKS_PER_SEC rate + SysTick_Config(SystemCoreClock / BSP_TICKS_PER_SEC); + + // assign all priority bits for preemption-prio. and none to sub-prio. + NVIC_SetPriorityGrouping(0U); + + // set priorities of ALL ISRs used in the system, see NOTE1 + NVIC_SetPriority(UART0_IRQn, 0U); // kernel unaware interrupt + NVIC_SetPriority(GPIOA_IRQn, QF_AWARE_ISR_CMSIS_PRI + 0U); + NVIC_SetPriority(SysTick_IRQn, QF_AWARE_ISR_CMSIS_PRI + 1U); + // ... + + // enable IRQs... + NVIC_EnableIRQ(GPIOA_IRQn); + +#ifdef Q_SPY + NVIC_EnableIRQ(UART0_IRQn); // UART interrupt used for QS-RX +#endif +} +//............................................................................ +void QF_onCleanup(void) { +} +//............................................................................ +void QXK_onIdle(void) { + // toggle the User LED on and then off, see NOTE3 + QF_INT_DISABLE(); + QF_MEM_SYS(); + GPIOF_AHB->DATA_Bits[LED_BLUE] = 0xFFU; // turn the Blue LED on + GPIOF_AHB->DATA_Bits[LED_BLUE] = 0U; // turn the Blue LED off + QF_MEM_APP(); + QF_INT_ENABLE(); + + // Some floating point code is to exercise the VFP... + float volatile x = 1.73205F; + x = x * 1.73205F; + +#ifdef Q_SPY + QF_INT_DISABLE(); + QF_MEM_SYS(); + QS_rxParse(); // parse all the received bytes + QF_MEM_APP(); + QF_INT_ENABLE(); + QF_CRIT_EXIT_NOP(); + + QF_INT_DISABLE(); + QF_MEM_SYS(); + if ((UART0->FR & UART_FR_TXFE) != 0U) { // TX done? + uint16_t fifo = UART_TXFIFO_DEPTH; // max bytes we can accept + + // try to get next contiguous block to transmit + uint8_t const *block = QS_getBlock(&fifo); + + while (fifo-- != 0U) { // any bytes in the block? + UART0->DR = *block++; // put into the FIFO + } + } + QF_MEM_APP(); + QF_INT_ENABLE(); +#elif defined NDEBUG + // Put the CPU and peripherals to the low-power mode. + // you might need to customize the clock management for your application, + // see the datasheet for your particular Cortex-M MCU. + // + __WFI(); // Wait-For-Interrupt +#endif +} + +//============================================================================ +// QS callbacks... +#ifdef Q_SPY + +#ifdef QF_MEM_ISOLATE +// Shared QS filters... +__attribute__((aligned(32))) +QS_Filter QS_filt_; +#endif + +//............................................................................ +uint8_t QS_onStartup(void const *arg) { + Q_UNUSED_PAR(arg); + + static uint8_t qsTxBuf[2*1024]; // buffer for QS-TX channel + QS_initBuf(qsTxBuf, sizeof(qsTxBuf)); + + static uint8_t qsRxBuf[100]; // buffer for QS-RX channel + QS_rxInitBuf(qsRxBuf, sizeof(qsRxBuf)); + + // enable clock for UART0 and GPIOA (used by UART0 pins) + SYSCTL->RCGCUART |= (1U << 0U); // enable Run mode for UART0 + SYSCTL->RCGCGPIO |= (1U << 0U); // enable Run mode for GPIOA + + // configure UART0 pins for UART operation + uint32_t tmp = (1U << 0U) | (1U << 1U); + GPIOA->DIR &= ~tmp; + GPIOA->SLR &= ~tmp; + GPIOA->ODR &= ~tmp; + GPIOA->PUR &= ~tmp; + GPIOA->PDR &= ~tmp; + GPIOA->AMSEL &= ~tmp; // disable analog function on the pins + GPIOA->AFSEL |= tmp; // enable ALT function on the pins + GPIOA->DEN |= tmp; // enable digital I/O on the pins + GPIOA->PCTL &= ~0x00U; + GPIOA->PCTL |= 0x11U; + + // configure the UART for the desired baud rate, 8-N-1 operation + tmp = (((SystemCoreClock * 8U) / UART_BAUD_RATE) + 1U) / 2U; + UART0->IBRD = tmp / 64U; + UART0->FBRD = tmp % 64U; + UART0->LCRH = (0x3U << 5U); // configure 8-N-1 operation + UART0->LCRH |= (0x1U << 4U); // enable FIFOs + UART0->CTL = (1U << 0U) // UART enable + | (1U << 8U) // UART TX enable + | (1U << 9U); // UART RX enable + + // configure UART interrupts (for the RX channel) + UART0->IM |= (1U << 4U) | (1U << 6U); // enable RX and RX-TO interrupt + UART0->IFLS |= (0x2U << 2U); // interrupt on RX FIFO half-full + // NOTE: do not enable the UART0 interrupt yet. Wait till QF_onStartup() + + // configure TIMER5 to produce QS time stamp + SYSCTL->RCGCTIMER |= (1U << 5U); // enable run mode for Timer5 + TIMER5->CTL = 0U; // disable Timer1 output + TIMER5->CFG = 0x0U; // 32-bit configuration + TIMER5->TAMR = (1U << 4U) | 0x02U; // up-counting periodic mode + TIMER5->TAILR= 0xFFFFFFFFU; // timer interval + TIMER5->ICR = 0x1U; // TimerA timeout flag bit clears + TIMER5->CTL |= (1U << 0U); // enable TimerA module + + return 1U; // return success +} +//............................................................................ +void QS_onCleanup(void) { +} +//............................................................................ +QSTimeCtr QS_onGetTime(void) { // NOTE: invoked with interrupts DISABLED + return TIMER5->TAV; +} +//............................................................................ +void QS_onFlush(void) { + for (;;) { + QF_INT_DISABLE(); + QF_MEM_SYS(); + uint16_t b = QS_getByte(); + if (b != QS_EOD) { + while ((UART0->FR & UART_FR_TXFE) == 0U) { // while TXE not empty + QF_MEM_APP(); + QF_INT_ENABLE(); + QF_CRIT_EXIT_NOP(); + + QF_INT_DISABLE(); + QF_MEM_SYS(); + } + UART0->DR = b; // put into the DR register + QF_MEM_APP(); + QF_INT_ENABLE(); + } + else { + QF_MEM_APP(); + QF_INT_ENABLE(); + break; + } + } +} +//............................................................................ +//! callback function to reset the target (to be implemented in the BSP) +void QS_onReset(void) { + NVIC_SystemReset(); +} +//............................................................................ +//! callback function to execute a user command +void QS_onCommand(uint8_t cmdId, uint32_t param1, + uint32_t param2, uint32_t param3) +{ + Q_UNUSED_PAR(cmdId); + Q_UNUSED_PAR(param1); + Q_UNUSED_PAR(param2); + Q_UNUSED_PAR(param3); +} + +#endif // Q_SPY +//---------------------------------------------------------------------------- + +//============================================================================ +// NOTE1: +// The QF_AWARE_ISR_CMSIS_PRI constant from the QF port specifies the highest +// ISR priority that is disabled by the QF framework. The value is suitable +// for the NVIC_SetPriority() CMSIS function. +// +// Only ISRs prioritized at or below the QF_AWARE_ISR_CMSIS_PRI level (i.e., +// with the numerical values of priorities equal or higher than +// QF_AWARE_ISR_CMSIS_PRI) are allowed to call the QK_ISR_ENTRY/ +// QXK_ISR_ENTRY macros or any other QF/QXK services. These ISRs are +// "QF-aware". +// +// Conversely, any ISRs prioritized above the QF_AWARE_ISR_CMSIS_PRI priority +// level (i.e., with the numerical values of priorities less than +// QF_AWARE_ISR_CMSIS_PRI) are never disabled and are not aware of the kernel. +// Such "QF-unaware" ISRs cannot call ANY QF/QXK services. In particular they +// can NOT call the macros QXK_ISR_ENTRY/QXK_ISR_ENTRY. The only mechanism +// by which a "QF-unaware" ISR can communicate with the QF framework is by +// triggering a "QF-aware" ISR, which can post/publish events. +// +// NOTE2: +// The User LED is used to visualize the idle loop activity. The brightness +// of the LED is proportional to the frequency of the idle loop. +// Please note that the LED is toggled with interrupts locked, so no interrupt +// execution time contributes to the brightness of the User LED. +// diff --git a/examples/arm-cm/dpp_ek-tm4c123gxl_mpu/qxk/gnu/Makefile b/examples/arm-cm/dpp_ek-tm4c123gxl_mpu/qxk/gnu/Makefile new file mode 100644 index 00000000..20fda4e2 --- /dev/null +++ b/examples/arm-cm/dpp_ek-tm4c123gxl_mpu/qxk/gnu/Makefile @@ -0,0 +1,320 @@ +############################################################################## +# Product: Makefile for QP/C on EK-TM4C123GXL, QXK kernel, GNU-ARM +# Last Updated for Version: 7.3.0 +# Date of the Last Update: 2023-09-07 +# +# Q u a n t u m L e a P s +# ------------------------ +# Modern Embedded Software +# +# Copyright (C) 2005 Quantum Leaps, LLC. +# +# This program is open source software: you can redistribute it and/or +# modify it under the terms of the GNU General Public License as published +# by the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Alternatively, this program may be distributed and modified under the +# terms of Quantum Leaps commercial licenses, which expressly supersede +# the GNU General Public License and are specifically designed for +# licensees interested in retaining the proprietary status of their code. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# +# Contact information: +# +# +############################################################################## +# examples of invoking this Makefile: +# building configurations: Debug (default), Release, and Spy +# make +# make CONF=rel +# make CONF=spy +# +# cleaning configurations: Debug (default), Release, and Spy +# make clean +# make CONF=rel clean +# make CONF=spy clean +# +# NOTE: +# To use this Makefile on Windows, you will need the GNU make utility, which +# is included in the Qtools collection for Windows, see: +# https://github.com/QuantumLeaps/qtools + +#----------------------------------------------------------------------------- +# project name +# +PROJECT := dpp-qxk + +#----------------------------------------------------------------------------- +# project directories +# + +# location of the QP/C framework (if not provided in an environemnt var.) +ifeq ($(QPC),) +QPC := ../../../../.. +endif + +# QP port used in this project +QP_PORT_DIR := $(QPC)/ports/arm-cm/qxk/gnu + +# list of all source directories used by this project +VPATH = \ + .. \ + ../.. \ + $(QPC)/src/qf \ + $(QPC)/src/qxk \ + $(QPC)/src/qs \ + $(QP_PORT_DIR) \ + $(QPC)/3rd_party/ek-tm4c123gxl \ + $(QPC)/3rd_party/ek-tm4c123gxl/gnu + +# list of all include directories needed by this project +INCLUDES = \ + -I../.. \ + -I$(QPC)/include \ + -I$(QP_PORT_DIR) \ + -I$(QPC)/3rd_party/CMSIS/Include \ + -I$(QPC)/3rd_party/ek-tm4c123gxl + +#----------------------------------------------------------------------------- +# files +# + +# assembler source files +ASM_SRCS := + +# C source files +C_SRCS := \ + bsp.c \ + main.c \ + philo.c \ + table.c \ + xthread1.c \ + xthread2.c \ + system_TM4C123GH6PM.c \ + startup_TM4C123GH6PM.c + +# C++ source files +CPP_SRCS := + +OUTPUT := $(PROJECT) +LD_SCRIPT := $(PROJECT).ld + +QP_SRCS := \ + qep_hsm.c \ + qep_msm.c \ + qf_act.c \ + qf_actq.c \ + qf_defer.c \ + qf_dyn.c \ + qf_mem.c \ + qf_ps.c \ + qf_qact.c \ + qf_qeq.c \ + qf_qmact.c \ + qf_time.c \ + qxk.c \ + qxk_xthr.c \ + qxk_sema.c \ + qxk_mutex.c \ + qxk_port.c + +QP_ASMS := + +QS_SRCS := \ + qs.c \ + qs_rx.c \ + qs_fp.c + +LIB_DIRS := +LIBS := + +# defines +DEFINES := \ + -DQP_CONFIG \ + -DTARGET_IS_TM4C123_RB1 + +# ARM CPU, ARCH, FPU, and Float-ABI types... +# ARM_CPU: [cortex-m0 | cortex-m0plus | cortex-m1 | cortex-m3 | cortex-m4] +# ARM_FPU: [ | vfp] +# FLOAT_ABI: [ | soft | softfp | hard] +# +ARM_CPU := -mcpu=cortex-m4 +ARM_FPU := -mfpu=vfp +FLOAT_ABI := -mfloat-abi=softfp + +#----------------------------------------------------------------------------- +# GNU-ARM toolset (NOTE: You need to adjust to your machine) +# see https://developer.arm.com/open-source/gnu-toolchain/gnu-rm/downloads +# +ifeq ($(GNU_ARM),) +GNU_ARM := $(QTOOLS)/gnu_arm-none-eabi +endif + +# make sure that the GNU-ARM toolset exists... +ifeq ("$(wildcard $(GNU_ARM))","") +$(error GNU_ARM toolset not found. Please adjust the Makefile) +endif + +CC := $(GNU_ARM)/bin/arm-none-eabi-gcc +CPP := $(GNU_ARM)/bin/arm-none-eabi-g++ +AS := $(GNU_ARM)/bin/arm-none-eabi-as +LINK := $(GNU_ARM)/bin/arm-none-eabi-gcc +BIN := $(GNU_ARM)/bin/arm-none-eabi-objcopy + +############################################################################## +# Typically you should not need to change anything below this line + +# basic utilities (included in QTools for Windows), see: +# https://www.state-machine.com/qtools + +MKDIR := mkdir +RM := rm + +#----------------------------------------------------------------------------- +# build options for various configurations for ARM Cortex-M +# + +# combine all the soruces... +C_SRCS += $(QP_SRCS) +ASM_SRCS += $(QP_ASMS) + +ifeq (rel, $(CONF)) # Release configuration .................................. + +BIN_DIR := rel + +ASFLAGS = $(ARM_CPU) $(ARM_FPU) $(ASM_CPU) $(ASM_FPU) + +CFLAGS = -c $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \ + -ffunction-sections -fdata-sections \ + -O2 $(INCLUDES) $(DEFINES) -DNDEBUG + +CPPFLAGS = -c $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \ + -ffunction-sections -fdata-sections -fno-rtti -fno-exceptions \ + -O2 $(INCLUDES) $(DEFINES) -DNDEBUG + +else ifeq (spy, $(CONF)) # Spy configuration ................................ + +BIN_DIR := spy + +C_SRCS += $(QS_SRCS) + +ASFLAGS = -g $(ARM_CPU) $(ARM_FPU) $(ASM_CPU) $(ASM_FPU) + +CFLAGS = -c -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \ + -ffunction-sections -fdata-sections \ + -O $(INCLUDES) $(DEFINES) -DQ_SPY + +CPPFLAGS = -c -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \ + -ffunction-sections -fdata-sections -fno-rtti -fno-exceptions \ + -O $(INCLUDES) $(DEFINES) -DQ_SPY + +else # default Debug configuration .......................................... + +BIN_DIR := dbg + +ASFLAGS = -g $(ARM_CPU) $(ARM_FPU) $(ASM_CPU) $(ASM_FPU) + +CFLAGS = -c -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \ + -ffunction-sections -fdata-sections \ + -O $(INCLUDES) $(DEFINES) + +CPPFLAGS = -c -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \ + -ffunction-sections -fdata-sections -fno-rtti -fno-exceptions \ + -O $(INCLUDES) $(DEFINES) + +endif # ...................................................................... + + +LINKFLAGS = -T$(LD_SCRIPT) $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb \ + -specs=nosys.specs -specs=nano.specs \ + -Wl,-Map,$(BIN_DIR)/$(OUTPUT).map,--cref,--gc-sections $(LIB_DIRS) + + +ASM_OBJS := $(patsubst %.s,%.o, $(notdir $(ASM_SRCS))) +C_OBJS := $(patsubst %.c,%.o, $(notdir $(C_SRCS))) +CPP_OBJS := $(patsubst %.cpp,%.o,$(notdir $(CPP_SRCS))) + +TARGET_BIN := $(BIN_DIR)/$(OUTPUT).bin +TARGET_ELF := $(BIN_DIR)/$(OUTPUT).elf +ASM_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(ASM_OBJS)) +C_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(C_OBJS)) +C_DEPS_EXT := $(patsubst %.o, %.d, $(C_OBJS_EXT)) +CPP_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(CPP_OBJS)) +CPP_DEPS_EXT := $(patsubst %.o, %.d, $(CPP_OBJS_EXT)) + +# create $(BIN_DIR) if it does not exist +ifeq ("$(wildcard $(BIN_DIR))","") +$(shell $(MKDIR) $(BIN_DIR)) +endif + +#----------------------------------------------------------------------------- +# rules +# + +.PHONY : run norun flash clean show + +ifeq ($(MAKECMDGOALS),norun) +all : $(TARGET_BIN) +norun : all +else +all : $(TARGET_BIN) run +endif + +$(TARGET_BIN): $(TARGET_ELF) + $(BIN) -O binary $< $@ + +$(TARGET_ELF) : $(ASM_OBJS_EXT) $(C_OBJS_EXT) $(CPP_OBJS_EXT) + $(CC) $(CFLAGS) $(QPC)/src/qs/qstamp.c -o $(BIN_DIR)/qstamp.o + $(LINK) $(LINKFLAGS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) + +$(BIN_DIR)/%.d : %.c + $(CC) -MM -MT $(@:.d=.o) $(CFLAGS) $< > $@ + +$(BIN_DIR)/%.d : %.cpp + $(CPP) -MM -MT $(@:.d=.o) $(CPPFLAGS) $< > $@ + +$(BIN_DIR)/%.o : %.s + $(AS) $(ASFLAGS) $< -o $@ + +$(BIN_DIR)/%.o : %.c + $(CC) $(CFLAGS) $< -o $@ + +$(BIN_DIR)/%.o : %.cpp + $(CPP) $(CPPFLAGS) $< -o $@ + +# include dependency files only if our goal depends on their existence +ifneq ($(MAKECMDGOALS),clean) + ifneq ($(MAKECMDGOALS),show) +-include $(C_DEPS_EXT) $(CPP_DEPS_EXT) + endif +endif + + +clean: + -$(RM) $(BIN_DIR)/*.o \ + $(BIN_DIR)/*.d \ + $(BIN_DIR)/*.bin \ + $(BIN_DIR)/*.elf \ + $(BIN_DIR)/*.map + +show: + @echo PROJECT = $(PROJECT) + @echo CONF = $(CONF) + @echo DEFINES = $(DEFINES) + @echo ASM_FPU = $(ASM_FPU) + @echo ASM_SRCS = $(ASM_SRCS) + @echo C_SRCS = $(C_SRCS) + @echo CPP_SRCS = $(CPP_SRCS) + @echo ASM_OBJS_EXT = $(ASM_OBJS_EXT) + @echo C_OBJS_EXT = $(C_OBJS_EXT) + @echo C_DEPS_EXT = $(C_DEPS_EXT) + @echo CPP_DEPS_EXT = $(CPP_DEPS_EXT) + @echo TARGET_ELF = $(TARGET_ELF) diff --git a/examples/arm-cm/blinky_efm32-slstk3401a/qk/gnu/blinky-qk.ld b/examples/arm-cm/dpp_ek-tm4c123gxl_mpu/qxk/gnu/dpp-qxk.ld similarity index 95% rename from examples/arm-cm/blinky_efm32-slstk3401a/qk/gnu/blinky-qk.ld rename to examples/arm-cm/dpp_ek-tm4c123gxl_mpu/qxk/gnu/dpp-qxk.ld index 12002fb8..5139ce62 100644 --- a/examples/arm-cm/blinky_efm32-slstk3401a/qk/gnu/blinky-qk.ld +++ b/examples/arm-cm/dpp_ek-tm4c123gxl_mpu/qxk/gnu/dpp-qxk.ld @@ -1,5 +1,5 @@ /***************************************************************************** -* Product: Linker script for EFM32-SLSTK3401A, GNU-ARM linker +* Product: Linker script for EK-TM4C123GXL, GNU-ARM linker * Last Updated for Version: 5.9.8 * Date of the Last Update: 2017-09-13 * @@ -28,14 +28,14 @@ * along with this program. If not, see . * * Contact information: -* http://www.state-machine.com -* mailto:info@state-machine.com +* Web : http://www.state-machine.com +* Email: info@state-machine.com *****************************************************************************/ OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm", "elf32-littlearm") OUTPUT_ARCH(arm) ENTRY(Reset_Handler) /* entry Point */ -MEMORY { /* memory map of Pearl Gecko EFM32PG1B200F256GM48 */ +MEMORY { /* memory map of Tiva TM4C123GH6PM */ ROM (rx) : ORIGIN = 0x00000000, LENGTH = 256K RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 32K } diff --git a/examples/arm-cm/dpp_ek-tm4c123gxl_mpu/qxk/gnu/flash.bat b/examples/arm-cm/dpp_ek-tm4c123gxl_mpu/qxk/gnu/flash.bat new file mode 100644 index 00000000..cb2a3886 --- /dev/null +++ b/examples/arm-cm/dpp_ek-tm4c123gxl_mpu/qxk/gnu/flash.bat @@ -0,0 +1,33 @@ +::============================================================================ +:: Batch file to program the flash of EK-TM4C123GXL +:: +:: NOTE: requires the LMFlash programmer (included in QTools for Windows) +:: +@echo off +setlocal + +@echo Load a given binary file to the flash of EK-TM4C123GXL +@echo usage: flash binary-file +@echo example: flash dbg\blinky-qk.bin + +::---------------------------------------------------------------------------- +:: NOTE: The following symbol LMFLASH assumes that LMFlash.exe can +:: be found on the PATH. You might need to adjust this symbol to the +:: location of the LMFlash utility on your machine +:: +set LMFLASH=LMFlash.exe + +if ["%~1"]==[""] ( + @echo The binary file missing + @goto end +) +if not exist %~s1 ( + @echo The binary file '%1' does not exist + @goto end +) + +%LMFLASH% -q ek-tm4c123gxl -e -v -r %1 + +:end + +endlocal \ No newline at end of file diff --git a/examples/arm-cm/dpp_ek-tm4c123gxl_mpu/qxk/iar/dpp-qxk.ewd b/examples/arm-cm/dpp_ek-tm4c123gxl_mpu/qxk/iar/dpp-qxk.ewd new file mode 100644 index 00000000..5d3dfa37 --- /dev/null +++ b/examples/arm-cm/dpp_ek-tm4c123gxl_mpu/qxk/iar/dpp-qxk.ewd @@ -0,0 +1,4654 @@ + + + 3 + + Debug + + ARM + + 1 + + C-SPY + 2 + + 32 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ARMSIM_ID + 2 + + 1 + 1 + 1 + + + + + + + + CADI_ID + 2 + + 0 + 1 + 1 + + + + + + + + + CMSISDAP_ID + 2 + + 4 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + GDBSERVER_ID + 2 + + 0 + 1 + 1 + + + + + + + + + + + IJET_ID + 2 + + 9 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + JLINK_ID + 2 + + 16 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + LMIFTDI_ID + 2 + + 3 + 1 + 1 + + + + + + + + + + + + + NULINK_ID + 2 + + 0 + 1 + 1 + + + + + + + PEMICRO_ID + 2 + + 3 + 1 + 1 + + + + + + + + STLINK_ID + 2 + + 8 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + THIRDPARTY_ID + 2 + + 0 + 1 + 1 + + + + + + + + TIFET_ID + 2 + + 1 + 1 + 1 + + + + + + + + + + + + + + + + + + + XDS100_ID + 2 + + 9 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + $TOOLKIT_DIR$\plugins\rtos\CMX\CmxArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\CMX\CmxTinyArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\FreeRtos\FreeRtosArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin2.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SafeRTOS\SafeRTOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9BE.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-286-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-III\uCOS-III-KA-CSpy.ewplugin + 0 + + + $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\TargetAccessServer\TargetAccessServer.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\uCProbe\uCProbePlugin.ENU.ewplugin + 0 + + + + + Release + + ARM + + 0 + + C-SPY + 2 + + 32 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ARMSIM_ID + 2 + + 1 + 1 + 0 + + + + + + + + CADI_ID + 2 + + 0 + 1 + 0 + + + + + + + + + CMSISDAP_ID + 2 + + 4 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + GDBSERVER_ID + 2 + + 0 + 1 + 0 + + + + + + + + + + + IJET_ID + 2 + + 9 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + JLINK_ID + 2 + + 16 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + LMIFTDI_ID + 2 + + 3 + 1 + 0 + + + + + + + + + + + + + NULINK_ID + 2 + + 0 + 1 + 0 + + + + + + + PEMICRO_ID + 2 + + 3 + 1 + 0 + + + + + + + + STLINK_ID + 2 + + 8 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + THIRDPARTY_ID + 2 + + 0 + 1 + 0 + + + + + + + + TIFET_ID + 2 + + 1 + 1 + 0 + + + + + + + + + + + + + + + + + + + XDS100_ID + 2 + + 9 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + $TOOLKIT_DIR$\plugins\rtos\CMX\CmxArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\CMX\CmxTinyArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\FreeRtos\FreeRtosArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin2.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SafeRTOS\SafeRTOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9BE.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-286-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-III\uCOS-III-KA-CSpy.ewplugin + 0 + + + $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\TargetAccessServer\TargetAccessServer.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\uCProbe\uCProbePlugin.ENU.ewplugin + 0 + + + + + Spy + + ARM + + 1 + + C-SPY + 2 + + 32 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ARMSIM_ID + 2 + + 1 + 1 + 1 + + + + + + + + CADI_ID + 2 + + 0 + 1 + 1 + + + + + + + + + CMSISDAP_ID + 2 + + 4 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + GDBSERVER_ID + 2 + + 0 + 1 + 1 + + + + + + + + + + + IJET_ID + 2 + + 9 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + JLINK_ID + 2 + + 16 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + LMIFTDI_ID + 2 + + 3 + 1 + 1 + + + + + + + + + + + + + NULINK_ID + 2 + + 0 + 1 + 1 + + + + + + + PEMICRO_ID + 2 + + 3 + 1 + 1 + + + + + + + + STLINK_ID + 2 + + 8 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + THIRDPARTY_ID + 2 + + 0 + 1 + 1 + + + + + + + + TIFET_ID + 2 + + 1 + 1 + 1 + + + + + + + + + + + + + + + + + + + XDS100_ID + 2 + + 9 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + $TOOLKIT_DIR$\plugins\rtos\CMX\CmxArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\CMX\CmxTinyArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\FreeRtos\FreeRtosArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin2.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SafeRTOS\SafeRTOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9BE.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-286-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-III\uCOS-III-KA-CSpy.ewplugin + 0 + + + $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\TargetAccessServer\TargetAccessServer.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\uCProbe\uCProbePlugin.ENU.ewplugin + 0 + + + + diff --git a/examples/arm-cm/dpp_ek-tm4c123gxl_mpu/qxk/iar/dpp-qxk.ewp b/examples/arm-cm/dpp_ek-tm4c123gxl_mpu/qxk/iar/dpp-qxk.ewp new file mode 100644 index 00000000..557a5057 --- /dev/null +++ b/examples/arm-cm/dpp_ek-tm4c123gxl_mpu/qxk/iar/dpp-qxk.ewp @@ -0,0 +1,3376 @@ + + + 3 + + Debug + + ARM + + 1 + + General + 3 + + 35 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ICCARM + 2 + + 37 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + AARM + 2 + + 11 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + OBJCOPY + 0 + + 1 + 1 + 1 + + + + + + + + + CUSTOM + 3 + + + + 0 + inputOutputBased + + + + BUILDACTION + 1 + + cmd /c "if exist $OBJ_DIR$\qstamp.o del $OBJ_DIR$\qstamp.o" + + + + + ILINK + 0 + + 27 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + IARCHIVE + 0 + + 0 + 1 + 1 + + + + + + + Coder + 0 + + + + + Release + + ARM + + 0 + + General + 3 + + 35 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ICCARM + 2 + + 37 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + AARM + 2 + + 11 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + OBJCOPY + 0 + + 1 + 1 + 0 + + + + + + + + + CUSTOM + 3 + + + + 0 + inputOutputBased + + + + BUILDACTION + 1 + + cmd /c "if exist $OBJ_DIR$\qstamp.o del $OBJ_DIR$\qstamp.o" + + + + + ILINK + 0 + + 27 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + IARCHIVE + 0 + + 0 + 1 + 0 + + + + + + + Coder + 0 + + + + + Spy + + ARM + + 1 + + General + 3 + + 35 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ICCARM + 2 + + 37 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + AARM + 2 + + 11 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + OBJCOPY + 0 + + 1 + 1 + 1 + + + + + + + + + CUSTOM + 3 + + + + 0 + inputOutputBased + + + + BUILDACTION + 1 + + cmd /c "if exist $OBJ_DIR$\qstamp.o del $OBJ_DIR$\qstamp.o" + + + + + ILINK + 0 + + 27 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + IARCHIVE + 0 + + 0 + 1 + 1 + + + + + + + Coder + 0 + + + + + Release + + + Application + + $PROJ_DIR$\..\bsp.c + + + $PROJ_DIR$\..\..\bsp.h + + + $PROJ_DIR$\..\..\dpp.h + + + $PROJ_DIR$\..\..\main.c + + + $PROJ_DIR$\..\..\philo.c + + + $PROJ_DIR$\..\..\table.c + + + $PROJ_DIR$\..\xthread1.c + + + $PROJ_DIR$\..\xthread2.c + + + + ek-tm4c123gxl + + $PROJ_DIR$\..\..\..\..\..\3rd_party\ek-tm4c123gxl\iar\startup_TM4C123GH6PM.s + + + $PROJ_DIR$\..\..\..\..\..\3rd_party\ek-tm4c123gxl\system_TM4C123GH6PM.c + + + $PROJ_DIR$\..\..\..\..\..\3rd_party\ek-tm4c123gxl\system_TM4C123GH6PM.h + + + $PROJ_DIR$\..\..\..\..\..\3rd_party\ek-tm4c123gxl\TM4C123GH6PM.h + + + + QP + + $PROJ_DIR$\..\..\..\..\..\src\qf\qep_hsm.c + + + $PROJ_DIR$\..\..\..\..\..\src\qf\qep_msm.c + + + $PROJ_DIR$\..\..\..\..\..\src\qf\qf_act.c + + + $PROJ_DIR$\..\..\..\..\..\src\qf\qf_actq.c + + + $PROJ_DIR$\..\..\..\..\..\src\qf\qf_defer.c + + + $PROJ_DIR$\..\..\..\..\..\src\qf\qf_dyn.c + + + $PROJ_DIR$\..\..\..\..\..\src\qf\qf_mem.c + + + $PROJ_DIR$\..\..\..\..\..\src\qf_pkg.h + + + $PROJ_DIR$\..\..\..\..\..\src\qf\qf_ps.c + + + $PROJ_DIR$\..\..\..\..\..\src\qf\qf_qact.c + + + $PROJ_DIR$\..\..\..\..\..\src\qf\qf_qeq.c + + + $PROJ_DIR$\..\..\..\..\..\src\qf\qf_qmact.c + + + $PROJ_DIR$\..\..\..\..\..\src\qf\qf_time.c + + + $PROJ_DIR$\..\..\..\..\..\src\qxk\qxk.c + + + $PROJ_DIR$\..\..\..\..\..\src\qxk\qxk_mutex.c + + + $PROJ_DIR$\..\..\..\..\..\src\qxk_pkg.h + + + $PROJ_DIR$\..\..\..\..\..\src\qxk\qxk_sema.c + + + $PROJ_DIR$\..\..\..\..\..\src\qxk\qxk_xthr.c + + + + QP_port + + $PROJ_DIR$\..\..\..\..\..\ports\arm-cm\qxk\iar\qxk_port.c + + + $PROJ_DIR$\..\..\..\..\..\ports\arm-cm\qxk\iar\qxk_port.h + + + + QS + + Debug + Release + + + $PROJ_DIR$\..\..\..\..\..\src\qs\qs.c + + + $PROJ_DIR$\..\..\..\..\..\src\qs\qs_fp.c + + + $PROJ_DIR$\..\..\..\..\..\src\qs\qs_rx.c + + + $PROJ_DIR$\..\..\..\..\..\src\qs\qstamp.c + + + diff --git a/examples/arm-cm/dpp_ek-tm4c123gxl_mpu/qxk/iar/dpp-qxk.eww b/examples/arm-cm/dpp_ek-tm4c123gxl_mpu/qxk/iar/dpp-qxk.eww new file mode 100644 index 00000000..38808ca3 --- /dev/null +++ b/examples/arm-cm/dpp_ek-tm4c123gxl_mpu/qxk/iar/dpp-qxk.eww @@ -0,0 +1,10 @@ + + + + + $WS_DIR$\dpp-qxk.ewp + + + + + diff --git a/examples/arm-cm/dpp_ek-tm4c123gxl_mpu/qxk/iar/dpp-qxk.icf b/examples/arm-cm/dpp_ek-tm4c123gxl_mpu/qxk/iar/dpp-qxk.icf new file mode 100644 index 00000000..c6b24e1c --- /dev/null +++ b/examples/arm-cm/dpp_ek-tm4c123gxl_mpu/qxk/iar/dpp-qxk.icf @@ -0,0 +1,29 @@ +/*###ICF### Section handled by ICF editor, don't touch! ****/ +/*-Editor annotation file-*/ +/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */ +/*-Specials-*/ +define symbol __ICFEDIT_intvec_start__ = 0x00000000; +/*-Memory Regions-*/ +define symbol __ICFEDIT_region_ROM_start__ = 0x00000000; +define symbol __ICFEDIT_region_ROM_end__ = 0x0003FFFF; +define symbol __ICFEDIT_region_RAM_start__ = 0x20000000; +define symbol __ICFEDIT_region_RAM_end__ = 0x20007FFF; +/*-Sizes-*/ +define symbol __ICFEDIT_size_cstack__ = 2048; +define symbol __ICFEDIT_size_heap__ = 0; +/**** End of ICF editor section. ###ICF###*/ + +define memory mem with size = 4G; +define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__]; +define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__]; + +define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { }; +define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { }; + +initialize by copy { readwrite }; +do not initialize { section .noinit }; + +place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec }; +place in ROM_region { readonly }; +place at start of RAM_region {block CSTACK }; /* <== Quantum Leaps */ +place in RAM_region { readwrite, block HEAP }; \ No newline at end of file diff --git a/examples/arm-cm/dpp_ek-tm4c123gxl_mpu/qxk/xthread1.c b/examples/arm-cm/dpp_ek-tm4c123gxl_mpu/qxk/xthread1.c new file mode 100644 index 00000000..18870543 --- /dev/null +++ b/examples/arm-cm/dpp_ek-tm4c123gxl_mpu/qxk/xthread1.c @@ -0,0 +1,125 @@ +//$file${qxk::xthread1.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// +// Model: dpp_mpu.qm +// File: ${qxk::xthread1.c} +// +// This code has been generated by QM 5.3.0 . +// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. +// +// SPDX-License-Identifier: GPL-3.0-or-later +// +// This generated code is open source software: you can redistribute it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation. +// +// This code is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// NOTE: +// Alternatively, this generated code may be distributed under the terms +// of Quantum Leaps commercial licenses, which expressly supersede the GNU +// General Public License and are specifically designed for licensees +// interested in retaining the proprietary status of their code. +// +// Contact information: +// +// +// +//$endhead${qxk::xthread1.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +#include "qpc.h" // QP/C real-time embedded framework +#include "dpp.h" // DPP Application interface +#include "bsp.h" // Board Support Package + +//---------------------------------------------------------------------------- +Q_DEFINE_THIS_FILE + +//---------------------------------------------------------------------------- +//$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// Check for the minimum required QP version +#if (QP_VERSION < 730U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) +#error qpc version 7.3.0 or higher required +#endif +//$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +//$define${Shared-TH::TH_sema} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${Shared-TH::TH_sema} ...................................................... +QXSemaphore TH_sema; +//$enddef${Shared-TH::TH_sema} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +//$define${Shared-TH::TH_mutex} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${Shared-TH::TH_mutex} ..................................................... +QXMutex TH_mutex; +//$enddef${Shared-TH::TH_mutex} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +//$declare${XThreads::XThread1} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${XThreads::XThread1} ...................................................... +typedef struct { +// protected: + QXThread super; + +// private: + + // NOTE: data needed by this thread should be members of + // the thread class. That way they are in the memory region + // accessible from this thread. + uint8_t foo; +} XThread1; + +// private: +static void XThread1_run(QXThread * const thr); +//$enddecl${XThreads::XThread1} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +//$define${Shared-TH::XThread1_ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${Shared-TH::XThread1_ctor} ................................................ +void XThread1_ctor( + uint8_t * const sto, + uint32_t const size, + void const * const mpu) +{ + Q_REQUIRE(sizeof(XThread1) <= size); + + XThread1 *me = (XThread1 *)sto; + QXThread_ctor(&me->super, &XThread1_run, 0U); + me->super.super.thread = mpu; +} +//$enddef${Shared-TH::XThread1_ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +//$define${XThreads::XThread1} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${XThreads::XThread1} ...................................................... + +//${XThreads::XThread1::run} ................................................. +static void XThread1_run(QXThread * const thr) { + QS_OBJ_DICTIONARY(TH_XThread1); + QS_OBJ_DICTIONARY(&TH_XThread1->timeEvt); + + // downcast the generic thr pointer to the specific thread + XThread1 *me = (XThread1 *)thr; + + // subscribe to the EAT signal (from the application) + QActive_subscribe(&me->super.super, EAT_SIG); + + for (;;) { + QEvt const *e = QXThread_queueGet(BSP_TICKS_PER_SEC/4U); + if (e) { + QXSemaphore_signal(&TH_sema); // signal Thread2 + QF_gc(e); // must explicitly recycle the received event! + } + + QXMutex_lock(&TH_mutex, QXTHREAD_NO_TIMEOUT); // lock the mutex + BSP_ledOn(); + if (QXMutex_tryLock(&TH_mutex)) { // exercise the mutex + // some floating point code to exercise the VFP... + float volatile x = 1.4142135F; + x = x * 1.4142135F; + QXThread_delay(10U); // BLOCK while holding a mutex + QXMutex_unlock(&TH_mutex); + } + QXMutex_unlock(&TH_mutex); + BSP_ledOff(); + } +} +//$enddef${XThreads::XThread1} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/examples/arm-cm/dpp_ek-tm4c123gxl_mpu/qxk/xthread2.c b/examples/arm-cm/dpp_ek-tm4c123gxl_mpu/qxk/xthread2.c new file mode 100644 index 00000000..bd8b6fd4 --- /dev/null +++ b/examples/arm-cm/dpp_ek-tm4c123gxl_mpu/qxk/xthread2.c @@ -0,0 +1,117 @@ +//$file${qxk::xthread2.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// +// Model: dpp_mpu.qm +// File: ${qxk::xthread2.c} +// +// This code has been generated by QM 5.3.0 . +// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. +// +// SPDX-License-Identifier: GPL-3.0-or-later +// +// This generated code is open source software: you can redistribute it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation. +// +// This code is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// NOTE: +// Alternatively, this generated code may be distributed under the terms +// of Quantum Leaps commercial licenses, which expressly supersede the GNU +// General Public License and are specifically designed for licensees +// interested in retaining the proprietary status of their code. +// +// Contact information: +// +// +// +//$endhead${qxk::xthread2.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +#include "qpc.h" // QP/C real-time embedded framework +#include "dpp.h" // DPP Application interface +#include "bsp.h" // Board Support Package + +//---------------------------------------------------------------------------- +Q_DEFINE_THIS_FILE + +//---------------------------------------------------------------------------- +//$declare${XThreads::XThread2} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${XThreads::XThread2} ...................................................... +typedef struct { +// protected: + QXThread super; + +// private: + + // NOTE: data needed by this thread should be members of + // the thread class. That way they are in the memory region + // accessible from this thread. + uint8_t foo; +} XThread2; + +// private: +static void XThread2_run(QXThread * const thr); +//$enddecl${XThreads::XThread2} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +//$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// Check for the minimum required QP version +#if (QP_VERSION < 730U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) +#error qpc version 7.3.0 or higher required +#endif +//$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +//$define${Shared-TH::XThread2_ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${Shared-TH::XThread2_ctor} ................................................ +void XThread2_ctor( + uint8_t * const sto, + uint32_t const size, + void const * const mpu) +{ + Q_REQUIRE(sizeof(XThread2) <= size); + + XThread2 *me = (XThread2 *)sto; + QXThread_ctor(&me->super, &XThread2_run, 0U); + me->super.super.thread = mpu; +} +//$enddef${Shared-TH::XThread2_ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +//$define${XThreads::XThread2} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${XThreads::XThread2} ...................................................... + +//${XThreads::XThread2::run} ................................................. +static void XThread2_run(QXThread * const thr) { + QS_OBJ_DICTIONARY(TH_XThread2); + QS_OBJ_DICTIONARY(&TH_XThread2->timeEvt); + QS_OBJ_DICTIONARY(&TH_sema); + QS_OBJ_DICTIONARY(&TH_mutex); + + // downcast the generic thr pointer to the specific thread + //XThread2 *me = (XThread2 *)thr; + + // initialize the semaphore before using it + // NOTE: Here the semaphore is initialized in the highest-priority thread + // that uses it. Alternatively, the semaphore can be initialized + // before any thread runs. + QXSemaphore_init(&TH_sema, + 0U, // count==0 (signaling semaphore) + 1U); // max_count==1 (binary semaphore) + + // initialize the mutex before using it + // NOTE: Here the mutex is initialized in the highest-priority thread + // that uses it. Alternatively, the mutex can be initialized + // before any thread runs. + QXMutex_init(&TH_mutex, N_PHILO + 6U); // priority-ceiling mutex + //QXMutex_init(&TH_mutex, 0U); // alternatively: priority-ceiling NOT used + + for (;;) { + // wait on a semaphore (BLOCK indefinitely) + QXSemaphore_wait(&TH_sema, QXTHREAD_NO_TIMEOUT); + + QXMutex_lock(&TH_mutex, QXTHREAD_NO_TIMEOUT); // lock the mutex + QXThread_delay(5U); // wait more (BLOCK) + QXMutex_unlock(&TH_mutex); + } +} +//$enddef${XThreads::XThread2} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/examples/arm-cm/dpp_ek-tm4c123gxl_mpu/table.c b/examples/arm-cm/dpp_ek-tm4c123gxl_mpu/table.c new file mode 100644 index 00000000..d93f6dba --- /dev/null +++ b/examples/arm-cm/dpp_ek-tm4c123gxl_mpu/table.c @@ -0,0 +1,342 @@ +//$file${.::table.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// +// Model: dpp_mpu.qm +// File: ${.::table.c} +// +// This code has been generated by QM 5.3.0 . +// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. +// +// SPDX-License-Identifier: GPL-3.0-or-later +// +// This generated code is open source software: you can redistribute it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation. +// +// This code is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// NOTE: +// Alternatively, this generated code may be distributed under the terms +// of Quantum Leaps commercial licenses, which expressly supersede the GNU +// General Public License and are specifically designed for licensees +// interested in retaining the proprietary status of their code. +// +// Contact information: +// +// +// +//$endhead${.::table.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +#include "qpc.h" // QP/C real-time embedded framework +#include "dpp.h" // DPP Application interface +#include "bsp.h" // Board Support Package + +//$declare${AOs::Table} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${AOs::Table} .............................................................. +typedef struct { +// protected: + QActive super; + +// private: + uint8_t fork[N_PHILO]; + bool isHungry[N_PHILO]; +} Table; + +// protected: +static QState Table_initial(Table * const me, void const * const par); +static QState Table_active(Table * const me, QEvt const * const e); +static QState Table_serving(Table * const me, QEvt const * const e); +static QState Table_paused(Table * const me, QEvt const * const e); +//$enddecl${AOs::Table} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +//---------------------------------------------------------------------------- +Q_DEFINE_THIS_FILE + +// helper function to provide the RIGHT neighbor of a Philo[n] +static inline uint8_t right(uint8_t const n) { + return (uint8_t)((n + (N_PHILO - 1U)) % N_PHILO); +} + +// helper function to provide the LEFT neighbor of a Philo[n] +static inline uint8_t left(uint8_t const n) { + return (uint8_t)((n + 1U) % N_PHILO); +} + +#define FREE ((uint8_t)0U) +#define USED ((uint8_t)1U) + +#define THINKING "thinking" +#define HUNGRY "hungry " +#define EATING "eating " + +//---------------------------------------------------------------------------- + +//$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// Check for the minimum required QP version +#if (QP_VERSION < 730U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) +#error qpc version 7.3.0 or higher required +#endif +//$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +//$define${Shared::Table_ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${Shared::Table_ctor} ...................................................... +void Table_ctor( + uint8_t * const sto, + uint32_t const size, + void const * const mpu) +{ + Q_REQUIRE(sizeof(Table) <= size); + + Table *me = (Table *)sto; + QActive_ctor(&me->super, Q_STATE_CAST(&Table_initial)); + for (uint8_t n = 0U; n < N_PHILO; ++n) { + me->fork[n] = FREE; + me->isHungry[n] = false; + } + me->super.thread = mpu; +} +//$enddef${Shared::Table_ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +//$define${AOs::Table} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${AOs::Table} .............................................................. + +//${AOs::Table::SM} .......................................................... +static QState Table_initial(Table * const me, void const * const par) { + //${AOs::Table::SM::initial} + Q_UNUSED_PAR(par); + + #ifdef Q_SPY + Table *Table_inst = me; + QS_OBJ_DICTIONARY(Table_inst); + #endif + + QActive_subscribe(&me->super, DONE_SIG); + QActive_subscribe(&me->super, PAUSE_SIG); + QActive_subscribe(&me->super, SERVE_SIG); + QActive_subscribe(&me->super, TEST_SIG); + + for (uint8_t n = 0U; n < N_PHILO; ++n) { + me->fork[n] = FREE; + me->isHungry[n] = false; + BSP_displayPhilStat(n, THINKING); + } + + QS_FUN_DICTIONARY(&Table_active); + QS_FUN_DICTIONARY(&Table_serving); + QS_FUN_DICTIONARY(&Table_paused); + + return Q_TRAN(&Table_serving); +} + +//${AOs::Table::SM::active} .................................................. +static QState Table_active(Table * const me, QEvt const * const e) { + QState status_; + switch (e->sig) { + //${AOs::Table::SM::active::TEST} + case TEST_SIG: { + status_ = Q_HANDLED(); + break; + } + //${AOs::Table::SM::active::EAT} + case EAT_SIG: { + Q_ERROR(); + status_ = Q_HANDLED(); + break; + } + default: { + status_ = Q_SUPER(&QHsm_top); + break; + } + } + return status_; +} + +//${AOs::Table::SM::active::serving} ......................................... +static QState Table_serving(Table * const me, QEvt const * const e) { + QState status_; + switch (e->sig) { + //${AOs::Table::SM::active::serving} + case Q_ENTRY_SIG: { + // give permissions to eat... + for (uint8_t n = 0U; n < N_PHILO; ++n) { + if (me->isHungry[n] + && (me->fork[left(n)] == FREE) + && (me->fork[n] == FREE)) + { + me->fork[left(n)] = USED; + me->fork[n] = USED; + #ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, EAT_SIG, n); + #else + TableEvt *pe = Q_NEW(TableEvt, EAT_SIG); + pe->philoId = n; + #endif + QACTIVE_PUBLISH(&pe->super, &me->super); + me->isHungry[n] = false; + BSP_displayPhilStat(n, EATING); + } + } + status_ = Q_HANDLED(); + break; + } + //${AOs::Table::SM::active::serving::HUNGRY} + case HUNGRY_SIG: { + uint8_t n = Q_EVT_CAST(TableEvt)->philoId; + + // phil ID must be in range and he must be not hungry + Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); + + BSP_displayPhilStat(n, HUNGRY); + uint8_t m = left(n); + //${AOs::Table::SM::active::serving::HUNGRY::[bothfree]} + if ((me->fork[m] == FREE) && (me->fork[n] == FREE)) { + me->fork[m] = USED; + me->fork[n] = USED; + + #ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, EAT_SIG, n); + #else + TableEvt *pe = Q_NEW(TableEvt, EAT_SIG); + pe->philoId = n; + #endif + QACTIVE_PUBLISH(&pe->super, &me->super); + BSP_displayPhilStat(n, EATING); + status_ = Q_HANDLED(); + } + //${AOs::Table::SM::active::serving::HUNGRY::[else]} + else { + me->isHungry[n] = true; + status_ = Q_HANDLED(); + } + break; + } + //${AOs::Table::SM::active::serving::DONE} + case DONE_SIG: { + uint8_t n = Q_EVT_CAST(TableEvt)->philoId; + + // phil ID must be in range and he must be not hungry + Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); + + BSP_displayPhilStat(n, THINKING); + uint8_t m = left(n); + + // both forks of Phil[n] must be used + Q_ASSERT((me->fork[n] == USED) && (me->fork[m] == USED)); + + me->fork[m] = FREE; + me->fork[n] = FREE; + m = right(n); // check the right neighbor + + if (me->isHungry[m] && (me->fork[m] == FREE)) { + me->fork[n] = USED; + me->fork[m] = USED; + me->isHungry[m] = false; + #ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, EAT_SIG, m); + #else + TableEvt *pe = Q_NEW(TableEvt, EAT_SIG); + pe->philoId = m; + #endif + QACTIVE_PUBLISH(&pe->super, &me->super); + BSP_displayPhilStat(m, EATING); + } + m = left(n); // check the left neighbor + n = left(m); // left fork of the left neighbor + if (me->isHungry[m] && (me->fork[n] == FREE)) { + me->fork[m] = USED; + me->fork[n] = USED; + me->isHungry[m] = false; + #ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, EAT_SIG, m); + #else + TableEvt *pe = Q_NEW(TableEvt, EAT_SIG); + pe->philoId = m; + #endif + QACTIVE_PUBLISH(&pe->super, &me->super); + BSP_displayPhilStat(m, EATING); + } + status_ = Q_HANDLED(); + break; + } + //${AOs::Table::SM::active::serving::EAT} + case EAT_SIG: { + Q_ERROR(); + status_ = Q_HANDLED(); + break; + } + //${AOs::Table::SM::active::serving::PAUSE} + case PAUSE_SIG: { + status_ = Q_TRAN(&Table_paused); + break; + } + default: { + status_ = Q_SUPER(&Table_active); + break; + } + } + return status_; +} + +//${AOs::Table::SM::active::paused} .......................................... +static QState Table_paused(Table * const me, QEvt const * const e) { + QState status_; + switch (e->sig) { + //${AOs::Table::SM::active::paused} + case Q_ENTRY_SIG: { + BSP_displayPaused(1U); + status_ = Q_HANDLED(); + break; + } + //${AOs::Table::SM::active::paused} + case Q_EXIT_SIG: { + BSP_displayPaused(0U); + status_ = Q_HANDLED(); + break; + } + //${AOs::Table::SM::active::paused::SERVE} + case SERVE_SIG: { + status_ = Q_TRAN(&Table_serving); + break; + } + //${AOs::Table::SM::active::paused::HUNGRY} + case HUNGRY_SIG: { + uint8_t n = Q_EVT_CAST(TableEvt)->philoId; + + // philo ID must be in range and he must be not hungry + Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); + + me->isHungry[n] = true; + BSP_displayPhilStat(n, HUNGRY); + status_ = Q_HANDLED(); + break; + } + //${AOs::Table::SM::active::paused::DONE} + case DONE_SIG: { + uint8_t n = Q_EVT_CAST(TableEvt)->philoId; + + // phil ID must be in range and he must be not hungry + Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); + + BSP_displayPhilStat(n, THINKING); + uint8_t m = left(n); + + // both forks of Phil[n] must be used + Q_ASSERT((me->fork[n] == USED) && (me->fork[m] == USED)); + + me->fork[m] = FREE; + me->fork[n] = FREE; + status_ = Q_HANDLED(); + break; + } + default: { + status_ = Q_SUPER(&Table_active); + break; + } + } + return status_; +} +//$enddef${AOs::Table} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/examples/arm-cm/dpp_mbed-lpc1768/README.md b/examples/arm-cm/dpp_mbed-lpc1768/README.md deleted file mode 100644 index f4042baf..00000000 --- a/examples/arm-cm/dpp_mbed-lpc1768/README.md +++ /dev/null @@ -1,5 +0,0 @@ -![STM32 EFM32-SLSTK3401A](../../../doxygen/images/bd_mbed-LPC1768.jpg) - -Documentation for this example is available in the QP/C Manual at: - -- https://www.state-machine.com/qpc/arm-cm_dpp_mbed-lpc1768.html diff --git a/examples/arm-cm/dpp_mbed-lpc1768/bsp.h b/examples/arm-cm/dpp_mbed-lpc1768/bsp.h index da221a88..da73dbfd 100644 --- a/examples/arm-cm/dpp_mbed-lpc1768/bsp.h +++ b/examples/arm-cm/dpp_mbed-lpc1768/bsp.h @@ -1,47 +1,49 @@ -/***************************************************************************** -* Product: DPP example -* Last Updated for Version: 5.4.0 -* Date of the Last Update: 2015-03-07 -* -* Q u a n t u m L e a P s -* --------------------------- -* innovating embedded systems -* -* Copyright (C) 2005 Quantum Leaps, LLC. state-machine.com. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* -* -*****************************************************************************/ -#ifndef BSP_H -#define BSP_H +//============================================================================ +// Product: Board Support Package example +// Last Updated for Version: 7.3.0 +// Date of the Last Update: 2023-08-12 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +//============================================================================ +#ifndef BSP_H_ +#define BSP_H_ #define BSP_TICKS_PER_SEC 100U void BSP_init(void); +void BSP_start(void); void BSP_displayPaused(uint8_t paused); void BSP_displayPhilStat(uint8_t n, char const *stat); void BSP_terminate(int16_t result); -void BSP_randomSeed(uint32_t seed); /* random seed */ -uint32_t BSP_random(void); /* pseudo-random generator */ +void BSP_randomSeed(uint32_t seed); // random seed +uint32_t BSP_random(void); // pseudo-random generator -#endif /* BSP_H */ +void BSP_ledOn(void); +void BSP_ledOff(void); + +#endif // BSP_H_ diff --git a/examples/arm-cm/dpp_mbed-lpc1768/dpp.h b/examples/arm-cm/dpp_mbed-lpc1768/dpp.h index c45cc7c6..e6d1557a 100644 --- a/examples/arm-cm/dpp_mbed-lpc1768/dpp.h +++ b/examples/arm-cm/dpp_mbed-lpc1768/dpp.h @@ -1,94 +1,117 @@ -/*$file${.::dpp.h} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* -* Model: dpp.qm -* File: ${.::dpp.h} -* -* This code has been generated by QM 5.2.4 . -* DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. -* -* SPDX-License-Identifier: GPL-3.0-or-later -* -* This generated code is open source software: you can redistribute it under -* the terms of the GNU General Public License as published by the Free -* Software Foundation. -* -* This code is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -* more details. -* -* NOTE: -* Alternatively, this generated code may be distributed under the terms -* of Quantum Leaps commercial licenses, which expressly supersede the GNU -* General Public License and are specifically designed for licensees -* interested in retaining the proprietary status of their code. -* -* Contact information: -* -* -*/ -/*$endhead${.::dpp.h} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -#ifndef DPP_H -#define DPP_H +//$file${.::dpp.h} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// +// Model: dpp.qm +// File: ${.::dpp.h} +// +// This code has been generated by QM 5.3.0 . +// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. +// +// SPDX-License-Identifier: GPL-3.0-or-later +// +// This generated code is open source software: you can redistribute it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation. +// +// This code is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// NOTE: +// Alternatively, this generated code may be distributed under the terms +// of Quantum Leaps commercial licenses, which expressly supersede the GNU +// General Public License and are specifically designed for licensees +// interested in retaining the proprietary status of their code. +// +// Contact information: +// +// +// +//$endhead${.::dpp.h} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +#ifndef DPP_H_ +#define DPP_H_ -enum DPPSignals { - EAT_SIG = Q_USER_SIG, /* published by Table to let a philosopher eat */ - DONE_SIG, /* published by Philosopher when done eating */ - PAUSE_SIG, /* published by BSP to pause serving forks */ - SERVE_SIG, /* published by BSP to serve re-start serving forks */ - TEST_SIG, /* published by BSP to test the application */ - MAX_PUB_SIG, /* the last published signal */ +//$declare${Shared} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv - HUNGRY_SIG, /* posted direclty to Table from hungry Philo */ - TIMEOUT_SIG, /* used by Philosophers for time events */ - MAX_SIG /* the last signal */ +//${Shared::AppSignals} ...................................................... +enum AppSignals { + EAT_SIG = Q_USER_SIG, // published by Table to let a Philo eat + DONE_SIG, // published by Philo when done eating + PAUSE_SIG, // published by BSP to pause the application + SERVE_SIG, // published by BSP to serve re-start serving forks + TEST_SIG, // published by BSP to test the application + MAX_PUB_SIG, // the last published signal + + TIMEOUT_SIG, // posted by time event to Philo + HUNGRY_SIG, // posted by hungry Philo to Table + MAX_SIG // the last signal }; -/*$declare${Events::TableEvt} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//${Shared::produce_sig_dict} ................................................ +#ifdef Q_SPY +static inline void produce_sig_dict(void) { + QS_SIG_DICTIONARY(EAT_SIG, (void *)0); + QS_SIG_DICTIONARY(DONE_SIG, (void *)0); + QS_SIG_DICTIONARY(PAUSE_SIG, (void *)0); + QS_SIG_DICTIONARY(SERVE_SIG, (void *)0); + QS_SIG_DICTIONARY(TEST_SIG, (void *)0); -/*${Events::TableEvt} ......................................................*/ + QS_SIG_DICTIONARY(TIMEOUT_SIG, (void *)0); + QS_SIG_DICTIONARY(HUNGRY_SIG, (void *)0); +} +#endif // def Q_SPY + +//${Shared::N_PHILO} ......................................................... +#define N_PHILO ((uint8_t)5U) + +//${Shared::TableEvt} ........................................................ typedef struct { -/* protected: */ +// protected: QEvt super; -/* public: */ - uint8_t philoNum; +// public: + uint8_t philoId; } TableEvt; -/*$enddecl${Events::TableEvt} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/* number of philosophers */ -#define N_PHILO ((uint8_t)5) +// public: -/*$declare${AOs::Philo_ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +#ifdef QEVT_DYN_CTOR +static inline TableEvt * TableEvt_ctor(TableEvt * const me, + uint8_t id) +{ + if (me != (TableEvt *)0) { + // don't call QEvt_ctor() because the initialization of all + // QEvt attributes is already done in QF_QF_newX_() + me->philoId = id; + } + return me; +} +#endif // def QEVT_DYN_CTOR -/*${AOs::Philo_ctor} .......................................................*/ -void Philo_ctor(void); -/*$enddecl${AOs::Philo_ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*$declare${AOs::AO_Philo[N_PHILO]} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${AOs::AO_Philo[N_PHILO]} ................................................*/ -/* opaque pointers to the Philo AOs */ +//${Shared::AO_Philo[N_PHILO]} ............................................... extern QActive * const AO_Philo[N_PHILO]; -/*$enddecl${AOs::AO_Philo[N_PHILO]} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*$declare${AOs::Table_ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//${Shared::Philo_ctor} ...................................................... +void Philo_ctor(uint_fast8_t const id); -/*${AOs::Table_ctor} .......................................................*/ -void Table_ctor(void); -/*$enddecl${AOs::Table_ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*$declare${AOs::AO_Table} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${AOs::AO_Table} .........................................................*/ -/* opaque pointer to the Table AO */ +//${Shared::AO_Table} ........................................................ extern QActive * const AO_Table; -/*$enddecl${AOs::AO_Table} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -#ifdef QP_INC_QXK_H_ - void Test1_ctor(void); - extern QXThread * const XT_Test1; - void Test2_ctor(void); - extern QXThread * const XT_Test2; -#endif /* QP_INC_QXK_H_ */ +//${Shared::Table_ctor} ...................................................... +void Table_ctor(void); +//$enddecl${Shared} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -#endif /* DPP_H */ +#ifdef QXK_H_ +extern QXThread * const TH_XThread1; +void XThread1_ctor(void); + +extern QXThread * const TH_XThread2; +void XThread2_ctor(void); + +extern QXSemaphore TH_sema; +extern QXMutex TH_mutex; + +#endif // QXK_H_ + +#endif // DPP_H_ diff --git a/examples/arm-cm/dpp_mbed-lpc1768/dpp.qm b/examples/arm-cm/dpp_mbed-lpc1768/dpp.qm index 79ff1da8..ac9f2bc9 100644 --- a/examples/arm-cm/dpp_mbed-lpc1768/dpp.qm +++ b/examples/arm-cm/dpp_mbed-lpc1768/dpp.qm @@ -1,131 +1,210 @@ - + Dining Philosopher Problem example - - - + + + + + { + EAT_SIG = Q_USER_SIG, // published by Table to let a Philo eat + DONE_SIG, // published by Philo when done eating + PAUSE_SIG, // published by BSP to pause the application + SERVE_SIG, // published by BSP to serve re-start serving forks + TEST_SIG, // published by BSP to test the application + MAX_PUB_SIG, // the last published signal + + TIMEOUT_SIG, // posted by time event to Philo + HUNGRY_SIG, // posted by hungry Philo to Table + MAX_SIG // the last signal +}; + + + + QS_SIG_DICTIONARY(EAT_SIG, (void *)0); +QS_SIG_DICTIONARY(DONE_SIG, (void *)0); +QS_SIG_DICTIONARY(PAUSE_SIG, (void *)0); +QS_SIG_DICTIONARY(SERVE_SIG, (void *)0); +QS_SIG_DICTIONARY(TEST_SIG, (void *)0); + +QS_SIG_DICTIONARY(TIMEOUT_SIG, (void *)0); +QS_SIG_DICTIONARY(HUNGRY_SIG, (void *)0); + + + + ((uint8_t)5U) + + - - + + + + + + + if (me != (TableEvt *)0) { + // don't call QEvt_ctor() because the initialization of all + // QEvt attributes is already done in QF_QF_newX_() + me->philoId = id; +} +return me; + + + + = { + &Philo_inst[0].super, + &Philo_inst[1].super, + &Philo_inst[2].super, + &Philo_inst[3].super, + &Philo_inst[4].super +}; + + + + + + Philo * const me = &Philo_inst[id]; +QActive_ctor(&me->super, Q_STATE_CAST(&Philo_initial)); +QTimeEvt_ctorX(&me->timeEvt, &me->super, TIMEOUT_SIG, 0U), +me->id = (uint8_t)id; + + + + = &Table_inst.super; + + + + Table * const me = &Table_inst; +QActive_ctor(&me->super, Q_STATE_CAST(&Table_initial)); +for (uint8_t n = 0U; n < N_PHILO; ++n) { + me->fork[n] = FREE; + me->isHungry[n] = false; +} + + The Philo AO and the N_PHILO instances + + + + - + - static uint8_t registered = (uint8_t)0; /* starts off with 0, per C-standard */ -(void)par; /* unused parameter */ -if (registered == (uint8_t)0) { - registered = (uint8_t)1; + Q_UNUSED_PAR(par); - QS_OBJ_DICTIONARY(&l_philo[0].timeEvt); - QS_OBJ_DICTIONARY(&l_philo[1].timeEvt); - QS_OBJ_DICTIONARY(&l_philo[2].timeEvt); - QS_OBJ_DICTIONARY(&l_philo[3].timeEvt); - QS_OBJ_DICTIONARY(&l_philo[4].timeEvt); - - QS_FUN_DICTIONARY(&Philo_initial); - QS_FUN_DICTIONARY(&Philo_thinking); - QS_FUN_DICTIONARY(&Philo_hungry); - QS_FUN_DICTIONARY(&Philo_eating); -} -QS_SIG_DICTIONARY(HUNGRY_SIG, me); /* signal for each Philos */ -QS_SIG_DICTIONARY(TIMEOUT_SIG, me); /* signal for each Philos */ +QS_OBJ_ARR_DICTIONARY(&Philo_inst[me->id], me->id); +QS_OBJ_ARR_DICTIONARY(&Philo_inst[me->id].timeEvt, me->id); QActive_subscribe(&me->super, EAT_SIG); QActive_subscribe(&me->super, TEST_SIG); - + - QTimeEvt_armX(&me->timeEvt, THINK_TIME, 0U); - QTimeEvt_disarm(&me->timeEvt); + QTimeEvt_armX(&me->timeEvt, think_time(), 0U); + (void)QTimeEvt_disarm(&me->timeEvt); - - + + - /* EAT or DONE must be for other Philos than this one */ -Q_ASSERT_ID(10, Q_EVT_CAST(TableEvt)->philoNum != PHILO_ID(me)); - + // EAT or DONE must be for other Philos than this one +Q_ASSERT(Q_EVT_CAST(TableEvt)->philoId != me->id); + - + + + + + + + - + - TableEvt *pe = Q_NEW(TableEvt, HUNGRY_SIG); -pe->philoNum = PHILO_ID(me); -QACTIVE_POST(AO_Table, &pe->super, me); + #ifdef QEVT_DYN_CTOR +TableEvt const *pe = Q_NEW(TableEvt, HUNGRY_SIG, me->id); +#else +TableEvt *pe = Q_NEW(TableEvt, HUNGRY_SIG); +pe->philoId = me->id; +#endif +QACTIVE_POST(AO_Table, &pe->super, &me->super); - + - Q_EVT_CAST(TableEvt)->philoNum == PHILO_ID(me) - - + Q_EVT_CAST(TableEvt)->philoId == me->id + + - + - /* DONE must be for other Philos than this one */ -Q_ASSERT_ID(20, Q_EVT_CAST(TableEvt)->philoNum != PHILO_ID(me)); - + // DONE must be for other Philos than this one +Q_ASSERT(Q_EVT_CAST(TableEvt)->philoId != me->id); + - + - QTimeEvt_armX(&me->timeEvt, EAT_TIME, 0U); - TableEvt *pe = Q_NEW(TableEvt, DONE_SIG); -pe->philoNum = PHILO_ID(me); -QACTIVE_PUBLISH(&pe->super, &me->super); -QTimeEvt_disarm(&me->timeEvt); + QTimeEvt_armX(&me->timeEvt, eat_time(), 0U); + (void)QTimeEvt_disarm(&me->timeEvt); + +#ifdef QEVT_DYN_CTOR +TableEvt const *pe = Q_NEW(TableEvt, DONE_SIG, me->id); +#else +TableEvt *pe = Q_NEW(TableEvt, DONE_SIG); +pe->philoId = me->id; +#endif +QACTIVE_PUBLISH(&pe->super, &me->super); - - + + - /* EAT or DONE must be for other Philos than this one */ -Q_ASSERT_ID(30, Q_EVT_CAST(TableEvt)->philoNum != PHILO_ID(me)); - + // EAT or DONE must be for other Philos than this one +Q_ASSERT(Q_EVT_CAST(TableEvt)->philoId != me->id); + - + - + @@ -133,149 +212,171 @@ Q_ASSERT_ID(30, Q_EVT_CAST(TableEvt)->philoNum != PHILO_ID(me)); - + + + - + - - uint8_t n; -(void)par; /* unused parameter */ + + Q_UNUSED_PAR(par); -QS_SIG_DICTIONARY(DONE_SIG, (void *)0); /* global signals */ -QS_SIG_DICTIONARY(EAT_SIG, (void *)0); -QS_SIG_DICTIONARY(PAUSE_SIG, (void *)0); -QS_SIG_DICTIONARY(SERVE_SIG, (void *)0); -QS_SIG_DICTIONARY(TEST_SIG, (void *)0); - -QS_SIG_DICTIONARY(HUNGRY_SIG, me); /* signal just for Table */ +#ifdef Q_SPY +Table *Table_inst = me; +QS_OBJ_DICTIONARY(Table_inst); +#endif QActive_subscribe(&me->super, DONE_SIG); QActive_subscribe(&me->super, PAUSE_SIG); QActive_subscribe(&me->super, SERVE_SIG); QActive_subscribe(&me->super, TEST_SIG); -for (n = 0U; n < N_PHILO; ++n) { +for (uint8_t n = 0U; n < N_PHILO; ++n) { me->fork[n] = FREE; - me->isHungry[n] = 0U; - BSP_displayPhilStat(n, "thinking"); + me->isHungry[n] = false; + BSP_displayPhilStat(n, THINKING); } - + + + + + + + - Q_ERROR_ID(60); - - + Q_ERROR(); + + - uint8_t n; -for (n = 0U; n < N_PHILO; ++n) { /* give permissions to eat... */ - if ((me->isHungry[n] != 0U) - && (me->fork[LEFT(n)] == FREE) + // give permissions to eat... +for (uint8_t n = 0U; n < N_PHILO; ++n) { + if (me->isHungry[n] + && (me->fork[left(n)] == FREE) && (me->fork[n] == FREE)) { - TableEvt *te; - - me->fork[LEFT(n)] = USED; + me->fork[left(n)] = USED; me->fork[n] = USED; - te = Q_NEW(TableEvt, EAT_SIG); - te->philoNum = n; - QACTIVE_PUBLISH(&te->super, &me->super); - me->isHungry[n] = 0U; - BSP_displayPhilStat(n, "eating "); +#ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, EAT_SIG, n); +#else + TableEvt *pe = Q_NEW(TableEvt, EAT_SIG); + pe->philoId = n; +#endif + QACTIVE_PUBLISH(&pe->super, &me->super); + me->isHungry[n] = false; + BSP_displayPhilStat(n, EATING); } } - uint8_t n, m; + uint8_t n = Q_EVT_CAST(TableEvt)->philoId; -n = Q_EVT_CAST(TableEvt)->philoNum; -/* phil ID must be in range and he must be not hungry */ -Q_ASSERT_ID(40, (n < N_PHILO) && (me->isHungry[n] == 0U)); +// phil ID must be in range and he must be not hungry +Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); -BSP_displayPhilStat(n, "hungry "); -m = LEFT(n); +BSP_displayPhilStat(n, HUNGRY); +uint8_t m = left(n); (me->fork[m] == FREE) && (me->fork[n] == FREE) - TableEvt *pe; -me->fork[m] = USED; + me->fork[m] = USED; me->fork[n] = USED; -pe = Q_NEW(TableEvt, EAT_SIG); -pe->philoNum = n; +#ifdef QEVT_DYN_CTOR +TableEvt const *pe = Q_NEW(TableEvt, EAT_SIG, n); +#else +TableEvt *pe = Q_NEW(TableEvt, EAT_SIG); +pe->philoId = n; +#endif QACTIVE_PUBLISH(&pe->super, &me->super); -BSP_displayPhilStat(n, "eating "); - +BSP_displayPhilStat(n, EATING); + else - me->isHungry[n] = 1U; - - + me->isHungry[n] = true; + + - + - uint8_t n, m; -TableEvt *pe; + uint8_t n = Q_EVT_CAST(TableEvt)->philoId; -n = Q_EVT_CAST(TableEvt)->philoNum; -/* phil ID must be in range and he must be not hungry */ -Q_ASSERT_ID(50, (n < N_PHILO) && (me->isHungry[n] == 0U)); +// phil ID must be in range and he must be not hungry +Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); -BSP_displayPhilStat(n, "thinking"); -m = LEFT(n); -/* both forks of Phil[n] must be used */ -Q_ASSERT_ID(51, (me->fork[n] == USED) && (me->fork[m] == USED)); +BSP_displayPhilStat(n, THINKING); +uint8_t m = left(n); + +// both forks of Phil[n] must be used +Q_ASSERT((me->fork[n] == USED) && (me->fork[m] == USED)); me->fork[m] = FREE; me->fork[n] = FREE; -m = RIGHT(n); /* check the right neighbor */ +m = right(n); // check the right neighbor -if ((me->isHungry[m] != 0U) && (me->fork[m] == FREE)) { +if (me->isHungry[m] && (me->fork[m] == FREE)) { me->fork[n] = USED; me->fork[m] = USED; - me->isHungry[m] = 0U; - pe = Q_NEW(TableEvt, EAT_SIG); - pe->philoNum = m; + me->isHungry[m] = false; +#ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, EAT_SIG, m); +#else + TableEvt *pe = Q_NEW(TableEvt, EAT_SIG); + pe->philoId = m; +#endif QACTIVE_PUBLISH(&pe->super, &me->super); - BSP_displayPhilStat(m, "eating "); + BSP_displayPhilStat(m, EATING); } -m = LEFT(n); /* check the left neighbor */ -n = LEFT(m); /* left fork of the left neighbor */ -if ((me->isHungry[m] != 0U) && (me->fork[n] == FREE)) { +m = left(n); // check the left neighbor +n = left(m); // left fork of the left neighbor +if (me->isHungry[m] && (me->fork[n] == FREE)) { me->fork[m] = USED; me->fork[n] = USED; - me->isHungry[m] = 0U; - pe = Q_NEW(TableEvt, EAT_SIG); - pe->philoNum = m; + me->isHungry[m] = false; +#ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, EAT_SIG, m); +#else + TableEvt *pe = Q_NEW(TableEvt, EAT_SIG); + pe->philoId = m; +#endif QACTIVE_PUBLISH(&pe->super, &me->super); - BSP_displayPhilStat(m, "eating "); + BSP_displayPhilStat(m, EATING); } - + + + + Q_ERROR(); + + + + - - + + - + @@ -284,187 +385,141 @@ if ((me->isHungry[m] != 0U) && (me->fork[n] == FREE)) { BSP_displayPaused(1U); BSP_displayPaused(0U); - - + + - uint8_t n = Q_EVT_CAST(TableEvt)->philoNum; -/* philo ID must be in range and he must be not hungry */ -Q_ASSERT_ID(60, (n < N_PHILO) && (me->isHungry[n] == 0U)); -me->isHungry[n] = 1U; -BSP_displayPhilStat(n, "hungry "); - + uint8_t n = Q_EVT_CAST(TableEvt)->philoId; + +// philo ID must be in range and he must be not hungry +Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); + +me->isHungry[n] = true; +BSP_displayPhilStat(n, HUNGRY); + - uint8_t n, m; + uint8_t n = Q_EVT_CAST(TableEvt)->philoId; -n = Q_EVT_CAST(TableEvt)->philoNum; -/* phil ID must be in range and he must be not hungry */ -Q_ASSERT_ID(70, (n < N_PHILO) && (me->isHungry[n] == 0U)); +// phil ID must be in range and he must be not hungry +Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); -BSP_displayPhilStat(n, "thinking"); -m = LEFT(n); -/* both forks of Phil[n] must be used */ -Q_ASSERT_ID(71, (me->fork[n] == USED) && (me->fork[m] == USED)); +BSP_displayPhilStat(n, THINKING); +uint8_t m = left(n); + +// both forks of Phil[n] must be used +Q_ASSERT((me->fork[n] == USED) && (me->fork[m] == USED)); me->fork[m] = FREE; me->fork[n] = FREE; - + - + - + - + - - - /* opaque pointers to the Philo AOs */ - = { - &l_philo[0].super, - &l_philo[1].super, - &l_philo[2].super, - &l_philo[3].super, - &l_philo[4].super -}; - - - - /* opaque pointer to the Table AO */ - = &l_table.super; - - - - uint8_t n; -Philo *me; -for (n = 0U; n < N_PHILO; ++n) { - me = &l_philo[n]; - QActive_ctor(&me->super, Q_STATE_CAST(&Philo_initial)); - QTimeEvt_ctorX(&me->timeEvt, &me->super, TIMEOUT_SIG, 0U); -} - - - - uint8_t n; -Table *me = &l_table; - -QActive_ctor(&me->super, Q_STATE_CAST(&Table_initial)); - -for (n = 0U; n < N_PHILO; ++n) { - me->fork[n] = FREE; - me->isHungry[n] = 0U; -} - - #ifndef DPP_H -#define DPP_H + #ifndef DPP_H_ +#define DPP_H_ -enum DPPSignals { - EAT_SIG = Q_USER_SIG, /* published by Table to let a philosopher eat */ - DONE_SIG, /* published by Philosopher when done eating */ - PAUSE_SIG, /* published by BSP to pause serving forks */ - SERVE_SIG, /* published by BSP to serve re-start serving forks */ - TEST_SIG, /* published by BSP to test the application */ - MAX_PUB_SIG, /* the last published signal */ +$declare ${Shared} - HUNGRY_SIG, /* posted direclty to Table from hungry Philo */ - TIMEOUT_SIG, /* used by Philosophers for time events */ - MAX_SIG /* the last signal */ -}; +#ifdef QXK_H_ -$declare${Events::TableEvt} +extern QXThread * const TH_XThread1; +void XThread1_ctor(void); -/* number of philosophers */ -#define N_PHILO ((uint8_t)5) +extern QXThread * const TH_XThread2; +void XThread2_ctor(void); -$declare${AOs::Philo_ctor} -$declare${AOs::AO_Philo[N_PHILO]} +extern QXSemaphore TH_sema; +extern QXMutex TH_mutex; -$declare${AOs::Table_ctor} -$declare${AOs::AO_Table} +#endif // QXK_H_ -#ifdef QP_INC_QXK_H_ - void Test1_ctor(void); - extern QXThread * const XT_Test1; - void Test2_ctor(void); - extern QXThread * const XT_Test2; -#endif /* QP_INC_QXK_H_ */ - -#endif /* DPP_H */ - +#endif // DPP_H_ - #include "qpc.h" -#include "dpp.h" -#include "bsp.h" + #include "qpc.h" // QP/C real-time embedded framework +#include "dpp.h" // DPP Application interface +#include "bsp.h" // Board Support Package -Q_DEFINE_THIS_MODULE("philo") +$declare ${AOs::Philo} -/* Active object class -----------------------------------------------------*/ -$declare${AOs::Philo} +//---------------------------------------------------------------------------- +Q_DEFINE_THIS_FILE -/* Local objects -----------------------------------------------------------*/ -static Philo l_philo[N_PHILO]; /* storage for all Philos */ +// helper function to provide a randomized think time for Philos +static QTimeEvtCtr think_time(void); // prototype +static inline QTimeEvtCtr think_time(void) { + return (QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + + (BSP_TICKS_PER_SEC/2U)); +} -#define THINK_TIME \ - (QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + (BSP_TICKS_PER_SEC/2U)) -#define EAT_TIME \ - (QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + BSP_TICKS_PER_SEC) +// helper function to provide a randomized eat time for Philos +static QTimeEvtCtr eat_time(void); // prototype +static inline QTimeEvtCtr eat_time(void) { + return (QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + + BSP_TICKS_PER_SEC); +} +//---------------------------------------------------------------------------- -/* helper macro to provide the ID of Philo "me_" */ -#define PHILO_ID(me_) ((uint8_t)((me_) - l_philo)) - -/* Global objects ----------------------------------------------------------*/ -$define${AOs::AO_Philo[N_PHILO]} - -/* Philo definition --------------------------------------------------------*/ -$define${AOs::Philo_ctor} -$define${AOs::Philo} - +$define ${Shared::Philo_ctor} +$define ${Shared::AO_Philo[N_PHILO]} +$define ${AOs::Philo} - #include "qpc.h" -#include "dpp.h" -#include "bsp.h" + #include "qpc.h" // QP/C real-time embedded framework +#include "dpp.h" // DPP Application interface +#include "bsp.h" // Board Support Package -Q_DEFINE_THIS_MODULE("table") +$declare ${AOs::Table} -/* Active object class -----------------------------------------------------*/ -$declare${AOs::Table} +//---------------------------------------------------------------------------- +Q_DEFINE_THIS_FILE -#define RIGHT(n_) ((uint8_t)(((n_) + (N_PHILO - 1U)) % N_PHILO)) -#define LEFT(n_) ((uint8_t)(((n_) + 1U) % N_PHILO)) -#define FREE ((uint8_t)0) -#define USED ((uint8_t)1) +// helper function to provide the RIGHT neighbor of a Philo[n] +static inline uint8_t right(uint8_t const n) { + return (uint8_t)((n + (N_PHILO - 1U)) % N_PHILO); +} -/* Local objects -----------------------------------------------------------*/ -static Table l_table; /* the single instance of the Table active object */ +// helper function to provide the LEFT neighbor of a Philo[n] +static inline uint8_t left(uint8_t const n) { + return (uint8_t)((n + 1U) % N_PHILO); +} -/* Global-scope objects ----------------------------------------------------*/ -$define${AOs::AO_Table} +#define FREE ((uint8_t)0U) +#define USED ((uint8_t)1U) -/*..........................................................................*/ -$define${AOs::Table_ctor} -$define${AOs::Table} - +#define THINKING "thinking" +#define HUNGRY "hungry " +#define EATING "eating " + +//---------------------------------------------------------------------------- + +$define ${Shared::Table_ctor} +$define ${Shared::AO_Table} +$define ${AOs::Table} diff --git a/examples/arm-cm/dpp_mbed-lpc1768/main.c b/examples/arm-cm/dpp_mbed-lpc1768/main.c index fa8de8d8..deac175a 100644 --- a/examples/arm-cm/dpp_mbed-lpc1768/main.c +++ b/examples/arm-cm/dpp_mbed-lpc1768/main.c @@ -1,87 +1,44 @@ -/***************************************************************************** -* Product: DPP example -* Last updated for version 7.1.2 -* Last updated on 2022-10-06 -* -* Q u a n t u m L e a P s -* ------------------------ -* Modern Embedded Software -* -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* -* -*****************************************************************************/ -#include "qpc.h" -#include "dpp.h" -#include "bsp.h" +//============================================================================ +// APP example +// Last updated for version 7.3.0 +// Last updated on 2023-08-09 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. +// +// This program is open source software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Alternatively, this program may be distributed and modified under the +// terms of Quantum Leaps commercial licenses, which expressly supersede +// the GNU General Public License and are specifically designed for +// licensees interested in retaining the proprietary status of their code. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Contact information: +// +// +//============================================================================ +#include "qpc.h" // QP/C real-time embedded framework +#include "dpp.h" // DPP Application interface +#include "bsp.h" // Board Support Package -Q_DEFINE_THIS_FILE - -/*..........................................................................*/ +//............................................................................ int main() { - static QEvt const *tableQueueSto[N_PHILO]; - static QEvt const *philoQueueSto[N_PHILO][N_PHILO]; - static QSubscrList subscrSto[MAX_PUB_SIG]; - static QF_MPOOL_EL(TableEvt) smlPoolSto[2*N_PHILO]; /* small pool */ - uint8_t n; - - Philo_ctor(); /* instantiate all Philosopher active objects */ - Table_ctor(); /* instantiate the Table active object */ - - QF_init(); /* initialize the framework and the underlying RT kernel */ - BSP_init(); /* initialize the Board Support Package */ - - /* object dictionaries... */ - QS_OBJ_DICTIONARY(AO_Table); - QS_OBJ_DICTIONARY(AO_Philo[0]); - QS_OBJ_DICTIONARY(AO_Philo[1]); - QS_OBJ_DICTIONARY(AO_Philo[2]); - QS_OBJ_DICTIONARY(AO_Philo[3]); - QS_OBJ_DICTIONARY(AO_Philo[4]); - - /* initialize publish-subscribe... */ - QF_psInit(subscrSto, Q_DIM(subscrSto)); - - /* initialize event pools... */ - QF_poolInit(smlPoolSto, sizeof(smlPoolSto), sizeof(smlPoolSto[0])); - - /* start the active objects... */ - for (n = 0U; n < N_PHILO; ++n) { - QACTIVE_START(AO_Philo[n], /* AO to start */ - n + 1U, /* QF-priority */ - philoQueueSto[n], /* event queue storage */ - Q_DIM(philoQueueSto[n]), /* queue length [events] */ - (void *)0, /* stack storage (not used) */ - 0U, /* size of the stack [bytes] */ - (void *)0); /* initialization param */ - } - QACTIVE_START(AO_Table, /* AO to start */ - N_PHILO + 1U, /* QF-priority */ - tableQueueSto, /* event queue storage */ - Q_DIM(tableQueueSto), /* queue length [events] */ - (void *)0, /* stack storage (not used) */ - 0U, /* size of the stack [bytes] */ - (void *)0); /* initialization param */ - - return QF_run(); /* run the QF application */ + QF_init(); // initialize the framework and the underlying RT kernel + BSP_init(); // initialize the BSP + BSP_start(); // start the AOs/Threads + return QF_run(); // run the QF application } diff --git a/examples/arm-cm/dpp_mbed-lpc1768/mbed-lpc1768.jpeg b/examples/arm-cm/dpp_mbed-lpc1768/mbed-lpc1768.jpeg new file mode 100644 index 00000000..5e9ef5b4 Binary files /dev/null and b/examples/arm-cm/dpp_mbed-lpc1768/mbed-lpc1768.jpeg differ diff --git a/examples/arm-cm/dpp_mbed-lpc1768/philo.c b/examples/arm-cm/dpp_mbed-lpc1768/philo.c index 919e39d6..eb6be531 100644 --- a/examples/arm-cm/dpp_mbed-lpc1768/philo.c +++ b/examples/arm-cm/dpp_mbed-lpc1768/philo.c @@ -1,160 +1,160 @@ -/*$file${.::philo.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* -* Model: dpp.qm -* File: ${.::philo.c} -* -* This code has been generated by QM 5.2.4 . -* DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. -* -* SPDX-License-Identifier: GPL-3.0-or-later -* -* This generated code is open source software: you can redistribute it under -* the terms of the GNU General Public License as published by the Free -* Software Foundation. -* -* This code is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -* more details. -* -* NOTE: -* Alternatively, this generated code may be distributed under the terms -* of Quantum Leaps commercial licenses, which expressly supersede the GNU -* General Public License and are specifically designed for licensees -* interested in retaining the proprietary status of their code. -* -* Contact information: -* -* -*/ -/*$endhead${.::philo.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -#include "qpc.h" -#include "dpp.h" -#include "bsp.h" +//$file${.::philo.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// +// Model: dpp.qm +// File: ${.::philo.c} +// +// This code has been generated by QM 5.3.0 . +// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. +// +// SPDX-License-Identifier: GPL-3.0-or-later +// +// This generated code is open source software: you can redistribute it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation. +// +// This code is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// NOTE: +// Alternatively, this generated code may be distributed under the terms +// of Quantum Leaps commercial licenses, which expressly supersede the GNU +// General Public License and are specifically designed for licensees +// interested in retaining the proprietary status of their code. +// +// Contact information: +// +// +// +//$endhead${.::philo.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +#include "qpc.h" // QP/C real-time embedded framework +#include "dpp.h" // DPP Application interface +#include "bsp.h" // Board Support Package -Q_DEFINE_THIS_MODULE("philo") +//$declare${AOs::Philo} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/* Active object class -----------------------------------------------------*/ -/*$declare${AOs::Philo} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${AOs::Philo} ............................................................*/ -typedef struct { -/* protected: */ +//${AOs::Philo} .............................................................. +typedef struct Philo { +// protected: QActive super; -/* private: */ +// private: QTimeEvt timeEvt; + uint8_t id; + +// public: } Philo; -/* protected: */ +extern Philo Philo_inst[N_PHILO]; + +// protected: static QState Philo_initial(Philo * const me, void const * const par); static QState Philo_thinking(Philo * const me, QEvt const * const e); static QState Philo_hungry(Philo * const me, QEvt const * const e); static QState Philo_eating(Philo * const me, QEvt const * const e); -/*$enddecl${AOs::Philo} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$enddecl${AOs::Philo} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -/* Local objects -----------------------------------------------------------*/ -static Philo l_philo[N_PHILO]; /* storage for all Philos */ +//---------------------------------------------------------------------------- +Q_DEFINE_THIS_FILE -#define THINK_TIME \ - (QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + (BSP_TICKS_PER_SEC/2U)) -#define EAT_TIME \ - (QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + BSP_TICKS_PER_SEC) - -/* helper macro to provide the ID of Philo "me_" */ -#define PHILO_ID(me_) ((uint8_t)((me_) - l_philo)) - -/* Global objects ----------------------------------------------------------*/ -/*$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* Check for the minimum required QP version */ -#if (QP_VERSION < 700U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) -#error qpc version 7.0.0 or higher required -#endif -/*$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ - -/*$define${AOs::AO_Philo[N_PHILO]} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${AOs::AO_Philo[N_PHILO]} ................................................*/ -QActive * const AO_Philo[N_PHILO] = { - &l_philo[0].super, - &l_philo[1].super, - &l_philo[2].super, - &l_philo[3].super, - &l_philo[4].super -}; -/*$enddef${AOs::AO_Philo[N_PHILO]} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ - -/* Philo definition --------------------------------------------------------*/ -/*$define${AOs::Philo_ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${AOs::Philo_ctor} .......................................................*/ -void Philo_ctor(void) { - uint8_t n; - Philo *me; - for (n = 0U; n < N_PHILO; ++n) { - me = &l_philo[n]; - QActive_ctor(&me->super, Q_STATE_CAST(&Philo_initial)); - QTimeEvt_ctorX(&me->timeEvt, &me->super, TIMEOUT_SIG, 0U); - } +// helper function to provide a randomized think time for Philos +static QTimeEvtCtr think_time(void); // prototype +static inline QTimeEvtCtr think_time(void) { + return (QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + + (BSP_TICKS_PER_SEC/2U)); } -/*$enddef${AOs::Philo_ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*$define${AOs::Philo} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/*${AOs::Philo} ............................................................*/ +// helper function to provide a randomized eat time for Philos +static QTimeEvtCtr eat_time(void); // prototype +static inline QTimeEvtCtr eat_time(void) { + return (QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + + BSP_TICKS_PER_SEC); +} +//---------------------------------------------------------------------------- -/*${AOs::Philo::SM} ........................................................*/ +//$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// Check for the minimum required QP version +#if (QP_VERSION < 730U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) +#error qpc version 7.3.0 or higher required +#endif +//$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +//$define${Shared::Philo_ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${Shared::Philo_ctor} ...................................................... +void Philo_ctor(uint_fast8_t const id) { + Philo * const me = &Philo_inst[id]; + QActive_ctor(&me->super, Q_STATE_CAST(&Philo_initial)); + QTimeEvt_ctorX(&me->timeEvt, &me->super, TIMEOUT_SIG, 0U), + me->id = (uint8_t)id; +} +//$enddef${Shared::Philo_ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +//$define${Shared::AO_Philo[N_PHILO]} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${Shared::AO_Philo[N_PHILO]} ............................................... +QActive * const AO_Philo[N_PHILO] = { + &Philo_inst[0].super, + &Philo_inst[1].super, + &Philo_inst[2].super, + &Philo_inst[3].super, + &Philo_inst[4].super +}; +//$enddef${Shared::AO_Philo[N_PHILO]} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +//$define${AOs::Philo} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${AOs::Philo} .............................................................. +Philo Philo_inst[N_PHILO]; + +//${AOs::Philo::SM} .......................................................... static QState Philo_initial(Philo * const me, void const * const par) { - /*${AOs::Philo::SM::initial} */ - static uint8_t registered = (uint8_t)0; /* starts off with 0, per C-standard */ - (void)par; /* unused parameter */ - if (registered == (uint8_t)0) { - registered = (uint8_t)1; + //${AOs::Philo::SM::initial} + Q_UNUSED_PAR(par); - QS_OBJ_DICTIONARY(&l_philo[0].timeEvt); - QS_OBJ_DICTIONARY(&l_philo[1].timeEvt); - QS_OBJ_DICTIONARY(&l_philo[2].timeEvt); - QS_OBJ_DICTIONARY(&l_philo[3].timeEvt); - QS_OBJ_DICTIONARY(&l_philo[4].timeEvt); - - QS_FUN_DICTIONARY(&Philo_initial); - QS_FUN_DICTIONARY(&Philo_thinking); - QS_FUN_DICTIONARY(&Philo_hungry); - QS_FUN_DICTIONARY(&Philo_eating); - } - QS_SIG_DICTIONARY(HUNGRY_SIG, me); /* signal for each Philos */ - QS_SIG_DICTIONARY(TIMEOUT_SIG, me); /* signal for each Philos */ + QS_OBJ_ARR_DICTIONARY(&Philo_inst[me->id], me->id); + QS_OBJ_ARR_DICTIONARY(&Philo_inst[me->id].timeEvt, me->id); QActive_subscribe(&me->super, EAT_SIG); QActive_subscribe(&me->super, TEST_SIG); + + QS_FUN_DICTIONARY(&Philo_thinking); + QS_FUN_DICTIONARY(&Philo_hungry); + QS_FUN_DICTIONARY(&Philo_eating); + return Q_TRAN(&Philo_thinking); } -/*${AOs::Philo::SM::thinking} ..............................................*/ +//${AOs::Philo::SM::thinking} ................................................ static QState Philo_thinking(Philo * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${AOs::Philo::SM::thinking} */ + //${AOs::Philo::SM::thinking} case Q_ENTRY_SIG: { - QTimeEvt_armX(&me->timeEvt, THINK_TIME, 0U); + QTimeEvt_armX(&me->timeEvt, think_time(), 0U); status_ = Q_HANDLED(); break; } - /*${AOs::Philo::SM::thinking} */ + //${AOs::Philo::SM::thinking} case Q_EXIT_SIG: { - QTimeEvt_disarm(&me->timeEvt); + (void)QTimeEvt_disarm(&me->timeEvt); status_ = Q_HANDLED(); break; } - /*${AOs::Philo::SM::thinking::TIMEOUT} */ + //${AOs::Philo::SM::thinking::TIMEOUT} case TIMEOUT_SIG: { status_ = Q_TRAN(&Philo_hungry); break; } - /*${AOs::Philo::SM::thinking::EAT, DONE} */ - case EAT_SIG: /* intentionally fall through */ + //${AOs::Philo::SM::thinking::EAT, DONE} + case EAT_SIG: // intentionally fall through case DONE_SIG: { - /* EAT or DONE must be for other Philos than this one */ - Q_ASSERT_ID(10, Q_EVT_CAST(TableEvt)->philoNum != PHILO_ID(me)); + // EAT or DONE must be for other Philos than this one + Q_ASSERT(Q_EVT_CAST(TableEvt)->philoId != me->id); + status_ = Q_HANDLED(); + break; + } + //${AOs::Philo::SM::thinking::TEST} + case TEST_SIG: { status_ = Q_HANDLED(); break; } @@ -166,22 +166,26 @@ static QState Philo_thinking(Philo * const me, QEvt const * const e) { return status_; } -/*${AOs::Philo::SM::hungry} ................................................*/ +//${AOs::Philo::SM::hungry} .................................................. static QState Philo_hungry(Philo * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${AOs::Philo::SM::hungry} */ + //${AOs::Philo::SM::hungry} case Q_ENTRY_SIG: { + #ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, HUNGRY_SIG, me->id); + #else TableEvt *pe = Q_NEW(TableEvt, HUNGRY_SIG); - pe->philoNum = PHILO_ID(me); - QACTIVE_POST(AO_Table, &pe->super, me); + pe->philoId = me->id; + #endif + QACTIVE_POST(AO_Table, &pe->super, &me->super); status_ = Q_HANDLED(); break; } - /*${AOs::Philo::SM::hungry::EAT} */ + //${AOs::Philo::SM::hungry::EAT} case EAT_SIG: { - /*${AOs::Philo::SM::hungry::EAT::[Q_EVT_CAST(TableEvt)->philoNum=~} */ - if (Q_EVT_CAST(TableEvt)->philoNum == PHILO_ID(me)) { + //${AOs::Philo::SM::hungry::EAT::[e->philoId==me->iid]} + if (Q_EVT_CAST(TableEvt)->philoId == me->id) { status_ = Q_TRAN(&Philo_eating); } else { @@ -189,10 +193,10 @@ static QState Philo_hungry(Philo * const me, QEvt const * const e) { } break; } - /*${AOs::Philo::SM::hungry::DONE} */ + //${AOs::Philo::SM::hungry::DONE} case DONE_SIG: { - /* DONE must be for other Philos than this one */ - Q_ASSERT_ID(20, Q_EVT_CAST(TableEvt)->philoNum != PHILO_ID(me)); + // DONE must be for other Philos than this one + Q_ASSERT(Q_EVT_CAST(TableEvt)->philoId != me->id); status_ = Q_HANDLED(); break; } @@ -204,35 +208,40 @@ static QState Philo_hungry(Philo * const me, QEvt const * const e) { return status_; } -/*${AOs::Philo::SM::eating} ................................................*/ +//${AOs::Philo::SM::eating} .................................................. static QState Philo_eating(Philo * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${AOs::Philo::SM::eating} */ + //${AOs::Philo::SM::eating} case Q_ENTRY_SIG: { - QTimeEvt_armX(&me->timeEvt, EAT_TIME, 0U); + QTimeEvt_armX(&me->timeEvt, eat_time(), 0U); status_ = Q_HANDLED(); break; } - /*${AOs::Philo::SM::eating} */ + //${AOs::Philo::SM::eating} case Q_EXIT_SIG: { + (void)QTimeEvt_disarm(&me->timeEvt); + + #ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, DONE_SIG, me->id); + #else TableEvt *pe = Q_NEW(TableEvt, DONE_SIG); - pe->philoNum = PHILO_ID(me); + pe->philoId = me->id; + #endif QACTIVE_PUBLISH(&pe->super, &me->super); - QTimeEvt_disarm(&me->timeEvt); status_ = Q_HANDLED(); break; } - /*${AOs::Philo::SM::eating::TIMEOUT} */ + //${AOs::Philo::SM::eating::TIMEOUT} case TIMEOUT_SIG: { status_ = Q_TRAN(&Philo_thinking); break; } - /*${AOs::Philo::SM::eating::EAT, DONE} */ - case EAT_SIG: /* intentionally fall through */ + //${AOs::Philo::SM::eating::EAT, DONE} + case EAT_SIG: // intentionally fall through case DONE_SIG: { - /* EAT or DONE must be for other Philos than this one */ - Q_ASSERT_ID(30, Q_EVT_CAST(TableEvt)->philoNum != PHILO_ID(me)); + // EAT or DONE must be for other Philos than this one + Q_ASSERT(Q_EVT_CAST(TableEvt)->philoId != me->id); status_ = Q_HANDLED(); break; } @@ -243,5 +252,4 @@ static QState Philo_eating(Philo * const me, QEvt const * const e) { } return status_; } -/*$enddef${AOs::Philo} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ - +//$enddef${AOs::Philo} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/examples/arm-cm/dpp_mbed-lpc1768/qk/armclang/dpp-qk.sct b/examples/arm-cm/dpp_mbed-lpc1768/qk/armclang/dpp-qk.sct new file mode 100644 index 00000000..cfd8b9c1 --- /dev/null +++ b/examples/arm-cm/dpp_mbed-lpc1768/qk/armclang/dpp-qk.sct @@ -0,0 +1,23 @@ +; ************************************************************* +; *** Scatter-Loading Description File generated by uVision *** +; +; Modified by Quantum Leaps: +; added STACK as the first section in RW_STACK +; ************************************************************* + +LR_IROM1 0x00000000 0x00080000 { ; load region size_region + ER_IROM1 0x00000000 0x00080000 { ; load address = execution address + *.o (RESET, +First) + *(InRoot$$Sections) + .ANY (+RO) + .ANY (+XO) + } + + RW_STACK 0x10000000 { ; <== Quantum Leaps + * (STACK, +First) + } + RW_IRAM1 +0 (0x00008000 - 2048) { ; NOTE: assume STACK size 2048! + .ANY (+RW +ZI) + } +} + diff --git a/examples/arm-cm/dpp_mbed-lpc1768/qk/armclang/dpp-qk.uvoptx b/examples/arm-cm/dpp_mbed-lpc1768/qk/armclang/dpp-qk.uvoptx index 93313050..d857806d 100644 --- a/examples/arm-cm/dpp_mbed-lpc1768/qk/armclang/dpp-qk.uvoptx +++ b/examples/arm-cm/dpp_mbed-lpc1768/qk/armclang/dpp-qk.uvoptx @@ -8,7 +8,7 @@ *.c *.s*; *.src; *.a* - *.obj + *.obj; *.o *.lib *.txt; *.h; *.inc; *.md *.plm @@ -406,6 +406,13 @@ + + 1 + 1 + 0 + 2 + 10000000 +
@@ -491,7 +498,7 @@ 1 0 0 - 0 + 3 @@ -502,7 +509,7 @@ - BIN\UL2CM3.DLL + BIN\CMSIS_AGDI.dll @@ -649,18 +656,6 @@ 0 0 0 - ..\..\main.c - main.c - 0 - 0 - - - 1 - 5 - 1 - 0 - 0 - 0 ..\..\philo.c philo.c 0 @@ -668,7 +663,7 @@ 1 - 6 + 5 1 0 0 @@ -680,13 +675,13 @@ 1 - 7 + 6 1 0 0 0 - ..\..\..\..\..\include\qstamp.c - qstamp.c + ..\..\main.c + main.c 0 0 @@ -700,7 +695,7 @@ 0 2 - 8 + 7 1 0 0 @@ -712,7 +707,7 @@ 2 - 9 + 8 2 0 0 @@ -732,7 +727,7 @@ 0 3 - 10 + 9 1 0 0 @@ -744,7 +739,7 @@ 3 - 11 + 10 1 0 0 @@ -756,7 +751,7 @@ 3 - 12 + 11 1 0 0 @@ -768,7 +763,7 @@ 3 - 13 + 12 1 0 0 @@ -780,7 +775,7 @@ 3 - 14 + 13 1 0 0 @@ -792,7 +787,7 @@ 3 - 15 + 14 1 0 0 @@ -804,7 +799,7 @@ 3 - 16 + 15 1 0 0 @@ -816,19 +811,7 @@ 3 - 17 - 5 - 0 - 0 - 0 - ..\..\..\..\..\src\qf_pkg.h - qf_pkg.h - 0 - 0 - - - 3 - 18 + 16 1 0 0 @@ -840,7 +823,7 @@ 3 - 19 + 17 1 0 0 @@ -852,7 +835,7 @@ 3 - 20 + 18 1 0 0 @@ -864,7 +847,7 @@ 3 - 21 + 19 1 0 0 @@ -876,7 +859,7 @@ 3 - 22 + 20 1 0 0 @@ -888,7 +871,7 @@ 3 - 23 + 21 1 0 0 @@ -898,30 +881,6 @@ 0 0 - - 3 - 24 - 5 - 0 - 0 - 0 - ..\..\..\..\..\src\qk_pkg.h - qk_pkg.h - 0 - 0 - - - 3 - 25 - 5 - 0 - 0 - 0 - ..\..\..\..\..\src\qf\qf_pkg.h - qf_pkg.h - 0 - 0 - @@ -932,43 +891,7 @@ 0 4 - 26 - 5 - 0 - 0 - 0 - ..\..\..\..\..\ports\arm-cm\qk\armclang\qep_port.h - qep_port.h - 0 - 0 - - - 4 - 27 - 5 - 0 - 0 - 0 - ..\..\..\..\..\ports\arm-cm\qk\armclang\qf_port.h - qf_port.h - 0 - 0 - - - 4 - 28 - 5 - 0 - 0 - 0 - ..\..\..\..\..\ports\arm-cm\qk\armclang\qk_port.h - qk_port.h - 0 - 0 - - - 4 - 29 + 22 1 0 0 @@ -980,7 +903,7 @@ 4 - 30 + 23 5 0 0 @@ -1000,7 +923,7 @@ 0 5 - 31 + 24 1 0 0 @@ -1012,7 +935,7 @@ 5 - 32 + 25 1 0 0 @@ -1024,25 +947,25 @@ 5 - 33 - 5 + 26 + 1 0 0 0 - ..\..\..\..\..\src\qs\qs_pkg.h - qs_pkg.h + ..\..\..\..\..\src\qs\qs_rx.c + qs_rx.c 0 0 5 - 34 - 5 + 27 + 1 0 0 0 - ..\..\..\..\..\src\qs_pkg.h - qs_pkg.h + ..\..\..\..\..\src\qs\qstamp.c + qstamp.c 0 0 diff --git a/examples/arm-cm/dpp_mbed-lpc1768/qk/armclang/dpp-qk.uvprojx b/examples/arm-cm/dpp_mbed-lpc1768/qk/armclang/dpp-qk.uvprojx index b9d96f14..121525ed 100644 --- a/examples/arm-cm/dpp_mbed-lpc1768/qk/armclang/dpp-qk.uvprojx +++ b/examples/arm-cm/dpp_mbed-lpc1768/qk/armclang/dpp-qk.uvprojx @@ -337,7 +337,7 @@ 0 - rvmdk __FPU_PRESENT + ..\..;..\..\..\..\..\include;..\..\..\..\..\ports\arm-cm\qk\armclang;..\..\..\..\..\3rd_party\CMSIS\Include;..\..\..\..\..\3rd_party\mbed-lpc1768 @@ -361,7 +361,7 @@ - 1 + 0 0 0 0 @@ -370,7 +370,7 @@ 0x00000000 0x20000000 - + dpp-qk.sct --entry Reset_Handler @@ -398,11 +398,6 @@ 5 ..\..\dpp.h - - main.c - 1 - ..\..\main.c - philo.c 1 @@ -414,9 +409,9 @@ ..\..\table.c - qstamp.c + main.c 1 - ..\..\..\..\..\include\qstamp.c + ..\..\main.c @@ -473,11 +468,6 @@ 1 ..\..\..\..\..\src\qf\qf_mem.c - - qf_pkg.h - 5 - ..\..\..\..\..\src\qf_pkg.h - qf_ps.c 1 @@ -508,36 +498,11 @@ 1 ..\..\..\..\..\src\qk\qk.c - - qk_pkg.h - 5 - ..\..\..\..\..\src\qk_pkg.h - - - qf_pkg.h - 5 - ..\..\..\..\..\src\qf\qf_pkg.h - QP_port - - qep_port.h - 5 - ..\..\..\..\..\ports\arm-cm\qk\armclang\qep_port.h - - - qf_port.h - 5 - ..\..\..\..\..\ports\arm-cm\qk\armclang\qf_port.h - - - qk_port.h - 5 - ..\..\..\..\..\ports\arm-cm\qk\armclang\qk_port.h - qk_port.c 1 @@ -633,14 +598,14 @@ ..\..\..\..\..\src\qs\qs_fp.c - qs_pkg.h - 5 - ..\..\..\..\..\src\qs\qs_pkg.h + qs_rx.c + 1 + ..\..\..\..\..\src\qs\qs_rx.c - qs_pkg.h - 5 - ..\..\..\..\..\src\qs_pkg.h + qstamp.c + 1 + ..\..\..\..\..\src\qs\qstamp.c @@ -650,7 +615,7 @@ dpp-rel 0x4 ARM-ADS - 6130001::V6.13.1::.\ARMCLANG + 6160000::V6.16::ARMCLANG 1 @@ -977,7 +942,7 @@ 0 - NDEBUG __FPU_PRESENT + NDEBUG ..\..;..\..\..\..\..\include;..\..\..\..\..\ports\arm-cm\qk\armclang;..\..\..\..\..\3rd_party\CMSIS\Include;..\..\..\..\..\3rd_party\mbed-lpc1768 @@ -1001,7 +966,7 @@ - 1 + 0 0 0 0 @@ -1038,11 +1003,6 @@ 5 ..\..\dpp.h - - main.c - 1 - ..\..\main.c - philo.c 1 @@ -1054,9 +1014,9 @@ ..\..\table.c - qstamp.c + main.c 1 - ..\..\..\..\..\include\qstamp.c + ..\..\main.c @@ -1113,11 +1073,6 @@ 1 ..\..\..\..\..\src\qf\qf_mem.c - - qf_pkg.h - 5 - ..\..\..\..\..\src\qf_pkg.h - qf_ps.c 1 @@ -1148,36 +1103,11 @@ 1 ..\..\..\..\..\src\qk\qk.c - - qk_pkg.h - 5 - ..\..\..\..\..\src\qk_pkg.h - - - qf_pkg.h - 5 - ..\..\..\..\..\src\qf\qf_pkg.h - QP_port - - qep_port.h - 5 - ..\..\..\..\..\ports\arm-cm\qk\armclang\qep_port.h - - - qf_port.h - 5 - ..\..\..\..\..\ports\arm-cm\qk\armclang\qf_port.h - - - qk_port.h - 5 - ..\..\..\..\..\ports\arm-cm\qk\armclang\qk_port.h - qk_port.c 1 @@ -1273,14 +1203,14 @@ ..\..\..\..\..\src\qs\qs_fp.c - qs_pkg.h - 5 - ..\..\..\..\..\src\qs\qs_pkg.h + qs_rx.c + 1 + ..\..\..\..\..\src\qs\qs_rx.c - qs_pkg.h - 5 - ..\..\..\..\..\src\qs_pkg.h + qstamp.c + 1 + ..\..\..\..\..\src\qs\qstamp.c @@ -1617,7 +1547,7 @@ 0 - Q_SPY __FPU_PRESENT + Q_SPY ,QF_ON_CONTEXT_SW,_FPU_PRESENT ..\..;..\..\..\..\..\include;..\..\..\..\..\ports\arm-cm\qk\armclang;..\..\..\..\..\3rd_party\CMSIS\Include;..\..\..\..\..\3rd_party\mbed-lpc1768 @@ -1641,7 +1571,7 @@ - 1 + 0 0 0 0 @@ -1678,11 +1608,6 @@ 5 ..\..\dpp.h - - main.c - 1 - ..\..\main.c - philo.c 1 @@ -1694,9 +1619,9 @@ ..\..\table.c - qstamp.c + main.c 1 - ..\..\..\..\..\include\qstamp.c + ..\..\main.c @@ -1753,11 +1678,6 @@ 1 ..\..\..\..\..\src\qf\qf_mem.c - - qf_pkg.h - 5 - ..\..\..\..\..\src\qf_pkg.h - qf_ps.c 1 @@ -1788,36 +1708,11 @@ 1 ..\..\..\..\..\src\qk\qk.c - - qk_pkg.h - 5 - ..\..\..\..\..\src\qk_pkg.h - - - qf_pkg.h - 5 - ..\..\..\..\..\src\qf\qf_pkg.h - QP_port - - qep_port.h - 5 - ..\..\..\..\..\ports\arm-cm\qk\armclang\qep_port.h - - - qf_port.h - 5 - ..\..\..\..\..\ports\arm-cm\qk\armclang\qf_port.h - - - qk_port.h - 5 - ..\..\..\..\..\ports\arm-cm\qk\armclang\qk_port.h - qk_port.c 1 @@ -1844,14 +1739,14 @@ ..\..\..\..\..\src\qs\qs_fp.c - qs_pkg.h - 5 - ..\..\..\..\..\src\qs\qs_pkg.h + qs_rx.c + 1 + ..\..\..\..\..\src\qs\qs_rx.c - qs_pkg.h - 5 - ..\..\..\..\..\src\qs_pkg.h + qstamp.c + 1 + ..\..\..\..\..\src\qs\qstamp.c diff --git a/examples/arm-cm/dpp_mbed-lpc1768/qk/bsp.c b/examples/arm-cm/dpp_mbed-lpc1768/qk/bsp.c index 17eb91d8..46b39ff9 100644 --- a/examples/arm-cm/dpp_mbed-lpc1768/qk/bsp.c +++ b/examples/arm-cm/dpp_mbed-lpc1768/qk/bsp.c @@ -1,66 +1,59 @@ -/***************************************************************************** -* Product: DPP example, NXP mbed-LPC1768 board, QK kernel -* Last updated for version 6.9.3 -* Last updated on 2021-03-03 -* -* Q u a n t u m L e a P s -* ------------------------ -* Modern Embedded Software -* -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* -* -*****************************************************************************/ -#include "qpc.h" -#include "dpp.h" -#include "bsp.h" +//============================================================================ +// Product: DPP example, NXP mbed-LPC1768 board, QK kernel +// Last updated for version 7.3.0 +// Last updated on 2023-08-15 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +//============================================================================ +#include "qpc.h" // QP/C real-time embedded framework +#include "dpp.h" // DPP Application interface +#include "bsp.h" // Board Support Package -#include "LPC17xx.h" /* CMSIS-compliant header file for the MCU used */ -/* add other drivers if necessary... */ +#include "LPC17xx.h" // CMSIS-compliant header file for the MCU used +// add other drivers if necessary... -Q_DEFINE_THIS_FILE +Q_DEFINE_THIS_FILE // define the name of this file for assertions -/* ISRs defined in this BSP ------------------------------------------------*/ -void SysTick_Handler(void); -void EINT0_IRQHandler(void); +// Local-scope objects ----------------------------------------------------- +#define LED_1 (1U << 18U) // P1.18 +#define LED_2 (1U << 20U) // P1.20 +#define LED_3 (1U << 21U) // P1.21 +#define LED_4 (1U << 23U) // P1.23 -/* Local-scope objects -----------------------------------------------------*/ -/* LEDs available on the board */ -#define LED_1 (1U << 18) /* P1.18 */ -#define LED_2 (1U << 20) /* P1.20 */ -#define LED_3 (1U << 21) /* P1.21 */ -#define LED_4 (1U << 23) /* P1.23 */ +// Push-Button wired externally to DIP8 (P0.6) +#define BTN_EXT (1U << 6U) // P0.6 -/* Push-Button wired externally to DIP8 (P0.6) */ -#define BTN_EXT (1U << 6) /* P0.6 */ - -static uint32_t l_rnd; /* random seed */ +static uint32_t l_rndSeed; #ifdef Q_SPY QSTimeCtr QS_tickTime_; QSTimeCtr QS_tickPeriod_; - /* QSpy source IDs */ + // QSpy source IDs static QSpyId const l_SysTick_Handler = { 0U }; static QSpyId const l_EINT0_IRQHandler = { 0U }; @@ -68,273 +61,377 @@ static uint32_t l_rnd; /* random seed */ #define UART_FR_TXFE 0x80U #define UART_TXFIFO_DEPTH 16U - enum AppRecords { /* application-specific trace records */ - PHILO_STAT = QS_USER + enum AppRecords { // application-specific trace records + PHILO_STAT = QS_USER, + PAUSED_STAT, + CONTEXT_SW, }; #endif -/* ISRs used in the application ==========================================*/ +//============================================================================ +// Error handler and ISRs... + +Q_NORETURN Q_onError(char const * const module, int_t const id) { + // NOTE: this implementation of the error handler is intended only + // for debugging and MUST be changed for deployment of the application + // (assuming that you ship your production code with assertions enabled). + Q_UNUSED_PAR(module); + Q_UNUSED_PAR(id); + QS_ASSERTION(module, id, 10000U); + +#ifndef NDEBUG + // light up all LEDs + LPC_GPIO1->FIOSET = LED_1; // turn LED on + LPC_GPIO1->FIOSET = LED_2; // turn LED on + LPC_GPIO1->FIOSET = LED_3; // turn LED on + LPC_GPIO1->FIOSET = LED_4; // turn LED on + // for debugging, hang on in an endless loop... + for (;;) { + } +#else + NVIC_SystemReset(); + for (;;) { // explicitly "no-return" + } +#endif +} +//............................................................................ +void assert_failed(char const * const module, int_t const id); // prototype +void assert_failed(char const * const module, int_t const id) { + Q_onError(module, id); +} + +// ISRs used in the application ============================================== + +void SysTick_Handler(void); // prototype void SysTick_Handler(void) { - /* state of the button debouncing, see below */ - static struct ButtonsDebouncing { + QK_ISR_ENTRY(); // inform QK about entering an ISR + + QTIMEEVT_TICK_X(0U, &l_SysTick_Handler); // time events at rate 0 + + // Perform the debouncing of buttons. The algorithm for debouncing + // adapted from the book "Embedded Systems Dictionary" by Jack Ganssle + // and Michael Barr, page 71. + static struct { uint32_t depressed; uint32_t previous; } buttons = { 0U, 0U }; - uint32_t current; - uint32_t tmp; - QK_ISR_ENTRY(); /* inform QK about entering an ISR */ + uint32_t current = ~LPC_GPIO0->FIOPIN; // read P0 with state of Buttons + uint32_t tmp = buttons.depressed; // save the depressed buttons + buttons.depressed |= (buttons.previous & current); // set depressed + buttons.depressed &= (buttons.previous | current); // clear released + buttons.previous = current; // update the history + tmp ^= buttons.depressed; // changed debounced depressed + current = buttons.depressed; -#ifdef Q_SPY - { - tmp = SysTick->CTRL; /* clear CTRL_COUNTFLAG */ - QS_tickTime_ += QS_tickPeriod_; /* account for the clock rollover */ - } -#endif - - QTIMEEVT_TICK_X(0U, &l_SysTick_Handler); /* process time events for rate 0 */ - - /* get state of the buttons */ - /* Perform the debouncing of buttons. The algorithm for debouncing - * adapted from the book "Embedded Systems Dictionary" by Jack Ganssle - * and Michael Barr, page 71. - */ - current = ~LPC_GPIO0->FIOPIN; /* read P0 with the state of the Buttons */ - tmp = buttons.depressed; /* save the debounced depressed buttons */ - buttons.depressed |= (buttons.previous & current); /* set depressed */ - buttons.depressed &= (buttons.previous | current); /* clear released */ - buttons.previous = current; /* update the history */ - tmp ^= buttons.depressed; /* changed debounced depressed */ - if ((tmp & BTN_EXT) != 0U) { /* debounced BTN_EXT state changed? */ - if ((buttons.depressed & BTN_EXT) != 0U) { /* is BTN_EXT depressed? */ - static QEvt const pauseEvt = { PAUSE_SIG, 0U, 0U}; + if ((tmp & BTN_EXT) != 0U) { // debounced BTN_EXT state changed? + if ((current & BTN_EXT) != 0U) { // is BTN_EXT depressed? + static QEvt const pauseEvt = QEVT_INITIALIZER(PAUSE_SIG); QACTIVE_PUBLISH(&pauseEvt, &l_SysTick_Handler); } - else { /* the button is released */ - static QEvt const serveEvt = { SERVE_SIG, 0U, 0U}; + else { // the button is released + static QEvt const serveEvt = QEVT_INITIALIZER(SERVE_SIG); QACTIVE_PUBLISH(&serveEvt, &l_SysTick_Handler); } } - QK_ISR_EXIT(); /* inform QK about exiting an ISR */ +#ifdef Q_SPY + tmp = SysTick->CTRL; // clear CTRL_COUNTFLAG + QS_tickTime_ += QS_tickPeriod_; // account for the clock rollover +#endif // Q_SPY + + QK_ISR_EXIT(); // inform QK about exiting an ISR } -/*..........................................................................*/ +//............................................................................ +// interrupt handler for testing preemptions in QK +void EINT0_IRQHandler(void); // prototype void EINT0_IRQHandler(void) { - QK_ISR_ENTRY(); /* inform QK about entering an ISR */ + QK_ISR_ENTRY(); // inform QK about entering an ISR - QACTIVE_POST(AO_Table, Q_NEW(QEvt, MAX_PUB_SIG), /* for testing... */ - &l_EINT0_IRQHandler); + // for testing... + static QEvt const testEvt = QEVT_INITIALIZER(TEST_SIG); + QACTIVE_POST(AO_Table, &testEvt, &l_EINT0_IRQHandler); - QK_ISR_EXIT(); /* inform QK about exiting an ISR */ + QK_ISR_EXIT(); // inform QK about exiting an ISR } +//............................................................................ +#ifdef QF_ON_CONTEXT_SW +// NOTE: the context-switch callback is called with interrupts DISABLED +void QF_onContextSw(QActive *prev, QActive *next) { + Q_UNUSED_PAR(prev); + Q_UNUSED_PAR(next); + + QS_BEGIN_INCRIT(CONTEXT_SW, 0U) // in critical section! + QS_OBJ(prev); + QS_OBJ(next); + QS_END_INCRIT() +} +#endif // QF_ON_CONTEXT_SW + +//============================================================================ +// BSP functions... -/* BSP functions ===========================================================*/ void BSP_init(void) { - /* enable the MemManage_Handler for MPU exception */ - SCB->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk; - - /* Configure the MPU to prevent NULL-pointer dereferencing ... */ - MPU->RBAR = 0x0U /* base address */ - | MPU_RBAR_VALID_Msk /* valid region */ - | (MPU_RBAR_REGION_Msk & 7U); /* region 7 */ - MPU->RASR = (7U << MPU_RASR_SIZE_Pos) /* 2**(7+1) region */ - | (0x0U << MPU_RASR_AP_Pos) /* no access */ - | MPU_RASR_ENABLE_Msk; /* region enable */ - - MPU->CTRL = MPU_CTRL_PRIVDEFENA_Msk /* enable background region */ - | MPU_CTRL_ENABLE_Msk; /* enable the MPU */ + // Configure the MPU to prevent NULL-pointer dereferencing ... + MPU->RBAR = 0x0U // base address (NULL) + | MPU_RBAR_VALID_Msk // valid region + | (MPU_RBAR_REGION_Msk & 7U); // region #7 + MPU->RASR = (7U << MPU_RASR_SIZE_Pos) // 2^(7+1) region + | (0x0U << MPU_RASR_AP_Pos) // no-access region + | MPU_RASR_ENABLE_Msk; // region enable + MPU->CTRL = MPU_CTRL_PRIVDEFENA_Msk // enable background region + | MPU_CTRL_ENABLE_Msk; // enable the MPU __ISB(); __DSB(); - /* NOTE: SystemInit() has been already called from the startup code - * but SystemCoreClock needs to be updated - */ + // enable the MemManage_Handler for MPU exception + SCB->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk; + + // NOTE: SystemInit() has been already called from the startup code + // but SystemCoreClock needs to be updated SystemCoreClockUpdate(); - /* turn the GPIO clock on */ + // turn the GPIO clock on LPC_SC->PCONP |= (1U << 15); - /* setup the GPIO pin functions for the LEDs... */ - LPC_PINCON->PINSEL3 &= ~(3U << 4); /* LED_1: function P1.18 to GPIO */ - LPC_PINCON->PINSEL3 &= ~(3U << 8); /* LED_2: function P1.20 to GPIO */ - LPC_PINCON->PINSEL3 &= ~(3U << 10); /* LED_3: function P1.21 to GPIO */ - LPC_PINCON->PINSEL3 &= ~(3U << 14); /* LED_4: function P1.23 to GPIO */ + // setup the GPIO pin functions for the LEDs... + LPC_PINCON->PINSEL3 &= ~(3U << 4); // LED_1: function P1.18 to GPIO + LPC_PINCON->PINSEL3 &= ~(3U << 8); // LED_2: function P1.20 to GPIO + LPC_PINCON->PINSEL3 &= ~(3U << 10); // LED_3: function P1.21 to GPIO + LPC_PINCON->PINSEL3 &= ~(3U << 14); // LED_4: function P1.23 to GPIO - /* Set GPIO-P1 LED pins to output */ + // Set GPIO-P1 LED pins to output LPC_GPIO1->FIODIR |= (LED_1 | LED_2 | LED_3 | LED_4); - /* setup the GPIO pin function for the Button... */ - LPC_PINCON->PINSEL0 &= ~(3U << 12); /* function P0.6 to GPIO, pull-up */ + // setup the GPIO pin function for the Button... + LPC_PINCON->PINSEL0 &= ~(3U << 12); // function P0.6 to GPIO, pull-up - /* Set GPIO-P0 Button pin as input */ + // Set GPIO-P0 Button pin as input LPC_GPIO0->FIODIR &= ~BTN_EXT; - BSP_randomSeed(1234U); + BSP_randomSeed(1234U); // seed the random number generator - if (QS_INIT((void *)0) == 0U) { /* initialize the QS software tracing */ + // initialize the QS software tracing... + if (!QS_INIT((void *)0)) { Q_ERROR(); } + + // dictionaries... QS_OBJ_DICTIONARY(&l_SysTick_Handler); QS_OBJ_DICTIONARY(&l_EINT0_IRQHandler); QS_USR_DICTIONARY(PHILO_STAT); + QS_USR_DICTIONARY(PAUSED_STAT); + QS_USR_DICTIONARY(CONTEXT_SW); - /* setup the QS filters... */ - QS_GLB_FILTER(QS_SM_RECORDS); /* state machine records */ - QS_GLB_FILTER(QS_AO_RECORDS); /* active object records */ - QS_GLB_FILTER(QS_UA_RECORDS); /* all user records */ + QS_ONLY(produce_sig_dict()); + + // setup the QS filters... + QS_GLB_FILTER(QS_ALL_RECORDS); // all records + QS_GLB_FILTER(-QS_QF_TICK); // exclude the clock tick } -/*..........................................................................*/ +//............................................................................ +void BSP_start(void) { + // initialize event pools + static QF_MPOOL_EL(TableEvt) smlPoolSto[2*N_PHILO]; + QF_poolInit(smlPoolSto, sizeof(smlPoolSto), sizeof(smlPoolSto[0])); + + // initialize publish-subscribe + static QSubscrList subscrSto[MAX_PUB_SIG]; + QActive_psInit(subscrSto, Q_DIM(subscrSto)); + + // instantiate and start AOs/threads... + + static QEvt const *philoQueueSto[N_PHILO][10]; + for (uint8_t n = 0U; n < N_PHILO; ++n) { + Philo_ctor(n); + QACTIVE_START(AO_Philo[n], + + // NOTE: set the preemption-threshold of all Philos to + // the same level, so that they cannot preempt each other. + Q_PRIO(n + 3U, N_PHILO + 2U), // QF-prio/pre-thre. + + philoQueueSto[n], // event queue storage + Q_DIM(philoQueueSto[n]), // queue length [events] + (void *)0, 0U, // no stack storage + (void *)0); // no initialization param + } + + static QEvt const *tableQueueSto[N_PHILO]; + Table_ctor(); + QACTIVE_START(AO_Table, + N_PHILO + 7U, // QP prio. of the AO + tableQueueSto, // event queue storage + Q_DIM(tableQueueSto), // queue length [events] + (void *)0, 0U, // no stack storage + (void *)0); // no initialization param +} +//............................................................................ void BSP_displayPhilStat(uint8_t n, char const *stat) { + Q_UNUSED_PAR(n); + if (stat[0] == 'h') { - LPC_GPIO1->FIOSET = LED_1; /* turn LED on */ + LPC_GPIO1->FIOSET = LED_1; // turn LED on } else { - LPC_GPIO1->FIOCLR = LED_1; /* turn LED off */ + LPC_GPIO1->FIOCLR = LED_1; // turn LED off } if (stat[0] == 'e') { - LPC_GPIO1->FIOSET = LED_2; /* turn LED on */ + LPC_GPIO1->FIOSET = LED_2; // turn LED on } else { - LPC_GPIO1->FIOCLR = LED_2; /* turn LED off */ + LPC_GPIO1->FIOCLR = LED_2; // turn LED off } - QS_BEGIN_ID(PHILO_STAT, AO_Philo[n]->prio) /* app-specific record */ - QS_U8(1, n); /* Philosopher number */ - QS_STR(stat); /* Philosopher status */ + // app-specific trace record... + QS_BEGIN_ID(PHILO_STAT, AO_Table->prio) + QS_U8(1, n); // Philosopher number + QS_STR(stat); // Philosopher status QS_END() } -/*..........................................................................*/ -void BSP_displayPaused(uint8_t paused) { +//............................................................................ +void BSP_displayPaused(uint8_t const paused) { if (paused != 0U) { - LPC_GPIO1->FIOSET = LED_3; /* turn LED on */ + LPC_GPIO1->FIOSET = LED_3; // turn LED on } else { - LPC_GPIO1->FIOCLR = LED_3; /* turn LED off */ + LPC_GPIO1->FIOCLR = LED_3; // turn LED off } + + // application-specific trace record + QS_BEGIN_ID(PAUSED_STAT, AO_Table->prio) + QS_U8(1, paused); // Paused status + QS_END() } -/*..........................................................................*/ -uint32_t BSP_random(void) { /* a very cheap pseudo-random-number generator */ - /* "Super-Duper" Linear Congruential Generator (LCG) - * LCG(2^32, 3*7*11*13*23, 0, seed) - */ - l_rnd = l_rnd * (3U*7U*11U*13U*23U); - return l_rnd >> 8; -} -/*..........................................................................*/ +//............................................................................ void BSP_randomSeed(uint32_t seed) { - l_rnd = seed; + l_rndSeed = seed; } -/*..........................................................................*/ +//............................................................................ +uint32_t BSP_random(void) { // a very cheap pseudo-random-number generator + QSchedStatus lockStat = QK_schedLock(N_PHILO); + // "Super-Duper" Linear Congruential Generator (LCG) + // LCG(2^32, 3*7*11*13*23, 0, seed) + // + uint32_t rnd = l_rndSeed * (3U*7U*11U*13U*23U); + l_rndSeed = rnd; // set for the next time + QK_schedUnlock(lockStat); + + return (rnd >> 8U); +} +//............................................................................ void BSP_terminate(int16_t result) { - (void)result; + Q_UNUSED_PAR(result); +} +//............................................................................ +void BSP_ledOn(void) { + LPC_GPIO1->FIOSET = LED_3; // turn LED on +} +//............................................................................ +void BSP_ledOff(void) { + LPC_GPIO1->FIOCLR = LED_3; // turn LED off } - -/* QF callbacks ============================================================*/ +//============================================================================ +// QF callbacks... void QF_onStartup(void) { - /* set up the SysTick timer to fire at BSP_TICKS_PER_SEC rate */ + // set up the SysTick timer to fire at BSP_TICKS_PER_SEC rate SysTick_Config(SystemCoreClock / BSP_TICKS_PER_SEC); - /* set priorities of ALL ISRs used in the system, see NOTE1 - * - * !!!!!!!!!!!!!!!!!!!!!!!!!!!! CAUTION !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - * Assign a priority to EVERY ISR explicitly by calling NVIC_SetPriority(). - * DO NOT LEAVE THE ISR PRIORITIES AT THE DEFAULT VALUE! - */ - NVIC_SetPriority(EINT0_IRQn, QF_AWARE_ISR_CMSIS_PRI); - NVIC_SetPriority(SysTick_IRQn, QF_AWARE_ISR_CMSIS_PRI + 1U); - /* ... */ + // assign all priority bits for preemption-prio. and none to sub-prio. + NVIC_SetPriorityGrouping(0U); - /* enable IRQs in the NVIC... */ + // set priorities of ALL ISRs used in the system, see NOTE1 + NVIC_SetPriority(EINT0_IRQn, QF_AWARE_ISR_CMSIS_PRI + 0U); + NVIC_SetPriority(SysTick_IRQn, QF_AWARE_ISR_CMSIS_PRI + 1U); + // ... + + // enable IRQs in the NVIC... NVIC_EnableIRQ(EINT0_IRQn); } -/*..........................................................................*/ +//............................................................................ void QF_onCleanup(void) { } -/*..........................................................................*/ +//............................................................................ void QK_onIdle(void) { - /* toggle the User LED on and then off, see NOTE2 */ + // toggle the User LED on and then off, see NOTE2 QF_INT_DISABLE(); - LPC_GPIO1->FIOSET = LED_4; /* turn LED on */ - __NOP(); /* a couple of NOPs to actually see the LED glow */ + LPC_GPIO1->FIOSET = LED_4; // turn LED on + __NOP(); // a couple of NOPs to actually see the LED glow __NOP(); __NOP(); __NOP(); - LPC_GPIO1->FIOCLR = LED_4; /* turn LED off */ + LPC_GPIO1->FIOCLR = LED_4; // turn LED off QF_INT_ENABLE(); #ifdef Q_SPY + QF_INT_DISABLE(); + QS_rxParse(); // parse all the received bytes + QF_INT_ENABLE(); - if ((LPC_UART0->LSR & 0x20U) != 0U) { /* TX Holding Register empty? */ - uint16_t fifo = UART_TXFIFO_DEPTH; /* max bytes we can accept */ - uint8_t const *block; + if ((LPC_UART0->LSR & 0x20U) != 0U) { // TX Holding Register empty? + uint16_t fifo = UART_TXFIFO_DEPTH; // max bytes we can accept QF_INT_DISABLE(); - block = QS_getBlock(&fifo); /* try to get next block to transmit */ + // try to get next contiguous block to transmit + uint8_t const *block = QS_getBlock(&fifo); QF_INT_ENABLE(); - while (fifo-- != 0) { /* any bytes in the block? */ - LPC_UART0->THR = *block++; /* put into the FIFO */ + while (fifo-- != 0U) { // any bytes in the block? + LPC_UART0->THR = *block++; // put into the FIFO } } - #elif defined NDEBUG - /* Put the CPU and peripherals to the low-power mode. - * you might need to customize the clock management for your application, - * see the datasheet for your particular Cortex-M MCU. - */ - __WFI(); /* Wait-For-Interrupt */ + // Put the CPU and peripherals to the low-power mode. + // you might need to customize the clock management for your application, + // see the datasheet for your particular Cortex-M MCU. + // + __WFI(); // Wait-For-Interrupt #endif } -/*..........................................................................*/ -Q_NORETURN Q_onAssert(char const * const module, int_t const loc) { - /* - * NOTE: add here your application-specific error handling - */ - (void)module; - (void)loc; - QS_ASSERTION(module, loc, 10000U); /* report assertion to QS */ - NVIC_SystemReset(); -} -/* QS callbacks ============================================================*/ +//============================================================================ +// QS callbacks... #ifdef Q_SPY -static void UART0_setBaudrate(uint32_t baud); /* helper function */ +static void UART0_setBaudrate(uint32_t baud); // helper function -/*..........................................................................*/ +//............................................................................ uint8_t QS_onStartup(void const *arg) { - static uint8_t qsBuf[2*1024]; /* buffer for Quantum Spy */ - QS_initBuf(qsBuf, sizeof(qsBuf)); + Q_UNUSED_PAR(arg); + + static uint8_t qsTxBuf[2*1024]; // buffer for QS-TX channel + QS_initBuf(qsTxBuf, sizeof(qsTxBuf)); + + // TBD: add support for QS-RX channel // setup the P0_2 UART0 TX pin - LPC_PINCON->PINSEL0 &= ~(3U << 4); /* clear P0_2 function */ - LPC_PINCON->PINSEL0 |= (1U << 4); /* P0_2 to UART function (TX) */ - LPC_PINCON->PINMODE0 &= ~(3U << 4); /* P0_2 pull-up register */ + LPC_PINCON->PINSEL0 &= ~(3U << 4); // clear P0_2 function + LPC_PINCON->PINSEL0 |= (1U << 4); // P0_2 to UART function (TX) + LPC_PINCON->PINMODE0 &= ~(3U << 4); // P0_2 pull-up register // setup the P0_3 UART0 RX pin - LPC_PINCON->PINSEL0 &= ~(3U << 6); /* clear P0_3 function */ - LPC_PINCON->PINSEL0 |= (1U << 6); /* P0_3 to UART function (RX) */ - LPC_PINCON->PINMODE0 &= ~(3U << 6); /* P0_3 pull-up register */ + LPC_PINCON->PINSEL0 &= ~(3U << 6); // clear P0_3 function + LPC_PINCON->PINSEL0 |= (1U << 6); // P0_3 to UART function (RX) + LPC_PINCON->PINMODE0 &= ~(3U << 6); // P0_3 pull-up register - /* enable power to UART0 */ + // enable power to UART0 LPC_SC->PCONP |= (1U << 3); - /* enable FIFOs and default RX trigger level */ + // enable FIFOs and default RX trigger level LPC_UART0->FCR = - (1U << 0) /* FIFO Enable - 0 = Disables, 1 = Enabled */ - | (0U << 1) /* Rx Fifo Reset */ - | (0U << 2) /* Tx Fifo Reset */ - | (0U << 6); /* Rx irq trig: 0=1char, 1=4chars, 2=8chars, 3=14chars */ + (1U << 0) // FIFO Enable - 0 = Disables, 1 = Enabled + | (0U << 1) // Rx Fifo Reset + | (0U << 2) // Tx Fifo Reset + | (0U << 6); // Rx irq trig: 0=1char, 1=4chars, 2=8chars, 3=14chars - /* disable IRQs */ + // disable IRQs LPC_UART0->IER = - (0U << 0) /* Rx Data available IRQ disable */ - | (0U << 1) /* Tx Fifo empty IRQ disable */ - | (0U << 2); /* Rx Line Status IRQ disable */ + (0U << 0) // Rx Data available IRQ disable + | (0U << 1) // Tx Fifo empty IRQ disable + | (0U << 2); // Rx Line Status IRQ disable // set default baud rate @@ -342,69 +439,91 @@ uint8_t QS_onStartup(void const *arg) { // format 8-data-bits, 1-stop-bit, parity-none LPC_UART0->LCR = - (3U << 0) /* 8-data-bits */ - | (0U << 2) /* 1 stop-bit */ - | (0U << 3) /* parity disable */ - | (0U << 4); /* parity none */ + (3U << 0) // 8-data-bits + | (0U << 2) // 1 stop-bit + | (0U << 3) // parity disable + | (0U << 4); // parity none QS_tickPeriod_ = SystemCoreClock / BSP_TICKS_PER_SEC; - QS_tickTime_ = QS_tickPeriod_; /* to start the timestamp at zero */ + QS_tickTime_ = QS_tickPeriod_; // to start the timestamp at zero - return 1U; /* return success */ + return 1U; // return success } -/*..........................................................................*/ +//............................................................................ void QS_onCleanup(void) { } -/*..........................................................................*/ -QSTimeCtr QS_onGetTime(void) { /* NOTE: invoked with interrupts DISABLED */ - if ((SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk) == 0) { /* not set? */ +//............................................................................ +QSTimeCtr QS_onGetTime(void) { // NOTE: invoked with interrupts DISABLED + if ((SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk) == 0) { // not set? return QS_tickTime_ - (QSTimeCtr)SysTick->VAL; } - else { /* the rollover occured, but the SysTick_ISR did not run yet */ + else { // the rollover occured, but the SysTick_ISR did not run yet return QS_tickTime_ + QS_tickPeriod_ - (QSTimeCtr)SysTick->VAL; } } -/*..........................................................................*/ +//............................................................................ void QS_onFlush(void) { - uint16_t b; - - QF_INT_DISABLE(); - while ((b = QS_getByte()) != QS_EOD) { /* while not End-Of-Data... */ - QF_INT_ENABLE(); - while ((LPC_UART0->LSR & 0x20U) == 0U) { /* while THR empty... */ - } - LPC_UART0->THR = (b & 0xFFU); /* put into the DR register */ + for (;;) { QF_INT_DISABLE(); + uint16_t b = QS_getByte(); + QF_INT_ENABLE(); + if (b != QS_EOD) { + while ((LPC_UART0->LSR & 0x20U) == 0U) { // while THR empty... + QF_INT_ENABLE(); + QF_CRIT_EXIT_NOP(); + + QF_INT_DISABLE(); + } + LPC_UART0->THR = b; // put into the THR register + QF_INT_ENABLE(); + } + else { + QF_INT_ENABLE(); + break; + } } - QF_INT_ENABLE(); +} +//............................................................................ +//! callback function to reset the target (to be implemented in the BSP) +void QS_onReset(void) { + NVIC_SystemReset(); +} +//............................................................................ +// callback function to execute a user command +void QS_onCommand(uint8_t cmdId, + uint32_t param1, uint32_t param2, uint32_t param3) +{ + Q_UNUSED_PAR(cmdId); + Q_UNUSED_PAR(param1); + Q_UNUSED_PAR(param2); + Q_UNUSED_PAR(param3); } - -/*..........................................................................*/ -/* -* Set the LPC UART0 barud-rate generator according to -* Section 14.4.12 in LPC176x Manual (document UM10360) -*/ +//............................................................................ +// +// Set the LPC UART0 barud-rate generator according to +// Section 14.4.12 in LPC176x Manual (document UM10360) +// static void UART0_setBaudrate(uint32_t baud) { - /* First we check to see if the basic divide with no DivAddVal/MulVal - * ratio gives us an integer result. If it does, we set DivAddVal = 0, - * MulVal = 1. Otherwise, we search the valid ratio value range to find - * the closest match. This could be more elegant, using search methods - * and/or lookup tables, but the brute force method is not that much - * slower, and is more maintainable. - */ - uint32_t PCLK = SystemCoreClock; /* divider /1 set below */ + // First we check to see if the basic divide with no DivAddVal/MulVal + // ratio gives us an integer result. If it does, we set DivAddVal = 0, + // MulVal = 1. Otherwise, we search the valid ratio value range to find + // the closest match. This could be more elegant, using search methods + // and/or lookup tables, but the brute force method is not that much + // slower, and is more maintainable. + // + uint32_t PCLK = SystemCoreClock; // divider /1 set below uint16_t DL = PCLK / (16U * baud); uint8_t DivAddVal = 0U; uint8_t MulVal = 1U; - /* set PCLK divider to 1 */ - LPC_SC->PCLKSEL0 &= ~(0x3U << 6); /* clear divider bits */ - LPC_SC->PCLKSEL0 |= (0x1U << 6); /* set divider to 1 */ + // set PCLK divider to 1 + LPC_SC->PCLKSEL0 &= ~(0x3U << 6); // clear divider bits + LPC_SC->PCLKSEL0 |= (0x1U << 6); // set divider to 1 - if ((PCLK % (16U * baud)) != 0U) { /* non zero remainder? */ + if ((PCLK % (16U * baud)) != 0U) { // non zero remainder? uint32_t err_best = baud; bool found = false; uint32_t b; @@ -413,37 +532,37 @@ static void UART0_setBaudrate(uint32_t baud) { uint16_t dlv; uint8_t dav; for (dav = 0U; dav < mv; ++dav) { - /* - * baud = PCLK / (16 * dlv * (1 + (DivAdd / Mul)) - * solving for dlv, we get - * dlv = mul * PCLK / (16 * baud * (divadd + mul)) - * mul has 4 bits, PCLK has 27 so we have 1 bit headroom, - * which can be used for rounding for many values of mul - * and PCLK we have 2 or more bits of headroom which can - * be used to improve precision - * note: X / 32 doesn't round correctly. - * Instead, we use ((X / 16) + 1) / 2 for correct rounding - */ - if ((mv*PCLK*2U) & 0x80000000U) { /* 1 bit headroom */ + // + // baud = PCLK / (16 * dlv * (1 + (DivAdd / Mul)) + // solving for dlv, we get + // dlv = mul * PCLK / (16 * baud * (divadd + mul)) + // mul has 4 bits, PCLK has 27 so we have 1 bit headroom, + // which can be used for rounding for many values of mul + // and PCLK we have 2 or more bits of headroom which can + // be used to improve precision + // note: X / 32 doesn't round correctly. + // Instead, we use ((X / 16) + 1) / 2 for correct rounding + // + if ((mv*PCLK*2U) & 0x80000000U) { // 1 bit headroom dlv = ((((2U*mv*PCLK) / (baud*(dav + mv)))/16U) + 1U)/2U; } - else { /* 2 bits headroom, use more precision */ + else { // 2 bits headroom, use more precision dlv = ((((4U*mv*PCLK) / (baud*(dav+mv)))/32U) + 1U)/2U; } - /* datasheet says if DLL==DLM==0, then 1 is used instead */ + // datasheet says if DLL==DLM==0, then 1 is used instead if (dlv == 0U) { dlv = 1U; } - /* datasheet says if dav > 0 then DL must be >= 2 */ + // datasheet says if dav > 0 then DL must be >= 2 if ((dav > 0U) && (dlv < 2U)) { dlv = 2U; } - /* integer rearrangement of baud equation (with rounding) */ + // integer rearrangement of baud equation (with rounding) b = ((PCLK*mv / (dlv*(dav + mv)*8U)) + 1U)/2U; b = (b >= baud) ? (b - baud) : (baud - b); - /* check to see how we did */ + // check to see how we did if (b < err_best) { err_best = b; DL = dlv; @@ -452,7 +571,7 @@ static void UART0_setBaudrate(uint32_t baud) { if (b == baud) { found = true; - break; /* break out of the inner for-loop */ + break; // break out of the inner for-loop } } } @@ -472,31 +591,31 @@ static void UART0_setBaudrate(uint32_t baud) { LPC_UART0->LCR &= ~(1U << 7); } -#endif /* Q_SPY */ -/*--------------------------------------------------------------------------*/ +#endif // Q_SPY +//---------------------------------------------------------------------------- -/***************************************************************************** -* NOTE1: -* The QF_AWARE_ISR_CMSIS_PRI constant from the QF port specifies the highest -* ISR priority that is disabled by the QF framework. The value is suitable -* for the NVIC_SetPriority() CMSIS function. -* -* Only ISRs prioritized at or below the QF_AWARE_ISR_CMSIS_PRI level (i.e., -* with the numerical values of priorities equal or higher than -* QF_AWARE_ISR_CMSIS_PRI) are allowed to call the QK_ISR_ENTRY/QK_ISR_ENTRY -* macros or any other QF/QK services. These ISRs are "QF-aware". -* -* Conversely, any ISRs prioritized above the QF_AWARE_ISR_CMSIS_PRI priority -* level (i.e., with the numerical values of priorities less than -* QF_AWARE_ISR_CMSIS_PRI) are never disabled and are not aware of the kernel. -* Such "QF-unaware" ISRs cannot call any QF/QK services. In particular they -* can NOT call the macros QK_ISR_ENTRY/QK_ISR_ENTRY. The only mechanism -* by which a "QF-unaware" ISR can communicate with the QF framework is by -* triggering a "QF-aware" ISR, which can post/publish events. -* -* NOTE2: -* The User LED is used to visualize the idle loop activity. The brightness -* of the LED is proportional to the frequency of invcations of the idle loop. -* Please note that the LED is toggled with interrupts locked, so no interrupt -* execution time contributes to the brightness of the User LED. -*/ +//============================================================================ +// NOTE1: +// The QF_AWARE_ISR_CMSIS_PRI constant from the QF port specifies the highest +// ISR priority that is disabled by the QF framework. The value is suitable +// for the NVIC_SetPriority() CMSIS function. +// +// Only ISRs prioritized at or below the QF_AWARE_ISR_CMSIS_PRI level (i.e., +// with the numerical values of priorities equal or higher than +// QF_AWARE_ISR_CMSIS_PRI) are allowed to call the QK_ISR_ENTRY/QK_ISR_ENTRY +// macros or any other QF/QK services. These ISRs are "QF-aware". +// +// Conversely, any ISRs prioritized above the QF_AWARE_ISR_CMSIS_PRI priority +// level (i.e., with the numerical values of priorities less than +// QF_AWARE_ISR_CMSIS_PRI) are never disabled and are not aware of the kernel. +// Such "QF-unaware" ISRs cannot call any QF/QK services. In particular they +// can NOT call the macros QK_ISR_ENTRY/QK_ISR_ENTRY. The only mechanism +// by which a "QF-unaware" ISR can communicate with the QF framework is by +// triggering a "QF-aware" ISR, which can post/publish events. +// +// NOTE2: +// The User LED is used to visualize the idle loop activity. The brightness +// of the LED is proportional to the frequency of invcations of the idle loop. +// Please note that the LED is toggled with interrupts locked, so no interrupt +// execution time contributes to the brightness of the User LED. +// diff --git a/examples/arm-cm/dpp_mbed-lpc1768/qk/gnu/Makefile b/examples/arm-cm/dpp_mbed-lpc1768/qk/gnu/Makefile index 4d9107bf..4fc31b5b 100644 --- a/examples/arm-cm/dpp_mbed-lpc1768/qk/gnu/Makefile +++ b/examples/arm-cm/dpp_mbed-lpc1768/qk/gnu/Makefile @@ -261,7 +261,7 @@ $(TARGET_BIN): $(TARGET_ELF) $(BIN) -O binary $< $@ $(TARGET_ELF) : $(ASM_OBJS_EXT) $(C_OBJS_EXT) $(CPP_OBJS_EXT) - $(CC) $(CFLAGS) $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o + $(CC) $(CFLAGS) $(QPC)/src/qs/qstamp.c -o $(BIN_DIR)/qstamp.o $(LINK) $(LINKFLAGS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) $(BIN_DIR)/%.d : %.c diff --git a/examples/arm-cm/dpp_mbed-lpc1768/qk/iar/dpp-qk.ewd b/examples/arm-cm/dpp_mbed-lpc1768/qk/iar/dpp-qk.ewd index f782d88e..7e97aee0 100644 --- a/examples/arm-cm/dpp_mbed-lpc1768/qk/iar/dpp-qk.ewd +++ b/examples/arm-cm/dpp_mbed-lpc1768/qk/iar/dpp-qk.ewd @@ -88,7 +88,7 @@ @@ -399,6 +406,13 @@ + + 1 + 1 + 0 + 2 + 10000000 + @@ -583,6 +597,13 @@ + + 1 + 1 + 0 + 2 + 10000000 + @@ -635,18 +656,6 @@ 0 0 0 - ..\..\main.c - main.c - 0 - 0 - - - 1 - 5 - 1 - 0 - 0 - 0 ..\..\philo.c philo.c 0 @@ -654,7 +663,7 @@ 1 - 6 + 5 1 0 0 @@ -666,13 +675,13 @@ 1 - 7 + 6 1 0 0 0 - ..\..\..\..\..\include\qstamp.c - qstamp.c + ..\..\main.c + main.c 0 0 @@ -686,7 +695,7 @@ 0 2 - 8 + 7 1 0 0 @@ -698,12 +707,12 @@ 2 - 9 + 8 2 0 0 0 - ..\..\..\..\.arm\startup-lpc1768\armclang\startup_LPC17xx.s + ..\..\..\..\..\3rd_party\mbed-lpc1768\arm\startup_LPC17xx.s startup_LPC17xx.s 0 0 @@ -718,7 +727,7 @@ 0 3 - 10 + 9 1 0 0 @@ -730,7 +739,7 @@ 3 - 11 + 10 1 0 0 @@ -742,7 +751,7 @@ 3 - 12 + 11 1 0 0 @@ -754,7 +763,7 @@ 3 - 13 + 12 1 0 0 @@ -766,7 +775,7 @@ 3 - 14 + 13 1 0 0 @@ -778,7 +787,7 @@ 3 - 15 + 14 1 0 0 @@ -790,7 +799,7 @@ 3 - 16 + 15 1 0 0 @@ -802,19 +811,7 @@ 3 - 17 - 5 - 0 - 0 - 0 - ..\..\..\..\..\src\qf_pkg.h - qf_pkg.h - 0 - 0 - - - 3 - 18 + 16 1 0 0 @@ -826,7 +823,7 @@ 3 - 19 + 17 1 0 0 @@ -838,7 +835,7 @@ 3 - 20 + 18 1 0 0 @@ -850,7 +847,7 @@ 3 - 21 + 19 1 0 0 @@ -862,7 +859,7 @@ 3 - 22 + 20 1 0 0 @@ -874,7 +871,7 @@ 3 - 23 + 21 1 0 0 @@ -894,43 +891,7 @@ 0 4 - 24 - 5 - 0 - 0 - 0 - ..\..\..\..\..\ports\arm-cm\qv\armclang\qep_port.h - qep_port.h - 0 - 0 - - - 4 - 25 - 5 - 0 - 0 - 0 - ..\..\..\..\..\ports\arm-cm\qv\armclang\qf_port.h - qf_port.h - 0 - 0 - - - 4 - 26 - 5 - 0 - 0 - 0 - ..\..\..\..\..\ports\arm-cm\qv\armclang\qv_port.h - qv_port.h - 0 - 0 - - - 4 - 27 + 22 5 0 0 @@ -942,7 +903,7 @@ 4 - 28 + 23 1 0 0 @@ -962,7 +923,7 @@ 0 5 - 29 + 24 1 0 0 @@ -974,37 +935,25 @@ 5 - 30 + 25 1 0 0 0 - ..\..\..\..\..\src\qs\qs_fp.c - qs_fp.c + ..\..\..\..\..\src\qs\qs_rx.c + qs_rx.c 0 0 5 - 31 - 5 + 26 + 1 0 0 0 - ..\..\..\..\..\src\qs\qs_pkg.h - qs_pkg.h - 0 - 0 - - - 5 - 32 - 5 - 0 - 0 - 0 - ..\..\..\..\..\src\qs_pkg.h - qs_pkg.h + ..\..\..\..\..\src\qs\qstamp.c + qstamp.c 0 0 diff --git a/examples/arm-cm/dpp_mbed-lpc1768/qv/armclang/dpp-qv.uvprojx b/examples/arm-cm/dpp_mbed-lpc1768/qv/armclang/dpp-qv.uvprojx index e7b3e243..69168dfc 100644 --- a/examples/arm-cm/dpp_mbed-lpc1768/qv/armclang/dpp-qv.uvprojx +++ b/examples/arm-cm/dpp_mbed-lpc1768/qv/armclang/dpp-qv.uvprojx @@ -10,13 +10,13 @@ dpp-dbg 0x4 ARM-ADS - 6130001::V6.13.1::.\ARMCLANG + 6160000::V6.16::ARMCLANG 1 LPC1768 NXP - Keil.LPC1700_DFP.2.2.0 + Keil.LPC1700_DFP.2.7.1 http://www.keil.com/pack/ IROM(0x00000000,0x80000) IRAM(0x10000000,0x8000) IRAM2(0x2007C000,0x8000) CPUTYPE("Cortex-M3") CLOCK(12000000) ELITTLE @@ -185,6 +185,7 @@ 0 0 0 + 0 1 0 8 @@ -336,7 +337,7 @@ 0 - rvmdk __FPU_PRESENT + ..\..;..\..\..\..\..\include;..\..\..\..\..\ports\arm-cm\qv\armclang;..\..\..\..\..\3rd_party\CMSIS\Include;..\..\..\..\..\3rd_party\mbed-lpc1768 @@ -351,7 +352,7 @@ 0 1 0 - 0 + 4 Stack_Size=2048 Heap_Size=16 @@ -360,7 +361,7 @@ - 1 + 0 0 0 0 @@ -369,7 +370,7 @@ 0x00000000 0x20000000 - + dpp-qv.sct --entry Reset_Handler @@ -397,11 +398,6 @@ 5 ..\..\dpp.h - - main.c - 1 - ..\..\main.c - philo.c 1 @@ -413,9 +409,9 @@ ..\..\table.c - qstamp.c + main.c 1 - ..\..\..\..\..\include\qstamp.c + ..\..\main.c @@ -472,11 +468,6 @@ 1 ..\..\..\..\..\src\qf\qf_mem.c - - qf_pkg.h - 5 - ..\..\..\..\..\src\qf_pkg.h - qf_ps.c 1 @@ -512,21 +503,6 @@ QP_port - - qep_port.h - 5 - ..\..\..\..\..\ports\arm-cm\qv\armclang\qep_port.h - - - qf_port.h - 5 - ..\..\..\..\..\ports\arm-cm\qv\armclang\qf_port.h - - - qv_port.h - 5 - ..\..\..\..\..\ports\arm-cm\qv\armclang\qv_port.h - qs_port.h 5 @@ -600,7 +576,7 @@ 2 2 2 - 2 + 0 @@ -617,19 +593,14 @@ ..\..\..\..\..\src\qs\qs.c - qs_fp.c + qs_rx.c 1 - ..\..\..\..\..\src\qs\qs_fp.c + ..\..\..\..\..\src\qs\qs_rx.c - qs_pkg.h - 5 - ..\..\..\..\..\src\qs\qs_pkg.h - - - qs_pkg.h - 5 - ..\..\..\..\..\src\qs_pkg.h + qstamp.c + 1 + ..\..\..\..\..\src\qs\qstamp.c @@ -639,13 +610,13 @@ dpp-rel 0x4 ARM-ADS - 5060020::V5.06 (build 20)::ARMCC + 6160000::V6.16::ARMCLANG 1 LPC1768 NXP - Keil.LPC1700_DFP.2.2.0 + Keil.LPC1700_DFP.2.7.1 http://www.keil.com/pack/ IROM(0x00000000,0x80000) IRAM(0x10000000,0x8000) IRAM2(0x2007C000,0x8000) CPUTYPE("Cortex-M3") CLOCK(12000000) ELITTLE @@ -814,6 +785,7 @@ 0 0 0 + 0 1 0 8 @@ -965,7 +937,7 @@ 0 - NDEBUG __FPU_PRESENT + NDEBUG ..\..;..\..\..\..\..\include;..\..\..\..\..\ports\arm-cm\qv\armclang;..\..\..\..\..\3rd_party\CMSIS\Include;..\..\..\..\..\3rd_party\mbed-lpc1768 @@ -980,7 +952,7 @@ 0 1 0 - 0 + 4 Stack_Size=2048 Heap_Size=16 @@ -989,7 +961,7 @@ - 1 + 0 0 0 0 @@ -1026,11 +998,6 @@ 5 ..\..\dpp.h - - main.c - 1 - ..\..\main.c - philo.c 1 @@ -1042,9 +1009,9 @@ ..\..\table.c - qstamp.c + main.c 1 - ..\..\..\..\..\include\qstamp.c + ..\..\main.c @@ -1101,11 +1068,6 @@ 1 ..\..\..\..\..\src\qf\qf_mem.c - - qf_pkg.h - 5 - ..\..\..\..\..\src\qf_pkg.h - qf_ps.c 1 @@ -1141,21 +1103,6 @@ QP_port - - qep_port.h - 5 - ..\..\..\..\..\ports\arm-cm\qv\armclang\qep_port.h - - - qf_port.h - 5 - ..\..\..\..\..\ports\arm-cm\qv\armclang\qf_port.h - - - qv_port.h - 5 - ..\..\..\..\..\ports\arm-cm\qv\armclang\qv_port.h - qs_port.h 5 @@ -1229,7 +1176,7 @@ 2 2 2 - 2 + 0 @@ -1246,19 +1193,14 @@ ..\..\..\..\..\src\qs\qs.c - qs_fp.c + qs_rx.c 1 - ..\..\..\..\..\src\qs\qs_fp.c + ..\..\..\..\..\src\qs\qs_rx.c - qs_pkg.h - 5 - ..\..\..\..\..\src\qs\qs_pkg.h - - - qs_pkg.h - 5 - ..\..\..\..\..\src\qs_pkg.h + qstamp.c + 1 + ..\..\..\..\..\src\qs\qstamp.c @@ -1268,13 +1210,13 @@ dpp-spy 0x4 ARM-ADS - 5060020::V5.06 (build 20)::ARMCC + 6160000::V6.16::ARMCLANG 1 LPC1768 NXP - Keil.LPC1700_DFP.2.2.0 + Keil.LPC1700_DFP.2.7.1 http://www.keil.com/pack/ IROM(0x00000000,0x80000) IRAM(0x10000000,0x8000) IRAM2(0x2007C000,0x8000) CPUTYPE("Cortex-M3") CLOCK(12000000) ELITTLE @@ -1443,6 +1385,7 @@ 0 0 0 + 0 1 0 8 @@ -1594,7 +1537,7 @@ 0 - Q_SPY __FPU_PRESENT + Q_SPY,QF_ON_CONTEXT_SW ..\..;..\..\..\..\..\include;..\..\..\..\..\ports\arm-cm\qv\armclang;..\..\..\..\..\3rd_party\CMSIS\Include;..\..\..\..\..\3rd_party\mbed-lpc1768 @@ -1609,7 +1552,7 @@ 0 1 0 - 0 + 4 Stack_Size=2048 Heap_Size=16 @@ -1618,7 +1561,7 @@ - 1 + 0 0 0 0 @@ -1655,11 +1598,6 @@ 5 ..\..\dpp.h - - main.c - 1 - ..\..\main.c - philo.c 1 @@ -1671,9 +1609,9 @@ ..\..\table.c - qstamp.c + main.c 1 - ..\..\..\..\..\include\qstamp.c + ..\..\main.c @@ -1730,11 +1668,6 @@ 1 ..\..\..\..\..\src\qf\qf_mem.c - - qf_pkg.h - 5 - ..\..\..\..\..\src\qf_pkg.h - qf_ps.c 1 @@ -1770,21 +1703,6 @@ QP_port - - qep_port.h - 5 - ..\..\..\..\..\ports\arm-cm\qv\armclang\qep_port.h - - - qf_port.h - 5 - ..\..\..\..\..\ports\arm-cm\qv\armclang\qf_port.h - - - qv_port.h - 5 - ..\..\..\..\..\ports\arm-cm\qv\armclang\qv_port.h - qs_port.h 5 @@ -1806,19 +1724,14 @@ ..\..\..\..\..\src\qs\qs.c - qs_fp.c + qs_rx.c 1 - ..\..\..\..\..\src\qs\qs_fp.c + ..\..\..\..\..\src\qs\qs_rx.c - qs_pkg.h - 5 - ..\..\..\..\..\src\qs\qs_pkg.h - - - qs_pkg.h - 5 - ..\..\..\..\..\src\qs_pkg.h + qstamp.c + 1 + ..\..\..\..\..\src\qs\qstamp.c diff --git a/examples/arm-cm/dpp_mbed-lpc1768/qv/bsp.c b/examples/arm-cm/dpp_mbed-lpc1768/qv/bsp.c index a5b06a93..8e3962a8 100644 --- a/examples/arm-cm/dpp_mbed-lpc1768/qv/bsp.c +++ b/examples/arm-cm/dpp_mbed-lpc1768/qv/bsp.c @@ -1,66 +1,61 @@ -/***************************************************************************** -* Product: DPP example, NXP mbed-LPC1768 board, coopearative QV kernel -* Last updated for version 6.9.3 -* Last updated on 2021-03-03 -* -* Q u a n t u m L e a P s -* ------------------------ -* Modern Embedded Software -* -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* -* -*****************************************************************************/ -#include "qpc.h" -#include "dpp.h" -#include "bsp.h" +//============================================================================ +// Product: DPP example, NXP mbed-LPC1768 board, QV kernel +// Last updated for version 7.3.0 +// Last updated on 2023-08-15 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. +// +// This program is open source software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Alternatively, this program may be distributed and modified under the +// terms of Quantum Leaps commercial licenses, which expressly supersede +// the GNU General Public License and are specifically designed for +// licensees interested in retaining the proprietary status of their code. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Contact information: +// +// +//============================================================================ +#include "qpc.h" // QP/C real-time embedded framework +#include "dpp.h" // DPP Application interface +#include "bsp.h" // Board Support Package -#include "LPC17xx.h" /* CMSIS-compliant header file for the MCU used */ -/* add other drivers if necessary... */ +#include "LPC17xx.h" // CMSIS-compliant header file for the MCU used +// add other drivers if necessary... -Q_DEFINE_THIS_FILE +Q_DEFINE_THIS_FILE // define the name of this file for assertions -/* ISRs defined in this BSP ------------------------------------------------*/ -void SysTick_Handler(void); -void EINT0_IRQHandler(void); +// Local-scope objects ----------------------------------------------------- +#define LED_1 (1U << 18U) // P1.18 +#define LED_2 (1U << 20U) // P1.20 +#define LED_3 (1U << 21U) // P1.21 +#define LED_4 (1U << 23U) // P1.23 -/* Local-scope objects -----------------------------------------------------*/ -/* LEDs available on the board */ -#define LED_1 (1U << 18) /* P1.18 */ -#define LED_2 (1U << 20) /* P1.20 */ -#define LED_3 (1U << 21) /* P1.21 */ -#define LED_4 (1U << 23) /* P1.23 */ +// Push-Button wired externally to DIP8 (P0.6) +#define BTN_EXT (1U << 6U) // P0.6 -/* Push-Button wired externally to DIP8 (P0.6) */ -#define BTN_EXT (1U << 6) /* P0.6 */ - -static uint32_t l_rnd; /* random seed */ +static uint32_t l_rndSeed; #ifdef Q_SPY QSTimeCtr QS_tickTime_; QSTimeCtr QS_tickPeriod_; - /* QSpy source IDs */ + // QSpy source IDs static QSpyId const l_SysTick_Handler = { 0U }; static QSpyId const l_EINT0_IRQHandler = { 0U }; @@ -68,252 +63,369 @@ static uint32_t l_rnd; /* random seed */ #define UART_FR_TXFE 0x80U #define UART_TXFIFO_DEPTH 16U - enum AppRecords { /* application-specific trace records */ - PHILO_STAT = QS_USER + enum AppRecords { // application-specific trace records + PHILO_STAT = QS_USER, + PAUSED_STAT, + CONTEXT_SW, }; #endif -/* ISRs used in the application ==========================================*/ +//============================================================================ +// Error handler and ISRs... + +Q_NORETURN Q_onError(char const * const module, int_t const id) { + // NOTE: this implementation of the error handler is intended only + // for debugging and MUST be changed for deployment of the application + // (assuming that you ship your production code with assertions enabled). + Q_UNUSED_PAR(module); + Q_UNUSED_PAR(id); + QS_ASSERTION(module, id, 10000U); + +#ifndef NDEBUG + // light up all LEDs + LPC_GPIO1->FIOSET = LED_1; // turn LED on + LPC_GPIO1->FIOSET = LED_2; // turn LED on + LPC_GPIO1->FIOSET = LED_3; // turn LED on + LPC_GPIO1->FIOSET = LED_4; // turn LED on + // for debugging, hang on in an endless loop... + for (;;) { + } +#else + NVIC_SystemReset(); + for (;;) { // explicitly "no-return" + } +#endif +} +//............................................................................ +void assert_failed(char const * const module, int_t const id); // prototype +void assert_failed(char const * const module, int_t const id) { + Q_onError(module, id); +} + +// ISRs used in the application ============================================== + +void SysTick_Handler(void); // prototype void SysTick_Handler(void) { - /* state of the button debouncing, see below */ - static struct ButtonsDebouncing { + + QTIMEEVT_TICK_X(0U, &l_SysTick_Handler); // time events at rate 0 + + // Perform the debouncing of buttons. The algorithm for debouncing + // adapted from the book "Embedded Systems Dictionary" by Jack Ganssle + // and Michael Barr, page 71. + // + // state of the button debouncing + static struct { uint32_t depressed; uint32_t previous; } buttons = { 0U, 0U }; - uint32_t current; - uint32_t tmp; -#ifdef Q_SPY - { - tmp = SysTick->CTRL; /* clear CTRL_COUNTFLAG */ - QS_tickTime_ += QS_tickPeriod_; /* account for the clock rollover */ - } -#endif + uint32_t current = ~LPC_GPIO0->FIOPIN; // read P0 with state of Buttons + uint32_t tmp = buttons.depressed; // save the depressed buttons + buttons.depressed |= (buttons.previous & current); // set depressed + buttons.depressed &= (buttons.previous | current); // clear released + buttons.previous = current; // update the history + tmp ^= buttons.depressed; // changed debounced depressed + current = buttons.depressed; - QTIMEEVT_TICK_X(0U, &l_SysTick_Handler); /* process time events for rate 0 */ - - /* get state of the buttons */ - /* Perform the debouncing of buttons. The algorithm for debouncing - * adapted from the book "Embedded Systems Dictionary" by Jack Ganssle - * and Michael Barr, page 71. - */ - current = ~LPC_GPIO0->FIOPIN; /* read P0 with the state of the Buttons */ - tmp = buttons.depressed; /* save the debounced depressed buttons */ - buttons.depressed |= (buttons.previous & current); /* set depressed */ - buttons.depressed &= (buttons.previous | current); /* clear released */ - buttons.previous = current; /* update the history */ - tmp ^= buttons.depressed; /* changed debounced depressed */ - if ((tmp & BTN_EXT) != 0U) { /* debounced BTN_EXT state changed? */ - if ((buttons.depressed & BTN_EXT) != 0U) { /* is BTN_EXT depressed? */ - static QEvt const pauseEvt = { PAUSE_SIG, 0U, 0U}; + if ((tmp & BTN_EXT) != 0U) { // debounced BTN_EXT state changed? + if ((current & BTN_EXT) != 0U) { // is BTN_EXT depressed? + static QEvt const pauseEvt = QEVT_INITIALIZER(PAUSE_SIG); QACTIVE_PUBLISH(&pauseEvt, &l_SysTick_Handler); } - else { /* the button is released */ - static QEvt const serveEvt = { SERVE_SIG, 0U, 0U}; + else { // the button is released + static QEvt const serveEvt = QEVT_INITIALIZER(SERVE_SIG); QACTIVE_PUBLISH(&serveEvt, &l_SysTick_Handler); } } + +#ifdef Q_SPY + tmp = SysTick->CTRL; // clear CTRL_COUNTFLAG + QS_tickTime_ += QS_tickPeriod_; // account for the clock rollover +#endif // Q_SPY + QV_ARM_ERRATUM_838869(); } -/*..........................................................................*/ +//............................................................................ +// interrupt handler for testing preemptions in QK +void EINT0_IRQHandler(void); // prototype void EINT0_IRQHandler(void) { - QACTIVE_POST(AO_Table, Q_NEW(QEvt, MAX_PUB_SIG), /* for testing... */ + // for testing... + QACTIVE_POST(AO_Table, Q_NEW(QEvt, MAX_PUB_SIG), // for testing... &l_EINT0_IRQHandler); + QV_ARM_ERRATUM_838869(); } -/* BSP functions ===========================================================*/ +//............................................................................ +#ifdef QF_ON_CONTEXT_SW +// NOTE: the context-switch callback is called with interrupts DISABLED +void QF_onContextSw(QActive *prev, QActive *next) { + Q_UNUSED_PAR(prev); + Q_UNUSED_PAR(next); + + QS_BEGIN_INCRIT(CONTEXT_SW, 0U) // in critical section! + QS_OBJ(prev); + QS_OBJ(next); + QS_END_INCRIT() +} +#endif // QF_ON_CONTEXT_SW + +//============================================================================ +// BSP functions... + void BSP_init(void) { - /* NOTE: SystemInit() has been already called from the startup code - * but SystemCoreClock needs to be updated - */ + // Configure the MPU to prevent NULL-pointer dereferencing ... + MPU->RBAR = 0x0U // base address (NULL) + | MPU_RBAR_VALID_Msk // valid region + | (MPU_RBAR_REGION_Msk & 7U); // region #7 + MPU->RASR = (7U << MPU_RASR_SIZE_Pos) // 2^(7+1) region + | (0x0U << MPU_RASR_AP_Pos) // no-access region + | MPU_RASR_ENABLE_Msk; // region enable + MPU->CTRL = MPU_CTRL_PRIVDEFENA_Msk // enable background region + | MPU_CTRL_ENABLE_Msk; // enable the MPU + __ISB(); + __DSB(); + + // enable the MemManage_Handler for MPU exception + SCB->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk; + + // NOTE: SystemInit() has been already called from the startup code + // but SystemCoreClock needs to be updated SystemCoreClockUpdate(); - /* turn the GPIO clock on */ + // turn the GPIO clock on LPC_SC->PCONP |= (1U << 15); - /* setup the GPIO pin functions for the LEDs... */ - LPC_PINCON->PINSEL3 &= ~(3U << 4); /* LED_1: function P1.18 to GPIO */ - LPC_PINCON->PINSEL3 &= ~(3U << 8); /* LED_2: function P1.20 to GPIO */ - LPC_PINCON->PINSEL3 &= ~(3U << 10); /* LED_3: function P1.21 to GPIO */ - LPC_PINCON->PINSEL3 &= ~(3U << 14); /* LED_4: function P1.23 to GPIO */ + // setup the GPIO pin functions for the LEDs... + LPC_PINCON->PINSEL3 &= ~(3U << 4); // LED_1: function P1.18 to GPIO + LPC_PINCON->PINSEL3 &= ~(3U << 8); // LED_2: function P1.20 to GPIO + LPC_PINCON->PINSEL3 &= ~(3U << 10); // LED_3: function P1.21 to GPIO + LPC_PINCON->PINSEL3 &= ~(3U << 14); // LED_4: function P1.23 to GPIO - /* Set GPIO-P1 LED pins to output */ + // Set GPIO-P1 LED pins to output LPC_GPIO1->FIODIR |= (LED_1 | LED_2 | LED_3 | LED_4); - /* setup the GPIO pin function for the Button... */ - LPC_PINCON->PINSEL0 &= ~(3U << 12); /* function P0.6 to GPIO, pull-up */ + // setup the GPIO pin function for the Button... + LPC_PINCON->PINSEL0 &= ~(3U << 12); // function P0.6 to GPIO, pull-up - /* Set GPIO-P0 Button pin as input */ + // Set GPIO-P0 Button pin as input LPC_GPIO0->FIODIR &= ~BTN_EXT; - BSP_randomSeed(1234U); + BSP_randomSeed(1234U); // seed the random number generator - if (QS_INIT((void *)0) == 0U) { /* initialize the QS software tracing */ + // initialize the QS software tracing... + if (!QS_INIT((void *)0)) { Q_ERROR(); } + + // dictionaries... QS_OBJ_DICTIONARY(&l_SysTick_Handler); QS_OBJ_DICTIONARY(&l_EINT0_IRQHandler); QS_USR_DICTIONARY(PHILO_STAT); + QS_USR_DICTIONARY(PAUSED_STAT); + QS_USR_DICTIONARY(CONTEXT_SW); - /* setup the QS filters... */ - QS_GLB_FILTER(QS_SM_RECORDS); /* state machine records */ - QS_GLB_FILTER(QS_AO_RECORDS); /* active object records */ - QS_GLB_FILTER(QS_UA_RECORDS); /* all user records */ + QS_ONLY(produce_sig_dict()); + + // setup the QS filters... + QS_GLB_FILTER(QS_ALL_RECORDS); // all records + QS_GLB_FILTER(-QS_QF_TICK); // exclude the clock tick } -/*..........................................................................*/ +//............................................................................ +void BSP_start(void) { + // initialize event pools + static QF_MPOOL_EL(TableEvt) smlPoolSto[2*N_PHILO]; + QF_poolInit(smlPoolSto, sizeof(smlPoolSto), sizeof(smlPoolSto[0])); + + // initialize publish-subscribe + static QSubscrList subscrSto[MAX_PUB_SIG]; + QActive_psInit(subscrSto, Q_DIM(subscrSto)); + + // instantiate and start AOs/threads... + + static QEvt const *philoQueueSto[N_PHILO][10]; + for (uint8_t n = 0U; n < N_PHILO; ++n) { + Philo_ctor(n); + QACTIVE_START(AO_Philo[n], + n + 3U, // QF-prio. + philoQueueSto[n], // event queue storage + Q_DIM(philoQueueSto[n]), // queue length [events] + (void *)0, 0U, // no stack storage + (void *)0); // no initialization param + } + + static QEvt const *tableQueueSto[N_PHILO]; + Table_ctor(); + QACTIVE_START(AO_Table, + N_PHILO + 7U, // QP prio. of the AO + tableQueueSto, // event queue storage + Q_DIM(tableQueueSto), // queue length [events] + (void *)0, 0U, // no stack storage + (void *)0); // no initialization param +} +//............................................................................ void BSP_displayPhilStat(uint8_t n, char const *stat) { + Q_UNUSED_PAR(n); + if (stat[0] == 'h') { - LPC_GPIO1->FIOSET = LED_1; /* turn LED on */ + LPC_GPIO1->FIOSET = LED_1; // turn LED on } else { - LPC_GPIO1->FIOCLR = LED_1; /* turn LED off */ + LPC_GPIO1->FIOCLR = LED_1; // turn LED off } if (stat[0] == 'e') { - LPC_GPIO1->FIOSET = LED_2; /* turn LED on */ + LPC_GPIO1->FIOSET = LED_2; // turn LED on } else { - LPC_GPIO1->FIOCLR = LED_2; /* turn LED off */ + LPC_GPIO1->FIOCLR = LED_2; // turn LED off } - QS_BEGIN_ID(PHILO_STAT, AO_Philo[n]->prio) /* app-specific record */ - QS_U8(1, n); /* Philosopher number */ - QS_STR(stat); /* Philosopher status */ + // app-specific trace record... + QS_BEGIN_ID(PHILO_STAT, AO_Table->prio) + QS_U8(1, n); // Philosopher number + QS_STR(stat); // Philosopher status QS_END() } -/*..........................................................................*/ -void BSP_displayPaused(uint8_t paused) { +//............................................................................ +void BSP_displayPaused(uint8_t const paused) { if (paused != 0U) { - LPC_GPIO1->FIOSET = LED_3; /* turn LED on */ + LPC_GPIO1->FIOSET = LED_3; // turn LED on } else { - LPC_GPIO1->FIOCLR = LED_3; /* turn LED off */ + LPC_GPIO1->FIOCLR = LED_3; // turn LED off } + + // application-specific trace record + QS_BEGIN_ID(PAUSED_STAT, AO_Table->prio) + QS_U8(1, paused); // Paused status + QS_END() } -/*..........................................................................*/ -uint32_t BSP_random(void) { /* a very cheap pseudo-random-number generator */ - /* "Super-Duper" Linear Congruential Generator (LCG) - * LCG(2^32, 3*7*11*13*23, 0, seed) - */ - l_rnd = l_rnd * (3U*7U*11U*13U*23U); - return l_rnd >> 8; -} -/*..........................................................................*/ +//............................................................................ void BSP_randomSeed(uint32_t seed) { - l_rnd = seed; + l_rndSeed = seed; } -/*..........................................................................*/ +//............................................................................ +uint32_t BSP_random(void) { // a very cheap pseudo-random-number generator + // "Super-Duper" Linear Congruential Generator (LCG) + // LCG(2^32, 3*7*11*13*23, 0, seed) + // + uint32_t rnd = l_rndSeed * (3U*7U*11U*13U*23U); + l_rndSeed = rnd; // set for the next time + + return (rnd >> 8U); +} +//............................................................................ void BSP_terminate(int16_t result) { - (void)result; + Q_UNUSED_PAR(result); +} +//............................................................................ +void BSP_ledOn(void) { + LPC_GPIO1->FIOSET = LED_3; // turn LED on +} +//............................................................................ +void BSP_ledOff(void) { + LPC_GPIO1->FIOCLR = LED_3; // turn LED off } - -/* QF callbacks ============================================================*/ +//============================================================================ +// QF callbacks... void QF_onStartup(void) { - /* set up the SysTick timer to fire at BSP_TICKS_PER_SEC rate */ + // set up the SysTick timer to fire at BSP_TICKS_PER_SEC rate SysTick_Config(SystemCoreClock / BSP_TICKS_PER_SEC); - /* set priorities of ALL ISRs used in the system, see NOTE00 - * - * !!!!!!!!!!!!!!!!!!!!!!!!!!!! CAUTION !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - * Assign a priority to EVERY ISR explicitly by calling NVIC_SetPriority(). - * DO NOT LEAVE THE ISR PRIORITIES AT THE DEFAULT VALUE! - */ - NVIC_SetPriority(EINT0_IRQn, QF_AWARE_ISR_CMSIS_PRI); - NVIC_SetPriority(SysTick_IRQn, QF_AWARE_ISR_CMSIS_PRI + 1U); - /* ... */ + // assign all priority bits for preemption-prio. and none to sub-prio. + NVIC_SetPriorityGrouping(0U); - /* enable IRQs in the NVIC... */ + // set priorities of ALL ISRs used in the system, see NOTE1 + NVIC_SetPriority(EINT0_IRQn, QF_AWARE_ISR_CMSIS_PRI + 0U); + NVIC_SetPriority(SysTick_IRQn, QF_AWARE_ISR_CMSIS_PRI + 1U); + // ... + + // enable IRQs in the NVIC... NVIC_EnableIRQ(EINT0_IRQn); } -/*..........................................................................*/ +//............................................................................ void QF_onCleanup(void) { } -/*..........................................................................*/ -void QV_onIdle(void) { /* called with interrupts disabled, see NOTE01 */ - /* toggle the LED on and then off, see NOTE02 */ - QF_INT_DISABLE(); - LPC_GPIO1->FIOSET = LED_4; /* turn LED on */ - __NOP(); /* a couple of NOPs to actually see the LED glow */ +//............................................................................ +void QV_onIdle(void) { // CATION: called with interrupts DISABLED, see NOTE0 + // toggle the User LED on and then off, see NOTE2 + LPC_GPIO1->FIOSET = LED_4; // turn LED on + __NOP(); // a couple of NOPs to actually see the LED glow __NOP(); __NOP(); __NOP(); - LPC_GPIO1->FIOCLR = LED_4; /* turn LED off */ + LPC_GPIO1->FIOCLR = LED_4; // turn LED off + +#ifdef Q_SPY + // interrupts still disabled + QS_rxParse(); // parse all the received bytes QF_INT_ENABLE(); -#ifdef Q_SPY - - if ((LPC_UART0->LSR & 0x20U) != 0U) { /* TX Holding Register empty? */ - uint16_t fifo = UART_TXFIFO_DEPTH; /* max bytes we can accept */ - uint8_t const *block; + if ((LPC_UART0->LSR & 0x20U) != 0U) { // TX Holding Register empty? + uint16_t fifo = UART_TXFIFO_DEPTH; // max bytes we can accept QF_INT_DISABLE(); - block = QS_getBlock(&fifo); /* try to get next block to transmit */ + uint8_t const *block = QS_getBlock(&fifo); QF_INT_ENABLE(); - while (fifo-- != 0) { /* any bytes in the block? */ - LPC_UART0->THR = *block++; /* put into the FIFO */ + while (fifo-- != 0U) { // any bytes in the block? + LPC_UART0->THR = *block++; // put into the FIFO } } - #elif defined NDEBUG - /* Put the CPU and peripherals to the low-power mode. - * you might need to customize the clock management for your application, - * see the datasheet for your particular Cortex-M MCU. - */ - QV_CPU_SLEEP(); /* atomically go to sleep and enable interrupts */ + // Put the CPU and peripherals to the low-power mode. + // you might need to customize the clock management for your application, + // see the datasheet for your particular Cortex-M MCU. + // + QV_CPU_SLEEP(); // atomically go to sleep and enable interrupts #else - QF_INT_ENABLE(); /* just enable interrupts */ + QF_INT_ENABLE(); // just enable interrupts #endif } -/*..........................................................................*/ -Q_NORETURN Q_onAssert(char const * const module, int_t const loc) { - /* - * NOTE: add here your application-specific error handling - */ - (void)module; - (void)loc; - QS_ASSERTION(module, loc, 10000U); /* report assertion to QS */ - NVIC_SystemReset(); -} -/* QS callbacks ============================================================*/ +//============================================================================ +// QS callbacks... #ifdef Q_SPY -static void UART0_setBaudrate(uint32_t baud); /* helper function */ +static void UART0_setBaudrate(uint32_t baud); // helper function -/*..........................................................................*/ +//............................................................................ uint8_t QS_onStartup(void const *arg) { - static uint8_t qsBuf[2*1024]; /* buffer for Quantum Spy */ - QS_initBuf(qsBuf, sizeof(qsBuf)); + Q_UNUSED_PAR(arg); + + static uint8_t qsTxBuf[2*1024]; // buffer for QS-TX channel + QS_initBuf(qsTxBuf, sizeof(qsTxBuf)); + + // TBD: add support for QS-RX channel // setup the P0_2 UART0 TX pin - LPC_PINCON->PINSEL0 &= ~(3U << 4); /* clear P0_2 function */ - LPC_PINCON->PINSEL0 |= (1U << 4); /* P0_2 to UART function (TX) */ - LPC_PINCON->PINMODE0 &= ~(3U << 4); /* P0_2 pull-up register */ + LPC_PINCON->PINSEL0 &= ~(3U << 4); // clear P0_2 function + LPC_PINCON->PINSEL0 |= (1U << 4); // P0_2 to UART function (TX) + LPC_PINCON->PINMODE0 &= ~(3U << 4); // P0_2 pull-up register // setup the P0_3 UART0 RX pin - LPC_PINCON->PINSEL0 &= ~(3U << 6); /* clear P0_3 function */ - LPC_PINCON->PINSEL0 |= (1U << 6); /* P0_3 to UART function (RX) */ - LPC_PINCON->PINMODE0 &= ~(3U << 6); /* P0_3 pull-up register */ + LPC_PINCON->PINSEL0 &= ~(3U << 6); // clear P0_3 function + LPC_PINCON->PINSEL0 |= (1U << 6); // P0_3 to UART function (RX) + LPC_PINCON->PINMODE0 &= ~(3U << 6); // P0_3 pull-up register - /* enable power to UART0 */ + // enable power to UART0 LPC_SC->PCONP |= (1U << 3); - /* enable FIFOs and default RX trigger level */ + // enable FIFOs and default RX trigger level LPC_UART0->FCR = - (1U << 0) /* FIFO Enable - 0 = Disables, 1 = Enabled */ - | (0U << 1) /* Rx Fifo Reset */ - | (0U << 2) /* Tx Fifo Reset */ - | (0U << 6); /* Rx irq trig: 0=1char, 1=4chars, 2=8chars, 3=14chars */ + (1U << 0) // FIFO Enable - 0 = Disables, 1 = Enabled + | (0U << 1) // Rx Fifo Reset + | (0U << 2) // Tx Fifo Reset + | (0U << 6); // Rx irq trig: 0=1char, 1=4chars, 2=8chars, 3=14chars - /* disable IRQs */ + // disable IRQs LPC_UART0->IER = - (0U << 0) /* Rx Data available IRQ disable */ - | (0U << 1) /* Tx Fifo empty IRQ disable */ - | (0U << 2); /* Rx Line Status IRQ disable */ + (0U << 0) // Rx Data available IRQ disable + | (0U << 1) // Tx Fifo empty IRQ disable + | (0U << 2); // Rx Line Status IRQ disable // set default baud rate @@ -321,69 +433,85 @@ uint8_t QS_onStartup(void const *arg) { // format 8-data-bits, 1-stop-bit, parity-none LPC_UART0->LCR = - (3U << 0) /* 8-data-bits */ - | (0U << 2) /* 1 stop-bit */ - | (0U << 3) /* parity disable */ - | (0U << 4); /* parity none */ + (3U << 0) // 8-data-bits + | (0U << 2) // 1 stop-bit + | (0U << 3) // parity disable + | (0U << 4); // parity none QS_tickPeriod_ = SystemCoreClock / BSP_TICKS_PER_SEC; - QS_tickTime_ = QS_tickPeriod_; /* to start the timestamp at zero */ + QS_tickTime_ = QS_tickPeriod_; // to start the timestamp at zero - return 1U; /* return success */ + return 1U; // return success } -/*..........................................................................*/ +//............................................................................ void QS_onCleanup(void) { } -/*..........................................................................*/ -QSTimeCtr QS_onGetTime(void) { /* NOTE: invoked with interrupts DISABLED */ - if ((SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk) == 0) { /* not set? */ +//............................................................................ +QSTimeCtr QS_onGetTime(void) { // NOTE: invoked with interrupts DISABLED + if ((SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk) == 0) { // not set? return QS_tickTime_ - (QSTimeCtr)SysTick->VAL; } - else { /* the rollover occured, but the SysTick_ISR did not run yet */ + else { // the rollover occured, but the SysTick_ISR did not run yet return QS_tickTime_ + QS_tickPeriod_ - (QSTimeCtr)SysTick->VAL; } } -/*..........................................................................*/ +//............................................................................ void QS_onFlush(void) { - uint16_t b; - - QF_INT_DISABLE(); - while ((b = QS_getByte()) != QS_EOD) { /* while not End-Of-Data... */ - QF_INT_ENABLE(); - while ((LPC_UART0->LSR & 0x20U) == 0U) { /* while THR empty... */ - } - LPC_UART0->THR = (b & 0xFFU); /* put into the DR register */ + for (;;) { QF_INT_DISABLE(); + uint16_t b = QS_getByte(); + QF_INT_ENABLE(); + if (b != QS_EOD) { + while ((LPC_UART0->LSR & 0x20U) == 0U) { // while THR empty... + } + LPC_UART0->THR = b; // put into the THR register + } + else { + break; + } } - QF_INT_ENABLE(); +} +//............................................................................ +//! callback function to reset the target (to be implemented in the BSP) +void QS_onReset(void) { + NVIC_SystemReset(); +} +//............................................................................ +// callback function to execute a user command +void QS_onCommand(uint8_t cmdId, + uint32_t param1, uint32_t param2, uint32_t param3) +{ + Q_UNUSED_PAR(cmdId); + Q_UNUSED_PAR(param1); + Q_UNUSED_PAR(param2); + Q_UNUSED_PAR(param3); } - -/*..........................................................................*/ -/* -* Set the LPC UART0 barud-rate generator according to -* Section 14.4.12 in LPC176x Manual (document UM10360) -*/ +//............................................................................ +// +// Set the LPC UART0 barud-rate generator according to +// Section 14.4.12 in LPC176x Manual (document UM10360) +// static void UART0_setBaudrate(uint32_t baud) { - /* First we check to see if the basic divide with no DivAddVal/MulVal - * ratio gives us an integer result. If it does, we set DivAddVal = 0, - * MulVal = 1. Otherwise, we search the valid ratio value range to find - * the closest match. This could be more elegant, using search methods - * and/or lookup tables, but the brute force method is not that much - * slower, and is more maintainable. - */ - uint32_t PCLK = SystemCoreClock; /* divider /1 set below */ + // First we check to see if the basic divide with no DivAddVal/MulVal + // ratio gives us an integer result. If it does, we set DivAddVal = 0, + // MulVal = 1. Otherwise, we search the valid ratio value range to find + // the closest match. This could be more elegant, using search methods + // and/or lookup tables, but the brute force method is not that much + // slower, and is more maintainable. + // + uint32_t PCLK = SystemCoreClock; // divider /1 set below uint16_t DL = PCLK / (16U * baud); uint8_t DivAddVal = 0U; uint8_t MulVal = 1U; - /* set PCLK divider to 1 */ - LPC_SC->PCLKSEL0 &= ~(0x3U << 6); /* clear divider bits */ - LPC_SC->PCLKSEL0 |= (0x1U << 6); /* set divider to 1 */ + // set PCLK divider to 1 + LPC_SC->PCLKSEL0 &= ~(0x3U << 6); // clear divider bits + LPC_SC->PCLKSEL0 |= (0x1U << 6); // set divider to 1 - if ((PCLK % (16U * baud)) != 0U) { /* non zero remainder? */ + if ((PCLK % (16U * baud)) != 0U) { // non zero remainder? uint32_t err_best = baud; bool found = false; uint32_t b; @@ -392,37 +520,37 @@ static void UART0_setBaudrate(uint32_t baud) { uint16_t dlv; uint8_t dav; for (dav = 0U; dav < mv; ++dav) { - /* - * baud = PCLK / (16 * dlv * (1 + (DivAdd / Mul)) - * solving for dlv, we get - * dlv = mul * PCLK / (16 * baud * (divadd + mul)) - * mul has 4 bits, PCLK has 27 so we have 1 bit headroom, - * which can be used for rounding for many values of mul - * and PCLK we have 2 or more bits of headroom which can - * be used to improve precision - * note: X / 32 doesn't round correctly. - * Instead, we use ((X / 16) + 1) / 2 for correct rounding - */ - if ((mv*PCLK*2U) & 0x80000000U) { /* 1 bit headroom */ + // + // baud = PCLK / (16 * dlv * (1 + (DivAdd / Mul)) + // solving for dlv, we get + // dlv = mul * PCLK / (16 * baud * (divadd + mul)) + // mul has 4 bits, PCLK has 27 so we have 1 bit headroom, + // which can be used for rounding for many values of mul + // and PCLK we have 2 or more bits of headroom which can + // be used to improve precision + // note: X / 32 doesn't round correctly. + // Instead, we use ((X / 16) + 1) / 2 for correct rounding + // + if ((mv*PCLK*2U) & 0x80000000U) { // 1 bit headroom dlv = ((((2U*mv*PCLK) / (baud*(dav + mv)))/16U) + 1U)/2U; } - else { /* 2 bits headroom, use more precision */ + else { // 2 bits headroom, use more precision dlv = ((((4U*mv*PCLK) / (baud*(dav+mv)))/32U) + 1U)/2U; } - /* datasheet says if DLL==DLM==0, then 1 is used instead */ + // datasheet says if DLL==DLM==0, then 1 is used instead if (dlv == 0U) { dlv = 1U; } - /* datasheet says if dav > 0 then DL must be >= 2 */ + // datasheet says if dav > 0 then DL must be >= 2 if ((dav > 0U) && (dlv < 2U)) { dlv = 2U; } - /* integer rearrangement of baud equation (with rounding) */ + // integer rearrangement of baud equation (with rounding) b = ((PCLK*mv / (dlv*(dav + mv)*8U)) + 1U)/2U; b = (b >= baud) ? (b - baud) : (baud - b); - /* check to see how we did */ + // check to see how we did if (b < err_best) { err_best = b; DL = dlv; @@ -431,7 +559,7 @@ static void UART0_setBaudrate(uint32_t baud) { if (b == baud) { found = true; - break; /* break out of the inner for-loop */ + break; // break out of the inner for-loop } } } @@ -451,38 +579,37 @@ static void UART0_setBaudrate(uint32_t baud) { LPC_UART0->LCR &= ~(1U << 7); } -#endif /* Q_SPY */ -/*--------------------------------------------------------------------------*/ +#endif // Q_SPY +//---------------------------------------------------------------------------- -/***************************************************************************** -* NOTE00: -* The QF_AWARE_ISR_CMSIS_PRI constant from the QF port specifies the highest -* ISR priority that is disabled by the QF framework. The value is suitable -* for the NVIC_SetPriority() CMSIS function. -* -* Only ISRs prioritized at or below the QF_AWARE_ISR_CMSIS_PRI level (i.e., -* with the numerical values of priorities equal or higher than -* QF_AWARE_ISR_CMSIS_PRI) are allowed to call the QK_ISR_ENTRY/QK_ISR_ENTRY -* macros or any other QF/QK services. These ISRs are "QF-aware". -* -* Conversely, any ISRs prioritized above the QF_AWARE_ISR_CMSIS_PRI priority -* level (i.e., with the numerical values of priorities less than -* QF_AWARE_ISR_CMSIS_PRI) are never disabled and are not aware of the kernel. -* Such "QF-unaware" ISRs cannot call any QF/QK services. In particular they -* can NOT call the macros QK_ISR_ENTRY/QK_ISR_ENTRY. The only mechanism -* by which a "QF-unaware" ISR can communicate with the QF framework is by -* triggering a "QF-aware" ISR, which can post/publish events. -* -* NOTE01: -* The QV_onIdle() callback is called with interrupts disabled, because the -* determination of the idle condition might change by any interrupt posting -* an event. QV_onIdle() must internally enable interrupts, ideally -* atomically with putting the CPU to the power-saving mode. -* -* NOTE02: -* The User LED is used to visualize the idle loop activity. The brightness -* The User LED is used to visualize the idle loop activity. The brightness -* of the LED is proportional to the frequency of invcations of the idle loop. -* Please note that the LED is toggled with interrupts locked, so no interrupt -* execution time contributes to the brightness of the User LED. -*/ +//============================================================================ +// NOTE0: +// The QV_onIdle() callback is called with interrupts disabled, because the +// determination of the idle condition might change by any interrupt posting +// an event. QV_onIdle() must internally enable interrupts, ideally +// atomically with putting the CPU to the power-saving mode. +// +// NOTE1: +// The QF_AWARE_ISR_CMSIS_PRI constant from the QF port specifies the highest +// ISR priority that is disabled by the QF framework. The value is suitable +// for the NVIC_SetPriority() CMSIS function. +// +// Only ISRs prioritized at or below the QF_AWARE_ISR_CMSIS_PRI level (i.e., +// with the numerical values of priorities equal or higher than +// QF_AWARE_ISR_CMSIS_PRI) are allowed to call any other QF/QV services. +// These ISRs are "QF-aware". +// +// Conversely, any ISRs prioritized above the QF_AWARE_ISR_CMSIS_PRI priority +// level (i.e., with the numerical values of priorities less than +// QF_AWARE_ISR_CMSIS_PRI) are never disabled and are not aware of the kernel. +// Such "QF-unaware" ISRs cannot call ANY QF/QV services. In particular they +// can NOT call the macros QV_ISR_ENTRY/QV_ISR_ENTRY. The only mechanism +// by which a "QF-unaware" ISR can communicate with the QF framework is by +// triggering a "QF-aware" ISR, which can post/publish events. +// +// NOTE2: +// The User LED is used to visualize the idle loop activity. The brightness +// of the LED is proportional to the frequency of the idle loop. +// Please note that the LED is toggled with interrupts locked, so no interrupt +// execution time contributes to the brightness of the User LED. +// diff --git a/examples/arm-cm/dpp_mbed-lpc1768/qv/gnu/Makefile b/examples/arm-cm/dpp_mbed-lpc1768/qv/gnu/Makefile index 3b356ddc..a40ee04e 100644 --- a/examples/arm-cm/dpp_mbed-lpc1768/qv/gnu/Makefile +++ b/examples/arm-cm/dpp_mbed-lpc1768/qv/gnu/Makefile @@ -261,7 +261,7 @@ $(TARGET_BIN): $(TARGET_ELF) $(BIN) -O binary $< $@ $(TARGET_ELF) : $(ASM_OBJS_EXT) $(C_OBJS_EXT) $(CPP_OBJS_EXT) - $(CC) $(CFLAGS) $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o + $(CC) $(CFLAGS) $(QPC)/src/qs/qstamp.c -o $(BIN_DIR)/qstamp.o $(LINK) $(LINKFLAGS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) $(BIN_DIR)/%.d : %.c diff --git a/examples/arm-cm/dpp_mbed-lpc1768/qv/iar/dpp-qv.ewd b/examples/arm-cm/dpp_mbed-lpc1768/qv/iar/dpp-qv.ewd index be6e11ed..7e97aee0 100644 --- a/examples/arm-cm/dpp_mbed-lpc1768/qv/iar/dpp-qv.ewd +++ b/examples/arm-cm/dpp_mbed-lpc1768/qv/iar/dpp-qv.ewd @@ -1,4462 +1,4654 @@ - - + - 2 - - Debug - - ARM - - 1 - - C-SPY - 2 - - 26 - 1 + 3 + + Debug + + ARM + 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ARMSIM_ID - 2 - - 1 - 1 - 1 - - - - - - - - ANGEL_ID - 2 - - 0 - 1 - 1 - - - - - - - - - - - - CMSISDAP_ID - 2 - - 2 - 1 - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - GDBSERVER_ID - 2 - - 0 - 1 - 1 - - - - - - - - - - - IARROM_ID - 2 - - 1 - 1 - 1 - - - - - - - - - IJET_ID - 2 - - 6 - 1 - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - JLINK_ID - 2 - - 15 - 1 - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - LMIFTDI_ID - 2 - - 2 - 1 - 1 - - - - - - - - - - MACRAIGOR_ID - 2 - - 3 - 1 - 1 - - - - - - - - - - - - - - - - - - - - - - - PEMICRO_ID - 2 - - 1 - 1 - 1 - - - - - - - - - - - - - - - - - - - RDI_ID - 2 - - 2 - 1 - 1 - - - - - - - - - - - - - - - - STLINK_ID - 2 - - 2 - 1 - 1 - - - - - - - - - - - THIRDPARTY_ID - 2 - - 0 - 1 - 1 - - - - - - - - XDS100_ID - 2 - - 4 - 1 - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - $TOOLKIT_DIR$\plugins\middleware\HCCWare\HCCWare.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\AVIX\AVIX.ENU.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\CMX\CmxArmPlugin.ENU.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\CMX\CmxTinyArmPlugin.ENU.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\MQX\MQXRtosPlugin.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\Quadros\Quadros_EWB7_Plugin.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\SafeRTOS\SafeRTOSPlugin.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\TI-RTOS\tirtosplugin.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-286-KA-CSpy.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-KA-CSpy.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\uCOS-III\uCOS-III-KA-CSpy.ewplugin - 0 - - - $EW_DIR$\common\plugins\CodeCoverage\CodeCoverage.ENU.ewplugin - 1 - - - $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin - 0 - - - $EW_DIR$\common\plugins\SymList\SymList.ENU.ewplugin - 1 - - - $EW_DIR$\common\plugins\uCProbe\uCProbePlugin.ENU.ewplugin - 0 - - - - - Release - - ARM - - 0 - - C-SPY - 2 - - 26 - 1 + + C-SPY + 2 + + 32 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ARMSIM_ID + 2 + + 1 + 1 + 1 + + + + + + + + CADI_ID + 2 + + 0 + 1 + 1 + + + + + + + + + CMSISDAP_ID + 2 + + 4 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + GDBSERVER_ID + 2 + + 0 + 1 + 1 + + + + + + + + + + + IJET_ID + 2 + + 9 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + JLINK_ID + 2 + + 16 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + LMIFTDI_ID + 2 + + 3 + 1 + 1 + + + + + + + + + + + + + NULINK_ID + 2 + + 0 + 1 + 1 + + + + + + + PEMICRO_ID + 2 + + 3 + 1 + 1 + + + + + + + + STLINK_ID + 2 + + 8 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + THIRDPARTY_ID + 2 + + 0 + 1 + 1 + + + + + + + + TIFET_ID + 2 + + 1 + 1 + 1 + + + + + + + + + + + + + + + + + + + XDS100_ID + 2 + + 9 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + $TOOLKIT_DIR$\plugins\rtos\CMX\CmxArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\CMX\CmxTinyArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\FreeRtos\FreeRtosArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin2.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SafeRTOS\SafeRTOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9BE.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-286-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-III\uCOS-III-KA-CSpy.ewplugin + 0 + + + $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\TargetAccessServer\TargetAccessServer.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\uCProbe\uCProbePlugin.ENU.ewplugin + 0 + + + + + Release + + ARM + 0 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ARMSIM_ID - 2 - - 1 - 1 - 0 - - - - - - - - ANGEL_ID - 2 - - 0 - 1 - 0 - - - - - - - - - - - - CMSISDAP_ID - 2 - - 2 - 1 - 0 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - GDBSERVER_ID - 2 - - 0 - 1 - 0 - - - - - - - - - - - IARROM_ID - 2 - - 1 - 1 - 0 - - - - - - - - - IJET_ID - 2 - - 6 - 1 - 0 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - JLINK_ID - 2 - - 15 - 1 - 0 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - LMIFTDI_ID - 2 - - 2 - 1 - 0 - - - - - - - - - - MACRAIGOR_ID - 2 - - 3 - 1 - 0 - - - - - - - - - - - - - - - - - - - - - - - PEMICRO_ID - 2 - - 1 - 1 - 0 - - - - - - - - - - - - - - - - - - - RDI_ID - 2 - - 2 - 1 - 0 - - - - - - - - - - - - - - - - STLINK_ID - 2 - - 2 - 1 - 0 - - - - - - - - - - - THIRDPARTY_ID - 2 - - 0 - 1 - 0 - - - - - - - - XDS100_ID - 2 - - 4 - 1 - 0 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - $TOOLKIT_DIR$\plugins\middleware\HCCWare\HCCWare.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\AVIX\AVIX.ENU.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\CMX\CmxArmPlugin.ENU.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\CMX\CmxTinyArmPlugin.ENU.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\MQX\MQXRtosPlugin.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\Quadros\Quadros_EWB7_Plugin.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\SafeRTOS\SafeRTOSPlugin.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\TI-RTOS\tirtosplugin.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-286-KA-CSpy.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-KA-CSpy.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\uCOS-III\uCOS-III-KA-CSpy.ewplugin - 0 - - - $EW_DIR$\common\plugins\CodeCoverage\CodeCoverage.ENU.ewplugin - 1 - - - $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin - 0 - - - $EW_DIR$\common\plugins\SymList\SymList.ENU.ewplugin - 1 - - - $EW_DIR$\common\plugins\uCProbe\uCProbePlugin.ENU.ewplugin - 0 - - - - - Spy - - ARM - - 1 - - C-SPY - 2 - - 26 - 1 + + C-SPY + 2 + + 32 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ARMSIM_ID + 2 + + 1 + 1 + 0 + + + + + + + + CADI_ID + 2 + + 0 + 1 + 0 + + + + + + + + + CMSISDAP_ID + 2 + + 4 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + GDBSERVER_ID + 2 + + 0 + 1 + 0 + + + + + + + + + + + IJET_ID + 2 + + 9 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + JLINK_ID + 2 + + 16 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + LMIFTDI_ID + 2 + + 3 + 1 + 0 + + + + + + + + + + + + + NULINK_ID + 2 + + 0 + 1 + 0 + + + + + + + PEMICRO_ID + 2 + + 3 + 1 + 0 + + + + + + + + STLINK_ID + 2 + + 8 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + THIRDPARTY_ID + 2 + + 0 + 1 + 0 + + + + + + + + TIFET_ID + 2 + + 1 + 1 + 0 + + + + + + + + + + + + + + + + + + + XDS100_ID + 2 + + 9 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + $TOOLKIT_DIR$\plugins\rtos\CMX\CmxArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\CMX\CmxTinyArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\FreeRtos\FreeRtosArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin2.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SafeRTOS\SafeRTOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9BE.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-286-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-III\uCOS-III-KA-CSpy.ewplugin + 0 + + + $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\TargetAccessServer\TargetAccessServer.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\uCProbe\uCProbePlugin.ENU.ewplugin + 0 + + + + + Spy + + ARM + 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ARMSIM_ID - 2 - - 1 - 1 - 1 - - - - - - - - ANGEL_ID - 2 - - 0 - 1 - 1 - - - - - - - - - - - - CMSISDAP_ID - 2 - - 2 - 1 - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - GDBSERVER_ID - 2 - - 0 - 1 - 1 - - - - - - - - - - - IARROM_ID - 2 - - 1 - 1 - 1 - - - - - - - - - IJET_ID - 2 - - 6 - 1 - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - JLINK_ID - 2 - - 15 - 1 - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - LMIFTDI_ID - 2 - - 2 - 1 - 1 - - - - - - - - - - MACRAIGOR_ID - 2 - - 3 - 1 - 1 - - - - - - - - - - - - - - - - - - - - - - - PEMICRO_ID - 2 - - 1 - 1 - 1 - - - - - - - - - - - - - - - - - - - RDI_ID - 2 - - 2 - 1 - 1 - - - - - - - - - - - - - - - - STLINK_ID - 2 - - 2 - 1 - 1 - - - - - - - - - - - THIRDPARTY_ID - 2 - - 0 - 1 - 1 - - - - - - - - XDS100_ID - 2 - - 4 - 1 - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - $TOOLKIT_DIR$\plugins\middleware\HCCWare\HCCWare.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\AVIX\AVIX.ENU.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\CMX\CmxArmPlugin.ENU.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\CMX\CmxTinyArmPlugin.ENU.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\MQX\MQXRtosPlugin.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\Quadros\Quadros_EWB7_Plugin.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\SafeRTOS\SafeRTOSPlugin.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\TI-RTOS\tirtosplugin.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-286-KA-CSpy.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-KA-CSpy.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\uCOS-III\uCOS-III-KA-CSpy.ewplugin - 0 - - - $EW_DIR$\common\plugins\CodeCoverage\CodeCoverage.ENU.ewplugin - 1 - - - $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin - 0 - - - $EW_DIR$\common\plugins\SymList\SymList.ENU.ewplugin - 1 - - - $EW_DIR$\common\plugins\uCProbe\uCProbePlugin.ENU.ewplugin - 0 - - - + + C-SPY + 2 + + 32 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ARMSIM_ID + 2 + + 1 + 1 + 1 + + + + + + + + CADI_ID + 2 + + 0 + 1 + 1 + + + + + + + + + CMSISDAP_ID + 2 + + 4 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + GDBSERVER_ID + 2 + + 0 + 1 + 1 + + + + + + + + + + + IJET_ID + 2 + + 9 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + JLINK_ID + 2 + + 16 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + LMIFTDI_ID + 2 + + 3 + 1 + 1 + + + + + + + + + + + + + NULINK_ID + 2 + + 0 + 1 + 1 + + + + + + + PEMICRO_ID + 2 + + 3 + 1 + 1 + + + + + + + + STLINK_ID + 2 + + 8 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + THIRDPARTY_ID + 2 + + 0 + 1 + 1 + + + + + + + + TIFET_ID + 2 + + 1 + 1 + 1 + + + + + + + + + + + + + + + + + + + XDS100_ID + 2 + + 9 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + $TOOLKIT_DIR$\plugins\rtos\CMX\CmxArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\CMX\CmxTinyArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\FreeRtos\FreeRtosArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin2.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SafeRTOS\SafeRTOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9BE.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-286-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-III\uCOS-III-KA-CSpy.ewplugin + 0 + + + $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\TargetAccessServer\TargetAccessServer.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\uCProbe\uCProbePlugin.ENU.ewplugin + 0 + + + - - diff --git a/examples/arm-cm/dpp_mbed-lpc1768/qv/iar/dpp-qv.ewp b/examples/arm-cm/dpp_mbed-lpc1768/qv/iar/dpp-qv.ewp index c1ac0d82..ece64819 100644 --- a/examples/arm-cm/dpp_mbed-lpc1768/qv/iar/dpp-qv.ewp +++ b/examples/arm-cm/dpp_mbed-lpc1768/qv/iar/dpp-qv.ewp @@ -1,3017 +1,3348 @@ - - + - 2 - - Debug - - ARM - - 1 - - General - 3 - - 24 - 1 + 3 + + Debug + + ARM + 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ICCARM - 2 - - 31 - 1 - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - AARM - 2 - - 9 - 1 - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - OBJCOPY - 0 - - 1 - 1 - 1 - - - - - - - - - CUSTOM - 3 - - - - 0 - - - - BICOMP - 0 - - - - BUILDACTION - 1 - - cmd /c "if exist $OBJ_DIR$\qstamp.o del $OBJ_DIR$\qstamp.o" - - - - - ILINK - 0 - - 17 - 1 - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - IARCHIVE - 0 - - 0 - 1 - 1 - - - - - - - BILINK - 0 - - - - Coder - 0 - - - - - Release - - ARM - - 0 - - General - 3 - - 24 - 1 + + General + 3 + + 35 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ICCARM + 2 + + 37 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + AARM + 2 + + 11 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + OBJCOPY + 0 + + 1 + 1 + 1 + + + + + + + + + CUSTOM + 3 + + + + 0 + inputOutputBased + + + + BUILDACTION + 1 + + cmd /c "if exist $OBJ_DIR$\qstamp.o del $OBJ_DIR$\qstamp.o" + + + + + ILINK + 0 + + 27 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + IARCHIVE + 0 + + 0 + 1 + 1 + + + + + + + Coder + 0 + + + + + Release + + ARM + 0 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ICCARM - 2 - - 31 - 1 - 0 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - AARM - 2 - - 9 - 1 - 0 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - OBJCOPY - 0 - - 1 - 1 - 0 - - - - - - - - - CUSTOM - 3 - - - - 0 - - - - BICOMP - 0 - - - - BUILDACTION - 1 - - cmd /c "if exist $OBJ_DIR$\qstamp.o del $OBJ_DIR$\qstamp.o" - - - - - ILINK - 0 - - 17 - 1 - 0 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - IARCHIVE - 0 - - 0 - 1 - 0 - - - - - - - BILINK - 0 - - - - Coder - 0 - - - - - Spy - - ARM - - 1 - - General - 3 - - 24 - 1 + + General + 3 + + 35 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ICCARM + 2 + + 37 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + AARM + 2 + + 11 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + OBJCOPY + 0 + + 1 + 1 + 0 + + + + + + + + + CUSTOM + 3 + + + + 0 + inputOutputBased + + + + BUILDACTION + 1 + + cmd /c "if exist $OBJ_DIR$\qstamp.o del $OBJ_DIR$\qstamp.o" + + + + + ILINK + 0 + + 27 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + IARCHIVE + 0 + + 0 + 1 + 0 + + + + + + + Coder + 0 + + + + + Spy + + ARM + 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ICCARM - 2 - - 31 - 1 - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - AARM - 2 - - 9 - 1 - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - OBJCOPY - 0 - - 1 - 1 - 1 - - - - - - - - - CUSTOM - 3 - - - - 0 - - - - BICOMP - 0 - - - - BUILDACTION - 1 - - cmd /c "if exist $OBJ_DIR$\qstamp.o del $OBJ_DIR$\qstamp.o" - - - - - ILINK - 0 - - 17 - 1 - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - IARCHIVE - 0 - - 0 - 1 - 1 - - - - - - - BILINK - 0 - - - - Coder - 0 - - - - - Application - - $PROJ_DIR$\..\bsp.c - - - $PROJ_DIR$\..\..\bsp.h - - - $PROJ_DIR$\..\..\dpp.h - - - $PROJ_DIR$\..\..\main.c - - - $PROJ_DIR$\..\..\philo.c - - - $PROJ_DIR$\..\..\..\..\..\include\qstamp.c - - - $PROJ_DIR$\..\..\table.c - - - - mbed-lpc1768 - - $PROJ_DIR$\..\..\..\..\..\3rd_party\mbed-lpc1768\LPC17xx.h - - - $PROJ_DIR$\..\..\..\..\..\3rd_party\mbed-lpc1768\iar\startup_LPC17xx.s - - - $PROJ_DIR$\..\..\..\..\..\3rd_party\mbed-lpc1768\system_LPC17xx.c - - - $PROJ_DIR$\..\..\..\..\..\3rd_party\mbed-lpc1768\system_LPC17xx.h - - - - QP - - $PROJ_DIR$\..\..\..\..\..\src\qf\qep_hsm.c - - - $PROJ_DIR$\..\..\..\..\..\src\qf\qep_msm.c - - - $PROJ_DIR$\..\..\..\..\..\src\qf\qf_act.c - - - $PROJ_DIR$\..\..\..\..\..\src\qf\qf_actq.c - - - $PROJ_DIR$\..\..\..\..\..\src\qf\qf_defer.c - - - $PROJ_DIR$\..\..\..\..\..\src\qf\qf_dyn.c - - - $PROJ_DIR$\..\..\..\..\..\src\qf\qf_mem.c - - - $PROJ_DIR$\..\..\..\..\..\src\qf_pkg.h - - - $PROJ_DIR$\..\..\..\..\..\src\qf\qf_ps.c - - - $PROJ_DIR$\..\..\..\..\..\src\qf\qf_qact.c - - - $PROJ_DIR$\..\..\..\..\..\src\qf\qf_qeq.c - - - $PROJ_DIR$\..\..\..\..\..\src\qf\qf_qmact.c - - - $PROJ_DIR$\..\..\..\..\..\src\qf\qf_time.c - - - $PROJ_DIR$\..\..\..\..\..\src\qv\qv.c - - - - QP_port - - $PROJ_DIR$\..\..\..\..\..\ports\arm-cm\qv\iar\qv_port.c - - - - QS - - Debug - Release - - - $PROJ_DIR$\..\..\..\..\..\src\qs\qs.c - - - $PROJ_DIR$\..\..\..\..\..\src\qs\qs_fp.c - - - $PROJ_DIR$\..\..\..\..\..\src\qs_pkg.h - - + + General + 3 + + 35 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ICCARM + 2 + + 37 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + AARM + 2 + + 11 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + OBJCOPY + 0 + + 1 + 1 + 1 + + + + + + + + + CUSTOM + 3 + + + + 0 + inputOutputBased + + + + BUILDACTION + 1 + + cmd /c "if exist $OBJ_DIR$\qstamp.o del $OBJ_DIR$\qstamp.o" + + + + + ILINK + 0 + + 27 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + IARCHIVE + 0 + + 0 + 1 + 1 + + + + + + + Coder + 0 + + + + + Application + + $PROJ_DIR$\..\bsp.c + + + $PROJ_DIR$\..\..\bsp.h + + + $PROJ_DIR$\..\..\dpp.h + + + $PROJ_DIR$\..\..\main.c + + + $PROJ_DIR$\..\..\philo.c + + + $PROJ_DIR$\..\..\table.c + + + + mbed-lpc1768 + + $PROJ_DIR$\..\..\..\..\..\3rd_party\mbed-lpc1768\LPC17xx.h + + + $PROJ_DIR$\..\..\..\..\..\3rd_party\mbed-lpc1768\iar\startup_LPC17xx.s + + + $PROJ_DIR$\..\..\..\..\..\3rd_party\mbed-lpc1768\system_LPC17xx.c + + + $PROJ_DIR$\..\..\..\..\..\3rd_party\mbed-lpc1768\system_LPC17xx.h + + + + QP + + $PROJ_DIR$\..\..\..\..\..\src\qf\qep_hsm.c + + + $PROJ_DIR$\..\..\..\..\..\src\qf\qep_msm.c + + + $PROJ_DIR$\..\..\..\..\..\src\qf\qf_act.c + + + $PROJ_DIR$\..\..\..\..\..\src\qf\qf_actq.c + + + $PROJ_DIR$\..\..\..\..\..\src\qf\qf_defer.c + + + $PROJ_DIR$\..\..\..\..\..\src\qf\qf_dyn.c + + + $PROJ_DIR$\..\..\..\..\..\src\qf\qf_mem.c + + + $PROJ_DIR$\..\..\..\..\..\src\qf_pkg.h + + + $PROJ_DIR$\..\..\..\..\..\src\qf\qf_ps.c + + + $PROJ_DIR$\..\..\..\..\..\src\qf\qf_qact.c + + + $PROJ_DIR$\..\..\..\..\..\src\qf\qf_qeq.c + + + $PROJ_DIR$\..\..\..\..\..\src\qf\qf_qmact.c + + + $PROJ_DIR$\..\..\..\..\..\src\qf\qf_time.c + + + $PROJ_DIR$\..\..\..\..\..\src\qv\qv.c + + + + QP_port + + $PROJ_DIR$\..\..\..\..\..\ports\arm-cm\qv\iar\qv_port.c + + + + QS + + Debug + Release + + + $PROJ_DIR$\..\..\..\..\..\src\qs\qs.c + + + $PROJ_DIR$\..\..\..\..\..\src\qs\qs_fp.c + + + $PROJ_DIR$\..\..\..\..\..\src\qs\qs_rx.c + + + $PROJ_DIR$\..\..\..\..\..\src\qs\qstamp.c + + - - diff --git a/examples/arm-cm/dpp_mbed-lpc1768/qxk/armclang/dpp-qxk.sct b/examples/arm-cm/dpp_mbed-lpc1768/qxk/armclang/dpp-qxk.sct new file mode 100644 index 00000000..cfd8b9c1 --- /dev/null +++ b/examples/arm-cm/dpp_mbed-lpc1768/qxk/armclang/dpp-qxk.sct @@ -0,0 +1,23 @@ +; ************************************************************* +; *** Scatter-Loading Description File generated by uVision *** +; +; Modified by Quantum Leaps: +; added STACK as the first section in RW_STACK +; ************************************************************* + +LR_IROM1 0x00000000 0x00080000 { ; load region size_region + ER_IROM1 0x00000000 0x00080000 { ; load address = execution address + *.o (RESET, +First) + *(InRoot$$Sections) + .ANY (+RO) + .ANY (+XO) + } + + RW_STACK 0x10000000 { ; <== Quantum Leaps + * (STACK, +First) + } + RW_IRAM1 +0 (0x00008000 - 2048) { ; NOTE: assume STACK size 2048! + .ANY (+RW +ZI) + } +} + diff --git a/examples/arm-cm/dpp_mbed-lpc1768/qxk/armclang/dpp-qxk.uvoptx b/examples/arm-cm/dpp_mbed-lpc1768/qxk/armclang/dpp-qxk.uvoptx new file mode 100644 index 00000000..89ca37ee --- /dev/null +++ b/examples/arm-cm/dpp_mbed-lpc1768/qxk/armclang/dpp-qxk.uvoptx @@ -0,0 +1,1022 @@ + + + + 1.0 + +
### uVision Project, (C) Keil Software
+ + + *.c + *.s*; *.src; *.a* + *.obj; *.o + *.lib + *.txt; *.h; *.inc; *.md + *.plm + *.cpp + 0 + + + + 0 + 0 + + + + dpp-dbg + 0x4 + ARM-ADS + + 12000000 + + 1 + 1 + 1 + 0 + 0 + + + 1 + 65535 + 0 + 0 + 0 + + + 79 + 66 + 8 + .\dbg\ + + + 1 + 1 + 1 + 0 + 1 + 1 + 0 + 1 + 0 + 0 + 0 + 0 + + + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + + + 1 + 0 + 1 + + 8 + + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + 1 + 1 + 0 + 1 + 0 + 1 + 1 + 0 + 0 + 1 + 0 + 0 + 0 + + + + + + + + + + + BIN\UL2CM3.DLL + + + + 0 + DLGUARM + ÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÈ`Â +—.Çv´ð4 + + + 0 + ARMRTXEVENTFLAGS + -L70 -Z18 -C0 -M0 -T1 + + + 0 + UL2CM3 + UL2CM3(-O207 -S0 -C0 -FO7 -FN1 -FCFE0 -FD10000000 -FF0LPC_IAP_512 -FL080000 -FS00 -FP0($$Device:LPC1768$Flash\LPC_IAP_512.FLM) + + + 0 + DLGTARM + (1010=-1,-1,-1,-1,0)(1007=-1,-1,-1,-1,0)(1008=-1,-1,-1,-1,0)(1009=-1,-1,-1,-1,0)(1012=-1,-1,-1,-1,0) + + + 0 + ARMDBGFLAGS + + + + 0 + lmidk-agdi + -U0E10259B -O4622 -S4 -FO61 + + + + + + 0 + 1 + me + + + + + 1 + 2 + 0x20000200 + 0 + + + + + 2 + 0 + 0x400 + 0 + + + + 0 + + + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + + + + 0 + 0 + 0 + + + + + + + + + + 1 + 1 + 0 + 2 + 10000000 + + + + + + dpp-rel + 0x4 + ARM-ADS + + 12000000 + + 1 + 1 + 1 + 0 + 0 + + + 1 + 65535 + 0 + 0 + 0 + + + 79 + 66 + 8 + .\rel\ + + + 1 + 1 + 1 + 0 + 1 + 1 + 0 + 1 + 0 + 0 + 0 + 0 + + + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + + + 1 + 0 + 0 + + 8 + + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + 1 + 1 + 0 + 1 + 0 + 1 + 1 + 0 + 0 + 1 + 0 + 0 + 0 + + + + + + + + + + + BIN\UL2CM3.DLL + + + + 0 + ARMRTXEVENTFLAGS + -L70 -Z18 -C0 -M0 -T1 + + + 0 + DLGTARM + (1010=-1,-1,-1,-1,0)(1007=-1,-1,-1,-1,0)(1008=-1,-1,-1,-1,0)(1009=-1,-1,-1,-1,0)(1012=-1,-1,-1,-1,0) + + + 0 + ARMDBGFLAGS + + + + 0 + lmidk-agdi + -U0E10259B -O4622 -S4 -FO61 + + + 0 + UL2CM3 + -O207 -S0 -C0 -FO7 -FN1 -FCFE0 -FD10000000 -FF0LPC_IAP_512 -FL080000 -FS00 -FP0($$Device:LPC1768$Flash\LPC_IAP_512.FLM) + + + + + + 1 + 2 + 0x20000200 + 0 + + + + + 2 + 0 + 0x400 + 0 + + + + 0 + + + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + + + + 0 + 0 + 0 + + + + + + + + + + 1 + 1 + 0 + 2 + 10000000 + + + + + + dpp-spy + 0x4 + ARM-ADS + + 12000000 + + 1 + 1 + 1 + 0 + 0 + + + 1 + 65535 + 0 + 0 + 0 + + + 79 + 66 + 8 + .\spy\ + + + 1 + 1 + 1 + 0 + 1 + 1 + 0 + 1 + 0 + 0 + 0 + 0 + + + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + + + 1 + 0 + 0 + + 8 + + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + 1 + 1 + 0 + 1 + 0 + 1 + 1 + 0 + 0 + 1 + 0 + 0 + 3 + + + + + + + + + + + BIN\CMSIS_AGDI.dll + + + + 0 + ARMRTXEVENTFLAGS + -L70 -Z18 -C0 -M0 -T1 + + + 0 + DLGTARM + (1010=-1,-1,-1,-1,0)(1007=-1,-1,-1,-1,0)(1008=-1,-1,-1,-1,0)(1009=-1,-1,-1,-1,0)(1012=-1,-1,-1,-1,0) + + + 0 + ARMDBGFLAGS + + + + 0 + lmidk-agdi + -U0E10259B -O4622 -S4 -FO61 + + + 0 + UL2CM3 + -O207 -S0 -C0 -FO7 -FN1 -FCFE0 -FD10000000 -FF0LPC_IAP_512 -FL080000 -FS00 -FP0($$Device:LPC1768$Flash\LPC_IAP_512.FLM) + + + + + + 1 + 2 + 0x20000200 + 0 + + + + + 2 + 0 + 0x400 + 0 + + + + 0 + + + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + + + + 0 + 0 + 0 + + + + + + + + + + 1 + 1 + 0 + 2 + 10000000 + + + + + + Source Code + 1 + 0 + 0 + 0 + + 1 + 1 + 1 + 0 + 0 + 0 + ..\bsp.c + bsp.c + 0 + 0 + + + 1 + 2 + 5 + 0 + 0 + 0 + ..\..\bsp.h + bsp.h + 0 + 0 + + + 1 + 3 + 5 + 0 + 0 + 0 + ..\..\dpp.h + dpp.h + 0 + 0 + + + 1 + 4 + 1 + 0 + 0 + 0 + ..\..\philo.c + philo.c + 0 + 0 + + + 1 + 5 + 1 + 0 + 0 + 0 + ..\..\table.c + table.c + 0 + 0 + + + 1 + 6 + 1 + 0 + 0 + 0 + ..\..\main.c + main.c + 0 + 0 + + + 1 + 7 + 1 + 0 + 0 + 0 + ..\xthread2.c + xthread2.c + 0 + 0 + + + 1 + 8 + 1 + 0 + 0 + 0 + ..\xthread1.c + xthread1.c + 0 + 0 + + + + + mbed-lpc1768 + 1 + 0 + 0 + 0 + + 2 + 9 + 1 + 0 + 0 + 0 + ..\..\..\..\..\3rd_party\mbed-lpc1768\system_LPC17xx.c + system_LPC17xx.c + 0 + 0 + + + 2 + 10 + 2 + 0 + 0 + 0 + ..\..\..\..\..\3rd_party\mbed-lpc1768\arm\startup_LPC17xx.s + startup_LPC17xx.s + 0 + 0 + + + + + QP + 1 + 0 + 0 + 0 + + 3 + 11 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qf\qep_hsm.c + qep_hsm.c + 0 + 0 + + + 3 + 12 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qf\qep_msm.c + qep_msm.c + 0 + 0 + + + 3 + 13 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qf\qf_act.c + qf_act.c + 0 + 0 + + + 3 + 14 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qf\qf_actq.c + qf_actq.c + 0 + 0 + + + 3 + 15 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qf\qf_defer.c + qf_defer.c + 0 + 0 + + + 3 + 16 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qf\qf_dyn.c + qf_dyn.c + 0 + 0 + + + 3 + 17 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qf\qf_mem.c + qf_mem.c + 0 + 0 + + + 3 + 18 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qf\qf_ps.c + qf_ps.c + 0 + 0 + + + 3 + 19 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qf\qf_qact.c + qf_qact.c + 0 + 0 + + + 3 + 20 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qf\qf_qeq.c + qf_qeq.c + 0 + 0 + + + 3 + 21 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qf\qf_qmact.c + qf_qmact.c + 0 + 0 + + + 3 + 22 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qf\qf_time.c + qf_time.c + 0 + 0 + + + 3 + 23 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qxk\qxk.c + qxk.c + 0 + 0 + + + 3 + 24 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qxk\qxk_mutex.c + qxk_mutex.c + 0 + 0 + + + 3 + 25 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qxk\qxk_sema.c + qxk_sema.c + 0 + 0 + + + 3 + 26 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qxk\qxk_xthr.c + qxk_xthr.c + 0 + 0 + + + + + QP_port + 1 + 0 + 0 + 0 + + 4 + 27 + 1 + 0 + 0 + 0 + ..\..\..\..\..\ports\arm-cm\qxk\armclang\qxk_port.c + qxk_port.c + 0 + 0 + + + + + QS + 1 + 0 + 0 + 0 + + 5 + 28 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qs\qs.c + qs.c + 0 + 0 + + + 5 + 29 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qs\qs_fp.c + qs_fp.c + 0 + 0 + + + 5 + 30 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qs\qs_rx.c + qs_rx.c + 0 + 0 + + + 5 + 31 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qs\qstamp.c + qstamp.c + 0 + 0 + + + +
diff --git a/examples/arm-cm/dpp_mbed-lpc1768/qxk/armclang/dpp-qxk.uvprojx b/examples/arm-cm/dpp_mbed-lpc1768/qxk/armclang/dpp-qxk.uvprojx new file mode 100644 index 00000000..03e86ef8 --- /dev/null +++ b/examples/arm-cm/dpp_mbed-lpc1768/qxk/armclang/dpp-qxk.uvprojx @@ -0,0 +1,1823 @@ + + + + 2.1 + +
### uVision Project, (C) Keil Software
+ + + + dpp-dbg + 0x4 + ARM-ADS + 6160000::V6.16::ARMCLANG + 1 + + + LPC1768 + NXP + Keil.LPC1700_DFP.2.7.1 + http://www.keil.com/pack/ + IROM(0x00000000,0x80000) IRAM(0x10000000,0x8000) IRAM2(0x2007C000,0x8000) CPUTYPE("Cortex-M3") CLOCK(12000000) ELITTLE + + + UL2CM3(-S0 -C0 -P0 -FD10000000 -FCFE0 -FN1 -FF0LPC_IAP_512 -FS00 -FL080000 -FP0($$Device:LPC1768$Flash\LPC_IAP_512.FLM)) + 0 + $$Device:LPC1768$Device\Include\LPC17xx.h + + + + + + + + + + $$Device:LPC1768$SVD\LPC176x5x.svd + 0 + 0 + + + + + + + 0 + 0 + 0 + 0 + 1 + + .\dbg\ + dpp-qxk + 1 + 0 + 0 + 1 + 1 + .\dbg\ + 1 + 0 + 0 + + 0 + 0 + + + 0 + 0 + 0 + 0 + + + 1 + 0 + cmd /c "del .\dbg\qstamp.o" + + 0 + 0 + 0 + 0 + + + 1 + 0 + fromelf --bin --output .\dbg\dpp-qxk.bin .\dbg\dpp-qxk.axf + + 0 + 0 + 0 + 0 + + 0 + + + + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 3 + + + 1 + + + SARMCM3.DLL + -MPU + DCM.DLL + -pCM3 + SARMCM3.DLL + -MPU + TCM.DLL + -pCM3 + + + + 1 + 0 + 0 + 0 + 16 + + + + + 1 + 0 + 0 + 1 + 1 + 4096 + + 1 + BIN\UL2CM3.DLL + + + + + + 0 + + + + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + 1 + 0 + 0 + 0 + 0 + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + "Cortex-M3" + + 0 + 0 + 0 + 1 + 1 + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 8 + 0 + 0 + 0 + 0 + 3 + 3 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 1 + 0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x10000000 + 0x8000 + + + 1 + 0x0 + 0x80000 + + + 0 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x80000 + + + 1 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x10000000 + 0x8000 + + + 0 + 0x2007c000 + 0x8000 + + + + + + 0 + 7 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 3 + 0 + 1 + 0 + 0 + 0 + 3 + 3 + 0 + 0 + 0 + 0 + 0 + + + + + ..\..;..\..\..\..\..\include;..\..\..\..\..\ports\arm-cm\qxk\armclang;..\..\..\..\..\3rd_party\CMSIS\Include;..\..\..\..\..\3rd_party\mbed-lpc1768 + + + + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 4 + + + Stack_Size=2048 Heap_Size=16 + + + + + + 0 + 0 + 0 + 0 + 1 + 0 + 0x00000000 + 0x20000000 + + dpp-qxk.sct + + + --entry Reset_Handler + + + + + + + + Source Code + + + bsp.c + 1 + ..\bsp.c + + + bsp.h + 5 + ..\..\bsp.h + + + dpp.h + 5 + ..\..\dpp.h + + + philo.c + 1 + ..\..\philo.c + + + table.c + 1 + ..\..\table.c + + + main.c + 1 + ..\..\main.c + + + xthread2.c + 1 + ..\xthread2.c + + + xthread1.c + 1 + ..\xthread1.c + + + + + mbed-lpc1768 + + + system_LPC17xx.c + 1 + ..\..\..\..\..\3rd_party\mbed-lpc1768\system_LPC17xx.c + + + startup_LPC17xx.s + 2 + ..\..\..\..\..\3rd_party\mbed-lpc1768\arm\startup_LPC17xx.s + + + + + QP + + + qep_hsm.c + 1 + ..\..\..\..\..\src\qf\qep_hsm.c + + + qep_msm.c + 1 + ..\..\..\..\..\src\qf\qep_msm.c + + + qf_act.c + 1 + ..\..\..\..\..\src\qf\qf_act.c + + + qf_actq.c + 1 + ..\..\..\..\..\src\qf\qf_actq.c + + + qf_defer.c + 1 + ..\..\..\..\..\src\qf\qf_defer.c + + + qf_dyn.c + 1 + ..\..\..\..\..\src\qf\qf_dyn.c + + + qf_mem.c + 1 + ..\..\..\..\..\src\qf\qf_mem.c + + + qf_ps.c + 1 + ..\..\..\..\..\src\qf\qf_ps.c + + + qf_qact.c + 1 + ..\..\..\..\..\src\qf\qf_qact.c + + + qf_qeq.c + 1 + ..\..\..\..\..\src\qf\qf_qeq.c + + + qf_qmact.c + 1 + ..\..\..\..\..\src\qf\qf_qmact.c + + + qf_time.c + 1 + ..\..\..\..\..\src\qf\qf_time.c + + + qxk.c + 1 + ..\..\..\..\..\src\qxk\qxk.c + + + qxk_mutex.c + 1 + ..\..\..\..\..\src\qxk\qxk_mutex.c + + + qxk_sema.c + 1 + ..\..\..\..\..\src\qxk\qxk_sema.c + + + qxk_xthr.c + 1 + ..\..\..\..\..\src\qxk\qxk_xthr.c + + + + + QP_port + + + qxk_port.c + 1 + ..\..\..\..\..\ports\arm-cm\qxk\armclang\qxk_port.c + + + + + QS + + + 0 + 0 + 0 + 0 + 0 + 0 + 2 + 2 + 2 + 2 + 11 + + + 1 + + + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 0 + 0 + 2 + 2 + 2 + + + + + + + + + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + + + + + + + + + + + + qs.c + 1 + ..\..\..\..\..\src\qs\qs.c + + + qs_fp.c + 1 + ..\..\..\..\..\src\qs\qs_fp.c + + + qs_rx.c + 1 + ..\..\..\..\..\src\qs\qs_rx.c + + + qstamp.c + 1 + ..\..\..\..\..\src\qs\qstamp.c + + + + + + + dpp-rel + 0x4 + ARM-ADS + 6160000::V6.16::ARMCLANG + 1 + + + LPC1768 + NXP + Keil.LPC1700_DFP.2.7.1 + http://www.keil.com/pack/ + IROM(0x00000000,0x80000) IRAM(0x10000000,0x8000) IRAM2(0x2007C000,0x8000) CPUTYPE("Cortex-M3") CLOCK(12000000) ELITTLE + + + UL2CM3(-S0 -C0 -P0 -FD10000000 -FCFE0 -FN1 -FF0LPC_IAP_512 -FS00 -FL080000 -FP0($$Device:LPC1768$Flash\LPC_IAP_512.FLM)) + 0 + $$Device:LPC1768$Device\Include\LPC17xx.h + + + + + + + + + + $$Device:LPC1768$SVD\LPC176x5x.svd + 0 + 0 + + + + + + + 0 + 0 + 0 + 0 + 1 + + .\rel\ + dpp-qxk + 1 + 0 + 0 + 0 + 0 + .\rel\ + 1 + 0 + 0 + + 0 + 0 + + + 0 + 0 + 0 + 0 + + + 1 + 0 + cmd /c "del .\rel\qstamp.o" + + 0 + 0 + 0 + 0 + + + 1 + 0 + fromelf --bin --output .\rel\dpp-qxk.bin .\rel\dpp-qxk.axf + + 0 + 0 + 0 + 0 + + 0 + + + + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 3 + + + 1 + + + SARMCM3.DLL + -MPU + DCM.DLL + -pCM3 + SARMCM3.DLL + -MPU + TCM.DLL + -pCM3 + + + + 1 + 0 + 0 + 0 + 16 + + + + + 1 + 0 + 0 + 1 + 1 + 4097 + + 1 + BIN\UL2CM3.DLL + + + + + + 0 + + + + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + 1 + 0 + 0 + 0 + 0 + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + "Cortex-M3" + + 0 + 0 + 0 + 1 + 1 + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 8 + 0 + 0 + 0 + 0 + 3 + 3 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 1 + 0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x10000000 + 0x8000 + + + 1 + 0x0 + 0x80000 + + + 0 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x80000 + + + 1 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x10000000 + 0x8000 + + + 0 + 0x2007c000 + 0x8000 + + + + + + 0 + 7 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 3 + 0 + 1 + 0 + 0 + 0 + 3 + 3 + 0 + 0 + 0 + 0 + 0 + + + NDEBUG + + ..\..;..\..\..\..\..\include;..\..\..\..\..\ports\arm-cm\qxk\armclang;..\..\..\..\..\3rd_party\CMSIS\Include;..\..\..\..\..\3rd_party\mbed-lpc1768 + + + + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 4 + + + Stack_Size=2048 Heap_Size=16 + + + + + + 0 + 0 + 0 + 0 + 1 + 0 + 0x00000000 + 0x20000000 + + dpp-qxk.sct + + + --entry Reset_Handler + + + + + + + + Source Code + + + bsp.c + 1 + ..\bsp.c + + + bsp.h + 5 + ..\..\bsp.h + + + dpp.h + 5 + ..\..\dpp.h + + + philo.c + 1 + ..\..\philo.c + + + table.c + 1 + ..\..\table.c + + + main.c + 1 + ..\..\main.c + + + xthread2.c + 1 + ..\xthread2.c + + + xthread1.c + 1 + ..\xthread1.c + + + + + mbed-lpc1768 + + + system_LPC17xx.c + 1 + ..\..\..\..\..\3rd_party\mbed-lpc1768\system_LPC17xx.c + + + startup_LPC17xx.s + 2 + ..\..\..\..\..\3rd_party\mbed-lpc1768\arm\startup_LPC17xx.s + + + + + QP + + + qep_hsm.c + 1 + ..\..\..\..\..\src\qf\qep_hsm.c + + + qep_msm.c + 1 + ..\..\..\..\..\src\qf\qep_msm.c + + + qf_act.c + 1 + ..\..\..\..\..\src\qf\qf_act.c + + + qf_actq.c + 1 + ..\..\..\..\..\src\qf\qf_actq.c + + + qf_defer.c + 1 + ..\..\..\..\..\src\qf\qf_defer.c + + + qf_dyn.c + 1 + ..\..\..\..\..\src\qf\qf_dyn.c + + + qf_mem.c + 1 + ..\..\..\..\..\src\qf\qf_mem.c + + + qf_ps.c + 1 + ..\..\..\..\..\src\qf\qf_ps.c + + + qf_qact.c + 1 + ..\..\..\..\..\src\qf\qf_qact.c + + + qf_qeq.c + 1 + ..\..\..\..\..\src\qf\qf_qeq.c + + + qf_qmact.c + 1 + ..\..\..\..\..\src\qf\qf_qmact.c + + + qf_time.c + 1 + ..\..\..\..\..\src\qf\qf_time.c + + + qxk.c + 1 + ..\..\..\..\..\src\qxk\qxk.c + + + qxk_mutex.c + 1 + ..\..\..\..\..\src\qxk\qxk_mutex.c + + + qxk_sema.c + 1 + ..\..\..\..\..\src\qxk\qxk_sema.c + + + qxk_xthr.c + 1 + ..\..\..\..\..\src\qxk\qxk_xthr.c + + + + + QP_port + + + qxk_port.c + 1 + ..\..\..\..\..\ports\arm-cm\qxk\armclang\qxk_port.c + + + + + QS + + + 0 + 0 + 0 + 0 + 0 + 0 + 2 + 2 + 2 + 2 + 11 + + + 1 + + + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 0 + 0 + 2 + 2 + 2 + + + + + + + + + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + + + + + + + + + + + + qs.c + 1 + ..\..\..\..\..\src\qs\qs.c + + + qs_fp.c + 1 + ..\..\..\..\..\src\qs\qs_fp.c + + + qs_rx.c + 1 + ..\..\..\..\..\src\qs\qs_rx.c + + + qstamp.c + 1 + ..\..\..\..\..\src\qs\qstamp.c + + + + + + + dpp-spy + 0x4 + ARM-ADS + 6160000::V6.16::ARMCLANG + 1 + + + LPC1768 + NXP + Keil.LPC1700_DFP.2.7.1 + http://www.keil.com/pack/ + IROM(0x00000000,0x80000) IRAM(0x10000000,0x8000) IRAM2(0x2007C000,0x8000) CPUTYPE("Cortex-M3") CLOCK(12000000) ELITTLE + + + UL2CM3(-S0 -C0 -P0 -FD10000000 -FCFE0 -FN1 -FF0LPC_IAP_512 -FS00 -FL080000 -FP0($$Device:LPC1768$Flash\LPC_IAP_512.FLM)) + 0 + $$Device:LPC1768$Device\Include\LPC17xx.h + + + + + + + + + + $$Device:LPC1768$SVD\LPC176x5x.svd + 0 + 0 + + + + + + + 0 + 0 + 0 + 0 + 1 + + .\spy\ + dpp-qxk + 1 + 0 + 0 + 1 + 1 + .\spy\ + 1 + 0 + 0 + + 0 + 0 + + + 0 + 0 + 0 + 0 + + + 1 + 0 + cmd /c "del .\spy\qstamp.o" + + 0 + 0 + 0 + 0 + + + 1 + 0 + fromelf --bin --output .\spy\dpp-qxk.bin .\spy\dpp-qxk.axf + + 0 + 0 + 0 + 0 + + 0 + + + + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 3 + + + 1 + + + SARMCM3.DLL + -MPU + DCM.DLL + -pCM3 + SARMCM3.DLL + -MPU + TCM.DLL + -pCM3 + + + + 1 + 0 + 0 + 0 + 16 + + + + + 1 + 0 + 0 + 1 + 1 + 4097 + + 1 + BIN\UL2CM3.DLL + + + + + + 0 + + + + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + 1 + 0 + 0 + 0 + 0 + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + "Cortex-M3" + + 0 + 0 + 0 + 1 + 1 + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 8 + 0 + 0 + 0 + 0 + 3 + 3 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 1 + 0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x10000000 + 0x8000 + + + 1 + 0x0 + 0x80000 + + + 0 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x80000 + + + 1 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x10000000 + 0x8000 + + + 0 + 0x2007c000 + 0x8000 + + + + + + 0 + 7 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 3 + 0 + 1 + 0 + 0 + 0 + 3 + 3 + 0 + 0 + 0 + 0 + 0 + + + Q_SPY ,QF_ON_CONTEXT_SW + + ..\..;..\..\..\..\..\include;..\..\..\..\..\ports\arm-cm\qxk\armclang;..\..\..\..\..\3rd_party\CMSIS\Include;..\..\..\..\..\3rd_party\mbed-lpc1768 + + + + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 4 + + + Stack_Size=2048 Heap_Size=16 + + + + + + 0 + 0 + 0 + 0 + 1 + 0 + 0x00000000 + 0x20000000 + + dpp-qxk.sct + + + --entry Reset_Handler + + + + + + + + Source Code + + + bsp.c + 1 + ..\bsp.c + + + bsp.h + 5 + ..\..\bsp.h + + + dpp.h + 5 + ..\..\dpp.h + + + philo.c + 1 + ..\..\philo.c + + + table.c + 1 + ..\..\table.c + + + main.c + 1 + ..\..\main.c + + + xthread2.c + 1 + ..\xthread2.c + + + xthread1.c + 1 + ..\xthread1.c + + + + + mbed-lpc1768 + + + system_LPC17xx.c + 1 + ..\..\..\..\..\3rd_party\mbed-lpc1768\system_LPC17xx.c + + + startup_LPC17xx.s + 2 + ..\..\..\..\..\3rd_party\mbed-lpc1768\arm\startup_LPC17xx.s + + + + + QP + + + qep_hsm.c + 1 + ..\..\..\..\..\src\qf\qep_hsm.c + + + qep_msm.c + 1 + ..\..\..\..\..\src\qf\qep_msm.c + + + qf_act.c + 1 + ..\..\..\..\..\src\qf\qf_act.c + + + qf_actq.c + 1 + ..\..\..\..\..\src\qf\qf_actq.c + + + qf_defer.c + 1 + ..\..\..\..\..\src\qf\qf_defer.c + + + qf_dyn.c + 1 + ..\..\..\..\..\src\qf\qf_dyn.c + + + qf_mem.c + 1 + ..\..\..\..\..\src\qf\qf_mem.c + + + qf_ps.c + 1 + ..\..\..\..\..\src\qf\qf_ps.c + + + qf_qact.c + 1 + ..\..\..\..\..\src\qf\qf_qact.c + + + qf_qeq.c + 1 + ..\..\..\..\..\src\qf\qf_qeq.c + + + qf_qmact.c + 1 + ..\..\..\..\..\src\qf\qf_qmact.c + + + qf_time.c + 1 + ..\..\..\..\..\src\qf\qf_time.c + + + qxk.c + 1 + ..\..\..\..\..\src\qxk\qxk.c + + + qxk_mutex.c + 1 + ..\..\..\..\..\src\qxk\qxk_mutex.c + + + qxk_sema.c + 1 + ..\..\..\..\..\src\qxk\qxk_sema.c + + + qxk_xthr.c + 1 + ..\..\..\..\..\src\qxk\qxk_xthr.c + + + + + QP_port + + + qxk_port.c + 1 + ..\..\..\..\..\ports\arm-cm\qxk\armclang\qxk_port.c + + + + + QS + + + qs.c + 1 + ..\..\..\..\..\src\qs\qs.c + + + qs_fp.c + 1 + ..\..\..\..\..\src\qs\qs_fp.c + + + qs_rx.c + 1 + ..\..\..\..\..\src\qs\qs_rx.c + + + qstamp.c + 1 + ..\..\..\..\..\src\qs\qstamp.c + + + + + + + + + + + + + +
diff --git a/examples/arm-cm/dpp_mbed-lpc1768/qxk/bsp.c b/examples/arm-cm/dpp_mbed-lpc1768/qxk/bsp.c new file mode 100644 index 00000000..9f81d0d3 --- /dev/null +++ b/examples/arm-cm/dpp_mbed-lpc1768/qxk/bsp.c @@ -0,0 +1,630 @@ +//============================================================================ +// Product: DPP example, NXP mbed-LPC1768 board, QXK kernel +// Last updated for version 7.3.0 +// Last updated on 2023-08-15 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. +// +// This program is open source software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Alternatively, this program may be distributed and modified under the +// terms of Quantum Leaps commercial licenses, which expressly supersede +// the GNU General Public License and are specifically designed for +// licensees interested in retaining the proprietary status of their code. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Contact information: +// +// +//============================================================================ +#include "qpc.h" // QP/C real-time embedded framework +#include "dpp.h" // DPP Application interface +#include "bsp.h" // Board Support Package + +#include "LPC17xx.h" // CMSIS-compliant header file for the MCU used +// add other drivers if necessary... + +Q_DEFINE_THIS_FILE // define the name of this file for assertions + +// Local-scope objects ----------------------------------------------------- +#define LED_1 (1U << 18U) // P1.18 +#define LED_2 (1U << 20U) // P1.20 +#define LED_3 (1U << 21U) // P1.21 +#define LED_4 (1U << 23U) // P1.23 + +// Push-Button wired externally to DIP8 (P0.6) +#define BTN_EXT (1U << 6U) // P0.6 + +static uint32_t l_rndSeed; + +#ifdef Q_SPY + QSTimeCtr QS_tickTime_; + QSTimeCtr QS_tickPeriod_; + + // QSpy source IDs + static QSpyId const l_SysTick_Handler = { 0U }; + static QSpyId const l_EINT0_IRQHandler = { 0U }; + + #define UART_BAUD_RATE 115200U + #define UART_FR_TXFE 0x80U + #define UART_TXFIFO_DEPTH 16U + + enum AppRecords { // application-specific trace records + PHILO_STAT = QS_USER, + PAUSED_STAT, + CONTEXT_SW, + }; + +#endif + +//============================================================================ +// Error handler and ISRs... + +Q_NORETURN Q_onError(char const * const module, int_t const id) { + // NOTE: this implementation of the assertion handler is intended only + // for debugging and MUST be changed for deployment of the application + // (assuming that you ship your production code with assertions enabled). + Q_UNUSED_PAR(module); + Q_UNUSED_PAR(id); + QS_ASSERTION(module, id, 10000U); + +#ifndef NDEBUG + // for debugging, hang on in an endless loop... + for (;;) { + } +#endif + + NVIC_SystemReset(); +} +//............................................................................ +void assert_failed(char const * const module, int_t const id); // prototype +void assert_failed(char const * const module, int_t const id) { + Q_onError(module, id); +} + +// ISRs used in the application ============================================ + +void SysTick_Handler(void); // prototype +void SysTick_Handler(void) { + QXK_ISR_ENTRY(); // inform QXK about entering an ISR + + QTIMEEVT_TICK_X(0U, &l_SysTick_Handler); // time events at rate 0 + + // Perform the debouncing of buttons. The algorithm for debouncing + // adapted from the book "Embedded Systems Dictionary" by Jack Ganssle + // and Michael Barr, page 71. + // + // state of the button debouncing + static struct { + uint32_t depressed; + uint32_t previous; + } buttons = { 0U, 0U }; + + uint32_t current = ~LPC_GPIO0->FIOPIN; // read P0 with state of Buttons + uint32_t tmp = buttons.depressed; // save the depressed buttons + buttons.depressed |= (buttons.previous & current); // set depressed + buttons.depressed &= (buttons.previous | current); // clear released + buttons.previous = current; // update the history + tmp ^= buttons.depressed; // changed debounced depressed + current = buttons.depressed; + + if ((tmp & BTN_EXT) != 0U) { // debounced BTN_EXT state changed? + if ((current & BTN_EXT) != 0U) { // is BTN_EXT depressed? + static QEvt const pauseEvt = QEVT_INITIALIZER(PAUSE_SIG); + QACTIVE_PUBLISH(&pauseEvt, &l_SysTick_Handler); + } + else { // the button is released + static QEvt const serveEvt = QEVT_INITIALIZER(SERVE_SIG); + QACTIVE_PUBLISH(&serveEvt, &l_SysTick_Handler); + } + } + +#ifdef Q_SPY + tmp = SysTick->CTRL; // clear CTRL_COUNTFLAG + QS_tickTime_ += QS_tickPeriod_; // account for the clock rollover +#endif // Q_SPY + + QXK_ISR_EXIT(); // inform QXK about exiting an ISR +} +//............................................................................ +// interrupt handler for testing preemptions in QXK +void EINT0_IRQHandler(void); // prototype +void EINT0_IRQHandler(void) { + QXK_ISR_ENTRY(); // inform QXK about entering an ISR + + // for testing... + QACTIVE_POST(AO_Table, Q_NEW(QEvt, MAX_PUB_SIG), // for testing... + &l_EINT0_IRQHandler); + + QXK_ISR_EXIT(); // inform QXK about exiting an ISR +} + +//............................................................................ +#ifdef QF_ON_CONTEXT_SW +// NOTE: the context-switch callback is called with interrupts DISABLED +void QF_onContextSw(QActive *prev, QActive *next) { + Q_UNUSED_PAR(prev); + Q_UNUSED_PAR(next); + + QS_BEGIN_INCRIT(CONTEXT_SW, 0U) // in critical section! + QS_OBJ(prev); + QS_OBJ(next); + QS_END_INCRIT() +} +#endif // QF_ON_CONTEXT_SW + +//============================================================================ +// BSP functions... + +void BSP_init(void) { + // Configure the MPU to prevent NULL-pointer dereferencing ... + MPU->RBAR = 0x0U // base address (NULL) + | MPU_RBAR_VALID_Msk // valid region + | (MPU_RBAR_REGION_Msk & 7U); // region #7 + MPU->RASR = (7U << MPU_RASR_SIZE_Pos) // 2^(7+1) region + | (0x0U << MPU_RASR_AP_Pos) // no-access region + | MPU_RASR_ENABLE_Msk; // region enable + MPU->CTRL = MPU_CTRL_PRIVDEFENA_Msk // enable background region + | MPU_CTRL_ENABLE_Msk; // enable the MPU + __ISB(); + __DSB(); + + // enable the MemManage_Handler for MPU exception + SCB->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk; + + // NOTE: SystemInit() has been already called from the startup code + // but SystemCoreClock needs to be updated + SystemCoreClockUpdate(); + + // turn the GPIO clock on + LPC_SC->PCONP |= (1U << 15); + + // setup the GPIO pin functions for the LEDs... + LPC_PINCON->PINSEL3 &= ~(3U << 4); // LED_1: function P1.18 to GPIO + LPC_PINCON->PINSEL3 &= ~(3U << 8); // LED_2: function P1.20 to GPIO + LPC_PINCON->PINSEL3 &= ~(3U << 10); // LED_3: function P1.21 to GPIO + LPC_PINCON->PINSEL3 &= ~(3U << 14); // LED_4: function P1.23 to GPIO + + // Set GPIO-P1 LED pins to output + LPC_GPIO1->FIODIR |= (LED_1 | LED_2 | LED_3 | LED_4); + + + // setup the GPIO pin function for the Button... + LPC_PINCON->PINSEL0 &= ~(3U << 12); // function P0.6 to GPIO, pull-up + + // Set GPIO-P0 Button pin as input + LPC_GPIO0->FIODIR &= ~BTN_EXT; + + BSP_randomSeed(1234U); // seed the random number generator + + // initialize the QS software tracing... + if (!QS_INIT((void *)0)) { + Q_ERROR(); + } + + // dictionaries... + QS_OBJ_DICTIONARY(&l_SysTick_Handler); + QS_OBJ_DICTIONARY(&l_EINT0_IRQHandler); + QS_USR_DICTIONARY(PHILO_STAT); + QS_USR_DICTIONARY(PAUSED_STAT); + QS_USR_DICTIONARY(CONTEXT_SW); + + QS_ONLY(produce_sig_dict()); + + // setup the QS filters... + QS_GLB_FILTER(QS_ALL_RECORDS); // all records + QS_GLB_FILTER(-QS_QF_TICK); // exclude the clock tick +} +//............................................................................ +void BSP_start(void) { + // initialize event pools + static QF_MPOOL_EL(TableEvt) smlPoolSto[2*N_PHILO]; + QF_poolInit(smlPoolSto, sizeof(smlPoolSto), sizeof(smlPoolSto[0])); + + // initialize publish-subscribe + static QSubscrList subscrSto[MAX_PUB_SIG]; + QActive_psInit(subscrSto, Q_DIM(subscrSto)); + + // instantiate and start AOs/threads... + static QEvt const *xThread1QueueSto[5]; + static uint64_t xThread1StackSto[64]; + XThread1_ctor(); + QXTHREAD_START(TH_XThread1, + 1U, // QP priority of the thread + xThread1QueueSto, // event queue storage + Q_DIM(xThread1QueueSto), // event length [events] + xThread1StackSto, // stack storage + sizeof(xThread1StackSto), // stack size [bytes] + (void *)0); // no initialization param + + static QEvt const *philoQueueSto[N_PHILO][10]; + for (uint8_t n = 0U; n < N_PHILO; ++n) { + Philo_ctor(n); + QACTIVE_START(AO_Philo[n], + n + 3U, // QF-prio. + philoQueueSto[n], // event queue storage + Q_DIM(philoQueueSto[n]), // queue length [events] + (void *)0, 0U, // no stack storage + (void *)0); // no initialization param + } + + static QEvt const *xThread2QueueSto[5]; + static uint64_t xThread2StackSto[64]; + XThread2_ctor(); + QXTHREAD_START(TH_XThread2, + N_PHILO + 5U, // QP priority of the thread + xThread2QueueSto, // event queue storage + Q_DIM(xThread2QueueSto), // event length [events] + xThread2StackSto, // stack storage + sizeof(xThread2StackSto), // stack size [bytes] + (void *)0); // no initialization param + + static QEvt const *tableQueueSto[N_PHILO]; + Table_ctor(); + QACTIVE_START(AO_Table, + N_PHILO + 7U, // QP prio. of the AO + tableQueueSto, // event queue storage + Q_DIM(tableQueueSto), // queue length [events] + (void *)0, 0U, // no stack storage + (void *)0); // no initialization param +} +//............................................................................ +void BSP_displayPhilStat(uint8_t n, char const *stat) { + Q_UNUSED_PAR(n); + + if (stat[0] == 'h') { + LPC_GPIO1->FIOSET = LED_1; // turn LED on + } + else { + LPC_GPIO1->FIOCLR = LED_1; // turn LED off + } + if (stat[0] == 'e') { + LPC_GPIO1->FIOSET = LED_2; // turn LED on + } + else { + LPC_GPIO1->FIOCLR = LED_2; // turn LED off + } + + // app-specific trace record... + QS_BEGIN_ID(PHILO_STAT, AO_Table->prio) + QS_U8(1, n); // Philosopher number + QS_STR(stat); // Philosopher status + QS_END() +} +//............................................................................ +void BSP_displayPaused(uint8_t const paused) { + if (paused != 0U) { + LPC_GPIO1->FIOSET = LED_3; // turn LED on + } + else { + LPC_GPIO1->FIOCLR = LED_3; // turn LED off + } + + // application-specific trace record + QS_BEGIN_ID(PAUSED_STAT, AO_Table->prio) + QS_U8(1, paused); // Paused status + QS_END() +} +//............................................................................ +void BSP_randomSeed(uint32_t seed) { + l_rndSeed = seed; +} +//............................................................................ +uint32_t BSP_random(void) { // a very cheap pseudo-random-number generator + QSchedStatus lockStat = QXK_schedLock(N_PHILO); + // "Super-Duper" Linear Congruential Generator (LCG) + // LCG(2^32, 3*7*11*13*23, 0, seed) + // + uint32_t rnd = l_rndSeed * (3U*7U*11U*13U*23U); + l_rndSeed = rnd; // set for the next time + QXK_schedUnlock(lockStat); + + return (rnd >> 8U); +} +//............................................................................ +void BSP_terminate(int16_t result) { + Q_UNUSED_PAR(result); +} +//............................................................................ +void BSP_ledOn(void) { + LPC_GPIO1->FIOSET = LED_3; // turn LED on +} +//............................................................................ +void BSP_ledOff(void) { + LPC_GPIO1->FIOCLR = LED_3; // turn LED off +} + +//============================================================================ +// QF callbacks... +void QF_onStartup(void) { + // set up the SysTick timer to fire at BSP_TICKS_PER_SEC rate + SysTick_Config(SystemCoreClock / BSP_TICKS_PER_SEC); + + // assign all priority bits for preemption-prio. and none to sub-prio. + NVIC_SetPriorityGrouping(0U); + + // set priorities of ALL ISRs used in the system, see NOTE1 + NVIC_SetPriority(EINT0_IRQn, QF_AWARE_ISR_CMSIS_PRI + 0U); + NVIC_SetPriority(SysTick_IRQn, QF_AWARE_ISR_CMSIS_PRI + 1U); + // ... + + // enable IRQs in the NVIC... + NVIC_EnableIRQ(EINT0_IRQn); +} +//............................................................................ +void QF_onCleanup(void) { +} +//............................................................................ +void QXK_onIdle(void) { + // toggle the User LED on and then off, see NOTE2 + QF_INT_DISABLE(); + LPC_GPIO1->FIOSET = LED_4; // turn LED on + __NOP(); // a couple of NOPs to actually see the LED glow + __NOP(); + __NOP(); + __NOP(); + LPC_GPIO1->FIOCLR = LED_4; // turn LED off + QF_INT_ENABLE(); + +#ifdef Q_SPY + QF_INT_DISABLE(); + QS_rxParse(); // parse all the received bytes + QF_INT_ENABLE(); + QF_CRIT_EXIT_NOP(); + + if ((LPC_UART0->LSR & 0x20U) != 0U) { // TX Holding Register empty? + uint16_t fifo = UART_TXFIFO_DEPTH; // max bytes we can accept + + QF_INT_DISABLE(); + // try to get next contiguous block to transmit + uint8_t const *block = QS_getBlock(&fifo); + QF_INT_ENABLE(); + + while (fifo-- != 0U) { // any bytes in the block? + LPC_UART0->THR = *block++; // put into the FIFO + } + } +#elif defined NDEBUG + // Put the CPU and peripherals to the low-power mode. + // you might need to customize the clock management for your application, + // see the datasheet for your particular Cortex-M MCU. + // + __WFI(); // Wait-For-Interrupt +#endif +} + +//============================================================================ +// QS callbacks... +#ifdef Q_SPY + +static void UART0_setBaudrate(uint32_t baud); // helper function + +//............................................................................ +uint8_t QS_onStartup(void const *arg) { + Q_UNUSED_PAR(arg); + + static uint8_t qsTxBuf[2*1024]; // buffer for QS-TX channel + QS_initBuf(qsTxBuf, sizeof(qsTxBuf)); + + // TBD: add support for QS-RX channel + + // setup the P0_2 UART0 TX pin + LPC_PINCON->PINSEL0 &= ~(3U << 4); // clear P0_2 function + LPC_PINCON->PINSEL0 |= (1U << 4); // P0_2 to UART function (TX) + LPC_PINCON->PINMODE0 &= ~(3U << 4); // P0_2 pull-up register + + // setup the P0_3 UART0 RX pin + LPC_PINCON->PINSEL0 &= ~(3U << 6); // clear P0_3 function + LPC_PINCON->PINSEL0 |= (1U << 6); // P0_3 to UART function (RX) + LPC_PINCON->PINMODE0 &= ~(3U << 6); // P0_3 pull-up register + + // enable power to UART0 + LPC_SC->PCONP |= (1U << 3); + + // enable FIFOs and default RX trigger level + LPC_UART0->FCR = + (1U << 0) // FIFO Enable - 0 = Disables, 1 = Enabled + | (0U << 1) // Rx Fifo Reset + | (0U << 2) // Tx Fifo Reset + | (0U << 6); // Rx irq trig: 0=1char, 1=4chars, 2=8chars, 3=14chars + + // disable IRQs + LPC_UART0->IER = + (0U << 0) // Rx Data available IRQ disable + | (0U << 1) // Tx Fifo empty IRQ disable + | (0U << 2); // Rx Line Status IRQ disable + + + // set default baud rate + UART0_setBaudrate(115200U); + + // format 8-data-bits, 1-stop-bit, parity-none + LPC_UART0->LCR = + (3U << 0) // 8-data-bits + | (0U << 2) // 1 stop-bit + | (0U << 3) // parity disable + | (0U << 4); // parity none + + + QS_tickPeriod_ = SystemCoreClock / BSP_TICKS_PER_SEC; + QS_tickTime_ = QS_tickPeriod_; // to start the timestamp at zero + + return 1U; // return success +} +//............................................................................ +void QS_onCleanup(void) { +} +//............................................................................ +QSTimeCtr QS_onGetTime(void) { // NOTE: invoked with interrupts DISABLED + if ((SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk) == 0) { // not set? + return QS_tickTime_ - (QSTimeCtr)SysTick->VAL; + } + else { // the rollover occured, but the SysTick_ISR did not run yet + return QS_tickTime_ + QS_tickPeriod_ - (QSTimeCtr)SysTick->VAL; + } +} +//............................................................................ +void QS_onFlush(void) { + for (;;) { + QF_INT_DISABLE(); + uint16_t b = QS_getByte(); + QF_INT_ENABLE(); + if (b != QS_EOD) { + while ((LPC_UART0->LSR & 0x20U) == 0U) { // while THR empty... + } + LPC_UART0->THR = b; // put into the THR register + } + else { + break; + } + } +} +//............................................................................ +//! callback function to reset the target (to be implemented in the BSP) +void QS_onReset(void) { + NVIC_SystemReset(); +} +//............................................................................ +// callback function to execute a user command +void QS_onCommand(uint8_t cmdId, + uint32_t param1, uint32_t param2, uint32_t param3) +{ + Q_UNUSED_PAR(cmdId); + Q_UNUSED_PAR(param1); + Q_UNUSED_PAR(param2); + Q_UNUSED_PAR(param3); +} + +//............................................................................ +// +// Set the LPC UART0 barud-rate generator according to +// Section 14.4.12 in LPC176x Manual (document UM10360) +// +static void UART0_setBaudrate(uint32_t baud) { + + // First we check to see if the basic divide with no DivAddVal/MulVal + // ratio gives us an integer result. If it does, we set DivAddVal = 0, + // MulVal = 1. Otherwise, we search the valid ratio value range to find + // the closest match. This could be more elegant, using search methods + // and/or lookup tables, but the brute force method is not that much + // slower, and is more maintainable. + // + uint32_t PCLK = SystemCoreClock; // divider /1 set below + uint16_t DL = PCLK / (16U * baud); + uint8_t DivAddVal = 0U; + uint8_t MulVal = 1U; + + // set PCLK divider to 1 + LPC_SC->PCLKSEL0 &= ~(0x3U << 6); // clear divider bits + LPC_SC->PCLKSEL0 |= (0x1U << 6); // set divider to 1 + + if ((PCLK % (16U * baud)) != 0U) { // non zero remainder? + uint32_t err_best = baud; + bool found = false; + uint32_t b; + uint8_t mv; + for (mv = 1U; mv < 16U && !found; mv++) { + uint16_t dlv; + uint8_t dav; + for (dav = 0U; dav < mv; ++dav) { + // + // baud = PCLK / (16 * dlv * (1 + (DivAdd / Mul)) + // solving for dlv, we get + // dlv = mul * PCLK / (16 * baud * (divadd + mul)) + // mul has 4 bits, PCLK has 27 so we have 1 bit headroom, + // which can be used for rounding for many values of mul + // and PCLK we have 2 or more bits of headroom which can + // be used to improve precision + // note: X / 32 doesn't round correctly. + // Instead, we use ((X / 16) + 1) / 2 for correct rounding + // + if ((mv*PCLK*2U) & 0x80000000U) { // 1 bit headroom + dlv = ((((2U*mv*PCLK) / (baud*(dav + mv)))/16U) + 1U)/2U; + } + else { // 2 bits headroom, use more precision + dlv = ((((4U*mv*PCLK) / (baud*(dav+mv)))/32U) + 1U)/2U; + } + + // datasheet says if DLL==DLM==0, then 1 is used instead + if (dlv == 0U) { + dlv = 1U; + } + // datasheet says if dav > 0 then DL must be >= 2 + if ((dav > 0U) && (dlv < 2U)) { + dlv = 2U; + } + // integer rearrangement of baud equation (with rounding) + b = ((PCLK*mv / (dlv*(dav + mv)*8U)) + 1U)/2U; + b = (b >= baud) ? (b - baud) : (baud - b); + + // check to see how we did + if (b < err_best) { + err_best = b; + DL = dlv; + MulVal = mv; + DivAddVal = dav; + + if (b == baud) { + found = true; + break; // break out of the inner for-loop + } + } + } + } + } + + // set LCR[DLAB] to enable writing to divider registers + LPC_UART0->LCR |= (1U << 7); + + // set divider values + LPC_UART0->DLM = (DL >> 8) & 0xFFU; + LPC_UART0->DLL = (DL >> 0) & 0xFFU; + LPC_UART0->FDR = ((uint32_t)DivAddVal << 0) + | ((uint32_t)MulVal << 4); + + // clear LCR[DLAB] + LPC_UART0->LCR &= ~(1U << 7); +} + +#endif // Q_SPY +//---------------------------------------------------------------------------- + +//============================================================================ +// NOTE1: +// The QF_AWARE_ISR_CMSIS_PRI constant from the QF port specifies the highest +// ISR priority that is disabled by the QF framework. The value is suitable +// for the NVIC_SetPriority() CMSIS function. +// +// Only ISRs prioritized at or below the QF_AWARE_ISR_CMSIS_PRI level (i.e., +// with the numerical values of priorities equal or higher than +// QF_AWARE_ISR_CMSIS_PRI) are allowed to call the QXK_ISR_ENTRY/QXK_ISR_EXIT +// macros or any other QF/QXK services. These ISRs are "QF-aware". +// +// Conversely, any ISRs prioritized above the QF_AWARE_ISR_CMSIS_PRI priority +// level (i.e., with the numerical values of priorities less than +// QF_AWARE_ISR_CMSIS_PRI) are never disabled and are not aware of the kernel. +// Such "QF-unaware" ISRs cannot call ANY QF/QXK services. In particular they +// can NOT call the macros QXK_ISR_ENTRY/QXK_ISR_ENTRY. The only mechanism +// by which a "QF-unaware" ISR can communicate with the QF framework is by +// triggering a "QF-aware" ISR, which can post/publish events. +// +// NOTE2: +// The User LED is used to visualize the idle loop activity. The brightness +// of the LED is proportional to the frequency of the idle loop. +// Please note that the LED is toggled with interrupts locked, so no interrupt +// execution time contributes to the brightness of the User LED. +// diff --git a/examples/arm-cm/dpp_efm32-slstk3401a/qxk/gnu/Makefile-nassert b/examples/arm-cm/dpp_mbed-lpc1768/qxk/gnu/Makefile similarity index 91% rename from examples/arm-cm/dpp_efm32-slstk3401a/qxk/gnu/Makefile-nassert rename to examples/arm-cm/dpp_mbed-lpc1768/qxk/gnu/Makefile index 63fa512e..9b7a0f18 100644 --- a/examples/arm-cm/dpp_efm32-slstk3401a/qxk/gnu/Makefile-nassert +++ b/examples/arm-cm/dpp_mbed-lpc1768/qxk/gnu/Makefile @@ -1,7 +1,7 @@ ############################################################################## -# Product: Makefile for QP/C on EMF32-SLSTK3401A, QXK kernel, GNU-ARM -# Last Updated for Version: 7.2.1 -# Date of the Last Update: 2023-01-14 +# Product: Makefile for QP/C on mbed-LPC1768, QXK kernel, GNU-ARM +# Last Updated for Version: 7.3.0 +# Date of the Last Update: 2023-08-23 # # Q u a n t u m L e a P s # ------------------------ @@ -73,8 +73,8 @@ VPATH = \ $(QPC)/src/qxk \ $(QPC)/src/qs \ $(QP_PORT_DIR) \ - $(QPC)/3rd_party/efm32pg1b \ - $(QPC)/3rd_party/efm32pg1b/gnu + $(QPC)/3rd_party/mbed-lpc1768 \ + $(QPC)/3rd_party/mbed-lpc1768/gnu # list of all include directories needed by this project INCLUDES = \ @@ -82,7 +82,7 @@ INCLUDES = \ -I$(QPC)/include \ -I$(QP_PORT_DIR) \ -I$(QPC)/3rd_party/CMSIS/Include \ - -I$(QPC)/3rd_party/efm32pg1b + -I$(QPC)/3rd_party/mbed-lpc1768 #----------------------------------------------------------------------------- # files @@ -97,13 +97,10 @@ C_SRCS := \ main.c \ philo.c \ table.c \ - test.c \ - startup_efm32pg1b.c \ - system_efm32pg1b.c \ - em_cmu.c \ - em_emu.c \ - em_gpio.c \ - em_usart.c + xthread1.c \ + xthread2.c \ + system_LPC17xx.c \ + startup_LPC17xx.c # C++ source files CPP_SRCS := @@ -141,20 +138,18 @@ LIB_DIRS := LIBS := # defines -DEFINES := -DEFM32PG1B200F256GM48=1 \ - -DQF_ON_CONTEXT_SW \ - -DQXK_USE_IRQ_NUM=33 \ - -DQXK_USE_IRQ_HANDLER=FPUEH_IRQHandler \ - -DQ_NASSERT +DEFINES := \ + -DQF_ON_CONTEXT_SW + # ARM CPU, ARCH, FPU, and Float-ABI types... # ARM_CPU: [cortex-m0 | cortex-m0plus | cortex-m1 | cortex-m3 | cortex-m4] # ARM_FPU: [ | vfp] # FLOAT_ABI: [ | soft | softfp | hard] # -ARM_CPU := -mcpu=cortex-m4 -ARM_FPU := -mfpu=vfp -FLOAT_ABI := -mfloat-abi=softfp +ARM_CPU := -mcpu=cortex-m3 +ARM_FPU := +FLOAT_ABI := #----------------------------------------------------------------------------- # GNU-ARM toolset (NOTE: You need to adjust to your machine) @@ -200,7 +195,7 @@ BIN_DIR := rel ASFLAGS = $(ARM_CPU) $(ARM_FPU) $(ASM_CPU) $(ASM_FPU) CFLAGS = -c $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb \ - -std=c99 -pedantic -Wall -Wextra -W \ + -std=c11 -pedantic -Wall -Wextra -W \ -ffunction-sections -fdata-sections \ -O1 $(INCLUDES) $(DEFINES) -DNDEBUG @@ -217,7 +212,7 @@ C_SRCS += $(QS_SRCS) ASFLAGS = -g $(ARM_CPU) $(ARM_FPU) $(ASM_CPU) $(ASM_FPU) CFLAGS = -c -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb \ - -std=c99 -pedantic -Wall -Wextra -W \ + -std=c11 -pedantic -Wall -Wextra -W \ -ffunction-sections -fdata-sections \ -O $(INCLUDES) $(DEFINES) -DQ_SPY @@ -232,7 +227,7 @@ BIN_DIR := dbg ASFLAGS = -g $(ARM_CPU) $(ARM_FPU) $(ASM_CPU) $(ASM_FPU) CFLAGS = -c -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb \ - -std=c99 -pedantic -Wall -Wextra -W \ + -std=c11 -pedantic -Wall -Wextra -W \ -ffunction-sections -fdata-sections \ -O $(INCLUDES) $(DEFINES) @@ -276,7 +271,7 @@ $(TARGET_BIN): $(TARGET_ELF) $(BIN) -O binary $< $@ $(TARGET_ELF) : $(ASM_OBJS_EXT) $(C_OBJS_EXT) $(CPP_OBJS_EXT) - $(CC) $(CFLAGS) $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o + $(CC) $(CFLAGS) $(QPC)/src/qs/qstamp.c -o $(BIN_DIR)/qstamp.o $(LINK) $(LINKFLAGS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) $(BIN_DIR)/%.d : %.c diff --git a/examples/arm-cm/dpp_nucleo-l053r8/qk/gnu_with-stack-prot/dpp-qk.ld b/examples/arm-cm/dpp_mbed-lpc1768/qxk/gnu/dpp-qxk.ld similarity index 88% rename from examples/arm-cm/dpp_nucleo-l053r8/qk/gnu_with-stack-prot/dpp-qk.ld rename to examples/arm-cm/dpp_mbed-lpc1768/qxk/gnu/dpp-qxk.ld index a1742a8b..77594d7f 100644 --- a/examples/arm-cm/dpp_nucleo-l053r8/qk/gnu_with-stack-prot/dpp-qk.ld +++ b/examples/arm-cm/dpp_mbed-lpc1768/qxk/gnu/dpp-qxk.ld @@ -1,5 +1,5 @@ /***************************************************************************** -* Product: Linker script for for STM32L053R8, GNU-ARM linker +* Product: Linker script for for LPC1768, GNU-ARM linker * Last Updated for Version: 5.9.8 * Date of the Last Update: 2017-09-13 * @@ -7,7 +7,7 @@ * --------------------------- * innovating embedded systems * -* Copyright (C) Quantum Leaps, LLC. All rights reserved. +* Copyright (C) 2002-2013 Quantum Leaps, LLC. All rights reserved. * * This program is open source software: you can redistribute it and/or * modify it under the terms of the GNU General Public License as published @@ -33,15 +33,18 @@ *****************************************************************************/ OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm", "elf32-littlearm") OUTPUT_ARCH(arm) -ENTRY(Reset_Handler) /* entry Point */ +ENTRY(Reset_Handler) /* entry Point */ -MEMORY { /* memory map of STM32L053R8 */ - ROM (rx) : ORIGIN = 0x08000000, LENGTH = 64K - RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 8K +MEMORY { /* memory map of mbed-LPC1768 */ + ROM (rx) : ORIGIN = 0x00000000, LENGTH = 512K + RAM (rwx) : ORIGIN = 0x10000000, LENGTH = 0x7FDF + + USB_RAM(rwx) : ORIGIN = 0x2007C000, LENGTH = 16K + ETH_RAM(rwx) : ORIGIN = 0x20080000, LENGTH = 16K } /* The size of the stack used by the application. NOTE: you need to adjust */ -STACK_SIZE = 1K; +STACK_SIZE = 2048; /* The size of the heap used by the application. NOTE: you need to adjust */ HEAP_SIZE = 0; diff --git a/examples/arm-cm/dpp_mbed-lpc1768/qxk/iar/dpp-qxk.ewd b/examples/arm-cm/dpp_mbed-lpc1768/qxk/iar/dpp-qxk.ewd new file mode 100644 index 00000000..7e97aee0 --- /dev/null +++ b/examples/arm-cm/dpp_mbed-lpc1768/qxk/iar/dpp-qxk.ewd @@ -0,0 +1,4654 @@ + + + 3 + + Debug + + ARM + + 1 + + C-SPY + 2 + + 32 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ARMSIM_ID + 2 + + 1 + 1 + 1 + + + + + + + + CADI_ID + 2 + + 0 + 1 + 1 + + + + + + + + + CMSISDAP_ID + 2 + + 4 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + GDBSERVER_ID + 2 + + 0 + 1 + 1 + + + + + + + + + + + IJET_ID + 2 + + 9 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + JLINK_ID + 2 + + 16 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + LMIFTDI_ID + 2 + + 3 + 1 + 1 + + + + + + + + + + + + + NULINK_ID + 2 + + 0 + 1 + 1 + + + + + + + PEMICRO_ID + 2 + + 3 + 1 + 1 + + + + + + + + STLINK_ID + 2 + + 8 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + THIRDPARTY_ID + 2 + + 0 + 1 + 1 + + + + + + + + TIFET_ID + 2 + + 1 + 1 + 1 + + + + + + + + + + + + + + + + + + + XDS100_ID + 2 + + 9 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + $TOOLKIT_DIR$\plugins\rtos\CMX\CmxArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\CMX\CmxTinyArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\FreeRtos\FreeRtosArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin2.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SafeRTOS\SafeRTOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9BE.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-286-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-III\uCOS-III-KA-CSpy.ewplugin + 0 + + + $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\TargetAccessServer\TargetAccessServer.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\uCProbe\uCProbePlugin.ENU.ewplugin + 0 + + + + + Release + + ARM + + 0 + + C-SPY + 2 + + 32 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ARMSIM_ID + 2 + + 1 + 1 + 0 + + + + + + + + CADI_ID + 2 + + 0 + 1 + 0 + + + + + + + + + CMSISDAP_ID + 2 + + 4 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + GDBSERVER_ID + 2 + + 0 + 1 + 0 + + + + + + + + + + + IJET_ID + 2 + + 9 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + JLINK_ID + 2 + + 16 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + LMIFTDI_ID + 2 + + 3 + 1 + 0 + + + + + + + + + + + + + NULINK_ID + 2 + + 0 + 1 + 0 + + + + + + + PEMICRO_ID + 2 + + 3 + 1 + 0 + + + + + + + + STLINK_ID + 2 + + 8 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + THIRDPARTY_ID + 2 + + 0 + 1 + 0 + + + + + + + + TIFET_ID + 2 + + 1 + 1 + 0 + + + + + + + + + + + + + + + + + + + XDS100_ID + 2 + + 9 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + $TOOLKIT_DIR$\plugins\rtos\CMX\CmxArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\CMX\CmxTinyArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\FreeRtos\FreeRtosArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin2.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SafeRTOS\SafeRTOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9BE.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-286-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-III\uCOS-III-KA-CSpy.ewplugin + 0 + + + $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\TargetAccessServer\TargetAccessServer.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\uCProbe\uCProbePlugin.ENU.ewplugin + 0 + + + + + Spy + + ARM + + 1 + + C-SPY + 2 + + 32 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ARMSIM_ID + 2 + + 1 + 1 + 1 + + + + + + + + CADI_ID + 2 + + 0 + 1 + 1 + + + + + + + + + CMSISDAP_ID + 2 + + 4 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + GDBSERVER_ID + 2 + + 0 + 1 + 1 + + + + + + + + + + + IJET_ID + 2 + + 9 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + JLINK_ID + 2 + + 16 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + LMIFTDI_ID + 2 + + 3 + 1 + 1 + + + + + + + + + + + + + NULINK_ID + 2 + + 0 + 1 + 1 + + + + + + + PEMICRO_ID + 2 + + 3 + 1 + 1 + + + + + + + + STLINK_ID + 2 + + 8 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + THIRDPARTY_ID + 2 + + 0 + 1 + 1 + + + + + + + + TIFET_ID + 2 + + 1 + 1 + 1 + + + + + + + + + + + + + + + + + + + XDS100_ID + 2 + + 9 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + $TOOLKIT_DIR$\plugins\rtos\CMX\CmxArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\CMX\CmxTinyArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\FreeRtos\FreeRtosArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin2.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SafeRTOS\SafeRTOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9BE.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-286-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-III\uCOS-III-KA-CSpy.ewplugin + 0 + + + $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\TargetAccessServer\TargetAccessServer.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\uCProbe\uCProbePlugin.ENU.ewplugin + 0 + + + + diff --git a/examples/arm-cm/dpp_mbed-lpc1768/qxk/iar/dpp-qxk.ewp b/examples/arm-cm/dpp_mbed-lpc1768/qxk/iar/dpp-qxk.ewp new file mode 100644 index 00000000..fa024dbe --- /dev/null +++ b/examples/arm-cm/dpp_mbed-lpc1768/qxk/iar/dpp-qxk.ewp @@ -0,0 +1,3360 @@ + + + 3 + + Debug + + ARM + + 1 + + General + 3 + + 35 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ICCARM + 2 + + 37 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + AARM + 2 + + 11 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + OBJCOPY + 0 + + 1 + 1 + 1 + + + + + + + + + CUSTOM + 3 + + + + 0 + inputOutputBased + + + + BUILDACTION + 1 + + cmd /c "if exist $OBJ_DIR$\qstamp.o del $OBJ_DIR$\qstamp.o" + + + + + ILINK + 0 + + 27 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + IARCHIVE + 0 + + 0 + 1 + 1 + + + + + + + Coder + 0 + + + + + Release + + ARM + + 0 + + General + 3 + + 35 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ICCARM + 2 + + 37 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + AARM + 2 + + 11 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + OBJCOPY + 0 + + 1 + 1 + 0 + + + + + + + + + CUSTOM + 3 + + + + 0 + inputOutputBased + + + + BUILDACTION + 1 + + cmd /c "if exist $OBJ_DIR$\qstamp.o del $OBJ_DIR$\qstamp.o" + + + + + ILINK + 0 + + 27 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + IARCHIVE + 0 + + 0 + 1 + 0 + + + + + + + Coder + 0 + + + + + Spy + + ARM + + 1 + + General + 3 + + 35 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ICCARM + 2 + + 37 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + AARM + 2 + + 11 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + OBJCOPY + 0 + + 1 + 1 + 1 + + + + + + + + + CUSTOM + 3 + + + + 0 + inputOutputBased + + + + BUILDACTION + 1 + + cmd /c "if exist $OBJ_DIR$\qstamp.o del $OBJ_DIR$\qstamp.o" + + + + + ILINK + 0 + + 27 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + IARCHIVE + 0 + + 0 + 1 + 1 + + + + + + + Coder + 0 + + + + + Application + + $PROJ_DIR$\..\bsp.c + + + $PROJ_DIR$\..\..\bsp.h + + + $PROJ_DIR$\..\..\dpp.h + + + $PROJ_DIR$\..\..\main.c + + + $PROJ_DIR$\..\..\philo.c + + + $PROJ_DIR$\..\..\table.c + + + $PROJ_DIR$\..\xthread1.c + + + $PROJ_DIR$\..\xthread2.c + + + + mbed-lpc1768 + + $PROJ_DIR$\..\..\..\..\..\3rd_party\mbed-lpc1768\LPC17xx.h + + + $PROJ_DIR$\..\..\..\..\..\3rd_party\mbed-lpc1768\iar\startup_LPC17xx.s + + + $PROJ_DIR$\..\..\..\..\..\3rd_party\mbed-lpc1768\system_LPC17xx.c + + + $PROJ_DIR$\..\..\..\..\..\3rd_party\mbed-lpc1768\system_LPC17xx.h + + + + QP + + $PROJ_DIR$\..\..\..\..\..\src\qf\qep_hsm.c + + + $PROJ_DIR$\..\..\..\..\..\src\qf\qep_msm.c + + + $PROJ_DIR$\..\..\..\..\..\src\qf\qf_act.c + + + $PROJ_DIR$\..\..\..\..\..\src\qf\qf_actq.c + + + $PROJ_DIR$\..\..\..\..\..\src\qf\qf_defer.c + + + $PROJ_DIR$\..\..\..\..\..\src\qf\qf_dyn.c + + + $PROJ_DIR$\..\..\..\..\..\src\qf\qf_mem.c + + + $PROJ_DIR$\..\..\..\..\..\src\qf_pkg.h + + + $PROJ_DIR$\..\..\..\..\..\src\qf\qf_ps.c + + + $PROJ_DIR$\..\..\..\..\..\src\qf\qf_qact.c + + + $PROJ_DIR$\..\..\..\..\..\src\qf\qf_qeq.c + + + $PROJ_DIR$\..\..\..\..\..\src\qf\qf_qmact.c + + + $PROJ_DIR$\..\..\..\..\..\src\qf\qf_time.c + + + $PROJ_DIR$\..\..\..\..\..\src\qxk\qxk.c + + + $PROJ_DIR$\..\..\..\..\..\src\qxk\qxk_mutex.c + + + $PROJ_DIR$\..\..\..\..\..\src\qxk\qxk_sema.c + + + $PROJ_DIR$\..\..\..\..\..\src\qxk\qxk_xthr.c + + + + QP_port + + $PROJ_DIR$\..\..\..\..\..\ports\arm-cm\qxk\iar\qxk_port.c + + + + QS + + Debug + Release + + + $PROJ_DIR$\..\..\..\..\..\src\qs\qs.c + + + $PROJ_DIR$\..\..\..\..\..\src\qs\qs_rx.c + + + $PROJ_DIR$\..\..\..\..\..\src\qs\qstamp.c + + + diff --git a/examples/arm-cm/dpp_mbed-lpc1768/qxk/iar/dpp-qxk.eww b/examples/arm-cm/dpp_mbed-lpc1768/qxk/iar/dpp-qxk.eww new file mode 100644 index 00000000..38808ca3 --- /dev/null +++ b/examples/arm-cm/dpp_mbed-lpc1768/qxk/iar/dpp-qxk.eww @@ -0,0 +1,10 @@ + + + + + $WS_DIR$\dpp-qxk.ewp + + + + + diff --git a/examples/arm-cm/dpp_mbed-lpc1768/qxk/iar/dpp-qxk.icf b/examples/arm-cm/dpp_mbed-lpc1768/qxk/iar/dpp-qxk.icf new file mode 100644 index 00000000..0b9e36c0 --- /dev/null +++ b/examples/arm-cm/dpp_mbed-lpc1768/qxk/iar/dpp-qxk.icf @@ -0,0 +1,39 @@ +/*###ICF### Section handled by ICF editor, don't touch! ****/ +/*-Editor annotation file-*/ +/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */ +/*-Specials-*/ +define symbol __ICFEDIT_intvec_start__ = 0x00000000; +/*-Memory Regions-*/ +define symbol __ICFEDIT_region_ROM_start__ = 0x00000000; +define symbol __ICFEDIT_region_ROM_end__ = 0x0007FFFF; +define symbol __ICFEDIT_region_RAM_start__ = 0x10000000; +define symbol __ICFEDIT_region_RAM_end__ = 0x10007FDF; +/*-Sizes-*/ +define symbol __ICFEDIT_size_cstack__ = 2048; +define symbol __ICFEDIT_size_heap__ = 0; +/**** End of ICF editor section. ###ICF###*/ + +define symbol __CRP_start__ = 0x000002FC; +define symbol __CRP_end__ = 0x000002FF; + +define symbol __RAM1_start__ = 0x2007C000; +define symbol __RAM1_end__ = 0x20083FFF; + +define memory mem with size = 4G; +define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__] - mem:[from __CRP_start__ to __CRP_end__]; +define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__]; +define region CRP_region = mem:[from __CRP_start__ to __CRP_end__]; +define region RAM1_region = mem:[from __RAM1_start__ to __RAM1_end__]; + +define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { }; +define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { }; + +initialize by copy { readwrite }; +do not initialize { section .noinit }; + +place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec }; +place in ROM_region { readonly }; +place in RAM_region { readwrite, + block CSTACK, block HEAP }; +place in CRP_region { section .crp }; +place in RAM1_region { section .sram }; \ No newline at end of file diff --git a/examples/arm-cm/dpp_mbed-lpc1768/qxk/xthread1.c b/examples/arm-cm/dpp_mbed-lpc1768/qxk/xthread1.c new file mode 100644 index 00000000..066b983d --- /dev/null +++ b/examples/arm-cm/dpp_mbed-lpc1768/qxk/xthread1.c @@ -0,0 +1,101 @@ +//============================================================================ +// QXThread example +// Last updated for version 7.3.0 +// Last updated on 2023-08-12 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. +// +// This program is open source software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Alternatively, this program may be distributed and modified under the +// terms of Quantum Leaps commercial licenses, which expressly supersede +// the GNU General Public License and are specifically designed for +// licensees interested in retaining the proprietary status of their code. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Contact information: +// +// +//============================================================================ +#include "qpc.h" // QP/C real-time embedded framework +#include "dpp.h" // DPP Application interface +#include "bsp.h" // Board Support Package + +//---------------------------------------------------------------------------- +//Q_DEFINE_THIS_FILE + +//............................................................................ +typedef struct XThread1 { +// protected: + QXThread super; + +// private: + // NOTE: data needed by this thread should be members of + // the thread class. That way they are in the memory region + // accessible from this thread. + uint8_t foo; + +// public: +} XThread1; + +// private: +static void XThread1_run(QXThread * const thr); +extern XThread1 XThread1_inst; + +//............................................................................ +QXThread * const TH_XThread1 = &XThread1_inst.super; + +//............................................................................ +void XThread1_ctor(void) { + XThread1 *me = &XThread1_inst; + QXThread_ctor(&me->super, &XThread1_run, 0U); +} + +//............................................................................ +XThread1 XThread1_inst; + +//............................................................................ +static void XThread1_run(QXThread * const thr) { + QS_OBJ_DICTIONARY(TH_XThread1); + QS_OBJ_DICTIONARY(&TH_XThread1->timeEvt); + + // downcast the generic thr pointer to the specific thread + XThread1 *me = (XThread1 *)thr; + + // subscribe to the EAT signal (from the application) + QActive_subscribe(&me->super.super, EAT_SIG); + + for (;;) { + QEvt const *e = QXThread_queueGet(BSP_TICKS_PER_SEC/4U); + if (e) { + QXSemaphore_signal(&TH_sema); // signal Thread2 + QF_gc(e); // must explicitly recycle the received event! + } + + QXMutex_lock(&TH_mutex, QXTHREAD_NO_TIMEOUT); // lock the mutex + BSP_ledOn(); + if (QXMutex_tryLock(&TH_mutex)) { // exercise the mutex + // some floating point code to exercise the VFP... + float volatile x = 1.4142135F; + x = x * 1.4142135F; + QXThread_delay(10U); // BLOCK while holding a mutex + QXMutex_unlock(&TH_mutex); + } + QXMutex_unlock(&TH_mutex); + BSP_ledOff(); + } +} diff --git a/examples/arm-cm/dpp_mbed-lpc1768/qxk/xthread2.c b/examples/arm-cm/dpp_mbed-lpc1768/qxk/xthread2.c new file mode 100644 index 00000000..d129603e --- /dev/null +++ b/examples/arm-cm/dpp_mbed-lpc1768/qxk/xthread2.c @@ -0,0 +1,110 @@ +//============================================================================ +// QXThread example +// Last updated for version 7.3.0 +// Last updated on 2023-08-12 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. +// +// This program is open source software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Alternatively, this program may be distributed and modified under the +// terms of Quantum Leaps commercial licenses, which expressly supersede +// the GNU General Public License and are specifically designed for +// licensees interested in retaining the proprietary status of their code. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Contact information: +// +// +//============================================================================ +#include "qpc.h" // QP/C real-time embedded framework +#include "dpp.h" // DPP Application interface +#include "bsp.h" // Board Support Package + +//---------------------------------------------------------------------------- +//Q_DEFINE_THIS_FILE + +//---------------------------------------------------------------------------- +QXSemaphore TH_sema; +QXMutex TH_mutex; + +//---------------------------------------------------------------------------- +typedef struct XThread2 { +// protected: + QXThread super; + +// private: + // NOTE: data needed by this thread should be members of + // the thread class. That way they are in the memory region + // accessible from this thread. + uint8_t foo; + +// public: +} XThread2; + +// private: +static void XThread2_run(QXThread * const thr); +extern XThread2 XThread2_inst; + +//............................................................................ +QXThread * const TH_XThread2 = &XThread2_inst.super; + +//............................................................................ +void XThread2_ctor(void) { + XThread2 *me = &XThread2_inst; + QXThread_ctor(&me->super, &XThread2_run, 0U); +} + +//............................................................................ +XThread2 XThread2_inst; + +//............................................................................ +static void XThread2_run(QXThread * const thr) { + Q_UNUSED_PAR(thr); + + QS_OBJ_DICTIONARY(TH_XThread2); + QS_OBJ_DICTIONARY(&TH_XThread2->timeEvt); + QS_OBJ_DICTIONARY(&TH_sema); + QS_OBJ_DICTIONARY(&TH_mutex); + + // downcast the generic thr pointer to the specific thread + //XThread2 *me = (XThread2 *)thr; + + // initialize the semaphore before using it + // NOTE: Here the semaphore is initialized in the highest-priority thread + // that uses it. Alternatively, the semaphore can be initialized + // before any thread runs. + QXSemaphore_init(&TH_sema, + 0U, // count==0 (signaling semaphore) + 1U); // max_count==1 (binary semaphore) + + // initialize the mutex before using it + // NOTE: Here the mutex is initialized in the highest-priority thread + // that uses it. Alternatively, the mutex can be initialized + // before any thread runs. + QXMutex_init(&TH_mutex, N_PHILO + 6U); // priority-ceiling mutex + //QXMutex_init(&TH_mutex, 0U); // alternatively: priority-ceiling NOT used + + for (;;) { + // wait on a semaphore (BLOCK indefinitely) + QXSemaphore_wait(&TH_sema, QXTHREAD_NO_TIMEOUT); + + QXMutex_lock(&TH_mutex, QXTHREAD_NO_TIMEOUT); // lock the mutex + QXThread_delay(5U); // wait more (BLOCK) + QXMutex_unlock(&TH_mutex); + } +} diff --git a/examples/arm-cm/dpp_mbed-lpc1768/table.c b/examples/arm-cm/dpp_mbed-lpc1768/table.c index d655896e..c3ae02f0 100644 --- a/examples/arm-cm/dpp_mbed-lpc1768/table.c +++ b/examples/arm-cm/dpp_mbed-lpc1768/table.c @@ -1,124 +1,130 @@ -/*$file${.::table.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* -* Model: dpp.qm -* File: ${.::table.c} -* -* This code has been generated by QM 5.2.4 . -* DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. -* -* SPDX-License-Identifier: GPL-3.0-or-later -* -* This generated code is open source software: you can redistribute it under -* the terms of the GNU General Public License as published by the Free -* Software Foundation. -* -* This code is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -* more details. -* -* NOTE: -* Alternatively, this generated code may be distributed under the terms -* of Quantum Leaps commercial licenses, which expressly supersede the GNU -* General Public License and are specifically designed for licensees -* interested in retaining the proprietary status of their code. -* -* Contact information: -* -* -*/ -/*$endhead${.::table.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -#include "qpc.h" -#include "dpp.h" -#include "bsp.h" +//$file${.::table.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// +// Model: dpp.qm +// File: ${.::table.c} +// +// This code has been generated by QM 5.3.0 . +// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. +// +// SPDX-License-Identifier: GPL-3.0-or-later +// +// This generated code is open source software: you can redistribute it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation. +// +// This code is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// NOTE: +// Alternatively, this generated code may be distributed under the terms +// of Quantum Leaps commercial licenses, which expressly supersede the GNU +// General Public License and are specifically designed for licensees +// interested in retaining the proprietary status of their code. +// +// Contact information: +// +// +// +//$endhead${.::table.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +#include "qpc.h" // QP/C real-time embedded framework +#include "dpp.h" // DPP Application interface +#include "bsp.h" // Board Support Package -Q_DEFINE_THIS_MODULE("table") +//$declare${AOs::Table} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/* Active object class -----------------------------------------------------*/ -/*$declare${AOs::Table} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${AOs::Table} ............................................................*/ -typedef struct { -/* protected: */ +//${AOs::Table} .............................................................. +typedef struct Table { +// protected: QActive super; -/* private: */ +// private: uint8_t fork[N_PHILO]; - uint8_t isHungry[N_PHILO]; + bool isHungry[N_PHILO]; + +// public: } Table; -/* protected: */ +extern Table Table_inst; + +// protected: static QState Table_initial(Table * const me, void const * const par); static QState Table_active(Table * const me, QEvt const * const e); static QState Table_serving(Table * const me, QEvt const * const e); static QState Table_paused(Table * const me, QEvt const * const e); -/*$enddecl${AOs::Table} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$enddecl${AOs::Table} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -#define RIGHT(n_) ((uint8_t)(((n_) + (N_PHILO - 1U)) % N_PHILO)) -#define LEFT(n_) ((uint8_t)(((n_) + 1U) % N_PHILO)) -#define FREE ((uint8_t)0) -#define USED ((uint8_t)1) +//---------------------------------------------------------------------------- +Q_DEFINE_THIS_FILE -/* Local objects -----------------------------------------------------------*/ -static Table l_table; /* the single instance of the Table active object */ +// helper function to provide the RIGHT neighbor of a Philo[n] +static inline uint8_t right(uint8_t const n) { + return (uint8_t)((n + (N_PHILO - 1U)) % N_PHILO); +} -/* Global-scope objects ----------------------------------------------------*/ -/*$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* Check for the minimum required QP version */ -#if (QP_VERSION < 700U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) -#error qpc version 7.0.0 or higher required +// helper function to provide the LEFT neighbor of a Philo[n] +static inline uint8_t left(uint8_t const n) { + return (uint8_t)((n + 1U) % N_PHILO); +} + +#define FREE ((uint8_t)0U) +#define USED ((uint8_t)1U) + +#define THINKING "thinking" +#define HUNGRY "hungry " +#define EATING "eating " + +//---------------------------------------------------------------------------- + +//$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// Check for the minimum required QP version +#if (QP_VERSION < 730U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) +#error qpc version 7.3.0 or higher required #endif -/*$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -/*$define${AOs::AO_Table} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//$define${Shared::Table_ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/*${AOs::AO_Table} .........................................................*/ -QActive * const AO_Table = &l_table.super; -/*$enddef${AOs::AO_Table} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ - -/*..........................................................................*/ -/*$define${AOs::Table_ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${AOs::Table_ctor} .......................................................*/ +//${Shared::Table_ctor} ...................................................... void Table_ctor(void) { - uint8_t n; - Table *me = &l_table; - + Table * const me = &Table_inst; QActive_ctor(&me->super, Q_STATE_CAST(&Table_initial)); - - for (n = 0U; n < N_PHILO; ++n) { + for (uint8_t n = 0U; n < N_PHILO; ++n) { me->fork[n] = FREE; - me->isHungry[n] = 0U; + me->isHungry[n] = false; } } -/*$enddef${AOs::Table_ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*$define${AOs::Table} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//$enddef${Shared::Table_ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +//$define${Shared::AO_Table} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/*${AOs::Table} ............................................................*/ +//${Shared::AO_Table} ........................................................ +QActive * const AO_Table = &Table_inst.super; +//$enddef${Shared::AO_Table} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +//$define${AOs::Table} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/*${AOs::Table::SM} ........................................................*/ +//${AOs::Table} .............................................................. +Table Table_inst; + +//${AOs::Table::SM} .......................................................... static QState Table_initial(Table * const me, void const * const par) { - /*${AOs::Table::SM::initial} */ - uint8_t n; - (void)par; /* unused parameter */ + //${AOs::Table::SM::initial} + Q_UNUSED_PAR(par); - QS_SIG_DICTIONARY(DONE_SIG, (void *)0); /* global signals */ - QS_SIG_DICTIONARY(EAT_SIG, (void *)0); - QS_SIG_DICTIONARY(PAUSE_SIG, (void *)0); - QS_SIG_DICTIONARY(SERVE_SIG, (void *)0); - QS_SIG_DICTIONARY(TEST_SIG, (void *)0); - - QS_SIG_DICTIONARY(HUNGRY_SIG, me); /* signal just for Table */ + #ifdef Q_SPY + Table *Table_inst = me; + QS_OBJ_DICTIONARY(Table_inst); + #endif QActive_subscribe(&me->super, DONE_SIG); QActive_subscribe(&me->super, PAUSE_SIG); QActive_subscribe(&me->super, SERVE_SIG); QActive_subscribe(&me->super, TEST_SIG); - for (n = 0U; n < N_PHILO; ++n) { + for (uint8_t n = 0U; n < N_PHILO; ++n) { me->fork[n] = FREE; - me->isHungry[n] = 0U; - BSP_displayPhilStat(n, "thinking"); + me->isHungry[n] = false; + BSP_displayPhilStat(n, THINKING); } QS_FUN_DICTIONARY(&Table_active); @@ -128,13 +134,18 @@ static QState Table_initial(Table * const me, void const * const par) { return Q_TRAN(&Table_serving); } -/*${AOs::Table::SM::active} ................................................*/ +//${AOs::Table::SM::active} .................................................. static QState Table_active(Table * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${AOs::Table::SM::active::EAT} */ + //${AOs::Table::SM::active::TEST} + case TEST_SIG: { + status_ = Q_HANDLED(); + break; + } + //${AOs::Table::SM::active::EAT} case EAT_SIG: { - Q_ERROR_ID(60); + Q_ERROR(); status_ = Q_HANDLED(); break; } @@ -146,102 +157,119 @@ static QState Table_active(Table * const me, QEvt const * const e) { return status_; } -/*${AOs::Table::SM::active::serving} .......................................*/ +//${AOs::Table::SM::active::serving} ......................................... static QState Table_serving(Table * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${AOs::Table::SM::active::serving} */ + //${AOs::Table::SM::active::serving} case Q_ENTRY_SIG: { - uint8_t n; - for (n = 0U; n < N_PHILO; ++n) { /* give permissions to eat... */ - if ((me->isHungry[n] != 0U) - && (me->fork[LEFT(n)] == FREE) + // give permissions to eat... + for (uint8_t n = 0U; n < N_PHILO; ++n) { + if (me->isHungry[n] + && (me->fork[left(n)] == FREE) && (me->fork[n] == FREE)) { - TableEvt *te; - - me->fork[LEFT(n)] = USED; + me->fork[left(n)] = USED; me->fork[n] = USED; - te = Q_NEW(TableEvt, EAT_SIG); - te->philoNum = n; - QACTIVE_PUBLISH(&te->super, &me->super); - me->isHungry[n] = 0U; - BSP_displayPhilStat(n, "eating "); + #ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, EAT_SIG, n); + #else + TableEvt *pe = Q_NEW(TableEvt, EAT_SIG); + pe->philoId = n; + #endif + QACTIVE_PUBLISH(&pe->super, &me->super); + me->isHungry[n] = false; + BSP_displayPhilStat(n, EATING); } } status_ = Q_HANDLED(); break; } - /*${AOs::Table::SM::active::serving::HUNGRY} */ + //${AOs::Table::SM::active::serving::HUNGRY} case HUNGRY_SIG: { - uint8_t n, m; + uint8_t n = Q_EVT_CAST(TableEvt)->philoId; - n = Q_EVT_CAST(TableEvt)->philoNum; - /* phil ID must be in range and he must be not hungry */ - Q_ASSERT_ID(40, (n < N_PHILO) && (me->isHungry[n] == 0U)); + // phil ID must be in range and he must be not hungry + Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); - BSP_displayPhilStat(n, "hungry "); - m = LEFT(n); - /*${AOs::Table::SM::active::serving::HUNGRY::[bothfree]} */ + BSP_displayPhilStat(n, HUNGRY); + uint8_t m = left(n); + //${AOs::Table::SM::active::serving::HUNGRY::[bothfree]} if ((me->fork[m] == FREE) && (me->fork[n] == FREE)) { - TableEvt *pe; me->fork[m] = USED; me->fork[n] = USED; - pe = Q_NEW(TableEvt, EAT_SIG); - pe->philoNum = n; + #ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, EAT_SIG, n); + #else + TableEvt *pe = Q_NEW(TableEvt, EAT_SIG); + pe->philoId = n; + #endif QACTIVE_PUBLISH(&pe->super, &me->super); - BSP_displayPhilStat(n, "eating "); + BSP_displayPhilStat(n, EATING); status_ = Q_HANDLED(); } - /*${AOs::Table::SM::active::serving::HUNGRY::[else]} */ + //${AOs::Table::SM::active::serving::HUNGRY::[else]} else { - me->isHungry[n] = 1U; + me->isHungry[n] = true; status_ = Q_HANDLED(); } break; } - /*${AOs::Table::SM::active::serving::DONE} */ + //${AOs::Table::SM::active::serving::DONE} case DONE_SIG: { - uint8_t n, m; - TableEvt *pe; + uint8_t n = Q_EVT_CAST(TableEvt)->philoId; - n = Q_EVT_CAST(TableEvt)->philoNum; - /* phil ID must be in range and he must be not hungry */ - Q_ASSERT_ID(50, (n < N_PHILO) && (me->isHungry[n] == 0U)); + // phil ID must be in range and he must be not hungry + Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); - BSP_displayPhilStat(n, "thinking"); - m = LEFT(n); - /* both forks of Phil[n] must be used */ - Q_ASSERT_ID(51, (me->fork[n] == USED) && (me->fork[m] == USED)); + BSP_displayPhilStat(n, THINKING); + uint8_t m = left(n); + + // both forks of Phil[n] must be used + Q_ASSERT((me->fork[n] == USED) && (me->fork[m] == USED)); me->fork[m] = FREE; me->fork[n] = FREE; - m = RIGHT(n); /* check the right neighbor */ + m = right(n); // check the right neighbor - if ((me->isHungry[m] != 0U) && (me->fork[m] == FREE)) { + if (me->isHungry[m] && (me->fork[m] == FREE)) { me->fork[n] = USED; me->fork[m] = USED; - me->isHungry[m] = 0U; - pe = Q_NEW(TableEvt, EAT_SIG); - pe->philoNum = m; + me->isHungry[m] = false; + #ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, EAT_SIG, m); + #else + TableEvt *pe = Q_NEW(TableEvt, EAT_SIG); + pe->philoId = m; + #endif QACTIVE_PUBLISH(&pe->super, &me->super); - BSP_displayPhilStat(m, "eating "); + BSP_displayPhilStat(m, EATING); } - m = LEFT(n); /* check the left neighbor */ - n = LEFT(m); /* left fork of the left neighbor */ - if ((me->isHungry[m] != 0U) && (me->fork[n] == FREE)) { + m = left(n); // check the left neighbor + n = left(m); // left fork of the left neighbor + if (me->isHungry[m] && (me->fork[n] == FREE)) { me->fork[m] = USED; me->fork[n] = USED; - me->isHungry[m] = 0U; - pe = Q_NEW(TableEvt, EAT_SIG); - pe->philoNum = m; + me->isHungry[m] = false; + #ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, EAT_SIG, m); + #else + TableEvt *pe = Q_NEW(TableEvt, EAT_SIG); + pe->philoId = m; + #endif QACTIVE_PUBLISH(&pe->super, &me->super); - BSP_displayPhilStat(m, "eating "); + BSP_displayPhilStat(m, EATING); } status_ = Q_HANDLED(); break; } - /*${AOs::Table::SM::active::serving::PAUSE} */ + //${AOs::Table::SM::active::serving::EAT} + case EAT_SIG: { + Q_ERROR(); + status_ = Q_HANDLED(); + break; + } + //${AOs::Table::SM::active::serving::PAUSE} case PAUSE_SIG: { status_ = Q_TRAN(&Table_paused); break; @@ -254,49 +282,51 @@ static QState Table_serving(Table * const me, QEvt const * const e) { return status_; } -/*${AOs::Table::SM::active::paused} ........................................*/ +//${AOs::Table::SM::active::paused} .......................................... static QState Table_paused(Table * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${AOs::Table::SM::active::paused} */ + //${AOs::Table::SM::active::paused} case Q_ENTRY_SIG: { BSP_displayPaused(1U); status_ = Q_HANDLED(); break; } - /*${AOs::Table::SM::active::paused} */ + //${AOs::Table::SM::active::paused} case Q_EXIT_SIG: { BSP_displayPaused(0U); status_ = Q_HANDLED(); break; } - /*${AOs::Table::SM::active::paused::SERVE} */ + //${AOs::Table::SM::active::paused::SERVE} case SERVE_SIG: { status_ = Q_TRAN(&Table_serving); break; } - /*${AOs::Table::SM::active::paused::HUNGRY} */ + //${AOs::Table::SM::active::paused::HUNGRY} case HUNGRY_SIG: { - uint8_t n = Q_EVT_CAST(TableEvt)->philoNum; - /* philo ID must be in range and he must be not hungry */ - Q_ASSERT_ID(60, (n < N_PHILO) && (me->isHungry[n] == 0U)); - me->isHungry[n] = 1U; - BSP_displayPhilStat(n, "hungry "); + uint8_t n = Q_EVT_CAST(TableEvt)->philoId; + + // philo ID must be in range and he must be not hungry + Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); + + me->isHungry[n] = true; + BSP_displayPhilStat(n, HUNGRY); status_ = Q_HANDLED(); break; } - /*${AOs::Table::SM::active::paused::DONE} */ + //${AOs::Table::SM::active::paused::DONE} case DONE_SIG: { - uint8_t n, m; + uint8_t n = Q_EVT_CAST(TableEvt)->philoId; - n = Q_EVT_CAST(TableEvt)->philoNum; - /* phil ID must be in range and he must be not hungry */ - Q_ASSERT_ID(70, (n < N_PHILO) && (me->isHungry[n] == 0U)); + // phil ID must be in range and he must be not hungry + Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); - BSP_displayPhilStat(n, "thinking"); - m = LEFT(n); - /* both forks of Phil[n] must be used */ - Q_ASSERT_ID(71, (me->fork[n] == USED) && (me->fork[m] == USED)); + BSP_displayPhilStat(n, THINKING); + uint8_t m = left(n); + + // both forks of Phil[n] must be used + Q_ASSERT((me->fork[n] == USED) && (me->fork[m] == USED)); me->fork[m] = FREE; me->fork[n] = FREE; @@ -310,5 +340,4 @@ static QState Table_paused(Table * const me, QEvt const * const e) { } return status_; } -/*$enddef${AOs::Table} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ - +//$enddef${AOs::Table} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/examples/arm-cm/dpp_nucleo-c031c6/README.md b/examples/arm-cm/dpp_nucleo-c031c6/README.md new file mode 100644 index 00000000..16866fc7 --- /dev/null +++ b/examples/arm-cm/dpp_nucleo-c031c6/README.md @@ -0,0 +1,131 @@ +> **NOTE** +This file is best viewed in a **markdown viewer**, such as the one built into GitHub. Markdown viewers are also available as plug-ins to popular Internet browsers. + +# DPP on NUCLEO-C031C6 +This example demonstrates the [Dining Philosophers Problem (DPP) application](https://www.state-machine.com/qpc/tut_dpp.html) on the STM32 NUCLEO-C031C6 board (ARM Cortex-M0+). + +

+
+STM32 NUCLEO-C031C6 +

+ +## Features Demonstrated +- multiple cooperating active objects +- immutable (const) events +- mutable (dynamic) events +- time events +- direct event posting +- publish-subscribe event delivery +- cooperative QV kernel + + with ARM-KEIL toolchain + + with GNU-ARM toolchain + + with IAR-ARM toolchain +- preemptive run-to-completion QK kernel + + with ARM-KEIL toolchain + + with GNU-ARM toolchain + + with IAR-ARM toolchain +- preemptive dual-mode QXK kernel + + with ARM-KEIL toolchain + + with GNU-ARM toolchain + + with IAR-ARM toolchain + +## Build Configurations +- Debug +- Release +- Spy - software tracing with the built-in virtual COM port + +# Code Organization +``` +examples\arm-cm\dpp_nucleo-c031c6 +| ++---qk // preemptive QK kernel +| +---gnu // GNU-ARM toolchain +| | \---targetConfigs +| | Makefile // Makefile for GNU-ARM +| +---armclang // ARM/KEIL toolchain with Compiler 6 (ARM/CLANG) +| | dpp-qk.uvprojx // uVision project +| \---iar // IAR EWARM +| dpp-qk.eww // IAR EW-ARM workspace +| +\---qv // cooperative QK kernel +| +---gnu // GNU-ARM toolchain +| | \---targetConfigs +| | Makefile // Makefile for GNU-ARM +| +---armclang // ARM/KEIL toolchain with Compiler 6 (ARM/CLANG) +| | dpp-qv.uvprojx // uVision project +| \---iar // IAR EWARM +| dpp-qv.eww // IAR EW-ARM workspace +| ++---qxk // preemptive, dual-mode QXK kernel +| +---gnu // GNU-ARM toolchain +| | \---targetConfigs +| | Makefile // Makefile for GNU-ARM +| +---armclang // ARM/KEIL toolchain with Compiler 6 (ARM/CLANG) +| | dpp-qk.uvprojx // uVision project +| \---iar // IAR EWARM +| dpp-qk.eww // IAR EW-ARM workspace +| +``` + +# Builing the example + +### GNU/ARM +- open terminal window +- change to the desired directory (either `examples\arm-cm\dpp_nucleo-c031c6\qk\gnu`, `examples\arm-cm\dpp_nucleo-c031c6\qv\gnu`, or `examples\arm-cm\dpp_nucleo-c031c6\qxk\gnu`) +- to build the default Debug configuration, type: + +``` +make +``` + +> **NOTE** +The `make` utility for Windows is provided in the QTools collection for Windows. + +- to build the Release configuration, type: + +``` +make CONF=rel +``` + +- to build the Spy configuration, type: + +``` +make CONF=spy +``` + + +### ARM/KEIL MDK +- Open the provided KEIL uVision project (either `dpp-qk.uvprojx`, `dpp-qv.uvprojx`, or `dpp-qxk.uvprojx`) +in Keil uVision IDE. Build/Debug/Download to the board from the IDE. +- Change the build configuration in the "Project Target" drop-down menu. + + +### IAR EWARM +- Open the provided IAR EWARM workspace (either `dpp-qk.eww`, `dpp-qv.eww`, or `dpp-qxk.eww`) +in IAR EWARM IDE. Build/Debug/Download to the board from the IDE. +- Change the build configuration in the "Project Configuration" drop-down menu. + + +# Tracing with QP/Spy +When the board is flashed with the Spy build configuration, it produces the QP/Spy software tracing output to the built-in virtual COM port of the TivaC LauchPad board. The trace is binary rather than ASCII, and therefore requires a special host-based application called QSPY. + +> **NOTE** QSPY host application is available in the QTools collection. + +To launch the QSPY host application: +- open terminal window +- type: + +``` +qspy -c COM5 +``` + +where "COM5" is an example virtual COM port enumerated by the board. You need to check the specific COM port number on your host computer using the Device Manager application, Ports (COM and LPT) section. + + +The following screen shot shows a typical output from QSPY: + +

+
+Typical QSPY output produced by the Spy build configuration +

+ diff --git a/examples/arm-cm/dpp_nucleo-c031c6/bsp.h b/examples/arm-cm/dpp_nucleo-c031c6/bsp.h new file mode 100644 index 00000000..fe8149a3 --- /dev/null +++ b/examples/arm-cm/dpp_nucleo-c031c6/bsp.h @@ -0,0 +1,49 @@ +//============================================================================ +// Product: DPP example +// Last Updated for Version: 7.3.0 +// Date of the Last Update: 2023-06-27 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +//============================================================================ +#ifndef BSP_H_ +#define BSP_H_ + +#define BSP_TICKS_PER_SEC 100U + +void BSP_init(void); +void BSP_start(void); +void BSP_displayPaused(uint8_t paused); +void BSP_displayPhilStat(uint8_t n, char const *stat); +void BSP_terminate(int16_t result); + +void BSP_randomSeed(uint32_t seed); // random seed +uint32_t BSP_random(void); // pseudo-random generator + +void BSP_ledOn(void); +void BSP_ledOff(void); + +#endif // BSP_H_ diff --git a/examples/arm-cm/dpp_nucleo-c031c6/dpp.h b/examples/arm-cm/dpp_nucleo-c031c6/dpp.h new file mode 100644 index 00000000..e6d1557a --- /dev/null +++ b/examples/arm-cm/dpp_nucleo-c031c6/dpp.h @@ -0,0 +1,117 @@ +//$file${.::dpp.h} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// +// Model: dpp.qm +// File: ${.::dpp.h} +// +// This code has been generated by QM 5.3.0 . +// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. +// +// SPDX-License-Identifier: GPL-3.0-or-later +// +// This generated code is open source software: you can redistribute it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation. +// +// This code is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// NOTE: +// Alternatively, this generated code may be distributed under the terms +// of Quantum Leaps commercial licenses, which expressly supersede the GNU +// General Public License and are specifically designed for licensees +// interested in retaining the proprietary status of their code. +// +// Contact information: +// +// +// +//$endhead${.::dpp.h} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +#ifndef DPP_H_ +#define DPP_H_ + +//$declare${Shared} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${Shared::AppSignals} ...................................................... +enum AppSignals { + EAT_SIG = Q_USER_SIG, // published by Table to let a Philo eat + DONE_SIG, // published by Philo when done eating + PAUSE_SIG, // published by BSP to pause the application + SERVE_SIG, // published by BSP to serve re-start serving forks + TEST_SIG, // published by BSP to test the application + MAX_PUB_SIG, // the last published signal + + TIMEOUT_SIG, // posted by time event to Philo + HUNGRY_SIG, // posted by hungry Philo to Table + MAX_SIG // the last signal +}; + +//${Shared::produce_sig_dict} ................................................ +#ifdef Q_SPY +static inline void produce_sig_dict(void) { + QS_SIG_DICTIONARY(EAT_SIG, (void *)0); + QS_SIG_DICTIONARY(DONE_SIG, (void *)0); + QS_SIG_DICTIONARY(PAUSE_SIG, (void *)0); + QS_SIG_DICTIONARY(SERVE_SIG, (void *)0); + QS_SIG_DICTIONARY(TEST_SIG, (void *)0); + + QS_SIG_DICTIONARY(TIMEOUT_SIG, (void *)0); + QS_SIG_DICTIONARY(HUNGRY_SIG, (void *)0); +} +#endif // def Q_SPY + +//${Shared::N_PHILO} ......................................................... +#define N_PHILO ((uint8_t)5U) + +//${Shared::TableEvt} ........................................................ +typedef struct { +// protected: + QEvt super; + +// public: + uint8_t philoId; +} TableEvt; + +// public: + +#ifdef QEVT_DYN_CTOR +static inline TableEvt * TableEvt_ctor(TableEvt * const me, + uint8_t id) +{ + if (me != (TableEvt *)0) { + // don't call QEvt_ctor() because the initialization of all + // QEvt attributes is already done in QF_QF_newX_() + me->philoId = id; + } + return me; +} +#endif // def QEVT_DYN_CTOR + +//${Shared::AO_Philo[N_PHILO]} ............................................... +extern QActive * const AO_Philo[N_PHILO]; + +//${Shared::Philo_ctor} ...................................................... +void Philo_ctor(uint_fast8_t const id); + +//${Shared::AO_Table} ........................................................ +extern QActive * const AO_Table; + +//${Shared::Table_ctor} ...................................................... +void Table_ctor(void); +//$enddecl${Shared} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +#ifdef QXK_H_ + +extern QXThread * const TH_XThread1; +void XThread1_ctor(void); + +extern QXThread * const TH_XThread2; +void XThread2_ctor(void); + +extern QXSemaphore TH_sema; +extern QXMutex TH_mutex; + +#endif // QXK_H_ + +#endif // DPP_H_ diff --git a/examples/arm-cm/dpp_nucleo-c031c6/dpp.qm b/examples/arm-cm/dpp_nucleo-c031c6/dpp.qm new file mode 100644 index 00000000..ac9f2bc9 --- /dev/null +++ b/examples/arm-cm/dpp_nucleo-c031c6/dpp.qm @@ -0,0 +1,525 @@ + + + Dining Philosopher Problem example + + + + + + + { + EAT_SIG = Q_USER_SIG, // published by Table to let a Philo eat + DONE_SIG, // published by Philo when done eating + PAUSE_SIG, // published by BSP to pause the application + SERVE_SIG, // published by BSP to serve re-start serving forks + TEST_SIG, // published by BSP to test the application + MAX_PUB_SIG, // the last published signal + + TIMEOUT_SIG, // posted by time event to Philo + HUNGRY_SIG, // posted by hungry Philo to Table + MAX_SIG // the last signal +}; + + + + QS_SIG_DICTIONARY(EAT_SIG, (void *)0); +QS_SIG_DICTIONARY(DONE_SIG, (void *)0); +QS_SIG_DICTIONARY(PAUSE_SIG, (void *)0); +QS_SIG_DICTIONARY(SERVE_SIG, (void *)0); +QS_SIG_DICTIONARY(TEST_SIG, (void *)0); + +QS_SIG_DICTIONARY(TIMEOUT_SIG, (void *)0); +QS_SIG_DICTIONARY(HUNGRY_SIG, (void *)0); + + + + ((uint8_t)5U) + + + + + + + + + + if (me != (TableEvt *)0) { + // don't call QEvt_ctor() because the initialization of all + // QEvt attributes is already done in QF_QF_newX_() + me->philoId = id; +} +return me; + + + + + = { + &Philo_inst[0].super, + &Philo_inst[1].super, + &Philo_inst[2].super, + &Philo_inst[3].super, + &Philo_inst[4].super +}; + + + + + + Philo * const me = &Philo_inst[id]; +QActive_ctor(&me->super, Q_STATE_CAST(&Philo_initial)); +QTimeEvt_ctorX(&me->timeEvt, &me->super, TIMEOUT_SIG, 0U), +me->id = (uint8_t)id; + + + + = &Table_inst.super; + + + + Table * const me = &Table_inst; +QActive_ctor(&me->super, Q_STATE_CAST(&Table_initial)); +for (uint8_t n = 0U; n < N_PHILO; ++n) { + me->fork[n] = FREE; + me->isHungry[n] = false; +} + + + + + + + The Philo AO and the N_PHILO instances + + + + + + + + + + + Q_UNUSED_PAR(par); + +QS_OBJ_ARR_DICTIONARY(&Philo_inst[me->id], me->id); +QS_OBJ_ARR_DICTIONARY(&Philo_inst[me->id].timeEvt, me->id); + +QActive_subscribe(&me->super, EAT_SIG); +QActive_subscribe(&me->super, TEST_SIG); + + + + + + + QTimeEvt_armX(&me->timeEvt, think_time(), 0U); + (void)QTimeEvt_disarm(&me->timeEvt); + + + + + + + + + // EAT or DONE must be for other Philos than this one +Q_ASSERT(Q_EVT_CAST(TableEvt)->philoId != me->id); + + + + + + + + + + + + + + + + + + #ifdef QEVT_DYN_CTOR +TableEvt const *pe = Q_NEW(TableEvt, HUNGRY_SIG, me->id); +#else +TableEvt *pe = Q_NEW(TableEvt, HUNGRY_SIG); +pe->philoId = me->id; +#endif +QACTIVE_POST(AO_Table, &pe->super, &me->super); + + + + + Q_EVT_CAST(TableEvt)->philoId == me->id + + + + + + + + + + + // DONE must be for other Philos than this one +Q_ASSERT(Q_EVT_CAST(TableEvt)->philoId != me->id); + + + + + + + + + + + QTimeEvt_armX(&me->timeEvt, eat_time(), 0U); + (void)QTimeEvt_disarm(&me->timeEvt); + +#ifdef QEVT_DYN_CTOR +TableEvt const *pe = Q_NEW(TableEvt, DONE_SIG, me->id); +#else +TableEvt *pe = Q_NEW(TableEvt, DONE_SIG); +pe->philoId = me->id; +#endif +QACTIVE_PUBLISH(&pe->super, &me->super); + + + + + + + + + // EAT or DONE must be for other Philos than this one +Q_ASSERT(Q_EVT_CAST(TableEvt)->philoId != me->id); + + + + + + + + + + + + + + + + + + + + + + + + + Q_UNUSED_PAR(par); + +#ifdef Q_SPY +Table *Table_inst = me; +QS_OBJ_DICTIONARY(Table_inst); +#endif + +QActive_subscribe(&me->super, DONE_SIG); +QActive_subscribe(&me->super, PAUSE_SIG); +QActive_subscribe(&me->super, SERVE_SIG); +QActive_subscribe(&me->super, TEST_SIG); + +for (uint8_t n = 0U; n < N_PHILO; ++n) { + me->fork[n] = FREE; + me->isHungry[n] = false; + BSP_displayPhilStat(n, THINKING); +} + + + + + + + + + + + + + + + Q_ERROR(); + + + + + + + // give permissions to eat... +for (uint8_t n = 0U; n < N_PHILO; ++n) { + if (me->isHungry[n] + && (me->fork[left(n)] == FREE) + && (me->fork[n] == FREE)) + { + me->fork[left(n)] = USED; + me->fork[n] = USED; +#ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, EAT_SIG, n); +#else + TableEvt *pe = Q_NEW(TableEvt, EAT_SIG); + pe->philoId = n; +#endif + QACTIVE_PUBLISH(&pe->super, &me->super); + me->isHungry[n] = false; + BSP_displayPhilStat(n, EATING); + } +} + + + uint8_t n = Q_EVT_CAST(TableEvt)->philoId; + +// phil ID must be in range and he must be not hungry +Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); + +BSP_displayPhilStat(n, HUNGRY); +uint8_t m = left(n); + + + (me->fork[m] == FREE) && (me->fork[n] == FREE) + me->fork[m] = USED; +me->fork[n] = USED; +#ifdef QEVT_DYN_CTOR +TableEvt const *pe = Q_NEW(TableEvt, EAT_SIG, n); +#else +TableEvt *pe = Q_NEW(TableEvt, EAT_SIG); +pe->philoId = n; +#endif +QACTIVE_PUBLISH(&pe->super, &me->super); +BSP_displayPhilStat(n, EATING); + + + + + + + else + me->isHungry[n] = true; + + + + + + + + + + + uint8_t n = Q_EVT_CAST(TableEvt)->philoId; + +// phil ID must be in range and he must be not hungry +Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); + +BSP_displayPhilStat(n, THINKING); +uint8_t m = left(n); + +// both forks of Phil[n] must be used +Q_ASSERT((me->fork[n] == USED) && (me->fork[m] == USED)); + +me->fork[m] = FREE; +me->fork[n] = FREE; +m = right(n); // check the right neighbor + +if (me->isHungry[m] && (me->fork[m] == FREE)) { + me->fork[n] = USED; + me->fork[m] = USED; + me->isHungry[m] = false; +#ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, EAT_SIG, m); +#else + TableEvt *pe = Q_NEW(TableEvt, EAT_SIG); + pe->philoId = m; +#endif + QACTIVE_PUBLISH(&pe->super, &me->super); + BSP_displayPhilStat(m, EATING); +} +m = left(n); // check the left neighbor +n = left(m); // left fork of the left neighbor +if (me->isHungry[m] && (me->fork[n] == FREE)) { + me->fork[m] = USED; + me->fork[n] = USED; + me->isHungry[m] = false; +#ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, EAT_SIG, m); +#else + TableEvt *pe = Q_NEW(TableEvt, EAT_SIG); + pe->philoId = m; +#endif + QACTIVE_PUBLISH(&pe->super, &me->super); + BSP_displayPhilStat(m, EATING); +} + + + + + + + Q_ERROR(); + + + + + + + + + + + + + + + + + BSP_displayPaused(1U); + BSP_displayPaused(0U); + + + + + + + + + uint8_t n = Q_EVT_CAST(TableEvt)->philoId; + +// philo ID must be in range and he must be not hungry +Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); + +me->isHungry[n] = true; +BSP_displayPhilStat(n, HUNGRY); + + + + + + + uint8_t n = Q_EVT_CAST(TableEvt)->philoId; + +// phil ID must be in range and he must be not hungry +Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); + +BSP_displayPhilStat(n, THINKING); +uint8_t m = left(n); + +// both forks of Phil[n] must be used +Q_ASSERT((me->fork[n] == USED) && (me->fork[m] == USED)); + +me->fork[m] = FREE; +me->fork[n] = FREE; + + + + + + + + + + + + + + + + + + + + #ifndef DPP_H_ +#define DPP_H_ + +$declare ${Shared} + +#ifdef QXK_H_ + +extern QXThread * const TH_XThread1; +void XThread1_ctor(void); + +extern QXThread * const TH_XThread2; +void XThread2_ctor(void); + +extern QXSemaphore TH_sema; +extern QXMutex TH_mutex; + +#endif // QXK_H_ + +#endif // DPP_H_ + + + + #include "qpc.h" // QP/C real-time embedded framework +#include "dpp.h" // DPP Application interface +#include "bsp.h" // Board Support Package + +$declare ${AOs::Philo} + +//---------------------------------------------------------------------------- +Q_DEFINE_THIS_FILE + +// helper function to provide a randomized think time for Philos +static QTimeEvtCtr think_time(void); // prototype +static inline QTimeEvtCtr think_time(void) { + return (QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + + (BSP_TICKS_PER_SEC/2U)); +} + +// helper function to provide a randomized eat time for Philos +static QTimeEvtCtr eat_time(void); // prototype +static inline QTimeEvtCtr eat_time(void) { + return (QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + + BSP_TICKS_PER_SEC); +} +//---------------------------------------------------------------------------- + +$define ${Shared::Philo_ctor} +$define ${Shared::AO_Philo[N_PHILO]} +$define ${AOs::Philo} + + + + #include "qpc.h" // QP/C real-time embedded framework +#include "dpp.h" // DPP Application interface +#include "bsp.h" // Board Support Package + +$declare ${AOs::Table} + +//---------------------------------------------------------------------------- +Q_DEFINE_THIS_FILE + +// helper function to provide the RIGHT neighbor of a Philo[n] +static inline uint8_t right(uint8_t const n) { + return (uint8_t)((n + (N_PHILO - 1U)) % N_PHILO); +} + +// helper function to provide the LEFT neighbor of a Philo[n] +static inline uint8_t left(uint8_t const n) { + return (uint8_t)((n + 1U) % N_PHILO); +} + +#define FREE ((uint8_t)0U) +#define USED ((uint8_t)1U) + +#define THINKING "thinking" +#define HUNGRY "hungry " +#define EATING "eating " + +//---------------------------------------------------------------------------- + +$define ${Shared::Table_ctor} +$define ${Shared::AO_Table} +$define ${AOs::Table} + + + diff --git a/examples/arm-cm/dpp_nucleo-c031c6/main.c b/examples/arm-cm/dpp_nucleo-c031c6/main.c new file mode 100644 index 00000000..cfcfaf07 --- /dev/null +++ b/examples/arm-cm/dpp_nucleo-c031c6/main.c @@ -0,0 +1,44 @@ +//============================================================================ +// APP example +// Last updated for version 7.3.0 +// Last updated on 2023-08-09 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. +// +// This program is open source software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Alternatively, this program may be distributed and modified under the +// terms of Quantum Leaps commercial licenses, which expressly supersede +// the GNU General Public License and are specifically designed for +// licensees interested in retaining the proprietary status of their code. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Contact information: +// +// +//============================================================================ +#include "qpc.h" // QP/C real-time embedded framework +#include "dpp.h" // DPP Application interface +#include "bsp.h" // Board Support Package + +//............................................................................ +int main() { + QF_init(); // initialize the framework and the underlying RT kernel + BSP_init(); // initialize the BSP + BSP_start(); // start the AOs/Threads + return QF_run(); // run the QF application +} diff --git a/examples/arm-cm/dpp_nucleo-c031c6/philo.c b/examples/arm-cm/dpp_nucleo-c031c6/philo.c new file mode 100644 index 00000000..eb6be531 --- /dev/null +++ b/examples/arm-cm/dpp_nucleo-c031c6/philo.c @@ -0,0 +1,255 @@ +//$file${.::philo.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// +// Model: dpp.qm +// File: ${.::philo.c} +// +// This code has been generated by QM 5.3.0 . +// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. +// +// SPDX-License-Identifier: GPL-3.0-or-later +// +// This generated code is open source software: you can redistribute it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation. +// +// This code is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// NOTE: +// Alternatively, this generated code may be distributed under the terms +// of Quantum Leaps commercial licenses, which expressly supersede the GNU +// General Public License and are specifically designed for licensees +// interested in retaining the proprietary status of their code. +// +// Contact information: +// +// +// +//$endhead${.::philo.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +#include "qpc.h" // QP/C real-time embedded framework +#include "dpp.h" // DPP Application interface +#include "bsp.h" // Board Support Package + +//$declare${AOs::Philo} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${AOs::Philo} .............................................................. +typedef struct Philo { +// protected: + QActive super; + +// private: + QTimeEvt timeEvt; + uint8_t id; + +// public: +} Philo; + +extern Philo Philo_inst[N_PHILO]; + +// protected: +static QState Philo_initial(Philo * const me, void const * const par); +static QState Philo_thinking(Philo * const me, QEvt const * const e); +static QState Philo_hungry(Philo * const me, QEvt const * const e); +static QState Philo_eating(Philo * const me, QEvt const * const e); +//$enddecl${AOs::Philo} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +//---------------------------------------------------------------------------- +Q_DEFINE_THIS_FILE + +// helper function to provide a randomized think time for Philos +static QTimeEvtCtr think_time(void); // prototype +static inline QTimeEvtCtr think_time(void) { + return (QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + + (BSP_TICKS_PER_SEC/2U)); +} + +// helper function to provide a randomized eat time for Philos +static QTimeEvtCtr eat_time(void); // prototype +static inline QTimeEvtCtr eat_time(void) { + return (QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + + BSP_TICKS_PER_SEC); +} +//---------------------------------------------------------------------------- + +//$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// Check for the minimum required QP version +#if (QP_VERSION < 730U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) +#error qpc version 7.3.0 or higher required +#endif +//$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +//$define${Shared::Philo_ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${Shared::Philo_ctor} ...................................................... +void Philo_ctor(uint_fast8_t const id) { + Philo * const me = &Philo_inst[id]; + QActive_ctor(&me->super, Q_STATE_CAST(&Philo_initial)); + QTimeEvt_ctorX(&me->timeEvt, &me->super, TIMEOUT_SIG, 0U), + me->id = (uint8_t)id; +} +//$enddef${Shared::Philo_ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +//$define${Shared::AO_Philo[N_PHILO]} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${Shared::AO_Philo[N_PHILO]} ............................................... +QActive * const AO_Philo[N_PHILO] = { + &Philo_inst[0].super, + &Philo_inst[1].super, + &Philo_inst[2].super, + &Philo_inst[3].super, + &Philo_inst[4].super +}; +//$enddef${Shared::AO_Philo[N_PHILO]} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +//$define${AOs::Philo} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${AOs::Philo} .............................................................. +Philo Philo_inst[N_PHILO]; + +//${AOs::Philo::SM} .......................................................... +static QState Philo_initial(Philo * const me, void const * const par) { + //${AOs::Philo::SM::initial} + Q_UNUSED_PAR(par); + + QS_OBJ_ARR_DICTIONARY(&Philo_inst[me->id], me->id); + QS_OBJ_ARR_DICTIONARY(&Philo_inst[me->id].timeEvt, me->id); + + QActive_subscribe(&me->super, EAT_SIG); + QActive_subscribe(&me->super, TEST_SIG); + + QS_FUN_DICTIONARY(&Philo_thinking); + QS_FUN_DICTIONARY(&Philo_hungry); + QS_FUN_DICTIONARY(&Philo_eating); + + return Q_TRAN(&Philo_thinking); +} + +//${AOs::Philo::SM::thinking} ................................................ +static QState Philo_thinking(Philo * const me, QEvt const * const e) { + QState status_; + switch (e->sig) { + //${AOs::Philo::SM::thinking} + case Q_ENTRY_SIG: { + QTimeEvt_armX(&me->timeEvt, think_time(), 0U); + status_ = Q_HANDLED(); + break; + } + //${AOs::Philo::SM::thinking} + case Q_EXIT_SIG: { + (void)QTimeEvt_disarm(&me->timeEvt); + status_ = Q_HANDLED(); + break; + } + //${AOs::Philo::SM::thinking::TIMEOUT} + case TIMEOUT_SIG: { + status_ = Q_TRAN(&Philo_hungry); + break; + } + //${AOs::Philo::SM::thinking::EAT, DONE} + case EAT_SIG: // intentionally fall through + case DONE_SIG: { + // EAT or DONE must be for other Philos than this one + Q_ASSERT(Q_EVT_CAST(TableEvt)->philoId != me->id); + status_ = Q_HANDLED(); + break; + } + //${AOs::Philo::SM::thinking::TEST} + case TEST_SIG: { + status_ = Q_HANDLED(); + break; + } + default: { + status_ = Q_SUPER(&QHsm_top); + break; + } + } + return status_; +} + +//${AOs::Philo::SM::hungry} .................................................. +static QState Philo_hungry(Philo * const me, QEvt const * const e) { + QState status_; + switch (e->sig) { + //${AOs::Philo::SM::hungry} + case Q_ENTRY_SIG: { + #ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, HUNGRY_SIG, me->id); + #else + TableEvt *pe = Q_NEW(TableEvt, HUNGRY_SIG); + pe->philoId = me->id; + #endif + QACTIVE_POST(AO_Table, &pe->super, &me->super); + status_ = Q_HANDLED(); + break; + } + //${AOs::Philo::SM::hungry::EAT} + case EAT_SIG: { + //${AOs::Philo::SM::hungry::EAT::[e->philoId==me->iid]} + if (Q_EVT_CAST(TableEvt)->philoId == me->id) { + status_ = Q_TRAN(&Philo_eating); + } + else { + status_ = Q_UNHANDLED(); + } + break; + } + //${AOs::Philo::SM::hungry::DONE} + case DONE_SIG: { + // DONE must be for other Philos than this one + Q_ASSERT(Q_EVT_CAST(TableEvt)->philoId != me->id); + status_ = Q_HANDLED(); + break; + } + default: { + status_ = Q_SUPER(&QHsm_top); + break; + } + } + return status_; +} + +//${AOs::Philo::SM::eating} .................................................. +static QState Philo_eating(Philo * const me, QEvt const * const e) { + QState status_; + switch (e->sig) { + //${AOs::Philo::SM::eating} + case Q_ENTRY_SIG: { + QTimeEvt_armX(&me->timeEvt, eat_time(), 0U); + status_ = Q_HANDLED(); + break; + } + //${AOs::Philo::SM::eating} + case Q_EXIT_SIG: { + (void)QTimeEvt_disarm(&me->timeEvt); + + #ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, DONE_SIG, me->id); + #else + TableEvt *pe = Q_NEW(TableEvt, DONE_SIG); + pe->philoId = me->id; + #endif + QACTIVE_PUBLISH(&pe->super, &me->super); + status_ = Q_HANDLED(); + break; + } + //${AOs::Philo::SM::eating::TIMEOUT} + case TIMEOUT_SIG: { + status_ = Q_TRAN(&Philo_thinking); + break; + } + //${AOs::Philo::SM::eating::EAT, DONE} + case EAT_SIG: // intentionally fall through + case DONE_SIG: { + // EAT or DONE must be for other Philos than this one + Q_ASSERT(Q_EVT_CAST(TableEvt)->philoId != me->id); + status_ = Q_HANDLED(); + break; + } + default: { + status_ = Q_SUPER(&QHsm_top); + break; + } + } + return status_; +} +//$enddef${AOs::Philo} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/examples/arm-cm/dpp_nucleo-c031c6/qk/armclang/README.txt b/examples/arm-cm/dpp_nucleo-c031c6/qk/armclang/README.txt new file mode 100644 index 00000000..946a6967 --- /dev/null +++ b/examples/arm-cm/dpp_nucleo-c031c6/qk/armclang/README.txt @@ -0,0 +1,74 @@ +About this Example +================== +This example demonstrates how to use the uVision IDE together with +the MDK-ARM toolchain. + +*** +NOTE: This example requires installing the following Software Pack +in the Keil uVision: Keil::STM32C0xx_DFP. +*** + +uVision Project File +==================== +The MDK-ARM uVision project file provided with this example uses +relative paths to the QP/C framework location (includes, port, and +libraries. These relative paths must be modified when the project +is moved to different relative location. + + +Adjusting Stack and Heap Sizes +============================== +The stack and heap sizes are determined in this project by the +command-line options for the ARM assembler (see the Asm tab in +the "Options for Target" dialog box in uVision). Specifically, +you should define symbols: Stack_Size=xxx Heap_Size=yyy, where +xxx represents a numerical value of stack size and yyy the +numberical value of the heap size. + + +Selecting QK Exception +====================== +The QK kernel needs a dedicated exception to return to the thread +context after preemption. The default is to use the NMI exception +for that purpose. However, in case NMI is needed for some other +purpose, the QK port allows you to select a any, otherwise unused +IRQ for that purpose. To choose a given IRQ, you need to define +the macros QK_USE_IRQ_NUM and QK_USE_IRQ_HANDLER. These macros can +be provided on the command-line to the compiler. + +For example, (see the vector table), you can define the QK IRQ +as follows: + +QK_USE_IRQ_HANDLER=Reserved31_IRQHandler +QK_USE_IRQ_NUM=31 + + +Startup Code +============ +The startup code for the STM32C0xx MCU used in this project is +located in the "3rd_party" folder in the following location: + +3rd_party\nucleo-c031c6\arm\startup_stm32c031xx.s + +The file startup_stm32c031xx.s provides a template of the recommended +startup for QP applications and should be easily customizable for other +ARM Cortex-M microcontrollers. + +The startup file typically does not need to be modified or adapted for +applications. It calls the assert_failed() function, which must be +defined in the application to customize it for the application-specific +error-handling policy. + + +Adjusting the CPU Clock Speed +============================= +The current setting is to run at 12MHz from the MSI (internal oscillator), +but the CPU clock speed can be modified. + +*** +NOTE: +The NUCLEO boards have a wide range of possible clock selections, depending +on the solder bridge configuration. Please see Chapter 5.7 "OSC clock" in +the STM32 NUCLEO Boards User Manual (ST document UM1724) for more information. +*** + diff --git a/examples/arm-cm/dpp_nucleo-c031c6/qk/armclang/dpp-qk.sct b/examples/arm-cm/dpp_nucleo-c031c6/qk/armclang/dpp-qk.sct new file mode 100644 index 00000000..ba687922 --- /dev/null +++ b/examples/arm-cm/dpp_nucleo-c031c6/qk/armclang/dpp-qk.sct @@ -0,0 +1,23 @@ +; ************************************************************* +; *** Scatter-Loading Description File generated by uVision *** +; +; Adapted by Quantum Leaps: +; added STACK as the first section in RW_STACK +; ************************************************************* + +LR_IROM1 0x08000000 0x00008000 { ; load region size_region + ER_IROM1 0x08000000 0x00008000 { ; load address = execution address + *.o (RESET, +First) + *(InRoot$$Sections) + .ANY (+RO) + .ANY (+XO) + } + + RW_STACK 0x20000000 { ; STACK area + * (STACK, +First) + } + RW_IRAM1 +0 (0x00003000 - 2048) { + .ANY (+RW +ZI) + } +} + diff --git a/examples/arm-cm/dpp_nucleo-c031c6/qk/armclang/dpp-qk.uvoptx b/examples/arm-cm/dpp_nucleo-c031c6/qk/armclang/dpp-qk.uvoptx new file mode 100644 index 00000000..096f8e0a --- /dev/null +++ b/examples/arm-cm/dpp_nucleo-c031c6/qk/armclang/dpp-qk.uvoptx @@ -0,0 +1,1039 @@ + + + + 1.0 + +
### uVision Project, (C) Keil Software
+ + + *.c + *.s*; *.src; *.a* + *.obj; *.o + *.lib + *.txt; *.h; *.inc; *.md + *.plm + *.cpp + 0 + + + + 0 + 0 + + + + dpp-dbg + 0x4 + ARM-ADS + + 12000000 + + 1 + 1 + 0 + 1 + 0 + + + 1 + 65535 + 0 + 0 + 0 + + + 79 + 66 + 8 + .\dbg\ + + + 1 + 1 + 1 + 0 + 1 + 1 + 0 + 1 + 0 + 0 + 0 + 0 + + + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + + + 1 + 0 + 1 + + 18 + + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + 0 + 1 + 1 + 0 + 0 + 1 + 0 + 0 + 6 + + + + + + + + + + + STLink\ST-LINKIII-KEIL_SWO.dll + + + + 0 + ST-LINKIII-KEIL_SWO + -U066BFF505153848667095842 -O206 -SF10000 -C0 -A0 -I0 -HNlocalhost -HP7184 -P1 -N00("ARM CoreSight SW-DP (ARM Core") -D00(0BC11477) -L00(0) -TO65554 -TC10000000 -TT10000000 -TP21 -TDS8007 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -FO7 -FD20000000 -FC1000 -FN1 -FF0STM32C0x_32.FLM -FS08000000 -FL08000 -FP0($$Device:STM32C031C6Tx$CMSIS\Flash\STM32C0x_32.FLM) + + + 0 + UL2CM3 + -U -O206 -S8 -C0 -P00 -N00("") -D00(00000000) -L00(0) -TO65554 -TC10000000 -TT10000000 -TP21 -TDS8007 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -FO7 -FD20000000 -FC1000 -FN1 -FF0STM32C0x_32.FLM -FS08000000 -FL08000 -FP0($$Device:STM32C031C6Tx$CMSIS\Flash\STM32C0x_32.FLM) + + + 0 + DLGUARM + (105=-1,-1,-1,-1,0) + + + 0 + ARMRTXEVENTFLAGS + -L70 -Z18 -C0 -M0 -T1 + + + 0 + DLGTARM + (1010=-1,-1,-1,-1,0)(1007=-1,-1,-1,-1,0)(1008=-1,-1,-1,-1,0)(1012=-1,-1,-1,-1,0)(1009=-1,-1,-1,-1,0) + + + 0 + ARMDBGFLAGS + + + + + + 0 + 0 + 336 + 1 +
134226654
+ 0 + 0 + 0 + 0 + 0 + 1 + ..\bsp.c + + \\dpp_qk\../bsp.c\336 +
+
+ + + 1 + 2 + 0x20000200 + 0 + + + + + 2 + 0 + 0x400 + 0 + + + + 0 + + + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + + + + 0 + 0 + 0 + + + + + + + + + + 1 + 0 + 0 + 2 + 10000000 + +
+
+ + + dpp-rel + 0x4 + ARM-ADS + + 12000000 + + 1 + 1 + 0 + 1 + 0 + + + 1 + 65535 + 0 + 0 + 0 + + + 79 + 66 + 8 + .\rel\ + + + 1 + 1 + 1 + 0 + 1 + 1 + 0 + 1 + 0 + 0 + 0 + 0 + + + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + + + 1 + 0 + 0 + + 18 + + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + 0 + 1 + 1 + 0 + 0 + 1 + 0 + 0 + 6 + + + + + + + + + + + STLink\ST-LINKIII-KEIL_SWO.dll + + + + 0 + UL2CM3 + UL2CM3(-S0 -C0 -P0 ) -FN1 -FC1000 -FD20000000 -FF0STM32C0x_32 -FL08000 -FS08000000 -FP0($$Device:STM32C031C6Tx$CMSIS\Flash\STM32C0x_32.FLM) + + + 0 + ST-LINKIII-KEIL_SWO + UL2CM3(-S0 -C0 -P0 ) -FN1 -FC1000 -FD20000000 -FF0STM32C0x_32 -FL08000 -FS08000000 -FP0($$Device:STM32C031C6Tx$CMSIS\Flash\STM32C0x_32.FLM) + + + 0 + DLGUARM + (105=-1,-1,-1,-1,0) + + + 0 + ARMRTXEVENTFLAGS + -L70 -Z18 -C0 -M0 -T1 + + + 0 + DLGTARM + (1010=-1,-1,-1,-1,0)(1007=-1,-1,-1,-1,0)(1008=-1,-1,-1,-1,0)(1009=-1,-1,-1,-1,0) + + + 0 + ARMDBGFLAGS + + + + + + + 1 + 2 + 0x20000200 + 0 + + + + + 2 + 0 + 0x400 + 0 + + + + 0 + + + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + + + + 0 + 0 + 0 + + + + + + + + + + 1 + 1 + 0 + 2 + 10000000 + + + + + + dpp-spy + 0x4 + ARM-ADS + + 12000000 + + 1 + 1 + 0 + 1 + 0 + + + 1 + 65535 + 0 + 0 + 0 + + + 79 + 66 + 8 + .\spy\ + + + 1 + 1 + 1 + 0 + 1 + 1 + 0 + 1 + 0 + 0 + 0 + 0 + + + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + + + 1 + 0 + 0 + + 18 + + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + 0 + 1 + 1 + 0 + 0 + 1 + 0 + 0 + 6 + + + + + + + + + + + STLink\ST-LINKIII-KEIL_SWO.dll + + + + 0 + UL2CM3 + UL2CM3(-S0 -C0 -P0 ) -FN1 -FC1000 -FD20000000 -FF0STM32C0x_32 -FL08000 -FS08000000 -FP0($$Device:STM32C031C6Tx$CMSIS\Flash\STM32C0x_32.FLM) + + + 0 + ST-LINKIII-KEIL_SWO + -U-O206 -O206 -SF10000 -C0 -A0 -I0 -HNlocalhost -HP7184 -P1 -N00("ARM CoreSight SW-DP (ARM Core") -D00(0BC11477) -L00(0) -TO131090 -TC10000000 -TT10000000 -TP21 -TDS8007 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -FO7 -FD20000000 -FC1000 -FN1 -FF0STM32C0x_32.FLM -FS08000000 -FL08000 -FP0($$Device:STM32C031C6Tx$CMSIS\Flash\STM32C0x_32.FLM) + + + 0 + DLGUARM + (105=-1,-1,-1,-1,0) + + + 0 + ARMRTXEVENTFLAGS + -L70 -Z18 -C0 -M0 -T1 + + + 0 + DLGTARM + (1010=-1,-1,-1,-1,0)(1007=-1,-1,-1,-1,0)(1008=-1,-1,-1,-1,0)(1012=-1,-1,-1,-1,0)(1009=-1,-1,-1,-1,0) + + + 0 + ARMDBGFLAGS + + + + + + + 1 + 2 + 0x20000200 + 0 + + + + + 2 + 0 + 0x400 + 0 + + + + 0 + + + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + + + + 0 + 0 + 0 + + + + + + + + + + + System Viewer\GPIOA + 35904 + + + System Viewer\USART2 + 35905 + + + + 1 + 0 + 0 + 2 + 10000000 + + + + + + Source Code + 1 + 0 + 0 + 0 + + 1 + 1 + 1 + 0 + 0 + 0 + ..\bsp.c + bsp.c + 0 + 0 + + + 1 + 2 + 5 + 0 + 0 + 0 + ..\..\bsp.h + bsp.h + 0 + 0 + + + 1 + 3 + 5 + 0 + 0 + 0 + ..\..\dpp.h + dpp.h + 0 + 0 + + + 1 + 4 + 1 + 0 + 0 + 0 + ..\..\philo.c + philo.c + 0 + 0 + + + 1 + 5 + 1 + 0 + 0 + 0 + ..\..\table.c + table.c + 0 + 0 + + + 1 + 6 + 1 + 0 + 0 + 0 + ..\..\main.c + main.c + 0 + 0 + + + + + nucleo-c031c6 + 1 + 0 + 0 + 0 + + 2 + 7 + 5 + 0 + 0 + 0 + ..\..\..\..\..\3rd_party\nucleo-c031c6\stm32c0xx.h + stm32c0xx.h + 0 + 0 + + + 2 + 8 + 5 + 0 + 0 + 0 + ..\..\..\..\..\3rd_party\nucleo-c031c6\stm32c031xx.h + stm32c031xx.h + 0 + 0 + + + 2 + 9 + 1 + 0 + 0 + 0 + ..\..\..\..\..\3rd_party\nucleo-c031c6\system_stm32c0xx.c + system_stm32c0xx.c + 0 + 0 + + + 2 + 10 + 2 + 0 + 0 + 0 + ..\..\..\..\..\3rd_party\nucleo-c031c6\arm\startup_stm32c031xx.s + startup_stm32c031xx.s + 0 + 0 + + + + + QP + 1 + 0 + 0 + 0 + + 3 + 11 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qf\qep_hsm.c + qep_hsm.c + 0 + 0 + + + 3 + 12 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qf\qep_msm.c + qep_msm.c + 0 + 0 + + + 3 + 13 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qf\qf_act.c + qf_act.c + 0 + 0 + + + 3 + 14 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qf\qf_actq.c + qf_actq.c + 0 + 0 + + + 3 + 15 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qf\qf_defer.c + qf_defer.c + 0 + 0 + + + 3 + 16 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qf\qf_dyn.c + qf_dyn.c + 0 + 0 + + + 3 + 17 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qf\qf_mem.c + qf_mem.c + 0 + 0 + + + 3 + 18 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qf\qf_ps.c + qf_ps.c + 0 + 0 + + + 3 + 19 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qf\qf_qact.c + qf_qact.c + 0 + 0 + + + 3 + 20 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qf\qf_qeq.c + qf_qeq.c + 0 + 0 + + + 3 + 21 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qf\qf_qmact.c + qf_qmact.c + 0 + 0 + + + 3 + 22 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qf\qf_time.c + qf_time.c + 0 + 0 + + + 3 + 23 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qk\qk.c + qk.c + 0 + 0 + + + + + QP_port + 1 + 0 + 0 + 0 + + 4 + 24 + 5 + 0 + 0 + 0 + ..\..\..\..\..\ports\arm-cm\qk\armclang\qs_port.h + qs_port.h + 0 + 0 + + + 4 + 25 + 1 + 0 + 0 + 0 + ..\..\..\..\..\ports\arm-cm\qk\armclang\qk_port.c + qk_port.c + 0 + 0 + + + + + QS + 1 + 0 + 0 + 0 + + 5 + 26 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qs\qs.c + qs.c + 0 + 0 + + + 5 + 27 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qs\qs_64bit.c + qs_64bit.c + 0 + 0 + + + 5 + 28 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qs\qs_fp.c + qs_fp.c + 0 + 0 + + + 5 + 29 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qs\qs_rx.c + qs_rx.c + 0 + 0 + + + 5 + 30 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qs\qstamp.c + qstamp.c + 0 + 0 + + + +
diff --git a/examples/arm-cm/dpp_nucleo-c031c6/qk/armclang/dpp-qk.uvprojx b/examples/arm-cm/dpp_nucleo-c031c6/qk/armclang/dpp-qk.uvprojx new file mode 100644 index 00000000..de254810 --- /dev/null +++ b/examples/arm-cm/dpp_nucleo-c031c6/qk/armclang/dpp-qk.uvprojx @@ -0,0 +1,1808 @@ + + + + 2.1 + +
### uVision Project, (C) Keil Software
+ + + + dpp-dbg + 0x4 + ARM-ADS + 6160000::V6.16::ARMCLANG + 1 + + + STM32C031C6Tx + STMicroelectronics + Keil.STM32C0xx_DFP.1.0.0 + https://www.keil.com/pack/ + IRAM(0x20000000,0x00003000) IROM(0x08000000,0x00008000) CPUTYPE("Cortex-M0+") CLOCK(12000000) ELITTLE + + + UL2CM3(-S0 -C0 -P0 -FD20000000 -FC1000 -FN1 -FF0STM32C0x_32 -FS08000000 -FL08000 -FP0($$Device:STM32C031C6Tx$CMSIS\Flash\STM32C0x_32.FLM)) + 0 + $$Device:STM32C031C6Tx$Drivers\CMSIS\Device\ST\STM32C0xx\Include\stm32c0xx.h + + + + + + + + + + $$Device:STM32C031C6Tx$CMSIS\SVD\STM32C031.svd + 0 + 0 + + + + + + + 0 + 0 + 0 + 0 + 1 + + .\dbg\ + dpp-qk + 1 + 0 + 0 + 1 + 1 + .\dbg\ + 1 + 0 + 0 + + 0 + 0 + + + 0 + 0 + 0 + 0 + + + 1 + 0 + cmd /c "del .\dbg\qstamp.o" + + 0 + 0 + 0 + 0 + + + 1 + 0 + fromelf --bin --output .\dbg\dpp-qk.bin .\dbg\dpp-qk.axf + + 0 + 0 + 0 + 0 + + 0 + + + + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 3 + + + 1 + + + SARMCM3.DLL + -REMAP-MPU + DARMCM1.DLL + -pCM0+ + SARMCM3.DLL + -MPU + TARMCM1.DLL + -pCM0+ + + + + 1 + 0 + 0 + 0 + 16 + + + + + 1 + 0 + 0 + 1 + 1 + 4096 + + 1 + BIN\UL2CM3.DLL + "" () + + + + + 0 + + + + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + 1 + 0 + 0 + 0 + 0 + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + "Cortex-M0+" + + 0 + 0 + 0 + 1 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 8 + 0 + 0 + 0 + 0 + 3 + 3 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 1 + 0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x20000000 + 0x3000 + + + 1 + 0x8000000 + 0x8000 + + + 0 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x8000000 + 0x8000 + + + 1 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x20000000 + 0x3000 + + + 0 + 0x0 + 0x0 + + + + + + 0 + 1 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 3 + 0 + 1 + 0 + 0 + 0 + 3 + 3 + 0 + 0 + 0 + 0 + 0 + + + QF_ON_CONTEXT_SW + + ..\..;..\..\..\..\..\include;..\..\..\..\..\ports\arm-cm\qk\armclang;..\..\..\..\..\3rd_party\CMSIS\Include;..\..\..\..\..\3rd_party\nucleo-c031c6 + + + + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 4 + + + Stack_Size=2048 Heap_Size=16 + + + + + + 0 + 0 + 0 + 0 + 1 + 0 + 0x00000000 + 0x20000000 + + .\dpp-qk.sct + + + --entry Reset_Handler + + + + + + + + Source Code + + + bsp.c + 1 + ..\bsp.c + + + bsp.h + 5 + ..\..\bsp.h + + + dpp.h + 5 + ..\..\dpp.h + + + philo.c + 1 + ..\..\philo.c + + + table.c + 1 + ..\..\table.c + + + main.c + 1 + ..\..\main.c + + + + + nucleo-c031c6 + + + stm32c0xx.h + 5 + ..\..\..\..\..\3rd_party\nucleo-c031c6\stm32c0xx.h + + + stm32c031xx.h + 5 + ..\..\..\..\..\3rd_party\nucleo-c031c6\stm32c031xx.h + + + system_stm32c0xx.c + 1 + ..\..\..\..\..\3rd_party\nucleo-c031c6\system_stm32c0xx.c + + + startup_stm32c031xx.s + 2 + ..\..\..\..\..\3rd_party\nucleo-c031c6\arm\startup_stm32c031xx.s + + + + + QP + + + qep_hsm.c + 1 + ..\..\..\..\..\src\qf\qep_hsm.c + + + qep_msm.c + 1 + ..\..\..\..\..\src\qf\qep_msm.c + + + qf_act.c + 1 + ..\..\..\..\..\src\qf\qf_act.c + + + qf_actq.c + 1 + ..\..\..\..\..\src\qf\qf_actq.c + + + qf_defer.c + 1 + ..\..\..\..\..\src\qf\qf_defer.c + + + qf_dyn.c + 1 + ..\..\..\..\..\src\qf\qf_dyn.c + + + qf_mem.c + 1 + ..\..\..\..\..\src\qf\qf_mem.c + + + qf_ps.c + 1 + ..\..\..\..\..\src\qf\qf_ps.c + + + qf_qact.c + 1 + ..\..\..\..\..\src\qf\qf_qact.c + + + qf_qeq.c + 1 + ..\..\..\..\..\src\qf\qf_qeq.c + + + qf_qmact.c + 1 + ..\..\..\..\..\src\qf\qf_qmact.c + + + qf_time.c + 1 + ..\..\..\..\..\src\qf\qf_time.c + + + qk.c + 1 + ..\..\..\..\..\src\qk\qk.c + + + + + QP_port + + + qs_port.h + 5 + ..\..\..\..\..\ports\arm-cm\qk\armclang\qs_port.h + + + qk_port.c + 1 + ..\..\..\..\..\ports\arm-cm\qk\armclang\qk_port.c + + + + + QS + + + 0 + 0 + 0 + 0 + 0 + 0 + 2 + 2 + 2 + 2 + 11 + + + 1 + + + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 0 + 0 + 0 + 0 + 2 + + + + + + + + + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + + + + + + + + + + + + qs.c + 1 + ..\..\..\..\..\src\qs\qs.c + + + qs_64bit.c + 1 + ..\..\..\..\..\src\qs\qs_64bit.c + + + qs_fp.c + 1 + ..\..\..\..\..\src\qs\qs_fp.c + + + qs_rx.c + 1 + ..\..\..\..\..\src\qs\qs_rx.c + + + qstamp.c + 1 + ..\..\..\..\..\src\qs\qstamp.c + + + + + + + dpp-rel + 0x4 + ARM-ADS + 6160000::V6.16::ARMCLANG + 1 + + + STM32C031C6Tx + STMicroelectronics + Keil.STM32C0xx_DFP.1.0.0 + https://www.keil.com/pack/ + IRAM(0x20000000,0x00003000) IROM(0x08000000,0x00008000) CPUTYPE("Cortex-M0+") CLOCK(12000000) ELITTLE + + + UL2CM3(-S0 -C0 -P0 -FD20000000 -FC1000 -FN1 -FF0STM32C0x_32 -FS08000000 -FL08000 -FP0($$Device:STM32C031C6Tx$CMSIS\Flash\STM32C0x_32.FLM)) + 0 + $$Device:STM32C031C6Tx$Drivers\CMSIS\Device\ST\STM32C0xx\Include\stm32c0xx.h + + + + + + + + + + $$Device:STM32C031C6Tx$CMSIS\SVD\STM32C031.svd + 0 + 0 + + + + + + + 0 + 0 + 0 + 0 + 1 + + .\rel\ + dpp-qk + 1 + 0 + 0 + 0 + 0 + .\rel\ + 1 + 0 + 0 + + 0 + 0 + + + 0 + 0 + 0 + 0 + + + 1 + 0 + cmd /c "del .\rel\qstamp.o" + + 0 + 0 + 0 + 0 + + + 1 + 0 + fromelf --bin --output .\rel\dpp-qk.bin .\rel\dpp-qk.axf + + 0 + 0 + 0 + 0 + + 0 + + + + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 3 + + + 1 + + + SARMCM3.DLL + -REMAP-MPU + DARMCM1.DLL + -pCM0+ + SARMCM3.DLL + -MPU + TARMCM1.DLL + -pCM0+ + + + + 1 + 0 + 0 + 0 + 16 + + + + + 1 + 0 + 0 + 1 + 1 + 4097 + + 1 + BIN\UL2CM3.DLL + + + + + + 0 + + + + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + 1 + 0 + 0 + 0 + 0 + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + "Cortex-M0+" + + 0 + 0 + 0 + 1 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 8 + 0 + 0 + 0 + 0 + 3 + 3 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 1 + 0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x20000000 + 0x3000 + + + 1 + 0x8000000 + 0x8000 + + + 0 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x8000000 + 0x8000 + + + 1 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x20000000 + 0x3000 + + + 0 + 0x0 + 0x0 + + + + + + 0 + 6 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 3 + 0 + 1 + 0 + 0 + 0 + 3 + 3 + 0 + 0 + 0 + 0 + 0 + + + NDEBUG,QF_ON_CONTEXT_SW + + ..\..;..\..\..\..\..\include;..\..\..\..\..\ports\arm-cm\qk\armclang;..\..\..\..\..\3rd_party\CMSIS\Include;..\..\..\..\..\3rd_party\nucleo-c031c6 + + + + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 4 + + + Stack_Size=2048 Heap_Size=16 + + + + + + 0 + 0 + 0 + 0 + 1 + 0 + 0x00000000 + 0x20000000 + + .\dpp-qk.sct + + + --entry Reset_Handler + + + + + + + + Source Code + + + bsp.c + 1 + ..\bsp.c + + + bsp.h + 5 + ..\..\bsp.h + + + dpp.h + 5 + ..\..\dpp.h + + + philo.c + 1 + ..\..\philo.c + + + table.c + 1 + ..\..\table.c + + + main.c + 1 + ..\..\main.c + + + + + nucleo-c031c6 + + + stm32c0xx.h + 5 + ..\..\..\..\..\3rd_party\nucleo-c031c6\stm32c0xx.h + + + stm32c031xx.h + 5 + ..\..\..\..\..\3rd_party\nucleo-c031c6\stm32c031xx.h + + + system_stm32c0xx.c + 1 + ..\..\..\..\..\3rd_party\nucleo-c031c6\system_stm32c0xx.c + + + startup_stm32c031xx.s + 2 + ..\..\..\..\..\3rd_party\nucleo-c031c6\arm\startup_stm32c031xx.s + + + + + QP + + + qep_hsm.c + 1 + ..\..\..\..\..\src\qf\qep_hsm.c + + + qep_msm.c + 1 + ..\..\..\..\..\src\qf\qep_msm.c + + + qf_act.c + 1 + ..\..\..\..\..\src\qf\qf_act.c + + + qf_actq.c + 1 + ..\..\..\..\..\src\qf\qf_actq.c + + + qf_defer.c + 1 + ..\..\..\..\..\src\qf\qf_defer.c + + + qf_dyn.c + 1 + ..\..\..\..\..\src\qf\qf_dyn.c + + + qf_mem.c + 1 + ..\..\..\..\..\src\qf\qf_mem.c + + + qf_ps.c + 1 + ..\..\..\..\..\src\qf\qf_ps.c + + + qf_qact.c + 1 + ..\..\..\..\..\src\qf\qf_qact.c + + + qf_qeq.c + 1 + ..\..\..\..\..\src\qf\qf_qeq.c + + + qf_qmact.c + 1 + ..\..\..\..\..\src\qf\qf_qmact.c + + + qf_time.c + 1 + ..\..\..\..\..\src\qf\qf_time.c + + + qk.c + 1 + ..\..\..\..\..\src\qk\qk.c + + + + + QP_port + + + qs_port.h + 5 + ..\..\..\..\..\ports\arm-cm\qk\armclang\qs_port.h + + + qk_port.c + 1 + ..\..\..\..\..\ports\arm-cm\qk\armclang\qk_port.c + + + + + QS + + + 0 + 0 + 0 + 0 + 0 + 0 + 2 + 2 + 2 + 2 + 11 + + + 1 + + + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 0 + 0 + 0 + 0 + 2 + + + + + + + + + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + + + + + + + + + + + + qs.c + 1 + ..\..\..\..\..\src\qs\qs.c + + + qs_64bit.c + 1 + ..\..\..\..\..\src\qs\qs_64bit.c + + + qs_fp.c + 1 + ..\..\..\..\..\src\qs\qs_fp.c + + + qs_rx.c + 1 + ..\..\..\..\..\src\qs\qs_rx.c + + + qstamp.c + 1 + ..\..\..\..\..\src\qs\qstamp.c + + + + + + + dpp-spy + 0x4 + ARM-ADS + 6160000::V6.16::ARMCLANG + 1 + + + STM32C031C6Tx + STMicroelectronics + Keil.STM32C0xx_DFP.1.0.0 + https://www.keil.com/pack/ + IRAM(0x20000000,0x00003000) IROM(0x08000000,0x00008000) CPUTYPE("Cortex-M0+") CLOCK(12000000) ELITTLE + + + UL2CM3(-S0 -C0 -P0 -FD20000000 -FC1000 -FN1 -FF0STM32C0x_32 -FS08000000 -FL08000 -FP0($$Device:STM32C031C6Tx$CMSIS\Flash\STM32C0x_32.FLM)) + 0 + $$Device:STM32C031C6Tx$Drivers\CMSIS\Device\ST\STM32C0xx\Include\stm32c0xx.h + + + + + + + + + + $$Device:STM32C031C6Tx$CMSIS\SVD\STM32C031.svd + 0 + 0 + + + + + + + 0 + 0 + 0 + 0 + 1 + + .\spy\ + dpp-qk + 1 + 0 + 0 + 1 + 1 + .\spy\ + 1 + 0 + 0 + + 0 + 0 + + + 0 + 0 + 0 + 0 + + + 1 + 0 + cmd /c "del .\spy\qstamp.o" + + 0 + 0 + 0 + 0 + + + 1 + 0 + fromelf --bin --output .\spy\dpp-qk.bin .\spy\dpp-qk.axf + + 0 + 0 + 0 + 0 + + 0 + + + + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 3 + + + 1 + + + SARMCM3.DLL + -REMAP-MPU + DARMCM1.DLL + -pCM0+ + SARMCM3.DLL + -MPU + TARMCM1.DLL + -pCM0+ + + + + 1 + 0 + 0 + 0 + 16 + + + + + 1 + 0 + 0 + 1 + 1 + 4096 + + 1 + BIN\UL2CM3.DLL + + + + + + 0 + + + + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + 1 + 0 + 0 + 0 + 0 + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + "Cortex-M0+" + + 0 + 0 + 0 + 1 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 8 + 0 + 0 + 0 + 0 + 3 + 3 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 1 + 0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x20000000 + 0x3000 + + + 1 + 0x8000000 + 0x8000 + + + 0 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x8000000 + 0x8000 + + + 1 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x20000000 + 0x3000 + + + 0 + 0x0 + 0x0 + + + + + + 0 + 2 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 3 + 0 + 1 + 0 + 0 + 0 + 3 + 3 + 0 + 0 + 0 + 0 + 0 + + + Q_SPY,QF_ON_CONTEXT_SW + + ..\..;..\..\..\..\..\include;..\..\..\..\..\ports\arm-cm\qk\armclang;..\..\..\..\..\3rd_party\CMSIS\Include;..\..\..\..\..\3rd_party\nucleo-c031c6 + + + + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 4 + + + Stack_Size=2048 Heap_Size=16 + + + + + + 0 + 0 + 0 + 0 + 1 + 0 + 0x00000000 + 0x20000000 + + .\dpp-qk.sct + + + --entry Reset_Handler + + + + + + + + Source Code + + + bsp.c + 1 + ..\bsp.c + + + bsp.h + 5 + ..\..\bsp.h + + + dpp.h + 5 + ..\..\dpp.h + + + philo.c + 1 + ..\..\philo.c + + + table.c + 1 + ..\..\table.c + + + main.c + 1 + ..\..\main.c + + + + + nucleo-c031c6 + + + stm32c0xx.h + 5 + ..\..\..\..\..\3rd_party\nucleo-c031c6\stm32c0xx.h + + + stm32c031xx.h + 5 + ..\..\..\..\..\3rd_party\nucleo-c031c6\stm32c031xx.h + + + system_stm32c0xx.c + 1 + ..\..\..\..\..\3rd_party\nucleo-c031c6\system_stm32c0xx.c + + + startup_stm32c031xx.s + 2 + ..\..\..\..\..\3rd_party\nucleo-c031c6\arm\startup_stm32c031xx.s + + + + + QP + + + qep_hsm.c + 1 + ..\..\..\..\..\src\qf\qep_hsm.c + + + qep_msm.c + 1 + ..\..\..\..\..\src\qf\qep_msm.c + + + qf_act.c + 1 + ..\..\..\..\..\src\qf\qf_act.c + + + qf_actq.c + 1 + ..\..\..\..\..\src\qf\qf_actq.c + + + qf_defer.c + 1 + ..\..\..\..\..\src\qf\qf_defer.c + + + qf_dyn.c + 1 + ..\..\..\..\..\src\qf\qf_dyn.c + + + qf_mem.c + 1 + ..\..\..\..\..\src\qf\qf_mem.c + + + qf_ps.c + 1 + ..\..\..\..\..\src\qf\qf_ps.c + + + qf_qact.c + 1 + ..\..\..\..\..\src\qf\qf_qact.c + + + qf_qeq.c + 1 + ..\..\..\..\..\src\qf\qf_qeq.c + + + qf_qmact.c + 1 + ..\..\..\..\..\src\qf\qf_qmact.c + + + qf_time.c + 1 + ..\..\..\..\..\src\qf\qf_time.c + + + qk.c + 1 + ..\..\..\..\..\src\qk\qk.c + + + + + QP_port + + + qs_port.h + 5 + ..\..\..\..\..\ports\arm-cm\qk\armclang\qs_port.h + + + qk_port.c + 1 + ..\..\..\..\..\ports\arm-cm\qk\armclang\qk_port.c + + + + + QS + + + qs.c + 1 + ..\..\..\..\..\src\qs\qs.c + + + qs_64bit.c + 1 + ..\..\..\..\..\src\qs\qs_64bit.c + + + qs_fp.c + 1 + ..\..\..\..\..\src\qs\qs_fp.c + + + qs_rx.c + 1 + ..\..\..\..\..\src\qs\qs_rx.c + + + qstamp.c + 1 + ..\..\..\..\..\src\qs\qstamp.c + + + + + + + + + + + + + +
diff --git a/examples/arm-cm/dpp_nucleo-c031c6/qk/bsp.c b/examples/arm-cm/dpp_nucleo-c031c6/qk/bsp.c new file mode 100644 index 00000000..4840830b --- /dev/null +++ b/examples/arm-cm/dpp_nucleo-c031c6/qk/bsp.c @@ -0,0 +1,535 @@ +//============================================================================ +// Product: DPP example, NUCLEO-C031C6 board, QK kernel +// Last updated for version 7.3.0 +// Last updated on 2023-08-15 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. +// +// This program is open source software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Alternatively, this program may be distributed and modified under the +// terms of Quantum Leaps commercial licenses, which expressly supersede +// the GNU General Public License and are specifically designed for +// licensees interested in retaining the proprietary status of their code. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Contact information: +// +// +//============================================================================ +#include "qpc.h" // QP/C real-time embedded framework +#include "dpp.h" // DPP Application interface +#include "bsp.h" // Board Support Package + +#include "stm32c0xx.h" // CMSIS-compliant header file for the MCU used +// add other drivers if necessary... + +Q_DEFINE_THIS_FILE // define the name of this file for assertions + +// Local-scope defines ----------------------------------------------------- +// LED pins available on the board (just one user LED LD4--Green on PA.5) +#define LD4_PIN 5U + +// Button pins available on the board (just one user Button B1 on PC.13) +#define B1_PIN 13U + +static uint32_t l_rndSeed; + +#ifdef Q_SPY + + QSTimeCtr QS_tickTime_; + QSTimeCtr QS_tickPeriod_; + + // QSpy source IDs + static QSpyId const l_SysTick_Handler = { 0U }; + + enum AppRecords { // application-specific trace records + PHILO_STAT = QS_USER, + PAUSED_STAT, + CONTEXT_SW, + }; + +#endif + +//============================================================================ +// Error handler and ISRs... + +Q_NORETURN Q_onError(char const * const module, int_t const id) { + // NOTE: this implementation of the assertion handler is intended only + // for debugging and MUST be changed for deployment of the application + // (assuming that you ship your production code with assertions enabled). + Q_UNUSED_PAR(module); + Q_UNUSED_PAR(id); + QS_ASSERTION(module, id, 10000U); + +#ifndef NDEBUG + // light up the user LED + GPIOA->BSRR = (1U << LD4_PIN); // turn LED on + // for debugging, hang on in an endless loop... + for (;;) { + } +#endif + + NVIC_SystemReset(); +} +//............................................................................ +void assert_failed(char const * const module, int_t const id); // prototype +void assert_failed(char const * const module, int_t const id) { + Q_onError(module, id); +} + +// ISRs used in the application ============================================ + +void SysTick_Handler(void); // prototype +void SysTick_Handler(void) { + QK_ISR_ENTRY(); // inform QK about entering an ISR + + QTIMEEVT_TICK_X(0U, &l_SysTick_Handler); // time events at rate 0 + + // Perform the debouncing of buttons. The algorithm for debouncing + // adapted from the book "Embedded Systems Dictionary" by Jack Ganssle + // and Michael Barr, page 71. + static struct { + uint32_t depressed; + uint32_t previous; + } buttons = { 0U, 0U }; + + uint32_t current = ~GPIOC->IDR; // read Port C with state of Button B1 + uint32_t tmp = buttons.depressed; // save the depressed buttons + buttons.depressed |= (buttons.previous & current); // set depressed + buttons.depressed &= (buttons.previous | current); // clear released + buttons.previous = current; // update the history + tmp ^= buttons.depressed; // changed debounced depressed + current = buttons.depressed; + + if ((tmp & (1U << B1_PIN)) != 0U) { // debounced B1 state changed? + if ((current & (1U << B1_PIN)) != 0U) { // is B1 depressed? + static QEvt const pauseEvt = QEVT_INITIALIZER(PAUSE_SIG); + QACTIVE_PUBLISH(&pauseEvt, &l_SysTick_Handler); + } + else { // the button is released + static QEvt const serveEvt = QEVT_INITIALIZER(SERVE_SIG); + QACTIVE_PUBLISH(&serveEvt, &l_SysTick_Handler); + } + } + +#ifdef Q_SPY + tmp = SysTick->CTRL; // clear CTRL_COUNTFLAG + QS_tickTime_ += QS_tickPeriod_; // account for the clock rollover +#endif + + QK_ISR_EXIT(); // inform QK about exiting an ISR +} +//............................................................................ +// interrupt handler for testing preemptions in QK +void EXTI0_1_IRQHandler(void); // prototype +void EXTI0_1_IRQHandler(void) { + QK_ISR_ENTRY(); // inform QK about entering an ISR + + static QEvt const testEvt = QEVT_INITIALIZER(TEST_SIG); + QACTIVE_POST(AO_Table, &testEvt, (void *)0); + + QK_ISR_EXIT(); // inform QK about exiting an ISR +} + +//............................................................................ +#ifdef Q_SPY +// ISR for receiving bytes from the QSPY Back-End +// NOTE: This ISR is "QF-unaware" meaning that it does not interact with +// the QF/QK and is not disabled. Such ISRs don't need to call +// QK_ISR_ENTRY/QK_ISR_EXIT and they cannot post or publish events. + +void USART2_IRQHandler(void); // prototype +void USART2_IRQHandler(void) { // used in QS-RX (kernel UNAWARE interrutp) + // is RX register NOT empty? + if ((USART2->ISR & (1U << 5)) != 0) { + uint32_t b = USART2->RDR; + QS_RX_PUT(b); + } + + QK_ARM_ERRATUM_838869(); +} +#endif // Q_SPY + +//............................................................................ +#ifdef QF_ON_CONTEXT_SW +// NOTE: the context-switch callback is called with interrupts DISABLED +void QF_onContextSw(QActive *prev, QActive *next) { + QS_BEGIN_INCRIT(CONTEXT_SW, 0U) // in critical section! + QS_OBJ(prev); + QS_OBJ(next); + QS_END_INCRIT() +} +#endif // QF_ON_CONTEXT_SW + +//============================================================================ +// BSP functions... + +void BSP_init(void) { + // Configure the MPU to prevent NULL-pointer dereferencing ... + MPU->RBAR = 0x0U // base address (NULL) + | MPU_RBAR_VALID_Msk // valid region + | (MPU_RBAR_REGION_Msk & 7U); // region #7 + MPU->RASR = (7U << MPU_RASR_SIZE_Pos) // 2^(7+1) region + | (0x0U << MPU_RASR_AP_Pos) // no-access region + | MPU_RASR_ENABLE_Msk; // region enable + MPU->CTRL = MPU_CTRL_PRIVDEFENA_Msk // enable background region + | MPU_CTRL_ENABLE_Msk; // enable the MPU + __ISB(); + __DSB(); + + // NOTE: SystemInit() has been already called from the startup code + // but SystemCoreClock needs to be updated + SystemCoreClockUpdate(); + + // enable GPIOA clock port for the LED LD4 + RCC->IOPENR |= (1U << 0U); + + // set all used GPIOA pins as push-pull output, no pull-up, pull-down + GPIOA->MODER &= ~(3U << 2U*LD4_PIN); + GPIOA->MODER |= (1U << 2U*LD4_PIN); + GPIOA->OTYPER &= ~(1U << LD4_PIN); + GPIOA->OSPEEDR &= ~(3U << 2U*LD4_PIN); + GPIOA->OSPEEDR |= (1U << 2U*LD4_PIN); + GPIOA->PUPDR &= ~(3U << 2U*LD4_PIN); + + // enable GPIOC clock port for the Button B1 + RCC->IOPENR |= (1U << 2U); + + // configure Button B1 pin on GPIOC as input, no pull-up, pull-down + GPIOC->MODER &= ~(3U << 2U*B1_PIN); + GPIOC->PUPDR &= ~(3U << 2U*B1_PIN); + + BSP_randomSeed(1234U); // seed the random number generator + + // initialize the QS software tracing... + if (!QS_INIT((void *)0)) { + Q_ERROR(); + } + + // dictionaries... + QS_OBJ_DICTIONARY(&l_SysTick_Handler); + QS_USR_DICTIONARY(PHILO_STAT); + QS_USR_DICTIONARY(PAUSED_STAT); + QS_USR_DICTIONARY(CONTEXT_SW); + + QS_ONLY(produce_sig_dict()); + + // setup the QS filters... + QS_GLB_FILTER(QS_ALL_RECORDS); // all records + QS_GLB_FILTER(-QS_QF_TICK); // exclude the clock tick +} +//............................................................................ +void BSP_start(void) { + // initialize event pools + static QF_MPOOL_EL(TableEvt) smlPoolSto[2*N_PHILO]; + QF_poolInit(smlPoolSto, sizeof(smlPoolSto), sizeof(smlPoolSto[0])); + + // initialize publish-subscribe + static QSubscrList subscrSto[MAX_PUB_SIG]; + QActive_psInit(subscrSto, Q_DIM(subscrSto)); + + // instantiate and start AOs/threads... + + static QEvt const *philoQueueSto[N_PHILO][10]; + for (uint8_t n = 0U; n < N_PHILO; ++n) { + Philo_ctor(n); + QACTIVE_START(AO_Philo[n], + + // NOTE: set the preemption-threshold of all Philos to + // the same level, so that they cannot preempt each other. + Q_PRIO(n + 3U, N_PHILO + 2U), // QF-prio/pre-thre. + + philoQueueSto[n], // event queue storage + Q_DIM(philoQueueSto[n]), // queue length [events] + (void *)0, 0U, // no stack storage + (void *)0); // no initialization param + } + + static QEvt const *tableQueueSto[N_PHILO]; + Table_ctor(); + QACTIVE_START(AO_Table, + N_PHILO + 7U, // QP prio. of the AO + tableQueueSto, // event queue storage + Q_DIM(tableQueueSto), // queue length [events] + (void *)0, 0U, // no stack storage + (void *)0); // no initialization param +} +//............................................................................ +void BSP_displayPhilStat(uint8_t n, char const *stat) { + Q_UNUSED_PAR(n); + + if (stat[0] == 'e') { + GPIOA->BSRR = (1U << LD4_PIN); // turn LED on + } + else { + GPIOA->BSRR = (1U << (LD4_PIN + 16U)); // turn LED off + } + + // app-specific trace record... + QS_BEGIN_ID(PHILO_STAT, AO_Table->prio) + QS_U8(1, n); // Philosopher number + QS_STR(stat); // Philosopher status + QS_END() +} +//............................................................................ +void BSP_displayPaused(uint8_t const paused) { + // not enough LEDs to implement this feature + if (paused != 0U) { + //GPIOA->BSRR = (1U << LD4_PIN); // turn LED[n] on + } + else { + //GPIOA->BSRR = (1U << (LD4_PIN + 16U)); // turn LED[n] off + } + + // application-specific trace record + QS_BEGIN_ID(PAUSED_STAT, AO_Table->prio) + QS_U8(1, paused); // Paused status + QS_END() +} +//............................................................................ +void BSP_randomSeed(uint32_t seed) { + l_rndSeed = seed; +} +//............................................................................ +uint32_t BSP_random(void) { // a very cheap pseudo-random-number generator + + QSchedStatus lockStat = QK_schedLock(N_PHILO); // N_PHILO prio. ceiling + // "Super-Duper" Linear Congruential Generator (LCG) + // LCG(2^32, 3*7*11*13*23, 0, seed) + // + uint32_t rnd = l_rndSeed * (3U*7U*11U*13U*23U); + l_rndSeed = rnd; // set for the next time + QK_schedUnlock(lockStat); + + return (rnd >> 8U); +} +//............................................................................ +void BSP_ledOn(void) { + GPIOA->BSRR = (1U << LD4_PIN); // turn LED on +} +//............................................................................ +void BSP_ledOff(void) { + GPIOA->BSRR = (1U << (LD4_PIN + 16U)); // turn LED off +} +//............................................................................ +void BSP_terminate(int16_t result) { + Q_UNUSED_PAR(result); +} + +//============================================================================ +// QF callbacks... +void QF_onStartup(void) { + // set up the SysTick timer to fire at BSP_TICKS_PER_SEC rate + SysTick_Config(SystemCoreClock / BSP_TICKS_PER_SEC); + + // assign all priority bits for preemption-prio. and none to sub-prio. + // NOTE: this might have been changed by STM32Cube. + NVIC_SetPriorityGrouping(0U); + + // set priorities of ALL ISRs used in the system, see NOTE1 + NVIC_SetPriority(USART2_IRQn, 0U); // kernel UNAWARE interrupt + NVIC_SetPriority(EXTI0_1_IRQn, QF_AWARE_ISR_CMSIS_PRI + 0U); + NVIC_SetPriority(SysTick_IRQn, QF_AWARE_ISR_CMSIS_PRI + 1U); + // ... + + // enable IRQs... + NVIC_EnableIRQ(EXTI0_1_IRQn); + +#ifdef Q_SPY + NVIC_EnableIRQ(USART2_IRQn); // UART2 interrupt used for QS-RX +#endif +} +//............................................................................ +void QF_onCleanup(void) { +} +//............................................................................ +void QK_onIdle(void) { + // toggle an LED on and then off (not enough LEDs, see NOTE2) + //QF_INT_DISABLE(); + //GPIOA->BSRR = (1U << LD4_PIN); // turn LED[n] on + //GPIOA->BSRR = (1U << (LD4_PIN + 16U)); // turn LED[n] off + //QF_INT_ENABLE(); + +#ifdef Q_SPY + QF_INT_DISABLE(); + QS_rxParse(); // parse all the received bytes + QF_INT_ENABLE(); + + if ((USART2->ISR & (1U << 7U)) != 0U) { // TXE empty? + QF_INT_DISABLE(); + uint16_t b = QS_getByte(); + QF_INT_ENABLE(); + + if (b != QS_EOD) { // not End-Of-Data? + USART2->TDR = b; // put into the DR register + } + } +#elif defined NDEBUG + // Put the CPU and peripherals to the low-power mode. + // you might need to customize the clock management for your application, + // see the datasheet for your particular Cortex-M MCU. + // + // !!!CAUTION!!! + // The WFI instruction stops the CPU clock, which unfortunately disables + // the JTAG port, so the ST-Link debugger can no longer connect to the + // board. For that reason, the call to __WFI() has to be used with CAUTION. + // + // NOTE: If you find your board "frozen" like this, strap BOOT0 to VDD and + // reset the board, then connect with ST-Link Utilities and erase the part. + // The trick with BOOT(0) is it gets the part to run the System Loader + // instead of your broken code. When done disconnect BOOT0, and start over. + // + //__WFI(); // Wait-For-Interrupt +#endif +} + +//============================================================================ +// QS callbacks... +#ifdef Q_SPY + +//............................................................................ +static uint16_t const UARTPrescTable[12] = { + 1U, 2U, 4U, 6U, 8U, 10U, 12U, 16U, 32U, 64U, 128U, 256U +}; + +#define UART_DIV_SAMPLING16(__PCLK__, __BAUD__, __CLOCKPRESCALER__) \ + ((((__PCLK__)/UARTPrescTable[(__CLOCKPRESCALER__)]) \ + + ((__BAUD__)/2U)) / (__BAUD__)) + +#define UART_PRESCALER_DIV1 0U + +// USART2 pins PA.2 and PA.3 +#define USART2_TX_PIN 2U +#define USART2_RX_PIN 3U + +//............................................................................ +uint8_t QS_onStartup(void const *arg) { + Q_UNUSED_PAR(arg); + + static uint8_t qsTxBuf[2*1024]; // buffer for QS-TX channel + QS_initBuf(qsTxBuf, sizeof(qsTxBuf)); + + static uint8_t qsRxBuf[100]; // buffer for QS-RX channel + QS_rxInitBuf(qsRxBuf, sizeof(qsRxBuf)); + + // enable peripheral clock for USART2 + RCC->IOPENR |= ( 1U << 0U); // Enable GPIOA clock for USART pins + RCC->APBENR1 |= ( 1U << 17U); // Enable USART#2 clock + + // Configure PA to USART2_RX, PA to USART2_TX + GPIOA->AFR[0] &= ~((15U << 4U*USART2_RX_PIN) | (15U << 4U*USART2_TX_PIN)); + GPIOA->AFR[0] |= (( 1U << 4U*USART2_RX_PIN) | ( 1U << 4U*USART2_TX_PIN)); + GPIOA->MODER &= ~(( 3U << 2U*USART2_RX_PIN) | ( 3U << 2U*USART2_TX_PIN)); + GPIOA->MODER |= (( 2U << 2U*USART2_RX_PIN) | ( 2U << 2U*USART2_TX_PIN)); + + // baud rate + USART2->BRR = UART_DIV_SAMPLING16( + SystemCoreClock, 115200U, UART_PRESCALER_DIV1); + USART2->CR3 = 0x0000U | // no flow control + (1U << 12U); // disable overrun detection (OVRDIS) + USART2->CR2 = 0x0000U; // 1 stop bit + USART2->CR1 = ((1U << 2U) | // enable RX + (1U << 3U) | // enable TX + (1U << 5U) | // enable RX interrupt + (0U << 12U) | // 8 data bits + (0U << 28U) | // 8 data bits + (1U << 0U)); // enable USART + + QS_tickPeriod_ = SystemCoreClock / BSP_TICKS_PER_SEC; + QS_tickTime_ = QS_tickPeriod_; // to start the timestamp at zero + + return 1U; // return success +} +//............................................................................ +void QS_onCleanup(void) { +} +//............................................................................ +QSTimeCtr QS_onGetTime(void) { // NOTE: invoked with interrupts DISABLED + if ((SysTick->CTRL & 0x00010000U) == 0U) { // not set? + return QS_tickTime_ - (QSTimeCtr)SysTick->VAL; + } + else { // the rollover occured, but the SysTick_ISR did not run yet + return QS_tickTime_ + QS_tickPeriod_ - (QSTimeCtr)SysTick->VAL; + } +} +//............................................................................ +void QS_onFlush(void) { + for (;;) { + QF_INT_DISABLE(); + uint16_t b = QS_getByte(); + if (b != QS_EOD) { + while ((USART2->ISR & (1U << 7U)) == 0U) { // while TXE not empty + QF_INT_ENABLE(); + QF_CRIT_EXIT_NOP(); + + QF_INT_DISABLE(); + } + USART2->TDR = b; + QF_INT_ENABLE(); + } + else { + QF_INT_ENABLE(); + break; + } + } +} +//............................................................................ +//! callback function to reset the target (to be implemented in the BSP) +void QS_onReset(void) { + NVIC_SystemReset(); +} +//............................................................................ +// callback function to execute a user command +void QS_onCommand(uint8_t cmdId, + uint32_t param1, uint32_t param2, uint32_t param3) +{ + Q_UNUSED_PAR(cmdId); + Q_UNUSED_PAR(param1); + Q_UNUSED_PAR(param2); + Q_UNUSED_PAR(param3); +} + +#endif // Q_SPY +//---------------------------------------------------------------------------- + +//============================================================================ +// NOTE1: +// The QF_AWARE_ISR_CMSIS_PRI constant from the QF port specifies the highest +// ISR priority that is disabled by the QF framework. The value is suitable +// for the NVIC_SetPriority() CMSIS function. +// +// Only ISRs prioritized at or below the QF_AWARE_ISR_CMSIS_PRI level (i.e., +// with the numerical values of priorities equal or higher than +// QF_AWARE_ISR_CMSIS_PRI) are allowed to call the QK_ISR_ENTRY/ +// QK_ISR_ENTRY macros or any other QF/QK services. These ISRs are +// "QF-aware". +// +// Conversely, any ISRs prioritized above the QF_AWARE_ISR_CMSIS_PRI priority +// level (i.e., with the numerical values of priorities less than +// QF_AWARE_ISR_CMSIS_PRI) are never disabled and are not aware of the kernel. +// Such "QF-unaware" ISRs cannot call ANY QF/QK services. In particular they +// can NOT call the macros QK_ISR_ENTRY/QK_ISR_ENTRY. The only mechanism +// by which a "QF-unaware" ISR can communicate with the QF framework is by +// triggering a "QF-aware" ISR, which can post/publish events. +// +// NOTE2: +// The User LED is used to visualize the idle loop activity. The brightness +// of the LED is proportional to the frequency of the idle loop. +// Please note that the LED is toggled with interrupts locked, so no interrupt +// execution time contributes to the brightness of the User LED. +// diff --git a/examples/arm-cm/dpp_nucleo-c031c6/qk/gnu/Makefile b/examples/arm-cm/dpp_nucleo-c031c6/qk/gnu/Makefile new file mode 100644 index 00000000..c110c912 --- /dev/null +++ b/examples/arm-cm/dpp_nucleo-c031c6/qk/gnu/Makefile @@ -0,0 +1,317 @@ +############################################################################## +# Product: Makefile for QP/C on NUCLEO-C031C6, QK kernel, GNU-ARM +# Last Updated for Version: 7.3.0 +# Date of the Last Update: 2023-05-26 +# +# Q u a n t u m L e a P s +# ------------------------ +# Modern Embedded Software +# +# Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +# +# This program is open source software: you can redistribute it and/or +# modify it under the terms of the GNU General Public License as published +# by the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Alternatively, this program may be distributed and modified under the +# terms of Quantum Leaps commercial licenses, which expressly supersede +# the GNU General Public License and are specifically designed for +# licensees interested in retaining the proprietary status of their code. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# +# Contact information: +# +# +############################################################################## +# examples of invoking this Makefile: +# building configurations: Debug (default), Release, and Spy +# make +# make CONF=rel +# make CONF=spy +# +# cleaning configurations: Debug (default), Release, and Spy +# make clean +# make CONF=rel clean +# make CONF=spy clean +# +# NOTE: +# To use this Makefile on Windows, you will need the GNU make utility, which +# is included in the Qtools collection for Windows, see: +# https://github.com/QuantumLeaps/qtools + +#----------------------------------------------------------------------------- +# project name +# +PROJECT := dpp-qk + +#----------------------------------------------------------------------------- +# project directories +# + +# location of the QP/C framework (if not provided in an environemnt var.) +ifeq ($(QPC),) +QPC := ../../../../.. +endif + +# QP port used in this project +QP_PORT_DIR := $(QPC)/ports/arm-cm/qk/gnu + +# list of all source directories used by this project +VPATH = \ + .. \ + ../.. \ + $(QPC)/src/qf \ + $(QPC)/src/qk \ + $(QPC)/src/qs \ + $(QP_PORT_DIR) \ + $(QPC)/3rd_party/nucleo-c031c6 \ + $(QPC)/3rd_party/nucleo-c031c6/gnu + +# list of all include directories needed by this project +INCLUDES = \ + -I../.. \ + -I$(QPC)/include \ + -I$(QP_PORT_DIR) \ + -I$(QPC)/3rd_party/CMSIS/Include \ + -I$(QPC)/3rd_party/nucleo-c031c6 + +#----------------------------------------------------------------------------- +# files +# + +# assembler source files +ASM_SRCS := + +# C source files +C_SRCS := \ + bsp.c \ + main.c \ + philo.c \ + table.c \ + system_stm32c0xx.c \ + startup_stm32c031xx.c + +# C++ source files +CPP_SRCS := + +OUTPUT := $(PROJECT) +LD_SCRIPT := $(PROJECT).ld + +QP_SRCS := \ + qep_hsm.c \ + qep_msm.c \ + qf_act.c \ + qf_actq.c \ + qf_defer.c \ + qf_dyn.c \ + qf_mem.c \ + qf_ps.c \ + qf_qact.c \ + qf_qeq.c \ + qf_qmact.c \ + qf_time.c \ + qk.c \ + qk_port.c + +QP_ASMS := + +QS_SRCS := \ + qs.c \ + qs_rx.c \ + qs_fp.c + +LIB_DIRS := +LIBS := + +# defines +DEFINES := -DSTM32C031xx \ + -DQF_ON_CONTEXT_SW \ + -DQK_USE_IRQ_NUM=31 \ + -DQK_USE_IRQ_HANDLER=Reserved31_IRQHandler + +# ARM CPU, ARCH, FPU, and Float-ABI types... +# ARM_CPU: [cortex-m0 | cortex-m0plus | cortex-m1 | cortex-m3 | cortex-m4] +# ARM_FPU: [ | vfp] +# FLOAT_ABI: [ | soft | softfp | hard] +# +ARM_CPU := -mcpu=cortex-m0plus +ARM_FPU := +FLOAT_ABI := + +#----------------------------------------------------------------------------- +# GNU-ARM toolset (NOTE: You need to adjust to your machine) +# see https://developer.arm.com/open-source/gnu-toolchain/gnu-rm/downloads +# +ifeq ($(GNU_ARM),) +GNU_ARM := $(QTOOLS)/gnu_arm-none-eabi +endif + +# make sure that the GNU-ARM toolset exists... +ifeq ("$(wildcard $(GNU_ARM))","") +$(error GNU_ARM toolset not found. Please adjust the Makefile) +endif + +CC := $(GNU_ARM)/bin/arm-none-eabi-gcc +CPP := $(GNU_ARM)/bin/arm-none-eabi-g++ +AS := $(GNU_ARM)/bin/arm-none-eabi-as +LINK := $(GNU_ARM)/bin/arm-none-eabi-gcc +BIN := $(GNU_ARM)/bin/arm-none-eabi-objcopy + +############################################################################## +# Typically you should not need to change anything below this line + +# basic utilities (included in QTools for Windows), see: +# https://www.state-machine.com/qtools + +MKDIR := mkdir +RM := rm + +#----------------------------------------------------------------------------- +# build options for various configurations for ARM Cortex-M +# + +# combine all the soruces... +C_SRCS += $(QP_SRCS) +ASM_SRCS += $(QP_ASMS) + +ifeq (rel, $(CONF)) # Release configuration .................................. + +BIN_DIR := rel + +ASFLAGS = $(ARM_CPU) $(ARM_FPU) $(ASM_CPU) $(ASM_FPU) + +CFLAGS = -c $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \ + -ffunction-sections -fdata-sections \ + -O2 $(INCLUDES) $(DEFINES) -DNDEBUG + +CPPFLAGS = -c $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \ + -ffunction-sections -fdata-sections -fno-rtti -fno-exceptions \ + -O2 $(INCLUDES) $(DEFINES) -DNDEBUG + +else ifeq (spy, $(CONF)) # Spy configuration ................................ + +BIN_DIR := spy + +C_SRCS += $(QS_SRCS) + +ASFLAGS = -g $(ARM_CPU) $(ARM_FPU) $(ASM_CPU) $(ASM_FPU) + +CFLAGS = -c -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \ + -ffunction-sections -fdata-sections \ + -O $(INCLUDES) $(DEFINES) -DQ_SPY + +CPPFLAGS = -c -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \ + -ffunction-sections -fdata-sections -fno-rtti -fno-exceptions \ + -O $(INCLUDES) $(DEFINES) -DQ_SPY + +else # default Debug configuration .......................................... + +BIN_DIR := dbg + +ASFLAGS = -g $(ARM_CPU) $(ARM_FPU) $(ASM_CPU) $(ASM_FPU) + +CFLAGS = -c -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \ + -ffunction-sections -fdata-sections \ + -O $(INCLUDES) $(DEFINES) + +CPPFLAGS = -c -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \ + -ffunction-sections -fdata-sections -fno-rtti -fno-exceptions \ + -O $(INCLUDES) $(DEFINES) + +endif # ...................................................................... + + +LINKFLAGS = -T$(LD_SCRIPT) $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb \ + -specs=nosys.specs -specs=nano.specs \ + -Wl,-Map,$(BIN_DIR)/$(OUTPUT).map,--cref,--gc-sections $(LIB_DIRS) + +ASM_OBJS := $(patsubst %.s,%.o, $(notdir $(ASM_SRCS))) +C_OBJS := $(patsubst %.c,%.o, $(notdir $(C_SRCS))) +CPP_OBJS := $(patsubst %.cpp,%.o,$(notdir $(CPP_SRCS))) + +TARGET_BIN := $(BIN_DIR)/$(OUTPUT).bin +TARGET_ELF := $(BIN_DIR)/$(OUTPUT).elf +ASM_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(ASM_OBJS)) +C_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(C_OBJS)) +C_DEPS_EXT := $(patsubst %.o, %.d, $(C_OBJS_EXT)) +CPP_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(CPP_OBJS)) +CPP_DEPS_EXT := $(patsubst %.o, %.d, $(CPP_OBJS_EXT)) + +# create $(BIN_DIR) if it does not exist +ifeq ("$(wildcard $(BIN_DIR))","") +$(shell $(MKDIR) $(BIN_DIR)) +endif + +#----------------------------------------------------------------------------- +# rules +# + +.PHONY : run norun flash + +ifeq ($(MAKECMDGOALS),norun) +all : $(TARGET_BIN) +norun : all +else +all : $(TARGET_BIN) run +endif + +$(TARGET_BIN): $(TARGET_ELF) + $(BIN) -O binary $< $@ + +$(TARGET_ELF) : $(ASM_OBJS_EXT) $(C_OBJS_EXT) $(CPP_OBJS_EXT) + $(CC) $(CFLAGS) $(QPC)/src/qs/qstamp.c -o $(BIN_DIR)/qstamp.o + $(LINK) $(LINKFLAGS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) + +$(BIN_DIR)/%.d : %.c + $(CC) -MM -MT $(@:.d=.o) $(CFLAGS) $< > $@ + +$(BIN_DIR)/%.d : %.cpp + $(CPP) -MM -MT $(@:.d=.o) $(CPPFLAGS) $< > $@ + +$(BIN_DIR)/%.o : %.s + $(AS) $(ASFLAGS) $< -o $@ + +$(BIN_DIR)/%.o : %.c + $(CC) $(CFLAGS) $< -o $@ + +$(BIN_DIR)/%.o : %.cpp + $(CPP) $(CPPFLAGS) $< -o $@ + +.PHONY : clean show + +# include dependency files only if our goal depends on their existence +ifneq ($(MAKECMDGOALS),clean) + ifneq ($(MAKECMDGOALS),show) +-include $(C_DEPS_EXT) $(CPP_DEPS_EXT) + endif +endif + + +clean: + -$(RM) $(BIN_DIR)/*.o \ + $(BIN_DIR)/*.d \ + $(BIN_DIR)/*.bin \ + $(BIN_DIR)/*.elf \ + $(BIN_DIR)/*.map + +show: + @echo PROJECT = $(PROJECT) + @echo CONF = $(CONF) + @echo DEFINES = $(DEFINES) + @echo ASM_FPU = $(ASM_FPU) + @echo ASM_SRCS = $(ASM_SRCS) + @echo C_SRCS = $(C_SRCS) + @echo CPP_SRCS = $(CPP_SRCS) + @echo ASM_OBJS_EXT = $(ASM_OBJS_EXT) + @echo C_OBJS_EXT = $(C_OBJS_EXT) + @echo C_DEPS_EXT = $(C_DEPS_EXT) + @echo CPP_DEPS_EXT = $(CPP_DEPS_EXT) + @echo TARGET_ELF = $(TARGET_ELF) diff --git a/examples/arm-cm/dpp_nucleo-c031c6/qk/gnu/README.txt b/examples/arm-cm/dpp_nucleo-c031c6/qk/gnu/README.txt new file mode 100644 index 00000000..d3fb3164 --- /dev/null +++ b/examples/arm-cm/dpp_nucleo-c031c6/qk/gnu/README.txt @@ -0,0 +1,92 @@ +About this Example +================== +This example can be built in two different ways: +- from the command prompt with the provided Makefile. +- from the Atollic TRUEStudio-ST32 with the provided project. + + +The Makefile +============ +The provided Makefile should be easy to adapt for your own projects. +It contains three build configurations: Debug (default), Release, and +Spy. + +Also, the Makefile has been specifically designed to work as an external +Makefile with the Eclipse CDT. + +The various build configurations are built as follows: + +make +make CONF=rel +make CONF=spy + +make clean +make CONF=rel clean +make CONF=spy clean + +*** +NOTE: +The installation folder of the GNU-ARM toolset on YOUR machine needs +to be adjusted in the provided Makefile, by editing the symbol: GNU_ARM. +As described in the comment for this symbol, the GNU-ARM toolset is taken +from: http://gnutoolchains.com/arm-eabi + +It is highly recommened to use the same GNU-ARM distribution, especially +for ARM Cortex-M projects, due to the support for the hardware FPU +(float-abi=hard). +*** + + +Selecting QK Exception +====================== +The QK kernel needs a dedicated exception to return to the thread +context after preemption. The default is to use the NMI exception +for that purpose. However, in case NMI is needed for some other +purpose, the QK port allows you to select a any, otherwise unused +IRQ for that purpose. To choose a given IRQ, you need to define +the macros QK_USE_IRQ_NUM and QK_USE_IRQ_HANDLER. These macros can +be provided on the command-line to the compiler. + +For example, (see the vector table), you can define the QK IRQ +as follows: + +QK_USE_IRQ_HANDLER=Reserved31_IRQHandler +QK_USE_IRQ_NUM=31 + + +Adjusting Stack and Heap Sizes +============================== +The stack and heap sizes are determined in this project by the GCC linker +script (.ld file), which provides a template of the recommended GCC linker +script for QP applications. + + +Startup Code +============ +The startup code for the STM32C0xx MCU used in this project is +located in the "3rd_party" folder in the following location: + +3rd_party\nucleo-c031c6\gnu\startup_stm32c031xx.c + +The file startup_stm32c031xx.c provides a template of the recommended +startup for QP applications and should be easily customizable for other +ARM Cortex-M microcontrollers. + +The startup file typically does not need to be modified or adapted for +applications. It calls the assert_failed() function, which must be +defined in the application to customize it for the application-specific +error-handling policy. + + +Adjusting the CPU Clock Speed +============================= +The current setting is to run at 12MHz from the MSI (internal oscillator), +but the CPU clock speed can be modified. + +*** +NOTE: +The NUCLEO boards have a wide range of possible clock selections, depending +on the solder bridge configuration. Please see Chapter 5.7 "OSC clock" in +the STM32 NUCLEO Boards User Manual (ST document UM1724) for more information. +*** + diff --git a/examples/arm-cm/dpp_nucleo-c031c6/qk/gnu/dpp-qk.ld b/examples/arm-cm/dpp_nucleo-c031c6/qk/gnu/dpp-qk.ld new file mode 100644 index 00000000..4a3ba851 --- /dev/null +++ b/examples/arm-cm/dpp_nucleo-c031c6/qk/gnu/dpp-qk.ld @@ -0,0 +1,135 @@ +/***************************************************************************** +* Linker script for for STM32C031C6, GNU-ARM linker +* +* Q u a n t u m L e a P s +* ------------------------ +* Modern Embedded Software +* +* Copyright (C) 2005 Quantum Leaps, LLC . +* +* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +* +* This software is dual-licensed under the terms of the open source GNU +* General Public License version 3 (or any later version), or alternatively, +* under the terms of one of the closed source Quantum Leaps commercial +* licenses. +* +* The terms of the open source GNU General Public License version 3 +* can be found at: +* +* The terms of the closed source Quantum Leaps commercial licenses +* can be found at: +* +* Redistributions in source code must retain this top-level comment block. +* Plagiarizing this software to sidestep the license obligations is illegal. +* +* Contact information: +* +* +*****************************************************************************/ +OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm", "elf32-littlearm") +OUTPUT_ARCH(arm) +ENTRY(Reset_Handler) /* entry Point */ + +MEMORY { /* memory map of STM32C031C6 */ + ROM (rx) : ORIGIN = 0x08000000, LENGTH = 32K + RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 12K +} + +/* The size of the stack used by the application. NOTE: you need to adjust */ +STACK_SIZE = 2048; + +/* The size of the heap used by the application. NOTE: you need to adjust */ +HEAP_SIZE = 0; + +SECTIONS { + + .isr_vector : { /* the vector table goes FIRST into ROM */ + KEEP(*(.isr_vector)) /* vector table */ + . = ALIGN(4); + } >ROM + + .text : { /* code and constants */ + . = ALIGN(4); + *(.text) /* .text sections (code) */ + *(.text*) /* .text* sections (code) */ + *(.rodata) /* .rodata sections (constants, strings, etc.) */ + *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ + + KEEP (*(.init)) + KEEP (*(.fini)) + + . = ALIGN(4); + } >ROM + + .preinit_array : { + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array*)) + PROVIDE_HIDDEN (__preinit_array_end = .); + } >ROM + + .init_array : { + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array*)) + PROVIDE_HIDDEN (__init_array_end = .); + } >ROM + + .fini_array : { + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(.fini_array*)) + KEEP (*(SORT(.fini_array.*))) + PROVIDE_HIDDEN (__fini_array_end = .); + } >ROM + + _etext = .; /* global symbols at end of code */ + + .stack : { + __stack_start__ = .; + . = . + STACK_SIZE; + . = ALIGN(4); + __stack_end__ = .; + } >RAM + + .data : AT (_etext) { + __data_load = LOADADDR (.data); + __data_start = .; + *(.data) /* .data sections */ + *(.data*) /* .data* sections */ + . = ALIGN(4); + __data_end__ = .; + _edata = __data_end__; + } >RAM + + .bss : { + __bss_start__ = .; + *(.bss) + *(.bss*) + *(COMMON) + . = ALIGN(4); + _ebss = .; /* define a global symbol at bss end */ + __bss_end__ = .; + } >RAM + + __exidx_start = .; + .ARM.exidx : { *(.ARM.exidx* .gnu.linkonce.armexidx.*) } >RAM + __exidx_end = .; + + PROVIDE ( end = _ebss ); + PROVIDE ( _end = _ebss ); + PROVIDE ( __end__ = _ebss ); + + .heap : { + __heap_start__ = .; + . = . + HEAP_SIZE; + . = ALIGN(4); + __heap_end__ = .; + } >RAM + + /* Remove information from the standard libraries */ + /DISCARD/ : { + libc.a ( * ) + libm.a ( * ) + libgcc.a ( * ) + } +} diff --git a/examples/arm-cm/dpp_nucleo-c031c6/qk/iar/dpp-qk.ewd b/examples/arm-cm/dpp_nucleo-c031c6/qk/iar/dpp-qk.ewd new file mode 100644 index 00000000..b3712b65 --- /dev/null +++ b/examples/arm-cm/dpp_nucleo-c031c6/qk/iar/dpp-qk.ewd @@ -0,0 +1,4654 @@ + + + 3 + + Debug + + ARM + + 1 + + C-SPY + 2 + + 32 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ARMSIM_ID + 2 + + 1 + 1 + 1 + + + + + + + + CADI_ID + 2 + + 0 + 1 + 1 + + + + + + + + + CMSISDAP_ID + 2 + + 4 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + GDBSERVER_ID + 2 + + 0 + 1 + 1 + + + + + + + + + + + IJET_ID + 2 + + 9 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + JLINK_ID + 2 + + 16 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + LMIFTDI_ID + 2 + + 3 + 1 + 1 + + + + + + + + + + + + + NULINK_ID + 2 + + 0 + 1 + 1 + + + + + + + PEMICRO_ID + 2 + + 3 + 1 + 1 + + + + + + + + STLINK_ID + 2 + + 8 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + THIRDPARTY_ID + 2 + + 0 + 1 + 1 + + + + + + + + TIFET_ID + 2 + + 1 + 1 + 1 + + + + + + + + + + + + + + + + + + + XDS100_ID + 2 + + 9 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + $TOOLKIT_DIR$\plugins\rtos\CMX\CmxArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\CMX\CmxTinyArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\FreeRtos\FreeRtosArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin2.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SafeRTOS\SafeRTOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9BE.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-286-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-III\uCOS-III-KA-CSpy.ewplugin + 0 + + + $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\TargetAccessServer\TargetAccessServer.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\uCProbe\uCProbePlugin.ENU.ewplugin + 0 + + + + + Release + + ARM + + 0 + + C-SPY + 2 + + 32 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ARMSIM_ID + 2 + + 1 + 1 + 0 + + + + + + + + CADI_ID + 2 + + 0 + 1 + 0 + + + + + + + + + CMSISDAP_ID + 2 + + 4 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + GDBSERVER_ID + 2 + + 0 + 1 + 0 + + + + + + + + + + + IJET_ID + 2 + + 9 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + JLINK_ID + 2 + + 16 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + LMIFTDI_ID + 2 + + 3 + 1 + 0 + + + + + + + + + + + + + NULINK_ID + 2 + + 0 + 1 + 0 + + + + + + + PEMICRO_ID + 2 + + 3 + 1 + 0 + + + + + + + + STLINK_ID + 2 + + 8 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + THIRDPARTY_ID + 2 + + 0 + 1 + 0 + + + + + + + + TIFET_ID + 2 + + 1 + 1 + 0 + + + + + + + + + + + + + + + + + + + XDS100_ID + 2 + + 9 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + $TOOLKIT_DIR$\plugins\rtos\CMX\CmxArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\CMX\CmxTinyArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\FreeRtos\FreeRtosArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin2.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SafeRTOS\SafeRTOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9BE.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-286-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-III\uCOS-III-KA-CSpy.ewplugin + 0 + + + $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\TargetAccessServer\TargetAccessServer.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\uCProbe\uCProbePlugin.ENU.ewplugin + 0 + + + + + Spy + + ARM + + 1 + + C-SPY + 2 + + 32 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ARMSIM_ID + 2 + + 1 + 1 + 1 + + + + + + + + CADI_ID + 2 + + 0 + 1 + 1 + + + + + + + + + CMSISDAP_ID + 2 + + 4 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + GDBSERVER_ID + 2 + + 0 + 1 + 1 + + + + + + + + + + + IJET_ID + 2 + + 9 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + JLINK_ID + 2 + + 16 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + LMIFTDI_ID + 2 + + 3 + 1 + 1 + + + + + + + + + + + + + NULINK_ID + 2 + + 0 + 1 + 1 + + + + + + + PEMICRO_ID + 2 + + 3 + 1 + 1 + + + + + + + + STLINK_ID + 2 + + 8 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + THIRDPARTY_ID + 2 + + 0 + 1 + 1 + + + + + + + + TIFET_ID + 2 + + 1 + 1 + 1 + + + + + + + + + + + + + + + + + + + XDS100_ID + 2 + + 9 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + $TOOLKIT_DIR$\plugins\rtos\CMX\CmxArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\CMX\CmxTinyArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\FreeRtos\FreeRtosArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin2.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SafeRTOS\SafeRTOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9BE.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-286-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-III\uCOS-III-KA-CSpy.ewplugin + 0 + + + $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\TargetAccessServer\TargetAccessServer.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\uCProbe\uCProbePlugin.ENU.ewplugin + 0 + + + + diff --git a/examples/arm-cm/dpp_nucleo-c031c6/qk/iar/dpp-qk.ewp b/examples/arm-cm/dpp_nucleo-c031c6/qk/iar/dpp-qk.ewp new file mode 100644 index 00000000..c1fed27d --- /dev/null +++ b/examples/arm-cm/dpp_nucleo-c031c6/qk/iar/dpp-qk.ewp @@ -0,0 +1,3364 @@ + + + 3 + + Debug + + ARM + + 1 + + General + 3 + + 35 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ICCARM + 2 + + 37 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + AARM + 2 + + 11 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + OBJCOPY + 0 + + 1 + 1 + 1 + + + + + + + + + CUSTOM + 3 + + + + 0 + inputOutputBased + + + + BUILDACTION + 1 + + cmd /c "if exist $OBJ_DIR$\qstamp.o del $OBJ_DIR$\qstamp.o" + + + + + ILINK + 0 + + 27 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + IARCHIVE + 0 + + 0 + 1 + 1 + + + + + + + Coder + 0 + + + + + Release + + ARM + + 0 + + General + 3 + + 35 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ICCARM + 2 + + 37 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + AARM + 2 + + 11 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + OBJCOPY + 0 + + 1 + 1 + 0 + + + + + + + + + CUSTOM + 3 + + + + 0 + inputOutputBased + + + + BUILDACTION + 1 + + cmd /c "if exist $OBJ_DIR$\qstamp.o del $OBJ_DIR$\qstamp.o" + + + + + ILINK + 0 + + 27 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + IARCHIVE + 0 + + 0 + 1 + 0 + + + + + + + Coder + 0 + + + + + Spy + + ARM + + 1 + + General + 3 + + 35 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ICCARM + 2 + + 37 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + AARM + 2 + + 11 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + OBJCOPY + 0 + + 1 + 1 + 1 + + + + + + + + + CUSTOM + 3 + + + + 0 + inputOutputBased + + + + BUILDACTION + 1 + + cmd /c "if exist $OBJ_DIR$\qstamp.o del $OBJ_DIR$\qstamp.o" + + + + + ILINK + 0 + + 27 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + IARCHIVE + 0 + + 0 + 1 + 1 + + + + + + + Coder + 0 + + + + + Release + + + Application + + $PROJ_DIR$\..\bsp.c + + + $PROJ_DIR$\..\..\bsp.h + + + $PROJ_DIR$\..\..\dpp.h + + + $PROJ_DIR$\..\..\main.c + + + $PROJ_DIR$\..\..\philo.c + + + $PROJ_DIR$\..\..\table.c + + + + nucleo-c031c6 + + $PROJ_DIR$\..\..\..\..\..\3rd_party\nucleo-c031c6\iar\startup_stm32c031xx.s + + + $PROJ_DIR$\..\..\..\..\..\3rd_party\nucleo-c031c6\stm32c031xx.h + + + $PROJ_DIR$\..\..\..\..\..\3rd_party\nucleo-c031c6\stm32c0xx.h + + + $PROJ_DIR$\..\..\..\..\..\3rd_party\nucleo-c031c6\system_stm32c0xx.c + + + + QP + + $PROJ_DIR$\..\..\..\..\..\src\qf\qep_hsm.c + + + $PROJ_DIR$\..\..\..\..\..\src\qf\qep_msm.c + + + $PROJ_DIR$\..\..\..\..\..\src\qf\qf_act.c + + + $PROJ_DIR$\..\..\..\..\..\src\qf\qf_actq.c + + + $PROJ_DIR$\..\..\..\..\..\src\qf\qf_defer.c + + + $PROJ_DIR$\..\..\..\..\..\src\qf\qf_dyn.c + + + $PROJ_DIR$\..\..\..\..\..\src\qf\qf_mem.c + + + $PROJ_DIR$\..\..\..\..\..\src\qf_pkg.h + + + $PROJ_DIR$\..\..\..\..\..\src\qf\qf_ps.c + + + $PROJ_DIR$\..\..\..\..\..\src\qf\qf_qact.c + + + $PROJ_DIR$\..\..\..\..\..\src\qf\qf_qeq.c + + + $PROJ_DIR$\..\..\..\..\..\src\qf\qf_qmact.c + + + $PROJ_DIR$\..\..\..\..\..\src\qf\qf_time.c + + + $PROJ_DIR$\..\..\..\..\..\src\qk\qk.c + + + + QP_port + + $PROJ_DIR$\..\..\..\..\..\ports\arm-cm\qk\iar\qep_port.h + + + $PROJ_DIR$\..\..\..\..\..\ports\arm-cm\qk\iar\qf_port.h + + + $PROJ_DIR$\..\..\..\..\..\ports\arm-cm\qk\iar\qk_port.c + + + $PROJ_DIR$\..\..\..\..\..\ports\arm-cm\qk\iar\qk_port.h + + + $PROJ_DIR$\..\..\..\..\..\ports\arm-cm\qk\iar\qs_port.h + + + + QS + + Debug + Release + + + $PROJ_DIR$\..\..\..\..\..\src\qs\qs.c + + + $PROJ_DIR$\..\..\..\..\..\src\qs\qs_fp.c + + + $PROJ_DIR$\..\..\..\..\..\src\qs\qs_rx.c + + + $PROJ_DIR$\..\..\..\..\..\src\qs\qstamp.c + + + diff --git a/examples/arm-cm/dpp_nucleo-c031c6/qk/iar/dpp-qk.eww b/examples/arm-cm/dpp_nucleo-c031c6/qk/iar/dpp-qk.eww new file mode 100644 index 00000000..c261124a --- /dev/null +++ b/examples/arm-cm/dpp_nucleo-c031c6/qk/iar/dpp-qk.eww @@ -0,0 +1,10 @@ + + + + + $WS_DIR$\dpp-qk.ewp + + + + + diff --git a/examples/arm-cm/dpp_nucleo-c031c6/qk/iar/dpp-qk.icf b/examples/arm-cm/dpp_nucleo-c031c6/qk/iar/dpp-qk.icf new file mode 100644 index 00000000..db057b16 --- /dev/null +++ b/examples/arm-cm/dpp_nucleo-c031c6/qk/iar/dpp-qk.icf @@ -0,0 +1,165 @@ +/*###ICF### Section handled by ICF editor, don't touch! ****/ +/*-Editor annotation file-*/ +/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_4.xml" */ +/*-Specials-*/ +define symbol __ICFEDIT_intvec_start__ = 0x08000000; +/*-Memory Regions-*/ +define symbol __ICFEDIT_region_IROM1_start__ = 0x08000000; +define symbol __ICFEDIT_region_IROM1_end__ = 0x08007FFF; +define symbol __ICFEDIT_region_IROM2_start__ = 0x0; +define symbol __ICFEDIT_region_IROM2_end__ = 0x0; +define symbol __ICFEDIT_region_EROM1_start__ = 0x0; +define symbol __ICFEDIT_region_EROM1_end__ = 0x0; +define symbol __ICFEDIT_region_EROM2_start__ = 0x0; +define symbol __ICFEDIT_region_EROM2_end__ = 0x0; +define symbol __ICFEDIT_region_EROM3_start__ = 0x0; +define symbol __ICFEDIT_region_EROM3_end__ = 0x0; +define symbol __ICFEDIT_region_IRAM1_start__ = 0x20000000; +define symbol __ICFEDIT_region_IRAM1_end__ = 0x20002FFF; +define symbol __ICFEDIT_region_IRAM2_start__ = 0x0; +define symbol __ICFEDIT_region_IRAM2_end__ = 0x0; +define symbol __ICFEDIT_region_ERAM1_start__ = 0x0; +define symbol __ICFEDIT_region_ERAM1_end__ = 0x0; +define symbol __ICFEDIT_region_ERAM2_start__ = 0x0; +define symbol __ICFEDIT_region_ERAM2_end__ = 0x0; +define symbol __ICFEDIT_region_ERAM3_start__ = 0x0; +define symbol __ICFEDIT_region_ERAM3_end__ = 0x0; +/*-Sizes-*/ +define symbol __ICFEDIT_size_cstack__ = 2048; +define symbol __ICFEDIT_size_proc_stack__ = 0x0; +define symbol __ICFEDIT_size_heap__ = 0; +/**** End of ICF editor section. ###ICF###*/ + +define memory mem with size = 4G; +define symbol use_IROM1 = (__ICFEDIT_region_IROM1_start__ != 0x0 || __ICFEDIT_region_IROM1_end__ != 0x0); +define symbol use_IROM2 = (__ICFEDIT_region_IROM2_start__ != 0x0 || __ICFEDIT_region_IROM2_end__ != 0x0); +define symbol use_EROM1 = (__ICFEDIT_region_EROM1_start__ != 0x0 || __ICFEDIT_region_EROM1_end__ != 0x0); +define symbol use_EROM2 = (__ICFEDIT_region_EROM2_start__ != 0x0 || __ICFEDIT_region_EROM2_end__ != 0x0); +define symbol use_EROM3 = (__ICFEDIT_region_EROM3_start__ != 0x0 || __ICFEDIT_region_EROM3_end__ != 0x0); +define symbol use_IRAM1 = (__ICFEDIT_region_IRAM1_start__ != 0x0 || __ICFEDIT_region_IRAM1_end__ != 0x0); +define symbol use_IRAM2 = (__ICFEDIT_region_IRAM2_start__ != 0x0 || __ICFEDIT_region_IRAM2_end__ != 0x0); +define symbol use_ERAM1 = (__ICFEDIT_region_ERAM1_start__ != 0x0 || __ICFEDIT_region_ERAM1_end__ != 0x0); +define symbol use_ERAM2 = (__ICFEDIT_region_ERAM2_start__ != 0x0 || __ICFEDIT_region_ERAM2_end__ != 0x0); +define symbol use_ERAM3 = (__ICFEDIT_region_ERAM3_start__ != 0x0 || __ICFEDIT_region_ERAM3_end__ != 0x0); + +if (use_IROM1) +{ + define region IROM1_region = mem:[from __ICFEDIT_region_IROM1_start__ to __ICFEDIT_region_IROM1_end__]; +} +else +{ + define region IROM1_region = []; +} + +if (use_IROM2) +{ + define region IROM2_region = mem:[from __ICFEDIT_region_IROM2_start__ to __ICFEDIT_region_IROM2_end__]; +} +else +{ + define region IROM2_region = []; +} +define region IROM_region = IROM1_region | IROM2_region; + +if (use_EROM1) +{ + define region EROM1_region = mem:[from __ICFEDIT_region_EROM1_start__ to __ICFEDIT_region_EROM1_end__]; +} +else +{ + define region EROM1_region = []; +} +if (use_EROM2) +{ + define region EROM2_region = mem:[from __ICFEDIT_region_EROM2_start__ to __ICFEDIT_region_EROM2_end__]; +} +else +{ + define region EROM2_region = []; +} +if (use_EROM3) +{ + define region EROM3_region = mem:[from __ICFEDIT_region_EROM3_start__ to __ICFEDIT_region_EROM3_end__]; +} +else +{ + define region EROM3_region = []; +} +define region EROM_region = EROM1_region | EROM2_region | EROM3_region; + +if (use_IRAM1) +{ + define region IRAM1_region = mem:[from __ICFEDIT_region_IRAM1_start__ to __ICFEDIT_region_IRAM1_end__]; +} +else +{ + define region IRAM1_region = []; +} +if (use_IRAM2) +{ + define region IRAM2_region = mem:[from __ICFEDIT_region_IRAM2_start__ to __ICFEDIT_region_IRAM2_end__]; +} +else +{ + define region IRAM2_region = []; +} +define region IRAM_region = IRAM1_region | IRAM2_region; + +if (use_ERAM1) +{ + define region ERAM1_region = mem:[from __ICFEDIT_region_ERAM1_start__ to __ICFEDIT_region_ERAM1_end__]; +} +else +{ + define region ERAM1_region = []; +} +if (use_ERAM2) +{ + define region ERAM2_region = mem:[from __ICFEDIT_region_ERAM2_start__ to __ICFEDIT_region_ERAM2_end__]; +} +else +{ + define region ERAM2_region = []; +} +if (use_ERAM3) +{ + define region ERAM3_region = mem:[from __ICFEDIT_region_ERAM3_start__ to __ICFEDIT_region_ERAM3_end__]; +} +else +{ + define region ERAM3_region = []; +} +define region ERAM_region = ERAM1_region | ERAM2_region | ERAM3_region; + +initialize by copy { readwrite }; +if (isdefinedsymbol(__USE_DLIB_PERTHREAD)) +{ + // Required in a multi-threaded application + initialize by copy with packing = none { section __DLIB_PERTHREAD }; +} + +place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec }; + +if (!isempty(IROM_region)) +{ + place in IROM_region { readonly }; +} + +if (!isempty(EROM_region)) +{ + place in EROM_region { readonly section application_specific_ro }; +} + +if (!isempty(IRAM_region)) +{ + define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { }; + define block PROC_STACK with alignment = 8, size = __ICFEDIT_size_proc_stack__ { }; + define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { }; + place at start of IRAM_region {block CSTACK }; /* <== Quantum Leaps */ + place in IRAM_region { readwrite, block PROC_STACK, block HEAP }; +} + +if (!isempty(ERAM_region)) +{ + place in ERAM_region { readwrite section application_specific_rw }; +} \ No newline at end of file diff --git a/examples/arm-cm/dpp_nucleo-c031c6/qspy-output.png b/examples/arm-cm/dpp_nucleo-c031c6/qspy-output.png new file mode 100644 index 00000000..ee764450 Binary files /dev/null and b/examples/arm-cm/dpp_nucleo-c031c6/qspy-output.png differ diff --git a/examples/arm-cm/dpp_nucleo-c031c6/qv/armclang/dpp-qv.sct b/examples/arm-cm/dpp_nucleo-c031c6/qv/armclang/dpp-qv.sct new file mode 100644 index 00000000..100826b8 --- /dev/null +++ b/examples/arm-cm/dpp_nucleo-c031c6/qv/armclang/dpp-qv.sct @@ -0,0 +1,23 @@ +; ************************************************************* +; *** Scatter-Loading Description File generated by uVision *** +; +; Adapted by Quantum Leaps: +; moved STACK as the first section in RW_STACK +; ************************************************************* + +LR_IROM1 0x08000000 0x00008000 { ; load region size_region + ER_IROM1 0x08000000 0x00008000 { ; load address = execution address + *.o (RESET, +First) + *(InRoot$$Sections) + .ANY (+RO) + .ANY (+XO) + } + + RW_STACK 0x20000000 { + * (STACK, +First) + } + RW_IRAM1 +0 (0x00003000 - 2048) { + .ANY (+RW +ZI) + } +} + diff --git a/examples/arm-cm/dpp_nucleo-c031c6/qv/armclang/dpp-qv.uvoptx b/examples/arm-cm/dpp_nucleo-c031c6/qv/armclang/dpp-qv.uvoptx new file mode 100644 index 00000000..4bb4e051 --- /dev/null +++ b/examples/arm-cm/dpp_nucleo-c031c6/qv/armclang/dpp-qv.uvoptx @@ -0,0 +1,1091 @@ + + + + 1.0 + +
### uVision Project, (C) Keil Software
+ + + *.c + *.s*; *.src; *.a* + *.obj; *.o + *.lib + *.txt; *.h; *.inc; *.md + *.plm + *.cpp + 0 + + + + 0 + 0 + + + + dpp-dbg + 0x4 + ARM-ADS + + 12000000 + + 1 + 1 + 0 + 1 + 0 + + + 1 + 65535 + 0 + 0 + 0 + + + 79 + 66 + 8 + .\dbg\ + + + 1 + 1 + 1 + 0 + 1 + 1 + 0 + 1 + 0 + 0 + 0 + 0 + + + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + + + 1 + 0 + 1 + + 18 + + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + 0 + 1 + 1 + 0 + 0 + 1 + 0 + 0 + 6 + + + + + + + + + + + STLink\ST-LINKIII-KEIL_SWO.dll + + + + 0 + ST-LINKIII-KEIL_SWO + -U066BFF505153848667095842 -O206 -SF10000 -C0 -A0 -I0 -HNlocalhost -HP7184 -P1 -N00("ARM CoreSight SW-DP (ARM Core") -D00(0BC11477) -L00(0) -TO65554 -TC10000000 -TT10000000 -TP21 -TDS8007 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -FO7 -FD20000000 -FC1000 -FN1 -FF0STM32C0x_32.FLM -FS08000000 -FL08000 -FP0($$Device:STM32C031C6Tx$CMSIS\Flash\STM32C0x_32.FLM) + + + 0 + UL2CM3 + -U -O206 -S8 -C0 -P00 -N00("") -D00(00000000) -L00(0) -TO65554 -TC10000000 -TT10000000 -TP21 -TDS8007 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -FO7 -FD20000000 -FC1000 -FN1 -FF0STM32C0x_32.FLM -FS08000000 -FL08000 -FP0($$Device:STM32C031C6Tx$CMSIS\Flash\STM32C0x_32.FLM) + + + 0 + DLGUARM + (105=-1,-1,-1,-1,0) + + + 0 + ARMRTXEVENTFLAGS + -L70 -Z18 -C0 -M0 -T1 + + + 0 + DLGTARM + (1010=-1,-1,-1,-1,0)(1007=-1,-1,-1,-1,0)(1008=-1,-1,-1,-1,0)(1012=-1,-1,-1,-1,0)(1009=-1,-1,-1,-1,0) + + + 0 + ARMDBGFLAGS + + + + + + 0 + 0 + 128 + 1 +
134218056
+ 0 + 0 + 0 + 0 + 0 + 1 + ..\..\..\..\..\3rd_party\nucleo-c031c6\arm\startup_stm32c031xx.s + + \\dpp_qv\../../../../../3rd_party/nucleo-c031c6/arm/startup_stm32c031xx.s\128 +
+ + 1 + 0 + 41 + 1 +
134228148
+ 0 + 0 + 0 + 0 + 0 + 1 + C:\qp-dev\qpc\examples\arm-cm\dpp_nucleo-c031c6\qv\main.c + + \\dpp_qv\../main.c\41 +
+
+ + + 1 + 2 + 0x20000200 + 0 + + + + + 2 + 0 + 0x400 + 0 + + + + 0 + + + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + + + + 0 + 0 + 0 + + + + + + + + + + 1 + 0 + 0 + 2 + 10000000 + +
+
+ + + dpp-rel + 0x4 + ARM-ADS + + 12000000 + + 1 + 1 + 0 + 1 + 0 + + + 1 + 65535 + 0 + 0 + 0 + + + 79 + 66 + 8 + .\rel\ + + + 1 + 1 + 1 + 0 + 1 + 1 + 0 + 1 + 0 + 0 + 0 + 0 + + + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + + + 1 + 0 + 0 + + 18 + + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + 0 + 1 + 1 + 0 + 0 + 1 + 0 + 0 + 6 + + + + + + + + + + + STLink\ST-LINKIII-KEIL_SWO.dll + + + + 0 + UL2CM3 + UL2CM3(-S0 -C0 -P0 ) -FN1 -FC1000 -FD20000000 -FF0STM32C0x_32 -FL08000 -FS08000000 -FP0($$Device:STM32C031C6Tx$CMSIS\Flash\STM32C0x_32.FLM) + + + 0 + ST-LINKIII-KEIL_SWO + UL2CM3(-S0 -C0 -P0 ) -FN1 -FC1000 -FD20000000 -FF0STM32C0x_32 -FL08000 -FS08000000 -FP0($$Device:STM32C031C6Tx$CMSIS\Flash\STM32C0x_32.FLM) + + + 0 + DLGUARM + (105=-1,-1,-1,-1,0) + + + 0 + ARMRTXEVENTFLAGS + -L70 -Z18 -C0 -M0 -T1 + + + 0 + DLGTARM + (1010=-1,-1,-1,-1,0)(1007=-1,-1,-1,-1,0)(1008=-1,-1,-1,-1,0)(1009=-1,-1,-1,-1,0) + + + 0 + ARMDBGFLAGS + + + + + + + 1 + 2 + 0x20000200 + 0 + + + + + 2 + 0 + 0x400 + 0 + + + + 0 + + + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + + + + 0 + 0 + 0 + + + + + + + + + + 1 + 1 + 0 + 2 + 10000000 + + + + + + dpp-spy + 0x4 + ARM-ADS + + 12000000 + + 1 + 1 + 0 + 1 + 0 + + + 1 + 65535 + 0 + 0 + 0 + + + 79 + 66 + 8 + .\spy\ + + + 1 + 1 + 1 + 0 + 1 + 1 + 0 + 1 + 0 + 0 + 0 + 0 + + + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + + + 1 + 0 + 0 + + 18 + + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + 0 + 1 + 1 + 0 + 0 + 1 + 0 + 0 + 6 + + + + + + + + + + + STLink\ST-LINKIII-KEIL_SWO.dll + + + + 0 + UL2CM3 + UL2CM3(-S0 -C0 -P0 ) -FN1 -FC1000 -FD20000000 -FF0STM32C0x_32 -FL08000 -FS08000000 -FP0($$Device:STM32C031C6Tx$CMSIS\Flash\STM32C0x_32.FLM) + + + 0 + ST-LINKIII-KEIL_SWO + -U-O206 -O206 -SF10000 -C0 -A0 -I0 -HNlocalhost -HP7184 -P1 -N00("ARM CoreSight SW-DP (ARM Core") -D00(0BC11477) -L00(0) -TO131090 -TC10000000 -TT10000000 -TP21 -TDS8007 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -FO7 -FD20000000 -FC1000 -FN1 -FF0STM32C0x_32.FLM -FS08000000 -FL08000 -FP0($$Device:STM32C031C6Tx$CMSIS\Flash\STM32C0x_32.FLM) + + + 0 + DLGUARM + (105=-1,-1,-1,-1,0) + + + 0 + ARMRTXEVENTFLAGS + -L70 -Z18 -C0 -M0 -T1 + + + 0 + DLGTARM + (1010=-1,-1,-1,-1,0)(1007=-1,-1,-1,-1,0)(1008=-1,-1,-1,-1,0)(1012=-1,-1,-1,-1,0)(1009=-1,-1,-1,-1,0) + + + 0 + ARMDBGFLAGS + + + + + + + 1 + 2 + 0x20000200 + 0 + + + + + 2 + 0 + 0x400 + 0 + + + + 0 + + + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + + + + 0 + 0 + 0 + + + + + + + + + + + System Viewer\GPIOA + 35904 + + + System Viewer\USART2 + 35905 + + + + 1 + 0 + 0 + 2 + 10000000 + + + + + + Source Code + 1 + 0 + 0 + 0 + + 1 + 1 + 1 + 0 + 0 + 0 + ..\bsp.c + bsp.c + 0 + 0 + + + 1 + 2 + 5 + 0 + 0 + 0 + ..\..\bsp.h + bsp.h + 0 + 0 + + + 1 + 3 + 5 + 0 + 0 + 0 + ..\..\dpp.h + dpp.h + 0 + 0 + + + 1 + 4 + 1 + 0 + 0 + 0 + ..\..\philo.c + philo.c + 0 + 0 + + + 1 + 5 + 1 + 0 + 0 + 0 + ..\..\table.c + table.c + 0 + 0 + + + 1 + 6 + 1 + 0 + 0 + 0 + ..\..\main.c + main.c + 0 + 0 + + + + + nucleo-c031c6 + 1 + 0 + 0 + 0 + + 2 + 7 + 5 + 0 + 0 + 0 + ..\..\..\..\..\3rd_party\nucleo-c031c6\stm32c0xx.h + stm32c0xx.h + 0 + 0 + + + 2 + 8 + 5 + 0 + 0 + 0 + ..\..\..\..\..\3rd_party\nucleo-c031c6\stm32c031xx.h + stm32c031xx.h + 0 + 0 + + + 2 + 9 + 1 + 0 + 0 + 0 + ..\..\..\..\..\3rd_party\nucleo-c031c6\system_stm32c0xx.c + system_stm32c0xx.c + 0 + 0 + + + 2 + 10 + 2 + 0 + 0 + 0 + ..\..\..\..\..\3rd_party\nucleo-c031c6\arm\startup_stm32c031xx.s + startup_stm32c031xx.s + 0 + 0 + + + + + QP + 1 + 0 + 0 + 0 + + 3 + 11 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qf\qep_hsm.c + qep_hsm.c + 0 + 0 + + + 3 + 12 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qf\qep_msm.c + qep_msm.c + 0 + 0 + + + 3 + 13 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qf\qf_act.c + qf_act.c + 0 + 0 + + + 3 + 14 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qf\qf_actq.c + qf_actq.c + 0 + 0 + + + 3 + 15 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qf\qf_defer.c + qf_defer.c + 0 + 0 + + + 3 + 16 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qf\qf_dyn.c + qf_dyn.c + 0 + 0 + + + 3 + 17 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qf\qf_mem.c + qf_mem.c + 0 + 0 + + + 3 + 18 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qf\qf_ps.c + qf_ps.c + 0 + 0 + + + 3 + 19 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qf\qf_qact.c + qf_qact.c + 0 + 0 + + + 3 + 20 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qf\qf_qeq.c + qf_qeq.c + 0 + 0 + + + 3 + 21 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qf\qf_qmact.c + qf_qmact.c + 0 + 0 + + + 3 + 22 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qf\qf_time.c + qf_time.c + 0 + 0 + + + 3 + 23 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qv\qv.c + qv.c + 0 + 0 + + + + + QP_port + 1 + 0 + 0 + 0 + + 4 + 24 + 5 + 0 + 0 + 0 + ..\..\..\..\..\ports\arm-cm\qv\armclang\qep_port.h + qep_port.h + 0 + 0 + + + 4 + 25 + 5 + 0 + 0 + 0 + ..\..\..\..\..\ports\arm-cm\qv\armclang\qf_port.h + qf_port.h + 0 + 0 + + + 4 + 26 + 5 + 0 + 0 + 0 + ..\..\..\..\..\ports\arm-cm\qv\armclang\qs_port.h + qs_port.h + 0 + 0 + + + 4 + 27 + 1 + 0 + 0 + 0 + ..\..\..\..\..\ports\arm-cm\qv\armclang\qv_port.c + qv_port.c + 0 + 0 + + + 4 + 28 + 5 + 0 + 0 + 0 + ..\..\..\..\..\ports\arm-cm\qv\armclang\qv_port.h + qv_port.h + 0 + 0 + + + + + QS + 1 + 0 + 0 + 0 + + 5 + 29 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qs\qs.c + qs.c + 0 + 0 + + + 5 + 30 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qs\qs_64bit.c + qs_64bit.c + 0 + 0 + + + 5 + 31 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qs\qs_fp.c + qs_fp.c + 0 + 0 + + + 5 + 32 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qs\qs_rx.c + qs_rx.c + 0 + 0 + + + 5 + 33 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qs\qstamp.c + qstamp.c + 0 + 0 + + + +
diff --git a/examples/arm-cm/dpp_nucleo-c031c6/qv/armclang/dpp-qv.uvprojx b/examples/arm-cm/dpp_nucleo-c031c6/qv/armclang/dpp-qv.uvprojx new file mode 100644 index 00000000..c7b2e9c8 --- /dev/null +++ b/examples/arm-cm/dpp_nucleo-c031c6/qv/armclang/dpp-qv.uvprojx @@ -0,0 +1,1853 @@ + + + + 2.1 + +
### uVision Project, (C) Keil Software
+ + + + dpp-dbg + 0x4 + ARM-ADS + 6160000::V6.16::ARMCLANG + 1 + + + STM32C031C6Tx + STMicroelectronics + Keil.STM32C0xx_DFP.1.0.0 + https://www.keil.com/pack/ + IRAM(0x20000000,0x00003000) IROM(0x08000000,0x00008000) CPUTYPE("Cortex-M0+") CLOCK(12000000) ELITTLE + + + UL2CM3(-S0 -C0 -P0 -FD20000000 -FC1000 -FN1 -FF0STM32C0x_32 -FS08000000 -FL08000 -FP0($$Device:STM32C031C6Tx$CMSIS\Flash\STM32C0x_32.FLM)) + 0 + $$Device:STM32C031C6Tx$Drivers\CMSIS\Device\ST\STM32C0xx\Include\stm32c0xx.h + + + + + + + + + + $$Device:STM32C031C6Tx$CMSIS\SVD\STM32C031.svd + 0 + 0 + + + + + + + 0 + 0 + 0 + 0 + 1 + + .\dbg\ + dpp-qv + 1 + 0 + 0 + 1 + 1 + .\dbg\ + 1 + 0 + 0 + + 0 + 0 + + + 0 + 0 + 0 + 0 + + + 1 + 0 + cmd /c "del .\dbg\qstamp.o" + + 0 + 0 + 0 + 0 + + + 1 + 0 + fromelf --bin --output .\dbg\dpp-qv.bin .\dbg\dpp-qv.axf + + 0 + 0 + 0 + 0 + + 0 + + + + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 3 + + + 1 + + + SARMCM3.DLL + -REMAP-MPU + DARMCM1.DLL + -pCM0+ + SARMCM3.DLL + -MPU + TARMCM1.DLL + -pCM0+ + + + + 1 + 0 + 0 + 0 + 16 + + + + + 1 + 0 + 0 + 1 + 1 + 4096 + + 1 + BIN\UL2CM3.DLL + "" () + + + + + 0 + + + + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + 1 + 0 + 0 + 0 + 0 + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + "Cortex-M0+" + + 0 + 0 + 0 + 1 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 8 + 0 + 0 + 0 + 0 + 3 + 3 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 1 + 0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x20000000 + 0x3000 + + + 1 + 0x8000000 + 0x8000 + + + 0 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x8000000 + 0x8000 + + + 1 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x20000000 + 0x3000 + + + 0 + 0x0 + 0x0 + + + + + + 0 + 1 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 3 + 0 + 1 + 0 + 0 + 0 + 3 + 3 + 0 + 0 + 0 + 0 + 0 + + + QF_ON_CONTEXT_SW + + ..\..;..\..\..\..\..\include;..\..\..\..\..\ports\arm-cm\qv\armclang;..\..\..\..\..\3rd_party\CMSIS\Include;..\..\..\..\..\3rd_party\nucleo-c031c6 + + + + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 4 + + + Stack_Size=2048 Heap_Size=16 + + + + + + 0 + 0 + 0 + 0 + 1 + 0 + 0x00000000 + 0x20000000 + + .\dpp-qv.sct + + + --entry Reset_Handler + + + + + + + + Source Code + + + bsp.c + 1 + ..\bsp.c + + + bsp.h + 5 + ..\..\bsp.h + + + dpp.h + 5 + ..\..\dpp.h + + + philo.c + 1 + ..\..\philo.c + + + table.c + 1 + ..\..\table.c + + + main.c + 1 + ..\..\main.c + + + + + nucleo-c031c6 + + + stm32c0xx.h + 5 + ..\..\..\..\..\3rd_party\nucleo-c031c6\stm32c0xx.h + + + stm32c031xx.h + 5 + ..\..\..\..\..\3rd_party\nucleo-c031c6\stm32c031xx.h + + + system_stm32c0xx.c + 1 + ..\..\..\..\..\3rd_party\nucleo-c031c6\system_stm32c0xx.c + + + startup_stm32c031xx.s + 2 + ..\..\..\..\..\3rd_party\nucleo-c031c6\arm\startup_stm32c031xx.s + + + + + QP + + + qep_hsm.c + 1 + ..\..\..\..\..\src\qf\qep_hsm.c + + + qep_msm.c + 1 + ..\..\..\..\..\src\qf\qep_msm.c + + + qf_act.c + 1 + ..\..\..\..\..\src\qf\qf_act.c + + + qf_actq.c + 1 + ..\..\..\..\..\src\qf\qf_actq.c + + + qf_defer.c + 1 + ..\..\..\..\..\src\qf\qf_defer.c + + + qf_dyn.c + 1 + ..\..\..\..\..\src\qf\qf_dyn.c + + + qf_mem.c + 1 + ..\..\..\..\..\src\qf\qf_mem.c + + + qf_ps.c + 1 + ..\..\..\..\..\src\qf\qf_ps.c + + + qf_qact.c + 1 + ..\..\..\..\..\src\qf\qf_qact.c + + + qf_qeq.c + 1 + ..\..\..\..\..\src\qf\qf_qeq.c + + + qf_qmact.c + 1 + ..\..\..\..\..\src\qf\qf_qmact.c + + + qf_time.c + 1 + ..\..\..\..\..\src\qf\qf_time.c + + + qv.c + 1 + ..\..\..\..\..\src\qv\qv.c + + + + + QP_port + + + qep_port.h + 5 + ..\..\..\..\..\ports\arm-cm\qv\armclang\qep_port.h + + + qf_port.h + 5 + ..\..\..\..\..\ports\arm-cm\qv\armclang\qf_port.h + + + qs_port.h + 5 + ..\..\..\..\..\ports\arm-cm\qv\armclang\qs_port.h + + + qv_port.c + 1 + ..\..\..\..\..\ports\arm-cm\qv\armclang\qv_port.c + + + qv_port.h + 5 + ..\..\..\..\..\ports\arm-cm\qv\armclang\qv_port.h + + + + + QS + + + 0 + 0 + 0 + 0 + 0 + 0 + 2 + 2 + 2 + 2 + 11 + + + 1 + + + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 0 + 0 + 0 + 0 + 2 + + + + + + + + + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + + + + + + + + + + + + qs.c + 1 + ..\..\..\..\..\src\qs\qs.c + + + qs_64bit.c + 1 + ..\..\..\..\..\src\qs\qs_64bit.c + + + qs_fp.c + 1 + ..\..\..\..\..\src\qs\qs_fp.c + + + qs_rx.c + 1 + ..\..\..\..\..\src\qs\qs_rx.c + + + qstamp.c + 1 + ..\..\..\..\..\src\qs\qstamp.c + + + + + + + dpp-rel + 0x4 + ARM-ADS + 6160000::V6.16::ARMCLANG + 1 + + + STM32C031C6Tx + STMicroelectronics + Keil.STM32C0xx_DFP.1.0.0 + https://www.keil.com/pack/ + IRAM(0x20000000,0x00003000) IROM(0x08000000,0x00008000) CPUTYPE("Cortex-M0+") CLOCK(12000000) ELITTLE + + + UL2CM3(-S0 -C0 -P0 -FD20000000 -FC1000 -FN1 -FF0STM32C0x_32 -FS08000000 -FL08000 -FP0($$Device:STM32C031C6Tx$CMSIS\Flash\STM32C0x_32.FLM)) + 0 + $$Device:STM32C031C6Tx$Drivers\CMSIS\Device\ST\STM32C0xx\Include\stm32c0xx.h + + + + + + + + + + $$Device:STM32C031C6Tx$CMSIS\SVD\STM32C031.svd + 0 + 0 + + + + + + + 0 + 0 + 0 + 0 + 1 + + .\rel\ + dpp-qv + 1 + 0 + 0 + 0 + 0 + .\rel\ + 1 + 0 + 0 + + 0 + 0 + + + 0 + 0 + 0 + 0 + + + 1 + 0 + cmd /c "del .\rel\qstamp.o" + + 0 + 0 + 0 + 0 + + + 1 + 0 + fromelf --bin --output .\rel\dpp-qv.bin .\rel\dpp-qv.axf + + 0 + 0 + 0 + 0 + + 0 + + + + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 3 + + + 1 + + + SARMCM3.DLL + -REMAP-MPU + DARMCM1.DLL + -pCM0+ + SARMCM3.DLL + -MPU + TARMCM1.DLL + -pCM0+ + + + + 1 + 0 + 0 + 0 + 16 + + + + + 1 + 0 + 0 + 1 + 1 + 4097 + + 1 + BIN\UL2CM3.DLL + + + + + + 0 + + + + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + 1 + 0 + 0 + 0 + 0 + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + "Cortex-M0+" + + 0 + 0 + 0 + 1 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 8 + 0 + 0 + 0 + 0 + 3 + 3 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 1 + 0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x20000000 + 0x3000 + + + 1 + 0x8000000 + 0x8000 + + + 0 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x8000000 + 0x8000 + + + 1 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x20000000 + 0x3000 + + + 0 + 0x0 + 0x0 + + + + + + 0 + 6 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 3 + 0 + 1 + 0 + 0 + 0 + 3 + 3 + 0 + 0 + 0 + 0 + 0 + + + NDEBUG,QF_ON_CONTEXT_SW + + ..\..;..\..\..\..\..\include;..\..\..\..\..\ports\arm-cm\qv\armclang;..\..\..\..\..\3rd_party\CMSIS\Include;..\..\..\..\..\3rd_party\nucleo-c031c6 + + + + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 4 + + + Stack_Size=2048 Heap_Size=16 + + + + + + 0 + 0 + 0 + 0 + 1 + 0 + 0x00000000 + 0x20000000 + + .\dpp-qv.sct + + + --entry Reset_Handler + + + + + + + + Source Code + + + bsp.c + 1 + ..\bsp.c + + + bsp.h + 5 + ..\..\bsp.h + + + dpp.h + 5 + ..\..\dpp.h + + + philo.c + 1 + ..\..\philo.c + + + table.c + 1 + ..\..\table.c + + + main.c + 1 + ..\..\main.c + + + + + nucleo-c031c6 + + + stm32c0xx.h + 5 + ..\..\..\..\..\3rd_party\nucleo-c031c6\stm32c0xx.h + + + stm32c031xx.h + 5 + ..\..\..\..\..\3rd_party\nucleo-c031c6\stm32c031xx.h + + + system_stm32c0xx.c + 1 + ..\..\..\..\..\3rd_party\nucleo-c031c6\system_stm32c0xx.c + + + startup_stm32c031xx.s + 2 + ..\..\..\..\..\3rd_party\nucleo-c031c6\arm\startup_stm32c031xx.s + + + + + QP + + + qep_hsm.c + 1 + ..\..\..\..\..\src\qf\qep_hsm.c + + + qep_msm.c + 1 + ..\..\..\..\..\src\qf\qep_msm.c + + + qf_act.c + 1 + ..\..\..\..\..\src\qf\qf_act.c + + + qf_actq.c + 1 + ..\..\..\..\..\src\qf\qf_actq.c + + + qf_defer.c + 1 + ..\..\..\..\..\src\qf\qf_defer.c + + + qf_dyn.c + 1 + ..\..\..\..\..\src\qf\qf_dyn.c + + + qf_mem.c + 1 + ..\..\..\..\..\src\qf\qf_mem.c + + + qf_ps.c + 1 + ..\..\..\..\..\src\qf\qf_ps.c + + + qf_qact.c + 1 + ..\..\..\..\..\src\qf\qf_qact.c + + + qf_qeq.c + 1 + ..\..\..\..\..\src\qf\qf_qeq.c + + + qf_qmact.c + 1 + ..\..\..\..\..\src\qf\qf_qmact.c + + + qf_time.c + 1 + ..\..\..\..\..\src\qf\qf_time.c + + + qv.c + 1 + ..\..\..\..\..\src\qv\qv.c + + + + + QP_port + + + qep_port.h + 5 + ..\..\..\..\..\ports\arm-cm\qv\armclang\qep_port.h + + + qf_port.h + 5 + ..\..\..\..\..\ports\arm-cm\qv\armclang\qf_port.h + + + qs_port.h + 5 + ..\..\..\..\..\ports\arm-cm\qv\armclang\qs_port.h + + + qv_port.c + 1 + ..\..\..\..\..\ports\arm-cm\qv\armclang\qv_port.c + + + qv_port.h + 5 + ..\..\..\..\..\ports\arm-cm\qv\armclang\qv_port.h + + + + + QS + + + 0 + 0 + 0 + 0 + 0 + 0 + 2 + 2 + 2 + 2 + 11 + + + 1 + + + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 0 + 0 + 0 + 0 + 2 + + + + + + + + + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + + + + + + + + + + + + qs.c + 1 + ..\..\..\..\..\src\qs\qs.c + + + qs_64bit.c + 1 + ..\..\..\..\..\src\qs\qs_64bit.c + + + qs_fp.c + 1 + ..\..\..\..\..\src\qs\qs_fp.c + + + qs_rx.c + 1 + ..\..\..\..\..\src\qs\qs_rx.c + + + qstamp.c + 1 + ..\..\..\..\..\src\qs\qstamp.c + + + + + + + dpp-spy + 0x4 + ARM-ADS + 6160000::V6.16::ARMCLANG + 1 + + + STM32C031C6Tx + STMicroelectronics + Keil.STM32C0xx_DFP.1.0.0 + https://www.keil.com/pack/ + IRAM(0x20000000,0x00003000) IROM(0x08000000,0x00008000) CPUTYPE("Cortex-M0+") CLOCK(12000000) ELITTLE + + + UL2CM3(-S0 -C0 -P0 -FD20000000 -FC1000 -FN1 -FF0STM32C0x_32 -FS08000000 -FL08000 -FP0($$Device:STM32C031C6Tx$CMSIS\Flash\STM32C0x_32.FLM)) + 0 + $$Device:STM32C031C6Tx$Drivers\CMSIS\Device\ST\STM32C0xx\Include\stm32c0xx.h + + + + + + + + + + $$Device:STM32C031C6Tx$CMSIS\SVD\STM32C031.svd + 0 + 0 + + + + + + + 0 + 0 + 0 + 0 + 1 + + .\spy\ + dpp-qv + 1 + 0 + 0 + 1 + 1 + .\spy\ + 1 + 0 + 0 + + 0 + 0 + + + 0 + 0 + 0 + 0 + + + 1 + 0 + cmd /c "del .\spy\qstamp.o" + + 0 + 0 + 0 + 0 + + + 1 + 0 + fromelf --bin --output .\spy\dpp-qv.bin .\spy\dpp-qv.axf + + 0 + 0 + 0 + 0 + + 0 + + + + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 3 + + + 1 + + + SARMCM3.DLL + -REMAP-MPU + DARMCM1.DLL + -pCM0+ + SARMCM3.DLL + -MPU + TARMCM1.DLL + -pCM0+ + + + + 1 + 0 + 0 + 0 + 16 + + + + + 1 + 0 + 0 + 1 + 1 + 4096 + + 1 + BIN\UL2CM3.DLL + + + + + + 0 + + + + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + 1 + 0 + 0 + 0 + 0 + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + "Cortex-M0+" + + 0 + 0 + 0 + 1 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 8 + 0 + 0 + 0 + 0 + 3 + 3 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 1 + 0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x20000000 + 0x3000 + + + 1 + 0x8000000 + 0x8000 + + + 0 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x8000000 + 0x8000 + + + 1 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x20000000 + 0x3000 + + + 0 + 0x0 + 0x0 + + + + + + 0 + 2 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 3 + 0 + 1 + 0 + 0 + 0 + 3 + 3 + 0 + 0 + 0 + 0 + 0 + + + Q_SPY,QF_ON_CONTEXT_SW + + ..\..;..\..\..\..\..\include;..\..\..\..\..\ports\arm-cm\qv\armclang;..\..\..\..\..\3rd_party\CMSIS\Include;..\..\..\..\..\3rd_party\nucleo-c031c6 + + + + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 4 + + + Stack_Size=2048 Heap_Size=16 + + + + + + 0 + 0 + 0 + 0 + 1 + 0 + 0x00000000 + 0x20000000 + + .\dpp-qv.sct + + + --entry Reset_Handler + + + + + + + + Source Code + + + bsp.c + 1 + ..\bsp.c + + + bsp.h + 5 + ..\..\bsp.h + + + dpp.h + 5 + ..\..\dpp.h + + + philo.c + 1 + ..\..\philo.c + + + table.c + 1 + ..\..\table.c + + + main.c + 1 + ..\..\main.c + + + + + nucleo-c031c6 + + + stm32c0xx.h + 5 + ..\..\..\..\..\3rd_party\nucleo-c031c6\stm32c0xx.h + + + stm32c031xx.h + 5 + ..\..\..\..\..\3rd_party\nucleo-c031c6\stm32c031xx.h + + + system_stm32c0xx.c + 1 + ..\..\..\..\..\3rd_party\nucleo-c031c6\system_stm32c0xx.c + + + startup_stm32c031xx.s + 2 + ..\..\..\..\..\3rd_party\nucleo-c031c6\arm\startup_stm32c031xx.s + + + + + QP + + + qep_hsm.c + 1 + ..\..\..\..\..\src\qf\qep_hsm.c + + + qep_msm.c + 1 + ..\..\..\..\..\src\qf\qep_msm.c + + + qf_act.c + 1 + ..\..\..\..\..\src\qf\qf_act.c + + + qf_actq.c + 1 + ..\..\..\..\..\src\qf\qf_actq.c + + + qf_defer.c + 1 + ..\..\..\..\..\src\qf\qf_defer.c + + + qf_dyn.c + 1 + ..\..\..\..\..\src\qf\qf_dyn.c + + + qf_mem.c + 1 + ..\..\..\..\..\src\qf\qf_mem.c + + + qf_ps.c + 1 + ..\..\..\..\..\src\qf\qf_ps.c + + + qf_qact.c + 1 + ..\..\..\..\..\src\qf\qf_qact.c + + + qf_qeq.c + 1 + ..\..\..\..\..\src\qf\qf_qeq.c + + + qf_qmact.c + 1 + ..\..\..\..\..\src\qf\qf_qmact.c + + + qf_time.c + 1 + ..\..\..\..\..\src\qf\qf_time.c + + + qv.c + 1 + ..\..\..\..\..\src\qv\qv.c + + + + + QP_port + + + qep_port.h + 5 + ..\..\..\..\..\ports\arm-cm\qv\armclang\qep_port.h + + + qf_port.h + 5 + ..\..\..\..\..\ports\arm-cm\qv\armclang\qf_port.h + + + qs_port.h + 5 + ..\..\..\..\..\ports\arm-cm\qv\armclang\qs_port.h + + + qv_port.c + 1 + ..\..\..\..\..\ports\arm-cm\qv\armclang\qv_port.c + + + qv_port.h + 5 + ..\..\..\..\..\ports\arm-cm\qv\armclang\qv_port.h + + + + + QS + + + qs.c + 1 + ..\..\..\..\..\src\qs\qs.c + + + qs_64bit.c + 1 + ..\..\..\..\..\src\qs\qs_64bit.c + + + qs_fp.c + 1 + ..\..\..\..\..\src\qs\qs_fp.c + + + qs_rx.c + 1 + ..\..\..\..\..\src\qs\qs_rx.c + + + qstamp.c + 1 + ..\..\..\..\..\src\qs\qstamp.c + + + + + + + + + + + + + +
diff --git a/examples/arm-cm/dpp_nucleo-c031c6/qv/bsp.c b/examples/arm-cm/dpp_nucleo-c031c6/qv/bsp.c new file mode 100644 index 00000000..4a46e8d4 --- /dev/null +++ b/examples/arm-cm/dpp_nucleo-c031c6/qv/bsp.c @@ -0,0 +1,539 @@ +//============================================================================ +// Product: DPP example, NUCLEO-C031C6 board, QV kernel +// Last updated for version 7.3.0 +// Last updated on 2023-08-23 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. +// +// This program is open source software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Alternatively, this program may be distributed and modified under the +// terms of Quantum Leaps commercial licenses, which expressly supersede +// the GNU General Public License and are specifically designed for +// licensees interested in retaining the proprietary status of their code. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Contact information: +// +// +//============================================================================ +#include "qpc.h" // QP/C real-time embedded framework +#include "dpp.h" // DPP Application interface +#include "bsp.h" // Board Support Package + +#include "stm32c0xx.h" // CMSIS-compliant header file for the MCU used +// add other drivers if necessary... + +Q_DEFINE_THIS_FILE // define the name of this file for assertions + +// Local-scope defines ----------------------------------------------------- +// LED pins available on the board (just one user LED LD4--Green on PA.5) +#define LD4_PIN 5U + +// Button pins available on the board (just one user Button B1 on PC.13) +#define B1_PIN 13U + +// Local-scope objects ----------------------------------------------------- +static uint32_t l_rndSeed; + +#ifdef Q_SPY + + QSTimeCtr QS_tickTime_; + QSTimeCtr QS_tickPeriod_; + + // QSpy source IDs + static QSpyId const l_SysTick_Handler = { 0U }; + static QSpyId const l_EXTI0_1_IRQHandler = { 0U }; + + enum AppRecords { // application-specific trace records + PHILO_STAT = QS_USER, + PAUSED_STAT, + CONTEXT_SW, + }; + +#endif + +//============================================================================ +// Error handler and ISRs... + +Q_NORETURN Q_onError(char const * const module, int_t const id) { + // NOTE: this implementation of the assertion handler is intended only + // for debugging and MUST be changed for deployment of the application + // (assuming that you ship your production code with assertions enabled). + Q_UNUSED_PAR(module); + Q_UNUSED_PAR(id); + QS_ASSERTION(module, id, 10000U); + +#ifndef NDEBUG + // light up the user LED + GPIOA->BSRR = (1U << LD4_PIN); // turn LED on + // for debugging, hang on in an endless loop... + for (;;) { + } +#endif + + NVIC_SystemReset(); +} +//............................................................................ +void assert_failed(char const * const module, int_t const id); // prototype +void assert_failed(char const * const module, int_t const id) { + Q_onError(module, id); +} + +// ISRs used in the application ============================================ + +void SysTick_Handler(void); // prototype +void SysTick_Handler(void) { + + QTIMEEVT_TICK_X(0U, &l_SysTick_Handler); // time events at rate 0 + + // Perform the debouncing of buttons. The algorithm for debouncing + // adapted from the book "Embedded Systems Dictionary" by Jack Ganssle + // and Michael Barr, page 71. + static struct { + uint32_t depressed; + uint32_t previous; + } buttons = { 0U, 0U }; + + uint32_t current = ~GPIOC->IDR; // read Port C with state of Button B1 + uint32_t tmp = buttons.depressed; // save the depressed buttons + buttons.depressed |= (buttons.previous & current); // set depressed + buttons.depressed &= (buttons.previous | current); // clear released + buttons.previous = current; // update the history + tmp ^= buttons.depressed; // changed debounced depressed + current = buttons.depressed; + + if ((tmp & (1U << B1_PIN)) != 0U) { // debounced B1 state changed? + if ((current & (1U << B1_PIN)) != 0U) { // is B1 depressed? + static QEvt const pauseEvt = QEVT_INITIALIZER(PAUSE_SIG); + QACTIVE_PUBLISH(&pauseEvt, &l_SysTick_Handler); + } + else { // the button is released + static QEvt const serveEvt = QEVT_INITIALIZER(SERVE_SIG); + QACTIVE_PUBLISH(&serveEvt, &l_SysTick_Handler); + } + } + +#ifdef Q_SPY + tmp = SysTick->CTRL; // clear CTRL_COUNTFLAG + QS_tickTime_ += QS_tickPeriod_; // account for the clock rollover +#endif + + QV_ARM_ERRATUM_838869(); +} +//............................................................................ +// interrupt handler for testing preemptions in QV +void EXTI0_1_IRQHandler(void); // prototype +void EXTI0_1_IRQHandler(void) { + + // for testing.. + static QEvt const testEvt = QEVT_INITIALIZER(TEST_SIG); + QACTIVE_POST(AO_Table, &testEvt, &l_EXTI0_1_IRQHandler); + + QV_ARM_ERRATUM_838869(); +} + +//............................................................................ +#ifdef Q_SPY +// ISR for receiving bytes from the QSPY Back-End +// NOTE: This ISR is "QF-unaware" meaning that it does not interact with +// the QF/QV and is not disabled. Such ISRs cannot post or publish events. + +void USART2_IRQHandler(void); // prototype +void USART2_IRQHandler(void) { // used in QS-RX (kernel UNAWARE interrutp) + // is RX register NOT empty? + if ((USART2->ISR & (1U << 5U)) != 0U) { + uint32_t b = USART2->RDR; + QS_RX_PUT(b); + } + + QV_ARM_ERRATUM_838869(); +} +#endif // Q_SPY + +//............................................................................ +#ifdef QF_ON_CONTEXT_SW +// NOTE: the context-switch callback is called with interrupts DISABLED +void QF_onContextSw(QActive *prev, QActive *next) { + QS_BEGIN_INCRIT(CONTEXT_SW, 0U) // in critical section! + QS_OBJ(prev); + QS_OBJ(next); + QS_END_INCRIT() +} +#endif // QF_ON_CONTEXT_SW + + +//============================================================================ +// BSP functions... + +void BSP_init(void) { + // Configure the MPU to prevent NULL-pointer dereferencing ... + MPU->RBAR = 0x0U // base address (NULL) + | MPU_RBAR_VALID_Msk // valid region + | (MPU_RBAR_REGION_Msk & 7U); // region #7 + MPU->RASR = (7U << MPU_RASR_SIZE_Pos) // 2^(7+1) region + | (0x0U << MPU_RASR_AP_Pos) // no-access region + | MPU_RASR_ENABLE_Msk; // region enable + MPU->CTRL = MPU_CTRL_PRIVDEFENA_Msk // enable background region + | MPU_CTRL_ENABLE_Msk; // enable the MPU + __ISB(); + __DSB(); + + // NOTE: SystemInit() has been already called from the startup code + // but SystemCoreClock needs to be updated + SystemCoreClockUpdate(); + + // enable GPIOA clock port for the LED LD4 + RCC->IOPENR |= (1U << 0U); + + // set all used GPIOA pins as push-pull output, no pull-up, pull-down + GPIOA->MODER &= ~(3U << 2U*LD4_PIN); + GPIOA->MODER |= (1U << 2U*LD4_PIN); + GPIOA->OTYPER &= ~(1U << LD4_PIN); + GPIOA->OSPEEDR &= ~(3U << 2U*LD4_PIN); + GPIOA->OSPEEDR |= (1U << 2U*LD4_PIN); + GPIOA->PUPDR &= ~(3U << 2U*LD4_PIN); + + // enable GPIOC clock port for the Button B1 + RCC->IOPENR |= (1U << 2U); + + // configure Button B1 pin on GPIOC as input, no pull-up, pull-down + GPIOC->MODER &= ~(3U << 2U*B1_PIN); + GPIOC->PUPDR &= ~(3U << 2U*B1_PIN); + + BSP_randomSeed(1234U); // seed the random number generator + + // initialize the QS software tracing... + if (!QS_INIT((void *)0)) { + Q_ERROR(); + } + + // dictionaries... + QS_OBJ_DICTIONARY(&l_SysTick_Handler); + QS_USR_DICTIONARY(PHILO_STAT); + QS_USR_DICTIONARY(PAUSED_STAT); + QS_USR_DICTIONARY(CONTEXT_SW); + + QS_ONLY(produce_sig_dict()); + + // setup the QS filters... + QS_GLB_FILTER(QS_ALL_RECORDS); // all records + QS_GLB_FILTER(-QS_QF_TICK); // exclude the clock tick +} +//............................................................................ +void BSP_start(void) { + // initialize event pools + static QF_MPOOL_EL(TableEvt) smlPoolSto[2*N_PHILO]; + QF_poolInit(smlPoolSto, sizeof(smlPoolSto), sizeof(smlPoolSto[0])); + + // initialize publish-subscribe + static QSubscrList subscrSto[MAX_PUB_SIG]; + QActive_psInit(subscrSto, Q_DIM(subscrSto)); + + // instantiate and start AOs/threads... + + static QEvt const *philoQueueSto[N_PHILO][10]; + for (uint8_t n = 0U; n < N_PHILO; ++n) { + Philo_ctor(n); + QACTIVE_START(AO_Philo[n], + n + 3U, // QF-prio. + philoQueueSto[n], // event queue storage + Q_DIM(philoQueueSto[n]), // queue length [events] + (void *)0, 0U, // no stack storage + (void *)0); // no initialization param + } + + static QEvt const *tableQueueSto[N_PHILO]; + Table_ctor(); + QACTIVE_START(AO_Table, + N_PHILO + 7U, // QP prio. of the AO + tableQueueSto, // event queue storage + Q_DIM(tableQueueSto), // queue length [events] + (void *)0, 0U, // no stack storage + (void *)0); // no initialization param +} +//............................................................................ +void BSP_displayPhilStat(uint8_t n, char const *stat) { + Q_UNUSED_PAR(n); + + if (stat[0] == 'e') { + GPIOA->BSRR = (1U << LD4_PIN); // turn LED on + } + else { + GPIOA->BSRR = (1U << (LD4_PIN + 16U)); // turn LED off + } + + // app-specific trace record... + QS_BEGIN_ID(PHILO_STAT, AO_Table->prio) + QS_U8(1, n); // Philosopher number + QS_STR(stat); // Philosopher status + QS_END() +} +//............................................................................ +void BSP_displayPaused(uint8_t const paused) { + // not enough LEDs to implement this feature + if (paused != 0U) { + //GPIOA->BSRR = (1U << LD4_PIN); // turn LED[n] on + } + else { + //GPIOA->BSRR = (1U << (LD4_PIN + 16U)); // turn LED[n] off + } + + // application-specific trace record + QS_BEGIN_ID(PAUSED_STAT, AO_Table->prio) + QS_U8(1, paused); // Paused status + QS_END() +} +//............................................................................ +void BSP_randomSeed(uint32_t seed) { + l_rndSeed = seed; +} +//............................................................................ +uint32_t BSP_random(void) { // a very cheap pseudo-random-number generator + + // "Super-Duper" Linear Congruential Generator (LCG) + // LCG(2^32, 3*7*11*13*23, 0, seed) + // + uint32_t rnd = l_rndSeed * (3U*7U*11U*13U*23U); + l_rndSeed = rnd; // set for the next time + + return (rnd >> 8U); +} +//............................................................................ +void BSP_ledOn(void) { + GPIOA->BSRR = (1U << LD4_PIN); // turn LED on +} +//............................................................................ +void BSP_ledOff(void) { + GPIOA->BSRR = (1U << (LD4_PIN + 16U)); // turn LED off +} +//............................................................................ +void BSP_terminate(int16_t result) { + Q_UNUSED_PAR(result); +} + +//============================================================================ +// QF callbacks... +void QF_onStartup(void) { + // set up the SysTick timer to fire at BSP_TICKS_PER_SEC rate + SysTick_Config(SystemCoreClock / BSP_TICKS_PER_SEC); + + // assign all priority bits for preemption-prio. and none to sub-prio. + // NOTE: this might have been changed by STM32Cube. + NVIC_SetPriorityGrouping(0U); + + // set priorities of ALL ISRs used in the system, see NOTE1 + NVIC_SetPriority(USART2_IRQn, 0U); // kernel UNAWARE interrupt + NVIC_SetPriority(EXTI0_1_IRQn, QF_AWARE_ISR_CMSIS_PRI + 0U); + NVIC_SetPriority(SysTick_IRQn, QF_AWARE_ISR_CMSIS_PRI + 1U); + // ... + + // enable IRQs... + NVIC_EnableIRQ(EXTI0_1_IRQn); + +#ifdef Q_SPY + NVIC_EnableIRQ(USART2_IRQn); // UART2 interrupt used for QS-RX +#endif +} +//............................................................................ +void QF_onCleanup(void) { +} +//............................................................................ +void QV_onIdle(void) { // CATION: called with interrupts DISABLED, see NOTE0 + + // toggle an LED on and then off (not enough LEDs, see NOTE02) + //GPIOA->BSRR = (1U << LD4_PIN); // turn LED[n] on + //GPIOA->BSRR = (1U << (LD4_PIN + 16U)); // turn LED[n] off + +#ifdef Q_SPY + // interrupts still disabled + QS_rxParse(); // parse all the received bytes + QF_INT_ENABLE(); + + if ((USART2->ISR & (1U << 7U)) != 0U) { // is TXE empty? + QF_INT_DISABLE(); + uint16_t b = QS_getByte(); + QF_INT_ENABLE(); + + if (b != QS_EOD) { // not End-Of-Data? + USART2->TDR = b; // put into the DR register + } + } +#elif defined NDEBUG + // Put the CPU and peripherals to the low-power mode. + // you might need to customize the clock management for your application, + // see the datasheet for your particular Cortex-M MCU. + // + // !!!CAUTION!!! + // QV_CPU_SLEEP() contains the WFI instruction, which stops the CPU + // clock, which unfortunately disables the JTAG port, so the ST-Link + // debugger can no longer connect to the board. For that reason, the call + // to QV_CPU_SLEEP() has to be used with CAUTION. + // + // NOTE: If you find your board "frozen" like this, strap BOOT0 to VDD and + // reset the board, then connect with ST-Link Utilities and erase the part. + // The trick with BOOT(0) is it gets the part to run the System Loader + // instead of your broken code. When done disconnect BOOT0, and start over. + // + //QV_CPU_SLEEP(); // atomically go to sleep and enable interrupts + QF_INT_ENABLE(); // for now, just enable interrupts +#else + QF_INT_ENABLE(); // just enable interrupts +#endif +} + +//============================================================================ +// QS callbacks... +#ifdef Q_SPY + +//............................................................................ +static uint16_t const UARTPrescTable[12] = { + 1U, 2U, 4U, 6U, 8U, 10U, 12U, 16U, 32U, 64U, 128U, 256U +}; + +#define UART_DIV_SAMPLING16(__PCLK__, __BAUD__, __CLOCKPRESCALER__) \ + ((((__PCLK__)/UARTPrescTable[(__CLOCKPRESCALER__)]) \ + + ((__BAUD__)/2U)) / (__BAUD__)) + +#define UART_PRESCALER_DIV1 0U + +// USART2 pins PA.2 and PA.3 +#define USART2_TX_PIN 2U +#define USART2_RX_PIN 3U + +//............................................................................ +uint8_t QS_onStartup(void const *arg) { + Q_UNUSED_PAR(arg); + + static uint8_t qsTxBuf[2*1024]; // buffer for QS-TX channel + QS_initBuf(qsTxBuf, sizeof(qsTxBuf)); + + static uint8_t qsRxBuf[100]; // buffer for QS-RX channel + QS_rxInitBuf(qsRxBuf, sizeof(qsRxBuf)); + + // enable peripheral clock for USART2 + RCC->IOPENR |= ( 1U << 0U); // Enable GPIOA clock for USART pins + RCC->APBENR1 |= ( 1U << 17U); // Enable USART#2 clock + + // Configure PA to USART2_RX, PA to USART2_TX + GPIOA->AFR[0] &= ~((15U << 4U*USART2_RX_PIN) | (15U << 4U*USART2_TX_PIN)); + GPIOA->AFR[0] |= (( 1U << 4U*USART2_RX_PIN) | ( 1U << 4U*USART2_TX_PIN)); + GPIOA->MODER &= ~(( 3U << 2U*USART2_RX_PIN) | ( 3U << 2U*USART2_TX_PIN)); + GPIOA->MODER |= (( 2U << 2U*USART2_RX_PIN) | ( 2U << 2U*USART2_TX_PIN)); + + // baud rate + USART2->BRR = UART_DIV_SAMPLING16( + SystemCoreClock, 115200U, UART_PRESCALER_DIV1); + USART2->CR3 = 0x0000U | // no flow control + (1U << 12U); // disable overrun detection (OVRDIS) + USART2->CR2 = 0x0000U; // 1 stop bit + USART2->CR1 = ((1U << 2U) | // enable RX + (1U << 3U) | // enable TX + (1U << 5U) | // enable RX interrupt + (0U << 12U) | // 8 data bits + (0U << 28U) | // 8 data bits + (1U << 0U)); // enable USART + + QS_tickPeriod_ = SystemCoreClock / BSP_TICKS_PER_SEC; + QS_tickTime_ = QS_tickPeriod_; // to start the timestamp at zero + + return 1U; // return success +} +//............................................................................ +void QS_onCleanup(void) { +} +//............................................................................ +QSTimeCtr QS_onGetTime(void) { // NOTE: invoked with interrupts DISABLED + if ((SysTick->CTRL & 0x00010000U) == 0U) { // not set? + return QS_tickTime_ - (QSTimeCtr)SysTick->VAL; + } + else { // the rollover occured, but the SysTick_ISR did not run yet + return QS_tickTime_ + QS_tickPeriod_ - (QSTimeCtr)SysTick->VAL; + } +} +//............................................................................ +void QS_onFlush(void) { + for (;;) { + QF_INT_DISABLE(); + uint16_t b = QS_getByte(); + if (b != QS_EOD) { + while ((USART2->ISR & (1U << 7U)) == 0U) { // while TXE not empty + QF_INT_ENABLE(); + QF_CRIT_EXIT_NOP(); + + QF_INT_DISABLE(); + } + USART2->TDR = b; // put into the DR register + QF_INT_ENABLE(); + } + else { + QF_INT_ENABLE(); + break; + } + } +} +//............................................................................ +//! callback function to reset the target (to be implemented in the BSP) +void QS_onReset(void) { + NVIC_SystemReset(); +} +//............................................................................ +// callback function to execute a user command +void QS_onCommand(uint8_t cmdId, + uint32_t param1, uint32_t param2, uint32_t param3) +{ + Q_UNUSED_PAR(cmdId); + Q_UNUSED_PAR(param1); + Q_UNUSED_PAR(param2); + Q_UNUSED_PAR(param3); +} + +#endif // Q_SPY +//---------------------------------------------------------------------------- + +//============================================================================ +// NOTE0: +// The QV_onIdle() callback is called with interrupts disabled, because the +// determination of the idle condition might change by any interrupt posting +// an event. QV_onIdle() must internally enable interrupts, ideally +// atomically with putting the CPU to the power-saving mode. +// +// NOTE1: +// The QF_AWARE_ISR_CMSIS_PRI constant from the QF port specifies the highest +// ISR priority that is disabled by the QF framework. The value is suitable +// for the NVIC_SetPriority() CMSIS function. +// +// Only ISRs prioritized at or below the QF_AWARE_ISR_CMSIS_PRI level (i.e., +// with the numerical values of priorities equal or higher than +// QF_AWARE_ISR_CMSIS_PRI) are allowed to call the QV_ISR_ENTRY/ +// QV_ISR_ENTRY macros or any other QF/QV services. These ISRs are +// "QF-aware". +// +// Conversely, any ISRs prioritized above the QF_AWARE_ISR_CMSIS_PRI priority +// level (i.e., with the numerical values of priorities less than +// QF_AWARE_ISR_CMSIS_PRI) are never disabled and are not aware of the kernel. +// Such "QF-unaware" ISRs cannot call ANY QF/QV services. In particular they +// can NOT call the macros QV_ISR_ENTRY/QV_ISR_ENTRY. The only mechanism +// by which a "QF-unaware" ISR can communicate with the QF framework is by +// triggering a "QF-aware" ISR, which can post/publish events. +// +// NOTE2: +// The User LED is used to visualize the idle loop activity. The brightness +// of the LED is proportional to the frequency of the idle loop. +// Please note that the LED is toggled with interrupts locked, so no interrupt +// execution time contributes to the brightness of the User LED. +// diff --git a/examples/arm-cm/dpp_nucleo-c031c6/qv/gnu/Makefile b/examples/arm-cm/dpp_nucleo-c031c6/qv/gnu/Makefile new file mode 100644 index 00000000..c56a8b35 --- /dev/null +++ b/examples/arm-cm/dpp_nucleo-c031c6/qv/gnu/Makefile @@ -0,0 +1,315 @@ +############################################################################## +# Product: Makefile for QP/C on NUCLEO-C031C6, QV kernel, GNU-ARM +# Last Updated for Version: 7.3.0 +# Date of the Last Update: 2023-05-26 +# +# Q u a n t u m L e a P s +# ------------------------ +# Modern Embedded Software +# +# Copyright (C) 2005 Quantum Leaps, LLC. +# +# This program is open source software: you can redistribute it and/or +# modify it under the terms of the GNU General Public License as published +# by the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Alternatively, this program may be distributed and modified under the +# terms of Quantum Leaps commercial licenses, which expressly supersede +# the GNU General Public License and are specifically designed for +# licensees interested in retaining the proprietary status of their code. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# +# Contact information: +# +# +############################################################################## +# examples of invoking this Makefile: +# building configurations: Debug (default), Release, and Spy +# make +# make CONF=rel +# make CONF=spy +# +# cleaning configurations: Debug (default), Release, and Spy +# make clean +# make CONF=rel clean +# make CONF=spy clean +# +# NOTE: +# To use this Makefile on Windows, you will need the GNU make utility, which +# is included in the Qtools collection for Windows, see: +# https://github.com/QuantumLeaps/qtools + +#----------------------------------------------------------------------------- +# project name +# +PROJECT := dpp-qv + +#----------------------------------------------------------------------------- +# project directories +# + +# location of the QP/C framework (if not provided in an environemnt var.) +ifeq ($(QPC),) +QPC := ../../../../.. +endif + +# QP port used in this project +QP_PORT_DIR := $(QPC)/ports/arm-cm/qv/gnu + +# list of all source directories used by this project +VPATH = \ + .. \ + ../.. \ + $(QPC)/src/qf \ + $(QPC)/src/qv \ + $(QPC)/src/qs \ + $(QP_PORT_DIR) \ + $(QPC)/3rd_party/nucleo-c031c6 \ + $(QPC)/3rd_party/nucleo-c031c6/gnu + +# list of all include directories needed by this project +INCLUDES = \ + -I../.. \ + -I$(QPC)/include \ + -I$(QP_PORT_DIR) \ + -I$(QPC)/3rd_party/CMSIS/Include \ + -I$(QPC)/3rd_party/nucleo-c031c6 + +#----------------------------------------------------------------------------- +# files +# + +# assembler source files +ASM_SRCS := + +# C source files +C_SRCS := \ + bsp.c \ + main.c \ + philo.c \ + table.c \ + system_stm32c0xx.c \ + startup_stm32c031xx.c + +# C++ source files +CPP_SRCS := + +OUTPUT := $(PROJECT) +LD_SCRIPT := $(PROJECT).ld + +QP_SRCS := \ + qep_hsm.c \ + qep_msm.c \ + qf_act.c \ + qf_actq.c \ + qf_defer.c \ + qf_dyn.c \ + qf_mem.c \ + qf_ps.c \ + qf_qact.c \ + qf_qeq.c \ + qf_qmact.c \ + qf_time.c \ + qv.c \ + qv_port.c + +QP_ASMS := + +QS_SRCS := \ + qs.c \ + qs_rx.c \ + qs_fp.c + +LIB_DIRS := +LIBS := + +# defines +DEFINES := -DSTM32C031xx \ + -DQF_ON_CONTEXT_SW + +# ARM CPU, ARCH, FPU, and Float-ABI types... +# ARM_CPU: [cortex-m0 | cortex-m0plus | cortex-m1 | cortex-m3 | cortex-m4] +# ARM_FPU: [ | vfp] +# FLOAT_ABI: [ | soft | softfp | hard] +# +ARM_CPU := -mcpu=cortex-m0plus +ARM_FPU := +FLOAT_ABI := + +#----------------------------------------------------------------------------- +# GNU-ARM toolset (NOTE: You need to adjust to your machine) +# see https://developer.arm.com/open-source/gnu-toolchain/gnu-rm/downloads +# +ifeq ($(GNU_ARM),) +GNU_ARM := $(QTOOLS)/gnu_arm-none-eabi +endif + +# make sure that the GNU-ARM toolset exists... +ifeq ("$(wildcard $(GNU_ARM))","") +$(error GNU_ARM toolset not found. Please adjust the Makefile) +endif + +CC := $(GNU_ARM)/bin/arm-none-eabi-gcc +CPP := $(GNU_ARM)/bin/arm-none-eabi-g++ +AS := $(GNU_ARM)/bin/arm-none-eabi-as +LINK := $(GNU_ARM)/bin/arm-none-eabi-gcc +BIN := $(GNU_ARM)/bin/arm-none-eabi-objcopy + +############################################################################## +# Typically you should not need to change anything below this line + +# basic utilities (included in QTools for Windows), see: +# https://www.state-machine.com/qtools + +MKDIR := mkdir +RM := rm + +#----------------------------------------------------------------------------- +# build options for various configurations for ARM Cortex-M +# + +# combine all the soruces... +C_SRCS += $(QP_SRCS) +ASM_SRCS += $(QP_ASMS) + +ifeq (rel, $(CONF)) # Release configuration .................................. + +BIN_DIR := rel + +ASFLAGS = $(ARM_CPU) $(ARM_FPU) $(ASM_CPU) $(ASM_FPU) + +CFLAGS = -c $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \ + -ffunction-sections -fdata-sections \ + -O2 $(INCLUDES) $(DEFINES) -DNDEBUG + +CPPFLAGS = -c $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \ + -ffunction-sections -fdata-sections -fno-rtti -fno-exceptions \ + -O2 $(INCLUDES) $(DEFINES) -DNDEBUG + +else ifeq (spy, $(CONF)) # Spy configuration ................................ + +BIN_DIR := spy + +C_SRCS += $(QS_SRCS) + +ASFLAGS = -g $(ARM_CPU) $(ARM_FPU) $(ASM_CPU) $(ASM_FPU) + +CFLAGS = -c -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \ + -ffunction-sections -fdata-sections \ + -O $(INCLUDES) $(DEFINES) -DQ_SPY + +CPPFLAGS = -c -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \ + -ffunction-sections -fdata-sections -fno-rtti -fno-exceptions \ + -O $(INCLUDES) $(DEFINES) -DQ_SPY + +else # default Debug configuration .......................................... + +BIN_DIR := dbg + +ASFLAGS = -g $(ARM_CPU) $(ARM_FPU) $(ASM_CPU) $(ASM_FPU) + +CFLAGS = -c -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \ + -ffunction-sections -fdata-sections \ + -O $(INCLUDES) $(DEFINES) + +CPPFLAGS = -c -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \ + -ffunction-sections -fdata-sections -fno-rtti -fno-exceptions \ + -O $(INCLUDES) $(DEFINES) + +endif # ...................................................................... + + +LINKFLAGS = -T$(LD_SCRIPT) $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb \ + -specs=nosys.specs -specs=nano.specs \ + -Wl,-Map,$(BIN_DIR)/$(OUTPUT).map,--cref,--gc-sections $(LIB_DIRS) + +ASM_OBJS := $(patsubst %.s,%.o, $(notdir $(ASM_SRCS))) +C_OBJS := $(patsubst %.c,%.o, $(notdir $(C_SRCS))) +CPP_OBJS := $(patsubst %.cpp,%.o,$(notdir $(CPP_SRCS))) + +TARGET_BIN := $(BIN_DIR)/$(OUTPUT).bin +TARGET_ELF := $(BIN_DIR)/$(OUTPUT).elf +ASM_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(ASM_OBJS)) +C_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(C_OBJS)) +C_DEPS_EXT := $(patsubst %.o, %.d, $(C_OBJS_EXT)) +CPP_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(CPP_OBJS)) +CPP_DEPS_EXT := $(patsubst %.o, %.d, $(CPP_OBJS_EXT)) + +# create $(BIN_DIR) if it does not exist +ifeq ("$(wildcard $(BIN_DIR))","") +$(shell $(MKDIR) $(BIN_DIR)) +endif + +#----------------------------------------------------------------------------- +# rules +# + +.PHONY : run norun flash + +ifeq ($(MAKECMDGOALS),norun) +all : $(TARGET_BIN) +norun : all +else +all : $(TARGET_BIN) run +endif + +$(TARGET_BIN): $(TARGET_ELF) + $(BIN) -O binary $< $@ + +$(TARGET_ELF) : $(ASM_OBJS_EXT) $(C_OBJS_EXT) $(CPP_OBJS_EXT) + $(CC) $(CFLAGS) $(QPC)/src/qs/qstamp.c -o $(BIN_DIR)/qstamp.o + $(LINK) $(LINKFLAGS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) + +$(BIN_DIR)/%.d : %.c + $(CC) -MM -MT $(@:.d=.o) $(CFLAGS) $< > $@ + +$(BIN_DIR)/%.d : %.cpp + $(CPP) -MM -MT $(@:.d=.o) $(CPPFLAGS) $< > $@ + +$(BIN_DIR)/%.o : %.s + $(AS) $(ASFLAGS) $< -o $@ + +$(BIN_DIR)/%.o : %.c + $(CC) $(CFLAGS) $< -o $@ + +$(BIN_DIR)/%.o : %.cpp + $(CPP) $(CPPFLAGS) $< -o $@ + +.PHONY : clean show + +# include dependency files only if our goal depends on their existence +ifneq ($(MAKECMDGOALS),clean) + ifneq ($(MAKECMDGOALS),show) +-include $(C_DEPS_EXT) $(CPP_DEPS_EXT) + endif +endif + + +clean: + -$(RM) $(BIN_DIR)/*.o \ + $(BIN_DIR)/*.d \ + $(BIN_DIR)/*.bin \ + $(BIN_DIR)/*.elf \ + $(BIN_DIR)/*.map + +show: + @echo PROJECT = $(PROJECT) + @echo CONF = $(CONF) + @echo DEFINES = $(DEFINES) + @echo ASM_FPU = $(ASM_FPU) + @echo ASM_SRCS = $(ASM_SRCS) + @echo C_SRCS = $(C_SRCS) + @echo CPP_SRCS = $(CPP_SRCS) + @echo ASM_OBJS_EXT = $(ASM_OBJS_EXT) + @echo C_OBJS_EXT = $(C_OBJS_EXT) + @echo C_DEPS_EXT = $(C_DEPS_EXT) + @echo CPP_DEPS_EXT = $(CPP_DEPS_EXT) + @echo TARGET_ELF = $(TARGET_ELF) diff --git a/examples/arm-cm/dpp_nucleo-c031c6/qv/gnu/dpp-qv.ld b/examples/arm-cm/dpp_nucleo-c031c6/qv/gnu/dpp-qv.ld new file mode 100644 index 00000000..4a3ba851 --- /dev/null +++ b/examples/arm-cm/dpp_nucleo-c031c6/qv/gnu/dpp-qv.ld @@ -0,0 +1,135 @@ +/***************************************************************************** +* Linker script for for STM32C031C6, GNU-ARM linker +* +* Q u a n t u m L e a P s +* ------------------------ +* Modern Embedded Software +* +* Copyright (C) 2005 Quantum Leaps, LLC . +* +* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +* +* This software is dual-licensed under the terms of the open source GNU +* General Public License version 3 (or any later version), or alternatively, +* under the terms of one of the closed source Quantum Leaps commercial +* licenses. +* +* The terms of the open source GNU General Public License version 3 +* can be found at: +* +* The terms of the closed source Quantum Leaps commercial licenses +* can be found at: +* +* Redistributions in source code must retain this top-level comment block. +* Plagiarizing this software to sidestep the license obligations is illegal. +* +* Contact information: +* +* +*****************************************************************************/ +OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm", "elf32-littlearm") +OUTPUT_ARCH(arm) +ENTRY(Reset_Handler) /* entry Point */ + +MEMORY { /* memory map of STM32C031C6 */ + ROM (rx) : ORIGIN = 0x08000000, LENGTH = 32K + RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 12K +} + +/* The size of the stack used by the application. NOTE: you need to adjust */ +STACK_SIZE = 2048; + +/* The size of the heap used by the application. NOTE: you need to adjust */ +HEAP_SIZE = 0; + +SECTIONS { + + .isr_vector : { /* the vector table goes FIRST into ROM */ + KEEP(*(.isr_vector)) /* vector table */ + . = ALIGN(4); + } >ROM + + .text : { /* code and constants */ + . = ALIGN(4); + *(.text) /* .text sections (code) */ + *(.text*) /* .text* sections (code) */ + *(.rodata) /* .rodata sections (constants, strings, etc.) */ + *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ + + KEEP (*(.init)) + KEEP (*(.fini)) + + . = ALIGN(4); + } >ROM + + .preinit_array : { + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array*)) + PROVIDE_HIDDEN (__preinit_array_end = .); + } >ROM + + .init_array : { + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array*)) + PROVIDE_HIDDEN (__init_array_end = .); + } >ROM + + .fini_array : { + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(.fini_array*)) + KEEP (*(SORT(.fini_array.*))) + PROVIDE_HIDDEN (__fini_array_end = .); + } >ROM + + _etext = .; /* global symbols at end of code */ + + .stack : { + __stack_start__ = .; + . = . + STACK_SIZE; + . = ALIGN(4); + __stack_end__ = .; + } >RAM + + .data : AT (_etext) { + __data_load = LOADADDR (.data); + __data_start = .; + *(.data) /* .data sections */ + *(.data*) /* .data* sections */ + . = ALIGN(4); + __data_end__ = .; + _edata = __data_end__; + } >RAM + + .bss : { + __bss_start__ = .; + *(.bss) + *(.bss*) + *(COMMON) + . = ALIGN(4); + _ebss = .; /* define a global symbol at bss end */ + __bss_end__ = .; + } >RAM + + __exidx_start = .; + .ARM.exidx : { *(.ARM.exidx* .gnu.linkonce.armexidx.*) } >RAM + __exidx_end = .; + + PROVIDE ( end = _ebss ); + PROVIDE ( _end = _ebss ); + PROVIDE ( __end__ = _ebss ); + + .heap : { + __heap_start__ = .; + . = . + HEAP_SIZE; + . = ALIGN(4); + __heap_end__ = .; + } >RAM + + /* Remove information from the standard libraries */ + /DISCARD/ : { + libc.a ( * ) + libm.a ( * ) + libgcc.a ( * ) + } +} diff --git a/examples/arm-cm/dpp_nucleo-c031c6/qv/iar/dpp-qv.ewd b/examples/arm-cm/dpp_nucleo-c031c6/qv/iar/dpp-qv.ewd new file mode 100644 index 00000000..b3712b65 --- /dev/null +++ b/examples/arm-cm/dpp_nucleo-c031c6/qv/iar/dpp-qv.ewd @@ -0,0 +1,4654 @@ + + + 3 + + Debug + + ARM + + 1 + + C-SPY + 2 + + 32 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ARMSIM_ID + 2 + + 1 + 1 + 1 + + + + + + + + CADI_ID + 2 + + 0 + 1 + 1 + + + + + + + + + CMSISDAP_ID + 2 + + 4 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + GDBSERVER_ID + 2 + + 0 + 1 + 1 + + + + + + + + + + + IJET_ID + 2 + + 9 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + JLINK_ID + 2 + + 16 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + LMIFTDI_ID + 2 + + 3 + 1 + 1 + + + + + + + + + + + + + NULINK_ID + 2 + + 0 + 1 + 1 + + + + + + + PEMICRO_ID + 2 + + 3 + 1 + 1 + + + + + + + + STLINK_ID + 2 + + 8 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + THIRDPARTY_ID + 2 + + 0 + 1 + 1 + + + + + + + + TIFET_ID + 2 + + 1 + 1 + 1 + + + + + + + + + + + + + + + + + + + XDS100_ID + 2 + + 9 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + $TOOLKIT_DIR$\plugins\rtos\CMX\CmxArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\CMX\CmxTinyArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\FreeRtos\FreeRtosArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin2.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SafeRTOS\SafeRTOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9BE.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-286-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-III\uCOS-III-KA-CSpy.ewplugin + 0 + + + $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\TargetAccessServer\TargetAccessServer.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\uCProbe\uCProbePlugin.ENU.ewplugin + 0 + + + + + Release + + ARM + + 0 + + C-SPY + 2 + + 32 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ARMSIM_ID + 2 + + 1 + 1 + 0 + + + + + + + + CADI_ID + 2 + + 0 + 1 + 0 + + + + + + + + + CMSISDAP_ID + 2 + + 4 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + GDBSERVER_ID + 2 + + 0 + 1 + 0 + + + + + + + + + + + IJET_ID + 2 + + 9 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + JLINK_ID + 2 + + 16 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + LMIFTDI_ID + 2 + + 3 + 1 + 0 + + + + + + + + + + + + + NULINK_ID + 2 + + 0 + 1 + 0 + + + + + + + PEMICRO_ID + 2 + + 3 + 1 + 0 + + + + + + + + STLINK_ID + 2 + + 8 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + THIRDPARTY_ID + 2 + + 0 + 1 + 0 + + + + + + + + TIFET_ID + 2 + + 1 + 1 + 0 + + + + + + + + + + + + + + + + + + + XDS100_ID + 2 + + 9 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + $TOOLKIT_DIR$\plugins\rtos\CMX\CmxArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\CMX\CmxTinyArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\FreeRtos\FreeRtosArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin2.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SafeRTOS\SafeRTOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9BE.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-286-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-III\uCOS-III-KA-CSpy.ewplugin + 0 + + + $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\TargetAccessServer\TargetAccessServer.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\uCProbe\uCProbePlugin.ENU.ewplugin + 0 + + + + + Spy + + ARM + + 1 + + C-SPY + 2 + + 32 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ARMSIM_ID + 2 + + 1 + 1 + 1 + + + + + + + + CADI_ID + 2 + + 0 + 1 + 1 + + + + + + + + + CMSISDAP_ID + 2 + + 4 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + GDBSERVER_ID + 2 + + 0 + 1 + 1 + + + + + + + + + + + IJET_ID + 2 + + 9 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + JLINK_ID + 2 + + 16 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + LMIFTDI_ID + 2 + + 3 + 1 + 1 + + + + + + + + + + + + + NULINK_ID + 2 + + 0 + 1 + 1 + + + + + + + PEMICRO_ID + 2 + + 3 + 1 + 1 + + + + + + + + STLINK_ID + 2 + + 8 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + THIRDPARTY_ID + 2 + + 0 + 1 + 1 + + + + + + + + TIFET_ID + 2 + + 1 + 1 + 1 + + + + + + + + + + + + + + + + + + + XDS100_ID + 2 + + 9 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + $TOOLKIT_DIR$\plugins\rtos\CMX\CmxArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\CMX\CmxTinyArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\FreeRtos\FreeRtosArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin2.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SafeRTOS\SafeRTOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9BE.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-286-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-III\uCOS-III-KA-CSpy.ewplugin + 0 + + + $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\TargetAccessServer\TargetAccessServer.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\uCProbe\uCProbePlugin.ENU.ewplugin + 0 + + + + diff --git a/examples/arm-cm/dpp_nucleo-c031c6/qv/iar/dpp-qv.ewp b/examples/arm-cm/dpp_nucleo-c031c6/qv/iar/dpp-qv.ewp new file mode 100644 index 00000000..f1b57402 --- /dev/null +++ b/examples/arm-cm/dpp_nucleo-c031c6/qv/iar/dpp-qv.ewp @@ -0,0 +1,3364 @@ + + + 3 + + Debug + + ARM + + 1 + + General + 3 + + 35 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ICCARM + 2 + + 37 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + AARM + 2 + + 11 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + OBJCOPY + 0 + + 1 + 1 + 1 + + + + + + + + + CUSTOM + 3 + + + + 0 + inputOutputBased + + + + BUILDACTION + 1 + + cmd /c "if exist $OBJ_DIR$\qstamp.o del $OBJ_DIR$\qstamp.o" + + + + + ILINK + 0 + + 27 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + IARCHIVE + 0 + + 0 + 1 + 1 + + + + + + + Coder + 0 + + + + + Release + + ARM + + 0 + + General + 3 + + 35 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ICCARM + 2 + + 37 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + AARM + 2 + + 11 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + OBJCOPY + 0 + + 1 + 1 + 0 + + + + + + + + + CUSTOM + 3 + + + + 0 + inputOutputBased + + + + BUILDACTION + 1 + + cmd /c "if exist $OBJ_DIR$\qstamp.o del $OBJ_DIR$\qstamp.o" + + + + + ILINK + 0 + + 27 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + IARCHIVE + 0 + + 0 + 1 + 0 + + + + + + + Coder + 0 + + + + + Spy + + ARM + + 1 + + General + 3 + + 35 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ICCARM + 2 + + 37 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + AARM + 2 + + 11 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + OBJCOPY + 0 + + 1 + 1 + 1 + + + + + + + + + CUSTOM + 3 + + + + 0 + inputOutputBased + + + + BUILDACTION + 1 + + cmd /c "if exist $OBJ_DIR$\qstamp.o del $OBJ_DIR$\qstamp.o" + + + + + ILINK + 0 + + 27 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + IARCHIVE + 0 + + 0 + 1 + 1 + + + + + + + Coder + 0 + + + + + Release + + + Application + + $PROJ_DIR$\..\bsp.c + + + $PROJ_DIR$\..\..\bsp.h + + + $PROJ_DIR$\..\..\dpp.h + + + $PROJ_DIR$\..\..\main.c + + + $PROJ_DIR$\..\..\philo.c + + + $PROJ_DIR$\..\..\table.c + + + + nucleo-c031c6 + + $PROJ_DIR$\..\..\..\..\..\3rd_party\nucleo-c031c6\iar\startup_stm32c031xx.s + + + $PROJ_DIR$\..\..\..\..\..\3rd_party\nucleo-c031c6\stm32c031xx.h + + + $PROJ_DIR$\..\..\..\..\..\3rd_party\nucleo-c031c6\stm32c0xx.h + + + $PROJ_DIR$\..\..\..\..\..\3rd_party\nucleo-c031c6\system_stm32c0xx.c + + + + QP + + $PROJ_DIR$\..\..\..\..\..\src\qf\qep_hsm.c + + + $PROJ_DIR$\..\..\..\..\..\src\qf\qep_msm.c + + + $PROJ_DIR$\..\..\..\..\..\src\qf\qf_act.c + + + $PROJ_DIR$\..\..\..\..\..\src\qf\qf_actq.c + + + $PROJ_DIR$\..\..\..\..\..\src\qf\qf_defer.c + + + $PROJ_DIR$\..\..\..\..\..\src\qf\qf_dyn.c + + + $PROJ_DIR$\..\..\..\..\..\src\qf\qf_mem.c + + + $PROJ_DIR$\..\..\..\..\..\src\qf_pkg.h + + + $PROJ_DIR$\..\..\..\..\..\src\qf\qf_ps.c + + + $PROJ_DIR$\..\..\..\..\..\src\qf\qf_qact.c + + + $PROJ_DIR$\..\..\..\..\..\src\qf\qf_qeq.c + + + $PROJ_DIR$\..\..\..\..\..\src\qf\qf_qmact.c + + + $PROJ_DIR$\..\..\..\..\..\src\qf\qf_time.c + + + $PROJ_DIR$\..\..\..\..\..\src\qv\qv.c + + + + QP_port + + $PROJ_DIR$\..\..\..\..\..\ports\arm-cm\qv\iar\qep_port.h + + + $PROJ_DIR$\..\..\..\..\..\ports\arm-cm\qv\iar\qf_port.h + + + $PROJ_DIR$\..\..\..\..\..\ports\arm-cm\qv\iar\qs_port.h + + + $PROJ_DIR$\..\..\..\..\..\ports\arm-cm\qv\iar\qv_port.c + + + $PROJ_DIR$\..\..\..\..\..\ports\arm-cm\qv\iar\qv_port.h + + + + QS + + Debug + Release + + + $PROJ_DIR$\..\..\..\..\..\src\qs\qs.c + + + $PROJ_DIR$\..\..\..\..\..\src\qs\qs_fp.c + + + $PROJ_DIR$\..\..\..\..\..\src\qs\qs_rx.c + + + $PROJ_DIR$\..\..\..\..\..\src\qs\qstamp.c + + + diff --git a/examples/arm-cm/dpp_nucleo-c031c6/qv/iar/dpp-qv.eww b/examples/arm-cm/dpp_nucleo-c031c6/qv/iar/dpp-qv.eww new file mode 100644 index 00000000..b96f3f62 --- /dev/null +++ b/examples/arm-cm/dpp_nucleo-c031c6/qv/iar/dpp-qv.eww @@ -0,0 +1,10 @@ + + + + + $WS_DIR$\dpp-qv.ewp + + + + + diff --git a/examples/arm-cm/dpp_nucleo-c031c6/qv/iar/dpp-qv.icf b/examples/arm-cm/dpp_nucleo-c031c6/qv/iar/dpp-qv.icf new file mode 100644 index 00000000..db057b16 --- /dev/null +++ b/examples/arm-cm/dpp_nucleo-c031c6/qv/iar/dpp-qv.icf @@ -0,0 +1,165 @@ +/*###ICF### Section handled by ICF editor, don't touch! ****/ +/*-Editor annotation file-*/ +/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_4.xml" */ +/*-Specials-*/ +define symbol __ICFEDIT_intvec_start__ = 0x08000000; +/*-Memory Regions-*/ +define symbol __ICFEDIT_region_IROM1_start__ = 0x08000000; +define symbol __ICFEDIT_region_IROM1_end__ = 0x08007FFF; +define symbol __ICFEDIT_region_IROM2_start__ = 0x0; +define symbol __ICFEDIT_region_IROM2_end__ = 0x0; +define symbol __ICFEDIT_region_EROM1_start__ = 0x0; +define symbol __ICFEDIT_region_EROM1_end__ = 0x0; +define symbol __ICFEDIT_region_EROM2_start__ = 0x0; +define symbol __ICFEDIT_region_EROM2_end__ = 0x0; +define symbol __ICFEDIT_region_EROM3_start__ = 0x0; +define symbol __ICFEDIT_region_EROM3_end__ = 0x0; +define symbol __ICFEDIT_region_IRAM1_start__ = 0x20000000; +define symbol __ICFEDIT_region_IRAM1_end__ = 0x20002FFF; +define symbol __ICFEDIT_region_IRAM2_start__ = 0x0; +define symbol __ICFEDIT_region_IRAM2_end__ = 0x0; +define symbol __ICFEDIT_region_ERAM1_start__ = 0x0; +define symbol __ICFEDIT_region_ERAM1_end__ = 0x0; +define symbol __ICFEDIT_region_ERAM2_start__ = 0x0; +define symbol __ICFEDIT_region_ERAM2_end__ = 0x0; +define symbol __ICFEDIT_region_ERAM3_start__ = 0x0; +define symbol __ICFEDIT_region_ERAM3_end__ = 0x0; +/*-Sizes-*/ +define symbol __ICFEDIT_size_cstack__ = 2048; +define symbol __ICFEDIT_size_proc_stack__ = 0x0; +define symbol __ICFEDIT_size_heap__ = 0; +/**** End of ICF editor section. ###ICF###*/ + +define memory mem with size = 4G; +define symbol use_IROM1 = (__ICFEDIT_region_IROM1_start__ != 0x0 || __ICFEDIT_region_IROM1_end__ != 0x0); +define symbol use_IROM2 = (__ICFEDIT_region_IROM2_start__ != 0x0 || __ICFEDIT_region_IROM2_end__ != 0x0); +define symbol use_EROM1 = (__ICFEDIT_region_EROM1_start__ != 0x0 || __ICFEDIT_region_EROM1_end__ != 0x0); +define symbol use_EROM2 = (__ICFEDIT_region_EROM2_start__ != 0x0 || __ICFEDIT_region_EROM2_end__ != 0x0); +define symbol use_EROM3 = (__ICFEDIT_region_EROM3_start__ != 0x0 || __ICFEDIT_region_EROM3_end__ != 0x0); +define symbol use_IRAM1 = (__ICFEDIT_region_IRAM1_start__ != 0x0 || __ICFEDIT_region_IRAM1_end__ != 0x0); +define symbol use_IRAM2 = (__ICFEDIT_region_IRAM2_start__ != 0x0 || __ICFEDIT_region_IRAM2_end__ != 0x0); +define symbol use_ERAM1 = (__ICFEDIT_region_ERAM1_start__ != 0x0 || __ICFEDIT_region_ERAM1_end__ != 0x0); +define symbol use_ERAM2 = (__ICFEDIT_region_ERAM2_start__ != 0x0 || __ICFEDIT_region_ERAM2_end__ != 0x0); +define symbol use_ERAM3 = (__ICFEDIT_region_ERAM3_start__ != 0x0 || __ICFEDIT_region_ERAM3_end__ != 0x0); + +if (use_IROM1) +{ + define region IROM1_region = mem:[from __ICFEDIT_region_IROM1_start__ to __ICFEDIT_region_IROM1_end__]; +} +else +{ + define region IROM1_region = []; +} + +if (use_IROM2) +{ + define region IROM2_region = mem:[from __ICFEDIT_region_IROM2_start__ to __ICFEDIT_region_IROM2_end__]; +} +else +{ + define region IROM2_region = []; +} +define region IROM_region = IROM1_region | IROM2_region; + +if (use_EROM1) +{ + define region EROM1_region = mem:[from __ICFEDIT_region_EROM1_start__ to __ICFEDIT_region_EROM1_end__]; +} +else +{ + define region EROM1_region = []; +} +if (use_EROM2) +{ + define region EROM2_region = mem:[from __ICFEDIT_region_EROM2_start__ to __ICFEDIT_region_EROM2_end__]; +} +else +{ + define region EROM2_region = []; +} +if (use_EROM3) +{ + define region EROM3_region = mem:[from __ICFEDIT_region_EROM3_start__ to __ICFEDIT_region_EROM3_end__]; +} +else +{ + define region EROM3_region = []; +} +define region EROM_region = EROM1_region | EROM2_region | EROM3_region; + +if (use_IRAM1) +{ + define region IRAM1_region = mem:[from __ICFEDIT_region_IRAM1_start__ to __ICFEDIT_region_IRAM1_end__]; +} +else +{ + define region IRAM1_region = []; +} +if (use_IRAM2) +{ + define region IRAM2_region = mem:[from __ICFEDIT_region_IRAM2_start__ to __ICFEDIT_region_IRAM2_end__]; +} +else +{ + define region IRAM2_region = []; +} +define region IRAM_region = IRAM1_region | IRAM2_region; + +if (use_ERAM1) +{ + define region ERAM1_region = mem:[from __ICFEDIT_region_ERAM1_start__ to __ICFEDIT_region_ERAM1_end__]; +} +else +{ + define region ERAM1_region = []; +} +if (use_ERAM2) +{ + define region ERAM2_region = mem:[from __ICFEDIT_region_ERAM2_start__ to __ICFEDIT_region_ERAM2_end__]; +} +else +{ + define region ERAM2_region = []; +} +if (use_ERAM3) +{ + define region ERAM3_region = mem:[from __ICFEDIT_region_ERAM3_start__ to __ICFEDIT_region_ERAM3_end__]; +} +else +{ + define region ERAM3_region = []; +} +define region ERAM_region = ERAM1_region | ERAM2_region | ERAM3_region; + +initialize by copy { readwrite }; +if (isdefinedsymbol(__USE_DLIB_PERTHREAD)) +{ + // Required in a multi-threaded application + initialize by copy with packing = none { section __DLIB_PERTHREAD }; +} + +place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec }; + +if (!isempty(IROM_region)) +{ + place in IROM_region { readonly }; +} + +if (!isempty(EROM_region)) +{ + place in EROM_region { readonly section application_specific_ro }; +} + +if (!isempty(IRAM_region)) +{ + define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { }; + define block PROC_STACK with alignment = 8, size = __ICFEDIT_size_proc_stack__ { }; + define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { }; + place at start of IRAM_region {block CSTACK }; /* <== Quantum Leaps */ + place in IRAM_region { readwrite, block PROC_STACK, block HEAP }; +} + +if (!isempty(ERAM_region)) +{ + place in ERAM_region { readwrite section application_specific_rw }; +} \ No newline at end of file diff --git a/examples/arm-cm/dpp_nucleo-c031c6/qview/dpp.py b/examples/arm-cm/dpp_nucleo-c031c6/qview/dpp.py new file mode 100644 index 00000000..73c51654 --- /dev/null +++ b/examples/arm-cm/dpp_nucleo-c031c6/qview/dpp.py @@ -0,0 +1,103 @@ +# This is an example of QView customization for a specific application +# (DPP in this case). This example animates the Phil images on the +# QView canvas. Additionally, there is a button in the middle of the screen, +# which, when clicked once pauses the DPP ("forks" are not being served). +# A second click on the button, "un-pauses" the DPP ("forks" are served +# to all hungry Philosophers). +# +# This version of the DPP customization uses the application-specific +# trace record QS_USER_00 (PHILO_STAT) produced when the status of +# a Philo changes. + +class DPP: + def __init__(self): + + # add commands to the Custom menu... + QView.custom_menu.add_command(label="Custom command", + command=self.cust_command) + + # configure the custom QView.canvas... + QView.show_canvas() # make the canvas visible + QView.canvas.configure(width=400, height=260) + + # tuple of activity images (correspond to self._philo_state) + self._act_img = ( + PhotoImage(file=HOME_DIR + "/img/thinking.gif"), + PhotoImage(file=HOME_DIR + "/img/hungry.gif"), + PhotoImage(file=HOME_DIR + "/img/eating.gif"), + ) + # tuple of philo canvas images (correspond to self._philo_obj) + self._philo_img = (\ + QView.canvas.create_image(190, 57, image=self._act_img[0]), + QView.canvas.create_image(273, 100, image=self._act_img[0]), + QView.canvas.create_image(237, 185, image=self._act_img[0]), + QView.canvas.create_image(146, 185, image=self._act_img[0]), + QView.canvas.create_image(107, 100, image=self._act_img[0]) + ) + + # button images for UP and DOWN + self.img_UP = PhotoImage(file=HOME_DIR + "/img/BTN_UP.gif") + self.img_DWN = PhotoImage(file=HOME_DIR + "/img/BTN_DWN.gif") + + # images of a button for pause/serve + self.btn = QView.canvas.create_image(200, 120, image=self.img_UP) + QView.canvas.tag_bind(self.btn, "", self.cust_pause) + + # request target reset on startup... + # NOTE: Normally, for an embedded application you would like + # to start with resetting the Target, to start clean with + # Qs dictionaries, etc. + reset_target() + + # on_reset() callback + def on_reset(self): + # clear the lists + self._philo_obj = [0, 0, 0, 0, 0] + self._philo_state = [0, 0, 0] + + # on_run() callback + def on_run(self): + glb_filter("QS_USER_00") + + # NOTE: the names of objects for current_obj() must match + # the QS Object Dictionaries produced by the application. + current_obj(OBJ_AO, "Table_inst") + + # turn lists into tuples for better performance + self._philo_obj = tuple(self._philo_obj) + self._philo_state = tuple(self._philo_state) + + + # example of a custom command + def cust_command(self): + command(1, 12345) + + # example of a custom interaction with a canvas object (pause/serve) + def cust_pause(self, event): + if QView.canvas.itemcget(self.btn, "image") != str(self.img_UP): + QView.canvas.itemconfig(self.btn, image=self.img_UP) + post("SERVE_SIG") + QView.print_text("Table SERVING") + else: + QView.canvas.itemconfig(self.btn, image=self.img_DWN) + post("PAUSE_SIG") + QView.print_text("Table PAUSED") + + # Intercept the QS_USER_00 application-specific trace record. + # This record has the following structure (see bsp.c:displayPhilStat()): + # Seq-Num, Record-ID, Timestamp, format-byte, Philo-num, + # format-byte, Zero-terminated string (status) + def QS_USER_00(self, packet): + # unpack: Timestamp->data[0], Philo-num->data[1], status->data[3] + data = qunpack("xxTxBxZ", packet) + i = data[1] + j = ("t", "h", "e").index(data[2][0]) # the first letter + + # animate the given philo image according to its activity + QView.canvas.itemconfig(self._philo_img[i], image=self._act_img[j]) + + # print a message to the text view + QView.print_text("%010d Philo %1d is %s"%(data[0], i, data[2])) + +#============================================================================= +QView.customize(DPP()) # set the QView customization diff --git a/examples/arm-cm/dpp_nucleo-c031c6/qview/dpp1.py b/examples/arm-cm/dpp_nucleo-c031c6/qview/dpp1.py new file mode 100644 index 00000000..d93f7b6d --- /dev/null +++ b/examples/arm-cm/dpp_nucleo-c031c6/qview/dpp1.py @@ -0,0 +1,147 @@ +# This is an example of QView customization for a specific application +# (DPP in this case). This example animates the Phil images on the +# QView canvas. Additionally, there is a button in the middle of the screen, +# which, when clicked once pauses the DPP ("forks" are not being served). +# A second click on the button, "un-pauses" the DPP ("forks" are served +# to all hungry Philosophers). +# +# This version of the DPP customization uses the predefined QS_QEP_TRAN +# trace record, which provides information about the state transitions of +# the Dining Philosophers. The example also demonstrates how to intercept +# the QS "dictionary" records QS_OBJ_DICT and QS_FUN_DICT to extract the +# information about the addresses of the Philosopher objects and the states +# of their state machines. + +class DPP: + def __init__(self): + + # add commands to the Custom menu... + QView.custom_menu.add_command(label="Custom command", + command=self.cust_command) + + # configure the custom QView.canvas... + QView.show_canvas() # make the canvas visible + QView.canvas.configure(width=400, height=260) + + # tuple of activity images (correspond to self._philo_state) + self._act_img = ( + PhotoImage(file=HOME_DIR + "/img/thinking.gif"), + PhotoImage(file=HOME_DIR + "/img/hungry.gif"), + PhotoImage(file=HOME_DIR + "/img/eating.gif"), + ) + # tuple of philo canvas images (correspond to self._philo_obj) + self._philo_img = (\ + QView.canvas.create_image(190, 57, image=self._act_img[0]), + QView.canvas.create_image(273, 100, image=self._act_img[0]), + QView.canvas.create_image(237, 185, image=self._act_img[0]), + QView.canvas.create_image(146, 185, image=self._act_img[0]), + QView.canvas.create_image(107, 100, image=self._act_img[0]) + ) + + # button images for UP and DOWN + self.img_UP = PhotoImage(file=HOME_DIR + "/img/BTN_UP.gif") + self.img_DWN = PhotoImage(file=HOME_DIR + "/img/BTN_DWN.gif") + + # images of a button for pause/serve + self.btn = QView.canvas.create_image(200, 120, image=self.img_UP) + QView.canvas.tag_bind(self.btn, "", self.cust_pause) + + # request target reset on startup... + # NOTE: Normally, for an embedded application you would like + # to start with resetting the Target, to start clean with + # Qs dictionaries, etc. + reset_target() + + + # on_reset() callback invoked when Target-reset packet is received + # NOTE: the QS dictionaries are not known at this time yet, so + # this callback shouild generally not set filters or current objects + def on_reset(self): + # (re)set the lists + self._philo_obj = [0, 0, 0, 0, 0] + self._philo_state = [0, 0, 0] + + # on_run() callback invoked when the QF_RUN packet is received + # NOTE: the QS dictionaries are typically known at this time yet, so + # this callback can set filters or current objects + def on_run(self): + glb_filter("QS_QEP_TRAN") + + # NOTE: the names of objects for current_obj() must match + # the QS Object Dictionaries produced by the application. + current_obj(OBJ_AO, "Table_inst") + + # turn lists into tuples for better performance + self._philo_obj = tuple(self._philo_obj) + self._philo_state = tuple(self._philo_state) + + + # example of a custom command + def cust_command(self): + command(1, 12345) + + # example of a custom interaction with a canvas object (pause/serve) + def cust_pause(self, event): + if QView.canvas.itemcget(self.btn, "image") != str(self.img_UP): + QView.canvas.itemconfig(self.btn, image=self.img_UP) + post("SERVE_SIG") + QView.print_text("Table SERVING") + else: + QView.canvas.itemconfig(self.btn, image=self.img_DWN) + post("PAUSE_SIG") + QView.print_text("Table PAUSED") + + # Intercept the QS_OBJ_DICT predefined trace record. + # This record has the following structure: + # Seq-Num, Record-ID, Object-ptr, Zero-terminated string + def QS_OBJ_DICT(self, packet): + data = qunpack("xxOZ", packet) + try: + # NOTE: the names of objects must match the QS Object Dictionaries + # produced by the application. + i = ("Philo_inst[0]", + "Philo_inst[1]", + "Philo_inst[2]", + "Philo_inst[3]", + "Philo_inst[4]").index(data[1]) + self._philo_obj[i] = data[0] + except: + pass # dictionary for a different object + + # Intercept the QS_FUN_DICT predefined trace record. + # This record has the following structure: + # Seq-Num, Record-ID, Function-ptr, Zero-terminated string + def QS_FUN_DICT(self, packet): + data = qunpack("xxFZ", packet) + try: + # NOTE: the names of states must match the QS Object Dictionaries + # produced by the application. + j = ("Philo_thinking", + "Philo_hungry", + "Philo_eating").index(data[1]) + self._philo_state[j] = data[0] + except: + pass # dictionary for a different state + + # Intercept the QS_QEP_TRAN predefined trace record. + # This record has the following structure (see qep_hsm.c): + # Seq-Num, Record-ID, Timestamp, Signal, Object-ptr, + # Function-ptr (source state), Function-ptr (new active state) + def QS_QEP_TRAN(self, packet): + data = qunpack("xxTSOFF", packet) + try: + i = self._philo_obj.index(data[2]) + j = self._philo_state.index(data[4]) + + # animate the given philo image according to its activity + QView.canvas.itemconfig(self._philo_img[i], + image=self._act_img[j]) + # print a message to the text view + QView.print_text("%010d Philo %d is %s"\ + %(data[0], i, ("thinking", "hungry", "eating")[j])) + except: + pass # state-entry in a different object + +#============================================================================= +# instantiate the DPP class and set it as the QView customization +QView.customize(DPP()) diff --git a/examples/arm-cm/dpp_nucleo-c031c6/qview/img/BTN_DWN.gif b/examples/arm-cm/dpp_nucleo-c031c6/qview/img/BTN_DWN.gif new file mode 100644 index 00000000..36d8c790 Binary files /dev/null and b/examples/arm-cm/dpp_nucleo-c031c6/qview/img/BTN_DWN.gif differ diff --git a/examples/arm-cm/dpp_nucleo-c031c6/qview/img/BTN_UP.gif b/examples/arm-cm/dpp_nucleo-c031c6/qview/img/BTN_UP.gif new file mode 100644 index 00000000..3246ff98 Binary files /dev/null and b/examples/arm-cm/dpp_nucleo-c031c6/qview/img/BTN_UP.gif differ diff --git a/examples/arm-cm/dpp_nucleo-c031c6/qview/img/eating.gif b/examples/arm-cm/dpp_nucleo-c031c6/qview/img/eating.gif new file mode 100644 index 00000000..632b9d23 Binary files /dev/null and b/examples/arm-cm/dpp_nucleo-c031c6/qview/img/eating.gif differ diff --git a/examples/arm-cm/dpp_nucleo-c031c6/qview/img/hungry.gif b/examples/arm-cm/dpp_nucleo-c031c6/qview/img/hungry.gif new file mode 100644 index 00000000..dc144db9 Binary files /dev/null and b/examples/arm-cm/dpp_nucleo-c031c6/qview/img/hungry.gif differ diff --git a/examples/arm-cm/dpp_nucleo-c031c6/qview/img/thinking.gif b/examples/arm-cm/dpp_nucleo-c031c6/qview/img/thinking.gif new file mode 100644 index 00000000..ec684ee5 Binary files /dev/null and b/examples/arm-cm/dpp_nucleo-c031c6/qview/img/thinking.gif differ diff --git a/examples/arm-cm/dpp_nucleo-c031c6/qview/qview-dpp.bat b/examples/arm-cm/dpp_nucleo-c031c6/qview/qview-dpp.bat new file mode 100644 index 00000000..b36e43d6 --- /dev/null +++ b/examples/arm-cm/dpp_nucleo-c031c6/qview/qview-dpp.bat @@ -0,0 +1,8 @@ +@setlocal + +if "%QTOOLS%"=="" ( + set QTOOLS=C:\qp\qtools +) +python3 %QTOOLS%\qview\qview.py dpp.py + +@endlocal diff --git a/examples/arm-cm/dpp_nucleo-c031c6/qview/qview-dpp.lnk b/examples/arm-cm/dpp_nucleo-c031c6/qview/qview-dpp.lnk new file mode 100644 index 00000000..a47d4d8b Binary files /dev/null and b/examples/arm-cm/dpp_nucleo-c031c6/qview/qview-dpp.lnk differ diff --git a/examples/arm-cm/dpp_nucleo-c031c6/qview/qview-dpp1.bat b/examples/arm-cm/dpp_nucleo-c031c6/qview/qview-dpp1.bat new file mode 100644 index 00000000..8bdb9ce5 --- /dev/null +++ b/examples/arm-cm/dpp_nucleo-c031c6/qview/qview-dpp1.bat @@ -0,0 +1,8 @@ +@setlocal + +if "%QTOOLS%"=="" ( + set QTOOLS=C:\qp\qtools +) +python3 %QTOOLS%\qview\qview.py dpp1.py + +@endlocal diff --git a/examples/arm-cm/dpp_nucleo-c031c6/qview/qview-dpp1.lnk b/examples/arm-cm/dpp_nucleo-c031c6/qview/qview-dpp1.lnk new file mode 100644 index 00000000..caf9b345 Binary files /dev/null and b/examples/arm-cm/dpp_nucleo-c031c6/qview/qview-dpp1.lnk differ diff --git a/examples/arm-cm/dpp_nucleo-c031c6/qxk/armclang/dpp-qxk.sct b/examples/arm-cm/dpp_nucleo-c031c6/qxk/armclang/dpp-qxk.sct new file mode 100644 index 00000000..100826b8 --- /dev/null +++ b/examples/arm-cm/dpp_nucleo-c031c6/qxk/armclang/dpp-qxk.sct @@ -0,0 +1,23 @@ +; ************************************************************* +; *** Scatter-Loading Description File generated by uVision *** +; +; Adapted by Quantum Leaps: +; moved STACK as the first section in RW_STACK +; ************************************************************* + +LR_IROM1 0x08000000 0x00008000 { ; load region size_region + ER_IROM1 0x08000000 0x00008000 { ; load address = execution address + *.o (RESET, +First) + *(InRoot$$Sections) + .ANY (+RO) + .ANY (+XO) + } + + RW_STACK 0x20000000 { + * (STACK, +First) + } + RW_IRAM1 +0 (0x00003000 - 2048) { + .ANY (+RW +ZI) + } +} + diff --git a/examples/arm-cm/dpp_nucleo-c031c6/qxk/armclang/dpp-qxk.uvoptx b/examples/arm-cm/dpp_nucleo-c031c6/qxk/armclang/dpp-qxk.uvoptx new file mode 100644 index 00000000..a8513061 --- /dev/null +++ b/examples/arm-cm/dpp_nucleo-c031c6/qxk/armclang/dpp-qxk.uvoptx @@ -0,0 +1,1120 @@ + + + + 1.0 + +
### uVision Project, (C) Keil Software
+ + + *.c + *.s*; *.src; *.a* + *.obj; *.o + *.lib + *.txt; *.h; *.inc; *.md + *.plm + *.cpp + 0 + + + + 0 + 0 + + + + dpp-dbg + 0x4 + ARM-ADS + + 12000000 + + 1 + 1 + 0 + 1 + 0 + + + 1 + 65535 + 0 + 0 + 0 + + + 79 + 66 + 8 + .\dbg\ + + + 1 + 1 + 1 + 0 + 1 + 1 + 0 + 1 + 0 + 0 + 0 + 0 + + + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + + + 1 + 0 + 1 + + 18 + + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + 0 + 1 + 1 + 0 + 0 + 1 + 0 + 0 + 6 + + + + + + + + + + + STLink\ST-LINKIII-KEIL_SWO.dll + + + + 0 + ST-LINKIII-KEIL_SWO + -U066BFF505153848667095842 -O206 -SF10000 -C0 -A0 -I0 -HNlocalhost -HP7184 -P1 -N00("ARM CoreSight SW-DP (ARM Core") -D00(0BC11477) -L00(0) -TO65554 -TC10000000 -TT10000000 -TP21 -TDS8007 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -FO7 -FD20000000 -FC1000 -FN1 -FF0STM32C0x_32.FLM -FS08000000 -FL08000 -FP0($$Device:STM32C031C6Tx$CMSIS\Flash\STM32C0x_32.FLM) + + + 0 + UL2CM3 + -U -O206 -S8 -C0 -P00 -N00("") -D00(00000000) -L00(0) -TO65554 -TC10000000 -TT10000000 -TP21 -TDS8007 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -FO7 -FD20000000 -FC1000 -FN1 -FF0STM32C0x_32.FLM -FS08000000 -FL08000 -FP0($$Device:STM32C031C6Tx$CMSIS\Flash\STM32C0x_32.FLM) + + + 0 + DLGUARM + (105=-1,-1,-1,-1,0) + + + 0 + ARMRTXEVENTFLAGS + -L70 -Z18 -C0 -M0 -T1 + + + 0 + DLGTARM + (1010=-1,-1,-1,-1,0)(1007=-1,-1,-1,-1,0)(1008=-1,-1,-1,-1,0)(1012=-1,-1,-1,-1,0)(1009=-1,-1,-1,-1,0) + + + 0 + ARMDBGFLAGS + + + + + + + 1 + 2 + 0x20000200 + 0 + + + + + 2 + 0 + 0x400 + 0 + + + + 0 + + + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + + + + 0 + 0 + 0 + + + + + + + + + + 1 + 0 + 0 + 2 + 10000000 + + + + + + dpp-rel + 0x4 + ARM-ADS + + 12000000 + + 1 + 1 + 0 + 1 + 0 + + + 1 + 65535 + 0 + 0 + 0 + + + 79 + 66 + 8 + .\rel\ + + + 1 + 1 + 1 + 0 + 1 + 1 + 0 + 1 + 0 + 0 + 0 + 0 + + + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + + + 1 + 0 + 0 + + 18 + + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + 0 + 1 + 1 + 0 + 0 + 1 + 0 + 0 + 6 + + + + + + + + + + + STLink\ST-LINKIII-KEIL_SWO.dll + + + + 0 + UL2CM3 + UL2CM3(-S0 -C0 -P0 ) -FN1 -FC1000 -FD20000000 -FF0STM32C0x_32 -FL08000 -FS08000000 -FP0($$Device:STM32C031C6Tx$CMSIS\Flash\STM32C0x_32.FLM) + + + 0 + ST-LINKIII-KEIL_SWO + UL2CM3(-S0 -C0 -P0 ) -FN1 -FC1000 -FD20000000 -FF0STM32C0x_32 -FL08000 -FS08000000 -FP0($$Device:STM32C031C6Tx$CMSIS\Flash\STM32C0x_32.FLM) + + + 0 + DLGUARM + (105=-1,-1,-1,-1,0) + + + 0 + ARMRTXEVENTFLAGS + -L70 -Z18 -C0 -M0 -T1 + + + 0 + DLGTARM + (1010=-1,-1,-1,-1,0)(1007=-1,-1,-1,-1,0)(1008=-1,-1,-1,-1,0)(1009=-1,-1,-1,-1,0) + + + 0 + ARMDBGFLAGS + + + + + + + 1 + 2 + 0x20000200 + 0 + + + + + 2 + 0 + 0x400 + 0 + + + + 0 + + + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + + + + 0 + 0 + 0 + + + + + + + + + + 1 + 1 + 0 + 2 + 10000000 + + + + + + dpp-spy + 0x4 + ARM-ADS + + 12000000 + + 1 + 1 + 0 + 1 + 0 + + + 1 + 65535 + 0 + 0 + 0 + + + 79 + 66 + 8 + .\spy\ + + + 1 + 1 + 1 + 0 + 1 + 1 + 0 + 1 + 0 + 0 + 0 + 0 + + + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + + + 1 + 0 + 0 + + 18 + + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + 0 + 1 + 1 + 0 + 0 + 1 + 0 + 0 + 6 + + + + + + + + + + + STLink\ST-LINKIII-KEIL_SWO.dll + + + + 0 + UL2CM3 + UL2CM3(-S0 -C0 -P0 ) -FN1 -FC1000 -FD20000000 -FF0STM32C0x_32 -FL08000 -FS08000000 -FP0($$Device:STM32C031C6Tx$CMSIS\Flash\STM32C0x_32.FLM) + + + 0 + ST-LINKIII-KEIL_SWO + -U-O206 -O206 -SF10000 -C0 -A0 -I0 -HNlocalhost -HP7184 -P1 -N00("ARM CoreSight SW-DP (ARM Core") -D00(0BC11477) -L00(0) -TO131090 -TC10000000 -TT10000000 -TP21 -TDS8007 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -FO7 -FD20000000 -FC1000 -FN1 -FF0STM32C0x_32.FLM -FS08000000 -FL08000 -FP0($$Device:STM32C031C6Tx$CMSIS\Flash\STM32C0x_32.FLM) + + + 0 + DLGUARM + (105=-1,-1,-1,-1,0) + + + 0 + ARMRTXEVENTFLAGS + -L70 -Z18 -C0 -M0 -T1 + + + 0 + DLGTARM + (1010=-1,-1,-1,-1,0)(1007=-1,-1,-1,-1,0)(1008=-1,-1,-1,-1,0)(1012=-1,-1,-1,-1,0)(1009=-1,-1,-1,-1,0) + + + 0 + ARMDBGFLAGS + + + + + + + 1 + 2 + 0x20000200 + 0 + + + + + 2 + 0 + 0x400 + 0 + + + + 0 + + + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + + + + 0 + 0 + 0 + + + + + + + + + + 1 + 0 + 0 + 2 + 10000000 + + + + + + Source Code + 1 + 0 + 0 + 0 + + 1 + 1 + 1 + 0 + 0 + 0 + ..\bsp.c + bsp.c + 0 + 0 + + + 1 + 2 + 5 + 0 + 0 + 0 + ..\..\bsp.h + bsp.h + 0 + 0 + + + 1 + 3 + 5 + 0 + 0 + 0 + ..\..\dpp.h + dpp.h + 0 + 0 + + + 1 + 4 + 1 + 0 + 0 + 0 + ..\..\philo.c + philo.c + 0 + 0 + + + 1 + 5 + 1 + 0 + 0 + 0 + ..\..\table.c + table.c + 0 + 0 + + + 1 + 6 + 5 + 0 + 0 + 0 + .\dpp-qxk.sct + dpp-qxk.sct + 0 + 0 + + + 1 + 7 + 1 + 0 + 0 + 0 + ..\xthread1.c + xthread1.c + 0 + 0 + + + 1 + 8 + 1 + 0 + 0 + 0 + ..\xthread2.c + xthread2.c + 0 + 0 + + + 1 + 9 + 1 + 0 + 0 + 0 + ..\..\main.c + main.c + 0 + 0 + + + + + nucleo-c031c6 + 1 + 0 + 0 + 0 + + 2 + 10 + 5 + 0 + 0 + 0 + ..\..\..\..\..\3rd_party\nucleo-c031c6\stm32c0xx.h + stm32c0xx.h + 0 + 0 + + + 2 + 11 + 5 + 0 + 0 + 0 + ..\..\..\..\..\3rd_party\nucleo-c031c6\stm32c031xx.h + stm32c031xx.h + 0 + 0 + + + 2 + 12 + 1 + 0 + 0 + 0 + ..\..\..\..\..\3rd_party\nucleo-c031c6\system_stm32c0xx.c + system_stm32c0xx.c + 0 + 0 + + + 2 + 13 + 2 + 0 + 0 + 0 + ..\..\..\..\..\3rd_party\nucleo-c031c6\arm\startup_stm32c031xx.s + startup_stm32c031xx.s + 0 + 0 + + + + + QP + 1 + 0 + 0 + 0 + + 3 + 14 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qf\qep_hsm.c + qep_hsm.c + 0 + 0 + + + 3 + 15 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qf\qep_msm.c + qep_msm.c + 0 + 0 + + + 3 + 16 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qf\qf_act.c + qf_act.c + 0 + 0 + + + 3 + 17 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qf\qf_actq.c + qf_actq.c + 0 + 0 + + + 3 + 18 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qf\qf_defer.c + qf_defer.c + 0 + 0 + + + 3 + 19 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qf\qf_dyn.c + qf_dyn.c + 0 + 0 + + + 3 + 20 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qf\qf_mem.c + qf_mem.c + 0 + 0 + + + 3 + 21 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qf\qf_ps.c + qf_ps.c + 0 + 0 + + + 3 + 22 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qf\qf_qact.c + qf_qact.c + 0 + 0 + + + 3 + 23 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qf\qf_qeq.c + qf_qeq.c + 0 + 0 + + + 3 + 24 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qf\qf_qmact.c + qf_qmact.c + 0 + 0 + + + 3 + 25 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qf\qf_time.c + qf_time.c + 0 + 0 + + + 3 + 26 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qxk\qxk.c + qxk.c + 0 + 0 + + + 3 + 27 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qxk\qxk_mutex.c + qxk_mutex.c + 0 + 0 + + + 3 + 28 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qxk\qxk_sema.c + qxk_sema.c + 0 + 0 + + + 3 + 29 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qxk\qxk_xthr.c + qxk_xthr.c + 0 + 0 + + + + + QP_port + 1 + 0 + 0 + 0 + + 4 + 30 + 5 + 0 + 0 + 0 + ..\..\..\..\..\ports\arm-cm\qxk\armclang\qep_port.h + qep_port.h + 0 + 0 + + + 4 + 31 + 5 + 0 + 0 + 0 + ..\..\..\..\..\ports\arm-cm\qxk\armclang\qf_port.h + qf_port.h + 0 + 0 + + + 4 + 32 + 5 + 0 + 0 + 0 + ..\..\..\..\..\ports\arm-cm\qxk\armclang\qs_port.h + qs_port.h + 0 + 0 + + + 4 + 33 + 1 + 0 + 0 + 0 + ..\..\..\..\..\ports\arm-cm\qxk\armclang\qxk_port.c + qxk_port.c + 0 + 0 + + + 4 + 34 + 5 + 0 + 0 + 0 + ..\..\..\..\..\ports\arm-cm\qxk\armclang\qxk_port.h + qxk_port.h + 0 + 0 + + + + + QS + 1 + 0 + 0 + 0 + + 5 + 35 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qs\qs.c + qs.c + 0 + 0 + + + 5 + 36 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qs\qs_64bit.c + qs_64bit.c + 0 + 0 + + + 5 + 37 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qs\qs_fp.c + qs_fp.c + 0 + 0 + + + 5 + 38 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qs\qs_rx.c + qs_rx.c + 0 + 0 + + + 5 + 39 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qs\qstamp.c + qstamp.c + 0 + 0 + + + +
diff --git a/examples/arm-cm/dpp_nucleo-c031c6/qxk/armclang/dpp-qxk.uvprojx b/examples/arm-cm/dpp_nucleo-c031c6/qxk/armclang/dpp-qxk.uvprojx new file mode 100644 index 00000000..32d048a8 --- /dev/null +++ b/examples/arm-cm/dpp_nucleo-c031c6/qxk/armclang/dpp-qxk.uvprojx @@ -0,0 +1,1943 @@ + + + + 2.1 + +
### uVision Project, (C) Keil Software
+ + + + dpp-dbg + 0x4 + ARM-ADS + 6160000::V6.16::ARMCLANG + 1 + + + STM32C031C6Tx + STMicroelectronics + Keil.STM32C0xx_DFP.1.0.0 + https://www.keil.com/pack/ + IRAM(0x20000000,0x00003000) IROM(0x08000000,0x00008000) CPUTYPE("Cortex-M0+") CLOCK(12000000) ELITTLE + + + UL2CM3(-S0 -C0 -P0 -FD20000000 -FC1000 -FN1 -FF0STM32C0x_32 -FS08000000 -FL08000 -FP0($$Device:STM32C031C6Tx$CMSIS\Flash\STM32C0x_32.FLM)) + 0 + $$Device:STM32C031C6Tx$Drivers\CMSIS\Device\ST\STM32C0xx\Include\stm32c0xx.h + + + + + + + + + + $$Device:STM32C031C6Tx$CMSIS\SVD\STM32C031.svd + 0 + 0 + + + + + + + 0 + 0 + 0 + 0 + 1 + + .\dbg\ + dpp-qxk + 1 + 0 + 0 + 1 + 1 + .\dbg\ + 1 + 0 + 0 + + 0 + 0 + + + 0 + 0 + 0 + 0 + + + 1 + 0 + cmd /c "del .\dbg\qstamp.o" + + 0 + 0 + 0 + 0 + + + 1 + 0 + fromelf --bin --output .\dbg\dpp-qxk.bin .\dbg\dpp-qxk.axf + + 0 + 0 + 0 + 0 + + 0 + + + + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 3 + + + 1 + + + SARMCM3.DLL + -REMAP-MPU + DARMCM1.DLL + -pCM0+ + SARMCM3.DLL + -MPU + TARMCM1.DLL + -pCM0+ + + + + 1 + 0 + 0 + 0 + 16 + + + + + 1 + 0 + 0 + 1 + 1 + 4096 + + 1 + BIN\UL2CM3.DLL + "" () + + + + + 0 + + + + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + 1 + 0 + 0 + 0 + 0 + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + "Cortex-M0+" + + 0 + 0 + 0 + 1 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 8 + 0 + 0 + 0 + 0 + 3 + 3 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 1 + 0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x20000000 + 0x3000 + + + 1 + 0x8000000 + 0x8000 + + + 0 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x8000000 + 0x8000 + + + 1 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x20000000 + 0x3000 + + + 0 + 0x0 + 0x0 + + + + + + 0 + 1 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 3 + 0 + 1 + 0 + 0 + 0 + 3 + 3 + 0 + 0 + 0 + 0 + 0 + + + QF_ON_CONTEXT_SW + + ..\..;..\..\..\..\..\include;..\..\..\..\..\ports\arm-cm\qxk\armclang;..\..\..\..\..\3rd_party\CMSIS\Include;..\..\..\..\..\3rd_party\nucleo-c031c6 + + + + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 4 + + + Stack_Size=2048 Heap_Size=16 + + + + + + 0 + 0 + 0 + 0 + 1 + 0 + 0x00000000 + 0x20000000 + + .\dpp-qxk.sct + + + --entry Reset_Handler + + + + + + + + Source Code + + + bsp.c + 1 + ..\bsp.c + + + bsp.h + 5 + ..\..\bsp.h + + + dpp.h + 5 + ..\..\dpp.h + + + philo.c + 1 + ..\..\philo.c + + + table.c + 1 + ..\..\table.c + + + dpp-qxk.sct + 5 + .\dpp-qxk.sct + + + xthread1.c + 1 + ..\xthread1.c + + + xthread2.c + 1 + ..\xthread2.c + + + main.c + 1 + ..\..\main.c + + + + + nucleo-c031c6 + + + stm32c0xx.h + 5 + ..\..\..\..\..\3rd_party\nucleo-c031c6\stm32c0xx.h + + + stm32c031xx.h + 5 + ..\..\..\..\..\3rd_party\nucleo-c031c6\stm32c031xx.h + + + system_stm32c0xx.c + 1 + ..\..\..\..\..\3rd_party\nucleo-c031c6\system_stm32c0xx.c + + + startup_stm32c031xx.s + 2 + ..\..\..\..\..\3rd_party\nucleo-c031c6\arm\startup_stm32c031xx.s + + + + + QP + + + qep_hsm.c + 1 + ..\..\..\..\..\src\qf\qep_hsm.c + + + qep_msm.c + 1 + ..\..\..\..\..\src\qf\qep_msm.c + + + qf_act.c + 1 + ..\..\..\..\..\src\qf\qf_act.c + + + qf_actq.c + 1 + ..\..\..\..\..\src\qf\qf_actq.c + + + qf_defer.c + 1 + ..\..\..\..\..\src\qf\qf_defer.c + + + qf_dyn.c + 1 + ..\..\..\..\..\src\qf\qf_dyn.c + + + qf_mem.c + 1 + ..\..\..\..\..\src\qf\qf_mem.c + + + qf_ps.c + 1 + ..\..\..\..\..\src\qf\qf_ps.c + + + qf_qact.c + 1 + ..\..\..\..\..\src\qf\qf_qact.c + + + qf_qeq.c + 1 + ..\..\..\..\..\src\qf\qf_qeq.c + + + qf_qmact.c + 1 + ..\..\..\..\..\src\qf\qf_qmact.c + + + qf_time.c + 1 + ..\..\..\..\..\src\qf\qf_time.c + + + qxk.c + 1 + ..\..\..\..\..\src\qxk\qxk.c + + + qxk_mutex.c + 1 + ..\..\..\..\..\src\qxk\qxk_mutex.c + + + qxk_sema.c + 1 + ..\..\..\..\..\src\qxk\qxk_sema.c + + + qxk_xthr.c + 1 + ..\..\..\..\..\src\qxk\qxk_xthr.c + + + + + QP_port + + + qep_port.h + 5 + ..\..\..\..\..\ports\arm-cm\qxk\armclang\qep_port.h + + + qf_port.h + 5 + ..\..\..\..\..\ports\arm-cm\qxk\armclang\qf_port.h + + + qs_port.h + 5 + ..\..\..\..\..\ports\arm-cm\qxk\armclang\qs_port.h + + + qxk_port.c + 1 + ..\..\..\..\..\ports\arm-cm\qxk\armclang\qxk_port.c + + + qxk_port.h + 5 + ..\..\..\..\..\ports\arm-cm\qxk\armclang\qxk_port.h + + + + + QS + + + 0 + 0 + 0 + 0 + 0 + 0 + 2 + 2 + 2 + 2 + 11 + + + 1 + + + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 0 + 0 + 0 + 0 + 2 + + + + + + + + + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + + + + + + + + + + + + qs.c + 1 + ..\..\..\..\..\src\qs\qs.c + + + qs_64bit.c + 1 + ..\..\..\..\..\src\qs\qs_64bit.c + + + qs_fp.c + 1 + ..\..\..\..\..\src\qs\qs_fp.c + + + qs_rx.c + 1 + ..\..\..\..\..\src\qs\qs_rx.c + + + qstamp.c + 1 + ..\..\..\..\..\src\qs\qstamp.c + + + + + + + dpp-rel + 0x4 + ARM-ADS + 6160000::V6.16::ARMCLANG + 1 + + + STM32C031C6Tx + STMicroelectronics + Keil.STM32C0xx_DFP.1.0.0 + https://www.keil.com/pack/ + IRAM(0x20000000,0x00003000) IROM(0x08000000,0x00008000) CPUTYPE("Cortex-M0+") CLOCK(12000000) ELITTLE + + + UL2CM3(-S0 -C0 -P0 -FD20000000 -FC1000 -FN1 -FF0STM32C0x_32 -FS08000000 -FL08000 -FP0($$Device:STM32C031C6Tx$CMSIS\Flash\STM32C0x_32.FLM)) + 0 + $$Device:STM32C031C6Tx$Drivers\CMSIS\Device\ST\STM32C0xx\Include\stm32c0xx.h + + + + + + + + + + $$Device:STM32C031C6Tx$CMSIS\SVD\STM32C031.svd + 0 + 0 + + + + + + + 0 + 0 + 0 + 0 + 1 + + .\rel\ + dpp-qxk + 1 + 0 + 0 + 0 + 0 + .\rel\ + 1 + 0 + 0 + + 0 + 0 + + + 0 + 0 + 0 + 0 + + + 1 + 0 + cmd /c "del .\rel\qstamp.o" + + 0 + 0 + 0 + 0 + + + 1 + 0 + fromelf --bin --output .\rel\dpp-qxk.bin .\rel\dpp-qxk.axf + + 0 + 0 + 0 + 0 + + 0 + + + + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 3 + + + 1 + + + SARMCM3.DLL + -REMAP-MPU + DARMCM1.DLL + -pCM0+ + SARMCM3.DLL + -MPU + TARMCM1.DLL + -pCM0+ + + + + 1 + 0 + 0 + 0 + 16 + + + + + 1 + 0 + 0 + 1 + 1 + 4097 + + 1 + BIN\UL2CM3.DLL + + + + + + 0 + + + + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + 1 + 0 + 0 + 0 + 0 + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + "Cortex-M0+" + + 0 + 0 + 0 + 1 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 8 + 0 + 0 + 0 + 0 + 3 + 3 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 1 + 0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x20000000 + 0x3000 + + + 1 + 0x8000000 + 0x8000 + + + 0 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x8000000 + 0x8000 + + + 1 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x20000000 + 0x3000 + + + 0 + 0x0 + 0x0 + + + + + + 0 + 6 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 3 + 0 + 1 + 0 + 0 + 0 + 3 + 3 + 0 + 0 + 0 + 0 + 0 + + + NDEBUG,QF_ON_CONTEXT_SW + + ..\..;..\..\..\..\..\include;..\..\..\..\..\ports\arm-cm\qxk\armclang;..\..\..\..\..\3rd_party\CMSIS\Include;..\..\..\..\..\3rd_party\nucleo-c031c6 + + + + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 4 + + + Stack_Size=2048 Heap_Size=16 + + + + + + 0 + 0 + 0 + 0 + 1 + 0 + 0x00000000 + 0x20000000 + + .\dpp-qxk.sct + + + --entry Reset_Handler + + + + + + + + Source Code + + + bsp.c + 1 + ..\bsp.c + + + bsp.h + 5 + ..\..\bsp.h + + + dpp.h + 5 + ..\..\dpp.h + + + philo.c + 1 + ..\..\philo.c + + + table.c + 1 + ..\..\table.c + + + dpp-qxk.sct + 5 + .\dpp-qxk.sct + + + xthread1.c + 1 + ..\xthread1.c + + + xthread2.c + 1 + ..\xthread2.c + + + main.c + 1 + ..\..\main.c + + + + + nucleo-c031c6 + + + stm32c0xx.h + 5 + ..\..\..\..\..\3rd_party\nucleo-c031c6\stm32c0xx.h + + + stm32c031xx.h + 5 + ..\..\..\..\..\3rd_party\nucleo-c031c6\stm32c031xx.h + + + system_stm32c0xx.c + 1 + ..\..\..\..\..\3rd_party\nucleo-c031c6\system_stm32c0xx.c + + + startup_stm32c031xx.s + 2 + ..\..\..\..\..\3rd_party\nucleo-c031c6\arm\startup_stm32c031xx.s + + + + + QP + + + qep_hsm.c + 1 + ..\..\..\..\..\src\qf\qep_hsm.c + + + qep_msm.c + 1 + ..\..\..\..\..\src\qf\qep_msm.c + + + qf_act.c + 1 + ..\..\..\..\..\src\qf\qf_act.c + + + qf_actq.c + 1 + ..\..\..\..\..\src\qf\qf_actq.c + + + qf_defer.c + 1 + ..\..\..\..\..\src\qf\qf_defer.c + + + qf_dyn.c + 1 + ..\..\..\..\..\src\qf\qf_dyn.c + + + qf_mem.c + 1 + ..\..\..\..\..\src\qf\qf_mem.c + + + qf_ps.c + 1 + ..\..\..\..\..\src\qf\qf_ps.c + + + qf_qact.c + 1 + ..\..\..\..\..\src\qf\qf_qact.c + + + qf_qeq.c + 1 + ..\..\..\..\..\src\qf\qf_qeq.c + + + qf_qmact.c + 1 + ..\..\..\..\..\src\qf\qf_qmact.c + + + qf_time.c + 1 + ..\..\..\..\..\src\qf\qf_time.c + + + qxk.c + 1 + ..\..\..\..\..\src\qxk\qxk.c + + + qxk_mutex.c + 1 + ..\..\..\..\..\src\qxk\qxk_mutex.c + + + qxk_sema.c + 1 + ..\..\..\..\..\src\qxk\qxk_sema.c + + + qxk_xthr.c + 1 + ..\..\..\..\..\src\qxk\qxk_xthr.c + + + + + QP_port + + + qep_port.h + 5 + ..\..\..\..\..\ports\arm-cm\qxk\armclang\qep_port.h + + + qf_port.h + 5 + ..\..\..\..\..\ports\arm-cm\qxk\armclang\qf_port.h + + + qs_port.h + 5 + ..\..\..\..\..\ports\arm-cm\qxk\armclang\qs_port.h + + + qxk_port.c + 1 + ..\..\..\..\..\ports\arm-cm\qxk\armclang\qxk_port.c + + + qxk_port.h + 5 + ..\..\..\..\..\ports\arm-cm\qxk\armclang\qxk_port.h + + + + + QS + + + 0 + 0 + 0 + 0 + 0 + 0 + 2 + 2 + 2 + 2 + 11 + + + 1 + + + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 0 + 0 + 0 + 0 + 2 + + + + + + + + + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + + + + + + + + + + + + qs.c + 1 + ..\..\..\..\..\src\qs\qs.c + + + qs_64bit.c + 1 + ..\..\..\..\..\src\qs\qs_64bit.c + + + qs_fp.c + 1 + ..\..\..\..\..\src\qs\qs_fp.c + + + qs_rx.c + 1 + ..\..\..\..\..\src\qs\qs_rx.c + + + qstamp.c + 1 + ..\..\..\..\..\src\qs\qstamp.c + + + + + + + dpp-spy + 0x4 + ARM-ADS + 6160000::V6.16::ARMCLANG + 1 + + + STM32C031C6Tx + STMicroelectronics + Keil.STM32C0xx_DFP.1.0.0 + https://www.keil.com/pack/ + IRAM(0x20000000,0x00003000) IROM(0x08000000,0x00008000) CPUTYPE("Cortex-M0+") CLOCK(12000000) ELITTLE + + + UL2CM3(-S0 -C0 -P0 -FD20000000 -FC1000 -FN1 -FF0STM32C0x_32 -FS08000000 -FL08000 -FP0($$Device:STM32C031C6Tx$CMSIS\Flash\STM32C0x_32.FLM)) + 0 + $$Device:STM32C031C6Tx$Drivers\CMSIS\Device\ST\STM32C0xx\Include\stm32c0xx.h + + + + + + + + + + $$Device:STM32C031C6Tx$CMSIS\SVD\STM32C031.svd + 0 + 0 + + + + + + + 0 + 0 + 0 + 0 + 1 + + .\spy\ + dpp-qxk + 1 + 0 + 0 + 1 + 1 + .\spy\ + 1 + 0 + 0 + + 0 + 0 + + + 0 + 0 + 0 + 0 + + + 1 + 0 + cmd /c "del .\spy\qstamp.o" + + 0 + 0 + 0 + 0 + + + 1 + 0 + fromelf --bin --output .\spy\dpp-qxk.bin .\spy\dpp-qxk.axf + + 0 + 0 + 0 + 0 + + 0 + + + + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 3 + + + 1 + + + SARMCM3.DLL + -REMAP-MPU + DARMCM1.DLL + -pCM0+ + SARMCM3.DLL + -MPU + TARMCM1.DLL + -pCM0+ + + + + 1 + 0 + 0 + 0 + 16 + + + + + 1 + 0 + 0 + 1 + 1 + 4096 + + 1 + BIN\UL2CM3.DLL + + + + + + 0 + + + + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + 1 + 0 + 0 + 0 + 0 + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + "Cortex-M0+" + + 0 + 0 + 0 + 1 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 8 + 0 + 0 + 0 + 0 + 3 + 3 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 1 + 0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x20000000 + 0x3000 + + + 1 + 0x8000000 + 0x8000 + + + 0 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x8000000 + 0x8000 + + + 1 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x20000000 + 0x3000 + + + 0 + 0x0 + 0x0 + + + + + + 0 + 2 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 3 + 0 + 1 + 0 + 0 + 0 + 3 + 3 + 0 + 0 + 0 + 0 + 0 + + + Q_SPY,QF_ON_CONTEXT_SW + + ..\..;..\..\..\..\..\include;..\..\..\..\..\ports\arm-cm\qxk\armclang;..\..\..\..\..\3rd_party\CMSIS\Include;..\..\..\..\..\3rd_party\nucleo-c031c6 + + + + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 4 + + + Stack_Size=2048 Heap_Size=16 + + + + + + 0 + 0 + 0 + 0 + 1 + 0 + 0x00000000 + 0x20000000 + + .\dpp-qxk.sct + + + --entry Reset_Handler + + + + + + + + Source Code + + + bsp.c + 1 + ..\bsp.c + + + bsp.h + 5 + ..\..\bsp.h + + + dpp.h + 5 + ..\..\dpp.h + + + philo.c + 1 + ..\..\philo.c + + + table.c + 1 + ..\..\table.c + + + dpp-qxk.sct + 5 + .\dpp-qxk.sct + + + xthread1.c + 1 + ..\xthread1.c + + + xthread2.c + 1 + ..\xthread2.c + + + main.c + 1 + ..\..\main.c + + + + + nucleo-c031c6 + + + stm32c0xx.h + 5 + ..\..\..\..\..\3rd_party\nucleo-c031c6\stm32c0xx.h + + + stm32c031xx.h + 5 + ..\..\..\..\..\3rd_party\nucleo-c031c6\stm32c031xx.h + + + system_stm32c0xx.c + 1 + ..\..\..\..\..\3rd_party\nucleo-c031c6\system_stm32c0xx.c + + + startup_stm32c031xx.s + 2 + ..\..\..\..\..\3rd_party\nucleo-c031c6\arm\startup_stm32c031xx.s + + + + + QP + + + qep_hsm.c + 1 + ..\..\..\..\..\src\qf\qep_hsm.c + + + qep_msm.c + 1 + ..\..\..\..\..\src\qf\qep_msm.c + + + qf_act.c + 1 + ..\..\..\..\..\src\qf\qf_act.c + + + qf_actq.c + 1 + ..\..\..\..\..\src\qf\qf_actq.c + + + qf_defer.c + 1 + ..\..\..\..\..\src\qf\qf_defer.c + + + qf_dyn.c + 1 + ..\..\..\..\..\src\qf\qf_dyn.c + + + qf_mem.c + 1 + ..\..\..\..\..\src\qf\qf_mem.c + + + qf_ps.c + 1 + ..\..\..\..\..\src\qf\qf_ps.c + + + qf_qact.c + 1 + ..\..\..\..\..\src\qf\qf_qact.c + + + qf_qeq.c + 1 + ..\..\..\..\..\src\qf\qf_qeq.c + + + qf_qmact.c + 1 + ..\..\..\..\..\src\qf\qf_qmact.c + + + qf_time.c + 1 + ..\..\..\..\..\src\qf\qf_time.c + + + qxk.c + 1 + ..\..\..\..\..\src\qxk\qxk.c + + + qxk_mutex.c + 1 + ..\..\..\..\..\src\qxk\qxk_mutex.c + + + qxk_sema.c + 1 + ..\..\..\..\..\src\qxk\qxk_sema.c + + + qxk_xthr.c + 1 + ..\..\..\..\..\src\qxk\qxk_xthr.c + + + + + QP_port + + + qep_port.h + 5 + ..\..\..\..\..\ports\arm-cm\qxk\armclang\qep_port.h + + + qf_port.h + 5 + ..\..\..\..\..\ports\arm-cm\qxk\armclang\qf_port.h + + + qs_port.h + 5 + ..\..\..\..\..\ports\arm-cm\qxk\armclang\qs_port.h + + + qxk_port.c + 1 + ..\..\..\..\..\ports\arm-cm\qxk\armclang\qxk_port.c + + + qxk_port.h + 5 + ..\..\..\..\..\ports\arm-cm\qxk\armclang\qxk_port.h + + + + + QS + + + qs.c + 1 + ..\..\..\..\..\src\qs\qs.c + + + qs_64bit.c + 1 + ..\..\..\..\..\src\qs\qs_64bit.c + + + qs_fp.c + 1 + ..\..\..\..\..\src\qs\qs_fp.c + + + qs_rx.c + 1 + ..\..\..\..\..\src\qs\qs_rx.c + + + qstamp.c + 1 + ..\..\..\..\..\src\qs\qstamp.c + + + + + + + + + + + + + +
diff --git a/examples/arm-cm/dpp_nucleo-c031c6/qxk/bsp.c b/examples/arm-cm/dpp_nucleo-c031c6/qxk/bsp.c new file mode 100644 index 00000000..521987db --- /dev/null +++ b/examples/arm-cm/dpp_nucleo-c031c6/qxk/bsp.c @@ -0,0 +1,549 @@ +//============================================================================ +// Product: DPP example, NUCLEO-C031C6 board, QXK kernel +// Last updated for version 7.3.0 +// Last updated on 2023-08-15 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. +// +// This program is open source software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Alternatively, this program may be distributed and modified under the +// terms of Quantum Leaps commercial licenses, which expressly supersede +// the GNU General Public License and are specifically designed for +// licensees interested in retaining the proprietary status of their code. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Contact information: +// +// +//============================================================================ +#include "qpc.h" // QP/C real-time embedded framework +#include "dpp.h" // DPP Application interface +#include "bsp.h" // Board Support Package + +#include "stm32c0xx.h" // CMSIS-compliant header file for the MCU used +// add other drivers if necessary... + +Q_DEFINE_THIS_FILE // define the name of this file for assertions + +// Local-scope defines ----------------------------------------------------- +// LED pins available on the board (just one user LED LD4--Green on PA.5) +#define LD4_PIN 5U + +// Button pins available on the board (just one user Button B1 on PC.13) +#define B1_PIN 13U + +static uint32_t l_rndSeed; + +#ifdef Q_SPY + QSTimeCtr QS_tickTime_; + QSTimeCtr QS_tickPeriod_; + + // QSpy source IDs + static QSpyId const l_SysTick_Handler = { 0U }; + + enum AppRecords { // application-specific trace records + PHILO_STAT = QS_USER, + PAUSED_STAT, + CONTEXT_SW, + }; + +#endif + +//============================================================================ +// Error handler and ISRs... + +Q_NORETURN Q_onError(char const * const module, int_t const id) { + // NOTE: this implementation of the assertion handler is intended only + // for debugging and MUST be changed for deployment of the application + // (assuming that you ship your production code with assertions enabled). + Q_UNUSED_PAR(module); + Q_UNUSED_PAR(id); + QS_ASSERTION(module, id, 10000U); + +#ifndef NDEBUG + // light up the user LED + GPIOA->BSRR = (1U << LD4_PIN); // turn LED on + // for debugging, hang on in an endless loop... + for (;;) { + } +#endif + + NVIC_SystemReset(); +} +//............................................................................ +void assert_failed(char const * const module, int_t const id); // prototype +void assert_failed(char const * const module, int_t const id) { + Q_onError(module, id); +} + +// ISRs used in the application ========================================== +void SysTick_Handler(void); // prototype +void SysTick_Handler(void) { + QXK_ISR_ENTRY(); // inform QXK about entering an ISR + + QTIMEEVT_TICK_X(0U, &l_SysTick_Handler); // time events at rate 0 + + // Perform the debouncing of buttons. The algorithm for debouncing + // adapted from the book "Embedded Systems Dictionary" by Jack Ganssle + // and Michael Barr, page 71. + static struct { + uint32_t depressed; + uint32_t previous; + } buttons = { 0U, 0U }; + + uint32_t current = ~GPIOC->IDR; // read Port C with state of Button B1 + uint32_t tmp = buttons.depressed; // save the depressed buttons + buttons.depressed |= (buttons.previous & current); // set depressed + buttons.depressed &= (buttons.previous | current); // clear released + buttons.previous = current; // update the history + tmp ^= buttons.depressed; // changed debounced depressed + current = buttons.depressed; + + if ((tmp & (1U << B1_PIN)) != 0U) { // debounced B1 state changed? + if ((current & (1U << B1_PIN)) != 0U) { // is B1 depressed? + static QEvt const pauseEvt = QEVT_INITIALIZER(PAUSE_SIG); + QACTIVE_PUBLISH(&pauseEvt, &l_SysTick_Handler); + } + else { // the button is released + static QEvt const serveEvt = QEVT_INITIALIZER(SERVE_SIG); + QACTIVE_PUBLISH(&serveEvt, &l_SysTick_Handler); + } + } + +#ifdef Q_SPY + tmp = SysTick->CTRL; // clear CTRL_COUNTFLAG + QS_tickTime_ += QS_tickPeriod_; // account for the clock rollover +#endif + + QXK_ISR_EXIT(); // inform QXK about exiting an ISR +} +//............................................................................ +// interrupt handler for testing preemptions in QXK +void EXTI0_1_IRQHandler(void); // prototype +void EXTI0_1_IRQHandler(void) { + QXK_ISR_ENTRY(); // inform QXK about entering an ISR + + static QEvt const testEvt = QEVT_INITIALIZER(TEST_SIG); + QACTIVE_POST(AO_Table, &testEvt, (void *)0); + + QXK_ISR_EXIT(); // inform QXK about exiting an ISR +} + +//............................................................................ +#ifdef Q_SPY +// ISR for receiving bytes from the QSPY Back-End +// NOTE: This ISR is "QF-unaware" meaning that it does not interact with +// the QF/QXK and is not disabled. Such ISRs don't need to call +// QXK_ISR_ENTRY/QXK_ISR_EXIT and they cannot post or publish events. + +void USART2_IRQHandler(void); // prototype +void USART2_IRQHandler(void) { // used in QS-RX (kernel UNAWARE interrutp) + // is RX register NOT empty? + if ((USART2->ISR & (1U << 5)) != 0) { + uint32_t b = USART2->RDR; + QS_RX_PUT(b); + } + + QXK_ARM_ERRATUM_838869(); +} +#endif // Q_SPY + +//............................................................................ +#ifdef QF_ON_CONTEXT_SW +// NOTE: the context-switch callback is called with interrupts DISABLED +void QF_onContextSw(QActive *prev, QActive *next) { + QS_BEGIN_INCRIT(CONTEXT_SW, 0U) // in critical section! + QS_OBJ(prev); + QS_OBJ(next); + QS_END_INCRIT() +} +#endif // QF_ON_CONTEXT_SW + +//============================================================================ +// BSP functions... + +void BSP_init(void) { + // Configure the MPU to prevent NULL-pointer dereferencing ... + MPU->RBAR = 0x0U // base address (NULL) + | MPU_RBAR_VALID_Msk // valid region + | (MPU_RBAR_REGION_Msk & 7U); // region #7 + MPU->RASR = (7U << MPU_RASR_SIZE_Pos) // 2^(7+1) region + | (0x0U << MPU_RASR_AP_Pos) // no-access region + | MPU_RASR_ENABLE_Msk; // region enable + MPU->CTRL = MPU_CTRL_PRIVDEFENA_Msk // enable background region + | MPU_CTRL_ENABLE_Msk; // enable the MPU + __ISB(); + __DSB(); + + // NOTE: SystemInit() has been already called from the startup code + // but SystemCoreClock needs to be updated + SystemCoreClockUpdate(); + + // enable GPIOA clock port for the LED LD4 + RCC->IOPENR |= (1U << 0U); + + // set all used GPIOA pins as push-pull output, no pull-up, pull-down + GPIOA->MODER &= ~(3U << 2U*LD4_PIN); + GPIOA->MODER |= (1U << 2U*LD4_PIN); + GPIOA->OTYPER &= ~(1U << LD4_PIN); + GPIOA->OSPEEDR &= ~(3U << 2U*LD4_PIN); + GPIOA->OSPEEDR |= (1U << 2U*LD4_PIN); + GPIOA->PUPDR &= ~(3U << 2U*LD4_PIN); + + // enable GPIOC clock port for the Button B1 + RCC->IOPENR |= (1U << 2U); + + // configure Button B1 pin on GPIOC as input, no pull-up, pull-down + GPIOC->MODER &= ~(3U << 2U*B1_PIN); + GPIOC->PUPDR &= ~(3U << 2U*B1_PIN); + + BSP_randomSeed(1234U); // seed the random number generator + + // initialize the QS software tracing... + if (!QS_INIT((void *)0)) { + Q_ERROR(); + } + + // dictionaries... + QS_OBJ_DICTIONARY(&l_SysTick_Handler); + QS_USR_DICTIONARY(PHILO_STAT); + QS_USR_DICTIONARY(PAUSED_STAT); + QS_USR_DICTIONARY(CONTEXT_SW); + + QS_ONLY(produce_sig_dict()); + + // setup the QS filters... + QS_GLB_FILTER(QS_ALL_RECORDS); // all records + QS_GLB_FILTER(-QS_QF_TICK); // exclude the clock tick +} +//............................................................................ +void BSP_start(void) { + // initialize event pools + static QF_MPOOL_EL(TableEvt) smlPoolSto[2*N_PHILO]; + QF_poolInit(smlPoolSto, sizeof(smlPoolSto), sizeof(smlPoolSto[0])); + + // initialize publish-subscribe + static QSubscrList subscrSto[MAX_PUB_SIG]; + QActive_psInit(subscrSto, Q_DIM(subscrSto)); + + // instantiate and start AOs/threads... + static QEvt const *xThread1QueueSto[5]; + static uint64_t xThread1StackSto[64]; + XThread1_ctor(); + QXTHREAD_START(TH_XThread1, + 1U, // QP priority of the thread + xThread1QueueSto, // event queue storage + Q_DIM(xThread1QueueSto), // event length [events] + xThread1StackSto, // stack storage + sizeof(xThread1StackSto), // stack size [bytes] + (void *)0); // no initialization param + + static QEvt const *philoQueueSto[N_PHILO][10]; + for (uint8_t n = 0U; n < N_PHILO; ++n) { + Philo_ctor(n); + QACTIVE_START(AO_Philo[n], + n + 3U, // QF-prio/pthre. see NOTE1 + philoQueueSto[n], // event queue storage + Q_DIM(philoQueueSto[n]), // queue length [events] + (void *)0, 0U, // no stack storage + (void *)0); // no initialization param + } + + static QEvt const *xThread2QueueSto[5]; + static uint64_t xThread2StackSto[64]; + XThread2_ctor(); + QXTHREAD_START(TH_XThread2, + N_PHILO + 5U, // QP priority of the thread + xThread2QueueSto, // event queue storage + Q_DIM(xThread2QueueSto), // event length [events] + xThread2StackSto, // stack storage + sizeof(xThread2StackSto), // stack size [bytes] + (void *)0); // no initialization param + + static QEvt const *tableQueueSto[N_PHILO]; + Table_ctor(); + QACTIVE_START(AO_Table, + N_PHILO + 7U, // QP prio. of the AO + tableQueueSto, // event queue storage + Q_DIM(tableQueueSto), // queue length [events] + (void *)0, 0U, // no stack storage + (void *)0); // no initialization param +} +//............................................................................ +void BSP_displayPhilStat(uint8_t n, char const *stat) { + Q_UNUSED_PAR(n); + + if (stat[0] == 'h') { + GPIOA->BSRR = (1U << LD4_PIN); // turn LED on + } + else { + GPIOA->BSRR = (1U << (LD4_PIN + 16U)); // turn LED off + } + + // app-specific trace record... + QS_BEGIN_ID(PHILO_STAT, AO_Table->prio) + QS_U8(1, n); // Philosopher number + QS_STR(stat); // Philosopher status + QS_END() +} +//............................................................................ +void BSP_displayPaused(uint8_t const paused) { + // not enough LEDs to implement this feature + if (paused != 0U) { + //GPIOA->BSRR = (1U << LD4_PIN); // turn LED[n] on + } + else { + //GPIOA->BSRR = (1U << (LD4_PIN + 16U)); // turn LED[n] off + } + + // application-specific trace record + QS_BEGIN_ID(PAUSED_STAT, AO_Table->prio) + QS_U8(1, paused); // Paused status + QS_END() +} +//............................................................................ +void BSP_randomSeed(uint32_t seed) { + l_rndSeed = seed; +} +//............................................................................ +uint32_t BSP_random(void) { // a very cheap pseudo-random-number generator + + QSchedStatus lockStat = QXK_schedLock(N_PHILO); + // "Super-Duper" Linear Congruential Generator (LCG) + // LCG(2^32, 3*7*11*13*23, 0, seed) + // + uint32_t rnd = l_rndSeed * (3U*7U*11U*13U*23U); + l_rndSeed = rnd; // set for the next time + QXK_schedUnlock(lockStat); + + return (rnd >> 8U); +} +//............................................................................ +void BSP_ledOn() { + GPIOA->BSRR = (1U << LD4_PIN); // turn LED on +} +//............................................................................ +void BSP_ledOff() { + GPIOA->BSRR = (1U << (LD4_PIN + 16U)); // turn LED off +} +//............................................................................ +void BSP_terminate(int16_t result) { + Q_UNUSED_PAR(result); +} + +//============================================================================ +// QF callbacks... +void QF_onStartup(void) { + // set up the SysTick timer to fire at BSP_TICKS_PER_SEC rate + SysTick_Config(SystemCoreClock / BSP_TICKS_PER_SEC); + + // assign all priority bits for preemption-prio. and none to sub-prio. + NVIC_SetPriorityGrouping(0U); + + // set priorities of ALL ISRs used in the system, see NOTE1 + NVIC_SetPriority(USART2_IRQn, 0); // kernel UNAWARE interrupt + NVIC_SetPriority(EXTI0_1_IRQn, QF_AWARE_ISR_CMSIS_PRI + 0U); + NVIC_SetPriority(SysTick_IRQn, QF_AWARE_ISR_CMSIS_PRI + 1U); + // ... + + // enable IRQs... + NVIC_EnableIRQ(EXTI0_1_IRQn); + +#ifdef Q_SPY + NVIC_EnableIRQ(USART2_IRQn); // UART2 interrupt used for QS-RX +#endif +} +//............................................................................ +void QF_onCleanup(void) { +} +//............................................................................ +void QXK_onIdle(void) { + // toggle an LED on and then off (not enough LEDs, see NOTE02) + //QF_INT_DISABLE(); + //GPIOA->BSRR = (1U << LD4_PIN); // turn LED[n] on + //GPIOA->BSRR = (1U << (LD4_PIN + 16U)); // turn LED[n] off + //QF_INT_ENABLE(); + +#ifdef Q_SPY + QF_INT_DISABLE(); + QS_rxParse(); // parse all the received bytes + QF_INT_ENABLE(); + QF_CRIT_EXIT_NOP(); + + QF_INT_DISABLE(); + if ((USART2->ISR & (1U << 7U)) != 0U) { // is TXE empty? + uint16_t b = QS_getByte(); + if (b != QS_EOD) { // not End-Of-Data? + USART2->TDR = b; // put into the DR register + } + } + QF_INT_ENABLE(); +#elif defined NDEBUG + // Put the CPU and peripherals to the low-power mode. + // you might need to customize the clock management for your application, + // see the datasheet for your particular Cortex-M MCU. + // + // !!!CAUTION!!! + // The WFI instruction stops the CPU clock, which unfortunately disables + // the JTAG port, so the ST-Link debugger can no longer connect to the + // board. For that reason, the call to __WFI() has to be used with CAUTION. + // + // NOTE: If you find your board "frozen" like this, strap BOOT0 to VDD and + // reset the board, then connect with ST-Link Utilities and erase the part. + // The trick with BOOT(0) is it gets the part to run the System Loader + // instead of your broken code. When done disconnect BOOT0, and start over. + // + //__WFI(); // Wait-For-Interrupt +#endif +} + +//============================================================================ +// QS callbacks... +#ifdef Q_SPY + +//............................................................................ +static uint16_t const UARTPrescTable[12] = { + 1U, 2U, 4U, 6U, 8U, 10U, 12U, 16U, 32U, 64U, 128U, 256U +}; + +#define UART_DIV_SAMPLING16(__PCLK__, __BAUD__, __CLOCKPRESCALER__) \ + ((((__PCLK__)/UARTPrescTable[(__CLOCKPRESCALER__)]) \ + + ((__BAUD__)/2U)) / (__BAUD__)) + +#define UART_PRESCALER_DIV1 0U + +// USART2 pins PA.2 and PA.3 +#define USART2_TX_PIN 2U +#define USART2_RX_PIN 3U + +//............................................................................ +uint8_t QS_onStartup(void const *arg) { + Q_UNUSED_PAR(arg); + + static uint8_t qsTxBuf[2*1024]; // buffer for QS-TX channel + QS_initBuf(qsTxBuf, sizeof(qsTxBuf)); + + static uint8_t qsRxBuf[100]; // buffer for QS-RX channel + QS_rxInitBuf(qsRxBuf, sizeof(qsRxBuf)); + + // enable peripheral clock for USART2 + RCC->IOPENR |= ( 1U << 0U); // Enable GPIOA clock for USART pins + RCC->APBENR1 |= ( 1U << 17U); // Enable USART#2 clock + + // Configure PA to USART2_RX, PA to USART2_TX + GPIOA->AFR[0] &= ~((15U << 4U*USART2_RX_PIN) | (15U << 4U*USART2_TX_PIN)); + GPIOA->AFR[0] |= (( 1U << 4U*USART2_RX_PIN) | ( 1U << 4U*USART2_TX_PIN)); + GPIOA->MODER &= ~(( 3U << 2U*USART2_RX_PIN) | ( 3U << 2U*USART2_TX_PIN)); + GPIOA->MODER |= (( 2U << 2U*USART2_RX_PIN) | ( 2U << 2U*USART2_TX_PIN)); + + // baud rate + USART2->BRR = UART_DIV_SAMPLING16( + SystemCoreClock, 115200U, UART_PRESCALER_DIV1); + USART2->CR3 = 0x0000U | // no flow control + (1U << 12U); // disable overrun detection (OVRDIS) + USART2->CR2 = 0x0000U; // 1 stop bit + USART2->CR1 = ((1U << 2U) | // enable RX + (1U << 3U) | // enable TX + (1U << 5U) | // enable RX interrupt + (0U << 12U) | // 8 data bits + (0U << 28U) | // 8 data bits + (1U << 0U)); // enable USART + + QS_tickPeriod_ = SystemCoreClock / BSP_TICKS_PER_SEC; + QS_tickTime_ = QS_tickPeriod_; // to start the timestamp at zero + + return 1U; // return success +} +//............................................................................ +void QS_onCleanup(void) { +} +//............................................................................ +QSTimeCtr QS_onGetTime(void) { // NOTE: invoked with interrupts DISABLED + if ((SysTick->CTRL & 0x00010000) == 0) { // COUNT no set? + return QS_tickTime_ - (QSTimeCtr)SysTick->VAL; + } + else { // the rollover occured, but the SysTick_ISR did not run yet + return QS_tickTime_ + QS_tickPeriod_ - (QSTimeCtr)SysTick->VAL; + } +} +//............................................................................ +void QS_onFlush(void) { + for (;;) { + QF_INT_DISABLE(); + uint16_t b = QS_getByte(); + if (b != QS_EOD) { + while ((USART2->ISR & (1U << 7U)) == 0U) { // while TXE not empty + QF_INT_ENABLE(); + QF_CRIT_EXIT_NOP(); + + QF_INT_DISABLE(); + } + USART2->TDR = b; // put into the DR register + QF_INT_ENABLE(); + } + else { + QF_INT_ENABLE(); + break; + } + } +} +//............................................................................ +//! callback function to reset the target (to be implemented in the BSP) +void QS_onReset(void) { + NVIC_SystemReset(); +} +//............................................................................ +//! callback function to execute a user command +void QS_onCommand(uint8_t cmdId, + uint32_t param1, uint32_t param2, uint32_t param3) +{ + Q_UNUSED_PAR(cmdId); + Q_UNUSED_PAR(param1); + Q_UNUSED_PAR(param2); + Q_UNUSED_PAR(param3); +} + +#endif // Q_SPY +//---------------------------------------------------------------------------- + +//============================================================================ +// NOTE1: +// The QF_AWARE_ISR_CMSIS_PRI constant from the QF port specifies the highest +// ISR priority that is disabled by the QF framework. The value is suitable +// for the NVIC_SetPriority() CMSIS function. +// +// Only ISRs prioritized at or below the QF_AWARE_ISR_CMSIS_PRI level (i.e., +// with the numerical values of priorities equal or higher than +// QF_AWARE_ISR_CMSIS_PRI) are allowed to call the QK_ISR_ENTRY/ +// QXK_ISR_ENTRY macros or any other QF/QXK services. These ISRs are +// "QF-aware". +// +// Conversely, any ISRs prioritized above the QF_AWARE_ISR_CMSIS_PRI priority +// level (i.e., with the numerical values of priorities less than +// QF_AWARE_ISR_CMSIS_PRI) are never disabled and are not aware of the kernel. +// Such "QF-unaware" ISRs cannot call ANY QF/QXK services. In particular they +// can NOT call the macros QXK_ISR_ENTRY/QXK_ISR_ENTRY. The only mechanism +// by which a "QF-unaware" ISR can communicate with the QF framework is by +// triggering a "QF-aware" ISR, which can post/publish events. +// +// NOTE2: +// The User LED is used to visualize the idle loop activity. The brightness +// of the LED is proportional to the frequency of the idle loop. +// Please note that the LED is toggled with interrupts locked, so no interrupt +// execution time contributes to the brightness of the User LED. +// diff --git a/examples/arm-cm/dpp_nucleo-c031c6/qxk/gnu/Makefile b/examples/arm-cm/dpp_nucleo-c031c6/qxk/gnu/Makefile new file mode 100644 index 00000000..bd91c5e8 --- /dev/null +++ b/examples/arm-cm/dpp_nucleo-c031c6/qxk/gnu/Makefile @@ -0,0 +1,323 @@ +############################################################################## +# Product: Makefile for QP/C on NUCLEO-C031C6, QXK kernel, GNU-ARM +# Last Updated for Version: 7.3.0 +# Date of the Last Update: 2023-05-26 +# +# Q u a n t u m L e a P s +# ------------------------ +# Modern Embedded Software +# +# Copyright (C) 2005 Quantum Leaps, LLC. +# +# This program is open source software: you can redistribute it and/or +# modify it under the terms of the GNU General Public License as published +# by the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Alternatively, this program may be distributed and modified under the +# terms of Quantum Leaps commercial licenses, which expressly supersede +# the GNU General Public License and are specifically designed for +# licensees interested in retaining the proprietary status of their code. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# +# Contact information: +# +# +############################################################################## +# examples of invoking this Makefile: +# building configurations: Debug (default), Release, and Spy +# make +# make CONF=rel +# make CONF=spy +# +# cleaning configurations: Debug (default), Release, and Spy +# make clean +# make CONF=rel clean +# make CONF=spy clean +# +# NOTE: +# To use this Makefile on Windows, you will need the GNU make utility, which +# is included in the Qtools collection for Windows, see: +# https://github.com/QuantumLeaps/qtools + +#----------------------------------------------------------------------------- +# project name +# +PROJECT := dpp-qxk + +#----------------------------------------------------------------------------- +# project directories +# + +# location of the QP/C framework (if not provided in an environemnt var.) +ifeq ($(QPC),) +QPC := ../../../../.. +endif + +# QP port used in this project +QP_PORT_DIR := $(QPC)/ports/arm-cm/qxk/gnu + +# list of all source directories used by this project +VPATH = \ + .. \ + ../.. \ + $(QPC)/src/qf \ + $(QPC)/src/qxk \ + $(QPC)/src/qs \ + $(QP_PORT_DIR) \ + $(QPC)/3rd_party/nucleo-c031c6 \ + $(QPC)/3rd_party/nucleo-c031c6/gnu + +# list of all include directories needed by this project +INCLUDES = \ + -I../.. \ + -I$(QPC)/include \ + -I$(QP_PORT_DIR) \ + -I$(QPC)/3rd_party/CMSIS/Include \ + -I$(QPC)/3rd_party/nucleo-c031c6 + +#----------------------------------------------------------------------------- +# files +# + +# assembler source files +ASM_SRCS := + +# C source files +C_SRCS := \ + bsp.c \ + main.c \ + philo.c \ + table.c \ + xthread1.c \ + xthread2.c \ + system_stm32c0xx.c \ + startup_stm32c031xx.c + +# C++ source files +CPP_SRCS := + +OUTPUT := $(PROJECT) +LD_SCRIPT := $(PROJECT).ld + +QP_SRCS := \ + qep_hsm.c \ + qep_msm.c \ + qf_act.c \ + qf_actq.c \ + qf_defer.c \ + qf_dyn.c \ + qf_mem.c \ + qf_ps.c \ + qf_qact.c \ + qf_qeq.c \ + qf_qmact.c \ + qf_time.c \ + qxk.c \ + qxk_xthr.c \ + qxk_sema.c \ + qxk_mutex.c \ + qxk_port.c + +QP_ASMS := + +QS_SRCS := \ + qs.c \ + qs_rx.c \ + qs_fp.c + +LIB_DIRS := +LIBS := + +# defines +DEFINES := \ + -DQF_ON_CONTEXT_SW \ + -DSTM32C031xx \ + -DQXK_USE_IRQ_NUM=31 \ + -DQXK_USE_IRQ_HANDLER=Reserved31_IRQHandler + +# ARM CPU, ARCH, FPU, and Float-ABI types... +# ARM_CPU: [cortex-m0 | cortex-m0plus | cortex-m1 | cortex-m3 | cortex-m4] +# ARM_FPU: [ | vfp] +# FLOAT_ABI: [ | soft | softfp | hard] +# +ARM_CPU := -mcpu=cortex-m0plus +ARM_FPU := +FLOAT_ABI := + +#----------------------------------------------------------------------------- +# GNU-ARM toolset (NOTE: You need to adjust to your machine) +# see https://developer.arm.com/open-source/gnu-toolchain/gnu-rm/downloads +# +ifeq ($(GNU_ARM),) +GNU_ARM := $(QTOOLS)/gnu_arm-none-eabi +endif + +# make sure that the GNU-ARM toolset exists... +ifeq ("$(wildcard $(GNU_ARM))","") +$(error GNU_ARM toolset not found. Please adjust the Makefile) +endif + +CC := $(GNU_ARM)/bin/arm-none-eabi-gcc +CPP := $(GNU_ARM)/bin/arm-none-eabi-g++ +AS := $(GNU_ARM)/bin/arm-none-eabi-as +LINK := $(GNU_ARM)/bin/arm-none-eabi-gcc +BIN := $(GNU_ARM)/bin/arm-none-eabi-objcopy + +############################################################################## +# Typically you should not need to change anything below this line + +# basic utilities (included in QTools for Windows), see: +# https://www.state-machine.com/qtools + +MKDIR := mkdir +RM := rm + +#----------------------------------------------------------------------------- +# build options for various configurations for ARM Cortex-M +# + +# combine all the soruces... +C_SRCS += $(QP_SRCS) +ASM_SRCS += $(QP_ASMS) + +ifeq (rel, $(CONF)) # Release configuration .................................. + +BIN_DIR := rel + +ASFLAGS = $(ARM_CPU) $(ARM_FPU) $(ASM_CPU) $(ASM_FPU) + +CFLAGS = -c $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \ + -ffunction-sections -fdata-sections \ + -O2 $(INCLUDES) $(DEFINES) -DNDEBUG + +CPPFLAGS = -c $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \ + -ffunction-sections -fdata-sections -fno-rtti -fno-exceptions \ + -O2 $(INCLUDES) $(DEFINES) -DNDEBUG + +else ifeq (spy, $(CONF)) # Spy configuration ................................ + +BIN_DIR := spy + +C_SRCS += $(QS_SRCS) + +ASFLAGS = -g $(ARM_CPU) $(ARM_FPU) $(ASM_CPU) $(ASM_FPU) + +CFLAGS = -c -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \ + -ffunction-sections -fdata-sections \ + -O $(INCLUDES) $(DEFINES) -DQ_SPY + +CPPFLAGS = -c -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \ + -ffunction-sections -fdata-sections -fno-rtti -fno-exceptions \ + -O $(INCLUDES) $(DEFINES) -DQ_SPY + +else # default Debug configuration .......................................... + +BIN_DIR := dbg + +ASFLAGS = -g $(ARM_CPU) $(ARM_FPU) $(ASM_CPU) $(ASM_FPU) + +CFLAGS = -c -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \ + -ffunction-sections -fdata-sections \ + -O $(INCLUDES) $(DEFINES) + +CPPFLAGS = -c -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \ + -ffunction-sections -fdata-sections -fno-rtti -fno-exceptions \ + -O $(INCLUDES) $(DEFINES) + +endif # ...................................................................... + + +LINKFLAGS = -T$(LD_SCRIPT) $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb \ + -specs=nosys.specs -specs=nano.specs \ + -Wl,-Map,$(BIN_DIR)/$(OUTPUT).map,--cref,--gc-sections $(LIB_DIRS) + +ASM_OBJS := $(patsubst %.s,%.o, $(notdir $(ASM_SRCS))) +C_OBJS := $(patsubst %.c,%.o, $(notdir $(C_SRCS))) +CPP_OBJS := $(patsubst %.cpp,%.o,$(notdir $(CPP_SRCS))) + +TARGET_BIN := $(BIN_DIR)/$(OUTPUT).bin +TARGET_ELF := $(BIN_DIR)/$(OUTPUT).elf +ASM_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(ASM_OBJS)) +C_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(C_OBJS)) +C_DEPS_EXT := $(patsubst %.o, %.d, $(C_OBJS_EXT)) +CPP_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(CPP_OBJS)) +CPP_DEPS_EXT := $(patsubst %.o, %.d, $(CPP_OBJS_EXT)) + +# create $(BIN_DIR) if it does not exist +ifeq ("$(wildcard $(BIN_DIR))","") +$(shell $(MKDIR) $(BIN_DIR)) +endif + +#----------------------------------------------------------------------------- +# rules +# + +.PHONY : run norun flash + +ifeq ($(MAKECMDGOALS),norun) +all : $(TARGET_BIN) +norun : all +else +all : $(TARGET_BIN) run +endif + +$(TARGET_BIN): $(TARGET_ELF) + $(BIN) -O binary $< $@ + +$(TARGET_ELF) : $(ASM_OBJS_EXT) $(C_OBJS_EXT) $(CPP_OBJS_EXT) + $(CC) $(CFLAGS) $(QPC)/src/qs/qstamp.c -o $(BIN_DIR)/qstamp.o + $(LINK) $(LINKFLAGS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) + +$(BIN_DIR)/%.d : %.c + $(CC) -MM -MT $(@:.d=.o) $(CFLAGS) $< > $@ + +$(BIN_DIR)/%.d : %.cpp + $(CPP) -MM -MT $(@:.d=.o) $(CPPFLAGS) $< > $@ + +$(BIN_DIR)/%.o : %.s + $(AS) $(ASFLAGS) $< -o $@ + +$(BIN_DIR)/%.o : %.c + $(CC) $(CFLAGS) $< -o $@ + +$(BIN_DIR)/%.o : %.cpp + $(CPP) $(CPPFLAGS) $< -o $@ + +.PHONY : clean show + +# include dependency files only if our goal depends on their existence +ifneq ($(MAKECMDGOALS),clean) + ifneq ($(MAKECMDGOALS),show) +-include $(C_DEPS_EXT) $(CPP_DEPS_EXT) + endif +endif + + +clean: + -$(RM) $(BIN_DIR)/*.o \ + $(BIN_DIR)/*.d \ + $(BIN_DIR)/*.bin \ + $(BIN_DIR)/*.elf \ + $(BIN_DIR)/*.map + +show: + @echo PROJECT = $(PROJECT) + @echo CONF = $(CONF) + @echo DEFINES = $(DEFINES) + @echo ASM_FPU = $(ASM_FPU) + @echo ASM_SRCS = $(ASM_SRCS) + @echo C_SRCS = $(C_SRCS) + @echo CPP_SRCS = $(CPP_SRCS) + @echo ASM_OBJS_EXT = $(ASM_OBJS_EXT) + @echo C_OBJS_EXT = $(C_OBJS_EXT) + @echo C_DEPS_EXT = $(C_DEPS_EXT) + @echo CPP_DEPS_EXT = $(CPP_DEPS_EXT) + @echo TARGET_ELF = $(TARGET_ELF) diff --git a/examples/arm-cm/dpp_nucleo-c031c6/qxk/gnu/README.txt b/examples/arm-cm/dpp_nucleo-c031c6/qxk/gnu/README.txt new file mode 100644 index 00000000..99a5d743 --- /dev/null +++ b/examples/arm-cm/dpp_nucleo-c031c6/qxk/gnu/README.txt @@ -0,0 +1,92 @@ +About this Example +================== +This example can be built in two different ways: +- from the command prompt with the provided Makefile. +- from the Atollic TRUEStudio-ST32 with the provided project. + + +The Makefile +============ +The provided Makefile should be easy to adapt for your own projects. +It contains three build configurations: Debug (default), Release, and +Spy. + +Also, the Makefile has been specifically designed to work as an external +Makefile with the Eclipse CDT. + +The various build configurations are built as follows: + +make +make CONF=rel +make CONF=spy + +make clean +make CONF=rel clean +make CONF=spy clean + +*** +NOTE: +The installation folder of the GNU-ARM toolset on YOUR machine needs +to be adjusted in the provided Makefile, by editing the symbol: GNU_ARM. +As described in the comment for this symbol, the GNU-ARM toolset is taken +from: http://gnutoolchains.com/arm-eabi + +It is highly recommened to use the same GNU-ARM distribution, especially +for ARM Cortex-M projects, due to the support for the hardware FPU +(float-abi=hard). +*** + + +Selecting QXK Exception +======================= +The QXK kernel needs a dedicated exception to return to the thread +context after preemption. The default is to use the NMI exception +for that purpose. However, in case NMI is needed for some other +purpose, the QXK port allows you to select a any, otherwise unused +IRQ for that purpose. To choose a given IRQ, you need to define +the macros QXK_USE_IRQ_NUM and QXK_USE_IRQ_HANDLER. These macros can +be provided on the command-line to the compiler. + +For example, (see the vector table), you can define the QXK IRQ +as follows: + +QXK_USE_IRQ_HANDLER=Reserved31_IRQHandler +QXK_USE_IRQ_NUM=31 + + +Adjusting Stack and Heap Sizes +============================== +The stack and heap sizes are determined in this project by the GCC linker +script (.ld file), which provides a template of the recommended GCC linker +script for QP applications. + + +Startup Code +============ +The startup code for the STM32C0xx MCU used in this project is +located in the "3rd_party" folder in the following location: + +3rd_party\nucleo-c031c6\gnu\startup_stm32c031xx.c + +The file startup_stm32c031xx.c provides a template of the recommended +startup for QP applications and should be easily customizable for other +ARM Cortex-M microcontrollers. + +The startup file typically does not need to be modified or adapted for +applications. It calls the assert_failed() function, which must be +defined in the application to customize it for the application-specific +error-handling policy. + + +Adjusting the CPU Clock Speed +============================= +The current setting is to run at 12MHz from the MSI (internal oscillator), +but the CPU clock speed can be modified. + +*** +NOTE: +The NUCLEO boards have a wide range of possible clock selections, depending +on the solder bridge configuration. Please see Chapter 5.7 "OSC clock" in +the STM32 NUCLEO Boards User Manual (ST document UM1724) for more information. +*** + diff --git a/examples/arm-cm/dpp_nucleo-c031c6/qxk/gnu/dpp-qxk.ld b/examples/arm-cm/dpp_nucleo-c031c6/qxk/gnu/dpp-qxk.ld new file mode 100644 index 00000000..4a3ba851 --- /dev/null +++ b/examples/arm-cm/dpp_nucleo-c031c6/qxk/gnu/dpp-qxk.ld @@ -0,0 +1,135 @@ +/***************************************************************************** +* Linker script for for STM32C031C6, GNU-ARM linker +* +* Q u a n t u m L e a P s +* ------------------------ +* Modern Embedded Software +* +* Copyright (C) 2005 Quantum Leaps, LLC . +* +* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +* +* This software is dual-licensed under the terms of the open source GNU +* General Public License version 3 (or any later version), or alternatively, +* under the terms of one of the closed source Quantum Leaps commercial +* licenses. +* +* The terms of the open source GNU General Public License version 3 +* can be found at: +* +* The terms of the closed source Quantum Leaps commercial licenses +* can be found at: +* +* Redistributions in source code must retain this top-level comment block. +* Plagiarizing this software to sidestep the license obligations is illegal. +* +* Contact information: +* +* +*****************************************************************************/ +OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm", "elf32-littlearm") +OUTPUT_ARCH(arm) +ENTRY(Reset_Handler) /* entry Point */ + +MEMORY { /* memory map of STM32C031C6 */ + ROM (rx) : ORIGIN = 0x08000000, LENGTH = 32K + RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 12K +} + +/* The size of the stack used by the application. NOTE: you need to adjust */ +STACK_SIZE = 2048; + +/* The size of the heap used by the application. NOTE: you need to adjust */ +HEAP_SIZE = 0; + +SECTIONS { + + .isr_vector : { /* the vector table goes FIRST into ROM */ + KEEP(*(.isr_vector)) /* vector table */ + . = ALIGN(4); + } >ROM + + .text : { /* code and constants */ + . = ALIGN(4); + *(.text) /* .text sections (code) */ + *(.text*) /* .text* sections (code) */ + *(.rodata) /* .rodata sections (constants, strings, etc.) */ + *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ + + KEEP (*(.init)) + KEEP (*(.fini)) + + . = ALIGN(4); + } >ROM + + .preinit_array : { + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array*)) + PROVIDE_HIDDEN (__preinit_array_end = .); + } >ROM + + .init_array : { + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array*)) + PROVIDE_HIDDEN (__init_array_end = .); + } >ROM + + .fini_array : { + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(.fini_array*)) + KEEP (*(SORT(.fini_array.*))) + PROVIDE_HIDDEN (__fini_array_end = .); + } >ROM + + _etext = .; /* global symbols at end of code */ + + .stack : { + __stack_start__ = .; + . = . + STACK_SIZE; + . = ALIGN(4); + __stack_end__ = .; + } >RAM + + .data : AT (_etext) { + __data_load = LOADADDR (.data); + __data_start = .; + *(.data) /* .data sections */ + *(.data*) /* .data* sections */ + . = ALIGN(4); + __data_end__ = .; + _edata = __data_end__; + } >RAM + + .bss : { + __bss_start__ = .; + *(.bss) + *(.bss*) + *(COMMON) + . = ALIGN(4); + _ebss = .; /* define a global symbol at bss end */ + __bss_end__ = .; + } >RAM + + __exidx_start = .; + .ARM.exidx : { *(.ARM.exidx* .gnu.linkonce.armexidx.*) } >RAM + __exidx_end = .; + + PROVIDE ( end = _ebss ); + PROVIDE ( _end = _ebss ); + PROVIDE ( __end__ = _ebss ); + + .heap : { + __heap_start__ = .; + . = . + HEAP_SIZE; + . = ALIGN(4); + __heap_end__ = .; + } >RAM + + /* Remove information from the standard libraries */ + /DISCARD/ : { + libc.a ( * ) + libm.a ( * ) + libgcc.a ( * ) + } +} diff --git a/examples/arm-cm/dpp_nucleo-c031c6/qxk/iar/dpp-qxk.ewd b/examples/arm-cm/dpp_nucleo-c031c6/qxk/iar/dpp-qxk.ewd new file mode 100644 index 00000000..b3712b65 --- /dev/null +++ b/examples/arm-cm/dpp_nucleo-c031c6/qxk/iar/dpp-qxk.ewd @@ -0,0 +1,4654 @@ + + + 3 + + Debug + + ARM + + 1 + + C-SPY + 2 + + 32 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ARMSIM_ID + 2 + + 1 + 1 + 1 + + + + + + + + CADI_ID + 2 + + 0 + 1 + 1 + + + + + + + + + CMSISDAP_ID + 2 + + 4 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + GDBSERVER_ID + 2 + + 0 + 1 + 1 + + + + + + + + + + + IJET_ID + 2 + + 9 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + JLINK_ID + 2 + + 16 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + LMIFTDI_ID + 2 + + 3 + 1 + 1 + + + + + + + + + + + + + NULINK_ID + 2 + + 0 + 1 + 1 + + + + + + + PEMICRO_ID + 2 + + 3 + 1 + 1 + + + + + + + + STLINK_ID + 2 + + 8 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + THIRDPARTY_ID + 2 + + 0 + 1 + 1 + + + + + + + + TIFET_ID + 2 + + 1 + 1 + 1 + + + + + + + + + + + + + + + + + + + XDS100_ID + 2 + + 9 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + $TOOLKIT_DIR$\plugins\rtos\CMX\CmxArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\CMX\CmxTinyArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\FreeRtos\FreeRtosArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin2.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SafeRTOS\SafeRTOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9BE.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-286-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-III\uCOS-III-KA-CSpy.ewplugin + 0 + + + $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\TargetAccessServer\TargetAccessServer.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\uCProbe\uCProbePlugin.ENU.ewplugin + 0 + + + + + Release + + ARM + + 0 + + C-SPY + 2 + + 32 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ARMSIM_ID + 2 + + 1 + 1 + 0 + + + + + + + + CADI_ID + 2 + + 0 + 1 + 0 + + + + + + + + + CMSISDAP_ID + 2 + + 4 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + GDBSERVER_ID + 2 + + 0 + 1 + 0 + + + + + + + + + + + IJET_ID + 2 + + 9 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + JLINK_ID + 2 + + 16 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + LMIFTDI_ID + 2 + + 3 + 1 + 0 + + + + + + + + + + + + + NULINK_ID + 2 + + 0 + 1 + 0 + + + + + + + PEMICRO_ID + 2 + + 3 + 1 + 0 + + + + + + + + STLINK_ID + 2 + + 8 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + THIRDPARTY_ID + 2 + + 0 + 1 + 0 + + + + + + + + TIFET_ID + 2 + + 1 + 1 + 0 + + + + + + + + + + + + + + + + + + + XDS100_ID + 2 + + 9 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + $TOOLKIT_DIR$\plugins\rtos\CMX\CmxArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\CMX\CmxTinyArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\FreeRtos\FreeRtosArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin2.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SafeRTOS\SafeRTOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9BE.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-286-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-III\uCOS-III-KA-CSpy.ewplugin + 0 + + + $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\TargetAccessServer\TargetAccessServer.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\uCProbe\uCProbePlugin.ENU.ewplugin + 0 + + + + + Spy + + ARM + + 1 + + C-SPY + 2 + + 32 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ARMSIM_ID + 2 + + 1 + 1 + 1 + + + + + + + + CADI_ID + 2 + + 0 + 1 + 1 + + + + + + + + + CMSISDAP_ID + 2 + + 4 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + GDBSERVER_ID + 2 + + 0 + 1 + 1 + + + + + + + + + + + IJET_ID + 2 + + 9 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + JLINK_ID + 2 + + 16 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + LMIFTDI_ID + 2 + + 3 + 1 + 1 + + + + + + + + + + + + + NULINK_ID + 2 + + 0 + 1 + 1 + + + + + + + PEMICRO_ID + 2 + + 3 + 1 + 1 + + + + + + + + STLINK_ID + 2 + + 8 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + THIRDPARTY_ID + 2 + + 0 + 1 + 1 + + + + + + + + TIFET_ID + 2 + + 1 + 1 + 1 + + + + + + + + + + + + + + + + + + + XDS100_ID + 2 + + 9 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + $TOOLKIT_DIR$\plugins\rtos\CMX\CmxArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\CMX\CmxTinyArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\FreeRtos\FreeRtosArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin2.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SafeRTOS\SafeRTOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9BE.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-286-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-III\uCOS-III-KA-CSpy.ewplugin + 0 + + + $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\TargetAccessServer\TargetAccessServer.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\uCProbe\uCProbePlugin.ENU.ewplugin + 0 + + + + diff --git a/examples/arm-cm/dpp_nucleo-c031c6/qxk/iar/dpp-qxk.ewp b/examples/arm-cm/dpp_nucleo-c031c6/qxk/iar/dpp-qxk.ewp new file mode 100644 index 00000000..7c3fa007 --- /dev/null +++ b/examples/arm-cm/dpp_nucleo-c031c6/qxk/iar/dpp-qxk.ewp @@ -0,0 +1,3379 @@ + + + 3 + + Debug + + ARM + + 1 + + General + 3 + + 35 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ICCARM + 2 + + 37 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + AARM + 2 + + 11 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + OBJCOPY + 0 + + 1 + 1 + 1 + + + + + + + + + CUSTOM + 3 + + + + 0 + inputOutputBased + + + + BUILDACTION + 1 + + cmd /c "if exist $OBJ_DIR$\qstamp.o del $OBJ_DIR$\qstamp.o" + + + + + ILINK + 0 + + 27 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + IARCHIVE + 0 + + 0 + 1 + 1 + + + + + + + Coder + 0 + + + + + Release + + ARM + + 0 + + General + 3 + + 35 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ICCARM + 2 + + 37 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + AARM + 2 + + 11 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + OBJCOPY + 0 + + 1 + 1 + 0 + + + + + + + + + CUSTOM + 3 + + + + 0 + inputOutputBased + + + + BUILDACTION + 1 + + cmd /c "if exist $OBJ_DIR$\qstamp.o del $OBJ_DIR$\qstamp.o" + + + + + ILINK + 0 + + 27 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + IARCHIVE + 0 + + 0 + 1 + 0 + + + + + + + Coder + 0 + + + + + Spy + + ARM + + 1 + + General + 3 + + 35 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ICCARM + 2 + + 37 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + AARM + 2 + + 11 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + OBJCOPY + 0 + + 1 + 1 + 1 + + + + + + + + + CUSTOM + 3 + + + + 0 + inputOutputBased + + + + BUILDACTION + 1 + + cmd /c "if exist $OBJ_DIR$\qstamp.o del $OBJ_DIR$\qstamp.o" + + + + + ILINK + 0 + + 27 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + IARCHIVE + 0 + + 0 + 1 + 1 + + + + + + + Coder + 0 + + + + + Release + + + Application + + $PROJ_DIR$\..\bsp.c + + + $PROJ_DIR$\..\..\bsp.h + + + $PROJ_DIR$\..\..\dpp.h + + + $PROJ_DIR$\..\..\main.c + + + $PROJ_DIR$\..\..\philo.c + + + $PROJ_DIR$\..\..\table.c + + + $PROJ_DIR$\..\xthread1.c + + + $PROJ_DIR$\..\xthread2.c + + + + nucleo-c031c6 + + $PROJ_DIR$\..\..\..\..\..\3rd_party\nucleo-c031c6\iar\startup_stm32c031xx.s + + + $PROJ_DIR$\..\..\..\..\..\3rd_party\nucleo-c031c6\stm32c031xx.h + + + $PROJ_DIR$\..\..\..\..\..\3rd_party\nucleo-c031c6\stm32c0xx.h + + + $PROJ_DIR$\..\..\..\..\..\3rd_party\nucleo-c031c6\system_stm32c0xx.c + + + + QP + + $PROJ_DIR$\..\..\..\..\..\src\qf\qep_hsm.c + + + $PROJ_DIR$\..\..\..\..\..\src\qf\qep_msm.c + + + $PROJ_DIR$\..\..\..\..\..\src\qf\qf_act.c + + + $PROJ_DIR$\..\..\..\..\..\src\qf\qf_actq.c + + + $PROJ_DIR$\..\..\..\..\..\src\qf\qf_defer.c + + + $PROJ_DIR$\..\..\..\..\..\src\qf\qf_dyn.c + + + $PROJ_DIR$\..\..\..\..\..\src\qf\qf_mem.c + + + $PROJ_DIR$\..\..\..\..\..\src\qf_pkg.h + + + $PROJ_DIR$\..\..\..\..\..\src\qf\qf_ps.c + + + $PROJ_DIR$\..\..\..\..\..\src\qf\qf_qact.c + + + $PROJ_DIR$\..\..\..\..\..\src\qf\qf_qeq.c + + + $PROJ_DIR$\..\..\..\..\..\src\qf\qf_qmact.c + + + $PROJ_DIR$\..\..\..\..\..\src\qf\qf_time.c + + + $PROJ_DIR$\..\..\..\..\..\src\qxk\qxk.c + + + $PROJ_DIR$\..\..\..\..\..\src\qxk\qxk_mutex.c + + + $PROJ_DIR$\..\..\..\..\..\src\qxk\qxk_sema.c + + + $PROJ_DIR$\..\..\..\..\..\src\qxk\qxk_xthr.c + + + + QP_port + + $PROJ_DIR$\..\..\..\..\..\ports\arm-cm\qxk\iar\qep_port.h + + + $PROJ_DIR$\..\..\..\..\..\ports\arm-cm\qxk\iar\qf_port.h + + + $PROJ_DIR$\..\..\..\..\..\ports\arm-cm\qxk\iar\qs_port.h + + + $PROJ_DIR$\..\..\..\..\..\ports\arm-cm\qxk\iar\qxk_port.c + + + $PROJ_DIR$\..\..\..\..\..\ports\arm-cm\qxk\iar\qxk_port.h + + + + QS + + Debug + Release + + + $PROJ_DIR$\..\..\..\..\..\src\qs\qs.c + + + $PROJ_DIR$\..\..\..\..\..\src\qs\qs_fp.c + + + $PROJ_DIR$\..\..\..\..\..\src\qs\qs_rx.c + + + $PROJ_DIR$\..\..\..\..\..\src\qs\qstamp.c + + + diff --git a/examples/arm-cm/dpp_nucleo-c031c6/qxk/iar/dpp-qxk.eww b/examples/arm-cm/dpp_nucleo-c031c6/qxk/iar/dpp-qxk.eww new file mode 100644 index 00000000..38808ca3 --- /dev/null +++ b/examples/arm-cm/dpp_nucleo-c031c6/qxk/iar/dpp-qxk.eww @@ -0,0 +1,10 @@ + + + + + $WS_DIR$\dpp-qxk.ewp + + + + + diff --git a/examples/arm-cm/dpp_nucleo-c031c6/qxk/iar/dpp-qxk.icf b/examples/arm-cm/dpp_nucleo-c031c6/qxk/iar/dpp-qxk.icf new file mode 100644 index 00000000..db057b16 --- /dev/null +++ b/examples/arm-cm/dpp_nucleo-c031c6/qxk/iar/dpp-qxk.icf @@ -0,0 +1,165 @@ +/*###ICF### Section handled by ICF editor, don't touch! ****/ +/*-Editor annotation file-*/ +/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_4.xml" */ +/*-Specials-*/ +define symbol __ICFEDIT_intvec_start__ = 0x08000000; +/*-Memory Regions-*/ +define symbol __ICFEDIT_region_IROM1_start__ = 0x08000000; +define symbol __ICFEDIT_region_IROM1_end__ = 0x08007FFF; +define symbol __ICFEDIT_region_IROM2_start__ = 0x0; +define symbol __ICFEDIT_region_IROM2_end__ = 0x0; +define symbol __ICFEDIT_region_EROM1_start__ = 0x0; +define symbol __ICFEDIT_region_EROM1_end__ = 0x0; +define symbol __ICFEDIT_region_EROM2_start__ = 0x0; +define symbol __ICFEDIT_region_EROM2_end__ = 0x0; +define symbol __ICFEDIT_region_EROM3_start__ = 0x0; +define symbol __ICFEDIT_region_EROM3_end__ = 0x0; +define symbol __ICFEDIT_region_IRAM1_start__ = 0x20000000; +define symbol __ICFEDIT_region_IRAM1_end__ = 0x20002FFF; +define symbol __ICFEDIT_region_IRAM2_start__ = 0x0; +define symbol __ICFEDIT_region_IRAM2_end__ = 0x0; +define symbol __ICFEDIT_region_ERAM1_start__ = 0x0; +define symbol __ICFEDIT_region_ERAM1_end__ = 0x0; +define symbol __ICFEDIT_region_ERAM2_start__ = 0x0; +define symbol __ICFEDIT_region_ERAM2_end__ = 0x0; +define symbol __ICFEDIT_region_ERAM3_start__ = 0x0; +define symbol __ICFEDIT_region_ERAM3_end__ = 0x0; +/*-Sizes-*/ +define symbol __ICFEDIT_size_cstack__ = 2048; +define symbol __ICFEDIT_size_proc_stack__ = 0x0; +define symbol __ICFEDIT_size_heap__ = 0; +/**** End of ICF editor section. ###ICF###*/ + +define memory mem with size = 4G; +define symbol use_IROM1 = (__ICFEDIT_region_IROM1_start__ != 0x0 || __ICFEDIT_region_IROM1_end__ != 0x0); +define symbol use_IROM2 = (__ICFEDIT_region_IROM2_start__ != 0x0 || __ICFEDIT_region_IROM2_end__ != 0x0); +define symbol use_EROM1 = (__ICFEDIT_region_EROM1_start__ != 0x0 || __ICFEDIT_region_EROM1_end__ != 0x0); +define symbol use_EROM2 = (__ICFEDIT_region_EROM2_start__ != 0x0 || __ICFEDIT_region_EROM2_end__ != 0x0); +define symbol use_EROM3 = (__ICFEDIT_region_EROM3_start__ != 0x0 || __ICFEDIT_region_EROM3_end__ != 0x0); +define symbol use_IRAM1 = (__ICFEDIT_region_IRAM1_start__ != 0x0 || __ICFEDIT_region_IRAM1_end__ != 0x0); +define symbol use_IRAM2 = (__ICFEDIT_region_IRAM2_start__ != 0x0 || __ICFEDIT_region_IRAM2_end__ != 0x0); +define symbol use_ERAM1 = (__ICFEDIT_region_ERAM1_start__ != 0x0 || __ICFEDIT_region_ERAM1_end__ != 0x0); +define symbol use_ERAM2 = (__ICFEDIT_region_ERAM2_start__ != 0x0 || __ICFEDIT_region_ERAM2_end__ != 0x0); +define symbol use_ERAM3 = (__ICFEDIT_region_ERAM3_start__ != 0x0 || __ICFEDIT_region_ERAM3_end__ != 0x0); + +if (use_IROM1) +{ + define region IROM1_region = mem:[from __ICFEDIT_region_IROM1_start__ to __ICFEDIT_region_IROM1_end__]; +} +else +{ + define region IROM1_region = []; +} + +if (use_IROM2) +{ + define region IROM2_region = mem:[from __ICFEDIT_region_IROM2_start__ to __ICFEDIT_region_IROM2_end__]; +} +else +{ + define region IROM2_region = []; +} +define region IROM_region = IROM1_region | IROM2_region; + +if (use_EROM1) +{ + define region EROM1_region = mem:[from __ICFEDIT_region_EROM1_start__ to __ICFEDIT_region_EROM1_end__]; +} +else +{ + define region EROM1_region = []; +} +if (use_EROM2) +{ + define region EROM2_region = mem:[from __ICFEDIT_region_EROM2_start__ to __ICFEDIT_region_EROM2_end__]; +} +else +{ + define region EROM2_region = []; +} +if (use_EROM3) +{ + define region EROM3_region = mem:[from __ICFEDIT_region_EROM3_start__ to __ICFEDIT_region_EROM3_end__]; +} +else +{ + define region EROM3_region = []; +} +define region EROM_region = EROM1_region | EROM2_region | EROM3_region; + +if (use_IRAM1) +{ + define region IRAM1_region = mem:[from __ICFEDIT_region_IRAM1_start__ to __ICFEDIT_region_IRAM1_end__]; +} +else +{ + define region IRAM1_region = []; +} +if (use_IRAM2) +{ + define region IRAM2_region = mem:[from __ICFEDIT_region_IRAM2_start__ to __ICFEDIT_region_IRAM2_end__]; +} +else +{ + define region IRAM2_region = []; +} +define region IRAM_region = IRAM1_region | IRAM2_region; + +if (use_ERAM1) +{ + define region ERAM1_region = mem:[from __ICFEDIT_region_ERAM1_start__ to __ICFEDIT_region_ERAM1_end__]; +} +else +{ + define region ERAM1_region = []; +} +if (use_ERAM2) +{ + define region ERAM2_region = mem:[from __ICFEDIT_region_ERAM2_start__ to __ICFEDIT_region_ERAM2_end__]; +} +else +{ + define region ERAM2_region = []; +} +if (use_ERAM3) +{ + define region ERAM3_region = mem:[from __ICFEDIT_region_ERAM3_start__ to __ICFEDIT_region_ERAM3_end__]; +} +else +{ + define region ERAM3_region = []; +} +define region ERAM_region = ERAM1_region | ERAM2_region | ERAM3_region; + +initialize by copy { readwrite }; +if (isdefinedsymbol(__USE_DLIB_PERTHREAD)) +{ + // Required in a multi-threaded application + initialize by copy with packing = none { section __DLIB_PERTHREAD }; +} + +place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec }; + +if (!isempty(IROM_region)) +{ + place in IROM_region { readonly }; +} + +if (!isempty(EROM_region)) +{ + place in EROM_region { readonly section application_specific_ro }; +} + +if (!isempty(IRAM_region)) +{ + define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { }; + define block PROC_STACK with alignment = 8, size = __ICFEDIT_size_proc_stack__ { }; + define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { }; + place at start of IRAM_region {block CSTACK }; /* <== Quantum Leaps */ + place in IRAM_region { readwrite, block PROC_STACK, block HEAP }; +} + +if (!isempty(ERAM_region)) +{ + place in ERAM_region { readwrite section application_specific_rw }; +} \ No newline at end of file diff --git a/examples/arm-cm/dpp_nucleo-c031c6/qxk/xthread1.c b/examples/arm-cm/dpp_nucleo-c031c6/qxk/xthread1.c new file mode 100644 index 00000000..066b983d --- /dev/null +++ b/examples/arm-cm/dpp_nucleo-c031c6/qxk/xthread1.c @@ -0,0 +1,101 @@ +//============================================================================ +// QXThread example +// Last updated for version 7.3.0 +// Last updated on 2023-08-12 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. +// +// This program is open source software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Alternatively, this program may be distributed and modified under the +// terms of Quantum Leaps commercial licenses, which expressly supersede +// the GNU General Public License and are specifically designed for +// licensees interested in retaining the proprietary status of their code. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Contact information: +// +// +//============================================================================ +#include "qpc.h" // QP/C real-time embedded framework +#include "dpp.h" // DPP Application interface +#include "bsp.h" // Board Support Package + +//---------------------------------------------------------------------------- +//Q_DEFINE_THIS_FILE + +//............................................................................ +typedef struct XThread1 { +// protected: + QXThread super; + +// private: + // NOTE: data needed by this thread should be members of + // the thread class. That way they are in the memory region + // accessible from this thread. + uint8_t foo; + +// public: +} XThread1; + +// private: +static void XThread1_run(QXThread * const thr); +extern XThread1 XThread1_inst; + +//............................................................................ +QXThread * const TH_XThread1 = &XThread1_inst.super; + +//............................................................................ +void XThread1_ctor(void) { + XThread1 *me = &XThread1_inst; + QXThread_ctor(&me->super, &XThread1_run, 0U); +} + +//............................................................................ +XThread1 XThread1_inst; + +//............................................................................ +static void XThread1_run(QXThread * const thr) { + QS_OBJ_DICTIONARY(TH_XThread1); + QS_OBJ_DICTIONARY(&TH_XThread1->timeEvt); + + // downcast the generic thr pointer to the specific thread + XThread1 *me = (XThread1 *)thr; + + // subscribe to the EAT signal (from the application) + QActive_subscribe(&me->super.super, EAT_SIG); + + for (;;) { + QEvt const *e = QXThread_queueGet(BSP_TICKS_PER_SEC/4U); + if (e) { + QXSemaphore_signal(&TH_sema); // signal Thread2 + QF_gc(e); // must explicitly recycle the received event! + } + + QXMutex_lock(&TH_mutex, QXTHREAD_NO_TIMEOUT); // lock the mutex + BSP_ledOn(); + if (QXMutex_tryLock(&TH_mutex)) { // exercise the mutex + // some floating point code to exercise the VFP... + float volatile x = 1.4142135F; + x = x * 1.4142135F; + QXThread_delay(10U); // BLOCK while holding a mutex + QXMutex_unlock(&TH_mutex); + } + QXMutex_unlock(&TH_mutex); + BSP_ledOff(); + } +} diff --git a/examples/arm-cm/dpp_nucleo-c031c6/qxk/xthread2.c b/examples/arm-cm/dpp_nucleo-c031c6/qxk/xthread2.c new file mode 100644 index 00000000..1caad4fa --- /dev/null +++ b/examples/arm-cm/dpp_nucleo-c031c6/qxk/xthread2.c @@ -0,0 +1,108 @@ +//============================================================================ +// QXThread example +// Last updated for version 7.3.0 +// Last updated on 2023-08-12 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. +// +// This program is open source software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Alternatively, this program may be distributed and modified under the +// terms of Quantum Leaps commercial licenses, which expressly supersede +// the GNU General Public License and are specifically designed for +// licensees interested in retaining the proprietary status of their code. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Contact information: +// +// +//============================================================================ +#include "qpc.h" // QP/C real-time embedded framework +#include "dpp.h" // DPP Application interface +#include "bsp.h" // Board Support Package + +//---------------------------------------------------------------------------- +//Q_DEFINE_THIS_FILE + +//---------------------------------------------------------------------------- +QXSemaphore TH_sema; +QXMutex TH_mutex; + +//---------------------------------------------------------------------------- +typedef struct XThread2 { +// protected: + QXThread super; + +// private: + // NOTE: data needed by this thread should be members of + // the thread class. That way they are in the memory region + // accessible from this thread. + uint8_t foo; + +// public: +} XThread2; + +// private: +static void XThread2_run(QXThread * const thr); +extern XThread2 XThread2_inst; + +//............................................................................ +QXThread * const TH_XThread2 = &XThread2_inst.super; + +//............................................................................ +void XThread2_ctor(void) { + XThread2 *me = &XThread2_inst; + QXThread_ctor(&me->super, &XThread2_run, 0U); +} + +//............................................................................ +XThread2 XThread2_inst; + +//............................................................................ +static void XThread2_run(QXThread * const thr) { + QS_OBJ_DICTIONARY(TH_XThread2); + QS_OBJ_DICTIONARY(&TH_XThread2->timeEvt); + QS_OBJ_DICTIONARY(&TH_sema); + QS_OBJ_DICTIONARY(&TH_mutex); + + // downcast the generic thr pointer to the specific thread + //XThread2 *me = (XThread2 *)thr; + + // initialize the semaphore before using it + // NOTE: Here the semaphore is initialized in the highest-priority thread + // that uses it. Alternatively, the semaphore can be initialized + // before any thread runs. + QXSemaphore_init(&TH_sema, + 0U, // count==0 (signaling semaphore) + 1U); // max_count==1 (binary semaphore) + + // initialize the mutex before using it + // NOTE: Here the mutex is initialized in the highest-priority thread + // that uses it. Alternatively, the mutex can be initialized + // before any thread runs. + QXMutex_init(&TH_mutex, N_PHILO + 6U); // priority-ceiling mutex + //QXMutex_init(&TH_mutex, 0U); // alternatively: priority-ceiling NOT used + + for (;;) { + // wait on a semaphore (BLOCK indefinitely) + QXSemaphore_wait(&TH_sema, QXTHREAD_NO_TIMEOUT); + + QXMutex_lock(&TH_mutex, QXTHREAD_NO_TIMEOUT); // lock the mutex + QXThread_delay(5U); // wait more (BLOCK) + QXMutex_unlock(&TH_mutex); + } +} diff --git a/examples/arm-cm/dpp_nucleo-c031c6/stm32-nucleo-c031c6.jpg b/examples/arm-cm/dpp_nucleo-c031c6/stm32-nucleo-c031c6.jpg new file mode 100644 index 00000000..6647e2d4 Binary files /dev/null and b/examples/arm-cm/dpp_nucleo-c031c6/stm32-nucleo-c031c6.jpg differ diff --git a/examples/arm-cm/dpp_nucleo-c031c6/table.c b/examples/arm-cm/dpp_nucleo-c031c6/table.c new file mode 100644 index 00000000..c3ae02f0 --- /dev/null +++ b/examples/arm-cm/dpp_nucleo-c031c6/table.c @@ -0,0 +1,343 @@ +//$file${.::table.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// +// Model: dpp.qm +// File: ${.::table.c} +// +// This code has been generated by QM 5.3.0 . +// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. +// +// SPDX-License-Identifier: GPL-3.0-or-later +// +// This generated code is open source software: you can redistribute it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation. +// +// This code is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// NOTE: +// Alternatively, this generated code may be distributed under the terms +// of Quantum Leaps commercial licenses, which expressly supersede the GNU +// General Public License and are specifically designed for licensees +// interested in retaining the proprietary status of their code. +// +// Contact information: +// +// +// +//$endhead${.::table.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +#include "qpc.h" // QP/C real-time embedded framework +#include "dpp.h" // DPP Application interface +#include "bsp.h" // Board Support Package + +//$declare${AOs::Table} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${AOs::Table} .............................................................. +typedef struct Table { +// protected: + QActive super; + +// private: + uint8_t fork[N_PHILO]; + bool isHungry[N_PHILO]; + +// public: +} Table; + +extern Table Table_inst; + +// protected: +static QState Table_initial(Table * const me, void const * const par); +static QState Table_active(Table * const me, QEvt const * const e); +static QState Table_serving(Table * const me, QEvt const * const e); +static QState Table_paused(Table * const me, QEvt const * const e); +//$enddecl${AOs::Table} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +//---------------------------------------------------------------------------- +Q_DEFINE_THIS_FILE + +// helper function to provide the RIGHT neighbor of a Philo[n] +static inline uint8_t right(uint8_t const n) { + return (uint8_t)((n + (N_PHILO - 1U)) % N_PHILO); +} + +// helper function to provide the LEFT neighbor of a Philo[n] +static inline uint8_t left(uint8_t const n) { + return (uint8_t)((n + 1U) % N_PHILO); +} + +#define FREE ((uint8_t)0U) +#define USED ((uint8_t)1U) + +#define THINKING "thinking" +#define HUNGRY "hungry " +#define EATING "eating " + +//---------------------------------------------------------------------------- + +//$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// Check for the minimum required QP version +#if (QP_VERSION < 730U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) +#error qpc version 7.3.0 or higher required +#endif +//$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +//$define${Shared::Table_ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${Shared::Table_ctor} ...................................................... +void Table_ctor(void) { + Table * const me = &Table_inst; + QActive_ctor(&me->super, Q_STATE_CAST(&Table_initial)); + for (uint8_t n = 0U; n < N_PHILO; ++n) { + me->fork[n] = FREE; + me->isHungry[n] = false; + } +} +//$enddef${Shared::Table_ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +//$define${Shared::AO_Table} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${Shared::AO_Table} ........................................................ +QActive * const AO_Table = &Table_inst.super; +//$enddef${Shared::AO_Table} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +//$define${AOs::Table} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${AOs::Table} .............................................................. +Table Table_inst; + +//${AOs::Table::SM} .......................................................... +static QState Table_initial(Table * const me, void const * const par) { + //${AOs::Table::SM::initial} + Q_UNUSED_PAR(par); + + #ifdef Q_SPY + Table *Table_inst = me; + QS_OBJ_DICTIONARY(Table_inst); + #endif + + QActive_subscribe(&me->super, DONE_SIG); + QActive_subscribe(&me->super, PAUSE_SIG); + QActive_subscribe(&me->super, SERVE_SIG); + QActive_subscribe(&me->super, TEST_SIG); + + for (uint8_t n = 0U; n < N_PHILO; ++n) { + me->fork[n] = FREE; + me->isHungry[n] = false; + BSP_displayPhilStat(n, THINKING); + } + + QS_FUN_DICTIONARY(&Table_active); + QS_FUN_DICTIONARY(&Table_serving); + QS_FUN_DICTIONARY(&Table_paused); + + return Q_TRAN(&Table_serving); +} + +//${AOs::Table::SM::active} .................................................. +static QState Table_active(Table * const me, QEvt const * const e) { + QState status_; + switch (e->sig) { + //${AOs::Table::SM::active::TEST} + case TEST_SIG: { + status_ = Q_HANDLED(); + break; + } + //${AOs::Table::SM::active::EAT} + case EAT_SIG: { + Q_ERROR(); + status_ = Q_HANDLED(); + break; + } + default: { + status_ = Q_SUPER(&QHsm_top); + break; + } + } + return status_; +} + +//${AOs::Table::SM::active::serving} ......................................... +static QState Table_serving(Table * const me, QEvt const * const e) { + QState status_; + switch (e->sig) { + //${AOs::Table::SM::active::serving} + case Q_ENTRY_SIG: { + // give permissions to eat... + for (uint8_t n = 0U; n < N_PHILO; ++n) { + if (me->isHungry[n] + && (me->fork[left(n)] == FREE) + && (me->fork[n] == FREE)) + { + me->fork[left(n)] = USED; + me->fork[n] = USED; + #ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, EAT_SIG, n); + #else + TableEvt *pe = Q_NEW(TableEvt, EAT_SIG); + pe->philoId = n; + #endif + QACTIVE_PUBLISH(&pe->super, &me->super); + me->isHungry[n] = false; + BSP_displayPhilStat(n, EATING); + } + } + status_ = Q_HANDLED(); + break; + } + //${AOs::Table::SM::active::serving::HUNGRY} + case HUNGRY_SIG: { + uint8_t n = Q_EVT_CAST(TableEvt)->philoId; + + // phil ID must be in range and he must be not hungry + Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); + + BSP_displayPhilStat(n, HUNGRY); + uint8_t m = left(n); + //${AOs::Table::SM::active::serving::HUNGRY::[bothfree]} + if ((me->fork[m] == FREE) && (me->fork[n] == FREE)) { + me->fork[m] = USED; + me->fork[n] = USED; + #ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, EAT_SIG, n); + #else + TableEvt *pe = Q_NEW(TableEvt, EAT_SIG); + pe->philoId = n; + #endif + QACTIVE_PUBLISH(&pe->super, &me->super); + BSP_displayPhilStat(n, EATING); + status_ = Q_HANDLED(); + } + //${AOs::Table::SM::active::serving::HUNGRY::[else]} + else { + me->isHungry[n] = true; + status_ = Q_HANDLED(); + } + break; + } + //${AOs::Table::SM::active::serving::DONE} + case DONE_SIG: { + uint8_t n = Q_EVT_CAST(TableEvt)->philoId; + + // phil ID must be in range and he must be not hungry + Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); + + BSP_displayPhilStat(n, THINKING); + uint8_t m = left(n); + + // both forks of Phil[n] must be used + Q_ASSERT((me->fork[n] == USED) && (me->fork[m] == USED)); + + me->fork[m] = FREE; + me->fork[n] = FREE; + m = right(n); // check the right neighbor + + if (me->isHungry[m] && (me->fork[m] == FREE)) { + me->fork[n] = USED; + me->fork[m] = USED; + me->isHungry[m] = false; + #ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, EAT_SIG, m); + #else + TableEvt *pe = Q_NEW(TableEvt, EAT_SIG); + pe->philoId = m; + #endif + QACTIVE_PUBLISH(&pe->super, &me->super); + BSP_displayPhilStat(m, EATING); + } + m = left(n); // check the left neighbor + n = left(m); // left fork of the left neighbor + if (me->isHungry[m] && (me->fork[n] == FREE)) { + me->fork[m] = USED; + me->fork[n] = USED; + me->isHungry[m] = false; + #ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, EAT_SIG, m); + #else + TableEvt *pe = Q_NEW(TableEvt, EAT_SIG); + pe->philoId = m; + #endif + QACTIVE_PUBLISH(&pe->super, &me->super); + BSP_displayPhilStat(m, EATING); + } + status_ = Q_HANDLED(); + break; + } + //${AOs::Table::SM::active::serving::EAT} + case EAT_SIG: { + Q_ERROR(); + status_ = Q_HANDLED(); + break; + } + //${AOs::Table::SM::active::serving::PAUSE} + case PAUSE_SIG: { + status_ = Q_TRAN(&Table_paused); + break; + } + default: { + status_ = Q_SUPER(&Table_active); + break; + } + } + return status_; +} + +//${AOs::Table::SM::active::paused} .......................................... +static QState Table_paused(Table * const me, QEvt const * const e) { + QState status_; + switch (e->sig) { + //${AOs::Table::SM::active::paused} + case Q_ENTRY_SIG: { + BSP_displayPaused(1U); + status_ = Q_HANDLED(); + break; + } + //${AOs::Table::SM::active::paused} + case Q_EXIT_SIG: { + BSP_displayPaused(0U); + status_ = Q_HANDLED(); + break; + } + //${AOs::Table::SM::active::paused::SERVE} + case SERVE_SIG: { + status_ = Q_TRAN(&Table_serving); + break; + } + //${AOs::Table::SM::active::paused::HUNGRY} + case HUNGRY_SIG: { + uint8_t n = Q_EVT_CAST(TableEvt)->philoId; + + // philo ID must be in range and he must be not hungry + Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); + + me->isHungry[n] = true; + BSP_displayPhilStat(n, HUNGRY); + status_ = Q_HANDLED(); + break; + } + //${AOs::Table::SM::active::paused::DONE} + case DONE_SIG: { + uint8_t n = Q_EVT_CAST(TableEvt)->philoId; + + // phil ID must be in range and he must be not hungry + Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); + + BSP_displayPhilStat(n, THINKING); + uint8_t m = left(n); + + // both forks of Phil[n] must be used + Q_ASSERT((me->fork[n] == USED) && (me->fork[m] == USED)); + + me->fork[m] = FREE; + me->fork[n] = FREE; + status_ = Q_HANDLED(); + break; + } + default: { + status_ = Q_SUPER(&Table_active); + break; + } + } + return status_; +} +//$enddef${AOs::Table} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/examples/arm-cm/dpp_nucleo-c031c6_mpu/bsp.h b/examples/arm-cm/dpp_nucleo-c031c6_mpu/bsp.h new file mode 100644 index 00000000..fe8149a3 --- /dev/null +++ b/examples/arm-cm/dpp_nucleo-c031c6_mpu/bsp.h @@ -0,0 +1,49 @@ +//============================================================================ +// Product: DPP example +// Last Updated for Version: 7.3.0 +// Date of the Last Update: 2023-06-27 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +//============================================================================ +#ifndef BSP_H_ +#define BSP_H_ + +#define BSP_TICKS_PER_SEC 100U + +void BSP_init(void); +void BSP_start(void); +void BSP_displayPaused(uint8_t paused); +void BSP_displayPhilStat(uint8_t n, char const *stat); +void BSP_terminate(int16_t result); + +void BSP_randomSeed(uint32_t seed); // random seed +uint32_t BSP_random(void); // pseudo-random generator + +void BSP_ledOn(void); +void BSP_ledOff(void); + +#endif // BSP_H_ diff --git a/examples/arm-cm/dpp_nucleo-c031c6_mpu/dpp.h b/examples/arm-cm/dpp_nucleo-c031c6_mpu/dpp.h new file mode 100644 index 00000000..4f4100c4 --- /dev/null +++ b/examples/arm-cm/dpp_nucleo-c031c6_mpu/dpp.h @@ -0,0 +1,144 @@ +//$file${.::dpp.h} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// +// Model: dpp_mpu.qm +// File: ${.::dpp.h} +// +// This code has been generated by QM 5.3.0 . +// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. +// +// SPDX-License-Identifier: GPL-3.0-or-later +// +// This generated code is open source software: you can redistribute it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation. +// +// This code is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// NOTE: +// Alternatively, this generated code may be distributed under the terms +// of Quantum Leaps commercial licenses, which expressly supersede the GNU +// General Public License and are specifically designed for licensees +// interested in retaining the proprietary status of their code. +// +// Contact information: +// +// +// +//$endhead${.::dpp.h} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +#ifndef DPP_H_ +#define DPP_H_ + +//$declare${Shared} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${Shared::AppSignals} ...................................................... +enum AppSignals { + EAT_SIG = Q_USER_SIG, // published by Table to let a Philo eat + DONE_SIG, // published by Philo when done eating + PAUSE_SIG, // published by BSP to pause the application + SERVE_SIG, // published by BSP to serve re-start serving forks + TEST_SIG, // published by BSP to test the application + MAX_PUB_SIG, // the last published signal + + TIMEOUT_SIG, // posted by time event to Philo + HUNGRY_SIG, // posted by hungry Philo to Table + MAX_SIG // the last signal +}; + +//${Shared::produce_sig_dict} ................................................ +#ifdef Q_SPY +static inline void produce_sig_dict(void) { + QS_SIG_DICTIONARY(EAT_SIG, (void *)0); + QS_SIG_DICTIONARY(DONE_SIG, (void *)0); + QS_SIG_DICTIONARY(PAUSE_SIG, (void *)0); + QS_SIG_DICTIONARY(SERVE_SIG, (void *)0); + QS_SIG_DICTIONARY(TEST_SIG, (void *)0); + + QS_SIG_DICTIONARY(TIMEOUT_SIG, (void *)0); + QS_SIG_DICTIONARY(HUNGRY_SIG, (void *)0); +} +#endif // def Q_SPY + +//${Shared::N_PHILO} ......................................................... +#define N_PHILO ((uint8_t)5U) + +//${Shared::TableEvt} ........................................................ +typedef struct { +// protected: + QEvt super; + +// public: + uint8_t philoId; +} TableEvt; + +// public: + +#ifdef QEVT_DYN_CTOR +static inline TableEvt * TableEvt_ctor(TableEvt * const me, + uint8_t id) +{ + if (me != (TableEvt *)0) { + // don't call QEvt_ctor() because the initialization of all + // QEvt attributes is already done in QF_QF_newX_() + me->philoId = id; + } + return me; +} +#endif // def QEVT_DYN_CTOR + +//${Shared::AO_Philo[N_PHILO]} ............................................... +extern QActive * const AO_Philo[N_PHILO]; + +//${Shared::Philo_ctor} ...................................................... +void Philo_ctor( + uint_fast8_t const id, + uint8_t * const sto, + uint32_t const size, + void const * const mpu); + +//${Shared::AO_Table} ........................................................ +extern QActive * const AO_Table; + +//${Shared::Table_ctor} ...................................................... +void Table_ctor( + uint8_t * const sto, + uint32_t const size, + void const * const mpu); +//$enddecl${Shared} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +#ifdef QXK_H_ +//$declare${Shared-TH} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${Shared-TH::TH_XThread1} .................................................. +extern QXThread * const TH_XThread1; + +//${Shared-TH::XThread1_ctor} ................................................ +void XThread1_ctor( + uint8_t * const sto, + uint32_t const size, + void const * const mpu); + +//${Shared-TH::TH_XThread2} .................................................. +extern QXThread * const TH_XThread2; + +//${Shared-TH::XThread2_ctor} ................................................ +void XThread2_ctor( + uint8_t * const sto, + uint32_t const size, + void const * const mpu); + +//${Shared-TH::TH_sema} ...................................................... +// NOTE: kernel objects can be allocated outside any memory regions +// accessible to the threads. +extern QXSemaphore TH_sema; + +//${Shared-TH::TH_mutex} ..................................................... +// NOTE: kernel objects can be allocated outside any memory regions +// accessible to the threads. +extern QXMutex TH_mutex; +//$enddecl${Shared-TH} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +#endif // QXK_H_ + +#endif // DPP_H_ diff --git a/examples/arm-cm/dpp_nucleo-c031c6_mpu/dpp_mpu.qm b/examples/arm-cm/dpp_nucleo-c031c6_mpu/dpp_mpu.qm new file mode 100644 index 00000000..7069d76f --- /dev/null +++ b/examples/arm-cm/dpp_nucleo-c031c6_mpu/dpp_mpu.qm @@ -0,0 +1,693 @@ + + + Dining Philosopher Problem example, including QXK and MPU isolation + + + + + + + { + EAT_SIG = Q_USER_SIG, // published by Table to let a Philo eat + DONE_SIG, // published by Philo when done eating + PAUSE_SIG, // published by BSP to pause the application + SERVE_SIG, // published by BSP to serve re-start serving forks + TEST_SIG, // published by BSP to test the application + MAX_PUB_SIG, // the last published signal + + TIMEOUT_SIG, // posted by time event to Philo + HUNGRY_SIG, // posted by hungry Philo to Table + MAX_SIG // the last signal +}; + + + + QS_SIG_DICTIONARY(EAT_SIG, (void *)0); +QS_SIG_DICTIONARY(DONE_SIG, (void *)0); +QS_SIG_DICTIONARY(PAUSE_SIG, (void *)0); +QS_SIG_DICTIONARY(SERVE_SIG, (void *)0); +QS_SIG_DICTIONARY(TEST_SIG, (void *)0); + +QS_SIG_DICTIONARY(TIMEOUT_SIG, (void *)0); +QS_SIG_DICTIONARY(HUNGRY_SIG, (void *)0); + + + + ((uint8_t)5U) + + + + + + + + + + if (me != (TableEvt *)0) { + // don't call QEvt_ctor() because the initialization of all + // QEvt attributes is already done in QF_QF_newX_() + me->philoId = id; +} +return me; + + + + + + + + + + + + + + + Q_REQUIRE(sizeof(Philo) <= size); + +Philo *me = (Philo *)sto; +QActive_ctor(&me->super, Q_STATE_CAST(&Philo_initial)); +QTimeEvt_ctorX(&me->timeEvt, &me->super, TIMEOUT_SIG, 0U), +me->id = (uint8_t)id; +me->super.thread = mpu; + + + + + + + + + + + + Q_REQUIRE(sizeof(Table) <= size); + +Table *me = (Table *)sto; +QActive_ctor(&me->super, Q_STATE_CAST(&Table_initial)); +for (uint8_t n = 0U; n < N_PHILO; ++n) { + me->fork[n] = FREE; + me->isHungry[n] = false; +} +me->super.thread = mpu; + + + + + + + + + + + + + + + Q_REQUIRE(sizeof(XThread1) <= size); + +XThread1 *me = (XThread1 *)sto; +QXThread_ctor(&me->super, &XThread1_run, 0U); +me->super.super.thread = mpu; + + + + + + + + + + + + Q_REQUIRE(sizeof(XThread2) <= size); + +XThread2 *me = (XThread2 *)sto; +QXThread_ctor(&me->super, &XThread2_run, 0U); +me->super.super.thread = mpu; + + + + // NOTE: kernel objects can be allocated outside any memory regions +// accessible to the threads. + + + + // NOTE: kernel objects can be allocated outside any memory regions +// accessible to the threads. + + + + + + + The Philo AO and the N_PHILO instances + + + + + + + + + Q_UNUSED_PAR(par); + +#ifdef Q_SPY +Philo *Philo_inst = me; +QS_OBJ_ARR_DICTIONARY(Philo_inst, me->id); +QS_OBJ_ARR_DICTIONARY(&Philo_inst->timeEvt, me->id); +#endif + +QActive_subscribe(&me->super, EAT_SIG); +QActive_subscribe(&me->super, TEST_SIG); + + + + + + + QTimeEvt_armX(&me->timeEvt, think_time(), 0U); + (void)QTimeEvt_disarm(&me->timeEvt); + + + + + + + + + // EAT or DONE must be for other Philos than this one +Q_ASSERT(Q_EVT_CAST(TableEvt)->philoId != me->id); + + + + + + + + + + + + + + + + + + #ifdef QEVT_DYN_CTOR +TableEvt const *pe = Q_NEW(TableEvt, HUNGRY_SIG, me->id); +#else +TableEvt *pe = Q_NEW(TableEvt, HUNGRY_SIG); +pe->philoId = me->id; +#endif +QACTIVE_POST(AO_Table, &pe->super, &me->super); + + + + + Q_EVT_CAST(TableEvt)->philoId == me->id + + + + + + + + + + + // DONE must be for other Philos than this one +Q_ASSERT(Q_EVT_CAST(TableEvt)->philoId != me->id); + + + + + + + + + + + QTimeEvt_armX(&me->timeEvt, eat_time(), 0U); + QTimeEvt_disarm(&me->timeEvt); + +#ifdef QEVT_DYN_CTOR +TableEvt const *pe = Q_NEW(TableEvt, DONE_SIG, me->id); +#else +TableEvt *pe = Q_NEW(TableEvt, DONE_SIG); +pe->philoId = me->id; +#endif +QACTIVE_PUBLISH(&pe->super, &me->super); + + + + + + + + + // EAT or DONE must be for other Philos than this one +Q_ASSERT(Q_EVT_CAST(TableEvt)->philoId != me->id); + + + + + + + + + + + + + + + + + + + + + + + Q_UNUSED_PAR(par); + +#ifdef Q_SPY +Table *Table_inst = me; +QS_OBJ_DICTIONARY(Table_inst); +#endif + +QActive_subscribe(&me->super, DONE_SIG); +QActive_subscribe(&me->super, PAUSE_SIG); +QActive_subscribe(&me->super, SERVE_SIG); +QActive_subscribe(&me->super, TEST_SIG); + +for (uint8_t n = 0U; n < N_PHILO; ++n) { + me->fork[n] = FREE; + me->isHungry[n] = false; + BSP_displayPhilStat(n, THINKING); +} + + + + + + + + + + + + + + + Q_ERROR(); + + + + + + + // give permissions to eat... +for (uint8_t n = 0U; n < N_PHILO; ++n) { + if (me->isHungry[n] + && (me->fork[left(n)] == FREE) + && (me->fork[n] == FREE)) + { + me->fork[left(n)] = USED; + me->fork[n] = USED; +#ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, EAT_SIG, n); +#else + TableEvt *pe = Q_NEW(TableEvt, EAT_SIG); + pe->philoId = n; +#endif + QACTIVE_PUBLISH(&pe->super, &me->super); + me->isHungry[n] = false; + BSP_displayPhilStat(n, EATING); + } +} + + + uint8_t n = Q_EVT_CAST(TableEvt)->philoId; + +// phil ID must be in range and he must be not hungry +Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); + +BSP_displayPhilStat(n, HUNGRY); +uint8_t m = left(n); + + + (me->fork[m] == FREE) && (me->fork[n] == FREE) + me->fork[m] = USED; +me->fork[n] = USED; + +#ifdef QEVT_DYN_CTOR +TableEvt const *pe = Q_NEW(TableEvt, EAT_SIG, n); +#else +TableEvt *pe = Q_NEW(TableEvt, EAT_SIG); +pe->philoId = n; +#endif +QACTIVE_PUBLISH(&pe->super, &me->super); +BSP_displayPhilStat(n, EATING); + + + + + + + else + me->isHungry[n] = true; + + + + + + + + + + + uint8_t n = Q_EVT_CAST(TableEvt)->philoId; + +// phil ID must be in range and he must be not hungry +Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); + +BSP_displayPhilStat(n, THINKING); +uint8_t m = left(n); + +// both forks of Phil[n] must be used +Q_ASSERT((me->fork[n] == USED) && (me->fork[m] == USED)); + +me->fork[m] = FREE; +me->fork[n] = FREE; +m = right(n); // check the right neighbor + +if (me->isHungry[m] && (me->fork[m] == FREE)) { + me->fork[n] = USED; + me->fork[m] = USED; + me->isHungry[m] = false; +#ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, EAT_SIG, m); +#else + TableEvt *pe = Q_NEW(TableEvt, EAT_SIG); + pe->philoId = m; +#endif + QACTIVE_PUBLISH(&pe->super, &me->super); + BSP_displayPhilStat(m, EATING); +} +m = left(n); // check the left neighbor +n = left(m); // left fork of the left neighbor +if (me->isHungry[m] && (me->fork[n] == FREE)) { + me->fork[m] = USED; + me->fork[n] = USED; + me->isHungry[m] = false; +#ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, EAT_SIG, m); +#else + TableEvt *pe = Q_NEW(TableEvt, EAT_SIG); + pe->philoId = m; +#endif + QACTIVE_PUBLISH(&pe->super, &me->super); + BSP_displayPhilStat(m, EATING); +} + + + + + + + Q_ERROR(); + + + + + + + + + + + + + + + + + BSP_displayPaused(1U); + BSP_displayPaused(0U); + + + + + + + + + uint8_t n = Q_EVT_CAST(TableEvt)->philoId; + +// philo ID must be in range and he must be not hungry +Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); + +me->isHungry[n] = true; +BSP_displayPhilStat(n, HUNGRY); + + + + + + + uint8_t n = Q_EVT_CAST(TableEvt)->philoId; + +// phil ID must be in range and he must be not hungry +Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); + +BSP_displayPhilStat(n, THINKING); +uint8_t m = left(n); + +// both forks of Phil[n] must be used +Q_ASSERT((me->fork[n] == USED) && (me->fork[m] == USED)); + +me->fork[m] = FREE; +me->fork[n] = FREE; + + + + + + + + + + + + + + + + + + + + + + // NOTE: data needed by this thread should be members of +// the thread class. That way they are in the memory region +// accessible from this thread. + + + + + + QS_OBJ_DICTIONARY(TH_XThread1); +QS_OBJ_DICTIONARY(&TH_XThread1->timeEvt); + +// downcast the generic thr pointer to the specific thread +XThread1 *me = (XThread1 *)thr; + +// subscribe to the EAT signal (from the application) +QActive_subscribe(&me->super.super, EAT_SIG); + +for (;;) { + QEvt const *e = QXThread_queueGet(BSP_TICKS_PER_SEC/4U); + if (e) { + QXSemaphore_signal(&TH_sema); // signal Thread2 + QF_gc(e); // must explicitly recycle the received event! + } + + QXMutex_lock(&TH_mutex, QXTHREAD_NO_TIMEOUT); // lock the mutex + BSP_ledOn(); + if (QXMutex_tryLock(&TH_mutex)) { // exercise the mutex + // some floating point code to exercise the VFP... + float volatile x = 1.4142135F; + x = x * 1.4142135F; + QXThread_delay(10U); // BLOCK while holding a mutex + QXMutex_unlock(&TH_mutex); + } + QXMutex_unlock(&TH_mutex); + BSP_ledOff(); +} + + + + + + + // NOTE: data needed by this thread should be members of +// the thread class. That way they are in the memory region +// accessible from this thread. + + + + + + QS_OBJ_DICTIONARY(TH_XThread2); +QS_OBJ_DICTIONARY(&TH_XThread2->timeEvt); +QS_OBJ_DICTIONARY(&TH_sema); +QS_OBJ_DICTIONARY(&TH_mutex); + +// downcast the generic thr pointer to the specific thread +//XThread2 *me = (XThread2 *)thr; + +// initialize the semaphore before using it +// NOTE: Here the semaphore is initialized in the highest-priority thread +// that uses it. Alternatively, the semaphore can be initialized +// before any thread runs. +QXSemaphore_init(&TH_sema, + 0U, // count==0 (signaling semaphore) + 1U); // max_count==1 (binary semaphore) + +// initialize the mutex before using it +// NOTE: Here the mutex is initialized in the highest-priority thread +// that uses it. Alternatively, the mutex can be initialized +// before any thread runs. +QXMutex_init(&TH_mutex, N_PHILO + 6U); // priority-ceiling mutex +//QXMutex_init(&TH_mutex, 0U); // alternatively: priority-ceiling NOT used + +for (;;) { + // wait on a semaphore (BLOCK indefinitely) + QXSemaphore_wait(&TH_sema, QXTHREAD_NO_TIMEOUT); + + QXMutex_lock(&TH_mutex, QXTHREAD_NO_TIMEOUT); // lock the mutex + QXThread_delay(5U); // wait more (BLOCK) + QXMutex_unlock(&TH_mutex); +} + + + + + + + + #ifndef DPP_H_ +#define DPP_H_ + +$declare ${Shared} + +#ifdef QXK_H_ +$declare ${Shared-TH} +#endif // QXK_H_ + +#endif // DPP_H_ + + + + #include "qpc.h" // QP/C real-time embedded framework +#include "dpp.h" // DPP Application interface +#include "bsp.h" // Board Support Package + +$declare ${AOs::Philo} + +//---------------------------------------------------------------------------- +Q_DEFINE_THIS_FILE + +// helper function to provide a randomized think time for Philos +static QTimeEvtCtr think_time(void); // prototype +static inline QTimeEvtCtr think_time(void) { + return (QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + + (BSP_TICKS_PER_SEC/2U)); +} + +// helper function to provide a randomized eat time for Philos +static QTimeEvtCtr eat_time(void); // prototype +static inline QTimeEvtCtr eat_time(void) { + return (QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + + BSP_TICKS_PER_SEC); +} +//---------------------------------------------------------------------------- + +$define ${Shared::Philo_ctor} + +$define ${AOs::Philo} + + + + #include "qpc.h" // QP/C real-time embedded framework +#include "dpp.h" // DPP Application interface +#include "bsp.h" // Board Support Package + +$declare ${AOs::Table} + +//---------------------------------------------------------------------------- +Q_DEFINE_THIS_FILE + +// helper function to provide the RIGHT neighbor of a Philo[n] +static inline uint8_t right(uint8_t const n) { + return (uint8_t)((n + (N_PHILO - 1U)) % N_PHILO); +} + +// helper function to provide the LEFT neighbor of a Philo[n] +static inline uint8_t left(uint8_t const n) { + return (uint8_t)((n + 1U) % N_PHILO); +} + +#define FREE ((uint8_t)0U) +#define USED ((uint8_t)1U) + +#define THINKING "thinking" +#define HUNGRY "hungry " +#define EATING "eating " + +//---------------------------------------------------------------------------- + +$define ${Shared::Table_ctor} + +$define ${AOs::Table} + + + + + + + #include "qpc.h" // QP/C real-time embedded framework +#include "dpp.h" // DPP Application interface +#include "bsp.h" // Board Support Package + +//---------------------------------------------------------------------------- +Q_DEFINE_THIS_FILE + +//---------------------------------------------------------------------------- +$define ${Shared-TH::TH_sema} +$define ${Shared-TH::TH_mutex} + +$declare ${XThreads::XThread1} +$define ${Shared-TH::XThread1_ctor} +$define ${XThreads::XThread1} + + + + #include "qpc.h" // QP/C real-time embedded framework +#include "dpp.h" // DPP Application interface +#include "bsp.h" // Board Support Package + +//---------------------------------------------------------------------------- +Q_DEFINE_THIS_FILE + +//---------------------------------------------------------------------------- +$declare ${XThreads::XThread2} +$define ${Shared-TH::XThread2_ctor} +$define ${XThreads::XThread2} + + + diff --git a/examples/arm-cm/dpp_nucleo-c031c6_mpu/main.c b/examples/arm-cm/dpp_nucleo-c031c6_mpu/main.c new file mode 100644 index 00000000..cfcfaf07 --- /dev/null +++ b/examples/arm-cm/dpp_nucleo-c031c6_mpu/main.c @@ -0,0 +1,44 @@ +//============================================================================ +// APP example +// Last updated for version 7.3.0 +// Last updated on 2023-08-09 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. +// +// This program is open source software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Alternatively, this program may be distributed and modified under the +// terms of Quantum Leaps commercial licenses, which expressly supersede +// the GNU General Public License and are specifically designed for +// licensees interested in retaining the proprietary status of their code. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Contact information: +// +// +//============================================================================ +#include "qpc.h" // QP/C real-time embedded framework +#include "dpp.h" // DPP Application interface +#include "bsp.h" // Board Support Package + +//............................................................................ +int main() { + QF_init(); // initialize the framework and the underlying RT kernel + BSP_init(); // initialize the BSP + BSP_start(); // start the AOs/Threads + return QF_run(); // run the QF application +} diff --git a/examples/arm-cm/dpp_nucleo-c031c6_mpu/philo.c b/examples/arm-cm/dpp_nucleo-c031c6_mpu/philo.c new file mode 100644 index 00000000..cb1f03ec --- /dev/null +++ b/examples/arm-cm/dpp_nucleo-c031c6_mpu/philo.c @@ -0,0 +1,251 @@ +//$file${.::philo.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// +// Model: dpp_mpu.qm +// File: ${.::philo.c} +// +// This code has been generated by QM 5.3.0 . +// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. +// +// SPDX-License-Identifier: GPL-3.0-or-later +// +// This generated code is open source software: you can redistribute it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation. +// +// This code is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// NOTE: +// Alternatively, this generated code may be distributed under the terms +// of Quantum Leaps commercial licenses, which expressly supersede the GNU +// General Public License and are specifically designed for licensees +// interested in retaining the proprietary status of their code. +// +// Contact information: +// +// +// +//$endhead${.::philo.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +#include "qpc.h" // QP/C real-time embedded framework +#include "dpp.h" // DPP Application interface +#include "bsp.h" // Board Support Package + +//$declare${AOs::Philo} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${AOs::Philo} .............................................................. +typedef struct { +// protected: + QActive super; + +// private: + QTimeEvt timeEvt; + uint8_t id; +} Philo; + +// protected: +static QState Philo_initial(Philo * const me, void const * const par); +static QState Philo_thinking(Philo * const me, QEvt const * const e); +static QState Philo_hungry(Philo * const me, QEvt const * const e); +static QState Philo_eating(Philo * const me, QEvt const * const e); +//$enddecl${AOs::Philo} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +//---------------------------------------------------------------------------- +Q_DEFINE_THIS_FILE + +// helper function to provide a randomized think time for Philos +static QTimeEvtCtr think_time(void); // prototype +static inline QTimeEvtCtr think_time(void) { + return (QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + + (BSP_TICKS_PER_SEC/2U)); +} + +// helper function to provide a randomized eat time for Philos +static QTimeEvtCtr eat_time(void); // prototype +static inline QTimeEvtCtr eat_time(void) { + return (QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + + BSP_TICKS_PER_SEC); +} +//---------------------------------------------------------------------------- + +//$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// Check for the minimum required QP version +#if (QP_VERSION < 730U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) +#error qpc version 7.3.0 or higher required +#endif +//$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +//$define${Shared::Philo_ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${Shared::Philo_ctor} ...................................................... +void Philo_ctor( + uint_fast8_t const id, + uint8_t * const sto, + uint32_t const size, + void const * const mpu) +{ + Q_REQUIRE(sizeof(Philo) <= size); + + Philo *me = (Philo *)sto; + QActive_ctor(&me->super, Q_STATE_CAST(&Philo_initial)); + QTimeEvt_ctorX(&me->timeEvt, &me->super, TIMEOUT_SIG, 0U), + me->id = (uint8_t)id; + me->super.thread = mpu; +} +//$enddef${Shared::Philo_ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +//$define${AOs::Philo} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${AOs::Philo} .............................................................. + +//${AOs::Philo::SM} .......................................................... +static QState Philo_initial(Philo * const me, void const * const par) { + //${AOs::Philo::SM::initial} + Q_UNUSED_PAR(par); + + #ifdef Q_SPY + Philo *Philo_inst = me; + QS_OBJ_ARR_DICTIONARY(Philo_inst, me->id); + QS_OBJ_ARR_DICTIONARY(&Philo_inst->timeEvt, me->id); + #endif + + QActive_subscribe(&me->super, EAT_SIG); + QActive_subscribe(&me->super, TEST_SIG); + + QS_FUN_DICTIONARY(&Philo_thinking); + QS_FUN_DICTIONARY(&Philo_hungry); + QS_FUN_DICTIONARY(&Philo_eating); + + return Q_TRAN(&Philo_thinking); +} + +//${AOs::Philo::SM::thinking} ................................................ +static QState Philo_thinking(Philo * const me, QEvt const * const e) { + QState status_; + switch (e->sig) { + //${AOs::Philo::SM::thinking} + case Q_ENTRY_SIG: { + QTimeEvt_armX(&me->timeEvt, think_time(), 0U); + status_ = Q_HANDLED(); + break; + } + //${AOs::Philo::SM::thinking} + case Q_EXIT_SIG: { + (void)QTimeEvt_disarm(&me->timeEvt); + status_ = Q_HANDLED(); + break; + } + //${AOs::Philo::SM::thinking::TIMEOUT} + case TIMEOUT_SIG: { + status_ = Q_TRAN(&Philo_hungry); + break; + } + //${AOs::Philo::SM::thinking::EAT, DONE} + case EAT_SIG: // intentionally fall through + case DONE_SIG: { + // EAT or DONE must be for other Philos than this one + Q_ASSERT(Q_EVT_CAST(TableEvt)->philoId != me->id); + status_ = Q_HANDLED(); + break; + } + //${AOs::Philo::SM::thinking::TEST} + case TEST_SIG: { + status_ = Q_HANDLED(); + break; + } + default: { + status_ = Q_SUPER(&QHsm_top); + break; + } + } + return status_; +} + +//${AOs::Philo::SM::hungry} .................................................. +static QState Philo_hungry(Philo * const me, QEvt const * const e) { + QState status_; + switch (e->sig) { + //${AOs::Philo::SM::hungry} + case Q_ENTRY_SIG: { + #ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, HUNGRY_SIG, me->id); + #else + TableEvt *pe = Q_NEW(TableEvt, HUNGRY_SIG); + pe->philoId = me->id; + #endif + QACTIVE_POST(AO_Table, &pe->super, &me->super); + status_ = Q_HANDLED(); + break; + } + //${AOs::Philo::SM::hungry::EAT} + case EAT_SIG: { + //${AOs::Philo::SM::hungry::EAT::[e->philoId==me->iid]} + if (Q_EVT_CAST(TableEvt)->philoId == me->id) { + status_ = Q_TRAN(&Philo_eating); + } + else { + status_ = Q_UNHANDLED(); + } + break; + } + //${AOs::Philo::SM::hungry::DONE} + case DONE_SIG: { + // DONE must be for other Philos than this one + Q_ASSERT(Q_EVT_CAST(TableEvt)->philoId != me->id); + status_ = Q_HANDLED(); + break; + } + default: { + status_ = Q_SUPER(&QHsm_top); + break; + } + } + return status_; +} + +//${AOs::Philo::SM::eating} .................................................. +static QState Philo_eating(Philo * const me, QEvt const * const e) { + QState status_; + switch (e->sig) { + //${AOs::Philo::SM::eating} + case Q_ENTRY_SIG: { + QTimeEvt_armX(&me->timeEvt, eat_time(), 0U); + status_ = Q_HANDLED(); + break; + } + //${AOs::Philo::SM::eating} + case Q_EXIT_SIG: { + QTimeEvt_disarm(&me->timeEvt); + + #ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, DONE_SIG, me->id); + #else + TableEvt *pe = Q_NEW(TableEvt, DONE_SIG); + pe->philoId = me->id; + #endif + QACTIVE_PUBLISH(&pe->super, &me->super); + status_ = Q_HANDLED(); + break; + } + //${AOs::Philo::SM::eating::TIMEOUT} + case TIMEOUT_SIG: { + status_ = Q_TRAN(&Philo_thinking); + break; + } + //${AOs::Philo::SM::eating::EAT, DONE} + case EAT_SIG: // intentionally fall through + case DONE_SIG: { + // EAT or DONE must be for other Philos than this one + Q_ASSERT(Q_EVT_CAST(TableEvt)->philoId != me->id); + status_ = Q_HANDLED(); + break; + } + default: { + status_ = Q_SUPER(&QHsm_top); + break; + } + } + return status_; +} +//$enddef${AOs::Philo} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/examples/arm-cm/dpp_nucleo-c031c6_mpu/qk/armclang/README.txt b/examples/arm-cm/dpp_nucleo-c031c6_mpu/qk/armclang/README.txt new file mode 100644 index 00000000..946a6967 --- /dev/null +++ b/examples/arm-cm/dpp_nucleo-c031c6_mpu/qk/armclang/README.txt @@ -0,0 +1,74 @@ +About this Example +================== +This example demonstrates how to use the uVision IDE together with +the MDK-ARM toolchain. + +*** +NOTE: This example requires installing the following Software Pack +in the Keil uVision: Keil::STM32C0xx_DFP. +*** + +uVision Project File +==================== +The MDK-ARM uVision project file provided with this example uses +relative paths to the QP/C framework location (includes, port, and +libraries. These relative paths must be modified when the project +is moved to different relative location. + + +Adjusting Stack and Heap Sizes +============================== +The stack and heap sizes are determined in this project by the +command-line options for the ARM assembler (see the Asm tab in +the "Options for Target" dialog box in uVision). Specifically, +you should define symbols: Stack_Size=xxx Heap_Size=yyy, where +xxx represents a numerical value of stack size and yyy the +numberical value of the heap size. + + +Selecting QK Exception +====================== +The QK kernel needs a dedicated exception to return to the thread +context after preemption. The default is to use the NMI exception +for that purpose. However, in case NMI is needed for some other +purpose, the QK port allows you to select a any, otherwise unused +IRQ for that purpose. To choose a given IRQ, you need to define +the macros QK_USE_IRQ_NUM and QK_USE_IRQ_HANDLER. These macros can +be provided on the command-line to the compiler. + +For example, (see the vector table), you can define the QK IRQ +as follows: + +QK_USE_IRQ_HANDLER=Reserved31_IRQHandler +QK_USE_IRQ_NUM=31 + + +Startup Code +============ +The startup code for the STM32C0xx MCU used in this project is +located in the "3rd_party" folder in the following location: + +3rd_party\nucleo-c031c6\arm\startup_stm32c031xx.s + +The file startup_stm32c031xx.s provides a template of the recommended +startup for QP applications and should be easily customizable for other +ARM Cortex-M microcontrollers. + +The startup file typically does not need to be modified or adapted for +applications. It calls the assert_failed() function, which must be +defined in the application to customize it for the application-specific +error-handling policy. + + +Adjusting the CPU Clock Speed +============================= +The current setting is to run at 12MHz from the MSI (internal oscillator), +but the CPU clock speed can be modified. + +*** +NOTE: +The NUCLEO boards have a wide range of possible clock selections, depending +on the solder bridge configuration. Please see Chapter 5.7 "OSC clock" in +the STM32 NUCLEO Boards User Manual (ST document UM1724) for more information. +*** + diff --git a/examples/arm-cm/dpp_nucleo-c031c6_mpu/qk/armclang/dpp-qk.sct b/examples/arm-cm/dpp_nucleo-c031c6_mpu/qk/armclang/dpp-qk.sct new file mode 100644 index 00000000..381870e8 --- /dev/null +++ b/examples/arm-cm/dpp_nucleo-c031c6_mpu/qk/armclang/dpp-qk.sct @@ -0,0 +1,23 @@ +; ************************************************************* +; *** Scatter-Loading Description File generated by uVision *** +; +; Adapted by Quantum Leaps: +; moved STACK as the first section in RW_STACK +; ************************************************************* + +LR_IROM1 0x08000000 0x00080000 { ; load region size_region + ER_IROM1 0x08000000 0x00080000 { ; load address = execution address + *.o (RESET, +First) + *(InRoot$$Sections) + .ANY (+RO) + .ANY (+XO) + } + + RW_STACK 0x20000000 { + * (STACK, +First) + } + RW_IRAM1 +0 (0x00030000 - 2048) { + .ANY (+RW +ZI) + } +} + diff --git a/examples/arm-cm/dpp_nucleo-c031c6_mpu/qk/armclang/dpp-qk.uvoptx b/examples/arm-cm/dpp_nucleo-c031c6_mpu/qk/armclang/dpp-qk.uvoptx new file mode 100644 index 00000000..a422cd8b --- /dev/null +++ b/examples/arm-cm/dpp_nucleo-c031c6_mpu/qk/armclang/dpp-qk.uvoptx @@ -0,0 +1,1012 @@ + + + + 1.0 + +
### uVision Project, (C) Keil Software
+ + + *.c + *.s*; *.src; *.a* + *.obj; *.o + *.lib + *.txt; *.h; *.inc; *.md + *.plm + *.cpp + 0 + + + + 0 + 0 + + + + dpp-dbg + 0x4 + ARM-ADS + + 12000000 + + 1 + 1 + 0 + 1 + 0 + + + 1 + 65535 + 0 + 0 + 0 + + + 79 + 66 + 8 + .\dbg\ + + + 1 + 1 + 1 + 0 + 1 + 1 + 0 + 1 + 0 + 0 + 0 + 0 + + + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + + + 1 + 0 + 1 + + 18 + + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + 0 + 1 + 1 + 0 + 0 + 1 + 0 + 0 + 6 + + + + + + + + + + + STLink\ST-LINKIII-KEIL_SWO.dll + + + + 0 + ST-LINKIII-KEIL_SWO + -U066BFF505153848667095842 -O206 -SF10000 -C0 -A0 -I0 -HNlocalhost -HP7184 -P1 -N00("ARM CoreSight SW-DP (ARM Core") -D00(0BC11477) -L00(0) -TO65554 -TC10000000 -TT10000000 -TP21 -TDS8007 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -FO7 -FD20000000 -FC1000 -FN1 -FF0STM32C0x_32.FLM -FS08000000 -FL08000 -FP0($$Device:STM32C031C6Tx$CMSIS\Flash\STM32C0x_32.FLM) + + + 0 + UL2CM3 + -U -O206 -S8 -C0 -P00 -N00("") -D00(00000000) -L00(0) -TO65554 -TC10000000 -TT10000000 -TP21 -TDS8007 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -FO7 -FD20000000 -FC1000 -FN1 -FF0STM32C0x_32.FLM -FS08000000 -FL08000 -FP0($$Device:STM32C031C6Tx$CMSIS\Flash\STM32C0x_32.FLM) + + + 0 + DLGUARM + (105=-1,-1,-1,-1,0) + + + 0 + ARMRTXEVENTFLAGS + -L70 -Z18 -C0 -M0 -T1 + + + 0 + DLGTARM + (1010=-1,-1,-1,-1,0)(1007=-1,-1,-1,-1,0)(1008=-1,-1,-1,-1,0)(1012=3145,367,3620,681,1)(1009=-1,-1,-1,-1,0) + + + 0 + ARMDBGFLAGS + + + + + + + 1 + 2 + 0x20000200 + 0 + + + + + 2 + 0 + 0x400 + 0 + + + + 0 + + + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + + + + 0 + 0 + 0 + + + + + + + + + + 1 + 0 + 0 + 2 + 10000000 + + + + + + dpp-rel + 0x4 + ARM-ADS + + 12000000 + + 1 + 1 + 0 + 1 + 0 + + + 1 + 65535 + 0 + 0 + 0 + + + 79 + 66 + 8 + .\rel\ + + + 1 + 1 + 1 + 0 + 1 + 1 + 0 + 1 + 0 + 0 + 0 + 0 + + + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + + + 1 + 0 + 0 + + 18 + + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + 0 + 1 + 1 + 0 + 0 + 1 + 0 + 0 + 6 + + + + + + + + + + + STLink\ST-LINKIII-KEIL_SWO.dll + + + + 0 + UL2CM3 + UL2CM3(-S0 -C0 -P0 ) -FN1 -FC1000 -FD20000000 -FF0STM32C0x_32 -FL08000 -FS08000000 -FP0($$Device:STM32C031C6Tx$CMSIS\Flash\STM32C0x_32.FLM) + + + 0 + ST-LINKIII-KEIL_SWO + -U-O206 -O206 -SF10000 -C0 -A0 -I0 -HNlocalhost -HP7184 -P1 -N00("ARM CoreSight SW-DP (ARM Core") -D00(0BC11477) -L00(0) -TO131090 -TC10000000 -TT10000000 -TP21 -TDS8007 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -FO7 -FD20000000 -FC1000 -FN1 -FF0STM32C0x_32.FLM -FS08000000 -FL08000 -FP0($$Device:STM32C031C6Tx$CMSIS\Flash\STM32C0x_32.FLM) + + + 0 + DLGUARM + (105=-1,-1,-1,-1,0) + + + 0 + ARMRTXEVENTFLAGS + -L70 -Z18 -C0 -M0 -T1 + + + 0 + DLGTARM + (1010=-1,-1,-1,-1,0)(1007=-1,-1,-1,-1,0)(1008=-1,-1,-1,-1,0)(1012=3332,469,3807,783,1)(1009=-1,-1,-1,-1,0) + + + 0 + ARMDBGFLAGS + + + + + + + 1 + 2 + 0x20000200 + 0 + + + + + 2 + 0 + 0x400 + 0 + + + + 0 + + + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + + + + 0 + 0 + 0 + + + + + + + + + + 1 + 0 + 0 + 2 + 10000000 + + + + + + dpp-spy + 0x4 + ARM-ADS + + 12000000 + + 1 + 1 + 0 + 1 + 0 + + + 1 + 65535 + 0 + 0 + 0 + + + 79 + 66 + 8 + .\spy\ + + + 1 + 1 + 1 + 0 + 1 + 1 + 0 + 1 + 0 + 0 + 0 + 0 + + + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + + + 1 + 0 + 0 + + 18 + + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + 0 + 1 + 1 + 0 + 0 + 1 + 0 + 0 + 6 + + + + + + + + + + + STLink\ST-LINKIII-KEIL_SWO.dll + + + + 0 + UL2CM3 + UL2CM3(-S0 -C0 -P0 ) -FN1 -FC1000 -FD20000000 -FF0STM32C0x_32 -FL08000 -FS08000000 -FP0($$Device:STM32C031C6Tx$CMSIS\Flash\STM32C0x_32.FLM) + + + 0 + ST-LINKIII-KEIL_SWO + -U-O206 -O206 -SF10000 -C0 -A0 -I0 -HNlocalhost -HP7184 -P1 -N00("ARM CoreSight SW-DP (ARM Core") -D00(0BC11477) -L00(0) -TO131090 -TC10000000 -TT10000000 -TP21 -TDS8007 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -FO7 -FD20000000 -FC1000 -FN1 -FF0STM32C0x_32.FLM -FS08000000 -FL08000 -FP0($$Device:STM32C031C6Tx$CMSIS\Flash\STM32C0x_32.FLM) + + + 0 + DLGUARM + (105=-1,-1,-1,-1,0) + + + 0 + ARMRTXEVENTFLAGS + -L70 -Z18 -C0 -M0 -T1 + + + 0 + DLGTARM + (1010=-1,-1,-1,-1,0)(1007=-1,-1,-1,-1,0)(1008=-1,-1,-1,-1,0)(1012=-1,-1,-1,-1,0)(1009=-1,-1,-1,-1,0) + + + 0 + ARMDBGFLAGS + + + + + + + 1 + 2 + 0x20000200 + 0 + + + + + 2 + 0 + 0x400 + 0 + + + + 0 + + + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + + + + 0 + 0 + 0 + + + + + + + + + + 1 + 0 + 0 + 2 + 10000000 + + + + + + Source Code + 1 + 0 + 0 + 0 + + 1 + 1 + 1 + 0 + 0 + 0 + ..\bsp.c + bsp.c + 0 + 0 + + + 1 + 2 + 5 + 0 + 0 + 0 + ..\..\bsp.h + bsp.h + 0 + 0 + + + 1 + 3 + 5 + 0 + 0 + 0 + ..\..\dpp.h + dpp.h + 0 + 0 + + + 1 + 4 + 1 + 0 + 0 + 0 + ..\..\philo.c + philo.c + 0 + 0 + + + 1 + 5 + 1 + 0 + 0 + 0 + ..\..\table.c + table.c + 0 + 0 + + + 1 + 6 + 5 + 0 + 0 + 0 + .\dpp-qk.sct + dpp-qk.sct + 0 + 0 + + + 1 + 7 + 1 + 0 + 0 + 0 + ..\..\main.c + main.c + 0 + 0 + + + + + nucleo-c031c6 + 1 + 0 + 0 + 0 + + 2 + 8 + 5 + 0 + 0 + 0 + ..\..\..\..\..\3rd_party\nucleo-c031c6\stm32c0xx.h + stm32c0xx.h + 0 + 0 + + + 2 + 9 + 5 + 0 + 0 + 0 + ..\..\..\..\..\3rd_party\nucleo-c031c6\stm32c031xx.h + stm32c031xx.h + 0 + 0 + + + 2 + 10 + 1 + 0 + 0 + 0 + ..\..\..\..\..\3rd_party\nucleo-c031c6\system_stm32c0xx.c + system_stm32c0xx.c + 0 + 0 + + + 2 + 11 + 2 + 0 + 0 + 0 + ..\..\..\..\..\3rd_party\nucleo-c031c6\arm\startup_stm32c031xx.s + startup_stm32c031xx.s + 0 + 0 + + + + + QP + 1 + 0 + 0 + 0 + + 3 + 12 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qf\qep_hsm.c + qep_hsm.c + 0 + 0 + + + 3 + 13 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qf\qep_msm.c + qep_msm.c + 0 + 0 + + + 3 + 14 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qf\qf_act.c + qf_act.c + 0 + 0 + + + 3 + 15 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qf\qf_actq.c + qf_actq.c + 0 + 0 + + + 3 + 16 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qf\qf_defer.c + qf_defer.c + 0 + 0 + + + 3 + 17 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qf\qf_dyn.c + qf_dyn.c + 0 + 0 + + + 3 + 18 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qf\qf_mem.c + qf_mem.c + 0 + 0 + + + 3 + 19 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qf\qf_ps.c + qf_ps.c + 0 + 0 + + + 3 + 20 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qf\qf_qact.c + qf_qact.c + 0 + 0 + + + 3 + 21 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qf\qf_qeq.c + qf_qeq.c + 0 + 0 + + + 3 + 22 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qf\qf_qmact.c + qf_qmact.c + 0 + 0 + + + 3 + 23 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qf\qf_time.c + qf_time.c + 0 + 0 + + + 3 + 24 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qk\qk.c + qk.c + 0 + 0 + + + + + QP_port + 1 + 0 + 0 + 0 + + 4 + 25 + 1 + 0 + 0 + 0 + ..\..\..\..\..\ports\arm-cm\qk\armclang\qk_port.c + qk_port.c + 0 + 0 + + + + + QS + 1 + 0 + 0 + 0 + + 5 + 26 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qs\qs.c + qs.c + 0 + 0 + + + 5 + 27 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qs\qs_64bit.c + qs_64bit.c + 0 + 0 + + + 5 + 28 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qs\qs_fp.c + qs_fp.c + 0 + 0 + + + 5 + 29 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qs\qs_rx.c + qs_rx.c + 0 + 0 + + + 5 + 30 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qs\qstamp.c + qstamp.c + 0 + 0 + + + +
diff --git a/examples/arm-cm/dpp_nucleo-c031c6_mpu/qk/armclang/dpp-qk.uvprojx b/examples/arm-cm/dpp_nucleo-c031c6_mpu/qk/armclang/dpp-qk.uvprojx new file mode 100644 index 00000000..7df747d3 --- /dev/null +++ b/examples/arm-cm/dpp_nucleo-c031c6_mpu/qk/armclang/dpp-qk.uvprojx @@ -0,0 +1,1808 @@ + + + + 2.1 + +
### uVision Project, (C) Keil Software
+ + + + dpp-dbg + 0x4 + ARM-ADS + 6160000::V6.16::ARMCLANG + 1 + + + STM32C031C6Tx + STMicroelectronics + Keil.STM32C0xx_DFP.1.0.0 + https://www.keil.com/pack/ + IRAM(0x20000000,0x00003000) IROM(0x08000000,0x00008000) CPUTYPE("Cortex-M0+") CLOCK(12000000) ELITTLE + + + UL2CM3(-S0 -C0 -P0 -FD20000000 -FC1000 -FN1 -FF0STM32C0x_32 -FS08000000 -FL08000 -FP0($$Device:STM32C031C6Tx$CMSIS\Flash\STM32C0x_32.FLM)) + 0 + $$Device:STM32C031C6Tx$Drivers\CMSIS\Device\ST\STM32C0xx\Include\stm32c0xx.h + + + + + + + + + + $$Device:STM32C031C6Tx$CMSIS\SVD\STM32C031.svd + 0 + 0 + + + + + + + 0 + 0 + 0 + 0 + 1 + + .\dbg\ + dpp-qk + 1 + 0 + 0 + 1 + 1 + .\dbg\ + 1 + 0 + 0 + + 0 + 0 + + + 0 + 0 + 0 + 0 + + + 1 + 0 + cmd /c "del .\dbg\qstamp.o" + + 0 + 0 + 0 + 0 + + + 1 + 0 + fromelf --bin --output .\dbg\dpp-qk.bin .\dbg\dpp-qk.axf + + 0 + 0 + 0 + 0 + + 0 + + + + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 3 + + + 1 + + + SARMCM3.DLL + -REMAP-MPU + DARMCM1.DLL + -pCM0+ + SARMCM3.DLL + -MPU + TARMCM1.DLL + -pCM0+ + + + + 1 + 0 + 0 + 0 + 16 + + + + + 1 + 0 + 0 + 1 + 1 + 4096 + + 1 + BIN\UL2CM3.DLL + "" () + + + + + 0 + + + + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + 1 + 0 + 0 + 0 + 0 + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + "Cortex-M0+" + + 0 + 0 + 0 + 1 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 8 + 0 + 0 + 0 + 0 + 3 + 3 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 1 + 0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x20000000 + 0x3000 + + + 1 + 0x8000000 + 0x8000 + + + 0 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x8000000 + 0x8000 + + + 1 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x20000000 + 0x3000 + + + 0 + 0x0 + 0x0 + + + + + + 0 + 1 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 3 + 0 + 1 + 0 + 0 + 0 + 3 + 3 + 0 + 0 + 0 + 0 + 0 + + + QP_CONFIG + + ..\..;..\..\..\..\..\include;..\..\..\..\..\ports\arm-cm\qk\armclang;..\..\..\..\..\3rd_party\CMSIS\Include;..\..\..\..\..\3rd_party\nucleo-c031c6 + + + + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 4 + + + Stack_Size=2048 Heap_Size=16 + + + + + + 0 + 0 + 0 + 0 + 1 + 0 + 0x00000000 + 0x20000000 + + .\dpp-qk.sct + + + --entry Reset_Handler + + + + + + + + Source Code + + + bsp.c + 1 + ..\bsp.c + + + bsp.h + 5 + ..\..\bsp.h + + + dpp.h + 5 + ..\..\dpp.h + + + philo.c + 1 + ..\..\philo.c + + + table.c + 1 + ..\..\table.c + + + dpp-qk.sct + 5 + .\dpp-qk.sct + + + main.c + 1 + ..\..\main.c + + + + + nucleo-c031c6 + + + stm32c0xx.h + 5 + ..\..\..\..\..\3rd_party\nucleo-c031c6\stm32c0xx.h + + + stm32c031xx.h + 5 + ..\..\..\..\..\3rd_party\nucleo-c031c6\stm32c031xx.h + + + system_stm32c0xx.c + 1 + ..\..\..\..\..\3rd_party\nucleo-c031c6\system_stm32c0xx.c + + + startup_stm32c031xx.s + 2 + ..\..\..\..\..\3rd_party\nucleo-c031c6\arm\startup_stm32c031xx.s + + + + + QP + + + qep_hsm.c + 1 + ..\..\..\..\..\src\qf\qep_hsm.c + + + qep_msm.c + 1 + ..\..\..\..\..\src\qf\qep_msm.c + + + qf_act.c + 1 + ..\..\..\..\..\src\qf\qf_act.c + + + qf_actq.c + 1 + ..\..\..\..\..\src\qf\qf_actq.c + + + qf_defer.c + 1 + ..\..\..\..\..\src\qf\qf_defer.c + + + qf_dyn.c + 1 + ..\..\..\..\..\src\qf\qf_dyn.c + + + qf_mem.c + 1 + ..\..\..\..\..\src\qf\qf_mem.c + + + qf_ps.c + 1 + ..\..\..\..\..\src\qf\qf_ps.c + + + qf_qact.c + 1 + ..\..\..\..\..\src\qf\qf_qact.c + + + qf_qeq.c + 1 + ..\..\..\..\..\src\qf\qf_qeq.c + + + qf_qmact.c + 1 + ..\..\..\..\..\src\qf\qf_qmact.c + + + qf_time.c + 1 + ..\..\..\..\..\src\qf\qf_time.c + + + qk.c + 1 + ..\..\..\..\..\src\qk\qk.c + + + + + QP_port + + + qk_port.c + 1 + ..\..\..\..\..\ports\arm-cm\qk\armclang\qk_port.c + + + + + QS + + + 0 + 0 + 0 + 0 + 0 + 0 + 2 + 2 + 2 + 2 + 11 + + + 1 + + + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 0 + 0 + 0 + 0 + 2 + + + + + + + + + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + + + + + + + + + + + + qs.c + 1 + ..\..\..\..\..\src\qs\qs.c + + + qs_64bit.c + 1 + ..\..\..\..\..\src\qs\qs_64bit.c + + + qs_fp.c + 1 + ..\..\..\..\..\src\qs\qs_fp.c + + + qs_rx.c + 1 + ..\..\..\..\..\src\qs\qs_rx.c + + + qstamp.c + 1 + ..\..\..\..\..\src\qs\qstamp.c + + + + + + + dpp-rel + 0x4 + ARM-ADS + 6160000::V6.16::ARMCLANG + 1 + + + STM32C031C6Tx + STMicroelectronics + Keil.STM32C0xx_DFP.1.0.0 + https://www.keil.com/pack/ + IRAM(0x20000000,0x00003000) IROM(0x08000000,0x00008000) CPUTYPE("Cortex-M0+") CLOCK(12000000) ELITTLE + + + UL2CM3(-S0 -C0 -P0 -FD20000000 -FC1000 -FN1 -FF0STM32C0x_32 -FS08000000 -FL08000 -FP0($$Device:STM32C031C6Tx$CMSIS\Flash\STM32C0x_32.FLM)) + 0 + $$Device:STM32C031C6Tx$Drivers\CMSIS\Device\ST\STM32C0xx\Include\stm32c0xx.h + + + + + + + + + + $$Device:STM32C031C6Tx$CMSIS\SVD\STM32C031.svd + 0 + 0 + + + + + + + 0 + 0 + 0 + 0 + 1 + + .\rel\ + dpp-qk + 1 + 0 + 0 + 0 + 0 + .\rel\ + 1 + 0 + 0 + + 0 + 0 + + + 0 + 0 + 0 + 0 + + + 1 + 0 + cmd /c "del .\rel\qstamp.o" + + 0 + 0 + 0 + 0 + + + 1 + 0 + fromelf --bin --output .\rel\dpp-qk.bin .\rel\dpp-qk.axf + + 0 + 0 + 0 + 0 + + 0 + + + + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 3 + + + 1 + + + SARMCM3.DLL + -REMAP-MPU + DARMCM1.DLL + -pCM0+ + SARMCM3.DLL + -MPU + TARMCM1.DLL + -pCM0+ + + + + 1 + 0 + 0 + 0 + 16 + + + + + 1 + 0 + 0 + 1 + 1 + 4097 + + 1 + BIN\UL2CM3.DLL + + + + + + 0 + + + + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + 1 + 0 + 0 + 0 + 0 + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + "Cortex-M0+" + + 0 + 0 + 0 + 1 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 8 + 0 + 0 + 0 + 0 + 3 + 3 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 1 + 0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x20000000 + 0x3000 + + + 1 + 0x8000000 + 0x8000 + + + 0 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x8000000 + 0x8000 + + + 1 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x20000000 + 0x3000 + + + 0 + 0x0 + 0x0 + + + + + + 0 + 6 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 3 + 0 + 1 + 0 + 0 + 0 + 3 + 3 + 0 + 0 + 1 + 0 + 0 + + + NDEBUG,QP_CONFIG + + ..\..;..\..\..\..\..\include;..\..\..\..\..\ports\arm-cm\qk\armclang;..\..\..\..\..\3rd_party\CMSIS\Include;..\..\..\..\..\3rd_party\nucleo-c031c6 + + + + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 4 + + + Stack_Size=2048 Heap_Size=16 + + + + + + 0 + 0 + 0 + 0 + 1 + 0 + 0x00000000 + 0x20000000 + + .\dpp-qk.sct + + + --entry Reset_Handler + + + + + + + + Source Code + + + bsp.c + 1 + ..\bsp.c + + + bsp.h + 5 + ..\..\bsp.h + + + dpp.h + 5 + ..\..\dpp.h + + + philo.c + 1 + ..\..\philo.c + + + table.c + 1 + ..\..\table.c + + + dpp-qk.sct + 5 + .\dpp-qk.sct + + + main.c + 1 + ..\..\main.c + + + + + nucleo-c031c6 + + + stm32c0xx.h + 5 + ..\..\..\..\..\3rd_party\nucleo-c031c6\stm32c0xx.h + + + stm32c031xx.h + 5 + ..\..\..\..\..\3rd_party\nucleo-c031c6\stm32c031xx.h + + + system_stm32c0xx.c + 1 + ..\..\..\..\..\3rd_party\nucleo-c031c6\system_stm32c0xx.c + + + startup_stm32c031xx.s + 2 + ..\..\..\..\..\3rd_party\nucleo-c031c6\arm\startup_stm32c031xx.s + + + + + QP + + + qep_hsm.c + 1 + ..\..\..\..\..\src\qf\qep_hsm.c + + + qep_msm.c + 1 + ..\..\..\..\..\src\qf\qep_msm.c + + + qf_act.c + 1 + ..\..\..\..\..\src\qf\qf_act.c + + + qf_actq.c + 1 + ..\..\..\..\..\src\qf\qf_actq.c + + + qf_defer.c + 1 + ..\..\..\..\..\src\qf\qf_defer.c + + + qf_dyn.c + 1 + ..\..\..\..\..\src\qf\qf_dyn.c + + + qf_mem.c + 1 + ..\..\..\..\..\src\qf\qf_mem.c + + + qf_ps.c + 1 + ..\..\..\..\..\src\qf\qf_ps.c + + + qf_qact.c + 1 + ..\..\..\..\..\src\qf\qf_qact.c + + + qf_qeq.c + 1 + ..\..\..\..\..\src\qf\qf_qeq.c + + + qf_qmact.c + 1 + ..\..\..\..\..\src\qf\qf_qmact.c + + + qf_time.c + 1 + ..\..\..\..\..\src\qf\qf_time.c + + + qk.c + 1 + ..\..\..\..\..\src\qk\qk.c + + + + + QP_port + + + qk_port.c + 1 + ..\..\..\..\..\ports\arm-cm\qk\armclang\qk_port.c + + + + + QS + + + 0 + 0 + 0 + 0 + 0 + 0 + 2 + 2 + 2 + 2 + 11 + + + 1 + + + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 0 + 0 + 0 + 0 + 2 + + + + + + + + + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + + + + + + + + + + + + qs.c + 1 + ..\..\..\..\..\src\qs\qs.c + + + qs_64bit.c + 1 + ..\..\..\..\..\src\qs\qs_64bit.c + + + qs_fp.c + 1 + ..\..\..\..\..\src\qs\qs_fp.c + + + qs_rx.c + 1 + ..\..\..\..\..\src\qs\qs_rx.c + + + qstamp.c + 1 + ..\..\..\..\..\src\qs\qstamp.c + + + + + + + dpp-spy + 0x4 + ARM-ADS + 6160000::V6.16::ARMCLANG + 1 + + + STM32C031C6Tx + STMicroelectronics + Keil.STM32C0xx_DFP.1.0.0 + https://www.keil.com/pack/ + IRAM(0x20000000,0x00003000) IROM(0x08000000,0x00008000) CPUTYPE("Cortex-M0+") CLOCK(12000000) ELITTLE + + + UL2CM3(-S0 -C0 -P0 -FD20000000 -FC1000 -FN1 -FF0STM32C0x_32 -FS08000000 -FL08000 -FP0($$Device:STM32C031C6Tx$CMSIS\Flash\STM32C0x_32.FLM)) + 0 + $$Device:STM32C031C6Tx$Drivers\CMSIS\Device\ST\STM32C0xx\Include\stm32c0xx.h + + + + + + + + + + $$Device:STM32C031C6Tx$CMSIS\SVD\STM32C031.svd + 0 + 0 + + + + + + + 0 + 0 + 0 + 0 + 1 + + .\spy\ + dpp-qk + 1 + 0 + 0 + 1 + 1 + .\spy\ + 1 + 0 + 0 + + 0 + 0 + + + 0 + 0 + 0 + 0 + + + 1 + 0 + cmd /c "del .\spy\qstamp.o" + + 0 + 0 + 0 + 0 + + + 1 + 0 + fromelf --bin --output .\spy\dpp-qk.bin .\spy\dpp-qk.axf + + 0 + 0 + 0 + 0 + + 0 + + + + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 3 + + + 1 + + + SARMCM3.DLL + -REMAP-MPU + DARMCM1.DLL + -pCM0+ + SARMCM3.DLL + -MPU + TARMCM1.DLL + -pCM0+ + + + + 1 + 0 + 0 + 0 + 16 + + + + + 1 + 0 + 0 + 1 + 1 + 4096 + + 1 + BIN\UL2CM3.DLL + + + + + + 0 + + + + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + 1 + 0 + 0 + 0 + 0 + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + "Cortex-M0+" + + 0 + 0 + 0 + 1 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 8 + 0 + 0 + 0 + 0 + 3 + 3 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 1 + 0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x20000000 + 0x3000 + + + 1 + 0x8000000 + 0x8000 + + + 0 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x8000000 + 0x8000 + + + 1 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x20000000 + 0x3000 + + + 0 + 0x0 + 0x0 + + + + + + 0 + 2 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 3 + 0 + 1 + 0 + 0 + 0 + 3 + 3 + 0 + 0 + 0 + 0 + 0 + + + Q_SPY,QP_CONFIG + + ..\..;..\..\..\..\..\include;..\..\..\..\..\ports\arm-cm\qk\armclang;..\..\..\..\..\3rd_party\CMSIS\Include;..\..\..\..\..\3rd_party\nucleo-c031c6 + + + + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 4 + + + Stack_Size=2048 Heap_Size=16 + + + + + + 0 + 0 + 0 + 0 + 1 + 0 + 0x00000000 + 0x20000000 + + .\dpp-qk.sct + + + --entry Reset_Handler + + + + + + + + Source Code + + + bsp.c + 1 + ..\bsp.c + + + bsp.h + 5 + ..\..\bsp.h + + + dpp.h + 5 + ..\..\dpp.h + + + philo.c + 1 + ..\..\philo.c + + + table.c + 1 + ..\..\table.c + + + dpp-qk.sct + 5 + .\dpp-qk.sct + + + main.c + 1 + ..\..\main.c + + + + + nucleo-c031c6 + + + stm32c0xx.h + 5 + ..\..\..\..\..\3rd_party\nucleo-c031c6\stm32c0xx.h + + + stm32c031xx.h + 5 + ..\..\..\..\..\3rd_party\nucleo-c031c6\stm32c031xx.h + + + system_stm32c0xx.c + 1 + ..\..\..\..\..\3rd_party\nucleo-c031c6\system_stm32c0xx.c + + + startup_stm32c031xx.s + 2 + ..\..\..\..\..\3rd_party\nucleo-c031c6\arm\startup_stm32c031xx.s + + + + + QP + + + qep_hsm.c + 1 + ..\..\..\..\..\src\qf\qep_hsm.c + + + qep_msm.c + 1 + ..\..\..\..\..\src\qf\qep_msm.c + + + qf_act.c + 1 + ..\..\..\..\..\src\qf\qf_act.c + + + qf_actq.c + 1 + ..\..\..\..\..\src\qf\qf_actq.c + + + qf_defer.c + 1 + ..\..\..\..\..\src\qf\qf_defer.c + + + qf_dyn.c + 1 + ..\..\..\..\..\src\qf\qf_dyn.c + + + qf_mem.c + 1 + ..\..\..\..\..\src\qf\qf_mem.c + + + qf_ps.c + 1 + ..\..\..\..\..\src\qf\qf_ps.c + + + qf_qact.c + 1 + ..\..\..\..\..\src\qf\qf_qact.c + + + qf_qeq.c + 1 + ..\..\..\..\..\src\qf\qf_qeq.c + + + qf_qmact.c + 1 + ..\..\..\..\..\src\qf\qf_qmact.c + + + qf_time.c + 1 + ..\..\..\..\..\src\qf\qf_time.c + + + qk.c + 1 + ..\..\..\..\..\src\qk\qk.c + + + + + QP_port + + + qk_port.c + 1 + ..\..\..\..\..\ports\arm-cm\qk\armclang\qk_port.c + + + + + QS + + + qs.c + 1 + ..\..\..\..\..\src\qs\qs.c + + + qs_64bit.c + 1 + ..\..\..\..\..\src\qs\qs_64bit.c + + + qs_fp.c + 1 + ..\..\..\..\..\src\qs\qs_fp.c + + + qs_rx.c + 1 + ..\..\..\..\..\src\qs\qs_rx.c + + + qstamp.c + 1 + ..\..\..\..\..\src\qs\qstamp.c + + + + + + + + + + + + + +
diff --git a/examples/arm-cm/dpp_nucleo-c031c6_mpu/qk/bsp.c b/examples/arm-cm/dpp_nucleo-c031c6_mpu/qk/bsp.c new file mode 100644 index 00000000..6b658921 --- /dev/null +++ b/examples/arm-cm/dpp_nucleo-c031c6_mpu/qk/bsp.c @@ -0,0 +1,853 @@ +//============================================================================ +// Product: DPP example, NUCLEO-C031C6 board, QK kernel, MPU isolation +// Last updated for version 7.3.0 +// Last updated on 2023-08-28 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. +// +// This program is open source software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Alternatively, this program may be distributed and modified under the +// terms of Quantum Leaps commercial licenses, which expressly supersede +// the GNU General Public License and are specifically designed for +// licensees interested in retaining the proprietary status of their code. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Contact information: +// +// +//============================================================================ +#include "qpc.h" // QP/C real-time embedded framework +#include "dpp.h" // DPP Application interface +#include "bsp.h" // Board Support Package + +#include "stm32c0xx.h" // CMSIS-compliant header file for the MCU used +// add other drivers if necessary... + +Q_DEFINE_THIS_FILE // define the name of this file for assertions + +// Local-scope defines ----------------------------------------------------- +// LED pins available on the board (just one user LED LD4--Green on PA.5) +#define LD4_PIN 5U + +// Button pins available on the board (just one user Button B1 on PC.13) +#define B1_PIN 13U + +#ifdef Q_SPY + QSTimeCtr QS_tickTime_; + QSTimeCtr QS_tickPeriod_; + + // QSpy source IDs + static QSpyId const l_SysTick_Handler = { 0U }; + + enum AppRecords { // application-specific trace records + PHILO_STAT = QS_USER, + PAUSED_STAT, + }; + +#endif + +//---------------------------------------------------------------------------- +// MPU storage and settings... +typedef struct { + uint32_t RBAR; + uint32_t RASR; +} MPU_Region; + +//============================================================================ +// Error handler and ISRs... + +Q_NORETURN Q_onError(char const *module, int_t const id) { + // NOTE: this implementation of the assertion handler is intended only + // for debugging and MUST be changed for deployment of the application + // (assuming that you ship your production code with assertions enabled). + Q_UNUSED_PAR(module); + Q_UNUSED_PAR(id); + QS_ASSERTION(module, id, 10000U); + +#ifndef NDEBUG + // light up the user LED + GPIOA->BSRR = (1U << LD4_PIN); // turn LED on + // for debugging, hang on in an endless loop... + for (;;) { + } +#endif + + NVIC_SystemReset(); +} +//............................................................................ +void assert_failed(char const * const module, int_t const id); // prototype +void assert_failed(char const * const module, int_t const id) { + Q_onError(module, id); +} + +// ISRs used in the application ========================================== +void SysTick_Handler(void); // prototype +void SysTick_Handler(void) { + QK_ISR_ENTRY(); // inform QK about entering an ISR + + QTIMEEVT_TICK_X(0U, &l_SysTick_Handler); // time events at rate 0 + + // Perform the debouncing of buttons. The algorithm for debouncing + // adapted from the book "Embedded Systems Dictionary" by Jack Ganssle + // and Michael Barr, page 71. + static struct { + uint32_t depressed; + uint32_t previous; + } buttons = { 0U, 0U }; + + QF_INT_DISABLE(); + QF_MEM_SYS(); + + uint32_t current = ~GPIOC->IDR; // read Port C with Button B1 + uint32_t tmp = buttons.depressed; // save the depressed buttons + buttons.depressed |= (buttons.previous & current); // set depressed + buttons.depressed &= (buttons.previous | current); // clear released + buttons.previous = current; // update the history + tmp ^= buttons.depressed; // changed debounced depressed + current = buttons.depressed; + +#ifdef Q_SPY + tmp = SysTick->CTRL; // clear CTRL_COUNTFLAG + QS_tickTime_ += QS_tickPeriod_; // account for the clock rollover +#endif + + QF_MEM_APP(); + QF_INT_ENABLE(); + + if ((tmp & (1U << B1_PIN)) != 0U) { // debounced B1 state changed? + if ((current & (1U << B1_PIN)) != 0U) { // is B1 depressed? + static QEvt const pauseEvt = QEVT_INITIALIZER(PAUSE_SIG); + QACTIVE_PUBLISH(&pauseEvt, &l_SysTick_Handler); + } + else { // the button is released + static QEvt const serveEvt = QEVT_INITIALIZER(SERVE_SIG); + QACTIVE_PUBLISH(&serveEvt, &l_SysTick_Handler); + } + } + + QK_ISR_EXIT(); // inform QK about exiting an ISR +} +//............................................................................ +// interrupt handler for testing preemptions in QK +void EXTI0_1_IRQHandler(void); // prototype +void EXTI0_1_IRQHandler(void) { + QK_ISR_ENTRY(); // inform QK about entering an ISR + + // for testing.. + static QEvt const testEvt = QEVT_INITIALIZER(TEST_SIG); + QACTIVE_POST(AO_Table, &testEvt, (void *)0); + + QK_ISR_EXIT(); // inform QK about exiting an ISR +} + +//............................................................................ +#ifdef Q_SPY +// ISR for receiving bytes from the QSPY Back-End +// NOTE: This ISR is "QF-unaware" meaning that it does not interact with +// the QF/QK and is not disabled. Such ISRs don't need to call +// QK_ISR_ENTRY/QK_ISR_EXIT and they cannot post or publish events. + +void USART2_IRQHandler(void); // prototype +void USART2_IRQHandler(void) { // used in QS-RX (kernel UNAWARE interrutp) + // is RX register NOT empty? + QF_MEM_SYS(); + if ((USART2->ISR & (1U << 5)) != 0) { + uint32_t b = USART2->RDR; + QS_RX_PUT(b); + } + + QK_ARM_ERRATUM_838869(); +} +#endif // Q_SPY + +#ifdef QF_MEM_ISOLATE +//............................................................................ +__attribute__(( used )) +void QF_onMemSys(void) { + MPU->CTRL = MPU_CTRL_ENABLE_Msk // enable the MPU + | MPU_CTRL_PRIVDEFENA_Msk; // enable background region + __ISB(); + __DSB(); +} +//............................................................................ +__attribute__(( used )) +void QF_onMemApp() { + MPU->CTRL = MPU_CTRL_ENABLE_Msk; // enable the MPU + // but do NOT enable background region + __ISB(); + __DSB(); +} +//............................................................................ +#ifdef QF_ON_CONTEXT_SW +// NOTE: the context-switch callback is called with interrupts DISABLED +void QF_onContextSw(QActive *prev, QActive *next) { + if (next != (QActive *)0) { + MPU->CTRL = 0U; // disable the MPU + + MPU_Region const * const region = + (MPU_Region const *)(next->thread); + MPU->RBAR = region[0].RBAR; + MPU->RASR = region[0].RASR; + MPU->RBAR = region[1].RBAR; + MPU->RASR = region[1].RASR; + MPU->RBAR = region[2].RBAR; + MPU->RASR = region[2].RASR; + + MPU->CTRL = MPU_CTRL_ENABLE_Msk // enable the MPU + | MPU_CTRL_PRIVDEFENA_Msk; // enable background region + __ISB(); + __DSB(); + } +} +#endif // QF_ON_CONTEXT_SW +#endif // QF_MEM_ISOLATE + +//============================================================================ + +// Stack ..................................................................... +// NOTE +// The main stack size (provided here as power of 2), MUST match the actual +// stack size defined in the linker-script/startup-code. +#define STACK_SIZE_POW2 ((uint32_t)11U) + +// Table AO................................................................... +// size of Table instance, as power-of-2 +#define TABLE_SIZE_POW2 ((uint32_t)6U) + +__attribute__((aligned((1U << TABLE_SIZE_POW2)))) +static uint8_t Table_sto[1U << TABLE_SIZE_POW2]; + +#ifdef QF_MEM_ISOLATE +static MPU_Region const MPU_Table[3] = { + { (uint32_t)Table_sto + 0x10U, //---- region #0 + ((TABLE_SIZE_POW2 - 1U) << MPU_RASR_SIZE_Pos) // size + + (3U << MPU_RASR_AP_Pos) // PA:rw/UA:rw + + (1U << MPU_RASR_XN_Pos) // XN=1 + + (1U << MPU_RASR_S_Pos) // S=1 + + (1U << MPU_RASR_C_Pos) // C=1 + + (0U << MPU_RASR_B_Pos) // B=0 + + (0U << MPU_RASR_TEX_Pos) // TEX=0 + + MPU_RASR_ENABLE_Msk }, // region enable + { GPIOA_BASE + 0x11U, //---- region #1 + ((9U - 1U) << MPU_RASR_SIZE_Pos) // 2^9=512B size + + (3U << MPU_RASR_AP_Pos) // PA:rw/UA:rw + + (1U << MPU_RASR_XN_Pos) // XN=1 + + (1U << MPU_RASR_S_Pos) // S=1 + + (0U << MPU_RASR_C_Pos) // C=0 + + (1U << MPU_RASR_B_Pos) // B=1 + + (0U << MPU_RASR_TEX_Pos) // TEX=0 + + MPU_RASR_ENABLE_Msk }, // region enable + { 0U + 0x12U, //---- region #2 + 0U }, +}; +#endif + +// Philo AOs................................................................ +// size of Philo instance, as power-of-2 +#define PHILO_SIZE_POW2 ((uint32_t)6U) + +__attribute__((aligned((1U << PHILO_SIZE_POW2)))) +static uint8_t Philo_sto[N_PHILO][1U << PHILO_SIZE_POW2]; + +#define PHILO_SHARED_SIZE_POW2 ((uint32_t)5U) +__attribute__((aligned((1U << PHILO_SHARED_SIZE_POW2)))) +static union { + uint32_t rnd_seed; + uint8_t byteso[1U << PHILO_SHARED_SIZE_POW2]; +} Philo_shared_sto; + +#ifdef QF_MEM_ISOLATE +static MPU_Region const MPU_Philo[N_PHILO][3] = { + {{ (uint32_t)Philo_sto[0] + 0x10U, //---- region #0 + ((PHILO_SIZE_POW2 - 1U) << MPU_RASR_SIZE_Pos) // size + + (3U << MPU_RASR_AP_Pos) // PA:rw/UA:rw + + (1U << MPU_RASR_XN_Pos) // XN=1 + + (1U << MPU_RASR_S_Pos) // S=1 + + (1U << MPU_RASR_C_Pos) // C=1 + + (0U << MPU_RASR_B_Pos) // B=0 + + (0U << MPU_RASR_TEX_Pos) // TEX=0 + + MPU_RASR_ENABLE_Msk }, // region enable + { (uint32_t)&Philo_shared_sto + 0x11U, //---- region #1 + ((PHILO_SHARED_SIZE_POW2 - 1U) << MPU_RASR_SIZE_Pos) // size + + (3U << MPU_RASR_AP_Pos) // PA:rw/UA:rw + + (1U << MPU_RASR_XN_Pos) // XN=1 + + (1U << MPU_RASR_S_Pos) // S=1 + + (1U << MPU_RASR_C_Pos) // C=1 + + (0U << MPU_RASR_B_Pos) // B=0 + + (0U << MPU_RASR_TEX_Pos) // TEX=0 + + MPU_RASR_ENABLE_Msk }, // region enable + { 0U + 0x12U, //---- region #2 + 0U }}, + {{ (uint32_t)Philo_sto[1] + 0x10U, //---- region #0 + ((PHILO_SIZE_POW2 - 1U) << MPU_RASR_SIZE_Pos) // size + + (3U << MPU_RASR_AP_Pos) // PA:rw/UA:rw + + (1U << MPU_RASR_XN_Pos) // XN=1 + + (1U << MPU_RASR_S_Pos) // S=1 + + (1U << MPU_RASR_C_Pos) // C=1 + + (0U << MPU_RASR_B_Pos) // B=0 + + (0U << MPU_RASR_TEX_Pos) // TEX=0 + + MPU_RASR_ENABLE_Msk }, // region enable + { (uint32_t)&Philo_shared_sto + 0x11U, //---- region #1 + ((PHILO_SHARED_SIZE_POW2 - 1U) << MPU_RASR_SIZE_Pos) // size + + (3U << MPU_RASR_AP_Pos) // PA:rw/UA:rw + + (1U << MPU_RASR_XN_Pos) // XN=1 + + (1U << MPU_RASR_S_Pos) // S=1 + + (1U << MPU_RASR_C_Pos) // C=1 + + (0U << MPU_RASR_B_Pos) // B=0 + + (0U << MPU_RASR_TEX_Pos) // TEX=0 + + MPU_RASR_ENABLE_Msk }, // region enable + { 0U + 0x12U, //---- region #2 + 0U }}, + {{ (uint32_t)Philo_sto[2] + 0x10U, //---- region #0 + ((PHILO_SIZE_POW2 - 1U) << MPU_RASR_SIZE_Pos) // size + + (3U << MPU_RASR_AP_Pos) // PA:rw/UA:rw + + (1U << MPU_RASR_XN_Pos) // XN=1 + + (1U << MPU_RASR_S_Pos) // S=1 + + (1U << MPU_RASR_C_Pos) // C=1 + + (0U << MPU_RASR_B_Pos) // B=0 + + (0U << MPU_RASR_TEX_Pos) // TEX=0 + + MPU_RASR_ENABLE_Msk }, // region enable + { (uint32_t)&Philo_shared_sto + 0x11U, //---- region #1 + ((PHILO_SHARED_SIZE_POW2 - 1U) << MPU_RASR_SIZE_Pos) // size + + (3U << MPU_RASR_AP_Pos) // PA:rw/UA:rw + + (1U << MPU_RASR_XN_Pos) // XN=1 + + (1U << MPU_RASR_S_Pos) // S=1 + + (1U << MPU_RASR_C_Pos) // C=1 + + (0U << MPU_RASR_B_Pos) // B=0 + + (0U << MPU_RASR_TEX_Pos) // TEX=0 + + MPU_RASR_ENABLE_Msk }, // region enable + { 0U + 0x12U, //---- region #2 + 0U }}, + {{ (uint32_t)Philo_sto[3] + 0x10U, //---- region #0 + ((PHILO_SIZE_POW2 - 1U) << MPU_RASR_SIZE_Pos) // size + + (3U << MPU_RASR_AP_Pos) // PA:rw/UA:rw + + (1U << MPU_RASR_XN_Pos) // XN=1 + + (1U << MPU_RASR_S_Pos) // S=1 + + (1U << MPU_RASR_C_Pos) // C=1 + + (0U << MPU_RASR_B_Pos) // B=0 + + (0U << MPU_RASR_TEX_Pos) // TEX=0 + + MPU_RASR_ENABLE_Msk }, // region enable + { (uint32_t)&Philo_shared_sto + 0x11U, //---- region #1 + ((PHILO_SHARED_SIZE_POW2 - 1U) << MPU_RASR_SIZE_Pos) // size + + (3U << MPU_RASR_AP_Pos) // PA:rw/UA:rw + + (1U << MPU_RASR_XN_Pos) // XN=1 + + (1U << MPU_RASR_S_Pos) // S=1 + + (1U << MPU_RASR_C_Pos) // C=1 + + (0U << MPU_RASR_B_Pos) // B=0 + + (0U << MPU_RASR_TEX_Pos) // TEX=0 + + MPU_RASR_ENABLE_Msk }, // region enable + { 0U + 0x12U, //---- region #2 + 0U }}, + {{ (uint32_t)Philo_sto[4] + 0x10U, //---- region #0 + ((PHILO_SIZE_POW2 - 1U) << MPU_RASR_SIZE_Pos) // size + + (3U << MPU_RASR_AP_Pos) // PA:rw/UA:rw + + (1U << MPU_RASR_XN_Pos) // XN=1 + + (1U << MPU_RASR_S_Pos) // S=1 + + (1U << MPU_RASR_C_Pos) // C=1 + + (0U << MPU_RASR_B_Pos) // B=0 + + (0U << MPU_RASR_TEX_Pos) // TEX=0 + + MPU_RASR_ENABLE_Msk }, // region enable + { (uint32_t)&Philo_shared_sto + 0x11U, //---- region #1 + ((PHILO_SHARED_SIZE_POW2 - 1U) << MPU_RASR_SIZE_Pos) // size + + (3U << MPU_RASR_AP_Pos) // PA:rw/UA:rw + + (1U << MPU_RASR_XN_Pos) // XN=1 + + (1U << MPU_RASR_S_Pos) // S=1 + + (1U << MPU_RASR_C_Pos) // C=1 + + (0U << MPU_RASR_B_Pos) // B=0 + + (0U << MPU_RASR_TEX_Pos) // TEX=0 + + MPU_RASR_ENABLE_Msk }, // region enable + { 0U + 0x12U, //---- region #2 + 0U }}, +}; +#endif + +// Shared Event-pools...................................................... +#define EPOOLS_SIZE_POW2 ((uint32_t)8U) + +__attribute__((aligned((1U << EPOOLS_SIZE_POW2)))) +static struct EPools { + QF_MPOOL_EL(TableEvt) smlPool[2*N_PHILO]; + // ... other pools +} EPools_sto; +Q_ASSERT_STATIC(sizeof(EPools_sto) <= (1U << EPOOLS_SIZE_POW2)); + +//............................................................................ +#ifdef QF_MEM_ISOLATE +static void STM32C031C6_MPU_setup(void) { + + MPU->CTRL = 0U; // disable the MPU + + // region #7: NULL-pointer protection region + MPU->RBAR = 0x00000000U + 0x17U; // base address + region #7 + MPU->RASR = ((8U - 1U) << MPU_RASR_SIZE_Pos) // 2^8=256B size + + (0U << MPU_RASR_AP_Pos) // PA:na/UA:na + + (1U << MPU_RASR_XN_Pos) // XN=1 + + (0U << MPU_RASR_S_Pos) // S=0 + + (0U << MPU_RASR_C_Pos) // C=0 + + (0U << MPU_RASR_B_Pos) // B=0 + + (0U << MPU_RASR_TEX_Pos) // TEX=0 + + MPU_RASR_ENABLE_Msk; // region enable + + // region #6: stack region + MPU->RBAR = 0x20000000U + 0x16U; // base address + region #6 + MPU->RASR = ((STACK_SIZE_POW2 - 1U) << MPU_RASR_SIZE_Pos) // size + + (3U << MPU_RASR_AP_Pos) // PA:rw/UA:rw + + (1U << MPU_RASR_XN_Pos) // XN=1 + + (1U << MPU_RASR_S_Pos) // S=1 + + (1U << MPU_RASR_C_Pos) // C=1 + + (0U << MPU_RASR_B_Pos) // B=0 + + (0U << MPU_RASR_TEX_Pos) // TEX=0 + + MPU_RASR_ENABLE_Msk; // region enable + + // region #5: ROM region for STM32C031C6, whole 32K + MPU->RBAR = 0x08000000U + 0x15U; // base address + region #5 + MPU->RASR = ((15U - 1U) << MPU_RASR_SIZE_Pos) // 2^15=32K size + + (6U << MPU_RASR_AP_Pos) // PA:ro/UA:ro + + (0U << MPU_RASR_XN_Pos) // XN=0 + + (0U << MPU_RASR_S_Pos) // S=0 + + (1U << MPU_RASR_C_Pos) // C=1 + + (0U << MPU_RASR_B_Pos) // B=0 + + (0U << MPU_RASR_TEX_Pos) // TEX=0 + + MPU_RASR_ENABLE_Msk; // region enable + + // region #4: Event-pools region + MPU->RBAR = (uint32_t)&EPools_sto + 0x14U;// base address + region #4 + MPU->RASR = ((EPOOLS_SIZE_POW2 - 1U) << MPU_RASR_SIZE_Pos) // size + + (3U << MPU_RASR_AP_Pos) // PA:rw/UA:rw + + (1U << MPU_RASR_XN_Pos) // XN=1 + + (1U << MPU_RASR_S_Pos) // S=1 + + (1U << MPU_RASR_C_Pos) // C=1 + + (0U << MPU_RASR_B_Pos) // B=0 + + (0U << MPU_RASR_TEX_Pos) // TEX=0 + + MPU_RASR_ENABLE_Msk; // region enable + +#ifdef Q_SPY + // region #3: QS-filters region + MPU->RBAR = (uint32_t)&QS_filt_ + 0x13U;// base address + region #3 + MPU->RASR = ((8U - 1U) << MPU_RASR_SIZE_Pos) // 2^8=256B size + + (3U << MPU_RASR_AP_Pos) // PA:rw/UA:rw + + (1U << MPU_RASR_XN_Pos) // XN=1 + + (1U << MPU_RASR_S_Pos) // S=1 + + (1U << MPU_RASR_C_Pos) // C=1 + + (0U << MPU_RASR_B_Pos) // B=0 + + (0U << MPU_RASR_TEX_Pos) // TEX=0 + + MPU_RASR_ENABLE_Msk; // region enable +#endif + + // region #0: temporary 4G region for initial transient + MPU->RBAR = 0x00000000U + 0x10U; // base address + region #0 + MPU->RASR = ((32U - 1U) << MPU_RASR_SIZE_Pos) // 2^32=4G size + + (3U << MPU_RASR_AP_Pos) // PA:rw/UA:rw + + (0U << MPU_RASR_XN_Pos) // XN=0 + + (1U << MPU_RASR_S_Pos) // S=1 + + (1U << MPU_RASR_C_Pos) // C=1 + + (0U << MPU_RASR_B_Pos) // B=0 + + (0U << MPU_RASR_TEX_Pos) // TEX=0 + + MPU_RASR_ENABLE_Msk; // region enable + + MPU->CTRL = MPU_CTRL_ENABLE_Msk; // enable the MPU + // but do NOT enable background region + __ISB(); + __DSB(); +} +#endif + +//============================================================================ + +// "opaque" pointer to AO +QActive * const AO_Table = (QActive *)Table_sto; + +QActive * const AO_Philo[N_PHILO] = { + (QActive *)Philo_sto[0], // "opaque" pointer + (QActive *)Philo_sto[1], // "opaque" pointer + (QActive *)Philo_sto[2], // "opaque" pointer + (QActive *)Philo_sto[3], // "opaque" pointer + (QActive *)Philo_sto[4] // "opaque" pointer +}; + +// BSP functions =========================================================== +void BSP_init(void) { +#ifdef QF_MEM_ISOLATE + // setup the MPU + STM32C031C6_MPU_setup(); +#endif + + // NOTE: SystemInit() has been already called from the startup code + // but SystemCoreClock needs to be updated + SystemCoreClockUpdate(); + + // enable GPIOA clock port for the LED LD4 + RCC->IOPENR |= (1U << 0U); + + // set all used GPIOA pins as push-pull output, no pull-up, pull-down + GPIOA->MODER &= ~(3U << 2U*LD4_PIN); + GPIOA->MODER |= (1U << 2U*LD4_PIN); + GPIOA->OTYPER &= ~(1U << LD4_PIN); + GPIOA->OSPEEDR &= ~(3U << 2U*LD4_PIN); + GPIOA->OSPEEDR |= (1U << 2U*LD4_PIN); + GPIOA->PUPDR &= ~(3U << 2U*LD4_PIN); + + // enable GPIOC clock port for the Button B1 + RCC->IOPENR |= (1U << 2U); + + // configure Button B1 pin on GPIOC as input, no pull-up, pull-down + GPIOC->MODER &= ~(3U << 2U*B1_PIN); + GPIOC->PUPDR &= ~(3U << 2U*B1_PIN); + + BSP_randomSeed(1234U); // seed the random number generator + + // initialize the QS software tracing... + if (!QS_INIT((void *)0)) { + Q_ERROR(); + } + + // dictionaries... + QS_OBJ_DICTIONARY(&l_SysTick_Handler); + QS_USR_DICTIONARY(PHILO_STAT); + QS_USR_DICTIONARY(PAUSED_STAT); + + QS_ONLY(produce_sig_dict()); + + // setup the QS filters... + QS_GLB_FILTER(QS_ALL_RECORDS); // all records + QS_GLB_FILTER(-QS_QF_TICK); // exclude the clock tick +} +//............................................................................ +void BSP_start(void) { + // initialize event pools + QF_poolInit(EPools_sto.smlPool, + sizeof(EPools_sto.smlPool), + sizeof(EPools_sto.smlPool[0])); + + // initialize publish-subscribe + static QSubscrList subscrSto[MAX_PUB_SIG]; + QActive_psInit(subscrSto, Q_DIM(subscrSto)); + + // instantiate and start AOs/threads... + static QEvt const *philoQueueSto[N_PHILO][10]; + for (uint8_t n = 0U; n < N_PHILO; ++n) { +#ifdef QF_MEM_ISOLATE + Philo_ctor(n, Philo_sto[n], sizeof(Philo_sto[n]), MPU_Philo[n]); +#else + Philo_ctor(n, Philo_sto[n], sizeof(Philo_sto[n]), (void *)0); +#endif + QACTIVE_START(AO_Philo[n], + + // NOTE: set the preemption-threshold of all Philos to + // the same level, so that they cannot preempt each other. + Q_PRIO(n + 3U, N_PHILO + 2U), // QF-prio/pre-thre. + + philoQueueSto[n], // event queue storage + Q_DIM(philoQueueSto[n]), // queue length [events] + (void *)0, 0U, // no stack storage + (void *)0); // no initialization param + } + + static QEvt const *tableQueueSto[N_PHILO]; +#ifdef QF_MEM_ISOLATE + Table_ctor(Table_sto, sizeof(Table_sto), MPU_Table); +#else + Table_ctor(Table_sto, sizeof(Table_sto), (void *)0); +#endif + QACTIVE_START(AO_Table, + N_PHILO + 7U, // QP prio. of the AO + tableQueueSto, // event queue storage + Q_DIM(tableQueueSto), // queue length [events] + (void *)0, 0U, // no stack storage + (void *)0); // no initialization param +} +//............................................................................ +void BSP_displayPhilStat(uint8_t n, char const *stat) { + Q_UNUSED_PAR(n); + + if (stat[0] == 'h') { + GPIOA->BSRR = (1U << LD4_PIN); // turn LED on + } + else { + GPIOA->BSRR = (1U << (LD4_PIN + 16U)); // turn LED off + } + + // app-specific trace record... + QS_BEGIN_ID(PHILO_STAT, AO_Table->prio) + QS_U8(1, n); // Philosopher number + QS_STR(stat); // Philosopher status + QS_END() +} +//............................................................................ +void BSP_displayPaused(uint8_t const paused) { + // not enough LEDs to implement this feature + if (paused != 0U) { + //GPIOA->BSRR = (1U << LD4_PIN); // turn LED[n] on + } + else { + //GPIOA->BSRR = (1U << (LD4_PIN + 16U)); // turn LED[n] off + } + + // application-specific trace record + QS_BEGIN_ID(PAUSED_STAT, AO_Table->prio) + QS_U8(1, paused); // Paused status + QS_END() +} +//............................................................................ +void BSP_randomSeed(uint32_t seed) { + Philo_shared_sto.rnd_seed = seed; +} +//............................................................................ +uint32_t BSP_random() { // a very cheap pseudo-random-number generator + + QSchedStatus lockStat = QK_schedLock(N_PHILO); + // "Super-Duper" Linear Congruential Generator (LCG) + // LCG(2^32, 3*7*11*13*23, 0, seed) + // + uint32_t rnd = Philo_shared_sto.rnd_seed * (3U*7U*11U*13U*23U); + Philo_shared_sto.rnd_seed = rnd; // set for the next time + QK_schedUnlock(lockStat); + + return (rnd >> 8U); +} +//............................................................................ +void BSP_ledOn() { + GPIOA->BSRR = (1U << LD4_PIN); // turn LED on +} +//............................................................................ +void BSP_ledOff() { + GPIOA->BSRR = (1U << (LD4_PIN + 16U)); // turn LED off +} +//............................................................................ +void BSP_terminate(int16_t result) { + Q_UNUSED_PAR(result); +} + +//============================================================================ +// QF callbacks... +void QF_onStartup(void) { + // set up the SysTick timer to fire at BSP_TICKS_PER_SEC rate + SysTick_Config(SystemCoreClock / BSP_TICKS_PER_SEC); + + // assign all priority bits for preemption-prio. and none to sub-prio. + NVIC_SetPriorityGrouping(0U); + + // set priorities of ALL ISRs used in the system, see NOTE1 + NVIC_SetPriority(USART2_IRQn, 0); // kernel UNAWARE interrupt + NVIC_SetPriority(EXTI0_1_IRQn, QF_AWARE_ISR_CMSIS_PRI + 0U); + NVIC_SetPriority(SysTick_IRQn, QF_AWARE_ISR_CMSIS_PRI + 1U); + // ... + + // enable IRQs... + NVIC_EnableIRQ(EXTI0_1_IRQn); + +#ifdef Q_SPY + NVIC_EnableIRQ(USART2_IRQn); // UART2 interrupt used for QS-RX +#endif +} +//............................................................................ +void QF_onCleanup(void) { +} +//............................................................................ +void QK_onIdle(void) { + // toggle an LED on and then off (not enough LEDs, see NOTE02) + //QF_INT_DISABLE(); + //QF_MEM_SYS(); + //GPIOA->BSRR = (1U << LD4_PIN); // turn LED[n] on + //GPIOA->BSRR = (1U << (LD4_PIN + 16U)); // turn LED[n] off + //QF_MEM_APP(); + //QF_INT_ENABLE(); + +#ifdef Q_SPY + QF_INT_DISABLE(); + QF_MEM_SYS(); + QS_rxParse(); // parse all the received bytes + QF_MEM_APP(); + QF_INT_ENABLE(); + QF_CRIT_EXIT_NOP(); + + QF_INT_DISABLE(); + QF_MEM_SYS(); + if ((USART2->ISR & (1U << 7U)) != 0U) { // is TXE empty? + uint16_t b = QS_getByte(); + if (b != QS_EOD) { // not End-Of-Data? + USART2->TDR = b; // put into the DR register + } + } + QF_MEM_APP(); + QF_INT_ENABLE(); +#elif defined NDEBUG + // Put the CPU and peripherals to the low-power mode. + // you might need to customize the clock management for your application, + // see the datasheet for your particular Cortex-M MCU. + // + // !!!CAUTION!!! + // The WFI instruction stops the CPU clock, which unfortunately disables + // the JTAG port, so the ST-Link debugger can no longer connect to the + // board. For that reason, the call to __WFI() has to be used with CAUTION. + // + // NOTE: If you find your board "frozen" like this, strap BOOT0 to VDD and + // reset the board, then connect with ST-Link Utilities and erase the part. + // The trick with BOOT(0) is it gets the part to run the System Loader + // instead of your broken code. When done disconnect BOOT0, and start over. + // + //__WFI(); // Wait-For-Interrupt +#endif +} + +//============================================================================ +// QS callbacks... +#ifdef Q_SPY + +#ifdef QF_MEM_ISOLATE +// Shared QS filters... +__attribute__((aligned(32))) +QS_Filter QS_filt_; +#endif + +//............................................................................ +static uint16_t const UARTPrescTable[12] = { + 1U, 2U, 4U, 6U, 8U, 10U, 12U, 16U, 32U, 64U, 128U, 256U +}; + +#define UART_DIV_SAMPLING16(__PCLK__, __BAUD__, __CLOCKPRESCALER__) \ + ((((__PCLK__)/UARTPrescTable[(__CLOCKPRESCALER__)]) \ + + ((__BAUD__)/2U)) / (__BAUD__)) + +#define UART_PRESCALER_DIV1 0U + +// USART2 pins PA.2 and PA.3 +#define USART2_TX_PIN 2U +#define USART2_RX_PIN 3U + +//............................................................................ +uint8_t QS_onStartup(void const *arg) { + Q_UNUSED_PAR(arg); + + static uint8_t qsTxBuf[2*1024]; // buffer for QS-TX channel + QS_initBuf(qsTxBuf, sizeof(qsTxBuf)); + + static uint8_t qsRxBuf[100]; // buffer for QS-RX channel + QS_rxInitBuf(qsRxBuf, sizeof(qsRxBuf)); + + // enable peripheral clock for USART2 + RCC->IOPENR |= ( 1U << 0U); // Enable GPIOA clock for USART pins + RCC->APBENR1 |= ( 1U << 17U); // Enable USART#2 clock + + // Configure PA to USART2_RX, PA to USART2_TX + GPIOA->AFR[0] &= ~((15U << 4U*USART2_RX_PIN) | (15U << 4U*USART2_TX_PIN)); + GPIOA->AFR[0] |= (( 1U << 4U*USART2_RX_PIN) | ( 1U << 4U*USART2_TX_PIN)); + GPIOA->MODER &= ~(( 3U << 2U*USART2_RX_PIN) | ( 3U << 2U*USART2_TX_PIN)); + GPIOA->MODER |= (( 2U << 2U*USART2_RX_PIN) | ( 2U << 2U*USART2_TX_PIN)); + + // baud rate + USART2->BRR = UART_DIV_SAMPLING16( + SystemCoreClock, 115200U, UART_PRESCALER_DIV1); + USART2->CR3 = 0x0000U | // no flow control + (1U << 12U); // disable overrun detection (OVRDIS) + USART2->CR2 = 0x0000U; // 1 stop bit + USART2->CR1 = ((1U << 2U) | // enable RX + (1U << 3U) | // enable TX + (1U << 5U) | // enable RX interrupt + (0U << 12U) | // 8 data bits + (0U << 28U) | // 8 data bits + (1U << 0U)); // enable USART + + QS_tickPeriod_ = SystemCoreClock / BSP_TICKS_PER_SEC; + QS_tickTime_ = QS_tickPeriod_; // to start the timestamp at zero + + return 1U; // return success +} +//............................................................................ +void QS_onCleanup(void) { +} +//............................................................................ +QSTimeCtr QS_onGetTime(void) { // NOTE: invoked with interrupts DISABLED + if ((SysTick->CTRL & 0x00010000) == 0) { // COUNT no set? + return QS_tickTime_ - (QSTimeCtr)SysTick->VAL; + } + else { // the rollover occured, but the SysTick_ISR did not run yet + return QS_tickTime_ + QS_tickPeriod_ - (QSTimeCtr)SysTick->VAL; + } +} +//............................................................................ +void QS_onFlush(void) { + for (;;) { + QF_INT_DISABLE(); + QF_MEM_SYS(); + uint16_t b = QS_getByte(); + if (b != QS_EOD) { + while ((USART2->ISR & (1U << 7U)) == 0U) { // while TXE not empty + QF_MEM_APP(); + QF_INT_ENABLE(); + QF_CRIT_EXIT_NOP(); + + QF_INT_DISABLE(); + QF_MEM_SYS(); + } + USART2->TDR = b; // put into the DR register + QF_MEM_APP(); + QF_INT_ENABLE(); + } + else { + QF_MEM_APP(); + QF_INT_ENABLE(); + break; + } + } +} +//............................................................................ +//! callback function to reset the target (to be implemented in the BSP) +void QS_onReset(void) { + NVIC_SystemReset(); +} +//............................................................................ +//! callback function to execute a user command +void QS_onCommand(uint8_t cmdId, + uint32_t param1, uint32_t param2, uint32_t param3) +{ + Q_UNUSED_PAR(cmdId); + Q_UNUSED_PAR(param1); + Q_UNUSED_PAR(param2); + Q_UNUSED_PAR(param3); +} + +#endif // Q_SPY +//---------------------------------------------------------------------------- + +//============================================================================ +// NOTE1: +// The QF_AWARE_ISR_CMSIS_PRI constant from the QF port specifies the highest +// ISR priority that is disabled by the QF framework. The value is suitable +// for the NVIC_SetPriority() CMSIS function. +// +// Only ISRs prioritized at or below the QF_AWARE_ISR_CMSIS_PRI level (i.e., +// with the numerical values of priorities equal or higher than +// QF_AWARE_ISR_CMSIS_PRI) are allowed to call the QK_ISR_ENTRY/ +// QK_ISR_ENTRY macros or any other QF/QK services. These ISRs are +// "QF-aware". +// +// Conversely, any ISRs prioritized above the QF_AWARE_ISR_CMSIS_PRI priority +// level (i.e., with the numerical values of priorities less than +// QF_AWARE_ISR_CMSIS_PRI) are never disabled and are not aware of the kernel. +// Such "QF-unaware" ISRs cannot call ANY QF/QK services. In particular they +// can NOT call the macros QK_ISR_ENTRY/QK_ISR_ENTRY. The only mechanism +// by which a "QF-unaware" ISR can communicate with the QF framework is by +// triggering a "QF-aware" ISR, which can post/publish events. +// +// NOTE2: +// The User LED is used to visualize the idle loop activity. The brightness +// of the LED is proportional to the frequency of the idle loop. +// Please note that the LED is toggled with interrupts locked, so no interrupt +// execution time contributes to the brightness of the User LED. +// diff --git a/examples/arm-cm/blinky_efm32-slstk3401a/qk/gnu/Makefile b/examples/arm-cm/dpp_nucleo-c031c6_mpu/qk/gnu/Makefile similarity index 87% rename from examples/arm-cm/blinky_efm32-slstk3401a/qk/gnu/Makefile rename to examples/arm-cm/dpp_nucleo-c031c6_mpu/qk/gnu/Makefile index f708ac68..445065e7 100644 --- a/examples/arm-cm/blinky_efm32-slstk3401a/qk/gnu/Makefile +++ b/examples/arm-cm/dpp_nucleo-c031c6_mpu/qk/gnu/Makefile @@ -1,13 +1,13 @@ ############################################################################## -# Product: Makefile for QP/C on EMF32-SLSTK3401A, QK kernel, GNU-ARM -# Last Updated for Version: 7.0.1 -# Date of the Last Update: 2022-05-23 +# Product: Makefile for QP/C on NUCLEO-C031C6, QK kernel, GNU-ARM +# Last Updated for Version: 7.3.0 +# Date of the Last Update: 2023-09-07 # # Q u a n t u m L e a P s # ------------------------ # Modern Embedded Software # -# Copyright (C) 2005-2021 Quantum Leaps, LLC. All rights reserved. +# Copyright (C) 2005 Quantum Leaps, LLC. # # This program is open source software: you can redistribute it and/or # modify it under the terms of the GNU General Public License as published @@ -45,13 +45,12 @@ # NOTE: # To use this Makefile on Windows, you will need the GNU make utility, which # is included in the Qtools collection for Windows, see: -# https://sourceforge.net/projects/qpc/files/QTools/ -# +# https://github.com/QuantumLeaps/qtools #----------------------------------------------------------------------------- # project name # -PROJECT := blinky-qk +PROJECT := dpp-qk #----------------------------------------------------------------------------- # project directories @@ -73,8 +72,8 @@ VPATH = \ $(QPC)/src/qk \ $(QPC)/src/qs \ $(QP_PORT_DIR) \ - $(QPC)/3rd_party/efm32pg1b \ - $(QPC)/3rd_party/efm32pg1b/gnu + $(QPC)/3rd_party/nucleo-c031c6 \ + $(QPC)/3rd_party/nucleo-c031c6/gnu # list of all include directories needed by this project INCLUDES = \ @@ -82,7 +81,7 @@ INCLUDES = \ -I$(QPC)/include \ -I$(QP_PORT_DIR) \ -I$(QPC)/3rd_party/CMSIS/Include \ - -I$(QPC)/3rd_party/efm32pg1b + -I$(QPC)/3rd_party/nucleo-c031c6 #----------------------------------------------------------------------------- # files @@ -93,14 +92,12 @@ ASM_SRCS := # C source files C_SRCS := \ - blinky.c \ bsp.c \ main.c \ - startup_efm32pg1b.c \ - system_efm32pg1b.c \ - em_cmu.c \ - em_emu.c \ - em_gpio.c + philo.c \ + table.c \ + system_stm32c0xx.c \ + startup_stm32c031xx.c # C++ source files CPP_SRCS := @@ -135,16 +132,18 @@ LIB_DIRS := LIBS := # defines -DEFINES := -DEFM32PG1B200F256GM48=1 +DEFINES := \ + -DQP_CONFIG \ + -DSTM32C031xx # ARM CPU, ARCH, FPU, and Float-ABI types... # ARM_CPU: [cortex-m0 | cortex-m0plus | cortex-m1 | cortex-m3 | cortex-m4] # ARM_FPU: [ | vfp] # FLOAT_ABI: [ | soft | softfp | hard] # -ARM_CPU := -mcpu=cortex-m4 -ARM_FPU := -mfpu=vfp -FLOAT_ABI := -mfloat-abi=softfp +ARM_CPU := -mcpu=cortex-m0plus +ARM_FPU := +FLOAT_ABI := #----------------------------------------------------------------------------- # GNU-ARM toolset (NOTE: You need to adjust to your machine) @@ -165,18 +164,17 @@ AS := $(GNU_ARM)/bin/arm-none-eabi-as LINK := $(GNU_ARM)/bin/arm-none-eabi-gcc BIN := $(GNU_ARM)/bin/arm-none-eabi-objcopy - ############################################################################## -# Typically, you should not need to change anything below this line +# Typically you should not need to change anything below this line -# basic utilities (included in Qtools for Windows), see: -# http://sourceforge.net/projects/qpc/files/Qtools +# basic utilities (included in QTools for Windows), see: +# https://www.state-machine.com/qtools MKDIR := mkdir RM := rm #----------------------------------------------------------------------------- -# build options for various configurations for ARM Cortex-M4F +# build options for various configurations for ARM Cortex-M # # combine all the soruces... @@ -191,11 +189,11 @@ ASFLAGS = $(ARM_CPU) $(ARM_FPU) $(ASM_CPU) $(ASM_FPU) CFLAGS = -c $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \ -ffunction-sections -fdata-sections \ - -O1 $(INCLUDES) $(DEFINES) -DNDEBUG + -O2 $(INCLUDES) $(DEFINES) -DNDEBUG CPPFLAGS = -c $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \ -ffunction-sections -fdata-sections -fno-rtti -fno-exceptions \ - -O1 $(INCLUDES) $(DEFINES) -DNDEBUG + -O2 $(INCLUDES) $(DEFINES) -DNDEBUG else ifeq (spy, $(CONF)) # Spy configuration ................................ @@ -256,14 +254,20 @@ endif # rules # -all: $(TARGET_BIN) -#all: $(TARGET_ELF) +.PHONY : run norun flash clean show + +ifeq ($(MAKECMDGOALS),norun) +all : $(TARGET_BIN) +norun : all +else +all : $(TARGET_BIN) run +endif $(TARGET_BIN): $(TARGET_ELF) $(BIN) -O binary $< $@ $(TARGET_ELF) : $(ASM_OBJS_EXT) $(C_OBJS_EXT) $(CPP_OBJS_EXT) - $(CC) $(CFLAGS) $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o + $(CC) $(CFLAGS) $(QPC)/src/qs/qstamp.c -o $(BIN_DIR)/qstamp.o $(LINK) $(LINKFLAGS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) $(BIN_DIR)/%.d : %.c @@ -289,7 +293,6 @@ ifneq ($(MAKECMDGOALS),clean) endif -.PHONY : clean clean: -$(RM) $(BIN_DIR)/*.o \ $(BIN_DIR)/*.d \ diff --git a/examples/arm-cm/dpp_nucleo-c031c6_mpu/qk/gnu/dpp-qk.ld b/examples/arm-cm/dpp_nucleo-c031c6_mpu/qk/gnu/dpp-qk.ld new file mode 100644 index 00000000..4a3ba851 --- /dev/null +++ b/examples/arm-cm/dpp_nucleo-c031c6_mpu/qk/gnu/dpp-qk.ld @@ -0,0 +1,135 @@ +/***************************************************************************** +* Linker script for for STM32C031C6, GNU-ARM linker +* +* Q u a n t u m L e a P s +* ------------------------ +* Modern Embedded Software +* +* Copyright (C) 2005 Quantum Leaps, LLC . +* +* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +* +* This software is dual-licensed under the terms of the open source GNU +* General Public License version 3 (or any later version), or alternatively, +* under the terms of one of the closed source Quantum Leaps commercial +* licenses. +* +* The terms of the open source GNU General Public License version 3 +* can be found at: +* +* The terms of the closed source Quantum Leaps commercial licenses +* can be found at: +* +* Redistributions in source code must retain this top-level comment block. +* Plagiarizing this software to sidestep the license obligations is illegal. +* +* Contact information: +* +* +*****************************************************************************/ +OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm", "elf32-littlearm") +OUTPUT_ARCH(arm) +ENTRY(Reset_Handler) /* entry Point */ + +MEMORY { /* memory map of STM32C031C6 */ + ROM (rx) : ORIGIN = 0x08000000, LENGTH = 32K + RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 12K +} + +/* The size of the stack used by the application. NOTE: you need to adjust */ +STACK_SIZE = 2048; + +/* The size of the heap used by the application. NOTE: you need to adjust */ +HEAP_SIZE = 0; + +SECTIONS { + + .isr_vector : { /* the vector table goes FIRST into ROM */ + KEEP(*(.isr_vector)) /* vector table */ + . = ALIGN(4); + } >ROM + + .text : { /* code and constants */ + . = ALIGN(4); + *(.text) /* .text sections (code) */ + *(.text*) /* .text* sections (code) */ + *(.rodata) /* .rodata sections (constants, strings, etc.) */ + *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ + + KEEP (*(.init)) + KEEP (*(.fini)) + + . = ALIGN(4); + } >ROM + + .preinit_array : { + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array*)) + PROVIDE_HIDDEN (__preinit_array_end = .); + } >ROM + + .init_array : { + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array*)) + PROVIDE_HIDDEN (__init_array_end = .); + } >ROM + + .fini_array : { + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(.fini_array*)) + KEEP (*(SORT(.fini_array.*))) + PROVIDE_HIDDEN (__fini_array_end = .); + } >ROM + + _etext = .; /* global symbols at end of code */ + + .stack : { + __stack_start__ = .; + . = . + STACK_SIZE; + . = ALIGN(4); + __stack_end__ = .; + } >RAM + + .data : AT (_etext) { + __data_load = LOADADDR (.data); + __data_start = .; + *(.data) /* .data sections */ + *(.data*) /* .data* sections */ + . = ALIGN(4); + __data_end__ = .; + _edata = __data_end__; + } >RAM + + .bss : { + __bss_start__ = .; + *(.bss) + *(.bss*) + *(COMMON) + . = ALIGN(4); + _ebss = .; /* define a global symbol at bss end */ + __bss_end__ = .; + } >RAM + + __exidx_start = .; + .ARM.exidx : { *(.ARM.exidx* .gnu.linkonce.armexidx.*) } >RAM + __exidx_end = .; + + PROVIDE ( end = _ebss ); + PROVIDE ( _end = _ebss ); + PROVIDE ( __end__ = _ebss ); + + .heap : { + __heap_start__ = .; + . = . + HEAP_SIZE; + . = ALIGN(4); + __heap_end__ = .; + } >RAM + + /* Remove information from the standard libraries */ + /DISCARD/ : { + libc.a ( * ) + libm.a ( * ) + libgcc.a ( * ) + } +} diff --git a/examples/arm-cm/dpp_nucleo-c031c6_mpu/qk/iar/dpp-qk.ewd b/examples/arm-cm/dpp_nucleo-c031c6_mpu/qk/iar/dpp-qk.ewd new file mode 100644 index 00000000..b3712b65 --- /dev/null +++ b/examples/arm-cm/dpp_nucleo-c031c6_mpu/qk/iar/dpp-qk.ewd @@ -0,0 +1,4654 @@ + + + 3 + + Debug + + ARM + + 1 + + C-SPY + 2 + + 32 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ARMSIM_ID + 2 + + 1 + 1 + 1 + + + + + + + + CADI_ID + 2 + + 0 + 1 + 1 + + + + + + + + + CMSISDAP_ID + 2 + + 4 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + GDBSERVER_ID + 2 + + 0 + 1 + 1 + + + + + + + + + + + IJET_ID + 2 + + 9 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + JLINK_ID + 2 + + 16 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + LMIFTDI_ID + 2 + + 3 + 1 + 1 + + + + + + + + + + + + + NULINK_ID + 2 + + 0 + 1 + 1 + + + + + + + PEMICRO_ID + 2 + + 3 + 1 + 1 + + + + + + + + STLINK_ID + 2 + + 8 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + THIRDPARTY_ID + 2 + + 0 + 1 + 1 + + + + + + + + TIFET_ID + 2 + + 1 + 1 + 1 + + + + + + + + + + + + + + + + + + + XDS100_ID + 2 + + 9 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + $TOOLKIT_DIR$\plugins\rtos\CMX\CmxArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\CMX\CmxTinyArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\FreeRtos\FreeRtosArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin2.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SafeRTOS\SafeRTOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9BE.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-286-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-III\uCOS-III-KA-CSpy.ewplugin + 0 + + + $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\TargetAccessServer\TargetAccessServer.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\uCProbe\uCProbePlugin.ENU.ewplugin + 0 + + + + + Release + + ARM + + 0 + + C-SPY + 2 + + 32 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ARMSIM_ID + 2 + + 1 + 1 + 0 + + + + + + + + CADI_ID + 2 + + 0 + 1 + 0 + + + + + + + + + CMSISDAP_ID + 2 + + 4 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + GDBSERVER_ID + 2 + + 0 + 1 + 0 + + + + + + + + + + + IJET_ID + 2 + + 9 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + JLINK_ID + 2 + + 16 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + LMIFTDI_ID + 2 + + 3 + 1 + 0 + + + + + + + + + + + + + NULINK_ID + 2 + + 0 + 1 + 0 + + + + + + + PEMICRO_ID + 2 + + 3 + 1 + 0 + + + + + + + + STLINK_ID + 2 + + 8 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + THIRDPARTY_ID + 2 + + 0 + 1 + 0 + + + + + + + + TIFET_ID + 2 + + 1 + 1 + 0 + + + + + + + + + + + + + + + + + + + XDS100_ID + 2 + + 9 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + $TOOLKIT_DIR$\plugins\rtos\CMX\CmxArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\CMX\CmxTinyArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\FreeRtos\FreeRtosArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin2.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SafeRTOS\SafeRTOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9BE.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-286-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-III\uCOS-III-KA-CSpy.ewplugin + 0 + + + $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\TargetAccessServer\TargetAccessServer.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\uCProbe\uCProbePlugin.ENU.ewplugin + 0 + + + + + Spy + + ARM + + 1 + + C-SPY + 2 + + 32 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ARMSIM_ID + 2 + + 1 + 1 + 1 + + + + + + + + CADI_ID + 2 + + 0 + 1 + 1 + + + + + + + + + CMSISDAP_ID + 2 + + 4 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + GDBSERVER_ID + 2 + + 0 + 1 + 1 + + + + + + + + + + + IJET_ID + 2 + + 9 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + JLINK_ID + 2 + + 16 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + LMIFTDI_ID + 2 + + 3 + 1 + 1 + + + + + + + + + + + + + NULINK_ID + 2 + + 0 + 1 + 1 + + + + + + + PEMICRO_ID + 2 + + 3 + 1 + 1 + + + + + + + + STLINK_ID + 2 + + 8 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + THIRDPARTY_ID + 2 + + 0 + 1 + 1 + + + + + + + + TIFET_ID + 2 + + 1 + 1 + 1 + + + + + + + + + + + + + + + + + + + XDS100_ID + 2 + + 9 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + $TOOLKIT_DIR$\plugins\rtos\CMX\CmxArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\CMX\CmxTinyArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\FreeRtos\FreeRtosArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin2.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SafeRTOS\SafeRTOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9BE.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-286-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-III\uCOS-III-KA-CSpy.ewplugin + 0 + + + $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\TargetAccessServer\TargetAccessServer.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\uCProbe\uCProbePlugin.ENU.ewplugin + 0 + + + + diff --git a/examples/arm-cm/dpp_nucleo-c031c6_mpu/qk/iar/dpp-qk.ewp b/examples/arm-cm/dpp_nucleo-c031c6_mpu/qk/iar/dpp-qk.ewp new file mode 100644 index 00000000..b96faf97 --- /dev/null +++ b/examples/arm-cm/dpp_nucleo-c031c6_mpu/qk/iar/dpp-qk.ewp @@ -0,0 +1,3367 @@ + + + 3 + + Debug + + ARM + + 1 + + General + 3 + + 35 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ICCARM + 2 + + 37 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + AARM + 2 + + 11 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + OBJCOPY + 0 + + 1 + 1 + 1 + + + + + + + + + CUSTOM + 3 + + + + 0 + inputOutputBased + + + + BUILDACTION + 1 + + cmd /c "if exist $OBJ_DIR$\qstamp.o del $OBJ_DIR$\qstamp.o" + + + + + ILINK + 0 + + 27 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + IARCHIVE + 0 + + 0 + 1 + 1 + + + + + + + Coder + 0 + + + + + Release + + ARM + + 0 + + General + 3 + + 35 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ICCARM + 2 + + 37 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + AARM + 2 + + 11 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + OBJCOPY + 0 + + 1 + 1 + 0 + + + + + + + + + CUSTOM + 3 + + + + 0 + inputOutputBased + + + + BUILDACTION + 1 + + cmd /c "if exist $OBJ_DIR$\qstamp.o del $OBJ_DIR$\qstamp.o" + + + + + ILINK + 0 + + 27 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + IARCHIVE + 0 + + 0 + 1 + 0 + + + + + + + Coder + 0 + + + + + Spy + + ARM + + 1 + + General + 3 + + 35 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ICCARM + 2 + + 37 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + AARM + 2 + + 11 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + OBJCOPY + 0 + + 1 + 1 + 1 + + + + + + + + + CUSTOM + 3 + + + + 0 + inputOutputBased + + + + BUILDACTION + 1 + + cmd /c "if exist $OBJ_DIR$\qstamp.o del $OBJ_DIR$\qstamp.o" + + + + + ILINK + 0 + + 27 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + IARCHIVE + 0 + + 0 + 1 + 1 + + + + + + + Coder + 0 + + + + + Release + + + Application + + $PROJ_DIR$\..\bsp.c + + + $PROJ_DIR$\..\..\bsp.h + + + $PROJ_DIR$\..\..\dpp.h + + + $PROJ_DIR$\..\..\main.c + + + $PROJ_DIR$\..\..\philo.c + + + $PROJ_DIR$\..\..\table.c + + + + nucleo-c031c6 + + $PROJ_DIR$\..\..\..\..\..\3rd_party\nucleo-c031c6\iar\startup_stm32c031xx.s + + + $PROJ_DIR$\..\..\..\..\..\3rd_party\nucleo-c031c6\stm32c031xx.h + + + $PROJ_DIR$\..\..\..\..\..\3rd_party\nucleo-c031c6\stm32c0xx.h + + + $PROJ_DIR$\..\..\..\..\..\3rd_party\nucleo-c031c6\system_stm32c0xx.c + + + + QP + + $PROJ_DIR$\..\..\..\..\..\src\qf\qep_hsm.c + + + $PROJ_DIR$\..\..\..\..\..\src\qf\qep_msm.c + + + $PROJ_DIR$\..\..\..\..\..\src\qf\qf_act.c + + + $PROJ_DIR$\..\..\..\..\..\src\qf\qf_actq.c + + + $PROJ_DIR$\..\..\..\..\..\src\qf\qf_defer.c + + + $PROJ_DIR$\..\..\..\..\..\src\qf\qf_dyn.c + + + $PROJ_DIR$\..\..\..\..\..\src\qf\qf_mem.c + + + $PROJ_DIR$\..\..\..\..\..\src\qf_pkg.h + + + $PROJ_DIR$\..\..\..\..\..\src\qf\qf_ps.c + + + $PROJ_DIR$\..\..\..\..\..\src\qf\qf_qact.c + + + $PROJ_DIR$\..\..\..\..\..\src\qf\qf_qeq.c + + + $PROJ_DIR$\..\..\..\..\..\src\qf\qf_qmact.c + + + $PROJ_DIR$\..\..\..\..\..\src\qf\qf_time.c + + + $PROJ_DIR$\..\..\..\..\..\src\qk\qk.c + + + + QP_port + + $PROJ_DIR$\..\..\..\..\..\ports\arm-cm\qk\iar\qep_port.h + + + $PROJ_DIR$\..\..\..\..\..\ports\arm-cm\qk\iar\qf_port.h + + + $PROJ_DIR$\..\..\..\..\..\ports\arm-cm\qk\iar\qk_port.c + + + $PROJ_DIR$\..\..\..\..\..\ports\arm-cm\qk\iar\qk_port.h + + + $PROJ_DIR$\..\..\..\..\..\ports\arm-cm\qk\iar\qs_port.h + + + + QS + + Debug + Release + + + $PROJ_DIR$\..\..\..\..\..\src\qs\qs.c + + + $PROJ_DIR$\..\..\..\..\..\src\qs\qs_fp.c + + + $PROJ_DIR$\..\..\..\..\..\src\qs\qs_rx.c + + + $PROJ_DIR$\..\..\..\..\..\src\qs\qstamp.c + + + diff --git a/examples/arm-cm/dpp_nucleo-c031c6_mpu/qk/iar/dpp-qk.eww b/examples/arm-cm/dpp_nucleo-c031c6_mpu/qk/iar/dpp-qk.eww new file mode 100644 index 00000000..c261124a --- /dev/null +++ b/examples/arm-cm/dpp_nucleo-c031c6_mpu/qk/iar/dpp-qk.eww @@ -0,0 +1,10 @@ + + + + + $WS_DIR$\dpp-qk.ewp + + + + + diff --git a/examples/arm-cm/dpp_nucleo-c031c6_mpu/qk/iar/dpp-qk.icf b/examples/arm-cm/dpp_nucleo-c031c6_mpu/qk/iar/dpp-qk.icf new file mode 100644 index 00000000..db057b16 --- /dev/null +++ b/examples/arm-cm/dpp_nucleo-c031c6_mpu/qk/iar/dpp-qk.icf @@ -0,0 +1,165 @@ +/*###ICF### Section handled by ICF editor, don't touch! ****/ +/*-Editor annotation file-*/ +/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_4.xml" */ +/*-Specials-*/ +define symbol __ICFEDIT_intvec_start__ = 0x08000000; +/*-Memory Regions-*/ +define symbol __ICFEDIT_region_IROM1_start__ = 0x08000000; +define symbol __ICFEDIT_region_IROM1_end__ = 0x08007FFF; +define symbol __ICFEDIT_region_IROM2_start__ = 0x0; +define symbol __ICFEDIT_region_IROM2_end__ = 0x0; +define symbol __ICFEDIT_region_EROM1_start__ = 0x0; +define symbol __ICFEDIT_region_EROM1_end__ = 0x0; +define symbol __ICFEDIT_region_EROM2_start__ = 0x0; +define symbol __ICFEDIT_region_EROM2_end__ = 0x0; +define symbol __ICFEDIT_region_EROM3_start__ = 0x0; +define symbol __ICFEDIT_region_EROM3_end__ = 0x0; +define symbol __ICFEDIT_region_IRAM1_start__ = 0x20000000; +define symbol __ICFEDIT_region_IRAM1_end__ = 0x20002FFF; +define symbol __ICFEDIT_region_IRAM2_start__ = 0x0; +define symbol __ICFEDIT_region_IRAM2_end__ = 0x0; +define symbol __ICFEDIT_region_ERAM1_start__ = 0x0; +define symbol __ICFEDIT_region_ERAM1_end__ = 0x0; +define symbol __ICFEDIT_region_ERAM2_start__ = 0x0; +define symbol __ICFEDIT_region_ERAM2_end__ = 0x0; +define symbol __ICFEDIT_region_ERAM3_start__ = 0x0; +define symbol __ICFEDIT_region_ERAM3_end__ = 0x0; +/*-Sizes-*/ +define symbol __ICFEDIT_size_cstack__ = 2048; +define symbol __ICFEDIT_size_proc_stack__ = 0x0; +define symbol __ICFEDIT_size_heap__ = 0; +/**** End of ICF editor section. ###ICF###*/ + +define memory mem with size = 4G; +define symbol use_IROM1 = (__ICFEDIT_region_IROM1_start__ != 0x0 || __ICFEDIT_region_IROM1_end__ != 0x0); +define symbol use_IROM2 = (__ICFEDIT_region_IROM2_start__ != 0x0 || __ICFEDIT_region_IROM2_end__ != 0x0); +define symbol use_EROM1 = (__ICFEDIT_region_EROM1_start__ != 0x0 || __ICFEDIT_region_EROM1_end__ != 0x0); +define symbol use_EROM2 = (__ICFEDIT_region_EROM2_start__ != 0x0 || __ICFEDIT_region_EROM2_end__ != 0x0); +define symbol use_EROM3 = (__ICFEDIT_region_EROM3_start__ != 0x0 || __ICFEDIT_region_EROM3_end__ != 0x0); +define symbol use_IRAM1 = (__ICFEDIT_region_IRAM1_start__ != 0x0 || __ICFEDIT_region_IRAM1_end__ != 0x0); +define symbol use_IRAM2 = (__ICFEDIT_region_IRAM2_start__ != 0x0 || __ICFEDIT_region_IRAM2_end__ != 0x0); +define symbol use_ERAM1 = (__ICFEDIT_region_ERAM1_start__ != 0x0 || __ICFEDIT_region_ERAM1_end__ != 0x0); +define symbol use_ERAM2 = (__ICFEDIT_region_ERAM2_start__ != 0x0 || __ICFEDIT_region_ERAM2_end__ != 0x0); +define symbol use_ERAM3 = (__ICFEDIT_region_ERAM3_start__ != 0x0 || __ICFEDIT_region_ERAM3_end__ != 0x0); + +if (use_IROM1) +{ + define region IROM1_region = mem:[from __ICFEDIT_region_IROM1_start__ to __ICFEDIT_region_IROM1_end__]; +} +else +{ + define region IROM1_region = []; +} + +if (use_IROM2) +{ + define region IROM2_region = mem:[from __ICFEDIT_region_IROM2_start__ to __ICFEDIT_region_IROM2_end__]; +} +else +{ + define region IROM2_region = []; +} +define region IROM_region = IROM1_region | IROM2_region; + +if (use_EROM1) +{ + define region EROM1_region = mem:[from __ICFEDIT_region_EROM1_start__ to __ICFEDIT_region_EROM1_end__]; +} +else +{ + define region EROM1_region = []; +} +if (use_EROM2) +{ + define region EROM2_region = mem:[from __ICFEDIT_region_EROM2_start__ to __ICFEDIT_region_EROM2_end__]; +} +else +{ + define region EROM2_region = []; +} +if (use_EROM3) +{ + define region EROM3_region = mem:[from __ICFEDIT_region_EROM3_start__ to __ICFEDIT_region_EROM3_end__]; +} +else +{ + define region EROM3_region = []; +} +define region EROM_region = EROM1_region | EROM2_region | EROM3_region; + +if (use_IRAM1) +{ + define region IRAM1_region = mem:[from __ICFEDIT_region_IRAM1_start__ to __ICFEDIT_region_IRAM1_end__]; +} +else +{ + define region IRAM1_region = []; +} +if (use_IRAM2) +{ + define region IRAM2_region = mem:[from __ICFEDIT_region_IRAM2_start__ to __ICFEDIT_region_IRAM2_end__]; +} +else +{ + define region IRAM2_region = []; +} +define region IRAM_region = IRAM1_region | IRAM2_region; + +if (use_ERAM1) +{ + define region ERAM1_region = mem:[from __ICFEDIT_region_ERAM1_start__ to __ICFEDIT_region_ERAM1_end__]; +} +else +{ + define region ERAM1_region = []; +} +if (use_ERAM2) +{ + define region ERAM2_region = mem:[from __ICFEDIT_region_ERAM2_start__ to __ICFEDIT_region_ERAM2_end__]; +} +else +{ + define region ERAM2_region = []; +} +if (use_ERAM3) +{ + define region ERAM3_region = mem:[from __ICFEDIT_region_ERAM3_start__ to __ICFEDIT_region_ERAM3_end__]; +} +else +{ + define region ERAM3_region = []; +} +define region ERAM_region = ERAM1_region | ERAM2_region | ERAM3_region; + +initialize by copy { readwrite }; +if (isdefinedsymbol(__USE_DLIB_PERTHREAD)) +{ + // Required in a multi-threaded application + initialize by copy with packing = none { section __DLIB_PERTHREAD }; +} + +place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec }; + +if (!isempty(IROM_region)) +{ + place in IROM_region { readonly }; +} + +if (!isempty(EROM_region)) +{ + place in EROM_region { readonly section application_specific_ro }; +} + +if (!isempty(IRAM_region)) +{ + define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { }; + define block PROC_STACK with alignment = 8, size = __ICFEDIT_size_proc_stack__ { }; + define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { }; + place at start of IRAM_region {block CSTACK }; /* <== Quantum Leaps */ + place in IRAM_region { readwrite, block PROC_STACK, block HEAP }; +} + +if (!isempty(ERAM_region)) +{ + place in ERAM_region { readwrite section application_specific_rw }; +} \ No newline at end of file diff --git a/examples/arm-cm/dpp_nucleo-c031c6_mpu/qp_config.h b/examples/arm-cm/dpp_nucleo-c031c6_mpu/qp_config.h new file mode 100644 index 00000000..d3ba1ee3 --- /dev/null +++ b/examples/arm-cm/dpp_nucleo-c031c6_mpu/qp_config.h @@ -0,0 +1,57 @@ +//============================================================================ +// QP configuration file example +// Last updated for version: 7.3.0 +// Last updated on: 2023-09-09 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +//============================================================================ +#ifndef QP_CONFIG_H_ +#define QP_CONFIG_H_ + +// NOTE: +// The QP configuration takes effect only when the macro QP_CONFIG +// is defined on the command-line to the compiler for all QP source files. + +// use memory isolation (MPU) +#define QF_MEM_ISOLATE + +// use event constructors for dynamic events +#define QEVT_DYN_CTOR + +// for QK kernel: +// use the Reserved31_IRQHandler() with IRQ number 31 +// for the QK return-from-preemption handler +#define QK_USE_IRQ_NUM 31 +#define QK_USE_IRQ_HANDLER Reserved31_IRQHandler + +// for QXK kernel: +// use the Reserved31_IRQHandler() with IRQ number 31 +// for the QXK return-from-preemption handler +#define QXK_USE_IRQ_NUM 31 +#define QXK_USE_IRQ_HANDLER Reserved31_IRQHandler + +#endif // QP_CONFIG_H_ diff --git a/examples/arm-cm/dpp_nucleo-c031c6_mpu/qv/armclang/dpp-qv.sct b/examples/arm-cm/dpp_nucleo-c031c6_mpu/qv/armclang/dpp-qv.sct new file mode 100644 index 00000000..100826b8 --- /dev/null +++ b/examples/arm-cm/dpp_nucleo-c031c6_mpu/qv/armclang/dpp-qv.sct @@ -0,0 +1,23 @@ +; ************************************************************* +; *** Scatter-Loading Description File generated by uVision *** +; +; Adapted by Quantum Leaps: +; moved STACK as the first section in RW_STACK +; ************************************************************* + +LR_IROM1 0x08000000 0x00008000 { ; load region size_region + ER_IROM1 0x08000000 0x00008000 { ; load address = execution address + *.o (RESET, +First) + *(InRoot$$Sections) + .ANY (+RO) + .ANY (+XO) + } + + RW_STACK 0x20000000 { + * (STACK, +First) + } + RW_IRAM1 +0 (0x00003000 - 2048) { + .ANY (+RW +ZI) + } +} + diff --git a/examples/arm-cm/dpp_nucleo-c031c6_mpu/qv/armclang/dpp-qv.uvoptx b/examples/arm-cm/dpp_nucleo-c031c6_mpu/qv/armclang/dpp-qv.uvoptx new file mode 100644 index 00000000..ae470790 --- /dev/null +++ b/examples/arm-cm/dpp_nucleo-c031c6_mpu/qv/armclang/dpp-qv.uvoptx @@ -0,0 +1,1046 @@ + + + + 1.0 + +
### uVision Project, (C) Keil Software
+ + + *.c + *.s*; *.src; *.a* + *.obj; *.o + *.lib + *.txt; *.h; *.inc; *.md + *.plm + *.cpp + 0 + + + + 0 + 0 + + + + dpp-dbg + 0x4 + ARM-ADS + + 12000000 + + 1 + 1 + 0 + 1 + 0 + + + 1 + 65535 + 0 + 0 + 0 + + + 79 + 66 + 8 + .\dbg\ + + + 1 + 1 + 1 + 0 + 1 + 1 + 0 + 1 + 0 + 0 + 0 + 0 + + + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + + + 1 + 0 + 1 + + 18 + + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + 0 + 1 + 1 + 0 + 0 + 1 + 0 + 0 + 6 + + + + + + + + + + + STLink\ST-LINKIII-KEIL_SWO.dll + + + + 0 + ST-LINKIII-KEIL_SWO + -U066BFF505153848667095842 -O206 -SF10000 -C0 -A0 -I0 -HNlocalhost -HP7184 -P1 -N00("ARM CoreSight SW-DP (ARM Core") -D00(0BC11477) -L00(0) -TO65554 -TC10000000 -TT10000000 -TP21 -TDS8007 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -FO7 -FD20000000 -FC1000 -FN1 -FF0STM32C0x_32.FLM -FS08000000 -FL08000 -FP0($$Device:STM32C031C6Tx$CMSIS\Flash\STM32C0x_32.FLM) + + + 0 + UL2CM3 + -U -O206 -S8 -C0 -P00 -N00("") -D00(00000000) -L00(0) -TO65554 -TC10000000 -TT10000000 -TP21 -TDS8007 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -FO7 -FD20000000 -FC1000 -FN1 -FF0STM32C0x_32.FLM -FS08000000 -FL08000 -FP0($$Device:STM32C031C6Tx$CMSIS\Flash\STM32C0x_32.FLM) + + + 0 + DLGUARM + (105=-1,-1,-1,-1,0) + + + 0 + ARMRTXEVENTFLAGS + -L70 -Z18 -C0 -M0 -T1 + + + 0 + DLGTARM + (1010=-1,-1,-1,-1,0)(1007=-1,-1,-1,-1,0)(1008=-1,-1,-1,-1,0)(1012=3265,699,3740,1013,1)(1009=-1,-1,-1,-1,0) + + + 0 + ARMDBGFLAGS + + + + + + 0 + 0 + 170 + 1 +
134218132
+ 0 + 0 + 0 + 0 + 0 + 1 + ..\..\..\..\..\3rd_party\nucleo-c031c6\arm\startup_stm32c031xx.s + + \\dpp_qv\../../../../../3rd_party/nucleo-c031c6/arm/startup_stm32c031xx.s\170 +
+
+ + + 1 + 2 + 0x20000200 + 0 + + + + + 2 + 0 + 0x400 + 0 + + + + 0 + + + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + + + + 0 + 0 + 0 + + + + + + + + + + 1 + 0 + 0 + 2 + 10000000 + +
+
+ + + dpp-rel + 0x4 + ARM-ADS + + 12000000 + + 1 + 1 + 0 + 1 + 0 + + + 1 + 65535 + 0 + 0 + 0 + + + 79 + 66 + 8 + .\rel\ + + + 1 + 1 + 1 + 0 + 1 + 1 + 0 + 1 + 0 + 0 + 0 + 0 + + + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + + + 1 + 0 + 0 + + 18 + + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + 0 + 1 + 1 + 0 + 0 + 1 + 0 + 0 + 6 + + + + + + + + + + + STLink\ST-LINKIII-KEIL_SWO.dll + + + + 0 + UL2CM3 + UL2CM3(-S0 -C0 -P0 ) -FN1 -FC1000 -FD20000000 -FF0STM32C0x_32 -FL08000 -FS08000000 -FP0($$Device:STM32C031C6Tx$CMSIS\Flash\STM32C0x_32.FLM) + + + 0 + ST-LINKIII-KEIL_SWO + -U-O206 -O206 -SF10000 -C0 -A0 -I0 -HNlocalhost -HP7184 -P1 -N00("ARM CoreSight SW-DP (ARM Core") -D00(0BC11477) -L00(0) -TO131090 -TC10000000 -TT10000000 -TP21 -TDS8007 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -FO7 -FD20000000 -FC1000 -FN1 -FF0STM32C0x_32.FLM -FS08000000 -FL08000 -FP0($$Device:STM32C031C6Tx$CMSIS\Flash\STM32C0x_32.FLM) + + + 0 + DLGUARM + (105=-1,-1,-1,-1,0) + + + 0 + ARMRTXEVENTFLAGS + -L70 -Z18 -C0 -M0 -T1 + + + 0 + DLGTARM + (1010=-1,-1,-1,-1,0)(1007=-1,-1,-1,-1,0)(1008=-1,-1,-1,-1,0)(1012=3319,222,3794,536,1)(1009=-1,-1,-1,-1,0) + + + 0 + ARMDBGFLAGS + + + + + + 0 + 0 + 170 + 1 +
134218132
+ 0 + 0 + 0 + 0 + 0 + 1 + ..\..\..\..\..\3rd_party\nucleo-c031c6\arm\startup_stm32c031xx.s + + \\dpp_qv\../../../../../3rd_party/nucleo-c031c6/arm/startup_stm32c031xx.s\170 +
+
+ + + 1 + 2 + 0x200007a0 + 0 + + + + + 2 + 0 + 0x400 + 0 + + + + 0 + + + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + + + + 0 + 0 + 0 + + + + + + + + + + 1 + 0 + 0 + 2 + 10000000 + +
+
+ + + dpp-spy + 0x4 + ARM-ADS + + 12000000 + + 1 + 1 + 0 + 1 + 0 + + + 1 + 65535 + 0 + 0 + 0 + + + 79 + 66 + 8 + .\spy\ + + + 1 + 1 + 1 + 0 + 1 + 1 + 0 + 1 + 0 + 0 + 0 + 0 + + + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + + + 1 + 0 + 0 + + 18 + + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + 0 + 1 + 1 + 0 + 0 + 1 + 0 + 0 + 6 + + + + + + + + + + + STLink\ST-LINKIII-KEIL_SWO.dll + + + + 0 + UL2CM3 + UL2CM3(-S0 -C0 -P0 ) -FN1 -FC1000 -FD20000000 -FF0STM32C0x_32 -FL08000 -FS08000000 -FP0($$Device:STM32C031C6Tx$CMSIS\Flash\STM32C0x_32.FLM) + + + 0 + ST-LINKIII-KEIL_SWO + -U-O206 -O206 -SF10000 -C0 -A0 -I0 -HNlocalhost -HP7184 -P1 -N00("ARM CoreSight SW-DP (ARM Core") -D00(0BC11477) -L00(0) -TO131090 -TC10000000 -TT10000000 -TP21 -TDS8007 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -FO7 -FD20000000 -FC1000 -FN1 -FF0STM32C0x_32.FLM -FS08000000 -FL08000 -FP0($$Device:STM32C031C6Tx$CMSIS\Flash\STM32C0x_32.FLM) + + + 0 + DLGUARM + (105=-1,-1,-1,-1,0) + + + 0 + ARMRTXEVENTFLAGS + -L70 -Z18 -C0 -M0 -T1 + + + 0 + DLGTARM + (1010=-1,-1,-1,-1,0)(1007=-1,-1,-1,-1,0)(1008=-1,-1,-1,-1,0)(1012=3074,642,3549,956,1)(1009=-1,-1,-1,-1,0) + + + 0 + ARMDBGFLAGS + + + + + + + 1 + 2 + 0x20000200 + 0 + + + + + 2 + 0 + 0x400 + 0 + + + + 0 + + + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + + + + 0 + 0 + 0 + + + + + + + + + + 1 + 0 + 0 + 2 + 10000000 + + + + + + Source Code + 1 + 0 + 0 + 0 + + 1 + 1 + 1 + 0 + 0 + 0 + ..\bsp.c + bsp.c + 0 + 0 + + + 1 + 2 + 5 + 0 + 0 + 0 + ..\..\bsp.h + bsp.h + 0 + 0 + + + 1 + 3 + 5 + 0 + 0 + 0 + ..\..\dpp.h + dpp.h + 0 + 0 + + + 1 + 4 + 1 + 0 + 0 + 0 + ..\..\philo.c + philo.c + 0 + 0 + + + 1 + 5 + 1 + 0 + 0 + 0 + ..\..\table.c + table.c + 0 + 0 + + + 1 + 6 + 5 + 0 + 0 + 0 + .\dpp-qv.sct + dpp-qv.sct + 0 + 0 + + + 1 + 7 + 1 + 0 + 0 + 0 + ..\..\main.c + main.c + 0 + 0 + + + + + nucleo-c031c6 + 1 + 0 + 0 + 0 + + 2 + 8 + 5 + 0 + 0 + 0 + ..\..\..\..\..\3rd_party\nucleo-c031c6\stm32c0xx.h + stm32c0xx.h + 0 + 0 + + + 2 + 9 + 5 + 0 + 0 + 0 + ..\..\..\..\..\3rd_party\nucleo-c031c6\stm32c031xx.h + stm32c031xx.h + 0 + 0 + + + 2 + 10 + 1 + 0 + 0 + 0 + ..\..\..\..\..\3rd_party\nucleo-c031c6\system_stm32c0xx.c + system_stm32c0xx.c + 0 + 0 + + + 2 + 11 + 2 + 0 + 0 + 0 + ..\..\..\..\..\3rd_party\nucleo-c031c6\arm\startup_stm32c031xx.s + startup_stm32c031xx.s + 0 + 0 + + + + + QP + 1 + 0 + 0 + 0 + + 3 + 12 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qf\qep_hsm.c + qep_hsm.c + 0 + 0 + + + 3 + 13 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qf\qep_msm.c + qep_msm.c + 0 + 0 + + + 3 + 14 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qf\qf_act.c + qf_act.c + 0 + 0 + + + 3 + 15 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qf\qf_actq.c + qf_actq.c + 0 + 0 + + + 3 + 16 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qf\qf_defer.c + qf_defer.c + 0 + 0 + + + 3 + 17 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qf\qf_dyn.c + qf_dyn.c + 0 + 0 + + + 3 + 18 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qf\qf_mem.c + qf_mem.c + 0 + 0 + + + 3 + 19 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qf\qf_ps.c + qf_ps.c + 0 + 0 + + + 3 + 20 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qf\qf_qact.c + qf_qact.c + 0 + 0 + + + 3 + 21 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qf\qf_qeq.c + qf_qeq.c + 0 + 0 + + + 3 + 22 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qf\qf_qmact.c + qf_qmact.c + 0 + 0 + + + 3 + 23 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qf\qf_time.c + qf_time.c + 0 + 0 + + + 3 + 24 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qv\qv.c + qv.c + 0 + 0 + + + + + QP_port + 1 + 0 + 0 + 0 + + 4 + 25 + 1 + 0 + 0 + 0 + ..\..\..\..\..\ports\arm-cm\qv\armclang\qv_port.c + qv_port.c + 0 + 0 + + + + + QS + 1 + 0 + 0 + 0 + + 5 + 26 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qs\qs.c + qs.c + 0 + 0 + + + 5 + 27 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qs\qs_64bit.c + qs_64bit.c + 0 + 0 + + + 5 + 28 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qs\qs_fp.c + qs_fp.c + 0 + 0 + + + 5 + 29 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qs\qs_rx.c + qs_rx.c + 0 + 0 + + + 5 + 30 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qs\qstamp.c + qstamp.c + 0 + 0 + + + +
diff --git a/examples/arm-cm/dpp_nucleo-c031c6_mpu/qv/armclang/dpp-qv.uvprojx b/examples/arm-cm/dpp_nucleo-c031c6_mpu/qv/armclang/dpp-qv.uvprojx new file mode 100644 index 00000000..0a1a315a --- /dev/null +++ b/examples/arm-cm/dpp_nucleo-c031c6_mpu/qv/armclang/dpp-qv.uvprojx @@ -0,0 +1,1808 @@ + + + + 2.1 + +
### uVision Project, (C) Keil Software
+ + + + dpp-dbg + 0x4 + ARM-ADS + 6160000::V6.16::ARMCLANG + 1 + + + STM32C031C6Tx + STMicroelectronics + Keil.STM32C0xx_DFP.1.0.0 + https://www.keil.com/pack/ + IRAM(0x20000000,0x00003000) IROM(0x08000000,0x00008000) CPUTYPE("Cortex-M0+") CLOCK(12000000) ELITTLE + + + UL2CM3(-S0 -C0 -P0 -FD20000000 -FC1000 -FN1 -FF0STM32C0x_32 -FS08000000 -FL08000 -FP0($$Device:STM32C031C6Tx$CMSIS\Flash\STM32C0x_32.FLM)) + 0 + $$Device:STM32C031C6Tx$Drivers\CMSIS\Device\ST\STM32C0xx\Include\stm32c0xx.h + + + + + + + + + + $$Device:STM32C031C6Tx$CMSIS\SVD\STM32C031.svd + 0 + 0 + + + + + + + 0 + 0 + 0 + 0 + 1 + + .\dbg\ + dpp-qv + 1 + 0 + 0 + 1 + 1 + .\dbg\ + 1 + 0 + 0 + + 0 + 0 + + + 0 + 0 + 0 + 0 + + + 1 + 0 + cmd /c "del .\dbg\qstamp.o" + + 0 + 0 + 0 + 0 + + + 1 + 0 + fromelf --bin --output .\dbg\dpp-qv.bin .\dbg\dpp-qv.axf + + 0 + 0 + 0 + 0 + + 0 + + + + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 3 + + + 1 + + + SARMCM3.DLL + -REMAP-MPU + DARMCM1.DLL + -pCM0+ + SARMCM3.DLL + -MPU + TARMCM1.DLL + -pCM0+ + + + + 1 + 0 + 0 + 0 + 16 + + + + + 1 + 0 + 0 + 1 + 1 + 4096 + + 1 + BIN\UL2CM3.DLL + "" () + + + + + 0 + + + + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + 1 + 0 + 0 + 0 + 0 + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + "Cortex-M0+" + + 0 + 0 + 0 + 1 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 8 + 0 + 0 + 0 + 0 + 3 + 3 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 1 + 0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x20000000 + 0x3000 + + + 1 + 0x8000000 + 0x8000 + + + 0 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x8000000 + 0x8000 + + + 1 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x20000000 + 0x3000 + + + 0 + 0x0 + 0x0 + + + + + + 0 + 1 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 3 + 0 + 1 + 0 + 0 + 0 + 3 + 3 + 0 + 0 + 0 + 0 + 0 + + + QP_CONFIG + + ..\..;..\..\..\..\..\include;..\..\..\..\..\ports\arm-cm\qv\armclang;..\..\..\..\..\3rd_party\CMSIS\Include;..\..\..\..\..\3rd_party\nucleo-c031c6 + + + + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 4 + + + Stack_Size=2048 Heap_Size=16 + + + + + + 0 + 0 + 0 + 0 + 1 + 0 + 0x00000000 + 0x20000000 + + .\dpp-qv.sct + + + --entry Reset_Handler + + + + + + + + Source Code + + + bsp.c + 1 + ..\bsp.c + + + bsp.h + 5 + ..\..\bsp.h + + + dpp.h + 5 + ..\..\dpp.h + + + philo.c + 1 + ..\..\philo.c + + + table.c + 1 + ..\..\table.c + + + dpp-qv.sct + 5 + .\dpp-qv.sct + + + main.c + 1 + ..\..\main.c + + + + + nucleo-c031c6 + + + stm32c0xx.h + 5 + ..\..\..\..\..\3rd_party\nucleo-c031c6\stm32c0xx.h + + + stm32c031xx.h + 5 + ..\..\..\..\..\3rd_party\nucleo-c031c6\stm32c031xx.h + + + system_stm32c0xx.c + 1 + ..\..\..\..\..\3rd_party\nucleo-c031c6\system_stm32c0xx.c + + + startup_stm32c031xx.s + 2 + ..\..\..\..\..\3rd_party\nucleo-c031c6\arm\startup_stm32c031xx.s + + + + + QP + + + qep_hsm.c + 1 + ..\..\..\..\..\src\qf\qep_hsm.c + + + qep_msm.c + 1 + ..\..\..\..\..\src\qf\qep_msm.c + + + qf_act.c + 1 + ..\..\..\..\..\src\qf\qf_act.c + + + qf_actq.c + 1 + ..\..\..\..\..\src\qf\qf_actq.c + + + qf_defer.c + 1 + ..\..\..\..\..\src\qf\qf_defer.c + + + qf_dyn.c + 1 + ..\..\..\..\..\src\qf\qf_dyn.c + + + qf_mem.c + 1 + ..\..\..\..\..\src\qf\qf_mem.c + + + qf_ps.c + 1 + ..\..\..\..\..\src\qf\qf_ps.c + + + qf_qact.c + 1 + ..\..\..\..\..\src\qf\qf_qact.c + + + qf_qeq.c + 1 + ..\..\..\..\..\src\qf\qf_qeq.c + + + qf_qmact.c + 1 + ..\..\..\..\..\src\qf\qf_qmact.c + + + qf_time.c + 1 + ..\..\..\..\..\src\qf\qf_time.c + + + qv.c + 1 + ..\..\..\..\..\src\qv\qv.c + + + + + QP_port + + + qv_port.c + 1 + ..\..\..\..\..\ports\arm-cm\qv\armclang\qv_port.c + + + + + QS + + + 0 + 0 + 0 + 0 + 0 + 0 + 2 + 2 + 2 + 2 + 11 + + + 1 + + + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 0 + 0 + 0 + 0 + 2 + + + + + + + + + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + + + + + + + + + + + + qs.c + 1 + ..\..\..\..\..\src\qs\qs.c + + + qs_64bit.c + 1 + ..\..\..\..\..\src\qs\qs_64bit.c + + + qs_fp.c + 1 + ..\..\..\..\..\src\qs\qs_fp.c + + + qs_rx.c + 1 + ..\..\..\..\..\src\qs\qs_rx.c + + + qstamp.c + 1 + ..\..\..\..\..\src\qs\qstamp.c + + + + + + + dpp-rel + 0x4 + ARM-ADS + 6160000::V6.16::ARMCLANG + 1 + + + STM32C031C6Tx + STMicroelectronics + Keil.STM32C0xx_DFP.1.0.0 + https://www.keil.com/pack/ + IRAM(0x20000000,0x00003000) IROM(0x08000000,0x00008000) CPUTYPE("Cortex-M0+") CLOCK(12000000) ELITTLE + + + UL2CM3(-S0 -C0 -P0 -FD20000000 -FC1000 -FN1 -FF0STM32C0x_32 -FS08000000 -FL08000 -FP0($$Device:STM32C031C6Tx$CMSIS\Flash\STM32C0x_32.FLM)) + 0 + $$Device:STM32C031C6Tx$Drivers\CMSIS\Device\ST\STM32C0xx\Include\stm32c0xx.h + + + + + + + + + + $$Device:STM32C031C6Tx$CMSIS\SVD\STM32C031.svd + 0 + 0 + + + + + + + 0 + 0 + 0 + 0 + 1 + + .\rel\ + dpp-qv + 1 + 0 + 0 + 1 + 0 + .\rel\ + 1 + 0 + 0 + + 0 + 0 + + + 0 + 0 + 0 + 0 + + + 1 + 0 + cmd /c "del .\rel\qstamp.o" + + 0 + 0 + 0 + 0 + + + 1 + 0 + fromelf --bin --output .\rel\dpp-qv.bin .\rel\dpp-qv.axf + + 0 + 0 + 0 + 0 + + 0 + + + + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 3 + + + 1 + + + SARMCM3.DLL + -REMAP-MPU + DARMCM1.DLL + -pCM0+ + SARMCM3.DLL + -MPU + TARMCM1.DLL + -pCM0+ + + + + 1 + 0 + 0 + 0 + 16 + + + + + 1 + 0 + 0 + 1 + 1 + 4097 + + 1 + BIN\UL2CM3.DLL + + + + + + 0 + + + + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + 1 + 0 + 0 + 0 + 0 + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + "Cortex-M0+" + + 0 + 0 + 0 + 1 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 8 + 0 + 0 + 0 + 0 + 3 + 3 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 1 + 0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x20000000 + 0x3000 + + + 1 + 0x8000000 + 0x8000 + + + 0 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x8000000 + 0x8000 + + + 1 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x20000000 + 0x3000 + + + 0 + 0x0 + 0x0 + + + + + + 0 + 6 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 3 + 0 + 1 + 0 + 0 + 0 + 3 + 3 + 1 + 1 + 1 + 0 + 0 + + + NDEBUG,QP_CONFIG + + ..\..;..\..\..\..\..\include;..\..\..\..\..\ports\arm-cm\qv\armclang;..\..\..\..\..\3rd_party\CMSIS\Include;..\..\..\..\..\3rd_party\nucleo-c031c6 + + + + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 4 + + + Stack_Size=2048 Heap_Size=16 + + + + + + 0 + 0 + 0 + 0 + 1 + 0 + 0x00000000 + 0x20000000 + + .\dpp-qv.sct + + + --entry Reset_Handler + + + + + + + + Source Code + + + bsp.c + 1 + ..\bsp.c + + + bsp.h + 5 + ..\..\bsp.h + + + dpp.h + 5 + ..\..\dpp.h + + + philo.c + 1 + ..\..\philo.c + + + table.c + 1 + ..\..\table.c + + + dpp-qv.sct + 5 + .\dpp-qv.sct + + + main.c + 1 + ..\..\main.c + + + + + nucleo-c031c6 + + + stm32c0xx.h + 5 + ..\..\..\..\..\3rd_party\nucleo-c031c6\stm32c0xx.h + + + stm32c031xx.h + 5 + ..\..\..\..\..\3rd_party\nucleo-c031c6\stm32c031xx.h + + + system_stm32c0xx.c + 1 + ..\..\..\..\..\3rd_party\nucleo-c031c6\system_stm32c0xx.c + + + startup_stm32c031xx.s + 2 + ..\..\..\..\..\3rd_party\nucleo-c031c6\arm\startup_stm32c031xx.s + + + + + QP + + + qep_hsm.c + 1 + ..\..\..\..\..\src\qf\qep_hsm.c + + + qep_msm.c + 1 + ..\..\..\..\..\src\qf\qep_msm.c + + + qf_act.c + 1 + ..\..\..\..\..\src\qf\qf_act.c + + + qf_actq.c + 1 + ..\..\..\..\..\src\qf\qf_actq.c + + + qf_defer.c + 1 + ..\..\..\..\..\src\qf\qf_defer.c + + + qf_dyn.c + 1 + ..\..\..\..\..\src\qf\qf_dyn.c + + + qf_mem.c + 1 + ..\..\..\..\..\src\qf\qf_mem.c + + + qf_ps.c + 1 + ..\..\..\..\..\src\qf\qf_ps.c + + + qf_qact.c + 1 + ..\..\..\..\..\src\qf\qf_qact.c + + + qf_qeq.c + 1 + ..\..\..\..\..\src\qf\qf_qeq.c + + + qf_qmact.c + 1 + ..\..\..\..\..\src\qf\qf_qmact.c + + + qf_time.c + 1 + ..\..\..\..\..\src\qf\qf_time.c + + + qv.c + 1 + ..\..\..\..\..\src\qv\qv.c + + + + + QP_port + + + qv_port.c + 1 + ..\..\..\..\..\ports\arm-cm\qv\armclang\qv_port.c + + + + + QS + + + 0 + 0 + 0 + 0 + 0 + 0 + 2 + 2 + 2 + 2 + 11 + + + 1 + + + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 0 + 0 + 0 + 0 + 2 + + + + + + + + + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + + + + + + + + + + + + qs.c + 1 + ..\..\..\..\..\src\qs\qs.c + + + qs_64bit.c + 1 + ..\..\..\..\..\src\qs\qs_64bit.c + + + qs_fp.c + 1 + ..\..\..\..\..\src\qs\qs_fp.c + + + qs_rx.c + 1 + ..\..\..\..\..\src\qs\qs_rx.c + + + qstamp.c + 1 + ..\..\..\..\..\src\qs\qstamp.c + + + + + + + dpp-spy + 0x4 + ARM-ADS + 6160000::V6.16::ARMCLANG + 1 + + + STM32C031C6Tx + STMicroelectronics + Keil.STM32C0xx_DFP.1.0.0 + https://www.keil.com/pack/ + IRAM(0x20000000,0x00003000) IROM(0x08000000,0x00008000) CPUTYPE("Cortex-M0+") CLOCK(12000000) ELITTLE + + + UL2CM3(-S0 -C0 -P0 -FD20000000 -FC1000 -FN1 -FF0STM32C0x_32 -FS08000000 -FL08000 -FP0($$Device:STM32C031C6Tx$CMSIS\Flash\STM32C0x_32.FLM)) + 0 + $$Device:STM32C031C6Tx$Drivers\CMSIS\Device\ST\STM32C0xx\Include\stm32c0xx.h + + + + + + + + + + $$Device:STM32C031C6Tx$CMSIS\SVD\STM32C031.svd + 0 + 0 + + + + + + + 0 + 0 + 0 + 0 + 1 + + .\spy\ + dpp-qv + 1 + 0 + 0 + 1 + 1 + .\spy\ + 1 + 0 + 0 + + 0 + 0 + + + 0 + 0 + 0 + 0 + + + 1 + 0 + cmd /c "del .\spy\qstamp.o" + + 0 + 0 + 0 + 0 + + + 1 + 0 + fromelf --bin --output .\spy\dpp-qv.bin .\spy\dpp-qv.axf + + 0 + 0 + 0 + 0 + + 0 + + + + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 3 + + + 1 + + + SARMCM3.DLL + -REMAP-MPU + DARMCM1.DLL + -pCM0+ + SARMCM3.DLL + -MPU + TARMCM1.DLL + -pCM0+ + + + + 1 + 0 + 0 + 0 + 16 + + + + + 1 + 0 + 0 + 1 + 1 + 4096 + + 1 + BIN\UL2CM3.DLL + + + + + + 0 + + + + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + 1 + 0 + 0 + 0 + 0 + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + "Cortex-M0+" + + 0 + 0 + 0 + 1 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 8 + 0 + 0 + 0 + 0 + 3 + 3 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 1 + 0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x20000000 + 0x3000 + + + 1 + 0x8000000 + 0x8000 + + + 0 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x8000000 + 0x8000 + + + 1 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x20000000 + 0x3000 + + + 0 + 0x0 + 0x0 + + + + + + 0 + 2 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 3 + 0 + 1 + 0 + 0 + 0 + 3 + 3 + 0 + 0 + 0 + 0 + 0 + + + Q_SPY,QP_CONFIG + + ..\..;..\..\..\..\..\include;..\..\..\..\..\ports\arm-cm\qv\armclang;..\..\..\..\..\3rd_party\CMSIS\Include;..\..\..\..\..\3rd_party\nucleo-c031c6 + + + + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 4 + + + Stack_Size=2048 Heap_Size=16 + + + + + + 0 + 0 + 0 + 0 + 1 + 0 + 0x00000000 + 0x20000000 + + .\dpp-qv.sct + + + --entry Reset_Handler + + + + + + + + Source Code + + + bsp.c + 1 + ..\bsp.c + + + bsp.h + 5 + ..\..\bsp.h + + + dpp.h + 5 + ..\..\dpp.h + + + philo.c + 1 + ..\..\philo.c + + + table.c + 1 + ..\..\table.c + + + dpp-qv.sct + 5 + .\dpp-qv.sct + + + main.c + 1 + ..\..\main.c + + + + + nucleo-c031c6 + + + stm32c0xx.h + 5 + ..\..\..\..\..\3rd_party\nucleo-c031c6\stm32c0xx.h + + + stm32c031xx.h + 5 + ..\..\..\..\..\3rd_party\nucleo-c031c6\stm32c031xx.h + + + system_stm32c0xx.c + 1 + ..\..\..\..\..\3rd_party\nucleo-c031c6\system_stm32c0xx.c + + + startup_stm32c031xx.s + 2 + ..\..\..\..\..\3rd_party\nucleo-c031c6\arm\startup_stm32c031xx.s + + + + + QP + + + qep_hsm.c + 1 + ..\..\..\..\..\src\qf\qep_hsm.c + + + qep_msm.c + 1 + ..\..\..\..\..\src\qf\qep_msm.c + + + qf_act.c + 1 + ..\..\..\..\..\src\qf\qf_act.c + + + qf_actq.c + 1 + ..\..\..\..\..\src\qf\qf_actq.c + + + qf_defer.c + 1 + ..\..\..\..\..\src\qf\qf_defer.c + + + qf_dyn.c + 1 + ..\..\..\..\..\src\qf\qf_dyn.c + + + qf_mem.c + 1 + ..\..\..\..\..\src\qf\qf_mem.c + + + qf_ps.c + 1 + ..\..\..\..\..\src\qf\qf_ps.c + + + qf_qact.c + 1 + ..\..\..\..\..\src\qf\qf_qact.c + + + qf_qeq.c + 1 + ..\..\..\..\..\src\qf\qf_qeq.c + + + qf_qmact.c + 1 + ..\..\..\..\..\src\qf\qf_qmact.c + + + qf_time.c + 1 + ..\..\..\..\..\src\qf\qf_time.c + + + qv.c + 1 + ..\..\..\..\..\src\qv\qv.c + + + + + QP_port + + + qv_port.c + 1 + ..\..\..\..\..\ports\arm-cm\qv\armclang\qv_port.c + + + + + QS + + + qs.c + 1 + ..\..\..\..\..\src\qs\qs.c + + + qs_64bit.c + 1 + ..\..\..\..\..\src\qs\qs_64bit.c + + + qs_fp.c + 1 + ..\..\..\..\..\src\qs\qs_fp.c + + + qs_rx.c + 1 + ..\..\..\..\..\src\qs\qs_rx.c + + + qstamp.c + 1 + ..\..\..\..\..\src\qs\qstamp.c + + + + + + + + + + + + + +
diff --git a/examples/arm-cm/dpp_nucleo-c031c6_mpu/qv/bsp.c b/examples/arm-cm/dpp_nucleo-c031c6_mpu/qv/bsp.c new file mode 100644 index 00000000..29f1ba96 --- /dev/null +++ b/examples/arm-cm/dpp_nucleo-c031c6_mpu/qv/bsp.c @@ -0,0 +1,852 @@ +//============================================================================ +// Product: DPP example, NUCLEO-C031C6 board, QV kernel, MPU isolation +// Last updated for version 7.3.0 +// Last updated on 2023-08-28 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. +// +// This program is open source software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Alternatively, this program may be distributed and modified under the +// terms of Quantum Leaps commercial licenses, which expressly supersede +// the GNU General Public License and are specifically designed for +// licensees interested in retaining the proprietary status of their code. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Contact information: +// +// +//============================================================================ +#include "qpc.h" // QP/C real-time embedded framework +#include "dpp.h" // DPP Application interface +#include "bsp.h" // Board Support Package + +#include "stm32c0xx.h" // CMSIS-compliant header file for the MCU used +// add other drivers if necessary... + +Q_DEFINE_THIS_FILE // define the name of this file for assertions + +// Local-scope defines ----------------------------------------------------- +// LED pins available on the board (just one user LED LD4--Green on PA.5) +#define LD4_PIN 5U + +// Button pins available on the board (just one user Button B1 on PC.13) +#define B1_PIN 13U + +#ifdef Q_SPY + QSTimeCtr QS_tickTime_; + QSTimeCtr QS_tickPeriod_; + + // QSpy source IDs + static QSpyId const l_SysTick_Handler = { 0U }; + static QSpyId const l_EXTI0_1_IRQHandler = { 0U }; + + enum AppRecords { // application-specific trace records + PHILO_STAT = QS_USER, + PAUSED_STAT, + }; + +#endif + +//---------------------------------------------------------------------------- +// MPU storage and settings... +typedef struct { + uint32_t RBAR; + uint32_t RASR; +} MPU_Region; + +//============================================================================ +// Error handler and ISRs... + +Q_NORETURN Q_onError(char const *module, int_t const id) { + // NOTE: this implementation of the assertion handler is intended only + // for debugging and MUST be changed for deployment of the application + // (assuming that you ship your production code with assertions enabled). + Q_UNUSED_PAR(module); + Q_UNUSED_PAR(id); + QS_ASSERTION(module, id, 10000U); + +#ifndef NDEBUG + // light up the user LED + GPIOA->BSRR = (1U << LD4_PIN); // turn LED on + // for debugging, hang on in an endless loop... + for (;;) { + } +#endif + + NVIC_SystemReset(); +} +//............................................................................ +void assert_failed(char const * const module, int_t const id); // prototype +void assert_failed(char const * const module, int_t const id) { + Q_onError(module, id); +} + +// ISRs used in the application ========================================== +void SysTick_Handler(void); // prototype +void SysTick_Handler(void) { + QTIMEEVT_TICK_X(0U, &l_SysTick_Handler); // time events at rate 0 + + // Perform the debouncing of buttons. The algorithm for debouncing + // adapted from the book "Embedded Systems Dictionary" by Jack Ganssle + // and Michael Barr, page 71. + static struct { + uint32_t depressed; + uint32_t previous; + } buttons = { 0U, 0U }; + + QF_INT_DISABLE(); + QF_MEM_SYS(); + + uint32_t current = ~GPIOC->IDR; // read Port C with Button B1 + uint32_t tmp = buttons.depressed; // save the depressed buttons + buttons.depressed |= (buttons.previous & current); // set depressed + buttons.depressed &= (buttons.previous | current); // clear released + buttons.previous = current; // update the history + tmp ^= buttons.depressed; // changed debounced depressed + current = buttons.depressed; + +#ifdef Q_SPY + tmp = SysTick->CTRL; // clear CTRL_COUNTFLAG + QS_tickTime_ += QS_tickPeriod_; // account for the clock rollover +#endif + + QF_MEM_APP(); + QF_INT_ENABLE(); + + if ((tmp & (1U << B1_PIN)) != 0U) { // debounced B1 state changed? + if ((current & (1U << B1_PIN)) != 0U) { // is B1 depressed? + static QEvt const pauseEvt = QEVT_INITIALIZER(PAUSE_SIG); + QACTIVE_PUBLISH(&pauseEvt, &l_SysTick_Handler); + } + else { // the button is released + static QEvt const serveEvt = QEVT_INITIALIZER(SERVE_SIG); + QACTIVE_PUBLISH(&serveEvt, &l_SysTick_Handler); + } + } + + QV_ARM_ERRATUM_838869(); +} +//............................................................................ +// interrupt handler for testing preemptions in QV +void EXTI0_1_IRQHandler(void); // prototype +void EXTI0_1_IRQHandler(void) { + // for testing.. + static QEvt const testEvt = QEVT_INITIALIZER(TEST_SIG); + QACTIVE_POST(AO_Table, &testEvt, (void *)0); + + QV_ARM_ERRATUM_838869(); +} + +//............................................................................ +#ifdef Q_SPY +// ISR for receiving bytes from the QSPY Back-End +// NOTE: This ISR is "QF-unaware" meaning that it does not interact with +// the QF/QV and is not disabled. Such ISRs cannot post or publish events. + +void USART2_IRQHandler(void); // prototype +void USART2_IRQHandler(void) { // used in QS-RX (kernel UNAWARE interrutp) + // is RX register NOT empty? + QF_MEM_SYS(); + if ((USART2->ISR & (1U << 5)) != 0) { + uint32_t b = USART2->RDR; + QS_RX_PUT(b); + } + + QV_ARM_ERRATUM_838869(); +} +#endif // Q_SPY + +#ifdef QF_MEM_ISOLATE +//............................................................................ +__attribute__(( used )) +void QF_onMemSys(void) { + MPU->CTRL = MPU_CTRL_ENABLE_Msk // enable the MPU + | MPU_CTRL_PRIVDEFENA_Msk; // enable background region + __ISB(); + __DSB(); +} +//............................................................................ +__attribute__(( used )) +void QF_onMemApp() { + MPU->CTRL = MPU_CTRL_ENABLE_Msk; // enable the MPU + // but do NOT enable background region + __ISB(); + __DSB(); +} +//............................................................................ +#ifdef QF_ON_CONTEXT_SW +// NOTE: the context-switch callback is called with interrupts DISABLED +void QF_onContextSw(QActive *prev, QActive *next) { + if (next != (QActive *)0) { + MPU->CTRL = 0U; // disable the MPU + + MPU_Region const * const region = + (MPU_Region const *)(next->thread); + MPU->RBAR = region[0].RBAR; + MPU->RASR = region[0].RASR; + MPU->RBAR = region[1].RBAR; + MPU->RASR = region[1].RASR; + MPU->RBAR = region[2].RBAR; + MPU->RASR = region[2].RASR; + + MPU->CTRL = MPU_CTRL_ENABLE_Msk // enable the MPU + | MPU_CTRL_PRIVDEFENA_Msk; // enable background region + __ISB(); + __DSB(); + } +} +#endif // QF_ON_CONTEXT_SW +#endif // QF_MEM_ISOLATE + +//============================================================================ + +// Stack ..................................................................... +// NOTE +// The main stack size (provided here as power of 2), MUST match the actual +// stack size defined in the linker-script/startup-code. +#define STACK_SIZE_POW2 ((uint32_t)11U) + +// Table AO................................................................... +// size of Table instance, as power-of-2 +#define TABLE_SIZE_POW2 ((uint32_t)6U) + +__attribute__((aligned((1U << TABLE_SIZE_POW2)))) +static uint8_t Table_sto[1U << TABLE_SIZE_POW2]; + +#ifdef QF_MEM_ISOLATE +static MPU_Region const MPU_Table[3] = { + { (uint32_t)Table_sto + 0x10U, //---- region #0 + ((TABLE_SIZE_POW2 - 1U) << MPU_RASR_SIZE_Pos) // size + + (3U << MPU_RASR_AP_Pos) // PA:rw/UA:rw + + (1U << MPU_RASR_XN_Pos) // XN=1 + + (1U << MPU_RASR_S_Pos) // S=1 + + (1U << MPU_RASR_C_Pos) // C=1 + + (0U << MPU_RASR_B_Pos) // B=0 + + (0U << MPU_RASR_TEX_Pos) // TEX=0 + + MPU_RASR_ENABLE_Msk }, // region enable + { GPIOA_BASE + 0x11U, //---- region #1 + ((9U - 1U) << MPU_RASR_SIZE_Pos) // 2^9=512B size + + (3U << MPU_RASR_AP_Pos) // PA:rw/UA:rw + + (1U << MPU_RASR_XN_Pos) // XN=1 + + (1U << MPU_RASR_S_Pos) // S=1 + + (0U << MPU_RASR_C_Pos) // C=0 + + (1U << MPU_RASR_B_Pos) // B=1 + + (0U << MPU_RASR_TEX_Pos) // TEX=0 + + MPU_RASR_ENABLE_Msk }, // region enable + { 0U + 0x12U, //---- region #2 + 0U }, +}; +#endif + +// Philo AOs................................................................ +// size of Philo instance, as power-of-2 +#define PHILO_SIZE_POW2 ((uint32_t)6U) + +__attribute__((aligned((1U << PHILO_SIZE_POW2)))) +static uint8_t Philo_sto[N_PHILO][1U << PHILO_SIZE_POW2]; + +#define PHILO_SHARED_SIZE_POW2 ((uint32_t)5U) +__attribute__((aligned((1U << PHILO_SHARED_SIZE_POW2)))) +static union { + uint32_t rnd_seed; + uint8_t byteso[1U << PHILO_SHARED_SIZE_POW2]; +} Philo_shared_sto; + +#ifdef QF_MEM_ISOLATE +static MPU_Region const MPU_Philo[N_PHILO][3] = { + {{ (uint32_t)Philo_sto[0] + 0x10U, //---- region #0 + ((PHILO_SIZE_POW2 - 1U) << MPU_RASR_SIZE_Pos) // size + + (3U << MPU_RASR_AP_Pos) // PA:rw/UA:rw + + (1U << MPU_RASR_XN_Pos) // XN=1 + + (1U << MPU_RASR_S_Pos) // S=1 + + (1U << MPU_RASR_C_Pos) // C=1 + + (0U << MPU_RASR_B_Pos) // B=0 + + (0U << MPU_RASR_TEX_Pos) // TEX=0 + + MPU_RASR_ENABLE_Msk }, // region enable + { (uint32_t)&Philo_shared_sto + 0x11U, //---- region #1 + ((PHILO_SHARED_SIZE_POW2 - 1U) << MPU_RASR_SIZE_Pos) // size + + (3U << MPU_RASR_AP_Pos) // PA:rw/UA:rw + + (1U << MPU_RASR_XN_Pos) // XN=1 + + (1U << MPU_RASR_S_Pos) // S=1 + + (1U << MPU_RASR_C_Pos) // C=1 + + (0U << MPU_RASR_B_Pos) // B=0 + + (0U << MPU_RASR_TEX_Pos) // TEX=0 + + MPU_RASR_ENABLE_Msk }, // region enable + { 0U + 0x12U, //---- region #2 + 0U }}, + {{ (uint32_t)Philo_sto[1] + 0x10U, //---- region #0 + ((PHILO_SIZE_POW2 - 1U) << MPU_RASR_SIZE_Pos) // size + + (3U << MPU_RASR_AP_Pos) // PA:rw/UA:rw + + (1U << MPU_RASR_XN_Pos) // XN=1 + + (1U << MPU_RASR_S_Pos) // S=1 + + (1U << MPU_RASR_C_Pos) // C=1 + + (0U << MPU_RASR_B_Pos) // B=0 + + (0U << MPU_RASR_TEX_Pos) // TEX=0 + + MPU_RASR_ENABLE_Msk }, // region enable + { (uint32_t)&Philo_shared_sto + 0x11U, //---- region #1 + ((PHILO_SHARED_SIZE_POW2 - 1U) << MPU_RASR_SIZE_Pos) // size + + (3U << MPU_RASR_AP_Pos) // PA:rw/UA:rw + + (1U << MPU_RASR_XN_Pos) // XN=1 + + (1U << MPU_RASR_S_Pos) // S=1 + + (1U << MPU_RASR_C_Pos) // C=1 + + (0U << MPU_RASR_B_Pos) // B=0 + + (0U << MPU_RASR_TEX_Pos) // TEX=0 + + MPU_RASR_ENABLE_Msk }, // region enable + { 0U + 0x12U, //---- region #2 + 0U }}, + {{ (uint32_t)Philo_sto[2] + 0x10U, //---- region #0 + ((PHILO_SIZE_POW2 - 1U) << MPU_RASR_SIZE_Pos) // size + + (3U << MPU_RASR_AP_Pos) // PA:rw/UA:rw + + (1U << MPU_RASR_XN_Pos) // XN=1 + + (1U << MPU_RASR_S_Pos) // S=1 + + (1U << MPU_RASR_C_Pos) // C=1 + + (0U << MPU_RASR_B_Pos) // B=0 + + (0U << MPU_RASR_TEX_Pos) // TEX=0 + + MPU_RASR_ENABLE_Msk }, // region enable + { (uint32_t)&Philo_shared_sto + 0x11U, //---- region #1 + ((PHILO_SHARED_SIZE_POW2 - 1U) << MPU_RASR_SIZE_Pos) // size + + (3U << MPU_RASR_AP_Pos) // PA:rw/UA:rw + + (1U << MPU_RASR_XN_Pos) // XN=1 + + (1U << MPU_RASR_S_Pos) // S=1 + + (1U << MPU_RASR_C_Pos) // C=1 + + (0U << MPU_RASR_B_Pos) // B=0 + + (0U << MPU_RASR_TEX_Pos) // TEX=0 + + MPU_RASR_ENABLE_Msk }, // region enable + { 0U + 0x12U, //---- region #2 + 0U }}, + {{ (uint32_t)Philo_sto[3] + 0x10U, //---- region #0 + ((PHILO_SIZE_POW2 - 1U) << MPU_RASR_SIZE_Pos) // size + + (3U << MPU_RASR_AP_Pos) // PA:rw/UA:rw + + (1U << MPU_RASR_XN_Pos) // XN=1 + + (1U << MPU_RASR_S_Pos) // S=1 + + (1U << MPU_RASR_C_Pos) // C=1 + + (0U << MPU_RASR_B_Pos) // B=0 + + (0U << MPU_RASR_TEX_Pos) // TEX=0 + + MPU_RASR_ENABLE_Msk }, // region enable + { (uint32_t)&Philo_shared_sto + 0x11U, //---- region #1 + ((PHILO_SHARED_SIZE_POW2 - 1U) << MPU_RASR_SIZE_Pos) // size + + (3U << MPU_RASR_AP_Pos) // PA:rw/UA:rw + + (1U << MPU_RASR_XN_Pos) // XN=1 + + (1U << MPU_RASR_S_Pos) // S=1 + + (1U << MPU_RASR_C_Pos) // C=1 + + (0U << MPU_RASR_B_Pos) // B=0 + + (0U << MPU_RASR_TEX_Pos) // TEX=0 + + MPU_RASR_ENABLE_Msk }, // region enable + { 0U + 0x12U, //---- region #2 + 0U }}, + {{ (uint32_t)Philo_sto[4] + 0x10U, //---- region #0 + ((PHILO_SIZE_POW2 - 1U) << MPU_RASR_SIZE_Pos) // size + + (3U << MPU_RASR_AP_Pos) // PA:rw/UA:rw + + (1U << MPU_RASR_XN_Pos) // XN=1 + + (1U << MPU_RASR_S_Pos) // S=1 + + (1U << MPU_RASR_C_Pos) // C=1 + + (0U << MPU_RASR_B_Pos) // B=0 + + (0U << MPU_RASR_TEX_Pos) // TEX=0 + + MPU_RASR_ENABLE_Msk }, // region enable + { (uint32_t)&Philo_shared_sto + 0x11U, //---- region #1 + ((PHILO_SHARED_SIZE_POW2 - 1U) << MPU_RASR_SIZE_Pos) // size + + (3U << MPU_RASR_AP_Pos) // PA:rw/UA:rw + + (1U << MPU_RASR_XN_Pos) // XN=1 + + (1U << MPU_RASR_S_Pos) // S=1 + + (1U << MPU_RASR_C_Pos) // C=1 + + (0U << MPU_RASR_B_Pos) // B=0 + + (0U << MPU_RASR_TEX_Pos) // TEX=0 + + MPU_RASR_ENABLE_Msk }, // region enable + { 0U + 0x12U, //---- region #2 + 0U }}, +}; +#endif + +// Shared Event-pools...................................................... +#define EPOOLS_SIZE_POW2 ((uint32_t)8U) + +__attribute__((aligned((1U << EPOOLS_SIZE_POW2)))) +static struct EPools { + QF_MPOOL_EL(TableEvt) smlPool[2*N_PHILO]; + // ... other pools +} EPools_sto; +Q_ASSERT_STATIC(sizeof(EPools_sto) <= (1U << EPOOLS_SIZE_POW2)); + +//............................................................................ +#ifdef QF_MEM_ISOLATE +static void STM32C031C6_MPU_setup(void) { + + MPU->CTRL = 0U; // disable the MPU + + // region #7: NULL-pointer protection region + MPU->RBAR = 0x00000000U + 0x17U; // base address + region #7 + MPU->RASR = ((8U - 1U) << MPU_RASR_SIZE_Pos) // 2^8=256B size + + (0U << MPU_RASR_AP_Pos) // PA:na/UA:na + + (1U << MPU_RASR_XN_Pos) // XN=1 + + (0U << MPU_RASR_S_Pos) // S=0 + + (0U << MPU_RASR_C_Pos) // C=0 + + (0U << MPU_RASR_B_Pos) // B=0 + + (0U << MPU_RASR_TEX_Pos) // TEX=0 + + MPU_RASR_ENABLE_Msk; // region enable + + // region #6: stack region + MPU->RBAR = 0x20000000U + 0x16U; // base address + region #6 + MPU->RASR = ((STACK_SIZE_POW2 - 1U) << MPU_RASR_SIZE_Pos) // size + + (3U << MPU_RASR_AP_Pos) // PA:rw/UA:rw + + (1U << MPU_RASR_XN_Pos) // XN=1 + + (1U << MPU_RASR_S_Pos) // S=1 + + (1U << MPU_RASR_C_Pos) // C=1 + + (0U << MPU_RASR_B_Pos) // B=0 + + (0U << MPU_RASR_TEX_Pos) // TEX=0 + + MPU_RASR_ENABLE_Msk; // region enable + + // region #5: ROM region for STM32C031C6, whole 32K + MPU->RBAR = 0x08000000U + 0x15U; // base address + region #5 + MPU->RASR = ((15U - 1U) << MPU_RASR_SIZE_Pos) // 2^15=32K size + + (6U << MPU_RASR_AP_Pos) // PA:ro/UA:ro + + (0U << MPU_RASR_XN_Pos) // XN=0 + + (0U << MPU_RASR_S_Pos) // S=0 + + (1U << MPU_RASR_C_Pos) // C=1 + + (0U << MPU_RASR_B_Pos) // B=0 + + (0U << MPU_RASR_TEX_Pos) // TEX=0 + + MPU_RASR_ENABLE_Msk; // region enable + + // region #4: Event-pools region + MPU->RBAR = (uint32_t)&EPools_sto + 0x14U;// base address + region #4 + MPU->RASR = ((EPOOLS_SIZE_POW2 - 1U) << MPU_RASR_SIZE_Pos) // size + + (3U << MPU_RASR_AP_Pos) // PA:rw/UA:rw + + (1U << MPU_RASR_XN_Pos) // XN=1 + + (1U << MPU_RASR_S_Pos) // S=1 + + (1U << MPU_RASR_C_Pos) // C=1 + + (0U << MPU_RASR_B_Pos) // B=0 + + (0U << MPU_RASR_TEX_Pos) // TEX=0 + + MPU_RASR_ENABLE_Msk; // region enable + +#ifdef Q_SPY + // region #3: QS-filters region + MPU->RBAR = (uint32_t)&QS_filt_ + 0x13U;// base address + region #3 + MPU->RASR = ((8U - 1U) << MPU_RASR_SIZE_Pos) // 2^8=256B size + + (3U << MPU_RASR_AP_Pos) // PA:rw/UA:rw + + (1U << MPU_RASR_XN_Pos) // XN=1 + + (1U << MPU_RASR_S_Pos) // S=1 + + (1U << MPU_RASR_C_Pos) // C=1 + + (0U << MPU_RASR_B_Pos) // B=0 + + (0U << MPU_RASR_TEX_Pos) // TEX=0 + + MPU_RASR_ENABLE_Msk; // region enable +#endif + + // region #0: temporary 4G region for the initial transient + MPU->RBAR = 0x00000000U + 0x10U; // base address + region #0 + MPU->RASR = ((32U - 1U) << MPU_RASR_SIZE_Pos) // 2^32=4G size + + (3U << MPU_RASR_AP_Pos) // PA:rw/UA:rw + + (0U << MPU_RASR_XN_Pos) // XN=0 + + (1U << MPU_RASR_S_Pos) // S=1 + + (1U << MPU_RASR_C_Pos) // C=1 + + (0U << MPU_RASR_B_Pos) // B=0 + + (0U << MPU_RASR_TEX_Pos) // TEX=0 + + MPU_RASR_ENABLE_Msk; // region enable + + MPU->CTRL = MPU_CTRL_ENABLE_Msk; // enable the MPU + // but do NOT enable background region + __ISB(); + __DSB(); +} +#endif + +//============================================================================ + +// "opaque" pointer to AO +QActive * const AO_Table = (QActive *)Table_sto; + +QActive * const AO_Philo[N_PHILO] = { + (QActive *)Philo_sto[0], // "opaque" pointer + (QActive *)Philo_sto[1], // "opaque" pointer + (QActive *)Philo_sto[2], // "opaque" pointer + (QActive *)Philo_sto[3], // "opaque" pointer + (QActive *)Philo_sto[4] // "opaque" pointer +}; + +// BSP functions =========================================================== +void BSP_init(void) { +#ifdef QF_MEM_ISOLATE + // setup the MPU + STM32C031C6_MPU_setup(); +#endif + + // NOTE: SystemInit() has been already called from the startup code + // but SystemCoreClock needs to be updated + SystemCoreClockUpdate(); + + // enable GPIOA clock port for the LED LD4 + RCC->IOPENR |= (1U << 0U); + + // set all used GPIOA pins as push-pull output, no pull-up, pull-down + GPIOA->MODER &= ~(3U << 2U*LD4_PIN); + GPIOA->MODER |= (1U << 2U*LD4_PIN); + GPIOA->OTYPER &= ~(1U << LD4_PIN); + GPIOA->OSPEEDR &= ~(3U << 2U*LD4_PIN); + GPIOA->OSPEEDR |= (1U << 2U*LD4_PIN); + GPIOA->PUPDR &= ~(3U << 2U*LD4_PIN); + + // enable GPIOC clock port for the Button B1 + RCC->IOPENR |= (1U << 2U); + + // configure Button B1 pin on GPIOC as input, no pull-up, pull-down + GPIOC->MODER &= ~(3U << 2U*B1_PIN); + GPIOC->PUPDR &= ~(3U << 2U*B1_PIN); + + BSP_randomSeed(1234U); // seed the random number generator + + // initialize the QS software tracing... + if (!QS_INIT((void *)0)) { + Q_ERROR(); + } + + // dictionaries... + QS_OBJ_DICTIONARY(&l_SysTick_Handler); + QS_OBJ_DICTIONARY(&l_EXTI0_1_IRQHandler); + QS_USR_DICTIONARY(PHILO_STAT); + QS_USR_DICTIONARY(PAUSED_STAT); + + QS_ONLY(produce_sig_dict()); + + // setup the QS filters... + QS_GLB_FILTER(QS_ALL_RECORDS); // all records + QS_GLB_FILTER(-QS_QF_TICK); // exclude the clock tick +} +//............................................................................ +void BSP_start(void) { + // initialize event pools + QF_poolInit(EPools_sto.smlPool, + sizeof(EPools_sto.smlPool), + sizeof(EPools_sto.smlPool[0])); + + // initialize publish-subscribe + static QSubscrList subscrSto[MAX_PUB_SIG]; + QActive_psInit(subscrSto, Q_DIM(subscrSto)); + + // instantiate and start AOs/threads... + static QEvt const *philoQueueSto[N_PHILO][10]; + for (uint8_t n = 0U; n < N_PHILO; ++n) { +#ifdef QF_MEM_ISOLATE + Philo_ctor(n, Philo_sto[n], sizeof(Philo_sto[n]), MPU_Philo[n]); +#else + Philo_ctor(n, Philo_sto[n], sizeof(Philo_sto[n]), (void *)0); +#endif + QACTIVE_START(AO_Philo[n], + n + 3U, // QF-prio/pthre. see NOTE1 + philoQueueSto[n], // event queue storage + Q_DIM(philoQueueSto[n]), // queue length [events] + (void *)0, 0U, // no stack storage + (void *)0); // no initialization param + } + + static QEvt const *tableQueueSto[N_PHILO]; +#ifdef QF_MEM_ISOLATE + Table_ctor(Table_sto, sizeof(Table_sto), MPU_Table); +#else + Table_ctor(Table_sto, sizeof(Table_sto), (void *)0); +#endif + QACTIVE_START(AO_Table, + N_PHILO + 7U, // QP prio. of the AO + tableQueueSto, // event queue storage + Q_DIM(tableQueueSto), // queue length [events] + (void *)0, 0U, // no stack storage + (void *)0); // no initialization param +} +//............................................................................ +void BSP_displayPhilStat(uint8_t n, char const *stat) { + Q_UNUSED_PAR(n); + + if (stat[0] == 'e') { + GPIOA->BSRR = (1U << LD4_PIN); // turn LED on + } + else { + GPIOA->BSRR = (1U << (LD4_PIN + 16U)); // turn LED off + } + + // app-specific trace record... + QS_BEGIN_ID(PHILO_STAT, AO_Table->prio) + QS_U8(1, n); // Philosopher number + QS_STR(stat); // Philosopher status + QS_END() +} +//............................................................................ +void BSP_displayPaused(uint8_t const paused) { + // not enough LEDs to implement this feature + if (paused != 0U) { + //GPIOA->BSRR = (1U << LD4_PIN); // turn LED[n] on + } + else { + //GPIOA->BSRR = (1U << (LD4_PIN + 16U)); // turn LED[n] off + } + + // application-specific trace record + QS_BEGIN_ID(PAUSED_STAT, AO_Table->prio) + QS_U8(1, paused); // Paused status + QS_END() +} +//............................................................................ +void BSP_randomSeed(uint32_t seed) { + Philo_shared_sto.rnd_seed = seed; +} +//............................................................................ +uint32_t BSP_random() { // a very cheap pseudo-random-number generator + // "Super-Duper" Linear Congruential Generator (LCG) + // LCG(2^32, 3*7*11*13*23, 0, seed) + // + uint32_t rnd = Philo_shared_sto.rnd_seed * (3U*7U*11U*13U*23U); + Philo_shared_sto.rnd_seed = rnd; // set for the next time + + return (rnd >> 8U); +} +//............................................................................ +void BSP_ledOn() { + GPIOA->BSRR = (1U << LD4_PIN); // turn LED on +} +//............................................................................ +void BSP_ledOff() { + GPIOA->BSRR = (1U << (LD4_PIN + 16U)); // turn LED off +} +//............................................................................ +void BSP_terminate(int16_t result) { + Q_UNUSED_PAR(result); +} + +//============================================================================ +// QF callbacks... +void QF_onStartup(void) { + // set up the SysTick timer to fire at BSP_TICKS_PER_SEC rate + SysTick_Config(SystemCoreClock / BSP_TICKS_PER_SEC); + + // assign all priority bits for preemption-prio. and none to sub-prio. + // NOTE: this might have been changed by STM32Cube. + NVIC_SetPriorityGrouping(0U); + + // set priorities of ALL ISRs used in the system, see NOTE1 + NVIC_SetPriority(USART2_IRQn, 0U); // kernel UNAWARE interrupt + NVIC_SetPriority(EXTI0_1_IRQn, QF_AWARE_ISR_CMSIS_PRI + 0U); + NVIC_SetPriority(SysTick_IRQn, QF_AWARE_ISR_CMSIS_PRI + 1U); + // ... + + // enable IRQs... + NVIC_EnableIRQ(EXTI0_1_IRQn); + +#ifdef Q_SPY + NVIC_EnableIRQ(USART2_IRQn); // UART2 interrupt used for QS-RX +#endif +} +//............................................................................ +void QF_onCleanup(void) { +} +//............................................................................ +void QV_onIdle(void) { // CAUTION: called with interrupts disabled, see NOTE0 + + // toggle an LED on and then off (not enough LEDs, see NOTE02) + QF_MEM_SYS(); + //GPIOA->BSRR = (1U << LD4_PIN); // turn LED[n] on + //GPIOA->BSRR = (1U << (LD4_PIN + 16U)); // turn LED[n] off + +#ifdef Q_SPY + // interrupts still disabled + QS_rxParse(); // parse all the received bytes + QF_MEM_APP(); + QF_INT_ENABLE(); + QF_CRIT_EXIT_NOP(); + + QF_INT_DISABLE(); + QF_MEM_SYS(); + if ((USART2->ISR & (1U << 7U)) != 0U) { // is TXE empty? + uint16_t b = QS_getByte(); + if (b != QS_EOD) { // not End-Of-Data? + USART2->TDR = b; // put into the DR register + } + } + QF_MEM_APP(); + QF_INT_ENABLE(); +#elif defined NDEBUG + // Put the CPU and peripherals to the low-power mode. + // you might need to customize the clock management for your application, + // see the datasheet for your particular Cortex-M MCU. + // + // !!!CAUTION!!! + // QV_CPU_SLEEP() contains the WFI instruction, which stops the CPU + // clock, which unfortunately disables the JTAG port, so the ST-Link + // debugger can no longer connect to the board. For that reason, the call + // to QV_CPU_SLEEP() has to be used with CAUTION. + // + // NOTE: If you find your board "frozen" like this, strap BOOT0 to VDD and + // reset the board, then connect with ST-Link Utilities and erase the part. + // The trick with BOOT(0) is it gets the part to run the System Loader + // instead of your broken code. When done disconnect BOOT0, and start over. + // + //QV_CPU_SLEEP(); // atomically go to sleep and enable interrupts + QF_MEM_APP(); + QF_INT_ENABLE(); // for now, just enable interrupts +#else + QF_MEM_APP(); + QF_INT_ENABLE(); // just enable interrupts +#endif +} + +//============================================================================ +// QS callbacks... +#ifdef Q_SPY + +#ifdef QF_MEM_ISOLATE +// Shared QS filters... +__attribute__((aligned(32))) +QS_Filter QS_filt_; +#endif + +//............................................................................ +static uint16_t const UARTPrescTable[12] = { + 1U, 2U, 4U, 6U, 8U, 10U, 12U, 16U, 32U, 64U, 128U, 256U +}; + +#define UART_DIV_SAMPLING16(__PCLK__, __BAUD__, __CLOCKPRESCALER__) \ + ((((__PCLK__)/UARTPrescTable[(__CLOCKPRESCALER__)]) \ + + ((__BAUD__)/2U)) / (__BAUD__)) + +#define UART_PRESCALER_DIV1 0U + +// USART2 pins PA.2 and PA.3 +#define USART2_TX_PIN 2U +#define USART2_RX_PIN 3U + +//............................................................................ +uint8_t QS_onStartup(void const *arg) { + Q_UNUSED_PAR(arg); + + static uint8_t qsTxBuf[2*1024]; // buffer for QS-TX channel + QS_initBuf(qsTxBuf, sizeof(qsTxBuf)); + + static uint8_t qsRxBuf[100]; // buffer for QS-RX channel + QS_rxInitBuf(qsRxBuf, sizeof(qsRxBuf)); + + // enable peripheral clock for USART2 + RCC->IOPENR |= ( 1U << 0U); // Enable GPIOA clock for USART pins + RCC->APBENR1 |= ( 1U << 17U); // Enable USART#2 clock + + // Configure PA to USART2_RX, PA to USART2_TX + GPIOA->AFR[0] &= ~((15U << 4U*USART2_RX_PIN) | (15U << 4U*USART2_TX_PIN)); + GPIOA->AFR[0] |= (( 1U << 4U*USART2_RX_PIN) | ( 1U << 4U*USART2_TX_PIN)); + GPIOA->MODER &= ~(( 3U << 2U*USART2_RX_PIN) | ( 3U << 2U*USART2_TX_PIN)); + GPIOA->MODER |= (( 2U << 2U*USART2_RX_PIN) | ( 2U << 2U*USART2_TX_PIN)); + + // baud rate + USART2->BRR = UART_DIV_SAMPLING16( + SystemCoreClock, 115200U, UART_PRESCALER_DIV1); + USART2->CR3 = 0x0000U | // no flow control + (1U << 12U); // disable overrun detection (OVRDIS) + USART2->CR2 = 0x0000U; // 1 stop bit + USART2->CR1 = ((1U << 2U) | // enable RX + (1U << 3U) | // enable TX + (1U << 5U) | // enable RX interrupt + (0U << 12U) | // 8 data bits + (0U << 28U) | // 8 data bits + (1U << 0U)); // enable USART + + QS_tickPeriod_ = SystemCoreClock / BSP_TICKS_PER_SEC; + QS_tickTime_ = QS_tickPeriod_; // to start the timestamp at zero + + return 1U; // return success +} +//............................................................................ +void QS_onCleanup(void) { +} +//............................................................................ +QSTimeCtr QS_onGetTime(void) { // NOTE: invoked with interrupts DISABLED + if ((SysTick->CTRL & 0x00010000U) == 0U) { // not set? + return QS_tickTime_ - (QSTimeCtr)SysTick->VAL; + } + else { // the rollover occured, but the SysTick_ISR did not run yet + return QS_tickTime_ + QS_tickPeriod_ - (QSTimeCtr)SysTick->VAL; + } +} +//............................................................................ +void QS_onFlush(void) { + for (;;) { + QF_INT_DISABLE(); + QF_MEM_SYS(); + uint16_t b = QS_getByte(); + if (b != QS_EOD) { + while ((USART2->ISR & (1U << 7U)) == 0U) { // while TXE not empty + QF_MEM_APP(); + QF_INT_ENABLE(); + QF_CRIT_EXIT_NOP(); + + QF_INT_DISABLE(); + QF_MEM_SYS(); + } + USART2->TDR = b; // put into the DR register + QF_MEM_APP(); + QF_INT_ENABLE(); + } + else { + QF_MEM_APP(); + QF_INT_ENABLE(); + break; + } + } +} +//............................................................................ +//! callback function to reset the target (to be implemented in the BSP) +void QS_onReset(void) { + NVIC_SystemReset(); +} +//............................................................................ +//! callback function to execute a user command +void QS_onCommand(uint8_t cmdId, + uint32_t param1, uint32_t param2, uint32_t param3) +{ + Q_UNUSED_PAR(cmdId); + Q_UNUSED_PAR(param1); + Q_UNUSED_PAR(param2); + Q_UNUSED_PAR(param3); +} + +#endif // Q_SPY +//---------------------------------------------------------------------------- + +//============================================================================ +// NOTE0: +// The QV_onIdle() callback is called with interrupts disabled, because the +// determination of the idle condition might change by any interrupt posting +// an event. QV_onIdle() must internally enable interrupts, ideally +// atomically with putting the CPU to the power-saving mode. +// +// NOTE1: +// The QF_AWARE_ISR_CMSIS_PRI constant from the QF port specifies the highest +// ISR priority that is disabled by the QF framework. The value is suitable +// for the NVIC_SetPriority() CMSIS function. +// +// Only ISRs prioritized at or below the QF_AWARE_ISR_CMSIS_PRI level (i.e., +// with the numerical values of priorities equal or higher than +// QF_AWARE_ISR_CMSIS_PRI) are allowed to call the QF/QV services. These ISRs +// are "QF-aware". +// +// Conversely, any ISRs prioritized above the QF_AWARE_ISR_CMSIS_PRI priority +// level (i.e., with the numerical values of priorities less than +// QF_AWARE_ISR_CMSIS_PRI) are never disabled and are not aware of the kernel. +// Such "QF-unaware" ISRs cannot call ANY QF/QV services. In particular they +// can NOT call any QF/QV services. The only mechanism by which a "QF-unaware" +// ISR can communicate with the QF framework is by pending a "QF-aware" ISR, +// which can post/publish events. +// +// NOTE2: +// The User LED is used to visualize the idle loop activity. The brightness +// of the LED is proportional to the frequency of the idle loop. +// Please note that the LED is toggled with interrupts locked, so no interrupt +// execution time contributes to the brightness of the User LED. +// diff --git a/examples/arm-cm/dpp_nucleo-c031c6_mpu/qv/gnu/Makefile b/examples/arm-cm/dpp_nucleo-c031c6_mpu/qv/gnu/Makefile new file mode 100644 index 00000000..b3f50e9f --- /dev/null +++ b/examples/arm-cm/dpp_nucleo-c031c6_mpu/qv/gnu/Makefile @@ -0,0 +1,315 @@ +############################################################################## +# Product: Makefile for QP/C on NUCLEO-C031C6, QV kernel, GNU-ARM +# Last Updated for Version: 7.3.0 +# Date of the Last Update: 2023-09-07 +# +# Q u a n t u m L e a P s +# ------------------------ +# Modern Embedded Software +# +# Copyright (C) 2005 Quantum Leaps, LLC. +# +# This program is open source software: you can redistribute it and/or +# modify it under the terms of the GNU General Public License as published +# by the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Alternatively, this program may be distributed and modified under the +# terms of Quantum Leaps commercial licenses, which expressly supersede +# the GNU General Public License and are specifically designed for +# licensees interested in retaining the proprietary status of their code. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# +# Contact information: +# +# +############################################################################## +# examples of invoking this Makefile: +# building configurations: Debug (default), Release, and Spy +# make +# make CONF=rel +# make CONF=spy +# +# cleaning configurations: Debug (default), Release, and Spy +# make clean +# make CONF=rel clean +# make CONF=spy clean +# +# NOTE: +# To use this Makefile on Windows, you will need the GNU make utility, which +# is included in the Qtools collection for Windows, see: +# https://github.com/QuantumLeaps/qtools + +#----------------------------------------------------------------------------- +# project name +# +PROJECT := dpp-qv + +#----------------------------------------------------------------------------- +# project directories +# + +# location of the QP/C framework (if not provided in an environemnt var.) +ifeq ($(QPC),) +QPC := ../../../../.. +endif + +# QP port used in this project +QP_PORT_DIR := $(QPC)/ports/arm-cm/qv/gnu + +# list of all source directories used by this project +VPATH = \ + .. \ + ../.. \ + $(QPC)/src/qf \ + $(QPC)/src/qv \ + $(QPC)/src/qs \ + $(QP_PORT_DIR) \ + $(QPC)/3rd_party/nucleo-c031c6 \ + $(QPC)/3rd_party/nucleo-c031c6/gnu + +# list of all include directories needed by this project +INCLUDES = \ + -I../.. \ + -I$(QPC)/include \ + -I$(QP_PORT_DIR) \ + -I$(QPC)/3rd_party/CMSIS/Include \ + -I$(QPC)/3rd_party/nucleo-c031c6 + +#----------------------------------------------------------------------------- +# files +# + +# assembler source files +ASM_SRCS := + +# C source files +C_SRCS := \ + bsp.c \ + main.c \ + philo.c \ + table.c \ + system_stm32c0xx.c \ + startup_stm32c031xx.c + +# C++ source files +CPP_SRCS := + +OUTPUT := $(PROJECT) +LD_SCRIPT := $(PROJECT).ld + +QP_SRCS := \ + qep_hsm.c \ + qep_msm.c \ + qf_act.c \ + qf_actq.c \ + qf_defer.c \ + qf_dyn.c \ + qf_mem.c \ + qf_ps.c \ + qf_qact.c \ + qf_qeq.c \ + qf_qmact.c \ + qf_time.c \ + qv.c \ + qv_port.c + +QP_ASMS := + +QS_SRCS := \ + qs.c \ + qs_rx.c \ + qs_fp.c + +LIB_DIRS := +LIBS := + +# defines +DEFINES := \ + -DQP_CONFIG \ + -DSTM32C031xx + +# ARM CPU, ARCH, FPU, and Float-ABI types... +# ARM_CPU: [cortex-m0 | cortex-m0plus | cortex-m1 | cortex-m3 | cortex-m4] +# ARM_FPU: [ | vfp] +# FLOAT_ABI: [ | soft | softfp | hard] +# +ARM_CPU := -mcpu=cortex-m0plus +ARM_FPU := +FLOAT_ABI := + +#----------------------------------------------------------------------------- +# GNU-ARM toolset (NOTE: You need to adjust to your machine) +# see https://developer.arm.com/open-source/gnu-toolchain/gnu-rm/downloads +# +ifeq ($(GNU_ARM),) +GNU_ARM := $(QTOOLS)/gnu_arm-none-eabi +endif + +# make sure that the GNU-ARM toolset exists... +ifeq ("$(wildcard $(GNU_ARM))","") +$(error GNU_ARM toolset not found. Please adjust the Makefile) +endif + +CC := $(GNU_ARM)/bin/arm-none-eabi-gcc +CPP := $(GNU_ARM)/bin/arm-none-eabi-g++ +AS := $(GNU_ARM)/bin/arm-none-eabi-as +LINK := $(GNU_ARM)/bin/arm-none-eabi-gcc +BIN := $(GNU_ARM)/bin/arm-none-eabi-objcopy + +############################################################################## +# Typically you should not need to change anything below this line + +# basic utilities (included in QTools for Windows), see: +# https://www.state-machine.com/qtools + +MKDIR := mkdir +RM := rm + +#----------------------------------------------------------------------------- +# build options for various configurations for ARM Cortex-M +# + +# combine all the soruces... +C_SRCS += $(QP_SRCS) +ASM_SRCS += $(QP_ASMS) + +ifeq (rel, $(CONF)) # Release configuration .................................. + +BIN_DIR := rel + +ASFLAGS = $(ARM_CPU) $(ARM_FPU) $(ASM_CPU) $(ASM_FPU) + +CFLAGS = -c $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \ + -ffunction-sections -fdata-sections \ + -O2 $(INCLUDES) $(DEFINES) -DNDEBUG + +CPPFLAGS = -c $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \ + -ffunction-sections -fdata-sections -fno-rtti -fno-exceptions \ + -O2 $(INCLUDES) $(DEFINES) -DNDEBUG + +else ifeq (spy, $(CONF)) # Spy configuration ................................ + +BIN_DIR := spy + +C_SRCS += $(QS_SRCS) + +ASFLAGS = -g $(ARM_CPU) $(ARM_FPU) $(ASM_CPU) $(ASM_FPU) + +CFLAGS = -c -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \ + -ffunction-sections -fdata-sections \ + -O $(INCLUDES) $(DEFINES) -DQ_SPY + +CPPFLAGS = -c -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \ + -ffunction-sections -fdata-sections -fno-rtti -fno-exceptions \ + -O $(INCLUDES) $(DEFINES) -DQ_SPY + +else # default Debug configuration .......................................... + +BIN_DIR := dbg + +ASFLAGS = -g $(ARM_CPU) $(ARM_FPU) $(ASM_CPU) $(ASM_FPU) + +CFLAGS = -c -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \ + -ffunction-sections -fdata-sections \ + -O $(INCLUDES) $(DEFINES) + +CPPFLAGS = -c -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \ + -ffunction-sections -fdata-sections -fno-rtti -fno-exceptions \ + -O $(INCLUDES) $(DEFINES) + +endif # ...................................................................... + + +LINKFLAGS = -T$(LD_SCRIPT) $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb \ + -specs=nosys.specs -specs=nano.specs \ + -Wl,-Map,$(BIN_DIR)/$(OUTPUT).map,--cref,--gc-sections $(LIB_DIRS) + + +ASM_OBJS := $(patsubst %.s,%.o, $(notdir $(ASM_SRCS))) +C_OBJS := $(patsubst %.c,%.o, $(notdir $(C_SRCS))) +CPP_OBJS := $(patsubst %.cpp,%.o,$(notdir $(CPP_SRCS))) + +TARGET_BIN := $(BIN_DIR)/$(OUTPUT).bin +TARGET_ELF := $(BIN_DIR)/$(OUTPUT).elf +ASM_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(ASM_OBJS)) +C_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(C_OBJS)) +C_DEPS_EXT := $(patsubst %.o, %.d, $(C_OBJS_EXT)) +CPP_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(CPP_OBJS)) +CPP_DEPS_EXT := $(patsubst %.o, %.d, $(CPP_OBJS_EXT)) + +# create $(BIN_DIR) if it does not exist +ifeq ("$(wildcard $(BIN_DIR))","") +$(shell $(MKDIR) $(BIN_DIR)) +endif + +#----------------------------------------------------------------------------- +# rules +# + +.PHONY : run norun flash clean show + +ifeq ($(MAKECMDGOALS),norun) +all : $(TARGET_BIN) +norun : all +else +all : $(TARGET_BIN) run +endif + +$(TARGET_BIN): $(TARGET_ELF) + $(BIN) -O binary $< $@ + +$(TARGET_ELF) : $(ASM_OBJS_EXT) $(C_OBJS_EXT) $(CPP_OBJS_EXT) + $(CC) $(CFLAGS) $(QPC)/src/qs/qstamp.c -o $(BIN_DIR)/qstamp.o + $(LINK) $(LINKFLAGS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) + +$(BIN_DIR)/%.d : %.c + $(CC) -MM -MT $(@:.d=.o) $(CFLAGS) $< > $@ + +$(BIN_DIR)/%.d : %.cpp + $(CPP) -MM -MT $(@:.d=.o) $(CPPFLAGS) $< > $@ + +$(BIN_DIR)/%.o : %.s + $(AS) $(ASFLAGS) $< -o $@ + +$(BIN_DIR)/%.o : %.c + $(CC) $(CFLAGS) $< -o $@ + +$(BIN_DIR)/%.o : %.cpp + $(CPP) $(CPPFLAGS) $< -o $@ + +# include dependency files only if our goal depends on their existence +ifneq ($(MAKECMDGOALS),clean) + ifneq ($(MAKECMDGOALS),show) +-include $(C_DEPS_EXT) $(CPP_DEPS_EXT) + endif +endif + + +clean: + -$(RM) $(BIN_DIR)/*.o \ + $(BIN_DIR)/*.d \ + $(BIN_DIR)/*.bin \ + $(BIN_DIR)/*.elf \ + $(BIN_DIR)/*.map + +show: + @echo PROJECT = $(PROJECT) + @echo CONF = $(CONF) + @echo DEFINES = $(DEFINES) + @echo ASM_FPU = $(ASM_FPU) + @echo ASM_SRCS = $(ASM_SRCS) + @echo C_SRCS = $(C_SRCS) + @echo CPP_SRCS = $(CPP_SRCS) + @echo ASM_OBJS_EXT = $(ASM_OBJS_EXT) + @echo C_OBJS_EXT = $(C_OBJS_EXT) + @echo C_DEPS_EXT = $(C_DEPS_EXT) + @echo CPP_DEPS_EXT = $(CPP_DEPS_EXT) + @echo TARGET_ELF = $(TARGET_ELF) diff --git a/examples/arm-cm/dpp_nucleo-c031c6_mpu/qv/gnu/dpp-qv.ld b/examples/arm-cm/dpp_nucleo-c031c6_mpu/qv/gnu/dpp-qv.ld new file mode 100644 index 00000000..4a3ba851 --- /dev/null +++ b/examples/arm-cm/dpp_nucleo-c031c6_mpu/qv/gnu/dpp-qv.ld @@ -0,0 +1,135 @@ +/***************************************************************************** +* Linker script for for STM32C031C6, GNU-ARM linker +* +* Q u a n t u m L e a P s +* ------------------------ +* Modern Embedded Software +* +* Copyright (C) 2005 Quantum Leaps, LLC . +* +* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +* +* This software is dual-licensed under the terms of the open source GNU +* General Public License version 3 (or any later version), or alternatively, +* under the terms of one of the closed source Quantum Leaps commercial +* licenses. +* +* The terms of the open source GNU General Public License version 3 +* can be found at: +* +* The terms of the closed source Quantum Leaps commercial licenses +* can be found at: +* +* Redistributions in source code must retain this top-level comment block. +* Plagiarizing this software to sidestep the license obligations is illegal. +* +* Contact information: +* +* +*****************************************************************************/ +OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm", "elf32-littlearm") +OUTPUT_ARCH(arm) +ENTRY(Reset_Handler) /* entry Point */ + +MEMORY { /* memory map of STM32C031C6 */ + ROM (rx) : ORIGIN = 0x08000000, LENGTH = 32K + RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 12K +} + +/* The size of the stack used by the application. NOTE: you need to adjust */ +STACK_SIZE = 2048; + +/* The size of the heap used by the application. NOTE: you need to adjust */ +HEAP_SIZE = 0; + +SECTIONS { + + .isr_vector : { /* the vector table goes FIRST into ROM */ + KEEP(*(.isr_vector)) /* vector table */ + . = ALIGN(4); + } >ROM + + .text : { /* code and constants */ + . = ALIGN(4); + *(.text) /* .text sections (code) */ + *(.text*) /* .text* sections (code) */ + *(.rodata) /* .rodata sections (constants, strings, etc.) */ + *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ + + KEEP (*(.init)) + KEEP (*(.fini)) + + . = ALIGN(4); + } >ROM + + .preinit_array : { + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array*)) + PROVIDE_HIDDEN (__preinit_array_end = .); + } >ROM + + .init_array : { + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array*)) + PROVIDE_HIDDEN (__init_array_end = .); + } >ROM + + .fini_array : { + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(.fini_array*)) + KEEP (*(SORT(.fini_array.*))) + PROVIDE_HIDDEN (__fini_array_end = .); + } >ROM + + _etext = .; /* global symbols at end of code */ + + .stack : { + __stack_start__ = .; + . = . + STACK_SIZE; + . = ALIGN(4); + __stack_end__ = .; + } >RAM + + .data : AT (_etext) { + __data_load = LOADADDR (.data); + __data_start = .; + *(.data) /* .data sections */ + *(.data*) /* .data* sections */ + . = ALIGN(4); + __data_end__ = .; + _edata = __data_end__; + } >RAM + + .bss : { + __bss_start__ = .; + *(.bss) + *(.bss*) + *(COMMON) + . = ALIGN(4); + _ebss = .; /* define a global symbol at bss end */ + __bss_end__ = .; + } >RAM + + __exidx_start = .; + .ARM.exidx : { *(.ARM.exidx* .gnu.linkonce.armexidx.*) } >RAM + __exidx_end = .; + + PROVIDE ( end = _ebss ); + PROVIDE ( _end = _ebss ); + PROVIDE ( __end__ = _ebss ); + + .heap : { + __heap_start__ = .; + . = . + HEAP_SIZE; + . = ALIGN(4); + __heap_end__ = .; + } >RAM + + /* Remove information from the standard libraries */ + /DISCARD/ : { + libc.a ( * ) + libm.a ( * ) + libgcc.a ( * ) + } +} diff --git a/examples/arm-cm/dpp_nucleo-c031c6_mpu/qv/iar/dpp-qv.ewd b/examples/arm-cm/dpp_nucleo-c031c6_mpu/qv/iar/dpp-qv.ewd new file mode 100644 index 00000000..b3712b65 --- /dev/null +++ b/examples/arm-cm/dpp_nucleo-c031c6_mpu/qv/iar/dpp-qv.ewd @@ -0,0 +1,4654 @@ + + + 3 + + Debug + + ARM + + 1 + + C-SPY + 2 + + 32 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ARMSIM_ID + 2 + + 1 + 1 + 1 + + + + + + + + CADI_ID + 2 + + 0 + 1 + 1 + + + + + + + + + CMSISDAP_ID + 2 + + 4 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + GDBSERVER_ID + 2 + + 0 + 1 + 1 + + + + + + + + + + + IJET_ID + 2 + + 9 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + JLINK_ID + 2 + + 16 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + LMIFTDI_ID + 2 + + 3 + 1 + 1 + + + + + + + + + + + + + NULINK_ID + 2 + + 0 + 1 + 1 + + + + + + + PEMICRO_ID + 2 + + 3 + 1 + 1 + + + + + + + + STLINK_ID + 2 + + 8 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + THIRDPARTY_ID + 2 + + 0 + 1 + 1 + + + + + + + + TIFET_ID + 2 + + 1 + 1 + 1 + + + + + + + + + + + + + + + + + + + XDS100_ID + 2 + + 9 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + $TOOLKIT_DIR$\plugins\rtos\CMX\CmxArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\CMX\CmxTinyArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\FreeRtos\FreeRtosArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin2.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SafeRTOS\SafeRTOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9BE.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-286-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-III\uCOS-III-KA-CSpy.ewplugin + 0 + + + $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\TargetAccessServer\TargetAccessServer.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\uCProbe\uCProbePlugin.ENU.ewplugin + 0 + + + + + Release + + ARM + + 0 + + C-SPY + 2 + + 32 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ARMSIM_ID + 2 + + 1 + 1 + 0 + + + + + + + + CADI_ID + 2 + + 0 + 1 + 0 + + + + + + + + + CMSISDAP_ID + 2 + + 4 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + GDBSERVER_ID + 2 + + 0 + 1 + 0 + + + + + + + + + + + IJET_ID + 2 + + 9 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + JLINK_ID + 2 + + 16 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + LMIFTDI_ID + 2 + + 3 + 1 + 0 + + + + + + + + + + + + + NULINK_ID + 2 + + 0 + 1 + 0 + + + + + + + PEMICRO_ID + 2 + + 3 + 1 + 0 + + + + + + + + STLINK_ID + 2 + + 8 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + THIRDPARTY_ID + 2 + + 0 + 1 + 0 + + + + + + + + TIFET_ID + 2 + + 1 + 1 + 0 + + + + + + + + + + + + + + + + + + + XDS100_ID + 2 + + 9 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + $TOOLKIT_DIR$\plugins\rtos\CMX\CmxArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\CMX\CmxTinyArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\FreeRtos\FreeRtosArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin2.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SafeRTOS\SafeRTOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9BE.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-286-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-III\uCOS-III-KA-CSpy.ewplugin + 0 + + + $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\TargetAccessServer\TargetAccessServer.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\uCProbe\uCProbePlugin.ENU.ewplugin + 0 + + + + + Spy + + ARM + + 1 + + C-SPY + 2 + + 32 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ARMSIM_ID + 2 + + 1 + 1 + 1 + + + + + + + + CADI_ID + 2 + + 0 + 1 + 1 + + + + + + + + + CMSISDAP_ID + 2 + + 4 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + GDBSERVER_ID + 2 + + 0 + 1 + 1 + + + + + + + + + + + IJET_ID + 2 + + 9 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + JLINK_ID + 2 + + 16 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + LMIFTDI_ID + 2 + + 3 + 1 + 1 + + + + + + + + + + + + + NULINK_ID + 2 + + 0 + 1 + 1 + + + + + + + PEMICRO_ID + 2 + + 3 + 1 + 1 + + + + + + + + STLINK_ID + 2 + + 8 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + THIRDPARTY_ID + 2 + + 0 + 1 + 1 + + + + + + + + TIFET_ID + 2 + + 1 + 1 + 1 + + + + + + + + + + + + + + + + + + + XDS100_ID + 2 + + 9 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + $TOOLKIT_DIR$\plugins\rtos\CMX\CmxArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\CMX\CmxTinyArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\FreeRtos\FreeRtosArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin2.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SafeRTOS\SafeRTOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9BE.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-286-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-III\uCOS-III-KA-CSpy.ewplugin + 0 + + + $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\TargetAccessServer\TargetAccessServer.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\uCProbe\uCProbePlugin.ENU.ewplugin + 0 + + + + diff --git a/examples/arm-cm/dpp_nucleo-c031c6_mpu/qv/iar/dpp-qv.ewp b/examples/arm-cm/dpp_nucleo-c031c6_mpu/qv/iar/dpp-qv.ewp new file mode 100644 index 00000000..2d36d929 --- /dev/null +++ b/examples/arm-cm/dpp_nucleo-c031c6_mpu/qv/iar/dpp-qv.ewp @@ -0,0 +1,3367 @@ + + + 3 + + Debug + + ARM + + 1 + + General + 3 + + 35 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ICCARM + 2 + + 37 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + AARM + 2 + + 11 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + OBJCOPY + 0 + + 1 + 1 + 1 + + + + + + + + + CUSTOM + 3 + + + + 0 + inputOutputBased + + + + BUILDACTION + 1 + + cmd /c "if exist $OBJ_DIR$\qstamp.o del $OBJ_DIR$\qstamp.o" + + + + + ILINK + 0 + + 27 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + IARCHIVE + 0 + + 0 + 1 + 1 + + + + + + + Coder + 0 + + + + + Release + + ARM + + 0 + + General + 3 + + 35 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ICCARM + 2 + + 37 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + AARM + 2 + + 11 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + OBJCOPY + 0 + + 1 + 1 + 0 + + + + + + + + + CUSTOM + 3 + + + + 0 + inputOutputBased + + + + BUILDACTION + 1 + + cmd /c "if exist $OBJ_DIR$\qstamp.o del $OBJ_DIR$\qstamp.o" + + + + + ILINK + 0 + + 27 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + IARCHIVE + 0 + + 0 + 1 + 0 + + + + + + + Coder + 0 + + + + + Spy + + ARM + + 1 + + General + 3 + + 35 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ICCARM + 2 + + 37 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + AARM + 2 + + 11 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + OBJCOPY + 0 + + 1 + 1 + 1 + + + + + + + + + CUSTOM + 3 + + + + 0 + inputOutputBased + + + + BUILDACTION + 1 + + cmd /c "if exist $OBJ_DIR$\qstamp.o del $OBJ_DIR$\qstamp.o" + + + + + ILINK + 0 + + 27 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + IARCHIVE + 0 + + 0 + 1 + 1 + + + + + + + Coder + 0 + + + + + Release + + + Application + + $PROJ_DIR$\..\bsp.c + + + $PROJ_DIR$\..\..\bsp.h + + + $PROJ_DIR$\..\..\dpp.h + + + $PROJ_DIR$\..\..\main.c + + + $PROJ_DIR$\..\..\philo.c + + + $PROJ_DIR$\..\..\table.c + + + + nucleo-c031c6 + + $PROJ_DIR$\..\..\..\..\..\3rd_party\nucleo-c031c6\iar\startup_stm32c031xx.s + + + $PROJ_DIR$\..\..\..\..\..\3rd_party\nucleo-c031c6\stm32c031xx.h + + + $PROJ_DIR$\..\..\..\..\..\3rd_party\nucleo-c031c6\stm32c0xx.h + + + $PROJ_DIR$\..\..\..\..\..\3rd_party\nucleo-c031c6\system_stm32c0xx.c + + + + QP + + $PROJ_DIR$\..\..\..\..\..\src\qf\qep_hsm.c + + + $PROJ_DIR$\..\..\..\..\..\src\qf\qep_msm.c + + + $PROJ_DIR$\..\..\..\..\..\src\qf\qf_act.c + + + $PROJ_DIR$\..\..\..\..\..\src\qf\qf_actq.c + + + $PROJ_DIR$\..\..\..\..\..\src\qf\qf_defer.c + + + $PROJ_DIR$\..\..\..\..\..\src\qf\qf_dyn.c + + + $PROJ_DIR$\..\..\..\..\..\src\qf\qf_mem.c + + + $PROJ_DIR$\..\..\..\..\..\src\qf_pkg.h + + + $PROJ_DIR$\..\..\..\..\..\src\qf\qf_ps.c + + + $PROJ_DIR$\..\..\..\..\..\src\qf\qf_qact.c + + + $PROJ_DIR$\..\..\..\..\..\src\qf\qf_qeq.c + + + $PROJ_DIR$\..\..\..\..\..\src\qf\qf_qmact.c + + + $PROJ_DIR$\..\..\..\..\..\src\qf\qf_time.c + + + $PROJ_DIR$\..\..\..\..\..\src\qv\qv.c + + + + QP_port + + $PROJ_DIR$\..\..\..\..\..\ports\arm-cm\qv\iar\qep_port.h + + + $PROJ_DIR$\..\..\..\..\..\ports\arm-cm\qv\iar\qf_port.h + + + $PROJ_DIR$\..\..\..\..\..\ports\arm-cm\qv\iar\qs_port.h + + + $PROJ_DIR$\..\..\..\..\..\ports\arm-cm\qv\iar\qv_port.c + + + $PROJ_DIR$\..\..\..\..\..\ports\arm-cm\qv\iar\qv_port.h + + + + QS + + Debug + Release + + + $PROJ_DIR$\..\..\..\..\..\src\qs\qs.c + + + $PROJ_DIR$\..\..\..\..\..\src\qs\qs_fp.c + + + $PROJ_DIR$\..\..\..\..\..\src\qs\qs_rx.c + + + $PROJ_DIR$\..\..\..\..\..\src\qs\qstamp.c + + + diff --git a/examples/arm-cm/dpp_nucleo-c031c6_mpu/qv/iar/dpp-qv.eww b/examples/arm-cm/dpp_nucleo-c031c6_mpu/qv/iar/dpp-qv.eww new file mode 100644 index 00000000..b96f3f62 --- /dev/null +++ b/examples/arm-cm/dpp_nucleo-c031c6_mpu/qv/iar/dpp-qv.eww @@ -0,0 +1,10 @@ + + + + + $WS_DIR$\dpp-qv.ewp + + + + + diff --git a/examples/arm-cm/dpp_nucleo-c031c6_mpu/qv/iar/dpp-qv.icf b/examples/arm-cm/dpp_nucleo-c031c6_mpu/qv/iar/dpp-qv.icf new file mode 100644 index 00000000..db057b16 --- /dev/null +++ b/examples/arm-cm/dpp_nucleo-c031c6_mpu/qv/iar/dpp-qv.icf @@ -0,0 +1,165 @@ +/*###ICF### Section handled by ICF editor, don't touch! ****/ +/*-Editor annotation file-*/ +/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_4.xml" */ +/*-Specials-*/ +define symbol __ICFEDIT_intvec_start__ = 0x08000000; +/*-Memory Regions-*/ +define symbol __ICFEDIT_region_IROM1_start__ = 0x08000000; +define symbol __ICFEDIT_region_IROM1_end__ = 0x08007FFF; +define symbol __ICFEDIT_region_IROM2_start__ = 0x0; +define symbol __ICFEDIT_region_IROM2_end__ = 0x0; +define symbol __ICFEDIT_region_EROM1_start__ = 0x0; +define symbol __ICFEDIT_region_EROM1_end__ = 0x0; +define symbol __ICFEDIT_region_EROM2_start__ = 0x0; +define symbol __ICFEDIT_region_EROM2_end__ = 0x0; +define symbol __ICFEDIT_region_EROM3_start__ = 0x0; +define symbol __ICFEDIT_region_EROM3_end__ = 0x0; +define symbol __ICFEDIT_region_IRAM1_start__ = 0x20000000; +define symbol __ICFEDIT_region_IRAM1_end__ = 0x20002FFF; +define symbol __ICFEDIT_region_IRAM2_start__ = 0x0; +define symbol __ICFEDIT_region_IRAM2_end__ = 0x0; +define symbol __ICFEDIT_region_ERAM1_start__ = 0x0; +define symbol __ICFEDIT_region_ERAM1_end__ = 0x0; +define symbol __ICFEDIT_region_ERAM2_start__ = 0x0; +define symbol __ICFEDIT_region_ERAM2_end__ = 0x0; +define symbol __ICFEDIT_region_ERAM3_start__ = 0x0; +define symbol __ICFEDIT_region_ERAM3_end__ = 0x0; +/*-Sizes-*/ +define symbol __ICFEDIT_size_cstack__ = 2048; +define symbol __ICFEDIT_size_proc_stack__ = 0x0; +define symbol __ICFEDIT_size_heap__ = 0; +/**** End of ICF editor section. ###ICF###*/ + +define memory mem with size = 4G; +define symbol use_IROM1 = (__ICFEDIT_region_IROM1_start__ != 0x0 || __ICFEDIT_region_IROM1_end__ != 0x0); +define symbol use_IROM2 = (__ICFEDIT_region_IROM2_start__ != 0x0 || __ICFEDIT_region_IROM2_end__ != 0x0); +define symbol use_EROM1 = (__ICFEDIT_region_EROM1_start__ != 0x0 || __ICFEDIT_region_EROM1_end__ != 0x0); +define symbol use_EROM2 = (__ICFEDIT_region_EROM2_start__ != 0x0 || __ICFEDIT_region_EROM2_end__ != 0x0); +define symbol use_EROM3 = (__ICFEDIT_region_EROM3_start__ != 0x0 || __ICFEDIT_region_EROM3_end__ != 0x0); +define symbol use_IRAM1 = (__ICFEDIT_region_IRAM1_start__ != 0x0 || __ICFEDIT_region_IRAM1_end__ != 0x0); +define symbol use_IRAM2 = (__ICFEDIT_region_IRAM2_start__ != 0x0 || __ICFEDIT_region_IRAM2_end__ != 0x0); +define symbol use_ERAM1 = (__ICFEDIT_region_ERAM1_start__ != 0x0 || __ICFEDIT_region_ERAM1_end__ != 0x0); +define symbol use_ERAM2 = (__ICFEDIT_region_ERAM2_start__ != 0x0 || __ICFEDIT_region_ERAM2_end__ != 0x0); +define symbol use_ERAM3 = (__ICFEDIT_region_ERAM3_start__ != 0x0 || __ICFEDIT_region_ERAM3_end__ != 0x0); + +if (use_IROM1) +{ + define region IROM1_region = mem:[from __ICFEDIT_region_IROM1_start__ to __ICFEDIT_region_IROM1_end__]; +} +else +{ + define region IROM1_region = []; +} + +if (use_IROM2) +{ + define region IROM2_region = mem:[from __ICFEDIT_region_IROM2_start__ to __ICFEDIT_region_IROM2_end__]; +} +else +{ + define region IROM2_region = []; +} +define region IROM_region = IROM1_region | IROM2_region; + +if (use_EROM1) +{ + define region EROM1_region = mem:[from __ICFEDIT_region_EROM1_start__ to __ICFEDIT_region_EROM1_end__]; +} +else +{ + define region EROM1_region = []; +} +if (use_EROM2) +{ + define region EROM2_region = mem:[from __ICFEDIT_region_EROM2_start__ to __ICFEDIT_region_EROM2_end__]; +} +else +{ + define region EROM2_region = []; +} +if (use_EROM3) +{ + define region EROM3_region = mem:[from __ICFEDIT_region_EROM3_start__ to __ICFEDIT_region_EROM3_end__]; +} +else +{ + define region EROM3_region = []; +} +define region EROM_region = EROM1_region | EROM2_region | EROM3_region; + +if (use_IRAM1) +{ + define region IRAM1_region = mem:[from __ICFEDIT_region_IRAM1_start__ to __ICFEDIT_region_IRAM1_end__]; +} +else +{ + define region IRAM1_region = []; +} +if (use_IRAM2) +{ + define region IRAM2_region = mem:[from __ICFEDIT_region_IRAM2_start__ to __ICFEDIT_region_IRAM2_end__]; +} +else +{ + define region IRAM2_region = []; +} +define region IRAM_region = IRAM1_region | IRAM2_region; + +if (use_ERAM1) +{ + define region ERAM1_region = mem:[from __ICFEDIT_region_ERAM1_start__ to __ICFEDIT_region_ERAM1_end__]; +} +else +{ + define region ERAM1_region = []; +} +if (use_ERAM2) +{ + define region ERAM2_region = mem:[from __ICFEDIT_region_ERAM2_start__ to __ICFEDIT_region_ERAM2_end__]; +} +else +{ + define region ERAM2_region = []; +} +if (use_ERAM3) +{ + define region ERAM3_region = mem:[from __ICFEDIT_region_ERAM3_start__ to __ICFEDIT_region_ERAM3_end__]; +} +else +{ + define region ERAM3_region = []; +} +define region ERAM_region = ERAM1_region | ERAM2_region | ERAM3_region; + +initialize by copy { readwrite }; +if (isdefinedsymbol(__USE_DLIB_PERTHREAD)) +{ + // Required in a multi-threaded application + initialize by copy with packing = none { section __DLIB_PERTHREAD }; +} + +place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec }; + +if (!isempty(IROM_region)) +{ + place in IROM_region { readonly }; +} + +if (!isempty(EROM_region)) +{ + place in EROM_region { readonly section application_specific_ro }; +} + +if (!isempty(IRAM_region)) +{ + define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { }; + define block PROC_STACK with alignment = 8, size = __ICFEDIT_size_proc_stack__ { }; + define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { }; + place at start of IRAM_region {block CSTACK }; /* <== Quantum Leaps */ + place in IRAM_region { readwrite, block PROC_STACK, block HEAP }; +} + +if (!isempty(ERAM_region)) +{ + place in ERAM_region { readwrite section application_specific_rw }; +} \ No newline at end of file diff --git a/examples/arm-cm/dpp_nucleo-c031c6_mpu/qview/dpp.py b/examples/arm-cm/dpp_nucleo-c031c6_mpu/qview/dpp.py new file mode 100644 index 00000000..73c51654 --- /dev/null +++ b/examples/arm-cm/dpp_nucleo-c031c6_mpu/qview/dpp.py @@ -0,0 +1,103 @@ +# This is an example of QView customization for a specific application +# (DPP in this case). This example animates the Phil images on the +# QView canvas. Additionally, there is a button in the middle of the screen, +# which, when clicked once pauses the DPP ("forks" are not being served). +# A second click on the button, "un-pauses" the DPP ("forks" are served +# to all hungry Philosophers). +# +# This version of the DPP customization uses the application-specific +# trace record QS_USER_00 (PHILO_STAT) produced when the status of +# a Philo changes. + +class DPP: + def __init__(self): + + # add commands to the Custom menu... + QView.custom_menu.add_command(label="Custom command", + command=self.cust_command) + + # configure the custom QView.canvas... + QView.show_canvas() # make the canvas visible + QView.canvas.configure(width=400, height=260) + + # tuple of activity images (correspond to self._philo_state) + self._act_img = ( + PhotoImage(file=HOME_DIR + "/img/thinking.gif"), + PhotoImage(file=HOME_DIR + "/img/hungry.gif"), + PhotoImage(file=HOME_DIR + "/img/eating.gif"), + ) + # tuple of philo canvas images (correspond to self._philo_obj) + self._philo_img = (\ + QView.canvas.create_image(190, 57, image=self._act_img[0]), + QView.canvas.create_image(273, 100, image=self._act_img[0]), + QView.canvas.create_image(237, 185, image=self._act_img[0]), + QView.canvas.create_image(146, 185, image=self._act_img[0]), + QView.canvas.create_image(107, 100, image=self._act_img[0]) + ) + + # button images for UP and DOWN + self.img_UP = PhotoImage(file=HOME_DIR + "/img/BTN_UP.gif") + self.img_DWN = PhotoImage(file=HOME_DIR + "/img/BTN_DWN.gif") + + # images of a button for pause/serve + self.btn = QView.canvas.create_image(200, 120, image=self.img_UP) + QView.canvas.tag_bind(self.btn, "", self.cust_pause) + + # request target reset on startup... + # NOTE: Normally, for an embedded application you would like + # to start with resetting the Target, to start clean with + # Qs dictionaries, etc. + reset_target() + + # on_reset() callback + def on_reset(self): + # clear the lists + self._philo_obj = [0, 0, 0, 0, 0] + self._philo_state = [0, 0, 0] + + # on_run() callback + def on_run(self): + glb_filter("QS_USER_00") + + # NOTE: the names of objects for current_obj() must match + # the QS Object Dictionaries produced by the application. + current_obj(OBJ_AO, "Table_inst") + + # turn lists into tuples for better performance + self._philo_obj = tuple(self._philo_obj) + self._philo_state = tuple(self._philo_state) + + + # example of a custom command + def cust_command(self): + command(1, 12345) + + # example of a custom interaction with a canvas object (pause/serve) + def cust_pause(self, event): + if QView.canvas.itemcget(self.btn, "image") != str(self.img_UP): + QView.canvas.itemconfig(self.btn, image=self.img_UP) + post("SERVE_SIG") + QView.print_text("Table SERVING") + else: + QView.canvas.itemconfig(self.btn, image=self.img_DWN) + post("PAUSE_SIG") + QView.print_text("Table PAUSED") + + # Intercept the QS_USER_00 application-specific trace record. + # This record has the following structure (see bsp.c:displayPhilStat()): + # Seq-Num, Record-ID, Timestamp, format-byte, Philo-num, + # format-byte, Zero-terminated string (status) + def QS_USER_00(self, packet): + # unpack: Timestamp->data[0], Philo-num->data[1], status->data[3] + data = qunpack("xxTxBxZ", packet) + i = data[1] + j = ("t", "h", "e").index(data[2][0]) # the first letter + + # animate the given philo image according to its activity + QView.canvas.itemconfig(self._philo_img[i], image=self._act_img[j]) + + # print a message to the text view + QView.print_text("%010d Philo %1d is %s"%(data[0], i, data[2])) + +#============================================================================= +QView.customize(DPP()) # set the QView customization diff --git a/examples/arm-cm/dpp_nucleo-c031c6_mpu/qview/dpp1.py b/examples/arm-cm/dpp_nucleo-c031c6_mpu/qview/dpp1.py new file mode 100644 index 00000000..d93f7b6d --- /dev/null +++ b/examples/arm-cm/dpp_nucleo-c031c6_mpu/qview/dpp1.py @@ -0,0 +1,147 @@ +# This is an example of QView customization for a specific application +# (DPP in this case). This example animates the Phil images on the +# QView canvas. Additionally, there is a button in the middle of the screen, +# which, when clicked once pauses the DPP ("forks" are not being served). +# A second click on the button, "un-pauses" the DPP ("forks" are served +# to all hungry Philosophers). +# +# This version of the DPP customization uses the predefined QS_QEP_TRAN +# trace record, which provides information about the state transitions of +# the Dining Philosophers. The example also demonstrates how to intercept +# the QS "dictionary" records QS_OBJ_DICT and QS_FUN_DICT to extract the +# information about the addresses of the Philosopher objects and the states +# of their state machines. + +class DPP: + def __init__(self): + + # add commands to the Custom menu... + QView.custom_menu.add_command(label="Custom command", + command=self.cust_command) + + # configure the custom QView.canvas... + QView.show_canvas() # make the canvas visible + QView.canvas.configure(width=400, height=260) + + # tuple of activity images (correspond to self._philo_state) + self._act_img = ( + PhotoImage(file=HOME_DIR + "/img/thinking.gif"), + PhotoImage(file=HOME_DIR + "/img/hungry.gif"), + PhotoImage(file=HOME_DIR + "/img/eating.gif"), + ) + # tuple of philo canvas images (correspond to self._philo_obj) + self._philo_img = (\ + QView.canvas.create_image(190, 57, image=self._act_img[0]), + QView.canvas.create_image(273, 100, image=self._act_img[0]), + QView.canvas.create_image(237, 185, image=self._act_img[0]), + QView.canvas.create_image(146, 185, image=self._act_img[0]), + QView.canvas.create_image(107, 100, image=self._act_img[0]) + ) + + # button images for UP and DOWN + self.img_UP = PhotoImage(file=HOME_DIR + "/img/BTN_UP.gif") + self.img_DWN = PhotoImage(file=HOME_DIR + "/img/BTN_DWN.gif") + + # images of a button for pause/serve + self.btn = QView.canvas.create_image(200, 120, image=self.img_UP) + QView.canvas.tag_bind(self.btn, "", self.cust_pause) + + # request target reset on startup... + # NOTE: Normally, for an embedded application you would like + # to start with resetting the Target, to start clean with + # Qs dictionaries, etc. + reset_target() + + + # on_reset() callback invoked when Target-reset packet is received + # NOTE: the QS dictionaries are not known at this time yet, so + # this callback shouild generally not set filters or current objects + def on_reset(self): + # (re)set the lists + self._philo_obj = [0, 0, 0, 0, 0] + self._philo_state = [0, 0, 0] + + # on_run() callback invoked when the QF_RUN packet is received + # NOTE: the QS dictionaries are typically known at this time yet, so + # this callback can set filters or current objects + def on_run(self): + glb_filter("QS_QEP_TRAN") + + # NOTE: the names of objects for current_obj() must match + # the QS Object Dictionaries produced by the application. + current_obj(OBJ_AO, "Table_inst") + + # turn lists into tuples for better performance + self._philo_obj = tuple(self._philo_obj) + self._philo_state = tuple(self._philo_state) + + + # example of a custom command + def cust_command(self): + command(1, 12345) + + # example of a custom interaction with a canvas object (pause/serve) + def cust_pause(self, event): + if QView.canvas.itemcget(self.btn, "image") != str(self.img_UP): + QView.canvas.itemconfig(self.btn, image=self.img_UP) + post("SERVE_SIG") + QView.print_text("Table SERVING") + else: + QView.canvas.itemconfig(self.btn, image=self.img_DWN) + post("PAUSE_SIG") + QView.print_text("Table PAUSED") + + # Intercept the QS_OBJ_DICT predefined trace record. + # This record has the following structure: + # Seq-Num, Record-ID, Object-ptr, Zero-terminated string + def QS_OBJ_DICT(self, packet): + data = qunpack("xxOZ", packet) + try: + # NOTE: the names of objects must match the QS Object Dictionaries + # produced by the application. + i = ("Philo_inst[0]", + "Philo_inst[1]", + "Philo_inst[2]", + "Philo_inst[3]", + "Philo_inst[4]").index(data[1]) + self._philo_obj[i] = data[0] + except: + pass # dictionary for a different object + + # Intercept the QS_FUN_DICT predefined trace record. + # This record has the following structure: + # Seq-Num, Record-ID, Function-ptr, Zero-terminated string + def QS_FUN_DICT(self, packet): + data = qunpack("xxFZ", packet) + try: + # NOTE: the names of states must match the QS Object Dictionaries + # produced by the application. + j = ("Philo_thinking", + "Philo_hungry", + "Philo_eating").index(data[1]) + self._philo_state[j] = data[0] + except: + pass # dictionary for a different state + + # Intercept the QS_QEP_TRAN predefined trace record. + # This record has the following structure (see qep_hsm.c): + # Seq-Num, Record-ID, Timestamp, Signal, Object-ptr, + # Function-ptr (source state), Function-ptr (new active state) + def QS_QEP_TRAN(self, packet): + data = qunpack("xxTSOFF", packet) + try: + i = self._philo_obj.index(data[2]) + j = self._philo_state.index(data[4]) + + # animate the given philo image according to its activity + QView.canvas.itemconfig(self._philo_img[i], + image=self._act_img[j]) + # print a message to the text view + QView.print_text("%010d Philo %d is %s"\ + %(data[0], i, ("thinking", "hungry", "eating")[j])) + except: + pass # state-entry in a different object + +#============================================================================= +# instantiate the DPP class and set it as the QView customization +QView.customize(DPP()) diff --git a/examples/arm-cm/dpp_nucleo-c031c6_mpu/qview/img/BTN_DWN.gif b/examples/arm-cm/dpp_nucleo-c031c6_mpu/qview/img/BTN_DWN.gif new file mode 100644 index 00000000..36d8c790 Binary files /dev/null and b/examples/arm-cm/dpp_nucleo-c031c6_mpu/qview/img/BTN_DWN.gif differ diff --git a/examples/arm-cm/dpp_nucleo-c031c6_mpu/qview/img/BTN_UP.gif b/examples/arm-cm/dpp_nucleo-c031c6_mpu/qview/img/BTN_UP.gif new file mode 100644 index 00000000..3246ff98 Binary files /dev/null and b/examples/arm-cm/dpp_nucleo-c031c6_mpu/qview/img/BTN_UP.gif differ diff --git a/examples/arm-cm/dpp_nucleo-c031c6_mpu/qview/img/eating.gif b/examples/arm-cm/dpp_nucleo-c031c6_mpu/qview/img/eating.gif new file mode 100644 index 00000000..632b9d23 Binary files /dev/null and b/examples/arm-cm/dpp_nucleo-c031c6_mpu/qview/img/eating.gif differ diff --git a/examples/arm-cm/dpp_nucleo-c031c6_mpu/qview/img/hungry.gif b/examples/arm-cm/dpp_nucleo-c031c6_mpu/qview/img/hungry.gif new file mode 100644 index 00000000..dc144db9 Binary files /dev/null and b/examples/arm-cm/dpp_nucleo-c031c6_mpu/qview/img/hungry.gif differ diff --git a/examples/arm-cm/dpp_nucleo-c031c6_mpu/qview/img/thinking.gif b/examples/arm-cm/dpp_nucleo-c031c6_mpu/qview/img/thinking.gif new file mode 100644 index 00000000..ec684ee5 Binary files /dev/null and b/examples/arm-cm/dpp_nucleo-c031c6_mpu/qview/img/thinking.gif differ diff --git a/examples/arm-cm/dpp_nucleo-c031c6_mpu/qview/qview-dpp.bat b/examples/arm-cm/dpp_nucleo-c031c6_mpu/qview/qview-dpp.bat new file mode 100644 index 00000000..b36e43d6 --- /dev/null +++ b/examples/arm-cm/dpp_nucleo-c031c6_mpu/qview/qview-dpp.bat @@ -0,0 +1,8 @@ +@setlocal + +if "%QTOOLS%"=="" ( + set QTOOLS=C:\qp\qtools +) +python3 %QTOOLS%\qview\qview.py dpp.py + +@endlocal diff --git a/examples/arm-cm/dpp_nucleo-c031c6_mpu/qview/qview-dpp.lnk b/examples/arm-cm/dpp_nucleo-c031c6_mpu/qview/qview-dpp.lnk new file mode 100644 index 00000000..a47d4d8b Binary files /dev/null and b/examples/arm-cm/dpp_nucleo-c031c6_mpu/qview/qview-dpp.lnk differ diff --git a/examples/arm-cm/dpp_nucleo-c031c6_mpu/qview/qview-dpp1.bat b/examples/arm-cm/dpp_nucleo-c031c6_mpu/qview/qview-dpp1.bat new file mode 100644 index 00000000..8bdb9ce5 --- /dev/null +++ b/examples/arm-cm/dpp_nucleo-c031c6_mpu/qview/qview-dpp1.bat @@ -0,0 +1,8 @@ +@setlocal + +if "%QTOOLS%"=="" ( + set QTOOLS=C:\qp\qtools +) +python3 %QTOOLS%\qview\qview.py dpp1.py + +@endlocal diff --git a/examples/arm-cm/dpp_nucleo-c031c6_mpu/qview/qview-dpp1.lnk b/examples/arm-cm/dpp_nucleo-c031c6_mpu/qview/qview-dpp1.lnk new file mode 100644 index 00000000..caf9b345 Binary files /dev/null and b/examples/arm-cm/dpp_nucleo-c031c6_mpu/qview/qview-dpp1.lnk differ diff --git a/examples/arm-cm/dpp_nucleo-c031c6_mpu/qxk/armclang/dpp-qxk.sct b/examples/arm-cm/dpp_nucleo-c031c6_mpu/qxk/armclang/dpp-qxk.sct new file mode 100644 index 00000000..100826b8 --- /dev/null +++ b/examples/arm-cm/dpp_nucleo-c031c6_mpu/qxk/armclang/dpp-qxk.sct @@ -0,0 +1,23 @@ +; ************************************************************* +; *** Scatter-Loading Description File generated by uVision *** +; +; Adapted by Quantum Leaps: +; moved STACK as the first section in RW_STACK +; ************************************************************* + +LR_IROM1 0x08000000 0x00008000 { ; load region size_region + ER_IROM1 0x08000000 0x00008000 { ; load address = execution address + *.o (RESET, +First) + *(InRoot$$Sections) + .ANY (+RO) + .ANY (+XO) + } + + RW_STACK 0x20000000 { + * (STACK, +First) + } + RW_IRAM1 +0 (0x00003000 - 2048) { + .ANY (+RW +ZI) + } +} + diff --git a/examples/arm-cm/dpp_nucleo-c031c6_mpu/qxk/armclang/dpp-qxk.uvoptx b/examples/arm-cm/dpp_nucleo-c031c6_mpu/qxk/armclang/dpp-qxk.uvoptx new file mode 100644 index 00000000..450fcccb --- /dev/null +++ b/examples/arm-cm/dpp_nucleo-c031c6_mpu/qxk/armclang/dpp-qxk.uvoptx @@ -0,0 +1,1108 @@ + + + + 1.0 + +
### uVision Project, (C) Keil Software
+ + + *.c + *.s*; *.src; *.a* + *.obj; *.o + *.lib + *.txt; *.h; *.inc; *.md + *.plm + *.cpp + 0 + + + + 0 + 0 + + + + dpp-dbg + 0x4 + ARM-ADS + + 12000000 + + 1 + 1 + 0 + 1 + 0 + + + 1 + 65535 + 0 + 0 + 0 + + + 79 + 66 + 8 + .\dbg\ + + + 1 + 1 + 1 + 0 + 1 + 1 + 0 + 1 + 0 + 0 + 0 + 0 + + + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + + + 1 + 0 + 1 + + 18 + + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + 0 + 1 + 1 + 0 + 0 + 1 + 0 + 0 + 6 + + + + + + + + + + + STLink\ST-LINKIII-KEIL_SWO.dll + + + + 0 + ST-LINKIII-KEIL_SWO + -U066BFF505153848667095842 -O206 -SF10000 -C0 -A0 -I0 -HNlocalhost -HP7184 -P1 -N00("ARM CoreSight SW-DP (ARM Core") -D00(0BC11477) -L00(0) -TO65554 -TC10000000 -TT10000000 -TP21 -TDS8007 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -FO7 -FD20000000 -FC1000 -FN1 -FF0STM32C0x_32.FLM -FS08000000 -FL08000 -FP0($$Device:STM32C031C6Tx$CMSIS\Flash\STM32C0x_32.FLM) + + + 0 + UL2CM3 + -U -O206 -S8 -C0 -P00 -N00("") -D00(00000000) -L00(0) -TO65554 -TC10000000 -TT10000000 -TP21 -TDS8007 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -FO7 -FD20000000 -FC1000 -FN1 -FF0STM32C0x_32.FLM -FS08000000 -FL08000 -FP0($$Device:STM32C031C6Tx$CMSIS\Flash\STM32C0x_32.FLM) + + + 0 + DLGUARM + (105=-1,-1,-1,-1,0) + + + 0 + ARMRTXEVENTFLAGS + -L70 -Z18 -C0 -M0 -T1 + + + 0 + DLGTARM + (1010=-1,-1,-1,-1,0)(1007=-1,-1,-1,-1,0)(1008=-1,-1,-1,-1,0)(1012=-1,-1,-1,-1,0)(1009=-1,-1,-1,-1,0) + + + 0 + ARMDBGFLAGS + + + + + + + 1 + 2 + 0x20000200 + 0 + + + + + 2 + 0 + 0x400 + 0 + + + + 0 + + + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + + + + 0 + 0 + 0 + + + + + + + + + + 1 + 0 + 0 + 2 + 10000000 + + + + + + dpp-rel + 0x4 + ARM-ADS + + 12000000 + + 1 + 1 + 0 + 1 + 0 + + + 1 + 65535 + 0 + 0 + 0 + + + 79 + 66 + 8 + .\rel\ + + + 1 + 1 + 1 + 0 + 1 + 1 + 0 + 1 + 0 + 0 + 0 + 0 + + + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + + + 1 + 0 + 0 + + 18 + + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + 0 + 1 + 1 + 0 + 0 + 1 + 0 + 0 + 6 + + + + + + + + + + + STLink\ST-LINKIII-KEIL_SWO.dll + + + + 0 + UL2CM3 + UL2CM3(-S0 -C0 -P0 ) -FN1 -FC1000 -FD20000000 -FF0STM32C0x_32 -FL08000 -FS08000000 -FP0($$Device:STM32C031C6Tx$CMSIS\Flash\STM32C0x_32.FLM) + + + 0 + ST-LINKIII-KEIL_SWO + UL2CM3(-S0 -C0 -P0 ) -FN1 -FC1000 -FD20000000 -FF0STM32C0x_32 -FL08000 -FS08000000 -FP0($$Device:STM32C031C6Tx$CMSIS\Flash\STM32C0x_32.FLM) + + + 0 + DLGUARM + (105=-1,-1,-1,-1,0) + + + 0 + ARMRTXEVENTFLAGS + -L70 -Z18 -C0 -M0 -T1 + + + 0 + DLGTARM + (1010=-1,-1,-1,-1,0)(1007=-1,-1,-1,-1,0)(1008=-1,-1,-1,-1,0)(1009=-1,-1,-1,-1,0) + + + 0 + ARMDBGFLAGS + + + + + + + 1 + 2 + 0x20000200 + 0 + + + + + 2 + 0 + 0x400 + 0 + + + + 0 + + + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + + + + 0 + 0 + 0 + + + + + + + + + + 1 + 1 + 0 + 2 + 10000000 + + + + + + dpp-spy + 0x4 + ARM-ADS + + 12000000 + + 1 + 1 + 0 + 1 + 0 + + + 1 + 65535 + 0 + 0 + 0 + + + 79 + 66 + 8 + .\spy\ + + + 1 + 1 + 1 + 0 + 1 + 1 + 0 + 1 + 0 + 0 + 0 + 0 + + + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + + + 1 + 0 + 0 + + 18 + + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + 0 + 1 + 1 + 0 + 0 + 1 + 0 + 0 + 6 + + + + + + + + + + + STLink\ST-LINKIII-KEIL_SWO.dll + + + + 0 + UL2CM3 + UL2CM3(-S0 -C0 -P0 ) -FN1 -FC1000 -FD20000000 -FF0STM32C0x_32 -FL08000 -FS08000000 -FP0($$Device:STM32C031C6Tx$CMSIS\Flash\STM32C0x_32.FLM) + + + 0 + ST-LINKIII-KEIL_SWO + -U-O206 -O206 -SF10000 -C0 -A0 -I0 -HNlocalhost -HP7184 -P1 -N00("ARM CoreSight SW-DP (ARM Core") -D00(0BC11477) -L00(0) -TO131090 -TC10000000 -TT10000000 -TP21 -TDS8007 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -FO7 -FD20000000 -FC1000 -FN1 -FF0STM32C0x_32.FLM -FS08000000 -FL08000 -FP0($$Device:STM32C031C6Tx$CMSIS\Flash\STM32C0x_32.FLM) + + + 0 + DLGUARM + (105=-1,-1,-1,-1,0) + + + 0 + ARMRTXEVENTFLAGS + -L70 -Z18 -C0 -M0 -T1 + + + 0 + DLGTARM + (1010=-1,-1,-1,-1,0)(1007=-1,-1,-1,-1,0)(1008=-1,-1,-1,-1,0)(1012=3241,488,3716,802,1)(1009=-1,-1,-1,-1,0) + + + 0 + ARMDBGFLAGS + + + + + + + 1 + 2 + 0x20000200 + 0 + + + + + 2 + 0 + 0x400 + 0 + + + + 0 + + + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + + + + 0 + 0 + 0 + + + + + + + + + + 1 + 0 + 0 + 2 + 10000000 + + + + + + Source Code + 1 + 0 + 0 + 0 + + 1 + 1 + 1 + 0 + 0 + 0 + ..\bsp.c + bsp.c + 0 + 0 + + + 1 + 2 + 5 + 0 + 0 + 0 + ..\..\bsp.h + bsp.h + 0 + 0 + + + 1 + 3 + 5 + 0 + 0 + 0 + ..\..\dpp.h + dpp.h + 0 + 0 + + + 1 + 4 + 1 + 0 + 0 + 0 + ..\..\philo.c + philo.c + 0 + 0 + + + 1 + 5 + 1 + 0 + 0 + 0 + ..\..\table.c + table.c + 0 + 0 + + + 1 + 6 + 5 + 0 + 0 + 0 + .\dpp-qxk.sct + dpp-qxk.sct + 0 + 0 + + + 1 + 7 + 1 + 0 + 0 + 0 + ..\xthread1.c + xthread1.c + 0 + 0 + + + 1 + 8 + 1 + 0 + 0 + 0 + ..\xthread2.c + xthread2.c + 0 + 0 + + + 1 + 9 + 1 + 0 + 0 + 0 + ..\..\main.c + main.c + 0 + 0 + + + + + nucleo-c031c6 + 1 + 0 + 0 + 0 + + 2 + 10 + 5 + 0 + 0 + 0 + ..\..\..\..\..\3rd_party\nucleo-c031c6\stm32c0xx.h + stm32c0xx.h + 0 + 0 + + + 2 + 11 + 5 + 0 + 0 + 0 + ..\..\..\..\..\3rd_party\nucleo-c031c6\stm32c031xx.h + stm32c031xx.h + 0 + 0 + + + 2 + 12 + 1 + 0 + 0 + 0 + ..\..\..\..\..\3rd_party\nucleo-c031c6\system_stm32c0xx.c + system_stm32c0xx.c + 0 + 0 + + + 2 + 13 + 2 + 0 + 0 + 0 + ..\..\..\..\..\3rd_party\nucleo-c031c6\arm\startup_stm32c031xx.s + startup_stm32c031xx.s + 0 + 0 + + + + + QP + 1 + 0 + 0 + 0 + + 3 + 14 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qf\qep_hsm.c + qep_hsm.c + 0 + 0 + + + 3 + 15 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qf\qep_msm.c + qep_msm.c + 0 + 0 + + + 3 + 16 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qf\qf_act.c + qf_act.c + 0 + 0 + + + 3 + 17 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qf\qf_actq.c + qf_actq.c + 0 + 0 + + + 3 + 18 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qf\qf_defer.c + qf_defer.c + 0 + 0 + + + 3 + 19 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qf\qf_dyn.c + qf_dyn.c + 0 + 0 + + + 3 + 20 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qf\qf_mem.c + qf_mem.c + 0 + 0 + + + 3 + 21 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qf\qf_ps.c + qf_ps.c + 0 + 0 + + + 3 + 22 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qf\qf_qact.c + qf_qact.c + 0 + 0 + + + 3 + 23 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qf\qf_qeq.c + qf_qeq.c + 0 + 0 + + + 3 + 24 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qf\qf_qmact.c + qf_qmact.c + 0 + 0 + + + 3 + 25 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qf\qf_time.c + qf_time.c + 0 + 0 + + + 3 + 26 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qxk\qxk.c + qxk.c + 0 + 0 + + + 3 + 27 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qxk\qxk_mutex.c + qxk_mutex.c + 0 + 0 + + + 3 + 28 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qxk\qxk_sema.c + qxk_sema.c + 0 + 0 + + + 3 + 29 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qxk\qxk_xthr.c + qxk_xthr.c + 0 + 0 + + + + + QP_port + 1 + 0 + 0 + 0 + + 4 + 30 + 5 + 0 + 0 + 0 + ..\..\..\..\..\ports\arm-cm\qxk\armclang\qep_port.h + qep_port.h + 0 + 0 + + + 4 + 31 + 5 + 0 + 0 + 0 + ..\..\..\..\..\ports\arm-cm\qxk\armclang\qf_port.h + qf_port.h + 0 + 0 + + + 4 + 32 + 5 + 0 + 0 + 0 + ..\..\..\..\..\ports\arm-cm\qxk\armclang\qs_port.h + qs_port.h + 0 + 0 + + + 4 + 33 + 1 + 0 + 0 + 0 + ..\..\..\..\..\ports\arm-cm\qxk\armclang\qxk_port.c + qxk_port.c + 0 + 0 + + + 4 + 34 + 5 + 0 + 0 + 0 + ..\..\..\..\..\ports\arm-cm\qxk\armclang\qxk_port.h + qxk_port.h + 0 + 0 + + + + + QS + 1 + 0 + 0 + 0 + + 5 + 35 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qs\qs.c + qs.c + 0 + 0 + + + 5 + 36 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qs\qs_fp.c + qs_fp.c + 0 + 0 + + + 5 + 37 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qs\qs_rx.c + qs_rx.c + 0 + 0 + + + 5 + 38 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qs\qstamp.c + qstamp.c + 0 + 0 + + + +
diff --git a/examples/arm-cm/dpp_nucleo-c031c6_mpu/qxk/armclang/dpp-qxk.uvprojx b/examples/arm-cm/dpp_nucleo-c031c6_mpu/qxk/armclang/dpp-qxk.uvprojx new file mode 100644 index 00000000..2e616045 --- /dev/null +++ b/examples/arm-cm/dpp_nucleo-c031c6_mpu/qxk/armclang/dpp-qxk.uvprojx @@ -0,0 +1,1928 @@ + + + + 2.1 + +
### uVision Project, (C) Keil Software
+ + + + dpp-dbg + 0x4 + ARM-ADS + 6160000::V6.16::ARMCLANG + 1 + + + STM32C031C6Tx + STMicroelectronics + Keil.STM32C0xx_DFP.1.0.0 + https://www.keil.com/pack/ + IRAM(0x20000000,0x00003000) IROM(0x08000000,0x00008000) CPUTYPE("Cortex-M0+") CLOCK(12000000) ELITTLE + + + UL2CM3(-S0 -C0 -P0 -FD20000000 -FC1000 -FN1 -FF0STM32C0x_32 -FS08000000 -FL08000 -FP0($$Device:STM32C031C6Tx$CMSIS\Flash\STM32C0x_32.FLM)) + 0 + $$Device:STM32C031C6Tx$Drivers\CMSIS\Device\ST\STM32C0xx\Include\stm32c0xx.h + + + + + + + + + + $$Device:STM32C031C6Tx$CMSIS\SVD\STM32C031.svd + 0 + 0 + + + + + + + 0 + 0 + 0 + 0 + 1 + + .\dbg\ + dpp-qxk + 1 + 0 + 0 + 1 + 1 + .\dbg\ + 1 + 0 + 0 + + 0 + 0 + + + 0 + 0 + 0 + 0 + + + 1 + 0 + cmd /c "del .\dbg\qstamp.o" + + 0 + 0 + 0 + 0 + + + 1 + 0 + fromelf --bin --output .\dbg\dpp-qxk.bin .\dbg\dpp-qxk.axf + + 0 + 0 + 0 + 0 + + 0 + + + + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 3 + + + 1 + + + SARMCM3.DLL + -REMAP-MPU + DARMCM1.DLL + -pCM0+ + SARMCM3.DLL + -MPU + TARMCM1.DLL + -pCM0+ + + + + 1 + 0 + 0 + 0 + 16 + + + + + 1 + 0 + 0 + 1 + 1 + 4096 + + 1 + BIN\UL2CM3.DLL + "" () + + + + + 0 + + + + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + 1 + 0 + 0 + 0 + 0 + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + "Cortex-M0+" + + 0 + 0 + 0 + 1 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 8 + 0 + 0 + 0 + 0 + 3 + 3 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 1 + 0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x20000000 + 0x3000 + + + 1 + 0x8000000 + 0x8000 + + + 0 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x8000000 + 0x8000 + + + 1 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x20000000 + 0x3000 + + + 0 + 0x0 + 0x0 + + + + + + 0 + 1 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 3 + 0 + 1 + 0 + 0 + 0 + 3 + 3 + 0 + 0 + 0 + 0 + 0 + + + QP_CONFIG + + ..\..;..\..\..\..\..\include;..\..\..\..\..\ports\arm-cm\qxk\armclang;..\..\..\..\..\3rd_party\CMSIS\Include;..\..\..\..\..\3rd_party\nucleo-c031c6 + + + + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 4 + + + Stack_Size=2048 Heap_Size=16 + + + + + + 0 + 0 + 0 + 0 + 1 + 0 + 0x00000000 + 0x20000000 + + .\dpp-qxk.sct + + + --entry Reset_Handler + + + + + + + + Source Code + + + bsp.c + 1 + ..\bsp.c + + + bsp.h + 5 + ..\..\bsp.h + + + dpp.h + 5 + ..\..\dpp.h + + + philo.c + 1 + ..\..\philo.c + + + table.c + 1 + ..\..\table.c + + + dpp-qxk.sct + 5 + .\dpp-qxk.sct + + + xthread1.c + 1 + ..\xthread1.c + + + xthread2.c + 1 + ..\xthread2.c + + + main.c + 1 + ..\..\main.c + + + + + nucleo-c031c6 + + + stm32c0xx.h + 5 + ..\..\..\..\..\3rd_party\nucleo-c031c6\stm32c0xx.h + + + stm32c031xx.h + 5 + ..\..\..\..\..\3rd_party\nucleo-c031c6\stm32c031xx.h + + + system_stm32c0xx.c + 1 + ..\..\..\..\..\3rd_party\nucleo-c031c6\system_stm32c0xx.c + + + startup_stm32c031xx.s + 2 + ..\..\..\..\..\3rd_party\nucleo-c031c6\arm\startup_stm32c031xx.s + + + + + QP + + + qep_hsm.c + 1 + ..\..\..\..\..\src\qf\qep_hsm.c + + + qep_msm.c + 1 + ..\..\..\..\..\src\qf\qep_msm.c + + + qf_act.c + 1 + ..\..\..\..\..\src\qf\qf_act.c + + + qf_actq.c + 1 + ..\..\..\..\..\src\qf\qf_actq.c + + + qf_defer.c + 1 + ..\..\..\..\..\src\qf\qf_defer.c + + + qf_dyn.c + 1 + ..\..\..\..\..\src\qf\qf_dyn.c + + + qf_mem.c + 1 + ..\..\..\..\..\src\qf\qf_mem.c + + + qf_ps.c + 1 + ..\..\..\..\..\src\qf\qf_ps.c + + + qf_qact.c + 1 + ..\..\..\..\..\src\qf\qf_qact.c + + + qf_qeq.c + 1 + ..\..\..\..\..\src\qf\qf_qeq.c + + + qf_qmact.c + 1 + ..\..\..\..\..\src\qf\qf_qmact.c + + + qf_time.c + 1 + ..\..\..\..\..\src\qf\qf_time.c + + + qxk.c + 1 + ..\..\..\..\..\src\qxk\qxk.c + + + qxk_mutex.c + 1 + ..\..\..\..\..\src\qxk\qxk_mutex.c + + + qxk_sema.c + 1 + ..\..\..\..\..\src\qxk\qxk_sema.c + + + qxk_xthr.c + 1 + ..\..\..\..\..\src\qxk\qxk_xthr.c + + + + + QP_port + + + qep_port.h + 5 + ..\..\..\..\..\ports\arm-cm\qxk\armclang\qep_port.h + + + qf_port.h + 5 + ..\..\..\..\..\ports\arm-cm\qxk\armclang\qf_port.h + + + qs_port.h + 5 + ..\..\..\..\..\ports\arm-cm\qxk\armclang\qs_port.h + + + qxk_port.c + 1 + ..\..\..\..\..\ports\arm-cm\qxk\armclang\qxk_port.c + + + qxk_port.h + 5 + ..\..\..\..\..\ports\arm-cm\qxk\armclang\qxk_port.h + + + + + QS + + + 0 + 0 + 0 + 0 + 0 + 0 + 2 + 2 + 2 + 2 + 11 + + + 1 + + + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 0 + 0 + 0 + 0 + 2 + + + + + + + + + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + + + + + + + + + + + + qs.c + 1 + ..\..\..\..\..\src\qs\qs.c + + + qs_fp.c + 1 + ..\..\..\..\..\src\qs\qs_fp.c + + + qs_rx.c + 1 + ..\..\..\..\..\src\qs\qs_rx.c + + + qstamp.c + 1 + ..\..\..\..\..\src\qs\qstamp.c + + + + + + + dpp-rel + 0x4 + ARM-ADS + 6160000::V6.16::ARMCLANG + 1 + + + STM32C031C6Tx + STMicroelectronics + Keil.STM32C0xx_DFP.1.0.0 + https://www.keil.com/pack/ + IRAM(0x20000000,0x00003000) IROM(0x08000000,0x00008000) CPUTYPE("Cortex-M0+") CLOCK(12000000) ELITTLE + + + UL2CM3(-S0 -C0 -P0 -FD20000000 -FC1000 -FN1 -FF0STM32C0x_32 -FS08000000 -FL08000 -FP0($$Device:STM32C031C6Tx$CMSIS\Flash\STM32C0x_32.FLM)) + 0 + $$Device:STM32C031C6Tx$Drivers\CMSIS\Device\ST\STM32C0xx\Include\stm32c0xx.h + + + + + + + + + + $$Device:STM32C031C6Tx$CMSIS\SVD\STM32C031.svd + 0 + 0 + + + + + + + 0 + 0 + 0 + 0 + 1 + + .\rel\ + dpp-qxk + 1 + 0 + 0 + 0 + 0 + .\rel\ + 1 + 0 + 0 + + 0 + 0 + + + 0 + 0 + 0 + 0 + + + 1 + 0 + cmd /c "del .\rel\qstamp.o" + + 0 + 0 + 0 + 0 + + + 1 + 0 + fromelf --bin --output .\rel\dpp-qxk.bin .\rel\dpp-qxk.axf + + 0 + 0 + 0 + 0 + + 0 + + + + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 3 + + + 1 + + + SARMCM3.DLL + -REMAP-MPU + DARMCM1.DLL + -pCM0+ + SARMCM3.DLL + -MPU + TARMCM1.DLL + -pCM0+ + + + + 1 + 0 + 0 + 0 + 16 + + + + + 1 + 0 + 0 + 1 + 1 + 4097 + + 1 + BIN\UL2CM3.DLL + + + + + + 0 + + + + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + 1 + 0 + 0 + 0 + 0 + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + "Cortex-M0+" + + 0 + 0 + 0 + 1 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 8 + 0 + 0 + 0 + 0 + 3 + 3 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 1 + 0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x20000000 + 0x3000 + + + 1 + 0x8000000 + 0x8000 + + + 0 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x8000000 + 0x8000 + + + 1 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x20000000 + 0x3000 + + + 0 + 0x0 + 0x0 + + + + + + 0 + 6 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 3 + 0 + 1 + 0 + 0 + 0 + 3 + 3 + 0 + 0 + 0 + 0 + 0 + + + NDEBUG,QP_CONFIG + + ..\..;..\..\..\..\..\include;..\..\..\..\..\ports\arm-cm\qxk\armclang;..\..\..\..\..\3rd_party\CMSIS\Include;..\..\..\..\..\3rd_party\nucleo-c031c6 + + + + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 4 + + + Stack_Size=2048 Heap_Size=16 + + + + + + 0 + 0 + 0 + 0 + 1 + 0 + 0x00000000 + 0x20000000 + + .\dpp-qxk.sct + + + --entry Reset_Handler + + + + + + + + Source Code + + + bsp.c + 1 + ..\bsp.c + + + bsp.h + 5 + ..\..\bsp.h + + + dpp.h + 5 + ..\..\dpp.h + + + philo.c + 1 + ..\..\philo.c + + + table.c + 1 + ..\..\table.c + + + dpp-qxk.sct + 5 + .\dpp-qxk.sct + + + xthread1.c + 1 + ..\xthread1.c + + + xthread2.c + 1 + ..\xthread2.c + + + main.c + 1 + ..\..\main.c + + + + + nucleo-c031c6 + + + stm32c0xx.h + 5 + ..\..\..\..\..\3rd_party\nucleo-c031c6\stm32c0xx.h + + + stm32c031xx.h + 5 + ..\..\..\..\..\3rd_party\nucleo-c031c6\stm32c031xx.h + + + system_stm32c0xx.c + 1 + ..\..\..\..\..\3rd_party\nucleo-c031c6\system_stm32c0xx.c + + + startup_stm32c031xx.s + 2 + ..\..\..\..\..\3rd_party\nucleo-c031c6\arm\startup_stm32c031xx.s + + + + + QP + + + qep_hsm.c + 1 + ..\..\..\..\..\src\qf\qep_hsm.c + + + qep_msm.c + 1 + ..\..\..\..\..\src\qf\qep_msm.c + + + qf_act.c + 1 + ..\..\..\..\..\src\qf\qf_act.c + + + qf_actq.c + 1 + ..\..\..\..\..\src\qf\qf_actq.c + + + qf_defer.c + 1 + ..\..\..\..\..\src\qf\qf_defer.c + + + qf_dyn.c + 1 + ..\..\..\..\..\src\qf\qf_dyn.c + + + qf_mem.c + 1 + ..\..\..\..\..\src\qf\qf_mem.c + + + qf_ps.c + 1 + ..\..\..\..\..\src\qf\qf_ps.c + + + qf_qact.c + 1 + ..\..\..\..\..\src\qf\qf_qact.c + + + qf_qeq.c + 1 + ..\..\..\..\..\src\qf\qf_qeq.c + + + qf_qmact.c + 1 + ..\..\..\..\..\src\qf\qf_qmact.c + + + qf_time.c + 1 + ..\..\..\..\..\src\qf\qf_time.c + + + qxk.c + 1 + ..\..\..\..\..\src\qxk\qxk.c + + + qxk_mutex.c + 1 + ..\..\..\..\..\src\qxk\qxk_mutex.c + + + qxk_sema.c + 1 + ..\..\..\..\..\src\qxk\qxk_sema.c + + + qxk_xthr.c + 1 + ..\..\..\..\..\src\qxk\qxk_xthr.c + + + + + QP_port + + + qep_port.h + 5 + ..\..\..\..\..\ports\arm-cm\qxk\armclang\qep_port.h + + + qf_port.h + 5 + ..\..\..\..\..\ports\arm-cm\qxk\armclang\qf_port.h + + + qs_port.h + 5 + ..\..\..\..\..\ports\arm-cm\qxk\armclang\qs_port.h + + + qxk_port.c + 1 + ..\..\..\..\..\ports\arm-cm\qxk\armclang\qxk_port.c + + + qxk_port.h + 5 + ..\..\..\..\..\ports\arm-cm\qxk\armclang\qxk_port.h + + + + + QS + + + 0 + 0 + 0 + 0 + 0 + 0 + 2 + 2 + 2 + 2 + 11 + + + 1 + + + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 0 + 0 + 0 + 0 + 2 + + + + + + + + + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + + + + + + + + + + + + qs.c + 1 + ..\..\..\..\..\src\qs\qs.c + + + qs_fp.c + 1 + ..\..\..\..\..\src\qs\qs_fp.c + + + qs_rx.c + 1 + ..\..\..\..\..\src\qs\qs_rx.c + + + qstamp.c + 1 + ..\..\..\..\..\src\qs\qstamp.c + + + + + + + dpp-spy + 0x4 + ARM-ADS + 6160000::V6.16::ARMCLANG + 1 + + + STM32C031C6Tx + STMicroelectronics + Keil.STM32C0xx_DFP.1.0.0 + https://www.keil.com/pack/ + IRAM(0x20000000,0x00003000) IROM(0x08000000,0x00008000) CPUTYPE("Cortex-M0+") CLOCK(12000000) ELITTLE + + + UL2CM3(-S0 -C0 -P0 -FD20000000 -FC1000 -FN1 -FF0STM32C0x_32 -FS08000000 -FL08000 -FP0($$Device:STM32C031C6Tx$CMSIS\Flash\STM32C0x_32.FLM)) + 0 + $$Device:STM32C031C6Tx$Drivers\CMSIS\Device\ST\STM32C0xx\Include\stm32c0xx.h + + + + + + + + + + $$Device:STM32C031C6Tx$CMSIS\SVD\STM32C031.svd + 0 + 0 + + + + + + + 0 + 0 + 0 + 0 + 1 + + .\spy\ + dpp-qxk + 1 + 0 + 0 + 1 + 1 + .\spy\ + 1 + 0 + 0 + + 0 + 0 + + + 0 + 0 + 0 + 0 + + + 1 + 0 + cmd /c "del .\spy\qstamp.o" + + 0 + 0 + 0 + 0 + + + 1 + 0 + fromelf --bin --output .\spy\dpp-qxk.bin .\spy\dpp-qxk.axf + + 0 + 0 + 0 + 0 + + 0 + + + + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 3 + + + 1 + + + SARMCM3.DLL + -REMAP-MPU + DARMCM1.DLL + -pCM0+ + SARMCM3.DLL + -MPU + TARMCM1.DLL + -pCM0+ + + + + 1 + 0 + 0 + 0 + 16 + + + + + 1 + 0 + 0 + 1 + 1 + 4096 + + 1 + BIN\UL2CM3.DLL + + + + + + 0 + + + + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + 1 + 0 + 0 + 0 + 0 + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + "Cortex-M0+" + + 0 + 0 + 0 + 1 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 8 + 0 + 0 + 0 + 0 + 3 + 3 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 1 + 0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x20000000 + 0x3000 + + + 1 + 0x8000000 + 0x8000 + + + 0 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x8000000 + 0x8000 + + + 1 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x20000000 + 0x3000 + + + 0 + 0x0 + 0x0 + + + + + + 0 + 2 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 3 + 0 + 1 + 0 + 0 + 0 + 3 + 3 + 0 + 0 + 0 + 0 + 0 + + + Q_SPY,QP_CONFIG + + ..\..;..\..\..\..\..\include;..\..\..\..\..\ports\arm-cm\qxk\armclang;..\..\..\..\..\3rd_party\CMSIS\Include;..\..\..\..\..\3rd_party\nucleo-c031c6 + + + + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 4 + + + Stack_Size=2048 Heap_Size=16 + + + + + + 0 + 0 + 0 + 0 + 1 + 0 + 0x00000000 + 0x20000000 + + .\dpp-qxk.sct + + + --entry Reset_Handler + + + + + + + + Source Code + + + bsp.c + 1 + ..\bsp.c + + + bsp.h + 5 + ..\..\bsp.h + + + dpp.h + 5 + ..\..\dpp.h + + + philo.c + 1 + ..\..\philo.c + + + table.c + 1 + ..\..\table.c + + + dpp-qxk.sct + 5 + .\dpp-qxk.sct + + + xthread1.c + 1 + ..\xthread1.c + + + xthread2.c + 1 + ..\xthread2.c + + + main.c + 1 + ..\..\main.c + + + + + nucleo-c031c6 + + + stm32c0xx.h + 5 + ..\..\..\..\..\3rd_party\nucleo-c031c6\stm32c0xx.h + + + stm32c031xx.h + 5 + ..\..\..\..\..\3rd_party\nucleo-c031c6\stm32c031xx.h + + + system_stm32c0xx.c + 1 + ..\..\..\..\..\3rd_party\nucleo-c031c6\system_stm32c0xx.c + + + startup_stm32c031xx.s + 2 + ..\..\..\..\..\3rd_party\nucleo-c031c6\arm\startup_stm32c031xx.s + + + + + QP + + + qep_hsm.c + 1 + ..\..\..\..\..\src\qf\qep_hsm.c + + + qep_msm.c + 1 + ..\..\..\..\..\src\qf\qep_msm.c + + + qf_act.c + 1 + ..\..\..\..\..\src\qf\qf_act.c + + + qf_actq.c + 1 + ..\..\..\..\..\src\qf\qf_actq.c + + + qf_defer.c + 1 + ..\..\..\..\..\src\qf\qf_defer.c + + + qf_dyn.c + 1 + ..\..\..\..\..\src\qf\qf_dyn.c + + + qf_mem.c + 1 + ..\..\..\..\..\src\qf\qf_mem.c + + + qf_ps.c + 1 + ..\..\..\..\..\src\qf\qf_ps.c + + + qf_qact.c + 1 + ..\..\..\..\..\src\qf\qf_qact.c + + + qf_qeq.c + 1 + ..\..\..\..\..\src\qf\qf_qeq.c + + + qf_qmact.c + 1 + ..\..\..\..\..\src\qf\qf_qmact.c + + + qf_time.c + 1 + ..\..\..\..\..\src\qf\qf_time.c + + + qxk.c + 1 + ..\..\..\..\..\src\qxk\qxk.c + + + qxk_mutex.c + 1 + ..\..\..\..\..\src\qxk\qxk_mutex.c + + + qxk_sema.c + 1 + ..\..\..\..\..\src\qxk\qxk_sema.c + + + qxk_xthr.c + 1 + ..\..\..\..\..\src\qxk\qxk_xthr.c + + + + + QP_port + + + qep_port.h + 5 + ..\..\..\..\..\ports\arm-cm\qxk\armclang\qep_port.h + + + qf_port.h + 5 + ..\..\..\..\..\ports\arm-cm\qxk\armclang\qf_port.h + + + qs_port.h + 5 + ..\..\..\..\..\ports\arm-cm\qxk\armclang\qs_port.h + + + qxk_port.c + 1 + ..\..\..\..\..\ports\arm-cm\qxk\armclang\qxk_port.c + + + qxk_port.h + 5 + ..\..\..\..\..\ports\arm-cm\qxk\armclang\qxk_port.h + + + + + QS + + + qs.c + 1 + ..\..\..\..\..\src\qs\qs.c + + + qs_fp.c + 1 + ..\..\..\..\..\src\qs\qs_fp.c + + + qs_rx.c + 1 + ..\..\..\..\..\src\qs\qs_rx.c + + + qstamp.c + 1 + ..\..\..\..\..\src\qs\qstamp.c + + + + + + + + + + + + + +
diff --git a/examples/arm-cm/dpp_nucleo-c031c6_mpu/qxk/bsp.c b/examples/arm-cm/dpp_nucleo-c031c6_mpu/qxk/bsp.c new file mode 100644 index 00000000..6c5f6fbb --- /dev/null +++ b/examples/arm-cm/dpp_nucleo-c031c6_mpu/qxk/bsp.c @@ -0,0 +1,951 @@ +//============================================================================ +// Product: DPP example, NUCLEO-C031C6 board, QXK kernel, MPU isolation +// Last updated for version 7.3.0 +// Last updated on 2023-08-28 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. +// +// This program is open source software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Alternatively, this program may be distributed and modified under the +// terms of Quantum Leaps commercial licenses, which expressly supersede +// the GNU General Public License and are specifically designed for +// licensees interested in retaining the proprietary status of their code. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Contact information: +// +// +//============================================================================ +#include "qpc.h" // QP/C real-time embedded framework +#include "dpp.h" // DPP Application interface +#include "bsp.h" // Board Support Package + +#include "stm32c0xx.h" // CMSIS-compliant header file for the MCU used +// add other drivers if necessary... + +Q_DEFINE_THIS_FILE // define the name of this file for assertions + +// Local-scope defines ----------------------------------------------------- +// LED pins available on the board (just one user LED LD4--Green on PA.5) +#define LD4_PIN 5U + +// Button pins available on the board (just one user Button B1 on PC.13) +#define B1_PIN 13U + +#ifdef Q_SPY + QSTimeCtr QS_tickTime_; + QSTimeCtr QS_tickPeriod_; + + // QSpy source IDs + static QSpyId const l_SysTick_Handler = { 0U }; + + enum AppRecords { // application-specific trace records + PHILO_STAT = QS_USER, + PAUSED_STAT, + }; + +#endif + +//---------------------------------------------------------------------------- +// MPU storage and settings... +typedef struct { + uint32_t RBAR; + uint32_t RASR; +} MPU_Region; + +//============================================================================ +// Error handler and ISRs... + +Q_NORETURN Q_onError(char const *module, int_t const id) { + // NOTE: this implementation of the assertion handler is intended only + // for debugging and MUST be changed for deployment of the application + // (assuming that you ship your production code with assertions enabled). + Q_UNUSED_PAR(module); + Q_UNUSED_PAR(id); + QS_ASSERTION(module, id, 10000U); + +#ifndef NDEBUG + // light up the user LED + GPIOA->BSRR = (1U << LD4_PIN); // turn LED on + // for debugging, hang on in an endless loop... + for (;;) { + } +#endif + + NVIC_SystemReset(); +} +//............................................................................ +void assert_failed(char const * const module, int_t const id); // prototype +void assert_failed(char const * const module, int_t const id) { + Q_onError(module, id); +} + +// ISRs used in the application ========================================== +void SysTick_Handler(void); // prototype +void SysTick_Handler(void) { + QXK_ISR_ENTRY(); // inform QXK about entering an ISR + + QTIMEEVT_TICK_X(0U, &l_SysTick_Handler); // time events at rate 0 + + // Perform the debouncing of buttons. The algorithm for debouncing + // adapted from the book "Embedded Systems Dictionary" by Jack Ganssle + // and Michael Barr, page 71. + static struct { + uint32_t depressed; + uint32_t previous; + } buttons = { 0U, 0U }; + + QF_INT_DISABLE(); + QF_MEM_SYS(); + + uint32_t current = ~GPIOC->IDR; // read Port C with Button B1 + uint32_t tmp = buttons.depressed; // save the depressed buttons + buttons.depressed |= (buttons.previous & current); // set depressed + buttons.depressed &= (buttons.previous | current); // clear released + buttons.previous = current; // update the history + tmp ^= buttons.depressed; // changed debounced depressed + current = buttons.depressed; + +#ifdef Q_SPY + tmp = SysTick->CTRL; // clear CTRL_COUNTFLAG + QS_tickTime_ += QS_tickPeriod_; // account for the clock rollover +#endif + + QF_MEM_APP(); + QF_INT_ENABLE(); + + if ((tmp & (1U << B1_PIN)) != 0U) { // debounced B1 state changed? + if ((current & (1U << B1_PIN)) != 0U) { // is B1 depressed? + static QEvt const pauseEvt = QEVT_INITIALIZER(PAUSE_SIG); + QACTIVE_PUBLISH(&pauseEvt, &l_SysTick_Handler); + } + else { // the button is released + static QEvt const serveEvt = QEVT_INITIALIZER(SERVE_SIG); + QACTIVE_PUBLISH(&serveEvt, &l_SysTick_Handler); + } + } + + QXK_ISR_EXIT(); // inform QXK about exiting an ISR +} +//............................................................................ +// interrupt handler for testing preemptions in QXK +void EXTI0_1_IRQHandler(void); // prototype +void EXTI0_1_IRQHandler(void) { + QXK_ISR_ENTRY(); // inform QXK about entering an ISR + + // for testing.. + static QEvt const testEvt = QEVT_INITIALIZER(TEST_SIG); + QACTIVE_POST(AO_Table, &testEvt, (void *)0); + + QXK_ISR_EXIT(); // inform QXK about exiting an ISR +} + +//............................................................................ +#ifdef Q_SPY +// ISR for receiving bytes from the QSPY Back-End +// NOTE: This ISR is "QF-unaware" meaning that it does not interact with +// the QF/QXK and is not disabled. Such ISRs don't need to call +// QXK_ISR_ENTRY/QXK_ISR_EXIT and they cannot post or publish events. + +void USART2_IRQHandler(void); // prototype +void USART2_IRQHandler(void) { // used in QS-RX (kernel UNAWARE interrutp) + // is RX register NOT empty? + QF_MEM_SYS(); + if ((USART2->ISR & (1U << 5)) != 0) { + uint32_t b = USART2->RDR; + QS_RX_PUT(b); + } + + QXK_ARM_ERRATUM_838869(); +} +#endif // Q_SPY + +#ifdef QF_MEM_ISOLATE +//............................................................................ +__attribute__(( used )) +void QF_onMemSys(void) { + MPU->CTRL = MPU_CTRL_ENABLE_Msk // enable the MPU + | MPU_CTRL_PRIVDEFENA_Msk; // enable background region + __ISB(); + __DSB(); +} +//............................................................................ +__attribute__(( used )) +void QF_onMemApp() { + MPU->CTRL = MPU_CTRL_ENABLE_Msk; // enable the MPU + // but do NOT enable background region + __ISB(); + __DSB(); +} +//............................................................................ +#ifdef QF_ON_CONTEXT_SW +// NOTE: the context-switch callback is called with interrupts DISABLED +void QF_onContextSw(QActive *prev, QActive *next) { + if (next != (QActive *)0) { + MPU->CTRL = 0U; // disable the MPU + + MPU_Region const * const region = + (MPU_Region const *)(next->thread); + MPU->RBAR = region[0].RBAR; + MPU->RASR = region[0].RASR; + MPU->RBAR = region[1].RBAR; + MPU->RASR = region[1].RASR; + MPU->RBAR = region[2].RBAR; + MPU->RASR = region[2].RASR; + + MPU->CTRL = MPU_CTRL_ENABLE_Msk // enable the MPU + | MPU_CTRL_PRIVDEFENA_Msk; // enable background region + __ISB(); + __DSB(); + } +} +#endif // QF_ON_CONTEXT_SW +#endif // QF_MEM_ISOLATE + +//============================================================================ + +// Stack ..................................................................... +// NOTE +// The main stack size (provided here as power of 2), MUST match the actual +// stack size defined in the linker-script/startup-code. +#define STACK_SIZE_POW2 ((uint32_t)11U) + +// Table AO................................................................... +// size of Table instance, as power-of-2 +#define TABLE_SIZE_POW2 ((uint32_t)6U) + +__attribute__((aligned((1U << TABLE_SIZE_POW2)))) +static uint8_t Table_sto[1U << TABLE_SIZE_POW2]; + +#ifdef QF_MEM_ISOLATE +static MPU_Region const MPU_Table[3] = { + { (uint32_t)Table_sto + 0x10U, //---- region #0 + ((TABLE_SIZE_POW2 - 1U) << MPU_RASR_SIZE_Pos) // size + + (3U << MPU_RASR_AP_Pos) // PA:rw/UA:rw + + (1U << MPU_RASR_XN_Pos) // XN=1 + + (1U << MPU_RASR_S_Pos) // S=1 + + (1U << MPU_RASR_C_Pos) // C=1 + + (0U << MPU_RASR_B_Pos) // B=0 + + (0U << MPU_RASR_TEX_Pos) // TEX=0 + + MPU_RASR_ENABLE_Msk }, // region enable + { GPIOA_BASE + 0x11U, //---- region #1 + ((9U - 1U) << MPU_RASR_SIZE_Pos) // 2^9=512B size + + (3U << MPU_RASR_AP_Pos) // PA:rw/UA:rw + + (1U << MPU_RASR_XN_Pos) // XN=1 + + (1U << MPU_RASR_S_Pos) // S=1 + + (0U << MPU_RASR_C_Pos) // C=0 + + (1U << MPU_RASR_B_Pos) // B=1 + + (0U << MPU_RASR_TEX_Pos) // TEX=0 + + MPU_RASR_ENABLE_Msk }, // region enable + { 0U + 0x12U, //---- region #2 + 0U }, +}; +#endif + +// Philo AOs................................................................ +// size of Philo instance, as power-of-2 +#define PHILO_SIZE_POW2 ((uint32_t)6U) + +__attribute__((aligned((1U << PHILO_SIZE_POW2)))) +static uint8_t Philo_sto[N_PHILO][1U << PHILO_SIZE_POW2]; + +#define PHILO_SHARED_SIZE_POW2 ((uint32_t)5U) +__attribute__((aligned((1U << PHILO_SHARED_SIZE_POW2)))) +static union { + uint32_t rnd_seed; + uint8_t byteso[1U << PHILO_SHARED_SIZE_POW2]; +} Philo_shared_sto; + +#ifdef QF_MEM_ISOLATE +static MPU_Region const MPU_Philo[N_PHILO][3] = { + {{ (uint32_t)Philo_sto[0] + 0x10U, //---- region #0 + ((PHILO_SIZE_POW2 - 1U) << MPU_RASR_SIZE_Pos) // size + + (3U << MPU_RASR_AP_Pos) // PA:rw/UA:rw + + (1U << MPU_RASR_XN_Pos) // XN=1 + + (1U << MPU_RASR_S_Pos) // S=1 + + (1U << MPU_RASR_C_Pos) // C=1 + + (0U << MPU_RASR_B_Pos) // B=0 + + (0U << MPU_RASR_TEX_Pos) // TEX=0 + + MPU_RASR_ENABLE_Msk }, // region enable + { (uint32_t)&Philo_shared_sto + 0x11U, //---- region #1 + ((PHILO_SHARED_SIZE_POW2 - 1U) << MPU_RASR_SIZE_Pos) // size + + (3U << MPU_RASR_AP_Pos) // PA:rw/UA:rw + + (1U << MPU_RASR_XN_Pos) // XN=1 + + (1U << MPU_RASR_S_Pos) // S=1 + + (1U << MPU_RASR_C_Pos) // C=1 + + (0U << MPU_RASR_B_Pos) // B=0 + + (0U << MPU_RASR_TEX_Pos) // TEX=0 + + MPU_RASR_ENABLE_Msk }, // region enable + { 0U + 0x12U, //---- region #2 + 0U }}, + {{ (uint32_t)Philo_sto[1] + 0x10U, //---- region #0 + ((PHILO_SIZE_POW2 - 1U) << MPU_RASR_SIZE_Pos) // size + + (3U << MPU_RASR_AP_Pos) // PA:rw/UA:rw + + (1U << MPU_RASR_XN_Pos) // XN=1 + + (1U << MPU_RASR_S_Pos) // S=1 + + (1U << MPU_RASR_C_Pos) // C=1 + + (0U << MPU_RASR_B_Pos) // B=0 + + (0U << MPU_RASR_TEX_Pos) // TEX=0 + + MPU_RASR_ENABLE_Msk }, // region enable + { (uint32_t)&Philo_shared_sto + 0x11U, //---- region #1 + ((PHILO_SHARED_SIZE_POW2 - 1U) << MPU_RASR_SIZE_Pos) // size + + (3U << MPU_RASR_AP_Pos) // PA:rw/UA:rw + + (1U << MPU_RASR_XN_Pos) // XN=1 + + (1U << MPU_RASR_S_Pos) // S=1 + + (1U << MPU_RASR_C_Pos) // C=1 + + (0U << MPU_RASR_B_Pos) // B=0 + + (0U << MPU_RASR_TEX_Pos) // TEX=0 + + MPU_RASR_ENABLE_Msk }, // region enable + { 0U + 0x12U, //---- region #2 + 0U }}, + {{ (uint32_t)Philo_sto[2] + 0x10U, //---- region #0 + ((PHILO_SIZE_POW2 - 1U) << MPU_RASR_SIZE_Pos) // size + + (3U << MPU_RASR_AP_Pos) // PA:rw/UA:rw + + (1U << MPU_RASR_XN_Pos) // XN=1 + + (1U << MPU_RASR_S_Pos) // S=1 + + (1U << MPU_RASR_C_Pos) // C=1 + + (0U << MPU_RASR_B_Pos) // B=0 + + (0U << MPU_RASR_TEX_Pos) // TEX=0 + + MPU_RASR_ENABLE_Msk }, // region enable + { (uint32_t)&Philo_shared_sto + 0x11U, //---- region #1 + ((PHILO_SHARED_SIZE_POW2 - 1U) << MPU_RASR_SIZE_Pos) // size + + (3U << MPU_RASR_AP_Pos) // PA:rw/UA:rw + + (1U << MPU_RASR_XN_Pos) // XN=1 + + (1U << MPU_RASR_S_Pos) // S=1 + + (1U << MPU_RASR_C_Pos) // C=1 + + (0U << MPU_RASR_B_Pos) // B=0 + + (0U << MPU_RASR_TEX_Pos) // TEX=0 + + MPU_RASR_ENABLE_Msk }, // region enable + { 0U + 0x12U, //---- region #2 + 0U }}, + {{ (uint32_t)Philo_sto[3] + 0x10U, //---- region #0 + ((PHILO_SIZE_POW2 - 1U) << MPU_RASR_SIZE_Pos) // size + + (3U << MPU_RASR_AP_Pos) // PA:rw/UA:rw + + (1U << MPU_RASR_XN_Pos) // XN=1 + + (1U << MPU_RASR_S_Pos) // S=1 + + (1U << MPU_RASR_C_Pos) // C=1 + + (0U << MPU_RASR_B_Pos) // B=0 + + (0U << MPU_RASR_TEX_Pos) // TEX=0 + + MPU_RASR_ENABLE_Msk }, // region enable + { (uint32_t)&Philo_shared_sto + 0x11U, //---- region #1 + ((PHILO_SHARED_SIZE_POW2 - 1U) << MPU_RASR_SIZE_Pos) // size + + (3U << MPU_RASR_AP_Pos) // PA:rw/UA:rw + + (1U << MPU_RASR_XN_Pos) // XN=1 + + (1U << MPU_RASR_S_Pos) // S=1 + + (1U << MPU_RASR_C_Pos) // C=1 + + (0U << MPU_RASR_B_Pos) // B=0 + + (0U << MPU_RASR_TEX_Pos) // TEX=0 + + MPU_RASR_ENABLE_Msk }, // region enable + { 0U + 0x12U, //---- region #2 + 0U }}, + {{ (uint32_t)Philo_sto[4] + 0x10U, //---- region #0 + ((PHILO_SIZE_POW2 - 1U) << MPU_RASR_SIZE_Pos) // size + + (3U << MPU_RASR_AP_Pos) // PA:rw/UA:rw + + (1U << MPU_RASR_XN_Pos) // XN=1 + + (1U << MPU_RASR_S_Pos) // S=1 + + (1U << MPU_RASR_C_Pos) // C=1 + + (0U << MPU_RASR_B_Pos) // B=0 + + (0U << MPU_RASR_TEX_Pos) // TEX=0 + + MPU_RASR_ENABLE_Msk }, // region enable + { (uint32_t)&Philo_shared_sto + 0x11U, //---- region #1 + ((PHILO_SHARED_SIZE_POW2 - 1U) << MPU_RASR_SIZE_Pos) // size + + (3U << MPU_RASR_AP_Pos) // PA:rw/UA:rw + + (1U << MPU_RASR_XN_Pos) // XN=1 + + (1U << MPU_RASR_S_Pos) // S=1 + + (1U << MPU_RASR_C_Pos) // C=1 + + (0U << MPU_RASR_B_Pos) // B=0 + + (0U << MPU_RASR_TEX_Pos) // TEX=0 + + MPU_RASR_ENABLE_Msk }, // region enable + { 0U + 0x12U, //---- region #2 + 0U }}, +}; +#endif + +// XThread1 thread............................................................ +#define XTHREAD1_SIZE_POW2 ((uint32_t)9U) // XThread1 instance + stack +#define XTHREAD1_STACK_SIZE ((uint32_t)448U) // Thread1 stack size + +__attribute__((aligned((1U << XTHREAD1_SIZE_POW2)))) +uint8_t XThread1_sto[1U << XTHREAD1_SIZE_POW2]; + +#ifdef QF_MEM_ISOLATE +static MPU_Region const MPU_XThread1[3] = { + { (uint32_t)XThread1_sto + 0x10U, //---- region #0 + ((XTHREAD1_SIZE_POW2 - 1U) << MPU_RASR_SIZE_Pos) // size + + (3U << MPU_RASR_AP_Pos) // PA:rw/UA:rw + + (1U << MPU_RASR_XN_Pos) // XN=1 + + (1U << MPU_RASR_S_Pos) // S=1 + + (1U << MPU_RASR_C_Pos) // C=1 + + (0U << MPU_RASR_B_Pos) // B=0 + + (0U << MPU_RASR_TEX_Pos) // TEX=0 + + MPU_RASR_ENABLE_Msk }, // region enable + { GPIOA_BASE + 0x11U, //---- region #1 + ((9U - 1U) << MPU_RASR_SIZE_Pos) // 2^9=512B size + + (3U << MPU_RASR_AP_Pos) // PA:rw/UA:rw + + (1U << MPU_RASR_XN_Pos) // XN=1 + + (1U << MPU_RASR_S_Pos) // S=1 + + (0U << MPU_RASR_C_Pos) // C=0 + + (1U << MPU_RASR_B_Pos) // B=1 + + (0U << MPU_RASR_TEX_Pos) // TEX=0 + + MPU_RASR_ENABLE_Msk }, // region enable + { 0U + 0x12U, //---- region #2 + 0U }, +}; +#endif + +// XThread2 thread............................................................ +#define XTHREAD2_SIZE_POW2 ((uint32_t)9U) // XThread2 instance + stack +#define XTHREAD2_STACK_SIZE ((uint32_t)448U) // Thread2 stack size + +__attribute__((aligned((1U << XTHREAD2_SIZE_POW2)))) +uint8_t XThread2_sto[1U << XTHREAD2_SIZE_POW2]; + +#ifdef QF_MEM_ISOLATE +static MPU_Region const MPU_XThread2[3] = { + { (uint32_t)XThread2_sto + 0x10U, //---- region #0 + ((XTHREAD2_SIZE_POW2 - 1U) << MPU_RASR_SIZE_Pos) // size + + (3U << MPU_RASR_AP_Pos) // PA:rw/UA:rw + + (1U << MPU_RASR_XN_Pos) // XN=1 + + (1U << MPU_RASR_S_Pos) // S=1 + + (1U << MPU_RASR_C_Pos) // C=1 + + (0U << MPU_RASR_B_Pos) // B=0 + + (0U << MPU_RASR_TEX_Pos) // TEX=0 + + MPU_RASR_ENABLE_Msk }, // region enable + { GPIOA_BASE + 0x11U, //---- region #1 + ((9U - 1U) << MPU_RASR_SIZE_Pos) // 2^9=512B size + + (3U << MPU_RASR_AP_Pos) // PA:rw/UA:rw + + (1U << MPU_RASR_XN_Pos) // XN=1 + + (1U << MPU_RASR_S_Pos) // S=1 + + (0U << MPU_RASR_C_Pos) // C=0 + + (1U << MPU_RASR_B_Pos) // B=1 + + (0U << MPU_RASR_TEX_Pos) // TEX=0 + + MPU_RASR_ENABLE_Msk }, // region enable + { 0U + 0x12U, //---- region #2 + 0U }, +}; +#endif + +// Shared Event-pools...................................................... +#define EPOOLS_SIZE_POW2 ((uint32_t)8U) + +__attribute__((aligned((1U << EPOOLS_SIZE_POW2)))) +static struct EPools { + QF_MPOOL_EL(TableEvt) smlPool[2*N_PHILO]; + // ... other pools +} EPools_sto; +Q_ASSERT_STATIC(sizeof(EPools_sto) <= (1U << EPOOLS_SIZE_POW2)); + +//............................................................................ +#ifdef QF_MEM_ISOLATE +static void STM32C031C6_MPU_setup(void) { + + MPU->CTRL = 0U; // disable the MPU + + // region #7: NULL-pointer protection region + MPU->RBAR = 0x00000000U + 0x17U; // base address + region #7 + MPU->RASR = ((8U - 1U) << MPU_RASR_SIZE_Pos) // 2^8=256B size + + (0U << MPU_RASR_AP_Pos) // PA:na/UA:na + + (1U << MPU_RASR_XN_Pos) // XN=1 + + (0U << MPU_RASR_S_Pos) // S=0 + + (0U << MPU_RASR_C_Pos) // C=0 + + (0U << MPU_RASR_B_Pos) // B=0 + + (0U << MPU_RASR_TEX_Pos) // TEX=0 + + MPU_RASR_ENABLE_Msk; // region enable + + // region #6: stack region + MPU->RBAR = 0x20000000U + 0x16U; // base address + region #6 + MPU->RASR = ((STACK_SIZE_POW2 - 1U) << MPU_RASR_SIZE_Pos) // size + + (3U << MPU_RASR_AP_Pos) // PA:rw/UA:rw + + (1U << MPU_RASR_XN_Pos) // XN=1 + + (1U << MPU_RASR_S_Pos) // S=1 + + (1U << MPU_RASR_C_Pos) // C=1 + + (0U << MPU_RASR_B_Pos) // B=0 + + (0U << MPU_RASR_TEX_Pos) // TEX=0 + + MPU_RASR_ENABLE_Msk; // region enable + + // region #5: ROM region for STM32C031C6, whole 32K + MPU->RBAR = 0x08000000U + 0x15U; // base address + region #5 + MPU->RASR = ((15U - 1U) << MPU_RASR_SIZE_Pos) // 2^15=32K size + + (6U << MPU_RASR_AP_Pos) // PA:ro/UA:ro + + (0U << MPU_RASR_XN_Pos) // XN=0 + + (0U << MPU_RASR_S_Pos) // S=0 + + (1U << MPU_RASR_C_Pos) // C=1 + + (0U << MPU_RASR_B_Pos) // B=0 + + (0U << MPU_RASR_TEX_Pos) // TEX=0 + + MPU_RASR_ENABLE_Msk; // region enable + + // region #4: Event-pools region + MPU->RBAR = (uint32_t)&EPools_sto + 0x14U;// base address + region #4 + MPU->RASR = ((EPOOLS_SIZE_POW2 - 1U) << MPU_RASR_SIZE_Pos) // size + + (3U << MPU_RASR_AP_Pos) // PA:rw/UA:rw + + (1U << MPU_RASR_XN_Pos) // XN=1 + + (1U << MPU_RASR_S_Pos) // S=1 + + (1U << MPU_RASR_C_Pos) // C=1 + + (0U << MPU_RASR_B_Pos) // B=0 + + (0U << MPU_RASR_TEX_Pos) // TEX=0 + + MPU_RASR_ENABLE_Msk; // region enable + +#ifdef Q_SPY + // region #3: QS-filters region + MPU->RBAR = (uint32_t)&QS_filt_ + 0x13U;// base address + region #3 + MPU->RASR = ((8U - 1U) << MPU_RASR_SIZE_Pos) // 2^8=256B size + + (3U << MPU_RASR_AP_Pos) // PA:rw/UA:rw + + (1U << MPU_RASR_XN_Pos) // XN=1 + + (1U << MPU_RASR_S_Pos) // S=1 + + (1U << MPU_RASR_C_Pos) // C=1 + + (0U << MPU_RASR_B_Pos) // B=0 + + (0U << MPU_RASR_TEX_Pos) // TEX=0 + + MPU_RASR_ENABLE_Msk; // region enable +#endif + + // region #0: temporary 4G region for initial transient + MPU->RBAR = 0x00000000U + 0x10U; // base address + region #0 + MPU->RASR = ((32U - 1U) << MPU_RASR_SIZE_Pos) // 2^32=4G size + + (3U << MPU_RASR_AP_Pos) // PA:rw/UA:rw + + (0U << MPU_RASR_XN_Pos) // XN=0 + + (1U << MPU_RASR_S_Pos) // S=1 + + (1U << MPU_RASR_C_Pos) // C=1 + + (0U << MPU_RASR_B_Pos) // B=0 + + (0U << MPU_RASR_TEX_Pos) // TEX=0 + + MPU_RASR_ENABLE_Msk; // region enable + + MPU->CTRL = MPU_CTRL_ENABLE_Msk; // enable the MPU + // but do NOT enable background region + __ISB(); + __DSB(); +} +#endif + +//============================================================================ + +// "opaque" pointer to AO +QActive * const AO_Table = (QActive *)Table_sto; + +QActive * const AO_Philo[N_PHILO] = { + (QActive *)Philo_sto[0], // "opaque" pointer + (QActive *)Philo_sto[1], // "opaque" pointer + (QActive *)Philo_sto[2], // "opaque" pointer + (QActive *)Philo_sto[3], // "opaque" pointer + (QActive *)Philo_sto[4] // "opaque" pointer +}; + +static uint8_t * const XThread1_inst = &XThread1_sto[XTHREAD1_STACK_SIZE]; +QXThread * const TH_XThread1 = (QXThread *)&XThread1_sto[XTHREAD1_STACK_SIZE]; + +static uint8_t * const XThread2_inst = &XThread2_sto[XTHREAD2_STACK_SIZE]; +QXThread * const TH_XThread2 = (QXThread *)&XThread2_sto[XTHREAD2_STACK_SIZE]; + +// BSP functions =========================================================== +void BSP_init(void) { +#ifdef QF_MEM_ISOLATE + // setup the MPU + STM32C031C6_MPU_setup(); +#endif + + // NOTE: SystemInit() has been already called from the startup code + // but SystemCoreClock needs to be updated + SystemCoreClockUpdate(); + + // enable GPIOA clock port for the LED LD4 + RCC->IOPENR |= (1U << 0U); + + // set all used GPIOA pins as push-pull output, no pull-up, pull-down + GPIOA->MODER &= ~(3U << 2U*LD4_PIN); + GPIOA->MODER |= (1U << 2U*LD4_PIN); + GPIOA->OTYPER &= ~(1U << LD4_PIN); + GPIOA->OSPEEDR &= ~(3U << 2U*LD4_PIN); + GPIOA->OSPEEDR |= (1U << 2U*LD4_PIN); + GPIOA->PUPDR &= ~(3U << 2U*LD4_PIN); + + // enable GPIOC clock port for the Button B1 + RCC->IOPENR |= (1U << 2U); + + // configure Button B1 pin on GPIOC as input, no pull-up, pull-down + GPIOC->MODER &= ~(3U << 2U*B1_PIN); + GPIOC->PUPDR &= ~(3U << 2U*B1_PIN); + + BSP_randomSeed(1234U); // seed the random number generator + + // initialize the QS software tracing... + if (!QS_INIT((void *)0)) { + Q_ERROR(); + } + + // dictionaries... + QS_OBJ_DICTIONARY(&l_SysTick_Handler); + QS_USR_DICTIONARY(PHILO_STAT); + QS_USR_DICTIONARY(PAUSED_STAT); + + QS_ONLY(produce_sig_dict()); + + // setup the QS filters... + QS_GLB_FILTER(QS_ALL_RECORDS); // all records + QS_GLB_FILTER(-QS_QF_TICK); // exclude the clock tick +} +//............................................................................ +void BSP_start(void) { + // initialize event pools + QF_poolInit(EPools_sto.smlPool, + sizeof(EPools_sto.smlPool), + sizeof(EPools_sto.smlPool[0])); + + // initialize publish-subscribe + static QSubscrList subscrSto[MAX_PUB_SIG]; + QActive_psInit(subscrSto, Q_DIM(subscrSto)); + + // instantiate and start AOs/threads... + static QEvt const *xThread1QueueSto[5]; +#ifdef QF_MEM_ISOLATE + XThread1_ctor(XThread1_inst, + sizeof(XThread1_sto) - XTHREAD1_STACK_SIZE, MPU_XThread1); +#else + XThread1_ctor(XThread1_inst, + sizeof(XThread1_sto) - XTHREAD1_STACK_SIZE, (void *)0); +#endif + QXTHREAD_START(TH_XThread1, + 1U, // QP priority of the thread + xThread1QueueSto, // event queue storage + Q_DIM(xThread1QueueSto), // event length [events] + &XThread1_sto[0], // stack storage + XTHREAD1_STACK_SIZE, // stack size [bytes] + (void *)0); // no initialization param + + static QEvt const *philoQueueSto[N_PHILO][10]; + for (uint8_t n = 0U; n < N_PHILO; ++n) { +#ifdef QF_MEM_ISOLATE + Philo_ctor(n, Philo_sto[n], sizeof(Philo_sto[n]), MPU_Philo[n]); +#else + Philo_ctor(n, Philo_sto[n], sizeof(Philo_sto[n]), (void *)0); +#endif + QACTIVE_START(AO_Philo[n], + n + 3U, // QF-prio/pthre. see NOTE1 + philoQueueSto[n], // event queue storage + Q_DIM(philoQueueSto[n]), // queue length [events] + (void *)0, 0U, // no stack storage + (void *)0); // no initialization param + } + + static QEvt const *xThread2QueueSto[5]; +#ifdef QF_MEM_ISOLATE + XThread2_ctor(XThread2_inst, + sizeof(XThread2_sto) - XTHREAD2_STACK_SIZE, MPU_XThread2); +#else + XThread2_ctor(XThread2_inst, + sizeof(XThread2_sto) - XTHREAD2_STACK_SIZE, (void *)0); +#endif + QXTHREAD_START(TH_XThread2, + N_PHILO + 5U, // QP priority of the thread + xThread2QueueSto, // event queue storage + Q_DIM(xThread2QueueSto), // event length [events] + &XThread2_sto[0], // stack storage + XTHREAD2_STACK_SIZE, // stack size [bytes] + (void *)0); // no initialization param + + static QEvt const *tableQueueSto[N_PHILO]; +#ifdef QF_MEM_ISOLATE + Table_ctor(Table_sto, sizeof(Table_sto), MPU_Table); +#else + Table_ctor(Table_sto, sizeof(Table_sto), (void *)0); +#endif + QACTIVE_START(AO_Table, + N_PHILO + 7U, // QP prio. of the AO + tableQueueSto, // event queue storage + Q_DIM(tableQueueSto), // queue length [events] + (void *)0, 0U, // no stack storage + (void *)0); // no initialization param +} +//............................................................................ +void BSP_displayPhilStat(uint8_t n, char const *stat) { + Q_UNUSED_PAR(n); + + if (stat[0] == 'h') { + GPIOA->BSRR = (1U << LD4_PIN); // turn LED on + } + else { + GPIOA->BSRR = (1U << (LD4_PIN + 16U)); // turn LED off + } + + // app-specific trace record... + QS_BEGIN_ID(PHILO_STAT, AO_Table->prio) + QS_U8(1, n); // Philosopher number + QS_STR(stat); // Philosopher status + QS_END() +} +//............................................................................ +void BSP_displayPaused(uint8_t const paused) { + // not enough LEDs to implement this feature + if (paused != 0U) { + //GPIOA->BSRR = (1U << LD4_PIN); // turn LED[n] on + } + else { + //GPIOA->BSRR = (1U << (LD4_PIN + 16U)); // turn LED[n] off + } + + // application-specific trace record + QS_BEGIN_ID(PAUSED_STAT, AO_Table->prio) + QS_U8(1, paused); // Paused status + QS_END() +} +//............................................................................ +void BSP_randomSeed(uint32_t seed) { + Philo_shared_sto.rnd_seed = seed; +} +//............................................................................ +uint32_t BSP_random() { // a very cheap pseudo-random-number generator + + QSchedStatus lockStat = QXK_schedLock(N_PHILO); + // "Super-Duper" Linear Congruential Generator (LCG) + // LCG(2^32, 3*7*11*13*23, 0, seed) + // + uint32_t rnd = Philo_shared_sto.rnd_seed * (3U*7U*11U*13U*23U); + Philo_shared_sto.rnd_seed = rnd; // set for the next time + QXK_schedUnlock(lockStat); + + return (rnd >> 8U); +} +//............................................................................ +void BSP_ledOn() { + GPIOA->BSRR = (1U << LD4_PIN); // turn LED on +} +//............................................................................ +void BSP_ledOff() { + GPIOA->BSRR = (1U << (LD4_PIN + 16U)); // turn LED off +} +//............................................................................ +void BSP_terminate(int16_t result) { + Q_UNUSED_PAR(result); +} + +//============================================================================ +// QF callbacks... +void QF_onStartup(void) { + // set up the SysTick timer to fire at BSP_TICKS_PER_SEC rate + SysTick_Config(SystemCoreClock / BSP_TICKS_PER_SEC); + + // assign all priority bits for preemption-prio. and none to sub-prio. + NVIC_SetPriorityGrouping(0U); + + // set priorities of ALL ISRs used in the system, see NOTE1 + NVIC_SetPriority(USART2_IRQn, 0); // kernel UNAWARE interrupt + NVIC_SetPriority(EXTI0_1_IRQn, QF_AWARE_ISR_CMSIS_PRI + 0U); + NVIC_SetPriority(SysTick_IRQn, QF_AWARE_ISR_CMSIS_PRI + 1U); + // ... + + // enable IRQs... + NVIC_EnableIRQ(EXTI0_1_IRQn); + +#ifdef Q_SPY + NVIC_EnableIRQ(USART2_IRQn); // UART2 interrupt used for QS-RX +#endif +} +//............................................................................ +void QF_onCleanup(void) { +} +//............................................................................ +void QXK_onIdle(void) { + // toggle an LED on and then off (not enough LEDs, see NOTE02) + //QF_INT_DISABLE(); + //QF_MEM_SYS(); + //GPIOA->BSRR = (1U << LD4_PIN); // turn LED[n] on + //GPIOA->BSRR = (1U << (LD4_PIN + 16U)); // turn LED[n] off + //QF_MEM_APP(); + //QF_INT_ENABLE(); + +#ifdef Q_SPY + QF_INT_DISABLE(); + QF_MEM_SYS(); + QS_rxParse(); // parse all the received bytes + QF_MEM_APP(); + QF_INT_ENABLE(); + QF_CRIT_EXIT_NOP(); + + QF_INT_DISABLE(); + QF_MEM_SYS(); + if ((USART2->ISR & (1U << 7U)) != 0U) { // is TXE empty? + uint16_t b = QS_getByte(); + if (b != QS_EOD) { // not End-Of-Data? + USART2->TDR = b; // put into the DR register + } + } + QF_MEM_APP(); + QF_INT_ENABLE(); +#elif defined NDEBUG + // Put the CPU and peripherals to the low-power mode. + // you might need to customize the clock management for your application, + // see the datasheet for your particular Cortex-M MCU. + // + // !!!CAUTION!!! + // The WFI instruction stops the CPU clock, which unfortunately disables + // the JTAG port, so the ST-Link debugger can no longer connect to the + // board. For that reason, the call to __WFI() has to be used with CAUTION. + // + // NOTE: If you find your board "frozen" like this, strap BOOT0 to VDD and + // reset the board, then connect with ST-Link Utilities and erase the part. + // The trick with BOOT(0) is it gets the part to run the System Loader + // instead of your broken code. When done disconnect BOOT0, and start over. + // + //__WFI(); // Wait-For-Interrupt +#endif +} + +//============================================================================ +// QS callbacks... +#ifdef Q_SPY + +#ifdef QF_MEM_ISOLATE +// Shared QS filters... +__attribute__((aligned(32))) +QS_Filter QS_filt_; +#endif + +//............................................................................ +static uint16_t const UARTPrescTable[12] = { + 1U, 2U, 4U, 6U, 8U, 10U, 12U, 16U, 32U, 64U, 128U, 256U +}; + +#define UART_DIV_SAMPLING16(__PCLK__, __BAUD__, __CLOCKPRESCALER__) \ + ((((__PCLK__)/UARTPrescTable[(__CLOCKPRESCALER__)]) \ + + ((__BAUD__)/2U)) / (__BAUD__)) + +#define UART_PRESCALER_DIV1 0U + +// USART2 pins PA.2 and PA.3 +#define USART2_TX_PIN 2U +#define USART2_RX_PIN 3U + +//............................................................................ +uint8_t QS_onStartup(void const *arg) { + Q_UNUSED_PAR(arg); + + static uint8_t qsTxBuf[2*1024]; // buffer for QS-TX channel + QS_initBuf(qsTxBuf, sizeof(qsTxBuf)); + + static uint8_t qsRxBuf[100]; // buffer for QS-RX channel + QS_rxInitBuf(qsRxBuf, sizeof(qsRxBuf)); + + // enable peripheral clock for USART2 + RCC->IOPENR |= ( 1U << 0U); // Enable GPIOA clock for USART pins + RCC->APBENR1 |= ( 1U << 17U); // Enable USART#2 clock + + // Configure PA to USART2_RX, PA to USART2_TX + GPIOA->AFR[0] &= ~((15U << 4U*USART2_RX_PIN) | (15U << 4U*USART2_TX_PIN)); + GPIOA->AFR[0] |= (( 1U << 4U*USART2_RX_PIN) | ( 1U << 4U*USART2_TX_PIN)); + GPIOA->MODER &= ~(( 3U << 2U*USART2_RX_PIN) | ( 3U << 2U*USART2_TX_PIN)); + GPIOA->MODER |= (( 2U << 2U*USART2_RX_PIN) | ( 2U << 2U*USART2_TX_PIN)); + + // baud rate + USART2->BRR = UART_DIV_SAMPLING16( + SystemCoreClock, 115200U, UART_PRESCALER_DIV1); + USART2->CR3 = 0x0000U | // no flow control + (1U << 12U); // disable overrun detection (OVRDIS) + USART2->CR2 = 0x0000U; // 1 stop bit + USART2->CR1 = ((1U << 2U) | // enable RX + (1U << 3U) | // enable TX + (1U << 5U) | // enable RX interrupt + (0U << 12U) | // 8 data bits + (0U << 28U) | // 8 data bits + (1U << 0U)); // enable USART + + QS_tickPeriod_ = SystemCoreClock / BSP_TICKS_PER_SEC; + QS_tickTime_ = QS_tickPeriod_; // to start the timestamp at zero + + return 1U; // return success +} +//............................................................................ +void QS_onCleanup(void) { +} +//............................................................................ +QSTimeCtr QS_onGetTime(void) { // NOTE: invoked with interrupts DISABLED + if ((SysTick->CTRL & 0x00010000) == 0) { // COUNT no set? + return QS_tickTime_ - (QSTimeCtr)SysTick->VAL; + } + else { // the rollover occured, but the SysTick_ISR did not run yet + return QS_tickTime_ + QS_tickPeriod_ - (QSTimeCtr)SysTick->VAL; + } +} +//............................................................................ +void QS_onFlush(void) { + for (;;) { + QF_INT_DISABLE(); + QF_MEM_SYS(); + uint16_t b = QS_getByte(); + if (b != QS_EOD) { + while ((USART2->ISR & (1U << 7U)) == 0U) { // while TXE not empty + QF_MEM_APP(); + QF_INT_ENABLE(); + QF_CRIT_EXIT_NOP(); + + QF_INT_DISABLE(); + QF_MEM_SYS(); + } + USART2->TDR = b; // put into the DR register + QF_MEM_APP(); + QF_INT_ENABLE(); + } + else { + QF_MEM_APP(); + QF_INT_ENABLE(); + break; + } + } +} +//............................................................................ +//! callback function to reset the target (to be implemented in the BSP) +void QS_onReset(void) { + NVIC_SystemReset(); +} +//............................................................................ +//! callback function to execute a user command +void QS_onCommand(uint8_t cmdId, + uint32_t param1, uint32_t param2, uint32_t param3) +{ + Q_UNUSED_PAR(cmdId); + Q_UNUSED_PAR(param1); + Q_UNUSED_PAR(param2); + Q_UNUSED_PAR(param3); +} + +#endif // Q_SPY +//---------------------------------------------------------------------------- + +//============================================================================ +// NOTE1: +// The QF_AWARE_ISR_CMSIS_PRI constant from the QF port specifies the highest +// ISR priority that is disabled by the QF framework. The value is suitable +// for the NVIC_SetPriority() CMSIS function. +// +// Only ISRs prioritized at or below the QF_AWARE_ISR_CMSIS_PRI level (i.e., +// with the numerical values of priorities equal or higher than +// QF_AWARE_ISR_CMSIS_PRI) are allowed to call the QK_ISR_ENTRY/ +// QXK_ISR_ENTRY macros or any other QF/QXK services. These ISRs are +// "QF-aware". +// +// Conversely, any ISRs prioritized above the QF_AWARE_ISR_CMSIS_PRI priority +// level (i.e., with the numerical values of priorities less than +// QF_AWARE_ISR_CMSIS_PRI) are never disabled and are not aware of the kernel. +// Such "QF-unaware" ISRs cannot call ANY QF/QXK services. In particular they +// can NOT call the macros QXK_ISR_ENTRY/QXK_ISR_ENTRY. The only mechanism +// by which a "QF-unaware" ISR can communicate with the QF framework is by +// triggering a "QF-aware" ISR, which can post/publish events. +// +// NOTE2: +// The User LED is used to visualize the idle loop activity. The brightness +// of the LED is proportional to the frequency of the idle loop. +// Please note that the LED is toggled with interrupts locked, so no interrupt +// execution time contributes to the brightness of the User LED. +// diff --git a/examples/arm-cm/dpp_nucleo-c031c6_mpu/qxk/gnu/Makefile b/examples/arm-cm/dpp_nucleo-c031c6_mpu/qxk/gnu/Makefile new file mode 100644 index 00000000..283c3512 --- /dev/null +++ b/examples/arm-cm/dpp_nucleo-c031c6_mpu/qxk/gnu/Makefile @@ -0,0 +1,320 @@ +############################################################################## +# Product: Makefile for QP/C on NUCLEO-C031C6, QXK kernel, GNU-ARM +# Last Updated for Version: 7.3.0 +# Date of the Last Update: 2023-09-07 +# +# Q u a n t u m L e a P s +# ------------------------ +# Modern Embedded Software +# +# Copyright (C) 2005 Quantum Leaps, LLC. +# +# This program is open source software: you can redistribute it and/or +# modify it under the terms of the GNU General Public License as published +# by the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Alternatively, this program may be distributed and modified under the +# terms of Quantum Leaps commercial licenses, which expressly supersede +# the GNU General Public License and are specifically designed for +# licensees interested in retaining the proprietary status of their code. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# +# Contact information: +# +# +############################################################################## +# examples of invoking this Makefile: +# building configurations: Debug (default), Release, and Spy +# make +# make CONF=rel +# make CONF=spy +# +# cleaning configurations: Debug (default), Release, and Spy +# make clean +# make CONF=rel clean +# make CONF=spy clean +# +# NOTE: +# To use this Makefile on Windows, you will need the GNU make utility, which +# is included in the Qtools collection for Windows, see: +# https://github.com/QuantumLeaps/qtools + +#----------------------------------------------------------------------------- +# project name +# +PROJECT := dpp-qxk + +#----------------------------------------------------------------------------- +# project directories +# + +# location of the QP/C framework (if not provided in an environemnt var.) +ifeq ($(QPC),) +QPC := ../../../../.. +endif + +# QP port used in this project +QP_PORT_DIR := $(QPC)/ports/arm-cm/qxk/gnu + +# list of all source directories used by this project +VPATH = \ + .. \ + ../.. \ + $(QPC)/src/qf \ + $(QPC)/src/qxk \ + $(QPC)/src/qs \ + $(QP_PORT_DIR) \ + $(QPC)/3rd_party/nucleo-c031c6 \ + $(QPC)/3rd_party/nucleo-c031c6/gnu + +# list of all include directories needed by this project +INCLUDES = \ + -I../.. \ + -I$(QPC)/include \ + -I$(QP_PORT_DIR) \ + -I$(QPC)/3rd_party/CMSIS/Include \ + -I$(QPC)/3rd_party/nucleo-c031c6 + +#----------------------------------------------------------------------------- +# files +# + +# assembler source files +ASM_SRCS := + +# C source files +C_SRCS := \ + bsp.c \ + main.c \ + philo.c \ + table.c \ + xthread1.c \ + xthread2.c \ + system_stm32c0xx.c \ + startup_stm32c031xx.c + +# C++ source files +CPP_SRCS := + +OUTPUT := $(PROJECT) +LD_SCRIPT := $(PROJECT).ld + +QP_SRCS := \ + qep_hsm.c \ + qep_msm.c \ + qf_act.c \ + qf_actq.c \ + qf_defer.c \ + qf_dyn.c \ + qf_mem.c \ + qf_ps.c \ + qf_qact.c \ + qf_qeq.c \ + qf_qmact.c \ + qf_time.c \ + qxk.c \ + qxk_xthr.c \ + qxk_sema.c \ + qxk_mutex.c \ + qxk_port.c + +QP_ASMS := + +QS_SRCS := \ + qs.c \ + qs_rx.c \ + qs_fp.c + +LIB_DIRS := +LIBS := + +# defines +DEFINES := \ + -DQP_CONFIG \ + -DSTM32C031xx + +# ARM CPU, ARCH, FPU, and Float-ABI types... +# ARM_CPU: [cortex-m0 | cortex-m0plus | cortex-m1 | cortex-m3 | cortex-m4] +# ARM_FPU: [ | vfp] +# FLOAT_ABI: [ | soft | softfp | hard] +# +ARM_CPU := -mcpu=cortex-m0plus +ARM_FPU := +FLOAT_ABI := + +#----------------------------------------------------------------------------- +# GNU-ARM toolset (NOTE: You need to adjust to your machine) +# see https://developer.arm.com/open-source/gnu-toolchain/gnu-rm/downloads +# +ifeq ($(GNU_ARM),) +GNU_ARM := $(QTOOLS)/gnu_arm-none-eabi +endif + +# make sure that the GNU-ARM toolset exists... +ifeq ("$(wildcard $(GNU_ARM))","") +$(error GNU_ARM toolset not found. Please adjust the Makefile) +endif + +CC := $(GNU_ARM)/bin/arm-none-eabi-gcc +CPP := $(GNU_ARM)/bin/arm-none-eabi-g++ +AS := $(GNU_ARM)/bin/arm-none-eabi-as +LINK := $(GNU_ARM)/bin/arm-none-eabi-gcc +BIN := $(GNU_ARM)/bin/arm-none-eabi-objcopy + +############################################################################## +# Typically you should not need to change anything below this line + +# basic utilities (included in QTools for Windows), see: +# https://www.state-machine.com/qtools + +MKDIR := mkdir +RM := rm + +#----------------------------------------------------------------------------- +# build options for various configurations for ARM Cortex-M +# + +# combine all the soruces... +C_SRCS += $(QP_SRCS) +ASM_SRCS += $(QP_ASMS) + +ifeq (rel, $(CONF)) # Release configuration .................................. + +BIN_DIR := rel + +ASFLAGS = $(ARM_CPU) $(ARM_FPU) $(ASM_CPU) $(ASM_FPU) + +CFLAGS = -c $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \ + -ffunction-sections -fdata-sections \ + -O2 $(INCLUDES) $(DEFINES) -DNDEBUG + +CPPFLAGS = -c $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \ + -ffunction-sections -fdata-sections -fno-rtti -fno-exceptions \ + -O2 $(INCLUDES) $(DEFINES) -DNDEBUG + +else ifeq (spy, $(CONF)) # Spy configuration ................................ + +BIN_DIR := spy + +C_SRCS += $(QS_SRCS) + +ASFLAGS = -g $(ARM_CPU) $(ARM_FPU) $(ASM_CPU) $(ASM_FPU) + +CFLAGS = -c -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \ + -ffunction-sections -fdata-sections \ + -O $(INCLUDES) $(DEFINES) -DQ_SPY + +CPPFLAGS = -c -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \ + -ffunction-sections -fdata-sections -fno-rtti -fno-exceptions \ + -O $(INCLUDES) $(DEFINES) -DQ_SPY + +else # default Debug configuration .......................................... + +BIN_DIR := dbg + +ASFLAGS = -g $(ARM_CPU) $(ARM_FPU) $(ASM_CPU) $(ASM_FPU) + +CFLAGS = -c -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \ + -ffunction-sections -fdata-sections \ + -O $(INCLUDES) $(DEFINES) + +CPPFLAGS = -c -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \ + -ffunction-sections -fdata-sections -fno-rtti -fno-exceptions \ + -O $(INCLUDES) $(DEFINES) + +endif # ...................................................................... + + +LINKFLAGS = -T$(LD_SCRIPT) $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb \ + -specs=nosys.specs -specs=nano.specs \ + -Wl,-Map,$(BIN_DIR)/$(OUTPUT).map,--cref,--gc-sections $(LIB_DIRS) + + +ASM_OBJS := $(patsubst %.s,%.o, $(notdir $(ASM_SRCS))) +C_OBJS := $(patsubst %.c,%.o, $(notdir $(C_SRCS))) +CPP_OBJS := $(patsubst %.cpp,%.o,$(notdir $(CPP_SRCS))) + +TARGET_BIN := $(BIN_DIR)/$(OUTPUT).bin +TARGET_ELF := $(BIN_DIR)/$(OUTPUT).elf +ASM_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(ASM_OBJS)) +C_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(C_OBJS)) +C_DEPS_EXT := $(patsubst %.o, %.d, $(C_OBJS_EXT)) +CPP_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(CPP_OBJS)) +CPP_DEPS_EXT := $(patsubst %.o, %.d, $(CPP_OBJS_EXT)) + +# create $(BIN_DIR) if it does not exist +ifeq ("$(wildcard $(BIN_DIR))","") +$(shell $(MKDIR) $(BIN_DIR)) +endif + +#----------------------------------------------------------------------------- +# rules +# + +.PHONY : run norun flash clean show + +ifeq ($(MAKECMDGOALS),norun) +all : $(TARGET_BIN) +norun : all +else +all : $(TARGET_BIN) run +endif + +$(TARGET_BIN): $(TARGET_ELF) + $(BIN) -O binary $< $@ + +$(TARGET_ELF) : $(ASM_OBJS_EXT) $(C_OBJS_EXT) $(CPP_OBJS_EXT) + $(CC) $(CFLAGS) $(QPC)/src/qs/qstamp.c -o $(BIN_DIR)/qstamp.o + $(LINK) $(LINKFLAGS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) + +$(BIN_DIR)/%.d : %.c + $(CC) -MM -MT $(@:.d=.o) $(CFLAGS) $< > $@ + +$(BIN_DIR)/%.d : %.cpp + $(CPP) -MM -MT $(@:.d=.o) $(CPPFLAGS) $< > $@ + +$(BIN_DIR)/%.o : %.s + $(AS) $(ASFLAGS) $< -o $@ + +$(BIN_DIR)/%.o : %.c + $(CC) $(CFLAGS) $< -o $@ + +$(BIN_DIR)/%.o : %.cpp + $(CPP) $(CPPFLAGS) $< -o $@ + +# include dependency files only if our goal depends on their existence +ifneq ($(MAKECMDGOALS),clean) + ifneq ($(MAKECMDGOALS),show) +-include $(C_DEPS_EXT) $(CPP_DEPS_EXT) + endif +endif + + +clean: + -$(RM) $(BIN_DIR)/*.o \ + $(BIN_DIR)/*.d \ + $(BIN_DIR)/*.bin \ + $(BIN_DIR)/*.elf \ + $(BIN_DIR)/*.map + +show: + @echo PROJECT = $(PROJECT) + @echo CONF = $(CONF) + @echo DEFINES = $(DEFINES) + @echo ASM_FPU = $(ASM_FPU) + @echo ASM_SRCS = $(ASM_SRCS) + @echo C_SRCS = $(C_SRCS) + @echo CPP_SRCS = $(CPP_SRCS) + @echo ASM_OBJS_EXT = $(ASM_OBJS_EXT) + @echo C_OBJS_EXT = $(C_OBJS_EXT) + @echo C_DEPS_EXT = $(C_DEPS_EXT) + @echo CPP_DEPS_EXT = $(CPP_DEPS_EXT) + @echo TARGET_ELF = $(TARGET_ELF) diff --git a/examples/arm-cm/dpp_nucleo-c031c6_mpu/qxk/gnu/dpp-qxk.ld b/examples/arm-cm/dpp_nucleo-c031c6_mpu/qxk/gnu/dpp-qxk.ld new file mode 100644 index 00000000..4a3ba851 --- /dev/null +++ b/examples/arm-cm/dpp_nucleo-c031c6_mpu/qxk/gnu/dpp-qxk.ld @@ -0,0 +1,135 @@ +/***************************************************************************** +* Linker script for for STM32C031C6, GNU-ARM linker +* +* Q u a n t u m L e a P s +* ------------------------ +* Modern Embedded Software +* +* Copyright (C) 2005 Quantum Leaps, LLC . +* +* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +* +* This software is dual-licensed under the terms of the open source GNU +* General Public License version 3 (or any later version), or alternatively, +* under the terms of one of the closed source Quantum Leaps commercial +* licenses. +* +* The terms of the open source GNU General Public License version 3 +* can be found at: +* +* The terms of the closed source Quantum Leaps commercial licenses +* can be found at: +* +* Redistributions in source code must retain this top-level comment block. +* Plagiarizing this software to sidestep the license obligations is illegal. +* +* Contact information: +* +* +*****************************************************************************/ +OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm", "elf32-littlearm") +OUTPUT_ARCH(arm) +ENTRY(Reset_Handler) /* entry Point */ + +MEMORY { /* memory map of STM32C031C6 */ + ROM (rx) : ORIGIN = 0x08000000, LENGTH = 32K + RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 12K +} + +/* The size of the stack used by the application. NOTE: you need to adjust */ +STACK_SIZE = 2048; + +/* The size of the heap used by the application. NOTE: you need to adjust */ +HEAP_SIZE = 0; + +SECTIONS { + + .isr_vector : { /* the vector table goes FIRST into ROM */ + KEEP(*(.isr_vector)) /* vector table */ + . = ALIGN(4); + } >ROM + + .text : { /* code and constants */ + . = ALIGN(4); + *(.text) /* .text sections (code) */ + *(.text*) /* .text* sections (code) */ + *(.rodata) /* .rodata sections (constants, strings, etc.) */ + *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ + + KEEP (*(.init)) + KEEP (*(.fini)) + + . = ALIGN(4); + } >ROM + + .preinit_array : { + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array*)) + PROVIDE_HIDDEN (__preinit_array_end = .); + } >ROM + + .init_array : { + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array*)) + PROVIDE_HIDDEN (__init_array_end = .); + } >ROM + + .fini_array : { + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(.fini_array*)) + KEEP (*(SORT(.fini_array.*))) + PROVIDE_HIDDEN (__fini_array_end = .); + } >ROM + + _etext = .; /* global symbols at end of code */ + + .stack : { + __stack_start__ = .; + . = . + STACK_SIZE; + . = ALIGN(4); + __stack_end__ = .; + } >RAM + + .data : AT (_etext) { + __data_load = LOADADDR (.data); + __data_start = .; + *(.data) /* .data sections */ + *(.data*) /* .data* sections */ + . = ALIGN(4); + __data_end__ = .; + _edata = __data_end__; + } >RAM + + .bss : { + __bss_start__ = .; + *(.bss) + *(.bss*) + *(COMMON) + . = ALIGN(4); + _ebss = .; /* define a global symbol at bss end */ + __bss_end__ = .; + } >RAM + + __exidx_start = .; + .ARM.exidx : { *(.ARM.exidx* .gnu.linkonce.armexidx.*) } >RAM + __exidx_end = .; + + PROVIDE ( end = _ebss ); + PROVIDE ( _end = _ebss ); + PROVIDE ( __end__ = _ebss ); + + .heap : { + __heap_start__ = .; + . = . + HEAP_SIZE; + . = ALIGN(4); + __heap_end__ = .; + } >RAM + + /* Remove information from the standard libraries */ + /DISCARD/ : { + libc.a ( * ) + libm.a ( * ) + libgcc.a ( * ) + } +} diff --git a/examples/arm-cm/dpp_nucleo-c031c6_mpu/qxk/iar/dpp-qxk.ewd b/examples/arm-cm/dpp_nucleo-c031c6_mpu/qxk/iar/dpp-qxk.ewd new file mode 100644 index 00000000..b3712b65 --- /dev/null +++ b/examples/arm-cm/dpp_nucleo-c031c6_mpu/qxk/iar/dpp-qxk.ewd @@ -0,0 +1,4654 @@ + + + 3 + + Debug + + ARM + + 1 + + C-SPY + 2 + + 32 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ARMSIM_ID + 2 + + 1 + 1 + 1 + + + + + + + + CADI_ID + 2 + + 0 + 1 + 1 + + + + + + + + + CMSISDAP_ID + 2 + + 4 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + GDBSERVER_ID + 2 + + 0 + 1 + 1 + + + + + + + + + + + IJET_ID + 2 + + 9 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + JLINK_ID + 2 + + 16 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + LMIFTDI_ID + 2 + + 3 + 1 + 1 + + + + + + + + + + + + + NULINK_ID + 2 + + 0 + 1 + 1 + + + + + + + PEMICRO_ID + 2 + + 3 + 1 + 1 + + + + + + + + STLINK_ID + 2 + + 8 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + THIRDPARTY_ID + 2 + + 0 + 1 + 1 + + + + + + + + TIFET_ID + 2 + + 1 + 1 + 1 + + + + + + + + + + + + + + + + + + + XDS100_ID + 2 + + 9 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + $TOOLKIT_DIR$\plugins\rtos\CMX\CmxArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\CMX\CmxTinyArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\FreeRtos\FreeRtosArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin2.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SafeRTOS\SafeRTOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9BE.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-286-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-III\uCOS-III-KA-CSpy.ewplugin + 0 + + + $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\TargetAccessServer\TargetAccessServer.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\uCProbe\uCProbePlugin.ENU.ewplugin + 0 + + + + + Release + + ARM + + 0 + + C-SPY + 2 + + 32 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ARMSIM_ID + 2 + + 1 + 1 + 0 + + + + + + + + CADI_ID + 2 + + 0 + 1 + 0 + + + + + + + + + CMSISDAP_ID + 2 + + 4 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + GDBSERVER_ID + 2 + + 0 + 1 + 0 + + + + + + + + + + + IJET_ID + 2 + + 9 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + JLINK_ID + 2 + + 16 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + LMIFTDI_ID + 2 + + 3 + 1 + 0 + + + + + + + + + + + + + NULINK_ID + 2 + + 0 + 1 + 0 + + + + + + + PEMICRO_ID + 2 + + 3 + 1 + 0 + + + + + + + + STLINK_ID + 2 + + 8 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + THIRDPARTY_ID + 2 + + 0 + 1 + 0 + + + + + + + + TIFET_ID + 2 + + 1 + 1 + 0 + + + + + + + + + + + + + + + + + + + XDS100_ID + 2 + + 9 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + $TOOLKIT_DIR$\plugins\rtos\CMX\CmxArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\CMX\CmxTinyArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\FreeRtos\FreeRtosArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin2.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SafeRTOS\SafeRTOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9BE.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-286-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-III\uCOS-III-KA-CSpy.ewplugin + 0 + + + $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\TargetAccessServer\TargetAccessServer.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\uCProbe\uCProbePlugin.ENU.ewplugin + 0 + + + + + Spy + + ARM + + 1 + + C-SPY + 2 + + 32 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ARMSIM_ID + 2 + + 1 + 1 + 1 + + + + + + + + CADI_ID + 2 + + 0 + 1 + 1 + + + + + + + + + CMSISDAP_ID + 2 + + 4 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + GDBSERVER_ID + 2 + + 0 + 1 + 1 + + + + + + + + + + + IJET_ID + 2 + + 9 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + JLINK_ID + 2 + + 16 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + LMIFTDI_ID + 2 + + 3 + 1 + 1 + + + + + + + + + + + + + NULINK_ID + 2 + + 0 + 1 + 1 + + + + + + + PEMICRO_ID + 2 + + 3 + 1 + 1 + + + + + + + + STLINK_ID + 2 + + 8 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + THIRDPARTY_ID + 2 + + 0 + 1 + 1 + + + + + + + + TIFET_ID + 2 + + 1 + 1 + 1 + + + + + + + + + + + + + + + + + + + XDS100_ID + 2 + + 9 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + $TOOLKIT_DIR$\plugins\rtos\CMX\CmxArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\CMX\CmxTinyArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\FreeRtos\FreeRtosArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin2.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SafeRTOS\SafeRTOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9BE.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-286-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-III\uCOS-III-KA-CSpy.ewplugin + 0 + + + $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\TargetAccessServer\TargetAccessServer.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\uCProbe\uCProbePlugin.ENU.ewplugin + 0 + + + + diff --git a/examples/arm-cm/dpp_nucleo-c031c6_mpu/qxk/iar/dpp-qxk.ewp b/examples/arm-cm/dpp_nucleo-c031c6_mpu/qxk/iar/dpp-qxk.ewp new file mode 100644 index 00000000..d63ac154 --- /dev/null +++ b/examples/arm-cm/dpp_nucleo-c031c6_mpu/qxk/iar/dpp-qxk.ewp @@ -0,0 +1,3382 @@ + + + 3 + + Debug + + ARM + + 1 + + General + 3 + + 35 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ICCARM + 2 + + 37 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + AARM + 2 + + 11 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + OBJCOPY + 0 + + 1 + 1 + 1 + + + + + + + + + CUSTOM + 3 + + + + 0 + inputOutputBased + + + + BUILDACTION + 1 + + cmd /c "if exist $OBJ_DIR$\qstamp.o del $OBJ_DIR$\qstamp.o" + + + + + ILINK + 0 + + 27 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + IARCHIVE + 0 + + 0 + 1 + 1 + + + + + + + Coder + 0 + + + + + Release + + ARM + + 0 + + General + 3 + + 35 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ICCARM + 2 + + 37 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + AARM + 2 + + 11 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + OBJCOPY + 0 + + 1 + 1 + 0 + + + + + + + + + CUSTOM + 3 + + + + 0 + inputOutputBased + + + + BUILDACTION + 1 + + cmd /c "if exist $OBJ_DIR$\qstamp.o del $OBJ_DIR$\qstamp.o" + + + + + ILINK + 0 + + 27 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + IARCHIVE + 0 + + 0 + 1 + 0 + + + + + + + Coder + 0 + + + + + Spy + + ARM + + 1 + + General + 3 + + 35 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ICCARM + 2 + + 37 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + AARM + 2 + + 11 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + OBJCOPY + 0 + + 1 + 1 + 1 + + + + + + + + + CUSTOM + 3 + + + + 0 + inputOutputBased + + + + BUILDACTION + 1 + + cmd /c "if exist $OBJ_DIR$\qstamp.o del $OBJ_DIR$\qstamp.o" + + + + + ILINK + 0 + + 27 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + IARCHIVE + 0 + + 0 + 1 + 1 + + + + + + + Coder + 0 + + + + + Release + + + Application + + $PROJ_DIR$\..\bsp.c + + + $PROJ_DIR$\..\..\bsp.h + + + $PROJ_DIR$\..\..\dpp.h + + + $PROJ_DIR$\..\..\main.c + + + $PROJ_DIR$\..\..\philo.c + + + $PROJ_DIR$\..\..\table.c + + + $PROJ_DIR$\..\xthread1.c + + + $PROJ_DIR$\..\xthread2.c + + + + nucleo-c031c6 + + $PROJ_DIR$\..\..\..\..\..\3rd_party\nucleo-c031c6\iar\startup_stm32c031xx.s + + + $PROJ_DIR$\..\..\..\..\..\3rd_party\nucleo-c031c6\stm32c031xx.h + + + $PROJ_DIR$\..\..\..\..\..\3rd_party\nucleo-c031c6\stm32c0xx.h + + + $PROJ_DIR$\..\..\..\..\..\3rd_party\nucleo-c031c6\system_stm32c0xx.c + + + + QP + + $PROJ_DIR$\..\..\..\..\..\src\qf\qep_hsm.c + + + $PROJ_DIR$\..\..\..\..\..\src\qf\qep_msm.c + + + $PROJ_DIR$\..\..\..\..\..\src\qf\qf_act.c + + + $PROJ_DIR$\..\..\..\..\..\src\qf\qf_actq.c + + + $PROJ_DIR$\..\..\..\..\..\src\qf\qf_defer.c + + + $PROJ_DIR$\..\..\..\..\..\src\qf\qf_dyn.c + + + $PROJ_DIR$\..\..\..\..\..\src\qf\qf_mem.c + + + $PROJ_DIR$\..\..\..\..\..\src\qf_pkg.h + + + $PROJ_DIR$\..\..\..\..\..\src\qf\qf_ps.c + + + $PROJ_DIR$\..\..\..\..\..\src\qf\qf_qact.c + + + $PROJ_DIR$\..\..\..\..\..\src\qf\qf_qeq.c + + + $PROJ_DIR$\..\..\..\..\..\src\qf\qf_qmact.c + + + $PROJ_DIR$\..\..\..\..\..\src\qf\qf_time.c + + + $PROJ_DIR$\..\..\..\..\..\src\qxk\qxk.c + + + $PROJ_DIR$\..\..\..\..\..\src\qxk\qxk_mutex.c + + + $PROJ_DIR$\..\..\..\..\..\src\qxk\qxk_sema.c + + + $PROJ_DIR$\..\..\..\..\..\src\qxk\qxk_xthr.c + + + + QP_port + + $PROJ_DIR$\..\..\..\..\..\ports\arm-cm\qxk\iar\qep_port.h + + + $PROJ_DIR$\..\..\..\..\..\ports\arm-cm\qxk\iar\qf_port.h + + + $PROJ_DIR$\..\..\..\..\..\ports\arm-cm\qxk\iar\qs_port.h + + + $PROJ_DIR$\..\..\..\..\..\ports\arm-cm\qxk\iar\qxk_port.c + + + $PROJ_DIR$\..\..\..\..\..\ports\arm-cm\qxk\iar\qxk_port.h + + + + QS + + Debug + Release + + + $PROJ_DIR$\..\..\..\..\..\src\qs\qs.c + + + $PROJ_DIR$\..\..\..\..\..\src\qs\qs_fp.c + + + $PROJ_DIR$\..\..\..\..\..\src\qs\qs_rx.c + + + $PROJ_DIR$\..\..\..\..\..\src\qs\qstamp.c + + + diff --git a/examples/arm-cm/dpp_nucleo-c031c6_mpu/qxk/iar/dpp-qxk.eww b/examples/arm-cm/dpp_nucleo-c031c6_mpu/qxk/iar/dpp-qxk.eww new file mode 100644 index 00000000..38808ca3 --- /dev/null +++ b/examples/arm-cm/dpp_nucleo-c031c6_mpu/qxk/iar/dpp-qxk.eww @@ -0,0 +1,10 @@ + + + + + $WS_DIR$\dpp-qxk.ewp + + + + + diff --git a/examples/arm-cm/dpp_nucleo-c031c6_mpu/qxk/iar/dpp-qxk.icf b/examples/arm-cm/dpp_nucleo-c031c6_mpu/qxk/iar/dpp-qxk.icf new file mode 100644 index 00000000..db057b16 --- /dev/null +++ b/examples/arm-cm/dpp_nucleo-c031c6_mpu/qxk/iar/dpp-qxk.icf @@ -0,0 +1,165 @@ +/*###ICF### Section handled by ICF editor, don't touch! ****/ +/*-Editor annotation file-*/ +/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_4.xml" */ +/*-Specials-*/ +define symbol __ICFEDIT_intvec_start__ = 0x08000000; +/*-Memory Regions-*/ +define symbol __ICFEDIT_region_IROM1_start__ = 0x08000000; +define symbol __ICFEDIT_region_IROM1_end__ = 0x08007FFF; +define symbol __ICFEDIT_region_IROM2_start__ = 0x0; +define symbol __ICFEDIT_region_IROM2_end__ = 0x0; +define symbol __ICFEDIT_region_EROM1_start__ = 0x0; +define symbol __ICFEDIT_region_EROM1_end__ = 0x0; +define symbol __ICFEDIT_region_EROM2_start__ = 0x0; +define symbol __ICFEDIT_region_EROM2_end__ = 0x0; +define symbol __ICFEDIT_region_EROM3_start__ = 0x0; +define symbol __ICFEDIT_region_EROM3_end__ = 0x0; +define symbol __ICFEDIT_region_IRAM1_start__ = 0x20000000; +define symbol __ICFEDIT_region_IRAM1_end__ = 0x20002FFF; +define symbol __ICFEDIT_region_IRAM2_start__ = 0x0; +define symbol __ICFEDIT_region_IRAM2_end__ = 0x0; +define symbol __ICFEDIT_region_ERAM1_start__ = 0x0; +define symbol __ICFEDIT_region_ERAM1_end__ = 0x0; +define symbol __ICFEDIT_region_ERAM2_start__ = 0x0; +define symbol __ICFEDIT_region_ERAM2_end__ = 0x0; +define symbol __ICFEDIT_region_ERAM3_start__ = 0x0; +define symbol __ICFEDIT_region_ERAM3_end__ = 0x0; +/*-Sizes-*/ +define symbol __ICFEDIT_size_cstack__ = 2048; +define symbol __ICFEDIT_size_proc_stack__ = 0x0; +define symbol __ICFEDIT_size_heap__ = 0; +/**** End of ICF editor section. ###ICF###*/ + +define memory mem with size = 4G; +define symbol use_IROM1 = (__ICFEDIT_region_IROM1_start__ != 0x0 || __ICFEDIT_region_IROM1_end__ != 0x0); +define symbol use_IROM2 = (__ICFEDIT_region_IROM2_start__ != 0x0 || __ICFEDIT_region_IROM2_end__ != 0x0); +define symbol use_EROM1 = (__ICFEDIT_region_EROM1_start__ != 0x0 || __ICFEDIT_region_EROM1_end__ != 0x0); +define symbol use_EROM2 = (__ICFEDIT_region_EROM2_start__ != 0x0 || __ICFEDIT_region_EROM2_end__ != 0x0); +define symbol use_EROM3 = (__ICFEDIT_region_EROM3_start__ != 0x0 || __ICFEDIT_region_EROM3_end__ != 0x0); +define symbol use_IRAM1 = (__ICFEDIT_region_IRAM1_start__ != 0x0 || __ICFEDIT_region_IRAM1_end__ != 0x0); +define symbol use_IRAM2 = (__ICFEDIT_region_IRAM2_start__ != 0x0 || __ICFEDIT_region_IRAM2_end__ != 0x0); +define symbol use_ERAM1 = (__ICFEDIT_region_ERAM1_start__ != 0x0 || __ICFEDIT_region_ERAM1_end__ != 0x0); +define symbol use_ERAM2 = (__ICFEDIT_region_ERAM2_start__ != 0x0 || __ICFEDIT_region_ERAM2_end__ != 0x0); +define symbol use_ERAM3 = (__ICFEDIT_region_ERAM3_start__ != 0x0 || __ICFEDIT_region_ERAM3_end__ != 0x0); + +if (use_IROM1) +{ + define region IROM1_region = mem:[from __ICFEDIT_region_IROM1_start__ to __ICFEDIT_region_IROM1_end__]; +} +else +{ + define region IROM1_region = []; +} + +if (use_IROM2) +{ + define region IROM2_region = mem:[from __ICFEDIT_region_IROM2_start__ to __ICFEDIT_region_IROM2_end__]; +} +else +{ + define region IROM2_region = []; +} +define region IROM_region = IROM1_region | IROM2_region; + +if (use_EROM1) +{ + define region EROM1_region = mem:[from __ICFEDIT_region_EROM1_start__ to __ICFEDIT_region_EROM1_end__]; +} +else +{ + define region EROM1_region = []; +} +if (use_EROM2) +{ + define region EROM2_region = mem:[from __ICFEDIT_region_EROM2_start__ to __ICFEDIT_region_EROM2_end__]; +} +else +{ + define region EROM2_region = []; +} +if (use_EROM3) +{ + define region EROM3_region = mem:[from __ICFEDIT_region_EROM3_start__ to __ICFEDIT_region_EROM3_end__]; +} +else +{ + define region EROM3_region = []; +} +define region EROM_region = EROM1_region | EROM2_region | EROM3_region; + +if (use_IRAM1) +{ + define region IRAM1_region = mem:[from __ICFEDIT_region_IRAM1_start__ to __ICFEDIT_region_IRAM1_end__]; +} +else +{ + define region IRAM1_region = []; +} +if (use_IRAM2) +{ + define region IRAM2_region = mem:[from __ICFEDIT_region_IRAM2_start__ to __ICFEDIT_region_IRAM2_end__]; +} +else +{ + define region IRAM2_region = []; +} +define region IRAM_region = IRAM1_region | IRAM2_region; + +if (use_ERAM1) +{ + define region ERAM1_region = mem:[from __ICFEDIT_region_ERAM1_start__ to __ICFEDIT_region_ERAM1_end__]; +} +else +{ + define region ERAM1_region = []; +} +if (use_ERAM2) +{ + define region ERAM2_region = mem:[from __ICFEDIT_region_ERAM2_start__ to __ICFEDIT_region_ERAM2_end__]; +} +else +{ + define region ERAM2_region = []; +} +if (use_ERAM3) +{ + define region ERAM3_region = mem:[from __ICFEDIT_region_ERAM3_start__ to __ICFEDIT_region_ERAM3_end__]; +} +else +{ + define region ERAM3_region = []; +} +define region ERAM_region = ERAM1_region | ERAM2_region | ERAM3_region; + +initialize by copy { readwrite }; +if (isdefinedsymbol(__USE_DLIB_PERTHREAD)) +{ + // Required in a multi-threaded application + initialize by copy with packing = none { section __DLIB_PERTHREAD }; +} + +place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec }; + +if (!isempty(IROM_region)) +{ + place in IROM_region { readonly }; +} + +if (!isempty(EROM_region)) +{ + place in EROM_region { readonly section application_specific_ro }; +} + +if (!isempty(IRAM_region)) +{ + define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { }; + define block PROC_STACK with alignment = 8, size = __ICFEDIT_size_proc_stack__ { }; + define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { }; + place at start of IRAM_region {block CSTACK }; /* <== Quantum Leaps */ + place in IRAM_region { readwrite, block PROC_STACK, block HEAP }; +} + +if (!isempty(ERAM_region)) +{ + place in ERAM_region { readwrite section application_specific_rw }; +} \ No newline at end of file diff --git a/examples/arm-cm/dpp_nucleo-c031c6_mpu/qxk/xthread1.c b/examples/arm-cm/dpp_nucleo-c031c6_mpu/qxk/xthread1.c new file mode 100644 index 00000000..18870543 --- /dev/null +++ b/examples/arm-cm/dpp_nucleo-c031c6_mpu/qxk/xthread1.c @@ -0,0 +1,125 @@ +//$file${qxk::xthread1.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// +// Model: dpp_mpu.qm +// File: ${qxk::xthread1.c} +// +// This code has been generated by QM 5.3.0 . +// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. +// +// SPDX-License-Identifier: GPL-3.0-or-later +// +// This generated code is open source software: you can redistribute it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation. +// +// This code is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// NOTE: +// Alternatively, this generated code may be distributed under the terms +// of Quantum Leaps commercial licenses, which expressly supersede the GNU +// General Public License and are specifically designed for licensees +// interested in retaining the proprietary status of their code. +// +// Contact information: +// +// +// +//$endhead${qxk::xthread1.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +#include "qpc.h" // QP/C real-time embedded framework +#include "dpp.h" // DPP Application interface +#include "bsp.h" // Board Support Package + +//---------------------------------------------------------------------------- +Q_DEFINE_THIS_FILE + +//---------------------------------------------------------------------------- +//$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// Check for the minimum required QP version +#if (QP_VERSION < 730U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) +#error qpc version 7.3.0 or higher required +#endif +//$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +//$define${Shared-TH::TH_sema} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${Shared-TH::TH_sema} ...................................................... +QXSemaphore TH_sema; +//$enddef${Shared-TH::TH_sema} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +//$define${Shared-TH::TH_mutex} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${Shared-TH::TH_mutex} ..................................................... +QXMutex TH_mutex; +//$enddef${Shared-TH::TH_mutex} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +//$declare${XThreads::XThread1} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${XThreads::XThread1} ...................................................... +typedef struct { +// protected: + QXThread super; + +// private: + + // NOTE: data needed by this thread should be members of + // the thread class. That way they are in the memory region + // accessible from this thread. + uint8_t foo; +} XThread1; + +// private: +static void XThread1_run(QXThread * const thr); +//$enddecl${XThreads::XThread1} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +//$define${Shared-TH::XThread1_ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${Shared-TH::XThread1_ctor} ................................................ +void XThread1_ctor( + uint8_t * const sto, + uint32_t const size, + void const * const mpu) +{ + Q_REQUIRE(sizeof(XThread1) <= size); + + XThread1 *me = (XThread1 *)sto; + QXThread_ctor(&me->super, &XThread1_run, 0U); + me->super.super.thread = mpu; +} +//$enddef${Shared-TH::XThread1_ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +//$define${XThreads::XThread1} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${XThreads::XThread1} ...................................................... + +//${XThreads::XThread1::run} ................................................. +static void XThread1_run(QXThread * const thr) { + QS_OBJ_DICTIONARY(TH_XThread1); + QS_OBJ_DICTIONARY(&TH_XThread1->timeEvt); + + // downcast the generic thr pointer to the specific thread + XThread1 *me = (XThread1 *)thr; + + // subscribe to the EAT signal (from the application) + QActive_subscribe(&me->super.super, EAT_SIG); + + for (;;) { + QEvt const *e = QXThread_queueGet(BSP_TICKS_PER_SEC/4U); + if (e) { + QXSemaphore_signal(&TH_sema); // signal Thread2 + QF_gc(e); // must explicitly recycle the received event! + } + + QXMutex_lock(&TH_mutex, QXTHREAD_NO_TIMEOUT); // lock the mutex + BSP_ledOn(); + if (QXMutex_tryLock(&TH_mutex)) { // exercise the mutex + // some floating point code to exercise the VFP... + float volatile x = 1.4142135F; + x = x * 1.4142135F; + QXThread_delay(10U); // BLOCK while holding a mutex + QXMutex_unlock(&TH_mutex); + } + QXMutex_unlock(&TH_mutex); + BSP_ledOff(); + } +} +//$enddef${XThreads::XThread1} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/examples/arm-cm/dpp_nucleo-c031c6_mpu/qxk/xthread2.c b/examples/arm-cm/dpp_nucleo-c031c6_mpu/qxk/xthread2.c new file mode 100644 index 00000000..bd8b6fd4 --- /dev/null +++ b/examples/arm-cm/dpp_nucleo-c031c6_mpu/qxk/xthread2.c @@ -0,0 +1,117 @@ +//$file${qxk::xthread2.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// +// Model: dpp_mpu.qm +// File: ${qxk::xthread2.c} +// +// This code has been generated by QM 5.3.0 . +// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. +// +// SPDX-License-Identifier: GPL-3.0-or-later +// +// This generated code is open source software: you can redistribute it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation. +// +// This code is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// NOTE: +// Alternatively, this generated code may be distributed under the terms +// of Quantum Leaps commercial licenses, which expressly supersede the GNU +// General Public License and are specifically designed for licensees +// interested in retaining the proprietary status of their code. +// +// Contact information: +// +// +// +//$endhead${qxk::xthread2.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +#include "qpc.h" // QP/C real-time embedded framework +#include "dpp.h" // DPP Application interface +#include "bsp.h" // Board Support Package + +//---------------------------------------------------------------------------- +Q_DEFINE_THIS_FILE + +//---------------------------------------------------------------------------- +//$declare${XThreads::XThread2} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${XThreads::XThread2} ...................................................... +typedef struct { +// protected: + QXThread super; + +// private: + + // NOTE: data needed by this thread should be members of + // the thread class. That way they are in the memory region + // accessible from this thread. + uint8_t foo; +} XThread2; + +// private: +static void XThread2_run(QXThread * const thr); +//$enddecl${XThreads::XThread2} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +//$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// Check for the minimum required QP version +#if (QP_VERSION < 730U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) +#error qpc version 7.3.0 or higher required +#endif +//$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +//$define${Shared-TH::XThread2_ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${Shared-TH::XThread2_ctor} ................................................ +void XThread2_ctor( + uint8_t * const sto, + uint32_t const size, + void const * const mpu) +{ + Q_REQUIRE(sizeof(XThread2) <= size); + + XThread2 *me = (XThread2 *)sto; + QXThread_ctor(&me->super, &XThread2_run, 0U); + me->super.super.thread = mpu; +} +//$enddef${Shared-TH::XThread2_ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +//$define${XThreads::XThread2} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${XThreads::XThread2} ...................................................... + +//${XThreads::XThread2::run} ................................................. +static void XThread2_run(QXThread * const thr) { + QS_OBJ_DICTIONARY(TH_XThread2); + QS_OBJ_DICTIONARY(&TH_XThread2->timeEvt); + QS_OBJ_DICTIONARY(&TH_sema); + QS_OBJ_DICTIONARY(&TH_mutex); + + // downcast the generic thr pointer to the specific thread + //XThread2 *me = (XThread2 *)thr; + + // initialize the semaphore before using it + // NOTE: Here the semaphore is initialized in the highest-priority thread + // that uses it. Alternatively, the semaphore can be initialized + // before any thread runs. + QXSemaphore_init(&TH_sema, + 0U, // count==0 (signaling semaphore) + 1U); // max_count==1 (binary semaphore) + + // initialize the mutex before using it + // NOTE: Here the mutex is initialized in the highest-priority thread + // that uses it. Alternatively, the mutex can be initialized + // before any thread runs. + QXMutex_init(&TH_mutex, N_PHILO + 6U); // priority-ceiling mutex + //QXMutex_init(&TH_mutex, 0U); // alternatively: priority-ceiling NOT used + + for (;;) { + // wait on a semaphore (BLOCK indefinitely) + QXSemaphore_wait(&TH_sema, QXTHREAD_NO_TIMEOUT); + + QXMutex_lock(&TH_mutex, QXTHREAD_NO_TIMEOUT); // lock the mutex + QXThread_delay(5U); // wait more (BLOCK) + QXMutex_unlock(&TH_mutex); + } +} +//$enddef${XThreads::XThread2} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/examples/arm-cm/dpp_nucleo-c031c6_mpu/stm32-nucleo-c031c6.jpg b/examples/arm-cm/dpp_nucleo-c031c6_mpu/stm32-nucleo-c031c6.jpg new file mode 100644 index 00000000..6647e2d4 Binary files /dev/null and b/examples/arm-cm/dpp_nucleo-c031c6_mpu/stm32-nucleo-c031c6.jpg differ diff --git a/examples/arm-cm/dpp_nucleo-c031c6_mpu/table.c b/examples/arm-cm/dpp_nucleo-c031c6_mpu/table.c new file mode 100644 index 00000000..d93f6dba --- /dev/null +++ b/examples/arm-cm/dpp_nucleo-c031c6_mpu/table.c @@ -0,0 +1,342 @@ +//$file${.::table.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// +// Model: dpp_mpu.qm +// File: ${.::table.c} +// +// This code has been generated by QM 5.3.0 . +// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. +// +// SPDX-License-Identifier: GPL-3.0-or-later +// +// This generated code is open source software: you can redistribute it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation. +// +// This code is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// NOTE: +// Alternatively, this generated code may be distributed under the terms +// of Quantum Leaps commercial licenses, which expressly supersede the GNU +// General Public License and are specifically designed for licensees +// interested in retaining the proprietary status of their code. +// +// Contact information: +// +// +// +//$endhead${.::table.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +#include "qpc.h" // QP/C real-time embedded framework +#include "dpp.h" // DPP Application interface +#include "bsp.h" // Board Support Package + +//$declare${AOs::Table} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${AOs::Table} .............................................................. +typedef struct { +// protected: + QActive super; + +// private: + uint8_t fork[N_PHILO]; + bool isHungry[N_PHILO]; +} Table; + +// protected: +static QState Table_initial(Table * const me, void const * const par); +static QState Table_active(Table * const me, QEvt const * const e); +static QState Table_serving(Table * const me, QEvt const * const e); +static QState Table_paused(Table * const me, QEvt const * const e); +//$enddecl${AOs::Table} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +//---------------------------------------------------------------------------- +Q_DEFINE_THIS_FILE + +// helper function to provide the RIGHT neighbor of a Philo[n] +static inline uint8_t right(uint8_t const n) { + return (uint8_t)((n + (N_PHILO - 1U)) % N_PHILO); +} + +// helper function to provide the LEFT neighbor of a Philo[n] +static inline uint8_t left(uint8_t const n) { + return (uint8_t)((n + 1U) % N_PHILO); +} + +#define FREE ((uint8_t)0U) +#define USED ((uint8_t)1U) + +#define THINKING "thinking" +#define HUNGRY "hungry " +#define EATING "eating " + +//---------------------------------------------------------------------------- + +//$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// Check for the minimum required QP version +#if (QP_VERSION < 730U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) +#error qpc version 7.3.0 or higher required +#endif +//$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +//$define${Shared::Table_ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${Shared::Table_ctor} ...................................................... +void Table_ctor( + uint8_t * const sto, + uint32_t const size, + void const * const mpu) +{ + Q_REQUIRE(sizeof(Table) <= size); + + Table *me = (Table *)sto; + QActive_ctor(&me->super, Q_STATE_CAST(&Table_initial)); + for (uint8_t n = 0U; n < N_PHILO; ++n) { + me->fork[n] = FREE; + me->isHungry[n] = false; + } + me->super.thread = mpu; +} +//$enddef${Shared::Table_ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +//$define${AOs::Table} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${AOs::Table} .............................................................. + +//${AOs::Table::SM} .......................................................... +static QState Table_initial(Table * const me, void const * const par) { + //${AOs::Table::SM::initial} + Q_UNUSED_PAR(par); + + #ifdef Q_SPY + Table *Table_inst = me; + QS_OBJ_DICTIONARY(Table_inst); + #endif + + QActive_subscribe(&me->super, DONE_SIG); + QActive_subscribe(&me->super, PAUSE_SIG); + QActive_subscribe(&me->super, SERVE_SIG); + QActive_subscribe(&me->super, TEST_SIG); + + for (uint8_t n = 0U; n < N_PHILO; ++n) { + me->fork[n] = FREE; + me->isHungry[n] = false; + BSP_displayPhilStat(n, THINKING); + } + + QS_FUN_DICTIONARY(&Table_active); + QS_FUN_DICTIONARY(&Table_serving); + QS_FUN_DICTIONARY(&Table_paused); + + return Q_TRAN(&Table_serving); +} + +//${AOs::Table::SM::active} .................................................. +static QState Table_active(Table * const me, QEvt const * const e) { + QState status_; + switch (e->sig) { + //${AOs::Table::SM::active::TEST} + case TEST_SIG: { + status_ = Q_HANDLED(); + break; + } + //${AOs::Table::SM::active::EAT} + case EAT_SIG: { + Q_ERROR(); + status_ = Q_HANDLED(); + break; + } + default: { + status_ = Q_SUPER(&QHsm_top); + break; + } + } + return status_; +} + +//${AOs::Table::SM::active::serving} ......................................... +static QState Table_serving(Table * const me, QEvt const * const e) { + QState status_; + switch (e->sig) { + //${AOs::Table::SM::active::serving} + case Q_ENTRY_SIG: { + // give permissions to eat... + for (uint8_t n = 0U; n < N_PHILO; ++n) { + if (me->isHungry[n] + && (me->fork[left(n)] == FREE) + && (me->fork[n] == FREE)) + { + me->fork[left(n)] = USED; + me->fork[n] = USED; + #ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, EAT_SIG, n); + #else + TableEvt *pe = Q_NEW(TableEvt, EAT_SIG); + pe->philoId = n; + #endif + QACTIVE_PUBLISH(&pe->super, &me->super); + me->isHungry[n] = false; + BSP_displayPhilStat(n, EATING); + } + } + status_ = Q_HANDLED(); + break; + } + //${AOs::Table::SM::active::serving::HUNGRY} + case HUNGRY_SIG: { + uint8_t n = Q_EVT_CAST(TableEvt)->philoId; + + // phil ID must be in range and he must be not hungry + Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); + + BSP_displayPhilStat(n, HUNGRY); + uint8_t m = left(n); + //${AOs::Table::SM::active::serving::HUNGRY::[bothfree]} + if ((me->fork[m] == FREE) && (me->fork[n] == FREE)) { + me->fork[m] = USED; + me->fork[n] = USED; + + #ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, EAT_SIG, n); + #else + TableEvt *pe = Q_NEW(TableEvt, EAT_SIG); + pe->philoId = n; + #endif + QACTIVE_PUBLISH(&pe->super, &me->super); + BSP_displayPhilStat(n, EATING); + status_ = Q_HANDLED(); + } + //${AOs::Table::SM::active::serving::HUNGRY::[else]} + else { + me->isHungry[n] = true; + status_ = Q_HANDLED(); + } + break; + } + //${AOs::Table::SM::active::serving::DONE} + case DONE_SIG: { + uint8_t n = Q_EVT_CAST(TableEvt)->philoId; + + // phil ID must be in range and he must be not hungry + Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); + + BSP_displayPhilStat(n, THINKING); + uint8_t m = left(n); + + // both forks of Phil[n] must be used + Q_ASSERT((me->fork[n] == USED) && (me->fork[m] == USED)); + + me->fork[m] = FREE; + me->fork[n] = FREE; + m = right(n); // check the right neighbor + + if (me->isHungry[m] && (me->fork[m] == FREE)) { + me->fork[n] = USED; + me->fork[m] = USED; + me->isHungry[m] = false; + #ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, EAT_SIG, m); + #else + TableEvt *pe = Q_NEW(TableEvt, EAT_SIG); + pe->philoId = m; + #endif + QACTIVE_PUBLISH(&pe->super, &me->super); + BSP_displayPhilStat(m, EATING); + } + m = left(n); // check the left neighbor + n = left(m); // left fork of the left neighbor + if (me->isHungry[m] && (me->fork[n] == FREE)) { + me->fork[m] = USED; + me->fork[n] = USED; + me->isHungry[m] = false; + #ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, EAT_SIG, m); + #else + TableEvt *pe = Q_NEW(TableEvt, EAT_SIG); + pe->philoId = m; + #endif + QACTIVE_PUBLISH(&pe->super, &me->super); + BSP_displayPhilStat(m, EATING); + } + status_ = Q_HANDLED(); + break; + } + //${AOs::Table::SM::active::serving::EAT} + case EAT_SIG: { + Q_ERROR(); + status_ = Q_HANDLED(); + break; + } + //${AOs::Table::SM::active::serving::PAUSE} + case PAUSE_SIG: { + status_ = Q_TRAN(&Table_paused); + break; + } + default: { + status_ = Q_SUPER(&Table_active); + break; + } + } + return status_; +} + +//${AOs::Table::SM::active::paused} .......................................... +static QState Table_paused(Table * const me, QEvt const * const e) { + QState status_; + switch (e->sig) { + //${AOs::Table::SM::active::paused} + case Q_ENTRY_SIG: { + BSP_displayPaused(1U); + status_ = Q_HANDLED(); + break; + } + //${AOs::Table::SM::active::paused} + case Q_EXIT_SIG: { + BSP_displayPaused(0U); + status_ = Q_HANDLED(); + break; + } + //${AOs::Table::SM::active::paused::SERVE} + case SERVE_SIG: { + status_ = Q_TRAN(&Table_serving); + break; + } + //${AOs::Table::SM::active::paused::HUNGRY} + case HUNGRY_SIG: { + uint8_t n = Q_EVT_CAST(TableEvt)->philoId; + + // philo ID must be in range and he must be not hungry + Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); + + me->isHungry[n] = true; + BSP_displayPhilStat(n, HUNGRY); + status_ = Q_HANDLED(); + break; + } + //${AOs::Table::SM::active::paused::DONE} + case DONE_SIG: { + uint8_t n = Q_EVT_CAST(TableEvt)->philoId; + + // phil ID must be in range and he must be not hungry + Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); + + BSP_displayPhilStat(n, THINKING); + uint8_t m = left(n); + + // both forks of Phil[n] must be used + Q_ASSERT((me->fork[n] == USED) && (me->fork[m] == USED)); + + me->fork[m] = FREE; + me->fork[n] = FREE; + status_ = Q_HANDLED(); + break; + } + default: { + status_ = Q_SUPER(&Table_active); + break; + } + } + return status_; +} +//$enddef${AOs::Table} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/examples/arm-cm/dpp_nucleo-h743zi/bsp.h b/examples/arm-cm/dpp_nucleo-h743zi/bsp.h index a0d2e549..da73dbfd 100644 --- a/examples/arm-cm/dpp_nucleo-h743zi/bsp.h +++ b/examples/arm-cm/dpp_nucleo-h743zi/bsp.h @@ -1,54 +1,49 @@ -/***************************************************************************** -* Product: BSP for DPP example -* Last updated for: @ref qpc_7_0_0 -* Last updated on 2022-01-21 -* -* Q u a n t u m L e a P s -* --------------------------- -* innovating embedded systems -* -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* -* -*****************************************************************************/ -#ifndef BSP_H -#define BSP_H +//============================================================================ +// Product: Board Support Package example +// Last Updated for Version: 7.3.0 +// Date of the Last Update: 2023-08-12 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +//============================================================================ +#ifndef BSP_H_ +#define BSP_H_ #define BSP_TICKS_PER_SEC 100U void BSP_init(void); +void BSP_start(void); void BSP_displayPaused(uint8_t paused); void BSP_displayPhilStat(uint8_t n, char const *stat); void BSP_terminate(int16_t result); -void BSP_randomSeed(uint32_t seed); /* random seed */ -uint32_t BSP_random(void); /* pseudo-random generator */ +void BSP_randomSeed(uint32_t seed); // random seed +uint32_t BSP_random(void); // pseudo-random generator -/* for testing... */ -void BSP_wait4PB1(void); void BSP_ledOn(void); void BSP_ledOff(void); -extern QTicker ticker0; - -#endif /* BSP_H */ +#endif // BSP_H_ diff --git a/examples/arm-cm/dpp_nucleo-h743zi/dpp.h b/examples/arm-cm/dpp_nucleo-h743zi/dpp.h index da094c2c..e6d1557a 100644 --- a/examples/arm-cm/dpp_nucleo-h743zi/dpp.h +++ b/examples/arm-cm/dpp_nucleo-h743zi/dpp.h @@ -1,92 +1,117 @@ -/*$file${.::dpp.h} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* -* Model: dpp.qm -* File: ${.::dpp.h} -* -* This code has been generated by QM 5.2.4 . -* DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. -* -* SPDX-License-Identifier: GPL-3.0-or-later -* -* This generated code is open source software: you can redistribute it under -* the terms of the GNU General Public License as published by the Free -* Software Foundation. -* -* This code is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -* more details. -* -* NOTE: -* Alternatively, this generated code may be distributed under the terms -* of Quantum Leaps commercial licenses, which expressly supersede the GNU -* General Public License and are specifically designed for licensees -* interested in retaining the proprietary status of their code. -* -* Contact information: -* -* -*/ -/*$endhead${.::dpp.h} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -#ifndef DPP_H -#define DPP_H +//$file${.::dpp.h} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// +// Model: dpp.qm +// File: ${.::dpp.h} +// +// This code has been generated by QM 5.3.0 . +// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. +// +// SPDX-License-Identifier: GPL-3.0-or-later +// +// This generated code is open source software: you can redistribute it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation. +// +// This code is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// NOTE: +// Alternatively, this generated code may be distributed under the terms +// of Quantum Leaps commercial licenses, which expressly supersede the GNU +// General Public License and are specifically designed for licensees +// interested in retaining the proprietary status of their code. +// +// Contact information: +// +// +// +//$endhead${.::dpp.h} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +#ifndef DPP_H_ +#define DPP_H_ -enum DPPSignals { - EAT_SIG = Q_USER_SIG, /* published by Table to let a philosopher eat */ - DONE_SIG, /* published by Philosopher when done eating */ - PAUSE_SIG, /* published by BSP to pause serving forks */ - SERVE_SIG, /* published by BSP to serve re-start serving forks */ - TEST_SIG, /* published by BSP to test the application */ - MAX_PUB_SIG, /* the last published signal */ +//$declare${Shared} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv - HUNGRY_SIG, /* posted direclty to Table from hungry Philo */ - TIMEOUT_SIG, /* used by Philosophers for time events */ - MAX_SIG /* the last signal */ +//${Shared::AppSignals} ...................................................... +enum AppSignals { + EAT_SIG = Q_USER_SIG, // published by Table to let a Philo eat + DONE_SIG, // published by Philo when done eating + PAUSE_SIG, // published by BSP to pause the application + SERVE_SIG, // published by BSP to serve re-start serving forks + TEST_SIG, // published by BSP to test the application + MAX_PUB_SIG, // the last published signal + + TIMEOUT_SIG, // posted by time event to Philo + HUNGRY_SIG, // posted by hungry Philo to Table + MAX_SIG // the last signal }; -/*$declare${Events::TableEvt} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//${Shared::produce_sig_dict} ................................................ +#ifdef Q_SPY +static inline void produce_sig_dict(void) { + QS_SIG_DICTIONARY(EAT_SIG, (void *)0); + QS_SIG_DICTIONARY(DONE_SIG, (void *)0); + QS_SIG_DICTIONARY(PAUSE_SIG, (void *)0); + QS_SIG_DICTIONARY(SERVE_SIG, (void *)0); + QS_SIG_DICTIONARY(TEST_SIG, (void *)0); -/*${Events::TableEvt} ......................................................*/ + QS_SIG_DICTIONARY(TIMEOUT_SIG, (void *)0); + QS_SIG_DICTIONARY(HUNGRY_SIG, (void *)0); +} +#endif // def Q_SPY + +//${Shared::N_PHILO} ......................................................... +#define N_PHILO ((uint8_t)5U) + +//${Shared::TableEvt} ........................................................ typedef struct { -/* protected: */ +// protected: QEvt super; -/* public: */ - uint8_t philoNum; +// public: + uint8_t philoId; } TableEvt; -/*$enddecl${Events::TableEvt} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/* number of philosophers */ -#define N_PHILO ((uint8_t)5) +// public: -/*$declare${AOs::Philo_ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +#ifdef QEVT_DYN_CTOR +static inline TableEvt * TableEvt_ctor(TableEvt * const me, + uint8_t id) +{ + if (me != (TableEvt *)0) { + // don't call QEvt_ctor() because the initialization of all + // QEvt attributes is already done in QF_QF_newX_() + me->philoId = id; + } + return me; +} +#endif // def QEVT_DYN_CTOR -/*${AOs::Philo_ctor} .......................................................*/ -void Philo_ctor(void); -/*$enddecl${AOs::Philo_ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*$declare${AOs::AO_Philo[N_PHILO]} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${AOs::AO_Philo[N_PHILO]} ................................................*/ +//${Shared::AO_Philo[N_PHILO]} ............................................... extern QActive * const AO_Philo[N_PHILO]; -/*$enddecl${AOs::AO_Philo[N_PHILO]} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*$declare${AOs::Table_ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//${Shared::Philo_ctor} ...................................................... +void Philo_ctor(uint_fast8_t const id); -/*${AOs::Table_ctor} .......................................................*/ -void Table_ctor(void); -/*$enddecl${AOs::Table_ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*$declare${AOs::AO_Table} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${AOs::AO_Table} .........................................................*/ +//${Shared::AO_Table} ........................................................ extern QActive * const AO_Table; -/*$enddecl${AOs::AO_Table} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -#ifdef QP_INC_QXK_H_ - void Test1_ctor(void); - extern QXThread * const XT_Test1; - void Test2_ctor(void); - extern QXThread * const XT_Test2; -#endif /* QP_INC_QXK_H_ */ +//${Shared::Table_ctor} ...................................................... +void Table_ctor(void); +//$enddecl${Shared} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -#endif /* DPP_H */ +#ifdef QXK_H_ +extern QXThread * const TH_XThread1; +void XThread1_ctor(void); + +extern QXThread * const TH_XThread2; +void XThread2_ctor(void); + +extern QXSemaphore TH_sema; +extern QXMutex TH_mutex; + +#endif // QXK_H_ + +#endif // DPP_H_ diff --git a/examples/arm-cm/dpp_nucleo-h743zi/dpp.qm b/examples/arm-cm/dpp_nucleo-h743zi/dpp.qm index f1256b39..ac9f2bc9 100644 --- a/examples/arm-cm/dpp_nucleo-h743zi/dpp.qm +++ b/examples/arm-cm/dpp_nucleo-h743zi/dpp.qm @@ -1,185 +1,242 @@ - + Dining Philosopher Problem example - - - + + + + + { + EAT_SIG = Q_USER_SIG, // published by Table to let a Philo eat + DONE_SIG, // published by Philo when done eating + PAUSE_SIG, // published by BSP to pause the application + SERVE_SIG, // published by BSP to serve re-start serving forks + TEST_SIG, // published by BSP to test the application + MAX_PUB_SIG, // the last published signal + + TIMEOUT_SIG, // posted by time event to Philo + HUNGRY_SIG, // posted by hungry Philo to Table + MAX_SIG // the last signal +}; + + + + QS_SIG_DICTIONARY(EAT_SIG, (void *)0); +QS_SIG_DICTIONARY(DONE_SIG, (void *)0); +QS_SIG_DICTIONARY(PAUSE_SIG, (void *)0); +QS_SIG_DICTIONARY(SERVE_SIG, (void *)0); +QS_SIG_DICTIONARY(TEST_SIG, (void *)0); + +QS_SIG_DICTIONARY(TIMEOUT_SIG, (void *)0); +QS_SIG_DICTIONARY(HUNGRY_SIG, (void *)0); + + + + ((uint8_t)5U) + + - - + + + + + + + if (me != (TableEvt *)0) { + // don't call QEvt_ctor() because the initialization of all + // QEvt attributes is already done in QF_QF_newX_() + me->philoId = id; +} +return me; + + + + = { + &Philo_inst[0].super, + &Philo_inst[1].super, + &Philo_inst[2].super, + &Philo_inst[3].super, + &Philo_inst[4].super +}; + + + + + + Philo * const me = &Philo_inst[id]; +QActive_ctor(&me->super, Q_STATE_CAST(&Philo_initial)); +QTimeEvt_ctorX(&me->timeEvt, &me->super, TIMEOUT_SIG, 0U), +me->id = (uint8_t)id; + + + + = &Table_inst.super; + + + + Table * const me = &Table_inst; +QActive_ctor(&me->super, Q_STATE_CAST(&Table_initial)); +for (uint8_t n = 0U; n < N_PHILO; ++n) { + me->fork[n] = FREE; + me->isHungry[n] = false; +} + - - - The array of static insts of the Philo class (Singleton pattern) - + The Philo AO and the N_PHILO instances + + + + - + - static uint8_t registered = (uint8_t)0; /* starts off with 0, per C-standard */ -(void)par; /* unused parameter */ -if (registered == (uint8_t)0) { - registered = (uint8_t)1; + Q_UNUSED_PAR(par); - QS_OBJ_DICTIONARY(&Philo_inst[0]); - QS_OBJ_DICTIONARY(&Philo_inst[0].timeEvt); - QS_OBJ_DICTIONARY(&Philo_inst[1]); - QS_OBJ_DICTIONARY(&Philo_inst[1].timeEvt); - QS_OBJ_DICTIONARY(&Philo_inst[2]); - QS_OBJ_DICTIONARY(&Philo_inst[2].timeEvt); - QS_OBJ_DICTIONARY(&Philo_inst[3]); - QS_OBJ_DICTIONARY(&Philo_inst[3].timeEvt); - QS_OBJ_DICTIONARY(&Philo_inst[4]); - QS_OBJ_DICTIONARY(&Philo_inst[4].timeEvt); - - QS_FUN_DICTIONARY(&Philo_initial); - QS_FUN_DICTIONARY(&Philo_thinking); - QS_FUN_DICTIONARY(&Philo_hungry); - QS_FUN_DICTIONARY(&Philo_eating); -} -QS_SIG_DICTIONARY(HUNGRY_SIG, me); /* signal for each Philos */ -QS_SIG_DICTIONARY(TIMEOUT_SIG, me); /* signal for each Philos */ +QS_OBJ_ARR_DICTIONARY(&Philo_inst[me->id], me->id); +QS_OBJ_ARR_DICTIONARY(&Philo_inst[me->id].timeEvt, me->id); QActive_subscribe(&me->super, EAT_SIG); QActive_subscribe(&me->super, TEST_SIG); - + - QTimeEvt_armX(&me->timeEvt, THINK_TIME, 0U); - QTimeEvt_disarm(&me->timeEvt); + QTimeEvt_armX(&me->timeEvt, think_time(), 0U); + (void)QTimeEvt_disarm(&me->timeEvt); - - + + - /* EAT or DONE must be for other Philos than this one */ -Q_ASSERT(Q_EVT_CAST(TableEvt)->philoNum != PHILO_ID(me)); - + // EAT or DONE must be for other Philos than this one +Q_ASSERT(Q_EVT_CAST(TableEvt)->philoId != me->id); + - + - + - + - TableEvt *pe = Q_NEW(TableEvt, HUNGRY_SIG); -pe->philoNum = PHILO_ID(me); -QACTIVE_POST(AO_Table, &pe->super, me); + #ifdef QEVT_DYN_CTOR +TableEvt const *pe = Q_NEW(TableEvt, HUNGRY_SIG, me->id); +#else +TableEvt *pe = Q_NEW(TableEvt, HUNGRY_SIG); +pe->philoId = me->id; +#endif +QACTIVE_POST(AO_Table, &pe->super, &me->super); - + - Q_EVT_CAST(TableEvt)->philoNum == PHILO_ID(me) - - + Q_EVT_CAST(TableEvt)->philoId == me->id + + - + - /* DONE must be for other Philos than this one */ -Q_ASSERT(Q_EVT_CAST(TableEvt)->philoNum != PHILO_ID(me)); - + // DONE must be for other Philos than this one +Q_ASSERT(Q_EVT_CAST(TableEvt)->philoId != me->id); + - + - QTimeEvt_armX(&me->timeEvt, EAT_TIME, 0U); - TableEvt *pe = Q_NEW(TableEvt, DONE_SIG); -pe->philoNum = PHILO_ID(me); + QTimeEvt_armX(&me->timeEvt, eat_time(), 0U); + (void)QTimeEvt_disarm(&me->timeEvt); + +#ifdef QEVT_DYN_CTOR +TableEvt const *pe = Q_NEW(TableEvt, DONE_SIG, me->id); +#else +TableEvt *pe = Q_NEW(TableEvt, DONE_SIG); +pe->philoId = me->id; +#endif QACTIVE_PUBLISH(&pe->super, &me->super); - - + + - /* EAT or DONE must be for other Philos than this one */ -Q_ASSERT(Q_EVT_CAST(TableEvt)->philoNum != PHILO_ID(me)); - + // EAT or DONE must be for other Philos than this one +Q_ASSERT(Q_EVT_CAST(TableEvt)->philoId != me->id); + - + - + - - - The only static inst of the Table class (Singleton pattern) - - + + + - + - uint8_t n; -(void)par; /* unused parameter */ + Q_UNUSED_PAR(par); -QS_OBJ_DICTIONARY(&Table_inst); - -QS_SIG_DICTIONARY(DONE_SIG, (void *)0); /* global signals */ -QS_SIG_DICTIONARY(EAT_SIG, (void *)0); -QS_SIG_DICTIONARY(PAUSE_SIG, (void *)0); -QS_SIG_DICTIONARY(SERVE_SIG, (void *)0); -QS_SIG_DICTIONARY(TEST_SIG, (void *)0); - -QS_SIG_DICTIONARY(HUNGRY_SIG, me); /* signal just for Table */ +#ifdef Q_SPY +Table *Table_inst = me; +QS_OBJ_DICTIONARY(Table_inst); +#endif QActive_subscribe(&me->super, DONE_SIG); QActive_subscribe(&me->super, PAUSE_SIG); QActive_subscribe(&me->super, SERVE_SIG); QActive_subscribe(&me->super, TEST_SIG); -for (n = 0U; n < N_PHILO; ++n) { +for (uint8_t n = 0U; n < N_PHILO; ++n) { me->fork[n] = FREE; - me->isHungry[n] = 0U; - BSP_displayPhilStat(n, "thinking"); + me->isHungry[n] = false; + BSP_displayPhilStat(n, THINKING); } - + @@ -187,128 +244,139 @@ for (n = 0U; n < N_PHILO; ++n) { - + Q_ERROR(); - + - uint8_t n; -for (n = 0U; n < N_PHILO; ++n) { /* give permissions to eat... */ - if ((me->isHungry[n] != 0U) - && (me->fork[LEFT(n)] == FREE) + // give permissions to eat... +for (uint8_t n = 0U; n < N_PHILO; ++n) { + if (me->isHungry[n] + && (me->fork[left(n)] == FREE) && (me->fork[n] == FREE)) { - TableEvt *te; - - me->fork[LEFT(n)] = USED; + me->fork[left(n)] = USED; me->fork[n] = USED; - te = Q_NEW(TableEvt, EAT_SIG); - te->philoNum = n; - QACTIVE_PUBLISH(&te->super, &me->super); - me->isHungry[n] = 0U; - BSP_displayPhilStat(n, "eating "); +#ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, EAT_SIG, n); +#else + TableEvt *pe = Q_NEW(TableEvt, EAT_SIG); + pe->philoId = n; +#endif + QACTIVE_PUBLISH(&pe->super, &me->super); + me->isHungry[n] = false; + BSP_displayPhilStat(n, EATING); } } - uint8_t n, m; + uint8_t n = Q_EVT_CAST(TableEvt)->philoId; -n = Q_EVT_CAST(TableEvt)->philoNum; -/* phil ID must be in range and he must be not hungry */ -Q_ASSERT((n < N_PHILO) && (me->isHungry[n] == 0U)); +// phil ID must be in range and he must be not hungry +Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); -BSP_displayPhilStat(n, "hungry "); -m = LEFT(n); +BSP_displayPhilStat(n, HUNGRY); +uint8_t m = left(n); (me->fork[m] == FREE) && (me->fork[n] == FREE) - TableEvt *pe; -me->fork[m] = USED; + me->fork[m] = USED; me->fork[n] = USED; -pe = Q_NEW(TableEvt, EAT_SIG); -pe->philoNum = n; +#ifdef QEVT_DYN_CTOR +TableEvt const *pe = Q_NEW(TableEvt, EAT_SIG, n); +#else +TableEvt *pe = Q_NEW(TableEvt, EAT_SIG); +pe->philoId = n; +#endif QACTIVE_PUBLISH(&pe->super, &me->super); -BSP_displayPhilStat(n, "eating "); - +BSP_displayPhilStat(n, EATING); + else - me->isHungry[n] = 1U; - - + me->isHungry[n] = true; + + - + - uint8_t n, m; -TableEvt *pe; + uint8_t n = Q_EVT_CAST(TableEvt)->philoId; -n = Q_EVT_CAST(TableEvt)->philoNum; -/* phil ID must be in range and he must be not hungry */ -Q_ASSERT((n < N_PHILO) && (me->isHungry[n] == 0U)); +// phil ID must be in range and he must be not hungry +Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); -BSP_displayPhilStat(n, "thinking"); -m = LEFT(n); -/* both forks of Phil[n] must be used */ +BSP_displayPhilStat(n, THINKING); +uint8_t m = left(n); + +// both forks of Phil[n] must be used Q_ASSERT((me->fork[n] == USED) && (me->fork[m] == USED)); me->fork[m] = FREE; me->fork[n] = FREE; -m = RIGHT(n); /* check the right neighbor */ +m = right(n); // check the right neighbor -if ((me->isHungry[m] != 0U) && (me->fork[m] == FREE)) { +if (me->isHungry[m] && (me->fork[m] == FREE)) { me->fork[n] = USED; me->fork[m] = USED; - me->isHungry[m] = 0U; - pe = Q_NEW(TableEvt, EAT_SIG); - pe->philoNum = m; + me->isHungry[m] = false; +#ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, EAT_SIG, m); +#else + TableEvt *pe = Q_NEW(TableEvt, EAT_SIG); + pe->philoId = m; +#endif QACTIVE_PUBLISH(&pe->super, &me->super); - BSP_displayPhilStat(m, "eating "); + BSP_displayPhilStat(m, EATING); } -m = LEFT(n); /* check the left neighbor */ -n = LEFT(m); /* left fork of the left neighbor */ -if ((me->isHungry[m] != 0U) && (me->fork[n] == FREE)) { +m = left(n); // check the left neighbor +n = left(m); // left fork of the left neighbor +if (me->isHungry[m] && (me->fork[n] == FREE)) { me->fork[m] = USED; me->fork[n] = USED; - me->isHungry[m] = 0U; - pe = Q_NEW(TableEvt, EAT_SIG); - pe->philoNum = m; + me->isHungry[m] = false; +#ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, EAT_SIG, m); +#else + TableEvt *pe = Q_NEW(TableEvt, EAT_SIG); + pe->philoId = m; +#endif QACTIVE_PUBLISH(&pe->super, &me->super); - BSP_displayPhilStat(m, "eating "); + BSP_displayPhilStat(m, EATING); } - + Q_ERROR(); - + - + - + @@ -318,170 +386,140 @@ if ((me->isHungry[m] != 0U) && (me->fork[n] == FREE)) { BSP_displayPaused(0U); - + - uint8_t n = Q_EVT_CAST(TableEvt)->philoNum; -/* philo ID must be in range and he must be not hungry */ -Q_ASSERT((n < N_PHILO) && (me->isHungry[n] == 0U)); -me->isHungry[n] = 1U; -BSP_displayPhilStat(n, "hungry "); - + uint8_t n = Q_EVT_CAST(TableEvt)->philoId; + +// philo ID must be in range and he must be not hungry +Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); + +me->isHungry[n] = true; +BSP_displayPhilStat(n, HUNGRY); + - uint8_t n, m; + uint8_t n = Q_EVT_CAST(TableEvt)->philoId; -n = Q_EVT_CAST(TableEvt)->philoNum; -/* phil ID must be in range and he must be not hungry */ -Q_ASSERT((n < N_PHILO) && (me->isHungry[n] == 0U)); +// phil ID must be in range and he must be not hungry +Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); -BSP_displayPhilStat(n, "thinking"); -m = LEFT(n); -/* both forks of Phil[n] must be used */ +BSP_displayPhilStat(n, THINKING); +uint8_t m = left(n); + +// both forks of Phil[n] must be used Q_ASSERT((me->fork[n] == USED) && (me->fork[m] == USED)); me->fork[m] = FREE; me->fork[n] = FREE; - + - + - + - + - - - = { /* "opaque" pointers to Philo AO */ - &Philo_inst[0].super, - &Philo_inst[1].super, - &Philo_inst[2].super, - &Philo_inst[3].super, - &Philo_inst[4].super -}; - - - - = &Table_inst.super; /* "opaque" pointer to Table AO */ - - - - uint8_t n; -Philo *me; -for (n = 0U; n < N_PHILO; ++n) { - me = &Philo_inst[n]; - QActive_ctor(&me->super, Q_STATE_CAST(&Philo_initial)); - QTimeEvt_ctorX(&me->timeEvt, &me->super, TIMEOUT_SIG, 0U); -} - - - - Table *me = &Table_inst; -uint8_t n; - -QActive_ctor(&me->super, Q_STATE_CAST(&Table_initial)); - -for (n = 0U; n < N_PHILO; ++n) { - me->fork[n] = FREE; - me->isHungry[n] = 0U; -} - - #ifndef DPP_H -#define DPP_H + #ifndef DPP_H_ +#define DPP_H_ -enum DPPSignals { - EAT_SIG = Q_USER_SIG, /* published by Table to let a philosopher eat */ - DONE_SIG, /* published by Philosopher when done eating */ - PAUSE_SIG, /* published by BSP to pause serving forks */ - SERVE_SIG, /* published by BSP to serve re-start serving forks */ - TEST_SIG, /* published by BSP to test the application */ - MAX_PUB_SIG, /* the last published signal */ +$declare ${Shared} - HUNGRY_SIG, /* posted direclty to Table from hungry Philo */ - TIMEOUT_SIG, /* used by Philosophers for time events */ - MAX_SIG /* the last signal */ -}; +#ifdef QXK_H_ -$declare(Events::TableEvt) +extern QXThread * const TH_XThread1; +void XThread1_ctor(void); -/* number of philosophers */ -#define N_PHILO ((uint8_t)5) +extern QXThread * const TH_XThread2; +void XThread2_ctor(void); -$declare(AOs::Philo_ctor) -$declare(AOs::AO_Philo[N_PHILO]) +extern QXSemaphore TH_sema; +extern QXMutex TH_mutex; -$declare(AOs::Table_ctor) -$declare(AOs::AO_Table) +#endif // QXK_H_ -#ifdef QP_INC_QXK_H_ - void Test1_ctor(void); - extern QXThread * const XT_Test1; - void Test2_ctor(void); - extern QXThread * const XT_Test2; -#endif /* QP_INC_QXK_H_ */ - -#endif /* DPP_H */ - +#endif // DPP_H_ - #include "qpc.h" -#include "dpp.h" -#include "bsp.h" + #include "qpc.h" // QP/C real-time embedded framework +#include "dpp.h" // DPP Application interface +#include "bsp.h" // Board Support Package +$declare ${AOs::Philo} + +//---------------------------------------------------------------------------- Q_DEFINE_THIS_FILE -/* Active object class -----------------------------------------------------*/ -$declare${AOs::Philo} +// helper function to provide a randomized think time for Philos +static QTimeEvtCtr think_time(void); // prototype +static inline QTimeEvtCtr think_time(void) { + return (QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + + (BSP_TICKS_PER_SEC/2U)); +} -#define THINK_TIME \ - (QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + (BSP_TICKS_PER_SEC/2U)) -#define EAT_TIME \ - (QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + BSP_TICKS_PER_SEC) +// helper function to provide a randomized eat time for Philos +static QTimeEvtCtr eat_time(void); // prototype +static inline QTimeEvtCtr eat_time(void) { + return (QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + + BSP_TICKS_PER_SEC); +} +//---------------------------------------------------------------------------- -/* helper macro to provide the ID of Philo "me_" */ -#define PHILO_ID(me_) ((uint8_t)((me_) - &Philo_inst[0])) - -$define${AOs::AO_Philo[N_PHILO]} -$define${AOs::Philo_ctor} -$define${AOs::Philo} +$define ${Shared::Philo_ctor} +$define ${Shared::AO_Philo[N_PHILO]} +$define ${AOs::Philo} - #include "qpc.h" -#include "dpp.h" -#include "bsp.h" + #include "qpc.h" // QP/C real-time embedded framework +#include "dpp.h" // DPP Application interface +#include "bsp.h" // Board Support Package +$declare ${AOs::Table} + +//---------------------------------------------------------------------------- Q_DEFINE_THIS_FILE -/* Active object class -----------------------------------------------------*/ -$declare${AOs::Table} +// helper function to provide the RIGHT neighbor of a Philo[n] +static inline uint8_t right(uint8_t const n) { + return (uint8_t)((n + (N_PHILO - 1U)) % N_PHILO); +} -#define RIGHT(n_) ((uint8_t)(((n_) + (N_PHILO - 1U)) % N_PHILO)) -#define LEFT(n_) ((uint8_t)(((n_) + 1U) % N_PHILO)) -#define FREE ((uint8_t)0) -#define USED ((uint8_t)1) +// helper function to provide the LEFT neighbor of a Philo[n] +static inline uint8_t left(uint8_t const n) { + return (uint8_t)((n + 1U) % N_PHILO); +} -$define${AOs::AO_Table} -$define${AOs::Table_ctor} -$define${AOs::Table} +#define FREE ((uint8_t)0U) +#define USED ((uint8_t)1U) + +#define THINKING "thinking" +#define HUNGRY "hungry " +#define EATING "eating " + +//---------------------------------------------------------------------------- + +$define ${Shared::Table_ctor} +$define ${Shared::AO_Table} +$define ${AOs::Table} diff --git a/examples/arm-cm/dpp_nucleo-h743zi/main.c b/examples/arm-cm/dpp_nucleo-h743zi/main.c new file mode 100644 index 00000000..deac175a --- /dev/null +++ b/examples/arm-cm/dpp_nucleo-h743zi/main.c @@ -0,0 +1,44 @@ +//============================================================================ +// APP example +// Last updated for version 7.3.0 +// Last updated on 2023-08-09 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. +// +// This program is open source software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Alternatively, this program may be distributed and modified under the +// terms of Quantum Leaps commercial licenses, which expressly supersede +// the GNU General Public License and are specifically designed for +// licensees interested in retaining the proprietary status of their code. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Contact information: +// +// +//============================================================================ +#include "qpc.h" // QP/C real-time embedded framework +#include "dpp.h" // DPP Application interface +#include "bsp.h" // Board Support Package + +//............................................................................ +int main() { + QF_init(); // initialize the framework and the underlying RT kernel + BSP_init(); // initialize the BSP + BSP_start(); // start the AOs/Threads + return QF_run(); // run the QF application +} diff --git a/examples/arm-cm/dpp_nucleo-h743zi/philo.c b/examples/arm-cm/dpp_nucleo-h743zi/philo.c index a5be8e68..eb6be531 100644 --- a/examples/arm-cm/dpp_nucleo-h743zi/philo.c +++ b/examples/arm-cm/dpp_nucleo-h743zi/philo.c @@ -1,167 +1,159 @@ -/*$file${.::philo.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* -* Model: dpp.qm -* File: ${.::philo.c} -* -* This code has been generated by QM 5.2.4 . -* DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. -* -* SPDX-License-Identifier: GPL-3.0-or-later -* -* This generated code is open source software: you can redistribute it under -* the terms of the GNU General Public License as published by the Free -* Software Foundation. -* -* This code is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -* more details. -* -* NOTE: -* Alternatively, this generated code may be distributed under the terms -* of Quantum Leaps commercial licenses, which expressly supersede the GNU -* General Public License and are specifically designed for licensees -* interested in retaining the proprietary status of their code. -* -* Contact information: -* -* -*/ -/*$endhead${.::philo.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -#include "qpc.h" -#include "dpp.h" -#include "bsp.h" +//$file${.::philo.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// +// Model: dpp.qm +// File: ${.::philo.c} +// +// This code has been generated by QM 5.3.0 . +// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. +// +// SPDX-License-Identifier: GPL-3.0-or-later +// +// This generated code is open source software: you can redistribute it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation. +// +// This code is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// NOTE: +// Alternatively, this generated code may be distributed under the terms +// of Quantum Leaps commercial licenses, which expressly supersede the GNU +// General Public License and are specifically designed for licensees +// interested in retaining the proprietary status of their code. +// +// Contact information: +// +// +// +//$endhead${.::philo.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +#include "qpc.h" // QP/C real-time embedded framework +#include "dpp.h" // DPP Application interface +#include "bsp.h" // Board Support Package -Q_DEFINE_THIS_FILE +//$declare${AOs::Philo} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/* Active object class -----------------------------------------------------*/ -/*$declare${AOs::Philo} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${AOs::Philo} ............................................................*/ +//${AOs::Philo} .............................................................. typedef struct Philo { -/* protected: */ +// protected: QActive super; -/* public: */ - -/* private: */ +// private: QTimeEvt timeEvt; + uint8_t id; + +// public: } Philo; + extern Philo Philo_inst[N_PHILO]; -/* protected: */ +// protected: static QState Philo_initial(Philo * const me, void const * const par); static QState Philo_thinking(Philo * const me, QEvt const * const e); static QState Philo_hungry(Philo * const me, QEvt const * const e); static QState Philo_eating(Philo * const me, QEvt const * const e); -/*$enddecl${AOs::Philo} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$enddecl${AOs::Philo} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -#define THINK_TIME \ - (QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + (BSP_TICKS_PER_SEC/2U)) -#define EAT_TIME \ - (QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + BSP_TICKS_PER_SEC) +//---------------------------------------------------------------------------- +Q_DEFINE_THIS_FILE -/* helper macro to provide the ID of Philo "me_" */ -#define PHILO_ID(me_) ((uint8_t)((me_) - &Philo_inst[0])) +// helper function to provide a randomized think time for Philos +static QTimeEvtCtr think_time(void); // prototype +static inline QTimeEvtCtr think_time(void) { + return (QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + + (BSP_TICKS_PER_SEC/2U)); +} -/*$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* Check for the minimum required QP version */ -#if (QP_VERSION < 700U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) -#error qpc version 7.0.0 or higher required +// helper function to provide a randomized eat time for Philos +static QTimeEvtCtr eat_time(void); // prototype +static inline QTimeEvtCtr eat_time(void) { + return (QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + + BSP_TICKS_PER_SEC); +} +//---------------------------------------------------------------------------- + +//$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// Check for the minimum required QP version +#if (QP_VERSION < 730U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) +#error qpc version 7.3.0 or higher required #endif -/*$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -/*$define${AOs::AO_Philo[N_PHILO]} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//$define${Shared::Philo_ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/*${AOs::AO_Philo[N_PHILO]} ................................................*/ -QActive * const AO_Philo[N_PHILO] = { /* "opaque" pointers to Philo AO */ +//${Shared::Philo_ctor} ...................................................... +void Philo_ctor(uint_fast8_t const id) { + Philo * const me = &Philo_inst[id]; + QActive_ctor(&me->super, Q_STATE_CAST(&Philo_initial)); + QTimeEvt_ctorX(&me->timeEvt, &me->super, TIMEOUT_SIG, 0U), + me->id = (uint8_t)id; +} +//$enddef${Shared::Philo_ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +//$define${Shared::AO_Philo[N_PHILO]} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${Shared::AO_Philo[N_PHILO]} ............................................... +QActive * const AO_Philo[N_PHILO] = { &Philo_inst[0].super, &Philo_inst[1].super, &Philo_inst[2].super, &Philo_inst[3].super, &Philo_inst[4].super }; -/*$enddef${AOs::AO_Philo[N_PHILO]} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*$define${AOs::Philo_ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//$enddef${Shared::AO_Philo[N_PHILO]} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +//$define${AOs::Philo} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/*${AOs::Philo_ctor} .......................................................*/ -void Philo_ctor(void) { - uint8_t n; - Philo *me; - for (n = 0U; n < N_PHILO; ++n) { - me = &Philo_inst[n]; - QActive_ctor(&me->super, Q_STATE_CAST(&Philo_initial)); - QTimeEvt_ctorX(&me->timeEvt, &me->super, TIMEOUT_SIG, 0U); - } -} -/*$enddef${AOs::Philo_ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*$define${AOs::Philo} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${AOs::Philo} ............................................................*/ +//${AOs::Philo} .............................................................. Philo Philo_inst[N_PHILO]; -/*${AOs::Philo::SM} ........................................................*/ +//${AOs::Philo::SM} .......................................................... static QState Philo_initial(Philo * const me, void const * const par) { - /*${AOs::Philo::SM::initial} */ - static uint8_t registered = (uint8_t)0; /* starts off with 0, per C-standard */ - (void)par; /* unused parameter */ - if (registered == (uint8_t)0) { - registered = (uint8_t)1; + //${AOs::Philo::SM::initial} + Q_UNUSED_PAR(par); - QS_OBJ_DICTIONARY(&Philo_inst[0]); - QS_OBJ_DICTIONARY(&Philo_inst[0].timeEvt); - QS_OBJ_DICTIONARY(&Philo_inst[1]); - QS_OBJ_DICTIONARY(&Philo_inst[1].timeEvt); - QS_OBJ_DICTIONARY(&Philo_inst[2]); - QS_OBJ_DICTIONARY(&Philo_inst[2].timeEvt); - QS_OBJ_DICTIONARY(&Philo_inst[3]); - QS_OBJ_DICTIONARY(&Philo_inst[3].timeEvt); - QS_OBJ_DICTIONARY(&Philo_inst[4]); - QS_OBJ_DICTIONARY(&Philo_inst[4].timeEvt); - - QS_FUN_DICTIONARY(&Philo_initial); - QS_FUN_DICTIONARY(&Philo_thinking); - QS_FUN_DICTIONARY(&Philo_hungry); - QS_FUN_DICTIONARY(&Philo_eating); - } - QS_SIG_DICTIONARY(HUNGRY_SIG, me); /* signal for each Philos */ - QS_SIG_DICTIONARY(TIMEOUT_SIG, me); /* signal for each Philos */ + QS_OBJ_ARR_DICTIONARY(&Philo_inst[me->id], me->id); + QS_OBJ_ARR_DICTIONARY(&Philo_inst[me->id].timeEvt, me->id); QActive_subscribe(&me->super, EAT_SIG); QActive_subscribe(&me->super, TEST_SIG); + + QS_FUN_DICTIONARY(&Philo_thinking); + QS_FUN_DICTIONARY(&Philo_hungry); + QS_FUN_DICTIONARY(&Philo_eating); + return Q_TRAN(&Philo_thinking); } -/*${AOs::Philo::SM::thinking} ..............................................*/ +//${AOs::Philo::SM::thinking} ................................................ static QState Philo_thinking(Philo * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${AOs::Philo::SM::thinking} */ + //${AOs::Philo::SM::thinking} case Q_ENTRY_SIG: { - QTimeEvt_armX(&me->timeEvt, THINK_TIME, 0U); + QTimeEvt_armX(&me->timeEvt, think_time(), 0U); status_ = Q_HANDLED(); break; } - /*${AOs::Philo::SM::thinking} */ + //${AOs::Philo::SM::thinking} case Q_EXIT_SIG: { - QTimeEvt_disarm(&me->timeEvt); + (void)QTimeEvt_disarm(&me->timeEvt); status_ = Q_HANDLED(); break; } - /*${AOs::Philo::SM::thinking::TIMEOUT} */ + //${AOs::Philo::SM::thinking::TIMEOUT} case TIMEOUT_SIG: { status_ = Q_TRAN(&Philo_hungry); break; } - /*${AOs::Philo::SM::thinking::EAT, DONE} */ - case EAT_SIG: /* intentionally fall through */ + //${AOs::Philo::SM::thinking::EAT, DONE} + case EAT_SIG: // intentionally fall through case DONE_SIG: { - /* EAT or DONE must be for other Philos than this one */ - Q_ASSERT(Q_EVT_CAST(TableEvt)->philoNum != PHILO_ID(me)); + // EAT or DONE must be for other Philos than this one + Q_ASSERT(Q_EVT_CAST(TableEvt)->philoId != me->id); status_ = Q_HANDLED(); break; } - /*${AOs::Philo::SM::thinking::TEST} */ + //${AOs::Philo::SM::thinking::TEST} case TEST_SIG: { status_ = Q_HANDLED(); break; @@ -174,22 +166,26 @@ static QState Philo_thinking(Philo * const me, QEvt const * const e) { return status_; } -/*${AOs::Philo::SM::hungry} ................................................*/ +//${AOs::Philo::SM::hungry} .................................................. static QState Philo_hungry(Philo * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${AOs::Philo::SM::hungry} */ + //${AOs::Philo::SM::hungry} case Q_ENTRY_SIG: { + #ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, HUNGRY_SIG, me->id); + #else TableEvt *pe = Q_NEW(TableEvt, HUNGRY_SIG); - pe->philoNum = PHILO_ID(me); - QACTIVE_POST(AO_Table, &pe->super, me); + pe->philoId = me->id; + #endif + QACTIVE_POST(AO_Table, &pe->super, &me->super); status_ = Q_HANDLED(); break; } - /*${AOs::Philo::SM::hungry::EAT} */ + //${AOs::Philo::SM::hungry::EAT} case EAT_SIG: { - /*${AOs::Philo::SM::hungry::EAT::[Q_EVT_CAST(TableEvt)->philoNum=~} */ - if (Q_EVT_CAST(TableEvt)->philoNum == PHILO_ID(me)) { + //${AOs::Philo::SM::hungry::EAT::[e->philoId==me->iid]} + if (Q_EVT_CAST(TableEvt)->philoId == me->id) { status_ = Q_TRAN(&Philo_eating); } else { @@ -197,10 +193,10 @@ static QState Philo_hungry(Philo * const me, QEvt const * const e) { } break; } - /*${AOs::Philo::SM::hungry::DONE} */ + //${AOs::Philo::SM::hungry::DONE} case DONE_SIG: { - /* DONE must be for other Philos than this one */ - Q_ASSERT(Q_EVT_CAST(TableEvt)->philoNum != PHILO_ID(me)); + // DONE must be for other Philos than this one + Q_ASSERT(Q_EVT_CAST(TableEvt)->philoId != me->id); status_ = Q_HANDLED(); break; } @@ -212,34 +208,40 @@ static QState Philo_hungry(Philo * const me, QEvt const * const e) { return status_; } -/*${AOs::Philo::SM::eating} ................................................*/ +//${AOs::Philo::SM::eating} .................................................. static QState Philo_eating(Philo * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${AOs::Philo::SM::eating} */ + //${AOs::Philo::SM::eating} case Q_ENTRY_SIG: { - QTimeEvt_armX(&me->timeEvt, EAT_TIME, 0U); + QTimeEvt_armX(&me->timeEvt, eat_time(), 0U); status_ = Q_HANDLED(); break; } - /*${AOs::Philo::SM::eating} */ + //${AOs::Philo::SM::eating} case Q_EXIT_SIG: { + (void)QTimeEvt_disarm(&me->timeEvt); + + #ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, DONE_SIG, me->id); + #else TableEvt *pe = Q_NEW(TableEvt, DONE_SIG); - pe->philoNum = PHILO_ID(me); + pe->philoId = me->id; + #endif QACTIVE_PUBLISH(&pe->super, &me->super); status_ = Q_HANDLED(); break; } - /*${AOs::Philo::SM::eating::TIMEOUT} */ + //${AOs::Philo::SM::eating::TIMEOUT} case TIMEOUT_SIG: { status_ = Q_TRAN(&Philo_thinking); break; } - /*${AOs::Philo::SM::eating::EAT, DONE} */ - case EAT_SIG: /* intentionally fall through */ + //${AOs::Philo::SM::eating::EAT, DONE} + case EAT_SIG: // intentionally fall through case DONE_SIG: { - /* EAT or DONE must be for other Philos than this one */ - Q_ASSERT(Q_EVT_CAST(TableEvt)->philoNum != PHILO_ID(me)); + // EAT or DONE must be for other Philos than this one + Q_ASSERT(Q_EVT_CAST(TableEvt)->philoId != me->id); status_ = Q_HANDLED(); break; } @@ -250,4 +252,4 @@ static QState Philo_eating(Philo * const me, QEvt const * const e) { } return status_; } -/*$enddef${AOs::Philo} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$enddef${AOs::Philo} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/examples/arm-cm/dpp_nucleo-h743zi/qk/armclang/dpp-qk.sct b/examples/arm-cm/dpp_nucleo-h743zi/qk/armclang/dpp-qk.sct new file mode 100644 index 00000000..c3e0c01e --- /dev/null +++ b/examples/arm-cm/dpp_nucleo-h743zi/qk/armclang/dpp-qk.sct @@ -0,0 +1,26 @@ +; ************************************************************* +; *** Scatter-Loading Description File generated by uVision *** +; +; Modified by Quantum Leaps: +; added STACK as the first section in RW_STACK +; ************************************************************* + +LR_IROM1 0x08000000 0x00200000 { ; load region size_region + ER_IROM1 0x08000000 0x00200000 { ; load address = execution address + *.o (RESET, +First) + *(InRoot$$Sections) + .ANY (+RO) + .ANY (+XO) + } + + RW_STACK 0x20000000 { ; <== Quantum Leaps + * (STACK, +First) + } + RW_IRAM1 +0 (0x00020000 - 2048) { ; NOTE: 2048 assumed for STACK size! + .ANY (+RW +ZI) + } + RW_IRAM2 0x24000000 0x00080000 { + .ANY (+RW +ZI) + } +} + diff --git a/examples/arm-cm/dpp_nucleo-h743zi/qk/armclang/dpp-qk.uvoptx b/examples/arm-cm/dpp_nucleo-h743zi/qk/armclang/dpp-qk.uvoptx index ea946d50..560df8cb 100644 --- a/examples/arm-cm/dpp_nucleo-h743zi/qk/armclang/dpp-qk.uvoptx +++ b/examples/arm-cm/dpp_nucleo-h743zi/qk/armclang/dpp-qk.uvoptx @@ -75,7 +75,7 @@ 1 0 - 0 + 1 18 @@ -140,7 +140,7 @@ 0 DLGTARM - (1010=-1,-1,-1,-1,0)(6017=-1,-1,-1,-1,0)(1008=-1,-1,-1,-1,0)(6016=-1,-1,-1,-1,0)(1012=3268,1338,3745,1653,0) + (1010=3041,603,3491,1160,1)(6017=-1,-1,-1,-1,0)(1008=-1,-1,-1,-1,0)(6016=-1,-1,-1,-1,0)(1012=3268,1338,3745,1653,0) 0 @@ -148,24 +148,7 @@
- - - 0 - 0 - 68 - 1 -
134227432
- 0 - 0 - 0 - 0 - 0 - 1 - ..\main.c - - \\dpp_qk\../main.c\68 -
-
+ 1 @@ -484,7 +467,7 @@ 1 0 - 1 + 0 18 @@ -549,7 +532,7 @@ 0 DLGTARM - (1010=-1,-1,-1,-1,0)(6017=-1,-1,-1,-1,0)(1008=-1,-1,-1,-1,0)(6016=-1,-1,-1,-1,0)(1012=2104,292,2581,607,0) + (1010=3008,635,3458,1192,1)(6017=-1,-1,-1,-1,0)(1008=-1,-1,-1,-1,0)(6016=-1,-1,-1,-1,0)(1012=2104,292,2581,607,0) 0 @@ -557,7 +540,24 @@ - + + + 0 + 0 + 81 + 1 +
134233186
+ 0 + 0 + 0 + 0 + 0 + 1 + ..\..\..\..\..\ports\arm-cm\qk\armclang\qk_port.c + + \\dpp_qk\../../../../../ports/arm-cm/qk/armclang/qk_port.c\81 +
+
1 @@ -647,18 +647,6 @@ 1 2 - 1 - 0 - 0 - 0 - ..\main.c - main.c - 0 - 0 - - - 1 - 3 5 0 0 @@ -670,7 +658,7 @@ 1 - 4 + 3 5 0 0 @@ -682,7 +670,7 @@ 1 - 5 + 4 1 0 0 @@ -694,7 +682,7 @@ 1 - 6 + 5 1 0 0 @@ -706,13 +694,13 @@ 1 - 7 - 8 + 6 + 1 0 0 0 - ..\..\..\..\..\include\qstamp.c - qstamp.c + ..\..\main.c + main.c 0 0 @@ -726,7 +714,7 @@ 0 2 - 8 + 7 2 0 0 @@ -738,7 +726,7 @@ 2 - 9 + 8 1 0 0 @@ -750,7 +738,7 @@ 2 - 10 + 9 5 0 0 @@ -762,7 +750,7 @@ 2 - 11 + 10 1 0 0 @@ -774,7 +762,7 @@ 2 - 12 + 11 1 0 0 @@ -794,7 +782,7 @@ 0 3 - 13 + 12 1 0 0 @@ -806,7 +794,7 @@ 3 - 14 + 13 1 0 0 @@ -818,7 +806,7 @@ 3 - 15 + 14 1 0 0 @@ -830,7 +818,7 @@ 3 - 16 + 15 1 0 0 @@ -842,7 +830,7 @@ 3 - 17 + 16 1 0 0 @@ -854,7 +842,7 @@ 3 - 18 + 17 1 0 0 @@ -866,7 +854,7 @@ 3 - 19 + 18 1 0 0 @@ -878,7 +866,7 @@ 3 - 20 + 19 1 0 0 @@ -898,7 +886,7 @@ 0 4 - 21 + 20 1 0 0 @@ -910,7 +898,7 @@ 4 - 22 + 21 1 0 0 @@ -922,7 +910,7 @@ 4 - 23 + 22 1 0 0 @@ -934,7 +922,7 @@ 4 - 24 + 23 1 0 0 @@ -946,7 +934,7 @@ 4 - 25 + 24 1 0 0 @@ -958,7 +946,7 @@ 4 - 26 + 25 1 0 0 @@ -970,7 +958,7 @@ 4 - 27 + 26 1 0 0 @@ -982,7 +970,7 @@ 4 - 28 + 27 1 0 0 @@ -994,7 +982,7 @@ 4 - 29 + 28 1 0 0 @@ -1006,7 +994,7 @@ 4 - 30 + 29 1 0 0 @@ -1018,7 +1006,7 @@ 4 - 31 + 30 1 0 0 @@ -1030,7 +1018,7 @@ 4 - 32 + 31 1 0 0 @@ -1042,7 +1030,7 @@ 4 - 33 + 32 1 0 0 @@ -1062,43 +1050,7 @@ 0 5 - 34 - 5 - 0 - 0 - 0 - ..\..\..\..\..\ports\arm-cm\qk\armclang\qep_port.h - qep_port.h - 0 - 0 - - - 5 - 35 - 5 - 0 - 0 - 0 - ..\..\..\..\..\ports\arm-cm\qk\armclang\qf_port.h - qf_port.h - 0 - 0 - - - 5 - 36 - 5 - 0 - 0 - 0 - ..\..\..\..\..\ports\arm-cm\qk\armclang\qs_port.h - qs_port.h - 0 - 0 - - - 5 - 37 + 33 1 0 0 @@ -1108,18 +1060,6 @@ 0 0 - - 5 - 38 - 5 - 0 - 0 - 0 - ..\..\..\..\..\ports\arm-cm\qk\armclang\qk_port.h - qk_port.h - 0 - 0 - @@ -1130,7 +1070,7 @@ 0 6 - 39 + 34 1 0 0 @@ -1142,7 +1082,7 @@ 6 - 40 + 35 1 0 0 @@ -1154,7 +1094,7 @@ 6 - 41 + 36 1 0 0 @@ -1166,7 +1106,7 @@ 6 - 42 + 37 1 0 0 @@ -1176,6 +1116,18 @@ 0 0 + + 6 + 38 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qs\qstamp.c + qstamp.c + 0 + 0 + diff --git a/examples/arm-cm/dpp_nucleo-h743zi/qk/armclang/dpp-qk.uvprojx b/examples/arm-cm/dpp_nucleo-h743zi/qk/armclang/dpp-qk.uvprojx index 2e185521..b89b997c 100644 --- a/examples/arm-cm/dpp_nucleo-h743zi/qk/armclang/dpp-qk.uvprojx +++ b/examples/arm-cm/dpp_nucleo-h743zi/qk/armclang/dpp-qk.uvprojx @@ -313,7 +313,7 @@ 0 - 2 + 1 0 0 1 @@ -337,7 +337,7 @@ 0 - STM32H743xx,USE_HAL_DRIVER,USE_STM32H7XX_NUCLEO_144 + QF_ON_CONTEXT_SW,STM32H743xx,USE_HAL_DRIVER,USE_STM32H7XX_NUCLEO_144 ..\..;..\..\..\..\..\include;..\..\..\..\..\ports\arm-cm\qk\armclang;..\..\..\..\..\3rd_party\CMSIS\Include;..\..\..\..\..\3rd_party\STM32CubeH7\Drivers\CMSIS\Device\ST/STM32H7xx\Include;..\..\..\..\..\3rd_party\STM32CubeH7\Drivers\BSP\STM32H7xx_Nucleo_144;..\..\..\..\..\3rd_party\STM32CubeH7\Drivers\STM32H7xx_HAL_Driver\Inc @@ -361,7 +361,7 @@ - 1 + 0 0 0 0 @@ -370,7 +370,7 @@ 0x00000000 0x20000000 - + .\dpp-qk.sct --entry Reset_Handler @@ -388,11 +388,6 @@ 1 ..\bsp.c - - main.c - 1 - ..\main.c - dpp.h 5 @@ -414,9 +409,9 @@ ..\..\table.c - qstamp.c - 8 - ..\..\..\..\..\include\qstamp.c + main.c + 1 + ..\..\main.c @@ -568,31 +563,11 @@ QP_port - - qep_port.h - 5 - ..\..\..\..\..\ports\arm-cm\qk\armclang\qep_port.h - - - qf_port.h - 5 - ..\..\..\..\..\ports\arm-cm\qk\armclang\qf_port.h - - - qs_port.h - 5 - ..\..\..\..\..\ports\arm-cm\qk\armclang\qs_port.h - qk_port.c 1 ..\..\..\..\..\ports\arm-cm\qk\armclang\qk_port.c - - qk_port.h - 5 - ..\..\..\..\..\ports\arm-cm\qk\armclang\qk_port.h - @@ -687,6 +662,11 @@ 1 ..\..\..\..\..\src\qs\qs_rx.c + + qstamp.c + 1 + ..\..\..\..\..\src\qs\qstamp.c + @@ -1022,7 +1002,7 @@ 0 - NDEBUG,STM32H743xx,USE_HAL_DRIVER,USE_STM32H7XX_NUCLEO_144 + NDEBUG,QF_ON_CONTEXT_SW,STM32H743xx,USE_HAL_DRIVER,USE_STM32H7XX_NUCLEO_144 ..\..;..\..\..\..\..\include;..\..\..\..\..\ports\arm-cm\qk\armclang;..\..\..\..\..\3rd_party\CMSIS\Include;..\..\..\..\..\3rd_party\STM32CubeH7\Drivers\CMSIS\Device\ST/STM32H7xx\Include;..\..\..\..\..\3rd_party\STM32CubeH7\Drivers\BSP\STM32H7xx_Nucleo_144;..\..\..\..\..\3rd_party\STM32CubeH7\Drivers\STM32H7xx_HAL_Driver\Inc @@ -1046,7 +1026,7 @@ - 1 + 0 0 0 0 @@ -1055,7 +1035,7 @@ 0x00000000 0x20000000 - + .\dpp-qk.sct --entry Reset_Handler @@ -1073,11 +1053,6 @@ 1 ..\bsp.c - - main.c - 1 - ..\main.c - dpp.h 5 @@ -1099,9 +1074,9 @@ ..\..\table.c - qstamp.c - 8 - ..\..\..\..\..\include\qstamp.c + main.c + 1 + ..\..\main.c @@ -1253,31 +1228,11 @@ QP_port - - qep_port.h - 5 - ..\..\..\..\..\ports\arm-cm\qk\armclang\qep_port.h - - - qf_port.h - 5 - ..\..\..\..\..\ports\arm-cm\qk\armclang\qf_port.h - - - qs_port.h - 5 - ..\..\..\..\..\ports\arm-cm\qk\armclang\qs_port.h - qk_port.c 1 ..\..\..\..\..\ports\arm-cm\qk\armclang\qk_port.c - - qk_port.h - 5 - ..\..\..\..\..\ports\arm-cm\qk\armclang\qk_port.h - @@ -1372,6 +1327,11 @@ 1 ..\..\..\..\..\src\qs\qs_rx.c + + qstamp.c + 1 + ..\..\..\..\..\src\qs\qstamp.c + @@ -1707,7 +1667,7 @@ 0 - Q_SPY,STM32H743xx,USE_HAL_DRIVER,USE_STM32H7XX_NUCLEO_144 + Q_SPY,QF_ON_CONTEXT_SW,STM32H743xx,USE_HAL_DRIVER,USE_STM32H7XX_NUCLEO_144 ..\..;..\..\..\..\..\include;..\..\..\..\..\ports\arm-cm\qk\armclang;..\..\..\..\..\3rd_party\CMSIS\Include;..\..\..\..\..\3rd_party\STM32CubeH7\Drivers\CMSIS\Device\ST/STM32H7xx\Include;..\..\..\..\..\3rd_party\STM32CubeH7\Drivers\BSP\STM32H7xx_Nucleo_144;..\..\..\..\..\3rd_party\STM32CubeH7\Drivers\STM32H7xx_HAL_Driver\Inc @@ -1731,7 +1691,7 @@ - 1 + 0 0 0 0 @@ -1740,7 +1700,7 @@ 0x00000000 0x20000000 - + .\dpp-qk.sct --entry Reset_Handler @@ -1758,11 +1718,6 @@ 1 ..\bsp.c - - main.c - 1 - ..\main.c - dpp.h 5 @@ -1784,9 +1739,9 @@ ..\..\table.c - qstamp.c - 8 - ..\..\..\..\..\include\qstamp.c + main.c + 1 + ..\..\main.c @@ -1938,31 +1893,11 @@ QP_port - - qep_port.h - 5 - ..\..\..\..\..\ports\arm-cm\qk\armclang\qep_port.h - - - qf_port.h - 5 - ..\..\..\..\..\ports\arm-cm\qk\armclang\qf_port.h - - - qs_port.h - 5 - ..\..\..\..\..\ports\arm-cm\qk\armclang\qs_port.h - qk_port.c 1 ..\..\..\..\..\ports\arm-cm\qk\armclang\qk_port.c - - qk_port.h - 5 - ..\..\..\..\..\ports\arm-cm\qk\armclang\qk_port.h - @@ -2057,6 +1992,11 @@ 1 ..\..\..\..\..\src\qs\qs_rx.c + + qstamp.c + 1 + ..\..\..\..\..\src\qs\qstamp.c + diff --git a/examples/arm-cm/dpp_nucleo-h743zi/qk/bsp.c b/examples/arm-cm/dpp_nucleo-h743zi/qk/bsp.c index a0f88601..a83e9e27 100644 --- a/examples/arm-cm/dpp_nucleo-h743zi/qk/bsp.c +++ b/examples/arm-cm/dpp_nucleo-h743zi/qk/bsp.c @@ -1,249 +1,316 @@ -/*============================================================================ -* QP/C Real-Time Embedded Framework (RTEF) -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2022-12-18 -* @version Last updated for: @ref qpc_7_2_0 -* -* @file -* @brief DPP example, NUCLEO-H743ZIE board, preemptive QK kernel -*/ -#include "qpc.h" -#include "dpp.h" -#include "bsp.h" +//============================================================================ +// Product: DPP example, NUCLEO-H743ZI board, QK kernel +// Last updated for version 7.3.0 +// Last updated on 2023-08-22 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. +// +// This program is open source software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Alternatively, this program may be distributed and modified under the +// terms of Quantum Leaps commercial licenses, which expressly supersede +// the GNU General Public License and are specifically designed for +// licensees interested in retaining the proprietary status of their code. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Contact information: +// +// +//============================================================================ +#include "qpc.h" // QP/C real-time embedded framework +#include "dpp.h" // DPP Application interface +#include "bsp.h" // Board Support Package -/* STM32CubeH7 include files */ +// STM32CubeH7 include files #include "stm32h7xx_hal.h" #include "stm32h7xx_nucleo_144.h" -/* add other drivers if necessary... */ +// add other drivers if necessary... Q_DEFINE_THIS_FILE -/* ISRs defined in this BSP ------------------------------------------------*/ +// ISRs defined in this BSP ------------------------------------------------ void SysTick_Handler(void); void USART3_IRQHandler(void); -/* Local-scope objects -----------------------------------------------------*/ -static uint32_t l_rnd; /* random seed */ +// Local-scope objects ----------------------------------------------------- +static uint32_t l_rndSeed; #ifdef Q_SPY QSTimeCtr QS_tickTime_; QSTimeCtr QS_tickPeriod_; - /* QSpy source IDs */ + // QSpy source IDs static QSpyId const l_SysTick_Handler = { 0U }; static UART_HandleTypeDef l_uartHandle; - enum AppRecords { /* application-specific trace records */ + enum AppRecords { // application-specific trace records PHILO_STAT = QS_USER, PAUSED_STAT, - COMMAND_STAT, CONTEXT_SW, }; #endif -/* ISRs used in this project ===============================================*/ -void SysTick_Handler(void) { - /* state of the button debouncing, see below */ - static struct ButtonsDebouncing { - uint32_t depressed; - uint32_t previous; - } buttons = { 0U, 0U }; - uint32_t current; - uint32_t tmp; +//============================================================================ +// Error handler and ISRs... - QK_ISR_ENTRY(); /* inform QK about entering an ISR */ +Q_NORETURN Q_onError(char const * const module, int_t const id) { + // NOTE: this implementation of the assertion handler is intended only + // for debugging and MUST be changed for deployment of the application + // (assuming that you ship your production code with assertions enabled). + Q_UNUSED_PAR(module); + Q_UNUSED_PAR(id); + QS_ASSERTION(module, id, 10000U); -#ifdef Q_SPY - { - tmp = SysTick->CTRL; /* clear SysTick_CTRL_COUNTFLAG */ - QS_tickTime_ += QS_tickPeriod_; /* account for the clock rollover */ +#ifndef NDEBUG + // light all LEDs + BSP_LED_On(LED1); + BSP_LED_On(LED2); + BSP_LED_On(LED3); + // for debugging, hang on in an endless loop... + for (;;) { } #endif - //QTIMEEVT_TICK_X(0U, &l_SysTick_Handler); /* process time events for rate 0 */ - QACTIVE_POST(&ticker0.super, 0, &l_SysTick_Handler); /* post to ticker0 */ + NVIC_SystemReset(); +} +//............................................................................ +void assert_failed(char const * const module, int_t const id); // prototype +void assert_failed(char const * const module, int_t const id) { + Q_onError(module, id); +} - /* Perform the debouncing of buttons. The algorithm for debouncing - * adapted from the book "Embedded Systems Dictionary" by Jack Ganssle - * and Michael Barr, page 71. - */ - current = BSP_PB_GetState(BUTTON_USER); /* read the User button */ - tmp = buttons.depressed; /* save the debounced depressed buttons */ - buttons.depressed |= (buttons.previous & current); /* set depressed */ - buttons.depressed &= (buttons.previous | current); /* clear released */ - buttons.previous = current; /* update the history */ - tmp ^= buttons.depressed; /* changed debounced depressed */ - if (tmp != 0U) { /* debounced Key button state changed? */ - if (buttons.depressed != 0U) { /* PB0 depressed?*/ - static QEvt const pauseEvt = { PAUSE_SIG, 0U, 0U}; + +// ISRs used in the application ============================================ + +void SysTick_Handler(void); // prototype +void SysTick_Handler(void) { + QK_ISR_ENTRY(); // inform QK about entering an ISR + + uint32_t tmp; +#ifdef Q_SPY + { + tmp = SysTick->CTRL; // clear SysTick_CTRL_COUNTFLAG + QS_tickTime_ += QS_tickPeriod_; // account for the clock rollover + } +#endif + + QTIMEEVT_TICK_X(0U, &l_SysTick_Handler); // time events for rate 0 + + // Perform the debouncing of buttons. The algorithm for debouncing + // adapted from the book "Embedded Systems Dictionary" by Jack Ganssle + // and Michael Barr, page 71. + // + // state of the button debouncing + static struct { + uint32_t depressed; + uint32_t previous; + } buttons = { 0U, 0U }; + + uint32_t current = BSP_PB_GetState(BUTTON_USER); // read the User button + tmp = buttons.depressed; // save the depressed buttons + buttons.depressed |= (buttons.previous & current); // set depressed + buttons.depressed &= (buttons.previous | current); // clear released + buttons.previous = current; // update the history + tmp ^= buttons.depressed; // changed debounced depressed + current = buttons.depressed; + + if (tmp != 0U) { // debounced Key button state changed? + if (current != 0U) { // PB0 depressed? + static QEvt const pauseEvt = QEVT_INITIALIZER(PAUSE_SIG); QACTIVE_PUBLISH(&pauseEvt, &l_SysTick_Handler); } - else { /* the button is released */ - static QEvt const serveEvt = { SERVE_SIG, 0U, 0U}; + else { // the button is released + static QEvt const serveEvt = QEVT_INITIALIZER(SERVE_SIG); QACTIVE_PUBLISH(&serveEvt, &l_SysTick_Handler); } } - QK_ISR_EXIT(); /* inform QK about exiting an ISR */ + QK_ISR_EXIT(); // inform QK about exiting an ISR } -/*..........................................................................*/ +//............................................................................ #ifdef Q_SPY -/* -* ISR for receiving bytes from the QSPY Back-End -* NOTE: This ISR is "QF-unaware" meaning that it does not interact with -* the QF/QK and is not disabled. Such ISRs don't need to call QK_ISR_ENTRY/ -* QK_ISR_EXIT and they cannot post or publish events. -*/ +// ISR for receiving bytes from the QSPY Back-End +// NOTE: This ISR is "QF-unaware" meaning that it does not interact with +// the QF/QK and is not disabled. Such ISRs don't need to call QK_ISR_ENTRY/ +// QK_ISR_EXIT and they cannot post or publish events. + +void USART3_IRQHandler(void); // prototype void USART3_IRQHandler(void) { - /* is RX register NOT empty? */ + // is RX register NOT empty? if ((l_uartHandle.Instance->ISR & USART_ISR_RXNE_RXFNE) != 0) { uint32_t b = l_uartHandle.Instance->RDR; QS_RX_PUT(b); - l_uartHandle.Instance->ISR &= ~USART_ISR_RXNE_RXFNE; /* clear int. */ + l_uartHandle.Instance->ISR &= ~USART_ISR_RXNE_RXFNE; // clear int. } -} -#endif -/* BSP functions ===========================================================*/ -/*..........................................................................*/ -/* MPU setup for STM32H743ZI MCU */ + QK_ARM_ERRATUM_838869(); +} +#endif // Q_SPY + +//............................................................................ +#ifdef QF_ON_CONTEXT_SW +// NOTE: the context-switch callback is called with interrupts DISABLED +void QF_onContextSw(QActive *prev, QActive *next) { + QS_BEGIN_INCRIT(CONTEXT_SW, 0U) // in critical section! + QS_OBJ(prev); + QS_OBJ(next); + QS_END_INCRIT() +} +#endif // QF_ON_CONTEXT_SW + +//............................................................................ +// MPU setup for STM32H743ZI MCU static void STM32H743ZI_MPU_setup(void) { - /* The following MPU configuration contains just a generic ROM - * region (with read-only access) and NULL-pointer protection region. - * Otherwise, the MPU will fall back on the background region (PRIVDEFENA). - */ + // The following MPU configuration contains just a generic ROM + // region (with read-only access) and NULL-pointer protection region. + // Otherwise, the MPU will fall back on the background region (PRIVDEFENA). + // static struct { uint32_t rbar; uint32_t rasr; } const mpu_setup[] = { - { /* region #0: Flash: base=0x0000'0000, size=512M=2^(28+1) */ - 0x00000000U /* base address */ - | MPU_RBAR_VALID_Msk /* valid region */ - | (MPU_RBAR_REGION_Msk & 0U), /* region #0 */ - (28U << MPU_RASR_SIZE_Pos) /* 2^(18+1) region */ - | (0x6U << MPU_RASR_AP_Pos) /* PA:ro/UA:ro */ - | (1U << MPU_RASR_C_Pos) /* C=1 */ - | MPU_RASR_ENABLE_Msk /* region enable */ + { // region #0: Flash: base=0x0000'0000, size=512M=2^(28+1) + 0x00000000U // base address + | MPU_RBAR_VALID_Msk // valid region + | (MPU_RBAR_REGION_Msk & 0U), // region #0 + (28U << MPU_RASR_SIZE_Pos) // 2^(18+1) region + | (0x6U << MPU_RASR_AP_Pos) // PA:ro/UA:ro + | (1U << MPU_RASR_C_Pos) // C=1 + | MPU_RASR_ENABLE_Msk // region enable }, - { /* region #7: NULL-pointer: base=0x000'0000, size=128M=2^(26+1) */ - /* NOTE: this region extends to 0x080'0000, which is where - * the ROM is re-mapped by STM32 - */ - 0x00000000U /* base address */ - | MPU_RBAR_VALID_Msk /* valid region */ - | (MPU_RBAR_REGION_Msk & 7U), /* region #7 */ - (26U << MPU_RASR_SIZE_Pos) /* 2^(26+1)=128M region */ - | (0x0U << MPU_RASR_AP_Pos) /* PA:na/UA:na */ - | (1U << MPU_RASR_XN_Pos) /* XN=1 */ - | MPU_RASR_ENABLE_Msk /* region enable */ + { // region #7: NULL-pointer: base=0x000'0000, size=128M=2^(26+1) + // NOTE: this region extends to 0x080'0000, which is where + // the ROM is re-mapped by STM32 + // + 0x00000000U // base address + | MPU_RBAR_VALID_Msk // valid region + | (MPU_RBAR_REGION_Msk & 7U), // region #7 + (26U << MPU_RASR_SIZE_Pos) // 2^(26+1)=128M region + | (0x0U << MPU_RASR_AP_Pos) // PA:na/UA:na + | (1U << MPU_RASR_XN_Pos) // XN=1 + | MPU_RASR_ENABLE_Msk // region enable }, }; - /* enable the MemManage_Handler for MPU exception */ + // enable the MemManage_Handler for MPU exception SCB->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk; __DSB(); - MPU->CTRL = 0U; /* disable the MPU */ + MPU->CTRL = 0U; // disable the MPU for (uint_fast8_t n = 0U; n < Q_DIM(mpu_setup); ++n) { MPU->RBAR = mpu_setup[n].rbar; MPU->RASR = mpu_setup[n].rasr; } - MPU->CTRL = MPU_CTRL_ENABLE_Msk /* enable the MPU */ - | MPU_CTRL_PRIVDEFENA_Msk; /* enable background region */ + MPU->CTRL = MPU_CTRL_ENABLE_Msk // enable the MPU + | MPU_CTRL_PRIVDEFENA_Msk; // enable background region __ISB(); __DSB(); } -/*..........................................................................*/ +//============================================================================ +// BSP functions... + void BSP_init(void) { - /* setup the MPU... */ + // setup the MPU... STM32H743ZI_MPU_setup(); - /* NOTE: SystemInit() has been already called from the startup code - * but SystemCoreClock needs to be updated - */ + // NOTE: SystemInit() has been already called from the startup code + // but SystemCoreClock needs to be updated SystemCoreClockUpdate(); - SCB_EnableICache(); /* Enable I-Cache */ - SCB_EnableDCache(); /* Enable D-Cache */ + SCB_EnableICache(); // Enable I-Cache + SCB_EnableDCache(); // Enable D-Cache - /* Configure Flash prefetch and Instr. cache through ART accelerator */ + // Configure Flash prefetch and Instr. cache through ART accelerator #if (ART_ACCLERATOR_ENABLE != 0) __HAL_FLASH_ART_ENABLE(); -#endif /* ART_ACCLERATOR_ENABLE */ +#endif // ART_ACCLERATOR_ENABLE - /* Configure the LEDs */ + // Configure the LEDs BSP_LED_Init(LED1); BSP_LED_Init(LED2); BSP_LED_Init(LED3); - /* Configure the User Button in GPIO Mode */ + // Configure the User Button in GPIO Mode BSP_PB_Init(BUTTON_USER, BUTTON_MODE_GPIO); //... BSP_randomSeed(1234U); - /* initialize the QS software tracing... */ - if (QS_INIT((void *)0) == 0) { + // initialize the QS software tracing... + if (!QS_INIT((void *)0)) { Q_ERROR(); } - /* object dictionaries... */ - QS_OBJ_DICTIONARY(AO_Table); - QS_OBJ_DICTIONARY(AO_Philo[0]); - QS_OBJ_DICTIONARY(AO_Philo[1]); - QS_OBJ_DICTIONARY(AO_Philo[2]); - QS_OBJ_DICTIONARY(AO_Philo[3]); - QS_OBJ_DICTIONARY(AO_Philo[4]); - QS_OBJ_DICTIONARY(&ticker0); - + // dictionaries... QS_OBJ_DICTIONARY(&l_SysTick_Handler); QS_USR_DICTIONARY(PHILO_STAT); QS_USR_DICTIONARY(PAUSED_STAT); - QS_USR_DICTIONARY(COMMAND_STAT); QS_USR_DICTIONARY(CONTEXT_SW); - /* setup the QS filters... */ - QS_GLB_FILTER(QS_ALL_RECORDS); /* all records */ - QS_GLB_FILTER(-QS_QF_TICK); /* exclude the clock tick */ + QS_ONLY(produce_sig_dict()); + + // setup the QS filters... + QS_GLB_FILTER(QS_ALL_RECORDS); // all records + QS_GLB_FILTER(-QS_QF_TICK); // exclude the clock tick } -/*..........................................................................*/ -void BSP_ledOn(void) { - BSP_LED_On(LED1); +//............................................................................ +void BSP_start(void) { + // initialize event pools + static QF_MPOOL_EL(TableEvt) smlPoolSto[2*N_PHILO]; + QF_poolInit(smlPoolSto, sizeof(smlPoolSto), sizeof(smlPoolSto[0])); + + // initialize publish-subscribe + static QSubscrList subscrSto[MAX_PUB_SIG]; + QActive_psInit(subscrSto, Q_DIM(subscrSto)); + + // instantiate and start AOs/threads... + + static QEvt const *philoQueueSto[N_PHILO][10]; + for (uint8_t n = 0U; n < N_PHILO; ++n) { + Philo_ctor(n); + QACTIVE_START(AO_Philo[n], + + // NOTE: set the preemption-threshold of all Philos to + // the same level, so that they cannot preempt each other. + Q_PRIO(n + 3U, N_PHILO + 2U), // QF-prio/pre-thre. + + philoQueueSto[n], // event queue storage + Q_DIM(philoQueueSto[n]), // queue length [events] + (void *)0, 0U, // no stack storage + (void *)0); // no initialization param + } + + static QEvt const *tableQueueSto[N_PHILO]; + Table_ctor(); + QACTIVE_START(AO_Table, + N_PHILO + 7U, // QP prio. of the AO + tableQueueSto, // event queue storage + Q_DIM(tableQueueSto), // queue length [events] + (void *)0, 0U, // no stack storage + (void *)0); // no initialization param } -/*..........................................................................*/ -void BSP_ledOff(void) { - BSP_LED_Off(LED1); -} -/*..........................................................................*/ +//............................................................................ void BSP_displayPhilStat(uint8_t n, char const *stat) { if (stat[0] == 'e') { BSP_LED_On(LED1); @@ -252,154 +319,143 @@ void BSP_displayPhilStat(uint8_t n, char const *stat) { BSP_LED_Off(LED1); } - QS_BEGIN_ID(PHILO_STAT, AO_Philo[n]->prio) /* app-specific record */ - QS_U8(1, n); /* Philosopher number */ - QS_STR(stat); /* Philosopher status */ - QS_END() /* application-specific record end */ + // app-specific trace record... + QS_BEGIN_ID(PHILO_STAT, AO_Table->prio) + QS_U8(1, n); // Philosopher number + QS_STR(stat); // Philosopher status + QS_END() } -/*..........................................................................*/ -void BSP_displayPaused(uint8_t paused) { +//............................................................................ +void BSP_displayPaused(uint8_t const paused) { if (paused != 0U) { BSP_LED_On(LED2); } else { BSP_LED_Off(LED2); } + + // application-specific trace record + QS_BEGIN_ID(PAUSED_STAT, AO_Table->prio) + QS_U8(1, paused); // Paused status + QS_END() } -/*..........................................................................*/ -uint32_t BSP_random(void) { /* a very cheap pseudo-random-number generator */ - uint32_t rnd; - - /* Some flating point code is to exercise the VFP... */ - float volatile x = 3.1415926F; - x = x + 2.7182818F; - - QSchedStatus lockStat = QK_schedLock(N_PHILO); /* N_PHILO prio. ceiling */ - /* "Super-Duper" Linear Congruential Generator (LCG) - * LCG(2^32, 3*7*11*13*23, 0, seed) - */ - rnd = l_rnd * (3U*7U*11U*13U*23U); - l_rnd = rnd; /* set for the next time */ - QK_schedUnlock(lockStat); /* unlock the scheduler */ - - return (rnd >> 8); -} -/*..........................................................................*/ +//............................................................................ void BSP_randomSeed(uint32_t seed) { - l_rnd = seed; + l_rndSeed = seed; } -/*..........................................................................*/ +//............................................................................ +uint32_t BSP_random(void) { // a very cheap pseudo-random-number generator + // Some flating point code is to exercise the VFP... + double volatile x = 3.1415926; + x = x + 2.7182818; + + QSchedStatus lockStat = QK_schedLock(N_PHILO); // N_PHILO prio. ceiling + // "Super-Duper" Linear Congruential Generator (LCG) + // LCG(2^32, 3*7*11*13*23, 0, seed) + // + uint32_t rnd = l_rndSeed * (3U*7U*11U*13U*23U); + l_rndSeed = rnd; // set for the next time + QK_schedUnlock(lockStat); + + return (rnd >> 8U); +} +//............................................................................ void BSP_terminate(int16_t result) { (void)result; } +//............................................................................ +void BSP_ledOn(void) { + BSP_LED_On(LED1); +} +//............................................................................ +void BSP_ledOff(void) { + BSP_LED_Off(LED1); +} -/*..........................................................................*/ +//============================================================================ +// QF callbacks... void QF_onStartup(void) { - /* assign all priority bits for preemption-prio. and none to sub-prio. - * NOTE: this might have been changed by STM32Cube. - */ + // assign all priority bits for preemption-prio. and none to sub-prio. + // NOTE: this might have been changed by STM32Cube. + // NVIC_SetPriorityGrouping(0U); - /* set up the SysTick timer to fire at BSP_TICKS_PER_SEC rate */ + // set up the SysTick timer to fire at BSP_TICKS_PER_SEC rate SysTick_Config(SystemCoreClock / BSP_TICKS_PER_SEC); - /* set priorities of ALL ISRs used in the system, see NOTE1 */ - NVIC_SetPriority(USART3_IRQn, 0U); /* kernel unaware interrupt */ + // set priorities of ALL ISRs used in the system, see NOTE1 + NVIC_SetPriority(USART3_IRQn, 0U); // kernel unaware interrupt NVIC_SetPriority(SysTick_IRQn, QF_AWARE_ISR_CMSIS_PRI); - /* ... */ + // ... - /* enable IRQs... */ + // enable IRQs... #ifdef Q_SPY - NVIC_EnableIRQ(USART3_IRQn); /* UART interrupt used for QS-RX */ + NVIC_EnableIRQ(USART3_IRQn); // UART interrupt used for QS-RX #endif } -/*..........................................................................*/ +//............................................................................ void QF_onCleanup(void) { } -/*..........................................................................*/ -#ifdef QF_ON_CONTEXT_SW -/* NOTE: the context-switch callback is called with interrupts DISABLED */ -void QF_onContextSw(QActive *prev, QActive *next) { - if ((prev != &ticker0.super) && (next != &ticker0.super)) { - QS_BEGIN_NOCRIT(CONTEXT_SW, 0U) /* no critical section! */ - QS_OBJ(prev); - QS_OBJ(next); - QS_END_NOCRIT() - } -} -#endif /* QF_ON_CONTEXT_SW */ - -/*..........................................................................*/ +//............................................................................ void QK_onIdle(void) { - /* toggle the User LED on and then off, see NOTE2 */ + // toggle the User LED on and then off, see NOTE2 QF_INT_DISABLE(); BSP_LED_On (LED3); BSP_LED_Off(LED3); QF_INT_ENABLE(); + // Some floating point code is to exercise the VFP... + double volatile x = 1.73205; + x = x * 1.73205; + #ifdef Q_SPY - QS_rxParse(); /* parse all the received bytes */ - - if ((l_uartHandle.Instance->ISR & UART_FLAG_TXE) != 0U) { /* TXE empty? */ - uint16_t b; + QF_INT_DISABLE(); + QS_rxParse(); // parse all the received bytes + QF_INT_ENABLE(); + QF_CRIT_EXIT_NOP(); + QF_INT_DISABLE(); + if ((l_uartHandle.Instance->ISR & UART_FLAG_TXE) != 0U) { // TXE empty? QF_INT_DISABLE(); - b = QS_getByte(); + uint16_t b = QS_getByte(); QF_INT_ENABLE(); - if (b != QS_EOD) { /* not End-Of-Data? */ - l_uartHandle.Instance->TDR = (b & 0xFFU); /* put into TDR */ + if (b != QS_EOD) { // not End-Of-Data? + l_uartHandle.Instance->TDR = b; // put into TDR } } + QF_INT_ENABLE(); #elif defined NDEBUG - /* Put the CPU and peripherals to the low-power mode. - * you might need to customize the clock management for your application, - * see the datasheet for your particular Cortex-M MCU. - */ - /* !!!CAUTION!!! - * The WFI instruction stops the CPU clock, which unfortunately disables - * the JTAG port, so the ST-Link debugger can no longer connect to the - * board. For that reason, the call to __WFI() has to be used with CAUTION. - * - * NOTE: If you find your board "frozen" like this, strap BOOT0 to VDD and - * reset the board, then connect with ST-Link Utilities and erase the part. - * The trick with BOOT(0) is it gets the part to run the System Loader - * instead of your broken code. When done disconnect BOOT0, and start over. - */ - //__WFI(); /* Wait-For-Interrupt */ + // Put the CPU and peripherals to the low-power mode. + // you might need to customize the clock management for your application, + // see the datasheet for your particular Cortex-M MCU. + // + // !!!CAUTION!!! + // The WFI instruction stops the CPU clock, which unfortunately disables + // the JTAG port, so the ST-Link debugger can no longer connect to the + // board. For that reason, the call to __WFI() has to be used with CAUTION. + // + // NOTE: If you find your board "frozen" like this, strap BOOT0 to VDD and + // reset the board, then connect with ST-Link Utilities and erase the part. + // The trick with BOOT(0) is it gets the part to run the System Loader + // instead of your broken code. When done disconnect BOOT0, and start over. + // + //__WFI(); // Wait-For-Interrupt #endif } -/*..........................................................................*/ -Q_NORETURN Q_onAssert(char const * const module, int_t const loc) { - /* - * NOTE: add here your application-specific error handling - */ - (void)module; - (void)loc; - QS_ASSERTION(module, loc, 10000U); /* report assertion to QS */ - -#ifndef NDEBUG - /* light all LEDs */ - BSP_LED_On(LED1); - BSP_LED_On(LED2); - BSP_LED_On(LED3); - /* for debugging, hang on in an endless loop... */ - for (;;) { - } -#endif - - NVIC_SystemReset(); -} - -/* QS callbacks ============================================================*/ +//============================================================================ +// QS callbacks... #ifdef Q_SPY -/*..........................................................................*/ -uint8_t QS_onStartup(void const *arg) { - static uint8_t qsTxBuf[2*1024]; /* buffer for QS-TX channel */ - static uint8_t qsRxBuf[256]; /* buffer for QS-RX channel */ - QS_initBuf (qsTxBuf, sizeof(qsTxBuf)); +//............................................................................ +uint8_t QS_onStartup(void const *arg) { + Q_UNUSED_PAR(arg); + + static uint8_t qsTxBuf[2*1024]; // buffer for QS-TX channel + QS_initBuf(qsTxBuf, sizeof(qsTxBuf)); + + static uint8_t qsRxBuf[100]; // buffer for QS-RX channel QS_rxInitBuf(qsRxBuf, sizeof(qsRxBuf)); l_uartHandle.Instance = USART3; @@ -411,51 +467,57 @@ uint8_t QS_onStartup(void const *arg) { l_uartHandle.Init.Mode = UART_MODE_TX_RX; l_uartHandle.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT; if (HAL_UART_Init(&l_uartHandle) != HAL_OK) { - return 0U; /* return failure */ + return 0U; // return failure } - /* Set UART to receive 1 byte at a time via interrupt */ + // Set UART to receive 1 byte at a time via interrupt HAL_UART_Receive_IT(&l_uartHandle, (uint8_t *)qsRxBuf, 1); QS_tickPeriod_ = SystemCoreClock / BSP_TICKS_PER_SEC; - QS_tickTime_ = QS_tickPeriod_; /* to start the timestamp at zero */ + QS_tickTime_ = QS_tickPeriod_; // to start the timestamp at zero - return 1U; /* return success */ + return 1U; // return success } -/*..........................................................................*/ +//............................................................................ void QS_onCleanup(void) { } -/*..........................................................................*/ -QSTimeCtr QS_onGetTime(void) { /* NOTE: invoked with interrupts DISABLED */ - if ((SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk) == 0) { /* not set? */ +//............................................................................ +QSTimeCtr QS_onGetTime(void) { // NOTE: invoked with interrupts DISABLED + if ((SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk) == 0) { // not set? return QS_tickTime_ - (QSTimeCtr)SysTick->VAL; } - else { /* the rollover occured, but the SysTick_ISR did not run yet */ + else { // the rollover occured, but the SysTick_ISR did not run yet return QS_tickTime_ + QS_tickPeriod_ - (QSTimeCtr)SysTick->VAL; } } -/*..........................................................................*/ +//............................................................................ void QS_onFlush(void) { - uint16_t b; - - QF_INT_DISABLE(); - while ((b = QS_getByte()) != QS_EOD) { /* while not End-Of-Data... */ - QF_INT_ENABLE(); - /* while TXE not empty */ - while ((l_uartHandle.Instance->ISR & UART_FLAG_TXE) == 0U) { - } - l_uartHandle.Instance->TDR = (b & 0xFFU); /* put into TDR */ + for (;;) { QF_INT_DISABLE(); + uint16_t b = QS_getByte(); + if (b != QS_EOD) { + while ((l_uartHandle.Instance->ISR & UART_FLAG_TXE) == 0U) { + QF_INT_ENABLE(); + QF_CRIT_EXIT_NOP(); + + QF_INT_DISABLE(); + } + l_uartHandle.Instance->TDR = b; + QF_INT_ENABLE(); + } + else { + QF_INT_ENABLE(); + break; + } } - QF_INT_ENABLE(); } -/*..........................................................................*/ -/*! callback function to reset the target (to be implemented in the BSP) */ +//............................................................................ +//! callback function to reset the target (to be implemented in the BSP) void QS_onReset(void) { NVIC_SystemReset(); } -/*..........................................................................*/ -/*! callback function to execute a user command (to be implemented in BSP) */ +//............................................................................ +//! callback function to execute a user command void QS_onCommand(uint8_t cmdId, uint32_t param1, uint32_t param2, uint32_t param3) { @@ -463,38 +525,33 @@ void QS_onCommand(uint8_t cmdId, Q_UNUSED_PAR(param1); Q_UNUSED_PAR(param2); Q_UNUSED_PAR(param3); - - QS_BEGIN_ID(COMMAND_STAT, 0U) /* app-specific record */ - QS_U8(2, cmdId); - QS_U32(8, param1); - QS_END() } -#endif /* Q_SPY */ -/*--------------------------------------------------------------------------*/ +#endif // Q_SPY +//---------------------------------------------------------------------------- -/***************************************************************************** -* NOTE1: -* The QF_AWARE_ISR_CMSIS_PRI constant from the QF port specifies the highest -* ISR priority that is disabled by the QF framework. The value is suitable -* for the NVIC_SetPriority() CMSIS function. -* -* Only ISRs prioritized at or below the QF_AWARE_ISR_CMSIS_PRI level (i.e., -* with the numerical values of priorities equal or higher than -* QF_AWARE_ISR_CMSIS_PRI) are allowed to call the QK_ISR_ENTRY/QK_ISR_ENTRY -* macros or any other QF services. These ISRs are "QF-aware". -* -* Conversely, any ISRs prioritized above the QF_AWARE_ISR_CMSIS_PRI priority -* level (i.e., with the numerical values of priorities less than -* QF_AWARE_ISR_CMSIS_PRI) are never disabled and are not aware of the kernel. -* Such "QF-unaware" ISRs cannot call any QF services. In particular they -* can NOT call the macros QK_ISR_ENTRY/QK_ISR_ENTRY. The only mechanism -* by which a "QF-unaware" ISR can communicate with the QF framework is by -* triggering a "QF-aware" ISR, which can post/publish events. -* -* NOTE2: -* The User LED is used to visualize the idle loop activity. The brightness -* of the LED is proportional to the frequency of invcations of the idle loop. -* Please note that the LED is toggled with interrupts locked, so no interrupt -* execution time contributes to the brightness of the User LED. -*/ +//============================================================================ +// NOTE0: +// The QF_AWARE_ISR_CMSIS_PRI constant from the QF port specifies the highest +// ISR priority that is disabled by the QF framework. The value is suitable +// for the NVIC_SetPriority() CMSIS function. +// +// Only ISRs prioritized at or below the QF_AWARE_ISR_CMSIS_PRI level (i.e., +// with the numerical values of priorities equal or higher than +// QF_AWARE_ISR_CMSIS_PRI) are allowed to call the QK_ISR_ENTRY/QK_ISR_ENTRY +// macros or any other QF services. These ISRs are "QF-aware". +// +// Conversely, any ISRs prioritized above the QF_AWARE_ISR_CMSIS_PRI priority +// level (i.e., with the numerical values of priorities less than +// QF_AWARE_ISR_CMSIS_PRI) are never disabled and are not aware of the kernel. +// Such "QF-unaware" ISRs cannot call any QF services. In particular they +// can NOT call the macros QK_ISR_ENTRY/QK_ISR_ENTRY. The only mechanism +// by which a "QF-unaware" ISR can communicate with the QF framework is by +// triggering a "QF-aware" ISR, which can post/publish events. +// +// NOTE2: +// The User LED is used to visualize the idle loop activity. The brightness +// of the LED is proportional to the frequency of invcations of the idle loop. +// Please note that the LED is toggled with interrupts locked, so no interrupt +// execution time contributes to the brightness of the User LED. +// diff --git a/examples/arm-cm/dpp_nucleo-h743zi/qk/gnu/Makefile b/examples/arm-cm/dpp_nucleo-h743zi/qk/gnu/Makefile index da832168..8cdabe24 100644 --- a/examples/arm-cm/dpp_nucleo-h743zi/qk/gnu/Makefile +++ b/examples/arm-cm/dpp_nucleo-h743zi/qk/gnu/Makefile @@ -1,7 +1,7 @@ ############################################################################## # Product: Makefile for QP/C on NUCLEO-H743ZI, QK kernel, GNU-ARM -# Last Updated for Version: 7.2.0 -# Date of the Last Update: 2022-12-13 +# Last Updated for Version: 7.3.0 +# Date of the Last Update: 2023-05-26 # # Q u a n t u m L e a P s # ------------------------ @@ -45,8 +45,7 @@ # NOTE: # To use this Makefile on Windows, you will need the GNU make utility, which # is included in the Qtools collection for Windows, see: -# https://sourceforge.net/projects/qpc/files/QTools/ -# +# https://github.com/QuantumLeaps/qtools #----------------------------------------------------------------------------- # project name @@ -147,6 +146,7 @@ LIBS := # defines DEFINES := \ + -DQF_ON_CONTEXT_SW \ -DSTM32H743xx -DUSE_HAL_DRIVER -DUSE_STM32H7XX_NUCLEO_144 \ -DQF_ON_CONTEXT_SW @@ -178,12 +178,11 @@ AS := $(GNU_ARM)/bin/arm-none-eabi-as LINK := $(GNU_ARM)/bin/arm-none-eabi-gcc BIN := $(GNU_ARM)/bin/arm-none-eabi-objcopy - ############################################################################## -# Typically, you should not need to change anything below this line +# Typically you should not need to change anything below this line -# basic utilities (included in Qtools for Windows), see: -# http://sourceforge.net/projects/qpc/files/Qtools +# basic utilities (included in QTools for Windows), see: +# https://www.state-machine.com/qtools MKDIR := mkdir RM := rm @@ -204,11 +203,11 @@ ASFLAGS = $(ARM_CPU) $(ARM_FPU) $(ASM_CPU) $(ASM_FPU) CFLAGS = -c $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \ -ffunction-sections -fdata-sections \ - -O1 $(INCLUDES) $(DEFINES) -DNDEBUG + -O2 $(INCLUDES) $(DEFINES) -DNDEBUG CPPFLAGS = -c $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \ -ffunction-sections -fdata-sections -fno-rtti -fno-exceptions \ - -O1 $(INCLUDES) $(DEFINES) -DNDEBUG + -O2 $(INCLUDES) $(DEFINES) -DNDEBUG else ifeq (spy, $(CONF)) # Spy configuration ................................ @@ -247,7 +246,6 @@ LINKFLAGS = -T$(LD_SCRIPT) $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb \ -specs=nosys.specs -specs=nano.specs \ -Wl,-Map,$(BIN_DIR)/$(OUTPUT).map,--cref,--gc-sections $(LIB_DIRS) - ASM_OBJS := $(patsubst %.s,%.o, $(notdir $(ASM_SRCS))) C_OBJS := $(patsubst %.c,%.o, $(notdir $(C_SRCS))) CPP_OBJS := $(patsubst %.cpp,%.o,$(notdir $(CPP_SRCS))) @@ -269,14 +267,20 @@ endif # rules # -all: $(TARGET_BIN) -#all: $(TARGET_ELF) +.PHONY : run norun flash + +ifeq ($(MAKECMDGOALS),norun) +all : $(TARGET_BIN) +norun : all +else +all : $(TARGET_BIN) run +endif $(TARGET_BIN): $(TARGET_ELF) $(BIN) -O binary $< $@ $(TARGET_ELF) : $(ASM_OBJS_EXT) $(C_OBJS_EXT) $(CPP_OBJS_EXT) - $(CC) $(CFLAGS) $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o + $(CC) $(CFLAGS) $(QPC)/src/qs/qstamp.c -o $(BIN_DIR)/qstamp.o $(LINK) $(LINKFLAGS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) $(BIN_DIR)/%.d : %.c @@ -294,6 +298,8 @@ $(BIN_DIR)/%.o : %.c $(BIN_DIR)/%.o : %.cpp $(CPP) $(CPPFLAGS) $< -o $@ +.PHONY : clean show + # include dependency files only if our goal depends on their existence ifneq ($(MAKECMDGOALS),clean) ifneq ($(MAKECMDGOALS),show) @@ -302,14 +308,13 @@ ifneq ($(MAKECMDGOALS),clean) endif -.PHONY : clean clean: -$(RM) $(BIN_DIR)/*.o \ $(BIN_DIR)/*.d \ $(BIN_DIR)/*.bin \ $(BIN_DIR)/*.elf \ $(BIN_DIR)/*.map - + show: @echo PROJECT = $(PROJECT) @echo CONF = $(CONF) diff --git a/examples/arm-cm/dpp_nucleo-h743zi/qk/iar/dpp-qk.ewd b/examples/arm-cm/dpp_nucleo-h743zi/qk/iar/dpp-qk.ewd index cafb89b6..f9dc3616 100644 --- a/examples/arm-cm/dpp_nucleo-h743zi/qk/iar/dpp-qk.ewd +++ b/examples/arm-cm/dpp_nucleo-h743zi/qk/iar/dpp-qk.ewd @@ -88,7 +88,7 @@
+ + + 0 + 1 + QF_readySet_ + + + 1 + 1 + QF_readySet_rmc_ + + 1 @@ -747,19 +727,7 @@ 0 0 0 - ..\..\..\..\..\include\qstamp.c - qstamp.c - 0 - 0 - - - 1 - 7 - 1 - 0 - 0 - 0 - ..\main.c + ..\..\main.c main.c 0 0 @@ -774,7 +742,7 @@ 0 2 - 8 + 7 5 0 0 @@ -786,7 +754,7 @@ 2 - 9 + 8 5 0 0 @@ -798,7 +766,7 @@ 2 - 10 + 9 1 0 0 @@ -810,7 +778,7 @@ 2 - 11 + 10 5 0 0 @@ -822,7 +790,7 @@ 2 - 12 + 11 2 0 0 @@ -842,7 +810,7 @@ 0 3 - 13 + 12 1 0 0 @@ -854,7 +822,7 @@ 3 - 14 + 13 1 0 0 @@ -866,7 +834,7 @@ 3 - 15 + 14 1 0 0 @@ -878,7 +846,7 @@ 3 - 16 + 15 1 0 0 @@ -890,7 +858,7 @@ 3 - 17 + 16 1 0 0 @@ -902,7 +870,7 @@ 3 - 18 + 17 1 0 0 @@ -914,7 +882,7 @@ 3 - 19 + 18 1 0 0 @@ -926,19 +894,7 @@ 3 - 20 - 5 - 0 - 0 - 0 - ..\..\..\..\..\src\qf_pkg.h - qf_pkg.h - 0 - 0 - - - 3 - 21 + 19 1 0 0 @@ -950,7 +906,7 @@ 3 - 22 + 20 1 0 0 @@ -962,7 +918,7 @@ 3 - 23 + 21 1 0 0 @@ -974,7 +930,7 @@ 3 - 24 + 22 1 0 0 @@ -986,7 +942,7 @@ 3 - 25 + 23 1 0 0 @@ -998,7 +954,7 @@ 3 - 26 + 24 1 0 0 @@ -1018,43 +974,7 @@ 0 4 - 27 - 5 - 0 - 0 - 0 - ..\..\..\..\..\ports\arm-cm\qk\armclang\qep_port.h - qep_port.h - 0 - 0 - - - 4 - 28 - 5 - 0 - 0 - 0 - ..\..\..\..\..\ports\arm-cm\qk\armclang\qf_port.h - qf_port.h - 0 - 0 - - - 4 - 29 - 5 - 0 - 0 - 0 - ..\..\..\..\..\ports\arm-cm\qk\armclang\qk_port.h - qk_port.h - 0 - 0 - - - 4 - 30 + 25 5 0 0 @@ -1066,7 +986,7 @@ 4 - 31 + 26 1 0 0 @@ -1086,7 +1006,7 @@ 0 5 - 32 + 27 1 0 0 @@ -1098,7 +1018,7 @@ 5 - 33 + 28 1 0 0 @@ -1110,7 +1030,7 @@ 5 - 34 + 29 1 0 0 @@ -1122,19 +1042,7 @@ 5 - 35 - 5 - 0 - 0 - 0 - ..\..\..\..\..\src\qs_pkg.h - qs_pkg.h - 0 - 0 - - - 5 - 36 + 30 1 0 0 @@ -1144,6 +1052,18 @@ 0 0 + + 5 + 31 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qs\qstamp.c + qstamp.c + 0 + 0 + diff --git a/examples/arm-cm/dpp_nucleo-l053r8/qk/armclang/dpp-qk.uvprojx b/examples/arm-cm/dpp_nucleo-l053r8/qk/armclang/dpp-qk.uvprojx index 18bd9d97..3adf9ac2 100644 --- a/examples/arm-cm/dpp_nucleo-l053r8/qk/armclang/dpp-qk.uvprojx +++ b/examples/arm-cm/dpp_nucleo-l053r8/qk/armclang/dpp-qk.uvprojx @@ -337,7 +337,7 @@ 0 - QK_USE_IRQ_HANDLER=LCD_IRQHandler QK_USE_IRQ_NUM=30 + QK_USE_IRQ_HANDLER=WWDG_IRQHandler QK_USE_IRQ_NUM=0 ..\..;..\..\..\..\..\include;..\..\..\..\..\ports\arm-cm\qk\armclang;..\..\..\..\..\3rd_party\CMSIS\Include;..\..\..\..\..\3rd_party\nucleo-l053r8 @@ -408,15 +408,10 @@ 1 ..\..\table.c - - qstamp.c - 1 - ..\..\..\..\..\include\qstamp.c - main.c 1 - ..\main.c + ..\..\main.c @@ -488,11 +483,6 @@ 1 ..\..\..\..\..\src\qf\qf_mem.c - - qf_pkg.h - 5 - ..\..\..\..\..\src\qf_pkg.h - qf_ps.c 1 @@ -528,21 +518,6 @@ QP_port - - qep_port.h - 5 - ..\..\..\..\..\ports\arm-cm\qk\armclang\qep_port.h - - - qf_port.h - 5 - ..\..\..\..\..\ports\arm-cm\qk\armclang\qf_port.h - - - qk_port.h - 5 - ..\..\..\..\..\ports\arm-cm\qk\armclang\qk_port.h - qs_port.h 5 @@ -552,57 +527,6 @@ qk_port.c 1 ..\..\..\..\..\ports\arm-cm\qk\armclang\qk_port.c - - - 2 - 0 - 0 - 0 - 0 - 2 - 2 - 2 - 2 - 2 - 11 - - - 1 - - - - 2 - 0 - 2 - 2 - 2 - 2 - 2 - 2 - 2 - 2 - 0 - 2 - 2 - 2 - 2 - 2 - 0 - 0 - 2 - 2 - 2 - 2 - 2 - - - QK_USE_IRQ_NUM=30 QK_USE_IRQ_HANDLER=LCD_IRQHandler - - - - - - @@ -693,16 +617,16 @@ 1 ..\..\..\..\..\src\qs\qs_fp.c - - qs_pkg.h - 5 - ..\..\..\..\..\src\qs_pkg.h - qs_rx.c 1 ..\..\..\..\..\src\qs\qs_rx.c + + qstamp.c + 1 + ..\..\..\..\..\src\qs\qstamp.c + @@ -1109,15 +1033,10 @@ 1 ..\..\table.c - - qstamp.c - 1 - ..\..\..\..\..\include\qstamp.c - main.c 1 - ..\main.c + ..\..\main.c @@ -1189,11 +1108,6 @@ 1 ..\..\..\..\..\src\qf\qf_mem.c - - qf_pkg.h - 5 - ..\..\..\..\..\src\qf_pkg.h - qf_ps.c 1 @@ -1229,21 +1143,6 @@ QP_port - - qep_port.h - 5 - ..\..\..\..\..\ports\arm-cm\qk\armclang\qep_port.h - - - qf_port.h - 5 - ..\..\..\..\..\ports\arm-cm\qk\armclang\qf_port.h - - - qk_port.h - 5 - ..\..\..\..\..\ports\arm-cm\qk\armclang\qk_port.h - qs_port.h 5 @@ -1343,16 +1242,16 @@ 1 ..\..\..\..\..\src\qs\qs_fp.c - - qs_pkg.h - 5 - ..\..\..\..\..\src\qs_pkg.h - qs_rx.c 1 ..\..\..\..\..\src\qs\qs_rx.c + + qstamp.c + 1 + ..\..\..\..\..\src\qs\qstamp.c + @@ -1759,15 +1658,10 @@ 1 ..\..\table.c - - qstamp.c - 1 - ..\..\..\..\..\include\qstamp.c - main.c 1 - ..\main.c + ..\..\main.c @@ -1839,11 +1733,6 @@ 1 ..\..\..\..\..\src\qf\qf_mem.c - - qf_pkg.h - 5 - ..\..\..\..\..\src\qf_pkg.h - qf_ps.c 1 @@ -1879,21 +1768,6 @@ QP_port - - qep_port.h - 5 - ..\..\..\..\..\ports\arm-cm\qk\armclang\qep_port.h - - - qf_port.h - 5 - ..\..\..\..\..\ports\arm-cm\qk\armclang\qf_port.h - - - qk_port.h - 5 - ..\..\..\..\..\ports\arm-cm\qk\armclang\qk_port.h - qs_port.h 5 @@ -1924,16 +1798,16 @@ 1 ..\..\..\..\..\src\qs\qs_fp.c - - qs_pkg.h - 5 - ..\..\..\..\..\src\qs_pkg.h - qs_rx.c 1 ..\..\..\..\..\src\qs\qs_rx.c + + qstamp.c + 1 + ..\..\..\..\..\src\qs\qstamp.c + diff --git a/examples/arm-cm/dpp_nucleo-l053r8/qk/bsp.c b/examples/arm-cm/dpp_nucleo-l053r8/qk/bsp.c index 382e9b59..23c4480b 100644 --- a/examples/arm-cm/dpp_nucleo-l053r8/qk/bsp.c +++ b/examples/arm-cm/dpp_nucleo-l053r8/qk/bsp.c @@ -1,449 +1,412 @@ -/*============================================================================ -* Product: DPP example, NUCLEO-L053R8 board, preemptive QK kernel -* Last updated for version 7.2.0 -* Last updated on 2022-12-13 -* -* Q u a n t u m L e a P s -* ------------------------ -* Modern Embedded Software -* -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* -* -============================================================================*/ -#include "qpc.h" -#include "dpp.h" -#include "bsp.h" +//============================================================================ +// Product: DPP example, NUCLEO-L053R8 board, QK kernel +// Last updated for version 7.3.0 +// Last updated on 2023-08-22 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. +// +// This program is open source software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Alternatively, this program may be distributed and modified under the +// terms of Quantum Leaps commercial licenses, which expressly supersede +// the GNU General Public License and are specifically designed for +// licensees interested in retaining the proprietary status of their code. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Contact information: +// +// +//============================================================================ +#include "qpc.h" // QP/C real-time embedded framework +#include "dpp.h" // DPP Application interface +#include "bsp.h" // Board Support Package -#include "stm32l0xx.h" /* CMSIS-compliant header file for the MCU used */ -/* add other drivers if necessary... */ +#include "stm32l0xx.h" // CMSIS-compliant header file for the MCU used +// add other drivers if necessary... Q_DEFINE_THIS_FILE -/* Local-scope defines -----------------------------------------------------*/ -/* LED pins available on the board (just one user LED LD2--Green on PA.5) */ -#define LED_LD2 (1U << 5) +// Local-scope objects ----------------------------------------------------- +// LED pins available on the board (just one user LED LD2--Green on PA.5) +#define LD2_PIN 5U -/* Button pins available on the board (just one user Button B1 on PC.13) */ -#define BTN_B1 (1U << 13) +// Button pins available on the board (just one user Button B1 on PC.13) +#define B1_PIN 13U -static uint32_t l_rnd; /* random seed */ +static uint32_t l_rndSeed; #ifdef Q_SPY - QSTimeCtr QS_tickTime_; - QSTimeCtr QS_tickPeriod_; + // QSpy source IDs + static QSpyId const l_SysTick_Handler = { 0U }; - /* QSpy source IDs */ - static QSpyId const l_SysTick_Handler = { 0U }; - static QSpyId const l_EXTI0_1_IRQHandler = { 0U }; + static QSTimeCtr QS_tickTime_; + static QSTimeCtr QS_tickPeriod_; - enum AppRecords { /* application-specific trace records */ + enum AppRecords { // application-specific trace records PHILO_STAT = QS_USER, + PAUSED_STAT, CONTEXT_SW, }; #endif -/* ISRs used in the application ==========================================*/ -void SysTick_Handler(void); -void EXTI0_1_IRQHandler(void); -void USART2_IRQHandler(void); +//============================================================================ +// Error handler and ISRs... -/*..........................................................................*/ -void SysTick_Handler(void) { /* system clock tick ISR */ - /* state of the button debouncing, see below */ - static struct ButtonsDebouncing { +Q_NORETURN Q_onError(char const * const module, int_t const id) { + // NOTE: this implementation of the error handler is intended only + // for debugging and MUST be changed for deployment of the application + // (assuming that you ship your production code with assertions enabled). + Q_UNUSED_PAR(module); + Q_UNUSED_PAR(id); + QS_ASSERTION(module, id, 10000U); // report assertion to QS + +#ifndef NDEBUG + // light up the user LED + GPIOA->BSRR = (1U << LD2_PIN); + for (;;) { // for debugging, hang on in an endless loop... + } +#else + NVIC_SystemReset(); + for (;;) { // explicitly "no-return" + } +#endif +} +//............................................................................ +void assert_failed(char const * const module, int_t const id); // prototype +void assert_failed(char const * const module, int_t const id) { + Q_onError(module, id); +} + +// ISRs used in the application ========================================== + +void SysTick_Handler(void); // prototype +void SysTick_Handler(void) { // system clock tick ISR + QK_ISR_ENTRY(); // inform QK about entering an ISR + + QTIMEEVT_TICK_X(0U, &l_SysTick_Handler); // time events at rate 0 + + // Perform the debouncing of buttons. The algorithm for debouncing + // adapted from the book "Embedded Systems Dictionary" by Jack Ganssle + // and Michael Barr, page 71. + static struct { uint32_t depressed; uint32_t previous; } buttons = { 0U, 0U }; - uint32_t current; - uint32_t tmp; - QK_ISR_ENTRY(); /* inform QK about entering an ISR */ + uint32_t current = ~GPIOC->IDR; // read Port C with state of Button B1 + uint32_t tmp = buttons.depressed; // save the depressed buttons + buttons.depressed |= (buttons.previous & current); // set depressed + buttons.depressed &= (buttons.previous | current); // clear released + buttons.previous = current; // update the history + tmp ^= buttons.depressed; // changed debounced depressed + current = buttons.depressed; -#ifdef Q_SPY - { - tmp = SysTick->CTRL; /* clear CTRL_COUNTFLAG */ - QS_tickTime_ += QS_tickPeriod_; /* account for the clock rollover */ - } -#endif - - QTIMEEVT_TICK_X(0U, &l_SysTick_Handler); /* process time events for rate 0 */ - //QACTIVE_POST(the_Ticker0, 0, &l_SysTick_Handler); /* post to Ticker0 */ - - /* get state of the user button */ - /* Perform the debouncing of buttons. The algorithm for debouncing - * adapted from the book "Embedded Systems Dictionary" by Jack Ganssle - * and Michael Barr, page 71. - */ - current = ~GPIOC->IDR; /* read Port C with the state of Button B1 */ - tmp = buttons.depressed; /* save the debounced depressed buttons */ - buttons.depressed |= (buttons.previous & current); /* set depressed */ - buttons.depressed &= (buttons.previous | current); /* clear released */ - buttons.previous = current; /* update the history */ - tmp ^= buttons.depressed; /* changed debounced depressed */ - if ((tmp & BTN_B1) != 0U) { /* debounced B1 state changed? */ - if ((buttons.depressed & BTN_B1) != 0U) { /* is B1 depressed? */ - static QEvt const pauseEvt = { PAUSE_SIG, 0U, 0U}; + if ((tmp & (1U << B1_PIN)) != 0U) { // debounced B1 state changed? + if ((current & (1U << B1_PIN)) != 0U) { // is B1 depressed? + static QEvt const pauseEvt = QEVT_INITIALIZER(PAUSE_SIG); QACTIVE_PUBLISH(&pauseEvt, &l_SysTick_Handler); } - else { /* the button is released */ - static QEvt const serveEvt = { SERVE_SIG, 0U, 0U}; + else { // the button is released + static QEvt const serveEvt = QEVT_INITIALIZER(SERVE_SIG); QACTIVE_PUBLISH(&serveEvt, &l_SysTick_Handler); } } - QK_ISR_EXIT(); /* inform QK about exiting an ISR */ -} -/*..........................................................................*/ -/* interrupt handler for testing preemptions in QK */ -void EXTI0_1_IRQHandler(void) { - static QEvt const testEvt = { TEST_SIG, 0U, 0U }; - QK_ISR_ENTRY(); /* inform QK about entering an ISR */ - QACTIVE_POST(AO_Table, &testEvt, (void *)0); - QK_ISR_EXIT(); /* inform QK about exiting an ISR */ -} -/*..........................................................................*/ #ifdef Q_SPY -void USART2_IRQHandler(void) { /* used in QS-RX (kernel UNAWARE interrutp) */ - /* is RX register NOT empty? */ - if ((USART2->ISR & (1U << 5)) != 0) { + tmp = SysTick->CTRL; // clear CTRL_COUNTFLAG + QS_tickTime_ += QS_tickPeriod_; // account for the clock rollover +#endif + + QK_ISR_EXIT(); // inform QK about exiting an ISR +} +//............................................................................ +// interrupt handler for testing preemptions in QK +void EXTI0_1_IRQHandler(void); // prototype +void EXTI0_1_IRQHandler(void) { + QK_ISR_ENTRY(); // inform QK about entering an ISR + + static QEvt const testEvt = QEVT_INITIALIZER(TEST_SIG); + QACTIVE_POST(AO_Table, &testEvt, (void *)0); + + QK_ISR_EXIT(); // inform QK about exiting an ISR +} + +//............................................................................ +#ifdef Q_SPY +// ISR for receiving bytes from the QSPY Back-End +// NOTE: This ISR is "QF-unaware" meaning that it does not interact with +// the QF/QK and is not disabled. Such ISRs don't need to call +// QK_ISR_ENTRY/QK_ISR_EXIT and they cannot post or publish events. + +void USART2_IRQHandler(void); // prototype +void USART2_IRQHandler(void) { // used in QS-RX (kernel UNAWARE interrutp) + // is RX register NOT empty? + if ((USART2->ISR & (1U << 5U)) != 0U) { uint32_t b = USART2->RDR; QS_RX_PUT(b); } + QK_ARM_ERRATUM_838869(); } -#endif +#endif // Q_SPY -/* BSP functions ===========================================================*/ -/*..........................................................................*/ -/* MPU setup for STM32L053R8 MCU */ -static void STM32L053R8_MPU_setup(void) { - /* The following MPU configuration contains the general STM32 memory model - * as described in the ST AppNote AN4838 "Managing memory protection unit - * in STM32 MCUs", Figure 2. Cortex-M0+/M3/M4/M7 processor memory map. - * - * Please note that the actual STM32 MCUs provide much less Flash and SRAM - * than the maximums configured here. This means that actual MCUs have - * unmapped memory regions (e.g., beyond the actual SRAM). Attempts to - * access these regions causes the HardFault exception, which is the - * desired behavior. - */ - static struct { - uint32_t rbar; - uint32_t rasr; - } const mpu_setup[] = { - - { /* region #0: Flash: base=0x0000'0000, size=512M=2^(28+1) */ - 0x00000000U /* base address */ - | MPU_RBAR_VALID_Msk /* valid region */ - | (MPU_RBAR_REGION_Msk & 0U), /* region #0 */ - (28U << MPU_RASR_SIZE_Pos) /* 2^(18+1) region */ - | (0x6U << MPU_RASR_AP_Pos) /* PA:ro/UA:ro */ - | (1U << MPU_RASR_C_Pos) /* C=1 */ - | MPU_RASR_ENABLE_Msk /* region enable */ - }, - - { /* region #1: SRAM: base=0x2000'0000, size=512M=2^(28+1) */ - 0x20000000U /* base address */ - | MPU_RBAR_VALID_Msk /* valid region */ - | (MPU_RBAR_REGION_Msk & 1U), /* region #1 */ - (28U << MPU_RASR_SIZE_Pos) /* 2^(28+1) region */ - | (0x3U << MPU_RASR_AP_Pos) /* PA:rw/UA:rw */ - | (1U << MPU_RASR_XN_Pos) /* XN=1 */ - | (1U << MPU_RASR_S_Pos) /* S=1 */ - | (1U << MPU_RASR_C_Pos) /* C=1 */ - | MPU_RASR_ENABLE_Msk /* region enable */ - }, - - /* region #3: (not configured) */ - { MPU_RBAR_VALID_Msk | (MPU_RBAR_REGION_Msk & 2U), 0U }, - - { /* region #3: Peripherals: base=0x4000'0000, size=512M=2^(28+1) */ - 0x40000000U /* base address */ - | MPU_RBAR_VALID_Msk /* valid region */ - | (MPU_RBAR_REGION_Msk & 3U), /* region #3 */ - (28U << MPU_RASR_SIZE_Pos) /* 2^(28+1) region */ - | (0x3U << MPU_RASR_AP_Pos) /* PA:rw/UA:rw */ - | (1U << MPU_RASR_XN_Pos) /* XN=1 */ - | (1U << MPU_RASR_S_Pos) /* S=1 */ - | (1U << MPU_RASR_B_Pos) /* B=1 */ - | MPU_RASR_ENABLE_Msk /* region enable */ - }, - - { /* region #4: Priv. Periph: base=0xE000'0000, size=512M=2^(28+1) */ - 0xE0000000U /* base address */ - | MPU_RBAR_VALID_Msk /* valid region */ - | (MPU_RBAR_REGION_Msk & 4U), /* region #4 */ - (28U << MPU_RASR_SIZE_Pos) /* 2^(28+1) region */ - | (0x3U << MPU_RASR_AP_Pos) /* PA:rw/UA:rw */ - | (1U << MPU_RASR_XN_Pos) /* XN=1 */ - | (1U << MPU_RASR_S_Pos) /* S=1 */ - | (1U << MPU_RASR_B_Pos) /* B=1 */ - | MPU_RASR_ENABLE_Msk /* region enable */ - }, - - { /* region #5: Ext RAM: base=0x6000'0000, size=1G=2^(29+1) */ - 0x60000000U /* base address */ - | MPU_RBAR_VALID_Msk /* valid region */ - | (MPU_RBAR_REGION_Msk & 5U), /* region #5 */ - (29U << MPU_RASR_SIZE_Pos) /* 2^(28+1) region */ - | (0x3U << MPU_RASR_AP_Pos) /* PA:rw/UA:rw */ - | (1U << MPU_RASR_XN_Pos) /* XN=1 */ - | (1U << MPU_RASR_S_Pos) /* S=1 */ - | (1U << MPU_RASR_B_Pos) /* B=1 */ - | MPU_RASR_ENABLE_Msk /* region enable */ - }, - - { /* region #6: Ext Dev: base=0xA000'0000, size=1G=2^(29+1) */ - 0xA0000000U /* base address */ - | MPU_RBAR_VALID_Msk /* valid region */ - | (MPU_RBAR_REGION_Msk & 6U), /* region #6 */ - (29U << MPU_RASR_SIZE_Pos) /* 2^(28+1) region */ - | (0x3U << MPU_RASR_AP_Pos) /* PA:rw/UA:rw */ - | (1U << MPU_RASR_XN_Pos) /* XN=1 */ - | (1U << MPU_RASR_S_Pos) /* S=1 */ - | (1U << MPU_RASR_B_Pos) /* B=1 */ - | MPU_RASR_ENABLE_Msk /* region enable */ - }, - - { /* region #7: NULL-pointer: base=0x000'0000, size=128M=2^(26+1) */ - /* NOTE: this region extends to 0x080'0000, which is where - * the ROM is re-mapped by STM32 - */ - 0x00000000U /* base address */ - | MPU_RBAR_VALID_Msk /* valid region */ - | (MPU_RBAR_REGION_Msk & 7U), /* region #7 */ - (26U << MPU_RASR_SIZE_Pos) /* 2^(26+1)=128M region */ - | (0x0U << MPU_RASR_AP_Pos) /* PA:na/UA:na */ - | (1U << MPU_RASR_XN_Pos) /* XN=1 */ - | MPU_RASR_ENABLE_Msk /* region enable */ - }, - - }; - - __DSB(); - MPU->CTRL = 0U; /* disable the MPU */ - for (uint_fast8_t n = 0U; n < Q_DIM(mpu_setup); ++n) { - MPU->RBAR = mpu_setup[n].rbar; - MPU->RASR = mpu_setup[n].rasr; - } - MPU->CTRL = MPU_CTRL_PRIVDEFENA_Msk /* enable background region */ - | MPU_CTRL_ENABLE_Msk; /* enable the MPU */ - __ISB(); - __DSB(); -} -/*..........................................................................*/ -void BSP_init(void) { - /* setup the MPU... */ - STM32L053R8_MPU_setup(); - - /* NOTE: SystemInit() has been already called from the startup code - * but SystemCoreClock needs to be updated - */ - SystemCoreClockUpdate(); - - /* enable GPIOA clock port for the LED LD2 */ - RCC->IOPENR |= (1U << 0); - - /* configure LED (PA.5) pin as push-pull output, no pull-up, pull-down */ - GPIOA->MODER &= ~((3U << 2*5)); - GPIOA->MODER |= ((1U << 2*5)); - GPIOA->OTYPER &= ~((1U << 5)); - GPIOA->OSPEEDR &= ~((3U << 2*5)); - GPIOA->OSPEEDR |= ((1U << 2*5)); - GPIOA->PUPDR &= ~((3U << 2*5)); - - /* enable GPIOC clock port for the Button B1 */ - RCC->IOPENR |= (1U << 2); - - /* configure Button (PC.13) pins as input, no pull-up, pull-down */ - GPIOC->MODER &= ~(3U << 2*13); - GPIOC->OSPEEDR &= ~(3U << 2*13); - GPIOC->OSPEEDR |= (1U << 2*13); - GPIOC->PUPDR &= ~(3U << 2*13); - - BSP_randomSeed(1234U); /* seed the random number generator */ - - /* initialize the QS software tracing... */ - if (QS_INIT((void *)0) == 0U) { - Q_ERROR(); - } - QS_OBJ_DICTIONARY(&l_SysTick_Handler); - QS_OBJ_DICTIONARY(&l_EXTI0_1_IRQHandler); - QS_USR_DICTIONARY(PHILO_STAT); - QS_USR_DICTIONARY(CONTEXT_SW); - - /* setup the QS filters... */ - QS_GLB_FILTER(QS_ALL_RECORDS); /* all records */ - QS_GLB_FILTER(-QS_QF_TICK); /* exclude the clock tick */ -} -/*..........................................................................*/ -void BSP_displayPhilStat(uint8_t n, char const *stat) { - if (stat[0] == 'h') { - GPIOA->BSRR |= LED_LD2; /* turn LED on */ - } - else { - GPIOA->BSRR |= (LED_LD2 << 16); /* turn LED off */ - } - - QS_BEGIN_ID(PHILO_STAT, AO_Philo[n]->prio) /* app-specific record */ - QS_U8(1, n); /* Philosopher number */ - QS_STR(stat); /* Philosopher status */ - QS_END() -} -/*..........................................................................*/ -void BSP_displayPaused(uint8_t paused) { - /* not enough LEDs to implement this feature */ - if (paused != 0U) { - //GPIOA->BSRR |= (LED_LD2); /* turn LED[n] on */ - } - else { - //GPIOA->BSRR |= (LED_LD2 << 16); /* turn LED[n] off */ - } -} -/*..........................................................................*/ -uint32_t BSP_random(void) { /* a very cheap pseudo-random-number generator */ - /* "Super-Duper" Linear Congruential Generator (LCG) - * LCG(2^32, 3*7*11*13*23, 0, seed) - */ - l_rnd = l_rnd * (3U*7U*11U*13U*23U); - return l_rnd >> 8; -} -/*..........................................................................*/ -void BSP_randomSeed(uint32_t seed) { - l_rnd = seed; -} -/*..........................................................................*/ -void BSP_terminate(int16_t result) { - (void)result; -} -/*..........................................................................*/ -void BSP_wait4SW1(void) { - while ((GPIOC->IDR & BTN_B1) != 0U) { - GPIOA->BSRR |= (LED_LD2); /* turn LED2 on */ - GPIOA->BSRR |= (LED_LD2 << 16); /* turn LED2 off */ - } -} -/*..........................................................................*/ -void BSP_ledOn(void) { - //GPIOA->BSRR |= (LED_LD2); /* turn LED2 on */ -} -/*..........................................................................*/ -void BSP_ledOff(void) { - //GPIOA->BSRR |= (LED_LD2 << 16); /* turn LED2 off */ -} - -/* QF callbacks ============================================================*/ -void QF_onStartup(void) { - /* set up the SysTick timer to fire at BSP_TICKS_PER_SEC rate */ - SysTick_Config(SystemCoreClock / BSP_TICKS_PER_SEC); - - /* set priorities of ALL ISRs used in the system */ - NVIC_SetPriority(USART2_IRQn, 0); - NVIC_SetPriority(SysTick_IRQn, QF_AWARE_ISR_CMSIS_PRI + 0U); - NVIC_SetPriority(EXTI0_1_IRQn, QF_AWARE_ISR_CMSIS_PRI + 1U); - /* ... */ - - /* enable IRQs... */ - NVIC_EnableIRQ(EXTI0_1_IRQn); -#ifdef Q_SPY - NVIC_EnableIRQ(USART2_IRQn); /* UART2 interrupt used for QS-RX */ -#endif -} -/*..........................................................................*/ -void QF_onCleanup(void) { -} -/*..........................................................................*/ +//............................................................................ #ifdef QF_ON_CONTEXT_SW -/* NOTE: the context-switch callback is called with interrupts DISABLED */ +// NOTE: the context-switch callback is called with interrupts DISABLED void QF_onContextSw(QActive *prev, QActive *next) { - QS_BEGIN_NOCRIT(CONTEXT_SW, 0U) /* no critical section! */ + QS_BEGIN_INCRIT(CONTEXT_SW, 0U) // in critical section! QS_OBJ(prev); QS_OBJ(next); - QS_END_NOCRIT() + QS_END_INCRIT() } -#endif /* QF_ON_CONTEXT_SW */ -/*..........................................................................*/ -void QK_onIdle(void) { /* called with interrupts enabled */ +#endif // QF_ON_CONTEXT_SW - /* toggle an LED on and then off (not enough LEDs, see NOTE01) */ - QF_INT_DISABLE(); - //GPIOA->BSRR |= (LED_LD2); /* turn LED[n] on */ - //GPIOA->BSRR |= (LED_LD2 << 16); /* turn LED[n] off */ - QF_INT_ENABLE(); +//============================================================================ +// BSP functions... + +void BSP_init(void) { + // Configure the MPU to prevent NULL-pointer dereferencing ... + MPU->RBAR = 0x0U // base address (NULL) + | MPU_RBAR_VALID_Msk // valid region + | (MPU_RBAR_REGION_Msk & 7U); // region #7 + MPU->RASR = (7U << MPU_RASR_SIZE_Pos) // 2^(7+1) region + | (0x0U << MPU_RASR_AP_Pos) // no-access region + | MPU_RASR_ENABLE_Msk; // region enable + MPU->CTRL = MPU_CTRL_PRIVDEFENA_Msk // enable background region + | MPU_CTRL_ENABLE_Msk; // enable the MPU + __ISB(); + __DSB(); + + // NOTE: SystemInit() has been already called from the startup code + // but SystemCoreClock needs to be updated + SystemCoreClockUpdate(); + + // enable GPIOA clock port for the LED LD2 + RCC->IOPENR |= (1U << 0U); + + // configure LED (PA.5) pin as push-pull output, no pull-up, pull-down + GPIOA->MODER &= ~((3U << 2U*LD2_PIN)); + GPIOA->MODER |= ((1U << 2U*LD2_PIN)); + GPIOA->OTYPER &= ~((1U << LD2_PIN)); + GPIOA->OSPEEDR &= ~((3U << 2U*LD2_PIN)); + GPIOA->OSPEEDR |= ((1U << 2U*LD2_PIN)); + GPIOA->PUPDR &= ~((3U << 2U*LD2_PIN)); + + // enable GPIOC clock port for the Button B1 + RCC->IOPENR |= (1U << 2U); + + // configure Button (PC.13) pins as input, no pull-up, pull-down + GPIOC->MODER &= ~(3U << 2U*B1_PIN); + GPIOC->OSPEEDR &= ~(3U << 2U*B1_PIN); + GPIOC->OSPEEDR |= (1U << 2U*B1_PIN); + GPIOC->PUPDR &= ~(3U << 2U*B1_PIN); + + // seed the random number generator + BSP_randomSeed(1234U); + + // initialize the QS software tracing... + if (!QS_INIT((void *)0)) { + Q_ERROR(); + } + + // dictionaries... + QS_OBJ_DICTIONARY(&l_SysTick_Handler); + QS_USR_DICTIONARY(PHILO_STAT); + QS_USR_DICTIONARY(PAUSED_STAT); + QS_USR_DICTIONARY(CONTEXT_SW); + + QS_ONLY(produce_sig_dict()); + + // setup the QS filters... + QS_GLB_FILTER(QS_ALL_RECORDS); // all records + QS_GLB_FILTER(-QS_QF_TICK); // exclude the clock tick +} +//............................................................................ +void BSP_start(void) { + // initialize event pools + static QF_MPOOL_EL(TableEvt) smlPoolSto[2*N_PHILO]; + QF_poolInit(smlPoolSto, sizeof(smlPoolSto), sizeof(smlPoolSto[0])); + + // initialize publish-subscribe + static QSubscrList subscrSto[MAX_PUB_SIG]; + QActive_psInit(subscrSto, Q_DIM(subscrSto)); + + // instantiate and start AOs/threads... + + static QEvt const *philoQueueSto[N_PHILO][10]; + for (uint8_t n = 0U; n < N_PHILO; ++n) { + Philo_ctor(n); + QACTIVE_START(AO_Philo[n], + + // NOTE: set the preemption-threshold of all Philos to + // the same level, so that they cannot preempt each other. + Q_PRIO(n + 3U, N_PHILO + 2U), // QF-prio/pre-thre. + + philoQueueSto[n], // event queue storage + Q_DIM(philoQueueSto[n]), // queue length [events] + (void *)0, 0U, // QK needs no stack storage + (void *)0); // no initialization param + } + + static QEvt const *tableQueueSto[N_PHILO]; + Table_ctor(); + QACTIVE_START(AO_Table, + N_PHILO + 7U, // QP prio. of the AO + tableQueueSto, // event queue storage + Q_DIM(tableQueueSto), // queue length [events] + (void *)0, 0U, // QK needs no stack storage + (void *)0); // no initialization param +} +//............................................................................ +void BSP_displayPhilStat(uint8_t n, char const *stat) { + Q_UNUSED_PAR(n); + + if (stat[0] == 'e') { + GPIOA->BSRR = (1U << LD2_PIN); // turn LED on + } + else { + GPIOA->BSRR = (1U << (LD2_PIN + 16U)); // turn LED off + } + + // app-specific trace record... + QS_BEGIN_ID(PHILO_STAT, AO_Table->prio) + QS_U8(1, n); // Philosopher number + QS_STR(stat); // Philosopher status + QS_END() +} +//............................................................................ +void BSP_displayPaused(uint8_t const paused) { + // not enough LEDs to implement this feature + if (paused != 0U) { + //GPIOA->BSRR = (1U << LD2_PIN); // turn LED[n] on + } + else { + //GPIOA->BSRR = (1U << (LD2_PIN + 16U)); // turn LED[n] off + } + + // application-specific trace record + QS_BEGIN_ID(PAUSED_STAT, AO_Table->prio) + QS_U8(1, paused); // Paused status + QS_END() +} +//............................................................................ +void BSP_randomSeed(uint32_t seed) { + l_rndSeed = seed; +} +//............................................................................ +uint32_t BSP_random(void) { // a very cheap pseudo-random-number generator + + QSchedStatus lockStat = QK_schedLock(N_PHILO); + // "Super-Duper" Linear Congruential Generator (LCG) + // LCG(2^32, 3*7*11*13*23, 0, seed) + uint32_t rnd = l_rndSeed * (3U*7U*11U*13U*23U); + l_rndSeed = rnd; // set for the next time + QK_schedUnlock(lockStat); + + return (rnd >> 8U); +} +//............................................................................ +void BSP_ledOn(void) { + //GPIOA->BSRR = (1U << LD2_PIN); // turn LED2 on +} +//............................................................................ +void BSP_ledOff(void) { + //GPIOA->BSRR = (1U << (LD2_PIN + 16U)); // turn LED2 off +} +//............................................................................ +void BSP_terminate(int16_t result) { + Q_UNUSED_PAR(result); +} + +//============================================================================ +// QF callbacks... +void QF_onStartup(void) { + // set up the SysTick timer to fire at BSP_TICKS_PER_SEC rate + SysTick_Config(SystemCoreClock / BSP_TICKS_PER_SEC); + + // assign all priority bits for preemption-prio. and none to sub-prio. + // NOTE: this might have been changed by STM32Cube. + NVIC_SetPriorityGrouping(0U); + + // set priorities of ALL ISRs used in the system, see NOTE1 + NVIC_SetPriority(USART2_IRQn, 0U); // kernel UNAWARE interrupt + NVIC_SetPriority(EXTI0_1_IRQn, QF_AWARE_ISR_CMSIS_PRI + 0U); + NVIC_SetPriority(SysTick_IRQn, QF_AWARE_ISR_CMSIS_PRI + 1U); + // ... + + // enable IRQs... + NVIC_EnableIRQ(EXTI0_1_IRQn); #ifdef Q_SPY - QS_rxParse(); /* parse all the received bytes */ + NVIC_EnableIRQ(USART2_IRQn); // UART2 interrupt used for QS-RX +#endif +} +//............................................................................ +void QF_onCleanup(void) { +} +//............................................................................ +void QK_onIdle(void) { - if ((USART2->ISR & (1U << 7)) != 0) { /* is TXE empty? */ - uint16_t b; + // toggle an LED on and then off (not enough LEDs, see NOTE01) + //QF_INT_DISABLE(); + //GPIOA->BSRR = (1U << LD2_PIN); // turn LED[n] on + //GPIOA->BSRR = (1U << (LD2_PIN + 16U)); // turn LED[n] off + //QF_INT_ENABLE(); +#ifdef Q_SPY + QF_INT_DISABLE(); + QS_rxParse(); // parse all the received bytes + QF_INT_ENABLE(); + QF_CRIT_EXIT_NOP(); + + if ((USART2->ISR & (1U << 7U)) != 0U) { // is TXE empty? QF_INT_DISABLE(); - b = QS_getByte(); + uint16_t b = QS_getByte(); QF_INT_ENABLE(); - if (b != QS_EOD) { /* not End-Of-Data? */ - USART2->TDR = (b & 0xFFU); /* put into the DR register */ + if (b != QS_EOD) { // not End-Of-Data? + USART2->TDR = b; // put into the DR register } } #elif defined NDEBUG - /* Put the CPU and peripherals to the low-power mode. - * you might need to customize the clock management for your application, - * see the datasheet for your particular Cortex-M MCU. - */ - /* !!!CAUTION!!! - * The WFI instruction stops the CPU clock, which unfortunately disables - * the JTAG port, so the ST-Link debugger can no longer connect to the - * board. For that reason, the call to __WFI() has to be used with CAUTION. - * - * NOTE: If you find your board "frozen" like this, strap BOOT0 to VDD and - * reset the board, then connect with ST-Link Utilities and erase the part. - * The trick with BOOT(0) is it gets the part to run the System Loader - * instead of your broken code. When done disconnect BOOT0, and start over. - */ - //__WFI(); /* Wait-For-Interrupt */ + // Put the CPU and peripherals to the low-power mode. + // you might need to customize the clock management for your application, + // see the datasheet for your particular Cortex-M MCU. + // + // !!!CAUTION!!! + // The WFI instruction stops the CPU clock, which unfortunately disables + // the JTAG port, so the ST-Link debugger can no longer connect to the + // board. For that reason, the call to __WFI() has to be used with CAUTION. + // + // NOTE: If you find your board "frozen" like this, strap BOOT0 to VDD and + // reset the board, then connect with ST-Link Utilities and erase the part. + // The trick with BOOT(0) is it gets the part to run the System Loader + // instead of your broken code. When done disconnect BOOT0, and start over. + // + //__WFI(); // Wait-For-Interrupt #endif } -/*..........................................................................*/ -Q_NORETURN Q_onAssert(char const * const module, int_t const loc) { - /* - * NOTE: add here your application-specific error handling - */ - (void)module; - (void)loc; - QS_ASSERTION(module, loc, 10000U); /* report assertion to QS */ - -#ifndef NDEBUG - BSP_wait4SW1(); -#endif - NVIC_SystemReset(); -} - -/* QS callbacks ============================================================*/ +//============================================================================ +// QS callbacks... #ifdef Q_SPY -/*..........................................................................*/ + +//............................................................................ #define __DIV(__PCLK, __BAUD) (((__PCLK / 4) *25)/(__BAUD)) #define __DIVMANT(__PCLK, __BAUD) (__DIV(__PCLK, __BAUD)/100) #define __DIVFRAQ(__PCLK, __BAUD) \ @@ -452,90 +415,116 @@ Q_NORETURN Q_onAssert(char const * const module, int_t const loc) { #define __USART_BRR(__PCLK, __BAUD) \ ((__DIVMANT(__PCLK, __BAUD) << 4)|(__DIVFRAQ(__PCLK, __BAUD) & 0x0F)) -/*..........................................................................*/ +// USART2 pins PA.2 and PA.3 +#define USART2_TX_PIN 2U +#define USART2_RX_PIN 3U + +//............................................................................ uint8_t QS_onStartup(void const *arg) { - static uint8_t qsBuf[2*1024]; /* buffer for Quantum Spy */ - static uint8_t qsRxBuf[256]; /* buffer for QS-RX channel */ + Q_UNUSED_PAR(arg); - (void)arg; /* avoid the "unused parameter" compiler warning */ + static uint8_t qsTxBuf[2*1024]; // buffer for QS-TX channel + QS_initBuf(qsTxBuf, sizeof(qsTxBuf)); - QS_initBuf(qsBuf, sizeof(qsBuf)); + static uint8_t qsRxBuf[100]; // buffer for QS-RX channel QS_rxInitBuf(qsRxBuf, sizeof(qsRxBuf)); - /* enable peripheral clock for USART2 */ - RCC->IOPENR |= ( 1U << 0); /* Enable GPIOA clock */ - RCC->APB1ENR |= ( 1U << 17); /* Enable USART#2 clock */ + // enable peripheral clock for USART2 + RCC->IOPENR |= ( 1U << 0U); // Enable GPIOA clock for USART pins + RCC->APB1ENR |= ( 1U << 17U); // Enable USART#2 clock - /* Configure PA3 to USART2_RX, PA2 to USART2_TX */ - GPIOA->AFR[0] &= ~((15U << 4* 3) | (15U << 4* 2) ); - GPIOA->AFR[0] |= (( 4U << 4* 3) | ( 4U << 4* 2) ); - GPIOA->MODER &= ~(( 3U << 2* 3) | ( 3U << 2* 2) ); - GPIOA->MODER |= (( 2U << 2* 3) | ( 2U << 2* 2) ); + // Configure PA3 to USART2_RX, PA2 to USART2_TX + GPIOA->AFR[0] &= ~((15U << 4U*USART2_RX_PIN) | (15U << 4U*USART2_TX_PIN)); + GPIOA->AFR[0] |= (( 4U << 4U*USART2_RX_PIN) | ( 4U << 4U*USART2_TX_PIN)); + GPIOA->MODER &= ~(( 3U << 2U*USART2_RX_PIN) | ( 3U << 2U*USART2_TX_PIN)); + GPIOA->MODER |= (( 2U << 2U*USART2_RX_PIN) | ( 2U << 2U*USART2_TX_PIN)); - USART2->BRR = __USART_BRR(SystemCoreClock, 115200U); /* baud rate */ - USART2->CR3 = 0x0000 | /* no flow control */ - (1U << 12); /* disable overrun detection (OVRDIS) */ - USART2->CR2 = 0x0000; /* 1 stop bit */ - USART2->CR1 = ((1U << 2) | /* enable RX */ - (1U << 3) | /* enable TX */ - (1U << 5) | /* enable RX interrupt */ - (0U << 12) | /* 8 data bits */ - (0U << 28) | /* 8 data bits */ - (1U << 0) ); /* enable USART */ + USART2->BRR = __USART_BRR(SystemCoreClock, 115200U); // baud rate + USART2->CR3 = 0x0000U | // no flow control + (1U << 12U); // disable overrun detection (OVRDIS) + USART2->CR2 = 0x0000U; // 1 stop bit + USART2->CR1 = ((1U << 2U) | // enable RX + (1U << 3U) | // enable TX + (1U << 5U) | // enable RX interrupt + (0U << 12U) | // 8 data bits + (0U << 28U) | // 8 data bits + (1U << 0U)); // enable USART QS_tickPeriod_ = SystemCoreClock / BSP_TICKS_PER_SEC; - QS_tickTime_ = QS_tickPeriod_; /* to start the timestamp at zero */ + QS_tickTime_ = QS_tickPeriod_; // to start the timestamp at zero - return 1U; /* return success */ + return 1U; // return success } -/*..........................................................................*/ +//............................................................................ void QS_onCleanup(void) { } -/*..........................................................................*/ -QSTimeCtr QS_onGetTime(void) { /* NOTE: invoked with interrupts DISABLED */ - if ((SysTick->CTRL & 0x00010000) == 0) { /* COUNT no set? */ +//............................................................................ +QSTimeCtr QS_onGetTime(void) { // NOTE: invoked with interrupts DISABLED + if ((SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk) == 0U) { // not set? return QS_tickTime_ - (QSTimeCtr)SysTick->VAL; } - else { /* the rollover occured, but the SysTick_ISR did not run yet */ + else { // the rollover occured, but the SysTick_ISR did not run yet return QS_tickTime_ + QS_tickPeriod_ - (QSTimeCtr)SysTick->VAL; } } -/*..........................................................................*/ +//............................................................................ void QS_onFlush(void) { - uint16_t b; + for (;;) { + QF_CRIT_STAT - QF_INT_DISABLE(); - while ((b = QS_getByte()) != QS_EOD) { /* while not End-Of-Data... */ - QF_INT_ENABLE(); - while ((USART2->ISR & (1U << 7)) == 0U) { /* while TXE not empty */ + QF_CRIT_ENTRY(); + uint16_t b = QS_getByte(); + QF_CRIT_EXIT(); + + if (b != QS_EOD) { // NOT end-of-data + // busy-wait as long as TX has data to transmit + while ((USART2->ISR & 0x0080U) == 0U) { + } + USART2->TDR = b; // put into the TDR register + } + else { + break; // break out of the loop } - USART2->TDR = (b & 0xFFU); /* put into the DR register */ - QF_INT_DISABLE(); } - QF_INT_ENABLE(); } -/*..........................................................................*/ -/*! callback function to reset the target (to be implemented in the BSP) */ +//............................................................................ +//! callback function to reset the target (to be implemented in the BSP) void QS_onReset(void) { NVIC_SystemReset(); } -/*..........................................................................*/ -/*! callback function to execute a user command (to be implemented in BSP) */ +//............................................................................ void QS_onCommand(uint8_t cmdId, uint32_t param1, uint32_t param2, uint32_t param3) { - (void)cmdId; - (void)param1; - (void)param2; - (void)param3; + Q_UNUSED_PAR(cmdId); + Q_UNUSED_PAR(param1); + Q_UNUSED_PAR(param2); + Q_UNUSED_PAR(param3); } -#endif /* Q_SPY */ -/*--------------------------------------------------------------------------*/ +#endif // Q_SPY +//---------------------------------------------------------------------------- -/***************************************************************************** -* NOTE01: -* Usually, one of the LEDs is used to visualize the idle loop activity. -* However, the board has not enough LEDs (only one, actually), so this -* feature is disabled. -*/ +//============================================================================ +// NOTE1: +// The QF_AWARE_ISR_CMSIS_PRI constant from the QF port specifies the highest +// ISR priority that is disabled by the QF framework. The value is suitable +// for the NVIC_SetPriority() CMSIS function. +// +// Only ISRs prioritized at or below the QF_AWARE_ISR_CMSIS_PRI level (i.e., +// with the numerical values of priorities equal or higher than +// QF_AWARE_ISR_CMSIS_PRI) are allowed to call any QF services. These ISRs +// are "QF-aware". +// +// Conversely, any ISRs prioritized above the QF_AWARE_ISR_CMSIS_PRI priority +// level (i.e., with the numerical values of priorities less than +// QF_AWARE_ISR_CMSIS_PRI) are never disabled and are not aware of the kernel. +// Such "QF-unaware" ISRs cannot call any QF services. The only mechanism +// by which a "QF-unaware" ISR can communicate with the QF framework is by +// triggering a "QF-aware" ISR, which can post/publish events. +// +// NOTE2: +// Usually, one of the LEDs is used to visualize the idle loop activity. +// However, the board has not enough LEDs (only one, actually), so this +// feature is disabled. +// diff --git a/examples/arm-cm/dpp_nucleo-l053r8/qk/gnu/Makefile b/examples/arm-cm/dpp_nucleo-l053r8/qk/gnu/Makefile index 80fe504c..67fd9f22 100644 --- a/examples/arm-cm/dpp_nucleo-l053r8/qk/gnu/Makefile +++ b/examples/arm-cm/dpp_nucleo-l053r8/qk/gnu/Makefile @@ -134,8 +134,8 @@ LIBS := # defines DEFINES := \ -DQF_ON_CONTEXT_SW \ - -DQK_USE_IRQ_NUM=30 \ - -DQK_USE_IRQ_HANDLER=LCD_IRQHandler + -DQK_USE_IRQ_HANDLER=LCD_IRQHandler \ + -DQK_USE_IRQ_NUM=30 # ARM CPU, ARCH, FPU, and Float-ABI types... # ARM_CPU: [cortex-m0 | cortex-m0plus | cortex-m1 | cortex-m3 | cortex-m4] @@ -162,7 +162,7 @@ endif CC := $(GNU_ARM)/bin/arm-none-eabi-gcc CPP := $(GNU_ARM)/bin/arm-none-eabi-g++ AS := $(GNU_ARM)/bin/arm-none-eabi-as -LINK := $(GNU_ARM)/bin/arm-none-eabi-g++ +LINK := $(GNU_ARM)/bin/arm-none-eabi-gcc BIN := $(GNU_ARM)/bin/arm-none-eabi-objcopy @@ -207,11 +207,11 @@ ASFLAGS = -g $(ARM_CPU) $(ARM_FPU) $(ASM_CPU) $(ASM_FPU) CFLAGS = -c -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \ -ffunction-sections -fdata-sections \ - -O2 $(INCLUDES) $(DEFINES) -DQ_SPY + -O $(INCLUDES) $(DEFINES) -DQ_SPY CPPFLAGS = -c -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \ -ffunction-sections -fdata-sections -fno-rtti -fno-exceptions \ - -O2 $(INCLUDES) $(DEFINES) -DQ_SPY + -O $(INCLUDES) $(DEFINES) -DQ_SPY else # default Debug configuration .......................................... @@ -221,11 +221,11 @@ ASFLAGS = -g $(ARM_CPU) $(ARM_FPU) $(ASM_CPU) $(ASM_FPU) CFLAGS = -c -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \ -ffunction-sections -fdata-sections \ - -O2 $(INCLUDES) $(DEFINES) + -O $(INCLUDES) $(DEFINES) CPPFLAGS = -c -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \ -ffunction-sections -fdata-sections -fno-rtti -fno-exceptions \ - -O2 $(INCLUDES) $(DEFINES) + -O $(INCLUDES) $(DEFINES) endif # ...................................................................... @@ -263,7 +263,7 @@ $(TARGET_BIN): $(TARGET_ELF) $(BIN) -O binary $< $@ $(TARGET_ELF) : $(ASM_OBJS_EXT) $(C_OBJS_EXT) $(CPP_OBJS_EXT) - $(CC) $(CFLAGS) $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o + $(CC) $(CFLAGS) $(QPC)/src/qs/qstamp.c -o $(BIN_DIR)/qstamp.o $(LINK) $(LINKFLAGS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) $(BIN_DIR)/%.d : %.c diff --git a/examples/arm-cm/dpp_nucleo-l053r8/qk/gnu_with-stack-prot/bsp_stack-prot.c b/examples/arm-cm/dpp_nucleo-l053r8/qk/gnu_with-stack-prot/bsp_stack-prot.c deleted file mode 100644 index 28a5f087..00000000 --- a/examples/arm-cm/dpp_nucleo-l053r8/qk/gnu_with-stack-prot/bsp_stack-prot.c +++ /dev/null @@ -1,414 +0,0 @@ -/***************************************************************************** -* Product: DPP example, NUCLEO-L053R8 board, preemptive QK kernel -* Last updated for version 6.9.3 -* Last updated on 2021-03-03 -* -* Q u a n t u m L e a P s -* ------------------------ -* Modern Embedded Software -* -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* -* -*****************************************************************************/ -#include "qpc.h" -#include "dpp.h" -#include "bsp.h" - -#include "stm32l0xx.h" /* CMSIS-compliant header file for the MCU used */ -/* add other drivers if necessary... */ - -Q_DEFINE_THIS_FILE - -void SysTick_Handler(void); -void EXTI0_1_IRQHandler(void); - -/* Local-scope defines -----------------------------------------------------*/ -/* LED pins available on the board (just one user LED LD2--Green on PA.5) */ -#define LED_LD2 (1U << 5) - -/* Button pins available on the board (just one user Button B1 on PC.13) */ -#define BTN_B1 (1U << 13) - - -static uint32_t l_rnd; /* random seed */ - -#ifdef Q_SPY - QSTimeCtr QS_tickTime_; - QSTimeCtr QS_tickPeriod_; - - /* QSpy source IDs */ - static QSpyId const l_SysTick_Handler = { 0U }; - - enum AppRecords { /* application-specific trace records */ - PHILO_STAT = QS_USER, - CONTEXT_SW - }; - -#endif - -/* ISRs used in the application ==========================================*/ -void SysTick_Handler(void) { /* system clock tick ISR */ - /* state of the button debouncing, see below */ - static struct ButtonsDebouncing { - uint32_t depressed; - uint32_t previous; - } buttons = { 0U, 0U }; - uint32_t current; - uint32_t tmp; - - QK_ISR_ENTRY(); /* inform QK about entering an ISR */ - -#ifdef Q_SPY - { - tmp = SysTick->CTRL; /* clear CTRL_COUNTFLAG */ - QS_tickTime_ += QS_tickPeriod_; /* account for the clock rollover */ - } -#endif - - QTIMEEVT_TICK_X(0U, &l_SysTick_Handler); /* process time events for rate 0 */ - //QACTIVE_POST(the_Ticker0, 0, &l_SysTick_Handler); /* post to Ticker0 */ - - /* get state of the user button */ - /* Perform the debouncing of buttons. The algorithm for debouncing - * adapted from the book "Embedded Systems Dictionary" by Jack Ganssle - * and Michael Barr, page 71. - */ - current = ~GPIOC->IDR; /* read Port C with the state of Button B1 */ - tmp = buttons.depressed; /* save the debounced depressed buttons */ - buttons.depressed |= (buttons.previous & current); /* set depressed */ - buttons.depressed &= (buttons.previous | current); /* clear released */ - buttons.previous = current; /* update the history */ - tmp ^= buttons.depressed; /* changed debounced depressed */ - if ((tmp & BTN_B1) != 0U) { /* debounced B1 state changed? */ - if ((buttons.depressed & BTN_B1) != 0U) { /* is B1 depressed? */ - static QEvt const pauseEvt = { PAUSE_SIG, 0U, 0U}; - QACTIVE_PUBLISH(&pauseEvt, &l_SysTick_Handler); - } - else { /* the button is released */ - static QEvt const serveEvt = { SERVE_SIG, 0U, 0U}; - QACTIVE_PUBLISH(&serveEvt, &l_SysTick_Handler); - } - } - - QK_ISR_EXIT(); /* inform QK about exiting an ISR */ -} -/*..........................................................................*/ -/* interrupt handler for testing preemptions in QXK */ -void EXTI0_1_IRQHandler(void) { - static QEvt const testEvt = { TEST_SIG, 0U, 0U }; - QK_ISR_ENTRY(); /* inform QK about entering an ISR */ - QACTIVE_POST(AO_Table, &testEvt, (void *)0); - QK_ISR_EXIT(); /* inform QK about exiting an ISR */ -} - - -/* BSP functions ===========================================================*/ -void BSP_init(void) { - /* NOTE: SystemInit() has been already called from the startup code - * but SystemCoreClock needs to be updated - */ - SystemCoreClockUpdate(); - - /* enable GPIOA clock port for the LED LD2 */ - RCC->IOPENR |= (1U << 0); - - /* configure LED (PA.5) pin as push-pull output, no pull-up, pull-down */ - GPIOA->MODER &= ~((3U << 2*5)); - GPIOA->MODER |= ((1U << 2*5)); - GPIOA->OTYPER &= ~((1U << 5)); - GPIOA->OSPEEDR &= ~((3U << 2*5)); - GPIOA->OSPEEDR |= ((1U << 2*5)); - GPIOA->PUPDR &= ~((3U << 2*5)); - - /* enable GPIOC clock port for the Button B1 */ - RCC->IOPENR |= (1U << 2); - - /* configure Button (PC.13) pins as input, no pull-up, pull-down */ - GPIOC->MODER &= ~(3U << 2*13); - GPIOC->OSPEEDR &= ~(3U << 2*13); - GPIOC->OSPEEDR |= (1U << 2*13); - GPIOC->PUPDR &= ~(3U << 2*13); - - BSP_randomSeed(1234U); /* seed the random number generator */ - - /* initialize the QS software tracing... */ - if (QS_INIT((void *)0) == 0U) { - Q_ERROR(); - } - QS_OBJ_DICTIONARY(&l_SysTick_Handler); - QS_USR_DICTIONARY(PHILO_STAT); - QS_USR_DICTIONARY(CONTEXT_SW); - - /* setup the QS filters... */ - QS_GLB_FILTER(QS_SM_RECORDS); - QS_GLB_FILTER(QS_UA_RECORDS); -} -/*..........................................................................*/ -void BSP_displayPhilStat(uint8_t n, char const *stat) { - if (stat[0] == 'h') { - GPIOA->BSRR |= LED_LD2; /* turn LED on */ - } - else { - GPIOA->BSRR |= (LED_LD2 << 16); /* turn LED off */ - } - - QS_BEGIN_ID(PHILO_STAT, AO_Philo[n]->prio) /* app-specific record */ - QS_U8(1, n); /* Philosopher number */ - QS_STR(stat); /* Philosopher status */ - QS_END() -} -/*..........................................................................*/ -void BSP_displayPaused(uint8_t paused) { - /* not enough LEDs to implement this feature */ - if (paused != (uint8_t)0) { - //GPIOA->BSRR |= (LED_LD2); /* turn LED[n] on */ - } - else { - //GPIOA->BSRR |= (LED_LD2 << 16); /* turn LED[n] off */ - } -} -/*..........................................................................*/ -uint32_t BSP_random(void) { /* a very cheap pseudo-random-number generator */ - /* "Super-Duper" Linear Congruential Generator (LCG) - * LCG(2^32, 3*7*11*13*23, 0, seed) - */ - l_rnd = l_rnd * (3U*7U*11U*13U*23U); - return l_rnd >> 8; -} -/*..........................................................................*/ -void BSP_randomSeed(uint32_t seed) { - l_rnd = seed; -} -/*..........................................................................*/ -void BSP_terminate(int16_t result) { - (void)result; -} -/*..........................................................................*/ -void BSP_wait4SW1(void) { - while ((GPIOC->IDR & BTN_B1) != 0U) { - GPIOA->BSRR |= (LED_LD2); /* turn LED2 on */ - GPIOA->BSRR |= (LED_LD2 << 16); /* turn LED2 off */ - } -} -/*..........................................................................*/ -void BSP_ledOn(void) { - //GPIOA->BSRR |= (LED_LD2); /* turn LED2 on */ -} -/*..........................................................................*/ -void BSP_ledOff(void) { - //GPIOA->BSRR |= (LED_LD2 << 16); /* turn LED2 off */ -} - -/* QF callbacks ============================================================*/ -void QF_onStartup(void) { - /* set up the SysTick timer to fire at BSP_TICKS_PER_SEC rate */ - SysTick_Config(SystemCoreClock / BSP_TICKS_PER_SEC); - - /* set priorities of ALL ISRs used in the system, see NOTE1 - * - * !!!!!!!!!!!!!!!!!!!!!!!!!!!! CAUTION !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - * Assign a priority to EVERY ISR explicitly by calling NVIC_SetPriority(). - * DO NOT LEAVE THE ISR PRIORITIES AT THE DEFAULT VALUE! - */ - NVIC_SetPriority(EXTI0_1_IRQn, QF_AWARE_ISR_CMSIS_PRI); - NVIC_SetPriority(SysTick_IRQn, QF_AWARE_ISR_CMSIS_PRI + 1U); - /* ... */ - - /* enable IRQs... */ - NVIC_EnableIRQ(EXTI0_1_IRQn); -} -/*..........................................................................*/ -void QF_onCleanup(void) { -} -/*..........................................................................*/ -#ifdef QF_ON_CONTEXT_SW -/* NOTE: the context-switch callback is called with interrupts DISABLED */ -void QK_onContextSw(QActive *prev, QActive *next) { - (void)prev; - if (next != (QActive *)0) { - //_impure_ptr = next->thread; /* switch to next TLS */ - } - QS_BEGIN_NOCRIT(CONTEXT_SW, 0U) /* no critical section! */ - QS_OBJ(prev); - QS_OBJ(next); - QS_END_NOCRIT() -} -#endif /* QF_ON_CONTEXT_SW */ -/*..........................................................................*/ -void QK_onIdle(void) { /* called with interrupts enabled */ - - /* toggle an LED on and then off (not enough LEDs, see NOTE2) */ - QF_INT_DISABLE(); - //GPIOA->BSRR |= (LED_LD2); /* turn LED[n] on */ - //GPIOA->BSRR |= (LED_LD2 << 16); /* turn LED[n] off */ - QF_INT_ENABLE(); - -#ifdef Q_SPY - if ((USART2->ISR & 0x0080U) != 0) { /* is TXE empty? */ - uint16_t b; - - QF_INT_DISABLE(); - b = QS_getByte(); - QF_INT_ENABLE(); - - if (b != QS_EOD) { /* not End-Of-Data? */ - USART2->TDR = (b & 0xFFU); /* put into the DR register */ - } - } -#elif defined NDEBUG - /* Put the CPU and peripherals to the low-power mode. - * you might need to customize the clock management for your application, - * see the datasheet for your particular Cortex-M3 MCU. - */ - /* !!!CAUTION!!! - * The WFI instruction stops the CPU clock, which unfortunately disables - * the JTAG port, so the ST-Link debugger can no longer connect to the - * board. For that reason, the call to __WFI() has to be used with CAUTION. - * - * NOTE: If you find your board "frozen" like this, strap BOOT0 to VDD and - * reset the board, then connect with ST-Link Utilities and erase the part. - * The trick with BOOT(0) is it gets the part to run the System Loader - * instead of your broken code. When done disconnect BOOT0, and start over. - */ - //__WFI(); /* Wait-For-Interrupt */ -#endif -} - -/*..........................................................................*/ -Q_NORETURN Q_onAssert(char const * const module, int_t const loc) { - /* - * NOTE: add here your application-specific error handling - */ - (void)module; - (void)loc; - QS_ASSERTION(module, loc, 10000U); /* report assertion to QS */ - -#ifndef NDEBUG - BSP_wait4SW1(); -#endif - NVIC_SystemReset(); -} -/*..........................................................................*/ -void *__stack_chk_guard = (void *)0xDEADBEEF; -__attribute__((noreturn)) void __stack_chk_fail(void); -__attribute__((noreturn)) void __stack_chk_fail(void) { - Q_onAssert("Stack ERROR", 0); - for (;;) {} -} - -/* QS callbacks ============================================================*/ -#ifdef Q_SPY -/*..........................................................................*/ -#define __DIV(__PCLK, __BAUD) (((__PCLK / 4) *25)/(__BAUD)) -#define __DIVMANT(__PCLK, __BAUD) (__DIV(__PCLK, __BAUD)/100) -#define __DIVFRAQ(__PCLK, __BAUD) \ - (((__DIV(__PCLK, __BAUD) - (__DIVMANT(__PCLK, __BAUD) * 100)) \ - * 16 + 50) / 100) -#define __USART_BRR(__PCLK, __BAUD) \ - ((__DIVMANT(__PCLK, __BAUD) << 4)|(__DIVFRAQ(__PCLK, __BAUD) & 0x0F)) - -/*..........................................................................*/ -uint8_t QS_onStartup(void const *arg) { - static uint8_t qsBuf[2*1024]; /* buffer for Quantum Spy */ - - (void)arg; /* avoid the "unused parameter" compiler warning */ - QS_initBuf(qsBuf, sizeof(qsBuf)); - - /* enable peripheral clock for USART2 */ - RCC->IOPENR |= ( 1ul << 0); /* Enable GPIOA clock */ - RCC->APB1ENR |= ( 1ul << 17); /* Enable USART#2 clock */ - - /* Configure PA3 to USART2_RX, PA2 to USART2_TX */ - GPIOA->AFR[0] &= ~((15ul << 4* 3) | (15ul << 4* 2) ); - GPIOA->AFR[0] |= (( 4ul << 4* 3) | ( 4ul << 4* 2) ); - GPIOA->MODER &= ~(( 3ul << 2* 3) | ( 3ul << 2* 2) ); - GPIOA->MODER |= (( 2ul << 2* 3) | ( 2ul << 2* 2) ); - - USART2->BRR = __USART_BRR(SystemCoreClock, 115200ul); /* baud rate */ - USART2->CR3 = 0x0000; /* no flow control */ - USART2->CR2 = 0x0000; /* 1 stop bit */ - USART2->CR1 = ((1ul << 2) | /* enable RX */ - (1ul << 3) | /* enable TX */ - (0ul << 12) | /* 8 data bits */ - (0ul << 28) | /* 8 data bits */ - (1ul << 0) ); /* enable USART */ - - QS_tickPeriod_ = SystemCoreClock / BSP_TICKS_PER_SEC; - QS_tickTime_ = QS_tickPeriod_; /* to start the timestamp at zero */ - - return (uint8_t)1; /* return success */ -} -/*..........................................................................*/ -void QS_onCleanup(void) { -} -/*..........................................................................*/ -QSTimeCtr QS_onGetTime(void) { /* NOTE: invoked with interrupts DISABLED */ - if ((SysTick->CTRL & 0x00010000) == 0) { /* COUNT no set? */ - return QS_tickTime_ - (QSTimeCtr)SysTick->VAL; - } - else { /* the rollover occured, but the SysTick_ISR did not run yet */ - return QS_tickTime_ + QS_tickPeriod_ - (QSTimeCtr)SysTick->VAL; - } -} -/*..........................................................................*/ -void QS_onFlush(void) { - uint16_t b; - - QF_INT_DISABLE(); - while ((b = QS_getByte()) != QS_EOD) { /* while not End-Of-Data... */ - QF_INT_ENABLE(); - while ((USART2->ISR & 0x0080U) == 0U) { /* while TXE not empty */ - } - USART2->TDR = (b & 0xFFU); /* put into the DR register */ - QF_INT_DISABLE(); - } - QF_INT_ENABLE(); -} - -#endif /* Q_SPY */ -/*--------------------------------------------------------------------------*/ - -/***************************************************************************** -* NOTE1: -* The QF_AWARE_ISR_CMSIS_PRI constant from the QF port specifies the highest -* ISR priority that is disabled by the QF framework. The value is suitable -* for the NVIC_SetPriority() CMSIS function. -* -* Only ISRs prioritized at or below the QF_AWARE_ISR_CMSIS_PRI level (i.e., -* with the numerical values of priorities equal or higher than -* QF_AWARE_ISR_CMSIS_PRI) are allowed to call any QF services. These ISRs -* are "QF-aware". -* -* Conversely, any ISRs prioritized above the QF_AWARE_ISR_CMSIS_PRI priority -* level (i.e., with the numerical values of priorities less than -* QF_AWARE_ISR_CMSIS_PRI) are never disabled and are not aware of the kernel. -* Such "QF-unaware" ISRs cannot call any QF services. The only mechanism -* by which a "QF-unaware" ISR can communicate with the QF framework is by -* triggering a "QF-aware" ISR, which can post/publish events. -* -* NOTE2: -* Usually, one of the LEDs is used to visualize the idle loop activity. -* However, the board has not enough LEDs (only one, actually), so this -* feature is disabled. -*/ diff --git a/examples/arm-cm/dpp_nucleo-l053r8/qk/iar/dpp-qk.ewd b/examples/arm-cm/dpp_nucleo-l053r8/qk/iar/dpp-qk.ewd index 473da05f..6a0e9ea2 100644 --- a/examples/arm-cm/dpp_nucleo-l053r8/qk/iar/dpp-qk.ewd +++ b/examples/arm-cm/dpp_nucleo-l053r8/qk/iar/dpp-qk.ewd @@ -11,7 +11,7 @@ C-SPY 2 - 28 + 32 1 1 - - + + + + + @@ -486,7 +498,7 @@ IJET_ID 2 - 8 + 9 1 1 + + + + + + + + + + + + + @@ -916,7 +980,7 @@ LMIFTDI_ID 2 - 2 + 3 1 1 + + + + + + + NULINK_ID + 2 + + 0 + 1 + 1 + + + @@ -974,7 +1072,7 @@ STLINK_ID 2 - 4 + 8 1 1 + + + + @@ -1185,7 +1300,7 @@ XDS100_ID 2 - 6 + 9 1 1 + + + + @@ -1362,6 +1493,18 @@ $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin 0 + + $TOOLKIT_DIR$\plugins\rtos\FreeRtos\FreeRtosArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin2.ENU.ewplugin + 0 + $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin 0 @@ -1371,11 +1514,15 @@ 0 - $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9.ewplugin 0 - $TOOLKIT_DIR$\plugins\rtos\TI-RTOS\tirtosplugin.ewplugin + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9BE.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin 0 @@ -1391,11 +1538,11 @@ 0 - $EW_DIR$\common\plugins\CodeCoverage\CodeCoverage.ENU.ewplugin - 1 + $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + 0 - $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + $EW_DIR$\common\plugins\TargetAccessServer\TargetAccessServer.ENU.ewplugin 0 @@ -1414,7 +1561,7 @@ C-SPY 2 - 28 + 32 1 0 - - + + + + + @@ -1889,7 +2048,7 @@ IJET_ID 2 - 8 + 9 1 0 + + + + + + + + + + + + + @@ -2319,7 +2530,7 @@ LMIFTDI_ID 2 - 2 + 3 1 0 + + + + + + + NULINK_ID + 2 + + 0 + 1 + 0 + + + @@ -2377,7 +2622,7 @@ STLINK_ID 2 - 4 + 8 1 0 + + + + @@ -2588,7 +2850,7 @@ XDS100_ID 2 - 6 + 9 1 0 + + + + @@ -2765,6 +3043,18 @@ $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin 0 + + $TOOLKIT_DIR$\plugins\rtos\FreeRtos\FreeRtosArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin2.ENU.ewplugin + 0 + $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin 0 @@ -2774,11 +3064,15 @@ 0 - $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9.ewplugin 0 - $TOOLKIT_DIR$\plugins\rtos\TI-RTOS\tirtosplugin.ewplugin + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9BE.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin 0 @@ -2794,11 +3088,11 @@ 0 - $EW_DIR$\common\plugins\CodeCoverage\CodeCoverage.ENU.ewplugin - 1 + $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + 0 - $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + $EW_DIR$\common\plugins\TargetAccessServer\TargetAccessServer.ENU.ewplugin 0 @@ -2817,7 +3111,7 @@ C-SPY 2 - 28 + 32 1 1 - - + + + + + @@ -3292,7 +3598,7 @@ IJET_ID 2 - 8 + 9 1 1 + + + + + + + + + + + + + @@ -3722,7 +4080,7 @@ LMIFTDI_ID 2 - 2 + 3 1 1 + + + + + + + NULINK_ID + 2 + + 0 + 1 + 1 + + + @@ -3780,7 +4172,7 @@ STLINK_ID 2 - 4 + 8 1 1 + + + + @@ -3991,7 +4400,7 @@ XDS100_ID 2 - 6 + 9 1 1 + + + + @@ -4168,6 +4593,18 @@ $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin 0 + + $TOOLKIT_DIR$\plugins\rtos\FreeRtos\FreeRtosArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin2.ENU.ewplugin + 0 + $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin 0 @@ -4177,11 +4614,15 @@ 0 - $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9.ewplugin 0 - $TOOLKIT_DIR$\plugins\rtos\TI-RTOS\tirtosplugin.ewplugin + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9BE.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin 0 @@ -4197,11 +4638,11 @@ 0 - $EW_DIR$\common\plugins\CodeCoverage\CodeCoverage.ENU.ewplugin - 1 + $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + 0 - $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + $EW_DIR$\common\plugins\TargetAccessServer\TargetAccessServer.ENU.ewplugin 0 diff --git a/examples/arm-cm/dpp_nucleo-l053r8/qk/iar/dpp-qk.ewp b/examples/arm-cm/dpp_nucleo-l053r8/qk/iar/dpp-qk.ewp index 4f9593d3..6648bce2 100644 --- a/examples/arm-cm/dpp_nucleo-l053r8/qk/iar/dpp-qk.ewp +++ b/examples/arm-cm/dpp_nucleo-l053r8/qk/iar/dpp-qk.ewp @@ -11,12 +11,12 @@ General 3 - 33 + 35 1 1 + + + @@ -672,7 +684,7 @@ ILINK 0 - 25 + 27 1 1 + + + + @@ -1063,12 +1091,12 @@ General 3 - 33 + 35 1 0 + + + @@ -1723,7 +1763,7 @@ ILINK 0 - 25 + 27 1 0 + + + + @@ -2114,12 +2170,12 @@ General 3 - 33 + 35 1 1 + + + @@ -2774,7 +2842,7 @@ ILINK 0 - 25 + 27 1 1 + + + + @@ -3167,14 +3251,11 @@ $PROJ_DIR$\..\..\dpp.h - $PROJ_DIR$\..\main.c + $PROJ_DIR$\..\..\main.c $PROJ_DIR$\..\..\philo.c - - $PROJ_DIR$\..\..\..\..\..\include\qstamp.c - $PROJ_DIR$\..\..\table.c @@ -3247,12 +3328,6 @@ QP_port - - $PROJ_DIR$\..\..\..\..\..\ports\arm-cm\qk\iar\qep_port.h - - - $PROJ_DIR$\..\..\..\..\..\ports\arm-cm\qk\iar\qf_port.h - $PROJ_DIR$\..\..\..\..\..\ports\arm-cm\qk\iar\qk_port.c @@ -3503,12 +3578,6 @@ - - $PROJ_DIR$\..\..\..\..\..\ports\arm-cm\qk\iar\qk_port.h - - - $PROJ_DIR$\..\..\..\..\..\ports\arm-cm\qk\iar\qs_port.h - QS @@ -3526,10 +3595,10 @@ $PROJ_DIR$\..\..\..\..\..\src\qs\qs_fp.c - $PROJ_DIR$\..\..\..\..\..\src\qs_pkg.h + $PROJ_DIR$\..\..\..\..\..\src\qs\qs_rx.c - $PROJ_DIR$\..\..\..\..\..\src\qs\qs_rx.c + $PROJ_DIR$\..\..\..\..\..\src\qs\qstamp.c diff --git a/examples/arm-cm/dpp_nucleo-l053r8/qk/main.c b/examples/arm-cm/dpp_nucleo-l053r8/qk/main.c deleted file mode 100644 index c723bd47..00000000 --- a/examples/arm-cm/dpp_nucleo-l053r8/qk/main.c +++ /dev/null @@ -1,87 +0,0 @@ -/***************************************************************************** -* Product: DPP example -* Last updated for version 7.1.1 -* Last updated on 2022-09-22 -* -* Q u a n t u m L e a P s -* ------------------------ -* Modern Embedded Software -* -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* -* -*****************************************************************************/ -#include "qpc.h" -#include "dpp.h" -#include "bsp.h" - -Q_DEFINE_THIS_FILE - -/*..........................................................................*/ -int main() { - static QEvt const *tableQueueSto[N_PHILO]; - static QEvt const *philoQueueSto[N_PHILO][N_PHILO]; - static QSubscrList subscrSto[MAX_PUB_SIG]; - static QF_MPOOL_EL(TableEvt) smlPoolSto[2*N_PHILO]; /* small pool */ - uint8_t n; - - Philo_ctor(); /* instantiate all Philosopher active objects */ - Table_ctor(); /* instantiate the Table active object */ - - QF_init(); /* initialize the framework and the underlying RT kernel */ - BSP_init(); /* initialize the Board Support Package */ - - /* object dictionaries... */ - QS_OBJ_DICTIONARY(AO_Table); - QS_OBJ_DICTIONARY(AO_Philo[0]); - QS_OBJ_DICTIONARY(AO_Philo[1]); - QS_OBJ_DICTIONARY(AO_Philo[2]); - QS_OBJ_DICTIONARY(AO_Philo[3]); - QS_OBJ_DICTIONARY(AO_Philo[4]); - - /* initialize publish-subscribe... */ - QF_psInit(subscrSto, Q_DIM(subscrSto)); - - /* initialize event pools... */ - QF_poolInit(smlPoolSto, sizeof(smlPoolSto), sizeof(smlPoolSto[0])); - - /* start the active objects... */ - for (n = 0U; n < N_PHILO; ++n) { - QACTIVE_START(AO_Philo[n], /* AO to start */ - Q_PRIO(n + 1U, N_PHILO), /* QF-prio/pre-thre. */ - philoQueueSto[n], /* event queue storage */ - Q_DIM(philoQueueSto[n]), /* queue length [events] */ - (void *)0, /* stack storage (not used) */ - 0U, /* size of the stack [bytes] */ - (void *)0); /* initialization param */ - } - QACTIVE_START(AO_Table, /* AO to start */ - N_PHILO + 1U, /* QF-prio/pre-thre. */ - tableQueueSto, /* event queue storage */ - Q_DIM(tableQueueSto), /* queue length [events] */ - (void *)0, /* stack storage (not used) */ - 0U, /* size of the stack [bytes] */ - (void *)0); /* initialization param */ - - return QF_run(); /* run the QF application */ -} diff --git a/examples/arm-cm/dpp_nucleo-l053r8/qv/armclang/dpp-qv.sct b/examples/arm-cm/dpp_nucleo-l053r8/qv/armclang/dpp-qv.sct new file mode 100644 index 00000000..04d0dc68 --- /dev/null +++ b/examples/arm-cm/dpp_nucleo-l053r8/qv/armclang/dpp-qv.sct @@ -0,0 +1,20 @@ +; ************************************************************* +; *** Scatter-Loading Description File generated by uVision *** +; +; Adapted by Quantum Leaps: +; moved STACK as the first section in RW_IRAM1 +; ************************************************************* + +LR_IROM1 0x08000000 0x00010000 { ; load region size_region + ER_IROM1 0x08000000 0x00010000 { ; load address = execution address + *.o (RESET, +First) + *(InRoot$$Sections) + .ANY (+RO) + .ANY (+XO) + } + RW_IRAM1 0x20000000 0x00002000 { ; RW data + *.o (STACK, +First) + .ANY (+RW +ZI) + } +} + diff --git a/examples/arm-cm/dpp_nucleo-l053r8/qv/armclang/dpp-qv.uvoptx b/examples/arm-cm/dpp_nucleo-l053r8/qv/armclang/dpp-qv.uvoptx index d3e1a4aa..0f56540d 100644 --- a/examples/arm-cm/dpp_nucleo-l053r8/qv/armclang/dpp-qv.uvoptx +++ b/examples/arm-cm/dpp_nucleo-l053r8/qv/armclang/dpp-qv.uvoptx @@ -152,9 +152,9 @@ 0 0 - 427 + 425 1 -
134224692
+
134224834
0 0 0 @@ -163,7 +163,7 @@ 1 ..\bsp.c - \\dpp_qv\../bsp.c\427 + \\dpp_qv\../bsp.c\425
@@ -512,7 +512,7 @@ 1 0 0 - 5 + 6 @@ -699,19 +699,7 @@ 0 0 0 - ..\..\..\..\..\include\qstamp.c - qstamp.c - 0 - 0 - - - 1 - 7 - 1 - 0 - 0 - 0 - ..\main.c + ..\..\main.c main.c 0 0 @@ -726,7 +714,7 @@ 0 2 - 8 + 7 5 0 0 @@ -738,7 +726,7 @@ 2 - 9 + 8 5 0 0 @@ -750,7 +738,7 @@ 2 - 10 + 9 1 0 0 @@ -762,7 +750,7 @@ 2 - 11 + 10 5 0 0 @@ -774,7 +762,7 @@ 2 - 12 + 11 2 0 0 @@ -794,7 +782,7 @@ 0 3 - 13 + 12 1 0 0 @@ -806,7 +794,7 @@ 3 - 14 + 13 1 0 0 @@ -818,7 +806,7 @@ 3 - 15 + 14 1 0 0 @@ -830,7 +818,7 @@ 3 - 16 + 15 1 0 0 @@ -842,7 +830,7 @@ 3 - 17 + 16 1 0 0 @@ -854,7 +842,7 @@ 3 - 18 + 17 1 0 0 @@ -866,7 +854,7 @@ 3 - 19 + 18 1 0 0 @@ -878,7 +866,7 @@ 3 - 20 + 19 5 0 0 @@ -890,7 +878,7 @@ 3 - 21 + 20 1 0 0 @@ -902,7 +890,7 @@ 3 - 22 + 21 1 0 0 @@ -914,7 +902,7 @@ 3 - 23 + 22 1 0 0 @@ -926,7 +914,7 @@ 3 - 24 + 23 1 0 0 @@ -938,7 +926,7 @@ 3 - 25 + 24 1 0 0 @@ -950,7 +938,7 @@ 3 - 26 + 25 1 0 0 @@ -970,31 +958,7 @@ 0 4 - 27 - 5 - 0 - 0 - 0 - ..\..\..\..\..\ports\arm-cm\qv\armclang\qep_port.h - qep_port.h - 0 - 0 - - - 4 - 28 - 5 - 0 - 0 - 0 - ..\..\..\..\..\ports\arm-cm\qv\armclang\qf_port.h - qf_port.h - 0 - 0 - - - 4 - 29 + 26 5 0 0 @@ -1006,7 +970,7 @@ 4 - 30 + 27 1 0 0 @@ -1016,18 +980,6 @@ 0 0 - - 4 - 31 - 5 - 0 - 0 - 0 - ..\..\..\..\..\ports\arm-cm\qv\armclang\qv_port.h - qv_port.h - 0 - 0 - @@ -1038,7 +990,7 @@ 0 5 - 32 + 28 1 0 0 @@ -1050,7 +1002,7 @@ 5 - 33 + 29 1 0 0 @@ -1062,7 +1014,7 @@ 5 - 34 + 30 1 0 0 @@ -1074,19 +1026,7 @@ 5 - 35 - 5 - 0 - 0 - 0 - ..\..\..\..\..\src\qs_pkg.h - qs_pkg.h - 0 - 0 - - - 5 - 36 + 31 1 0 0 @@ -1096,6 +1036,18 @@ 0 0 + + 5 + 32 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qs\qstamp.c + qstamp.c + 0 + 0 + diff --git a/examples/arm-cm/dpp_nucleo-l053r8/qv/armclang/dpp-qv.uvprojx b/examples/arm-cm/dpp_nucleo-l053r8/qv/armclang/dpp-qv.uvprojx index 858419fe..378b3be9 100644 --- a/examples/arm-cm/dpp_nucleo-l053r8/qv/armclang/dpp-qv.uvprojx +++ b/examples/arm-cm/dpp_nucleo-l053r8/qv/armclang/dpp-qv.uvprojx @@ -408,15 +408,10 @@ 1 ..\..\table.c - - qstamp.c - 1 - ..\..\..\..\..\include\qstamp.c - main.c 1 - ..\main.c + ..\..\main.c @@ -528,16 +523,6 @@ QP_port - - qep_port.h - 5 - ..\..\..\..\..\ports\arm-cm\qv\armclang\qep_port.h - - - qf_port.h - 5 - ..\..\..\..\..\ports\arm-cm\qv\armclang\qf_port.h - qs_port.h 5 @@ -548,11 +533,6 @@ 1 ..\..\..\..\..\ports\arm-cm\qv\armclang\qv_port.c - - qv_port.h - 5 - ..\..\..\..\..\ports\arm-cm\qv\armclang\qv_port.h - @@ -642,16 +622,16 @@ 1 ..\..\..\..\..\src\qs\qs_fp.c - - qs_pkg.h - 5 - ..\..\..\..\..\src\qs_pkg.h - qs_rx.c 1 ..\..\..\..\..\src\qs\qs_rx.c + + qstamp.c + 1 + ..\..\..\..\..\src\qs\qstamp.c + @@ -1058,15 +1038,10 @@ 1 ..\..\table.c - - qstamp.c - 1 - ..\..\..\..\..\include\qstamp.c - main.c 1 - ..\main.c + ..\..\main.c @@ -1178,16 +1153,6 @@ QP_port - - qep_port.h - 5 - ..\..\..\..\..\ports\arm-cm\qv\armclang\qep_port.h - - - qf_port.h - 5 - ..\..\..\..\..\ports\arm-cm\qv\armclang\qf_port.h - qs_port.h 5 @@ -1198,11 +1163,6 @@ 1 ..\..\..\..\..\ports\arm-cm\qv\armclang\qv_port.c - - qv_port.h - 5 - ..\..\..\..\..\ports\arm-cm\qv\armclang\qv_port.h - @@ -1292,16 +1252,16 @@ 1 ..\..\..\..\..\src\qs\qs_fp.c - - qs_pkg.h - 5 - ..\..\..\..\..\src\qs_pkg.h - qs_rx.c 1 ..\..\..\..\..\src\qs\qs_rx.c + + qstamp.c + 1 + ..\..\..\..\..\src\qs\qstamp.c + @@ -1310,7 +1270,7 @@ dpp-spy 0x4 ARM-ADS - 6130001::V6.13.1::.\ARMCLANG + 6160000::V6.16::ARMCLANG 1 @@ -1637,7 +1597,7 @@ 0 - Q_SPY + Q_SPY,QF_ON_CONTEXT_SW ..\..;..\..\..\..\..\include;..\..\..\..\..\ports\arm-cm\qv\armclang;..\..\..\..\..\3rd_party\CMSIS\Include;..\..\..\..\..\3rd_party\nucleo-l053r8 @@ -1708,15 +1668,10 @@ 1 ..\..\table.c - - qstamp.c - 1 - ..\..\..\..\..\include\qstamp.c - main.c 1 - ..\main.c + ..\..\main.c @@ -1828,16 +1783,6 @@ QP_port - - qep_port.h - 5 - ..\..\..\..\..\ports\arm-cm\qv\armclang\qep_port.h - - - qf_port.h - 5 - ..\..\..\..\..\ports\arm-cm\qv\armclang\qf_port.h - qs_port.h 5 @@ -1848,11 +1793,6 @@ 1 ..\..\..\..\..\ports\arm-cm\qv\armclang\qv_port.c - - qv_port.h - 5 - ..\..\..\..\..\ports\arm-cm\qv\armclang\qv_port.h - @@ -1873,16 +1813,16 @@ 1 ..\..\..\..\..\src\qs\qs_fp.c - - qs_pkg.h - 5 - ..\..\..\..\..\src\qs_pkg.h - qs_rx.c 1 ..\..\..\..\..\src\qs\qs_rx.c + + qstamp.c + 1 + ..\..\..\..\..\src\qs\qstamp.c + diff --git a/examples/arm-cm/dpp_nucleo-l053r8/qv/bsp.c b/examples/arm-cm/dpp_nucleo-l053r8/qv/bsp.c index b0077830..dd9ff6b6 100644 --- a/examples/arm-cm/dpp_nucleo-l053r8/qv/bsp.c +++ b/examples/arm-cm/dpp_nucleo-l053r8/qv/bsp.c @@ -1,446 +1,404 @@ -/*============================================================================ -* Product: DPP example, NUCLEO-L053R8 board, cooperative QV kernel -* Last updated for version 7.2.0 -* Last updated on 2022-12-13 -* -* Q u a n t u m L e a P s -* ------------------------ -* Modern Embedded Software -* -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* -* -============================================================================*/ -#include "qpc.h" -#include "dpp.h" -#include "bsp.h" +//============================================================================ +// Product: DPP example, NUCLEO-L053R8 board, QV kernel +// Last updated for version 7.3.0 +// Last updated on 2023-08-23 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. +// +// This program is open source software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Alternatively, this program may be distributed and modified under the +// terms of Quantum Leaps commercial licenses, which expressly supersede +// the GNU General Public License and are specifically designed for +// licensees interested in retaining the proprietary status of their code. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Contact information: +// +// +//============================================================================ +#include "qpc.h" // QP/C real-time embedded framework +#include "dpp.h" // DPP Application interface +#include "bsp.h" // Board Support Package -#include "stm32l0xx.h" /* CMSIS-compliant header file for the MCU used */ -/* add other drivers if necessary... */ +#include "stm32l0xx.h" // CMSIS-compliant header file for the MCU used +// add other drivers if necessary... Q_DEFINE_THIS_FILE -/* Local-scope defines -----------------------------------------------------*/ -/* LED pins available on the board (just one user LED LD2--Green on PA.5) */ -#define LED_LD2 (1U << 5) +// Local-scope objects ----------------------------------------------------- +// LED pins available on the board (just one user LED LD2--Green on PA.5) +#define LD2_PIN 5U -/* Button pins available on the board (just one user Button B1 on PC.13) */ -#define BTN_B1 (1U << 13) +// Button pins available on the board (just one user Button B1 on PC.13) +#define B1_PIN 13U -static uint32_t l_rnd; /* random seed */ +static uint32_t l_rndSeed; #ifdef Q_SPY - QSTimeCtr QS_tickTime_; - QSTimeCtr QS_tickPeriod_; - - /* QSpy source IDs */ + // QSpy source IDs static QSpyId const l_SysTick_Handler = { 0U }; - enum AppRecords { /* application-specific trace records */ + static QSTimeCtr QS_tickTime_; + static QSTimeCtr QS_tickPeriod_; + + enum AppRecords { // application-specific trace records PHILO_STAT = QS_USER, + PAUSED_STAT, CONTEXT_SW, }; #endif -/* ISRs used in the application ==========================================*/ -void SysTick_Handler(void); -void EXTI0_1_IRQHandler(void); -void USART2_IRQHandler(void); +//============================================================================ +// Error handler and ISRs... -/*..........................................................................*/ -void SysTick_Handler(void) { /* system clock tick ISR */ - /* state of the button debouncing, see below */ - static struct ButtonsDebouncing { +Q_NORETURN Q_onError(char const * const module, int_t const id) { + // NOTE: this implementation of the error handler is intended only + // for debugging and MUST be changed for deployment of the application + // (assuming that you ship your production code with assertions enabled). + Q_UNUSED_PAR(module); + Q_UNUSED_PAR(id); + QS_ASSERTION(module, id, 10000U); // report assertion to QS + +#ifndef NDEBUG + // light up the user LED + GPIOA->BSRR = (1U << LD2_PIN); + for (;;) { // for debugging, hang on in an endless loop... + } +#else + NVIC_SystemReset(); + for (;;) { // explicitly "no-return" + } +#endif +} +//............................................................................ +void assert_failed(char const * const module, int_t const id); // prototype +void assert_failed(char const * const module, int_t const id) { + Q_onError(module, id); +} + +// ISRs used in the application ========================================== + +void SysTick_Handler(void); // prototype +void SysTick_Handler(void) { + + QTIMEEVT_TICK_X(0U, &l_SysTick_Handler); // time events at rate 0 + + // Perform the debouncing of buttons. The algorithm for debouncing + // adapted from the book "Embedded Systems Dictionary" by Jack Ganssle + // and Michael Barr, page 71. + static struct { uint32_t depressed; uint32_t previous; } buttons = { 0U, 0U }; - uint32_t current; - uint32_t tmp; -#ifdef Q_SPY - { - tmp = SysTick->CTRL; /* clear CTRL_COUNTFLAG */ - QS_tickTime_ += QS_tickPeriod_; /* account for the clock rollover */ - } -#endif + uint32_t current = ~GPIOC->IDR; // read Port C with state of Button B1 + uint32_t tmp = buttons.depressed; // save the depressed buttons + buttons.depressed |= (buttons.previous & current); // set depressed + buttons.depressed &= (buttons.previous | current); // clear released + buttons.previous = current; // update the history + tmp ^= buttons.depressed; // changed debounced depressed + current = buttons.depressed; - QTIMEEVT_TICK_X(0U, &l_SysTick_Handler); /* process time events for rate 0 */ - //QACTIVE_POST(the_Ticker0, 0, &l_SysTick_Handler); /* post to Ticker0 */ - - /* get state of the user button */ - /* Perform the debouncing of buttons. The algorithm for debouncing - * adapted from the book "Embedded Systems Dictionary" by Jack Ganssle - * and Michael Barr, page 71. - */ - current = ~GPIOC->IDR; /* read Port C with the state of Button B1 */ - tmp = buttons.depressed; /* save the debounced depressed buttons */ - buttons.depressed |= (buttons.previous & current); /* set depressed */ - buttons.depressed &= (buttons.previous | current); /* clear released */ - buttons.previous = current; /* update the history */ - tmp ^= buttons.depressed; /* changed debounced depressed */ - if ((tmp & BTN_B1) != 0U) { /* debounced B1 state changed? */ - if ((buttons.depressed & BTN_B1) != 0U) { /* is B1 depressed? */ - static QEvt const pauseEvt = { PAUSE_SIG, 0U, 0U}; + if ((tmp & (1U << B1_PIN)) != 0U) { // debounced B1 state changed? + if ((current & (1U << B1_PIN)) != 0U) { // is B1 depressed? + static QEvt const pauseEvt = QEVT_INITIALIZER(PAUSE_SIG); QACTIVE_PUBLISH(&pauseEvt, &l_SysTick_Handler); } - else { /* the button is released */ - static QEvt const serveEvt = { SERVE_SIG, 0U, 0U}; + else { // the button is released + static QEvt const serveEvt = QEVT_INITIALIZER(SERVE_SIG); QACTIVE_PUBLISH(&serveEvt, &l_SysTick_Handler); } } - QV_ARM_ERRATUM_838869(); -} -/*..........................................................................*/ -/* interrupt handler for testing preemptions in QV */ -void EXTI0_1_IRQHandler(void) { - static QEvt const testEvt = { TEST_SIG, 0U, 0U }; - QACTIVE_POST(AO_Table, &testEvt, (void *)0); - QV_ARM_ERRATUM_838869(); -} -/*..........................................................................*/ + #ifdef Q_SPY -void USART2_IRQHandler(void) { /* used in QS-RX (kernel UNAWARE interrutp) */ - /* is RX register NOT empty? */ - if ((USART2->ISR & (1U << 5)) != 0) { + tmp = SysTick->CTRL; // clear CTRL_COUNTFLAG + QS_tickTime_ += QS_tickPeriod_; // account for the clock rollover +#endif + + QV_ARM_ERRATUM_838869(); +} +//............................................................................ +// interrupt handler for testing preemptions in QV +void EXTI0_1_IRQHandler(void); // prototype +void EXTI0_1_IRQHandler(void) { + static QEvt const testEvt = QEVT_INITIALIZER(TEST_SIG); + QACTIVE_POST(AO_Table, &testEvt, (void *)0); + + QV_ARM_ERRATUM_838869(); +} + +//............................................................................ +#ifdef Q_SPY +// ISR for receiving bytes from the QSPY Back-End +// NOTE: This ISR is "QF-unaware" meaning that it does not interact with +// the QF/QV and is not disabled. Such ISRs cannot post or publish events. + +void USART2_IRQHandler(void); // prototype +void USART2_IRQHandler(void) { // used in QS-RX (kernel UNAWARE interrutp) + // is RX register NOT empty? + if ((USART2->ISR & (1U << 5U)) != 0U) { uint32_t b = USART2->RDR; QS_RX_PUT(b); } + QV_ARM_ERRATUM_838869(); } -#endif +#endif // Q_SPY -/* BSP functions ===========================================================*/ -/*..........................................................................*/ -/* MPU setup for STM32L053R8 MCU */ -static void STM32L053R8_MPU_setup(void) { - /* The following MPU configuration contains the general STM32 memory model - * as described in the ST AppNote AN4838 "Managing memory protection unit - * in STM32 MCUs", Figure 2. Cortex-M0+/M3/M4/M7 processor memory map. - * - * Please note that the actual STM32 MCUs provide much less Flash and SRAM - * than the maximums configured here. This means that actual MCUs have - * unmapped memory regions (e.g., beyond the actual SRAM). Attempts to - * access these regions causes the HardFault exception, which is the - * desired behavior. - */ - static struct { - uint32_t rbar; - uint32_t rasr; - } const mpu_setup[] = { - - { /* region #0: Flash: base=0x0000'0000, size=512M=2^(28+1) */ - 0x00000000U /* base address */ - | MPU_RBAR_VALID_Msk /* valid region */ - | (MPU_RBAR_REGION_Msk & 0U), /* region #0 */ - (28U << MPU_RASR_SIZE_Pos) /* 2^(18+1) region */ - | (0x6U << MPU_RASR_AP_Pos) /* PA:ro/UA:ro */ - | (1U << MPU_RASR_C_Pos) /* C=1 */ - | MPU_RASR_ENABLE_Msk /* region enable */ - }, - - { /* region #1: SRAM: base=0x2000'0000, size=512M=2^(28+1) */ - 0x20000000U /* base address */ - | MPU_RBAR_VALID_Msk /* valid region */ - | (MPU_RBAR_REGION_Msk & 1U), /* region #1 */ - (28U << MPU_RASR_SIZE_Pos) /* 2^(28+1) region */ - | (0x3U << MPU_RASR_AP_Pos) /* PA:rw/UA:rw */ - | (1U << MPU_RASR_XN_Pos) /* XN=1 */ - | (1U << MPU_RASR_S_Pos) /* S=1 */ - | (1U << MPU_RASR_C_Pos) /* C=1 */ - | MPU_RASR_ENABLE_Msk /* region enable */ - }, - - /* region #3: (not configured) */ - { MPU_RBAR_VALID_Msk | (MPU_RBAR_REGION_Msk & 2U), 0U }, - - { /* region #3: Peripherals: base=0x4000'0000, size=512M=2^(28+1) */ - 0x40000000U /* base address */ - | MPU_RBAR_VALID_Msk /* valid region */ - | (MPU_RBAR_REGION_Msk & 3U), /* region #3 */ - (28U << MPU_RASR_SIZE_Pos) /* 2^(28+1) region */ - | (0x3U << MPU_RASR_AP_Pos) /* PA:rw/UA:rw */ - | (1U << MPU_RASR_XN_Pos) /* XN=1 */ - | (1U << MPU_RASR_S_Pos) /* S=1 */ - | (1U << MPU_RASR_B_Pos) /* B=1 */ - | MPU_RASR_ENABLE_Msk /* region enable */ - }, - - { /* region #4: Priv. Periph: base=0xE000'0000, size=512M=2^(28+1) */ - 0xE0000000U /* base address */ - | MPU_RBAR_VALID_Msk /* valid region */ - | (MPU_RBAR_REGION_Msk & 4U), /* region #4 */ - (28U << MPU_RASR_SIZE_Pos) /* 2^(28+1) region */ - | (0x3U << MPU_RASR_AP_Pos) /* PA:rw/UA:rw */ - | (1U << MPU_RASR_XN_Pos) /* XN=1 */ - | (1U << MPU_RASR_S_Pos) /* S=1 */ - | (1U << MPU_RASR_B_Pos) /* B=1 */ - | MPU_RASR_ENABLE_Msk /* region enable */ - }, - - { /* region #5: Ext RAM: base=0x6000'0000, size=1G=2^(29+1) */ - 0x60000000U /* base address */ - | MPU_RBAR_VALID_Msk /* valid region */ - | (MPU_RBAR_REGION_Msk & 5U), /* region #5 */ - (29U << MPU_RASR_SIZE_Pos) /* 2^(28+1) region */ - | (0x3U << MPU_RASR_AP_Pos) /* PA:rw/UA:rw */ - | (1U << MPU_RASR_XN_Pos) /* XN=1 */ - | (1U << MPU_RASR_S_Pos) /* S=1 */ - | (1U << MPU_RASR_B_Pos) /* B=1 */ - | MPU_RASR_ENABLE_Msk /* region enable */ - }, - - { /* region #6: Ext Dev: base=0xA000'0000, size=1G=2^(29+1) */ - 0xA0000000U /* base address */ - | MPU_RBAR_VALID_Msk /* valid region */ - | (MPU_RBAR_REGION_Msk & 6U), /* region #6 */ - (29U << MPU_RASR_SIZE_Pos) /* 2^(28+1) region */ - | (0x3U << MPU_RASR_AP_Pos) /* PA:rw/UA:rw */ - | (1U << MPU_RASR_XN_Pos) /* XN=1 */ - | (1U << MPU_RASR_S_Pos) /* S=1 */ - | (1U << MPU_RASR_B_Pos) /* B=1 */ - | MPU_RASR_ENABLE_Msk /* region enable */ - }, - - { /* region #7: NULL-pointer: base=0x000'0000, size=128M=2^(26+1) */ - /* NOTE: this region extends to 0x080'0000, which is where - * the ROM is re-mapped by STM32 - */ - 0x00000000U /* base address */ - | MPU_RBAR_VALID_Msk /* valid region */ - | (MPU_RBAR_REGION_Msk & 7U), /* region #7 */ - (26U << MPU_RASR_SIZE_Pos) /* 2^(26+1)=128M region */ - | (0x0U << MPU_RASR_AP_Pos) /* PA:na/UA:na */ - | (1U << MPU_RASR_XN_Pos) /* XN=1 */ - | MPU_RASR_ENABLE_Msk /* region enable */ - }, - - }; - - __DSB(); - MPU->CTRL = 0U; /* disable the MPU */ - for (uint_fast8_t n = 0U; n < Q_DIM(mpu_setup); ++n) { - MPU->RBAR = mpu_setup[n].rbar; - MPU->RASR = mpu_setup[n].rasr; - } - MPU->CTRL = MPU_CTRL_PRIVDEFENA_Msk /* enable background region */ - | MPU_CTRL_ENABLE_Msk; /* enable the MPU */ - __ISB(); - __DSB(); -} -/*..........................................................................*/ -void BSP_init(void) { - /* setup the MPU... */ - STM32L053R8_MPU_setup(); - - /* NOTE: SystemInit() has been already called from the startup code - * but SystemCoreClock needs to be updated - */ - SystemCoreClockUpdate(); - - /* enable GPIOA clock port for the LED LD2 */ - RCC->IOPENR |= (1U << 0); - - /* configure LED (PA.5) pin as push-pull output, no pull-up, pull-down */ - GPIOA->MODER &= ~((3U << 2*5)); - GPIOA->MODER |= ((1U << 2*5)); - GPIOA->OTYPER &= ~((1U << 5)); - GPIOA->OSPEEDR &= ~((3U << 2*5)); - GPIOA->OSPEEDR |= ((1U << 2*5)); - GPIOA->PUPDR &= ~((3U << 2*5)); - - /* enable GPIOC clock port for the Button B1 */ - RCC->IOPENR |= (1U << 2); - - /* configure Button (PC.13) pins as input, no pull-up, pull-down */ - GPIOC->MODER &= ~(3U << 2*13); - GPIOC->OSPEEDR &= ~(3U << 2*13); - GPIOC->OSPEEDR |= (1U << 2*13); - GPIOC->PUPDR &= ~(3U << 2*13); - - BSP_randomSeed(1234U); /* seed the random number generator */ - - /* initialize the QS software tracing... */ - if (QS_INIT((void *)0) == 0U) { - Q_ERROR(); - } - QS_OBJ_DICTIONARY(&l_SysTick_Handler); - QS_USR_DICTIONARY(PHILO_STAT); - QS_USR_DICTIONARY(CONTEXT_SW); - - /* setup the QS filters... */ - QS_GLB_FILTER(QS_ALL_RECORDS); /* all records */ - QS_GLB_FILTER(-QS_QF_TICK); /* exclude the clock tick */ -} -/*..........................................................................*/ -void BSP_displayPhilStat(uint8_t n, char const *stat) { - if (stat[0] == 'h') { - GPIOA->BSRR |= LED_LD2; /* turn LED on */ - } - else { - GPIOA->BSRR |= (LED_LD2 << 16); /* turn LED off */ - } - - QS_BEGIN_ID(PHILO_STAT, AO_Philo[n]->prio) /* app-specific record */ - QS_U8(1, n); /* Philosopher number */ - QS_STR(stat); /* Philosopher status */ - QS_END() -} -/*..........................................................................*/ -void BSP_displayPaused(uint8_t paused) { - /* not enough LEDs to implement this feature */ - if (paused != 0U) { - //GPIOA->BSRR |= (LED_LD2); /* turn LED[n] on */ - } - else { - //GPIOA->BSRR |= (LED_LD2 << 16); /* turn LED[n] off */ - } -} -/*..........................................................................*/ -uint32_t BSP_random(void) { /* a very cheap pseudo-random-number generator */ - /* "Super-Duper" Linear Congruential Generator (LCG) - * LCG(2^32, 3*7*11*13*23, 0, seed) - */ - l_rnd = l_rnd * (3U*7U*11U*13U*23U); - return l_rnd >> 8; -} -/*..........................................................................*/ -void BSP_randomSeed(uint32_t seed) { - l_rnd = seed; -} -/*..........................................................................*/ -void BSP_terminate(int16_t result) { - (void)result; -} -/*..........................................................................*/ -void BSP_wait4SW1(void) { - while ((GPIOC->IDR & BTN_B1) != 0U) { - GPIOA->BSRR |= (LED_LD2); /* turn LED2 on */ - GPIOA->BSRR |= (LED_LD2 << 16); /* turn LED2 off */ - } -} -/*..........................................................................*/ -void BSP_ledOn(void) { - //GPIOA->BSRR |= (LED_LD2); /* turn LED2 on */ -} -/*..........................................................................*/ -void BSP_ledOff(void) { - //GPIOA->BSRR |= (LED_LD2 << 16); /* turn LED2 off */ -} - -/* QF callbacks ============================================================*/ -void QF_onStartup(void) { - /* set up the SysTick timer to fire at BSP_TICKS_PER_SEC rate */ - SysTick_Config(SystemCoreClock / BSP_TICKS_PER_SEC); - - /* set priorities of ALL ISRs used in the system */ - NVIC_SetPriority(USART2_IRQn, 0); - NVIC_SetPriority(SysTick_IRQn, QF_AWARE_ISR_CMSIS_PRI + 0U); - NVIC_SetPriority(EXTI0_1_IRQn, QF_AWARE_ISR_CMSIS_PRI + 1U); - /* ... */ - - /* enable IRQs... */ - NVIC_EnableIRQ(EXTI0_1_IRQn); -#ifdef Q_SPY - NVIC_EnableIRQ(USART2_IRQn); /* UART2 interrupt used for QS-RX */ -#endif -} -/*..........................................................................*/ -void QF_onCleanup(void) { -} -/*..........................................................................*/ +//............................................................................ #ifdef QF_ON_CONTEXT_SW -/* NOTE: the context-switch callback is called with interrupts DISABLED */ +// NOTE: the context-switch callback is called with interrupts DISABLED void QF_onContextSw(QActive *prev, QActive *next) { - QS_BEGIN_NOCRIT(CONTEXT_SW, 0U) /* no critical section! */ + QS_BEGIN_INCRIT(CONTEXT_SW, 0U) // in critical section! QS_OBJ(prev); QS_OBJ(next); - QS_END_NOCRIT() + QS_END_INCRIT() } -#endif /* QF_ON_CONTEXT_SW */ -/*..........................................................................*/ -void QV_onIdle(void) { /* called with interrupts disabled, see NOTE01 */ +#endif // QF_ON_CONTEXT_SW - /* toggle an LED on and then off (not enough LEDs, see NOTE02) */ - //GPIOA->BSRR |= (LED_LD2); /* turn LED[n] on */ - //GPIOA->BSRR |= (LED_LD2 << 16); /* turn LED[n] off */ +//============================================================================ +// BSP functions... + +void BSP_init(void) { + // Configure the MPU to prevent NULL-pointer dereferencing ... + MPU->RBAR = 0x0U // base address (NULL) + | MPU_RBAR_VALID_Msk // valid region + | (MPU_RBAR_REGION_Msk & 7U); // region #7 + MPU->RASR = (7U << MPU_RASR_SIZE_Pos) // 2^(7+1) region + | (0x0U << MPU_RASR_AP_Pos) // no-access region + | MPU_RASR_ENABLE_Msk; // region enable + MPU->CTRL = MPU_CTRL_PRIVDEFENA_Msk // enable background region + | MPU_CTRL_ENABLE_Msk; // enable the MPU + __ISB(); + __DSB(); + + // NOTE: SystemInit() has been already called from the startup code + // but SystemCoreClock needs to be updated + SystemCoreClockUpdate(); + + // enable GPIOA clock port for the LED LD2 + RCC->IOPENR |= (1U << 0U); + + // configure LED (PA.5) pin as push-pull output, no pull-up, pull-down + GPIOA->MODER &= ~((3U << 2U*LD2_PIN)); + GPIOA->MODER |= ((1U << 2U*LD2_PIN)); + GPIOA->OTYPER &= ~((1U << LD2_PIN)); + GPIOA->OSPEEDR &= ~((3U << 2U*LD2_PIN)); + GPIOA->OSPEEDR |= ((1U << 2U*LD2_PIN)); + GPIOA->PUPDR &= ~((3U << 2U*LD2_PIN)); + + // enable GPIOC clock port for the Button B1 + RCC->IOPENR |= (1U << 2U); + + // configure Button (PC.13) pins as input, no pull-up, pull-down + GPIOC->MODER &= ~(3U << 2U*B1_PIN); + GPIOC->OSPEEDR &= ~(3U << 2U*B1_PIN); + GPIOC->OSPEEDR |= (1U << 2U*B1_PIN); + GPIOC->PUPDR &= ~(3U << 2U*B1_PIN); + + // seed the random number generator + BSP_randomSeed(1234U); + + // initialize the QS software tracing... + if (!QS_INIT((void *)0)) { + Q_ERROR(); + } + + // dictionaries... + QS_OBJ_DICTIONARY(&l_SysTick_Handler); + QS_USR_DICTIONARY(PHILO_STAT); + QS_USR_DICTIONARY(PAUSED_STAT); + QS_USR_DICTIONARY(CONTEXT_SW); + + QS_ONLY(produce_sig_dict()); + + // setup the QS filters... + QS_GLB_FILTER(QS_ALL_RECORDS); // all records + QS_GLB_FILTER(-QS_QF_TICK); // exclude the clock tick +} +//............................................................................ +void BSP_start(void) { + // initialize event pools + static QF_MPOOL_EL(TableEvt) smlPoolSto[2*N_PHILO]; + QF_poolInit(smlPoolSto, sizeof(smlPoolSto), sizeof(smlPoolSto[0])); + + // initialize publish-subscribe + static QSubscrList subscrSto[MAX_PUB_SIG]; + QActive_psInit(subscrSto, Q_DIM(subscrSto)); + + // instantiate and start AOs/threads... + + static QEvt const *philoQueueSto[N_PHILO][10]; + for (uint8_t n = 0U; n < N_PHILO; ++n) { + Philo_ctor(n); + QACTIVE_START(AO_Philo[n], + n + 3U, // QF-prio. + philoQueueSto[n], // event queue storage + Q_DIM(philoQueueSto[n]), // queue length [events] + (void *)0, 0U, // no stack storage + (void *)0); // no initialization param + } + + static QEvt const *tableQueueSto[N_PHILO]; + Table_ctor(); + QACTIVE_START(AO_Table, + N_PHILO + 7U, // QP prio. of the AO + tableQueueSto, // event queue storage + Q_DIM(tableQueueSto), // queue length [events] + (void *)0, 0U, // no stack storage + (void *)0); // no initialization param +} +//............................................................................ +void BSP_displayPhilStat(uint8_t n, char const *stat) { + Q_UNUSED_PAR(n); + + if (stat[0] == 'e') { + GPIOA->BSRR = (1U << LD2_PIN); // turn LED on + } + else { + GPIOA->BSRR = (1U << (LD2_PIN + 16U)); // turn LED off + } + + // app-specific trace record... + QS_BEGIN_ID(PHILO_STAT, AO_Table->prio) + QS_U8(1, n); // Philosopher number + QS_STR(stat); // Philosopher status + QS_END() +} +//............................................................................ +void BSP_displayPaused(uint8_t const paused) { + // not enough LEDs to implement this feature + if (paused != 0U) { + //GPIOA->BSRR = (1U << LD2_PIN); // turn LED[n] on + } + else { + //GPIOA->BSRR = (1U << (LD2_PIN + 16U)); // turn LED[n] off + } + + // application-specific trace record + QS_BEGIN_ID(PAUSED_STAT, AO_Table->prio) + QS_U8(1, paused); // Paused status + QS_END() +} +//............................................................................ +void BSP_randomSeed(uint32_t seed) { + l_rndSeed = seed; +} +//............................................................................ +uint32_t BSP_random(void) { // a very cheap pseudo-random-number generator + + // "Super-Duper" Linear Congruential Generator (LCG) + // LCG(2^32, 3*7*11*13*23, 0, seed) + uint32_t rnd = l_rndSeed * (3U*7U*11U*13U*23U); + l_rndSeed = rnd; // set for the next time + + return (rnd >> 8U); +} +//............................................................................ +void BSP_ledOn(void) { + GPIOA->BSRR = (1U << LD2_PIN); // turn LED2 on +} +//............................................................................ +void BSP_ledOff(void) { + GPIOA->BSRR = (1U << (LD2_PIN + 16U)); // turn LED2 off +} +//............................................................................ +void BSP_terminate(int16_t result) { + Q_UNUSED_PAR(result); +} + +//============================================================================ +// QF callbacks... +void QF_onStartup(void) { + // set up the SysTick timer to fire at BSP_TICKS_PER_SEC rate + SysTick_Config(SystemCoreClock / BSP_TICKS_PER_SEC); + + // assign all priority bits for preemption-prio. and none to sub-prio. + // NOTE: this might have been changed by STM32Cube. + NVIC_SetPriorityGrouping(0U); + + // set priorities of ALL ISRs used in the system, see NOTE1 + NVIC_SetPriority(USART2_IRQn, 0U); // kernel UNAWARE interrupt + NVIC_SetPriority(EXTI0_1_IRQn, QF_AWARE_ISR_CMSIS_PRI + 0U); + NVIC_SetPriority(SysTick_IRQn, QF_AWARE_ISR_CMSIS_PRI + 1U); + // ... + + // enable IRQs... + NVIC_EnableIRQ(EXTI0_1_IRQn); #ifdef Q_SPY + NVIC_EnableIRQ(USART2_IRQn); // UART2 interrupt used for QS-RX +#endif +} +//............................................................................ +void QF_onCleanup(void) { +} +//............................................................................ +void QV_onIdle(void) { // CATION: called with interrupts DISABLED, see NOTE0 + + // toggle an LED on and then off (not enough LEDs, see NOTE02) + //GPIOA->BSRR = (1U << LD2_PIN); // turn LED[n] on + //GPIOA->BSRR = (1U << (LD2_PIN + 16U)); // turn LED[n] off + +#ifdef Q_SPY + // interrupts still disabled + QS_rxParse(); // parse all the received bytes QF_INT_ENABLE(); - QS_rxParse(); /* parse all the received bytes */ - - if ((USART2->ISR & (1U << 7)) != 0) { /* is TXE empty? */ - uint16_t b; + QF_CRIT_EXIT_NOP(); + if ((USART2->ISR & (1U << 7U)) != 0U) { // is TXE empty? QF_INT_DISABLE(); - b = QS_getByte(); + uint16_t b = QS_getByte(); QF_INT_ENABLE(); - if (b != QS_EOD) { /* not End-Of-Data? */ - USART2->TDR = (b & 0xFFU); /* put into the DR register */ + if (b != QS_EOD) { // not End-Of-Data? + USART2->TDR = b; // put into the DR register } } #elif defined NDEBUG - /* Put the CPU and peripherals to the low-power mode. - * you might need to customize the clock management for your application, - * see the datasheet for your particular Cortex-M MCU. - */ - /* !!!CAUTION!!! - * QV_CPU_SLEEP() contains the WFI instruction, which stops the CPU - * clock, which unfortunately disables the JTAG port, so the ST-Link - * debugger can no longer connect to the board. For that reason, the call - * to QV_CPU_SLEEP() has to be used with CAUTION. - */ - /* NOTE: If you find your board "frozen" like this, strap BOOT0 to VDD and - * reset the board, then connect with ST-Link Utilities and erase the part. - * The trick with BOOT(0) is it gets the part to run the System Loader - * instead of your broken code. When done disconnect BOOT0, and start over. - */ - //QV_CPU_SLEEP(); /* atomically go to sleep and enable interrupts */ - QF_INT_ENABLE(); /* for now, just enable interrupts */ + // Put the CPU and peripherals to the low-power mode. + // you might need to customize the clock management for your application, + // see the datasheet for your particular Cortex-M MCU. + // + // !!!CAUTION!!! + // QV_CPU_SLEEP() contains the WFI instruction, which stops the CPU + // clock, which unfortunately disables the JTAG port, so the ST-Link + // debugger can no longer connect to the board. For that reason, the call + // to QV_CPU_SLEEP() has to be used with CAUTION. + // + // NOTE: If you find your board "frozen" like this, strap BOOT0 to VDD and + // reset the board, then connect with ST-Link Utilities and erase the part. + // The trick with BOOT(0) is it gets the part to run the System Loader + // instead of your broken code. When done disconnect BOOT0, and start over. + // + //QV_CPU_SLEEP(); // atomically go to sleep and enable interrupts + QF_INT_ENABLE(); // for now, just enable interrupts #else - QF_INT_ENABLE(); /* just enable interrupts */ + QF_INT_ENABLE(); // just enable interrupts #endif } -/*..........................................................................*/ -Q_NORETURN Q_onAssert(char const * const module, int_t const loc) { - /* - * NOTE: add here your application-specific error handling - */ - (void)module; - (void)loc; - QS_ASSERTION(module, loc, 10000U); /* report assertion to QS */ - -#ifndef NDEBUG - BSP_wait4SW1(); -#endif - NVIC_SystemReset(); -} - -/* QS callbacks ============================================================*/ +//============================================================================ +// QS callbacks... #ifdef Q_SPY -/*..........................................................................*/ + +//............................................................................ #define __DIV(__PCLK, __BAUD) (((__PCLK / 4) *25)/(__BAUD)) #define __DIVMANT(__PCLK, __BAUD) (__DIV(__PCLK, __BAUD)/100) #define __DIVFRAQ(__PCLK, __BAUD) \ @@ -449,98 +407,125 @@ Q_NORETURN Q_onAssert(char const * const module, int_t const loc) { #define __USART_BRR(__PCLK, __BAUD) \ ((__DIVMANT(__PCLK, __BAUD) << 4)|(__DIVFRAQ(__PCLK, __BAUD) & 0x0F)) -/*..........................................................................*/ +// USART2 pins PA.2 and PA.3 +#define USART2_TX_PIN 2U +#define USART2_RX_PIN 3U + +//............................................................................ uint8_t QS_onStartup(void const *arg) { - static uint8_t qsBuf[2*1024]; /* buffer for Quantum Spy */ - static uint8_t qsRxBuf[256]; /* buffer for QS-RX channel */ + Q_UNUSED_PAR(arg); - (void)arg; /* avoid the "unused parameter" compiler warning */ + static uint8_t qsTxBuf[2*1024]; // buffer for QS-TX channel + QS_initBuf(qsTxBuf, sizeof(qsTxBuf)); - QS_initBuf(qsBuf, sizeof(qsBuf)); + static uint8_t qsRxBuf[100]; // buffer for QS-RX channel QS_rxInitBuf(qsRxBuf, sizeof(qsRxBuf)); - /* enable peripheral clock for USART2 */ - RCC->IOPENR |= ( 1U << 0); /* Enable GPIOA clock */ - RCC->APB1ENR |= ( 1U << 17); /* Enable USART#2 clock */ + // enable peripheral clock for USART2 + RCC->IOPENR |= ( 1U << 0U); // Enable GPIOA clock for USART pins + RCC->APB1ENR |= ( 1U << 17U); // Enable USART#2 clock - /* Configure PA3 to USART2_RX, PA2 to USART2_TX */ - GPIOA->AFR[0] &= ~((15U << 4* 3) | (15U << 4* 2) ); - GPIOA->AFR[0] |= (( 4U << 4* 3) | ( 4U << 4* 2) ); - GPIOA->MODER &= ~(( 3U << 2* 3) | ( 3U << 2* 2) ); - GPIOA->MODER |= (( 2U << 2* 3) | ( 2U << 2* 2) ); + // Configure PA3 to USART2_RX, PA2 to USART2_TX + GPIOA->AFR[0] &= ~((15U << 4U*USART2_RX_PIN) | (15U << 4U*USART2_TX_PIN)); + GPIOA->AFR[0] |= (( 4U << 4U*USART2_RX_PIN) | ( 4U << 4U*USART2_TX_PIN)); + GPIOA->MODER &= ~(( 3U << 2U*USART2_RX_PIN) | ( 3U << 2U*USART2_TX_PIN)); + GPIOA->MODER |= (( 2U << 2U*USART2_RX_PIN) | ( 2U << 2U*USART2_TX_PIN)); - USART2->BRR = __USART_BRR(SystemCoreClock, 115200U); /* baud rate */ - USART2->CR3 = 0x0000 | /* no flow control */ - (1U << 12); /* disable overrun detection (OVRDIS) */ - USART2->CR2 = 0x0000; /* 1 stop bit */ - USART2->CR1 = ((1U << 2) | /* enable RX */ - (1U << 3) | /* enable TX */ - (1U << 5) | /* enable RX interrupt */ - (0U << 12) | /* 8 data bits */ - (0U << 28) | /* 8 data bits */ - (1U << 0) ); /* enable USART */ + USART2->BRR = __USART_BRR(SystemCoreClock, 115200U); // baud rate + USART2->CR3 = 0x0000U | // no flow control + (1U << 12U); // disable overrun detection (OVRDIS) + USART2->CR2 = 0x0000U; // 1 stop bit + USART2->CR1 = ((1U << 2U) | // enable RX + (1U << 3U) | // enable TX + (1U << 5U) | // enable RX interrupt + (0U << 12U) | // 8 data bits + (0U << 28U) | // 8 data bits + (1U << 0U)); // enable USART QS_tickPeriod_ = SystemCoreClock / BSP_TICKS_PER_SEC; - QS_tickTime_ = QS_tickPeriod_; /* to start the timestamp at zero */ + QS_tickTime_ = QS_tickPeriod_; // to start the timestamp at zero - return 1U; /* return success */ + return 1U; // return success } -/*..........................................................................*/ +//............................................................................ void QS_onCleanup(void) { } -/*..........................................................................*/ -QSTimeCtr QS_onGetTime(void) { /* NOTE: invoked with interrupts DISABLED */ - if ((SysTick->CTRL & 0x00010000) == 0) { /* COUNT no set? */ +//............................................................................ +QSTimeCtr QS_onGetTime(void) { // NOTE: invoked with interrupts DISABLED + if ((SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk) == 0U) { // not set? return QS_tickTime_ - (QSTimeCtr)SysTick->VAL; } - else { /* the rollover occured, but the SysTick_ISR did not run yet */ + else { // the rollover occured, but the SysTick_ISR did not run yet return QS_tickTime_ + QS_tickPeriod_ - (QSTimeCtr)SysTick->VAL; } } -/*..........................................................................*/ +//............................................................................ void QS_onFlush(void) { - uint16_t b; + for (;;) { + QF_CRIT_STAT + QF_CRIT_ENTRY(); + uint16_t b = QS_getByte(); + QF_CRIT_EXIT(); - QF_INT_DISABLE(); - while ((b = QS_getByte()) != QS_EOD) { /* while not End-Of-Data... */ - QF_INT_ENABLE(); - while ((USART2->ISR & (1U << 7)) == 0U) { /* while TXE not empty */ + if (b != QS_EOD) { // NOT end-of-data + // busy-wait as long as TX has data to transmit + while ((USART2->ISR & (1U << 7U)) == 0U) { + } + USART2->TDR = b; // put into the TDR register + } + else { + break; // break out of the loop } - USART2->TDR = (b & 0xFFU); /* put into the DR register */ - QF_INT_DISABLE(); } - QF_INT_ENABLE(); } -/*..........................................................................*/ -/*! callback function to reset the target (to be implemented in the BSP) */ +//............................................................................ +//! callback function to reset the target (to be implemented in the BSP) void QS_onReset(void) { NVIC_SystemReset(); } -/*..........................................................................*/ -/*! callback function to execute a user command (to be implemented in BSP) */ +//............................................................................ +//! callback function to execute a user command void QS_onCommand(uint8_t cmdId, uint32_t param1, uint32_t param2, uint32_t param3) { - (void)cmdId; - (void)param1; - (void)param2; - (void)param3; + Q_UNUSED_PAR(cmdId); + Q_UNUSED_PAR(param1); + Q_UNUSED_PAR(param2); + Q_UNUSED_PAR(param3); } -#endif /* Q_SPY */ -/*--------------------------------------------------------------------------*/ +#endif // Q_SPY +//---------------------------------------------------------------------------- -/***************************************************************************** -* NOTE01: -* The QV_onIdle() callback is called with interrupts disabled, because the -* determination of the idle condition might change by any interrupt posting -* an event. QV_onIdle() must internally enable interrupts, ideally -* atomically with putting the CPU to the power-saving mode. -* -* NOTE02: -* The User LED is used to visualize the idle loop activity. The brightness -* The User LED is used to visualize the idle loop activity. The brightness -* of the LED is proportional to the frequency of invcations of the idle loop. -* Please note that the LED is toggled with interrupts locked, so no interrupt -* execution time contributes to the brightness of the User LED. -*/ +//============================================================================ +// NOTE0: +// The QV_onIdle() callback is called with interrupts disabled, because the +// determination of the idle condition might change by any interrupt posting +// an event. QV_onIdle() must internally enable interrupts, ideally +// atomically with putting the CPU to the power-saving mode. +// +// NOTE1: +// The QF_AWARE_ISR_CMSIS_PRI constant from the QF port specifies the highest +// ISR priority that is disabled by the QF framework. The value is suitable +// for the NVIC_SetPriority() CMSIS function. +// +// Only ISRs prioritized at or below the QF_AWARE_ISR_CMSIS_PRI level (i.e., +// with the numerical values of priorities equal or higher than +// QF_AWARE_ISR_CMSIS_PRI) are allowed to call the QV_ISR_ENTRY/ +// QV_ISR_ENTRY macros or any other QF/QV services. These ISRs are +// "QF-aware". +// +// Conversely, any ISRs prioritized above the QF_AWARE_ISR_CMSIS_PRI priority +// level (i.e., with the numerical values of priorities less than +// QF_AWARE_ISR_CMSIS_PRI) are never disabled and are not aware of the kernel. +// Such "QF-unaware" ISRs cannot call ANY QF/QV services. In particular they +// can NOT call the macros QV_ISR_ENTRY/QV_ISR_ENTRY. The only mechanism +// by which a "QF-unaware" ISR can communicate with the QF framework is by +// triggering a "QF-aware" ISR, which can post/publish events. +// +// NOTE2: +// The User LED is used to visualize the idle loop activity. The brightness +// of the LED is proportional to the frequency of the idle loop. +// Please note that the LED is toggled with interrupts locked, so no interrupt +// execution time contributes to the brightness of the User LED. +// diff --git a/examples/arm-cm/dpp_nucleo-l053r8/qv/gnu/Makefile b/examples/arm-cm/dpp_nucleo-l053r8/qv/gnu/Makefile index 092d4af4..016411d0 100644 --- a/examples/arm-cm/dpp_nucleo-l053r8/qv/gnu/Makefile +++ b/examples/arm-cm/dpp_nucleo-l053r8/qv/gnu/Makefile @@ -205,11 +205,11 @@ ASFLAGS = -g $(ARM_CPU) $(ARM_FPU) $(ASM_CPU) $(ASM_FPU) CFLAGS = -c -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \ -ffunction-sections -fdata-sections \ - -O2 $(INCLUDES) $(DEFINES) -DQ_SPY + -O $(INCLUDES) $(DEFINES) -DQ_SPY CPPFLAGS = -c -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \ -ffunction-sections -fdata-sections -fno-rtti -fno-exceptions \ - -O2 $(INCLUDES) $(DEFINES) -DQ_SPY + -O $(INCLUDES) $(DEFINES) -DQ_SPY else # default Debug configuration .......................................... @@ -219,11 +219,11 @@ ASFLAGS = -g $(ARM_CPU) $(ARM_FPU) $(ASM_CPU) $(ASM_FPU) CFLAGS = -c -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \ -ffunction-sections -fdata-sections \ - -O2 $(INCLUDES) $(DEFINES) + -O $(INCLUDES) $(DEFINES) CPPFLAGS = -c -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \ -ffunction-sections -fdata-sections -fno-rtti -fno-exceptions \ - -O2 $(INCLUDES) $(DEFINES) + -O $(INCLUDES) $(DEFINES) endif # ...................................................................... @@ -261,7 +261,7 @@ $(TARGET_BIN): $(TARGET_ELF) $(BIN) -O binary $< $@ $(TARGET_ELF) : $(ASM_OBJS_EXT) $(C_OBJS_EXT) $(CPP_OBJS_EXT) - $(CC) $(CFLAGS) $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o + $(CC) $(CFLAGS) $(QPC)/src/qs/qstamp.c -o $(BIN_DIR)/qstamp.o $(LINK) $(LINKFLAGS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) $(BIN_DIR)/%.d : %.c diff --git a/examples/arm-cm/dpp_nucleo-l053r8/qv/iar/dpp-qv.ewd b/examples/arm-cm/dpp_nucleo-l053r8/qv/iar/dpp-qv.ewd index 07f57330..de341ac5 100644 --- a/examples/arm-cm/dpp_nucleo-l053r8/qv/iar/dpp-qv.ewd +++ b/examples/arm-cm/dpp_nucleo-l053r8/qv/iar/dpp-qv.ewd @@ -11,7 +11,7 @@ C-SPY 2 - 28 + 32 1 1 - - + + + + + @@ -486,7 +498,7 @@ IJET_ID 2 - 8 + 9 1 1 + + + + + + + + + + + + + @@ -916,7 +980,7 @@ LMIFTDI_ID 2 - 2 + 3 1 1 + + + + + + + NULINK_ID + 2 + + 0 + 1 + 1 + + + @@ -974,7 +1072,7 @@ STLINK_ID 2 - 4 + 8 1 1 + + + + @@ -1185,7 +1300,7 @@ XDS100_ID 2 - 6 + 9 1 1 + + + + @@ -1362,6 +1493,18 @@ $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin 0 + + $TOOLKIT_DIR$\plugins\rtos\FreeRtos\FreeRtosArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin2.ENU.ewplugin + 0 + $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin 0 @@ -1371,11 +1514,15 @@ 0 - $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9.ewplugin 0 - $TOOLKIT_DIR$\plugins\rtos\TI-RTOS\tirtosplugin.ewplugin + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9BE.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin 0 @@ -1391,11 +1538,11 @@ 0 - $EW_DIR$\common\plugins\CodeCoverage\CodeCoverage.ENU.ewplugin - 1 + $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + 0 - $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + $EW_DIR$\common\plugins\TargetAccessServer\TargetAccessServer.ENU.ewplugin 0 @@ -1414,7 +1561,7 @@ C-SPY 2 - 28 + 32 1 0 - - + + + + + @@ -1889,7 +2048,7 @@ IJET_ID 2 - 8 + 9 1 0 + + + + + + + + + + + + + @@ -2319,7 +2530,7 @@ LMIFTDI_ID 2 - 2 + 3 1 0 + + + + + + + NULINK_ID + 2 + + 0 + 1 + 0 + + + @@ -2377,7 +2622,7 @@ STLINK_ID 2 - 4 + 8 1 0 + + + + @@ -2588,7 +2850,7 @@ XDS100_ID 2 - 6 + 9 1 0 + + + + @@ -2765,6 +3043,18 @@ $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin 0 + + $TOOLKIT_DIR$\plugins\rtos\FreeRtos\FreeRtosArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin2.ENU.ewplugin + 0 + $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin 0 @@ -2774,11 +3064,15 @@ 0 - $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9.ewplugin 0 - $TOOLKIT_DIR$\plugins\rtos\TI-RTOS\tirtosplugin.ewplugin + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9BE.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin 0 @@ -2794,11 +3088,11 @@ 0 - $EW_DIR$\common\plugins\CodeCoverage\CodeCoverage.ENU.ewplugin - 1 + $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + 0 - $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + $EW_DIR$\common\plugins\TargetAccessServer\TargetAccessServer.ENU.ewplugin 0 @@ -2817,7 +3111,7 @@ C-SPY 2 - 28 + 32 1 1 - - + + + + + @@ -3292,7 +3598,7 @@ IJET_ID 2 - 8 + 9 1 1 + + + + + + + + + + + + + @@ -3722,7 +4080,7 @@ LMIFTDI_ID 2 - 2 + 3 1 1 + + + + + + + NULINK_ID + 2 + + 0 + 1 + 1 + + + @@ -3780,7 +4172,7 @@ STLINK_ID 2 - 4 + 8 1 1 + + + + @@ -3991,7 +4400,7 @@ XDS100_ID 2 - 6 + 9 1 1 + + + + @@ -4168,6 +4593,18 @@ $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin 0 + + $TOOLKIT_DIR$\plugins\rtos\FreeRtos\FreeRtosArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin2.ENU.ewplugin + 0 + $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin 0 @@ -4177,11 +4614,15 @@ 0 - $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9.ewplugin 0 - $TOOLKIT_DIR$\plugins\rtos\TI-RTOS\tirtosplugin.ewplugin + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9BE.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin 0 @@ -4197,11 +4638,11 @@ 0 - $EW_DIR$\common\plugins\CodeCoverage\CodeCoverage.ENU.ewplugin - 1 + $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + 0 - $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + $EW_DIR$\common\plugins\TargetAccessServer\TargetAccessServer.ENU.ewplugin 0 diff --git a/examples/arm-cm/dpp_nucleo-l053r8/qv/iar/dpp-qv.ewp b/examples/arm-cm/dpp_nucleo-l053r8/qv/iar/dpp-qv.ewp index 79ebe13a..1e324776 100644 --- a/examples/arm-cm/dpp_nucleo-l053r8/qv/iar/dpp-qv.ewp +++ b/examples/arm-cm/dpp_nucleo-l053r8/qv/iar/dpp-qv.ewp @@ -11,12 +11,12 @@ General 3 - 33 + 35 1 1 + + + @@ -671,7 +683,7 @@ ILINK 0 - 25 + 27 1 1 + + + + @@ -1062,12 +1090,12 @@ General 3 - 33 + 35 1 0 + + + @@ -1722,7 +1762,7 @@ ILINK 0 - 25 + 27 1 0 + + + + @@ -2113,12 +2169,12 @@ General 3 - 33 + 35 1 1 + + + @@ -2317,6 +2385,7 @@ @@ -3169,14 +3254,11 @@ $PROJ_DIR$\..\..\dpp.h - $PROJ_DIR$\..\main.c + $PROJ_DIR$\..\..\main.c $PROJ_DIR$\..\..\philo.c - - $PROJ_DIR$\..\..\..\..\..\include\qstamp.c - $PROJ_DIR$\..\..\table.c @@ -3246,21 +3328,9 @@ QP_port - - $PROJ_DIR$\..\..\..\..\..\ports\arm-cm\qv\iar\qep_port.h - - - $PROJ_DIR$\..\..\..\..\..\ports\arm-cm\qv\iar\qf_port.h - - - $PROJ_DIR$\..\..\..\..\..\ports\arm-cm\qv\iar\qs_port.h - $PROJ_DIR$\..\..\..\..\..\ports\arm-cm\qv\iar\qv_port.c - - $PROJ_DIR$\..\..\..\..\..\ports\arm-cm\qv\iar\qv_port.h - QS @@ -3277,5 +3347,8 @@ $PROJ_DIR$\..\..\..\..\..\src\qs\qs_rx.c + + $PROJ_DIR$\..\..\..\..\..\src\qs\qstamp.c + diff --git a/examples/arm-cm/dpp_nucleo-l053r8/qv/main.c b/examples/arm-cm/dpp_nucleo-l053r8/qv/main.c deleted file mode 100644 index 291504c8..00000000 --- a/examples/arm-cm/dpp_nucleo-l053r8/qv/main.c +++ /dev/null @@ -1,88 +0,0 @@ -/***************************************************************************** -* Product: DPP example -* Last updated for version 7.1.2 -* Last updated on 2022-10-06 -* -* Q u a n t u m L e a P s -* ------------------------ -* Modern Embedded Software -* -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* -* -*****************************************************************************/ -#include "qpc.h" -#include "dpp.h" -#include "bsp.h" - -Q_DEFINE_THIS_FILE - -/*..........................................................................*/ -int main() { - static QEvt const *tableQueueSto[N_PHILO]; - static QEvt const *philoQueueSto[N_PHILO][N_PHILO]; - static QSubscrList subscrSto[MAX_PUB_SIG]; - static QF_MPOOL_EL(TableEvt) smlPoolSto[2*N_PHILO]; /* small pool */ - uint8_t n; - - Philo_ctor(); /* instantiate all Philosopher active objects */ - Table_ctor(); /* instantiate the Table active object */ - - QF_init(); /* initialize the framework and the underlying RT kernel */ - BSP_init(); /* initialize the Board Support Package */ - - /* object dictionaries... */ - QS_OBJ_DICTIONARY(AO_Table); - QS_OBJ_DICTIONARY(AO_Philo[0]); - QS_OBJ_DICTIONARY(AO_Philo[1]); - QS_OBJ_DICTIONARY(AO_Philo[2]); - QS_OBJ_DICTIONARY(AO_Philo[3]); - QS_OBJ_DICTIONARY(AO_Philo[4]); - - /* initialize publish-subscribe... */ - QF_psInit(subscrSto, Q_DIM(subscrSto)); - - /* initialize event pools... */ - QF_poolInit(smlPoolSto, sizeof(smlPoolSto), sizeof(smlPoolSto[0])); - - /* start the active objects... */ - for (n = 0U; n < N_PHILO; ++n) { - QACTIVE_START(AO_Philo[n], /* AO to start */ - n + 1U, /* QF-priority */ - philoQueueSto[n], /* event queue storage */ - Q_DIM(philoQueueSto[n]), /* queue length [events] */ - (void *)0, /* stack storage (not used) */ - 0U, /* size of the stack [bytes] */ - (void *)0); /* initialization param */ - } - QACTIVE_START(AO_Table, /* AO to start */ - N_PHILO + 1U, /* QF-priority */ - tableQueueSto, /* event queue storage */ - Q_DIM(tableQueueSto), /* queue length [events] */ - (void *)0, /* stack storage (not used) */ - 0U, /* size of the stack [bytes] */ - (void *)0); /* initialization param */ - - return QF_run(); /* run the QF application */ -} - diff --git a/examples/arm-cm/dpp_nucleo-l053r8/qxk/armclang/dpp-qxk.sct b/examples/arm-cm/dpp_nucleo-l053r8/qxk/armclang/dpp-qxk.sct new file mode 100644 index 00000000..04d0dc68 --- /dev/null +++ b/examples/arm-cm/dpp_nucleo-l053r8/qxk/armclang/dpp-qxk.sct @@ -0,0 +1,20 @@ +; ************************************************************* +; *** Scatter-Loading Description File generated by uVision *** +; +; Adapted by Quantum Leaps: +; moved STACK as the first section in RW_IRAM1 +; ************************************************************* + +LR_IROM1 0x08000000 0x00010000 { ; load region size_region + ER_IROM1 0x08000000 0x00010000 { ; load address = execution address + *.o (RESET, +First) + *(InRoot$$Sections) + .ANY (+RO) + .ANY (+XO) + } + RW_IRAM1 0x20000000 0x00002000 { ; RW data + *.o (STACK, +First) + .ANY (+RW +ZI) + } +} + diff --git a/examples/arm-cm/dpp_nucleo-l053r8/qxk/armclang/dpp-qxk.uvoptx b/examples/arm-cm/dpp_nucleo-l053r8/qxk/armclang/dpp-qxk.uvoptx index 4a810aa6..3a63ea29 100644 --- a/examples/arm-cm/dpp_nucleo-l053r8/qxk/armclang/dpp-qxk.uvoptx +++ b/examples/arm-cm/dpp_nucleo-l053r8/qxk/armclang/dpp-qxk.uvoptx @@ -299,7 +299,7 @@ 1 0 0 - 5 + 6 @@ -316,12 +316,12 @@ 0 UL2CM3 - UL2CM3(-S0 -C0 -P0 -FD20000000 -FC1000 -FN1 -FF0STM32L0xx_64 -FS08000000 -FL010000 -FP0($$Device:STM32L053R8Tx$Flash\STM32L0xx_64.FLM)) + UL2CM3(-S0 -C0 -P0 -FD20000000 -FC1000 -FN1 -FF0STM32L0xx_64 -FS08000000 -FL010000 -FP0($$Device:STM32L053R8Tx$CMSIS\Flash\STM32L0xx_64.FLM)) 0 ST-LINKIII-KEIL_SWO - -U066CFF484951775087074312 -I0 -O8431 -S0 -C0 -A0 -N00("ARM CoreSight SW-DP") -D00(0BC11477) -L00(0) -TO18 -TC10000000 -TP21 -TDS8007 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -FO7 -FD20000000 -FC1000 -FN1 -FF0STM32L0xx_64.FLM -FS08000000 -FL010000 -FP0($$Device:STM32L053R8Tx$Flash\STM32L0xx_64.FLM) + -U066CFF484951775087074312 -I0 -O8431 -S0 -C0 -A0 -N00("ARM CoreSight SW-DP") -D00(0BC11477) -L00(0) -TO18 -TC10000000 -TP21 -TDS8007 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -FO7 -FD20000000 -FC1000 -FN1 -FF0STM32L0xx_64.FLM -FS08000000 -FL010000 -FP0($$Device:STM32L053R8Tx$CMSIS\Flash\STM32L0xx_64.FLM) 0 @@ -403,6 +403,13 @@ + + 1 + 1 + 0 + 2 + 10000000 + @@ -675,8 +682,8 @@ 0 0 0 - ..\..\..\..\..\include\qstamp.c - qstamp.c + ..\xthread1.c + xthread1.c 0 0 @@ -687,8 +694,8 @@ 0 0 0 - ..\main.c - main.c + ..\xthread2.c + xthread2.c 0 0 @@ -699,8 +706,8 @@ 0 0 0 - ..\test.c - test.c + ..\..\main.c + main.c 0 0 @@ -867,18 +874,6 @@ 3 21 - 5 - 0 - 0 - 0 - ..\..\..\..\..\src\qf_pkg.h - qf_pkg.h - 0 - 0 - - - 3 - 22 1 0 0 @@ -890,7 +885,7 @@ 3 - 23 + 22 1 0 0 @@ -902,7 +897,7 @@ 3 - 24 + 23 1 0 0 @@ -914,7 +909,7 @@ 3 - 25 + 24 1 0 0 @@ -926,7 +921,7 @@ 3 - 26 + 25 1 0 0 @@ -938,7 +933,7 @@ 3 - 27 + 26 1 0 0 @@ -950,7 +945,7 @@ 3 - 28 + 27 1 0 0 @@ -962,19 +957,7 @@ 3 - 29 - 5 - 0 - 0 - 0 - ..\..\..\..\..\src\qxk_pkg.h - qxk_pkg.h - 0 - 0 - - - 3 - 30 + 28 1 0 0 @@ -986,7 +969,7 @@ 3 - 31 + 29 1 0 0 @@ -1006,31 +989,7 @@ 0 4 - 32 - 5 - 0 - 0 - 0 - ..\..\..\..\..\ports\arm-cm\qxk\armclang\qep_port.h - qep_port.h - 0 - 0 - - - 4 - 33 - 5 - 0 - 0 - 0 - ..\..\..\..\..\ports\arm-cm\qxk\armclang\qf_port.h - qf_port.h - 0 - 0 - - - 4 - 34 + 30 5 0 0 @@ -1042,7 +1001,7 @@ 4 - 35 + 31 1 0 0 @@ -1052,18 +1011,6 @@ 0 0 - - 4 - 36 - 5 - 0 - 0 - 0 - ..\..\..\..\..\ports\arm-cm\qxk\armclang\qxk_port.h - qxk_port.h - 0 - 0 - @@ -1074,7 +1021,7 @@ 0 5 - 37 + 32 1 0 0 @@ -1086,7 +1033,7 @@ 5 - 38 + 33 1 0 0 @@ -1098,7 +1045,7 @@ 5 - 39 + 34 1 0 0 @@ -1110,19 +1057,7 @@ 5 - 40 - 5 - 0 - 0 - 0 - ..\..\..\..\..\src\qs_pkg.h - qs_pkg.h - 0 - 0 - - - 5 - 41 + 35 1 0 0 @@ -1132,6 +1067,18 @@ 0 0 + + 5 + 36 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qs\qstamp.c + qstamp.c + 0 + 0 + diff --git a/examples/arm-cm/dpp_nucleo-l053r8/qxk/armclang/dpp-qxk.uvprojx b/examples/arm-cm/dpp_nucleo-l053r8/qxk/armclang/dpp-qxk.uvprojx index f48ec96c..a5ccc99e 100644 --- a/examples/arm-cm/dpp_nucleo-l053r8/qxk/armclang/dpp-qxk.uvprojx +++ b/examples/arm-cm/dpp_nucleo-l053r8/qxk/armclang/dpp-qxk.uvprojx @@ -313,7 +313,7 @@ 0 - 2 + 1 0 0 1 @@ -337,7 +337,7 @@ 0 - QF_ON_CONTEXT_SW + QF_ON_CONTEXT_SW,QXK_USE_IRQ_HANDLER=WWDG_IRQHandler,QXK_USE_IRQ_NUM=0 ..\..;..\..\..\..\..\include;..\..\..\..\..\ports\arm-cm\qxk\armclang;..\..\..\..\..\3rd_party\CMSIS\Include;..\..\..\..\..\3rd_party\nucleo-l053r8 @@ -361,7 +361,7 @@ - 1 + 0 0 0 0 @@ -370,7 +370,7 @@ 0x00000000 0x20000000 - + .\dpp-qxk.sct --entry Reset_Handler @@ -409,19 +409,19 @@ ..\..\table.c - qstamp.c + xthread1.c 1 - ..\..\..\..\..\include\qstamp.c + ..\xthread1.c + + + xthread2.c + 1 + ..\xthread2.c main.c 1 - ..\main.c - - - test.c - 1 - ..\test.c + ..\..\main.c @@ -493,11 +493,6 @@ 1 ..\..\..\..\..\src\qf\qf_mem.c - - qf_pkg.h - 5 - ..\..\..\..\..\src\qf_pkg.h - qf_ps.c 1 @@ -533,11 +528,6 @@ 1 ..\..\..\..\..\src\qxk\qxk_mutex.c - - qxk_pkg.h - 5 - ..\..\..\..\..\src\qxk_pkg.h - qxk_sema.c 1 @@ -553,16 +543,6 @@ QP_port - - qep_port.h - 5 - ..\..\..\..\..\ports\arm-cm\qxk\armclang\qep_port.h - - - qf_port.h - 5 - ..\..\..\..\..\ports\arm-cm\qxk\armclang\qf_port.h - qs_port.h 5 @@ -572,62 +552,6 @@ qxk_port.c 1 ..\..\..\..\..\ports\arm-cm\qxk\armclang\qxk_port.c - - - 2 - 0 - 0 - 0 - 0 - 2 - 2 - 2 - 2 - 2 - 11 - - - 1 - - - - 2 - 0 - 2 - 2 - 2 - 2 - 2 - 2 - 2 - 2 - 0 - 2 - 2 - 2 - 2 - 2 - 0 - 0 - 2 - 2 - 2 - 2 - 2 - - - QXK_USE_IRQ_NUM=30 QXK_USE_IRQ_HANDLER=LCD_IRQHandler - - - - - - - - - qxk_port.h - 5 - ..\..\..\..\..\ports\arm-cm\qxk\armclang\qxk_port.h @@ -718,16 +642,16 @@ 1 ..\..\..\..\..\src\qs\qs_fp.c - - qs_pkg.h - 5 - ..\..\..\..\..\src\qs_pkg.h - qs_rx.c 1 ..\..\..\..\..\src\qs\qs_rx.c + + qstamp.c + 1 + ..\..\..\..\..\src\qs\qstamp.c + @@ -736,7 +660,7 @@ dpp-rel 0x4 ARM-ADS - 6070000::V6.7::.\ARMCLANG + 6160000::V6.16::ARMCLANG 1 @@ -1063,7 +987,7 @@ 0 - NDEBUG + NDEBUG,QF_ON_CONTEXT_SW ..\..;..\..\..\..\..\include;..\..\..\..\..\ports\arm-cm\qxk\armclang;..\..\..\..\..\3rd_party\CMSIS\Include;..\..\..\..\..\3rd_party\nucleo-l053r8 @@ -1087,7 +1011,7 @@ - 1 + 0 0 0 0 @@ -1096,7 +1020,7 @@ 0x00000000 0x20000000 - dpp-qxk.sct + .\dpp-qxk.sct --entry Reset_Handler @@ -1135,19 +1059,19 @@ ..\..\table.c - qstamp.c + xthread1.c 1 - ..\..\..\..\..\include\qstamp.c + ..\xthread1.c + + + xthread2.c + 1 + ..\xthread2.c main.c 1 - ..\main.c - - - test.c - 1 - ..\test.c + ..\..\main.c @@ -1219,11 +1143,6 @@ 1 ..\..\..\..\..\src\qf\qf_mem.c - - qf_pkg.h - 5 - ..\..\..\..\..\src\qf_pkg.h - qf_ps.c 1 @@ -1259,11 +1178,6 @@ 1 ..\..\..\..\..\src\qxk\qxk_mutex.c - - qxk_pkg.h - 5 - ..\..\..\..\..\src\qxk_pkg.h - qxk_sema.c 1 @@ -1279,16 +1193,6 @@ QP_port - - qep_port.h - 5 - ..\..\..\..\..\ports\arm-cm\qxk\armclang\qep_port.h - - - qf_port.h - 5 - ..\..\..\..\..\ports\arm-cm\qxk\armclang\qf_port.h - qs_port.h 5 @@ -1299,11 +1203,6 @@ 1 ..\..\..\..\..\ports\arm-cm\qxk\armclang\qxk_port.c - - qxk_port.h - 5 - ..\..\..\..\..\ports\arm-cm\qxk\armclang\qxk_port.h - @@ -1393,16 +1292,16 @@ 1 ..\..\..\..\..\src\qs\qs_fp.c - - qs_pkg.h - 5 - ..\..\..\..\..\src\qs_pkg.h - qs_rx.c 1 ..\..\..\..\..\src\qs\qs_rx.c + + qstamp.c + 1 + ..\..\..\..\..\src\qs\qstamp.c + @@ -1762,7 +1661,7 @@ - 1 + 0 0 0 0 @@ -1771,7 +1670,7 @@ 0x00000000 0x20000000 - dpp-qxk.sct + .\dpp-qxk.sct --entry Reset_Handler @@ -1810,19 +1709,19 @@ ..\..\table.c - qstamp.c + xthread1.c 1 - ..\..\..\..\..\include\qstamp.c + ..\xthread1.c + + + xthread2.c + 1 + ..\xthread2.c main.c 1 - ..\main.c - - - test.c - 1 - ..\test.c + ..\..\main.c @@ -1894,11 +1793,6 @@ 1 ..\..\..\..\..\src\qf\qf_mem.c - - qf_pkg.h - 5 - ..\..\..\..\..\src\qf_pkg.h - qf_ps.c 1 @@ -1934,11 +1828,6 @@ 1 ..\..\..\..\..\src\qxk\qxk_mutex.c - - qxk_pkg.h - 5 - ..\..\..\..\..\src\qxk_pkg.h - qxk_sema.c 1 @@ -1954,16 +1843,6 @@ QP_port - - qep_port.h - 5 - ..\..\..\..\..\ports\arm-cm\qxk\armclang\qep_port.h - - - qf_port.h - 5 - ..\..\..\..\..\ports\arm-cm\qxk\armclang\qf_port.h - qs_port.h 5 @@ -1974,11 +1853,6 @@ 1 ..\..\..\..\..\ports\arm-cm\qxk\armclang\qxk_port.c - - qxk_port.h - 5 - ..\..\..\..\..\ports\arm-cm\qxk\armclang\qxk_port.h - @@ -1999,16 +1873,16 @@ 1 ..\..\..\..\..\src\qs\qs_fp.c - - qs_pkg.h - 5 - ..\..\..\..\..\src\qs_pkg.h - qs_rx.c 1 ..\..\..\..\..\src\qs\qs_rx.c + + qstamp.c + 1 + ..\..\..\..\..\src\qs\qstamp.c + diff --git a/examples/arm-cm/dpp_nucleo-l053r8/qxk/bsp.c b/examples/arm-cm/dpp_nucleo-l053r8/qxk/bsp.c index 33cf3e8f..ca364726 100644 --- a/examples/arm-cm/dpp_nucleo-l053r8/qxk/bsp.c +++ b/examples/arm-cm/dpp_nucleo-l053r8/qxk/bsp.c @@ -1,335 +1,426 @@ -/***************************************************************************** -* Product: DPP example, NUCLEO-L053R8 board, preemptive QXK kernel -* Last updated for version 6.9.3 -* Last updated on 2021-03-03 -* -* Q u a n t u m L e a P s -* ------------------------ -* Modern Embedded Software -* -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* -* -*****************************************************************************/ -#include "qpc.h" -#include "dpp.h" -#include "bsp.h" +//============================================================================ +// Product: DPP example, NUCLEO-L053R8 board, QXK kernel +// Last updated for version 7.3.0 +// Last updated on 2023-08-22 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +//============================================================================ +#include "qpc.h" // QP/C real-time embedded framework +#include "dpp.h" // DPP Application interface +#include "bsp.h" // Board Support Package -#include "stm32l0xx.h" /* CMSIS-compliant header file for the MCU used */ -/* add other drivers if necessary... */ +#include "stm32l0xx.h" // CMSIS-compliant header file for the MCU used +// add other drivers if necessary... Q_DEFINE_THIS_FILE -/* Local-scope objects -----------------------------------------------------*/ -/* LED pins available on the board (just one user LED LD2--Green on PA.5) */ -#define LED_LD2 (1U << 5) +// Local-scope objects ----------------------------------------------------- +// LED pins available on the board (just one user LED LD2--Green on PA.5) +#define LD2_PIN 5U -/* Button pins available on the board (just one user Button B1 on PC.13) */ -#define BTN_B1 (1U << 13) +// Button pins available on the board (just one user Button B1 on PC.13) +#define B1_PIN 13U -static uint32_t l_rnd; /* random seed */ +static uint32_t l_rndSeed; #ifdef Q_SPY QSTimeCtr QS_tickTime_; QSTimeCtr QS_tickPeriod_; - /* QSpy source IDs */ + // QSpy source IDs static QSpyId const l_SysTick_Handler = { 0U }; + static QSpyId const l_EXTI0_1_IRQHandler = { 0U }; - enum AppRecords { /* application-specific trace records */ + enum AppRecords { // application-specific trace records PHILO_STAT = QS_USER, + PAUSED_STAT, CONTEXT_SW, }; #endif -/* ISRs used in the application ==========================================*/ -void SysTick_Handler(void); -void EXTI0_1_IRQHandler(void); -void USART2_IRQHandler(void); +//============================================================================ +// Error handler and ISRs... -/*..........................................................................*/ -void SysTick_Handler(void) { /* system clock tick ISR */ - /* state of the button debouncing, see below */ - static struct ButtonsDebouncing { - uint32_t depressed; - uint32_t previous; - } buttons = { 0U, 0U }; - uint32_t current; - uint32_t tmp; +Q_NORETURN Q_onError(char const * const module, int_t const id) { + // NOTE: this implementation of the assertion handler is intended only + // for debugging and MUST be changed for deployment of the application + // (assuming that you ship your production code with assertions enabled). + Q_UNUSED_PAR(module); + Q_UNUSED_PAR(id); + QS_ASSERTION(module, id, 10000U); - QXK_ISR_ENTRY(); /* inform QXK about entering an ISR */ - -#ifdef Q_SPY - { - tmp = SysTick->CTRL; /* clear CTRL_COUNTFLAG */ - QS_tickTime_ += QS_tickPeriod_; /* account for the clock rollover */ +#ifndef NDEBUG + // light up the user LED + GPIOA->BSRR = (1U << LD2_PIN); + // for debugging, hang on in an endless loop... + for (;;) { } #endif - QTIMEEVT_TICK_X(0U, &l_SysTick_Handler); /* process time events for rate 0 */ - //QACTIVE_POST(the_Ticker0, 0, &l_SysTick_Handler); /* post to Ticker0 */ + NVIC_SystemReset(); +} +//............................................................................ +void assert_failed(char const * const module, int_t const id); // prototype +void assert_failed(char const * const module, int_t const id) { + Q_onError(module, id); +} - /* get state of the user button */ - /* Perform the debouncing of buttons. The algorithm for debouncing - * adapted from the book "Embedded Systems Dictionary" by Jack Ganssle - * and Michael Barr, page 71. - */ - current = ~GPIOC->IDR; /* read Port C with the state of Button B1 */ - tmp = buttons.depressed; /* save the debounced depressed buttons */ - buttons.depressed |= (buttons.previous & current); /* set depressed */ - buttons.depressed &= (buttons.previous | current); /* clear released */ - buttons.previous = current; /* update the history */ - tmp ^= buttons.depressed; /* changed debounced depressed */ - if ((tmp & BTN_B1) != 0U) { /* debounced B1 state changed? */ - if ((buttons.depressed & BTN_B1) != 0U) { /* is B1 depressed? */ - static QEvt const pauseEvt = { PAUSE_SIG, 0U, 0U}; +// ISRs used in the application ========================================== +void SysTick_Handler(void); // prototype +void SysTick_Handler(void) { // system clock tick ISR + QXK_ISR_ENTRY(); // inform QXK about entering an ISR + + QTIMEEVT_TICK_X(0U, &l_SysTick_Handler); // time events for rate 0 + + // Perform the debouncing of buttons. The algorithm for debouncing + // adapted from the book "Embedded Systems Dictionary" by Jack Ganssle + // and Michael Barr, page 71. + static struct { + uint32_t depressed; + uint32_t previous; + } buttons = { 0U, 0U }; + uint32_t current = ~GPIOC->IDR; // read Port C with Button B1 + uint32_t tmp = buttons.depressed; // save the depressed buttons + buttons.depressed |= (buttons.previous & current); // set depressed + buttons.depressed &= (buttons.previous | current); // clear released + buttons.previous = current; // update the history + tmp ^= buttons.depressed; // changed debounced depressed + current = buttons.depressed; + + if ((tmp & (1U << B1_PIN)) != 0U) { // debounced B1 state changed? + if ((current & (1U << B1_PIN)) != 0U) { // is B1 depressed? + static QEvt const pauseEvt = QEVT_INITIALIZER(PAUSE_SIG); QACTIVE_PUBLISH(&pauseEvt, &l_SysTick_Handler); } - else { /* the button is released */ - static QEvt const serveEvt = { SERVE_SIG, 0U, 0U}; + else { // the button is released + static QEvt const serveEvt = QEVT_INITIALIZER(SERVE_SIG); QACTIVE_PUBLISH(&serveEvt, &l_SysTick_Handler); } } - QXK_ISR_EXIT(); /* inform QXK about exiting an ISR */ -} -/*..........................................................................*/ -/* interrupt handler for testing preemptions in QXK */ -void EXTI0_1_IRQHandler(void) { - static QEvt const testEvt = { TEST_SIG, 0U, 0U }; - QXK_ISR_ENTRY(); /* inform QXK about entering an ISR */ - QXTHREAD_POST_X(XT_Test2, &testEvt, 0U, (void *)0); - QXK_ISR_EXIT(); /* inform QXK about exiting an ISR */ -} -/*..........................................................................*/ #ifdef Q_SPY -void USART2_IRQHandler(void) { /* used in QS-RX (kernel UNAWARE interrutp) */ - /* is RX register NOT empty? */ - if ((USART2->ISR & (1U << 5)) != 0) { + tmp = SysTick->CTRL; // clear CTRL_COUNTFLAG + QS_tickTime_ += QS_tickPeriod_; // account for the clock rollover +#endif + + QXK_ISR_EXIT(); // inform QXK about exiting an ISR +} +//............................................................................ +// interrupt handler for testing preemptions in QXK +void EXTI0_1_IRQHandler(void); // prototype +void EXTI0_1_IRQHandler(void) { + QXK_ISR_ENTRY(); // inform QXK about entering an ISR + + static QEvt const testEvt = QEVT_INITIALIZER(TEST_SIG); + QACTIVE_POST(AO_Table, &testEvt, &l_EXTI0_1_IRQHandler); + + QXK_ISR_EXIT(); // inform QXK about exiting an ISR +} + +//............................................................................ +#ifdef Q_SPY +// ISR for receiving bytes from the QSPY Back-End +// NOTE: This ISR is "QF-unaware" meaning that it does not interact with +// the QF/QXK and is not disabled. Such ISRs don't need to call +// QXK_ISR_ENTRY/QXK_ISR_EXIT and they cannot post or publish events. + +void USART2_IRQHandler(void); // prototype +void USART2_IRQHandler(void) { // used in QS-RX (kernel UNAWARE interrutp) + // is RX register NOT empty? + if ((USART2->ISR & (1U << 5U)) != 0U) { uint32_t b = USART2->RDR; QS_RX_PUT(b); } + QXK_ARM_ERRATUM_838869(); } -#endif +#endif // Q_SPY -/* BSP functions ===========================================================*/ -void BSP_init(void) { - /* NOTE: SystemInit() has been already called from the startup code - * but SystemCoreClock needs to be updated - */ - SystemCoreClockUpdate(); - - /* enable GPIOA clock port for the LED LD2 */ - RCC->IOPENR |= (1U << 0); - - /* configure LED (PA.5) pin as push-pull output, no pull-up, pull-down */ - GPIOA->MODER &= ~((3U << 2*5)); - GPIOA->MODER |= ((1U << 2*5)); - GPIOA->OTYPER &= ~((1U << 5)); - GPIOA->OSPEEDR &= ~((3U << 2*5)); - GPIOA->OSPEEDR |= ((1U << 2*5)); - GPIOA->PUPDR &= ~((3U << 2*5)); - - /* enable GPIOC clock port for the Button B1 */ - RCC->IOPENR |= (1U << 2); - - /* configure Button (PC.13) pins as input, no pull-up, pull-down */ - GPIOC->MODER &= ~(3U << 2*13); - GPIOC->OSPEEDR &= ~(3U << 2*13); - GPIOC->OSPEEDR |= (1U << 2*13); - GPIOC->PUPDR &= ~(3U << 2*13); - - BSP_randomSeed(1234U); /* seed the random number generator */ - - /* initialize the QS software tracing... */ - if (QS_INIT((void *)0) == 0U) { - Q_ERROR(); - } - QS_OBJ_DICTIONARY(&l_SysTick_Handler); - QS_OBJ_DICTIONARY(XT_Test1); - QS_OBJ_DICTIONARY(XT_Test2); - QS_OBJ_DICTIONARY(the_Ticker0); - - QS_USR_DICTIONARY(PHILO_STAT); - QS_USR_DICTIONARY(CONTEXT_SW); - - /* setup the QS filters... */ - QS_GLB_FILTER(QS_ALL_RECORDS); /* all records */ - QS_GLB_FILTER(-QS_QF_TICK); /* exclude the clock tick */ -} -/*..........................................................................*/ -void BSP_displayPhilStat(uint8_t n, char const *stat) { - if (stat[0] == 'h') { - GPIOA->BSRR |= LED_LD2; /* turn LED on */ - } - else { - GPIOA->BSRR |= (LED_LD2 << 16); /* turn LED off */ - } - - QS_BEGIN_ID(PHILO_STAT, AO_Philo[n]->prio) /* app-specific record */ - QS_U8(1, n); /* Philosopher number */ - QS_STR(stat); /* Philosopher status */ - QS_END() -} -/*..........................................................................*/ -void BSP_displayPaused(uint8_t paused) { - /* not enough LEDs to implement this feature */ - if (paused != 0U) { - //GPIOA->BSRR |= (LED_LD2); /* turn LED[n] on */ - } - else { - //GPIOA->BSRR |= (LED_LD2 << 16); /* turn LED[n] off */ - } -} -/*..........................................................................*/ -uint32_t BSP_random(void) { /* a very cheap pseudo-random-number generator */ - /* "Super-Duper" Linear Congruential Generator (LCG) - * LCG(2^32, 3*7*11*13*23, 0, seed) - */ - l_rnd = l_rnd * (3U*7U*11U*13U*23U); - return l_rnd >> 8; -} -/*..........................................................................*/ -void BSP_randomSeed(uint32_t seed) { - l_rnd = seed; -} -/*..........................................................................*/ -void BSP_terminate(int16_t result) { - (void)result; -} -/*..........................................................................*/ -void BSP_wait4SW1(void) { - while ((GPIOC->IDR & BTN_B1) != 0U) { - GPIOA->BSRR |= (LED_LD2); /* turn LED2 on */ - GPIOA->BSRR |= (LED_LD2 << 16); /* turn LED2 off */ - } -} -/*..........................................................................*/ -void BSP_ledOn(void) { - //GPIOA->BSRR |= (LED_LD2); /* turn LED2 on */ -} -/*..........................................................................*/ -void BSP_ledOff(void) { - //GPIOA->BSRR |= (LED_LD2 << 16); /* turn LED2 off */ -} - -/* QF callbacks ============================================================*/ -void QF_onStartup(void) { - /* set up the SysTick timer to fire at BSP_TICKS_PER_SEC rate */ - SysTick_Config(SystemCoreClock / BSP_TICKS_PER_SEC); - - /* set priorities of ALL ISRs used in the system, see NOTE00 - * - * !!!!!!!!!!!!!!!!!!!!!!!!!!!! CAUTION !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - * Assign a priority to EVERY ISR explicitly by calling NVIC_SetPriority(). - * DO NOT LEAVE THE ISR PRIORITIES AT THE DEFAULT VALUE! - */ - NVIC_SetPriority(SysTick_IRQn, QF_AWARE_ISR_CMSIS_PRI + 1); - NVIC_SetPriority(EXTI0_1_IRQn, QF_AWARE_ISR_CMSIS_PRI + 2); - NVIC_SetPriority(USART2_IRQn, 0); /* kernel UNAWARE interrupt */ - /* ... */ - - /* enable IRQs... */ - NVIC_EnableIRQ(EXTI0_1_IRQn); -#ifdef Q_SPY - NVIC_EnableIRQ(USART2_IRQn); /* UART2 interrupt used for QS-RX */ -#endif -} -/*..........................................................................*/ -void QF_onCleanup(void) { -} -/*..........................................................................*/ +//............................................................................ #ifdef QF_ON_CONTEXT_SW -/* NOTE: the context-switch callback is called with interrupts DISABLED */ +// NOTE: the context-switch callback is called with interrupts DISABLED void QF_onContextSw(QActive *prev, QActive *next) { - QS_BEGIN_NOCRIT(CONTEXT_SW, 0U) /* no critical section! */ + QS_BEGIN_INCRIT(CONTEXT_SW, 0U) // in critical section! QS_OBJ(prev); QS_OBJ(next); - QS_END_NOCRIT() + QS_END_INCRIT() } -#endif /* QF_ON_CONTEXT_SW */ -/*..........................................................................*/ -void QXK_onIdle(void) { /* called with interrupts enabled */ +#endif // QF_ON_CONTEXT_SW - /* toggle an LED on and then off (not enough LEDs, see NOTE01) */ - QF_INT_DISABLE(); - //GPIOA->BSRR |= (LED_LD2); /* turn LED[n] on */ - //GPIOA->BSRR |= (LED_LD2 << 16); /* turn LED[n] off */ - QF_INT_ENABLE(); + +//============================================================================ +// BSP functions... + +void BSP_init(void) { + // Configure the MPU to prevent NULL-pointer dereferencing ... + MPU->RBAR = 0x0U // base address (NULL) + | MPU_RBAR_VALID_Msk // valid region + | (MPU_RBAR_REGION_Msk & 7U); // region #7 + MPU->RASR = (7U << MPU_RASR_SIZE_Pos) // 2^(7+1) region + | (0x0U << MPU_RASR_AP_Pos) // no-access region + | MPU_RASR_ENABLE_Msk; // region enable + MPU->CTRL = MPU_CTRL_PRIVDEFENA_Msk // enable background region + | MPU_CTRL_ENABLE_Msk; // enable the MPU + __ISB(); + __DSB(); + + // NOTE: SystemInit() has been already called from the startup code + // but SystemCoreClock needs to be updated + SystemCoreClockUpdate(); + + // enable GPIOA clock port for the LED LD2 + RCC->IOPENR |= (1U << 0U); + + // configure LED (PA.5) pin as push-pull output, no pull-up, pull-down + GPIOA->MODER &= ~((3U << 2U*LD2_PIN)); + GPIOA->MODER |= ((1U << 2U*LD2_PIN)); + GPIOA->OTYPER &= ~((1U << LD2_PIN)); + GPIOA->OSPEEDR &= ~((3U << 2U*LD2_PIN)); + GPIOA->OSPEEDR |= ((1U << 2U*LD2_PIN)); + GPIOA->PUPDR &= ~((3U << 2U*LD2_PIN)); + + // enable GPIOC clock port for the Button B1 + RCC->IOPENR |= (1U << 2U); + + // configure Button (PC.13) pins as input, no pull-up, pull-down + GPIOC->MODER &= ~(3U << 2U*B1_PIN); + GPIOC->OSPEEDR &= ~(3U << 2U*B1_PIN); + GPIOC->OSPEEDR |= (1U << 2U*B1_PIN); + GPIOC->PUPDR &= ~(3U << 2U*B1_PIN); + + BSP_randomSeed(1234U); // seed the random number generator + + // initialize the QS software tracing... + if (!QS_INIT((void *)0)) { + Q_ERROR(); + } + + // dictionaries... + QS_OBJ_DICTIONARY(&l_SysTick_Handler); + QS_OBJ_DICTIONARY(&l_EXTI0_1_IRQHandler); + QS_USR_DICTIONARY(PHILO_STAT); + QS_USR_DICTIONARY(PAUSED_STAT); + QS_USR_DICTIONARY(CONTEXT_SW); + + QS_ONLY(produce_sig_dict()); + + // setup the QS filters... + QS_GLB_FILTER(QS_ALL_RECORDS); // all records + QS_GLB_FILTER(-QS_QF_TICK); // exclude the clock tick +} +//............................................................................ +void BSP_start(void) { + // initialize event pools + static QF_MPOOL_EL(TableEvt) smlPoolSto[2*N_PHILO]; + QF_poolInit(smlPoolSto, sizeof(smlPoolSto), sizeof(smlPoolSto[0])); + + // initialize publish-subscribe + static QSubscrList subscrSto[MAX_PUB_SIG]; + QActive_psInit(subscrSto, Q_DIM(subscrSto)); + + // instantiate and start AOs/threads... + static QEvt const *xThread1QueueSto[5]; + static uint64_t xThread1StackSto[64]; + XThread1_ctor(); + QXTHREAD_START(TH_XThread1, + 1U, // QP priority of the thread + xThread1QueueSto, // event queue storage + Q_DIM(xThread1QueueSto), // event length [events] + xThread1StackSto, // stack storage + sizeof(xThread1StackSto), // stack size [bytes] + (void *)0); // no initialization param + + static QEvt const *philoQueueSto[N_PHILO][10]; + for (uint8_t n = 0U; n < N_PHILO; ++n) { + Philo_ctor(n); + QACTIVE_START(AO_Philo[n], + n + 3U, // QF-prio/pthre. see NOTE1 + philoQueueSto[n], // event queue storage + Q_DIM(philoQueueSto[n]), // queue length [events] + (void *)0, 0U, // no stack storage + (void *)0); // no initialization param + } + + static QEvt const *xThread2QueueSto[5]; + static uint64_t xThread2StackSto[64]; + XThread2_ctor(); + QXTHREAD_START(TH_XThread2, + N_PHILO + 5U, // QP priority of the thread + xThread2QueueSto, // event queue storage + Q_DIM(xThread2QueueSto), // event length [events] + xThread2StackSto, // stack storage + sizeof(xThread2StackSto), // stack size [bytes] + (void *)0); // no initialization param + + static QEvt const *tableQueueSto[N_PHILO]; + Table_ctor(); + QACTIVE_START(AO_Table, + N_PHILO + 7U, // QP prio. of the AO + tableQueueSto, // event queue storage + Q_DIM(tableQueueSto), // queue length [events] + (void *)0, 0U, // no stack storage + (void *)0); // no initialization param +} +//............................................................................ +void BSP_displayPhilStat(uint8_t n, char const *stat) { + Q_UNUSED_PAR(n); + + if (stat[0] == 'h') { + GPIOA->BSRR = (1U << LD2_PIN); // turn LED on + } + else { + GPIOA->BSRR = (1U << (LD2_PIN + 16U)); // turn LED off + } + + // app-specific trace record... + QS_BEGIN_ID(PHILO_STAT, AO_Table->prio) + QS_U8(1, n); // Philosopher number + QS_STR(stat); // Philosopher status + QS_END() +} +//............................................................................ +void BSP_displayPaused(uint8_t const paused) { + // not enough LEDs to implement this feature + if (paused != 0U) { + //GPIOA->BSRR = (1U << LD2_PIN); // turn LED[n] on + } + else { + //GPIOA->BSRR = (1U << (LD2_PIN + 16U)); // turn LED[n] off + } + + // application-specific trace record + QS_BEGIN_ID(PAUSED_STAT, AO_Table->prio) + QS_U8(1, paused); // Paused status + QS_END() +} +//............................................................................ +void BSP_randomSeed(uint32_t seed) { + l_rndSeed = seed; +} +//............................................................................ +uint32_t BSP_random(void) { // a very cheap pseudo-random-number generator + + QSchedStatus lockStat = QXK_schedLock(N_PHILO); + // "Super-Duper" Linear Congruential Generator (LCG) + // LCG(2^32, 3*7*11*13*23, 0, seed) + // + uint32_t rnd = l_rndSeed * (3U*7U*11U*13U*23U); + l_rndSeed = rnd; // set for the next time + QXK_schedUnlock(lockStat); + + return (rnd >> 8U); +} +//............................................................................ +void BSP_ledOn(void) { + //GPIOA->BSRR = (1U << LD2_PIN); // turn LED2 on +} +//............................................................................ +void BSP_ledOff(void) { + //GPIOA->BSRR = (1U << (LD2_PIN + 16U)); // turn LED2 off +} +//............................................................................ +void BSP_terminate(int16_t result) { + Q_UNUSED_PAR(result); +} + +//============================================================================ +// QF callbacks... +void QF_onStartup(void) { + // set up the SysTick timer to fire at BSP_TICKS_PER_SEC rate + SysTick_Config(SystemCoreClock / BSP_TICKS_PER_SEC); + + // assign all priority bits for preemption-prio. and none to sub-prio. + // NOTE: this might have been changed by STM32Cube. + NVIC_SetPriorityGrouping(0U); + + // set priorities of ALL ISRs used in the system, see NOTE1 + NVIC_SetPriority(USART2_IRQn, 0U); // kernel UNAWARE interrupt + NVIC_SetPriority(EXTI0_1_IRQn, QF_AWARE_ISR_CMSIS_PRI + 0U); + NVIC_SetPriority(SysTick_IRQn, QF_AWARE_ISR_CMSIS_PRI + 1U); + // ... + + // enable IRQs... + NVIC_EnableIRQ(EXTI0_1_IRQn); #ifdef Q_SPY - QS_rxParse(); /* parse all the received bytes */ + NVIC_EnableIRQ(USART2_IRQn); // UART2 interrupt used for QS-RX +#endif +} +//............................................................................ +void QF_onCleanup(void) { +} +//............................................................................ +void QXK_onIdle(void) { // called with interrupts enabled - if ((USART2->ISR & (1U << 7)) != 0) { /* is TXE empty? */ - uint16_t b; + // toggle an LED on and then off (not enough LEDs, see NOTE01) + //QF_INT_DISABLE(); + //GPIOA->BSRR = (1U << LD2_PIN); // turn LED[n] on + //GPIOA->BSRR = (1U << (LD2_PIN + 16U)); // turn LED[n] off + //QF_INT_ENABLE(); +#ifdef Q_SPY + QF_INT_DISABLE(); + QS_rxParse(); // parse all the received bytes + QF_INT_ENABLE(); + + if ((USART2->ISR & (1U << 7U)) != 0U) { // is TXE empty? QF_INT_DISABLE(); - b = QS_getByte(); + uint16_t b = QS_getByte(); QF_INT_ENABLE(); - if (b != QS_EOD) { /* not End-Of-Data? */ - USART2->TDR = (b & 0xFFU); /* put into the DR register */ + if (b != QS_EOD) { // not End-Of-Data? + USART2->TDR = b; // put into the DR register } } #elif defined NDEBUG - /* Put the CPU and peripherals to the low-power mode. - * you might need to customize the clock management for your application, - * see the datasheet for your particular Cortex-M MCU. - */ - /* !!!CAUTION!!! - * The WFI instruction stops the CPU clock, which unfortunately disables - * the JTAG port, so the ST-Link debugger can no longer connect to the - * board. For that reason, the call to __WFI() has to be used with CAUTION. - * - * NOTE: If you find your board "frozen" like this, strap BOOT0 to VDD and - * reset the board, then connect with ST-Link Utilities and erase the part. - * The trick with BOOT(0) is it gets the part to run the System Loader - * instead of your broken code. When done disconnect BOOT0, and start over. - */ - //__WFI(); /* Wait-For-Interrupt */ + // Put the CPU and peripherals to the low-power mode. + // you might need to customize the clock management for your application, + // see the datasheet for your particular Cortex-M MCU. + // + // !!!CAUTION!!! + // The WFI instruction stops the CPU clock, which unfortunately disables + // the JTAG port, so the ST-Link debugger can no longer connect to the + // board. For that reason, the call to __WFI() has to be used with CAUTION. + // + // NOTE: If you find your board "frozen" like this, strap BOOT0 to VDD and + // reset the board, then connect with ST-Link Utilities and erase the part. + // The trick with BOOT(0) is it gets the part to run the System Loader + // instead of your broken code. When done disconnect BOOT0, and start over. + // + //__WFI(); // Wait-For-Interrupt #endif } -/*..........................................................................*/ -Q_NORETURN Q_onAssert(char const * const module, int_t const loc) { - /* - * NOTE: add here your application-specific error handling - */ - (void)module; - (void)loc; - QS_ASSERTION(module, loc, 10000U); /* report assertion to QS */ - -#ifndef NDEBUG - BSP_wait4SW1(); -#endif - NVIC_SystemReset(); -} - -/* QS callbacks ============================================================*/ +//============================================================================ +// QS callbacks... #ifdef Q_SPY -/*..........................................................................*/ + +//............................................................................ #define __DIV(__PCLK, __BAUD) (((__PCLK / 4) *25)/(__BAUD)) #define __DIVMANT(__PCLK, __BAUD) (__DIV(__PCLK, __BAUD)/100) #define __DIVFRAQ(__PCLK, __BAUD) \ @@ -338,107 +429,118 @@ Q_NORETURN Q_onAssert(char const * const module, int_t const loc) { #define __USART_BRR(__PCLK, __BAUD) \ ((__DIVMANT(__PCLK, __BAUD) << 4)|(__DIVFRAQ(__PCLK, __BAUD) & 0x0F)) -/*..........................................................................*/ +// USART2 pins PA.2 and PA.3 +#define USART2_TX_PIN 2U +#define USART2_RX_PIN 3U + +//............................................................................ uint8_t QS_onStartup(void const *arg) { - static uint8_t qsBuf[2*1024]; /* buffer for Quantum Spy */ - static uint8_t qsRxBuf[128]; /* buffer for QS-RX channel */ + Q_UNUSED_PAR(arg); - (void)arg; /* avoid the "unused parameter" compiler warning */ + static uint8_t qsTxBuf[2*1024]; // buffer for QS-TX channel + QS_initBuf(qsTxBuf, sizeof(qsTxBuf)); - QS_initBuf(qsBuf, sizeof(qsBuf)); + static uint8_t qsRxBuf[100]; // buffer for QS-RX channel QS_rxInitBuf(qsRxBuf, sizeof(qsRxBuf)); - /* enable peripheral clock for USART2 */ - RCC->IOPENR |= ( 1U << 0); /* Enable GPIOA clock */ - RCC->APB1ENR |= ( 1U << 17); /* Enable USART#2 clock */ + // enable peripheral clock for USART2 + RCC->IOPENR |= ( 1U << 0U); // Enable GPIOA clock for USART pins + RCC->APB1ENR |= ( 1U << 17U); // Enable USART#2 clock - /* Configure PA3 to USART2_RX, PA2 to USART2_TX */ - GPIOA->AFR[0] &= ~((15U << 4* 3) | (15U << 4* 2) ); - GPIOA->AFR[0] |= (( 4U << 4* 3) | ( 4U << 4* 2) ); - GPIOA->MODER &= ~(( 3U << 2* 3) | ( 3U << 2* 2) ); - GPIOA->MODER |= (( 2U << 2* 3) | ( 2U << 2* 2) ); + // Configure PA3 to USART2_RX, PA2 to USART2_TX + GPIOA->AFR[0] &= ~((15U << 4U*USART2_RX_PIN) | (15U << 4U*USART2_TX_PIN)); + GPIOA->AFR[0] |= (( 4U << 4U*USART2_RX_PIN) | ( 4U << 4U*USART2_TX_PIN)); + GPIOA->MODER &= ~(( 3U << 2U*USART2_RX_PIN) | ( 3U << 2U*USART2_TX_PIN)); + GPIOA->MODER |= (( 2U << 2U*USART2_RX_PIN) | ( 2U << 2U*USART2_TX_PIN)); - USART2->BRR = __USART_BRR(SystemCoreClock, 115200U); /* baud rate */ - USART2->CR3 = 0x0000 | /* no flow control */ - (1U << 12); /* disable overrun detection (OVRDIS) */ - USART2->CR2 = 0x0000; /* 1 stop bit */ - USART2->CR1 = ((1U << 2) | /* enable RX */ - (1U << 3) | /* enable TX */ - (1U << 5) | /* enable RX interrupt */ - (0U << 12) | /* 8 data bits */ - (0U << 28) | /* 8 data bits */ - (1U << 0) ); /* enable USART */ + USART2->BRR = __USART_BRR(SystemCoreClock, 115200U); // baud rate + USART2->CR3 = 0x0000U | // no flow control + (1U << 12U); // disable overrun detection (OVRDIS) + USART2->CR2 = 0x0000U; // 1 stop bit + USART2->CR1 = ((1U << 2U) | // enable RX + (1U << 3U) | // enable TX + (1U << 5U) | // enable RX interrupt + (0U << 12U) | // 8 data bits + (0U << 28U) | // 8 data bits + (1U << 0U)); // enable USART QS_tickPeriod_ = SystemCoreClock / BSP_TICKS_PER_SEC; - QS_tickTime_ = QS_tickPeriod_; /* to start the timestamp at zero */ + QS_tickTime_ = QS_tickPeriod_; // to start the timestamp at zero - return 1U; /* return success */ + return 1U; // return success } -/*..........................................................................*/ +//............................................................................ void QS_onCleanup(void) { } -/*..........................................................................*/ -QSTimeCtr QS_onGetTime(void) { /* NOTE: invoked with interrupts DISABLED */ - if ((SysTick->CTRL & 0x00010000) == 0) { /* COUNT no set? */ +//............................................................................ +QSTimeCtr QS_onGetTime(void) { // NOTE: invoked with interrupts DISABLED + if ((SysTick->CTRL & 0x00010000) == 0) { // COUNT no set? return QS_tickTime_ - (QSTimeCtr)SysTick->VAL; } - else { /* the rollover occured, but the SysTick_ISR did not run yet */ + else { // the rollover occured, but the SysTick_ISR did not run yet return QS_tickTime_ + QS_tickPeriod_ - (QSTimeCtr)SysTick->VAL; } } -/*..........................................................................*/ +//............................................................................ void QS_onFlush(void) { - uint16_t b; - - QF_INT_DISABLE(); - while ((b = QS_getByte()) != QS_EOD) { /* while not End-Of-Data... */ - QF_INT_ENABLE(); - while ((USART2->ISR & (1U << 7)) == 0U) { /* while TXE not empty */ - } - USART2->TDR = (b & 0xFFU); /* put into the DR register */ + for (;;) { QF_INT_DISABLE(); + uint16_t b = QS_getByte(); + if (b != QS_EOD) { + while ((USART2->ISR & (1U << 7U)) == 0U) { // while TXE not empty + QF_INT_ENABLE(); + QF_CRIT_EXIT_NOP(); + + QF_INT_DISABLE(); + } + USART2->TDR = b; // put into the DR register + QF_INT_ENABLE(); + } + else { + QF_INT_ENABLE(); + break; + } } - QF_INT_ENABLE(); } -/*..........................................................................*/ -/*! callback function to reset the target (to be implemented in the BSP) */ +//............................................................................ +//! callback function to reset the target (to be implemented in the BSP) void QS_onReset(void) { NVIC_SystemReset(); } -/*..........................................................................*/ -/*! callback function to execute a user command (to be implemented in BSP) */ +//............................................................................ +//! callback function to execute a user command void QS_onCommand(uint8_t cmdId, uint32_t param1, uint32_t param2, uint32_t param3) { - (void)cmdId; - (void)param1; - (void)param2; - (void)param3; + Q_UNUSED_PAR(cmdId); + Q_UNUSED_PAR(param1); + Q_UNUSED_PAR(param2); + Q_UNUSED_PAR(param3); } -#endif /* Q_SPY */ -/*--------------------------------------------------------------------------*/ +#endif // Q_SPY +//---------------------------------------------------------------------------- -/***************************************************************************** -* NOTE00: -* The QF_AWARE_ISR_CMSIS_PRI constant from the QF port specifies the highest -* ISR priority that is disabled by the QF framework. The value is suitable -* for the NVIC_SetPriority() CMSIS function. -* -* Only ISRs prioritized at or below the QF_AWARE_ISR_CMSIS_PRI level (i.e., -* with the numerical values of priorities equal or higher than -* QF_AWARE_ISR_CMSIS_PRI) are allowed to call any QF services. These ISRs -* are "QF-aware". -* -* Conversely, any ISRs prioritized above the QF_AWARE_ISR_CMSIS_PRI priority -* level (i.e., with the numerical values of priorities less than -* QF_AWARE_ISR_CMSIS_PRI) are never disabled and are not aware of the kernel. -* Such "QF-unaware" ISRs cannot call any QF services. The only mechanism -* by which a "QF-unaware" ISR can communicate with the QF framework is by -* triggering a "QF-aware" ISR, which can post/publish events. -* -* NOTE01: -* Usually, one of the LEDs is used to visualize the idle loop activity. -* However, the board has not enough LEDs (only one, actually), so this -* feature is disabled. -*/ +//============================================================================ +// NOTE1: +// The QF_AWARE_ISR_CMSIS_PRI constant from the QF port specifies the highest +// ISR priority that is disabled by the QF framework. The value is suitable +// for the NVIC_SetPriority() CMSIS function. +// +// Only ISRs prioritized at or below the QF_AWARE_ISR_CMSIS_PRI level (i.e., +// with the numerical values of priorities equal or higher than +// QF_AWARE_ISR_CMSIS_PRI) are allowed to call any QF services. These ISRs +// are "QF-aware". +// +// Conversely, any ISRs prioritized above the QF_AWARE_ISR_CMSIS_PRI priority +// level (i.e., with the numerical values of priorities less than +// QF_AWARE_ISR_CMSIS_PRI) are never disabled and are not aware of the kernel. +// Such "QF-unaware" ISRs cannot call any QF services. The only mechanism +// by which a "QF-unaware" ISR can communicate with the QF framework is by +// triggering a "QF-aware" ISR, which can post/publish events. +// +// NOTE2: +// Usually, one of the LEDs is used to visualize the idle loop activity. +// However, the board has not enough LEDs (only one, actually), so this +// feature is disabled. +// diff --git a/examples/arm-cm/dpp_nucleo-l053r8/qxk/gnu/Makefile b/examples/arm-cm/dpp_nucleo-l053r8/qxk/gnu/Makefile index 2ca57712..9ca4ea32 100644 --- a/examples/arm-cm/dpp_nucleo-l053r8/qxk/gnu/Makefile +++ b/examples/arm-cm/dpp_nucleo-l053r8/qxk/gnu/Makefile @@ -97,7 +97,8 @@ C_SRCS := \ main.c \ philo.c \ table.c \ - test.c \ + xthread1.c \ + xthread2.c \ system_stm32l0xx.c \ startup_stm32l053xx.c @@ -212,11 +213,11 @@ ASFLAGS = -g $(ARM_CPU) $(ARM_FPU) $(ASM_CPU) $(ASM_FPU) CFLAGS = -c -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \ -ffunction-sections -fdata-sections \ - -O2 $(INCLUDES) $(DEFINES) -DQ_SPY + -O $(INCLUDES) $(DEFINES) -DQ_SPY CPPFLAGS = -c -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \ -ffunction-sections -fdata-sections -fno-rtti -fno-exceptions \ - -O2 $(INCLUDES) $(DEFINES) -DQ_SPY + -O $(INCLUDES) $(DEFINES) -DQ_SPY else # default Debug configuration .......................................... @@ -226,11 +227,11 @@ ASFLAGS = -g $(ARM_CPU) $(ARM_FPU) $(ASM_CPU) $(ASM_FPU) CFLAGS = -c -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \ -ffunction-sections -fdata-sections \ - -O2 $(INCLUDES) $(DEFINES) + -O $(INCLUDES) $(DEFINES) CPPFLAGS = -c -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \ -ffunction-sections -fdata-sections -fno-rtti -fno-exceptions \ - -O2 $(INCLUDES) $(DEFINES) + -O $(INCLUDES) $(DEFINES) endif # ...................................................................... @@ -268,7 +269,7 @@ $(TARGET_BIN): $(TARGET_ELF) $(BIN) -O binary $< $@ $(TARGET_ELF) : $(ASM_OBJS_EXT) $(C_OBJS_EXT) $(CPP_OBJS_EXT) - $(CC) $(CFLAGS) $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o + $(CC) $(CFLAGS) $(QPC)/src/qs/qstamp.c -o $(BIN_DIR)/qstamp.o $(LINK) $(LINKFLAGS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) $(BIN_DIR)/%.d : %.c diff --git a/examples/arm-cm/dpp_nucleo-l053r8/qxk/iar/dpp-qxk.ewd b/examples/arm-cm/dpp_nucleo-l053r8/qxk/iar/dpp-qxk.ewd index 473da05f..6a0e9ea2 100644 --- a/examples/arm-cm/dpp_nucleo-l053r8/qxk/iar/dpp-qxk.ewd +++ b/examples/arm-cm/dpp_nucleo-l053r8/qxk/iar/dpp-qxk.ewd @@ -11,7 +11,7 @@ C-SPY 2 - 28 + 32 1 1 - - + + + + + @@ -486,7 +498,7 @@ IJET_ID 2 - 8 + 9 1 1 + + + + + + + + + + + + + @@ -916,7 +980,7 @@ LMIFTDI_ID 2 - 2 + 3 1 1 + + + + + + + NULINK_ID + 2 + + 0 + 1 + 1 + + + @@ -974,7 +1072,7 @@ STLINK_ID 2 - 4 + 8 1 1 + + + + @@ -1185,7 +1300,7 @@ XDS100_ID 2 - 6 + 9 1 1 + + + + @@ -1362,6 +1493,18 @@ $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin 0 + + $TOOLKIT_DIR$\plugins\rtos\FreeRtos\FreeRtosArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin2.ENU.ewplugin + 0 + $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin 0 @@ -1371,11 +1514,15 @@ 0 - $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9.ewplugin 0 - $TOOLKIT_DIR$\plugins\rtos\TI-RTOS\tirtosplugin.ewplugin + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9BE.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin 0 @@ -1391,11 +1538,11 @@ 0 - $EW_DIR$\common\plugins\CodeCoverage\CodeCoverage.ENU.ewplugin - 1 + $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + 0 - $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + $EW_DIR$\common\plugins\TargetAccessServer\TargetAccessServer.ENU.ewplugin 0 @@ -1414,7 +1561,7 @@ C-SPY 2 - 28 + 32 1 0 - - + + + + + @@ -1889,7 +2048,7 @@ IJET_ID 2 - 8 + 9 1 0 + + + + + + + + + + + + + @@ -2319,7 +2530,7 @@ LMIFTDI_ID 2 - 2 + 3 1 0 + + + + + + + NULINK_ID + 2 + + 0 + 1 + 0 + + + @@ -2377,7 +2622,7 @@ STLINK_ID 2 - 4 + 8 1 0 + + + + @@ -2588,7 +2850,7 @@ XDS100_ID 2 - 6 + 9 1 0 + + + + @@ -2765,6 +3043,18 @@ $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin 0 + + $TOOLKIT_DIR$\plugins\rtos\FreeRtos\FreeRtosArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin2.ENU.ewplugin + 0 + $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin 0 @@ -2774,11 +3064,15 @@ 0 - $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9.ewplugin 0 - $TOOLKIT_DIR$\plugins\rtos\TI-RTOS\tirtosplugin.ewplugin + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9BE.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin 0 @@ -2794,11 +3088,11 @@ 0 - $EW_DIR$\common\plugins\CodeCoverage\CodeCoverage.ENU.ewplugin - 1 + $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + 0 - $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + $EW_DIR$\common\plugins\TargetAccessServer\TargetAccessServer.ENU.ewplugin 0 @@ -2817,7 +3111,7 @@ C-SPY 2 - 28 + 32 1 1 - - + + + + + @@ -3292,7 +3598,7 @@ IJET_ID 2 - 8 + 9 1 1 + + + + + + + + + + + + + @@ -3722,7 +4080,7 @@ LMIFTDI_ID 2 - 2 + 3 1 1 + + + + + + + NULINK_ID + 2 + + 0 + 1 + 1 + + + @@ -3780,7 +4172,7 @@ STLINK_ID 2 - 4 + 8 1 1 + + + + @@ -3991,7 +4400,7 @@ XDS100_ID 2 - 6 + 9 1 1 + + + + @@ -4168,6 +4593,18 @@ $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin 0 + + $TOOLKIT_DIR$\plugins\rtos\FreeRtos\FreeRtosArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin2.ENU.ewplugin + 0 + $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin 0 @@ -4177,11 +4614,15 @@ 0 - $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9.ewplugin 0 - $TOOLKIT_DIR$\plugins\rtos\TI-RTOS\tirtosplugin.ewplugin + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9BE.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin 0 @@ -4197,11 +4638,11 @@ 0 - $EW_DIR$\common\plugins\CodeCoverage\CodeCoverage.ENU.ewplugin - 1 + $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + 0 - $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + $EW_DIR$\common\plugins\TargetAccessServer\TargetAccessServer.ENU.ewplugin 0 diff --git a/examples/arm-cm/dpp_nucleo-l053r8/qxk/iar/dpp-qxk.ewp b/examples/arm-cm/dpp_nucleo-l053r8/qxk/iar/dpp-qxk.ewp index c6e27ffa..18d1a12e 100644 --- a/examples/arm-cm/dpp_nucleo-l053r8/qxk/iar/dpp-qxk.ewp +++ b/examples/arm-cm/dpp_nucleo-l053r8/qxk/iar/dpp-qxk.ewp @@ -11,12 +11,12 @@ General 3 - 33 + 35 1 1 + + + @@ -216,6 +228,7 @@ CCDefines QXK_USE_IRQ_HANDLER=LCD_IRQHandler QXK_USE_IRQ_NUM=30 + QF_ON_CONTEXT_SW @@ -1063,12 +1092,12 @@ General 3 - 33 + 35 1 0 + + + @@ -1412,7 +1453,7 @@ @@ -2114,12 +2171,12 @@ General 3 - 33 + 35 1 1 + + + @@ -2775,7 +2844,7 @@ ILINK 0 - 25 + 27 1 1 + + + + @@ -3168,19 +3253,19 @@ $PROJ_DIR$\..\..\dpp.h - $PROJ_DIR$\..\main.c + $PROJ_DIR$\..\..\main.c $PROJ_DIR$\..\..\philo.c - - $PROJ_DIR$\..\..\..\..\..\include\qstamp.c - $PROJ_DIR$\..\..\table.c - $PROJ_DIR$\..\test.c + $PROJ_DIR$\..\xthread1.c + + + $PROJ_DIR$\..\xthread2.c @@ -3260,21 +3345,9 @@ QP_port - - $PROJ_DIR$\..\..\..\..\..\ports\arm-cm\qxk\iar\qep_port.h - - - $PROJ_DIR$\..\..\..\..\..\ports\arm-cm\qxk\iar\qf_port.h - - - $PROJ_DIR$\..\..\..\..\..\ports\arm-cm\qxk\iar\qs_port.h - $PROJ_DIR$\..\..\..\..\..\ports\arm-cm\qxk\iar\qxk_port.c - - $PROJ_DIR$\..\..\..\..\..\ports\arm-cm\qxk\iar\qxk_port.h - QS @@ -3285,17 +3358,14 @@ $PROJ_DIR$\..\..\..\..\..\src\qs\qs.c - - $PROJ_DIR$\..\..\..\..\..\src\qs\qs_64bit.c - $PROJ_DIR$\..\..\..\..\..\src\qs\qs_fp.c - - $PROJ_DIR$\..\..\..\..\..\src\qs_pkg.h - $PROJ_DIR$\..\..\..\..\..\src\qs\qs_rx.c + + $PROJ_DIR$\..\..\..\..\..\src\qs\qstamp.c + diff --git a/examples/arm-cm/dpp_nucleo-l053r8/qxk/main.c b/examples/arm-cm/dpp_nucleo-l053r8/qxk/main.c deleted file mode 100644 index abeb4598..00000000 --- a/examples/arm-cm/dpp_nucleo-l053r8/qxk/main.c +++ /dev/null @@ -1,128 +0,0 @@ -/***************************************************************************** -* Product: DPP example extened for QXK -* Last updated for version 6.8.2 -* Last updated on 2020-07-15 -* -* Q u a n t u m L e a P s -* ------------------------ -* Modern Embedded Software -* -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* -* -*****************************************************************************/ -#include "qpc.h" -#include "dpp.h" -#include "bsp.h" - -Q_DEFINE_THIS_FILE - -static QTicker l_ticker0; -QActive *the_Ticker0 = &l_ticker0.super; - -/*..........................................................................*/ -int main() { - static QEvt const *tableQueueSto[N_PHILO]; - static QEvt const *philoQueueSto[N_PHILO][N_PHILO]; - static QSubscrList subscrSto[MAX_PUB_SIG]; - static QF_MPOOL_EL(TableEvt) smlPoolSto[2*N_PHILO]; /* small pool */ - - /* stacks and queues for the extended test threads */ - static void const *test1QueueSto[5]; - static uint64_t test1StackSto[64]; - static void const *test2QueueSto[5]; - static uint64_t test2StackSto[64]; - - uint8_t n; - - Philo_ctor(); /* instantiate all Philosopher active objects */ - Table_ctor(); /* instantiate the Table active object */ - QTicker_ctor(&l_ticker0, 0U); /* ticker AO for tick rate 0 */ - Test1_ctor(); /* instantiate the Test1 extended thread */ - Test2_ctor(); /* instantiate the Test2 extended thread */ - - QF_init(); /* initialize the framework and the underlying RT kernel */ - - /* initialize publish-subscribe... */ - QF_psInit(subscrSto, Q_DIM(subscrSto)); - - /* initialize event pools... */ - QF_poolInit(smlPoolSto, sizeof(smlPoolSto), sizeof(smlPoolSto[0])); - - /* initialize the Board Support Package - * NOTE: BSP_init() is called *after* initializing publish-subscribe and - * event pools, to make the system ready to accept SysTick interrupts. - * Unfortunately, the STM32Cube code that must be called from BSP, - * configures and starts SysTick. - */ - BSP_init(); - - /* start the extended thread */ - QXTHREAD_START(XT_Test1, /* Thread to start */ - 1U, /* QP priority of the thread */ - test1QueueSto, /* message queue storage */ - Q_DIM(test1QueueSto), /* message length [events] */ - test1StackSto, /* stack storage */ - sizeof(test1StackSto), /* stack size [bytes] */ - (QEvt *)0); /* initialization event */ - - /* NOTE: leave priority 2 free for a mutex */ - - /* start the Philo active objects... */ - for (n = 0U; n < N_PHILO; ++n) { - QACTIVE_START(AO_Philo[n], /* AO to start */ - n + 3U, /* QP priority of the AO */ - philoQueueSto[n], /* event queue storage */ - Q_DIM(philoQueueSto[n]), /* queue length [events] */ - (void *)0, /* stack storage (not used) */ - 0U, /* size of the stack [bytes] */ - (QEvt *)0); /* initialization event */ - } - - /* example of prioritizing the Ticker0 active object */ - QACTIVE_START(the_Ticker0, N_PHILO + 3U, - 0, 0, 0, 0, 0); - - /* NOTE: leave priority (N_PHILO + 4) free for mutex */ - - QXTHREAD_START(XT_Test2, /* Thread to start */ - N_PHILO + 5U, /* QP priority of the thread */ - test2QueueSto, /* message queue storage */ - Q_DIM(test2QueueSto), /* message length [events] */ - test2StackSto, /* stack storage */ - sizeof(test2StackSto), /* stack size [bytes] */ - (QEvt *)0); /* initialization event */ - - /* NOTE: leave priority (N_PHILO + 6) free for mutex */ - - QACTIVE_START(AO_Table, /* AO to start */ - N_PHILO + 7U, /* QP priority of the AO */ - tableQueueSto, /* event queue storage */ - Q_DIM(tableQueueSto), /* queue length [events] */ - (void *)0, /* stack storage (not used) */ - 0U, /* size of the stack [bytes] */ - (QEvt *)0); /* initialization event */ - - return QF_run(); /* run the QF application */ -} - diff --git a/examples/arm-cm/dpp_nucleo-l053r8/qxk/test.c b/examples/arm-cm/dpp_nucleo-l053r8/qxk/test.c deleted file mode 100644 index 56a1ba20..00000000 --- a/examples/arm-cm/dpp_nucleo-l053r8/qxk/test.c +++ /dev/null @@ -1,140 +0,0 @@ -/***************************************************************************** -* Product: DPP example -* Last updated for: @ref qpc_7_0_0 -* Last updated on 2022-04-11 -* -* Q u a n t u m L e a P s -* ------------------------ -* Modern Embedded Software -* -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* -* -*****************************************************************************/ -#include "qpc.h" -#include "dpp.h" -#include "bsp.h" - -/* local "extended" thread object ..........................................*/ -static QXThread l_test1; -static QXThread l_test2; -static QXMutex l_mutex; -static QXSemaphore l_sema; - -/* Thread-Local Storage for the "extended" threads .........................*/ -typedef struct { - uint32_t foo; - uint8_t bar[10]; -} TLS_test; -static TLS_test l_tls1; -static TLS_test l_tls2; - -static void lib_fun(uint32_t x) { - QXK_TLS(TLS_test *)->foo = x; -} - -/* global pointer to the test thread .......................................*/ -QXThread * const XT_Test1 = &l_test1; -QXThread * const XT_Test2 = &l_test2; - -/*..........................................................................*/ -static void Thread1_run(QXThread * const me) { - - QS_OBJ_DICTIONARY(&l_test1); - - me->super.thread = &l_tls1; /* initialize the TLS for Thread1 */ - - for (;;) { - QXMutex_lock(&l_mutex, QXTHREAD_NO_TIMEOUT); /* lock the mutex */ - BSP_ledOn(); - - if (QXMutex_tryLock(&l_mutex)) { /* exercise the mutex */ - (void)QXSemaphore_signal(&l_sema); /* signal Thread2 */ - - QXThread_delay(10U); /* BLOCK while holding a mutex */ - - QXMutex_unlock(&l_mutex); - } - - QXMutex_unlock(&l_mutex); - BSP_ledOff(); - - QXThread_delay(BSP_TICKS_PER_SEC/7); /* BLOCK */ - - /* publish to thread2 */ - //QACTIVE_PUBLISH(Q_NEW(QEvt, TEST_SIG), &l_test1.super); - - /* test TLS */ - lib_fun(1U); - } -} - -/*..........................................................................*/ -void Test1_ctor(void) { - QXThread_ctor(&l_test1, &Thread1_run, 0U); -} - -/*..........................................................................*/ -static void Thread2_run(QXThread * const me) { - - QS_OBJ_DICTIONARY(&l_test2); - - /* initialize the semaphore before using it - * NOTE: the semaphore is initialized in the highest-priority thread - * that uses it. Alternatively, the semaphore can be initialized - * before any thread runs. - */ - QXSemaphore_init(&l_sema, - 0U, /* count==0 (signaling semaphore) */ - 1U); /* max_count==1 (binary semaphore) */ - - /* initialize the mutex before using it - * NOTE: Here the mutex is initialized in the highest-priority thread - * that uses it. Alternatively, the mutex can be initialized - * before any thread runs. - */ - //QXMutex_init(&l_mutex, 0U); /* priority-ceiling NOT used */ - QXMutex_init(&l_mutex, N_PHILO + 6U); /*priority-ceiling protocol used*/ - - me->super.thread = &l_tls2; /* initialize the TLS for Thread2 */ - - /* subscribe to the test signal */ - QActive_subscribe(&me->super, TEST_SIG); - - for (;;) { - /* wait on a semaphore (BLOCK indefinitely) */ - QXSemaphore_wait(&l_sema, QXTHREAD_NO_TIMEOUT); - - QXMutex_lock(&l_mutex, QXTHREAD_NO_TIMEOUT); /* lock the mutex */ - QXThread_delay(1U); /* wait more (BLOCK) */ - QXMutex_unlock(&l_mutex); - - /* test TLS */ - lib_fun(2U); - } -} - -/*..........................................................................*/ -void Test2_ctor(void) { - QXThread_ctor(&l_test2, &Thread2_run, 0U); -} diff --git a/examples/arm-cm/dpp_nucleo-l053r8/qxk/xthread1.c b/examples/arm-cm/dpp_nucleo-l053r8/qxk/xthread1.c new file mode 100644 index 00000000..066b983d --- /dev/null +++ b/examples/arm-cm/dpp_nucleo-l053r8/qxk/xthread1.c @@ -0,0 +1,101 @@ +//============================================================================ +// QXThread example +// Last updated for version 7.3.0 +// Last updated on 2023-08-12 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. +// +// This program is open source software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Alternatively, this program may be distributed and modified under the +// terms of Quantum Leaps commercial licenses, which expressly supersede +// the GNU General Public License and are specifically designed for +// licensees interested in retaining the proprietary status of their code. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Contact information: +// +// +//============================================================================ +#include "qpc.h" // QP/C real-time embedded framework +#include "dpp.h" // DPP Application interface +#include "bsp.h" // Board Support Package + +//---------------------------------------------------------------------------- +//Q_DEFINE_THIS_FILE + +//............................................................................ +typedef struct XThread1 { +// protected: + QXThread super; + +// private: + // NOTE: data needed by this thread should be members of + // the thread class. That way they are in the memory region + // accessible from this thread. + uint8_t foo; + +// public: +} XThread1; + +// private: +static void XThread1_run(QXThread * const thr); +extern XThread1 XThread1_inst; + +//............................................................................ +QXThread * const TH_XThread1 = &XThread1_inst.super; + +//............................................................................ +void XThread1_ctor(void) { + XThread1 *me = &XThread1_inst; + QXThread_ctor(&me->super, &XThread1_run, 0U); +} + +//............................................................................ +XThread1 XThread1_inst; + +//............................................................................ +static void XThread1_run(QXThread * const thr) { + QS_OBJ_DICTIONARY(TH_XThread1); + QS_OBJ_DICTIONARY(&TH_XThread1->timeEvt); + + // downcast the generic thr pointer to the specific thread + XThread1 *me = (XThread1 *)thr; + + // subscribe to the EAT signal (from the application) + QActive_subscribe(&me->super.super, EAT_SIG); + + for (;;) { + QEvt const *e = QXThread_queueGet(BSP_TICKS_PER_SEC/4U); + if (e) { + QXSemaphore_signal(&TH_sema); // signal Thread2 + QF_gc(e); // must explicitly recycle the received event! + } + + QXMutex_lock(&TH_mutex, QXTHREAD_NO_TIMEOUT); // lock the mutex + BSP_ledOn(); + if (QXMutex_tryLock(&TH_mutex)) { // exercise the mutex + // some floating point code to exercise the VFP... + float volatile x = 1.4142135F; + x = x * 1.4142135F; + QXThread_delay(10U); // BLOCK while holding a mutex + QXMutex_unlock(&TH_mutex); + } + QXMutex_unlock(&TH_mutex); + BSP_ledOff(); + } +} diff --git a/examples/arm-cm/dpp_nucleo-l053r8/qxk/xthread2.c b/examples/arm-cm/dpp_nucleo-l053r8/qxk/xthread2.c new file mode 100644 index 00000000..1caad4fa --- /dev/null +++ b/examples/arm-cm/dpp_nucleo-l053r8/qxk/xthread2.c @@ -0,0 +1,108 @@ +//============================================================================ +// QXThread example +// Last updated for version 7.3.0 +// Last updated on 2023-08-12 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. +// +// This program is open source software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Alternatively, this program may be distributed and modified under the +// terms of Quantum Leaps commercial licenses, which expressly supersede +// the GNU General Public License and are specifically designed for +// licensees interested in retaining the proprietary status of their code. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Contact information: +// +// +//============================================================================ +#include "qpc.h" // QP/C real-time embedded framework +#include "dpp.h" // DPP Application interface +#include "bsp.h" // Board Support Package + +//---------------------------------------------------------------------------- +//Q_DEFINE_THIS_FILE + +//---------------------------------------------------------------------------- +QXSemaphore TH_sema; +QXMutex TH_mutex; + +//---------------------------------------------------------------------------- +typedef struct XThread2 { +// protected: + QXThread super; + +// private: + // NOTE: data needed by this thread should be members of + // the thread class. That way they are in the memory region + // accessible from this thread. + uint8_t foo; + +// public: +} XThread2; + +// private: +static void XThread2_run(QXThread * const thr); +extern XThread2 XThread2_inst; + +//............................................................................ +QXThread * const TH_XThread2 = &XThread2_inst.super; + +//............................................................................ +void XThread2_ctor(void) { + XThread2 *me = &XThread2_inst; + QXThread_ctor(&me->super, &XThread2_run, 0U); +} + +//............................................................................ +XThread2 XThread2_inst; + +//............................................................................ +static void XThread2_run(QXThread * const thr) { + QS_OBJ_DICTIONARY(TH_XThread2); + QS_OBJ_DICTIONARY(&TH_XThread2->timeEvt); + QS_OBJ_DICTIONARY(&TH_sema); + QS_OBJ_DICTIONARY(&TH_mutex); + + // downcast the generic thr pointer to the specific thread + //XThread2 *me = (XThread2 *)thr; + + // initialize the semaphore before using it + // NOTE: Here the semaphore is initialized in the highest-priority thread + // that uses it. Alternatively, the semaphore can be initialized + // before any thread runs. + QXSemaphore_init(&TH_sema, + 0U, // count==0 (signaling semaphore) + 1U); // max_count==1 (binary semaphore) + + // initialize the mutex before using it + // NOTE: Here the mutex is initialized in the highest-priority thread + // that uses it. Alternatively, the mutex can be initialized + // before any thread runs. + QXMutex_init(&TH_mutex, N_PHILO + 6U); // priority-ceiling mutex + //QXMutex_init(&TH_mutex, 0U); // alternatively: priority-ceiling NOT used + + for (;;) { + // wait on a semaphore (BLOCK indefinitely) + QXSemaphore_wait(&TH_sema, QXTHREAD_NO_TIMEOUT); + + QXMutex_lock(&TH_mutex, QXTHREAD_NO_TIMEOUT); // lock the mutex + QXThread_delay(5U); // wait more (BLOCK) + QXMutex_unlock(&TH_mutex); + } +} diff --git a/examples/arm-cm/dpp_nucleo-l053r8/stm32-nucleo-l053r8.jpg b/examples/arm-cm/dpp_nucleo-l053r8/stm32-nucleo-l053r8.jpg new file mode 100644 index 00000000..1c7c4159 Binary files /dev/null and b/examples/arm-cm/dpp_nucleo-l053r8/stm32-nucleo-l053r8.jpg differ diff --git a/examples/arm-cm/dpp_nucleo-l053r8/table.c b/examples/arm-cm/dpp_nucleo-l053r8/table.c index edfc073a..c3ae02f0 100644 --- a/examples/arm-cm/dpp_nucleo-l053r8/table.c +++ b/examples/arm-cm/dpp_nucleo-l053r8/table.c @@ -1,124 +1,130 @@ -/*$file${.::table.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* -* Model: dpp.qm -* File: ${.::table.c} -* -* This code has been generated by QM 5.2.4 . -* DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. -* -* SPDX-License-Identifier: GPL-3.0-or-later -* -* This generated code is open source software: you can redistribute it under -* the terms of the GNU General Public License as published by the Free -* Software Foundation. -* -* This code is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -* more details. -* -* NOTE: -* Alternatively, this generated code may be distributed under the terms -* of Quantum Leaps commercial licenses, which expressly supersede the GNU -* General Public License and are specifically designed for licensees -* interested in retaining the proprietary status of their code. -* -* Contact information: -* -* -*/ -/*$endhead${.::table.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -#include "qpc.h" -#include "dpp.h" -#include "bsp.h" +//$file${.::table.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// +// Model: dpp.qm +// File: ${.::table.c} +// +// This code has been generated by QM 5.3.0 . +// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. +// +// SPDX-License-Identifier: GPL-3.0-or-later +// +// This generated code is open source software: you can redistribute it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation. +// +// This code is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// NOTE: +// Alternatively, this generated code may be distributed under the terms +// of Quantum Leaps commercial licenses, which expressly supersede the GNU +// General Public License and are specifically designed for licensees +// interested in retaining the proprietary status of their code. +// +// Contact information: +// +// +// +//$endhead${.::table.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +#include "qpc.h" // QP/C real-time embedded framework +#include "dpp.h" // DPP Application interface +#include "bsp.h" // Board Support Package -Q_DEFINE_THIS_FILE +//$declare${AOs::Table} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/* Active object class -----------------------------------------------------*/ -/*$declare${AOs::Table} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${AOs::Table} ............................................................*/ +//${AOs::Table} .............................................................. typedef struct Table { -/* protected: */ +// protected: QActive super; -/* public: */ - -/* private: */ +// private: uint8_t fork[N_PHILO]; - uint8_t isHungry[N_PHILO]; + bool isHungry[N_PHILO]; + +// public: } Table; + extern Table Table_inst; -/* protected: */ +// protected: static QState Table_initial(Table * const me, void const * const par); static QState Table_active(Table * const me, QEvt const * const e); static QState Table_serving(Table * const me, QEvt const * const e); static QState Table_paused(Table * const me, QEvt const * const e); -/*$enddecl${AOs::Table} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$enddecl${AOs::Table} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -#define RIGHT(n_) ((uint8_t)(((n_) + (N_PHILO - 1U)) % N_PHILO)) -#define LEFT(n_) ((uint8_t)(((n_) + 1U) % N_PHILO)) -#define FREE ((uint8_t)0) -#define USED ((uint8_t)1) +//---------------------------------------------------------------------------- +Q_DEFINE_THIS_FILE -/*$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* Check for the minimum required QP version */ -#if (QP_VERSION < 700U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) -#error qpc version 7.0.0 or higher required +// helper function to provide the RIGHT neighbor of a Philo[n] +static inline uint8_t right(uint8_t const n) { + return (uint8_t)((n + (N_PHILO - 1U)) % N_PHILO); +} + +// helper function to provide the LEFT neighbor of a Philo[n] +static inline uint8_t left(uint8_t const n) { + return (uint8_t)((n + 1U) % N_PHILO); +} + +#define FREE ((uint8_t)0U) +#define USED ((uint8_t)1U) + +#define THINKING "thinking" +#define HUNGRY "hungry " +#define EATING "eating " + +//---------------------------------------------------------------------------- + +//$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// Check for the minimum required QP version +#if (QP_VERSION < 730U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) +#error qpc version 7.3.0 or higher required #endif -/*$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -/*$define${AOs::AO_Table} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//$define${Shared::Table_ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/*${AOs::AO_Table} .........................................................*/ -QActive * const AO_Table = &Table_inst.super; /* "opaque" pointer to Table AO */ -/*$enddef${AOs::AO_Table} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*$define${AOs::Table_ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${AOs::Table_ctor} .......................................................*/ +//${Shared::Table_ctor} ...................................................... void Table_ctor(void) { - Table *me = &Table_inst; - uint8_t n; - + Table * const me = &Table_inst; QActive_ctor(&me->super, Q_STATE_CAST(&Table_initial)); - - for (n = 0U; n < N_PHILO; ++n) { + for (uint8_t n = 0U; n < N_PHILO; ++n) { me->fork[n] = FREE; - me->isHungry[n] = 0U; + me->isHungry[n] = false; } } -/*$enddef${AOs::Table_ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*$define${AOs::Table} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//$enddef${Shared::Table_ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +//$define${Shared::AO_Table} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/*${AOs::Table} ............................................................*/ +//${Shared::AO_Table} ........................................................ +QActive * const AO_Table = &Table_inst.super; +//$enddef${Shared::AO_Table} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +//$define${AOs::Table} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${AOs::Table} .............................................................. Table Table_inst; -/*${AOs::Table::SM} ........................................................*/ +//${AOs::Table::SM} .......................................................... static QState Table_initial(Table * const me, void const * const par) { - /*${AOs::Table::SM::initial} */ - uint8_t n; - (void)par; /* unused parameter */ + //${AOs::Table::SM::initial} + Q_UNUSED_PAR(par); - QS_OBJ_DICTIONARY(&Table_inst); - - QS_SIG_DICTIONARY(DONE_SIG, (void *)0); /* global signals */ - QS_SIG_DICTIONARY(EAT_SIG, (void *)0); - QS_SIG_DICTIONARY(PAUSE_SIG, (void *)0); - QS_SIG_DICTIONARY(SERVE_SIG, (void *)0); - QS_SIG_DICTIONARY(TEST_SIG, (void *)0); - - QS_SIG_DICTIONARY(HUNGRY_SIG, me); /* signal just for Table */ + #ifdef Q_SPY + Table *Table_inst = me; + QS_OBJ_DICTIONARY(Table_inst); + #endif QActive_subscribe(&me->super, DONE_SIG); QActive_subscribe(&me->super, PAUSE_SIG); QActive_subscribe(&me->super, SERVE_SIG); QActive_subscribe(&me->super, TEST_SIG); - for (n = 0U; n < N_PHILO; ++n) { + for (uint8_t n = 0U; n < N_PHILO; ++n) { me->fork[n] = FREE; - me->isHungry[n] = 0U; - BSP_displayPhilStat(n, "thinking"); + me->isHungry[n] = false; + BSP_displayPhilStat(n, THINKING); } QS_FUN_DICTIONARY(&Table_active); @@ -128,16 +134,16 @@ static QState Table_initial(Table * const me, void const * const par) { return Q_TRAN(&Table_serving); } -/*${AOs::Table::SM::active} ................................................*/ +//${AOs::Table::SM::active} .................................................. static QState Table_active(Table * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${AOs::Table::SM::active::TEST} */ + //${AOs::Table::SM::active::TEST} case TEST_SIG: { status_ = Q_HANDLED(); break; } - /*${AOs::Table::SM::active::EAT} */ + //${AOs::Table::SM::active::EAT} case EAT_SIG: { Q_ERROR(); status_ = Q_HANDLED(); @@ -151,108 +157,119 @@ static QState Table_active(Table * const me, QEvt const * const e) { return status_; } -/*${AOs::Table::SM::active::serving} .......................................*/ +//${AOs::Table::SM::active::serving} ......................................... static QState Table_serving(Table * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${AOs::Table::SM::active::serving} */ + //${AOs::Table::SM::active::serving} case Q_ENTRY_SIG: { - uint8_t n; - for (n = 0U; n < N_PHILO; ++n) { /* give permissions to eat... */ - if ((me->isHungry[n] != 0U) - && (me->fork[LEFT(n)] == FREE) + // give permissions to eat... + for (uint8_t n = 0U; n < N_PHILO; ++n) { + if (me->isHungry[n] + && (me->fork[left(n)] == FREE) && (me->fork[n] == FREE)) { - TableEvt *te; - - me->fork[LEFT(n)] = USED; + me->fork[left(n)] = USED; me->fork[n] = USED; - te = Q_NEW(TableEvt, EAT_SIG); - te->philoNum = n; - QACTIVE_PUBLISH(&te->super, &me->super); - me->isHungry[n] = 0U; - BSP_displayPhilStat(n, "eating "); + #ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, EAT_SIG, n); + #else + TableEvt *pe = Q_NEW(TableEvt, EAT_SIG); + pe->philoId = n; + #endif + QACTIVE_PUBLISH(&pe->super, &me->super); + me->isHungry[n] = false; + BSP_displayPhilStat(n, EATING); } } status_ = Q_HANDLED(); break; } - /*${AOs::Table::SM::active::serving::HUNGRY} */ + //${AOs::Table::SM::active::serving::HUNGRY} case HUNGRY_SIG: { - uint8_t n, m; + uint8_t n = Q_EVT_CAST(TableEvt)->philoId; - n = Q_EVT_CAST(TableEvt)->philoNum; - /* phil ID must be in range and he must be not hungry */ - Q_ASSERT((n < N_PHILO) && (me->isHungry[n] == 0U)); + // phil ID must be in range and he must be not hungry + Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); - BSP_displayPhilStat(n, "hungry "); - m = LEFT(n); - /*${AOs::Table::SM::active::serving::HUNGRY::[bothfree]} */ + BSP_displayPhilStat(n, HUNGRY); + uint8_t m = left(n); + //${AOs::Table::SM::active::serving::HUNGRY::[bothfree]} if ((me->fork[m] == FREE) && (me->fork[n] == FREE)) { - TableEvt *pe; me->fork[m] = USED; me->fork[n] = USED; - pe = Q_NEW(TableEvt, EAT_SIG); - pe->philoNum = n; + #ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, EAT_SIG, n); + #else + TableEvt *pe = Q_NEW(TableEvt, EAT_SIG); + pe->philoId = n; + #endif QACTIVE_PUBLISH(&pe->super, &me->super); - BSP_displayPhilStat(n, "eating "); + BSP_displayPhilStat(n, EATING); status_ = Q_HANDLED(); } - /*${AOs::Table::SM::active::serving::HUNGRY::[else]} */ + //${AOs::Table::SM::active::serving::HUNGRY::[else]} else { - me->isHungry[n] = 1U; + me->isHungry[n] = true; status_ = Q_HANDLED(); } break; } - /*${AOs::Table::SM::active::serving::DONE} */ + //${AOs::Table::SM::active::serving::DONE} case DONE_SIG: { - uint8_t n, m; - TableEvt *pe; + uint8_t n = Q_EVT_CAST(TableEvt)->philoId; - n = Q_EVT_CAST(TableEvt)->philoNum; - /* phil ID must be in range and he must be not hungry */ - Q_ASSERT((n < N_PHILO) && (me->isHungry[n] == 0U)); + // phil ID must be in range and he must be not hungry + Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); - BSP_displayPhilStat(n, "thinking"); - m = LEFT(n); - /* both forks of Phil[n] must be used */ + BSP_displayPhilStat(n, THINKING); + uint8_t m = left(n); + + // both forks of Phil[n] must be used Q_ASSERT((me->fork[n] == USED) && (me->fork[m] == USED)); me->fork[m] = FREE; me->fork[n] = FREE; - m = RIGHT(n); /* check the right neighbor */ + m = right(n); // check the right neighbor - if ((me->isHungry[m] != 0U) && (me->fork[m] == FREE)) { + if (me->isHungry[m] && (me->fork[m] == FREE)) { me->fork[n] = USED; me->fork[m] = USED; - me->isHungry[m] = 0U; - pe = Q_NEW(TableEvt, EAT_SIG); - pe->philoNum = m; + me->isHungry[m] = false; + #ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, EAT_SIG, m); + #else + TableEvt *pe = Q_NEW(TableEvt, EAT_SIG); + pe->philoId = m; + #endif QACTIVE_PUBLISH(&pe->super, &me->super); - BSP_displayPhilStat(m, "eating "); + BSP_displayPhilStat(m, EATING); } - m = LEFT(n); /* check the left neighbor */ - n = LEFT(m); /* left fork of the left neighbor */ - if ((me->isHungry[m] != 0U) && (me->fork[n] == FREE)) { + m = left(n); // check the left neighbor + n = left(m); // left fork of the left neighbor + if (me->isHungry[m] && (me->fork[n] == FREE)) { me->fork[m] = USED; me->fork[n] = USED; - me->isHungry[m] = 0U; - pe = Q_NEW(TableEvt, EAT_SIG); - pe->philoNum = m; + me->isHungry[m] = false; + #ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, EAT_SIG, m); + #else + TableEvt *pe = Q_NEW(TableEvt, EAT_SIG); + pe->philoId = m; + #endif QACTIVE_PUBLISH(&pe->super, &me->super); - BSP_displayPhilStat(m, "eating "); + BSP_displayPhilStat(m, EATING); } status_ = Q_HANDLED(); break; } - /*${AOs::Table::SM::active::serving::EAT} */ + //${AOs::Table::SM::active::serving::EAT} case EAT_SIG: { Q_ERROR(); status_ = Q_HANDLED(); break; } - /*${AOs::Table::SM::active::serving::PAUSE} */ + //${AOs::Table::SM::active::serving::PAUSE} case PAUSE_SIG: { status_ = Q_TRAN(&Table_paused); break; @@ -265,48 +282,50 @@ static QState Table_serving(Table * const me, QEvt const * const e) { return status_; } -/*${AOs::Table::SM::active::paused} ........................................*/ +//${AOs::Table::SM::active::paused} .......................................... static QState Table_paused(Table * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${AOs::Table::SM::active::paused} */ + //${AOs::Table::SM::active::paused} case Q_ENTRY_SIG: { BSP_displayPaused(1U); status_ = Q_HANDLED(); break; } - /*${AOs::Table::SM::active::paused} */ + //${AOs::Table::SM::active::paused} case Q_EXIT_SIG: { BSP_displayPaused(0U); status_ = Q_HANDLED(); break; } - /*${AOs::Table::SM::active::paused::SERVE} */ + //${AOs::Table::SM::active::paused::SERVE} case SERVE_SIG: { status_ = Q_TRAN(&Table_serving); break; } - /*${AOs::Table::SM::active::paused::HUNGRY} */ + //${AOs::Table::SM::active::paused::HUNGRY} case HUNGRY_SIG: { - uint8_t n = Q_EVT_CAST(TableEvt)->philoNum; - /* philo ID must be in range and he must be not hungry */ - Q_ASSERT((n < N_PHILO) && (me->isHungry[n] == 0U)); - me->isHungry[n] = 1U; - BSP_displayPhilStat(n, "hungry "); + uint8_t n = Q_EVT_CAST(TableEvt)->philoId; + + // philo ID must be in range and he must be not hungry + Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); + + me->isHungry[n] = true; + BSP_displayPhilStat(n, HUNGRY); status_ = Q_HANDLED(); break; } - /*${AOs::Table::SM::active::paused::DONE} */ + //${AOs::Table::SM::active::paused::DONE} case DONE_SIG: { - uint8_t n, m; + uint8_t n = Q_EVT_CAST(TableEvt)->philoId; - n = Q_EVT_CAST(TableEvt)->philoNum; - /* phil ID must be in range and he must be not hungry */ - Q_ASSERT((n < N_PHILO) && (me->isHungry[n] == 0U)); + // phil ID must be in range and he must be not hungry + Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); - BSP_displayPhilStat(n, "thinking"); - m = LEFT(n); - /* both forks of Phil[n] must be used */ + BSP_displayPhilStat(n, THINKING); + uint8_t m = left(n); + + // both forks of Phil[n] must be used Q_ASSERT((me->fork[n] == USED) && (me->fork[m] == USED)); me->fork[m] = FREE; @@ -321,4 +340,4 @@ static QState Table_paused(Table * const me, QEvt const * const e) { } return status_; } -/*$enddef${AOs::Table} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$enddef${AOs::Table} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/examples/arm-cm/dpp_nucleo-l152re/README.md b/examples/arm-cm/dpp_nucleo-l152re/README.md deleted file mode 100644 index 7c6a2197..00000000 --- a/examples/arm-cm/dpp_nucleo-l152re/README.md +++ /dev/null @@ -1,5 +0,0 @@ -![STM32 NUCLEO-L552ZE Q](../../../doxygen/images/bd_NUCLEO-L152RE.jpg) - -Documentation for this example is available in the QP/C Manual at: - -- https://www.state-machine.com/qpc/arm-cm_dpp_nucleo-l152re.html diff --git a/examples/arm-cm/dpp_nucleo-l152re/bsp.h b/examples/arm-cm/dpp_nucleo-l152re/bsp.h index 213b2dc1..fe8149a3 100644 --- a/examples/arm-cm/dpp_nucleo-l152re/bsp.h +++ b/examples/arm-cm/dpp_nucleo-l152re/bsp.h @@ -1,54 +1,49 @@ -/***************************************************************************** -* Product: DPP example -* Last Updated for Version: 5.9.9 -* Date of the Last Update: 2017-10-09 -* -* Q u a n t u m L e a P s -* --------------------------- -* innovating embedded systems -* -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* -* -*****************************************************************************/ -#ifndef BSP_H -#define BSP_H +//============================================================================ +// Product: DPP example +// Last Updated for Version: 7.3.0 +// Date of the Last Update: 2023-06-27 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +//============================================================================ +#ifndef BSP_H_ +#define BSP_H_ #define BSP_TICKS_PER_SEC 100U void BSP_init(void); +void BSP_start(void); void BSP_displayPaused(uint8_t paused); void BSP_displayPhilStat(uint8_t n, char const *stat); void BSP_terminate(int16_t result); -void BSP_randomSeed(uint32_t seed); /* random seed */ -uint32_t BSP_random(void); /* pseudo-random generator */ +void BSP_randomSeed(uint32_t seed); // random seed +uint32_t BSP_random(void); // pseudo-random generator -/* for testing... */ -void BSP_wait4SW1(void); void BSP_ledOn(void); void BSP_ledOff(void); -extern QActive *the_Ticker0; - -#endif /* BSP_H */ +#endif // BSP_H_ diff --git a/examples/arm-cm/dpp_nucleo-l152re/dpp.h b/examples/arm-cm/dpp_nucleo-l152re/dpp.h index da094c2c..e6d1557a 100644 --- a/examples/arm-cm/dpp_nucleo-l152re/dpp.h +++ b/examples/arm-cm/dpp_nucleo-l152re/dpp.h @@ -1,92 +1,117 @@ -/*$file${.::dpp.h} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* -* Model: dpp.qm -* File: ${.::dpp.h} -* -* This code has been generated by QM 5.2.4 . -* DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. -* -* SPDX-License-Identifier: GPL-3.0-or-later -* -* This generated code is open source software: you can redistribute it under -* the terms of the GNU General Public License as published by the Free -* Software Foundation. -* -* This code is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -* more details. -* -* NOTE: -* Alternatively, this generated code may be distributed under the terms -* of Quantum Leaps commercial licenses, which expressly supersede the GNU -* General Public License and are specifically designed for licensees -* interested in retaining the proprietary status of their code. -* -* Contact information: -* -* -*/ -/*$endhead${.::dpp.h} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -#ifndef DPP_H -#define DPP_H +//$file${.::dpp.h} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// +// Model: dpp.qm +// File: ${.::dpp.h} +// +// This code has been generated by QM 5.3.0 . +// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. +// +// SPDX-License-Identifier: GPL-3.0-or-later +// +// This generated code is open source software: you can redistribute it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation. +// +// This code is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// NOTE: +// Alternatively, this generated code may be distributed under the terms +// of Quantum Leaps commercial licenses, which expressly supersede the GNU +// General Public License and are specifically designed for licensees +// interested in retaining the proprietary status of their code. +// +// Contact information: +// +// +// +//$endhead${.::dpp.h} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +#ifndef DPP_H_ +#define DPP_H_ -enum DPPSignals { - EAT_SIG = Q_USER_SIG, /* published by Table to let a philosopher eat */ - DONE_SIG, /* published by Philosopher when done eating */ - PAUSE_SIG, /* published by BSP to pause serving forks */ - SERVE_SIG, /* published by BSP to serve re-start serving forks */ - TEST_SIG, /* published by BSP to test the application */ - MAX_PUB_SIG, /* the last published signal */ +//$declare${Shared} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv - HUNGRY_SIG, /* posted direclty to Table from hungry Philo */ - TIMEOUT_SIG, /* used by Philosophers for time events */ - MAX_SIG /* the last signal */ +//${Shared::AppSignals} ...................................................... +enum AppSignals { + EAT_SIG = Q_USER_SIG, // published by Table to let a Philo eat + DONE_SIG, // published by Philo when done eating + PAUSE_SIG, // published by BSP to pause the application + SERVE_SIG, // published by BSP to serve re-start serving forks + TEST_SIG, // published by BSP to test the application + MAX_PUB_SIG, // the last published signal + + TIMEOUT_SIG, // posted by time event to Philo + HUNGRY_SIG, // posted by hungry Philo to Table + MAX_SIG // the last signal }; -/*$declare${Events::TableEvt} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//${Shared::produce_sig_dict} ................................................ +#ifdef Q_SPY +static inline void produce_sig_dict(void) { + QS_SIG_DICTIONARY(EAT_SIG, (void *)0); + QS_SIG_DICTIONARY(DONE_SIG, (void *)0); + QS_SIG_DICTIONARY(PAUSE_SIG, (void *)0); + QS_SIG_DICTIONARY(SERVE_SIG, (void *)0); + QS_SIG_DICTIONARY(TEST_SIG, (void *)0); -/*${Events::TableEvt} ......................................................*/ + QS_SIG_DICTIONARY(TIMEOUT_SIG, (void *)0); + QS_SIG_DICTIONARY(HUNGRY_SIG, (void *)0); +} +#endif // def Q_SPY + +//${Shared::N_PHILO} ......................................................... +#define N_PHILO ((uint8_t)5U) + +//${Shared::TableEvt} ........................................................ typedef struct { -/* protected: */ +// protected: QEvt super; -/* public: */ - uint8_t philoNum; +// public: + uint8_t philoId; } TableEvt; -/*$enddecl${Events::TableEvt} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/* number of philosophers */ -#define N_PHILO ((uint8_t)5) +// public: -/*$declare${AOs::Philo_ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +#ifdef QEVT_DYN_CTOR +static inline TableEvt * TableEvt_ctor(TableEvt * const me, + uint8_t id) +{ + if (me != (TableEvt *)0) { + // don't call QEvt_ctor() because the initialization of all + // QEvt attributes is already done in QF_QF_newX_() + me->philoId = id; + } + return me; +} +#endif // def QEVT_DYN_CTOR -/*${AOs::Philo_ctor} .......................................................*/ -void Philo_ctor(void); -/*$enddecl${AOs::Philo_ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*$declare${AOs::AO_Philo[N_PHILO]} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${AOs::AO_Philo[N_PHILO]} ................................................*/ +//${Shared::AO_Philo[N_PHILO]} ............................................... extern QActive * const AO_Philo[N_PHILO]; -/*$enddecl${AOs::AO_Philo[N_PHILO]} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*$declare${AOs::Table_ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//${Shared::Philo_ctor} ...................................................... +void Philo_ctor(uint_fast8_t const id); -/*${AOs::Table_ctor} .......................................................*/ -void Table_ctor(void); -/*$enddecl${AOs::Table_ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*$declare${AOs::AO_Table} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${AOs::AO_Table} .........................................................*/ +//${Shared::AO_Table} ........................................................ extern QActive * const AO_Table; -/*$enddecl${AOs::AO_Table} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -#ifdef QP_INC_QXK_H_ - void Test1_ctor(void); - extern QXThread * const XT_Test1; - void Test2_ctor(void); - extern QXThread * const XT_Test2; -#endif /* QP_INC_QXK_H_ */ +//${Shared::Table_ctor} ...................................................... +void Table_ctor(void); +//$enddecl${Shared} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -#endif /* DPP_H */ +#ifdef QXK_H_ +extern QXThread * const TH_XThread1; +void XThread1_ctor(void); + +extern QXThread * const TH_XThread2; +void XThread2_ctor(void); + +extern QXSemaphore TH_sema; +extern QXMutex TH_mutex; + +#endif // QXK_H_ + +#endif // DPP_H_ diff --git a/examples/arm-cm/dpp_nucleo-l152re/dpp.qm b/examples/arm-cm/dpp_nucleo-l152re/dpp.qm index f1256b39..ac9f2bc9 100644 --- a/examples/arm-cm/dpp_nucleo-l152re/dpp.qm +++ b/examples/arm-cm/dpp_nucleo-l152re/dpp.qm @@ -1,185 +1,242 @@ - + Dining Philosopher Problem example - - - + + + + + { + EAT_SIG = Q_USER_SIG, // published by Table to let a Philo eat + DONE_SIG, // published by Philo when done eating + PAUSE_SIG, // published by BSP to pause the application + SERVE_SIG, // published by BSP to serve re-start serving forks + TEST_SIG, // published by BSP to test the application + MAX_PUB_SIG, // the last published signal + + TIMEOUT_SIG, // posted by time event to Philo + HUNGRY_SIG, // posted by hungry Philo to Table + MAX_SIG // the last signal +}; + + + + QS_SIG_DICTIONARY(EAT_SIG, (void *)0); +QS_SIG_DICTIONARY(DONE_SIG, (void *)0); +QS_SIG_DICTIONARY(PAUSE_SIG, (void *)0); +QS_SIG_DICTIONARY(SERVE_SIG, (void *)0); +QS_SIG_DICTIONARY(TEST_SIG, (void *)0); + +QS_SIG_DICTIONARY(TIMEOUT_SIG, (void *)0); +QS_SIG_DICTIONARY(HUNGRY_SIG, (void *)0); + + + + ((uint8_t)5U) + + - - + + + + + + + if (me != (TableEvt *)0) { + // don't call QEvt_ctor() because the initialization of all + // QEvt attributes is already done in QF_QF_newX_() + me->philoId = id; +} +return me; + + + + = { + &Philo_inst[0].super, + &Philo_inst[1].super, + &Philo_inst[2].super, + &Philo_inst[3].super, + &Philo_inst[4].super +}; + + + + + + Philo * const me = &Philo_inst[id]; +QActive_ctor(&me->super, Q_STATE_CAST(&Philo_initial)); +QTimeEvt_ctorX(&me->timeEvt, &me->super, TIMEOUT_SIG, 0U), +me->id = (uint8_t)id; + + + + = &Table_inst.super; + + + + Table * const me = &Table_inst; +QActive_ctor(&me->super, Q_STATE_CAST(&Table_initial)); +for (uint8_t n = 0U; n < N_PHILO; ++n) { + me->fork[n] = FREE; + me->isHungry[n] = false; +} + - - - The array of static insts of the Philo class (Singleton pattern) - + The Philo AO and the N_PHILO instances + + + + - + - static uint8_t registered = (uint8_t)0; /* starts off with 0, per C-standard */ -(void)par; /* unused parameter */ -if (registered == (uint8_t)0) { - registered = (uint8_t)1; + Q_UNUSED_PAR(par); - QS_OBJ_DICTIONARY(&Philo_inst[0]); - QS_OBJ_DICTIONARY(&Philo_inst[0].timeEvt); - QS_OBJ_DICTIONARY(&Philo_inst[1]); - QS_OBJ_DICTIONARY(&Philo_inst[1].timeEvt); - QS_OBJ_DICTIONARY(&Philo_inst[2]); - QS_OBJ_DICTIONARY(&Philo_inst[2].timeEvt); - QS_OBJ_DICTIONARY(&Philo_inst[3]); - QS_OBJ_DICTIONARY(&Philo_inst[3].timeEvt); - QS_OBJ_DICTIONARY(&Philo_inst[4]); - QS_OBJ_DICTIONARY(&Philo_inst[4].timeEvt); - - QS_FUN_DICTIONARY(&Philo_initial); - QS_FUN_DICTIONARY(&Philo_thinking); - QS_FUN_DICTIONARY(&Philo_hungry); - QS_FUN_DICTIONARY(&Philo_eating); -} -QS_SIG_DICTIONARY(HUNGRY_SIG, me); /* signal for each Philos */ -QS_SIG_DICTIONARY(TIMEOUT_SIG, me); /* signal for each Philos */ +QS_OBJ_ARR_DICTIONARY(&Philo_inst[me->id], me->id); +QS_OBJ_ARR_DICTIONARY(&Philo_inst[me->id].timeEvt, me->id); QActive_subscribe(&me->super, EAT_SIG); QActive_subscribe(&me->super, TEST_SIG); - + - QTimeEvt_armX(&me->timeEvt, THINK_TIME, 0U); - QTimeEvt_disarm(&me->timeEvt); + QTimeEvt_armX(&me->timeEvt, think_time(), 0U); + (void)QTimeEvt_disarm(&me->timeEvt); - - + + - /* EAT or DONE must be for other Philos than this one */ -Q_ASSERT(Q_EVT_CAST(TableEvt)->philoNum != PHILO_ID(me)); - + // EAT or DONE must be for other Philos than this one +Q_ASSERT(Q_EVT_CAST(TableEvt)->philoId != me->id); + - + - + - + - TableEvt *pe = Q_NEW(TableEvt, HUNGRY_SIG); -pe->philoNum = PHILO_ID(me); -QACTIVE_POST(AO_Table, &pe->super, me); + #ifdef QEVT_DYN_CTOR +TableEvt const *pe = Q_NEW(TableEvt, HUNGRY_SIG, me->id); +#else +TableEvt *pe = Q_NEW(TableEvt, HUNGRY_SIG); +pe->philoId = me->id; +#endif +QACTIVE_POST(AO_Table, &pe->super, &me->super); - + - Q_EVT_CAST(TableEvt)->philoNum == PHILO_ID(me) - - + Q_EVT_CAST(TableEvt)->philoId == me->id + + - + - /* DONE must be for other Philos than this one */ -Q_ASSERT(Q_EVT_CAST(TableEvt)->philoNum != PHILO_ID(me)); - + // DONE must be for other Philos than this one +Q_ASSERT(Q_EVT_CAST(TableEvt)->philoId != me->id); + - + - QTimeEvt_armX(&me->timeEvt, EAT_TIME, 0U); - TableEvt *pe = Q_NEW(TableEvt, DONE_SIG); -pe->philoNum = PHILO_ID(me); + QTimeEvt_armX(&me->timeEvt, eat_time(), 0U); + (void)QTimeEvt_disarm(&me->timeEvt); + +#ifdef QEVT_DYN_CTOR +TableEvt const *pe = Q_NEW(TableEvt, DONE_SIG, me->id); +#else +TableEvt *pe = Q_NEW(TableEvt, DONE_SIG); +pe->philoId = me->id; +#endif QACTIVE_PUBLISH(&pe->super, &me->super); - - + + - /* EAT or DONE must be for other Philos than this one */ -Q_ASSERT(Q_EVT_CAST(TableEvt)->philoNum != PHILO_ID(me)); - + // EAT or DONE must be for other Philos than this one +Q_ASSERT(Q_EVT_CAST(TableEvt)->philoId != me->id); + - + - + - - - The only static inst of the Table class (Singleton pattern) - - + + + - + - uint8_t n; -(void)par; /* unused parameter */ + Q_UNUSED_PAR(par); -QS_OBJ_DICTIONARY(&Table_inst); - -QS_SIG_DICTIONARY(DONE_SIG, (void *)0); /* global signals */ -QS_SIG_DICTIONARY(EAT_SIG, (void *)0); -QS_SIG_DICTIONARY(PAUSE_SIG, (void *)0); -QS_SIG_DICTIONARY(SERVE_SIG, (void *)0); -QS_SIG_DICTIONARY(TEST_SIG, (void *)0); - -QS_SIG_DICTIONARY(HUNGRY_SIG, me); /* signal just for Table */ +#ifdef Q_SPY +Table *Table_inst = me; +QS_OBJ_DICTIONARY(Table_inst); +#endif QActive_subscribe(&me->super, DONE_SIG); QActive_subscribe(&me->super, PAUSE_SIG); QActive_subscribe(&me->super, SERVE_SIG); QActive_subscribe(&me->super, TEST_SIG); -for (n = 0U; n < N_PHILO; ++n) { +for (uint8_t n = 0U; n < N_PHILO; ++n) { me->fork[n] = FREE; - me->isHungry[n] = 0U; - BSP_displayPhilStat(n, "thinking"); + me->isHungry[n] = false; + BSP_displayPhilStat(n, THINKING); } - + @@ -187,128 +244,139 @@ for (n = 0U; n < N_PHILO; ++n) { - + Q_ERROR(); - + - uint8_t n; -for (n = 0U; n < N_PHILO; ++n) { /* give permissions to eat... */ - if ((me->isHungry[n] != 0U) - && (me->fork[LEFT(n)] == FREE) + // give permissions to eat... +for (uint8_t n = 0U; n < N_PHILO; ++n) { + if (me->isHungry[n] + && (me->fork[left(n)] == FREE) && (me->fork[n] == FREE)) { - TableEvt *te; - - me->fork[LEFT(n)] = USED; + me->fork[left(n)] = USED; me->fork[n] = USED; - te = Q_NEW(TableEvt, EAT_SIG); - te->philoNum = n; - QACTIVE_PUBLISH(&te->super, &me->super); - me->isHungry[n] = 0U; - BSP_displayPhilStat(n, "eating "); +#ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, EAT_SIG, n); +#else + TableEvt *pe = Q_NEW(TableEvt, EAT_SIG); + pe->philoId = n; +#endif + QACTIVE_PUBLISH(&pe->super, &me->super); + me->isHungry[n] = false; + BSP_displayPhilStat(n, EATING); } } - uint8_t n, m; + uint8_t n = Q_EVT_CAST(TableEvt)->philoId; -n = Q_EVT_CAST(TableEvt)->philoNum; -/* phil ID must be in range and he must be not hungry */ -Q_ASSERT((n < N_PHILO) && (me->isHungry[n] == 0U)); +// phil ID must be in range and he must be not hungry +Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); -BSP_displayPhilStat(n, "hungry "); -m = LEFT(n); +BSP_displayPhilStat(n, HUNGRY); +uint8_t m = left(n); (me->fork[m] == FREE) && (me->fork[n] == FREE) - TableEvt *pe; -me->fork[m] = USED; + me->fork[m] = USED; me->fork[n] = USED; -pe = Q_NEW(TableEvt, EAT_SIG); -pe->philoNum = n; +#ifdef QEVT_DYN_CTOR +TableEvt const *pe = Q_NEW(TableEvt, EAT_SIG, n); +#else +TableEvt *pe = Q_NEW(TableEvt, EAT_SIG); +pe->philoId = n; +#endif QACTIVE_PUBLISH(&pe->super, &me->super); -BSP_displayPhilStat(n, "eating "); - +BSP_displayPhilStat(n, EATING); + else - me->isHungry[n] = 1U; - - + me->isHungry[n] = true; + + - + - uint8_t n, m; -TableEvt *pe; + uint8_t n = Q_EVT_CAST(TableEvt)->philoId; -n = Q_EVT_CAST(TableEvt)->philoNum; -/* phil ID must be in range and he must be not hungry */ -Q_ASSERT((n < N_PHILO) && (me->isHungry[n] == 0U)); +// phil ID must be in range and he must be not hungry +Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); -BSP_displayPhilStat(n, "thinking"); -m = LEFT(n); -/* both forks of Phil[n] must be used */ +BSP_displayPhilStat(n, THINKING); +uint8_t m = left(n); + +// both forks of Phil[n] must be used Q_ASSERT((me->fork[n] == USED) && (me->fork[m] == USED)); me->fork[m] = FREE; me->fork[n] = FREE; -m = RIGHT(n); /* check the right neighbor */ +m = right(n); // check the right neighbor -if ((me->isHungry[m] != 0U) && (me->fork[m] == FREE)) { +if (me->isHungry[m] && (me->fork[m] == FREE)) { me->fork[n] = USED; me->fork[m] = USED; - me->isHungry[m] = 0U; - pe = Q_NEW(TableEvt, EAT_SIG); - pe->philoNum = m; + me->isHungry[m] = false; +#ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, EAT_SIG, m); +#else + TableEvt *pe = Q_NEW(TableEvt, EAT_SIG); + pe->philoId = m; +#endif QACTIVE_PUBLISH(&pe->super, &me->super); - BSP_displayPhilStat(m, "eating "); + BSP_displayPhilStat(m, EATING); } -m = LEFT(n); /* check the left neighbor */ -n = LEFT(m); /* left fork of the left neighbor */ -if ((me->isHungry[m] != 0U) && (me->fork[n] == FREE)) { +m = left(n); // check the left neighbor +n = left(m); // left fork of the left neighbor +if (me->isHungry[m] && (me->fork[n] == FREE)) { me->fork[m] = USED; me->fork[n] = USED; - me->isHungry[m] = 0U; - pe = Q_NEW(TableEvt, EAT_SIG); - pe->philoNum = m; + me->isHungry[m] = false; +#ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, EAT_SIG, m); +#else + TableEvt *pe = Q_NEW(TableEvt, EAT_SIG); + pe->philoId = m; +#endif QACTIVE_PUBLISH(&pe->super, &me->super); - BSP_displayPhilStat(m, "eating "); + BSP_displayPhilStat(m, EATING); } - + Q_ERROR(); - + - + - + @@ -318,170 +386,140 @@ if ((me->isHungry[m] != 0U) && (me->fork[n] == FREE)) { BSP_displayPaused(0U); - + - uint8_t n = Q_EVT_CAST(TableEvt)->philoNum; -/* philo ID must be in range and he must be not hungry */ -Q_ASSERT((n < N_PHILO) && (me->isHungry[n] == 0U)); -me->isHungry[n] = 1U; -BSP_displayPhilStat(n, "hungry "); - + uint8_t n = Q_EVT_CAST(TableEvt)->philoId; + +// philo ID must be in range and he must be not hungry +Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); + +me->isHungry[n] = true; +BSP_displayPhilStat(n, HUNGRY); + - uint8_t n, m; + uint8_t n = Q_EVT_CAST(TableEvt)->philoId; -n = Q_EVT_CAST(TableEvt)->philoNum; -/* phil ID must be in range and he must be not hungry */ -Q_ASSERT((n < N_PHILO) && (me->isHungry[n] == 0U)); +// phil ID must be in range and he must be not hungry +Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); -BSP_displayPhilStat(n, "thinking"); -m = LEFT(n); -/* both forks of Phil[n] must be used */ +BSP_displayPhilStat(n, THINKING); +uint8_t m = left(n); + +// both forks of Phil[n] must be used Q_ASSERT((me->fork[n] == USED) && (me->fork[m] == USED)); me->fork[m] = FREE; me->fork[n] = FREE; - + - + - + - + - - - = { /* "opaque" pointers to Philo AO */ - &Philo_inst[0].super, - &Philo_inst[1].super, - &Philo_inst[2].super, - &Philo_inst[3].super, - &Philo_inst[4].super -}; - - - - = &Table_inst.super; /* "opaque" pointer to Table AO */ - - - - uint8_t n; -Philo *me; -for (n = 0U; n < N_PHILO; ++n) { - me = &Philo_inst[n]; - QActive_ctor(&me->super, Q_STATE_CAST(&Philo_initial)); - QTimeEvt_ctorX(&me->timeEvt, &me->super, TIMEOUT_SIG, 0U); -} - - - - Table *me = &Table_inst; -uint8_t n; - -QActive_ctor(&me->super, Q_STATE_CAST(&Table_initial)); - -for (n = 0U; n < N_PHILO; ++n) { - me->fork[n] = FREE; - me->isHungry[n] = 0U; -} - - #ifndef DPP_H -#define DPP_H + #ifndef DPP_H_ +#define DPP_H_ -enum DPPSignals { - EAT_SIG = Q_USER_SIG, /* published by Table to let a philosopher eat */ - DONE_SIG, /* published by Philosopher when done eating */ - PAUSE_SIG, /* published by BSP to pause serving forks */ - SERVE_SIG, /* published by BSP to serve re-start serving forks */ - TEST_SIG, /* published by BSP to test the application */ - MAX_PUB_SIG, /* the last published signal */ +$declare ${Shared} - HUNGRY_SIG, /* posted direclty to Table from hungry Philo */ - TIMEOUT_SIG, /* used by Philosophers for time events */ - MAX_SIG /* the last signal */ -}; +#ifdef QXK_H_ -$declare(Events::TableEvt) +extern QXThread * const TH_XThread1; +void XThread1_ctor(void); -/* number of philosophers */ -#define N_PHILO ((uint8_t)5) +extern QXThread * const TH_XThread2; +void XThread2_ctor(void); -$declare(AOs::Philo_ctor) -$declare(AOs::AO_Philo[N_PHILO]) +extern QXSemaphore TH_sema; +extern QXMutex TH_mutex; -$declare(AOs::Table_ctor) -$declare(AOs::AO_Table) +#endif // QXK_H_ -#ifdef QP_INC_QXK_H_ - void Test1_ctor(void); - extern QXThread * const XT_Test1; - void Test2_ctor(void); - extern QXThread * const XT_Test2; -#endif /* QP_INC_QXK_H_ */ - -#endif /* DPP_H */ - +#endif // DPP_H_ - #include "qpc.h" -#include "dpp.h" -#include "bsp.h" + #include "qpc.h" // QP/C real-time embedded framework +#include "dpp.h" // DPP Application interface +#include "bsp.h" // Board Support Package +$declare ${AOs::Philo} + +//---------------------------------------------------------------------------- Q_DEFINE_THIS_FILE -/* Active object class -----------------------------------------------------*/ -$declare${AOs::Philo} +// helper function to provide a randomized think time for Philos +static QTimeEvtCtr think_time(void); // prototype +static inline QTimeEvtCtr think_time(void) { + return (QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + + (BSP_TICKS_PER_SEC/2U)); +} -#define THINK_TIME \ - (QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + (BSP_TICKS_PER_SEC/2U)) -#define EAT_TIME \ - (QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + BSP_TICKS_PER_SEC) +// helper function to provide a randomized eat time for Philos +static QTimeEvtCtr eat_time(void); // prototype +static inline QTimeEvtCtr eat_time(void) { + return (QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + + BSP_TICKS_PER_SEC); +} +//---------------------------------------------------------------------------- -/* helper macro to provide the ID of Philo "me_" */ -#define PHILO_ID(me_) ((uint8_t)((me_) - &Philo_inst[0])) - -$define${AOs::AO_Philo[N_PHILO]} -$define${AOs::Philo_ctor} -$define${AOs::Philo} +$define ${Shared::Philo_ctor} +$define ${Shared::AO_Philo[N_PHILO]} +$define ${AOs::Philo} - #include "qpc.h" -#include "dpp.h" -#include "bsp.h" + #include "qpc.h" // QP/C real-time embedded framework +#include "dpp.h" // DPP Application interface +#include "bsp.h" // Board Support Package +$declare ${AOs::Table} + +//---------------------------------------------------------------------------- Q_DEFINE_THIS_FILE -/* Active object class -----------------------------------------------------*/ -$declare${AOs::Table} +// helper function to provide the RIGHT neighbor of a Philo[n] +static inline uint8_t right(uint8_t const n) { + return (uint8_t)((n + (N_PHILO - 1U)) % N_PHILO); +} -#define RIGHT(n_) ((uint8_t)(((n_) + (N_PHILO - 1U)) % N_PHILO)) -#define LEFT(n_) ((uint8_t)(((n_) + 1U) % N_PHILO)) -#define FREE ((uint8_t)0) -#define USED ((uint8_t)1) +// helper function to provide the LEFT neighbor of a Philo[n] +static inline uint8_t left(uint8_t const n) { + return (uint8_t)((n + 1U) % N_PHILO); +} -$define${AOs::AO_Table} -$define${AOs::Table_ctor} -$define${AOs::Table} +#define FREE ((uint8_t)0U) +#define USED ((uint8_t)1U) + +#define THINKING "thinking" +#define HUNGRY "hungry " +#define EATING "eating " + +//---------------------------------------------------------------------------- + +$define ${Shared::Table_ctor} +$define ${Shared::AO_Table} +$define ${AOs::Table} diff --git a/examples/arm-cm/dpp_nucleo-l152re/main.c b/examples/arm-cm/dpp_nucleo-l152re/main.c new file mode 100644 index 00000000..cfcfaf07 --- /dev/null +++ b/examples/arm-cm/dpp_nucleo-l152re/main.c @@ -0,0 +1,44 @@ +//============================================================================ +// APP example +// Last updated for version 7.3.0 +// Last updated on 2023-08-09 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. +// +// This program is open source software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Alternatively, this program may be distributed and modified under the +// terms of Quantum Leaps commercial licenses, which expressly supersede +// the GNU General Public License and are specifically designed for +// licensees interested in retaining the proprietary status of their code. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Contact information: +// +// +//============================================================================ +#include "qpc.h" // QP/C real-time embedded framework +#include "dpp.h" // DPP Application interface +#include "bsp.h" // Board Support Package + +//............................................................................ +int main() { + QF_init(); // initialize the framework and the underlying RT kernel + BSP_init(); // initialize the BSP + BSP_start(); // start the AOs/Threads + return QF_run(); // run the QF application +} diff --git a/examples/arm-cm/dpp_nucleo-l152re/philo.c b/examples/arm-cm/dpp_nucleo-l152re/philo.c index a5be8e68..eb6be531 100644 --- a/examples/arm-cm/dpp_nucleo-l152re/philo.c +++ b/examples/arm-cm/dpp_nucleo-l152re/philo.c @@ -1,167 +1,159 @@ -/*$file${.::philo.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* -* Model: dpp.qm -* File: ${.::philo.c} -* -* This code has been generated by QM 5.2.4 . -* DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. -* -* SPDX-License-Identifier: GPL-3.0-or-later -* -* This generated code is open source software: you can redistribute it under -* the terms of the GNU General Public License as published by the Free -* Software Foundation. -* -* This code is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -* more details. -* -* NOTE: -* Alternatively, this generated code may be distributed under the terms -* of Quantum Leaps commercial licenses, which expressly supersede the GNU -* General Public License and are specifically designed for licensees -* interested in retaining the proprietary status of their code. -* -* Contact information: -* -* -*/ -/*$endhead${.::philo.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -#include "qpc.h" -#include "dpp.h" -#include "bsp.h" +//$file${.::philo.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// +// Model: dpp.qm +// File: ${.::philo.c} +// +// This code has been generated by QM 5.3.0 . +// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. +// +// SPDX-License-Identifier: GPL-3.0-or-later +// +// This generated code is open source software: you can redistribute it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation. +// +// This code is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// NOTE: +// Alternatively, this generated code may be distributed under the terms +// of Quantum Leaps commercial licenses, which expressly supersede the GNU +// General Public License and are specifically designed for licensees +// interested in retaining the proprietary status of their code. +// +// Contact information: +// +// +// +//$endhead${.::philo.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +#include "qpc.h" // QP/C real-time embedded framework +#include "dpp.h" // DPP Application interface +#include "bsp.h" // Board Support Package -Q_DEFINE_THIS_FILE +//$declare${AOs::Philo} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/* Active object class -----------------------------------------------------*/ -/*$declare${AOs::Philo} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${AOs::Philo} ............................................................*/ +//${AOs::Philo} .............................................................. typedef struct Philo { -/* protected: */ +// protected: QActive super; -/* public: */ - -/* private: */ +// private: QTimeEvt timeEvt; + uint8_t id; + +// public: } Philo; + extern Philo Philo_inst[N_PHILO]; -/* protected: */ +// protected: static QState Philo_initial(Philo * const me, void const * const par); static QState Philo_thinking(Philo * const me, QEvt const * const e); static QState Philo_hungry(Philo * const me, QEvt const * const e); static QState Philo_eating(Philo * const me, QEvt const * const e); -/*$enddecl${AOs::Philo} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$enddecl${AOs::Philo} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -#define THINK_TIME \ - (QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + (BSP_TICKS_PER_SEC/2U)) -#define EAT_TIME \ - (QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + BSP_TICKS_PER_SEC) +//---------------------------------------------------------------------------- +Q_DEFINE_THIS_FILE -/* helper macro to provide the ID of Philo "me_" */ -#define PHILO_ID(me_) ((uint8_t)((me_) - &Philo_inst[0])) +// helper function to provide a randomized think time for Philos +static QTimeEvtCtr think_time(void); // prototype +static inline QTimeEvtCtr think_time(void) { + return (QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + + (BSP_TICKS_PER_SEC/2U)); +} -/*$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* Check for the minimum required QP version */ -#if (QP_VERSION < 700U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) -#error qpc version 7.0.0 or higher required +// helper function to provide a randomized eat time for Philos +static QTimeEvtCtr eat_time(void); // prototype +static inline QTimeEvtCtr eat_time(void) { + return (QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + + BSP_TICKS_PER_SEC); +} +//---------------------------------------------------------------------------- + +//$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// Check for the minimum required QP version +#if (QP_VERSION < 730U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) +#error qpc version 7.3.0 or higher required #endif -/*$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -/*$define${AOs::AO_Philo[N_PHILO]} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//$define${Shared::Philo_ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/*${AOs::AO_Philo[N_PHILO]} ................................................*/ -QActive * const AO_Philo[N_PHILO] = { /* "opaque" pointers to Philo AO */ +//${Shared::Philo_ctor} ...................................................... +void Philo_ctor(uint_fast8_t const id) { + Philo * const me = &Philo_inst[id]; + QActive_ctor(&me->super, Q_STATE_CAST(&Philo_initial)); + QTimeEvt_ctorX(&me->timeEvt, &me->super, TIMEOUT_SIG, 0U), + me->id = (uint8_t)id; +} +//$enddef${Shared::Philo_ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +//$define${Shared::AO_Philo[N_PHILO]} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${Shared::AO_Philo[N_PHILO]} ............................................... +QActive * const AO_Philo[N_PHILO] = { &Philo_inst[0].super, &Philo_inst[1].super, &Philo_inst[2].super, &Philo_inst[3].super, &Philo_inst[4].super }; -/*$enddef${AOs::AO_Philo[N_PHILO]} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*$define${AOs::Philo_ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//$enddef${Shared::AO_Philo[N_PHILO]} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +//$define${AOs::Philo} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/*${AOs::Philo_ctor} .......................................................*/ -void Philo_ctor(void) { - uint8_t n; - Philo *me; - for (n = 0U; n < N_PHILO; ++n) { - me = &Philo_inst[n]; - QActive_ctor(&me->super, Q_STATE_CAST(&Philo_initial)); - QTimeEvt_ctorX(&me->timeEvt, &me->super, TIMEOUT_SIG, 0U); - } -} -/*$enddef${AOs::Philo_ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*$define${AOs::Philo} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${AOs::Philo} ............................................................*/ +//${AOs::Philo} .............................................................. Philo Philo_inst[N_PHILO]; -/*${AOs::Philo::SM} ........................................................*/ +//${AOs::Philo::SM} .......................................................... static QState Philo_initial(Philo * const me, void const * const par) { - /*${AOs::Philo::SM::initial} */ - static uint8_t registered = (uint8_t)0; /* starts off with 0, per C-standard */ - (void)par; /* unused parameter */ - if (registered == (uint8_t)0) { - registered = (uint8_t)1; + //${AOs::Philo::SM::initial} + Q_UNUSED_PAR(par); - QS_OBJ_DICTIONARY(&Philo_inst[0]); - QS_OBJ_DICTIONARY(&Philo_inst[0].timeEvt); - QS_OBJ_DICTIONARY(&Philo_inst[1]); - QS_OBJ_DICTIONARY(&Philo_inst[1].timeEvt); - QS_OBJ_DICTIONARY(&Philo_inst[2]); - QS_OBJ_DICTIONARY(&Philo_inst[2].timeEvt); - QS_OBJ_DICTIONARY(&Philo_inst[3]); - QS_OBJ_DICTIONARY(&Philo_inst[3].timeEvt); - QS_OBJ_DICTIONARY(&Philo_inst[4]); - QS_OBJ_DICTIONARY(&Philo_inst[4].timeEvt); - - QS_FUN_DICTIONARY(&Philo_initial); - QS_FUN_DICTIONARY(&Philo_thinking); - QS_FUN_DICTIONARY(&Philo_hungry); - QS_FUN_DICTIONARY(&Philo_eating); - } - QS_SIG_DICTIONARY(HUNGRY_SIG, me); /* signal for each Philos */ - QS_SIG_DICTIONARY(TIMEOUT_SIG, me); /* signal for each Philos */ + QS_OBJ_ARR_DICTIONARY(&Philo_inst[me->id], me->id); + QS_OBJ_ARR_DICTIONARY(&Philo_inst[me->id].timeEvt, me->id); QActive_subscribe(&me->super, EAT_SIG); QActive_subscribe(&me->super, TEST_SIG); + + QS_FUN_DICTIONARY(&Philo_thinking); + QS_FUN_DICTIONARY(&Philo_hungry); + QS_FUN_DICTIONARY(&Philo_eating); + return Q_TRAN(&Philo_thinking); } -/*${AOs::Philo::SM::thinking} ..............................................*/ +//${AOs::Philo::SM::thinking} ................................................ static QState Philo_thinking(Philo * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${AOs::Philo::SM::thinking} */ + //${AOs::Philo::SM::thinking} case Q_ENTRY_SIG: { - QTimeEvt_armX(&me->timeEvt, THINK_TIME, 0U); + QTimeEvt_armX(&me->timeEvt, think_time(), 0U); status_ = Q_HANDLED(); break; } - /*${AOs::Philo::SM::thinking} */ + //${AOs::Philo::SM::thinking} case Q_EXIT_SIG: { - QTimeEvt_disarm(&me->timeEvt); + (void)QTimeEvt_disarm(&me->timeEvt); status_ = Q_HANDLED(); break; } - /*${AOs::Philo::SM::thinking::TIMEOUT} */ + //${AOs::Philo::SM::thinking::TIMEOUT} case TIMEOUT_SIG: { status_ = Q_TRAN(&Philo_hungry); break; } - /*${AOs::Philo::SM::thinking::EAT, DONE} */ - case EAT_SIG: /* intentionally fall through */ + //${AOs::Philo::SM::thinking::EAT, DONE} + case EAT_SIG: // intentionally fall through case DONE_SIG: { - /* EAT or DONE must be for other Philos than this one */ - Q_ASSERT(Q_EVT_CAST(TableEvt)->philoNum != PHILO_ID(me)); + // EAT or DONE must be for other Philos than this one + Q_ASSERT(Q_EVT_CAST(TableEvt)->philoId != me->id); status_ = Q_HANDLED(); break; } - /*${AOs::Philo::SM::thinking::TEST} */ + //${AOs::Philo::SM::thinking::TEST} case TEST_SIG: { status_ = Q_HANDLED(); break; @@ -174,22 +166,26 @@ static QState Philo_thinking(Philo * const me, QEvt const * const e) { return status_; } -/*${AOs::Philo::SM::hungry} ................................................*/ +//${AOs::Philo::SM::hungry} .................................................. static QState Philo_hungry(Philo * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${AOs::Philo::SM::hungry} */ + //${AOs::Philo::SM::hungry} case Q_ENTRY_SIG: { + #ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, HUNGRY_SIG, me->id); + #else TableEvt *pe = Q_NEW(TableEvt, HUNGRY_SIG); - pe->philoNum = PHILO_ID(me); - QACTIVE_POST(AO_Table, &pe->super, me); + pe->philoId = me->id; + #endif + QACTIVE_POST(AO_Table, &pe->super, &me->super); status_ = Q_HANDLED(); break; } - /*${AOs::Philo::SM::hungry::EAT} */ + //${AOs::Philo::SM::hungry::EAT} case EAT_SIG: { - /*${AOs::Philo::SM::hungry::EAT::[Q_EVT_CAST(TableEvt)->philoNum=~} */ - if (Q_EVT_CAST(TableEvt)->philoNum == PHILO_ID(me)) { + //${AOs::Philo::SM::hungry::EAT::[e->philoId==me->iid]} + if (Q_EVT_CAST(TableEvt)->philoId == me->id) { status_ = Q_TRAN(&Philo_eating); } else { @@ -197,10 +193,10 @@ static QState Philo_hungry(Philo * const me, QEvt const * const e) { } break; } - /*${AOs::Philo::SM::hungry::DONE} */ + //${AOs::Philo::SM::hungry::DONE} case DONE_SIG: { - /* DONE must be for other Philos than this one */ - Q_ASSERT(Q_EVT_CAST(TableEvt)->philoNum != PHILO_ID(me)); + // DONE must be for other Philos than this one + Q_ASSERT(Q_EVT_CAST(TableEvt)->philoId != me->id); status_ = Q_HANDLED(); break; } @@ -212,34 +208,40 @@ static QState Philo_hungry(Philo * const me, QEvt const * const e) { return status_; } -/*${AOs::Philo::SM::eating} ................................................*/ +//${AOs::Philo::SM::eating} .................................................. static QState Philo_eating(Philo * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${AOs::Philo::SM::eating} */ + //${AOs::Philo::SM::eating} case Q_ENTRY_SIG: { - QTimeEvt_armX(&me->timeEvt, EAT_TIME, 0U); + QTimeEvt_armX(&me->timeEvt, eat_time(), 0U); status_ = Q_HANDLED(); break; } - /*${AOs::Philo::SM::eating} */ + //${AOs::Philo::SM::eating} case Q_EXIT_SIG: { + (void)QTimeEvt_disarm(&me->timeEvt); + + #ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, DONE_SIG, me->id); + #else TableEvt *pe = Q_NEW(TableEvt, DONE_SIG); - pe->philoNum = PHILO_ID(me); + pe->philoId = me->id; + #endif QACTIVE_PUBLISH(&pe->super, &me->super); status_ = Q_HANDLED(); break; } - /*${AOs::Philo::SM::eating::TIMEOUT} */ + //${AOs::Philo::SM::eating::TIMEOUT} case TIMEOUT_SIG: { status_ = Q_TRAN(&Philo_thinking); break; } - /*${AOs::Philo::SM::eating::EAT, DONE} */ - case EAT_SIG: /* intentionally fall through */ + //${AOs::Philo::SM::eating::EAT, DONE} + case EAT_SIG: // intentionally fall through case DONE_SIG: { - /* EAT or DONE must be for other Philos than this one */ - Q_ASSERT(Q_EVT_CAST(TableEvt)->philoNum != PHILO_ID(me)); + // EAT or DONE must be for other Philos than this one + Q_ASSERT(Q_EVT_CAST(TableEvt)->philoId != me->id); status_ = Q_HANDLED(); break; } @@ -250,4 +252,4 @@ static QState Philo_eating(Philo * const me, QEvt const * const e) { } return status_; } -/*$enddef${AOs::Philo} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$enddef${AOs::Philo} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/examples/arm-cm/dpp_nucleo-l152re/qk/armclang/dpp-qk.sct b/examples/arm-cm/dpp_nucleo-l152re/qk/armclang/dpp-qk.sct new file mode 100644 index 00000000..fbadbbfa --- /dev/null +++ b/examples/arm-cm/dpp_nucleo-l152re/qk/armclang/dpp-qk.sct @@ -0,0 +1,22 @@ +; ************************************************************* +; *** Scatter-Loading Description File generated by uVision *** +; +; Adapted by Quantum Leaps: +; moved STACK as the first section in RW_IRAM1 +; ************************************************************* + +LR_IROM1 0x08000000 0x00080000 { ; load region size_region + ER_IROM1 0x08000000 0x00080000 { ; load address = execution address + *.o (RESET, +First) + *(InRoot$$Sections) + .ANY (+RO) + .ANY (+XO) + } + RW_STACK 0x20000000 { ; <== Quantum Leaps + * (STACK, +First) + } + RW_IRAM1 +0 (0x00014000 - 2048) { ; NOTE: 2048 assumed for STACK size! + .ANY (+RW +ZI) + } +} + diff --git a/examples/arm-cm/dpp_nucleo-l152re/qk/armclang/dpp-qk.uvoptx b/examples/arm-cm/dpp_nucleo-l152re/qk/armclang/dpp-qk.uvoptx index 772a62d0..0e0db992 100644 --- a/examples/arm-cm/dpp_nucleo-l152re/qk/armclang/dpp-qk.uvoptx +++ b/examples/arm-cm/dpp_nucleo-l152re/qk/armclang/dpp-qk.uvoptx @@ -10,7 +10,7 @@ *.s*; *.src; *.a* *.obj; *.o *.lib - *.txt; *.h; *.inc + *.txt; *.h; *.inc; *.md *.plm *.cpp 0 @@ -75,7 +75,7 @@ 1 0 - 0 + 1 18 @@ -103,7 +103,7 @@ 1 0 0 - 5 + 6 @@ -125,7 +125,7 @@ 0 DLGTARM - (1010=-1,-1,-1,-1,0)(1007=-1,-1,-1,-1,0)(1008=-1,-1,-1,-1,0)(1009=-1,-1,-1,-1,0)(1012=-1,-1,-1,-1,0) + (1010=1313,409,1763,966,0)(1007=-1,-1,-1,-1,0)(1008=-1,-1,-1,-1,0)(1009=-1,-1,-1,-1,0)(1012=-1,-1,-1,-1,0) 0 @@ -140,15 +140,44 @@ 0 ST-LINKIII-KEIL_SWO - -U066EFF495056805087184715 -O8398 -S1 -C0 -A0 -N00("ARM CoreSight SW-DP") -D00(2BA01477) -L00(0) -TO18 -TC10000000 -TP21 -TDS8007 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -FO15 -FD20000000 -FC1000 -FN1 -FF0STM32L1xx_512.FLM -FS08000000 -FL080000 -FP0($$Device:STM32L152RE$Flash\STM32L1xx_512.FLM) + -U066EFF495056805087184715 -O8398 -SF10000 -C0 -A0 -I0 -HNlocalhost -HP7184 -P1 -N00("ARM CoreSight SW-DP (ARM Core") -D00(2BA01477) -L00(0) -TO131090 -TC10000000 -TT10000000 -TP21 -TDS8007 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -FO15 -FD20000000 -FC1000 -FN1 -FF0STM32L1xx_512.FLM -FS08000000 -FL080000 -FP0($$Device:STM32L152RE$CMSIS\Flash\STM32L1xx_512.FLM) 0 UL2CM3 - UL2CM3(-S0 -C0 -P0 -FD20000000 -FC1000 -FN1 -FF0STM32L1xx_512 -FS08000000 -FL080000 -FP0($$Device:STM32L152RE$Flash\STM32L1xx_512.FLM)) + UL2CM3(-S0 -C0 -P0 -FD20000000 -FC1000 -FN1 -FF0STM32L1xx_512 -FS08000000 -FL080000 -FP0($$Device:STM32L152RE$CMSIS\Flash\STM32L1xx_512.FLM)) - + + + 0 + 0 + 288 + 1 +
134223096
+ 0 + 0 + 0 + 0 + 0 + 1 + ..\bsp.c + + \\dpp_qk\../bsp.c\288 +
+
+ + + 0 + 1 + QF_readySet_ + + + 1 + 1 + QF_readySet_rmc_ + + 1 @@ -207,6 +236,13 @@ + + 1 + 0 + 0 + 2 + 10000000 +
@@ -264,7 +300,7 @@ 1 0 - 1 + 0 18 @@ -292,7 +328,7 @@ 1 0 0 - 5 + 6 @@ -329,12 +365,12 @@ 0 ST-LINKIII-KEIL_SWO - -U066EFF495056805087184715 -I0 -O8430 -S1 -C0 -A0 -N00("ARM CoreSight SW-DP") -D00(2BA01477) -L00(0) -TO18 -TC10000000 -TP21 -TDS8007 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -FO15 -FD20000000 -FC1000 -FN1 -FF0STM32L1xx_512.FLM -FS08000000 -FL080000 -FP0($$Device:STM32L152RE$Flash\STM32L1xx_512.FLM) + -U066EFF495056805087184715 -I0 -O8430 -S1 -C0 -A0 -N00("ARM CoreSight SW-DP") -D00(2BA01477) -L00(0) -TO18 -TC10000000 -TP21 -TDS8007 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -FO15 -FD20000000 -FC1000 -FN1 -FF0STM32L1xx_512.FLM -FS08000000 -FL080000 -FP0($$Device:STM32L152RE$CMSIS\Flash\STM32L1xx_512.FLM) 0 UL2CM3 - UL2CM3(-S0 -C0 -P0 -FD20000000 -FC1000 -FN1 -FF0STM32L1xx_512 -FS08000000 -FL080000 -FP0($$Device:STM32L152RE$Flash\STM32L1xx_512.FLM)) + UL2CM3(-S0 -C0 -P0 -FD20000000 -FC1000 -FN1 -FF0STM32L1xx_512 -FS08000000 -FL080000 -FP0($$Device:STM32L152RE$CMSIS\Flash\STM32L1xx_512.FLM)) @@ -413,6 +449,13 @@ + + 1 + 1 + 0 + 2 + 10000000 + @@ -498,7 +541,7 @@ 1 0 0 - 5 + 6 @@ -535,12 +578,12 @@ 0 ST-LINKIII-KEIL_SWO - -U066EFF495056805087184715 -I0 -O8398 -S1 -C0 -A0 -N00("ARM CoreSight SW-DP") -D00(2BA01477) -L00(0) -TO18 -TC10000000 -TP21 -TDS8007 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -FO15 -FD20000000 -FC1000 -FN1 -FF0STM32L1xx_512.FLM -FS08000000 -FL080000 -FP0($$Device:STM32L152RE$Flash\STM32L1xx_512.FLM) + -U066EFF495056805087184715 -I0 -O8398 -S1 -C0 -A0 -N00("ARM CoreSight SW-DP") -D00(2BA01477) -L00(0) -TO18 -TC10000000 -TP21 -TDS8007 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -FO15 -FD20000000 -FC1000 -FN1 -FF0STM32L1xx_512.FLM -FS08000000 -FL080000 -FP0($$Device:STM32L152RE$CMSIS\Flash\STM32L1xx_512.FLM) 0 UL2CM3 - UL2CM3(-S0 -C0 -P0 -FD20000000 -FC1000 -FN1 -FF0STM32L1xx_512 -FS08000000 -FL080000 -FP0($$Device:STM32L152RE$Flash\STM32L1xx_512.FLM)) + UL2CM3(-S0 -C0 -P0 -FD20000000 -FC1000 -FN1 -FF0STM32L1xx_512 -FS08000000 -FL080000 -FP0($$Device:STM32L152RE$CMSIS\Flash\STM32L1xx_512.FLM)) @@ -619,6 +662,13 @@ + + 1 + 1 + 0 + 2 + 10000000 + @@ -679,18 +729,6 @@ 1 5 - 5 - 0 - 0 - 0 - ..\..\README.txt - README.txt - 0 - 0 - - - 1 - 6 1 0 0 @@ -702,24 +740,12 @@ 1 - 7 + 6 1 0 0 0 - ..\..\..\..\..\include\qstamp.c - qstamp.c - 0 - 0 - - - 1 - 8 - 1 - 0 - 0 - 0 - ..\main.c + ..\..\main.c main.c 0 0 @@ -734,7 +760,7 @@ 0 2 - 9 + 7 5 0 0 @@ -746,7 +772,7 @@ 2 - 10 + 8 5 0 0 @@ -758,7 +784,7 @@ 2 - 11 + 9 1 0 0 @@ -770,7 +796,7 @@ 2 - 12 + 10 5 0 0 @@ -782,7 +808,7 @@ 2 - 13 + 11 2 0 0 @@ -802,7 +828,7 @@ 0 3 - 14 + 12 1 0 0 @@ -814,7 +840,7 @@ 3 - 15 + 13 1 0 0 @@ -826,7 +852,7 @@ 3 - 16 + 14 1 0 0 @@ -838,7 +864,7 @@ 3 - 17 + 15 1 0 0 @@ -850,7 +876,7 @@ 3 - 18 + 16 1 0 0 @@ -862,7 +888,7 @@ 3 - 19 + 17 1 0 0 @@ -874,7 +900,7 @@ 3 - 20 + 18 1 0 0 @@ -886,19 +912,7 @@ 3 - 21 - 5 - 0 - 0 - 0 - ..\..\..\..\..\src\qf_pkg.h - qf_pkg.h - 0 - 0 - - - 3 - 22 + 19 1 0 0 @@ -910,7 +924,7 @@ 3 - 23 + 20 1 0 0 @@ -922,7 +936,7 @@ 3 - 24 + 21 1 0 0 @@ -934,7 +948,7 @@ 3 - 25 + 22 1 0 0 @@ -946,7 +960,7 @@ 3 - 26 + 23 1 0 0 @@ -958,7 +972,7 @@ 3 - 27 + 24 1 0 0 @@ -978,43 +992,7 @@ 0 4 - 28 - 5 - 0 - 0 - 0 - ..\..\..\..\..\ports\arm-cm\qk\armclang\qep_port.h - qep_port.h - 0 - 0 - - - 4 - 29 - 5 - 0 - 0 - 0 - ..\..\..\..\..\ports\arm-cm\qk\armclang\qf_port.h - qf_port.h - 0 - 0 - - - 4 - 30 - 5 - 0 - 0 - 0 - ..\..\..\..\..\ports\arm-cm\qk\armclang\qk_port.h - qk_port.h - 0 - 0 - - - 4 - 31 + 25 1 0 0 @@ -1026,7 +1004,7 @@ 4 - 32 + 26 5 0 0 @@ -1046,7 +1024,7 @@ 0 5 - 33 + 27 1 0 0 @@ -1058,7 +1036,7 @@ 5 - 34 + 28 1 0 0 @@ -1070,7 +1048,7 @@ 5 - 35 + 29 1 0 0 @@ -1080,6 +1058,18 @@ 0 0 + + 5 + 30 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qs\qstamp.c + qstamp.c + 0 + 0 + diff --git a/examples/arm-cm/dpp_nucleo-l152re/qk/armclang/dpp-qk.uvprojx b/examples/arm-cm/dpp_nucleo-l152re/qk/armclang/dpp-qk.uvprojx index 48d0f85e..ae786be6 100644 --- a/examples/arm-cm/dpp_nucleo-l152re/qk/armclang/dpp-qk.uvprojx +++ b/examples/arm-cm/dpp_nucleo-l152re/qk/armclang/dpp-qk.uvprojx @@ -10,13 +10,13 @@ dpp-dbg 0x4 ARM-ADS - 6130001::V6.13.1::.\ARMCLANG + 6160000::V6.16::ARMCLANG 1 STM32L152RE STMicroelectronics - Keil.STM32L1xx_DFP.1.0.2 + Keil.STM32L1xx_DFP.1.4.1 http://www.keil.com/pack/ IROM(0x08000000,0x80000) IRAM(0x20000000,0x14000) CPUTYPE("Cortex-M3") CLOCK(12000000) ELITTLE @@ -185,6 +185,7 @@ 0 0 0 + 0 0 0 8 @@ -351,7 +352,7 @@ 0 1 0 - 0 + 4 Stack_Size=2048 Heap_Size=16 @@ -360,7 +361,7 @@ - 1 + 0 0 0 0 @@ -369,7 +370,7 @@ 0x00000000 0x20000000 - + .\dpp-qk.sct --entry Reset_Handler @@ -402,25 +403,15 @@ 1 ..\..\philo.c - - README.txt - 5 - ..\..\README.txt - table.c 1 ..\..\table.c - - qstamp.c - 1 - ..\..\..\..\..\include\qstamp.c - main.c 1 - ..\main.c + ..\..\main.c @@ -492,11 +483,6 @@ 1 ..\..\..\..\..\src\qf\qf_mem.c - - qf_pkg.h - 5 - ..\..\..\..\..\src\qf_pkg.h - qf_ps.c 1 @@ -532,21 +518,6 @@ QP_port - - qep_port.h - 5 - ..\..\..\..\..\ports\arm-cm\qk\armclang\qep_port.h - - - qf_port.h - 5 - ..\..\..\..\..\ports\arm-cm\qk\armclang\qf_port.h - - - qk_port.h - 5 - ..\..\..\..\..\ports\arm-cm\qk\armclang\qk_port.h - qk_port.c 1 @@ -620,7 +591,7 @@ 2 2 2 - 2 + 0 @@ -646,6 +617,11 @@ 1 ..\..\..\..\..\src\qs\qs_rx.c + + qstamp.c + 1 + ..\..\..\..\..\src\qs\qstamp.c + @@ -660,7 +636,7 @@ STM32L152RE STMicroelectronics - Keil.STM32L1xx_DFP.1.0.2 + Keil.STM32L1xx_DFP.1.4.1 http://www.keil.com/pack/ IROM(0x08000000,0x80000) IRAM(0x20000000,0x14000) CPUTYPE("Cortex-M3") CLOCK(12000000) ELITTLE @@ -829,6 +805,7 @@ 0 0 0 + 0 0 0 8 @@ -995,7 +972,7 @@ 0 1 0 - 0 + 4 Stack_Size=2048 Heap_Size=16 @@ -1004,7 +981,7 @@ - 1 + 0 0 0 0 @@ -1013,7 +990,7 @@ 0x00000000 0x20000000 - dpp-qk.sct + .\dpp-qk.sct --entry Reset_Handler @@ -1046,25 +1023,15 @@ 1 ..\..\philo.c - - README.txt - 5 - ..\..\README.txt - table.c 1 ..\..\table.c - - qstamp.c - 1 - ..\..\..\..\..\include\qstamp.c - main.c 1 - ..\main.c + ..\..\main.c @@ -1136,11 +1103,6 @@ 1 ..\..\..\..\..\src\qf\qf_mem.c - - qf_pkg.h - 5 - ..\..\..\..\..\src\qf_pkg.h - qf_ps.c 1 @@ -1176,21 +1138,6 @@ QP_port - - qep_port.h - 5 - ..\..\..\..\..\ports\arm-cm\qk\armclang\qep_port.h - - - qf_port.h - 5 - ..\..\..\..\..\ports\arm-cm\qk\armclang\qf_port.h - - - qk_port.h - 5 - ..\..\..\..\..\ports\arm-cm\qk\armclang\qk_port.h - qk_port.c 1 @@ -1264,7 +1211,7 @@ 2 2 2 - 2 + 0 @@ -1290,6 +1237,11 @@ 1 ..\..\..\..\..\src\qs\qs_rx.c + + qstamp.c + 1 + ..\..\..\..\..\src\qs\qstamp.c + @@ -1298,13 +1250,13 @@ dpp-spy 0x4 ARM-ADS - 6130001::V6.13.1::.\ARMCLANG + 6160000::V6.16::ARMCLANG 1 STM32L152RE STMicroelectronics - Keil.STM32L1xx_DFP.1.0.2 + Keil.STM32L1xx_DFP.1.4.1 http://www.keil.com/pack/ IROM(0x08000000,0x80000) IRAM(0x20000000,0x14000) CPUTYPE("Cortex-M3") CLOCK(12000000) ELITTLE @@ -1473,6 +1425,7 @@ 0 0 0 + 0 0 0 8 @@ -1624,7 +1577,7 @@ 0 - Q_SPY + Q_SPY,QF_ON_CONTEXT_SW ..\..;..\..\..\..\..\include;..\..\..\..\..\ports\arm-cm\qk\armclang;..\..\..\..\..\3rd_party\CMSIS\Include; ..\..\..\..\..\3rd_party\nucleo-l152re @@ -1639,7 +1592,7 @@ 0 1 0 - 0 + 4 Stack_Size=2048 Heap_Size=16 @@ -1648,7 +1601,7 @@ - 1 + 0 0 0 0 @@ -1657,7 +1610,7 @@ 0x00000000 0x20000000 - dpp-qk.sct + .\dpp-qk.sct --entry Reset_Handler @@ -1690,25 +1643,15 @@ 1 ..\..\philo.c - - README.txt - 5 - ..\..\README.txt - table.c 1 ..\..\table.c - - qstamp.c - 1 - ..\..\..\..\..\include\qstamp.c - main.c 1 - ..\main.c + ..\..\main.c @@ -1780,11 +1723,6 @@ 1 ..\..\..\..\..\src\qf\qf_mem.c - - qf_pkg.h - 5 - ..\..\..\..\..\src\qf_pkg.h - qf_ps.c 1 @@ -1820,21 +1758,6 @@ QP_port - - qep_port.h - 5 - ..\..\..\..\..\ports\arm-cm\qk\armclang\qep_port.h - - - qf_port.h - 5 - ..\..\..\..\..\ports\arm-cm\qk\armclang\qf_port.h - - - qk_port.h - 5 - ..\..\..\..\..\ports\arm-cm\qk\armclang\qk_port.h - qk_port.c 1 @@ -1865,6 +1788,11 @@ 1 ..\..\..\..\..\src\qs\qs_rx.c + + qstamp.c + 1 + ..\..\..\..\..\src\qs\qstamp.c + diff --git a/examples/arm-cm/dpp_nucleo-l152re/qk/bsp.c b/examples/arm-cm/dpp_nucleo-l152re/qk/bsp.c index 45dce7bd..10912c64 100644 --- a/examples/arm-cm/dpp_nucleo-l152re/qk/bsp.c +++ b/examples/arm-cm/dpp_nucleo-l152re/qk/bsp.c @@ -1,307 +1,406 @@ -/***************************************************************************** -* Product: DPP example, STM32 NUCLEO-L152RE board, preemptive QK kernel -* Last updated for version 6.9.3 -* Last updated on 2021-03-03 -* -* Q u a n t u m L e a P s -* ------------------------ -* Modern Embedded Software -* -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* -* -*****************************************************************************/ -#include "qpc.h" -#include "dpp.h" -#include "bsp.h" +//============================================================================ +// Product: DPP example, NUCLEO-L152RE board, QK kernel +// Last updated for version 7.3.0 +// Last updated on 2023-08-23 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. +// +// This program is open source software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Alternatively, this program may be distributed and modified under the +// terms of Quantum Leaps commercial licenses, which expressly supersede +// the GNU General Public License and are specifically designed for +// licensees interested in retaining the proprietary status of their code. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Contact information: +// +// +//============================================================================ +#include "qpc.h" // QP/C real-time embedded framework +#include "dpp.h" // DPP Application interface +#include "bsp.h" // Board Support Package -#include "stm32l1xx.h" /* CMSIS-compliant header file for the MCU used */ -/* add other drivers if necessary... */ +#include "stm32l1xx.h" // CMSIS-compliant header file for the MCU used +// add other drivers if necessary... -Q_DEFINE_THIS_FILE +Q_DEFINE_THIS_FILE // define the name of this file for assertions -/* Local-scope objects -----------------------------------------------------*/ -/* LED pins available on the board (just one user LED LD2--Green on PA.5) */ -#define LED_LD2 (1U << 5) +// Local-scope defines ----------------------------------------------------- +// LED pins available on the board (just one user LED LD2--Green on PA.5) +#define LED_PIN 5U -/* Button pins available on the board (just one user Button B1 on PC.13) */ -#define BTN_B1 (1U << 13) +// Button pins available on the board (just one user Button B1 on PC.13) +#define BTN_PIN 13U -static uint32_t l_rnd; /* random seed */ +static uint32_t l_rndSeed; #ifdef Q_SPY QSTimeCtr QS_tickTime_; QSTimeCtr QS_tickPeriod_; - /* QSpy source IDs */ + // QSpy source IDs static QSpyId const l_SysTick_Handler = { 0U }; - enum AppRecords { /* application-specific trace records */ - PHILO_STAT = QS_USER + enum AppRecords { // application-specific trace records + PHILO_STAT = QS_USER, + PAUSED_STAT, + CONTEXT_SW, }; #endif -/* ISRs used in the application ==========================================*/ -void SysTick_Handler(void); -void USART2_IRQHandler(void); +//============================================================================ +// Error handler and ISRs... -/*..........................................................................*/ -void SysTick_Handler(void) { /* system clock tick ISR -- kernel aware */ - /* state of the button debouncing, see below */ - static struct ButtonsDebouncing { - uint32_t depressed; - uint32_t previous; - } buttons = { 0U, 0U }; - uint32_t current; - uint32_t tmp; +Q_NORETURN Q_onError(char const * const module, int_t const id) { + // NOTE: this implementation of the assertion handler is intended only + // for debugging and MUST be changed for deployment of the application + // (assuming that you ship your production code with assertions enabled). + Q_UNUSED_PAR(module); + Q_UNUSED_PAR(id); + QS_ASSERTION(module, id, 10000U); - QK_ISR_ENTRY(); /* inform QK about entering an ISR */ - -#ifdef Q_SPY - { - tmp = SysTick->CTRL; /* clear CTRL_COUNTFLAG */ - QS_tickTime_ += QS_tickPeriod_; /* account for the clock rollover */ +#ifndef NDEBUG + // light up the user LED + GPIOA->BSRRL = (1U << LED_PIN); // turn LED on + // for debugging, hang on in an endless loop... + for (;;) { } #endif - QTIMEEVT_TICK_X(0U, &l_SysTick_Handler); /* process time events for rate 0 */ + NVIC_SystemReset(); +} +//............................................................................ +void assert_failed(char const * const module, int_t const id); // prototype +void assert_failed(char const * const module, int_t const id) { + Q_onError(module, id); +} - /* get state of the user button */ - /* Perform the debouncing of buttons. The algorithm for debouncing - * adapted from the book "Embedded Systems Dictionary" by Jack Ganssle - * and Michael Barr, page 71. - */ - current = ~GPIOC->IDR; /* read Port C with the state of Button B1 */ - tmp = buttons.depressed; /* save the debounced depressed buttons */ - buttons.depressed |= (buttons.previous & current); /* set depressed */ - buttons.depressed &= (buttons.previous | current); /* clear released */ - buttons.previous = current; /* update the history */ - tmp ^= buttons.depressed; /* changed debounced depressed */ - if ((tmp & BTN_B1) != 0U) { /* debounced B1 state changed? */ - if ((buttons.depressed & BTN_B1) != 0U) { /* is B1 depressed? */ - static QEvt const pauseEvt = { PAUSE_SIG, 0U, 0U}; +// ISRs used in the application ========================================== +void SysTick_Handler(void); // prototype +void SysTick_Handler(void) { + QK_ISR_ENTRY(); // inform QK about entering an ISR + + QTIMEEVT_TICK_X(0U, &l_SysTick_Handler); // time events at rate 0 + + // Perform the debouncing of buttons. The algorithm for debouncing + // adapted from the book "Embedded Systems Dictionary" by Jack Ganssle + // and Michael Barr, page 71. + // + // state of the button debouncing + static struct { + uint32_t depressed; + uint32_t previous; + } buttons = { 0U, 0U }; + + uint32_t current = ~GPIOC->IDR; // Port C with state of Button B1 + uint32_t tmp = buttons.depressed; // save the depressed buttons + buttons.depressed |= (buttons.previous & current); // set depressed + buttons.depressed &= (buttons.previous | current); // clear released + buttons.previous = current; // update the history + tmp ^= buttons.depressed; // changed debounced depressed + current = buttons.depressed; + + if ((tmp & (1U << BTN_PIN)) != 0U) { // debounced BTN state changed? + if ((current & (1U << BTN_PIN)) != 0U) { // is BTN depressed? + static QEvt const pauseEvt = QEVT_INITIALIZER(PAUSE_SIG); QACTIVE_PUBLISH(&pauseEvt, &l_SysTick_Handler); } - else { /* the button is released */ - static QEvt const serveEvt = { SERVE_SIG, 0U, 0U}; + else { // the button is released + static QEvt const serveEvt = QEVT_INITIALIZER(SERVE_SIG); QACTIVE_PUBLISH(&serveEvt, &l_SysTick_Handler); } } - QK_ISR_EXIT(); /* inform QK about exiting an ISR */ +#ifdef Q_SPY + tmp = SysTick->CTRL; // clear CTRL_COUNTFLAG + QS_tickTime_ += QS_tickPeriod_; // account for the clock rollover +#endif + + QK_ISR_EXIT(); // inform QK about exiting an ISR } -/*..........................................................................*/ -#if Q_SPY -void USART2_IRQHandler(void) { /* kernel UNAWARE interrupt */ - /* is RX register NOT empty? */ +//............................................................................ +// interrupt handler for testing preemptions in QK +void EXTI0_1_IRQHandler(void); // prototype +void EXTI0_1_IRQHandler(void) { + QK_ISR_ENTRY(); // inform QK about entering an ISR + + static QEvt const testEvt = QEVT_INITIALIZER(TEST_SIG); + QACTIVE_POST(AO_Table, &testEvt, (void *)0); + + QK_ISR_EXIT(); // inform QK about exiting an ISR +} + +//............................................................................ +#ifdef Q_SPY +// ISR for receiving bytes from the QSPY Back-End +// NOTE: This ISR is "QF-unaware" meaning that it does not interact with +// the QF/QK and is not disabled. Such ISRs don't need to call +// QK_ISR_ENTRY/QK_ISR_EXIT and they cannot post or publish events. + +void USART2_IRQHandler(void); // prototype +void USART2_IRQHandler(void) { // used in QS-RX (kernel UNAWARE interrutp) + // is RX register NOT empty? if ((USART2->SR & (1U << 5)) != 0) { uint32_t b = USART2->DR; QS_RX_PUT(b); } + QK_ARM_ERRATUM_838869(); } -#endif +#endif // Q_SPY + +//............................................................................ +#ifdef QF_ON_CONTEXT_SW +// NOTE: the context-switch callback is called with interrupts DISABLED +void QF_onContextSw(QActive *prev, QActive *next) { + QS_BEGIN_INCRIT(CONTEXT_SW, 0U) // in critical section! + QS_OBJ(prev); + QS_OBJ(next); + QS_END_INCRIT() +} +#endif // QF_ON_CONTEXT_SW + +//============================================================================ +// BSP functions... -/* BSP functions ===========================================================*/ void BSP_init(void) { - /* NOTE: SystemInit() has been already called from the startup code - * but SystemCoreClock needs to be updated - */ + // Configure the MPU to prevent NULL-pointer dereferencing ... + MPU->RBAR = 0x0U // base address (NULL) + | MPU_RBAR_VALID_Msk // valid region + | (MPU_RBAR_REGION_Msk & 7U); // region #7 + MPU->RASR = (7U << MPU_RASR_SIZE_Pos) // 2^(7+1) region + | (0x0U << MPU_RASR_AP_Pos) // no-access region + | MPU_RASR_ENABLE_Msk; // region enable + MPU->CTRL = MPU_CTRL_PRIVDEFENA_Msk // enable background region + | MPU_CTRL_ENABLE_Msk; // enable the MPU + __ISB(); + __DSB(); + + // NOTE: SystemInit() has been already called from the startup code + // but SystemCoreClock needs to be updated SystemCoreClockUpdate(); - /* enable GPIOA clock port for the LED LD2 */ + // enable GPIOA clock port for the LED LD2 RCC->AHBENR |= (1U << 0); - /* configure LED (PA.5) pin as push-pull output, no pull-up, pull-down */ - GPIOA->MODER &= ~((3U << 2*5)); - GPIOA->MODER |= ((1U << 2*5)); - GPIOA->OTYPER &= ~((1U << 5)); - GPIOA->OSPEEDR &= ~((3U << 2*5)); - GPIOA->OSPEEDR |= ((1U << 2*5)); - GPIOA->PUPDR &= ~((3U << 2*5)); + // configure LED (PA.5) pin as push-pull output, no pull-up, pull-down + GPIOA->MODER &= ~((3U << 2U*LED_PIN)); + GPIOA->MODER |= ((1U << 2U*LED_PIN)); + GPIOA->OTYPER &= ~((1U << LED_PIN)); + GPIOA->OSPEEDR &= ~((3U << 2U*LED_PIN)); + GPIOA->OSPEEDR |= ((1U << 2U*LED_PIN)); + GPIOA->PUPDR &= ~((3U << 2U*LED_PIN)); - /* enable GPIOC clock port for the Button B1 */ + // enable GPIOC clock port for the Button B1 RCC->AHBENR |= (1U << 2); - /* configure Button (PC.13) pins as input, no pull-up, pull-down */ - GPIOC->MODER &= ~(3U << 2*13); - GPIOC->OSPEEDR &= ~(3U << 2*13); - GPIOC->OSPEEDR |= (1U << 2*13); - GPIOC->PUPDR &= ~(3U << 2*13); + // configure Button (PC.13) pins as input, no pull-up, pull-down + GPIOC->MODER &= ~(3U << 2U*BTN_PIN); + GPIOC->OSPEEDR &= ~(3U << 2U*BTN_PIN); + GPIOC->OSPEEDR |= (1U << 2U*BTN_PIN); + GPIOC->PUPDR &= ~(3U << 2U*BTN_PIN); - BSP_randomSeed(1234U); /* seed the random number generator */ + BSP_randomSeed(1234U); // seed the random number generator - /* initialize the QS software tracing... */ - if (QS_INIT((void *)0) == 0U) { + // initialize the QS software tracing... + if (!QS_INIT((void *)0)) { Q_ERROR(); } + + // dictionaries... QS_OBJ_DICTIONARY(&l_SysTick_Handler); QS_USR_DICTIONARY(PHILO_STAT); + QS_USR_DICTIONARY(PAUSED_STAT); + QS_USR_DICTIONARY(CONTEXT_SW); - /* setup the QS filters... */ - QS_GLB_FILTER(QS_ALL_RECORDS); - QS_GLB_FILTER(-QS_QF_TICK); + QS_ONLY(produce_sig_dict()); + + // setup the QS filters... + QS_GLB_FILTER(QS_ALL_RECORDS); // all records + QS_GLB_FILTER(-QS_QF_TICK); // exclude the clock tick } -/*..........................................................................*/ +//............................................................................ +void BSP_start(void) { + // initialize event pools + static QF_MPOOL_EL(TableEvt) smlPoolSto[2*N_PHILO]; + QF_poolInit(smlPoolSto, sizeof(smlPoolSto), sizeof(smlPoolSto[0])); + + // initialize publish-subscribe + static QSubscrList subscrSto[MAX_PUB_SIG]; + QActive_psInit(subscrSto, Q_DIM(subscrSto)); + + // instantiate and start AOs/threads... + + static QEvt const *philoQueueSto[N_PHILO][10]; + for (uint8_t n = 0U; n < N_PHILO; ++n) { + Philo_ctor(n); + QACTIVE_START(AO_Philo[n], + + // NOTE: set the preemption-threshold of all Philos to + // the same level, so that they cannot preempt each other. + Q_PRIO(n + 3U, N_PHILO + 2U), // QF-prio/pre-thre. + + philoQueueSto[n], // event queue storage + Q_DIM(philoQueueSto[n]), // queue length [events] + (void *)0, 0U, // no stack storage + (void *)0); // no initialization param + } + + static QEvt const *tableQueueSto[N_PHILO]; + Table_ctor(); + QACTIVE_START(AO_Table, + N_PHILO + 7U, // QP prio. of the AO + tableQueueSto, // event queue storage + Q_DIM(tableQueueSto), // queue length [events] + (void *)0, 0U, // no stack storage + (void *)0); // no initialization param +} +//............................................................................ void BSP_displayPhilStat(uint8_t n, char const *stat) { + Q_UNUSED_PAR(n); + if (stat[0] == 'h') { - GPIOA->BSRRL |= LED_LD2; /* turn LED on */ + GPIOA->BSRRL = (1U << LED_PIN); // turn LED on } else { - GPIOA->BSRRH |= LED_LD2; /* turn LED off */ + GPIOA->BSRRH = (1U << LED_PIN); // turn LED off } - QS_BEGIN_ID(PHILO_STAT, AO_Philo[n]->prio) /* app-specific record */ - QS_U8(0, n); /* Philosopher number */ - QS_STR(stat); /* Philosopher status */ + // app-specific trace record... + QS_BEGIN_ID(PHILO_STAT, AO_Table->prio) + QS_U8(1, n); // Philosopher number + QS_STR(stat); // Philosopher status QS_END() } -/*..........................................................................*/ -void BSP_displayPaused(uint8_t paused) { - // not enough LEDs to show the "Paused" status +//............................................................................ +void BSP_displayPaused(uint8_t const paused) { + // not enough LEDs to implement this feature if (paused != 0U) { - //GPIOA->BSRRL |= LED_LD2; /* turn LED on */ + //GPIOA->BSRRL = (1U << LED_PIN); // turn LED on } else { - //GPIOA->BSRRH |= LED_LD2; /* turn LED off */ + //GPIOA->BSRRH = (1U << LED_PIN); // turn LED off } + + // application-specific trace record + QS_BEGIN_ID(PAUSED_STAT, AO_Table->prio) + QS_U8(1, paused); // Paused status + QS_END() } -/*..........................................................................*/ -uint32_t BSP_random(void) { /* a very cheap pseudo-random-number generator */ - /* "Super-Duper" Linear Congruential Generator (LCG) - * LCG(2^32, 3*7*11*13*23, 0, seed) - */ - l_rnd = l_rnd * (3U*7U*11U*13U*23U); - return l_rnd >> 8; -} -/*..........................................................................*/ +//............................................................................ void BSP_randomSeed(uint32_t seed) { - l_rnd = seed; + l_rndSeed = seed; } -/*..........................................................................*/ -void BSP_terminate(int16_t result) { - (void)result; +//............................................................................ +uint32_t BSP_random(void) { // a very cheap pseudo-random-number generator + + QSchedStatus lockStat = QK_schedLock(N_PHILO); + // "Super-Duper" Linear Congruential Generator (LCG) + // LCG(2^32, 3*7*11*13*23, 0, seed) + // + uint32_t rnd = l_rndSeed * (3U*7U*11U*13U*23U); + l_rndSeed = rnd; // set for the next time + QK_schedUnlock(lockStat); + + return (rnd >> 8U); } -/*..........................................................................*/ -void BSP_wait4SW1(void) { - while ((GPIOC->IDR & BTN_B1) != 0U) { - GPIOA->BSRRL |= LED_LD2; /* turn LED[n] on */ - GPIOA->BSRRH |= LED_LD2; /* turn LED[n] off */ - } -} -/*..........................................................................*/ +//............................................................................ void BSP_ledOn(void) { - //GPIOA->BSRL |= (LED_LD2); /* turn LED2 on */ + GPIOA->BSRRL = (1U << LED_PIN); // turn LED on } -/*..........................................................................*/ +//............................................................................ void BSP_ledOff(void) { - //GPIOA->BSRRH |= LED_LD2; /* turn LED2 off */ + GPIOA->BSRRH = (1U << LED_PIN); // turn LED off +} +//............................................................................ +void BSP_terminate(int16_t result) { + Q_UNUSED_PAR(result); } -/* QF callbacks ============================================================*/ +//============================================================================ +// QF callbacks... void QF_onStartup(void) { - /* set up the SysTick timer to fire at BSP_TICKS_PER_SEC rate */ + // set up the SysTick timer to fire at BSP_TICKS_PER_SEC rate SysTick_Config(SystemCoreClock / BSP_TICKS_PER_SEC); - /* set priorities of ALL ISRs used in the system, see NOTE00 - * - * !!!!!!!!!!!!!!!!!!!!!!!!!!!! CAUTION !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - * Assign a priority to EVERY ISR explicitly by calling NVIC_SetPriority(). - * DO NOT LEAVE THE ISR PRIORITIES AT THE DEFAULT VALUE! - */ - NVIC_SetPriority(SysTick_IRQn, QF_AWARE_ISR_CMSIS_PRI + 1); - NVIC_SetPriority(USART2_IRQn, 0); /* kernel UNAWARE interrupt */ - /* ... */ + // assign all priority bits for preemption-prio. and none to sub-prio. + NVIC_SetPriorityGrouping(0U); - /* enable IRQs... */ + // set priorities of ALL ISRs used in the system, see NOTE1 + NVIC_SetPriority(USART2_IRQn, 0); // kernel UNAWARE interrupt + NVIC_SetPriority(SysTick_IRQn, QF_AWARE_ISR_CMSIS_PRI + 1U); + // ... + + // enable IRQs... #ifdef Q_SPY - NVIC_EnableIRQ(USART2_IRQn); /* UART2 interrupt used for QS-RX */ + NVIC_EnableIRQ(USART2_IRQn); // UART2 interrupt used for QS-RX #endif } -/*..........................................................................*/ +//............................................................................ void QF_onCleanup(void) { } -/*..........................................................................*/ -void QK_onIdle(void) { /* called with interrupts enabled */ - - /* toggle an LED on and then off (not enough LEDs, see NOTE01) */ - QF_INT_DISABLE(); - //GPIOA->BSRRL |= LED_LD2; /* turn LED[n] on */ - //GPIOA->BSRRH |= LED_LD2; /* turn LED[n] off */ - QF_INT_ENABLE(); +//............................................................................ +void QK_onIdle(void) { + // toggle an LED on and then off (not enough LEDs, see NOTE02) + //QF_INT_DISABLE(); + //GPIOA->BSRRL = (1U << LED_PIN); // turn LED[n] on + //GPIOA->BSRRH = (1U << LED_PIN); // turn LED[n] off + //QF_INT_ENABLE(); #ifdef Q_SPY - QS_rxParse(); /* parse all the received bytes */ + QF_INT_DISABLE(); + QS_rxParse(); // parse all the received bytes + QF_INT_ENABLE(); + QF_CRIT_EXIT_NOP(); - if ((USART2->SR & (1U << 7)) != 0) { /* is TXE empty? */ - uint16_t b; - - QF_INT_DISABLE(); - b = QS_getByte(); - QF_INT_ENABLE(); - - if (b != QS_EOD) { /* not End-Of-Data? */ - USART2->DR = (b & 0xFFU); /* put into the DR register */ + QF_INT_DISABLE(); + if ((USART2->SR & (1U << 7U)) != 0U) { // is TXE empty? + uint16_t b = QS_getByte(); + if (b != QS_EOD) { // not End-Of-Data? + USART2->DR = b; // put into the DR register } } + QF_INT_ENABLE(); #elif defined NDEBUG - /* Put the CPU and peripherals to the low-power mode. - * you might need to customize the clock management for your application, - * see the datasheet for your particular Cortex-M MCU. - */ - /* !!!CAUTION!!! - * The WFI instruction stops the CPU clock, which unfortunately disables - * the JTAG port, so the ST-Link debugger can no longer connect to the - * board. For that reason, the call to __WFI() has to be used with CAUTION. - * - * NOTE: If you find your board "frozen" like this, strap BOOT0 to VDD and - * reset the board, then connect with ST-Link Utilities and erase the part. - * The trick with BOOT(0) is it gets the part to run the System Loader - * instead of your broken code. When done disconnect BOOT0, and start over. - */ - //__WFI(); /* Wait-For-Interrupt */ + // Put the CPU and peripherals to the low-power mode. + // you might need to customize the clock management for your application, + // see the datasheet for your particular Cortex-M MCU. + // + // !!!CAUTION!!! + // The WFI instruction stops the CPU clock, which unfortunately disables + // the JTAG port, so the ST-Link debugger can no longer connect to the + // board. For that reason, the call to __WFI() has to be used with CAUTION. + // + // NOTE: If you find your board "frozen" like this, strap BOOT0 to VDD and + // reset the board, then connect with ST-Link Utilities and erase the part. + // The trick with BOOT(0) is that it gets the part to run the System Loader + // instead of your broken code. When done disconnect BOOT0, and start over. + // + //__WFI(); // Wait-For-Interrupt #endif } -/*..........................................................................*/ -Q_NORETURN Q_onAssert(char const * const module, int_t const loc) { - /* - * NOTE: add here your application-specific error handling - */ - (void)module; - (void)loc; - QS_ASSERTION(module, loc, 10000U); /* report assertion to QS */ - -#ifndef NDEBUG - BSP_wait4SW1(); -#endif - NVIC_SystemReset(); -} - -/* QS callbacks ============================================================*/ +//============================================================================ +// QS callbacks... #ifdef Q_SPY -/*..........................................................................*/ + +//............................................................................ #define __DIV(__PCLK, __BAUD) (((__PCLK / 4) *25)/(__BAUD)) #define __DIVMANT(__PCLK, __BAUD) (__DIV(__PCLK, __BAUD)/100) #define __DIVFRAQ(__PCLK, __BAUD) \ @@ -310,102 +409,120 @@ Q_NORETURN Q_onAssert(char const * const module, int_t const loc) { #define __USART_BRR(__PCLK, __BAUD) \ ((__DIVMANT(__PCLK, __BAUD) << 4)|(__DIVFRAQ(__PCLK, __BAUD) & 0x0F)) -/*..........................................................................*/ +// USART2 pins PA.2 and PA.3 +#define USART2_TX_PIN 2U +#define USART2_RX_PIN 3U + +//............................................................................ uint8_t QS_onStartup(void const *arg) { - static uint8_t qsBuf[2*1024]; /* buffer for Quantum Spy */ - static uint8_t qsRxBuf[128]; /* buffer for QS-RX channel */ + Q_UNUSED_PAR(arg); - (void)arg; /* avoid the "unused parameter" compiler warning */ + static uint8_t qsTxBuf[2*1024]; // buffer for QS-TX channel + QS_initBuf(qsTxBuf, sizeof(qsTxBuf)); - QS_initBuf(qsBuf, sizeof(qsBuf)); + static uint8_t qsRxBuf[100]; // buffer for QS-RX channel QS_rxInitBuf(qsRxBuf, sizeof(qsRxBuf)); - /* enable peripheral clock for USART2 */ - RCC->AHBENR |= (1U << 0); /* Enable GPIOA clock */ - RCC->APB1ENR |= (1U << 17); /* Enable USART#2 clock */ + // enable peripheral clock for USART2 + RCC->AHBENR |= ( 1U << 0U); // Enable GPIOA clock + RCC->APB1ENR |= ( 1U << 17U); // Enable USART#2 clock - /* Configure PA3 to USART2_RX, PA2 to USART2_TX */ - GPIOA->AFR[0] &= ~((15U << 4*3) | (15U << 4*2)); - GPIOA->AFR[0] |= (( 7U << 4*3) | ( 7U << 4*2)); - GPIOA->MODER &= ~(( 3U << 2*3) | ( 3U << 2*2)); - GPIOA->MODER |= (( 2U << 2*3) | ( 2U << 2*2)); + // Configure PA3 to USART2_RX, PA2 to USART2_TX + GPIOA->AFR[0] &= ~((15U << 4U*USART2_RX_PIN) | (15U << 4U*USART2_TX_PIN)); + GPIOA->AFR[0] |= (( 7U << 4U*USART2_RX_PIN) | ( 7U << 4U*USART2_TX_PIN)); + GPIOA->MODER &= ~(( 3U << 2U*USART2_RX_PIN) | ( 3U << 2U*USART2_TX_PIN)); + GPIOA->MODER |= (( 2U << 2U*USART2_RX_PIN) | ( 2U << 2U*USART2_TX_PIN)); - USART2->BRR = __USART_BRR(SystemCoreClock, 115200U); /* baud rate */ - USART2->CR3 = 0x0000U; /* no flow control */ - USART2->CR2 = 0x0000U; /* 1 stop bit */ - USART2->CR1 = ((1U << 2) | /* enable RX */ - (1U << 3) | /* enable TX */ - (1U << 5) | /* enable RX interrupt */ - (0U << 12) | /* 1 start bit, 8 data bits */ - (1U << 13)); /* enable USART */ + USART2->BRR = __USART_BRR(SystemCoreClock, 115200U); // baud rate + USART2->CR3 = 0x0000U; // no flow control + USART2->CR2 = 0x0000U; // 1 stop bit + USART2->CR1 = ((1U << 2U) | // enable RX + (1U << 3U) | // enable TX + (1U << 5U) | // enable RX interrupt + (0U << 12U) | // 8 data bits + (0U << 28U) | // 8 data bits + (1U << 13U)); // enable USART - return 1U; /* return success */ + QS_tickPeriod_ = SystemCoreClock / BSP_TICKS_PER_SEC; + QS_tickTime_ = QS_tickPeriod_; // to start the timestamp at zero + + return 1U; // return success } -/*..........................................................................*/ +//............................................................................ void QS_onCleanup(void) { } -/*..........................................................................*/ -QSTimeCtr QS_onGetTime(void) { /* NOTE: invoked with interrupts DISABLED */ - if ((SysTick->CTRL & 0x00010000) == 0) { /* COUNT no set? */ +//............................................................................ +QSTimeCtr QS_onGetTime(void) { // NOTE: invoked with interrupts DISABLED + if ((SysTick->CTRL & 0x00010000U) == 0U) { // COUNT no set? return QS_tickTime_ - (QSTimeCtr)SysTick->VAL; } - else { /* the rollover occured, but the SysTick_ISR did not run yet */ + else { // the rollover occured, but the SysTick_ISR did not run yet return QS_tickTime_ + QS_tickPeriod_ - (QSTimeCtr)SysTick->VAL; } } -/*..........................................................................*/ +//............................................................................ void QS_onFlush(void) { - uint16_t b; - - QF_INT_DISABLE(); - while ((b = QS_getByte()) != QS_EOD) { /* while not End-Of-Data... */ - QF_INT_ENABLE(); - while ((USART2->SR & (1U << 7)) == 0U) { /* while TXE not empty */ - } - USART2->DR = (b & 0xFFU); /* put into the DR register */ + for (;;) { QF_INT_DISABLE(); + uint16_t b = QS_getByte(); + if (b != QS_EOD) { + while ((USART2->SR & (1U << 7U)) == 0U) { // while TXE not empty + QF_INT_ENABLE(); + QF_CRIT_EXIT_NOP(); + + QF_INT_DISABLE(); + } + USART2->DR = b; // put into the DR register + QF_INT_ENABLE(); + } + else { + QF_INT_ENABLE(); + break; + } } - QF_INT_ENABLE(); } -/*..........................................................................*/ -/*! callback function to reset the target (to be implemented in the BSP) */ +//............................................................................ +//! callback function to reset the target (to be implemented in the BSP) void QS_onReset(void) { NVIC_SystemReset(); } -/*..........................................................................*/ -/*! callback function to execute a user command (to be implemented in BSP) */ +//............................................................................ +//! callback function to execute a user command void QS_onCommand(uint8_t cmdId, uint32_t param1, uint32_t param2, uint32_t param3) { - (void)cmdId; - (void)param1; - (void)param2; - (void)param3; + Q_UNUSED_PAR(cmdId); + Q_UNUSED_PAR(param1); + Q_UNUSED_PAR(param2); + Q_UNUSED_PAR(param3); } -#endif /* Q_SPY */ -/*--------------------------------------------------------------------------*/ +#endif // Q_SPY +//---------------------------------------------------------------------------- -/***************************************************************************** -* NOTE00: -* The QF_AWARE_ISR_CMSIS_PRI constant from the QF port specifies the highest -* ISR priority that is disabled by the QF framework. The value is suitable -* for the NVIC_SetPriority() CMSIS function. -* -* Only ISRs prioritized at or below the QF_AWARE_ISR_CMSIS_PRI level (i.e., -* with the numerical values of priorities equal or higher than -* QF_AWARE_ISR_CMSIS_PRI) are allowed to call any QF services. These ISRs -* are "QF-aware". -* -* Conversely, any ISRs prioritized above the QF_AWARE_ISR_CMSIS_PRI priority -* level (i.e., with the numerical values of priorities less than -* QF_AWARE_ISR_CMSIS_PRI) are never disabled and are not aware of the kernel. -* Such "QF-unaware" ISRs cannot call any QF services. The only mechanism -* by which a "QF-unaware" ISR can communicate with the QF framework is by -* triggering a "QF-aware" ISR, which can post/publish events. -* -* NOTE01: -* Usually, one of the LEDs is used to visualize the idle loop activity. -* However, the board has not enough LEDs (only one, actually), so this -* feature is disabled. -*/ +//============================================================================ +// NOTE1: +// The QF_AWARE_ISR_CMSIS_PRI constant from the QF port specifies the highest +// ISR priority that is disabled by the QF framework. The value is suitable +// for the NVIC_SetPriority() CMSIS function. +// +// Only ISRs prioritized at or below the QF_AWARE_ISR_CMSIS_PRI level (i.e., +// with the numerical values of priorities equal or higher than +// QF_AWARE_ISR_CMSIS_PRI) are allowed to call the QK_ISR_ENTRY/ +// QK_ISR_ENTRY macros or any other QF/QK services. These ISRs are +// "QF-aware". +// +// Conversely, any ISRs prioritized above the QF_AWARE_ISR_CMSIS_PRI priority +// level (i.e., with the numerical values of priorities less than +// QF_AWARE_ISR_CMSIS_PRI) are never disabled and are not aware of the kernel. +// Such "QF-unaware" ISRs cannot call ANY QF/QK services. In particular they +// can NOT call the macros QK_ISR_ENTRY/QK_ISR_ENTRY. The only mechanism +// by which a "QF-unaware" ISR can communicate with the QF framework is by +// triggering a "QF-aware" ISR, which can post/publish events. +// +// NOTE2: +// The User LED is used to visualize the idle loop activity. The brightness +// of the LED is proportional to the frequency of the idle loop. +// Please note that the LED is toggled with interrupts locked, so no interrupt +// execution time contributes to the brightness of the User LED. +// diff --git a/examples/arm-cm/dpp_nucleo-l152re/qk/gnu/Makefile b/examples/arm-cm/dpp_nucleo-l152re/qk/gnu/Makefile index 7955ce92..c55ba5e9 100644 --- a/examples/arm-cm/dpp_nucleo-l152re/qk/gnu/Makefile +++ b/examples/arm-cm/dpp_nucleo-l152re/qk/gnu/Makefile @@ -127,14 +127,14 @@ QP_ASMS := QS_SRCS := \ qs.c \ qs_rx.c \ - qs_64bit.c \ qs_fp.c LIB_DIRS := LIBS := # defines -DEFINES := +DEFINES := \ + -DQF_ON_CONTEXT_SW # ARM CPU, ARCH, FPU, and Float-ABI types... # ARM_CPU: [cortex-m0 | cortex-m0plus | cortex-m1 | cortex-m3 | cortex-m4] @@ -262,7 +262,7 @@ $(TARGET_BIN): $(TARGET_ELF) $(BIN) -O binary $< $@ $(TARGET_ELF) : $(ASM_OBJS_EXT) $(C_OBJS_EXT) $(CPP_OBJS_EXT) - $(CC) $(CFLAGS) $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o + $(CC) $(CFLAGS) $(QPC)/src/qs/qstamp.c -o $(BIN_DIR)/qstamp.o $(LINK) $(LINKFLAGS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) $(BIN_DIR)/%.d : %.c diff --git a/examples/arm-cm/dpp_nucleo-l152re/qk/gnu/dpp-qk.ld b/examples/arm-cm/dpp_nucleo-l152re/qk/gnu/dpp-qk.ld index b3a6ec97..349f5dc6 100644 --- a/examples/arm-cm/dpp_nucleo-l152re/qk/gnu/dpp-qk.ld +++ b/examples/arm-cm/dpp_nucleo-l152re/qk/gnu/dpp-qk.ld @@ -91,8 +91,9 @@ SECTIONS { .stack : { __stack_start__ = .; . = . + STACK_SIZE; - . = ALIGN(4); + . = ALIGN(8); __stack_end__ = .; + ASSERT(((. - __stack_start__) == STACK_SIZE), "Error: Stack misaligned"); } >RAM .data : AT (_etext) { diff --git a/examples/arm-cm/dpp_nucleo-l152re/qk/iar/dpp-qk.ewd b/examples/arm-cm/dpp_nucleo-l152re/qk/iar/dpp-qk.ewd index fe187d7a..63befcfe 100644 --- a/examples/arm-cm/dpp_nucleo-l152re/qk/iar/dpp-qk.ewd +++ b/examples/arm-cm/dpp_nucleo-l152re/qk/iar/dpp-qk.ewd @@ -11,7 +11,7 @@ C-SPY 2 - 29 + 32 1 1 - - + + + + @@ -490,7 +498,7 @@ IJET_ID 2 - 8 + 9 1 1 + + + + + + + + + + + + + @@ -920,7 +980,7 @@ LMIFTDI_ID 2 - 2 + 3 1 1 + + + + + + + NULINK_ID + 2 + + 0 + 1 + 1 + + + @@ -978,7 +1072,7 @@ STLINK_ID 2 - 4 + 8 1 1 + + + + @@ -1189,7 +1300,7 @@ XDS100_ID 2 - 6 + 9 1 1 + + + + @@ -1366,10 +1493,18 @@ $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin 0 + + $TOOLKIT_DIR$\plugins\rtos\FreeRtos\FreeRtosArmPlugin.ENU.ewplugin + 0 + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin.ENU.ewplugin 0 + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin2.ENU.ewplugin + 0 + $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin 0 @@ -1379,11 +1514,15 @@ 0 - $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9.ewplugin 0 - $TOOLKIT_DIR$\plugins\rtos\TI-RTOS\tirtosplugin.ewplugin + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9BE.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin 0 @@ -1398,10 +1537,6 @@ $TOOLKIT_DIR$\plugins\rtos\uCOS-III\uCOS-III-KA-CSpy.ewplugin 0 - - $EW_DIR$\common\plugins\CodeCoverage\CodeCoverage.ENU.ewplugin - 1 - $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin 0 @@ -1426,7 +1561,7 @@ C-SPY 2 - 29 + 32 1 0 - - + + + + @@ -1905,7 +2048,7 @@ IJET_ID 2 - 8 + 9 1 0 + + + + + + + + + + + + + @@ -2335,7 +2530,7 @@ LMIFTDI_ID 2 - 2 + 3 1 0 + + + + + + + NULINK_ID + 2 + + 0 + 1 + 0 + + + @@ -2393,7 +2622,7 @@ STLINK_ID 2 - 4 + 8 1 0 + + + + @@ -2604,7 +2850,7 @@ XDS100_ID 2 - 6 + 9 1 0 + + + + @@ -2781,10 +3043,18 @@ $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin 0 + + $TOOLKIT_DIR$\plugins\rtos\FreeRtos\FreeRtosArmPlugin.ENU.ewplugin + 0 + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin.ENU.ewplugin 0 + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin2.ENU.ewplugin + 0 + $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin 0 @@ -2794,11 +3064,15 @@ 0 - $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9.ewplugin 0 - $TOOLKIT_DIR$\plugins\rtos\TI-RTOS\tirtosplugin.ewplugin + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9BE.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin 0 @@ -2813,10 +3087,6 @@ $TOOLKIT_DIR$\plugins\rtos\uCOS-III\uCOS-III-KA-CSpy.ewplugin 0 - - $EW_DIR$\common\plugins\CodeCoverage\CodeCoverage.ENU.ewplugin - 1 - $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin 0 @@ -2841,7 +3111,7 @@ C-SPY 2 - 29 + 32 1 1 - - + + + + @@ -3320,7 +3598,7 @@ IJET_ID 2 - 8 + 9 1 1 + + + + + + + + + + + + + @@ -3750,7 +4080,7 @@ LMIFTDI_ID 2 - 2 + 3 1 1 + + + + + + + NULINK_ID + 2 + + 0 + 1 + 1 + + + @@ -3808,7 +4172,7 @@ STLINK_ID 2 - 4 + 8 1 1 + + + + @@ -4019,7 +4400,7 @@ XDS100_ID 2 - 6 + 9 1 1 + + + + @@ -4196,10 +4593,18 @@ $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin 0 + + $TOOLKIT_DIR$\plugins\rtos\FreeRtos\FreeRtosArmPlugin.ENU.ewplugin + 0 + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin.ENU.ewplugin 0 + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin2.ENU.ewplugin + 0 + $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin 0 @@ -4209,11 +4614,15 @@ 0 - $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9.ewplugin 0 - $TOOLKIT_DIR$\plugins\rtos\TI-RTOS\tirtosplugin.ewplugin + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9BE.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin 0 @@ -4228,10 +4637,6 @@ $TOOLKIT_DIR$\plugins\rtos\uCOS-III\uCOS-III-KA-CSpy.ewplugin 0 - - $EW_DIR$\common\plugins\CodeCoverage\CodeCoverage.ENU.ewplugin - 1 - $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin 0 diff --git a/examples/arm-cm/dpp_nucleo-l152re/qk/iar/dpp-qk.ewp b/examples/arm-cm/dpp_nucleo-l152re/qk/iar/dpp-qk.ewp index eec6876e..4422b426 100644 --- a/examples/arm-cm/dpp_nucleo-l152re/qk/iar/dpp-qk.ewp +++ b/examples/arm-cm/dpp_nucleo-l152re/qk/iar/dpp-qk.ewp @@ -11,9 +11,13 @@ General 3 - 31 + 35 1 1 + - - - - - + + + + + ICCARM 2 - 35 + 37 1 1 - - - + AARM 2 - 10 + 11 1 1 + @@ -672,13 +668,9 @@ 0 + inputOutputBased - - BICOMP - 0 - - BUILDACTION 1 @@ -691,17 +683,13 @@ ILINK 0 - 23 + 27 1 1 - + + + + + + + + + @@ -1050,11 +1074,6 @@ - - BILINK - 0 - - Coder 0 @@ -1071,9 +1090,13 @@ General 3 - 31 + 35 1 0 + - - - - - + + + + + ICCARM 2 - 35 + 37 1 0 - - - + AARM 2 - 10 + 11 1 0 + @@ -1732,13 +1747,9 @@ 0 + inputOutputBased - - BICOMP - 0 - - BUILDACTION 1 @@ -1751,17 +1762,13 @@ ILINK 0 - 23 + 27 1 0 - + + + + + + + + + @@ -2110,11 +2153,6 @@ - - BILINK - 0 - - Coder 0 @@ -2131,9 +2169,13 @@ General 3 - 31 + 35 1 1 + - - - - - + + + + + ICCARM 2 - 35 + 37 1 1 - - - + AARM 2 - 10 + 11 1 1 + @@ -2792,13 +2826,9 @@ 0 + inputOutputBased - - BICOMP - 0 - - BUILDACTION 1 @@ -2811,17 +2841,13 @@ ILINK 0 - 23 + 27 1 1 - + + + + + + + + + @@ -3170,11 +3232,6 @@ - - BILINK - 0 - - Coder 0 @@ -3193,14 +3250,11 @@ $PROJ_DIR$\..\..\dpp.h - $PROJ_DIR$\..\main.c + $PROJ_DIR$\..\..\main.c $PROJ_DIR$\..\..\philo.c - - $PROJ_DIR$\..\..\..\..\..\include\qstamp.c - $PROJ_DIR$\..\..\table.c @@ -3270,21 +3324,9 @@ QP_port - - $PROJ_DIR$\..\..\..\..\..\ports\arm-cm\qk\iar\qep_port.h - - - $PROJ_DIR$\..\..\..\..\..\ports\arm-cm\qk\iar\qf_port.h - $PROJ_DIR$\..\..\..\..\..\ports\arm-cm\qk\iar\qk_port.c - - $PROJ_DIR$\..\..\..\..\..\ports\arm-cm\qk\iar\qk_port.h - - - $PROJ_DIR$\..\..\..\..\..\ports\arm-cm\qk\iar\qs_port.h - QS @@ -3301,5 +3343,8 @@ $PROJ_DIR$\..\..\..\..\..\src\qs\qs_rx.c + + $PROJ_DIR$\..\..\..\..\..\src\qs\qstamp.c + diff --git a/examples/arm-cm/dpp_nucleo-l152re/qk/main.c b/examples/arm-cm/dpp_nucleo-l152re/qk/main.c deleted file mode 100644 index c723bd47..00000000 --- a/examples/arm-cm/dpp_nucleo-l152re/qk/main.c +++ /dev/null @@ -1,87 +0,0 @@ -/***************************************************************************** -* Product: DPP example -* Last updated for version 7.1.1 -* Last updated on 2022-09-22 -* -* Q u a n t u m L e a P s -* ------------------------ -* Modern Embedded Software -* -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* -* -*****************************************************************************/ -#include "qpc.h" -#include "dpp.h" -#include "bsp.h" - -Q_DEFINE_THIS_FILE - -/*..........................................................................*/ -int main() { - static QEvt const *tableQueueSto[N_PHILO]; - static QEvt const *philoQueueSto[N_PHILO][N_PHILO]; - static QSubscrList subscrSto[MAX_PUB_SIG]; - static QF_MPOOL_EL(TableEvt) smlPoolSto[2*N_PHILO]; /* small pool */ - uint8_t n; - - Philo_ctor(); /* instantiate all Philosopher active objects */ - Table_ctor(); /* instantiate the Table active object */ - - QF_init(); /* initialize the framework and the underlying RT kernel */ - BSP_init(); /* initialize the Board Support Package */ - - /* object dictionaries... */ - QS_OBJ_DICTIONARY(AO_Table); - QS_OBJ_DICTIONARY(AO_Philo[0]); - QS_OBJ_DICTIONARY(AO_Philo[1]); - QS_OBJ_DICTIONARY(AO_Philo[2]); - QS_OBJ_DICTIONARY(AO_Philo[3]); - QS_OBJ_DICTIONARY(AO_Philo[4]); - - /* initialize publish-subscribe... */ - QF_psInit(subscrSto, Q_DIM(subscrSto)); - - /* initialize event pools... */ - QF_poolInit(smlPoolSto, sizeof(smlPoolSto), sizeof(smlPoolSto[0])); - - /* start the active objects... */ - for (n = 0U; n < N_PHILO; ++n) { - QACTIVE_START(AO_Philo[n], /* AO to start */ - Q_PRIO(n + 1U, N_PHILO), /* QF-prio/pre-thre. */ - philoQueueSto[n], /* event queue storage */ - Q_DIM(philoQueueSto[n]), /* queue length [events] */ - (void *)0, /* stack storage (not used) */ - 0U, /* size of the stack [bytes] */ - (void *)0); /* initialization param */ - } - QACTIVE_START(AO_Table, /* AO to start */ - N_PHILO + 1U, /* QF-prio/pre-thre. */ - tableQueueSto, /* event queue storage */ - Q_DIM(tableQueueSto), /* queue length [events] */ - (void *)0, /* stack storage (not used) */ - 0U, /* size of the stack [bytes] */ - (void *)0); /* initialization param */ - - return QF_run(); /* run the QF application */ -} diff --git a/examples/arm-cm/dpp_nucleo-l152re/qspy200824_123319.bin b/examples/arm-cm/dpp_nucleo-l152re/qspy200824_123319.bin deleted file mode 100644 index 66d268bc..00000000 Binary files a/examples/arm-cm/dpp_nucleo-l152re/qspy200824_123319.bin and /dev/null differ diff --git a/examples/arm-cm/dpp_nucleo-l152re/qspy200824_123412.seq b/examples/arm-cm/dpp_nucleo-l152re/qspy200824_123412.seq deleted file mode 100644 index 9f4c2883..00000000 --- a/examples/arm-cm/dpp_nucleo-l152re/qspy200824_123412.seq +++ /dev/null @@ -1,126 +0,0 @@ --g l_SysTick_Handler,Table_inst,Philo_inst[0],Philo_inst[1],Philo_inst[2],Philo_inst[3],Philo_inst[4] - - +-------+-------+ +-------+-------+ +-------+-------+ +-------+-------+ +-------+-------+ +-------+-------+ +-------+-------+ - |l_SysTick_Handl| | Table_inst | | Philo_inst[0] | | Philo_inst[1] | | Philo_inst[2] | | Philo_inst[3] | | Philo_inst[4] | - +-------+-------+ +-------+-------+ +-------+-------+ +-------+-------+ +-------+-------+ +-------+-------+ +-------+-------+ -4294946722 . . . . * .SERVE_SIG. . . . | . . . . . . . . . | . . . . . . . . . | . . . . . . . . . | . . . . . . . . . | . . . . . . . . . | . . . -4294947277 *--SERVE_SIG------->| | | | | | -4294947535 *--TIMEOUT_SIG------+-------------------+-------------------+-------------------+-------------------+------------------>| -4294952081 | |<------------------+-------------------+-------------------+-------------------+-------HUNGRY_SIG--* -4294955759 . . . . | . . . . . . . . . * .EAT_SIG. . . . . | . . . . . . . . . | . . . . . . . . . | . . . . . . . . . | . . . . . . . . . | . . . -4294956667 | *--EAT_SIG----------+-------------------+-------------------+-------------------+------------------>| -4294957464 | *--EAT_SIG----------+-------------------+-------------------+------------------>| | -4294958261 | *--EAT_SIG----------+-------------------+------------------>| | | -4294959058 | *--EAT_SIG----------+------------------>| | | | -4294959855 | *--EAT_SIG--------->| | | | | -4294964080 | | | | | | -4294946874 | | | | | | -4294947628 *--TIMEOUT_SIG------+------------------>| | | | | -4294952066 | |<------HUNGRY_SIG--* | | | | -4294956967 | | | | | | -4294947560 *--TIMEOUT_SIG------+-------------------+-------------------+------------------>| | | -4294952034 | |<------------------+-------------------+-------HUNGRY_SIG--* | | -4294955712 . . . . | . . . . . . . . . * .EAT_SIG. . . . . | . . . . . . . . . | . . . . . . . . . | . . . . . . . . . | . . . . . . . . . | . . . -4294956620 | *--EAT_SIG----------+-------------------+-------------------+-------------------+------------------>| -4294957416 | *--EAT_SIG----------+-------------------+-------------------+------------------>| | -4294958212 | *--EAT_SIG----------+-------------------+------------------>| | | -4294959008 | *--EAT_SIG----------+------------------>| | | | -4294959804 | *--EAT_SIG--------->| | | | | -4294948109 | | | | | | -4294951527 | | | | | | -4294947560 *--TIMEOUT_SIG------+-------------------+------------------>| | | | -4294952034 | |<------------------+-------HUNGRY_SIG--* | | | -4294956932 | | | | | | -4294947535 *--TIMEOUT_SIG------+-------------------+-------------------+-------------------+------------------>| | -4294952009 | |<------------------+-------------------+-------------------+-------HUNGRY_SIG--* | -4294956907 | | | | | | -4294947530 *--TIMEOUT_SIG------+-------------------+-------------------+-------------------+-------------------+------------------>| -4294950987 . . . . | . . . . . . . . . | . . . . . . . . . | . . . . . . . . . | . . . . . . . . . | . . . . . . . . . | . . . . DONE_SIG. * . . . -4294951895 | |<------------------+-------------------+-------------------+-------------------+---------DONE_SIG--* -4294956005 . . . . | . . . . . . . . . * .EAT_SIG. . . . . | . . . . . . . . . | . . . . . . . . . | . . . . . . . . . | . . . . . . . . . | . . . -4294956913 | *--EAT_SIG----------+-------------------+-------------------+-------------------+------------------>| -4294957725 | *--EAT_SIG----------+-------------------+-------------------+------------------>| | -4294958521 | *--EAT_SIG----------+-------------------+------------------>| | | -4294959317 | *--EAT_SIG----------+------------------>| | | | -4294960113 | *--EAT_SIG--------->| | | | | -4294965793 | | | | | | -4294959029 | | | | | | -4294946649 . . . . * .PAUSE_SIG. . . . | . . . . . . . . . | . . . . . . . . . | . . . . . . . . . | . . . . . . . . . | . . . . . . . . . | . . . -4294947203 *--PAUSE_SIG------->| | | | | | -4294950125 | | | | | | -4294947520 *--TIMEOUT_SIG------+-------------------+-------------------+------------------>| | | -4294950997 . . . . | . . . . . . . . . | . . . . . . . . . | . . . . . . . . . | . . . . . . . . . * .DONE_SIG . . . . | . . . . . . . . . | . . . -4294951905 | |<------------------+-------------------+---------DONE_SIG--* | | -4294958730 | | | | | | -4294947521 *--TIMEOUT_SIG------+-------------------+-------------------+-------------------+-------------------+------------------>| -4294951995 | |<------------------+-------------------+-------------------+-------------------+-------HUNGRY_SIG--* -4294956867 | | | | | | -4294947520 *--TIMEOUT_SIG------+------------------>| | | | | -4294950961 . . . . | . . . . . . . . . | . . . . . . . . . * .DONE_SIG . . . . | . . . . . . . . . | . . . . . . . . . | . . . . . . . . . | . . . -4294951869 | |<--------DONE_SIG--* | | | | -4294958646 | | | | | | -4294947524 *--TIMEOUT_SIG------+-------------------+-------------------+------------------>| | | -4294951962 | |<------------------+-------------------+-------HUNGRY_SIG--* | | -4294956834 | | | | | | -4294947537 *--TIMEOUT_SIG------+------------------>| | | | | -4294951939 | |<------HUNGRY_SIG--* | | | | -4294956811 | | | | | | -4294946542 . . . . * .SERVE_SIG. . . . | . . . . . . . . . | . . . . . . . . . | . . . . . . . . . | . . . . . . . . . | . . . . . . . . . | . . . -4294947096 *--SERVE_SIG------->| | | | | | -4294950966 . . . . | . . . . . . . . . * .EAT_SIG. . . . . | . . . . . . . . . | . . . . . . . . . | . . . . . . . . . | . . . . . . . . . | . . . -4294951874 | *--EAT_SIG----------+-------------------+-------------------+-------------------+------------------>| -4294952670 | *--EAT_SIG----------+-------------------+-------------------+------------------>| | -4294953466 | *--EAT_SIG----------+-------------------+------------------>| | | -4294954262 | *--EAT_SIG----------+------------------>| | | | -4294955058 | *--EAT_SIG--------->| | | | | -4294958067 . . . . | . . . . . . . . . * .EAT_SIG. . . . . | . . . . . . . . . | . . . . . . . . . | . . . . . . . . . | . . . . . . . . . | . . . -4294958976 | *--EAT_SIG----------+-------------------+-------------------+-------------------+------------------>| -4294959752 | *--EAT_SIG----------+-------------------+-------------------+------------------>| | -4294960528 | *--EAT_SIG----------+-------------------+------------------>| | | -4294961304 | *--EAT_SIG----------+------------------>| | | | -4294962080 | *--EAT_SIG--------->| | | | | -4294964514 | | | | | | -4294961504 | | | | | | -4294950324 | | | | | | -4294947523 *--TIMEOUT_SIG------+-------------------+-------------------+------------------>| | | -4294950964 . . . . | . . . . . . . . . | . . . . . . . . . | . . . . . . . . . | . . . . . . . . . * .DONE_SIG . . . . | . . . . . . . . . | . . . -4294951872 | |<------------------+-------------------+---------DONE_SIG--* | | -4294955992 . . . . | . . . . . . . . . * .EAT_SIG. . . . . | . . . . . . . . . | . . . . . . . . . | . . . . . . . . . | . . . . . . . . . | . . . -4294956900 | *--EAT_SIG----------+-------------------+-------------------+-------------------+------------------>| -4294957696 | *--EAT_SIG----------+-------------------+-------------------+------------------>| | -4294958508 | *--EAT_SIG----------+-------------------+------------------>| | | -4294959304 | *--EAT_SIG----------+------------------>| | | | -4294960100 | *--EAT_SIG--------->| | | | | -4294947872 | | | | | | -4294951644 | | | | | | -4294947527 *--TIMEOUT_SIG------+------------------>| | | | | -4294949289 *--TIMEOUT_SIG------+-------------------+-------------------+------------------>| | | -4294953727 | |<------------------+-------------------+-------HUNGRY_SIG--* | | -4294958625 | | | | | | -4294961848 . . . . | . . . . . . . . . | . . . . . . . . . * .DONE_SIG . . . . | . . . . . . . . . | . . . . . . . . . | . . . . . . . . . | . . . -4294962756 | |<--------DONE_SIG--* | | | | -4294966866 . . . . | . . . . . . . . . * .EAT_SIG. . . . . | . . . . . . . . . | . . . . . . . . . | . . . . . . . . . | . . . . . . . . . | . . . - +-------+-------+ +-------+-------+ +-------+-------+ +-------+-------+ +-------+-------+ +-------+-------+ +-------+-------+ - |l_SysTick_Handl| | Table_inst | | Philo_inst[0] | | Philo_inst[1] | | Philo_inst[2] | | Philo_inst[3] | | Philo_inst[4] | - +-------+-------+ +-------+-------+ +-------+-------+ +-------+-------+ +-------+-------+ +-------+-------+ +-------+-------+ -4294946999 | *--EAT_SIG----------+-------------------+-------------------+-------------------+------------------>| -4294947795 | *--EAT_SIG----------+-------------------+-------------------+------------------>| | -4294948591 | *--EAT_SIG----------+-------------------+------------------>| | | -4294949387 | *--EAT_SIG----------+------------------>| | | | -4294950183 | *--EAT_SIG--------->| | | | | -4294964009 | | | | | | -4294947090 | | | | | | -4294947559 *--TIMEOUT_SIG------+------------------>| | | | | -4294951997 | |<------HUNGRY_SIG--* | | | | -4294956911 | | | | | | -4294947520 *--TIMEOUT_SIG------+-------------------+-------------------+-------------------+------------------>| | -4294950961 . . . . | . . . . . . . . . | . . . . . . . . . | . . . . . . . . . | . . . . . . . . . | . . . . . . . . . * .DONE_SIG . . . . | . . . -4294951869 | |<------------------+-------------------+-------------------+---------DONE_SIG--* | -4294955979 . . . . | . . . . . . . . . * .EAT_SIG. . . . . | . . . . . . . . . | . . . . . . . . . | . . . . . . . . . | . . . . . . . . . | . . . -4294956887 | *--EAT_SIG----------+-------------------+-------------------+-------------------+------------------>| -4294957683 | *--EAT_SIG----------+-------------------+-------------------+------------------>| | -4294958479 | *--EAT_SIG----------+-------------------+------------------>| | | -4294959275 | *--EAT_SIG----------+------------------>| | | | -4294960071 | *--EAT_SIG--------->| | | | | -4294965770 | | | | | | -4294948812 | | | | | | diff --git a/examples/arm-cm/dpp_nucleo-l152re/qspy200824_123438.seq b/examples/arm-cm/dpp_nucleo-l152re/qspy200824_123438.seq deleted file mode 100644 index 81d33a92..00000000 --- a/examples/arm-cm/dpp_nucleo-l152re/qspy200824_123438.seq +++ /dev/null @@ -1,99 +0,0 @@ --g l_SysTick_Handler,Table_inst,? - - +-------+-------+ +-------+-------+ +-------+-------+ - |l_SysTick_Handl| | Table_inst | | ? | - +-------+-------+ +-------+-------+ +-------+-------+ -4294946722 . . . . * .SERVE_SIG. . . . | . . . . . . . . . / . . . -4294947277 *--SERVE_SIG------->| / -4294947535 *--TIMEOUT_SIG------+------------------>/ -4294952081 | |<------HUNGRY_SIG--* -4294955759 . . . . | . . . . . . . . . * .EAT_SIG. . . . . / . . . -4294956667 | *--EAT_SIG--------->/ -4294957464 | *--EAT_SIG--------->/ -4294958261 | *--EAT_SIG--------->/ -4294959058 | *--EAT_SIG--------->/ -4294959855 | *--EAT_SIG--------->/ -4294947628 *--TIMEOUT_SIG------+------------------>/ -4294952066 | |<------HUNGRY_SIG--* -4294947560 *--TIMEOUT_SIG------+------------------>/ -4294952034 | |<------HUNGRY_SIG--* -4294955712 . . . . | . . . . . . . . . * .EAT_SIG. . . . . / . . . -4294956620 | *--EAT_SIG--------->/ -4294957416 | *--EAT_SIG--------->/ -4294958212 | *--EAT_SIG--------->/ -4294959008 | *--EAT_SIG--------->/ -4294959804 | *--EAT_SIG--------->/ -4294947560 *--TIMEOUT_SIG------+------------------>/ -4294952034 | |<------HUNGRY_SIG--* -4294947535 *--TIMEOUT_SIG------+------------------>/ -4294952009 | |<------HUNGRY_SIG--* -4294947530 *--TIMEOUT_SIG------+------------------>/ -4294950987 . . . . | . . . . . . . . . | . . . . DONE_SIG. * . . . -4294951895 | |<--------DONE_SIG--* -4294956005 . . . . | . . . . . . . . . * .EAT_SIG. . . . . / . . . -4294956913 | *--EAT_SIG--------->/ -4294957725 | *--EAT_SIG--------->/ -4294958521 | *--EAT_SIG--------->/ -4294959317 | *--EAT_SIG--------->/ -4294960113 | *--EAT_SIG--------->/ -4294946649 . . . . * .PAUSE_SIG. . . . | . . . . . . . . . / . . . -4294947203 *--PAUSE_SIG------->| / -4294950125 | / -4294947520 *--TIMEOUT_SIG------+------------------>/ -4294950997 . . . . | . . . . . . . . . | . . . . DONE_SIG. * . . . -4294951905 | |<--------DONE_SIG--* -4294947521 *--TIMEOUT_SIG------+------------------>/ -4294951995 | |<------HUNGRY_SIG--* -4294947520 *--TIMEOUT_SIG------+------------------>/ -4294950961 . . . . | . . . . . . . . . | . . . . DONE_SIG. * . . . -4294951869 | |<--------DONE_SIG--* -4294947524 *--TIMEOUT_SIG------+------------------>/ -4294951962 | |<------HUNGRY_SIG--* -4294947537 *--TIMEOUT_SIG------+------------------>/ -4294951939 | |<------HUNGRY_SIG--* -4294946542 . . . . * .SERVE_SIG. . . . | . . . . . . . . . / . . . -4294947096 *--SERVE_SIG------->| / -4294950966 . . . . | . . . . . . . . . * .EAT_SIG. . . . . / . . . -4294951874 | *--EAT_SIG--------->/ -4294952670 | *--EAT_SIG--------->/ -4294953466 | *--EAT_SIG--------->/ -4294954262 | *--EAT_SIG--------->/ -4294955058 | *--EAT_SIG--------->/ -4294958067 . . . . | . . . . . . . . . * .EAT_SIG. . . . . / . . . -4294958976 | *--EAT_SIG--------->/ -4294959752 | *--EAT_SIG--------->/ -4294960528 | *--EAT_SIG--------->/ -4294961304 | *--EAT_SIG--------->/ -4294962080 | *--EAT_SIG--------->/ -4294964514 | / -4294947523 *--TIMEOUT_SIG------+------------------>/ -4294950964 . . . . | . . . . . . . . . | . . . . DONE_SIG. * . . . -4294951872 | |<--------DONE_SIG--* -4294955992 . . . . | . . . . . . . . . * .EAT_SIG. . . . . / . . . -4294956900 | *--EAT_SIG--------->/ -4294957696 | *--EAT_SIG--------->/ -4294958508 | *--EAT_SIG--------->/ -4294959304 | *--EAT_SIG--------->/ -4294960100 | *--EAT_SIG--------->/ -4294947527 *--TIMEOUT_SIG------+------------------>/ -4294949289 *--TIMEOUT_SIG------+------------------>/ -4294953727 | |<------HUNGRY_SIG--* -4294961848 . . . . | . . . . . . . . . | . . . . DONE_SIG. * . . . -4294962756 | |<--------DONE_SIG--* -4294966866 . . . . | . . . . . . . . . * .EAT_SIG. . . . . / . . . -4294946999 | *--EAT_SIG--------->/ -4294947795 | *--EAT_SIG--------->/ -4294948591 | *--EAT_SIG--------->/ -4294949387 | *--EAT_SIG--------->/ -4294950183 | *--EAT_SIG--------->/ -4294947559 *--TIMEOUT_SIG------+------------------>/ -4294951997 | |<------HUNGRY_SIG--* -4294947520 *--TIMEOUT_SIG------+------------------>/ -4294950961 . . . . | . . . . . . . . . | . . . . DONE_SIG. * . . . -4294951869 | |<--------DONE_SIG--* -4294955979 . . . . | . . . . . . . . . * .EAT_SIG. . . . . / . . . -4294956887 | *--EAT_SIG--------->/ -4294957683 | *--EAT_SIG--------->/ -4294958479 | *--EAT_SIG--------->/ -4294959275 | *--EAT_SIG--------->/ -4294960071 | *--EAT_SIG--------->/ diff --git a/examples/arm-cm/dpp_nucleo-l152re/qv/armclang/dpp-qv.sct b/examples/arm-cm/dpp_nucleo-l152re/qv/armclang/dpp-qv.sct new file mode 100644 index 00000000..fbadbbfa --- /dev/null +++ b/examples/arm-cm/dpp_nucleo-l152re/qv/armclang/dpp-qv.sct @@ -0,0 +1,22 @@ +; ************************************************************* +; *** Scatter-Loading Description File generated by uVision *** +; +; Adapted by Quantum Leaps: +; moved STACK as the first section in RW_IRAM1 +; ************************************************************* + +LR_IROM1 0x08000000 0x00080000 { ; load region size_region + ER_IROM1 0x08000000 0x00080000 { ; load address = execution address + *.o (RESET, +First) + *(InRoot$$Sections) + .ANY (+RO) + .ANY (+XO) + } + RW_STACK 0x20000000 { ; <== Quantum Leaps + * (STACK, +First) + } + RW_IRAM1 +0 (0x00014000 - 2048) { ; NOTE: 2048 assumed for STACK size! + .ANY (+RW +ZI) + } +} + diff --git a/examples/arm-cm/dpp_nucleo-l152re/qv/armclang/dpp-qv.uvoptx b/examples/arm-cm/dpp_nucleo-l152re/qv/armclang/dpp-qv.uvoptx index 231fca7c..b7a0efc2 100644 --- a/examples/arm-cm/dpp_nucleo-l152re/qv/armclang/dpp-qv.uvoptx +++ b/examples/arm-cm/dpp_nucleo-l152re/qv/armclang/dpp-qv.uvoptx @@ -116,6 +116,415 @@ STLink\ST-LINKIII-KEIL_SWO.dll + + + 0 + ARMRTXEVENTFLAGS + -L70 -Z18 -C0 -M0 -T1 + + + 0 + DLGTARM + (1010=1491,653,1941,1210,1)(1007=-1,-1,-1,-1,0)(1008=-1,-1,-1,-1,0)(1009=-1,-1,-1,-1,0)(1012=-1,-1,-1,-1,0) + + + 0 + ARMDBGFLAGS + + + + 0 + DLGUARM + (105=-1,-1,-1,-1,0) + + + 0 + ST-LINKIII-KEIL_SWO + -U066EFF495056805087184715 -O8398 -SF10000 -C0 -A0 -I0 -HNlocalhost -HP7184 -P1 -N00("ARM CoreSight SW-DP (ARM Core") -D00(2BA01477) -L00(0) -TO131090 -TC10000000 -TT10000000 -TP21 -TDS8007 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -FO15 -FD20000000 -FC1000 -FN1 -FF0STM32L1xx_512.FLM -FS08000000 -FL080000 -FP0($$Device:STM32L152RE$CMSIS\Flash\STM32L1xx_512.FLM) + + + 0 + UL2CM3 + UL2CM3(-S0 -C0 -P0 -FD20000000 -FC1000 -FN1 -FF0STM32L1xx_512 -FS08000000 -FL080000 -FP0($$Device:STM32L152RE$CMSIS\Flash\STM32L1xx_512.FLM)) + + + + + 0 + 0 + 273 + 1 +
0
+ 0 + 0 + 0 + 0 + 0 + 0 + ..\bsp.c + + +
+
+ + + 1 + 2 + 0x20000200 + 0 + + + + + 2 + 0 + 0x400 + 0 + + + + 0 + + + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + + + + 0 + 0 + 0 + + + + + + + + + + 1 + 0 + 0 + 2 + 10000000 + + + + + + dpp-rel + 0x4 + ARM-ADS + + 12000000 + + 1 + 1 + 0 + 1 + 0 + + + 1 + 65535 + 0 + 0 + 0 + + + 79 + 66 + 8 + .\rel\ + + + 1 + 1 + 1 + 0 + 1 + 1 + 0 + 1 + 0 + 0 + 0 + 0 + + + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + + + 1 + 0 + 0 + + 18 + + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + 0 + 1 + 1 + 0 + 0 + 1 + 0 + 0 + 6 + + + + + + + + + + + STLink\ST-LINKIII-KEIL_SWO.dll + + + + 0 + ARMRTXEVENTFLAGS + -L70 -Z18 -C0 -M0 -T1 + + + 0 + DLGTARM + (1010=-1,-1,-1,-1,0)(1007=-1,-1,-1,-1,0)(1008=-1,-1,-1,-1,0)(1009=-1,-1,-1,-1,0)(1012=-1,-1,-1,-1,0) + + + 0 + ARMDBGFLAGS + + + + 0 + DLGUARM + (105=-1,-1,-1,-1,0) + + + 0 + ST-LINKIII-KEIL_SWO + -U066EFF495056805087184715 -I0 -O8430 -S1 -C0 -A0 -N00("ARM CoreSight SW-DP") -D00(2BA01477) -L00(0) -TO18 -TC10000000 -TP21 -TDS8007 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -FO15 -FD20000000 -FC1000 -FN1 -FF0STM32L1xx_512.FLM -FS08000000 -FL080000 -FP0($$Device:STM32L152RE$CMSIS\Flash\STM32L1xx_512.FLM) + + + 0 + UL2CM3 + UL2CM3(-S0 -C0 -P0 -FD20000000 -FC1000 -FN1 -FF0STM32L1xx_512 -FS08000000 -FL080000 -FP0($$Device:STM32L152RE$CMSIS\Flash\STM32L1xx_512.FLM)) + + + + + + 1 + 2 + 0x20000200 + 0 + + + + + 2 + 0 + 0x400 + 0 + + + + 0 + + + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + + + + 0 + 0 + 0 + + + + + + + + + + 1 + 1 + 0 + 2 + 10000000 + + + + + + dpp-spy + 0x4 + ARM-ADS + + 12000000 + + 1 + 1 + 0 + 1 + 0 + + + 1 + 65535 + 0 + 0 + 0 + + + 79 + 66 + 8 + .\spy\ + + + 1 + 1 + 1 + 0 + 1 + 1 + 0 + 1 + 0 + 0 + 0 + 0 + + + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + + + 1 + 0 + 0 + + 18 + + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + 0 + 1 + 1 + 0 + 0 + 1 + 0 + 0 + 6 + + + + + + + + + + + STLink\ST-LINKIII-KEIL_SWO.dll + 0 @@ -217,384 +626,6 @@ - - dpp-rel - 0x4 - ARM-ADS - - 12000000 - - 1 - 1 - 0 - 1 - 0 - - - 1 - 65535 - 0 - 0 - 0 - - - 79 - 66 - 8 - .\rel\ - - - 1 - 1 - 1 - 0 - 1 - 1 - 0 - 1 - 0 - 0 - 0 - 0 - - - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 0 - 0 - - - 1 - 0 - 0 - - 18 - - 0 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 0 - 1 - 0 - 1 - 1 - 0 - 0 - 1 - 0 - 0 - 5 - - - - - - - - - - - STLink\ST-LINKIII-KEIL_SWO.dll - - - - 0 - ARMRTXEVENTFLAGS - -L70 -Z18 -C0 -M0 -T1 - - - 0 - DLGTARM - (1010=-1,-1,-1,-1,0)(1007=-1,-1,-1,-1,0)(1008=-1,-1,-1,-1,0)(1009=-1,-1,-1,-1,0)(1012=-1,-1,-1,-1,0) - - - 0 - ARMDBGFLAGS - - - - 0 - DLGUARM - (105=-1,-1,-1,-1,0) - - - 0 - ST-LINKIII-KEIL_SWO - -U066EFF495056805087184715 -I0 -O8430 -S1 -C0 -A0 -N00("ARM CoreSight SW-DP") -D00(2BA01477) -L00(0) -TO18 -TC10000000 -TP21 -TDS8007 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -FO15 -FD20000000 -FC1000 -FN1 -FF0STM32L1xx_512.FLM -FS08000000 -FL080000 -FP0($$Device:STM32L152RE$Flash\STM32L1xx_512.FLM) - - - 0 - UL2CM3 - UL2CM3(-S0 -C0 -P0 -FD20000000 -FC1000 -FN1 -FF0STM32L1xx_512 -FS08000000 -FL080000 -FP0($$Device:STM32L152RE$Flash\STM32L1xx_512.FLM)) - - - - - - 1 - 2 - 0x20000200 - 0 - - - - - 2 - 0 - 0x400 - 0 - - - - 0 - - - 0 - 0 - 1 - 0 - 0 - 0 - 0 - 1 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - - - - 0 - 0 - 0 - - - - - - - - - - - - - dpp-spy - 0x4 - ARM-ADS - - 12000000 - - 1 - 1 - 0 - 1 - 0 - - - 1 - 65535 - 0 - 0 - 0 - - - 79 - 66 - 8 - .\spy\ - - - 1 - 1 - 1 - 0 - 1 - 1 - 0 - 1 - 0 - 0 - 0 - 0 - - - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 0 - 0 - - - 1 - 0 - 0 - - 18 - - 0 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 0 - 1 - 0 - 1 - 1 - 0 - 0 - 1 - 0 - 0 - 5 - - - - - - - - - - - STLink\ST-LINKIII-KEIL_SWO.dll - - - - 0 - ARMRTXEVENTFLAGS - -L70 -Z18 -C0 -M0 -T1 - - - 0 - DLGTARM - (1010=-1,-1,-1,-1,0)(1007=-1,-1,-1,-1,0)(1008=-1,-1,-1,-1,0)(1009=-1,-1,-1,-1,0)(1012=-1,-1,-1,-1,0) - - - 0 - ARMDBGFLAGS - - - - 0 - DLGUARM - (105=-1,-1,-1,-1,0) - - - 0 - ST-LINKIII-KEIL_SWO - -U066EFF495056805087184715 -I0 -O8398 -S1 -C0 -A0 -N00("ARM CoreSight SW-DP") -D00(2BA01477) -L00(0) -TO18 -TC10000000 -TP21 -TDS8007 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -FO15 -FD20000000 -FC1000 -FN1 -FF0STM32L1xx_512.FLM -FS08000000 -FL080000 -FP0($$Device:STM32L152RE$Flash\STM32L1xx_512.FLM) - - - 0 - UL2CM3 - UL2CM3(-S0 -C0 -P0 -FD20000000 -FC1000 -FN1 -FF0STM32L1xx_512 -FS08000000 -FL080000 -FP0($$Device:STM32L152RE$Flash\STM32L1xx_512.FLM)) - - - - - - 1 - 2 - 0x20000200 - 0 - - - - - 2 - 0 - 0x400 - 0 - - - - 0 - - - 0 - 0 - 1 - 0 - 0 - 0 - 0 - 1 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - - - - 0 - 0 - 0 - - - - - - - - - - - Application 1 @@ -616,6 +647,18 @@ 1 2 + 1 + 0 + 0 + 0 + ..\bsp.c + bsp.c + 0 + 0 + + + 1 + 3 5 0 0 @@ -627,7 +670,7 @@ 1 - 3 + 4 1 0 0 @@ -637,18 +680,6 @@ 0 0 - - 1 - 4 - 5 - 0 - 0 - 0 - ..\..\README.txt - README.txt - 0 - 0 - 1 5 @@ -668,31 +699,7 @@ 0 0 0 - ..\bsp.c - bsp.c - 0 - 0 - - - 1 - 7 - 1 - 0 - 0 - 0 - ..\..\..\..\..\include\qstamp.c - qstamp.c - 0 - 0 - - - 1 - 8 - 1 - 0 - 0 - 0 - ..\main.c + ..\..\main.c main.c 0 0 @@ -701,13 +708,13 @@ nucleo-l152re - 0 + 1 0 0 0 2 - 9 + 7 5 0 0 @@ -719,7 +726,7 @@ 2 - 10 + 8 5 0 0 @@ -731,7 +738,7 @@ 2 - 11 + 9 1 0 0 @@ -743,7 +750,7 @@ 2 - 12 + 10 5 0 0 @@ -755,7 +762,7 @@ 2 - 13 + 11 2 0 0 @@ -775,7 +782,7 @@ 0 3 - 14 + 12 1 0 0 @@ -787,7 +794,7 @@ 3 - 15 + 13 1 0 0 @@ -799,7 +806,7 @@ 3 - 16 + 14 1 0 0 @@ -811,7 +818,7 @@ 3 - 17 + 15 1 0 0 @@ -823,7 +830,7 @@ 3 - 18 + 16 1 0 0 @@ -835,7 +842,7 @@ 3 - 19 + 17 1 0 0 @@ -847,7 +854,7 @@ 3 - 20 + 18 1 0 0 @@ -859,7 +866,7 @@ 3 - 21 + 19 5 0 0 @@ -871,7 +878,7 @@ 3 - 22 + 20 1 0 0 @@ -883,7 +890,7 @@ 3 - 23 + 21 1 0 0 @@ -895,7 +902,7 @@ 3 - 24 + 22 1 0 0 @@ -907,7 +914,7 @@ 3 - 25 + 23 1 0 0 @@ -919,7 +926,7 @@ 3 - 26 + 24 1 0 0 @@ -931,7 +938,7 @@ 3 - 27 + 25 1 0 0 @@ -951,43 +958,7 @@ 0 4 - 28 - 5 - 0 - 0 - 0 - ..\..\..\..\..\ports\arm-cm\qv\armclang\qep_port.h - qep_port.h - 0 - 0 - - - 4 - 29 - 5 - 0 - 0 - 0 - ..\..\..\..\..\ports\arm-cm\qv\armclang\qf_port.h - qf_port.h - 0 - 0 - - - 4 - 30 - 5 - 0 - 0 - 0 - ..\..\..\..\..\ports\arm-cm\qv\armclang\qv_port.h - qv_port.h - 0 - 0 - - - 4 - 31 + 26 5 0 0 @@ -999,7 +970,7 @@ 4 - 32 + 27 1 0 0 @@ -1019,7 +990,7 @@ 0 5 - 33 + 28 1 0 0 @@ -1031,7 +1002,7 @@ 5 - 34 + 29 1 0 0 @@ -1043,7 +1014,7 @@ 5 - 35 + 30 1 0 0 @@ -1053,6 +1024,18 @@ 0 0 + + 5 + 31 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qs\qstamp.c + qstamp.c + 0 + 0 + diff --git a/examples/arm-cm/dpp_nucleo-l152re/qv/armclang/dpp-qv.uvprojx b/examples/arm-cm/dpp_nucleo-l152re/qv/armclang/dpp-qv.uvprojx index a711a892..3278f1f3 100644 --- a/examples/arm-cm/dpp_nucleo-l152re/qv/armclang/dpp-qv.uvprojx +++ b/examples/arm-cm/dpp_nucleo-l152re/qv/armclang/dpp-qv.uvprojx @@ -361,7 +361,7 @@ - 1 + 0 0 0 0 @@ -370,7 +370,7 @@ 0x00000000 0x20000000 - + .\dpp-qv.sct --entry Reset_Handler @@ -388,6 +388,11 @@ 5 ..\..\bsp.h + + bsp.c + 1 + ..\bsp.c + dpp.h 5 @@ -398,30 +403,15 @@ 1 ..\..\philo.c - - README.txt - 5 - ..\..\README.txt - table.c 1 ..\..\table.c - - bsp.c - 1 - ..\bsp.c - - - qstamp.c - 1 - ..\..\..\..\..\include\qstamp.c - main.c 1 - ..\main.c + ..\..\main.c @@ -533,21 +523,6 @@ QP_port - - qep_port.h - 5 - ..\..\..\..\..\ports\arm-cm\qv\armclang\qep_port.h - - - qf_port.h - 5 - ..\..\..\..\..\ports\arm-cm\qv\armclang\qf_port.h - - - qv_port.h - 5 - ..\..\..\..\..\ports\arm-cm\qv\armclang\qv_port.h - qs_port.h 5 @@ -647,6 +622,11 @@ 1 ..\..\..\..\..\src\qs\qs_rx.c + + qstamp.c + 1 + ..\..\..\..\..\src\qs\qstamp.c + @@ -1006,7 +986,7 @@ - 1 + 0 0 0 0 @@ -1015,7 +995,7 @@ 0x00000000 0x20000000 - dpp-qv.sct + .\dpp-qv.sct --entry Reset_Handler @@ -1033,6 +1013,11 @@ 5 ..\..\bsp.h + + bsp.c + 1 + ..\bsp.c + dpp.h 5 @@ -1043,30 +1028,15 @@ 1 ..\..\philo.c - - README.txt - 5 - ..\..\README.txt - table.c 1 ..\..\table.c - - bsp.c - 1 - ..\bsp.c - - - qstamp.c - 1 - ..\..\..\..\..\include\qstamp.c - main.c 1 - ..\main.c + ..\..\main.c @@ -1178,21 +1148,6 @@ QP_port - - qep_port.h - 5 - ..\..\..\..\..\ports\arm-cm\qv\armclang\qep_port.h - - - qf_port.h - 5 - ..\..\..\..\..\ports\arm-cm\qv\armclang\qf_port.h - - - qv_port.h - 5 - ..\..\..\..\..\ports\arm-cm\qv\armclang\qv_port.h - qs_port.h 5 @@ -1292,6 +1247,11 @@ 1 ..\..\..\..\..\src\qs\qs_rx.c + + qstamp.c + 1 + ..\..\..\..\..\src\qs\qstamp.c + @@ -1300,7 +1260,7 @@ dpp-spy 0x4 ARM-ADS - 6130001::V6.13.1::.\ARMCLANG + 6160000::V6.16::ARMCLANG 1 @@ -1627,7 +1587,7 @@ 0 - Q_SPY + Q_SPY,QF_ON_CONTEXT_SW ..\..;..\..\..\..\..\include;..\..\..\..\..\ports\arm-cm\qv\armclang;..\..\..\..\..\3rd_party\CMSIS\Include; ..\..\..\..\..\3rd_party\nucleo-l152re @@ -1651,7 +1611,7 @@ - 1 + 0 0 0 0 @@ -1660,7 +1620,7 @@ 0x00000000 0x20000000 - dpp-qv.sct + .\dpp-qv.sct --entry Reset_Handler @@ -1678,6 +1638,11 @@ 5 ..\..\bsp.h + + bsp.c + 1 + ..\bsp.c + dpp.h 5 @@ -1688,30 +1653,15 @@ 1 ..\..\philo.c - - README.txt - 5 - ..\..\README.txt - table.c 1 ..\..\table.c - - bsp.c - 1 - ..\bsp.c - - - qstamp.c - 1 - ..\..\..\..\..\include\qstamp.c - main.c 1 - ..\main.c + ..\..\main.c @@ -1823,21 +1773,6 @@ QP_port - - qep_port.h - 5 - ..\..\..\..\..\ports\arm-cm\qv\armclang\qep_port.h - - - qf_port.h - 5 - ..\..\..\..\..\ports\arm-cm\qv\armclang\qf_port.h - - - qv_port.h - 5 - ..\..\..\..\..\ports\arm-cm\qv\armclang\qv_port.h - qs_port.h 5 @@ -1868,6 +1803,11 @@ 1 ..\..\..\..\..\src\qs\qs_rx.c + + qstamp.c + 1 + ..\..\..\..\..\src\qs\qstamp.c + @@ -1880,4 +1820,13 @@ + + + + dpp-qv + 1 + + + + diff --git a/examples/arm-cm/dpp_nucleo-l152re/qv/bsp.c b/examples/arm-cm/dpp_nucleo-l152re/qv/bsp.c index 1fe09848..3770c762 100644 --- a/examples/arm-cm/dpp_nucleo-l152re/qv/bsp.c +++ b/examples/arm-cm/dpp_nucleo-l152re/qv/bsp.c @@ -1,288 +1,402 @@ -/***************************************************************************** -* Product: DPP example, STM32 NUCLEO-L152RE board, cooperative QV kernel -* Last updated for version 6.9.3 -* Last updated on 2021-03-03 -* -* Q u a n t u m L e a P s -* ------------------------ -* Modern Embedded Software -* -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* -* -*****************************************************************************/ -#include "qpc.h" -#include "dpp.h" -#include "bsp.h" +//============================================================================ +// Product: DPP example, NUCLEO-L152RE board, QV kernel +// Last updated for version 7.3.0 +// Last updated on 2023-08-23 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. +// +// This program is open source software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Alternatively, this program may be distributed and modified under the +// terms of Quantum Leaps commercial licenses, which expressly supersede +// the GNU General Public License and are specifically designed for +// licensees interested in retaining the proprietary status of their code. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Contact information: +// +// +//============================================================================ +#include "qpc.h" // QP/C real-time embedded framework +#include "dpp.h" // DPP Application interface +#include "bsp.h" // Board Support Package -#include "stm32l1xx.h" /* CMSIS-compliant header file for the MCU used */ -/* add other drivers if necessary... */ +#include "stm32l1xx.h" // CMSIS-compliant header file for the MCU used +// add other drivers if necessary... -Q_DEFINE_THIS_FILE +Q_DEFINE_THIS_FILE // define the name of this file for assertions -/* Local-scope objects -----------------------------------------------------*/ -/* LED pins available on the board (just one user LED LD2--Green on PA.5) */ -#define LED_LD2 (1U << 5) +// Local-scope defines ----------------------------------------------------- +// LED pins available on the board (just one user LED LD2--Green on PA.5) +#define LED_PIN 5U -/* Button pins available on the board (just one user Button B1 on PC.13) */ -#define BTN_B1 (1U << 13) +// Button pins available on the board (just one user Button B1 on PC.13) +#define BTN_PIN 13U -static uint32_t l_rnd; /* random seed */ +static uint32_t l_rndSeed; #ifdef Q_SPY + QSTimeCtr QS_tickTime_; QSTimeCtr QS_tickPeriod_; - /* QSpy source IDs */ + // QSpy source IDs static QSpyId const l_SysTick_Handler = { 0U }; - enum AppRecords { /* application-specific trace records */ - PHILO_STAT = QS_USER + enum AppRecords { // application-specific trace records + PHILO_STAT = QS_USER, + PAUSED_STAT, + CONTEXT_SW, }; #endif -/* ISRs used in the application ==========================================*/ -void SysTick_Handler(void); -void USART2_IRQHandler(void); +//============================================================================ +// Error handler and ISRs... -/*..........................................................................*/ -void SysTick_Handler(void) { /* system clock tick ISR -- kernel aware */ - /* state of the button debouncing, see below */ - static struct ButtonsDebouncing { +Q_NORETURN Q_onError(char const * const module, int_t const id) { + // NOTE: this implementation of the assertion handler is intended only + // for debugging and MUST be changed for deployment of the application + // (assuming that you ship your production code with assertions enabled). + Q_UNUSED_PAR(module); + Q_UNUSED_PAR(id); + QS_ASSERTION(module, id, 10000U); + +#ifndef NDEBUG + // light up the user LED + GPIOA->BSRRL = (1U << LED_PIN); // turn LED on + // for debugging, hang on in an endless loop... + for (;;) { + } +#endif + + NVIC_SystemReset(); +} +//............................................................................ +void assert_failed(char const * const module, int_t const id); // prototype +void assert_failed(char const * const module, int_t const id) { + Q_onError(module, id); +} + +// ISRs used in the application ========================================== + +void SysTick_Handler(void); // prototype +void SysTick_Handler(void) { + + QTIMEEVT_TICK_X(0U, &l_SysTick_Handler); // time events at rate 0 + + // Perform the debouncing of buttons. The algorithm for debouncing + // adapted from the book "Embedded Systems Dictionary" by Jack Ganssle + // and Michael Barr, page 71. + // + // state of the button debouncing + static struct { uint32_t depressed; uint32_t previous; } buttons = { 0U, 0U }; - uint32_t current; - uint32_t tmp; -#ifdef Q_SPY - { - tmp = SysTick->CTRL; /* clear CTRL_COUNTFLAG */ - QS_tickTime_ += QS_tickPeriod_; /* account for the clock rollover */ - } -#endif + uint32_t current = ~GPIOC->IDR; // read Port C with state of Button B1 + uint32_t tmp = buttons.depressed; // save the depressed buttons + buttons.depressed |= (buttons.previous & current); // set depressed + buttons.depressed &= (buttons.previous | current); // clear released + buttons.previous = current; // update the history + tmp ^= buttons.depressed; // changed debounced depressed + current = buttons.depressed; - QTIMEEVT_TICK_X(0U, &l_SysTick_Handler); /* process time events for rate 0 */ - - /* get state of the user button */ - /* Perform the debouncing of buttons. The algorithm for debouncing - * adapted from the book "Embedded Systems Dictionary" by Jack Ganssle - * and Michael Barr, page 71. - */ - current = ~GPIOC->IDR; /* read Port C with the state of Button B1 */ - tmp = buttons.depressed; /* save the debounced depressed buttons */ - buttons.depressed |= (buttons.previous & current); /* set depressed */ - buttons.depressed &= (buttons.previous | current); /* clear released */ - buttons.previous = current; /* update the history */ - tmp ^= buttons.depressed; /* changed debounced depressed */ - if ((tmp & BTN_B1) != 0U) { /* debounced B1 state changed? */ - if ((buttons.depressed & BTN_B1) != 0U) { /* is B1 depressed? */ - static QEvt const pauseEvt = { PAUSE_SIG, 0U, 0U}; + if ((tmp & (1U << BTN_PIN)) != 0U) { // debounced BTN state changed? + if ((current & (1U << BTN_PIN)) != 0U) { // is BTN depressed? + static QEvt const pauseEvt = QEVT_INITIALIZER(PAUSE_SIG); QACTIVE_PUBLISH(&pauseEvt, &l_SysTick_Handler); } - else { /* the button is released */ - static QEvt const serveEvt = { SERVE_SIG, 0U, 0U}; + else { // the button is released + static QEvt const serveEvt = QEVT_INITIALIZER(SERVE_SIG); QACTIVE_PUBLISH(&serveEvt, &l_SysTick_Handler); } } + +#ifdef Q_SPY + tmp = SysTick->CTRL; // clear CTRL_COUNTFLAG + QS_tickTime_ += QS_tickPeriod_; // account for the clock rollover +#endif + QV_ARM_ERRATUM_838869(); } -/*..........................................................................*/ -#if Q_SPY -void USART2_IRQHandler(void) { /* kernel UNAWARE interrupt */ - /* is RX register NOT empty? */ - if ((USART2->SR & (1U << 5)) != 0) { +//............................................................................ +// interrupt handler for testing preemptions in QV +void EXTI0_1_IRQHandler(void); // prototype +void EXTI0_1_IRQHandler(void) { + static QEvt const testEvt = QEVT_INITIALIZER(TEST_SIG); + QACTIVE_POST(AO_Table, &testEvt, (void *)0); + + QV_ARM_ERRATUM_838869(); +} + +//............................................................................ +#ifdef Q_SPY +// ISR for receiving bytes from the QSPY Back-End +// NOTE: This ISR is "QF-unaware" meaning that it does not interact with +// the QF/QV and is not disabled. Such ISRs cannot post or publish events. + +void USART2_IRQHandler(void); // prototype +void USART2_IRQHandler(void) { // used in QS-RX (kernel UNAWARE interrutp) + // is RX register NOT empty? + if ((USART2->SR & (1U << 5U)) != 0U) { uint32_t b = USART2->DR; QS_RX_PUT(b); } + QV_ARM_ERRATUM_838869(); } -#endif +#endif // Q_SPY + +//............................................................................ +#ifdef QF_ON_CONTEXT_SW +// NOTE: the context-switch callback is called with interrupts DISABLED +void QF_onContextSw(QActive *prev, QActive *next) { + QS_BEGIN_INCRIT(CONTEXT_SW, 0U) // in critical section! + QS_OBJ(prev); + QS_OBJ(next); + QS_END_INCRIT() +} +#endif // QF_ON_CONTEXT_SW + +//============================================================================ +// BSP functions... -/* BSP functions ===========================================================*/ void BSP_init(void) { - /* NOTE: SystemInit() has been already called from the startup code - * but SystemCoreClock needs to be updated - */ + // Configure the MPU to prevent NULL-pointer dereferencing ... + MPU->RBAR = 0x0U // base address (NULL) + | MPU_RBAR_VALID_Msk // valid region + | (MPU_RBAR_REGION_Msk & 7U); // region #7 + MPU->RASR = (7U << MPU_RASR_SIZE_Pos) // 2^(7+1) region + | (0x0U << MPU_RASR_AP_Pos) // no-access region + | MPU_RASR_ENABLE_Msk; // region enable + MPU->CTRL = MPU_CTRL_PRIVDEFENA_Msk // enable background region + | MPU_CTRL_ENABLE_Msk; // enable the MPU + __ISB(); + __DSB(); + + // NOTE: SystemInit() has been already called from the startup code + // but SystemCoreClock needs to be updated SystemCoreClockUpdate(); - /* enable GPIOA clock port for the LED LD2 */ - RCC->AHBENR |= (1U << 0); + // enable GPIOA clock port for the LED LD2 + RCC->AHBENR |= (1U << 0U); - /* configure LED (PA.5) pin as push-pull output, no pull-up, pull-down */ - GPIOA->MODER &= ~((3U << 2*5)); - GPIOA->MODER |= ((1U << 2*5)); - GPIOA->OTYPER &= ~((1U << 5)); - GPIOA->OSPEEDR &= ~((3U << 2*5)); - GPIOA->OSPEEDR |= ((1U << 2*5)); - GPIOA->PUPDR &= ~((3U << 2*5)); + // configure LED (PA.5) pin as push-pull output, no pull-up, pull-down + GPIOA->MODER &= ~((3U << 2U*LED_PIN)); + GPIOA->MODER |= ((1U << 2U*LED_PIN)); + GPIOA->OTYPER &= ~((1U << LED_PIN)); + GPIOA->OSPEEDR &= ~((3U << 2U*LED_PIN)); + GPIOA->OSPEEDR |= ((1U << 2U*LED_PIN)); + GPIOA->PUPDR &= ~((3U << 2U*LED_PIN)); - /* enable GPIOC clock port for the Button B1 */ + // enable GPIOC clock port for the Button B1 RCC->AHBENR |= (1U << 2); - /* configure Button (PC.13) pins as input, no pull-up, pull-down */ - GPIOC->MODER &= ~(3U << 2*13); - GPIOC->OSPEEDR &= ~(3U << 2*13); - GPIOC->OSPEEDR |= (1U << 2*13); - GPIOC->PUPDR &= ~(3U << 2*13); + // configure Button (PC.13) pins as input, no pull-up, pull-down + GPIOC->MODER &= ~(3U << 2U*BTN_PIN); + GPIOC->OSPEEDR &= ~(3U << 2U*BTN_PIN); + GPIOC->OSPEEDR |= (1U << 2U*BTN_PIN); + GPIOC->PUPDR &= ~(3U << 2U*BTN_PIN); - BSP_randomSeed(1234U); /* seed the random number generator */ + BSP_randomSeed(1234U); // seed the random number generator - /* initialize the QS software tracing... */ - if (QS_INIT((void *)0) == 0U) { + // initialize the QS software tracing... + if (!QS_INIT((void *)0)) { Q_ERROR(); } + + // dictionaries... QS_OBJ_DICTIONARY(&l_SysTick_Handler); QS_USR_DICTIONARY(PHILO_STAT); + QS_USR_DICTIONARY(PAUSED_STAT); + QS_USR_DICTIONARY(CONTEXT_SW); - /* setup the QS filters... */ - QS_GLB_FILTER(QS_ALL_RECORDS); - QS_GLB_FILTER(-QS_QF_TICK); + QS_ONLY(produce_sig_dict()); + + // setup the QS filters... + QS_GLB_FILTER(QS_ALL_RECORDS); // all records + QS_GLB_FILTER(-QS_QF_TICK); // exclude the clock tick } -/*..........................................................................*/ +//............................................................................ +void BSP_start(void) { + // initialize event pools + static QF_MPOOL_EL(TableEvt) smlPoolSto[2*N_PHILO]; + QF_poolInit(smlPoolSto, sizeof(smlPoolSto), sizeof(smlPoolSto[0])); + + // initialize publish-subscribe + static QSubscrList subscrSto[MAX_PUB_SIG]; + QActive_psInit(subscrSto, Q_DIM(subscrSto)); + + // instantiate and start AOs/threads... + + static QEvt const *philoQueueSto[N_PHILO][10]; + for (uint8_t n = 0U; n < N_PHILO; ++n) { + Philo_ctor(n); + QACTIVE_START(AO_Philo[n], + n + 3U, // QF-prio. + philoQueueSto[n], // event queue storage + Q_DIM(philoQueueSto[n]), // queue length [events] + (void *)0, 0U, // no stack storage + (void *)0); // no initialization param + } + + static QEvt const *tableQueueSto[N_PHILO]; + Table_ctor(); + QACTIVE_START(AO_Table, + N_PHILO + 7U, // QP prio. of the AO + tableQueueSto, // event queue storage + Q_DIM(tableQueueSto), // queue length [events] + (void *)0, 0U, // no stack storage + (void *)0); // no initialization param +} +//............................................................................ void BSP_displayPhilStat(uint8_t n, char const *stat) { + Q_UNUSED_PAR(n); + if (stat[0] == 'h') { - GPIOA->BSRRL |= LED_LD2; /* turn LED on */ + GPIOA->BSRRL = (1U << LED_PIN); // turn LED on } else { - GPIOA->BSRRH |= LED_LD2; /* turn LED off */ + GPIOA->BSRRH = (1U << LED_PIN); // turn LED off } - QS_BEGIN_ID(PHILO_STAT, AO_Philo[n]->prio) /* app-specific record */ - QS_U8(1, n); /* Philosopher number */ - QS_STR(stat); /* Philosopher status */ + // app-specific trace record... + QS_BEGIN_ID(PHILO_STAT, AO_Table->prio) + QS_U8(1, n); // Philosopher number + QS_STR(stat); // Philosopher status QS_END() } -/*..........................................................................*/ -void BSP_displayPaused(uint8_t paused) { - // not enough LEDs to show the "Paused" status +//............................................................................ +void BSP_displayPaused(uint8_t const paused) { + // not enough LEDs to implement this feature if (paused != 0U) { - //GPIOA->BSRRL |= LED_LD2; /* turn LED on */ + //GPIOA->BSRRL = (1U << LED_PIN); // turn LED on } else { - //GPIOA->BSRRH |= LED_LD2; /* turn LED off */ + //GPIOA->BSRRH = (1U << LED_PIN); // turn LED off } + + // application-specific trace record + QS_BEGIN_ID(PAUSED_STAT, AO_Table->prio) + QS_U8(1, paused); // Paused status + QS_END() } -/*..........................................................................*/ -uint32_t BSP_random(void) { /* a very cheap pseudo-random-number generator */ - /* "Super-Duper" Linear Congruential Generator (LCG) - * LCG(2^32, 3*7*11*13*23, 0, seed) - */ - l_rnd = l_rnd * (3U*7U*11U*13U*23U); - return l_rnd >> 8; -} -/*..........................................................................*/ +//............................................................................ void BSP_randomSeed(uint32_t seed) { - l_rnd = seed; + l_rndSeed = seed; } -/*..........................................................................*/ +//............................................................................ +uint32_t BSP_random(void) { // a very cheap pseudo-random-number generator + + // "Super-Duper" Linear Congruential Generator (LCG) + // LCG(2^32, 3*7*11*13*23, 0, seed) + // + uint32_t rnd = l_rndSeed * (3U*7U*11U*13U*23U); + l_rndSeed = rnd; // set for the next time + + return (rnd >> 8U); +} +//............................................................................ +void BSP_ledOn(void) { + GPIOA->BSRRL = (1U << LED_PIN); // turn LED on +} +//............................................................................ +void BSP_ledOff(void) { + GPIOA->BSRRH = (1U << LED_PIN); // turn LED off +} +//............................................................................ void BSP_terminate(int16_t result) { - (void)result; + Q_UNUSED_PAR(result); } -/* QF callbacks ============================================================*/ +//============================================================================ +// QF callbacks... void QF_onStartup(void) { - /* set up the SysTick timer to fire at BSP_TICKS_PER_SEC rate */ + // set up the SysTick timer to fire at BSP_TICKS_PER_SEC rate SysTick_Config(SystemCoreClock / BSP_TICKS_PER_SEC); - /* set priorities of ALL ISRs used in the system, see NOTE00 - * - * !!!!!!!!!!!!!!!!!!!!!!!!!!!! CAUTION !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - * Assign a priority to EVERY ISR explicitly by calling NVIC_SetPriority(). - * DO NOT LEAVE THE ISR PRIORITIES AT THE DEFAULT VALUE! - */ - NVIC_SetPriority(SysTick_IRQn, QF_AWARE_ISR_CMSIS_PRI + 1); - NVIC_SetPriority(USART2_IRQn, 0); /* kernel UNAWARE interrupt */ - /* ... */ + // assign all priority bits for preemption-prio. and none to sub-prio. + NVIC_SetPriorityGrouping(0U); - /* enable IRQs... */ + // set priorities of ALL ISRs used in the system, see NOTE1 + NVIC_SetPriority(USART2_IRQn, 0U); // kernel UNAWARE interrupt + NVIC_SetPriority(SysTick_IRQn, QF_AWARE_ISR_CMSIS_PRI + 1U); + // ... + + // enable IRQs... #ifdef Q_SPY - NVIC_EnableIRQ(USART2_IRQn); /* UART2 interrupt used for QS-RX */ + NVIC_EnableIRQ(USART2_IRQn); // USART2 interrupt used for QS-RX #endif } -/*..........................................................................*/ +//............................................................................ void QF_onCleanup(void) { } -/*..........................................................................*/ -void QV_onIdle(void) { /* called with interrupts disabled, see NOTE01 */ +//............................................................................ +void QV_onIdle(void) { // CATION: called with interrupts DISABLED, see NOTE0 - /* toggle an LED on and then off (not enough LEDs, see NOTE02) */ - //GPIOA->BSRRL |= LED_LD2; /* turn LED[n] on */ - //GPIOA->BSRRH |= LED_LD2; /* turn LED[n] off */ + // toggle an LED on and then off (not enough LEDs, see NOTE02) + //GPIOA->BSRRL = (1U << LED_PIN); // turn LED[n] on + //GPIOA->BSRRH = (1U << LED_PIN); // turn LED[n] off #ifdef Q_SPY + // interrupts still disabled + QS_rxParse(); // parse all the received bytes QF_INT_ENABLE(); - QS_rxParse(); /* parse all the received bytes */ - - if ((USART2->SR & (1U << 7)) != 0) { /* is TXE empty? */ - uint16_t b; + QF_CRIT_EXIT_NOP(); + if ((USART2->SR & (1U << 7U)) != 0U) { // is TXE empty? QF_INT_DISABLE(); - b = QS_getByte(); + uint16_t b = QS_getByte(); QF_INT_ENABLE(); - if (b != QS_EOD) { /* not End-Of-Data? */ - USART2->DR = (b & 0xFFU); /* put into the DR register */ + if (b != QS_EOD) { // not End-Of-Data? + USART2->DR = b; // put into the DR register } } #elif defined NDEBUG - /* Put the CPU and peripherals to the low-power mode. - * you might need to customize the clock management for your application, - * see the datasheet for your particular Cortex-M MCU. - */ - /* !!!CAUTION!!! - * QV_CPU_SLEEP() contains the WFI instruction, which stops the CPU - * clock, which unfortunately disables the JTAG port, so the ST-Link - * debugger can no longer connect to the board. For that reason, the call - * to QV_CPU_SLEEP() has to be used with CAUTION. - */ - /* NOTE: If you find your board "frozen" like this, strap BOOT0 to VDD and - * reset the board, then connect with ST-Link Utilities and erase the part. - * The trick with BOOT(0) is it gets the part to run the System Loader - * instead of your broken code. When done disconnect BOOT0, and start over. - */ - //QV_CPU_SLEEP(); /* atomically go to sleep and enable interrupts */ - QF_INT_ENABLE(); /* for now, just enable interrupts */ + // Put the CPU and peripherals to the low-power mode. + // you might need to customize the clock management for your application, + // see the datasheet for your particular Cortex-M MCU. + // + // !!!CAUTION!!! + // QV_CPU_SLEEP() contains the WFI instruction, which stops the CPU + // clock, which unfortunately disables the JTAG port, so the ST-Link + // debugger can no longer connect to the board. For that reason, the call + // to QV_CPU_SLEEP() has to be used with CAUTION. + // + // NOTE: If you find your board "frozen" like this, strap BOOT0 to VDD and + // reset the board, then connect with ST-Link Utilities and erase the part. + // The trick with BOOT(0) is that it gets the part to run the System Loader + // instead of your broken code. When done disconnect BOOT0, and start over. + // + //QV_CPU_SLEEP(); // atomically go to sleep and enable interrupts + QF_INT_ENABLE(); // for now, just enable interrupts #else - QF_INT_ENABLE(); /* just enable interrupts */ + QF_INT_ENABLE(); // just enable interrupts #endif } -/*..........................................................................*/ -Q_NORETURN Q_onAssert(char const * const module, int_t const loc) { - /* - * NOTE: add here your application-specific error handling - */ - (void)module; - (void)loc; - QS_ASSERTION(module, loc, 10000U); /* report assertion to QS */ - NVIC_SystemReset(); -} - -/* QS callbacks ============================================================*/ +//============================================================================ +// QS callbacks... #ifdef Q_SPY -/*..........................................................................*/ + +//............................................................................ #define __DIV(__PCLK, __BAUD) (((__PCLK / 4) *25)/(__BAUD)) #define __DIVMANT(__PCLK, __BAUD) (__DIV(__PCLK, __BAUD)/100) #define __DIVFRAQ(__PCLK, __BAUD) \ @@ -291,110 +405,126 @@ Q_NORETURN Q_onAssert(char const * const module, int_t const loc) { #define __USART_BRR(__PCLK, __BAUD) \ ((__DIVMANT(__PCLK, __BAUD) << 4)|(__DIVFRAQ(__PCLK, __BAUD) & 0x0F)) -/*..........................................................................*/ +// USART2 pins PA.2 and PA.3 +#define USART2_TX_PIN 2U +#define USART2_RX_PIN 3U + +//............................................................................ uint8_t QS_onStartup(void const *arg) { - static uint8_t qsBuf[2*1024]; /* buffer for Quantum Spy */ - static uint8_t qsRxBuf[128]; /* buffer for QS-RX channel */ + Q_UNUSED_PAR(arg); - (void)arg; /* avoid the "unused parameter" compiler warning */ + static uint8_t qsTxBuf[2*1024]; // buffer for QS-TX channel + QS_initBuf(qsTxBuf, sizeof(qsTxBuf)); - QS_initBuf(qsBuf, sizeof(qsBuf)); + static uint8_t qsRxBuf[100]; // buffer for QS-RX channel QS_rxInitBuf(qsRxBuf, sizeof(qsRxBuf)); - /* enable peripheral clock for USART2 */ - RCC->AHBENR |= (1U << 0); /* Enable GPIOA clock */ - RCC->APB1ENR |= (1U << 17); /* Enable USART#2 clock */ + // enable peripheral clock for USART2 + RCC->AHBENR |= ( 1U << 0U); // Enable GPIOA clock + RCC->APB1ENR |= ( 1U << 17U); // Enable USART#2 clock - /* Configure PA3 to USART2_RX, PA2 to USART2_TX */ - GPIOA->AFR[0] &= ~((15U << 4*3) | (15U << 4*2)); - GPIOA->AFR[0] |= (( 7U << 4*3) | ( 7U << 4*2)); - GPIOA->MODER &= ~(( 3U << 2*3) | ( 3U << 2*2)); - GPIOA->MODER |= (( 2U << 2*3) | ( 2U << 2*2)); + // Configure PA3 to USART2_RX, PA2 to USART2_TX + GPIOA->AFR[0] &= ~((15U << 4U*USART2_RX_PIN) | (15U << 4U*USART2_TX_PIN)); + GPIOA->AFR[0] |= (( 7U << 4U*USART2_RX_PIN) | ( 7U << 4U*USART2_TX_PIN)); + GPIOA->MODER &= ~(( 3U << 2U*USART2_RX_PIN) | ( 3U << 2U*USART2_TX_PIN)); + GPIOA->MODER |= (( 2U << 2U*USART2_RX_PIN) | ( 2U << 2U*USART2_TX_PIN)); - USART2->BRR = __USART_BRR(SystemCoreClock, 115200U); /* baud rate */ - USART2->CR3 = 0x0000U; /* no flow control */ - USART2->CR2 = 0x0000U; /* 1 stop bit */ - USART2->CR1 = ((1U << 2) | /* enable RX */ - (1U << 3) | /* enable TX */ - (1U << 5) | /* enable RX interrupt */ - (0U << 12) | /* 1 start bit, 8 data bits */ - (1U << 13)); /* enable USART */ + USART2->BRR = __USART_BRR(SystemCoreClock, 115200U); // baud rate + USART2->CR3 = 0x0000U; // no flow control + USART2->CR2 = 0x0000U; // 1 stop bit + USART2->CR1 = ((1U << 2U) | // enable RX + (1U << 3U) | // enable TX + (1U << 5U) | // enable RX interrupt + (0U << 12U) | // 8 data bits + (0U << 28U) | // 8 data bits + (1U << 13U)); // enable USART - return 1U; /* return success */ + QS_tickPeriod_ = SystemCoreClock / BSP_TICKS_PER_SEC; + QS_tickTime_ = QS_tickPeriod_; // to start the timestamp at zero + + return 1U; // return success } -/*..........................................................................*/ +//............................................................................ void QS_onCleanup(void) { } -/*..........................................................................*/ -QSTimeCtr QS_onGetTime(void) { /* NOTE: invoked with interrupts DISABLED */ - if ((SysTick->CTRL & 0x00010000) == 0) { /* COUNT no set? */ +//............................................................................ +QSTimeCtr QS_onGetTime(void) { // NOTE: invoked with interrupts DISABLED + if ((SysTick->CTRL & 0x00010000U) == 0U) { // COUNT no set? return QS_tickTime_ - (QSTimeCtr)SysTick->VAL; } - else { /* the rollover occured, but the SysTick_ISR did not run yet */ + else { // the rollover occured, but the SysTick_ISR did not run yet return QS_tickTime_ + QS_tickPeriod_ - (QSTimeCtr)SysTick->VAL; } } -/*..........................................................................*/ +//............................................................................ void QS_onFlush(void) { - uint16_t b; - - QF_INT_DISABLE(); - while ((b = QS_getByte()) != QS_EOD) { /* while not End-Of-Data... */ - QF_INT_ENABLE(); - while ((USART2->SR & (1U << 7)) == 0U) { /* while TXE not empty */ - } - USART2->DR = (b & 0xFFU); /* put into the DR register */ + for (;;) { QF_INT_DISABLE(); + uint16_t b = QS_getByte(); + if (b != QS_EOD) { + while ((USART2->SR & (1U << 7U)) == 0U) { // while TXE not empty + QF_INT_ENABLE(); + QF_CRIT_EXIT_NOP(); + + QF_INT_DISABLE(); + } + USART2->DR = b; // put into the DR register + QF_INT_ENABLE(); + } + else { + QF_INT_ENABLE(); + break; + } } - QF_INT_ENABLE(); } -/*..........................................................................*/ -/*! callback function to reset the target (to be implemented in the BSP) */ +//............................................................................ +//! callback function to reset the target (to be implemented in the BSP) void QS_onReset(void) { NVIC_SystemReset(); } -/*..........................................................................*/ -/*! callback function to execute a user command (to be implemented in BSP) */ +//............................................................................ +//! callback function to execute a user command void QS_onCommand(uint8_t cmdId, uint32_t param1, uint32_t param2, uint32_t param3) { - (void)cmdId; - (void)param1; - (void)param2; - (void)param3; + Q_UNUSED_PAR(cmdId); + Q_UNUSED_PAR(param1); + Q_UNUSED_PAR(param2); + Q_UNUSED_PAR(param3); } -#endif /* Q_SPY */ -/*--------------------------------------------------------------------------*/ +#endif // Q_SPY +//---------------------------------------------------------------------------- -/***************************************************************************** -* NOTE00: -* The QF_AWARE_ISR_CMSIS_PRI constant from the QF port specifies the highest -* ISR priority that is disabled by the QF framework. The value is suitable -* for the NVIC_SetPriority() CMSIS function. -* -* Only ISRs prioritized at or below the QF_AWARE_ISR_CMSIS_PRI level (i.e., -* with the numerical values of priorities equal or higher than -* QF_AWARE_ISR_CMSIS_PRI) are allowed to call any QF services. These ISRs -* are "QF-aware". -* -* Conversely, any ISRs prioritized above the QF_AWARE_ISR_CMSIS_PRI priority -* level (i.e., with the numerical values of priorities less than -* QF_AWARE_ISR_CMSIS_PRI) are never disabled and are not aware of the kernel. -* Such "QF-unaware" ISRs cannot call any QF services. The only mechanism -* by which a "QF-unaware" ISR can communicate with the QF framework is by -* triggering a "QF-aware" ISR, which can post/publish events. -* -* NOTE01: -* The QV_onIdle() callback is called with interrupts disabled, because the -* determination of the idle condition might change by any interrupt posting -* an event. QV_onIdle() must internally enable interrupts, ideally -* atomically with putting the CPU to the power-saving mode. -* -* NOTE02: -* The User LED is used to visualize the idle loop activity. The brightness -* The User LED is used to visualize the idle loop activity. The brightness -* of the LED is proportional to the frequency of invcations of the idle loop. -* Please note that the LED is toggled with interrupts locked, so no interrupt -* execution time contributes to the brightness of the User LED. -*/ +//============================================================================ +// NOTE0: +// The QV_onIdle() callback is called with interrupts disabled, because the +// determination of the idle condition might change by any interrupt posting +// an event. QV_onIdle() must internally enable interrupts, ideally +// atomically with putting the CPU to the power-saving mode. +// +// NOTE1: +// The QF_AWARE_ISR_CMSIS_PRI constant from the QF port specifies the highest +// ISR priority that is disabled by the QF framework. The value is suitable +// for the NVIC_SetPriority() CMSIS function. +// +// Only ISRs prioritized at or below the QF_AWARE_ISR_CMSIS_PRI level (i.e., +// with the numerical values of priorities equal or higher than +// QF_AWARE_ISR_CMSIS_PRI) are allowed to call the QV_ISR_ENTRY/ +// QV_ISR_ENTRY macros or any other QF/QV services. These ISRs are +// "QF-aware". +// +// Conversely, any ISRs prioritized above the QF_AWARE_ISR_CMSIS_PRI priority +// level (i.e., with the numerical values of priorities less than +// QF_AWARE_ISR_CMSIS_PRI) are never disabled and are not aware of the kernel. +// Such "QF-unaware" ISRs cannot call ANY QF/QV services. In particular they +// can NOT call the macros QV_ISR_ENTRY/QV_ISR_ENTRY. The only mechanism +// by which a "QF-unaware" ISR can communicate with the QF framework is by +// triggering a "QF-aware" ISR, which can post/publish events. +// +// NOTE2: +// The User LED is used to visualize the idle loop activity. The brightness +// of the LED is proportional to the frequency of the idle loop. +// Please note that the LED is toggled with interrupts locked, so no interrupt +// execution time contributes to the brightness of the User LED. +// diff --git a/examples/arm-cm/dpp_nucleo-l152re/qv/gnu/Makefile b/examples/arm-cm/dpp_nucleo-l152re/qv/gnu/Makefile index edced21f..8445cd62 100644 --- a/examples/arm-cm/dpp_nucleo-l152re/qv/gnu/Makefile +++ b/examples/arm-cm/dpp_nucleo-l152re/qv/gnu/Makefile @@ -133,7 +133,8 @@ LIB_DIRS := LIBS := # defines -DEFINES := +DEFINES := \ + -DQF_ON_CONTEXT_SW # ARM CPU, ARCH, FPU, and Float-ABI types... # ARM_CPU: [cortex-m0 | cortex-m0plus | cortex-m1 | cortex-m3 | cortex-m4] @@ -174,7 +175,7 @@ MKDIR := mkdir RM := rm #----------------------------------------------------------------------------- -# build options for various configurations for ARM Cortex-M4F +# build options for various configurations for ARM Cortex-M # # combine all the soruces... @@ -261,7 +262,7 @@ $(TARGET_BIN): $(TARGET_ELF) $(BIN) -O binary $< $@ $(TARGET_ELF) : $(ASM_OBJS_EXT) $(C_OBJS_EXT) $(CPP_OBJS_EXT) - $(CC) $(CFLAGS) $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o + $(CC) $(CFLAGS) $(QPC)/src/qs/qstamp.c -o $(BIN_DIR)/qstamp.o $(LINK) $(LINKFLAGS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) $(BIN_DIR)/%.d : %.c diff --git a/examples/arm-cm/dpp_nucleo-l152re/qv/gnu/dpp-qv.ld b/examples/arm-cm/dpp_nucleo-l152re/qv/gnu/dpp-qv.ld index b3a6ec97..349f5dc6 100644 --- a/examples/arm-cm/dpp_nucleo-l152re/qv/gnu/dpp-qv.ld +++ b/examples/arm-cm/dpp_nucleo-l152re/qv/gnu/dpp-qv.ld @@ -91,8 +91,9 @@ SECTIONS { .stack : { __stack_start__ = .; . = . + STACK_SIZE; - . = ALIGN(4); + . = ALIGN(8); __stack_end__ = .; + ASSERT(((. - __stack_start__) == STACK_SIZE), "Error: Stack misaligned"); } >RAM .data : AT (_etext) { diff --git a/examples/arm-cm/dpp_nucleo-l152re/qv/iar/dpp-qv.ewd b/examples/arm-cm/dpp_nucleo-l152re/qv/iar/dpp-qv.ewd index 0f2b25ed..1201cb55 100644 --- a/examples/arm-cm/dpp_nucleo-l152re/qv/iar/dpp-qv.ewd +++ b/examples/arm-cm/dpp_nucleo-l152re/qv/iar/dpp-qv.ewd @@ -88,7 +88,7 @@ - - BILINK - 0 - - Coder 0 @@ -1071,9 +1090,13 @@ General 3 - 31 + 35 1 0 + - - - - - + + + + + ICCARM 2 - 35 + 37 1 0 - - - + AARM 2 - 10 + 11 1 0 + @@ -1732,13 +1747,9 @@ 0 + inputOutputBased - - BICOMP - 0 - - BUILDACTION 1 @@ -1751,17 +1762,13 @@ ILINK 0 - 23 + 27 1 0 - + + + + + + + + + @@ -2110,11 +2153,6 @@ - - BILINK - 0 - - Coder 0 @@ -2131,9 +2169,13 @@ General 3 - 31 + 35 1 1 + - - - - - + + + + + ICCARM 2 - 35 + 37 1 1 - - - + AARM 2 - 10 + 11 1 1 + @@ -2792,13 +2827,9 @@ 0 + inputOutputBased - - BICOMP - 0 - - BUILDACTION 1 @@ -2811,17 +2842,13 @@ ILINK 0 - 23 + 27 1 1 - + + + + + + + + + @@ -3170,11 +3233,6 @@ - - BILINK - 0 - - Coder 0 @@ -3193,14 +3251,11 @@ $PROJ_DIR$\..\..\dpp.h - $PROJ_DIR$\..\main.c + $PROJ_DIR$\..\..\main.c $PROJ_DIR$\..\..\philo.c - - $PROJ_DIR$\..\..\..\..\..\include\qstamp.c - $PROJ_DIR$\..\..\table.c @@ -3267,21 +3322,9 @@ QP_port - - $PROJ_DIR$\..\..\..\..\..\ports\arm-cm\qv\iar\qep_port.h - - - $PROJ_DIR$\..\..\..\..\..\ports\arm-cm\qv\iar\qf_port.h - - - $PROJ_DIR$\..\..\..\..\..\ports\arm-cm\qv\iar\qs_port.h - $PROJ_DIR$\..\..\..\..\..\ports\arm-cm\qv\iar\qv_port.c - - $PROJ_DIR$\..\..\..\..\..\ports\arm-cm\qv\iar\qv_port.h - QS @@ -3304,5 +3347,8 @@ $PROJ_DIR$\..\..\..\..\..\src\qs\qs_rx.c + + $PROJ_DIR$\..\..\..\..\..\src\qs\qstamp.c + diff --git a/examples/arm-cm/dpp_nucleo-l152re/qv/main.c b/examples/arm-cm/dpp_nucleo-l152re/qv/main.c deleted file mode 100644 index fa8de8d8..00000000 --- a/examples/arm-cm/dpp_nucleo-l152re/qv/main.c +++ /dev/null @@ -1,87 +0,0 @@ -/***************************************************************************** -* Product: DPP example -* Last updated for version 7.1.2 -* Last updated on 2022-10-06 -* -* Q u a n t u m L e a P s -* ------------------------ -* Modern Embedded Software -* -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* -* -*****************************************************************************/ -#include "qpc.h" -#include "dpp.h" -#include "bsp.h" - -Q_DEFINE_THIS_FILE - -/*..........................................................................*/ -int main() { - static QEvt const *tableQueueSto[N_PHILO]; - static QEvt const *philoQueueSto[N_PHILO][N_PHILO]; - static QSubscrList subscrSto[MAX_PUB_SIG]; - static QF_MPOOL_EL(TableEvt) smlPoolSto[2*N_PHILO]; /* small pool */ - uint8_t n; - - Philo_ctor(); /* instantiate all Philosopher active objects */ - Table_ctor(); /* instantiate the Table active object */ - - QF_init(); /* initialize the framework and the underlying RT kernel */ - BSP_init(); /* initialize the Board Support Package */ - - /* object dictionaries... */ - QS_OBJ_DICTIONARY(AO_Table); - QS_OBJ_DICTIONARY(AO_Philo[0]); - QS_OBJ_DICTIONARY(AO_Philo[1]); - QS_OBJ_DICTIONARY(AO_Philo[2]); - QS_OBJ_DICTIONARY(AO_Philo[3]); - QS_OBJ_DICTIONARY(AO_Philo[4]); - - /* initialize publish-subscribe... */ - QF_psInit(subscrSto, Q_DIM(subscrSto)); - - /* initialize event pools... */ - QF_poolInit(smlPoolSto, sizeof(smlPoolSto), sizeof(smlPoolSto[0])); - - /* start the active objects... */ - for (n = 0U; n < N_PHILO; ++n) { - QACTIVE_START(AO_Philo[n], /* AO to start */ - n + 1U, /* QF-priority */ - philoQueueSto[n], /* event queue storage */ - Q_DIM(philoQueueSto[n]), /* queue length [events] */ - (void *)0, /* stack storage (not used) */ - 0U, /* size of the stack [bytes] */ - (void *)0); /* initialization param */ - } - QACTIVE_START(AO_Table, /* AO to start */ - N_PHILO + 1U, /* QF-priority */ - tableQueueSto, /* event queue storage */ - Q_DIM(tableQueueSto), /* queue length [events] */ - (void *)0, /* stack storage (not used) */ - 0U, /* size of the stack [bytes] */ - (void *)0); /* initialization param */ - - return QF_run(); /* run the QF application */ -} diff --git a/examples/arm-cm/dpp_nucleo-l152re/qxk/armclang/dpp-qxk.sct b/examples/arm-cm/dpp_nucleo-l152re/qxk/armclang/dpp-qxk.sct new file mode 100644 index 00000000..fbadbbfa --- /dev/null +++ b/examples/arm-cm/dpp_nucleo-l152re/qxk/armclang/dpp-qxk.sct @@ -0,0 +1,22 @@ +; ************************************************************* +; *** Scatter-Loading Description File generated by uVision *** +; +; Adapted by Quantum Leaps: +; moved STACK as the first section in RW_IRAM1 +; ************************************************************* + +LR_IROM1 0x08000000 0x00080000 { ; load region size_region + ER_IROM1 0x08000000 0x00080000 { ; load address = execution address + *.o (RESET, +First) + *(InRoot$$Sections) + .ANY (+RO) + .ANY (+XO) + } + RW_STACK 0x20000000 { ; <== Quantum Leaps + * (STACK, +First) + } + RW_IRAM1 +0 (0x00014000 - 2048) { ; NOTE: 2048 assumed for STACK size! + .ANY (+RW +ZI) + } +} + diff --git a/examples/arm-cm/dpp_nucleo-l152re/qxk/armclang/dpp-qxk.uvoptx b/examples/arm-cm/dpp_nucleo-l152re/qxk/armclang/dpp-qxk.uvoptx index 21622001..4d4d4109 100644 --- a/examples/arm-cm/dpp_nucleo-l152re/qxk/armclang/dpp-qxk.uvoptx +++ b/examples/arm-cm/dpp_nucleo-l152re/qxk/armclang/dpp-qxk.uvoptx @@ -125,7 +125,7 @@ 0 DLGTARM - (1010=-1,-1,-1,-1,0)(1007=-1,-1,-1,-1,0)(1008=-1,-1,-1,-1,0)(1009=-1,-1,-1,-1,0)(1012=-1,-1,-1,-1,0) + (1010=2681,172,3131,729,0)(1007=-1,-1,-1,-1,0)(1008=-1,-1,-1,-1,0)(1009=-1,-1,-1,-1,0)(1012=2661,343,3138,658,0) 0 @@ -140,7 +140,7 @@ 0 ST-LINKIII-KEIL_SWO - -U066EFF495056805087184715 -O8398 -S1 -C0 -A0 -N00("ARM CoreSight SW-DP") -D00(2BA01477) -L00(0) -TO18 -TC10000000 -TP21 -TDS8007 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -FO15 -FD20000000 -FC1000 -FN1 -FF0STM32L1xx_512.FLM -FS08000000 -FL080000 -FP0($$Device:STM32L152RE$CMSIS\Flash\STM32L1xx_512.FLM) + -U066EFF495056805087184715 -O8398 -SF10000 -C0 -A0 -I0 -HNlocalhost -HP7184 -P1 -N00("ARM CoreSight SW-DP (ARM Core") -D00(2BA01477) -L00(0) -TO131090 -TC10000000 -TT10000000 -TP21 -TDS8007 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -FO15 -FD20000000 -FC1000 -FN1 -FF0STM32L1xx_512.FLM -FS08000000 -FL080000 -FP0($$Device:STM32L152RE$CMSIS\Flash\STM32L1xx_512.FLM) 0 @@ -148,12 +148,29 @@ UL2CM3(-S0 -C0 -P0 -FD20000000 -FC1000 -FN1 -FF0STM32L1xx_512 -FS08000000 -FL080000 -FP0($$Device:STM32L152RE$CMSIS\Flash\STM32L1xx_512.FLM)) - + + + 0 + 0 + 304 + 1 +
134228394
+ 0 + 0 + 0 + 0 + 0 + 1 + ..\bsp.c + + \\dpp_qxk\../bsp.c\304 +
+
1 2 - 0x20000200 + 0x0 0 @@ -209,7 +226,7 @@ 1 - 1 + 0 0 2 10000000 @@ -299,7 +316,7 @@ 1 0 0 - 5 + 6 @@ -336,12 +353,12 @@ 0 ST-LINKIII-KEIL_SWO - -U066EFF495056805087184715 -I0 -O8430 -S1 -C0 -A0 -N00("ARM CoreSight SW-DP") -D00(2BA01477) -L00(0) -TO18 -TC10000000 -TP21 -TDS8007 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -FO15 -FD20000000 -FC1000 -FN1 -FF0STM32L1xx_512.FLM -FS08000000 -FL080000 -FP0($$Device:STM32L152RE$Flash\STM32L1xx_512.FLM) + -U066EFF495056805087184715 -I0 -O8430 -S1 -C0 -A0 -N00("ARM CoreSight SW-DP") -D00(2BA01477) -L00(0) -TO18 -TC10000000 -TP21 -TDS8007 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -FO15 -FD20000000 -FC1000 -FN1 -FF0STM32L1xx_512.FLM -FS08000000 -FL080000 -FP0($$Device:STM32L152RE$CMSIS\Flash\STM32L1xx_512.FLM) 0 UL2CM3 - UL2CM3(-S0 -C0 -P0 -FD20000000 -FC1000 -FN1 -FF0STM32L1xx_512 -FS08000000 -FL080000 -FP0($$Device:STM32L152RE$Flash\STM32L1xx_512.FLM)) + UL2CM3(-S0 -C0 -P0 -FD20000000 -FC1000 -FN1 -FF0STM32L1xx_512 -FS08000000 -FL080000 -FP0($$Device:STM32L152RE$CMSIS\Flash\STM32L1xx_512.FLM)) @@ -420,6 +437,13 @@ + + 1 + 1 + 0 + 2 + 10000000 +
@@ -505,7 +529,7 @@ 1 0 0 - 5 + 6 @@ -542,32 +566,22 @@ 0 ST-LINKIII-KEIL_SWO - -U066EFF495056805087184715 -I0 -O8398 -S1 -C0 -A0 -N00("ARM CoreSight SW-DP") -D00(2BA01477) -L00(0) -TO18 -TC10000000 -TP21 -TDS8007 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -FO15 -FD20000000 -FC1000 -FN1 -FF0STM32L1xx_512.FLM -FS08000000 -FL080000 -FP0($$Device:STM32L152RE$Flash\STM32L1xx_512.FLM) + -U066EFF495056805087184715 -O8398 -SF10000 -C0 -A0 -I0 -HNlocalhost -HP7184 -P1 -N00("ARM CoreSight SW-DP (ARM Core") -D00(2BA01477) -L00(0) -TO131090 -TC10000000 -TT10000000 -TP21 -TDS8007 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -FO15 -FD20000000 -FC1000 -FN1 -FF0STM32L1xx_512.FLM -FS08000000 -FL080000 -FP0($$Device:STM32L152RE$CMSIS\Flash\STM32L1xx_512.FLM) 0 UL2CM3 - UL2CM3(-S0 -C0 -P0 -FD20000000 -FC1000 -FN1 -FF0STM32L1xx_512 -FS08000000 -FL080000 -FP0($$Device:STM32L152RE$Flash\STM32L1xx_512.FLM)) + UL2CM3(-S0 -C0 -P0 -FD20000000 -FC1000 -FN1 -FF0STM32L1xx_512 -FS08000000 -FL080000 -FP0($$Device:STM32L152RE$CMSIS\Flash\STM32L1xx_512.FLM)) - - - 0 - 0 - 214 - 1 -
134222098
- 0 - 0 - 0 - 0 - 0 - 1 - ..\bsp.c - - \\dpp_qxk\../bsp.c\214 -
-
+ + + + 0 + 1 + QS_filter_ + + 1 @@ -626,6 +640,13 @@ + + 1 + 0 + 0 + 2 + 10000000 + @@ -686,18 +707,6 @@ 1 5 - 5 - 0 - 0 - 0 - ..\..\README.txt - README.txt - 0 - 0 - - - 1 - 6 1 0 0 @@ -707,6 +716,18 @@ 0 0 + + 1 + 6 + 1 + 0 + 0 + 0 + ..\xthread1.c + xthread1.c + 0 + 0 + 1 7 @@ -714,8 +735,8 @@ 0 0 0 - ..\..\..\..\..\include\qstamp.c - qstamp.c + ..\xthread2.c + xthread2.c 0 0 @@ -726,23 +747,11 @@ 0 0 0 - ..\main.c + ..\..\main.c main.c 0 0 - - 1 - 9 - 1 - 0 - 0 - 0 - ..\test.c - test.c - 0 - 0 - @@ -753,7 +762,7 @@ 0 2 - 10 + 9 5 0 0 @@ -765,7 +774,7 @@ 2 - 11 + 10 5 0 0 @@ -777,7 +786,7 @@ 2 - 12 + 11 1 0 0 @@ -789,7 +798,7 @@ 2 - 13 + 12 5 0 0 @@ -801,7 +810,7 @@ 2 - 14 + 13 2 0 0 @@ -821,7 +830,7 @@ 0 3 - 15 + 14 1 0 0 @@ -833,7 +842,7 @@ 3 - 16 + 15 1 0 0 @@ -845,7 +854,7 @@ 3 - 17 + 16 1 0 0 @@ -857,7 +866,7 @@ 3 - 18 + 17 1 0 0 @@ -869,7 +878,7 @@ 3 - 19 + 18 1 0 0 @@ -881,7 +890,7 @@ 3 - 20 + 19 1 0 0 @@ -893,7 +902,7 @@ 3 - 21 + 20 1 0 0 @@ -905,19 +914,7 @@ 3 - 22 - 5 - 0 - 0 - 0 - ..\..\..\..\..\src\qf_pkg.h - qf_pkg.h - 0 - 0 - - - 3 - 23 + 21 1 0 0 @@ -929,7 +926,7 @@ 3 - 24 + 22 1 0 0 @@ -941,7 +938,7 @@ 3 - 25 + 23 1 0 0 @@ -953,7 +950,7 @@ 3 - 26 + 24 1 0 0 @@ -965,7 +962,7 @@ 3 - 27 + 25 1 0 0 @@ -977,7 +974,7 @@ 3 - 28 + 26 1 0 0 @@ -989,7 +986,7 @@ 3 - 29 + 27 1 0 0 @@ -1001,7 +998,7 @@ 3 - 30 + 28 1 0 0 @@ -1013,7 +1010,7 @@ 3 - 31 + 29 1 0 0 @@ -1033,43 +1030,7 @@ 0 4 - 32 - 5 - 0 - 0 - 0 - ..\..\..\..\..\ports\arm-cm\qxk\armclang\qep_port.h - qep_port.h - 0 - 0 - - - 4 - 33 - 5 - 0 - 0 - 0 - ..\..\..\..\..\ports\arm-cm\qxk\armclang\qf_port.h - qf_port.h - 0 - 0 - - - 4 - 34 - 5 - 0 - 0 - 0 - ..\..\..\..\..\ports\arm-cm\qxk\armclang\qxk_port.h - qxk_port.h - 0 - 0 - - - 4 - 35 + 30 1 0 0 @@ -1081,7 +1042,7 @@ 4 - 36 + 31 5 0 0 @@ -1101,7 +1062,7 @@ 0 5 - 37 + 32 1 0 0 @@ -1113,7 +1074,7 @@ 5 - 38 + 33 1 0 0 @@ -1125,7 +1086,7 @@ 5 - 39 + 34 1 0 0 @@ -1135,6 +1096,18 @@ 0 0 + + 5 + 35 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qs\qstamp.c + qstamp.c + 0 + 0 + diff --git a/examples/arm-cm/dpp_nucleo-l152re/qxk/armclang/dpp-qxk.uvprojx b/examples/arm-cm/dpp_nucleo-l152re/qxk/armclang/dpp-qxk.uvprojx index 3ee18a1a..29c377aa 100644 --- a/examples/arm-cm/dpp_nucleo-l152re/qxk/armclang/dpp-qxk.uvprojx +++ b/examples/arm-cm/dpp_nucleo-l152re/qxk/armclang/dpp-qxk.uvprojx @@ -313,7 +313,7 @@ 0 - 7 + 1 0 0 1 @@ -361,7 +361,7 @@ - 1 + 0 0 0 0 @@ -370,7 +370,7 @@ 0x00000000 0x20000000 - + dpp-qxk.sct --entry Reset_Handler @@ -403,30 +403,25 @@ 1 ..\..\philo.c - - README.txt - 5 - ..\..\README.txt - table.c 1 ..\..\table.c - qstamp.c + xthread1.c 1 - ..\..\..\..\..\include\qstamp.c + ..\xthread1.c + + + xthread2.c + 1 + ..\xthread2.c main.c 1 - ..\main.c - - - test.c - 1 - ..\test.c + ..\..\main.c @@ -498,11 +493,6 @@ 1 ..\..\..\..\..\src\qf\qf_mem.c - - qf_pkg.h - 5 - ..\..\..\..\..\src\qf_pkg.h - qf_ps.c 1 @@ -553,21 +543,6 @@ QP_port - - qep_port.h - 5 - ..\..\..\..\..\ports\arm-cm\qxk\armclang\qep_port.h - - - qf_port.h - 5 - ..\..\..\..\..\ports\arm-cm\qxk\armclang\qf_port.h - - - qxk_port.h - 5 - ..\..\..\..\..\ports\arm-cm\qxk\armclang\qxk_port.h - qxk_port.c 1 @@ -667,6 +642,11 @@ 1 ..\..\..\..\..\src\qs\qs_rx.c + + qstamp.c + 1 + ..\..\..\..\..\src\qs\qstamp.c + @@ -675,13 +655,13 @@ dpp-rel 0x4 ARM-ADS - 5060020::V5.06 (build 20)::ARMCC + 6160000::V6.16::ARMCLANG 1 STM32L152RE STMicroelectronics - Keil.STM32L1xx_DFP.1.0.2 + Keil.STM32L1xx_DFP.1.4.1 http://www.keil.com/pack/ IROM(0x08000000,0x80000) IRAM(0x20000000,0x14000) CPUTYPE("Cortex-M3") CLOCK(12000000) ELITTLE @@ -1026,7 +1006,7 @@ - 1 + 0 0 0 0 @@ -1035,7 +1015,7 @@ 0x00000000 0x20000000 - dpp-qxk.sct + .\dpp-qxk.sct --entry Reset_Handler @@ -1068,30 +1048,25 @@ 1 ..\..\philo.c - - README.txt - 5 - ..\..\README.txt - table.c 1 ..\..\table.c - qstamp.c + xthread1.c 1 - ..\..\..\..\..\include\qstamp.c + ..\xthread1.c + + + xthread2.c + 1 + ..\xthread2.c main.c 1 - ..\main.c - - - test.c - 1 - ..\test.c + ..\..\main.c @@ -1163,11 +1138,6 @@ 1 ..\..\..\..\..\src\qf\qf_mem.c - - qf_pkg.h - 5 - ..\..\..\..\..\src\qf_pkg.h - qf_ps.c 1 @@ -1218,21 +1188,6 @@ QP_port - - qep_port.h - 5 - ..\..\..\..\..\ports\arm-cm\qxk\armclang\qep_port.h - - - qf_port.h - 5 - ..\..\..\..\..\ports\arm-cm\qxk\armclang\qf_port.h - - - qxk_port.h - 5 - ..\..\..\..\..\ports\arm-cm\qxk\armclang\qxk_port.h - qxk_port.c 1 @@ -1332,6 +1287,11 @@ 1 ..\..\..\..\..\src\qs\qs_rx.c + + qstamp.c + 1 + ..\..\..\..\..\src\qs\qstamp.c + @@ -1340,13 +1300,13 @@ dpp-spy 0x4 ARM-ADS - 6130001::V6.13.1::.\ARMCLANG + 6160000::V6.16::ARMCLANG 1 STM32L152RE STMicroelectronics - Keil.STM32L1xx_DFP.1.0.2 + Keil.STM32L1xx_DFP.1.4.1 http://www.keil.com/pack/ IROM(0x08000000,0x80000) IRAM(0x20000000,0x14000) CPUTYPE("Cortex-M3") CLOCK(12000000) ELITTLE @@ -1643,7 +1603,7 @@ 0 - 7 + 1 0 0 1 @@ -1667,7 +1627,7 @@ 0 - Q_SPY + Q_SPY,QF_ON_CONTEXT_SW ..\..;..\..\..\..\..\include;..\..\..\..\..\ports\arm-cm\qxk\armclang;..\..\..\..\..\3rd_party\CMSIS\Include; ..\..\..\..\..\3rd_party\nucleo-l152re @@ -1691,7 +1651,7 @@ - 1 + 0 0 0 0 @@ -1700,7 +1660,7 @@ 0x00000000 0x20000000 - dpp-qxk.sct + .\dpp-qxk.sct --entry Reset_Handler @@ -1733,30 +1693,25 @@ 1 ..\..\philo.c - - README.txt - 5 - ..\..\README.txt - table.c 1 ..\..\table.c - qstamp.c + xthread1.c 1 - ..\..\..\..\..\include\qstamp.c + ..\xthread1.c + + + xthread2.c + 1 + ..\xthread2.c main.c 1 - ..\main.c - - - test.c - 1 - ..\test.c + ..\..\main.c @@ -1828,11 +1783,6 @@ 1 ..\..\..\..\..\src\qf\qf_mem.c - - qf_pkg.h - 5 - ..\..\..\..\..\src\qf_pkg.h - qf_ps.c 1 @@ -1883,21 +1833,6 @@ QP_port - - qep_port.h - 5 - ..\..\..\..\..\ports\arm-cm\qxk\armclang\qep_port.h - - - qf_port.h - 5 - ..\..\..\..\..\ports\arm-cm\qxk\armclang\qf_port.h - - - qxk_port.h - 5 - ..\..\..\..\..\ports\arm-cm\qxk\armclang\qxk_port.h - qxk_port.c 1 @@ -1928,6 +1863,11 @@ 1 ..\..\..\..\..\src\qs\qs_rx.c + + qstamp.c + 1 + ..\..\..\..\..\src\qs\qstamp.c + diff --git a/examples/arm-cm/dpp_nucleo-l152re/qxk/bsp.c b/examples/arm-cm/dpp_nucleo-l152re/qxk/bsp.c index 0b6087d7..4b55255c 100644 --- a/examples/arm-cm/dpp_nucleo-l152re/qxk/bsp.c +++ b/examples/arm-cm/dpp_nucleo-l152re/qxk/bsp.c @@ -1,307 +1,429 @@ -/***************************************************************************** -* Product: DPP example, STM32 NUCLEO-L152RE board, preemptive QXK kernel -* Last updated for version 6.9.3 -* Last updated on 2021-03-03 -* -* Q u a n t u m L e a P s -* ------------------------ -* Modern Embedded Software -* -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* -* -*****************************************************************************/ -#include "qpc.h" -#include "dpp.h" -#include "bsp.h" +//============================================================================ +// Product: DPP example, NUCLEO-L152RE board, QXK kernel +// Last updated for version 7.3.0 +// Last updated on 2023-08-23 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. +// +// This program is open source software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Alternatively, this program may be distributed and modified under the +// terms of Quantum Leaps commercial licenses, which expressly supersede +// the GNU General Public License and are specifically designed for +// licensees interested in retaining the proprietary status of their code. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Contact information: +// +// +//============================================================================ +#include "qpc.h" // QP/C real-time embedded framework +#include "dpp.h" // DPP Application interface +#include "bsp.h" // Board Support Package -#include "stm32l1xx.h" /* CMSIS-compliant header file for the MCU used */ -/* add other drivers if necessary... */ +#include "stm32l1xx.h" // CMSIS-compliant header file for the MCU used +// add other drivers if necessary... -Q_DEFINE_THIS_FILE +Q_DEFINE_THIS_FILE // define the name of this file for assertions -/* Local-scope objects -----------------------------------------------------*/ -/* LED pins available on the board (just one user LED LD2--Green on PA.5) */ -#define LED_LD2 (1U << 5) +// Local-scope defines ----------------------------------------------------- +// LED pins available on the board (just one user LED LD2--Green on PA.5) +#define LD2_PIN 5U -/* Button pins available on the board (just one user Button B1 on PC.13) */ -#define BTN_B1 (1U << 13) +// Button pins available on the board (just one user Button B1 on PC.13) +#define B1_PIN 13U -static uint32_t l_rnd; /* random seed */ +static uint32_t l_rndSeed; #ifdef Q_SPY + QSTimeCtr QS_tickTime_; QSTimeCtr QS_tickPeriod_; - /* QSpy source IDs */ + // QSpy source IDs static QSpyId const l_SysTick_Handler = { 0U }; + static QSpyId const l_EXTI9_5_IRQHandler = { 0U }; - enum AppRecords { /* application-specific trace records */ - PHILO_STAT = QS_USER + enum AppRecords { // application-specific trace records + PHILO_STAT = QS_USER, + PAUSED_STAT, + CONTEXT_SW, }; #endif -/* ISRs used in the application ==========================================*/ -void SysTick_Handler(void); -void USART2_IRQHandler(void); +//============================================================================ +// Error handler and ISRs... -/*..........................................................................*/ -void SysTick_Handler(void) { /* system clock tick ISR -- kernel aware */ - /* state of the button debouncing, see below */ - static struct ButtonsDebouncing { - uint32_t depressed; - uint32_t previous; - } buttons = { 0U, 0U }; - uint32_t current; - uint32_t tmp; +Q_NORETURN Q_onError(char const * const module, int_t const id) { + // NOTE: this implementation of the assertion handler is intended only + // for debugging and MUST be changed for deployment of the application + // (assuming that you ship your production code with assertions enabled). + Q_UNUSED_PAR(module); + Q_UNUSED_PAR(id); + QS_ASSERTION(module, id, 10000U); - QXK_ISR_ENTRY(); /* inform QXK about entering an ISR */ - -#ifdef Q_SPY - { - tmp = SysTick->CTRL; /* clear CTRL_COUNTFLAG */ - QS_tickTime_ += QS_tickPeriod_; /* account for the clock rollover */ +#ifndef NDEBUG + // light up the user LED + GPIOA->BSRRL = (1U << LD2_PIN); // turn LED on + // for debugging, hang on in an endless loop... + for (;;) { } #endif - QTIMEEVT_TICK_X(0U, &l_SysTick_Handler); /* process time events for rate 0 */ + NVIC_SystemReset(); +} +//............................................................................ +void assert_failed(char const * const module, int_t const id); // prototype +void assert_failed(char const * const module, int_t const id) { + Q_onError(module, id); +} - /* get state of the user button */ - /* Perform the debouncing of buttons. The algorithm for debouncing - * adapted from the book "Embedded Systems Dictionary" by Jack Ganssle - * and Michael Barr, page 71. - */ - current = ~GPIOC->IDR; /* read Port C with the state of Button B1 */ - tmp = buttons.depressed; /* save the debounced depressed buttons */ - buttons.depressed |= (buttons.previous & current); /* set depressed */ - buttons.depressed &= (buttons.previous | current); /* clear released */ - buttons.previous = current; /* update the history */ - tmp ^= buttons.depressed; /* changed debounced depressed */ - if ((tmp & BTN_B1) != 0U) { /* debounced B1 state changed? */ - if ((buttons.depressed & BTN_B1) != 0U) { /* is B1 depressed? */ - static QEvt const pauseEvt = { PAUSE_SIG, 0U, 0U}; +// ISRs used in the application ========================================== +void SysTick_Handler(void); // prototype +void SysTick_Handler(void) { + QXK_ISR_ENTRY(); // inform QXK about entering an ISR + + QTIMEEVT_TICK_X(0U, &l_SysTick_Handler); // time events at rate 0 + + // Perform the debouncing of buttons. The algorithm for debouncing + // adapted from the book "Embedded Systems Dictionary" by Jack Ganssle + // and Michael Barr, page 71. + static struct { + uint32_t depressed; + uint32_t previous; + } buttons = { 0U, 0U }; + + uint32_t current = ~GPIOC->IDR; // read Port C with Button B1 + uint32_t tmp = buttons.depressed; // save the depressed buttons + buttons.depressed |= (buttons.previous & current); // set depressed + buttons.depressed &= (buttons.previous | current); // clear released + buttons.previous = current; // update the history + tmp ^= buttons.depressed; // changed debounced depressed + current = buttons.depressed; + + if ((tmp & (1U << B1_PIN)) != 0U) { // debounced B1 state changed? + if ((current & (1U << B1_PIN)) != 0U) { // is B1 depressed? + static QEvt const pauseEvt = QEVT_INITIALIZER(PAUSE_SIG); QACTIVE_PUBLISH(&pauseEvt, &l_SysTick_Handler); } - else { /* the button is released */ - static QEvt const serveEvt = { SERVE_SIG, 0U, 0U}; + else { // the button is released + static QEvt const serveEvt = QEVT_INITIALIZER(SERVE_SIG); QACTIVE_PUBLISH(&serveEvt, &l_SysTick_Handler); } } - QXK_ISR_EXIT(); /* inform QXK about exiting an ISR */ +#ifdef Q_SPY + tmp = SysTick->CTRL; // clear CTRL_COUNTFLAG + QS_tickTime_ += QS_tickPeriod_; // account for the clock rollover +#endif + + QXK_ISR_EXIT(); // inform QXK about exiting an ISR } -/*..........................................................................*/ -#if Q_SPY -void USART2_IRQHandler(void) { /* kernel UNAWARE interrupt */ - /* is RX register NOT empty? */ - if ((USART2->SR & (1U << 5)) != 0) { +//............................................................................ +// interrupt handler for testing preemptions in QXK +void EXTI9_5_IRQHandler(void); // prototype +void EXTI9_5_IRQHandler(void) { + QXK_ISR_ENTRY(); // inform QXK about entering an ISR + + // for testing.. + static QEvt const testEvt = QEVT_INITIALIZER(TEST_SIG); + QACTIVE_POST(AO_Table, &testEvt, &l_EXTI9_5_IRQHandler); + + QXK_ISR_EXIT(); // inform QXK about exiting an ISR +} + +//............................................................................ +#ifdef Q_SPY +// ISR for receiving bytes from the QSPY Back-End +// NOTE: This ISR is "QF-unaware" meaning that it does not interact with +// the QF/QXK and is not disabled. Such ISRs don't need to call +// QXK_ISR_ENTRY/QXK_ISR_EXIT and they cannot post or publish events. + +void USART2_IRQHandler(void); // prototype +void USART2_IRQHandler(void) { // used in QS-RX (kernel UNAWARE interrutp) + // is RX register NOT empty? + if ((USART2->SR & (1U << 5U)) != 0U) { uint32_t b = USART2->DR; QS_RX_PUT(b); } + QXK_ARM_ERRATUM_838869(); } -#endif +#endif // Q_SPY + +//............................................................................ +#ifdef QF_ON_CONTEXT_SW +// NOTE: the context-switch callback is called with interrupts DISABLED +void QF_onContextSw(QActive *prev, QActive *next) { + QS_BEGIN_INCRIT(CONTEXT_SW, 0U) // in critical section! + QS_OBJ(prev); + QS_OBJ(next); + QS_END_INCRIT() +} +#endif // QF_ON_CONTEXT_SW + +//============================================================================ +// BSP functions... -/* BSP functions ===========================================================*/ void BSP_init(void) { - /* NOTE: SystemInit() has been already called from the startup code - * but SystemCoreClock needs to be updated - */ + // Configure the MPU to prevent NULL-pointer dereferencing ... + MPU->RBAR = 0x0U // base address (NULL) + | MPU_RBAR_VALID_Msk // valid region + | (MPU_RBAR_REGION_Msk & 7U); // region #7 + MPU->RASR = (7U << MPU_RASR_SIZE_Pos) // 2^(7+1) region + | (0x0U << MPU_RASR_AP_Pos) // no-access region + | MPU_RASR_ENABLE_Msk; // region enable + MPU->CTRL = MPU_CTRL_PRIVDEFENA_Msk // enable background region + | MPU_CTRL_ENABLE_Msk; // enable the MPU + __ISB(); + __DSB(); + + // NOTE: SystemInit() has been already called from the startup code + // but SystemCoreClock needs to be updated SystemCoreClockUpdate(); - /* enable GPIOA clock port for the LED LD2 */ + // enable GPIOA clock port for the LED LD2 RCC->AHBENR |= (1U << 0); - /* configure LED (PA.5) pin as push-pull output, no pull-up, pull-down */ - GPIOA->MODER &= ~((3U << 2*5)); - GPIOA->MODER |= ((1U << 2*5)); - GPIOA->OTYPER &= ~((1U << 5)); - GPIOA->OSPEEDR &= ~((3U << 2*5)); - GPIOA->OSPEEDR |= ((1U << 2*5)); - GPIOA->PUPDR &= ~((3U << 2*5)); + // configure LED (PA.5) pin as push-pull output, no pull-up, pull-down + GPIOA->MODER &= ~((3U << 2U*LD2_PIN)); + GPIOA->MODER |= ((1U << 2U*LD2_PIN)); + GPIOA->OTYPER &= ~((1U << LD2_PIN)); + GPIOA->OSPEEDR &= ~((3U << 2U*LD2_PIN)); + GPIOA->OSPEEDR |= ((1U << 2U*LD2_PIN)); + GPIOA->PUPDR &= ~((3U << 2U*LD2_PIN)); - /* enable GPIOC clock port for the Button B1 */ + // enable GPIOC clock port for the Button B1 RCC->AHBENR |= (1U << 2); - /* configure Button (PC.13) pins as input, no pull-up, pull-down */ - GPIOC->MODER &= ~(3U << 2*13); - GPIOC->OSPEEDR &= ~(3U << 2*13); - GPIOC->OSPEEDR |= (1U << 2*13); - GPIOC->PUPDR &= ~(3U << 2*13); + // configure Button (PC.13) pins as input, no pull-up, pull-down + GPIOC->MODER &= ~(3U << 2U*B1_PIN); + GPIOC->OSPEEDR &= ~(3U << 2U*B1_PIN); + GPIOC->OSPEEDR |= (1U << 2U*B1_PIN); + GPIOC->PUPDR &= ~(3U << 2U*B1_PIN); - BSP_randomSeed(1234U); /* seed the random number generator */ + BSP_randomSeed(1234U); // seed the random number generator - /* initialize the QS software tracing... */ - if (QS_INIT((void *)0) == 0U) { + // initialize the QS software tracing... + if (!QS_INIT((void *)0)) { Q_ERROR(); } - QS_OBJ_DICTIONARY(&l_SysTick_Handler); - QS_USR_DICTIONARY(PHILO_STAT); - /* setup the QS filters... */ - QS_GLB_FILTER(QS_ALL_RECORDS); - QS_GLB_FILTER(-QS_QF_TICK); + // dictionaries... + QS_OBJ_DICTIONARY(&l_SysTick_Handler); + QS_OBJ_DICTIONARY(&l_EXTI9_5_IRQHandler); + QS_USR_DICTIONARY(PHILO_STAT); + QS_USR_DICTIONARY(PAUSED_STAT); + QS_USR_DICTIONARY(CONTEXT_SW); + + QS_ONLY(produce_sig_dict()); + + // setup the QS filters... + QS_GLB_FILTER(QS_ALL_RECORDS); // all records + QS_GLB_FILTER(-QS_QF_TICK); // exclude the clock tick } -/*..........................................................................*/ +//............................................................................ +void BSP_start(void) { + // initialize event pools + static QF_MPOOL_EL(TableEvt) smlPoolSto[2*N_PHILO]; + QF_poolInit(smlPoolSto, sizeof(smlPoolSto), sizeof(smlPoolSto[0])); + + // initialize publish-subscribe + static QSubscrList subscrSto[MAX_PUB_SIG]; + QActive_psInit(subscrSto, Q_DIM(subscrSto)); + + // instantiate and start AOs/threads... + static QEvt const *xThread1QueueSto[5]; + static uint64_t xThread1StackSto[64]; + XThread1_ctor(); + QXTHREAD_START(TH_XThread1, + 1U, // QP priority of the thread + xThread1QueueSto, // event queue storage + Q_DIM(xThread1QueueSto), // event length [events] + xThread1StackSto, // stack storage + sizeof(xThread1StackSto), // stack size [bytes] + (void *)0); // no initialization param + + static QEvt const *philoQueueSto[N_PHILO][10]; + for (uint8_t n = 0U; n < N_PHILO; ++n) { + Philo_ctor(n); + QACTIVE_START(AO_Philo[n], + n + 3U, // QF-prio/pthre. see NOTE1 + philoQueueSto[n], // event queue storage + Q_DIM(philoQueueSto[n]), // queue length [events] + (void *)0, 0U, // no stack storage + (void *)0); // no initialization param + } + + static QEvt const *xThread2QueueSto[5]; + static uint64_t xThread2StackSto[64]; + XThread2_ctor(); + QXTHREAD_START(TH_XThread2, + N_PHILO + 5U, // QP priority of the thread + xThread2QueueSto, // event queue storage + Q_DIM(xThread2QueueSto), // event length [events] + xThread2StackSto, // stack storage + sizeof(xThread2StackSto), // stack size [bytes] + (void *)0); // no initialization param + + static QEvt const *tableQueueSto[N_PHILO]; + Table_ctor(); + QACTIVE_START(AO_Table, + N_PHILO + 7U, // QP prio. of the AO + tableQueueSto, // event queue storage + Q_DIM(tableQueueSto), // queue length [events] + (void *)0, 0U, // no stack storage + (void *)0); // no initialization param +} +//............................................................................ void BSP_displayPhilStat(uint8_t n, char const *stat) { + Q_UNUSED_PAR(n); + if (stat[0] == 'h') { - GPIOA->BSRRL |= LED_LD2; /* turn LED on */ + GPIOA->BSRRL = (1U << LD2_PIN); // turn LED on } else { - GPIOA->BSRRH |= LED_LD2; /* turn LED off */ + GPIOA->BSRRH = (1U << LD2_PIN); // turn LED off } - QS_BEGIN_ID(PHILO_STAT, AO_Philo[n]->prio) /* app-specific record */ - QS_U8(1, n); /* Philosopher number */ - QS_STR(stat); /* Philosopher status */ + // app-specific trace record... + QS_BEGIN_ID(PHILO_STAT, AO_Table->prio) + QS_U8(1, n); // Philosopher number + QS_STR(stat); // Philosopher status QS_END() } -/*..........................................................................*/ -void BSP_displayPaused(uint8_t paused) { - // not enough LEDs to show the "Paused" status +//............................................................................ +void BSP_displayPaused(uint8_t const paused) { + // not enough LEDs to implement this feature if (paused != 0U) { - //GPIOA->BSRRL |= LED_LD2; /* turn LED on */ + //GPIOA->BSRRL = (1U << LD2_PIN); // turn LED on } else { - //GPIOA->BSRRH |= LED_LD2; /* turn LED off */ + //GPIOA->BSRRH = (1U << LD2_PIN); // turn LED off } + + // application-specific trace record + QS_BEGIN_ID(PAUSED_STAT, AO_Table->prio) + QS_U8(1, paused); // Paused status + QS_END() } -/*..........................................................................*/ -uint32_t BSP_random(void) { /* a very cheap pseudo-random-number generator */ - /* "Super-Duper" Linear Congruential Generator (LCG) - * LCG(2^32, 3*7*11*13*23, 0, seed) - */ - l_rnd = l_rnd * (3U*7U*11U*13U*23U); - return l_rnd >> 8; -} -/*..........................................................................*/ +//............................................................................ void BSP_randomSeed(uint32_t seed) { - l_rnd = seed; + l_rndSeed = seed; } -/*..........................................................................*/ -void BSP_terminate(int16_t result) { - (void)result; +//............................................................................ +uint32_t BSP_random(void) { // a very cheap pseudo-random-number generator + + QSchedStatus lockStat = QXK_schedLock(N_PHILO); + // "Super-Duper" Linear Congruential Generator (LCG) + // LCG(2^32, 3*7*11*13*23, 0, seed) + // + uint32_t rnd = l_rndSeed * (3U*7U*11U*13U*23U); + l_rndSeed = rnd; // set for the next time + QXK_schedUnlock(lockStat); + + return (rnd >> 8U); } -/*..........................................................................*/ -void BSP_wait4SW1(void) { - while ((GPIOC->IDR & BTN_B1) != 0U) { - GPIOA->BSRRL |= LED_LD2; /* turn LED[n] on */ - GPIOA->BSRRH |= LED_LD2; /* turn LED[n] off */ - } -} -/*..........................................................................*/ +//............................................................................ void BSP_ledOn(void) { - //GPIOA->BSRL |= (LED_LD2); /* turn LED2 on */ + GPIOA->BSRRL = (1U << LD2_PIN); // turn LED on } -/*..........................................................................*/ +//............................................................................ void BSP_ledOff(void) { - //GPIOA->BSRRH |= LED_LD2; /* turn LED2 off */ + GPIOA->BSRRH = (1U << LD2_PIN); // turn LED off +} +//............................................................................ +void BSP_terminate(int16_t result) { + Q_UNUSED_PAR(result); } -/* QF callbacks ============================================================*/ +//============================================================================ +// QF callbacks... void QF_onStartup(void) { - /* set up the SysTick timer to fire at BSP_TICKS_PER_SEC rate */ + // set up the SysTick timer to fire at BSP_TICKS_PER_SEC rate SysTick_Config(SystemCoreClock / BSP_TICKS_PER_SEC); - /* set priorities of ALL ISRs used in the system, see NOTE00 - * - * !!!!!!!!!!!!!!!!!!!!!!!!!!!! CAUTION !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - * Assign a priority to EVERY ISR explicitly by calling NVIC_SetPriority(). - * DO NOT LEAVE THE ISR PRIORITIES AT THE DEFAULT VALUE! - */ - NVIC_SetPriority(SysTick_IRQn, QF_AWARE_ISR_CMSIS_PRI + 1); - NVIC_SetPriority(USART2_IRQn, 0); /* kernel UNAWARE interrupt */ - /* ... */ + // assign all priority bits for preemption-prio. and none to sub-prio. + // NOTE: this might have been changed by STM32Cube. + NVIC_SetPriorityGrouping(0U); + + // set priorities of ALL ISRs used in the system, see NOTE1 + NVIC_SetPriority(USART2_IRQn, 0U); // kernel UNAWARE interrupt + NVIC_SetPriority(EXTI9_5_IRQn, QF_AWARE_ISR_CMSIS_PRI + 0U); + NVIC_SetPriority(SysTick_IRQn, QF_AWARE_ISR_CMSIS_PRI + 1U); + // ... + + // enable IRQs... + NVIC_EnableIRQ(EXTI9_5_IRQn); - /* enable IRQs... */ #ifdef Q_SPY - NVIC_EnableIRQ(USART2_IRQn); /* UART2 interrupt used for QS-RX */ + NVIC_EnableIRQ(USART2_IRQn); // UART2 interrupt used for QS-RX #endif } -/*..........................................................................*/ +//............................................................................ void QF_onCleanup(void) { } -/*..........................................................................*/ -void QXK_onIdle(void) { /* called with interrupts enabled */ - - /* toggle an LED on and then off (not enough LEDs, see NOTE01) */ - QF_INT_DISABLE(); - //GPIOA->BSRRL |= LED_LD2; /* turn LED[n] on */ - //GPIOA->BSRRH |= LED_LD2; /* turn LED[n] off */ - QF_INT_ENABLE(); +//............................................................................ +void QXK_onIdle(void) { + // toggle an LED on and then off (not enough LEDs, see NOTE02) + //QF_INT_DISABLE(); + //GPIOA->BSRRL = (1U << LD2_PIN); // turn LED[n] on + //GPIOA->BSRRH = (1U << LD2_PIN); // turn LED[n] off + //QF_INT_ENABLE(); #ifdef Q_SPY - QS_rxParse(); /* parse all the received bytes */ - - if ((USART2->SR & (1U << 7)) != 0) { /* is TXE empty? */ - uint16_t b; + QF_INT_DISABLE(); + QS_rxParse(); // parse all the received bytes + QF_INT_ENABLE(); + if ((USART2->SR & (1U << 7U)) != 0U) { // is TXE empty? QF_INT_DISABLE(); - b = QS_getByte(); + uint16_t b = QS_getByte(); QF_INT_ENABLE(); - if (b != QS_EOD) { /* not End-Of-Data? */ - USART2->DR = (b & 0xFFU); /* put into the DR register */ + if (b != QS_EOD) { // not End-Of-Data? + USART2->DR = b; // put into the DR register } } #elif defined NDEBUG - /* Put the CPU and peripherals to the low-power mode. - * you might need to customize the clock management for your application, - * see the datasheet for your particular Cortex-M MCU. - */ - /* !!!CAUTION!!! - * The WFI instruction stops the CPU clock, which unfortunately disables - * the JTAG port, so the ST-Link debugger can no longer connect to the - * board. For that reason, the call to __WFI() has to be used with CAUTION. - * - * NOTE: If you find your board "frozen" like this, strap BOOT0 to VDD and - * reset the board, then connect with ST-Link Utilities and erase the part. - * The trick with BOOT(0) is it gets the part to run the System Loader - * instead of your broken code. When done disconnect BOOT0, and start over. - */ - //__WFI(); /* Wait-For-Interrupt */ + // Put the CPU and peripherals to the low-power mode. + // you might need to customize the clock management for your application, + // see the datasheet for your particular Cortex-M MCU. + // + // !!!CAUTION!!! + // The WFI instruction stops the CPU clock, which unfortunately disables + // the JTAG port, so the ST-Link debugger can no longer connect to the + // board. For that reason, the call to __WFI() has to be used with CAUTION. + // + // NOTE: If you find your board "frozen" like this, strap BOOT0 to VDD and + // reset the board, then connect with ST-Link Utilities and erase the part. + // The trick with BOOT(0) is it gets the part to run the System Loader + // instead of your broken code. When done disconnect BOOT0, and start over. + // + //__WFI(); // Wait-For-Interrupt #endif } -/*..........................................................................*/ -Q_NORETURN Q_onAssert(char const * const module, int_t const loc) { - /* - * NOTE: add here your application-specific error handling - */ - (void)module; - (void)loc; - QS_ASSERTION(module, loc, 10000U); /* report assertion to QS */ - -#ifndef NDEBUG - BSP_wait4SW1(); -#endif - NVIC_SystemReset(); -} - -/* QS callbacks ============================================================*/ +//============================================================================ +// QS callbacks... #ifdef Q_SPY -/*..........................................................................*/ + +//............................................................................ #define __DIV(__PCLK, __BAUD) (((__PCLK / 4) *25)/(__BAUD)) #define __DIVMANT(__PCLK, __BAUD) (__DIV(__PCLK, __BAUD)/100) #define __DIVFRAQ(__PCLK, __BAUD) \ @@ -310,102 +432,120 @@ Q_NORETURN Q_onAssert(char const * const module, int_t const loc) { #define __USART_BRR(__PCLK, __BAUD) \ ((__DIVMANT(__PCLK, __BAUD) << 4)|(__DIVFRAQ(__PCLK, __BAUD) & 0x0F)) -/*..........................................................................*/ +// USART2 pins PA.2 and PA.3 +#define USART2_TX_PIN 2U +#define USART2_RX_PIN 3U + +//............................................................................ uint8_t QS_onStartup(void const *arg) { - static uint8_t qsBuf[2*1024]; /* buffer for Quantum Spy */ - static uint8_t qsRxBuf[128]; /* buffer for QS-RX channel */ + Q_UNUSED_PAR(arg); - (void)arg; /* avoid the "unused parameter" compiler warning */ + static uint8_t qsTxBuf[2*1024]; // buffer for QS-TX channel + QS_initBuf(qsTxBuf, sizeof(qsTxBuf)); - QS_initBuf(qsBuf, sizeof(qsBuf)); + static uint8_t qsRxBuf[100]; // buffer for QS-RX channel QS_rxInitBuf(qsRxBuf, sizeof(qsRxBuf)); - /* enable peripheral clock for USART2 */ - RCC->AHBENR |= (1U << 0); /* Enable GPIOA clock */ - RCC->APB1ENR |= (1U << 17); /* Enable USART#2 clock */ + // enable peripheral clock for USART2 + RCC->AHBENR |= ( 1U << 0U); // Enable GPIOA clock + RCC->APB1ENR |= ( 1U << 17U); // Enable USART#2 clock - /* Configure PA3 to USART2_RX, PA2 to USART2_TX */ - GPIOA->AFR[0] &= ~((15U << 4*3) | (15U << 4*2)); - GPIOA->AFR[0] |= (( 7U << 4*3) | ( 7U << 4*2)); - GPIOA->MODER &= ~(( 3U << 2*3) | ( 3U << 2*2)); - GPIOA->MODER |= (( 2U << 2*3) | ( 2U << 2*2)); + // Configure PA3 to USART2_RX, PA2 to USART2_TX + GPIOA->AFR[0] &= ~((15U << 4U*USART2_RX_PIN) | (15U << 4U*USART2_TX_PIN)); + GPIOA->AFR[0] |= (( 7U << 4U*USART2_RX_PIN) | ( 7U << 4U*USART2_TX_PIN)); + GPIOA->MODER &= ~(( 3U << 2U*USART2_RX_PIN) | ( 3U << 2U*USART2_TX_PIN)); + GPIOA->MODER |= (( 2U << 2U*USART2_RX_PIN) | ( 2U << 2U*USART2_TX_PIN)); - USART2->BRR = __USART_BRR(SystemCoreClock, 115200U); /* baud rate */ - USART2->CR3 = 0x0000U; /* no flow control */ - USART2->CR2 = 0x0000U; /* 1 stop bit */ - USART2->CR1 = ((1U << 2) | /* enable RX */ - (1U << 3) | /* enable TX */ - (1U << 5) | /* enable RX interrupt */ - (0U << 12) | /* 1 start bit, 8 data bits */ - (1U << 13)); /* enable USART */ + USART2->BRR = __USART_BRR(SystemCoreClock, 115200U); // baud rate + USART2->CR3 = 0x0000U; // no flow control + USART2->CR2 = 0x0000U; // 1 stop bit + USART2->CR1 = ((1U << 2U) | // enable RX + (1U << 3U) | // enable TX + (1U << 5U) | // enable RX interrupt + (0U << 12U) | // 8 data bits + (0U << 28U) | // 8 data bits + (1U << 13U)); // enable USART - return 1U; /* return success */ + QS_tickPeriod_ = SystemCoreClock / BSP_TICKS_PER_SEC; + QS_tickTime_ = QS_tickPeriod_; // to start the timestamp at zero + + return 1U; // return success } -/*..........................................................................*/ +//............................................................................ void QS_onCleanup(void) { } -/*..........................................................................*/ -QSTimeCtr QS_onGetTime(void) { /* NOTE: invoked with interrupts DISABLED */ - if ((SysTick->CTRL & 0x00010000) == 0) { /* COUNT no set? */ +//............................................................................ +QSTimeCtr QS_onGetTime(void) { // NOTE: invoked with interrupts DISABLED + if ((SysTick->CTRL & 0x00010000) == 0) { // COUNT no set? return QS_tickTime_ - (QSTimeCtr)SysTick->VAL; } - else { /* the rollover occured, but the SysTick_ISR did not run yet */ + else { // the rollover occured, but the SysTick_ISR did not run yet return QS_tickTime_ + QS_tickPeriod_ - (QSTimeCtr)SysTick->VAL; } } -/*..........................................................................*/ +//............................................................................ void QS_onFlush(void) { - uint16_t b; - - QF_INT_DISABLE(); - while ((b = QS_getByte()) != QS_EOD) { /* while not End-Of-Data... */ - QF_INT_ENABLE(); - while ((USART2->SR & (1U << 7)) == 0U) { /* while TXE not empty */ - } - USART2->DR = (b & 0xFFU); /* put into the DR register */ + for (;;) { QF_INT_DISABLE(); + uint16_t b = QS_getByte(); + if (b != QS_EOD) { + while ((USART2->SR & (1U << 7U)) == 0U) { // while TXE not empty + QF_INT_ENABLE(); + QF_CRIT_EXIT_NOP(); + + QF_INT_DISABLE(); + } + USART2->DR = b; // put into the DR register + QF_INT_ENABLE(); + } + else { + QF_INT_ENABLE(); + break; + } } - QF_INT_ENABLE(); } -/*..........................................................................*/ -/*! callback function to reset the target (to be implemented in the BSP) */ +//............................................................................ +//! callback function to reset the target (to be implemented in the BSP) void QS_onReset(void) { NVIC_SystemReset(); } -/*..........................................................................*/ -/*! callback function to execute a user command (to be implemented in BSP) */ +//............................................................................ +//! callback function to execute a user command void QS_onCommand(uint8_t cmdId, uint32_t param1, uint32_t param2, uint32_t param3) { - (void)cmdId; - (void)param1; - (void)param2; - (void)param3; + Q_UNUSED_PAR(cmdId); + Q_UNUSED_PAR(param1); + Q_UNUSED_PAR(param2); + Q_UNUSED_PAR(param3); } -#endif /* Q_SPY */ -/*--------------------------------------------------------------------------*/ +#endif // Q_SPY +//---------------------------------------------------------------------------- -/***************************************************************************** -* NOTE00: -* The QF_AWARE_ISR_CMSIS_PRI constant from the QF port specifies the highest -* ISR priority that is disabled by the QF framework. The value is suitable -* for the NVIC_SetPriority() CMSIS function. -* -* Only ISRs prioritized at or below the QF_AWARE_ISR_CMSIS_PRI level (i.e., -* with the numerical values of priorities equal or higher than -* QF_AWARE_ISR_CMSIS_PRI) are allowed to call any QF services. These ISRs -* are "QF-aware". -* -* Conversely, any ISRs prioritized above the QF_AWARE_ISR_CMSIS_PRI priority -* level (i.e., with the numerical values of priorities less than -* QF_AWARE_ISR_CMSIS_PRI) are never disabled and are not aware of the kernel. -* Such "QF-unaware" ISRs cannot call any QF services. The only mechanism -* by which a "QF-unaware" ISR can communicate with the QF framework is by -* triggering a "QF-aware" ISR, which can post/publish events. -* -* NOTE01: -* Usually, one of the LEDs is used to visualize the idle loop activity. -* However, the board has not enough LEDs (only one, actually), so this -* feature is disabled. -*/ +//============================================================================ +// NOTE1: +// The QF_AWARE_ISR_CMSIS_PRI constant from the QF port specifies the highest +// ISR priority that is disabled by the QF framework. The value is suitable +// for the NVIC_SetPriority() CMSIS function. +// +// Only ISRs prioritized at or below the QF_AWARE_ISR_CMSIS_PRI level (i.e., +// with the numerical values of priorities equal or higher than +// QF_AWARE_ISR_CMSIS_PRI) are allowed to call the QK_ISR_ENTRY/ +// QXK_ISR_ENTRY macros or any other QF/QXK services. These ISRs are +// "QF-aware". +// +// Conversely, any ISRs prioritized above the QF_AWARE_ISR_CMSIS_PRI priority +// level (i.e., with the numerical values of priorities less than +// QF_AWARE_ISR_CMSIS_PRI) are never disabled and are not aware of the kernel. +// Such "QF-unaware" ISRs cannot call ANY QF/QXK services. In particular they +// can NOT call the macros QXK_ISR_ENTRY/QXK_ISR_ENTRY. The only mechanism +// by which a "QF-unaware" ISR can communicate with the QF framework is by +// triggering a "QF-aware" ISR, which can post/publish events. +// +// NOTE2: +// The User LED is used to visualize the idle loop activity. The brightness +// of the LED is proportional to the frequency of the idle loop. +// Please note that the LED is toggled with interrupts locked, so no interrupt +// execution time contributes to the brightness of the User LED. +// diff --git a/examples/arm-cm/dpp_nucleo-l152re/qxk/gnu/Makefile b/examples/arm-cm/dpp_nucleo-l152re/qxk/gnu/Makefile index b74c7294..b266d288 100644 --- a/examples/arm-cm/dpp_nucleo-l152re/qxk/gnu/Makefile +++ b/examples/arm-cm/dpp_nucleo-l152re/qxk/gnu/Makefile @@ -97,7 +97,8 @@ C_SRCS := \ main.c \ philo.c \ table.c \ - test.c \ + xthread1.c \ + xthread2.c \ system_stm32l1xx.c \ startup_stm32l1xx.c @@ -137,7 +138,8 @@ LIB_DIRS := LIBS := # defines -DEFINES := +DEFINES := \ + -DQF_ON_CONTEXT_SW # ARM CPU, ARCH, FPU, and Float-ABI types... # ARM_CPU: [cortex-m0 | cortex-m0plus | cortex-m1 | cortex-m3 | cortex-m4] @@ -265,7 +267,7 @@ $(TARGET_BIN): $(TARGET_ELF) $(BIN) -O binary $< $@ $(TARGET_ELF) : $(ASM_OBJS_EXT) $(C_OBJS_EXT) $(CPP_OBJS_EXT) - $(CC) $(CFLAGS) $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o + $(CC) $(CFLAGS) $(QPC)/src/qs/qstamp.c -o $(BIN_DIR)/qstamp.o $(LINK) $(LINKFLAGS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) $(BIN_DIR)/%.d : %.c diff --git a/examples/arm-cm/dpp_nucleo-l152re/qxk/gnu/dpp-qxk.ld b/examples/arm-cm/dpp_nucleo-l152re/qxk/gnu/dpp-qxk.ld index b3a6ec97..349f5dc6 100644 --- a/examples/arm-cm/dpp_nucleo-l152re/qxk/gnu/dpp-qxk.ld +++ b/examples/arm-cm/dpp_nucleo-l152re/qxk/gnu/dpp-qxk.ld @@ -91,8 +91,9 @@ SECTIONS { .stack : { __stack_start__ = .; . = . + STACK_SIZE; - . = ALIGN(4); + . = ALIGN(8); __stack_end__ = .; + ASSERT(((. - __stack_start__) == STACK_SIZE), "Error: Stack misaligned"); } >RAM .data : AT (_etext) { diff --git a/examples/arm-cm/dpp_nucleo-l152re/qxk/iar/dpp-qxk.ewd b/examples/arm-cm/dpp_nucleo-l152re/qxk/iar/dpp-qxk.ewd index fe187d7a..9a99484e 100644 --- a/examples/arm-cm/dpp_nucleo-l152re/qxk/iar/dpp-qxk.ewd +++ b/examples/arm-cm/dpp_nucleo-l152re/qxk/iar/dpp-qxk.ewd @@ -11,7 +11,7 @@ C-SPY 2 - 29 + 32 1 1 - - + + + + @@ -490,7 +498,7 @@ IJET_ID 2 - 8 + 9 1 1 + + + + + + + + + + + + + @@ -920,7 +980,7 @@ LMIFTDI_ID 2 - 2 + 3 1 1 + + + + + + + NULINK_ID + 2 + + 0 + 1 + 1 + + + @@ -978,7 +1072,7 @@ STLINK_ID 2 - 4 + 8 1 1 + + + + @@ -1189,7 +1300,7 @@ XDS100_ID 2 - 6 + 9 1 1 + + + + @@ -1366,10 +1493,18 @@ $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin 0 + + $TOOLKIT_DIR$\plugins\rtos\FreeRtos\FreeRtosArmPlugin.ENU.ewplugin + 0 + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin.ENU.ewplugin 0 + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin2.ENU.ewplugin + 0 + $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin 0 @@ -1379,11 +1514,15 @@ 0 - $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9.ewplugin 0 - $TOOLKIT_DIR$\plugins\rtos\TI-RTOS\tirtosplugin.ewplugin + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9BE.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin 0 @@ -1398,10 +1537,6 @@ $TOOLKIT_DIR$\plugins\rtos\uCOS-III\uCOS-III-KA-CSpy.ewplugin 0 - - $EW_DIR$\common\plugins\CodeCoverage\CodeCoverage.ENU.ewplugin - 1 - $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin 0 @@ -1426,7 +1561,7 @@ C-SPY 2 - 29 + 32 1 0 - - + + + + @@ -1905,7 +2048,7 @@ IJET_ID 2 - 8 + 9 1 0 + + + + + + + + + + + + + @@ -2335,7 +2530,7 @@ LMIFTDI_ID 2 - 2 + 3 1 0 + + + + + + + NULINK_ID + 2 + + 0 + 1 + 0 + + + @@ -2393,7 +2622,7 @@ STLINK_ID 2 - 4 + 8 1 0 + + + + @@ -2604,7 +2850,7 @@ XDS100_ID 2 - 6 + 9 1 0 + + + + @@ -2781,10 +3043,18 @@ $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin 0 + + $TOOLKIT_DIR$\plugins\rtos\FreeRtos\FreeRtosArmPlugin.ENU.ewplugin + 0 + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin.ENU.ewplugin 0 + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin2.ENU.ewplugin + 0 + $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin 0 @@ -2794,11 +3064,15 @@ 0 - $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9.ewplugin 0 - $TOOLKIT_DIR$\plugins\rtos\TI-RTOS\tirtosplugin.ewplugin + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9BE.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin 0 @@ -2813,10 +3087,6 @@ $TOOLKIT_DIR$\plugins\rtos\uCOS-III\uCOS-III-KA-CSpy.ewplugin 0 - - $EW_DIR$\common\plugins\CodeCoverage\CodeCoverage.ENU.ewplugin - 1 - $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin 0 @@ -2841,7 +3111,7 @@ C-SPY 2 - 29 + 32 1 1 - - + + + + @@ -3320,7 +3598,7 @@ IJET_ID 2 - 8 + 9 1 1 + + + + + + + + + + + + + @@ -3750,7 +4080,7 @@ LMIFTDI_ID 2 - 2 + 3 1 1 + + + + + + + NULINK_ID + 2 + + 0 + 1 + 1 + + + @@ -3808,7 +4172,7 @@ STLINK_ID 2 - 4 + 8 1 1 + + + + @@ -4019,7 +4400,7 @@ XDS100_ID 2 - 6 + 9 1 1 + + + + @@ -4196,10 +4593,18 @@ $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin 0 + + $TOOLKIT_DIR$\plugins\rtos\FreeRtos\FreeRtosArmPlugin.ENU.ewplugin + 0 + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin.ENU.ewplugin 0 + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin2.ENU.ewplugin + 0 + $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin 0 @@ -4209,11 +4614,15 @@ 0 - $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9.ewplugin 0 - $TOOLKIT_DIR$\plugins\rtos\TI-RTOS\tirtosplugin.ewplugin + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9BE.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin 0 @@ -4228,10 +4637,6 @@ $TOOLKIT_DIR$\plugins\rtos\uCOS-III\uCOS-III-KA-CSpy.ewplugin 0 - - $EW_DIR$\common\plugins\CodeCoverage\CodeCoverage.ENU.ewplugin - 1 - $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin 0 diff --git a/examples/arm-cm/dpp_nucleo-l152re/qxk/iar/dpp-qxk.ewp b/examples/arm-cm/dpp_nucleo-l152re/qxk/iar/dpp-qxk.ewp index 8f3f3532..ee0bd354 100644 --- a/examples/arm-cm/dpp_nucleo-l152re/qxk/iar/dpp-qxk.ewp +++ b/examples/arm-cm/dpp_nucleo-l152re/qxk/iar/dpp-qxk.ewp @@ -11,9 +11,13 @@ General 3 - 31 + 35 1 1 + - - - - - + + + + + ICCARM 2 - 35 + 37 1 1 - - - + AARM 2 - 10 + 11 1 1 + @@ -672,13 +668,9 @@ 0 + inputOutputBased - - BICOMP - 0 - - BUILDACTION 1 @@ -691,17 +683,13 @@ ILINK 0 - 23 + 27 1 1 - + + + + + + + + + @@ -1050,11 +1074,6 @@ - - BILINK - 0 - - Coder 0 @@ -1071,9 +1090,13 @@ General 3 - 31 + 35 1 0 + - - - - - + + + + + ICCARM 2 - 35 + 37 1 0 - - - + AARM 2 - 10 + 11 1 0 + @@ -1732,13 +1747,9 @@ 0 + inputOutputBased - - BICOMP - 0 - - BUILDACTION 1 @@ -1751,17 +1762,13 @@ ILINK 0 - 23 + 27 1 0 - + + + + + + + + + @@ -2110,11 +2153,6 @@ - - BILINK - 0 - - Coder 0 @@ -2131,9 +2169,13 @@ General 3 - 31 + 35 1 1 + - - - - - + + + + + ICCARM 2 - 35 + 37 1 1 - - - + AARM 2 - 10 + 11 1 1 + @@ -2792,13 +2827,9 @@ 0 + inputOutputBased - - BICOMP - 0 - - BUILDACTION 1 @@ -2811,17 +2842,13 @@ ILINK 0 - 23 + 27 1 1 - + + + + + + + + + @@ -3170,11 +3233,6 @@ - - BILINK - 0 - - Coder 0 @@ -3193,19 +3251,19 @@ $PROJ_DIR$\..\..\dpp.h - $PROJ_DIR$\..\main.c + $PROJ_DIR$\..\..\main.c $PROJ_DIR$\..\..\philo.c - - $PROJ_DIR$\..\..\..\..\..\include\qstamp.c - $PROJ_DIR$\..\..\table.c - $PROJ_DIR$\..\test.c + $PROJ_DIR$\..\xthread1.c + + + $PROJ_DIR$\..\xthread2.c @@ -3282,21 +3340,9 @@ QP_port - - $PROJ_DIR$\..\..\..\..\..\ports\arm-cm\qxk\iar\qep_port.h - - - $PROJ_DIR$\..\..\..\..\..\ports\arm-cm\qxk\iar\qf_port.h - - - $PROJ_DIR$\..\..\..\..\..\ports\arm-cm\qxk\iar\qs_port.h - $PROJ_DIR$\..\..\..\..\..\ports\arm-cm\qxk\iar\qxk_port.c - - $PROJ_DIR$\..\..\..\..\..\ports\arm-cm\qxk\iar\qxk_port.h - QS @@ -3313,5 +3359,8 @@ $PROJ_DIR$\..\..\..\..\..\src\qs\qs_rx.c + + $PROJ_DIR$\..\..\..\..\..\src\qs\qstamp.c + diff --git a/examples/arm-cm/dpp_nucleo-l152re/qxk/main.c b/examples/arm-cm/dpp_nucleo-l152re/qxk/main.c deleted file mode 100644 index 38b517bf..00000000 --- a/examples/arm-cm/dpp_nucleo-l152re/qxk/main.c +++ /dev/null @@ -1,131 +0,0 @@ -/***************************************************************************** -* Product: DPP example extened for QXK -* Last updated for version 7.1.0 -* Last updated on 2022-08-28 -* -* Q u a n t u m L e a P s -* ------------------------ -* Modern Embedded Software -* -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* -* -*****************************************************************************/ -#include "qpc.h" -#include "dpp.h" -#include "bsp.h" - -Q_DEFINE_THIS_FILE - -static QTicker l_ticker0; -QActive *the_Ticker0 = &l_ticker0.super; - -/*..........................................................................*/ -int main() { - static QEvt const *tableQueueSto[N_PHILO]; - static QEvt const *philoQueueSto[N_PHILO][N_PHILO]; - static QSubscrList subscrSto[MAX_PUB_SIG]; - static QF_MPOOL_EL(TableEvt) smlPoolSto[2*N_PHILO]; /* small pool */ - - /* stacks and queues for the extended test threads */ - static void const *test1QueueSto[5]; - static uint64_t test1StackSto[64]; - static void const *test2QueueSto[5]; - static uint64_t test2StackSto[64]; - - uint8_t n; - - Philo_ctor(); /* instantiate all Philosopher active objects */ - Table_ctor(); /* instantiate the Table active object */ - QTicker_ctor(&l_ticker0, 0U); /* ticker AO for tick rate 0 */ - Test1_ctor(); /* instantiate the Test1 extended thread */ - Test2_ctor(); /* instantiate the Test2 extended thread */ - - QF_init(); /* initialize the framework and the underlying RT kernel */ - - /* initialize publish-subscribe... */ - QF_psInit(subscrSto, Q_DIM(subscrSto)); - - /* initialize event pools... */ - QF_poolInit(smlPoolSto, sizeof(smlPoolSto), sizeof(smlPoolSto[0])); - - /* initialize the Board Support Package - * NOTE: BSP_init() is called *after* initializing publish-subscribe and - * event pools, to make the system ready to accept SysTick interrupts. - * Unfortunately, the STM32Cube code that must be called from BSP, - * configures and starts SysTick. - */ - BSP_init(); - - /* object dictionaries... */ - QS_OBJ_DICTIONARY(&l_ticker0); - - /* start the extended thread */ - QXTHREAD_START(XT_Test1, /* Thread to start */ - 1U, /* QP priority of the thread */ - test1QueueSto, /* message queue storage */ - Q_DIM(test1QueueSto), /* message length [events] */ - test1StackSto, /* stack storage */ - sizeof(test1StackSto), /* stack size [bytes] */ - (void *)0); /* initialization param */ - - /* NOTE: leave priority 2 free for a mutex */ - - /* start the Philo active objects... */ - for (n = 0U; n < N_PHILO; ++n) { - QACTIVE_START(AO_Philo[n], /* AO to start */ - n + 3U, /* QP priority of the AO */ - philoQueueSto[n], /* event queue storage */ - Q_DIM(philoQueueSto[n]), /* queue length [events] */ - (void *)0, /* stack storage (not used) */ - 0U, /* size of the stack [bytes] */ - (void *)0); /* initialization param */ - } - - /* example of prioritizing the Ticker0 active object */ - QACTIVE_START(the_Ticker0, N_PHILO + 3U, - 0, 0, 0, 0, 0); - - /* NOTE: leave priority (N_PHILO + 4) free for mutex */ - - QXTHREAD_START(XT_Test2, /* Thread to start */ - N_PHILO + 5U, /* QP priority of the thread */ - test2QueueSto, /* message queue storage */ - Q_DIM(test2QueueSto), /* message length [events] */ - test2StackSto, /* stack storage */ - sizeof(test2StackSto), /* stack size [bytes] */ - (void *)0); /* initialization param */ - - /* NOTE: leave priority (N_PHILO + 6) free for mutex */ - - QACTIVE_START(AO_Table, /* AO to start */ - N_PHILO + 7U, /* QP priority of the AO */ - tableQueueSto, /* event queue storage */ - Q_DIM(tableQueueSto), /* queue length [events] */ - (void *)0, /* stack storage (not used) */ - 0U, /* size of the stack [bytes] */ - (void *)0); /* initialization param */ - - return QF_run(); /* run the QF application */ -} - diff --git a/examples/arm-cm/dpp_nucleo-l152re/qxk/test.c b/examples/arm-cm/dpp_nucleo-l152re/qxk/test.c deleted file mode 100644 index 487288ef..00000000 --- a/examples/arm-cm/dpp_nucleo-l152re/qxk/test.c +++ /dev/null @@ -1,140 +0,0 @@ -/***************************************************************************** -* Product: DPP example -* Last updated for version 6.7.0 -* Last updated on 2019-12-27 -* -* Q u a n t u m L e a P s -* ------------------------ -* Modern Embedded Software -* -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* -* -*****************************************************************************/ -#include "qpc.h" -#include "dpp.h" -#include "bsp.h" - -/* local "extended" thread object ..........................................*/ -static QXThread l_test1; -static QXThread l_test2; -static QXMutex l_mutex; -static QXSemaphore l_sema; - -/* Thread-Local Storage for the "extended" threads .........................*/ -typedef struct { - uint32_t foo; - uint8_t bar[10]; -} TLS_test; -static TLS_test l_tls1; -static TLS_test l_tls2; - -static void lib_fun(uint32_t x) { - QXK_TLS(TLS_test *)->foo = x; -} - -/* global pointer to the test thread .......................................*/ -QXThread * const XT_Test1 = &l_test1; -QXThread * const XT_Test2 = &l_test2; - -/*..........................................................................*/ -static void Thread1_run(QXThread * const me) { - - QS_OBJ_DICTIONARY(&l_test1); - - me->super.thread = &l_tls1; /* initialize the TLS for Thread1 */ - - for (;;) { - QXMutex_lock(&l_mutex, QXTHREAD_NO_TIMEOUT); /* lock the mutex */ - BSP_ledOn(); - - if (QXMutex_tryLock(&l_mutex)) { /* exercise the mutex */ - (void)QXSemaphore_signal(&l_sema); /* signal Thread2 */ - - QXThread_delay(10U); /* BLOCK while holding a mutex */ - - QXMutex_unlock(&l_mutex); - } - - QXMutex_unlock(&l_mutex); - BSP_ledOff(); - - QXThread_delay(BSP_TICKS_PER_SEC/7); /* BLOCK */ - - /* publish to thread2 */ - //QACTIVE_PUBLISH(Q_NEW(QEvt, TEST_SIG), &l_test1.super); - - /* test TLS */ - lib_fun(1U); - } -} - -/*..........................................................................*/ -void Test1_ctor(void) { - QXThread_ctor(&l_test1, &Thread1_run, 0U); -} - -/*..........................................................................*/ -static void Thread2_run(QXThread * const me) { - - QS_OBJ_DICTIONARY(&l_test2); - - /* initialize the semaphore before using it - * NOTE: the semaphore is initialized in the highest-priority thread - * that uses it. Alternatively, the semaphore can be initialized - * before any thread runs. - */ - QXSemaphore_init(&l_sema, - 0U, /* count==0 (signaling semaphore) */ - 1U); /* max_count==1 (binary semaphore) */ - - /* initialize the mutex before using it - * NOTE: Here the mutex is initialized in the highest-priority thread - * that uses it. Alternatively, the mutex can be initialized - * before any thread runs. - */ - //QXMutex_init(&l_mutex, 0U); /* priority-ceiling NOT used */ - QXMutex_init(&l_mutex, N_PHILO + 6U); /*priority-ceiling protocol used*/ - - me->super.thread = &l_tls2; /* initialize the TLS for Thread2 */ - - /* subscribe to the test signal */ - QActive_subscribe(&me->super, TEST_SIG); - - for (;;) { - /* wait on a semaphore (BLOCK indefinitely) */ - QXSemaphore_wait(&l_sema, QXTHREAD_NO_TIMEOUT); - - QXMutex_lock(&l_mutex, QXTHREAD_NO_TIMEOUT); /* lock the mutex */ - QXThread_delay(1U); /* wait more (BLOCK) */ - QXMutex_unlock(&l_mutex); - - /* test TLS */ - lib_fun(2U); - } -} - -/*..........................................................................*/ -void Test2_ctor(void) { - QXThread_ctor(&l_test2, &Thread2_run, 0U); -} diff --git a/examples/arm-cm/dpp_nucleo-l152re/qxk/xthread1.c b/examples/arm-cm/dpp_nucleo-l152re/qxk/xthread1.c new file mode 100644 index 00000000..066b983d --- /dev/null +++ b/examples/arm-cm/dpp_nucleo-l152re/qxk/xthread1.c @@ -0,0 +1,101 @@ +//============================================================================ +// QXThread example +// Last updated for version 7.3.0 +// Last updated on 2023-08-12 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. +// +// This program is open source software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Alternatively, this program may be distributed and modified under the +// terms of Quantum Leaps commercial licenses, which expressly supersede +// the GNU General Public License and are specifically designed for +// licensees interested in retaining the proprietary status of their code. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Contact information: +// +// +//============================================================================ +#include "qpc.h" // QP/C real-time embedded framework +#include "dpp.h" // DPP Application interface +#include "bsp.h" // Board Support Package + +//---------------------------------------------------------------------------- +//Q_DEFINE_THIS_FILE + +//............................................................................ +typedef struct XThread1 { +// protected: + QXThread super; + +// private: + // NOTE: data needed by this thread should be members of + // the thread class. That way they are in the memory region + // accessible from this thread. + uint8_t foo; + +// public: +} XThread1; + +// private: +static void XThread1_run(QXThread * const thr); +extern XThread1 XThread1_inst; + +//............................................................................ +QXThread * const TH_XThread1 = &XThread1_inst.super; + +//............................................................................ +void XThread1_ctor(void) { + XThread1 *me = &XThread1_inst; + QXThread_ctor(&me->super, &XThread1_run, 0U); +} + +//............................................................................ +XThread1 XThread1_inst; + +//............................................................................ +static void XThread1_run(QXThread * const thr) { + QS_OBJ_DICTIONARY(TH_XThread1); + QS_OBJ_DICTIONARY(&TH_XThread1->timeEvt); + + // downcast the generic thr pointer to the specific thread + XThread1 *me = (XThread1 *)thr; + + // subscribe to the EAT signal (from the application) + QActive_subscribe(&me->super.super, EAT_SIG); + + for (;;) { + QEvt const *e = QXThread_queueGet(BSP_TICKS_PER_SEC/4U); + if (e) { + QXSemaphore_signal(&TH_sema); // signal Thread2 + QF_gc(e); // must explicitly recycle the received event! + } + + QXMutex_lock(&TH_mutex, QXTHREAD_NO_TIMEOUT); // lock the mutex + BSP_ledOn(); + if (QXMutex_tryLock(&TH_mutex)) { // exercise the mutex + // some floating point code to exercise the VFP... + float volatile x = 1.4142135F; + x = x * 1.4142135F; + QXThread_delay(10U); // BLOCK while holding a mutex + QXMutex_unlock(&TH_mutex); + } + QXMutex_unlock(&TH_mutex); + BSP_ledOff(); + } +} diff --git a/examples/arm-cm/dpp_nucleo-l152re/qxk/xthread2.c b/examples/arm-cm/dpp_nucleo-l152re/qxk/xthread2.c new file mode 100644 index 00000000..1caad4fa --- /dev/null +++ b/examples/arm-cm/dpp_nucleo-l152re/qxk/xthread2.c @@ -0,0 +1,108 @@ +//============================================================================ +// QXThread example +// Last updated for version 7.3.0 +// Last updated on 2023-08-12 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. +// +// This program is open source software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Alternatively, this program may be distributed and modified under the +// terms of Quantum Leaps commercial licenses, which expressly supersede +// the GNU General Public License and are specifically designed for +// licensees interested in retaining the proprietary status of their code. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Contact information: +// +// +//============================================================================ +#include "qpc.h" // QP/C real-time embedded framework +#include "dpp.h" // DPP Application interface +#include "bsp.h" // Board Support Package + +//---------------------------------------------------------------------------- +//Q_DEFINE_THIS_FILE + +//---------------------------------------------------------------------------- +QXSemaphore TH_sema; +QXMutex TH_mutex; + +//---------------------------------------------------------------------------- +typedef struct XThread2 { +// protected: + QXThread super; + +// private: + // NOTE: data needed by this thread should be members of + // the thread class. That way they are in the memory region + // accessible from this thread. + uint8_t foo; + +// public: +} XThread2; + +// private: +static void XThread2_run(QXThread * const thr); +extern XThread2 XThread2_inst; + +//............................................................................ +QXThread * const TH_XThread2 = &XThread2_inst.super; + +//............................................................................ +void XThread2_ctor(void) { + XThread2 *me = &XThread2_inst; + QXThread_ctor(&me->super, &XThread2_run, 0U); +} + +//............................................................................ +XThread2 XThread2_inst; + +//............................................................................ +static void XThread2_run(QXThread * const thr) { + QS_OBJ_DICTIONARY(TH_XThread2); + QS_OBJ_DICTIONARY(&TH_XThread2->timeEvt); + QS_OBJ_DICTIONARY(&TH_sema); + QS_OBJ_DICTIONARY(&TH_mutex); + + // downcast the generic thr pointer to the specific thread + //XThread2 *me = (XThread2 *)thr; + + // initialize the semaphore before using it + // NOTE: Here the semaphore is initialized in the highest-priority thread + // that uses it. Alternatively, the semaphore can be initialized + // before any thread runs. + QXSemaphore_init(&TH_sema, + 0U, // count==0 (signaling semaphore) + 1U); // max_count==1 (binary semaphore) + + // initialize the mutex before using it + // NOTE: Here the mutex is initialized in the highest-priority thread + // that uses it. Alternatively, the mutex can be initialized + // before any thread runs. + QXMutex_init(&TH_mutex, N_PHILO + 6U); // priority-ceiling mutex + //QXMutex_init(&TH_mutex, 0U); // alternatively: priority-ceiling NOT used + + for (;;) { + // wait on a semaphore (BLOCK indefinitely) + QXSemaphore_wait(&TH_sema, QXTHREAD_NO_TIMEOUT); + + QXMutex_lock(&TH_mutex, QXTHREAD_NO_TIMEOUT); // lock the mutex + QXThread_delay(5U); // wait more (BLOCK) + QXMutex_unlock(&TH_mutex); + } +} diff --git a/examples/arm-cm/dpp_nucleo-l152re/stm32-nucleo-l152re.jpeg b/examples/arm-cm/dpp_nucleo-l152re/stm32-nucleo-l152re.jpeg new file mode 100644 index 00000000..266c7148 Binary files /dev/null and b/examples/arm-cm/dpp_nucleo-l152re/stm32-nucleo-l152re.jpeg differ diff --git a/examples/arm-cm/dpp_nucleo-l152re/table.c b/examples/arm-cm/dpp_nucleo-l152re/table.c index edfc073a..c3ae02f0 100644 --- a/examples/arm-cm/dpp_nucleo-l152re/table.c +++ b/examples/arm-cm/dpp_nucleo-l152re/table.c @@ -1,124 +1,130 @@ -/*$file${.::table.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* -* Model: dpp.qm -* File: ${.::table.c} -* -* This code has been generated by QM 5.2.4 . -* DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. -* -* SPDX-License-Identifier: GPL-3.0-or-later -* -* This generated code is open source software: you can redistribute it under -* the terms of the GNU General Public License as published by the Free -* Software Foundation. -* -* This code is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -* more details. -* -* NOTE: -* Alternatively, this generated code may be distributed under the terms -* of Quantum Leaps commercial licenses, which expressly supersede the GNU -* General Public License and are specifically designed for licensees -* interested in retaining the proprietary status of their code. -* -* Contact information: -* -* -*/ -/*$endhead${.::table.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -#include "qpc.h" -#include "dpp.h" -#include "bsp.h" +//$file${.::table.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// +// Model: dpp.qm +// File: ${.::table.c} +// +// This code has been generated by QM 5.3.0 . +// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. +// +// SPDX-License-Identifier: GPL-3.0-or-later +// +// This generated code is open source software: you can redistribute it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation. +// +// This code is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// NOTE: +// Alternatively, this generated code may be distributed under the terms +// of Quantum Leaps commercial licenses, which expressly supersede the GNU +// General Public License and are specifically designed for licensees +// interested in retaining the proprietary status of their code. +// +// Contact information: +// +// +// +//$endhead${.::table.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +#include "qpc.h" // QP/C real-time embedded framework +#include "dpp.h" // DPP Application interface +#include "bsp.h" // Board Support Package -Q_DEFINE_THIS_FILE +//$declare${AOs::Table} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/* Active object class -----------------------------------------------------*/ -/*$declare${AOs::Table} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${AOs::Table} ............................................................*/ +//${AOs::Table} .............................................................. typedef struct Table { -/* protected: */ +// protected: QActive super; -/* public: */ - -/* private: */ +// private: uint8_t fork[N_PHILO]; - uint8_t isHungry[N_PHILO]; + bool isHungry[N_PHILO]; + +// public: } Table; + extern Table Table_inst; -/* protected: */ +// protected: static QState Table_initial(Table * const me, void const * const par); static QState Table_active(Table * const me, QEvt const * const e); static QState Table_serving(Table * const me, QEvt const * const e); static QState Table_paused(Table * const me, QEvt const * const e); -/*$enddecl${AOs::Table} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$enddecl${AOs::Table} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -#define RIGHT(n_) ((uint8_t)(((n_) + (N_PHILO - 1U)) % N_PHILO)) -#define LEFT(n_) ((uint8_t)(((n_) + 1U) % N_PHILO)) -#define FREE ((uint8_t)0) -#define USED ((uint8_t)1) +//---------------------------------------------------------------------------- +Q_DEFINE_THIS_FILE -/*$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* Check for the minimum required QP version */ -#if (QP_VERSION < 700U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) -#error qpc version 7.0.0 or higher required +// helper function to provide the RIGHT neighbor of a Philo[n] +static inline uint8_t right(uint8_t const n) { + return (uint8_t)((n + (N_PHILO - 1U)) % N_PHILO); +} + +// helper function to provide the LEFT neighbor of a Philo[n] +static inline uint8_t left(uint8_t const n) { + return (uint8_t)((n + 1U) % N_PHILO); +} + +#define FREE ((uint8_t)0U) +#define USED ((uint8_t)1U) + +#define THINKING "thinking" +#define HUNGRY "hungry " +#define EATING "eating " + +//---------------------------------------------------------------------------- + +//$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// Check for the minimum required QP version +#if (QP_VERSION < 730U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) +#error qpc version 7.3.0 or higher required #endif -/*$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -/*$define${AOs::AO_Table} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//$define${Shared::Table_ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/*${AOs::AO_Table} .........................................................*/ -QActive * const AO_Table = &Table_inst.super; /* "opaque" pointer to Table AO */ -/*$enddef${AOs::AO_Table} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*$define${AOs::Table_ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${AOs::Table_ctor} .......................................................*/ +//${Shared::Table_ctor} ...................................................... void Table_ctor(void) { - Table *me = &Table_inst; - uint8_t n; - + Table * const me = &Table_inst; QActive_ctor(&me->super, Q_STATE_CAST(&Table_initial)); - - for (n = 0U; n < N_PHILO; ++n) { + for (uint8_t n = 0U; n < N_PHILO; ++n) { me->fork[n] = FREE; - me->isHungry[n] = 0U; + me->isHungry[n] = false; } } -/*$enddef${AOs::Table_ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*$define${AOs::Table} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//$enddef${Shared::Table_ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +//$define${Shared::AO_Table} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/*${AOs::Table} ............................................................*/ +//${Shared::AO_Table} ........................................................ +QActive * const AO_Table = &Table_inst.super; +//$enddef${Shared::AO_Table} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +//$define${AOs::Table} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${AOs::Table} .............................................................. Table Table_inst; -/*${AOs::Table::SM} ........................................................*/ +//${AOs::Table::SM} .......................................................... static QState Table_initial(Table * const me, void const * const par) { - /*${AOs::Table::SM::initial} */ - uint8_t n; - (void)par; /* unused parameter */ + //${AOs::Table::SM::initial} + Q_UNUSED_PAR(par); - QS_OBJ_DICTIONARY(&Table_inst); - - QS_SIG_DICTIONARY(DONE_SIG, (void *)0); /* global signals */ - QS_SIG_DICTIONARY(EAT_SIG, (void *)0); - QS_SIG_DICTIONARY(PAUSE_SIG, (void *)0); - QS_SIG_DICTIONARY(SERVE_SIG, (void *)0); - QS_SIG_DICTIONARY(TEST_SIG, (void *)0); - - QS_SIG_DICTIONARY(HUNGRY_SIG, me); /* signal just for Table */ + #ifdef Q_SPY + Table *Table_inst = me; + QS_OBJ_DICTIONARY(Table_inst); + #endif QActive_subscribe(&me->super, DONE_SIG); QActive_subscribe(&me->super, PAUSE_SIG); QActive_subscribe(&me->super, SERVE_SIG); QActive_subscribe(&me->super, TEST_SIG); - for (n = 0U; n < N_PHILO; ++n) { + for (uint8_t n = 0U; n < N_PHILO; ++n) { me->fork[n] = FREE; - me->isHungry[n] = 0U; - BSP_displayPhilStat(n, "thinking"); + me->isHungry[n] = false; + BSP_displayPhilStat(n, THINKING); } QS_FUN_DICTIONARY(&Table_active); @@ -128,16 +134,16 @@ static QState Table_initial(Table * const me, void const * const par) { return Q_TRAN(&Table_serving); } -/*${AOs::Table::SM::active} ................................................*/ +//${AOs::Table::SM::active} .................................................. static QState Table_active(Table * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${AOs::Table::SM::active::TEST} */ + //${AOs::Table::SM::active::TEST} case TEST_SIG: { status_ = Q_HANDLED(); break; } - /*${AOs::Table::SM::active::EAT} */ + //${AOs::Table::SM::active::EAT} case EAT_SIG: { Q_ERROR(); status_ = Q_HANDLED(); @@ -151,108 +157,119 @@ static QState Table_active(Table * const me, QEvt const * const e) { return status_; } -/*${AOs::Table::SM::active::serving} .......................................*/ +//${AOs::Table::SM::active::serving} ......................................... static QState Table_serving(Table * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${AOs::Table::SM::active::serving} */ + //${AOs::Table::SM::active::serving} case Q_ENTRY_SIG: { - uint8_t n; - for (n = 0U; n < N_PHILO; ++n) { /* give permissions to eat... */ - if ((me->isHungry[n] != 0U) - && (me->fork[LEFT(n)] == FREE) + // give permissions to eat... + for (uint8_t n = 0U; n < N_PHILO; ++n) { + if (me->isHungry[n] + && (me->fork[left(n)] == FREE) && (me->fork[n] == FREE)) { - TableEvt *te; - - me->fork[LEFT(n)] = USED; + me->fork[left(n)] = USED; me->fork[n] = USED; - te = Q_NEW(TableEvt, EAT_SIG); - te->philoNum = n; - QACTIVE_PUBLISH(&te->super, &me->super); - me->isHungry[n] = 0U; - BSP_displayPhilStat(n, "eating "); + #ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, EAT_SIG, n); + #else + TableEvt *pe = Q_NEW(TableEvt, EAT_SIG); + pe->philoId = n; + #endif + QACTIVE_PUBLISH(&pe->super, &me->super); + me->isHungry[n] = false; + BSP_displayPhilStat(n, EATING); } } status_ = Q_HANDLED(); break; } - /*${AOs::Table::SM::active::serving::HUNGRY} */ + //${AOs::Table::SM::active::serving::HUNGRY} case HUNGRY_SIG: { - uint8_t n, m; + uint8_t n = Q_EVT_CAST(TableEvt)->philoId; - n = Q_EVT_CAST(TableEvt)->philoNum; - /* phil ID must be in range and he must be not hungry */ - Q_ASSERT((n < N_PHILO) && (me->isHungry[n] == 0U)); + // phil ID must be in range and he must be not hungry + Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); - BSP_displayPhilStat(n, "hungry "); - m = LEFT(n); - /*${AOs::Table::SM::active::serving::HUNGRY::[bothfree]} */ + BSP_displayPhilStat(n, HUNGRY); + uint8_t m = left(n); + //${AOs::Table::SM::active::serving::HUNGRY::[bothfree]} if ((me->fork[m] == FREE) && (me->fork[n] == FREE)) { - TableEvt *pe; me->fork[m] = USED; me->fork[n] = USED; - pe = Q_NEW(TableEvt, EAT_SIG); - pe->philoNum = n; + #ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, EAT_SIG, n); + #else + TableEvt *pe = Q_NEW(TableEvt, EAT_SIG); + pe->philoId = n; + #endif QACTIVE_PUBLISH(&pe->super, &me->super); - BSP_displayPhilStat(n, "eating "); + BSP_displayPhilStat(n, EATING); status_ = Q_HANDLED(); } - /*${AOs::Table::SM::active::serving::HUNGRY::[else]} */ + //${AOs::Table::SM::active::serving::HUNGRY::[else]} else { - me->isHungry[n] = 1U; + me->isHungry[n] = true; status_ = Q_HANDLED(); } break; } - /*${AOs::Table::SM::active::serving::DONE} */ + //${AOs::Table::SM::active::serving::DONE} case DONE_SIG: { - uint8_t n, m; - TableEvt *pe; + uint8_t n = Q_EVT_CAST(TableEvt)->philoId; - n = Q_EVT_CAST(TableEvt)->philoNum; - /* phil ID must be in range and he must be not hungry */ - Q_ASSERT((n < N_PHILO) && (me->isHungry[n] == 0U)); + // phil ID must be in range and he must be not hungry + Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); - BSP_displayPhilStat(n, "thinking"); - m = LEFT(n); - /* both forks of Phil[n] must be used */ + BSP_displayPhilStat(n, THINKING); + uint8_t m = left(n); + + // both forks of Phil[n] must be used Q_ASSERT((me->fork[n] == USED) && (me->fork[m] == USED)); me->fork[m] = FREE; me->fork[n] = FREE; - m = RIGHT(n); /* check the right neighbor */ + m = right(n); // check the right neighbor - if ((me->isHungry[m] != 0U) && (me->fork[m] == FREE)) { + if (me->isHungry[m] && (me->fork[m] == FREE)) { me->fork[n] = USED; me->fork[m] = USED; - me->isHungry[m] = 0U; - pe = Q_NEW(TableEvt, EAT_SIG); - pe->philoNum = m; + me->isHungry[m] = false; + #ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, EAT_SIG, m); + #else + TableEvt *pe = Q_NEW(TableEvt, EAT_SIG); + pe->philoId = m; + #endif QACTIVE_PUBLISH(&pe->super, &me->super); - BSP_displayPhilStat(m, "eating "); + BSP_displayPhilStat(m, EATING); } - m = LEFT(n); /* check the left neighbor */ - n = LEFT(m); /* left fork of the left neighbor */ - if ((me->isHungry[m] != 0U) && (me->fork[n] == FREE)) { + m = left(n); // check the left neighbor + n = left(m); // left fork of the left neighbor + if (me->isHungry[m] && (me->fork[n] == FREE)) { me->fork[m] = USED; me->fork[n] = USED; - me->isHungry[m] = 0U; - pe = Q_NEW(TableEvt, EAT_SIG); - pe->philoNum = m; + me->isHungry[m] = false; + #ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, EAT_SIG, m); + #else + TableEvt *pe = Q_NEW(TableEvt, EAT_SIG); + pe->philoId = m; + #endif QACTIVE_PUBLISH(&pe->super, &me->super); - BSP_displayPhilStat(m, "eating "); + BSP_displayPhilStat(m, EATING); } status_ = Q_HANDLED(); break; } - /*${AOs::Table::SM::active::serving::EAT} */ + //${AOs::Table::SM::active::serving::EAT} case EAT_SIG: { Q_ERROR(); status_ = Q_HANDLED(); break; } - /*${AOs::Table::SM::active::serving::PAUSE} */ + //${AOs::Table::SM::active::serving::PAUSE} case PAUSE_SIG: { status_ = Q_TRAN(&Table_paused); break; @@ -265,48 +282,50 @@ static QState Table_serving(Table * const me, QEvt const * const e) { return status_; } -/*${AOs::Table::SM::active::paused} ........................................*/ +//${AOs::Table::SM::active::paused} .......................................... static QState Table_paused(Table * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${AOs::Table::SM::active::paused} */ + //${AOs::Table::SM::active::paused} case Q_ENTRY_SIG: { BSP_displayPaused(1U); status_ = Q_HANDLED(); break; } - /*${AOs::Table::SM::active::paused} */ + //${AOs::Table::SM::active::paused} case Q_EXIT_SIG: { BSP_displayPaused(0U); status_ = Q_HANDLED(); break; } - /*${AOs::Table::SM::active::paused::SERVE} */ + //${AOs::Table::SM::active::paused::SERVE} case SERVE_SIG: { status_ = Q_TRAN(&Table_serving); break; } - /*${AOs::Table::SM::active::paused::HUNGRY} */ + //${AOs::Table::SM::active::paused::HUNGRY} case HUNGRY_SIG: { - uint8_t n = Q_EVT_CAST(TableEvt)->philoNum; - /* philo ID must be in range and he must be not hungry */ - Q_ASSERT((n < N_PHILO) && (me->isHungry[n] == 0U)); - me->isHungry[n] = 1U; - BSP_displayPhilStat(n, "hungry "); + uint8_t n = Q_EVT_CAST(TableEvt)->philoId; + + // philo ID must be in range and he must be not hungry + Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); + + me->isHungry[n] = true; + BSP_displayPhilStat(n, HUNGRY); status_ = Q_HANDLED(); break; } - /*${AOs::Table::SM::active::paused::DONE} */ + //${AOs::Table::SM::active::paused::DONE} case DONE_SIG: { - uint8_t n, m; + uint8_t n = Q_EVT_CAST(TableEvt)->philoId; - n = Q_EVT_CAST(TableEvt)->philoNum; - /* phil ID must be in range and he must be not hungry */ - Q_ASSERT((n < N_PHILO) && (me->isHungry[n] == 0U)); + // phil ID must be in range and he must be not hungry + Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); - BSP_displayPhilStat(n, "thinking"); - m = LEFT(n); - /* both forks of Phil[n] must be used */ + BSP_displayPhilStat(n, THINKING); + uint8_t m = left(n); + + // both forks of Phil[n] must be used Q_ASSERT((me->fork[n] == USED) && (me->fork[m] == USED)); me->fork[m] = FREE; @@ -321,4 +340,4 @@ static QState Table_paused(Table * const me, QEvt const * const e) { } return status_; } -/*$enddef${AOs::Table} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$enddef${AOs::Table} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/examples/arm-cm/dpp_nucleo-l552ze/bsp.h b/examples/arm-cm/dpp_nucleo-l552ze/bsp.h index a0d2e549..fe8149a3 100644 --- a/examples/arm-cm/dpp_nucleo-l552ze/bsp.h +++ b/examples/arm-cm/dpp_nucleo-l552ze/bsp.h @@ -1,54 +1,49 @@ -/***************************************************************************** -* Product: BSP for DPP example -* Last updated for: @ref qpc_7_0_0 -* Last updated on 2022-01-21 -* -* Q u a n t u m L e a P s -* --------------------------- -* innovating embedded systems -* -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* -* -*****************************************************************************/ -#ifndef BSP_H -#define BSP_H +//============================================================================ +// Product: DPP example +// Last Updated for Version: 7.3.0 +// Date of the Last Update: 2023-06-27 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +//============================================================================ +#ifndef BSP_H_ +#define BSP_H_ #define BSP_TICKS_PER_SEC 100U void BSP_init(void); +void BSP_start(void); void BSP_displayPaused(uint8_t paused); void BSP_displayPhilStat(uint8_t n, char const *stat); void BSP_terminate(int16_t result); -void BSP_randomSeed(uint32_t seed); /* random seed */ -uint32_t BSP_random(void); /* pseudo-random generator */ +void BSP_randomSeed(uint32_t seed); // random seed +uint32_t BSP_random(void); // pseudo-random generator -/* for testing... */ -void BSP_wait4PB1(void); void BSP_ledOn(void); void BSP_ledOff(void); -extern QTicker ticker0; - -#endif /* BSP_H */ +#endif // BSP_H_ diff --git a/examples/arm-cm/dpp_nucleo-l552ze/dpp.h b/examples/arm-cm/dpp_nucleo-l552ze/dpp.h index da094c2c..e6d1557a 100644 --- a/examples/arm-cm/dpp_nucleo-l552ze/dpp.h +++ b/examples/arm-cm/dpp_nucleo-l552ze/dpp.h @@ -1,92 +1,117 @@ -/*$file${.::dpp.h} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* -* Model: dpp.qm -* File: ${.::dpp.h} -* -* This code has been generated by QM 5.2.4 . -* DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. -* -* SPDX-License-Identifier: GPL-3.0-or-later -* -* This generated code is open source software: you can redistribute it under -* the terms of the GNU General Public License as published by the Free -* Software Foundation. -* -* This code is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -* more details. -* -* NOTE: -* Alternatively, this generated code may be distributed under the terms -* of Quantum Leaps commercial licenses, which expressly supersede the GNU -* General Public License and are specifically designed for licensees -* interested in retaining the proprietary status of their code. -* -* Contact information: -* -* -*/ -/*$endhead${.::dpp.h} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -#ifndef DPP_H -#define DPP_H +//$file${.::dpp.h} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// +// Model: dpp.qm +// File: ${.::dpp.h} +// +// This code has been generated by QM 5.3.0 . +// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. +// +// SPDX-License-Identifier: GPL-3.0-or-later +// +// This generated code is open source software: you can redistribute it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation. +// +// This code is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// NOTE: +// Alternatively, this generated code may be distributed under the terms +// of Quantum Leaps commercial licenses, which expressly supersede the GNU +// General Public License and are specifically designed for licensees +// interested in retaining the proprietary status of their code. +// +// Contact information: +// +// +// +//$endhead${.::dpp.h} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +#ifndef DPP_H_ +#define DPP_H_ -enum DPPSignals { - EAT_SIG = Q_USER_SIG, /* published by Table to let a philosopher eat */ - DONE_SIG, /* published by Philosopher when done eating */ - PAUSE_SIG, /* published by BSP to pause serving forks */ - SERVE_SIG, /* published by BSP to serve re-start serving forks */ - TEST_SIG, /* published by BSP to test the application */ - MAX_PUB_SIG, /* the last published signal */ +//$declare${Shared} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv - HUNGRY_SIG, /* posted direclty to Table from hungry Philo */ - TIMEOUT_SIG, /* used by Philosophers for time events */ - MAX_SIG /* the last signal */ +//${Shared::AppSignals} ...................................................... +enum AppSignals { + EAT_SIG = Q_USER_SIG, // published by Table to let a Philo eat + DONE_SIG, // published by Philo when done eating + PAUSE_SIG, // published by BSP to pause the application + SERVE_SIG, // published by BSP to serve re-start serving forks + TEST_SIG, // published by BSP to test the application + MAX_PUB_SIG, // the last published signal + + TIMEOUT_SIG, // posted by time event to Philo + HUNGRY_SIG, // posted by hungry Philo to Table + MAX_SIG // the last signal }; -/*$declare${Events::TableEvt} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//${Shared::produce_sig_dict} ................................................ +#ifdef Q_SPY +static inline void produce_sig_dict(void) { + QS_SIG_DICTIONARY(EAT_SIG, (void *)0); + QS_SIG_DICTIONARY(DONE_SIG, (void *)0); + QS_SIG_DICTIONARY(PAUSE_SIG, (void *)0); + QS_SIG_DICTIONARY(SERVE_SIG, (void *)0); + QS_SIG_DICTIONARY(TEST_SIG, (void *)0); -/*${Events::TableEvt} ......................................................*/ + QS_SIG_DICTIONARY(TIMEOUT_SIG, (void *)0); + QS_SIG_DICTIONARY(HUNGRY_SIG, (void *)0); +} +#endif // def Q_SPY + +//${Shared::N_PHILO} ......................................................... +#define N_PHILO ((uint8_t)5U) + +//${Shared::TableEvt} ........................................................ typedef struct { -/* protected: */ +// protected: QEvt super; -/* public: */ - uint8_t philoNum; +// public: + uint8_t philoId; } TableEvt; -/*$enddecl${Events::TableEvt} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/* number of philosophers */ -#define N_PHILO ((uint8_t)5) +// public: -/*$declare${AOs::Philo_ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +#ifdef QEVT_DYN_CTOR +static inline TableEvt * TableEvt_ctor(TableEvt * const me, + uint8_t id) +{ + if (me != (TableEvt *)0) { + // don't call QEvt_ctor() because the initialization of all + // QEvt attributes is already done in QF_QF_newX_() + me->philoId = id; + } + return me; +} +#endif // def QEVT_DYN_CTOR -/*${AOs::Philo_ctor} .......................................................*/ -void Philo_ctor(void); -/*$enddecl${AOs::Philo_ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*$declare${AOs::AO_Philo[N_PHILO]} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${AOs::AO_Philo[N_PHILO]} ................................................*/ +//${Shared::AO_Philo[N_PHILO]} ............................................... extern QActive * const AO_Philo[N_PHILO]; -/*$enddecl${AOs::AO_Philo[N_PHILO]} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*$declare${AOs::Table_ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//${Shared::Philo_ctor} ...................................................... +void Philo_ctor(uint_fast8_t const id); -/*${AOs::Table_ctor} .......................................................*/ -void Table_ctor(void); -/*$enddecl${AOs::Table_ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*$declare${AOs::AO_Table} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${AOs::AO_Table} .........................................................*/ +//${Shared::AO_Table} ........................................................ extern QActive * const AO_Table; -/*$enddecl${AOs::AO_Table} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -#ifdef QP_INC_QXK_H_ - void Test1_ctor(void); - extern QXThread * const XT_Test1; - void Test2_ctor(void); - extern QXThread * const XT_Test2; -#endif /* QP_INC_QXK_H_ */ +//${Shared::Table_ctor} ...................................................... +void Table_ctor(void); +//$enddecl${Shared} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -#endif /* DPP_H */ +#ifdef QXK_H_ +extern QXThread * const TH_XThread1; +void XThread1_ctor(void); + +extern QXThread * const TH_XThread2; +void XThread2_ctor(void); + +extern QXSemaphore TH_sema; +extern QXMutex TH_mutex; + +#endif // QXK_H_ + +#endif // DPP_H_ diff --git a/examples/arm-cm/dpp_nucleo-l552ze/dpp.qm b/examples/arm-cm/dpp_nucleo-l552ze/dpp.qm index f1256b39..ac9f2bc9 100644 --- a/examples/arm-cm/dpp_nucleo-l552ze/dpp.qm +++ b/examples/arm-cm/dpp_nucleo-l552ze/dpp.qm @@ -1,185 +1,242 @@ - + Dining Philosopher Problem example - - - + + + + + { + EAT_SIG = Q_USER_SIG, // published by Table to let a Philo eat + DONE_SIG, // published by Philo when done eating + PAUSE_SIG, // published by BSP to pause the application + SERVE_SIG, // published by BSP to serve re-start serving forks + TEST_SIG, // published by BSP to test the application + MAX_PUB_SIG, // the last published signal + + TIMEOUT_SIG, // posted by time event to Philo + HUNGRY_SIG, // posted by hungry Philo to Table + MAX_SIG // the last signal +}; + + + + QS_SIG_DICTIONARY(EAT_SIG, (void *)0); +QS_SIG_DICTIONARY(DONE_SIG, (void *)0); +QS_SIG_DICTIONARY(PAUSE_SIG, (void *)0); +QS_SIG_DICTIONARY(SERVE_SIG, (void *)0); +QS_SIG_DICTIONARY(TEST_SIG, (void *)0); + +QS_SIG_DICTIONARY(TIMEOUT_SIG, (void *)0); +QS_SIG_DICTIONARY(HUNGRY_SIG, (void *)0); + + + + ((uint8_t)5U) + + - - + + + + + + + if (me != (TableEvt *)0) { + // don't call QEvt_ctor() because the initialization of all + // QEvt attributes is already done in QF_QF_newX_() + me->philoId = id; +} +return me; + + + + = { + &Philo_inst[0].super, + &Philo_inst[1].super, + &Philo_inst[2].super, + &Philo_inst[3].super, + &Philo_inst[4].super +}; + + + + + + Philo * const me = &Philo_inst[id]; +QActive_ctor(&me->super, Q_STATE_CAST(&Philo_initial)); +QTimeEvt_ctorX(&me->timeEvt, &me->super, TIMEOUT_SIG, 0U), +me->id = (uint8_t)id; + + + + = &Table_inst.super; + + + + Table * const me = &Table_inst; +QActive_ctor(&me->super, Q_STATE_CAST(&Table_initial)); +for (uint8_t n = 0U; n < N_PHILO; ++n) { + me->fork[n] = FREE; + me->isHungry[n] = false; +} + - - - The array of static insts of the Philo class (Singleton pattern) - + The Philo AO and the N_PHILO instances + + + + - + - static uint8_t registered = (uint8_t)0; /* starts off with 0, per C-standard */ -(void)par; /* unused parameter */ -if (registered == (uint8_t)0) { - registered = (uint8_t)1; + Q_UNUSED_PAR(par); - QS_OBJ_DICTIONARY(&Philo_inst[0]); - QS_OBJ_DICTIONARY(&Philo_inst[0].timeEvt); - QS_OBJ_DICTIONARY(&Philo_inst[1]); - QS_OBJ_DICTIONARY(&Philo_inst[1].timeEvt); - QS_OBJ_DICTIONARY(&Philo_inst[2]); - QS_OBJ_DICTIONARY(&Philo_inst[2].timeEvt); - QS_OBJ_DICTIONARY(&Philo_inst[3]); - QS_OBJ_DICTIONARY(&Philo_inst[3].timeEvt); - QS_OBJ_DICTIONARY(&Philo_inst[4]); - QS_OBJ_DICTIONARY(&Philo_inst[4].timeEvt); - - QS_FUN_DICTIONARY(&Philo_initial); - QS_FUN_DICTIONARY(&Philo_thinking); - QS_FUN_DICTIONARY(&Philo_hungry); - QS_FUN_DICTIONARY(&Philo_eating); -} -QS_SIG_DICTIONARY(HUNGRY_SIG, me); /* signal for each Philos */ -QS_SIG_DICTIONARY(TIMEOUT_SIG, me); /* signal for each Philos */ +QS_OBJ_ARR_DICTIONARY(&Philo_inst[me->id], me->id); +QS_OBJ_ARR_DICTIONARY(&Philo_inst[me->id].timeEvt, me->id); QActive_subscribe(&me->super, EAT_SIG); QActive_subscribe(&me->super, TEST_SIG); - + - QTimeEvt_armX(&me->timeEvt, THINK_TIME, 0U); - QTimeEvt_disarm(&me->timeEvt); + QTimeEvt_armX(&me->timeEvt, think_time(), 0U); + (void)QTimeEvt_disarm(&me->timeEvt); - - + + - /* EAT or DONE must be for other Philos than this one */ -Q_ASSERT(Q_EVT_CAST(TableEvt)->philoNum != PHILO_ID(me)); - + // EAT or DONE must be for other Philos than this one +Q_ASSERT(Q_EVT_CAST(TableEvt)->philoId != me->id); + - + - + - + - TableEvt *pe = Q_NEW(TableEvt, HUNGRY_SIG); -pe->philoNum = PHILO_ID(me); -QACTIVE_POST(AO_Table, &pe->super, me); + #ifdef QEVT_DYN_CTOR +TableEvt const *pe = Q_NEW(TableEvt, HUNGRY_SIG, me->id); +#else +TableEvt *pe = Q_NEW(TableEvt, HUNGRY_SIG); +pe->philoId = me->id; +#endif +QACTIVE_POST(AO_Table, &pe->super, &me->super); - + - Q_EVT_CAST(TableEvt)->philoNum == PHILO_ID(me) - - + Q_EVT_CAST(TableEvt)->philoId == me->id + + - + - /* DONE must be for other Philos than this one */ -Q_ASSERT(Q_EVT_CAST(TableEvt)->philoNum != PHILO_ID(me)); - + // DONE must be for other Philos than this one +Q_ASSERT(Q_EVT_CAST(TableEvt)->philoId != me->id); + - + - QTimeEvt_armX(&me->timeEvt, EAT_TIME, 0U); - TableEvt *pe = Q_NEW(TableEvt, DONE_SIG); -pe->philoNum = PHILO_ID(me); + QTimeEvt_armX(&me->timeEvt, eat_time(), 0U); + (void)QTimeEvt_disarm(&me->timeEvt); + +#ifdef QEVT_DYN_CTOR +TableEvt const *pe = Q_NEW(TableEvt, DONE_SIG, me->id); +#else +TableEvt *pe = Q_NEW(TableEvt, DONE_SIG); +pe->philoId = me->id; +#endif QACTIVE_PUBLISH(&pe->super, &me->super); - - + + - /* EAT or DONE must be for other Philos than this one */ -Q_ASSERT(Q_EVT_CAST(TableEvt)->philoNum != PHILO_ID(me)); - + // EAT or DONE must be for other Philos than this one +Q_ASSERT(Q_EVT_CAST(TableEvt)->philoId != me->id); + - + - + - - - The only static inst of the Table class (Singleton pattern) - - + + + - + - uint8_t n; -(void)par; /* unused parameter */ + Q_UNUSED_PAR(par); -QS_OBJ_DICTIONARY(&Table_inst); - -QS_SIG_DICTIONARY(DONE_SIG, (void *)0); /* global signals */ -QS_SIG_DICTIONARY(EAT_SIG, (void *)0); -QS_SIG_DICTIONARY(PAUSE_SIG, (void *)0); -QS_SIG_DICTIONARY(SERVE_SIG, (void *)0); -QS_SIG_DICTIONARY(TEST_SIG, (void *)0); - -QS_SIG_DICTIONARY(HUNGRY_SIG, me); /* signal just for Table */ +#ifdef Q_SPY +Table *Table_inst = me; +QS_OBJ_DICTIONARY(Table_inst); +#endif QActive_subscribe(&me->super, DONE_SIG); QActive_subscribe(&me->super, PAUSE_SIG); QActive_subscribe(&me->super, SERVE_SIG); QActive_subscribe(&me->super, TEST_SIG); -for (n = 0U; n < N_PHILO; ++n) { +for (uint8_t n = 0U; n < N_PHILO; ++n) { me->fork[n] = FREE; - me->isHungry[n] = 0U; - BSP_displayPhilStat(n, "thinking"); + me->isHungry[n] = false; + BSP_displayPhilStat(n, THINKING); } - + @@ -187,128 +244,139 @@ for (n = 0U; n < N_PHILO; ++n) { - + Q_ERROR(); - + - uint8_t n; -for (n = 0U; n < N_PHILO; ++n) { /* give permissions to eat... */ - if ((me->isHungry[n] != 0U) - && (me->fork[LEFT(n)] == FREE) + // give permissions to eat... +for (uint8_t n = 0U; n < N_PHILO; ++n) { + if (me->isHungry[n] + && (me->fork[left(n)] == FREE) && (me->fork[n] == FREE)) { - TableEvt *te; - - me->fork[LEFT(n)] = USED; + me->fork[left(n)] = USED; me->fork[n] = USED; - te = Q_NEW(TableEvt, EAT_SIG); - te->philoNum = n; - QACTIVE_PUBLISH(&te->super, &me->super); - me->isHungry[n] = 0U; - BSP_displayPhilStat(n, "eating "); +#ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, EAT_SIG, n); +#else + TableEvt *pe = Q_NEW(TableEvt, EAT_SIG); + pe->philoId = n; +#endif + QACTIVE_PUBLISH(&pe->super, &me->super); + me->isHungry[n] = false; + BSP_displayPhilStat(n, EATING); } } - uint8_t n, m; + uint8_t n = Q_EVT_CAST(TableEvt)->philoId; -n = Q_EVT_CAST(TableEvt)->philoNum; -/* phil ID must be in range and he must be not hungry */ -Q_ASSERT((n < N_PHILO) && (me->isHungry[n] == 0U)); +// phil ID must be in range and he must be not hungry +Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); -BSP_displayPhilStat(n, "hungry "); -m = LEFT(n); +BSP_displayPhilStat(n, HUNGRY); +uint8_t m = left(n); (me->fork[m] == FREE) && (me->fork[n] == FREE) - TableEvt *pe; -me->fork[m] = USED; + me->fork[m] = USED; me->fork[n] = USED; -pe = Q_NEW(TableEvt, EAT_SIG); -pe->philoNum = n; +#ifdef QEVT_DYN_CTOR +TableEvt const *pe = Q_NEW(TableEvt, EAT_SIG, n); +#else +TableEvt *pe = Q_NEW(TableEvt, EAT_SIG); +pe->philoId = n; +#endif QACTIVE_PUBLISH(&pe->super, &me->super); -BSP_displayPhilStat(n, "eating "); - +BSP_displayPhilStat(n, EATING); + else - me->isHungry[n] = 1U; - - + me->isHungry[n] = true; + + - + - uint8_t n, m; -TableEvt *pe; + uint8_t n = Q_EVT_CAST(TableEvt)->philoId; -n = Q_EVT_CAST(TableEvt)->philoNum; -/* phil ID must be in range and he must be not hungry */ -Q_ASSERT((n < N_PHILO) && (me->isHungry[n] == 0U)); +// phil ID must be in range and he must be not hungry +Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); -BSP_displayPhilStat(n, "thinking"); -m = LEFT(n); -/* both forks of Phil[n] must be used */ +BSP_displayPhilStat(n, THINKING); +uint8_t m = left(n); + +// both forks of Phil[n] must be used Q_ASSERT((me->fork[n] == USED) && (me->fork[m] == USED)); me->fork[m] = FREE; me->fork[n] = FREE; -m = RIGHT(n); /* check the right neighbor */ +m = right(n); // check the right neighbor -if ((me->isHungry[m] != 0U) && (me->fork[m] == FREE)) { +if (me->isHungry[m] && (me->fork[m] == FREE)) { me->fork[n] = USED; me->fork[m] = USED; - me->isHungry[m] = 0U; - pe = Q_NEW(TableEvt, EAT_SIG); - pe->philoNum = m; + me->isHungry[m] = false; +#ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, EAT_SIG, m); +#else + TableEvt *pe = Q_NEW(TableEvt, EAT_SIG); + pe->philoId = m; +#endif QACTIVE_PUBLISH(&pe->super, &me->super); - BSP_displayPhilStat(m, "eating "); + BSP_displayPhilStat(m, EATING); } -m = LEFT(n); /* check the left neighbor */ -n = LEFT(m); /* left fork of the left neighbor */ -if ((me->isHungry[m] != 0U) && (me->fork[n] == FREE)) { +m = left(n); // check the left neighbor +n = left(m); // left fork of the left neighbor +if (me->isHungry[m] && (me->fork[n] == FREE)) { me->fork[m] = USED; me->fork[n] = USED; - me->isHungry[m] = 0U; - pe = Q_NEW(TableEvt, EAT_SIG); - pe->philoNum = m; + me->isHungry[m] = false; +#ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, EAT_SIG, m); +#else + TableEvt *pe = Q_NEW(TableEvt, EAT_SIG); + pe->philoId = m; +#endif QACTIVE_PUBLISH(&pe->super, &me->super); - BSP_displayPhilStat(m, "eating "); + BSP_displayPhilStat(m, EATING); } - + Q_ERROR(); - + - + - + @@ -318,170 +386,140 @@ if ((me->isHungry[m] != 0U) && (me->fork[n] == FREE)) { BSP_displayPaused(0U); - + - uint8_t n = Q_EVT_CAST(TableEvt)->philoNum; -/* philo ID must be in range and he must be not hungry */ -Q_ASSERT((n < N_PHILO) && (me->isHungry[n] == 0U)); -me->isHungry[n] = 1U; -BSP_displayPhilStat(n, "hungry "); - + uint8_t n = Q_EVT_CAST(TableEvt)->philoId; + +// philo ID must be in range and he must be not hungry +Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); + +me->isHungry[n] = true; +BSP_displayPhilStat(n, HUNGRY); + - uint8_t n, m; + uint8_t n = Q_EVT_CAST(TableEvt)->philoId; -n = Q_EVT_CAST(TableEvt)->philoNum; -/* phil ID must be in range and he must be not hungry */ -Q_ASSERT((n < N_PHILO) && (me->isHungry[n] == 0U)); +// phil ID must be in range and he must be not hungry +Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); -BSP_displayPhilStat(n, "thinking"); -m = LEFT(n); -/* both forks of Phil[n] must be used */ +BSP_displayPhilStat(n, THINKING); +uint8_t m = left(n); + +// both forks of Phil[n] must be used Q_ASSERT((me->fork[n] == USED) && (me->fork[m] == USED)); me->fork[m] = FREE; me->fork[n] = FREE; - + - + - + - + - - - = { /* "opaque" pointers to Philo AO */ - &Philo_inst[0].super, - &Philo_inst[1].super, - &Philo_inst[2].super, - &Philo_inst[3].super, - &Philo_inst[4].super -}; - - - - = &Table_inst.super; /* "opaque" pointer to Table AO */ - - - - uint8_t n; -Philo *me; -for (n = 0U; n < N_PHILO; ++n) { - me = &Philo_inst[n]; - QActive_ctor(&me->super, Q_STATE_CAST(&Philo_initial)); - QTimeEvt_ctorX(&me->timeEvt, &me->super, TIMEOUT_SIG, 0U); -} - - - - Table *me = &Table_inst; -uint8_t n; - -QActive_ctor(&me->super, Q_STATE_CAST(&Table_initial)); - -for (n = 0U; n < N_PHILO; ++n) { - me->fork[n] = FREE; - me->isHungry[n] = 0U; -} - - #ifndef DPP_H -#define DPP_H + #ifndef DPP_H_ +#define DPP_H_ -enum DPPSignals { - EAT_SIG = Q_USER_SIG, /* published by Table to let a philosopher eat */ - DONE_SIG, /* published by Philosopher when done eating */ - PAUSE_SIG, /* published by BSP to pause serving forks */ - SERVE_SIG, /* published by BSP to serve re-start serving forks */ - TEST_SIG, /* published by BSP to test the application */ - MAX_PUB_SIG, /* the last published signal */ +$declare ${Shared} - HUNGRY_SIG, /* posted direclty to Table from hungry Philo */ - TIMEOUT_SIG, /* used by Philosophers for time events */ - MAX_SIG /* the last signal */ -}; +#ifdef QXK_H_ -$declare(Events::TableEvt) +extern QXThread * const TH_XThread1; +void XThread1_ctor(void); -/* number of philosophers */ -#define N_PHILO ((uint8_t)5) +extern QXThread * const TH_XThread2; +void XThread2_ctor(void); -$declare(AOs::Philo_ctor) -$declare(AOs::AO_Philo[N_PHILO]) +extern QXSemaphore TH_sema; +extern QXMutex TH_mutex; -$declare(AOs::Table_ctor) -$declare(AOs::AO_Table) +#endif // QXK_H_ -#ifdef QP_INC_QXK_H_ - void Test1_ctor(void); - extern QXThread * const XT_Test1; - void Test2_ctor(void); - extern QXThread * const XT_Test2; -#endif /* QP_INC_QXK_H_ */ - -#endif /* DPP_H */ - +#endif // DPP_H_ - #include "qpc.h" -#include "dpp.h" -#include "bsp.h" + #include "qpc.h" // QP/C real-time embedded framework +#include "dpp.h" // DPP Application interface +#include "bsp.h" // Board Support Package +$declare ${AOs::Philo} + +//---------------------------------------------------------------------------- Q_DEFINE_THIS_FILE -/* Active object class -----------------------------------------------------*/ -$declare${AOs::Philo} +// helper function to provide a randomized think time for Philos +static QTimeEvtCtr think_time(void); // prototype +static inline QTimeEvtCtr think_time(void) { + return (QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + + (BSP_TICKS_PER_SEC/2U)); +} -#define THINK_TIME \ - (QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + (BSP_TICKS_PER_SEC/2U)) -#define EAT_TIME \ - (QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + BSP_TICKS_PER_SEC) +// helper function to provide a randomized eat time for Philos +static QTimeEvtCtr eat_time(void); // prototype +static inline QTimeEvtCtr eat_time(void) { + return (QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + + BSP_TICKS_PER_SEC); +} +//---------------------------------------------------------------------------- -/* helper macro to provide the ID of Philo "me_" */ -#define PHILO_ID(me_) ((uint8_t)((me_) - &Philo_inst[0])) - -$define${AOs::AO_Philo[N_PHILO]} -$define${AOs::Philo_ctor} -$define${AOs::Philo} +$define ${Shared::Philo_ctor} +$define ${Shared::AO_Philo[N_PHILO]} +$define ${AOs::Philo} - #include "qpc.h" -#include "dpp.h" -#include "bsp.h" + #include "qpc.h" // QP/C real-time embedded framework +#include "dpp.h" // DPP Application interface +#include "bsp.h" // Board Support Package +$declare ${AOs::Table} + +//---------------------------------------------------------------------------- Q_DEFINE_THIS_FILE -/* Active object class -----------------------------------------------------*/ -$declare${AOs::Table} +// helper function to provide the RIGHT neighbor of a Philo[n] +static inline uint8_t right(uint8_t const n) { + return (uint8_t)((n + (N_PHILO - 1U)) % N_PHILO); +} -#define RIGHT(n_) ((uint8_t)(((n_) + (N_PHILO - 1U)) % N_PHILO)) -#define LEFT(n_) ((uint8_t)(((n_) + 1U) % N_PHILO)) -#define FREE ((uint8_t)0) -#define USED ((uint8_t)1) +// helper function to provide the LEFT neighbor of a Philo[n] +static inline uint8_t left(uint8_t const n) { + return (uint8_t)((n + 1U) % N_PHILO); +} -$define${AOs::AO_Table} -$define${AOs::Table_ctor} -$define${AOs::Table} +#define FREE ((uint8_t)0U) +#define USED ((uint8_t)1U) + +#define THINKING "thinking" +#define HUNGRY "hungry " +#define EATING "eating " + +//---------------------------------------------------------------------------- + +$define ${Shared::Table_ctor} +$define ${Shared::AO_Table} +$define ${AOs::Table} diff --git a/examples/arm-cm/dpp_nucleo-l552ze/main.c b/examples/arm-cm/dpp_nucleo-l552ze/main.c new file mode 100644 index 00000000..cfcfaf07 --- /dev/null +++ b/examples/arm-cm/dpp_nucleo-l552ze/main.c @@ -0,0 +1,44 @@ +//============================================================================ +// APP example +// Last updated for version 7.3.0 +// Last updated on 2023-08-09 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. +// +// This program is open source software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Alternatively, this program may be distributed and modified under the +// terms of Quantum Leaps commercial licenses, which expressly supersede +// the GNU General Public License and are specifically designed for +// licensees interested in retaining the proprietary status of their code. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Contact information: +// +// +//============================================================================ +#include "qpc.h" // QP/C real-time embedded framework +#include "dpp.h" // DPP Application interface +#include "bsp.h" // Board Support Package + +//............................................................................ +int main() { + QF_init(); // initialize the framework and the underlying RT kernel + BSP_init(); // initialize the BSP + BSP_start(); // start the AOs/Threads + return QF_run(); // run the QF application +} diff --git a/examples/arm-cm/dpp_nucleo-l552ze/philo.c b/examples/arm-cm/dpp_nucleo-l552ze/philo.c index a5be8e68..eb6be531 100644 --- a/examples/arm-cm/dpp_nucleo-l552ze/philo.c +++ b/examples/arm-cm/dpp_nucleo-l552ze/philo.c @@ -1,167 +1,159 @@ -/*$file${.::philo.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* -* Model: dpp.qm -* File: ${.::philo.c} -* -* This code has been generated by QM 5.2.4 . -* DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. -* -* SPDX-License-Identifier: GPL-3.0-or-later -* -* This generated code is open source software: you can redistribute it under -* the terms of the GNU General Public License as published by the Free -* Software Foundation. -* -* This code is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -* more details. -* -* NOTE: -* Alternatively, this generated code may be distributed under the terms -* of Quantum Leaps commercial licenses, which expressly supersede the GNU -* General Public License and are specifically designed for licensees -* interested in retaining the proprietary status of their code. -* -* Contact information: -* -* -*/ -/*$endhead${.::philo.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -#include "qpc.h" -#include "dpp.h" -#include "bsp.h" +//$file${.::philo.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// +// Model: dpp.qm +// File: ${.::philo.c} +// +// This code has been generated by QM 5.3.0 . +// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. +// +// SPDX-License-Identifier: GPL-3.0-or-later +// +// This generated code is open source software: you can redistribute it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation. +// +// This code is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// NOTE: +// Alternatively, this generated code may be distributed under the terms +// of Quantum Leaps commercial licenses, which expressly supersede the GNU +// General Public License and are specifically designed for licensees +// interested in retaining the proprietary status of their code. +// +// Contact information: +// +// +// +//$endhead${.::philo.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +#include "qpc.h" // QP/C real-time embedded framework +#include "dpp.h" // DPP Application interface +#include "bsp.h" // Board Support Package -Q_DEFINE_THIS_FILE +//$declare${AOs::Philo} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/* Active object class -----------------------------------------------------*/ -/*$declare${AOs::Philo} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${AOs::Philo} ............................................................*/ +//${AOs::Philo} .............................................................. typedef struct Philo { -/* protected: */ +// protected: QActive super; -/* public: */ - -/* private: */ +// private: QTimeEvt timeEvt; + uint8_t id; + +// public: } Philo; + extern Philo Philo_inst[N_PHILO]; -/* protected: */ +// protected: static QState Philo_initial(Philo * const me, void const * const par); static QState Philo_thinking(Philo * const me, QEvt const * const e); static QState Philo_hungry(Philo * const me, QEvt const * const e); static QState Philo_eating(Philo * const me, QEvt const * const e); -/*$enddecl${AOs::Philo} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$enddecl${AOs::Philo} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -#define THINK_TIME \ - (QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + (BSP_TICKS_PER_SEC/2U)) -#define EAT_TIME \ - (QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + BSP_TICKS_PER_SEC) +//---------------------------------------------------------------------------- +Q_DEFINE_THIS_FILE -/* helper macro to provide the ID of Philo "me_" */ -#define PHILO_ID(me_) ((uint8_t)((me_) - &Philo_inst[0])) +// helper function to provide a randomized think time for Philos +static QTimeEvtCtr think_time(void); // prototype +static inline QTimeEvtCtr think_time(void) { + return (QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + + (BSP_TICKS_PER_SEC/2U)); +} -/*$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* Check for the minimum required QP version */ -#if (QP_VERSION < 700U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) -#error qpc version 7.0.0 or higher required +// helper function to provide a randomized eat time for Philos +static QTimeEvtCtr eat_time(void); // prototype +static inline QTimeEvtCtr eat_time(void) { + return (QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + + BSP_TICKS_PER_SEC); +} +//---------------------------------------------------------------------------- + +//$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// Check for the minimum required QP version +#if (QP_VERSION < 730U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) +#error qpc version 7.3.0 or higher required #endif -/*$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -/*$define${AOs::AO_Philo[N_PHILO]} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//$define${Shared::Philo_ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/*${AOs::AO_Philo[N_PHILO]} ................................................*/ -QActive * const AO_Philo[N_PHILO] = { /* "opaque" pointers to Philo AO */ +//${Shared::Philo_ctor} ...................................................... +void Philo_ctor(uint_fast8_t const id) { + Philo * const me = &Philo_inst[id]; + QActive_ctor(&me->super, Q_STATE_CAST(&Philo_initial)); + QTimeEvt_ctorX(&me->timeEvt, &me->super, TIMEOUT_SIG, 0U), + me->id = (uint8_t)id; +} +//$enddef${Shared::Philo_ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +//$define${Shared::AO_Philo[N_PHILO]} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${Shared::AO_Philo[N_PHILO]} ............................................... +QActive * const AO_Philo[N_PHILO] = { &Philo_inst[0].super, &Philo_inst[1].super, &Philo_inst[2].super, &Philo_inst[3].super, &Philo_inst[4].super }; -/*$enddef${AOs::AO_Philo[N_PHILO]} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*$define${AOs::Philo_ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//$enddef${Shared::AO_Philo[N_PHILO]} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +//$define${AOs::Philo} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/*${AOs::Philo_ctor} .......................................................*/ -void Philo_ctor(void) { - uint8_t n; - Philo *me; - for (n = 0U; n < N_PHILO; ++n) { - me = &Philo_inst[n]; - QActive_ctor(&me->super, Q_STATE_CAST(&Philo_initial)); - QTimeEvt_ctorX(&me->timeEvt, &me->super, TIMEOUT_SIG, 0U); - } -} -/*$enddef${AOs::Philo_ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*$define${AOs::Philo} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${AOs::Philo} ............................................................*/ +//${AOs::Philo} .............................................................. Philo Philo_inst[N_PHILO]; -/*${AOs::Philo::SM} ........................................................*/ +//${AOs::Philo::SM} .......................................................... static QState Philo_initial(Philo * const me, void const * const par) { - /*${AOs::Philo::SM::initial} */ - static uint8_t registered = (uint8_t)0; /* starts off with 0, per C-standard */ - (void)par; /* unused parameter */ - if (registered == (uint8_t)0) { - registered = (uint8_t)1; + //${AOs::Philo::SM::initial} + Q_UNUSED_PAR(par); - QS_OBJ_DICTIONARY(&Philo_inst[0]); - QS_OBJ_DICTIONARY(&Philo_inst[0].timeEvt); - QS_OBJ_DICTIONARY(&Philo_inst[1]); - QS_OBJ_DICTIONARY(&Philo_inst[1].timeEvt); - QS_OBJ_DICTIONARY(&Philo_inst[2]); - QS_OBJ_DICTIONARY(&Philo_inst[2].timeEvt); - QS_OBJ_DICTIONARY(&Philo_inst[3]); - QS_OBJ_DICTIONARY(&Philo_inst[3].timeEvt); - QS_OBJ_DICTIONARY(&Philo_inst[4]); - QS_OBJ_DICTIONARY(&Philo_inst[4].timeEvt); - - QS_FUN_DICTIONARY(&Philo_initial); - QS_FUN_DICTIONARY(&Philo_thinking); - QS_FUN_DICTIONARY(&Philo_hungry); - QS_FUN_DICTIONARY(&Philo_eating); - } - QS_SIG_DICTIONARY(HUNGRY_SIG, me); /* signal for each Philos */ - QS_SIG_DICTIONARY(TIMEOUT_SIG, me); /* signal for each Philos */ + QS_OBJ_ARR_DICTIONARY(&Philo_inst[me->id], me->id); + QS_OBJ_ARR_DICTIONARY(&Philo_inst[me->id].timeEvt, me->id); QActive_subscribe(&me->super, EAT_SIG); QActive_subscribe(&me->super, TEST_SIG); + + QS_FUN_DICTIONARY(&Philo_thinking); + QS_FUN_DICTIONARY(&Philo_hungry); + QS_FUN_DICTIONARY(&Philo_eating); + return Q_TRAN(&Philo_thinking); } -/*${AOs::Philo::SM::thinking} ..............................................*/ +//${AOs::Philo::SM::thinking} ................................................ static QState Philo_thinking(Philo * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${AOs::Philo::SM::thinking} */ + //${AOs::Philo::SM::thinking} case Q_ENTRY_SIG: { - QTimeEvt_armX(&me->timeEvt, THINK_TIME, 0U); + QTimeEvt_armX(&me->timeEvt, think_time(), 0U); status_ = Q_HANDLED(); break; } - /*${AOs::Philo::SM::thinking} */ + //${AOs::Philo::SM::thinking} case Q_EXIT_SIG: { - QTimeEvt_disarm(&me->timeEvt); + (void)QTimeEvt_disarm(&me->timeEvt); status_ = Q_HANDLED(); break; } - /*${AOs::Philo::SM::thinking::TIMEOUT} */ + //${AOs::Philo::SM::thinking::TIMEOUT} case TIMEOUT_SIG: { status_ = Q_TRAN(&Philo_hungry); break; } - /*${AOs::Philo::SM::thinking::EAT, DONE} */ - case EAT_SIG: /* intentionally fall through */ + //${AOs::Philo::SM::thinking::EAT, DONE} + case EAT_SIG: // intentionally fall through case DONE_SIG: { - /* EAT or DONE must be for other Philos than this one */ - Q_ASSERT(Q_EVT_CAST(TableEvt)->philoNum != PHILO_ID(me)); + // EAT or DONE must be for other Philos than this one + Q_ASSERT(Q_EVT_CAST(TableEvt)->philoId != me->id); status_ = Q_HANDLED(); break; } - /*${AOs::Philo::SM::thinking::TEST} */ + //${AOs::Philo::SM::thinking::TEST} case TEST_SIG: { status_ = Q_HANDLED(); break; @@ -174,22 +166,26 @@ static QState Philo_thinking(Philo * const me, QEvt const * const e) { return status_; } -/*${AOs::Philo::SM::hungry} ................................................*/ +//${AOs::Philo::SM::hungry} .................................................. static QState Philo_hungry(Philo * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${AOs::Philo::SM::hungry} */ + //${AOs::Philo::SM::hungry} case Q_ENTRY_SIG: { + #ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, HUNGRY_SIG, me->id); + #else TableEvt *pe = Q_NEW(TableEvt, HUNGRY_SIG); - pe->philoNum = PHILO_ID(me); - QACTIVE_POST(AO_Table, &pe->super, me); + pe->philoId = me->id; + #endif + QACTIVE_POST(AO_Table, &pe->super, &me->super); status_ = Q_HANDLED(); break; } - /*${AOs::Philo::SM::hungry::EAT} */ + //${AOs::Philo::SM::hungry::EAT} case EAT_SIG: { - /*${AOs::Philo::SM::hungry::EAT::[Q_EVT_CAST(TableEvt)->philoNum=~} */ - if (Q_EVT_CAST(TableEvt)->philoNum == PHILO_ID(me)) { + //${AOs::Philo::SM::hungry::EAT::[e->philoId==me->iid]} + if (Q_EVT_CAST(TableEvt)->philoId == me->id) { status_ = Q_TRAN(&Philo_eating); } else { @@ -197,10 +193,10 @@ static QState Philo_hungry(Philo * const me, QEvt const * const e) { } break; } - /*${AOs::Philo::SM::hungry::DONE} */ + //${AOs::Philo::SM::hungry::DONE} case DONE_SIG: { - /* DONE must be for other Philos than this one */ - Q_ASSERT(Q_EVT_CAST(TableEvt)->philoNum != PHILO_ID(me)); + // DONE must be for other Philos than this one + Q_ASSERT(Q_EVT_CAST(TableEvt)->philoId != me->id); status_ = Q_HANDLED(); break; } @@ -212,34 +208,40 @@ static QState Philo_hungry(Philo * const me, QEvt const * const e) { return status_; } -/*${AOs::Philo::SM::eating} ................................................*/ +//${AOs::Philo::SM::eating} .................................................. static QState Philo_eating(Philo * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${AOs::Philo::SM::eating} */ + //${AOs::Philo::SM::eating} case Q_ENTRY_SIG: { - QTimeEvt_armX(&me->timeEvt, EAT_TIME, 0U); + QTimeEvt_armX(&me->timeEvt, eat_time(), 0U); status_ = Q_HANDLED(); break; } - /*${AOs::Philo::SM::eating} */ + //${AOs::Philo::SM::eating} case Q_EXIT_SIG: { + (void)QTimeEvt_disarm(&me->timeEvt); + + #ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, DONE_SIG, me->id); + #else TableEvt *pe = Q_NEW(TableEvt, DONE_SIG); - pe->philoNum = PHILO_ID(me); + pe->philoId = me->id; + #endif QACTIVE_PUBLISH(&pe->super, &me->super); status_ = Q_HANDLED(); break; } - /*${AOs::Philo::SM::eating::TIMEOUT} */ + //${AOs::Philo::SM::eating::TIMEOUT} case TIMEOUT_SIG: { status_ = Q_TRAN(&Philo_thinking); break; } - /*${AOs::Philo::SM::eating::EAT, DONE} */ - case EAT_SIG: /* intentionally fall through */ + //${AOs::Philo::SM::eating::EAT, DONE} + case EAT_SIG: // intentionally fall through case DONE_SIG: { - /* EAT or DONE must be for other Philos than this one */ - Q_ASSERT(Q_EVT_CAST(TableEvt)->philoNum != PHILO_ID(me)); + // EAT or DONE must be for other Philos than this one + Q_ASSERT(Q_EVT_CAST(TableEvt)->philoId != me->id); status_ = Q_HANDLED(); break; } @@ -250,4 +252,4 @@ static QState Philo_eating(Philo * const me, QEvt const * const e) { } return status_; } -/*$enddef${AOs::Philo} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$enddef${AOs::Philo} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/examples/arm-cm/dpp_nucleo-l552ze/qk/armclang/dpp-qk.sct b/examples/arm-cm/dpp_nucleo-l552ze/qk/armclang/dpp-qk.sct index a2c35683..a8e702a5 100644 --- a/examples/arm-cm/dpp_nucleo-l552ze/qk/armclang/dpp-qk.sct +++ b/examples/arm-cm/dpp_nucleo-l552ze/qk/armclang/dpp-qk.sct @@ -1,5 +1,8 @@ ; ************************************************************* ; *** Scatter-Loading Description File generated by uVision *** +; +; Adapted by Quantum Leaps: +; moved STACK as the first section in RW_STACK ; ************************************************************* LR_IROM1 0x08000000 0x00080000 { ; load region size_region @@ -9,7 +12,11 @@ LR_IROM1 0x08000000 0x00080000 { ; load region size_region .ANY (+RO) .ANY (+XO) } - RW_IRAM1 0x20000000 0x00030000 { ; RW data + + RW_STACK 0x20000000 { + * (STACK, +First) + } + RW_IRAM1 +0 (0x00003000 - 2048) { .ANY (+RW +ZI) } } diff --git a/examples/arm-cm/dpp_nucleo-l552ze/qk/armclang/dpp-qk.uvoptx b/examples/arm-cm/dpp_nucleo-l552ze/qk/armclang/dpp-qk.uvoptx index d4bba87b..e1b6e44f 100644 --- a/examples/arm-cm/dpp_nucleo-l552ze/qk/armclang/dpp-qk.uvoptx +++ b/examples/arm-cm/dpp_nucleo-l552ze/qk/armclang/dpp-qk.uvoptx @@ -120,7 +120,7 @@ 0 DLGTARM - (6010=-1,-1,-1,-1,0)(6018=-1,-1,-1,-1,0)(6019=-1,-1,-1,-1,0)(6008=-1,-1,-1,-1,0)(6009=-1,-1,-1,-1,0)(6014=-1,-1,-1,-1,0)(6015=-1,-1,-1,-1,0)(6003=2088,1225,2670,1761,1)(6000=1945,199,2398,531,0) + (6010=-1,-1,-1,-1,0)(6018=-1,-1,-1,-1,0)(6019=-1,-1,-1,-1,0)(6008=-1,-1,-1,-1,0)(6009=-1,-1,-1,-1,0)(6014=-1,-1,-1,-1,0)(6015=-1,-1,-1,-1,0)(6003=2966,593,3548,1129,0)(6000=1945,199,2398,531,0) 0 @@ -143,40 +143,7 @@ -U066FFF353638425043092845 -O2254 -SF10000 -C0 -A0 -I0 -HNlocalhost -HP7184 -P1 -N00("ARM CoreSight SW-DP (ARM Core") -D00(0BE12477) -L00(0) -TO131090 -TC10000000 -TT10000000 -TP21 -TDS8007 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -FO7 -FD20000000 -FC1000 -FN1 -FF0STM32L5x_512_0800.FLM -FS08000000 -FL080000 -FP0($$Device:STM32L552ZETxQ$CMSIS\Flash\STM32L5x_512_0800.FLM) - - - 0 - 0 - 147 - 1 -
134218946
- 0 - 0 - 0 - 0 - 0 - 1 - ..\bsp.c - - \\dpp_qk\../bsp.c\147 -
- - 1 - 0 - 262 - 1 -
134218882
- 0 - 0 - 0 - 0 - 0 - 1 - ..\bsp.c - - \\dpp_qk\../bsp.c\262 -
-
+ 1 @@ -502,7 +469,7 @@ 1 0 0 - 5 + 6 @@ -632,18 +599,6 @@ 1 2 - 1 - 0 - 0 - 0 - ..\main.c - main.c - 0 - 0 - - - 1 - 3 5 0 0 @@ -655,7 +610,7 @@ 1 - 4 + 3 5 0 0 @@ -667,7 +622,7 @@ 1 - 5 + 4 1 0 0 @@ -679,7 +634,7 @@ 1 - 6 + 5 1 0 0 @@ -691,13 +646,13 @@ 1 - 7 + 6 1 0 0 0 - ..\..\..\..\..\include\qstamp.c - qstamp.c + ..\..\main.c + main.c 0 0 @@ -711,7 +666,7 @@ 0 2 - 8 + 7 1 0 0 @@ -723,7 +678,7 @@ 2 - 9 + 8 1 0 0 @@ -735,7 +690,7 @@ 2 - 10 + 9 1 0 0 @@ -747,7 +702,7 @@ 2 - 11 + 10 1 0 0 @@ -759,7 +714,7 @@ 2 - 12 + 11 1 0 0 @@ -771,7 +726,7 @@ 2 - 13 + 12 1 0 0 @@ -783,7 +738,7 @@ 2 - 14 + 13 1 0 0 @@ -795,7 +750,7 @@ 2 - 15 + 14 1 0 0 @@ -807,7 +762,7 @@ 2 - 16 + 15 1 0 0 @@ -819,7 +774,7 @@ 2 - 17 + 16 1 0 0 @@ -831,7 +786,7 @@ 2 - 18 + 17 1 0 0 @@ -843,7 +798,7 @@ 2 - 19 + 18 1 0 0 @@ -863,7 +818,7 @@ 0 3 - 20 + 19 2 0 0 @@ -875,7 +830,7 @@ 3 - 21 + 20 5 0 0 @@ -887,7 +842,7 @@ 3 - 22 + 21 5 0 0 @@ -899,7 +854,7 @@ 3 - 23 + 22 1 0 0 @@ -911,7 +866,7 @@ 3 - 24 + 23 1 0 0 @@ -923,7 +878,7 @@ 3 - 25 + 24 1 0 0 @@ -943,7 +898,7 @@ 0 4 - 26 + 25 1 0 0 @@ -955,7 +910,7 @@ 4 - 27 + 26 1 0 0 @@ -967,7 +922,7 @@ 4 - 28 + 27 1 0 0 @@ -979,7 +934,7 @@ 4 - 29 + 28 1 0 0 @@ -991,7 +946,7 @@ 4 - 30 + 29 1 0 0 @@ -1003,7 +958,7 @@ 4 - 31 + 30 1 0 0 @@ -1015,7 +970,7 @@ 4 - 32 + 31 1 0 0 @@ -1027,7 +982,7 @@ 4 - 33 + 32 1 0 0 @@ -1039,7 +994,7 @@ 4 - 34 + 33 1 0 0 @@ -1051,7 +1006,7 @@ 4 - 35 + 34 1 0 0 @@ -1063,7 +1018,7 @@ 4 - 36 + 35 1 0 0 @@ -1075,7 +1030,7 @@ 4 - 37 + 36 1 0 0 @@ -1087,7 +1042,7 @@ 4 - 38 + 37 1 0 0 @@ -1107,31 +1062,7 @@ 0 5 - 39 - 5 - 0 - 0 - 0 - ..\..\..\..\..\ports\arm-cm\qk\armclang\qep_port.h - qep_port.h - 0 - 0 - - - 5 - 40 - 5 - 0 - 0 - 0 - ..\..\..\..\..\ports\arm-cm\qk\armclang\qf_port.h - qf_port.h - 0 - 0 - - - 5 - 41 + 38 5 0 0 @@ -1143,7 +1074,7 @@ 5 - 42 + 39 1 0 0 @@ -1153,18 +1084,6 @@ 0 0 - - 5 - 43 - 5 - 0 - 0 - 0 - ..\..\..\..\..\ports\arm-cm\qk\armclang\qk_port.h - qk_port.h - 0 - 0 - @@ -1175,7 +1094,7 @@ 0 6 - 44 + 40 1 0 0 @@ -1187,7 +1106,7 @@ 6 - 45 + 41 1 0 0 @@ -1199,7 +1118,7 @@ 6 - 46 + 42 1 0 0 @@ -1209,6 +1128,18 @@ 0 0 + + 6 + 43 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qs\qstamp.c + qstamp.c + 0 + 0 + diff --git a/examples/arm-cm/dpp_nucleo-l552ze/qk/armclang/dpp-qk.uvprojx b/examples/arm-cm/dpp_nucleo-l552ze/qk/armclang/dpp-qk.uvprojx index d09eddac..dd11f403 100644 --- a/examples/arm-cm/dpp_nucleo-l552ze/qk/armclang/dpp-qk.uvprojx +++ b/examples/arm-cm/dpp_nucleo-l552ze/qk/armclang/dpp-qk.uvprojx @@ -388,11 +388,6 @@ 1 ..\bsp.c - - main.c - 1 - ..\main.c - bsp.h 5 @@ -414,9 +409,9 @@ ..\..\table.c - qstamp.c + main.c 1 - ..\..\..\..\..\include\qstamp.c + ..\..\main.c @@ -593,16 +588,6 @@ QP_port - - qep_port.h - 5 - ..\..\..\..\..\ports\arm-cm\qk\armclang\qep_port.h - - - qf_port.h - 5 - ..\..\..\..\..\ports\arm-cm\qk\armclang\qf_port.h - qs_port.h 5 @@ -613,11 +598,6 @@ 1 ..\..\..\..\..\ports\arm-cm\qk\armclang\qk_port.c - - qk_port.h - 5 - ..\..\..\..\..\ports\arm-cm\qk\armclang\qk_port.h - @@ -707,6 +687,11 @@ 1 ..\..\..\..\..\src\qs\qs_rx.c + + qstamp.c + 1 + ..\..\..\..\..\src\qs\qstamp.c + @@ -1093,11 +1078,6 @@ 1 ..\bsp.c - - main.c - 1 - ..\main.c - bsp.h 5 @@ -1119,9 +1099,9 @@ ..\..\table.c - qstamp.c + main.c 1 - ..\..\..\..\..\include\qstamp.c + ..\..\main.c @@ -1298,16 +1278,6 @@ QP_port - - qep_port.h - 5 - ..\..\..\..\..\ports\arm-cm\qk\armclang\qep_port.h - - - qf_port.h - 5 - ..\..\..\..\..\ports\arm-cm\qk\armclang\qf_port.h - qs_port.h 5 @@ -1318,11 +1288,6 @@ 1 ..\..\..\..\..\ports\arm-cm\qk\armclang\qk_port.c - - qk_port.h - 5 - ..\..\..\..\..\ports\arm-cm\qk\armclang\qk_port.h - @@ -1412,6 +1377,11 @@ 1 ..\..\..\..\..\src\qs\qs_rx.c + + qstamp.c + 1 + ..\..\..\..\..\src\qs\qstamp.c + @@ -1747,7 +1717,7 @@ 0 - Q_SPY,USE_HAL_DRIVER,STM32L552xx + Q_SPY,QF_ON_CONTEXT_SW,USE_HAL_DRIVER,STM32L552xx ../..;../../../../../include;../../../../../src;../../../../../ports/arm-cm/qk/armclang;../../../../../3rd_party/CMSIS/Include;../../../../../3rd_party/STM32CubeL5/Drivers/STM32L5xx_HAL_Driver/Inc;../../../../../3rd_party/STM32CubeL5/Drivers/STM32L5xx_HAL_Driver/Inc/Legacy;../../../../../3rd_party/STM32CubeL5/Drivers/CMSIS/Device/ST/STM32L5xx/Include;../../../../../3rd_party/STM32CubeL5/Drivers/BSP/STM32L5xx_Nucleo @@ -1780,7 +1750,7 @@ - dpp-qk.sct + .\dpp-qk.sct @@ -1798,11 +1768,6 @@ 1 ..\bsp.c - - main.c - 1 - ..\main.c - bsp.h 5 @@ -1824,9 +1789,9 @@ ..\..\table.c - qstamp.c + main.c 1 - ..\..\..\..\..\include\qstamp.c + ..\..\main.c @@ -2003,16 +1968,6 @@ QP_port - - qep_port.h - 5 - ..\..\..\..\..\ports\arm-cm\qk\armclang\qep_port.h - - - qf_port.h - 5 - ..\..\..\..\..\ports\arm-cm\qk\armclang\qf_port.h - qs_port.h 5 @@ -2023,11 +1978,6 @@ 1 ..\..\..\..\..\ports\arm-cm\qk\armclang\qk_port.c - - qk_port.h - 5 - ..\..\..\..\..\ports\arm-cm\qk\armclang\qk_port.h - @@ -2117,6 +2067,11 @@ 1 ..\..\..\..\..\src\qs\qs_rx.c + + qstamp.c + 1 + ..\..\..\..\..\src\qs\qstamp.c + diff --git a/examples/arm-cm/dpp_nucleo-l552ze/qk/bsp.c b/examples/arm-cm/dpp_nucleo-l552ze/qk/bsp.c index bc2089a0..092479bb 100644 --- a/examples/arm-cm/dpp_nucleo-l552ze/qk/bsp.c +++ b/examples/arm-cm/dpp_nucleo-l552ze/qk/bsp.c @@ -1,198 +1,203 @@ -/*============================================================================ -* QP/C Real-Time Embedded Framework (RTEF) -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2022-02-25 -* @version Last updated for: @ref qpc_7_0_0 -* -* @file -* @brief DPP example, NUCLEO-L552ZE board, preemptive QK kernel -*/ -#include "qpc.h" -#include "dpp.h" -#include "bsp.h" +//============================================================================ +// Product: DPP example, NUCLEO-L552ZE board, QK kernel +// Last updated for version 7.3.0 +// Last updated on 2023-08-23 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. +// +// This program is open source software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Alternatively, this program may be distributed and modified under the +// terms of Quantum Leaps commercial licenses, which expressly supersede +// the GNU General Public License and are specifically designed for +// licensees interested in retaining the proprietary status of their code. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Contact information: +// +// +//============================================================================ +#include "qpc.h" // QP/C real-time embedded framework +#include "dpp.h" // DPP Application interface +#include "bsp.h" // Board Support Package -/* STM32CubeL5 include files */ +// STM32CubeL5 include files #include "stm32l5xx_hal.h" #include "stm32l5xx_nucleo.h" -/* add other drivers if necessary... */ +// add other drivers if necessary... Q_DEFINE_THIS_FILE -/* ISRs defined in this BSP ------------------------------------------------*/ +// ISRs defined in this BSP ------------------------------------------------ void SysTick_Handler(void); void LPUART1_IRQHandler(void); -/* Local-scope objects -----------------------------------------------------*/ -static uint32_t l_rnd; /* random seed */ +// Local-scope objects ----------------------------------------------------- +static uint32_t l_rndSeed; #ifdef Q_SPY QSTimeCtr QS_tickTime_; QSTimeCtr QS_tickPeriod_; - /* QSpy source IDs */ + // QSpy source IDs static QSpyId const l_SysTick_Handler = { 0U }; static UART_HandleTypeDef l_uartHandle; - enum AppRecords { /* application-specific trace records */ + enum AppRecords { // application-specific trace records PHILO_STAT = QS_USER, - COMMAND_STAT + PAUSED_STAT, + CONTEXT_SW, }; #endif -/* ISRs used in this project ===============================================*/ -void SysTick_Handler(void) { - /* state of the button debouncing, see below */ - static struct ButtonsDebouncing { - uint32_t depressed; - uint32_t previous; - } buttons = { 0U, 0U }; - uint32_t current; - uint32_t tmp; +//============================================================================ +// Error handler and ISRs... - QK_ISR_ENTRY(); /* inform QK about entering an ISR */ +Q_NORETURN Q_onError(char const * const module, int_t const id) { + // NOTE: this implementation of the assertion handler is intended only + // for debugging and MUST be changed for deployment of the application + // (assuming that you ship your production code with assertions enabled). + Q_UNUSED_PAR(module); + Q_UNUSED_PAR(id); + QS_ASSERTION(module, id, 10000U); -#ifdef Q_SPY - { - tmp = SysTick->CTRL; /* clear SysTick_CTRL_COUNTFLAG */ - QS_tickTime_ += QS_tickPeriod_; /* account for the clock rollover */ +#ifndef NDEBUG + // light all LEDs + BSP_LED_On(LED1); + BSP_LED_On(LED2); + BSP_LED_On(LED3); + // for debugging, hang on in an endless loop... + for (;;) { } #endif - QTIMEEVT_TICK_X(0U, &l_SysTick_Handler); /* process time events for rate 0 */ + NVIC_SystemReset(); +} +//............................................................................ +void assert_failed(char const * const module, int_t const id); // prototype +void assert_failed(char const * const module, int_t const id) { + Q_onError(module, id); +} - /* Perform the debouncing of buttons. The algorithm for debouncing - * adapted from the book "Embedded Systems Dictionary" by Jack Ganssle - * and Michael Barr, page 71. - */ - current = BSP_PB_GetState(BUTTON_USER); /* read the User button */ - tmp = buttons.depressed; /* save the debounced depressed buttons */ - buttons.depressed |= (buttons.previous & current); /* set depressed */ - buttons.depressed &= (buttons.previous | current); /* clear released */ - buttons.previous = current; /* update the history */ - tmp ^= buttons.depressed; /* changed debounced depressed */ - if (tmp != 0U) { /* debounced Key button state changed? */ - if (buttons.depressed != 0U) { /* PB0 depressed?*/ - static QEvt const pauseEvt = { PAUSE_SIG, 0U, 0U}; +// ISRs used in the application ============================================ + +void SysTick_Handler(void); // prototype +void SysTick_Handler(void) { + QK_ISR_ENTRY(); // inform QK about entering an ISR + + QTIMEEVT_TICK_X(0U, &l_SysTick_Handler); // time events for rate 0 + + // Perform the debouncing of buttons. The algorithm for debouncing + // adapted from the book "Embedded Systems Dictionary" by Jack Ganssle + // and Michael Barr, page 71. + static struct { + uint32_t depressed; + uint32_t previous; + } buttons = { 0U, 0U }; + + uint32_t current = BSP_PB_GetState(BUTTON_USER); // read User button + uint32_t tmp = buttons.depressed; // save the depressed buttons + buttons.depressed |= (buttons.previous & current); // set depressed + buttons.depressed &= (buttons.previous | current); // clear released + buttons.previous = current; // update the history + tmp ^= buttons.depressed; // changed debounced depressed + current = buttons.depressed; + + if (tmp != 0U) { // debounced User button state changed? + if (current != 0U) { // is User button depressed? + static QEvt const pauseEvt = QEVT_INITIALIZER(PAUSE_SIG); QACTIVE_PUBLISH(&pauseEvt, &l_SysTick_Handler); } - else { /* the button is released */ - static QEvt const serveEvt = { SERVE_SIG, 0U, 0U}; + else { // the button is released + static QEvt const serveEvt = QEVT_INITIALIZER(SERVE_SIG); QACTIVE_PUBLISH(&serveEvt, &l_SysTick_Handler); } } - QK_ISR_EXIT(); /* inform QK about exiting an ISR */ -} - -/*..........................................................................*/ #ifdef Q_SPY -/* -* ISR for receiving bytes from the QSPY Back-End -* NOTE: This ISR is "QF-unaware" meaning that it does not interact with -* the QF/QK and is not disabled. Such ISRs don't need to call QK_ISR_ENTRY/ -* QK_ISR_EXIT and they cannot post or publish events. -*/ -void LPUART1_IRQHandler(void) { - /* is RX register NOT empty? */ - if ((l_uartHandle.Instance->ISR & USART_ISR_RXNE_RXFNE) != 0) { - uint32_t b = l_uartHandle.Instance->RDR; - QS_RX_PUT(b); - l_uartHandle.Instance->ISR &= ~USART_ISR_RXNE_RXFNE; /* clear int. */ - } -} + tmp = SysTick->CTRL; // clear SysTick_CTRL_COUNTFLAG + QS_tickTime_ += QS_tickPeriod_; // account for the clock rollover #endif -static void SystemClock_Config(void); + QK_ISR_EXIT(); // inform QK about exiting an ISR +} -/*..........................................................................*/ -void BSP_init(void) { - /* Reset of all peripherals, Initializes the Flash interface - * - * NOTE: - * STM32Cube's HAL_Init() calls the weakly defined HAL_InitTick(), which - * by default configures and starts the Systick interrupt. This is - * TOO EARLY, because the system os NOT ready yet to handle interrupts. - * To avoid problems, a dummy definition for HAL_InitTick() is provided - * in the file stm32l5xx_hal_msp.c. The SystTick is configured and - * started later in QF_onStartup(). - */ - HAL_Init(); +//............................................................................ +#ifdef Q_SPY +// ISR for receiving bytes from the QSPY Back-End +// NOTE: This ISR is "QF-unaware" meaning that it does not interact with +// the QF/QK and is not disabled. Such ISRs don't need to call QK_ISR_ENTRY/ +// QK_ISR_EXIT and they cannot post or publish events. - /* Configure the system clock */ - SystemClock_Config(); - - Q_ALLEGE(HAL_ICACHE_ConfigAssociativityMode(ICACHE_1WAY) == HAL_OK); - Q_ALLEGE(HAL_ICACHE_Enable() == HAL_OK); - - /* Configure the LEDs */ - BSP_LED_Init(LED1); - BSP_LED_Init(LED2); - BSP_LED_Init(LED3); - - /* Configure the User Button in GPIO Mode */ - BSP_PB_Init(BUTTON_USER, BUTTON_MODE_GPIO); - - //... - BSP_randomSeed(1234U); - - /* initialize the QS software tracing... */ - if (QS_INIT((void *)0) == 0) { - Q_ERROR(); +void LPUART1_IRQHandler(void); // prototype +void LPUART1_IRQHandler(void) { + // is RX register NOT empty? + if ((l_uartHandle.Instance->ISR & USART_ISR_RXNE_RXFNE) != 0) { + uint8_t b = l_uartHandle.Instance->RDR; + QS_RX_PUT(b); + l_uartHandle.Instance->ISR &= ~USART_ISR_RXNE_RXFNE; // clear int. } - /* object dictionaries... */ - QS_OBJ_DICTIONARY(AO_Table); - QS_OBJ_DICTIONARY(AO_Philo[0]); - QS_OBJ_DICTIONARY(AO_Philo[1]); - QS_OBJ_DICTIONARY(AO_Philo[2]); - QS_OBJ_DICTIONARY(AO_Philo[3]); - QS_OBJ_DICTIONARY(AO_Philo[4]); - - QS_OBJ_DICTIONARY(&l_SysTick_Handler); - QS_USR_DICTIONARY(PHILO_STAT); - QS_USR_DICTIONARY(COMMAND_STAT); - - /* setup the QS filters... */ - QS_GLB_FILTER(QS_SM_RECORDS); - QS_GLB_FILTER(QS_UA_RECORDS); + QK_ARM_ERRATUM_838869(); } -/*..........................................................................*/ -static void SystemClock_Config(void) { +#endif // Q_SPY + +//............................................................................ +#ifdef QF_ON_CONTEXT_SW +// NOTE: the context-switch callback is called with interrupts DISABLED +void QF_onContextSw(QActive *prev, QActive *next) { + QS_BEGIN_INCRIT(CONTEXT_SW, 0U) // in critical section! + QS_OBJ(prev); + QS_OBJ(next); + QS_END_INCRIT() +} +#endif // QF_ON_CONTEXT_SW + +//============================================================================ +// BSP functions... + +void BSP_init(void) { + // Reset of all peripherals, Initializes the Flash interface + // + // NOTE: + // STM32Cube's HAL_Init() calls the weakly defined HAL_InitTick(), which + // by default configures and starts the Systick interrupt. This is + // TOO EARLY, because the system os NOT ready yet to handle interrupts. + // To avoid problems, a dummy definition for HAL_InitTick() is provided + // in the file stm32l5xx_hal_msp.c. The SystTick is configured and + // started later in QF_onStartup(). + // + HAL_Init(); + + // Configure the system clock RCC_OscInitTypeDef RCC_OscInitStruct = { 0 }; RCC_ClkInitTypeDef RCC_ClkInitStruct = { 0 }; - /* Configure the main internal regulator output voltage */ - Q_ALLEGE(HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE0) - == HAL_OK); + // Configure the main internal regulator output voltage + HAL_StatusTypeDef err = + HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE0); + Q_ASSERT(err == HAL_OK); - /* Initializes the RCC Oscillators according to the specified parameters - * in the RCC_OscInitTypeDef structure. - */ + // Initializes the RCC Oscillators according to the specified parameters + // in the RCC_OscInitTypeDef structure. + // RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI; RCC_OscInitStruct.HSIState = RCC_HSI_ON; RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT; @@ -203,29 +208,92 @@ static void SystemClock_Config(void) { RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV7; RCC_OscInitStruct.PLL.PLLQ = RCC_PLLQ_DIV2; RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV2; - Q_ALLEGE(HAL_RCC_OscConfig(&RCC_OscInitStruct) == HAL_OK); + err = HAL_RCC_OscConfig(&RCC_OscInitStruct); + Q_ASSERT(err == HAL_OK); - /* Initializes the CPU, AHB and APB buses clocks */ + // Initializes the CPU, AHB and APB buses clocks RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2; RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1; RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; - Q_ALLEGE(HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5) - == HAL_OK); -} + err = HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5); + Q_ASSERT(err == HAL_OK); -/*..........................................................................*/ -void BSP_ledOn(void) { - BSP_LED_On(LED1); + err = HAL_ICACHE_ConfigAssociativityMode(ICACHE_1WAY); + Q_ASSERT(err == HAL_OK); + + err = HAL_ICACHE_Enable(); + Q_ASSERT(err == HAL_OK); + + // Configure the LEDs + BSP_LED_Init(LED1); + BSP_LED_Init(LED2); + BSP_LED_Init(LED3); + + // Configure the User Button in GPIO Mode + BSP_PB_Init(BUTTON_USER, BUTTON_MODE_GPIO); + + BSP_randomSeed(1234U); // seed the random number generator + + // initialize the QS software tracing... + if (!QS_INIT((void *)0)) { + Q_ERROR(); + } + + // dictionaries... + QS_OBJ_DICTIONARY(&l_SysTick_Handler); + QS_USR_DICTIONARY(PHILO_STAT); + QS_USR_DICTIONARY(PAUSED_STAT); + QS_USR_DICTIONARY(CONTEXT_SW); + + QS_ONLY(produce_sig_dict()); + + // setup the QS filters... + QS_GLB_FILTER(QS_ALL_RECORDS); // all records + QS_GLB_FILTER(-QS_QF_TICK); // exclude the clock tick } -/*..........................................................................*/ -void BSP_ledOff(void) { - BSP_LED_Off(LED1); +//............................................................................ +void BSP_start(void) { + // initialize event pools + static QF_MPOOL_EL(TableEvt) smlPoolSto[2*N_PHILO]; + QF_poolInit(smlPoolSto, sizeof(smlPoolSto), sizeof(smlPoolSto[0])); + + // initialize publish-subscribe + static QSubscrList subscrSto[MAX_PUB_SIG]; + QActive_psInit(subscrSto, Q_DIM(subscrSto)); + + // instantiate and start AOs/threads... + + static QEvt const *philoQueueSto[N_PHILO][10]; + for (uint8_t n = 0U; n < N_PHILO; ++n) { + Philo_ctor(n); + QACTIVE_START(AO_Philo[n], + + // NOTE: set the preemption-threshold of all Philos to + // the same level, so that they cannot preempt each other. + Q_PRIO(n + 3U, N_PHILO + 2U), // QF-prio/pre-thre. + + philoQueueSto[n], // event queue storage + Q_DIM(philoQueueSto[n]), // queue length [events] + (void *)0, 0U, // no stack storage + (void *)0); // no initialization param + } + + static QEvt const *tableQueueSto[N_PHILO]; + Table_ctor(); + QACTIVE_START(AO_Table, + N_PHILO + 7U, // QP prio. of the AO + tableQueueSto, // event queue storage + Q_DIM(tableQueueSto), // queue length [events] + (void *)0, 0U, // no stack storage + (void *)0); // no initialization param } -/*..........................................................................*/ +//............................................................................ void BSP_displayPhilStat(uint8_t n, char const *stat) { + Q_UNUSED_PAR(n); + if (stat[0] == 'e') { BSP_LED_On(LED1); } @@ -233,161 +301,142 @@ void BSP_displayPhilStat(uint8_t n, char const *stat) { BSP_LED_Off(LED1); } - QS_BEGIN_ID(PHILO_STAT, AO_Philo[n]->prio) /* app-specific record */ - QS_U8(1, n); /* Philosopher number */ - QS_STR(stat); /* Philosopher status */ - QS_END() /* application-specific record end */ + // app-specific trace record... + QS_BEGIN_ID(PHILO_STAT, AO_Table->prio) + QS_U8(1, n); // Philosopher number + QS_STR(stat); // Philosopher status + QS_END() } -/*..........................................................................*/ -void BSP_displayPaused(uint8_t paused) { +//............................................................................ +void BSP_displayPaused(uint8_t const paused) { if (paused != 0U) { BSP_LED_On(LED2); } else { BSP_LED_Off(LED2); } + + // application-specific trace record + QS_BEGIN_ID(PAUSED_STAT, AO_Table->prio) + QS_U8(1, paused); // Paused status + QS_END() } -/*..........................................................................*/ -uint32_t BSP_random(void) { /* a very cheap pseudo-random-number generator */ - uint32_t rnd; - - /* Some flating point code is to exercise the VFP... */ - float volatile x = 3.1415926F; - x = x + 2.7182818F; - - QSchedStatus lockStat = QK_schedLock(N_PHILO); /* N_PHILO prio. ceiling */ - /* "Super-Duper" Linear Congruential Generator (LCG) - * LCG(2^32, 3*7*11*13*23, 0, seed) - */ - rnd = l_rnd * (3U*7U*11U*13U*23U); - l_rnd = rnd; /* set for the next time */ - QK_schedUnlock(lockStat); /* unlock the scheduler */ - - return (rnd >> 8); -} -/*..........................................................................*/ +//............................................................................ void BSP_randomSeed(uint32_t seed) { - l_rnd = seed; + l_rndSeed = seed; } -/*..........................................................................*/ +//............................................................................ +uint32_t BSP_random(void) { // a very cheap pseudo-random-number generator + // Some flating point code is to exercise the VFP... + double volatile x = 3.1415926; + x = x + 2.7182818; + + QSchedStatus lockStat = QK_schedLock(N_PHILO); // N_PHILO prio. ceiling + // "Super-Duper" Linear Congruential Generator (LCG) + // LCG(2^32, 3*7*11*13*23, 0, seed) + // + uint32_t rnd = l_rndSeed * (3U*7U*11U*13U*23U); + l_rndSeed = rnd; // set for the next time + QK_schedUnlock(lockStat); + + return (rnd >> 8U); +} +//............................................................................ +void BSP_ledOn(void) { + BSP_LED_On(LED1); +} +//............................................................................ +void BSP_ledOff(void) { + BSP_LED_Off(LED1); +} +//............................................................................ void BSP_terminate(int16_t result) { - (void)result; + Q_UNUSED_PAR(result); } -/*..........................................................................*/ +//============================================================================ +// QF callbacks... void QF_onStartup(void) { - /* assign all priority bits for preemption-prio. and none to sub-prio. - * NOTE: this might have been changed by STM32Cube. - */ - NVIC_SetPriorityGrouping(0U); - - /* set up the SysTick timer to fire at BSP_TICKS_PER_SEC rate */ + // set up the SysTick timer to fire at BSP_TICKS_PER_SEC rate SysTick_Config(SystemCoreClock / BSP_TICKS_PER_SEC); - /* set priorities of ALL ISRs used in the system, see NOTE1 - * - * !!!!!!!!!!!!!!!!!!!!!!!!!!!! CAUTION !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - * Assign a priority to EVERY ISR explicitly by calling NVIC_SetPriority(). - * DO NOT LEAVE THE ISR PRIORITIES AT THE DEFAULT VALUE! - */ - NVIC_SetPriority(LPUART1_IRQn, 0U); /* kernel unaware interrupt */ - NVIC_SetPriority(SysTick_IRQn, QF_AWARE_ISR_CMSIS_PRI); - /* ... */ + // assign all priority bits for preemption-prio. and none to sub-prio. + // NOTE: this might have been changed by STM32Cube. + NVIC_SetPriorityGrouping(0U); - /* enable IRQs... */ + // set priorities of ALL ISRs used in the system, see NOTE1 + NVIC_SetPriority(USART3_IRQn, 0U); // kernel UNAWARE interrupt + NVIC_SetPriority(SysTick_IRQn, QF_AWARE_ISR_CMSIS_PRI + 0U); + // ... + + // enable IRQs... #ifdef Q_SPY - NVIC_EnableIRQ(LPUART1_IRQn); /* UART interrupt used for QS-RX */ + NVIC_EnableIRQ(USART3_IRQn); // UART interrupt used for QS-RX #endif } -/*..........................................................................*/ +//............................................................................ void QF_onCleanup(void) { } - -/*..........................................................................*/ -#ifdef QF_ON_CONTEXT_SW -/* NOTE: the context-switch callback is called with interrupts DISABLED */ -void QF_onContextSw(QActive *prev, QActive *next) { - (void)prev; - if (next != (QActive *)0) { - //_impure_ptr = next->thread; /* switch to next TLS */ - } - QS_BEGIN_NOCRIT(CONTEXT_SW, 0U) /* no critical section! */ - QS_OBJ(prev); - QS_OBJ(next); - QS_END_NOCRIT() -} -#endif /* QF_ON_CONTEXT_SW */ -/*..........................................................................*/ +//............................................................................ void QK_onIdle(void) { - /* toggle the User LED on and then off, see NOTE2 */ + // toggle the User LED on and then off, see NOTE2 QF_INT_DISABLE(); BSP_LED_On (LED3); BSP_LED_Off(LED3); QF_INT_ENABLE(); + // Some floating point code is to exercise the VFP... + double volatile x = 1.73205; + x = x * 1.73205; + #ifdef Q_SPY - QS_rxParse(); /* parse all the received bytes */ - - if ((l_uartHandle.Instance->ISR & UART_FLAG_TXE) != 0U) { /* TXE empty? */ - uint16_t b; + QF_INT_DISABLE(); + QS_rxParse(); // parse all the received bytes + QF_INT_ENABLE(); + QF_CRIT_EXIT_NOP(); + QF_INT_DISABLE(); + if ((l_uartHandle.Instance->ISR & UART_FLAG_TXE) != 0U) { // TXE empty? QF_INT_DISABLE(); - b = QS_getByte(); + uint16_t b = QS_getByte(); QF_INT_ENABLE(); - if (b != QS_EOD) { /* not End-Of-Data? */ - l_uartHandle.Instance->TDR = (b & 0xFFU); /* put into TDR */ + if (b != QS_EOD) { // not End-Of-Data? + l_uartHandle.Instance->TDR = b; // put into TDR } } + QF_INT_ENABLE(); #elif defined NDEBUG - /* Put the CPU and peripherals to the low-power mode. - * you might need to customize the clock management for your application, - * see the datasheet for your particular Cortex-M MCU. - */ - /* !!!CAUTION!!! - * The WFI instruction stops the CPU clock, which unfortunately disables - * the JTAG port, so the ST-Link debugger can no longer connect to the - * board. For that reason, the call to __WFI() has to be used with CAUTION. - * - * NOTE: If you find your board "frozen" like this, strap BOOT0 to VDD and - * reset the board, then connect with ST-Link Utilities and erase the part. - * The trick with BOOT(0) is it gets the part to run the System Loader - * instead of your broken code. When done disconnect BOOT0, and start over. - */ - //__WFI(); /* Wait-For-Interrupt */ + // Put the CPU and peripherals to the low-power mode. + // you might need to customize the clock management for your application, + // see the datasheet for your particular Cortex-M MCU. + // + // !!!CAUTION!!! + // The WFI instruction stops the CPU clock, which unfortunately disables + // the JTAG port, so the ST-Link debugger can no longer connect to the + // board. For that reason, the call to __WFI() has to be used with CAUTION. + // + // NOTE: If you find your board "frozen" like this, strap BOOT0 to VDD and + // reset the board, then connect with ST-Link Utilities and erase the part. + // The trick with BOOT(0) is it gets the part to run the System Loader + // instead of your broken code. When done disconnect BOOT0, and start over. + // + //__WFI(); // Wait-For-Interrupt #endif } -/*..........................................................................*/ -Q_NORETURN Q_onAssert(char const * const module, int_t const loc) { - /* - * NOTE: add here your application-specific error handling - */ - (void)module; - (void)loc; - QS_ASSERTION(module, loc, 10000U); /* report assertion to QS */ - -#ifndef NDEBUG - /* light all LEDs */ - BSP_LED_On(LED1); - BSP_LED_On(LED2); - BSP_LED_On(LED3); - /* for debugging, hang on in an endless loop... */ - for (;;) { - } -#endif - - NVIC_SystemReset(); -} - -/* QS callbacks ============================================================*/ +//============================================================================ +// QS callbacks... #ifdef Q_SPY -/*..........................................................................*/ -uint8_t QS_onStartup(void const *arg) { - static uint8_t qsTxBuf[1024]; /* buffer for QS-TX channel */ - static uint8_t qsRxBuf[256]; /* buffer for QS-RX channel */ - QS_initBuf (qsTxBuf, sizeof(qsTxBuf)); +//............................................................................ +uint8_t QS_onStartup(void const *arg) { + Q_UNUSED_PAR(arg); + + static uint8_t qsTxBuf[2*1024]; // buffer for QS-TX channel + QS_initBuf(qsTxBuf, sizeof(qsTxBuf)); + + static uint8_t qsRxBuf[100]; // buffer for QS-RX channel QS_rxInitBuf(qsRxBuf, sizeof(qsRxBuf)); l_uartHandle.Instance = LPUART1; @@ -402,97 +451,92 @@ uint8_t QS_onStartup(void const *arg) { l_uartHandle.Init.ClockPrescaler = UART_PRESCALER_DIV1; l_uartHandle.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT; if (HAL_UART_Init(&l_uartHandle) != HAL_OK) { - return 0U; /* failure */ + return 0U; // failure } - /* Set UART to receive 1 byte at a time via interrupt */ + // Set UART to receive 1 byte at a time via interrupt HAL_UART_Receive_IT(&l_uartHandle, (uint8_t *)qsRxBuf, 1); QS_tickPeriod_ = SystemCoreClock / BSP_TICKS_PER_SEC; - QS_tickTime_ = QS_tickPeriod_; /* to start the timestamp at zero */ + QS_tickTime_ = QS_tickPeriod_; // to start the timestamp at zero - return 1U; /* return success */ + return 1U; // return success } -/*..........................................................................*/ +//............................................................................ void QS_onCleanup(void) { } -/*..........................................................................*/ -QSTimeCtr QS_onGetTime(void) { /* NOTE: invoked with interrupts DISABLED */ - if ((SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk) == 0) { /* not set? */ +//............................................................................ +QSTimeCtr QS_onGetTime(void) { // NOTE: invoked with interrupts DISABLED + if ((SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk) == 0U) { // not set? return QS_tickTime_ - (QSTimeCtr)SysTick->VAL; } - else { /* the rollover occured, but the SysTick_ISR did not run yet */ + else { // the rollover occured, but the SysTick_ISR did not run yet return QS_tickTime_ + QS_tickPeriod_ - (QSTimeCtr)SysTick->VAL; } } -/*..........................................................................*/ +//............................................................................ void QS_onFlush(void) { - uint16_t b; - - QF_INT_DISABLE(); - while ((b = QS_getByte()) != QS_EOD) { /* while not End-Of-Data... */ - QF_INT_ENABLE(); - /* while TXE not empty */ - while ((l_uartHandle.Instance->ISR & UART_FLAG_TXE) == 0U) { - } - l_uartHandle.Instance->TDR = (b & 0xFFU); /* put into TDR */ + for (;;) { QF_INT_DISABLE(); + uint16_t b = QS_getByte(); + if (b != QS_EOD) { + while ((l_uartHandle.Instance->ISR & UART_FLAG_TXE) == 0U) { + QF_INT_ENABLE(); + QF_CRIT_EXIT_NOP(); + + QF_INT_DISABLE(); + } + l_uartHandle.Instance->TDR = b; + QF_INT_ENABLE(); + } + else { + QF_INT_ENABLE(); + break; + } } - QF_INT_ENABLE(); } -/*..........................................................................*/ -/*! callback function to reset the target (to be implemented in the BSP) */ +//............................................................................ +//! callback function to reset the target (to be implemented in the BSP) void QS_onReset(void) { NVIC_SystemReset(); } -/*..........................................................................*/ -/*! callback function to execute a user command (to be implemented in BSP) */ +//............................................................................ +//! callback function to execute a user command void QS_onCommand(uint8_t cmdId, uint32_t param1, uint32_t param2, uint32_t param3) { - void assert_failed(char const *module, int loc); - (void)cmdId; - (void)param1; - (void)param2; - (void)param3; - QS_BEGIN_ID(COMMAND_STAT, 0U) /* app-specific record */ - QS_U8(2, cmdId); - QS_U32(8, param1); - QS_END() - - if (cmdId == 10U) { - Q_ERROR(); - } - else if (cmdId == 11U) { - assert_failed("QS_onCommand", 123); - } + Q_UNUSED_PAR(cmdId); + Q_UNUSED_PAR(param1); + Q_UNUSED_PAR(param2); + Q_UNUSED_PAR(param3); } -#endif /* Q_SPY */ -/*--------------------------------------------------------------------------*/ +#endif // Q_SPY +//---------------------------------------------------------------------------- -/***************************************************************************** -* NOTE1: -* The QF_AWARE_ISR_CMSIS_PRI constant from the QF port specifies the highest -* ISR priority that is disabled by the QF framework. The value is suitable -* for the NVIC_SetPriority() CMSIS function. -* -* Only ISRs prioritized at or below the QF_AWARE_ISR_CMSIS_PRI level (i.e., -* with the numerical values of priorities equal or higher than -* QF_AWARE_ISR_CMSIS_PRI) are allowed to call the QK_ISR_ENTRY/QK_ISR_ENTRY -* macros or any other QF services. These ISRs are "QF-aware". -* -* Conversely, any ISRs prioritized above the QF_AWARE_ISR_CMSIS_PRI priority -* level (i.e., with the numerical values of priorities less than -* QF_AWARE_ISR_CMSIS_PRI) are never disabled and are not aware of the kernel. -* Such "QF-unaware" ISRs cannot call any QF services. In particular they -* can NOT call the macros QK_ISR_ENTRY/QK_ISR_ENTRY. The only mechanism -* by which a "QF-unaware" ISR can communicate with the QF framework is by -* triggering a "QF-aware" ISR, which can post/publish events. -* -* NOTE2: -* The User LED is used to visualize the idle loop activity. The brightness -* of the LED is proportional to the frequency of invcations of the idle loop. -* Please note that the LED is toggled with interrupts locked, so no interrupt -* execution time contributes to the brightness of the User LED. -*/ +//============================================================================ +// NOTE1: +// The QF_AWARE_ISR_CMSIS_PRI constant from the QF port specifies the highest +// ISR priority that is disabled by the QF framework. The value is suitable +// for the NVIC_SetPriority() CMSIS function. +// +// Only ISRs prioritized at or below the QF_AWARE_ISR_CMSIS_PRI level (i.e., +// with the numerical values of priorities equal or higher than +// QF_AWARE_ISR_CMSIS_PRI) are allowed to call the QK_ISR_ENTRY/ +// QK_ISR_ENTRY macros or any other QF/QK services. These ISRs are +// "QF-aware". +// +// Conversely, any ISRs prioritized above the QF_AWARE_ISR_CMSIS_PRI priority +// level (i.e., with the numerical values of priorities less than +// QF_AWARE_ISR_CMSIS_PRI) are never disabled and are not aware of the kernel. +// Such "QF-unaware" ISRs cannot call ANY QF/QK services. In particular they +// can NOT call the macros QK_ISR_ENTRY/QK_ISR_ENTRY. The only mechanism +// by which a "QF-unaware" ISR can communicate with the QF framework is by +// triggering a "QF-aware" ISR, which can post/publish events. +// +// NOTE2: +// The User LED is used to visualize the idle loop activity. The brightness +// of the LED is proportional to the frequency of the idle loop. +// Please note that the LED is toggled with interrupts locked, so no interrupt +// execution time contributes to the brightness of the User LED. +// diff --git a/examples/arm-cm/dpp_nucleo-l552ze/qk/gnu/Makefile b/examples/arm-cm/dpp_nucleo-l552ze/qk/gnu/Makefile index 6f0f2d7e..ba1eebb3 100644 --- a/examples/arm-cm/dpp_nucleo-l552ze/qk/gnu/Makefile +++ b/examples/arm-cm/dpp_nucleo-l552ze/qk/gnu/Makefile @@ -154,7 +154,10 @@ LIB_DIRS := LIBS := # defines -DEFINES := -DUSE_HAL_DRIVER -DSTM32L552xx +DEFINES := \ + -DQF_ON_CONTEXT_SW \ + -DUSE_HAL_DRIVER \ + -DSTM32L552xx # ARM CPU, ARCH, FPU, and Float-ABI types... # ARM_CPU: [cortex-m0 | cortex-m0plus | cortex-m1 | cortex-m3 | cortex-m4] @@ -282,7 +285,7 @@ $(TARGET_BIN): $(TARGET_ELF) $(BIN) -O binary $< $@ $(TARGET_ELF) : $(ASM_OBJS_EXT) $(C_OBJS_EXT) $(CPP_OBJS_EXT) - $(CC) $(CFLAGS) $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o + $(CC) $(CFLAGS) $(QPC)/src/qs/qstamp.c -o $(BIN_DIR)/qstamp.o $(LINK) $(LINKFLAGS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) $(BIN_DIR)/%.d : %.c diff --git a/examples/arm-cm/dpp_nucleo-l552ze/qk/iar/dpp-qk.ewd b/examples/arm-cm/dpp_nucleo-l552ze/qk/iar/dpp-qk.ewd index f3a209f9..7dd57ca5 100644 --- a/examples/arm-cm/dpp_nucleo-l552ze/qk/iar/dpp-qk.ewd +++ b/examples/arm-cm/dpp_nucleo-l552ze/qk/iar/dpp-qk.ewd @@ -88,7 +88,7 @@ - - BILINK - 0 - - Coder 0 @@ -1032,9 +1092,13 @@ General 3 - 28 + 35 1 0 + - - - - - + + + + + + + + ICCARM 2 - 34 + 37 1 0 - - - + + AARM 2 - 10 + 11 1 0 + @@ -1678,13 +1751,9 @@ 0 + inputOutputBased - - BICOMP - 0 - - BUILDACTION 1 @@ -1697,17 +1766,13 @@ ILINK 0 - 20 + 27 1 0 - + + + + + + + + + + + + + + + @@ -2032,11 +2157,6 @@ - - BILINK - 0 - - Coder 0 @@ -2053,9 +2173,13 @@ General 3 - 28 + 35 1 1 + - - - - - + + + + + + + + ICCARM 2 - 34 + 37 1 1 - - - + + AARM 2 - 10 + 11 1 1 + @@ -2699,13 +2833,9 @@ 0 + inputOutputBased - - BICOMP - 0 - - BUILDACTION 1 @@ -2718,17 +2848,13 @@ ILINK 0 - 20 + 27 1 1 - + + + + + + + + + + + + + + + @@ -3053,11 +3239,6 @@ - - BILINK - 0 - - Coder 0 @@ -3076,14 +3257,11 @@ $PROJ_DIR$\..\..\dpp.h - $PROJ_DIR$\..\main.c + $PROJ_DIR$\..\..\main.c $PROJ_DIR$\..\..\philo.c - - $PROJ_DIR$\..\..\..\..\..\include\qstamp.c - $PROJ_DIR$\..\..\table.c @@ -3132,21 +3310,9 @@ QP_port - - $PROJ_DIR$\..\..\..\..\..\ports\arm-cm\qk\iar\qep_port.h - - - $PROJ_DIR$\..\..\..\..\..\ports\arm-cm\qk\iar\qf_port.h - - - $PROJ_DIR$\..\..\..\..\..\ports\arm-cm\qk\iar\qk_port.h - $PROJ_DIR$\..\..\..\..\..\ports\arm-cm\qk\iar\qk_port.c - - $PROJ_DIR$\..\..\..\..\..\ports\arm-cm\qk\iar\qs_port.h - QS @@ -3157,17 +3323,11 @@ $PROJ_DIR$\..\..\..\..\..\src\qs\qs.c - - $PROJ_DIR$\..\..\..\..\..\src\qs\qs_64bit.c - - - $PROJ_DIR$\..\..\..\..\..\src\qs\qs_fp.c - $PROJ_DIR$\..\..\..\..\..\src\qs\qs_rx.c - $PROJ_DIR$\..\..\..\..\..\src\qs\qutest.c + $PROJ_DIR$\..\..\..\..\..\src\qs\qstamp.c diff --git a/examples/arm-cm/dpp_stm32f4-discovery/qk/main.c b/examples/arm-cm/dpp_stm32f4-discovery/qk/main.c deleted file mode 100644 index ab1e447f..00000000 --- a/examples/arm-cm/dpp_stm32f4-discovery/qk/main.c +++ /dev/null @@ -1,93 +0,0 @@ -/***************************************************************************** -* Product: DPP example -* Last updated for version 6.8.2 -* Last updated on 2020-07-17 -* -* Q u a n t u m L e a P s -* ------------------------ -* Modern Embedded Software -* -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* -* -*****************************************************************************/ -#include "qpc.h" -#include "dpp.h" -#include "bsp.h" - -Q_DEFINE_THIS_FILE - -static QTicker l_ticker0; -QActive *the_Ticker0 = &l_ticker0.super; - -/*..........................................................................*/ -int main() { - static QEvt const *tableQueueSto[N_PHILO]; - static QEvt const *philoQueueSto[N_PHILO][N_PHILO]; - static QSubscrList subscrSto[MAX_PUB_SIG]; - static QF_MPOOL_EL(TableEvt) smlPoolSto[2*N_PHILO]; /* small pool */ - uint8_t n; - - Philo_ctor(); /* instantiate all Philosopher active objects */ - Table_ctor(); /* instantiate the Table active object */ - QTicker_ctor(&l_ticker0, 0U); /* ticker AO for tick rate 0 */ - - QF_init(); /* initialize the framework and the underlying RT kernel */ - - /* initialize publish-subscribe... */ - QF_psInit(subscrSto, Q_DIM(subscrSto)); - - /* initialize event pools... */ - QF_poolInit(smlPoolSto, sizeof(smlPoolSto), sizeof(smlPoolSto[0])); - - /* initialize the Board Support Package - * NOTE: BSP_init() is called *after* initializing publish-subscribe and - * event pools, to make the system ready to accept SysTick interrupts. - * Unfortunately, the STM32Cube code that must be called from BSP, - * configures and starts SysTick. - */ - BSP_init(); - - QACTIVE_START(the_Ticker0, 1U, 0, 0, 0, 0, 0); - - /* start the active objects... */ - for (n = 0U; n < N_PHILO; ++n) { - QACTIVE_START(AO_Philo[n], /* AO to start */ - (uint_fast8_t)(n + 2), /* QP priority of the AO */ - philoQueueSto[n], /* event queue storage */ - Q_DIM(philoQueueSto[n]), /* queue length [events] */ - (void *)0, /* stack storage (not used) */ - 0U, /* size of the stack [bytes] */ - (QEvt *)0); /* initialization event */ - } - QACTIVE_START(AO_Table, /* AO to start */ - (uint_fast8_t)(N_PHILO + 2), /* QP priority of the AO */ - tableQueueSto, /* event queue storage */ - Q_DIM(tableQueueSto), /* queue length [events] */ - (void *)0, /* stack storage (not used) */ - 0U, /* size of the stack [bytes] */ - (QEvt *)0); /* initialization event */ - - return QF_run(); /* run the QF application */ -} - diff --git a/examples/arm-cm/dpp_stm32f4-discovery/qv/armclang/dpp-qv.sct b/examples/arm-cm/dpp_stm32f4-discovery/qv/armclang/dpp-qv.sct new file mode 100644 index 00000000..eb3902ad --- /dev/null +++ b/examples/arm-cm/dpp_stm32f4-discovery/qv/armclang/dpp-qv.sct @@ -0,0 +1,22 @@ +; ************************************************************* +; *** Scatter-Loading Description File generated by uVision *** +; +; Adapted by Quantum Leaps: +; moved STACK as the first section in RW_IRAM1 +; ************************************************************* + +LR_IROM1 0x08000000 0x00100000 { ; load region size_region + ER_IROM1 0x08000000 0x00100000 { ; load address = execution address + *.o (RESET, +First) + *(InRoot$$Sections) + .ANY (+RO) + .ANY (+XO) + } + RW_STACK 0x20000000 { ; <== Quantum Leaps + * (STACK, +First) + } + RW_IRAM1 +0 (0x00020000 - 2048) { ; NOTE: 2048 assumed for STACK size! + .ANY (+RW +ZI) + } +} + diff --git a/examples/arm-cm/dpp_stm32f4-discovery/qv/armclang/dpp-qv.uvoptx b/examples/arm-cm/dpp_stm32f4-discovery/qv/armclang/dpp-qv.uvoptx index f283a0cc..290003c0 100644 --- a/examples/arm-cm/dpp_stm32f4-discovery/qv/armclang/dpp-qv.uvoptx +++ b/examples/arm-cm/dpp_stm32f4-discovery/qv/armclang/dpp-qv.uvoptx @@ -8,9 +8,9 @@ *.c *.s*; *.src; *.a* - *.obj + *.obj; *.o *.lib - *.txt; *.h; *.inc + *.txt; *.h; *.inc; *.md *.plm *.cpp 0 @@ -103,7 +103,7 @@ 1 0 0 - 5 + 6 @@ -299,7 +299,7 @@ 1 0 0 - 5 + 6 @@ -495,7 +495,7 @@ 1 0 0 - 5 + 6 @@ -611,7 +611,7 @@ Application - 0 + 1 0 0 0 @@ -682,19 +682,7 @@ 0 0 0 - ..\..\..\..\..\include\qstamp.c - qstamp.c - 0 - 0 - - - 1 - 7 - 1 - 0 - 0 - 0 - ..\main.c + ..\..\main.c main.c 0 0 @@ -709,7 +697,7 @@ 0 2 - 8 + 7 2 0 0 @@ -721,7 +709,7 @@ 2 - 9 + 8 5 0 0 @@ -733,7 +721,7 @@ 2 - 10 + 9 5 0 0 @@ -745,7 +733,7 @@ 2 - 11 + 10 1 0 0 @@ -757,7 +745,7 @@ 2 - 12 + 11 5 0 0 @@ -769,7 +757,7 @@ 2 - 13 + 12 1 0 0 @@ -781,7 +769,7 @@ 2 - 14 + 13 1 0 0 @@ -793,7 +781,7 @@ 2 - 15 + 14 1 0 0 @@ -813,7 +801,7 @@ 0 3 - 16 + 15 1 0 0 @@ -825,7 +813,7 @@ 3 - 17 + 16 1 0 0 @@ -837,7 +825,7 @@ 3 - 18 + 17 1 0 0 @@ -849,7 +837,7 @@ 3 - 19 + 18 1 0 0 @@ -861,7 +849,7 @@ 3 - 20 + 19 1 0 0 @@ -873,7 +861,7 @@ 3 - 21 + 20 1 0 0 @@ -885,7 +873,7 @@ 3 - 22 + 21 1 0 0 @@ -897,7 +885,7 @@ 3 - 23 + 22 1 0 0 @@ -909,7 +897,7 @@ 3 - 24 + 23 1 0 0 @@ -921,7 +909,7 @@ 3 - 25 + 24 1 0 0 @@ -933,7 +921,7 @@ 3 - 26 + 25 1 0 0 @@ -945,7 +933,7 @@ 3 - 27 + 26 1 0 0 @@ -957,7 +945,7 @@ 3 - 28 + 27 1 0 0 @@ -971,61 +959,13 @@ QP_port - 0 + 1 0 0 0 4 - 29 - 5 - 0 - 0 - 0 - ..\..\..\..\..\ports\arm-cm\qv\armclang\qep_port.h - qep_port.h - 0 - 0 - - - 4 - 30 - 5 - 0 - 0 - 0 - ..\..\..\..\..\ports\arm-cm\qv\armclang\qf_port.h - qf_port.h - 0 - 0 - - - 4 - 31 - 5 - 0 - 0 - 0 - ..\..\..\..\..\ports\arm-cm\qv\armclang\qv_port.h - qv_port.h - 0 - 0 - - - 4 - 32 - 5 - 0 - 0 - 0 - ..\..\..\..\..\ports\arm-cm\qv\armclang\qs_port.h - qs_port.h - 0 - 0 - - - 4 - 33 + 28 1 0 0 @@ -1039,13 +979,13 @@ QS - 0 + 1 0 0 0 5 - 34 + 29 1 0 0 @@ -1057,31 +997,7 @@ 5 - 35 - 1 - 0 - 0 - 0 - ..\..\..\..\..\src\qs\qs_64bit.c - qs_64bit.c - 0 - 0 - - - 5 - 36 - 1 - 0 - 0 - 0 - ..\..\..\..\..\src\qs\qs_fp.c - qs_fp.c - 0 - 0 - - - 5 - 37 + 30 1 0 0 @@ -1093,13 +1009,13 @@ 5 - 38 + 31 1 0 0 0 - ..\..\..\..\..\src\qs\qutest.c - qutest.c + ..\..\..\..\..\src\qs\qstamp.c + qstamp.c 0 0 diff --git a/examples/arm-cm/dpp_stm32f4-discovery/qv/armclang/dpp-qv.uvprojx b/examples/arm-cm/dpp_stm32f4-discovery/qv/armclang/dpp-qv.uvprojx index be398b9e..b733243c 100644 --- a/examples/arm-cm/dpp_stm32f4-discovery/qv/armclang/dpp-qv.uvprojx +++ b/examples/arm-cm/dpp_stm32f4-discovery/qv/armclang/dpp-qv.uvprojx @@ -16,8 +16,8 @@ STM32F407VGTx STMicroelectronics - Keil.STM32F4xx_DFP.2.9.0 - http://www.keil.com/pack + Keil.STM32F4xx_DFP.2.17.0 + https://www.keil.com/pack/ IRAM(0x20000000,0x20000) IRAM2(0x10000000,0x10000) IROM(0x08000000,0x100000) CPUTYPE("Cortex-M4") FPU2 CLOCK(12000000) ELITTLE @@ -185,6 +185,7 @@ 0 2 0 + 0 1 0 8 @@ -351,7 +352,7 @@ 0 1 0 - 0 + 4 Stack_Size=2048 Heap_Size=16 @@ -360,7 +361,7 @@ - 1 + 0 0 0 0 @@ -369,7 +370,7 @@ 0x00000000 0x20000000 - + dpp-qv.sct --entry Reset_Handler @@ -407,15 +408,10 @@ 1 ..\..\table.c - - qstamp.c - 1 - ..\..\..\..\..\include\qstamp.c - main.c 1 - ..\main.c + ..\..\main.c @@ -537,26 +533,6 @@ QP_port - - qep_port.h - 5 - ..\..\..\..\..\ports\arm-cm\qv\armclang\qep_port.h - - - qf_port.h - 5 - ..\..\..\..\..\ports\arm-cm\qv\armclang\qf_port.h - - - qv_port.h - 5 - ..\..\..\..\..\ports\arm-cm\qv\armclang\qv_port.h - - - qs_port.h - 5 - ..\..\..\..\..\ports\arm-cm\qv\armclang\qs_port.h - qv_port.c 1 @@ -625,7 +601,7 @@ 2 2 2 - 2 + 0 @@ -641,25 +617,15 @@ 1 ..\..\..\..\..\src\qs\qs.c - - qs_64bit.c - 1 - ..\..\..\..\..\src\qs\qs_64bit.c - - - qs_fp.c - 1 - ..\..\..\..\..\src\qs\qs_fp.c - qs_rx.c 1 ..\..\..\..\..\src\qs\qs_rx.c - qutest.c + qstamp.c 1 - ..\..\..\..\..\src\qs\qutest.c + ..\..\..\..\..\src\qs\qstamp.c @@ -675,8 +641,8 @@ STM32F407VGTx STMicroelectronics - Keil.STM32F4xx_DFP.2.9.0 - http://www.keil.com/pack + Keil.STM32F4xx_DFP.2.17.0 + https://www.keil.com/pack/ IRAM(0x20000000,0x20000) IRAM2(0x10000000,0x10000) IROM(0x08000000,0x100000) CPUTYPE("Cortex-M4") FPU2 CLOCK(12000000) ELITTLE @@ -844,6 +810,7 @@ 0 2 0 + 0 1 0 8 @@ -1010,7 +977,7 @@ 0 1 0 - 0 + 4 Stack_Size=2048 Heap_Size=16 @@ -1019,7 +986,7 @@ - 1 + 0 0 0 0 @@ -1066,15 +1033,10 @@ 1 ..\..\table.c - - qstamp.c - 1 - ..\..\..\..\..\include\qstamp.c - main.c 1 - ..\main.c + ..\..\main.c @@ -1196,26 +1158,6 @@ QP_port - - qep_port.h - 5 - ..\..\..\..\..\ports\arm-cm\qv\armclang\qep_port.h - - - qf_port.h - 5 - ..\..\..\..\..\ports\arm-cm\qv\armclang\qf_port.h - - - qv_port.h - 5 - ..\..\..\..\..\ports\arm-cm\qv\armclang\qv_port.h - - - qs_port.h - 5 - ..\..\..\..\..\ports\arm-cm\qv\armclang\qs_port.h - qv_port.c 1 @@ -1284,7 +1226,7 @@ 2 2 2 - 2 + 0 @@ -1300,25 +1242,15 @@ 1 ..\..\..\..\..\src\qs\qs.c - - qs_64bit.c - 1 - ..\..\..\..\..\src\qs\qs_64bit.c - - - qs_fp.c - 1 - ..\..\..\..\..\src\qs\qs_fp.c - qs_rx.c 1 ..\..\..\..\..\src\qs\qs_rx.c - qutest.c + qstamp.c 1 - ..\..\..\..\..\src\qs\qutest.c + ..\..\..\..\..\src\qs\qstamp.c @@ -1328,14 +1260,14 @@ dpp-spy 0x4 ARM-ADS - 5060183::V5.06 update 2 (build 183)::ARMCC + 6160000::V6.16::ARMCLANG 1 STM32F407VGTx STMicroelectronics - Keil.STM32F4xx_DFP.2.9.0 - http://www.keil.com/pack + Keil.STM32F4xx_DFP.2.17.0 + https://www.keil.com/pack/ IRAM(0x20000000,0x20000) IRAM2(0x10000000,0x10000) IROM(0x08000000,0x100000) CPUTYPE("Cortex-M4") FPU2 CLOCK(12000000) ELITTLE @@ -1503,6 +1435,7 @@ 0 2 0 + 0 1 0 8 @@ -1654,7 +1587,7 @@ 0 - Q_SPY + Q_SPY,QF_ON_CONTEXT_SW ..\..;..\..\..\..\..\include;..\..\..\..\..\ports\arm-cm\qv\armclang;..\..\..\..\..\3rd_party\CMSIS\Include; ..\..\..\..\..\3rd_party\stm32f4-discovery; ..\..\..\..\..\3rd_party\stm32f4-discovery\inc @@ -1669,7 +1602,7 @@ 0 1 0 - 0 + 4 Stack_Size=2048 Heap_Size=16 @@ -1678,7 +1611,7 @@ - 1 + 0 0 0 0 @@ -1725,15 +1658,10 @@ 1 ..\..\table.c - - qstamp.c - 1 - ..\..\..\..\..\include\qstamp.c - main.c 1 - ..\main.c + ..\..\main.c @@ -1855,26 +1783,6 @@ QP_port - - qep_port.h - 5 - ..\..\..\..\..\ports\arm-cm\qv\armclang\qep_port.h - - - qf_port.h - 5 - ..\..\..\..\..\ports\arm-cm\qv\armclang\qf_port.h - - - qv_port.h - 5 - ..\..\..\..\..\ports\arm-cm\qv\armclang\qv_port.h - - - qs_port.h - 5 - ..\..\..\..\..\ports\arm-cm\qv\armclang\qs_port.h - qv_port.c 1 @@ -1890,25 +1798,15 @@ 1 ..\..\..\..\..\src\qs\qs.c - - qs_64bit.c - 1 - ..\..\..\..\..\src\qs\qs_64bit.c - - - qs_fp.c - 1 - ..\..\..\..\..\src\qs\qs_fp.c - qs_rx.c 1 ..\..\..\..\..\src\qs\qs_rx.c - qutest.c + qstamp.c 1 - ..\..\..\..\..\src\qs\qutest.c + ..\..\..\..\..\src\qs\qstamp.c diff --git a/examples/arm-cm/dpp_stm32f4-discovery/qv/bsp.c b/examples/arm-cm/dpp_stm32f4-discovery/qv/bsp.c index 5a28144c..8d875912 100644 --- a/examples/arm-cm/dpp_stm32f4-discovery/qv/bsp.c +++ b/examples/arm-cm/dpp_stm32f4-discovery/qv/bsp.c @@ -1,54 +1,50 @@ -/***************************************************************************** -* Product: "DPP" example on STM32F4-Discovery board, cooperative QV kernel -* Last updated for version 6.9.3 -* Last updated on 2021-03-03 -* -* Q u a n t u m L e a P s -* ------------------------ -* Modern Embedded Software -* -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* -* -*****************************************************************************/ -#include "qpc.h" -#include "dpp.h" -#include "bsp.h" +//============================================================================ +// Product: DPP example, STM32F4-Discovery board, QV kernel +// Last updated for version 7.3.0 +// Last updated on 2023-08-23 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. +// +// This program is open source software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Alternatively, this program may be distributed and modified under the +// terms of Quantum Leaps commercial licenses, which expressly supersede +// the GNU General Public License and are specifically designed for +// licensees interested in retaining the proprietary status of their code. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Contact information: +// +// +//============================================================================ +#include "qpc.h" // QP/C real-time embedded framework +#include "dpp.h" // DPP Application interface +#include "bsp.h" // Board Support Package -#include "stm32f4xx.h" /* CMSIS-compliant header file for the MCU used */ +#include "stm32f4xx.h" // CMSIS-compliant header file for the MCU used #include "stm32f4xx_exti.h" #include "stm32f4xx_gpio.h" #include "stm32f4xx_rcc.h" #include "stm32f4xx_usart.h" -/* add other drivers if necessary... */ +// add other drivers if necessary... -Q_DEFINE_THIS_FILE +Q_DEFINE_THIS_FILE // define the name of this file for assertions -/* ISRs defined in this BSP ------------------------------------------------*/ -void SysTick_Handler(void); -void USART2_IRQHandler(void); - -/* Local-scope defines -----------------------------------------------------*/ +// Local-scope defines ----------------------------------------------------- #define LED_GPIO_PORT GPIOD #define LED_GPIO_CLK RCC_AHB1Periph_GPIOD @@ -61,99 +57,149 @@ void USART2_IRQHandler(void); #define BTN_GPIO_CLK RCC_AHB1Periph_GPIOA #define BTN_B1 GPIO_Pin_0 -static uint32_t l_rnd; /* random seed */ +static uint32_t l_rndSeed; #ifdef Q_SPY static QSTimeCtr QS_tickTime_; static QSTimeCtr QS_tickPeriod_; - /* QSpy source IDs */ - static QSpyId const l_SysTick = { 0U }; + // QSpy source IDs + static QSpyId const l_SysTick_Handler = { 0U }; - enum AppRecords { /* application-specific trace records */ + enum AppRecords { // application-specific trace records PHILO_STAT = QS_USER, - COMMAND_STAT + PAUSED_STAT, + CONTEXT_SW, }; #endif -/* ISRs used in this project ===============================================*/ +//============================================================================ +// Error handler and ISRs... + +Q_NORETURN Q_onError(char const * const module, int_t const id) { + // NOTE: this implementation of the assertion handler is intended only + // for debugging and MUST be changed for deployment of the application + // (assuming that you ship your production code with assertions enabled). + Q_UNUSED_PAR(module); + Q_UNUSED_PAR(id); + QS_ASSERTION(module, id, 10000U); + +#ifndef NDEBUG + // for debugging, hang on in an endless loop... + for (;;) { + } +#endif + + NVIC_SystemReset(); +} +//............................................................................ +void assert_failed(char const * const module, int_t const id); // prototype +void assert_failed(char const * const module, int_t const id) { + Q_onError(module, id); +} + +// ISRs used in the application ========================================== + +void SysTick_Handler(void); // prototype void SysTick_Handler(void) { - /* state of the button debouncing, see below */ - static struct ButtonsDebouncing { + + QTIMEEVT_TICK_X(0U, &l_SysTick_Handler); // time events at rate 0 + + // Perform the debouncing of buttons. The algorithm for debouncing + // adapted from the book "Embedded Systems Dictionary" by Jack Ganssle + // and Michael Barr, page 71. + // + // state of the button debouncing + static struct { uint32_t depressed; uint32_t previous; } buttons = { 0U, 0U }; - uint32_t current; - uint32_t tmp; + + uint32_t current = BTN_GPIO_PORT->IDR; // read BTN GPIO + uint32_t tmp = buttons.depressed; // save the depressed buttons + buttons.depressed |= (buttons.previous & current); // set depressed + buttons.depressed &= (buttons.previous | current); // clear released + buttons.previous = current; // update the history + tmp ^= buttons.depressed; // changed debounced depressed + current = buttons.depressed; + + if ((tmp & BTN_B1) != 0U) { // debounced B1 state changed? + if ((current & BTN_B1) != 0U) { // is B1 depressed? + static QEvt const pauseEvt = QEVT_INITIALIZER(PAUSE_SIG); + QACTIVE_PUBLISH(&pauseEvt, &l_SysTick_Handler); + } + else { // the button is released + static QEvt const serveEvt = QEVT_INITIALIZER(SERVE_SIG); + QACTIVE_PUBLISH(&serveEvt, &l_SysTick_Handler); + } + } #ifdef Q_SPY - { - tmp = SysTick->CTRL; /* clear SysTick_CTRL_COUNTFLAG */ - QS_tickTime_ += QS_tickPeriod_; /* account for the clock rollover */ - } + tmp = SysTick->CTRL; // clear CTRL_COUNTFLAG + QS_tickTime_ += QS_tickPeriod_; // account for the clock rollover #endif - QTIMEEVT_TICK_X(0U, &l_SysTick); /* process time events for tick rate 0 */ - - /* Perform the debouncing of buttons. The algorithm for debouncing - * adapted from the book "Embedded Systems Dictionary" by Jack Ganssle - * and Michael Barr, page 71. - */ - current = BTN_GPIO_PORT->IDR; /* read BTN GPIO */ - tmp = buttons.depressed; /* save the debounced depressed buttons */ - buttons.depressed |= (buttons.previous & current); /* set depressed */ - buttons.depressed &= (buttons.previous | current); /* clear released */ - buttons.previous = current; /* update the history */ - tmp ^= buttons.depressed; /* changed debounced depressed */ - if ((tmp & BTN_B1) != 0U) { /* debounced B1 state changed? */ - if ((buttons.depressed & BTN_B1) != 0U) { /* is B1 depressed? */ - static QEvt const pauseEvt = { PAUSE_SIG, 0U, 0U}; - QACTIVE_PUBLISH(&pauseEvt, &l_SysTick); - } - else { /* the button is released */ - static QEvt const serveEvt = { SERVE_SIG, 0U, 0U}; - QACTIVE_PUBLISH(&serveEvt, &l_SysTick); - } - } QV_ARM_ERRATUM_838869(); } -/*..........................................................................*/ +//............................................................................ #ifdef Q_SPY -/* -* ISR for receiving bytes from the QSPY Back-End -* NOTE: This ISR is "QF-unaware" meaning that it does not interact with -* the QF/QK and is not disabled. Such ISRs don't need to call QK_ISR_ENTRY/ -* QK_ISR_EXIT and they cannot post or publish events. -*/ -void USART2_IRQHandler(void) { - if ((USART2->SR & USART_SR_RXNE) != 0) { +// ISR for receiving bytes from the QSPY Back-End +// NOTE: This ISR is "QF-unaware" meaning that it does not interact with +// the QF/QK and is not disabled. Such ISRs don't need to call +// QK_ISR_ENTRY/QK_ISR_EXIT and they cannot post or publish events. + +void USART2_IRQHandler(void); // prototype +void USART2_IRQHandler(void) { // used in QS-RX (kernel UNAWARE interrutp) + // is RX register NOT empty? + if ((USART2->SR & USART_SR_RXNE) != 0U) { uint32_t b = USART2->DR; QS_RX_PUT(b); } + QV_ARM_ERRATUM_838869(); } -#else -void USART2_IRQHandler(void) {} -#endif +#endif // Q_SPY +//............................................................................ +#ifdef QF_ON_CONTEXT_SW +// NOTE: the context-switch callback is called with interrupts DISABLED +void QF_onContextSw(QActive *prev, QActive *next) { + QS_BEGIN_INCRIT(CONTEXT_SW, 0U) // in critical section! + QS_OBJ(prev); + QS_OBJ(next); + QS_END_INCRIT() +} +#endif // QF_ON_CONTEXT_SW + +//============================================================================ +// BSP functions... -/* BSP functions ===========================================================*/ void BSP_init(void) { - GPIO_InitTypeDef GPIO_struct; + // Configure the MPU to prevent NULL-pointer dereferencing ... + MPU->RBAR = 0x0U // base address (NULL) + | MPU_RBAR_VALID_Msk // valid region + | (MPU_RBAR_REGION_Msk & 7U); // region #7 + MPU->RASR = (7U << MPU_RASR_SIZE_Pos) // 2^(7+1) region + | (0x0U << MPU_RASR_AP_Pos) // no-access region + | MPU_RASR_ENABLE_Msk; // region enable + MPU->CTRL = MPU_CTRL_PRIVDEFENA_Msk // enable background region + | MPU_CTRL_ENABLE_Msk; // enable the MPU + __ISB(); + __DSB(); - /* NOTE: SystemInit() already called from the startup code - * but SystemCoreClock needs to be updated - */ + // NOTE: SystemInit() has been already called from the startup code + // but SystemCoreClock needs to be updated SystemCoreClockUpdate(); - /* NOTE The VFP (hardware Floating Point) unit is configured by QV-port */ + // NOTE The VFP (Floating Point Unit) unit is configured by QK-port - /* Initialize thr port for the LEDs */ + // Initialize thr port for the LEDs RCC_AHB1PeriphClockCmd(LED_GPIO_CLK , ENABLE); - /* GPIO Configuration for the LEDs... */ + // GPIO Configuration for the LEDs... + GPIO_InitTypeDef GPIO_struct; GPIO_struct.GPIO_Mode = GPIO_Mode_OUT; GPIO_struct.GPIO_OType = GPIO_OType_PP; GPIO_struct.GPIO_PuPd = GPIO_PuPd_UP; @@ -161,24 +207,24 @@ void BSP_init(void) { GPIO_struct.GPIO_Pin = LED3_PIN; GPIO_Init(LED_GPIO_PORT, &GPIO_struct); - LED_GPIO_PORT->BSRRH = LED3_PIN; /* turn LED off */ + LED_GPIO_PORT->BSRRH = LED3_PIN; // turn LED off GPIO_struct.GPIO_Pin = LED4_PIN; GPIO_Init(LED_GPIO_PORT, &GPIO_struct); - LED_GPIO_PORT->BSRRH = LED4_PIN; /* turn LED off */ + LED_GPIO_PORT->BSRRH = LED4_PIN; // turn LED off GPIO_struct.GPIO_Pin = LED5_PIN; GPIO_Init(LED_GPIO_PORT, &GPIO_struct); - LED_GPIO_PORT->BSRRH = LED5_PIN; /* turn LED off */ + LED_GPIO_PORT->BSRRH = LED5_PIN; // turn LED off GPIO_struct.GPIO_Pin = LED6_PIN; GPIO_Init(LED_GPIO_PORT, &GPIO_struct); - LED_GPIO_PORT->BSRRH = LED6_PIN; /* turn LED off */ + LED_GPIO_PORT->BSRRH = LED6_PIN; // turn LED off - /* Initialize thr port for Button */ + // Initialize thr port for Button RCC_AHB1PeriphClockCmd(BTN_GPIO_CLK , ENABLE); - /* GPIO Configuration for the Button... */ + // GPIO Configuration for the Button... GPIO_struct.GPIO_Pin = BTN_B1; GPIO_struct.GPIO_Mode = GPIO_Mode_IN; GPIO_struct.GPIO_OType = GPIO_OType_PP; @@ -186,190 +232,231 @@ void BSP_init(void) { GPIO_struct.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(BTN_GPIO_PORT, &GPIO_struct); - /* seed the random number generator */ - BSP_randomSeed(1234U); + BSP_randomSeed(1234U); // seed the random number generator - if (QS_INIT((void *)0) == 0U) { /* initialize the QS software tracing */ + // initialize the QS software tracing... + if (!QS_INIT((void *)0)) { Q_ERROR(); } - QS_OBJ_DICTIONARY(&l_SysTick); - QS_USR_DICTIONARY(PHILO_STAT); - QS_USR_DICTIONARY(COMMAND_STAT); - /* setup the QS filters... */ - QS_GLB_FILTER(QS_SM_RECORDS); /* state machine records */ - QS_GLB_FILTER(QS_AO_RECORDS); /* active object records */ - QS_GLB_FILTER(QS_UA_RECORDS); /* all user records */ + // dictionaries... + QS_OBJ_DICTIONARY(&l_SysTick_Handler); + QS_USR_DICTIONARY(PHILO_STAT); + QS_USR_DICTIONARY(PAUSED_STAT); + QS_USR_DICTIONARY(CONTEXT_SW); + + QS_ONLY(produce_sig_dict()); + + // setup the QS filters... + QS_GLB_FILTER(QS_ALL_RECORDS); // all records + QS_GLB_FILTER(-QS_QF_TICK); // exclude the clock tick } -/*..........................................................................*/ -void BSP_ledOn(void) { - LED_GPIO_PORT->BSRRL = LED6_PIN; +//............................................................................ +void BSP_start(void) { + // initialize event pools + static QF_MPOOL_EL(TableEvt) smlPoolSto[2*N_PHILO]; + QF_poolInit(smlPoolSto, sizeof(smlPoolSto), sizeof(smlPoolSto[0])); + + // initialize publish-subscribe + static QSubscrList subscrSto[MAX_PUB_SIG]; + QActive_psInit(subscrSto, Q_DIM(subscrSto)); + + // instantiate and start AOs/threads... + + static QEvt const *philoQueueSto[N_PHILO][10]; + for (uint8_t n = 0U; n < N_PHILO; ++n) { + Philo_ctor(n); + QACTIVE_START(AO_Philo[n], + n + 3U, // QF-prio. + philoQueueSto[n], // event queue storage + Q_DIM(philoQueueSto[n]), // queue length [events] + (void *)0, 0U, // no stack storage + (void *)0); // no initialization param + } + + static QEvt const *tableQueueSto[N_PHILO]; + Table_ctor(); + QACTIVE_START(AO_Table, + N_PHILO + 7U, // QP prio. of the AO + tableQueueSto, // event queue storage + Q_DIM(tableQueueSto), // queue length [events] + (void *)0, 0U, // no stack storage + (void *)0); // no initialization param } -/*..........................................................................*/ -void BSP_ledOff(void) { - LED_GPIO_PORT->BSRRH = LED6_PIN; -} -/*..........................................................................*/ +//............................................................................ void BSP_displayPhilStat(uint8_t n, char const *stat) { - (void)n; + Q_UNUSED_PAR(n); if (stat[0] == 'h') { - LED_GPIO_PORT->BSRRL = LED3_PIN; /* turn LED on */ + LED_GPIO_PORT->BSRRL = LED3_PIN; // turn LED on } else { - LED_GPIO_PORT->BSRRH = LED3_PIN; /* turn LED off */ + LED_GPIO_PORT->BSRRH = LED3_PIN; // turn LED off } if (stat[0] == 'e') { - LED_GPIO_PORT->BSRRL = LED5_PIN; /* turn LED on */ + LED_GPIO_PORT->BSRRL = LED5_PIN; // turn LED on } else { - LED_GPIO_PORT->BSRRH = LED5_PIN; /* turn LED off */ + LED_GPIO_PORT->BSRRH = LED5_PIN; // turn LED off } - QS_BEGIN_ID(PHILO_STAT, AO_Philo[n]->prio) /* app-specific record */ - QS_U8(1, n); /* Philosopher number */ - QS_STR(stat); /* Philosopher status */ - QS_END() /* application-specific record end */ + // app-specific trace record... + QS_BEGIN_ID(PHILO_STAT, AO_Table->prio) + QS_U8(1, n); // Philosopher number + QS_STR(stat); // Philosopher status + QS_END() } -/*..........................................................................*/ -void BSP_displayPaused(uint8_t paused) { +//............................................................................ +void BSP_displayPaused(uint8_t const paused) { if (paused) { - LED_GPIO_PORT->BSRRL = LED4_PIN; /* turn LED on */ + LED_GPIO_PORT->BSRRL = LED4_PIN; // turn LED on } else { - LED_GPIO_PORT->BSRRH = LED4_PIN; /* turn LED off */ + LED_GPIO_PORT->BSRRH = LED4_PIN; // turn LED off } -} -/*..........................................................................*/ -uint32_t BSP_random(void) { /* a very cheap pseudo-random-number generator */ - uint32_t rnd; - /* Some flating point code is to exercise the FPU... */ + // application-specific trace record + QS_BEGIN_ID(PAUSED_STAT, AO_Table->prio) + QS_U8(1, paused); // Paused status + QS_END() +} +//............................................................................ +void BSP_randomSeed(uint32_t seed) { + l_rndSeed = seed; +} +//............................................................................ +uint32_t BSP_random(void) { // a very cheap pseudo-random-number generator + + // Some flating point code is to exercise the FPU... float volatile x = 3.1415926F; x = x + 2.7182818F; - /* "Super-Duper" Linear Congruential Generator (LCG) - * LCG(2^32, 3*7*11*13*23, 0, seed) - */ - rnd = l_rnd * (3U*7U*11U*13U*23U); - l_rnd = rnd; /* set for the next time */ + // "Super-Duper" Linear Congruential Generator (LCG) + // LCG(2^32, 3*7*11*13*23, 0, seed) + // + uint32_t rnd = l_rndSeed * (3U*7U*11U*13U*23U); + l_rndSeed = rnd; // set for the next time - return (rnd >> 8); + return (rnd >> 8U); } -/*..........................................................................*/ -void BSP_randomSeed(uint32_t seed) { - l_rnd = seed; +//............................................................................ +void BSP_ledOn(void) { + LED_GPIO_PORT->BSRRL = LED6_PIN; } -/*..........................................................................*/ +//............................................................................ +void BSP_ledOff(void) { + LED_GPIO_PORT->BSRRH = LED6_PIN; +} +//............................................................................ void BSP_terminate(int16_t result) { - (void)result; + Q_UNUSED_PAR(result); } -/* QF callbacks ============================================================*/ +//============================================================================ +// QF callbacks... void QF_onStartup(void) { - /* set up the SysTick timer to fire at BSP_TICKS_PER_SEC rate */ + // set up the SysTick timer to fire at BSP_TICKS_PER_SEC rate SysTick_Config(SystemCoreClock / BSP_TICKS_PER_SEC); - /* assign all priority bits for preemption-prio. and none to sub-prio. */ + // assign all priority bits for preemption-prio. and none to sub-prio. NVIC_SetPriorityGrouping(0U); - /* !!!!!!!!!!!!!!!!!!!!!!!!!!!! CAUTION !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - * Assign a priority to EVERY ISR explicitly, see NOTE00. - * DO NOT LEAVE THE ISR PRIORITIES AT THE DEFAULT VALUE! - */ - /* kernel UNAWARE interrupts, see NOTE00 */ - NVIC_SetPriority(USART2_IRQn, 0U); - /* ... */ + // set priorities of ALL ISRs used in the system, see NOTE1 + NVIC_SetPriority(USART2_IRQn, 0U); // kernel UNAWARE interrupt + NVIC_SetPriority(SysTick_IRQn, QF_AWARE_ISR_CMSIS_PRI + 1U); + // ... - /* kernel AWARE interrupts, see NOTE00 */ - NVIC_SetPriority(SysTick_IRQn, QF_AWARE_ISR_CMSIS_PRI); - /* ... */ - - /* enable IRQs... */ + // enable IRQs... #ifdef Q_SPY - NVIC_EnableIRQ(USART2_IRQn); /* USART2 interrupt used for QS-RX */ + NVIC_EnableIRQ(USART2_IRQn); // USART2 interrupt used for QS-RX #endif } -/*..........................................................................*/ +//............................................................................ void QF_onCleanup(void) { } -/*..........................................................................*/ -void QV_onIdle(void) { /* CATION: called with interrupts DISABLED, NOTE01 */ - LED_GPIO_PORT->BSRRL = LED6_PIN; /* turn LED on */ - __NOP(); /* wait a little to actually see the LED glow */ +//............................................................................ +void QV_onIdle(void) { // CATION: called with interrupts DISABLED, see NOTE0 + + // toggle an LED on and then off (not enough LEDs, see NOTE02) + LED_GPIO_PORT->BSRRL = LED6_PIN; // turn LED on + __NOP(); // wait a little to actually see the LED glow __NOP(); __NOP(); __NOP(); - LED_GPIO_PORT->BSRRH = LED6_PIN; /* turn LED off */ + LED_GPIO_PORT->BSRRH = LED6_PIN; // turn LED off #ifdef Q_SPY + // interrupts still disabled + QS_rxParse(); // parse all the received bytes QF_INT_ENABLE(); - QS_rxParse(); /* parse all the received bytes */ - - if ((USART2->SR & USART_FLAG_TXE) != 0) { /* TXE empty? */ - uint16_t b; + QF_CRIT_EXIT_NOP(); + if ((USART2->SR & USART_FLAG_TXE) != 0) { // TXE empty? QF_INT_DISABLE(); - b = QS_getByte(); + uint16_t b = QS_getByte(); QF_INT_ENABLE(); - if (b != QS_EOD) { /* not End-Of-Data? */ - USART2->DR = (b & 0xFFU); /* put into the DR register */ + if (b != QS_EOD) { // not End-Of-Data? + USART2->DR = b; // put into the DR register } } #elif defined NDEBUG - /* Put the CPU and peripherals to the low-power mode. - * you might need to customize the clock management for your application, - * see the datasheet for your particular Cortex-M MCU. - */ - /* !!!CAUTION!!! - * The WFI instruction stops the CPU clock, which unfortunately disables - * the JTAG port, so the ST-Link debugger can no longer connect to the - * board. For that reason, the call to __WFI() has to be used with CAUTION. - * - * NOTE: If you find your board "frozen" like this, strap BOOT0 to VDD and - * reset the board, then connect with ST-Link Utilities and erase the part. - * The trick with BOOT(0) is that it gets the part to run the System Loader - * instead of your broken code. When done disconnect BOOT0, and start over. - */ - //QV_CPU_SLEEP(); /* atomically go to sleep and enable interrupts */ - QF_INT_ENABLE(); /* just enable interrupts */ + // Put the CPU and peripherals to the low-power mode. + // you might need to customize the clock management for your application, + // see the datasheet for your particular Cortex-M MCU. + // + // !!!CAUTION!!! + // The WFI instruction stops the CPU clock, which unfortunately disables + // the JTAG port, so the ST-Link debugger can no longer connect to the + // board. For that reason, the call to __WFI() has to be used with CAUTION. + // + // NOTE: If you find your board "frozen" like this, strap BOOT0 to VDD and + // reset the board, then connect with ST-Link Utilities and erase the part. + // The trick with BOOT(0) is that it gets the part to run the System Loader + // instead of your broken code. When done disconnect BOOT0, and start over. + // + //QV_CPU_SLEEP(); // atomically go to sleep and enable interrupts + QF_INT_ENABLE(); // for now, just enable interrupts #else - QF_INT_ENABLE(); /* just enable interrupts */ + QF_INT_ENABLE(); // just enable interrupts #endif } -/*..........................................................................*/ -Q_NORETURN Q_onAssert(char const * const module, int_t const loc) { - /* - * NOTE: add here your application-specific error handling - */ - (void)module; - (void)loc; - QS_ASSERTION(module, loc, 10000U); /* report assertion to QS */ - NVIC_SystemReset(); -} - -/* QS callbacks ============================================================*/ +//============================================================================ +// QS callbacks... #ifdef Q_SPY -/*..........................................................................*/ -uint8_t QS_onStartup(void const *arg) { - static uint8_t qsBuf[2*1024]; /* buffer for QS-TX channel */ - static uint8_t qsRxBuf[100]; /* buffer for QS-RX channel */ - GPIO_InitTypeDef GPIO_struct; - USART_InitTypeDef USART_struct; - (void)arg; /* avoid the "unused parameter" compiler warning */ - QS_initBuf(qsBuf, sizeof(qsBuf)); +//............................................................................ +#define __DIV(__PCLK, __BAUD) (((__PCLK / 4) *25)/(__BAUD)) +#define __DIVMANT(__PCLK, __BAUD) (__DIV(__PCLK, __BAUD)/100) +#define __DIVFRAQ(__PCLK, __BAUD) \ + (((__DIV(__PCLK, __BAUD) - (__DIVMANT(__PCLK, __BAUD) * 100)) \ + * 16 + 50) / 100) +#define __USART_BRR(__PCLK, __BAUD) \ + ((__DIVMANT(__PCLK, __BAUD) << 4)|(__DIVFRAQ(__PCLK, __BAUD) & 0x0F)) + +// USART2 pins PA.2 and PA.3 +#define USART2_TX_PIN 2U +#define USART2_RX_PIN 3U + +//............................................................................ +uint8_t QS_onStartup(void const *arg) { + Q_UNUSED_PAR(arg); + + static uint8_t qsTxBuf[2*1024]; // buffer for QS-TX channel + QS_initBuf(qsTxBuf, sizeof(qsTxBuf)); + + static uint8_t qsRxBuf[100]; // buffer for QS-RX channel QS_rxInitBuf(qsRxBuf, sizeof(qsRxBuf)); - /* enable peripheral clock for USART2 */ + // enable peripheral clock for USART2 RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE); - /* GPIOA clock enable */ + // GPIOA clock enable RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); - /* GPIOA Configuration: USART2 TX on PA2 and RX on PA3 */ + // GPIOA Configuration: USART2 TX on PA2 and RX on PA3 + GPIO_InitTypeDef GPIO_struct; GPIO_struct.GPIO_Pin = GPIO_Pin_2 | GPIO_Pin_3; GPIO_struct.GPIO_Mode = GPIO_Mode_AF; GPIO_struct.GPIO_Speed = GPIO_Speed_50MHz; @@ -377,10 +464,11 @@ uint8_t QS_onStartup(void const *arg) { GPIO_struct.GPIO_PuPd = GPIO_PuPd_UP ; GPIO_Init(GPIOA, &GPIO_struct); - /* Connect USART2 pins to AF2 */ - GPIO_PinAFConfig(GPIOA, GPIO_PinSource2, GPIO_AF_USART2); /* TX = PA2 */ - GPIO_PinAFConfig(GPIOA, GPIO_PinSource3, GPIO_AF_USART2); /* RX = PA3 */ + // Connect USART2 pins to AF2 + GPIO_PinAFConfig(GPIOA, GPIO_PinSource2, GPIO_AF_USART2); // TX = PA2 + GPIO_PinAFConfig(GPIOA, GPIO_PinSource3, GPIO_AF_USART2); // RX = PA3 + USART_InitTypeDef USART_struct; USART_struct.USART_BaudRate = 115200; USART_struct.USART_WordLength = USART_WordLength_8b; USART_struct.USART_StopBits = USART_StopBits_1; @@ -389,100 +477,95 @@ uint8_t QS_onStartup(void const *arg) { USART_struct.USART_Mode = USART_Mode_Tx | USART_Mode_Rx; USART_Init(USART2, &USART_struct); - USART_ITConfig(USART2, USART_IT_RXNE, ENABLE); /* enable RX interrupt */ - USART_Cmd(USART2, ENABLE); /* enable USART2 */ + USART_ITConfig(USART2, USART_IT_RXNE, ENABLE); // enable RX interrupt + USART_Cmd(USART2, ENABLE); // enable USART2 QS_tickPeriod_ = SystemCoreClock / BSP_TICKS_PER_SEC; - QS_tickTime_ = QS_tickPeriod_; /* to start the timestamp at zero */ + QS_tickTime_ = QS_tickPeriod_; // to start the timestamp at zero - return 1U; /* return success */ + return 1U; // return success } -/*..........................................................................*/ +//............................................................................ void QS_onCleanup(void) { } -/*..........................................................................*/ -QSTimeCtr QS_onGetTime(void) { /* NOTE: invoked with interrupts DISABLED */ - if ((SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk) == 0) { /* not set? */ +//............................................................................ +QSTimeCtr QS_onGetTime(void) { // NOTE: invoked with interrupts DISABLED + if ((SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk) == 0U) { // not set? return QS_tickTime_ - (QSTimeCtr)SysTick->VAL; } - else { /* the rollover occured, but the SysTick_ISR did not run yet */ + else { // the rollover occured, but the SysTick_ISR did not run yet return QS_tickTime_ + QS_tickPeriod_ - (QSTimeCtr)SysTick->VAL; } } -/*..........................................................................*/ +//............................................................................ void QS_onFlush(void) { - uint16_t b; - - QF_INT_DISABLE(); - while ((b = QS_getByte()) != QS_EOD) { /* while not End-Of-Data... */ - QF_INT_ENABLE(); - while ((USART2->SR & USART_FLAG_TXE) == 0) { /* while TXE not empty */ - } - USART2->DR = (b & 0xFFU); /* put into the DR register */ + for (;;) { QF_INT_DISABLE(); + uint16_t b = QS_getByte(); + if (b != QS_EOD) { + while ((USART2->SR & USART_FLAG_TXE) == 0U) { // while TXE not empty + QF_INT_ENABLE(); + QF_CRIT_EXIT_NOP(); + + QF_INT_DISABLE(); + } + USART2->DR = b; // put into the DR register + QF_INT_ENABLE(); + } + else { + QF_INT_ENABLE(); + break; + } } - QF_INT_ENABLE(); } -/*..........................................................................*/ -/*! callback function to reset the target (to be implemented in the BSP) */ +//............................................................................ +//! callback function to reset the target (to be implemented in the BSP) void QS_onReset(void) { NVIC_SystemReset(); } -/*..........................................................................*/ -/*! callback function to execute a user command (to be implemented in BSP) */ +//............................................................................ +//! callback function to execute a user command void QS_onCommand(uint8_t cmdId, uint32_t param1, uint32_t param2, uint32_t param3) { - void assert_failed(char const *module, int loc); - (void)cmdId; - (void)param1; - (void)param2; - (void)param3; - QS_BEGIN_ID(COMMAND_STAT, 0U) /* app-specific record */ - QS_U8(2, cmdId); - QS_U32(8, param1); - QS_U32(8, param2); - QS_U32(8, param3); - QS_END() - - if (cmdId == 10U) { - Q_ERROR(); - } - else if (cmdId == 11U) { - assert_failed("QS_onCommand", 123); - } + Q_UNUSED_PAR(cmdId); + Q_UNUSED_PAR(param1); + Q_UNUSED_PAR(param2); + Q_UNUSED_PAR(param3); } -#endif /* Q_SPY */ -/*--------------------------------------------------------------------------*/ +#endif // Q_SPY +//---------------------------------------------------------------------------- -/***************************************************************************** -* NOTE00: -* The QF_AWARE_ISR_CMSIS_PRI constant from the QF port specifies the highest -* ISR priority that is disabled by the QF framework. The value is suitable -* for the NVIC_SetPriority() CMSIS function. -* -* Only ISRs prioritized at or below the QF_AWARE_ISR_CMSIS_PRI level (i.e., -* with the numerical values of priorities equal or higher than -* QF_AWARE_ISR_CMSIS_PRI) are allowed to call any QF services. These ISRs -* are "QF-aware". -* -* Conversely, any ISRs prioritized above the QF_AWARE_ISR_CMSIS_PRI priority -* level (i.e., with the numerical values of priorities less than -* QF_AWARE_ISR_CMSIS_PRI) are never disabled and are not aware of the kernel. -* Such "QF-unaware" ISRs cannot call any QF services. The only mechanism -* by which a "QF-unaware" ISR can communicate with the QF framework is by -* triggering a "QF-aware" ISR, which can post/publish events. -* -* NOTE01: -* The QV_onIdle() callback is called with interrupts disabled, because the -* determination of the idle condition might change by any interrupt posting -* an event. QV_onIdle() must internally enable interrupts, ideally -* atomically with putting the CPU to the power-saving mode. -* -* NOTE02: -* One of the LEDs is used to visualize the idle loop activity. The brightness -* of the LED is proportional to the frequency of invcations of the idle loop. -* Please note that the LED is toggled with interrupts locked, so no interrupt -* execution time contributes to the brightness of the User LED. -*/ +//============================================================================ +// NOTE0: +// The QV_onIdle() callback is called with interrupts disabled, because the +// determination of the idle condition might change by any interrupt posting +// an event. QV_onIdle() must internally enable interrupts, ideally +// atomically with putting the CPU to the power-saving mode. +// +// NOTE1: +// The QF_AWARE_ISR_CMSIS_PRI constant from the QF port specifies the highest +// ISR priority that is disabled by the QF framework. The value is suitable +// for the NVIC_SetPriority() CMSIS function. +// +// Only ISRs prioritized at or below the QF_AWARE_ISR_CMSIS_PRI level (i.e., +// with the numerical values of priorities equal or higher than +// QF_AWARE_ISR_CMSIS_PRI) are allowed to call the QV_ISR_ENTRY/ +// QV_ISR_ENTRY macros or any other QF/QV services. These ISRs are +// "QF-aware". +// +// Conversely, any ISRs prioritized above the QF_AWARE_ISR_CMSIS_PRI priority +// level (i.e., with the numerical values of priorities less than +// QF_AWARE_ISR_CMSIS_PRI) are never disabled and are not aware of the kernel. +// Such "QF-unaware" ISRs cannot call ANY QF/QV services. In particular they +// can NOT call the macros QV_ISR_ENTRY/QV_ISR_ENTRY. The only mechanism +// by which a "QF-unaware" ISR can communicate with the QF framework is by +// triggering a "QF-aware" ISR, which can post/publish events. +// +// NOTE2: +// The User LED is used to visualize the idle loop activity. The brightness +// of the LED is proportional to the frequency of the idle loop. +// Please note that the LED is toggled with interrupts locked, so no interrupt +// execution time contributes to the brightness of the User LED. +// diff --git a/examples/arm-cm/dpp_stm32f4-discovery/qv/gnu/Makefile b/examples/arm-cm/dpp_stm32f4-discovery/qv/gnu/Makefile index 393d3ed8..1d14d399 100644 --- a/examples/arm-cm/dpp_stm32f4-discovery/qv/gnu/Makefile +++ b/examples/arm-cm/dpp_stm32f4-discovery/qv/gnu/Makefile @@ -1,13 +1,13 @@ ############################################################################## # Product: Makefile for QP/C on STM32F4-Discovery, QV kernel, GNU-ARM -# Last Updated for Version: 7.0.1 -# Date of the Last Update: 2022-05-23 +# Last Updated for Version: 7.3.0 +# Date of the Last Update: 2023-08-24 # # Q u a n t u m L e a P s # ------------------------ # Modern Embedded Software # -# Copyright (C) 2005-2021 Quantum Leaps, LLC. All rights reserved. +# Copyright (C) 2005 Quantum Leaps, LLC. # # This program is open source software: you can redistribute it and/or # modify it under the terms of the GNU General Public License as published @@ -179,7 +179,7 @@ MKDIR := mkdir RM := rm #----------------------------------------------------------------------------- -# build options for various configurations for ARM Cortex-M4F +# build options for various configurations for ARM Cortex-M # # combine all the soruces... @@ -266,7 +266,7 @@ $(TARGET_BIN): $(TARGET_ELF) $(BIN) -O binary $< $@ $(TARGET_ELF) : $(ASM_OBJS_EXT) $(C_OBJS_EXT) $(CPP_OBJS_EXT) - $(CC) $(CFLAGS) $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o + $(CC) $(CFLAGS) $(QPC)/src/qs/qstamp.c -o $(BIN_DIR)/qstamp.o $(LINK) $(LINKFLAGS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) $(BIN_DIR)/%.d : %.c diff --git a/examples/arm-cm/dpp_stm32f4-discovery/qv/iar/dpp-qv.ewd b/examples/arm-cm/dpp_stm32f4-discovery/qv/iar/dpp-qv.ewd index f3025db5..22af80f9 100644 --- a/examples/arm-cm/dpp_stm32f4-discovery/qv/iar/dpp-qv.ewd +++ b/examples/arm-cm/dpp_stm32f4-discovery/qv/iar/dpp-qv.ewd @@ -11,7 +11,7 @@ C-SPY 2 - 28 + 32 1 1 - - + + + + + @@ -486,7 +498,7 @@ IJET_ID 2 - 8 + 9 1 1 + + + + + + + + + + + + + @@ -916,7 +980,7 @@ LMIFTDI_ID 2 - 2 + 3 1 1 + + + + + + + NULINK_ID + 2 + + 0 + 1 + 1 + + + @@ -974,7 +1072,7 @@ STLINK_ID 2 - 4 + 8 1 1 + + + + @@ -1185,7 +1300,7 @@ XDS100_ID 2 - 6 + 9 1 1 + + + + @@ -1362,6 +1493,18 @@ $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin 0 + + $TOOLKIT_DIR$\plugins\rtos\FreeRtos\FreeRtosArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin2.ENU.ewplugin + 0 + $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin 0 @@ -1371,11 +1514,15 @@ 0 - $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9.ewplugin 0 - $TOOLKIT_DIR$\plugins\rtos\TI-RTOS\tirtosplugin.ewplugin + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9BE.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin 0 @@ -1391,11 +1538,11 @@ 0 - $EW_DIR$\common\plugins\CodeCoverage\CodeCoverage.ENU.ewplugin - 1 + $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + 0 - $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + $EW_DIR$\common\plugins\TargetAccessServer\TargetAccessServer.ENU.ewplugin 0 @@ -1414,7 +1561,7 @@ C-SPY 2 - 28 + 32 1 0 - - + + + + + @@ -1889,7 +2048,7 @@ IJET_ID 2 - 8 + 9 1 0 + + + + + + + + + + + + + @@ -2319,7 +2530,7 @@ LMIFTDI_ID 2 - 2 + 3 1 0 + + + + + + + NULINK_ID + 2 + + 0 + 1 + 0 + + + @@ -2377,7 +2622,7 @@ STLINK_ID 2 - 4 + 8 1 0 + + + + @@ -2588,7 +2850,7 @@ XDS100_ID 2 - 6 + 9 1 0 + + + + @@ -2765,6 +3043,18 @@ $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin 0 + + $TOOLKIT_DIR$\plugins\rtos\FreeRtos\FreeRtosArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin2.ENU.ewplugin + 0 + $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin 0 @@ -2774,11 +3064,15 @@ 0 - $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9.ewplugin 0 - $TOOLKIT_DIR$\plugins\rtos\TI-RTOS\tirtosplugin.ewplugin + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9BE.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin 0 @@ -2794,11 +3088,11 @@ 0 - $EW_DIR$\common\plugins\CodeCoverage\CodeCoverage.ENU.ewplugin - 1 + $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + 0 - $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + $EW_DIR$\common\plugins\TargetAccessServer\TargetAccessServer.ENU.ewplugin 0 @@ -2817,7 +3111,7 @@ C-SPY 2 - 28 + 32 1 1 - - + + + + + @@ -3292,7 +3598,7 @@ IJET_ID 2 - 8 + 9 1 1 + + + + + + + + + + + + + @@ -3722,7 +4080,7 @@ LMIFTDI_ID 2 - 2 + 3 1 1 + + + + + + + NULINK_ID + 2 + + 0 + 1 + 1 + + + @@ -3780,7 +4172,7 @@ STLINK_ID 2 - 4 + 8 1 1 + + + + @@ -3991,7 +4400,7 @@ XDS100_ID 2 - 6 + 9 1 1 + + + + @@ -4168,6 +4593,18 @@ $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin 0 + + $TOOLKIT_DIR$\plugins\rtos\FreeRtos\FreeRtosArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin2.ENU.ewplugin + 0 + $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin 0 @@ -4177,11 +4614,15 @@ 0 - $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9.ewplugin 0 - $TOOLKIT_DIR$\plugins\rtos\TI-RTOS\tirtosplugin.ewplugin + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9BE.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin 0 @@ -4197,11 +4638,11 @@ 0 - $EW_DIR$\common\plugins\CodeCoverage\CodeCoverage.ENU.ewplugin - 1 + $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + 0 - $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + $EW_DIR$\common\plugins\TargetAccessServer\TargetAccessServer.ENU.ewplugin 0 diff --git a/examples/arm-cm/dpp_stm32f4-discovery/qv/iar/dpp-qv.ewp b/examples/arm-cm/dpp_stm32f4-discovery/qv/iar/dpp-qv.ewp index e76013f3..91cd5a6c 100644 --- a/examples/arm-cm/dpp_stm32f4-discovery/qv/iar/dpp-qv.ewp +++ b/examples/arm-cm/dpp_stm32f4-discovery/qv/iar/dpp-qv.ewp @@ -11,9 +11,13 @@ General 3 - 28 + 35 1 1 + - - - - - + + + + + + + + ICCARM 2 - 34 + 37 1 1 - - - + + AARM 2 - 10 + 11 1 1 + @@ -657,13 +670,9 @@ 0 + inputOutputBased - - BICOMP - 0 - - BUILDACTION 1 @@ -676,17 +685,13 @@ ILINK 0 - 20 + 27 1 1 - + + + + + + + + + + + + + + + @@ -1011,11 +1076,6 @@ - - BILINK - 0 - - Coder 0 @@ -1032,9 +1092,13 @@ General 3 - 28 + 35 1 0 + - - - - - + + + + + + + + ICCARM 2 - 34 + 37 1 0 - - - + + AARM 2 - 10 + 11 1 0 + @@ -1678,13 +1751,9 @@ 0 + inputOutputBased - - BICOMP - 0 - - BUILDACTION 1 @@ -1697,17 +1766,13 @@ ILINK 0 - 20 + 27 1 0 - + + + + + + + + + + + + + + + @@ -2032,11 +2157,6 @@ - - BILINK - 0 - - Coder 0 @@ -2053,9 +2173,13 @@ General 3 - 28 + 35 1 1 + - - - - - + + + + + + + + ICCARM 2 - 34 + 37 1 1 - - - + + AARM 2 - 10 + 11 1 1 + @@ -2699,13 +2833,9 @@ 0 + inputOutputBased - - BICOMP - 0 - - BUILDACTION 1 @@ -2718,17 +2848,13 @@ ILINK 0 - 20 + 27 1 1 - + + + + + + + + + + + + + + + @@ -3053,11 +3239,6 @@ - - BILINK - 0 - - Coder 0 @@ -3076,14 +3257,11 @@ $PROJ_DIR$\..\..\dpp.h - $PROJ_DIR$\..\main.c + $PROJ_DIR$\..\..\main.c $PROJ_DIR$\..\..\philo.c - - $PROJ_DIR$\..\..\..\..\..\include\qstamp.c - $PROJ_DIR$\..\..\table.c @@ -3145,17 +3323,11 @@ $PROJ_DIR$\..\..\..\..\..\src\qs\qs.c - - $PROJ_DIR$\..\..\..\..\..\src\qs\qs_64bit.c - - - $PROJ_DIR$\..\..\..\..\..\src\qs\qs_fp.c - $PROJ_DIR$\..\..\..\..\..\src\qs\qs_rx.c - $PROJ_DIR$\..\..\..\..\..\src\qs\qutest.c + $PROJ_DIR$\..\..\..\..\..\src\qs\qstamp.c diff --git a/examples/arm-cm/dpp_stm32f4-discovery/qv/main.c b/examples/arm-cm/dpp_stm32f4-discovery/qv/main.c deleted file mode 100644 index ab1e447f..00000000 --- a/examples/arm-cm/dpp_stm32f4-discovery/qv/main.c +++ /dev/null @@ -1,93 +0,0 @@ -/***************************************************************************** -* Product: DPP example -* Last updated for version 6.8.2 -* Last updated on 2020-07-17 -* -* Q u a n t u m L e a P s -* ------------------------ -* Modern Embedded Software -* -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* -* -*****************************************************************************/ -#include "qpc.h" -#include "dpp.h" -#include "bsp.h" - -Q_DEFINE_THIS_FILE - -static QTicker l_ticker0; -QActive *the_Ticker0 = &l_ticker0.super; - -/*..........................................................................*/ -int main() { - static QEvt const *tableQueueSto[N_PHILO]; - static QEvt const *philoQueueSto[N_PHILO][N_PHILO]; - static QSubscrList subscrSto[MAX_PUB_SIG]; - static QF_MPOOL_EL(TableEvt) smlPoolSto[2*N_PHILO]; /* small pool */ - uint8_t n; - - Philo_ctor(); /* instantiate all Philosopher active objects */ - Table_ctor(); /* instantiate the Table active object */ - QTicker_ctor(&l_ticker0, 0U); /* ticker AO for tick rate 0 */ - - QF_init(); /* initialize the framework and the underlying RT kernel */ - - /* initialize publish-subscribe... */ - QF_psInit(subscrSto, Q_DIM(subscrSto)); - - /* initialize event pools... */ - QF_poolInit(smlPoolSto, sizeof(smlPoolSto), sizeof(smlPoolSto[0])); - - /* initialize the Board Support Package - * NOTE: BSP_init() is called *after* initializing publish-subscribe and - * event pools, to make the system ready to accept SysTick interrupts. - * Unfortunately, the STM32Cube code that must be called from BSP, - * configures and starts SysTick. - */ - BSP_init(); - - QACTIVE_START(the_Ticker0, 1U, 0, 0, 0, 0, 0); - - /* start the active objects... */ - for (n = 0U; n < N_PHILO; ++n) { - QACTIVE_START(AO_Philo[n], /* AO to start */ - (uint_fast8_t)(n + 2), /* QP priority of the AO */ - philoQueueSto[n], /* event queue storage */ - Q_DIM(philoQueueSto[n]), /* queue length [events] */ - (void *)0, /* stack storage (not used) */ - 0U, /* size of the stack [bytes] */ - (QEvt *)0); /* initialization event */ - } - QACTIVE_START(AO_Table, /* AO to start */ - (uint_fast8_t)(N_PHILO + 2), /* QP priority of the AO */ - tableQueueSto, /* event queue storage */ - Q_DIM(tableQueueSto), /* queue length [events] */ - (void *)0, /* stack storage (not used) */ - 0U, /* size of the stack [bytes] */ - (QEvt *)0); /* initialization event */ - - return QF_run(); /* run the QF application */ -} - diff --git a/examples/arm-cm/dpp_stm32f4-discovery/qxk/armclang/dpp-qxk.sct b/examples/arm-cm/dpp_stm32f4-discovery/qxk/armclang/dpp-qxk.sct new file mode 100644 index 00000000..eb3902ad --- /dev/null +++ b/examples/arm-cm/dpp_stm32f4-discovery/qxk/armclang/dpp-qxk.sct @@ -0,0 +1,22 @@ +; ************************************************************* +; *** Scatter-Loading Description File generated by uVision *** +; +; Adapted by Quantum Leaps: +; moved STACK as the first section in RW_IRAM1 +; ************************************************************* + +LR_IROM1 0x08000000 0x00100000 { ; load region size_region + ER_IROM1 0x08000000 0x00100000 { ; load address = execution address + *.o (RESET, +First) + *(InRoot$$Sections) + .ANY (+RO) + .ANY (+XO) + } + RW_STACK 0x20000000 { ; <== Quantum Leaps + * (STACK, +First) + } + RW_IRAM1 +0 (0x00020000 - 2048) { ; NOTE: 2048 assumed for STACK size! + .ANY (+RW +ZI) + } +} + diff --git a/examples/arm-cm/dpp_stm32f4-discovery/qxk/armclang/dpp-qxk.uvoptx b/examples/arm-cm/dpp_stm32f4-discovery/qxk/armclang/dpp-qxk.uvoptx index 0b244fa0..5b51b5ab 100644 --- a/examples/arm-cm/dpp_stm32f4-discovery/qxk/armclang/dpp-qxk.uvoptx +++ b/examples/arm-cm/dpp_stm32f4-discovery/qxk/armclang/dpp-qxk.uvoptx @@ -299,7 +299,7 @@ 1 0 0 - 5 + 6 @@ -495,7 +495,7 @@ 1 0 0 - 5 + 6 @@ -682,8 +682,8 @@ 0 0 0 - ..\..\..\..\..\include\qstamp.c - qstamp.c + ..\xthread1.c + xthread1.c 0 0 @@ -694,8 +694,8 @@ 0 0 0 - ..\main.c - main.c + ..\xthread2.c + xthread2.c 0 0 @@ -706,8 +706,8 @@ 0 0 0 - ..\test.c - test.c + ..\..\main.c + main.c 0 0 @@ -1026,54 +1026,6 @@ 4 33 - 5 - 0 - 0 - 0 - ..\..\..\..\..\ports\arm-cm\qxk\armclang\qep_port.h - qep_port.h - 0 - 0 - - - 4 - 34 - 5 - 0 - 0 - 0 - ..\..\..\..\..\ports\arm-cm\qxk\armclang\qf_port.h - qf_port.h - 0 - 0 - - - 4 - 35 - 5 - 0 - 0 - 0 - ..\..\..\..\..\ports\arm-cm\qxk\armclang\qxk_port.h - qxk_port.h - 0 - 0 - - - 4 - 36 - 5 - 0 - 0 - 0 - ..\..\..\..\..\ports\arm-cm\qxk\armclang\qs_port.h - qs_port.h - 0 - 0 - - - 4 - 37 1 0 0 @@ -1087,13 +1039,13 @@ QS - 0 + 1 0 0 0 5 - 38 + 34 1 0 0 @@ -1105,31 +1057,7 @@ 5 - 39 - 1 - 0 - 0 - 0 - ..\..\..\..\..\src\qs\qs_64bit.c - qs_64bit.c - 0 - 0 - - - 5 - 40 - 1 - 0 - 0 - 0 - ..\..\..\..\..\src\qs\qs_fp.c - qs_fp.c - 0 - 0 - - - 5 - 41 + 35 1 0 0 @@ -1141,13 +1069,13 @@ 5 - 42 + 36 1 0 0 0 - ..\..\..\..\..\src\qs\qutest.c - qutest.c + ..\..\..\..\..\src\qs\qstamp.c + qstamp.c 0 0 diff --git a/examples/arm-cm/dpp_stm32f4-discovery/qxk/armclang/dpp-qxk.uvprojx b/examples/arm-cm/dpp_stm32f4-discovery/qxk/armclang/dpp-qxk.uvprojx index a5bf99e0..510dbe0b 100644 --- a/examples/arm-cm/dpp_stm32f4-discovery/qxk/armclang/dpp-qxk.uvprojx +++ b/examples/arm-cm/dpp_stm32f4-discovery/qxk/armclang/dpp-qxk.uvprojx @@ -16,8 +16,8 @@ STM32F407VGTx STMicroelectronics - Keil.STM32F4xx_DFP.2.16.0 - http://www.keil.com/pack/ + Keil.STM32F4xx_DFP.2.17.0 + https://www.keil.com/pack/ IRAM(0x20000000,0x20000) IRAM2(0x10000000,0x10000) IROM(0x08000000,0x100000) CPUTYPE("Cortex-M4") FPU2 CLOCK(12000000) ELITTLE @@ -313,7 +313,7 @@ 0 - 7 + 1 0 0 1 @@ -361,7 +361,7 @@ - 1 + 0 0 0 0 @@ -370,7 +370,7 @@ 0x00000000 0x20000000 - + dpp-qxk.sct --entry Reset_Handler @@ -409,19 +409,19 @@ ..\..\table.c - qstamp.c + xthread1.c 1 - ..\..\..\..\..\include\qstamp.c + ..\xthread1.c + + + xthread2.c + 1 + ..\xthread2.c main.c 1 - ..\main.c - - - test.c - 1 - ..\test.c + ..\..\main.c @@ -558,26 +558,6 @@ QP_port - - qep_port.h - 5 - ..\..\..\..\..\ports\arm-cm\qxk\armclang\qep_port.h - - - qf_port.h - 5 - ..\..\..\..\..\ports\arm-cm\qxk\armclang\qf_port.h - - - qxk_port.h - 5 - ..\..\..\..\..\ports\arm-cm\qxk\armclang\qxk_port.h - - - qs_port.h - 5 - ..\..\..\..\..\ports\arm-cm\qxk\armclang\qs_port.h - qxk_port.c 1 @@ -662,25 +642,15 @@ 1 ..\..\..\..\..\src\qs\qs.c - - qs_64bit.c - 1 - ..\..\..\..\..\src\qs\qs_64bit.c - - - qs_fp.c - 1 - ..\..\..\..\..\src\qs\qs_fp.c - qs_rx.c 1 ..\..\..\..\..\src\qs\qs_rx.c - qutest.c + qstamp.c 1 - ..\..\..\..\..\src\qs\qutest.c + ..\..\..\..\..\src\qs\qstamp.c @@ -696,8 +666,8 @@ STM32F407VGTx STMicroelectronics - Keil.STM32F4xx_DFP.2.9.0 - http://www.keil.com/pack + Keil.STM32F4xx_DFP.2.17.0 + https://www.keil.com/pack/ IRAM(0x20000000,0x20000) IRAM2(0x10000000,0x10000) IROM(0x08000000,0x100000) CPUTYPE("Cortex-M4") FPU2 CLOCK(12000000) ELITTLE @@ -1041,7 +1011,7 @@ - 1 + 0 0 0 0 @@ -1089,19 +1059,19 @@ ..\..\table.c - qstamp.c + xthread1.c 1 - ..\..\..\..\..\include\qstamp.c + ..\xthread1.c + + + xthread2.c + 1 + ..\xthread2.c main.c 1 - ..\main.c - - - test.c - 1 - ..\test.c + ..\..\main.c @@ -1238,26 +1208,6 @@ QP_port - - qep_port.h - 5 - ..\..\..\..\..\ports\arm-cm\qxk\armclang\qep_port.h - - - qf_port.h - 5 - ..\..\..\..\..\ports\arm-cm\qxk\armclang\qf_port.h - - - qxk_port.h - 5 - ..\..\..\..\..\ports\arm-cm\qxk\armclang\qxk_port.h - - - qs_port.h - 5 - ..\..\..\..\..\ports\arm-cm\qxk\armclang\qs_port.h - qxk_port.c 1 @@ -1342,25 +1292,15 @@ 1 ..\..\..\..\..\src\qs\qs.c - - qs_64bit.c - 1 - ..\..\..\..\..\src\qs\qs_64bit.c - - - qs_fp.c - 1 - ..\..\..\..\..\src\qs\qs_fp.c - qs_rx.c 1 ..\..\..\..\..\src\qs\qs_rx.c - qutest.c + qstamp.c 1 - ..\..\..\..\..\src\qs\qutest.c + ..\..\..\..\..\src\qs\qstamp.c @@ -1370,14 +1310,14 @@ dpp-spy 0x4 ARM-ADS - 5060183::V5.06 update 2 (build 183)::ARMCC + 6160000::V6.16::ARMCLANG 1 STM32F407VGTx STMicroelectronics - Keil.STM32F4xx_DFP.2.9.0 - http://www.keil.com/pack + Keil.STM32F4xx_DFP.2.17.0 + https://www.keil.com/pack/ IRAM(0x20000000,0x20000) IRAM2(0x10000000,0x10000) IROM(0x08000000,0x100000) CPUTYPE("Cortex-M4") FPU2 CLOCK(12000000) ELITTLE @@ -1697,7 +1637,7 @@ 0 - Q_SPY + Q_SPY,QF_ON_CONTEXT_SW ..\..;..\..\..\..\..\include;..\..\..\..\..\ports\arm-cm\qxk\armclang;..\..\..\..\..\3rd_party\CMSIS\Include; ..\..\..\..\..\3rd_party\stm32f4-discovery; ..\..\..\..\..\3rd_party\stm32f4-discovery\inc @@ -1721,7 +1661,7 @@ - 1 + 0 0 0 0 @@ -1769,19 +1709,19 @@ ..\..\table.c - qstamp.c + xthread1.c 1 - ..\..\..\..\..\include\qstamp.c + ..\xthread1.c + + + xthread2.c + 1 + ..\xthread2.c main.c 1 - ..\main.c - - - test.c - 1 - ..\test.c + ..\..\main.c @@ -1918,26 +1858,6 @@ QP_port - - qep_port.h - 5 - ..\..\..\..\..\ports\arm-cm\qxk\armclang\qep_port.h - - - qf_port.h - 5 - ..\..\..\..\..\ports\arm-cm\qxk\armclang\qf_port.h - - - qxk_port.h - 5 - ..\..\..\..\..\ports\arm-cm\qxk\armclang\qxk_port.h - - - qs_port.h - 5 - ..\..\..\..\..\ports\arm-cm\qxk\armclang\qs_port.h - qxk_port.c 1 @@ -1953,25 +1873,15 @@ 1 ..\..\..\..\..\src\qs\qs.c - - qs_64bit.c - 1 - ..\..\..\..\..\src\qs\qs_64bit.c - - - qs_fp.c - 1 - ..\..\..\..\..\src\qs\qs_fp.c - qs_rx.c 1 ..\..\..\..\..\src\qs\qs_rx.c - qutest.c + qstamp.c 1 - ..\..\..\..\..\src\qs\qutest.c + ..\..\..\..\..\src\qs\qstamp.c diff --git a/examples/arm-cm/dpp_stm32f4-discovery/qxk/bsp.c b/examples/arm-cm/dpp_stm32f4-discovery/qxk/bsp.c index 70d11b95..af3683fa 100644 --- a/examples/arm-cm/dpp_stm32f4-discovery/qxk/bsp.c +++ b/examples/arm-cm/dpp_stm32f4-discovery/qxk/bsp.c @@ -1,54 +1,50 @@ -/***************************************************************************** -* Product: "DPP" example on STM32F4-Discovery board, dual-mode QXK kernel -* Last updated for version 6.9.3 -* Last updated on 2021-03-03 -* -* Q u a n t u m L e a P s -* ------------------------ -* Modern Embedded Software -* -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* -* -*****************************************************************************/ -#include "qpc.h" -#include "dpp.h" -#include "bsp.h" +//============================================================================ +// Product: DPP example, STM32F4-Discovery board, QXK kernel +// Last updated for version 7.3.0 +// Last updated on 2023-08-23 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. +// +// This program is open source software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Alternatively, this program may be distributed and modified under the +// terms of Quantum Leaps commercial licenses, which expressly supersede +// the GNU General Public License and are specifically designed for +// licensees interested in retaining the proprietary status of their code. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Contact information: +// +// +//============================================================================ +#include "qpc.h" // QP/C real-time embedded framework +#include "dpp.h" // DPP Application interface +#include "bsp.h" // Board Support Package -#include "stm32f4xx.h" /* CMSIS-compliant header file for the MCU used */ +#include "stm32f4xx.h" // CMSIS-compliant header file for the MCU used #include "stm32f4xx_exti.h" #include "stm32f4xx_gpio.h" #include "stm32f4xx_rcc.h" #include "stm32f4xx_usart.h" -/* add other drivers if necessary... */ +// add other drivers if necessary... -Q_DEFINE_THIS_FILE +Q_DEFINE_THIS_FILE // define the name of this file for assertions -/* ISRs defined in this BSP ------------------------------------------------*/ -void SysTick_Handler(void); -void USART2_IRQHandler(void); - -/* Local-scope defines -----------------------------------------------------*/ +// Local-scope defines ----------------------------------------------------- #define LED_GPIO_PORT GPIOD #define LED_GPIO_CLK RCC_AHB1Periph_GPIOD @@ -61,102 +57,153 @@ void USART2_IRQHandler(void); #define BTN_GPIO_CLK RCC_AHB1Periph_GPIOA #define BTN_B1 GPIO_Pin_0 -static uint32_t l_rnd; /* random seed */ +static uint32_t l_rndSeed; #ifdef Q_SPY static QSTimeCtr QS_tickTime_; static QSTimeCtr QS_tickPeriod_; - /* QSpy source IDs */ - static QSpyId const l_SysTick = { 0U }; + // QSpy source IDs + static QSpyId const l_SysTick_Handler = { 0U }; - enum AppRecords { /* application-specific trace records */ + enum AppRecords { // application-specific trace records PHILO_STAT = QS_USER, - COMMAND_STAT + PAUSED_STAT, + CONTEXT_SW, }; #endif -/* ISRs used in this project ===============================================*/ +//============================================================================ +// Error handler and ISRs... + +Q_NORETURN Q_onError(char const * const module, int_t const id) { + // NOTE: this implementation of the assertion handler is intended only + // for debugging and MUST be changed for deployment of the application + // (assuming that you ship your production code with assertions enabled). + Q_UNUSED_PAR(module); + Q_UNUSED_PAR(id); + QS_ASSERTION(module, id, 10000U); + +#ifndef NDEBUG + // light up the user LED + LED_GPIO_PORT->BSRRL = LED3_PIN; // turn LED on + LED_GPIO_PORT->BSRRL = LED4_PIN; // turn LED on + LED_GPIO_PORT->BSRRL = LED5_PIN; // turn LED on + LED_GPIO_PORT->BSRRL = LED6_PIN; // turn LED on + // for debugging, hang on in an endless loop... + for (;;) { + } +#endif + + NVIC_SystemReset(); +} +//............................................................................ +void assert_failed(char const * const module, int_t const id); // prototype +void assert_failed(char const * const module, int_t const id) { + Q_onError(module, id); +} + +// ISRs used in the application ========================================== + +void SysTick_Handler(void); // prototype void SysTick_Handler(void) { - /* state of the button debouncing, see below */ - static struct ButtonsDebouncing { + QXK_ISR_ENTRY(); // inform QXK about entering an ISR + + QTIMEEVT_TICK_X(0U, &l_SysTick_Handler); // time events at rate 0 + + // Perform the debouncing of buttons. The algorithm for debouncing + // adapted from the book "Embedded Systems Dictionary" by Jack Ganssle + // and Michael Barr, page 71. + static struct { uint32_t depressed; uint32_t previous; } buttons = { 0U, 0U }; - uint32_t current; - uint32_t tmp; - QXK_ISR_ENTRY(); /* inform QXK about entering an ISR */ + uint32_t current = BTN_GPIO_PORT->IDR; // read BTN GPIO + uint32_t tmp = buttons.depressed; // save the depressed buttons + buttons.depressed |= (buttons.previous & current); // set depressed + buttons.depressed &= (buttons.previous | current); // clear released + buttons.previous = current; // update the history + tmp ^= buttons.depressed; // changed debounced depressed + current = buttons.depressed; + + if ((tmp & BTN_B1) != 0U) { // debounced B1 state changed? + if ((current & BTN_B1) != 0U) { // is B1 depressed? + static QEvt const pauseEvt = QEVT_INITIALIZER(PAUSE_SIG); + QACTIVE_PUBLISH(&pauseEvt, &l_SysTick_Handler); + } + else { // the button is released + static QEvt const serveEvt = QEVT_INITIALIZER(SERVE_SIG); + QACTIVE_PUBLISH(&serveEvt, &l_SysTick_Handler); + } + } #ifdef Q_SPY - { - tmp = SysTick->CTRL; /* clear SysTick_CTRL_COUNTFLAG */ - QS_tickTime_ += QS_tickPeriod_; /* account for the clock rollover */ - } + tmp = SysTick->CTRL; // clear CTRL_COUNTFLAG + QS_tickTime_ += QS_tickPeriod_; // account for the clock rollover #endif - QTIMEEVT_TICK_X(0U, &l_SysTick); /* process time events for tick rate 0 */ - - /* Perform the debouncing of buttons. The algorithm for debouncing - * adapted from the book "Embedded Systems Dictionary" by Jack Ganssle - * and Michael Barr, page 71. - */ - current = BTN_GPIO_PORT->IDR; /* read BTN GPIO */ - tmp = buttons.depressed; /* save the debounced depressed buttons */ - buttons.depressed |= (buttons.previous & current); /* set depressed */ - buttons.depressed &= (buttons.previous | current); /* clear released */ - buttons.previous = current; /* update the history */ - tmp ^= buttons.depressed; /* changed debounced depressed */ - if ((tmp & BTN_B1) != 0U) { /* debounced B1 state changed? */ - if ((buttons.depressed & BTN_B1) != 0U) { /* is B1 depressed? */ - static QEvt const pauseEvt = { PAUSE_SIG, 0U, 0U}; - QACTIVE_PUBLISH(&pauseEvt, &l_SysTick); - } - else { /* the button is released */ - static QEvt const serveEvt = { SERVE_SIG, 0U, 0U}; - QACTIVE_PUBLISH(&serveEvt, &l_SysTick); - } - } - - QXK_ISR_EXIT(); /* inform QXK about exiting an ISR */ + QXK_ISR_EXIT(); // inform QXK about exiting an ISR } -/*..........................................................................*/ +//............................................................................ #ifdef Q_SPY -/* -* ISR for receiving bytes from the QSPY Back-End -* NOTE: This ISR is "QF-unaware" meaning that it does not interact with -* the QF/QXK and is not disabled. Such ISRs don't need to call QXK_ISR_ENTRY/ -* QXK_ISR_EXIT and they cannot post or publish events. -*/ -void USART2_IRQHandler(void) { - if ((USART2->SR & USART_SR_RXNE) != 0) { +// ISR for receiving bytes from the QSPY Back-End +// NOTE: This ISR is "QF-unaware" meaning that it does not interact with +// the QF/QXK and is not disabled. Such ISRs don't need to call +// QXK_ISR_ENTRY/QXK_ISR_EXIT and they cannot post or publish events. + +void USART2_IRQHandler(void); // prototype +void USART2_IRQHandler(void) { // used in QS-RX (kernel UNAWARE interrutp) + // is RX register NOT empty? + if ((USART2->SR & USART_SR_RXNE) != 0U) { uint32_t b = USART2->DR; QS_RX_PUT(b); } + QXK_ARM_ERRATUM_838869(); } -#else -void USART2_IRQHandler(void) {} -#endif +#endif // Q_SPY +//............................................................................ +#ifdef QF_ON_CONTEXT_SW +// NOTE: the context-switch callback is called with interrupts DISABLED +void QF_onContextSw(QActive *prev, QActive *next) { + QS_BEGIN_INCRIT(CONTEXT_SW, 0U) // in critical section! + QS_OBJ(prev); + QS_OBJ(next); + QS_END_INCRIT() +} +#endif // QF_ON_CONTEXT_SW + +//============================================================================ +// BSP functions... -/* BSP functions ===========================================================*/ void BSP_init(void) { - GPIO_InitTypeDef GPIO_struct; + // Configure the MPU to prevent NULL-pointer dereferencing ... + MPU->RBAR = 0x0U // base address (NULL) + | MPU_RBAR_VALID_Msk // valid region + | (MPU_RBAR_REGION_Msk & 7U); // region #7 + MPU->RASR = (7U << MPU_RASR_SIZE_Pos) // 2^(7+1) region + | (0x0U << MPU_RASR_AP_Pos) // no-access region + | MPU_RASR_ENABLE_Msk; // region enable + MPU->CTRL = MPU_CTRL_PRIVDEFENA_Msk // enable background region + | MPU_CTRL_ENABLE_Msk; // enable the MPU + __ISB(); + __DSB(); - /* NOTE: SystemInit() already called from the startup code - * but SystemCoreClock needs to be updated - */ + // NOTE: SystemInit() has been already called from the startup code + // but SystemCoreClock needs to be updated SystemCoreClockUpdate(); - /* NOTE The VFP (Floating Point Unit) unit is configured by QXK-port */ + // NOTE The VFP (Floating Point Unit) unit is configured by QXK-port - /* Initialize thr port for the LEDs */ + // Initialize thr port for the LEDs RCC_AHB1PeriphClockCmd(LED_GPIO_CLK , ENABLE); - /* GPIO Configuration for the LEDs... */ + // GPIO Configuration for the LEDs... + GPIO_InitTypeDef GPIO_struct; GPIO_struct.GPIO_Mode = GPIO_Mode_OUT; GPIO_struct.GPIO_OType = GPIO_OType_PP; GPIO_struct.GPIO_PuPd = GPIO_PuPd_UP; @@ -164,24 +211,24 @@ void BSP_init(void) { GPIO_struct.GPIO_Pin = LED3_PIN; GPIO_Init(LED_GPIO_PORT, &GPIO_struct); - LED_GPIO_PORT->BSRRH = LED3_PIN; /* turn LED off */ + LED_GPIO_PORT->BSRRH = LED3_PIN; // turn LED off GPIO_struct.GPIO_Pin = LED4_PIN; GPIO_Init(LED_GPIO_PORT, &GPIO_struct); - LED_GPIO_PORT->BSRRH = LED4_PIN; /* turn LED off */ + LED_GPIO_PORT->BSRRH = LED4_PIN; // turn LED off GPIO_struct.GPIO_Pin = LED5_PIN; GPIO_Init(LED_GPIO_PORT, &GPIO_struct); - LED_GPIO_PORT->BSRRH = LED5_PIN; /* turn LED off */ + LED_GPIO_PORT->BSRRH = LED5_PIN; // turn LED off GPIO_struct.GPIO_Pin = LED6_PIN; GPIO_Init(LED_GPIO_PORT, &GPIO_struct); - LED_GPIO_PORT->BSRRH = LED6_PIN; /* turn LED off */ + LED_GPIO_PORT->BSRRH = LED6_PIN; // turn LED off - /* Initialize thr port for Button */ + // Initialize thr port for Button RCC_AHB1PeriphClockCmd(BTN_GPIO_CLK , ENABLE); - /* GPIO Configuration for the Button... */ + // GPIO Configuration for the Button... GPIO_struct.GPIO_Pin = BTN_B1; GPIO_struct.GPIO_Mode = GPIO_Mode_IN; GPIO_struct.GPIO_OType = GPIO_OType_PP; @@ -189,191 +236,252 @@ void BSP_init(void) { GPIO_struct.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(BTN_GPIO_PORT, &GPIO_struct); - /* seed the random number generator */ - BSP_randomSeed(1234U); + BSP_randomSeed(1234U); // seed the random number generator - if (QS_INIT((void *)0) == 0U) { /* initialize the QS software tracing */ + // initialize the QS software tracing... + if (!QS_INIT((void *)0)) { Q_ERROR(); } - QS_OBJ_DICTIONARY(&l_SysTick); - QS_USR_DICTIONARY(PHILO_STAT); - QS_USR_DICTIONARY(COMMAND_STAT); - /* setup the QS filters... */ - QS_GLB_FILTER(QS_SM_RECORDS); /* state machine records */ - QS_GLB_FILTER(QS_AO_RECORDS); /* active object records */ - QS_GLB_FILTER(QS_UA_RECORDS); /* all user records */ + // dictionaries... + QS_OBJ_DICTIONARY(&l_SysTick_Handler); + QS_USR_DICTIONARY(PHILO_STAT); + QS_USR_DICTIONARY(PAUSED_STAT); + QS_USR_DICTIONARY(CONTEXT_SW); + + QS_ONLY(produce_sig_dict()); + + // setup the QS filters... + QS_GLB_FILTER(QS_ALL_RECORDS); // all records + QS_GLB_FILTER(-QS_QF_TICK); // exclude the clock tick } -/*..........................................................................*/ -void BSP_ledOn(void) { - LED_GPIO_PORT->BSRRL = LED6_PIN; +//............................................................................ +void BSP_start(void) { + // initialize event pools + static QF_MPOOL_EL(TableEvt) smlPoolSto[2*N_PHILO]; + QF_poolInit(smlPoolSto, sizeof(smlPoolSto), sizeof(smlPoolSto[0])); + + // initialize publish-subscribe + static QSubscrList subscrSto[MAX_PUB_SIG]; + QActive_psInit(subscrSto, Q_DIM(subscrSto)); + + // instantiate and start AOs/threads... + static QEvt const *xThread1QueueSto[5]; + static uint64_t xThread1StackSto[64]; + XThread1_ctor(); + QXTHREAD_START(TH_XThread1, + 1U, // QP priority of the thread + xThread1QueueSto, // event queue storage + Q_DIM(xThread1QueueSto), // event length [events] + xThread1StackSto, // stack storage + sizeof(xThread1StackSto), // stack size [bytes] + (void *)0); // no initialization param + + static QEvt const *philoQueueSto[N_PHILO][10]; + for (uint8_t n = 0U; n < N_PHILO; ++n) { + Philo_ctor(n); + QACTIVE_START(AO_Philo[n], + n + 3U, // QF-prio. + philoQueueSto[n], // event queue storage + Q_DIM(philoQueueSto[n]), // queue length [events] + (void *)0, 0U, // no stack storage + (void *)0); // no initialization param + } + + static QEvt const *xThread2QueueSto[5]; + static uint64_t xThread2StackSto[64]; + XThread2_ctor(); + QXTHREAD_START(TH_XThread2, + N_PHILO + 5U, // QP priority of the thread + xThread2QueueSto, // event queue storage + Q_DIM(xThread2QueueSto), // event length [events] + xThread2StackSto, // stack storage + sizeof(xThread2StackSto), // stack size [bytes] + (void *)0); // no initialization param + + static QEvt const *tableQueueSto[N_PHILO]; + Table_ctor(); + QACTIVE_START(AO_Table, + N_PHILO + 7U, // QP prio. of the AO + tableQueueSto, // event queue storage + Q_DIM(tableQueueSto), // queue length [events] + (void *)0, 0U, // no stack storage + (void *)0); // no initialization param } -/*..........................................................................*/ -void BSP_ledOff(void) { - LED_GPIO_PORT->BSRRH = LED6_PIN; -} -/*..........................................................................*/ +//............................................................................ void BSP_displayPhilStat(uint8_t n, char const *stat) { - (void)n; + Q_UNUSED_PAR(n); if (stat[0] == 'h') { - LED_GPIO_PORT->BSRRL = LED3_PIN; /* turn LED on */ + LED_GPIO_PORT->BSRRL = LED3_PIN; // turn LED on } else { - LED_GPIO_PORT->BSRRH = LED3_PIN; /* turn LED off */ + LED_GPIO_PORT->BSRRH = LED3_PIN; // turn LED off } if (stat[0] == 'e') { - LED_GPIO_PORT->BSRRL = LED5_PIN; /* turn LED on */ + LED_GPIO_PORT->BSRRL = LED5_PIN; // turn LED on } else { - LED_GPIO_PORT->BSRRH = LED5_PIN; /* turn LED off */ + LED_GPIO_PORT->BSRRH = LED5_PIN; // turn LED off } - QS_BEGIN_ID(PHILO_STAT, AO_Philo[n]->prio) /* app-specific record */ - QS_U8(1, n); /* Philosopher number */ - QS_STR(stat); /* Philosopher status */ - QS_END() /* application-specific record end */ + // app-specific trace record... + QS_BEGIN_ID(PHILO_STAT, AO_Table->prio) + QS_U8(1, n); // Philosopher number + QS_STR(stat); // Philosopher status + QS_END() } -/*..........................................................................*/ -void BSP_displayPaused(uint8_t paused) { +//............................................................................ +void BSP_displayPaused(uint8_t const paused) { if (paused) { - LED_GPIO_PORT->BSRRL = LED4_PIN; /* turn LED on */ + LED_GPIO_PORT->BSRRL = LED4_PIN; // turn LED on } else { - LED_GPIO_PORT->BSRRH = LED4_PIN; /* turn LED off */ + LED_GPIO_PORT->BSRRH = LED4_PIN; // turn LED off } -} -/*..........................................................................*/ -uint32_t BSP_random(void) { /* a very cheap pseudo-random-number generator */ - uint32_t rnd; - QSchedStatus lockStat; - /* Some flating point code is to exercise the FPU... */ + // application-specific trace record + QS_BEGIN_ID(PAUSED_STAT, AO_Table->prio) + QS_U8(1, paused); // Paused status + QS_END() +} +//............................................................................ +void BSP_randomSeed(uint32_t seed) { + l_rndSeed = seed; +} +//............................................................................ +uint32_t BSP_random(void) { // a very cheap pseudo-random-number generator + + // Some flating point code is to exercise the FPU... float volatile x = 3.1415926F; x = x + 2.7182818F; - lockStat = QXK_schedLock(N_PHILO); /* lock scheduler up to N_PHILO prio */ - /* "Super-Duper" Linear Congruential Generator (LCG) - * LCG(2^32, 3*7*11*13*23, 0, seed) - */ - rnd = l_rnd * (3U*7U*11U*13U*23U); - l_rnd = rnd; /* set for the next time */ - QXK_schedUnlock(lockStat); /* unlock the scheduler */ + QSchedStatus lockStat = QXK_schedLock(N_PHILO); + // "Super-Duper" Linear Congruential Generator (LCG) + // LCG(2^32, 3*7*11*13*23, 0, seed) + // + uint32_t rnd = l_rndSeed * (3U*7U*11U*13U*23U); + l_rndSeed = rnd; // set for the next time + QXK_schedUnlock(lockStat); - return (rnd >> 8); + return (rnd >> 8U); } -/*..........................................................................*/ -void BSP_randomSeed(uint32_t seed) { - l_rnd = seed; +//............................................................................ +void BSP_ledOn(void) { + LED_GPIO_PORT->BSRRL = LED6_PIN; } -/*..........................................................................*/ +//............................................................................ +void BSP_ledOff(void) { + LED_GPIO_PORT->BSRRH = LED6_PIN; +} +//............................................................................ void BSP_terminate(int16_t result) { - (void)result; + Q_UNUSED_PAR(result); } -/* QF callbacks ============================================================*/ +//============================================================================ +// QF callbacks... void QF_onStartup(void) { - /* set up the SysTick timer to fire at BSP_TICKS_PER_SEC rate */ + // set up the SysTick timer to fire at BSP_TICKS_PER_SEC rate SysTick_Config(SystemCoreClock / BSP_TICKS_PER_SEC); - /* assign all priority bits for preemption-prio. and none to sub-prio. */ + // assign all priority bits for preemption-prio. and none to sub-prio. NVIC_SetPriorityGrouping(0U); - /* !!!!!!!!!!!!!!!!!!!!!!!!!!!! CAUTION !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - * Assign a priority to EVERY ISR explicitly, see NOTE00. - * DO NOT LEAVE THE ISR PRIORITIES AT THE DEFAULT VALUE! - */ - /* kernel UNAWARE interrupts, see NOTE00 */ - NVIC_SetPriority(USART2_IRQn, 0U); - /* ... */ + // set priorities of ALL ISRs used in the system, see NOTE1 + NVIC_SetPriority(USART2_IRQn, 0U); // kernel UNAWARE interrupt + NVIC_SetPriority(SysTick_IRQn, QF_AWARE_ISR_CMSIS_PRI + 1U); + // ... - /* kernel AWARE interrupts, see NOTE00 */ - NVIC_SetPriority(SysTick_IRQn, QF_AWARE_ISR_CMSIS_PRI); - /* ... */ + // enable IRQs... - /* enable IRQs... */ #ifdef Q_SPY - NVIC_EnableIRQ(USART2_IRQn); /* USART2 interrupt used for QS-RX */ + NVIC_EnableIRQ(USART2_IRQn); // USART2 interrupt used for QS-RX #endif } -/*..........................................................................*/ +//............................................................................ void QF_onCleanup(void) { } -/*..........................................................................*/ +//............................................................................ void QXK_onIdle(void) { + // toggle an LED on and then off (not enough LEDs, see NOTE02) QF_INT_DISABLE(); - LED_GPIO_PORT->BSRRL = LED6_PIN; /* turn LED on */ - __NOP(); /* wait a little to actually see the LED glow */ + LED_GPIO_PORT->BSRRL = LED6_PIN; // turn LED on + __NOP(); // wait a little to actually see the LED glow __NOP(); __NOP(); __NOP(); - LED_GPIO_PORT->BSRRH = LED6_PIN; /* turn LED off */ + LED_GPIO_PORT->BSRRH = LED6_PIN; // turn LED off QF_INT_ENABLE(); #ifdef Q_SPY - QS_rxParse(); /* parse all the received bytes */ - - if ((USART2->SR & USART_FLAG_TXE) != 0) { /* TXE empty? */ - uint16_t b; + QF_INT_DISABLE(); + QS_rxParse(); // parse all the received bytes + QF_INT_ENABLE(); + if ((USART2->SR & USART_FLAG_TXE) != 0) { // TXE empty? QF_INT_DISABLE(); - b = QS_getByte(); + uint16_t b = QS_getByte(); QF_INT_ENABLE(); - if (b != QS_EOD) { /* not End-Of-Data? */ - USART2->DR = (b & 0xFFU); /* put into the DR register */ + if (b != QS_EOD) { // not End-Of-Data? + USART2->DR = b; // put into the DR register } } #elif defined NDEBUG - /* Put the CPU and peripherals to the low-power mode. - * you might need to customize the clock management for your application, - * see the datasheet for your particular Cortex-M MCU. - */ - /* !!!CAUTION!!! - * The WFI instruction stops the CPU clock, which unfortunately disables - * the JTAG port, so the ST-Link debugger can no longer connect to the - * board. For that reason, the call to __WFI() has to be used with CAUTION. - * - * NOTE: If you find your board "frozen" like this, strap BOOT0 to VDD and - * reset the board, then connect with ST-Link Utilities and erase the part. - * The trick with BOOT(0) is that it gets the part to run the System Loader - * instead of your broken code. When done disconnect BOOT0, and start over. - */ - //__WFI(); /* Wait-For-Interrupt */ + // Put the CPU and peripherals to the low-power mode. + // you might need to customize the clock management for your application, + // see the datasheet for your particular Cortex-M MCU. + // + // !!!CAUTION!!! + // The WFI instruction stops the CPU clock, which unfortunately disables + // the JTAG port, so the ST-Link debugger can no longer connect to the + // board. For that reason, the call to __WFI() has to be used with CAUTION. + // + // NOTE: If you find your board "frozen" like this, strap BOOT0 to VDD and + // reset the board, then connect with ST-Link Utilities and erase the part. + // The trick with BOOT(0) is that it gets the part to run the System Loader + // instead of your broken code. When done disconnect BOOT0, and start over. + // + //__WFI(); // Wait-For-Interrupt #endif } -/*..........................................................................*/ -Q_NORETURN Q_onAssert(char const * const module, int_t const loc) { - /* - * NOTE: add here your application-specific error handling - */ - (void)module; - (void)loc; - QS_ASSERTION(module, loc, 10000U); /* report assertion to QS */ - NVIC_SystemReset(); -} - -/* QS callbacks ============================================================*/ +//============================================================================ +// QS callbacks... #ifdef Q_SPY -/*..........................................................................*/ -uint8_t QS_onStartup(void const *arg) { - static uint8_t qsBuf[2*1024]; /* buffer for QS-TX channel */ - static uint8_t qsRxBuf[100]; /* buffer for QS-RX channel */ - GPIO_InitTypeDef GPIO_struct; - USART_InitTypeDef USART_struct; - (void)arg; /* avoid the "unused parameter" compiler warning */ - QS_initBuf(qsBuf, sizeof(qsBuf)); +//............................................................................ +#define __DIV(__PCLK, __BAUD) (((__PCLK / 4) *25)/(__BAUD)) +#define __DIVMANT(__PCLK, __BAUD) (__DIV(__PCLK, __BAUD)/100) +#define __DIVFRAQ(__PCLK, __BAUD) \ + (((__DIV(__PCLK, __BAUD) - (__DIVMANT(__PCLK, __BAUD) * 100)) \ + * 16 + 50) / 100) +#define __USART_BRR(__PCLK, __BAUD) \ + ((__DIVMANT(__PCLK, __BAUD) << 4)|(__DIVFRAQ(__PCLK, __BAUD) & 0x0F)) + +// USART2 pins PA.2 and PA.3 +#define USART2_TX_PIN 2U +#define USART2_RX_PIN 3U + +//............................................................................ +uint8_t QS_onStartup(void const *arg) { + Q_UNUSED_PAR(arg); + + static uint8_t qsTxBuf[2*1024]; // buffer for QS-TX channel + QS_initBuf(qsTxBuf, sizeof(qsTxBuf)); + + static uint8_t qsRxBuf[100]; // buffer for QS-RX channel QS_rxInitBuf(qsRxBuf, sizeof(qsRxBuf)); - /* enable peripheral clock for USART2 */ + // enable peripheral clock for USART2 RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE); - /* GPIOA clock enable */ + // GPIOA clock enable RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); - /* GPIOA Configuration: USART2 TX on PA2 and RX on PA3 */ + // GPIOA Configuration: USART2 TX on PA2 and RX on PA3 + GPIO_InitTypeDef GPIO_struct; GPIO_struct.GPIO_Pin = GPIO_Pin_2 | GPIO_Pin_3; GPIO_struct.GPIO_Mode = GPIO_Mode_AF; GPIO_struct.GPIO_Speed = GPIO_Speed_50MHz; @@ -381,10 +489,11 @@ uint8_t QS_onStartup(void const *arg) { GPIO_struct.GPIO_PuPd = GPIO_PuPd_UP ; GPIO_Init(GPIOA, &GPIO_struct); - /* Connect USART2 pins to AF2 */ - GPIO_PinAFConfig(GPIOA, GPIO_PinSource2, GPIO_AF_USART2); /* TX = PA2 */ - GPIO_PinAFConfig(GPIOA, GPIO_PinSource3, GPIO_AF_USART2); /* RX = PA3 */ + // Connect USART2 pins to AF2 + GPIO_PinAFConfig(GPIOA, GPIO_PinSource2, GPIO_AF_USART2); // TX = PA2 + GPIO_PinAFConfig(GPIOA, GPIO_PinSource3, GPIO_AF_USART2); // RX = PA3 + USART_InitTypeDef USART_struct; USART_struct.USART_BaudRate = 115200; USART_struct.USART_WordLength = USART_WordLength_8b; USART_struct.USART_StopBits = USART_StopBits_1; @@ -393,97 +502,89 @@ uint8_t QS_onStartup(void const *arg) { USART_struct.USART_Mode = USART_Mode_Tx | USART_Mode_Rx; USART_Init(USART2, &USART_struct); - USART_ITConfig(USART2, USART_IT_RXNE, ENABLE); /* enable RX interrupt */ - USART_Cmd(USART2, ENABLE); /* enable USART2 */ + USART_ITConfig(USART2, USART_IT_RXNE, ENABLE); // enable RX interrupt + USART_Cmd(USART2, ENABLE); // enable USART2 QS_tickPeriod_ = SystemCoreClock / BSP_TICKS_PER_SEC; - QS_tickTime_ = QS_tickPeriod_; /* to start the timestamp at zero */ + QS_tickTime_ = QS_tickPeriod_; // to start the timestamp at zero - return 1U; /* return success */ + return 1U; // return success } -/*..........................................................................*/ +//............................................................................ void QS_onCleanup(void) { } -/*..........................................................................*/ -QSTimeCtr QS_onGetTime(void) { /* NOTE: invoked with interrupts DISABLED */ - if ((SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk) == 0) { /* not set? */ +//............................................................................ +QSTimeCtr QS_onGetTime(void) { // NOTE: invoked with interrupts DISABLED + if ((SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk) == 0U) { // not set? return QS_tickTime_ - (QSTimeCtr)SysTick->VAL; } - else { /* the rollover occured, but the SysTick_ISR did not run yet */ + else { // the rollover occured, but the SysTick_ISR did not run yet return QS_tickTime_ + QS_tickPeriod_ - (QSTimeCtr)SysTick->VAL; } } -/*..........................................................................*/ +//............................................................................ void QS_onFlush(void) { - uint16_t b; - - QF_INT_DISABLE(); - while ((b = QS_getByte()) != QS_EOD) { /* while not End-Of-Data... */ - QF_INT_ENABLE(); - while ((USART2->SR & USART_FLAG_TXE) == 0) { /* while TXE not empty */ - } - USART2->DR = (b & 0xFFU); /* put into the DR register */ + for (;;) { QF_INT_DISABLE(); + uint16_t b = QS_getByte(); + if (b != QS_EOD) { + while ((USART2->SR & USART_FLAG_TXE) == 0U) { // while TXE not empty + QF_INT_ENABLE(); + QF_CRIT_EXIT_NOP(); + + QF_INT_DISABLE(); + } + USART2->DR = b; // put into the DR register + QF_INT_ENABLE(); + } + else { + QF_INT_ENABLE(); + break; + } } - QF_INT_ENABLE(); } -/*..........................................................................*/ -/*! callback function to reset the target (to be implemented in the BSP) */ +//............................................................................ +//! callback function to reset the target (to be implemented in the BSP) void QS_onReset(void) { NVIC_SystemReset(); } -/*..........................................................................*/ -/*! callback function to execute a user command (to be implemented in BSP) */ +//............................................................................ +//! callback function to execute a user command void QS_onCommand(uint8_t cmdId, uint32_t param1, uint32_t param2, uint32_t param3) { - void assert_failed(char const *module, int loc); - (void)cmdId; - (void)param1; - (void)param2; - (void)param3; - QS_BEGIN_ID(COMMAND_STAT, 0U) /* app-specific record */ - QS_U8(2, cmdId); - QS_U32(8, param1); - QS_U32(8, param2); - QS_U32(8, param3); - QS_END() - - if (cmdId == 10U) { - Q_ERROR(); - } - else if (cmdId == 11U) { - assert_failed("QS_onCommand", 123); - } + Q_UNUSED_PAR(cmdId); + Q_UNUSED_PAR(param1); + Q_UNUSED_PAR(param2); + Q_UNUSED_PAR(param3); } -#endif /* Q_SPY */ -/*--------------------------------------------------------------------------*/ +#endif // Q_SPY +//---------------------------------------------------------------------------- -/***************************************************************************** -* NOTE00: -* The QF_AWARE_ISR_CMSIS_PRI constant from the QF port specifies the highest -* ISR priority that is disabled by the QF framework. The value is suitable -* for the NVIC_SetPriority() CMSIS function. -* -* Only ISRs prioritized at or below the QF_AWARE_ISR_CMSIS_PRI level (i.e., -* with the numerical values of priorities equal or higher than -* QF_AWARE_ISR_CMSIS_PRI) are allowed to call any QF services. These ISRs -* are "QF-aware". -* -* Conversely, any ISRs prioritized above the QF_AWARE_ISR_CMSIS_PRI priority -* level (i.e., with the numerical values of priorities less than -* QF_AWARE_ISR_CMSIS_PRI) are never disabled and are not aware of the kernel. -* Such "QF-unaware" ISRs cannot call any QF services. The only mechanism -* by which a "QF-unaware" ISR can communicate with the QF framework is by -* triggering a "QF-aware" ISR, which can post/publish events. -* -* NOTE01: -* The QXK_onIdle() callback is called with interrupts enabled. -* -* NOTE02: -* One of the LEDs is used to visualize the idle loop activity. The brightness -* of the LED is proportional to the frequency of invcations of the idle loop. -* Please note that the LED is toggled with interrupts locked, so no interrupt -* execution time contributes to the brightness of the User LED. -*/ +//============================================================================ +// NOTE1: +// The QF_AWARE_ISR_CMSIS_PRI constant from the QF port specifies the highest +// ISR priority that is disabled by the QF framework. The value is suitable +// for the NVIC_SetPriority() CMSIS function. +// +// Only ISRs prioritized at or below the QF_AWARE_ISR_CMSIS_PRI level (i.e., +// with the numerical values of priorities equal or higher than +// QF_AWARE_ISR_CMSIS_PRI) are allowed to call the QK_ISR_ENTRY/ +// QXK_ISR_ENTRY macros or any other QF/QXK services. These ISRs are +// "QF-aware". +// +// Conversely, any ISRs prioritized above the QF_AWARE_ISR_CMSIS_PRI priority +// level (i.e., with the numerical values of priorities less than +// QF_AWARE_ISR_CMSIS_PRI) are never disabled and are not aware of the kernel. +// Such "QF-unaware" ISRs cannot call ANY QF/QXK services. In particular they +// can NOT call the macros QXK_ISR_ENTRY/QXK_ISR_ENTRY. The only mechanism +// by which a "QF-unaware" ISR can communicate with the QF framework is by +// triggering a "QF-aware" ISR, which can post/publish events. +// +// NOTE2: +// The User LED is used to visualize the idle loop activity. The brightness +// of the LED is proportional to the frequency of the idle loop. +// Please note that the LED is toggled with interrupts locked, so no interrupt +// execution time contributes to the brightness of the User LED. +// diff --git a/examples/arm-cm/dpp_stm32f4-discovery/qxk/gnu/Makefile b/examples/arm-cm/dpp_stm32f4-discovery/qxk/gnu/Makefile index 6399d028..aea06e43 100644 --- a/examples/arm-cm/dpp_stm32f4-discovery/qxk/gnu/Makefile +++ b/examples/arm-cm/dpp_stm32f4-discovery/qxk/gnu/Makefile @@ -1,13 +1,13 @@ ############################################################################## # Product: Makefile for QP/C on STM32F4-Discovery, QXK kernel, GNU-ARM -# Last Updated for Version: 7.0.1 -# Date of the Last Update: 2022-05-23 +# Last Updated for Version: 7.3.0 +# Date of the Last Update: 2023-08-24 # # Q u a n t u m L e a P s # ------------------------ # Modern Embedded Software # -# Copyright (C) 2005-2021 Quantum Leaps, LLC. All rights reserved. +# Copyright (C) 2005 Quantum Leaps, LLC. # # This program is open source software: you can redistribute it and/or # modify it under the terms of the GNU General Public License as published @@ -99,7 +99,8 @@ C_SRCS := \ main.c \ philo.c \ table.c \ - test.c \ + xthread1.c \ + xthread2.c \ system_stm32f4xx.c \ startup_stm32f4xx.c \ stm32f4xx_gpio.c \ @@ -142,7 +143,8 @@ LIB_DIRS := LIBS := # defines -DEFINES := +DEFINES := \ + -DQF_ON_CONTEXT_SW # ARM CPU, ARCH, FPU, and Float-ABI types... # ARM_CPU: [cortex-m0 | cortex-m0plus | cortex-m1 | cortex-m3 | cortex-m4] @@ -183,7 +185,7 @@ MKDIR := mkdir RM := rm #----------------------------------------------------------------------------- -# build options for various configurations for ARM Cortex-M4F +# build options for various configurations for ARM Cortex-M # # combine all the soruces... @@ -270,7 +272,7 @@ $(TARGET_BIN): $(TARGET_ELF) $(BIN) -O binary $< $@ $(TARGET_ELF) : $(ASM_OBJS_EXT) $(C_OBJS_EXT) $(CPP_OBJS_EXT) - $(CC) $(CFLAGS) $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o + $(CC) $(CFLAGS) $(QPC)/src/qs/qstamp.c -o $(BIN_DIR)/qstamp.o $(LINK) $(LINKFLAGS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) $(BIN_DIR)/%.d : %.c diff --git a/examples/arm-cm/dpp_stm32f4-discovery/qxk/iar/dpp-qxk.ewd b/examples/arm-cm/dpp_stm32f4-discovery/qxk/iar/dpp-qxk.ewd index f3025db5..22af80f9 100644 --- a/examples/arm-cm/dpp_stm32f4-discovery/qxk/iar/dpp-qxk.ewd +++ b/examples/arm-cm/dpp_stm32f4-discovery/qxk/iar/dpp-qxk.ewd @@ -11,7 +11,7 @@ C-SPY 2 - 28 + 32 1 1 - - + + + + + @@ -486,7 +498,7 @@ IJET_ID 2 - 8 + 9 1 1 + + + + + + + + + + + + + @@ -916,7 +980,7 @@ LMIFTDI_ID 2 - 2 + 3 1 1 + + + + + + + NULINK_ID + 2 + + 0 + 1 + 1 + + + @@ -974,7 +1072,7 @@ STLINK_ID 2 - 4 + 8 1 1 + + + + @@ -1185,7 +1300,7 @@ XDS100_ID 2 - 6 + 9 1 1 + + + + @@ -1362,6 +1493,18 @@ $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin 0 + + $TOOLKIT_DIR$\plugins\rtos\FreeRtos\FreeRtosArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin2.ENU.ewplugin + 0 + $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin 0 @@ -1371,11 +1514,15 @@ 0 - $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9.ewplugin 0 - $TOOLKIT_DIR$\plugins\rtos\TI-RTOS\tirtosplugin.ewplugin + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9BE.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin 0 @@ -1391,11 +1538,11 @@ 0 - $EW_DIR$\common\plugins\CodeCoverage\CodeCoverage.ENU.ewplugin - 1 + $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + 0 - $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + $EW_DIR$\common\plugins\TargetAccessServer\TargetAccessServer.ENU.ewplugin 0 @@ -1414,7 +1561,7 @@ C-SPY 2 - 28 + 32 1 0 - - + + + + + @@ -1889,7 +2048,7 @@ IJET_ID 2 - 8 + 9 1 0 + + + + + + + + + + + + + @@ -2319,7 +2530,7 @@ LMIFTDI_ID 2 - 2 + 3 1 0 + + + + + + + NULINK_ID + 2 + + 0 + 1 + 0 + + + @@ -2377,7 +2622,7 @@ STLINK_ID 2 - 4 + 8 1 0 + + + + @@ -2588,7 +2850,7 @@ XDS100_ID 2 - 6 + 9 1 0 + + + + @@ -2765,6 +3043,18 @@ $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin 0 + + $TOOLKIT_DIR$\plugins\rtos\FreeRtos\FreeRtosArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin2.ENU.ewplugin + 0 + $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin 0 @@ -2774,11 +3064,15 @@ 0 - $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9.ewplugin 0 - $TOOLKIT_DIR$\plugins\rtos\TI-RTOS\tirtosplugin.ewplugin + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9BE.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin 0 @@ -2794,11 +3088,11 @@ 0 - $EW_DIR$\common\plugins\CodeCoverage\CodeCoverage.ENU.ewplugin - 1 + $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + 0 - $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + $EW_DIR$\common\plugins\TargetAccessServer\TargetAccessServer.ENU.ewplugin 0 @@ -2817,7 +3111,7 @@ C-SPY 2 - 28 + 32 1 1 - - + + + + + @@ -3292,7 +3598,7 @@ IJET_ID 2 - 8 + 9 1 1 + + + + + + + + + + + + + @@ -3722,7 +4080,7 @@ LMIFTDI_ID 2 - 2 + 3 1 1 + + + + + + + NULINK_ID + 2 + + 0 + 1 + 1 + + + @@ -3780,7 +4172,7 @@ STLINK_ID 2 - 4 + 8 1 1 + + + + @@ -3991,7 +4400,7 @@ XDS100_ID 2 - 6 + 9 1 1 + + + + @@ -4168,6 +4593,18 @@ $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin 0 + + $TOOLKIT_DIR$\plugins\rtos\FreeRtos\FreeRtosArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin2.ENU.ewplugin + 0 + $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin 0 @@ -4177,11 +4614,15 @@ 0 - $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9.ewplugin 0 - $TOOLKIT_DIR$\plugins\rtos\TI-RTOS\tirtosplugin.ewplugin + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9BE.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin 0 @@ -4197,11 +4638,11 @@ 0 - $EW_DIR$\common\plugins\CodeCoverage\CodeCoverage.ENU.ewplugin - 1 + $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + 0 - $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + $EW_DIR$\common\plugins\TargetAccessServer\TargetAccessServer.ENU.ewplugin 0 diff --git a/examples/arm-cm/dpp_stm32f4-discovery/qxk/iar/dpp-qxk.ewp b/examples/arm-cm/dpp_stm32f4-discovery/qxk/iar/dpp-qxk.ewp index 49f512d0..8051bfc8 100644 --- a/examples/arm-cm/dpp_stm32f4-discovery/qxk/iar/dpp-qxk.ewp +++ b/examples/arm-cm/dpp_stm32f4-discovery/qxk/iar/dpp-qxk.ewp @@ -11,9 +11,13 @@ General 3 - 28 + 35 1 1 + - - - - - + + + + + + + + ICCARM 2 - 34 + 37 1 1 - - - + + AARM 2 - 10 + 11 1 1 + @@ -657,13 +670,9 @@ 0 + inputOutputBased - - BICOMP - 0 - - BUILDACTION 1 @@ -676,17 +685,13 @@ ILINK 0 - 20 + 27 1 1 - + + + + + + + + + + + + + + + @@ -1011,11 +1076,6 @@ - - BILINK - 0 - - Coder 0 @@ -1032,9 +1092,13 @@ General 3 - 28 + 35 1 0 + - - - - - + + + + + + + + ICCARM 2 - 34 + 37 1 0 - - - + + AARM 2 - 10 + 11 1 0 + @@ -1678,13 +1751,9 @@ 0 + inputOutputBased - - BICOMP - 0 - - BUILDACTION 1 @@ -1697,17 +1766,13 @@ ILINK 0 - 20 + 27 1 0 - + + + + + + + + + + + + + + + @@ -2032,11 +2157,6 @@ - - BILINK - 0 - - Coder 0 @@ -2053,9 +2173,13 @@ General 3 - 28 + 35 1 1 + - - - - - + + + + + + + + ICCARM 2 - 34 + 37 1 1 - - - + + AARM 2 - 10 + 11 1 1 + @@ -2699,13 +2833,9 @@ 0 + inputOutputBased - - BICOMP - 0 - - BUILDACTION 1 @@ -2718,17 +2848,13 @@ ILINK 0 - 20 + 27 1 1 - + + + + + + + + + + + + + + + @@ -3053,11 +3239,6 @@ - - BILINK - 0 - - Coder 0 @@ -3076,19 +3257,19 @@ $PROJ_DIR$\..\..\dpp.h - $PROJ_DIR$\..\main.c + $PROJ_DIR$\..\..\main.c $PROJ_DIR$\..\..\philo.c - - $PROJ_DIR$\..\..\..\..\..\include\qstamp.c - $PROJ_DIR$\..\..\table.c - $PROJ_DIR$\..\test.c + $PROJ_DIR$\..\xthread1.c + + + $PROJ_DIR$\..\xthread2.c @@ -3135,24 +3316,6 @@ $PROJ_DIR$\..\..\..\..\..\src\qxk\qxk_mutex.c - - - QP_port - - $PROJ_DIR$\..\..\..\..\..\ports\arm-cm\qxk\iar\qep_port.h - - - $PROJ_DIR$\..\..\..\..\..\ports\arm-cm\qxk\iar\qf_port.h - - - $PROJ_DIR$\..\..\..\..\..\ports\arm-cm\qxk\iar\qs_port.h - - - $PROJ_DIR$\..\..\..\..\..\ports\arm-cm\qxk\iar\qxk_port.h - - - $PROJ_DIR$\..\..\..\..\..\ports\arm-cm\qxk\iar\qxk_port.c - $PROJ_DIR$\..\..\..\..\..\src\qxk\qxk_sema.c @@ -3160,6 +3323,12 @@ $PROJ_DIR$\..\..\..\..\..\src\qxk\qxk_xthr.c + + QP_port + + $PROJ_DIR$\..\..\..\..\..\ports\arm-cm\qxk\iar\qxk_port.c + + QS @@ -3169,17 +3338,11 @@ $PROJ_DIR$\..\..\..\..\..\src\qs\qs.c - - $PROJ_DIR$\..\..\..\..\..\src\qs\qs_64bit.c - - - $PROJ_DIR$\..\..\..\..\..\src\qs\qs_fp.c - $PROJ_DIR$\..\..\..\..\..\src\qs\qs_rx.c - $PROJ_DIR$\..\..\..\..\..\src\qs\qutest.c + $PROJ_DIR$\..\..\..\..\..\src\qs\qstamp.c diff --git a/examples/arm-cm/dpp_stm32f4-discovery/qxk/main.c b/examples/arm-cm/dpp_stm32f4-discovery/qxk/main.c deleted file mode 100644 index 80fc8f77..00000000 --- a/examples/arm-cm/dpp_stm32f4-discovery/qxk/main.c +++ /dev/null @@ -1,128 +0,0 @@ -/***************************************************************************** -* Product: DPP example extened for QXK -* Last updated for version 7.1.2 -* Last updated on 2022-10-05 -* -* Q u a n t u m L e a P s -* ------------------------ -* Modern Embedded Software -* -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* -* -*****************************************************************************/ -#include "qpc.h" -#include "dpp.h" -#include "bsp.h" - -Q_DEFINE_THIS_FILE - -static QTicker l_ticker0; -QActive *the_Ticker0 = &l_ticker0.super; - -/*..........................................................................*/ -int main() { - static QEvt const *tableQueueSto[N_PHILO]; - static QEvt const *philoQueueSto[N_PHILO][N_PHILO]; - static QSubscrList subscrSto[MAX_PUB_SIG]; - static QF_MPOOL_EL(TableEvt) smlPoolSto[2*N_PHILO]; /* small pool */ - - /* stacks and queues for the extended test threads */ - static void const *test1QueueSto[5]; - static uint64_t test1StackSto[64]; - static void const *test2QueueSto[5]; - static uint64_t test2StackSto[64]; - - uint8_t n; - - Philo_ctor(); /* instantiate all Philosopher active objects */ - Table_ctor(); /* instantiate the Table active object */ - QTicker_ctor(&l_ticker0, 0U); /* ticker AO for tick rate 0 */ - Test1_ctor(); /* instantiate the Test1 extended thread */ - Test2_ctor(); /* instantiate the Test2 extended thread */ - - QF_init(); /* initialize the framework and the underlying RT kernel */ - - /* initialize publish-subscribe... */ - QF_psInit(subscrSto, Q_DIM(subscrSto)); - - /* initialize event pools... */ - QF_poolInit(smlPoolSto, sizeof(smlPoolSto), sizeof(smlPoolSto[0])); - - /* initialize the Board Support Package - * NOTE: BSP_init() is called *after* initializing publish-subscribe and - * event pools, to make the system ready to accept SysTick interrupts. - * Unfortunately, the STM32Cube code that must be called from BSP, - * configures and starts SysTick. - */ - BSP_init(); - - /* start the extended thread */ - QXTHREAD_START(XT_Test1, /* Thread to start */ - 1U, /* QP priority of the thread */ - test1QueueSto, /* message queue storage */ - Q_DIM(test1QueueSto), /* message length [events] */ - test1StackSto, /* stack storage */ - sizeof(test1StackSto), /* stack size [bytes] */ - (QEvt *)0); /* initialization event */ - - /* NOTE: leave priority 2 free for a mutex */ - - /* start the Philo active objects... */ - for (n = 0U; n < N_PHILO; ++n) { - QACTIVE_START(AO_Philo[n], /* AO to start */ - n + 3U, /* QP priority of the AO */ - philoQueueSto[n], /* event queue storage */ - Q_DIM(philoQueueSto[n]), /* queue length [events] */ - (void *)0, /* stack storage (not used) */ - 0U, /* size of the stack [bytes] */ - (QEvt *)0); /* initialization event */ - } - - /* example of prioritizing the Ticker0 active object */ - QACTIVE_START(the_Ticker0, N_PHILO + 3U, - 0, 0, 0, 0, 0); - - /* NOTE: leave priority (N_PHILO + 4) free for mutex */ - - QXTHREAD_START(XT_Test2, /* Thread to start */ - N_PHILO + 5U, /* QP priority of the thread */ - test2QueueSto, /* message queue storage */ - Q_DIM(test2QueueSto), /* message length [events] */ - test2StackSto, /* stack storage */ - sizeof(test2StackSto), /* stack size [bytes] */ - (QEvt *)0); /* initialization event */ - - /* NOTE: leave priority (N_PHILO + 6) free for mutex */ - - QACTIVE_START(AO_Table, /* AO to start */ - N_PHILO + 7U, /* QP priority of the AO */ - tableQueueSto, /* event queue storage */ - Q_DIM(tableQueueSto), /* queue length [events] */ - (void *)0, /* stack storage (not used) */ - 0U, /* size of the stack [bytes] */ - (QEvt *)0); /* initialization event */ - - return QF_run(); /* run the QF application */ -} - diff --git a/examples/arm-cm/dpp_stm32f4-discovery/qxk/test.c b/examples/arm-cm/dpp_stm32f4-discovery/qxk/test.c deleted file mode 100644 index 3754ec42..00000000 --- a/examples/arm-cm/dpp_stm32f4-discovery/qxk/test.c +++ /dev/null @@ -1,146 +0,0 @@ -/***************************************************************************** -* Product: DPP example -* Last updated for version 6.7.0 -* Last updated on 2019-12-27 -* -* Q u a n t u m L e a P s -* ------------------------ -* Modern Embedded Software -* -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* -* -*****************************************************************************/ -#include "qpc.h" -#include "dpp.h" -#include "bsp.h" - -/* local "extended" thread object ..........................................*/ -static QXThread l_test1; -static QXThread l_test2; -static QXMutex l_mutex; -static QXSemaphore l_sema; - -/* Thread-Local Storage for the "extended" threads .........................*/ -typedef struct { - uint32_t foo; - uint8_t bar[10]; -} TLS_test; -static TLS_test l_tls1; -static TLS_test l_tls2; - -static void lib_fun(uint32_t x) { - QXK_TLS(TLS_test *)->foo = x; -} - -/* global pointer to the test thread .......................................*/ -QXThread * const XT_Test1 = &l_test1; -QXThread * const XT_Test2 = &l_test2; - -/*..........................................................................*/ -static void Thread1_run(QXThread * const me) { - - QS_OBJ_DICTIONARY(&l_test1); - - me->super.thread = &l_tls1; /* initialize the TLS for Thread1 */ - - for (;;) { - QXMutex_lock(&l_mutex, QXTHREAD_NO_TIMEOUT); /* lock the mutex */ - BSP_ledOn(); - - if (QXMutex_tryLock(&l_mutex)) { /* exercise the mutex */ - float volatile x; - - /* some flating point code to exercise the VFP... */ - x = 1.4142135F; - x = x * 1.4142135F; - - (void)QXSemaphore_signal(&l_sema); /* signal Thread2 */ - - QXThread_delay(10U); /* BLOCK while holding a mutex */ - - QXMutex_unlock(&l_mutex); - } - - QXMutex_unlock(&l_mutex); - BSP_ledOff(); - - QXThread_delay(BSP_TICKS_PER_SEC/7); /* BLOCK */ - - /* publish to thread2 */ - //QACTIVE_PUBLISH(Q_NEW(QEvt, TEST_SIG), &l_test1.super); - - /* test TLS */ - lib_fun(1U); - } -} - -/*..........................................................................*/ -void Test1_ctor(void) { - QXThread_ctor(&l_test1, &Thread1_run, 0U); -} - -/*..........................................................................*/ -static void Thread2_run(QXThread * const me) { - - QS_OBJ_DICTIONARY(&l_test2); - - /* initialize the semaphore before using it - * NOTE: the semaphore is initialized in the highest-priority thread - * that uses it. Alternatively, the semaphore can be initialized - * before any thread runs. - */ - QXSemaphore_init(&l_sema, - 0U, /* count==0 (signaling semaphore) */ - 1U); /* max_count==1 (binary semaphore) */ - - /* initialize the mutex before using it - * NOTE: Here the mutex is initialized in the highest-priority thread - * that uses it. Alternatively, the mutex can be initialized - * before any thread runs. - */ - //QXMutex_init(&l_mutex, 0U); /* priority-ceiling NOT used */ - QXMutex_init(&l_mutex, N_PHILO + 6U); /*priority-ceiling protocol used*/ - - me->super.thread = &l_tls2; /* initialize the TLS for Thread2 */ - - /* subscribe to the test signal */ - QActive_subscribe(&me->super, TEST_SIG); - - for (;;) { - /* wait on a semaphore (BLOCK indefinitely) */ - QXSemaphore_wait(&l_sema, QXTHREAD_NO_TIMEOUT); - - QXMutex_lock(&l_mutex, QXTHREAD_NO_TIMEOUT); /* lock the mutex */ - QXThread_delay(1U); /* wait more (BLOCK) */ - QXMutex_unlock(&l_mutex); - - /* test TLS */ - lib_fun(2U); - } -} - -/*..........................................................................*/ -void Test2_ctor(void) { - QXThread_ctor(&l_test2, &Thread2_run, 0U); -} diff --git a/examples/arm-cm/dpp_stm32f4-discovery/qxk/xthread1.c b/examples/arm-cm/dpp_stm32f4-discovery/qxk/xthread1.c new file mode 100644 index 00000000..066b983d --- /dev/null +++ b/examples/arm-cm/dpp_stm32f4-discovery/qxk/xthread1.c @@ -0,0 +1,101 @@ +//============================================================================ +// QXThread example +// Last updated for version 7.3.0 +// Last updated on 2023-08-12 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. +// +// This program is open source software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Alternatively, this program may be distributed and modified under the +// terms of Quantum Leaps commercial licenses, which expressly supersede +// the GNU General Public License and are specifically designed for +// licensees interested in retaining the proprietary status of their code. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Contact information: +// +// +//============================================================================ +#include "qpc.h" // QP/C real-time embedded framework +#include "dpp.h" // DPP Application interface +#include "bsp.h" // Board Support Package + +//---------------------------------------------------------------------------- +//Q_DEFINE_THIS_FILE + +//............................................................................ +typedef struct XThread1 { +// protected: + QXThread super; + +// private: + // NOTE: data needed by this thread should be members of + // the thread class. That way they are in the memory region + // accessible from this thread. + uint8_t foo; + +// public: +} XThread1; + +// private: +static void XThread1_run(QXThread * const thr); +extern XThread1 XThread1_inst; + +//............................................................................ +QXThread * const TH_XThread1 = &XThread1_inst.super; + +//............................................................................ +void XThread1_ctor(void) { + XThread1 *me = &XThread1_inst; + QXThread_ctor(&me->super, &XThread1_run, 0U); +} + +//............................................................................ +XThread1 XThread1_inst; + +//............................................................................ +static void XThread1_run(QXThread * const thr) { + QS_OBJ_DICTIONARY(TH_XThread1); + QS_OBJ_DICTIONARY(&TH_XThread1->timeEvt); + + // downcast the generic thr pointer to the specific thread + XThread1 *me = (XThread1 *)thr; + + // subscribe to the EAT signal (from the application) + QActive_subscribe(&me->super.super, EAT_SIG); + + for (;;) { + QEvt const *e = QXThread_queueGet(BSP_TICKS_PER_SEC/4U); + if (e) { + QXSemaphore_signal(&TH_sema); // signal Thread2 + QF_gc(e); // must explicitly recycle the received event! + } + + QXMutex_lock(&TH_mutex, QXTHREAD_NO_TIMEOUT); // lock the mutex + BSP_ledOn(); + if (QXMutex_tryLock(&TH_mutex)) { // exercise the mutex + // some floating point code to exercise the VFP... + float volatile x = 1.4142135F; + x = x * 1.4142135F; + QXThread_delay(10U); // BLOCK while holding a mutex + QXMutex_unlock(&TH_mutex); + } + QXMutex_unlock(&TH_mutex); + BSP_ledOff(); + } +} diff --git a/examples/arm-cm/dpp_stm32f4-discovery/qxk/xthread2.c b/examples/arm-cm/dpp_stm32f4-discovery/qxk/xthread2.c new file mode 100644 index 00000000..1caad4fa --- /dev/null +++ b/examples/arm-cm/dpp_stm32f4-discovery/qxk/xthread2.c @@ -0,0 +1,108 @@ +//============================================================================ +// QXThread example +// Last updated for version 7.3.0 +// Last updated on 2023-08-12 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. +// +// This program is open source software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Alternatively, this program may be distributed and modified under the +// terms of Quantum Leaps commercial licenses, which expressly supersede +// the GNU General Public License and are specifically designed for +// licensees interested in retaining the proprietary status of their code. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Contact information: +// +// +//============================================================================ +#include "qpc.h" // QP/C real-time embedded framework +#include "dpp.h" // DPP Application interface +#include "bsp.h" // Board Support Package + +//---------------------------------------------------------------------------- +//Q_DEFINE_THIS_FILE + +//---------------------------------------------------------------------------- +QXSemaphore TH_sema; +QXMutex TH_mutex; + +//---------------------------------------------------------------------------- +typedef struct XThread2 { +// protected: + QXThread super; + +// private: + // NOTE: data needed by this thread should be members of + // the thread class. That way they are in the memory region + // accessible from this thread. + uint8_t foo; + +// public: +} XThread2; + +// private: +static void XThread2_run(QXThread * const thr); +extern XThread2 XThread2_inst; + +//............................................................................ +QXThread * const TH_XThread2 = &XThread2_inst.super; + +//............................................................................ +void XThread2_ctor(void) { + XThread2 *me = &XThread2_inst; + QXThread_ctor(&me->super, &XThread2_run, 0U); +} + +//............................................................................ +XThread2 XThread2_inst; + +//............................................................................ +static void XThread2_run(QXThread * const thr) { + QS_OBJ_DICTIONARY(TH_XThread2); + QS_OBJ_DICTIONARY(&TH_XThread2->timeEvt); + QS_OBJ_DICTIONARY(&TH_sema); + QS_OBJ_DICTIONARY(&TH_mutex); + + // downcast the generic thr pointer to the specific thread + //XThread2 *me = (XThread2 *)thr; + + // initialize the semaphore before using it + // NOTE: Here the semaphore is initialized in the highest-priority thread + // that uses it. Alternatively, the semaphore can be initialized + // before any thread runs. + QXSemaphore_init(&TH_sema, + 0U, // count==0 (signaling semaphore) + 1U); // max_count==1 (binary semaphore) + + // initialize the mutex before using it + // NOTE: Here the mutex is initialized in the highest-priority thread + // that uses it. Alternatively, the mutex can be initialized + // before any thread runs. + QXMutex_init(&TH_mutex, N_PHILO + 6U); // priority-ceiling mutex + //QXMutex_init(&TH_mutex, 0U); // alternatively: priority-ceiling NOT used + + for (;;) { + // wait on a semaphore (BLOCK indefinitely) + QXSemaphore_wait(&TH_sema, QXTHREAD_NO_TIMEOUT); + + QXMutex_lock(&TH_mutex, QXTHREAD_NO_TIMEOUT); // lock the mutex + QXThread_delay(5U); // wait more (BLOCK) + QXMutex_unlock(&TH_mutex); + } +} diff --git a/examples/arm-cm/dpp_stm32f4-discovery/table.c b/examples/arm-cm/dpp_stm32f4-discovery/table.c index d14c29d4..c3ae02f0 100644 --- a/examples/arm-cm/dpp_stm32f4-discovery/table.c +++ b/examples/arm-cm/dpp_stm32f4-discovery/table.c @@ -1,111 +1,120 @@ -/*$file${.::table.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* -* Model: dpp.qm -* File: ${.::table.c} -* -* This code has been generated by QM 5.2.4 . -* DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. -* -* SPDX-License-Identifier: GPL-3.0-or-later -* -* This generated code is open source software: you can redistribute it under -* the terms of the GNU General Public License as published by the Free -* Software Foundation. -* -* This code is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -* more details. -* -* NOTE: -* Alternatively, this generated code may be distributed under the terms -* of Quantum Leaps commercial licenses, which expressly supersede the GNU -* General Public License and are specifically designed for licensees -* interested in retaining the proprietary status of their code. -* -* Contact information: -* -* -*/ -/*$endhead${.::table.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -#include "qpc.h" -#include "dpp.h" -#include "bsp.h" +//$file${.::table.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// +// Model: dpp.qm +// File: ${.::table.c} +// +// This code has been generated by QM 5.3.0 . +// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. +// +// SPDX-License-Identifier: GPL-3.0-or-later +// +// This generated code is open source software: you can redistribute it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation. +// +// This code is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// NOTE: +// Alternatively, this generated code may be distributed under the terms +// of Quantum Leaps commercial licenses, which expressly supersede the GNU +// General Public License and are specifically designed for licensees +// interested in retaining the proprietary status of their code. +// +// Contact information: +// +// +// +//$endhead${.::table.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +#include "qpc.h" // QP/C real-time embedded framework +#include "dpp.h" // DPP Application interface +#include "bsp.h" // Board Support Package -Q_DEFINE_THIS_FILE +//$declare${AOs::Table} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/* Active object class -----------------------------------------------------*/ -/*$declare${AOs::Table} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${AOs::Table} ............................................................*/ -typedef struct { -/* protected: */ +//${AOs::Table} .............................................................. +typedef struct Table { +// protected: QActive super; -/* private: */ +// private: uint8_t fork[N_PHILO]; - uint8_t isHungry[N_PHILO]; + bool isHungry[N_PHILO]; + +// public: } Table; -/* protected: */ +extern Table Table_inst; + +// protected: static QState Table_initial(Table * const me, void const * const par); static QState Table_active(Table * const me, QEvt const * const e); static QState Table_serving(Table * const me, QEvt const * const e); static QState Table_paused(Table * const me, QEvt const * const e); -/*$enddecl${AOs::Table} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$enddecl${AOs::Table} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -#define RIGHT(n_) ((uint8_t)(((n_) + (N_PHILO - 1U)) % N_PHILO)) -#define LEFT(n_) ((uint8_t)(((n_) + 1U) % N_PHILO)) -#define FREE ((uint8_t)0) -#define USED ((uint8_t)1) +//---------------------------------------------------------------------------- +Q_DEFINE_THIS_FILE -/* Local objects -----------------------------------------------------------*/ -static Table l_table; /* the single instance of the Table active object */ +// helper function to provide the RIGHT neighbor of a Philo[n] +static inline uint8_t right(uint8_t const n) { + return (uint8_t)((n + (N_PHILO - 1U)) % N_PHILO); +} -/* Global-scope objects ----------------------------------------------------*/ -QActive * const AO_Table = &l_table.super; /* "opaque" AO pointer */ +// helper function to provide the LEFT neighbor of a Philo[n] +static inline uint8_t left(uint8_t const n) { + return (uint8_t)((n + 1U) % N_PHILO); +} -/*..........................................................................*/ -/*$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* Check for the minimum required QP version */ -#if (QP_VERSION < 700U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) -#error qpc version 7.0.0 or higher required +#define FREE ((uint8_t)0U) +#define USED ((uint8_t)1U) + +#define THINKING "thinking" +#define HUNGRY "hungry " +#define EATING "eating " + +//---------------------------------------------------------------------------- + +//$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// Check for the minimum required QP version +#if (QP_VERSION < 730U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) +#error qpc version 7.3.0 or higher required #endif -/*$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -/*$define${AOs::Table_ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//$define${Shared::Table_ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/*${AOs::Table_ctor} .......................................................*/ +//${Shared::Table_ctor} ...................................................... void Table_ctor(void) { - uint8_t n; - Table *me = &l_table; - + Table * const me = &Table_inst; QActive_ctor(&me->super, Q_STATE_CAST(&Table_initial)); - - for (n = 0U; n < N_PHILO; ++n) { + for (uint8_t n = 0U; n < N_PHILO; ++n) { me->fork[n] = FREE; - me->isHungry[n] = 0U; + me->isHungry[n] = false; } } -/*$enddef${AOs::Table_ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*$define${AOs::Table} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//$enddef${Shared::Table_ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +//$define${Shared::AO_Table} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/*${AOs::Table} ............................................................*/ +//${Shared::AO_Table} ........................................................ +QActive * const AO_Table = &Table_inst.super; +//$enddef${Shared::AO_Table} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +//$define${AOs::Table} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/*${AOs::Table::SM} ........................................................*/ +//${AOs::Table} .............................................................. +Table Table_inst; + +//${AOs::Table::SM} .......................................................... static QState Table_initial(Table * const me, void const * const par) { - /*${AOs::Table::SM::initial} */ - (void)par; /* unused parameter */ + //${AOs::Table::SM::initial} + Q_UNUSED_PAR(par); - QS_OBJ_DICTIONARY(&l_table); - - QS_SIG_DICTIONARY(DONE_SIG, (void *)0); /* global signals */ - QS_SIG_DICTIONARY(EAT_SIG, (void *)0); - QS_SIG_DICTIONARY(PAUSE_SIG, (void *)0); - QS_SIG_DICTIONARY(SERVE_SIG, (void *)0); - QS_SIG_DICTIONARY(TEST_SIG, (void *)0); - - QS_SIG_DICTIONARY(HUNGRY_SIG, me); /* signal just for Table */ + #ifdef Q_SPY + Table *Table_inst = me; + QS_OBJ_DICTIONARY(Table_inst); + #endif QActive_subscribe(&me->super, DONE_SIG); QActive_subscribe(&me->super, PAUSE_SIG); @@ -114,8 +123,8 @@ static QState Table_initial(Table * const me, void const * const par) { for (uint8_t n = 0U; n < N_PHILO; ++n) { me->fork[n] = FREE; - me->isHungry[n] = 0U; - BSP_displayPhilStat(n, "thinking"); + me->isHungry[n] = false; + BSP_displayPhilStat(n, THINKING); } QS_FUN_DICTIONARY(&Table_active); @@ -125,16 +134,16 @@ static QState Table_initial(Table * const me, void const * const par) { return Q_TRAN(&Table_serving); } -/*${AOs::Table::SM::active} ................................................*/ +//${AOs::Table::SM::active} .................................................. static QState Table_active(Table * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${AOs::Table::SM::active::TEST} */ + //${AOs::Table::SM::active::TEST} case TEST_SIG: { status_ = Q_HANDLED(); break; } - /*${AOs::Table::SM::active::EAT} */ + //${AOs::Table::SM::active::EAT} case EAT_SIG: { Q_ERROR(); status_ = Q_HANDLED(); @@ -148,108 +157,119 @@ static QState Table_active(Table * const me, QEvt const * const e) { return status_; } -/*${AOs::Table::SM::active::serving} .......................................*/ +//${AOs::Table::SM::active::serving} ......................................... static QState Table_serving(Table * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${AOs::Table::SM::active::serving} */ + //${AOs::Table::SM::active::serving} case Q_ENTRY_SIG: { - uint8_t n; - for (n = 0U; n < N_PHILO; ++n) { /* give permissions to eat... */ - if ((me->isHungry[n] != 0U) - && (me->fork[LEFT(n)] == FREE) + // give permissions to eat... + for (uint8_t n = 0U; n < N_PHILO; ++n) { + if (me->isHungry[n] + && (me->fork[left(n)] == FREE) && (me->fork[n] == FREE)) { - TableEvt *te; - - me->fork[LEFT(n)] = USED; + me->fork[left(n)] = USED; me->fork[n] = USED; - te = Q_NEW(TableEvt, EAT_SIG); - te->philoNum = n; - QACTIVE_PUBLISH(&te->super, &me->super); - me->isHungry[n] = 0U; - BSP_displayPhilStat(n, "eating "); + #ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, EAT_SIG, n); + #else + TableEvt *pe = Q_NEW(TableEvt, EAT_SIG); + pe->philoId = n; + #endif + QACTIVE_PUBLISH(&pe->super, &me->super); + me->isHungry[n] = false; + BSP_displayPhilStat(n, EATING); } } status_ = Q_HANDLED(); break; } - /*${AOs::Table::SM::active::serving::HUNGRY} */ + //${AOs::Table::SM::active::serving::HUNGRY} case HUNGRY_SIG: { - uint8_t n, m; + uint8_t n = Q_EVT_CAST(TableEvt)->philoId; - n = Q_EVT_CAST(TableEvt)->philoNum; - /* phil ID must be in range and he must be not hungry */ - Q_ASSERT((n < N_PHILO) && (me->isHungry[n] == 0U)); + // phil ID must be in range and he must be not hungry + Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); - BSP_displayPhilStat(n, "hungry "); - m = LEFT(n); - /*${AOs::Table::SM::active::serving::HUNGRY::[bothfree]} */ + BSP_displayPhilStat(n, HUNGRY); + uint8_t m = left(n); + //${AOs::Table::SM::active::serving::HUNGRY::[bothfree]} if ((me->fork[m] == FREE) && (me->fork[n] == FREE)) { - TableEvt *pe; me->fork[m] = USED; me->fork[n] = USED; - pe = Q_NEW(TableEvt, EAT_SIG); - pe->philoNum = n; + #ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, EAT_SIG, n); + #else + TableEvt *pe = Q_NEW(TableEvt, EAT_SIG); + pe->philoId = n; + #endif QACTIVE_PUBLISH(&pe->super, &me->super); - BSP_displayPhilStat(n, "eating "); + BSP_displayPhilStat(n, EATING); status_ = Q_HANDLED(); } - /*${AOs::Table::SM::active::serving::HUNGRY::[else]} */ + //${AOs::Table::SM::active::serving::HUNGRY::[else]} else { - me->isHungry[n] = 1U; + me->isHungry[n] = true; status_ = Q_HANDLED(); } break; } - /*${AOs::Table::SM::active::serving::DONE} */ + //${AOs::Table::SM::active::serving::DONE} case DONE_SIG: { - uint8_t n, m; - TableEvt *pe; + uint8_t n = Q_EVT_CAST(TableEvt)->philoId; - n = Q_EVT_CAST(TableEvt)->philoNum; - /* phil ID must be in range and he must be not hungry */ - Q_ASSERT((n < N_PHILO) && (me->isHungry[n] == 0U)); + // phil ID must be in range and he must be not hungry + Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); - BSP_displayPhilStat(n, "thinking"); - m = LEFT(n); - /* both forks of Phil[n] must be used */ + BSP_displayPhilStat(n, THINKING); + uint8_t m = left(n); + + // both forks of Phil[n] must be used Q_ASSERT((me->fork[n] == USED) && (me->fork[m] == USED)); me->fork[m] = FREE; me->fork[n] = FREE; - m = RIGHT(n); /* check the right neighbor */ + m = right(n); // check the right neighbor - if ((me->isHungry[m] != 0U) && (me->fork[m] == FREE)) { + if (me->isHungry[m] && (me->fork[m] == FREE)) { me->fork[n] = USED; me->fork[m] = USED; - me->isHungry[m] = 0U; - pe = Q_NEW(TableEvt, EAT_SIG); - pe->philoNum = m; + me->isHungry[m] = false; + #ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, EAT_SIG, m); + #else + TableEvt *pe = Q_NEW(TableEvt, EAT_SIG); + pe->philoId = m; + #endif QACTIVE_PUBLISH(&pe->super, &me->super); - BSP_displayPhilStat(m, "eating "); + BSP_displayPhilStat(m, EATING); } - m = LEFT(n); /* check the left neighbor */ - n = LEFT(m); /* left fork of the left neighbor */ - if ((me->isHungry[m] != 0U) && (me->fork[n] == FREE)) { + m = left(n); // check the left neighbor + n = left(m); // left fork of the left neighbor + if (me->isHungry[m] && (me->fork[n] == FREE)) { me->fork[m] = USED; me->fork[n] = USED; - me->isHungry[m] = 0U; - pe = Q_NEW(TableEvt, EAT_SIG); - pe->philoNum = m; + me->isHungry[m] = false; + #ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, EAT_SIG, m); + #else + TableEvt *pe = Q_NEW(TableEvt, EAT_SIG); + pe->philoId = m; + #endif QACTIVE_PUBLISH(&pe->super, &me->super); - BSP_displayPhilStat(m, "eating "); + BSP_displayPhilStat(m, EATING); } status_ = Q_HANDLED(); break; } - /*${AOs::Table::SM::active::serving::EAT} */ + //${AOs::Table::SM::active::serving::EAT} case EAT_SIG: { Q_ERROR(); status_ = Q_HANDLED(); break; } - /*${AOs::Table::SM::active::serving::PAUSE} */ + //${AOs::Table::SM::active::serving::PAUSE} case PAUSE_SIG: { status_ = Q_TRAN(&Table_paused); break; @@ -262,48 +282,50 @@ static QState Table_serving(Table * const me, QEvt const * const e) { return status_; } -/*${AOs::Table::SM::active::paused} ........................................*/ +//${AOs::Table::SM::active::paused} .......................................... static QState Table_paused(Table * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${AOs::Table::SM::active::paused} */ + //${AOs::Table::SM::active::paused} case Q_ENTRY_SIG: { BSP_displayPaused(1U); status_ = Q_HANDLED(); break; } - /*${AOs::Table::SM::active::paused} */ + //${AOs::Table::SM::active::paused} case Q_EXIT_SIG: { BSP_displayPaused(0U); status_ = Q_HANDLED(); break; } - /*${AOs::Table::SM::active::paused::SERVE} */ + //${AOs::Table::SM::active::paused::SERVE} case SERVE_SIG: { status_ = Q_TRAN(&Table_serving); break; } - /*${AOs::Table::SM::active::paused::HUNGRY} */ + //${AOs::Table::SM::active::paused::HUNGRY} case HUNGRY_SIG: { - uint8_t n = Q_EVT_CAST(TableEvt)->philoNum; - /* philo ID must be in range and he must be not hungry */ - Q_ASSERT((n < N_PHILO) && (me->isHungry[n] == 0U)); - me->isHungry[n] = 1U; - BSP_displayPhilStat(n, "hungry "); + uint8_t n = Q_EVT_CAST(TableEvt)->philoId; + + // philo ID must be in range and he must be not hungry + Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); + + me->isHungry[n] = true; + BSP_displayPhilStat(n, HUNGRY); status_ = Q_HANDLED(); break; } - /*${AOs::Table::SM::active::paused::DONE} */ + //${AOs::Table::SM::active::paused::DONE} case DONE_SIG: { - uint8_t n, m; + uint8_t n = Q_EVT_CAST(TableEvt)->philoId; - n = Q_EVT_CAST(TableEvt)->philoNum; - /* phil ID must be in range and he must be not hungry */ - Q_ASSERT((n < N_PHILO) && (me->isHungry[n] == 0U)); + // phil ID must be in range and he must be not hungry + Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); - BSP_displayPhilStat(n, "thinking"); - m = LEFT(n); - /* both forks of Phil[n] must be used */ + BSP_displayPhilStat(n, THINKING); + uint8_t m = left(n); + + // both forks of Phil[n] must be used Q_ASSERT((me->fork[n] == USED) && (me->fork[m] == USED)); me->fork[m] = FREE; @@ -318,4 +340,4 @@ static QState Table_paused(Table * const me, QEvt const * const e) { } return status_; } -/*$enddef${AOs::Table} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$enddef${AOs::Table} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/examples/arm-cm/game_efm32-slstk3401a/README.md b/examples/arm-cm/game_efm32-slstk3401a/README.md index 3b1e9ed5..82697911 100644 --- a/examples/arm-cm/game_efm32-slstk3401a/README.md +++ b/examples/arm-cm/game_efm32-slstk3401a/README.md @@ -44,10 +44,10 @@ Please check the Device Manager to find the COM port number. # Win32-GUI Emulation -The sub-directory "win32-gui" provides the emulation of the example -on Windows GUI, either single-threaded (win32-qv) or multithreded (win32). -This sub-directory contains the Makefile for the GNU-GCC toolset (MinGW) -and Visual Studio solution file (game-gui.sln) for Visual C++. +The directory `qpc\examples\workstation\game-gui` conatins the emulation +of the "Fly 'n' Shoot" game on Windows GUI, either single-threaded (win32-qv) +or multithreded (win32). This sub-directory contains the Visual Studio +solution file (game-gui.sln) for Visual C++. The Win32-GUI emulation is based on the QWin™ GUI Prototyping Toolkit, see: diff --git a/examples/arm-cm/game_efm32-slstk3401a/bsp.h b/examples/arm-cm/game_efm32-slstk3401a/bsp.h index 4fcee479..7c3e38e3 100644 --- a/examples/arm-cm/game_efm32-slstk3401a/bsp.h +++ b/examples/arm-cm/game_efm32-slstk3401a/bsp.h @@ -1,38 +1,38 @@ -/***************************************************************************** -* Product: "Fly 'n' Shoot" game example on EFM32-SLSTK3401A board -* Last updated for version 5.8.1 -* Last updated on 2016-12-12 -* -* Q u a n t u m L e a P s -* --------------------------- -* innovating embedded systems -* -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* -* -*****************************************************************************/ -#ifndef BSP_H -#define BSP_H +//============================================================================ +// Product: "Fly 'n' Shoot" game example on EFM32-SLSTK3401A board +// Last updated for version 7.3.0 +// Last updated on 2023-06-29 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// This program is open source software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Alternatively, this program may be distributed and modified under the +// terms of Quantum Leaps commercial licenses, which expressly supersede +// the GNU General Public License and are specifically designed for +// licensees interested in retaining the proprietary status of their code. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Contact information: +// +// +//============================================================================ +#ifndef BSP_H_ +#define BSP_H_ #define BSP_TICKS_PER_SEC 33U #define BSP_SCREEN_WIDTH 128U @@ -49,7 +49,7 @@ void BSP_paintBitmap(uint8_t x, uint8_t y, uint8_t bmp_id); void BSP_advanceWalls(uint8_t top, uint8_t bottom); void BSP_updateScore(uint16_t score); -bool BSP_isThrottle(void); /* is the throttle button depressed? */ +bool BSP_isThrottle(void); // is the throttle button depressed? bool BSP_doBitmapsOverlap(uint8_t bmp_id1, uint8_t x1, uint8_t y1, uint8_t bmp_id2, uint8_t x2, uint8_t y2); bool BSP_isWallHit(uint8_t bmp_id, uint8_t x, uint8_t y); @@ -57,9 +57,9 @@ bool BSP_isWallHit(uint8_t bmp_id, uint8_t x, uint8_t y); void BSP_displayOn(void); void BSP_displayOff(void); -void BSP_randomSeed(uint32_t seed); /* random seed */ -uint32_t BSP_random(void); /* pseudo-random generator */ +void BSP_randomSeed(uint32_t seed); // random seed +uint32_t BSP_random(void); // pseudo-random generator -extern QActive *the_Ticker0; /* "Ticker" active object for tick rate 0 */ +extern QActive *const the_Ticker0; // "Ticker" AO for tick rate 0 -#endif /* BSP_H */ +#endif // BSP_H_ diff --git a/examples/arm-cm/game_efm32-slstk3401a/efm32-slstk3401a.jpg b/examples/arm-cm/game_efm32-slstk3401a/efm32-slstk3401a.jpg new file mode 100644 index 00000000..384488d9 Binary files /dev/null and b/examples/arm-cm/game_efm32-slstk3401a/efm32-slstk3401a.jpg differ diff --git a/examples/arm-cm/game_efm32-slstk3401a/game.h b/examples/arm-cm/game_efm32-slstk3401a/game.h index ed86a814..2b48bd58 100644 --- a/examples/arm-cm/game_efm32-slstk3401a/game.h +++ b/examples/arm-cm/game_efm32-slstk3401a/game.h @@ -1,66 +1,66 @@ -/*$file${.::game.h} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* -* Model: game.qm -* File: ${.::game.h} -* -* This code has been generated by QM 5.2.4 . -* DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. -* -* SPDX-License-Identifier: GPL-3.0-or-later -* -* This generated code is open source software: you can redistribute it under -* the terms of the GNU General Public License as published by the Free -* Software Foundation. -* -* This code is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -* more details. -* -* NOTE: -* Alternatively, this generated code may be distributed under the terms -* of Quantum Leaps commercial licenses, which expressly supersede the GNU -* General Public License and are specifically designed for licensees -* interested in retaining the proprietary status of their code. -* -* Contact information: -* -* -*/ -/*$endhead${.::game.h} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$file${.::game.h} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// +// Model: game.qm +// File: ${.::game.h} +// +// This code has been generated by QM 5.3.0 . +// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. +// +// SPDX-License-Identifier: GPL-3.0-or-later +// +// This generated code is open source software: you can redistribute it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation. +// +// This code is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// NOTE: +// Alternatively, this generated code may be distributed under the terms +// of Quantum Leaps commercial licenses, which expressly supersede the GNU +// General Public License and are specifically designed for licensees +// interested in retaining the proprietary status of their code. +// +// Contact information: +// +// +// +//$endhead${.::game.h} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ #ifndef GAME_H #define GAME_H -enum GameSignals { /* signals used in the game */ - TIME_TICK_SIG = Q_USER_SIG, /* published from tick ISR */ - PLAYER_TRIGGER_SIG, /* published by Player (ISR) to trigger the Missile */ - PLAYER_QUIT_SIG, /* published by Player (ISR) to quit the game */ - GAME_OVER_SIG, /* published by Ship when it finishes exploding */ +enum GameSignals { // signals used in the game + TIME_TICK_SIG = Q_USER_SIG, // published from tick ISR + PLAYER_TRIGGER_SIG, // published by Player (ISR) to trigger the Missile + PLAYER_QUIT_SIG, // published by Player (ISR) to quit the game + GAME_OVER_SIG, // published by Ship when it finishes exploding - /* insert other published signals here ... */ - MAX_PUB_SIG, /* the last published signal */ + // insert other published signals here ... + MAX_PUB_SIG, // the last published signal - PLAYER_SHIP_UP_SIG, /* posted by Player (ISR) to Ship to move it up */ - PLAYER_SHIP_DOWN_SIG, /* posted by Player (ISR) to Ship to let if fall */ + PLAYER_SHIP_UP_SIG, // posted by Player (ISR) to Ship to move it up + PLAYER_SHIP_DOWN_SIG, // posted by Player (ISR) to Ship to let if fall - BLINK_TIMEOUT_SIG, /* signal for Tunnel's blink timeout event */ - SCREEN_TIMEOUT_SIG, /* signal for Tunnel's screen timeout event */ + BLINK_TIMEOUT_SIG, // signal for Tunnel's blink timeout event + SCREEN_TIMEOUT_SIG, // signal for Tunnel's screen timeout event - TAKE_OFF_SIG, /* from Tunnel to Ship to grant permission to take off */ - HIT_WALL_SIG, /* from Tunnel to Ship when Ship hits the wall */ - HIT_MINE_SIG, /* from Mine to Ship or Missile when it hits the mine */ - SHIP_IMG_SIG, /* from Ship to the Tunnel to draw and check for hits */ - MISSILE_IMG_SIG, /* from Missile the Tunnel to draw and check for hits */ - MINE_IMG_SIG, /* sent by Mine to the Tunnel to draw the mine */ - MISSILE_FIRE_SIG, /* sent by Ship to the Missile to fire */ - DESTROYED_MINE_SIG, /* from Missile to Ship when Missile destroyed Mine */ - EXPLOSION_SIG, /* from any exploding object to render the explosion */ - MINE_PLANT_SIG, /* from Tunnel to the Mine to plant it */ - MINE_DISABLED_SIG, /* from Mine to Tunnel when it becomes disabled */ - MINE_RECYCLE_SIG, /* sent by Tunnel to Mine to recycle the mine */ - SCORE_SIG, /* from Ship to Tunnel to adjust game level based on score */ + TAKE_OFF_SIG, // from Tunnel to Ship to grant permission to take off + HIT_WALL_SIG, // from Tunnel to Ship when Ship hits the wall + HIT_MINE_SIG, // from Mine to Ship or Missile when it hits the mine + SHIP_IMG_SIG, // from Ship to the Tunnel to draw and check for hits + MISSILE_IMG_SIG, // from Missile the Tunnel to draw and check for hits + MINE_IMG_SIG, // sent by Mine to the Tunnel to draw the mine + MISSILE_FIRE_SIG, // sent by Ship to the Missile to fire + DESTROYED_MINE_SIG, // from Missile to Ship when Missile destroyed Mine + EXPLOSION_SIG, // from any exploding object to render the explosion + MINE_PLANT_SIG, // from Tunnel to the Mine to plant it + MINE_DISABLED_SIG, // from Mine to Tunnel when it becomes disabled + MINE_RECYCLE_SIG, // sent by Tunnel to Mine to recycle the mine + SCORE_SIG, // from Ship to Tunnel to adjust game level based on score - MAX_SIG /* the last signal (keep always last) */ + MAX_SIG // the last signal (keep always last) }; #define GAME_TUNNEL_WIDTH BSP_SCREEN_WIDTH @@ -87,75 +87,74 @@ enum GameBitmapIds { MAX_BMP }; -/* declare shared facilities */ -/*$declare${Shared} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +// declare shared facilities +//$declare${Shared} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/*${Shared::ObjectPosEvt} ..................................................*/ +//${Shared::ObjectPosEvt} .................................................... typedef struct { -/* protected: */ +// protected: QEvt super; -/* public: */ +// public: uint8_t x; uint8_t y; } ObjectPosEvt; -/*${Shared::ObjectImageEvt} ................................................*/ +//${Shared::ObjectImageEvt} .................................................. typedef struct { -/* protected: */ +// protected: QEvt super; -/* public: */ +// public: uint8_t x; int8_t y; uint8_t bmp; } ObjectImageEvt; -/*${Shared::MineEvt} .......................................................*/ +//${Shared::MineEvt} ......................................................... typedef struct { -/* protected: */ +// protected: QEvt super; -/* public: */ +// public: uint8_t id; } MineEvt; -/*${Shared::ScoreEvt} ......................................................*/ +//${Shared::ScoreEvt} ........................................................ typedef struct { -/* protected: */ +// protected: QEvt super; -/* public: */ +// public: uint16_t score; } ScoreEvt; -/*${Shared::AO_Tunnel} .....................................................*/ -/* opaque AO pointer */ +//${Shared::AO_Tunnel} ....................................................... +// opaque AO pointer extern QActive * const AO_Tunnel; -/*${Shared::AO_Ship} .......................................................*/ -/* opaque AO pointer */ +//${Shared::AO_Ship} ......................................................... +// opaque AO pointer extern QActive * const AO_Ship; -/*${Shared::AO_Missile} ....................................................*/ -/* opaque AO pointer */ +//${Shared::AO_Missile} ...................................................... +// opaque AO pointer extern QActive * const AO_Missile; -/*${Shared::Tunnel_ctor_call} ..............................................*/ +//${Shared::Tunnel_ctor_call} ................................................ void Tunnel_ctor_call(void); -/*${Shared::Ship_ctor_call} ................................................*/ +//${Shared::Ship_ctor_call} .................................................. void Ship_ctor_call(void); -/*${Shared::Missile_ctor_call} .............................................*/ +//${Shared::Missile_ctor_call} ............................................... void Missile_ctor_call(void); -/*${Shared::Mine1_ctor_call} ...............................................*/ +//${Shared::Mine1_ctor_call} ................................................. QHsm * Mine1_ctor_call(uint8_t id); -/*${Shared::Mine2_ctor_call} ...............................................*/ +//${Shared::Mine2_ctor_call} ................................................. QHsm * Mine2_ctor_call(uint8_t id); -/*$enddecl${Shared} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ - -#endif /* GAME_H */ +//$enddecl${Shared} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +#endif // GAME_H diff --git a/examples/arm-cm/game_efm32-slstk3401a/game.qm b/examples/arm-cm/game_efm32-slstk3401a/game.qm index 11aeff2e..4256eb9b 100644 --- a/examples/arm-cm/game_efm32-slstk3401a/game.qm +++ b/examples/arm-cm/game_efm32-slstk3401a/game.qm @@ -1,5 +1,5 @@ - + "Fly 'n' Shoot" game model from Chapters 1 & 9 of PSiCC2 @@ -33,17 +33,17 @@ - /* opaque AO pointer */ + // opaque AO pointer = &Tunnel_inst.super; - /* opaque AO pointer */ + // opaque AO pointer = &Ship_inst.super; - /* opaque AO pointer */ + // opaque AO pointer = &Missile_inst.super; @@ -112,19 +112,19 @@ return &Mine2_inst[id].super; rnd = (BSP_random() & 0xFFU); -/* reduce the top wall thickness 18.75% of the time */ +// reduce the top wall thickness 18.75% of the time if ((rnd < 48U) && (me->wall_thickness_top > 0U)) { --me->wall_thickness_top; } -/* reduce the bottom wall thickness 18.75% of the time */ +// reduce the bottom wall thickness 18.75% of the time if ((rnd > 208U) && (me->wall_thickness_bottom > 0U)) { --me->wall_thickness_bottom; } rnd = (BSP_random() & 0xFFU); -/* grow the bottom wall thickness 19.14% of the time */ +// grow the bottom wall thickness 19.14% of the time if ((rnd < 49U) && ((GAME_TUNNEL_HEIGHT - me->wall_thickness_top @@ -133,7 +133,7 @@ if ((rnd < 49U) ++me->wall_thickness_bottom; } -/* grow the top wall thickness 19.14% of the time */ +// grow the top wall thickness 19.14% of the time if ((rnd > 207U) && ((GAME_TUNNEL_HEIGHT - me->wall_thickness_top @@ -142,9 +142,8 @@ if ((rnd > 207U) ++me->wall_thickness_top; } -/* advance the Tunnel by 1 game step to the left -* and copy the Tunnel layer to the main frame buffer -*/ +// advance the Tunnel by 1 game step to the left +// and copy the Tunnel layer to the main frame buffer BSP_advanceWalls(me->wall_thickness_top, me->wall_thickness_bottom); @@ -152,43 +151,43 @@ BSP_advanceWalls(me->wall_thickness_top, me->wall_thickness_bottom);uint32_t rnd = (BSP_random() & 0xFFU); if (me->last_mine_x > 0U) { - --me->last_mine_x; /* shift the last Mine 1 position to the left */ + --me->last_mine_x; // shift the last Mine 1 position to the left } -/* last mine far enough? */ +// last mine far enough? if ((me->last_mine_x + GAME_MINES_DIST_MIN < GAME_TUNNEL_WIDTH) - && (rnd < 8U)) /* place the mines only 5% of the time */ + && (rnd < 8U)) // place the mines only 5% of the time { uint8_t n; - for (n = 0U; n < Q_DIM(me->mines); ++n) { /*look for disabled mines */ + for (n = 0U; n < Q_DIM(me->mines); ++n) { //look for disabled mines if (me->mines[n] == (QHsm *)0) { break; } } - if (n < Q_DIM(me->mines)) { /* a disabled Mine found? */ - ObjectPosEvt ope; /* event to dispatch to the Mine */ + if (n < Q_DIM(me->mines)) { // a disabled Mine found? rnd = (BSP_random() & 0xFFFFU); - if ((rnd & 1U) == 0U) { /* choose the type of the mine */ + if ((rnd & 1U) == 0U) { // choose the type of the mine me->mines[n] = me->mine1_pool[n]; } else { me->mines[n] = me->mine2_pool[n]; } - /* new Mine is planted by the end of the tunnel */ + // new Mine is planted by the end of the tunnel me->last_mine_x = GAME_TUNNEL_WIDTH - 8U; - /* choose a random y-position for the Mine in the Tunnel */ + // choose a random y-position for the Mine in the Tunnel rnd %= (GAME_TUNNEL_HEIGHT - me->wall_thickness_top - me->wall_thickness_bottom - 4U); me->last_mine_y = (uint8_t)(me->wall_thickness_top + 2U + rnd); - ope.super.sig = MINE_PLANT_SIG; + ObjectPosEvt ope; // event to dispatch to the Mine + QEvt_ctor(&ope.super, MINE_PLANT_SIG); ope.x = me->last_mine_x; ope.y = me->last_mine_y; - /* direct dispatch */ - QHSM_DISPATCH(me->mines[n], (QEvt *)&ope, me->super.prio); + // direct dispatch + QASM_DISPATCH(me->mines[n], &ope.super, me->super.prio); } } @@ -196,10 +195,9 @@ if ((me->last_mine_x + GAME_MINES_DIST_MIN < GAME_TUNNEL_WIDTH) - uint8_t n; -for (n = 0U; n < GAME_MINES_MAX; ++n) { - if (me->mines[n] != (QHsm *)0) { /* is the mine used? */ - QHSM_DISPATCH(me->mines[n], e, me->super.prio); + for (uint8_t n = 0U; n < GAME_MINES_MAX; ++n) { + if (me->mines[n] != (QHsm *)0) { // is the mine used? + QASM_DISPATCH(me->mines[n], e, me->super.prio); } } @@ -211,11 +209,11 @@ QActive_ctor(&me->super, Q_STATE_CAST(&Tunnel_initial)); QTimeEvt_ctorX(&me->blinkTimeEvt, &me->super, BLINK_TIMEOUT_SIG, 0U); QTimeEvt_ctorX(&me->screenTimeEvt, &me->super, SCREEN_TIMEOUT_SIG, 0U); for (n = 0; n < GAME_MINES_MAX; ++n) { - me->mine1_pool[n] = Mine1_ctor_call(n); /* instantiate Mine1 */ - me->mine2_pool[n] = Mine2_ctor_call(n); /* instantiate Mine2 */ - me->mines[n] = (QHsm *)0; /* mine 'n' is unused */ + me->mine1_pool[n] = Mine1_ctor_call(n); // instantiate Mine1 + me->mine2_pool[n] = Mine2_ctor_call(n); // instantiate Mine2 + me->mines[n] = (QHsm *)0; // mine 'n' is unused } -me->last_mine_x = 0; /* the last mine at the right edge of the tunnel */ +me->last_mine_x = 0; // the last mine at the right edge of the tunnel me->last_mine_y = 0; @@ -224,20 +222,20 @@ me->last_mine_y = 0; uint8_t n; for (n = 0U; n < GAME_MINES_MAX; ++n) { - QHSM_INIT(me->mine1_pool[n], (void *)0, me->super.prio); - QHSM_INIT(me->mine2_pool[n], (void *)0, me->super.prio); + QASM_INIT(me->mine1_pool[n], (void *)0, me->super.prio); + QASM_INIT(me->mine2_pool[n], (void *)0, me->super.prio); } -BSP_randomSeed(1234); /* seed the pseudo-random generator */ +BSP_randomSeed(1234); // seed the pseudo-random generator QActive_subscribe(&me->super, TIME_TICK_SIG); QActive_subscribe(&me->super, PLAYER_TRIGGER_SIG); QActive_subscribe(&me->super, PLAYER_QUIT_SIG); -/* object dictionaries... */ +// object dictionaries... QS_OBJ_DICTIONARY(&Tunnel_inst.blinkTimeEvt); QS_OBJ_DICTIONARY(&Tunnel_inst.screenTimeEvt); -/* local signals... */ +// local signals... QS_SIG_DICTIONARY(BLINK_TIMEOUT_SIG, me); QS_SIG_DICTIONARY(SCREEN_TIMEOUT_SIG, me); QS_SIG_DICTIONARY(SHIP_IMG_SIG, me); @@ -247,7 +245,7 @@ QS_SIG_DICTIONARY(MINE_DISABLED_SIG, me); QS_SIG_DICTIONARY(EXPLOSION_SIG, me); QS_SIG_DICTIONARY(SCORE_SIG, me); -(void)par; /* unused parameter */ +(void)par; // unused parameter @@ -292,7 +290,7 @@ QTimeEvt_disarm(&me->screenTimeEvt); - me->blink_ctr ^= 1U; /* toggle the blink counter */ + me->blink_ctr ^= 1U; // toggle the blink counter me->blink_ctr == 0U @@ -322,26 +320,26 @@ BSP_updateScreen(); - me->last_mine_x = 0U; /* last mine at right edge of the tunnel */ + me->last_mine_x = 0U; // last mine at right edge of the tunnel me->last_mine_y = 0U; -/* set the tunnel properties... */ +// set the tunnel properties... me->wall_thickness_top = 0U; me->wall_thickness_bottom = 0U; me->wall_gap = GAME_WALLS_GAP_Y; -/* clear the tunnel walls */ +// clear the tunnel walls BSP_clearWalls(); QTimeEvt_armX(&me->blinkTimeEvt, BSP_TICKS_PER_SEC/2U, - BSP_TICKS_PER_SEC/2U); /* every 1/2 sec */ + BSP_TICKS_PER_SEC/2U); // every 1/2 sec QTimeEvt_armX(&me->screenTimeEvt, BSP_TICKS_PER_SEC*20U, 0U); -me->blink_ctr = 0U; /* init the blink counter */ +me->blink_ctr = 0U; // init the blink counter QTimeEvt_disarm(&me->blinkTimeEvt); QTimeEvt_disarm(&me->screenTimeEvt); - me->blink_ctr ^= 1U; /* toggle the blink cunter */ + me->blink_ctr ^= 1U; // toggle the blink cunter @@ -356,7 +354,7 @@ QTimeEvt_disarm(&me->screenTimeEvt); Tunnel_advance(me); if (me->blink_ctr != 0U) { - /* add the text bitmap into the frame buffer */ + // add the text bitmap into the frame buffer BSP_paintString((GAME_TUNNEL_WIDTH - 10U*6U)/2U, (GAME_TUNNEL_HEIGHT - 4U)/2U, "Press BTN0"); @@ -379,15 +377,14 @@ BSP_updateScreen(); - static QEvt const takeoff = { TAKE_OFF_SIG, 0U, 0U }; + static QEvt const takeoff = QEVT_INITIALIZER(TAKE_OFF_SIG); me->wall_gap = GAME_WALLS_GAP_Y; -QACTIVE_POST(AO_Ship, &takeoff, me); /* post the TAKEOFF sig */ - QEvt recycle; -recycle.sig = MINE_RECYCLE_SIG; -Tunnel_dispatchToAllMines(me, &recycle); /* recycle all Mines */ +QACTIVE_POST(AO_Ship, &takeoff, me); // post the TAKEOFF sig + static QEvt const recycle = QEVT_INITIALIZER(MINE_RECYCLE_SIG); +Tunnel_dispatchToAllMines(me, &recycle); // recycle all Mines - /* render this frame on the display */ + // render this frame on the display BSP_updateScreen(); Tunnel_advance(me); Tunnel_plantMine(me); @@ -402,13 +399,13 @@ Tunnel_dispatchToAllMines(me, e); int8_t y = Q_EVT_CAST(ObjectImageEvt)->y; uint8_t bmp = Q_EVT_CAST(ObjectImageEvt)->bmp; -/* did the Ship/Missile hit the tunnel wall? */ +// did the Ship/Missile hit the tunnel wall? if (BSP_isWallHit(bmp, x, y)) { - static QEvt const hit = { HIT_WALL_SIG, 0U, 0U }; + static QEvt const hit = QEVT_INITIALIZER(HIT_WALL_SIG); QACTIVE_POST(AO_Ship, &hit, me); } BSP_paintBitmap(x, y, bmp); -Tunnel_dispatchToAllMines(me, e); /* let Mines check for hits */ +Tunnel_dispatchToAllMines(me, e); // let Mines check for hits @@ -419,13 +416,13 @@ Tunnel_dispatchToAllMines(me, e); /* let Mines check for hits */ int8_t y = Q_EVT_CAST(ObjectImageEvt)->y; uint8_t bmp = Q_EVT_CAST(ObjectImageEvt)->bmp; -/* did the Ship/Missile hit the tunnel wall? */ +// did the Ship/Missile hit the tunnel wall? if (BSP_isWallHit(bmp, x, y)) { - static QEvt const hit = { HIT_WALL_SIG, 0U, 0U }; + static QEvt const hit = QEVT_INITIALIZER(HIT_WALL_SIG); QACTIVE_POST(AO_Missile, &hit, me); } BSP_paintBitmap(x, y, bmp); -Tunnel_dispatchToAllMines(me, e); /* let Mines check for hits */ +Tunnel_dispatchToAllMines(me, e); // let Mines check for hits @@ -451,9 +448,8 @@ Tunnel_dispatchToAllMines(me, e); /* let Mines check for hits */ BSP_updateScore(Q_EVT_CAST(ScoreEvt)->score); -/* increase difficulty of the game: -* the tunnel gets narrower as the score goes up -*/ +// increase difficulty of the game: +// the tunnel gets narrower as the score goes up me->wall_gap = (uint8_t)(GAME_WALLS_GAP_Y - Q_EVT_CAST(ScoreEvt)->score/100U); if (me->wall_gap < GAME_WALLS_MIN_GAP_Y) { @@ -480,7 +476,7 @@ BSP_updateScreen(); QTimeEvt_armX(&me->blinkTimeEvt, BSP_TICKS_PER_SEC/2U, - BSP_TICKS_PER_SEC/2U); /* every 1/2 sec */ + BSP_TICKS_PER_SEC/2U); // every 1/2 sec QTimeEvt_armX(&me->screenTimeEvt, BSP_TICKS_PER_SEC*5U, 0U); me->blink_ctr = 0U; BSP_paintString((GAME_TUNNEL_WIDTH - 6U * 9U) / 2U, @@ -489,10 +485,10 @@ BSP_paintString((GAME_TUNNEL_WIDTH - 6U * 9U) / 2U, BSP_updateScreen(); QTimeEvt_disarm(&me->blinkTimeEvt); QTimeEvt_disarm(&me->screenTimeEvt); -BSP_updateScore(0); /* update the score on the display */ +BSP_updateScore(0); // update the score on the display - me->blink_ctr ^= 1U; /* toggle the blink counter */ + me->blink_ctr ^= 1U; // toggle the blink counter BSP_paintString((GAME_TUNNEL_WIDTH - 6U*9U) / 2U, (GAME_TUNNEL_HEIGHT / 2U) - 4U, ((me->blink_ctr == 0U) @@ -530,10 +526,10 @@ BSP_updateScreen(); - BSP_displayOff(); /* power down the display */ + BSP_displayOff(); // power down the display QTimeEvt_armX(&me->screenTimeEvt, BSP_TICKS_PER_SEC*3U, 0U); QTimeEvt_disarm(&me->screenTimeEvt); -BSP_displayOn(); /* power up the display */ +BSP_displayOn(); // power up the display @@ -548,7 +544,7 @@ BSP_displayOn(); /* power up the display */ uint32_t rnd = BSP_random(); -/* clear the screen frame buffer */ +// clear the screen frame buffer BSP_clearFB(); BSP_paintString((uint8_t)(rnd % (GAME_TUNNEL_WIDTH - 10U*6U)), (uint8_t) (rnd % (GAME_TUNNEL_HEIGHT - 8U)), @@ -575,10 +571,10 @@ BSP_updateScreen(); - /* clear the screen */ + // clear the screen BSP_clearFB(); BSP_updateScreen(); -QF_stop(); /* stop QF and cleanup */ +QF_stop(); // stop QF and cleanup @@ -614,12 +610,12 @@ me->y = (GAME_SHIP_Y << 2); - (void)par; /* usused parameter */ + (void)par; // usused parameter QActive_subscribe(&me->super, TIME_TICK_SIG); QActive_subscribe(&me->super, PLAYER_TRIGGER_SIG); -/* local signals... */ +// local signals... //QS_SIG_DICTIONARY(PLAYER_SHIP_MOVE_SIG, me); QS_SIG_DICTIONARY(TAKE_OFF_SIG, me); QS_SIG_DICTIONARY(HIT_WALL_SIG, me); @@ -650,12 +646,12 @@ QS_SIG_DICTIONARY(DESTROYED_MINE_SIG, me); ScoreEvt *sev; -me->score = 0U; /* reset the score */ +me->score = 0U; // reset the score sev = Q_NEW(ScoreEvt, SCORE_SIG); sev->score = me->score; QACTIVE_POST(AO_Tunnel, (QEvt *)sev, me); -/* lauch the ship from the initial position */ +// lauch the ship from the initial position me->x = GAME_SHIP_X; me->y = (GAME_SHIP_Y << 2); @@ -673,16 +669,16 @@ else { } } -/* tell the Tunnel to draw the Ship and test for hits */ +// tell the Tunnel to draw the Ship and test for hits oie = Q_NEW(ObjectImageEvt, SHIP_IMG_SIG); oie->x = me->x; oie->y = (uint8_t)(me->y >> 2); oie->bmp = SHIP_BMP; QACTIVE_POST(AO_Tunnel, (QEvt *)oie, me); -++me->score; /* increment the score for surviving another tick */ +++me->score; // increment the score for surviving another tick -if ((me->score % 10U) == 0U) { /* is the score "round"? */ +if ((me->score % 10U) == 0U) { // is the score "round"? ScoreEvt *sev = Q_NEW(ScoreEvt, SCORE_SIG); sev->score = me->score; QACTIVE_POST(AO_Tunnel, (QEvt *)sev, me); @@ -704,7 +700,7 @@ QACTIVE_POST(AO_Missile, (QEvt *)ope, me); me->score += Q_EVT_CAST(ScoreEvt)->score; -/* the score will be sent to the Tunnel by the next TIME_TICK */ +// the score will be sent to the Tunnel by the next TIME_TICK @@ -735,10 +731,10 @@ QACTIVE_POST(AO_Missile, (QEvt *)ope, me); me->exp_ctr < 15U ObjectImageEvt *oie; ++me->exp_ctr; -/* tell the Tunnel to draw the current stage of Explosion */ +// tell the Tunnel to draw the current stage of Explosion oie = Q_NEW(ObjectImageEvt, EXPLOSION_SIG); oie->bmp = EXPLOSION0_BMP + (me->exp_ctr >> 2); -oie->x = me->x; /* x of explosion */ +oie->x = me->x; // x of explosion oie->y = (int8_t)((int)(me->y >> 2) - 4U + SHIP_HEIGHT); QACTIVE_POST(AO_Tunnel, (QEvt *)oie, me); @@ -790,10 +786,10 @@ QACTIVE_POST(AO_Tunnel, (QEvt *)gameOver, me); - (void)par; /* unused parameter */ + (void)par; // unused parameter QActive_subscribe(&me->super, TIME_TICK_SIG); -/* local signals */ +// local signals QS_SIG_DICTIONARY(MISSILE_FIRE_SIG, me); QS_SIG_DICTIONARY(HIT_WALL_SIG, me); QS_SIG_DICTIONARY(DESTROYED_MINE_SIG, me); @@ -822,7 +818,7 @@ me->y = Q_EVT_CAST(ObjectPosEvt)->y; me->x + GAME_MISSILE_SPEED_X < GAME_TUNNEL_WIDTH ObjectImageEvt *oie; me->x += GAME_MISSILE_SPEED_X; -/*tell the Tunnel to draw the Missile and test for wall hits*/ +//tell the Tunnel to draw the Missile and test for wall hits oie = Q_NEW(ObjectImageEvt, MISSILE_IMG_SIG); oie->x = me->x; oie->y = me->y; @@ -868,13 +864,13 @@ QACTIVE_POST(AO_Tunnel, (QEvt *)oie, me); (me->x >= GAME_SPEED_X) && (me->exp_ctr < 15U) ObjectImageEvt *oie; -++me->exp_ctr; /* advance the explosion counter */ -me->x -= GAME_SPEED_X; /* move the explosion by one step */ +++me->exp_ctr; // advance the explosion counter +me->x -= GAME_SPEED_X; // move the explosion by one step -/* tell the Tunnel to render the current stage of Explosion */ +// tell the Tunnel to render the current stage of Explosion oie = Q_NEW(ObjectImageEvt, EXPLOSION_SIG); -oie->x = me->x + 3U; /* x-pos of explosion */ -oie->y = (int8_t)((int)me->y - 4U); /* y-pos */ +oie->x = me->x + 3U; // x-pos of explosion +oie->y = (int8_t)((int)me->y - 4U); // y-pos oie->bmp = EXPLOSION0_BMP + (me->exp_ctr >> 2); QACTIVE_POST(AO_Tunnel, (QEvt *)oie, me); @@ -915,7 +911,7 @@ QACTIVE_POST(AO_Tunnel, (QEvt *)oie, me); constructor - /* superclass' ctor */ + // superclass' ctor QHsm_ctor(&me->super, Q_STATE_CAST(&Mine1_initial)); @@ -931,7 +927,7 @@ if (!dict_sent) { QS_OBJ_DICTIONARY(&Mine1_inst[3]); QS_OBJ_DICTIONARY(&Mine1_inst[4]); - QS_FUN_DICTIONARY(&Mine1_initial);/*fun. dictionaries for Mine1 HSM */ + QS_FUN_DICTIONARY(&Mine1_initial);//fun. dictionaries for Mine1 HSM QS_FUN_DICTIONARY(&Mine1_unused); QS_FUN_DICTIONARY(&Mine1_used); QS_FUN_DICTIONARY(&Mine1_planted); @@ -939,14 +935,14 @@ if (!dict_sent) { dict_sent = 1U; } -/* local signals */ +// local signals QS_SIG_DICTIONARY(MINE_PLANT_SIG, me); QS_SIG_DICTIONARY(MINE_DISABLED_SIG, me); QS_SIG_DICTIONARY(MINE_RECYCLE_SIG, me); QS_SIG_DICTIONARY(SHIP_IMG_SIG, me); QS_SIG_DICTIONARY(MISSILE_IMG_SIG, me); -(void)par; /* unused parameter */ +(void)par; // unused parameter @@ -965,7 +961,7 @@ me->y = Q_EVT_CAST(ObjectPosEvt)->y; - /* tell the Tunnel that this mine is becoming disabled */ + // tell the Tunnel that this mine is becoming disabled MineEvt *mev = Q_NEW(MineEvt, MINE_DISABLED_SIG); mev->id = MINE_ID(me); QACTIVE_POST(AO_Tunnel, (QEvt *)mev, me); @@ -983,8 +979,8 @@ QACTIVE_POST(AO_Tunnel, (QEvt *)mev, me); me->x >= GAME_SPEED_X ObjectImageEvt *oie; -me->x -= GAME_SPEED_X; /* move the mine 1 step */ -/* tell the Tunnel to draw the Mine */ +me->x -= GAME_SPEED_X; // move the mine 1 step +// tell the Tunnel to draw the Mine oie = Q_NEW(ObjectImageEvt, MINE_IMG_SIG); oie->x = me->x; oie->y = me->y; @@ -1014,12 +1010,11 @@ uint8_t bmp = Q_EVT_CAST(ObjectImageEvt)->bmp; BSP_doBitmapsOverlap(MINE1_BMP, me->x, me->y, bmp, x, y) static MineEvt const mine1_hit = { - { HIT_MINE_SIG, 0U, 0U }, /* the QEvt base instance */ - 1U /* type of the mine (1 for Mine type-1) */ + QEVT_INITIALIZER(HIT_MINE_SIG), // the QEvt base instance + 1U // type of the mine (1 for Mine type-1) }; QACTIVE_POST(AO_Ship, (QEvt *)&mine1_hit, me); -/* go straight to 'disabled' and let the Ship do - * the exploding */ +// go straight to 'disabled' and let the Ship do the exploding @@ -1037,8 +1032,8 @@ uint8_t bmp = Q_EVT_CAST(ObjectImageEvt)->bmp; BSP_doBitmapsOverlap(MINE1_BMP, me->x, me->y, bmp, x, y) static ScoreEvt const mine1_destroyed = { - { DESTROYED_MINE_SIG, 0U, 0U }, /* the QEvt base instance */ - 25U /* score for destroying Mine type-1 */ + QEVT_INITIALIZER(DESTROYED_MINE_SIG), // the QEvt base instance + 25U // score for destroying Mine type-1 }; QACTIVE_POST(AO_Missile, (QEvt *)&mine1_destroyed, me); @@ -1060,13 +1055,13 @@ QACTIVE_POST(AO_Missile, (QEvt *)&mine1_destroyed, me); (me->x >= GAME_SPEED_X) && (me->exp_ctr < 15) ObjectImageEvt *oie; -++me->exp_ctr; /* advance the explosion counter */ -me->x -= GAME_SPEED_X; /* move explosion by 1 step */ +++me->exp_ctr; // advance the explosion counter +me->x -= GAME_SPEED_X; // move explosion by 1 step -/* tell the Game to render the current stage of Explosion */ +// tell the Game to render the current stage of Explosion oie = Q_NEW(ObjectImageEvt, EXPLOSION_SIG); -oie->x = me->x + 1U; /* x of explosion */ -oie->y = (int8_t)((int)me->y - 4 + 2); /* y of explosion */ +oie->x = me->x + 1U; // x of explosion +oie->y = (int8_t)((int)me->y - 4 + 2); // y of explosion oie->bmp = EXPLOSION0_BMP + (me->exp_ctr >> 2); QACTIVE_POST(AO_Tunnel, (QEvt *)oie, me); @@ -1111,7 +1106,7 @@ QACTIVE_POST(AO_Tunnel, (QEvt *)oie, me); constructor - /* superclass' ctor */ + // superclass' ctor QHsm_ctor(&me->super, Q_STATE_CAST(&Mine2_initial)); @@ -1121,14 +1116,14 @@ QHsm_ctor(&me->super, Q_STATE_CAST(&Mine2_initial)); static uint8_t dict_sent; if (!dict_sent) { - /* object dictionaries for Mine2 pool... */ + // object dictionaries for Mine2 pool... QS_OBJ_DICTIONARY(&Mine2_inst[0]); QS_OBJ_DICTIONARY(&Mine2_inst[1]); QS_OBJ_DICTIONARY(&Mine2_inst[2]); QS_OBJ_DICTIONARY(&Mine2_inst[3]); QS_OBJ_DICTIONARY(&Mine2_inst[4]); - /*function dictionaries for Mine2 HSM... */ + //function dictionaries for Mine2 HSM... QS_FUN_DICTIONARY(&Mine2_initial); QS_FUN_DICTIONARY(&Mine2_unused); QS_FUN_DICTIONARY(&Mine2_used); @@ -1137,14 +1132,14 @@ if (!dict_sent) { dict_sent = 1U; } -/* local signals... */ +// local signals... QS_SIG_DICTIONARY(MINE_PLANT_SIG, me); QS_SIG_DICTIONARY(MINE_DISABLED_SIG, me); QS_SIG_DICTIONARY(MINE_RECYCLE_SIG, me); QS_SIG_DICTIONARY(SHIP_IMG_SIG, me); QS_SIG_DICTIONARY(MISSILE_IMG_SIG, me); -(void)par; /* unused parameter */ +(void)par; // unused parameter @@ -1163,7 +1158,7 @@ me->y = Q_EVT_CAST(ObjectPosEvt)->y; - /* tell the Tunnel that this mine is becoming disabled */ + // tell the Tunnel that this mine is becoming disabled MineEvt *mev = Q_NEW(MineEvt, MINE_DISABLED_SIG); mev->id = MINE_ID(me); QACTIVE_POST(AO_Tunnel, (QEvt *)mev, me); @@ -1181,8 +1176,8 @@ QACTIVE_POST(AO_Tunnel, (QEvt *)mev, me); me->x >= GAME_SPEED_X ObjectImageEvt *oie; - me->x -= GAME_SPEED_X; /* move the mine 1 step */ -/* tell the Tunnel to draw the Mine */ + me->x -= GAME_SPEED_X; // move the mine 1 step +// tell the Tunnel to draw the Mine oie = Q_NEW(ObjectImageEvt, MINE_IMG_SIG); oie->x = me->x; oie->y = me->y; @@ -1212,12 +1207,11 @@ uint8_t bmp = Q_EVT_CAST(ObjectImageEvt)->bmp; BSP_doBitmapsOverlap(MINE2_BMP, me->x, me->y, bmp, x, y) static MineEvt const mine1_hit = { - { HIT_MINE_SIG, 0U, 0U }, /* the QEvt base instance */ - 2U /* type of the mine (2 for Mine type-2) */ + QEVT_INITIALIZER(HIT_MINE_SIG), // the QEvt base instance + 2U // type of the mine (2 for Mine type-2) }; - QACTIVE_POST(AO_Ship, (QEvt *)&mine1_hit, me); - /* go straight to 'disabled' and let the Ship do - * the exploding */ +QACTIVE_POST(AO_Ship, (QEvt *)&mine1_hit, me); +// go straight to 'disabled' and let the Ship do the exploding @@ -1234,15 +1228,14 @@ uint8_t bmp = Q_EVT_CAST(ObjectImageEvt)->bmp; BSP_doBitmapsOverlap(MINE2_MISSILE_BMP, me->x, me->y, bmp, x, y) - /* NOTE: Mine type-2 is nastier than Mine type-1. -* The type-2 mine can hit the Ship with any of its -* "tentacles". However, it can be destroyed by the -* Missile only by hitting its center, defined as -* a smaller bitmap MINE2_MISSILE_BMP. -*/ + // NOTE: Mine type-2 is nastier than Mine type-1. +// The type-2 mine can hit the Ship with any of its +// "tentacles". However, it can be destroyed by the +// Missile only by hitting its center, defined as +// a smaller bitmap MINE2_MISSILE_BMP. static ScoreEvt const mine2_destroyed = { - { DESTROYED_MINE_SIG, 0U, 0U }, /* the QEvt base instance */ - 45U /* score for destroying Mine type-2 */ + QEVT_INITIALIZER(DESTROYED_MINE_SIG), // the QEvt base instance + 45U // score for destroying Mine type-2 }; QACTIVE_POST(AO_Missile, (QEvt *)&mine2_destroyed, me); @@ -1264,13 +1257,13 @@ QACTIVE_POST(AO_Missile, (QEvt *)&mine2_destroyed, me); (me->x >= GAME_SPEED_X) && (me->exp_ctr < 15U) ObjectImageEvt *oie; -++me->exp_ctr; /* advance the explosion counter */ - me->x -= GAME_SPEED_X; /* move explosion by 1 step */ +++me->exp_ctr; // advance the explosion counter + me->x -= GAME_SPEED_X; // move explosion by 1 step -/* tell the Game to render the current stage of Explosion */ +// tell the Game to render the current stage of Explosion oie = Q_NEW(ObjectImageEvt, EXPLOSION_SIG); -oie->x = me->x + 1U; /* x of explosion */ -oie->y = (int8_t)((int)me->y - 4 + 2); /* y of explosion */ +oie->x = me->x + 1U; // x of explosion +oie->y = (int8_t)((int)me->y - 4 + 2); // y of explosion oie->bmp = EXPLOSION0_BMP + (me->exp_ctr >> 2); QACTIVE_POST(AO_Tunnel, (QEvt *)oie, me); @@ -1307,36 +1300,36 @@ QACTIVE_POST(AO_Tunnel, (QEvt *)oie, me); #ifndef GAME_H #define GAME_H -enum GameSignals { /* signals used in the game */ - TIME_TICK_SIG = Q_USER_SIG, /* published from tick ISR */ - PLAYER_TRIGGER_SIG, /* published by Player (ISR) to trigger the Missile */ - PLAYER_QUIT_SIG, /* published by Player (ISR) to quit the game */ - GAME_OVER_SIG, /* published by Ship when it finishes exploding */ +enum GameSignals { // signals used in the game + TIME_TICK_SIG = Q_USER_SIG, // published from tick ISR + PLAYER_TRIGGER_SIG, // published by Player (ISR) to trigger the Missile + PLAYER_QUIT_SIG, // published by Player (ISR) to quit the game + GAME_OVER_SIG, // published by Ship when it finishes exploding - /* insert other published signals here ... */ - MAX_PUB_SIG, /* the last published signal */ + // insert other published signals here ... + MAX_PUB_SIG, // the last published signal - PLAYER_SHIP_UP_SIG, /* posted by Player (ISR) to Ship to move it up */ - PLAYER_SHIP_DOWN_SIG, /* posted by Player (ISR) to Ship to let if fall */ + PLAYER_SHIP_UP_SIG, // posted by Player (ISR) to Ship to move it up + PLAYER_SHIP_DOWN_SIG, // posted by Player (ISR) to Ship to let if fall - BLINK_TIMEOUT_SIG, /* signal for Tunnel's blink timeout event */ - SCREEN_TIMEOUT_SIG, /* signal for Tunnel's screen timeout event */ + BLINK_TIMEOUT_SIG, // signal for Tunnel's blink timeout event + SCREEN_TIMEOUT_SIG, // signal for Tunnel's screen timeout event - TAKE_OFF_SIG, /* from Tunnel to Ship to grant permission to take off */ - HIT_WALL_SIG, /* from Tunnel to Ship when Ship hits the wall */ - HIT_MINE_SIG, /* from Mine to Ship or Missile when it hits the mine */ - SHIP_IMG_SIG, /* from Ship to the Tunnel to draw and check for hits */ - MISSILE_IMG_SIG, /* from Missile the Tunnel to draw and check for hits */ - MINE_IMG_SIG, /* sent by Mine to the Tunnel to draw the mine */ - MISSILE_FIRE_SIG, /* sent by Ship to the Missile to fire */ - DESTROYED_MINE_SIG, /* from Missile to Ship when Missile destroyed Mine */ - EXPLOSION_SIG, /* from any exploding object to render the explosion */ - MINE_PLANT_SIG, /* from Tunnel to the Mine to plant it */ - MINE_DISABLED_SIG, /* from Mine to Tunnel when it becomes disabled */ - MINE_RECYCLE_SIG, /* sent by Tunnel to Mine to recycle the mine */ - SCORE_SIG, /* from Ship to Tunnel to adjust game level based on score */ + TAKE_OFF_SIG, // from Tunnel to Ship to grant permission to take off + HIT_WALL_SIG, // from Tunnel to Ship when Ship hits the wall + HIT_MINE_SIG, // from Mine to Ship or Missile when it hits the mine + SHIP_IMG_SIG, // from Ship to the Tunnel to draw and check for hits + MISSILE_IMG_SIG, // from Missile the Tunnel to draw and check for hits + MINE_IMG_SIG, // sent by Mine to the Tunnel to draw the mine + MISSILE_FIRE_SIG, // sent by Ship to the Missile to fire + DESTROYED_MINE_SIG, // from Missile to Ship when Missile destroyed Mine + EXPLOSION_SIG, // from any exploding object to render the explosion + MINE_PLANT_SIG, // from Tunnel to the Mine to plant it + MINE_DISABLED_SIG, // from Mine to Tunnel when it becomes disabled + MINE_RECYCLE_SIG, // sent by Tunnel to Mine to recycle the mine + SCORE_SIG, // from Ship to Tunnel to adjust game level based on score - MAX_SIG /* the last signal (keep always last) */ + MAX_SIG // the last signal (keep always last) }; #define GAME_TUNNEL_WIDTH BSP_SCREEN_WIDTH @@ -1363,11 +1356,10 @@ enum GameBitmapIds { MAX_BMP }; -/* declare shared facilities */ -$declare${Shared} +// declare shared facilities +$declare ${Shared} -#endif /* GAME_H */ - +#endif // GAME_H @@ -1375,17 +1367,17 @@ $declare${Shared} #include "bsp.h" #include "game.h" -/* Q_DEFINE_THIS_FILE */ +// Q_DEFINE_THIS_FILE -/* local objects -----------------------------------------------------------*/ -$declare${AOs::Missile} +// local objects ----------------------------------------------------------- +$declare ${AOs::Missile} -/* Public-scope objects ----------------------------------------------------*/ -$define${Shared::AO_Missile} +// Public-scope objects ---------------------------------------------------- +$define ${Shared::AO_Missile} -/* Active object definition ------------------------------------------------*/ -$define${Shared::Missile_ctor_call} -$define${AOs::Missile} +// Active object definition ------------------------------------------------ +$define ${Shared::Missile_ctor_call} +$define ${AOs::Missile} @@ -1393,20 +1385,20 @@ $define${AOs::Missile} #include "bsp.h" #include "game.h" -/* Q_DEFINE_THIS_FILE */ +// Q_DEFINE_THIS_FILE #define SHIP_WIDTH 5 #define SHIP_HEIGHT 3 -/* encapsulated delcaration of the Ship active object ----------------------*/ -$declare${AOs::Ship} +// encapsulated delcaration of the Ship active object ---------------------- +$declare ${AOs::Ship} -/* Public-scope objects ----------------------------------------------------*/ -$define${Shared::AO_Ship} +// Public-scope objects ---------------------------------------------------- +$define ${Shared::AO_Ship} -/* Active object definition ------------------------------------------------*/ -$define${Shared::Ship_ctor_call} -$define${AOs::Ship} +// Active object definition ------------------------------------------------ +$define ${Shared::Ship_ctor_call} +$define ${AOs::Ship} @@ -1416,15 +1408,15 @@ $define${AOs::Ship} Q_DEFINE_THIS_FILE -/* local objects -----------------------------------------------------------*/ -$declare${AOs::Tunnel} +// local objects ----------------------------------------------------------- +$declare ${AOs::Tunnel} -/* Public-scope objects ----------------------------------------------------*/ -$define${Shared::AO_Tunnel} +// Public-scope objects ---------------------------------------------------- +$define ${Shared::AO_Tunnel} -/* Active object definition ================================================*/ -$define${Shared::Tunnel_ctor_call} -$define${AOs::Tunnel} +// Active object definition ================================================ +$define ${Shared::Tunnel_ctor_call} +$define ${AOs::Tunnel} @@ -1434,15 +1426,15 @@ $define${AOs::Tunnel} Q_DEFINE_THIS_FILE -/* encapsulated delcaration of the Mine1 HSM -------------------------------*/ -$declare(AOs::Mine1) +// encapsulated delcaration of the Mine1 HSM ------------------------------- +$declare ${AOs::Mine1} -/* helper macro to provide the ID of this mine */ +// helper macro to provide the ID of this mine #define MINE_ID(me_) ((uint8_t)((me_) - &Mine1_inst[0])) -/* Mine1 class definition --------------------------------------------------*/ -$define(Shared::Mine1_ctor_call) -$define(AOs::Mine1) +// Mine1 class definition -------------------------------------------------- +$define ${Shared::Mine1_ctor_call} +$define ${AOs::Mine1} @@ -1452,15 +1444,15 @@ $define(AOs::Mine1) Q_DEFINE_THIS_FILE -/* encapsulated delcaration of the Mine2 HSM -------------------------------*/ -$declare(AOs::Mine2) +// encapsulated delcaration of the Mine2 HSM ------------------------------- +$declare ${AOs::Mine2} -/* helper macro to provide the ID of this mine */ +// helper macro to provide the ID of this mine #define MINE_ID(me_) ((uint8_t)((me_) - &Mine2_inst[0])) -/* Mine2 class definition --------------------------------------------------*/ -$define(Shared::Mine2_ctor_call) -$define(AOs::Mine2) +// Mine2 class definition -------------------------------------------------- +$define ${Shared::Mine2_ctor_call} +$define ${AOs::Mine2} diff --git a/examples/arm-cm/game_efm32-slstk3401a/main.c b/examples/arm-cm/game_efm32-slstk3401a/main.c index 7b108499..4585ba88 100644 --- a/examples/arm-cm/game_efm32-slstk3401a/main.c +++ b/examples/arm-cm/game_efm32-slstk3401a/main.c @@ -1,101 +1,108 @@ -/***************************************************************************** -* Product: "Fly 'n' Shoot" game example -* Last updated for version 6.9.2 -* Last updated on 2021-02-12 -* -* Q u a n t u m L e a P s -* ------------------------ -* Modern Embedded Software -* -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* -* -*****************************************************************************/ +//============================================================================ +// Product: "Fly 'n' Shoot" game example +// Last updated for version 7.3.0 +// Last updated on 2023-09-06 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// This program is open source software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Alternatively, this program may be distributed and modified under the +// terms of Quantum Leaps commercial licenses, which expressly supersede +// the GNU General Public License and are specifically designed for +// licensees interested in retaining the proprietary status of their code. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Contact information: +// +// +//============================================================================ #include "qpc.h" #include "bsp.h" #include "game.h" -Q_DEFINE_THIS_FILE +//Q_DEFINE_THIS_FILE -static QTicker l_ticker0; /* ticker active object for tick rate 0 */ -QActive *the_Ticker0 = &l_ticker0.super; +static QTicker l_ticker0; // ticker active object for tick rate 0 +QActive * const the_Ticker0 = &l_ticker0.super; -/*..........................................................................*/ +//............................................................................ int main() { - static QEvt const * missileQueueSto[2]; - static QEvt const * shipQueueSto[3]; - static QEvt const * tunnelQueueSto[GAME_MINES_MAX + 5]; + QF_init(); // initialize the framework and the underlying RT kernel + BSP_init(); // initialize the Board Support Package - static QF_MPOOL_EL(QEvt) smlPoolSto[10]; - static QF_MPOOL_EL(ObjectImageEvt) medPoolSto[2*GAME_MINES_MAX + 10]; + // init publish-subscribe... + static QSubscrList subscrSto[MAX_PUB_SIG]; + QActive_psInit(subscrSto, Q_DIM(subscrSto)); - static QSubscrList subscrSto[MAX_PUB_SIG]; + // initialize the event pools... - QF_init(); /* initialize the framework and the underlying RT kernel */ - BSP_init(); /* initialize the Board Support Package */ + //static QF_MPOOL_EL(QEvt) smlPoolSto[10]; + //QF_poolInit(smlPoolSto, sizeof(smlPoolSto), sizeof(smlPoolSto[0])); + // NOTE: + // After new rounding up, the "small" memory pool has the same block-size + // as the next "medium" pool. If such "small" pool is initialized, + // the next "medium" pool will casuse an assertion (the same block-size + // pool already exists). - /* init publish-subscribe... */ - QF_psInit(subscrSto, Q_DIM(subscrSto)); - - /* initialize the event pools... */ - QF_poolInit(smlPoolSto, sizeof(smlPoolSto), sizeof(smlPoolSto[0])); + static QF_MPOOL_EL(ObjectImageEvt) medPoolSto[2*GAME_MINES_MAX + 20]; QF_poolInit(medPoolSto, sizeof(medPoolSto), sizeof(medPoolSto[0])); - /* object dictionaries for AOs... */ + // object dictionaries for AOs... QS_OBJ_DICTIONARY(AO_Missile); QS_OBJ_DICTIONARY(AO_Ship); QS_OBJ_DICTIONARY(AO_Tunnel); - /* signal dictionaries for globally published events... */ + // signal dictionaries for globally published events... QS_SIG_DICTIONARY(TIME_TICK_SIG, (void *)0); QS_SIG_DICTIONARY(PLAYER_TRIGGER_SIG, (void *)0); QS_SIG_DICTIONARY(PLAYER_QUIT_SIG, (void *)0); QS_SIG_DICTIONARY(GAME_OVER_SIG, (void *)0); - /* start the active objects... */ - QTicker_ctor(&l_ticker0, 0U); /* active object for tick rate 0 */ + // start the active objects... + QTicker_ctor(&l_ticker0, 0U); // active object for tick rate 0 QACTIVE_START(the_Ticker0, - 1U, /* QP priority */ - 0, 0, 0, 0, 0); /* no queue, no stack , no init. event */ + 1U, // QP priority + 0, 0, 0, 0, 0); // no queue, no stack , no init. event + + static QEvt const *tunnelQueueSto[GAME_MINES_MAX + 5]; Tunnel_ctor_call(); QACTIVE_START(AO_Tunnel, - 2U, /* QP priority */ - tunnelQueueSto, Q_DIM(tunnelQueueSto), /* evt queue */ - (void *)0, 0U, /* no per-thread stack */ - (QEvt *)0); /* no initialization event */ + 2U, // QP priority + tunnelQueueSto, Q_DIM(tunnelQueueSto), // evt queue + (void *)0, 0U, // no per-thread stack + (QEvt *)0); // no initialization event + + static QEvt const *shipQueueSto[3]; Ship_ctor_call(); QACTIVE_START(AO_Ship, - 3U, /* QP priority */ - shipQueueSto, Q_DIM(shipQueueSto), /* evt queue */ - (void *)0, 0U, /* no per-thread stack */ - (QEvt *)0); /* no initialization event */ + 3U, // QP priority + shipQueueSto, Q_DIM(shipQueueSto), // evt queue + (void *)0, 0U, // no per-thread stack + (QEvt *)0); // no initialization event + + static QEvt const *missileQueueSto[2]; Missile_ctor_call(); QACTIVE_START(AO_Missile, - 4U, /* QP priority */ - missileQueueSto, Q_DIM(missileQueueSto), /* evt queue */ - (void *)0, 0U, /* no per-thread stack */ - (QEvt *)0); /* no initialization event */ + 4U, // QP priority + missileQueueSto, Q_DIM(missileQueueSto), // evt queue + (void *)0, 0U, // no per-thread stack + (QEvt *)0); // no initialization event - return QF_run(); /* run the QF application */ + return QF_run(); // run the QF application } diff --git a/examples/arm-cm/game_efm32-slstk3401a/mine1.c b/examples/arm-cm/game_efm32-slstk3401a/mine1.c index 7473c732..c5d0bed7 100644 --- a/examples/arm-cm/game_efm32-slstk3401a/mine1.c +++ b/examples/arm-cm/game_efm32-slstk3401a/mine1.c @@ -1,101 +1,101 @@ -/*$file${.::mine1.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* -* Model: game.qm -* File: ${.::mine1.c} -* -* This code has been generated by QM 5.2.4 . -* DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. -* -* SPDX-License-Identifier: GPL-3.0-or-later -* -* This generated code is open source software: you can redistribute it under -* the terms of the GNU General Public License as published by the Free -* Software Foundation. -* -* This code is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -* more details. -* -* NOTE: -* Alternatively, this generated code may be distributed under the terms -* of Quantum Leaps commercial licenses, which expressly supersede the GNU -* General Public License and are specifically designed for licensees -* interested in retaining the proprietary status of their code. -* -* Contact information: -* -* -*/ -/*$endhead${.::mine1.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$file${.::mine1.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// +// Model: game.qm +// File: ${.::mine1.c} +// +// This code has been generated by QM 5.3.0 . +// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. +// +// SPDX-License-Identifier: GPL-3.0-or-later +// +// This generated code is open source software: you can redistribute it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation. +// +// This code is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// NOTE: +// Alternatively, this generated code may be distributed under the terms +// of Quantum Leaps commercial licenses, which expressly supersede the GNU +// General Public License and are specifically designed for licensees +// interested in retaining the proprietary status of their code. +// +// Contact information: +// +// +// +//$endhead${.::mine1.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ #include "qpc.h" #include "bsp.h" #include "game.h" Q_DEFINE_THIS_FILE -/* encapsulated delcaration of the Mine1 HSM -------------------------------*/ -/*$declare${AOs::Mine1} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +// encapsulated delcaration of the Mine1 HSM ------------------------------- +//$declare${AOs::Mine1} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/*${AOs::Mine1} ............................................................*/ +//${AOs::Mine1} .............................................................. typedef struct Mine1 { -/* protected: */ +// protected: QHsm super; -/* private: */ +// private: uint8_t x; uint8_t y; -/* public: */ +// public: uint8_t exp_ctr; } Mine1; -/* public: */ +// public: static void Mine1_ctor(Mine1 * const me); extern Mine1 Mine1_inst[GAME_MINES_MAX]; -/* protected: */ +// protected: static QState Mine1_initial(Mine1 * const me, void const * const par); static QState Mine1_unused(Mine1 * const me, QEvt const * const e); static QState Mine1_used(Mine1 * const me, QEvt const * const e); static QState Mine1_planted(Mine1 * const me, QEvt const * const e); static QState Mine1_exploding(Mine1 * const me, QEvt const * const e); -/*$enddecl${AOs::Mine1} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$enddecl${AOs::Mine1} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -/* helper macro to provide the ID of this mine */ +// helper macro to provide the ID of this mine #define MINE_ID(me_) ((uint8_t)((me_) - &Mine1_inst[0])) -/* Mine1 class definition --------------------------------------------------*/ -/*$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* Check for the minimum required QP version */ -#if (QP_VERSION < 700U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) -#error qpc version 7.0.0 or higher required +// Mine1 class definition -------------------------------------------------- +//$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// Check for the minimum required QP version +#if (QP_VERSION < 730U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) +#error qpc version 7.3.0 or higher required #endif -/*$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -/*$define${Shared::Mine1_ctor_call} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//$define${Shared::Mine1_ctor_call} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/*${Shared::Mine1_ctor_call} ...............................................*/ +//${Shared::Mine1_ctor_call} ................................................. QHsm * Mine1_ctor_call(uint8_t id) { Q_REQUIRE(id < GAME_MINES_MAX); Mine1_ctor(&Mine1_inst[id]); return &Mine1_inst[id].super; } -/*$enddef${Shared::Mine1_ctor_call} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*$define${AOs::Mine1} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//$enddef${Shared::Mine1_ctor_call} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +//$define${AOs::Mine1} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/*${AOs::Mine1} ............................................................*/ +//${AOs::Mine1} .............................................................. Mine1 Mine1_inst[GAME_MINES_MAX]; -/*${AOs::Mine1::ctor} ......................................................*/ +//${AOs::Mine1::ctor} ........................................................ static void Mine1_ctor(Mine1 * const me) { - /* superclass' ctor */ + // superclass' ctor QHsm_ctor(&me->super, Q_STATE_CAST(&Mine1_initial)); } -/*${AOs::Mine1::SM} ........................................................*/ +//${AOs::Mine1::SM} .......................................................... static QState Mine1_initial(Mine1 * const me, void const * const par) { - /*${AOs::Mine1::SM::initial} */ + //${AOs::Mine1::SM::initial} static uint8_t dict_sent; if (!dict_sent) { @@ -105,7 +105,7 @@ static QState Mine1_initial(Mine1 * const me, void const * const par) { QS_OBJ_DICTIONARY(&Mine1_inst[3]); QS_OBJ_DICTIONARY(&Mine1_inst[4]); - QS_FUN_DICTIONARY(&Mine1_initial);/*fun. dictionaries for Mine1 HSM */ + QS_FUN_DICTIONARY(&Mine1_initial);//fun. dictionaries for Mine1 HSM QS_FUN_DICTIONARY(&Mine1_unused); QS_FUN_DICTIONARY(&Mine1_used); QS_FUN_DICTIONARY(&Mine1_planted); @@ -113,22 +113,22 @@ static QState Mine1_initial(Mine1 * const me, void const * const par) { dict_sent = 1U; } - /* local signals */ + // local signals QS_SIG_DICTIONARY(MINE_PLANT_SIG, me); QS_SIG_DICTIONARY(MINE_DISABLED_SIG, me); QS_SIG_DICTIONARY(MINE_RECYCLE_SIG, me); QS_SIG_DICTIONARY(SHIP_IMG_SIG, me); QS_SIG_DICTIONARY(MISSILE_IMG_SIG, me); - (void)par; /* unused parameter */ + (void)par; // unused parameter return Q_TRAN(&Mine1_unused); } -/*${AOs::Mine1::SM::unused} ................................................*/ +//${AOs::Mine1::SM::unused} .................................................. static QState Mine1_unused(Mine1 * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${AOs::Mine1::SM::unused::MINE_PLANT} */ + //${AOs::Mine1::SM::unused::MINE_PLANT} case MINE_PLANT_SIG: { me->x = Q_EVT_CAST(ObjectPosEvt)->x; me->y = Q_EVT_CAST(ObjectPosEvt)->y; @@ -143,20 +143,20 @@ static QState Mine1_unused(Mine1 * const me, QEvt const * const e) { return status_; } -/*${AOs::Mine1::SM::used} ..................................................*/ +//${AOs::Mine1::SM::used} .................................................... static QState Mine1_used(Mine1 * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${AOs::Mine1::SM::used} */ + //${AOs::Mine1::SM::used} case Q_EXIT_SIG: { - /* tell the Tunnel that this mine is becoming disabled */ + // tell the Tunnel that this mine is becoming disabled MineEvt *mev = Q_NEW(MineEvt, MINE_DISABLED_SIG); mev->id = MINE_ID(me); QACTIVE_POST(AO_Tunnel, (QEvt *)mev, me); status_ = Q_HANDLED(); break; } - /*${AOs::Mine1::SM::used::MINE_RECYCLE} */ + //${AOs::Mine1::SM::used::MINE_RECYCLE} case MINE_RECYCLE_SIG: { status_ = Q_TRAN(&Mine1_unused); break; @@ -169,17 +169,17 @@ static QState Mine1_used(Mine1 * const me, QEvt const * const e) { return status_; } -/*${AOs::Mine1::SM::used::planted} .........................................*/ +//${AOs::Mine1::SM::used::planted} ........................................... static QState Mine1_planted(Mine1 * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${AOs::Mine1::SM::used::planted::TIME_TICK} */ + //${AOs::Mine1::SM::used::planted::TIME_TICK} case TIME_TICK_SIG: { - /*${AOs::Mine1::SM::used::planted::TIME_TICK::[me->x>=GAME_SPEED_X]} */ + //${AOs::Mine1::SM::used::planted::TIME_TICK::[me->x>=GAME_SPEED_X]} if (me->x >= GAME_SPEED_X) { ObjectImageEvt *oie; - me->x -= GAME_SPEED_X; /* move the mine 1 step */ - /* tell the Tunnel to draw the Mine */ + me->x -= GAME_SPEED_X; // move the mine 1 step + // tell the Tunnel to draw the Mine oie = Q_NEW(ObjectImageEvt, MINE_IMG_SIG); oie->x = me->x; oie->y = me->y; @@ -187,26 +187,25 @@ static QState Mine1_planted(Mine1 * const me, QEvt const * const e) { QACTIVE_POST(AO_Tunnel, (QEvt *)oie, me); status_ = Q_HANDLED(); } - /*${AOs::Mine1::SM::used::planted::TIME_TICK::[else]} */ + //${AOs::Mine1::SM::used::planted::TIME_TICK::[else]} else { status_ = Q_TRAN(&Mine1_unused); } break; } - /*${AOs::Mine1::SM::used::planted::SHIP_IMG} */ + //${AOs::Mine1::SM::used::planted::SHIP_IMG} case SHIP_IMG_SIG: { uint8_t x = Q_EVT_CAST(ObjectImageEvt)->x; uint8_t y = Q_EVT_CAST(ObjectImageEvt)->y; uint8_t bmp = Q_EVT_CAST(ObjectImageEvt)->bmp; - /*${AOs::Mine1::SM::used::planted::SHIP_IMG::[collisionwithMINE1_BMP?]} */ + //${AOs::Mine1::SM::used::planted::SHIP_IMG::[collisionwithMINE1_BMP?]} if (BSP_doBitmapsOverlap(MINE1_BMP, me->x, me->y, bmp, x, y)) { static MineEvt const mine1_hit = { - { HIT_MINE_SIG, 0U, 0U }, /* the QEvt base instance */ - 1U /* type of the mine (1 for Mine type-1) */ + QEVT_INITIALIZER(HIT_MINE_SIG), // the QEvt base instance + 1U // type of the mine (1 for Mine type-1) }; QACTIVE_POST(AO_Ship, (QEvt *)&mine1_hit, me); - /* go straight to 'disabled' and let the Ship do - * the exploding */ + // go straight to 'disabled' and let the Ship do the exploding status_ = Q_TRAN(&Mine1_unused); } else { @@ -214,16 +213,16 @@ static QState Mine1_planted(Mine1 * const me, QEvt const * const e) { } break; } - /*${AOs::Mine1::SM::used::planted::MISSILE_IMG} */ + //${AOs::Mine1::SM::used::planted::MISSILE_IMG} case MISSILE_IMG_SIG: { uint8_t x = Q_EVT_CAST(ObjectImageEvt)->x; uint8_t y = Q_EVT_CAST(ObjectImageEvt)->y; uint8_t bmp = Q_EVT_CAST(ObjectImageEvt)->bmp; - /*${AOs::Mine1::SM::used::planted::MISSILE_IMG::[collisionwithMINE1_BMP?]} */ + //${AOs::Mine1::SM::used::planted::MISSILE_IMG::[collisionwithMINE1_BMP?]} if (BSP_doBitmapsOverlap(MINE1_BMP, me->x, me->y, bmp, x, y)) { static ScoreEvt const mine1_destroyed = { - { DESTROYED_MINE_SIG, 0U, 0U }, /* the QEvt base instance */ - 25U /* score for destroying Mine type-1 */ + QEVT_INITIALIZER(DESTROYED_MINE_SIG), // the QEvt base instance + 25U // score for destroying Mine type-1 }; QACTIVE_POST(AO_Missile, (QEvt *)&mine1_destroyed, me); status_ = Q_TRAN(&Mine1_exploding); @@ -241,33 +240,33 @@ static QState Mine1_planted(Mine1 * const me, QEvt const * const e) { return status_; } -/*${AOs::Mine1::SM::used::exploding} .......................................*/ +//${AOs::Mine1::SM::used::exploding} ......................................... static QState Mine1_exploding(Mine1 * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${AOs::Mine1::SM::used::exploding} */ + //${AOs::Mine1::SM::used::exploding} case Q_ENTRY_SIG: { me->exp_ctr = 0U; status_ = Q_HANDLED(); break; } - /*${AOs::Mine1::SM::used::exploding::TIME_TICK} */ + //${AOs::Mine1::SM::used::exploding::TIME_TICK} case TIME_TICK_SIG: { - /*${AOs::Mine1::SM::used::exploding::TIME_TICK::[stillonscreen?]} */ + //${AOs::Mine1::SM::used::exploding::TIME_TICK::[stillonscreen?]} if ((me->x >= GAME_SPEED_X) && (me->exp_ctr < 15)) { ObjectImageEvt *oie; - ++me->exp_ctr; /* advance the explosion counter */ - me->x -= GAME_SPEED_X; /* move explosion by 1 step */ + ++me->exp_ctr; // advance the explosion counter + me->x -= GAME_SPEED_X; // move explosion by 1 step - /* tell the Game to render the current stage of Explosion */ + // tell the Game to render the current stage of Explosion oie = Q_NEW(ObjectImageEvt, EXPLOSION_SIG); - oie->x = me->x + 1U; /* x of explosion */ - oie->y = (int8_t)((int)me->y - 4 + 2); /* y of explosion */ + oie->x = me->x + 1U; // x of explosion + oie->y = (int8_t)((int)me->y - 4 + 2); // y of explosion oie->bmp = EXPLOSION0_BMP + (me->exp_ctr >> 2); QACTIVE_POST(AO_Tunnel, (QEvt *)oie, me); status_ = Q_HANDLED(); } - /*${AOs::Mine1::SM::used::exploding::TIME_TICK::[else]} */ + //${AOs::Mine1::SM::used::exploding::TIME_TICK::[else]} else { status_ = Q_TRAN(&Mine1_unused); } @@ -280,4 +279,4 @@ static QState Mine1_exploding(Mine1 * const me, QEvt const * const e) { } return status_; } -/*$enddef${AOs::Mine1} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$enddef${AOs::Mine1} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/examples/arm-cm/game_efm32-slstk3401a/mine2.c b/examples/arm-cm/game_efm32-slstk3401a/mine2.c index a6eddf11..27f7d629 100644 --- a/examples/arm-cm/game_efm32-slstk3401a/mine2.c +++ b/examples/arm-cm/game_efm32-slstk3401a/mine2.c @@ -1,112 +1,112 @@ -/*$file${.::mine2.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* -* Model: game.qm -* File: ${.::mine2.c} -* -* This code has been generated by QM 5.2.4 . -* DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. -* -* SPDX-License-Identifier: GPL-3.0-or-later -* -* This generated code is open source software: you can redistribute it under -* the terms of the GNU General Public License as published by the Free -* Software Foundation. -* -* This code is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -* more details. -* -* NOTE: -* Alternatively, this generated code may be distributed under the terms -* of Quantum Leaps commercial licenses, which expressly supersede the GNU -* General Public License and are specifically designed for licensees -* interested in retaining the proprietary status of their code. -* -* Contact information: -* -* -*/ -/*$endhead${.::mine2.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$file${.::mine2.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// +// Model: game.qm +// File: ${.::mine2.c} +// +// This code has been generated by QM 5.3.0 . +// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. +// +// SPDX-License-Identifier: GPL-3.0-or-later +// +// This generated code is open source software: you can redistribute it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation. +// +// This code is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// NOTE: +// Alternatively, this generated code may be distributed under the terms +// of Quantum Leaps commercial licenses, which expressly supersede the GNU +// General Public License and are specifically designed for licensees +// interested in retaining the proprietary status of their code. +// +// Contact information: +// +// +// +//$endhead${.::mine2.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ #include "qpc.h" #include "bsp.h" #include "game.h" Q_DEFINE_THIS_FILE -/* encapsulated delcaration of the Mine2 HSM -------------------------------*/ -/*$declare${AOs::Mine2} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +// encapsulated delcaration of the Mine2 HSM ------------------------------- +//$declare${AOs::Mine2} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/*${AOs::Mine2} ............................................................*/ +//${AOs::Mine2} .............................................................. typedef struct Mine2 { -/* protected: */ +// protected: QHsm super; -/* private: */ +// private: uint8_t x; uint8_t y; -/* public: */ +// public: uint8_t exp_ctr; } Mine2; -/* public: */ +// public: static void Mine2_ctor(Mine2 * const me); extern Mine2 Mine2_inst[GAME_MINES_MAX]; -/* protected: */ +// protected: static QState Mine2_initial(Mine2 * const me, void const * const par); static QState Mine2_unused(Mine2 * const me, QEvt const * const e); static QState Mine2_used(Mine2 * const me, QEvt const * const e); static QState Mine2_planted(Mine2 * const me, QEvt const * const e); static QState Mine2_exploding(Mine2 * const me, QEvt const * const e); -/*$enddecl${AOs::Mine2} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$enddecl${AOs::Mine2} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -/* helper macro to provide the ID of this mine */ +// helper macro to provide the ID of this mine #define MINE_ID(me_) ((uint8_t)((me_) - &Mine2_inst[0])) -/* Mine2 class definition --------------------------------------------------*/ -/*$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* Check for the minimum required QP version */ -#if (QP_VERSION < 700U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) -#error qpc version 7.0.0 or higher required +// Mine2 class definition -------------------------------------------------- +//$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// Check for the minimum required QP version +#if (QP_VERSION < 730U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) +#error qpc version 7.3.0 or higher required #endif -/*$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -/*$define${Shared::Mine2_ctor_call} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//$define${Shared::Mine2_ctor_call} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/*${Shared::Mine2_ctor_call} ...............................................*/ +//${Shared::Mine2_ctor_call} ................................................. QHsm * Mine2_ctor_call(uint8_t id) { Q_REQUIRE(id < GAME_MINES_MAX); Mine2_ctor(&Mine2_inst[id]); return &Mine2_inst[id].super; } -/*$enddef${Shared::Mine2_ctor_call} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*$define${AOs::Mine2} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//$enddef${Shared::Mine2_ctor_call} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +//$define${AOs::Mine2} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/*${AOs::Mine2} ............................................................*/ +//${AOs::Mine2} .............................................................. Mine2 Mine2_inst[GAME_MINES_MAX]; -/*${AOs::Mine2::ctor} ......................................................*/ +//${AOs::Mine2::ctor} ........................................................ static void Mine2_ctor(Mine2 * const me) { - /* superclass' ctor */ + // superclass' ctor QHsm_ctor(&me->super, Q_STATE_CAST(&Mine2_initial)); } -/*${AOs::Mine2::SM} ........................................................*/ +//${AOs::Mine2::SM} .......................................................... static QState Mine2_initial(Mine2 * const me, void const * const par) { - /*${AOs::Mine2::SM::initial} */ + //${AOs::Mine2::SM::initial} static uint8_t dict_sent; if (!dict_sent) { - /* object dictionaries for Mine2 pool... */ + // object dictionaries for Mine2 pool... QS_OBJ_DICTIONARY(&Mine2_inst[0]); QS_OBJ_DICTIONARY(&Mine2_inst[1]); QS_OBJ_DICTIONARY(&Mine2_inst[2]); QS_OBJ_DICTIONARY(&Mine2_inst[3]); QS_OBJ_DICTIONARY(&Mine2_inst[4]); - /*function dictionaries for Mine2 HSM... */ + //function dictionaries for Mine2 HSM... QS_FUN_DICTIONARY(&Mine2_initial); QS_FUN_DICTIONARY(&Mine2_unused); QS_FUN_DICTIONARY(&Mine2_used); @@ -115,22 +115,22 @@ static QState Mine2_initial(Mine2 * const me, void const * const par) { dict_sent = 1U; } - /* local signals... */ + // local signals... QS_SIG_DICTIONARY(MINE_PLANT_SIG, me); QS_SIG_DICTIONARY(MINE_DISABLED_SIG, me); QS_SIG_DICTIONARY(MINE_RECYCLE_SIG, me); QS_SIG_DICTIONARY(SHIP_IMG_SIG, me); QS_SIG_DICTIONARY(MISSILE_IMG_SIG, me); - (void)par; /* unused parameter */ + (void)par; // unused parameter return Q_TRAN(&Mine2_unused); } -/*${AOs::Mine2::SM::unused} ................................................*/ +//${AOs::Mine2::SM::unused} .................................................. static QState Mine2_unused(Mine2 * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${AOs::Mine2::SM::unused::MINE_PLANT} */ + //${AOs::Mine2::SM::unused::MINE_PLANT} case MINE_PLANT_SIG: { me->x = Q_EVT_CAST(ObjectPosEvt)->x; me->y = Q_EVT_CAST(ObjectPosEvt)->y; @@ -145,20 +145,20 @@ static QState Mine2_unused(Mine2 * const me, QEvt const * const e) { return status_; } -/*${AOs::Mine2::SM::used} ..................................................*/ +//${AOs::Mine2::SM::used} .................................................... static QState Mine2_used(Mine2 * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${AOs::Mine2::SM::used} */ + //${AOs::Mine2::SM::used} case Q_EXIT_SIG: { - /* tell the Tunnel that this mine is becoming disabled */ + // tell the Tunnel that this mine is becoming disabled MineEvt *mev = Q_NEW(MineEvt, MINE_DISABLED_SIG); mev->id = MINE_ID(me); QACTIVE_POST(AO_Tunnel, (QEvt *)mev, me); status_ = Q_HANDLED(); break; } - /*${AOs::Mine2::SM::used::MINE_RECYCLE} */ + //${AOs::Mine2::SM::used::MINE_RECYCLE} case MINE_RECYCLE_SIG: { status_ = Q_TRAN(&Mine2_unused); break; @@ -171,17 +171,17 @@ static QState Mine2_used(Mine2 * const me, QEvt const * const e) { return status_; } -/*${AOs::Mine2::SM::used::planted} .........................................*/ +//${AOs::Mine2::SM::used::planted} ........................................... static QState Mine2_planted(Mine2 * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${AOs::Mine2::SM::used::planted::TIME_TICK} */ + //${AOs::Mine2::SM::used::planted::TIME_TICK} case TIME_TICK_SIG: { - /*${AOs::Mine2::SM::used::planted::TIME_TICK::[me->x>=GAME_SPEED_X]} */ + //${AOs::Mine2::SM::used::planted::TIME_TICK::[me->x>=GAME_SPEED_X]} if (me->x >= GAME_SPEED_X) { ObjectImageEvt *oie; - me->x -= GAME_SPEED_X; /* move the mine 1 step */ - /* tell the Tunnel to draw the Mine */ + me->x -= GAME_SPEED_X; // move the mine 1 step + // tell the Tunnel to draw the Mine oie = Q_NEW(ObjectImageEvt, MINE_IMG_SIG); oie->x = me->x; oie->y = me->y; @@ -189,26 +189,25 @@ static QState Mine2_planted(Mine2 * const me, QEvt const * const e) { QACTIVE_POST(AO_Tunnel, (QEvt *)oie, me); status_ = Q_HANDLED(); } - /*${AOs::Mine2::SM::used::planted::TIME_TICK::[else]} */ + //${AOs::Mine2::SM::used::planted::TIME_TICK::[else]} else { status_ = Q_TRAN(&Mine2_unused); } break; } - /*${AOs::Mine2::SM::used::planted::SHIP_IMG} */ + //${AOs::Mine2::SM::used::planted::SHIP_IMG} case SHIP_IMG_SIG: { uint8_t x = Q_EVT_CAST(ObjectImageEvt)->x; uint8_t y = Q_EVT_CAST(ObjectImageEvt)->y; uint8_t bmp = Q_EVT_CAST(ObjectImageEvt)->bmp; - /*${AOs::Mine2::SM::used::planted::SHIP_IMG::[collisionwithMINE2_BMP?]} */ + //${AOs::Mine2::SM::used::planted::SHIP_IMG::[collisionwithMINE2_BMP?]} if (BSP_doBitmapsOverlap(MINE2_BMP, me->x, me->y, bmp, x, y)) { static MineEvt const mine1_hit = { - { HIT_MINE_SIG, 0U, 0U }, /* the QEvt base instance */ - 2U /* type of the mine (2 for Mine type-2) */ + QEVT_INITIALIZER(HIT_MINE_SIG), // the QEvt base instance + 2U // type of the mine (2 for Mine type-2) }; - QACTIVE_POST(AO_Ship, (QEvt *)&mine1_hit, me); - /* go straight to 'disabled' and let the Ship do - * the exploding */ + QACTIVE_POST(AO_Ship, (QEvt *)&mine1_hit, me); + // go straight to 'disabled' and let the Ship do the exploding status_ = Q_TRAN(&Mine2_unused); } else { @@ -216,22 +215,21 @@ static QState Mine2_planted(Mine2 * const me, QEvt const * const e) { } break; } - /*${AOs::Mine2::SM::used::planted::MISSILE_IMG} */ + //${AOs::Mine2::SM::used::planted::MISSILE_IMG} case MISSILE_IMG_SIG: { uint8_t x = Q_EVT_CAST(ObjectImageEvt)->x; uint8_t y = Q_EVT_CAST(ObjectImageEvt)->y; uint8_t bmp = Q_EVT_CAST(ObjectImageEvt)->bmp; - /*${AOs::Mine2::SM::used::planted::MISSILE_IMG::[collisionwithMINE2_MISSILE_BMP?~} */ + //${AOs::Mine2::SM::used::planted::MISSILE_IMG::[collisionwithMINE2_MISSILE_BMP?~} if (BSP_doBitmapsOverlap(MINE2_MISSILE_BMP, me->x, me->y, bmp, x, y)) { - /* NOTE: Mine type-2 is nastier than Mine type-1. - * The type-2 mine can hit the Ship with any of its - * "tentacles". However, it can be destroyed by the - * Missile only by hitting its center, defined as - * a smaller bitmap MINE2_MISSILE_BMP. - */ + // NOTE: Mine type-2 is nastier than Mine type-1. + // The type-2 mine can hit the Ship with any of its + // "tentacles". However, it can be destroyed by the + // Missile only by hitting its center, defined as + // a smaller bitmap MINE2_MISSILE_BMP. static ScoreEvt const mine2_destroyed = { - { DESTROYED_MINE_SIG, 0U, 0U }, /* the QEvt base instance */ - 45U /* score for destroying Mine type-2 */ + QEVT_INITIALIZER(DESTROYED_MINE_SIG), // the QEvt base instance + 45U // score for destroying Mine type-2 }; QACTIVE_POST(AO_Missile, (QEvt *)&mine2_destroyed, me); status_ = Q_TRAN(&Mine2_exploding); @@ -249,33 +247,33 @@ static QState Mine2_planted(Mine2 * const me, QEvt const * const e) { return status_; } -/*${AOs::Mine2::SM::used::exploding} .......................................*/ +//${AOs::Mine2::SM::used::exploding} ......................................... static QState Mine2_exploding(Mine2 * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${AOs::Mine2::SM::used::exploding} */ + //${AOs::Mine2::SM::used::exploding} case Q_ENTRY_SIG: { me->exp_ctr = 0U; status_ = Q_HANDLED(); break; } - /*${AOs::Mine2::SM::used::exploding::TIME_TICK} */ + //${AOs::Mine2::SM::used::exploding::TIME_TICK} case TIME_TICK_SIG: { - /*${AOs::Mine2::SM::used::exploding::TIME_TICK::[stillonscreen?]} */ + //${AOs::Mine2::SM::used::exploding::TIME_TICK::[stillonscreen?]} if ((me->x >= GAME_SPEED_X) && (me->exp_ctr < 15U)) { ObjectImageEvt *oie; - ++me->exp_ctr; /* advance the explosion counter */ - me->x -= GAME_SPEED_X; /* move explosion by 1 step */ + ++me->exp_ctr; // advance the explosion counter + me->x -= GAME_SPEED_X; // move explosion by 1 step - /* tell the Game to render the current stage of Explosion */ + // tell the Game to render the current stage of Explosion oie = Q_NEW(ObjectImageEvt, EXPLOSION_SIG); - oie->x = me->x + 1U; /* x of explosion */ - oie->y = (int8_t)((int)me->y - 4 + 2); /* y of explosion */ + oie->x = me->x + 1U; // x of explosion + oie->y = (int8_t)((int)me->y - 4 + 2); // y of explosion oie->bmp = EXPLOSION0_BMP + (me->exp_ctr >> 2); QACTIVE_POST(AO_Tunnel, (QEvt *)oie, me); status_ = Q_HANDLED(); } - /*${AOs::Mine2::SM::used::exploding::TIME_TICK::[else]} */ + //${AOs::Mine2::SM::used::exploding::TIME_TICK::[else]} else { status_ = Q_TRAN(&Mine2_unused); } @@ -288,4 +286,4 @@ static QState Mine2_exploding(Mine2 * const me, QEvt const * const e) { } return status_; } -/*$enddef${AOs::Mine2} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$enddef${AOs::Mine2} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/examples/arm-cm/game_efm32-slstk3401a/missile.c b/examples/arm-cm/game_efm32-slstk3401a/missile.c index 4165158a..5b39b99c 100644 --- a/examples/arm-cm/game_efm32-slstk3401a/missile.c +++ b/examples/arm-cm/game_efm32-slstk3401a/missile.c @@ -1,105 +1,105 @@ -/*$file${.::missile.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* -* Model: game.qm -* File: ${.::missile.c} -* -* This code has been generated by QM 5.2.4 . -* DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. -* -* SPDX-License-Identifier: GPL-3.0-or-later -* -* This generated code is open source software: you can redistribute it under -* the terms of the GNU General Public License as published by the Free -* Software Foundation. -* -* This code is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -* more details. -* -* NOTE: -* Alternatively, this generated code may be distributed under the terms -* of Quantum Leaps commercial licenses, which expressly supersede the GNU -* General Public License and are specifically designed for licensees -* interested in retaining the proprietary status of their code. -* -* Contact information: -* -* -*/ -/*$endhead${.::missile.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$file${.::missile.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// +// Model: game.qm +// File: ${.::missile.c} +// +// This code has been generated by QM 5.3.0 . +// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. +// +// SPDX-License-Identifier: GPL-3.0-or-later +// +// This generated code is open source software: you can redistribute it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation. +// +// This code is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// NOTE: +// Alternatively, this generated code may be distributed under the terms +// of Quantum Leaps commercial licenses, which expressly supersede the GNU +// General Public License and are specifically designed for licensees +// interested in retaining the proprietary status of their code. +// +// Contact information: +// +// +// +//$endhead${.::missile.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ #include "qpc.h" #include "bsp.h" #include "game.h" -/* Q_DEFINE_THIS_FILE */ +// Q_DEFINE_THIS_FILE -/* local objects -----------------------------------------------------------*/ -/*$declare${AOs::Missile} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +// local objects ----------------------------------------------------------- +//$declare${AOs::Missile} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/*${AOs::Missile} ..........................................................*/ +//${AOs::Missile} ............................................................ typedef struct Missile { -/* protected: */ +// protected: QActive super; -/* private: */ +// private: uint8_t x; uint8_t y; uint8_t exp_ctr; -/* public: */ +// public: } Missile; -/* public: */ +// public: static void Missile_ctor(Missile * const me); extern Missile Missile_inst; -/* protected: */ +// protected: static QState Missile_initial(Missile * const me, void const * const par); static QState Missile_armed(Missile * const me, QEvt const * const e); static QState Missile_flying(Missile * const me, QEvt const * const e); static QState Missile_exploding(Missile * const me, QEvt const * const e); -/*$enddecl${AOs::Missile} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$enddecl${AOs::Missile} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -/* Public-scope objects ----------------------------------------------------*/ -/*$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* Check for the minimum required QP version */ -#if (QP_VERSION < 700U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) -#error qpc version 7.0.0 or higher required +// Public-scope objects ---------------------------------------------------- +//$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// Check for the minimum required QP version +#if (QP_VERSION < 730U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) +#error qpc version 7.3.0 or higher required #endif -/*$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -/*$define${Shared::AO_Missile} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//$define${Shared::AO_Missile} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/*${Shared::AO_Missile} ....................................................*/ +//${Shared::AO_Missile} ...................................................... QActive * const AO_Missile = &Missile_inst.super; -/*$enddef${Shared::AO_Missile} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$enddef${Shared::AO_Missile} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -/* Active object definition ------------------------------------------------*/ -/*$define${Shared::Missile_ctor_call} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +// Active object definition ------------------------------------------------ +//$define${Shared::Missile_ctor_call} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/*${Shared::Missile_ctor_call} .............................................*/ +//${Shared::Missile_ctor_call} ............................................... void Missile_ctor_call(void) { Missile_ctor(&Missile_inst); } -/*$enddef${Shared::Missile_ctor_call} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*$define${AOs::Missile} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//$enddef${Shared::Missile_ctor_call} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +//$define${AOs::Missile} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/*${AOs::Missile} ..........................................................*/ +//${AOs::Missile} ............................................................ Missile Missile_inst; -/*${AOs::Missile::ctor} ....................................................*/ +//${AOs::Missile::ctor} ...................................................... static void Missile_ctor(Missile * const me) { QActive_ctor(&me->super, Q_STATE_CAST(&Missile_initial)); } -/*${AOs::Missile::SM} ......................................................*/ +//${AOs::Missile::SM} ........................................................ static QState Missile_initial(Missile * const me, void const * const par) { - /*${AOs::Missile::SM::initial} */ - (void)par; /* unused parameter */ + //${AOs::Missile::SM::initial} + (void)par; // unused parameter QActive_subscribe(&me->super, TIME_TICK_SIG); - /* local signals */ + // local signals QS_SIG_DICTIONARY(MISSILE_FIRE_SIG, me); QS_SIG_DICTIONARY(HIT_WALL_SIG, me); QS_SIG_DICTIONARY(DESTROYED_MINE_SIG, me); @@ -111,11 +111,11 @@ static QState Missile_initial(Missile * const me, void const * const par) { return Q_TRAN(&Missile_armed); } -/*${AOs::Missile::SM::armed} ...............................................*/ +//${AOs::Missile::SM::armed} ................................................. static QState Missile_armed(Missile * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${AOs::Missile::SM::armed::MISSILE_FIRE} */ + //${AOs::Missile::SM::armed::MISSILE_FIRE} case MISSILE_FIRE_SIG: { me->x = Q_EVT_CAST(ObjectPosEvt)->x; me->y = Q_EVT_CAST(ObjectPosEvt)->y; @@ -130,17 +130,17 @@ static QState Missile_armed(Missile * const me, QEvt const * const e) { return status_; } -/*${AOs::Missile::SM::flying} ..............................................*/ +//${AOs::Missile::SM::flying} ................................................ static QState Missile_flying(Missile * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${AOs::Missile::SM::flying::TIME_TICK} */ + //${AOs::Missile::SM::flying::TIME_TICK} case TIME_TICK_SIG: { - /*${AOs::Missile::SM::flying::TIME_TICK::[me->x+GAME_MISSILE_SPEED_Xx+GAME_MISSILE_SPEED_Xx + GAME_MISSILE_SPEED_X < GAME_TUNNEL_WIDTH) { ObjectImageEvt *oie; me->x += GAME_MISSILE_SPEED_X; - /*tell the Tunnel to draw the Missile and test for wall hits*/ + //tell the Tunnel to draw the Missile and test for wall hits oie = Q_NEW(ObjectImageEvt, MISSILE_IMG_SIG); oie->x = me->x; oie->y = me->y; @@ -148,18 +148,18 @@ static QState Missile_flying(Missile * const me, QEvt const * const e) { QACTIVE_POST(AO_Tunnel, (QEvt *)oie, me); status_ = Q_HANDLED(); } - /*${AOs::Missile::SM::flying::TIME_TICK::[else]} */ + //${AOs::Missile::SM::flying::TIME_TICK::[else]} else { status_ = Q_TRAN(&Missile_armed); } break; } - /*${AOs::Missile::SM::flying::HIT_WALL} */ + //${AOs::Missile::SM::flying::HIT_WALL} case HIT_WALL_SIG: { status_ = Q_TRAN(&Missile_exploding); break; } - /*${AOs::Missile::SM::flying::DESTROYED_MINE} */ + //${AOs::Missile::SM::flying::DESTROYED_MINE} case DESTROYED_MINE_SIG: { QACTIVE_POST(AO_Ship, e, me); status_ = Q_TRAN(&Missile_armed); @@ -173,34 +173,34 @@ static QState Missile_flying(Missile * const me, QEvt const * const e) { return status_; } -/*${AOs::Missile::SM::exploding} ...........................................*/ +//${AOs::Missile::SM::exploding} ............................................. static QState Missile_exploding(Missile * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${AOs::Missile::SM::exploding} */ + //${AOs::Missile::SM::exploding} case Q_ENTRY_SIG: { me->exp_ctr = 0U; status_ = Q_HANDLED(); break; } - /*${AOs::Missile::SM::exploding::TIME_TICK} */ + //${AOs::Missile::SM::exploding::TIME_TICK} case TIME_TICK_SIG: { - /*${AOs::Missile::SM::exploding::TIME_TICK::[(me->x>=GAME_SPEED_X)&&(me->exp~} */ + //${AOs::Missile::SM::exploding::TIME_TICK::[(me->x>=GAME_SPEED_X)&&(me->exp~} if ((me->x >= GAME_SPEED_X) && (me->exp_ctr < 15U)) { ObjectImageEvt *oie; - ++me->exp_ctr; /* advance the explosion counter */ - me->x -= GAME_SPEED_X; /* move the explosion by one step */ + ++me->exp_ctr; // advance the explosion counter + me->x -= GAME_SPEED_X; // move the explosion by one step - /* tell the Tunnel to render the current stage of Explosion */ + // tell the Tunnel to render the current stage of Explosion oie = Q_NEW(ObjectImageEvt, EXPLOSION_SIG); - oie->x = me->x + 3U; /* x-pos of explosion */ - oie->y = (int8_t)((int)me->y - 4U); /* y-pos */ + oie->x = me->x + 3U; // x-pos of explosion + oie->y = (int8_t)((int)me->y - 4U); // y-pos oie->bmp = EXPLOSION0_BMP + (me->exp_ctr >> 2); QACTIVE_POST(AO_Tunnel, (QEvt *)oie, me); status_ = Q_HANDLED(); } - /*${AOs::Missile::SM::exploding::TIME_TICK::[else]} */ + //${AOs::Missile::SM::exploding::TIME_TICK::[else]} else { status_ = Q_TRAN(&Missile_armed); } @@ -213,4 +213,4 @@ static QState Missile_exploding(Missile * const me, QEvt const * const e) { } return status_; } -/*$enddef${AOs::Missile} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$enddef${AOs::Missile} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/examples/arm-cm/game_efm32-slstk3401a/qk/armclang/game-qk.uvoptx b/examples/arm-cm/game_efm32-slstk3401a/qk/armclang/game-qk.uvoptx index 714e9a24..440a7817 100644 --- a/examples/arm-cm/game_efm32-slstk3401a/qk/armclang/game-qk.uvoptx +++ b/examples/arm-cm/game_efm32-slstk3401a/qk/armclang/game-qk.uvoptx @@ -120,7 +120,7 @@ 0 DLGUARM - / + d 0 @@ -153,7 +153,31 @@ -U0E2006F4 -O4622 -S4 -FO61 - + + + 0 + 0 + 742 + 1 +
19130
+ 0 + 0 + 0 + 0 + 0 + 1 + ..\bsp.c + + \\game_qk\../bsp.c\742 +
+
+ + + 0 + 1 + QF_ePool_ + + 1 @@ -641,7 +665,7 @@ 0 0 0 - ..\..\..\..\..\include\qstamp.c + ..\..\..\..\..\src\qs\qstamp.c qstamp.c 0 0 diff --git a/examples/arm-cm/game_efm32-slstk3401a/qk/armclang/game-qk.uvprojx b/examples/arm-cm/game_efm32-slstk3401a/qk/armclang/game-qk.uvprojx index aea165c4..e6422953 100644 --- a/examples/arm-cm/game_efm32-slstk3401a/qk/armclang/game-qk.uvprojx +++ b/examples/arm-cm/game_efm32-slstk3401a/qk/armclang/game-qk.uvprojx @@ -313,7 +313,7 @@ 0 - 7 + 1 0 0 1 @@ -337,7 +337,7 @@ 0 - EFM32PG1B200F256GM48=1 __FPU_PRESENT + EFM32PG1B200F256GM48=1 ..\..;..\..\..\..\..\include;..\..\..\..\..\ports\arm-cm\qk\armclang;..\..\..\..\..\3rd_party\CMSIS\Include;..\..\..\..\..\3rd_party\efm32pg1b @@ -396,7 +396,7 @@ qstamp.c 1 - ..\..\..\..\..\include\qstamp.c + ..\..\..\..\..\src\qs\qstamp.c bsp.h @@ -691,7 +691,7 @@ EFM32PG1B200F256GM48 Silicon Labs - SiliconLabs.EFM32PG1B_DFP.5.5.0 + SiliconLabs.GeckoPlatform_EFM32PG1B_DFP.4.0.0 https://www.silabs.com/documents/public/cmsis-packs/ IRAM(0x20000000,0x00008000) IROM(0x00000000,0x00020000) CPUTYPE("Cortex-M4") FPU2 CLOCK(12000000) ELITTLE @@ -1012,7 +1012,7 @@ 0 - NDEBUG EFM32PG1B200F256GM48=1 __FPU_PRESENT + NDEBUG EFM32PG1B200F256GM48=1 ..\..;..\..\..\..\..\include;..\..\..\..\..\ports\arm-cm\qk\armclang;..\..\..\..\..\3rd_party\CMSIS\Include;..\..\..\..\..\3rd_party\efm32pg1b @@ -1071,7 +1071,7 @@ qstamp.c 1 - ..\..\..\..\..\include\qstamp.c + ..\..\..\..\..\src\qs\qstamp.c bsp.h @@ -1687,7 +1687,7 @@ 0 - Q_SPY EFM32PG1B200F256GM48=1 __FPU_PRESENT + Q_SPY EFM32PG1B200F256GM48=1 ..\..;..\..\..\..\..\include;..\..\..\..\..\ports\arm-cm\qk\armclang;..\..\..\..\..\3rd_party\CMSIS\Include;..\..\..\..\..\3rd_party\efm32pg1b @@ -1746,7 +1746,7 @@ qstamp.c 1 - ..\..\..\..\..\include\qstamp.c + ..\..\..\..\..\src\qs\qstamp.c bsp.h diff --git a/examples/arm-cm/game_efm32-slstk3401a/qk/bsp.c b/examples/arm-cm/game_efm32-slstk3401a/qk/bsp.c index 9193469d..0fd9655a 100644 --- a/examples/arm-cm/game_efm32-slstk3401a/qk/bsp.c +++ b/examples/arm-cm/game_efm32-slstk3401a/qk/bsp.c @@ -1,56 +1,56 @@ -/***************************************************************************** -* Product: "Fly 'n' Shoot" game example, EFM32-SLSTK3401A board, QK kernel -* Last updated for version 6.9.2a -* Last updated on 2021-01-31 -* -* Q u a n t u m L e a P s -* ------------------------ -* Modern Embedded Software -* -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* -* -*****************************************************************************/ +//============================================================================ +// Product: "Fly 'n' Shoot" game example, EFM32-SLSTK3401A board, QK kernel +// Last updated for version 7.3.0 +// Last updated on 2023-08-23 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// This program is open source software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Alternatively, this program may be distributed and modified under the +// terms of Quantum Leaps commercial licenses, which expressly supersede +// the GNU General Public License and are specifically designed for +// licensees interested in retaining the proprietary status of their code. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Contact information: +// +// +//============================================================================ #include "qpc.h" #include "game.h" #include "bsp.h" -#include "em_device.h" /* the device specific header (SiLabs) */ -#include "em_chip.h" /* Chip errata (SiLabs) */ -#include "em_cmu.h" /* Clock Management Unit (SiLabs) */ -#include "em_gpio.h" /* GPIO (SiLabs) */ -#include "em_usart.h" /* USART (SiLabs) */ -#include "display_ls013b7dh03.h" /* LS013b7DH03 display (SiLabs/QL) */ -/* add other drivers if necessary... */ +#include "em_device.h" // the device specific header (SiLabs) +#include "em_chip.h" // Chip errata (SiLabs) +#include "em_cmu.h" // Clock Management Unit (SiLabs) +#include "em_gpio.h" // GPIO (SiLabs) +#include "em_usart.h" // USART (SiLabs) +#include "display_ls013b7dh03.h" // LS013b7DH03 display (SiLabs/QL) +// add other drivers if necessary... Q_DEFINE_THIS_FILE -/* ISRs defined in this BSP ------------------------------------------------*/ +// ISRs defined in this BSP ------------------------------------------------ void SysTick_Handler(void); void GPIO_EVEN_IRQHandler(void); void USART0_RX_IRQHandler(void); -/* Local-scope objects -----------------------------------------------------*/ +// Local-scope objects ----------------------------------------------------- #define LED_PORT gpioPortF #define LED0_PIN 4 #define LED1_PIN 5 @@ -59,13 +59,13 @@ void USART0_RX_IRQHandler(void); #define PB0_PIN 6 #define PB1_PIN 7 -/* LCD geometry and frame buffer */ +// LCD geometry and frame buffer static uint32_t l_fb[BSP_SCREEN_HEIGHT + 1][BSP_SCREEN_WIDTH / 32U]; -/* the walls buffer */ +// the walls buffer static uint32_t l_walls[GAME_TUNNEL_HEIGHT + 1][BSP_SCREEN_WIDTH / 32U]; -static unsigned l_rnd; /* random seed */ +static unsigned l_rnd; // random seed static void paintBits(uint8_t x, uint8_t y, uint8_t const *bits, uint8_t h); static void paintBitsClear(uint8_t x, uint8_t y, @@ -74,41 +74,41 @@ static void paintBitsClear(uint8_t x, uint8_t y, QSTimeCtr QS_tickTime_; QSTimeCtr QS_tickPeriod_; - /* QSpy source IDs */ + // QSpy source IDs static QSpyId const l_SysTick_Handler = { 0U }; static QSpyId const l_GPIO_EVEN_IRQHandler = { 0U }; static USART_TypeDef * const l_USART0 = ((USART_TypeDef *)(0x40010000UL)); - enum AppRecords { /* application-specific trace records */ + enum AppRecords { // application-specific trace records SCORE_STAT = QS_USER, COMMAND_STAT }; #endif -/* ISRs used in the application ==========================================*/ +// ISRs used in the application ========================================== void SysTick_Handler(void) { - static QEvt const tickEvt = { TIME_TICK_SIG, 0U, 0U }; + static QEvt const tickEvt = QEVT_INITIALIZER(TIME_TICK_SIG); - QK_ISR_ENTRY(); /* inform QK about entering an ISR */ + QK_ISR_ENTRY(); // inform QK about entering an ISR #ifdef Q_SPY { - /* clear SysTick_CTRL_COUNTFLAG */ + // clear SysTick_CTRL_COUNTFLAG uint32_t volatile tmp = SysTick->CTRL; - (void)tmp; /* avoid compiler warning about unused local variable */ - QS_tickTime_ += QS_tickPeriod_; /* account for the clock rollover */ + (void)tmp; // avoid compiler warning about unused local variable + QS_tickTime_ += QS_tickPeriod_; // account for the clock rollover } #endif - //QTIMEEVT_TICK_X(0U, &l_SysTick_Handler); /* process time events for rate 0 */ - QACTIVE_POST(the_Ticker0, 0, 0); /* post a don't-care event to Ticker0 */ + //QTIMEEVT_TICK_X(0U, &l_SysTick_Handler); // process time events for rate 0 + QTICKER_TRIG(the_Ticker0, &l_SysTick_Handler); // trigger ticker AO - QACTIVE_PUBLISH(&tickEvt, &l_SysTick_Handler); /* publish to all subscribers */ + QACTIVE_PUBLISH(&tickEvt, &l_SysTick_Handler); // publish to all subscribers { - /* state of the button debouncing, see below */ + // state of the button debouncing, see below static struct ButtonsDebouncing { uint32_t depressed; uint32_t previous; @@ -116,45 +116,45 @@ void SysTick_Handler(void) { uint32_t current; uint32_t tmp; - /* Perform the debouncing of buttons. The algorithm for debouncing - * adapted from the book "Embedded Systems Dictionary" by Jack Ganssle - * and Michael Barr, page 71. - */ - current = ~GPIO->P[PB_PORT].DIN; /* read PB0 and BP1 */ - tmp = buttons.depressed; /* save the debounced depressed buttons */ - buttons.depressed |= (buttons.previous & current); /* set depressed */ - buttons.depressed &= (buttons.previous | current); /* clear released */ - buttons.previous = current; /* update the history */ - tmp ^= buttons.depressed; /* changed debounced depressed */ - if ((tmp & (1U << PB0_PIN)) != 0U) { /* debounced PB0 state changed? */ - if ((buttons.depressed & (1U << PB0_PIN)) != 0U) {/*PB0 depressed?*/ - static QEvt const trigEvt = { PLAYER_TRIGGER_SIG, 0U, 0U}; + // Perform the debouncing of buttons. The algorithm for debouncing + // adapted from the book "Embedded Systems Dictionary" by Jack Ganssle + // and Michael Barr, page 71. + // + current = ~GPIO->P[PB_PORT].DIN; // read PB0 and BP1 + tmp = buttons.depressed; // save the debounced depressed buttons + buttons.depressed |= (buttons.previous & current); // set depressed + buttons.depressed &= (buttons.previous | current); // clear released + buttons.previous = current; // update the history + tmp ^= buttons.depressed; // changed debounced depressed + if ((tmp & (1U << PB0_PIN)) != 0U) { // debounced PB0 state changed? + if ((buttons.depressed & (1U << PB0_PIN)) != 0U) {//PB0 depressed? + static QEvt const trigEvt = QEVT_INITIALIZER(PLAYER_TRIGGER_SIG); QACTIVE_PUBLISH(&trigEvt, &l_SysTick_Handler); } } } - QK_ISR_EXIT(); /* inform QK about exiting an ISR */ + QK_ISR_EXIT(); // inform QK about exiting an ISR } -/*..........................................................................*/ +//............................................................................ void GPIO_EVEN_IRQHandler(void) { - QK_ISR_ENTRY(); /* inform QK about entering an ISR */ + QK_ISR_ENTRY(); // inform QK about entering an ISR - QACTIVE_POST(AO_Tunnel, Q_NEW(QEvt, MAX_PUB_SIG), /* for testing... */ + QACTIVE_POST(AO_Tunnel, Q_NEW(QEvt, MAX_PUB_SIG), // for testing... &l_GPIO_EVEN_IRQHandler); - QK_ISR_EXIT(); /* inform QK about exiting an ISR */ + QK_ISR_EXIT(); // inform QK about exiting an ISR } -/*..........................................................................*/ +//............................................................................ void USART0_RX_IRQHandler(void); // prototype #ifdef Q_SPY -/* ISR for receiving bytes from the QSPY Back-End -* NOTE: This ISR is "QF-unaware" meaning that it does not interact with -* the QF/QK and is not disabled. Such ISRs don't need to call QK_ISR_ENTRY/ -* QK_ISR_EXIT and they cannot post or publish events. -*/ +// ISR for receiving bytes from the QSPY Back-End +// NOTE: This ISR is "QF-unaware" meaning that it does not interact with +// the QF/QK and is not disabled. Such ISRs don't need to call QK_ISR_ENTRY/ +// QK_ISR_EXIT and they cannot post or publish events. +// void USART0_RX_IRQHandler(void) { - /* while RX FIFO NOT empty */ + // while RX FIFO NOT empty while ((l_USART0->STATUS & USART_STATUS_RXDATAV) != 0) { uint32_t b = l_USART0->RXDATA; QS_RX_PUT(b); @@ -163,43 +163,43 @@ void USART0_RX_IRQHandler(void) { } #else void USART0_RX_IRQHandler(void) {} -#endif /* Q_SPY */ +#endif // Q_SPY -/* BSP functions ===========================================================*/ +// BSP functions =========================================================== void BSP_init(void) { - /* Chip errata */ + // Chip errata CHIP_Init(); - /* NOTE: SystemInit() already called from startup_TM4C123GH6PM.s - * but SystemCoreClock needs to be updated - */ + // NOTE: SystemInit() already called from startup_TM4C123GH6PM.s + // but SystemCoreClock needs to be updated + // SystemCoreClockUpdate(); - /* NOTE The VFP (Floating Point Unit) unit is configured by QK-port */ + // NOTE The VFP (Floating Point Unit) unit is configured by QK-port - /* enable clock for to the peripherals used by this application... */ + // enable clock for to the peripherals used by this application... CMU_ClockEnable(cmuClock_HFPER, true); CMU_ClockEnable(cmuClock_GPIO, true); CMU_ClockEnable(cmuClock_HFPER, true); CMU_ClockEnable(cmuClock_GPIO, true); - /* configure the LEDs */ + // configure the LEDs GPIO_PinModeSet(LED_PORT, LED0_PIN, gpioModePushPull, 0); GPIO_PinModeSet(LED_PORT, LED1_PIN, gpioModePushPull, 0); GPIO_PinOutClear(LED_PORT, LED0_PIN); GPIO_PinOutClear(LED_PORT, LED1_PIN); - /* configure the Buttons */ + // configure the Buttons GPIO_PinModeSet(PB_PORT, PB0_PIN, gpioModeInputPull, 1); GPIO_PinModeSet(PB_PORT, PB1_PIN, gpioModeInputPull, 1); - /* Initialize the DISPLAY driver. */ + // Initialize the DISPLAY driver if (!Display_init()) { Q_ERROR(); } - /* initialize the QS software tracing */ + // initialize the QS software tracing if (QS_INIT((void *)0) == 0U) { Q_ERROR(); } @@ -209,19 +209,19 @@ void BSP_init(void) { QS_USR_DICTIONARY(SCORE_STAT); QS_USR_DICTIONARY(COMMAND_STAT); - /* setup the QS filters... */ - QS_GLB_FILTER(QS_SM_RECORDS); /* state machine records */ - QS_GLB_FILTER(QS_AO_RECORDS); /* active object records */ - QS_GLB_FILTER(QS_UA_RECORDS); /* all user records */ + // setup the QS filters... + QS_GLB_FILTER(QS_SM_RECORDS); // state machine records + QS_GLB_FILTER(QS_AO_RECORDS); // active object records + QS_GLB_FILTER(QS_UA_RECORDS); // all user records } -/*..........................................................................*/ +//............................................................................ void BSP_updateScreen(void) { GPIO->P[LED_PORT].DOUT |= (1U << LED1_PIN); Display_sendPA(&l_fb[0][0], 0, LS013B7DH03_HEIGHT); GPIO->P[LED_PORT].DOUT &= ~(1U << LED1_PIN); } -/*..........................................................................*/ +//............................................................................ void BSP_clearFB() { uint_fast8_t y; for (y = 0U; y < BSP_SCREEN_HEIGHT; ++y) { @@ -231,7 +231,7 @@ void BSP_clearFB() { l_fb[y][3] = 0U; } } -/*..........................................................................*/ +//............................................................................ void BSP_clearWalls() { uint_fast8_t y; for (y = 0U; y < GAME_TUNNEL_HEIGHT; ++y) { @@ -241,108 +241,108 @@ void BSP_clearWalls() { l_walls[y][3] = 0U; } } -/*..........................................................................*/ -bool BSP_isThrottle(void) { /* is the throttle button depressed? */ +//............................................................................ +bool BSP_isThrottle(void) { // is the throttle button depressed? return (GPIO->P[PB_PORT].DIN & (1U << PB1_PIN)) == 0U; } -/*..........................................................................*/ +//............................................................................ void BSP_paintString(uint8_t x, uint8_t y, char const *str) { static uint8_t const font5x7[95][7] = { - { 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U }, /* */ - { 0x04U, 0x04U, 0x04U, 0x04U, 0x00U, 0x00U, 0x04U }, /* ! */ - { 0x0AU, 0x0AU, 0x0AU, 0x00U, 0x00U, 0x00U, 0x00U }, /* " */ - { 0x0AU, 0x0AU, 0x1FU, 0x0AU, 0x1FU, 0x0AU, 0x0AU }, /* # */ - { 0x04U, 0x1EU, 0x05U, 0x0EU, 0x14U, 0x0FU, 0x04U }, /* $ */ - { 0x03U, 0x13U, 0x08U, 0x04U, 0x02U, 0x19U, 0x18U }, /* % */ - { 0x06U, 0x09U, 0x05U, 0x02U, 0x15U, 0x09U, 0x16U }, /* & */ - { 0x06U, 0x04U, 0x02U, 0x00U, 0x00U, 0x00U, 0x00U }, /* ' */ - { 0x08U, 0x04U, 0x02U, 0x02U, 0x02U, 0x04U, 0x08U }, /* ( */ - { 0x02U, 0x04U, 0x08U, 0x08U, 0x08U, 0x04U, 0x02U }, /* ) */ - { 0x00U, 0x04U, 0x15U, 0x0EU, 0x15U, 0x04U, 0x00U }, /* * */ - { 0x00U, 0x04U, 0x04U, 0x1FU, 0x04U, 0x04U, 0x00U }, /* + */ - { 0x00U, 0x00U, 0x00U, 0x00U, 0x06U, 0x04U, 0x02U }, /* , */ - { 0x00U, 0x00U, 0x00U, 0x1FU, 0x00U, 0x00U, 0x00U }, /* - */ - { 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x06U, 0x06U }, /* . */ - { 0x00U, 0x10U, 0x08U, 0x04U, 0x02U, 0x01U, 0x00U }, /* / */ - { 0x0EU, 0x11U, 0x19U, 0x15U, 0x13U, 0x11U, 0x0EU }, /* 0 */ - { 0x04U, 0x06U, 0x04U, 0x04U, 0x04U, 0x04U, 0x0EU }, /* 1 */ - { 0x0EU, 0x11U, 0x10U, 0x08U, 0x04U, 0x02U, 0x1FU }, /* 2 */ - { 0x1FU, 0x08U, 0x04U, 0x08U, 0x10U, 0x11U, 0x0EU }, /* 3 */ - { 0x08U, 0x0CU, 0x0AU, 0x09U, 0x1FU, 0x08U, 0x08U }, /* 4 */ - { 0x1FU, 0x01U, 0x0FU, 0x10U, 0x10U, 0x11U, 0x0EU }, /* 5 */ - { 0x0CU, 0x02U, 0x01U, 0x0FU, 0x11U, 0x11U, 0x0EU }, /* 6 */ - { 0x1FU, 0x10U, 0x08U, 0x04U, 0x02U, 0x02U, 0x02U }, /* 7 */ - { 0x0EU, 0x11U, 0x11U, 0x0EU, 0x11U, 0x11U, 0x0EU }, /* 8 */ - { 0x0EU, 0x11U, 0x11U, 0x1EU, 0x10U, 0x08U, 0x06U }, /* 9 */ - { 0x00U, 0x06U, 0x06U, 0x00U, 0x06U, 0x06U, 0x00U }, /* : */ - { 0x00U, 0x06U, 0x06U, 0x00U, 0x06U, 0x04U, 0x02U }, /* ; */ - { 0x08U, 0x04U, 0x02U, 0x01U, 0x02U, 0x04U, 0x08U }, /* < */ - { 0x00U, 0x00U, 0x1FU, 0x00U, 0x1FU, 0x00U, 0x00U }, /* = */ - { 0x02U, 0x04U, 0x08U, 0x10U, 0x08U, 0x04U, 0x02U }, /* > */ - { 0x0EU, 0x11U, 0x10U, 0x08U, 0x04U, 0x00U, 0x04U }, /* ? */ - { 0x0EU, 0x11U, 0x10U, 0x16U, 0x15U, 0x15U, 0x0EU }, /* @ */ - { 0x0EU, 0x11U, 0x11U, 0x11U, 0x1FU, 0x11U, 0x11U }, /* A */ - { 0x0FU, 0x11U, 0x11U, 0x0FU, 0x11U, 0x11U, 0x0FU }, /* B */ - { 0x0EU, 0x11U, 0x01U, 0x01U, 0x01U, 0x11U, 0x0EU }, /* C */ - { 0x07U, 0x09U, 0x11U, 0x11U, 0x11U, 0x09U, 0x07U }, /* D */ - { 0x1FU, 0x01U, 0x01U, 0x0FU, 0x01U, 0x01U, 0x1FU }, /* E */ - { 0x1FU, 0x01U, 0x01U, 0x0FU, 0x01U, 0x01U, 0x01U }, /* F */ - { 0x0EU, 0x11U, 0x01U, 0x1DU, 0x11U, 0x11U, 0x1EU }, /* G */ - { 0x11U, 0x11U, 0x11U, 0x1FU, 0x11U, 0x11U, 0x11U }, /* H */ - { 0x0EU, 0x04U, 0x04U, 0x04U, 0x04U, 0x04U, 0x0EU }, /* I */ - { 0x1CU, 0x08U, 0x08U, 0x08U, 0x08U, 0x09U, 0x06U }, /* J */ - { 0x11U, 0x09U, 0x05U, 0x03U, 0x05U, 0x09U, 0x11U }, /* K */ - { 0x01U, 0x01U, 0x01U, 0x01U, 0x01U, 0x01U, 0x1FU }, /* L */ - { 0x11U, 0x1BU, 0x15U, 0x15U, 0x11U, 0x11U, 0x11U }, /* M */ - { 0x11U, 0x11U, 0x13U, 0x15U, 0x19U, 0x11U, 0x11U }, /* N */ - { 0x0EU, 0x11U, 0x11U, 0x11U, 0x11U, 0x11U, 0x0EU }, /* O */ - { 0x0FU, 0x11U, 0x11U, 0x0FU, 0x01U, 0x01U, 0x01U }, /* P */ - { 0x0EU, 0x11U, 0x11U, 0x11U, 0x15U, 0x09U, 0x16U }, /* Q */ - { 0x0FU, 0x11U, 0x11U, 0x0FU, 0x05U, 0x09U, 0x11U }, /* R */ - { 0x1EU, 0x01U, 0x01U, 0x0EU, 0x10U, 0x10U, 0x0FU }, /* S */ - { 0x1FU, 0x04U, 0x04U, 0x04U, 0x04U, 0x04U, 0x04U }, /* T */ - { 0x11U, 0x11U, 0x11U, 0x11U, 0x11U, 0x11U, 0x0EU }, /* U */ - { 0x11U, 0x11U, 0x11U, 0x11U, 0x11U, 0x0AU, 0x04U }, /* V */ - { 0x11U, 0x11U, 0x11U, 0x15U, 0x15U, 0x15U, 0x0AU }, /* W */ - { 0x11U, 0x11U, 0x0AU, 0x04U, 0x0AU, 0x11U, 0x11U }, /* X */ - { 0x11U, 0x11U, 0x11U, 0x0AU, 0x04U, 0x04U, 0x04U }, /* Y */ - { 0x1FU, 0x10U, 0x08U, 0x04U, 0x02U, 0x01U, 0x1FU }, /* Z */ - { 0x0EU, 0x02U, 0x02U, 0x02U, 0x02U, 0x02U, 0x0EU }, /* [ */ - { 0x00U, 0x01U, 0x02U, 0x04U, 0x08U, 0x10U, 0x00U }, /* \ */ - { 0x0EU, 0x08U, 0x08U, 0x08U, 0x08U, 0x08U, 0x0EU }, /* ] */ - { 0x04U, 0x0AU, 0x11U, 0x00U, 0x00U, 0x00U, 0x00U }, /* ^ */ - { 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x1FU }, /* _ */ - { 0x02U, 0x04U, 0x08U, 0x00U, 0x00U, 0x00U, 0x00U }, /* ` */ - { 0x00U, 0x00U, 0x0EU, 0x10U, 0x1EU, 0x11U, 0x1EU }, /* a */ - { 0x01U, 0x01U, 0x0DU, 0x13U, 0x11U, 0x11U, 0x0FU }, /* b */ - { 0x00U, 0x00U, 0x0EU, 0x01U, 0x01U, 0x11U, 0x0EU }, /* c */ - { 0x10U, 0x10U, 0x16U, 0x19U, 0x11U, 0x11U, 0x1EU }, /* d */ - { 0x00U, 0x00U, 0x0EU, 0x11U, 0x1FU, 0x01U, 0x0EU }, /* e */ - { 0x0CU, 0x12U, 0x02U, 0x07U, 0x02U, 0x02U, 0x02U }, /* f */ - { 0x00U, 0x1EU, 0x11U, 0x11U, 0x1EU, 0x10U, 0x0EU }, /* g */ - { 0x01U, 0x01U, 0x0DU, 0x13U, 0x11U, 0x11U, 0x11U }, /* h */ - { 0x04U, 0x00U, 0x06U, 0x04U, 0x04U, 0x04U, 0x0EU }, /* i */ - { 0x08U, 0x00U, 0x0CU, 0x08U, 0x08U, 0x09U, 0x06U }, /* j */ - { 0x01U, 0x01U, 0x09U, 0x05U, 0x03U, 0x05U, 0x09U }, /* k */ - { 0x06U, 0x04U, 0x04U, 0x04U, 0x04U, 0x04U, 0x0EU }, /* l */ - { 0x00U, 0x00U, 0x0BU, 0x15U, 0x15U, 0x11U, 0x11U }, /* m */ - { 0x00U, 0x00U, 0x0DU, 0x13U, 0x11U, 0x11U, 0x11U }, /* n */ - { 0x00U, 0x00U, 0x0EU, 0x11U, 0x11U, 0x11U, 0x0EU }, /* o */ - { 0x00U, 0x00U, 0x0FU, 0x11U, 0x0FU, 0x01U, 0x01U }, /* p */ - { 0x00U, 0x00U, 0x16U, 0x19U, 0x1EU, 0x10U, 0x10U }, /* q */ - { 0x00U, 0x00U, 0x0DU, 0x13U, 0x01U, 0x01U, 0x01U }, /* r */ - { 0x00U, 0x00U, 0x0EU, 0x01U, 0x0EU, 0x10U, 0x0FU }, /* s */ - { 0x02U, 0x02U, 0x07U, 0x02U, 0x02U, 0x12U, 0x0CU }, /* t */ - { 0x00U, 0x00U, 0x11U, 0x11U, 0x11U, 0x19U, 0x16U }, /* u */ - { 0x00U, 0x00U, 0x11U, 0x11U, 0x11U, 0x0AU, 0x04U }, /* v */ - { 0x00U, 0x00U, 0x11U, 0x11U, 0x15U, 0x15U, 0x0AU }, /* w */ - { 0x00U, 0x00U, 0x11U, 0x0AU, 0x04U, 0x0AU, 0x11U }, /* x */ - { 0x00U, 0x00U, 0x11U, 0x11U, 0x1EU, 0x10U, 0x0EU }, /* y */ - { 0x00U, 0x00U, 0x1FU, 0x08U, 0x04U, 0x02U, 0x1FU }, /* z */ - { 0x08U, 0x04U, 0x04U, 0x02U, 0x04U, 0x04U, 0x08U }, /* { */ - { 0x04U, 0x04U, 0x04U, 0x04U, 0x04U, 0x04U, 0x04U }, /* | */ - { 0x02U, 0x04U, 0x04U, 0x08U, 0x04U, 0x04U, 0x02U }, /* } */ - { 0x02U, 0x15U, 0x08U, 0x00U, 0x00U, 0x00U, 0x00U }, /* ~ */ + { 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U }, // + { 0x04U, 0x04U, 0x04U, 0x04U, 0x00U, 0x00U, 0x04U }, // ! + { 0x0AU, 0x0AU, 0x0AU, 0x00U, 0x00U, 0x00U, 0x00U }, // " + { 0x0AU, 0x0AU, 0x1FU, 0x0AU, 0x1FU, 0x0AU, 0x0AU }, // # + { 0x04U, 0x1EU, 0x05U, 0x0EU, 0x14U, 0x0FU, 0x04U }, // $ + { 0x03U, 0x13U, 0x08U, 0x04U, 0x02U, 0x19U, 0x18U }, // % + { 0x06U, 0x09U, 0x05U, 0x02U, 0x15U, 0x09U, 0x16U }, // & + { 0x06U, 0x04U, 0x02U, 0x00U, 0x00U, 0x00U, 0x00U }, // ' + { 0x08U, 0x04U, 0x02U, 0x02U, 0x02U, 0x04U, 0x08U }, // ( + { 0x02U, 0x04U, 0x08U, 0x08U, 0x08U, 0x04U, 0x02U }, // ) + { 0x00U, 0x04U, 0x15U, 0x0EU, 0x15U, 0x04U, 0x00U }, // * + { 0x00U, 0x04U, 0x04U, 0x1FU, 0x04U, 0x04U, 0x00U }, // + + { 0x00U, 0x00U, 0x00U, 0x00U, 0x06U, 0x04U, 0x02U }, // , + { 0x00U, 0x00U, 0x00U, 0x1FU, 0x00U, 0x00U, 0x00U }, // - + { 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x06U, 0x06U }, // . + { 0x00U, 0x10U, 0x08U, 0x04U, 0x02U, 0x01U, 0x00U }, // / + { 0x0EU, 0x11U, 0x19U, 0x15U, 0x13U, 0x11U, 0x0EU }, // 0 + { 0x04U, 0x06U, 0x04U, 0x04U, 0x04U, 0x04U, 0x0EU }, // 1 + { 0x0EU, 0x11U, 0x10U, 0x08U, 0x04U, 0x02U, 0x1FU }, // 2 + { 0x1FU, 0x08U, 0x04U, 0x08U, 0x10U, 0x11U, 0x0EU }, // 3 + { 0x08U, 0x0CU, 0x0AU, 0x09U, 0x1FU, 0x08U, 0x08U }, // 4 + { 0x1FU, 0x01U, 0x0FU, 0x10U, 0x10U, 0x11U, 0x0EU }, // 5 + { 0x0CU, 0x02U, 0x01U, 0x0FU, 0x11U, 0x11U, 0x0EU }, // 6 + { 0x1FU, 0x10U, 0x08U, 0x04U, 0x02U, 0x02U, 0x02U }, // 7 + { 0x0EU, 0x11U, 0x11U, 0x0EU, 0x11U, 0x11U, 0x0EU }, // 8 + { 0x0EU, 0x11U, 0x11U, 0x1EU, 0x10U, 0x08U, 0x06U }, // 9 + { 0x00U, 0x06U, 0x06U, 0x00U, 0x06U, 0x06U, 0x00U }, // : + { 0x00U, 0x06U, 0x06U, 0x00U, 0x06U, 0x04U, 0x02U }, // ; + { 0x08U, 0x04U, 0x02U, 0x01U, 0x02U, 0x04U, 0x08U }, // < + { 0x00U, 0x00U, 0x1FU, 0x00U, 0x1FU, 0x00U, 0x00U }, // = + { 0x02U, 0x04U, 0x08U, 0x10U, 0x08U, 0x04U, 0x02U }, // > + { 0x0EU, 0x11U, 0x10U, 0x08U, 0x04U, 0x00U, 0x04U }, // ? + { 0x0EU, 0x11U, 0x10U, 0x16U, 0x15U, 0x15U, 0x0EU }, // @ + { 0x0EU, 0x11U, 0x11U, 0x11U, 0x1FU, 0x11U, 0x11U }, // A + { 0x0FU, 0x11U, 0x11U, 0x0FU, 0x11U, 0x11U, 0x0FU }, // B + { 0x0EU, 0x11U, 0x01U, 0x01U, 0x01U, 0x11U, 0x0EU }, // C + { 0x07U, 0x09U, 0x11U, 0x11U, 0x11U, 0x09U, 0x07U }, // D + { 0x1FU, 0x01U, 0x01U, 0x0FU, 0x01U, 0x01U, 0x1FU }, // E + { 0x1FU, 0x01U, 0x01U, 0x0FU, 0x01U, 0x01U, 0x01U }, // F + { 0x0EU, 0x11U, 0x01U, 0x1DU, 0x11U, 0x11U, 0x1EU }, // G + { 0x11U, 0x11U, 0x11U, 0x1FU, 0x11U, 0x11U, 0x11U }, // H + { 0x0EU, 0x04U, 0x04U, 0x04U, 0x04U, 0x04U, 0x0EU }, // I + { 0x1CU, 0x08U, 0x08U, 0x08U, 0x08U, 0x09U, 0x06U }, // J + { 0x11U, 0x09U, 0x05U, 0x03U, 0x05U, 0x09U, 0x11U }, // K + { 0x01U, 0x01U, 0x01U, 0x01U, 0x01U, 0x01U, 0x1FU }, // L + { 0x11U, 0x1BU, 0x15U, 0x15U, 0x11U, 0x11U, 0x11U }, // M + { 0x11U, 0x11U, 0x13U, 0x15U, 0x19U, 0x11U, 0x11U }, // N + { 0x0EU, 0x11U, 0x11U, 0x11U, 0x11U, 0x11U, 0x0EU }, // O + { 0x0FU, 0x11U, 0x11U, 0x0FU, 0x01U, 0x01U, 0x01U }, // P + { 0x0EU, 0x11U, 0x11U, 0x11U, 0x15U, 0x09U, 0x16U }, // Q + { 0x0FU, 0x11U, 0x11U, 0x0FU, 0x05U, 0x09U, 0x11U }, // R + { 0x1EU, 0x01U, 0x01U, 0x0EU, 0x10U, 0x10U, 0x0FU }, // S + { 0x1FU, 0x04U, 0x04U, 0x04U, 0x04U, 0x04U, 0x04U }, // T + { 0x11U, 0x11U, 0x11U, 0x11U, 0x11U, 0x11U, 0x0EU }, // U + { 0x11U, 0x11U, 0x11U, 0x11U, 0x11U, 0x0AU, 0x04U }, // V + { 0x11U, 0x11U, 0x11U, 0x15U, 0x15U, 0x15U, 0x0AU }, // W + { 0x11U, 0x11U, 0x0AU, 0x04U, 0x0AU, 0x11U, 0x11U }, // X + { 0x11U, 0x11U, 0x11U, 0x0AU, 0x04U, 0x04U, 0x04U }, // Y + { 0x1FU, 0x10U, 0x08U, 0x04U, 0x02U, 0x01U, 0x1FU }, // Z + { 0x0EU, 0x02U, 0x02U, 0x02U, 0x02U, 0x02U, 0x0EU }, // [ + { 0x00U, 0x01U, 0x02U, 0x04U, 0x08U, 0x10U, 0x00U }, // '\' + { 0x0EU, 0x08U, 0x08U, 0x08U, 0x08U, 0x08U, 0x0EU }, // ] + { 0x04U, 0x0AU, 0x11U, 0x00U, 0x00U, 0x00U, 0x00U }, // ^ + { 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x1FU }, // _ + { 0x02U, 0x04U, 0x08U, 0x00U, 0x00U, 0x00U, 0x00U }, // ` + { 0x00U, 0x00U, 0x0EU, 0x10U, 0x1EU, 0x11U, 0x1EU }, // a + { 0x01U, 0x01U, 0x0DU, 0x13U, 0x11U, 0x11U, 0x0FU }, // b + { 0x00U, 0x00U, 0x0EU, 0x01U, 0x01U, 0x11U, 0x0EU }, // c + { 0x10U, 0x10U, 0x16U, 0x19U, 0x11U, 0x11U, 0x1EU }, // d + { 0x00U, 0x00U, 0x0EU, 0x11U, 0x1FU, 0x01U, 0x0EU }, // e + { 0x0CU, 0x12U, 0x02U, 0x07U, 0x02U, 0x02U, 0x02U }, // f + { 0x00U, 0x1EU, 0x11U, 0x11U, 0x1EU, 0x10U, 0x0EU }, // g + { 0x01U, 0x01U, 0x0DU, 0x13U, 0x11U, 0x11U, 0x11U }, // h + { 0x04U, 0x00U, 0x06U, 0x04U, 0x04U, 0x04U, 0x0EU }, // i + { 0x08U, 0x00U, 0x0CU, 0x08U, 0x08U, 0x09U, 0x06U }, // j + { 0x01U, 0x01U, 0x09U, 0x05U, 0x03U, 0x05U, 0x09U }, // k + { 0x06U, 0x04U, 0x04U, 0x04U, 0x04U, 0x04U, 0x0EU }, // l + { 0x00U, 0x00U, 0x0BU, 0x15U, 0x15U, 0x11U, 0x11U }, // m + { 0x00U, 0x00U, 0x0DU, 0x13U, 0x11U, 0x11U, 0x11U }, // n + { 0x00U, 0x00U, 0x0EU, 0x11U, 0x11U, 0x11U, 0x0EU }, // o + { 0x00U, 0x00U, 0x0FU, 0x11U, 0x0FU, 0x01U, 0x01U }, // p + { 0x00U, 0x00U, 0x16U, 0x19U, 0x1EU, 0x10U, 0x10U }, // q + { 0x00U, 0x00U, 0x0DU, 0x13U, 0x01U, 0x01U, 0x01U }, // r + { 0x00U, 0x00U, 0x0EU, 0x01U, 0x0EU, 0x10U, 0x0FU }, // s + { 0x02U, 0x02U, 0x07U, 0x02U, 0x02U, 0x12U, 0x0CU }, // t + { 0x00U, 0x00U, 0x11U, 0x11U, 0x11U, 0x19U, 0x16U }, // u + { 0x00U, 0x00U, 0x11U, 0x11U, 0x11U, 0x0AU, 0x04U }, // v + { 0x00U, 0x00U, 0x11U, 0x11U, 0x15U, 0x15U, 0x0AU }, // w + { 0x00U, 0x00U, 0x11U, 0x0AU, 0x04U, 0x0AU, 0x11U }, // x + { 0x00U, 0x00U, 0x11U, 0x11U, 0x1EU, 0x10U, 0x0EU }, // y + { 0x00U, 0x00U, 0x1FU, 0x08U, 0x04U, 0x02U, 0x1FU }, // z + { 0x08U, 0x04U, 0x04U, 0x02U, 0x04U, 0x04U, 0x08U }, // { + { 0x04U, 0x04U, 0x04U, 0x04U, 0x04U, 0x04U, 0x04U }, // | + { 0x02U, 0x04U, 0x04U, 0x08U, 0x04U, 0x04U, 0x02U }, // } + { 0x02U, 0x15U, 0x08U, 0x00U, 0x00U, 0x00U, 0x00U }, // ~ }; for (; *str != '\0'; ++str, x += 6) { @@ -351,112 +351,112 @@ void BSP_paintString(uint8_t x, uint8_t y, char const *str) { } } -/*==========================================================================*/ -typedef struct { /* the auxiliary structure to hold const bitmaps */ - uint8_t const *bits; /* the bits in the bitmap */ - uint8_t height; /* the height of the bitmap */ +//========================================================================== +typedef struct { // the auxiliary structure to hold const bitmaps + uint8_t const *bits; // the bits in the bitmap + uint8_t height; // the height of the bitmap } Bitmap; -/* bitmap of the Ship: -* -* x.... -* xxx.. -* xxxxx -*/ +// bitmap of the Ship: +// +// x.... +// xxx.. +// xxxxx +// static uint8_t const ship_bits[] = { 0x01U, 0x07U, 0x1FU }; -/* bitmap of the Missile: -* -* xxxx -*/ +// bitmap of the Missile: +// +// xxxx +// static uint8_t const missile_bits[] = { 0x0FU }; -/* bitmap of the Mine type-1: -* -* .x. -* xxx -* .x. -*/ +// bitmap of the Mine type-1: +// +// .x. +// xxx +// .x. +// static uint8_t const mine1_bits[] = { 0x02U, 0x07U, 0x02U }; -/* bitmap of the Mine type-2: -* -* x..x -* .xx. -* .xx. -* x..x -*/ +// bitmap of the Mine type-2: +// +// x..x +// .xx. +// .xx. +// x..x +// static uint8_t const mine2_bits[] = { 0x09U, 0x06U, 0x06U, 0x09U }; -/* Mine type-2 is nastier than Mine type-1. The type-2 mine can -* hit the Ship with any of its "tentacles". However, it can be -* destroyed by the Missile only by hitting its center, defined as -* the following bitmap: -* -* .... -* .xx. -* .xx. -*/ +// Mine type-2 is nastier than Mine type-1. The type-2 mine can +// hit the Ship with any of its "tentacles". However, it can be +// destroyed by the Missile only by hitting its center, defined as +// the following bitmap: +// +// .... +// .xx. +// .xx. +// static uint8_t const mine2_missile_bits[] = { 0x00U, 0x06U, 0x06U }; -/* -* The bitmap of the explosion stage 0: -* -* ....... -* ...x... -* ..x.x.. -* ...x... -*/ +// +// The bitmap of the explosion stage 0: +// +// ....... +// ...x... +// ..x.x.. +// ...x... +// static uint8_t const explosion0_bits[] = { 0x00U, 0x08U, 0x14U, 0x08U }; -/* -* The bitmap of the explosion stage 1: -* -* ....... -* ..x.x.. -* ...x... -* ..x.x.. -*/ +// +// The bitmap of the explosion stage 1: +// +// ....... +// ..x.x.. +// ...x... +// ..x.x.. +// static uint8_t const explosion1_bits[] = { 0x00U, 0x14U, 0x08U, 0x14U }; -/* -* The bitmap of the explosion stage 2: -* -* .x...x. -* ..x.x.. -* ...x... -* ..x.x.. -* .x...x. -*/ +// +// The bitmap of the explosion stage 2: +// +// .x...x. +// ..x.x.. +// ...x... +// ..x.x.. +// .x...x. +// static uint8_t const explosion2_bits[] = { 0x11U, 0x0AU, 0x04U, 0x0AU, 0x11U }; -/* -* The bitmap of the explosion stage 3: -* -* x..x..x -* .x.x.x. -* ..x.x.. -* xx.x.xx -* ..x.x.. -* .x.x.x. -* x..x..x -*/ +// +// The bitmap of the explosion stage 3: +// +// x..x..x +// .x.x.x. +// ..x.x.. +// xx.x.xx +// ..x.x.. +// .x.x.x. +// x..x..x +// static uint8_t const explosion3_bits[] = { 0x49, 0x2A, 0x14, 0x6B, 0x14, 0x2A, 0x49 }; @@ -473,22 +473,22 @@ static Bitmap const l_bitmap[MAX_BMP] = { { explosion3_bits, Q_DIM(explosion3_bits) } }; -/*..........................................................................*/ +//............................................................................ void BSP_paintBitmap(uint8_t x, uint8_t y, uint8_t bmp_id) { Bitmap const *bmp = &l_bitmap[bmp_id]; paintBits(x, y, bmp->bits, bmp->height); } -/*..........................................................................*/ +//............................................................................ void BSP_advanceWalls(uint8_t top, uint8_t bottom) { uint_fast8_t y; for (y = 0U; y < GAME_TUNNEL_HEIGHT; ++y) { - /* shift the walls one pixel to the left */ + // shift the walls one pixel to the left l_walls[y][0] = (l_walls[y][0] >> 1) | (l_walls[y][1] << 31); l_walls[y][1] = (l_walls[y][1] >> 1) | (l_walls[y][2] << 31); l_walls[y][2] = (l_walls[y][2] >> 1) | (l_walls[y][3] << 31); l_walls[y][3] = (l_walls[y][3] >> 1); - /* add new column of walls at the end */ + // add new column of walls at the end if (y <= top) { l_walls[y][3] |= (1U << 31); } @@ -496,14 +496,14 @@ void BSP_advanceWalls(uint8_t top, uint8_t bottom) { l_walls[y][3] |= (1U << 31); } - /* copy the walls to the frame buffer */ + // copy the walls to the frame buffer l_fb[y][0] = l_walls[y][0]; l_fb[y][1] = l_walls[y][1]; l_fb[y][2] = l_walls[y][2]; l_fb[y][3] = l_walls[y][3]; } } -/*..........................................................................*/ +//............................................................................ bool BSP_doBitmapsOverlap(uint8_t bmp_id1, uint8_t x1, uint8_t y1, uint8_t bmp_id2, uint8_t x2, uint8_t y2) { @@ -517,7 +517,7 @@ bool BSP_doBitmapsOverlap(uint8_t bmp_id1, uint8_t x1, uint8_t y1, Q_REQUIRE((bmp_id1 < Q_DIM(l_bitmap)) && (bmp_id2 < Q_DIM(l_bitmap))); - /* are the bitmaps close enough in x? */ + // are the bitmaps close enough in x? if (x1 >= x2) { if (x1 > x2 + 8U) { return false; @@ -541,11 +541,11 @@ bool BSP_doBitmapsOverlap(uint8_t bmp_id1, uint8_t x1, uint8_t y1, if (h > bmp2->height) { h = bmp2->height; } - for (y = 0; y < h; ++y) { /* scan over the overlapping rows */ + for (y = 0; y < h; ++y) { // scan over the overlapping rows bits1 = ((uint32_t)bmp1->bits[y + y0] << x1); bits2 = ((uint32_t)bmp2->bits[y] << x2); - if ((bits1 & bits2) != 0U) { /* do the bits overlap? */ - return true; /* yes! */ + if ((bits1 & bits2) != 0U) { // do the bits overlap? + return true; // yes! } } } @@ -556,18 +556,18 @@ bool BSP_doBitmapsOverlap(uint8_t bmp_id1, uint8_t x1, uint8_t y1, if (h > bmp1->height) { h = bmp1->height; } - for (y = 0; y < h; ++y) { /* scan over the overlapping rows */ + for (y = 0; y < h; ++y) { // scan over the overlapping rows bits1 = ((uint32_t)bmp1->bits[y] << x1); bits2 = ((uint32_t)bmp2->bits[y + y0] << x2); - if ((bits1 & bits2) != 0U) { /* do the bits overlap? */ - return true; /* yes! */ + if ((bits1 & bits2) != 0U) { // do the bits overlap? + return true; // yes! } } } } - return false; /* the bitmaps do not overlap */ + return false; // the bitmaps do not overlap } -/*..........................................................................*/ +//............................................................................ bool BSP_isWallHit(uint8_t bmp_id, uint8_t x, uint8_t y) { Bitmap const *bmp = &l_bitmap[bmp_id]; uint32_t shft = (x & 0x1FU); @@ -585,7 +585,7 @@ bool BSP_isWallHit(uint8_t bmp_id, uint8_t x, uint8_t y) { return false; } -/*..........................................................................*/ +//............................................................................ void BSP_updateScore(uint16_t score) { char str[5]; uint16_t s = score; @@ -594,7 +594,7 @@ void BSP_updateScore(uint16_t score) { BSP_paintString(1U, BSP_SCREEN_HEIGHT - 8U, "SCORE:"); } - /* update the SCORE area on the screeen */ + // update the SCORE area on the screeen str[4] = '\0'; str[3] = (s % 10U) + '0'; s /= 10U; str[2] = (s % 10U) + '0'; s /= 10U; @@ -602,40 +602,37 @@ void BSP_updateScore(uint16_t score) { str[0] = (s % 10U) + '0'; BSP_paintString(6U*6U, BSP_SCREEN_HEIGHT - 8U, str); - QS_BEGIN_ID(SCORE_STAT, 0U) /* app-specific record */ + QS_BEGIN_ID(SCORE_STAT, 0U) // app-specific record QS_U16(4, score); QS_END() } -/*..........................................................................*/ +//............................................................................ void BSP_displayOn(void) { Display_enable(true); } -/*..........................................................................*/ +//............................................................................ void BSP_displayOff(void) { Display_enable(false); } -/*..........................................................................*/ -uint32_t BSP_random(void) { /* a very cheap pseudo-random-number generator */ - uint32_t rnd; - QSchedStatus lockStat; - - lockStat = QK_schedLock(AO_Tunnel->prio); /* lock up to Table's prio */ - /* "Super-Duper" Linear Congruential Generator (LCG) - * LCG(2^32, 3*7*11*13*23, 0, seed) - */ - rnd = l_rnd * (3U*7U*11U*13U*23U); - l_rnd = rnd; /* set for the next time */ - QK_schedUnlock(lockStat); /* unlock the scheduler */ +//............................................................................ +uint32_t BSP_random(void) { // a very cheap pseudo-random-number generator + QSchedStatus lockStat = QK_schedLock(AO_Tunnel->prio); // Table's prio + // "Super-Duper" Linear Congruential Generator (LCG) + // LCG(2^32, 3*7*11*13*23, 0, seed) + // + uint32_t rnd = l_rnd * (3U*7U*11U*13U*23U); + l_rnd = rnd; // set for the next time + QK_schedUnlock(lockStat); // unlock the scheduler return (rnd >> 8); } -/*..........................................................................*/ +//............................................................................ void BSP_randomSeed(uint32_t seed) { l_rnd = seed; } -/*--------------------------------------------------------------------------*/ -/*..........................................................................*/ +//---------------------------------------------------------------------------- +//............................................................................ static void paintBits(uint8_t x, uint8_t y, uint8_t const *bits, uint8_t h) { uint32_t *fb = &l_fb[y][x >> 5]; uint32_t shft = (x & 0x1FU); @@ -646,7 +643,7 @@ static void paintBits(uint8_t x, uint8_t y, uint8_t const *bits, uint8_t h) { } } } -/*..........................................................................*/ +//............................................................................ static void paintBitsClear(uint8_t x, uint8_t y, uint8_t const *bits, uint8_t h) { @@ -666,193 +663,198 @@ static void paintBitsClear(uint8_t x, uint8_t y, } } -/* QF callbacks ============================================================*/ +// QF callbacks ============================================================ void QF_onStartup(void) { - /* set up the SysTick timer to fire at BSP_TICKS_PER_SEC rate */ + // set up the SysTick timer to fire at BSP_TICKS_PER_SEC rate SysTick_Config(SystemCoreClock / BSP_TICKS_PER_SEC); - /* assing all priority bits for preemption-prio. and none to sub-prio. */ + // assing all priority bits for preemption-prio. and none to sub-prio. NVIC_SetPriorityGrouping(0U); - /* set priorities of ALL ISRs used in the system, see NOTE1 - * - * !!!!!!!!!!!!!!!!!!!!!!!!!!!! CAUTION !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - * Assign a priority to EVERY ISR explicitly by calling NVIC_SetPriority(). - * DO NOT LEAVE THE ISR PRIORITIES AT THE DEFAULT VALUE! - */ - NVIC_SetPriority(USART0_RX_IRQn, 0U); /* kernel unaware interrupt */ + // set priorities of ALL ISRs used in the system, see NOTE1 + // + // !!!!!!!!!!!!!!!!!!!!!!!!!!!! CAUTION !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + // Assign a priority to EVERY ISR explicitly by calling NVIC_SetPriority(). + // DO NOT LEAVE THE ISR PRIORITIES AT THE DEFAULT VALUE! + // + NVIC_SetPriority(USART0_RX_IRQn, 0U); // kernel unaware interrupt NVIC_SetPriority(GPIO_EVEN_IRQn, QF_AWARE_ISR_CMSIS_PRI); NVIC_SetPriority(SysTick_IRQn, QF_AWARE_ISR_CMSIS_PRI + 1U); - /* ... */ + // ... - /* enable IRQs... */ + // enable IRQs... NVIC_EnableIRQ(GPIO_EVEN_IRQn); #ifdef Q_SPY - NVIC_EnableIRQ(USART0_RX_IRQn); /* UART0 interrupt used for QS-RX */ + NVIC_EnableIRQ(USART0_RX_IRQn); // UART0 interrupt used for QS-RX #endif } -/*..........................................................................*/ +//............................................................................ void QF_onCleanup(void) { } -/*..........................................................................*/ +//............................................................................ void QK_onIdle(void) { - /* toggle the User LED on and then off, see NOTE2 */ + // toggle the User LED on and then off, see NOTE2 QF_INT_DISABLE(); GPIO->P[LED_PORT].DOUT |= (1U << LED0_PIN); GPIO->P[LED_PORT].DOUT &= ~(1U << LED0_PIN); QF_INT_ENABLE(); #ifdef Q_SPY - QS_rxParse(); /* parse all the received bytes */ + QS_rxParse(); // parse all the received bytes - if ((l_USART0->STATUS & USART_STATUS_TXBL) != 0) { /* is TXE empty? */ + if ((l_USART0->STATUS & USART_STATUS_TXBL) != 0) { // is TXE empty? uint16_t b; QF_INT_DISABLE(); b = QS_getByte(); QF_INT_ENABLE(); - if (b != QS_EOD) { /* not End-Of-Data? */ - l_USART0->TXDATA = (b & 0xFFU); /* put into the DR register */ + if (b != QS_EOD) { // not End-Of-Data? + l_USART0->TXDATA = (b & 0xFFU); // put into the DR register } } #elif defined NDEBUG - /* Put the CPU and peripherals to the low-power mode. - * you might need to customize the clock management for your application, - * see the datasheet for your particular Cortex-M MCU. - */ - __WFI(); /* Wait-For-Interrupt */ + // Put the CPU and peripherals to the low-power mode. + // you might need to customize the clock management for your application, + // see the datasheet for your particular Cortex-M MCU. + // + __WFI(); // Wait-For-Interrupt #endif } -/*..........................................................................*/ -Q_NORETURN Q_onAssert(char const * const module, int_t const loc) { - /* - * NOTE: add here your application-specific error handling - */ - (void)module; - (void)loc; - QS_ASSERTION(module, loc, 10000U); /* report assertion to QS */ +//............................................................................ +Q_NORETURN Q_onError(char const * const module, int_t const id) { + // + // NOTE: add here your application-specific error handling + // + Q_UNUSED_PAR(module); + Q_UNUSED_PAR(id); + + QS_ASSERTION(module, id, 10000U); // report assertion to QS #ifndef NDEBUG - /* light up both LEDs */ + // light up both LEDs GPIO->P[LED_PORT].DOUT |= ((1U << LED0_PIN) | (1U << LED1_PIN)); - /* for debugging, hang on in an endless loop until PB1 is pressed... */ + // for debugging, hang on in an endless loop until PB1 is pressed... while ((GPIO->P[PB_PORT].DIN & (1U << PB1_PIN)) != 0) { } #endif NVIC_SystemReset(); } +//............................................................................ +void assert_failed(char const * const module, int_t const id); // prototype +void assert_failed(char const * const module, int_t const id) { + Q_onError(module, id); +} -/* QS callbacks ============================================================*/ +// QS callbacks ============================================================ #ifdef Q_SPY -/*..........................................................................*/ +//............................................................................ uint8_t QS_onStartup(void const *arg) { - static uint8_t qsTxBuf[2*1024]; /* buffer for QS transmit channel */ - static uint8_t qsRxBuf[100]; /* buffer for QS receive channel */ + static uint8_t qsTxBuf[2*1024]; // buffer for QS transmit channel + static uint8_t qsRxBuf[100]; // buffer for QS receive channel static USART_InitAsync_TypeDef init = { - usartEnable, /* Enable RX/TX when init completed */ - 0, /* Use current clock for configuring baudrate */ - 115200, /* 115200 bits/s */ - usartOVS16, /* 16x oversampling */ - usartDatabits8, /* 8 databits */ - usartNoParity, /* No parity */ - usartStopbits1, /* 1 stopbit */ - 0, /* Do not disable majority vote */ - 0, /* Not USART PRS input mode */ - usartPrsRxCh0, /* PRS channel 0 */ - 0, /* Auto CS functionality enable/disable switch */ - 0, /* Auto CS Hold cycles */ - 0 /* Auto CS Setup cycles */ + usartEnable, // Enable RX/TX when init completed + 0, // Use current clock for configuring baudrate + 115200, // 115200 bits/s + usartOVS16, // 16x oversampling + usartDatabits8, // 8 databits + usartNoParity, // No parity + usartStopbits1, // 1 stopbit + 0, // Do not disable majority vote + 0, // Not USART PRS input mode + usartPrsRxCh0, // PRS channel 0 + 0, // Auto CS functionality enable/disable switch + 0, // Auto CS Hold cycles + 0 // Auto CS Setup cycles }; QS_initBuf (qsTxBuf, sizeof(qsTxBuf)); QS_rxInitBuf(qsRxBuf, sizeof(qsRxBuf)); - /* Enable peripheral clocks */ + // Enable peripheral clocks CMU_ClockEnable(cmuClock_HFPER, true); CMU_ClockEnable(cmuClock_GPIO, true); - /* To avoid false start, configure output as high */ + // To avoid false start, configure output as high GPIO_PinModeSet(gpioPortA, 0, gpioModePushPull, 1); // TX pin GPIO_PinModeSet(gpioPortA, 1, gpioModeInput, 0); // RX pin - /* Enable DK RS232/UART switch */ + // Enable DK RS232/UART switch GPIO_PinModeSet(gpioPortA, 5, gpioModePushPull, 1); CMU_ClockEnable(cmuClock_USART0, true); - /* configure the UART for the desired baud rate, 8-N-1 operation */ + // configure the UART for the desired baud rate, 8-N-1 operation init.enable = usartDisable; USART_InitAsync(l_USART0, &init); - /* enable pins at correct UART/USART location. */ + // enable pins at correct UART/USART location. l_USART0->ROUTEPEN = USART_ROUTEPEN_RXPEN | USART_ROUTEPEN_TXPEN; l_USART0->ROUTELOC0 = (l_USART0->ROUTELOC0 & ~(_USART_ROUTELOC0_TXLOC_MASK | _USART_ROUTELOC0_RXLOC_MASK)); - /* Clear previous RX interrupts */ + // Clear previous RX interrupts USART_IntClear(l_USART0, USART_IF_RXDATAV); NVIC_ClearPendingIRQ(USART0_RX_IRQn); - /* Enable RX interrupts */ + // Enable RX interrupts USART_IntEnable(l_USART0, USART_IF_RXDATAV); - /* NOTE: do not enable the UART0 interrupt in the NVIC yet. - * Wait till QF_onStartup() - */ + // NOTE: do not enable the UART0 interrupt in the NVIC yet. + // Wait till QF_onStartup() + // - /* Finally enable the UART */ + // Finally enable the UART USART_Enable(l_USART0, usartEnable); QS_tickPeriod_ = SystemCoreClock / BSP_TICKS_PER_SEC; - QS_tickTime_ = QS_tickPeriod_; /* to start the timestamp at zero */ + QS_tickTime_ = QS_tickPeriod_; // to start the timestamp at zero - return 1U; /* return success */ + return 1U; // return success } -/*..........................................................................*/ +//............................................................................ void QS_onCleanup(void) { } -/*..........................................................................*/ -QSTimeCtr QS_onGetTime(void) { /* NOTE: invoked with interrupts DISABLED */ - if ((SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk) == 0) { /* not set? */ +//............................................................................ +QSTimeCtr QS_onGetTime(void) { // NOTE: invoked with interrupts DISABLED + if ((SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk) == 0) { // not set? return QS_tickTime_ - (QSTimeCtr)SysTick->VAL; } - else { /* the rollover occured, but the SysTick_ISR did not run yet */ + else { // the rollover occured, but the SysTick_ISR did not run yet return QS_tickTime_ + QS_tickPeriod_ - (QSTimeCtr)SysTick->VAL; } } -/*..........................................................................*/ +//............................................................................ void QS_onFlush(void) { uint16_t b; QF_INT_DISABLE(); - while ((b = QS_getByte()) != QS_EOD) { /* while not End-Of-Data... */ + while ((b = QS_getByte()) != QS_EOD) { // while not End-Of-Data... QF_INT_ENABLE(); - /* while TXE not empty */ + // while TXE not empty while ((l_USART0->STATUS & USART_STATUS_TXBL) == 0U) { } - l_USART0->TXDATA = (b & 0xFFU); /* put into the DR register */ + l_USART0->TXDATA = (b & 0xFFU); // put into the DR register QF_INT_DISABLE(); } QF_INT_ENABLE(); } -/*..........................................................................*/ -/*! callback function to reset the target (to be implemented in the BSP) */ +//............................................................................ +//! callback function to reset the target (to be implemented in the BSP) void QS_onReset(void) { NVIC_SystemReset(); } -/*..........................................................................*/ -/*! callback function to execute a user command (to be implemented in BSP) */ +//............................................................................ +//! callback function to execute a user command (to be implemented in BSP) void QS_onCommand(uint8_t cmdId, uint32_t param1, uint32_t param2, uint32_t param3) { - void assert_failed(char const *module, int loc); (void)cmdId; (void)param1; (void)param2; (void)param3; - QS_BEGIN_ID(COMMAND_STAT, 0U) /* app-specific record */ + QS_BEGIN_ID(COMMAND_STAT, 0U) // app-specific record QS_U8(2, cmdId); QS_U32(8, param1); QS_U32(8, param2); @@ -862,36 +864,33 @@ void QS_onCommand(uint8_t cmdId, if (cmdId == 10U) { Q_ERROR(); } - else if (cmdId == 11U) { - assert_failed("QS_onCommand", 123); - } } -#endif /* Q_SPY */ -/*--------------------------------------------------------------------------*/ +#endif // Q_SPY +//---------------------------------------------------------------------------- -/***************************************************************************** -* NOTE1: -* The QF_AWARE_ISR_CMSIS_PRI constant from the QF port specifies the highest -* ISR priority that is disabled by the QF framework. The value is suitable -* for the NVIC_SetPriority() CMSIS function. -* -* Only ISRs prioritized at or below the QF_AWARE_ISR_CMSIS_PRI level (i.e., -* with the numerical values of priorities equal or higher than -* QF_AWARE_ISR_CMSIS_PRI) are allowed to call the QK_ISR_ENTRY/QK_ISR_ENTRY -* macros or any other QF/QK services. These ISRs are "QF-aware". -* -* Conversely, any ISRs prioritized above the QF_AWARE_ISR_CMSIS_PRI priority -* level (i.e., with the numerical values of priorities less than -* QF_AWARE_ISR_CMSIS_PRI) are never disabled and are not aware of the kernel. -* Such "QF-unaware" ISRs cannot call any QF/QK services. In particular they -* can NOT call the macros QK_ISR_ENTRY/QK_ISR_ENTRY. The only mechanism -* by which a "QF-unaware" ISR can communicate with the QF framework is by -* triggering a "QF-aware" ISR, which can post/publish events. -* -* NOTE2: -* The User LED is used to visualize the idle loop activity. The brightness -* of the LED is proportional to the frequency of invcations of the idle loop. -* Please note that the LED is toggled with interrupts locked, so no interrupt -* execution time contributes to the brightness of the User LED. -*/ +//============================================================================ +// NOTE1: +// The QF_AWARE_ISR_CMSIS_PRI constant from the QF port specifies the highest +// ISR priority that is disabled by the QF framework. The value is suitable +// for the NVIC_SetPriority() CMSIS function. +// +// Only ISRs prioritized at or below the QF_AWARE_ISR_CMSIS_PRI level (i.e., +// with the numerical values of priorities equal or higher than +// QF_AWARE_ISR_CMSIS_PRI) are allowed to call the QK_ISR_ENTRY/QK_ISR_ENTRY +// macros or any other QF/QK services. These ISRs are "QF-aware". +// +// Conversely, any ISRs prioritized above the QF_AWARE_ISR_CMSIS_PRI priority +// level (i.e., with the numerical values of priorities less than +// QF_AWARE_ISR_CMSIS_PRI) are never disabled and are not aware of the kernel. +// Such "QF-unaware" ISRs cannot call any QF/QK services. In particular they +// can NOT call the macros QK_ISR_ENTRY/QK_ISR_ENTRY. The only mechanism +// by which a "QF-unaware" ISR can communicate with the QF framework is by +// triggering a "QF-aware" ISR, which can post/publish events. +// +// NOTE2: +// The User LED is used to visualize the idle loop activity. The brightness +// of the LED is proportional to the frequency of invcations of the idle loop. +// Please note that the LED is toggled with interrupts locked, so no interrupt +// execution time contributes to the brightness of the User LED. +// diff --git a/examples/arm-cm/game_efm32-slstk3401a/qk/gnu/Makefile b/examples/arm-cm/game_efm32-slstk3401a/qk/gnu/Makefile index 03824449..a443198c 100644 --- a/examples/arm-cm/game_efm32-slstk3401a/qk/gnu/Makefile +++ b/examples/arm-cm/game_efm32-slstk3401a/qk/gnu/Makefile @@ -275,7 +275,7 @@ $(TARGET_BIN): $(TARGET_ELF) $(BIN) -O binary $< $@ $(TARGET_ELF) : $(ASM_OBJS_EXT) $(C_OBJS_EXT) $(CPP_OBJS_EXT) - $(CC) $(CFLAGS) $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o + $(CC) $(CFLAGS) $(QPC)/src/qs/qstamp.c -o $(BIN_DIR)/qstamp.o $(LINK) $(LINKFLAGS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) $(BIN_DIR)/%.d : %.c diff --git a/examples/arm-cm/game_efm32-slstk3401a/qk/iar/game-qk.ewd b/examples/arm-cm/game_efm32-slstk3401a/qk/iar/game-qk.ewd index 99524260..1b080fb1 100644 --- a/examples/arm-cm/game_efm32-slstk3401a/qk/iar/game-qk.ewd +++ b/examples/arm-cm/game_efm32-slstk3401a/qk/iar/game-qk.ewd @@ -88,7 +88,7 @@
@@ -1292,7 +1300,7 @@ XDS100_ID 2 - 8 + 9 1 1 + @@ -1513,6 +1525,18 @@ $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin 0
+ + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-286-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-III\uCOS-III-KA-CSpy.ewplugin + 0 + $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin 0 @@ -2598,7 +2622,7 @@ STLINK_ID 2 - 7 + 8 1 0 + + @@ -2818,7 +2850,7 @@ XDS100_ID 2 - 8 + 9 1 0 + @@ -3039,6 +3075,18 @@ $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin 0 + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-286-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-III\uCOS-III-KA-CSpy.ewplugin + 0 + $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin 0 @@ -4124,7 +4172,7 @@ STLINK_ID 2 - 7 + 8 1 1 + + @@ -4344,7 +4400,7 @@ XDS100_ID 2 - 8 + 9 1 1 + @@ -4565,6 +4625,18 @@ $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin 0 + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-286-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-III\uCOS-III-KA-CSpy.ewplugin + 0 + $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin 0 diff --git a/examples/arm-cm/game_efm32-slstk3401a/qk/iar/game-qk.ewp b/examples/arm-cm/game_efm32-slstk3401a/qk/iar/game-qk.ewp index c08ff410..f6e35d49 100644 --- a/examples/arm-cm/game_efm32-slstk3401a/qk/iar/game-qk.ewp +++ b/examples/arm-cm/game_efm32-slstk3401a/qk/iar/game-qk.ewp @@ -11,12 +11,12 @@ General 3 - 33 + 35 1 1 + + + @@ -672,7 +684,7 @@ ILINK 0 - 25 + 27 1 1 + + + + @@ -1063,12 +1091,12 @@ General 3 - 33 + 35 1 0 + + + @@ -1725,7 +1765,7 @@ ILINK 0 - 25 + 27 1 0 + + + + @@ -2116,12 +2172,12 @@ General 3 - 33 + 35 1 1 + + + @@ -2778,7 +2846,7 @@ ILINK 0 - 25 + 27 1 1 + + + + @@ -3183,7 +3267,7 @@ $PROJ_DIR$\..\..\missile.c - $PROJ_DIR$\..\..\..\..\..\include\qstamp.c + $PROJ_DIR$\..\..\..\..\..\src\qs\qstamp.c $PROJ_DIR$\..\..\ship.c diff --git a/examples/arm-cm/game_efm32-slstk3401a/qv/armclang/game-qv.uvoptx b/examples/arm-cm/game_efm32-slstk3401a/qv/armclang/game-qv.uvoptx index e8de80f9..db82948c 100644 --- a/examples/arm-cm/game_efm32-slstk3401a/qv/armclang/game-qv.uvoptx +++ b/examples/arm-cm/game_efm32-slstk3401a/qv/armclang/game-qv.uvoptx @@ -636,7 +636,7 @@ 0 0 0 - ..\..\..\..\..\include\qstamp.c + ..\..\..\..\..\src\qs\qstamp.c qstamp.c 0 0 @@ -923,7 +923,7 @@ 3 - 26 + 16 1 0 0 diff --git a/examples/arm-cm/game_efm32-slstk3401a/qv/armclang/game-qv.uvprojx b/examples/arm-cm/game_efm32-slstk3401a/qv/armclang/game-qv.uvprojx index aa517ecc..1b511564 100644 --- a/examples/arm-cm/game_efm32-slstk3401a/qv/armclang/game-qv.uvprojx +++ b/examples/arm-cm/game_efm32-slstk3401a/qv/armclang/game-qv.uvprojx @@ -336,7 +336,7 @@ 0 - EFM32PG1B200F256GM48=1 __FPU_PRESENT + EFM32PG1B200F256GM48=1 ..\..;..\..\..\..\..\include;..\..\..\..\..\ports\arm-cm\qv\armclang;..\..\..\..\..\3rd_party\CMSIS\Include;..\..\..\..\..\3rd_party\efm32pg1b @@ -395,7 +395,7 @@ qstamp.c 1 - ..\..\..\..\..\include\qstamp.c + ..\..\..\..\..\src\qs\qstamp.c bsp.h @@ -1010,7 +1010,7 @@ 0 - NDEBUG EFM32PG1B200F256GM48=1 __FPU_PRESENT + NDEBUG EFM32PG1B200F256GM48=1 ..\..;..\..\..\..\..\include;..\..\..\..\..\ports\arm-cm\qv\armclang;..\..\..\..\..\3rd_party\CMSIS\Include;..\..\..\..\..\3rd_party\efm32pg1b @@ -1069,7 +1069,7 @@ qstamp.c 1 - ..\..\..\..\..\include\qstamp.c + ..\..\..\..\..\src\qs\qstamp.c bsp.h @@ -1684,7 +1684,7 @@ 0 - Q_SPY EFM32PG1B200F256GM48=1 __FPU_PRESENT + Q_SPY EFM32PG1B200F256GM48=1 ..\..;..\..\..\..\..\include;..\..\..\..\..\ports\arm-cm\qv\armclang;..\..\..\..\..\3rd_party\CMSIS\Include;..\..\..\..\..\3rd_party\efm32pg1b @@ -1743,7 +1743,7 @@ qstamp.c 1 - ..\..\..\..\..\include\qstamp.c + ..\..\..\..\..\src\qs\qstamp.c bsp.h diff --git a/examples/arm-cm/game_efm32-slstk3401a/qv/bsp.c b/examples/arm-cm/game_efm32-slstk3401a/qv/bsp.c index 444d65e8..f940fc2a 100644 --- a/examples/arm-cm/game_efm32-slstk3401a/qv/bsp.c +++ b/examples/arm-cm/game_efm32-slstk3401a/qv/bsp.c @@ -1,56 +1,56 @@ -/***************************************************************************** -* Product: "Fly 'n' Shoot" game example, EFM32-SLSTK3401A board, QV kernel -* Last updated for version 6.9.3 -* Last updated on 2021-03-03 -* -* Q u a n t u m L e a P s -* ------------------------ -* Modern Embedded Software -* -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* -* -*****************************************************************************/ +//============================================================================ +// Product: "Fly 'n' Shoot" game example, EFM32-SLSTK3401A board, QV kernel +// Last updated for version 7.3.0 +// Last updated on 2023-07-27 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// This program is open source software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Alternatively, this program may be distributed and modified under the +// terms of Quantum Leaps commercial licenses, which expressly supersede +// the GNU General Public License and are specifically designed for +// licensees interested in retaining the proprietary status of their code. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Contact information: +// +// +//============================================================================ #include "qpc.h" #include "game.h" #include "bsp.h" -#include "em_device.h" /* the device specific header (SiLabs) */ -#include "em_chip.h" /* Chip errata (SiLabs) */ -#include "em_cmu.h" /* Clock Management Unit (SiLabs) */ -#include "em_gpio.h" /* GPIO (SiLabs) */ -#include "em_usart.h" /* USART (SiLabs) */ -#include "display_ls013b7dh03.h" /* LS013b7DH03 display (SiLabs/QL) */ -/* add other drivers if necessary... */ +#include "em_device.h" // the device specific header (SiLabs) +#include "em_chip.h" // Chip errata (SiLabs) +#include "em_cmu.h" // Clock Management Unit (SiLabs) +#include "em_gpio.h" // GPIO (SiLabs) +#include "em_usart.h" // USART (SiLabs) +#include "display_ls013b7dh03.h" // LS013b7DH03 display (SiLabs/QL) +// add other drivers if necessary... Q_DEFINE_THIS_FILE -/* ISRs defined in this BSP ------------------------------------------------*/ +// ISRs defined in this BSP ------------------------------------------------ void SysTick_Handler(void); void GPIO_EVEN_IRQHandler(void); void USART0_RX_IRQHandler(void); -/* Local-scope objects -----------------------------------------------------*/ +// Local-scope objects ----------------------------------------------------- #define LED_PORT gpioPortF #define LED0_PIN 4 #define LED1_PIN 5 @@ -59,13 +59,14 @@ void USART0_RX_IRQHandler(void); #define PB0_PIN 6 #define PB1_PIN 7 -/* LCD geometry and frame buffer */ +// LCD geometry and frame buffer static uint32_t l_fb[BSP_SCREEN_HEIGHT + 1][BSP_SCREEN_WIDTH / 32U]; -/* the walls buffer */ +// the walls buffer static uint32_t l_walls[GAME_TUNNEL_HEIGHT + 1][BSP_SCREEN_WIDTH / 32U]; -static unsigned l_rnd; /* random seed */ +static unsigned l_rnd; // random seed + static void paintBits(uint8_t x, uint8_t y, uint8_t const *bits, uint8_t h); static void paintBitsClear(uint8_t x, uint8_t y, uint8_t const *bits, uint8_t h); @@ -73,38 +74,39 @@ static void paintBitsClear(uint8_t x, uint8_t y, QSTimeCtr QS_tickTime_; QSTimeCtr QS_tickPeriod_; - /* QSpy source IDs */ + // QSpy source IDs static QSpyId const l_SysTick_Handler = { 0U }; static QSpyId const l_GPIO_EVEN_IRQHandler = { 0U }; static USART_TypeDef * const l_USART0 = ((USART_TypeDef *)(0x40010000UL)); - enum AppRecords { /* application-specific trace records */ + enum AppRecords { // application-specific trace records SCORE_STAT = QS_USER, COMMAND_STAT }; #endif -/* ISRs used in the application ==========================================*/ +// ISRs used in the application ========================================== void SysTick_Handler(void) { - static QEvt const tickEvt = { TIME_TICK_SIG, 0U, 0U }; + static QEvt const tickEvt = QEVT_INITIALIZER(TIME_TICK_SIG); #ifdef Q_SPY { - /* clear SysTick_CTRL_COUNTFLAG */ + // clear SysTick_CTRL_COUNTFLAG uint32_t volatile tmp = SysTick->CTRL; - (void)tmp; /* avoid compiler warning about unused local variable */ - QS_tickTime_ += QS_tickPeriod_; /* account for the clock rollover */ + (void)tmp; // avoid compiler warning about unused local variable + QS_tickTime_ += QS_tickPeriod_; // account for the clock rollover } #endif - //QTIMEEVT_TICK_X(0U, &l_SysTick_Handler); /* process time events for rate 0 */ - QACTIVE_POST(the_Ticker0, 0, 0); /* post a don't-care event to Ticker0 */ - QACTIVE_PUBLISH(&tickEvt, &l_SysTick_Handler); /* publish to all subscribers */ + //QTIMEEVT_TICK_X(0U, &l_SysTick_Handler); // process time events for rate 0 + QTICKER_TRIG(the_Ticker0, &l_SysTick_Handler); // trigger ticker AO + + QACTIVE_PUBLISH(&tickEvt, &l_SysTick_Handler); // publish to all subscribers { - /* state of the button debouncing, see below */ + // state of the button debouncing, see below static struct ButtonsDebouncing { uint32_t depressed; uint32_t previous; @@ -112,40 +114,40 @@ void SysTick_Handler(void) { uint32_t current; uint32_t tmp; - /* Perform the debouncing of buttons. The algorithm for debouncing - * adapted from the book "Embedded Systems Dictionary" by Jack Ganssle - * and Michael Barr, page 71. - */ - current = ~GPIO->P[PB_PORT].DIN; /* read PB0 and BP1 */ - tmp = buttons.depressed; /* save the debounced depressed buttons */ - buttons.depressed |= (buttons.previous & current); /* set depressed */ - buttons.depressed &= (buttons.previous | current); /* clear released */ - buttons.previous = current; /* update the history */ - tmp ^= buttons.depressed; /* changed debounced depressed */ - if ((tmp & (1U << PB0_PIN)) != 0U) { /* debounced PB0 state changed? */ - if ((buttons.depressed & (1U << PB0_PIN)) != 0U) {/*PB0 depressed?*/ - static QEvt const trigEvt = { PLAYER_TRIGGER_SIG, 0U, 0U}; + // Perform the debouncing of buttons. The algorithm for debouncing + // adapted from the book "Embedded Systems Dictionary" by Jack Ganssle + // and Michael Barr, page 71. + // + current = ~GPIO->P[PB_PORT].DIN; // read PB0 and BP1 + tmp = buttons.depressed; // save the debounced depressed buttons + buttons.depressed |= (buttons.previous & current); // set depressed + buttons.depressed &= (buttons.previous | current); // clear released + buttons.previous = current; // update the history + tmp ^= buttons.depressed; // changed debounced depressed + if ((tmp & (1U << PB0_PIN)) != 0U) { // debounced PB0 state changed? + if ((buttons.depressed & (1U << PB0_PIN)) != 0U) {//PB0 depressed? + static QEvt const trigEvt = QEVT_INITIALIZER(PLAYER_TRIGGER_SIG); QACTIVE_PUBLISH(&trigEvt, &l_SysTick_Handler); } } } QV_ARM_ERRATUM_838869(); } -/*..........................................................................*/ +//............................................................................ void GPIO_EVEN_IRQHandler(void) { - QACTIVE_POST(AO_Tunnel, Q_NEW(QEvt, MAX_PUB_SIG), /* for testing... */ + QACTIVE_POST(AO_Tunnel, Q_NEW(QEvt, MAX_PUB_SIG), // for testing... &l_GPIO_EVEN_IRQHandler); } -/*..........................................................................*/ +//............................................................................ void USART0_RX_IRQHandler(void); // prototype #ifdef Q_SPY -/* ISR for receiving bytes from the QSPY Back-End -* NOTE: This ISR is "QF-unaware" meaning that it does not interact with -* the QF/QK and is not disabled. Such ISRs don't need to call QK_ISR_ENTRY/ -* QK_ISR_EXIT and they cannot post or publish events. -*/ +// ISR for receiving bytes from the QSPY Back-End +// NOTE: This ISR is "QF-unaware" meaning that it does not interact with +// the QF/QK and is not disabled. Such ISRs don't need to call QK_ISR_ENTRY/ +// QK_ISR_EXIT and they cannot post or publish events. +// void USART0_RX_IRQHandler(void) { - /* while RX FIFO NOT empty */ + // while RX FIFO NOT empty while ((l_USART0->STATUS & USART_STATUS_RXDATAV) != 0) { uint32_t b = l_USART0->RXDATA; QS_RX_PUT(b); @@ -154,43 +156,43 @@ void USART0_RX_IRQHandler(void) { } #else void USART0_RX_IRQHandler(void) {} -#endif /* Q_SPY */ +#endif // Q_SPY -/* BSP functions ===========================================================*/ +// BSP functions =========================================================== void BSP_init(void) { - /* Chip errata */ + // Chip errata CHIP_Init(); - /* NOTE: SystemInit() already called from startup_TM4C123GH6PM.s - * but SystemCoreClock needs to be updated - */ + // NOTE: SystemInit() already called from startup_TM4C123GH6PM.s + // but SystemCoreClock needs to be updated + // SystemCoreClockUpdate(); - /* NOTE The VFP (Floating Point Unit) unit is configured by QV-port */ + // NOTE The VFP (Floating Point Unit) unit is configured by QV-port - /* enable clock for to the peripherals used by this application... */ + // enable clock for to the peripherals used by this application... CMU_ClockEnable(cmuClock_HFPER, true); CMU_ClockEnable(cmuClock_GPIO, true); CMU_ClockEnable(cmuClock_HFPER, true); CMU_ClockEnable(cmuClock_GPIO, true); - /* configure the LEDs */ + // configure the LEDs GPIO_PinModeSet(LED_PORT, LED0_PIN, gpioModePushPull, 0); GPIO_PinModeSet(LED_PORT, LED1_PIN, gpioModePushPull, 0); GPIO_PinOutClear(LED_PORT, LED0_PIN); GPIO_PinOutClear(LED_PORT, LED1_PIN); - /* configure the Buttons */ + // configure the Buttons GPIO_PinModeSet(PB_PORT, PB0_PIN, gpioModeInputPull, 1); GPIO_PinModeSet(PB_PORT, PB1_PIN, gpioModeInputPull, 1); - /* Initialize the DISPLAY driver. */ + // Initialize the DISPLAY driver. if (!Display_init()) { Q_ERROR(); } - /* initialize the QS software tracing */ + // initialize the QS software tracing if (QS_INIT((void *)0) == 0U) { Q_ERROR(); } @@ -200,19 +202,19 @@ void BSP_init(void) { QS_USR_DICTIONARY(SCORE_STAT); QS_USR_DICTIONARY(COMMAND_STAT); - /* setup the QS filters... */ - QS_GLB_FILTER(QS_SM_RECORDS); /* state machine records */ - QS_GLB_FILTER(QS_AO_RECORDS); /* active object records */ - QS_GLB_FILTER(QS_UA_RECORDS); /* all user records */ + // setup the QS filters... + QS_GLB_FILTER(QS_SM_RECORDS); // state machine records + QS_GLB_FILTER(QS_AO_RECORDS); // active object records + QS_GLB_FILTER(QS_UA_RECORDS); // all user records } -/*..........................................................................*/ +//............................................................................ void BSP_updateScreen(void) { GPIO->P[LED_PORT].DOUT |= (1U << LED1_PIN); Display_sendPA(&l_fb[0][0], 0, LS013B7DH03_HEIGHT); GPIO->P[LED_PORT].DOUT &= ~(1U << LED1_PIN); } -/*..........................................................................*/ +//............................................................................ void BSP_clearFB() { uint_fast8_t y; for (y = 0U; y < BSP_SCREEN_HEIGHT; ++y) { @@ -222,7 +224,7 @@ void BSP_clearFB() { l_fb[y][3] = 0U; } } -/*..........................................................................*/ +//............................................................................ void BSP_clearWalls() { uint_fast8_t y; for (y = 0U; y < GAME_TUNNEL_HEIGHT; ++y) { @@ -232,108 +234,108 @@ void BSP_clearWalls() { l_walls[y][3] = 0U; } } -/*..........................................................................*/ -bool BSP_isThrottle(void) { /* is the throttle button depressed? */ +//............................................................................ +bool BSP_isThrottle(void) { // is the throttle button depressed? return (GPIO->P[PB_PORT].DIN & (1U << PB1_PIN)) == 0U; } -/*..........................................................................*/ +//............................................................................ void BSP_paintString(uint8_t x, uint8_t y, char const *str) { static uint8_t const font5x7[95][7] = { - { 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U }, /* */ - { 0x04U, 0x04U, 0x04U, 0x04U, 0x00U, 0x00U, 0x04U }, /* ! */ - { 0x0AU, 0x0AU, 0x0AU, 0x00U, 0x00U, 0x00U, 0x00U }, /* " */ - { 0x0AU, 0x0AU, 0x1FU, 0x0AU, 0x1FU, 0x0AU, 0x0AU }, /* # */ - { 0x04U, 0x1EU, 0x05U, 0x0EU, 0x14U, 0x0FU, 0x04U }, /* $ */ - { 0x03U, 0x13U, 0x08U, 0x04U, 0x02U, 0x19U, 0x18U }, /* % */ - { 0x06U, 0x09U, 0x05U, 0x02U, 0x15U, 0x09U, 0x16U }, /* & */ - { 0x06U, 0x04U, 0x02U, 0x00U, 0x00U, 0x00U, 0x00U }, /* ' */ - { 0x08U, 0x04U, 0x02U, 0x02U, 0x02U, 0x04U, 0x08U }, /* ( */ - { 0x02U, 0x04U, 0x08U, 0x08U, 0x08U, 0x04U, 0x02U }, /* ) */ - { 0x00U, 0x04U, 0x15U, 0x0EU, 0x15U, 0x04U, 0x00U }, /* * */ - { 0x00U, 0x04U, 0x04U, 0x1FU, 0x04U, 0x04U, 0x00U }, /* + */ - { 0x00U, 0x00U, 0x00U, 0x00U, 0x06U, 0x04U, 0x02U }, /* , */ - { 0x00U, 0x00U, 0x00U, 0x1FU, 0x00U, 0x00U, 0x00U }, /* - */ - { 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x06U, 0x06U }, /* . */ - { 0x00U, 0x10U, 0x08U, 0x04U, 0x02U, 0x01U, 0x00U }, /* / */ - { 0x0EU, 0x11U, 0x19U, 0x15U, 0x13U, 0x11U, 0x0EU }, /* 0 */ - { 0x04U, 0x06U, 0x04U, 0x04U, 0x04U, 0x04U, 0x0EU }, /* 1 */ - { 0x0EU, 0x11U, 0x10U, 0x08U, 0x04U, 0x02U, 0x1FU }, /* 2 */ - { 0x1FU, 0x08U, 0x04U, 0x08U, 0x10U, 0x11U, 0x0EU }, /* 3 */ - { 0x08U, 0x0CU, 0x0AU, 0x09U, 0x1FU, 0x08U, 0x08U }, /* 4 */ - { 0x1FU, 0x01U, 0x0FU, 0x10U, 0x10U, 0x11U, 0x0EU }, /* 5 */ - { 0x0CU, 0x02U, 0x01U, 0x0FU, 0x11U, 0x11U, 0x0EU }, /* 6 */ - { 0x1FU, 0x10U, 0x08U, 0x04U, 0x02U, 0x02U, 0x02U }, /* 7 */ - { 0x0EU, 0x11U, 0x11U, 0x0EU, 0x11U, 0x11U, 0x0EU }, /* 8 */ - { 0x0EU, 0x11U, 0x11U, 0x1EU, 0x10U, 0x08U, 0x06U }, /* 9 */ - { 0x00U, 0x06U, 0x06U, 0x00U, 0x06U, 0x06U, 0x00U }, /* : */ - { 0x00U, 0x06U, 0x06U, 0x00U, 0x06U, 0x04U, 0x02U }, /* ; */ - { 0x08U, 0x04U, 0x02U, 0x01U, 0x02U, 0x04U, 0x08U }, /* < */ - { 0x00U, 0x00U, 0x1FU, 0x00U, 0x1FU, 0x00U, 0x00U }, /* = */ - { 0x02U, 0x04U, 0x08U, 0x10U, 0x08U, 0x04U, 0x02U }, /* > */ - { 0x0EU, 0x11U, 0x10U, 0x08U, 0x04U, 0x00U, 0x04U }, /* ? */ - { 0x0EU, 0x11U, 0x10U, 0x16U, 0x15U, 0x15U, 0x0EU }, /* @ */ - { 0x0EU, 0x11U, 0x11U, 0x11U, 0x1FU, 0x11U, 0x11U }, /* A */ - { 0x0FU, 0x11U, 0x11U, 0x0FU, 0x11U, 0x11U, 0x0FU }, /* B */ - { 0x0EU, 0x11U, 0x01U, 0x01U, 0x01U, 0x11U, 0x0EU }, /* C */ - { 0x07U, 0x09U, 0x11U, 0x11U, 0x11U, 0x09U, 0x07U }, /* D */ - { 0x1FU, 0x01U, 0x01U, 0x0FU, 0x01U, 0x01U, 0x1FU }, /* E */ - { 0x1FU, 0x01U, 0x01U, 0x0FU, 0x01U, 0x01U, 0x01U }, /* F */ - { 0x0EU, 0x11U, 0x01U, 0x1DU, 0x11U, 0x11U, 0x1EU }, /* G */ - { 0x11U, 0x11U, 0x11U, 0x1FU, 0x11U, 0x11U, 0x11U }, /* H */ - { 0x0EU, 0x04U, 0x04U, 0x04U, 0x04U, 0x04U, 0x0EU }, /* I */ - { 0x1CU, 0x08U, 0x08U, 0x08U, 0x08U, 0x09U, 0x06U }, /* J */ - { 0x11U, 0x09U, 0x05U, 0x03U, 0x05U, 0x09U, 0x11U }, /* K */ - { 0x01U, 0x01U, 0x01U, 0x01U, 0x01U, 0x01U, 0x1FU }, /* L */ - { 0x11U, 0x1BU, 0x15U, 0x15U, 0x11U, 0x11U, 0x11U }, /* M */ - { 0x11U, 0x11U, 0x13U, 0x15U, 0x19U, 0x11U, 0x11U }, /* N */ - { 0x0EU, 0x11U, 0x11U, 0x11U, 0x11U, 0x11U, 0x0EU }, /* O */ - { 0x0FU, 0x11U, 0x11U, 0x0FU, 0x01U, 0x01U, 0x01U }, /* P */ - { 0x0EU, 0x11U, 0x11U, 0x11U, 0x15U, 0x09U, 0x16U }, /* Q */ - { 0x0FU, 0x11U, 0x11U, 0x0FU, 0x05U, 0x09U, 0x11U }, /* R */ - { 0x1EU, 0x01U, 0x01U, 0x0EU, 0x10U, 0x10U, 0x0FU }, /* S */ - { 0x1FU, 0x04U, 0x04U, 0x04U, 0x04U, 0x04U, 0x04U }, /* T */ - { 0x11U, 0x11U, 0x11U, 0x11U, 0x11U, 0x11U, 0x0EU }, /* U */ - { 0x11U, 0x11U, 0x11U, 0x11U, 0x11U, 0x0AU, 0x04U }, /* V */ - { 0x11U, 0x11U, 0x11U, 0x15U, 0x15U, 0x15U, 0x0AU }, /* W */ - { 0x11U, 0x11U, 0x0AU, 0x04U, 0x0AU, 0x11U, 0x11U }, /* X */ - { 0x11U, 0x11U, 0x11U, 0x0AU, 0x04U, 0x04U, 0x04U }, /* Y */ - { 0x1FU, 0x10U, 0x08U, 0x04U, 0x02U, 0x01U, 0x1FU }, /* Z */ - { 0x0EU, 0x02U, 0x02U, 0x02U, 0x02U, 0x02U, 0x0EU }, /* [ */ - { 0x00U, 0x01U, 0x02U, 0x04U, 0x08U, 0x10U, 0x00U }, /* \ */ - { 0x0EU, 0x08U, 0x08U, 0x08U, 0x08U, 0x08U, 0x0EU }, /* ] */ - { 0x04U, 0x0AU, 0x11U, 0x00U, 0x00U, 0x00U, 0x00U }, /* ^ */ - { 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x1FU }, /* _ */ - { 0x02U, 0x04U, 0x08U, 0x00U, 0x00U, 0x00U, 0x00U }, /* ` */ - { 0x00U, 0x00U, 0x0EU, 0x10U, 0x1EU, 0x11U, 0x1EU }, /* a */ - { 0x01U, 0x01U, 0x0DU, 0x13U, 0x11U, 0x11U, 0x0FU }, /* b */ - { 0x00U, 0x00U, 0x0EU, 0x01U, 0x01U, 0x11U, 0x0EU }, /* c */ - { 0x10U, 0x10U, 0x16U, 0x19U, 0x11U, 0x11U, 0x1EU }, /* d */ - { 0x00U, 0x00U, 0x0EU, 0x11U, 0x1FU, 0x01U, 0x0EU }, /* e */ - { 0x0CU, 0x12U, 0x02U, 0x07U, 0x02U, 0x02U, 0x02U }, /* f */ - { 0x00U, 0x1EU, 0x11U, 0x11U, 0x1EU, 0x10U, 0x0EU }, /* g */ - { 0x01U, 0x01U, 0x0DU, 0x13U, 0x11U, 0x11U, 0x11U }, /* h */ - { 0x04U, 0x00U, 0x06U, 0x04U, 0x04U, 0x04U, 0x0EU }, /* i */ - { 0x08U, 0x00U, 0x0CU, 0x08U, 0x08U, 0x09U, 0x06U }, /* j */ - { 0x01U, 0x01U, 0x09U, 0x05U, 0x03U, 0x05U, 0x09U }, /* k */ - { 0x06U, 0x04U, 0x04U, 0x04U, 0x04U, 0x04U, 0x0EU }, /* l */ - { 0x00U, 0x00U, 0x0BU, 0x15U, 0x15U, 0x11U, 0x11U }, /* m */ - { 0x00U, 0x00U, 0x0DU, 0x13U, 0x11U, 0x11U, 0x11U }, /* n */ - { 0x00U, 0x00U, 0x0EU, 0x11U, 0x11U, 0x11U, 0x0EU }, /* o */ - { 0x00U, 0x00U, 0x0FU, 0x11U, 0x0FU, 0x01U, 0x01U }, /* p */ - { 0x00U, 0x00U, 0x16U, 0x19U, 0x1EU, 0x10U, 0x10U }, /* q */ - { 0x00U, 0x00U, 0x0DU, 0x13U, 0x01U, 0x01U, 0x01U }, /* r */ - { 0x00U, 0x00U, 0x0EU, 0x01U, 0x0EU, 0x10U, 0x0FU }, /* s */ - { 0x02U, 0x02U, 0x07U, 0x02U, 0x02U, 0x12U, 0x0CU }, /* t */ - { 0x00U, 0x00U, 0x11U, 0x11U, 0x11U, 0x19U, 0x16U }, /* u */ - { 0x00U, 0x00U, 0x11U, 0x11U, 0x11U, 0x0AU, 0x04U }, /* v */ - { 0x00U, 0x00U, 0x11U, 0x11U, 0x15U, 0x15U, 0x0AU }, /* w */ - { 0x00U, 0x00U, 0x11U, 0x0AU, 0x04U, 0x0AU, 0x11U }, /* x */ - { 0x00U, 0x00U, 0x11U, 0x11U, 0x1EU, 0x10U, 0x0EU }, /* y */ - { 0x00U, 0x00U, 0x1FU, 0x08U, 0x04U, 0x02U, 0x1FU }, /* z */ - { 0x08U, 0x04U, 0x04U, 0x02U, 0x04U, 0x04U, 0x08U }, /* { */ - { 0x04U, 0x04U, 0x04U, 0x04U, 0x04U, 0x04U, 0x04U }, /* | */ - { 0x02U, 0x04U, 0x04U, 0x08U, 0x04U, 0x04U, 0x02U }, /* } */ - { 0x02U, 0x15U, 0x08U, 0x00U, 0x00U, 0x00U, 0x00U }, /* ~ */ + { 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U }, // + { 0x04U, 0x04U, 0x04U, 0x04U, 0x00U, 0x00U, 0x04U }, // ! + { 0x0AU, 0x0AU, 0x0AU, 0x00U, 0x00U, 0x00U, 0x00U }, // " + { 0x0AU, 0x0AU, 0x1FU, 0x0AU, 0x1FU, 0x0AU, 0x0AU }, // # + { 0x04U, 0x1EU, 0x05U, 0x0EU, 0x14U, 0x0FU, 0x04U }, // $ + { 0x03U, 0x13U, 0x08U, 0x04U, 0x02U, 0x19U, 0x18U }, // % + { 0x06U, 0x09U, 0x05U, 0x02U, 0x15U, 0x09U, 0x16U }, // & + { 0x06U, 0x04U, 0x02U, 0x00U, 0x00U, 0x00U, 0x00U }, // ' + { 0x08U, 0x04U, 0x02U, 0x02U, 0x02U, 0x04U, 0x08U }, // ( + { 0x02U, 0x04U, 0x08U, 0x08U, 0x08U, 0x04U, 0x02U }, // ) + { 0x00U, 0x04U, 0x15U, 0x0EU, 0x15U, 0x04U, 0x00U }, // * + { 0x00U, 0x04U, 0x04U, 0x1FU, 0x04U, 0x04U, 0x00U }, // + + { 0x00U, 0x00U, 0x00U, 0x00U, 0x06U, 0x04U, 0x02U }, // , + { 0x00U, 0x00U, 0x00U, 0x1FU, 0x00U, 0x00U, 0x00U }, // - + { 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x06U, 0x06U }, // . + { 0x00U, 0x10U, 0x08U, 0x04U, 0x02U, 0x01U, 0x00U }, // / + { 0x0EU, 0x11U, 0x19U, 0x15U, 0x13U, 0x11U, 0x0EU }, // 0 + { 0x04U, 0x06U, 0x04U, 0x04U, 0x04U, 0x04U, 0x0EU }, // 1 + { 0x0EU, 0x11U, 0x10U, 0x08U, 0x04U, 0x02U, 0x1FU }, // 2 + { 0x1FU, 0x08U, 0x04U, 0x08U, 0x10U, 0x11U, 0x0EU }, // 3 + { 0x08U, 0x0CU, 0x0AU, 0x09U, 0x1FU, 0x08U, 0x08U }, // 4 + { 0x1FU, 0x01U, 0x0FU, 0x10U, 0x10U, 0x11U, 0x0EU }, // 5 + { 0x0CU, 0x02U, 0x01U, 0x0FU, 0x11U, 0x11U, 0x0EU }, // 6 + { 0x1FU, 0x10U, 0x08U, 0x04U, 0x02U, 0x02U, 0x02U }, // 7 + { 0x0EU, 0x11U, 0x11U, 0x0EU, 0x11U, 0x11U, 0x0EU }, // 8 + { 0x0EU, 0x11U, 0x11U, 0x1EU, 0x10U, 0x08U, 0x06U }, // 9 + { 0x00U, 0x06U, 0x06U, 0x00U, 0x06U, 0x06U, 0x00U }, // : + { 0x00U, 0x06U, 0x06U, 0x00U, 0x06U, 0x04U, 0x02U }, // ; + { 0x08U, 0x04U, 0x02U, 0x01U, 0x02U, 0x04U, 0x08U }, // < + { 0x00U, 0x00U, 0x1FU, 0x00U, 0x1FU, 0x00U, 0x00U }, // = + { 0x02U, 0x04U, 0x08U, 0x10U, 0x08U, 0x04U, 0x02U }, // > + { 0x0EU, 0x11U, 0x10U, 0x08U, 0x04U, 0x00U, 0x04U }, // ? + { 0x0EU, 0x11U, 0x10U, 0x16U, 0x15U, 0x15U, 0x0EU }, // @ + { 0x0EU, 0x11U, 0x11U, 0x11U, 0x1FU, 0x11U, 0x11U }, // A + { 0x0FU, 0x11U, 0x11U, 0x0FU, 0x11U, 0x11U, 0x0FU }, // B + { 0x0EU, 0x11U, 0x01U, 0x01U, 0x01U, 0x11U, 0x0EU }, // C + { 0x07U, 0x09U, 0x11U, 0x11U, 0x11U, 0x09U, 0x07U }, // D + { 0x1FU, 0x01U, 0x01U, 0x0FU, 0x01U, 0x01U, 0x1FU }, // E + { 0x1FU, 0x01U, 0x01U, 0x0FU, 0x01U, 0x01U, 0x01U }, // F + { 0x0EU, 0x11U, 0x01U, 0x1DU, 0x11U, 0x11U, 0x1EU }, // G + { 0x11U, 0x11U, 0x11U, 0x1FU, 0x11U, 0x11U, 0x11U }, // H + { 0x0EU, 0x04U, 0x04U, 0x04U, 0x04U, 0x04U, 0x0EU }, // I + { 0x1CU, 0x08U, 0x08U, 0x08U, 0x08U, 0x09U, 0x06U }, // J + { 0x11U, 0x09U, 0x05U, 0x03U, 0x05U, 0x09U, 0x11U }, // K + { 0x01U, 0x01U, 0x01U, 0x01U, 0x01U, 0x01U, 0x1FU }, // L + { 0x11U, 0x1BU, 0x15U, 0x15U, 0x11U, 0x11U, 0x11U }, // M + { 0x11U, 0x11U, 0x13U, 0x15U, 0x19U, 0x11U, 0x11U }, // N + { 0x0EU, 0x11U, 0x11U, 0x11U, 0x11U, 0x11U, 0x0EU }, // O + { 0x0FU, 0x11U, 0x11U, 0x0FU, 0x01U, 0x01U, 0x01U }, // P + { 0x0EU, 0x11U, 0x11U, 0x11U, 0x15U, 0x09U, 0x16U }, // Q + { 0x0FU, 0x11U, 0x11U, 0x0FU, 0x05U, 0x09U, 0x11U }, // R + { 0x1EU, 0x01U, 0x01U, 0x0EU, 0x10U, 0x10U, 0x0FU }, // S + { 0x1FU, 0x04U, 0x04U, 0x04U, 0x04U, 0x04U, 0x04U }, // T + { 0x11U, 0x11U, 0x11U, 0x11U, 0x11U, 0x11U, 0x0EU }, // U + { 0x11U, 0x11U, 0x11U, 0x11U, 0x11U, 0x0AU, 0x04U }, // V + { 0x11U, 0x11U, 0x11U, 0x15U, 0x15U, 0x15U, 0x0AU }, // W + { 0x11U, 0x11U, 0x0AU, 0x04U, 0x0AU, 0x11U, 0x11U }, // X + { 0x11U, 0x11U, 0x11U, 0x0AU, 0x04U, 0x04U, 0x04U }, // Y + { 0x1FU, 0x10U, 0x08U, 0x04U, 0x02U, 0x01U, 0x1FU }, // Z + { 0x0EU, 0x02U, 0x02U, 0x02U, 0x02U, 0x02U, 0x0EU }, // [ + { 0x00U, 0x01U, 0x02U, 0x04U, 0x08U, 0x10U, 0x00U }, // '\' + { 0x0EU, 0x08U, 0x08U, 0x08U, 0x08U, 0x08U, 0x0EU }, // ] + { 0x04U, 0x0AU, 0x11U, 0x00U, 0x00U, 0x00U, 0x00U }, // ^ + { 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x1FU }, // _ + { 0x02U, 0x04U, 0x08U, 0x00U, 0x00U, 0x00U, 0x00U }, // ` + { 0x00U, 0x00U, 0x0EU, 0x10U, 0x1EU, 0x11U, 0x1EU }, // a + { 0x01U, 0x01U, 0x0DU, 0x13U, 0x11U, 0x11U, 0x0FU }, // b + { 0x00U, 0x00U, 0x0EU, 0x01U, 0x01U, 0x11U, 0x0EU }, // c + { 0x10U, 0x10U, 0x16U, 0x19U, 0x11U, 0x11U, 0x1EU }, // d + { 0x00U, 0x00U, 0x0EU, 0x11U, 0x1FU, 0x01U, 0x0EU }, // e + { 0x0CU, 0x12U, 0x02U, 0x07U, 0x02U, 0x02U, 0x02U }, // f + { 0x00U, 0x1EU, 0x11U, 0x11U, 0x1EU, 0x10U, 0x0EU }, // g + { 0x01U, 0x01U, 0x0DU, 0x13U, 0x11U, 0x11U, 0x11U }, // h + { 0x04U, 0x00U, 0x06U, 0x04U, 0x04U, 0x04U, 0x0EU }, // i + { 0x08U, 0x00U, 0x0CU, 0x08U, 0x08U, 0x09U, 0x06U }, // j + { 0x01U, 0x01U, 0x09U, 0x05U, 0x03U, 0x05U, 0x09U }, // k + { 0x06U, 0x04U, 0x04U, 0x04U, 0x04U, 0x04U, 0x0EU }, // l + { 0x00U, 0x00U, 0x0BU, 0x15U, 0x15U, 0x11U, 0x11U }, // m + { 0x00U, 0x00U, 0x0DU, 0x13U, 0x11U, 0x11U, 0x11U }, // n + { 0x00U, 0x00U, 0x0EU, 0x11U, 0x11U, 0x11U, 0x0EU }, // o + { 0x00U, 0x00U, 0x0FU, 0x11U, 0x0FU, 0x01U, 0x01U }, // p + { 0x00U, 0x00U, 0x16U, 0x19U, 0x1EU, 0x10U, 0x10U }, // q + { 0x00U, 0x00U, 0x0DU, 0x13U, 0x01U, 0x01U, 0x01U }, // r + { 0x00U, 0x00U, 0x0EU, 0x01U, 0x0EU, 0x10U, 0x0FU }, // s + { 0x02U, 0x02U, 0x07U, 0x02U, 0x02U, 0x12U, 0x0CU }, // t + { 0x00U, 0x00U, 0x11U, 0x11U, 0x11U, 0x19U, 0x16U }, // u + { 0x00U, 0x00U, 0x11U, 0x11U, 0x11U, 0x0AU, 0x04U }, // v + { 0x00U, 0x00U, 0x11U, 0x11U, 0x15U, 0x15U, 0x0AU }, // w + { 0x00U, 0x00U, 0x11U, 0x0AU, 0x04U, 0x0AU, 0x11U }, // x + { 0x00U, 0x00U, 0x11U, 0x11U, 0x1EU, 0x10U, 0x0EU }, // y + { 0x00U, 0x00U, 0x1FU, 0x08U, 0x04U, 0x02U, 0x1FU }, // z + { 0x08U, 0x04U, 0x04U, 0x02U, 0x04U, 0x04U, 0x08U }, // { + { 0x04U, 0x04U, 0x04U, 0x04U, 0x04U, 0x04U, 0x04U }, // | + { 0x02U, 0x04U, 0x04U, 0x08U, 0x04U, 0x04U, 0x02U }, // } + { 0x02U, 0x15U, 0x08U, 0x00U, 0x00U, 0x00U, 0x00U }, // ~ }; for (; *str != '\0'; ++str, x += 6) { @@ -342,112 +344,112 @@ void BSP_paintString(uint8_t x, uint8_t y, char const *str) { } } -/*==========================================================================*/ -typedef struct { /* the auxiliary structure to hold const bitmaps */ - uint8_t const *bits; /* the bits in the bitmap */ - uint8_t height; /* the height of the bitmap */ +//========================================================================== +typedef struct { // the auxiliary structure to hold const bitmaps + uint8_t const *bits; // the bits in the bitmap + uint8_t height; // the height of the bitmap } Bitmap; -/* bitmap of the Ship: -* -* x.... -* xxx.. -* xxxxx -*/ +// bitmap of the Ship: +// +// x.... +// xxx.. +// xxxxx +// static uint8_t const ship_bits[] = { 0x01U, 0x07U, 0x1FU }; -/* bitmap of the Missile: -* -* xxxx -*/ +// bitmap of the Missile: +// +// xxxx +// static uint8_t const missile_bits[] = { 0x0FU }; -/* bitmap of the Mine type-1: -* -* .x. -* xxx -* .x. -*/ +// bitmap of the Mine type-1: +// +// .x. +// xxx +// .x. +// static uint8_t const mine1_bits[] = { 0x02U, 0x07U, 0x02U }; -/* bitmap of the Mine type-2: -* -* x..x -* .xx. -* .xx. -* x..x -*/ +// bitmap of the Mine type-2: +// +// x..x +// .xx. +// .xx. +// x..x +// static uint8_t const mine2_bits[] = { 0x09U, 0x06U, 0x06U, 0x09U }; -/* Mine type-2 is nastier than Mine type-1. The type-2 mine can -* hit the Ship with any of its "tentacles". However, it can be -* destroyed by the Missile only by hitting its center, defined as -* the following bitmap: -* -* .... -* .xx. -* .xx. -*/ +// Mine type-2 is nastier than Mine type-1. The type-2 mine can +// hit the Ship with any of its "tentacles". However, it can be +// destroyed by the Missile only by hitting its center, defined as +// the following bitmap: +// +// .... +// .xx. +// .xx. +// static uint8_t const mine2_missile_bits[] = { 0x00U, 0x06U, 0x06U }; -/* -* The bitmap of the explosion stage 0: -* -* ....... -* ...x... -* ..x.x.. -* ...x... -*/ +// +// The bitmap of the explosion stage 0: +// +// ....... +// ...x... +// ..x.x.. +// ...x... +// static uint8_t const explosion0_bits[] = { 0x00U, 0x08U, 0x14U, 0x08U }; -/* -* The bitmap of the explosion stage 1: -* -* ....... -* ..x.x.. -* ...x... -* ..x.x.. -*/ +// +// The bitmap of the explosion stage 1: +// +// ....... +// ..x.x.. +// ...x... +// ..x.x.. +// static uint8_t const explosion1_bits[] = { 0x00U, 0x14U, 0x08U, 0x14U }; -/* -* The bitmap of the explosion stage 2: -* -* .x...x. -* ..x.x.. -* ...x... -* ..x.x.. -* .x...x. -*/ +// +// The bitmap of the explosion stage 2: +// +// .x...x. +// ..x.x.. +// ...x... +// ..x.x.. +// .x...x. +// static uint8_t const explosion2_bits[] = { 0x11U, 0x0AU, 0x04U, 0x0AU, 0x11U }; -/* -* The bitmap of the explosion stage 3: -* -* x..x..x -* .x.x.x. -* ..x.x.. -* xx.x.xx -* ..x.x.. -* .x.x.x. -* x..x..x -*/ +// +// The bitmap of the explosion stage 3: +// +// x..x..x +// .x.x.x. +// ..x.x.. +// xx.x.xx +// ..x.x.. +// .x.x.x. +// x..x..x +// static uint8_t const explosion3_bits[] = { 0x49, 0x2A, 0x14, 0x6B, 0x14, 0x2A, 0x49 }; @@ -464,22 +466,22 @@ static Bitmap const l_bitmap[MAX_BMP] = { { explosion3_bits, Q_DIM(explosion3_bits) } }; -/*..........................................................................*/ +//............................................................................ void BSP_paintBitmap(uint8_t x, uint8_t y, uint8_t bmp_id) { Bitmap const *bmp = &l_bitmap[bmp_id]; paintBits(x, y, bmp->bits, bmp->height); } -/*..........................................................................*/ +//............................................................................ void BSP_advanceWalls(uint8_t top, uint8_t bottom) { uint_fast8_t y; for (y = 0U; y < GAME_TUNNEL_HEIGHT; ++y) { - /* shift the walls one pixel to the left */ + // shift the walls one pixel to the left l_walls[y][0] = (l_walls[y][0] >> 1) | (l_walls[y][1] << 31); l_walls[y][1] = (l_walls[y][1] >> 1) | (l_walls[y][2] << 31); l_walls[y][2] = (l_walls[y][2] >> 1) | (l_walls[y][3] << 31); l_walls[y][3] = (l_walls[y][3] >> 1); - /* add new column of walls at the end */ + // add new column of walls at the end if (y <= top) { l_walls[y][3] |= (1U << 31); } @@ -487,14 +489,14 @@ void BSP_advanceWalls(uint8_t top, uint8_t bottom) { l_walls[y][3] |= (1U << 31); } - /* copy the walls to the frame buffer */ + // copy the walls to the frame buffer l_fb[y][0] = l_walls[y][0]; l_fb[y][1] = l_walls[y][1]; l_fb[y][2] = l_walls[y][2]; l_fb[y][3] = l_walls[y][3]; } } -/*..........................................................................*/ +//............................................................................ bool BSP_doBitmapsOverlap(uint8_t bmp_id1, uint8_t x1, uint8_t y1, uint8_t bmp_id2, uint8_t x2, uint8_t y2) { @@ -508,7 +510,7 @@ bool BSP_doBitmapsOverlap(uint8_t bmp_id1, uint8_t x1, uint8_t y1, Q_REQUIRE((bmp_id1 < Q_DIM(l_bitmap)) && (bmp_id2 < Q_DIM(l_bitmap))); - /* are the bitmaps close enough in x? */ + // are the bitmaps close enough in x? if (x1 >= x2) { if (x1 > x2 + 8U) { return false; @@ -532,11 +534,11 @@ bool BSP_doBitmapsOverlap(uint8_t bmp_id1, uint8_t x1, uint8_t y1, if (h > bmp2->height) { h = bmp2->height; } - for (y = 0; y < h; ++y) { /* scan over the overlapping rows */ + for (y = 0; y < h; ++y) { // scan over the overlapping rows bits1 = ((uint32_t)bmp1->bits[y + y0] << x1); bits2 = ((uint32_t)bmp2->bits[y] << x2); - if ((bits1 & bits2) != 0U) { /* do the bits overlap? */ - return true; /* yes! */ + if ((bits1 & bits2) != 0U) { // do the bits overlap? + return true; // yes! } } } @@ -547,18 +549,18 @@ bool BSP_doBitmapsOverlap(uint8_t bmp_id1, uint8_t x1, uint8_t y1, if (h > bmp1->height) { h = bmp1->height; } - for (y = 0; y < h; ++y) { /* scan over the overlapping rows */ + for (y = 0; y < h; ++y) { // scan over the overlapping rows bits1 = ((uint32_t)bmp1->bits[y] << x1); bits2 = ((uint32_t)bmp2->bits[y + y0] << x2); - if ((bits1 & bits2) != 0U) { /* do the bits overlap? */ - return true; /* yes! */ + if ((bits1 & bits2) != 0U) { // do the bits overlap? + return true; // yes! } } } } - return false; /* the bitmaps do not overlap */ + return false; // the bitmaps do not overlap } -/*..........................................................................*/ +//............................................................................ bool BSP_isWallHit(uint8_t bmp_id, uint8_t x, uint8_t y) { Bitmap const *bmp = &l_bitmap[bmp_id]; uint32_t shft = (x & 0x1FU); @@ -576,7 +578,7 @@ bool BSP_isWallHit(uint8_t bmp_id, uint8_t x, uint8_t y) { return false; } -/*..........................................................................*/ +//............................................................................ void BSP_updateScore(uint16_t score) { char str[5]; uint16_t s = score; @@ -585,7 +587,7 @@ void BSP_updateScore(uint16_t score) { BSP_paintString(1U, BSP_SCREEN_HEIGHT - 8U, "SCORE:"); } - /* update the SCORE area on the screeen */ + // update the SCORE area on the screeen str[4] = '\0'; str[3] = (s % 10U) + '0'; s /= 10U; str[2] = (s % 10U) + '0'; s /= 10U; @@ -593,33 +595,33 @@ void BSP_updateScore(uint16_t score) { str[0] = (s % 10U) + '0'; BSP_paintString(6U*6U, BSP_SCREEN_HEIGHT - 8U, str); - QS_BEGIN_ID(SCORE_STAT, 0U) /* app-specific record */ + QS_BEGIN_ID(SCORE_STAT, 0U) // app-specific record QS_U16(4, score); QS_END() } -/*..........................................................................*/ +//............................................................................ void BSP_displayOn(void) { Display_enable(true); } -/*..........................................................................*/ +//............................................................................ void BSP_displayOff(void) { Display_enable(false); } -/*..........................................................................*/ -uint32_t BSP_random(void) { /* a very cheap pseudo-random-number generator */ - /* "Super-Duper" Linear Congruential Generator (LCG) - * LCG(2^32, 3*7*11*13*23, 0, seed) - */ +//............................................................................ +uint32_t BSP_random(void) { // a very cheap pseudo-random-number generator + // "Super-Duper" Linear Congruential Generator (LCG) + // LCG(2^32, 3*7*11*13*23, 0, seed) + // l_rnd = l_rnd * (3U*7U*11U*13U*23U); return l_rnd >> 8; } -/*..........................................................................*/ +//............................................................................ void BSP_randomSeed(uint32_t seed) { l_rnd = seed; } -/*--------------------------------------------------------------------------*/ -/*..........................................................................*/ +//---------------------------------------------------------------------------- +//............................................................................ static void paintBits(uint8_t x, uint8_t y, uint8_t const *bits, uint8_t h) { uint32_t *fb = &l_fb[y][x >> 5]; uint32_t shft = (x & 0x1FU); @@ -630,7 +632,7 @@ static void paintBits(uint8_t x, uint8_t y, uint8_t const *bits, uint8_t h) { } } } -/*..........................................................................*/ +//............................................................................ static void paintBitsClear(uint8_t x, uint8_t y, uint8_t const *bits, uint8_t h) { @@ -650,194 +652,199 @@ static void paintBitsClear(uint8_t x, uint8_t y, } } -/* QF callbacks ============================================================*/ +// QF callbacks ============================================================ void QF_onStartup(void) { - /* set up the SysTick timer to fire at BSP_TICKS_PER_SEC rate */ + // set up the SysTick timer to fire at BSP_TICKS_PER_SEC rate SysTick_Config(SystemCoreClock / BSP_TICKS_PER_SEC); - /* assing all priority bits for preemption-prio. and none to sub-prio. */ + // assing all priority bits for preemption-prio. and none to sub-prio. NVIC_SetPriorityGrouping(0U); - /* set priorities of ALL ISRs used in the system, see NOTE00 - * - * !!!!!!!!!!!!!!!!!!!!!!!!!!!! CAUTION !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - * Assign a priority to EVERY ISR explicitly by calling NVIC_SetPriority(). - * DO NOT LEAVE THE ISR PRIORITIES AT THE DEFAULT VALUE! - */ - NVIC_SetPriority(USART0_RX_IRQn, 0U); /* kernel unaware interrupt */ + // set priorities of ALL ISRs used in the system, see NOTE00 + // + // !!!!!!!!!!!!!!!!!!!!!!!!!!!! CAUTION !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + // Assign a priority to EVERY ISR explicitly by calling NVIC_SetPriority(). + // DO NOT LEAVE THE ISR PRIORITIES AT THE DEFAULT VALUE! + // + NVIC_SetPriority(USART0_RX_IRQn, 0U); // kernel unaware interrupt NVIC_SetPriority(GPIO_EVEN_IRQn, QF_AWARE_ISR_CMSIS_PRI); NVIC_SetPriority(SysTick_IRQn, QF_AWARE_ISR_CMSIS_PRI + 1U); - /* ... */ + // ... - /* enable IRQs... */ + // enable IRQs... NVIC_EnableIRQ(GPIO_EVEN_IRQn); #ifdef Q_SPY - NVIC_EnableIRQ(USART0_RX_IRQn); /* UART0 interrupt used for QS-RX */ + NVIC_EnableIRQ(USART0_RX_IRQn); // UART0 interrupt used for QS-RX #endif } -/*..........................................................................*/ +//............................................................................ void QF_onCleanup(void) { } -/*..........................................................................*/ -void QV_onIdle(void) { /* called with interrupts disabled, see NOTE01 */ - /* toggle the User LED on and then off, see NOTE02 */ +//............................................................................ +void QV_onIdle(void) { // called with interrupts disabled, see NOTE01 + // toggle the User LED on and then off, see NOTE02 GPIO->P[LED_PORT].DOUT |= (1U << LED0_PIN); GPIO->P[LED_PORT].DOUT &= ~(1U << LED0_PIN); #ifdef Q_SPY QF_INT_ENABLE(); - QS_rxParse(); /* parse all the received bytes */ + QS_rxParse(); // parse all the received bytes - if ((l_USART0->STATUS & USART_STATUS_TXBL) != 0) { /* is TXE empty? */ + if ((l_USART0->STATUS & USART_STATUS_TXBL) != 0) { // is TXE empty? uint16_t b; QF_INT_DISABLE(); b = QS_getByte(); QF_INT_ENABLE(); - if (b != QS_EOD) { /* not End-Of-Data? */ - l_USART0->TXDATA = (b & 0xFFU); /* put into the DR register */ + if (b != QS_EOD) { // not End-Of-Data? + l_USART0->TXDATA = (b & 0xFFU); // put into the DR register } } #elif defined NDEBUG - /* Put the CPU and peripherals to the low-power mode. - * you might need to customize the clock management for your application, - * see the datasheet for your particular Cortex-M MCU. - */ - QV_CPU_SLEEP(); /* atomically go to sleep and enable interrupts */ + // Put the CPU and peripherals to the low-power mode. + // you might need to customize the clock management for your application, + // see the datasheet for your particular Cortex-M MCU. + // + QV_CPU_SLEEP(); // atomically go to sleep and enable interrupts #else - QF_INT_ENABLE(); /* just enable interrupts */ + QF_INT_ENABLE(); // just enable interrupts #endif } -/*..........................................................................*/ -Q_NORETURN Q_onAssert(char const * const module, int_t const loc) { - /* - * NOTE: add here your application-specific error handling - */ - (void)module; - (void)loc; - QS_ASSERTION(module, loc, 10000U); /* report assertion to QS */ +//............................................................................ +Q_NORETURN Q_onError(char const * const module, int_t const id) { + // + // NOTE: add here your application-specific error handling + // + Q_UNUSED_PAR(module); + Q_UNUSED_PAR(id); + + QS_ASSERTION(module, id, 10000U); // report assertion to QS #ifndef NDEBUG - /* light up both LEDs */ + // light up both LEDs GPIO->P[LED_PORT].DOUT |= ((1U << LED0_PIN) | (1U << LED1_PIN)); - /* for debugging, hang on in an endless loop until PB1 is pressed... */ + // for debugging, hang on in an endless loop until PB1 is pressed... while ((GPIO->P[PB_PORT].DIN & (1U << PB1_PIN)) != 0) { } #endif NVIC_SystemReset(); } +//............................................................................ +void assert_failed(char const * const module, int_t const id); // prototype +void assert_failed(char const * const module, int_t const id) { + Q_onError(module, id); +} -/* QS callbacks ============================================================*/ +// QS callbacks ============================================================ #ifdef Q_SPY -/*..........................................................................*/ +//............................................................................ uint8_t QS_onStartup(void const *arg) { - static uint8_t qsTxBuf[2*1024]; /* buffer for QS transmit channel */ - static uint8_t qsRxBuf[100]; /* buffer for QS receive channel */ + static uint8_t qsTxBuf[2*1024]; // buffer for QS transmit channel + static uint8_t qsRxBuf[100]; // buffer for QS receive channel static USART_InitAsync_TypeDef init = { - usartEnable, /* Enable RX/TX when init completed */ - 0, /* Use current clock for configuring baudrate */ - 115200, /* 115200 bits/s */ - usartOVS16, /* 16x oversampling */ - usartDatabits8, /* 8 databits */ - usartNoParity, /* No parity */ - usartStopbits1, /* 1 stopbit */ - 0, /* Do not disable majority vote */ - 0, /* Not USART PRS input mode */ - usartPrsRxCh0, /* PRS channel 0 */ - 0, /* Auto CS functionality enable/disable switch */ - 0, /* Auto CS Hold cycles */ - 0 /* Auto CS Setup cycles */ + usartEnable, // Enable RX/TX when init completed + 0, // Use current clock for configuring baudrate + 115200, // 115200 bits/s + usartOVS16, // 16x oversampling + usartDatabits8, // 8 databits + usartNoParity, // No parity + usartStopbits1, // 1 stopbit + 0, // Do not disable majority vote + 0, // Not USART PRS input mode + usartPrsRxCh0, // PRS channel 0 + 0, // Auto CS functionality enable/disable switch + 0, // Auto CS Hold cycles + 0 // Auto CS Setup cycles }; QS_initBuf (qsTxBuf, sizeof(qsTxBuf)); QS_rxInitBuf(qsRxBuf, sizeof(qsRxBuf)); - /* Enable peripheral clocks */ + // Enable peripheral clocks CMU_ClockEnable(cmuClock_HFPER, true); CMU_ClockEnable(cmuClock_GPIO, true); - /* To avoid false start, configure output as high */ + // To avoid false start, configure output as high GPIO_PinModeSet(gpioPortA, 0, gpioModePushPull, 1); // TX pin GPIO_PinModeSet(gpioPortA, 1, gpioModeInput, 0); // RX pin - /* Enable DK RS232/UART switch */ + // Enable DK RS232/UART switch GPIO_PinModeSet(gpioPortA, 5, gpioModePushPull, 1); CMU_ClockEnable(cmuClock_USART0, true); - /* configure the UART for the desired baud rate, 8-N-1 operation */ + // configure the UART for the desired baud rate, 8-N-1 operation init.enable = usartDisable; USART_InitAsync(l_USART0, &init); - /* enable pins at correct UART/USART location. */ + // enable pins at correct UART/USART location. l_USART0->ROUTEPEN = USART_ROUTEPEN_RXPEN | USART_ROUTEPEN_TXPEN; l_USART0->ROUTELOC0 = (l_USART0->ROUTELOC0 & ~(_USART_ROUTELOC0_TXLOC_MASK | _USART_ROUTELOC0_RXLOC_MASK)); - /* Clear previous RX interrupts */ + // Clear previous RX interrupts USART_IntClear(l_USART0, USART_IF_RXDATAV); NVIC_ClearPendingIRQ(USART0_RX_IRQn); - /* Enable RX interrupts */ + // Enable RX interrupts USART_IntEnable(l_USART0, USART_IF_RXDATAV); - /* NOTE: do not enable the UART0 interrupt in the NVIC yet. - * Wait till QF_onStartup() - */ + // NOTE: do not enable the UART0 interrupt in the NVIC yet. + // Wait till QF_onStartup() + // - /* Finally enable the UART */ + // Finally enable the UART USART_Enable(l_USART0, usartEnable); QS_tickPeriod_ = SystemCoreClock / BSP_TICKS_PER_SEC; - QS_tickTime_ = QS_tickPeriod_; /* to start the timestamp at zero */ + QS_tickTime_ = QS_tickPeriod_; // to start the timestamp at zero - return 1U; /* return success */ + return 1U; // return success } -/*..........................................................................*/ +//............................................................................ void QS_onCleanup(void) { } -/*..........................................................................*/ -QSTimeCtr QS_onGetTime(void) { /* NOTE: invoked with interrupts DISABLED */ - if ((SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk) == 0) { /* not set? */ +//............................................................................ +QSTimeCtr QS_onGetTime(void) { // NOTE: invoked with interrupts DISABLED + if ((SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk) == 0) { // not set? return QS_tickTime_ - (QSTimeCtr)SysTick->VAL; } - else { /* the rollover occured, but the SysTick_ISR did not run yet */ + else { // the rollover occured, but the SysTick_ISR did not run yet return QS_tickTime_ + QS_tickPeriod_ - (QSTimeCtr)SysTick->VAL; } } -/*..........................................................................*/ +//............................................................................ void QS_onFlush(void) { uint16_t b; QF_INT_DISABLE(); - while ((b = QS_getByte()) != QS_EOD) { /* while not End-Of-Data... */ + while ((b = QS_getByte()) != QS_EOD) { // while not End-Of-Data... QF_INT_ENABLE(); - /* while TXE not empty */ + // while TXE not empty while ((l_USART0->STATUS & USART_STATUS_TXBL) == 0U) { } - l_USART0->TXDATA = (b & 0xFFU); /* put into the DR register */ + l_USART0->TXDATA = (b & 0xFFU); // put into the DR register QF_INT_DISABLE(); } QF_INT_ENABLE(); } -/*..........................................................................*/ -/*! callback function to reset the target (to be implemented in the BSP) */ +//............................................................................ +//! callback function to reset the target (to be implemented in the BSP) void QS_onReset(void) { NVIC_SystemReset(); } -/*..........................................................................*/ -/*! callback function to execute a user command (to be implemented in BSP) */ +//............................................................................ +//! callback function to execute a user command (to be implemented in BSP) void QS_onCommand(uint8_t cmdId, uint32_t param1, uint32_t param2, uint32_t param3) { - void assert_failed(char const *module, int loc); (void)cmdId; (void)param1; (void)param2; (void)param3; - QS_BEGIN_ID(COMMAND_STAT, 0U) /* app-specific record */ + QS_BEGIN_ID(COMMAND_STAT, 0U) // app-specific record QS_U8(2, cmdId); QS_U32(8, param1); QS_U32(8, param2); @@ -847,42 +854,39 @@ void QS_onCommand(uint8_t cmdId, if (cmdId == 10U) { Q_ERROR(); } - else if (cmdId == 11U) { - assert_failed("QS_onCommand", 123); - } } -#endif /* Q_SPY */ -/*--------------------------------------------------------------------------*/ +#endif // Q_SPY +//---------------------------------------------------------------------------- -/***************************************************************************** -* NOTE00: -* The QF_AWARE_ISR_CMSIS_PRI constant from the QF port specifies the highest -* ISR priority that is disabled by the QF framework. The value is suitable -* for the NVIC_SetPriority() CMSIS function. -* -* Only ISRs prioritized at or below the QF_AWARE_ISR_CMSIS_PRI level (i.e., -* with the numerical values of priorities equal or higher than -* QF_AWARE_ISR_CMSIS_PRI) are allowed to call the QK_ISR_ENTRY/QK_ISR_ENTRY -* macros or any other QF/QK services. These ISRs are "QF-aware". -* -* Conversely, any ISRs prioritized above the QF_AWARE_ISR_CMSIS_PRI priority -* level (i.e., with the numerical values of priorities less than -* QF_AWARE_ISR_CMSIS_PRI) are never disabled and are not aware of the kernel. -* Such "QF-unaware" ISRs cannot call any QF/QK services. In particular they -* can NOT call the macros QK_ISR_ENTRY/QK_ISR_ENTRY. The only mechanism -* by which a "QF-unaware" ISR can communicate with the QF framework is by -* triggering a "QF-aware" ISR, which can post/publish events. -* -* NOTE01: -* The QV_onIdle() callback is called with interrupts disabled, because the -* determination of the idle condition might change by any interrupt posting -* an event. QV_onIdle() must internally enable interrupts, ideally -* atomically with putting the CPU to the power-saving mode. -* -* NOTE02: -* The User LED is used to visualize the idle loop activity. The brightness -* of the LED is proportional to the frequency of invcations of the idle loop. -* Please note that the LED is toggled with interrupts locked, so no interrupt -* execution time contributes to the brightness of the User LED. -*/ +//============================================================================ +// NOTE00: +// The QF_AWARE_ISR_CMSIS_PRI constant from the QF port specifies the highest +// ISR priority that is disabled by the QF framework. The value is suitable +// for the NVIC_SetPriority() CMSIS function. +// +// Only ISRs prioritized at or below the QF_AWARE_ISR_CMSIS_PRI level (i.e., +// with the numerical values of priorities equal or higher than +// QF_AWARE_ISR_CMSIS_PRI) are allowed to call the QK_ISR_ENTRY/QK_ISR_ENTRY +// macros or any other QF/QK services. These ISRs are "QF-aware". +// +// Conversely, any ISRs prioritized above the QF_AWARE_ISR_CMSIS_PRI priority +// level (i.e., with the numerical values of priorities less than +// QF_AWARE_ISR_CMSIS_PRI) are never disabled and are not aware of the kernel. +// Such "QF-unaware" ISRs cannot call any QF/QK services. In particular they +// can NOT call the macros QK_ISR_ENTRY/QK_ISR_ENTRY. The only mechanism +// by which a "QF-unaware" ISR can communicate with the QF framework is by +// triggering a "QF-aware" ISR, which can post/publish events. +// +// NOTE01: +// The QV_onIdle() callback is called with interrupts disabled, because the +// determination of the idle condition might change by any interrupt posting +// an event. QV_onIdle() must internally enable interrupts, ideally +// atomically with putting the CPU to the power-saving mode. +// +// NOTE02: +// The User LED is used to visualize the idle loop activity. The brightness +// of the LED is proportional to the frequency of invcations of the idle loop. +// Please note that the LED is toggled with interrupts locked, so no interrupt +// execution time contributes to the brightness of the User LED. +// diff --git a/examples/arm-cm/game_efm32-slstk3401a/qv/gnu/Makefile b/examples/arm-cm/game_efm32-slstk3401a/qv/gnu/Makefile index 09d5510c..a25d41f3 100644 --- a/examples/arm-cm/game_efm32-slstk3401a/qv/gnu/Makefile +++ b/examples/arm-cm/game_efm32-slstk3401a/qv/gnu/Makefile @@ -275,7 +275,7 @@ $(TARGET_BIN): $(TARGET_ELF) $(BIN) -O binary $< $@ $(TARGET_ELF) : $(ASM_OBJS_EXT) $(C_OBJS_EXT) $(CPP_OBJS_EXT) - $(CC) $(CFLAGS) $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o + $(CC) $(CFLAGS) $(QPC)/src/qs/qstamp.c -o $(BIN_DIR)/qstamp.o $(LINK) $(LINKFLAGS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) $(BIN_DIR)/%.d : %.c diff --git a/examples/arm-cm/game_efm32-slstk3401a/qv/iar/game-qv.ewd b/examples/arm-cm/game_efm32-slstk3401a/qv/iar/game-qv.ewd index a1aba753..cb16c888 100644 --- a/examples/arm-cm/game_efm32-slstk3401a/qv/iar/game-qv.ewd +++ b/examples/arm-cm/game_efm32-slstk3401a/qv/iar/game-qv.ewd @@ -1,4741 +1,4654 @@ - - + - 2 - - Debug - - ARM - - 1 - - C-SPY - 2 - - 28 - 1 + 3 + + Debug + + ARM + 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ARMSIM_ID - 2 - - 1 - 1 - 1 - - - - - - - - ANGEL_ID - 2 - - 0 - 1 - 1 - - - - - - - - - - - - CMSISDAP_ID - 2 - - 4 - 1 - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - GDBSERVER_ID - 2 - - 0 - 1 - 1 - - - - - - - - - - - IARROM_ID - 2 - - 1 - 1 - 1 - - - - - - - - - IJET_ID - 2 - - 8 - 1 - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - JLINK_ID - 2 - - 16 - 1 - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - LMIFTDI_ID - 2 - - 2 - 1 - 1 - - - - - - - - - - MACRAIGOR_ID - 2 - - 3 - 1 - 1 - - - - - - - - - - - - - - - - - - - - - - - PEMICRO_ID - 2 - - 3 - 1 - 1 - - - - - - - - RDI_ID - 2 - - 2 - 1 - 1 - - - - - - - - - - - - - - - - STLINK_ID - 2 - - 3 - 1 - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - THIRDPARTY_ID - 2 - - 0 - 1 - 1 - - - - - - - - TIFET_ID - 2 - - 1 - 1 - 1 - - - - - - - - - - - - - - - - - - - XDS100_ID - 2 - - 5 - 1 - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - $TOOLKIT_DIR$\plugins\middleware\HCCWare\HCCWare.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\middleware\PercepioTraceExporter\PercepioTraceExportPlugin.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\AVIX\AVIX.ENU.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\CMX\CmxArmPlugin.ENU.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\CMX\CmxTinyArmPlugin.ENU.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\MQX\MQXRtosPlugin.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\Quadros\Quadros_EWB7_Plugin.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\SafeRTOS\SafeRTOSPlugin.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\TI-RTOS\tirtosplugin.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-286-KA-CSpy.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-KA-CSpy.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\uCOS-III\uCOS-III-KA-CSpy.ewplugin - 0 - - - $EW_DIR$\common\plugins\CodeCoverage\CodeCoverage.ENU.ewplugin - 1 - - - $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin - 0 - - - $EW_DIR$\common\plugins\uCProbe\uCProbePlugin.ENU.ewplugin - 0 - - - - - Release - - ARM - - 0 - - C-SPY - 2 - - 28 - 1 + + C-SPY + 2 + + 32 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ARMSIM_ID + 2 + + 1 + 1 + 1 + + + + + + + + CADI_ID + 2 + + 0 + 1 + 1 + + + + + + + + + CMSISDAP_ID + 2 + + 4 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + GDBSERVER_ID + 2 + + 0 + 1 + 1 + + + + + + + + + + + IJET_ID + 2 + + 9 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + JLINK_ID + 2 + + 16 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + LMIFTDI_ID + 2 + + 3 + 1 + 1 + + + + + + + + + + + + + NULINK_ID + 2 + + 0 + 1 + 1 + + + + + + + PEMICRO_ID + 2 + + 3 + 1 + 1 + + + + + + + + STLINK_ID + 2 + + 8 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + THIRDPARTY_ID + 2 + + 0 + 1 + 1 + + + + + + + + TIFET_ID + 2 + + 1 + 1 + 1 + + + + + + + + + + + + + + + + + + + XDS100_ID + 2 + + 9 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + $TOOLKIT_DIR$\plugins\rtos\CMX\CmxArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\CMX\CmxTinyArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\FreeRtos\FreeRtosArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin2.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SafeRTOS\SafeRTOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9BE.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-286-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-III\uCOS-III-KA-CSpy.ewplugin + 0 + + + $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\TargetAccessServer\TargetAccessServer.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\uCProbe\uCProbePlugin.ENU.ewplugin + 0 + + + + + Release + + ARM + 0 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ARMSIM_ID - 2 - - 1 - 1 - 0 - - - - - - - - ANGEL_ID - 2 - - 0 - 1 - 0 - - - - - - - - - - - - CMSISDAP_ID - 2 - - 4 - 1 - 0 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - GDBSERVER_ID - 2 - - 0 - 1 - 0 - - - - - - - - - - - IARROM_ID - 2 - - 1 - 1 - 0 - - - - - - - - - IJET_ID - 2 - - 8 - 1 - 0 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - JLINK_ID - 2 - - 16 - 1 - 0 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - LMIFTDI_ID - 2 - - 2 - 1 - 0 - - - - - - - - - - MACRAIGOR_ID - 2 - - 3 - 1 - 0 - - - - - - - - - - - - - - - - - - - - - - - PEMICRO_ID - 2 - - 3 - 1 - 0 - - - - - - - - RDI_ID - 2 - - 2 - 1 - 0 - - - - - - - - - - - - - - - - STLINK_ID - 2 - - 3 - 1 - 0 - - - - - - - - - - - - - - - - - - - - - - - - - - - THIRDPARTY_ID - 2 - - 0 - 1 - 0 - - - - - - - - TIFET_ID - 2 - - 1 - 1 - 0 - - - - - - - - - - - - - - - - - - - XDS100_ID - 2 - - 5 - 1 - 0 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - $TOOLKIT_DIR$\plugins\middleware\HCCWare\HCCWare.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\middleware\PercepioTraceExporter\PercepioTraceExportPlugin.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\AVIX\AVIX.ENU.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\CMX\CmxArmPlugin.ENU.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\CMX\CmxTinyArmPlugin.ENU.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\MQX\MQXRtosPlugin.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\Quadros\Quadros_EWB7_Plugin.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\SafeRTOS\SafeRTOSPlugin.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\TI-RTOS\tirtosplugin.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-286-KA-CSpy.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-KA-CSpy.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\uCOS-III\uCOS-III-KA-CSpy.ewplugin - 0 - - - $EW_DIR$\common\plugins\CodeCoverage\CodeCoverage.ENU.ewplugin - 1 - - - $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin - 0 - - - $EW_DIR$\common\plugins\uCProbe\uCProbePlugin.ENU.ewplugin - 0 - - - - - Spy - - ARM - - 1 - - C-SPY - 2 - - 28 - 1 + + C-SPY + 2 + + 32 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ARMSIM_ID + 2 + + 1 + 1 + 0 + + + + + + + + CADI_ID + 2 + + 0 + 1 + 0 + + + + + + + + + CMSISDAP_ID + 2 + + 4 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + GDBSERVER_ID + 2 + + 0 + 1 + 0 + + + + + + + + + + + IJET_ID + 2 + + 9 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + JLINK_ID + 2 + + 16 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + LMIFTDI_ID + 2 + + 3 + 1 + 0 + + + + + + + + + + + + + NULINK_ID + 2 + + 0 + 1 + 0 + + + + + + + PEMICRO_ID + 2 + + 3 + 1 + 0 + + + + + + + + STLINK_ID + 2 + + 8 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + THIRDPARTY_ID + 2 + + 0 + 1 + 0 + + + + + + + + TIFET_ID + 2 + + 1 + 1 + 0 + + + + + + + + + + + + + + + + + + + XDS100_ID + 2 + + 9 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + $TOOLKIT_DIR$\plugins\rtos\CMX\CmxArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\CMX\CmxTinyArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\FreeRtos\FreeRtosArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin2.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SafeRTOS\SafeRTOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9BE.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-286-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-III\uCOS-III-KA-CSpy.ewplugin + 0 + + + $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\TargetAccessServer\TargetAccessServer.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\uCProbe\uCProbePlugin.ENU.ewplugin + 0 + + + + + Spy + + ARM + 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ARMSIM_ID - 2 - - 1 - 1 - 1 - - - - - - - - ANGEL_ID - 2 - - 0 - 1 - 1 - - - - - - - - - - - - CMSISDAP_ID - 2 - - 4 - 1 - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - GDBSERVER_ID - 2 - - 0 - 1 - 1 - - - - - - - - - - - IARROM_ID - 2 - - 1 - 1 - 1 - - - - - - - - - IJET_ID - 2 - - 8 - 1 - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - JLINK_ID - 2 - - 16 - 1 - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - LMIFTDI_ID - 2 - - 2 - 1 - 1 - - - - - - - - - - MACRAIGOR_ID - 2 - - 3 - 1 - 1 - - - - - - - - - - - - - - - - - - - - - - - PEMICRO_ID - 2 - - 3 - 1 - 1 - - - - - - - - RDI_ID - 2 - - 2 - 1 - 1 - - - - - - - - - - - - - - - - STLINK_ID - 2 - - 3 - 1 - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - THIRDPARTY_ID - 2 - - 0 - 1 - 1 - - - - - - - - TIFET_ID - 2 - - 1 - 1 - 1 - - - - - - - - - - - - - - - - - - - XDS100_ID - 2 - - 5 - 1 - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - $TOOLKIT_DIR$\plugins\middleware\HCCWare\HCCWare.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\middleware\PercepioTraceExporter\PercepioTraceExportPlugin.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\AVIX\AVIX.ENU.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\CMX\CmxArmPlugin.ENU.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\CMX\CmxTinyArmPlugin.ENU.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\MQX\MQXRtosPlugin.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\Quadros\Quadros_EWB7_Plugin.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\SafeRTOS\SafeRTOSPlugin.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\TI-RTOS\tirtosplugin.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-286-KA-CSpy.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-KA-CSpy.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\uCOS-III\uCOS-III-KA-CSpy.ewplugin - 0 - - - $EW_DIR$\common\plugins\CodeCoverage\CodeCoverage.ENU.ewplugin - 1 - - - $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin - 0 - - - $EW_DIR$\common\plugins\uCProbe\uCProbePlugin.ENU.ewplugin - 0 - - - + + C-SPY + 2 + + 32 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ARMSIM_ID + 2 + + 1 + 1 + 1 + + + + + + + + CADI_ID + 2 + + 0 + 1 + 1 + + + + + + + + + CMSISDAP_ID + 2 + + 4 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + GDBSERVER_ID + 2 + + 0 + 1 + 1 + + + + + + + + + + + IJET_ID + 2 + + 9 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + JLINK_ID + 2 + + 16 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + LMIFTDI_ID + 2 + + 3 + 1 + 1 + + + + + + + + + + + + + NULINK_ID + 2 + + 0 + 1 + 1 + + + + + + + PEMICRO_ID + 2 + + 3 + 1 + 1 + + + + + + + + STLINK_ID + 2 + + 8 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + THIRDPARTY_ID + 2 + + 0 + 1 + 1 + + + + + + + + TIFET_ID + 2 + + 1 + 1 + 1 + + + + + + + + + + + + + + + + + + + XDS100_ID + 2 + + 9 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + $TOOLKIT_DIR$\plugins\rtos\CMX\CmxArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\CMX\CmxTinyArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\FreeRtos\FreeRtosArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin2.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SafeRTOS\SafeRTOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9BE.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-286-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-III\uCOS-III-KA-CSpy.ewplugin + 0 + + + $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\TargetAccessServer\TargetAccessServer.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\uCProbe\uCProbePlugin.ENU.ewplugin + 0 + + + - - diff --git a/examples/arm-cm/game_efm32-slstk3401a/qv/iar/game-qv.ewp b/examples/arm-cm/game_efm32-slstk3401a/qv/iar/game-qv.ewp index 01fae0ae..8ba6847b 100644 --- a/examples/arm-cm/game_efm32-slstk3401a/qv/iar/game-qv.ewp +++ b/examples/arm-cm/game_efm32-slstk3401a/qv/iar/game-qv.ewp @@ -1,3067 +1,3397 @@ - - + - 2 - - Debug - - ARM - - 1 - - General - 3 - - 24 - 1 + 3 + + Debug + + ARM + 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ICCARM - 2 - - 31 - 1 - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - AARM - 2 - - 9 - 1 - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - OBJCOPY - 0 - - 1 - 1 - 1 - - - - - - - - - CUSTOM - 3 - - - - 0 - - - - BICOMP - 0 - - - - BUILDACTION - 1 - - cmd /c "if exist $OBJ_DIR$\qstamp.o del $OBJ_DIR$\qstamp.o" - - - - - ILINK - 0 - - 17 - 1 - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - IARCHIVE - 0 - - 0 - 1 - 1 - - - - - - - BILINK - 0 - - - - Coder - 0 - - - - - Release - - ARM - - 0 - - General - 3 - - 24 - 1 + + General + 3 + + 35 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ICCARM + 2 + + 37 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + AARM + 2 + + 11 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + OBJCOPY + 0 + + 1 + 1 + 1 + + + + + + + + + CUSTOM + 3 + + + + 0 + inputOutputBased + + + + BUILDACTION + 1 + + cmd /c "if exist $OBJ_DIR$\qstamp.o del $OBJ_DIR$\qstamp.o" + + + + + ILINK + 0 + + 27 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + IARCHIVE + 0 + + 0 + 1 + 1 + + + + + + + Coder + 0 + + + + + Release + + ARM + 0 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ICCARM - 2 - - 31 - 1 - 0 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - AARM - 2 - - 9 - 1 - 0 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - OBJCOPY - 0 - - 1 - 1 - 0 - - - - - - - - - CUSTOM - 3 - - - - 0 - - - - BICOMP - 0 - - - - BUILDACTION - 1 - - cmd /c "if exist $OBJ_DIR$\qstamp.o del $OBJ_DIR$\qstamp.o" - - - - - ILINK - 0 - - 17 - 1 - 0 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - IARCHIVE - 0 - - 0 - 1 - 0 - - - - - - - BILINK - 0 - - - - Coder - 0 - - - - - Spy - - ARM - - 1 - - General - 3 - - 24 - 1 + + General + 3 + + 35 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ICCARM + 2 + + 37 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + AARM + 2 + + 11 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + OBJCOPY + 0 + + 1 + 1 + 0 + + + + + + + + + CUSTOM + 3 + + + + 0 + inputOutputBased + + + + BUILDACTION + 1 + + cmd /c "if exist $OBJ_DIR$\qstamp.o del $OBJ_DIR$\qstamp.o" + + + + + ILINK + 0 + + 27 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + IARCHIVE + 0 + + 0 + 1 + 0 + + + + + + + Coder + 0 + + + + + Spy + + ARM + 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ICCARM - 2 - - 31 - 1 - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - AARM - 2 - - 9 - 1 - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - OBJCOPY - 0 - - 1 - 1 - 1 - - - - - - - - - CUSTOM - 3 - - - - 0 - - - - BICOMP - 0 - - - - BUILDACTION - 1 - - cmd /c "if exist $OBJ_DIR$\qstamp.o del $OBJ_DIR$\qstamp.o" - - - - - ILINK - 0 - - 17 - 1 - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - IARCHIVE - 0 - - 0 - 1 - 1 - - - - - - - BILINK - 0 - - - - Coder - 0 - - - - - Application - - $PROJ_DIR$\..\bsp.c - - - $PROJ_DIR$\..\..\bsp.h - - - $PROJ_DIR$\..\..\game.h - - - $PROJ_DIR$\..\..\main.c - - - $PROJ_DIR$\..\..\mine1.c - - - $PROJ_DIR$\..\..\mine2.c - - - $PROJ_DIR$\..\..\missile.c - - - $PROJ_DIR$\..\..\..\..\..\include\qstamp.c - - - $PROJ_DIR$\..\..\ship.c - - - $PROJ_DIR$\..\..\tunnel.c - - - - efm32pg1b - - $PROJ_DIR$\..\..\..\..\..\3rd_party\efm32pg1b\display_ls013b7dh03.c - - - $PROJ_DIR$\..\..\..\..\..\3rd_party\efm32pg1b\display_ls013b7dh03.h - - - $PROJ_DIR$\..\..\..\..\..\3rd_party\efm32pg1b\displaypalemlib.c - - - $PROJ_DIR$\..\..\..\..\..\3rd_party\efm32pg1b\em_assert.c - - - $PROJ_DIR$\..\..\..\..\..\3rd_party\efm32pg1b\em_cmu.c - - - $PROJ_DIR$\..\..\..\..\..\3rd_party\efm32pg1b\em_emu.c - - - $PROJ_DIR$\..\..\..\..\..\3rd_party\efm32pg1b\em_gpio.c - - - $PROJ_DIR$\..\..\..\..\..\3rd_party\efm32pg1b\em_int.c - - - $PROJ_DIR$\..\..\..\..\..\3rd_party\efm32pg1b\em_prs.c - - - $PROJ_DIR$\..\..\..\..\..\3rd_party\efm32pg1b\em_rtcc.c - - - $PROJ_DIR$\..\..\..\..\..\3rd_party\efm32pg1b\em_system.c - - - $PROJ_DIR$\..\..\..\..\..\3rd_party\efm32pg1b\em_usart.c - - - $PROJ_DIR$\..\..\..\..\..\3rd_party\efm32pg1b\iar\startup_efm32pg1b.s - - - $PROJ_DIR$\..\..\..\..\..\3rd_party\efm32pg1b\system_efm32pg1b.c - - - $PROJ_DIR$\..\..\..\..\..\3rd_party\efm32pg1b\udelay.c - - - - QP - - $PROJ_DIR$\..\..\..\..\..\src\qf\qep_hsm.c - - - $PROJ_DIR$\..\..\..\..\..\src\qf\qep_msm.c - - - $PROJ_DIR$\..\..\..\..\..\src\qf\qf_act.c - - - $PROJ_DIR$\..\..\..\..\..\src\qf\qf_actq.c - - - $PROJ_DIR$\..\..\..\..\..\src\qf\qf_defer.c - - - $PROJ_DIR$\..\..\..\..\..\src\qf\qf_dyn.c - - - $PROJ_DIR$\..\..\..\..\..\src\qf\qf_mem.c - - - $PROJ_DIR$\..\..\..\..\..\src\qf_pkg.h - - - $PROJ_DIR$\..\..\..\..\..\src\qf\qf_ps.c - - - $PROJ_DIR$\..\..\..\..\..\src\qf\qf_qact.c - - - $PROJ_DIR$\..\..\..\..\..\src\qf\qf_qeq.c - - - $PROJ_DIR$\..\..\..\..\..\src\qf\qf_qmact.c - - - $PROJ_DIR$\..\..\..\..\..\src\qf\qf_time.c - - - $PROJ_DIR$\..\..\..\..\..\src\qv\qv.c - - - - QP_port - - $PROJ_DIR$\..\..\..\..\..\ports\arm-cm\qv\iar\qv_port.c - - - - QS - - Debug - Release - - - $PROJ_DIR$\..\..\..\..\..\src\qs\qs.c - - - $PROJ_DIR$\..\..\..\..\..\src\qs\qs_fp.c - - - $PROJ_DIR$\..\..\..\..\..\src\qs_pkg.h - - - $PROJ_DIR$\..\..\..\..\..\src\qs\qs_rx.c - - + + General + 3 + + 35 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ICCARM + 2 + + 37 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + AARM + 2 + + 11 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + OBJCOPY + 0 + + 1 + 1 + 1 + + + + + + + + + CUSTOM + 3 + + + + 0 + inputOutputBased + + + + BUILDACTION + 1 + + cmd /c "if exist $OBJ_DIR$\qstamp.o del $OBJ_DIR$\qstamp.o" + + + + + ILINK + 0 + + 27 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + IARCHIVE + 0 + + 0 + 1 + 1 + + + + + + + Coder + 0 + + + + + Application + + $PROJ_DIR$\..\bsp.c + + + $PROJ_DIR$\..\..\bsp.h + + + $PROJ_DIR$\..\..\game.h + + + $PROJ_DIR$\..\..\main.c + + + $PROJ_DIR$\..\..\mine1.c + + + $PROJ_DIR$\..\..\mine2.c + + + $PROJ_DIR$\..\..\missile.c + + + $PROJ_DIR$\..\..\..\..\..\src\qs\qstamp.c + + + $PROJ_DIR$\..\..\ship.c + + + $PROJ_DIR$\..\..\tunnel.c + + + + efm32pg1b + + $PROJ_DIR$\..\..\..\..\..\3rd_party\efm32pg1b\display_ls013b7dh03.c + + + $PROJ_DIR$\..\..\..\..\..\3rd_party\efm32pg1b\display_ls013b7dh03.h + + + $PROJ_DIR$\..\..\..\..\..\3rd_party\efm32pg1b\displaypalemlib.c + + + $PROJ_DIR$\..\..\..\..\..\3rd_party\efm32pg1b\em_assert.c + + + $PROJ_DIR$\..\..\..\..\..\3rd_party\efm32pg1b\em_cmu.c + + + $PROJ_DIR$\..\..\..\..\..\3rd_party\efm32pg1b\em_emu.c + + + $PROJ_DIR$\..\..\..\..\..\3rd_party\efm32pg1b\em_gpio.c + + + $PROJ_DIR$\..\..\..\..\..\3rd_party\efm32pg1b\em_int.c + + + $PROJ_DIR$\..\..\..\..\..\3rd_party\efm32pg1b\em_prs.c + + + $PROJ_DIR$\..\..\..\..\..\3rd_party\efm32pg1b\em_rtcc.c + + + $PROJ_DIR$\..\..\..\..\..\3rd_party\efm32pg1b\em_system.c + + + $PROJ_DIR$\..\..\..\..\..\3rd_party\efm32pg1b\em_usart.c + + + $PROJ_DIR$\..\..\..\..\..\3rd_party\efm32pg1b\iar\startup_efm32pg1b.s + + + $PROJ_DIR$\..\..\..\..\..\3rd_party\efm32pg1b\system_efm32pg1b.c + + + $PROJ_DIR$\..\..\..\..\..\3rd_party\efm32pg1b\udelay.c + + + + QP + + $PROJ_DIR$\..\..\..\..\..\src\qf\qep_hsm.c + + + $PROJ_DIR$\..\..\..\..\..\src\qf\qep_msm.c + + + $PROJ_DIR$\..\..\..\..\..\src\qf\qf_act.c + + + $PROJ_DIR$\..\..\..\..\..\src\qf\qf_actq.c + + + $PROJ_DIR$\..\..\..\..\..\src\qf\qf_defer.c + + + $PROJ_DIR$\..\..\..\..\..\src\qf\qf_dyn.c + + + $PROJ_DIR$\..\..\..\..\..\src\qf\qf_mem.c + + + $PROJ_DIR$\..\..\..\..\..\src\qf_pkg.h + + + $PROJ_DIR$\..\..\..\..\..\src\qf\qf_ps.c + + + $PROJ_DIR$\..\..\..\..\..\src\qf\qf_qact.c + + + $PROJ_DIR$\..\..\..\..\..\src\qf\qf_qeq.c + + + $PROJ_DIR$\..\..\..\..\..\src\qf\qf_qmact.c + + + $PROJ_DIR$\..\..\..\..\..\src\qf\qf_time.c + + + $PROJ_DIR$\..\..\..\..\..\src\qv\qv.c + + + + QP_port + + $PROJ_DIR$\..\..\..\..\..\ports\arm-cm\qv\iar\qv_port.c + + + + QS + + Debug + Release + + + $PROJ_DIR$\..\..\..\..\..\src\qs\qs.c + + + $PROJ_DIR$\..\..\..\..\..\src\qs\qs_fp.c + + + $PROJ_DIR$\..\..\..\..\..\src\qs_pkg.h + + + $PROJ_DIR$\..\..\..\..\..\src\qs\qs_rx.c + + - - diff --git a/examples/arm-cm/game_efm32-slstk3401a/ship.c b/examples/arm-cm/game_efm32-slstk3401a/ship.c index 4744af4b..ae6c8bf7 100644 --- a/examples/arm-cm/game_efm32-slstk3401a/ship.c +++ b/examples/arm-cm/game_efm32-slstk3401a/ship.c @@ -1,114 +1,114 @@ -/*$file${.::ship.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* -* Model: game.qm -* File: ${.::ship.c} -* -* This code has been generated by QM 5.2.4 . -* DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. -* -* SPDX-License-Identifier: GPL-3.0-or-later -* -* This generated code is open source software: you can redistribute it under -* the terms of the GNU General Public License as published by the Free -* Software Foundation. -* -* This code is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -* more details. -* -* NOTE: -* Alternatively, this generated code may be distributed under the terms -* of Quantum Leaps commercial licenses, which expressly supersede the GNU -* General Public License and are specifically designed for licensees -* interested in retaining the proprietary status of their code. -* -* Contact information: -* -* -*/ -/*$endhead${.::ship.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$file${.::ship.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// +// Model: game.qm +// File: ${.::ship.c} +// +// This code has been generated by QM 5.3.0 . +// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. +// +// SPDX-License-Identifier: GPL-3.0-or-later +// +// This generated code is open source software: you can redistribute it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation. +// +// This code is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// NOTE: +// Alternatively, this generated code may be distributed under the terms +// of Quantum Leaps commercial licenses, which expressly supersede the GNU +// General Public License and are specifically designed for licensees +// interested in retaining the proprietary status of their code. +// +// Contact information: +// +// +// +//$endhead${.::ship.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ #include "qpc.h" #include "bsp.h" #include "game.h" -/* Q_DEFINE_THIS_FILE */ +// Q_DEFINE_THIS_FILE #define SHIP_WIDTH 5 #define SHIP_HEIGHT 3 -/* encapsulated delcaration of the Ship active object ----------------------*/ -/*$declare${AOs::Ship} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +// encapsulated delcaration of the Ship active object ---------------------- +//$declare${AOs::Ship} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/*${AOs::Ship} .............................................................*/ +//${AOs::Ship} ............................................................... typedef struct Ship { -/* protected: */ +// protected: QActive super; -/* private: */ +// private: uint8_t x; uint16_t y; uint8_t exp_ctr; uint16_t score; -/* public: */ +// public: } Ship; -/* public: */ +// public: static void Ship_ctor(Ship * const me); extern Ship Ship_inst; -/* protected: */ +// protected: static QState Ship_initial(Ship * const me, void const * const par); static QState Ship_active(Ship * const me, QEvt const * const e); static QState Ship_parked(Ship * const me, QEvt const * const e); static QState Ship_flying(Ship * const me, QEvt const * const e); static QState Ship_exploding(Ship * const me, QEvt const * const e); -/*$enddecl${AOs::Ship} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$enddecl${AOs::Ship} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -/* Public-scope objects ----------------------------------------------------*/ -/*$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* Check for the minimum required QP version */ -#if (QP_VERSION < 700U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) -#error qpc version 7.0.0 or higher required +// Public-scope objects ---------------------------------------------------- +//$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// Check for the minimum required QP version +#if (QP_VERSION < 730U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) +#error qpc version 7.3.0 or higher required #endif -/*$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -/*$define${Shared::AO_Ship} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//$define${Shared::AO_Ship} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/*${Shared::AO_Ship} .......................................................*/ +//${Shared::AO_Ship} ......................................................... QActive * const AO_Ship = &Ship_inst.super; -/*$enddef${Shared::AO_Ship} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$enddef${Shared::AO_Ship} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -/* Active object definition ------------------------------------------------*/ -/*$define${Shared::Ship_ctor_call} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +// Active object definition ------------------------------------------------ +//$define${Shared::Ship_ctor_call} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/*${Shared::Ship_ctor_call} ................................................*/ +//${Shared::Ship_ctor_call} .................................................. void Ship_ctor_call(void) { Ship_ctor(&Ship_inst); } -/*$enddef${Shared::Ship_ctor_call} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*$define${AOs::Ship} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//$enddef${Shared::Ship_ctor_call} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +//$define${AOs::Ship} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/*${AOs::Ship} .............................................................*/ +//${AOs::Ship} ............................................................... Ship Ship_inst; -/*${AOs::Ship::ctor} .......................................................*/ +//${AOs::Ship::ctor} ......................................................... static void Ship_ctor(Ship * const me) { QActive_ctor(&me->super, Q_STATE_CAST(&Ship_initial)); me->x = GAME_SHIP_X; me->y = (GAME_SHIP_Y << 2); } -/*${AOs::Ship::SM} .........................................................*/ +//${AOs::Ship::SM} ........................................................... static QState Ship_initial(Ship * const me, void const * const par) { - /*${AOs::Ship::SM::initial} */ - (void)par; /* usused parameter */ + //${AOs::Ship::SM::initial} + (void)par; // usused parameter QActive_subscribe(&me->super, TIME_TICK_SIG); QActive_subscribe(&me->super, PLAYER_TRIGGER_SIG); - /* local signals... */ + // local signals... //QS_SIG_DICTIONARY(PLAYER_SHIP_MOVE_SIG, me); QS_SIG_DICTIONARY(TAKE_OFF_SIG, me); QS_SIG_DICTIONARY(HIT_WALL_SIG, me); @@ -123,11 +123,11 @@ static QState Ship_initial(Ship * const me, void const * const par) { return Q_TRAN(&Ship_active); } -/*${AOs::Ship::SM::active} .................................................*/ +//${AOs::Ship::SM::active} ................................................... static QState Ship_active(Ship * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${AOs::Ship::SM::active::initial} */ + //${AOs::Ship::SM::active::initial} case Q_INIT_SIG: { status_ = Q_TRAN(&Ship_parked); break; @@ -140,11 +140,11 @@ static QState Ship_active(Ship * const me, QEvt const * const e) { return status_; } -/*${AOs::Ship::SM::active::parked} .........................................*/ +//${AOs::Ship::SM::active::parked} ........................................... static QState Ship_parked(Ship * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${AOs::Ship::SM::active::parked::TAKE_OFF} */ + //${AOs::Ship::SM::active::parked::TAKE_OFF} case TAKE_OFF_SIG: { status_ = Q_TRAN(&Ship_flying); break; @@ -157,25 +157,25 @@ static QState Ship_parked(Ship * const me, QEvt const * const e) { return status_; } -/*${AOs::Ship::SM::active::flying} .........................................*/ +//${AOs::Ship::SM::active::flying} ........................................... static QState Ship_flying(Ship * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${AOs::Ship::SM::active::flying} */ + //${AOs::Ship::SM::active::flying} case Q_ENTRY_SIG: { ScoreEvt *sev; - me->score = 0U; /* reset the score */ + me->score = 0U; // reset the score sev = Q_NEW(ScoreEvt, SCORE_SIG); sev->score = me->score; QACTIVE_POST(AO_Tunnel, (QEvt *)sev, me); - /* lauch the ship from the initial position */ + // lauch the ship from the initial position me->x = GAME_SHIP_X; me->y = (GAME_SHIP_Y << 2); status_ = Q_HANDLED(); break; } - /*${AOs::Ship::SM::active::flying::TIME_TICK} */ + //${AOs::Ship::SM::active::flying::TIME_TICK} case TIME_TICK_SIG: { ObjectImageEvt *oie; @@ -190,16 +190,16 @@ static QState Ship_flying(Ship * const me, QEvt const * const e) { } } - /* tell the Tunnel to draw the Ship and test for hits */ + // tell the Tunnel to draw the Ship and test for hits oie = Q_NEW(ObjectImageEvt, SHIP_IMG_SIG); oie->x = me->x; oie->y = (uint8_t)(me->y >> 2); oie->bmp = SHIP_BMP; QACTIVE_POST(AO_Tunnel, (QEvt *)oie, me); - ++me->score; /* increment the score for surviving another tick */ + ++me->score; // increment the score for surviving another tick - if ((me->score % 10U) == 0U) { /* is the score "round"? */ + if ((me->score % 10U) == 0U) { // is the score "round"? ScoreEvt *sev = Q_NEW(ScoreEvt, SCORE_SIG); sev->score = me->score; QACTIVE_POST(AO_Tunnel, (QEvt *)sev, me); @@ -207,7 +207,7 @@ static QState Ship_flying(Ship * const me, QEvt const * const e) { status_ = Q_HANDLED(); break; } - /*${AOs::Ship::SM::active::flying::PLAYER_TRIGGER} */ + //${AOs::Ship::SM::active::flying::PLAYER_TRIGGER} case PLAYER_TRIGGER_SIG: { ObjectPosEvt *ope = Q_NEW(ObjectPosEvt, MISSILE_FIRE_SIG); ope->x = me->x; @@ -216,19 +216,19 @@ static QState Ship_flying(Ship * const me, QEvt const * const e) { status_ = Q_HANDLED(); break; } - /*${AOs::Ship::SM::active::flying::DESTROYED_MINE} */ + //${AOs::Ship::SM::active::flying::DESTROYED_MINE} case DESTROYED_MINE_SIG: { me->score += Q_EVT_CAST(ScoreEvt)->score; - /* the score will be sent to the Tunnel by the next TIME_TICK */ + // the score will be sent to the Tunnel by the next TIME_TICK status_ = Q_HANDLED(); break; } - /*${AOs::Ship::SM::active::flying::HIT_WALL} */ + //${AOs::Ship::SM::active::flying::HIT_WALL} case HIT_WALL_SIG: { status_ = Q_TRAN(&Ship_exploding); break; } - /*${AOs::Ship::SM::active::flying::HIT_MINE} */ + //${AOs::Ship::SM::active::flying::HIT_MINE} case HIT_MINE_SIG: { status_ = Q_TRAN(&Ship_exploding); break; @@ -241,31 +241,31 @@ static QState Ship_flying(Ship * const me, QEvt const * const e) { return status_; } -/*${AOs::Ship::SM::active::exploding} ......................................*/ +//${AOs::Ship::SM::active::exploding} ........................................ static QState Ship_exploding(Ship * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${AOs::Ship::SM::active::exploding} */ + //${AOs::Ship::SM::active::exploding} case Q_ENTRY_SIG: { me->exp_ctr = 0U; status_ = Q_HANDLED(); break; } - /*${AOs::Ship::SM::active::exploding::TIME_TICK} */ + //${AOs::Ship::SM::active::exploding::TIME_TICK} case TIME_TICK_SIG: { - /*${AOs::Ship::SM::active::exploding::TIME_TICK::[me->exp_ctr<15U]} */ + //${AOs::Ship::SM::active::exploding::TIME_TICK::[me->exp_ctr<15U]} if (me->exp_ctr < 15U) { ObjectImageEvt *oie; ++me->exp_ctr; - /* tell the Tunnel to draw the current stage of Explosion */ + // tell the Tunnel to draw the current stage of Explosion oie = Q_NEW(ObjectImageEvt, EXPLOSION_SIG); oie->bmp = EXPLOSION0_BMP + (me->exp_ctr >> 2); - oie->x = me->x; /* x of explosion */ + oie->x = me->x; // x of explosion oie->y = (int8_t)((int)(me->y >> 2) - 4U + SHIP_HEIGHT); QACTIVE_POST(AO_Tunnel, (QEvt *)oie, me); status_ = Q_HANDLED(); } - /*${AOs::Ship::SM::active::exploding::TIME_TICK::[else]} */ + //${AOs::Ship::SM::active::exploding::TIME_TICK::[else]} else { ScoreEvt *gameOver = Q_NEW(ScoreEvt, GAME_OVER_SIG); gameOver->score = me->score; @@ -281,4 +281,4 @@ static QState Ship_exploding(Ship * const me, QEvt const * const e) { } return status_; } -/*$enddef${AOs::Ship} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$enddef${AOs::Ship} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/examples/arm-cm/game_efm32-slstk3401a/tunnel.c b/examples/arm-cm/game_efm32-slstk3401a/tunnel.c index 50aa527d..c9e2fce9 100644 --- a/examples/arm-cm/game_efm32-slstk3401a/tunnel.c +++ b/examples/arm-cm/game_efm32-slstk3401a/tunnel.c @@ -1,48 +1,48 @@ -/*$file${.::tunnel.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* -* Model: game.qm -* File: ${.::tunnel.c} -* -* This code has been generated by QM 5.2.4 . -* DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. -* -* SPDX-License-Identifier: GPL-3.0-or-later -* -* This generated code is open source software: you can redistribute it under -* the terms of the GNU General Public License as published by the Free -* Software Foundation. -* -* This code is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -* more details. -* -* NOTE: -* Alternatively, this generated code may be distributed under the terms -* of Quantum Leaps commercial licenses, which expressly supersede the GNU -* General Public License and are specifically designed for licensees -* interested in retaining the proprietary status of their code. -* -* Contact information: -* -* -*/ -/*$endhead${.::tunnel.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$file${.::tunnel.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// +// Model: game.qm +// File: ${.::tunnel.c} +// +// This code has been generated by QM 5.3.0 . +// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. +// +// SPDX-License-Identifier: GPL-3.0-or-later +// +// This generated code is open source software: you can redistribute it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation. +// +// This code is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// NOTE: +// Alternatively, this generated code may be distributed under the terms +// of Quantum Leaps commercial licenses, which expressly supersede the GNU +// General Public License and are specifically designed for licensees +// interested in retaining the proprietary status of their code. +// +// Contact information: +// +// +// +//$endhead${.::tunnel.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ #include "qpc.h" #include "bsp.h" #include "game.h" Q_DEFINE_THIS_FILE -/* local objects -----------------------------------------------------------*/ -/*$declare${AOs::Tunnel} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +// local objects ----------------------------------------------------------- +//$declare${AOs::Tunnel} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/*${AOs::Tunnel} ...........................................................*/ +//${AOs::Tunnel} ............................................................. typedef struct Tunnel { -/* protected: */ +// protected: QActive super; -/* private: */ +// private: QTimeEvt blinkTimeEvt; QTimeEvt screenTimeEvt; QHsm * mines[GAME_MINES_MAX]; @@ -55,20 +55,20 @@ typedef struct Tunnel { uint8_t wall_thickness_bottom; uint8_t wall_gap; -/* public: */ +// public: } Tunnel; -/* private: */ +// private: static void Tunnel_advance(Tunnel * const me); static void Tunnel_plantMine(Tunnel * const me); static void Tunnel_dispatchToAllMines(Tunnel * const me, QEvt const * e); -/* public: */ +// public: static void Tunnel_ctor(Tunnel * const me); extern Tunnel Tunnel_inst; -/* protected: */ +// protected: static QState Tunnel_initial(Tunnel * const me, void const * const par); static QState Tunnel_active(Tunnel * const me, QEvt const * const e); static QState Tunnel_show_logo(Tunnel * const me, QEvt const * const e); @@ -79,54 +79,54 @@ static QState Tunnel_screen_saver(Tunnel * const me, QEvt const * const e); static QState Tunnel_screen_saver_hide(Tunnel * const me, QEvt const * const e); static QState Tunnel_screen_saver_show(Tunnel * const me, QEvt const * const e); static QState Tunnel_final(Tunnel * const me, QEvt const * const e); -/*$enddecl${AOs::Tunnel} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$enddecl${AOs::Tunnel} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -/* Public-scope objects ----------------------------------------------------*/ -/*$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* Check for the minimum required QP version */ -#if (QP_VERSION < 700U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) -#error qpc version 7.0.0 or higher required +// Public-scope objects ---------------------------------------------------- +//$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// Check for the minimum required QP version +#if (QP_VERSION < 730U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) +#error qpc version 7.3.0 or higher required #endif -/*$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -/*$define${Shared::AO_Tunnel} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//$define${Shared::AO_Tunnel} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/*${Shared::AO_Tunnel} .....................................................*/ +//${Shared::AO_Tunnel} ....................................................... QActive * const AO_Tunnel = &Tunnel_inst.super; -/*$enddef${Shared::AO_Tunnel} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$enddef${Shared::AO_Tunnel} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -/* Active object definition ================================================*/ -/*$define${Shared::Tunnel_ctor_call} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +// Active object definition ================================================ +//$define${Shared::Tunnel_ctor_call} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/*${Shared::Tunnel_ctor_call} ..............................................*/ +//${Shared::Tunnel_ctor_call} ................................................ void Tunnel_ctor_call(void) { Tunnel_ctor(&Tunnel_inst); } -/*$enddef${Shared::Tunnel_ctor_call} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*$define${AOs::Tunnel} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//$enddef${Shared::Tunnel_ctor_call} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +//$define${AOs::Tunnel} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/*${AOs::Tunnel} ...........................................................*/ +//${AOs::Tunnel} ............................................................. Tunnel Tunnel_inst; -/*${AOs::Tunnel::advance} ..................................................*/ +//${AOs::Tunnel::advance} .................................................... static void Tunnel_advance(Tunnel * const me) { uint32_t rnd; rnd = (BSP_random() & 0xFFU); - /* reduce the top wall thickness 18.75% of the time */ + // reduce the top wall thickness 18.75% of the time if ((rnd < 48U) && (me->wall_thickness_top > 0U)) { --me->wall_thickness_top; } - /* reduce the bottom wall thickness 18.75% of the time */ + // reduce the bottom wall thickness 18.75% of the time if ((rnd > 208U) && (me->wall_thickness_bottom > 0U)) { --me->wall_thickness_bottom; } rnd = (BSP_random() & 0xFFU); - /* grow the bottom wall thickness 19.14% of the time */ + // grow the bottom wall thickness 19.14% of the time if ((rnd < 49U) && ((GAME_TUNNEL_HEIGHT - me->wall_thickness_top @@ -135,7 +135,7 @@ static void Tunnel_advance(Tunnel * const me) { ++me->wall_thickness_bottom; } - /* grow the top wall thickness 19.14% of the time */ + // grow the top wall thickness 19.14% of the time if ((rnd > 207U) && ((GAME_TUNNEL_HEIGHT - me->wall_thickness_top @@ -144,104 +144,102 @@ static void Tunnel_advance(Tunnel * const me) { ++me->wall_thickness_top; } - /* advance the Tunnel by 1 game step to the left - * and copy the Tunnel layer to the main frame buffer - */ + // advance the Tunnel by 1 game step to the left + // and copy the Tunnel layer to the main frame buffer BSP_advanceWalls(me->wall_thickness_top, me->wall_thickness_bottom); } -/*${AOs::Tunnel::plantMine} ................................................*/ +//${AOs::Tunnel::plantMine} .................................................. static void Tunnel_plantMine(Tunnel * const me) { uint32_t rnd = (BSP_random() & 0xFFU); if (me->last_mine_x > 0U) { - --me->last_mine_x; /* shift the last Mine 1 position to the left */ + --me->last_mine_x; // shift the last Mine 1 position to the left } - /* last mine far enough? */ + // last mine far enough? if ((me->last_mine_x + GAME_MINES_DIST_MIN < GAME_TUNNEL_WIDTH) - && (rnd < 8U)) /* place the mines only 5% of the time */ + && (rnd < 8U)) // place the mines only 5% of the time { uint8_t n; - for (n = 0U; n < Q_DIM(me->mines); ++n) { /*look for disabled mines */ + for (n = 0U; n < Q_DIM(me->mines); ++n) { //look for disabled mines if (me->mines[n] == (QHsm *)0) { break; } } - if (n < Q_DIM(me->mines)) { /* a disabled Mine found? */ - ObjectPosEvt ope; /* event to dispatch to the Mine */ + if (n < Q_DIM(me->mines)) { // a disabled Mine found? rnd = (BSP_random() & 0xFFFFU); - if ((rnd & 1U) == 0U) { /* choose the type of the mine */ + if ((rnd & 1U) == 0U) { // choose the type of the mine me->mines[n] = me->mine1_pool[n]; } else { me->mines[n] = me->mine2_pool[n]; } - /* new Mine is planted by the end of the tunnel */ + // new Mine is planted by the end of the tunnel me->last_mine_x = GAME_TUNNEL_WIDTH - 8U; - /* choose a random y-position for the Mine in the Tunnel */ + // choose a random y-position for the Mine in the Tunnel rnd %= (GAME_TUNNEL_HEIGHT - me->wall_thickness_top - me->wall_thickness_bottom - 4U); me->last_mine_y = (uint8_t)(me->wall_thickness_top + 2U + rnd); - ope.super.sig = MINE_PLANT_SIG; + ObjectPosEvt ope; // event to dispatch to the Mine + QEvt_ctor(&ope.super, MINE_PLANT_SIG); ope.x = me->last_mine_x; ope.y = me->last_mine_y; - /* direct dispatch */ - QHSM_DISPATCH(me->mines[n], (QEvt *)&ope, me->super.prio); + // direct dispatch + QASM_DISPATCH(me->mines[n], &ope.super, me->super.prio); } } } -/*${AOs::Tunnel::dispatchToAllMines} .......................................*/ +//${AOs::Tunnel::dispatchToAllMines} ......................................... static void Tunnel_dispatchToAllMines(Tunnel * const me, QEvt const * e) { - uint8_t n; - for (n = 0U; n < GAME_MINES_MAX; ++n) { - if (me->mines[n] != (QHsm *)0) { /* is the mine used? */ - QHSM_DISPATCH(me->mines[n], e, me->super.prio); + for (uint8_t n = 0U; n < GAME_MINES_MAX; ++n) { + if (me->mines[n] != (QHsm *)0) { // is the mine used? + QASM_DISPATCH(me->mines[n], e, me->super.prio); } } } -/*${AOs::Tunnel::ctor} .....................................................*/ +//${AOs::Tunnel::ctor} ....................................................... static void Tunnel_ctor(Tunnel * const me) { uint8_t n; QActive_ctor(&me->super, Q_STATE_CAST(&Tunnel_initial)); QTimeEvt_ctorX(&me->blinkTimeEvt, &me->super, BLINK_TIMEOUT_SIG, 0U); QTimeEvt_ctorX(&me->screenTimeEvt, &me->super, SCREEN_TIMEOUT_SIG, 0U); for (n = 0; n < GAME_MINES_MAX; ++n) { - me->mine1_pool[n] = Mine1_ctor_call(n); /* instantiate Mine1 */ - me->mine2_pool[n] = Mine2_ctor_call(n); /* instantiate Mine2 */ - me->mines[n] = (QHsm *)0; /* mine 'n' is unused */ + me->mine1_pool[n] = Mine1_ctor_call(n); // instantiate Mine1 + me->mine2_pool[n] = Mine2_ctor_call(n); // instantiate Mine2 + me->mines[n] = (QHsm *)0; // mine 'n' is unused } - me->last_mine_x = 0; /* the last mine at the right edge of the tunnel */ + me->last_mine_x = 0; // the last mine at the right edge of the tunnel me->last_mine_y = 0; } -/*${AOs::Tunnel::SM} .......................................................*/ +//${AOs::Tunnel::SM} ......................................................... static QState Tunnel_initial(Tunnel * const me, void const * const par) { - /*${AOs::Tunnel::SM::initial} */ + //${AOs::Tunnel::SM::initial} uint8_t n; for (n = 0U; n < GAME_MINES_MAX; ++n) { - QHSM_INIT(me->mine1_pool[n], (void *)0, me->super.prio); - QHSM_INIT(me->mine2_pool[n], (void *)0, me->super.prio); + QASM_INIT(me->mine1_pool[n], (void *)0, me->super.prio); + QASM_INIT(me->mine2_pool[n], (void *)0, me->super.prio); } - BSP_randomSeed(1234); /* seed the pseudo-random generator */ + BSP_randomSeed(1234); // seed the pseudo-random generator QActive_subscribe(&me->super, TIME_TICK_SIG); QActive_subscribe(&me->super, PLAYER_TRIGGER_SIG); QActive_subscribe(&me->super, PLAYER_QUIT_SIG); - /* object dictionaries... */ + // object dictionaries... QS_OBJ_DICTIONARY(&Tunnel_inst.blinkTimeEvt); QS_OBJ_DICTIONARY(&Tunnel_inst.screenTimeEvt); - /* local signals... */ + // local signals... QS_SIG_DICTIONARY(BLINK_TIMEOUT_SIG, me); QS_SIG_DICTIONARY(SCREEN_TIMEOUT_SIG, me); QS_SIG_DICTIONARY(SHIP_IMG_SIG, me); @@ -251,7 +249,7 @@ static QState Tunnel_initial(Tunnel * const me, void const * const par) { QS_SIG_DICTIONARY(EXPLOSION_SIG, me); QS_SIG_DICTIONARY(SCORE_SIG, me); - (void)par; /* unused parameter */ + (void)par; // unused parameter QS_FUN_DICTIONARY(&Tunnel_active); QS_FUN_DICTIONARY(&Tunnel_show_logo); @@ -266,11 +264,11 @@ static QState Tunnel_initial(Tunnel * const me, void const * const par) { return Q_TRAN(&Tunnel_show_logo); } -/*${AOs::Tunnel::SM::active} ...............................................*/ +//${AOs::Tunnel::SM::active} ................................................. static QState Tunnel_active(Tunnel * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${AOs::Tunnel::SM::active::MINE_DISABLED} */ + //${AOs::Tunnel::SM::active::MINE_DISABLED} case MINE_DISABLED_SIG: { Q_ASSERT((Q_EVT_CAST(MineEvt)->id < GAME_MINES_MAX) && (me->mines[Q_EVT_CAST(MineEvt)->id] != (QHsm *)0)); @@ -278,7 +276,7 @@ static QState Tunnel_active(Tunnel * const me, QEvt const * const e) { status_ = Q_HANDLED(); break; } - /*${AOs::Tunnel::SM::active::PLAYER_QUIT} */ + //${AOs::Tunnel::SM::active::PLAYER_QUIT} case PLAYER_QUIT_SIG: { status_ = Q_TRAN(&Tunnel_final); break; @@ -291,11 +289,11 @@ static QState Tunnel_active(Tunnel * const me, QEvt const * const e) { return status_; } -/*${AOs::Tunnel::SM::active::show_logo} ....................................*/ +//${AOs::Tunnel::SM::active::show_logo} ...................................... static QState Tunnel_show_logo(Tunnel * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${AOs::Tunnel::SM::active::show_logo} */ + //${AOs::Tunnel::SM::active::show_logo} case Q_ENTRY_SIG: { QTimeEvt_armX(&me->blinkTimeEvt, BSP_TICKS_PER_SEC/2U, BSP_TICKS_PER_SEC/2U); @@ -311,28 +309,28 @@ static QState Tunnel_show_logo(Tunnel * const me, QEvt const * const e) { status_ = Q_HANDLED(); break; } - /*${AOs::Tunnel::SM::active::show_logo} */ + //${AOs::Tunnel::SM::active::show_logo} case Q_EXIT_SIG: { QTimeEvt_disarm(&me->blinkTimeEvt); QTimeEvt_disarm(&me->screenTimeEvt); status_ = Q_HANDLED(); break; } - /*${AOs::Tunnel::SM::active::show_logo::SCREEN_TIMEOUT} */ + //${AOs::Tunnel::SM::active::show_logo::SCREEN_TIMEOUT} case SCREEN_TIMEOUT_SIG: { status_ = Q_TRAN(&Tunnel_demo); break; } - /*${AOs::Tunnel::SM::active::show_logo::BLINK_TIMEOUT} */ + //${AOs::Tunnel::SM::active::show_logo::BLINK_TIMEOUT} case BLINK_TIMEOUT_SIG: { - me->blink_ctr ^= 1U; /* toggle the blink counter */ - /*${AOs::Tunnel::SM::active::show_logo::BLINK_TIMEOUT::[me->blink_ctr==0U]} */ + me->blink_ctr ^= 1U; // toggle the blink counter + //${AOs::Tunnel::SM::active::show_logo::BLINK_TIMEOUT::[me->blink_ctr==0U]} if (me->blink_ctr == 0U) { BSP_paintString(24U + 8U*6U, (GAME_TUNNEL_HEIGHT / 2U) - 8U, "LeAps"); BSP_updateScreen(); status_ = Q_HANDLED(); } - /*${AOs::Tunnel::SM::active::show_logo::BLINK_TIMEOUT::[else]} */ + //${AOs::Tunnel::SM::active::show_logo::BLINK_TIMEOUT::[else]} else { BSP_paintString(24U + 8U*6U, (GAME_TUNNEL_HEIGHT / 2U) - 8U, "LeaPs"); BSP_updateScreen(); @@ -348,53 +346,53 @@ static QState Tunnel_show_logo(Tunnel * const me, QEvt const * const e) { return status_; } -/*${AOs::Tunnel::SM::active::demo} .........................................*/ +//${AOs::Tunnel::SM::active::demo} ........................................... static QState Tunnel_demo(Tunnel * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${AOs::Tunnel::SM::active::demo} */ + //${AOs::Tunnel::SM::active::demo} case Q_ENTRY_SIG: { - me->last_mine_x = 0U; /* last mine at right edge of the tunnel */ + me->last_mine_x = 0U; // last mine at right edge of the tunnel me->last_mine_y = 0U; - /* set the tunnel properties... */ + // set the tunnel properties... me->wall_thickness_top = 0U; me->wall_thickness_bottom = 0U; me->wall_gap = GAME_WALLS_GAP_Y; - /* clear the tunnel walls */ + // clear the tunnel walls BSP_clearWalls(); QTimeEvt_armX(&me->blinkTimeEvt, BSP_TICKS_PER_SEC/2U, - BSP_TICKS_PER_SEC/2U); /* every 1/2 sec */ + BSP_TICKS_PER_SEC/2U); // every 1/2 sec QTimeEvt_armX(&me->screenTimeEvt, BSP_TICKS_PER_SEC*20U, 0U); - me->blink_ctr = 0U; /* init the blink counter */ + me->blink_ctr = 0U; // init the blink counter status_ = Q_HANDLED(); break; } - /*${AOs::Tunnel::SM::active::demo} */ + //${AOs::Tunnel::SM::active::demo} case Q_EXIT_SIG: { QTimeEvt_disarm(&me->blinkTimeEvt); QTimeEvt_disarm(&me->screenTimeEvt); status_ = Q_HANDLED(); break; } - /*${AOs::Tunnel::SM::active::demo::BLINK_TIMEOUT} */ + //${AOs::Tunnel::SM::active::demo::BLINK_TIMEOUT} case BLINK_TIMEOUT_SIG: { - me->blink_ctr ^= 1U; /* toggle the blink cunter */ + me->blink_ctr ^= 1U; // toggle the blink cunter status_ = Q_HANDLED(); break; } - /*${AOs::Tunnel::SM::active::demo::SCREEN_TIMEOUT} */ + //${AOs::Tunnel::SM::active::demo::SCREEN_TIMEOUT} case SCREEN_TIMEOUT_SIG: { status_ = Q_TRAN(&Tunnel_screen_saver); break; } - /*${AOs::Tunnel::SM::active::demo::TIME_TICK} */ + //${AOs::Tunnel::SM::active::demo::TIME_TICK} case TIME_TICK_SIG: { Tunnel_advance(me); if (me->blink_ctr != 0U) { - /* add the text bitmap into the frame buffer */ + // add the text bitmap into the frame buffer BSP_paintString((GAME_TUNNEL_WIDTH - 10U*6U)/2U, (GAME_TUNNEL_HEIGHT - 4U)/2U, "Press BTN0"); @@ -403,7 +401,7 @@ static QState Tunnel_demo(Tunnel * const me, QEvt const * const e) { status_ = Q_HANDLED(); break; } - /*${AOs::Tunnel::SM::active::demo::PLAYER_TRIGGER} */ + //${AOs::Tunnel::SM::active::demo::PLAYER_TRIGGER} case PLAYER_TRIGGER_SIG: { status_ = Q_TRAN(&Tunnel_playing); break; @@ -416,29 +414,28 @@ static QState Tunnel_demo(Tunnel * const me, QEvt const * const e) { return status_; } -/*${AOs::Tunnel::SM::active::playing} ......................................*/ +//${AOs::Tunnel::SM::active::playing} ........................................ static QState Tunnel_playing(Tunnel * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${AOs::Tunnel::SM::active::playing} */ + //${AOs::Tunnel::SM::active::playing} case Q_ENTRY_SIG: { - static QEvt const takeoff = { TAKE_OFF_SIG, 0U, 0U }; + static QEvt const takeoff = QEVT_INITIALIZER(TAKE_OFF_SIG); me->wall_gap = GAME_WALLS_GAP_Y; - QACTIVE_POST(AO_Ship, &takeoff, me); /* post the TAKEOFF sig */ + QACTIVE_POST(AO_Ship, &takeoff, me); // post the TAKEOFF sig status_ = Q_HANDLED(); break; } - /*${AOs::Tunnel::SM::active::playing} */ + //${AOs::Tunnel::SM::active::playing} case Q_EXIT_SIG: { - QEvt recycle; - recycle.sig = MINE_RECYCLE_SIG; - Tunnel_dispatchToAllMines(me, &recycle); /* recycle all Mines */ + static QEvt const recycle = QEVT_INITIALIZER(MINE_RECYCLE_SIG); + Tunnel_dispatchToAllMines(me, &recycle); // recycle all Mines status_ = Q_HANDLED(); break; } - /*${AOs::Tunnel::SM::active::playing::TIME_TICK} */ + //${AOs::Tunnel::SM::active::playing::TIME_TICK} case TIME_TICK_SIG: { - /* render this frame on the display */ + // render this frame on the display BSP_updateScreen(); Tunnel_advance(me); Tunnel_plantMine(me); @@ -446,39 +443,39 @@ static QState Tunnel_playing(Tunnel * const me, QEvt const * const e) { status_ = Q_HANDLED(); break; } - /*${AOs::Tunnel::SM::active::playing::SHIP_IMG} */ + //${AOs::Tunnel::SM::active::playing::SHIP_IMG} case SHIP_IMG_SIG: { uint8_t x = Q_EVT_CAST(ObjectImageEvt)->x; int8_t y = Q_EVT_CAST(ObjectImageEvt)->y; uint8_t bmp = Q_EVT_CAST(ObjectImageEvt)->bmp; - /* did the Ship/Missile hit the tunnel wall? */ + // did the Ship/Missile hit the tunnel wall? if (BSP_isWallHit(bmp, x, y)) { - static QEvt const hit = { HIT_WALL_SIG, 0U, 0U }; + static QEvt const hit = QEVT_INITIALIZER(HIT_WALL_SIG); QACTIVE_POST(AO_Ship, &hit, me); } BSP_paintBitmap(x, y, bmp); - Tunnel_dispatchToAllMines(me, e); /* let Mines check for hits */ + Tunnel_dispatchToAllMines(me, e); // let Mines check for hits status_ = Q_HANDLED(); break; } - /*${AOs::Tunnel::SM::active::playing::MISSILE_IMG} */ + //${AOs::Tunnel::SM::active::playing::MISSILE_IMG} case MISSILE_IMG_SIG: { uint8_t x = Q_EVT_CAST(ObjectImageEvt)->x; int8_t y = Q_EVT_CAST(ObjectImageEvt)->y; uint8_t bmp = Q_EVT_CAST(ObjectImageEvt)->bmp; - /* did the Ship/Missile hit the tunnel wall? */ + // did the Ship/Missile hit the tunnel wall? if (BSP_isWallHit(bmp, x, y)) { - static QEvt const hit = { HIT_WALL_SIG, 0U, 0U }; + static QEvt const hit = QEVT_INITIALIZER(HIT_WALL_SIG); QACTIVE_POST(AO_Missile, &hit, me); } BSP_paintBitmap(x, y, bmp); - Tunnel_dispatchToAllMines(me, e); /* let Mines check for hits */ + Tunnel_dispatchToAllMines(me, e); // let Mines check for hits status_ = Q_HANDLED(); break; } - /*${AOs::Tunnel::SM::active::playing::MINE_IMG} */ + //${AOs::Tunnel::SM::active::playing::MINE_IMG} case MINE_IMG_SIG: { BSP_paintBitmap(Q_EVT_CAST(ObjectImageEvt)->x, Q_EVT_CAST(ObjectImageEvt)->y, @@ -486,7 +483,7 @@ static QState Tunnel_playing(Tunnel * const me, QEvt const * const e) { status_ = Q_HANDLED(); break; } - /*${AOs::Tunnel::SM::active::playing::EXPLOSION} */ + //${AOs::Tunnel::SM::active::playing::EXPLOSION} case EXPLOSION_SIG: { BSP_paintBitmap(Q_EVT_CAST(ObjectImageEvt)->x, Q_EVT_CAST(ObjectImageEvt)->y, @@ -494,12 +491,11 @@ static QState Tunnel_playing(Tunnel * const me, QEvt const * const e) { status_ = Q_HANDLED(); break; } - /*${AOs::Tunnel::SM::active::playing::SCORE} */ + //${AOs::Tunnel::SM::active::playing::SCORE} case SCORE_SIG: { BSP_updateScore(Q_EVT_CAST(ScoreEvt)->score); - /* increase difficulty of the game: - * the tunnel gets narrower as the score goes up - */ + // increase difficulty of the game: + // the tunnel gets narrower as the score goes up me->wall_gap = (uint8_t)(GAME_WALLS_GAP_Y - Q_EVT_CAST(ScoreEvt)->score/100U); if (me->wall_gap < GAME_WALLS_MIN_GAP_Y) { @@ -508,7 +504,7 @@ static QState Tunnel_playing(Tunnel * const me, QEvt const * const e) { status_ = Q_HANDLED(); break; } - /*${AOs::Tunnel::SM::active::playing::GAME_OVER} */ + //${AOs::Tunnel::SM::active::playing::GAME_OVER} case GAME_OVER_SIG: { BSP_clearWalls(); BSP_updateScore(Q_EVT_CAST(ScoreEvt)->score); @@ -524,14 +520,14 @@ static QState Tunnel_playing(Tunnel * const me, QEvt const * const e) { return status_; } -/*${AOs::Tunnel::SM::active::game_over} ....................................*/ +//${AOs::Tunnel::SM::active::game_over} ...................................... static QState Tunnel_game_over(Tunnel * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${AOs::Tunnel::SM::active::game_over} */ + //${AOs::Tunnel::SM::active::game_over} case Q_ENTRY_SIG: { QTimeEvt_armX(&me->blinkTimeEvt, BSP_TICKS_PER_SEC/2U, - BSP_TICKS_PER_SEC/2U); /* every 1/2 sec */ + BSP_TICKS_PER_SEC/2U); // every 1/2 sec QTimeEvt_armX(&me->screenTimeEvt, BSP_TICKS_PER_SEC*5U, 0U); me->blink_ctr = 0U; BSP_paintString((GAME_TUNNEL_WIDTH - 6U * 9U) / 2U, @@ -541,17 +537,17 @@ static QState Tunnel_game_over(Tunnel * const me, QEvt const * const e) { status_ = Q_HANDLED(); break; } - /*${AOs::Tunnel::SM::active::game_over} */ + //${AOs::Tunnel::SM::active::game_over} case Q_EXIT_SIG: { QTimeEvt_disarm(&me->blinkTimeEvt); QTimeEvt_disarm(&me->screenTimeEvt); - BSP_updateScore(0); /* update the score on the display */ + BSP_updateScore(0); // update the score on the display status_ = Q_HANDLED(); break; } - /*${AOs::Tunnel::SM::active::game_over::BLINK_TIMEOUT} */ + //${AOs::Tunnel::SM::active::game_over::BLINK_TIMEOUT} case BLINK_TIMEOUT_SIG: { - me->blink_ctr ^= 1U; /* toggle the blink counter */ + me->blink_ctr ^= 1U; // toggle the blink counter BSP_paintString((GAME_TUNNEL_WIDTH - 6U*9U) / 2U, (GAME_TUNNEL_HEIGHT / 2U) - 4U, ((me->blink_ctr == 0U) @@ -561,7 +557,7 @@ static QState Tunnel_game_over(Tunnel * const me, QEvt const * const e) { status_ = Q_HANDLED(); break; } - /*${AOs::Tunnel::SM::active::game_over::SCREEN_TIMEOUT} */ + //${AOs::Tunnel::SM::active::game_over::SCREEN_TIMEOUT} case SCREEN_TIMEOUT_SIG: { status_ = Q_TRAN(&Tunnel_demo); break; @@ -574,16 +570,16 @@ static QState Tunnel_game_over(Tunnel * const me, QEvt const * const e) { return status_; } -/*${AOs::Tunnel::SM::active::screen_saver} .................................*/ +//${AOs::Tunnel::SM::active::screen_saver} ................................... static QState Tunnel_screen_saver(Tunnel * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${AOs::Tunnel::SM::active::screen_saver::initial} */ + //${AOs::Tunnel::SM::active::screen_saver::initial} case Q_INIT_SIG: { status_ = Q_TRAN(&Tunnel_screen_saver_hide); break; } - /*${AOs::Tunnel::SM::active::screen_saver::PLAYER_TRIGGER} */ + //${AOs::Tunnel::SM::active::screen_saver::PLAYER_TRIGGER} case PLAYER_TRIGGER_SIG: { status_ = Q_TRAN(&Tunnel_demo); break; @@ -596,25 +592,25 @@ static QState Tunnel_screen_saver(Tunnel * const me, QEvt const * const e) { return status_; } -/*${AOs::Tunnel::SM::active::screen_saver::screen_saver_hide} ..............*/ +//${AOs::Tunnel::SM::active::screen_saver::screen_saver_hide} ................ static QState Tunnel_screen_saver_hide(Tunnel * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${AOs::Tunnel::SM::active::screen_saver::screen_saver_hide} */ + //${AOs::Tunnel::SM::active::screen_saver::screen_saver_hide} case Q_ENTRY_SIG: { - BSP_displayOff(); /* power down the display */ + BSP_displayOff(); // power down the display QTimeEvt_armX(&me->screenTimeEvt, BSP_TICKS_PER_SEC*3U, 0U); status_ = Q_HANDLED(); break; } - /*${AOs::Tunnel::SM::active::screen_saver::screen_saver_hide} */ + //${AOs::Tunnel::SM::active::screen_saver::screen_saver_hide} case Q_EXIT_SIG: { QTimeEvt_disarm(&me->screenTimeEvt); - BSP_displayOn(); /* power up the display */ + BSP_displayOn(); // power up the display status_ = Q_HANDLED(); break; } - /*${AOs::Tunnel::SM::active::screen_saver::screen_saver_hid~::SCREEN_TIMEOUT} */ + //${AOs::Tunnel::SM::active::screen_saver::screen_saver_hid~::SCREEN_TIMEOUT} case SCREEN_TIMEOUT_SIG: { status_ = Q_TRAN(&Tunnel_screen_saver_show); break; @@ -627,14 +623,14 @@ static QState Tunnel_screen_saver_hide(Tunnel * const me, QEvt const * const e) return status_; } -/*${AOs::Tunnel::SM::active::screen_saver::screen_saver_show} ..............*/ +//${AOs::Tunnel::SM::active::screen_saver::screen_saver_show} ................ static QState Tunnel_screen_saver_show(Tunnel * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${AOs::Tunnel::SM::active::screen_saver::screen_saver_show} */ + //${AOs::Tunnel::SM::active::screen_saver::screen_saver_show} case Q_ENTRY_SIG: { uint32_t rnd = BSP_random(); - /* clear the screen frame buffer */ + // clear the screen frame buffer BSP_clearFB(); BSP_paintString((uint8_t)(rnd % (GAME_TUNNEL_WIDTH - 10U*6U)), (uint8_t) (rnd % (GAME_TUNNEL_HEIGHT - 8U)), @@ -644,7 +640,7 @@ static QState Tunnel_screen_saver_show(Tunnel * const me, QEvt const * const e) status_ = Q_HANDLED(); break; } - /*${AOs::Tunnel::SM::active::screen_saver::screen_saver_show} */ + //${AOs::Tunnel::SM::active::screen_saver::screen_saver_show} case Q_EXIT_SIG: { QTimeEvt_disarm(&me->screenTimeEvt); BSP_clearFB(); @@ -652,7 +648,7 @@ static QState Tunnel_screen_saver_show(Tunnel * const me, QEvt const * const e) status_ = Q_HANDLED(); break; } - /*${AOs::Tunnel::SM::active::screen_saver::screen_saver_sho~::SCREEN_TIMEOUT} */ + //${AOs::Tunnel::SM::active::screen_saver::screen_saver_sho~::SCREEN_TIMEOUT} case SCREEN_TIMEOUT_SIG: { status_ = Q_TRAN(&Tunnel_screen_saver_hide); break; @@ -665,16 +661,16 @@ static QState Tunnel_screen_saver_show(Tunnel * const me, QEvt const * const e) return status_; } -/*${AOs::Tunnel::SM::final} ................................................*/ +//${AOs::Tunnel::SM::final} .................................................. static QState Tunnel_final(Tunnel * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${AOs::Tunnel::SM::final} */ + //${AOs::Tunnel::SM::final} case Q_ENTRY_SIG: { - /* clear the screen */ + // clear the screen BSP_clearFB(); BSP_updateScreen(); - QF_stop(); /* stop QF and cleanup */ + QF_stop(); // stop QF and cleanup status_ = Q_HANDLED(); break; } @@ -685,4 +681,4 @@ static QState Tunnel_final(Tunnel * const me, QEvt const * const e) { } return status_; } -/*$enddef${AOs::Tunnel} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$enddef${AOs::Tunnel} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/examples/arm-cm/game_efm32-slstk3401a/win32-gui/bsp.c b/examples/arm-cm/game_efm32-slstk3401a/win32-gui/bsp.c deleted file mode 100644 index c9c86982..00000000 --- a/examples/arm-cm/game_efm32-slstk3401a/win32-gui/bsp.c +++ /dev/null @@ -1,871 +0,0 @@ -/***************************************************************************** -* Product: "Fly 'n' Shoot" game example, EFM32-SLSTK3401A, Win32-GUI -* Last updated for version 6.9.3 -* Last updated on 2021-03-03 -* -* Q u a n t u m L e a P s -* ------------------------ -* Modern Embedded Software -* -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* -* -*****************************************************************************/ -#include "qpc.h" -#include "game.h" -#include "bsp.h" - -#include "qwin_gui.h" /* QWIN GUI */ -#include "resource.h" /* GUI resource IDs generated by the resource editior */ - -#include "safe_std.h" /* portable "safe" / facilities */ - -Q_DEFINE_THIS_FILE - -/* local variables ---------------------------------------------------------*/ -static HINSTANCE l_hInst; /* this application instance */ -static HWND l_hWnd; /* main window handle */ -static LPSTR l_cmdLine; /* the command line string */ - -static GraphicDisplay l_lcd; /* LCD display on EFM32-SLSTK3401A */ -static SegmentDisplay l_userLED0; /* USER LED0 on EFM32-SLSTK3401A */ -static SegmentDisplay l_userLED1; /* USER LED1 on EFM32-SLSTK3401A */ -static SegmentDisplay l_scoreBoard; /* segment display for the score */ -static OwnerDrawnButton l_userBtn0; /* USER Button0 on EFM32-SLSTK3401A */ -static OwnerDrawnButton l_userBtn1; /* USER Button1 on EFM32-SLSTK3401A */ - -/* (R,G,B) colors for the LCD display */ -static BYTE const c_onColor[3] = { 0x07U, 0x07U, 0x07U }; /* dark grey */ -static BYTE const c_offColor[3] = { 0xA0U, 0xA0U, 0xA0U }; /* light grey */ - -/* LCD geometry and frame buffer */ -static uint32_t l_fb[BSP_SCREEN_HEIGHT + 1][BSP_SCREEN_WIDTH / 32U]; - -/* the walls buffer */ -static uint32_t l_walls[GAME_TUNNEL_HEIGHT + 1][BSP_SCREEN_WIDTH / 32U]; - -static unsigned l_rnd; /* random seed */ - -static void paintBits(uint8_t x, uint8_t y, uint8_t const *bits, uint8_t h); -static void paintBitsClear(uint8_t x, uint8_t y, - uint8_t const *bits, uint8_t h); -#ifdef Q_SPY - enum QSUserRecords { - PLAYER_TRIGGER = QS_USER, - COMMAND_STAT - }; - - /* QSpy source IDs */ - static QSpyId const l_clock_tick = { 0U }; - static QSpyId const l_player = { 0U }; -#endif - -/* Local functions ---------------------------------------------------------*/ -static LRESULT CALLBACK WndProc(HWND hWnd, UINT iMsg, - WPARAM wParam, LPARAM lParam); - -/*..........................................................................*/ -static void playerTrigger(void) { - static QEvt const fireEvt = { PLAYER_TRIGGER_SIG, 0U, 0U }; - QACTIVE_PUBLISH(&fireEvt, &l_player); -} - -/*--------------------------------------------------------------------------*/ -void QF_onStartup(void) { - QF_setTickRate(BSP_TICKS_PER_SEC, 30); /* set the desired tick rate */ -} -/*..........................................................................*/ -void QF_onCleanup(void) { -} -/*..........................................................................*/ -void QF_onClockTick(void) { - static QEvt const tickEvt = { TIME_TICK_SIG, 0U, 0U }; - QTIMEEVT_TICK_X(0U, &l_clock_tick); /* process time events for rate 0 */ - QACTIVE_PUBLISH(&tickEvt, &l_clock_tick); /* publish the tick event */ - - QS_RX_INPUT(); /* handle the QS-RX input */ - QS_OUTPUT(); /* handle the QS output */ -} - -/*..........................................................................*/ -Q_NORETURN Q_onAssert(char const * const module, int_t const loc) { - char message[80]; - QF_stop(); /* stop ticking */ - - QS_ASSERTION(module, loc, 10000U); /* report assertion to QS */ - SNPRINTF_S(message, Q_DIM(message) - 1, - "Assertion failed in module %s location %d", module, loc); - MessageBox(l_hWnd, message, "!!! ASSERTION !!!", - MB_OK | MB_ICONEXCLAMATION | MB_APPLMODAL); - PostQuitMessage(-1); -} - -/*..........................................................................*/ -void BSP_init(void) { - if (QS_INIT(l_cmdLine) == 0U) { /* QS initialization failed? */ - MessageBox(l_hWnd, - "Cannot connect to QSPY via TCP/IP\n" - "Please make sure that 'qspy -t' is running", - "QS_INIT() Error", - MB_OK | MB_ICONEXCLAMATION | MB_APPLMODAL); - } - - /* send the QS dictionaries... */ - QS_OBJ_DICTIONARY(&l_clock_tick); - QS_OBJ_DICTIONARY(&l_player); - QS_USR_DICTIONARY(PLAYER_TRIGGER); - - /* setup the QS filters... */ - QS_GLB_FILTER(QS_ALL_RECORDS); - QS_GLB_FILTER(-QS_QF_TICK); -} -/*..........................................................................*/ -void BSP_terminate(int16_t result) { - QF_stop(); /* stop the main QF application and the ticker thread */ - - /* cleanup all QWIN resources... */ - OwnerDrawnButton_xtor(&l_userBtn0); /* cleanup the l_userBtn0 resources */ - OwnerDrawnButton_xtor(&l_userBtn1); /* cleanup the l_userBtn1 resources */ - SegmentDisplay_xtor(&l_userLED0); /* cleanup the l_userLED0 resources */ - SegmentDisplay_xtor(&l_userLED1); /* cleanup the l_userLED1 resources */ - SegmentDisplay_xtor(&l_scoreBoard); /* cleanup the scoreBoard resources */ - GraphicDisplay_xtor(&l_lcd); /* cleanup the l_lcd resources */ - - /* end the main dialog */ - EndDialog(l_hWnd, result); -} -/*..........................................................................*/ -void BSP_updateScreen(void) { - UINT x, y; - - /* turn LED1 on */ - SegmentDisplay_setSegment(&l_userLED1, 0U, 1U); - - /* map the LCD pixels to the GraphicDisplay pixels... */ - for (y = 0; y < BSP_SCREEN_HEIGHT; ++y) { - for (x = 0; x < BSP_SCREEN_WIDTH; ++x) { - uint32_t bits = l_fb[y][x >> 5]; - if ((bits & (1U << (x & 0x1FU))) != 0U) { - GraphicDisplay_setPixel(&l_lcd, x, y, c_onColor); - } - else { - GraphicDisplay_clearPixel(&l_lcd, x, y); - } - } - } - - GraphicDisplay_redraw(&l_lcd); /* redraw the updated display */ - - /* turn LED1 off */ - SegmentDisplay_setSegment(&l_userLED1, 0U, 0U); -} -/*..........................................................................*/ -void BSP_clearFB() { - uint_fast8_t y; - for (y = 0U; y < BSP_SCREEN_HEIGHT; ++y) { - l_fb[y][0] = 0U; - l_fb[y][1] = 0U; - l_fb[y][2] = 0U; - l_fb[y][3] = 0U; - } -} -/*..........................................................................*/ -void BSP_clearWalls() { - uint_fast8_t y; - for (y = 0U; y < GAME_TUNNEL_HEIGHT; ++y) { - l_walls[y][0] = 0U; - l_walls[y][1] = 0U; - l_walls[y][2] = 0U; - l_walls[y][3] = 0U; - } -} -/*..........................................................................*/ -bool BSP_isThrottle(void) { /* is the throttle button depressed? */ - return OwnerDrawnButton_isDepressed(&l_userBtn1) != 0; -} -/*..........................................................................*/ -void BSP_paintString(uint8_t x, uint8_t y, char const *str) { - static uint8_t const font5x7[95][7] = { - { 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U }, /* */ - { 0x04U, 0x04U, 0x04U, 0x04U, 0x00U, 0x00U, 0x04U }, /* ! */ - { 0x0AU, 0x0AU, 0x0AU, 0x00U, 0x00U, 0x00U, 0x00U }, /* " */ - { 0x0AU, 0x0AU, 0x1FU, 0x0AU, 0x1FU, 0x0AU, 0x0AU }, /* # */ - { 0x04U, 0x1EU, 0x05U, 0x0EU, 0x14U, 0x0FU, 0x04U }, /* $ */ - { 0x03U, 0x13U, 0x08U, 0x04U, 0x02U, 0x19U, 0x18U }, /* % */ - { 0x06U, 0x09U, 0x05U, 0x02U, 0x15U, 0x09U, 0x16U }, /* & */ - { 0x06U, 0x04U, 0x02U, 0x00U, 0x00U, 0x00U, 0x00U }, /* ' */ - { 0x08U, 0x04U, 0x02U, 0x02U, 0x02U, 0x04U, 0x08U }, /* ( */ - { 0x02U, 0x04U, 0x08U, 0x08U, 0x08U, 0x04U, 0x02U }, /* ) */ - { 0x00U, 0x04U, 0x15U, 0x0EU, 0x15U, 0x04U, 0x00U }, /* * */ - { 0x00U, 0x04U, 0x04U, 0x1FU, 0x04U, 0x04U, 0x00U }, /* + */ - { 0x00U, 0x00U, 0x00U, 0x00U, 0x06U, 0x04U, 0x02U }, /* , */ - { 0x00U, 0x00U, 0x00U, 0x1FU, 0x00U, 0x00U, 0x00U }, /* - */ - { 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x06U, 0x06U }, /* . */ - { 0x00U, 0x10U, 0x08U, 0x04U, 0x02U, 0x01U, 0x00U }, /* / */ - { 0x0EU, 0x11U, 0x19U, 0x15U, 0x13U, 0x11U, 0x0EU }, /* 0 */ - { 0x04U, 0x06U, 0x04U, 0x04U, 0x04U, 0x04U, 0x0EU }, /* 1 */ - { 0x0EU, 0x11U, 0x10U, 0x08U, 0x04U, 0x02U, 0x1FU }, /* 2 */ - { 0x1FU, 0x08U, 0x04U, 0x08U, 0x10U, 0x11U, 0x0EU }, /* 3 */ - { 0x08U, 0x0CU, 0x0AU, 0x09U, 0x1FU, 0x08U, 0x08U }, /* 4 */ - { 0x1FU, 0x01U, 0x0FU, 0x10U, 0x10U, 0x11U, 0x0EU }, /* 5 */ - { 0x0CU, 0x02U, 0x01U, 0x0FU, 0x11U, 0x11U, 0x0EU }, /* 6 */ - { 0x1FU, 0x10U, 0x08U, 0x04U, 0x02U, 0x02U, 0x02U }, /* 7 */ - { 0x0EU, 0x11U, 0x11U, 0x0EU, 0x11U, 0x11U, 0x0EU }, /* 8 */ - { 0x0EU, 0x11U, 0x11U, 0x1EU, 0x10U, 0x08U, 0x06U }, /* 9 */ - { 0x00U, 0x06U, 0x06U, 0x00U, 0x06U, 0x06U, 0x00U }, /* : */ - { 0x00U, 0x06U, 0x06U, 0x00U, 0x06U, 0x04U, 0x02U }, /* ; */ - { 0x08U, 0x04U, 0x02U, 0x01U, 0x02U, 0x04U, 0x08U }, /* < */ - { 0x00U, 0x00U, 0x1FU, 0x00U, 0x1FU, 0x00U, 0x00U }, /* = */ - { 0x02U, 0x04U, 0x08U, 0x10U, 0x08U, 0x04U, 0x02U }, /* > */ - { 0x0EU, 0x11U, 0x10U, 0x08U, 0x04U, 0x00U, 0x04U }, /* ? */ - { 0x0EU, 0x11U, 0x10U, 0x16U, 0x15U, 0x15U, 0x0EU }, /* @ */ - { 0x0EU, 0x11U, 0x11U, 0x11U, 0x1FU, 0x11U, 0x11U }, /* A */ - { 0x0FU, 0x11U, 0x11U, 0x0FU, 0x11U, 0x11U, 0x0FU }, /* B */ - { 0x0EU, 0x11U, 0x01U, 0x01U, 0x01U, 0x11U, 0x0EU }, /* C */ - { 0x07U, 0x09U, 0x11U, 0x11U, 0x11U, 0x09U, 0x07U }, /* D */ - { 0x1FU, 0x01U, 0x01U, 0x0FU, 0x01U, 0x01U, 0x1FU }, /* E */ - { 0x1FU, 0x01U, 0x01U, 0x0FU, 0x01U, 0x01U, 0x01U }, /* F */ - { 0x0EU, 0x11U, 0x01U, 0x1DU, 0x11U, 0x11U, 0x1EU }, /* G */ - { 0x11U, 0x11U, 0x11U, 0x1FU, 0x11U, 0x11U, 0x11U }, /* H */ - { 0x0EU, 0x04U, 0x04U, 0x04U, 0x04U, 0x04U, 0x0EU }, /* I */ - { 0x1CU, 0x08U, 0x08U, 0x08U, 0x08U, 0x09U, 0x06U }, /* J */ - { 0x11U, 0x09U, 0x05U, 0x03U, 0x05U, 0x09U, 0x11U }, /* K */ - { 0x01U, 0x01U, 0x01U, 0x01U, 0x01U, 0x01U, 0x1FU }, /* L */ - { 0x11U, 0x1BU, 0x15U, 0x15U, 0x11U, 0x11U, 0x11U }, /* M */ - { 0x11U, 0x11U, 0x13U, 0x15U, 0x19U, 0x11U, 0x11U }, /* N */ - { 0x0EU, 0x11U, 0x11U, 0x11U, 0x11U, 0x11U, 0x0EU }, /* O */ - { 0x0FU, 0x11U, 0x11U, 0x0FU, 0x01U, 0x01U, 0x01U }, /* P */ - { 0x0EU, 0x11U, 0x11U, 0x11U, 0x15U, 0x09U, 0x16U }, /* Q */ - { 0x0FU, 0x11U, 0x11U, 0x0FU, 0x05U, 0x09U, 0x11U }, /* R */ - { 0x1EU, 0x01U, 0x01U, 0x0EU, 0x10U, 0x10U, 0x0FU }, /* S */ - { 0x1FU, 0x04U, 0x04U, 0x04U, 0x04U, 0x04U, 0x04U }, /* T */ - { 0x11U, 0x11U, 0x11U, 0x11U, 0x11U, 0x11U, 0x0EU }, /* U */ - { 0x11U, 0x11U, 0x11U, 0x11U, 0x11U, 0x0AU, 0x04U }, /* V */ - { 0x11U, 0x11U, 0x11U, 0x15U, 0x15U, 0x15U, 0x0AU }, /* W */ - { 0x11U, 0x11U, 0x0AU, 0x04U, 0x0AU, 0x11U, 0x11U }, /* X */ - { 0x11U, 0x11U, 0x11U, 0x0AU, 0x04U, 0x04U, 0x04U }, /* Y */ - { 0x1FU, 0x10U, 0x08U, 0x04U, 0x02U, 0x01U, 0x1FU }, /* Z */ - { 0x0EU, 0x02U, 0x02U, 0x02U, 0x02U, 0x02U, 0x0EU }, /* [ */ - { 0x00U, 0x01U, 0x02U, 0x04U, 0x08U, 0x10U, 0x00U }, /* \ */ - { 0x0EU, 0x08U, 0x08U, 0x08U, 0x08U, 0x08U, 0x0EU }, /* ] */ - { 0x04U, 0x0AU, 0x11U, 0x00U, 0x00U, 0x00U, 0x00U }, /* ^ */ - { 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x1FU }, /* _ */ - { 0x02U, 0x04U, 0x08U, 0x00U, 0x00U, 0x00U, 0x00U }, /* ` */ - { 0x00U, 0x00U, 0x0EU, 0x10U, 0x1EU, 0x11U, 0x1EU }, /* a */ - { 0x01U, 0x01U, 0x0DU, 0x13U, 0x11U, 0x11U, 0x0FU }, /* b */ - { 0x00U, 0x00U, 0x0EU, 0x01U, 0x01U, 0x11U, 0x0EU }, /* c */ - { 0x10U, 0x10U, 0x16U, 0x19U, 0x11U, 0x11U, 0x1EU }, /* d */ - { 0x00U, 0x00U, 0x0EU, 0x11U, 0x1FU, 0x01U, 0x0EU }, /* e */ - { 0x0CU, 0x12U, 0x02U, 0x07U, 0x02U, 0x02U, 0x02U }, /* f */ - { 0x00U, 0x1EU, 0x11U, 0x11U, 0x1EU, 0x10U, 0x0EU }, /* g */ - { 0x01U, 0x01U, 0x0DU, 0x13U, 0x11U, 0x11U, 0x11U }, /* h */ - { 0x04U, 0x00U, 0x06U, 0x04U, 0x04U, 0x04U, 0x0EU }, /* i */ - { 0x08U, 0x00U, 0x0CU, 0x08U, 0x08U, 0x09U, 0x06U }, /* j */ - { 0x01U, 0x01U, 0x09U, 0x05U, 0x03U, 0x05U, 0x09U }, /* k */ - { 0x06U, 0x04U, 0x04U, 0x04U, 0x04U, 0x04U, 0x0EU }, /* l */ - { 0x00U, 0x00U, 0x0BU, 0x15U, 0x15U, 0x11U, 0x11U }, /* m */ - { 0x00U, 0x00U, 0x0DU, 0x13U, 0x11U, 0x11U, 0x11U }, /* n */ - { 0x00U, 0x00U, 0x0EU, 0x11U, 0x11U, 0x11U, 0x0EU }, /* o */ - { 0x00U, 0x00U, 0x0FU, 0x11U, 0x0FU, 0x01U, 0x01U }, /* p */ - { 0x00U, 0x00U, 0x16U, 0x19U, 0x1EU, 0x10U, 0x10U }, /* q */ - { 0x00U, 0x00U, 0x0DU, 0x13U, 0x01U, 0x01U, 0x01U }, /* r */ - { 0x00U, 0x00U, 0x0EU, 0x01U, 0x0EU, 0x10U, 0x0FU }, /* s */ - { 0x02U, 0x02U, 0x07U, 0x02U, 0x02U, 0x12U, 0x0CU }, /* t */ - { 0x00U, 0x00U, 0x11U, 0x11U, 0x11U, 0x19U, 0x16U }, /* u */ - { 0x00U, 0x00U, 0x11U, 0x11U, 0x11U, 0x0AU, 0x04U }, /* v */ - { 0x00U, 0x00U, 0x11U, 0x11U, 0x15U, 0x15U, 0x0AU }, /* w */ - { 0x00U, 0x00U, 0x11U, 0x0AU, 0x04U, 0x0AU, 0x11U }, /* x */ - { 0x00U, 0x00U, 0x11U, 0x11U, 0x1EU, 0x10U, 0x0EU }, /* y */ - { 0x00U, 0x00U, 0x1FU, 0x08U, 0x04U, 0x02U, 0x1FU }, /* z */ - { 0x08U, 0x04U, 0x04U, 0x02U, 0x04U, 0x04U, 0x08U }, /* { */ - { 0x04U, 0x04U, 0x04U, 0x04U, 0x04U, 0x04U, 0x04U }, /* | */ - { 0x02U, 0x04U, 0x04U, 0x08U, 0x04U, 0x04U, 0x02U }, /* } */ - { 0x02U, 0x15U, 0x08U, 0x00U, 0x00U, 0x00U, 0x00U }, /* ~ */ - }; - - for (; *str != '\0'; ++str, x += 6) { - uint8_t const *ch = &font5x7[*str - ' '][0]; - paintBitsClear(x, y, ch, 7); - } -} - -/*==========================================================================*/ -typedef struct { /* the auxiliary structure to hold const bitmaps */ - uint8_t const *bits; /* the bits in the bitmap */ - uint8_t height; /* the height of the bitmap */ -} Bitmap; - -/* bitmap of the Ship: -* -* x.... -* xxx.. -* xxxxx -*/ -static uint8_t const ship_bits[] = { - 0x01U, 0x07U, 0x1FU -}; - -/* bitmap of the Missile: -* -* xxxx -*/ -static uint8_t const missile_bits[] = { - 0x0FU -}; - -/* bitmap of the Mine type-1: -* -* .x. -* xxx -* .x. -*/ -static uint8_t const mine1_bits[] = { - 0x02U, 0x07U, 0x02U -}; - -/* bitmap of the Mine type-2: -* -* x..x -* .xx. -* .xx. -* x..x -*/ -static uint8_t const mine2_bits[] = { - 0x09U, 0x06U, 0x06U, 0x09U -}; - -/* Mine type-2 is nastier than Mine type-1. The type-2 mine can -* hit the Ship with any of its "tentacles". However, it can be -* destroyed by the Missile only by hitting its center, defined as -* the following bitmap: -* -* .... -* .xx. -* .xx. -*/ -static uint8_t const mine2_missile_bits[] = { - 0x00U, 0x06U, 0x06U -}; - -/* -* The bitmap of the explosion stage 0: -* -* ....... -* ...x... -* ..x.x.. -* ...x... -*/ -static uint8_t const explosion0_bits[] = { - 0x00U, 0x08U, 0x14U, 0x08U -}; - -/* -* The bitmap of the explosion stage 1: -* -* ....... -* ..x.x.. -* ...x... -* ..x.x.. -*/ -static uint8_t const explosion1_bits[] = { - 0x00U, 0x14U, 0x08U, 0x14U -}; - -/* -* The bitmap of the explosion stage 2: -* -* .x...x. -* ..x.x.. -* ...x... -* ..x.x.. -* .x...x. -*/ -static uint8_t const explosion2_bits[] = { - 0x11U, 0x0AU, 0x04U, 0x0AU, 0x11U -}; - -/* -* The bitmap of the explosion stage 3: -* -* x..x..x -* .x.x.x. -* ..x.x.. -* xx.x.xx -* ..x.x.. -* .x.x.x. -* x..x..x -*/ -static uint8_t const explosion3_bits[] = { - 0x49, 0x2A, 0x14, 0x6B, 0x14, 0x2A, 0x49 -}; - -static Bitmap const l_bitmap[MAX_BMP] = { - { ship_bits, Q_DIM(ship_bits) }, - { missile_bits, Q_DIM(missile_bits) }, - { mine1_bits, Q_DIM(mine1_bits) }, - { mine2_bits, Q_DIM(mine2_bits) }, - { mine2_missile_bits, Q_DIM(mine2_missile_bits) }, - { explosion0_bits, Q_DIM(explosion0_bits) }, - { explosion1_bits, Q_DIM(explosion1_bits) }, - { explosion2_bits, Q_DIM(explosion2_bits) }, - { explosion3_bits, Q_DIM(explosion3_bits) } -}; - -/*..........................................................................*/ -void BSP_paintBitmap(uint8_t x, uint8_t y, uint8_t bmp_id) { - Bitmap const *bmp = &l_bitmap[bmp_id]; - paintBits(x, y, bmp->bits, bmp->height); -} -/*..........................................................................*/ -void BSP_advanceWalls(uint8_t top, uint8_t bottom) { - uint_fast8_t y; - for (y = 0U; y < GAME_TUNNEL_HEIGHT; ++y) { - /* shift the walls one pixel to the left */ - l_walls[y][0] = (l_walls[y][0] >> 1) | (l_walls[y][1] << 31); - l_walls[y][1] = (l_walls[y][1] >> 1) | (l_walls[y][2] << 31); - l_walls[y][2] = (l_walls[y][2] >> 1) | (l_walls[y][3] << 31); - l_walls[y][3] = (l_walls[y][3] >> 1); - - /* add new column of walls at the end */ - if (y <= top) { - l_walls[y][3] |= (1U << 31); - } - if (y >= (GAME_TUNNEL_HEIGHT - bottom)) { - l_walls[y][3] |= (1U << 31); - } - - /* copy the walls to the frame buffer */ - l_fb[y][0] = l_walls[y][0]; - l_fb[y][1] = l_walls[y][1]; - l_fb[y][2] = l_walls[y][2]; - l_fb[y][3] = l_walls[y][3]; - } -} -/*..........................................................................*/ -bool BSP_doBitmapsOverlap(uint8_t bmp_id1, uint8_t x1, uint8_t y1, - uint8_t bmp_id2, uint8_t x2, uint8_t y2) -{ - uint8_t y; - uint8_t y0; - uint8_t h; - uint32_t bits1; - uint32_t bits2; - Bitmap const *bmp1; - Bitmap const *bmp2; - - Q_REQUIRE((bmp_id1 < Q_DIM(l_bitmap)) && (bmp_id2 < Q_DIM(l_bitmap))); - - /* are the bitmaps close enough in x? */ - if (x1 >= x2) { - if (x1 > x2 + 8U) { - return false; - } - x1 -= x2; - x2 = 0U; - } - else { - if (x2 > x1 + 8U) { - return false; - } - x2 -= x1; - x1 = 0U; - } - - bmp1 = &l_bitmap[bmp_id1]; - bmp2 = &l_bitmap[bmp_id2]; - if ((y1 <= y2) && (y1 + bmp1->height > y2)) { - y0 = y2 - y1; - h = y1 + bmp1->height - y2; - if (h > bmp2->height) { - h = bmp2->height; - } - for (y = 0; y < h; ++y) { /* scan over the overlapping rows */ - bits1 = ((uint32_t)bmp1->bits[y + y0] << x1); - bits2 = ((uint32_t)bmp2->bits[y] << x2); - if ((bits1 & bits2) != 0U) { /* do the bits overlap? */ - return true; /* yes! */ - } - } - } - else { - if ((y1 > y2) && (y2 + bmp2->height > y1)) { - y0 = y1 - y2; - h = y2 + bmp2->height - y1; - if (h > bmp1->height) { - h = bmp1->height; - } - for (y = 0; y < h; ++y) { /* scan over the overlapping rows */ - bits1 = ((uint32_t)bmp1->bits[y] << x1); - bits2 = ((uint32_t)bmp2->bits[y + y0] << x2); - if ((bits1 & bits2) != 0U) { /* do the bits overlap? */ - return true; /* yes! */ - } - } - } - } - return false; /* the bitmaps do not overlap */ -} -/*..........................................................................*/ -bool BSP_isWallHit(uint8_t bmp_id, uint8_t x, uint8_t y) { - Bitmap const *bmp = &l_bitmap[bmp_id]; - uint32_t shft = (x & 0x1FU); - uint32_t *walls = &l_walls[y][x >> 5]; - for (y = 0; y < bmp->height; ++y, walls += (BSP_SCREEN_WIDTH >> 5)) { - if (*walls & ((uint32_t)bmp->bits[y] << shft)) { - return true; - } - if (shft > 24U) { - if (*(walls + 1) & ((uint32_t)bmp->bits[y] >> (32U - shft))) { - return true; - } - } - } - return false; -} - -/*..........................................................................*/ -void BSP_updateScore(uint16_t score) { - uint8_t seg[5]; - char str[5]; - - if (score == 0U) { - BSP_paintString(1U, BSP_SCREEN_HEIGHT - 8U, "SCORE:"); - } - - seg[0] = score % 10U; score /= 10U; - seg[1] = score % 10U; score /= 10U; - seg[2] = score % 10U; score /= 10U; - seg[3] = score % 10U; - - /* update the SCORE area on the screeen */ - str[0] = seg[3] + '0'; - str[1] = seg[2] + '0'; - str[2] = seg[1] + '0'; - str[3] = seg[0] + '0'; - str[4] = '\0'; - BSP_paintString(6U*6U, BSP_SCREEN_HEIGHT - 8U, str); - - /* update the score in the l_scoreBoard SegmentDisplay */ - SegmentDisplay_setSegment(&l_scoreBoard, 0U, (UINT)seg[0]); - SegmentDisplay_setSegment(&l_scoreBoard, 1U, (UINT)seg[1]); - SegmentDisplay_setSegment(&l_scoreBoard, 2U, (UINT)seg[2]); - SegmentDisplay_setSegment(&l_scoreBoard, 3U, (UINT)seg[3]); -} -/*..........................................................................*/ -void BSP_displayOn(void) { - SegmentDisplay_setSegment(&l_userLED0, 0U, 1U); -} -/*..........................................................................*/ -void BSP_displayOff(void) { - SegmentDisplay_setSegment(&l_userLED0, 0U, 0U); - GraphicDisplay_clear(&l_lcd); - GraphicDisplay_redraw(&l_lcd); -} -/*..........................................................................*/ -uint32_t BSP_random(void) { /* a very cheap pseudo-random-number generator */ - /* "Super-Duper" Linear Congruential Generator (LCG) - * LCG(2^32, 3*7*11*13*23, 0, seed) - */ - l_rnd = l_rnd * (3U*7U*11U*13U*23U); - return l_rnd >> 8; -} -/*..........................................................................*/ -void BSP_randomSeed(uint32_t seed) { - l_rnd = seed; -} - -/*--------------------------------------------------------------------------*/ -/*..........................................................................*/ -static void paintBits(uint8_t x, uint8_t y, uint8_t const *bits, uint8_t h) { - uint32_t *fb = &l_fb[y][x >> 5]; - uint32_t shft = (x & 0x1FU); - for (y = 0; y < h; ++y, fb += (BSP_SCREEN_WIDTH >> 5)) { - *fb |= ((uint32_t)bits[y] << shft); - if (shft > 24U) { - *(fb + 1) |= ((uint32_t)bits[y] >> (32U - shft)); - } - } -} -/*..........................................................................*/ -static void paintBitsClear(uint8_t x, uint8_t y, - uint8_t const *bits, uint8_t h) -{ - uint32_t *fb = &l_fb[y][x >> 5]; - uint32_t shft = (x & 0x1FU); - uint32_t mask1 = ~((uint32_t)0xFFU << shft); - uint32_t mask2; - if (shft > 24U) { - mask2 = ~(0xFFU >> (32U - shft)); - } - for (y = 0; y < h; ++y, fb += (BSP_SCREEN_WIDTH >> 5)) { - *fb = ((*fb & mask1) | ((uint32_t)bits[y] << shft)); - if (shft > 24U) { - *(fb + 1) = ((*(fb + 1) & mask2) - | ((uint32_t)bits[y] >> (32U - shft))); - } - } -} - -/*..........................................................................*/ -/* thread function for running the application main_gui() */ -static DWORD WINAPI appThread(LPVOID par) { - (void)par; /* unused parameter */ - return (DWORD)main_gui(); /* run the QF application */ -} - -/*--------------------------------------------------------------------------*/ -int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, - LPSTR cmdLine, int iCmdShow) -{ - HWND hWnd; - MSG msg; - - (void)hPrevInst; /* unused parameter */ - - l_hInst = hInst; /* save the application instance */ - l_cmdLine = cmdLine; /* save the command line string */ - - //AllocConsole(); - - /* create the main custom dialog window */ - hWnd = CreateCustDialog(hInst, IDD_APPLICATION, NULL, - &WndProc, "MY_CLASS"); - ShowWindow(hWnd, iCmdShow); /* show the main window */ - - /* enter the message loop... */ - while (GetMessage(&msg, NULL, 0, 0)) { - TranslateMessage(&msg); - DispatchMessage(&msg); - } - - //FreeConsole(); - BSP_terminate(0); - - return msg.wParam; -} - -/*..........................................................................*/ -static LRESULT CALLBACK WndProc(HWND hWnd, UINT iMsg, - WPARAM wParam, LPARAM lParam) -{ - switch (iMsg) { - - /* Perform initialization upon cration of the main dialog window - * NOTE: Any child-windows are NOT created yet at this time, so - * the GetDlgItem() function can't be used (it will return NULL). - */ - case WM_CREATE: { - l_hWnd = hWnd; /* save the window handle */ - - /* initialize the owner-drawn buttons... - * NOTE: must be done *before* the first drawing of the buttons, - * so WM_INITDIALOG is too late. - */ - OwnerDrawnButton_init(&l_userBtn0, IDC_USER0, - LoadBitmap(l_hInst, MAKEINTRESOURCE(IDB_BTN_UP)), - LoadBitmap(l_hInst, MAKEINTRESOURCE(IDB_BTN_DWN)), - LoadCursor(NULL, IDC_HAND)); - OwnerDrawnButton_init(&l_userBtn1, IDC_USER1, - LoadBitmap(l_hInst, MAKEINTRESOURCE(IDB_BTN_UP)), - LoadBitmap(l_hInst, MAKEINTRESOURCE(IDB_BTN_DWN)), - LoadCursor(NULL, IDC_HAND)); - return 0; - } - - /* Perform initialization after all child windows have been created */ - case WM_INITDIALOG: { - GraphicDisplay_init(&l_lcd, 128, 128, IDC_LCD, c_offColor); - - SegmentDisplay_init(&l_userLED0, - 1U, /* 1 "segment" (the LED0 itself) */ - 2U); /* 2 bitmaps (for LED0 OFF/ON states) */ - SegmentDisplay_initSegment(&l_userLED0, 0U, IDC_LED0); - SegmentDisplay_initBitmap(&l_userLED0, - 0U, LoadBitmap(l_hInst, MAKEINTRESOURCE(IDB_LED_OFF))); - SegmentDisplay_initBitmap(&l_userLED0, - 1U, LoadBitmap(l_hInst, MAKEINTRESOURCE(IDB_LED_ON))); - - SegmentDisplay_init(&l_userLED1, - 1U, /* 1 "segment" (the LED1 itself) */ - 2U); /* 2 bitmaps (for LED1 OFF/ON states) */ - SegmentDisplay_initSegment(&l_userLED1, 0U, IDC_LED1); - SegmentDisplay_initBitmap(&l_userLED1, - 0U, LoadBitmap(l_hInst, MAKEINTRESOURCE(IDB_LED_OFF))); - SegmentDisplay_initBitmap(&l_userLED1, - 1U, LoadBitmap(l_hInst, MAKEINTRESOURCE(IDB_LED_ON))); - - SegmentDisplay_init(&l_scoreBoard, - 4U, /* 4 "segments" (digits 0-3) */ - 10U); /* 10 bitmaps (for 0-9 states) */ - SegmentDisplay_initSegment(&l_scoreBoard, 0U, IDC_SEG0); - SegmentDisplay_initSegment(&l_scoreBoard, 1U, IDC_SEG1); - SegmentDisplay_initSegment(&l_scoreBoard, 2U, IDC_SEG2); - SegmentDisplay_initSegment(&l_scoreBoard, 3U, IDC_SEG3); - SegmentDisplay_initBitmap(&l_scoreBoard, - 0U, LoadBitmap(l_hInst, MAKEINTRESOURCE(IDB_SEG0))); - SegmentDisplay_initBitmap(&l_scoreBoard, - 1U, LoadBitmap(l_hInst, MAKEINTRESOURCE(IDB_SEG1))); - SegmentDisplay_initBitmap(&l_scoreBoard, - 2U, LoadBitmap(l_hInst, MAKEINTRESOURCE(IDB_SEG2))); - SegmentDisplay_initBitmap(&l_scoreBoard, - 3U, LoadBitmap(l_hInst, MAKEINTRESOURCE(IDB_SEG3))); - SegmentDisplay_initBitmap(&l_scoreBoard, - 4U, LoadBitmap(l_hInst, MAKEINTRESOURCE(IDB_SEG4))); - SegmentDisplay_initBitmap(&l_scoreBoard, - 5U, LoadBitmap(l_hInst, MAKEINTRESOURCE(IDB_SEG5))); - SegmentDisplay_initBitmap(&l_scoreBoard, - 6U, LoadBitmap(l_hInst, MAKEINTRESOURCE(IDB_SEG6))); - SegmentDisplay_initBitmap(&l_scoreBoard, - 7U, LoadBitmap(l_hInst, MAKEINTRESOURCE(IDB_SEG7))); - SegmentDisplay_initBitmap(&l_scoreBoard, - 8U, LoadBitmap(l_hInst, MAKEINTRESOURCE(IDB_SEG8))); - SegmentDisplay_initBitmap(&l_scoreBoard, - 9U, LoadBitmap(l_hInst, MAKEINTRESOURCE(IDB_SEG9))); - - BSP_updateScore(0U); - - /* --> QP: spawn the application thread to run main_gui() */ - Q_ALLEGE(CreateThread(NULL, 0, &appThread, NULL, 0, NULL) - != (HANDLE)0); - return 0; - } - - case WM_DESTROY: { - OutputDebugString("DESTROY\n"); - PostQuitMessage(0); - return 0; - } - - /* commands from child controls and menus... */ - case WM_COMMAND: { - switch (wParam) { - case IDOK: - case IDCANCEL: { - OutputDebugString("QUIT\n"); - PostQuitMessage(0); - break; - } - case IDC_USER0: /* owner-drawn buttons... */ - case IDC_USER1: { - SetFocus(hWnd); - break; - } - } - return 0; - } - - /* drawing of owner-drawn buttons... */ - case WM_DRAWITEM: { - LPDRAWITEMSTRUCT pdis = (LPDRAWITEMSTRUCT)lParam; - switch (pdis->CtlID) { - case IDC_USER0: { /* owner-drawn Button0 */ - OutputDebugString("USER0\n"); - switch (OwnerDrawnButton_draw(&l_userBtn0, pdis)) { - case BTN_DEPRESSED: { - playerTrigger(); - SegmentDisplay_setSegment(&l_userLED0, 0U, 1U); - break; - } - case BTN_RELEASED: { - SegmentDisplay_setSegment(&l_userLED0, 0U, 0U); - break; - } - default: { - break; - } - } - break; - } - case IDC_USER1: { /* owner-drawn Button1 */ - OutputDebugString("USER1\n"); - switch (OwnerDrawnButton_draw(&l_userBtn1, pdis)) { - case BTN_DEPRESSED: { - break; - } - case BTN_RELEASED: { - break; - } - default: { - break; - } - } - break; - } - } - return 0; - } - - /* mouse wheel input... */ - case WM_MOUSEWHEEL: { - OutputDebugString("MOUSEWHEEL\n"); - return 0; - } - - /* keyboard input... */ - case WM_KEYDOWN: { - OutputDebugString("KEYDOWN\n"); - switch (wParam) { - case VK_SPACE: - playerTrigger(); - OwnerDrawnButton_set(&l_userBtn0, 1); - break; - } - return 0; - } - - case WM_KEYUP: { - OutputDebugString("KEYUP\n"); - switch (wParam) { - case VK_SPACE: - OwnerDrawnButton_set(&l_userBtn0, 0); - break; - } - return 0; - } - } - return DefWindowProc(hWnd, iMsg, wParam, lParam); -} - -/*--------------------------------------------------------------------------*/ -#ifdef Q_SPY /* define QS callbacks */ - -/*! callback function to execute user commands */ -void QS_onCommand(uint8_t cmdId, - uint32_t param1, uint32_t param2, uint32_t param3) -{ - switch (cmdId) { - case 0U: { - break; - } - default: - break; - } - - /* unused parameters */ - (void)param1; - (void)param2; - (void)param3; -} - -#endif /* Q_SPY */ -/*--------------------------------------------------------------------------*/ diff --git a/examples/arm-cm/game_efm32-slstk3401a/win32-gui/main.c b/examples/arm-cm/game_efm32-slstk3401a/win32-gui/main.c deleted file mode 100644 index 060f608c..00000000 --- a/examples/arm-cm/game_efm32-slstk3401a/win32-gui/main.c +++ /dev/null @@ -1,116 +0,0 @@ -/***************************************************************************** -* Product: "Fly 'n' Shoot" game example for Windows -* Last updated for version 6.9.2 -* Last updated on 2021-02-12 -* -* Q u a n t u m L e a P s -* ------------------------ -* Modern Embedded Software -* -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* -* -*****************************************************************************/ -#include "qpc.h" -#include "bsp.h" -#include "game.h" - -Q_DEFINE_THIS_FILE - -/* "fudge factor" for Windows, see NOTE1 */ -enum { WIN_FUDGE_FACTOR = 10 }; - -/*..........................................................................*/ -int main() { - static QEvt const *missileQueueSto[2*WIN_FUDGE_FACTOR]; - static QEvt const *shipQueueSto[3*WIN_FUDGE_FACTOR]; - static QEvt const *tunnelQueueSto[(GAME_MINES_MAX + 5)*WIN_FUDGE_FACTOR]; - static QF_MPOOL_EL(QEvt) smlPoolSto[10*WIN_FUDGE_FACTOR]; - static QF_MPOOL_EL(ObjectImageEvt) - medPoolSto[(2*GAME_MINES_MAX + 10)*WIN_FUDGE_FACTOR]; - static QSubscrList subscrSto[MAX_PUB_SIG]; - - QF_init(); /* initialize the framework and the underlying RT kernel */ - BSP_init(); /* initialize the Board Support Package */ - - /* init publish-subscribe... */ - QF_psInit(subscrSto, Q_DIM(subscrSto)); - - /* initialize the event pools... */ - QF_poolInit(smlPoolSto, sizeof(smlPoolSto), sizeof(smlPoolSto[0])); - QF_poolInit(medPoolSto, sizeof(medPoolSto), sizeof(medPoolSto[0])); - - /* object dictionaries for AOs... */ - QS_OBJ_DICTIONARY(AO_Missile); - QS_OBJ_DICTIONARY(AO_Ship); - QS_OBJ_DICTIONARY(AO_Tunnel); - - /* signal dictionaries for globally published events... */ - QS_SIG_DICTIONARY(TIME_TICK_SIG, (void *)0); - QS_SIG_DICTIONARY(PLAYER_TRIGGER_SIG, (void *)0); - QS_SIG_DICTIONARY(PLAYER_QUIT_SIG, (void *)0); - QS_SIG_DICTIONARY(GAME_OVER_SIG, (void *)0); - - /* start the active objects... */ - Tunnel_ctor_call(); - QACTIVE_START(AO_Tunnel, - 1U, /* QP priority */ - tunnelQueueSto, Q_DIM(tunnelQueueSto), /* evt queue */ - (void *)0, 0U, /* no per-thread stack */ - (QEvt *)0); /* no initialization event */ - Ship_ctor_call(); - QACTIVE_START(AO_Ship, - 2U, /* QP priority */ - shipQueueSto, Q_DIM(shipQueueSto), /* evt queue */ - (void *)0, 0U, /* no per-thread stack */ - (QEvt *)0); /* no initialization event */ - Missile_ctor_call(); - QACTIVE_START(AO_Missile, - 3U, /* QP priority */ - missileQueueSto, Q_DIM(missileQueueSto), /* evt queue */ - (void *)0, 0U, /* no per-thread stack */ - (QEvt *)0); /* no initialization event */ - - return QF_run(); /* run the QF application */ -} - -/***************************************************************************** -* NOTE1: -* Windows is not a deterministic real-time system, which means that the -* system can occasionally and unexpectedly "choke and freeze" for a number -* of seconds. The designers of Windows have dealt with these sort of issues -* by massively oversizing the resources available to the applications. For -* example, the default Windows GUI message queues size is 10,000 entries, -* which can dynamically grow to an even larger number. Also the stacks of -* Win32 threads can dynamically grow to several megabytes. -* -* In contrast, the event queues, event pools, and stack size inside the -* real-time embedded (RTE) systems can be (and must be) much smaller, -* because you typically can put an upper bound on the real-time behavior -* and the resulting delays. -* -* To be able to run the unmodified applications designed originally for -* RTE systems on Windows, and to reduce the odds of resource shortages in -* this case, the generous WIN_FUDGE_FACTOR is used to oversize the -* event queues and event pools. -*/ diff --git a/examples/arm-cm/low-power_ek-tm4c123gxl/blinky0.c b/examples/arm-cm/low-power_ek-tm4c123gxl/blinky0.c index 517729c9..bdeaab55 100644 --- a/examples/arm-cm/low-power_ek-tm4c123gxl/blinky0.c +++ b/examples/arm-cm/low-power_ek-tm4c123gxl/blinky0.c @@ -1,86 +1,86 @@ -/*$file${.::blinky0.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* -* Model: low-power.qm -* File: ${.::blinky0.c} -* -* This code has been generated by QM 5.2.4 . -* DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. -* -* SPDX-License-Identifier: GPL-3.0-or-later -* -* This generated code is open source software: you can redistribute it under -* the terms of the GNU General Public License as published by the Free -* Software Foundation. -* -* This code is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -* more details. -* -* NOTE: -* Alternatively, this generated code may be distributed under the terms -* of Quantum Leaps commercial licenses, which expressly supersede the GNU -* General Public License and are specifically designed for licensees -* interested in retaining the proprietary status of their code. -* -* Contact information: -* -* -*/ -/*$endhead${.::blinky0.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$file${.::blinky0.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// +// Model: low-power.qm +// File: ${.::blinky0.c} +// +// This code has been generated by QM 5.3.0 . +// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. +// +// SPDX-License-Identifier: GPL-3.0-or-later +// +// This generated code is open source software: you can redistribute it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation. +// +// This code is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// NOTE: +// Alternatively, this generated code may be distributed under the terms +// of Quantum Leaps commercial licenses, which expressly supersede the GNU +// General Public License and are specifically designed for licensees +// interested in retaining the proprietary status of their code. +// +// Contact information: +// +// +// +//$endhead${.::blinky0.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ #include "qpc.h" #include "low_power.h" #include "bsp.h" //Q_DEFINE_THIS_FILE -/*$declare${AOs::Blinky0} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//$declare${AOs::Blinky0} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/*${AOs::Blinky0} ..........................................................*/ +//${AOs::Blinky0} ............................................................ typedef struct Blinky0 { -/* protected: */ +// protected: QActive super; -/* private: */ +// private: QTimeEvt timeEvt0; -/* public: */ +// public: -/* private: */ +// private: uint8_t count; } Blinky0; extern Blinky0 Blinky0_instance; -/* protected: */ +// protected: static QState Blinky0_initial(Blinky0 * const me, void const * const par); static QState Blinky0_active(Blinky0 * const me, QEvt const * const e); static QState Blinky0_on(Blinky0 * const me, QEvt const * const e); static QState Blinky0_off(Blinky0 * const me, QEvt const * const e); static QState Blinky0_inactive(Blinky0 * const me, QEvt const * const e); -/*$enddecl${AOs::Blinky0} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$enddecl${AOs::Blinky0} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -/*$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* Check for the minimum required QP version */ -#if (QP_VERSION < 700U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) -#error qpc version 7.0.0 or higher required +//$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// Check for the minimum required QP version +#if (QP_VERSION < 730U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) +#error qpc version 7.3.0 or higher required #endif -/*$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -/*$define${AOs::AO_Blinky0} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//$define${AOs::AO_Blinky0} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/*${AOs::AO_Blinky0} .......................................................*/ +//${AOs::AO_Blinky0} ......................................................... QActive * const AO_Blinky0 = &Blinky0_instance.super; -/*$enddef${AOs::AO_Blinky0} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$enddef${AOs::AO_Blinky0} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -/*$define${AOs::Blinky0} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//$define${AOs::Blinky0} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/*${AOs::Blinky0} ..........................................................*/ +//${AOs::Blinky0} ............................................................ Blinky0 Blinky0_instance; -/*${AOs::Blinky0::SM} ......................................................*/ +//${AOs::Blinky0::SM} ........................................................ static QState Blinky0_initial(Blinky0 * const me, void const * const par) { - /*${AOs::Blinky0::SM::initial} */ - (void)par; /* unused parameter */ + //${AOs::Blinky0::SM::initial} + (void)par; // unused parameter QActive_subscribe(&me->super, BTN_PRESSED_SIG); QS_FUN_DICTIONARY(&Blinky0_active); @@ -91,11 +91,11 @@ static QState Blinky0_initial(Blinky0 * const me, void const * const par) { return Q_TRAN(&Blinky0_active); } -/*${AOs::Blinky0::SM::active} ..............................................*/ +//${AOs::Blinky0::SM::active} ................................................ static QState Blinky0_active(Blinky0 * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${AOs::Blinky0::SM::active} */ + //${AOs::Blinky0::SM::active} case Q_ENTRY_SIG: { BSP_tickRate0_on(); me->count = 4U; @@ -103,13 +103,13 @@ static QState Blinky0_active(Blinky0 * const me, QEvt const * const e) { status_ = Q_HANDLED(); break; } - /*${AOs::Blinky0::SM::active} */ + //${AOs::Blinky0::SM::active} case Q_EXIT_SIG: { QTimeEvt_disarm(&me->timeEvt0); status_ = Q_HANDLED(); break; } - /*${AOs::Blinky0::SM::active::initial} */ + //${AOs::Blinky0::SM::active::initial} case Q_INIT_SIG: { status_ = Q_TRAN(&Blinky0_on); break; @@ -122,30 +122,30 @@ static QState Blinky0_active(Blinky0 * const me, QEvt const * const e) { return status_; } -/*${AOs::Blinky0::SM::active::on} ..........................................*/ +//${AOs::Blinky0::SM::active::on} ............................................ static QState Blinky0_on(Blinky0 * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${AOs::Blinky0::SM::active::on} */ + //${AOs::Blinky0::SM::active::on} case Q_ENTRY_SIG: { BSP_led0_on(); status_ = Q_HANDLED(); break; } - /*${AOs::Blinky0::SM::active::on} */ + //${AOs::Blinky0::SM::active::on} case Q_EXIT_SIG: { BSP_led0_off(); status_ = Q_HANDLED(); break; } - /*${AOs::Blinky0::SM::active::on::TIMEOUT0} */ + //${AOs::Blinky0::SM::active::on::TIMEOUT0} case TIMEOUT0_SIG: { --me->count; - /*${AOs::Blinky0::SM::active::on::TIMEOUT0::[me->count>0]} */ + //${AOs::Blinky0::SM::active::on::TIMEOUT0::[me->count>0]} if (me->count > 0) { status_ = Q_TRAN(&Blinky0_off); } - /*${AOs::Blinky0::SM::active::on::TIMEOUT0::[else]} */ + //${AOs::Blinky0::SM::active::on::TIMEOUT0::[else]} else { status_ = Q_TRAN(&Blinky0_inactive); } @@ -159,11 +159,11 @@ static QState Blinky0_on(Blinky0 * const me, QEvt const * const e) { return status_; } -/*${AOs::Blinky0::SM::active::off} .........................................*/ +//${AOs::Blinky0::SM::active::off} ........................................... static QState Blinky0_off(Blinky0 * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${AOs::Blinky0::SM::active::off::TIMEOUT0} */ + //${AOs::Blinky0::SM::active::off::TIMEOUT0} case TIMEOUT0_SIG: { status_ = Q_TRAN(&Blinky0_on); break; @@ -176,11 +176,11 @@ static QState Blinky0_off(Blinky0 * const me, QEvt const * const e) { return status_; } -/*${AOs::Blinky0::SM::inactive} ............................................*/ +//${AOs::Blinky0::SM::inactive} .............................................. static QState Blinky0_inactive(Blinky0 * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${AOs::Blinky0::SM::inactive::BTN_PRESSED} */ + //${AOs::Blinky0::SM::inactive::BTN_PRESSED} case BTN_PRESSED_SIG: { status_ = Q_TRAN(&Blinky0_active); break; @@ -192,15 +192,15 @@ static QState Blinky0_inactive(Blinky0 * const me, QEvt const * const e) { } return status_; } -/*$enddef${AOs::Blinky0} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$enddef${AOs::Blinky0} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -/*$define${AOs::Blinky0_ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//$define${AOs::Blinky0_ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/*${AOs::Blinky0_ctor} .....................................................*/ +//${AOs::Blinky0_ctor} ....................................................... void Blinky0_ctor(void) { Blinky0 *me = &Blinky0_instance; QActive_ctor(&me->super, Q_STATE_CAST(&Blinky0_initial)); QTimeEvt_ctorX(&me->timeEvt0, &me->super, TIMEOUT0_SIG, 0U); } -/*$enddef${AOs::Blinky0_ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$enddef${AOs::Blinky0_ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/examples/arm-cm/low-power_ek-tm4c123gxl/blinky1.c b/examples/arm-cm/low-power_ek-tm4c123gxl/blinky1.c index c4446f06..f2565e17 100644 --- a/examples/arm-cm/low-power_ek-tm4c123gxl/blinky1.c +++ b/examples/arm-cm/low-power_ek-tm4c123gxl/blinky1.c @@ -1,84 +1,84 @@ -/*$file${.::blinky1.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* -* Model: low-power.qm -* File: ${.::blinky1.c} -* -* This code has been generated by QM 5.2.4 . -* DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. -* -* SPDX-License-Identifier: GPL-3.0-or-later -* -* This generated code is open source software: you can redistribute it under -* the terms of the GNU General Public License as published by the Free -* Software Foundation. -* -* This code is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -* more details. -* -* NOTE: -* Alternatively, this generated code may be distributed under the terms -* of Quantum Leaps commercial licenses, which expressly supersede the GNU -* General Public License and are specifically designed for licensees -* interested in retaining the proprietary status of their code. -* -* Contact information: -* -* -*/ -/*$endhead${.::blinky1.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$file${.::blinky1.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// +// Model: low-power.qm +// File: ${.::blinky1.c} +// +// This code has been generated by QM 5.3.0 . +// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. +// +// SPDX-License-Identifier: GPL-3.0-or-later +// +// This generated code is open source software: you can redistribute it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation. +// +// This code is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// NOTE: +// Alternatively, this generated code may be distributed under the terms +// of Quantum Leaps commercial licenses, which expressly supersede the GNU +// General Public License and are specifically designed for licensees +// interested in retaining the proprietary status of their code. +// +// Contact information: +// +// +// +//$endhead${.::blinky1.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ #include "qpc.h" #include "low_power.h" #include "bsp.h" //Q_DEFINE_THIS_FILE -/*$declare${AOs::Blinky1} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//$declare${AOs::Blinky1} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/*${AOs::Blinky1} ..........................................................*/ +//${AOs::Blinky1} ............................................................ typedef struct Blinky1 { -/* protected: */ +// protected: QActive super; -/* public: */ +// public: -/* private: */ +// private: QTimeEvt timeEvt1; uint8_t count; } Blinky1; extern Blinky1 Blinky1_instance; -/* protected: */ +// protected: static QState Blinky1_initial(Blinky1 * const me, void const * const par); static QState Blinky1_inactive(Blinky1 * const me, QEvt const * const e); static QState Blinky1_active(Blinky1 * const me, QEvt const * const e); static QState Blinky1_off(Blinky1 * const me, QEvt const * const e); static QState Blinky1_on(Blinky1 * const me, QEvt const * const e); -/*$enddecl${AOs::Blinky1} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$enddecl${AOs::Blinky1} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -/*$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* Check for the minimum required QP version */ -#if (QP_VERSION < 700U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) -#error qpc version 7.0.0 or higher required +//$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// Check for the minimum required QP version +#if (QP_VERSION < 730U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) +#error qpc version 7.3.0 or higher required #endif -/*$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -/*$define${AOs::AO_Blinky1} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//$define${AOs::AO_Blinky1} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/*${AOs::AO_Blinky1} .......................................................*/ +//${AOs::AO_Blinky1} ......................................................... QActive * const AO_Blinky1 = &Blinky1_instance.super; -/*$enddef${AOs::AO_Blinky1} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$enddef${AOs::AO_Blinky1} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -/*$define${AOs::Blinky1} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//$define${AOs::Blinky1} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/*${AOs::Blinky1} ..........................................................*/ +//${AOs::Blinky1} ............................................................ Blinky1 Blinky1_instance; -/*${AOs::Blinky1::SM} ......................................................*/ +//${AOs::Blinky1::SM} ........................................................ static QState Blinky1_initial(Blinky1 * const me, void const * const par) { - /*${AOs::Blinky1::SM::initial} */ - (void)par; /* unused parameter */ + //${AOs::Blinky1::SM::initial} + (void)par; // unused parameter QActive_subscribe(&me->super, BTN_PRESSED_SIG); QS_FUN_DICTIONARY(&Blinky1_inactive); @@ -89,11 +89,11 @@ static QState Blinky1_initial(Blinky1 * const me, void const * const par) { return Q_TRAN(&Blinky1_inactive); } -/*${AOs::Blinky1::SM::inactive} ............................................*/ +//${AOs::Blinky1::SM::inactive} .............................................. static QState Blinky1_inactive(Blinky1 * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${AOs::Blinky1::SM::inactive::BTN_PRESSED} */ + //${AOs::Blinky1::SM::inactive::BTN_PRESSED} case BTN_PRESSED_SIG: { status_ = Q_TRAN(&Blinky1_active); break; @@ -106,11 +106,11 @@ static QState Blinky1_inactive(Blinky1 * const me, QEvt const * const e) { return status_; } -/*${AOs::Blinky1::SM::active} ..............................................*/ +//${AOs::Blinky1::SM::active} ................................................ static QState Blinky1_active(Blinky1 * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${AOs::Blinky1::SM::active} */ + //${AOs::Blinky1::SM::active} case Q_ENTRY_SIG: { BSP_tickRate1_on(); me->count = 13U; @@ -118,13 +118,13 @@ static QState Blinky1_active(Blinky1 * const me, QEvt const * const e) { status_ = Q_HANDLED(); break; } - /*${AOs::Blinky1::SM::active} */ + //${AOs::Blinky1::SM::active} case Q_EXIT_SIG: { QTimeEvt_disarm(&me->timeEvt1); status_ = Q_HANDLED(); break; } - /*${AOs::Blinky1::SM::active::initial} */ + //${AOs::Blinky1::SM::active::initial} case Q_INIT_SIG: { status_ = Q_TRAN(&Blinky1_on); break; @@ -137,11 +137,11 @@ static QState Blinky1_active(Blinky1 * const me, QEvt const * const e) { return status_; } -/*${AOs::Blinky1::SM::active::off} .........................................*/ +//${AOs::Blinky1::SM::active::off} ........................................... static QState Blinky1_off(Blinky1 * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${AOs::Blinky1::SM::active::off::TIMEOUT1} */ + //${AOs::Blinky1::SM::active::off::TIMEOUT1} case TIMEOUT1_SIG: { status_ = Q_TRAN(&Blinky1_on); break; @@ -154,30 +154,30 @@ static QState Blinky1_off(Blinky1 * const me, QEvt const * const e) { return status_; } -/*${AOs::Blinky1::SM::active::on} ..........................................*/ +//${AOs::Blinky1::SM::active::on} ............................................ static QState Blinky1_on(Blinky1 * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${AOs::Blinky1::SM::active::on} */ + //${AOs::Blinky1::SM::active::on} case Q_ENTRY_SIG: { BSP_led1_on(); status_ = Q_HANDLED(); break; } - /*${AOs::Blinky1::SM::active::on} */ + //${AOs::Blinky1::SM::active::on} case Q_EXIT_SIG: { BSP_led1_off(); status_ = Q_HANDLED(); break; } - /*${AOs::Blinky1::SM::active::on::TIMEOUT1} */ + //${AOs::Blinky1::SM::active::on::TIMEOUT1} case TIMEOUT1_SIG: { --me->count; - /*${AOs::Blinky1::SM::active::on::TIMEOUT1::[me->count>0]} */ + //${AOs::Blinky1::SM::active::on::TIMEOUT1::[me->count>0]} if (me->count > 0) { status_ = Q_TRAN(&Blinky1_off); } - /*${AOs::Blinky1::SM::active::on::TIMEOUT1::[else]} */ + //${AOs::Blinky1::SM::active::on::TIMEOUT1::[else]} else { status_ = Q_TRAN(&Blinky1_inactive); } @@ -190,15 +190,15 @@ static QState Blinky1_on(Blinky1 * const me, QEvt const * const e) { } return status_; } -/*$enddef${AOs::Blinky1} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$enddef${AOs::Blinky1} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -/*$define${AOs::Blinky1_ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//$define${AOs::Blinky1_ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/*${AOs::Blinky1_ctor} .....................................................*/ +//${AOs::Blinky1_ctor} ....................................................... void Blinky1_ctor(void) { Blinky1 *me = &Blinky1_instance; QActive_ctor(&me->super, Q_STATE_CAST(&Blinky1_initial)); QTimeEvt_ctorX(&me->timeEvt1, &me->super, TIMEOUT1_SIG, 1U); } -/*$enddef${AOs::Blinky1_ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$enddef${AOs::Blinky1_ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/examples/arm-cm/low-power_ek-tm4c123gxl/bsp.h b/examples/arm-cm/low-power_ek-tm4c123gxl/bsp.h index 8a931f2e..081699b1 100644 --- a/examples/arm-cm/low-power_ek-tm4c123gxl/bsp.h +++ b/examples/arm-cm/low-power_ek-tm4c123gxl/bsp.h @@ -1,43 +1,43 @@ -/***************************************************************************** -* Product: "Blinky Low-Power" example -* Last updated for version: 6.6.0 -* Last updated on: 2019-12-10 -* -* Q u a n t u m L e a P s -* ------------------------ -* Modern Embedded Software -* -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* -* -*****************************************************************************/ -#ifndef BSP_H -#define BSP_H +//============================================================================ +// Product: "Blinky Low-Power" example +// Last updated for version: 6.6.0 +// Last updated on: 2019-12-10 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// This program is open source software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Alternatively, this program may be distributed and modified under the +// terms of Quantum Leaps commercial licenses, which expressly supersede +// the GNU General Public License and are specifically designed for +// licensees interested in retaining the proprietary status of their code. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Contact information: +// +// +//============================================================================ +#ifndef BSP_H_ +#define BSP_H_ -/* The following ticks-per-second constants determine the speed of the app. -* The default (#if 1) is the SLOW speed for humans to see the blinking. -* Change the #if 1 into #if 0 for FAST speed appropriate for logic analyzers. -*/ +// The following ticks-per-second constants determine the speed of the app. +// The default (#if 1) is the SLOW speed for humans to see the blinking. +// Change the #if 1 into #if 0 for FAST speed appropriate for logic analyzers. +// #if 1 #define BSP_TICKS0_PER_SEC 2U #define BSP_TICKS1_PER_SEC 20U @@ -61,4 +61,4 @@ void BSP_led1_off(void); void BSP_tickRate0_on(void); void BSP_tickRate1_on(void); -#endif /* BSP_H */ +#endif // BSP_H_ diff --git a/examples/arm-cm/low-power_ek-tm4c123gxl/ek-tm4c123gxl.jpg b/examples/arm-cm/low-power_ek-tm4c123gxl/ek-tm4c123gxl.jpg new file mode 100644 index 00000000..5ed6188c Binary files /dev/null and b/examples/arm-cm/low-power_ek-tm4c123gxl/ek-tm4c123gxl.jpg differ diff --git a/examples/arm-cm/low-power_ek-tm4c123gxl/low-power.qm b/examples/arm-cm/low-power_ek-tm4c123gxl/low-power.qm index 25b6554a..0f2d38e9 100644 --- a/examples/arm-cm/low-power_ek-tm4c123gxl/low-power.qm +++ b/examples/arm-cm/low-power_ek-tm4c123gxl/low-power.qm @@ -1,5 +1,5 @@ - + Low-Power example with multiple clock rates @@ -21,7 +21,7 @@ - (void)par; /* unused parameter */ + (void)par; // unused parameter QActive_subscribe(&me->super, BTN_PRESSED_SIG); @@ -113,7 +113,7 @@ QTimeEvt_armX(&me->timeEvt0, 2U, 2U); - (void)par; /* unused parameter */ + (void)par; // unused parameter QActive_subscribe(&me->super, BTN_PRESSED_SIG); @@ -218,31 +218,31 @@ QTimeEvt_ctorX(&me->timeEvt1, &me->super, TIMEOUT1_SIG, 1U); diff --git a/examples/arm-cm/low-power_ek-tm4c123gxl/low_power.h b/examples/arm-cm/low-power_ek-tm4c123gxl/low_power.h index 7c416874..0598dce3 100644 --- a/examples/arm-cm/low-power_ek-tm4c123gxl/low_power.h +++ b/examples/arm-cm/low-power_ek-tm4c123gxl/low_power.h @@ -1,76 +1,76 @@ -/*$file${.::low_power.h} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* -* Model: low-power.qm -* File: ${.::low_power.h} -* -* This code has been generated by QM 5.2.4 . -* DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. -* -* SPDX-License-Identifier: GPL-3.0-or-later -* -* This generated code is open source software: you can redistribute it under -* the terms of the GNU General Public License as published by the Free -* Software Foundation. -* -* This code is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -* more details. -* -* NOTE: -* Alternatively, this generated code may be distributed under the terms -* of Quantum Leaps commercial licenses, which expressly supersede the GNU -* General Public License and are specifically designed for licensees -* interested in retaining the proprietary status of their code. -* -* Contact information: -* -* -*/ -/*$endhead${.::low_power.h} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$file${.::low_power.h} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// +// Model: low-power.qm +// File: ${.::low_power.h} +// +// This code has been generated by QM 5.3.0 . +// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. +// +// SPDX-License-Identifier: GPL-3.0-or-later +// +// This generated code is open source software: you can redistribute it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation. +// +// This code is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// NOTE: +// Alternatively, this generated code may be distributed under the terms +// of Quantum Leaps commercial licenses, which expressly supersede the GNU +// General Public License and are specifically designed for licensees +// interested in retaining the proprietary status of their code. +// +// Contact information: +// +// +// +//$endhead${.::low_power.h} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ #ifndef LOW_POWER_H #define LOW_POWER_H enum BlinkySignals { - BTN_PRESSED_SIG = Q_USER_SIG, /* button SW1 was pressed */ - MAX_PUB_SIG, /* the last published signal */ + BTN_PRESSED_SIG = Q_USER_SIG, // button SW1 was pressed + MAX_PUB_SIG, // the last published signal - TIMEOUT0_SIG, /* timeout for Blinky0 */ - TIMEOUT1_SIG, /* timeout for Blinky1 */ - MAX_SIG /* the last signal */ + TIMEOUT0_SIG, // timeout for Blinky0 + TIMEOUT1_SIG, // timeout for Blinky1 + MAX_SIG // the last signal }; -/*$declare${AOs::AO_Blinky0} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//$declare${AOs::AO_Blinky0} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/*${AOs::AO_Blinky0} .......................................................*/ +//${AOs::AO_Blinky0} ......................................................... extern QActive * const AO_Blinky0; -/*$enddecl${AOs::AO_Blinky0} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*$declare${AOs::Blinky0_ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//$enddecl${AOs::AO_Blinky0} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +//$declare${AOs::Blinky0_ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/*${AOs::Blinky0_ctor} .....................................................*/ +//${AOs::Blinky0_ctor} ....................................................... void Blinky0_ctor(void); -/*$enddecl${AOs::Blinky0_ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$enddecl${AOs::Blinky0_ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -#ifdef QP_INC_QXK_H_ /* QXK kernel? */ +#ifdef QXK_H_ // QXK kernel? void XBlinky1_ctor(void); extern QXThread XT_Blinky1; extern QXSemaphore XSEM_sw1; -#else /* QV or QK kernels */ +#else // QV or QK kernels -/*$declare${AOs::AO_Blinky1} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//$declare${AOs::AO_Blinky1} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/*${AOs::AO_Blinky1} .......................................................*/ +//${AOs::AO_Blinky1} ......................................................... extern QActive * const AO_Blinky1; -/*$enddecl${AOs::AO_Blinky1} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*$declare${AOs::Blinky1_ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//$enddecl${AOs::AO_Blinky1} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +//$declare${AOs::Blinky1_ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/*${AOs::Blinky1_ctor} .....................................................*/ +//${AOs::Blinky1_ctor} ....................................................... void Blinky1_ctor(void); -/*$enddecl${AOs::Blinky1_ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$enddecl${AOs::Blinky1_ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ #endif -#endif /* LOW_POWER_H */ +#endif // LOW_POWER_H diff --git a/examples/arm-cm/low-power_ek-tm4c123gxl/main.c b/examples/arm-cm/low-power_ek-tm4c123gxl/main.c index 5ee14712..c185871a 100644 --- a/examples/arm-cm/low-power_ek-tm4c123gxl/main.c +++ b/examples/arm-cm/low-power_ek-tm4c123gxl/main.c @@ -1,91 +1,86 @@ -/***************************************************************************** -* Product: "Blinky Low-Power" example -* Last updated for version 7.1.1 -* Last updated on 2022-09-21 -* -* Q u a n t u m L e a P s -* ------------------------ -* Modern Embedded Software -* -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* -* -*****************************************************************************/ +//============================================================================ +// Product: "Low-Power" example +// Last updated for version 7.3.0 +// Last updated on 2023-08-25 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// This program is open source software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Alternatively, this program may be distributed and modified under the +// terms of Quantum Leaps commercial licenses, which expressly supersede +// the GNU General Public License and are specifically designed for +// licensees interested in retaining the proprietary status of their code. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Contact information: +// +// +//============================================================================ #include "qpc.h" #include "low_power.h" #include "bsp.h" -Q_DEFINE_THIS_FILE +//Q_DEFINE_THIS_FILE -/*..........................................................................*/ +//............................................................................ int main() { - static QSubscrList subscrSto[MAX_PUB_SIG]; + QF_init(); // initialize the framework and the underlying RT kernel + BSP_init(); // initialize the Board Support Package - static QEvt const *l_blinky0QSto[10]; /* queue storage for Blinky0 */ -#ifdef QP_INC_QXK_H_ /* QXK kernel? */ - static uint32_t const *l_xblinky1Stack[64]; /* stack for XBlinky1 */ -#else - static QEvt const *l_blinky1QSto[10]; /* queue storage for Blinky1 */ -#endif /* QP_INC_QXK_H_ */ - - QF_init(); /* initialize the framework and the underlying RT kernel */ - BSP_init(); /* initialize the Board Support Package */ - - QF_psInit(subscrSto, Q_DIM(subscrSto)); /* init publish-subscribe */ - - /* initialize event pools... */ + // initialize event pools... //QF_poolInit(smlPoolSto, sizeof(smlPoolSto), sizeof(smlPoolSto[0])); - /* instantiate and start the active objects... */ + static QSubscrList subscrSto[MAX_PUB_SIG]; + QActive_psInit(subscrSto, Q_DIM(subscrSto)); // init publish-subscribe + + // instantiate and start the active objects... Blinky0_ctor(); - QACTIVE_START(AO_Blinky0, /* AO pointer */ - 1U, /* unique QP priority of the AO */ - l_blinky0QSto, /* storage for the AO's queue */ - Q_DIM(l_blinky0QSto), /* length of the queue [entries] */ - (void *)0, /* stack storage (not used in QK) */ - 0U, /* stack size [bytes] (not used in QK) */ - (QEvt *)0); /* initial event (or 0) */ + static QEvt const *l_blinky0QSto[10]; // queue storage for Blinky0 + QACTIVE_START(AO_Blinky0, // AO pointer + 1U, // unique QP priority of the AO + l_blinky0QSto, // storage for the AO's queue + Q_DIM(l_blinky0QSto), // length of the queue [entries] + (void *)0, // stack storage (not used in QK) + 0U, // stack size [bytes] (not used in QK) + (void *)0); // initial param (not used) -#ifdef QP_INC_QXK_H_ /* QXK kernel? */ - QXSemaphore_init(&XSEM_sw1, 0U, 1U); /* signaling binary semaphore */ +#ifdef QXK_H_ // QXK kernel? XBlinky1_ctor(); - QXTHREAD_START(&XT_Blinky1, /* extended thread pointer */ - 2U, /* unique QP priority of the AO */ - (QEvt *)0, /* storage for the AO's queue (not used) */ - 0U, /* length of the queue [entries] */ - l_xblinky1Stack, /* stack storage (must provide in QXK) */ - sizeof(l_xblinky1Stack), /* stack size [bytes] */ - (QEvt *)0); /* initial event (or 0) */ -#else /* QV or QK kernels */ + static uint32_t const *l_xblinky1Stack[64]; // stack for XBlinky1 + QXSemaphore_init(&XSEM_sw1, 0U, 1U); // signaling binary semaphore + QXTHREAD_START(&XT_Blinky1, // extended thread pointer + 2U, // unique QP priority of the AO + (QEvt const **)0, // storage for the AO's queue (not used) + 0U, // length of the queue [entries] + l_xblinky1Stack, // stack storage (must provide in QXK) + sizeof(l_xblinky1Stack), // stack size [bytes] + (void *)0); // initial param (not used) +#else // QV or QK kernels Blinky1_ctor(); - QACTIVE_START(AO_Blinky1, /* AO pointer */ - 2U, /* unique QP priority of the AO */ - l_blinky1QSto, /* storage for the AO's queue */ - Q_DIM(l_blinky1QSto), /* lenght of the queue [entries] */ - (void *)0, /* stack storage (not used in QK) */ - 0U, /* stack size [bytes] (not used in QK) */ - (QEvt *)0); /* initial event (or 0) */ -#endif /* QP_INC_QXK_H_ */ + static QEvt const *l_blinky1QSto[10]; // queue storage for Blinky1 + QACTIVE_START(AO_Blinky1, // AO pointer + 2U, // unique QP priority of the AO + l_blinky1QSto, // storage for the AO's queue + Q_DIM(l_blinky1QSto), // length of the queue [entries] + (void *)0, // stack storage (not used in QK) + 0U, // stack size [bytes] (not used in QK) + (void *)0); // initial param (not used) +#endif // QXK_H_ - return QF_run(); /* run the QF application */ + return QF_run(); // run the QF application } diff --git a/examples/arm-cm/low-power_ek-tm4c123gxl/qk/armclang/low-power-qk.uvoptx b/examples/arm-cm/low-power_ek-tm4c123gxl/qk/armclang/low-power-qk.uvoptx index 632a3d74..470c60c0 100644 --- a/examples/arm-cm/low-power_ek-tm4c123gxl/qk/armclang/low-power-qk.uvoptx +++ b/examples/arm-cm/low-power_ek-tm4c123gxl/qk/armclang/low-power-qk.uvoptx @@ -10,7 +10,7 @@ *.s*; *.src; *.a* *.obj; *.o *.lib - *.txt; *.h; *.inc + *.txt; *.h; *.inc; *.md *.plm *.cpp 0 @@ -103,7 +103,7 @@ 1 0 0 - 8 + 19 @@ -287,7 +287,7 @@ 1 0 0 - 8 + 19 @@ -510,7 +510,7 @@ 1 0 0 - 8 + 19 @@ -666,7 +666,7 @@ 0 0 0 - ..\..\..\..\..\include\qstamp.c + ..\..\..\..\..\src\qs\qstamp.c qstamp.c 0 0 diff --git a/examples/arm-cm/low-power_ek-tm4c123gxl/qk/armclang/low-power-qk.uvprojx b/examples/arm-cm/low-power_ek-tm4c123gxl/qk/armclang/low-power-qk.uvprojx index cd3754c8..5edb2593 100644 --- a/examples/arm-cm/low-power_ek-tm4c123gxl/qk/armclang/low-power-qk.uvprojx +++ b/examples/arm-cm/low-power_ek-tm4c123gxl/qk/armclang/low-power-qk.uvprojx @@ -10,7 +10,7 @@ low-power-dbg 0x4 ARM-ADS - 5060750::V5.06 update 6 (build 750)::ARMCC + 6160000::V6.16::ARMCLANG 1 @@ -185,6 +185,7 @@ 0 2 0 + 0 0 0 8 @@ -336,7 +337,7 @@ 0 - __FPU_PRESENT + QP_CONFIG ..\..;..\..\..\..\..\include;..\..\..\..\..\ports\arm-cm\qk\armclang;..\..\..\..\..\3rd_party\CMSIS\Include;..\..\..\..\..\3rd_party\ek-tm4c123gxl @@ -351,7 +352,7 @@ 0 1 0 - 0 + 4 Stack_Size=2048 Heap_Size=16 @@ -395,7 +396,7 @@ qstamp.c 1 - ..\..\..\..\..\include\qstamp.c + ..\..\..\..\..\src\qs\qstamp.c blinky0.c @@ -600,7 +601,7 @@ 2 2 2 - 2 + 0 @@ -639,7 +640,7 @@ low-power-rel 0x4 ARM-ADS - 5060020::V5.06 (build 20)::ARMCC + 6160000::V6.16::ARMCLANG 1 @@ -814,6 +815,7 @@ 0 2 0 + 0 0 0 8 @@ -965,7 +967,7 @@ 0 - NDEBUG __FPU_PRESENT + NDEBUG,QP_CONFIG ..\..;..\..\..\..\..\include;..\..\..\..\..\ports\arm-cm\qk\armclang;..\..\..\..\..\3rd_party\CMSIS\Include;..\..\..\..\..\3rd_party\ek-tm4c123gxl @@ -980,7 +982,7 @@ 0 1 0 - 0 + 4 Stack_Size=2048 Heap_Size=16 @@ -1024,7 +1026,7 @@ qstamp.c 1 - ..\..\..\..\..\include\qstamp.c + ..\..\..\..\..\src\qs\qstamp.c blinky0.c @@ -1229,7 +1231,7 @@ 2 2 2 - 2 + 0 @@ -1268,7 +1270,7 @@ low-power-spy 0x4 ARM-ADS - 5060183::V5.06 update 2 (build 183)::ARMCC + 6160000::V6.16::ARMCLANG 1 @@ -1443,6 +1445,7 @@ 0 2 0 + 0 0 0 8 @@ -1594,7 +1597,7 @@ 0 - Q_SPY __FPU_PRESENT + Q_SPY,QP_CONFIG ..\..;..\..\..\..\..\include;..\..\..\..\..\ports\arm-cm\qk\armclang;..\..\..\..\..\3rd_party\CMSIS\Include;..\..\..\..\..\3rd_party\ek-tm4c123gxl @@ -1609,7 +1612,7 @@ 0 1 0 - 0 + 4 Stack_Size=2048 Heap_Size=16 @@ -1653,7 +1656,7 @@ qstamp.c 1 - ..\..\..\..\..\include\qstamp.c + ..\..\..\..\..\src\qs\qstamp.c blinky0.c diff --git a/examples/arm-cm/low-power_ek-tm4c123gxl/qk/bsp.c b/examples/arm-cm/low-power_ek-tm4c123gxl/qk/bsp.c index b426c297..dff8f62b 100644 --- a/examples/arm-cm/low-power_ek-tm4c123gxl/qk/bsp.c +++ b/examples/arm-cm/low-power_ek-tm4c123gxl/qk/bsp.c @@ -1,45 +1,45 @@ -/***************************************************************************** -* Product: "Low-Power" example, EK-TM4C123GXL board, QK kernel -* Last updated for version 6.4.0 -* Last updated on 2019-02-25 -* -* Q u a n t u m L e a P s -* ------------------------ -* Modern Embedded Software -* -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* -* -*****************************************************************************/ +//============================================================================ +// Product: "Low-Power" example, EK-TM4C123GXL board, QK kernel +// Last updated for version 7.3.0 +// Last updated on 2023-07-23 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// This program is open source software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Alternatively, this program may be distributed and modified under the +// terms of Quantum Leaps commercial licenses, which expressly supersede +// the GNU General Public License and are specifically designed for +// licensees interested in retaining the proprietary status of their code. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Contact information: +// +// +//============================================================================ #include "qpc.h" #include "low_power.h" #include "bsp.h" -#include "TM4C123GH6PM.h" /* the device specific header (TI) */ -#include "rom.h" /* the built-in ROM functions (TI) */ -#include "sysctl.h" /* system control driver (TI) */ -#include "gpio.h" /* GPIO driver (TI) */ -/* add other drivers if necessary... */ +#include "TM4C123GH6PM.h" // the device specific header (TI) +#include "rom.h" // the built-in ROM functions (TI) +#include "sysctl.h" // system control driver (TI) +#include "gpio.h" // GPIO driver (TI) +// add other drivers if necessary... //Q_DEFINE_THIS_FILE @@ -47,22 +47,22 @@ #error The low-power example does not provide Spy build configuration #endif -/* ISRs defined in this BSP ------------------------------------------------*/ +// ISRs defined in this BSP ------------------------------------------------ void SysTick_Handler(void); void GPIOPortA_IRQHandler(void); -/* Local-scope objects -----------------------------------------------------*/ +// Local-scope objects ----------------------------------------------------- -/* bitmask of active sub-systems needed for low-power operation. -* NOTE: shared between the idle thread application, see NOTE1 -*/ +// bitmask of active sub-systems needed for low-power operation. +// NOTE: shared between the idle thread application, see NOTE1 +// static uint32_t volatile l_activeSet; -/* bits in the l_activeSet bitmask */ +// bits in the l_activeSet bitmask enum { SYSTICK_ACTIVE, TIMER0_ACTIVE, - /* ... */ + // ... }; #define LED_RED (1U << 1) @@ -72,158 +72,159 @@ enum { #define XTAL_HZ 16000000U -/* ISRs used in this project ===============================================*/ +// ISRs used in this project =============================================== void SysTick_Handler(void) { - QK_ISR_ENTRY(); /* inform QK about entering an ISR */ - QTIMEEVT_TICK_X(0U, (void *)0); /* process time events for rate 0 */ - QK_ISR_EXIT(); /* inform QK about exiting an ISR */ + QK_ISR_ENTRY(); // inform QK about entering an ISR + QTIMEEVT_TICK_X(0U, (void *)0); // process time events for rate 0 + QK_ISR_EXIT(); // inform QK about exiting an ISR } -/*..........................................................................*/ +//............................................................................ void Timer0A_IRQHandler(void) { - QK_ISR_ENTRY(); /* inform QK about entering an ISR */ - TIMER0->ICR |= (1U << 0); /* clear the Timer0 interrupt source */ - QTIMEEVT_TICK_X(1U, (void *)0); /* process time events for rate 1 */ - QK_ISR_EXIT(); /* inform QK about exiting an ISR */ + QK_ISR_ENTRY(); // inform QK about entering an ISR + TIMER0->ICR |= (1U << 0); // clear the Timer0 interrupt source + QTIMEEVT_TICK_X(1U, (void *)0); // process time events for rate 1 + QK_ISR_EXIT(); // inform QK about exiting an ISR } -/*..........................................................................*/ +//............................................................................ void GPIOPortF_IRQHandler(void) { - QK_ISR_ENTRY(); /* inform QK about entering an ISR */ - if ((GPIOF->RIS & BTN_SW1) != 0U) { /* interrupt caused by SW1? */ - static QEvt const pressedEvt = { BTN_PRESSED_SIG, 0U, 0U}; + QK_ISR_ENTRY(); // inform QK about entering an ISR + if ((GPIOF->RIS & BTN_SW1) != 0U) { // interrupt caused by SW1? + static QEvt const pressedEvt = QEVT_INITIALIZER(BTN_PRESSED_SIG); QACTIVE_PUBLISH(&pressedEvt, (void *)0); } - GPIOF->ICR = 0xFFU; /* clear interrupt sources */ - QK_ISR_EXIT(); /* inform QK about exiting an ISR */ + GPIOF->ICR = 0xFFU; // clear interrupt sources + QK_ISR_EXIT(); // inform QK about exiting an ISR } -/* BSP functions ===========================================================*/ +// BSP functions =========================================================== void BSP_init(void) { - /* Set the clocking to run directly from the crystal */ + // Set the clocking to run directly from the crystal ROM_SysCtlClockSet(SYSCTL_SYSDIV_1 | SYSCTL_USE_OSC | SYSCTL_OSC_MAIN | SYSCTL_XTAL_16MHZ); SystemCoreClock = XTAL_HZ; - /* NOTE The VFP (Floating Point Unit) unit is configured by QK-port */ + // NOTE The VFP (Floating Point Unit) unit is configured by QK-port - /* configure Timer0, but don't enable the interrupt just yet */ - SYSCTL->RCGCTIMER |= (1U << 0); /* enable Run mode for Timer0 */ - TIMER0->CTL &= ~(1U << 0); /* disable Timer0 before any changes */ + // configure Timer0, but don't enable the interrupt just yet + SYSCTL->RCGCTIMER |= (1U << 0); // enable Run mode for Timer0 + TIMER0->CTL &= ~(1U << 0); // disable Timer0 before any changes TIMER0->CFG = 0U; - TIMER0->TAMR |= (0x2 << 0); /* Timer0A */ + TIMER0->TAMR |= (0x2 << 0); // Timer0A TIMER0->TAMR &= ~(1U << 4); TIMER0->TAILR = XTAL_HZ / BSP_TICKS1_PER_SEC; - TIMER0->IMR &= ~(1U << 0); /* disable timer interrupt for now */ - SYSCTL->RCGCTIMER &= ~(1U << 0); /* disable Run mode for Timer0 */ + TIMER0->IMR &= ~(1U << 0); // disable timer interrupt for now + SYSCTL->RCGCTIMER &= ~(1U << 0); // disable Run mode for Timer0 - /* configure the LEDs and push buttons */ - SYSCTL->RCGCGPIO |= (1U << 5); /* enable Run mode for GPIOF */ - GPIOF->DIR |= (LED_RED | LED_GREEN | LED_BLUE);/* set direction: output */ - GPIOF->DEN |= (LED_RED | LED_GREEN | LED_BLUE); /* digital enable */ - GPIOF->DATA_Bits[LED_RED | LED_GREEN | LED_BLUE] = 0U; /* turn off */ + // configure the LEDs and push buttons + SYSCTL->RCGCGPIO |= (1U << 5); // enable Run mode for GPIOF + GPIOF->DIR |= (LED_RED | LED_GREEN | LED_BLUE);// set direction: output + GPIOF->DEN |= (LED_RED | LED_GREEN | LED_BLUE); // digital enable + GPIOF->DATA_Bits[LED_RED | LED_GREEN | LED_BLUE] = 0U; // turn off - /* configure the button SW1 */ - GPIOF->DIR &= ~BTN_SW1; /* input */ - GPIOF->DEN |= BTN_SW1; /* digital enable */ - GPIOF->PUR |= BTN_SW1; /* pull-up resistor enable */ + // configure the button SW1 + GPIOF->DIR &= ~BTN_SW1; // input + GPIOF->DEN |= BTN_SW1; // digital enable + GPIOF->PUR |= BTN_SW1; // pull-up resistor enable - /* configure the GPIO interrupt for SW1 */ - GPIOF->IS &= ~BTN_SW1; /* edge detect for SW1 */ - GPIOF->IBE &= ~BTN_SW1; /* only one edge generate the interrupt */ - GPIOF->IEV &= ~BTN_SW1; /* a falling edge triggers the interrupt */ - GPIOF->IM |= BTN_SW1; /* enable GPIOF interrupt for SW1 */ + // configure the GPIO interrupt for SW1 + GPIOF->IS &= ~BTN_SW1; // edge detect for SW1 + GPIOF->IBE &= ~BTN_SW1; // only one edge generate the interrupt + GPIOF->IEV &= ~BTN_SW1; // a falling edge triggers the interrupt + GPIOF->IM |= BTN_SW1; // enable GPIOF interrupt for SW1 } -/*..........................................................................*/ +//............................................................................ void BSP_led0_off(void) { GPIOF->DATA_Bits[LED_GREEN] = 0U; } -/*..........................................................................*/ +//............................................................................ void BSP_led0_on(void) { GPIOF->DATA_Bits[LED_GREEN] = 0xFFU; } -/*..........................................................................*/ +//............................................................................ void BSP_led1_off(void) { GPIOF->DATA_Bits[LED_BLUE] = 0U; } -/*..........................................................................*/ +//............................................................................ void BSP_led1_on(void) { GPIOF->DATA_Bits[LED_BLUE] = 0xFFU; } -/*..........................................................................*/ +//............................................................................ void BSP_tickRate0_on(void) { - /* enable SysTick IRQ and Timer */ + // enable SysTick IRQ and Timer SysTick->CTRL |= (SysTick_CTRL_TICKINT_Msk | SysTick_CTRL_ENABLE_Msk); l_activeSet |= (1U << SYSTICK_ACTIVE); } -/*..........................................................................*/ +//............................................................................ void BSP_tickRate1_on(void) { - SYSCTL->RCGCTIMER |= (1U << 0); /* enable Run mode for Timer0 */ - TIMER0->CTL &= ~(1U << 0); /* disable Timer0 before any changes */ - TIMER0->IMR |= (1U << 0); /* enable timer interrupt */ - TIMER0->CTL |= (1U << 0); /* enable Timer0 after the changes */ + SYSCTL->RCGCTIMER |= (1U << 0); // enable Run mode for Timer0 + TIMER0->CTL &= ~(1U << 0); // disable Timer0 before any changes + TIMER0->IMR |= (1U << 0); // enable timer interrupt + TIMER0->CTL |= (1U << 0); // enable Timer0 after the changes l_activeSet |= (1U << TIMER0_ACTIVE); } -/* QF callbacks ============================================================*/ +// QF callbacks ============================================================ void QF_onStartup(void) { - /* set up the SysTick timer to fire at BSP_TICKS0_PER_SEC rate */ + // set up the SysTick timer to fire at BSP_TICKS0_PER_SEC rate SysTick_Config(SystemCoreClock / BSP_TICKS0_PER_SEC); - /* assign all priority bits for preemption-prio. and none to sub-prio. */ + // assign all priority bits for preemption-prio. and none to sub-prio. NVIC_SetPriorityGrouping(0U); - /* set priorities of ALL ISRs used in the system, see NOTE00 - * - * !!!!!!!!!!!!!!!!!!!!!!!!!!!! CAUTION !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - * Assign a priority to EVERY ISR explicitly by calling NVIC_SetPriority(). - * DO NOT LEAVE THE ISR PRIORITIES AT THE DEFAULT VALUE! - */ + // set priorities of ALL ISRs used in the system, see NOTE00 + // + // !!!!!!!!!!!!!!!!!!!!!!!!!!!! CAUTION !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + // Assign a priority to EVERY ISR explicitly by calling NVIC_SetPriority(). + // DO NOT LEAVE THE ISR PRIORITIES AT THE DEFAULT VALUE! + // NVIC_SetPriority(TIMER0A_IRQn, QF_AWARE_ISR_CMSIS_PRI); NVIC_SetPriority(SysTick_IRQn, QF_AWARE_ISR_CMSIS_PRI + 1U); NVIC_SetPriority(GPIOF_IRQn, QF_AWARE_ISR_CMSIS_PRI + 1U); - /* ... */ + // ... - /* enable IRQs in the NVIC... */ + // enable IRQs in the NVIC... NVIC_EnableIRQ(GPIOF_IRQn); NVIC_EnableIRQ(TIMER0A_IRQn); } -/*..........................................................................*/ +//............................................................................ void QF_onCleanup(void) { } -/*..........................................................................*/ +//............................................................................ void QK_onIdle(void) { QF_INT_DISABLE(); - if (((l_activeSet & (1U << SYSTICK_ACTIVE)) != 0U) /* rate-0 enabled? */ - && QF_noTimeEvtsActiveX(0U)) /* no time events at rate-0? */ + if (((l_activeSet & (1U << SYSTICK_ACTIVE)) != 0U) // rate-0 enabled? + && QTimeEvt_noActive(0U)) // no time events at rate-0? { - /* safe to disable SysTick and interrupt */ + // safe to disable SysTick and interrupt SysTick->CTRL &= ~(SysTick_CTRL_TICKINT_Msk | SysTick_CTRL_ENABLE_Msk); - l_activeSet &= ~(1U << SYSTICK_ACTIVE); /* mark rate-0 as disabled */ + l_activeSet &= ~(1U << SYSTICK_ACTIVE); // mark rate-0 as disabled } - if (((l_activeSet & (1U << TIMER0_ACTIVE)) != 0U) /* rate-1 enabled? */ - && QF_noTimeEvtsActiveX(1U)) /* no time events at rate-1? */ + if (((l_activeSet & (1U << TIMER0_ACTIVE)) != 0U) // rate-1 enabled? + && QTimeEvt_noActive(1U)) // no time events at rate-1? { - /* safe to disable Timer0 and interrupt */ - TIMER0->CTL &= ~(1U << 0); /* disable Timer0 */ - TIMER0->IMR &= ~(1U << 0); /* disable timer interrupt */ - l_activeSet &= ~(1U << TIMER0_ACTIVE); /* mark rate-1 as disabled */ + // safe to disable Timer0 and interrupt + TIMER0->CTL &= ~(1U << 0); // disable Timer0 + TIMER0->IMR &= ~(1U << 0); // disable timer interrupt + l_activeSet &= ~(1U << TIMER0_ACTIVE); // mark rate-1 as disabled } QF_INT_ENABLE(); - GPIOF->DATA_Bits[LED_RED] = 0xFFU; /* turn LED on, see NOTE2 */ - __WFI(); // wait for interrupt */ - GPIOF->DATA_Bits[LED_RED] = 0x00U; /* turn LED off, see NOTE2 */ + GPIOF->DATA_Bits[LED_RED] = 0xFFU; // turn LED on, see NOTE2 + __WFI(); // wait for interrupt + GPIOF->DATA_Bits[LED_RED] = 0x00U; // turn LED off, see NOTE2 } -/*..........................................................................*/ -Q_NORETURN Q_onAssert(char const * const module, int_t const loc) { - /* - * NOTE: add here your application-specific error handling - */ - (void)module; - (void)loc; +//............................................................................ +Q_NORETURN Q_onError(char const * const module, int_t const id) { + // + // NOTE: add here your application-specific error handling + // + Q_UNUSED_PAR(module); + Q_UNUSED_PAR(id); + #ifndef NDEBUG - /* for debugging, hang on in an endless loop toggling the RED LED... */ + // for debugging, hang on in an endless loop toggling the RED LED... while (GPIOF->DATA_Bits[BTN_SW1] != 0) { GPIOF->DATA = LED_RED; GPIOF->DATA = 0U; @@ -231,20 +232,25 @@ Q_NORETURN Q_onAssert(char const * const module, int_t const loc) { #endif NVIC_SystemReset(); } +//............................................................................ +void assert_failed(char const * const module, int_t const id); // prototype +void assert_failed(char const * const module, int_t const id) { + Q_onError(module, id); +} -/***************************************************************************** -* NOTE1: -* The bitmask l_activeSet is **shared** between the QK idle thread and -* the application-level threads. Therefore this variable needs to be -* always accessed in a critical section. -* -* NOTE2: -* One of the LEDs is used to visualize the CPU sleep mode. The LED is turned -* on before entering the sleep mode and turned off after waking up, so that -* the LED stays ON when the CPU sleeps. -* -* NOTE3: -* The additional polling-delay is added to artificially extend the CPU -* activity after the sleep mode is exited, so that the time the idle-LED -* stays off for a bit longer and can be observed on the slower logic analyzer. -*/ +//============================================================================ +// NOTE1: +// The bitmask l_activeSet is **shared** between the QK idle thread and +// the application-level threads. Therefore this variable needs to be +// always accessed in a critical section. +// +// NOTE2: +// One of the LEDs is used to visualize the CPU sleep mode. The LED is turned +// on before entering the sleep mode and turned off after waking up, so that +// the LED stays ON when the CPU sleeps. +// +// NOTE3: +// The additional polling-delay is added to artificially extend the CPU +// activity after the sleep mode is exited, so that the time the idle-LED +// stays off for a bit longer and can be observed on the slower logic analyzer. +// diff --git a/examples/arm-cm/low-power_ek-tm4c123gxl/qk/gnu/Makefile b/examples/arm-cm/low-power_ek-tm4c123gxl/qk/gnu/Makefile index 374739a6..b73ec70c 100644 --- a/examples/arm-cm/low-power_ek-tm4c123gxl/qk/gnu/Makefile +++ b/examples/arm-cm/low-power_ek-tm4c123gxl/qk/gnu/Makefile @@ -1,7 +1,7 @@ ############################################################################## # Product: Makefile for QP/C on EK-TM4C123GXL, QK kernel, GNU-ARM -# Last Updated for Version: 7.0.1 -# Date of the Last Update: 2022-05-23 +# Last Updated for Version: 7.3.0 +# Date of the Last Update: 2023-09-03 # # Q u a n t u m L e a P s # ------------------------ @@ -133,7 +133,7 @@ LIB_DIRS := LIBS := # defines -DEFINES := -DTARGET_IS_TM4C123_RB1 +DEFINES := -DQP_CONFIG # ARM CPU, ARCH, FPU, and Float-ABI types... # ARM_CPU: [cortex-m0 | cortex-m0plus | cortex-m1 | cortex-m3 | cortex-m4] @@ -267,7 +267,7 @@ $(TARGET_BIN): $(TARGET_ELF) $(BIN) -O binary $< $@ $(TARGET_ELF) : $(ASM_OBJS_EXT) $(C_OBJS_EXT) $(CPP_OBJS_EXT) - $(CC) $(CFLAGS) $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o + $(CC) $(CFLAGS) $(QPC)/src/qs/qstamp.c -o $(BIN_DIR)/qstamp.o $(LINK) $(LINKFLAGS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) $(BIN_DIR)/%.d : %.c diff --git a/examples/arm-cm/low-power_ek-tm4c123gxl/qk/iar/low-power-qk.ewd b/examples/arm-cm/low-power_ek-tm4c123gxl/qk/iar/low-power-qk.ewd index 1587ed94..ddd36639 100644 --- a/examples/arm-cm/low-power_ek-tm4c123gxl/qk/iar/low-power-qk.ewd +++ b/examples/arm-cm/low-power_ek-tm4c123gxl/qk/iar/low-power-qk.ewd @@ -11,7 +11,7 @@ C-SPY 2 - 28 + 32 1 1 - - + + + + + @@ -486,7 +498,7 @@ IJET_ID 2 - 8 + 9 1 1 + + + + + + + + + + + + + @@ -916,7 +980,7 @@ LMIFTDI_ID 2 - 2 + 3 1 1 + + + + + + + NULINK_ID + 2 + + 0 + 1 + 1 + + + @@ -974,7 +1072,7 @@ STLINK_ID 2 - 4 + 8 1 1 + + + + @@ -1185,7 +1300,7 @@ XDS100_ID 2 - 6 + 9 1 1 + + + + @@ -1362,6 +1493,18 @@ $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin 0 + + $TOOLKIT_DIR$\plugins\rtos\FreeRtos\FreeRtosArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin2.ENU.ewplugin + 0 + $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin 0 @@ -1371,11 +1514,15 @@ 0 - $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9.ewplugin 0 - $TOOLKIT_DIR$\plugins\rtos\TI-RTOS\tirtosplugin.ewplugin + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9BE.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin 0 @@ -1391,11 +1538,11 @@ 0 - $EW_DIR$\common\plugins\CodeCoverage\CodeCoverage.ENU.ewplugin - 1 + $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + 0 - $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + $EW_DIR$\common\plugins\TargetAccessServer\TargetAccessServer.ENU.ewplugin 0 @@ -1414,7 +1561,7 @@ C-SPY 2 - 28 + 32 1 0 - - + + + + + @@ -1889,7 +2048,7 @@ IJET_ID 2 - 8 + 9 1 0 + + + + + + + + + + + + + @@ -2319,7 +2530,7 @@ LMIFTDI_ID 2 - 2 + 3 1 0 + + + + + + + NULINK_ID + 2 + + 0 + 1 + 0 + + + @@ -2377,7 +2622,7 @@ STLINK_ID 2 - 4 + 8 1 0 + + + + @@ -2588,7 +2850,7 @@ XDS100_ID 2 - 6 + 9 1 0 + + + + @@ -2765,6 +3043,18 @@ $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin 0 + + $TOOLKIT_DIR$\plugins\rtos\FreeRtos\FreeRtosArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin2.ENU.ewplugin + 0 + $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin 0 @@ -2774,11 +3064,15 @@ 0 - $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9.ewplugin 0 - $TOOLKIT_DIR$\plugins\rtos\TI-RTOS\tirtosplugin.ewplugin + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9BE.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin 0 @@ -2794,11 +3088,11 @@ 0 - $EW_DIR$\common\plugins\CodeCoverage\CodeCoverage.ENU.ewplugin - 1 + $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + 0 - $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + $EW_DIR$\common\plugins\TargetAccessServer\TargetAccessServer.ENU.ewplugin 0 @@ -2817,7 +3111,7 @@ C-SPY 2 - 28 + 32 1 1 - - + + + + + @@ -3292,7 +3598,7 @@ IJET_ID 2 - 8 + 9 1 1 + + + + + + + + + + + + + @@ -3722,7 +4080,7 @@ LMIFTDI_ID 2 - 2 + 3 1 1 + + + + + + + NULINK_ID + 2 + + 0 + 1 + 1 + + + @@ -3780,7 +4172,7 @@ STLINK_ID 2 - 4 + 8 1 1 + + + + @@ -3991,7 +4400,7 @@ XDS100_ID 2 - 6 + 9 1 1 + + + + @@ -4168,6 +4593,18 @@ $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin 0 + + $TOOLKIT_DIR$\plugins\rtos\FreeRtos\FreeRtosArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin2.ENU.ewplugin + 0 + $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin 0 @@ -4177,11 +4614,15 @@ 0 - $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9.ewplugin 0 - $TOOLKIT_DIR$\plugins\rtos\TI-RTOS\tirtosplugin.ewplugin + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9BE.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin 0 @@ -4197,11 +4638,11 @@ 0 - $EW_DIR$\common\plugins\CodeCoverage\CodeCoverage.ENU.ewplugin - 1 + $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + 0 - $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + $EW_DIR$\common\plugins\TargetAccessServer\TargetAccessServer.ENU.ewplugin 0 diff --git a/examples/arm-cm/low-power_ek-tm4c123gxl/qk/iar/low-power-qk.ewp b/examples/arm-cm/low-power_ek-tm4c123gxl/qk/iar/low-power-qk.ewp index eee295bd..6b18a156 100644 --- a/examples/arm-cm/low-power_ek-tm4c123gxl/qk/iar/low-power-qk.ewp +++ b/examples/arm-cm/low-power_ek-tm4c123gxl/qk/iar/low-power-qk.ewp @@ -11,9 +11,13 @@ General 3 - 31 + 35 1 1 + - - - - - + + + + + ICCARM 2 - 35 + 37 1 1 - - - + AARM 2 - 10 + 11 1 1 + @@ -673,13 +669,9 @@ 0 + inputOutputBased - - BICOMP - 0 - - BUILDACTION 1 @@ -692,17 +684,13 @@ ILINK 0 - 22 + 27 1 1 - + + + + + + + + + + + + + @@ -1035,11 +1075,6 @@ - - BILINK - 0 - - Coder 0 @@ -1056,9 +1091,13 @@ General 3 - 31 + 35 1 0 + - - - - - + + + + + ICCARM 2 - 35 + 37 1 0 - - - + AARM 2 - 10 + 11 1 0 + @@ -1718,13 +1750,9 @@ 0 + inputOutputBased - - BICOMP - 0 - - BUILDACTION 1 @@ -1737,17 +1765,13 @@ ILINK 0 - 22 + 27 1 0 - + + + + + + + + + + + + + @@ -2080,11 +2156,6 @@ - - BILINK - 0 - - Coder 0 @@ -2101,9 +2172,13 @@ General 3 - 31 + 35 1 1 + - - - - - + + + + + ICCARM 2 - 35 + 37 1 1 - - - + AARM 2 - 10 + 11 1 1 + @@ -2763,13 +2831,9 @@ 0 + inputOutputBased - - BICOMP - 0 - - BUILDACTION 1 @@ -2782,17 +2846,13 @@ ILINK 0 - 22 + 27 1 1 - + + + + + + + + + + + + + @@ -3125,11 +3237,6 @@ - - BILINK - 0 - - Coder 0 @@ -3156,9 +3263,6 @@ $PROJ_DIR$\..\..\main.c - - $PROJ_DIR$\..\..\..\..\..\include\qstamp.c - ek-tm4c123gxl @@ -3254,10 +3358,10 @@ $PROJ_DIR$\..\..\..\..\..\src\qs\qs_fp.c - $PROJ_DIR$\..\..\..\..\..\src\qs\qs_pkg.h + $PROJ_DIR$\..\..\..\..\..\src\qs\qs_rx.c - $PROJ_DIR$\..\..\..\..\..\src\qs\qs_rx.c + $PROJ_DIR$\..\..\..\..\..\src\qs\qstamp.c diff --git a/examples/arm-cm/low-power_ek-tm4c123gxl/qp_config.h b/examples/arm-cm/low-power_ek-tm4c123gxl/qp_config.h new file mode 100644 index 00000000..f1f75ea5 --- /dev/null +++ b/examples/arm-cm/low-power_ek-tm4c123gxl/qp_config.h @@ -0,0 +1,42 @@ +//============================================================================ +// QP configuration file example +// Last updated for version: 7.3.0 +// Last updated on: 2023-09-02 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +//============================================================================ +#ifndef QP_CONFIG_H_ +#define QP_CONFIG_H_ + +// NOTE: +// The QP configuration takes effect only when the macro QP_CONFIG +// is defined on the command-line to the compiler for all QP source files. + +// The maximum number of system clock tick rates +#define QF_MAX_TICK_RATE 2U + +#endif // QP_CONFIG_H_ diff --git a/examples/arm-cm/low-power_ek-tm4c123gxl/qv/armclang/low-power-qv.uvoptx b/examples/arm-cm/low-power_ek-tm4c123gxl/qv/armclang/low-power-qv.uvoptx index fd62d96b..e019ae35 100644 --- a/examples/arm-cm/low-power_ek-tm4c123gxl/qv/armclang/low-power-qv.uvoptx +++ b/examples/arm-cm/low-power_ek-tm4c123gxl/qv/armclang/low-power-qv.uvoptx @@ -10,7 +10,7 @@ *.s*; *.src; *.a* *.obj; *.o *.lib - *.txt; *.h; *.inc + *.txt; *.h; *.inc; *.md *.plm *.cpp 0 @@ -103,7 +103,7 @@ 1 0 0 - 8 + 19 @@ -304,7 +304,7 @@ 1 0 0 - 8 + 19 @@ -527,7 +527,7 @@ 1 0 0 - 8 + 19 @@ -683,7 +683,7 @@ 0 0 0 - ..\..\..\..\..\include\qstamp.c + ..\..\..\..\..\src\qs\qstamp.c qstamp.c 0 0 diff --git a/examples/arm-cm/low-power_ek-tm4c123gxl/qv/armclang/low-power-qv.uvprojx b/examples/arm-cm/low-power_ek-tm4c123gxl/qv/armclang/low-power-qv.uvprojx index e6585247..30e3873f 100644 --- a/examples/arm-cm/low-power_ek-tm4c123gxl/qv/armclang/low-power-qv.uvprojx +++ b/examples/arm-cm/low-power_ek-tm4c123gxl/qv/armclang/low-power-qv.uvprojx @@ -10,7 +10,7 @@ low-power-dbg 0x4 ARM-ADS - 5060750::V5.06 update 6 (build 750)::ARMCC + 6160000::V6.16::ARMCLANG 1 @@ -185,6 +185,7 @@ 0 2 0 + 0 0 0 8 @@ -336,7 +337,7 @@ 0 - __FPU_PRESENT + QP_CONFIG ..\..;..\..\..\..\..\include;..\..\..\..\..\ports\arm-cm\qv\armclang;..\..\..\..\..\3rd_party\CMSIS\Include;..\..\..\..\..\3rd_party\ek-tm4c123gxl @@ -351,7 +352,7 @@ 0 1 0 - 0 + 4 Stack_Size=2048 Heap_Size=16 @@ -395,7 +396,7 @@ qstamp.c 1 - ..\..\..\..\..\include\qstamp.c + ..\..\..\..\..\src\qs\qstamp.c blinky0.c @@ -600,7 +601,7 @@ 2 2 2 - 2 + 0 @@ -814,6 +815,7 @@ 0 2 0 + 0 0 0 8 @@ -965,7 +967,7 @@ 0 - NDEBUG __FPU_PRESENT + NDEBUG,QP_CONFIG ..\..;..\..\..\..\..\include;..\..\..\..\..\ports\arm-cm\qv\armclang;..\..\..\..\..\3rd_party\CMSIS\Include;..\..\..\..\..\3rd_party\ek-tm4c123gxl @@ -980,7 +982,7 @@ 0 1 0 - 0 + 4 Stack_Size=2048 Heap_Size=16 @@ -1024,7 +1026,7 @@ qstamp.c 1 - ..\..\..\..\..\include\qstamp.c + ..\..\..\..\..\src\qs\qstamp.c blinky0.c @@ -1229,7 +1231,7 @@ 2 2 2 - 2 + 0 @@ -1443,6 +1445,7 @@ 0 2 0 + 0 0 0 8 @@ -1594,7 +1597,7 @@ 0 - Q_SPY __FPU_PRESENT + Q_SPY,QP_CONFIG ..\..;..\..\..\..\..\include;..\..\..\..\..\ports\arm-cm\qv\armclang;..\..\..\..\..\3rd_party\CMSIS\Include;..\..\..\..\..\3rd_party\ek-tm4c123gxl @@ -1609,7 +1612,7 @@ 0 1 0 - 0 + 4 Stack_Size=2048 Heap_Size=16 @@ -1653,7 +1656,7 @@ qstamp.c 1 - ..\..\..\..\..\include\qstamp.c + ..\..\..\..\..\src\qs\qstamp.c blinky0.c diff --git a/examples/arm-cm/low-power_ek-tm4c123gxl/qv/bsp.c b/examples/arm-cm/low-power_ek-tm4c123gxl/qv/bsp.c index 3b93f082..4576957c 100644 --- a/examples/arm-cm/low-power_ek-tm4c123gxl/qv/bsp.c +++ b/examples/arm-cm/low-power_ek-tm4c123gxl/qv/bsp.c @@ -1,45 +1,45 @@ -/***************************************************************************** -* Product: "Low-Power" example, EK-TM4C123GXL board, QV kernel -* Last updated for version 6.4.0 -* Last updated on 2019-02-25 -* -* Q u a n t u m L e a P s -* ------------------------ -* Modern Embedded Software -* -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* -* -*****************************************************************************/ +//============================================================================ +// Product: "Low-Power" example, EK-TM4C123GXL board, QV kernel +// Last updated for version 7.3.0 +// Last updated on 2023-07-23 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// This program is open source software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Alternatively, this program may be distributed and modified under the +// terms of Quantum Leaps commercial licenses, which expressly supersede +// the GNU General Public License and are specifically designed for +// licensees interested in retaining the proprietary status of their code. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Contact information: +// +// +//============================================================================ #include "qpc.h" #include "low_power.h" #include "bsp.h" -#include "TM4C123GH6PM.h" /* the device specific header (TI) */ -#include "rom.h" /* the built-in ROM functions (TI) */ -#include "sysctl.h" /* system control driver (TI) */ -#include "gpio.h" /* GPIO driver (TI) */ -/* add other drivers if necessary... */ +#include "TM4C123GH6PM.h" // the device specific header (TI) +#include "rom.h" // the built-in ROM functions (TI) +#include "sysctl.h" // system control driver (TI) +#include "gpio.h" // GPIO driver (TI) +// add other drivers if necessary... //Q_DEFINE_THIS_FILE @@ -47,22 +47,22 @@ #error The low-power example does not provide Spy build configuration #endif -/* ISRs defined in this BSP ------------------------------------------------*/ +// ISRs defined in this BSP ------------------------------------------------ void SysTick_Handler(void); void GPIOPortA_IRQHandler(void); -/* Local-scope objects -----------------------------------------------------*/ +// Local-scope objects ----------------------------------------------------- -/* bitmask of active sub-systems needed for low-power operation. -* NOTE: shared between the idle thread application, see NOTE1 -*/ +// bitmask of active sub-systems needed for low-power operation. +// NOTE: shared between the idle thread application, see NOTE1 +// static uint32_t volatile l_activeSet; -/* bits in the l_activeSet bitmask */ +// bits in the l_activeSet bitmask enum { SYSTICK_ACTIVE, TIMER0_ACTIVE, - /* ... */ + // ... }; #define LED_RED (1U << 1) @@ -72,155 +72,156 @@ enum { #define XTAL_HZ 16000000U -/* ISRs used in this project ===============================================*/ +// ISRs used in this project =============================================== void SysTick_Handler(void) { - QTIMEEVT_TICK_X(0U, (void *)0); /* process time events for rate 0 */ + QTIMEEVT_TICK_X(0U, (void *)0); // process time events for rate 0 } -/*..........................................................................*/ +//............................................................................ void Timer0A_IRQHandler(void) { - TIMER0->ICR |= (1U << 0); /* clear the Timer0 interrupt source */ - QTIMEEVT_TICK_X(1U, (void *)0); /* process time events for rate 1 */ + TIMER0->ICR |= (1U << 0); // clear the Timer0 interrupt source + QTIMEEVT_TICK_X(1U, (void *)0); // process time events for rate 1 QV_ARM_ERRATUM_838869(); } -/*..........................................................................*/ +//............................................................................ void GPIOPortF_IRQHandler(void) { - if ((GPIOF->RIS & BTN_SW1) != 0U) { /* interrupt caused by SW1? */ - static QEvt const pressedEvt = { BTN_PRESSED_SIG, 0U, 0U}; + if ((GPIOF->RIS & BTN_SW1) != 0U) { // interrupt caused by SW1? + static QEvt const pressedEvt = QEVT_INITIALIZER(BTN_PRESSED_SIG); QACTIVE_PUBLISH(&pressedEvt, (void *)0); } - GPIOF->ICR = 0xFFU; /* clear interrupt sources */ + GPIOF->ICR = 0xFFU; // clear interrupt sources QV_ARM_ERRATUM_838869(); } -/* BSP functions ===========================================================*/ +// BSP functions =========================================================== void BSP_init(void) { - /* Set the clocking to run directly from the crystal */ + // Set the clocking to run directly from the crystal ROM_SysCtlClockSet(SYSCTL_SYSDIV_1 | SYSCTL_USE_OSC | SYSCTL_OSC_MAIN | SYSCTL_XTAL_16MHZ); SystemCoreClock = XTAL_HZ; - /* NOTE The VFP (Floating Point Unit) unit is configured by QV-port */ + // NOTE The VFP (Floating Point Unit) unit is configured by QV-port - /* configure Timer0, but don't enable the interrupt just yet */ - SYSCTL->RCGCTIMER |= (1U << 0); /* enable Run mode for Timer0 */ - TIMER0->CTL &= ~(1U << 0); /* disable Timer0 before any changes */ + // configure Timer0, but don't enable the interrupt just yet + SYSCTL->RCGCTIMER |= (1U << 0); // enable Run mode for Timer0 + TIMER0->CTL &= ~(1U << 0); // disable Timer0 before any changes TIMER0->CFG = 0U; - TIMER0->TAMR |= (0x2 << 0); /* Timer0A */ + TIMER0->TAMR |= (0x2 << 0); // Timer0A TIMER0->TAMR &= ~(1U << 4); TIMER0->TAILR = XTAL_HZ / BSP_TICKS1_PER_SEC; - TIMER0->IMR &= ~(1U << 0); /* disable timer interrupt for now */ - SYSCTL->RCGCTIMER &= ~(1U << 0); /* disable Run mode for Timer0 */ + TIMER0->IMR &= ~(1U << 0); // disable timer interrupt for now + SYSCTL->RCGCTIMER &= ~(1U << 0); // disable Run mode for Timer0 - /* configure the LEDs and push buttons */ - SYSCTL->RCGCGPIO |= (1U << 5); /* enable Run mode for GPIOF */ - GPIOF->DIR |= (LED_RED | LED_GREEN | LED_BLUE);/* set direction: output */ - GPIOF->DEN |= (LED_RED | LED_GREEN | LED_BLUE); /* digital enable */ - GPIOF->DATA_Bits[LED_RED | LED_GREEN | LED_BLUE] = 0U; /* turn off */ + // configure the LEDs and push buttons + SYSCTL->RCGCGPIO |= (1U << 5); // enable Run mode for GPIOF + GPIOF->DIR |= (LED_RED | LED_GREEN | LED_BLUE);// set direction: output + GPIOF->DEN |= (LED_RED | LED_GREEN | LED_BLUE); // digital enable + GPIOF->DATA_Bits[LED_RED | LED_GREEN | LED_BLUE] = 0U; // turn off - /* configure the button SW1 */ - GPIOF->DIR &= ~BTN_SW1; /* input */ - GPIOF->DEN |= BTN_SW1; /* digital enable */ - GPIOF->PUR |= BTN_SW1; /* pull-up resistor enable */ + // configure the button SW1 + GPIOF->DIR &= ~BTN_SW1; // input + GPIOF->DEN |= BTN_SW1; // digital enable + GPIOF->PUR |= BTN_SW1; // pull-up resistor enable - /* configure the GPIO interrupt for SW1 */ - GPIOF->IS &= ~BTN_SW1; /* edge detect for SW1 */ - GPIOF->IBE &= ~BTN_SW1; /* only one edge generate the interrupt */ - GPIOF->IEV &= ~BTN_SW1; /* a falling edge triggers the interrupt */ - GPIOF->IM |= BTN_SW1; /* enable GPIOF interrupt for SW1 */ + // configure the GPIO interrupt for SW1 + GPIOF->IS &= ~BTN_SW1; // edge detect for SW1 + GPIOF->IBE &= ~BTN_SW1; // only one edge generate the interrupt + GPIOF->IEV &= ~BTN_SW1; // a falling edge triggers the interrupt + GPIOF->IM |= BTN_SW1; // enable GPIOF interrupt for SW1 } -/*..........................................................................*/ +//............................................................................ void BSP_led0_off(void) { GPIOF->DATA_Bits[LED_GREEN] = 0U; } -/*..........................................................................*/ +//............................................................................ void BSP_led0_on(void) { GPIOF->DATA_Bits[LED_GREEN] = 0xFFU; } -/*..........................................................................*/ +//............................................................................ void BSP_led1_off(void) { GPIOF->DATA_Bits[LED_BLUE] = 0U; } -/*..........................................................................*/ +//............................................................................ void BSP_led1_on(void) { GPIOF->DATA_Bits[LED_BLUE] = 0xFFU; } -/*..........................................................................*/ +//............................................................................ void BSP_tickRate0_on(void) { - /* enable SysTick IRQ and Timer */ + // enable SysTick IRQ and Timer SysTick->CTRL |= (SysTick_CTRL_TICKINT_Msk | SysTick_CTRL_ENABLE_Msk); l_activeSet |= (1U << SYSTICK_ACTIVE); } -/*..........................................................................*/ +//............................................................................ void BSP_tickRate1_on(void) { - SYSCTL->RCGCTIMER |= (1U << 0); /* enable Run mode for Timer0 */ - TIMER0->CTL &= ~(1U << 0); /* disable Timer0 before any changes */ - TIMER0->IMR |= (1U << 0); /* enable timer interrupt */ - TIMER0->CTL |= (1U << 0); /* enable Timer0 after the changes */ + SYSCTL->RCGCTIMER |= (1U << 0); // enable Run mode for Timer0 + TIMER0->CTL &= ~(1U << 0); // disable Timer0 before any changes + TIMER0->IMR |= (1U << 0); // enable timer interrupt + TIMER0->CTL |= (1U << 0); // enable Timer0 after the changes l_activeSet |= (1U << TIMER0_ACTIVE); } -/* QF callbacks ============================================================*/ +// QF callbacks ============================================================ void QF_onStartup(void) { - /* set up the SysTick timer to fire at BSP_TICKS0_PER_SEC rate */ + // set up the SysTick timer to fire at BSP_TICKS0_PER_SEC rate SysTick_Config(SystemCoreClock / BSP_TICKS0_PER_SEC); - /* assign all priority bits for preemption-prio. and none to sub-prio. */ + // assign all priority bits for preemption-prio. and none to sub-prio. NVIC_SetPriorityGrouping(0U); - /* set priorities of ALL ISRs used in the system, see NOTE00 - * - * !!!!!!!!!!!!!!!!!!!!!!!!!!!! CAUTION !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - * Assign a priority to EVERY ISR explicitly by calling NVIC_SetPriority(). - * DO NOT LEAVE THE ISR PRIORITIES AT THE DEFAULT VALUE! - */ + // set priorities of ALL ISRs used in the system, see NOTE00 + // + // !!!!!!!!!!!!!!!!!!!!!!!!!!!! CAUTION !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + // Assign a priority to EVERY ISR explicitly by calling NVIC_SetPriority(). + // DO NOT LEAVE THE ISR PRIORITIES AT THE DEFAULT VALUE! + // NVIC_SetPriority(TIMER0A_IRQn, QF_AWARE_ISR_CMSIS_PRI); NVIC_SetPriority(SysTick_IRQn, QF_AWARE_ISR_CMSIS_PRI + 1U); NVIC_SetPriority(GPIOF_IRQn, QF_AWARE_ISR_CMSIS_PRI + 1U); - /* ... */ + // ... - /* enable IRQs in the NVIC... */ + // enable IRQs in the NVIC... NVIC_EnableIRQ(GPIOF_IRQn); NVIC_EnableIRQ(TIMER0A_IRQn); // enable interrupts in hardware GPIOF->IM |= BTN_SW1; // enable GPIOF interrupt for SW1 } -/*..........................................................................*/ +//............................................................................ void QF_onCleanup(void) { } -/*..........................................................................*/ -void QV_onIdle(void) { /* NOTE: called with interrupts DISABLED */ +//............................................................................ +void QV_onIdle(void) { // NOTE: called with interrupts DISABLED - if (((l_activeSet & (1U << SYSTICK_ACTIVE)) != 0U) /* rate-0 enabled? */ - && QF_noTimeEvtsActiveX(0U)) /* no time events at rate-0? */ + if (((l_activeSet & (1U << SYSTICK_ACTIVE)) != 0U) // rate-0 enabled? + && QTimeEvt_noActive(0U)) // no time events at rate-0? { - /* safe to disable SysTick and interrupt */ + // safe to disable SysTick and interrupt SysTick->CTRL &= ~(SysTick_CTRL_TICKINT_Msk | SysTick_CTRL_ENABLE_Msk); - l_activeSet &= ~(1U << SYSTICK_ACTIVE); /* mark rate-0 as disabled */ + l_activeSet &= ~(1U << SYSTICK_ACTIVE); // mark rate-0 as disabled } - if (((l_activeSet & (1U << TIMER0_ACTIVE)) != 0U) /* rate-1 enabled? */ - && QF_noTimeEvtsActiveX(1U)) /* no time events at rate-1? */ + if (((l_activeSet & (1U << TIMER0_ACTIVE)) != 0U) // rate-1 enabled? + && QTimeEvt_noActive(1U)) // no time events at rate-1? { - /* safe to disable Timer0 and interrupt */ - TIMER0->CTL &= ~(1U << 0); /* disable Timer0 */ - TIMER0->IMR &= ~(1U << 0); /* disable timer interrupt */ - l_activeSet &= ~(1U << TIMER0_ACTIVE); /* mark rate-1 as disabled */ + // safe to disable Timer0 and interrupt + TIMER0->CTL &= ~(1U << 0); // disable Timer0 + TIMER0->IMR &= ~(1U << 0); // disable timer interrupt + l_activeSet &= ~(1U << TIMER0_ACTIVE); // mark rate-1 as disabled } - GPIOF->DATA_Bits[LED_RED] = 0xFFU; /* turn LED on, see NOTE2 */ - QV_CPU_SLEEP(); /* atomically go to sleep and enable interrupts */ - GPIOF->DATA_Bits[LED_RED] = 0x00U; /* turn LED off, see NOTE2 */ + GPIOF->DATA_Bits[LED_RED] = 0xFFU; // turn LED on, see NOTE2 + QV_CPU_SLEEP(); // atomically go to sleep and enable interrupts + GPIOF->DATA_Bits[LED_RED] = 0x00U; // turn LED off, see NOTE2 } -/*..........................................................................*/ -Q_NORETURN Q_onAssert(char const * const module, int_t const loc) { - /* - * NOTE: add here your application-specific error handling - */ - (void)module; - (void)loc; +//............................................................................ +Q_NORETURN Q_onError(char const * const module, int_t const id) { + // + // NOTE: add here your application-specific error handling + // + Q_UNUSED_PAR(module); + Q_UNUSED_PAR(id); + #ifndef NDEBUG - /* for debugging, hang on in an endless loop toggling the RED LED... */ + // for debugging, hang on in an endless loop toggling the RED LED... while (GPIOF->DATA_Bits[BTN_SW1] != 0) { GPIOF->DATA = LED_RED; GPIOF->DATA = 0U; @@ -228,15 +229,20 @@ Q_NORETURN Q_onAssert(char const * const module, int_t const loc) { #endif NVIC_SystemReset(); } +//............................................................................ +void assert_failed(char const * const module, int_t const id); // prototype +void assert_failed(char const * const module, int_t const id) { + Q_onError(module, id); +} -/***************************************************************************** -* NOTE1: -* The bitmask l_activeSet is **shared** between the QK idle thread and -* the application-level threads. Therefore this variable needs to be -* always accessed in a critical section. -* -* NOTE2: -* One of the LEDs is used to visualize the CPU sleep mode. The LED is turned -* on before entering the sleep mode and turned off after waking up, so that -* the LED stays ON when the CPU sleeps. -*/ +//============================================================================ +// NOTE1: +// The bitmask l_activeSet is **shared** between the QK idle thread and +// the application-level threads. Therefore this variable needs to be +// always accessed in a critical section. +// +// NOTE2: +// One of the LEDs is used to visualize the CPU sleep mode. The LED is turned +// on before entering the sleep mode and turned off after waking up, so that +// the LED stays ON when the CPU sleeps. +// diff --git a/examples/arm-cm/low-power_ek-tm4c123gxl/qv/gnu/Makefile b/examples/arm-cm/low-power_ek-tm4c123gxl/qv/gnu/Makefile index 662889af..9fb23194 100644 --- a/examples/arm-cm/low-power_ek-tm4c123gxl/qv/gnu/Makefile +++ b/examples/arm-cm/low-power_ek-tm4c123gxl/qv/gnu/Makefile @@ -133,7 +133,7 @@ LIB_DIRS := LIBS := # defines -DEFINES := -DTARGET_IS_TM4C123_RB1 +DEFINES := -DQP_CONFIG # ARM CPU, ARCH, FPU, and Float-ABI types... # ARM_CPU: [cortex-m0 | cortex-m0plus | cortex-m1 | cortex-m3 | cortex-m4] @@ -267,7 +267,7 @@ $(TARGET_BIN): $(TARGET_ELF) $(BIN) -O binary $< $@ $(TARGET_ELF) : $(ASM_OBJS_EXT) $(C_OBJS_EXT) $(CPP_OBJS_EXT) - $(CC) $(CFLAGS) $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o + $(CC) $(CFLAGS) $(QPC)/src/qs/qstamp.c -o $(BIN_DIR)/qstamp.o $(LINK) $(LINKFLAGS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) $(BIN_DIR)/%.d : %.c diff --git a/examples/arm-cm/low-power_ek-tm4c123gxl/qv/iar/low-power-qv.ewd b/examples/arm-cm/low-power_ek-tm4c123gxl/qv/iar/low-power-qv.ewd index 71e2f66a..7f745b03 100644 --- a/examples/arm-cm/low-power_ek-tm4c123gxl/qv/iar/low-power-qv.ewd +++ b/examples/arm-cm/low-power_ek-tm4c123gxl/qv/iar/low-power-qv.ewd @@ -11,7 +11,7 @@ C-SPY 2 - 28 + 32 1 1 - - + + + + + @@ -486,7 +498,7 @@ IJET_ID 2 - 8 + 9 1 1 + + + + + + + + + + + + + @@ -916,7 +980,7 @@ LMIFTDI_ID 2 - 2 + 3 1 1 + + + + + + + NULINK_ID + 2 + + 0 + 1 + 1 + + + @@ -974,7 +1072,7 @@ STLINK_ID 2 - 4 + 8 1 1 + + + + @@ -1185,7 +1300,7 @@ XDS100_ID 2 - 6 + 9 1 1 + + + + @@ -1362,6 +1493,18 @@ $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin 0 + + $TOOLKIT_DIR$\plugins\rtos\FreeRtos\FreeRtosArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin2.ENU.ewplugin + 0 + $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin 0 @@ -1371,11 +1514,15 @@ 0 - $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9.ewplugin 0 - $TOOLKIT_DIR$\plugins\rtos\TI-RTOS\tirtosplugin.ewplugin + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9BE.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin 0 @@ -1391,11 +1538,11 @@ 0 - $EW_DIR$\common\plugins\CodeCoverage\CodeCoverage.ENU.ewplugin - 1 + $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + 0 - $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + $EW_DIR$\common\plugins\TargetAccessServer\TargetAccessServer.ENU.ewplugin 0 @@ -1414,7 +1561,7 @@ C-SPY 2 - 28 + 32 1 0 - - + + + + + @@ -1889,7 +2048,7 @@ IJET_ID 2 - 8 + 9 1 0 + + + + + + + + + + + + + @@ -2319,7 +2530,7 @@ LMIFTDI_ID 2 - 2 + 3 1 0 + + + + + + + NULINK_ID + 2 + + 0 + 1 + 0 + + + @@ -2377,7 +2622,7 @@ STLINK_ID 2 - 4 + 8 1 0 + + + + @@ -2588,7 +2850,7 @@ XDS100_ID 2 - 6 + 9 1 0 + + + + @@ -2765,6 +3043,18 @@ $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin 0 + + $TOOLKIT_DIR$\plugins\rtos\FreeRtos\FreeRtosArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin2.ENU.ewplugin + 0 + $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin 0 @@ -2774,11 +3064,15 @@ 0 - $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9.ewplugin 0 - $TOOLKIT_DIR$\plugins\rtos\TI-RTOS\tirtosplugin.ewplugin + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9BE.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin 0 @@ -2794,11 +3088,11 @@ 0 - $EW_DIR$\common\plugins\CodeCoverage\CodeCoverage.ENU.ewplugin - 1 + $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + 0 - $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + $EW_DIR$\common\plugins\TargetAccessServer\TargetAccessServer.ENU.ewplugin 0 @@ -2817,7 +3111,7 @@ C-SPY 2 - 28 + 32 1 1 - - + + + + + @@ -3292,7 +3598,7 @@ IJET_ID 2 - 8 + 9 1 1 + + + + + + + + + + + + + @@ -3722,7 +4080,7 @@ LMIFTDI_ID 2 - 2 + 3 1 1 + + + + + + + NULINK_ID + 2 + + 0 + 1 + 1 + + + @@ -3780,7 +4172,7 @@ STLINK_ID 2 - 4 + 8 1 1 + + + + @@ -3991,7 +4400,7 @@ XDS100_ID 2 - 6 + 9 1 1 + + + + @@ -4168,6 +4593,18 @@ $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin 0 + + $TOOLKIT_DIR$\plugins\rtos\FreeRtos\FreeRtosArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin2.ENU.ewplugin + 0 + $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin 0 @@ -4177,11 +4614,15 @@ 0 - $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9.ewplugin 0 - $TOOLKIT_DIR$\plugins\rtos\TI-RTOS\tirtosplugin.ewplugin + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9BE.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin 0 @@ -4197,11 +4638,11 @@ 0 - $EW_DIR$\common\plugins\CodeCoverage\CodeCoverage.ENU.ewplugin - 1 + $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + 0 - $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + $EW_DIR$\common\plugins\TargetAccessServer\TargetAccessServer.ENU.ewplugin 0 diff --git a/examples/arm-cm/low-power_ek-tm4c123gxl/qv/iar/low-power-qv.ewp b/examples/arm-cm/low-power_ek-tm4c123gxl/qv/iar/low-power-qv.ewp index f745f1c2..5708c7fc 100644 --- a/examples/arm-cm/low-power_ek-tm4c123gxl/qv/iar/low-power-qv.ewp +++ b/examples/arm-cm/low-power_ek-tm4c123gxl/qv/iar/low-power-qv.ewp @@ -11,9 +11,13 @@ General 3 - 31 + 35 1 1 + - - - - - + + + + + ICCARM 2 - 35 + 37 1 1 - - - + AARM 2 - 10 + 11 1 1 + @@ -673,13 +669,9 @@ 0 + inputOutputBased - - BICOMP - 0 - - BUILDACTION 1 @@ -692,17 +684,13 @@ ILINK 0 - 22 + 27 1 1 - + + + + + + + + + + + + + @@ -1035,11 +1075,6 @@ - - BILINK - 0 - - Coder 0 @@ -1056,9 +1091,13 @@ General 3 - 31 + 35 1 0 + - - - - - + + + + + ICCARM 2 - 35 + 37 1 0 - - - + AARM 2 - 10 + 11 1 0 + @@ -1718,13 +1750,9 @@ 0 + inputOutputBased - - BICOMP - 0 - - BUILDACTION 1 @@ -1737,17 +1765,13 @@ ILINK 0 - 22 + 27 1 0 - + + + + + + + + + + + + + @@ -2080,11 +2156,6 @@ - - BILINK - 0 - - Coder 0 @@ -2101,9 +2172,13 @@ General 3 - 31 + 35 1 1 + - - - - - + + + + + ICCARM 2 - 35 + 37 1 1 - - - + AARM 2 - 10 + 11 1 1 + @@ -2763,13 +2831,9 @@ 0 + inputOutputBased - - BICOMP - 0 - - BUILDACTION 1 @@ -2782,17 +2846,13 @@ ILINK 0 - 22 + 27 1 1 - + + + + + + + + + + + + + @@ -3125,11 +3237,6 @@ - - BILINK - 0 - - Coder 0 @@ -3213,30 +3320,15 @@ $PROJ_DIR$\..\..\..\..\..\src\qf\qf_time.c - - $PROJ_DIR$\..\..\..\..\..\include\qstamp.c - $PROJ_DIR$\..\..\..\..\..\src\qv\qv.c QP_port - - $PROJ_DIR$\..\..\..\..\..\ports\arm-cm\qv\iar\qep_port.h - - - $PROJ_DIR$\..\..\..\..\..\ports\arm-cm\qv\iar\qf_port.h - - - $PROJ_DIR$\..\..\..\..\..\ports\arm-cm\qv\iar\qs_port.h - $PROJ_DIR$\..\..\..\..\..\ports\arm-cm\qv\iar\qv_port.c - - $PROJ_DIR$\..\..\..\..\..\ports\arm-cm\qv\iar\qv_port.h - QS @@ -3251,10 +3343,10 @@ $PROJ_DIR$\..\..\..\..\..\src\qs\qs_fp.c - $PROJ_DIR$\..\..\..\..\..\src\qs_pkg.h + $PROJ_DIR$\..\..\..\..\..\src\qs\qs_rx.c - $PROJ_DIR$\..\..\..\..\..\src\qs\qs_rx.c + $PROJ_DIR$\..\..\..\..\..\src\qs\qstamp.c diff --git a/examples/arm-cm/low-power_ek-tm4c123gxl/qxk/armclang/low-power-qxk.uvoptx b/examples/arm-cm/low-power_ek-tm4c123gxl/qxk/armclang/low-power-qxk.uvoptx index 4c82e83e..dbc7a9e9 100644 --- a/examples/arm-cm/low-power_ek-tm4c123gxl/qxk/armclang/low-power-qxk.uvoptx +++ b/examples/arm-cm/low-power_ek-tm4c123gxl/qxk/armclang/low-power-qxk.uvoptx @@ -10,7 +10,7 @@ *.s*; *.src; *.a* *.obj; *.o *.lib - *.txt; *.h; *.inc + *.txt; *.h; *.inc; *.md *.plm *.cpp 0 @@ -103,7 +103,7 @@ 1 0 0 - 8 + 19 @@ -300,7 +300,7 @@ 1 0 0 - 8 + 19 @@ -490,7 +490,7 @@ 1 0 0 - 8 + 19 @@ -629,7 +629,7 @@ 0 0 0 - ..\..\..\..\..\include\qstamp.c + ..\..\..\..\..\src\qs\qstamp.c qstamp.c 0 0 diff --git a/examples/arm-cm/low-power_ek-tm4c123gxl/qxk/armclang/low-power-qxk.uvprojx b/examples/arm-cm/low-power_ek-tm4c123gxl/qxk/armclang/low-power-qxk.uvprojx index d6be2dce..929a916c 100644 --- a/examples/arm-cm/low-power_ek-tm4c123gxl/qxk/armclang/low-power-qxk.uvprojx +++ b/examples/arm-cm/low-power_ek-tm4c123gxl/qxk/armclang/low-power-qxk.uvprojx @@ -10,7 +10,7 @@ low-power-dbg 0x4 ARM-ADS - 6130001::V6.13.1::.\ARMCLANG + 6160000::V6.16::ARMCLANG 1 @@ -185,6 +185,7 @@ 0 2 0 + 0 0 0 8 @@ -336,7 +337,7 @@ 0 - __FPU_PRESENT + QP_CONFIG ..\..;..\..\..\..\..\include;..\..\..\..\..\ports\arm-cm\qxk\armclang;..\..\..\..\..\3rd_party\CMSIS\Include;..\..\..\..\..\3rd_party\ek-tm4c123gxl @@ -351,7 +352,7 @@ 0 1 0 - 0 + 4 Stack_Size=2048 Heap_Size=16 @@ -395,7 +396,7 @@ qstamp.c 1 - ..\..\..\..\..\include\qstamp.c + ..\..\..\..\..\src\qs\qstamp.c xblinky1.c @@ -615,7 +616,7 @@ 2 2 2 - 2 + 0 @@ -654,7 +655,7 @@ low-power-rel 0x4 ARM-ADS - 5060020::V5.06 (build 20)::ARMCC + 6160000::V6.16::ARMCLANG 1 @@ -829,6 +830,7 @@ 0 2 0 + 0 0 0 8 @@ -980,7 +982,7 @@ 0 - NDEBUG __FPU_PRESENT + NDEBUG,QP_CONFIG ..\..;..\..\..\..\..\include;..\..\..\..\..\ports\arm-cm\qxk\armclang;..\..\..\..\..\3rd_party\CMSIS\Include;..\..\..\..\..\3rd_party\ek-tm4c123gxl @@ -995,7 +997,7 @@ 0 1 0 - 0 + 4 Stack_Size=2048 Heap_Size=16 @@ -1039,7 +1041,7 @@ qstamp.c 1 - ..\..\..\..\..\include\qstamp.c + ..\..\..\..\..\src\qs\qstamp.c xblinky1.c @@ -1259,7 +1261,7 @@ 2 2 2 - 2 + 0 @@ -1473,6 +1475,7 @@ 0 2 0 + 0 0 0 8 @@ -1624,7 +1627,7 @@ 0 - Q_SPY __FPU_PRESENT + Q_SPY,QP_CONFIG ..\..;..\..\..\..\..\include;..\..\..\..\..\ports\arm-cm\qxk\armclang;..\..\..\..\..\3rd_party\CMSIS\Include;..\..\..\..\..\3rd_party\ek-tm4c123gxl @@ -1639,7 +1642,7 @@ 0 1 0 - 0 + 4 Stack_Size=2048 Heap_Size=16 @@ -1683,7 +1686,7 @@ qstamp.c 1 - ..\..\..\..\..\include\qstamp.c + ..\..\..\..\..\src\qs\qstamp.c xblinky1.c diff --git a/examples/arm-cm/low-power_ek-tm4c123gxl/qxk/bsp.c b/examples/arm-cm/low-power_ek-tm4c123gxl/qxk/bsp.c index d26e233c..e5a21513 100644 --- a/examples/arm-cm/low-power_ek-tm4c123gxl/qxk/bsp.c +++ b/examples/arm-cm/low-power_ek-tm4c123gxl/qxk/bsp.c @@ -1,45 +1,45 @@ -/***************************************************************************** -* Product: "Low-Power" example, EK-TM4C123GXL board, QXK kernel -* Last updated for version 6.4.0 -* Last updated on 2019-02-25 -* -* Q u a n t u m L e a P s -* ------------------------ -* Modern Embedded Software -* -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* -* -*****************************************************************************/ +//============================================================================ +// Product: "Low-Power" example, EK-TM4C123GXL board, QXK kernel +// Last updated for version 7.3.0 +// Last updated on 2023-07-23 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// This program is open source software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Alternatively, this program may be distributed and modified under the +// terms of Quantum Leaps commercial licenses, which expressly supersede +// the GNU General Public License and are specifically designed for +// licensees interested in retaining the proprietary status of their code. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Contact information: +// +// +//============================================================================ #include "qpc.h" #include "low_power.h" #include "bsp.h" -#include "TM4C123GH6PM.h" /* the device specific header (TI) */ -#include "rom.h" /* the built-in ROM functions (TI) */ -#include "sysctl.h" /* system control driver (TI) */ -#include "gpio.h" /* GPIO driver (TI) */ -/* add other drivers if necessary... */ +#include "TM4C123GH6PM.h" // the device specific header (TI) +#include "rom.h" // the built-in ROM functions (TI) +#include "sysctl.h" // system control driver (TI) +#include "gpio.h" // GPIO driver (TI) +// add other drivers if necessary... //Q_DEFINE_THIS_FILE @@ -47,22 +47,22 @@ #error The low-power example does not provide Spy build configuration #endif -/* ISRs defined in this BSP ------------------------------------------------*/ +// ISRs defined in this BSP ------------------------------------------------ void SysTick_Handler(void); void GPIOPortA_IRQHandler(void); -/* Local-scope objects -----------------------------------------------------*/ +// Local-scope objects ----------------------------------------------------- -/* bitmask of active sub-systems needed for low-power operation. -* NOTE: shared between the idle thread application, see NOTE1 -*/ +// bitmask of active sub-systems needed for low-power operation. +// NOTE: shared between the idle thread application, see NOTE1 +// static uint32_t volatile l_activeSet; -/* bits in the l_activeSet bitmask */ +// bits in the l_activeSet bitmask enum { SYSTICK_ACTIVE, TIMER0_ACTIVE, - /* ... */ + // ... }; #define LED_RED (1U << 1) @@ -72,159 +72,160 @@ enum { #define XTAL_HZ 16000000U -/* ISRs used in this project ===============================================*/ +// ISRs used in this project =============================================== void SysTick_Handler(void) { - QXK_ISR_ENTRY(); /* inform QXK about entering an ISR */ - QTIMEEVT_TICK_X(0U, (void *)0); /* process time events for rate 0 */ - QXK_ISR_EXIT(); /* inform QXK about exiting an ISR */ + QXK_ISR_ENTRY(); // inform QXK about entering an ISR + QTIMEEVT_TICK_X(0U, (void *)0); // process time events for rate 0 + QXK_ISR_EXIT(); // inform QXK about exiting an ISR } -/*..........................................................................*/ +//............................................................................ void Timer0A_IRQHandler(void) { - QXK_ISR_ENTRY(); /* inform QXK about entering an ISR */ - TIMER0->ICR |= (1U << 0); /* clear the Timer0 interrupt source */ - QTIMEEVT_TICK_X(1U, (void *)0); /* process time events for rate 1 */ - QXK_ISR_EXIT(); /* inform QXK about exiting an ISR */ + QXK_ISR_ENTRY(); // inform QXK about entering an ISR + TIMER0->ICR |= (1U << 0); // clear the Timer0 interrupt source + QTIMEEVT_TICK_X(1U, (void *)0); // process time events for rate 1 + QXK_ISR_EXIT(); // inform QXK about exiting an ISR } -/*..........................................................................*/ +//............................................................................ void GPIOPortF_IRQHandler(void) { - QXK_ISR_ENTRY(); /* inform QXK about entering an ISR */ - if ((GPIOF->RIS & BTN_SW1) != 0U) { /* interrupt caused by SW1? */ - static QEvt const pressedEvt = { BTN_PRESSED_SIG, 0U, 0U}; + QXK_ISR_ENTRY(); // inform QXK about entering an ISR + if ((GPIOF->RIS & BTN_SW1) != 0U) { // interrupt caused by SW1? + static QEvt const pressedEvt = QEVT_INITIALIZER(BTN_PRESSED_SIG); QACTIVE_PUBLISH(&pressedEvt, (void *)0); QXSemaphore_signal(&XSEM_sw1); } - GPIOF->ICR = 0xFFU; /* clear interrupt sources */ - QXK_ISR_EXIT(); /* inform QXK about exiting an ISR */ + GPIOF->ICR = 0xFFU; // clear interrupt sources + QXK_ISR_EXIT(); // inform QXK about exiting an ISR } -/* BSP functions ===========================================================*/ +// BSP functions =========================================================== void BSP_init(void) { - /* Set the clocking to run directly from the crystal */ + // Set the clocking to run directly from the crystal ROM_SysCtlClockSet(SYSCTL_SYSDIV_1 | SYSCTL_USE_OSC | SYSCTL_OSC_MAIN | SYSCTL_XTAL_16MHZ); SystemCoreClock = XTAL_HZ; - /* NOTE The VFP (Floating Point Unit) unit is configured by QXK-port */ + // NOTE The VFP (Floating Point Unit) unit is configured by QXK-port - /* configure Timer0, but don't enable the interrupt just yet */ - SYSCTL->RCGCTIMER |= (1U << 0); /* enable Run mode for Timer0 */ - TIMER0->CTL &= ~(1U << 0); /* disable Timer0 before any changes */ + // configure Timer0, but don't enable the interrupt just yet + SYSCTL->RCGCTIMER |= (1U << 0); // enable Run mode for Timer0 + TIMER0->CTL &= ~(1U << 0); // disable Timer0 before any changes TIMER0->CFG = 0U; - TIMER0->TAMR |= (0x2 << 0); /* Timer0A */ + TIMER0->TAMR |= (0x2 << 0); // Timer0A TIMER0->TAMR &= ~(1U << 4); TIMER0->TAILR = XTAL_HZ / BSP_TICKS1_PER_SEC; - TIMER0->IMR &= ~(1U << 0); /* disable timer interrupt for now */ - SYSCTL->RCGCTIMER &= ~(1U << 0); /* disable Run mode for Timer0 */ + TIMER0->IMR &= ~(1U << 0); // disable timer interrupt for now + SYSCTL->RCGCTIMER &= ~(1U << 0); // disable Run mode for Timer0 - /* configure the LEDs and push buttons */ - SYSCTL->RCGCGPIO |= (1U << 5); /* enable Run mode for GPIOF */ - GPIOF->DIR |= (LED_RED | LED_GREEN | LED_BLUE); /* direction: output */ - GPIOF->DEN |= (LED_RED | LED_GREEN | LED_BLUE); /* digital enable */ - GPIOF->DATA_Bits[LED_RED | LED_GREEN | LED_BLUE] = 0U; /* turn off */ + // configure the LEDs and push buttons + SYSCTL->RCGCGPIO |= (1U << 5); // enable Run mode for GPIOF + GPIOF->DIR |= (LED_RED | LED_GREEN | LED_BLUE); // direction: output + GPIOF->DEN |= (LED_RED | LED_GREEN | LED_BLUE); // digital enable + GPIOF->DATA_Bits[LED_RED | LED_GREEN | LED_BLUE] = 0U; // turn off - /* configure the button SW1 */ - GPIOF->DIR &= ~BTN_SW1; /* input */ - GPIOF->DEN |= BTN_SW1; /* digital enable */ - GPIOF->PUR |= BTN_SW1; /* pull-up resistor enable */ + // configure the button SW1 + GPIOF->DIR &= ~BTN_SW1; // input + GPIOF->DEN |= BTN_SW1; // digital enable + GPIOF->PUR |= BTN_SW1; // pull-up resistor enable - /* configure the GPIO interrupt for SW1 */ - GPIOF->IS &= ~BTN_SW1; /* edge detect for SW1 */ - GPIOF->IBE &= ~BTN_SW1; /* only one edge generate the interrupt */ - GPIOF->IEV &= ~BTN_SW1; /* a falling edge triggers the interrupt */ - GPIOF->IM |= BTN_SW1; /* enable GPIOF interrupt for SW1 */ + // configure the GPIO interrupt for SW1 + GPIOF->IS &= ~BTN_SW1; // edge detect for SW1 + GPIOF->IBE &= ~BTN_SW1; // only one edge generate the interrupt + GPIOF->IEV &= ~BTN_SW1; // a falling edge triggers the interrupt + GPIOF->IM |= BTN_SW1; // enable GPIOF interrupt for SW1 } -/*..........................................................................*/ +//............................................................................ void BSP_led0_off(void) { GPIOF->DATA_Bits[LED_GREEN] = 0U; } -/*..........................................................................*/ +//............................................................................ void BSP_led0_on(void) { GPIOF->DATA_Bits[LED_GREEN] = 0xFFU; } -/*..........................................................................*/ +//............................................................................ void BSP_led1_off(void) { GPIOF->DATA_Bits[LED_BLUE] = 0U; } -/*..........................................................................*/ +//............................................................................ void BSP_led1_on(void) { GPIOF->DATA_Bits[LED_BLUE] = 0xFFU; } -/*..........................................................................*/ +//............................................................................ void BSP_tickRate0_on(void) { - /* enable SysTick IRQ and Timer */ + // enable SysTick IRQ and Timer SysTick->CTRL |= (SysTick_CTRL_TICKINT_Msk | SysTick_CTRL_ENABLE_Msk); l_activeSet |= (1U << SYSTICK_ACTIVE); } -/*..........................................................................*/ +//............................................................................ void BSP_tickRate1_on(void) { - SYSCTL->RCGCTIMER |= (1U << 0); /* enable Run mode for Timer0 */ - TIMER0->CTL &= ~(1U << 0); /* disable Timer0 before any changes */ - TIMER0->IMR |= (1U << 0); /* enable timer interrupt */ - TIMER0->CTL |= (1U << 0); /* enable Timer0 after the changes */ + SYSCTL->RCGCTIMER |= (1U << 0); // enable Run mode for Timer0 + TIMER0->CTL &= ~(1U << 0); // disable Timer0 before any changes + TIMER0->IMR |= (1U << 0); // enable timer interrupt + TIMER0->CTL |= (1U << 0); // enable Timer0 after the changes l_activeSet |= (1U << TIMER0_ACTIVE); } -/* QF callbacks ============================================================*/ +// QF callbacks ============================================================ void QF_onStartup(void) { - /* set up the SysTick timer to fire at BSP_TICKS0_PER_SEC rate */ + // set up the SysTick timer to fire at BSP_TICKS0_PER_SEC rate SysTick_Config(SystemCoreClock / BSP_TICKS0_PER_SEC); - /* assign all priority bits for preemption-prio. and none to sub-prio. */ + // assign all priority bits for preemption-prio. and none to sub-prio. NVIC_SetPriorityGrouping(0U); - /* set priorities of ALL ISRs used in the system, see NOTE00 - * - * !!!!!!!!!!!!!!!!!!!!!!!!!!!! CAUTION !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - * Assign a priority to EVERY ISR explicitly by calling NVIC_SetPriority(). - * DO NOT LEAVE THE ISR PRIORITIES AT THE DEFAULT VALUE! - */ + // set priorities of ALL ISRs used in the system, see NOTE00 + // + // !!!!!!!!!!!!!!!!!!!!!!!!!!!! CAUTION !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + // Assign a priority to EVERY ISR explicitly by calling NVIC_SetPriority(). + // DO NOT LEAVE THE ISR PRIORITIES AT THE DEFAULT VALUE! + // NVIC_SetPriority(TIMER0A_IRQn, QF_AWARE_ISR_CMSIS_PRI); NVIC_SetPriority(SysTick_IRQn, QF_AWARE_ISR_CMSIS_PRI + 1U); NVIC_SetPriority(GPIOF_IRQn, QF_AWARE_ISR_CMSIS_PRI + 1U); - /* ... */ + // ... - /* enable IRQs in the NVIC... */ + // enable IRQs in the NVIC... NVIC_EnableIRQ(GPIOF_IRQn); NVIC_EnableIRQ(TIMER0A_IRQn); } -/*..........................................................................*/ +//............................................................................ void QF_onCleanup(void) { } -/*..........................................................................*/ +//............................................................................ void QXK_onIdle(void) { QF_INT_DISABLE(); - if (((l_activeSet & (1U << SYSTICK_ACTIVE)) != 0U) /* rate-0 enabled? */ - && QF_noTimeEvtsActiveX(0U)) /* no time events at rate-0? */ + if (((l_activeSet & (1U << SYSTICK_ACTIVE)) != 0U) // rate-0 enabled? + && QTimeEvt_noActive(0U)) // no time events at rate-0? { - /* safe to disable SysTick and interrupt */ + // safe to disable SysTick and interrupt SysTick->CTRL &= ~(SysTick_CTRL_TICKINT_Msk | SysTick_CTRL_ENABLE_Msk); - l_activeSet &= ~(1U << SYSTICK_ACTIVE); /* mark rate-0 as disabled */ + l_activeSet &= ~(1U << SYSTICK_ACTIVE); // mark rate-0 as disabled } - if (((l_activeSet & (1U << TIMER0_ACTIVE)) != 0U) /* rate-1 enabled? */ - && QF_noTimeEvtsActiveX(1U)) /* no time events at rate-1? */ + if (((l_activeSet & (1U << TIMER0_ACTIVE)) != 0U) // rate-1 enabled? + && QTimeEvt_noActive(1U)) // no time events at rate-1? { - /* safe to disable Timer0 and interrupt */ - TIMER0->CTL &= ~(1U << 0); /* disable Timer0 */ - TIMER0->IMR &= ~(1U << 0); /* disable timer interrupt */ - l_activeSet &= ~(1U << TIMER0_ACTIVE); /* mark rate-1 as disabled */ + // safe to disable Timer0 and interrupt + TIMER0->CTL &= ~(1U << 0); // disable Timer0 + TIMER0->IMR &= ~(1U << 0); // disable timer interrupt + l_activeSet &= ~(1U << TIMER0_ACTIVE); // mark rate-1 as disabled } QF_INT_ENABLE(); - GPIOF->DATA_Bits[LED_RED] = 0xFFU; /* turn LED on, see NOTE2 */ - __WFI(); // wait for interrupt */ - GPIOF->DATA_Bits[LED_RED] = 0x00U; /* turn LED off, see NOTE2 */ + GPIOF->DATA_Bits[LED_RED] = 0xFFU; // turn LED on, see NOTE2 + __WFI(); // wait for interrupt + GPIOF->DATA_Bits[LED_RED] = 0x00U; // turn LED off, see NOTE2 } -/*..........................................................................*/ -Q_NORETURN Q_onAssert(char const * const module, int_t const loc) { - /* - * NOTE: add here your application-specific error handling - */ - (void)module; - (void)loc; +//............................................................................ +Q_NORETURN Q_onError(char const * const module, int_t const id) { + // + // NOTE: add here your application-specific error handling + // + Q_UNUSED_PAR(module); + Q_UNUSED_PAR(id); + #ifndef NDEBUG - /* for debugging, hang on in an endless loop toggling the RED LED... */ + // for debugging, hang on in an endless loop toggling the RED LED... while (GPIOF->DATA_Bits[BTN_SW1] != 0) { GPIOF->DATA = LED_RED; GPIOF->DATA = 0U; @@ -232,20 +233,25 @@ Q_NORETURN Q_onAssert(char const * const module, int_t const loc) { #endif NVIC_SystemReset(); } +//............................................................................ +void assert_failed(char const * const module, int_t const id); // prototype +void assert_failed(char const * const module, int_t const id) { + Q_onError(module, id); +} -/***************************************************************************** -* NOTE1: -* The bitmask l_activeSet is **shared** between the QXK idle thread and -* the application-level threads. Therefore this variable needs to be -* always accessed in a critical section. -* -* NOTE2: -* One of the LEDs is used to visualize the CPU sleep mode. The LED is turned -* on before entering the sleep mode and turned off after waking up, so that -* the LED stays ON when the CPU sleeps. -* -* NOTE3: -* The additional polling-delay is added to artificially extend the CPU -* activity after the sleep mode is exited, so that the time the idle-LED -* stays off for a bit longer and can be observed on the slower logic analyzer. -*/ +//============================================================================ +// NOTE1: +// The bitmask l_activeSet is **shared** between the QXK idle thread and +// the application-level threads. Therefore this variable needs to be +// always accessed in a critical section. +// +// NOTE2: +// One of the LEDs is used to visualize the CPU sleep mode. The LED is turned +// on before entering the sleep mode and turned off after waking up, so that +// the LED stays ON when the CPU sleeps. +// +// NOTE3: +// The additional polling-delay is added to artificially extend the CPU +// activity after the sleep mode is exited, so that the time the idle-LED +// stays off for a bit longer and can be observed on the slower logic analyzer. +// diff --git a/examples/arm-cm/low-power_ek-tm4c123gxl/qxk/gnu/Makefile b/examples/arm-cm/low-power_ek-tm4c123gxl/qxk/gnu/Makefile index 1f4bcb40..57f1bd7e 100644 --- a/examples/arm-cm/low-power_ek-tm4c123gxl/qxk/gnu/Makefile +++ b/examples/arm-cm/low-power_ek-tm4c123gxl/qxk/gnu/Makefile @@ -1,7 +1,7 @@ ############################################################################## # Product: Makefile for QP/C on EK-TM4C123GXL, QXK kernel, GNU-ARM -# Last Updated for Version: 7.0.1 -# Date of the Last Update: 2022-05-23 +# Last Updated for Version: 7.3.0 +# Date of the Last Update: 2023-09-03 # # Q u a n t u m L e a P s # ------------------------ @@ -136,7 +136,7 @@ LIB_DIRS := LIBS := # defines -DEFINES := -DTARGET_IS_TM4C123_RB1 +DEFINES := -DQP_CONFIG # ARM CPU, ARCH, FPU, and Float-ABI types... # ARM_CPU: [cortex-m0 | cortex-m0plus | cortex-m1 | cortex-m3 | cortex-m4] @@ -270,7 +270,7 @@ $(TARGET_BIN): $(TARGET_ELF) $(BIN) -O binary $< $@ $(TARGET_ELF) : $(ASM_OBJS_EXT) $(C_OBJS_EXT) $(CPP_OBJS_EXT) - $(CC) $(CFLAGS) $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o + $(CC) $(CFLAGS) $(QPC)/src/qs/qstamp.c -o $(BIN_DIR)/qstamp.o $(LINK) $(LINKFLAGS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) $(BIN_DIR)/%.d : %.c diff --git a/examples/arm-cm/low-power_ek-tm4c123gxl/qxk/iar/low-power-qxk.ewd b/examples/arm-cm/low-power_ek-tm4c123gxl/qxk/iar/low-power-qxk.ewd index 3566d6b2..13d732d4 100644 --- a/examples/arm-cm/low-power_ek-tm4c123gxl/qxk/iar/low-power-qxk.ewd +++ b/examples/arm-cm/low-power_ek-tm4c123gxl/qxk/iar/low-power-qxk.ewd @@ -11,7 +11,7 @@ C-SPY 2 - 28 + 32 1 1 - - + + + + + @@ -486,7 +498,7 @@ IJET_ID 2 - 8 + 9 1 1 + + + + + + + + + + + + + @@ -916,7 +980,7 @@ LMIFTDI_ID 2 - 2 + 3 1 1 + + + + + + + NULINK_ID + 2 + + 0 + 1 + 1 + + + @@ -974,7 +1072,7 @@ STLINK_ID 2 - 4 + 8 1 1 + + + + @@ -1185,7 +1300,7 @@ XDS100_ID 2 - 6 + 9 1 1 + + + + @@ -1362,6 +1493,18 @@ $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin 0 + + $TOOLKIT_DIR$\plugins\rtos\FreeRtos\FreeRtosArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin2.ENU.ewplugin + 0 + $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin 0 @@ -1371,11 +1514,15 @@ 0 - $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9.ewplugin 0 - $TOOLKIT_DIR$\plugins\rtos\TI-RTOS\tirtosplugin.ewplugin + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9BE.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin 0 @@ -1391,11 +1538,11 @@ 0 - $EW_DIR$\common\plugins\CodeCoverage\CodeCoverage.ENU.ewplugin - 1 + $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + 0 - $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + $EW_DIR$\common\plugins\TargetAccessServer\TargetAccessServer.ENU.ewplugin 0 @@ -1414,7 +1561,7 @@ C-SPY 2 - 28 + 32 1 0 - - + + + + + @@ -1889,7 +2048,7 @@ IJET_ID 2 - 8 + 9 1 0 + + + + + + + + + + + + + @@ -2319,7 +2530,7 @@ LMIFTDI_ID 2 - 2 + 3 1 0 + + + + + + + NULINK_ID + 2 + + 0 + 1 + 0 + + + @@ -2377,7 +2622,7 @@ STLINK_ID 2 - 4 + 8 1 0 + + + + @@ -2588,7 +2850,7 @@ XDS100_ID 2 - 6 + 9 1 0 + + + + @@ -2765,6 +3043,18 @@ $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin 0 + + $TOOLKIT_DIR$\plugins\rtos\FreeRtos\FreeRtosArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin2.ENU.ewplugin + 0 + $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin 0 @@ -2774,11 +3064,15 @@ 0 - $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9.ewplugin 0 - $TOOLKIT_DIR$\plugins\rtos\TI-RTOS\tirtosplugin.ewplugin + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9BE.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin 0 @@ -2794,11 +3088,11 @@ 0 - $EW_DIR$\common\plugins\CodeCoverage\CodeCoverage.ENU.ewplugin - 1 + $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + 0 - $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + $EW_DIR$\common\plugins\TargetAccessServer\TargetAccessServer.ENU.ewplugin 0 @@ -2817,7 +3111,7 @@ C-SPY 2 - 28 + 32 1 1 - - + + + + + @@ -3292,7 +3598,7 @@ IJET_ID 2 - 8 + 9 1 1 + + + + + + + + + + + + + @@ -3722,7 +4080,7 @@ LMIFTDI_ID 2 - 2 + 3 1 1 + + + + + + + NULINK_ID + 2 + + 0 + 1 + 1 + + + @@ -3780,7 +4172,7 @@ STLINK_ID 2 - 4 + 8 1 1 + + + + @@ -3991,7 +4400,7 @@ XDS100_ID 2 - 6 + 9 1 1 + + + + @@ -4168,6 +4593,18 @@ $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin 0 + + $TOOLKIT_DIR$\plugins\rtos\FreeRtos\FreeRtosArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin2.ENU.ewplugin + 0 + $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin 0 @@ -4177,11 +4614,15 @@ 0 - $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9.ewplugin 0 - $TOOLKIT_DIR$\plugins\rtos\TI-RTOS\tirtosplugin.ewplugin + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9BE.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin 0 @@ -4197,11 +4638,11 @@ 0 - $EW_DIR$\common\plugins\CodeCoverage\CodeCoverage.ENU.ewplugin - 1 + $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + 0 - $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + $EW_DIR$\common\plugins\TargetAccessServer\TargetAccessServer.ENU.ewplugin 0 diff --git a/examples/arm-cm/low-power_ek-tm4c123gxl/qxk/iar/low-power-qxk.ewp b/examples/arm-cm/low-power_ek-tm4c123gxl/qxk/iar/low-power-qxk.ewp index 541f84bf..290f9585 100644 --- a/examples/arm-cm/low-power_ek-tm4c123gxl/qxk/iar/low-power-qxk.ewp +++ b/examples/arm-cm/low-power_ek-tm4c123gxl/qxk/iar/low-power-qxk.ewp @@ -11,9 +11,13 @@ General 3 - 31 + 35 1 1 + - - - - - + + + + + ICCARM 2 - 35 + 37 1 1 - - - + AARM 2 - 10 + 11 1 1 + @@ -673,13 +669,9 @@ 0 + inputOutputBased - - BICOMP - 0 - - BUILDACTION 1 @@ -692,17 +684,13 @@ ILINK 0 - 22 + 27 1 1 - + + + + + + + + + + + + + @@ -1035,11 +1075,6 @@ - - BILINK - 0 - - Coder 0 @@ -1056,9 +1091,13 @@ General 3 - 31 + 35 1 0 + - - - - - + + + + + ICCARM 2 - 35 + 37 1 0 - @@ -1426,16 +1460,6 @@ CCOptLevelSlave 3 - - + AARM 2 - 10 + 11 1 0 + @@ -1718,13 +1750,9 @@ 0 + inputOutputBased - - BICOMP - 0 - - BUILDACTION 1 @@ -1737,17 +1765,13 @@ ILINK 0 - 22 + 27 1 0 - + + + + + + + + + + + + + @@ -2080,11 +2156,6 @@ - - BILINK - 0 - - Coder 0 @@ -2101,9 +2172,13 @@ General 3 - 31 + 35 1 1 + - - - - - + + + + + ICCARM 2 - 35 + 37 1 1 - @@ -2471,16 +2541,6 @@ CCOptLevelSlave 1 - - + AARM 2 - 10 + 11 1 1 + @@ -2763,13 +2831,9 @@ 0 + inputOutputBased - - BICOMP - 0 - - BUILDACTION 1 @@ -2782,17 +2846,13 @@ ILINK 0 - 22 + 27 1 1 - + + + + + + + + + + + + + @@ -3125,11 +3237,6 @@ - - BILINK - 0 - - Coder 0 @@ -3153,9 +3260,6 @@ $PROJ_DIR$\..\..\main.c - - $PROJ_DIR$\..\..\..\..\..\include\qstamp.c - $PROJ_DIR$\..\xblinky1.c @@ -3260,10 +3364,10 @@ $PROJ_DIR$\..\..\..\..\..\src\qs\qs_fp.c - $PROJ_DIR$\..\..\..\..\..\src\qs_pkg.h + $PROJ_DIR$\..\..\..\..\..\src\qs\qs_rx.c - $PROJ_DIR$\..\..\..\..\..\src\qs\qs_rx.c + $PROJ_DIR$\..\..\..\..\..\src\qs\qstamp.c diff --git a/examples/arm-cm/low-power_ek-tm4c123gxl/qxk/xblinky1.c b/examples/arm-cm/low-power_ek-tm4c123gxl/qxk/xblinky1.c index 9c712604..f97828a0 100644 --- a/examples/arm-cm/low-power_ek-tm4c123gxl/qxk/xblinky1.c +++ b/examples/arm-cm/low-power_ek-tm4c123gxl/qxk/xblinky1.c @@ -1,61 +1,61 @@ -/***************************************************************************** -* Product: "Low-Power" example, EK-TM4C123GXL board, QXK kernel -* Last updated for version 6.4.0 -* Last updated on 2019-02-24 -* -* Q u a n t u m L e a P s -* --------------------------- -* innovating embedded systems -* -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* -* -*****************************************************************************/ +//============================================================================ +// Product: "Low-Power" example, EK-TM4C123GXL board, QXK kernel +// Last updated for version 6.4.0 +// Last updated on 2019-02-24 +// +// Q u a n t u m L e a P s +// --------------------------- +// innovating embedded systems +// +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// This program is open source software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Alternatively, this program may be distributed and modified under the +// terms of Quantum Leaps commercial licenses, which expressly supersede +// the GNU General Public License and are specifically designed for +// licensees interested in retaining the proprietary status of their code. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Contact information: +// +// +//============================================================================ #include "qpc.h" #include "low_power.h" #include "bsp.h" //Q_DEFINE_THIS_FILE -/* local objects -----------------------------------------------------------*/ +// local objects ----------------------------------------------------------- static void XBlinky1_run(QXThread * const me); -/* global objects ----------------------------------------------------------*/ +// global objects ---------------------------------------------------------- QXThread XT_Blinky1; QXSemaphore XSEM_sw1; -/*..........................................................................*/ +//............................................................................ void XBlinky1_ctor(void) { QXThread_ctor(&XT_Blinky1, - &XBlinky1_run, /* thread routine */ - 1U); /* associate the thread with tick rate-1 */ + &XBlinky1_run, // thread routine + 1U); // associate the thread with tick rate-1 } -/*..........................................................................*/ +//............................................................................ static void XBlinky1_run(QXThread * const me) { bool isActive = false; - (void)me; /* unused parameter */ + (void)me; // unused parameter for (;;) { if (!isActive) { QXSemaphore_wait(&XSEM_sw1, QXTHREAD_NO_TIMEOUT); diff --git a/examples/arm-cr/blinky_launchxl2-tms57012/blinky.c b/examples/arm-cr/blinky_launchxl2-tms57012/blinky.c index 0f92891b..006a552d 100644 --- a/examples/arm-cr/blinky_launchxl2-tms57012/blinky.c +++ b/examples/arm-cr/blinky_launchxl2-tms57012/blinky.c @@ -1,74 +1,74 @@ -/***************************************************************************** -* Product: Simple Blinky example -* Last Updated for Version: 5.6.4 -* Date of the Last Update: 2016-05-07 -* -* Q u a n t u m L e a P s -* --------------------------- -* innovating embedded systems -* -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* Web: www.state-machine.com -* -*****************************************************************************/ +//============================================================================ +// Product: Simple Blinky example +// Last Updated for Version: 5.6.4 +// Date of the Last Update: 2016-05-07 +// +// Q u a n t u m L e a P s +// --------------------------- +// innovating embedded systems +// +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// This program is open source software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Alternatively, this program may be distributed and modified under the +// terms of Quantum Leaps commercial licenses, which expressly supersede +// the GNU General Public License and are specifically designed for +// licensees interested in retaining the proprietary status of their code. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Contact information: +// Web: www.state-machine.com +// +//============================================================================ #include "qpc.h" #include "blinky.h" #include "bsp.h" //Q_DEFINE_THIS_FILE -/*..........................................................................*/ -typedef struct { /* the Blinky active object */ - QActive super; /* inherit QActive */ +//............................................................................ +typedef struct { // the Blinky active object + QActive super; // inherit QActive - QTimeEvt timeEvt; /* private time event generator */ + QTimeEvt timeEvt; // private time event generator } Blinky; -static Blinky l_blinky; /* the Blinky active object */ +static Blinky l_blinky; // the Blinky active object QActive * const AO_Blinky = &l_blinky.super; -/* hierarchical state machine ... */ +// hierarchical state machine ... static QState Blinky_initial(Blinky * const me, QEvt const * const e); static QState Blinky_off (Blinky * const me, QEvt const * const e); static QState Blinky_on (Blinky * const me, QEvt const * const e); -/*..........................................................................*/ +//............................................................................ void Blinky_ctor(void) { Blinky * const me = &l_blinky; QActive_ctor(&me->super, Q_STATE_CAST(&Blinky_initial)); QTimeEvt_ctorX(&me->timeEvt, &me->super, TIMEOUT_SIG, 0U); } -/* HSM definition ----------------------------------------------------------*/ +// HSM definition ---------------------------------------------------------- QState Blinky_initial(Blinky * const me, QEvt const * const e) { - (void)e; /* avoid compiler warning about unused parameter */ + (void)e; // avoid compiler warning about unused parameter - /* arm the time event to expire in half a second and every half second */ + // arm the time event to expire in half a second and every half second QTimeEvt_armX(&me->timeEvt, BSP_TICKS_PER_SEC/2U, BSP_TICKS_PER_SEC/2U); return Q_TRAN(&Blinky_off); } -/*..........................................................................*/ +//............................................................................ QState Blinky_off(Blinky * const me, QEvt const * const e) { QState status; switch (e->sig) { @@ -88,7 +88,7 @@ QState Blinky_off(Blinky * const me, QEvt const * const e) { } return status; } -/*..........................................................................*/ +//............................................................................ QState Blinky_on(Blinky * const me, QEvt const * const e) { QState status; switch (e->sig) { diff --git a/examples/arm-cr/blinky_launchxl2-tms57012/blinky.h b/examples/arm-cr/blinky_launchxl2-tms57012/blinky.h index 5568238a..3ac6dfa3 100644 --- a/examples/arm-cr/blinky_launchxl2-tms57012/blinky.h +++ b/examples/arm-cr/blinky_launchxl2-tms57012/blinky.h @@ -1,48 +1,48 @@ -/***************************************************************************** -* Product: simple "Blinky" example -* Last Updated for Version: 5.4.0 -* Date of the Last Update: 2015-03-07 -* -* Q u a n t u m L e a P s -* --------------------------- -* innovating embedded systems -* -* Copyright (C) 2005 Quantum Leaps, LLC. state-machine.com. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* -* -*****************************************************************************/ +//============================================================================ +// Product: simple "Blinky" example +// Last Updated for Version: 5.4.0 +// Date of the Last Update: 2015-03-07 +// +// Q u a n t u m L e a P s +// --------------------------- +// innovating embedded systems +// +// Copyright (C) 2005 Quantum Leaps, LLC. state-machine.com. +// +// This program is open source software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Alternatively, this program may be distributed and modified under the +// terms of Quantum Leaps commercial licenses, which expressly supersede +// the GNU General Public License and are specifically designed for +// licensees interested in retaining the proprietary status of their code. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Contact information: +// +// +//============================================================================ #ifndef BLINKY_H #define BLINKY_H enum BlinkySignals { DUMMY_SIG = Q_USER_SIG, - MAX_PUB_SIG, /* the last published signal */ + MAX_PUB_SIG, // the last published signal TIMEOUT_SIG, - MAX_SIG /* the last signal */ + MAX_SIG // the last signal }; void Blinky_ctor(void); -extern QActive * const AO_Blinky; /* opaque pointer */ +extern QActive * const AO_Blinky; // opaque pointer -#endif /* BLINKY_H */ +#endif // BLINKY_H diff --git a/examples/arm-cr/blinky_launchxl2-tms57012/bsp.h b/examples/arm-cr/blinky_launchxl2-tms57012/bsp.h index 34e7571e..90f6ae9b 100644 --- a/examples/arm-cr/blinky_launchxl2-tms57012/bsp.h +++ b/examples/arm-cr/blinky_launchxl2-tms57012/bsp.h @@ -1,38 +1,38 @@ -/***************************************************************************** -* Product: "Blinky" example -* Last Updated for Version: 5.6.4 -* Date of the Last Update: 2016-05-07 -* -* Q u a n t u m L e a P s -* --------------------------- -* innovating embedded systems -* -* Copyright (C) 2005 Quantum Leaps, LLC. state-machine.com. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* -* -*****************************************************************************/ -#ifndef BSP_H -#define BSP_H +//============================================================================ +// Product: "Blinky" example +// Last Updated for Version: 5.6.4 +// Date of the Last Update: 2016-05-07 +// +// Q u a n t u m L e a P s +// --------------------------- +// innovating embedded systems +// +// Copyright (C) 2005 Quantum Leaps, LLC. state-machine.com. +// +// This program is open source software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Alternatively, this program may be distributed and modified under the +// terms of Quantum Leaps commercial licenses, which expressly supersede +// the GNU General Public License and are specifically designed for +// licensees interested in retaining the proprietary status of their code. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Contact information: +// +// +//============================================================================ +#ifndef BSP_H_ +#define BSP_H_ #define BSP_TICKS_PER_SEC 100U @@ -40,4 +40,4 @@ void BSP_init(void); void BSP_ledOff(void); void BSP_ledOn(void); -#endif /* BSP_H */ +#endif // BSP_H_ diff --git a/examples/arm-cr/blinky_launchxl2-tms57012/main.c b/examples/arm-cr/blinky_launchxl2-tms57012/main.c index aac1a812..f83223ec 100644 --- a/examples/arm-cr/blinky_launchxl2-tms57012/main.c +++ b/examples/arm-cr/blinky_launchxl2-tms57012/main.c @@ -1,60 +1,60 @@ -/***************************************************************************** -* Product: "Blinky" example -* Last updated for version 7.1.1 -* Last updated on 2022-09-22 -* -* Q u a n t u m L e a P s -* ------------------------ -* Modern Embedded Software -* -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* -* -*****************************************************************************/ +//============================================================================ +// Product: "Blinky" example +// Last updated for version 7.1.1 +// Last updated on 2022-09-22 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// This program is open source software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Alternatively, this program may be distributed and modified under the +// terms of Quantum Leaps commercial licenses, which expressly supersede +// the GNU General Public License and are specifically designed for +// licensees interested in retaining the proprietary status of their code. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Contact information: +// +// +//============================================================================ #include "qpc.h" #include "blinky.h" #include "bsp.h" -Q_DEFINE_THIS_FILE +//Q_DEFINE_THIS_FILE -/*..........................................................................*/ +//............................................................................ int main() { - QF_init(); /* initialize the framework and the underlying RT kernel */ - BSP_init(); /* initialize the Board Support Package */ + QF_init(); // initialize the framework and the underlying RT kernel + BSP_init(); // initialize the Board Support Package - /* publish-subscribe not used, no call to QF_psInit() */ - /* dynamic event allocation not used, no call to QF_poolInit() */ + // publish-subscribe not used, no call to QActive_psInit() + // dynamic event allocation not used, no call to QF_poolInit() - /* instantiate and start the active objects... */ + // instantiate and start the active objects... Blinky_ctor(); - static QEvt const *l_blinkyQSto[10]; /* Event queue storage for Blinky */ - QACTIVE_START(AO_Blinky, /* AO pointer to start */ - 2U, /* QF-priority/preemption-threshold */ - l_blinkyQSto, /* storage for the AO's queue */ - Q_DIM(l_blinkyQSto), /* length of the queue [entries] */ - (void *)0, /* stack storage (not used in QK) */ - 0U, /* stack size [bytes] (not used in QK) */ - (QEvt *)0); /* initial event (or 0) */ + static QEvt const *l_blinkyQSto[10]; // Event queue storage for Blinky + QACTIVE_START(AO_Blinky, // AO pointer to start + 2U, // QF-priority/preemption-threshold + l_blinkyQSto, // storage for the AO's queue + Q_DIM(l_blinkyQSto), // length of the queue [entries] + (void *)0, // stack storage (not used in QK) + 0U, // stack size [bytes] (not used in QK) + (QEvt *)0); // initial event (or 0) - return QF_run(); /* run the QF application */ + return QF_run(); // run the QF application } diff --git a/examples/arm-cr/blinky_launchxl2-tms57012/qk/bsp.c b/examples/arm-cr/blinky_launchxl2-tms57012/qk/bsp.c index 8a20759e..e09c33aa 100644 --- a/examples/arm-cr/blinky_launchxl2-tms57012/qk/bsp.c +++ b/examples/arm-cr/blinky_launchxl2-tms57012/qk/bsp.c @@ -1,36 +1,36 @@ -/***************************************************************************** -* Product: "Blinky" on LAUCHXL2-TMS570LS12 board, preemptive QK kernel -* Last Updated for Version: 5.8.1 -* Date of the Last Update: 2016-12-14 -* -* Q u a n t u m L e a P s -* --------------------------- -* innovating embedded systems -* -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* -* -*****************************************************************************/ +//============================================================================ +// Product: "Blinky" on LAUCHXL2-TMS570LS12 board, preemptive QK kernel +// Last Updated for Version: 5.8.1 +// Date of the Last Update: 2016-12-14 +// +// Q u a n t u m L e a P s +// --------------------------- +// innovating embedded systems +// +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// This program is open source software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Alternatively, this program may be distributed and modified under the +// terms of Quantum Leaps commercial licenses, which expressly supersede +// the GNU General Public License and are specifically designed for +// licensees interested in retaining the proprietary status of their code. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Contact information: +// +// +//============================================================================ #include "qpc.h" #include "blinky.h" #include "bsp.h" @@ -42,7 +42,7 @@ #include "gio.h" #include "rti.h" #include "het.h" -/* add other drivers if necessary... */ +// add other drivers if necessary... Q_DEFINE_THIS_FILE @@ -50,18 +50,18 @@ Q_DEFINE_THIS_FILE #error Simple Blinky Application does not provide Spy build configuration #endif -/* ISRs defined in this BSP ------------------------------------------------*/ +// ISRs defined in this BSP ------------------------------------------------ -/* Local-scope objects -----------------------------------------------------*/ +// Local-scope objects ----------------------------------------------------- #define LED2_PIN 1 #define LED2_PORT gioPORTB #define LED3_PIN 2 #define LED3_PORT gioPORTB -/* NOTE: Switch-A is multiplexed on the same port/pin as LED3, -* so you can use one or the other but not both simultaneously. -*/ +// NOTE: Switch-A is multiplexed on the same port/pin as LED3, +// so you can use one or the other but not both simultaneously. +// #define SWA_PIN 2 #define SWA_PORT gioPORTB @@ -70,30 +70,30 @@ Q_DEFINE_THIS_FILE #define VIM_RAM ((t_isrFuncPTR *)0xFFF82000U) -/* ISRs used in this project ===============================================*/ +// ISRs used in this project =============================================== QK_IRQ_BEGIN(rtiCompare0) - rtiREG1->INTFLAG = 1U; /* clear the interrutp source */ - QTIMEEVT_TICK_X(0U, (void *)0); /* process time events for rate 0 */ + rtiREG1->INTFLAG = 1U; // clear the interrutp source + QTIMEEVT_TICK_X(0U, (void *)0); // process time events for rate 0 QK_IRQ_END() -/* BSP functions ===========================================================*/ +// BSP functions =========================================================== void BSP_init(void) { - /* configure the LEDs */ + // configure the LEDs gioInit(); - LED2_PORT->DIR |= (1U << LED2_PIN); /* set as output */ - LED3_PORT->DIR |= (1U << LED3_PIN); /* set as output */ + LED2_PORT->DIR |= (1U << LED2_PIN); // set as output + LED3_PORT->DIR |= (1U << LED3_PIN); // set as output - /* configure the Buttons */ - SWB_PORT->DIR &= (1U << SWB_PIN); /* set as input */ + // configure the Buttons + SWB_PORT->DIR &= (1U << SWB_PIN); // set as input } -/*..........................................................................*/ +//............................................................................ void BSP_ledOff(void) { LED2_PORT->DCLR = (1U << LED2_PIN); } -/*..........................................................................*/ +//............................................................................ void BSP_ledOn(void) { - /* exercise the FPU with some floating point computations */ + // exercise the FPU with some floating point computations float volatile x = 3.1415926F; x = x + 2.7182818F; @@ -101,63 +101,68 @@ void BSP_ledOn(void) { } -/* QF callbacks ============================================================*/ +// QF callbacks ============================================================ void QF_onStartup(void) { - rtiInit(); /* configure RTI with UC counter of 7 */ + rtiInit(); // configure RTI with UC counter of 7 rtiSetPeriod(rtiCOUNTER_BLOCK0, (uint32)((RTI_FREQ*1E6/(7+1))/BSP_TICKS_PER_SEC)); rtiEnableNotification(rtiNOTIFICATION_COMPARE0); rtiStartCounter(rtiCOUNTER_BLOCK0); - VIM_RAM[2 + 1] = (t_isrFuncPTR)&rtiCompare0; /* install the IRQ */ - vimREG->FIRQPR0 &= ~(1U << 2); /* designate interrupt as IRQ, NOTE00 */ - vimREG->REQMASKSET0 = (1U << 2); /* enable RTI interrupt */ + VIM_RAM[2 + 1] = (t_isrFuncPTR)&rtiCompare0; // install the IRQ + vimREG->FIRQPR0 &= ~(1U << 2); // designate interrupt as IRQ, NOTE00 + vimREG->REQMASKSET0 = (1U << 2); // enable RTI interrupt - QF_INT_ENABLE_ALL(); /* enable all interrupts (IRQ and FIQ) */ + QF_INT_ENABLE_ALL(); // enable all interrupts (IRQ and FIQ) } -/*..........................................................................*/ +//............................................................................ void QF_onCleanup(void) { } -/*..........................................................................*/ +//............................................................................ void QK_onIdle(void) { - /* toggle LED1 on and then off, see NOTE01 */ + // toggle LED1 on and then off, see NOTE01 QF_INT_DISABLE(); LED3_PORT->DSET = (1U << LED3_PIN); LED3_PORT->DCLR = (1U << LED3_PIN); QF_INT_ENABLE(); #ifdef NDEBUG - /* Put the CPU and peripherals to the low-power mode. - * you might need to customize the clock management for your application, - * see the datasheet for your particular Cortex-R MCU. - */ - _gotoCPUIdle_(); /* wait for interrupt */ + // Put the CPU and peripherals to the low-power mode. + // you might need to customize the clock management for your application, + // see the datasheet for your particular Cortex-R MCU. + // + _gotoCPUIdle_(); // wait for interrupt #endif } -/*..........................................................................*/ -Q_NORETURN Q_onAssert(char const * const module, int_t const loc) { - /* - * NOTE: add here your application-specific error handling - */ - (void)module; - (void)loc; - QS_ASSERTION(module, loc, 10000U); /* report assertion to QS */ - systemREG1->SYSECR = 0; /* perform system reset */ +//............................................................................ +Q_NORETURN Q_onError(char const * const module, int_t const id) { + // + // NOTE: add here your application-specific error handling + // + Q_UNUSED_PAR(module); + Q_UNUSED_PAR(id); + QS_ASSERTION(module, id, 10000U); // report assertion to QS + systemREG1->SYSECR = 0; // perform system reset +} +//............................................................................ +void assert_failed(char const * const module, int_t const id); // prototype +void assert_failed(char const * const module, int_t const id) { + Q_onError(module, id); } -/***************************************************************************** -* NOTE00: -* The FIQ-type interrupts are never disabled in this QP port, therefore -* they can always preempt any code, including the IRQ-handlers (ISRs). -* Therefore, FIQ-type interrupts are "kernel-unaware" and must NEVER call -* any QP services, such as posting events. -* -* NOTE01: -* One of the LEDs is used to visualize the idle loop activity. The brightness -* of the LED is proportional to the frequency of invcations of the idle loop. -* Please note that the LED is toggled with interrupts locked, so no interrupt -* execution time contributes to the brightness of the User LED. -*/ +//============================================================================ +// NOTE00: +// The FIQ-type interrupts are never disabled in this QP port, therefore +// they can always preempt any code, including the IRQ-handlers (ISRs). +// Therefore, FIQ-type interrupts are "kernel-unaware" and must NEVER call +// any QP services, such as posting events. +// +// NOTE01: +// One of the LEDs is used to visualize the idle loop activity. The brightness +// of the LED is proportional to the frequency of invcations of the idle loop. +// Please note that the LED is toggled with interrupts locked, so no interrupt +// execution time contributes to the brightness of the User LED. +// diff --git a/examples/arm-cr/blinky_launchxl2-tms57012/qk/iar/blinky-qk.ewd b/examples/arm-cr/blinky_launchxl2-tms57012/qk/iar/blinky-qk.ewd index 55042ab7..05b9e883 100644 --- a/examples/arm-cr/blinky_launchxl2-tms57012/qk/iar/blinky-qk.ewd +++ b/examples/arm-cr/blinky_launchxl2-tms57012/qk/iar/blinky-qk.ewd @@ -1,4900 +1,4654 @@ - - + - 2 - - Debug - - ARM - - 1 - - C-SPY - 2 - - 28 - 1 + 3 + + Debug + + ARM + 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ARMSIM_ID - 2 - - 1 - 1 - 1 - - - - - - - - ANGEL_ID - 2 - - 0 - 1 - 1 - - - - - - - - - - - - CADI_ID - 2 - - 0 - 1 - 1 - - - - - - - - - CMSISDAP_ID - 2 - - 4 - 1 - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - GDBSERVER_ID - 2 - - 0 - 1 - 1 - - - - - - - - - - - IARROM_ID - 2 - - 1 - 1 - 1 - - - - - - - - - IJET_ID - 2 - - 8 - 1 - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - JLINK_ID - 2 - - 16 - 1 - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - LMIFTDI_ID - 2 - - 2 - 1 - 1 - - - - - - - - - - MACRAIGOR_ID - 2 - - 3 - 1 - 1 - - - - - - - - - - - - - - - - - - - - - - - PEMICRO_ID - 2 - - 3 - 1 - 1 - - - - - - - - RDI_ID - 2 - - 2 - 1 - 1 - - - - - - - - - - - - - - - - STLINK_ID - 2 - - 3 - 1 - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - THIRDPARTY_ID - 2 - - 0 - 1 - 1 - - - - - - - - TIFET_ID - 2 - - 1 - 1 - 1 - - - - - - - - - - - - - - - - - - - XDS100_ID - 2 - - 5 - 1 - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - $TOOLKIT_DIR$\plugins\middleware\HCCWare\HCCWare.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\middleware\PercepioTraceExporter\PercepioTraceExportPlugin.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\AVIX\AVIX.ENU.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\CMX\CmxArmPlugin.ENU.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\CMX\CmxTinyArmPlugin.ENU.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\MQX\MQXRtosPlugin.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\Quadros\Quadros_EWB7_Plugin.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\SafeRTOS\SafeRTOSPlugin.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\TI-RTOS\tirtosplugin.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-286-KA-CSpy.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-KA-CSpy.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\uCOS-III\uCOS-III-KA-CSpy.ewplugin - 0 - - - $EW_DIR$\common\plugins\CodeCoverage\CodeCoverage.ENU.ewplugin - 1 - - - $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin - 0 - - - $EW_DIR$\common\plugins\uCProbe\uCProbePlugin.ENU.ewplugin - 0 - - - - - Release - - ARM - - 0 - - C-SPY - 2 - - 28 - 1 + + C-SPY + 2 + + 32 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ARMSIM_ID + 2 + + 1 + 1 + 1 + + + + + + + + CADI_ID + 2 + + 0 + 1 + 1 + + + + + + + + + CMSISDAP_ID + 2 + + 4 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + GDBSERVER_ID + 2 + + 0 + 1 + 1 + + + + + + + + + + + IJET_ID + 2 + + 9 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + JLINK_ID + 2 + + 16 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + LMIFTDI_ID + 2 + + 3 + 1 + 1 + + + + + + + + + + + + + NULINK_ID + 2 + + 0 + 1 + 1 + + + + + + + PEMICRO_ID + 2 + + 3 + 1 + 1 + + + + + + + + STLINK_ID + 2 + + 8 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + THIRDPARTY_ID + 2 + + 0 + 1 + 1 + + + + + + + + TIFET_ID + 2 + + 1 + 1 + 1 + + + + + + + + + + + + + + + + + + + XDS100_ID + 2 + + 9 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + $TOOLKIT_DIR$\plugins\rtos\CMX\CmxArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\CMX\CmxTinyArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\FreeRtos\FreeRtosArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin2.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SafeRTOS\SafeRTOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9BE.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-286-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-III\uCOS-III-KA-CSpy.ewplugin + 0 + + + $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\TargetAccessServer\TargetAccessServer.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\uCProbe\uCProbePlugin.ENU.ewplugin + 0 + + + + + Release + + ARM + 0 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ARMSIM_ID - 2 - - 1 - 1 - 0 - - - - - - - - ANGEL_ID - 2 - - 0 - 1 - 0 - - - - - - - - - - - - CADI_ID - 2 - - 0 - 1 - 0 - - - - - - - - - CMSISDAP_ID - 2 - - 4 - 1 - 0 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - GDBSERVER_ID - 2 - - 0 - 1 - 0 - - - - - - - - - - - IARROM_ID - 2 - - 1 - 1 - 0 - - - - - - - - - IJET_ID - 2 - - 8 - 1 - 0 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - JLINK_ID - 2 - - 16 - 1 - 0 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - LMIFTDI_ID - 2 - - 2 - 1 - 0 - - - - - - - - - - MACRAIGOR_ID - 2 - - 3 - 1 - 0 - - - - - - - - - - - - - - - - - - - - - - - PEMICRO_ID - 2 - - 3 - 1 - 0 - - - - - - - - RDI_ID - 2 - - 2 - 1 - 0 - - - - - - - - - - - - - - - - STLINK_ID - 2 - - 3 - 1 - 0 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - THIRDPARTY_ID - 2 - - 0 - 1 - 0 - - - - - - - - TIFET_ID - 2 - - 1 - 1 - 0 - - - - - - - - - - - - - - - - - - - XDS100_ID - 2 - - 5 - 1 - 0 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - $TOOLKIT_DIR$\plugins\middleware\HCCWare\HCCWare.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\middleware\PercepioTraceExporter\PercepioTraceExportPlugin.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\AVIX\AVIX.ENU.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\CMX\CmxArmPlugin.ENU.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\CMX\CmxTinyArmPlugin.ENU.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\MQX\MQXRtosPlugin.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\Quadros\Quadros_EWB7_Plugin.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\SafeRTOS\SafeRTOSPlugin.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\TI-RTOS\tirtosplugin.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-286-KA-CSpy.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-KA-CSpy.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\uCOS-III\uCOS-III-KA-CSpy.ewplugin - 0 - - - $EW_DIR$\common\plugins\CodeCoverage\CodeCoverage.ENU.ewplugin - 1 - - - $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin - 0 - - - $EW_DIR$\common\plugins\uCProbe\uCProbePlugin.ENU.ewplugin - 0 - - - - - Spy - - ARM - - 1 - - C-SPY - 2 - - 28 - 1 + + C-SPY + 2 + + 32 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ARMSIM_ID + 2 + + 1 + 1 + 0 + + + + + + + + CADI_ID + 2 + + 0 + 1 + 0 + + + + + + + + + CMSISDAP_ID + 2 + + 4 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + GDBSERVER_ID + 2 + + 0 + 1 + 0 + + + + + + + + + + + IJET_ID + 2 + + 9 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + JLINK_ID + 2 + + 16 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + LMIFTDI_ID + 2 + + 3 + 1 + 0 + + + + + + + + + + + + + NULINK_ID + 2 + + 0 + 1 + 0 + + + + + + + PEMICRO_ID + 2 + + 3 + 1 + 0 + + + + + + + + STLINK_ID + 2 + + 8 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + THIRDPARTY_ID + 2 + + 0 + 1 + 0 + + + + + + + + TIFET_ID + 2 + + 1 + 1 + 0 + + + + + + + + + + + + + + + + + + + XDS100_ID + 2 + + 9 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + $TOOLKIT_DIR$\plugins\rtos\CMX\CmxArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\CMX\CmxTinyArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\FreeRtos\FreeRtosArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin2.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SafeRTOS\SafeRTOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9BE.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-286-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-III\uCOS-III-KA-CSpy.ewplugin + 0 + + + $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\TargetAccessServer\TargetAccessServer.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\uCProbe\uCProbePlugin.ENU.ewplugin + 0 + + + + + Spy + + ARM + 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ARMSIM_ID - 2 - - 1 - 1 - 1 - - - - - - - - ANGEL_ID - 2 - - 0 - 1 - 1 - - - - - - - - - - - - CADI_ID - 2 - - 0 - 1 - 1 - - - - - - - - - CMSISDAP_ID - 2 - - 4 - 1 - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - GDBSERVER_ID - 2 - - 0 - 1 - 1 - - - - - - - - - - - IARROM_ID - 2 - - 1 - 1 - 1 - - - - - - - - - IJET_ID - 2 - - 8 - 1 - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - JLINK_ID - 2 - - 16 - 1 - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - LMIFTDI_ID - 2 - - 2 - 1 - 1 - - - - - - - - - - MACRAIGOR_ID - 2 - - 3 - 1 - 1 - - - - - - - - - - - - - - - - - - - - - - - PEMICRO_ID - 2 - - 3 - 1 - 1 - - - - - - - - RDI_ID - 2 - - 2 - 1 - 1 - - - - - - - - - - - - - - - - STLINK_ID - 2 - - 3 - 1 - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - THIRDPARTY_ID - 2 - - 0 - 1 - 1 - - - - - - - - TIFET_ID - 2 - - 1 - 1 - 1 - - - - - - - - - - - - - - - - - - - XDS100_ID - 2 - - 5 - 1 - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - $TOOLKIT_DIR$\plugins\middleware\HCCWare\HCCWare.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\middleware\PercepioTraceExporter\PercepioTraceExportPlugin.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\AVIX\AVIX.ENU.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\CMX\CmxArmPlugin.ENU.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\CMX\CmxTinyArmPlugin.ENU.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\MQX\MQXRtosPlugin.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\Quadros\Quadros_EWB7_Plugin.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\SafeRTOS\SafeRTOSPlugin.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\TI-RTOS\tirtosplugin.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-286-KA-CSpy.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-KA-CSpy.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\uCOS-III\uCOS-III-KA-CSpy.ewplugin - 0 - - - $EW_DIR$\common\plugins\CodeCoverage\CodeCoverage.ENU.ewplugin - 1 - - - $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin - 0 - - - $EW_DIR$\common\plugins\uCProbe\uCProbePlugin.ENU.ewplugin - 0 - - - + + C-SPY + 2 + + 32 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ARMSIM_ID + 2 + + 1 + 1 + 1 + + + + + + + + CADI_ID + 2 + + 0 + 1 + 1 + + + + + + + + + CMSISDAP_ID + 2 + + 4 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + GDBSERVER_ID + 2 + + 0 + 1 + 1 + + + + + + + + + + + IJET_ID + 2 + + 9 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + JLINK_ID + 2 + + 16 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + LMIFTDI_ID + 2 + + 3 + 1 + 1 + + + + + + + + + + + + + NULINK_ID + 2 + + 0 + 1 + 1 + + + + + + + PEMICRO_ID + 2 + + 3 + 1 + 1 + + + + + + + + STLINK_ID + 2 + + 8 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + THIRDPARTY_ID + 2 + + 0 + 1 + 1 + + + + + + + + TIFET_ID + 2 + + 1 + 1 + 1 + + + + + + + + + + + + + + + + + + + XDS100_ID + 2 + + 9 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + $TOOLKIT_DIR$\plugins\rtos\CMX\CmxArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\CMX\CmxTinyArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\FreeRtos\FreeRtosArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin2.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SafeRTOS\SafeRTOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9BE.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-286-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-III\uCOS-III-KA-CSpy.ewplugin + 0 + + + $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\TargetAccessServer\TargetAccessServer.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\uCProbe\uCProbePlugin.ENU.ewplugin + 0 + + + - - diff --git a/examples/arm-cr/blinky_launchxl2-tms57012/qk/iar/blinky-qk.ewp b/examples/arm-cr/blinky_launchxl2-tms57012/qk/iar/blinky-qk.ewp index deaf0096..e863c15f 100644 --- a/examples/arm-cr/blinky_launchxl2-tms57012/qk/iar/blinky-qk.ewp +++ b/examples/arm-cr/blinky_launchxl2-tms57012/qk/iar/blinky-qk.ewp @@ -1,3077 +1,3407 @@ - - + - 2 - - Debug - - ARM - - 1 - - General - 3 - - 24 - 1 + 3 + + Debug + + ARM + 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ICCARM - 2 - - 31 - 1 - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - AARM - 2 - - 9 - 1 - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - OBJCOPY - 0 - - 1 - 1 - 1 - - - - - - - - - CUSTOM - 3 - - - - 0 - - - - BICOMP - 0 - - - - BUILDACTION - 1 - - cmd /c "if exist $OBJ_DIR$\qstamp.o del $OBJ_DIR$\qstamp.o" - - - - - ILINK - 0 - - 17 - 1 - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - IARCHIVE - 0 - - 0 - 1 - 1 - - - - - - - BILINK - 0 - - - - Coder - 0 - - - - - Release - - ARM - - 0 - - General - 3 - - 24 - 1 + + General + 3 + + 35 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ICCARM + 2 + + 37 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + AARM + 2 + + 11 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + OBJCOPY + 0 + + 1 + 1 + 1 + + + + + + + + + CUSTOM + 3 + + + + 0 + inputOutputBased + + + + BUILDACTION + 1 + + cmd /c "if exist $OBJ_DIR$\qstamp.o del $OBJ_DIR$\qstamp.o" + + + + + ILINK + 0 + + 27 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + IARCHIVE + 0 + + 0 + 1 + 1 + + + + + + + Coder + 0 + + + + + Release + + ARM + 0 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ICCARM - 2 - - 31 - 1 - 0 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - AARM - 2 - - 9 - 1 - 0 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - OBJCOPY - 0 - - 1 - 1 - 0 - - - - - - - - - CUSTOM - 3 - - - - 0 - - - - BICOMP - 0 - - - - BUILDACTION - 1 - - cmd /c "if exist $OBJ_DIR$\qstamp.o del $OBJ_DIR$\qstamp.o" - - - - - ILINK - 0 - - 17 - 1 - 0 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - IARCHIVE - 0 - - 0 - 1 - 0 - - - - - - - BILINK - 0 - - - - Coder - 0 - - - - - Spy - - ARM - - 1 - - General - 3 - - 24 - 1 + + General + 3 + + 35 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ICCARM + 2 + + 37 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + AARM + 2 + + 11 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + OBJCOPY + 0 + + 1 + 1 + 0 + + + + + + + + + CUSTOM + 3 + + + + 0 + inputOutputBased + + + + BUILDACTION + 1 + + cmd /c "if exist $OBJ_DIR$\qstamp.o del $OBJ_DIR$\qstamp.o" + + + + + ILINK + 0 + + 27 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + IARCHIVE + 0 + + 0 + 1 + 0 + + + + + + + Coder + 0 + + + + + Spy + + ARM + 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ICCARM - 2 - - 31 - 1 - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - AARM - 2 - - 9 - 1 - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - OBJCOPY - 0 - - 1 - 1 - 1 - - - - - - - - - CUSTOM - 3 - - - - 0 - - - - BICOMP - 0 - - - - BUILDACTION - 1 - - cmd /c "if exist $OBJ_DIR$\qstamp.o del $OBJ_DIR$\qstamp.o" - - - - - ILINK - 0 - - 17 - 1 - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - IARCHIVE - 0 - - 0 - 1 - 1 - - - - - - - BILINK - 0 - - - - Coder - 0 - - - - - Application - - $PROJ_DIR$\..\..\blinky.c - - - $PROJ_DIR$\..\..\blinky.h - - - $PROJ_DIR$\..\bsp.c - - - $PROJ_DIR$\..\..\bsp.h - - - $PROJ_DIR$\..\..\main.c - - - $PROJ_DIR$\..\..\..\..\..\include\qstamp.c - - - - launchxl2-tms57012 - - $PROJ_DIR$\..\..\..\..\..\3rd_party\launchxl2-tms57012\iar\source\dabort.asm - - - $PROJ_DIR$\..\..\..\..\..\3rd_party\launchxl2-tms57012\iar\source\esm.c - - - $PROJ_DIR$\..\..\..\..\..\3rd_party\launchxl2-tms57012\iar\source\exceptions.c - - - $PROJ_DIR$\..\..\..\..\..\3rd_party\launchxl2-tms57012\iar\source\gio.c - - - $PROJ_DIR$\..\..\..\..\..\3rd_party\launchxl2-tms57012\iar\source\het.c - - - $PROJ_DIR$\..\..\..\..\..\3rd_party\launchxl2-tms57012\iar\source\notification.c - - - $PROJ_DIR$\..\..\..\..\..\3rd_party\launchxl2-tms57012\iar\source\pinmux.c - - - $PROJ_DIR$\..\..\..\..\..\3rd_party\launchxl2-tms57012\iar\source\rti.c - - - $PROJ_DIR$\..\..\..\..\..\3rd_party\launchxl2-tms57012\iar\source\sci.c - - - $PROJ_DIR$\..\..\..\..\..\3rd_party\launchxl2-tms57012\iar\source\sys_core.asm - - - $PROJ_DIR$\..\..\..\..\..\3rd_party\launchxl2-tms57012\iar\source\sys_intvecs.asm - - - $PROJ_DIR$\..\..\..\..\..\3rd_party\launchxl2-tms57012\iar\source\sys_mpu.asm - - - $PROJ_DIR$\..\..\..\..\..\3rd_party\launchxl2-tms57012\iar\source\sys_pcr.c - - - $PROJ_DIR$\..\..\..\..\..\3rd_party\launchxl2-tms57012\iar\source\sys_phantom.c - - - $PROJ_DIR$\..\..\..\..\..\3rd_party\launchxl2-tms57012\iar\source\sys_pmm.c - - - $PROJ_DIR$\..\..\..\..\..\3rd_party\launchxl2-tms57012\iar\source\sys_pmu.asm - - - $PROJ_DIR$\..\..\..\..\..\3rd_party\launchxl2-tms57012\iar\source\sys_selftest.c - - - $PROJ_DIR$\..\..\..\..\..\3rd_party\launchxl2-tms57012\iar\source\sys_startup.c - - - $PROJ_DIR$\..\..\..\..\..\3rd_party\launchxl2-tms57012\iar\source\sys_vim.c - - - $PROJ_DIR$\..\..\..\..\..\3rd_party\launchxl2-tms57012\iar\source\system.c - - - - QP - - $PROJ_DIR$\..\..\..\..\..\src\qf\qep_hsm.c - - - $PROJ_DIR$\..\..\..\..\..\src\qf\qep_msm.c - - - $PROJ_DIR$\..\..\..\..\..\src\qf\qf_act.c - - - $PROJ_DIR$\..\..\..\..\..\src\qf\qf_actq.c - - - $PROJ_DIR$\..\..\..\..\..\src\qf\qf_defer.c - - - $PROJ_DIR$\..\..\..\..\..\src\qf\qf_dyn.c - - - $PROJ_DIR$\..\..\..\..\..\src\qf\qf_mem.c - - - $PROJ_DIR$\..\..\..\..\..\src\qf_pkg.h - - - $PROJ_DIR$\..\..\..\..\..\src\qf\qf_ps.c - - - $PROJ_DIR$\..\..\..\..\..\src\qf\qf_qact.c - - - $PROJ_DIR$\..\..\..\..\..\src\qf\qf_qeq.c - - - $PROJ_DIR$\..\..\..\..\..\src\qf\qf_qmact.c - - - $PROJ_DIR$\..\..\..\..\..\src\qf\qf_time.c - - - $PROJ_DIR$\..\..\..\..\..\src\qk\qk.c - - - $PROJ_DIR$\..\..\..\..\..\src\qk_pkg.h - - - - QP_port - - $PROJ_DIR$\..\..\..\..\..\ports\arm-cr\qk\iar\qep_port.h - - - $PROJ_DIR$\..\..\..\..\..\ports\arm-cr\qk\iar\qf_port.h - - - $PROJ_DIR$\..\..\..\..\..\ports\arm-cr\qk\iar\qk_port.h - - - $PROJ_DIR$\..\..\..\..\..\ports\arm-cr\qk\iar\qs_port.h - - - - QS - - Debug - Release - - - $PROJ_DIR$\..\..\..\..\..\src\qs\qs.c - - - $PROJ_DIR$\..\..\..\..\..\src\qs\qs_fp.c - - - $PROJ_DIR$\..\..\..\..\..\src\qs_pkg.h - - - $PROJ_DIR$\..\..\..\..\..\src\qs\qs_rx.c - - + + General + 3 + + 35 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ICCARM + 2 + + 37 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + AARM + 2 + + 11 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + OBJCOPY + 0 + + 1 + 1 + 1 + + + + + + + + + CUSTOM + 3 + + + + 0 + inputOutputBased + + + + BUILDACTION + 1 + + cmd /c "if exist $OBJ_DIR$\qstamp.o del $OBJ_DIR$\qstamp.o" + + + + + ILINK + 0 + + 27 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + IARCHIVE + 0 + + 0 + 1 + 1 + + + + + + + Coder + 0 + + + + + Application + + $PROJ_DIR$\..\..\blinky.c + + + $PROJ_DIR$\..\..\blinky.h + + + $PROJ_DIR$\..\bsp.c + + + $PROJ_DIR$\..\..\bsp.h + + + $PROJ_DIR$\..\..\main.c + + + + launchxl2-tms57012 + + $PROJ_DIR$\..\..\..\..\..\3rd_party\launchxl2-tms57012\iar\source\dabort.asm + + + $PROJ_DIR$\..\..\..\..\..\3rd_party\launchxl2-tms57012\iar\source\esm.c + + + $PROJ_DIR$\..\..\..\..\..\3rd_party\launchxl2-tms57012\iar\source\exceptions.c + + + $PROJ_DIR$\..\..\..\..\..\3rd_party\launchxl2-tms57012\iar\source\gio.c + + + $PROJ_DIR$\..\..\..\..\..\3rd_party\launchxl2-tms57012\iar\source\het.c + + + $PROJ_DIR$\..\..\..\..\..\3rd_party\launchxl2-tms57012\iar\source\notification.c + + + $PROJ_DIR$\..\..\..\..\..\3rd_party\launchxl2-tms57012\iar\source\pinmux.c + + + $PROJ_DIR$\..\..\..\..\..\3rd_party\launchxl2-tms57012\iar\source\rti.c + + + $PROJ_DIR$\..\..\..\..\..\3rd_party\launchxl2-tms57012\iar\source\sci.c + + + $PROJ_DIR$\..\..\..\..\..\3rd_party\launchxl2-tms57012\iar\source\sys_core.asm + + + $PROJ_DIR$\..\..\..\..\..\3rd_party\launchxl2-tms57012\iar\source\sys_intvecs.asm + + + $PROJ_DIR$\..\..\..\..\..\3rd_party\launchxl2-tms57012\iar\source\sys_mpu.asm + + + $PROJ_DIR$\..\..\..\..\..\3rd_party\launchxl2-tms57012\iar\source\sys_pcr.c + + + $PROJ_DIR$\..\..\..\..\..\3rd_party\launchxl2-tms57012\iar\source\sys_phantom.c + + + $PROJ_DIR$\..\..\..\..\..\3rd_party\launchxl2-tms57012\iar\source\sys_pmm.c + + + $PROJ_DIR$\..\..\..\..\..\3rd_party\launchxl2-tms57012\iar\source\sys_pmu.asm + + + $PROJ_DIR$\..\..\..\..\..\3rd_party\launchxl2-tms57012\iar\source\sys_selftest.c + + + $PROJ_DIR$\..\..\..\..\..\3rd_party\launchxl2-tms57012\iar\source\sys_startup.c + + + $PROJ_DIR$\..\..\..\..\..\3rd_party\launchxl2-tms57012\iar\source\sys_vim.c + + + $PROJ_DIR$\..\..\..\..\..\3rd_party\launchxl2-tms57012\iar\source\system.c + + + + QP + + $PROJ_DIR$\..\..\..\..\..\src\qf\qep_hsm.c + + + $PROJ_DIR$\..\..\..\..\..\src\qf\qep_msm.c + + + $PROJ_DIR$\..\..\..\..\..\src\qf\qf_act.c + + + $PROJ_DIR$\..\..\..\..\..\src\qf\qf_actq.c + + + $PROJ_DIR$\..\..\..\..\..\src\qf\qf_defer.c + + + $PROJ_DIR$\..\..\..\..\..\src\qf\qf_dyn.c + + + $PROJ_DIR$\..\..\..\..\..\src\qf\qf_mem.c + + + $PROJ_DIR$\..\..\..\..\..\src\qf_pkg.h + + + $PROJ_DIR$\..\..\..\..\..\src\qf\qf_ps.c + + + $PROJ_DIR$\..\..\..\..\..\src\qf\qf_qact.c + + + $PROJ_DIR$\..\..\..\..\..\src\qf\qf_qeq.c + + + $PROJ_DIR$\..\..\..\..\..\src\qf\qf_qmact.c + + + $PROJ_DIR$\..\..\..\..\..\src\qf\qf_time.c + + + $PROJ_DIR$\..\..\..\..\..\src\qk\qk.c + + + $PROJ_DIR$\..\..\..\..\..\src\qk_pkg.h + + + + QP_port + + $PROJ_DIR$\..\..\..\..\..\ports\arm-cr\qk\iar\qep_port.h + + + $PROJ_DIR$\..\..\..\..\..\ports\arm-cr\qk\iar\qf_port.h + + + $PROJ_DIR$\..\..\..\..\..\ports\arm-cr\qk\iar\qk_port.h + + + $PROJ_DIR$\..\..\..\..\..\ports\arm-cr\qk\iar\qs_port.h + + + + QS + + Debug + Release + + + $PROJ_DIR$\..\..\..\..\..\src\qs\qs.c + + + $PROJ_DIR$\..\..\..\..\..\src\qs\qs_fp.c + + + $PROJ_DIR$\..\..\..\..\..\src\qs_pkg.h + + + $PROJ_DIR$\..\..\..\..\..\src\qs\qs_rx.c + + + $PROJ_DIR$\..\..\..\..\..\src\qs\qstamp.c + + - - diff --git a/examples/arm-cr/blinky_launchxl2-tms57012/qv/bsp.c b/examples/arm-cr/blinky_launchxl2-tms57012/qv/bsp.c index 44ab55a3..87909d32 100644 --- a/examples/arm-cr/blinky_launchxl2-tms57012/qv/bsp.c +++ b/examples/arm-cr/blinky_launchxl2-tms57012/qv/bsp.c @@ -1,36 +1,36 @@ -/***************************************************************************** -* Product: "Blinky" on LAUCHXL2-TMS570LS12 board, cooperative QV kernel -* Last Updated for Version: 5.7.0 -* Date of the Last Update: 2016-08-28 -* -* Q u a n t u m L e a P s -* --------------------------- -* innovating embedded systems -* -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* -* -*****************************************************************************/ +//============================================================================ +// Product: "Blinky" on LAUCHXL2-TMS570LS12 board, cooperative QV kernel +// Last Updated for Version: 5.7.0 +// Date of the Last Update: 2016-08-28 +// +// Q u a n t u m L e a P s +// --------------------------- +// innovating embedded systems +// +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// This program is open source software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Alternatively, this program may be distributed and modified under the +// terms of Quantum Leaps commercial licenses, which expressly supersede +// the GNU General Public License and are specifically designed for +// licensees interested in retaining the proprietary status of their code. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Contact information: +// +// +//============================================================================ #include "qpc.h" #include "blinky.h" #include "bsp.h" @@ -42,7 +42,7 @@ #include "gio.h" #include "rti.h" #include "het.h" -/* add other drivers if necessary... */ +// add other drivers if necessary... //Q_DEFINE_THIS_FILE @@ -50,18 +50,18 @@ #error Simple Blinky Application does not provide Spy build configuration #endif -/* ISRs defined in this BSP ------------------------------------------------*/ +// ISRs defined in this BSP ------------------------------------------------ -/* Local-scope objects -----------------------------------------------------*/ +// Local-scope objects ----------------------------------------------------- #define LED2_PIN 1 #define LED2_PORT gioPORTB #define LED3_PIN 2 #define LED3_PORT gioPORTB -/* NOTE: Switch-A is multiplexed on the same port/pin as LED3, -* so you can use one or the other but not both simultaneously. -*/ +// NOTE: Switch-A is multiplexed on the same port/pin as LED3, +// so you can use one or the other but not both simultaneously. +// #define SWA_PIN 2 #define SWA_PORT gioPORTB @@ -70,36 +70,36 @@ #define VIM_RAM ((t_isrFuncPTR *)0xFFF82000U) -/* ISRs used in this project ===============================================*/ -/* NOTE: -* The QV kernel can use the standard interrupt implementation generated -* by the HALCoGen. Here the RTI COMPARE0 is handled in a "notification" -* function called from rtiCompare0Interrupt() in the rti.c module. -*/ +// ISRs used in this project =============================================== +// NOTE: +// The QV kernel can use the standard interrupt implementation generated +// by the HALCoGen. Here the RTI COMPARE0 is handled in a "notification" +// function called from rtiCompare0Interrupt() in the rti.c module. +// void rtiNotification(uint32 notification) { if (notification == rtiNOTIFICATION_COMPARE0) { - QTIMEEVT_TICK_X(0U, (void *)0); /* process time events for rate 0 */ + QTIMEEVT_TICK_X(0U, (void *)0); // process time events for rate 0 } } -/* BSP functions ===========================================================*/ +// BSP functions =========================================================== void BSP_init(void) { - /* configure the LEDs */ + // configure the LEDs gioInit(); - LED2_PORT->DIR |= (1U << LED2_PIN); /* set as output */ - LED3_PORT->DIR |= (1U << LED3_PIN); /* set as output */ + LED2_PORT->DIR |= (1U << LED2_PIN); // set as output + LED3_PORT->DIR |= (1U << LED3_PIN); // set as output - /* configure the Buttons */ - SWB_PORT->DIR &= (1U << SWB_PIN); /* set as input */ + // configure the Buttons + SWB_PORT->DIR &= (1U << SWB_PIN); // set as input } -/*..........................................................................*/ +//............................................................................ void BSP_ledOff(void) { LED2_PORT->DCLR = (1U << LED2_PIN); } -/*..........................................................................*/ +//............................................................................ void BSP_ledOn(void) { - /* exercise the FPU with some floating point computations */ + // exercise the FPU with some floating point computations float volatile x = 3.1415926F; x = x + 2.7182818F; @@ -107,70 +107,77 @@ void BSP_ledOn(void) { } -/* QF callbacks ============================================================*/ +// QF callbacks ============================================================ void QF_onStartup(void) { - rtiInit(); /* configure RTI with UC counter of 7 */ + rtiInit(); // configure RTI with UC counter of 7 rtiSetPeriod(rtiCOUNTER_BLOCK0, (uint32)((RTI_FREQ*1E6/(7+1))/BSP_TICKS_PER_SEC)); - rtiEnableNotification(rtiNOTIFICATION_COMPARE0); /* enable interrupt */ + rtiEnableNotification(rtiNOTIFICATION_COMPARE0); // enable interrupt rtiStartCounter(rtiCOUNTER_BLOCK0); - /* NOTE: don't need to install the IRQ handler in VIM_RAM, because - * the standard handler rtiCompare0Interrupt() installed in the - * HALCoGen code is adequate - */ - vimREG->FIRQPR0 &= ~(1U << 2); /* designate interrupt as IRQ, NOTE00 */ - vimREG->REQMASKSET0 = (1U << 2); /* enable RTI interrupt */ + // NOTE: don't need to install the IRQ handler in VIM_RAM, because + // the standard handler rtiCompare0Interrupt() installed in the + // HALCoGen code is adequate + // + vimREG->FIRQPR0 &= ~(1U << 2); // designate interrupt as IRQ, NOTE00 + vimREG->REQMASKSET0 = (1U << 2); // enable RTI interrupt - QF_INT_ENABLE_ALL(); /* enable all interrupts (IRQ and FIQ) */ + QF_INT_ENABLE_ALL(); // enable all interrupts (IRQ and FIQ) } -/*..........................................................................*/ +//............................................................................ void QF_onCleanup(void) { } -/*..........................................................................*/ -void QV_onIdle(void) { /* CATION: called with interrupts DISABLED, NOTE01 */ - /* toggle LED1 on and then off, see NOTE01 */ +//............................................................................ +void QV_onIdle(void) { // CATION: called with interrupts DISABLED, NOTE01 + // toggle LED1 on and then off, see NOTE01 LED3_PORT->DSET = (1U << LED3_PIN); LED3_PORT->DCLR = (1U << LED3_PIN); #ifdef NDEBUG - /* Put the CPU and peripherals to the low-power mode. - * you might need to customize the clock management for your application, - * see the datasheet for your particular Cortex-R MCU. - */ - QV_CPU_SLEEP(); /* atomically go to sleep and enable interrupts */ + // Put the CPU and peripherals to the low-power mode. + // you might need to customize the clock management for your application, + // see the datasheet for your particular Cortex-R MCU. + // + QV_CPU_SLEEP(); // atomically go to sleep and enable interrupts #else - QF_INT_ENABLE(); /* just enable interrupts */ + QF_INT_ENABLE(); // just enable interrupts #endif } -/*..........................................................................*/ -Q_NORETURN Q_onAssert(char const * const module, int_t const loc) { - /* - * NOTE: add here your application-specific error handling - */ - (void)module; - (void)loc; - QS_ASSERTION(module, loc, 10000U); /* report assertion to QS */ - systemREG1->SYSECR = 0; /* perform system reset */ +//............................................................................ +Q_NORETURN Q_onError(char const * const module, int_t const id) { + // + // NOTE: add here your application-specific error handling + // + Q_UNUSED_PAR(module); + Q_UNUSED_PAR(id); + + QS_ASSERTION(module, id, 10000U); // report assertion to QS + systemREG1->SYSECR = 0; // perform system reset + for (;;) {} // explicitly no-return +} +//............................................................................ +void assert_failed(char const * const module, int_t const id); // prototype +void assert_failed(char const * const module, int_t const id) { + Q_onError(module, id); } -/***************************************************************************** -* NOTE00: -* The FIQ-type interrupts are never disabled in this QP port, therefore -* they can always preempt any code, including the IRQ-handlers (ISRs). -* Therefore, FIQ-type interrupts are "kernel-unaware" and must NEVER call -* any QP services, such as posting events. -* -* NOTE01: -* The QV_onIdle() callback is called with interrupts disabled, because the -* determination of the idle condition might change by any interrupt posting -* an event. QV_onIdle() must internally enable interrupts, ideally -* atomically with putting the CPU to the power-saving mode. -* -* NOTE02: -* One of the LEDs is used to visualize the idle loop activity. The brightness -* of the LED is proportional to the frequency of invcations of the idle loop. -* Please note that the LED is toggled with interrupts locked, so no interrupt -* execution time contributes to the brightness of the User LED. -*/ +//============================================================================ +// NOTE00: +// The FIQ-type interrupts are never disabled in this QP port, therefore +// they can always preempt any code, including the IRQ-handlers (ISRs). +// Therefore, FIQ-type interrupts are "kernel-unaware" and must NEVER call +// any QP services, such as posting events. +// +// NOTE01: +// The QV_onIdle() callback is called with interrupts disabled, because the +// determination of the idle condition might change by any interrupt posting +// an event. QV_onIdle() must internally enable interrupts, ideally +// atomically with putting the CPU to the power-saving mode. +// +// NOTE02: +// One of the LEDs is used to visualize the idle loop activity. The brightness +// of the LED is proportional to the frequency of invcations of the idle loop. +// Please note that the LED is toggled with interrupts locked, so no interrupt +// execution time contributes to the brightness of the User LED. +// diff --git a/examples/arm-cr/blinky_launchxl2-tms57012/qv/iar/blinky-qv.ewd b/examples/arm-cr/blinky_launchxl2-tms57012/qv/iar/blinky-qv.ewd index 55042ab7..05b9e883 100644 --- a/examples/arm-cr/blinky_launchxl2-tms57012/qv/iar/blinky-qv.ewd +++ b/examples/arm-cr/blinky_launchxl2-tms57012/qv/iar/blinky-qv.ewd @@ -1,4900 +1,4654 @@ - - + - 2 - - Debug - - ARM - - 1 - - C-SPY - 2 - - 28 - 1 + 3 + + Debug + + ARM + 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ARMSIM_ID - 2 - - 1 - 1 - 1 - - - - - - - - ANGEL_ID - 2 - - 0 - 1 - 1 - - - - - - - - - - - - CADI_ID - 2 - - 0 - 1 - 1 - - - - - - - - - CMSISDAP_ID - 2 - - 4 - 1 - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - GDBSERVER_ID - 2 - - 0 - 1 - 1 - - - - - - - - - - - IARROM_ID - 2 - - 1 - 1 - 1 - - - - - - - - - IJET_ID - 2 - - 8 - 1 - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - JLINK_ID - 2 - - 16 - 1 - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - LMIFTDI_ID - 2 - - 2 - 1 - 1 - - - - - - - - - - MACRAIGOR_ID - 2 - - 3 - 1 - 1 - - - - - - - - - - - - - - - - - - - - - - - PEMICRO_ID - 2 - - 3 - 1 - 1 - - - - - - - - RDI_ID - 2 - - 2 - 1 - 1 - - - - - - - - - - - - - - - - STLINK_ID - 2 - - 3 - 1 - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - THIRDPARTY_ID - 2 - - 0 - 1 - 1 - - - - - - - - TIFET_ID - 2 - - 1 - 1 - 1 - - - - - - - - - - - - - - - - - - - XDS100_ID - 2 - - 5 - 1 - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - $TOOLKIT_DIR$\plugins\middleware\HCCWare\HCCWare.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\middleware\PercepioTraceExporter\PercepioTraceExportPlugin.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\AVIX\AVIX.ENU.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\CMX\CmxArmPlugin.ENU.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\CMX\CmxTinyArmPlugin.ENU.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\MQX\MQXRtosPlugin.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\Quadros\Quadros_EWB7_Plugin.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\SafeRTOS\SafeRTOSPlugin.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\TI-RTOS\tirtosplugin.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-286-KA-CSpy.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-KA-CSpy.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\uCOS-III\uCOS-III-KA-CSpy.ewplugin - 0 - - - $EW_DIR$\common\plugins\CodeCoverage\CodeCoverage.ENU.ewplugin - 1 - - - $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin - 0 - - - $EW_DIR$\common\plugins\uCProbe\uCProbePlugin.ENU.ewplugin - 0 - - - - - Release - - ARM - - 0 - - C-SPY - 2 - - 28 - 1 + + C-SPY + 2 + + 32 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ARMSIM_ID + 2 + + 1 + 1 + 1 + + + + + + + + CADI_ID + 2 + + 0 + 1 + 1 + + + + + + + + + CMSISDAP_ID + 2 + + 4 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + GDBSERVER_ID + 2 + + 0 + 1 + 1 + + + + + + + + + + + IJET_ID + 2 + + 9 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + JLINK_ID + 2 + + 16 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + LMIFTDI_ID + 2 + + 3 + 1 + 1 + + + + + + + + + + + + + NULINK_ID + 2 + + 0 + 1 + 1 + + + + + + + PEMICRO_ID + 2 + + 3 + 1 + 1 + + + + + + + + STLINK_ID + 2 + + 8 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + THIRDPARTY_ID + 2 + + 0 + 1 + 1 + + + + + + + + TIFET_ID + 2 + + 1 + 1 + 1 + + + + + + + + + + + + + + + + + + + XDS100_ID + 2 + + 9 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + $TOOLKIT_DIR$\plugins\rtos\CMX\CmxArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\CMX\CmxTinyArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\FreeRtos\FreeRtosArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin2.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SafeRTOS\SafeRTOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9BE.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-286-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-III\uCOS-III-KA-CSpy.ewplugin + 0 + + + $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\TargetAccessServer\TargetAccessServer.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\uCProbe\uCProbePlugin.ENU.ewplugin + 0 + + + + + Release + + ARM + 0 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ARMSIM_ID - 2 - - 1 - 1 - 0 - - - - - - - - ANGEL_ID - 2 - - 0 - 1 - 0 - - - - - - - - - - - - CADI_ID - 2 - - 0 - 1 - 0 - - - - - - - - - CMSISDAP_ID - 2 - - 4 - 1 - 0 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - GDBSERVER_ID - 2 - - 0 - 1 - 0 - - - - - - - - - - - IARROM_ID - 2 - - 1 - 1 - 0 - - - - - - - - - IJET_ID - 2 - - 8 - 1 - 0 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - JLINK_ID - 2 - - 16 - 1 - 0 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - LMIFTDI_ID - 2 - - 2 - 1 - 0 - - - - - - - - - - MACRAIGOR_ID - 2 - - 3 - 1 - 0 - - - - - - - - - - - - - - - - - - - - - - - PEMICRO_ID - 2 - - 3 - 1 - 0 - - - - - - - - RDI_ID - 2 - - 2 - 1 - 0 - - - - - - - - - - - - - - - - STLINK_ID - 2 - - 3 - 1 - 0 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - THIRDPARTY_ID - 2 - - 0 - 1 - 0 - - - - - - - - TIFET_ID - 2 - - 1 - 1 - 0 - - - - - - - - - - - - - - - - - - - XDS100_ID - 2 - - 5 - 1 - 0 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - $TOOLKIT_DIR$\plugins\middleware\HCCWare\HCCWare.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\middleware\PercepioTraceExporter\PercepioTraceExportPlugin.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\AVIX\AVIX.ENU.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\CMX\CmxArmPlugin.ENU.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\CMX\CmxTinyArmPlugin.ENU.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\MQX\MQXRtosPlugin.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\Quadros\Quadros_EWB7_Plugin.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\SafeRTOS\SafeRTOSPlugin.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\TI-RTOS\tirtosplugin.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-286-KA-CSpy.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-KA-CSpy.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\uCOS-III\uCOS-III-KA-CSpy.ewplugin - 0 - - - $EW_DIR$\common\plugins\CodeCoverage\CodeCoverage.ENU.ewplugin - 1 - - - $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin - 0 - - - $EW_DIR$\common\plugins\uCProbe\uCProbePlugin.ENU.ewplugin - 0 - - - - - Spy - - ARM - - 1 - - C-SPY - 2 - - 28 - 1 + + C-SPY + 2 + + 32 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ARMSIM_ID + 2 + + 1 + 1 + 0 + + + + + + + + CADI_ID + 2 + + 0 + 1 + 0 + + + + + + + + + CMSISDAP_ID + 2 + + 4 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + GDBSERVER_ID + 2 + + 0 + 1 + 0 + + + + + + + + + + + IJET_ID + 2 + + 9 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + JLINK_ID + 2 + + 16 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + LMIFTDI_ID + 2 + + 3 + 1 + 0 + + + + + + + + + + + + + NULINK_ID + 2 + + 0 + 1 + 0 + + + + + + + PEMICRO_ID + 2 + + 3 + 1 + 0 + + + + + + + + STLINK_ID + 2 + + 8 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + THIRDPARTY_ID + 2 + + 0 + 1 + 0 + + + + + + + + TIFET_ID + 2 + + 1 + 1 + 0 + + + + + + + + + + + + + + + + + + + XDS100_ID + 2 + + 9 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + $TOOLKIT_DIR$\plugins\rtos\CMX\CmxArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\CMX\CmxTinyArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\FreeRtos\FreeRtosArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin2.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SafeRTOS\SafeRTOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9BE.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-286-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-III\uCOS-III-KA-CSpy.ewplugin + 0 + + + $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\TargetAccessServer\TargetAccessServer.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\uCProbe\uCProbePlugin.ENU.ewplugin + 0 + + + + + Spy + + ARM + 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ARMSIM_ID - 2 - - 1 - 1 - 1 - - - - - - - - ANGEL_ID - 2 - - 0 - 1 - 1 - - - - - - - - - - - - CADI_ID - 2 - - 0 - 1 - 1 - - - - - - - - - CMSISDAP_ID - 2 - - 4 - 1 - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - GDBSERVER_ID - 2 - - 0 - 1 - 1 - - - - - - - - - - - IARROM_ID - 2 - - 1 - 1 - 1 - - - - - - - - - IJET_ID - 2 - - 8 - 1 - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - JLINK_ID - 2 - - 16 - 1 - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - LMIFTDI_ID - 2 - - 2 - 1 - 1 - - - - - - - - - - MACRAIGOR_ID - 2 - - 3 - 1 - 1 - - - - - - - - - - - - - - - - - - - - - - - PEMICRO_ID - 2 - - 3 - 1 - 1 - - - - - - - - RDI_ID - 2 - - 2 - 1 - 1 - - - - - - - - - - - - - - - - STLINK_ID - 2 - - 3 - 1 - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - THIRDPARTY_ID - 2 - - 0 - 1 - 1 - - - - - - - - TIFET_ID - 2 - - 1 - 1 - 1 - - - - - - - - - - - - - - - - - - - XDS100_ID - 2 - - 5 - 1 - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - $TOOLKIT_DIR$\plugins\middleware\HCCWare\HCCWare.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\middleware\PercepioTraceExporter\PercepioTraceExportPlugin.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\AVIX\AVIX.ENU.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\CMX\CmxArmPlugin.ENU.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\CMX\CmxTinyArmPlugin.ENU.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\MQX\MQXRtosPlugin.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\Quadros\Quadros_EWB7_Plugin.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\SafeRTOS\SafeRTOSPlugin.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\TI-RTOS\tirtosplugin.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-286-KA-CSpy.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-KA-CSpy.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\uCOS-III\uCOS-III-KA-CSpy.ewplugin - 0 - - - $EW_DIR$\common\plugins\CodeCoverage\CodeCoverage.ENU.ewplugin - 1 - - - $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin - 0 - - - $EW_DIR$\common\plugins\uCProbe\uCProbePlugin.ENU.ewplugin - 0 - - - + + C-SPY + 2 + + 32 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ARMSIM_ID + 2 + + 1 + 1 + 1 + + + + + + + + CADI_ID + 2 + + 0 + 1 + 1 + + + + + + + + + CMSISDAP_ID + 2 + + 4 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + GDBSERVER_ID + 2 + + 0 + 1 + 1 + + + + + + + + + + + IJET_ID + 2 + + 9 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + JLINK_ID + 2 + + 16 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + LMIFTDI_ID + 2 + + 3 + 1 + 1 + + + + + + + + + + + + + NULINK_ID + 2 + + 0 + 1 + 1 + + + + + + + PEMICRO_ID + 2 + + 3 + 1 + 1 + + + + + + + + STLINK_ID + 2 + + 8 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + THIRDPARTY_ID + 2 + + 0 + 1 + 1 + + + + + + + + TIFET_ID + 2 + + 1 + 1 + 1 + + + + + + + + + + + + + + + + + + + XDS100_ID + 2 + + 9 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + $TOOLKIT_DIR$\plugins\rtos\CMX\CmxArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\CMX\CmxTinyArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\FreeRtos\FreeRtosArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin2.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SafeRTOS\SafeRTOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9BE.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-286-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-III\uCOS-III-KA-CSpy.ewplugin + 0 + + + $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\TargetAccessServer\TargetAccessServer.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\uCProbe\uCProbePlugin.ENU.ewplugin + 0 + + + - - diff --git a/examples/arm-cr/blinky_launchxl2-tms57012/qv/iar/blinky-qv.ewp b/examples/arm-cr/blinky_launchxl2-tms57012/qv/iar/blinky-qv.ewp index 71e99e47..9207aedb 100644 --- a/examples/arm-cr/blinky_launchxl2-tms57012/qv/iar/blinky-qv.ewp +++ b/examples/arm-cr/blinky_launchxl2-tms57012/qv/iar/blinky-qv.ewp @@ -1,3071 +1,3401 @@ - - + - 2 - - Debug - - ARM - - 1 - - General - 3 - - 24 - 1 + 3 + + Debug + + ARM + 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ICCARM - 2 - - 31 - 1 - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - AARM - 2 - - 9 - 1 - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - OBJCOPY - 0 - - 1 - 1 - 1 - - - - - - - - - CUSTOM - 3 - - - - 0 - - - - BICOMP - 0 - - - - BUILDACTION - 1 - - cmd /c "if exist $OBJ_DIR$\qstamp.o del $OBJ_DIR$\qstamp.o" - - - - - ILINK - 0 - - 17 - 1 - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - IARCHIVE - 0 - - 0 - 1 - 1 - - - - - - - BILINK - 0 - - - - Coder - 0 - - - - - Release - - ARM - - 0 - - General - 3 - - 24 - 1 + + General + 3 + + 35 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ICCARM + 2 + + 37 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + AARM + 2 + + 11 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + OBJCOPY + 0 + + 1 + 1 + 1 + + + + + + + + + CUSTOM + 3 + + + + 0 + inputOutputBased + + + + BUILDACTION + 1 + + cmd /c "if exist $OBJ_DIR$\qstamp.o del $OBJ_DIR$\qstamp.o" + + + + + ILINK + 0 + + 27 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + IARCHIVE + 0 + + 0 + 1 + 1 + + + + + + + Coder + 0 + + + + + Release + + ARM + 0 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ICCARM - 2 - - 31 - 1 - 0 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - AARM - 2 - - 9 - 1 - 0 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - OBJCOPY - 0 - - 1 - 1 - 0 - - - - - - - - - CUSTOM - 3 - - - - 0 - - - - BICOMP - 0 - - - - BUILDACTION - 1 - - cmd /c "if exist $OBJ_DIR$\qstamp.o del $OBJ_DIR$\qstamp.o" - - - - - ILINK - 0 - - 17 - 1 - 0 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - IARCHIVE - 0 - - 0 - 1 - 0 - - - - - - - BILINK - 0 - - - - Coder - 0 - - - - - Spy - - ARM - - 1 - - General - 3 - - 24 - 1 + + General + 3 + + 35 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ICCARM + 2 + + 37 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + AARM + 2 + + 11 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + OBJCOPY + 0 + + 1 + 1 + 0 + + + + + + + + + CUSTOM + 3 + + + + 0 + inputOutputBased + + + + BUILDACTION + 1 + + cmd /c "if exist $OBJ_DIR$\qstamp.o del $OBJ_DIR$\qstamp.o" + + + + + ILINK + 0 + + 27 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + IARCHIVE + 0 + + 0 + 1 + 0 + + + + + + + Coder + 0 + + + + + Spy + + ARM + 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ICCARM - 2 - - 31 - 1 - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - AARM - 2 - - 9 - 1 - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - OBJCOPY - 0 - - 1 - 1 - 1 - - - - - - - - - CUSTOM - 3 - - - - 0 - - - - BICOMP - 0 - - - - BUILDACTION - 1 - - cmd /c "if exist $OBJ_DIR$\qstamp.o del $OBJ_DIR$\qstamp.o" - - - - - ILINK - 0 - - 17 - 1 - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - IARCHIVE - 0 - - 0 - 1 - 1 - - - - - - - BILINK - 0 - - - - Coder - 0 - - - - - Application - - $PROJ_DIR$\..\..\blinky.c - - - $PROJ_DIR$\..\..\blinky.h - - - $PROJ_DIR$\..\bsp.c - - - $PROJ_DIR$\..\..\bsp.h - - - $PROJ_DIR$\..\..\main.c - - - $PROJ_DIR$\..\..\..\..\..\include\qstamp.c - - - - launchxl2-tms57012 - - $PROJ_DIR$\..\..\..\..\..\3rd_party\launchxl2-tms57012\iar\source\dabort.asm - - - $PROJ_DIR$\..\..\..\..\..\3rd_party\launchxl2-tms57012\iar\source\esm.c - - - $PROJ_DIR$\..\..\..\..\..\3rd_party\launchxl2-tms57012\iar\source\exceptions.c - - - $PROJ_DIR$\..\..\..\..\..\3rd_party\launchxl2-tms57012\iar\source\gio.c - - - $PROJ_DIR$\..\..\..\..\..\3rd_party\launchxl2-tms57012\iar\source\notification.c - - - $PROJ_DIR$\..\..\..\..\..\3rd_party\launchxl2-tms57012\iar\source\pinmux.c - - - $PROJ_DIR$\..\..\..\..\..\3rd_party\launchxl2-tms57012\iar\source\rti.c - - - $PROJ_DIR$\..\..\..\..\..\3rd_party\launchxl2-tms57012\iar\source\sci.c - - - $PROJ_DIR$\..\..\..\..\..\3rd_party\launchxl2-tms57012\iar\source\sys_core.asm - - - $PROJ_DIR$\..\..\..\..\..\3rd_party\launchxl2-tms57012\iar\source\sys_intvecs.asm - - - $PROJ_DIR$\..\..\..\..\..\3rd_party\launchxl2-tms57012\iar\source\sys_mpu.asm - - - $PROJ_DIR$\..\..\..\..\..\3rd_party\launchxl2-tms57012\iar\source\sys_pcr.c - - - $PROJ_DIR$\..\..\..\..\..\3rd_party\launchxl2-tms57012\iar\source\sys_phantom.c - - - $PROJ_DIR$\..\..\..\..\..\3rd_party\launchxl2-tms57012\iar\source\sys_pmm.c - - - $PROJ_DIR$\..\..\..\..\..\3rd_party\launchxl2-tms57012\iar\source\sys_pmu.asm - - - $PROJ_DIR$\..\..\..\..\..\3rd_party\launchxl2-tms57012\iar\source\sys_selftest.c - - - $PROJ_DIR$\..\..\..\..\..\3rd_party\launchxl2-tms57012\iar\source\sys_startup.c - - - $PROJ_DIR$\..\..\..\..\..\3rd_party\launchxl2-tms57012\iar\source\sys_vim.c - - - $PROJ_DIR$\..\..\..\..\..\3rd_party\launchxl2-tms57012\iar\source\system.c - - - - QP - - $PROJ_DIR$\..\..\..\..\..\src\qf\qep_hsm.c - - - $PROJ_DIR$\..\..\..\..\..\src\qf\qep_msm.c - - - $PROJ_DIR$\..\..\..\..\..\src\qf\qf_act.c - - - $PROJ_DIR$\..\..\..\..\..\src\qf\qf_actq.c - - - $PROJ_DIR$\..\..\..\..\..\src\qf\qf_defer.c - - - $PROJ_DIR$\..\..\..\..\..\src\qf\qf_dyn.c - - - $PROJ_DIR$\..\..\..\..\..\src\qf\qf_mem.c - - - $PROJ_DIR$\..\..\..\..\..\src\qf_pkg.h - - - $PROJ_DIR$\..\..\..\..\..\src\qf\qf_ps.c - - - $PROJ_DIR$\..\..\..\..\..\src\qf\qf_qact.c - - - $PROJ_DIR$\..\..\..\..\..\src\qf\qf_qeq.c - - - $PROJ_DIR$\..\..\..\..\..\src\qf\qf_qmact.c - - - $PROJ_DIR$\..\..\..\..\..\src\qf\qf_time.c - - - $PROJ_DIR$\..\..\..\..\..\src\qv\qv.c - - - - QP_port - - $PROJ_DIR$\..\..\..\..\..\ports\arm-cr\qv\iar\qep_port.h - - - $PROJ_DIR$\..\..\..\..\..\ports\arm-cr\qv\iar\qf_port.h - - - $PROJ_DIR$\..\..\..\..\..\ports\arm-cr\qv\iar\qs_port.h - - - $PROJ_DIR$\..\..\..\..\..\ports\arm-cr\qv\iar\qv_port.h - - - - QS - - Debug - Release - - - $PROJ_DIR$\..\..\..\..\..\src\qs\qs.c - - - $PROJ_DIR$\..\..\..\..\..\src\qs\qs_fp.c - - - $PROJ_DIR$\..\..\..\..\..\src\qs_pkg.h - - - $PROJ_DIR$\..\..\..\..\..\src\qs\qs_rx.c - - + + General + 3 + + 35 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ICCARM + 2 + + 37 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + AARM + 2 + + 11 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + OBJCOPY + 0 + + 1 + 1 + 1 + + + + + + + + + CUSTOM + 3 + + + + 0 + inputOutputBased + + + + BUILDACTION + 1 + + cmd /c "if exist $OBJ_DIR$\qstamp.o del $OBJ_DIR$\qstamp.o" + + + + + ILINK + 0 + + 27 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + IARCHIVE + 0 + + 0 + 1 + 1 + + + + + + + Coder + 0 + + + + + Application + + $PROJ_DIR$\..\..\blinky.c + + + $PROJ_DIR$\..\..\blinky.h + + + $PROJ_DIR$\..\bsp.c + + + $PROJ_DIR$\..\..\bsp.h + + + $PROJ_DIR$\..\..\main.c + + + + launchxl2-tms57012 + + $PROJ_DIR$\..\..\..\..\..\3rd_party\launchxl2-tms57012\iar\source\dabort.asm + + + $PROJ_DIR$\..\..\..\..\..\3rd_party\launchxl2-tms57012\iar\source\esm.c + + + $PROJ_DIR$\..\..\..\..\..\3rd_party\launchxl2-tms57012\iar\source\exceptions.c + + + $PROJ_DIR$\..\..\..\..\..\3rd_party\launchxl2-tms57012\iar\source\gio.c + + + $PROJ_DIR$\..\..\..\..\..\3rd_party\launchxl2-tms57012\iar\source\notification.c + + + $PROJ_DIR$\..\..\..\..\..\3rd_party\launchxl2-tms57012\iar\source\pinmux.c + + + $PROJ_DIR$\..\..\..\..\..\3rd_party\launchxl2-tms57012\iar\source\rti.c + + + $PROJ_DIR$\..\..\..\..\..\3rd_party\launchxl2-tms57012\iar\source\sci.c + + + $PROJ_DIR$\..\..\..\..\..\3rd_party\launchxl2-tms57012\iar\source\sys_core.asm + + + $PROJ_DIR$\..\..\..\..\..\3rd_party\launchxl2-tms57012\iar\source\sys_intvecs.asm + + + $PROJ_DIR$\..\..\..\..\..\3rd_party\launchxl2-tms57012\iar\source\sys_mpu.asm + + + $PROJ_DIR$\..\..\..\..\..\3rd_party\launchxl2-tms57012\iar\source\sys_pcr.c + + + $PROJ_DIR$\..\..\..\..\..\3rd_party\launchxl2-tms57012\iar\source\sys_phantom.c + + + $PROJ_DIR$\..\..\..\..\..\3rd_party\launchxl2-tms57012\iar\source\sys_pmm.c + + + $PROJ_DIR$\..\..\..\..\..\3rd_party\launchxl2-tms57012\iar\source\sys_pmu.asm + + + $PROJ_DIR$\..\..\..\..\..\3rd_party\launchxl2-tms57012\iar\source\sys_selftest.c + + + $PROJ_DIR$\..\..\..\..\..\3rd_party\launchxl2-tms57012\iar\source\sys_startup.c + + + $PROJ_DIR$\..\..\..\..\..\3rd_party\launchxl2-tms57012\iar\source\sys_vim.c + + + $PROJ_DIR$\..\..\..\..\..\3rd_party\launchxl2-tms57012\iar\source\system.c + + + + QP + + $PROJ_DIR$\..\..\..\..\..\src\qf\qep_hsm.c + + + $PROJ_DIR$\..\..\..\..\..\src\qf\qep_msm.c + + + $PROJ_DIR$\..\..\..\..\..\src\qf\qf_act.c + + + $PROJ_DIR$\..\..\..\..\..\src\qf\qf_actq.c + + + $PROJ_DIR$\..\..\..\..\..\src\qf\qf_defer.c + + + $PROJ_DIR$\..\..\..\..\..\src\qf\qf_dyn.c + + + $PROJ_DIR$\..\..\..\..\..\src\qf\qf_mem.c + + + $PROJ_DIR$\..\..\..\..\..\src\qf_pkg.h + + + $PROJ_DIR$\..\..\..\..\..\src\qf\qf_ps.c + + + $PROJ_DIR$\..\..\..\..\..\src\qf\qf_qact.c + + + $PROJ_DIR$\..\..\..\..\..\src\qf\qf_qeq.c + + + $PROJ_DIR$\..\..\..\..\..\src\qf\qf_qmact.c + + + $PROJ_DIR$\..\..\..\..\..\src\qf\qf_time.c + + + $PROJ_DIR$\..\..\..\..\..\src\qv\qv.c + + + + QP_port + + $PROJ_DIR$\..\..\..\..\..\ports\arm-cr\qv\iar\qep_port.h + + + $PROJ_DIR$\..\..\..\..\..\ports\arm-cr\qv\iar\qf_port.h + + + $PROJ_DIR$\..\..\..\..\..\ports\arm-cr\qv\iar\qs_port.h + + + $PROJ_DIR$\..\..\..\..\..\ports\arm-cr\qv\iar\qv_port.h + + + + QS + + Debug + Release + + + $PROJ_DIR$\..\..\..\..\..\src\qs\qs.c + + + $PROJ_DIR$\..\..\..\..\..\src\qs\qs_fp.c + + + $PROJ_DIR$\..\..\..\..\..\src\qs_pkg.h + + + $PROJ_DIR$\..\..\..\..\..\src\qs\qs_rx.c + + + $PROJ_DIR$\..\..\..\..\..\src\qs\qstamp.c + + - - diff --git a/examples/arm-cr/dpp_launchxl2-tms57012/bsp.h b/examples/arm-cr/dpp_launchxl2-tms57012/bsp.h index a31e759f..da73dbfd 100644 --- a/examples/arm-cr/dpp_launchxl2-tms57012/bsp.h +++ b/examples/arm-cr/dpp_launchxl2-tms57012/bsp.h @@ -1,52 +1,49 @@ -/***************************************************************************** -* Product: DPP example -* Last Updated for Version: 5.6.4 -* Date of the Last Update: 2016-05-09 -* -* Q u a n t u m L e a P s -* --------------------------- -* innovating embedded systems -* -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* -* -*****************************************************************************/ -#ifndef BSP_H -#define BSP_H +//============================================================================ +// Product: Board Support Package example +// Last Updated for Version: 7.3.0 +// Date of the Last Update: 2023-08-12 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +//============================================================================ +#ifndef BSP_H_ +#define BSP_H_ #define BSP_TICKS_PER_SEC 100U void BSP_init(void); +void BSP_start(void); void BSP_displayPaused(uint8_t paused); void BSP_displayPhilStat(uint8_t n, char const *stat); void BSP_terminate(int16_t result); -void BSP_randomSeed(uint32_t seed); /* random seed */ -uint32_t BSP_random(void); /* pseudo-random generator */ +void BSP_randomSeed(uint32_t seed); // random seed +uint32_t BSP_random(void); // pseudo-random generator -/* for testing... */ -void BSP_wait4PB1(void); void BSP_ledOn(void); void BSP_ledOff(void); -#endif /* BSP_H */ +#endif // BSP_H_ diff --git a/examples/arm-cr/dpp_launchxl2-tms57012/dpp.h b/examples/arm-cr/dpp_launchxl2-tms57012/dpp.h index da094c2c..e6d1557a 100644 --- a/examples/arm-cr/dpp_launchxl2-tms57012/dpp.h +++ b/examples/arm-cr/dpp_launchxl2-tms57012/dpp.h @@ -1,92 +1,117 @@ -/*$file${.::dpp.h} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* -* Model: dpp.qm -* File: ${.::dpp.h} -* -* This code has been generated by QM 5.2.4 . -* DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. -* -* SPDX-License-Identifier: GPL-3.0-or-later -* -* This generated code is open source software: you can redistribute it under -* the terms of the GNU General Public License as published by the Free -* Software Foundation. -* -* This code is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -* more details. -* -* NOTE: -* Alternatively, this generated code may be distributed under the terms -* of Quantum Leaps commercial licenses, which expressly supersede the GNU -* General Public License and are specifically designed for licensees -* interested in retaining the proprietary status of their code. -* -* Contact information: -* -* -*/ -/*$endhead${.::dpp.h} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -#ifndef DPP_H -#define DPP_H +//$file${.::dpp.h} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// +// Model: dpp.qm +// File: ${.::dpp.h} +// +// This code has been generated by QM 5.3.0 . +// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. +// +// SPDX-License-Identifier: GPL-3.0-or-later +// +// This generated code is open source software: you can redistribute it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation. +// +// This code is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// NOTE: +// Alternatively, this generated code may be distributed under the terms +// of Quantum Leaps commercial licenses, which expressly supersede the GNU +// General Public License and are specifically designed for licensees +// interested in retaining the proprietary status of their code. +// +// Contact information: +// +// +// +//$endhead${.::dpp.h} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +#ifndef DPP_H_ +#define DPP_H_ -enum DPPSignals { - EAT_SIG = Q_USER_SIG, /* published by Table to let a philosopher eat */ - DONE_SIG, /* published by Philosopher when done eating */ - PAUSE_SIG, /* published by BSP to pause serving forks */ - SERVE_SIG, /* published by BSP to serve re-start serving forks */ - TEST_SIG, /* published by BSP to test the application */ - MAX_PUB_SIG, /* the last published signal */ +//$declare${Shared} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv - HUNGRY_SIG, /* posted direclty to Table from hungry Philo */ - TIMEOUT_SIG, /* used by Philosophers for time events */ - MAX_SIG /* the last signal */ +//${Shared::AppSignals} ...................................................... +enum AppSignals { + EAT_SIG = Q_USER_SIG, // published by Table to let a Philo eat + DONE_SIG, // published by Philo when done eating + PAUSE_SIG, // published by BSP to pause the application + SERVE_SIG, // published by BSP to serve re-start serving forks + TEST_SIG, // published by BSP to test the application + MAX_PUB_SIG, // the last published signal + + TIMEOUT_SIG, // posted by time event to Philo + HUNGRY_SIG, // posted by hungry Philo to Table + MAX_SIG // the last signal }; -/*$declare${Events::TableEvt} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//${Shared::produce_sig_dict} ................................................ +#ifdef Q_SPY +static inline void produce_sig_dict(void) { + QS_SIG_DICTIONARY(EAT_SIG, (void *)0); + QS_SIG_DICTIONARY(DONE_SIG, (void *)0); + QS_SIG_DICTIONARY(PAUSE_SIG, (void *)0); + QS_SIG_DICTIONARY(SERVE_SIG, (void *)0); + QS_SIG_DICTIONARY(TEST_SIG, (void *)0); -/*${Events::TableEvt} ......................................................*/ + QS_SIG_DICTIONARY(TIMEOUT_SIG, (void *)0); + QS_SIG_DICTIONARY(HUNGRY_SIG, (void *)0); +} +#endif // def Q_SPY + +//${Shared::N_PHILO} ......................................................... +#define N_PHILO ((uint8_t)5U) + +//${Shared::TableEvt} ........................................................ typedef struct { -/* protected: */ +// protected: QEvt super; -/* public: */ - uint8_t philoNum; +// public: + uint8_t philoId; } TableEvt; -/*$enddecl${Events::TableEvt} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/* number of philosophers */ -#define N_PHILO ((uint8_t)5) +// public: -/*$declare${AOs::Philo_ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +#ifdef QEVT_DYN_CTOR +static inline TableEvt * TableEvt_ctor(TableEvt * const me, + uint8_t id) +{ + if (me != (TableEvt *)0) { + // don't call QEvt_ctor() because the initialization of all + // QEvt attributes is already done in QF_QF_newX_() + me->philoId = id; + } + return me; +} +#endif // def QEVT_DYN_CTOR -/*${AOs::Philo_ctor} .......................................................*/ -void Philo_ctor(void); -/*$enddecl${AOs::Philo_ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*$declare${AOs::AO_Philo[N_PHILO]} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${AOs::AO_Philo[N_PHILO]} ................................................*/ +//${Shared::AO_Philo[N_PHILO]} ............................................... extern QActive * const AO_Philo[N_PHILO]; -/*$enddecl${AOs::AO_Philo[N_PHILO]} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*$declare${AOs::Table_ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//${Shared::Philo_ctor} ...................................................... +void Philo_ctor(uint_fast8_t const id); -/*${AOs::Table_ctor} .......................................................*/ -void Table_ctor(void); -/*$enddecl${AOs::Table_ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*$declare${AOs::AO_Table} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${AOs::AO_Table} .........................................................*/ +//${Shared::AO_Table} ........................................................ extern QActive * const AO_Table; -/*$enddecl${AOs::AO_Table} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -#ifdef QP_INC_QXK_H_ - void Test1_ctor(void); - extern QXThread * const XT_Test1; - void Test2_ctor(void); - extern QXThread * const XT_Test2; -#endif /* QP_INC_QXK_H_ */ +//${Shared::Table_ctor} ...................................................... +void Table_ctor(void); +//$enddecl${Shared} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -#endif /* DPP_H */ +#ifdef QXK_H_ +extern QXThread * const TH_XThread1; +void XThread1_ctor(void); + +extern QXThread * const TH_XThread2; +void XThread2_ctor(void); + +extern QXSemaphore TH_sema; +extern QXMutex TH_mutex; + +#endif // QXK_H_ + +#endif // DPP_H_ diff --git a/examples/arm-cr/dpp_launchxl2-tms57012/dpp.qm b/examples/arm-cr/dpp_launchxl2-tms57012/dpp.qm index f1256b39..ac9f2bc9 100644 --- a/examples/arm-cr/dpp_launchxl2-tms57012/dpp.qm +++ b/examples/arm-cr/dpp_launchxl2-tms57012/dpp.qm @@ -1,185 +1,242 @@ - + Dining Philosopher Problem example - - - + + + + + { + EAT_SIG = Q_USER_SIG, // published by Table to let a Philo eat + DONE_SIG, // published by Philo when done eating + PAUSE_SIG, // published by BSP to pause the application + SERVE_SIG, // published by BSP to serve re-start serving forks + TEST_SIG, // published by BSP to test the application + MAX_PUB_SIG, // the last published signal + + TIMEOUT_SIG, // posted by time event to Philo + HUNGRY_SIG, // posted by hungry Philo to Table + MAX_SIG // the last signal +}; + + + + QS_SIG_DICTIONARY(EAT_SIG, (void *)0); +QS_SIG_DICTIONARY(DONE_SIG, (void *)0); +QS_SIG_DICTIONARY(PAUSE_SIG, (void *)0); +QS_SIG_DICTIONARY(SERVE_SIG, (void *)0); +QS_SIG_DICTIONARY(TEST_SIG, (void *)0); + +QS_SIG_DICTIONARY(TIMEOUT_SIG, (void *)0); +QS_SIG_DICTIONARY(HUNGRY_SIG, (void *)0); + + + + ((uint8_t)5U) + + - - + + + + + + + if (me != (TableEvt *)0) { + // don't call QEvt_ctor() because the initialization of all + // QEvt attributes is already done in QF_QF_newX_() + me->philoId = id; +} +return me; + + + + = { + &Philo_inst[0].super, + &Philo_inst[1].super, + &Philo_inst[2].super, + &Philo_inst[3].super, + &Philo_inst[4].super +}; + + + + + + Philo * const me = &Philo_inst[id]; +QActive_ctor(&me->super, Q_STATE_CAST(&Philo_initial)); +QTimeEvt_ctorX(&me->timeEvt, &me->super, TIMEOUT_SIG, 0U), +me->id = (uint8_t)id; + + + + = &Table_inst.super; + + + + Table * const me = &Table_inst; +QActive_ctor(&me->super, Q_STATE_CAST(&Table_initial)); +for (uint8_t n = 0U; n < N_PHILO; ++n) { + me->fork[n] = FREE; + me->isHungry[n] = false; +} + - - - The array of static insts of the Philo class (Singleton pattern) - + The Philo AO and the N_PHILO instances + + + + - + - static uint8_t registered = (uint8_t)0; /* starts off with 0, per C-standard */ -(void)par; /* unused parameter */ -if (registered == (uint8_t)0) { - registered = (uint8_t)1; + Q_UNUSED_PAR(par); - QS_OBJ_DICTIONARY(&Philo_inst[0]); - QS_OBJ_DICTIONARY(&Philo_inst[0].timeEvt); - QS_OBJ_DICTIONARY(&Philo_inst[1]); - QS_OBJ_DICTIONARY(&Philo_inst[1].timeEvt); - QS_OBJ_DICTIONARY(&Philo_inst[2]); - QS_OBJ_DICTIONARY(&Philo_inst[2].timeEvt); - QS_OBJ_DICTIONARY(&Philo_inst[3]); - QS_OBJ_DICTIONARY(&Philo_inst[3].timeEvt); - QS_OBJ_DICTIONARY(&Philo_inst[4]); - QS_OBJ_DICTIONARY(&Philo_inst[4].timeEvt); - - QS_FUN_DICTIONARY(&Philo_initial); - QS_FUN_DICTIONARY(&Philo_thinking); - QS_FUN_DICTIONARY(&Philo_hungry); - QS_FUN_DICTIONARY(&Philo_eating); -} -QS_SIG_DICTIONARY(HUNGRY_SIG, me); /* signal for each Philos */ -QS_SIG_DICTIONARY(TIMEOUT_SIG, me); /* signal for each Philos */ +QS_OBJ_ARR_DICTIONARY(&Philo_inst[me->id], me->id); +QS_OBJ_ARR_DICTIONARY(&Philo_inst[me->id].timeEvt, me->id); QActive_subscribe(&me->super, EAT_SIG); QActive_subscribe(&me->super, TEST_SIG); - + - QTimeEvt_armX(&me->timeEvt, THINK_TIME, 0U); - QTimeEvt_disarm(&me->timeEvt); + QTimeEvt_armX(&me->timeEvt, think_time(), 0U); + (void)QTimeEvt_disarm(&me->timeEvt); - - + + - /* EAT or DONE must be for other Philos than this one */ -Q_ASSERT(Q_EVT_CAST(TableEvt)->philoNum != PHILO_ID(me)); - + // EAT or DONE must be for other Philos than this one +Q_ASSERT(Q_EVT_CAST(TableEvt)->philoId != me->id); + - + - + - + - TableEvt *pe = Q_NEW(TableEvt, HUNGRY_SIG); -pe->philoNum = PHILO_ID(me); -QACTIVE_POST(AO_Table, &pe->super, me); + #ifdef QEVT_DYN_CTOR +TableEvt const *pe = Q_NEW(TableEvt, HUNGRY_SIG, me->id); +#else +TableEvt *pe = Q_NEW(TableEvt, HUNGRY_SIG); +pe->philoId = me->id; +#endif +QACTIVE_POST(AO_Table, &pe->super, &me->super); - + - Q_EVT_CAST(TableEvt)->philoNum == PHILO_ID(me) - - + Q_EVT_CAST(TableEvt)->philoId == me->id + + - + - /* DONE must be for other Philos than this one */ -Q_ASSERT(Q_EVT_CAST(TableEvt)->philoNum != PHILO_ID(me)); - + // DONE must be for other Philos than this one +Q_ASSERT(Q_EVT_CAST(TableEvt)->philoId != me->id); + - + - QTimeEvt_armX(&me->timeEvt, EAT_TIME, 0U); - TableEvt *pe = Q_NEW(TableEvt, DONE_SIG); -pe->philoNum = PHILO_ID(me); + QTimeEvt_armX(&me->timeEvt, eat_time(), 0U); + (void)QTimeEvt_disarm(&me->timeEvt); + +#ifdef QEVT_DYN_CTOR +TableEvt const *pe = Q_NEW(TableEvt, DONE_SIG, me->id); +#else +TableEvt *pe = Q_NEW(TableEvt, DONE_SIG); +pe->philoId = me->id; +#endif QACTIVE_PUBLISH(&pe->super, &me->super); - - + + - /* EAT or DONE must be for other Philos than this one */ -Q_ASSERT(Q_EVT_CAST(TableEvt)->philoNum != PHILO_ID(me)); - + // EAT or DONE must be for other Philos than this one +Q_ASSERT(Q_EVT_CAST(TableEvt)->philoId != me->id); + - + - + - - - The only static inst of the Table class (Singleton pattern) - - + + + - + - uint8_t n; -(void)par; /* unused parameter */ + Q_UNUSED_PAR(par); -QS_OBJ_DICTIONARY(&Table_inst); - -QS_SIG_DICTIONARY(DONE_SIG, (void *)0); /* global signals */ -QS_SIG_DICTIONARY(EAT_SIG, (void *)0); -QS_SIG_DICTIONARY(PAUSE_SIG, (void *)0); -QS_SIG_DICTIONARY(SERVE_SIG, (void *)0); -QS_SIG_DICTIONARY(TEST_SIG, (void *)0); - -QS_SIG_DICTIONARY(HUNGRY_SIG, me); /* signal just for Table */ +#ifdef Q_SPY +Table *Table_inst = me; +QS_OBJ_DICTIONARY(Table_inst); +#endif QActive_subscribe(&me->super, DONE_SIG); QActive_subscribe(&me->super, PAUSE_SIG); QActive_subscribe(&me->super, SERVE_SIG); QActive_subscribe(&me->super, TEST_SIG); -for (n = 0U; n < N_PHILO; ++n) { +for (uint8_t n = 0U; n < N_PHILO; ++n) { me->fork[n] = FREE; - me->isHungry[n] = 0U; - BSP_displayPhilStat(n, "thinking"); + me->isHungry[n] = false; + BSP_displayPhilStat(n, THINKING); } - + @@ -187,128 +244,139 @@ for (n = 0U; n < N_PHILO; ++n) { - + Q_ERROR(); - + - uint8_t n; -for (n = 0U; n < N_PHILO; ++n) { /* give permissions to eat... */ - if ((me->isHungry[n] != 0U) - && (me->fork[LEFT(n)] == FREE) + // give permissions to eat... +for (uint8_t n = 0U; n < N_PHILO; ++n) { + if (me->isHungry[n] + && (me->fork[left(n)] == FREE) && (me->fork[n] == FREE)) { - TableEvt *te; - - me->fork[LEFT(n)] = USED; + me->fork[left(n)] = USED; me->fork[n] = USED; - te = Q_NEW(TableEvt, EAT_SIG); - te->philoNum = n; - QACTIVE_PUBLISH(&te->super, &me->super); - me->isHungry[n] = 0U; - BSP_displayPhilStat(n, "eating "); +#ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, EAT_SIG, n); +#else + TableEvt *pe = Q_NEW(TableEvt, EAT_SIG); + pe->philoId = n; +#endif + QACTIVE_PUBLISH(&pe->super, &me->super); + me->isHungry[n] = false; + BSP_displayPhilStat(n, EATING); } } - uint8_t n, m; + uint8_t n = Q_EVT_CAST(TableEvt)->philoId; -n = Q_EVT_CAST(TableEvt)->philoNum; -/* phil ID must be in range and he must be not hungry */ -Q_ASSERT((n < N_PHILO) && (me->isHungry[n] == 0U)); +// phil ID must be in range and he must be not hungry +Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); -BSP_displayPhilStat(n, "hungry "); -m = LEFT(n); +BSP_displayPhilStat(n, HUNGRY); +uint8_t m = left(n); (me->fork[m] == FREE) && (me->fork[n] == FREE) - TableEvt *pe; -me->fork[m] = USED; + me->fork[m] = USED; me->fork[n] = USED; -pe = Q_NEW(TableEvt, EAT_SIG); -pe->philoNum = n; +#ifdef QEVT_DYN_CTOR +TableEvt const *pe = Q_NEW(TableEvt, EAT_SIG, n); +#else +TableEvt *pe = Q_NEW(TableEvt, EAT_SIG); +pe->philoId = n; +#endif QACTIVE_PUBLISH(&pe->super, &me->super); -BSP_displayPhilStat(n, "eating "); - +BSP_displayPhilStat(n, EATING); + else - me->isHungry[n] = 1U; - - + me->isHungry[n] = true; + + - + - uint8_t n, m; -TableEvt *pe; + uint8_t n = Q_EVT_CAST(TableEvt)->philoId; -n = Q_EVT_CAST(TableEvt)->philoNum; -/* phil ID must be in range and he must be not hungry */ -Q_ASSERT((n < N_PHILO) && (me->isHungry[n] == 0U)); +// phil ID must be in range and he must be not hungry +Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); -BSP_displayPhilStat(n, "thinking"); -m = LEFT(n); -/* both forks of Phil[n] must be used */ +BSP_displayPhilStat(n, THINKING); +uint8_t m = left(n); + +// both forks of Phil[n] must be used Q_ASSERT((me->fork[n] == USED) && (me->fork[m] == USED)); me->fork[m] = FREE; me->fork[n] = FREE; -m = RIGHT(n); /* check the right neighbor */ +m = right(n); // check the right neighbor -if ((me->isHungry[m] != 0U) && (me->fork[m] == FREE)) { +if (me->isHungry[m] && (me->fork[m] == FREE)) { me->fork[n] = USED; me->fork[m] = USED; - me->isHungry[m] = 0U; - pe = Q_NEW(TableEvt, EAT_SIG); - pe->philoNum = m; + me->isHungry[m] = false; +#ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, EAT_SIG, m); +#else + TableEvt *pe = Q_NEW(TableEvt, EAT_SIG); + pe->philoId = m; +#endif QACTIVE_PUBLISH(&pe->super, &me->super); - BSP_displayPhilStat(m, "eating "); + BSP_displayPhilStat(m, EATING); } -m = LEFT(n); /* check the left neighbor */ -n = LEFT(m); /* left fork of the left neighbor */ -if ((me->isHungry[m] != 0U) && (me->fork[n] == FREE)) { +m = left(n); // check the left neighbor +n = left(m); // left fork of the left neighbor +if (me->isHungry[m] && (me->fork[n] == FREE)) { me->fork[m] = USED; me->fork[n] = USED; - me->isHungry[m] = 0U; - pe = Q_NEW(TableEvt, EAT_SIG); - pe->philoNum = m; + me->isHungry[m] = false; +#ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, EAT_SIG, m); +#else + TableEvt *pe = Q_NEW(TableEvt, EAT_SIG); + pe->philoId = m; +#endif QACTIVE_PUBLISH(&pe->super, &me->super); - BSP_displayPhilStat(m, "eating "); + BSP_displayPhilStat(m, EATING); } - + Q_ERROR(); - + - + - + @@ -318,170 +386,140 @@ if ((me->isHungry[m] != 0U) && (me->fork[n] == FREE)) { BSP_displayPaused(0U); - + - uint8_t n = Q_EVT_CAST(TableEvt)->philoNum; -/* philo ID must be in range and he must be not hungry */ -Q_ASSERT((n < N_PHILO) && (me->isHungry[n] == 0U)); -me->isHungry[n] = 1U; -BSP_displayPhilStat(n, "hungry "); - + uint8_t n = Q_EVT_CAST(TableEvt)->philoId; + +// philo ID must be in range and he must be not hungry +Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); + +me->isHungry[n] = true; +BSP_displayPhilStat(n, HUNGRY); + - uint8_t n, m; + uint8_t n = Q_EVT_CAST(TableEvt)->philoId; -n = Q_EVT_CAST(TableEvt)->philoNum; -/* phil ID must be in range and he must be not hungry */ -Q_ASSERT((n < N_PHILO) && (me->isHungry[n] == 0U)); +// phil ID must be in range and he must be not hungry +Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); -BSP_displayPhilStat(n, "thinking"); -m = LEFT(n); -/* both forks of Phil[n] must be used */ +BSP_displayPhilStat(n, THINKING); +uint8_t m = left(n); + +// both forks of Phil[n] must be used Q_ASSERT((me->fork[n] == USED) && (me->fork[m] == USED)); me->fork[m] = FREE; me->fork[n] = FREE; - + - + - + - + - - - = { /* "opaque" pointers to Philo AO */ - &Philo_inst[0].super, - &Philo_inst[1].super, - &Philo_inst[2].super, - &Philo_inst[3].super, - &Philo_inst[4].super -}; - - - - = &Table_inst.super; /* "opaque" pointer to Table AO */ - - - - uint8_t n; -Philo *me; -for (n = 0U; n < N_PHILO; ++n) { - me = &Philo_inst[n]; - QActive_ctor(&me->super, Q_STATE_CAST(&Philo_initial)); - QTimeEvt_ctorX(&me->timeEvt, &me->super, TIMEOUT_SIG, 0U); -} - - - - Table *me = &Table_inst; -uint8_t n; - -QActive_ctor(&me->super, Q_STATE_CAST(&Table_initial)); - -for (n = 0U; n < N_PHILO; ++n) { - me->fork[n] = FREE; - me->isHungry[n] = 0U; -} - - #ifndef DPP_H -#define DPP_H + #ifndef DPP_H_ +#define DPP_H_ -enum DPPSignals { - EAT_SIG = Q_USER_SIG, /* published by Table to let a philosopher eat */ - DONE_SIG, /* published by Philosopher when done eating */ - PAUSE_SIG, /* published by BSP to pause serving forks */ - SERVE_SIG, /* published by BSP to serve re-start serving forks */ - TEST_SIG, /* published by BSP to test the application */ - MAX_PUB_SIG, /* the last published signal */ +$declare ${Shared} - HUNGRY_SIG, /* posted direclty to Table from hungry Philo */ - TIMEOUT_SIG, /* used by Philosophers for time events */ - MAX_SIG /* the last signal */ -}; +#ifdef QXK_H_ -$declare(Events::TableEvt) +extern QXThread * const TH_XThread1; +void XThread1_ctor(void); -/* number of philosophers */ -#define N_PHILO ((uint8_t)5) +extern QXThread * const TH_XThread2; +void XThread2_ctor(void); -$declare(AOs::Philo_ctor) -$declare(AOs::AO_Philo[N_PHILO]) +extern QXSemaphore TH_sema; +extern QXMutex TH_mutex; -$declare(AOs::Table_ctor) -$declare(AOs::AO_Table) +#endif // QXK_H_ -#ifdef QP_INC_QXK_H_ - void Test1_ctor(void); - extern QXThread * const XT_Test1; - void Test2_ctor(void); - extern QXThread * const XT_Test2; -#endif /* QP_INC_QXK_H_ */ - -#endif /* DPP_H */ - +#endif // DPP_H_ - #include "qpc.h" -#include "dpp.h" -#include "bsp.h" + #include "qpc.h" // QP/C real-time embedded framework +#include "dpp.h" // DPP Application interface +#include "bsp.h" // Board Support Package +$declare ${AOs::Philo} + +//---------------------------------------------------------------------------- Q_DEFINE_THIS_FILE -/* Active object class -----------------------------------------------------*/ -$declare${AOs::Philo} +// helper function to provide a randomized think time for Philos +static QTimeEvtCtr think_time(void); // prototype +static inline QTimeEvtCtr think_time(void) { + return (QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + + (BSP_TICKS_PER_SEC/2U)); +} -#define THINK_TIME \ - (QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + (BSP_TICKS_PER_SEC/2U)) -#define EAT_TIME \ - (QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + BSP_TICKS_PER_SEC) +// helper function to provide a randomized eat time for Philos +static QTimeEvtCtr eat_time(void); // prototype +static inline QTimeEvtCtr eat_time(void) { + return (QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + + BSP_TICKS_PER_SEC); +} +//---------------------------------------------------------------------------- -/* helper macro to provide the ID of Philo "me_" */ -#define PHILO_ID(me_) ((uint8_t)((me_) - &Philo_inst[0])) - -$define${AOs::AO_Philo[N_PHILO]} -$define${AOs::Philo_ctor} -$define${AOs::Philo} +$define ${Shared::Philo_ctor} +$define ${Shared::AO_Philo[N_PHILO]} +$define ${AOs::Philo} - #include "qpc.h" -#include "dpp.h" -#include "bsp.h" + #include "qpc.h" // QP/C real-time embedded framework +#include "dpp.h" // DPP Application interface +#include "bsp.h" // Board Support Package +$declare ${AOs::Table} + +//---------------------------------------------------------------------------- Q_DEFINE_THIS_FILE -/* Active object class -----------------------------------------------------*/ -$declare${AOs::Table} +// helper function to provide the RIGHT neighbor of a Philo[n] +static inline uint8_t right(uint8_t const n) { + return (uint8_t)((n + (N_PHILO - 1U)) % N_PHILO); +} -#define RIGHT(n_) ((uint8_t)(((n_) + (N_PHILO - 1U)) % N_PHILO)) -#define LEFT(n_) ((uint8_t)(((n_) + 1U) % N_PHILO)) -#define FREE ((uint8_t)0) -#define USED ((uint8_t)1) +// helper function to provide the LEFT neighbor of a Philo[n] +static inline uint8_t left(uint8_t const n) { + return (uint8_t)((n + 1U) % N_PHILO); +} -$define${AOs::AO_Table} -$define${AOs::Table_ctor} -$define${AOs::Table} +#define FREE ((uint8_t)0U) +#define USED ((uint8_t)1U) + +#define THINKING "thinking" +#define HUNGRY "hungry " +#define EATING "eating " + +//---------------------------------------------------------------------------- + +$define ${Shared::Table_ctor} +$define ${Shared::AO_Table} +$define ${AOs::Table} diff --git a/examples/arm-cr/dpp_launchxl2-tms57012/main.c b/examples/arm-cr/dpp_launchxl2-tms57012/main.c new file mode 100644 index 00000000..deac175a --- /dev/null +++ b/examples/arm-cr/dpp_launchxl2-tms57012/main.c @@ -0,0 +1,44 @@ +//============================================================================ +// APP example +// Last updated for version 7.3.0 +// Last updated on 2023-08-09 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. +// +// This program is open source software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Alternatively, this program may be distributed and modified under the +// terms of Quantum Leaps commercial licenses, which expressly supersede +// the GNU General Public License and are specifically designed for +// licensees interested in retaining the proprietary status of their code. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Contact information: +// +// +//============================================================================ +#include "qpc.h" // QP/C real-time embedded framework +#include "dpp.h" // DPP Application interface +#include "bsp.h" // Board Support Package + +//............................................................................ +int main() { + QF_init(); // initialize the framework and the underlying RT kernel + BSP_init(); // initialize the BSP + BSP_start(); // start the AOs/Threads + return QF_run(); // run the QF application +} diff --git a/examples/arm-cr/dpp_launchxl2-tms57012/philo.c b/examples/arm-cr/dpp_launchxl2-tms57012/philo.c index a5be8e68..eb6be531 100644 --- a/examples/arm-cr/dpp_launchxl2-tms57012/philo.c +++ b/examples/arm-cr/dpp_launchxl2-tms57012/philo.c @@ -1,167 +1,159 @@ -/*$file${.::philo.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* -* Model: dpp.qm -* File: ${.::philo.c} -* -* This code has been generated by QM 5.2.4 . -* DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. -* -* SPDX-License-Identifier: GPL-3.0-or-later -* -* This generated code is open source software: you can redistribute it under -* the terms of the GNU General Public License as published by the Free -* Software Foundation. -* -* This code is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -* more details. -* -* NOTE: -* Alternatively, this generated code may be distributed under the terms -* of Quantum Leaps commercial licenses, which expressly supersede the GNU -* General Public License and are specifically designed for licensees -* interested in retaining the proprietary status of their code. -* -* Contact information: -* -* -*/ -/*$endhead${.::philo.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -#include "qpc.h" -#include "dpp.h" -#include "bsp.h" +//$file${.::philo.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// +// Model: dpp.qm +// File: ${.::philo.c} +// +// This code has been generated by QM 5.3.0 . +// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. +// +// SPDX-License-Identifier: GPL-3.0-or-later +// +// This generated code is open source software: you can redistribute it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation. +// +// This code is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// NOTE: +// Alternatively, this generated code may be distributed under the terms +// of Quantum Leaps commercial licenses, which expressly supersede the GNU +// General Public License and are specifically designed for licensees +// interested in retaining the proprietary status of their code. +// +// Contact information: +// +// +// +//$endhead${.::philo.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +#include "qpc.h" // QP/C real-time embedded framework +#include "dpp.h" // DPP Application interface +#include "bsp.h" // Board Support Package -Q_DEFINE_THIS_FILE +//$declare${AOs::Philo} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/* Active object class -----------------------------------------------------*/ -/*$declare${AOs::Philo} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${AOs::Philo} ............................................................*/ +//${AOs::Philo} .............................................................. typedef struct Philo { -/* protected: */ +// protected: QActive super; -/* public: */ - -/* private: */ +// private: QTimeEvt timeEvt; + uint8_t id; + +// public: } Philo; + extern Philo Philo_inst[N_PHILO]; -/* protected: */ +// protected: static QState Philo_initial(Philo * const me, void const * const par); static QState Philo_thinking(Philo * const me, QEvt const * const e); static QState Philo_hungry(Philo * const me, QEvt const * const e); static QState Philo_eating(Philo * const me, QEvt const * const e); -/*$enddecl${AOs::Philo} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$enddecl${AOs::Philo} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -#define THINK_TIME \ - (QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + (BSP_TICKS_PER_SEC/2U)) -#define EAT_TIME \ - (QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + BSP_TICKS_PER_SEC) +//---------------------------------------------------------------------------- +Q_DEFINE_THIS_FILE -/* helper macro to provide the ID of Philo "me_" */ -#define PHILO_ID(me_) ((uint8_t)((me_) - &Philo_inst[0])) +// helper function to provide a randomized think time for Philos +static QTimeEvtCtr think_time(void); // prototype +static inline QTimeEvtCtr think_time(void) { + return (QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + + (BSP_TICKS_PER_SEC/2U)); +} -/*$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* Check for the minimum required QP version */ -#if (QP_VERSION < 700U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) -#error qpc version 7.0.0 or higher required +// helper function to provide a randomized eat time for Philos +static QTimeEvtCtr eat_time(void); // prototype +static inline QTimeEvtCtr eat_time(void) { + return (QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + + BSP_TICKS_PER_SEC); +} +//---------------------------------------------------------------------------- + +//$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// Check for the minimum required QP version +#if (QP_VERSION < 730U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) +#error qpc version 7.3.0 or higher required #endif -/*$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -/*$define${AOs::AO_Philo[N_PHILO]} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//$define${Shared::Philo_ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/*${AOs::AO_Philo[N_PHILO]} ................................................*/ -QActive * const AO_Philo[N_PHILO] = { /* "opaque" pointers to Philo AO */ +//${Shared::Philo_ctor} ...................................................... +void Philo_ctor(uint_fast8_t const id) { + Philo * const me = &Philo_inst[id]; + QActive_ctor(&me->super, Q_STATE_CAST(&Philo_initial)); + QTimeEvt_ctorX(&me->timeEvt, &me->super, TIMEOUT_SIG, 0U), + me->id = (uint8_t)id; +} +//$enddef${Shared::Philo_ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +//$define${Shared::AO_Philo[N_PHILO]} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${Shared::AO_Philo[N_PHILO]} ............................................... +QActive * const AO_Philo[N_PHILO] = { &Philo_inst[0].super, &Philo_inst[1].super, &Philo_inst[2].super, &Philo_inst[3].super, &Philo_inst[4].super }; -/*$enddef${AOs::AO_Philo[N_PHILO]} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*$define${AOs::Philo_ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//$enddef${Shared::AO_Philo[N_PHILO]} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +//$define${AOs::Philo} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/*${AOs::Philo_ctor} .......................................................*/ -void Philo_ctor(void) { - uint8_t n; - Philo *me; - for (n = 0U; n < N_PHILO; ++n) { - me = &Philo_inst[n]; - QActive_ctor(&me->super, Q_STATE_CAST(&Philo_initial)); - QTimeEvt_ctorX(&me->timeEvt, &me->super, TIMEOUT_SIG, 0U); - } -} -/*$enddef${AOs::Philo_ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*$define${AOs::Philo} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${AOs::Philo} ............................................................*/ +//${AOs::Philo} .............................................................. Philo Philo_inst[N_PHILO]; -/*${AOs::Philo::SM} ........................................................*/ +//${AOs::Philo::SM} .......................................................... static QState Philo_initial(Philo * const me, void const * const par) { - /*${AOs::Philo::SM::initial} */ - static uint8_t registered = (uint8_t)0; /* starts off with 0, per C-standard */ - (void)par; /* unused parameter */ - if (registered == (uint8_t)0) { - registered = (uint8_t)1; + //${AOs::Philo::SM::initial} + Q_UNUSED_PAR(par); - QS_OBJ_DICTIONARY(&Philo_inst[0]); - QS_OBJ_DICTIONARY(&Philo_inst[0].timeEvt); - QS_OBJ_DICTIONARY(&Philo_inst[1]); - QS_OBJ_DICTIONARY(&Philo_inst[1].timeEvt); - QS_OBJ_DICTIONARY(&Philo_inst[2]); - QS_OBJ_DICTIONARY(&Philo_inst[2].timeEvt); - QS_OBJ_DICTIONARY(&Philo_inst[3]); - QS_OBJ_DICTIONARY(&Philo_inst[3].timeEvt); - QS_OBJ_DICTIONARY(&Philo_inst[4]); - QS_OBJ_DICTIONARY(&Philo_inst[4].timeEvt); - - QS_FUN_DICTIONARY(&Philo_initial); - QS_FUN_DICTIONARY(&Philo_thinking); - QS_FUN_DICTIONARY(&Philo_hungry); - QS_FUN_DICTIONARY(&Philo_eating); - } - QS_SIG_DICTIONARY(HUNGRY_SIG, me); /* signal for each Philos */ - QS_SIG_DICTIONARY(TIMEOUT_SIG, me); /* signal for each Philos */ + QS_OBJ_ARR_DICTIONARY(&Philo_inst[me->id], me->id); + QS_OBJ_ARR_DICTIONARY(&Philo_inst[me->id].timeEvt, me->id); QActive_subscribe(&me->super, EAT_SIG); QActive_subscribe(&me->super, TEST_SIG); + + QS_FUN_DICTIONARY(&Philo_thinking); + QS_FUN_DICTIONARY(&Philo_hungry); + QS_FUN_DICTIONARY(&Philo_eating); + return Q_TRAN(&Philo_thinking); } -/*${AOs::Philo::SM::thinking} ..............................................*/ +//${AOs::Philo::SM::thinking} ................................................ static QState Philo_thinking(Philo * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${AOs::Philo::SM::thinking} */ + //${AOs::Philo::SM::thinking} case Q_ENTRY_SIG: { - QTimeEvt_armX(&me->timeEvt, THINK_TIME, 0U); + QTimeEvt_armX(&me->timeEvt, think_time(), 0U); status_ = Q_HANDLED(); break; } - /*${AOs::Philo::SM::thinking} */ + //${AOs::Philo::SM::thinking} case Q_EXIT_SIG: { - QTimeEvt_disarm(&me->timeEvt); + (void)QTimeEvt_disarm(&me->timeEvt); status_ = Q_HANDLED(); break; } - /*${AOs::Philo::SM::thinking::TIMEOUT} */ + //${AOs::Philo::SM::thinking::TIMEOUT} case TIMEOUT_SIG: { status_ = Q_TRAN(&Philo_hungry); break; } - /*${AOs::Philo::SM::thinking::EAT, DONE} */ - case EAT_SIG: /* intentionally fall through */ + //${AOs::Philo::SM::thinking::EAT, DONE} + case EAT_SIG: // intentionally fall through case DONE_SIG: { - /* EAT or DONE must be for other Philos than this one */ - Q_ASSERT(Q_EVT_CAST(TableEvt)->philoNum != PHILO_ID(me)); + // EAT or DONE must be for other Philos than this one + Q_ASSERT(Q_EVT_CAST(TableEvt)->philoId != me->id); status_ = Q_HANDLED(); break; } - /*${AOs::Philo::SM::thinking::TEST} */ + //${AOs::Philo::SM::thinking::TEST} case TEST_SIG: { status_ = Q_HANDLED(); break; @@ -174,22 +166,26 @@ static QState Philo_thinking(Philo * const me, QEvt const * const e) { return status_; } -/*${AOs::Philo::SM::hungry} ................................................*/ +//${AOs::Philo::SM::hungry} .................................................. static QState Philo_hungry(Philo * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${AOs::Philo::SM::hungry} */ + //${AOs::Philo::SM::hungry} case Q_ENTRY_SIG: { + #ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, HUNGRY_SIG, me->id); + #else TableEvt *pe = Q_NEW(TableEvt, HUNGRY_SIG); - pe->philoNum = PHILO_ID(me); - QACTIVE_POST(AO_Table, &pe->super, me); + pe->philoId = me->id; + #endif + QACTIVE_POST(AO_Table, &pe->super, &me->super); status_ = Q_HANDLED(); break; } - /*${AOs::Philo::SM::hungry::EAT} */ + //${AOs::Philo::SM::hungry::EAT} case EAT_SIG: { - /*${AOs::Philo::SM::hungry::EAT::[Q_EVT_CAST(TableEvt)->philoNum=~} */ - if (Q_EVT_CAST(TableEvt)->philoNum == PHILO_ID(me)) { + //${AOs::Philo::SM::hungry::EAT::[e->philoId==me->iid]} + if (Q_EVT_CAST(TableEvt)->philoId == me->id) { status_ = Q_TRAN(&Philo_eating); } else { @@ -197,10 +193,10 @@ static QState Philo_hungry(Philo * const me, QEvt const * const e) { } break; } - /*${AOs::Philo::SM::hungry::DONE} */ + //${AOs::Philo::SM::hungry::DONE} case DONE_SIG: { - /* DONE must be for other Philos than this one */ - Q_ASSERT(Q_EVT_CAST(TableEvt)->philoNum != PHILO_ID(me)); + // DONE must be for other Philos than this one + Q_ASSERT(Q_EVT_CAST(TableEvt)->philoId != me->id); status_ = Q_HANDLED(); break; } @@ -212,34 +208,40 @@ static QState Philo_hungry(Philo * const me, QEvt const * const e) { return status_; } -/*${AOs::Philo::SM::eating} ................................................*/ +//${AOs::Philo::SM::eating} .................................................. static QState Philo_eating(Philo * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${AOs::Philo::SM::eating} */ + //${AOs::Philo::SM::eating} case Q_ENTRY_SIG: { - QTimeEvt_armX(&me->timeEvt, EAT_TIME, 0U); + QTimeEvt_armX(&me->timeEvt, eat_time(), 0U); status_ = Q_HANDLED(); break; } - /*${AOs::Philo::SM::eating} */ + //${AOs::Philo::SM::eating} case Q_EXIT_SIG: { + (void)QTimeEvt_disarm(&me->timeEvt); + + #ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, DONE_SIG, me->id); + #else TableEvt *pe = Q_NEW(TableEvt, DONE_SIG); - pe->philoNum = PHILO_ID(me); + pe->philoId = me->id; + #endif QACTIVE_PUBLISH(&pe->super, &me->super); status_ = Q_HANDLED(); break; } - /*${AOs::Philo::SM::eating::TIMEOUT} */ + //${AOs::Philo::SM::eating::TIMEOUT} case TIMEOUT_SIG: { status_ = Q_TRAN(&Philo_thinking); break; } - /*${AOs::Philo::SM::eating::EAT, DONE} */ - case EAT_SIG: /* intentionally fall through */ + //${AOs::Philo::SM::eating::EAT, DONE} + case EAT_SIG: // intentionally fall through case DONE_SIG: { - /* EAT or DONE must be for other Philos than this one */ - Q_ASSERT(Q_EVT_CAST(TableEvt)->philoNum != PHILO_ID(me)); + // EAT or DONE must be for other Philos than this one + Q_ASSERT(Q_EVT_CAST(TableEvt)->philoId != me->id); status_ = Q_HANDLED(); break; } @@ -250,4 +252,4 @@ static QState Philo_eating(Philo * const me, QEvt const * const e) { } return status_; } -/*$enddef${AOs::Philo} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$enddef${AOs::Philo} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/examples/arm-cr/dpp_launchxl2-tms57012/qk/bsp.c b/examples/arm-cr/dpp_launchxl2-tms57012/qk/bsp.c index e3729ea5..cf5fcee2 100644 --- a/examples/arm-cr/dpp_launchxl2-tms57012/qk/bsp.c +++ b/examples/arm-cr/dpp_launchxl2-tms57012/qk/bsp.c @@ -1,39 +1,39 @@ -/***************************************************************************** -* Product: "DPP" on LAUCHXL2-TMS570LS12 board, preemptive QK kernel -* Last updated for version 6.9.1 -* Last updated on 2020-09-22 -* -* Q u a n t u m L e a P s -* ------------------------ -* Modern Embedded Software -* -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* -* -*****************************************************************************/ -#include "qpc.h" -#include "dpp.h" -#include "bsp.h" +//============================================================================ +// Product: "DPP" on LAUCHXL2-TMS570LS12 board, QK kernel +// Last updated for version 7.3.0 +// Last updated on 2023-08-15 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. +// +// This program is open source software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Alternatively, this program may be distributed and modified under the +// terms of Quantum Leaps commercial licenses, which expressly supersede +// the GNU General Public License and are specifically designed for +// licensees interested in retaining the proprietary status of their code. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Contact information: +// +// +//============================================================================ +#include "qpc.h" // QP/C real-time embedded framework +#include "dpp.h" // DPP Application interface +#include "bsp.h" // Board Support Package #include "sys_common.h" #include "sys_core.h" @@ -43,95 +43,122 @@ #include "rti.h" #include "het.h" #include "sci.h" -/* add other drivers if necessary... */ +// add other drivers if necessary... -Q_DEFINE_THIS_FILE +Q_DEFINE_THIS_FILE // define the name of this file for assertions -/* ISRs defined in this BSP ------------------------------------------------*/ - -/* Local-scope objects -----------------------------------------------------*/ -#define LED2_PIN 1 +// Local-scope objects ----------------------------------------------------- +#define LED2_PIN 1U #define LED2_PORT gioPORTB -#define LED3_PIN 2 +#define LED3_PIN 2U #define LED3_PORT gioPORTB -/* NOTE: Switch-A is multiplexed on the same port/pin as LED3, -* so you can use one or the other but not both simultaneously. -*/ -#define SWA_PIN 2 +// NOTE: Switch-A is multiplexed on the same port/pin as LED3, +// so you can use one or the other but not both simultaneously. +// +#define SWA_PIN 2U #define SWA_PORT gioPORTB -#define SWB_PIN 15 +#define SWB_PIN 15U #define SWB_PORT hetREG1 #define VIM_RAM ((t_isrFuncPTR *)0xFFF82000U) -static uint32_t l_rnd; /* random seed */ +static uint32_t l_rndSeed; #ifdef Q_SPY - /* QSpy source IDs */ + // QSpy source IDs static QSpyId const l_rtiCompare0 = { 0U }; static QSpyId const l_ssiTest = { 0U }; - enum AppRecords { /* application-specific trace records */ + enum AppRecords { // application-specific trace records PHILO_STAT = QS_USER, - COMMAND_STAT + PAUSED_STAT, + CONTEXT_SW, }; #endif +//============================================================================ +// Error handler and ISRs... -/* ISRs used in this project ===============================================*/ -/* CAUTION: ISRs MUST be both __stackless and __arm! */ +//............................................................................ +Q_NORETURN Q_onError(char const * const module, int_t const id) { + // NOTE: this implementation of the error handler is intended only + // for debugging and MUST be changed for deployment of the application + // (assuming that you ship your production code with assertions enabled). + Q_UNUSED_PAR(module); + Q_UNUSED_PAR(id); + + QS_ASSERTION(module, id, 10000U); // report assertion to QS + +#ifndef NDEBUG + // for debugging, hang on in an endless loop... + for (;;) { + } +#else + systemREG1->SYSECR = 0; // perform system reset + for (;;) { // explicitly "no-return" + } +#endif +} +//............................................................................ +void assert_failed(char const * const module, int_t const id); // prototype +void assert_failed(char const * const module, int_t const id) { + Q_onError(module, id); +} + +// ISRs used in this project =============================================== +// CAUTION: ISRs MUST be both __stackless and __arm! QK_IRQ_BEGIN(rtiCompare0) - /* state of the button debouncing, see below */ - static struct ButtonsDebouncing { + + rtiREG1->INTFLAG = 1U; // clear the interrutp source + QTIMEEVT_TICK_X(0U, (void *)0); // time events at rate 0 + + // Perform the debouncing of buttons. The algorithm for debouncing + // adapted from the book "Embedded Systems Dictionary" by Jack Ganssle + // and Michael Barr, page 71. + static struct { uint32_t depressed; uint32_t previous; } buttons = { 0U, 0U }; - uint32_t current; - uint32_t tmp; - rtiREG1->INTFLAG = 1U; /* clear the interrutp source */ - QTIMEEVT_TICK_X(0U, (void *)0); /* process time events for rate 0 */ + uint32_t current = ~SWB_PORT->DIN; // read SWB + uint32_t tmp = buttons.depressed; // save the depressed buttons + buttons.depressed |= (buttons.previous & current); // set depressed + buttons.depressed &= (buttons.previous | current); // clear released + buttons.previous = current; // update the history + tmp ^= buttons.depressed; // changed debounced depressed + current = buttons.depressed; - /* Perform the debouncing of buttons. The algorithm for debouncing - * adapted from the book "Embedded Systems Dictionary" by Jack Ganssle - * and Michael Barr, page 71. - */ - current = ~SWB_PORT->DIN; /* read SWB */ - tmp = buttons.depressed; /* save the debounced depressed buttons */ - buttons.depressed |= (buttons.previous & current); /* set depressed */ - buttons.depressed &= (buttons.previous | current); /* clear released */ - buttons.previous = current; /* update the history */ - tmp ^= buttons.depressed; /* changed debounced depressed */ - if ((tmp & (1U << SWB_PIN)) != 0U) { /* debounced SWB state changed? */ - if ((buttons.depressed & (1U << SWB_PIN)) != 0U) { /* SWB depressed?*/ - static QEvt const pauseEvt = { PAUSE_SIG, 0U, 0U}; + if ((tmp & (1U << SWB_PIN)) != 0U) { // debounced SWB state changed? + if ((current & (1U << SWB_PIN)) != 0U) { // SWB depressed? + static QEvt const pauseEvt = QEVT_INITIALIZER(PAUSE_SIG); QACTIVE_PUBLISH(&pauseEvt, &l_rtiCompare0); } - else { /* the button is released */ - static QEvt const serveEvt = { SERVE_SIG, 0U, 0U}; + else { // the button is released + static QEvt const serveEvt = QEVT_INITIALIZER(SERVE_SIG); QACTIVE_PUBLISH(&serveEvt, &l_rtiCompare0); } } QK_IRQ_END() -/*..........................................................................*/ -QK_IRQ_BEGIN(ssiTest) /* System Software Interrupt for testing */ - systemREG1->SSIF = 0x01; /* clear the SSI0 source */ - QACTIVE_POST(AO_Table, Q_NEW(QEvt, MAX_PUB_SIG), /* for testing... */ - &l_ssiTest); + +//............................................................................ +QK_IRQ_BEGIN(ssiTest) // System Software Interrupt for testing + systemREG1->SSIF = 0x01; // clear the SSI0 source + // for testing... + QACTIVE_POST(AO_Table, Q_NEW(QEvt, MAX_PUB_SIG),&l_ssiTest); QK_IRQ_END() -/*..........................................................................*/ + +//............................................................................ #ifdef Q_SPY -/* -* ISR for receiving bytes from the QSPY Back-End -* NOTE: This ISR is "QP-unaware" meaning that it does not interact with -* the QP and is not disabled. Such ISRs don't need to be defined with -* QK_IRQ_BEGIN()/QK_IRQ_END(). -*/ +// ISR for receiving bytes from the QSPY Back-End +// NOTE: This ISR is "QP-unaware" meaning that it does not interact with +// the QP and is not disabled. Such ISRs don't need to be defined with +// QK_IRQ_BEGIN()/QK_IRQ_END(). + #if defined __IAR_SYSTEMS_ICC__ FIQ #elif defined __TI_ARM__ @@ -142,42 +169,98 @@ QK_IRQ_END() #endif void sciHighLevel(void) { uint32_t vec = scilinREG->INTVECT0; - if (vec == 11U) { /* SCI receive interrupt */ + if (vec == 11U) { // SCI receive interrupt uint32_t b = scilinREG->RD; QS_RX_PUT(b); } } -#endif +#endif // Q_SPY + +//............................................................................ +#ifdef QF_ON_CONTEXT_SW +// NOTE: the context-switch callback is called with interrupts DISABLED +void QF_onContextSw(QActive *prev, QActive *next) { + QS_BEGIN_INCRIT(CONTEXT_SW, 0U) // in critical section! + QS_OBJ(prev); + QS_OBJ(next); + QS_END_INCRIT() +} +#endif // QF_ON_CONTEXT_SW + +//============================================================================ +// BSP functions... -/* BSP functions ===========================================================*/ void BSP_init(void) { - /* configure the LEDs */ + // configure the LEDs gioInit(); - LED2_PORT->DIR |= (1U << LED2_PIN); /* set as output */ - LED3_PORT->DIR |= (1U << LED3_PIN); /* set as output */ + LED2_PORT->DIR |= (1U << LED2_PIN); // set as output + LED3_PORT->DIR |= (1U << LED3_PIN); // set as output - /* configure the Buttons */ - SWB_PORT->DIR &= (1U << SWB_PIN); /* set as input */ + // configure the Buttons + SWB_PORT->DIR &= (1U << SWB_PIN); // set as input - /* initialize the random seed */ + // initialize the random seed BSP_randomSeed(1234U); - if (QS_INIT((void *)0) == 0) { /* initialize the QS software tracing */ + // initialize the QS software tracing... + if (QS_INIT((void *)0) == 0) { Q_ERROR(); } + + // dictionaries... QS_OBJ_DICTIONARY(&l_rtiCompare0); QS_OBJ_DICTIONARY(&l_ssiTest); QS_USR_DICTIONARY(PHILO_STAT); - QS_USR_DICTIONARY(COMMAND_STAT); + QS_USR_DICTIONARY(PAUSED_STAT); + QS_USR_DICTIONARY(CONTEXT_SW); - /* setup the QS filters... */ - QS_GLB_FILTER(QS_SM_RECORDS); /* state machine records */ - QS_GLB_FILTER(QS_AO_RECORDS); /* active object records */ - QS_GLB_FILTER(QS_UA_RECORDS); /* all user records */ + QS_ONLY(produce_sig_dict()); + + // setup the QS filters... + QS_GLB_FILTER(QS_ALL_RECORDS); // all records + QS_GLB_FILTER(-QS_QF_TICK); // exclude the clock tick } -/*..........................................................................*/ +//............................................................................ +void BSP_start(void) { + // initialize event pools + static QF_MPOOL_EL(TableEvt) smlPoolSto[2*N_PHILO]; + QF_poolInit(smlPoolSto, sizeof(smlPoolSto), sizeof(smlPoolSto[0])); + + // initialize publish-subscribe + static QSubscrList subscrSto[MAX_PUB_SIG]; + QActive_psInit(subscrSto, Q_DIM(subscrSto)); + + // instantiate and start AOs/threads... + + static QEvt const *philoQueueSto[N_PHILO][10]; + for (uint8_t n = 0U; n < N_PHILO; ++n) { + Philo_ctor(n); + QACTIVE_START(AO_Philo[n], + + // NOTE: set the preemption-threshold of all Philos to + // the same level, so that they cannot preempt each other. + Q_PRIO(n + 3U, N_PHILO + 2U), // QF-prio/pre-thre. + + philoQueueSto[n], // event queue storage + Q_DIM(philoQueueSto[n]), // queue length [events] + (void *)0, 0U, // no stack storage + (void *)0); // no initialization param + } + + static QEvt const *tableQueueSto[N_PHILO]; + Table_ctor(); + QACTIVE_START(AO_Table, + N_PHILO + 7U, // QP prio. of the AO + tableQueueSto, // event queue storage + Q_DIM(tableQueueSto), // queue length [events] + (void *)0, 0U, // no stack storage + (void *)0); // no initialization param +} +//............................................................................ void BSP_displayPhilStat(uint8_t n, char const *stat) { + Q_UNUSED_PAR(n); + if (stat[0] == 'e') { LED2_PORT->DSET = (1U << LED2_PIN); } @@ -185,182 +268,183 @@ void BSP_displayPhilStat(uint8_t n, char const *stat) { LED2_PORT->DCLR = (1U << LED2_PIN); } - QS_BEGIN_ID(PHILO_STAT, AO_Philo[n]->prio) /* app-specific record */ - QS_U8(1, n); /* Philosopher number */ - QS_STR(stat); /* Philosopher status */ + // app-specific trace record... + QS_BEGIN_ID(PHILO_STAT, AO_Table->prio) + QS_U8(1, n); // Philosopher number + QS_STR(stat); // Philosopher status QS_END() } -/*..........................................................................*/ -void BSP_displayPaused(uint8_t paused) { +//............................................................................ +void BSP_displayPaused(uint8_t const paused) { if (paused != 0U) { //LED2_PORT->DSET = (1U << LED2_PIN); } else { //LED2_PORT->DCLR = (1U << LED2_PIN); } -} -/*..........................................................................*/ -uint32_t BSP_random(void) { /* a very cheap pseudo-random-number generator */ - uint32_t rnd; - QSchedStatus lockStat; - /* Some flating point code is to exercise the VFP... */ + // application-specific trace record + QS_BEGIN_ID(PAUSED_STAT, AO_Table->prio) + QS_U8(1, paused); // Paused status + QS_END() +} +//............................................................................ +void BSP_randomSeed(uint32_t seed) { + l_rndSeed = seed; +} +//............................................................................ +uint32_t BSP_random(void) { // a very cheap pseudo-random-number generator + // Some floating point code is to exercise the FP... float volatile x = 3.1415926F; x = x + 2.7182818F; - lockStat = QK_schedLock(N_PHILO); /* lock scheduler up to N_PHILO prio */ - /* "Super-Duper" Linear Congruential Generator (LCG) - * LCG(2^32, 3*7*11*13*23, 0, seed) - */ - rnd = l_rnd * (3U*7U*11U*13U*23U); - l_rnd = rnd; /* set for the next time */ - QK_schedUnlock(lockStat); /* unlock the scheduler */ + // lock the scheduler around l_rnd up to the (N_PHILO + 1U) ceiling + QSchedStatus lockStat = QK_schedLock(N_PHILO); + // "Super-Duper" Linear Congruential Generator (LCG) + // LCG(2^32, 3*7*11*13*23, 0, seed) + uint32_t rnd = l_rndSeed * (3U*7U*11U*13U*23U); + l_rndSeed = rnd; // set for the next time + QK_schedUnlock(lockStat); // unlock the scheduler - return (rnd >> 8); + return (rnd >> 8U); } -/*..........................................................................*/ -void BSP_randomSeed(uint32_t seed) { - l_rnd = seed; -} -/*..........................................................................*/ +//............................................................................ void BSP_terminate(int16_t result) { - (void)result; + Q_UNUSED_PAR(result); } +//============================================================================ -/* QF callbacks ============================================================*/ +// QF callbacks... void QF_onStartup(void) { - rtiInit(); /* configure RTI with UC counter of 7 */ + rtiInit(); // configure RTI with UC counter of 7 rtiSetPeriod(rtiCOUNTER_BLOCK0, (uint32)((RTI_FREQ*1E6/(7+1))/BSP_TICKS_PER_SEC)); rtiEnableNotification(rtiNOTIFICATION_COMPARE0); rtiStartCounter(rtiCOUNTER_BLOCK0); - VIM_RAM[2 + 1] = (t_isrFuncPTR)&rtiCompare0; /* install the IRQ */ - vimREG->FIRQPR0 &= ~(1U << 2); /* designate interrupt as IRQ, NOTE00 */ - vimREG->REQMASKSET0 = (1U << 2); /* enable interrupt */ + VIM_RAM[2 + 1] = (t_isrFuncPTR)&rtiCompare0; // install the IRQ + vimREG->FIRQPR0 &= ~(1U << 2); // designate interrupt as IRQ, NOTE0 + vimREG->REQMASKSET0 = (1U << 2); // enable interrupt - VIM_RAM[21 + 1] = (t_isrFuncPTR)&ssiTest ; /* install the IRQ */ - vimREG->FIRQPR0 &= ~(1U << 21); /* designate interrupt as IRQ, NOTE00 */ - vimREG->REQMASKSET0 = (1U << 21); /* enable interrupt */ + VIM_RAM[21 + 1] = (t_isrFuncPTR)&ssiTest ; // install the IRQ + vimREG->FIRQPR0 &= ~(1U << 21); // designate interrupt as IRQ, NOTE0 + vimREG->REQMASKSET0 = (1U << 21); // enable interrupt - QF_INT_ENABLE_ALL(); /* enable all interrupts (IRQ and FIQ) */ + QF_INT_ENABLE_ALL(); // enable all interrupts (IRQ and FIQ) } -/*..........................................................................*/ +//............................................................................ void QF_onCleanup(void) { } -/*..........................................................................*/ +//............................................................................ void QK_onIdle(void) { - /* toggle LED1 on and then off, see NOTE01 */ + // toggle LED1 on and then off, see NOTE1 QF_INT_DISABLE(); LED3_PORT->DSET = (1U << LED3_PIN); LED3_PORT->DCLR = (1U << LED3_PIN); QF_INT_ENABLE(); #ifdef Q_SPY - QS_rxParse(); /* parse all the received bytes */ + QS_rxParse(); // parse all the received bytes //if (sciIsTxReady(scilinREG)) { - if ((scilinREG->FLR & (uint32)SCI_TX_INT) != 0U) { /* is TX empty? */ - uint16_t b; - + if ((scilinREG->FLR & (uint32)SCI_TX_INT) != 0U) { // is TX empty? QF_INT_DISABLE(); - b = QS_getByte(); + uint16_t b = QS_getByte(); QF_INT_ENABLE(); - if (b != QS_EOD) { /* not End-Of-Data? */ - //sciSendByte(scilinREG, (b & 0xFFU)); - scilinREG->TD = (b & 0xFFU); /* put into the TD register */ + if (b != QS_EOD) { // not End-Of-Data? + //sciSendByte(scilinREG, b); + scilinREG->TD = b; // put into the TD register } } #elif defined NDEBUG - /* Put the CPU and peripherals to the low-power mode. - * you might need to customize the clock management for your application, - * see the datasheet for your particular Cortex-R MCU. - */ - _gotoCPUIdle_(); /* wait for interrupt */ + // Put the CPU and peripherals to the low-power mode. + // you might need to customize the clock management for your application, + // see the datasheet for your particular Cortex-R MCU. + // + _gotoCPUIdle_(); // wait for interrupt #endif } -/*..........................................................................*/ -Q_NORETURN Q_onAssert(char const * const module, int_t const loc) { - /* - * NOTE: add here your application-specific error handling - */ - (void)module; - (void)loc; - QS_ASSERTION(module, loc, 10000U); /* report assertion to QS */ - systemREG1->SYSECR = 0; /* perform system reset */ -} -/* QS callbacks ============================================================*/ +//============================================================================ +// QS callbacks... #ifdef Q_SPY -/*..........................................................................*/ -uint8_t QS_onStartup(void const *arg) { - static uint8_t qsTxBuf[2*1024]; /* buffer for QS transmit channel */ - static uint8_t qsRxBuf[100]; /* buffer for QS receive channel */ - QS_initBuf (qsTxBuf, sizeof(qsTxBuf)); +//............................................................................ +uint8_t QS_onStartup(void const *arg) { + Q_UNUSED_PAR(arg); + + static uint8_t qsTxBuf[2*1024]; // buffer for QS-TX channel + QS_initBuf(qsTxBuf, sizeof(qsTxBuf)); + + static uint8_t qsRxBuf[100]; // buffer for QS-RX channel QS_rxInitBuf(qsRxBuf, sizeof(qsRxBuf)); sciInit(); - VIM_RAM[13 + 1] = (t_isrFuncPTR)&sciHighLevel; /* install the ISR */ - vimREG->FIRQPR0 |= (1U << 13); /* designate interrupt as FIQ */ - vimREG->REQMASKSET0 = (1U << 13); /* enable interrupt */ + VIM_RAM[13 + 1] = (t_isrFuncPTR)&sciHighLevel; // install the ISR + vimREG->FIRQPR0 |= (1U << 13U); // designate interrupt as FIQ + vimREG->REQMASKSET0 = (1U << 13U); // enable interrupt - return 1U; /* return success */ + return 1U; // return success } -/*..........................................................................*/ +//............................................................................ void QS_onCleanup(void) { } -/*..........................................................................*/ -QSTimeCtr QS_onGetTime(void) { /* NOTE: invoked with interrupts DISABLED */ - return rtiREG1->CNT[0].FRCx; /* free running RTI counter0 */ +//............................................................................ +QSTimeCtr QS_onGetTime(void) { // NOTE: invoked with interrupts DISABLED + return rtiREG1->CNT[0].FRCx; // free running RTI counter0 } -/*..........................................................................*/ +//............................................................................ void QS_onFlush(void) { - uint16_t b; - - QF_INT_DISABLE(); - while ((b = QS_getByte()) != QS_EOD) { /* while not End-Of-Data... */ - QF_INT_ENABLE(); - //while (!sciIsTxReady(scilinREG)) { - while ((scilinREG->FLR & (uint32)SCI_TX_INT) == 0U) { - } - //sciSendByte(scilinREG, (b & 0xFFU)); - scilinREG->TD = (b & 0xFFU); + for (;;) { QF_INT_DISABLE(); + uint16_t b = QS_getByte(); + if (b != QS_EOD) { + while ((scilinREG->FLR & (uint32)SCI_TX_INT) == 0U) { + QF_INT_ENABLE(); + QF_CRIT_EXIT_NOP(); + + QF_INT_DISABLE(); + } + scilinREG->TD = b; + QF_INT_ENABLE(); + } + else { + QF_INT_ENABLE(); + break; + } } - QF_INT_ENABLE(); } -/*..........................................................................*/ -/*! callback function to reset the target (to be implemented in the BSP) */ +//............................................................................ +//! callback function to reset the target (to be implemented in the BSP) void QS_onReset(void) { - systemREG1->SYSECR = 0; /* perform system reset */ + systemREG1->SYSECR = 0U; // perform system reset } -/*..........................................................................*/ -/*! callback function to execute a user command (to be implemented in BSP) */ +//............................................................................ +// callback function to execute a user command void QS_onCommand(uint8_t cmdId, uint32_t param1, uint32_t param2, uint32_t param3) { - (void)cmdId; - (void)param1; - (void)param2; - (void)param3; + Q_UNUSED_PAR(cmdId); + Q_UNUSED_PAR(param1); + Q_UNUSED_PAR(param2); + Q_UNUSED_PAR(param3); } -#endif /* Q_SPY */ -/*--------------------------------------------------------------------------*/ +#endif // Q_SPY +//---------------------------------------------------------------------------- -/***************************************************************************** -* NOTE00: -* The FIQ-type interrupts are never disabled in this QP port, therefore -* they can always preempt any code, including the IRQ-handlers (ISRs). -* Therefore, FIQ-type interrupts are "kernel-unaware" and must NEVER call -* any QP services, such as posting events. -* -* NOTE01: -* One of the LEDs is used to visualize the idle loop activity. The brightness -* of the LED is proportional to the frequency of invcations of the idle loop. -* Please note that the LED is toggled with interrupts locked, so no interrupt -* execution time contributes to the brightness of the User LED. -*/ +//============================================================================ +// NOTE0: +// The FIQ-type interrupts are never disabled in this QP port, therefore +// they can always preempt any code, including the IRQ-handlers (ISRs). +// Therefore, FIQ-type interrupts are "kernel-unaware" and must NEVER call +// any QP services, such as posting events. +// +// NOTE1: +// One of the LEDs is used to visualize the idle loop activity. The brightness +// of the LED is proportional to the frequency of invocations of the idle loop. +// Please note that the LED is toggled with interrupts locked, so no interrupt +// execution time contributes to the brightness of the User LED. +// diff --git a/examples/arm-cr/dpp_launchxl2-tms57012/qk/iar/dpp-qk.ewd b/examples/arm-cr/dpp_launchxl2-tms57012/qk/iar/dpp-qk.ewd index dc1d7bd0..04d055d6 100644 --- a/examples/arm-cr/dpp_launchxl2-tms57012/qk/iar/dpp-qk.ewd +++ b/examples/arm-cr/dpp_launchxl2-tms57012/qk/iar/dpp-qk.ewd @@ -88,7 +88,7 @@ - - BILINK - 0 - - Coder 0 @@ -1071,9 +1090,13 @@ General 3 - 31 + 35 1 0 + - - - - - + + + + + ICCARM 2 - 35 + 37 1 0 - - - + AARM 2 - 10 + 11 1 0 + @@ -1732,13 +1747,9 @@ 0 + inputOutputBased - - BICOMP - 0 - - BUILDACTION 1 @@ -1751,17 +1762,13 @@ ILINK 0 - 23 + 27 1 0 - + + + + + + + + + @@ -2110,11 +2153,6 @@ - - BILINK - 0 - - Coder 0 @@ -2131,9 +2169,13 @@ General 3 - 31 + 35 1 1 + - - - - - + + + + + ICCARM 2 - 35 + 37 1 1 - - - + AARM 2 - 10 + 11 1 1 + @@ -2792,13 +2826,9 @@ 0 + inputOutputBased - - BICOMP - 0 - - BUILDACTION 1 @@ -2811,17 +2841,13 @@ ILINK 0 - 23 + 27 1 1 - + + + + + + + + + @@ -3170,11 +3232,6 @@ - - BILINK - 0 - - Coder 0 @@ -3193,14 +3250,11 @@ $PROJ_DIR$\..\..\dpp.h - $PROJ_DIR$\..\main.c + $PROJ_DIR$\..\..\main.c $PROJ_DIR$\..\..\philo.c - - $PROJ_DIR$\..\..\..\..\..\include\qstamp.c - $PROJ_DIR$\..\..\table.c @@ -3335,10 +3389,10 @@ $PROJ_DIR$\..\..\..\..\..\src\qs\qs_fp.c - $PROJ_DIR$\..\..\..\..\..\src\qs_pkg.h + $PROJ_DIR$\..\..\..\..\..\src\qs\qs_rx.c - $PROJ_DIR$\..\..\..\..\..\src\qs\qs_rx.c + $PROJ_DIR$\..\..\..\..\..\src\qs\qstamp.c diff --git a/examples/arm-cr/dpp_launchxl2-tms57012/qk/main.c b/examples/arm-cr/dpp_launchxl2-tms57012/qk/main.c deleted file mode 100644 index 7047b71b..00000000 --- a/examples/arm-cr/dpp_launchxl2-tms57012/qk/main.c +++ /dev/null @@ -1,80 +0,0 @@ -/***************************************************************************** -* Product: DPP example -* Last updated for version 6.4.0 -* Last updated on 2019-02-08 -* -* Q u a n t u m L e a P s -* ------------------------ -* Modern Embedded Software -* -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* -* -*****************************************************************************/ -#include "qpc.h" -#include "dpp.h" -#include "bsp.h" - -Q_DEFINE_THIS_FILE - -/*..........................................................................*/ -int main() { - static QEvt const *tableQueueSto[N_PHILO]; - static QEvt const *philoQueueSto[N_PHILO][N_PHILO]; - static QSubscrList subscrSto[MAX_PUB_SIG]; - static QF_MPOOL_EL(TableEvt) smlPoolSto[2*N_PHILO]; /* small pool */ - uint8_t n; - - Philo_ctor(); /* instantiate all Philosopher active objects */ - Table_ctor(); /* instantiate the Table active object */ - - QF_init(); /* initialize the framework and the underlying RT kernel */ - BSP_init(); /* initialize the Board Support Package */ - - /* initialize publish-subscribe... */ - QF_psInit(subscrSto, Q_DIM(subscrSto)); - - /* initialize event pools... */ - QF_poolInit(smlPoolSto, sizeof(smlPoolSto), sizeof(smlPoolSto[0])); - - /* start the active objects... */ - for (n = 0U; n < N_PHILO; ++n) { - QACTIVE_START(AO_Philo[n], /* AO to start */ - (uint_fast8_t)(n + 1), /* QP priority of the AO */ - philoQueueSto[n], /* event queue storage */ - Q_DIM(philoQueueSto[n]), /* queue length [events] */ - (void *)0, /* stack storage (not used) */ - 0U, /* size of the stack [bytes] */ - (QEvt *)0); /* initialization event */ - } - QACTIVE_START(AO_Table, /* AO to start */ - (uint_fast8_t)(N_PHILO + 1), /* QP priority of the AO */ - tableQueueSto, /* event queue storage */ - Q_DIM(tableQueueSto), /* queue length [events] */ - (void *)0, /* stack storage (not used) */ - 0U, /* size of the stack [bytes] */ - (QEvt *)0); /* initialization event */ - - return QF_run(); /* run the QF application */ -} - diff --git a/examples/arm-cr/dpp_launchxl2-tms57012/qk/ti/.cproject b/examples/arm-cr/dpp_launchxl2-tms57012/qk/ti/.cproject index f33f0892..357cf2c7 100644 --- a/examples/arm-cr/dpp_launchxl2-tms57012/qk/ti/.cproject +++ b/examples/arm-cr/dpp_launchxl2-tms57012/qk/ti/.cproject @@ -15,81 +15,89 @@ - - - - @@ -114,7 +122,7 @@ - - + + \ No newline at end of file diff --git a/examples/arm-cr/dpp_launchxl2-tms57012/qk/ti/.project b/examples/arm-cr/dpp_launchxl2-tms57012/qk/ti/.project index f32613b8..54858375 100644 --- a/examples/arm-cr/dpp_launchxl2-tms57012/qk/ti/.project +++ b/examples/arm-cr/dpp_launchxl2-tms57012/qk/ti/.project @@ -7,6 +7,7 @@ org.eclipse.cdt.managedbuilder.core.genmakebuilder + clean,full,incremental, @@ -63,18 +64,13 @@ main.c 1 - PARENT-1-PROJECT_LOC/main.c + PARENT-2-PROJECT_LOC/main.c philo.c 1 PARENT-2-PROJECT_LOC/philo.c - - qstamp.c - 1 - PARENT-5-PROJECT_LOC/include/qstamp.c - table.c 1 diff --git a/examples/arm-cr/dpp_launchxl2-tms57012/qv/bsp.c b/examples/arm-cr/dpp_launchxl2-tms57012/qv/bsp.c index eed89dbf..5db2ce8b 100644 --- a/examples/arm-cr/dpp_launchxl2-tms57012/qv/bsp.c +++ b/examples/arm-cr/dpp_launchxl2-tms57012/qv/bsp.c @@ -1,39 +1,39 @@ -/***************************************************************************** -* Product: "DPP" on LAUCHXL2-TMS570LS12 board, cooperative QV kernel -* Last updated for version 6.9.3 -* Last updated on 2021-03-03 -* -* Q u a n t u m L e a P s -* ------------------------ -* Modern Embedded Software -* -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* -* -*****************************************************************************/ -#include "qpc.h" -#include "dpp.h" -#include "bsp.h" +//============================================================================ +// Product: "DPP" on LAUCHXL2-TMS570LS12 board, QV kernel +// Last updated for version 7.3.0 +// Last updated on 2023-08-15 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. +// +// This program is open source software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Alternatively, this program may be distributed and modified under the +// terms of Quantum Leaps commercial licenses, which expressly supersede +// the GNU General Public License and are specifically designed for +// licensees interested in retaining the proprietary status of their code. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Contact information: +// +// +//============================================================================ +#include "qpc.h" // QP/C real-time embedded framework +#include "dpp.h" // DPP Application interface +#include "bsp.h" // Board Support Package #include "sys_common.h" #include "sys_core.h" @@ -43,95 +43,118 @@ #include "rti.h" #include "het.h" #include "sci.h" -/* add other drivers if necessary... */ +// add other drivers if necessary... -Q_DEFINE_THIS_FILE +Q_DEFINE_THIS_FILE // define the name of this file for assertions -/* ISRs defined in this BSP ------------------------------------------------*/ - -/* Local-scope objects -----------------------------------------------------*/ -#define LED2_PIN 1 +// Local-scope objects ----------------------------------------------------- +#define LED2_PIN 1U #define LED2_PORT gioPORTB -#define LED3_PIN 2 +#define LED3_PIN 2U #define LED3_PORT gioPORTB -/* NOTE: Switch-A is multiplexed on the same port/pin as LED3, -* so you can use one or the other but not both simultaneously. -*/ -#define SWA_PIN 2 +// NOTE: Switch-A is multiplexed on the same port/pin as LED3, +// so you can use one or the other but not both simultaneously. +// +#define SWA_PIN 2U #define SWA_PORT gioPORTB -#define SWB_PIN 15 +#define SWB_PIN 15U #define SWB_PORT hetREG1 #define VIM_RAM ((t_isrFuncPTR *)0xFFF82000U) -static uint32_t l_rnd; /* random seed */ +static uint32_t l_rndSeed; #ifdef Q_SPY - /* QSpy source IDs */ + // QSpy source IDs static QSpyId const l_rtiCompare0 = { 0U }; static QSpyId const l_ssiTest = { 0U }; - enum AppRecords { /* application-specific trace records */ + enum AppRecords { // application-specific trace records PHILO_STAT = QS_USER, - COMMAND_STAT + PAUSED_STAT, + CONTEXT_SW, }; #endif +//============================================================================ +// Error handler and ISRs... -/* ISRs used in this project ===============================================*/ -/* NOTE: -* The QV kernel can use the standard interrupt implementation generated -* by the HALCoGen. Here the RTI COMPARE0 is handled in a "notification" -* function called from rtiCompare0Interrupt() in the rti.c module. -*/ +//............................................................................ +Q_NORETURN Q_onError(char const * const module, int_t const id) { + // NOTE: this implementation of the error handler is intended only + // for debugging and MUST be changed for deployment of the application + // (assuming that you ship your production code with assertions enabled). + Q_UNUSED_PAR(module); + Q_UNUSED_PAR(id); + + QS_ASSERTION(module, id, 10000U); // report assertion to QS + +#ifndef NDEBUG + // for debugging, hang on in an endless loop... + for (;;) { + } +#else + systemREG1->SYSECR = 0; // perform system reset + for (;;) { // explicitly "no-return" + } +#endif +} +//............................................................................ +void assert_failed(char const * const module, int_t const id); // prototype +void assert_failed(char const * const module, int_t const id) { + Q_onError(module, id); +} + +// ISRs used in this project =============================================== +// The QV kernel can use the standard interrupt implementation generated +// by the HALCoGen. Here the RTI COMPARE0 is handled in a "notification" +// function called from rtiCompare0Interrupt() in the rti.c module. +// void rtiNotification(uint32 notification) { - if (notification == rtiNOTIFICATION_COMPARE0) { - /* state of the button debouncing, see below */ - static struct ButtonsDebouncing { - uint32_t depressed; - uint32_t previous; - } buttons = { 0U, 0U }; - uint32_t current; - uint32_t tmp; - rtiREG1->INTFLAG = 1U; /* clear the interrutp source */ - QTIMEEVT_TICK_X(0U, (void *)0); /* process time events for rate 0 */ + rtiREG1->INTFLAG = 1U; // clear the interrutp source + QTIMEEVT_TICK_X(0U, (void *)0); // time events at rate 0 - /* Perform the debouncing of buttons. The algorithm for debouncing - * adapted from the book "Embedded Systems Dictionary" by Jack Ganssle - * and Michael Barr, page 71. - */ - current = ~SWB_PORT->DIN; /* read SWB */ - tmp = buttons.depressed; /* save the debounced depressed buttons */ - buttons.depressed |= (buttons.previous & current); /* set depressed */ - buttons.depressed &= (buttons.previous | current); /* clear released */ - buttons.previous = current; /* update the history */ - tmp ^= buttons.depressed; /* changed debounced depressed */ - if ((tmp & (1U << SWB_PIN)) != 0U) { /* debounced SWB state changed? */ - if ((buttons.depressed & (1U << SWB_PIN)) != 0U) { /* SWB depressed?*/ - static QEvt const pauseEvt = { PAUSE_SIG, 0U, 0U}; - QACTIVE_PUBLISH(&pauseEvt, &l_rtiCompare0); - } - else { /* the button is released */ - static QEvt const serveEvt = { SERVE_SIG, 0U, 0U}; - QACTIVE_PUBLISH(&serveEvt, &l_rtiCompare0); - } + // Perform the debouncing of buttons. The algorithm for debouncing + // adapted from the book "Embedded Systems Dictionary" by Jack Ganssle + // and Michael Barr, page 71. + // + // state of the button debouncing + static struct { + uint32_t depressed; + uint32_t previous; + } buttons = { 0U, 0U }; + + uint32_t current = ~SWB_PORT->DIN; // read SWB + uint32_t tmp = buttons.depressed; // save the depressed buttons + buttons.depressed |= (buttons.previous & current); // set depressed + buttons.depressed &= (buttons.previous | current); // clear released + buttons.previous = current; // update the history + tmp ^= buttons.depressed; // changed debounced depressed + current = buttons.depressed; + + if ((tmp & (1U << SWB_PIN)) != 0U) { // debounced SWB state changed? + if ((current & (1U << SWB_PIN)) != 0U) { // SWB depressed? + static QEvt const pauseEvt = QEVT_INITIALIZER(PAUSE_SIG); + QACTIVE_PUBLISH(&pauseEvt, &l_rtiCompare0); + } + else { // the button is released + static QEvt const serveEvt = QEVT_INITIALIZER(SERVE_SIG); + QACTIVE_PUBLISH(&serveEvt, &l_rtiCompare0); } } } -/*..........................................................................*/ +//............................................................................ #ifdef Q_SPY -/* -* ISR for receiving bytes from the QSPY Back-End -* NOTE: This ISR is "QP-unaware" meaning that it does not interact with -* the QP and is not disabled. Such ISRs don't need to call QK_ISR_ENTRY/ -* QK_ISR_EXIT and they cannot post or publish events. -*/ +// ISR for receiving bytes from the QSPY Back-End +// NOTE: This ISR is "QP-unaware" meaning that it does not interact with +// the QP and is not disabled. + #if defined __IAR_SYSTEMS_ICC__ FIQ #elif defined __TI_ARM__ @@ -142,41 +165,87 @@ void rtiNotification(uint32 notification) { #endif void sciHighLevel(void) { uint32_t vec = scilinREG->INTVECT0; - if (vec == 11U) { /* SCI receive interrupt */ + if (vec == 11U) { // SCI receive interrupt uint32_t b = scilinREG->RD; QS_RX_PUT(b); } } -#endif +#endif // Q_SPY + +//............................................................................ +#ifdef QF_ON_CONTEXT_SW +// NOTE: the context-switch callback is called with interrupts DISABLED +void QF_onContextSw(QActive *prev, QActive *next) { + QS_BEGIN_INCRIT(CONTEXT_SW, 0U) // in critical section! + QS_OBJ(prev); + QS_OBJ(next); + QS_END_INCRIT() +} +#endif // QF_ON_CONTEXT_SW + +//============================================================================ +// BSP functions... -/* BSP functions ===========================================================*/ void BSP_init(void) { - /* configure the LEDs */ + // configure the LEDs gioInit(); - LED2_PORT->DIR |= (1U << LED2_PIN); /* set as output */ - LED3_PORT->DIR |= (1U << LED3_PIN); /* set as output */ + LED2_PORT->DIR |= (1U << LED2_PIN); // set as output + LED3_PORT->DIR |= (1U << LED3_PIN); // set as output - /* configure the Buttons */ - SWB_PORT->DIR &= (1U << SWB_PIN); /* set as input */ + // configure the Buttons + SWB_PORT->DIR &= (1U << SWB_PIN); // set as input - /* initialize the random seed */ + // initialize the random seed BSP_randomSeed(1234U); - if (QS_INIT((void *)0) == 0) { /* initialize the QS software tracing */ + if (QS_INIT((void *)0) == 0) { // initialize the QS software tracing Q_ERROR(); } QS_OBJ_DICTIONARY(&l_rtiCompare0); QS_OBJ_DICTIONARY(&l_ssiTest); QS_USR_DICTIONARY(PHILO_STAT); - QS_USR_DICTIONARY(COMMAND_STAT); + QS_USR_DICTIONARY(PAUSED_STAT); + QS_USR_DICTIONARY(CONTEXT_SW); - /* setup the QS filters... */ - QS_GLB_FILTER(QS_SM_RECORDS); /* state machine records */ - QS_GLB_FILTER(QS_AO_RECORDS); /* active object records */ - QS_GLB_FILTER(QS_UA_RECORDS); /* all user records */ + QS_ONLY(produce_sig_dict()); + + // setup the QS filters... + QS_GLB_FILTER(QS_ALL_RECORDS); // all records + QS_GLB_FILTER(-QS_QF_TICK); // exclude the clock tick } -/*..........................................................................*/ +void BSP_start(void) { + // initialize event pools + static QF_MPOOL_EL(TableEvt) smlPoolSto[2*N_PHILO]; + QF_poolInit(smlPoolSto, sizeof(smlPoolSto), sizeof(smlPoolSto[0])); + + // initialize publish-subscribe + static QSubscrList subscrSto[MAX_PUB_SIG]; + QActive_psInit(subscrSto, Q_DIM(subscrSto)); + + // instantiate and start AOs/threads... + + static QEvt const *philoQueueSto[N_PHILO][10]; + for (uint8_t n = 0U; n < N_PHILO; ++n) { + Philo_ctor(n); + QACTIVE_START(AO_Philo[n], + n + 3U, // QF-prio/pre-thre. + philoQueueSto[n], // event queue storage + Q_DIM(philoQueueSto[n]), // queue length [events] + (void *)0, 0U, // no stack storage + (void *)0); // no initialization param + } + + static QEvt const *tableQueueSto[N_PHILO]; + Table_ctor(); + QACTIVE_START(AO_Table, + N_PHILO + 7U, // QP prio. of the AO + tableQueueSto, // event queue storage + Q_DIM(tableQueueSto), // queue length [events] + (void *)0, 0U, // no stack storage + (void *)0); // no initialization param +} +//............................................................................ void BSP_displayPhilStat(uint8_t n, char const *stat) { if (stat[0] == 'e') { LED2_PORT->DSET = (1U << LED2_PIN); @@ -185,190 +254,176 @@ void BSP_displayPhilStat(uint8_t n, char const *stat) { LED2_PORT->DCLR = (1U << LED2_PIN); } - QS_BEGIN_ID(PHILO_STAT, AO_Philo[n]->prio) /* app-specific record */ - QS_U8(1, n); /* Philosopher number */ - QS_STR(stat); /* Philosopher status */ + // app-specific trace record... + QS_BEGIN_ID(PHILO_STAT, AO_Table->prio) + QS_U8(1, n); // Philosopher number + QS_STR(stat); // Philosopher status QS_END() } -/*..........................................................................*/ -void BSP_displayPaused(uint8_t paused) { +//............................................................................ +void BSP_displayPaused(uint8_t const paused) { if (paused != 0U) { //LED2_PORT->DSET = (1U << LED2_PIN); } else { //LED2_PORT->DCLR = (1U << LED2_PIN); } -} -/*..........................................................................*/ -uint32_t BSP_random(void) { /* a very cheap pseudo-random-number generator */ - uint32_t rnd; - /* Some flating point code is to exercise the VFP... */ + // application-specific trace record + QS_BEGIN_ID(PAUSED_STAT, AO_Table->prio) + QS_U8(1, paused); // Paused status + QS_END() +} +//............................................................................ +void BSP_randomSeed(uint32_t seed) { + l_rndSeed = seed; +} +//............................................................................ +uint32_t BSP_random(void) { // a very cheap pseudo-random-number generator + // Some floating point code is to exercise the FP... float volatile x = 3.1415926F; x = x + 2.7182818F; - /* "Super-Duper" Linear Congruential Generator (LCG) - * LCG(2^32, 3*7*11*13*23, 0, seed) - */ - rnd = l_rnd * (3U*7U*11U*13U*23U); - l_rnd = rnd; /* set for the next time */ + // "Super-Duper" Linear Congruential Generator (LCG) + // LCG(2^32, 3*7*11*13*23, 0, seed) + uint32_t rnd = l_rndSeed * (3U*7U*11U*13U*23U); + l_rndSeed = rnd; // set for the next time return (rnd >> 8); } -/*..........................................................................*/ -void BSP_randomSeed(uint32_t seed) { - l_rnd = seed; -} -/*..........................................................................*/ +//............................................................................ void BSP_terminate(int16_t result) { (void)result; } -/* QF callbacks ============================================================*/ +// QF callbacks ============================================================ void QF_onStartup(void) { - rtiInit(); /* configure RTI with UC counter of 7 */ + rtiInit(); // configure RTI with UC counter of 7 rtiSetPeriod(rtiCOUNTER_BLOCK0, (uint32)((RTI_FREQ*1E6/(7+1))/BSP_TICKS_PER_SEC)); rtiEnableNotification(rtiNOTIFICATION_COMPARE0); rtiStartCounter(rtiCOUNTER_BLOCK0); - QF_INT_ENABLE_ALL(); /* enable all interrupts (IRQ and FIQ) */ + QF_INT_ENABLE_ALL(); // enable all interrupts (IRQ and FIQ) } -/*..........................................................................*/ +//............................................................................ void QF_onCleanup(void) { } -/*..........................................................................*/ -void QV_onIdle(void) { /* CATION: called with interrupts DISABLED, NOTE01 */ - /* toggle LED1 on and then off, see NOTE02 */ +//............................................................................ +void QV_onIdle(void) { // CATION: called with interrupts DISABLED, NOTE1 LED3_PORT->DSET = (1U << LED3_PIN); LED3_PORT->DCLR = (1U << LED3_PIN); #ifdef Q_SPY - QS_rxParse(); /* parse all the received bytes */ + QS_rxParse(); // parse all the received bytes //if (sciIsTxReady(scilinREG)) { - if ((scilinREG->FLR & (uint32)SCI_TX_INT) != 0U) { /* is TX empty? */ - uint16_t b; - + if ((scilinREG->FLR & (uint32)SCI_TX_INT) != 0U) { // is TX empty? QF_INT_DISABLE(); - b = QS_getByte(); + uint16_t b = QS_getByte(); QF_INT_ENABLE(); - if (b != QS_EOD) { /* not End-Of-Data? */ - //sciSendByte(scilinREG, (b & 0xFFU)); - scilinREG->TD = (b & 0xFFU); /* put into the TD register */ + if (b != QS_EOD) { // not End-Of-Data? + //sciSendByte(scilinREG, b); + scilinREG->TD = b; // put into the TD register } } #elif defined NDEBUG - /* Put the CPU and peripherals to the low-power mode. - * you might need to customize the clock management for your application, - * see the datasheet for your particular Cortex-R MCU. - */ - QV_CPU_SLEEP(); /* atomically go to sleep and enable interrupts */ + // Put the CPU and peripherals to the low-power mode. + // you might need to customize the clock management for your application, + // see the datasheet for your particular Cortex-R MCU. + // + QV_CPU_SLEEP(); // atomically go to sleep and enable interrupts #else - QF_INT_ENABLE(); /* just enable interrupts */ + QF_INT_ENABLE(); // just enable interrupts #endif } -/*..........................................................................*/ -Q_NORETURN Q_onAssert(char const * const module, int_t const loc) { - /* - * NOTE: add here your application-specific error handling - */ - (void)module; - (void)loc; - QS_ASSERTION(module, loc, 10000U); /* report assertion to QS */ - systemREG1->SYSECR = 0; /* perform system reset */ -} -/* QS callbacks ============================================================*/ +//============================================================================ +// QS callbacks... #ifdef Q_SPY -/*..........................................................................*/ -uint8_t QS_onStartup(void const *arg) { - static uint8_t qsTxBuf[2*1024]; /* buffer for QS transmit channel */ - static uint8_t qsRxBuf[100]; /* buffer for QS receive channel */ - QS_initBuf (qsTxBuf, sizeof(qsTxBuf)); +//............................................................................ +uint8_t QS_onStartup(void const *arg) { + Q_UNUSED_PAR(arg); + + static uint8_t qsTxBuf[2*1024]; // buffer for QS-TX channel + QS_initBuf(qsTxBuf, sizeof(qsTxBuf)); + + static uint8_t qsRxBuf[100]; // buffer for QS-RX channel QS_rxInitBuf(qsRxBuf, sizeof(qsRxBuf)); sciInit(); - VIM_RAM[13 + 1] = (t_isrFuncPTR)&sciHighLevel; /* install the ISR */ - vimREG->FIRQPR0 |= (1U << 13); /* designate interrupt as FIQ */ - vimREG->REQMASKSET0 = (1U << 13); /* enable interrupt */ + VIM_RAM[13 + 1] = (t_isrFuncPTR)&sciHighLevel; // install the ISR + vimREG->FIRQPR0 |= (1U << 13U); // designate interrupt as FIQ + vimREG->REQMASKSET0 = (1U << 13U); // enable interrupt - return 1U; /* return success */ + return 1U; // return success } -/*..........................................................................*/ +//............................................................................ void QS_onCleanup(void) { } -/*..........................................................................*/ -QSTimeCtr QS_onGetTime(void) { /* NOTE: invoked with interrupts DISABLED */ - return rtiREG1->CNT[0].FRCx; /* free running RTI counter0 */ +//............................................................................ +QSTimeCtr QS_onGetTime(void) { // NOTE: invoked with interrupts DISABLED + return rtiREG1->CNT[0].FRCx; // free running RTI counter0 } -/*..........................................................................*/ +//............................................................................ void QS_onFlush(void) { - uint16_t b; - - QF_INT_DISABLE(); - while ((b = QS_getByte()) != QS_EOD) { /* while not End-Of-Data... */ - QF_INT_ENABLE(); - //while (!sciIsTxReady(scilinREG)) { - while ((scilinREG->FLR & (uint32)SCI_TX_INT) == 0U) { - } - //sciSendByte(scilinREG, (b & 0xFFU)); - scilinREG->TD = (b & 0xFFU); + for (;;) { QF_INT_DISABLE(); + uint16_t b = QS_getByte(); + if (b != QS_EOD) { + while ((scilinREG->FLR & (uint32)SCI_TX_INT) == 0U) { + QF_INT_ENABLE(); + QF_CRIT_EXIT_NOP(); + + QF_INT_DISABLE(); + } + scilinREG->TD = b; + QF_INT_ENABLE(); + } + else { + QF_INT_ENABLE(); + break; + } } - QF_INT_ENABLE(); } -/*..........................................................................*/ -/*! callback function to reset the target (to be implemented in the BSP) */ +//............................................................................ +//! callback function to reset the target (to be implemented in the BSP) void QS_onReset(void) { - systemREG1->SYSECR = 0; /* perform system reset */ + systemREG1->SYSECR = 0U; // perform system reset } -/*..........................................................................*/ -/*! callback function to execute a user command (to be implemented in BSP) */ +//............................................................................ +// callback function to execute a user command void QS_onCommand(uint8_t cmdId, uint32_t param1, uint32_t param2, uint32_t param3) { - (void)cmdId; - (void)param1; - (void)param2; - (void)param3; - QS_BEGIN_ID(COMMAND_STAT, 0U) /* app-specific record */ - QS_U8(2, cmdId); - QS_U32(8, param1); - QS_U32(8, param2); - QS_U32(8, param3); - QS_END() - - if (cmdId == 10U) { - Q_ERROR(); - } - else if (cmdId == 11U) { - Q_ERROR(); - } + Q_UNUSED_PAR(cmdId); + Q_UNUSED_PAR(param1); + Q_UNUSED_PAR(param2); + Q_UNUSED_PAR(param3); } -#endif /* Q_SPY */ -/*--------------------------------------------------------------------------*/ +#endif // Q_SPY +//---------------------------------------------------------------------------- -/***************************************************************************** -* NOTE00: -* The FIQ-type interrupts are never disabled in this QP port, therefore -* they can always preempt any code, including the IRQ-handlers (ISRs). -* Therefore, FIQ-type interrupts are "kernel-unaware" and must NEVER call -* any QP services, such as posting events. -* -* NOTE01: -* The QV_onIdle() callback is called with interrupts disabled, because the -* determination of the idle condition might change by any interrupt posting -* an event. QV_onIdle() must internally enable interrupts, ideally -* atomically with putting the CPU to the power-saving mode. -* -* NOTE02: -* One of the LEDs is used to visualize the idle loop activity. The brightness -* of the LED is proportional to the frequency of invcations of the idle loop. -* Please note that the LED is toggled with interrupts locked, so no interrupt -* execution time contributes to the brightness of the User LED. -*/ +//============================================================================ +// NOTE0: +// The FIQ-type interrupts are never disabled in this QP port, therefore +// they can always preempt any code, including the IRQ-handlers (ISRs). +// Therefore, FIQ-type interrupts are "kernel-unaware" and must NEVER call +// any QP services, such as posting events. +// +// NOTE1: +// The QV_onIdle() callback is called with interrupts disabled, because the +// determination of the idle condition might change by any interrupt posting +// an event. QV_onIdle() must internally enable interrupts, ideally +// atomically with putting the CPU to the power-saving mode. +// +// NOTE2: +// One of the LEDs is used to visualize the idle loop activity. The brightness +// of the LED is proportional to the frequency of invcations of the idle loop. +// Please note that the LED is toggled with interrupts locked, so no interrupt +// execution time contributes to the brightness of the User LED. +// diff --git a/examples/arm-cr/dpp_launchxl2-tms57012/qv/iar/dpp-qv.ewd b/examples/arm-cr/dpp_launchxl2-tms57012/qv/iar/dpp-qv.ewd index 55042ab7..05b9e883 100644 --- a/examples/arm-cr/dpp_launchxl2-tms57012/qv/iar/dpp-qv.ewd +++ b/examples/arm-cr/dpp_launchxl2-tms57012/qv/iar/dpp-qv.ewd @@ -1,4900 +1,4654 @@ - - + - 2 - - Debug - - ARM - - 1 - - C-SPY - 2 - - 28 - 1 + 3 + + Debug + + ARM + 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ARMSIM_ID - 2 - - 1 - 1 - 1 - - - - - - - - ANGEL_ID - 2 - - 0 - 1 - 1 - - - - - - - - - - - - CADI_ID - 2 - - 0 - 1 - 1 - - - - - - - - - CMSISDAP_ID - 2 - - 4 - 1 - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - GDBSERVER_ID - 2 - - 0 - 1 - 1 - - - - - - - - - - - IARROM_ID - 2 - - 1 - 1 - 1 - - - - - - - - - IJET_ID - 2 - - 8 - 1 - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - JLINK_ID - 2 - - 16 - 1 - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - LMIFTDI_ID - 2 - - 2 - 1 - 1 - - - - - - - - - - MACRAIGOR_ID - 2 - - 3 - 1 - 1 - - - - - - - - - - - - - - - - - - - - - - - PEMICRO_ID - 2 - - 3 - 1 - 1 - - - - - - - - RDI_ID - 2 - - 2 - 1 - 1 - - - - - - - - - - - - - - - - STLINK_ID - 2 - - 3 - 1 - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - THIRDPARTY_ID - 2 - - 0 - 1 - 1 - - - - - - - - TIFET_ID - 2 - - 1 - 1 - 1 - - - - - - - - - - - - - - - - - - - XDS100_ID - 2 - - 5 - 1 - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - $TOOLKIT_DIR$\plugins\middleware\HCCWare\HCCWare.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\middleware\PercepioTraceExporter\PercepioTraceExportPlugin.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\AVIX\AVIX.ENU.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\CMX\CmxArmPlugin.ENU.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\CMX\CmxTinyArmPlugin.ENU.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\MQX\MQXRtosPlugin.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\Quadros\Quadros_EWB7_Plugin.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\SafeRTOS\SafeRTOSPlugin.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\TI-RTOS\tirtosplugin.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-286-KA-CSpy.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-KA-CSpy.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\uCOS-III\uCOS-III-KA-CSpy.ewplugin - 0 - - - $EW_DIR$\common\plugins\CodeCoverage\CodeCoverage.ENU.ewplugin - 1 - - - $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin - 0 - - - $EW_DIR$\common\plugins\uCProbe\uCProbePlugin.ENU.ewplugin - 0 - - - - - Release - - ARM - - 0 - - C-SPY - 2 - - 28 - 1 + + C-SPY + 2 + + 32 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ARMSIM_ID + 2 + + 1 + 1 + 1 + + + + + + + + CADI_ID + 2 + + 0 + 1 + 1 + + + + + + + + + CMSISDAP_ID + 2 + + 4 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + GDBSERVER_ID + 2 + + 0 + 1 + 1 + + + + + + + + + + + IJET_ID + 2 + + 9 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + JLINK_ID + 2 + + 16 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + LMIFTDI_ID + 2 + + 3 + 1 + 1 + + + + + + + + + + + + + NULINK_ID + 2 + + 0 + 1 + 1 + + + + + + + PEMICRO_ID + 2 + + 3 + 1 + 1 + + + + + + + + STLINK_ID + 2 + + 8 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + THIRDPARTY_ID + 2 + + 0 + 1 + 1 + + + + + + + + TIFET_ID + 2 + + 1 + 1 + 1 + + + + + + + + + + + + + + + + + + + XDS100_ID + 2 + + 9 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + $TOOLKIT_DIR$\plugins\rtos\CMX\CmxArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\CMX\CmxTinyArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\FreeRtos\FreeRtosArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin2.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SafeRTOS\SafeRTOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9BE.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-286-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-III\uCOS-III-KA-CSpy.ewplugin + 0 + + + $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\TargetAccessServer\TargetAccessServer.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\uCProbe\uCProbePlugin.ENU.ewplugin + 0 + + + + + Release + + ARM + 0 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ARMSIM_ID - 2 - - 1 - 1 - 0 - - - - - - - - ANGEL_ID - 2 - - 0 - 1 - 0 - - - - - - - - - - - - CADI_ID - 2 - - 0 - 1 - 0 - - - - - - - - - CMSISDAP_ID - 2 - - 4 - 1 - 0 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - GDBSERVER_ID - 2 - - 0 - 1 - 0 - - - - - - - - - - - IARROM_ID - 2 - - 1 - 1 - 0 - - - - - - - - - IJET_ID - 2 - - 8 - 1 - 0 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - JLINK_ID - 2 - - 16 - 1 - 0 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - LMIFTDI_ID - 2 - - 2 - 1 - 0 - - - - - - - - - - MACRAIGOR_ID - 2 - - 3 - 1 - 0 - - - - - - - - - - - - - - - - - - - - - - - PEMICRO_ID - 2 - - 3 - 1 - 0 - - - - - - - - RDI_ID - 2 - - 2 - 1 - 0 - - - - - - - - - - - - - - - - STLINK_ID - 2 - - 3 - 1 - 0 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - THIRDPARTY_ID - 2 - - 0 - 1 - 0 - - - - - - - - TIFET_ID - 2 - - 1 - 1 - 0 - - - - - - - - - - - - - - - - - - - XDS100_ID - 2 - - 5 - 1 - 0 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - $TOOLKIT_DIR$\plugins\middleware\HCCWare\HCCWare.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\middleware\PercepioTraceExporter\PercepioTraceExportPlugin.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\AVIX\AVIX.ENU.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\CMX\CmxArmPlugin.ENU.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\CMX\CmxTinyArmPlugin.ENU.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\MQX\MQXRtosPlugin.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\Quadros\Quadros_EWB7_Plugin.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\SafeRTOS\SafeRTOSPlugin.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\TI-RTOS\tirtosplugin.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-286-KA-CSpy.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-KA-CSpy.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\uCOS-III\uCOS-III-KA-CSpy.ewplugin - 0 - - - $EW_DIR$\common\plugins\CodeCoverage\CodeCoverage.ENU.ewplugin - 1 - - - $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin - 0 - - - $EW_DIR$\common\plugins\uCProbe\uCProbePlugin.ENU.ewplugin - 0 - - - - - Spy - - ARM - - 1 - - C-SPY - 2 - - 28 - 1 + + C-SPY + 2 + + 32 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ARMSIM_ID + 2 + + 1 + 1 + 0 + + + + + + + + CADI_ID + 2 + + 0 + 1 + 0 + + + + + + + + + CMSISDAP_ID + 2 + + 4 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + GDBSERVER_ID + 2 + + 0 + 1 + 0 + + + + + + + + + + + IJET_ID + 2 + + 9 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + JLINK_ID + 2 + + 16 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + LMIFTDI_ID + 2 + + 3 + 1 + 0 + + + + + + + + + + + + + NULINK_ID + 2 + + 0 + 1 + 0 + + + + + + + PEMICRO_ID + 2 + + 3 + 1 + 0 + + + + + + + + STLINK_ID + 2 + + 8 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + THIRDPARTY_ID + 2 + + 0 + 1 + 0 + + + + + + + + TIFET_ID + 2 + + 1 + 1 + 0 + + + + + + + + + + + + + + + + + + + XDS100_ID + 2 + + 9 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + $TOOLKIT_DIR$\plugins\rtos\CMX\CmxArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\CMX\CmxTinyArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\FreeRtos\FreeRtosArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin2.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SafeRTOS\SafeRTOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9BE.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-286-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-III\uCOS-III-KA-CSpy.ewplugin + 0 + + + $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\TargetAccessServer\TargetAccessServer.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\uCProbe\uCProbePlugin.ENU.ewplugin + 0 + + + + + Spy + + ARM + 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ARMSIM_ID - 2 - - 1 - 1 - 1 - - - - - - - - ANGEL_ID - 2 - - 0 - 1 - 1 - - - - - - - - - - - - CADI_ID - 2 - - 0 - 1 - 1 - - - - - - - - - CMSISDAP_ID - 2 - - 4 - 1 - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - GDBSERVER_ID - 2 - - 0 - 1 - 1 - - - - - - - - - - - IARROM_ID - 2 - - 1 - 1 - 1 - - - - - - - - - IJET_ID - 2 - - 8 - 1 - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - JLINK_ID - 2 - - 16 - 1 - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - LMIFTDI_ID - 2 - - 2 - 1 - 1 - - - - - - - - - - MACRAIGOR_ID - 2 - - 3 - 1 - 1 - - - - - - - - - - - - - - - - - - - - - - - PEMICRO_ID - 2 - - 3 - 1 - 1 - - - - - - - - RDI_ID - 2 - - 2 - 1 - 1 - - - - - - - - - - - - - - - - STLINK_ID - 2 - - 3 - 1 - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - THIRDPARTY_ID - 2 - - 0 - 1 - 1 - - - - - - - - TIFET_ID - 2 - - 1 - 1 - 1 - - - - - - - - - - - - - - - - - - - XDS100_ID - 2 - - 5 - 1 - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - $TOOLKIT_DIR$\plugins\middleware\HCCWare\HCCWare.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\middleware\PercepioTraceExporter\PercepioTraceExportPlugin.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\AVIX\AVIX.ENU.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\CMX\CmxArmPlugin.ENU.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\CMX\CmxTinyArmPlugin.ENU.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\MQX\MQXRtosPlugin.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\Quadros\Quadros_EWB7_Plugin.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\SafeRTOS\SafeRTOSPlugin.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\TI-RTOS\tirtosplugin.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-286-KA-CSpy.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-KA-CSpy.ewplugin - 0 - - - $TOOLKIT_DIR$\plugins\rtos\uCOS-III\uCOS-III-KA-CSpy.ewplugin - 0 - - - $EW_DIR$\common\plugins\CodeCoverage\CodeCoverage.ENU.ewplugin - 1 - - - $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin - 0 - - - $EW_DIR$\common\plugins\uCProbe\uCProbePlugin.ENU.ewplugin - 0 - - - + + C-SPY + 2 + + 32 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ARMSIM_ID + 2 + + 1 + 1 + 1 + + + + + + + + CADI_ID + 2 + + 0 + 1 + 1 + + + + + + + + + CMSISDAP_ID + 2 + + 4 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + GDBSERVER_ID + 2 + + 0 + 1 + 1 + + + + + + + + + + + IJET_ID + 2 + + 9 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + JLINK_ID + 2 + + 16 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + LMIFTDI_ID + 2 + + 3 + 1 + 1 + + + + + + + + + + + + + NULINK_ID + 2 + + 0 + 1 + 1 + + + + + + + PEMICRO_ID + 2 + + 3 + 1 + 1 + + + + + + + + STLINK_ID + 2 + + 8 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + THIRDPARTY_ID + 2 + + 0 + 1 + 1 + + + + + + + + TIFET_ID + 2 + + 1 + 1 + 1 + + + + + + + + + + + + + + + + + + + XDS100_ID + 2 + + 9 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + $TOOLKIT_DIR$\plugins\rtos\CMX\CmxArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\CMX\CmxTinyArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\FreeRtos\FreeRtosArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin2.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SafeRTOS\SafeRTOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9BE.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-286-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-III\uCOS-III-KA-CSpy.ewplugin + 0 + + + $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\TargetAccessServer\TargetAccessServer.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\uCProbe\uCProbePlugin.ENU.ewplugin + 0 + + + - - diff --git a/examples/arm-cr/dpp_launchxl2-tms57012/qv/iar/dpp-qv.ewp b/examples/arm-cr/dpp_launchxl2-tms57012/qv/iar/dpp-qv.ewp index 4b1fcc57..d79bf960 100644 --- a/examples/arm-cr/dpp_launchxl2-tms57012/qv/iar/dpp-qv.ewp +++ b/examples/arm-cr/dpp_launchxl2-tms57012/qv/iar/dpp-qv.ewp @@ -1,3068 +1,3397 @@ - - + - 2 - - Debug - - ARM - - 1 - - General - 3 - - 24 - 1 + 3 + + Debug + + ARM + 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ICCARM - 2 - - 31 - 1 - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - AARM - 2 - - 9 - 1 - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - OBJCOPY - 0 - - 1 - 1 - 1 - - - - - - - - - CUSTOM - 3 - - - - 0 - - - - BICOMP - 0 - - - - BUILDACTION - 1 - - cmd /c "if exist $OBJ_DIR$\qstamp.o del $OBJ_DIR$\qstamp.o" - - - - - ILINK - 0 - - 17 - 1 - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - IARCHIVE - 0 - - 0 - 1 - 1 - - - - - - - BILINK - 0 - - - - Coder - 0 - - - - - Release - - ARM - - 0 - - General - 3 - - 24 - 1 + + General + 3 + + 35 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ICCARM + 2 + + 37 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + AARM + 2 + + 11 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + OBJCOPY + 0 + + 1 + 1 + 1 + + + + + + + + + CUSTOM + 3 + + + + 0 + inputOutputBased + + + + BUILDACTION + 1 + + cmd /c "if exist $OBJ_DIR$\qstamp.o del $OBJ_DIR$\qstamp.o" + + + + + ILINK + 0 + + 27 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + IARCHIVE + 0 + + 0 + 1 + 1 + + + + + + + Coder + 0 + + + + + Release + + ARM + 0 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ICCARM - 2 - - 31 - 1 - 0 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - AARM - 2 - - 9 - 1 - 0 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - OBJCOPY - 0 - - 1 - 1 - 0 - - - - - - - - - CUSTOM - 3 - - - - 0 - - - - BICOMP - 0 - - - - BUILDACTION - 1 - - cmd /c "if exist $OBJ_DIR$\qstamp.o del $OBJ_DIR$\qstamp.o" - - - - - ILINK - 0 - - 17 - 1 - 0 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - IARCHIVE - 0 - - 0 - 1 - 0 - - - - - - - BILINK - 0 - - - - Coder - 0 - - - - - Spy - - ARM - - 1 - - General - 3 - - 24 - 1 + + General + 3 + + 35 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ICCARM + 2 + + 37 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + AARM + 2 + + 11 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + OBJCOPY + 0 + + 1 + 1 + 0 + + + + + + + + + CUSTOM + 3 + + + + 0 + inputOutputBased + + + + BUILDACTION + 1 + + cmd /c "if exist $OBJ_DIR$\qstamp.o del $OBJ_DIR$\qstamp.o" + + + + + ILINK + 0 + + 27 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + IARCHIVE + 0 + + 0 + 1 + 0 + + + + + + + Coder + 0 + + + + + Spy + + ARM + 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ICCARM - 2 - - 31 - 1 - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - AARM - 2 - - 9 - 1 - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - OBJCOPY - 0 - - 1 - 1 - 1 - - - - - - - - - CUSTOM - 3 - - - - 0 - - - - BICOMP - 0 - - - - BUILDACTION - 1 - - cmd /c "if exist $OBJ_DIR$\qstamp.o del $OBJ_DIR$\qstamp.o" - - - - - ILINK - 0 - - 17 - 1 - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - IARCHIVE - 0 - - 0 - 1 - 1 - - - - - - - BILINK - 0 - - - - Coder - 0 - - - - - Application - - $PROJ_DIR$\..\bsp.c - - - $PROJ_DIR$\..\..\bsp.h - - - $PROJ_DIR$\..\..\dpp.h - - - $PROJ_DIR$\..\main.c - - - $PROJ_DIR$\..\..\philo.c - - - $PROJ_DIR$\..\..\..\..\..\include\qstamp.c - - - $PROJ_DIR$\..\..\table.c - - - - launchxl2-tms57012 - - $PROJ_DIR$\..\..\..\..\..\3rd_party\launchxl2-tms57012\iar\source\dabort.asm - - - $PROJ_DIR$\..\..\..\..\..\3rd_party\launchxl2-tms57012\iar\source\esm.c - - - $PROJ_DIR$\..\..\..\..\..\3rd_party\launchxl2-tms57012\iar\source\exceptions.c - - - $PROJ_DIR$\..\..\..\..\..\3rd_party\launchxl2-tms57012\iar\source\gio.c - - - $PROJ_DIR$\..\..\..\..\..\3rd_party\launchxl2-tms57012\iar\source\notification.c - - - $PROJ_DIR$\..\..\..\..\..\3rd_party\launchxl2-tms57012\iar\source\pinmux.c - - - $PROJ_DIR$\..\..\..\..\..\3rd_party\launchxl2-tms57012\iar\source\rti.c - - - $PROJ_DIR$\..\..\..\..\..\3rd_party\launchxl2-tms57012\iar\source\sci.c - - - $PROJ_DIR$\..\..\..\..\..\3rd_party\launchxl2-tms57012\iar\source\sys_core.asm - - - $PROJ_DIR$\..\..\..\..\..\3rd_party\launchxl2-tms57012\iar\source\sys_intvecs.asm - - - $PROJ_DIR$\..\..\..\..\..\3rd_party\launchxl2-tms57012\iar\source\sys_mpu.asm - - - $PROJ_DIR$\..\..\..\..\..\3rd_party\launchxl2-tms57012\iar\source\sys_phantom.c - - - $PROJ_DIR$\..\..\..\..\..\3rd_party\launchxl2-tms57012\iar\source\sys_pmu.asm - - - $PROJ_DIR$\..\..\..\..\..\3rd_party\launchxl2-tms57012\iar\source\sys_selftest.c - - - $PROJ_DIR$\..\..\..\..\..\3rd_party\launchxl2-tms57012\iar\source\sys_startup.c - - - $PROJ_DIR$\..\..\..\..\..\3rd_party\launchxl2-tms57012\iar\source\sys_vim.c - - - $PROJ_DIR$\..\..\..\..\..\3rd_party\launchxl2-tms57012\iar\source\system.c - - - - QP - - $PROJ_DIR$\..\..\..\..\..\src\qf\qep_hsm.c - - - $PROJ_DIR$\..\..\..\..\..\src\qf\qep_msm.c - - - $PROJ_DIR$\..\..\..\..\..\src\qf\qf_act.c - - - $PROJ_DIR$\..\..\..\..\..\src\qf\qf_actq.c - - - $PROJ_DIR$\..\..\..\..\..\src\qf\qf_defer.c - - - $PROJ_DIR$\..\..\..\..\..\src\qf\qf_dyn.c - - - $PROJ_DIR$\..\..\..\..\..\src\qf\qf_mem.c - - - $PROJ_DIR$\..\..\..\..\..\src\qf_pkg.h - - - $PROJ_DIR$\..\..\..\..\..\src\qf\qf_ps.c - - - $PROJ_DIR$\..\..\..\..\..\src\qf\qf_qact.c - - - $PROJ_DIR$\..\..\..\..\..\src\qf\qf_qeq.c - - - $PROJ_DIR$\..\..\..\..\..\src\qf\qf_qmact.c - - - $PROJ_DIR$\..\..\..\..\..\src\qf\qf_time.c - - - $PROJ_DIR$\..\..\..\..\..\src\qv\qv.c - - - - QP_port - - $PROJ_DIR$\..\..\..\..\..\ports\arm-cr\qv\iar\qep_port.h - - - $PROJ_DIR$\..\..\..\..\..\ports\arm-cr\qv\iar\qf_port.h - - - $PROJ_DIR$\..\..\..\..\..\ports\arm-cr\qv\iar\qv_port.h - - - $PROJ_DIR$\..\..\..\..\..\ports\arm-cr\qv\iar\qs_port.h - - - - QS - - Debug - Release - - - $PROJ_DIR$\..\..\..\..\..\src\qs\qs.c - - - $PROJ_DIR$\..\..\..\..\..\src\qs\qs_fp.c - - - $PROJ_DIR$\..\..\..\..\..\src\qs_pkg.h - - - $PROJ_DIR$\..\..\..\..\..\src\qs\qs_rx.c - - + + General + 3 + + 35 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ICCARM + 2 + + 37 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + AARM + 2 + + 11 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + OBJCOPY + 0 + + 1 + 1 + 1 + + + + + + + + + CUSTOM + 3 + + + + 0 + inputOutputBased + + + + BUILDACTION + 1 + + cmd /c "if exist $OBJ_DIR$\qstamp.o del $OBJ_DIR$\qstamp.o" + + + + + ILINK + 0 + + 27 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + IARCHIVE + 0 + + 0 + 1 + 1 + + + + + + + Coder + 0 + + + + + Application + + $PROJ_DIR$\..\bsp.c + + + $PROJ_DIR$\..\..\bsp.h + + + $PROJ_DIR$\..\..\dpp.h + + + $PROJ_DIR$\..\..\main.c + + + $PROJ_DIR$\..\..\philo.c + + + $PROJ_DIR$\..\..\table.c + + + + launchxl2-tms57012 + + $PROJ_DIR$\..\..\..\..\..\3rd_party\launchxl2-tms57012\iar\source\dabort.asm + + + $PROJ_DIR$\..\..\..\..\..\3rd_party\launchxl2-tms57012\iar\source\esm.c + + + $PROJ_DIR$\..\..\..\..\..\3rd_party\launchxl2-tms57012\iar\source\exceptions.c + + + $PROJ_DIR$\..\..\..\..\..\3rd_party\launchxl2-tms57012\iar\source\gio.c + + + $PROJ_DIR$\..\..\..\..\..\3rd_party\launchxl2-tms57012\iar\source\notification.c + + + $PROJ_DIR$\..\..\..\..\..\3rd_party\launchxl2-tms57012\iar\source\pinmux.c + + + $PROJ_DIR$\..\..\..\..\..\3rd_party\launchxl2-tms57012\iar\source\rti.c + + + $PROJ_DIR$\..\..\..\..\..\3rd_party\launchxl2-tms57012\iar\source\sci.c + + + $PROJ_DIR$\..\..\..\..\..\3rd_party\launchxl2-tms57012\iar\source\sys_core.asm + + + $PROJ_DIR$\..\..\..\..\..\3rd_party\launchxl2-tms57012\iar\source\sys_intvecs.asm + + + $PROJ_DIR$\..\..\..\..\..\3rd_party\launchxl2-tms57012\iar\source\sys_mpu.asm + + + $PROJ_DIR$\..\..\..\..\..\3rd_party\launchxl2-tms57012\iar\source\sys_phantom.c + + + $PROJ_DIR$\..\..\..\..\..\3rd_party\launchxl2-tms57012\iar\source\sys_pmu.asm + + + $PROJ_DIR$\..\..\..\..\..\3rd_party\launchxl2-tms57012\iar\source\sys_selftest.c + + + $PROJ_DIR$\..\..\..\..\..\3rd_party\launchxl2-tms57012\iar\source\sys_startup.c + + + $PROJ_DIR$\..\..\..\..\..\3rd_party\launchxl2-tms57012\iar\source\sys_vim.c + + + $PROJ_DIR$\..\..\..\..\..\3rd_party\launchxl2-tms57012\iar\source\system.c + + + + QP + + $PROJ_DIR$\..\..\..\..\..\src\qf\qep_hsm.c + + + $PROJ_DIR$\..\..\..\..\..\src\qf\qep_msm.c + + + $PROJ_DIR$\..\..\..\..\..\src\qf\qf_act.c + + + $PROJ_DIR$\..\..\..\..\..\src\qf\qf_actq.c + + + $PROJ_DIR$\..\..\..\..\..\src\qf\qf_defer.c + + + $PROJ_DIR$\..\..\..\..\..\src\qf\qf_dyn.c + + + $PROJ_DIR$\..\..\..\..\..\src\qf\qf_mem.c + + + $PROJ_DIR$\..\..\..\..\..\src\qf_pkg.h + + + $PROJ_DIR$\..\..\..\..\..\src\qf\qf_ps.c + + + $PROJ_DIR$\..\..\..\..\..\src\qf\qf_qact.c + + + $PROJ_DIR$\..\..\..\..\..\src\qf\qf_qeq.c + + + $PROJ_DIR$\..\..\..\..\..\src\qf\qf_qmact.c + + + $PROJ_DIR$\..\..\..\..\..\src\qf\qf_time.c + + + $PROJ_DIR$\..\..\..\..\..\src\qv\qv.c + + + + QP_port + + $PROJ_DIR$\..\..\..\..\..\ports\arm-cr\qv\iar\qep_port.h + + + $PROJ_DIR$\..\..\..\..\..\ports\arm-cr\qv\iar\qf_port.h + + + $PROJ_DIR$\..\..\..\..\..\ports\arm-cr\qv\iar\qs_port.h + + + $PROJ_DIR$\..\..\..\..\..\ports\arm-cr\qv\iar\qv_port.h + + + + QS + + Debug + Release + + + $PROJ_DIR$\..\..\..\..\..\src\qs\qs.c + + + $PROJ_DIR$\..\..\..\..\..\src\qs\qs_fp.c + + + $PROJ_DIR$\..\..\..\..\..\src\qs\qs_rx.c + + + $PROJ_DIR$\..\..\..\..\..\src\qs\qstamp.c + + - - diff --git a/examples/arm-cr/dpp_launchxl2-tms57012/qv/main.c b/examples/arm-cr/dpp_launchxl2-tms57012/qv/main.c deleted file mode 100644 index 7047b71b..00000000 --- a/examples/arm-cr/dpp_launchxl2-tms57012/qv/main.c +++ /dev/null @@ -1,80 +0,0 @@ -/***************************************************************************** -* Product: DPP example -* Last updated for version 6.4.0 -* Last updated on 2019-02-08 -* -* Q u a n t u m L e a P s -* ------------------------ -* Modern Embedded Software -* -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* -* -*****************************************************************************/ -#include "qpc.h" -#include "dpp.h" -#include "bsp.h" - -Q_DEFINE_THIS_FILE - -/*..........................................................................*/ -int main() { - static QEvt const *tableQueueSto[N_PHILO]; - static QEvt const *philoQueueSto[N_PHILO][N_PHILO]; - static QSubscrList subscrSto[MAX_PUB_SIG]; - static QF_MPOOL_EL(TableEvt) smlPoolSto[2*N_PHILO]; /* small pool */ - uint8_t n; - - Philo_ctor(); /* instantiate all Philosopher active objects */ - Table_ctor(); /* instantiate the Table active object */ - - QF_init(); /* initialize the framework and the underlying RT kernel */ - BSP_init(); /* initialize the Board Support Package */ - - /* initialize publish-subscribe... */ - QF_psInit(subscrSto, Q_DIM(subscrSto)); - - /* initialize event pools... */ - QF_poolInit(smlPoolSto, sizeof(smlPoolSto), sizeof(smlPoolSto[0])); - - /* start the active objects... */ - for (n = 0U; n < N_PHILO; ++n) { - QACTIVE_START(AO_Philo[n], /* AO to start */ - (uint_fast8_t)(n + 1), /* QP priority of the AO */ - philoQueueSto[n], /* event queue storage */ - Q_DIM(philoQueueSto[n]), /* queue length [events] */ - (void *)0, /* stack storage (not used) */ - 0U, /* size of the stack [bytes] */ - (QEvt *)0); /* initialization event */ - } - QACTIVE_START(AO_Table, /* AO to start */ - (uint_fast8_t)(N_PHILO + 1), /* QP priority of the AO */ - tableQueueSto, /* event queue storage */ - Q_DIM(tableQueueSto), /* queue length [events] */ - (void *)0, /* stack storage (not used) */ - 0U, /* size of the stack [bytes] */ - (QEvt *)0); /* initialization event */ - - return QF_run(); /* run the QF application */ -} - diff --git a/examples/arm-cr/dpp_launchxl2-tms57012/qv/ti/.cproject b/examples/arm-cr/dpp_launchxl2-tms57012/qv/ti/.cproject index 83c3e740..3bee61ad 100644 --- a/examples/arm-cr/dpp_launchxl2-tms57012/qv/ti/.cproject +++ b/examples/arm-cr/dpp_launchxl2-tms57012/qv/ti/.cproject @@ -15,81 +15,89 @@ - - - - @@ -113,59 +121,64 @@ - - @@ -189,70 +202,75 @@ - - @@ -278,4 +296,5 @@ - + + \ No newline at end of file diff --git a/examples/arm-cr/dpp_launchxl2-tms57012/qv/ti/.project b/examples/arm-cr/dpp_launchxl2-tms57012/qv/ti/.project index e93a4299..201e4be4 100644 --- a/examples/arm-cr/dpp_launchxl2-tms57012/qv/ti/.project +++ b/examples/arm-cr/dpp_launchxl2-tms57012/qv/ti/.project @@ -63,18 +63,13 @@ main.c 1 - PARENT-1-PROJECT_LOC/main.c + PARENT-2-PROJECT_LOC/main.c philo.c 1 PARENT-2-PROJECT_LOC/philo.c - - qstamp.c - 1 - PARENT-5-PROJECT_LOC/include/qstamp.c - table.c 1 diff --git a/examples/arm-cr/dpp_launchxl2-tms57012/table.c b/examples/arm-cr/dpp_launchxl2-tms57012/table.c index edfc073a..c3ae02f0 100644 --- a/examples/arm-cr/dpp_launchxl2-tms57012/table.c +++ b/examples/arm-cr/dpp_launchxl2-tms57012/table.c @@ -1,124 +1,130 @@ -/*$file${.::table.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* -* Model: dpp.qm -* File: ${.::table.c} -* -* This code has been generated by QM 5.2.4 . -* DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. -* -* SPDX-License-Identifier: GPL-3.0-or-later -* -* This generated code is open source software: you can redistribute it under -* the terms of the GNU General Public License as published by the Free -* Software Foundation. -* -* This code is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -* more details. -* -* NOTE: -* Alternatively, this generated code may be distributed under the terms -* of Quantum Leaps commercial licenses, which expressly supersede the GNU -* General Public License and are specifically designed for licensees -* interested in retaining the proprietary status of their code. -* -* Contact information: -* -* -*/ -/*$endhead${.::table.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -#include "qpc.h" -#include "dpp.h" -#include "bsp.h" +//$file${.::table.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// +// Model: dpp.qm +// File: ${.::table.c} +// +// This code has been generated by QM 5.3.0 . +// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. +// +// SPDX-License-Identifier: GPL-3.0-or-later +// +// This generated code is open source software: you can redistribute it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation. +// +// This code is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// NOTE: +// Alternatively, this generated code may be distributed under the terms +// of Quantum Leaps commercial licenses, which expressly supersede the GNU +// General Public License and are specifically designed for licensees +// interested in retaining the proprietary status of their code. +// +// Contact information: +// +// +// +//$endhead${.::table.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +#include "qpc.h" // QP/C real-time embedded framework +#include "dpp.h" // DPP Application interface +#include "bsp.h" // Board Support Package -Q_DEFINE_THIS_FILE +//$declare${AOs::Table} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/* Active object class -----------------------------------------------------*/ -/*$declare${AOs::Table} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${AOs::Table} ............................................................*/ +//${AOs::Table} .............................................................. typedef struct Table { -/* protected: */ +// protected: QActive super; -/* public: */ - -/* private: */ +// private: uint8_t fork[N_PHILO]; - uint8_t isHungry[N_PHILO]; + bool isHungry[N_PHILO]; + +// public: } Table; + extern Table Table_inst; -/* protected: */ +// protected: static QState Table_initial(Table * const me, void const * const par); static QState Table_active(Table * const me, QEvt const * const e); static QState Table_serving(Table * const me, QEvt const * const e); static QState Table_paused(Table * const me, QEvt const * const e); -/*$enddecl${AOs::Table} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$enddecl${AOs::Table} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -#define RIGHT(n_) ((uint8_t)(((n_) + (N_PHILO - 1U)) % N_PHILO)) -#define LEFT(n_) ((uint8_t)(((n_) + 1U) % N_PHILO)) -#define FREE ((uint8_t)0) -#define USED ((uint8_t)1) +//---------------------------------------------------------------------------- +Q_DEFINE_THIS_FILE -/*$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* Check for the minimum required QP version */ -#if (QP_VERSION < 700U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) -#error qpc version 7.0.0 or higher required +// helper function to provide the RIGHT neighbor of a Philo[n] +static inline uint8_t right(uint8_t const n) { + return (uint8_t)((n + (N_PHILO - 1U)) % N_PHILO); +} + +// helper function to provide the LEFT neighbor of a Philo[n] +static inline uint8_t left(uint8_t const n) { + return (uint8_t)((n + 1U) % N_PHILO); +} + +#define FREE ((uint8_t)0U) +#define USED ((uint8_t)1U) + +#define THINKING "thinking" +#define HUNGRY "hungry " +#define EATING "eating " + +//---------------------------------------------------------------------------- + +//$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// Check for the minimum required QP version +#if (QP_VERSION < 730U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) +#error qpc version 7.3.0 or higher required #endif -/*$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -/*$define${AOs::AO_Table} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//$define${Shared::Table_ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/*${AOs::AO_Table} .........................................................*/ -QActive * const AO_Table = &Table_inst.super; /* "opaque" pointer to Table AO */ -/*$enddef${AOs::AO_Table} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*$define${AOs::Table_ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${AOs::Table_ctor} .......................................................*/ +//${Shared::Table_ctor} ...................................................... void Table_ctor(void) { - Table *me = &Table_inst; - uint8_t n; - + Table * const me = &Table_inst; QActive_ctor(&me->super, Q_STATE_CAST(&Table_initial)); - - for (n = 0U; n < N_PHILO; ++n) { + for (uint8_t n = 0U; n < N_PHILO; ++n) { me->fork[n] = FREE; - me->isHungry[n] = 0U; + me->isHungry[n] = false; } } -/*$enddef${AOs::Table_ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*$define${AOs::Table} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//$enddef${Shared::Table_ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +//$define${Shared::AO_Table} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/*${AOs::Table} ............................................................*/ +//${Shared::AO_Table} ........................................................ +QActive * const AO_Table = &Table_inst.super; +//$enddef${Shared::AO_Table} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +//$define${AOs::Table} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${AOs::Table} .............................................................. Table Table_inst; -/*${AOs::Table::SM} ........................................................*/ +//${AOs::Table::SM} .......................................................... static QState Table_initial(Table * const me, void const * const par) { - /*${AOs::Table::SM::initial} */ - uint8_t n; - (void)par; /* unused parameter */ + //${AOs::Table::SM::initial} + Q_UNUSED_PAR(par); - QS_OBJ_DICTIONARY(&Table_inst); - - QS_SIG_DICTIONARY(DONE_SIG, (void *)0); /* global signals */ - QS_SIG_DICTIONARY(EAT_SIG, (void *)0); - QS_SIG_DICTIONARY(PAUSE_SIG, (void *)0); - QS_SIG_DICTIONARY(SERVE_SIG, (void *)0); - QS_SIG_DICTIONARY(TEST_SIG, (void *)0); - - QS_SIG_DICTIONARY(HUNGRY_SIG, me); /* signal just for Table */ + #ifdef Q_SPY + Table *Table_inst = me; + QS_OBJ_DICTIONARY(Table_inst); + #endif QActive_subscribe(&me->super, DONE_SIG); QActive_subscribe(&me->super, PAUSE_SIG); QActive_subscribe(&me->super, SERVE_SIG); QActive_subscribe(&me->super, TEST_SIG); - for (n = 0U; n < N_PHILO; ++n) { + for (uint8_t n = 0U; n < N_PHILO; ++n) { me->fork[n] = FREE; - me->isHungry[n] = 0U; - BSP_displayPhilStat(n, "thinking"); + me->isHungry[n] = false; + BSP_displayPhilStat(n, THINKING); } QS_FUN_DICTIONARY(&Table_active); @@ -128,16 +134,16 @@ static QState Table_initial(Table * const me, void const * const par) { return Q_TRAN(&Table_serving); } -/*${AOs::Table::SM::active} ................................................*/ +//${AOs::Table::SM::active} .................................................. static QState Table_active(Table * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${AOs::Table::SM::active::TEST} */ + //${AOs::Table::SM::active::TEST} case TEST_SIG: { status_ = Q_HANDLED(); break; } - /*${AOs::Table::SM::active::EAT} */ + //${AOs::Table::SM::active::EAT} case EAT_SIG: { Q_ERROR(); status_ = Q_HANDLED(); @@ -151,108 +157,119 @@ static QState Table_active(Table * const me, QEvt const * const e) { return status_; } -/*${AOs::Table::SM::active::serving} .......................................*/ +//${AOs::Table::SM::active::serving} ......................................... static QState Table_serving(Table * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${AOs::Table::SM::active::serving} */ + //${AOs::Table::SM::active::serving} case Q_ENTRY_SIG: { - uint8_t n; - for (n = 0U; n < N_PHILO; ++n) { /* give permissions to eat... */ - if ((me->isHungry[n] != 0U) - && (me->fork[LEFT(n)] == FREE) + // give permissions to eat... + for (uint8_t n = 0U; n < N_PHILO; ++n) { + if (me->isHungry[n] + && (me->fork[left(n)] == FREE) && (me->fork[n] == FREE)) { - TableEvt *te; - - me->fork[LEFT(n)] = USED; + me->fork[left(n)] = USED; me->fork[n] = USED; - te = Q_NEW(TableEvt, EAT_SIG); - te->philoNum = n; - QACTIVE_PUBLISH(&te->super, &me->super); - me->isHungry[n] = 0U; - BSP_displayPhilStat(n, "eating "); + #ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, EAT_SIG, n); + #else + TableEvt *pe = Q_NEW(TableEvt, EAT_SIG); + pe->philoId = n; + #endif + QACTIVE_PUBLISH(&pe->super, &me->super); + me->isHungry[n] = false; + BSP_displayPhilStat(n, EATING); } } status_ = Q_HANDLED(); break; } - /*${AOs::Table::SM::active::serving::HUNGRY} */ + //${AOs::Table::SM::active::serving::HUNGRY} case HUNGRY_SIG: { - uint8_t n, m; + uint8_t n = Q_EVT_CAST(TableEvt)->philoId; - n = Q_EVT_CAST(TableEvt)->philoNum; - /* phil ID must be in range and he must be not hungry */ - Q_ASSERT((n < N_PHILO) && (me->isHungry[n] == 0U)); + // phil ID must be in range and he must be not hungry + Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); - BSP_displayPhilStat(n, "hungry "); - m = LEFT(n); - /*${AOs::Table::SM::active::serving::HUNGRY::[bothfree]} */ + BSP_displayPhilStat(n, HUNGRY); + uint8_t m = left(n); + //${AOs::Table::SM::active::serving::HUNGRY::[bothfree]} if ((me->fork[m] == FREE) && (me->fork[n] == FREE)) { - TableEvt *pe; me->fork[m] = USED; me->fork[n] = USED; - pe = Q_NEW(TableEvt, EAT_SIG); - pe->philoNum = n; + #ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, EAT_SIG, n); + #else + TableEvt *pe = Q_NEW(TableEvt, EAT_SIG); + pe->philoId = n; + #endif QACTIVE_PUBLISH(&pe->super, &me->super); - BSP_displayPhilStat(n, "eating "); + BSP_displayPhilStat(n, EATING); status_ = Q_HANDLED(); } - /*${AOs::Table::SM::active::serving::HUNGRY::[else]} */ + //${AOs::Table::SM::active::serving::HUNGRY::[else]} else { - me->isHungry[n] = 1U; + me->isHungry[n] = true; status_ = Q_HANDLED(); } break; } - /*${AOs::Table::SM::active::serving::DONE} */ + //${AOs::Table::SM::active::serving::DONE} case DONE_SIG: { - uint8_t n, m; - TableEvt *pe; + uint8_t n = Q_EVT_CAST(TableEvt)->philoId; - n = Q_EVT_CAST(TableEvt)->philoNum; - /* phil ID must be in range and he must be not hungry */ - Q_ASSERT((n < N_PHILO) && (me->isHungry[n] == 0U)); + // phil ID must be in range and he must be not hungry + Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); - BSP_displayPhilStat(n, "thinking"); - m = LEFT(n); - /* both forks of Phil[n] must be used */ + BSP_displayPhilStat(n, THINKING); + uint8_t m = left(n); + + // both forks of Phil[n] must be used Q_ASSERT((me->fork[n] == USED) && (me->fork[m] == USED)); me->fork[m] = FREE; me->fork[n] = FREE; - m = RIGHT(n); /* check the right neighbor */ + m = right(n); // check the right neighbor - if ((me->isHungry[m] != 0U) && (me->fork[m] == FREE)) { + if (me->isHungry[m] && (me->fork[m] == FREE)) { me->fork[n] = USED; me->fork[m] = USED; - me->isHungry[m] = 0U; - pe = Q_NEW(TableEvt, EAT_SIG); - pe->philoNum = m; + me->isHungry[m] = false; + #ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, EAT_SIG, m); + #else + TableEvt *pe = Q_NEW(TableEvt, EAT_SIG); + pe->philoId = m; + #endif QACTIVE_PUBLISH(&pe->super, &me->super); - BSP_displayPhilStat(m, "eating "); + BSP_displayPhilStat(m, EATING); } - m = LEFT(n); /* check the left neighbor */ - n = LEFT(m); /* left fork of the left neighbor */ - if ((me->isHungry[m] != 0U) && (me->fork[n] == FREE)) { + m = left(n); // check the left neighbor + n = left(m); // left fork of the left neighbor + if (me->isHungry[m] && (me->fork[n] == FREE)) { me->fork[m] = USED; me->fork[n] = USED; - me->isHungry[m] = 0U; - pe = Q_NEW(TableEvt, EAT_SIG); - pe->philoNum = m; + me->isHungry[m] = false; + #ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, EAT_SIG, m); + #else + TableEvt *pe = Q_NEW(TableEvt, EAT_SIG); + pe->philoId = m; + #endif QACTIVE_PUBLISH(&pe->super, &me->super); - BSP_displayPhilStat(m, "eating "); + BSP_displayPhilStat(m, EATING); } status_ = Q_HANDLED(); break; } - /*${AOs::Table::SM::active::serving::EAT} */ + //${AOs::Table::SM::active::serving::EAT} case EAT_SIG: { Q_ERROR(); status_ = Q_HANDLED(); break; } - /*${AOs::Table::SM::active::serving::PAUSE} */ + //${AOs::Table::SM::active::serving::PAUSE} case PAUSE_SIG: { status_ = Q_TRAN(&Table_paused); break; @@ -265,48 +282,50 @@ static QState Table_serving(Table * const me, QEvt const * const e) { return status_; } -/*${AOs::Table::SM::active::paused} ........................................*/ +//${AOs::Table::SM::active::paused} .......................................... static QState Table_paused(Table * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${AOs::Table::SM::active::paused} */ + //${AOs::Table::SM::active::paused} case Q_ENTRY_SIG: { BSP_displayPaused(1U); status_ = Q_HANDLED(); break; } - /*${AOs::Table::SM::active::paused} */ + //${AOs::Table::SM::active::paused} case Q_EXIT_SIG: { BSP_displayPaused(0U); status_ = Q_HANDLED(); break; } - /*${AOs::Table::SM::active::paused::SERVE} */ + //${AOs::Table::SM::active::paused::SERVE} case SERVE_SIG: { status_ = Q_TRAN(&Table_serving); break; } - /*${AOs::Table::SM::active::paused::HUNGRY} */ + //${AOs::Table::SM::active::paused::HUNGRY} case HUNGRY_SIG: { - uint8_t n = Q_EVT_CAST(TableEvt)->philoNum; - /* philo ID must be in range and he must be not hungry */ - Q_ASSERT((n < N_PHILO) && (me->isHungry[n] == 0U)); - me->isHungry[n] = 1U; - BSP_displayPhilStat(n, "hungry "); + uint8_t n = Q_EVT_CAST(TableEvt)->philoId; + + // philo ID must be in range and he must be not hungry + Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); + + me->isHungry[n] = true; + BSP_displayPhilStat(n, HUNGRY); status_ = Q_HANDLED(); break; } - /*${AOs::Table::SM::active::paused::DONE} */ + //${AOs::Table::SM::active::paused::DONE} case DONE_SIG: { - uint8_t n, m; + uint8_t n = Q_EVT_CAST(TableEvt)->philoId; - n = Q_EVT_CAST(TableEvt)->philoNum; - /* phil ID must be in range and he must be not hungry */ - Q_ASSERT((n < N_PHILO) && (me->isHungry[n] == 0U)); + // phil ID must be in range and he must be not hungry + Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); - BSP_displayPhilStat(n, "thinking"); - m = LEFT(n); - /* both forks of Phil[n] must be used */ + BSP_displayPhilStat(n, THINKING); + uint8_t m = left(n); + + // both forks of Phil[n] must be used Q_ASSERT((me->fork[n] == USED) && (me->fork[m] == USED)); me->fork[m] = FREE; @@ -321,4 +340,4 @@ static QState Table_paused(Table * const me, QEvt const * const e) { } return status_; } -/*$enddef${AOs::Table} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$enddef${AOs::Table} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/examples/embos/arm-cm/dpp_nucleo-h743zi/bsp.c b/examples/embos/arm-cm/dpp_nucleo-h743zi/bsp.c index e111ccc4..73f52da3 100644 --- a/examples/embos/arm-cm/dpp_nucleo-h743zi/bsp.c +++ b/examples/embos/arm-cm/dpp_nucleo-h743zi/bsp.c @@ -1,340 +1,389 @@ -/***************************************************************************** -* Product: "Dining Philosophers Problem" example, embOS kernel -* Last updated for: @ref qpc_7_0_0 -* Last updated on 2021-12-21 -* -* Q u a n t u m L e a P s -* ------------------------ -* Modern Embedded Software -* -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* -* -*****************************************************************************/ -#include "qpc.h" -#include "dpp.h" -#include "bsp.h" +//============================================================================ +// Product: "Dining Philosophers Problem" example, embOS kernel +// Last updated for: @ref qpc_7_3_0 +// Last updated on 2023-08-22 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// This program is open source software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Alternatively, this program may be distributed and modified under the +// terms of Quantum Leaps commercial licenses, which expressly supersede +// the GNU General Public License and are specifically designed for +// licensees interested in retaining the proprietary status of their code. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Contact information: +// +// +//============================================================================ +#include "qpc.h" // QP/C real-time embedded framework +#include "dpp.h" // DPP Application interface +#include "bsp.h" // Board Support Package -/* STM32CubeH7 include files */ +// STM32CubeH7 include files #include "stm32h7xx_hal.h" #include "stm32h7xx_nucleo_144.h" -/* add other drivers if necessary... */ +// add other drivers if necessary... Q_DEFINE_THIS_FILE -/* ISRs defined in this BSP ------------------------------------------------*/ +// ISRs defined in this BSP ------------------------------------------------ void SysTick_Handler(void); void USART3_IRQHandler(void); -/* Local-scope objects -----------------------------------------------------*/ -static uint32_t l_rnd; /* random seed */ +// Local-scope objects ----------------------------------------------------- +static uint32_t l_rnd; // random seed #ifdef Q_SPY - /* event-source identifiers used for tracing */ + + // QS source IDs static QSpyId const l_embos_ticker = { 0U }; + static UART_HandleTypeDef l_uartHandle; QSTimeCtr QS_tickTime_; QSTimeCtr QS_tickPeriod_; - /* QSpy source IDs */ - static QSpyId const l_SysTick_Handler = { 0U }; - static QSpyId const l_EXTI0_IRQHandler = { 0U }; - - static UART_HandleTypeDef l_uartHandle; - - enum AppRecords { /* application-specific trace records */ + enum AppRecords { // application-specific trace records PHILO_STAT = QS_USER, - COMMAND_STAT + PAUSED_STAT, }; + #endif -/* embOS application hooks =================================================*/ -static void tick_handler(void) { /* signature of embOS tick hook routine */ - /* state of the button debouncing, see below */ - static struct ButtonsDebouncing { +//============================================================================ +// Error handler + +Q_NORETURN Q_onError(char const * const module, int_t const id) { + // + // NOTE: add here your application-specific error handling + // + Q_UNUSED_PAR(module); + Q_UNUSED_PAR(id); + QS_ASSERTION(module, id, 10000U); // report assertion to QS + +#ifndef NDEBUG + BSP_LED_On(LED1); // turn LED on + BSP_LED_On(LED2); // turn LED on + BSP_LED_On(LED3); // turn LED on + // for debugging, hang on in an endless loop... + for (;;) { + } +#endif + + NVIC_SystemReset(); + for (;;) {} // explicitly no-retur +} +//............................................................................ +void assert_failed(char const * const module, int_t const id); // prototype +void assert_failed(char const * const module, int_t const id) { + Q_onError(module, id); +} + +// ISRs used in the application ========================================== +#ifdef Q_SPY + +// ISR for receiving bytes from the QSPY Back-End +// NOTE: This ISR is "QF-unaware" meaning that it does not interact with +// the QF/QK and is not disabled. Such ISRs don't need to call QK_ISR_ENTRY/ +// QK_ISR_EXIT and they cannot post or publish events. +// +void USART3_IRQHandler(void) { + // is RX register NOT empty? + if ((l_uartHandle.Instance->ISR & USART_ISR_RXNE_RXFNE) != 0U) { + uint32_t b = l_uartHandle.Instance->RDR; + QS_RX_PUT(b); + l_uartHandle.Instance->ISR &= ~USART_ISR_RXNE_RXFNE; // clear int. + } +} +#endif + +// embOS application hooks ================================================= +static void tick_handler(void) { // signature of embOS tick hook routine + // process time events at rate 0 + QTIMEEVT_TICK_X(0U, &l_embos_ticker); + + // Perform the debouncing of buttons. The algorithm for debouncing + // adapted from the book "Embedded Systems Dictionary" by Jack Ganssle + // and Michael Barr, page 71. + static struct { uint32_t depressed; uint32_t previous; } buttons = { 0U, 0U }; - uint32_t current; - uint32_t tmp; - static uint_fast8_t ctr = 1U; -#ifdef Q_SPY - { - tmp = SysTick->CTRL; /* clear SysTick_CTRL_COUNTFLAG */ - QS_tickTime_ += QS_tickPeriod_; /* account for the clock rollover */ - } -#endif + uint32_t current = BSP_PB_GetState(BUTTON_KEY); // read the Key button + uint32_t tmp = buttons.depressed; // save debounced depressed buttons + buttons.depressed |= (buttons.previous & current); // set depressed + buttons.depressed &= (buttons.previous | current); // clear released + buttons.previous = current; // update the history + tmp ^= buttons.depressed; // changed debounced depressed + current = buttons.depressed; - /* scale down the 1000Hz embOS tick to the desired BSP_TICKS_PER_SEC */ - if (--ctr == 0U) { - ctr = 1000U/BSP_TICKS_PER_SEC; - QTIMEEVT_TICK_X(0U, &l_embos_ticker); - - /* Perform the debouncing of buttons. The algorithm for debouncing - * adapted from the book "Embedded Systems Dictionary" by Jack Ganssle - * and Michael Barr, page 71. - */ - current = BSP_PB_GetState(BUTTON_KEY); /* read the Key button */ - tmp = buttons.depressed; /* save the debounced depressed buttons */ - buttons.depressed |= (buttons.previous & current); /* set depressed */ - buttons.depressed &= (buttons.previous | current); /* clear released */ - buttons.previous = current; /* update the history */ - tmp ^= buttons.depressed; /* changed debounced depressed */ - if (tmp != 0U) { /* debounced Key button state changed? */ - if (buttons.depressed != 0U) { /* PB0 depressed?*/ - static QEvt const pauseEvt = { PAUSE_SIG, 0U, 0U}; - QACTIVE_PUBLISH(&pauseEvt, &l_SysTick_Handler); - } - else { /* the button is released */ - static QEvt const serveEvt = { SERVE_SIG, 0U, 0U}; - QACTIVE_PUBLISH(&serveEvt, &l_SysTick_Handler); - } + if (tmp != 0U) { // debounced Key button state changed? + if (current != 0U) { // is PB0 depressed? + static QEvt const pauseEvt = QEVT_INITIALIZER(PAUSE_SIG); + QACTIVE_PUBLISH(&pauseEvt, &l_embos_ticker); + } + else { // the button is released + static QEvt const serveEvt = QEVT_INITIALIZER(SERVE_SIG); + QACTIVE_PUBLISH(&serveEvt, &l_embos_ticker); } } -} -/*..........................................................................*/ #ifdef Q_SPY -/* -* ISR for receiving bytes from the QSPY Back-End -* NOTE: This ISR is "QF-unaware" meaning that it does not interact with -* the QF/QK and is not disabled. Such ISRs don't need to call QK_ISR_ENTRY/ -* QK_ISR_EXIT and they cannot post or publish events. -*/ -void USART3_IRQHandler(void) { - /* is RX register NOT empty? */ - if ((l_uartHandle.Instance->ISR & USART_ISR_RXNE_RXFNE) != 0) { - uint32_t b = l_uartHandle.Instance->RDR; - QS_RX_PUT(b); - l_uartHandle.Instance->ISR &= ~USART_ISR_RXNE_RXFNE; /* clear int. */ - } -} + tmp = SysTick->CTRL; // clear SysTick_CTRL_COUNTFLAG + QS_tickTime_ += QS_tickPeriod_; // account for the clock rollover #endif +} -/*..........................................................................*/ -/* -* OS_Idle() function overridden from RTOSInit_STM32F4x_CMSIS.c -* -* Function description -* This is basically the "core" of the embOS idle loop. -* This core loop can be changed, but: -* The idle loop does not have a stack of its own, therefore no -* functionality should be implemented that relies on the stack -* to be preserved. However, a simple program loop can be programmed -* (like toggling an output or incrementing a counter) -*/ +//............................................................................ +// +// OS_Idle() function overridden from RTOSInit_STM32F4x_CMSIS.c +// +// Function description +// This is basically the "core" of the embOS idle loop. +// This core loop can be changed, but: +// The idle loop does not have a stack of its own, therefore no +// functionality should be implemented that relies on the stack +// to be preserved. However, a simple program loop can be programmed +// (like toggling an output or incrementing a counter) +// void OS_Idle(void) { while (1) { - /* toggle the User LED on and then off, see NOTE2 */ + // toggle the User LED on and then off, see NOTE2 QF_INT_DISABLE(); - BSP_LED_On (LED3); - BSP_LED_Off(LED3); + BSP_LED_On(LED3); QF_INT_ENABLE(); #ifdef Q_SPY - QS_rxParse(); /* parse all the received bytes */ - - if ((l_uartHandle.Instance->ISR & UART_FLAG_TXE) != 0U) { /* TXE empty? */ - uint16_t b; + QF_INT_DISABLE(); + QS_rxParse(); // parse all the received bytes + QF_INT_ENABLE(); + if ((l_uartHandle.Instance->ISR & UART_FLAG_TXE) != 0U) { // TXE empty? QF_INT_DISABLE(); - b = QS_getByte(); + uint16_t b = QS_getByte(); QF_INT_ENABLE(); - if (b != QS_EOD) { /* not End-Of-Data? */ - l_uartHandle.Instance->TDR = (b & 0xFFU); /* put into TDR */ + if (b != QS_EOD) { // not End-Of-Data? + l_uartHandle.Instance->TDR = (b & 0xFFU); // put into TDR } } #elif defined NDEBUG - /* Put the CPU and peripherals to the low-power mode. - * you might need to customize the clock management for your application, - * see the datasheet for your particular Cortex-M MCU. - */ - /* !!!CAUTION!!! - * The WFI instruction stops the CPU clock, which unfortunately disables - * the JTAG port, so the ST-Link debugger can no longer connect to the - * board. For that reason, the call to __WFI() has to be used with CAUTION. - * - * NOTE: If you find your board "frozen" like this, strap BOOT0 to VDD and - * reset the board, then connect with ST-Link Utilities and erase the part. - * The trick with BOOT(0) is it gets the part to run the System Loader - * instead of your broken code. When done disconnect BOOT0, and start over. - */ - //__WFI(); /* Wait-For-Interrupt */ -#elif defined NDEBUG - /* Put the CPU and peripherals to the low-power mode. - * NOTE: You might need to customize the clock management for your - * application, see the datasheet for your particular Cortex-M3 MCU. - */ - /* !!!CAUTION!!! - * The WFI instruction stops the CPU clock, which unfortunately - * disables the STM32 JTAG port, so the ST-Link debugger can no longer - * connect to the board. For that reason, the call to __WFI() has to - * be used with CAUTION. See also NOTE02 - */ -#if ((OS_VIEW_IFSELECT != OS_VIEW_IF_JLINK) && (OS_DEBUG == 0)) - //__WFI(); /* Wait-For-Interrupt */ -#endif + // Put the CPU and peripherals to the low-power mode. + // you might need to customize the clock management for your application, + // see the datasheet for your particular Cortex-M MCU. + // + // !!!CAUTION!!! + // The WFI instruction stops the CPU clock, which unfortunately disables + // the JTAG port, so the ST-Link debugger can no longer connect to the + // board. For that reason, the call to __WFI() has to be used with CAUTION. + // + // NOTE: If you find your board "frozen" like this, strap BOOT0 to VDD and + // reset the board, then connect with ST-Link Utilities and erase the part. + // The trick with BOOT(0) is it gets the part to run the System Loader + // instead of your broken code. When done disconnect BOOT0, and start over. + // + //__WFI(); // Wait-For-Interrupt #endif } } -/* BSP functions ===========================================================*/ +// BSP functions =========================================================== void BSP_init(void) { + // Configure the MPU to prevent NULL-pointer dereferencing ... + MPU->RBAR = 0x0U // base address (NULL) + | MPU_RBAR_VALID_Msk // valid region + | (MPU_RBAR_REGION_Msk & 7U); // region #7 + MPU->RASR = (7U << MPU_RASR_SIZE_Pos) // 2^(7+1) region + | (0x0U << MPU_RASR_AP_Pos) // no-access region + | MPU_RASR_ENABLE_Msk; // region enable + MPU->CTRL = MPU_CTRL_PRIVDEFENA_Msk // enable background region + | MPU_CTRL_ENABLE_Msk; // enable the MPU + __ISB(); + __DSB(); - /* NOTE: SystemInit() already called from the startup code - * but SystemCoreClock needs to be updated - */ + // enable the MemManage_Handler for MPU exception + SCB->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk; + + // NOTE: SystemInit() has been already called from the startup code + // but SystemCoreClock needs to be updated SystemCoreClockUpdate(); - SCB_EnableICache(); /* Enable I-Cache */ - SCB_EnableDCache(); /* Enable D-Cache */ + // NOTE: VFP (hardware Floating Point) unit is configured by embOS - /* Configure Flash prefetch and Instr. cache through ART accelerator */ + // enable clock for to the peripherals used by this application... + SCB_EnableICache(); // Enable I-Cache + SCB_EnableDCache(); // Enable D-Cache + + // configure Flash prefetch and Instr. cache through ART accelerator #if (ART_ACCLERATOR_ENABLE != 0) __HAL_FLASH_ART_ENABLE(); -#endif /* ART_ACCLERATOR_ENABLE */ +#endif // ART_ACCLERATOR_ENABLE - /* NOTE The VFP (Floating Point Unit) unit is configured by EROS */ - - /* Configure the LEDs */ + // Configure the LEDs BSP_LED_Init(LED1); BSP_LED_Init(LED2); BSP_LED_Init(LED3); - /* Configure the User Button in GPIO Mode */ + // configure the User Button in GPIO Mode BSP_PB_Init(BUTTON_KEY, BUTTON_MODE_GPIO); - //... + // seed the random number generator BSP_randomSeed(1234U); - /* initialize the QS software tracing... */ - if (QS_INIT((void *)0) == 0) { + // initialize the QS software tracing... + if (QS_INIT((void *)0) == 0U) { Q_ERROR(); } - QS_OBJ_DICTIONARY(&l_SysTick_Handler); - QS_OBJ_DICTIONARY(&l_EXTI0_IRQHandler); - QS_USR_DICTIONARY(PHILO_STAT); - QS_USR_DICTIONARY(COMMAND_STAT); - /* setup the QS filters... */ - QS_GLB_FILTER(QS_SM_RECORDS); - QS_GLB_FILTER(QS_UA_RECORDS); + // dictionaries... + QS_OBJ_DICTIONARY(&l_embos_ticker); + QS_USR_DICTIONARY(PHILO_STAT); + QS_USR_DICTIONARY(PAUSED_STAT); + + QS_ONLY(produce_sig_dict()); + + // setup the QS filters... + QS_GLB_FILTER(QS_ALL_RECORDS); // all records + QS_GLB_FILTER(-QS_QF_TICK); // exclude the clock tick } -/*..........................................................................*/ +//............................................................................ +void BSP_start(void) { + // initialize event pools + static QF_MPOOL_EL(TableEvt) smlPoolSto[2*N_PHILO]; + QF_poolInit(smlPoolSto, sizeof(smlPoolSto), sizeof(smlPoolSto[0])); + + // initialize publish-subscribe + static QSubscrList subscrSto[MAX_PUB_SIG]; + QActive_psInit(subscrSto, Q_DIM(subscrSto)); + + // instantiate and start AOs/threads... + + static QEvt const *philoQueueSto[N_PHILO][10]; + static OS_STACKPTR int philoStack[N_PHILO][128]; + for (uint8_t n = 0U; n < N_PHILO; ++n) { + Philo_ctor(n); + QACTIVE_START(AO_Philo[n], + n + 3U, // QF-prio. of the AO + philoQueueSto[n], // event queue storage + Q_DIM(philoQueueSto[n]), // queue length [events] + philoStack[n], // private stack for embOS + sizeof(philoStack[n]), // stack size [bytes] + (void *)0); // no initialization param + } + + static QEvt const *tableQueueSto[N_PHILO]; + static OS_STACKPTR int tableStack[128]; + Table_ctor(); + QACTIVE_START(AO_Table, + N_PHILO + 7U, // QP prio. of the AO + tableQueueSto, // event queue storage + Q_DIM(tableQueueSto), // queue length [events] + tableStack, // private stack for embOS + sizeof(tableStack), // stack size [bytes] + (void *)0); // no initialization param +} +//............................................................................ void BSP_displayPhilStat(uint8_t n, char const *stat) { (void)n; if (stat[0] == 'h') { - BSP_LED_On(LED1); /* turn LED on */ + BSP_LED_On(LED1); // turn LED on } else { - BSP_LED_Off(LED1); /* turn LED off */ + BSP_LED_Off(LED1); // turn LED off } if (stat[0] == 'e') { - BSP_LED_On(LED2); /* turn LED on */ + BSP_LED_On(LED2); // turn LED on } else { - BSP_LED_Off(LED2); /* turn LED on */ + BSP_LED_Off(LED2); // turn LED on } - QS_BEGIN_ID(PHILO_STAT, AO_Philo[n]->prio) /* app-specific record */ - QS_U8(1, n); /* Philosopher number */ - QS_STR(stat); /* Philosopher status */ - QS_END() /* application-specific record end */ + QS_BEGIN_ID(PHILO_STAT, AO_Philo[n]->prio) // app-specific record + QS_U8(1, n); // Philosopher number + QS_STR(stat); // Philosopher status + QS_END() } -/*..........................................................................*/ +//............................................................................ void BSP_displayPaused(uint8_t paused) { if (paused) { - BSP_LED_On(LED3); /* turn LED on */ + BSP_LED_On(LED3); // turn LED on } else { - BSP_LED_Off(LED3); /* turn LED on */ + BSP_LED_Off(LED3); // turn LED on } -} -/*..........................................................................*/ -uint32_t BSP_random(void) { /* a very cheap pseudo-random-number generator */ - uint32_t rnd; - /* exercise the FPU with some floating point computations */ - /* NOTE: this code can be only called from a task that created with - * the option OS_TASK_OPT_SAVE_FP. - */ + QS_BEGIN_ID(PAUSED_STAT, 0U) // app-specific record + QS_U8(1, paused); // Paused status + QS_END() +} +//............................................................................ +uint32_t BSP_random(void) { // a very cheap pseudo-random-number generator + // exercise the FPU with some floating point computations + // NOTE: this code can be only called from a task that created with + // the option OS_TASK_OPT_SAVE_FP. + // float volatile x = 3.1415926F; x = x + 2.7182818F; - /* "Super-Duper" Linear Congruential Generator (LCG) - * LCG(2^32, 3*7*11*13*23, 0, seed) - */ - rnd = l_rnd * (3U*7U*11U*13U*23U); - l_rnd = rnd; /* set for the next time */ + // "Super-Duper" Linear Congruential Generator (LCG) + // LCG(2^32, 3*7*11*13*23, 0, seed) + uint32_t rnd = l_rnd * (3U*7U*11U*13U*23U); + l_rnd = rnd; // set for the next time return (rnd >> 8); } -/*..........................................................................*/ +//............................................................................ void BSP_randomSeed(uint32_t seed) { l_rnd = seed; } -/*..........................................................................*/ +//............................................................................ void BSP_terminate(int16_t result) { (void)result; } -/* QF callbacks ============================================================*/ +// QF callbacks ============================================================ void QF_onStartup(void) { static OS_TICK_HOOK tick_hook; OS_TICK_AddHook(&tick_hook, &tick_handler); #ifdef Q_SPY - NVIC_SetPriority(USART3_IRQn, 0U); /* kernel unaware interrupt */ - NVIC_EnableIRQ(USART3_IRQn); /* UART interrupt used for QS-RX */ + NVIC_SetPriority(USART3_IRQn, 0U); // kernel unaware interrupt + NVIC_EnableIRQ(USART3_IRQn); // UART interrupt used for QS-RX #endif } -/*..........................................................................*/ +//............................................................................ void QF_onCleanup(void) { } -/*..........................................................................*/ -Q_NORETURN Q_onAssert(char const * const module, int_t const loc) { - /* - * NOTE: add here your application-specific error handling - */ - (void)module; - (void)loc; - QS_ASSERTION(module, loc, 10000U); /* report assertion to QS */ - NVIC_SystemReset(); -} - -/* QS callbacks ============================================================*/ +// QS callbacks ============================================================ #ifdef Q_SPY -/*..........................................................................*/ -uint8_t QS_onStartup(void const *arg) { - static uint8_t qsTxBuf[2*1024]; /* buffer for QS-TX channel */ - static uint8_t qsRxBuf[100]; /* buffer for QS-RX channel */ +//............................................................................ +uint8_t QS_onStartup(void const *arg) { + Q_UNUSED_PAR(arg); + + static uint8_t qsTxBuf[2*1024]; // buffer for QS-TX channel QS_initBuf (qsTxBuf, sizeof(qsTxBuf)); + + static uint8_t qsRxBuf[100]; // buffer for QS-RX channel QS_rxInitBuf(qsRxBuf, sizeof(qsRxBuf)); l_uartHandle.Instance = USART3; @@ -346,73 +395,80 @@ uint8_t QS_onStartup(void const *arg) { l_uartHandle.Init.Mode = UART_MODE_TX_RX; l_uartHandle.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT; if (HAL_UART_Init(&l_uartHandle) != HAL_OK) { - return 0U; /* return failure */ + return 0U; // return failure } - /* Set UART to receive 1 byte at a time via interrupt */ + // Set UART to receive 1 byte at a time via interrupt HAL_UART_Receive_IT(&l_uartHandle, (uint8_t *)qsRxBuf, 1); + // NOTE: wait till QF_onStartup() to enable UART interrupt in NVIC QS_tickPeriod_ = SystemCoreClock / BSP_TICKS_PER_SEC; - QS_tickTime_ = QS_tickPeriod_; /* to start the timestamp at zero */ + QS_tickTime_ = QS_tickPeriod_; // to start the timestamp at zero - return 1U; /* return success */ + return 1U; // return success } -/*..........................................................................*/ +//............................................................................ void QS_onCleanup(void) { } -/*..........................................................................*/ -QSTimeCtr QS_onGetTime(void) { /* NOTE: invoked with interrupts DISABLED */ - if ((SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk) == 0) { /* not set? */ +//............................................................................ +QSTimeCtr QS_onGetTime(void) { // NOTE: invoked with interrupts DISABLED + if ((SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk) == 0) { // not set? return QS_tickTime_ - (QSTimeCtr)SysTick->VAL; } - else { /* the rollover occured, but the SysTick_ISR did not run yet */ + else { // the rollover occured, but the SysTick_ISR did not run yet return QS_tickTime_ + QS_tickPeriod_ - (QSTimeCtr)SysTick->VAL; } } -/*..........................................................................*/ +//............................................................................ void QS_onFlush(void) { - uint16_t b; + while (true) { + // try to get next byte to transmit + QF_CRIT_STAT + QF_CRIT_ENTRY(); + uint16_t b = QS_getByte(); + QF_CRIT_EXIT(); - QF_INT_DISABLE(); - while ((b = QS_getByte()) != QS_EOD) { /* while not End-Of-Data... */ - QF_INT_ENABLE(); - /* while TXE not empty */ - while ((l_uartHandle.Instance->ISR & UART_FLAG_TXE) == 0U) { + if (b != QS_EOD) { // NOT end-of-data + // busy-wait as long as TXE not set + while ((l_uartHandle.Instance->ISR & UART_FLAG_TXE) == 0U) { + } + // place the byte in the UART TDR register + l_uartHandle.Instance->TDR = b; + } + else { + break; // break out of the loop } - l_uartHandle.Instance->TDR = (b & 0xFFU); /* put into TDR */ - QF_INT_DISABLE(); } - QF_INT_ENABLE(); } -/*..........................................................................*/ -/*! callback function to reset the target (to be implemented in the BSP) */ -_Noreturn void QS_onReset(void) { +//............................................................................ +//! callback function to reset the target (to be implemented in the BSP) +void QS_onReset(void) { NVIC_SystemReset(); } -/*..........................................................................*/ +//............................................................................ void QS_onCommand(uint8_t cmdId, uint32_t param1, uint32_t param2, uint32_t param3) { - (void)cmdId; - (void)param1; - (void)param2; - (void)param3; + Q_UNUSED_PAR(cmdId); + Q_UNUSED_PAR(param1); + Q_UNUSED_PAR(param2); + Q_UNUSED_PAR(param3); } -#endif /* Q_SPY */ -/*--------------------------------------------------------------------------*/ +#endif // Q_SPY +//---------------------------------------------------------------------------- -/***************************************************************************** -* NOTE01: -* One of the LEDs is used to visualize the idle loop activity. The brightness -* of the LED is proportional to the frequency of invcations of the idle loop. -* Please note that the LED is toggled with interrupts disabled, so no -* interrupt execution time contributes to the brightness of the LED. -* -* NOTE02: -* If you find your board "frozen" like this, strap BOOT0 to VDD and reset -* the board, then connect with ST-Link Utilities and erase the part. The -* trick with BOOT(0) is it gets the part to run the System Loader instead of -* your broken code. When done disconnect BOOT0, and start over. -*/ +//============================================================================ +// NOTE1: +// One of the LEDs is used to visualize the idle loop activity. The brightness +// of the LED is proportional to the frequency of invcations of the idle loop. +// Please note that the LED is toggled with interrupts disabled, so no +// interrupt execution time contributes to the brightness of the LED. +// +// NOTE2: +// If you find your board "frozen" like this, strap BOOT0 to VDD and reset +// the board, then connect with ST-Link Utilities and erase the part. The +// trick with BOOT(0) is it gets the part to run the System Loader instead of +// your broken code. When done disconnect BOOT0, and start over. +// diff --git a/examples/embos/arm-cm/dpp_nucleo-h743zi/bsp.h b/examples/embos/arm-cm/dpp_nucleo-h743zi/bsp.h index 5cb18e66..455047f6 100644 --- a/examples/embos/arm-cm/dpp_nucleo-h743zi/bsp.h +++ b/examples/embos/arm-cm/dpp_nucleo-h743zi/bsp.h @@ -1,47 +1,53 @@ -/***************************************************************************** -* Product: DPP example -* Last updated for version 5.9.2 -* Last updated on 2017-06-03 -* -* Q u a n t u m L e a P s -* --------------------------- -* innovating embedded systems -* -* Copyright (C) 2005 Quantum Leaps, www.state-machine.com. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* -* -*****************************************************************************/ -#ifndef BSP_H -#define BSP_H +//============================================================================ +// Product: DPP example +// Last Updated for Version: 7.3.0 +// Date of the Last Update: 2023-08-30 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. +// +// This program is open source software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Alternatively, this program may be distributed and modified under the +// terms of Quantum Leaps commercial licenses, which expressly supersede +// the GNU General Public License and are specifically designed for +// licensees interested in retaining the proprietary status of their code. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Contact information: +// +// +//============================================================================ +#ifndef BSP_H_ +#define BSP_H_ -#define BSP_TICKS_PER_SEC 50U +// embOS default tick rate +#define BSP_TICKS_PER_SEC 1000U void BSP_init(void); +void BSP_start(void); void BSP_displayPaused(uint8_t paused); void BSP_displayPhilStat(uint8_t n, char const *stat); void BSP_terminate(int16_t result); -void BSP_randomSeed(uint32_t seed); /* random seed */ -uint32_t BSP_random(void); /* pseudo-random generator */ +void BSP_randomSeed(uint32_t seed); // random seed +uint32_t BSP_random(void); // pseudo-random generator + +void BSP_ledOn(void); +void BSP_ledOff(void); + +#endif // BSP_H_ -#endif /* BSP_H */ diff --git a/examples/embos/arm-cm/dpp_nucleo-h743zi/dpp.h b/examples/embos/arm-cm/dpp_nucleo-h743zi/dpp.h index da094c2c..e6d1557a 100644 --- a/examples/embos/arm-cm/dpp_nucleo-h743zi/dpp.h +++ b/examples/embos/arm-cm/dpp_nucleo-h743zi/dpp.h @@ -1,92 +1,117 @@ -/*$file${.::dpp.h} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* -* Model: dpp.qm -* File: ${.::dpp.h} -* -* This code has been generated by QM 5.2.4 . -* DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. -* -* SPDX-License-Identifier: GPL-3.0-or-later -* -* This generated code is open source software: you can redistribute it under -* the terms of the GNU General Public License as published by the Free -* Software Foundation. -* -* This code is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -* more details. -* -* NOTE: -* Alternatively, this generated code may be distributed under the terms -* of Quantum Leaps commercial licenses, which expressly supersede the GNU -* General Public License and are specifically designed for licensees -* interested in retaining the proprietary status of their code. -* -* Contact information: -* -* -*/ -/*$endhead${.::dpp.h} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -#ifndef DPP_H -#define DPP_H +//$file${.::dpp.h} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// +// Model: dpp.qm +// File: ${.::dpp.h} +// +// This code has been generated by QM 5.3.0 . +// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. +// +// SPDX-License-Identifier: GPL-3.0-or-later +// +// This generated code is open source software: you can redistribute it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation. +// +// This code is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// NOTE: +// Alternatively, this generated code may be distributed under the terms +// of Quantum Leaps commercial licenses, which expressly supersede the GNU +// General Public License and are specifically designed for licensees +// interested in retaining the proprietary status of their code. +// +// Contact information: +// +// +// +//$endhead${.::dpp.h} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +#ifndef DPP_H_ +#define DPP_H_ -enum DPPSignals { - EAT_SIG = Q_USER_SIG, /* published by Table to let a philosopher eat */ - DONE_SIG, /* published by Philosopher when done eating */ - PAUSE_SIG, /* published by BSP to pause serving forks */ - SERVE_SIG, /* published by BSP to serve re-start serving forks */ - TEST_SIG, /* published by BSP to test the application */ - MAX_PUB_SIG, /* the last published signal */ +//$declare${Shared} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv - HUNGRY_SIG, /* posted direclty to Table from hungry Philo */ - TIMEOUT_SIG, /* used by Philosophers for time events */ - MAX_SIG /* the last signal */ +//${Shared::AppSignals} ...................................................... +enum AppSignals { + EAT_SIG = Q_USER_SIG, // published by Table to let a Philo eat + DONE_SIG, // published by Philo when done eating + PAUSE_SIG, // published by BSP to pause the application + SERVE_SIG, // published by BSP to serve re-start serving forks + TEST_SIG, // published by BSP to test the application + MAX_PUB_SIG, // the last published signal + + TIMEOUT_SIG, // posted by time event to Philo + HUNGRY_SIG, // posted by hungry Philo to Table + MAX_SIG // the last signal }; -/*$declare${Events::TableEvt} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//${Shared::produce_sig_dict} ................................................ +#ifdef Q_SPY +static inline void produce_sig_dict(void) { + QS_SIG_DICTIONARY(EAT_SIG, (void *)0); + QS_SIG_DICTIONARY(DONE_SIG, (void *)0); + QS_SIG_DICTIONARY(PAUSE_SIG, (void *)0); + QS_SIG_DICTIONARY(SERVE_SIG, (void *)0); + QS_SIG_DICTIONARY(TEST_SIG, (void *)0); -/*${Events::TableEvt} ......................................................*/ + QS_SIG_DICTIONARY(TIMEOUT_SIG, (void *)0); + QS_SIG_DICTIONARY(HUNGRY_SIG, (void *)0); +} +#endif // def Q_SPY + +//${Shared::N_PHILO} ......................................................... +#define N_PHILO ((uint8_t)5U) + +//${Shared::TableEvt} ........................................................ typedef struct { -/* protected: */ +// protected: QEvt super; -/* public: */ - uint8_t philoNum; +// public: + uint8_t philoId; } TableEvt; -/*$enddecl${Events::TableEvt} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/* number of philosophers */ -#define N_PHILO ((uint8_t)5) +// public: -/*$declare${AOs::Philo_ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +#ifdef QEVT_DYN_CTOR +static inline TableEvt * TableEvt_ctor(TableEvt * const me, + uint8_t id) +{ + if (me != (TableEvt *)0) { + // don't call QEvt_ctor() because the initialization of all + // QEvt attributes is already done in QF_QF_newX_() + me->philoId = id; + } + return me; +} +#endif // def QEVT_DYN_CTOR -/*${AOs::Philo_ctor} .......................................................*/ -void Philo_ctor(void); -/*$enddecl${AOs::Philo_ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*$declare${AOs::AO_Philo[N_PHILO]} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${AOs::AO_Philo[N_PHILO]} ................................................*/ +//${Shared::AO_Philo[N_PHILO]} ............................................... extern QActive * const AO_Philo[N_PHILO]; -/*$enddecl${AOs::AO_Philo[N_PHILO]} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*$declare${AOs::Table_ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//${Shared::Philo_ctor} ...................................................... +void Philo_ctor(uint_fast8_t const id); -/*${AOs::Table_ctor} .......................................................*/ -void Table_ctor(void); -/*$enddecl${AOs::Table_ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*$declare${AOs::AO_Table} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${AOs::AO_Table} .........................................................*/ +//${Shared::AO_Table} ........................................................ extern QActive * const AO_Table; -/*$enddecl${AOs::AO_Table} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -#ifdef QP_INC_QXK_H_ - void Test1_ctor(void); - extern QXThread * const XT_Test1; - void Test2_ctor(void); - extern QXThread * const XT_Test2; -#endif /* QP_INC_QXK_H_ */ +//${Shared::Table_ctor} ...................................................... +void Table_ctor(void); +//$enddecl${Shared} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -#endif /* DPP_H */ +#ifdef QXK_H_ +extern QXThread * const TH_XThread1; +void XThread1_ctor(void); + +extern QXThread * const TH_XThread2; +void XThread2_ctor(void); + +extern QXSemaphore TH_sema; +extern QXMutex TH_mutex; + +#endif // QXK_H_ + +#endif // DPP_H_ diff --git a/examples/embos/arm-cm/dpp_nucleo-h743zi/dpp.qm b/examples/embos/arm-cm/dpp_nucleo-h743zi/dpp.qm index b78ede00..ac9f2bc9 100644 --- a/examples/embos/arm-cm/dpp_nucleo-h743zi/dpp.qm +++ b/examples/embos/arm-cm/dpp_nucleo-h743zi/dpp.qm @@ -1,141 +1,210 @@ - + Dining Philosopher Problem example - - - + + + + + { + EAT_SIG = Q_USER_SIG, // published by Table to let a Philo eat + DONE_SIG, // published by Philo when done eating + PAUSE_SIG, // published by BSP to pause the application + SERVE_SIG, // published by BSP to serve re-start serving forks + TEST_SIG, // published by BSP to test the application + MAX_PUB_SIG, // the last published signal + + TIMEOUT_SIG, // posted by time event to Philo + HUNGRY_SIG, // posted by hungry Philo to Table + MAX_SIG // the last signal +}; + + + + QS_SIG_DICTIONARY(EAT_SIG, (void *)0); +QS_SIG_DICTIONARY(DONE_SIG, (void *)0); +QS_SIG_DICTIONARY(PAUSE_SIG, (void *)0); +QS_SIG_DICTIONARY(SERVE_SIG, (void *)0); +QS_SIG_DICTIONARY(TEST_SIG, (void *)0); + +QS_SIG_DICTIONARY(TIMEOUT_SIG, (void *)0); +QS_SIG_DICTIONARY(HUNGRY_SIG, (void *)0); + + + + ((uint8_t)5U) + + - - + + + + + + + if (me != (TableEvt *)0) { + // don't call QEvt_ctor() because the initialization of all + // QEvt attributes is already done in QF_QF_newX_() + me->philoId = id; +} +return me; + + + + = { + &Philo_inst[0].super, + &Philo_inst[1].super, + &Philo_inst[2].super, + &Philo_inst[3].super, + &Philo_inst[4].super +}; + + + + + + Philo * const me = &Philo_inst[id]; +QActive_ctor(&me->super, Q_STATE_CAST(&Philo_initial)); +QTimeEvt_ctorX(&me->timeEvt, &me->super, TIMEOUT_SIG, 0U), +me->id = (uint8_t)id; + + + + = &Table_inst.super; + + + + Table * const me = &Table_inst; +QActive_ctor(&me->super, Q_STATE_CAST(&Table_initial)); +for (uint8_t n = 0U; n < N_PHILO; ++n) { + me->fork[n] = FREE; + me->isHungry[n] = false; +} + + The Philo AO and the N_PHILO instances + + + + - + - static uint8_t registered = (uint8_t)0; /* starts off with 0, per C-standard */ -(void)par; /* unused parameter */ -if (registered == (uint8_t)0) { - registered = (uint8_t)1; + Q_UNUSED_PAR(par); - QS_OBJ_DICTIONARY(&l_philo[0]); - QS_OBJ_DICTIONARY(&l_philo[0].timeEvt); - QS_OBJ_DICTIONARY(&l_philo[1]); - QS_OBJ_DICTIONARY(&l_philo[1].timeEvt); - QS_OBJ_DICTIONARY(&l_philo[2]); - QS_OBJ_DICTIONARY(&l_philo[2].timeEvt); - QS_OBJ_DICTIONARY(&l_philo[3]); - QS_OBJ_DICTIONARY(&l_philo[3].timeEvt); - QS_OBJ_DICTIONARY(&l_philo[4]); - QS_OBJ_DICTIONARY(&l_philo[4].timeEvt); - - QS_FUN_DICTIONARY(&Philo_initial); - QS_FUN_DICTIONARY(&Philo_thinking); - QS_FUN_DICTIONARY(&Philo_hungry); - QS_FUN_DICTIONARY(&Philo_eating); -} -QS_SIG_DICTIONARY(HUNGRY_SIG, me); /* signal for each Philos */ -QS_SIG_DICTIONARY(TIMEOUT_SIG, me); /* signal for each Philos */ +QS_OBJ_ARR_DICTIONARY(&Philo_inst[me->id], me->id); +QS_OBJ_ARR_DICTIONARY(&Philo_inst[me->id].timeEvt, me->id); QActive_subscribe(&me->super, EAT_SIG); QActive_subscribe(&me->super, TEST_SIG); - + - QTimeEvt_armX(&me->timeEvt, THINK_TIME, 0U); - QTimeEvt_disarm(&me->timeEvt); + QTimeEvt_armX(&me->timeEvt, think_time(), 0U); + (void)QTimeEvt_disarm(&me->timeEvt); - - + + - /* EAT or DONE must be for other Philos than this one */ -Q_ASSERT(Q_EVT_CAST(TableEvt)->philoNum != PHILO_ID(me)); - + // EAT or DONE must be for other Philos than this one +Q_ASSERT(Q_EVT_CAST(TableEvt)->philoId != me->id); + - + - + - + - TableEvt *pe = Q_NEW(TableEvt, HUNGRY_SIG); -pe->philoNum = PHILO_ID(me); -QACTIVE_POST(AO_Table, &pe->super, me); + #ifdef QEVT_DYN_CTOR +TableEvt const *pe = Q_NEW(TableEvt, HUNGRY_SIG, me->id); +#else +TableEvt *pe = Q_NEW(TableEvt, HUNGRY_SIG); +pe->philoId = me->id; +#endif +QACTIVE_POST(AO_Table, &pe->super, &me->super); - + - Q_EVT_CAST(TableEvt)->philoNum == PHILO_ID(me) - - + Q_EVT_CAST(TableEvt)->philoId == me->id + + - + - /* DONE must be for other Philos than this one */ -Q_ASSERT(Q_EVT_CAST(TableEvt)->philoNum != PHILO_ID(me)); - + // DONE must be for other Philos than this one +Q_ASSERT(Q_EVT_CAST(TableEvt)->philoId != me->id); + - + - QTimeEvt_armX(&me->timeEvt, EAT_TIME, 0U); - TableEvt *pe = Q_NEW(TableEvt, DONE_SIG); -pe->philoNum = PHILO_ID(me); + QTimeEvt_armX(&me->timeEvt, eat_time(), 0U); + (void)QTimeEvt_disarm(&me->timeEvt); + +#ifdef QEVT_DYN_CTOR +TableEvt const *pe = Q_NEW(TableEvt, DONE_SIG, me->id); +#else +TableEvt *pe = Q_NEW(TableEvt, DONE_SIG); +pe->philoId = me->id; +#endif QACTIVE_PUBLISH(&pe->super, &me->super); - - + + - /* EAT or DONE must be for other Philos than this one */ -Q_ASSERT(Q_EVT_CAST(TableEvt)->philoNum != PHILO_ID(me)); - + // EAT or DONE must be for other Philos than this one +Q_ASSERT(Q_EVT_CAST(TableEvt)->philoId != me->id); + - + - + @@ -143,22 +212,19 @@ Q_ASSERT(Q_EVT_CAST(TableEvt)->philoNum != PHILO_ID(me)); - + + + - + - (void)par; /* unused parameter */ + Q_UNUSED_PAR(par); -QS_OBJ_DICTIONARY(&l_table); - -QS_SIG_DICTIONARY(DONE_SIG, (void *)0); /* global signals */ -QS_SIG_DICTIONARY(EAT_SIG, (void *)0); -QS_SIG_DICTIONARY(PAUSE_SIG, (void *)0); -QS_SIG_DICTIONARY(SERVE_SIG, (void *)0); -QS_SIG_DICTIONARY(TEST_SIG, (void *)0); - -QS_SIG_DICTIONARY(HUNGRY_SIG, me); /* signal just for Table */ +#ifdef Q_SPY +Table *Table_inst = me; +QS_OBJ_DICTIONARY(Table_inst); +#endif QActive_subscribe(&me->super, DONE_SIG); QActive_subscribe(&me->super, PAUSE_SIG); @@ -167,10 +233,10 @@ QActive_subscribe(&me->super, TEST_SIG); for (uint8_t n = 0U; n < N_PHILO; ++n) { me->fork[n] = FREE; - me->isHungry[n] = 0U; - BSP_displayPhilStat(n, "thinking"); + me->isHungry[n] = false; + BSP_displayPhilStat(n, THINKING); } - + @@ -178,128 +244,139 @@ for (uint8_t n = 0U; n < N_PHILO; ++n) { - + Q_ERROR(); - + - uint8_t n; -for (n = 0U; n < N_PHILO; ++n) { /* give permissions to eat... */ - if ((me->isHungry[n] != 0U) - && (me->fork[LEFT(n)] == FREE) + // give permissions to eat... +for (uint8_t n = 0U; n < N_PHILO; ++n) { + if (me->isHungry[n] + && (me->fork[left(n)] == FREE) && (me->fork[n] == FREE)) { - TableEvt *te; - - me->fork[LEFT(n)] = USED; + me->fork[left(n)] = USED; me->fork[n] = USED; - te = Q_NEW(TableEvt, EAT_SIG); - te->philoNum = n; - QACTIVE_PUBLISH(&te->super, &me->super); - me->isHungry[n] = 0U; - BSP_displayPhilStat(n, "eating "); +#ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, EAT_SIG, n); +#else + TableEvt *pe = Q_NEW(TableEvt, EAT_SIG); + pe->philoId = n; +#endif + QACTIVE_PUBLISH(&pe->super, &me->super); + me->isHungry[n] = false; + BSP_displayPhilStat(n, EATING); } } - uint8_t n, m; + uint8_t n = Q_EVT_CAST(TableEvt)->philoId; -n = Q_EVT_CAST(TableEvt)->philoNum; -/* phil ID must be in range and he must be not hungry */ -Q_ASSERT((n < N_PHILO) && (me->isHungry[n] == 0U)); +// phil ID must be in range and he must be not hungry +Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); -BSP_displayPhilStat(n, "hungry "); -m = LEFT(n); +BSP_displayPhilStat(n, HUNGRY); +uint8_t m = left(n); (me->fork[m] == FREE) && (me->fork[n] == FREE) - TableEvt *pe; -me->fork[m] = USED; + me->fork[m] = USED; me->fork[n] = USED; -pe = Q_NEW(TableEvt, EAT_SIG); -pe->philoNum = n; +#ifdef QEVT_DYN_CTOR +TableEvt const *pe = Q_NEW(TableEvt, EAT_SIG, n); +#else +TableEvt *pe = Q_NEW(TableEvt, EAT_SIG); +pe->philoId = n; +#endif QACTIVE_PUBLISH(&pe->super, &me->super); -BSP_displayPhilStat(n, "eating "); - +BSP_displayPhilStat(n, EATING); + else - me->isHungry[n] = 1U; - - + me->isHungry[n] = true; + + - + - uint8_t n, m; -TableEvt *pe; + uint8_t n = Q_EVT_CAST(TableEvt)->philoId; -n = Q_EVT_CAST(TableEvt)->philoNum; -/* phil ID must be in range and he must be not hungry */ -Q_ASSERT((n < N_PHILO) && (me->isHungry[n] == 0U)); +// phil ID must be in range and he must be not hungry +Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); -BSP_displayPhilStat(n, "thinking"); -m = LEFT(n); -/* both forks of Phil[n] must be used */ +BSP_displayPhilStat(n, THINKING); +uint8_t m = left(n); + +// both forks of Phil[n] must be used Q_ASSERT((me->fork[n] == USED) && (me->fork[m] == USED)); me->fork[m] = FREE; me->fork[n] = FREE; -m = RIGHT(n); /* check the right neighbor */ +m = right(n); // check the right neighbor -if ((me->isHungry[m] != 0U) && (me->fork[m] == FREE)) { +if (me->isHungry[m] && (me->fork[m] == FREE)) { me->fork[n] = USED; me->fork[m] = USED; - me->isHungry[m] = 0U; - pe = Q_NEW(TableEvt, EAT_SIG); - pe->philoNum = m; + me->isHungry[m] = false; +#ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, EAT_SIG, m); +#else + TableEvt *pe = Q_NEW(TableEvt, EAT_SIG); + pe->philoId = m; +#endif QACTIVE_PUBLISH(&pe->super, &me->super); - BSP_displayPhilStat(m, "eating "); + BSP_displayPhilStat(m, EATING); } -m = LEFT(n); /* check the left neighbor */ -n = LEFT(m); /* left fork of the left neighbor */ -if ((me->isHungry[m] != 0U) && (me->fork[n] == FREE)) { +m = left(n); // check the left neighbor +n = left(m); // left fork of the left neighbor +if (me->isHungry[m] && (me->fork[n] == FREE)) { me->fork[m] = USED; me->fork[n] = USED; - me->isHungry[m] = 0U; - pe = Q_NEW(TableEvt, EAT_SIG); - pe->philoNum = m; + me->isHungry[m] = false; +#ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, EAT_SIG, m); +#else + TableEvt *pe = Q_NEW(TableEvt, EAT_SIG); + pe->philoId = m; +#endif QACTIVE_PUBLISH(&pe->super, &me->super); - BSP_displayPhilStat(m, "eating "); + BSP_displayPhilStat(m, EATING); } - + Q_ERROR(); - + - + - + @@ -309,178 +386,140 @@ if ((me->isHungry[m] != 0U) && (me->fork[n] == FREE)) { BSP_displayPaused(0U); - + - uint8_t n = Q_EVT_CAST(TableEvt)->philoNum; -/* philo ID must be in range and he must be not hungry */ -Q_ASSERT((n < N_PHILO) && (me->isHungry[n] == 0U)); -me->isHungry[n] = 1U; -BSP_displayPhilStat(n, "hungry "); - + uint8_t n = Q_EVT_CAST(TableEvt)->philoId; + +// philo ID must be in range and he must be not hungry +Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); + +me->isHungry[n] = true; +BSP_displayPhilStat(n, HUNGRY); + - uint8_t n, m; + uint8_t n = Q_EVT_CAST(TableEvt)->philoId; -n = Q_EVT_CAST(TableEvt)->philoNum; -/* phil ID must be in range and he must be not hungry */ -Q_ASSERT((n < N_PHILO) && (me->isHungry[n] == 0U)); +// phil ID must be in range and he must be not hungry +Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); -BSP_displayPhilStat(n, "thinking"); -m = LEFT(n); -/* both forks of Phil[n] must be used */ +BSP_displayPhilStat(n, THINKING); +uint8_t m = left(n); + +// both forks of Phil[n] must be used Q_ASSERT((me->fork[n] == USED) && (me->fork[m] == USED)); me->fork[m] = FREE; me->fork[n] = FREE; - + - + - + - + - - - - - - - uint8_t n; -Philo *me; -for (n = 0U; n < N_PHILO; ++n) { - me = &l_philo[n]; - QActive_ctor(&me->super, Q_STATE_CAST(&Philo_initial)); - QTimeEvt_ctorX(&me->timeEvt, &me->super, TIMEOUT_SIG, 0U); -} - - - - uint8_t n; -Table *me = &l_table; - -QActive_ctor(&me->super, Q_STATE_CAST(&Table_initial)); - -for (n = 0U; n < N_PHILO; ++n) { - me->fork[n] = FREE; - me->isHungry[n] = 0U; -} - - #ifndef DPP_H -#define DPP_H + #ifndef DPP_H_ +#define DPP_H_ -enum DPPSignals { - EAT_SIG = Q_USER_SIG, /* published by Table to let a philosopher eat */ - DONE_SIG, /* published by Philosopher when done eating */ - PAUSE_SIG, /* published by BSP to pause serving forks */ - SERVE_SIG, /* published by BSP to serve re-start serving forks */ - TEST_SIG, /* published by BSP to test the application */ - MAX_PUB_SIG, /* the last published signal */ +$declare ${Shared} - HUNGRY_SIG, /* posted direclty to Table from hungry Philo */ - TIMEOUT_SIG, /* used by Philosophers for time events */ - MAX_SIG /* the last signal */ -}; +#ifdef QXK_H_ -$declare(Events::TableEvt) +extern QXThread * const TH_XThread1; +void XThread1_ctor(void); -/* number of philosophers */ -#define N_PHILO ((uint8_t)5) +extern QXThread * const TH_XThread2; +void XThread2_ctor(void); -$declare(AOs::Philo_ctor) -$declare(AOs::AO_Philo[N_PHILO]) +extern QXSemaphore TH_sema; +extern QXMutex TH_mutex; -$declare(AOs::Table_ctor) -$declare(AOs::AO_Table) +#endif // QXK_H_ -#ifdef QP_INC_QXK_H_ - void Test1_ctor(void); - extern QXThread * const XT_Test1; - void Test2_ctor(void); - extern QXThread * const XT_Test2; -#endif /* QP_INC_QXK_H_ */ - -#endif /* DPP_H */ - +#endif // DPP_H_ - #include "qpc.h" -#include "dpp.h" -#include "bsp.h" + #include "qpc.h" // QP/C real-time embedded framework +#include "dpp.h" // DPP Application interface +#include "bsp.h" // Board Support Package +$declare ${AOs::Philo} + +//---------------------------------------------------------------------------- Q_DEFINE_THIS_FILE -/* Active object class -----------------------------------------------------*/ -$declare(AOs::Philo) +// helper function to provide a randomized think time for Philos +static QTimeEvtCtr think_time(void); // prototype +static inline QTimeEvtCtr think_time(void) { + return (QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + + (BSP_TICKS_PER_SEC/2U)); +} -/* Local objects -----------------------------------------------------------*/ -static Philo l_philo[N_PHILO]; /* storage for all Philos */ +// helper function to provide a randomized eat time for Philos +static QTimeEvtCtr eat_time(void); // prototype +static inline QTimeEvtCtr eat_time(void) { + return (QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + + BSP_TICKS_PER_SEC); +} +//---------------------------------------------------------------------------- -#define THINK_TIME \ - (QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + (BSP_TICKS_PER_SEC/2U)) -#define EAT_TIME \ - (QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + BSP_TICKS_PER_SEC) - -/* helper macro to provide the ID of Philo "me_" */ -#define PHILO_ID(me_) ((uint8_t)((me_) - l_philo)) - -/* Global objects ----------------------------------------------------------*/ -QActive * const AO_Philo[N_PHILO] = { /* "opaque" pointers to Philo AO */ - &l_philo[0].super, - &l_philo[1].super, - &l_philo[2].super, - &l_philo[3].super, - &l_philo[4].super -}; - -/* Philo definition --------------------------------------------------------*/ -$define(AOs::Philo_ctor) -$define(AOs::Philo) +$define ${Shared::Philo_ctor} +$define ${Shared::AO_Philo[N_PHILO]} +$define ${AOs::Philo} - #include "qpc.h" -#include "dpp.h" -#include "bsp.h" + #include "qpc.h" // QP/C real-time embedded framework +#include "dpp.h" // DPP Application interface +#include "bsp.h" // Board Support Package +$declare ${AOs::Table} + +//---------------------------------------------------------------------------- Q_DEFINE_THIS_FILE -/* Active object class -----------------------------------------------------*/ -$declare(AOs::Table) +// helper function to provide the RIGHT neighbor of a Philo[n] +static inline uint8_t right(uint8_t const n) { + return (uint8_t)((n + (N_PHILO - 1U)) % N_PHILO); +} -#define RIGHT(n_) ((uint8_t)(((n_) + (N_PHILO - 1U)) % N_PHILO)) -#define LEFT(n_) ((uint8_t)(((n_) + 1U) % N_PHILO)) -#define FREE ((uint8_t)0) -#define USED ((uint8_t)1) +// helper function to provide the LEFT neighbor of a Philo[n] +static inline uint8_t left(uint8_t const n) { + return (uint8_t)((n + 1U) % N_PHILO); +} -/* Local objects -----------------------------------------------------------*/ -static Table l_table; /* the single instance of the Table active object */ +#define FREE ((uint8_t)0U) +#define USED ((uint8_t)1U) -/* Global-scope objects ----------------------------------------------------*/ -QActive * const AO_Table = &l_table.super; /* "opaque" AO pointer */ +#define THINKING "thinking" +#define HUNGRY "hungry " +#define EATING "eating " -/*..........................................................................*/ -$define(AOs::Table_ctor) -$define(AOs::Table) +//---------------------------------------------------------------------------- + +$define ${Shared::Table_ctor} +$define ${Shared::AO_Table} +$define ${AOs::Table} diff --git a/examples/embos/arm-cm/dpp_nucleo-h743zi/gnu/Makefile b/examples/embos/arm-cm/dpp_nucleo-h743zi/gnu/Makefile index b71fb1ad..b1ca441e 100644 --- a/examples/embos/arm-cm/dpp_nucleo-h743zi/gnu/Makefile +++ b/examples/embos/arm-cm/dpp_nucleo-h743zi/gnu/Makefile @@ -280,7 +280,7 @@ $(TARGET_BIN): $(TARGET_ELF) $(BIN) -O binary $< $@ $(TARGET_ELF) : $(ASM_OBJS_EXT) $(C_OBJS_EXT) $(CPP_OBJS_EXT) - $(CC) $(CFLAGS) $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o + $(CC) $(CFLAGS) $(QPC)/src/qs/qstamp.c -o $(BIN_DIR)/qstamp.o $(LINK) $(LINKFLAGS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) $(BIN_DIR)/%.d : %.c diff --git a/examples/embos/arm-cm/dpp_nucleo-h743zi/gnu/dpp.ld b/examples/embos/arm-cm/dpp_nucleo-h743zi/gnu/dpp.ld index 6814e751..4fd7fdba 100644 --- a/examples/embos/arm-cm/dpp_nucleo-h743zi/gnu/dpp.ld +++ b/examples/embos/arm-cm/dpp_nucleo-h743zi/gnu/dpp.ld @@ -41,7 +41,7 @@ MEMORY { /* memory map of STM32F746NG */ } /* The size of the stack used by the application. NOTE: you need to adjust */ -STACK_SIZE = 2048; +STACK_SIZE = 1024; /* The size of the heap used by the application. NOTE: you need to adjust */ HEAP_SIZE = 0; diff --git a/examples/embos/arm-cm/dpp_nucleo-h743zi/iar/dpp.ewd b/examples/embos/arm-cm/dpp_nucleo-h743zi/iar/dpp.ewd index 4f61f120..7ba8c84a 100644 --- a/examples/embos/arm-cm/dpp_nucleo-h743zi/iar/dpp.ewd +++ b/examples/embos/arm-cm/dpp_nucleo-h743zi/iar/dpp.ewd @@ -88,7 +88,7 @@ #include "qpc.h" #include "dpp.h" -#include "esp_log.h" +#include "bsp.h" Q_DEFINE_THIS_FILE -/* Active object class -----------------------------------------------------*/ -$declare(AOs::Philo) - -/* Local objects -----------------------------------------------------------*/ -static Philo l_philo[N_PHILO]; /* storage for all Philos */ +// Active object class ----------------------------------------------------- +$declare${AOs::Philo} #define THINK_TIME \ - (QTimeEvtCtr)((esp_random() % CONFIG_FREERTOS_HZ) + (CONFIG_FREERTOS_HZ/2U)) + (QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + (BSP_TICKS_PER_SEC/2U)) #define EAT_TIME \ - (QTimeEvtCtr)((esp_random() % CONFIG_FREERTOS_HZ) + CONFIG_FREERTOS_HZ) + (QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + BSP_TICKS_PER_SEC) -/* helper macro to provide the ID of Philo "me_" */ -#define PHILO_ID(me_) ((uint8_t)((me_) - l_philo)) +// helper macro to provide the ID of Philo "me_" +static inline uint8_t PHILO_ID(Philo * const me) { + return (uint8_t)(me - &Philo_inst[0]); +} -/* Global objects ----------------------------------------------------------*/ -QActive * const AO_Philo[N_PHILO] = { /* "opaque" pointers to Philo AO */ - &l_philo[0].super, - &l_philo[1].super, - &l_philo[2].super, - &l_philo[3].super, - &l_philo[4].super -}; - -/* Philo definition --------------------------------------------------------*/ -$define(AOs::Philo_ctor) -$define(AOs::Philo) +$define${AOs::AO_Philo[N_PHILO]} +$define${AOs::Philo_ctor} +$define${AOs::Philo} #include "qpc.h" #include "dpp.h" -#include "esp_log.h" +#include "bsp.h" Q_DEFINE_THIS_FILE -static const char * TAG = "table"; -/* Active object class -----------------------------------------------------*/ -$declare(AOs::Table) +// Active object class ----------------------------------------------------- +$declare${AOs::Table} #define RIGHT(n_) ((uint8_t)(((n_) + (N_PHILO - 1U)) % N_PHILO)) #define LEFT(n_) ((uint8_t)(((n_) + 1U) % N_PHILO)) #define FREE ((uint8_t)0) #define USED ((uint8_t)1) -/* Local objects -----------------------------------------------------------*/ -static Table l_table; /* the single instance of the Table active object */ - -/* Global-scope objects ----------------------------------------------------*/ -QActive * const AO_Table = &l_table.super; /* "opaque" AO pointer */ - -/*..........................................................................*/ -$define(AOs::Table_ctor) -$define(AOs::Table) - +$define${AOs::AO_Table} +$define${AOs::Table_ctor} +$define${AOs::Table}
diff --git a/examples/esp-idf/dpp-esp32devkitc/main/main.c b/examples/esp-idf/dpp-esp32devkitc/main/main.c index 2d2c1707..c17076e1 100644 --- a/examples/esp-idf/dpp-esp32devkitc/main/main.c +++ b/examples/esp-idf/dpp-esp32devkitc/main/main.c @@ -3,28 +3,28 @@ #include "dpp.h" #include "freertos/FreeRTOS.h" -Q_DEFINE_THIS_FILE +//Q_DEFINE_THIS_FILE static const char * TAG = "main"; -/* - * small event memory pool - */ +// +// small event memory pool +// static QF_MPOOL_EL(QEvt) smallPoolSto[CONFIG_QPC_SMALL_POOL_SIZE]; -/* - * medium size event memory pool - * size: QEvt + CONFIG_QPC_MEDIUM_POOL_ENTRY_SIZE words - */ +// +// medium size event memory pool +// size: QEvt + CONFIG_QPC_MEDIUM_POOL_ENTRY_SIZE words +// typedef struct { QEvt super; uint32_t data[CONFIG_QPC_MEDIUM_POOL_ENTRY_SIZE]; } mediumPool; static QF_MPOOL_EL(mediumPool) mediumPoolSto[CONFIG_QPC_MEDIUM_POOL_SIZE]; -/* - * large size event memory pool - * size: QEvt + CONFIG_QPC_LARGE_POOL_ENTRY_SIZE words - */ +// +// large size event memory pool +// size: QEvt + CONFIG_QPC_LARGE_POOL_ENTRY_SIZE words +// typedef struct { QEvt super; uint32_t data[CONFIG_QPC_LARGE_POOL_ENTRY_SIZE]; @@ -41,40 +41,40 @@ void app_main() { uint8_t n; - Philo_ctor(); /* instantiate all Philosopher active objects */ - Table_ctor(); /* instantiate the Table active object */ + Philo_ctor(); // instantiate all Philosopher active objects + Table_ctor(); // instantiate the Table active object - /* Initialzie QP/C Framework */ + // Initialzie QP/C Framework QF_init(); - /* initialize publish-subscribe... */ - QF_psInit(subscrSto, Q_DIM(subscrSto)); + // initialize publish-subscribe... + QActive_psInit(subscrSto, Q_DIM(subscrSto)); - /* Initialize Event Memory Pool */ + // Initialize Event Memory Pool QF_poolInit(smallPoolSto, sizeof(smallPoolSto), sizeof(smallPoolSto[0])); QF_poolInit(mediumPoolSto, sizeof(mediumPoolSto), sizeof(mediumPoolSto[0])); QF_poolInit(largePoolSto, sizeof(largePoolSto), sizeof(largePoolSto[0])); - /* start the active objects... */ + // start the active objects... for (n = 0U; n < N_PHILO; ++n) { QActive_setAttr(AO_Philo[n], TASK_NAME_ATTR, "Philo"); - QACTIVE_START(AO_Philo[n], /* AO to start */ - (uint_fast8_t)(n + 1), /* QP priority of the AO */ - philoQueueSto[n], /* event queue storage */ - Q_DIM(philoQueueSto[n]), /* queue length [events] */ - philoStack[n], /* stack storage */ - sizeof(philoStack[n]), /* stack size [bytes] */ - (QEvt *)0); /* initialization event (not used) */ + QACTIVE_START(AO_Philo[n], // AO to start + (uint_fast8_t)(n + 1), // QP priority of the AO + philoQueueSto[n], // event queue storage + Q_DIM(philoQueueSto[n]), // queue length [events] + philoStack[n], // stack storage + sizeof(philoStack[n]), // stack size [bytes] + (QEvt *)0); // initialization event (not used) } QActive_setAttr(AO_Table, TASK_NAME_ATTR, "Table"); - QACTIVE_START(AO_Table, /* AO to start */ - (uint_fast8_t)(N_PHILO + 1), /* QP priority of the AO */ - tableQueueSto, /* event queue storage */ - Q_DIM(tableQueueSto), /* queue length [events] */ - tableStack, /* stack storage */ - sizeof(tableStack), /* stack size [bytes] */ - (QEvt *)0); /* initialization event (not used) */ + QACTIVE_START(AO_Table, // AO to start + (uint_fast8_t)(N_PHILO + 1), // QP priority of the AO + tableQueueSto, // event queue storage + Q_DIM(tableQueueSto), // queue length [events] + tableStack, // stack storage + sizeof(tableStack), // stack size [bytes] + (QEvt *)0); // initialization event (not used) QF_run(); diff --git a/examples/esp-idf/dpp-esp32devkitc/main/philo.c b/examples/esp-idf/dpp-esp32devkitc/main/philo.c index 396c4cf1..010991e7 100644 --- a/examples/esp-idf/dpp-esp32devkitc/main/philo.c +++ b/examples/esp-idf/dpp-esp32devkitc/main/philo.c @@ -1,165 +1,168 @@ -/*$file${.::philo.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* -* Model: dpp.qm -* File: ${.::philo.c} -* -* This code has been generated by QM 5.2.4 . -* DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. -* -* SPDX-License-Identifier: GPL-3.0-or-later -* -* This generated code is open source software: you can redistribute it under -* the terms of the GNU General Public License as published by the Free -* Software Foundation. -* -* This code is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -* more details. -* -* NOTE: -* Alternatively, this generated code may be distributed under the terms -* of Quantum Leaps commercial licenses, which expressly supersede the GNU -* General Public License and are specifically designed for licensees -* interested in retaining the proprietary status of their code. -* -* Contact information: -* -* -*/ -/*$endhead${.::philo.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$file${.::philo.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// +// Model: dpp.qm +// File: ${.::philo.c} +// +// This code has been generated by QM 5.3.0 . +// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. +// +// SPDX-License-Identifier: GPL-3.0-or-later +// +// This generated code is open source software: you can redistribute it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation. +// +// This code is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// NOTE: +// Alternatively, this generated code may be distributed under the terms +// of Quantum Leaps commercial licenses, which expressly supersede the GNU +// General Public License and are specifically designed for licensees +// interested in retaining the proprietary status of their code. +// +// Contact information: +// +// +// +//$endhead${.::philo.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ #include "qpc.h" #include "dpp.h" -#include "esp_log.h" +#include "bsp.h" Q_DEFINE_THIS_FILE -/* Active object class -----------------------------------------------------*/ -/*$declare${AOs::Philo} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +// Active object class ----------------------------------------------------- +//$declare${AOs::Philo} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/*${AOs::Philo} ............................................................*/ -typedef struct { -/* protected: */ +//${AOs::Philo} .............................................................. +typedef struct Philo { +// protected: QActive super; -/* private: */ +// public: + +// private: QTimeEvt timeEvt; } Philo; +extern Philo Philo_inst[N_PHILO]; -/* protected: */ +// protected: static QState Philo_initial(Philo * const me, void const * const par); static QState Philo_thinking(Philo * const me, QEvt const * const e); static QState Philo_hungry(Philo * const me, QEvt const * const e); static QState Philo_eating(Philo * const me, QEvt const * const e); -/*$enddecl${AOs::Philo} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ - -/* Local objects -----------------------------------------------------------*/ -static Philo l_philo[N_PHILO]; /* storage for all Philos */ +//$enddecl${AOs::Philo} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ #define THINK_TIME \ - (QTimeEvtCtr)((esp_random() % CONFIG_FREERTOS_HZ) + (CONFIG_FREERTOS_HZ/2U)) + (QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + (BSP_TICKS_PER_SEC/2U)) #define EAT_TIME \ - (QTimeEvtCtr)((esp_random() % CONFIG_FREERTOS_HZ) + CONFIG_FREERTOS_HZ) + (QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + BSP_TICKS_PER_SEC) -/* helper macro to provide the ID of Philo "me_" */ -#define PHILO_ID(me_) ((uint8_t)((me_) - l_philo)) +// helper macro to provide the ID of Philo "me_" +static inline uint8_t PHILO_ID(Philo * const me) { + return (uint8_t)(me - &Philo_inst[0]); +} -/* Global objects ----------------------------------------------------------*/ -QActive * const AO_Philo[N_PHILO] = { /* "opaque" pointers to Philo AO */ - &l_philo[0].super, - &l_philo[1].super, - &l_philo[2].super, - &l_philo[3].super, - &l_philo[4].super -}; - -/* Philo definition --------------------------------------------------------*/ -/*$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* Check for the minimum required QP version */ -#if (QP_VERSION < 700U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) -#error qpc version 7.0.0 or higher required +//$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// Check for the minimum required QP version +#if (QP_VERSION < 730U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) +#error qpc version 7.3.0 or higher required #endif -/*$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -/*$define${AOs::Philo_ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//$define${AOs::AO_Philo[N_PHILO]} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/*${AOs::Philo_ctor} .......................................................*/ +//${AOs::AO_Philo[N_PHILO]} .................................................. +QActive * const AO_Philo[N_PHILO] = { // "opaque" pointers to Philo AO + &Philo_inst[0].super, + &Philo_inst[1].super, + &Philo_inst[2].super, + &Philo_inst[3].super, + &Philo_inst[4].super +}; +//$enddef${AOs::AO_Philo[N_PHILO]} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +//$define${AOs::Philo_ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${AOs::Philo_ctor} ......................................................... void Philo_ctor(void) { uint8_t n; Philo *me; for (n = 0U; n < N_PHILO; ++n) { - me = &l_philo[n]; + me = &Philo_inst[n]; QActive_ctor(&me->super, Q_STATE_CAST(&Philo_initial)); - QTimeEvt_ctorX(&me->timeEvt, &me->super, TIMEOUT_SIG, 0U); + QTimeEvt_ctorX(&me->timeEvt, &me->super, (enum_t)TIMEOUT_SIG, 0U); } } -/*$enddef${AOs::Philo_ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*$define${AOs::Philo} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//$enddef${AOs::Philo_ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +//$define${AOs::Philo} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/*${AOs::Philo} ............................................................*/ +//${AOs::Philo} .............................................................. +Philo Philo_inst[N_PHILO]; -/*${AOs::Philo::SM} ........................................................*/ +//${AOs::Philo::SM} .......................................................... static QState Philo_initial(Philo * const me, void const * const par) { - /*${AOs::Philo::SM::initial} */ - static uint8_t registered = (uint8_t)0; /* starts off with 0, per C-standard */ - (void)par; /* unused parameter */ - if (registered == (uint8_t)0) { - registered = (uint8_t)1; + //${AOs::Philo::SM::initial} + Q_UNUSED_PAR(par); - QS_OBJ_DICTIONARY(&l_philo[0]); - QS_OBJ_DICTIONARY(&l_philo[0].timeEvt); - QS_OBJ_DICTIONARY(&l_philo[1]); - QS_OBJ_DICTIONARY(&l_philo[1].timeEvt); - QS_OBJ_DICTIONARY(&l_philo[2]); - QS_OBJ_DICTIONARY(&l_philo[2].timeEvt); - QS_OBJ_DICTIONARY(&l_philo[3]); - QS_OBJ_DICTIONARY(&l_philo[3].timeEvt); - QS_OBJ_DICTIONARY(&l_philo[4]); - QS_OBJ_DICTIONARY(&l_philo[4].timeEvt); + static bool registered = false; + if (!registered) { + registered = true; + + QS_OBJ_DICTIONARY(&Philo_inst[0]); + QS_OBJ_DICTIONARY(&Philo_inst[0].timeEvt); + QS_OBJ_DICTIONARY(&Philo_inst[1]); + QS_OBJ_DICTIONARY(&Philo_inst[1].timeEvt); + QS_OBJ_DICTIONARY(&Philo_inst[2]); + QS_OBJ_DICTIONARY(&Philo_inst[2].timeEvt); + QS_OBJ_DICTIONARY(&Philo_inst[3]); + QS_OBJ_DICTIONARY(&Philo_inst[3].timeEvt); + QS_OBJ_DICTIONARY(&Philo_inst[4]); + QS_OBJ_DICTIONARY(&Philo_inst[4].timeEvt); QS_FUN_DICTIONARY(&Philo_initial); QS_FUN_DICTIONARY(&Philo_thinking); QS_FUN_DICTIONARY(&Philo_hungry); QS_FUN_DICTIONARY(&Philo_eating); } - QS_SIG_DICTIONARY(HUNGRY_SIG, me); /* signal for each Philos */ - QS_SIG_DICTIONARY(TIMEOUT_SIG, me); /* signal for each Philos */ - QActive_subscribe(&me->super, EAT_SIG); - QActive_subscribe(&me->super, TEST_SIG); + QActive_subscribe(&me->super, (enum_t)EAT_SIG); + QActive_subscribe(&me->super, (enum_t)TEST_SIG); return Q_TRAN(&Philo_thinking); } -/*${AOs::Philo::SM::thinking} ..............................................*/ +//${AOs::Philo::SM::thinking} ................................................ static QState Philo_thinking(Philo * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${AOs::Philo::SM::thinking} */ + //${AOs::Philo::SM::thinking} case Q_ENTRY_SIG: { QTimeEvt_armX(&me->timeEvt, THINK_TIME, 0U); status_ = Q_HANDLED(); break; } - /*${AOs::Philo::SM::thinking} */ + //${AOs::Philo::SM::thinking} case Q_EXIT_SIG: { - QTimeEvt_disarm(&me->timeEvt); + (void)QTimeEvt_disarm(&me->timeEvt); status_ = Q_HANDLED(); break; } - /*${AOs::Philo::SM::thinking::TIMEOUT} */ + //${AOs::Philo::SM::thinking::TIMEOUT} case TIMEOUT_SIG: { status_ = Q_TRAN(&Philo_hungry); break; } - /*${AOs::Philo::SM::thinking::EAT, DONE} */ - case EAT_SIG: /* intentionally fall through */ + //${AOs::Philo::SM::thinking::EAT, DONE} + case EAT_SIG: // intentionally fall through case DONE_SIG: { - /* EAT or DONE must be for other Philos than this one */ + // EAT or DONE must be for other Philos than this one Q_ASSERT(Q_EVT_CAST(TableEvt)->philoNum != PHILO_ID(me)); status_ = Q_HANDLED(); break; } - /*${AOs::Philo::SM::thinking::TEST} */ + //${AOs::Philo::SM::thinking::TEST} case TEST_SIG: { status_ = Q_HANDLED(); break; @@ -172,11 +175,11 @@ static QState Philo_thinking(Philo * const me, QEvt const * const e) { return status_; } -/*${AOs::Philo::SM::hungry} ................................................*/ +//${AOs::Philo::SM::hungry} .................................................. static QState Philo_hungry(Philo * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${AOs::Philo::SM::hungry} */ + //${AOs::Philo::SM::hungry} case Q_ENTRY_SIG: { TableEvt *pe = Q_NEW(TableEvt, HUNGRY_SIG); pe->philoNum = PHILO_ID(me); @@ -184,9 +187,9 @@ static QState Philo_hungry(Philo * const me, QEvt const * const e) { status_ = Q_HANDLED(); break; } - /*${AOs::Philo::SM::hungry::EAT} */ + //${AOs::Philo::SM::hungry::EAT} case EAT_SIG: { - /*${AOs::Philo::SM::hungry::EAT::[Q_EVT_CAST(TableEvt)->philoNum=~} */ + //${AOs::Philo::SM::hungry::EAT::[Q_EVT_CAST(TableEvt)->philoNum=~} if (Q_EVT_CAST(TableEvt)->philoNum == PHILO_ID(me)) { status_ = Q_TRAN(&Philo_eating); } @@ -195,9 +198,9 @@ static QState Philo_hungry(Philo * const me, QEvt const * const e) { } break; } - /*${AOs::Philo::SM::hungry::DONE} */ + //${AOs::Philo::SM::hungry::DONE} case DONE_SIG: { - /* DONE must be for other Philos than this one */ + // DONE must be for other Philos than this one Q_ASSERT(Q_EVT_CAST(TableEvt)->philoNum != PHILO_ID(me)); status_ = Q_HANDLED(); break; @@ -210,33 +213,33 @@ static QState Philo_hungry(Philo * const me, QEvt const * const e) { return status_; } -/*${AOs::Philo::SM::eating} ................................................*/ +//${AOs::Philo::SM::eating} .................................................. static QState Philo_eating(Philo * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${AOs::Philo::SM::eating} */ + //${AOs::Philo::SM::eating} case Q_ENTRY_SIG: { QTimeEvt_armX(&me->timeEvt, EAT_TIME, 0U); status_ = Q_HANDLED(); break; } - /*${AOs::Philo::SM::eating} */ + //${AOs::Philo::SM::eating} case Q_EXIT_SIG: { TableEvt *pe = Q_NEW(TableEvt, DONE_SIG); pe->philoNum = PHILO_ID(me); - QF_PUBLISH(&pe->super, &me->super); + QACTIVE_PUBLISH(&pe->super, &me->super); status_ = Q_HANDLED(); break; } - /*${AOs::Philo::SM::eating::TIMEOUT} */ + //${AOs::Philo::SM::eating::TIMEOUT} case TIMEOUT_SIG: { status_ = Q_TRAN(&Philo_thinking); break; } - /*${AOs::Philo::SM::eating::EAT, DONE} */ - case EAT_SIG: /* intentionally fall through */ + //${AOs::Philo::SM::eating::EAT, DONE} + case EAT_SIG: // intentionally fall through case DONE_SIG: { - /* EAT or DONE must be for other Philos than this one */ + // EAT or DONE must be for other Philos than this one Q_ASSERT(Q_EVT_CAST(TableEvt)->philoNum != PHILO_ID(me)); status_ = Q_HANDLED(); break; @@ -248,4 +251,4 @@ static QState Philo_eating(Philo * const me, QEvt const * const e) { } return status_; } -/*$enddef${AOs::Philo} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$enddef${AOs::Philo} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/examples/esp-idf/dpp-esp32devkitc/main/table.c b/examples/esp-idf/dpp-esp32devkitc/main/table.c index 9a0c3d19..e504b951 100644 --- a/examples/esp-idf/dpp-esp32devkitc/main/table.c +++ b/examples/esp-idf/dpp-esp32devkitc/main/table.c @@ -1,85 +1,85 @@ -/*$file${.::table.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* -* Model: dpp.qm -* File: ${.::table.c} -* -* This code has been generated by QM 5.2.4 . -* DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. -* -* SPDX-License-Identifier: GPL-3.0-or-later -* -* This generated code is open source software: you can redistribute it under -* the terms of the GNU General Public License as published by the Free -* Software Foundation. -* -* This code is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -* more details. -* -* NOTE: -* Alternatively, this generated code may be distributed under the terms -* of Quantum Leaps commercial licenses, which expressly supersede the GNU -* General Public License and are specifically designed for licensees -* interested in retaining the proprietary status of their code. -* -* Contact information: -* -* -*/ -/*$endhead${.::table.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$file${.::table.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// +// Model: dpp.qm +// File: ${.::table.c} +// +// This code has been generated by QM 5.3.0 . +// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. +// +// SPDX-License-Identifier: GPL-3.0-or-later +// +// This generated code is open source software: you can redistribute it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation. +// +// This code is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// NOTE: +// Alternatively, this generated code may be distributed under the terms +// of Quantum Leaps commercial licenses, which expressly supersede the GNU +// General Public License and are specifically designed for licensees +// interested in retaining the proprietary status of their code. +// +// Contact information: +// +// +// +//$endhead${.::table.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ #include "qpc.h" #include "dpp.h" -#include "esp_log.h" +#include "bsp.h" Q_DEFINE_THIS_FILE -static const char * TAG = "table"; -/* Active object class -----------------------------------------------------*/ -/*$declare${AOs::Table} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +// Active object class ----------------------------------------------------- +//$declare${AOs::Table} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/*${AOs::Table} ............................................................*/ -typedef struct { -/* protected: */ +//${AOs::Table} .............................................................. +typedef struct Table { +// protected: QActive super; -/* private: */ +// public: + +// private: uint8_t fork[N_PHILO]; uint8_t isHungry[N_PHILO]; } Table; +extern Table Table_inst; -/* protected: */ +// protected: static QState Table_initial(Table * const me, void const * const par); static QState Table_active(Table * const me, QEvt const * const e); static QState Table_serving(Table * const me, QEvt const * const e); static QState Table_paused(Table * const me, QEvt const * const e); -/*$enddecl${AOs::Table} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$enddecl${AOs::Table} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ #define RIGHT(n_) ((uint8_t)(((n_) + (N_PHILO - 1U)) % N_PHILO)) #define LEFT(n_) ((uint8_t)(((n_) + 1U) % N_PHILO)) #define FREE ((uint8_t)0) #define USED ((uint8_t)1) -/* Local objects -----------------------------------------------------------*/ -static Table l_table; /* the single instance of the Table active object */ - -/* Global-scope objects ----------------------------------------------------*/ -QActive * const AO_Table = &l_table.super; /* "opaque" AO pointer */ - -/*..........................................................................*/ -/*$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* Check for the minimum required QP version */ -#if (QP_VERSION < 700U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) -#error qpc version 7.0.0 or higher required +//$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// Check for the minimum required QP version +#if (QP_VERSION < 730U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) +#error qpc version 7.3.0 or higher required #endif -/*$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -/*$define${AOs::Table_ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//$define${AOs::AO_Table} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/*${AOs::Table_ctor} .......................................................*/ +//${AOs::AO_Table} ........................................................... +QActive * const AO_Table = &Table_inst.super; // "opaque" pointer to Table AO +//$enddef${AOs::AO_Table} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +//$define${AOs::Table_ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${AOs::Table_ctor} ......................................................... void Table_ctor(void) { + Table *me = &Table_inst; uint8_t n; - Table *me = &l_table; QActive_ctor(&me->super, Q_STATE_CAST(&Table_initial)); @@ -88,35 +88,28 @@ void Table_ctor(void) { me->isHungry[n] = 0U; } } -/*$enddef${AOs::Table_ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*$define${AOs::Table} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//$enddef${AOs::Table_ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +//$define${AOs::Table} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/*${AOs::Table} ............................................................*/ +//${AOs::Table} .............................................................. +Table Table_inst; -/*${AOs::Table::SM} ........................................................*/ +//${AOs::Table::SM} .......................................................... static QState Table_initial(Table * const me, void const * const par) { - /*${AOs::Table::SM::initial} */ - (void)par; /* unused parameter */ + //${AOs::Table::SM::initial} + Q_UNUSED_PAR(par); - QS_OBJ_DICTIONARY(&l_table); + QS_OBJ_DICTIONARY(&Table_inst); - QS_SIG_DICTIONARY(DONE_SIG, (void *)0); /* global signals */ - QS_SIG_DICTIONARY(EAT_SIG, (void *)0); - QS_SIG_DICTIONARY(PAUSE_SIG, (void *)0); - QS_SIG_DICTIONARY(SERVE_SIG, (void *)0); - QS_SIG_DICTIONARY(TEST_SIG, (void *)0); - - QS_SIG_DICTIONARY(HUNGRY_SIG, me); /* signal just for Table */ - - QActive_subscribe(&me->super, DONE_SIG); - QActive_subscribe(&me->super, PAUSE_SIG); - QActive_subscribe(&me->super, SERVE_SIG); - QActive_subscribe(&me->super, TEST_SIG); + QActive_subscribe(&me->super, (enum_t)DONE_SIG); + QActive_subscribe(&me->super, (enum_t)PAUSE_SIG); + QActive_subscribe(&me->super, (enum_t)SERVE_SIG); + QActive_subscribe(&me->super, (enum_t)TEST_SIG); for (uint8_t n = 0U; n < N_PHILO; ++n) { me->fork[n] = FREE; me->isHungry[n] = 0U; - ESP_LOGI(TAG, "Philo%d thinking", n); + BSP_displayPhilStat(n, "thinking"); } QS_FUN_DICTIONARY(&Table_active); @@ -126,16 +119,16 @@ static QState Table_initial(Table * const me, void const * const par) { return Q_TRAN(&Table_serving); } -/*${AOs::Table::SM::active} ................................................*/ +//${AOs::Table::SM::active} .................................................. static QState Table_active(Table * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${AOs::Table::SM::active::TEST} */ + //${AOs::Table::SM::active::TEST} case TEST_SIG: { status_ = Q_HANDLED(); break; } - /*${AOs::Table::SM::active::EAT} */ + //${AOs::Table::SM::active::EAT} case EAT_SIG: { Q_ERROR(); status_ = Q_HANDLED(); @@ -149,14 +142,14 @@ static QState Table_active(Table * const me, QEvt const * const e) { return status_; } -/*${AOs::Table::SM::active::serving} .......................................*/ +//${AOs::Table::SM::active::serving} ......................................... static QState Table_serving(Table * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${AOs::Table::SM::active::serving} */ + //${AOs::Table::SM::active::serving} case Q_ENTRY_SIG: { uint8_t n; - for (n = 0U; n < N_PHILO; ++n) { /* give permissions to eat... */ + for (n = 0U; n < N_PHILO; ++n) { // give permissions to eat... if ((me->isHungry[n] != 0U) && (me->fork[LEFT(n)] == FREE) && (me->fork[n] == FREE)) @@ -167,60 +160,59 @@ static QState Table_serving(Table * const me, QEvt const * const e) { me->fork[n] = USED; te = Q_NEW(TableEvt, EAT_SIG); te->philoNum = n; - QF_PUBLISH(&te->super, &me->super); + QACTIVE_PUBLISH(&te->super, &me->super); me->isHungry[n] = 0U; - ESP_LOGI(TAG, "Philo%d eating", n); + BSP_displayPhilStat(n, "eating "); } } status_ = Q_HANDLED(); break; } - /*${AOs::Table::SM::active::serving::HUNGRY} */ + //${AOs::Table::SM::active::serving::HUNGRY} case HUNGRY_SIG: { uint8_t n, m; n = Q_EVT_CAST(TableEvt)->philoNum; - /* phil ID must be in range and he must be not hungry */ + // phil ID must be in range and he must be not hungry Q_ASSERT((n < N_PHILO) && (me->isHungry[n] == 0U)); - ESP_LOGI(TAG, "Philo%d hungry", n); + BSP_displayPhilStat(n, "hungry "); m = LEFT(n); - /*${AOs::Table::SM::active::serving::HUNGRY::[bothfree]} */ + //${AOs::Table::SM::active::serving::HUNGRY::[bothfree]} if ((me->fork[m] == FREE) && (me->fork[n] == FREE)) { TableEvt *pe; me->fork[m] = USED; me->fork[n] = USED; pe = Q_NEW(TableEvt, EAT_SIG); pe->philoNum = n; - QF_PUBLISH(&pe->super, &me->super); - ESP_LOGI(TAG, "Philo%d eating", n); - + QACTIVE_PUBLISH(&pe->super, &me->super); + BSP_displayPhilStat(n, "eating "); status_ = Q_HANDLED(); } - /*${AOs::Table::SM::active::serving::HUNGRY::[else]} */ + //${AOs::Table::SM::active::serving::HUNGRY::[else]} else { me->isHungry[n] = 1U; status_ = Q_HANDLED(); } break; } - /*${AOs::Table::SM::active::serving::DONE} */ + //${AOs::Table::SM::active::serving::DONE} case DONE_SIG: { uint8_t n, m; TableEvt *pe; n = Q_EVT_CAST(TableEvt)->philoNum; - /* phil ID must be in range and he must be not hungry */ + // phil ID must be in range and he must be not hungry Q_ASSERT((n < N_PHILO) && (me->isHungry[n] == 0U)); - ESP_LOGI(TAG, "Philo%d thinking", n); + BSP_displayPhilStat(n, "thinking"); m = LEFT(n); - /* both forks of Phil[n] must be used */ + // both forks of Phil[n] must be used Q_ASSERT((me->fork[n] == USED) && (me->fork[m] == USED)); me->fork[m] = FREE; me->fork[n] = FREE; - m = RIGHT(n); /* check the right neighbor */ + m = RIGHT(n); // check the right neighbor if ((me->isHungry[m] != 0U) && (me->fork[m] == FREE)) { me->fork[n] = USED; @@ -228,30 +220,24 @@ static QState Table_serving(Table * const me, QEvt const * const e) { me->isHungry[m] = 0U; pe = Q_NEW(TableEvt, EAT_SIG); pe->philoNum = m; - QF_PUBLISH(&pe->super, &me->super); - ESP_LOGI(TAG, "Philo%d eating", m); + QACTIVE_PUBLISH(&pe->super, &me->super); + BSP_displayPhilStat(m, "eating "); } - m = LEFT(n); /* check the left neighbor */ - n = LEFT(m); /* left fork of the left neighbor */ + m = LEFT(n); // check the left neighbor + n = LEFT(m); // left fork of the left neighbor if ((me->isHungry[m] != 0U) && (me->fork[n] == FREE)) { me->fork[m] = USED; me->fork[n] = USED; me->isHungry[m] = 0U; pe = Q_NEW(TableEvt, EAT_SIG); pe->philoNum = m; - QF_PUBLISH(&pe->super, &me->super); - ESP_LOGI(TAG, "Philo%d eating", m); + QACTIVE_PUBLISH(&pe->super, &me->super); + BSP_displayPhilStat(m, "eating "); } status_ = Q_HANDLED(); break; } - /*${AOs::Table::SM::active::serving::EAT} */ - case EAT_SIG: { - Q_ERROR(); - status_ = Q_HANDLED(); - break; - } - /*${AOs::Table::SM::active::serving::PAUSE} */ + //${AOs::Table::SM::active::serving::PAUSE} case PAUSE_SIG: { status_ = Q_TRAN(&Table_paused); break; @@ -264,51 +250,48 @@ static QState Table_serving(Table * const me, QEvt const * const e) { return status_; } -/*${AOs::Table::SM::active::paused} ........................................*/ +//${AOs::Table::SM::active::paused} .......................................... static QState Table_paused(Table * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${AOs::Table::SM::active::paused} */ + //${AOs::Table::SM::active::paused} case Q_ENTRY_SIG: { - ESP_LOGI(TAG, "Paused(1)"); - + BSP_displayPaused(1U); status_ = Q_HANDLED(); break; } - /*${AOs::Table::SM::active::paused} */ + //${AOs::Table::SM::active::paused} case Q_EXIT_SIG: { - ESP_LOGI(TAG, "Paused(0)"); - + BSP_displayPaused(0U); status_ = Q_HANDLED(); break; } - /*${AOs::Table::SM::active::paused::SERVE} */ + //${AOs::Table::SM::active::paused::SERVE} case SERVE_SIG: { status_ = Q_TRAN(&Table_serving); break; } - /*${AOs::Table::SM::active::paused::HUNGRY} */ + //${AOs::Table::SM::active::paused::HUNGRY} case HUNGRY_SIG: { uint8_t n = Q_EVT_CAST(TableEvt)->philoNum; - /* philo ID must be in range and he must be not hungry */ + // philo ID must be in range and he must be not hungry Q_ASSERT((n < N_PHILO) && (me->isHungry[n] == 0U)); me->isHungry[n] = 1U; - ESP_LOGI(TAG, "Philo%d hungry", n); - + BSP_displayPhilStat(n, "hungry "); status_ = Q_HANDLED(); break; } - /*${AOs::Table::SM::active::paused::DONE} */ + //${AOs::Table::SM::active::paused::DONE} case DONE_SIG: { uint8_t n, m; n = Q_EVT_CAST(TableEvt)->philoNum; - /* phil ID must be in range and he must be not hungry */ + // phil ID must be in range and he must be not hungry Q_ASSERT((n < N_PHILO) && (me->isHungry[n] == 0U)); - ESP_LOGI(TAG, "Philo%d thinking", n); + BSP_displayPhilStat(n, "thinking"); m = LEFT(n); - /* both forks of Phil[n] must be used */ + // both forks of Phil[n] must be used Q_ASSERT((me->fork[n] == USED) && (me->fork[m] == USED)); me->fork[m] = FREE; @@ -323,5 +306,4 @@ static QState Table_paused(Table * const me, QEvt const * const e) { } return status_; } -/*$enddef${AOs::Table} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ - +//$enddef${AOs::Table} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/examples/freertos/arm-cm/dpp_ek-tm4c123gxl/FreeRTOSConfig.h b/examples/freertos/arm-cm/dpp_ek-tm4c123gxl/FreeRTOSConfig.h index 473ef386..9ae0fc5d 100644 --- a/examples/freertos/arm-cm/dpp_ek-tm4c123gxl/FreeRTOSConfig.h +++ b/examples/freertos/arm-cm/dpp_ek-tm4c123gxl/FreeRTOSConfig.h @@ -1,46 +1,46 @@ -/* Modified by Quantum Leaps - */ -/* - * FreeRTOS Kernel V10.0.1 - * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * http://www.FreeRTOS.org - * http://aws.amazon.com/freertos - * - * 1 tab == 4 spaces! - */ +// Modified by Quantum Leaps +// +// +// FreeRTOS Kernel V10.0.1 +// Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +// http://www.FreeRTOS.org +// http://aws.amazon.com/freertos +// +// 1 tab == 4 spaces! +// #ifndef FREERTOS_CONFIG_H #define FREERTOS_CONFIG_H -/*----------------------------------------------------------- - * Application specific definitions. - * - * These definitions should be adjusted for your particular hardware and - * application requirements. - * - * THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE - * FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE. - * - * See http://www.freertos.org/a00110.html. - *----------------------------------------------------------*/ +//----------------------------------------------------------- +// Application specific definitions. +// +// These definitions should be adjusted for your particular hardware and +// application requirements. +// +// THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE +// FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE. +// +// See http://www.freertos.org/a00110.html. +// ---------------------------------------------------------- #define configUSE_PREEMPTION 1 #define configUSE_IDLE_HOOK 1 @@ -59,6 +59,7 @@ #define configCHECK_FOR_STACK_OVERFLOW 2 #define configUSE_QUEUE_SETS 0 #define configUSE_COUNTING_SEMAPHORES 1 +#define configUSE_MALLOC_FAILED_HOOK 0 #define configMAX_PRIORITIES ( 32UL ) #define configMAX_CO_ROUTINE_PRIORITIES ( 2 ) @@ -66,14 +67,14 @@ #define configSUPPORT_DYNAMIC_ALLOCATION 0 #define configSUPPORT_STATIC_ALLOCATION 1 -/* Timer related defines. */ +// Timer related defines. #define configUSE_TIMERS 0 #define configTIMER_TASK_PRIORITY 2 #define configTIMER_QUEUE_LENGTH 20 #define configTIMER_TASK_STACK_DEPTH ( configMINIMAL_STACK_SIZE * 2 ) -/* Set the following definitions to 1 to include the API function, or zero -to exclude the API function. */ +// Set the following definitions to 1 to include the API function, or zero +// to exclude the API function. #define INCLUDE_vTaskPrioritySet 1 #define INCLUDE_uxTaskPriorityGet 1 @@ -90,26 +91,26 @@ to exclude the API function. */ #define INCLUDE_eTaskGetState 1 #define INCLUDE_xTimerPendFunctionCall 0 -#define configKERNEL_INTERRUPT_PRIORITY ( 7 << 5 ) /* Priority 7, or 255 as only the top three bits are implemented. This is the lowest priority. */ -/* !!!! configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to zero !!!! -See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html. */ -#define configMAX_SYSCALL_INTERRUPT_PRIORITY ( 5 << 5 ) /* Priority 5, or 160 as only the top three bits are implemented. */ +#define configKERNEL_INTERRUPT_PRIORITY ( 7 << 5 ) // Priority 7, or 255 as only the top three bits are implemented. This is the lowest priority. +// !!!! configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to zero !!!! +// See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html. +#define configMAX_SYSCALL_INTERRUPT_PRIORITY ( 5 << 5 ) // Priority 5, or 160 as only the top three bits are implemented. -/* Use the Cortex-M3 optimised task selection rather than the generic C code -version. */ +// Use the Cortex-M3 optimised task selection rather than the generic C code +// version. #define configUSE_PORT_OPTIMISED_TASK_SELECTION 1 -/* Prevent the inclusion of items the assembler will not understand in assembly files. */ +// Prevent the inclusion of items the assembler will not understand in assembly files. #ifndef __IAR_SYSTEMS_ASM__ #define configASSERT( x ) if( ( x ) == 0 ) assert_failed( __FILE__, __LINE__ ); - void assert_failed(char const * const module, int location); + void assert_failed(char const * const module, int const id); extern uint32_t SystemCoreClock; #endif -/* Map the FreeRTOS port interrupt handlers to their CMSIS standard names. */ +// Map the FreeRTOS port interrupt handlers to their CMSIS standard names. #define vPortSVCHandler SVC_Handler #define xPortPendSVHandler PendSV_Handler #define xPortSysTickHandler SysTick_Handler -#endif /* FREERTOS_CONFIG_H */ +#endif // FREERTOS_CONFIG_H diff --git a/examples/freertos/arm-cm/dpp_ek-tm4c123gxl/armclang/dpp.uvoptx b/examples/freertos/arm-cm/dpp_ek-tm4c123gxl/armclang/dpp.uvoptx index ab67cde4..05d0eabb 100644 --- a/examples/freertos/arm-cm/dpp_ek-tm4c123gxl/armclang/dpp.uvoptx +++ b/examples/freertos/arm-cm/dpp_ek-tm4c123gxl/armclang/dpp.uvoptx @@ -75,7 +75,7 @@ 1 0 - 1 + 0 4 @@ -147,9 +147,25 @@ 0 0 + 491 + 1 +
10530
+ 0 + 0 + 0 + 0 + 0 + 1 + ..\bsp.c + + \\dpp\../bsp.c\491 +
+ + 1 + 0 321 1 -
1050
+
1116
0 0 0 @@ -161,36 +177,20 @@ \\dpp\../../../../../3rd_party/ek-tm4c123gxl/arm/startup_TM4C123GH6PM.s\321
- 1 + 2 0 333 1 -
1056
+
0
0 0 0 0 0 - 1 + 0 ..\..\..\..\..\3rd_party\ek-tm4c123gxl\arm\startup_TM4C123GH6PM.s - \\dpp\../../../../../3rd_party/ek-tm4c123gxl/arm/startup_TM4C123GH6PM.s\333 -
- - 2 - 0 - 267 - 1 -
8136
- 0 - 0 - 0 - 0 - 0 - 1 - ..\..\..\..\..\3rd_party\FreeRTOS\Source\portable\GCC\ARM_CM4F\port.c - - \\dpp\../../../../../3rd_party/FreeRTOS/Source/portable/GCC/ARM_CM4F/port.c\267 +
@@ -499,7 +499,7 @@ 1 0 - 0 + 1 4 @@ -654,7 +654,7 @@ 0 0 0 - ..\..\..\..\..\include\qstamp.c + ..\..\..\..\..\src\qs\qstamp.c qstamp.c 0 0 @@ -719,6 +719,18 @@ 0 0 + + 1 + 8 + 5 + 0 + 0 + 0 + ..\qp_config.h + qp_config.h + 0 + 0 + @@ -729,7 +741,7 @@ 0 2 - 8 + 9 1 0 0 @@ -741,7 +753,7 @@ 2 - 9 + 10 5 0 0 @@ -753,7 +765,7 @@ 2 - 10 + 11 5 0 0 @@ -765,7 +777,7 @@ 2 - 11 + 12 5 0 0 @@ -777,7 +789,7 @@ 2 - 12 + 13 5 0 0 @@ -789,7 +801,7 @@ 2 - 13 + 14 5 0 0 @@ -801,7 +813,7 @@ 2 - 14 + 15 2 0 0 @@ -821,7 +833,7 @@ 0 3 - 15 + 16 1 0 0 @@ -833,7 +845,7 @@ 3 - 16 + 17 1 0 0 @@ -845,7 +857,7 @@ 3 - 17 + 18 1 0 0 @@ -857,7 +869,7 @@ 3 - 18 + 19 1 0 0 @@ -869,7 +881,7 @@ 3 - 19 + 20 1 0 0 @@ -881,7 +893,7 @@ 3 - 20 + 21 1 0 0 @@ -893,7 +905,7 @@ 3 - 21 + 22 1 0 0 @@ -905,7 +917,7 @@ 3 - 22 + 23 1 0 0 @@ -917,7 +929,7 @@ 3 - 23 + 24 1 0 0 @@ -929,7 +941,7 @@ 3 - 24 + 25 1 0 0 @@ -941,7 +953,7 @@ 3 - 25 + 26 1 0 0 @@ -961,7 +973,7 @@ 0 4 - 26 + 27 1 0 0 @@ -971,18 +983,6 @@ 0 0 - - 4 - 27 - 5 - 0 - 0 - 0 - ..\..\..\..\..\ports\freertos\qf_port.h - qf_port.h - 0 - 0 - 4 28 @@ -1022,30 +1022,6 @@ 0 0 0 - ..\..\..\..\..\src\qs\qs_64bit.c - qs_64bit.c - 0 - 0 - - - 5 - 31 - 1 - 0 - 0 - 0 - ..\..\..\..\..\src\qs\qs_fp.c - qs_fp.c - 0 - 0 - - - 5 - 32 - 1 - 0 - 0 - 0 ..\..\..\..\..\src\qs\qs_rx.c qs_rx.c 0 @@ -1061,36 +1037,36 @@ 0 6 - 33 + 31 1 0 0 0 - ..\..\..\..\..\3rd_party\FreeRTOS\Source\list.c + ..\..\..\..\..\3rd_party\FreeRTOS-Kernel\list.c list.c 0 0 6 - 34 + 32 1 0 0 0 - ..\..\..\..\..\3rd_party\FreeRTOS\Source\queue.c + ..\..\..\..\..\3rd_party\FreeRTOS-Kernel\queue.c queue.c 0 0 6 - 35 + 33 1 0 0 0 - ..\..\..\..\..\3rd_party\FreeRTOS\Source\tasks.c + ..\..\..\..\..\3rd_party\FreeRTOS-Kernel\tasks.c tasks.c 0 0 @@ -1105,12 +1081,12 @@ 0 7 - 36 + 34 1 0 0 0 - ..\..\..\..\..\3rd_party\FreeRTOS\Source\portable\GCC\ARM_CM4F\port.c + ..\..\..\..\..\3rd_party\FreeRTOS-Kernel\portable\GCC\ARM_CM4F\port.c port.c 0 0 diff --git a/examples/freertos/arm-cm/dpp_ek-tm4c123gxl/armclang/dpp.uvprojx b/examples/freertos/arm-cm/dpp_ek-tm4c123gxl/armclang/dpp.uvprojx index 0b5f6b68..10f5dd16 100644 --- a/examples/freertos/arm-cm/dpp_ek-tm4c123gxl/armclang/dpp.uvprojx +++ b/examples/freertos/arm-cm/dpp_ek-tm4c123gxl/armclang/dpp.uvprojx @@ -313,7 +313,7 @@ 0 - 7 + 1 0 0 1 @@ -337,9 +337,9 @@ 0 - __FPU_PRESENT + QP_CONFIG - ..;..\..\..\..\..\include;..\..\..\..\..\ports\freertos;..\..\..\..\..\3rd_party\FreeRTOS\Source\include;..\..\..\..\..\3rd_party\FreeRTOS\Source\portable\GCC\ARM_CM4F;..\..\..\..\..\3rd_party\ek-tm4c123gxl;..\..\..\..\..\3rd_party\CMSIS\Include + ..;..\..\..\..\..\include;..\..\..\..\..\ports\freertos;..\..\..\..\..\3rd_party\FreeRTOS-Kernel\include;..\..\..\..\..\3rd_party\FreeRTOS-Kernel\portable\GCC\ARM_CM4F;..\..\..\..\..\3rd_party\ek-tm4c123gxl;..\..\..\..\..\3rd_party\CMSIS\Include @@ -391,7 +391,7 @@ qstamp.c 1 - ..\..\..\..\..\include\qstamp.c + ..\..\..\..\..\src\qs\qstamp.c main.c @@ -418,6 +418,11 @@ 1 ..\table.c + + qp_config.h + 5 + ..\qp_config.h + @@ -528,11 +533,6 @@ 1 ..\..\..\..\..\ports\freertos\qf_port.c - - qf_port.h - 5 - ..\..\..\..\..\ports\freertos\qf_port.h - qs_port.h 5 @@ -617,16 +617,6 @@ 1 ..\..\..\..\..\src\qs\qs.c - - qs_64bit.c - 1 - ..\..\..\..\..\src\qs\qs_64bit.c - - - qs_fp.c - 1 - ..\..\..\..\..\src\qs\qs_fp.c - qs_rx.c 1 @@ -640,17 +630,17 @@ list.c 1 - ..\..\..\..\..\3rd_party\FreeRTOS\Source\list.c + ..\..\..\..\..\3rd_party\FreeRTOS-Kernel\list.c queue.c 1 - ..\..\..\..\..\3rd_party\FreeRTOS\Source\queue.c + ..\..\..\..\..\3rd_party\FreeRTOS-Kernel\queue.c tasks.c 1 - ..\..\..\..\..\3rd_party\FreeRTOS\Source\tasks.c + ..\..\..\..\..\3rd_party\FreeRTOS-Kernel\tasks.c @@ -660,7 +650,7 @@ port.c 1 - ..\..\..\..\..\3rd_party\FreeRTOS\Source\portable\GCC\ARM_CM4F\port.c + ..\..\..\..\..\3rd_party\FreeRTOS-Kernel\portable\GCC\ARM_CM4F\port.c @@ -997,9 +987,9 @@ 0 - NDEBUG __FPU_PRESENT + NDEBUG,QP_CONFIG - ..;..\..\..\..\..\include;..\..\..\..\..\ports\freertos;..\..\..\..\..\3rd_party\FreeRTOS\Source\include;..\..\..\..\..\3rd_party\FreeRTOS\Source\portable\GCC\ARM_CM4F;..\..\..\..\..\3rd_party\ek-tm4c123gxl;..\..\..\..\..\3rd_party\CMSIS\Include + ..;..\..\..\..\..\include;..\..\..\..\..\ports\freertos;..\..\..\..\..\3rd_party\FreeRTOS-Kernel\include;..\..\..\..\..\3rd_party\FreeRTOS-Kernel\portable\GCC\ARM_CM4F;..\..\..\..\..\3rd_party\ek-tm4c123gxl;..\..\..\..\..\3rd_party\CMSIS\Include
@@ -1051,7 +1041,7 @@ qstamp.c 1 - ..\..\..\..\..\include\qstamp.c + ..\..\..\..\..\src\qs\qstamp.c main.c @@ -1078,6 +1068,11 @@ 1 ..\table.c + + qp_config.h + 5 + ..\qp_config.h + @@ -1188,11 +1183,6 @@ 1 ..\..\..\..\..\ports\freertos\qf_port.c - - qf_port.h - 5 - ..\..\..\..\..\ports\freertos\qf_port.h - qs_port.h 5 @@ -1277,16 +1267,6 @@ 1 ..\..\..\..\..\src\qs\qs.c - - qs_64bit.c - 1 - ..\..\..\..\..\src\qs\qs_64bit.c - - - qs_fp.c - 1 - ..\..\..\..\..\src\qs\qs_fp.c - qs_rx.c 1 @@ -1300,17 +1280,17 @@ list.c 1 - ..\..\..\..\..\3rd_party\FreeRTOS\Source\list.c + ..\..\..\..\..\3rd_party\FreeRTOS-Kernel\list.c queue.c 1 - ..\..\..\..\..\3rd_party\FreeRTOS\Source\queue.c + ..\..\..\..\..\3rd_party\FreeRTOS-Kernel\queue.c tasks.c 1 - ..\..\..\..\..\3rd_party\FreeRTOS\Source\tasks.c + ..\..\..\..\..\3rd_party\FreeRTOS-Kernel\tasks.c @@ -1320,7 +1300,7 @@ port.c 1 - ..\..\..\..\..\3rd_party\FreeRTOS\Source\portable\GCC\ARM_CM4F\port.c + ..\..\..\..\..\3rd_party\FreeRTOS-Kernel\portable\GCC\ARM_CM4F\port.c @@ -1657,9 +1637,9 @@ 0 - Q_SPY __FPU_PRESENT + Q_SPY,QP_CONFIG - ..;..\..\..\..\..\include;..\..\..\..\..\ports\freertos;..\..\..\..\..\3rd_party\FreeRTOS\Source\include;..\..\..\..\..\3rd_party\FreeRTOS\Source\portable\GCC\ARM_CM4F;..\..\..\..\..\3rd_party\ek-tm4c123gxl;..\..\..\..\..\3rd_party\CMSIS\Include + ..;..\..\..\..\..\include;..\..\..\..\..\ports\freertos;..\..\..\..\..\3rd_party\FreeRTOS-Kernel\include;..\..\..\..\..\3rd_party\FreeRTOS-Kernel\portable\GCC\ARM_CM4F;..\..\..\..\..\3rd_party\ek-tm4c123gxl;..\..\..\..\..\3rd_party\CMSIS\Include @@ -1711,7 +1691,7 @@ qstamp.c 1 - ..\..\..\..\..\include\qstamp.c + ..\..\..\..\..\src\qs\qstamp.c main.c @@ -1738,6 +1718,11 @@ 1 ..\table.c + + qp_config.h + 5 + ..\qp_config.h + @@ -1848,11 +1833,6 @@ 1 ..\..\..\..\..\ports\freertos\qf_port.c - - qf_port.h - 5 - ..\..\..\..\..\ports\freertos\qf_port.h - qs_port.h 5 @@ -1868,16 +1848,6 @@ 1 ..\..\..\..\..\src\qs\qs.c - - qs_64bit.c - 1 - ..\..\..\..\..\src\qs\qs_64bit.c - - - qs_fp.c - 1 - ..\..\..\..\..\src\qs\qs_fp.c - qs_rx.c 1 @@ -1891,17 +1861,17 @@ list.c 1 - ..\..\..\..\..\3rd_party\FreeRTOS\Source\list.c + ..\..\..\..\..\3rd_party\FreeRTOS-Kernel\list.c queue.c 1 - ..\..\..\..\..\3rd_party\FreeRTOS\Source\queue.c + ..\..\..\..\..\3rd_party\FreeRTOS-Kernel\queue.c tasks.c 1 - ..\..\..\..\..\3rd_party\FreeRTOS\Source\tasks.c + ..\..\..\..\..\3rd_party\FreeRTOS-Kernel\tasks.c @@ -1911,7 +1881,7 @@ port.c 1 - ..\..\..\..\..\3rd_party\FreeRTOS\Source\portable\GCC\ARM_CM4F\port.c + ..\..\..\..\..\3rd_party\FreeRTOS-Kernel\portable\GCC\ARM_CM4F\port.c diff --git a/examples/freertos/arm-cm/dpp_ek-tm4c123gxl/bsp.c b/examples/freertos/arm-cm/dpp_ek-tm4c123gxl/bsp.c index 43514d76..745be970 100644 --- a/examples/freertos/arm-cm/dpp_ek-tm4c123gxl/bsp.c +++ b/examples/freertos/arm-cm/dpp_ek-tm4c123gxl/bsp.c @@ -1,66 +1,64 @@ -/***************************************************************************** -* Product: DPP example, EK-TM4C123GXL board, FreeRTOS kernel -* Last updated for version 7.2.0 -* Last updated on 2022-12-17 -* -* Q u a n t u m L e a P s -* ------------------------ -* Modern Embedded Software -* -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* -* -*****************************************************************************/ -#include "qpc.h" -#include "dpp.h" -#include "bsp.h" +//============================================================================ +// Product: DPP example, EK-TM4C123GXL board, FreeRTOS kernel +// Last updated for version 7.3.0 +// Last updated on 2023-08-29 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +//============================================================================ +#include "qpc.h" // QP/C real-time embedded framework +#include "dpp.h" // DPP Application interface +#include "bsp.h" // Board Support Package -#include "TM4C123GH6PM.h" /* the device specific header (TI) */ -#include "rom.h" /* the built-in ROM functions (TI) */ -#include "sysctl.h" /* system control driver (TI) */ -#include "gpio.h" /* GPIO driver (TI) */ -/* add other drivers if necessary... */ +#include "TM4C123GH6PM.h" // the device specific header (TI) +#include "rom.h" // the built-in ROM functions (TI) +#include "sysctl.h" // system control driver (TI) +#include "gpio.h" // GPIO driver (TI) +// add other drivers if necessary... -Q_DEFINE_THIS_FILE /* define the name of this file for assertions */ +Q_DEFINE_THIS_FILE // define the name of this file for assertions -/* LEDs and Switches of the EK-TM4C123GXL board ............................*/ -#define LED_RED (1U << 1) -#define LED_GREEN (1U << 3) -#define LED_BLUE (1U << 2) +// LEDs and Switches of the EK-TM4C123GXL board ............................ +#define LED_RED (1U << 1U) +#define LED_GREEN (1U << 3U) +#define LED_BLUE (1U << 2U) -#define BTN_SW1 (1U << 4) -#define BTN_SW2 (1U << 0) +#define BTN_SW1 (1U << 4U) +#define BTN_SW2 (1U << 0U) -/* "RTOS-aware" interrupt priorities for FreeRTOS on ARM Cortex-M, NOTE1 */ +// "RTOS-aware" interrupt priorities for FreeRTOS on ARM Cortex-M, NOTE1 #define RTOS_AWARE_ISR_CMSIS_PRI \ (configMAX_SYSCALL_INTERRUPT_PRIORITY >> (8-__NVIC_PRIO_BITS)) -/* Local-scope objects ------------------------------------------------------*/ -static uint32_t l_rnd; // random seed +// Local-scope objects ----------------------------------------------------- +static uint32_t l_rndSeed; #ifdef Q_SPY - /* QS identifiers for non-QP sources of events */ + // QS identifiers for non-QP sources of events static uint8_t const l_TickHook = 0U; static uint8_t const l_GPIOPortA_IRQHandler = 0U; @@ -69,570 +67,528 @@ static uint32_t l_rnd; // random seed #define UART_FR_RXFE (1U << 4) #define UART_TXFIFO_DEPTH 16U - enum AppRecords { /* application-specific trace records */ + enum AppRecords { // application-specific trace records PHILO_STAT = QS_USER, PAUSED_STAT, - COMMAND_STAT }; #endif -/* ISRs used in this project ===============================================*/ +//============================================================================ +// Error handler -/* NOTE: this ISR is for testing of the various preemption scenarios -* by triggering the GPIOPortA interrupt from the debugger. You achieve -* this by writing 0 to the SWTRIG register at 0xE000,EF00. -* -* Code Composer Studio: From the CCS debugger you need open the register -* window and select NVIC registers from the drop-down list. You scroll to -* the NVIC_SW_TRIG register, which denotes the Software Trigger Interrupt -* Register in the NVIC. To trigger the GPIOA interrupt you need to write -* 0x00 to the NVIC_SW_TRIG by clicking on this field, entering the value, -* and pressing the Enter key. -* -* IAR EWARM: From the C-Spy debugger you need to open Registers view and -* select the "Other Systems Register" group. From there, you need to write -* 0 to the STIR write-only register and press enter. -*/ -/* NOTE: only the "FromISR" FreeRTOS API variants are allowed in the ISRs! */ -void GPIOPortA_IRQHandler(void); /* prototype */ +Q_NORETURN Q_onError(char const * const module, int_t const id) { + // NOTE: this implementation of the error handler is intended only + // for debugging and MUST be changed for deployment of the application + // (assuming that you ship your production code with assertions enabled). + Q_UNUSED_PAR(module); + Q_UNUSED_PAR(id); + QS_ASSERTION(module, id, 10000U); // report assertion to QS + +#ifndef NDEBUG + // light up all LEDs + GPIOF_AHB->DATA_Bits[LED_GREEN | LED_RED | LED_BLUE] = 0xFFU; + // for debugging, hang on in an endless loop... + for (;;) { + } +#else + NVIC_SystemReset(); + for (;;) { // explicitly "no-return" + } +#endif +} +//............................................................................ +void assert_failed(char const * const module, int_t const id); // prototype +void assert_failed(char const * const module, int_t const id) { + Q_onError(module, id); +} + +// ISRs used in the application ============================================== + +// NOTE: this ISR is for testing of the various preemption scenarios +// by triggering the GPIOPortA interrupt from the debugger. You achieve +// this by writing 0 to the SWTRIG register at 0xE000,EF00. +// +// Code Composer Studio: From the CCS debugger you need open the register +// window and select NVIC registers from the drop-down list. You scroll to +// the NVIC_SW_TRIG register, which denotes the Software Trigger Interrupt +// Register in the NVIC. To trigger the GPIOA interrupt you need to write +// 0x00 to the NVIC_SW_TRIG by clicking on this field, entering the value, +// and pressing the Enter key. +// +// IAR EWARM: From the C-Spy debugger you need to open Registers view and +// select the "Other Systems Register" group. From there, you need to write +// 0 to the STIR write-only register and press enter. +// +// NOTE: only the "FromISR" FreeRTOS API variants are allowed in the ISRs! +void GPIOPortA_IRQHandler(void); // prototype void GPIOPortA_IRQHandler(void) { BaseType_t xHigherPriorityTaskWoken = pdFALSE; - /* for testing... */ + // for testing... QACTIVE_POST_FROM_ISR(AO_Table, Q_NEW_FROM_ISR(QEvt, MAX_PUB_SIG), &xHigherPriorityTaskWoken, &l_GPIOPortA_IRQHandler); - /* the usual end of FreeRTOS ISR... */ + // the usual end of FreeRTOS ISR... portEND_SWITCHING_ISR(xHigherPriorityTaskWoken); } -/*..........................................................................*/ +//............................................................................ #ifdef Q_SPY -/* -* ISR for receiving bytes from the QSPY Back-End -* NOTE: This ISR is "kernel-unaware" meaning that it does not interact with -* the FreeRTOS or QP and is not disabled. Such ISRs don't need to call -* portEND_SWITCHING_ISR(() at the end, but they also cannot call any -* FreeRTOS or QP APIs. -*/ -void UART0_IRQHandler(void) { - uint32_t status = UART0->RIS; /* get the raw interrupt status */ - UART0->ICR = status; /* clear the asserted interrupts */ - while ((UART0->FR & UART_FR_RXFE) == 0) { /* while RX FIFO NOT empty */ +// ISR for receiving bytes from the QSPY Back-End +// NOTE: This ISR is "kernel-unaware" meaning that it does not interact with +// the FreeRTOS or QP and is not disabled. Such ISRs don't need to call +// portEND_SWITCHING_ISR(() at the end, but they also cannot call any +// FreeRTOS or QP APIs. +void UART0_IRQHandler(void); // prototype +void UART0_IRQHandler(void) { + uint32_t status = UART0->RIS; // get the raw interrupt status + UART0->ICR = status; // clear the asserted interrupts + + while ((UART0->FR & UART_FR_RXFE) == 0) { // while RX FIFO NOT empty uint32_t b = UART0->DR; QS_RX_PUT(b); } } #endif -/* Application hooks used in this project ==================================*/ -/* NOTE: only the "FromISR" API variants are allowed in vApplicationTickHook */ +// Application hooks used in this project ==================================== +// NOTE: only the "FromISR" API variants are allowed in vApplicationTickHook + void vApplicationTickHook(void) { BaseType_t xHigherPriorityTaskWoken = pdFALSE; - /* process time events for rate 0 */ + // process time events at rate 0 QTIMEEVT_TICK_FROM_ISR(0U, &xHigherPriorityTaskWoken, &l_TickHook); - /* Perform the debouncing of buttons. The algorithm for debouncing - * adapted from the book "Embedded Systems Dictionary" by Jack Ganssle - * and Michael Barr, page 71. - */ - /* state of the button debouncing, see below */ - static struct ButtonsDebouncing { + // Perform the debouncing of buttons. The algorithm for debouncing + // adapted from the book "Embedded Systems Dictionary" by Jack Ganssle + // and Michael Barr, page 71. + static struct { uint32_t depressed; uint32_t previous; } buttons = { 0U, 0U }; - uint32_t current = ~GPIOF_AHB->DATA_Bits[BTN_SW1 | BTN_SW2]; /* read SW1&SW2 */ - uint32_t tmp = buttons.depressed; /* save debounced depressed buttons */ - buttons.depressed |= (buttons.previous & current); /* set depressed */ - buttons.depressed &= (buttons.previous | current); /* clear released */ - buttons.previous = current; /* update the history */ - tmp ^= buttons.depressed; /* changed debounced depressed */ - if ((tmp & BTN_SW1) != 0U) { /* debounced SW1 state changed? */ - if ((buttons.depressed & BTN_SW1) != 0U) { /* is SW1 depressed? */ - /* demonstrate the "FromISR APIs: - * QACTIVE_PUBLISH_FROM_ISR() and Q_NEW_FROM_ISR() - */ - QACTIVE_PUBLISH_FROM_ISR(Q_NEW_FROM_ISR(QEvt, PAUSE_SIG), + + uint32_t current = ~GPIOF_AHB->DATA_Bits[BTN_SW1 | BTN_SW2]; // SW1&SW2 + uint32_t tmp = buttons.depressed; // save debounced depressed buttons + buttons.depressed |= (buttons.previous & current); // set depressed + buttons.depressed &= (buttons.previous | current); // clear released + buttons.previous = current; // update the history + tmp ^= buttons.depressed; // changed debounced depressed + current = buttons.depressed; + + if ((tmp & BTN_SW1) != 0U) { // debounced SW1 state changed? + if ((current & BTN_SW1) != 0U) { // is SW1 depressed? + static QEvt const pauseEvt = QEVT_INITIALIZER(PAUSE_SIG); + QACTIVE_PUBLISH_FROM_ISR(&pauseEvt, &xHigherPriorityTaskWoken, &l_TickHook); } - else { /* the button is released */ - /* demonstrate the ISR APIs: POST_FROM_ISR and Q_NEW_FROM_ISR */ - QACTIVE_POST_FROM_ISR(AO_Table, - Q_NEW_FROM_ISR(QEvt, SERVE_SIG), - &xHigherPriorityTaskWoken, - &l_TickHook); + else { // the button is released + static QEvt const serveEvt = QEVT_INITIALIZER(SERVE_SIG); + QACTIVE_PUBLISH_FROM_ISR(&serveEvt, + &xHigherPriorityTaskWoken, + &l_TickHook); } } - /* notify FreeRTOS to perform context switch from ISR, if needed */ + // notify FreeRTOS to perform context switch from ISR, if needed portEND_SWITCHING_ISR(xHigherPriorityTaskWoken); } -/*..........................................................................*/ +//............................................................................ void vApplicationIdleHook(void) { - /* toggle the User LED on and then off, see NOTE01 */ + // toggle the User LED on and then off, see NOTE01 QF_INT_DISABLE(); - GPIOF_AHB->DATA_Bits[LED_BLUE] = 0xFFU; /* turn the Blue LED on */ - GPIOF_AHB->DATA_Bits[LED_BLUE] = 0U; /* turn the Blue LED off */ + GPIOF_AHB->DATA_Bits[LED_BLUE] = 0xFFU; // turn the Blue LED on + GPIOF_AHB->DATA_Bits[LED_BLUE] = 0U; // turn the Blue LED off QF_INT_ENABLE(); - /* Some floating point code is to exercise the VFP... */ + // Some floating point code is to exercise the VFP... float volatile x = 1.73205F; x = x * 1.73205F; #ifdef Q_SPY - QS_rxParse(); /* parse all the received bytes */ + QS_rxParse(); // parse all the received bytes - if ((UART0->FR & UART_FR_TXFE) != 0U) { /* TX done? */ - uint16_t fifo = UART_TXFIFO_DEPTH; /* max bytes we can accept */ + if ((UART0->FR & UART_FR_TXFE) != 0U) { // TX done? + uint16_t fifo = UART_TXFIFO_DEPTH; // max bytes we can accept uint8_t const *block; QF_INT_DISABLE(); - block = QS_getBlock(&fifo); /* try to get next block to transmit */ + block = QS_getBlock(&fifo); // try to get next block to transmit QF_INT_ENABLE(); - while (fifo-- != 0) { /* any bytes in the block? */ - UART0->DR = *block++; /* put into the FIFO */ + while (fifo-- != 0U) { // any bytes in the block? + UART0->DR = *block++; // put into the FIFO } } #elif defined NDEBUG - /* Put the CPU and peripherals to the low-power mode. - * you might need to customize the clock management for your application, - * see the datasheet for your particular Cortex-M3 MCU. - */ - __WFI(); /* Wait-For-Interrupt */ + // Put the CPU and peripherals to the low-power mode. + // you might need to customize the clock management for your application, + // see the datasheet for your particular Cortex-M MCU. + // + __WFI(); // Wait-For-Interrupt #endif } -/*..........................................................................*/ +//............................................................................ void vApplicationStackOverflowHook(TaskHandle_t xTask, char *pcTaskName) { - (void)xTask; - (void)pcTaskName; + Q_UNUSED_PAR(xTask); + Q_UNUSED_PAR(pcTaskName); Q_ERROR(); } -/*..........................................................................*/ -/* configSUPPORT_STATIC_ALLOCATION is set to 1, so the application must -* provide an implementation of vApplicationGetIdleTaskMemory() to provide -* the memory that is used by the Idle task. -*/ +//............................................................................ +// configSUPPORT_STATIC_ALLOCATION is set to 1, so the application must +// provide an implementation of vApplicationGetIdleTaskMemory() to provide +// the memory that is used by the Idle task. void vApplicationGetIdleTaskMemory( StaticTask_t **ppxIdleTaskTCBBuffer, StackType_t **ppxIdleTaskStackBuffer, uint32_t *pulIdleTaskStackSize ) { - /* If the buffers to be provided to the Idle task are declared inside - * this function then they must be declared static - otherwise they will - * be allocated on the stack and so not exists after this function exits. - */ + // If the buffers to be provided to the Idle task are declared inside + // this function then they must be declared static - otherwise they will + // be allocated on the stack and so not exists after this function exits. + // static StaticTask_t xIdleTaskTCB; static StackType_t uxIdleTaskStack[ configMINIMAL_STACK_SIZE ]; - /* Pass out a pointer to the StaticTask_t structure in which the - * Idle task's state will be stored. - */ + // Pass out a pointer to the StaticTask_t structure in which the + // Idle task's state will be stored. *ppxIdleTaskTCBBuffer = &xIdleTaskTCB; - /* Pass out the array that will be used as the Idle task's stack. */ + // Pass out the array that will be used as the Idle task's stack. *ppxIdleTaskStackBuffer = uxIdleTaskStack; - /* Pass out the size of the array pointed to by *ppxIdleTaskStackBuffer. - * Note that, as the array is necessarily of type StackType_t, - * configMINIMAL_STACK_SIZE is specified in words, not bytes. - */ + // Pass out the size of the array pointed to by *ppxIdleTaskStackBuffer. + // Note that, as the array is necessarily of type StackType_t, + // configMINIMAL_STACK_SIZE is specified in words, not bytes. + // *pulIdleTaskStackSize = Q_DIM(uxIdleTaskStack); } -//* BSP functions ===========================================================*/ -/* MPU setup for TM4C123GXL MCU */ -static void TM4C123GXL_MPU_setup(void) { - /* The following MPU configuration contains the general TM4C memory map. - * - * Please note that the actual TM4C MCUs provide much less Flash and SRAM - * than the maximums configured here. This means that actual MCUs have - * unmapped memory regions (e.g., beyond the actual SRAM). Attempts to - * access these regions causes the HardFault exception, which is the - * desired behavior. - */ - static struct { - uint32_t rbar; - uint32_t rasr; - } const mpu_setup[] = { - { /* region #0: Flash: base=0x0000'0000, size=512M=2^(28+1) */ - 0x00000000U /* base address */ - | MPU_RBAR_VALID_Msk /* valid region */ - | (MPU_RBAR_REGION_Msk & 0U), /* region #0 */ - (28U << MPU_RASR_SIZE_Pos) /* 2^(18+1) region */ - | (0x6U << MPU_RASR_AP_Pos) /* PA:ro/UA:ro */ - | (1U << MPU_RASR_C_Pos) /* C=1 */ - | MPU_RASR_ENABLE_Msk /* region enable */ - }, +// BSP functions ============================================================= - { /* region #1: SRAM: base=0x2000'0000, size=512M=2^(28+1) */ - 0x20000000U /* base address */ - | MPU_RBAR_VALID_Msk /* valid region */ - | (MPU_RBAR_REGION_Msk & 1U), /* region #1 */ - (28U << MPU_RASR_SIZE_Pos) /* 2^(28+1) region */ - | (0x3U << MPU_RASR_AP_Pos) /* PA:rw/UA:rw */ - | (1U << MPU_RASR_XN_Pos) /* XN=1 */ - | (1U << MPU_RASR_S_Pos) /* S=1 */ - | (1U << MPU_RASR_C_Pos) /* C=1 */ - | MPU_RASR_ENABLE_Msk /* region enable */ - }, +//............................................................................ +void BSP_init(void) { + // Configure the MPU to prevent NULL-pointer dereferencing ... + MPU->RBAR = 0x0U // base address (NULL) + | MPU_RBAR_VALID_Msk // valid region + | (MPU_RBAR_REGION_Msk & 7U); // region #7 + MPU->RASR = (7U << MPU_RASR_SIZE_Pos) // 2^(7+1) region + | (0x0U << MPU_RASR_AP_Pos) // no-access region + | MPU_RASR_ENABLE_Msk; // region enable + MPU->CTRL = MPU_CTRL_PRIVDEFENA_Msk // enable background region + | MPU_CTRL_ENABLE_Msk; // enable the MPU + __ISB(); + __DSB(); - /* region #3: (not configured) */ - { MPU_RBAR_VALID_Msk | (MPU_RBAR_REGION_Msk & 2U), 0U }, - - { /* region #3: Peripherals: base=0x4000'0000, size=512M=2^(28+1) */ - 0x40000000U /* base address */ - | MPU_RBAR_VALID_Msk /* valid region */ - | (MPU_RBAR_REGION_Msk & 3U), /* region #3 */ - (28U << MPU_RASR_SIZE_Pos) /* 2^(28+1) region */ - | (0x3U << MPU_RASR_AP_Pos) /* PA:rw/UA:rw */ - | (1U << MPU_RASR_XN_Pos) /* XN=1 */ - | (1U << MPU_RASR_S_Pos) /* S=1 */ - | (1U << MPU_RASR_B_Pos) /* B=1 */ - | MPU_RASR_ENABLE_Msk /* region enable */ - }, - - { /* region #4: Priv. Periph: base=0xE000'0000, size=512M=2^(28+1) */ - 0xE0000000U /* base address */ - | MPU_RBAR_VALID_Msk /* valid region */ - | (MPU_RBAR_REGION_Msk & 4U), /* region #4 */ - (28U << MPU_RASR_SIZE_Pos) /* 2^(28+1) region */ - | (0x3U << MPU_RASR_AP_Pos) /* PA:rw/UA:rw */ - | (1U << MPU_RASR_XN_Pos) /* XN=1 */ - | (1U << MPU_RASR_S_Pos) /* S=1 */ - | (1U << MPU_RASR_B_Pos) /* B=1 */ - | MPU_RASR_ENABLE_Msk /* region enable */ - }, - - { /* region #5: Ext RAM: base=0x6000'0000, size=1G=2^(29+1) */ - 0x60000000U /* base address */ - | MPU_RBAR_VALID_Msk /* valid region */ - | (MPU_RBAR_REGION_Msk & 5U), /* region #5 */ - (29U << MPU_RASR_SIZE_Pos) /* 2^(28+1) region */ - | (0x3U << MPU_RASR_AP_Pos) /* PA:rw/UA:rw */ - | (1U << MPU_RASR_XN_Pos) /* XN=1 */ - | (1U << MPU_RASR_S_Pos) /* S=1 */ - | (1U << MPU_RASR_B_Pos) /* B=1 */ - | MPU_RASR_ENABLE_Msk /* region enable */ - }, - - { /* region #6: Ext Dev: base=0xA000'0000, size=1G=2^(29+1) */ - 0xA0000000U /* base address */ - | MPU_RBAR_VALID_Msk /* valid region */ - | (MPU_RBAR_REGION_Msk & 6U), /* region #6 */ - (29U << MPU_RASR_SIZE_Pos) /* 2^(28+1) region */ - | (0x3U << MPU_RASR_AP_Pos) /* PA:rw/UA:rw */ - | (1U << MPU_RASR_XN_Pos) /* XN=1 */ - | (1U << MPU_RASR_S_Pos) /* S=1 */ - | (1U << MPU_RASR_B_Pos) /* B=1 */ - | MPU_RASR_ENABLE_Msk /* region enable */ - }, - - { /* region #7: NULL-pointer: base=0x000'0000, size=256B */ - 0x00000000U /* base address */ - | MPU_RBAR_VALID_Msk /* valid region */ - | (MPU_RBAR_REGION_Msk & 7U), /* region #7 */ - (7U << MPU_RASR_SIZE_Pos) /* 2^(7+1)=256B region */ - | (0x0U << MPU_RASR_AP_Pos) /* PA:na/UA:na */ - | (1U << MPU_RASR_XN_Pos) /* XN=1 */ - | MPU_RASR_ENABLE_Msk /* region enable */ - }, - }; - - /* enable the MemManage_Handler for MPU exception */ + // enable the MemManage_Handler for MPU exception SCB->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk; - __DSB(); - MPU->CTRL = 0U; /* disable the MPU */ - for (uint_fast8_t n = 0U; n < Q_DIM(mpu_setup); ++n) { - MPU->RBAR = mpu_setup[n].rbar; - MPU->RASR = mpu_setup[n].rasr; - } - MPU->CTRL = MPU_CTRL_ENABLE_Msk; /* enable the MPU */ - __ISB(); - __DSB(); -} - -/*..........................................................................*/ -void BSP_init(void) { - /* setup the MPU... */ - TM4C123GXL_MPU_setup(); - - /* NOTE: SystemInit() already called from the startup code - * but SystemCoreClock needs to be updated - */ + // NOTE: SystemInit() has been already called from the startup code + // but SystemCoreClock needs to be updated SystemCoreClockUpdate(); - /* NOTE: The VFP (hardware Floating Point) unit is configured by FreeRTOS */ + // NOTE: VFP (hardware Floating Point) unit is configured by FreeRTOS - /* enable clock for to the peripherals used by this application... */ - SYSCTL->RCGCGPIO |= (1U << 5); /* enable Run mode for GPIOF */ - SYSCTL->GPIOHBCTL |= (1U << 5); /* enable AHB for GPIOF */ + // enable clock for to the peripherals used by this application... + SYSCTL->RCGCGPIO |= (1U << 5U); // enable Run mode for GPIOF + SYSCTL->GPIOHBCTL |= (1U << 5U); // enable AHB for GPIOF __ISB(); __DSB(); - /* configure LEDs (digital output) */ + // configure LEDs (digital output) GPIOF_AHB->DIR |= (LED_RED | LED_BLUE | LED_GREEN); GPIOF_AHB->DEN |= (LED_RED | LED_BLUE | LED_GREEN); GPIOF_AHB->DATA_Bits[LED_RED | LED_BLUE | LED_GREEN] = 0U; - /* configure switches... */ + // configure switches... - /* unlock access to the SW2 pin because it is PROTECTED */ - GPIOF_AHB->LOCK = 0x4C4F434BU; /* unlock GPIOCR register for SW2 */ - /* commit the write (cast const away) */ + // unlock access to the SW2 pin because it is PROTECTED + GPIOF_AHB->LOCK = 0x4C4F434BU; // unlock GPIOCR register for SW2 + // commit the write (cast const away) *(uint32_t volatile *)&GPIOF_AHB->CR = 0x01U; - GPIOF_AHB->DIR &= ~(BTN_SW1 | BTN_SW2); /* input */ - GPIOF_AHB->DEN |= (BTN_SW1 | BTN_SW2); /* digital enable */ - GPIOF_AHB->PUR |= (BTN_SW1 | BTN_SW2); /* pull-up resistor enable */ + GPIOF_AHB->DIR &= ~(BTN_SW1 | BTN_SW2); // input + GPIOF_AHB->DEN |= (BTN_SW1 | BTN_SW2); // digital enable + GPIOF_AHB->PUR |= (BTN_SW1 | BTN_SW2); // pull-up resistor enable *(uint32_t volatile *)&GPIOF_AHB->CR = 0x00U; - GPIOF_AHB->LOCK = 0x0; /* lock GPIOCR register for SW2 */ + GPIOF_AHB->LOCK = 0x0; // lock GPIOCR register for SW2 BSP_randomSeed(1234U); - /* initialize the QS software tracing... */ - if (QS_INIT((void *)0) == 0U) { + // initialize the QS software tracing... + if (!QS_INIT((void *)0)) { Q_ERROR(); } + + // dictionaries... QS_OBJ_DICTIONARY(&l_TickHook); QS_OBJ_DICTIONARY(&l_GPIOPortA_IRQHandler); QS_USR_DICTIONARY(PHILO_STAT); QS_USR_DICTIONARY(PAUSED_STAT); - QS_USR_DICTIONARY(COMMAND_STAT); - /* setup the QS filters... */ - QS_GLB_FILTER(QS_ALL_RECORDS); /* all records */ - QS_GLB_FILTER(-QS_QF_TICK); /* exclude the clock tick */ + QS_ONLY(produce_sig_dict()); + + // setup the QS filters... + QS_GLB_FILTER(QS_ALL_RECORDS); // all records + QS_GLB_FILTER(-QS_QF_TICK); // exclude the clock tick } -/*..........................................................................*/ +//............................................................................ +void BSP_start(void) { + // initialize event pools + static QF_MPOOL_EL(TableEvt) smlPoolSto[2*N_PHILO]; // small pool + QF_poolInit(smlPoolSto, sizeof(smlPoolSto), sizeof(smlPoolSto[0])); + + // initialize publish-subscribe + static QSubscrList subscrSto[MAX_PUB_SIG]; + QActive_psInit(subscrSto, Q_DIM(subscrSto)); + + // start the active objects/threads... + static QEvt const *philoQueueSto[N_PHILO][10]; + static StackType_t philoStack[N_PHILO][configMINIMAL_STACK_SIZE]; + for (uint8_t n = 0U; n < N_PHILO; ++n) { + Philo_ctor(n); // instantiate all Philosopher active objects + QActive_setAttr(AO_Philo[n], TASK_NAME_ATTR, "Philo"); + QACTIVE_START(AO_Philo[n], // AO to start + n + 3U, // QP prio. of the AO + philoQueueSto[n], // event queue storage + Q_DIM(philoQueueSto[n]), // queue length [events] + philoStack[n], // stack storage + sizeof(philoStack[n]), // stack size [bytes] + (QEvt *)0); // initialization event (not used) + } + + static QEvt const *tableQueueSto[N_PHILO]; + static StackType_t tableStack[configMINIMAL_STACK_SIZE]; + Table_ctor(); // instantiate the Table active object + QActive_setAttr(AO_Table, TASK_NAME_ATTR, "Table"); + QACTIVE_START(AO_Table, // AO to start + N_PHILO + 7U, // QP prio. of the AO + tableQueueSto, // event queue storage + Q_DIM(tableQueueSto), // queue length [events] + tableStack, // stack storage + sizeof(tableStack), // stack size [bytes] + (QEvt *)0); // initialization event (not used) +} +//............................................................................ void BSP_displayPhilStat(uint8_t n, char const *stat) { + Q_UNUSED_PAR(n); + GPIOF_AHB->DATA_Bits[LED_GREEN] = ((stat[0] == 'e') ? LED_GREEN : 0U); - QS_BEGIN_ID(PHILO_STAT, AO_Philo[n]->prio) /* app-specific record */ - QS_U8(1, n); /* Philosopher number */ - QS_STR(stat); /* Philosopher status */ + // app-specific trace record... + QS_BEGIN_ID(PHILO_STAT, AO_Table->prio) + QS_U8(1, n); // Philosopher number + QS_STR(stat); // Philosopher status QS_END() } -/*..........................................................................*/ -void BSP_displayPaused(uint8_t paused) { +//............................................................................ +void BSP_displayPaused(uint8_t const paused) { GPIOF_AHB->DATA_Bits[LED_BLUE] = ((paused != 0U) ? LED_BLUE : 0U); - QS_BEGIN_ID(PAUSED_STAT, 0U) /* app-specific record */ - QS_U8(1, paused); /* Paused status */ + // application-specific trace record + QS_BEGIN_ID(PAUSED_STAT, AO_Table->prio) + QS_U8(1, paused); // Paused status QS_END() } -/*..........................................................................*/ -uint32_t BSP_random(void) { /* a very cheap pseudo-random-number generator */ - /* Some flating point code is to exercise the VFP... */ +//............................................................................ +void BSP_randomSeed(uint32_t const seed) { + l_rndSeed = seed; +} +//............................................................................ +uint32_t BSP_random(void) { // a very cheap pseudo-random-number generator + // Some floating point code is to exercise the VFP... float volatile x = 3.1415926F; x = x + 2.7182818F; - vTaskSuspendAll(); /* lock FreeRTOS scheduler */ - /* "Super-Duper" Linear Congruential Generator (LCG) - * LCG(2^32, 3*7*11*13*23, 0, seed) - */ - l_rnd = l_rnd * (3U*7U*11U*13U*23U); - xTaskResumeAll(); /* unlock the FreeRTOS scheduler */ + vTaskSuspendAll(); // lock FreeRTOS scheduler + // "Super-Duper" Linear Congruential Generator (LCG) + // LCG(2^32, 3*7*11*13*23, 0, seed) + // + uint32_t rnd = l_rndSeed * (3U*7U*11U*13U*23U); + l_rndSeed = rnd; // set for the next time + xTaskResumeAll(); // unlock the FreeRTOS scheduler - return l_rnd >> 8; + return (rnd >> 8); } -/*..........................................................................*/ -void BSP_randomSeed(uint32_t seed) { - l_rnd = seed; +//............................................................................ +void BSP_ledOn(void) { + GPIOF_AHB->DATA_Bits[LED_RED] = 0xFFU; } -/*..........................................................................*/ +//............................................................................ +void BSP_ledOff(void) { + GPIOF_AHB->DATA_Bits[LED_RED] = 0x00U; +} +//............................................................................ void BSP_terminate(int16_t result) { - (void)result; + Q_UNUSED_PAR(result); } -/* QF callbacks ============================================================*/ -void QF_onStartup(void) { - /* set up the SysTick timer to fire at BSP_TICKS_PER_SEC rate */ - SysTick_Config(SystemCoreClock / BSP_TICKS_PER_SEC); +//============================================================================ - /* assing all priority bits for preemption-prio. and none to sub-prio. */ +// QF callbacks -------------------------------------------------------------- + +void QF_onStartup(void) { + // set up the SysTick timer to fire at BSP_TICKS_PER_SEC rate + //SysTick_Config(SystemCoreClock / BSP_TICKS_PER_SEC); // done in FreeRTOS + + // assign all priority bits for preemption-prio. and none to sub-prio. NVIC_SetPriorityGrouping(0U); - /* set priorities of ALL ISRs used in the system, see NOTE1 - * - * !!!!!!!!!!!!!!!!!!!!!!!!!!!! CAUTION !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - * Assign a priority to EVERY ISR explicitly by calling NVIC_SetPriority(). - * DO NOT LEAVE THE ISR PRIORITIES AT THE DEFAULT VALUE! - */ - NVIC_SetPriority(UART0_IRQn, 0U); /* kernel unaware interrupt */ - NVIC_SetPriority(GPIOA_IRQn, RTOS_AWARE_ISR_CMSIS_PRI); - NVIC_SetPriority(SysTick_IRQn, RTOS_AWARE_ISR_CMSIS_PRI + 1U); - /* ... */ + // set priorities of ALL ISRs used in the system, see NOTE1 + NVIC_SetPriority(UART0_IRQn, 0U); // kernel unaware interrupt + NVIC_SetPriority(GPIOA_IRQn, RTOS_AWARE_ISR_CMSIS_PRI + 0U); + NVIC_SetPriority(SysTick_IRQn, RTOS_AWARE_ISR_CMSIS_PRI + 1U); + // ... - /* enable IRQs... */ + // enable IRQs... NVIC_EnableIRQ(GPIOA_IRQn); #ifdef Q_SPY - NVIC_EnableIRQ(UART0_IRQn); /* UART0 interrupt used for QS-RX */ + NVIC_EnableIRQ(UART0_IRQn); // UART0 interrupt used for QS-RX #endif } -/*..........................................................................*/ +//............................................................................ void QF_onCleanup(void) { } -/*..........................................................................*/ -Q_NORETURN Q_onAssert(char const * const module, int_t const loc) { - /* - * NOTE: add here your application-specific error handling - */ - (void)module; - (void)loc; - QS_ASSERTION(module, loc, 10000U); /* report assertion to QS */ - -#ifndef NDEBUG - /* light up all LEDs */ - GPIOF_AHB->DATA_Bits[LED_GREEN | LED_RED | LED_BLUE] = 0xFFU; - /* for debugging, hang on in an endless loop... */ - for (;;) { - } -#endif - - NVIC_SystemReset(); -} - -/* QS callbacks ============================================================*/ +// QS callbacks -------------------------------------------------------------- #ifdef Q_SPY -/*..........................................................................*/ +//............................................................................ uint8_t QS_onStartup(void const *arg) { Q_UNUSED_PAR(arg); - static uint8_t qsTxBuf[2*1024]; /* buffer for QS-TX channel */ - static uint8_t qsRxBuf[100]; /* buffer for QS-RX channel */ + static uint8_t qsTxBuf[2*1024]; // buffer for QS-TX channel + QS_initBuf(qsTxBuf, sizeof(qsTxBuf)); - QS_initBuf (qsTxBuf, sizeof(qsTxBuf)); + static uint8_t qsRxBuf[100]; // buffer for QS-RX channel QS_rxInitBuf(qsRxBuf, sizeof(qsRxBuf)); - /* enable clock for UART0 and GPIOA (used by UART0 pins) */ - SYSCTL->RCGCUART |= (1U << 0); /* enable Run mode for UART0 */ - SYSCTL->RCGCGPIO |= (1U << 0); /* enable Run mode for GPIOA */ + // enable clock for UART0 and GPIOA (used by UART0 pins) + SYSCTL->RCGCUART |= (1U << 0U); // enable Run mode for UART0 + SYSCTL->RCGCGPIO |= (1U << 0U); // enable Run mode for GPIOA - /* configure UART0 pins for UART operation */ - uint32_t tmp = (1U << 0) | (1U << 1); + // configure UART0 pins for UART operation + uint32_t tmp = (1U << 0U) | (1U << 1U); GPIOA->DIR &= ~tmp; GPIOA->SLR &= ~tmp; GPIOA->ODR &= ~tmp; GPIOA->PUR &= ~tmp; GPIOA->PDR &= ~tmp; - GPIOA->AMSEL &= ~tmp; /* disable analog function on the pins */ - GPIOA->AFSEL |= tmp; /* enable ALT function on the pins */ - GPIOA->DEN |= tmp; /* enable digital I/O on the pins */ + GPIOA->AMSEL &= ~tmp; // disable analog function on the pins + GPIOA->AFSEL |= tmp; // enable ALT function on the pins + GPIOA->DEN |= tmp; // enable digital I/O on the pins GPIOA->PCTL &= ~0x00U; GPIOA->PCTL |= 0x11U; - /* configure the UART for the desired baud rate, 8-N-1 operation */ + // configure the UART for the desired baud rate, 8-N-1 operation tmp = (((SystemCoreClock * 8U) / UART_BAUD_RATE) + 1U) / 2U; UART0->IBRD = tmp / 64U; UART0->FBRD = tmp % 64U; - UART0->LCRH = (0x3U << 5); /* configure 8-N-1 operation */ - UART0->LCRH |= (0x1U << 4); /* enable FIFOs */ - UART0->CTL = (1U << 0) /* UART enable */ - | (1U << 8) /* UART TX enable */ - | (1U << 9); /* UART RX enable */ + UART0->LCRH = (0x3U << 5U); // configure 8-N-1 operation + UART0->LCRH |= (0x1U << 4U); // enable FIFOs + UART0->CTL = (1U << 0U) // UART enable + | (1U << 8U) // UART TX enable + | (1U << 9U); // UART RX enable - /* configure UART interrupts (for the RX channel) */ - UART0->IM |= (1U << 4) | (1U << 6); /* enable RX and RX-TO interrupt */ - UART0->IFLS |= (0x2U << 2); /* interrupt on RX FIFO half-full */ - /* NOTE: do not enable the UART0 interrupt yet. Wait till QF_onStartup() */ + // configure UART interrupts (for the RX channel) + UART0->IM |= (1U << 4U) | (1U << 6U); // enable RX and RX-TO interrupt + UART0->IFLS |= (0x2U << 2U); // interrupt on RX FIFO half-full + // NOTE: do not enable the UART0 interrupt yet. Wait till QF_onStartup() - /* configure TIMER5 to produce QS time stamp */ - SYSCTL->RCGCTIMER |= (1U << 5); /* enable run mode for Timer5 */ - TIMER5->CTL = 0U; /* disable Timer1 output */ - TIMER5->CFG = 0x0U; /* 32-bit configuration */ - TIMER5->TAMR = (1U << 4) | 0x02; /* up-counting periodic mode */ - TIMER5->TAILR= 0xFFFFFFFFU; /* timer interval */ - TIMER5->ICR = 0x1U; /* TimerA timeout flag bit clears*/ - TIMER5->CTL |= (1U << 0); /* enable TimerA module */ + // configure TIMER5 to produce QS time stamp + SYSCTL->RCGCTIMER |= (1U << 5U); // enable run mode for Timer5 + TIMER5->CTL = 0U; // disable Timer1 output + TIMER5->CFG = 0x0U; // 32-bit configuration + TIMER5->TAMR = (1U << 4U) | 0x02U; // up-counting periodic mode + TIMER5->TAILR= 0xFFFFFFFFU; // timer interval + TIMER5->ICR = 0x1U; // TimerA timeout flag bit clears + TIMER5->CTL |= (1U << 0U); // enable TimerA module - return 1U; /* return success */ + return 1U; // return success } -/*..........................................................................*/ +//............................................................................ void QS_onCleanup(void) { } -/*..........................................................................*/ -QSTimeCtr QS_onGetTime(void) { /* NOTE: invoked with interrupts DISABLED */ +//............................................................................ +QSTimeCtr QS_onGetTime(void) { // NOTE: invoked with interrupts DISABLED return TIMER5->TAV; } -/*..........................................................................*/ +//............................................................................ void QS_onFlush(void) { - while (true) { - /* try to get next byte to transmit */ + for (;;) { QF_INT_DISABLE(); uint16_t b = QS_getByte(); QF_INT_ENABLE(); - if (b != QS_EOD) { /* NOT end-of-data */ - /* busy-wait as long as TX FIFO has data to transmit */ - while ((UART0->FR & UART_FR_TXFE) == 0) { + if (b != QS_EOD) { // NOT end-of-data + // busy-wait as long as TX FIFO has data to transmit + while ((UART0->FR & UART_FR_TXFE) == 0U) { + QF_INT_ENABLE(); + QF_CRIT_EXIT_NOP(); + + QF_INT_DISABLE(); } - /* place the byte in the UART DR register */ + // place the byte in the UART DR register UART0->DR = b; + QF_INT_ENABLE(); } else { - break; /* break out of the loop */ + QF_INT_ENABLE(); + break; // break out of the loop } } } -/*..........................................................................*/ -/*! callback function to reset the target (to be implemented in the BSP) */ +//............................................................................ +//! callback function to reset the target (to be implemented in the BSP) void QS_onReset(void) { NVIC_SystemReset(); } -/*..........................................................................*/ -/*! callback function to execute a user command (to be implemented in BSP) */ +//............................................................................ +//! callback function to execute a user command (to be implemented in BSP) void QS_onCommand(uint8_t cmdId, uint32_t param1, uint32_t param2, uint32_t param3) { - QS_BEGIN_ID(COMMAND_STAT, 0U) /* app-specific record */ - QS_U8(2, cmdId); - QS_U32(8, param1); - QS_U32(8, param2); - QS_U32(8, param3); - QS_END() + Q_UNUSED_PAR(cmdId); + Q_UNUSED_PAR(param1); + Q_UNUSED_PAR(param2); + Q_UNUSED_PAR(param3); } -#endif /* Q_SPY */ -/*--------------------------------------------------------------------------*/ +#endif // Q_SPY +//---------------------------------------------------------------------------- -/***************************************************************************** -* NOTE1: -* The configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY constant from the -* FreeRTOS configuration file specifies the highest ISR priority that -* is disabled by the QF framework. The value is suitable for the -* NVIC_SetPriority() CMSIS function. -* -* Only ISRs prioritized at or below the -* configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY level (i.e., -* with the numerical values of priorities equal or higher than -* configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY) are allowed to call any -* QP/FreeRTOS services. These ISRs are "kernel-aware". -* -* Conversely, any ISRs prioritized above the -* configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY priority level (i.e., with -* the numerical values of priorities less than -* configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY) are never disabled and are -* not aware of the kernel. Such "kernel-unaware" ISRs cannot call any -* QP/FreeRTOS services. The only mechanism by which a "kernel-unaware" ISR -* can communicate with the QF framework is by triggering a "kernel-aware" -* ISR, which can post/publish events. -* -* For more information, see article "Running the RTOS on a ARM Cortex-M Core" -* http://www.freertos.org/RTOS-Cortex-M3-M4.html -* -* NOTE2: -* The User LED is used to visualize the idle loop activity. The brightness -* of the LED is proportional to the frequency of invcations of the idle loop. -* Please note that the LED is toggled with interrupts locked, so no interrupt -* execution time contributes to the brightness of the User LED. -*/ +//============================================================================ +// NOTE1: +// The configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY constant from the +// FreeRTOS configuration file specifies the highest ISR priority that +// is disabled by the QF framework. The value is suitable for the +// NVIC_SetPriority() CMSIS function. +// +// Only ISRs prioritized at or below the +// configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY level (i.e., +// with the numerical values of priorities equal or higher than +// configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY) are allowed to call any +// QP/FreeRTOS services. These ISRs are "kernel-aware". +// +// Conversely, any ISRs prioritized above the +// configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY priority level (i.e., with +// the numerical values of priorities less than +// configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY) are never disabled and are +// not aware of the kernel. Such "kernel-unaware" ISRs cannot call any +// QP/FreeRTOS services. The only mechanism by which a "kernel-unaware" ISR +// can communicate with the QF framework is by triggering a "kernel-aware" +// ISR, which can post/publish events. +// +// For more information, see article "Running the RTOS on a ARM Cortex-M Core" +// http://www.freertos.org/RTOS-Cortex-M3-M4.html +// +// NOTE2: +// The User LED is used to visualize the idle loop activity. The brightness +// of the LED is proportional to the frequency of invcations of the idle loop. +// Please note that the LED is toggled with interrupts locked, so no interrupt +// execution time contributes to the brightness of the User LED. diff --git a/examples/freertos/arm-cm/dpp_ek-tm4c123gxl/bsp.h b/examples/freertos/arm-cm/dpp_ek-tm4c123gxl/bsp.h index d1518fa9..4d9f9d39 100644 --- a/examples/freertos/arm-cm/dpp_ek-tm4c123gxl/bsp.h +++ b/examples/freertos/arm-cm/dpp_ek-tm4c123gxl/bsp.h @@ -1,47 +1,51 @@ -/***************************************************************************** -* Product: DPP example, FreeRTOS kernel -* Last Updated for Version: 5.4.0 -* Date of the Last Update: 2015-03-07 -* -* Q u a n t u m L e a P s -* --------------------------- -* innovating embedded systems -* -* Copyright (C) 2005 Quantum Leaps, LLC. state-machine.com. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* Web : http://www.state-machine.com -* -*****************************************************************************/ -#ifndef BSP_H -#define BSP_H +//============================================================================ +// Product: DPP example, FreeRTOS kernel +// Last Updated for Version: 7.3.0 +// Date of the Last Update: 2023-08-22 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// This program is open source software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Alternatively, this program may be distributed and modified under the +// terms of Quantum Leaps commercial licenses, which expressly supersede +// the GNU General Public License and are specifically designed for +// licensees interested in retaining the proprietary status of their code. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Contact information: +// +// +//============================================================================ +#ifndef BSP_H_ +#define BSP_H_ #define BSP_TICKS_PER_SEC configTICK_RATE_HZ void BSP_init(void); +void BSP_start(void); void BSP_displayPaused(uint8_t paused); void BSP_displayPhilStat(uint8_t n, char const *stat); void BSP_terminate(int16_t result); -void BSP_randomSeed(uint32_t seed); /* random seed */ -uint32_t BSP_random(void); /* pseudo-random generator */ +void BSP_randomSeed(uint32_t seed); // random seed +uint32_t BSP_random(void); // pseudo-random generator -#endif /* BSP_H */ +void BSP_ledOn(void); +void BSP_ledOff(void); + +#endif // BSP_H_ diff --git a/examples/freertos/arm-cm/dpp_ek-tm4c123gxl/dpp.h b/examples/freertos/arm-cm/dpp_ek-tm4c123gxl/dpp.h index da094c2c..e6d1557a 100644 --- a/examples/freertos/arm-cm/dpp_ek-tm4c123gxl/dpp.h +++ b/examples/freertos/arm-cm/dpp_ek-tm4c123gxl/dpp.h @@ -1,92 +1,117 @@ -/*$file${.::dpp.h} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* -* Model: dpp.qm -* File: ${.::dpp.h} -* -* This code has been generated by QM 5.2.4 . -* DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. -* -* SPDX-License-Identifier: GPL-3.0-or-later -* -* This generated code is open source software: you can redistribute it under -* the terms of the GNU General Public License as published by the Free -* Software Foundation. -* -* This code is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -* more details. -* -* NOTE: -* Alternatively, this generated code may be distributed under the terms -* of Quantum Leaps commercial licenses, which expressly supersede the GNU -* General Public License and are specifically designed for licensees -* interested in retaining the proprietary status of their code. -* -* Contact information: -* -* -*/ -/*$endhead${.::dpp.h} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -#ifndef DPP_H -#define DPP_H +//$file${.::dpp.h} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// +// Model: dpp.qm +// File: ${.::dpp.h} +// +// This code has been generated by QM 5.3.0 . +// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. +// +// SPDX-License-Identifier: GPL-3.0-or-later +// +// This generated code is open source software: you can redistribute it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation. +// +// This code is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// NOTE: +// Alternatively, this generated code may be distributed under the terms +// of Quantum Leaps commercial licenses, which expressly supersede the GNU +// General Public License and are specifically designed for licensees +// interested in retaining the proprietary status of their code. +// +// Contact information: +// +// +// +//$endhead${.::dpp.h} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +#ifndef DPP_H_ +#define DPP_H_ -enum DPPSignals { - EAT_SIG = Q_USER_SIG, /* published by Table to let a philosopher eat */ - DONE_SIG, /* published by Philosopher when done eating */ - PAUSE_SIG, /* published by BSP to pause serving forks */ - SERVE_SIG, /* published by BSP to serve re-start serving forks */ - TEST_SIG, /* published by BSP to test the application */ - MAX_PUB_SIG, /* the last published signal */ +//$declare${Shared} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv - HUNGRY_SIG, /* posted direclty to Table from hungry Philo */ - TIMEOUT_SIG, /* used by Philosophers for time events */ - MAX_SIG /* the last signal */ +//${Shared::AppSignals} ...................................................... +enum AppSignals { + EAT_SIG = Q_USER_SIG, // published by Table to let a Philo eat + DONE_SIG, // published by Philo when done eating + PAUSE_SIG, // published by BSP to pause the application + SERVE_SIG, // published by BSP to serve re-start serving forks + TEST_SIG, // published by BSP to test the application + MAX_PUB_SIG, // the last published signal + + TIMEOUT_SIG, // posted by time event to Philo + HUNGRY_SIG, // posted by hungry Philo to Table + MAX_SIG // the last signal }; -/*$declare${Events::TableEvt} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//${Shared::produce_sig_dict} ................................................ +#ifdef Q_SPY +static inline void produce_sig_dict(void) { + QS_SIG_DICTIONARY(EAT_SIG, (void *)0); + QS_SIG_DICTIONARY(DONE_SIG, (void *)0); + QS_SIG_DICTIONARY(PAUSE_SIG, (void *)0); + QS_SIG_DICTIONARY(SERVE_SIG, (void *)0); + QS_SIG_DICTIONARY(TEST_SIG, (void *)0); -/*${Events::TableEvt} ......................................................*/ + QS_SIG_DICTIONARY(TIMEOUT_SIG, (void *)0); + QS_SIG_DICTIONARY(HUNGRY_SIG, (void *)0); +} +#endif // def Q_SPY + +//${Shared::N_PHILO} ......................................................... +#define N_PHILO ((uint8_t)5U) + +//${Shared::TableEvt} ........................................................ typedef struct { -/* protected: */ +// protected: QEvt super; -/* public: */ - uint8_t philoNum; +// public: + uint8_t philoId; } TableEvt; -/*$enddecl${Events::TableEvt} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/* number of philosophers */ -#define N_PHILO ((uint8_t)5) +// public: -/*$declare${AOs::Philo_ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +#ifdef QEVT_DYN_CTOR +static inline TableEvt * TableEvt_ctor(TableEvt * const me, + uint8_t id) +{ + if (me != (TableEvt *)0) { + // don't call QEvt_ctor() because the initialization of all + // QEvt attributes is already done in QF_QF_newX_() + me->philoId = id; + } + return me; +} +#endif // def QEVT_DYN_CTOR -/*${AOs::Philo_ctor} .......................................................*/ -void Philo_ctor(void); -/*$enddecl${AOs::Philo_ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*$declare${AOs::AO_Philo[N_PHILO]} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${AOs::AO_Philo[N_PHILO]} ................................................*/ +//${Shared::AO_Philo[N_PHILO]} ............................................... extern QActive * const AO_Philo[N_PHILO]; -/*$enddecl${AOs::AO_Philo[N_PHILO]} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*$declare${AOs::Table_ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//${Shared::Philo_ctor} ...................................................... +void Philo_ctor(uint_fast8_t const id); -/*${AOs::Table_ctor} .......................................................*/ -void Table_ctor(void); -/*$enddecl${AOs::Table_ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*$declare${AOs::AO_Table} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${AOs::AO_Table} .........................................................*/ +//${Shared::AO_Table} ........................................................ extern QActive * const AO_Table; -/*$enddecl${AOs::AO_Table} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -#ifdef QP_INC_QXK_H_ - void Test1_ctor(void); - extern QXThread * const XT_Test1; - void Test2_ctor(void); - extern QXThread * const XT_Test2; -#endif /* QP_INC_QXK_H_ */ +//${Shared::Table_ctor} ...................................................... +void Table_ctor(void); +//$enddecl${Shared} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -#endif /* DPP_H */ +#ifdef QXK_H_ +extern QXThread * const TH_XThread1; +void XThread1_ctor(void); + +extern QXThread * const TH_XThread2; +void XThread2_ctor(void); + +extern QXSemaphore TH_sema; +extern QXMutex TH_mutex; + +#endif // QXK_H_ + +#endif // DPP_H_ diff --git a/examples/freertos/arm-cm/dpp_ek-tm4c123gxl/dpp.qm b/examples/freertos/arm-cm/dpp_ek-tm4c123gxl/dpp.qm index b78ede00..ac9f2bc9 100644 --- a/examples/freertos/arm-cm/dpp_ek-tm4c123gxl/dpp.qm +++ b/examples/freertos/arm-cm/dpp_ek-tm4c123gxl/dpp.qm @@ -1,141 +1,210 @@ - + Dining Philosopher Problem example - - - + + + + + { + EAT_SIG = Q_USER_SIG, // published by Table to let a Philo eat + DONE_SIG, // published by Philo when done eating + PAUSE_SIG, // published by BSP to pause the application + SERVE_SIG, // published by BSP to serve re-start serving forks + TEST_SIG, // published by BSP to test the application + MAX_PUB_SIG, // the last published signal + + TIMEOUT_SIG, // posted by time event to Philo + HUNGRY_SIG, // posted by hungry Philo to Table + MAX_SIG // the last signal +}; + + + + QS_SIG_DICTIONARY(EAT_SIG, (void *)0); +QS_SIG_DICTIONARY(DONE_SIG, (void *)0); +QS_SIG_DICTIONARY(PAUSE_SIG, (void *)0); +QS_SIG_DICTIONARY(SERVE_SIG, (void *)0); +QS_SIG_DICTIONARY(TEST_SIG, (void *)0); + +QS_SIG_DICTIONARY(TIMEOUT_SIG, (void *)0); +QS_SIG_DICTIONARY(HUNGRY_SIG, (void *)0); + + + + ((uint8_t)5U) + + - - + + + + + + + if (me != (TableEvt *)0) { + // don't call QEvt_ctor() because the initialization of all + // QEvt attributes is already done in QF_QF_newX_() + me->philoId = id; +} +return me; + + + + = { + &Philo_inst[0].super, + &Philo_inst[1].super, + &Philo_inst[2].super, + &Philo_inst[3].super, + &Philo_inst[4].super +}; + + + + + + Philo * const me = &Philo_inst[id]; +QActive_ctor(&me->super, Q_STATE_CAST(&Philo_initial)); +QTimeEvt_ctorX(&me->timeEvt, &me->super, TIMEOUT_SIG, 0U), +me->id = (uint8_t)id; + + + + = &Table_inst.super; + + + + Table * const me = &Table_inst; +QActive_ctor(&me->super, Q_STATE_CAST(&Table_initial)); +for (uint8_t n = 0U; n < N_PHILO; ++n) { + me->fork[n] = FREE; + me->isHungry[n] = false; +} + + The Philo AO and the N_PHILO instances + + + + - + - static uint8_t registered = (uint8_t)0; /* starts off with 0, per C-standard */ -(void)par; /* unused parameter */ -if (registered == (uint8_t)0) { - registered = (uint8_t)1; + Q_UNUSED_PAR(par); - QS_OBJ_DICTIONARY(&l_philo[0]); - QS_OBJ_DICTIONARY(&l_philo[0].timeEvt); - QS_OBJ_DICTIONARY(&l_philo[1]); - QS_OBJ_DICTIONARY(&l_philo[1].timeEvt); - QS_OBJ_DICTIONARY(&l_philo[2]); - QS_OBJ_DICTIONARY(&l_philo[2].timeEvt); - QS_OBJ_DICTIONARY(&l_philo[3]); - QS_OBJ_DICTIONARY(&l_philo[3].timeEvt); - QS_OBJ_DICTIONARY(&l_philo[4]); - QS_OBJ_DICTIONARY(&l_philo[4].timeEvt); - - QS_FUN_DICTIONARY(&Philo_initial); - QS_FUN_DICTIONARY(&Philo_thinking); - QS_FUN_DICTIONARY(&Philo_hungry); - QS_FUN_DICTIONARY(&Philo_eating); -} -QS_SIG_DICTIONARY(HUNGRY_SIG, me); /* signal for each Philos */ -QS_SIG_DICTIONARY(TIMEOUT_SIG, me); /* signal for each Philos */ +QS_OBJ_ARR_DICTIONARY(&Philo_inst[me->id], me->id); +QS_OBJ_ARR_DICTIONARY(&Philo_inst[me->id].timeEvt, me->id); QActive_subscribe(&me->super, EAT_SIG); QActive_subscribe(&me->super, TEST_SIG); - + - QTimeEvt_armX(&me->timeEvt, THINK_TIME, 0U); - QTimeEvt_disarm(&me->timeEvt); + QTimeEvt_armX(&me->timeEvt, think_time(), 0U); + (void)QTimeEvt_disarm(&me->timeEvt); - - + + - /* EAT or DONE must be for other Philos than this one */ -Q_ASSERT(Q_EVT_CAST(TableEvt)->philoNum != PHILO_ID(me)); - + // EAT or DONE must be for other Philos than this one +Q_ASSERT(Q_EVT_CAST(TableEvt)->philoId != me->id); + - + - + - + - TableEvt *pe = Q_NEW(TableEvt, HUNGRY_SIG); -pe->philoNum = PHILO_ID(me); -QACTIVE_POST(AO_Table, &pe->super, me); + #ifdef QEVT_DYN_CTOR +TableEvt const *pe = Q_NEW(TableEvt, HUNGRY_SIG, me->id); +#else +TableEvt *pe = Q_NEW(TableEvt, HUNGRY_SIG); +pe->philoId = me->id; +#endif +QACTIVE_POST(AO_Table, &pe->super, &me->super); - + - Q_EVT_CAST(TableEvt)->philoNum == PHILO_ID(me) - - + Q_EVT_CAST(TableEvt)->philoId == me->id + + - + - /* DONE must be for other Philos than this one */ -Q_ASSERT(Q_EVT_CAST(TableEvt)->philoNum != PHILO_ID(me)); - + // DONE must be for other Philos than this one +Q_ASSERT(Q_EVT_CAST(TableEvt)->philoId != me->id); + - + - QTimeEvt_armX(&me->timeEvt, EAT_TIME, 0U); - TableEvt *pe = Q_NEW(TableEvt, DONE_SIG); -pe->philoNum = PHILO_ID(me); + QTimeEvt_armX(&me->timeEvt, eat_time(), 0U); + (void)QTimeEvt_disarm(&me->timeEvt); + +#ifdef QEVT_DYN_CTOR +TableEvt const *pe = Q_NEW(TableEvt, DONE_SIG, me->id); +#else +TableEvt *pe = Q_NEW(TableEvt, DONE_SIG); +pe->philoId = me->id; +#endif QACTIVE_PUBLISH(&pe->super, &me->super); - - + + - /* EAT or DONE must be for other Philos than this one */ -Q_ASSERT(Q_EVT_CAST(TableEvt)->philoNum != PHILO_ID(me)); - + // EAT or DONE must be for other Philos than this one +Q_ASSERT(Q_EVT_CAST(TableEvt)->philoId != me->id); + - + - + @@ -143,22 +212,19 @@ Q_ASSERT(Q_EVT_CAST(TableEvt)->philoNum != PHILO_ID(me)); - + + + - + - (void)par; /* unused parameter */ + Q_UNUSED_PAR(par); -QS_OBJ_DICTIONARY(&l_table); - -QS_SIG_DICTIONARY(DONE_SIG, (void *)0); /* global signals */ -QS_SIG_DICTIONARY(EAT_SIG, (void *)0); -QS_SIG_DICTIONARY(PAUSE_SIG, (void *)0); -QS_SIG_DICTIONARY(SERVE_SIG, (void *)0); -QS_SIG_DICTIONARY(TEST_SIG, (void *)0); - -QS_SIG_DICTIONARY(HUNGRY_SIG, me); /* signal just for Table */ +#ifdef Q_SPY +Table *Table_inst = me; +QS_OBJ_DICTIONARY(Table_inst); +#endif QActive_subscribe(&me->super, DONE_SIG); QActive_subscribe(&me->super, PAUSE_SIG); @@ -167,10 +233,10 @@ QActive_subscribe(&me->super, TEST_SIG); for (uint8_t n = 0U; n < N_PHILO; ++n) { me->fork[n] = FREE; - me->isHungry[n] = 0U; - BSP_displayPhilStat(n, "thinking"); + me->isHungry[n] = false; + BSP_displayPhilStat(n, THINKING); } - + @@ -178,128 +244,139 @@ for (uint8_t n = 0U; n < N_PHILO; ++n) { - + Q_ERROR(); - + - uint8_t n; -for (n = 0U; n < N_PHILO; ++n) { /* give permissions to eat... */ - if ((me->isHungry[n] != 0U) - && (me->fork[LEFT(n)] == FREE) + // give permissions to eat... +for (uint8_t n = 0U; n < N_PHILO; ++n) { + if (me->isHungry[n] + && (me->fork[left(n)] == FREE) && (me->fork[n] == FREE)) { - TableEvt *te; - - me->fork[LEFT(n)] = USED; + me->fork[left(n)] = USED; me->fork[n] = USED; - te = Q_NEW(TableEvt, EAT_SIG); - te->philoNum = n; - QACTIVE_PUBLISH(&te->super, &me->super); - me->isHungry[n] = 0U; - BSP_displayPhilStat(n, "eating "); +#ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, EAT_SIG, n); +#else + TableEvt *pe = Q_NEW(TableEvt, EAT_SIG); + pe->philoId = n; +#endif + QACTIVE_PUBLISH(&pe->super, &me->super); + me->isHungry[n] = false; + BSP_displayPhilStat(n, EATING); } } - uint8_t n, m; + uint8_t n = Q_EVT_CAST(TableEvt)->philoId; -n = Q_EVT_CAST(TableEvt)->philoNum; -/* phil ID must be in range and he must be not hungry */ -Q_ASSERT((n < N_PHILO) && (me->isHungry[n] == 0U)); +// phil ID must be in range and he must be not hungry +Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); -BSP_displayPhilStat(n, "hungry "); -m = LEFT(n); +BSP_displayPhilStat(n, HUNGRY); +uint8_t m = left(n); (me->fork[m] == FREE) && (me->fork[n] == FREE) - TableEvt *pe; -me->fork[m] = USED; + me->fork[m] = USED; me->fork[n] = USED; -pe = Q_NEW(TableEvt, EAT_SIG); -pe->philoNum = n; +#ifdef QEVT_DYN_CTOR +TableEvt const *pe = Q_NEW(TableEvt, EAT_SIG, n); +#else +TableEvt *pe = Q_NEW(TableEvt, EAT_SIG); +pe->philoId = n; +#endif QACTIVE_PUBLISH(&pe->super, &me->super); -BSP_displayPhilStat(n, "eating "); - +BSP_displayPhilStat(n, EATING); + else - me->isHungry[n] = 1U; - - + me->isHungry[n] = true; + + - + - uint8_t n, m; -TableEvt *pe; + uint8_t n = Q_EVT_CAST(TableEvt)->philoId; -n = Q_EVT_CAST(TableEvt)->philoNum; -/* phil ID must be in range and he must be not hungry */ -Q_ASSERT((n < N_PHILO) && (me->isHungry[n] == 0U)); +// phil ID must be in range and he must be not hungry +Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); -BSP_displayPhilStat(n, "thinking"); -m = LEFT(n); -/* both forks of Phil[n] must be used */ +BSP_displayPhilStat(n, THINKING); +uint8_t m = left(n); + +// both forks of Phil[n] must be used Q_ASSERT((me->fork[n] == USED) && (me->fork[m] == USED)); me->fork[m] = FREE; me->fork[n] = FREE; -m = RIGHT(n); /* check the right neighbor */ +m = right(n); // check the right neighbor -if ((me->isHungry[m] != 0U) && (me->fork[m] == FREE)) { +if (me->isHungry[m] && (me->fork[m] == FREE)) { me->fork[n] = USED; me->fork[m] = USED; - me->isHungry[m] = 0U; - pe = Q_NEW(TableEvt, EAT_SIG); - pe->philoNum = m; + me->isHungry[m] = false; +#ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, EAT_SIG, m); +#else + TableEvt *pe = Q_NEW(TableEvt, EAT_SIG); + pe->philoId = m; +#endif QACTIVE_PUBLISH(&pe->super, &me->super); - BSP_displayPhilStat(m, "eating "); + BSP_displayPhilStat(m, EATING); } -m = LEFT(n); /* check the left neighbor */ -n = LEFT(m); /* left fork of the left neighbor */ -if ((me->isHungry[m] != 0U) && (me->fork[n] == FREE)) { +m = left(n); // check the left neighbor +n = left(m); // left fork of the left neighbor +if (me->isHungry[m] && (me->fork[n] == FREE)) { me->fork[m] = USED; me->fork[n] = USED; - me->isHungry[m] = 0U; - pe = Q_NEW(TableEvt, EAT_SIG); - pe->philoNum = m; + me->isHungry[m] = false; +#ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, EAT_SIG, m); +#else + TableEvt *pe = Q_NEW(TableEvt, EAT_SIG); + pe->philoId = m; +#endif QACTIVE_PUBLISH(&pe->super, &me->super); - BSP_displayPhilStat(m, "eating "); + BSP_displayPhilStat(m, EATING); } - + Q_ERROR(); - + - + - + @@ -309,178 +386,140 @@ if ((me->isHungry[m] != 0U) && (me->fork[n] == FREE)) { BSP_displayPaused(0U); - + - uint8_t n = Q_EVT_CAST(TableEvt)->philoNum; -/* philo ID must be in range and he must be not hungry */ -Q_ASSERT((n < N_PHILO) && (me->isHungry[n] == 0U)); -me->isHungry[n] = 1U; -BSP_displayPhilStat(n, "hungry "); - + uint8_t n = Q_EVT_CAST(TableEvt)->philoId; + +// philo ID must be in range and he must be not hungry +Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); + +me->isHungry[n] = true; +BSP_displayPhilStat(n, HUNGRY); + - uint8_t n, m; + uint8_t n = Q_EVT_CAST(TableEvt)->philoId; -n = Q_EVT_CAST(TableEvt)->philoNum; -/* phil ID must be in range and he must be not hungry */ -Q_ASSERT((n < N_PHILO) && (me->isHungry[n] == 0U)); +// phil ID must be in range and he must be not hungry +Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); -BSP_displayPhilStat(n, "thinking"); -m = LEFT(n); -/* both forks of Phil[n] must be used */ +BSP_displayPhilStat(n, THINKING); +uint8_t m = left(n); + +// both forks of Phil[n] must be used Q_ASSERT((me->fork[n] == USED) && (me->fork[m] == USED)); me->fork[m] = FREE; me->fork[n] = FREE; - + - + - + - + - - - - - - - uint8_t n; -Philo *me; -for (n = 0U; n < N_PHILO; ++n) { - me = &l_philo[n]; - QActive_ctor(&me->super, Q_STATE_CAST(&Philo_initial)); - QTimeEvt_ctorX(&me->timeEvt, &me->super, TIMEOUT_SIG, 0U); -} - - - - uint8_t n; -Table *me = &l_table; - -QActive_ctor(&me->super, Q_STATE_CAST(&Table_initial)); - -for (n = 0U; n < N_PHILO; ++n) { - me->fork[n] = FREE; - me->isHungry[n] = 0U; -} - - #ifndef DPP_H -#define DPP_H + #ifndef DPP_H_ +#define DPP_H_ -enum DPPSignals { - EAT_SIG = Q_USER_SIG, /* published by Table to let a philosopher eat */ - DONE_SIG, /* published by Philosopher when done eating */ - PAUSE_SIG, /* published by BSP to pause serving forks */ - SERVE_SIG, /* published by BSP to serve re-start serving forks */ - TEST_SIG, /* published by BSP to test the application */ - MAX_PUB_SIG, /* the last published signal */ +$declare ${Shared} - HUNGRY_SIG, /* posted direclty to Table from hungry Philo */ - TIMEOUT_SIG, /* used by Philosophers for time events */ - MAX_SIG /* the last signal */ -}; +#ifdef QXK_H_ -$declare(Events::TableEvt) +extern QXThread * const TH_XThread1; +void XThread1_ctor(void); -/* number of philosophers */ -#define N_PHILO ((uint8_t)5) +extern QXThread * const TH_XThread2; +void XThread2_ctor(void); -$declare(AOs::Philo_ctor) -$declare(AOs::AO_Philo[N_PHILO]) +extern QXSemaphore TH_sema; +extern QXMutex TH_mutex; -$declare(AOs::Table_ctor) -$declare(AOs::AO_Table) +#endif // QXK_H_ -#ifdef QP_INC_QXK_H_ - void Test1_ctor(void); - extern QXThread * const XT_Test1; - void Test2_ctor(void); - extern QXThread * const XT_Test2; -#endif /* QP_INC_QXK_H_ */ - -#endif /* DPP_H */ - +#endif // DPP_H_ - #include "qpc.h" -#include "dpp.h" -#include "bsp.h" + #include "qpc.h" // QP/C real-time embedded framework +#include "dpp.h" // DPP Application interface +#include "bsp.h" // Board Support Package +$declare ${AOs::Philo} + +//---------------------------------------------------------------------------- Q_DEFINE_THIS_FILE -/* Active object class -----------------------------------------------------*/ -$declare(AOs::Philo) +// helper function to provide a randomized think time for Philos +static QTimeEvtCtr think_time(void); // prototype +static inline QTimeEvtCtr think_time(void) { + return (QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + + (BSP_TICKS_PER_SEC/2U)); +} -/* Local objects -----------------------------------------------------------*/ -static Philo l_philo[N_PHILO]; /* storage for all Philos */ +// helper function to provide a randomized eat time for Philos +static QTimeEvtCtr eat_time(void); // prototype +static inline QTimeEvtCtr eat_time(void) { + return (QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + + BSP_TICKS_PER_SEC); +} +//---------------------------------------------------------------------------- -#define THINK_TIME \ - (QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + (BSP_TICKS_PER_SEC/2U)) -#define EAT_TIME \ - (QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + BSP_TICKS_PER_SEC) - -/* helper macro to provide the ID of Philo "me_" */ -#define PHILO_ID(me_) ((uint8_t)((me_) - l_philo)) - -/* Global objects ----------------------------------------------------------*/ -QActive * const AO_Philo[N_PHILO] = { /* "opaque" pointers to Philo AO */ - &l_philo[0].super, - &l_philo[1].super, - &l_philo[2].super, - &l_philo[3].super, - &l_philo[4].super -}; - -/* Philo definition --------------------------------------------------------*/ -$define(AOs::Philo_ctor) -$define(AOs::Philo) +$define ${Shared::Philo_ctor} +$define ${Shared::AO_Philo[N_PHILO]} +$define ${AOs::Philo} - #include "qpc.h" -#include "dpp.h" -#include "bsp.h" + #include "qpc.h" // QP/C real-time embedded framework +#include "dpp.h" // DPP Application interface +#include "bsp.h" // Board Support Package +$declare ${AOs::Table} + +//---------------------------------------------------------------------------- Q_DEFINE_THIS_FILE -/* Active object class -----------------------------------------------------*/ -$declare(AOs::Table) +// helper function to provide the RIGHT neighbor of a Philo[n] +static inline uint8_t right(uint8_t const n) { + return (uint8_t)((n + (N_PHILO - 1U)) % N_PHILO); +} -#define RIGHT(n_) ((uint8_t)(((n_) + (N_PHILO - 1U)) % N_PHILO)) -#define LEFT(n_) ((uint8_t)(((n_) + 1U) % N_PHILO)) -#define FREE ((uint8_t)0) -#define USED ((uint8_t)1) +// helper function to provide the LEFT neighbor of a Philo[n] +static inline uint8_t left(uint8_t const n) { + return (uint8_t)((n + 1U) % N_PHILO); +} -/* Local objects -----------------------------------------------------------*/ -static Table l_table; /* the single instance of the Table active object */ +#define FREE ((uint8_t)0U) +#define USED ((uint8_t)1U) -/* Global-scope objects ----------------------------------------------------*/ -QActive * const AO_Table = &l_table.super; /* "opaque" AO pointer */ +#define THINKING "thinking" +#define HUNGRY "hungry " +#define EATING "eating " -/*..........................................................................*/ -$define(AOs::Table_ctor) -$define(AOs::Table) +//---------------------------------------------------------------------------- + +$define ${Shared::Table_ctor} +$define ${Shared::AO_Table} +$define ${AOs::Table} diff --git a/examples/freertos/arm-cm/dpp_ek-tm4c123gxl/ek-tm4c123gxl.jpg b/examples/freertos/arm-cm/dpp_ek-tm4c123gxl/ek-tm4c123gxl.jpg new file mode 100644 index 00000000..5ed6188c Binary files /dev/null and b/examples/freertos/arm-cm/dpp_ek-tm4c123gxl/ek-tm4c123gxl.jpg differ diff --git a/examples/freertos/arm-cm/dpp_ek-tm4c123gxl/gnu/Makefile b/examples/freertos/arm-cm/dpp_ek-tm4c123gxl/gnu/Makefile index 178946be..6091d436 100644 --- a/examples/freertos/arm-cm/dpp_ek-tm4c123gxl/gnu/Makefile +++ b/examples/freertos/arm-cm/dpp_ek-tm4c123gxl/gnu/Makefile @@ -1,13 +1,13 @@ ############################################################################## -# Product: Makefile for QP/C on EK-TM4C123GXL, FreeRTOS kernel, GNU-ARM -# Last Updated for Version: 7.0.1 -# Date of the Last Update: 2022-06-13 +# Product: Makefile for QP/C on EK-TM4C123GXL, FreeRTOS-Kernel, GNU-ARM +# Last Updated for Version: 7.2.2 +# Date of the Last Update: 2023-03-04 # # Q u a n t u m L e a P s # ------------------------ # Modern Embedded Software # -# Copyright (C) 2005-2021 Quantum Leaps, LLC. All rights reserved. +# Copyright (C) 2005 Quantum Leaps, LLC. . # # This program is open source software: you can redistribute it and/or # modify it under the terms of the GNU General Public License as published @@ -64,7 +64,7 @@ endif # location of the FREERTOS (if not provided in an environemnt var.) ifeq ($(FREERTOS),) -FREERTOS := $(QPC)/3rd_party/FreeRTOS +FREERTOS := $(QPC)/3rd_party/FreeRTOS-Kernel endif # QP port used in this project @@ -76,8 +76,8 @@ VPATH = \ $(QPC)/src/qf \ $(QPC)/src/qs \ $(QP_PORT_DIR) \ - $(FREERTOS)/Source \ - $(FREERTOS)/Source/portable/GCC/ARM_CM4F \ + $(FREERTOS) \ + $(FREERTOS)/portable/GCC/ARM_CM4F \ $(QPC)/3rd_party/ek-tm4c123gxl \ $(QPC)/3rd_party/ek-tm4c123gxl/gnu @@ -86,8 +86,8 @@ INCLUDES = \ -I.. \ -I$(QPC)/include \ -I$(QP_PORT_DIR) \ - -I$(FREERTOS)/Source/include \ - -I$(FREERTOS)/Source/portable/GCC/ARM_CM4F \ + -I$(FREERTOS)/include \ + -I$(FREERTOS)/portable/GCC/ARM_CM4F \ -I$(QPC)/3rd_party/CMSIS/Include \ -I$(QPC)/3rd_party/ek-tm4c123gxl @@ -142,7 +142,7 @@ LIB_DIRS := LIBS := # defines -DEFINES := -DTARGET_IS_TM4C123_RB1 +DEFINES := -DQP_CONFIG # ARM CPU, ARCH, FPU, and Float-ABI types... # ARM_CPU: [cortex-m0 | cortex-m0plus | cortex-m1 | cortex-m3 | cortex-m4] @@ -270,7 +270,7 @@ $(TARGET_BIN): $(TARGET_ELF) $(BIN) -O binary $< $@ $(TARGET_ELF) : $(ASM_OBJS_EXT) $(C_OBJS_EXT) $(CPP_OBJS_EXT) - $(CC) $(CFLAGS) $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o + $(CC) $(CFLAGS) $(QPC)/src/qs/qstamp.c -o $(BIN_DIR)/qstamp.o $(LINK) $(LINKFLAGS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) $(BIN_DIR)/%.d : %.c diff --git a/examples/freertos/arm-cm/dpp_ek-tm4c123gxl/gnu/dpp.ld b/examples/freertos/arm-cm/dpp_ek-tm4c123gxl/gnu/dpp.ld index a2e7e500..f9229c80 100644 --- a/examples/freertos/arm-cm/dpp_ek-tm4c123gxl/gnu/dpp.ld +++ b/examples/freertos/arm-cm/dpp_ek-tm4c123gxl/gnu/dpp.ld @@ -41,7 +41,7 @@ MEMORY { /* memory map of Tiva TM4C123GH6PM */ } /* The size of the stack used by the application. NOTE: you need to adjust */ -STACK_SIZE = 512; +STACK_SIZE = 1024; /* The size of the heap used by the application. NOTE: you need to adjust */ HEAP_SIZE = 0; diff --git a/examples/freertos/arm-cm/dpp_ek-tm4c123gxl/iar/dpp.ewd b/examples/freertos/arm-cm/dpp_ek-tm4c123gxl/iar/dpp.ewd index 1af6df07..ac11f153 100644 --- a/examples/freertos/arm-cm/dpp_ek-tm4c123gxl/iar/dpp.ewd +++ b/examples/freertos/arm-cm/dpp_ek-tm4c123gxl/iar/dpp.ewd @@ -11,7 +11,7 @@ C-SPY 2 - 28 + 32 1 1 - - + + + + + @@ -486,7 +498,7 @@ IJET_ID 2 - 8 + 9 1 1 + + + + + + + + + + + + + @@ -916,7 +980,7 @@ LMIFTDI_ID 2 - 2 + 3 1 1 + + + + + + + NULINK_ID + 2 + + 0 + 1 + 1 + + + @@ -974,7 +1072,7 @@ STLINK_ID 2 - 4 + 8 1 1 + + + + @@ -1185,7 +1300,7 @@ XDS100_ID 2 - 6 + 9 1 1 + + + + @@ -1362,6 +1493,18 @@ $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin 0 + + $TOOLKIT_DIR$\plugins\rtos\FreeRtos\FreeRtosArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin2.ENU.ewplugin + 0 + $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin 0 @@ -1371,11 +1514,15 @@ 0 - $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9.ewplugin 0 - $TOOLKIT_DIR$\plugins\rtos\TI-RTOS\tirtosplugin.ewplugin + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9BE.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin 0 @@ -1391,11 +1538,11 @@ 0 - $EW_DIR$\common\plugins\CodeCoverage\CodeCoverage.ENU.ewplugin - 1 + $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + 0 - $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + $EW_DIR$\common\plugins\TargetAccessServer\TargetAccessServer.ENU.ewplugin 0 @@ -1414,7 +1561,7 @@ C-SPY 2 - 28 + 32 1 0 - - + + + + + @@ -1889,7 +2048,7 @@ IJET_ID 2 - 8 + 9 1 0 + + + + + + + + + + + + + @@ -2319,7 +2530,7 @@ LMIFTDI_ID 2 - 2 + 3 1 0 + + + + + + + NULINK_ID + 2 + + 0 + 1 + 0 + + + @@ -2377,7 +2622,7 @@ STLINK_ID 2 - 4 + 8 1 0 + + + + @@ -2588,7 +2850,7 @@ XDS100_ID 2 - 6 + 9 1 0 + + + + @@ -2765,6 +3043,18 @@ $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin 0 + + $TOOLKIT_DIR$\plugins\rtos\FreeRtos\FreeRtosArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin2.ENU.ewplugin + 0 + $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin 0 @@ -2774,11 +3064,15 @@ 0 - $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9.ewplugin 0 - $TOOLKIT_DIR$\plugins\rtos\TI-RTOS\tirtosplugin.ewplugin + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9BE.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin 0 @@ -2794,11 +3088,11 @@ 0 - $EW_DIR$\common\plugins\CodeCoverage\CodeCoverage.ENU.ewplugin - 1 + $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + 0 - $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + $EW_DIR$\common\plugins\TargetAccessServer\TargetAccessServer.ENU.ewplugin 0 @@ -2817,7 +3111,7 @@ C-SPY 2 - 28 + 32 1 1 - - + + + + + @@ -3292,7 +3598,7 @@ IJET_ID 2 - 8 + 9 1 1 + + + + + + + + + + + + + @@ -3722,7 +4080,7 @@ LMIFTDI_ID 2 - 2 + 3 1 1 + + + + + + + NULINK_ID + 2 + + 0 + 1 + 1 + + + @@ -3780,7 +4172,7 @@ STLINK_ID 2 - 4 + 8 1 1 + + + + @@ -3991,7 +4400,7 @@ XDS100_ID 2 - 6 + 9 1 1 + + + + @@ -4168,6 +4593,18 @@ $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin 0 + + $TOOLKIT_DIR$\plugins\rtos\FreeRtos\FreeRtosArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin2.ENU.ewplugin + 0 + $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin 0 @@ -4177,11 +4614,15 @@ 0 - $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9.ewplugin 0 - $TOOLKIT_DIR$\plugins\rtos\TI-RTOS\tirtosplugin.ewplugin + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9BE.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin 0 @@ -4197,11 +4638,11 @@ 0 - $EW_DIR$\common\plugins\CodeCoverage\CodeCoverage.ENU.ewplugin - 1 + $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + 0 - $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + $EW_DIR$\common\plugins\TargetAccessServer\TargetAccessServer.ENU.ewplugin 0 diff --git a/examples/freertos/arm-cm/dpp_ek-tm4c123gxl/iar/dpp.ewp b/examples/freertos/arm-cm/dpp_ek-tm4c123gxl/iar/dpp.ewp index 3eea3f2b..b07addc9 100644 --- a/examples/freertos/arm-cm/dpp_ek-tm4c123gxl/iar/dpp.ewp +++ b/examples/freertos/arm-cm/dpp_ek-tm4c123gxl/iar/dpp.ewp @@ -11,12 +11,12 @@ General 3 - 33 + 35 1 1 + + + @@ -212,10 +224,6 @@ CCOptimizationNoSizeConstraints 0 - @@ -1065,12 +1089,12 @@ General 3 - 33 + 35 1 0 + + + @@ -1269,7 +1305,6 @@ @@ -2120,12 +2171,12 @@ General 3 - 33 + 35 1 1 + + + @@ -2324,7 +2387,6 @@ @@ -3185,9 +3263,6 @@ $PROJ_DIR$\..\philo.c - - $PROJ_DIR$\..\..\..\..\..\include\qstamp.c - $PROJ_DIR$\..\table.c @@ -3219,22 +3294,22 @@ FreeRTOS - $PROJ_DIR$\..\..\..\..\..\3rd_party\FreeRTOS\Source\list.c + $PROJ_DIR$\..\..\..\..\..\3rd_party\FreeRTOS-Kernel\list.c - $PROJ_DIR$\..\..\..\..\..\3rd_party\FreeRTOS\Source\portable\IAR\ARM_CM4F\port.c + $PROJ_DIR$\..\..\..\..\..\3rd_party\FreeRTOS-Kernel\portable\IAR\ARM_CM4F\port.c - $PROJ_DIR$\..\..\..\..\..\3rd_party\FreeRTOS\Source\portable\IAR\ARM_CM4F\portasm.s + $PROJ_DIR$\..\..\..\..\..\3rd_party\FreeRTOS-Kernel\portable\IAR\ARM_CM4F\portasm.s - $PROJ_DIR$\..\..\..\..\..\3rd_party\FreeRTOS\Source\portable\IAR\ARM_CM4F\portmacro.h + $PROJ_DIR$\..\..\..\..\..\3rd_party\FreeRTOS-Kernel\portable\IAR\ARM_CM4F\portmacro.h - $PROJ_DIR$\..\..\..\..\..\3rd_party\FreeRTOS\Source\queue.c + $PROJ_DIR$\..\..\..\..\..\3rd_party\FreeRTOS-Kernel\queue.c - $PROJ_DIR$\..\..\..\..\..\3rd_party\FreeRTOS\Source\tasks.c + $PROJ_DIR$\..\..\..\..\..\3rd_party\FreeRTOS-Kernel\tasks.c @@ -3306,6 +3381,9 @@ $PROJ_DIR$\..\..\..\..\..\src\qs\qs_rx.c + + $PROJ_DIR$\..\..\..\..\..\src\qs\qstamp.c + $PROJ_DIR$\..\..\..\..\..\src\qs\qutest.c diff --git a/examples/freertos/arm-cm/dpp_ek-tm4c123gxl/iar/dpp.icf b/examples/freertos/arm-cm/dpp_ek-tm4c123gxl/iar/dpp.icf index 0fdfc4b3..ee7abef3 100644 --- a/examples/freertos/arm-cm/dpp_ek-tm4c123gxl/iar/dpp.icf +++ b/examples/freertos/arm-cm/dpp_ek-tm4c123gxl/iar/dpp.icf @@ -9,7 +9,7 @@ define symbol __ICFEDIT_region_ROM_end__ = 0x0003FFFF; define symbol __ICFEDIT_region_RAM_start__ = 0x20000000; define symbol __ICFEDIT_region_RAM_end__ = 0x20007FFF; /*-Sizes-*/ -define symbol __ICFEDIT_size_cstack__ = 2048; +define symbol __ICFEDIT_size_cstack__ = 1024; define symbol __ICFEDIT_size_heap__ = 0; /**** End of ICF editor section. ###ICF###*/ @@ -25,5 +25,5 @@ do not initialize { section .noinit }; place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec }; place in ROM_region { readonly }; -place at start of RAM_region {block CSTACK }; +place at start of RAM_region {block CSTACK }; /* <== Quantum Leaps */ place in RAM_region { readwrite, block HEAP }; \ No newline at end of file diff --git a/examples/freertos/arm-cm/dpp_ek-tm4c123gxl/main.c b/examples/freertos/arm-cm/dpp_ek-tm4c123gxl/main.c index ae3b25ce..cfcfaf07 100644 --- a/examples/freertos/arm-cm/dpp_ek-tm4c123gxl/main.c +++ b/examples/freertos/arm-cm/dpp_ek-tm4c123gxl/main.c @@ -1,91 +1,44 @@ -/***************************************************************************** -* Product: DPP example, FreeRTOS kernel -* Last updated for version 7.0.1 -* Last updated on 2022-06-13 -* -* Q u a n t u m L e a P s -* ------------------------ -* Modern Embedded Software -* -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* -* -*****************************************************************************/ -#include "qpc.h" -#include "dpp.h" -#include "bsp.h" +//============================================================================ +// APP example +// Last updated for version 7.3.0 +// Last updated on 2023-08-09 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. +// +// This program is open source software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Alternatively, this program may be distributed and modified under the +// terms of Quantum Leaps commercial licenses, which expressly supersede +// the GNU General Public License and are specifically designed for +// licensees interested in retaining the proprietary status of their code. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Contact information: +// +// +//============================================================================ +#include "qpc.h" // QP/C real-time embedded framework +#include "dpp.h" // DPP Application interface +#include "bsp.h" // Board Support Package -Q_DEFINE_THIS_FILE - -/*..........................................................................*/ +//............................................................................ int main() { - static QEvt const *tableQueueSto[N_PHILO]; - static QEvt const *philoQueueSto[N_PHILO][N_PHILO]; - static QSubscrList subscrSto[MAX_PUB_SIG]; - static QF_MPOOL_EL(TableEvt) smlPoolSto[2*N_PHILO]; /* small pool */ - - static StackType_t philoStack[N_PHILO][configMINIMAL_STACK_SIZE]; - static StackType_t tableStack[configMINIMAL_STACK_SIZE]; - - QF_init(); /* initialize the framework and the underlying RT kernel */ - - /* initialize publish-subscribe... */ - QF_psInit(subscrSto, Q_DIM(subscrSto)); - - /* initialize event pools... */ - QF_poolInit(smlPoolSto, sizeof(smlPoolSto), sizeof(smlPoolSto[0])); - - /* initialize the Board Support Package - * NOTE: BSP_init() is called *after* initializing publish-subscribe and - * event pools, to make the system ready to accept SysTick interrupts. - * Unfortunately, the STM32Cube code that must be called from BSP, - * configures and starts SysTick. - */ - BSP_init(); - - /* start the active objects... */ - Philo_ctor(); /* instantiate all Philosopher active objects */ - for (uint8_t n = 0U; n < N_PHILO; ++n) { - QActive_setAttr(AO_Philo[n], TASK_NAME_ATTR, "Philo"); - QACTIVE_START(AO_Philo[n], /* AO to start */ - (uint_fast8_t)(n + 1), /* QP priority of the AO */ - philoQueueSto[n], /* event queue storage */ - Q_DIM(philoQueueSto[n]), /* queue length [events] */ - philoStack[n], /* stack storage */ - sizeof(philoStack[n]), /* stack size [bytes] */ - (QEvt *)0); /* initialization event (not used) */ - } - - Table_ctor(); /* instantiate the Table active object */ - QActive_setAttr(AO_Table, TASK_NAME_ATTR, "Table"); - QACTIVE_START(AO_Table, /* AO to start */ - (uint_fast8_t)(N_PHILO + 1), /* QP priority of the AO */ - tableQueueSto, /* event queue storage */ - Q_DIM(tableQueueSto), /* queue length [events] */ - tableStack, /* stack storage */ - sizeof(tableStack), /* stack size [bytes] */ - (QEvt *)0); /* initialization event (not used) */ - - return QF_run(); /* run the QF application */ + QF_init(); // initialize the framework and the underlying RT kernel + BSP_init(); // initialize the BSP + BSP_start(); // start the AOs/Threads + return QF_run(); // run the QF application } - diff --git a/examples/freertos/arm-cm/dpp_ek-tm4c123gxl/philo.c b/examples/freertos/arm-cm/dpp_ek-tm4c123gxl/philo.c index 7614912a..eb6be531 100644 --- a/examples/freertos/arm-cm/dpp_ek-tm4c123gxl/philo.c +++ b/examples/freertos/arm-cm/dpp_ek-tm4c123gxl/philo.c @@ -1,165 +1,159 @@ -/*$file${.::philo.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* -* Model: dpp.qm -* File: ${.::philo.c} -* -* This code has been generated by QM 5.2.4 . -* DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. -* -* SPDX-License-Identifier: GPL-3.0-or-later -* -* This generated code is open source software: you can redistribute it under -* the terms of the GNU General Public License as published by the Free -* Software Foundation. -* -* This code is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -* more details. -* -* NOTE: -* Alternatively, this generated code may be distributed under the terms -* of Quantum Leaps commercial licenses, which expressly supersede the GNU -* General Public License and are specifically designed for licensees -* interested in retaining the proprietary status of their code. -* -* Contact information: -* -* -*/ -/*$endhead${.::philo.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -#include "qpc.h" -#include "dpp.h" -#include "bsp.h" +//$file${.::philo.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// +// Model: dpp.qm +// File: ${.::philo.c} +// +// This code has been generated by QM 5.3.0 . +// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. +// +// SPDX-License-Identifier: GPL-3.0-or-later +// +// This generated code is open source software: you can redistribute it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation. +// +// This code is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// NOTE: +// Alternatively, this generated code may be distributed under the terms +// of Quantum Leaps commercial licenses, which expressly supersede the GNU +// General Public License and are specifically designed for licensees +// interested in retaining the proprietary status of their code. +// +// Contact information: +// +// +// +//$endhead${.::philo.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +#include "qpc.h" // QP/C real-time embedded framework +#include "dpp.h" // DPP Application interface +#include "bsp.h" // Board Support Package -Q_DEFINE_THIS_FILE +//$declare${AOs::Philo} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/* Active object class -----------------------------------------------------*/ -/*$declare${AOs::Philo} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${AOs::Philo} ............................................................*/ -typedef struct { -/* protected: */ +//${AOs::Philo} .............................................................. +typedef struct Philo { +// protected: QActive super; -/* private: */ +// private: QTimeEvt timeEvt; + uint8_t id; + +// public: } Philo; -/* protected: */ +extern Philo Philo_inst[N_PHILO]; + +// protected: static QState Philo_initial(Philo * const me, void const * const par); static QState Philo_thinking(Philo * const me, QEvt const * const e); static QState Philo_hungry(Philo * const me, QEvt const * const e); static QState Philo_eating(Philo * const me, QEvt const * const e); -/*$enddecl${AOs::Philo} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$enddecl${AOs::Philo} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -/* Local objects -----------------------------------------------------------*/ -static Philo l_philo[N_PHILO]; /* storage for all Philos */ +//---------------------------------------------------------------------------- +Q_DEFINE_THIS_FILE -#define THINK_TIME \ - (QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + (BSP_TICKS_PER_SEC/2U)) -#define EAT_TIME \ - (QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + BSP_TICKS_PER_SEC) - -/* helper macro to provide the ID of Philo "me_" */ -#define PHILO_ID(me_) ((uint8_t)((me_) - l_philo)) - -/* Global objects ----------------------------------------------------------*/ -QActive * const AO_Philo[N_PHILO] = { /* "opaque" pointers to Philo AO */ - &l_philo[0].super, - &l_philo[1].super, - &l_philo[2].super, - &l_philo[3].super, - &l_philo[4].super -}; - -/* Philo definition --------------------------------------------------------*/ -/*$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* Check for the minimum required QP version */ -#if (QP_VERSION < 700U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) -#error qpc version 7.0.0 or higher required -#endif -/*$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ - -/*$define${AOs::Philo_ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${AOs::Philo_ctor} .......................................................*/ -void Philo_ctor(void) { - uint8_t n; - Philo *me; - for (n = 0U; n < N_PHILO; ++n) { - me = &l_philo[n]; - QActive_ctor(&me->super, Q_STATE_CAST(&Philo_initial)); - QTimeEvt_ctorX(&me->timeEvt, &me->super, TIMEOUT_SIG, 0U); - } +// helper function to provide a randomized think time for Philos +static QTimeEvtCtr think_time(void); // prototype +static inline QTimeEvtCtr think_time(void) { + return (QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + + (BSP_TICKS_PER_SEC/2U)); } -/*$enddef${AOs::Philo_ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*$define${AOs::Philo} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/*${AOs::Philo} ............................................................*/ +// helper function to provide a randomized eat time for Philos +static QTimeEvtCtr eat_time(void); // prototype +static inline QTimeEvtCtr eat_time(void) { + return (QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + + BSP_TICKS_PER_SEC); +} +//---------------------------------------------------------------------------- -/*${AOs::Philo::SM} ........................................................*/ +//$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// Check for the minimum required QP version +#if (QP_VERSION < 730U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) +#error qpc version 7.3.0 or higher required +#endif +//$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +//$define${Shared::Philo_ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${Shared::Philo_ctor} ...................................................... +void Philo_ctor(uint_fast8_t const id) { + Philo * const me = &Philo_inst[id]; + QActive_ctor(&me->super, Q_STATE_CAST(&Philo_initial)); + QTimeEvt_ctorX(&me->timeEvt, &me->super, TIMEOUT_SIG, 0U), + me->id = (uint8_t)id; +} +//$enddef${Shared::Philo_ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +//$define${Shared::AO_Philo[N_PHILO]} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${Shared::AO_Philo[N_PHILO]} ............................................... +QActive * const AO_Philo[N_PHILO] = { + &Philo_inst[0].super, + &Philo_inst[1].super, + &Philo_inst[2].super, + &Philo_inst[3].super, + &Philo_inst[4].super +}; +//$enddef${Shared::AO_Philo[N_PHILO]} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +//$define${AOs::Philo} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${AOs::Philo} .............................................................. +Philo Philo_inst[N_PHILO]; + +//${AOs::Philo::SM} .......................................................... static QState Philo_initial(Philo * const me, void const * const par) { - /*${AOs::Philo::SM::initial} */ - static uint8_t registered = (uint8_t)0; /* starts off with 0, per C-standard */ - (void)par; /* unused parameter */ - if (registered == (uint8_t)0) { - registered = (uint8_t)1; + //${AOs::Philo::SM::initial} + Q_UNUSED_PAR(par); - QS_OBJ_DICTIONARY(&l_philo[0]); - QS_OBJ_DICTIONARY(&l_philo[0].timeEvt); - QS_OBJ_DICTIONARY(&l_philo[1]); - QS_OBJ_DICTIONARY(&l_philo[1].timeEvt); - QS_OBJ_DICTIONARY(&l_philo[2]); - QS_OBJ_DICTIONARY(&l_philo[2].timeEvt); - QS_OBJ_DICTIONARY(&l_philo[3]); - QS_OBJ_DICTIONARY(&l_philo[3].timeEvt); - QS_OBJ_DICTIONARY(&l_philo[4]); - QS_OBJ_DICTIONARY(&l_philo[4].timeEvt); - - QS_FUN_DICTIONARY(&Philo_initial); - QS_FUN_DICTIONARY(&Philo_thinking); - QS_FUN_DICTIONARY(&Philo_hungry); - QS_FUN_DICTIONARY(&Philo_eating); - } - QS_SIG_DICTIONARY(HUNGRY_SIG, me); /* signal for each Philos */ - QS_SIG_DICTIONARY(TIMEOUT_SIG, me); /* signal for each Philos */ + QS_OBJ_ARR_DICTIONARY(&Philo_inst[me->id], me->id); + QS_OBJ_ARR_DICTIONARY(&Philo_inst[me->id].timeEvt, me->id); QActive_subscribe(&me->super, EAT_SIG); QActive_subscribe(&me->super, TEST_SIG); + + QS_FUN_DICTIONARY(&Philo_thinking); + QS_FUN_DICTIONARY(&Philo_hungry); + QS_FUN_DICTIONARY(&Philo_eating); + return Q_TRAN(&Philo_thinking); } -/*${AOs::Philo::SM::thinking} ..............................................*/ +//${AOs::Philo::SM::thinking} ................................................ static QState Philo_thinking(Philo * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${AOs::Philo::SM::thinking} */ + //${AOs::Philo::SM::thinking} case Q_ENTRY_SIG: { - QTimeEvt_armX(&me->timeEvt, THINK_TIME, 0U); + QTimeEvt_armX(&me->timeEvt, think_time(), 0U); status_ = Q_HANDLED(); break; } - /*${AOs::Philo::SM::thinking} */ + //${AOs::Philo::SM::thinking} case Q_EXIT_SIG: { - QTimeEvt_disarm(&me->timeEvt); + (void)QTimeEvt_disarm(&me->timeEvt); status_ = Q_HANDLED(); break; } - /*${AOs::Philo::SM::thinking::TIMEOUT} */ + //${AOs::Philo::SM::thinking::TIMEOUT} case TIMEOUT_SIG: { status_ = Q_TRAN(&Philo_hungry); break; } - /*${AOs::Philo::SM::thinking::EAT, DONE} */ - case EAT_SIG: /* intentionally fall through */ + //${AOs::Philo::SM::thinking::EAT, DONE} + case EAT_SIG: // intentionally fall through case DONE_SIG: { - /* EAT or DONE must be for other Philos than this one */ - Q_ASSERT(Q_EVT_CAST(TableEvt)->philoNum != PHILO_ID(me)); + // EAT or DONE must be for other Philos than this one + Q_ASSERT(Q_EVT_CAST(TableEvt)->philoId != me->id); status_ = Q_HANDLED(); break; } - /*${AOs::Philo::SM::thinking::TEST} */ + //${AOs::Philo::SM::thinking::TEST} case TEST_SIG: { status_ = Q_HANDLED(); break; @@ -172,22 +166,26 @@ static QState Philo_thinking(Philo * const me, QEvt const * const e) { return status_; } -/*${AOs::Philo::SM::hungry} ................................................*/ +//${AOs::Philo::SM::hungry} .................................................. static QState Philo_hungry(Philo * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${AOs::Philo::SM::hungry} */ + //${AOs::Philo::SM::hungry} case Q_ENTRY_SIG: { + #ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, HUNGRY_SIG, me->id); + #else TableEvt *pe = Q_NEW(TableEvt, HUNGRY_SIG); - pe->philoNum = PHILO_ID(me); - QACTIVE_POST(AO_Table, &pe->super, me); + pe->philoId = me->id; + #endif + QACTIVE_POST(AO_Table, &pe->super, &me->super); status_ = Q_HANDLED(); break; } - /*${AOs::Philo::SM::hungry::EAT} */ + //${AOs::Philo::SM::hungry::EAT} case EAT_SIG: { - /*${AOs::Philo::SM::hungry::EAT::[Q_EVT_CAST(TableEvt)->philoNum=~} */ - if (Q_EVT_CAST(TableEvt)->philoNum == PHILO_ID(me)) { + //${AOs::Philo::SM::hungry::EAT::[e->philoId==me->iid]} + if (Q_EVT_CAST(TableEvt)->philoId == me->id) { status_ = Q_TRAN(&Philo_eating); } else { @@ -195,10 +193,10 @@ static QState Philo_hungry(Philo * const me, QEvt const * const e) { } break; } - /*${AOs::Philo::SM::hungry::DONE} */ + //${AOs::Philo::SM::hungry::DONE} case DONE_SIG: { - /* DONE must be for other Philos than this one */ - Q_ASSERT(Q_EVT_CAST(TableEvt)->philoNum != PHILO_ID(me)); + // DONE must be for other Philos than this one + Q_ASSERT(Q_EVT_CAST(TableEvt)->philoId != me->id); status_ = Q_HANDLED(); break; } @@ -210,34 +208,40 @@ static QState Philo_hungry(Philo * const me, QEvt const * const e) { return status_; } -/*${AOs::Philo::SM::eating} ................................................*/ +//${AOs::Philo::SM::eating} .................................................. static QState Philo_eating(Philo * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${AOs::Philo::SM::eating} */ + //${AOs::Philo::SM::eating} case Q_ENTRY_SIG: { - QTimeEvt_armX(&me->timeEvt, EAT_TIME, 0U); + QTimeEvt_armX(&me->timeEvt, eat_time(), 0U); status_ = Q_HANDLED(); break; } - /*${AOs::Philo::SM::eating} */ + //${AOs::Philo::SM::eating} case Q_EXIT_SIG: { + (void)QTimeEvt_disarm(&me->timeEvt); + + #ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, DONE_SIG, me->id); + #else TableEvt *pe = Q_NEW(TableEvt, DONE_SIG); - pe->philoNum = PHILO_ID(me); + pe->philoId = me->id; + #endif QACTIVE_PUBLISH(&pe->super, &me->super); status_ = Q_HANDLED(); break; } - /*${AOs::Philo::SM::eating::TIMEOUT} */ + //${AOs::Philo::SM::eating::TIMEOUT} case TIMEOUT_SIG: { status_ = Q_TRAN(&Philo_thinking); break; } - /*${AOs::Philo::SM::eating::EAT, DONE} */ - case EAT_SIG: /* intentionally fall through */ + //${AOs::Philo::SM::eating::EAT, DONE} + case EAT_SIG: // intentionally fall through case DONE_SIG: { - /* EAT or DONE must be for other Philos than this one */ - Q_ASSERT(Q_EVT_CAST(TableEvt)->philoNum != PHILO_ID(me)); + // EAT or DONE must be for other Philos than this one + Q_ASSERT(Q_EVT_CAST(TableEvt)->philoId != me->id); status_ = Q_HANDLED(); break; } @@ -248,4 +252,4 @@ static QState Philo_eating(Philo * const me, QEvt const * const e) { } return status_; } -/*$enddef${AOs::Philo} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$enddef${AOs::Philo} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/examples/freertos/arm-cm/dpp_ek-tm4c123gxl/qp_config.h b/examples/freertos/arm-cm/dpp_ek-tm4c123gxl/qp_config.h new file mode 100644 index 00000000..497ce748 --- /dev/null +++ b/examples/freertos/arm-cm/dpp_ek-tm4c123gxl/qp_config.h @@ -0,0 +1,41 @@ +//============================================================================ +// QP configuration file example +// Last updated for version: 7.3.0 +// Last updated on: 2023-09-02 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +//============================================================================ +#ifndef QP_CONFIG_H_ +#define QP_CONFIG_H_ + +// NOTE: +// The QP configuration takes effect only when the macro QP_CONFIG +// is defined on the command-line to the compiler for all QP source files. + +#define QF_MAX_ACTIVE configMAX_PRIORITIES + +#endif // QP_CONFIG_H_ diff --git a/examples/freertos/arm-cm/dpp_ek-tm4c123gxl/table.c b/examples/freertos/arm-cm/dpp_ek-tm4c123gxl/table.c index d14c29d4..c3ae02f0 100644 --- a/examples/freertos/arm-cm/dpp_ek-tm4c123gxl/table.c +++ b/examples/freertos/arm-cm/dpp_ek-tm4c123gxl/table.c @@ -1,111 +1,120 @@ -/*$file${.::table.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* -* Model: dpp.qm -* File: ${.::table.c} -* -* This code has been generated by QM 5.2.4 . -* DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. -* -* SPDX-License-Identifier: GPL-3.0-or-later -* -* This generated code is open source software: you can redistribute it under -* the terms of the GNU General Public License as published by the Free -* Software Foundation. -* -* This code is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -* more details. -* -* NOTE: -* Alternatively, this generated code may be distributed under the terms -* of Quantum Leaps commercial licenses, which expressly supersede the GNU -* General Public License and are specifically designed for licensees -* interested in retaining the proprietary status of their code. -* -* Contact information: -* -* -*/ -/*$endhead${.::table.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -#include "qpc.h" -#include "dpp.h" -#include "bsp.h" +//$file${.::table.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// +// Model: dpp.qm +// File: ${.::table.c} +// +// This code has been generated by QM 5.3.0 . +// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. +// +// SPDX-License-Identifier: GPL-3.0-or-later +// +// This generated code is open source software: you can redistribute it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation. +// +// This code is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// NOTE: +// Alternatively, this generated code may be distributed under the terms +// of Quantum Leaps commercial licenses, which expressly supersede the GNU +// General Public License and are specifically designed for licensees +// interested in retaining the proprietary status of their code. +// +// Contact information: +// +// +// +//$endhead${.::table.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +#include "qpc.h" // QP/C real-time embedded framework +#include "dpp.h" // DPP Application interface +#include "bsp.h" // Board Support Package -Q_DEFINE_THIS_FILE +//$declare${AOs::Table} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/* Active object class -----------------------------------------------------*/ -/*$declare${AOs::Table} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${AOs::Table} ............................................................*/ -typedef struct { -/* protected: */ +//${AOs::Table} .............................................................. +typedef struct Table { +// protected: QActive super; -/* private: */ +// private: uint8_t fork[N_PHILO]; - uint8_t isHungry[N_PHILO]; + bool isHungry[N_PHILO]; + +// public: } Table; -/* protected: */ +extern Table Table_inst; + +// protected: static QState Table_initial(Table * const me, void const * const par); static QState Table_active(Table * const me, QEvt const * const e); static QState Table_serving(Table * const me, QEvt const * const e); static QState Table_paused(Table * const me, QEvt const * const e); -/*$enddecl${AOs::Table} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$enddecl${AOs::Table} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -#define RIGHT(n_) ((uint8_t)(((n_) + (N_PHILO - 1U)) % N_PHILO)) -#define LEFT(n_) ((uint8_t)(((n_) + 1U) % N_PHILO)) -#define FREE ((uint8_t)0) -#define USED ((uint8_t)1) +//---------------------------------------------------------------------------- +Q_DEFINE_THIS_FILE -/* Local objects -----------------------------------------------------------*/ -static Table l_table; /* the single instance of the Table active object */ +// helper function to provide the RIGHT neighbor of a Philo[n] +static inline uint8_t right(uint8_t const n) { + return (uint8_t)((n + (N_PHILO - 1U)) % N_PHILO); +} -/* Global-scope objects ----------------------------------------------------*/ -QActive * const AO_Table = &l_table.super; /* "opaque" AO pointer */ +// helper function to provide the LEFT neighbor of a Philo[n] +static inline uint8_t left(uint8_t const n) { + return (uint8_t)((n + 1U) % N_PHILO); +} -/*..........................................................................*/ -/*$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* Check for the minimum required QP version */ -#if (QP_VERSION < 700U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) -#error qpc version 7.0.0 or higher required +#define FREE ((uint8_t)0U) +#define USED ((uint8_t)1U) + +#define THINKING "thinking" +#define HUNGRY "hungry " +#define EATING "eating " + +//---------------------------------------------------------------------------- + +//$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// Check for the minimum required QP version +#if (QP_VERSION < 730U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) +#error qpc version 7.3.0 or higher required #endif -/*$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -/*$define${AOs::Table_ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//$define${Shared::Table_ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/*${AOs::Table_ctor} .......................................................*/ +//${Shared::Table_ctor} ...................................................... void Table_ctor(void) { - uint8_t n; - Table *me = &l_table; - + Table * const me = &Table_inst; QActive_ctor(&me->super, Q_STATE_CAST(&Table_initial)); - - for (n = 0U; n < N_PHILO; ++n) { + for (uint8_t n = 0U; n < N_PHILO; ++n) { me->fork[n] = FREE; - me->isHungry[n] = 0U; + me->isHungry[n] = false; } } -/*$enddef${AOs::Table_ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*$define${AOs::Table} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//$enddef${Shared::Table_ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +//$define${Shared::AO_Table} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/*${AOs::Table} ............................................................*/ +//${Shared::AO_Table} ........................................................ +QActive * const AO_Table = &Table_inst.super; +//$enddef${Shared::AO_Table} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +//$define${AOs::Table} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/*${AOs::Table::SM} ........................................................*/ +//${AOs::Table} .............................................................. +Table Table_inst; + +//${AOs::Table::SM} .......................................................... static QState Table_initial(Table * const me, void const * const par) { - /*${AOs::Table::SM::initial} */ - (void)par; /* unused parameter */ + //${AOs::Table::SM::initial} + Q_UNUSED_PAR(par); - QS_OBJ_DICTIONARY(&l_table); - - QS_SIG_DICTIONARY(DONE_SIG, (void *)0); /* global signals */ - QS_SIG_DICTIONARY(EAT_SIG, (void *)0); - QS_SIG_DICTIONARY(PAUSE_SIG, (void *)0); - QS_SIG_DICTIONARY(SERVE_SIG, (void *)0); - QS_SIG_DICTIONARY(TEST_SIG, (void *)0); - - QS_SIG_DICTIONARY(HUNGRY_SIG, me); /* signal just for Table */ + #ifdef Q_SPY + Table *Table_inst = me; + QS_OBJ_DICTIONARY(Table_inst); + #endif QActive_subscribe(&me->super, DONE_SIG); QActive_subscribe(&me->super, PAUSE_SIG); @@ -114,8 +123,8 @@ static QState Table_initial(Table * const me, void const * const par) { for (uint8_t n = 0U; n < N_PHILO; ++n) { me->fork[n] = FREE; - me->isHungry[n] = 0U; - BSP_displayPhilStat(n, "thinking"); + me->isHungry[n] = false; + BSP_displayPhilStat(n, THINKING); } QS_FUN_DICTIONARY(&Table_active); @@ -125,16 +134,16 @@ static QState Table_initial(Table * const me, void const * const par) { return Q_TRAN(&Table_serving); } -/*${AOs::Table::SM::active} ................................................*/ +//${AOs::Table::SM::active} .................................................. static QState Table_active(Table * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${AOs::Table::SM::active::TEST} */ + //${AOs::Table::SM::active::TEST} case TEST_SIG: { status_ = Q_HANDLED(); break; } - /*${AOs::Table::SM::active::EAT} */ + //${AOs::Table::SM::active::EAT} case EAT_SIG: { Q_ERROR(); status_ = Q_HANDLED(); @@ -148,108 +157,119 @@ static QState Table_active(Table * const me, QEvt const * const e) { return status_; } -/*${AOs::Table::SM::active::serving} .......................................*/ +//${AOs::Table::SM::active::serving} ......................................... static QState Table_serving(Table * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${AOs::Table::SM::active::serving} */ + //${AOs::Table::SM::active::serving} case Q_ENTRY_SIG: { - uint8_t n; - for (n = 0U; n < N_PHILO; ++n) { /* give permissions to eat... */ - if ((me->isHungry[n] != 0U) - && (me->fork[LEFT(n)] == FREE) + // give permissions to eat... + for (uint8_t n = 0U; n < N_PHILO; ++n) { + if (me->isHungry[n] + && (me->fork[left(n)] == FREE) && (me->fork[n] == FREE)) { - TableEvt *te; - - me->fork[LEFT(n)] = USED; + me->fork[left(n)] = USED; me->fork[n] = USED; - te = Q_NEW(TableEvt, EAT_SIG); - te->philoNum = n; - QACTIVE_PUBLISH(&te->super, &me->super); - me->isHungry[n] = 0U; - BSP_displayPhilStat(n, "eating "); + #ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, EAT_SIG, n); + #else + TableEvt *pe = Q_NEW(TableEvt, EAT_SIG); + pe->philoId = n; + #endif + QACTIVE_PUBLISH(&pe->super, &me->super); + me->isHungry[n] = false; + BSP_displayPhilStat(n, EATING); } } status_ = Q_HANDLED(); break; } - /*${AOs::Table::SM::active::serving::HUNGRY} */ + //${AOs::Table::SM::active::serving::HUNGRY} case HUNGRY_SIG: { - uint8_t n, m; + uint8_t n = Q_EVT_CAST(TableEvt)->philoId; - n = Q_EVT_CAST(TableEvt)->philoNum; - /* phil ID must be in range and he must be not hungry */ - Q_ASSERT((n < N_PHILO) && (me->isHungry[n] == 0U)); + // phil ID must be in range and he must be not hungry + Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); - BSP_displayPhilStat(n, "hungry "); - m = LEFT(n); - /*${AOs::Table::SM::active::serving::HUNGRY::[bothfree]} */ + BSP_displayPhilStat(n, HUNGRY); + uint8_t m = left(n); + //${AOs::Table::SM::active::serving::HUNGRY::[bothfree]} if ((me->fork[m] == FREE) && (me->fork[n] == FREE)) { - TableEvt *pe; me->fork[m] = USED; me->fork[n] = USED; - pe = Q_NEW(TableEvt, EAT_SIG); - pe->philoNum = n; + #ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, EAT_SIG, n); + #else + TableEvt *pe = Q_NEW(TableEvt, EAT_SIG); + pe->philoId = n; + #endif QACTIVE_PUBLISH(&pe->super, &me->super); - BSP_displayPhilStat(n, "eating "); + BSP_displayPhilStat(n, EATING); status_ = Q_HANDLED(); } - /*${AOs::Table::SM::active::serving::HUNGRY::[else]} */ + //${AOs::Table::SM::active::serving::HUNGRY::[else]} else { - me->isHungry[n] = 1U; + me->isHungry[n] = true; status_ = Q_HANDLED(); } break; } - /*${AOs::Table::SM::active::serving::DONE} */ + //${AOs::Table::SM::active::serving::DONE} case DONE_SIG: { - uint8_t n, m; - TableEvt *pe; + uint8_t n = Q_EVT_CAST(TableEvt)->philoId; - n = Q_EVT_CAST(TableEvt)->philoNum; - /* phil ID must be in range and he must be not hungry */ - Q_ASSERT((n < N_PHILO) && (me->isHungry[n] == 0U)); + // phil ID must be in range and he must be not hungry + Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); - BSP_displayPhilStat(n, "thinking"); - m = LEFT(n); - /* both forks of Phil[n] must be used */ + BSP_displayPhilStat(n, THINKING); + uint8_t m = left(n); + + // both forks of Phil[n] must be used Q_ASSERT((me->fork[n] == USED) && (me->fork[m] == USED)); me->fork[m] = FREE; me->fork[n] = FREE; - m = RIGHT(n); /* check the right neighbor */ + m = right(n); // check the right neighbor - if ((me->isHungry[m] != 0U) && (me->fork[m] == FREE)) { + if (me->isHungry[m] && (me->fork[m] == FREE)) { me->fork[n] = USED; me->fork[m] = USED; - me->isHungry[m] = 0U; - pe = Q_NEW(TableEvt, EAT_SIG); - pe->philoNum = m; + me->isHungry[m] = false; + #ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, EAT_SIG, m); + #else + TableEvt *pe = Q_NEW(TableEvt, EAT_SIG); + pe->philoId = m; + #endif QACTIVE_PUBLISH(&pe->super, &me->super); - BSP_displayPhilStat(m, "eating "); + BSP_displayPhilStat(m, EATING); } - m = LEFT(n); /* check the left neighbor */ - n = LEFT(m); /* left fork of the left neighbor */ - if ((me->isHungry[m] != 0U) && (me->fork[n] == FREE)) { + m = left(n); // check the left neighbor + n = left(m); // left fork of the left neighbor + if (me->isHungry[m] && (me->fork[n] == FREE)) { me->fork[m] = USED; me->fork[n] = USED; - me->isHungry[m] = 0U; - pe = Q_NEW(TableEvt, EAT_SIG); - pe->philoNum = m; + me->isHungry[m] = false; + #ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, EAT_SIG, m); + #else + TableEvt *pe = Q_NEW(TableEvt, EAT_SIG); + pe->philoId = m; + #endif QACTIVE_PUBLISH(&pe->super, &me->super); - BSP_displayPhilStat(m, "eating "); + BSP_displayPhilStat(m, EATING); } status_ = Q_HANDLED(); break; } - /*${AOs::Table::SM::active::serving::EAT} */ + //${AOs::Table::SM::active::serving::EAT} case EAT_SIG: { Q_ERROR(); status_ = Q_HANDLED(); break; } - /*${AOs::Table::SM::active::serving::PAUSE} */ + //${AOs::Table::SM::active::serving::PAUSE} case PAUSE_SIG: { status_ = Q_TRAN(&Table_paused); break; @@ -262,48 +282,50 @@ static QState Table_serving(Table * const me, QEvt const * const e) { return status_; } -/*${AOs::Table::SM::active::paused} ........................................*/ +//${AOs::Table::SM::active::paused} .......................................... static QState Table_paused(Table * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${AOs::Table::SM::active::paused} */ + //${AOs::Table::SM::active::paused} case Q_ENTRY_SIG: { BSP_displayPaused(1U); status_ = Q_HANDLED(); break; } - /*${AOs::Table::SM::active::paused} */ + //${AOs::Table::SM::active::paused} case Q_EXIT_SIG: { BSP_displayPaused(0U); status_ = Q_HANDLED(); break; } - /*${AOs::Table::SM::active::paused::SERVE} */ + //${AOs::Table::SM::active::paused::SERVE} case SERVE_SIG: { status_ = Q_TRAN(&Table_serving); break; } - /*${AOs::Table::SM::active::paused::HUNGRY} */ + //${AOs::Table::SM::active::paused::HUNGRY} case HUNGRY_SIG: { - uint8_t n = Q_EVT_CAST(TableEvt)->philoNum; - /* philo ID must be in range and he must be not hungry */ - Q_ASSERT((n < N_PHILO) && (me->isHungry[n] == 0U)); - me->isHungry[n] = 1U; - BSP_displayPhilStat(n, "hungry "); + uint8_t n = Q_EVT_CAST(TableEvt)->philoId; + + // philo ID must be in range and he must be not hungry + Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); + + me->isHungry[n] = true; + BSP_displayPhilStat(n, HUNGRY); status_ = Q_HANDLED(); break; } - /*${AOs::Table::SM::active::paused::DONE} */ + //${AOs::Table::SM::active::paused::DONE} case DONE_SIG: { - uint8_t n, m; + uint8_t n = Q_EVT_CAST(TableEvt)->philoId; - n = Q_EVT_CAST(TableEvt)->philoNum; - /* phil ID must be in range and he must be not hungry */ - Q_ASSERT((n < N_PHILO) && (me->isHungry[n] == 0U)); + // phil ID must be in range and he must be not hungry + Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); - BSP_displayPhilStat(n, "thinking"); - m = LEFT(n); - /* both forks of Phil[n] must be used */ + BSP_displayPhilStat(n, THINKING); + uint8_t m = left(n); + + // both forks of Phil[n] must be used Q_ASSERT((me->fork[n] == USED) && (me->fork[m] == USED)); me->fork[m] = FREE; @@ -318,4 +340,4 @@ static QState Table_paused(Table * const me, QEvt const * const e) { } return status_; } -/*$enddef${AOs::Table} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$enddef${AOs::Table} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/examples/freertos/arm-cm/dpp_nucleo-h743zi/FreeRTOSConfig.h b/examples/freertos/arm-cm/dpp_nucleo-h743zi/FreeRTOSConfig.h index 5ee4348b..f0d415c3 100644 --- a/examples/freertos/arm-cm/dpp_nucleo-h743zi/FreeRTOSConfig.h +++ b/examples/freertos/arm-cm/dpp_nucleo-h743zi/FreeRTOSConfig.h @@ -1,46 +1,46 @@ -/* Modified by Quantum Leaps - */ -/* - * FreeRTOS Kernel V10.0.1 - * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * http://www.FreeRTOS.org - * http://aws.amazon.com/freertos - * - * 1 tab == 4 spaces! - */ +// Modified by Quantum Leaps +// +// +// FreeRTOS Kernel V10.0.1 +// Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +// http://www.FreeRTOS.org +// http://aws.amazon.com/freertos +// +// 1 tab == 4 spaces! +// #ifndef FREERTOS_CONFIG_H #define FREERTOS_CONFIG_H -/*----------------------------------------------------------- - * Application specific definitions. - * - * These definitions should be adjusted for your particular hardware and - * application requirements. - * - * THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE - * FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE. - * - * See http://www.freertos.org/a00110.html. - *----------------------------------------------------------*/ +//----------------------------------------------------------- +// Application specific definitions. +// +// These definitions should be adjusted for your particular hardware and +// application requirements. +// +// THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE +// FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE. +// +// See http://www.freertos.org/a00110.html. +// ---------------------------------------------------------- #define configUSE_PREEMPTION 1 #define configUSE_IDLE_HOOK 1 @@ -59,6 +59,7 @@ #define configCHECK_FOR_STACK_OVERFLOW 2 #define configUSE_QUEUE_SETS 0 #define configUSE_COUNTING_SEMAPHORES 1 +#define configUSE_MALLOC_FAILED_HOOK 0 #define configMAX_PRIORITIES ( 32UL ) #define configMAX_CO_ROUTINE_PRIORITIES ( 2 ) @@ -66,14 +67,14 @@ #define configSUPPORT_DYNAMIC_ALLOCATION 0 #define configSUPPORT_STATIC_ALLOCATION 1 -/* Timer related defines. */ +// Timer related defines. #define configUSE_TIMERS 0 #define configTIMER_TASK_PRIORITY 2 #define configTIMER_QUEUE_LENGTH 20 #define configTIMER_TASK_STACK_DEPTH ( configMINIMAL_STACK_SIZE * 2 ) -/* Set the following definitions to 1 to include the API function, or zero -to exclude the API function. */ +// Set the following definitions to 1 to include the API function, or zero +// to exclude the API function. #define INCLUDE_vTaskPrioritySet 1 #define INCLUDE_uxTaskPriorityGet 1 @@ -90,48 +91,45 @@ to exclude the API function. */ #define INCLUDE_eTaskGetState 1 #define INCLUDE_xTimerPendFunctionCall 0 -/* Cortex-M specific definitions. */ +// Cortex-M specific definitions. #ifdef __NVIC_PRIO_BITS - /* __BVIC_PRIO_BITS will be specified when CMSIS is being used. */ + // __BVIC_PRIO_BITS will be specified when CMSIS is being used. #define configPRIO_BITS __NVIC_PRIO_BITS #else - #define configPRIO_BITS 4 /* 15 priority levels */ + #define configPRIO_BITS 4 // 15 priority levels #endif -/* The lowest interrupt priority that can be used in a call to a "set priority" -function. */ +// The lowest interrupt priority that can be used in a call to a "set priority" +// function. #define configLIBRARY_LOWEST_INTERRUPT_PRIORITY 15 -/* The highest interrupt priority that can be used by any interrupt service -routine that makes calls to interrupt safe FreeRTOS API functions. DO NOT CALL -INTERRUPT SAFE FREERTOS API FUNCTIONS FROM ANY INTERRUPT THAT HAS A HIGHER -PRIORITY THAN THIS! (higher priorities are lower numeric values. */ +// The highest interrupt priority that can be used by any interrupt service +// routine that makes calls to interrupt safe FreeRTOS API functions. DO NOT CALL +// INTERRUPT SAFE FREERTOS API FUNCTIONS FROM ANY INTERRUPT THAT HAS A HIGHER +// PRIORITY THAN THIS! (higher priorities are lower numeric values. #define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 4 -/* Interrupt priorities used by the kernel port layer itself. These are generic -to all Cortex-M ports, and do not rely on any particular library functions. */ +// Interrupt priorities used by the kernel port layer itself. These are generic +// to all Cortex-M ports, and do not rely on any particular library functions. #define configKERNEL_INTERRUPT_PRIORITY ( configLIBRARY_LOWEST_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) ) -/* !!!! configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to zero !!!! -See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html. */ +// !!!! configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to zero !!!! +// See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html. #define configMAX_SYSCALL_INTERRUPT_PRIORITY ( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) ) -/* Definitions that map the FreeRTOS port interrupt handlers to their CMSIS -standard names. */ +// Definitions that map the FreeRTOS port interrupt handlers to their CMSIS +// standard names. #define xPortPendSVHandler PendSV_Handler #define vPortSVCHandler SVC_Handler #define xPortSysTickHandler SysTick_Handler -/* Prevent the inclusion of items the assembler will not understand in assembly files. */ +// Prevent the inclusion of items the assembler will not understand in assembly files. #ifndef __IAR_SYSTEMS_ASM__ - /* Library includes. */ - #include "stm32h7xx_hal.h" - extern uint32_t SystemCoreClock; - /* Normal assert() semantics without relying on the provision of an assert.h header file. */ - void assert_failed(char const * const module, int location); + // Normal assert() semantics without relying on the provision of an assert.h header file. + void assert_failed(char const * const module, int const id); #define configASSERT( x ) if( ( x ) == 0 ) assert_failed( __FILE__, __LINE__ ); -#endif /* __IAR_SYSTEMS_ASM__ */ +#endif // __IAR_SYSTEMS_ASM__ -#endif /* FREERTOS_CONFIG_H */ +#endif // FREERTOS_CONFIG_H diff --git a/examples/freertos/arm-cm/dpp_nucleo-h743zi/armclang/dpp.uvoptx b/examples/freertos/arm-cm/dpp_nucleo-h743zi/armclang/dpp.uvoptx index 8c9d80c2..f027aa39 100644 --- a/examples/freertos/arm-cm/dpp_nucleo-h743zi/armclang/dpp.uvoptx +++ b/examples/freertos/arm-cm/dpp_nucleo-h743zi/armclang/dpp.uvoptx @@ -644,7 +644,7 @@ Applicatioin - 0 + 1 0 0 0 @@ -703,7 +703,7 @@ 0 0 0 - ..\..\..\..\..\include\qstamp.c + ..\..\..\..\..\src\qs\qstamp.c qstamp.c 0 0 @@ -955,6 +955,18 @@ 0 0 0 + ..\..\..\..\..\src\qf\qf_act.c + qf_act.c + 0 + 0 + + + 4 + 25 + 1 + 0 + 0 + 0 ..\..\..\..\..\src\qf\qf_defer.c qf_defer.c 0 @@ -962,7 +974,7 @@ 4 - 25 + 26 1 0 0 @@ -974,7 +986,7 @@ 4 - 26 + 27 1 0 0 @@ -986,7 +998,7 @@ 4 - 27 + 28 1 0 0 @@ -998,7 +1010,7 @@ 4 - 28 + 29 1 0 0 @@ -1010,7 +1022,7 @@ 4 - 29 + 30 1 0 0 @@ -1022,7 +1034,7 @@ 4 - 30 + 31 1 0 0 @@ -1034,7 +1046,7 @@ 4 - 31 + 32 1 0 0 @@ -1054,7 +1066,7 @@ 0 5 - 32 + 33 5 0 0 @@ -1066,7 +1078,7 @@ 5 - 33 + 34 1 0 0 @@ -1078,7 +1090,7 @@ 5 - 34 + 35 5 0 0 @@ -1090,7 +1102,7 @@ 5 - 35 + 36 5 0 0 @@ -1104,13 +1116,13 @@ QS - 0 + 1 0 0 0 6 - 36 + 37 1 0 0 @@ -1120,18 +1132,6 @@ 0 0 - - 6 - 37 - 1 - 0 - 0 - 0 - ..\..\..\..\..\src\qs\qs_64bit.c - qs_64bit.c - 0 - 0 - 6 38 @@ -1139,18 +1139,6 @@ 0 0 0 - ..\..\..\..\..\src\qs\qs_fp.c - qs_fp.c - 0 - 0 - - - 6 - 39 - 1 - 0 - 0 - 0 ..\..\..\..\..\src\qs\qs_rx.c qs_rx.c 0 @@ -1164,6 +1152,18 @@ 0 0 0 + + 7 + 39 + 1 + 0 + 0 + 0 + ..\..\..\..\..\3rd_party\FreeRTOS-Kernel\list.c + list.c + 0 + 0 + 7 40 @@ -1171,8 +1171,8 @@ 0 0 0 - ..\..\..\..\..\3rd_party\FreeRTOS\Source\list.c - list.c + ..\..\..\..\..\3rd_party\FreeRTOS-Kernel\queue.c + queue.c 0 0 @@ -1183,19 +1183,7 @@ 0 0 0 - ..\..\..\..\..\3rd_party\FreeRTOS\Source\queue.c - queue.c - 0 - 0 - - - 7 - 42 - 1 - 0 - 0 - 0 - ..\..\..\..\..\3rd_party\FreeRTOS\Source\tasks.c + ..\..\..\..\..\3rd_party\FreeRTOS-Kernel\tasks.c tasks.c 0 0 @@ -1210,24 +1198,24 @@ 0 8 - 43 + 42 1 0 0 0 - ..\..\..\..\..\3rd_party\FreeRTOS\Source\portable\GCC\ARM_CM7\r0p1\port.c + ..\..\..\..\..\3rd_party\FreeRTOS-Kernel\portable\GCC\ARM_CM7\r0p1\port.c port.c 0 0 8 - 44 + 43 5 0 0 0 - ..\..\..\..\..\3rd_party\FreeRTOS\Source\portable\GCC\ARM_CM7\r0p1\portmacro.h + ..\..\..\..\..\3rd_party\FreeRTOS-Kernel\portable\GCC\ARM_CM7\r0p1\portmacro.h portmacro.h 0 0 diff --git a/examples/freertos/arm-cm/dpp_nucleo-h743zi/armclang/dpp.uvprojx b/examples/freertos/arm-cm/dpp_nucleo-h743zi/armclang/dpp.uvprojx index 56af5276..bd378e2a 100644 --- a/examples/freertos/arm-cm/dpp_nucleo-h743zi/armclang/dpp.uvprojx +++ b/examples/freertos/arm-cm/dpp_nucleo-h743zi/armclang/dpp.uvprojx @@ -339,7 +339,7 @@ STM32H743xx,USE_HAL_DRIVER,USE_STM32H7XX_NUCLEO_144 - ..;..\..\..\..\..\include;..\..\..\..\..\ports\freertos;..\..\..\..\..\3rd_party\FreeRTOS\Source\include;..\..\..\..\..\3rd_party\FreeRTOS\Source\portable\GCC\ARM_CM7\r0p1;..\..\..\..\..\3rd_party\CMSIS\Include;..\..\..\..\..\3rd_party\STM32CubeH7\Drivers\CMSIS\Device\ST/STM32H7xx\Include;..\..\..\..\..\3rd_party\STM32CubeH7\Drivers\BSP\STM32H7xx_Nucleo_144;..\..\..\..\..\3rd_party\STM32CubeH7\Drivers\STM32H7xx_HAL_Driver\Inc + ..;..\..\..\..\..\include;..\..\..\..\..\ports\freertos;..\..\..\..\..\3rd_party\FreeRTOS-Kernel\include;..\..\..\..\..\3rd_party\FreeRTOS-Kernel\portable\GCC\ARM_CM7\r0p1;..\..\..\..\..\3rd_party\CMSIS\Include;..\..\..\..\..\3rd_party\STM32CubeH7\Drivers\CMSIS\Device\ST/STM32H7xx\Include;..\..\..\..\..\3rd_party\STM32CubeH7\Drivers\BSP\STM32H7xx_Nucleo_144;..\..\..\..\..\3rd_party\STM32CubeH7\Drivers\STM32H7xx_HAL_Driver\Inc @@ -406,7 +406,7 @@ qstamp.c 8 - ..\..\..\..\..\include\qstamp.c + ..\..\..\..\..\src\qs\qstamp.c bsp.h @@ -513,6 +513,11 @@ 1 ..\..\..\..\..\src\qf\qep_msm.c + + qf_act.c + 1 + ..\..\..\..\..\src\qf\qf_act.c + qf_defer.c 1 @@ -657,16 +662,6 @@ 1 ..\..\..\..\..\src\qs\qs.c - - qs_64bit.c - 1 - ..\..\..\..\..\src\qs\qs_64bit.c - - - qs_fp.c - 1 - ..\..\..\..\..\src\qs\qs_fp.c - qs_rx.c 1 @@ -680,17 +675,17 @@ list.c 1 - ..\..\..\..\..\3rd_party\FreeRTOS\Source\list.c + ..\..\..\..\..\3rd_party\FreeRTOS-Kernel\list.c queue.c 1 - ..\..\..\..\..\3rd_party\FreeRTOS\Source\queue.c + ..\..\..\..\..\3rd_party\FreeRTOS-Kernel\queue.c tasks.c 1 - ..\..\..\..\..\3rd_party\FreeRTOS\Source\tasks.c + ..\..\..\..\..\3rd_party\FreeRTOS-Kernel\tasks.c @@ -700,12 +695,12 @@ port.c 1 - ..\..\..\..\..\3rd_party\FreeRTOS\Source\portable\GCC\ARM_CM7\r0p1\port.c + ..\..\..\..\..\3rd_party\FreeRTOS-Kernel\portable\GCC\ARM_CM7\r0p1\port.c portmacro.h 5 - ..\..\..\..\..\3rd_party\FreeRTOS\Source\portable\GCC\ARM_CM7\r0p1\portmacro.h + ..\..\..\..\..\3rd_party\FreeRTOS-Kernel\portable\GCC\ARM_CM7\r0p1\portmacro.h @@ -1044,7 +1039,7 @@ NDEBUG,STM32H743xx,USE_HAL_DRIVER,USE_STM32H7XX_NUCLEO_144 - ..;..\..\..\..\..\include;..\..\..\..\..\ports\freertos;..\..\..\..\..\3rd_party\FreeRTOS\Source\include;..\..\..\..\..\3rd_party\FreeRTOS\Source\portable\GCC\ARM_CM7\r0p1;..\..\..\..\..\3rd_party\CMSIS\Include;..\..\..\..\..\3rd_party\STM32CubeH7\Drivers\CMSIS\Device\ST/STM32H7xx\Include;..\..\..\..\..\3rd_party\STM32CubeH7\Drivers\BSP\STM32H7xx_Nucleo_144;..\..\..\..\..\3rd_party\STM32CubeH7\Drivers\STM32H7xx_HAL_Driver\Inc + ..;..\..\..\..\..\include;..\..\..\..\..\ports\freertos;..\..\..\..\..\3rd_party\FreeRTOS-Kernel\include;..\..\..\..\..\3rd_party\FreeRTOS-Kernel\portable\GCC\ARM_CM7\r0p1;..\..\..\..\..\3rd_party\CMSIS\Include;..\..\..\..\..\3rd_party\STM32CubeH7\Drivers\CMSIS\Device\ST/STM32H7xx\Include;..\..\..\..\..\3rd_party\STM32CubeH7\Drivers\BSP\STM32H7xx_Nucleo_144;..\..\..\..\..\3rd_party\STM32CubeH7\Drivers\STM32H7xx_HAL_Driver\Inc @@ -1111,7 +1106,7 @@ qstamp.c 8 - ..\..\..\..\..\include\qstamp.c + ..\..\..\..\..\src\qs\qstamp.c bsp.h @@ -1218,6 +1213,11 @@ 1 ..\..\..\..\..\src\qf\qep_msm.c + + qf_act.c + 1 + ..\..\..\..\..\src\qf\qf_act.c + qf_defer.c 1 @@ -1362,16 +1362,6 @@ 1 ..\..\..\..\..\src\qs\qs.c - - qs_64bit.c - 1 - ..\..\..\..\..\src\qs\qs_64bit.c - - - qs_fp.c - 1 - ..\..\..\..\..\src\qs\qs_fp.c - qs_rx.c 1 @@ -1385,17 +1375,17 @@ list.c 1 - ..\..\..\..\..\3rd_party\FreeRTOS\Source\list.c + ..\..\..\..\..\3rd_party\FreeRTOS-Kernel\list.c queue.c 1 - ..\..\..\..\..\3rd_party\FreeRTOS\Source\queue.c + ..\..\..\..\..\3rd_party\FreeRTOS-Kernel\queue.c tasks.c 1 - ..\..\..\..\..\3rd_party\FreeRTOS\Source\tasks.c + ..\..\..\..\..\3rd_party\FreeRTOS-Kernel\tasks.c @@ -1405,12 +1395,12 @@ port.c 1 - ..\..\..\..\..\3rd_party\FreeRTOS\Source\portable\GCC\ARM_CM7\r0p1\port.c + ..\..\..\..\..\3rd_party\FreeRTOS-Kernel\portable\GCC\ARM_CM7\r0p1\port.c portmacro.h 5 - ..\..\..\..\..\3rd_party\FreeRTOS\Source\portable\GCC\ARM_CM7\r0p1\portmacro.h + ..\..\..\..\..\3rd_party\FreeRTOS-Kernel\portable\GCC\ARM_CM7\r0p1\portmacro.h @@ -1747,9 +1737,9 @@ 0 -Wno-padded - Q_SPY,QF_ON_CONTEXT_SW,STM32H743xx,USE_HAL_DRIVER,USE_STM32H7XX_NUCLEO_144 + Q_SPY,STM32H743xx,USE_HAL_DRIVER,USE_STM32H7XX_NUCLEO_144 - ..;..\..\..\..\..\include;..\..\..\..\..\ports\freertos;..\..\..\..\..\3rd_party\FreeRTOS\Source\include;..\..\..\..\..\3rd_party\FreeRTOS\Source\portable\GCC\ARM_CM7\r0p1;..\..\..\..\..\3rd_party\CMSIS\Include;..\..\..\..\..\3rd_party\STM32CubeH7\Drivers\CMSIS\Device\ST/STM32H7xx\Include;..\..\..\..\..\3rd_party\STM32CubeH7\Drivers\BSP\STM32H7xx_Nucleo_144;..\..\..\..\..\3rd_party\STM32CubeH7\Drivers\STM32H7xx_HAL_Driver\Inc + ..;..\..\..\..\..\include;..\..\..\..\..\ports\freertos;..\..\..\..\..\3rd_party\FreeRTOS-Kernel\include;..\..\..\..\..\3rd_party\FreeRTOS-Kernel\portable\GCC\ARM_CM7\r0p1;..\..\..\..\..\3rd_party\CMSIS\Include;..\..\..\..\..\3rd_party\STM32CubeH7\Drivers\CMSIS\Device\ST/STM32H7xx\Include;..\..\..\..\..\3rd_party\STM32CubeH7\Drivers\BSP\STM32H7xx_Nucleo_144;..\..\..\..\..\3rd_party\STM32CubeH7\Drivers\STM32H7xx_HAL_Driver\Inc @@ -1816,7 +1806,7 @@ qstamp.c 8 - ..\..\..\..\..\include\qstamp.c + ..\..\..\..\..\src\qs\qstamp.c bsp.h @@ -1923,6 +1913,11 @@ 1 ..\..\..\..\..\src\qf\qep_msm.c + + qf_act.c + 1 + ..\..\..\..\..\src\qf\qf_act.c + qf_defer.c 1 @@ -2067,20 +2062,61 @@ 1 ..\..\..\..\..\src\qs\qs.c - - qs_64bit.c - 1 - ..\..\..\..\..\src\qs\qs_64bit.c - - - qs_fp.c - 1 - ..\..\..\..\..\src\qs\qs_fp.c - qs_rx.c 1 ..\..\..\..\..\src\qs\qs_rx.c + + + 2 + 0 + 0 + 0 + 0 + 2 + 2 + 2 + 2 + 2 + 11 + + + 1 + + + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 2 + 2 + 2 + 2 + 2 + + -Wno-cast-align + + + + + + + @@ -2090,17 +2126,17 @@ list.c 1 - ..\..\..\..\..\3rd_party\FreeRTOS\Source\list.c + ..\..\..\..\..\3rd_party\FreeRTOS-Kernel\list.c queue.c 1 - ..\..\..\..\..\3rd_party\FreeRTOS\Source\queue.c + ..\..\..\..\..\3rd_party\FreeRTOS-Kernel\queue.c tasks.c 1 - ..\..\..\..\..\3rd_party\FreeRTOS\Source\tasks.c + ..\..\..\..\..\3rd_party\FreeRTOS-Kernel\tasks.c @@ -2110,12 +2146,12 @@ port.c 1 - ..\..\..\..\..\3rd_party\FreeRTOS\Source\portable\GCC\ARM_CM7\r0p1\port.c + ..\..\..\..\..\3rd_party\FreeRTOS-Kernel\portable\GCC\ARM_CM7\r0p1\port.c portmacro.h 5 - ..\..\..\..\..\3rd_party\FreeRTOS\Source\portable\GCC\ARM_CM7\r0p1\portmacro.h + ..\..\..\..\..\3rd_party\FreeRTOS-Kernel\portable\GCC\ARM_CM7\r0p1\portmacro.h diff --git a/examples/freertos/arm-cm/dpp_nucleo-h743zi/bsp.c b/examples/freertos/arm-cm/dpp_nucleo-h743zi/bsp.c index d2d53fb6..e81350b6 100644 --- a/examples/freertos/arm-cm/dpp_nucleo-h743zi/bsp.c +++ b/examples/freertos/arm-cm/dpp_nucleo-h743zi/bsp.c @@ -1,288 +1,361 @@ -/***************************************************************************** -* Product: DPP example, NUCLEO-H743ZI board, FreeRTOS kernel -* Last updated for: @ref qpc_7_0_0 -* Last updated on 2022-02-28 -* -* Q u a n t u m L e a P s -* ------------------------ -* Modern Embedded Software -* -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* -* -*****************************************************************************/ -#include "qpc.h" -#include "dpp.h" -#include "bsp.h" +//============================================================================ +// Product: DPP example, NUCLEO-H743ZI board, FreeRTOS kernel +// Last updated for version 7.3.0 +// Last updated on 2023-08-29 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +//============================================================================ +#include "qpc.h" // QP/C real-time embedded framework +#include "dpp.h" // DPP Application interface +#include "bsp.h" // Board Support Package -/* STM32CubeH7 include files */ +// STM32CubeH7 include files //#include "stm32h7xx_it.h" #include "stm32h7xx_hal.h" #include "stm32h7xx_nucleo_144.h" -/* add other drivers if necessary... */ +// add other drivers if necessary... -Q_DEFINE_THIS_FILE /* define the name of this file for assertions */ +Q_DEFINE_THIS_FILE // define the name of this file for assertions -/* "RTOS-aware" interrupt priorities for FreeRTOS on ARM Cortex-M, NOTE1 */ +// "RTOS-aware" interrupt priorities for FreeRTOS on ARM Cortex-M, NOTE1 #define RTOS_AWARE_ISR_CMSIS_PRI \ (configMAX_SYSCALL_INTERRUPT_PRIORITY >> (8-__NVIC_PRIO_BITS)) -/* Local-scope objects -----------------------------------------------------*/ -static uint32_t l_rnd; /* random seed */ +// Local-scope objects ----------------------------------------------------- +static uint32_t l_rndSeed; #ifdef Q_SPY + // QS identifiers for non-QP sources of events + static uint8_t const l_TickHook = 0U; + static uint8_t const l_EXTI0_IRQHandler = 0U; + static UART_HandleTypeDef l_uartHandle; + QSTimeCtr QS_tickTime_; QSTimeCtr QS_tickPeriod_; - /* QS identifiers for non-QP sources of events */ - static uint8_t const l_TickHook = 0U; - static UART_HandleTypeDef l_uartHandle; - static uint8_t const l_EXTI0_IRQHandler = 0U; - - enum AppRecords { /* application-specific trace records */ + enum AppRecords { // application-specific trace records PHILO_STAT = QS_USER, PAUSED_STAT, - COMMAND_STAT }; #endif -/* ISRs used in this project ===============================================*/ -/* NOTE: only the "FromISR" API variants are allowed in the ISRs! */ +//============================================================================ +// Error handler + +Q_NORETURN Q_onError(char const * const module, int_t const id) { + // NOTE: this implementation of the error handler is intended only + // for debugging and MUST be changed for deployment of the application + // (assuming that you ship your production code with assertions enabled). + Q_UNUSED_PAR(module); + Q_UNUSED_PAR(id); + QS_ASSERTION(module, id, 10000U); // report assertion to QS + +#ifndef NDEBUG + // light up LED + BSP_LED_On(LED1); + // for debugging, hang on in an endless loop... + for (;;) { + } +#else + NVIC_SystemReset(); + for (;;) { // explicitly "no-return" + } +#endif +} +//............................................................................ +void assert_failed(char const * const module, int_t const id); // prototype +void assert_failed(char const * const module, int_t const id) { + Q_onError(module, id); +} + +// ISRs used in the application ============================================== +// NOTE: only the "FromISR" API variants are allowed in the ISRs! void EXTI0_IRQHandler(void); // prototype void EXTI0_IRQHandler(void) { BaseType_t xHigherPriorityTaskWoken = pdFALSE; - /* for testing... */ + // for testing... QACTIVE_POST_FROM_ISR(AO_Table, Q_NEW_FROM_ISR(QEvt, MAX_PUB_SIG), &xHigherPriorityTaskWoken, &l_EXTI0_IRQHandler); - /* the usual end of FreeRTOS ISR... */ + // the usual end of FreeRTOS ISR... portEND_SWITCHING_ISR(xHigherPriorityTaskWoken); } -/*..........................................................................*/ +//............................................................................ #ifdef Q_SPY -/* -* ISR for receiving bytes from the QSPY Back-End -* NOTE: This ISR is "kernel-unaware" meaning that it does not interact with -* the FreeRTOS or QP and is not disabled. Such ISRs don't need to call -* portEND_SWITCHING_ISR(() at the end, but they also cannot call any -* FreeRTOS or QP APIs. -*/ -void USART3_IRQHandler(void); /* prototype */ + +// ISR for receiving bytes from the QSPY Back-End +// NOTE: This ISR is "kernel-unaware" meaning that it does not interact with +// the FreeRTOS or QP and is not disabled. Such ISRs don't need to call +// portEND_SWITCHING_ISR(() at the end, but they also cannot call any +// FreeRTOS or QP APIs. +void USART3_IRQHandler(void); // prototype void USART3_IRQHandler(void) { - /* is RX register NOT empty? */ + // is RX register NOT empty? if ((l_uartHandle.Instance->ISR & USART_ISR_RXNE_RXFNE) != 0) { uint32_t b = l_uartHandle.Instance->RDR; QS_RX_PUT(b); - l_uartHandle.Instance->ISR &= ~USART_ISR_RXNE_RXFNE; /* clear int. */ + l_uartHandle.Instance->ISR &= ~USART_ISR_RXNE_RXFNE; // clear int. } } #endif -/* Application hooks used in this project ==================================*/ -/* NOTE: only the "FromISR" API variants are allowed in vApplicationTickHook */ +// Application hooks used in this project ==================================== +// NOTE: only the "FromISR" API variants are allowed in vApplicationTickHook + void vApplicationTickHook(void) { - /* state of the button debouncing, see below */ - static struct ButtonsDebouncing { + BaseType_t xHigherPriorityTaskWoken = pdFALSE; + + // process time events at rate 0 + QTIMEEVT_TICK_FROM_ISR(0U, &xHigherPriorityTaskWoken, &l_TickHook); + + // Perform the debouncing of buttons. The algorithm for debouncing + // adapted from the book "Embedded Systems Dictionary" by Jack Ganssle + // and Michael Barr, page 71. + static struct { uint32_t depressed; uint32_t previous; } buttons = { 0U, 0U }; - uint32_t current; - uint32_t tmp; - BaseType_t xHigherPriorityTaskWoken = pdFALSE; - /* process time events for rate 0 */ - QTIMEEVT_TICK_FROM_ISR(0U, &xHigherPriorityTaskWoken, &l_TickHook); + uint32_t current = BSP_PB_GetState(BUTTON_KEY); // read the Key button + uint32_t tmp = buttons.depressed; // save debounced depressed buttons + buttons.depressed |= (buttons.previous & current); // set depressed + buttons.depressed &= (buttons.previous | current); // clear released + buttons.previous = current; // update the history + tmp ^= buttons.depressed; // changed debounced depressed + current = buttons.depressed; -#ifdef Q_SPY - { - tmp = SysTick->CTRL; /* clear SysTick_CTRL_COUNTFLAG */ - QS_tickTime_ += QS_tickPeriod_; /* account for the clock rollover */ - } -#endif - - /* Perform the debouncing of buttons. The algorithm for debouncing - * adapted from the book "Embedded Systems Dictionary" by Jack Ganssle - * and Michael Barr, page 71. - */ - current = BSP_PB_GetState(BUTTON_KEY); /* read the Key button */ - tmp = buttons.depressed; /* save the debounced depressed buttons */ - buttons.depressed |= (buttons.previous & current); /* set depressed */ - buttons.depressed &= (buttons.previous | current); /* clear released */ - buttons.previous = current; /* update the history */ - tmp ^= buttons.depressed; /* changed debounced depressed */ - if (tmp != 0U) { /* debounced Key button state changed? */ - if (buttons.depressed != 0U) { /* PB0 depressed?*/ - /* demonstrate the "FromISR APIs: - * QACTIVE_PUBLISH_FROM_ISR() and Q_NEW_FROM_ISR() - */ - QACTIVE_PUBLISH_FROM_ISR(Q_NEW_FROM_ISR(QEvt, PAUSE_SIG), + if (tmp != 0U) { // debounced Key button state changed? + if (current != 0U) { // is PB0 depressed? + static QEvt const pauseEvt = QEVT_INITIALIZER(PAUSE_SIG); + QACTIVE_PUBLISH_FROM_ISR(&pauseEvt, &xHigherPriorityTaskWoken, &l_TickHook); } - else { /* the button is released */ - /* demonstrate the ISR APIs: POST_FROM_ISR and Q_NEW_FROM_ISR */ - QACTIVE_POST_FROM_ISR(AO_Table, - Q_NEW_FROM_ISR(QEvt, SERVE_SIG), - &xHigherPriorityTaskWoken, - &l_TickHook); + else { // the button is released + static QEvt const serveEvt = QEVT_INITIALIZER(SERVE_SIG); + QACTIVE_PUBLISH_FROM_ISR(&serveEvt, + &xHigherPriorityTaskWoken, + &l_TickHook); } } - /* notify FreeRTOS to perform context switch from ISR, if needed */ +#ifdef Q_SPY + tmp = SysTick->CTRL; // clear SysTick_CTRL_COUNTFLAG + QS_tickTime_ += QS_tickPeriod_; // account for the clock rollover +#endif + + // notify FreeRTOS to perform context switch from ISR, if needed portEND_SWITCHING_ISR(xHigherPriorityTaskWoken); } -/*..........................................................................*/ +//............................................................................ void vApplicationIdleHook(void) { - double volatile x; - - /* toggle the User LED on and then off, see NOTE01 */ + // toggle the User LED on and then off, see NOTE01 QF_INT_DISABLE(); BSP_LED_On (LED3); BSP_LED_Off(LED3); QF_INT_ENABLE(); - /* Some flating point code is to exercise the VFP... */ - x = 1.73205F; - x = x * 1.73205F; + // Some floating point code is to exercise the VFP... + double volatile x = 1.73205; + x = x * 1.73205; #ifdef Q_SPY - QS_rxParse(); /* parse all the received bytes */ + QS_rxParse(); // parse all the received bytes - if ((l_uartHandle.Instance->ISR & UART_FLAG_TXE) != 0U) { /* TXE empty? */ - uint16_t b; + if ((l_uartHandle.Instance->ISR & UART_FLAG_TXE) != 0U) { // TXE empty? + QF_INT_DISABLE(); + uint16_t b = QS_getByte(); + QF_INT_ENABLE(); - b = QS_getByte(); - - if (b != QS_EOD) { /* not End-Of-Data? */ - l_uartHandle.Instance->TDR = (b & 0xFFU); /* put into TDR */ + if (b != QS_EOD) { // not End-Of-Data? + l_uartHandle.Instance->TDR = (b & 0xFFU); // put into TDR } } #elif defined NDEBUG - /* Put the CPU and peripherals to the low-power mode. - * you might need to customize the clock management for your application, - * see the datasheet for your particular Cortex-M MCU. - */ - /* !!!CAUTION!!! - * The WFI instruction stops the CPU clock, which unfortunately disables - * the JTAG port, so the ST-Link debugger can no longer connect to the - * board. For that reason, the call to __WFI() has to be used with CAUTION. - * - * NOTE: If you find your board "frozen" like this, strap BOOT0 to VDD and - * reset the board, then connect with ST-Link Utilities and erase the part. - * The trick with BOOT(0) is it gets the part to run the System Loader - * instead of your broken code. When done disconnect BOOT0, and start over. - */ - //__WFI(); /* Wait-For-Interrupt */ + // Put the CPU and peripherals to the low-power mode. + // you might need to customize the clock management for your application, + // see the datasheet for your particular Cortex-M MCU. + // + // !!!CAUTION!!! + // The WFI instruction stops the CPU clock, which unfortunately disables + // the JTAG port, so the ST-Link debugger can no longer connect to the + // board. For that reason, the call to __WFI() has to be used with CAUTION. + // + // NOTE: If you find your board "frozen" like this, strap BOOT0 to VDD and + // reset the board, then connect with ST-Link Utilities and erase the part. + // The trick with BOOT(0) is it gets the part to run the System Loader + // instead of your broken code. When done disconnect BOOT0, and start over. + // + //__WFI(); // Wait-For-Interrupt #endif } -/*..........................................................................*/ +//............................................................................ void vApplicationStackOverflowHook(TaskHandle_t xTask, char *pcTaskName) { (void)xTask; (void)pcTaskName; Q_ERROR(); } -/*..........................................................................*/ -/* configSUPPORT_STATIC_ALLOCATION is set to 1, so the application must -* provide an implementation of vApplicationGetIdleTaskMemory() to provide -* the memory that is used by the Idle task. -*/ +//............................................................................ +// configSUPPORT_STATIC_ALLOCATION is set to 1, so the application must +// provide an implementation of vApplicationGetIdleTaskMemory() to provide +// the memory that is used by the Idle task. void vApplicationGetIdleTaskMemory( StaticTask_t **ppxIdleTaskTCBBuffer, StackType_t **ppxIdleTaskStackBuffer, uint32_t *pulIdleTaskStackSize ) { - /* If the buffers to be provided to the Idle task are declared inside - * this function then they must be declared static - otherwise they will - * be allocated on the stack and so not exists after this function exits. - */ + // If the buffers to be provided to the Idle task are declared inside + // this function then they must be declared static - otherwise they will + // be allocated on the stack and so not exists after this function exits. + // static StaticTask_t xIdleTaskTCB; static StackType_t uxIdleTaskStack[ configMINIMAL_STACK_SIZE ]; - /* Pass out a pointer to the StaticTask_t structure in which the - * Idle task's state will be stored. - */ + // Pass out a pointer to the StaticTask_t structure in which the + // Idle task's state will be stored. *ppxIdleTaskTCBBuffer = &xIdleTaskTCB; - /* Pass out the array that will be used as the Idle task's stack. */ + // Pass out the array that will be used as the Idle task's stack. *ppxIdleTaskStackBuffer = uxIdleTaskStack; - /* Pass out the size of the array pointed to by *ppxIdleTaskStackBuffer. - * Note that, as the array is necessarily of type StackType_t, - * configMINIMAL_STACK_SIZE is specified in words, not bytes. - */ + // Pass out the size of the array pointed to by *ppxIdleTaskStackBuffer. + // Note that, as the array is necessarily of type StackType_t, + // configMINIMAL_STACK_SIZE is specified in words, not bytes. + // *pulIdleTaskStackSize = Q_DIM(uxIdleTaskStack); } -/* BSP functions ===========================================================*/ +// BSP functions ============================================================= + +//............................................................................ void BSP_init(void) { - /* NOTE: SystemInit() has been already called from the startup code - * but SystemCoreClock needs to be updated - */ + // Configure the MPU to prevent NULL-pointer dereferencing ... + MPU->RBAR = 0x0U // base address (NULL) + | MPU_RBAR_VALID_Msk // valid region + | (MPU_RBAR_REGION_Msk & 7U); // region #7 + MPU->RASR = (7U << MPU_RASR_SIZE_Pos) // 2^(7+1) region + | (0x0U << MPU_RASR_AP_Pos) // no-access region + | MPU_RASR_ENABLE_Msk; // region enable + MPU->CTRL = MPU_CTRL_PRIVDEFENA_Msk // enable background region + | MPU_CTRL_ENABLE_Msk; // enable the MPU + __ISB(); + __DSB(); + + // enable the MemManage_Handler for MPU exception + SCB->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk; + + // NOTE: SystemInit() has been already called from the startup code + // but SystemCoreClock needs to be updated SystemCoreClockUpdate(); - /* NOTE: The VFP (hardware Floating Point) unit is configured by FreeRTOS */ + // NOTE: VFP (hardware Floating Point) unit is configured by FreeRTOS - SCB_EnableICache(); /* Enable I-Cache */ - SCB_EnableDCache(); /* Enable D-Cache */ + // enable clock for to the peripherals used by this application... + SCB_EnableICache(); // Enable I-Cache + SCB_EnableDCache(); // Enable D-Cache - /* Configure Flash prefetch and Instr. cache through ART accelerator */ + // configure Flash prefetch and Instr. cache through ART accelerator #if (ART_ACCLERATOR_ENABLE != 0) __HAL_FLASH_ART_ENABLE(); -#endif /* ART_ACCLERATOR_ENABLE */ +#endif // ART_ACCLERATOR_ENABLE - /* Configure the LEDs */ + // Configure the LEDs BSP_LED_Init(LED1); BSP_LED_Init(LED2); BSP_LED_Init(LED3); - /* Configure the User Button in GPIO Mode */ + // configure the User Button in GPIO Mode BSP_PB_Init(BUTTON_KEY, BUTTON_MODE_GPIO); - //... BSP_randomSeed(1234U); - /* initialize the QS software tracing... */ - if (QS_INIT((void *)0) == 0) { + // initialize the QS software tracing... + if (!QS_INIT((void *)0)) { Q_ERROR(); } + + // dictionaries... QS_OBJ_DICTIONARY(&l_TickHook); QS_OBJ_DICTIONARY(&l_EXTI0_IRQHandler); QS_USR_DICTIONARY(PHILO_STAT); QS_USR_DICTIONARY(PAUSED_STAT); - QS_USR_DICTIONARY(COMMAND_STAT); - /* setup the QS filters... */ - QS_GLB_FILTER(QS_SM_RECORDS); /* state machine records */ - QS_GLB_FILTER(QS_AO_RECORDS); /* active object records */ - QS_GLB_FILTER(QS_UA_RECORDS); /* all user records */ + QS_ONLY(produce_sig_dict()); + + // setup the QS filters... + QS_GLB_FILTER(QS_ALL_RECORDS); // all records + QS_GLB_FILTER(-QS_QF_TICK); // exclude the clock tick } -/*..........................................................................*/ +//............................................................................ +void BSP_start(void) { + // initialize event pools + static QF_MPOOL_EL(TableEvt) smlPoolSto[2*N_PHILO]; // small pool + QF_poolInit(smlPoolSto, sizeof(smlPoolSto), sizeof(smlPoolSto[0])); + + // initialize publish-subscribe + static QSubscrList subscrSto[MAX_PUB_SIG]; + QActive_psInit(subscrSto, Q_DIM(subscrSto)); + + // start the active objects/threads... + static QEvt const *philoQueueSto[N_PHILO][N_PHILO]; + static StackType_t philoStack[N_PHILO][configMINIMAL_STACK_SIZE]; + for (uint8_t n = 0U; n < N_PHILO; ++n) { + Philo_ctor(n); // instantiate all Philosopher active objects + QActive_setAttr(AO_Philo[n], TASK_NAME_ATTR, "Philo"); + QACTIVE_START(AO_Philo[n], // AO to start + n + 3U, // QP prio. of the AO + philoQueueSto[n], // event queue storage + Q_DIM(philoQueueSto[n]), // queue length [events] + philoStack[n], // stack storage + sizeof(philoStack[n]), // stack size [bytes] + (QEvt *)0); // initialization event (not used) + } + + static QEvt const *tableQueueSto[N_PHILO]; + static StackType_t tableStack[configMINIMAL_STACK_SIZE]; + Table_ctor(); // instantiate the Table active object + QActive_setAttr(AO_Table, TASK_NAME_ATTR, "Table"); + QACTIVE_START(AO_Table, // AO to start + N_PHILO + 7U, // QP prio. of the AO + tableQueueSto, // event queue storage + Q_DIM(tableQueueSto), // queue length [events] + tableStack, // stack storage + sizeof(tableStack), // stack size [bytes] + (QEvt *)0); // initialization event (not used) +} +//............................................................................ void BSP_displayPhilStat(uint8_t n, char const *stat) { + Q_UNUSED_PAR(n); + if (stat[0] == 'e') { BSP_LED_On(LED1); } @@ -290,104 +363,97 @@ void BSP_displayPhilStat(uint8_t n, char const *stat) { BSP_LED_Off(LED1); } - QS_BEGIN_ID(PHILO_STAT, AO_Philo[n]->prio) /* app-specific record */ - QS_U8(1, n); /* Philosopher number */ - QS_STR(stat); /* Philosopher status */ - QS_END() /* application-specific record end */ + // app-specific trace record... + QS_BEGIN_ID(PHILO_STAT, AO_Table->prio) + QS_U8(1, n); // Philosopher number + QS_STR(stat); // Philosopher status + QS_END() } -/*..........................................................................*/ -void BSP_displayPaused(uint8_t paused) { +//............................................................................ +void BSP_displayPaused(uint8_t const paused) { if (paused != 0U) { BSP_LED_On(LED2); } else { BSP_LED_Off(LED2); } + + // application-specific trace record + QS_BEGIN_ID(PAUSED_STAT, AO_Table->prio) + QS_U8(1, paused); // Paused status + QS_END() } -/*..........................................................................*/ -uint32_t BSP_random(void) { /* a very cheap pseudo-random-number generator */ - uint32_t rnd; +//............................................................................ +void BSP_randomSeed(uint32_t const seed) { + l_rndSeed = seed; +} +//............................................................................ +uint32_t BSP_random(void) { // a very cheap pseudo-random-number generator + // Some floating point code is to exercise the VFP... + double volatile x = 3.1415926; + x = x + 2.7182818; - /* Some flating point code is to exercise the VFP... */ - float volatile x = 3.1415926F; - x = x + 2.7182818F; - - vTaskSuspendAll(); /* lock FreeRTOS scheduler */ - /* "Super-Duper" Linear Congruential Generator (LCG) - * LCG(2^32, 3*7*11*13*23, 0, seed) - */ - rnd = l_rnd * (3U*7U*11U*13U*23U); - l_rnd = rnd; /* set for the next time */ - xTaskResumeAll(); /* unlock the FreeRTOS scheduler */ + vTaskSuspendAll(); // lock FreeRTOS scheduler + // "Super-Duper" Linear Congruential Generator (LCG) + // LCG(2^32, 3*7*11*13*23, 0, seed) + // + uint32_t rnd = l_rndSeed * (3U*7U*11U*13U*23U); + l_rndSeed = rnd; // set for the next time + xTaskResumeAll(); // unlock the FreeRTOS scheduler return (rnd >> 8); } -/*..........................................................................*/ -void BSP_randomSeed(uint32_t seed) { - l_rnd = seed; +//............................................................................ +void BSP_ledOn(void) { + BSP_LED_On(LED3); } -/*..........................................................................*/ +//............................................................................ +void BSP_ledOff(void) { + BSP_LED_Off(LED3); +} +//............................................................................ void BSP_terminate(int16_t result) { - (void)result; + Q_UNUSED_PAR(result); } -/* QF callbacks ============================================================*/ +//============================================================================ + +// QF callbacks -------------------------------------------------------------- + void QF_onStartup(void) { - /* set up the SysTick timer to fire at BSP_TICKS_PER_SEC rate */ + // set up the SysTick timer to fire at BSP_TICKS_PER_SEC rate //SysTick_Config(SystemCoreClock / BSP_TICKS_PER_SEC); // done in FreeRTOS - /* assing all priority bits for preemption-prio. and none to sub-prio. */ + // assign all priority bits for preemption-prio. and none to sub-prio. NVIC_SetPriorityGrouping(0U); - /* set priorities of ALL ISRs used in the system, see NOTE1 - * - * !!!!!!!!!!!!!!!!!!!!!!!!!!!! CAUTION !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - * Assign a priority to EVERY ISR explicitly by calling NVIC_SetPriority(). - * DO NOT LEAVE THE ISR PRIORITIES AT THE DEFAULT VALUE! - */ - NVIC_SetPriority(USART3_IRQn, 0U); /* kernel unaware interrupt */ - NVIC_SetPriority(EXTI0_IRQn, RTOS_AWARE_ISR_CMSIS_PRI); - NVIC_SetPriority(SysTick_IRQn, RTOS_AWARE_ISR_CMSIS_PRI + 1U); - /* ... */ + // set priorities of ALL ISRs used in the system, see NOTE1 + NVIC_SetPriority(USART3_IRQn, 0U); // kernel unaware interrupt + NVIC_SetPriority(EXTI0_IRQn, RTOS_AWARE_ISR_CMSIS_PRI + 0U); + NVIC_SetPriority(SysTick_IRQn, RTOS_AWARE_ISR_CMSIS_PRI + 1U); + // ... - /* enable IRQs... */ + // enable IRQs... NVIC_EnableIRQ(EXTI0_IRQn); + #ifdef Q_SPY - NVIC_EnableIRQ(USART3_IRQn); /* UART interrupt used for QS-RX */ + NVIC_EnableIRQ(USART3_IRQn); // UART3 interrupt used for QS-RX #endif } -/*..........................................................................*/ +//............................................................................ void QF_onCleanup(void) { } -/*..........................................................................*/ -Q_NORETURN Q_onAssert(char const * const module, int_t const loc) { - /* - * NOTE: add here your application-specific error handling - */ - (void)module; - (void)loc; - QS_ASSERTION(module, loc, 10000U); /* report assertion to QS */ - -#ifndef NDEBUG - /* light up LED */ - BSP_LED_On(LED1); - /* for debugging, hang on in an endless loop... */ - for (;;) { - } -#endif - - NVIC_SystemReset(); -} - -/* QS callbacks ============================================================*/ +// QS callbacks -------------------------------------------------------------- #ifdef Q_SPY -/*..........................................................................*/ +//............................................................................ uint8_t QS_onStartup(void const *arg) { - static uint8_t qsTxBuf[2*1024]; /* buffer for QS-TX channel */ - static uint8_t qsRxBuf[100]; /* buffer for QS-RX channel */ + Q_UNUSED_PAR(arg); - QS_initBuf (qsTxBuf, sizeof(qsTxBuf)); + static uint8_t qsTxBuf[2*1024]; // buffer for QS-TX channel + QS_initBuf(qsTxBuf, sizeof(qsTxBuf)); + + static uint8_t qsRxBuf[100]; // buffer for QS-RX channel QS_rxInitBuf(qsRxBuf, sizeof(qsRxBuf)); l_uartHandle.Instance = USART3; @@ -399,103 +465,102 @@ uint8_t QS_onStartup(void const *arg) { l_uartHandle.Init.Mode = UART_MODE_TX_RX; l_uartHandle.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT; if (HAL_UART_Init(&l_uartHandle) != HAL_OK) { - return 0U; /* return failure */ + return 0U; // return failure } - /* Set UART to receive 1 byte at a time via interrupt */ + // Set UART to receive 1 byte at a time via interrupt HAL_UART_Receive_IT(&l_uartHandle, (uint8_t *)qsRxBuf, 1); - /* NOTE: wait till QF::onStartup() to enable UART interrupt in NVIC */ + // NOTE: wait till QF::onStartup() to enable UART interrupt in NVIC QS_tickPeriod_ = SystemCoreClock / BSP_TICKS_PER_SEC; - QS_tickTime_ = QS_tickPeriod_; /* to start the timestamp at zero */ + QS_tickTime_ = QS_tickPeriod_; // to start the timestamp at zero - return 1U; /* return success */ + return 1U; // return success } -/*..........................................................................*/ +//............................................................................ void QS_onCleanup(void) { } -/*..........................................................................*/ -QSTimeCtr QS_onGetTime(void) { /* NOTE: invoked with interrupts DISABLED */ - if ((SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk) == 0) { /* not set? */ +//............................................................................ +QSTimeCtr QS_onGetTime(void) { // NOTE: invoked with interrupts DISABLED + if ((SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk) == 0) { // not set? return QS_tickTime_ - (QSTimeCtr)SysTick->VAL; } - else { /* the rollover occured, but the SysTick_ISR did not run yet */ + else { // the rollover occured, but the SysTick_ISR did not run yet return QS_tickTime_ + QS_tickPeriod_ - (QSTimeCtr)SysTick->VAL; } } -/*..........................................................................*/ +//............................................................................ void QS_onFlush(void) { - uint16_t b; + for (;;) { + QF_INT_DISABLE(); + uint16_t b = QS_getByte(); + QF_INT_ENABLE(); - while ((b = QS_getByte()) != QS_EOD) { /* while not End-Of-Data... */ - /* while TXE not empty */ - while ((l_uartHandle.Instance->ISR & UART_FLAG_TXE) == 0U) { + if (b != QS_EOD) { // NOT end-of-data + // busy-wait as long as TX FIFO has data to transmit + while ((l_uartHandle.Instance->ISR & UART_FLAG_TXE) == 0U) { + QF_INT_ENABLE(); + QF_CRIT_EXIT_NOP(); + + QF_INT_DISABLE(); + } + // place the byte in the UART TDR register + l_uartHandle.Instance->TDR = b; + QF_INT_ENABLE(); + } + else { + QF_INT_ENABLE(); + break; // break out of the loop } - l_uartHandle.Instance->TDR = (b & 0xFFU); /* put into TDR */ } } -/*..........................................................................*/ -/*! callback function to reset the target (to be implemented in the BSP) */ +//............................................................................ +//! callback function to reset the target (to be implemented in the BSP) void QS_onReset(void) { NVIC_SystemReset(); } -/*..........................................................................*/ -/*! callback function to execute a user command (to be implemented in BSP) */ +//............................................................................ +//! callback function to execute a user command (to be implemented in BSP) void QS_onCommand(uint8_t cmdId, uint32_t param1, uint32_t param2, uint32_t param3) { - (void)cmdId; - (void)param1; - (void)param2; - (void)param3; - - QS_BEGIN_ID(COMMAND_STAT, 0U)/* app-specific record */ - QS_U8(2, cmdId); - QS_U32(8, param1); - QS_U32(8, param2); - QS_U32(8, param3); - QS_END() - - if (cmdId == 10U) { - Q_ERROR(); /* for testing of assertion failure */ - } - else if (cmdId == 11U) { - assert_failed("QS_onCommand", 123); - } + Q_UNUSED_PAR(cmdId); + Q_UNUSED_PAR(param1); + Q_UNUSED_PAR(param2); + Q_UNUSED_PAR(param3); } -#endif /* Q_SPY */ -/*--------------------------------------------------------------------------*/ +#endif // Q_SPY +//---------------------------------------------------------------------------- -/***************************************************************************** -* NOTE1: -* The configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY constant from the -* FreeRTOS configuration file specifies the highest ISR priority that -* is disabled by the QF framework. The value is suitable for the -* NVIC_SetPriority() CMSIS function. -* -* Only ISRs prioritized at or below the -* configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY level (i.e., -* with the numerical values of priorities equal or higher than -* configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY) are allowed to call any -* QP/FreeRTOS services. These ISRs are "kernel-aware". -* -* Conversely, any ISRs prioritized above the -* configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY priority level (i.e., with -* the numerical values of priorities less than -* configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY) are never disabled and are -* not aware of the kernel. Such "kernel-unaware" ISRs cannot call any -* QP/FreeRTOS services. The only mechanism by which a "kernel-unaware" ISR -* can communicate with the QF framework is by triggering a "kernel-aware" -* ISR, which can post/publish events. -* -* For more information, see article "Running the RTOS on a ARM Cortex-M Core" -* http://www.freertos.org/RTOS-Cortex-M3-M4.html -* -* NOTE2: -* The User LED is used to visualize the idle loop activity. The brightness -* of the LED is proportional to the frequency of invcations of the idle loop. -* Please note that the LED is toggled with interrupts locked, so no interrupt -* execution time contributes to the brightness of the User LED. -*/ +//============================================================================ +// NOTE1: +// The configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY constant from the +// FreeRTOS configuration file specifies the highest ISR priority that +// is disabled by the QF framework. The value is suitable for the +// NVIC_SetPriority() CMSIS function. +// +// Only ISRs prioritized at or below the +// configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY level (i.e., +// with the numerical values of priorities equal or higher than +// configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY) are allowed to call any +// QP/FreeRTOS services. These ISRs are "kernel-aware". +// +// Conversely, any ISRs prioritized above the +// configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY priority level (i.e., with +// the numerical values of priorities less than +// configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY) are never disabled and are +// not aware of the kernel. Such "kernel-unaware" ISRs cannot call any +// QP/FreeRTOS services. The only mechanism by which a "kernel-unaware" ISR +// can communicate with the QF framework is by triggering a "kernel-aware" +// ISR, which can post/publish events. +// +// For more information, see article "Running the RTOS on a ARM Cortex-M Core" +// http://www.freertos.org/RTOS-Cortex-M3-M4.html +// +// NOTE2: +// The User LED is used to visualize the idle loop activity. The brightness +// of the LED is proportional to the frequency of invcations of the idle loop. +// Please note that the LED is toggled with interrupts locked, so no interrupt +// execution time contributes to the brightness of the User LED. diff --git a/examples/freertos/arm-cm/dpp_nucleo-h743zi/bsp.h b/examples/freertos/arm-cm/dpp_nucleo-h743zi/bsp.h index d1518fa9..e22f0041 100644 --- a/examples/freertos/arm-cm/dpp_nucleo-h743zi/bsp.h +++ b/examples/freertos/arm-cm/dpp_nucleo-h743zi/bsp.h @@ -1,47 +1,51 @@ -/***************************************************************************** -* Product: DPP example, FreeRTOS kernel -* Last Updated for Version: 5.4.0 -* Date of the Last Update: 2015-03-07 -* -* Q u a n t u m L e a P s -* --------------------------- -* innovating embedded systems -* -* Copyright (C) 2005 Quantum Leaps, LLC. state-machine.com. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* Web : http://www.state-machine.com -* -*****************************************************************************/ -#ifndef BSP_H -#define BSP_H +//============================================================================ +// Product: DPP example, FreeRTOS kernel +// Last Updated for Version: 7.3.0 +// Date of the Last Update: 2023-06-27 +// +// Q u a n t u m L e a P s +// --------------------------- +// innovating embedded systems +// +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// This program is open source software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Alternatively, this program may be distributed and modified under the +// terms of Quantum Leaps commercial licenses, which expressly supersede +// the GNU General Public License and are specifically designed for +// licensees interested in retaining the proprietary status of their code. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Contact information: +// +// +//============================================================================ +#ifndef BSP_H_ +#define BSP_H_ #define BSP_TICKS_PER_SEC configTICK_RATE_HZ void BSP_init(void); +void BSP_start(void); void BSP_displayPaused(uint8_t paused); void BSP_displayPhilStat(uint8_t n, char const *stat); void BSP_terminate(int16_t result); -void BSP_randomSeed(uint32_t seed); /* random seed */ -uint32_t BSP_random(void); /* pseudo-random generator */ +void BSP_randomSeed(uint32_t seed); // random seed +uint32_t BSP_random(void); // pseudo-random generator -#endif /* BSP_H */ +void BSP_ledOn(void); +void BSP_ledOff(void); + +#endif // BSP_H_ diff --git a/examples/freertos/arm-cm/dpp_nucleo-h743zi/dpp.h b/examples/freertos/arm-cm/dpp_nucleo-h743zi/dpp.h index da094c2c..e6d1557a 100644 --- a/examples/freertos/arm-cm/dpp_nucleo-h743zi/dpp.h +++ b/examples/freertos/arm-cm/dpp_nucleo-h743zi/dpp.h @@ -1,92 +1,117 @@ -/*$file${.::dpp.h} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* -* Model: dpp.qm -* File: ${.::dpp.h} -* -* This code has been generated by QM 5.2.4 . -* DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. -* -* SPDX-License-Identifier: GPL-3.0-or-later -* -* This generated code is open source software: you can redistribute it under -* the terms of the GNU General Public License as published by the Free -* Software Foundation. -* -* This code is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -* more details. -* -* NOTE: -* Alternatively, this generated code may be distributed under the terms -* of Quantum Leaps commercial licenses, which expressly supersede the GNU -* General Public License and are specifically designed for licensees -* interested in retaining the proprietary status of their code. -* -* Contact information: -* -* -*/ -/*$endhead${.::dpp.h} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -#ifndef DPP_H -#define DPP_H +//$file${.::dpp.h} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// +// Model: dpp.qm +// File: ${.::dpp.h} +// +// This code has been generated by QM 5.3.0 . +// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. +// +// SPDX-License-Identifier: GPL-3.0-or-later +// +// This generated code is open source software: you can redistribute it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation. +// +// This code is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// NOTE: +// Alternatively, this generated code may be distributed under the terms +// of Quantum Leaps commercial licenses, which expressly supersede the GNU +// General Public License and are specifically designed for licensees +// interested in retaining the proprietary status of their code. +// +// Contact information: +// +// +// +//$endhead${.::dpp.h} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +#ifndef DPP_H_ +#define DPP_H_ -enum DPPSignals { - EAT_SIG = Q_USER_SIG, /* published by Table to let a philosopher eat */ - DONE_SIG, /* published by Philosopher when done eating */ - PAUSE_SIG, /* published by BSP to pause serving forks */ - SERVE_SIG, /* published by BSP to serve re-start serving forks */ - TEST_SIG, /* published by BSP to test the application */ - MAX_PUB_SIG, /* the last published signal */ +//$declare${Shared} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv - HUNGRY_SIG, /* posted direclty to Table from hungry Philo */ - TIMEOUT_SIG, /* used by Philosophers for time events */ - MAX_SIG /* the last signal */ +//${Shared::AppSignals} ...................................................... +enum AppSignals { + EAT_SIG = Q_USER_SIG, // published by Table to let a Philo eat + DONE_SIG, // published by Philo when done eating + PAUSE_SIG, // published by BSP to pause the application + SERVE_SIG, // published by BSP to serve re-start serving forks + TEST_SIG, // published by BSP to test the application + MAX_PUB_SIG, // the last published signal + + TIMEOUT_SIG, // posted by time event to Philo + HUNGRY_SIG, // posted by hungry Philo to Table + MAX_SIG // the last signal }; -/*$declare${Events::TableEvt} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//${Shared::produce_sig_dict} ................................................ +#ifdef Q_SPY +static inline void produce_sig_dict(void) { + QS_SIG_DICTIONARY(EAT_SIG, (void *)0); + QS_SIG_DICTIONARY(DONE_SIG, (void *)0); + QS_SIG_DICTIONARY(PAUSE_SIG, (void *)0); + QS_SIG_DICTIONARY(SERVE_SIG, (void *)0); + QS_SIG_DICTIONARY(TEST_SIG, (void *)0); -/*${Events::TableEvt} ......................................................*/ + QS_SIG_DICTIONARY(TIMEOUT_SIG, (void *)0); + QS_SIG_DICTIONARY(HUNGRY_SIG, (void *)0); +} +#endif // def Q_SPY + +//${Shared::N_PHILO} ......................................................... +#define N_PHILO ((uint8_t)5U) + +//${Shared::TableEvt} ........................................................ typedef struct { -/* protected: */ +// protected: QEvt super; -/* public: */ - uint8_t philoNum; +// public: + uint8_t philoId; } TableEvt; -/*$enddecl${Events::TableEvt} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/* number of philosophers */ -#define N_PHILO ((uint8_t)5) +// public: -/*$declare${AOs::Philo_ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +#ifdef QEVT_DYN_CTOR +static inline TableEvt * TableEvt_ctor(TableEvt * const me, + uint8_t id) +{ + if (me != (TableEvt *)0) { + // don't call QEvt_ctor() because the initialization of all + // QEvt attributes is already done in QF_QF_newX_() + me->philoId = id; + } + return me; +} +#endif // def QEVT_DYN_CTOR -/*${AOs::Philo_ctor} .......................................................*/ -void Philo_ctor(void); -/*$enddecl${AOs::Philo_ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*$declare${AOs::AO_Philo[N_PHILO]} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${AOs::AO_Philo[N_PHILO]} ................................................*/ +//${Shared::AO_Philo[N_PHILO]} ............................................... extern QActive * const AO_Philo[N_PHILO]; -/*$enddecl${AOs::AO_Philo[N_PHILO]} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*$declare${AOs::Table_ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//${Shared::Philo_ctor} ...................................................... +void Philo_ctor(uint_fast8_t const id); -/*${AOs::Table_ctor} .......................................................*/ -void Table_ctor(void); -/*$enddecl${AOs::Table_ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*$declare${AOs::AO_Table} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${AOs::AO_Table} .........................................................*/ +//${Shared::AO_Table} ........................................................ extern QActive * const AO_Table; -/*$enddecl${AOs::AO_Table} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -#ifdef QP_INC_QXK_H_ - void Test1_ctor(void); - extern QXThread * const XT_Test1; - void Test2_ctor(void); - extern QXThread * const XT_Test2; -#endif /* QP_INC_QXK_H_ */ +//${Shared::Table_ctor} ...................................................... +void Table_ctor(void); +//$enddecl${Shared} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -#endif /* DPP_H */ +#ifdef QXK_H_ +extern QXThread * const TH_XThread1; +void XThread1_ctor(void); + +extern QXThread * const TH_XThread2; +void XThread2_ctor(void); + +extern QXSemaphore TH_sema; +extern QXMutex TH_mutex; + +#endif // QXK_H_ + +#endif // DPP_H_ diff --git a/examples/freertos/arm-cm/dpp_nucleo-h743zi/dpp.qm b/examples/freertos/arm-cm/dpp_nucleo-h743zi/dpp.qm index 988dcbfa..ac9f2bc9 100644 --- a/examples/freertos/arm-cm/dpp_nucleo-h743zi/dpp.qm +++ b/examples/freertos/arm-cm/dpp_nucleo-h743zi/dpp.qm @@ -1,141 +1,210 @@ - + Dining Philosopher Problem example - - - + + + + + { + EAT_SIG = Q_USER_SIG, // published by Table to let a Philo eat + DONE_SIG, // published by Philo when done eating + PAUSE_SIG, // published by BSP to pause the application + SERVE_SIG, // published by BSP to serve re-start serving forks + TEST_SIG, // published by BSP to test the application + MAX_PUB_SIG, // the last published signal + + TIMEOUT_SIG, // posted by time event to Philo + HUNGRY_SIG, // posted by hungry Philo to Table + MAX_SIG // the last signal +}; + + + + QS_SIG_DICTIONARY(EAT_SIG, (void *)0); +QS_SIG_DICTIONARY(DONE_SIG, (void *)0); +QS_SIG_DICTIONARY(PAUSE_SIG, (void *)0); +QS_SIG_DICTIONARY(SERVE_SIG, (void *)0); +QS_SIG_DICTIONARY(TEST_SIG, (void *)0); + +QS_SIG_DICTIONARY(TIMEOUT_SIG, (void *)0); +QS_SIG_DICTIONARY(HUNGRY_SIG, (void *)0); + + + + ((uint8_t)5U) + + - - + + + + + + + if (me != (TableEvt *)0) { + // don't call QEvt_ctor() because the initialization of all + // QEvt attributes is already done in QF_QF_newX_() + me->philoId = id; +} +return me; + + + + = { + &Philo_inst[0].super, + &Philo_inst[1].super, + &Philo_inst[2].super, + &Philo_inst[3].super, + &Philo_inst[4].super +}; + + + + + + Philo * const me = &Philo_inst[id]; +QActive_ctor(&me->super, Q_STATE_CAST(&Philo_initial)); +QTimeEvt_ctorX(&me->timeEvt, &me->super, TIMEOUT_SIG, 0U), +me->id = (uint8_t)id; + + + + = &Table_inst.super; + + + + Table * const me = &Table_inst; +QActive_ctor(&me->super, Q_STATE_CAST(&Table_initial)); +for (uint8_t n = 0U; n < N_PHILO; ++n) { + me->fork[n] = FREE; + me->isHungry[n] = false; +} + + The Philo AO and the N_PHILO instances + + + + - + - static uint8_t registered = (uint8_t)0; /* starts off with 0, per C-standard */ -(void)par; /* unused parameter */ -if (registered == (uint8_t)0) { - registered = (uint8_t)1; + Q_UNUSED_PAR(par); - QS_OBJ_DICTIONARY(&l_philo[0]); - QS_OBJ_DICTIONARY(&l_philo[0].timeEvt); - QS_OBJ_DICTIONARY(&l_philo[1]); - QS_OBJ_DICTIONARY(&l_philo[1].timeEvt); - QS_OBJ_DICTIONARY(&l_philo[2]); - QS_OBJ_DICTIONARY(&l_philo[2].timeEvt); - QS_OBJ_DICTIONARY(&l_philo[3]); - QS_OBJ_DICTIONARY(&l_philo[3].timeEvt); - QS_OBJ_DICTIONARY(&l_philo[4]); - QS_OBJ_DICTIONARY(&l_philo[4].timeEvt); - - QS_FUN_DICTIONARY(&Philo_initial); - QS_FUN_DICTIONARY(&Philo_thinking); - QS_FUN_DICTIONARY(&Philo_hungry); - QS_FUN_DICTIONARY(&Philo_eating); -} -QS_SIG_DICTIONARY(HUNGRY_SIG, me); /* signal for each Philos */ -QS_SIG_DICTIONARY(TIMEOUT_SIG, me); /* signal for each Philos */ +QS_OBJ_ARR_DICTIONARY(&Philo_inst[me->id], me->id); +QS_OBJ_ARR_DICTIONARY(&Philo_inst[me->id].timeEvt, me->id); QActive_subscribe(&me->super, EAT_SIG); QActive_subscribe(&me->super, TEST_SIG); - + - QTimeEvt_armX(&me->timeEvt, THINK_TIME, 0U); - QTimeEvt_disarm(&me->timeEvt); + QTimeEvt_armX(&me->timeEvt, think_time(), 0U); + (void)QTimeEvt_disarm(&me->timeEvt); - - + + - /* EAT or DONE must be for other Philos than this one */ -Q_ASSERT(Q_EVT_CAST(TableEvt)->philoNum != PHILO_ID(me)); - + // EAT or DONE must be for other Philos than this one +Q_ASSERT(Q_EVT_CAST(TableEvt)->philoId != me->id); + - + - + - + - TableEvt *pe = Q_NEW(TableEvt, HUNGRY_SIG); -pe->philoNum = PHILO_ID(me); -QACTIVE_POST(AO_Table, &pe->super, me); + #ifdef QEVT_DYN_CTOR +TableEvt const *pe = Q_NEW(TableEvt, HUNGRY_SIG, me->id); +#else +TableEvt *pe = Q_NEW(TableEvt, HUNGRY_SIG); +pe->philoId = me->id; +#endif +QACTIVE_POST(AO_Table, &pe->super, &me->super); - + - Q_EVT_CAST(TableEvt)->philoNum == PHILO_ID(me) - - + Q_EVT_CAST(TableEvt)->philoId == me->id + + - + - /* DONE must be for other Philos than this one */ -Q_ASSERT(Q_EVT_CAST(TableEvt)->philoNum != PHILO_ID(me)); - + // DONE must be for other Philos than this one +Q_ASSERT(Q_EVT_CAST(TableEvt)->philoId != me->id); + - + - QTimeEvt_armX(&me->timeEvt, EAT_TIME, 0U); - TableEvt *pe = Q_NEW(TableEvt, DONE_SIG); -pe->philoNum = PHILO_ID(me); + QTimeEvt_armX(&me->timeEvt, eat_time(), 0U); + (void)QTimeEvt_disarm(&me->timeEvt); + +#ifdef QEVT_DYN_CTOR +TableEvt const *pe = Q_NEW(TableEvt, DONE_SIG, me->id); +#else +TableEvt *pe = Q_NEW(TableEvt, DONE_SIG); +pe->philoId = me->id; +#endif QACTIVE_PUBLISH(&pe->super, &me->super); - - + + - /* EAT or DONE must be for other Philos than this one */ -Q_ASSERT(Q_EVT_CAST(TableEvt)->philoNum != PHILO_ID(me)); - + // EAT or DONE must be for other Philos than this one +Q_ASSERT(Q_EVT_CAST(TableEvt)->philoId != me->id); + - + - + @@ -143,22 +212,19 @@ Q_ASSERT(Q_EVT_CAST(TableEvt)->philoNum != PHILO_ID(me)); - + + + - + - (void)par; /* unused parameter */ + Q_UNUSED_PAR(par); -QS_OBJ_DICTIONARY(&l_table); - -QS_SIG_DICTIONARY(DONE_SIG, (void *)0); /* global signals */ -QS_SIG_DICTIONARY(EAT_SIG, (void *)0); -QS_SIG_DICTIONARY(PAUSE_SIG, (void *)0); -QS_SIG_DICTIONARY(SERVE_SIG, (void *)0); -QS_SIG_DICTIONARY(TEST_SIG, (void *)0); - -QS_SIG_DICTIONARY(HUNGRY_SIG, me); /* signal just for Table */ +#ifdef Q_SPY +Table *Table_inst = me; +QS_OBJ_DICTIONARY(Table_inst); +#endif QActive_subscribe(&me->super, DONE_SIG); QActive_subscribe(&me->super, PAUSE_SIG); @@ -167,10 +233,10 @@ QActive_subscribe(&me->super, TEST_SIG); for (uint8_t n = 0U; n < N_PHILO; ++n) { me->fork[n] = FREE; - me->isHungry[n] = 0U; - BSP_displayPhilStat(n, "thinking"); + me->isHungry[n] = false; + BSP_displayPhilStat(n, THINKING); } - + @@ -178,128 +244,139 @@ for (uint8_t n = 0U; n < N_PHILO; ++n) { - + Q_ERROR(); - + - uint8_t n; -for (n = 0U; n < N_PHILO; ++n) { /* give permissions to eat... */ - if ((me->isHungry[n] != 0U) - && (me->fork[LEFT(n)] == FREE) + // give permissions to eat... +for (uint8_t n = 0U; n < N_PHILO; ++n) { + if (me->isHungry[n] + && (me->fork[left(n)] == FREE) && (me->fork[n] == FREE)) { - TableEvt *te; - - me->fork[LEFT(n)] = USED; + me->fork[left(n)] = USED; me->fork[n] = USED; - te = Q_NEW(TableEvt, EAT_SIG); - te->philoNum = n; - QACTIVE_PUBLISH(&te->super, &me->super); - me->isHungry[n] = 0U; - BSP_displayPhilStat(n, "eating "); +#ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, EAT_SIG, n); +#else + TableEvt *pe = Q_NEW(TableEvt, EAT_SIG); + pe->philoId = n; +#endif + QACTIVE_PUBLISH(&pe->super, &me->super); + me->isHungry[n] = false; + BSP_displayPhilStat(n, EATING); } } - uint8_t n, m; + uint8_t n = Q_EVT_CAST(TableEvt)->philoId; -n = Q_EVT_CAST(TableEvt)->philoNum; -/* phil ID must be in range and he must be not hungry */ -Q_ASSERT((n < N_PHILO) && (me->isHungry[n] == 0U)); +// phil ID must be in range and he must be not hungry +Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); -BSP_displayPhilStat(n, "hungry "); -m = LEFT(n); +BSP_displayPhilStat(n, HUNGRY); +uint8_t m = left(n); (me->fork[m] == FREE) && (me->fork[n] == FREE) - TableEvt *pe; -me->fork[m] = USED; + me->fork[m] = USED; me->fork[n] = USED; -pe = Q_NEW(TableEvt, EAT_SIG); -pe->philoNum = n; +#ifdef QEVT_DYN_CTOR +TableEvt const *pe = Q_NEW(TableEvt, EAT_SIG, n); +#else +TableEvt *pe = Q_NEW(TableEvt, EAT_SIG); +pe->philoId = n; +#endif QACTIVE_PUBLISH(&pe->super, &me->super); -BSP_displayPhilStat(n, "eating "); - +BSP_displayPhilStat(n, EATING); + else - me->isHungry[n] = 1U; - - + me->isHungry[n] = true; + + - + - uint8_t n, m; -TableEvt *pe; + uint8_t n = Q_EVT_CAST(TableEvt)->philoId; -n = Q_EVT_CAST(TableEvt)->philoNum; -/* phil ID must be in range and he must be not hungry */ -Q_ASSERT((n < N_PHILO) && (me->isHungry[n] == 0U)); +// phil ID must be in range and he must be not hungry +Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); -BSP_displayPhilStat(n, "thinking"); -m = LEFT(n); -/* both forks of Phil[n] must be used */ +BSP_displayPhilStat(n, THINKING); +uint8_t m = left(n); + +// both forks of Phil[n] must be used Q_ASSERT((me->fork[n] == USED) && (me->fork[m] == USED)); me->fork[m] = FREE; me->fork[n] = FREE; -m = RIGHT(n); /* check the right neighbor */ +m = right(n); // check the right neighbor -if ((me->isHungry[m] != 0U) && (me->fork[m] == FREE)) { +if (me->isHungry[m] && (me->fork[m] == FREE)) { me->fork[n] = USED; me->fork[m] = USED; - me->isHungry[m] = 0U; - pe = Q_NEW(TableEvt, EAT_SIG); - pe->philoNum = m; + me->isHungry[m] = false; +#ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, EAT_SIG, m); +#else + TableEvt *pe = Q_NEW(TableEvt, EAT_SIG); + pe->philoId = m; +#endif QACTIVE_PUBLISH(&pe->super, &me->super); - BSP_displayPhilStat(m, "eating "); + BSP_displayPhilStat(m, EATING); } -m = LEFT(n); /* check the left neighbor */ -n = LEFT(m); /* left fork of the left neighbor */ -if ((me->isHungry[m] != 0U) && (me->fork[n] == FREE)) { +m = left(n); // check the left neighbor +n = left(m); // left fork of the left neighbor +if (me->isHungry[m] && (me->fork[n] == FREE)) { me->fork[m] = USED; me->fork[n] = USED; - me->isHungry[m] = 0U; - pe = Q_NEW(TableEvt, EAT_SIG); - pe->philoNum = m; + me->isHungry[m] = false; +#ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, EAT_SIG, m); +#else + TableEvt *pe = Q_NEW(TableEvt, EAT_SIG); + pe->philoId = m; +#endif QACTIVE_PUBLISH(&pe->super, &me->super); - BSP_displayPhilStat(m, "eating "); + BSP_displayPhilStat(m, EATING); } - + Q_ERROR(); - + - + - + @@ -309,178 +386,140 @@ if ((me->isHungry[m] != 0U) && (me->fork[n] == FREE)) { BSP_displayPaused(0U); - + - uint8_t n = Q_EVT_CAST(TableEvt)->philoNum; -/* philo ID must be in range and he must be not hungry */ -Q_ASSERT((n < N_PHILO) && (me->isHungry[n] == 0U)); -me->isHungry[n] = 1U; -BSP_displayPhilStat(n, "hungry "); - + uint8_t n = Q_EVT_CAST(TableEvt)->philoId; + +// philo ID must be in range and he must be not hungry +Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); + +me->isHungry[n] = true; +BSP_displayPhilStat(n, HUNGRY); + - uint8_t n, m; + uint8_t n = Q_EVT_CAST(TableEvt)->philoId; -n = Q_EVT_CAST(TableEvt)->philoNum; -/* phil ID must be in range and he must be not hungry */ -Q_ASSERT((n < N_PHILO) && (me->isHungry[n] == 0U)); +// phil ID must be in range and he must be not hungry +Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); -BSP_displayPhilStat(n, "thinking"); -m = LEFT(n); -/* both forks of Phil[n] must be used */ +BSP_displayPhilStat(n, THINKING); +uint8_t m = left(n); + +// both forks of Phil[n] must be used Q_ASSERT((me->fork[n] == USED) && (me->fork[m] == USED)); me->fork[m] = FREE; me->fork[n] = FREE; - + - + - + - + - - - - - - - uint8_t n; -Philo *me; -for (n = 0U; n < N_PHILO; ++n) { - me = &l_philo[n]; - QActive_ctor(&me->super, Q_STATE_CAST(&Philo_initial)); - QTimeEvt_ctorX(&me->timeEvt, &me->super, TIMEOUT_SIG, 0U); -} - - - - uint8_t n; -Table *me = &l_table; - -QActive_ctor(&me->super, Q_STATE_CAST(&Table_initial)); - -for (n = 0U; n < N_PHILO; ++n) { - me->fork[n] = FREE; - me->isHungry[n] = 0U; -} - - #ifndef DPP_H -#define DPP_H + #ifndef DPP_H_ +#define DPP_H_ -enum DPPSignals { - EAT_SIG = Q_USER_SIG, /* published by Table to let a philosopher eat */ - DONE_SIG, /* published by Philosopher when done eating */ - PAUSE_SIG, /* published by BSP to pause serving forks */ - SERVE_SIG, /* published by BSP to serve re-start serving forks */ - TEST_SIG, /* published by BSP to test the application */ - MAX_PUB_SIG, /* the last published signal */ +$declare ${Shared} - HUNGRY_SIG, /* posted direclty to Table from hungry Philo */ - TIMEOUT_SIG, /* used by Philosophers for time events */ - MAX_SIG /* the last signal */ -}; +#ifdef QXK_H_ -$declare(Events::TableEvt) +extern QXThread * const TH_XThread1; +void XThread1_ctor(void); -/* number of philosophers */ -#define N_PHILO ((uint8_t)5) +extern QXThread * const TH_XThread2; +void XThread2_ctor(void); -$declare(AOs::Philo_ctor) -$declare(AOs::AO_Philo[N_PHILO]) +extern QXSemaphore TH_sema; +extern QXMutex TH_mutex; -$declare(AOs::Table_ctor) -$declare(AOs::AO_Table) +#endif // QXK_H_ -#ifdef QP_INC_QXK_H_ - void Test1_ctor(void); - extern QXThread * const XT_Test1; - void Test2_ctor(void); - extern QXThread * const XT_Test2; -#endif /* QP_INC_QXK_H_ */ - -#endif /* DPP_H */ - +#endif // DPP_H_ - #include "qpc.h" -#include "dpp.h" -#include "bsp.h" + #include "qpc.h" // QP/C real-time embedded framework +#include "dpp.h" // DPP Application interface +#include "bsp.h" // Board Support Package +$declare ${AOs::Philo} + +//---------------------------------------------------------------------------- Q_DEFINE_THIS_FILE -/* Active object class -----------------------------------------------------*/ -$declare(AOs::Philo) +// helper function to provide a randomized think time for Philos +static QTimeEvtCtr think_time(void); // prototype +static inline QTimeEvtCtr think_time(void) { + return (QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + + (BSP_TICKS_PER_SEC/2U)); +} -/* Local objects -----------------------------------------------------------*/ -static Philo l_philo[N_PHILO]; /* storage for all Philos */ +// helper function to provide a randomized eat time for Philos +static QTimeEvtCtr eat_time(void); // prototype +static inline QTimeEvtCtr eat_time(void) { + return (QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + + BSP_TICKS_PER_SEC); +} +//---------------------------------------------------------------------------- -#define THINK_TIME \ - (QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + (BSP_TICKS_PER_SEC/2U)) -#define EAT_TIME \ - (QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + BSP_TICKS_PER_SEC) - -/* helper macro to provide the ID of Philo "me_" */ -#define PHILO_ID(me_) ((uint8_t)((me_) - l_philo)) - -/* Global objects ----------------------------------------------------------*/ -QActive * const AO_Philo[N_PHILO] = { /* "opaque" pointers to Philo AO */ - &l_philo[0].super, - &l_philo[1].super, - &l_philo[2].super, - &l_philo[3].super, - &l_philo[4].super -}; - -/* Philo definition --------------------------------------------------------*/ -$define(AOs::Philo_ctor) -$define(AOs::Philo) +$define ${Shared::Philo_ctor} +$define ${Shared::AO_Philo[N_PHILO]} +$define ${AOs::Philo} - #include "qpc.h" -#include "dpp.h" -#include "bsp.h" + #include "qpc.h" // QP/C real-time embedded framework +#include "dpp.h" // DPP Application interface +#include "bsp.h" // Board Support Package +$declare ${AOs::Table} + +//---------------------------------------------------------------------------- Q_DEFINE_THIS_FILE -/* Active object class -----------------------------------------------------*/ -$declare(AOs::Table) +// helper function to provide the RIGHT neighbor of a Philo[n] +static inline uint8_t right(uint8_t const n) { + return (uint8_t)((n + (N_PHILO - 1U)) % N_PHILO); +} -#define RIGHT(n_) ((uint8_t)(((n_) + (N_PHILO - 1U)) % N_PHILO)) -#define LEFT(n_) ((uint8_t)(((n_) + 1U) % N_PHILO)) -#define FREE ((uint8_t)0) -#define USED ((uint8_t)1) +// helper function to provide the LEFT neighbor of a Philo[n] +static inline uint8_t left(uint8_t const n) { + return (uint8_t)((n + 1U) % N_PHILO); +} -/* Local objects -----------------------------------------------------------*/ -static Table l_table; /* the single instance of the Table active object */ +#define FREE ((uint8_t)0U) +#define USED ((uint8_t)1U) -/* Global-scope objects ----------------------------------------------------*/ -QActive * const AO_Table = &l_table.super; /* "opaque" AO pointer */ +#define THINKING "thinking" +#define HUNGRY "hungry " +#define EATING "eating " -/*..........................................................................*/ -$define(AOs::Table_ctor) -$define(AOs::Table) +//---------------------------------------------------------------------------- + +$define ${Shared::Table_ctor} +$define ${Shared::AO_Table} +$define ${AOs::Table} diff --git a/examples/freertos/arm-cm/dpp_nucleo-h743zi/gnu/Makefile b/examples/freertos/arm-cm/dpp_nucleo-h743zi/gnu/Makefile index 590d589b..2fbf7e69 100644 --- a/examples/freertos/arm-cm/dpp_nucleo-h743zi/gnu/Makefile +++ b/examples/freertos/arm-cm/dpp_nucleo-h743zi/gnu/Makefile @@ -1,13 +1,13 @@ ############################################################################## -# Product: Makefile for QP/C on NUCLEO-H743ZI, FreeRTOS, GNU-ARM -# Last Updated for Version: 7.0.1 -# Date of the Last Update: 2022-06-13 +# Product: Makefile for QP/C on NUCLEO-H743ZI, FreeRTOS-Kernel, GNU-ARM +# Last Updated for Version: 7.2.2 +# Date of the Last Update: 2023-03-04 # # Q u a n t u m L e a P s # ------------------------ # Modern Embedded Software # -# Copyright (C) 2005-2021 Quantum Leaps, LLC. All rights reserved. +# Copyright (C) 2005 Quantum Leaps, LLC. . # # This program is open source software: you can redistribute it and/or # modify it under the terms of the GNU General Public License as published @@ -64,7 +64,7 @@ endif # location of the FREERTOS (if not provided in an environemnt var.) ifeq ($(FREERTOS),) -FREERTOS := $(QPC)/3rd_party/FreeRTOS +FREERTOS := $(QPC)/3rd_party/FreeRTOS-Kernel endif # QP port used in this project @@ -76,8 +76,8 @@ VPATH = \ $(QPC)/src/qf \ $(QPC)/src/qs \ $(QP_PORT_DIR) \ - $(FREERTOS)/Source \ - $(FREERTOS)/Source/portable/GCC/ARM_CM7/r0p1 \ + $(FREERTOS) \ + $(FREERTOS)/portable/GCC/ARM_CM7/r0p1 \ $(QPC)/3rd_party/STM32CubeH7/nucleo-h743zi/gnu \ $(QPC)/3rd_party/STM32CubeH7/Drivers/BSP\STM32H7xx_Nucleo_144 \ $(QPC)/3rd_party/STM32CubeH7/Drivers/STM32H7xx_HAL_Driver/Src \ @@ -88,8 +88,8 @@ INCLUDES = \ -I.. \ -I$(QPC)/include \ -I$(QP_PORT_DIR) \ - -I$(FREERTOS)/Source/include \ - -I$(FREERTOS)/Source/portable/GCC/ARM_CM4F \ + -I$(FREERTOS)/include \ + -I$(FREERTOS)/portable/GCC/ARM_CM4F \ -I$(QPC)/3rd_party/CMSIS/Include \ -I$(QPC)/3rd_party/STM32CubeH7/Drivers/CMSIS/Device/ST/STM32H7xx/Include \ -I$(QPC)/3rd_party/STM32CubeH7/Drivers/BSP/STM32H7xx_Nucleo_144 \ @@ -155,7 +155,10 @@ LIB_DIRS := LIBS := # defines -DEFINES := -DSTM32H743xx -DUSE_HAL_DRIVER -DUSE_STM32H7XX_NUCLEO_144 +DEFINES := -DQP_CONFIG \ + -DSTM32H743xx \ + -DUSE_HAL_DRIVER \ + -DUSE_STM32H7XX_NUCLEO_144 # ARM CPU, ARCH, FPU, and Float-ABI types... # ARM_CPU: [cortex-m0 | cortex-m0plus | cortex-m1 | cortex-m3 | cortex-m4] @@ -283,7 +286,7 @@ $(TARGET_BIN): $(TARGET_ELF) $(BIN) -O binary $< $@ $(TARGET_ELF) : $(ASM_OBJS_EXT) $(C_OBJS_EXT) $(CPP_OBJS_EXT) - $(CC) $(CFLAGS) $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o + $(CC) $(CFLAGS) $(QPC)/src/qs/qstamp.c -o $(BIN_DIR)/qstamp.o $(LINK) $(LINKFLAGS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) $(BIN_DIR)/%.d : %.c diff --git a/examples/freertos/arm-cm/dpp_nucleo-h743zi/gnu/dpp.ld b/examples/freertos/arm-cm/dpp_nucleo-h743zi/gnu/dpp.ld index 8b0e2363..8f3b98ac 100644 --- a/examples/freertos/arm-cm/dpp_nucleo-h743zi/gnu/dpp.ld +++ b/examples/freertos/arm-cm/dpp_nucleo-h743zi/gnu/dpp.ld @@ -41,7 +41,7 @@ MEMORY { /* memory map of STM32F746NG */ } /* The size of the stack used by the application. NOTE: you need to adjust */ -STACK_SIZE = 2048; +STACK_SIZE = 1024; /* The size of the heap used by the application. NOTE: you need to adjust */ HEAP_SIZE = 0; diff --git a/examples/freertos/arm-cm/dpp_nucleo-h743zi/iar/dpp.ewd b/examples/freertos/arm-cm/dpp_nucleo-h743zi/iar/dpp.ewd index e3b3a198..ba7c2c02 100644 --- a/examples/freertos/arm-cm/dpp_nucleo-h743zi/iar/dpp.ewd +++ b/examples/freertos/arm-cm/dpp_nucleo-h743zi/iar/dpp.ewd @@ -11,7 +11,7 @@ C-SPY 2 - 28 + 32 1 1 - - + + + + + @@ -486,7 +498,7 @@ IJET_ID 2 - 8 + 9 1 1 + + + + + + + + + + + + + @@ -916,7 +980,7 @@ LMIFTDI_ID 2 - 2 + 3 1 1 + + + + + + + NULINK_ID + 2 + + 0 + 1 + 1 + + + @@ -974,7 +1072,7 @@ STLINK_ID 2 - 4 + 8 1 1 + + + + @@ -1185,7 +1300,7 @@ XDS100_ID 2 - 6 + 9 1 1 + + + + @@ -1362,6 +1493,18 @@ $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin 0 + + $TOOLKIT_DIR$\plugins\rtos\FreeRtos\FreeRtosArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin2.ENU.ewplugin + 0 + $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin 0 @@ -1371,11 +1514,15 @@ 0 - $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9.ewplugin 0 - $TOOLKIT_DIR$\plugins\rtos\TI-RTOS\tirtosplugin.ewplugin + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9BE.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin 0 @@ -1391,11 +1538,11 @@ 0 - $EW_DIR$\common\plugins\CodeCoverage\CodeCoverage.ENU.ewplugin - 1 + $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + 0 - $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + $EW_DIR$\common\plugins\TargetAccessServer\TargetAccessServer.ENU.ewplugin 0 @@ -1414,7 +1561,7 @@ C-SPY 2 - 28 + 32 1 0 - - + + + + + @@ -1889,7 +2048,7 @@ IJET_ID 2 - 8 + 9 1 0 + + + + + + + + + + + + + @@ -2319,7 +2530,7 @@ LMIFTDI_ID 2 - 2 + 3 1 0 + + + + + + + NULINK_ID + 2 + + 0 + 1 + 0 + + + @@ -2377,7 +2622,7 @@ STLINK_ID 2 - 4 + 8 1 0 + + + + @@ -2588,7 +2850,7 @@ XDS100_ID 2 - 6 + 9 1 0 + + + + @@ -2765,6 +3043,18 @@ $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin 0 + + $TOOLKIT_DIR$\plugins\rtos\FreeRtos\FreeRtosArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin2.ENU.ewplugin + 0 + $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin 0 @@ -2774,11 +3064,15 @@ 0 - $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9.ewplugin 0 - $TOOLKIT_DIR$\plugins\rtos\TI-RTOS\tirtosplugin.ewplugin + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9BE.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin 0 @@ -2794,11 +3088,11 @@ 0 - $EW_DIR$\common\plugins\CodeCoverage\CodeCoverage.ENU.ewplugin - 1 + $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + 0 - $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + $EW_DIR$\common\plugins\TargetAccessServer\TargetAccessServer.ENU.ewplugin 0 @@ -2817,7 +3111,7 @@ C-SPY 2 - 28 + 32 1 1 - - + + + + + @@ -3292,7 +3598,7 @@ IJET_ID 2 - 8 + 9 1 1 + + + + + + + + + + + + + @@ -3722,7 +4080,7 @@ LMIFTDI_ID 2 - 2 + 3 1 1 + + + + + + + NULINK_ID + 2 + + 0 + 1 + 1 + + + @@ -3780,7 +4172,7 @@ STLINK_ID 2 - 4 + 8 1 1 + + + + @@ -3991,7 +4400,7 @@ XDS100_ID 2 - 6 + 9 1 1 + + + + @@ -4168,6 +4593,18 @@ $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin 0 + + $TOOLKIT_DIR$\plugins\rtos\FreeRtos\FreeRtosArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin2.ENU.ewplugin + 0 + $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin 0 @@ -4177,11 +4614,15 @@ 0 - $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9.ewplugin 0 - $TOOLKIT_DIR$\plugins\rtos\TI-RTOS\tirtosplugin.ewplugin + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9BE.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin 0 @@ -4197,11 +4638,11 @@ 0 - $EW_DIR$\common\plugins\CodeCoverage\CodeCoverage.ENU.ewplugin - 1 + $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + 0 - $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + $EW_DIR$\common\plugins\TargetAccessServer\TargetAccessServer.ENU.ewplugin 0 diff --git a/examples/freertos/arm-cm/dpp_nucleo-h743zi/iar/dpp.ewp b/examples/freertos/arm-cm/dpp_nucleo-h743zi/iar/dpp.ewp index 3fa69052..f7b578ca 100644 --- a/examples/freertos/arm-cm/dpp_nucleo-h743zi/iar/dpp.ewp +++ b/examples/freertos/arm-cm/dpp_nucleo-h743zi/iar/dpp.ewp @@ -11,12 +11,12 @@ General 3 - 33 + 35 1 1 + + + @@ -340,8 +352,8 @@ $PROJ_DIR$\.. $PROJ_DIR$\..\..\..\..\..\include $PROJ_DIR$\..\..\..\..\..\ports\freertos - $PROJ_DIR$\..\..\..\..\..\3rd_party\FreeRTOS\Source\include - $PROJ_DIR$\..\..\..\..\..\3rd_party\FreeRTOS\Source\portable\IAR\ARM_CM7\r0p1 + $PROJ_DIR$\..\..\..\..\..\3rd_party\FreeRTOS-Kernel\include + $PROJ_DIR$\..\..\..\..\..\3rd_party\FreeRTOS-Kernel\portable\IAR\ARM_CM7\r0p1 $PROJ_DIR$\..\..\..\..\..\3rd_party\CMSIS\Include $PROJ_DIR$\..\..\..\..\..\3rd_party\STM32CubeH7\Drivers\CMSIS\Device\ST\STM32H7xx\Include $PROJ_DIR$\..\..\..\..\..\3rd_party\STM32CubeH7\Drivers\BSP\STM32H7xx_Nucleo_144 @@ -678,7 +690,7 @@ ILINK 0 - 25 + 27 1 1 + + + + @@ -1069,12 +1097,12 @@ General 3 - 33 + 35 1 0 + + + @@ -1399,8 +1439,8 @@ $PROJ_DIR$\.. $PROJ_DIR$\..\..\..\..\..\include $PROJ_DIR$\..\..\..\..\..\ports\freertos - $PROJ_DIR$\..\..\..\..\..\3rd_party\FreeRTOS\Source\include - $PROJ_DIR$\..\..\..\..\..\3rd_party\FreeRTOS\Source\portable\IAR\ARM_CM7\r0p1 + $PROJ_DIR$\..\..\..\..\..\3rd_party\FreeRTOS-Kernel\include + $PROJ_DIR$\..\..\..\..\..\3rd_party\FreeRTOS-Kernel\portable\IAR\ARM_CM7\r0p1 $PROJ_DIR$\..\..\..\..\..\3rd_party\CMSIS\Include $PROJ_DIR$\..\..\..\..\..\3rd_party\STM32CubeH7\Drivers\CMSIS\Device\ST\STM32H7xx\Include $PROJ_DIR$\..\..\..\..\..\3rd_party\STM32CubeH7\Drivers\BSP\STM32H7xx_Nucleo_144 @@ -1737,7 +1777,7 @@ ILINK 0 - 25 + 27 1 0 + + + + @@ -2128,12 +2184,12 @@ General 3 - 33 + 35 1 1 + + + @@ -2458,8 +2526,8 @@ $PROJ_DIR$\.. $PROJ_DIR$\..\..\..\..\..\include $PROJ_DIR$\..\..\..\..\..\ports\freertos - $PROJ_DIR$\..\..\..\..\..\3rd_party\FreeRTOS\Source\include - $PROJ_DIR$\..\..\..\..\..\3rd_party\FreeRTOS\Source\portable\IAR\ARM_CM7\r0p1 + $PROJ_DIR$\..\..\..\..\..\3rd_party\FreeRTOS-Kernel\include + $PROJ_DIR$\..\..\..\..\..\3rd_party\FreeRTOS-Kernel\portable\IAR\ARM_CM7\r0p1 $PROJ_DIR$\..\..\..\..\..\3rd_party\CMSIS\Include $PROJ_DIR$\..\..\..\..\..\3rd_party\STM32CubeH7\Drivers\CMSIS\Device\ST\STM32H7xx\Include $PROJ_DIR$\..\..\..\..\..\3rd_party\STM32CubeH7\Drivers\BSP\STM32H7xx_Nucleo_144 @@ -2796,7 +2864,7 @@ ILINK 0 - 25 + 27 1 1 + + + + @@ -3201,7 +3285,7 @@ $PROJ_DIR$\..\philo.c - $PROJ_DIR$\..\..\..\..\..\include\qstamp.c + $PROJ_DIR$\..\..\..\..\..\src\qs\qstamp.c $PROJ_DIR$\..\table.c @@ -3210,22 +3294,22 @@ FreeRTOS - $PROJ_DIR$\..\..\..\..\..\3rd_party\FreeRTOS\Source\list.c + $PROJ_DIR$\..\..\..\..\..\3rd_party\FreeRTOS-Kernel\list.c - $PROJ_DIR$\..\..\..\..\..\3rd_party\FreeRTOS\Source\portable\IAR\ARM_CM7\r0p1\port.c + $PROJ_DIR$\..\..\..\..\..\3rd_party\FreeRTOS-Kernel\portable\IAR\ARM_CM7\r0p1\port.c - $PROJ_DIR$\..\..\..\..\..\3rd_party\FreeRTOS\Source\portable\IAR\ARM_CM7\r0p1\portasm.s + $PROJ_DIR$\..\..\..\..\..\3rd_party\FreeRTOS-Kernel\portable\IAR\ARM_CM7\r0p1\portasm.s - $PROJ_DIR$\..\..\..\..\..\3rd_party\FreeRTOS\Source\portable\IAR\ARM_CM7\r0p1\portmacro.h + $PROJ_DIR$\..\..\..\..\..\3rd_party\FreeRTOS-Kernel\portable\IAR\ARM_CM7\r0p1\portmacro.h - $PROJ_DIR$\..\..\..\..\..\3rd_party\FreeRTOS\Source\queue.c + $PROJ_DIR$\..\..\..\..\..\3rd_party\FreeRTOS-Kernel\queue.c - $PROJ_DIR$\..\..\..\..\..\3rd_party\FreeRTOS\Source\tasks.c + $PROJ_DIR$\..\..\..\..\..\3rd_party\FreeRTOS-Kernel\tasks.c diff --git a/examples/freertos/arm-cm/dpp_nucleo-h743zi/iar/dpp.icf b/examples/freertos/arm-cm/dpp_nucleo-h743zi/iar/dpp.icf index 8d3950cc..2b57a3a4 100644 --- a/examples/freertos/arm-cm/dpp_nucleo-h743zi/iar/dpp.icf +++ b/examples/freertos/arm-cm/dpp_nucleo-h743zi/iar/dpp.icf @@ -35,7 +35,7 @@ define symbol __ICFEDIT_region_SDR1_end__ = 0x0; define symbol __ICFEDIT_region_SDR2_start__ = 0x0; define symbol __ICFEDIT_region_SDR2_end__ = 0x0; /*-Sizes-*/ -define symbol __ICFEDIT_size_cstack__ = 2048; +define symbol __ICFEDIT_size_cstack__ = 1024; define symbol __ICFEDIT_size_proc_stack__ = 0; define symbol __ICFEDIT_size_heap__ = 0; /**** End of ICF editor section. ###ICF###*/ @@ -77,7 +77,8 @@ place in QSPI_region { readonly section application_specific_ro }; //place in NORPSR_region { }; //place in NAND_region { }; place in ITCMR_region { section .textrw }; -place in DTCMR_region { section .dtcm_ram, block CSTACK, block PROC_STACK }; +place at start of DTCMR_region { block CSTACK }; /* <== Quantum Leaps */ +place in DTCMR_region { section .dtcm_ram, block PROC_STACK }; place in SRAM_region { section .axi_sram, block HEAP }; place in AXISR_region { readwrite }; place in BKPR_region { section .backup_sram }; diff --git a/examples/freertos/arm-cm/dpp_nucleo-h743zi/main.c b/examples/freertos/arm-cm/dpp_nucleo-h743zi/main.c index 6413f4ff..cfcfaf07 100644 --- a/examples/freertos/arm-cm/dpp_nucleo-h743zi/main.c +++ b/examples/freertos/arm-cm/dpp_nucleo-h743zi/main.c @@ -1,84 +1,44 @@ -/***************************************************************************** -* Product: DPP example, FreeRTOS kernel -* Last updated for version 6.4.0 -* Last updated on 2019-02-08 -* -* Q u a n t u m L e a P s -* ------------------------ -* Modern Embedded Software -* -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* -* -*****************************************************************************/ -#include "qpc.h" -#include "dpp.h" -#include "bsp.h" +//============================================================================ +// APP example +// Last updated for version 7.3.0 +// Last updated on 2023-08-09 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. +// +// This program is open source software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Alternatively, this program may be distributed and modified under the +// terms of Quantum Leaps commercial licenses, which expressly supersede +// the GNU General Public License and are specifically designed for +// licensees interested in retaining the proprietary status of their code. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Contact information: +// +// +//============================================================================ +#include "qpc.h" // QP/C real-time embedded framework +#include "dpp.h" // DPP Application interface +#include "bsp.h" // Board Support Package -Q_DEFINE_THIS_FILE - -/*..........................................................................*/ +//............................................................................ int main() { - static QEvt const *tableQueueSto[N_PHILO]; - static QEvt const *philoQueueSto[N_PHILO][N_PHILO]; - static QSubscrList subscrSto[MAX_PUB_SIG]; - static QF_MPOOL_EL(TableEvt) smlPoolSto[2*N_PHILO]; /* small pool */ - - static StackType_t philoStack[N_PHILO][configMINIMAL_STACK_SIZE]; - static StackType_t tableStack[configMINIMAL_STACK_SIZE]; - - QF_init(); /* initialize the framework and the underlying RT kernel */ - BSP_init(); /* initialize the Board Support Package */ - - /* initialize publish-subscribe... */ - QF_psInit(subscrSto, Q_DIM(subscrSto)); - - /* initialize event pools... */ - QF_poolInit(smlPoolSto, sizeof(smlPoolSto), sizeof(smlPoolSto[0])); - - /* start the active objects... */ - Philo_ctor(); /* instantiate all Philosopher active objects */ - for (uint8_t n = 0U; n < N_PHILO; ++n) { - QActive_setAttr(AO_Philo[n], TASK_NAME_ATTR, "Philo"); - QACTIVE_START(AO_Philo[n], /* AO to start */ - (uint_fast8_t)(n + 1), /* QP priority of the AO */ - philoQueueSto[n], /* event queue storage */ - Q_DIM(philoQueueSto[n]), /* queue length [events] */ - philoStack[n], /* stack storage */ - sizeof(philoStack[n]), /* stack size [bytes] */ - (QEvt *)0); /* initialization event (not used) */ - } - - Table_ctor(); /* instantiate the Table active object */ - QActive_setAttr(AO_Table, TASK_NAME_ATTR, "Table"); - QACTIVE_START(AO_Table, /* AO to start */ - (uint_fast8_t)(N_PHILO + 1), /* QP priority of the AO */ - tableQueueSto, /* event queue storage */ - Q_DIM(tableQueueSto), /* queue length [events] */ - tableStack, /* stack storage */ - sizeof(tableStack), /* stack size [bytes] */ - (QEvt *)0); /* initialization event (not used) */ - - return QF_run(); /* run the QF application */ + QF_init(); // initialize the framework and the underlying RT kernel + BSP_init(); // initialize the BSP + BSP_start(); // start the AOs/Threads + return QF_run(); // run the QF application } - diff --git a/examples/freertos/arm-cm/dpp_nucleo-h743zi/philo.c b/examples/freertos/arm-cm/dpp_nucleo-h743zi/philo.c index 7614912a..eb6be531 100644 --- a/examples/freertos/arm-cm/dpp_nucleo-h743zi/philo.c +++ b/examples/freertos/arm-cm/dpp_nucleo-h743zi/philo.c @@ -1,165 +1,159 @@ -/*$file${.::philo.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* -* Model: dpp.qm -* File: ${.::philo.c} -* -* This code has been generated by QM 5.2.4 . -* DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. -* -* SPDX-License-Identifier: GPL-3.0-or-later -* -* This generated code is open source software: you can redistribute it under -* the terms of the GNU General Public License as published by the Free -* Software Foundation. -* -* This code is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -* more details. -* -* NOTE: -* Alternatively, this generated code may be distributed under the terms -* of Quantum Leaps commercial licenses, which expressly supersede the GNU -* General Public License and are specifically designed for licensees -* interested in retaining the proprietary status of their code. -* -* Contact information: -* -* -*/ -/*$endhead${.::philo.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -#include "qpc.h" -#include "dpp.h" -#include "bsp.h" +//$file${.::philo.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// +// Model: dpp.qm +// File: ${.::philo.c} +// +// This code has been generated by QM 5.3.0 . +// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. +// +// SPDX-License-Identifier: GPL-3.0-or-later +// +// This generated code is open source software: you can redistribute it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation. +// +// This code is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// NOTE: +// Alternatively, this generated code may be distributed under the terms +// of Quantum Leaps commercial licenses, which expressly supersede the GNU +// General Public License and are specifically designed for licensees +// interested in retaining the proprietary status of their code. +// +// Contact information: +// +// +// +//$endhead${.::philo.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +#include "qpc.h" // QP/C real-time embedded framework +#include "dpp.h" // DPP Application interface +#include "bsp.h" // Board Support Package -Q_DEFINE_THIS_FILE +//$declare${AOs::Philo} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/* Active object class -----------------------------------------------------*/ -/*$declare${AOs::Philo} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${AOs::Philo} ............................................................*/ -typedef struct { -/* protected: */ +//${AOs::Philo} .............................................................. +typedef struct Philo { +// protected: QActive super; -/* private: */ +// private: QTimeEvt timeEvt; + uint8_t id; + +// public: } Philo; -/* protected: */ +extern Philo Philo_inst[N_PHILO]; + +// protected: static QState Philo_initial(Philo * const me, void const * const par); static QState Philo_thinking(Philo * const me, QEvt const * const e); static QState Philo_hungry(Philo * const me, QEvt const * const e); static QState Philo_eating(Philo * const me, QEvt const * const e); -/*$enddecl${AOs::Philo} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$enddecl${AOs::Philo} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -/* Local objects -----------------------------------------------------------*/ -static Philo l_philo[N_PHILO]; /* storage for all Philos */ +//---------------------------------------------------------------------------- +Q_DEFINE_THIS_FILE -#define THINK_TIME \ - (QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + (BSP_TICKS_PER_SEC/2U)) -#define EAT_TIME \ - (QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + BSP_TICKS_PER_SEC) - -/* helper macro to provide the ID of Philo "me_" */ -#define PHILO_ID(me_) ((uint8_t)((me_) - l_philo)) - -/* Global objects ----------------------------------------------------------*/ -QActive * const AO_Philo[N_PHILO] = { /* "opaque" pointers to Philo AO */ - &l_philo[0].super, - &l_philo[1].super, - &l_philo[2].super, - &l_philo[3].super, - &l_philo[4].super -}; - -/* Philo definition --------------------------------------------------------*/ -/*$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* Check for the minimum required QP version */ -#if (QP_VERSION < 700U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) -#error qpc version 7.0.0 or higher required -#endif -/*$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ - -/*$define${AOs::Philo_ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${AOs::Philo_ctor} .......................................................*/ -void Philo_ctor(void) { - uint8_t n; - Philo *me; - for (n = 0U; n < N_PHILO; ++n) { - me = &l_philo[n]; - QActive_ctor(&me->super, Q_STATE_CAST(&Philo_initial)); - QTimeEvt_ctorX(&me->timeEvt, &me->super, TIMEOUT_SIG, 0U); - } +// helper function to provide a randomized think time for Philos +static QTimeEvtCtr think_time(void); // prototype +static inline QTimeEvtCtr think_time(void) { + return (QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + + (BSP_TICKS_PER_SEC/2U)); } -/*$enddef${AOs::Philo_ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*$define${AOs::Philo} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/*${AOs::Philo} ............................................................*/ +// helper function to provide a randomized eat time for Philos +static QTimeEvtCtr eat_time(void); // prototype +static inline QTimeEvtCtr eat_time(void) { + return (QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + + BSP_TICKS_PER_SEC); +} +//---------------------------------------------------------------------------- -/*${AOs::Philo::SM} ........................................................*/ +//$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// Check for the minimum required QP version +#if (QP_VERSION < 730U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) +#error qpc version 7.3.0 or higher required +#endif +//$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +//$define${Shared::Philo_ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${Shared::Philo_ctor} ...................................................... +void Philo_ctor(uint_fast8_t const id) { + Philo * const me = &Philo_inst[id]; + QActive_ctor(&me->super, Q_STATE_CAST(&Philo_initial)); + QTimeEvt_ctorX(&me->timeEvt, &me->super, TIMEOUT_SIG, 0U), + me->id = (uint8_t)id; +} +//$enddef${Shared::Philo_ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +//$define${Shared::AO_Philo[N_PHILO]} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${Shared::AO_Philo[N_PHILO]} ............................................... +QActive * const AO_Philo[N_PHILO] = { + &Philo_inst[0].super, + &Philo_inst[1].super, + &Philo_inst[2].super, + &Philo_inst[3].super, + &Philo_inst[4].super +}; +//$enddef${Shared::AO_Philo[N_PHILO]} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +//$define${AOs::Philo} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${AOs::Philo} .............................................................. +Philo Philo_inst[N_PHILO]; + +//${AOs::Philo::SM} .......................................................... static QState Philo_initial(Philo * const me, void const * const par) { - /*${AOs::Philo::SM::initial} */ - static uint8_t registered = (uint8_t)0; /* starts off with 0, per C-standard */ - (void)par; /* unused parameter */ - if (registered == (uint8_t)0) { - registered = (uint8_t)1; + //${AOs::Philo::SM::initial} + Q_UNUSED_PAR(par); - QS_OBJ_DICTIONARY(&l_philo[0]); - QS_OBJ_DICTIONARY(&l_philo[0].timeEvt); - QS_OBJ_DICTIONARY(&l_philo[1]); - QS_OBJ_DICTIONARY(&l_philo[1].timeEvt); - QS_OBJ_DICTIONARY(&l_philo[2]); - QS_OBJ_DICTIONARY(&l_philo[2].timeEvt); - QS_OBJ_DICTIONARY(&l_philo[3]); - QS_OBJ_DICTIONARY(&l_philo[3].timeEvt); - QS_OBJ_DICTIONARY(&l_philo[4]); - QS_OBJ_DICTIONARY(&l_philo[4].timeEvt); - - QS_FUN_DICTIONARY(&Philo_initial); - QS_FUN_DICTIONARY(&Philo_thinking); - QS_FUN_DICTIONARY(&Philo_hungry); - QS_FUN_DICTIONARY(&Philo_eating); - } - QS_SIG_DICTIONARY(HUNGRY_SIG, me); /* signal for each Philos */ - QS_SIG_DICTIONARY(TIMEOUT_SIG, me); /* signal for each Philos */ + QS_OBJ_ARR_DICTIONARY(&Philo_inst[me->id], me->id); + QS_OBJ_ARR_DICTIONARY(&Philo_inst[me->id].timeEvt, me->id); QActive_subscribe(&me->super, EAT_SIG); QActive_subscribe(&me->super, TEST_SIG); + + QS_FUN_DICTIONARY(&Philo_thinking); + QS_FUN_DICTIONARY(&Philo_hungry); + QS_FUN_DICTIONARY(&Philo_eating); + return Q_TRAN(&Philo_thinking); } -/*${AOs::Philo::SM::thinking} ..............................................*/ +//${AOs::Philo::SM::thinking} ................................................ static QState Philo_thinking(Philo * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${AOs::Philo::SM::thinking} */ + //${AOs::Philo::SM::thinking} case Q_ENTRY_SIG: { - QTimeEvt_armX(&me->timeEvt, THINK_TIME, 0U); + QTimeEvt_armX(&me->timeEvt, think_time(), 0U); status_ = Q_HANDLED(); break; } - /*${AOs::Philo::SM::thinking} */ + //${AOs::Philo::SM::thinking} case Q_EXIT_SIG: { - QTimeEvt_disarm(&me->timeEvt); + (void)QTimeEvt_disarm(&me->timeEvt); status_ = Q_HANDLED(); break; } - /*${AOs::Philo::SM::thinking::TIMEOUT} */ + //${AOs::Philo::SM::thinking::TIMEOUT} case TIMEOUT_SIG: { status_ = Q_TRAN(&Philo_hungry); break; } - /*${AOs::Philo::SM::thinking::EAT, DONE} */ - case EAT_SIG: /* intentionally fall through */ + //${AOs::Philo::SM::thinking::EAT, DONE} + case EAT_SIG: // intentionally fall through case DONE_SIG: { - /* EAT or DONE must be for other Philos than this one */ - Q_ASSERT(Q_EVT_CAST(TableEvt)->philoNum != PHILO_ID(me)); + // EAT or DONE must be for other Philos than this one + Q_ASSERT(Q_EVT_CAST(TableEvt)->philoId != me->id); status_ = Q_HANDLED(); break; } - /*${AOs::Philo::SM::thinking::TEST} */ + //${AOs::Philo::SM::thinking::TEST} case TEST_SIG: { status_ = Q_HANDLED(); break; @@ -172,22 +166,26 @@ static QState Philo_thinking(Philo * const me, QEvt const * const e) { return status_; } -/*${AOs::Philo::SM::hungry} ................................................*/ +//${AOs::Philo::SM::hungry} .................................................. static QState Philo_hungry(Philo * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${AOs::Philo::SM::hungry} */ + //${AOs::Philo::SM::hungry} case Q_ENTRY_SIG: { + #ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, HUNGRY_SIG, me->id); + #else TableEvt *pe = Q_NEW(TableEvt, HUNGRY_SIG); - pe->philoNum = PHILO_ID(me); - QACTIVE_POST(AO_Table, &pe->super, me); + pe->philoId = me->id; + #endif + QACTIVE_POST(AO_Table, &pe->super, &me->super); status_ = Q_HANDLED(); break; } - /*${AOs::Philo::SM::hungry::EAT} */ + //${AOs::Philo::SM::hungry::EAT} case EAT_SIG: { - /*${AOs::Philo::SM::hungry::EAT::[Q_EVT_CAST(TableEvt)->philoNum=~} */ - if (Q_EVT_CAST(TableEvt)->philoNum == PHILO_ID(me)) { + //${AOs::Philo::SM::hungry::EAT::[e->philoId==me->iid]} + if (Q_EVT_CAST(TableEvt)->philoId == me->id) { status_ = Q_TRAN(&Philo_eating); } else { @@ -195,10 +193,10 @@ static QState Philo_hungry(Philo * const me, QEvt const * const e) { } break; } - /*${AOs::Philo::SM::hungry::DONE} */ + //${AOs::Philo::SM::hungry::DONE} case DONE_SIG: { - /* DONE must be for other Philos than this one */ - Q_ASSERT(Q_EVT_CAST(TableEvt)->philoNum != PHILO_ID(me)); + // DONE must be for other Philos than this one + Q_ASSERT(Q_EVT_CAST(TableEvt)->philoId != me->id); status_ = Q_HANDLED(); break; } @@ -210,34 +208,40 @@ static QState Philo_hungry(Philo * const me, QEvt const * const e) { return status_; } -/*${AOs::Philo::SM::eating} ................................................*/ +//${AOs::Philo::SM::eating} .................................................. static QState Philo_eating(Philo * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${AOs::Philo::SM::eating} */ + //${AOs::Philo::SM::eating} case Q_ENTRY_SIG: { - QTimeEvt_armX(&me->timeEvt, EAT_TIME, 0U); + QTimeEvt_armX(&me->timeEvt, eat_time(), 0U); status_ = Q_HANDLED(); break; } - /*${AOs::Philo::SM::eating} */ + //${AOs::Philo::SM::eating} case Q_EXIT_SIG: { + (void)QTimeEvt_disarm(&me->timeEvt); + + #ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, DONE_SIG, me->id); + #else TableEvt *pe = Q_NEW(TableEvt, DONE_SIG); - pe->philoNum = PHILO_ID(me); + pe->philoId = me->id; + #endif QACTIVE_PUBLISH(&pe->super, &me->super); status_ = Q_HANDLED(); break; } - /*${AOs::Philo::SM::eating::TIMEOUT} */ + //${AOs::Philo::SM::eating::TIMEOUT} case TIMEOUT_SIG: { status_ = Q_TRAN(&Philo_thinking); break; } - /*${AOs::Philo::SM::eating::EAT, DONE} */ - case EAT_SIG: /* intentionally fall through */ + //${AOs::Philo::SM::eating::EAT, DONE} + case EAT_SIG: // intentionally fall through case DONE_SIG: { - /* EAT or DONE must be for other Philos than this one */ - Q_ASSERT(Q_EVT_CAST(TableEvt)->philoNum != PHILO_ID(me)); + // EAT or DONE must be for other Philos than this one + Q_ASSERT(Q_EVT_CAST(TableEvt)->philoId != me->id); status_ = Q_HANDLED(); break; } @@ -248,4 +252,4 @@ static QState Philo_eating(Philo * const me, QEvt const * const e) { } return status_; } -/*$enddef${AOs::Philo} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$enddef${AOs::Philo} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/examples/freertos/arm-cm/dpp_nucleo-h743zi/qp_config.h b/examples/freertos/arm-cm/dpp_nucleo-h743zi/qp_config.h new file mode 100644 index 00000000..497ce748 --- /dev/null +++ b/examples/freertos/arm-cm/dpp_nucleo-h743zi/qp_config.h @@ -0,0 +1,41 @@ +//============================================================================ +// QP configuration file example +// Last updated for version: 7.3.0 +// Last updated on: 2023-09-02 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +//============================================================================ +#ifndef QP_CONFIG_H_ +#define QP_CONFIG_H_ + +// NOTE: +// The QP configuration takes effect only when the macro QP_CONFIG +// is defined on the command-line to the compiler for all QP source files. + +#define QF_MAX_ACTIVE configMAX_PRIORITIES + +#endif // QP_CONFIG_H_ diff --git a/examples/freertos/arm-cm/dpp_nucleo-h743zi/stm32-nucleo-h743zi.jpg b/examples/freertos/arm-cm/dpp_nucleo-h743zi/stm32-nucleo-h743zi.jpg new file mode 100644 index 00000000..40916c69 Binary files /dev/null and b/examples/freertos/arm-cm/dpp_nucleo-h743zi/stm32-nucleo-h743zi.jpg differ diff --git a/examples/freertos/arm-cm/dpp_nucleo-h743zi/stm32h7xx_hal_conf.h b/examples/freertos/arm-cm/dpp_nucleo-h743zi/stm32h7xx_hal_conf.h index b8d883b8..b4974459 100644 --- a/examples/freertos/arm-cm/dpp_nucleo-h743zi/stm32h7xx_hal_conf.h +++ b/examples/freertos/arm-cm/dpp_nucleo-h743zi/stm32h7xx_hal_conf.h @@ -1,24 +1,24 @@ -/** - ****************************************************************************** - * @file Demonstrations/Inc/stm32h7xx_hal_conf.h - * @author MCD Application Team - * @brief HAL configuration template file. - * This file should be copied to the application folder and renamed - * to stm32h7xx_hal_conf.h. - ****************************************************************************** - * @attention - * - * Copyright (c) 2017 STMicroelectronics. - * All rights reserved. - * - * This software is licensed under terms that can be found in the LICENSE file - * in the root directory of this software component. - * If no LICENSE file comes with this software, it is provided AS-IS. - * - ****************************************************************************** - */ +//! +//!***************************************************************************** +//! @file Demonstrations/Inc/stm32h7xx_hal_conf.h +//! @author MCD Application Team +//! @brief HAL configuration template file. +//! This file should be copied to the application folder and renamed +//! to stm32h7xx_hal_conf.h. +//!***************************************************************************** +//! @attention +//! +//! Copyright (c) 2017 STMicroelectronics. +//! All rights reserved. +//! +//! This software is licensed under terms that can be found in the LICENSE file +//! in the root directory of this software component. +//! If no LICENSE file comes with this software, it is provided AS-IS. +//! +//!***************************************************************************** +//! -/* Define to prevent recursive inclusion -------------------------------------*/ +// Define to prevent recursive inclusion ------------------------------------- #ifndef __STM32H7xx_HAL_CONF_H #define __STM32H7xx_HAL_CONF_H @@ -26,142 +26,144 @@ extern "C" { #endif -/* Exported types ------------------------------------------------------------*/ -/* Exported constants --------------------------------------------------------*/ +// Exported types ------------------------------------------------------------ +// Exported constants -------------------------------------------------------- -/* ########################## Module Selection ############################## */ -/** - * @brief This is the list of modules to be used in the HAL driver - */ +// ########################## Module Selection ############################## +//! +//! @brief This is the list of modules to be used in the HAL driver +//! #define HAL_MODULE_ENABLED -/* #define HAL_ADC_MODULE_ENABLED */ -/* #define HAL_CEC_MODULE_ENABLED */ -/* #define HAL_COMP_MODULE_ENABLED */ +// #define HAL_ADC_MODULE_ENABLED +// #define HAL_CEC_MODULE_ENABLED +// #define HAL_COMP_MODULE_ENABLED #define HAL_CORTEX_MODULE_ENABLED -/* #define HAL_CRC_MODULE_ENABLED */ -/* #define HAL_CRYP_MODULE_ENABLED */ -/* #define HAL_DAC_MODULE_ENABLED */ -/* #define HAL_DCMI_MODULE_ENABLED */ -/* #define HAL_DFSDM_MODULE_ENABLED */ +// #define HAL_CRC_MODULE_ENABLED +// #define HAL_CRYP_MODULE_ENABLED +// #define HAL_DAC_MODULE_ENABLED +// #define HAL_DCMI_MODULE_ENABLED +// #define HAL_DFSDM_MODULE_ENABLED #define HAL_DMA_MODULE_ENABLED -/* #define HAL_DMA2D_MODULE_ENABLED */ -/* #define HAL_ETH_MODULE_ENABLED */ +// #define HAL_DMA2D_MODULE_ENABLED +// #define HAL_ETH_MODULE_ENABLED #define HAL_EXTI_MODULE_ENABLED -/* #define HAL_FDCAN_MODULE_ENABLED */ +// #define HAL_FDCAN_MODULE_ENABLED #define HAL_FLASH_MODULE_ENABLED #define HAL_GPIO_MODULE_ENABLED -/* #define HAL_HASH_MODULE_ENABLED */ -/* #define HAL_HCD_MODULE_ENABLED */ -/* #define HAL_HRTIM_MODULE_ENABLED */ -/* #define HAL_HSEM_MODULE_ENABLED */ -/* #define HAL_I2C_MODULE_ENABLED */ -/* #define HAL_I2S_MODULE_ENABLED */ -/* #define HAL_IRDA_MODULE_ENABLED */ -/* #define HAL_IWDG_MODULE_ENABLED */ -/* #define HAL_JPEG_MODULE_ENABLED */ -/* #define HAL_LPTIM_MODULE_ENABLED */ -/* #define HAL_LTDC_MODULE_ENABLED */ -/* #define HAL_MDIOS_MODULE_ENABLED */ -/* #define HAL_MDMA_MODULE_ENABLED */ -/* #define HAL_MMC_MODULE_ENABLED */ -/* #define HAL_NAND_MODULE_ENABLED */ -/* #define HAL_NOR_MODULE_ENABLED */ -/* #define HAL_OPAMP_MODULE_ENABLED */ -/* #define HAL_PCD_MODULE_ENABLED */ +// #define HAL_HASH_MODULE_ENABLED +// #define HAL_HCD_MODULE_ENABLED +// #define HAL_HRTIM_MODULE_ENABLED +// #define HAL_HSEM_MODULE_ENABLED +// #define HAL_I2C_MODULE_ENABLED +// #define HAL_I2S_MODULE_ENABLED +// #define HAL_IRDA_MODULE_ENABLED +// #define HAL_IWDG_MODULE_ENABLED +// #define HAL_JPEG_MODULE_ENABLED +// #define HAL_LPTIM_MODULE_ENABLED +// #define HAL_LTDC_MODULE_ENABLED +// #define HAL_MDIOS_MODULE_ENABLED +// #define HAL_MDMA_MODULE_ENABLED +// #define HAL_MMC_MODULE_ENABLED +// #define HAL_NAND_MODULE_ENABLED +// #define HAL_NOR_MODULE_ENABLED +// #define HAL_OPAMP_MODULE_ENABLED +// #define HAL_PCD_MODULE_ENABLED #define HAL_PWR_MODULE_ENABLED -/* #define HAL_QSPI_MODULE_ENABLED */ -/* #define HAL_RAMECC_MODULE_ENABLED */ +// #define HAL_QSPI_MODULE_ENABLED +// #define HAL_RAMECC_MODULE_ENABLED #define HAL_RCC_MODULE_ENABLED -/* #define HAL_RNG_MODULE_ENABLED */ -/* #define HAL_RTC_MODULE_ENABLED */ -/* #define HAL_SAI_MODULE_ENABLED */ -/* #define HAL_SD_MODULE_ENABLED */ -/* #define HAL_SDRAM_MODULE_ENABLED */ -/* #define HAL_SMARTCARD_MODULE_ENABLED */ -/* #define HAL_SMBUS_MODULE_ENABLED */ -/* #define HAL_SPDIFRX_MODULE_ENABLED */ -/* #define HAL_SPI_MODULE_ENABLED */ -/* #define HAL_SRAM_MODULE_ENABLED */ -/* #define HAL_SWPMI_MODULE_ENABLED */ -/* #define HAL_TIM_MODULE_ENABLED */ +// #define HAL_RNG_MODULE_ENABLED +// #define HAL_RTC_MODULE_ENABLED +// #define HAL_SAI_MODULE_ENABLED +// #define HAL_SD_MODULE_ENABLED +// #define HAL_SDRAM_MODULE_ENABLED +// #define HAL_SMARTCARD_MODULE_ENABLED +// #define HAL_SMBUS_MODULE_ENABLED +// #define HAL_SPDIFRX_MODULE_ENABLED +// #define HAL_SPI_MODULE_ENABLED +// #define HAL_SRAM_MODULE_ENABLED +// #define HAL_SWPMI_MODULE_ENABLED +// #define HAL_TIM_MODULE_ENABLED #define HAL_UART_MODULE_ENABLED -/* #define HAL_USART_MODULE_ENABLED */ -/* #define HAL_WWDG_MODULE_ENABLED */ +// #define HAL_USART_MODULE_ENABLED +// #define HAL_WWDG_MODULE_ENABLED -/* ########################## Oscillator Values adaptation ####################*/ -/** - * @brief Adjust the value of External High Speed oscillator (HSE) used in your application. - * This value is used by the RCC HAL module to compute the system frequency - * (when HSE is used as system clock source, directly or through the PLL). - */ +// ########################## Oscillator Values adaptation #################### +//! +//! @brief Adjust the value of External High Speed oscillator (HSE) used in your application. +//! This value is used by the RCC HAL module to compute the system frequency +//! (when HSE is used as system clock source, directly or through the PLL). +//! #if !defined (HSE_VALUE) -#define HSE_VALUE ((uint32_t)8000000) /*!< Value of the External oscillator in Hz */ -#endif /* HSE_VALUE */ +#define HSE_VALUE ((uint32_t)8000000) //!< Value of the External oscillator in Hz +#endif // HSE_VALUE #if !defined (HSE_STARTUP_TIMEOUT) - #define HSE_STARTUP_TIMEOUT ((uint32_t)100) /*!< Time out for HSE start up, in ms */ -#endif /* HSE_STARTUP_TIMEOUT */ + #define HSE_STARTUP_TIMEOUT ((uint32_t)100) //!< Time out for HSE start up, in ms +#endif // HSE_STARTUP_TIMEOUT -/** - * @brief Internal oscillator (CSI) default value. - * This value is the default CSI value after Reset. - */ +//! +//! @brief Internal oscillator (CSI) default value. +//! This value is the default CSI value after Reset. +//! #if !defined (CSI_VALUE) - #define CSI_VALUE ((uint32_t)4000000) /*!< Value of the Internal oscillator in Hz*/ -#endif /* CSI_VALUE */ + #define CSI_VALUE ((uint32_t)4000000) //!< Value of the Internal oscillator in Hz +#endif // CSI_VALUE -/** - * @brief Internal High Speed oscillator (HSI) value. - * This value is used by the RCC HAL module to compute the system frequency - * (when HSI is used as system clock source, directly or through the PLL). - */ +//! +//! @brief Internal High Speed oscillator (HSI) value. +//! This value is used by the RCC HAL module to compute the system frequency +//! (when HSI is used as system clock source, directly or through the PLL). +//! #if !defined (HSI_VALUE) - #define HSI_VALUE ((uint32_t)64000000) /*!< Value of the Internal oscillator in Hz*/ -#endif /* HSI_VALUE */ + #define HSI_VALUE ((uint32_t)64000000) //!< Value of the Internal oscillator in Hz +#endif // HSI_VALUE -/** - * @brief External Low Speed oscillator (LSE) value. - * This value is used by the UART, RTC HAL module to compute the system frequency - */ +//! +//! @brief External Low Speed oscillator (LSE) value. +//! This value is used by the UART, RTC HAL module to compute the system frequency +//! #if !defined (LSE_VALUE) - #define LSE_VALUE ((uint32_t)32768) /*!< Value of the External oscillator in Hz*/ -#endif /* LSE_VALUE */ + #define LSE_VALUE ((uint32_t)32768) //!< Value of the External oscillator in Hz +#endif // LSE_VALUE #if !defined (LSE_STARTUP_TIMEOUT) - #define LSE_STARTUP_TIMEOUT ((uint32_t)5000) /*!< Time out for LSE start up, in ms */ -#endif /* LSE_STARTUP_TIMEOUT */ + #define LSE_STARTUP_TIMEOUT ((uint32_t)5000) //!< Time out for LSE start up, in ms +#endif // LSE_STARTUP_TIMEOUT #if !defined (LSI_VALUE) - #define LSI_VALUE ((uint32_t)32000) /*!< LSI Typical Value in Hz*/ -#endif /* LSI_VALUE */ /*!< Value of the Internal Low Speed oscillator in Hz - The real value may vary depending on the variations - in voltage and temperature.*/ + #define LSI_VALUE ((uint32_t)32000) //!< LSI Typical Value in Hz +#endif // LSI_VALUE + //!< Value of the Internal Low Speed oscillator in Hz + //!< The real value may vary depending on the variations + //!< in voltage and temperature. -/** - * @brief External clock source for I2S peripheral - * This value is used by the I2S HAL module to compute the I2S clock source - * frequency, this source is inserted directly through I2S_CKIN pad. - */ +//! +//! @brief External clock source for I2S peripheral +//! This value is used by the I2S HAL module to compute the I2S clock source +//! frequency, this source is inserted directly through I2S_CKIN pad. +//! #if !defined (EXTERNAL_CLOCK_VALUE) - #define EXTERNAL_CLOCK_VALUE 12288000U /*!< Value of the External clock in Hz*/ -#endif /* EXTERNAL_CLOCK_VALUE */ + #define EXTERNAL_CLOCK_VALUE 12288000U //!< Value of the External clock in Hz +#endif // EXTERNAL_CLOCK_VALUE -/* Tip: To avoid modifying this file each time you need to use different HSE, - === you can define the HSE value in your toolchain compiler preprocessor. */ +// Tip: To avoid modifying this file each time you need to use different HSE, +// === you can define the HSE value in your toolchain compiler preprocessor. -/* ########################### System Configuration ######################### */ -/** - * @brief This is the HAL system configuration section - */ -#define VDD_VALUE 3300UL /*!< Value of VDD in mv */ -#define TICK_INT_PRIORITY ((uint32_t)0x0F) /*!< tick interrupt priority */ +// ########################### System Configuration ######################### +//! +//! @brief This is the HAL system configuration section +//! +#define VDD_VALUE 3300UL //!< Value of VDD in mv +#define TICK_INT_PRIORITY ((uint32_t)0x0F) //!< tick interrupt priority #define USE_RTOS 0 -/* #define USE_SD_TRANSCEIVER 1U */ /*!< use uSD Transceiver */ +// #define USE_SD_TRANSCEIVER 1U + //!< use uSD Transceiver -/* ########################### Ethernet Configuration ######################### */ -#define ETH_TX_DESC_CNT 4 /* number of Ethernet Tx DMA descriptors */ -#define ETH_RX_DESC_CNT 4 /* number of Ethernet Rx DMA descriptors */ +// ########################### Ethernet Configuration ######################### +#define ETH_TX_DESC_CNT 4 // number of Ethernet Tx DMA descriptors +#define ETH_RX_DESC_CNT 4 // number of Ethernet Rx DMA descriptors #define ETH_MAC_ADDR0 ((uint8_t)0x02) #define ETH_MAC_ADDR1 ((uint8_t)0x00) @@ -170,263 +172,263 @@ #define ETH_MAC_ADDR4 ((uint8_t)0x00) #define ETH_MAC_ADDR5 ((uint8_t)0x00) -/* ########################## Assert Selection ############################## */ -/** - * @brief Uncomment the line below to expanse the "assert_param" macro in the - * HAL drivers code - */ -/* #define USE_FULL_ASSERT 1 */ +// ########################## Assert Selection ############################## +//! +//! @brief Uncomment the line below to expanse the "assert_param" macro in the +//! HAL drivers code +//! +// #define USE_FULL_ASSERT 1 -/* ################## SPI peripheral configuration ########################## */ -/** - * @brief Used to activate CRC feature inside HAL SPI Driver - * Activated (1U): CRC code is compiled within HAL SPI driver - * Deactivated (0U): CRC code excluded from HAL SPI driver - */ +// ################## SPI peripheral configuration ########################## +//! +//! @brief Used to activate CRC feature inside HAL SPI Driver +//! Activated (1U): CRC code is compiled within HAL SPI driver +//! Deactivated (0U): CRC code excluded from HAL SPI driver +//! #define USE_SPI_CRC 1U -/* Includes ------------------------------------------------------------------*/ -/** - * @brief Include module's header file - */ +// Includes ------------------------------------------------------------------ +//! +//! @brief Include module's header file +//! #ifdef HAL_RCC_MODULE_ENABLED #include "stm32h7xx_hal_rcc.h" -#endif /* HAL_RCC_MODULE_ENABLED */ +#endif // HAL_RCC_MODULE_ENABLED #ifdef HAL_GPIO_MODULE_ENABLED #include "stm32h7xx_hal_gpio.h" -#endif /* HAL_GPIO_MODULE_ENABLED */ +#endif // HAL_GPIO_MODULE_ENABLED #ifdef HAL_DMA_MODULE_ENABLED #include "stm32h7xx_hal_dma.h" -#endif /* HAL_DMA_MODULE_ENABLED */ +#endif // HAL_DMA_MODULE_ENABLED #ifdef HAL_MDMA_MODULE_ENABLED #include "stm32h7xx_hal_mdma.h" -#endif /* HAL_MDMA_MODULE_ENABLED */ +#endif // HAL_MDMA_MODULE_ENABLED #ifdef HAL_HASH_MODULE_ENABLED #include "stm32h7xx_hal_hash.h" -#endif /* HAL_HASH_MODULE_ENABLED */ +#endif // HAL_HASH_MODULE_ENABLED #ifdef HAL_DCMI_MODULE_ENABLED #include "stm32h7xx_hal_dcmi.h" -#endif /* HAL_DCMI_MODULE_ENABLED */ +#endif // HAL_DCMI_MODULE_ENABLED #ifdef HAL_DMA2D_MODULE_ENABLED #include "stm32h7xx_hal_dma2d.h" -#endif /* HAL_DMA2D_MODULE_ENABLED */ +#endif // HAL_DMA2D_MODULE_ENABLED #ifdef HAL_DFSDM_MODULE_ENABLED #include "stm32h7xx_hal_dfsdm.h" -#endif /* HAL_DFSDM_MODULE_ENABLED */ +#endif // HAL_DFSDM_MODULE_ENABLED #ifdef HAL_ETH_MODULE_ENABLED #include "stm32h7xx_hal_eth.h" -#endif /* HAL_ETH_MODULE_ENABLED */ +#endif // HAL_ETH_MODULE_ENABLED #ifdef HAL_EXTI_MODULE_ENABLED #include "stm32h7xx_hal_exti.h" -#endif /* HAL_EXTI_MODULE_ENABLED */ +#endif // HAL_EXTI_MODULE_ENABLED #ifdef HAL_CORTEX_MODULE_ENABLED #include "stm32h7xx_hal_cortex.h" -#endif /* HAL_CORTEX_MODULE_ENABLED */ +#endif // HAL_CORTEX_MODULE_ENABLED #ifdef HAL_ADC_MODULE_ENABLED #include "stm32h7xx_hal_adc.h" -#endif /* HAL_ADC_MODULE_ENABLED */ +#endif // HAL_ADC_MODULE_ENABLED #ifdef HAL_FDCAN_MODULE_ENABLED #include "stm32h7xx_hal_fdcan.h" -#endif /* HAL_FDCAN_MODULE_ENABLED */ +#endif // HAL_FDCAN_MODULE_ENABLED #ifdef HAL_CEC_MODULE_ENABLED #include "stm32h7xx_hal_cec.h" -#endif /* HAL_CEC_MODULE_ENABLED */ +#endif // HAL_CEC_MODULE_ENABLED #ifdef HAL_COMP_MODULE_ENABLED #include "stm32h7xx_hal_comp.h" -#endif /* HAL_COMP_MODULE_ENABLED */ +#endif // HAL_COMP_MODULE_ENABLED #ifdef HAL_CRC_MODULE_ENABLED #include "stm32h7xx_hal_crc.h" -#endif /* HAL_CRC_MODULE_ENABLED */ +#endif // HAL_CRC_MODULE_ENABLED #ifdef HAL_CRYP_MODULE_ENABLED #include "stm32h7xx_hal_cryp.h" -#endif /* HAL_CRYP_MODULE_ENABLED */ +#endif // HAL_CRYP_MODULE_ENABLED #ifdef HAL_DAC_MODULE_ENABLED #include "stm32h7xx_hal_dac.h" -#endif /* HAL_DAC_MODULE_ENABLED */ +#endif // HAL_DAC_MODULE_ENABLED #ifdef HAL_FLASH_MODULE_ENABLED #include "stm32h7xx_hal_flash.h" -#endif /* HAL_FLASH_MODULE_ENABLED */ +#endif // HAL_FLASH_MODULE_ENABLED #ifdef HAL_HRTIM_MODULE_ENABLED #include "stm32h7xx_hal_hrtim.h" -#endif /* HAL_HRTIM_MODULE_ENABLED */ +#endif // HAL_HRTIM_MODULE_ENABLED #ifdef HAL_HSEM_MODULE_ENABLED #include "stm32h7xx_hal_hsem.h" -#endif /* HAL_HSEM_MODULE_ENABLED */ +#endif // HAL_HSEM_MODULE_ENABLED #ifdef HAL_SRAM_MODULE_ENABLED #include "stm32h7xx_hal_sram.h" -#endif /* HAL_SRAM_MODULE_ENABLED */ +#endif // HAL_SRAM_MODULE_ENABLED #ifdef HAL_NOR_MODULE_ENABLED #include "stm32h7xx_hal_nor.h" -#endif /* HAL_NOR_MODULE_ENABLED */ +#endif // HAL_NOR_MODULE_ENABLED #ifdef HAL_NAND_MODULE_ENABLED #include "stm32h7xx_hal_nand.h" -#endif /* HAL_NAND_MODULE_ENABLED */ +#endif // HAL_NAND_MODULE_ENABLED #ifdef HAL_I2C_MODULE_ENABLED #include "stm32h7xx_hal_i2c.h" -#endif /* HAL_I2C_MODULE_ENABLED */ +#endif // HAL_I2C_MODULE_ENABLED #ifdef HAL_I2S_MODULE_ENABLED #include "stm32h7xx_hal_i2s.h" -#endif /* HAL_I2S_MODULE_ENABLED */ +#endif // HAL_I2S_MODULE_ENABLED #ifdef HAL_IWDG_MODULE_ENABLED #include "stm32h7xx_hal_iwdg.h" -#endif /* HAL_IWDG_MODULE_ENABLED */ +#endif // HAL_IWDG_MODULE_ENABLED #ifdef HAL_JPEG_MODULE_ENABLED #include "stm32h7xx_hal_jpeg.h" -#endif /* HAL_JPEG_MODULE_ENABLED */ +#endif // HAL_JPEG_MODULE_ENABLED #ifdef HAL_MDIOS_MODULE_ENABLED #include "stm32h7xx_hal_mdios.h" -#endif /* HAL_MDIOS_MODULE_ENABLED */ +#endif // HAL_MDIOS_MODULE_ENABLED #ifdef HAL_MMC_MODULE_ENABLED #include "stm32h7xx_hal_mmc.h" -#endif /* HAL_MMC_MODULE_ENABLED */ +#endif // HAL_MMC_MODULE_ENABLED #ifdef HAL_LPTIM_MODULE_ENABLED #include "stm32h7xx_hal_lptim.h" -#endif /* HAL_LPTIM_MODULE_ENABLED */ +#endif // HAL_LPTIM_MODULE_ENABLED #ifdef HAL_LTDC_MODULE_ENABLED #include "stm32h7xx_hal_ltdc.h" -#endif /* HAL_LTDC_MODULE_ENABLED */ +#endif // HAL_LTDC_MODULE_ENABLED #ifdef HAL_OPAMP_MODULE_ENABLED #include "stm32h7xx_hal_opamp.h" -#endif /* HAL_OPAMP_MODULE_ENABLED */ +#endif // HAL_OPAMP_MODULE_ENABLED #ifdef HAL_PWR_MODULE_ENABLED #include "stm32h7xx_hal_pwr.h" -#endif /* HAL_PWR_MODULE_ENABLED */ +#endif // HAL_PWR_MODULE_ENABLED #ifdef HAL_QSPI_MODULE_ENABLED #include "stm32h7xx_hal_qspi.h" -#endif /* HAL_QSPI_MODULE_ENABLED */ +#endif // HAL_QSPI_MODULE_ENABLED #ifdef HAL_RAMECC_MODULE_ENABLED #include "stm32h7xx_hal_ramecc.h" -#endif /* HAL_HCD_MODULE_ENABLED */ +#endif // HAL_HCD_MODULE_ENABLED #ifdef HAL_RNG_MODULE_ENABLED #include "stm32h7xx_hal_rng.h" -#endif /* HAL_RNG_MODULE_ENABLED */ +#endif // HAL_RNG_MODULE_ENABLED #ifdef HAL_RTC_MODULE_ENABLED #include "stm32h7xx_hal_rtc.h" -#endif /* HAL_RTC_MODULE_ENABLED */ +#endif // HAL_RTC_MODULE_ENABLED #ifdef HAL_SAI_MODULE_ENABLED #include "stm32h7xx_hal_sai.h" -#endif /* HAL_SAI_MODULE_ENABLED */ +#endif // HAL_SAI_MODULE_ENABLED #ifdef HAL_SD_MODULE_ENABLED #include "stm32h7xx_hal_sd.h" -#endif /* HAL_SD_MODULE_ENABLED */ +#endif // HAL_SD_MODULE_ENABLED #ifdef HAL_SDRAM_MODULE_ENABLED #include "stm32h7xx_hal_sdram.h" -#endif /* HAL_SDRAM_MODULE_ENABLED */ +#endif // HAL_SDRAM_MODULE_ENABLED #ifdef HAL_SPI_MODULE_ENABLED #include "stm32h7xx_hal_spi.h" -#endif /* HAL_SPI_MODULE_ENABLED */ +#endif // HAL_SPI_MODULE_ENABLED #ifdef HAL_SPDIFRX_MODULE_ENABLED #include "stm32h7xx_hal_spdifrx.h" -#endif /* HAL_SPDIFRX_MODULE_ENABLED */ +#endif // HAL_SPDIFRX_MODULE_ENABLED #ifdef HAL_SWPMI_MODULE_ENABLED #include "stm32h7xx_hal_swpmi.h" -#endif /* HAL_SWPMI_MODULE_ENABLED */ +#endif // HAL_SWPMI_MODULE_ENABLED #ifdef HAL_TIM_MODULE_ENABLED #include "stm32h7xx_hal_tim.h" -#endif /* HAL_TIM_MODULE_ENABLED */ +#endif // HAL_TIM_MODULE_ENABLED #ifdef HAL_UART_MODULE_ENABLED #include "stm32h7xx_hal_uart.h" -#endif /* HAL_UART_MODULE_ENABLED */ +#endif // HAL_UART_MODULE_ENABLED #ifdef HAL_USART_MODULE_ENABLED #include "stm32h7xx_hal_usart.h" -#endif /* HAL_USART_MODULE_ENABLED */ +#endif // HAL_USART_MODULE_ENABLED #ifdef HAL_IRDA_MODULE_ENABLED #include "stm32h7xx_hal_irda.h" -#endif /* HAL_IRDA_MODULE_ENABLED */ +#endif // HAL_IRDA_MODULE_ENABLED #ifdef HAL_SMARTCARD_MODULE_ENABLED #include "stm32h7xx_hal_smartcard.h" -#endif /* HAL_SMARTCARD_MODULE_ENABLED */ +#endif // HAL_SMARTCARD_MODULE_ENABLED #ifdef HAL_SMBUS_MODULE_ENABLED #include "stm32h7xx_hal_smbus.h" -#endif /* HAL_SMBUS_MODULE_ENABLED */ +#endif // HAL_SMBUS_MODULE_ENABLED #ifdef HAL_WWDG_MODULE_ENABLED #include "stm32h7xx_hal_wwdg.h" -#endif /* HAL_WWDG_MODULE_ENABLED */ +#endif // HAL_WWDG_MODULE_ENABLED #ifdef HAL_PCD_MODULE_ENABLED #include "stm32h7xx_hal_pcd.h" -#endif /* HAL_PCD_MODULE_ENABLED */ +#endif // HAL_PCD_MODULE_ENABLED #ifdef HAL_HCD_MODULE_ENABLED #include "stm32h7xx_hal_hcd.h" -#endif /* HAL_HCD_MODULE_ENABLED */ +#endif // HAL_HCD_MODULE_ENABLED -/* Exported macro ------------------------------------------------------------*/ +// Exported macro ------------------------------------------------------------ #ifdef USE_FULL_ASSERT -/** - * @brief The assert_param macro is used for function's parameters check. - * @param expr: If expr is false, it calls assert_failed function - * which reports the name of the source file and the source - * line number of the call that failed. - * If expr is true, it returns no value. - * @retval None - */ +//! +//! @brief The assert_param macro is used for function's parameters check. +//! @param expr: If expr is false, it calls assert_failed function +//! which reports the name of the source file and the source +//! line number of the call that failed. +//! If expr is true, it returns no value. +//! @retval None +//! #define assert_param(expr) ((expr) ? (void)0U : assert_failed((uint8_t *)__FILE__, __LINE__)) -/* Exported functions ------------------------------------------------------- */ +// Exported functions ------------------------------------------------------- void assert_failed(uint8_t* file, uint32_t line); #else #define assert_param(expr) ((void)0U) -#endif /* USE_FULL_ASSERT */ +#endif // USE_FULL_ASSERT #ifdef __cplusplus } #endif -#endif /* __STM32H7xx_HAL_CONF_H */ +#endif // __STM32H7xx_HAL_CONF_H diff --git a/examples/freertos/arm-cm/dpp_nucleo-h743zi/stm32h7xx_hal_msp.c b/examples/freertos/arm-cm/dpp_nucleo-h743zi/stm32h7xx_hal_msp.c index 224ba02f..a37af714 100644 --- a/examples/freertos/arm-cm/dpp_nucleo-h743zi/stm32h7xx_hal_msp.c +++ b/examples/freertos/arm-cm/dpp_nucleo-h743zi/stm32h7xx_hal_msp.c @@ -1,57 +1,57 @@ -/** - ****************************************************************************** - * @file UART/UART_WakeUpFromStopUsingFIFO/Src/stm32h7xx_hal_msp.c - * @author MCD Application Team - * @version V1.2.0 - * @date 29-December-2017 - * @brief HAL MSP module. - ****************************************************************************** - * @attention - * - *

© COPYRIGHT(c) 2017 STMicroelectronics

- * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. Neither the name of STMicroelectronics nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - ****************************************************************************** - */ +//! +//!***************************************************************************** +//! @file UART/UART_WakeUpFromStopUsingFIFO/Src/stm32h7xx_hal_msp.c +//! @author MCD Application Team +//! @version V1.2.0 +//! @date 29-December-2017 +//! @brief HAL MSP module. +//!***************************************************************************** +//! @attention +//! +//!

© COPYRIGHT(c) 2017 STMicroelectronics

+//! +//! Redistribution and use in source and binary forms, with or without modification, +//! are permitted provided that the following conditions are met: +//! 1. Redistributions of source code must retain the above copyright notice, +//! this list of conditions and the following disclaimer. +//! 2. Redistributions in binary form must reproduce the above copyright notice, +//! this list of conditions and the following disclaimer in the documentation +//! and/or other materials provided with the distribution. +//! 3. Neither the name of STMicroelectronics nor the names of its contributors +//! may be used to endorse or promote products derived from this software +//! without specific prior written permission. +//! +//! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +//! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +//! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +//! DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +//! FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +//! DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +//! SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +//! CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +//! OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +//! OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +//! +//!***************************************************************************** +//! -/* Includes ------------------------------------------------------------------*/ +// Includes ------------------------------------------------------------------ //#include "main.h" #include "stm32h7xx_hal.h" #include "stm32h7xx_nucleo_144.h" -/** @addtogroup STM32H7xx_HAL_Examples - * @{ - */ +//! @addtogroup STM32H7xx_HAL_Examples +//! @{ +//! -/** @defgroup HAL_MSP - * @brief HAL MSP module. - * @{ - */ +//! @defgroup HAL_MSP +//! @brief HAL MSP module. +//! @{ +//! -/* User can use this section to tailor USARTx/UARTx instance used and associated - resources */ -/* Definition for USARTx clock resources */ +// User can use this section to tailor USARTx/UARTx instance used and associated +// resources +// Definition for USARTx clock resources #define USARTx USART3 #define USARTx_CLK_ENABLE() __HAL_RCC_USART3_CLK_ENABLE() #define USARTx_RX_GPIO_CLK_ENABLE() __HAL_RCC_GPIOD_CLK_ENABLE() @@ -60,7 +60,7 @@ #define USARTx_FORCE_RESET() __HAL_RCC_USART3_FORCE_RESET() #define USARTx_RELEASE_RESET() __HAL_RCC_USART3_RELEASE_RESET() -/* Definition for USARTx Pins */ +// Definition for USARTx Pins #define USARTx_TX_PIN GPIO_PIN_8 #define USARTx_TX_GPIO_PORT GPIOD #define USARTx_TX_AF GPIO_AF7_USART3 @@ -68,58 +68,58 @@ #define USARTx_RX_GPIO_PORT GPIOD #define USARTx_RX_AF GPIO_AF7_USART3 -/** @addtogroup STM32F7xx_HAL_Examples - * @{ - */ +//! @addtogroup STM32F7xx_HAL_Examples +//! @{ +//! -/** @defgroup UART_TwoBoards_ComPolling - * @{ - */ +//! @defgroup UART_TwoBoards_ComPolling +//! @{ +//! -/* Private typedef -----------------------------------------------------------*/ -/* Private define ------------------------------------------------------------*/ -/* Private macro -------------------------------------------------------------*/ -/* Private variables ---------------------------------------------------------*/ -/* Private function prototypes -----------------------------------------------*/ -/* Private functions ---------------------------------------------------------*/ +// Private typedef ----------------------------------------------------------- +// Private define ------------------------------------------------------------ +// Private macro ------------------------------------------------------------- +// Private variables --------------------------------------------------------- +// Private function prototypes ----------------------------------------------- +// Private functions --------------------------------------------------------- -/** @defgroup HAL_MSP_Private_Functions - * @{ - */ +//! @defgroup HAL_MSP_Private_Functions +//! @{ +//! -/* NOTE: -* STM32Cube's initialization calls the weakly defiend HAL_InitTick(), which -* by default configures and starts the Systick interrupt. This is TOO EARLY, -* because the system os NOT ready yet to handle interrutps. -* To avoid problems, a dummy definition for HAL_InitTick() is provided -* in the fiel stm32l5xx_hal_msp.c. The SystTick is configured and -* started later in QF_onStartup(). -*/ +// NOTE: +// STM32Cube's initialization calls the weakly defiend HAL_InitTick(), which +// by default configures and starts the Systick interrupt. This is TOO EARLY, +// because the system os NOT ready yet to handle interrutps. +// To avoid problems, a dummy definition for HAL_InitTick() is provided +// in the fiel stm32l5xx_hal_msp.c. The SystTick is configured and +// started later in QF_onStartup(). +// HAL_StatusTypeDef HAL_InitTick(uint32_t TickPriority) { - (void)TickPriority; /* unused parameter */ + (void)TickPriority; // unused parameter return HAL_OK; } -/** - * @brief UART MSP Initialization - * This function configures the hardware resources used in this example: - * - Peripheral's clock enable - * - Peripheral's GPIO Configuration - * @param huart: UART handle pointer - * @retval None - */ +//! +//! @brief UART MSP Initialization +//! This function configures the hardware resources used in this example: +//! - Peripheral's clock enable +//! - Peripheral's GPIO Configuration +//! @param huart: UART handle pointer +//! @retval None +//! void HAL_UART_MspInit(UART_HandleTypeDef *huart) { - /*##-1- Enable peripherals and GPIO Clocks #################################*/ - /* Enable GPIO TX/RX clock */ + //##-1- Enable peripherals and GPIO Clocks ################################# + // Enable GPIO TX/RX clock USARTx_TX_GPIO_CLK_ENABLE(); USARTx_RX_GPIO_CLK_ENABLE(); - /* Enable USARTx clock */ + // Enable USARTx clock USARTx_CLK_ENABLE(); - /*##-2- Configure peripheral GPIO ##########################################*/ - /* UART TX GPIO pin configuration */ + //##-2- Configure peripheral GPIO ########################################## + // UART TX GPIO pin configuration GPIO_InitTypeDef GPIO_InitStruct; GPIO_InitStruct.Pin = USARTx_TX_PIN; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; @@ -128,67 +128,67 @@ void HAL_UART_MspInit(UART_HandleTypeDef *huart) { GPIO_InitStruct.Alternate = USARTx_TX_AF; HAL_GPIO_Init(USARTx_TX_GPIO_PORT, &GPIO_InitStruct); - /* UART RX GPIO pin configuration */ + // UART RX GPIO pin configuration GPIO_InitStruct.Pin = USARTx_RX_PIN; GPIO_InitStruct.Alternate = USARTx_RX_AF; HAL_GPIO_Init(USARTx_RX_GPIO_PORT, &GPIO_InitStruct); - /*##-3- Configure the NVIC for UART ########################################*/ - /* NVIC for USART */ - /* this is delayed till QF_onStartup() */ + //##-3- Configure the NVIC for UART ######################################## + // NVIC for USART + // this is delayed till QF_onStartup() } -/** - * @brief UART MSP De-Initialization - * This function frees the hardware resources used in this example: - * - Disable the Peripheral's clock - * - Revert GPIO and NVIC configuration to their default state - * @param huart: UART handle pointer - * @retval None - */ +//! +//! @brief UART MSP De-Initialization +//! This function frees the hardware resources used in this example: +//! - Disable the Peripheral's clock +//! - Revert GPIO and NVIC configuration to their default state +//! @param huart: UART handle pointer +//! @retval None +//! void HAL_UART_MspDeInit(UART_HandleTypeDef *huart) { - /*##-1- Reset peripherals ##################################################*/ + //##-1- Reset peripherals ################################################## USARTx_FORCE_RESET(); USARTx_RELEASE_RESET(); - /*##-2- Disable peripherals and GPIO Clocks ################################*/ - /* Configure USART Tx as alternate function */ + //##-2- Disable peripherals and GPIO Clocks ################################ + // Configure USART Tx as alternate function HAL_GPIO_DeInit(USARTx_TX_GPIO_PORT, USARTx_TX_PIN); - /* Configure USART Rx as alternate function */ + // Configure USART Rx as alternate function HAL_GPIO_DeInit(USARTx_RX_GPIO_PORT, USARTx_RX_PIN); - /*##-3- Disable the NVIC for UART ##########################################*/ - /* this is delayed till QF_onCleanup() */ + //##-3- Disable the NVIC for UART ########################################## + // this is delayed till QF_onCleanup() } -/* dummy legacy callacks for STM32CubeH7 */ +// dummy legacy callacks for STM32CubeH7 void HAL_UARTEx_RxFifoFullCallback(UART_HandleTypeDef *huart) { - (void)huart; /* unused parameter */ + (void)huart; // unused parameter } void HAL_UARTEx_TxFifoEmptyCallback(UART_HandleTypeDef *huart) { - (void)huart; /* unused parameter */ + (void)huart; // unused parameter } void HAL_UARTEx_WakeupCallback(UART_HandleTypeDef *huart) { - (void)huart; /* unused parameter */ + (void)huart; // unused parameter } void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) { - (void)huart; /* unused parameter */ + (void)huart; // unused parameter } -/** - * @} - */ +//! +//! @} +//! -/** - * @} - */ +//! +//! @} +//! -/** - * @} - */ +//! +//! @} +//! -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ +//*********************** (C) COPYRIGHT STMicroelectronics *****END OF FILE***** diff --git a/examples/freertos/arm-cm/dpp_nucleo-h743zi/table.c b/examples/freertos/arm-cm/dpp_nucleo-h743zi/table.c index b2345c2a..c3ae02f0 100644 --- a/examples/freertos/arm-cm/dpp_nucleo-h743zi/table.c +++ b/examples/freertos/arm-cm/dpp_nucleo-h743zi/table.c @@ -1,111 +1,120 @@ -/*$file${.::table.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* -* Model: dpp.qm -* File: ${.::table.c} -* -* This code has been generated by QM 5.2.4 . -* DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. -* -* SPDX-License-Identifier: GPL-3.0-or-later -* -* This generated code is open source software: you can redistribute it under -* the terms of the GNU General Public License as published by the Free -* Software Foundation. -* -* This code is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -* more details. -* -* NOTE: -* Alternatively, this generated code may be distributed under the terms -* of Quantum Leaps commercial licenses, which expressly supersede the GNU -* General Public License and are specifically designed for licensees -* interested in retaining the proprietary status of their code. -* -* Contact information: -* -* -*/ -/*$endhead${.::table.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -#include "qpc.h" -#include "dpp.h" -#include "bsp.h" +//$file${.::table.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// +// Model: dpp.qm +// File: ${.::table.c} +// +// This code has been generated by QM 5.3.0 . +// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. +// +// SPDX-License-Identifier: GPL-3.0-or-later +// +// This generated code is open source software: you can redistribute it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation. +// +// This code is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// NOTE: +// Alternatively, this generated code may be distributed under the terms +// of Quantum Leaps commercial licenses, which expressly supersede the GNU +// General Public License and are specifically designed for licensees +// interested in retaining the proprietary status of their code. +// +// Contact information: +// +// +// +//$endhead${.::table.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +#include "qpc.h" // QP/C real-time embedded framework +#include "dpp.h" // DPP Application interface +#include "bsp.h" // Board Support Package -Q_DEFINE_THIS_FILE +//$declare${AOs::Table} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/* Active object class -----------------------------------------------------*/ -/*$declare${AOs::Table} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${AOs::Table} ............................................................*/ -typedef struct { -/* protected: */ +//${AOs::Table} .............................................................. +typedef struct Table { +// protected: QActive super; -/* private: */ +// private: uint8_t fork[N_PHILO]; - uint8_t isHungry[N_PHILO]; + bool isHungry[N_PHILO]; + +// public: } Table; -/* protected: */ +extern Table Table_inst; + +// protected: static QState Table_initial(Table * const me, void const * const par); static QState Table_active(Table * const me, QEvt const * const e); static QState Table_serving(Table * const me, QEvt const * const e); static QState Table_paused(Table * const me, QEvt const * const e); -/*$enddecl${AOs::Table} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$enddecl${AOs::Table} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -#define RIGHT(n_) ((uint8_t)(((n_) + (N_PHILO - 1U)) % N_PHILO)) -#define LEFT(n_) ((uint8_t)(((n_) + 1U) % N_PHILO)) -#define FREE ((uint8_t)0) -#define USED ((uint8_t)1) +//---------------------------------------------------------------------------- +Q_DEFINE_THIS_FILE -/* Local objects -----------------------------------------------------------*/ -static Table l_table; /* the single instance of the Table active object */ +// helper function to provide the RIGHT neighbor of a Philo[n] +static inline uint8_t right(uint8_t const n) { + return (uint8_t)((n + (N_PHILO - 1U)) % N_PHILO); +} -/* Global-scope objects ----------------------------------------------------*/ -QActive * const AO_Table = &l_table.super; /* "opaque" AO pointer */ +// helper function to provide the LEFT neighbor of a Philo[n] +static inline uint8_t left(uint8_t const n) { + return (uint8_t)((n + 1U) % N_PHILO); +} -/*..........................................................................*/ -/*$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* Check for the minimum required QP version */ -#if (QP_VERSION < 700U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) -#error qpc version 7.0.0 or higher required +#define FREE ((uint8_t)0U) +#define USED ((uint8_t)1U) + +#define THINKING "thinking" +#define HUNGRY "hungry " +#define EATING "eating " + +//---------------------------------------------------------------------------- + +//$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// Check for the minimum required QP version +#if (QP_VERSION < 730U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) +#error qpc version 7.3.0 or higher required #endif -/*$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -/*$define${AOs::Table_ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//$define${Shared::Table_ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/*${AOs::Table_ctor} .......................................................*/ +//${Shared::Table_ctor} ...................................................... void Table_ctor(void) { - uint8_t n; - Table *me = &l_table; - + Table * const me = &Table_inst; QActive_ctor(&me->super, Q_STATE_CAST(&Table_initial)); - - for (n = 0U; n < N_PHILO; ++n) { + for (uint8_t n = 0U; n < N_PHILO; ++n) { me->fork[n] = FREE; - me->isHungry[n] = 0U; + me->isHungry[n] = false; } } -/*$enddef${AOs::Table_ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*$define${AOs::Table} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//$enddef${Shared::Table_ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +//$define${Shared::AO_Table} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/*${AOs::Table} ............................................................*/ +//${Shared::AO_Table} ........................................................ +QActive * const AO_Table = &Table_inst.super; +//$enddef${Shared::AO_Table} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +//$define${AOs::Table} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/*${AOs::Table::SM} ........................................................*/ +//${AOs::Table} .............................................................. +Table Table_inst; + +//${AOs::Table::SM} .......................................................... static QState Table_initial(Table * const me, void const * const par) { - /*${AOs::Table::SM::initial} */ - (void)par; /* unused parameter */ + //${AOs::Table::SM::initial} + Q_UNUSED_PAR(par); - QS_OBJ_DICTIONARY(&l_table); - - QS_SIG_DICTIONARY(DONE_SIG, (void *)0); /* global signals */ - QS_SIG_DICTIONARY(EAT_SIG, (void *)0); - QS_SIG_DICTIONARY(PAUSE_SIG, (void *)0); - QS_SIG_DICTIONARY(SERVE_SIG, (void *)0); - QS_SIG_DICTIONARY(TEST_SIG, (void *)0); - - QS_SIG_DICTIONARY(HUNGRY_SIG, me); /* signal just for Table */ + #ifdef Q_SPY + Table *Table_inst = me; + QS_OBJ_DICTIONARY(Table_inst); + #endif QActive_subscribe(&me->super, DONE_SIG); QActive_subscribe(&me->super, PAUSE_SIG); @@ -114,22 +123,27 @@ static QState Table_initial(Table * const me, void const * const par) { for (uint8_t n = 0U; n < N_PHILO; ++n) { me->fork[n] = FREE; - me->isHungry[n] = 0U; - BSP_displayPhilStat(n, "thinking"); + me->isHungry[n] = false; + BSP_displayPhilStat(n, THINKING); } + + QS_FUN_DICTIONARY(&Table_active); + QS_FUN_DICTIONARY(&Table_serving); + QS_FUN_DICTIONARY(&Table_paused); + return Q_TRAN(&Table_serving); } -/*${AOs::Table::SM::active} ................................................*/ +//${AOs::Table::SM::active} .................................................. static QState Table_active(Table * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${AOs::Table::SM::active::TEST} */ + //${AOs::Table::SM::active::TEST} case TEST_SIG: { status_ = Q_HANDLED(); break; } - /*${AOs::Table::SM::active::EAT} */ + //${AOs::Table::SM::active::EAT} case EAT_SIG: { Q_ERROR(); status_ = Q_HANDLED(); @@ -143,108 +157,119 @@ static QState Table_active(Table * const me, QEvt const * const e) { return status_; } -/*${AOs::Table::SM::active::serving} .......................................*/ +//${AOs::Table::SM::active::serving} ......................................... static QState Table_serving(Table * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${AOs::Table::SM::active::serving} */ + //${AOs::Table::SM::active::serving} case Q_ENTRY_SIG: { - uint8_t n; - for (n = 0U; n < N_PHILO; ++n) { /* give permissions to eat... */ - if ((me->isHungry[n] != 0U) - && (me->fork[LEFT(n)] == FREE) + // give permissions to eat... + for (uint8_t n = 0U; n < N_PHILO; ++n) { + if (me->isHungry[n] + && (me->fork[left(n)] == FREE) && (me->fork[n] == FREE)) { - TableEvt *te; - - me->fork[LEFT(n)] = USED; + me->fork[left(n)] = USED; me->fork[n] = USED; - te = Q_NEW(TableEvt, EAT_SIG); - te->philoNum = n; - QACTIVE_PUBLISH(&te->super, &me->super); - me->isHungry[n] = 0U; - BSP_displayPhilStat(n, "eating "); + #ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, EAT_SIG, n); + #else + TableEvt *pe = Q_NEW(TableEvt, EAT_SIG); + pe->philoId = n; + #endif + QACTIVE_PUBLISH(&pe->super, &me->super); + me->isHungry[n] = false; + BSP_displayPhilStat(n, EATING); } } status_ = Q_HANDLED(); break; } - /*${AOs::Table::SM::active::serving::HUNGRY} */ + //${AOs::Table::SM::active::serving::HUNGRY} case HUNGRY_SIG: { - uint8_t n, m; + uint8_t n = Q_EVT_CAST(TableEvt)->philoId; - n = Q_EVT_CAST(TableEvt)->philoNum; - /* phil ID must be in range and he must be not hungry */ - Q_ASSERT((n < N_PHILO) && (me->isHungry[n] == 0U)); + // phil ID must be in range and he must be not hungry + Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); - BSP_displayPhilStat(n, "hungry "); - m = LEFT(n); - /*${AOs::Table::SM::active::serving::HUNGRY::[bothfree]} */ + BSP_displayPhilStat(n, HUNGRY); + uint8_t m = left(n); + //${AOs::Table::SM::active::serving::HUNGRY::[bothfree]} if ((me->fork[m] == FREE) && (me->fork[n] == FREE)) { - TableEvt *pe; me->fork[m] = USED; me->fork[n] = USED; - pe = Q_NEW(TableEvt, EAT_SIG); - pe->philoNum = n; + #ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, EAT_SIG, n); + #else + TableEvt *pe = Q_NEW(TableEvt, EAT_SIG); + pe->philoId = n; + #endif QACTIVE_PUBLISH(&pe->super, &me->super); - BSP_displayPhilStat(n, "eating "); + BSP_displayPhilStat(n, EATING); status_ = Q_HANDLED(); } - /*${AOs::Table::SM::active::serving::HUNGRY::[else]} */ + //${AOs::Table::SM::active::serving::HUNGRY::[else]} else { - me->isHungry[n] = 1U; + me->isHungry[n] = true; status_ = Q_HANDLED(); } break; } - /*${AOs::Table::SM::active::serving::DONE} */ + //${AOs::Table::SM::active::serving::DONE} case DONE_SIG: { - uint8_t n, m; - TableEvt *pe; + uint8_t n = Q_EVT_CAST(TableEvt)->philoId; - n = Q_EVT_CAST(TableEvt)->philoNum; - /* phil ID must be in range and he must be not hungry */ - Q_ASSERT((n < N_PHILO) && (me->isHungry[n] == 0U)); + // phil ID must be in range and he must be not hungry + Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); - BSP_displayPhilStat(n, "thinking"); - m = LEFT(n); - /* both forks of Phil[n] must be used */ + BSP_displayPhilStat(n, THINKING); + uint8_t m = left(n); + + // both forks of Phil[n] must be used Q_ASSERT((me->fork[n] == USED) && (me->fork[m] == USED)); me->fork[m] = FREE; me->fork[n] = FREE; - m = RIGHT(n); /* check the right neighbor */ + m = right(n); // check the right neighbor - if ((me->isHungry[m] != 0U) && (me->fork[m] == FREE)) { + if (me->isHungry[m] && (me->fork[m] == FREE)) { me->fork[n] = USED; me->fork[m] = USED; - me->isHungry[m] = 0U; - pe = Q_NEW(TableEvt, EAT_SIG); - pe->philoNum = m; + me->isHungry[m] = false; + #ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, EAT_SIG, m); + #else + TableEvt *pe = Q_NEW(TableEvt, EAT_SIG); + pe->philoId = m; + #endif QACTIVE_PUBLISH(&pe->super, &me->super); - BSP_displayPhilStat(m, "eating "); + BSP_displayPhilStat(m, EATING); } - m = LEFT(n); /* check the left neighbor */ - n = LEFT(m); /* left fork of the left neighbor */ - if ((me->isHungry[m] != 0U) && (me->fork[n] == FREE)) { + m = left(n); // check the left neighbor + n = left(m); // left fork of the left neighbor + if (me->isHungry[m] && (me->fork[n] == FREE)) { me->fork[m] = USED; me->fork[n] = USED; - me->isHungry[m] = 0U; - pe = Q_NEW(TableEvt, EAT_SIG); - pe->philoNum = m; + me->isHungry[m] = false; + #ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, EAT_SIG, m); + #else + TableEvt *pe = Q_NEW(TableEvt, EAT_SIG); + pe->philoId = m; + #endif QACTIVE_PUBLISH(&pe->super, &me->super); - BSP_displayPhilStat(m, "eating "); + BSP_displayPhilStat(m, EATING); } status_ = Q_HANDLED(); break; } - /*${AOs::Table::SM::active::serving::EAT} */ + //${AOs::Table::SM::active::serving::EAT} case EAT_SIG: { Q_ERROR(); status_ = Q_HANDLED(); break; } - /*${AOs::Table::SM::active::serving::PAUSE} */ + //${AOs::Table::SM::active::serving::PAUSE} case PAUSE_SIG: { status_ = Q_TRAN(&Table_paused); break; @@ -257,48 +282,50 @@ static QState Table_serving(Table * const me, QEvt const * const e) { return status_; } -/*${AOs::Table::SM::active::paused} ........................................*/ +//${AOs::Table::SM::active::paused} .......................................... static QState Table_paused(Table * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${AOs::Table::SM::active::paused} */ + //${AOs::Table::SM::active::paused} case Q_ENTRY_SIG: { BSP_displayPaused(1U); status_ = Q_HANDLED(); break; } - /*${AOs::Table::SM::active::paused} */ + //${AOs::Table::SM::active::paused} case Q_EXIT_SIG: { BSP_displayPaused(0U); status_ = Q_HANDLED(); break; } - /*${AOs::Table::SM::active::paused::SERVE} */ + //${AOs::Table::SM::active::paused::SERVE} case SERVE_SIG: { status_ = Q_TRAN(&Table_serving); break; } - /*${AOs::Table::SM::active::paused::HUNGRY} */ + //${AOs::Table::SM::active::paused::HUNGRY} case HUNGRY_SIG: { - uint8_t n = Q_EVT_CAST(TableEvt)->philoNum; - /* philo ID must be in range and he must be not hungry */ - Q_ASSERT((n < N_PHILO) && (me->isHungry[n] == 0U)); - me->isHungry[n] = 1U; - BSP_displayPhilStat(n, "hungry "); + uint8_t n = Q_EVT_CAST(TableEvt)->philoId; + + // philo ID must be in range and he must be not hungry + Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); + + me->isHungry[n] = true; + BSP_displayPhilStat(n, HUNGRY); status_ = Q_HANDLED(); break; } - /*${AOs::Table::SM::active::paused::DONE} */ + //${AOs::Table::SM::active::paused::DONE} case DONE_SIG: { - uint8_t n, m; + uint8_t n = Q_EVT_CAST(TableEvt)->philoId; - n = Q_EVT_CAST(TableEvt)->philoNum; - /* phil ID must be in range and he must be not hungry */ - Q_ASSERT((n < N_PHILO) && (me->isHungry[n] == 0U)); + // phil ID must be in range and he must be not hungry + Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); - BSP_displayPhilStat(n, "thinking"); - m = LEFT(n); - /* both forks of Phil[n] must be used */ + BSP_displayPhilStat(n, THINKING); + uint8_t m = left(n); + + // both forks of Phil[n] must be used Q_ASSERT((me->fork[n] == USED) && (me->fork[m] == USED)); me->fork[m] = FREE; @@ -313,4 +340,4 @@ static QState Table_paused(Table * const me, QEvt const * const e) { } return status_; } -/*$enddef${AOs::Table} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$enddef${AOs::Table} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/examples/lwip/arm-cm/lwip_ek-lm3s6965/bsp.h b/examples/lwip/arm-cm/lwip_ek-lm3s6965/bsp.h index dd103a6f..a1106f86 100644 --- a/examples/lwip/arm-cm/lwip_ek-lm3s6965/bsp.h +++ b/examples/lwip/arm-cm/lwip_ek-lm3s6965/bsp.h @@ -1,32 +1,32 @@ -/***************************************************************************** -* Product: BSP for DPP application with lwIP on EV-LM3S9665 board -* Last Updated for Version: 4.1.03 -* Date of the Last Update: Mar 05, 2010 -* -* Q u a n t u m L e a P s -* --------------------------- -* innovating embedded systems -* -* Copyright (C)-2010 Quantum Leaps, LLC. All rights reserved. -* -* This software may be distributed and modified under the terms of the GNU -* General Public License version 2 (GPL) as published by the Free Software -* Foundation and appearing in the file GPL.TXT included in the packaging of -* this file. Please note that GPL Section 2[b] requires that all works based -* on this software must also be made publicly available under the terms of -* the GPL ("Copyleft"). -* -* Alternatively, this software may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GPL and are specifically designed for licensees interested in -* retaining the proprietary status of their code. -* -* Contact information: -* Quantum Leaps Web site: http://www.quantum-leaps.com -* e-mail: info@quantum-leaps.com -*****************************************************************************/ -#ifndef BSP_H -#define BSP_H +//============================================================================ +// Product: BSP for DPP application with lwIP on EV-LM3S9665 board +// Last Updated for Version: 4.1.03 +// Date of the Last Update: Mar 05, 2010 +// +// Q u a n t u m L e a P s +// --------------------------- +// innovating embedded systems +// +// Copyright (C)-2010 Quantum Leaps, LLC. All rights reserved. +// +// This software may be distributed and modified under the terms of the GNU +// General Public License version 2 (GPL) as published by the Free Software +// Foundation and appearing in the file GPL.TXT included in the packaging of +// this file. Please note that GPL Section 2[b] requires that all works based +// on this software must also be made publicly available under the terms of +// the GPL ("Copyleft"). +// +// Alternatively, this software may be distributed and modified under the +// terms of Quantum Leaps commercial licenses, which expressly supersede +// the GPL and are specifically designed for licensees interested in +// retaining the proprietary status of their code. +// +// Contact information: +// Quantum Leaps Web site: http://www.quantum-leaps.com +// e-mail: info@quantum-leaps.com +//============================================================================ +#ifndef BSP_H_ +#define BSP_H_ #define BSP_TICKS_PER_SEC 100 @@ -38,4 +38,4 @@ void ISR_Nmi(void); void ISR_Fault(void); void ISR_DefaultHandler(void); -#endif /* BSP_H */ +#endif // BSP_H_ diff --git a/examples/lwip/arm-cm/lwip_ek-lm3s6965/dpp.h b/examples/lwip/arm-cm/lwip_ek-lm3s6965/dpp.h index df379b31..dc4aaa59 100644 --- a/examples/lwip/arm-cm/lwip_ek-lm3s6965/dpp.h +++ b/examples/lwip/arm-cm/lwip_ek-lm3s6965/dpp.h @@ -1,79 +1,79 @@ -/***************************************************************************** -* Product: DPP example with lwIP -* Last Updated for Version: 5.1.1 -* Date of the Last Update: Oct 20, 2013 -* -* Q u a n t u m L e a P s -* --------------------------- -* innovating embedded systems -* -* Copyright (C)-2013 Quantum Leaps, LLC. All rights reserved. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* Quantum Leaps Web sites: http://www.quantum-leaps.com -* -* e-mail: info@quantum-leaps.com -*****************************************************************************/ +//============================================================================ +// Product: DPP example with lwIP +// Last Updated for Version: 5.1.1 +// Date of the Last Update: Oct 20, 2013 +// +// Q u a n t u m L e a P s +// --------------------------- +// innovating embedded systems +// +// Copyright (C)-2013 Quantum Leaps, LLC. All rights reserved. +// +// This program is open source software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Alternatively, this program may be distributed and modified under the +// terms of Quantum Leaps commercial licenses, which expressly supersede +// the GNU General Public License and are specifically designed for +// licensees interested in retaining the proprietary status of their code. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Contact information: +// Quantum Leaps Web sites: http://www.quantum-leaps.com +// +// e-mail: info@quantum-leaps.com +//============================================================================ #ifndef DPP_H #define DPP_H enum DPPSignals { - EAT_SIG = Q_USER_SIG, /* published by Table to let a philosopher eat */ - DONE_SIG, /* published by Philosopher when done eating */ - BTN_DOWN_SIG, /* published by ISR_SysTick when user button is pressed */ - BTN_UP_SIG, /* published by ISR_SysTick when user button is released */ + EAT_SIG = Q_USER_SIG, // published by Table to let a philosopher eat + DONE_SIG, // published by Philosopher when done eating + BTN_DOWN_SIG, // published by ISR_SysTick when user button is pressed + BTN_UP_SIG, // published by ISR_SysTick when user button is released - DISPLAY_IPADDR_SIG, /* published by lwIPMgr to display IP addres */ - DISPLAY_CGI_SIG, /* published by lwIPMgr to display CGI text */ - DISPLAY_UDP_SIG, /* published by lwIPMgr to display UDP text */ - MAX_PUB_SIG, /* the last published signal */ + DISPLAY_IPADDR_SIG, // published by lwIPMgr to display IP addres + DISPLAY_CGI_SIG, // published by lwIPMgr to display CGI text + DISPLAY_UDP_SIG, // published by lwIPMgr to display UDP text + MAX_PUB_SIG, // the last published signal - HUNGRY_SIG, /* posted direclty to Table from hungry Philosopher */ - SEND_UDP_SIG, /* posted directly to lwIPMgr to send text via UDP */ - LWIP_DRIVER_GROUP, /* LwIP driver signal group */ - LWIP_DRIVER_END = LWIP_DRIVER_GROUP + 10, /* reserve 10 signals */ - LWIP_SLOW_TICK_SIG, /* slow tick signal for LwIP manager */ - MAX_SIG /* the last signal */ + HUNGRY_SIG, // posted direclty to Table from hungry Philosopher + SEND_UDP_SIG, // posted directly to lwIPMgr to send text via UDP + LWIP_DRIVER_GROUP, // LwIP driver signal group + LWIP_DRIVER_END = LWIP_DRIVER_GROUP + 10, // reserve 10 signals + LWIP_SLOW_TICK_SIG, // slow tick signal for LwIP manager + MAX_SIG // the last signal }; typedef struct TableEvtTag { - QEvt super; /* derives from QEvt */ - uint8_t philoNum; /* philosopher number */ + QEvt super; // derives from QEvt + uint8_t philoNum; // philosopher number } TableEvt; #define MAX_TEXT_LEN 16 typedef struct TextEvtTag { - QEvt super; /* derives from QEvt */ - char text[MAX_TEXT_LEN]; /* text to deliver */ + QEvt super; // derives from QEvt + char text[MAX_TEXT_LEN]; // text to deliver } TextEvt; - /* number of philosophers */ + // number of philosophers #define N_PHILO 5 void Philo_ctor(void); void Table_ctor(void); void LwIPMgr_ctor(void); -extern QActive * const AO_Philo[N_PHILO]; /* "opaque" pointers to Philo AO */ -extern QActive * const AO_Table; /* "opaque" pointer to Table AO */ -extern QActive * const AO_LwIPMgr; /* "opaque" pointer to LwIPMgr AO */ +extern QActive * const AO_Philo[N_PHILO]; // "opaque" pointers to Philo AO +extern QActive * const AO_Table; // "opaque" pointer to Table AO +extern QActive * const AO_LwIPMgr; // "opaque" pointer to LwIPMgr AO -#endif /* DPP_H */ +#endif // DPP_H diff --git a/examples/lwip/arm-cm/lwip_ek-lm3s6965/ek-lm3s6965.jpg b/examples/lwip/arm-cm/lwip_ek-lm3s6965/ek-lm3s6965.jpg new file mode 100644 index 00000000..61113074 Binary files /dev/null and b/examples/lwip/arm-cm/lwip_ek-lm3s6965/ek-lm3s6965.jpg differ diff --git a/examples/lwip/arm-cm/lwip_ek-lm3s6965/fsdata.h b/examples/lwip/arm-cm/lwip_ek-lm3s6965/fsdata.h index 7e2eee51..4e987314 100644 --- a/examples/lwip/arm-cm/lwip_ek-lm3s6965/fsdata.h +++ b/examples/lwip/arm-cm/lwip_ek-lm3s6965/fsdata.h @@ -1,10 +1,10 @@ -/* This file has been generated with the qfsgen utility. */ +// This file has been generated with the qfsgen utility. -/* /404.htm */ +// /404.htm static unsigned char const data_404_htm[] = { - /* name: */ + // name: 0x2F, 0x34, 0x30, 0x34, 0x2E, 0x68, 0x74, 0x6D, 0x00, - /* HTTP header: */ + // HTTP header: 0x48, 0x54, 0x54, 0x50, 0x2F, 0x31, 0x2E, 0x30, 0x20, 0x34, 0x30, 0x34, 0x20, 0x46, 0x69, 0x6C, 0x65, 0x20, 0x6E, 0x6F, 0x74, 0x20, 0x66, 0x6F, 0x75, 0x6E, 0x64, 0x0D, 0x0A, 0x53, @@ -15,7 +15,7 @@ static unsigned char const data_404_htm[] = { 0x6F, 0x6E, 0x74, 0x65, 0x6E, 0x74, 0x2D, 0x74, 0x79, 0x70, 0x65, 0x3A, 0x20, 0x74, 0x65, 0x78, 0x74, 0x2F, 0x68, 0x74, 0x6D, 0x6C, 0x0D, 0x0A, 0x0D, 0x0A, - /* data: */ + // data: 0x3C, 0x21, 0x44, 0x4F, 0x43, 0x54, 0x59, 0x50, 0x45, 0x20, 0x68, 0x74, 0x6D, 0x6C, 0x20, 0x50, 0x55, 0x42, 0x4C, 0x49, 0x43, 0x20, 0x22, 0x2D, 0x2F, 0x2F, 0x57, 0x33, 0x43, 0x2F, @@ -79,12 +79,12 @@ struct fsdata_file const file_404_htm[] = { } }; -/* /bg_footer.gif */ +// /bg_footer.gif static unsigned char const data_bg_footer_gif[] = { - /* name: */ + // name: 0x2F, 0x62, 0x67, 0x5F, 0x66, 0x6F, 0x6F, 0x74, 0x65, 0x72, 0x2E, 0x67, 0x69, 0x66, 0x00, - /* HTTP header: */ + // HTTP header: 0x48, 0x54, 0x54, 0x50, 0x2F, 0x31, 0x2E, 0x30, 0x20, 0x32, 0x30, 0x30, 0x20, 0x4F, 0x4B, 0x0D, 0x0A, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x3A, 0x20, 0x51, 0x4C, 0x20, 0x28, 0x68, @@ -94,7 +94,7 @@ static unsigned char const data_bg_footer_gif[] = { 0x74, 0x65, 0x6E, 0x74, 0x2D, 0x74, 0x79, 0x70, 0x65, 0x3A, 0x20, 0x69, 0x6D, 0x61, 0x67, 0x65, 0x2F, 0x67, 0x69, 0x66, 0x0D, 0x0A, 0x0D, 0x0A, - /* data: */ + // data: 0x47, 0x49, 0x46, 0x38, 0x39, 0x61, 0xD4, 0x03, 0x08, 0x00, 0xD5, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFB, 0xFB, 0xFB, 0xFC, 0xFC, 0xFC, 0xF7, 0xF7, 0xF7, 0xF1, 0xF1, 0xF1, 0xF9, 0xF9, @@ -195,12 +195,12 @@ struct fsdata_file const file_bg_footer_gif[] = { } }; -/* /cgi_demo.htm */ +// /cgi_demo.htm static unsigned char const data_cgi_demo_htm[] = { - /* name: */ + // name: 0x2F, 0x63, 0x67, 0x69, 0x5F, 0x64, 0x65, 0x6D, 0x6F, 0x2E, 0x68, 0x74, 0x6D, 0x00, - /* HTTP header: */ + // HTTP header: 0x48, 0x54, 0x54, 0x50, 0x2F, 0x31, 0x2E, 0x30, 0x20, 0x32, 0x30, 0x30, 0x20, 0x4F, 0x4B, 0x0D, 0x0A, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x3A, 0x20, 0x51, 0x4C, 0x20, 0x28, 0x68, @@ -210,7 +210,7 @@ static unsigned char const data_cgi_demo_htm[] = { 0x74, 0x65, 0x6E, 0x74, 0x2D, 0x74, 0x79, 0x70, 0x65, 0x3A, 0x20, 0x74, 0x65, 0x78, 0x74, 0x2F, 0x68, 0x74, 0x6D, 0x6C, 0x0D, 0x0A, 0x0D, 0x0A, - /* data: */ + // data: 0x3C, 0x21, 0x44, 0x4F, 0x43, 0x54, 0x59, 0x50, 0x45, 0x20, 0x68, 0x74, 0x6D, 0x6C, 0x20, 0x50, 0x55, 0x42, 0x4C, 0x49, 0x43, 0x20, 0x22, 0x2D, 0x2F, 0x2F, 0x57, 0x33, 0x43, 0x2F, @@ -704,13 +704,13 @@ struct fsdata_file const file_cgi_demo_htm[] = { } }; -/* /img/AN_QP_and_lwIP.jpg */ +// /img/AN_QP_and_lwIP.jpg static unsigned char const data_img_AN_QP_and_lwIP_jpg[] = { - /* name: */ + // name: 0x2F, 0x69, 0x6D, 0x67, 0x2F, 0x41, 0x4E, 0x5F, 0x51, 0x50, 0x5F, 0x61, 0x6E, 0x64, 0x5F, 0x6C, 0x77, 0x49, 0x50, 0x2E, 0x6A, 0x70, 0x67, 0x00, - /* HTTP header: */ + // HTTP header: 0x48, 0x54, 0x54, 0x50, 0x2F, 0x31, 0x2E, 0x30, 0x20, 0x32, 0x30, 0x30, 0x20, 0x4F, 0x4B, 0x0D, 0x0A, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x3A, 0x20, 0x51, 0x4C, 0x20, 0x28, 0x68, @@ -720,7 +720,7 @@ static unsigned char const data_img_AN_QP_and_lwIP_jpg[] = { 0x74, 0x65, 0x6E, 0x74, 0x2D, 0x74, 0x79, 0x70, 0x65, 0x3A, 0x20, 0x69, 0x6D, 0x61, 0x67, 0x65, 0x2F, 0x6A, 0x70, 0x65, 0x67, 0x0D, 0x0A, 0x0D, 0x0A, - /* data: */ + // data: 0xFF, 0xD8, 0xFF, 0xE0, 0x00, 0x10, 0x4A, 0x46, 0x49, 0x46, 0x00, 0x01, 0x02, 0x00, 0x00, 0x64, 0x00, 0x64, 0x00, 0x00, 0xFF, 0xEC, 0x00, 0x11, 0x44, 0x75, 0x63, 0x6B, 0x79, 0x00, @@ -1489,12 +1489,12 @@ struct fsdata_file const file_img_AN_QP_and_lwIP_jpg[] = { } }; -/* /img/arrow.gif */ +// /img/arrow.gif static unsigned char const data_img_arrow_gif[] = { - /* name: */ + // name: 0x2F, 0x69, 0x6D, 0x67, 0x2F, 0x61, 0x72, 0x72, 0x6F, 0x77, 0x2E, 0x67, 0x69, 0x66, 0x00, - /* HTTP header: */ + // HTTP header: 0x48, 0x54, 0x54, 0x50, 0x2F, 0x31, 0x2E, 0x30, 0x20, 0x32, 0x30, 0x30, 0x20, 0x4F, 0x4B, 0x0D, 0x0A, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x3A, 0x20, 0x51, 0x4C, 0x20, 0x28, 0x68, @@ -1504,7 +1504,7 @@ static unsigned char const data_img_arrow_gif[] = { 0x74, 0x65, 0x6E, 0x74, 0x2D, 0x74, 0x79, 0x70, 0x65, 0x3A, 0x20, 0x69, 0x6D, 0x61, 0x67, 0x65, 0x2F, 0x67, 0x69, 0x66, 0x0D, 0x0A, 0x0D, 0x0A, - /* data: */ + // data: 0x47, 0x49, 0x46, 0x38, 0x39, 0x61, 0x07, 0x00, 0x09, 0x00, 0x80, 0x01, 0x00, 0x00, 0x33, 0xCC, 0xFF, 0xFF, 0xFF, 0x21, 0xF9, 0x04, 0x01, 0x00, 0x00, 0x01, 0x00, 0x2C, 0x00, 0x00, @@ -1522,12 +1522,12 @@ struct fsdata_file const file_img_arrow_gif[] = { } }; -/* /img/favicon.ico */ +// /img/favicon.ico static unsigned char const data_img_favicon_ico[] = { - /* name: */ + // name: 0x2F, 0x69, 0x6D, 0x67, 0x2F, 0x66, 0x61, 0x76, 0x69, 0x63, 0x6F, 0x6E, 0x2E, 0x69, 0x63, 0x6F, 0x00, - /* HTTP header: */ + // HTTP header: 0x48, 0x54, 0x54, 0x50, 0x2F, 0x31, 0x2E, 0x30, 0x20, 0x32, 0x30, 0x30, 0x20, 0x4F, 0x4B, 0x0D, 0x0A, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x3A, 0x20, 0x51, 0x4C, 0x20, 0x28, 0x68, @@ -1537,7 +1537,7 @@ static unsigned char const data_img_favicon_ico[] = { 0x74, 0x65, 0x6E, 0x74, 0x2D, 0x74, 0x79, 0x70, 0x65, 0x3A, 0x20, 0x74, 0x65, 0x78, 0x74, 0x2F, 0x70, 0x6C, 0x61, 0x69, 0x6E, 0x0D, 0x0A, 0x0D, 0x0A, - /* data: */ + // data: 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x68, 0x05, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, @@ -1690,12 +1690,12 @@ struct fsdata_file const file_img_favicon_ico[] = { } }; -/* /img/footer.jpg */ +// /img/footer.jpg static unsigned char const data_img_footer_jpg[] = { - /* name: */ + // name: 0x2F, 0x69, 0x6D, 0x67, 0x2F, 0x66, 0x6F, 0x6F, 0x74, 0x65, 0x72, 0x2E, 0x6A, 0x70, 0x67, 0x00, - /* HTTP header: */ + // HTTP header: 0x48, 0x54, 0x54, 0x50, 0x2F, 0x31, 0x2E, 0x30, 0x20, 0x32, 0x30, 0x30, 0x20, 0x4F, 0x4B, 0x0D, 0x0A, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x3A, 0x20, 0x51, 0x4C, 0x20, 0x28, 0x68, @@ -1705,7 +1705,7 @@ static unsigned char const data_img_footer_jpg[] = { 0x74, 0x65, 0x6E, 0x74, 0x2D, 0x74, 0x79, 0x70, 0x65, 0x3A, 0x20, 0x69, 0x6D, 0x61, 0x67, 0x65, 0x2F, 0x6A, 0x70, 0x65, 0x67, 0x0D, 0x0A, 0x0D, 0x0A, - /* data: */ + // data: 0xFF, 0xD8, 0xFF, 0xE0, 0x00, 0x10, 0x4A, 0x46, 0x49, 0x46, 0x00, 0x01, 0x02, 0x00, 0x00, 0x64, 0x00, 0x64, 0x00, 0x00, 0xFF, 0xEC, 0x00, 0x11, 0x44, 0x75, 0x63, 0x6B, 0x79, 0x00, @@ -1755,13 +1755,13 @@ struct fsdata_file const file_img_footer_jpg[] = { } }; -/* /img/logo_lwip_qp.jpg */ +// /img/logo_lwip_qp.jpg static unsigned char const data_img_logo_lwip_qp_jpg[] = { - /* name: */ + // name: 0x2F, 0x69, 0x6D, 0x67, 0x2F, 0x6C, 0x6F, 0x67, 0x6F, 0x5F, 0x6C, 0x77, 0x69, 0x70, 0x5F, 0x71, 0x70, 0x2E, 0x6A, 0x70, 0x67, 0x00, - /* HTTP header: */ + // HTTP header: 0x48, 0x54, 0x54, 0x50, 0x2F, 0x31, 0x2E, 0x30, 0x20, 0x32, 0x30, 0x30, 0x20, 0x4F, 0x4B, 0x0D, 0x0A, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x3A, 0x20, 0x51, 0x4C, 0x20, 0x28, 0x68, @@ -1771,7 +1771,7 @@ static unsigned char const data_img_logo_lwip_qp_jpg[] = { 0x74, 0x65, 0x6E, 0x74, 0x2D, 0x74, 0x79, 0x70, 0x65, 0x3A, 0x20, 0x69, 0x6D, 0x61, 0x67, 0x65, 0x2F, 0x6A, 0x70, 0x65, 0x67, 0x0D, 0x0A, 0x0D, 0x0A, - /* data: */ + // data: 0xFF, 0xD8, 0xFF, 0xE0, 0x00, 0x10, 0x4A, 0x46, 0x49, 0x46, 0x00, 0x01, 0x02, 0x00, 0x00, 0x64, 0x00, 0x64, 0x00, 0x00, 0xFF, 0xEC, 0x00, 0x11, 0x44, 0x75, 0x63, 0x6B, 0x79, 0x00, @@ -2274,12 +2274,12 @@ struct fsdata_file const file_img_logo_lwip_qp_jpg[] = { } }; -/* /img/logo_ql.jpg */ +// /img/logo_ql.jpg static unsigned char const data_img_logo_ql_jpg[] = { - /* name: */ + // name: 0x2F, 0x69, 0x6D, 0x67, 0x2F, 0x6C, 0x6F, 0x67, 0x6F, 0x5F, 0x71, 0x6C, 0x2E, 0x6A, 0x70, 0x67, 0x00, - /* HTTP header: */ + // HTTP header: 0x48, 0x54, 0x54, 0x50, 0x2F, 0x31, 0x2E, 0x30, 0x20, 0x32, 0x30, 0x30, 0x20, 0x4F, 0x4B, 0x0D, 0x0A, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x3A, 0x20, 0x51, 0x4C, 0x20, 0x28, 0x68, @@ -2289,7 +2289,7 @@ static unsigned char const data_img_logo_ql_jpg[] = { 0x74, 0x65, 0x6E, 0x74, 0x2D, 0x74, 0x79, 0x70, 0x65, 0x3A, 0x20, 0x69, 0x6D, 0x61, 0x67, 0x65, 0x2F, 0x6A, 0x70, 0x65, 0x67, 0x0D, 0x0A, 0x0D, 0x0A, - /* data: */ + // data: 0xFF, 0xD8, 0xFF, 0xE0, 0x00, 0x10, 0x4A, 0x46, 0x49, 0x46, 0x00, 0x01, 0x02, 0x00, 0x00, 0x64, 0x00, 0x64, 0x00, 0x00, 0xFF, 0xEC, 0x00, 0x11, 0x44, 0x75, 0x63, 0x6B, 0x79, 0x00, @@ -3268,12 +3268,12 @@ struct fsdata_file const file_img_logo_ql_jpg[] = { } }; -/* /img/logo_sics.gif */ +// /img/logo_sics.gif static unsigned char const data_img_logo_sics_gif[] = { - /* name: */ + // name: 0x2F, 0x69, 0x6D, 0x67, 0x2F, 0x6C, 0x6F, 0x67, 0x6F, 0x5F, 0x73, 0x69, 0x63, 0x73, 0x2E, 0x67, 0x69, 0x66, 0x00, - /* HTTP header: */ + // HTTP header: 0x48, 0x54, 0x54, 0x50, 0x2F, 0x31, 0x2E, 0x30, 0x20, 0x32, 0x30, 0x30, 0x20, 0x4F, 0x4B, 0x0D, 0x0A, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x3A, 0x20, 0x51, 0x4C, 0x20, 0x28, 0x68, @@ -3283,7 +3283,7 @@ static unsigned char const data_img_logo_sics_gif[] = { 0x74, 0x65, 0x6E, 0x74, 0x2D, 0x74, 0x79, 0x70, 0x65, 0x3A, 0x20, 0x69, 0x6D, 0x61, 0x67, 0x65, 0x2F, 0x67, 0x69, 0x66, 0x0D, 0x0A, 0x0D, 0x0A, - /* data: */ + // data: 0x47, 0x49, 0x46, 0x38, 0x39, 0x61, 0x78, 0x00, 0x35, 0x00, 0xE6, 0x00, 0x00, 0x95, 0x95, 0x95, 0x32, 0x32, 0x32, 0xE9, 0x92, 0x9A, 0xDC, 0x1B, 0x2D, 0xEA, 0xEA, 0xEA, 0x8A, 0x8A, @@ -3511,12 +3511,12 @@ struct fsdata_file const file_img_logo_sics_gif[] = { } }; -/* /img/PSiCC2.gif */ +// /img/PSiCC2.gif static unsigned char const data_img_PSiCC2_gif[] = { - /* name: */ + // name: 0x2F, 0x69, 0x6D, 0x67, 0x2F, 0x50, 0x53, 0x69, 0x43, 0x43, 0x32, 0x2E, 0x67, 0x69, 0x66, 0x00, - /* HTTP header: */ + // HTTP header: 0x48, 0x54, 0x54, 0x50, 0x2F, 0x31, 0x2E, 0x30, 0x20, 0x32, 0x30, 0x30, 0x20, 0x4F, 0x4B, 0x0D, 0x0A, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x3A, 0x20, 0x51, 0x4C, 0x20, 0x28, 0x68, @@ -3526,7 +3526,7 @@ static unsigned char const data_img_PSiCC2_gif[] = { 0x74, 0x65, 0x6E, 0x74, 0x2D, 0x74, 0x79, 0x70, 0x65, 0x3A, 0x20, 0x69, 0x6D, 0x61, 0x67, 0x65, 0x2F, 0x67, 0x69, 0x66, 0x0D, 0x0A, 0x0D, 0x0A, - /* data: */ + // data: 0x47, 0x49, 0x46, 0x38, 0x39, 0x61, 0x64, 0x00, 0x7D, 0x00, 0xE6, 0x00, 0x00, 0xA6, 0xAE, 0xB7, 0xFD, 0xFE, 0xFC, 0xE3, 0x30, 0x33, 0xFB, 0xB7, 0xAA, 0x13, 0x28, 0x4A, 0xB4, 0x49, @@ -4190,13 +4190,13 @@ struct fsdata_file const file_img_PSiCC2_gif[] = { } }; -/* /img/QP_datasheet.gif */ +// /img/QP_datasheet.gif static unsigned char const data_img_QP_datasheet_gif[] = { - /* name: */ + // name: 0x2F, 0x69, 0x6D, 0x67, 0x2F, 0x51, 0x50, 0x5F, 0x64, 0x61, 0x74, 0x61, 0x73, 0x68, 0x65, 0x65, 0x74, 0x2E, 0x67, 0x69, 0x66, 0x00, - /* HTTP header: */ + // HTTP header: 0x48, 0x54, 0x54, 0x50, 0x2F, 0x31, 0x2E, 0x30, 0x20, 0x32, 0x30, 0x30, 0x20, 0x4F, 0x4B, 0x0D, 0x0A, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x3A, 0x20, 0x51, 0x4C, 0x20, 0x28, 0x68, @@ -4206,7 +4206,7 @@ static unsigned char const data_img_QP_datasheet_gif[] = { 0x74, 0x65, 0x6E, 0x74, 0x2D, 0x74, 0x79, 0x70, 0x65, 0x3A, 0x20, 0x69, 0x6D, 0x61, 0x67, 0x65, 0x2F, 0x67, 0x69, 0x66, 0x0D, 0x0A, 0x0D, 0x0A, - /* data: */ + // data: 0x47, 0x49, 0x46, 0x38, 0x39, 0x61, 0x64, 0x00, 0x81, 0x00, 0xE6, 0x00, 0x00, 0xAD, 0xC8, 0xDB, 0xDC, 0xDC, 0xDC, 0xD3, 0xD4, 0xD4, 0x4F, 0x73, 0xA8, 0xCB, 0xCC, 0xCC, 0x98, 0xAD, @@ -5088,11 +5088,11 @@ struct fsdata_file const file_img_QP_datasheet_gif[] = { } }; -/* /index.htm */ +// /index.htm static unsigned char const data_index_htm[] = { - /* name: */ + // name: 0x2F, 0x69, 0x6E, 0x64, 0x65, 0x78, 0x2E, 0x68, 0x74, 0x6D , 0x00, - /* HTTP header: */ + // HTTP header: 0x48, 0x54, 0x54, 0x50, 0x2F, 0x31, 0x2E, 0x30, 0x20, 0x32, 0x30, 0x30, 0x20, 0x4F, 0x4B, 0x0D, 0x0A, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x3A, 0x20, 0x51, 0x4C, 0x20, 0x28, 0x68, @@ -5102,7 +5102,7 @@ static unsigned char const data_index_htm[] = { 0x74, 0x65, 0x6E, 0x74, 0x2D, 0x74, 0x79, 0x70, 0x65, 0x3A, 0x20, 0x74, 0x65, 0x78, 0x74, 0x2F, 0x68, 0x74, 0x6D, 0x6C, 0x0D, 0x0A, 0x0D, 0x0A, - /* data: */ + // data: 0x3C, 0x21, 0x44, 0x4F, 0x43, 0x54, 0x59, 0x50, 0x45, 0x20, 0x68, 0x74, 0x6D, 0x6C, 0x20, 0x50, 0x55, 0x42, 0x4C, 0x49, 0x43, 0x20, 0x22, 0x2D, 0x2F, 0x2F, 0x57, 0x33, 0x43, 0x2F, @@ -6130,12 +6130,12 @@ struct fsdata_file const file_index_htm[] = { } }; -/* /ssi_demo.shtm */ +// /ssi_demo.shtm static unsigned char const data_ssi_demo_shtm[] = { - /* name: */ + // name: 0x2F, 0x73, 0x73, 0x69, 0x5F, 0x64, 0x65, 0x6D, 0x6F, 0x2E, 0x73, 0x68, 0x74, 0x6D, 0x00, - /* HTTP header: */ + // HTTP header: 0x48, 0x54, 0x54, 0x50, 0x2F, 0x31, 0x2E, 0x30, 0x20, 0x32, 0x30, 0x30, 0x20, 0x4F, 0x4B, 0x0D, 0x0A, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x3A, 0x20, 0x51, 0x4C, 0x20, 0x28, 0x68, @@ -6147,7 +6147,7 @@ static unsigned char const data_ssi_demo_shtm[] = { 0x0D, 0x0A, 0x50, 0x72, 0x61, 0x67, 0x6D, 0x61, 0x3A, 0x20, 0x6E, 0x6F, 0x2D, 0x63, 0x61, 0x63, 0x68, 0x65, 0x0D, 0x0A, 0x0D, 0x0A, 0x0D, 0x0A, - /* data: */ + // data: 0x3C, 0x21, 0x44, 0x4F, 0x43, 0x54, 0x59, 0x50, 0x45, 0x20, 0x68, 0x74, 0x6D, 0x6C, 0x20, 0x50, 0x55, 0x42, 0x4C, 0x49, 0x43, 0x20, 0x22, 0x2D, 0x2F, 0x2F, 0x57, 0x33, 0x43, 0x2F, @@ -6731,11 +6731,11 @@ struct fsdata_file const file_ssi_demo_shtm[] = { } }; -/* /style.css */ +// /style.css static unsigned char const data_style_css[] = { - /* name: */ + // name: 0x2F, 0x73, 0x74, 0x79, 0x6C, 0x65, 0x2E, 0x63, 0x73, 0x73 , 0x00, - /* HTTP header: */ + // HTTP header: 0x48, 0x54, 0x54, 0x50, 0x2F, 0x31, 0x2E, 0x30, 0x20, 0x32, 0x30, 0x30, 0x20, 0x4F, 0x4B, 0x0D, 0x0A, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x3A, 0x20, 0x51, 0x4C, 0x20, 0x28, 0x68, @@ -6745,7 +6745,7 @@ static unsigned char const data_style_css[] = { 0x74, 0x65, 0x6E, 0x74, 0x2D, 0x74, 0x79, 0x70, 0x65, 0x3A, 0x20, 0x74, 0x65, 0x78, 0x74, 0x2F, 0x63, 0x73, 0x73, 0x0D, 0x0A, 0x0D, 0x0A, - /* data: */ + // data: 0x68, 0x74, 0x6D, 0x6C, 0x20, 0x7B, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x3A, 0x31, 0x30, 0x30, 0x25, 0x3B, 0x7D, 0x0A, 0x2F, 0x2A, 0x20, 0x66, 0x69, 0x78, 0x20, 0x73, 0x63, 0x72, @@ -6848,12 +6848,12 @@ struct fsdata_file const file_style_css[] = { } }; -/* /thank_you.htm */ +// /thank_you.htm static unsigned char const data_thank_you_htm[] = { - /* name: */ + // name: 0x2F, 0x74, 0x68, 0x61, 0x6E, 0x6B, 0x5F, 0x79, 0x6F, 0x75, 0x2E, 0x68, 0x74, 0x6D, 0x00, - /* HTTP header: */ + // HTTP header: 0x48, 0x54, 0x54, 0x50, 0x2F, 0x31, 0x2E, 0x30, 0x20, 0x32, 0x30, 0x30, 0x20, 0x4F, 0x4B, 0x0D, 0x0A, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x3A, 0x20, 0x51, 0x4C, 0x20, 0x28, 0x68, @@ -6863,7 +6863,7 @@ static unsigned char const data_thank_you_htm[] = { 0x74, 0x65, 0x6E, 0x74, 0x2D, 0x74, 0x79, 0x70, 0x65, 0x3A, 0x20, 0x74, 0x65, 0x78, 0x74, 0x2F, 0x68, 0x74, 0x6D, 0x6C, 0x0D, 0x0A, 0x0D, 0x0A, - /* data: */ + // data: 0x3C, 0x21, 0x44, 0x4F, 0x43, 0x54, 0x59, 0x50, 0x45, 0x20, 0x68, 0x74, 0x6D, 0x6C, 0x20, 0x50, 0x55, 0x42, 0x4C, 0x49, 0x43, 0x20, 0x22, 0x2D, 0x2F, 0x2F, 0x57, 0x33, 0x43, 0x2F, @@ -7091,12 +7091,12 @@ struct fsdata_file const file_thank_you_htm[] = { } }; -/* /udp_demo.htm */ +// /udp_demo.htm static unsigned char const data_udp_demo_htm[] = { - /* name: */ + // name: 0x2F, 0x75, 0x64, 0x70, 0x5F, 0x64, 0x65, 0x6D, 0x6F, 0x2E, 0x68, 0x74, 0x6D, 0x00, - /* HTTP header: */ + // HTTP header: 0x48, 0x54, 0x54, 0x50, 0x2F, 0x31, 0x2E, 0x30, 0x20, 0x32, 0x30, 0x30, 0x20, 0x4F, 0x4B, 0x0D, 0x0A, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x3A, 0x20, 0x51, 0x4C, 0x20, 0x28, 0x68, @@ -7106,7 +7106,7 @@ static unsigned char const data_udp_demo_htm[] = { 0x74, 0x65, 0x6E, 0x74, 0x2D, 0x74, 0x79, 0x70, 0x65, 0x3A, 0x20, 0x74, 0x65, 0x78, 0x74, 0x2F, 0x68, 0x74, 0x6D, 0x6C, 0x0D, 0x0A, 0x0D, 0x0A, - /* data: */ + // data: 0x3C, 0x21, 0x44, 0x4F, 0x43, 0x54, 0x59, 0x50, 0x45, 0x20, 0x68, 0x74, 0x6D, 0x6C, 0x20, 0x50, 0x55, 0x42, 0x4C, 0x49, 0x43, 0x20, 0x22, 0x2D, 0x2F, 0x2F, 0x57, 0x33, 0x43, 0x2F, diff --git a/examples/lwip/arm-cm/lwip_ek-lm3s6965/lwip.c b/examples/lwip/arm-cm/lwip_ek-lm3s6965/lwip.c index caf2c4a4..bd49f086 100644 --- a/examples/lwip/arm-cm/lwip_ek-lm3s6965/lwip.c +++ b/examples/lwip/arm-cm/lwip_ek-lm3s6965/lwip.c @@ -1,43 +1,43 @@ -/***************************************************************************** -* Product: lwIP consolidated file for QP-lwIP integration -* Last Updated for Version: lwIPv1.3.1 / QPv4.1.00 -* Date of the Last Update: Oct 12, 2009 -* -* Q u a n t u m L e a P s -* --------------------------- -* innovating embedded systems -* -* Copyright (C)-2009 Quantum Leaps, LLC. All rights reserved. -* -* This software may be distributed and modified under the terms of the GNU -* General Public License version 2 (GPL) as published by the Free Software -* Foundation and appearing in the file GPL.TXT included in the packaging of -* this file. Please note that GPL Section 2[b] requires that all works based -* on this software must also be made publicly available under the terms of -* the GPL ("Copyleft"). -* -* Alternatively, this software may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GPL and are specifically designed for licensees interested in -* retaining the proprietary status of their code. -* -* Contact information: -* Quantum Leaps Web site: http://www.quantum-leaps.com -* e-mail: info@quantum-leaps.com -*****************************************************************************/ -#include "lwip/opt.h" /* lwIP options come first */ +//============================================================================ +// Product: lwIP consolidated file for QP-lwIP integration +// Last Updated for Version: lwIPv1.3.1 / QPv4.1.00 +// Date of the Last Update: Oct 12, 2009 +// +// Q u a n t u m L e a P s +// --------------------------- +// innovating embedded systems +// +// Copyright (C)-2009 Quantum Leaps, LLC. All rights reserved. +// +// This software may be distributed and modified under the terms of the GNU +// General Public License version 2 (GPL) as published by the Free Software +// Foundation and appearing in the file GPL.TXT included in the packaging of +// this file. Please note that GPL Section 2[b] requires that all works based +// on this software must also be made publicly available under the terms of +// the GPL ("Copyleft"). +// +// Alternatively, this software may be distributed and modified under the +// terms of Quantum Leaps commercial licenses, which expressly supersede +// the GPL and are specifically designed for licensees interested in +// retaining the proprietary status of their code. +// +// Contact information: +// Quantum Leaps Web site: http://www.quantum-leaps.com +// e-mail: info@quantum-leaps.com +//============================================================================ +#include "lwip/opt.h" // lwIP options come first #include "lwip/api.h" #include "lwip/tcp.h" #include "lwip/udp.h" #include "lwip/tcpip.h" #include "lwip/mem.h" -/* NOTE: all the following modules contain conditional compilation protection, -* so tht code will be actually generated only if the appropriate options are -* set in the lwipopts.h header file included from lwip/opt.h. -*/ +// NOTE: all the following modules contain conditional compilation protection, +// so tht code will be actually generated only if the appropriate options are +// set in the lwipopts.h header file included from lwip/opt.h. +// -/* Core lwIP TCP/IP stack ..................................................*/ +// Core lwIP TCP/IP stack .................................................. #include "core/def.c" #include "core/dhcp.c" #include "core/dns.c" @@ -55,7 +55,7 @@ #include "core/timers.c" #include "core/udp.c" -/* IPv4 ....................................................................*/ +// IPv4 .................................................................... #include "core/ipv4/autoip.c" #include "core/ipv4/icmp.c" #include "core/ipv4/igmp.c" @@ -65,7 +65,7 @@ #include "core/ipv4/ip_addr.c" #include "core/ipv4/ip_frag.c" -/* SNMP ....................................................................*/ +// SNMP .................................................................... #include "core/snmp/asn1_dec.c" #include "core/snmp/asn1_enc.c" #include "core/snmp/mib2.c" @@ -73,11 +73,11 @@ #include "core/snmp/msg_in.c" #include "core/snmp/msg_out.c" -/* Ethernet interface ......................................................*/ +// Ethernet interface ...................................................... #include "netif/etharp.c" //???#include "netif/loopif.c" -/* PPP .....................................................................*/ +// PPP ..................................................................... #if PPP_SUPPORT #include "netif/ppp/auth.c" #include "netif/ppp/chap.c" @@ -92,25 +92,25 @@ #include "netif/ppp/ppp_oe.c" #include "netif/ppp/randm.c" #include "netif/ppp/vj.c" -#endif /* PPP_SUPPORT */ +#endif // PPP_SUPPORT -/* utilities added by QL ...................................................*/ -/** -* Allocate a transport-layer pbuf and copies the provided data buffer 'data' -* of length 'len' bytes into the payload(s) of the pbuf. The function takes -* care of splitting the data into successive pbuf payloads, if necessary. -* -* The function returns the newly created pbuf or NULL if the pbuf cannot -* be allocated. -*/ +// utilities added by QL ................................................... +//! +//! Allocate a transport-layer pbuf and copies the provided data buffer 'data' +//! of length 'len' bytes into the payload(s) of the pbuf. The function takes +//! care of splitting the data into successive pbuf payloads, if necessary. +//! +//! The function returns the newly created pbuf or NULL if the pbuf cannot +//! be allocated. +//! struct pbuf *pbuf_new(u8_t *data, u16_t len) { struct pbuf *p = pbuf_alloc(PBUF_TRANSPORT, len, PBUF_RAM); struct pbuf *q = p; while ((q != (struct pbuf *)0) && (len >= q->len)) { - memcpy(q->payload, data, q->len); /* copy data into payload */ - len -= q->len; /* remaining length */ - data += q->len; /* remainig data chunk */ - q = q->next; /* get next pbuf */ + memcpy(q->payload, data, q->len); // copy data into payload + len -= q->len; // remaining length + data += q->len; // remainig data chunk + q = q->next; // get next pbuf } return p; } diff --git a/examples/lwip/arm-cm/lwip_ek-lm3s6965/lwip.h b/examples/lwip/arm-cm/lwip_ek-lm3s6965/lwip.h index a0b415e1..5d9a5709 100644 --- a/examples/lwip/arm-cm/lwip_ek-lm3s6965/lwip.h +++ b/examples/lwip/arm-cm/lwip_ek-lm3s6965/lwip.h @@ -1,46 +1,46 @@ -/***************************************************************************** -* Product: lwIP consolidated file for QP-lwIP integration -* Last Updated for Version: LwIP 1.4.1/QP 5.1.1 -* Date of the Last Update: Oct 21, 2013 -* -* Q u a n t u m L e a P s -* --------------------------- -* innovating embedded systems -* -* Copyright (C)-2013 Quantum Leaps, LLC. All rights reserved. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* Quantum Leaps Web sites: http://www.quantum-leaps.com -* -* e-mail: info@quantum-leaps.com -*****************************************************************************/ +//============================================================================ +// Product: lwIP consolidated file for QP-lwIP integration +// Last Updated for Version: LwIP 1.4.1/QP 5.1.1 +// Date of the Last Update: Oct 21, 2013 +// +// Q u a n t u m L e a P s +// --------------------------- +// innovating embedded systems +// +// Copyright (C)-2013 Quantum Leaps, LLC. All rights reserved. +// +// This program is open source software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Alternatively, this program may be distributed and modified under the +// terms of Quantum Leaps commercial licenses, which expressly supersede +// the GNU General Public License and are specifically designed for +// licensees interested in retaining the proprietary status of their code. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Contact information: +// Quantum Leaps Web sites: http://www.quantum-leaps.com +// +// e-mail: info@quantum-leaps.com +//============================================================================ #ifndef LWIP_H #define LWIP_H - /* protection against including lwIP in unauthorized modules */ + // protection against including lwIP in unauthorized modules #ifndef LWIP_ALLOWED #error "The lwIP code is not reentrant and is not allowed in this module." #endif -#include "lwip/opt.h" /* lwIP options come first */ +#include "lwip/opt.h" // lwIP options come first #include "lwip/stats.h" #include "lwip/tcp.h" #include "lwip/tcp_impl.h" @@ -52,23 +52,23 @@ #include "netif/etharp.h" #include "netif/eth_driver.h" - /* utilities added by QL... */ + // utilities added by QL... #ifdef __cplusplus extern "C" { #endif -/** -* Allocate a transport-layer pbuf and copies the provided data buffer 'data' -* of length 'len' bytes into the payload(s) of the pbuf. The function takes -* care of splitting the data into successive pbuf payloads, if necessary. -* -* The function returns the newly created pbuf or NULL if the pbuf cannot -* be allocated. -*/ +//! +//! Allocate a transport-layer pbuf and copies the provided data buffer 'data' +//! of length 'len' bytes into the payload(s) of the pbuf. The function takes +//! care of splitting the data into successive pbuf payloads, if necessary. +//! +//! The function returns the newly created pbuf or NULL if the pbuf cannot +//! be allocated. +//! struct pbuf *pbuf_new(u8_t *data, u16_t len); #ifdef __cplusplus } #endif -#endif /* LWIP_H */ +#endif // LWIP_H diff --git a/examples/lwip/arm-cm/lwip_ek-lm3s6965/lwipmgr.c b/examples/lwip/arm-cm/lwip_ek-lm3s6965/lwipmgr.c index f528aab2..5a191d4c 100644 --- a/examples/lwip/arm-cm/lwip_ek-lm3s6965/lwipmgr.c +++ b/examples/lwip/arm-cm/lwip_ek-lm3s6965/lwipmgr.c @@ -1,65 +1,65 @@ -/***************************************************************************** -* Product: lwIP-Manager Active Object -* Last updated for version 7.2.0 -* Last updated on 2022-12-22 -* -* Q u a n t u m L e a P s -* ------------------------ -* Modern Embedded Software -* -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* -* -*****************************************************************************/ +//============================================================================ +// Product: lwIP-Manager Active Object +// Last updated for version 7.2.0 +// Last updated on 2022-12-22 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// This program is open source software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Alternatively, this program may be distributed and modified under the +// terms of Quantum Leaps commercial licenses, which expressly supersede +// the GNU General Public License and are specifically designed for +// licensees interested in retaining the proprietary status of their code. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Contact information: +// +// +//============================================================================ #define LWIP_ALLOWED -#include "qpc.h" /* QP/C API */ -#include "dpp.h" /* application events and active objects */ -#include "bsp.h" /* Board Support Package */ +#include "qpc.h" // QP/C API +#include "dpp.h" // application events and active objects +#include "bsp.h" // Board Support Package -#include "lwip.h" /* lwIP stack */ -#include "httpd.h" /* lwIP application */ +#include "lwip.h" // lwIP stack +#include "httpd.h" // lwIP application -#include /* for snprintf() */ -#include /* for strlen() */ +#include // for snprintf() +#include // for strlen() Q_DEFINE_THIS_FILE -/* the LwIP driver signal group must fit the actual number of signals */ +// the LwIP driver signal group must fit the actual number of signals Q_ASSERT_STATIC((LWIP_DRIVER_END - LWIP_DRIVER_GROUP) >= LWIP_MAX_OFFSET); #define FLASH_USERREG0 (*(uint32_t const *)0x400FE1E0) #define FLASH_USERREG1 (*(uint32_t const *)0x400FE1E4) #define LWIP_SLOW_TICK_MS TCP_TMR_INTERVAL -/* Active object class -----------------------------------------------------*/ +// Active object class ----------------------------------------------------- typedef struct LwIPMgrTag { - QActive super; /* inherit QActive */ + QActive super; // inherit QActive QTimeEvt te_LWIP_SLOW_TICK; struct netif *netif; struct udp_pcb *upcb; - uint32_t ip_addr; /* IP address in the native host byte order */ + uint32_t ip_addr; // IP address in the native host byte order #if LWIP_TCP uint32_t tcp_tmr; @@ -79,13 +79,13 @@ typedef struct LwIPMgrTag { static QState LwIPMgr_initial(LwIPMgr *me, QEvt const *e); static QState LwIPMgr_running(LwIPMgr *me, QEvt const *e); -/* Local objects -----------------------------------------------------------*/ -static LwIPMgr l_lwIPMgr; /* the single instance of LwIPMgr AO */ +// Local objects ----------------------------------------------------------- +static LwIPMgr l_lwIPMgr; // the single instance of LwIPMgr AO -/* Global-scope objects ----------------------------------------------------*/ -QActive * const AO_LwIPMgr = (QActive *)&l_lwIPMgr; /* "opaque" pointer */ +// Global-scope objects ---------------------------------------------------- +QActive * const AO_LwIPMgr = (QActive *)&l_lwIPMgr; // "opaque" pointer -/* Server-Side Include (SSI) demo ..........................................*/ +// Server-Side Include (SSI) demo .......................................... static char const * const ssi_tags[] = { "s_xmit", "s_recv", @@ -101,7 +101,7 @@ static char const * const ssi_tags[] = { }; static int ssi_handler(int iIndex, char *pcInsert, int iInsertLen); -/* Common Gateway Iinterface (CG) demo .....................................*/ +// Common Gateway Iinterface (CG) demo ..................................... static char const *cgi_display(int index, int numParams, char const *param[], char const *value[]); @@ -109,10 +109,10 @@ static tCGI const cgi_handlers[] = { { "/display.cgi", &cgi_display }, }; -/* UDP handler .............................................................*/ +// UDP handler ............................................................. static void udp_rx_handler(void *arg, struct udp_pcb *upcb, struct pbuf *p, struct ip_addr *addr, u16_t port); -/*..........................................................................*/ +//............................................................................ void LwIPMgr_ctor(void) { LwIPMgr *me = &l_lwIPMgr; @@ -120,30 +120,30 @@ void LwIPMgr_ctor(void) { QTimeEvt_ctorX(&me->te_LWIP_SLOW_TICK, &me->super, LWIP_SLOW_TICK_SIG, 0U); } -/*..........................................................................*/ +//............................................................................ QState LwIPMgr_initial(LwIPMgr *me, QEvt const *e) { uint32_t user0, user1; uint8_t macaddr[NETIF_MAX_HWADDR_LEN]; - (void)e; /* suppress the compiler warning about unused parameter */ + (void)e; // suppress the compiler warning about unused parameter - /* Configure the hardware MAC address for the Ethernet Controller - * - * For the Stellaris Eval Kits, the MAC address will be stored in the - * non-volatile USER0 and USER1 registers. These registers can be read - * using the FlashUserGet function, as illustrated below. - */ + // Configure the hardware MAC address for the Ethernet Controller + // + // For the Stellaris Eval Kits, the MAC address will be stored in the + // non-volatile USER0 and USER1 registers. These registers can be read + // using the FlashUserGet function, as illustrated below. + // user0 = FLASH_USERREG0; user1 = FLASH_USERREG1; - /* the MAC address must have been programmed! */ + // the MAC address must have been programmed! Q_ASSERT((user0 != 0xFFFFFFFF) && (user1 != 0xFFFFFFFF)); - /* - * Convert the 24/24 split MAC address from NV ram into a 32/16 split MAC - * address needed to program the hardware registers, then program the MAC - * address into the Ethernet Controller registers. - */ + // + // Convert the 24/24 split MAC address from NV ram into a 32/16 split MAC + // address needed to program the hardware registers, then program the MAC + // address into the Ethernet Controller registers. + // macaddr[0] = (uint8_t)user0; user0 >>= 8; macaddr[1] = (uint8_t)user0; user0 >>= 8; macaddr[2] = (uint8_t)user0; user0 >>= 8; @@ -151,18 +151,18 @@ QState LwIPMgr_initial(LwIPMgr *me, QEvt const *e) { macaddr[4] = (uint8_t)user1; user1 >>= 8; macaddr[5] = (uint8_t)user1; - /* initialize the Ethernet Driver */ + // initialize the Ethernet Driver me->netif = eth_driver_init((QActive *)me, LWIP_DRIVER_GROUP, macaddr); - me->ip_addr = 0xFFFFFFFF; /* initialize to impossible value */ + me->ip_addr = 0xFFFFFFFF; // initialize to impossible value - /* initialize the lwIP applications... */ - httpd_init(); /* initialize the simple HTTP-Deamon (web server) */ + // initialize the lwIP applications... + httpd_init(); // initialize the simple HTTP-Deamon (web server) http_set_ssi_handler(&ssi_handler, ssi_tags, Q_DIM(ssi_tags)); http_set_cgi_handlers(cgi_handlers, Q_DIM(cgi_handlers)); me->upcb = udp_new(); - udp_bind(me->upcb, IP_ADDR_ANY, 777); /* use port 777 for UDP */ + udp_bind(me->upcb, IP_ADDR_ANY, 777); // use port 777 for UDP udp_recv(me->upcb, &udp_rx_handler, me); QS_OBJ_DICTIONARY(&l_lwIPMgr); @@ -178,7 +178,7 @@ QState LwIPMgr_initial(LwIPMgr *me, QEvt const *e) { return Q_TRAN(&LwIPMgr_running); } -/*..........................................................................*/ +//............................................................................ QState LwIPMgr_running(LwIPMgr *me, QEvt const *e) { switch (e->sig) { case Q_ENTRY_SIG: { @@ -198,7 +198,7 @@ QState LwIPMgr_running(LwIPMgr *me, QEvt const *e) { strlen(((TextEvt const *)e)->text) + 1); if (p != (struct pbuf *)0) { udp_send(me->upcb, p); - pbuf_free(p); /* don't leak the pbuf! */ + pbuf_free(p); // don't leak the pbuf! } } return Q_HANDLED(); @@ -213,14 +213,14 @@ QState LwIPMgr_running(LwIPMgr *me, QEvt const *e) { return Q_HANDLED(); } case LWIP_SLOW_TICK_SIG: { - /* has IP address changed? */ + // has IP address changed? if (me->ip_addr != me->netif->ip_addr.addr) { TextEvt *te; - uint32_t ip_net; /* IP address in the network byte order */ + uint32_t ip_net; // IP address in the network byte order - me->ip_addr = me->netif->ip_addr.addr; /* save the IP addr. */ + me->ip_addr = me->netif->ip_addr.addr; // save the IP addr. ip_net = ntohl(me->ip_addr); - /* publish the text event to display the new IP address */ + // publish the text event to display the new IP address te = Q_NEW(TextEvt, DISPLAY_IPADDR_SIG); snprintf(te->text, sizeof(te->text), "%d.%d.%d.%d", (int)(((ip_net) >> 24) & 0xFFU), @@ -273,45 +273,45 @@ QState LwIPMgr_running(LwIPMgr *me, QEvt const *e) { return Q_SUPER(&QHsm_top); } -/* HTTPD customizations ----------------------------------------------------*/ +// HTTPD customizations ---------------------------------------------------- -/* Server-Side Include (SSI) handler .......................................*/ +// Server-Side Include (SSI) handler ....................................... static int ssi_handler(int iIndex, char *pcInsert, int iInsertLen) { struct stats_proto *stats = &lwip_stats.link; STAT_COUNTER value = 0; switch (iIndex) { - case 0: /* s_xmit */ + case 0: // s_xmit value = stats->xmit; break; - case 1: /* s_recv */ + case 1: // s_recv value = stats->recv; break; - case 2: /* s_fw */ + case 2: // s_fw value = stats->fw; break; - case 3: /* s_drop */ + case 3: // s_drop value = stats->drop; break; - case 4: /* s_chkerr */ + case 4: // s_chkerr value = stats->chkerr; break; - case 5: /* s_lenerr */ + case 5: // s_lenerr value = stats->lenerr; break; - case 6: /* s_memerr */ + case 6: // s_memerr value = stats->memerr; break; - case 7: /* s_rterr */ + case 7: // s_rterr value = stats->rterr; break; - case 8: /* s_proerr */ + case 8: // s_proerr value = stats->proterr; break; - case 9: /* s_opterr */ + case 9: // s_opterr value = stats->opterr; break; - case 10: /* s_err */ + case 10: // s_err value = stats->err; break; } @@ -319,24 +319,24 @@ static int ssi_handler(int iIndex, char *pcInsert, int iInsertLen) { return snprintf(pcInsert, MAX_TAG_INSERT_LEN, "%d", value); } -/* Common Gateway Iinterface (CG) handler ..................................*/ +// Common Gateway Iinterface (CG) handler .................................. static char const *cgi_display(int index, int numParams, char const *param[], char const *value[]) { int i; for (i = 0; i < numParams; ++i) { - if (strstr(param[i], "text") != (char *)0) { /* param text found? */ + if (strstr(param[i], "text") != (char *)0) { // param text found? TextEvt *te = Q_NEW(TextEvt, DISPLAY_CGI_SIG); strncpy(te->text, value[i], Q_DIM(te->text)); QACTIVE_PUBLISH((QEvt *)te, AO_LwIPMgr); return "/thank_you.htm"; } } - return (char *)0;/*no URI, HTTPD will send 404 error page to the browser*/ + return (char *)0;//no URI, HTTPD will send 404 error page to the browser } -/* UDP receive handler -----------------------------------------------------*/ +// UDP receive handler ----------------------------------------------------- static void udp_rx_handler(void *arg, struct udp_pcb *upcb, struct pbuf *p, struct ip_addr *addr, u16_t port) { @@ -344,7 +344,7 @@ static void udp_rx_handler(void *arg, struct udp_pcb *upcb, strncpy(te->text, (char *)p->payload, Q_DIM(te->text)); QACTIVE_PUBLISH((QEvt *)te, AO_LwIPMgr); - udp_connect(upcb, addr, port); /* connect to the remote host */ - pbuf_free(p); /* don't leak the pbuf! */ + udp_connect(upcb, addr, port); // connect to the remote host + pbuf_free(p); // don't leak the pbuf! } diff --git a/examples/lwip/arm-cm/lwip_ek-lm3s6965/lwipopts.h b/examples/lwip/arm-cm/lwip_ek-lm3s6965/lwipopts.h index fe5de391..057ffe76 100644 --- a/examples/lwip/arm-cm/lwip_ek-lm3s6965/lwipopts.h +++ b/examples/lwip/arm-cm/lwip_ek-lm3s6965/lwipopts.h @@ -1,44 +1,44 @@ -/***************************************************************************** -* Product: lwIP options for the LM3S6965 evaluaiton board -* Last Updated for lwIP Version: 1.4.0.rc2 -* Date of the Last Update: Feb 10, 2011 -* -* Q u a n t u m L e a P s -* --------------------------- -* innovating embedded systems -* -* Copyright (C)-2011 Quantum Leaps, LLC. All rights reserved. -* -* This software may be distributed and modified under the terms of the GNU -* General Public License version 2 (GPL) as published by the Free Software -* Foundation and appearing in the file GPL.TXT included in the packaging of -* this file. Please note that GPL Section 2[b] requires that all works based -* on this software must also be made publicly available under the terms of -* the GPL ("Copyleft"). -* -* Alternatively, this software may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GPL and are specifically designed for licensees interested in -* retaining the proprietary status of their code. -* -* Contact information: -* Quantum Leaps Web site: http://www.quantum-leaps.com -* e-mail: info@quantum-leaps.com -*****************************************************************************/ -/* -* NOTE: This file has been derived from the lwip/src/include/lwip/opt.h -* header file. For additional details, refer to the original "opt.h" file -* and lwIP documentation. -*/ +//============================================================================ +// Product: lwIP options for the LM3S6965 evaluaiton board +// Last Updated for lwIP Version: 1.4.0.rc2 +// Date of the Last Update: Feb 10, 2011 +// +// Q u a n t u m L e a P s +// --------------------------- +// innovating embedded systems +// +// Copyright (C)-2011 Quantum Leaps, LLC. All rights reserved. +// +// This software may be distributed and modified under the terms of the GNU +// General Public License version 2 (GPL) as published by the Free Software +// Foundation and appearing in the file GPL.TXT included in the packaging of +// this file. Please note that GPL Section 2[b] requires that all works based +// on this software must also be made publicly available under the terms of +// the GPL ("Copyleft"). +// +// Alternatively, this software may be distributed and modified under the +// terms of Quantum Leaps commercial licenses, which expressly supersede +// the GPL and are specifically designed for licensees interested in +// retaining the proprietary status of their code. +// +// Contact information: +// Quantum Leaps Web site: http://www.quantum-leaps.com +// e-mail: info@quantum-leaps.com +//============================================================================ +// +// NOTE: This file has been derived from the lwip/src/include/lwip/opt.h +// header file. For additional details, refer to the original "opt.h" file +// and lwIP documentation. +// #ifndef __LWIPOPTS_H__ #define __LWIPOPTS_H__ -//**************************************************************************** +//============================================================================ // // -------------- Static IPv4 addresses ---------------- // (relevant only when DHCP or AUTOIP are NOT configured // -//**************************************************************************** +//============================================================================ // the default IP address of the host... #define STATIC_IPADDR0 192 #define STATIC_IPADDR1 168 @@ -55,41 +55,41 @@ #define STATIC_GW_IPADDR2 0 #define STATIC_GW_IPADDR3 0 -//**************************************************************************** +//============================================================================ // // ---------------- lwIP Port Options ---------- // -//**************************************************************************** +//============================================================================ //#define HOST_TMR_INTERVAL //#define DHCP_EXPIRE_TIMER_MSECS (60 * 1000) //#define TX_PBUF_QUEUE_LEN 8 -//**************************************************************************** +//============================================================================ // // ---------- Platform specific locking ---------- // -//**************************************************************************** +//============================================================================ //#define SYS_LIGHTWEIGHT_PROT 0 #define NO_SYS 1 // default is 0 //#define NO_SYS_NO_TIMERS 0 //#define MEMCPY(dst,src,len) memcpy(dst,src,len) //#define SMEMCPY(dst,src,len) memcpy(dst,src,len) -//**************************************************************************** +//============================================================================ // // ---------------- HTTPD Options ---------- // -//**************************************************************************** +//============================================================================ #define INCLUDE_HTTPD_SSI #define INCLUDE_HTTPD_CGI //#define DYNAMIC_HTTP_HEADERS //#define INCLUDE_HTTPD_DEBUG -//**************************************************************************** +//============================================================================ // // ---------- Memory options ---------- // -//**************************************************************************** +//============================================================================ //#define MEM_LIBC_MALLOC 0 //#define MEMP_MEM_MALLOC 0 #define MEM_ALIGNMENT 4 // default is 1 @@ -102,11 +102,11 @@ //#define MEMP_USE_CUSTOM_POOLS 0 //#define LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT 0 -//**************************************************************************** +//============================================================================ // // ---------- Internal Memory Pool Sizes ---------- // -//**************************************************************************** +//============================================================================ //#define MEMP_NUM_PBUF 16 //#define MEMP_NUM_RAW_PCB 4 //#define MEMP_NUM_UDP_PCB 4 @@ -130,11 +130,11 @@ //#define MEMP_NUM_PPPOE_INTERFACES 1 //#define PBUF_POOL_SIZE 16 -//**************************************************************************** +//============================================================================ // // ---------- ARP options ---------- // -//**************************************************************************** +//============================================================================ //#define LWIP_ARP 1 //#define ARP_TABLE_SIZE 10 //#define ARP_QUEUEING 0 @@ -144,11 +144,11 @@ //#define ETH_PAD_SIZE 0 //#define ETHARP_SUPPORT_STATIC_ENTRIES 0 -//**************************************************************************** +//============================================================================ // // ---------- IP options ---------- // -//**************************************************************************** +//============================================================================ //#define IP_FORWARD 0 //#define IP_OPTIONS_ALLOWED 1 #define IP_REASSEMBLY 0 // default is 1 @@ -161,46 +161,46 @@ //#define IP_SOF_BROADCAST 0 //#define IP_SOF_BROADCAST_RECV 0 -//**************************************************************************** +//============================================================================ // // ---------- ICMP options ---------- // -//**************************************************************************** +//============================================================================ //#define LWIP_ICMP 1 //#define ICMP_TTL (IP_DEFAULT_TTL) //#define LWIP_BROADCAST_PING 0 //#define LWIP_MULTICAST_PING 0 -//**************************************************************************** +//============================================================================ // // ---------- RAW options ---------- // -//**************************************************************************** +//============================================================================ //#define LWIP_RAW 1 //#define RAW_TTL (IP_DEFAULT_TTL) -//**************************************************************************** +//============================================================================ // // ---------- DHCP options ---------- // -//**************************************************************************** +//============================================================================ #define LWIP_DHCP 1 // default is 0 //#define DHCP_DOES_ARP_CHECK ((LWIP_DHCP) && (LWIP_ARP)) -//**************************************************************************** +//============================================================================ // // ---------- AUTOIP options ---------- // -//**************************************************************************** +//============================================================================ //#define LWIP_AUTOIP 1 // default is 0 //#define LWIP_DHCP_AUTOIP_COOP 0 //#define LWIP_DHCP_AUTOIP_COOP_TRIES 9 -//**************************************************************************** +//============================================================================ // // ---------- SNMP options ---------- // -//**************************************************************************** +//============================================================================ //#define LWIP_SNMP 0 //#define SNMP_CONCURRENT_REQUESTS 1 //#define SNMP_TRAP_DESTINATIONS 1 @@ -209,18 +209,18 @@ //#define SNMP_MAX_OCTET_STRING_LEN 127 //#define SNMP_MAX_TREE_DEPTH 15 -//**************************************************************************** +//============================================================================ // // ---------- IGMP options ---------- // -//**************************************************************************** +//============================================================================ //#define LWIP_IGMP 0 -//**************************************************************************** +//============================================================================ // // ---------- DNS options ----------- // -//**************************************************************************** +//============================================================================ //#define LWIP_DNS 0 //#define DNS_TABLE_SIZE 4 //#define DNS_MAX_NAME_LENGTH 256 @@ -231,35 +231,35 @@ //#define DNS_LOCAL_HOSTLIST 0 //#define DNS_LOCAL_HOSTLIST_IS_DYNAMIC 0 -//**************************************************************************** +//============================================================================ // // ---------- UDP options ---------- // -//**************************************************************************** +//============================================================================ //#define LWIP_UDP 1 //#define LWIP_UDPLITE 0 //#define UDP_TTL (IP_DEFAULT_TTL) //#define LWIP_NETBUF_RECVINFO 0 -//**************************************************************************** +//============================================================================ // // ---------- UPNP options ---------- // -//**************************************************************************** +//============================================================================ //#define LWIP_UPNP 0 -//**************************************************************************** +//============================================================================ // // ---------- PTPD options ---------- // -//**************************************************************************** +//============================================================================ //#define LWIP_PTPD 0 -//**************************************************************************** +//============================================================================ // // ---------- TCP options ---------- // -//**************************************************************************** +//============================================================================ //#define LWIP_TCP 1 //#define TCP_TTL (IP_DEFAULT_TTL) //#define TCP_WND (4 * TCP_MSS) @@ -277,28 +277,28 @@ //#define LWIP_TCP_TIMESTAMPS 0 //#define TCP_WND_UPDATE_THRESHOLD (TCP_WND / 4) -//**************************************************************************** +//============================================================================ // // ---------- API options ---------- // -//**************************************************************************** +//============================================================================ //#define LWIP_EVENT_API 0 //#define LWIP_CALLBACK_API 1 -//**************************************************************************** +//============================================================================ // // ---------- Pbuf options ---------- // -//**************************************************************************** +//============================================================================ #define ETH_PAD_SIZE 2 // default is 0 //#define PBUF_LINK_HLEN (14 + ETH_PAD_SIZE) //#define PBUF_POOL_BUFSIZE LWIP_MEM_ALIGN_SIZE(TCP_MSS+40+PBUF_LINK_HLEN) -//**************************************************************************** +//============================================================================ // // ---------- Network Interfaces options ---------- // -//**************************************************************************** +//============================================================================ #define LWIP_NETIF_HOSTNAME 1 // default is 0 //#define LWIP_NETIF_API 0 //#define LWIP_NETIF_STATUS_CALLBACK 0 @@ -310,25 +310,25 @@ //#define LWIP_NETIF_TX_SINGLE_PBUF 0 -//**************************************************************************** +//============================================================================ // // ---------- LOOPIF options ---------- // -//**************************************************************************** +//============================================================================ //#define LWIP_HAVE_LOOPIF 0 -//**************************************************************************** +//============================================================================ // // ---------- SLIPIF options ---------- // -//**************************************************************************** +//============================================================================ //#define LWIP_HAVE_SLIPIF 0 -//**************************************************************************** +//============================================================================ // // ---------- Thread options ---------- // -//**************************************************************************** +//============================================================================ //#define TCPIP_THREAD_NAME "tcpip_thread" //#define TCPIP_THREAD_STACKSIZE 0 //#define TCPIP_THREAD_PRIO 1 @@ -347,21 +347,21 @@ //#define DEFAULT_TCP_RECVMBOX_SIZE 0 //#define DEFAULT_ACCEPTMBOX_SIZE 0 -//**************************************************************************** +//============================================================================ // // ---------- Sequential layer options ---------- // -//**************************************************************************** +//============================================================================ //#define LWIP_TCPIP_CORE_LOCKING 0 //#define LWIP_TCPIP_CORE_LOCKING_INPUT 0 #define LWIP_NETCONN 0 // default is 1 //#define LWIP_TCPIP_TIMEOUT 1 -//**************************************************************************** +//============================================================================ // // ---------- Socket Options ---------- // -//**************************************************************************** +//============================================================================ #define LWIP_SOCKET 0 // default is 1 //#define LWIP_COMPAT_SOCKETS 1 //#define LWIP_POSIX_SOCKETS_IO_NAMES 1 @@ -372,11 +372,11 @@ //#define SO_REUSE 0 //#define SO_REUSE_RXTOALL 0 -//**************************************************************************** +//============================================================================ // // ---------- Statistics options ---------- // -//**************************************************************************** +//============================================================================ #define LWIP_STATS 1 //#define LWIP_STATS_DISPLAY 0 #define LINK_STATS 1 @@ -391,11 +391,11 @@ //#define MEMP_STATS (MEMP_MEM_MALLOC == 0) //#define SYS_STATS (NO_SYS == 0) -//**************************************************************************** +//============================================================================ // // ---------- PPP options ---------- // -//**************************************************************************** +//============================================================================ //#define PPP_SUPPORT 0 //#define PPPOE_SUPPORT 0 //#define PPPOS_SUPPORT PPP_SUPPORT @@ -425,11 +425,11 @@ //#define PPP_DEFMRU 296 #endif -//**************************************************************************** +//============================================================================ // // ---------- checksum options ---------- // -//**************************************************************************** +//============================================================================ //#define CHECKSUM_GEN_IP 1 //#define CHECKSUM_GEN_UDP 1 //#define CHECKSUM_GEN_TCP 1 @@ -438,11 +438,11 @@ //#define CHECKSUM_CHECK_TCP 1 //#define LWIP_CHECKSUM_ON_COPY 0 -//**************************************************************************** +//============================================================================ // // ---------- Debugging options ---------- // -//**************************************************************************** +//============================================================================ #define LWIP_DBG_MIN_LEVEL LWIP_DBG_LEVEL_OFF // LWIP_DBG_LEVEL_ALL //#define LWIP_DBG_MIN_LEVEL LWIP_DBG_LEVEL_WARNING //#define LWIP_DBG_MIN_LEVEL LWIP_DBG_LEVEL_SERIOUS @@ -486,4 +486,4 @@ //#define SNMP_MIB_DEBUG LWIP_DBG_OFF //#define DNS_DEBUG LWIP_DBG_OFF -#endif /* __LWIPOPTS_H__ */ +#endif // __LWIPOPTS_H__ diff --git a/examples/lwip/arm-cm/lwip_ek-lm3s6965/main.c b/examples/lwip/arm-cm/lwip_ek-lm3s6965/main.c index 6f9dfc97..ce112273 100644 --- a/examples/lwip/arm-cm/lwip_ek-lm3s6965/main.c +++ b/examples/lwip/arm-cm/lwip_ek-lm3s6965/main.c @@ -1,64 +1,64 @@ -/***************************************************************************** -* Product: DPP with lwIP application -* Last updated for version 6.4.0 -* Last updated on 2019-02-08 -* -* Q u a n t u m L e a P s -* ------------------------ -* Modern Embedded Software -* -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* -* -*****************************************************************************/ +//============================================================================ +// Product: DPP with lwIP application +// Last updated for version 6.4.0 +// Last updated on 2019-02-08 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// This program is open source software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Alternatively, this program may be distributed and modified under the +// terms of Quantum Leaps commercial licenses, which expressly supersede +// the GNU General Public License and are specifically designed for +// licensees interested in retaining the proprietary status of their code. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Contact information: +// +// +//============================================================================ #include "qpc.h" -#include "dpp.h" /* application events and active objects */ +#include "dpp.h" // application events and active objects #include "bsp.h" -Q_DEFINE_THIS_FILE +//Q_DEFINE_THIS_FILE -/* Local-scope objects -----------------------------------------------------*/ +// Local-scope objects ----------------------------------------------------- static QEvt const *l_tableQueueSto[N_PHILO]; static QEvt const *l_philoQueueSto[N_PHILO][N_PHILO]; static QEvt const *l_lwIPMgrQueueSto[10]; static QSubscrList l_subscrSto[MAX_PUB_SIG]; -static QF_MPOOL_EL(TableEvt) l_smlPoolSto[20]; /* small event pool */ -static QF_MPOOL_EL(TextEvt) l_medPoolSto[4]; /* med. event pool */ +static QF_MPOOL_EL(TableEvt) l_smlPoolSto[20]; // small event pool +static QF_MPOOL_EL(TextEvt) l_medPoolSto[4]; // med. event pool -/*..........................................................................*/ +//............................................................................ int main(void) { uint8_t n; - Philo_ctor(); /* instantiate all Philosopher active objects */ - Table_ctor(); /* instantiate the Table active object */ - LwIPMgr_ctor(); /* instantiate all LwIP-Manager active object */ + Philo_ctor(); // instantiate all Philosopher active objects + Table_ctor(); // instantiate the Table active object + LwIPMgr_ctor(); // instantiate all LwIP-Manager active object - BSP_init(); /* initialize the Board Support Package */ + BSP_init(); // initialize the Board Support Package - QF_init(); /* initialize the framework and the underlying RT kernel */ + QF_init(); // initialize the framework and the underlying RT kernel - /* object dictionaries... */ + // object dictionaries... QS_OBJ_DICTIONARY(l_smlPoolSto); QS_OBJ_DICTIONARY(l_medPoolSto); QS_OBJ_DICTIONARY(l_lwIPMgrQueueSto); @@ -69,17 +69,17 @@ int main(void) { QS_OBJ_DICTIONARY(l_philoQueueSto[4]); QS_OBJ_DICTIONARY(l_tableQueueSto); - /* init publish-subscribe */ - QF_psInit(l_subscrSto, Q_DIM(l_subscrSto)); + // init publish-subscribe + QActive_psInit(l_subscrSto, Q_DIM(l_subscrSto)); - /* initialize event pools... */ + // initialize event pools... QF_poolInit(l_smlPoolSto, sizeof(l_smlPoolSto), sizeof(l_smlPoolSto[0])); QF_poolInit(l_medPoolSto, sizeof(l_medPoolSto), sizeof(l_medPoolSto[0])); QACTIVE_START(AO_LwIPMgr, 1, l_lwIPMgrQueueSto, Q_DIM(l_lwIPMgrQueueSto), (void *)0, 0, (QEvt *)0); - for (n = 0; n < N_PHILO; ++n) { /* start the active objects... */ + for (n = 0; n < N_PHILO; ++n) { // start the active objects... QACTIVE_START(AO_Philo[n], (uint8_t)(n + 2), l_philoQueueSto[n], Q_DIM(l_philoQueueSto[n]), (void *)0, 0, (QEvt *)0); @@ -88,5 +88,5 @@ int main(void) { l_tableQueueSto, Q_DIM(l_tableQueueSto), (void *)0, 0, (QEvt *)0); - return QF_run(); /* run the QF application */ + return QF_run(); // run the QF application } diff --git a/examples/lwip/arm-cm/lwip_ek-lm3s6965/philo.c b/examples/lwip/arm-cm/lwip_ek-lm3s6965/philo.c index 5ce395d5..d95c23f8 100644 --- a/examples/lwip/arm-cm/lwip_ek-lm3s6965/philo.c +++ b/examples/lwip/arm-cm/lwip_ek-lm3s6965/philo.c @@ -1,46 +1,46 @@ -/***************************************************************************** -* Product: DPP example -* Last updated for version 5.4.0 -* Last updated on 2015-03-25 -* -* Q u a n t u m L e a P s -* --------------------------- -* innovating embedded systems -* -* Copyright (C) 2005 Quantum Leaps, www.state-machine.com. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* Web: www.state-machine.com -* -*****************************************************************************/ -#include "qpc.h" /* QP/C header file */ -#include "dpp.h" /* application events and active objects */ -#include "bsp.h" /* Board Support Package header file */ +//============================================================================ +// Product: DPP example +// Last updated for version 5.4.0 +// Last updated on 2015-03-25 +// +// Q u a n t u m L e a P s +// --------------------------- +// innovating embedded systems +// +// Copyright (C) 2005 Quantum Leaps, www.state-machine.com. +// +// This program is open source software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Alternatively, this program may be distributed and modified under the +// terms of Quantum Leaps commercial licenses, which expressly supersede +// the GNU General Public License and are specifically designed for +// licensees interested in retaining the proprietary status of their code. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Contact information: +// Web: www.state-machine.com +// +//============================================================================ +#include "qpc.h" // QP/C header file +#include "dpp.h" // application events and active objects +#include "bsp.h" // Board Support Package header file Q_DEFINE_THIS_FILE -/* Active object class -----------------------------------------------------*/ +// Active object class ----------------------------------------------------- typedef struct PhiloTag { QActive super; - QTimeEvt timeEvt; /* for timing out thining or eating */ + QTimeEvt timeEvt; // for timing out thining or eating } Philo; static QState Philo_initial (Philo *me, QEvt const *e); @@ -48,21 +48,21 @@ static QState Philo_thinking(Philo *me, QEvt const *e); static QState Philo_hungry (Philo *me, QEvt const *e); static QState Philo_eating (Philo *me, QEvt const *e); -/* Local objects -----------------------------------------------------------*/ -static Philo l_philo[N_PHILO]; /* storage for all Philos */ +// Local objects ----------------------------------------------------------- +static Philo l_philo[N_PHILO]; // storage for all Philos #define THINK_TIME (BSP_TICKS_PER_SEC/2) #define EAT_TIME (BSP_TICKS_PER_SEC/5) - /* helper macro to provide the ID of Philo "me_" */ + // helper macro to provide the ID of Philo "me_" #define PHILO_ID(me_) ((uint8_t)((me_) - l_philo)) -enum InternalSignals { /* internal signals */ +enum InternalSignals { // internal signals TIMEOUT_SIG = MAX_SIG }; -/* Global objects ----------------------------------------------------------*/ -QActive * const AO_Philo[N_PHILO] = { /* "opaque" pointers to Philo AO */ +// Global objects ---------------------------------------------------------- +QActive * const AO_Philo[N_PHILO] = { // "opaque" pointers to Philo AO (QActive *)&l_philo[0], (QActive *)&l_philo[1], (QActive *)&l_philo[2], @@ -70,8 +70,8 @@ QActive * const AO_Philo[N_PHILO] = { /* "opaque" pointers to Philo AO */ (QActive *)&l_philo[4] }; -/*..........................................................................*/ -void Philo_ctor(void) { /* instantiate all Philo objects */ +//............................................................................ +void Philo_ctor(void) { // instantiate all Philo objects uint8_t n; Philo *me; for (n = 0; n < N_PHILO; ++n) { @@ -80,10 +80,10 @@ void Philo_ctor(void) { /* instantiate all Philo objects */ QTimeEvt_ctorX(&me->timeEvt, &me->super, TIMEOUT_SIG, 0U); } } -/*..........................................................................*/ +//............................................................................ QState Philo_initial(Philo *me, QEvt const *e) { - static uint8_t registered; /* starts off with 0, per C-standard */ - (void)e; /* suppress the compiler warning about unused parameter */ + static uint8_t registered; // starts off with 0, per C-standard + (void)e; // suppress the compiler warning about unused parameter if (!registered) { QS_OBJ_DICTIONARY(&l_philo[0]); QS_OBJ_DICTIONARY(&l_philo[0].timeEvt); @@ -103,14 +103,14 @@ QState Philo_initial(Philo *me, QEvt const *e) { registered = (uint8_t)1; } - QS_SIG_DICTIONARY(HUNGRY_SIG, me); /* signal for each Philos */ - QS_SIG_DICTIONARY(TIMEOUT_SIG, me); /* signal for each Philos */ + QS_SIG_DICTIONARY(HUNGRY_SIG, me); // signal for each Philos + QS_SIG_DICTIONARY(TIMEOUT_SIG, me); // signal for each Philos QActive_subscribe((QActive *)me, EAT_SIG); - return Q_TRAN(&Philo_thinking); /* top-most initial transition */ + return Q_TRAN(&Philo_thinking); // top-most initial transition } -/*..........................................................................*/ +//............................................................................ QState Philo_thinking(Philo *me, QEvt const *e) { switch (e->sig) { case Q_ENTRY_SIG: { @@ -120,16 +120,16 @@ QState Philo_thinking(Philo *me, QEvt const *e) { case TIMEOUT_SIG: { return Q_TRAN(&Philo_hungry); } - case EAT_SIG: /* intentionally fall-through */ + case EAT_SIG: // intentionally fall-through case DONE_SIG: { - /* EAT or DONE must be for other Philos than this one */ + // EAT or DONE must be for other Philos than this one Q_ASSERT(((TableEvt const *)e)->philoNum != PHILO_ID(me)); return Q_HANDLED(); } } return Q_SUPER(&QHsm_top); } -/*..........................................................................*/ +//............................................................................ QState Philo_hungry(Philo *me, QEvt const *e) { switch (e->sig) { case Q_ENTRY_SIG: { @@ -145,14 +145,14 @@ QState Philo_hungry(Philo *me, QEvt const *e) { break; } case DONE_SIG: { - /* DONE must be for other Philos than this one */ + // DONE must be for other Philos than this one Q_ASSERT(((TableEvt const *)e)->philoNum != PHILO_ID(me)); return Q_HANDLED(); } } return Q_SUPER(&QHsm_top); } -/*..........................................................................*/ +//............................................................................ QState Philo_eating(Philo *me, QEvt const *e) { switch (e->sig) { case Q_ENTRY_SIG: { @@ -168,9 +168,9 @@ QState Philo_eating(Philo *me, QEvt const *e) { case TIMEOUT_SIG: { return Q_TRAN(&Philo_thinking); } - case EAT_SIG: /* intentionally fall-through */ + case EAT_SIG: // intentionally fall-through case DONE_SIG: { - /* EAT or DONE must be for other Philos than this one */ + // EAT or DONE must be for other Philos than this one Q_ASSERT(((TableEvt const *)e)->philoNum != PHILO_ID(me)); return Q_HANDLED(); } diff --git a/examples/lwip/arm-cm/lwip_ek-lm3s6965/qk/bsp.c b/examples/lwip/arm-cm/lwip_ek-lm3s6965/qk/bsp.c index c85aaf18..aa985d5b 100644 --- a/examples/lwip/arm-cm/lwip_ek-lm3s6965/qk/bsp.c +++ b/examples/lwip/arm-cm/lwip_ek-lm3s6965/qk/bsp.c @@ -1,48 +1,48 @@ -/***************************************************************************** -* Product: DPP with lwIP application, preemptive QK kernel -* Last updated for version 6.9.3 -* Last updated on 2021-03-03 -* -* Q u a n t u m L e a P s -* ------------------------ -* Modern Embedded Software -* -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* -* -*****************************************************************************/ -#include "qpc.h" /* QP/C header file */ -#include "dpp.h" /* application events and active objects */ -#include "bsp.h" /* Board Support Package header file */ +//============================================================================ +// Product: DPP with lwIP application, preemptive QK kernel +// Last updated for version 6.9.3 +// Last updated on 2021-03-03 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// This program is open source software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Alternatively, this program may be distributed and modified under the +// terms of Quantum Leaps commercial licenses, which expressly supersede +// the GNU General Public License and are specifically designed for +// licensees interested in retaining the proprietary status of their code. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Contact information: +// +// +//============================================================================ +#include "qpc.h" // QP/C header file +#include "dpp.h" // application events and active objects +#include "bsp.h" // Board Support Package header file -#include "LM3S6965.h" /* the device specific header (TI) */ +#include "LM3S6965.h" // the device specific header (TI) Q_DEFINE_THIS_FILE -/* ISRs defined in this BSP ------------------------------------------------*/ +// ISRs defined in this BSP ------------------------------------------------ void SysTick_Handler(void); -/* Local-scope objects -----------------------------------------------------*/ +// Local-scope objects ----------------------------------------------------- #define USER_LED (1U << 0) #define USER_BTN (1U << 1) @@ -56,7 +56,7 @@ static uint32_t l_nTicks; QSTimeCtr QS_tickTime_; QSTimeCtr QS_tickPeriod_; - /* QSpy source IDs */ + // QSpy source IDs static QSpyId const l_SysTick_Handler = { 0U }; #define UART_BAUD_RATE 115200U @@ -65,9 +65,9 @@ static uint32_t l_nTicks; #endif -/*..........................................................................*/ +//............................................................................ void SysTick_Handler(void) { - /* state of the button debouncing, see below */ + // state of the button debouncing, see below static struct ButtonsDebouncing { uint32_t depressed; uint32_t previous; @@ -75,54 +75,54 @@ void SysTick_Handler(void) { uint32_t current; uint32_t volatile tmp; - QK_ISR_ENTRY(); /* inform QK about ISR entry */ + QK_ISR_ENTRY(); // inform QK about ISR entry - ++l_nTicks; /* count the number of clock ticks */ + ++l_nTicks; // count the number of clock ticks #ifdef Q_SPY - tmp = SysTick->CTRL; /* clear SysTick_CTRL_COUNTFLAG */ - QS_tickTime_ += QS_tickPeriod_; /* account for the clock rollover */ + tmp = SysTick->CTRL; // clear SysTick_CTRL_COUNTFLAG + QS_tickTime_ += QS_tickPeriod_; // account for the clock rollover #endif - QTIMEEVT_TICK_X(0U, &l_SysTick_Handler); /* process time events for rate 0 */ + QTIMEEVT_TICK_X(0U, &l_SysTick_Handler); // process time events for rate 0 - /* Perform the debouncing of buttons. The algorithm for debouncing - * adapted from the book "Embedded Systems Dictionary" by Jack Ganssle - * and Michael Barr, page 71. - */ - current = ~GPIOF->DATA_Bits[USER_BTN]; /* read USER_BTN */ - tmp = buttons.depressed; /* save the debounced depressed buttons */ - buttons.depressed |= (buttons.previous & current); /* set depressed */ - buttons.depressed &= (buttons.previous | current); /* clear released */ - buttons.previous = current; /* update the history */ - tmp ^= buttons.depressed; /* changed debounced depressed */ - if ((tmp & USER_BTN) != 0U) { /* debounced USER_BTN state changed? */ - if ((buttons.depressed & USER_BTN) != 0U) { /* is BTN depressed? */ - static QEvt const bd = { BTN_DOWN_SIG, 0U, 0U }; + // Perform the debouncing of buttons. The algorithm for debouncing + // adapted from the book "Embedded Systems Dictionary" by Jack Ganssle + // and Michael Barr, page 71. + // + current = ~GPIOF->DATA_Bits[USER_BTN]; // read USER_BTN + tmp = buttons.depressed; // save the debounced depressed buttons + buttons.depressed |= (buttons.previous & current); // set depressed + buttons.depressed &= (buttons.previous | current); // clear released + buttons.previous = current; // update the history + tmp ^= buttons.depressed; // changed debounced depressed + if ((tmp & USER_BTN) != 0U) { // debounced USER_BTN state changed? + if ((buttons.depressed & USER_BTN) != 0U) { // is BTN depressed? + static QEvt const bd = QEVT_INITIALIZER(BTN_DOWN_SIG); QACTIVE_PUBLISH(&bd, &l_SysTick_Handler); } - else { /* the button is released */ - static QEvt const bu = { BTN_UP_SIG, 0U, 0U }; + else { // the button is released + static QEvt const bu = QEVT_INITIALIZER(BTN_UP_SIG); QACTIVE_PUBLISH(&bu, &l_SysTick_Handler); } } - QK_ISR_EXIT(); /* inform QK about ISR exit */ + QK_ISR_EXIT(); // inform QK about ISR exit } -/*..........................................................................*/ +//............................................................................ void BSP_init(void) { - /* NOTE: SystemInit() already called from startup_TM4C123GH6PM.s - * but SystemCoreClock needs to be updated - */ + // NOTE: SystemInit() already called from startup_TM4C123GH6PM.s + // but SystemCoreClock needs to be updated + // SystemCoreClockUpdate(); - SYSCTL->RCGC2 |= (1 << 5); /* enable clock to GPIOF (User and Eth LEDs)*/ + SYSCTL->RCGC2 |= (1 << 5); // enable clock to GPIOF (User and Eth LEDs) __NOP(); __NOP(); - /* configure the pin driving the Ethernet LED */ - GPIOF->DIR &= ~(ETH0_LED | ETH1_LED); /* set direction: hardware */ + // configure the pin driving the Ethernet LED + GPIOF->DIR &= ~(ETH0_LED | ETH1_LED); // set direction: hardware GPIOF->AFSEL |= (ETH0_LED | ETH1_LED); GPIOF->DR2R |= (ETH0_LED | ETH1_LED); GPIOF->ODR &= ~(ETH0_LED | ETH1_LED); @@ -131,15 +131,15 @@ void BSP_init(void) { GPIOF->DEN |= (ETH0_LED | ETH1_LED); GPIOF->AMSEL &= ~(ETH0_LED | ETH1_LED); - /* configure the pin driving the User LED */ - GPIOF->DIR |= USER_LED; /* set direction: output */ + // configure the pin driving the User LED + GPIOF->DIR |= USER_LED; // set direction: output GPIOF->DR2R |= USER_LED; GPIOF->DEN |= USER_LED; GPIOF->AMSEL &= ~USER_LED; - GPIOF->DATA_Bits[USER_LED] = 0; /* turn the LED off */ + GPIOF->DATA_Bits[USER_LED] = 0; // turn the LED off - /* configure the pin connected to the Buttons */ - GPIOF->DIR &= ~USER_BTN; /* set direction: input */ + // configure the pin connected to the Buttons + GPIOF->DIR &= ~USER_BTN; // set direction: input GPIOF->DR2R |= USER_BTN; GPIOF->ODR &= ~USER_BTN; GPIOF->PUR |= USER_BTN; @@ -147,114 +147,120 @@ void BSP_init(void) { GPIOF->DEN |= USER_BTN; GPIOF->AMSEL &= ~USER_BTN; - /* NOTE: - * The OLED display is encapsulated inside the Table AO, so the - * initialization of the OLED display happens in the top-most initial - * transition of the Table AO (see Table_displayInit()). - */ + // NOTE: + // The OLED display is encapsulated inside the Table AO, so the + // initialization of the OLED display happens in the top-most initial + // transition of the Table AO (see Table_displayInit()). + // - if (QS_INIT((void *)0) == 0) { /* initialize the QS software tracing */ + if (QS_INIT((void *)0) == 0) { // initialize the QS software tracing Q_ERROR(); } QS_OBJ_DICTIONARY(&l_SysTick_Handler); - /* setup the QS filters... */ - QS_GLB_FILTER(QS_SM_RECORDS); /* state machine records */ - QS_GLB_FILTER(QS_AO_RECORDS); /* active object records */ - QS_GLB_FILTER(QS_UA_RECORDS); /* all user records */ + // setup the QS filters... + QS_GLB_FILTER(QS_SM_RECORDS); // state machine records + QS_GLB_FILTER(QS_AO_RECORDS); // active object records + QS_GLB_FILTER(QS_UA_RECORDS); // all user records } -/*..........................................................................*/ +//............................................................................ void QF_onStartup(void) { - /* set up the SysTick timer to fire at BSP_TICKS_PER_SEC rate */ + // set up the SysTick timer to fire at BSP_TICKS_PER_SEC rate SysTick_Config(SystemCoreClock / BSP_TICKS_PER_SEC); - /* assing all priority bits for preemption-prio. and none to sub-prio. */ + // assing all priority bits for preemption-prio. and none to sub-prio. NVIC_SetPriorityGrouping(0U); - /* set priorities of ALL ISRs used in the system, see NOTE1 - * - * !!!!!!!!!!!!!!!!!!!!!!!!!!!! CAUTION !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - * Assign a priority to EVERY ISR explicitly by calling NVIC_SetPriority(). - * DO NOT LEAVE THE ISR PRIORITIES AT THE DEFAULT VALUE! - */ + // set priorities of ALL ISRs used in the system, see NOTE1 + // + // !!!!!!!!!!!!!!!!!!!!!!!!!!!! CAUTION !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + // Assign a priority to EVERY ISR explicitly by calling NVIC_SetPriority(). + // DO NOT LEAVE THE ISR PRIORITIES AT THE DEFAULT VALUE! + // NVIC_SetPriority(Ethernet_IRQn, QF_AWARE_ISR_CMSIS_PRI); NVIC_SetPriority(SysTick_IRQn, QF_AWARE_ISR_CMSIS_PRI + 1U); - /* ... */ + // ... - NVIC_EnableIRQ(Ethernet_IRQn); /* enable the Ethernet Interrupt */ + NVIC_EnableIRQ(Ethernet_IRQn); // enable the Ethernet Interrupt } -/*..........................................................................*/ +//............................................................................ void QF_onCleanup(void) { } -/*..........................................................................*/ +//............................................................................ void QK_onIdle(void) { - /* toggle the User LED on and then off, see NOTE2 */ + // toggle the User LED on and then off, see NOTE2 QF_INT_DISABLE(); - GPIOF->DATA_Bits[USER_LED] = USER_LED; /* turn the User LED on */ - GPIOF->DATA_Bits[USER_LED] = 0; /* turn the User LED off */ + GPIOF->DATA_Bits[USER_LED] = USER_LED; // turn the User LED on + GPIOF->DATA_Bits[USER_LED] = 0; // turn the User LED off QF_INT_ENABLE(); #ifdef Q_SPY - if ((UART0->FR & UART_FR_TXFE) != 0) { /* TX done? */ - uint16_t fifo = UART_TXFIFO_DEPTH; /* max bytes we can accept */ + if ((UART0->FR & UART_FR_TXFE) != 0) { // TX done? + uint16_t fifo = UART_TXFIFO_DEPTH; // max bytes we can accept uint8_t const *block; QF_INT_DISABLE(); - block = QS_getBlock(&fifo); /* try to get next block to transmit */ + block = QS_getBlock(&fifo); // try to get next block to transmit QF_INT_ENABLE(); - while (fifo-- != 0) { /* any bytes in the block? */ - UART0->DR = *block++; /* put into the FIFO */ + while (fifo-- != 0) { // any bytes in the block? + UART0->DR = *block++; // put into the FIFO } } #elif defined NDEBUG - /* Put the CPU and peripherals to the low-power mode. - * you might need to customize the clock management for your application, - * see the datasheet for your particular MCU. - */ - __WFI(); /* Wait-For-Interrupt */ + // Put the CPU and peripherals to the low-power mode. + // you might need to customize the clock management for your application, + // see the datasheet for your particular MCU. + // + __WFI(); // Wait-For-Interrupt #endif } -/*..........................................................................*/ -Q_NORETURN Q_onAssert(char const * const module, int_t const loc) { - /* - * NOTE: add here your application-specific error handling - */ - (void)module; - (void)loc; - QS_ASSERTION(module, loc, 10000U); /* report assertion to QS */ +//............................................................................ +Q_NORETURN Q_onError(char const * const module, int_t const id) { + // + // NOTE: add here your application-specific error handling + // + Q_UNUSED_PAR(module); + Q_UNUSED_PAR(id); + + QS_ASSERTION(module, id, 10000U); // report assertion to QS NVIC_SystemReset(); } -/*..........................................................................*/ -/* sys_now() is used in the lwIP stack -*/ +//............................................................................ +// sys_now() is used in the lwIP stack +// uint32_t sys_now(void) { return l_nTicks * (1000 / BSP_TICKS_PER_SEC); } +//............................................................................ +void assert_failed(char const * const module, int_t const id); // prototype +void assert_failed(char const * const module, int_t const id) { + Q_onError(module, id); +} -/*--------------------------------------------------------------------------*/ +//---------------------------------------------------------------------------- #ifdef Q_SPY -/*..........................................................................*/ +//............................................................................ uint8_t QS_onStartup(void const *arg) { - static uint8_t qsBuf[6*256]; /* buffer for Quantum Spy */ + static uint8_t qsBuf[6*256]; // buffer for Quantum Spy uint32_t tmp; QS_initBuf(qsBuf, sizeof(qsBuf)); - /* enable the peripherals used by the UART0 */ - SYSCTL->RCGC1 |= (1 << 0); /* enable clock to UART0 */ - SYSCTL->RCGC2 |= (1 << 0); /* enable clock to GPIOA */ - __NOP(); /* wait after enabling clocks */ + // enable the peripherals used by the UART0 + SYSCTL->RCGC1 |= (1 << 0); // enable clock to UART0 + SYSCTL->RCGC2 |= (1 << 0); // enable clock to GPIOA + __NOP(); // wait after enabling clocks __NOP(); __NOP(); - /* configure UART0 pins for UART operation */ + // configure UART0 pins for UART operation tmp = (1 << 0) | (1 << 1); GPIOA->DIR &= ~tmp; GPIOA->AFSEL |= tmp; - GPIOA->DR2R |= tmp; /* set 2mA drive, DR4R and DR8R are cleared */ + GPIOA->DR2R |= tmp; // set 2mA drive, DR4R and DR8R are cleared GPIOA->SLR &= ~tmp; GPIOA->ODR &= ~tmp; GPIOA->PUR &= ~tmp; @@ -262,76 +268,76 @@ uint8_t QS_onStartup(void const *arg) { GPIOA->DEN |= tmp; GPIOA->AMSEL &= ~tmp; - /* configure the UART for the desired baud rate, 8-N-1 operation */ + // configure the UART for the desired baud rate, 8-N-1 operation tmp = (((SystemCoreClock * 8) / UART_BAUD_RATE) + 1) / 2; UART0->IBRD = tmp / 64; UART0->FBRD = tmp % 64; - UART0->LCRH = 0x60; /* configure 8-bit operation */ - UART0->LCRH |= 0x10; /* enable FIFOs */ + UART0->LCRH = 0x60; // configure 8-bit operation + UART0->LCRH |= 0x10; // enable FIFOs UART0->CTL |= (1 << 0) | (1 << 8) | (1 << 9); QS_tickPeriod_ = SystemCoreClock / BSP_TICKS_PER_SEC; - QS_tickTime_ = QS_tickPeriod_; /* to start the timestamp at zero */ + QS_tickTime_ = QS_tickPeriod_; // to start the timestamp at zero - return 1U; /* return success */ + return 1U; // return success } -/*..........................................................................*/ +//............................................................................ void QS_onCleanup(void) { } -/*..........................................................................*/ -QSTimeCtr QS_onGetTime(void) { /* invoked with interrupts disabled */ - if ((SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk) == 0) { /* not set? */ +//............................................................................ +QSTimeCtr QS_onGetTime(void) { // invoked with interrupts disabled + if ((SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk) == 0) { // not set? return QS_tickTime_ - (QSTimeCtr)SysTick->VAL; } - else { /* the rollover occured, but the SysTick_ISR did not run yet */ + else { // the rollover occured, but the SysTick_ISR did not run yet return QS_tickTime_ + QS_tickPeriod_ - (QSTimeCtr)SysTick->VAL; } } -/*..........................................................................*/ +//............................................................................ void QS_onFlush(void) { - uint16_t fifo = UART_TXFIFO_DEPTH; /* Tx FIFO depth */ + uint16_t fifo = UART_TXFIFO_DEPTH; // Tx FIFO depth uint8_t const *block; QF_INT_DISABLE(); while ((block = QS_getBlock(&fifo)) != (uint8_t *)0) { QF_INT_ENABLE(); - /* busy-wait until TX FIFO empty */ + // busy-wait until TX FIFO empty while ((UART0->FR & UART_FR_TXFE) == 0) { } - while (fifo-- != 0) { /* any bytes in the block? */ - UART0->DR = *block++; /* put into the TX FIFO */ + while (fifo-- != 0) { // any bytes in the block? + UART0->DR = *block++; // put into the TX FIFO } - fifo = UART_TXFIFO_DEPTH; /* re-load the Tx FIFO depth */ + fifo = UART_TXFIFO_DEPTH; // re-load the Tx FIFO depth QF_INT_DISABLE(); } QF_INT_ENABLE(); } -#endif /* Q_SPY */ -/*--------------------------------------------------------------------------*/ +#endif // Q_SPY +//---------------------------------------------------------------------------- -/***************************************************************************** -* NOTE1: -* The QF_AWARE_ISR_CMSIS_PRI constant from the QF port specifies the highest -* ISR priority that is disabled by the QF framework. The value is suitable -* for the NVIC_SetPriority() CMSIS function. -* -* Only ISRs prioritized at or below the QF_AWARE_ISR_CMSIS_PRI level (i.e., -* with the numerical values of priorities equal or higher than -* QF_AWARE_ISR_CMSIS_PRI) are allowed to call the QK_ISR_ENTRY/QK_ISR_ENTRY -* macros or any other QF/QK services. These ISRs are "QF-aware". -* -* Conversely, any ISRs prioritized above the QF_AWARE_ISR_CMSIS_PRI priority -* level (i.e., with the numerical values of priorities less than -* QF_AWARE_ISR_CMSIS_PRI) are never disabled and are not aware of the kernel. -* Such "QF-unaware" ISRs cannot call any QF/QK services. In particular they -* can NOT call the macros QK_ISR_ENTRY/QK_ISR_ENTRY. The only mechanism -* by which a "QF-unaware" ISR can communicate with the QF framework is by -* triggering a "QF-aware" ISR, which can post/publish events. -* -* NOTE2: -* The User LED is used to visualize the idle loop activity. The brightness -* of the LED is proportional to the frequency of invcations of the idle loop. -* Please note that the LED is toggled with interrupts locked, so no interrupt -* execution time contributes to the brightness of the User LED. -*/ +//============================================================================ +// NOTE1: +// The QF_AWARE_ISR_CMSIS_PRI constant from the QF port specifies the highest +// ISR priority that is disabled by the QF framework. The value is suitable +// for the NVIC_SetPriority() CMSIS function. +// +// Only ISRs prioritized at or below the QF_AWARE_ISR_CMSIS_PRI level (i.e., +// with the numerical values of priorities equal or higher than +// QF_AWARE_ISR_CMSIS_PRI) are allowed to call the QK_ISR_ENTRY/QK_ISR_ENTRY +// macros or any other QF/QK services. These ISRs are "QF-aware". +// +// Conversely, any ISRs prioritized above the QF_AWARE_ISR_CMSIS_PRI priority +// level (i.e., with the numerical values of priorities less than +// QF_AWARE_ISR_CMSIS_PRI) are never disabled and are not aware of the kernel. +// Such "QF-unaware" ISRs cannot call any QF/QK services. In particular they +// can NOT call the macros QK_ISR_ENTRY/QK_ISR_ENTRY. The only mechanism +// by which a "QF-unaware" ISR can communicate with the QF framework is by +// triggering a "QF-aware" ISR, which can post/publish events. +// +// NOTE2: +// The User LED is used to visualize the idle loop activity. The brightness +// of the LED is proportional to the frequency of invcations of the idle loop. +// Please note that the LED is toggled with interrupts locked, so no interrupt +// execution time contributes to the brightness of the User LED. +// diff --git a/examples/lwip/arm-cm/lwip_ek-lm3s6965/qk/gnu/Makefile b/examples/lwip/arm-cm/lwip_ek-lm3s6965/qk/gnu/Makefile index 4b933af1..33556dfa 100644 --- a/examples/lwip/arm-cm/lwip_ek-lm3s6965/qk/gnu/Makefile +++ b/examples/lwip/arm-cm/lwip_ek-lm3s6965/qk/gnu/Makefile @@ -274,7 +274,7 @@ $(TARGET_BIN): $(TARGET_ELF) $(BIN) -O binary $< $@ $(TARGET_ELF) : $(ASM_OBJS_EXT) $(C_OBJS_EXT) $(CPP_OBJS_EXT) - $(CC) $(CFLAGS) $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o + $(CC) $(CFLAGS) $(QPC)/src/qs/qstamp.c -o $(BIN_DIR)/qstamp.o $(LINK) $(LINKFLAGS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) $(BIN_DIR)/%.d : %.c diff --git a/examples/lwip/arm-cm/lwip_ek-lm3s6965/qk/iar/lwip-qk.ewd b/examples/lwip/arm-cm/lwip_ek-lm3s6965/qk/iar/lwip-qk.ewd index 95b9e57c..0e91d871 100644 --- a/examples/lwip/arm-cm/lwip_ek-lm3s6965/qk/iar/lwip-qk.ewd +++ b/examples/lwip/arm-cm/lwip_ek-lm3s6965/qk/iar/lwip-qk.ewd @@ -11,7 +11,7 @@ C-SPY 2 - 28 + 32 1 1 - - + + + + +
@@ -486,7 +498,7 @@ IJET_ID 2 - 8 + 9 1 1 + + + + + + + + + + + + + @@ -916,7 +980,7 @@ LMIFTDI_ID 2 - 2 + 3 1 1 + + + + + + + NULINK_ID + 2 + + 0 + 1 + 1 + + + @@ -974,7 +1072,7 @@ STLINK_ID 2 - 4 + 8 1 1 + + + + @@ -1185,7 +1300,7 @@ XDS100_ID 2 - 6 + 9 1 1 + + + + @@ -1362,6 +1493,18 @@ $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin 0
+ + $TOOLKIT_DIR$\plugins\rtos\FreeRtos\FreeRtosArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin2.ENU.ewplugin + 0 + $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin 0 @@ -1371,11 +1514,15 @@ 0 - $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9.ewplugin 0 - $TOOLKIT_DIR$\plugins\rtos\TI-RTOS\tirtosplugin.ewplugin + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9BE.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin 0 @@ -1391,11 +1538,11 @@ 0 - $EW_DIR$\common\plugins\CodeCoverage\CodeCoverage.ENU.ewplugin - 1 + $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + 0 - $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + $EW_DIR$\common\plugins\TargetAccessServer\TargetAccessServer.ENU.ewplugin 0 @@ -1414,7 +1561,7 @@ C-SPY 2 - 28 + 32 1 0 - - + + + + + @@ -1889,7 +2048,7 @@ IJET_ID 2 - 8 + 9 1 0 + + + + + + + + + + + + + @@ -2319,7 +2530,7 @@ LMIFTDI_ID 2 - 2 + 3 1 0 + + + + + + + NULINK_ID + 2 + + 0 + 1 + 0 + + + @@ -2377,7 +2622,7 @@ STLINK_ID 2 - 4 + 8 1 0 + + + + @@ -2588,7 +2850,7 @@ XDS100_ID 2 - 6 + 9 1 0 + + + + @@ -2765,6 +3043,18 @@ $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin 0 + + $TOOLKIT_DIR$\plugins\rtos\FreeRtos\FreeRtosArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin2.ENU.ewplugin + 0 + $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin 0 @@ -2774,11 +3064,15 @@ 0 - $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9.ewplugin 0 - $TOOLKIT_DIR$\plugins\rtos\TI-RTOS\tirtosplugin.ewplugin + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9BE.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin 0 @@ -2794,11 +3088,11 @@ 0 - $EW_DIR$\common\plugins\CodeCoverage\CodeCoverage.ENU.ewplugin - 1 + $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + 0 - $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + $EW_DIR$\common\plugins\TargetAccessServer\TargetAccessServer.ENU.ewplugin 0 @@ -2817,7 +3111,7 @@ C-SPY 2 - 28 + 32 1 1 - - + + + + + @@ -3292,7 +3598,7 @@ IJET_ID 2 - 8 + 9 1 1 + + + + + + + + + + + + + @@ -3722,7 +4080,7 @@ LMIFTDI_ID 2 - 2 + 3 1 1 + + + + + + + NULINK_ID + 2 + + 0 + 1 + 1 + + + @@ -3780,7 +4172,7 @@ STLINK_ID 2 - 4 + 8 1 1 + + + + @@ -3991,7 +4400,7 @@ XDS100_ID 2 - 6 + 9 1 1 + + + + @@ -4168,6 +4593,18 @@ $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin 0 + + $TOOLKIT_DIR$\plugins\rtos\FreeRtos\FreeRtosArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin2.ENU.ewplugin + 0 + $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin 0 @@ -4177,11 +4614,15 @@ 0 - $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9.ewplugin 0 - $TOOLKIT_DIR$\plugins\rtos\TI-RTOS\tirtosplugin.ewplugin + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9BE.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin 0 @@ -4197,11 +4638,11 @@ 0 - $EW_DIR$\common\plugins\CodeCoverage\CodeCoverage.ENU.ewplugin - 1 + $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + 0 - $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + $EW_DIR$\common\plugins\TargetAccessServer\TargetAccessServer.ENU.ewplugin 0 diff --git a/examples/lwip/arm-cm/lwip_ek-lm3s6965/qk/iar/lwip-qk.ewp b/examples/lwip/arm-cm/lwip_ek-lm3s6965/qk/iar/lwip-qk.ewp index 0bc557a2..faf020b4 100644 --- a/examples/lwip/arm-cm/lwip_ek-lm3s6965/qk/iar/lwip-qk.ewp +++ b/examples/lwip/arm-cm/lwip_ek-lm3s6965/qk/iar/lwip-qk.ewp @@ -11,9 +11,13 @@ General 3 - 28 + 35 1 1 + - - - - - + + + + + + + + ICCARM 2 - 34 + 37 1 1 - - - + + AARM 2 - 10 + 11 1 1 + @@ -662,13 +675,9 @@ 0 + inputOutputBased - - BICOMP - 0 - - BUILDACTION 1 @@ -681,17 +690,13 @@ ILINK 0 - 20 + 27 1 1 - + + + + + + + + + + + + + + + @@ -1016,11 +1081,6 @@ - - BILINK - 0 - - Coder 0 @@ -1037,9 +1097,13 @@ General 3 - 28 + 35 1 0 + - - - - - + + + + + + + + ICCARM 2 - 34 + 37 1 0 - - - + + AARM 2 - 10 + 11 1 0 + @@ -1688,13 +1761,9 @@ 0 + inputOutputBased - - BICOMP - 0 - - BUILDACTION 1 @@ -1707,17 +1776,13 @@ ILINK 0 - 20 + 27 1 0 - + + + + + + + + + + + + + + + @@ -2042,11 +2167,6 @@ - - BILINK - 0 - - Coder 0 @@ -2063,9 +2183,13 @@ General 3 - 28 + 35 1 1 + - - - - - + + + + + + + + ICCARM 2 - 34 + 37 1 1 - - - + + AARM 2 - 10 + 11 1 1 + @@ -2714,13 +2847,9 @@ 0 + inputOutputBased - - BICOMP - 0 - - BUILDACTION 1 @@ -2733,17 +2862,13 @@ ILINK 0 - 20 + 27 1 1 - + + + + + + + + + + + + + + + @@ -3068,11 +3253,6 @@ - - BILINK - 0 - - Coder 0 @@ -3112,7 +3292,7 @@ $PROJ_DIR$\..\..\philo.c - $PROJ_DIR$\..\..\..\..\..\..\include\qstamp.c + $PROJ_DIR$\..\..\..\..\..\..\src\qs\qstamp.c $PROJ_DIR$\..\..\table.c @@ -3196,10 +3376,10 @@ $PROJ_DIR$\..\..\..\..\..\..\ports\arm-cm\qk\iar\qf_port.h - $PROJ_DIR$\..\..\..\..\..\..\ports\arm-cm\qk\iar\qk_port.h + $PROJ_DIR$\..\..\..\..\..\..\ports\arm-cm\qk\iar\qk_port.c - $PROJ_DIR$\..\..\..\..\..\..\ports\arm-cm\qk\iar\qk_port.c + $PROJ_DIR$\..\..\..\..\..\..\ports\arm-cm\qk\iar\qk_port.h $PROJ_DIR$\..\..\..\..\..\..\ports\arm-cm\qk\iar\qs_port.h diff --git a/examples/lwip/arm-cm/lwip_ek-lm3s6965/qv/bsp.c b/examples/lwip/arm-cm/lwip_ek-lm3s6965/qv/bsp.c index dbdc000c..9ffe0deb 100644 --- a/examples/lwip/arm-cm/lwip_ek-lm3s6965/qv/bsp.c +++ b/examples/lwip/arm-cm/lwip_ek-lm3s6965/qv/bsp.c @@ -1,48 +1,48 @@ -/***************************************************************************** -* Product: DPP with lwIP application, cooperative QV kernel -* Last updated for version 6.9.3 -* Last updated on 2021-03-03 -* -* Q u a n t u m L e a P s -* ------------------------ -* Modern Embedded Software -* -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* -* -*****************************************************************************/ -#include "qpc.h" /* QP/C header file */ -#include "dpp.h" /* application events and active objects */ -#include "bsp.h" /* Board Support Package header file */ +//============================================================================ +// Product: DPP with lwIP application, cooperative QV kernel +// Last updated for version 6.9.3 +// Last updated on 2021-03-03 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// This program is open source software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Alternatively, this program may be distributed and modified under the +// terms of Quantum Leaps commercial licenses, which expressly supersede +// the GNU General Public License and are specifically designed for +// licensees interested in retaining the proprietary status of their code. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Contact information: +// +// +//============================================================================ +#include "qpc.h" // QP/C header file +#include "dpp.h" // application events and active objects +#include "bsp.h" // Board Support Package header file -#include "LM3S6965.h" /* the device specific header (TI) */ +#include "LM3S6965.h" // the device specific header (TI) Q_DEFINE_THIS_FILE -/* ISRs defined in this BSP ------------------------------------------------*/ +// ISRs defined in this BSP ------------------------------------------------ void SysTick_Handler(void); -/* Local-scope objects -----------------------------------------------------*/ +// Local-scope objects ----------------------------------------------------- #define USER_LED (1U << 0) #define USER_BTN (1U << 1) @@ -56,7 +56,7 @@ static uint32_t l_nTicks; QSTimeCtr QS_tickTime_; QSTimeCtr QS_tickPeriod_; - /* QSpy source IDs */ + // QSpy source IDs static QSpyId const l_SysTick_Handler = { 0U }; #define UART_BAUD_RATE 115200U @@ -65,9 +65,9 @@ static uint32_t l_nTicks; #endif -/*..........................................................................*/ +//............................................................................ void SysTick_Handler(void) { - /* state of the button debouncing, see below */ + // state of the button debouncing, see below static struct ButtonsDebouncing { uint32_t depressed; uint32_t previous; @@ -75,50 +75,50 @@ void SysTick_Handler(void) { uint32_t current; uint32_t volatile tmp; - ++l_nTicks; /* count the number of clock ticks */ + ++l_nTicks; // count the number of clock ticks #ifdef Q_SPY - tmp = SysTick->CTRL; /* clear SysTick_CTRL_COUNTFLAG */ - QS_tickTime_ += QS_tickPeriod_; /* account for the clock rollover */ + tmp = SysTick->CTRL; // clear SysTick_CTRL_COUNTFLAG + QS_tickTime_ += QS_tickPeriod_; // account for the clock rollover #endif - QTIMEEVT_TICK_X(0U, &l_SysTick_Handler); /* process time events for rate 0 */ + QTIMEEVT_TICK_X(0U, &l_SysTick_Handler); // process time events for rate 0 - /* Perform the debouncing of buttons. The algorithm for debouncing - * adapted from the book "Embedded Systems Dictionary" by Jack Ganssle - * and Michael Barr, page 71. - */ - current = ~GPIOF->DATA_Bits[USER_BTN]; /* read USER_BTN */ - tmp = buttons.depressed; /* save the debounced depressed buttons */ - buttons.depressed |= (buttons.previous & current); /* set depressed */ - buttons.depressed &= (buttons.previous | current); /* clear released */ - buttons.previous = current; /* update the history */ - tmp ^= buttons.depressed; /* changed debounced depressed */ - if ((tmp & USER_BTN) != 0U) { /* debounced USER_BTN state changed? */ - if ((buttons.depressed & USER_BTN) != 0U) { /* is BTN depressed? */ - static QEvt const bd = { BTN_DOWN_SIG, 0U, 0U }; + // Perform the debouncing of buttons. The algorithm for debouncing + // adapted from the book "Embedded Systems Dictionary" by Jack Ganssle + // and Michael Barr, page 71. + // + current = ~GPIOF->DATA_Bits[USER_BTN]; // read USER_BTN + tmp = buttons.depressed; // save the debounced depressed buttons + buttons.depressed |= (buttons.previous & current); // set depressed + buttons.depressed &= (buttons.previous | current); // clear released + buttons.previous = current; // update the history + tmp ^= buttons.depressed; // changed debounced depressed + if ((tmp & USER_BTN) != 0U) { // debounced USER_BTN state changed? + if ((buttons.depressed & USER_BTN) != 0U) { // is BTN depressed? + static QEvt const bd = QEVT_INITIALIZER(BTN_DOWN_SIG); QACTIVE_PUBLISH(&bd, &l_SysTick_Handler); } - else { /* the button is released */ - static QEvt const bu = { BTN_UP_SIG, 0U, 0U }; + else { // the button is released + static QEvt const bu = QEVT_INITIALIZER(BTN_UP_SIG); QACTIVE_PUBLISH(&bu, &l_SysTick_Handler); } } } -/*..........................................................................*/ +//............................................................................ void BSP_init(void) { - /* NOTE: SystemInit() already called from startup_TM4C123GH6PM.s - * but SystemCoreClock needs to be updated - */ + // NOTE: SystemInit() already called from startup_TM4C123GH6PM.s + // but SystemCoreClock needs to be updated + // SystemCoreClockUpdate(); - SYSCTL->RCGC2 |= (1 << 5); /* enable clock to GPIOF (User and Eth LEDs)*/ + SYSCTL->RCGC2 |= (1 << 5); // enable clock to GPIOF (User and Eth LEDs) __NOP(); __NOP(); - /* configure the pin driving the Ethernet LED */ - GPIOF->DIR &= ~(ETH0_LED | ETH1_LED); /* set direction: hardware */ + // configure the pin driving the Ethernet LED + GPIOF->DIR &= ~(ETH0_LED | ETH1_LED); // set direction: hardware GPIOF->AFSEL |= (ETH0_LED | ETH1_LED); GPIOF->DR2R |= (ETH0_LED | ETH1_LED); GPIOF->ODR &= ~(ETH0_LED | ETH1_LED); @@ -127,15 +127,15 @@ void BSP_init(void) { GPIOF->DEN |= (ETH0_LED | ETH1_LED); GPIOF->AMSEL &= ~(ETH0_LED | ETH1_LED); - /* configure the pin driving the User LED */ - GPIOF->DIR |= USER_LED; /* set direction: output */ + // configure the pin driving the User LED + GPIOF->DIR |= USER_LED; // set direction: output GPIOF->DR2R |= USER_LED; GPIOF->DEN |= USER_LED; GPIOF->AMSEL &= ~USER_LED; - GPIOF->DATA_Bits[USER_LED] = 0; /* turn the LED off */ + GPIOF->DATA_Bits[USER_LED] = 0; // turn the LED off - /* configure the pin connected to the Buttons */ - GPIOF->DIR &= ~USER_BTN; /* set direction: input */ + // configure the pin connected to the Buttons + GPIOF->DIR &= ~USER_BTN; // set direction: input GPIOF->DR2R |= USER_BTN; GPIOF->ODR &= ~USER_BTN; GPIOF->PUR |= USER_BTN; @@ -143,116 +143,122 @@ void BSP_init(void) { GPIOF->DEN |= USER_BTN; GPIOF->AMSEL &= ~USER_BTN; - /* NOTE: - * The OLED display is encapsulated inside the Table AO, so the - * initialization of the OLED display happens in the top-most initial - * transition of the Table AO (see Table_displayInit()). - */ + // NOTE: + // The OLED display is encapsulated inside the Table AO, so the + // initialization of the OLED display happens in the top-most initial + // transition of the Table AO (see Table_displayInit()). + // - if (QS_INIT((void *)0) == 0) { /* initialize the QS software tracing */ + if (QS_INIT((void *)0) == 0) { // initialize the QS software tracing Q_ERROR(); } QS_OBJ_DICTIONARY(&l_SysTick_Handler); - /* setup the QS filters... */ - QS_GLB_FILTER(QS_SM_RECORDS); /* state machine records */ - QS_GLB_FILTER(QS_AO_RECORDS); /* active object records */ - QS_GLB_FILTER(QS_UA_RECORDS); /* all user records */ + // setup the QS filters... + QS_GLB_FILTER(QS_SM_RECORDS); // state machine records + QS_GLB_FILTER(QS_AO_RECORDS); // active object records + QS_GLB_FILTER(QS_UA_RECORDS); // all user records } -/*..........................................................................*/ +//............................................................................ void QF_onStartup(void) { - /* set up the SysTick timer to fire at BSP_TICKS_PER_SEC rate */ + // set up the SysTick timer to fire at BSP_TICKS_PER_SEC rate SysTick_Config(SystemCoreClock / BSP_TICKS_PER_SEC); - /* assing all priority bits for preemption-prio. and none to sub-prio. */ + // assing all priority bits for preemption-prio. and none to sub-prio. NVIC_SetPriorityGrouping(0U); - /* set priorities of ALL ISRs used in the system, see NOTE1 - * - * !!!!!!!!!!!!!!!!!!!!!!!!!!!! CAUTION !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - * Assign a priority to EVERY ISR explicitly by calling NVIC_SetPriority(). - * DO NOT LEAVE THE ISR PRIORITIES AT THE DEFAULT VALUE! - */ + // set priorities of ALL ISRs used in the system, see NOTE1 + // + // !!!!!!!!!!!!!!!!!!!!!!!!!!!! CAUTION !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + // Assign a priority to EVERY ISR explicitly by calling NVIC_SetPriority(). + // DO NOT LEAVE THE ISR PRIORITIES AT THE DEFAULT VALUE! + // NVIC_SetPriority(Ethernet_IRQn, QF_AWARE_ISR_CMSIS_PRI); NVIC_SetPriority(SysTick_IRQn, QF_AWARE_ISR_CMSIS_PRI + 1U); - /* ... */ + // ... - NVIC_EnableIRQ(Ethernet_IRQn); /* enable the Ethernet Interrupt */ + NVIC_EnableIRQ(Ethernet_IRQn); // enable the Ethernet Interrupt } -/*..........................................................................*/ +//............................................................................ void QF_onCleanup(void) { } -/*..........................................................................*/ -void QV_onIdle(void) { /* NOTE: called with interrutps DISABLED, see NOTE2 */ +//............................................................................ +void QV_onIdle(void) { // NOTE: called with interrutps DISABLED, see NOTE2 - /* toggle the User LED on and then off, see NOTE3 */ + // toggle the User LED on and then off, see NOTE3 QF_INT_DISABLE(); - GPIOF->DATA_Bits[USER_LED] = USER_LED; /* turn the User LED on */ - GPIOF->DATA_Bits[USER_LED] = 0; /* turn the User LED off */ + GPIOF->DATA_Bits[USER_LED] = USER_LED; // turn the User LED on + GPIOF->DATA_Bits[USER_LED] = 0; // turn the User LED off QF_INT_ENABLE(); #ifdef Q_SPY - if ((UART0->FR & UART_FR_TXFE) != 0) { /* TX done? */ - uint16_t fifo = UART_TXFIFO_DEPTH; /* max bytes we can accept */ + if ((UART0->FR & UART_FR_TXFE) != 0) { // TX done? + uint16_t fifo = UART_TXFIFO_DEPTH; // max bytes we can accept uint8_t const *block; QF_INT_DISABLE(); - block = QS_getBlock(&fifo); /* try to get next block to transmit */ + block = QS_getBlock(&fifo); // try to get next block to transmit QF_INT_ENABLE(); - while (fifo-- != 0) { /* any bytes in the block? */ - UART0->DR = *block++; /* put into the FIFO */ + while (fifo-- != 0) { // any bytes in the block? + UART0->DR = *block++; // put into the FIFO } } #elif defined NDEBUG - /* Put the CPU and peripherals to the low-power mode. - * you might need to customize the clock management for your application, - * see the datasheet for your particular MCU. - */ - QV_CPU_SLEEP(); /* atomically go to sleep and enable interrupts */ + // Put the CPU and peripherals to the low-power mode. + // you might need to customize the clock management for your application, + // see the datasheet for your particular MCU. + // + QV_CPU_SLEEP(); // atomically go to sleep and enable interrupts #else - QF_INT_ENABLE(); /* just enable interrupts */ + QF_INT_ENABLE(); // just enable interrupts #endif } -/*..........................................................................*/ -Q_NORETURN Q_onAssert(char const * const module, int_t const loc) { - /* - * NOTE: add here your application-specific error handling - */ - (void)module; - (void)loc; - QS_ASSERTION(module, loc, 10000U); /* report assertion to QS */ +//............................................................................ +Q_NORETURN Q_onError(char const * const module, int_t const id) { + // + // NOTE: add here your application-specific error handling + // + Q_UNUSED_PAR(module); + Q_UNUSED_PAR(id); + + QS_ASSERTION(module, id, 10000U); // report assertion to QS NVIC_SystemReset(); } +//............................................................................ +void assert_failed(char const * const module, int_t const id); // prototype +void assert_failed(char const * const module, int_t const id) { + Q_onError(module, id); +} -/*..........................................................................*/ -/* sys_now() is used in the lwIP stack -*/ +//............................................................................ +// sys_now() is used in the lwIP stack +// uint32_t sys_now(void) { return l_nTicks * (1000 / BSP_TICKS_PER_SEC); } -/*--------------------------------------------------------------------------*/ +//---------------------------------------------------------------------------- #ifdef Q_SPY -/*..........................................................................*/ +//............................................................................ uint8_t QS_onStartup(void const *arg) { - static uint8_t qsBuf[6*256]; /* buffer for Quantum Spy */ + static uint8_t qsBuf[6*256]; // buffer for Quantum Spy uint32_t tmp; QS_initBuf(qsBuf, sizeof(qsBuf)); - /* enable the peripherals used by the UART0 */ - SYSCTL->RCGC1 |= (1 << 0); /* enable clock to UART0 */ - SYSCTL->RCGC2 |= (1 << 0); /* enable clock to GPIOA */ - __NOP(); /* wait after enabling clocks */ + // enable the peripherals used by the UART0 + SYSCTL->RCGC1 |= (1 << 0); // enable clock to UART0 + SYSCTL->RCGC2 |= (1 << 0); // enable clock to GPIOA + __NOP(); // wait after enabling clocks __NOP(); __NOP(); - /* configure UART0 pins for UART operation */ + // configure UART0 pins for UART operation tmp = (1 << 0) | (1 << 1); GPIOA->DIR &= ~tmp; GPIOA->AFSEL |= tmp; - GPIOA->DR2R |= tmp; /* set 2mA drive, DR4R and DR8R are cleared */ + GPIOA->DR2R |= tmp; // set 2mA drive, DR4R and DR8R are cleared GPIOA->SLR &= ~tmp; GPIOA->ODR &= ~tmp; GPIOA->PUR &= ~tmp; @@ -260,82 +266,82 @@ uint8_t QS_onStartup(void const *arg) { GPIOA->DEN |= tmp; GPIOA->AMSEL &= ~tmp; - /* configure the UART for the desired baud rate, 8-N-1 operation */ + // configure the UART for the desired baud rate, 8-N-1 operation tmp = (((SystemCoreClock * 8) / UART_BAUD_RATE) + 1) / 2; UART0->IBRD = tmp / 64; UART0->FBRD = tmp % 64; - UART0->LCRH = 0x60; /* configure 8-bit operation */ - UART0->LCRH |= 0x10; /* enable FIFOs */ + UART0->LCRH = 0x60; // configure 8-bit operation + UART0->LCRH |= 0x10; // enable FIFOs UART0->CTL |= (1 << 0) | (1 << 8) | (1 << 9); QS_tickPeriod_ = SystemCoreClock / BSP_TICKS_PER_SEC; - QS_tickTime_ = QS_tickPeriod_; /* to start the timestamp at zero */ + QS_tickTime_ = QS_tickPeriod_; // to start the timestamp at zero - return 1U; /* return success */ + return 1U; // return success } -/*..........................................................................*/ +//............................................................................ void QS_onCleanup(void) { } -/*..........................................................................*/ -QSTimeCtr QS_onGetTime(void) { /* invoked with interrupts disabled */ - if ((SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk) == 0) { /* not set? */ +//............................................................................ +QSTimeCtr QS_onGetTime(void) { // invoked with interrupts disabled + if ((SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk) == 0) { // not set? return QS_tickTime_ - (QSTimeCtr)SysTick->VAL; } - else { /* the rollover occured, but the SysTick_ISR did not run yet */ + else { // the rollover occured, but the SysTick_ISR did not run yet return QS_tickTime_ + QS_tickPeriod_ - (QSTimeCtr)SysTick->VAL; } } -/*..........................................................................*/ +//............................................................................ void QS_onFlush(void) { - uint16_t fifo = UART_TXFIFO_DEPTH; /* Tx FIFO depth */ + uint16_t fifo = UART_TXFIFO_DEPTH; // Tx FIFO depth uint8_t const *block; QF_INT_DISABLE(); while ((block = QS_getBlock(&fifo)) != (uint8_t *)0) { QF_INT_ENABLE(); - /* busy-wait until TX FIFO empty */ + // busy-wait until TX FIFO empty while ((UART0->FR & UART_FR_TXFE) == 0) { } - while (fifo-- != 0) { /* any bytes in the block? */ - UART0->DR = *block++; /* put into the TX FIFO */ + while (fifo-- != 0) { // any bytes in the block? + UART0->DR = *block++; // put into the TX FIFO } - fifo = UART_TXFIFO_DEPTH; /* re-load the Tx FIFO depth */ + fifo = UART_TXFIFO_DEPTH; // re-load the Tx FIFO depth QF_INT_DISABLE(); } QF_INT_ENABLE(); } -#endif /* Q_SPY */ -/*--------------------------------------------------------------------------*/ +#endif // Q_SPY +//---------------------------------------------------------------------------- -/***************************************************************************** -* NOTE1: -* The QF_AWARE_ISR_CMSIS_PRI constant from the QF port specifies the highest -* ISR priority that is disabled by the QF framework. The value is suitable -* for the NVIC_SetPriority() CMSIS function. -* -* Only ISRs prioritized at or below the QF_AWARE_ISR_CMSIS_PRI level (i.e., -* with the numerical values of priorities equal or higher than -* QF_AWARE_ISR_CMSIS_PRI) are allowed to call the QK_ISR_ENTRY/QK_ISR_ENTRY -* macros or any other QF/QK services. These ISRs are "QF-aware". -* -* Conversely, any ISRs prioritized above the QF_AWARE_ISR_CMSIS_PRI priority -* level (i.e., with the numerical values of priorities less than -* QF_AWARE_ISR_CMSIS_PRI) are never disabled and are not aware of the kernel. -* Such "QF-unaware" ISRs cannot call any QF/QK services. In particular they -* can NOT call the macros QK_ISR_ENTRY/QK_ISR_ENTRY. The only mechanism -* by which a "QF-unaware" ISR can communicate with the QF framework is by -* triggering a "QF-aware" ISR, which can post/publish events. -* -* NOTE2: -* The QV_onIdle() callback is called with interrupts disabled, because the -* determination of the idle condition might change by any interrupt posting -* an event. QV_onIdle() must internally enable interrupts, ideally -* atomically with putting the CPU to the power-saving mode. -* -* NOTE3: -* The User LED is used to visualize the idle loop activity. The brightness -* of the LED is proportional to the frequency of invcations of the idle loop. -* Please note that the LED is toggled with interrupts locked, so no interrupt -* execution time contributes to the brightness of the User LED. -*/ +//============================================================================ +// NOTE1: +// The QF_AWARE_ISR_CMSIS_PRI constant from the QF port specifies the highest +// ISR priority that is disabled by the QF framework. The value is suitable +// for the NVIC_SetPriority() CMSIS function. +// +// Only ISRs prioritized at or below the QF_AWARE_ISR_CMSIS_PRI level (i.e., +// with the numerical values of priorities equal or higher than +// QF_AWARE_ISR_CMSIS_PRI) are allowed to call the QK_ISR_ENTRY/QK_ISR_ENTRY +// macros or any other QF/QK services. These ISRs are "QF-aware". +// +// Conversely, any ISRs prioritized above the QF_AWARE_ISR_CMSIS_PRI priority +// level (i.e., with the numerical values of priorities less than +// QF_AWARE_ISR_CMSIS_PRI) are never disabled and are not aware of the kernel. +// Such "QF-unaware" ISRs cannot call any QF/QK services. In particular they +// can NOT call the macros QK_ISR_ENTRY/QK_ISR_ENTRY. The only mechanism +// by which a "QF-unaware" ISR can communicate with the QF framework is by +// triggering a "QF-aware" ISR, which can post/publish events. +// +// NOTE2: +// The QV_onIdle() callback is called with interrupts disabled, because the +// determination of the idle condition might change by any interrupt posting +// an event. QV_onIdle() must internally enable interrupts, ideally +// atomically with putting the CPU to the power-saving mode. +// +// NOTE3: +// The User LED is used to visualize the idle loop activity. The brightness +// of the LED is proportional to the frequency of invcations of the idle loop. +// Please note that the LED is toggled with interrupts locked, so no interrupt +// execution time contributes to the brightness of the User LED. +// diff --git a/examples/lwip/arm-cm/lwip_ek-lm3s6965/qv/gnu/Makefile b/examples/lwip/arm-cm/lwip_ek-lm3s6965/qv/gnu/Makefile index a3140c98..3f48c442 100644 --- a/examples/lwip/arm-cm/lwip_ek-lm3s6965/qv/gnu/Makefile +++ b/examples/lwip/arm-cm/lwip_ek-lm3s6965/qv/gnu/Makefile @@ -274,7 +274,7 @@ $(TARGET_BIN): $(TARGET_ELF) $(BIN) -O binary $< $@ $(TARGET_ELF) : $(ASM_OBJS_EXT) $(C_OBJS_EXT) $(CPP_OBJS_EXT) - $(CC) $(CFLAGS) $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o + $(CC) $(CFLAGS) $(QPC)/src/qs/qstamp.c -o $(BIN_DIR)/qstamp.o $(LINK) $(LINKFLAGS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) $(BIN_DIR)/%.d : %.c diff --git a/examples/lwip/arm-cm/lwip_ek-lm3s6965/qv/iar/lwip-qv.ewd b/examples/lwip/arm-cm/lwip_ek-lm3s6965/qv/iar/lwip-qv.ewd index 95b9e57c..0e91d871 100644 --- a/examples/lwip/arm-cm/lwip_ek-lm3s6965/qv/iar/lwip-qv.ewd +++ b/examples/lwip/arm-cm/lwip_ek-lm3s6965/qv/iar/lwip-qv.ewd @@ -11,7 +11,7 @@ C-SPY 2 - 28 + 32 1 1 - - + + + + + @@ -486,7 +498,7 @@ IJET_ID 2 - 8 + 9 1 1 + + + + + + + + + + + + + @@ -916,7 +980,7 @@ LMIFTDI_ID 2 - 2 + 3 1 1 + + + + + + + NULINK_ID + 2 + + 0 + 1 + 1 + + + @@ -974,7 +1072,7 @@ STLINK_ID 2 - 4 + 8 1 1 + + + + @@ -1185,7 +1300,7 @@ XDS100_ID 2 - 6 + 9 1 1 + + + + @@ -1362,6 +1493,18 @@ $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin 0 + + $TOOLKIT_DIR$\plugins\rtos\FreeRtos\FreeRtosArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin2.ENU.ewplugin + 0 + $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin 0 @@ -1371,11 +1514,15 @@ 0 - $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9.ewplugin 0 - $TOOLKIT_DIR$\plugins\rtos\TI-RTOS\tirtosplugin.ewplugin + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9BE.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin 0 @@ -1391,11 +1538,11 @@ 0 - $EW_DIR$\common\plugins\CodeCoverage\CodeCoverage.ENU.ewplugin - 1 + $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + 0 - $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + $EW_DIR$\common\plugins\TargetAccessServer\TargetAccessServer.ENU.ewplugin 0 @@ -1414,7 +1561,7 @@ C-SPY 2 - 28 + 32 1 0 - - + + + + + @@ -1889,7 +2048,7 @@ IJET_ID 2 - 8 + 9 1 0 + + + + + + + + + + + + + @@ -2319,7 +2530,7 @@ LMIFTDI_ID 2 - 2 + 3 1 0 + + + + + + + NULINK_ID + 2 + + 0 + 1 + 0 + + + @@ -2377,7 +2622,7 @@ STLINK_ID 2 - 4 + 8 1 0 + + + + @@ -2588,7 +2850,7 @@ XDS100_ID 2 - 6 + 9 1 0 + + + + @@ -2765,6 +3043,18 @@ $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin 0 + + $TOOLKIT_DIR$\plugins\rtos\FreeRtos\FreeRtosArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin2.ENU.ewplugin + 0 + $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin 0 @@ -2774,11 +3064,15 @@ 0 - $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9.ewplugin 0 - $TOOLKIT_DIR$\plugins\rtos\TI-RTOS\tirtosplugin.ewplugin + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9BE.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin 0 @@ -2794,11 +3088,11 @@ 0 - $EW_DIR$\common\plugins\CodeCoverage\CodeCoverage.ENU.ewplugin - 1 + $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + 0 - $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + $EW_DIR$\common\plugins\TargetAccessServer\TargetAccessServer.ENU.ewplugin 0 @@ -2817,7 +3111,7 @@ C-SPY 2 - 28 + 32 1 1 - - + + + + + @@ -3292,7 +3598,7 @@ IJET_ID 2 - 8 + 9 1 1 + + + + + + + + + + + + + @@ -3722,7 +4080,7 @@ LMIFTDI_ID 2 - 2 + 3 1 1 + + + + + + + NULINK_ID + 2 + + 0 + 1 + 1 + + + @@ -3780,7 +4172,7 @@ STLINK_ID 2 - 4 + 8 1 1 + + + + @@ -3991,7 +4400,7 @@ XDS100_ID 2 - 6 + 9 1 1 + + + + @@ -4168,6 +4593,18 @@ $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin 0 + + $TOOLKIT_DIR$\plugins\rtos\FreeRtos\FreeRtosArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin2.ENU.ewplugin + 0 + $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin 0 @@ -4177,11 +4614,15 @@ 0 - $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9.ewplugin 0 - $TOOLKIT_DIR$\plugins\rtos\TI-RTOS\tirtosplugin.ewplugin + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9BE.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin 0 @@ -4197,11 +4638,11 @@ 0 - $EW_DIR$\common\plugins\CodeCoverage\CodeCoverage.ENU.ewplugin - 1 + $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + 0 - $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + $EW_DIR$\common\plugins\TargetAccessServer\TargetAccessServer.ENU.ewplugin 0 diff --git a/examples/lwip/arm-cm/lwip_ek-lm3s6965/qv/iar/lwip-qv.ewp b/examples/lwip/arm-cm/lwip_ek-lm3s6965/qv/iar/lwip-qv.ewp index c459ee9a..51aa1dae 100644 --- a/examples/lwip/arm-cm/lwip_ek-lm3s6965/qv/iar/lwip-qv.ewp +++ b/examples/lwip/arm-cm/lwip_ek-lm3s6965/qv/iar/lwip-qv.ewp @@ -11,9 +11,13 @@ General 3 - 28 + 35 1 1 + - - - - - + + + + + + + + ICCARM 2 - 34 + 37 1 1 - - - + + AARM 2 - 10 + 11 1 1 + @@ -662,13 +675,9 @@ 0 + inputOutputBased - - BICOMP - 0 - - BUILDACTION 1 @@ -681,17 +690,13 @@ ILINK 0 - 20 + 27 1 1 - + + + + + + + + + + + + + + + @@ -1016,11 +1081,6 @@ - - BILINK - 0 - - Coder 0 @@ -1037,9 +1097,13 @@ General 3 - 28 + 35 1 0 + - - - - - + + + + + + + + ICCARM 2 - 34 + 37 1 0 - - - + + AARM 2 - 10 + 11 1 0 + @@ -1688,13 +1761,9 @@ 0 + inputOutputBased - - BICOMP - 0 - - BUILDACTION 1 @@ -1707,17 +1776,13 @@ ILINK 0 - 20 + 27 1 0 - + + + + + + + + + + + + + + + @@ -2042,11 +2167,6 @@ - - BILINK - 0 - - Coder 0 @@ -2063,9 +2183,13 @@ General 3 - 28 + 35 1 1 + - - - - - + + + + + + + + ICCARM 2 - 34 + 37 1 1 - - - + + AARM 2 - 10 + 11 1 1 + @@ -2714,13 +2847,9 @@ 0 + inputOutputBased - - BICOMP - 0 - - BUILDACTION 1 @@ -2733,17 +2862,13 @@ ILINK 0 - 20 + 27 1 1 - + + + + + + + + + + + + + + + @@ -3068,11 +3253,6 @@ - - BILINK - 0 - - Coder 0 @@ -3112,7 +3292,7 @@ $PROJ_DIR$\..\..\philo.c - $PROJ_DIR$\..\..\..\..\..\..\include\qstamp.c + $PROJ_DIR$\..\..\..\..\..\..\src\qs\qstamp.c $PROJ_DIR$\..\..\table.c diff --git a/examples/lwip/arm-cm/lwip_ek-lm3s6965/table.c b/examples/lwip/arm-cm/lwip_ek-lm3s6965/table.c index 0b2d757e..3252293d 100644 --- a/examples/lwip/arm-cm/lwip_ek-lm3s6965/table.c +++ b/examples/lwip/arm-cm/lwip_ek-lm3s6965/table.c @@ -1,47 +1,47 @@ -/***************************************************************************** -* Product: DPP example with lwIP and direct screen output -* Last updated for version 7.2.0 -* Last updated on 2022-12-22 -* -* Q u a n t u m L e a P s -* ------------------------ -* Modern Embedded Software -* -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* -* -*****************************************************************************/ -#include "qpc.h" /* QP/C header file */ -#include "dpp.h" /* application events and active objects */ -#include "bsp.h" /* Board Support Package header file */ +//============================================================================ +// Product: DPP example with lwIP and direct screen output +// Last updated for version 7.2.0 +// Last updated on 2022-12-22 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// This program is open source software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Alternatively, this program may be distributed and modified under the +// terms of Quantum Leaps commercial licenses, which expressly supersede +// the GNU General Public License and are specifically designed for +// licensees interested in retaining the proprietary status of their code. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Contact information: +// +// +//============================================================================ +#include "qpc.h" // QP/C header file +#include "dpp.h" // application events and active objects +#include "bsp.h" // Board Support Package header file -#include "rit128x96x4.h" /* RITEK 128x96x4 OLED used in Rev C-D boards */ +#include "rit128x96x4.h" // RITEK 128x96x4 OLED used in Rev C-D boards -#include /* for snprintf() */ +#include // for snprintf() Q_DEFINE_THIS_FILE -/* Active object class -----------------------------------------------------*/ +// Active object class ----------------------------------------------------- typedef struct TableTag { QActive super; @@ -68,15 +68,15 @@ static void Table_displyCgiText(Table *me, char const *text); enum ForkState { FREE, USED }; #ifdef Q_SPY -enum AppRecords { /* application-specific QS trace records */ +enum AppRecords { // application-specific QS trace records PHILO_STAT = QS_USER, CGI_TEXT, UDP_TEXT, }; #endif -/* Local objects -----------------------------------------------------------*/ -static Table l_table; /* the single instance of the Table active object */ +// Local objects ----------------------------------------------------------- +static Table l_table; // the single instance of the Table active object enum TablePrivateSignals { DISPLAY_TIMEOUT_SIG = MAX_SIG @@ -84,10 +84,10 @@ enum TablePrivateSignals { #define DISPLAY_TIMEOUT (BSP_TICKS_PER_SEC * 30) -/* Global-scope objects ----------------------------------------------------*/ -QActive * const AO_Table = (QActive *)&l_table; /* "opaque" AO pointer */ +// Global-scope objects ---------------------------------------------------- +QActive * const AO_Table = (QActive *)&l_table; // "opaque" AO pointer -/*..........................................................................*/ +//............................................................................ void Table_ctor(void) { uint8_t n; Table *me = &l_table; @@ -102,11 +102,11 @@ void Table_ctor(void) { } me->udpCtr = 0; } -/*..........................................................................*/ +//............................................................................ QState Table_initial(Table *me, QEvt const *e) { - (void)e; /* unused parameter */ + (void)e; // unused parameter - /* Initialize the OLED display */ + // Initialize the OLED display Table_displayInit(me); QActive_subscribe((QActive *)me, DONE_SIG); @@ -119,18 +119,18 @@ QState Table_initial(Table *me, QEvt const *e) { QS_FUN_DICTIONARY(&Table_initial); QS_FUN_DICTIONARY(&Table_serving); - QS_SIG_DICTIONARY(DONE_SIG, 0); /* global signals */ + QS_SIG_DICTIONARY(DONE_SIG, 0); // global signals QS_SIG_DICTIONARY(EAT_SIG, 0); QS_SIG_DICTIONARY(DISPLAY_IPADDR_SIG, 0); QS_SIG_DICTIONARY(DISPLAY_CGI_SIG, 0); QS_SIG_DICTIONARY(DISPLAY_UDP_SIG, 0); - QS_SIG_DICTIONARY(HUNGRY_SIG, me); /* signal just for Table */ - QS_SIG_DICTIONARY(DISPLAY_TIMEOUT_SIG, me); /* signal just for Table */ + QS_SIG_DICTIONARY(HUNGRY_SIG, me); // signal just for Table + QS_SIG_DICTIONARY(DISPLAY_TIMEOUT_SIG, me); // signal just for Table return Q_TRAN(&Table_serving); } -/*..........................................................................*/ +//............................................................................ QState Table_serving(Table *me, QEvt const *e) { uint8_t n, m; TableEvt *pe; @@ -149,7 +149,7 @@ QState Table_serving(Table *me, QEvt const *e) { } case HUNGRY_SIG: { n = ((TableEvt const *)e)->philoNum; - /* phil ID must be in range and he must be not hungry */ + // phil ID must be in range and he must be not hungry Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); Table_displayPhilStat(me, n, "hungry "); @@ -168,16 +168,16 @@ QState Table_serving(Table *me, QEvt const *e) { } case DONE_SIG: { n = ((TableEvt const *)e)->philoNum; - /* phil ID must be in range and he must be not hungry */ + // phil ID must be in range and he must be not hungry Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); Table_displayPhilStat(me, n, "thinking"); m = LEFT(n); - /* both forks of Phil[n] must be used */ + // both forks of Phil[n] must be used Q_ASSERT((me->fork[n] == USED) && (me->fork[m] == USED)); me->fork[m] = me->fork[n] = FREE; - m = RIGHT(n); /* check the right neighbor */ + m = RIGHT(n); // check the right neighbor if (me->isHungry[m] && (me->fork[m] == FREE)) { me->fork[n] = me->fork[m] = USED; me->isHungry[m] = 0; @@ -186,8 +186,8 @@ QState Table_serving(Table *me, QEvt const *e) { QACTIVE_PUBLISH((QEvt *)pe, &me->super); Table_displayPhilStat(me, m, "eating "); } - m = LEFT(n); /* check the left neighbor */ - n = LEFT(m); /* left fork of the left neighbor */ + m = LEFT(n); // check the left neighbor + n = LEFT(m); // left fork of the left neighbor if (me->isHungry[m] && (me->fork[n] == FREE)) { me->fork[m] = me->fork[n] = USED; me->isHungry[m] = 0; @@ -223,7 +223,7 @@ QState Table_serving(Table *me, QEvt const *e) { te = Q_NEW(TextEvt, SEND_UDP_SIG); snprintf(te->text, Q_DIM(te->text), "%s-%d", Q_EVT_CAST(TextEvt)->text, (int)me->udpCtr); - QACTIVE_POST(AO_LwIPMgr, (QEvt *)te, me); /* post directly */ + QACTIVE_POST(AO_LwIPMgr, (QEvt *)te, me); // post directly return Q_HANDLED(); } @@ -231,8 +231,8 @@ QState Table_serving(Table *me, QEvt const *e) { return Q_SUPER(&QHsm_top); } -/* helper functions for the display ........................................*/ -/* include the correct OLED display implementation... */ +// helper functions for the display ........................................ +// include the correct OLED display implementation... void Table_displayInit(Table *me) { RIT128x96x4Init(1000000); RIT128x96x4StringDraw("QP-lwIP Demo", 4*6, 0*8, 9); @@ -243,7 +243,7 @@ void Table_displayInit(Table *me) { RIT128x96x4StringDraw("state-machine.com", 2*6,10*8, 9); me->displayOn = 1; } -/*..........................................................................*/ +//............................................................................ static void Table_displayOn(Table *me) { QTimeEvt_rearm(&me->te_DISPLAY_TIMEOUT, DISPLAY_TIMEOUT); if (!me->displayOn) { @@ -251,14 +251,14 @@ static void Table_displayOn(Table *me) { RIT128x96x4DisplayOn(); } } -/*..........................................................................*/ +//............................................................................ static void Table_displayOff(Table *me) { if (me->displayOn) { me->displayOn = 0; RIT128x96x4DisplayOff(); } } -/*..........................................................................*/ +//............................................................................ static void Table_displayPhilStat(Table *me, uint8_t n, char const *stat) { if (me->displayOn) { char str[2]; @@ -266,35 +266,35 @@ static void Table_displayPhilStat(Table *me, uint8_t n, char const *stat) { str[1] = '\0'; RIT128x96x4StringDraw(str, (6*6 + 3*6*n), 4*8, 15); } - QS_BEGIN_ID(PHILO_STAT, AO_Philo[n]->prio) /* app-specific record */ - QS_U8(1, n); /* Philosopher number */ - QS_STR(stat); /* Philosopher status */ + QS_BEGIN_ID(PHILO_STAT, AO_Philo[n]->prio) // app-specific record + QS_U8(1, n); // Philosopher number + QS_STR(stat); // Philosopher status QS_END() } -/*..........................................................................*/ +//............................................................................ static void Table_displyIPAddr(Table *me, char const *ip_addr) { - Table_displayOn(me); /* make sure the screen is on */ - RIT128x96x4StringDraw(" ", 5*6, 2*8, 15); /* wipe */ + Table_displayOn(me); // make sure the screen is on + RIT128x96x4StringDraw(" ", 5*6, 2*8, 15); // wipe RIT128x96x4StringDraw(ip_addr, 5*6, 2*8, 15); } -/*..........................................................................*/ +//............................................................................ void Table_displyCgiText(Table *me, char const *text) { - Table_displayOn(me); /* make sure the screen is on */ - RIT128x96x4StringDraw(" ", 5*6, 6*8, 15); /* wipe */ + Table_displayOn(me); // make sure the screen is on + RIT128x96x4StringDraw(" ", 5*6, 6*8, 15); // wipe RIT128x96x4StringDraw(text, 5*6, 6*8, 15); - QS_BEGIN_ID(CGI_TEXT, 0U) /* app-specific record */ - QS_STR(text); /* User text */ + QS_BEGIN_ID(CGI_TEXT, 0U) // app-specific record + QS_STR(text); // User text QS_END() } -/*..........................................................................*/ +//............................................................................ void Table_displyUdpText(Table *me, char const *text) { - Table_displayOn(me); /* make sure the screen is on */ - RIT128x96x4StringDraw(" ", 5*6, 6*8, 15); /* wipe */ + Table_displayOn(me); // make sure the screen is on + RIT128x96x4StringDraw(" ", 5*6, 6*8, 15); // wipe RIT128x96x4StringDraw(text, 5*6, 6*8, 15); - QS_BEGIN_ID(UDP_TEXT, 0U) /* app-specific record */ - QS_STR(text); /* User text */ + QS_BEGIN_ID(UDP_TEXT, 0U) // app-specific record + QS_STR(text); // User text QS_END() } diff --git a/examples/msp430/blinky_msp-exp430f5529lp/blinky.c b/examples/msp430/blinky_msp-exp430f5529lp/blinky.c index 96c48e60..68017985 100644 --- a/examples/msp430/blinky_msp-exp430f5529lp/blinky.c +++ b/examples/msp430/blinky_msp-exp430f5529lp/blinky.c @@ -1,68 +1,68 @@ -/***************************************************************************** -* Product: Simple Blinky example -* Last Updated for Version: 7.2.0 -* Date of the Last Update: 2022-12-22 -* -* Q u a n t u m L e a P s -* --------------------------- -* innovating embedded systems -* -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* -* -*****************************************************************************/ +//============================================================================ +// Product: Simple Blinky example +// Last Updated for Version: 7.2.0 +// Date of the Last Update: 2022-12-22 +// +// Q u a n t u m L e a P s +// --------------------------- +// innovating embedded systems +// +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// This program is open source software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Alternatively, this program may be distributed and modified under the +// terms of Quantum Leaps commercial licenses, which expressly supersede +// the GNU General Public License and are specifically designed for +// licensees interested in retaining the proprietary status of their code. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Contact information: +// +// +//============================================================================ #include "qpc.h" #include "blinky.h" #include "bsp.h" //Q_DEFINE_THIS_FILE -/*..........................................................................*/ -typedef struct { /* the Blinky active object */ - QActive super; /* inherit QActive */ +//............................................................................ +typedef struct { // the Blinky active object + QActive super; // inherit QActive - QTimeEvt timeEvt; /* private time event generator */ + QTimeEvt timeEvt; // private time event generator } Blinky; -static Blinky l_blinky; /* the Blinky active object */ +static Blinky l_blinky; // the Blinky active object QActive * const AO_Blinky = &l_blinky.super; -/* hierarchical state machine ... */ +// hierarchical state machine ... static QState Blinky_initial(Blinky * const me, QEvt const * const e); static QState Blinky_off (Blinky * const me, QEvt const * const e); static QState Blinky_on (Blinky * const me, QEvt const * const e); -/*..........................................................................*/ +//............................................................................ void Blinky_ctor(void) { Blinky * const me = &l_blinky; QActive_ctor(&me->super, Q_STATE_CAST(&Blinky_initial)); QTimeEvt_ctorX(&me->timeEvt, &me->super, TIMEOUT_SIG, 0U); } -/* HSM definition ----------------------------------------------------------*/ +// HSM definition ---------------------------------------------------------- QState Blinky_initial(Blinky * const me, QEvt const * const e) { - (void)e; /* avoid compiler warning about unused parameter */ + (void)e; // avoid compiler warning about unused parameter QS_OBJ_DICTIONARY(&l_blinky); QS_OBJ_DICTIONARY(&l_blinky.timeEvt); @@ -71,14 +71,14 @@ QState Blinky_initial(Blinky * const me, QEvt const * const e) { QS_FUN_DICTIONARY(&Blinky_off); QS_FUN_DICTIONARY(&Blinky_on); - QS_SIG_DICTIONARY(DUMMY_SIG, (void *)0); /* global signal */ - QS_SIG_DICTIONARY(TIMEOUT_SIG, me); /* signal just for Blinky */ + QS_SIG_DICTIONARY(DUMMY_SIG, (void *)0); // global signal + QS_SIG_DICTIONARY(TIMEOUT_SIG, me); // signal just for Blinky - /* arm the time event to expire in half a second and every half second */ + // arm the time event to expire in half a second and every half second QTimeEvt_armX(&me->timeEvt, BSP_TICKS_PER_SEC/2U, BSP_TICKS_PER_SEC/2U); return Q_TRAN(&Blinky_off); } -/*..........................................................................*/ +//............................................................................ QState Blinky_off(Blinky * const me, QEvt const * const e) { QState status; switch (e->sig) { @@ -98,7 +98,7 @@ QState Blinky_off(Blinky * const me, QEvt const * const e) { } return status; } -/*..........................................................................*/ +//............................................................................ QState Blinky_on(Blinky * const me, QEvt const * const e) { QState status; switch (e->sig) { diff --git a/examples/msp430/blinky_msp-exp430f5529lp/blinky.h b/examples/msp430/blinky_msp-exp430f5529lp/blinky.h index 5568238a..3ac6dfa3 100644 --- a/examples/msp430/blinky_msp-exp430f5529lp/blinky.h +++ b/examples/msp430/blinky_msp-exp430f5529lp/blinky.h @@ -1,48 +1,48 @@ -/***************************************************************************** -* Product: simple "Blinky" example -* Last Updated for Version: 5.4.0 -* Date of the Last Update: 2015-03-07 -* -* Q u a n t u m L e a P s -* --------------------------- -* innovating embedded systems -* -* Copyright (C) 2005 Quantum Leaps, LLC. state-machine.com. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* -* -*****************************************************************************/ +//============================================================================ +// Product: simple "Blinky" example +// Last Updated for Version: 5.4.0 +// Date of the Last Update: 2015-03-07 +// +// Q u a n t u m L e a P s +// --------------------------- +// innovating embedded systems +// +// Copyright (C) 2005 Quantum Leaps, LLC. state-machine.com. +// +// This program is open source software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Alternatively, this program may be distributed and modified under the +// terms of Quantum Leaps commercial licenses, which expressly supersede +// the GNU General Public License and are specifically designed for +// licensees interested in retaining the proprietary status of their code. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Contact information: +// +// +//============================================================================ #ifndef BLINKY_H #define BLINKY_H enum BlinkySignals { DUMMY_SIG = Q_USER_SIG, - MAX_PUB_SIG, /* the last published signal */ + MAX_PUB_SIG, // the last published signal TIMEOUT_SIG, - MAX_SIG /* the last signal */ + MAX_SIG // the last signal }; void Blinky_ctor(void); -extern QActive * const AO_Blinky; /* opaque pointer */ +extern QActive * const AO_Blinky; // opaque pointer -#endif /* BLINKY_H */ +#endif // BLINKY_H diff --git a/examples/msp430/blinky_msp-exp430f5529lp/bsp.h b/examples/msp430/blinky_msp-exp430f5529lp/bsp.h index 34e7571e..90f6ae9b 100644 --- a/examples/msp430/blinky_msp-exp430f5529lp/bsp.h +++ b/examples/msp430/blinky_msp-exp430f5529lp/bsp.h @@ -1,38 +1,38 @@ -/***************************************************************************** -* Product: "Blinky" example -* Last Updated for Version: 5.6.4 -* Date of the Last Update: 2016-05-07 -* -* Q u a n t u m L e a P s -* --------------------------- -* innovating embedded systems -* -* Copyright (C) 2005 Quantum Leaps, LLC. state-machine.com. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* -* -*****************************************************************************/ -#ifndef BSP_H -#define BSP_H +//============================================================================ +// Product: "Blinky" example +// Last Updated for Version: 5.6.4 +// Date of the Last Update: 2016-05-07 +// +// Q u a n t u m L e a P s +// --------------------------- +// innovating embedded systems +// +// Copyright (C) 2005 Quantum Leaps, LLC. state-machine.com. +// +// This program is open source software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Alternatively, this program may be distributed and modified under the +// terms of Quantum Leaps commercial licenses, which expressly supersede +// the GNU General Public License and are specifically designed for +// licensees interested in retaining the proprietary status of their code. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Contact information: +// +// +//============================================================================ +#ifndef BSP_H_ +#define BSP_H_ #define BSP_TICKS_PER_SEC 100U @@ -40,4 +40,4 @@ void BSP_init(void); void BSP_ledOff(void); void BSP_ledOn(void); -#endif /* BSP_H */ +#endif // BSP_H_ diff --git a/examples/msp430/blinky_msp-exp430f5529lp/main.c b/examples/msp430/blinky_msp-exp430f5529lp/main.c index aac1a812..f83223ec 100644 --- a/examples/msp430/blinky_msp-exp430f5529lp/main.c +++ b/examples/msp430/blinky_msp-exp430f5529lp/main.c @@ -1,60 +1,60 @@ -/***************************************************************************** -* Product: "Blinky" example -* Last updated for version 7.1.1 -* Last updated on 2022-09-22 -* -* Q u a n t u m L e a P s -* ------------------------ -* Modern Embedded Software -* -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* -* -*****************************************************************************/ +//============================================================================ +// Product: "Blinky" example +// Last updated for version 7.1.1 +// Last updated on 2022-09-22 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// This program is open source software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Alternatively, this program may be distributed and modified under the +// terms of Quantum Leaps commercial licenses, which expressly supersede +// the GNU General Public License and are specifically designed for +// licensees interested in retaining the proprietary status of their code. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Contact information: +// +// +//============================================================================ #include "qpc.h" #include "blinky.h" #include "bsp.h" -Q_DEFINE_THIS_FILE +//Q_DEFINE_THIS_FILE -/*..........................................................................*/ +//............................................................................ int main() { - QF_init(); /* initialize the framework and the underlying RT kernel */ - BSP_init(); /* initialize the Board Support Package */ + QF_init(); // initialize the framework and the underlying RT kernel + BSP_init(); // initialize the Board Support Package - /* publish-subscribe not used, no call to QF_psInit() */ - /* dynamic event allocation not used, no call to QF_poolInit() */ + // publish-subscribe not used, no call to QActive_psInit() + // dynamic event allocation not used, no call to QF_poolInit() - /* instantiate and start the active objects... */ + // instantiate and start the active objects... Blinky_ctor(); - static QEvt const *l_blinkyQSto[10]; /* Event queue storage for Blinky */ - QACTIVE_START(AO_Blinky, /* AO pointer to start */ - 2U, /* QF-priority/preemption-threshold */ - l_blinkyQSto, /* storage for the AO's queue */ - Q_DIM(l_blinkyQSto), /* length of the queue [entries] */ - (void *)0, /* stack storage (not used in QK) */ - 0U, /* stack size [bytes] (not used in QK) */ - (QEvt *)0); /* initial event (or 0) */ + static QEvt const *l_blinkyQSto[10]; // Event queue storage for Blinky + QACTIVE_START(AO_Blinky, // AO pointer to start + 2U, // QF-priority/preemption-threshold + l_blinkyQSto, // storage for the AO's queue + Q_DIM(l_blinkyQSto), // length of the queue [entries] + (void *)0, // stack storage (not used in QK) + 0U, // stack size [bytes] (not used in QK) + (QEvt *)0); // initial event (or 0) - return QF_run(); /* run the QF application */ + return QF_run(); // run the QF application } diff --git a/examples/msp430/blinky_msp-exp430f5529lp/qk/bsp.c b/examples/msp430/blinky_msp-exp430f5529lp/qk/bsp.c index 4b48eed4..a2586d34 100644 --- a/examples/msp430/blinky_msp-exp430f5529lp/qk/bsp.c +++ b/examples/msp430/blinky_msp-exp430f5529lp/qk/bsp.c @@ -1,42 +1,42 @@ -/***************************************************************************** -* Product: "Blinky" on MSP-EXP430F5529LP, preemptive QK kernel -* Last updated for version 7.1.1 -* Last updated on 2022-09-09 -* -* Q u a n t u m L e a P s -* ------------------------ -* Modern Embedded Software -* -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* -* -*****************************************************************************/ +//============================================================================ +// Product: "Blinky" on MSP-EXP430F5529LP, preemptive QK kernel +// Last updated for version 7.1.1 +// Last updated on 2022-09-09 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// This program is open source software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Alternatively, this program may be distributed and modified under the +// terms of Quantum Leaps commercial licenses, which expressly supersede +// the GNU General Public License and are specifically designed for +// licensees interested in retaining the proprietary status of their code. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Contact information: +// +// +//============================================================================ #include "qpc.h" #include "blinky.h" #include "bsp.h" -#include /* MSP430 variant used */ -/* add other drivers if necessary... */ +#include // MSP430 variant used +// add other drivers if necessary... Q_DEFINE_THIS_FILE @@ -44,20 +44,49 @@ Q_DEFINE_THIS_FILE #error Simple Blinky Application does not provide Spy build configuration #endif -/* Local-scope objects -----------------------------------------------------*/ -/* 1MHz clock setting, see BSP_init() */ +// Local-scope objects ----------------------------------------------------- +// 1MHz clock setting, see BSP_init() #define BSP_MCK 1000000U #define BSP_SMCLK 1000000U -#define LED1 (1U << 0) -#define LED2 (1U << 7) +#define LED1 (1U << 0U) +#define LED2 (1U << 7U) -#define BTN_S1 (1U << 1) +#define BTN_S1 (1U << 1U) -/* ISRs used in this project ===============================================*/ +//============================================================================ +// Error handler and ISRs... + +Q_NORETURN Q_onError(char const * const module, int_t const id) { + // NOTE: this implementation of the error handler is intended only + // for debugging and MUST be changed for deployment of the application + // (assuming that you ship your production code with assertions enabled). + Q_UNUSED_PAR(module); + Q_UNUSED_PAR(id); + QS_ASSERTION(module, id, 10000U); // report assertion to QS + +#ifndef NDEBUG + P4OUT |= LED2; // turn LED2 on + // for debugging, hang on in an endless loop... + for (;;) { + } +#else + WDTCTL = 0xDEAD; + for (;;) { // explicitly "no-return" + } +#endif +} +//............................................................................ +void assert_failed(char const * const module, int_t const id); // prototype +void assert_failed(char const * const module, int_t const id) { + Q_onError(module, id); +} + +// ISRs used in the application ============================================== + #if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__) - __interrupt void TIMER0_A0_ISR(void); /* prototype */ + __interrupt void TIMER0_A0_ISR(void); // prototype #pragma vector=TIMER0_A0_VECTOR __interrupt void TIMER0_A0_ISR(void) #elif defined(__GNUC__) @@ -67,90 +96,74 @@ Q_DEFINE_THIS_FILE #error MSP430 compiler not supported! #endif { - QK_ISR_ENTRY(); /* inform QK about entering the ISR */ + QK_ISR_ENTRY(); // inform QK about entering the ISR - QTIMEEVT_TICK_X(0U, (void *)0); /* process all time events at rate 0 */ + QTIMEEVT_TICK_X(0U, (void *)0); // process all time events at rate 0 - QK_ISR_EXIT(); /* inform QK about exiting the ISR */ + QK_ISR_EXIT(); // inform QK about exiting the ISR #ifdef NDEBUG - __low_power_mode_off_on_exit(); /* see NOTE1 */ + __low_power_mode_off_on_exit(); // see NOTE1 #endif } -/* BSP functions ===========================================================*/ +// BSP functions =========================================================== void BSP_init(void) { - WDTCTL = WDTPW | WDTHOLD; /* stop watchdog timer */ + WDTCTL = WDTPW | WDTHOLD; // stop watchdog timer - /* leave the MCK and SMCLK at default DCO setting */ + // leave the MCK and SMCLK at default DCO setting - P1DIR |= LED1; /* set LED1 pin to output */ - P4DIR |= LED2; /* set LED2 pin to output */ + P1DIR |= LED1; // set LED1 pin to output + P4DIR |= LED2; // set LED2 pin to output } -/*..........................................................................*/ +//............................................................................ void BSP_ledOff(void) { - P1OUT &= ~LED1; /* turn LED1 off */ + P1OUT &= ~LED1; // turn LED1 off } -/*..........................................................................*/ +//............................................................................ void BSP_ledOn(void) { - P1OUT |= LED1; /* turn LED1 on */ + P1OUT |= LED1; // turn LED1 on } -/* QF callbacks ============================================================*/ +// QF callbacks ============================================================ void QF_onStartup(void) { TA0CCTL0 = CCIE; // CCR0 interrupt enabled TA0CCR0 = BSP_SMCLK / BSP_TICKS_PER_SEC; TA0CTL = TASSEL_2 + MC_1 + TACLR; // SMCLK, upmode, clear TAR } -/*..........................................................................*/ +//............................................................................ void QF_onCleanup(void) { } -/*..........................................................................*/ +//............................................................................ void QK_onIdle(void) { - /* toggle LED2 on and then off, see NOTE2 */ + // toggle LED2 on and then off, see NOTE2 QF_INT_DISABLE(); - P4OUT |= LED2; /* turn LED2 on */ - P4OUT &= ~LED2; /* turn LED2 off */ + P4OUT |= LED2; // turn LED2 on + P4OUT &= ~LED2; // turn LED2 off QF_INT_ENABLE(); #ifdef NDEBUG - /* Put the CPU and peripherals to the low-power mode. - * you might need to customize the clock management for your application, - * see the datasheet for your particular MSP430 MCU. - */ - __low_power_mode_1(); /* enter LPM1; also ENABLES interrupts, see NOTE1 */ + // Put the CPU and peripherals to the low-power mode. + // you might need to customize the clock management for your application, + // see the datasheet for your particular MSP430 MCU. + // + __low_power_mode_1(); // enter LPM1; also ENABLES interrupts, see NOTE1 #endif } -/*..........................................................................*/ -Q_NORETURN Q_onAssert(char const * const module, int_t const loc) { - /* - * NOTE: add here your application-specific error handling - */ - (void)module; - (void)loc; - QS_ASSERTION(module, loc, 10000U); /* report assertion to QS */ - QF_INT_DISABLE(); /* disable all interrupts */ - - /* cause the reset of the CPU... */ - WDTCTL = WDTPW | WDTHOLD; - __asm(" push &0xFFFE"); - /* return from function does the reset */ -} - -/***************************************************************************** -* NOTE1: -* With the preemptive QK kernel for MSP430, the idle callback QK::onIdle() -* will execute only ONCE, if the low-power mode is not explicitly turned OFF -* in the interrupt. This might or might not be what you want. -* -* NOTE2: -* One of the LEDs is used to visualize the idle loop activity. The brightness -* of the LED is proportional to the frequency of invcations of the idle loop. -* Please note that the LED is toggled with interrupts locked, so no interrupt -* execution time contributes to the brightness of the User LED. -*/ +//============================================================================ +// NOTE1: +// With the preemptive QK kernel for MSP430, the idle callback QK::onIdle() +// will execute only ONCE, if the low-power mode is not explicitly turned OFF +// in the interrupt. This might or might not be what you want. +// +// NOTE2: +// One of the LEDs is used to visualize the idle loop activity. The brightness +// of the LED is proportional to the frequency of invcations of the idle loop. +// Please note that the LED is toggled with interrupts locked, so no interrupt +// execution time contributes to the brightness of the User LED. +// diff --git a/examples/msp430/blinky_msp-exp430f5529lp/qk/iar/blinky-qk.ewp b/examples/msp430/blinky_msp-exp430f5529lp/qk/iar/blinky-qk.ewp index 255d3e89..0227f81d 100644 --- a/examples/msp430/blinky_msp-exp430f5529lp/qk/iar/blinky-qk.ewp +++ b/examples/msp430/blinky_msp-exp430f5529lp/qk/iar/blinky-qk.ewp @@ -250,10 +250,6 @@ 38 1 1 -
- + - - @@ -100,70 +103,75 @@ - + - - @@ -187,22 +195,25 @@ - - @@ -279,4 +292,4 @@ - + \ No newline at end of file diff --git a/examples/msp430/dpp_msp-exp430f5529lp/qk/iar/dpp-qk.ewp b/examples/msp430/dpp_msp-exp430f5529lp/qk/iar/dpp-qk.ewp index 9da681c3..ab61e2ed 100644 --- a/examples/msp430/dpp_msp-exp430f5529lp/qk/iar/dpp-qk.ewp +++ b/examples/msp430/dpp_msp-exp430f5529lp/qk/iar/dpp-qk.ewp @@ -3456,6 +3456,9 @@ + + Release + Application @@ -3473,9 +3476,6 @@ $PROJ_DIR$\..\..\philo.c - - $PROJ_DIR$\..\..\..\..\..\include\qstamp.c - $PROJ_DIR$\..\..\table.c @@ -3528,21 +3528,6 @@ $PROJ_DIR$\..\..\..\..\..\src\qk_pkg.h - - QP_port - - $PROJ_DIR$\..\..\..\..\..\ports\msp430\qk\qep_port.h - - - $PROJ_DIR$\..\..\..\..\..\ports\msp430\qk\qf_port.h - - - $PROJ_DIR$\..\..\..\..\..\ports\msp430\qk\qk_port.h - - - $PROJ_DIR$\..\..\..\..\..\ports\msp430\qk\qs_port.h - - QS @@ -3553,7 +3538,7 @@ $PROJ_DIR$\..\..\..\..\..\src\qs\qs.c - $PROJ_DIR$\..\..\..\..\..\src\qs_pkg.h + $PROJ_DIR$\..\..\..\..\..\src\qs\qstamp.c diff --git a/examples/msp430/dpp_msp-exp430f5529lp/qp_config.h b/examples/msp430/dpp_msp-exp430f5529lp/qp_config.h new file mode 100644 index 00000000..7aa4ef89 --- /dev/null +++ b/examples/msp430/dpp_msp-exp430f5529lp/qp_config.h @@ -0,0 +1,50 @@ +//============================================================================ +// QP configuration file example +// Last updated for version: 7.3.0 +// Last updated on: 2023-09-02 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +//============================================================================ +#ifndef QP_CONFIG_H_ +#define QP_CONFIG_H_ + +// NOTE: +// The QP configuration is required in the MSP430 port. + +#define QF_MAX_ACTIVE 8U +#define QF_EVENT_SIZ_SIZE 1U +#define QF_EQUEUE_CTR_SIZE 1U +#define QF_MPOOL_SIZ_SIZE 1U +#define QF_MPOOL_CTR_SIZE 1U +#define QF_TIMEEVT_CTR_SIZE 2U + +#ifdef Q_SPY +// for the Spy build configuration, enable the context-switch callback +#define QF_ON_CONTEXT_SW +#endif + +#endif // QP_CONFIG_H_ diff --git a/examples/msp430/dpp_msp-exp430f5529lp/qv/bsp.c b/examples/msp430/dpp_msp-exp430f5529lp/qv/bsp.c index 87eaf381..17a5dbbf 100644 --- a/examples/msp430/dpp_msp-exp430f5529lp/qv/bsp.c +++ b/examples/msp430/dpp_msp-exp430f5529lp/qv/bsp.c @@ -1,77 +1,105 @@ -/***************************************************************************** -* Product: DPP on MSP-EXP430F5529LP, cooperative QV kernel -* Last updated for version 6.9.1 -* Last updated on 2020-09-22 -* -* Q u a n t u m L e a P s -* ------------------------ -* Modern Embedded Software -* -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* -* -*****************************************************************************/ -#include "qpc.h" -#include "dpp.h" -#include "bsp.h" +//============================================================================ +// Product: DPP on MSP-EXP430F5529LP, QV kernel +// Last updated for version 7.3.0 +// Last updated on 2023-08-15 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. +// +// This program is open source software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Alternatively, this program may be distributed and modified under the +// terms of Quantum Leaps commercial licenses, which expressly supersede +// the GNU General Public License and are specifically designed for +// licensees interested in retaining the proprietary status of their code. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Contact information: +// +// +//============================================================================ +#include "qpc.h" // QP/C real-time embedded framework +#include "dpp.h" // DPP Application interface +#include "bsp.h" // Board Support Package -#include /* MSP430 variant used */ -/* add other drivers if necessary... */ +#include // MSP430 variant used +// add other drivers if necessary... Q_DEFINE_THIS_FILE -/* random seed */ -static uint32_t l_rnd; +static uint32_t l_rndSeed; #ifdef Q_SPY - /* UART1 pins TX:P4.4, RX:P4.5 */ - #define TXD (1U << 4) - #define RXD (1U << 5) + // UART1 pins TX:P4.4, RX:P4.5 + #define TXD (1U << 4U) + #define RXD (1U << 5U) QSTimeCtr QS_tickTime_; static uint8_t const l_timerA_ISR = 0U; - enum AppRecords { /* application-specific trace records */ + enum AppRecords { // application-specific trace records PHILO_STAT = QS_USER, - COMMAND_STAT + CONTEXT_SW, + PAUSED_STAT, }; #endif -/* Local-scope objects -----------------------------------------------------*/ -/* 1MHz clock setting, see BSP_init() */ +// Local-scope objects ----------------------------------------------------- +// 1MHz clock setting, see BSP_init() #define BSP_MCK 1000000U #define BSP_SMCLK 1000000U -#define LED1 (1U << 0) -#define LED2 (1U << 7) +#define LED1 (1U << 0U) +#define LED2 (1U << 7U) -#define BTN_S1 (1U << 1) +#define BTN_S1 (1U << 1U) -/* ISRs used in this project ===============================================*/ +//============================================================================ +// Error handler and ISRs... + +Q_NORETURN Q_onError(char const * const module, int_t const id) { + // NOTE: this implementation of the error handler is intended only + // for debugging and MUST be changed for deployment of the application + // (assuming that you ship your production code with assertions enabled). + Q_UNUSED_PAR(module); + Q_UNUSED_PAR(id); + QS_ASSERTION(module, id, 10000U); // report assertion to QS + +#ifndef NDEBUG + P4OUT |= LED2; // turn LED2 on + // for debugging, hang on in an endless loop... + for (;;) { + } +#else + // write invalid password to WDT: cause a password-validation RESET + WDTCTL = 0xDEAD; + for (;;) {} // explicit no-return +#endif +} +//............................................................................ +void assert_failed(char const * const module, int_t const id); // prototype +void assert_failed(char const * const module, int_t const id) { + Q_onError(module, id); +} + +// ISRs used in this project =============================================== #if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__) - __interrupt void TIMER0_A0_ISR(void); /* prototype */ + __interrupt void TIMER0_A0_ISR(void); // prototype #pragma vector=TIMER0_A0_VECTOR __interrupt void TIMER0_A0_ISR(void) #elif defined(__GNUC__) @@ -82,7 +110,7 @@ static uint32_t l_rnd; #endif { #ifdef NDEBUG - __low_power_mode_off_on_exit(); /* see NOTE1 */ + __low_power_mode_off_on_exit(); // see NOTE1 #endif #ifdef Q_SPY @@ -90,48 +118,89 @@ static uint32_t l_rnd; (((BSP_SMCLK / 8) + BSP_TICKS_PER_SEC/2) / BSP_TICKS_PER_SEC) + 1; #endif - QTIMEEVT_TICK_X(0U, (void *)0); /* process all time events at rate 0 */ + QTIMEEVT_TICK_X(0U, (void *)0); // process all time events at rate 0 } -/* BSP functions ===========================================================*/ +// BSP functions =========================================================== void BSP_init(void) { - WDTCTL = WDTPW | WDTHOLD; /* stop watchdog timer */ + WDTCTL = WDTPW | WDTHOLD; // stop watchdog timer - /* leave the MCK and SMCLK at default DCO setting */ + // leave the MCK and SMCLK at default DCO setting - P1DIR |= LED1; /* set LED1 pin to output */ - P4DIR |= LED2; /* set LED2 pin to output */ + // configure pins for LEDs + P1DIR |= LED1; // set LED1 pin to output + P4DIR |= LED2; // set LED2 pin to output - if (QS_INIT((void *)0) == 0) { /* initialize the QS software tracing */ + // initialize the QS software tracing... + if (!QS_INIT((void *)0)) { Q_ERROR(); } + + // dictionaries... QS_OBJ_DICTIONARY(&l_timerA_ISR); QS_USR_DICTIONARY(PHILO_STAT); - QS_USR_DICTIONARY(COMMAND_STAT); + QS_USR_DICTIONARY(PAUSED_STAT); + QS_USR_DICTIONARY(CONTEXT_SW); - /* setup the QS filters... */ - QS_GLB_FILTER(QS_SM_RECORDS); /* state machine records */ - QS_GLB_FILTER(QS_AO_RECORDS); /* active object records */ - QS_GLB_FILTER(QS_UA_RECORDS); /* all user records */ + QS_ONLY(produce_sig_dict()); + + // setup the QS filters... + QS_GLB_FILTER(QS_ALL_RECORDS); // all records + QS_GLB_FILTER(-QS_QF_TICK); // exclude the clock tick } -/*..........................................................................*/ +//............................................................................ +void BSP_start(void) { + // initialize event pools + static QF_MPOOL_EL(TableEvt) smlPoolSto[2*N_PHILO]; + QF_poolInit(smlPoolSto, sizeof(smlPoolSto), sizeof(smlPoolSto[0])); + + // initialize publish-subscribe + static QSubscrList subscrSto[MAX_PUB_SIG]; + QActive_psInit(subscrSto, Q_DIM(subscrSto)); + + // instantiate and start AOs/threads... + + static QEvt const *philoQueueSto[N_PHILO][10]; + for (uint8_t n = 0U; n < N_PHILO; ++n) { + Philo_ctor(n); + QACTIVE_START(AO_Philo[n], + n + 1U, // QF-prio/pthre. see NOTE1 + philoQueueSto[n], // event queue storage + Q_DIM(philoQueueSto[n]), // queue length [events] + (void *)0, 0U, // no stack storage + (void *)0); // no initialization param + } + + static QEvt const *tableQueueSto[N_PHILO]; + Table_ctor(); + QACTIVE_START(AO_Table, + N_PHILO + 1U, // QP prio. of the AO + tableQueueSto, // event queue storage + Q_DIM(tableQueueSto), // queue length [events] + (void *)0, 0U, // no stack storage + (void *)0); // no initialization param +} +//............................................................................ void BSP_displayPhilStat(uint8_t n, char const *stat) { - if (stat[0] == 'h') { /* is Philo hungry? */ - P1OUT |= LED1; /* turn LED1 on */ + Q_UNUSED_PAR(n); + + if (stat[0] == 'h') { // is Philo hungry? + P1OUT |= LED1; // turn LED1 on } else { - P1OUT &= ~LED1; /* turn LED1 off */ + P1OUT &= ~LED1; // turn LED1 off } - QS_BEGIN_ID(PHILO_STAT, AO_Philo[n]->prio) /* app-specific record */ - QS_U8(1, n); /* Philosopher number */ - QS_STR(stat); /* Philosopher status */ + // app-specific trace record... + QS_BEGIN_ID(PHILO_STAT, AO_Table->prio) + QS_U8(1, n); // Philosopher number + QS_STR(stat); // Philosopher status QS_END() } -/*..........................................................................*/ -void BSP_displayPaused(uint8_t paused) { - /* not enouhg LEDs to implement this feature */ +//............................................................................ +void BSP_displayPaused(uint8_t const paused) { + // not enouhg LEDs to implement this feature if (paused != 0U) { //P1OUT |= LED1; } @@ -139,85 +208,73 @@ void BSP_displayPaused(uint8_t paused) { //P1OUT &= ~LED1; } } -/*..........................................................................*/ -uint32_t BSP_random(void) { /* a very cheap pseudo-random-number generator */ - /* "Super-Duper" Linear Congruential Generator (LCG) - * LCG(2^32, 3*7*11*13*23, 0, seed) - */ - l_rnd = l_rnd * ((uint32_t)3U*7U*11U*13U*23U); +//............................................................................ +void BSP_randomSeed(uint32_t const seed) { + l_rndSeed = seed; +} +//............................................................................ +uint32_t BSP_random(void) { // a very cheap pseudo-random-number generator + // "Super-Duper" Linear Congruential Generator (LCG) + // LCG(2^32, 3*7*11*13*23, 0, seed) + // + uint32_t rnd = l_rndSeed * (3U*7U*11U*13U*23U); + l_rndSeed = rnd; // set for the next time - return l_rnd >> 8; + return (rnd >> 8U); } -/*..........................................................................*/ -void BSP_randomSeed(uint32_t seed) { - l_rnd = seed; -} -/*..........................................................................*/ +//............................................................................ void BSP_terminate(int16_t result) { - (void)result; + Q_UNUSED_PAR(result); } - -/* QF callbacks ============================================================*/ +//============================================================================ +// QF callbacks... void QF_onStartup(void) { TA0CCTL0 = CCIE; // CCR0 interrupt enabled TA0CCR0 = BSP_MCK / BSP_TICKS_PER_SEC; TA0CTL = TASSEL_2 + MC_1 + TACLR; // SMCLK, upmode, clear TAR } -/*..........................................................................*/ +//............................................................................ void QF_onCleanup(void) { } -/*..........................................................................*/ -void QV_onIdle(void) { /* NOTE: called with interrutps DISABLED, see NOTE1 */ - /* toggle LED2 on and then off, see NOTE2 */ - P4OUT |= LED2; /* turn LED2 on */ - P4OUT &= ~LED2; /* turn LED2 off */ +//............................................................................ +void QV_onIdle(void) { // NOTE: called with interrutps DISABLED, see NOTE1 + // toggle LED2 on and then off, see NOTE2 + P4OUT |= LED2; // turn LED2 on + P4OUT &= ~LED2; // turn LED2 off #ifdef Q_SPY + QS_rxParse(); // parse all the received bytes QF_INT_ENABLE(); - QS_rxParse(); /* parse all the received bytes */ + QF_CRIT_EXIT_NOP(); - if ((UCA1STAT & UCBUSY) == 0U) { /* TX NOT busy? */ - - uint16_t b; + if ((UCA1STAT & UCBUSY) == 0U) { // TX done? QF_INT_DISABLE(); - b = QS_getByte(); + uint16_t b = QS_getByte(); QF_INT_ENABLE(); if (b != QS_EOD) { - UCA1TXBUF = (uint8_t)b; /* stick the byte to the TX BUF */ + UCA1TXBUF = (uint8_t)b; // stick the byte to the TX BUF } } #elif defined NDEBUG - /* Put the CPU and peripherals to the low-power mode. - * you might need to customize the clock management for your application, - * see the datasheet for your particular MSP430 MCU. - */ - __low_power_mode_1(); /* enter LPM1; also ENABLES interrupts */ + // Put the CPU and peripherals to the low-power mode. + // you might need to customize the clock management for your application, + // see the datasheet for your particular MSP430 MCU. + // + __low_power_mode_1(); // enter LPM1; also ENABLES interrupts #else - QF_INT_ENABLE(); /* just enable interrupts */ + QF_INT_ENABLE(); // just enable interrupts #endif } -/*..........................................................................*/ -Q_NORETURN Q_onAssert(char const * const module, int_t const loc) { - /* - * NOTE: add here your application-specific error handling - */ - (void)module; - (void)loc; - QS_ASSERTION(module, loc, 10000U); /* report assertion to QS */ - - /* write invalid password to WDT: cause a password-validation RESET */ - WDTCTL = 0xDEAD; -} - -/* QS callbacks ============================================================*/ +//============================================================================ +// QS callbacks... #ifdef Q_SPY #if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__) - __interrupt void USCI_A1_ISR(void); /* prototype */ + __interrupt void USCI_A1_ISR(void); // prototype #pragma vector=USCI_A1_VECTOR __interrupt void USCI_A1_ISR(void) #elif defined(__GNUC__) @@ -232,98 +289,92 @@ Q_NORETURN Q_onAssert(char const * const module, int_t const loc) { QS_RX_PUT(b); } } -/*..........................................................................*/ +//............................................................................ uint8_t QS_onStartup(void const *arg) { - static uint8_t qsBuf[256]; /* buffer for QS; RAM is tight! */ - static uint8_t qsRxBuf[80]; /* buffer for QS receive channel */ + static uint8_t qsBuf[256]; // buffer for QS; RAM is tight! + static uint8_t qsRxBuf[80]; // buffer for QS receive channel //uint16_t tmp; QS_initBuf(qsBuf, sizeof(qsBuf)); QS_rxInitBuf(qsRxBuf, sizeof(qsRxBuf)); - /* USCI setup code... */ - P4SEL |= (RXD | TXD); /* select the UART function for the pins */ - UCA1CTL1 |= UCSWRST; /* reset USCI state machine */ - UCA1CTL1 |= UCSSEL_2; /* choose the SMCLK clock */ + // USCI setup code... + P4SEL |= (RXD | TXD); // select the UART function for the pins + UCA1CTL1 |= UCSWRST; // reset USCI state machine + UCA1CTL1 |= UCSSEL_2; // choose the SMCLK clock #if 1 - UCA1BR0 = 6; /* 1MHz 9600 (see User's Guide) */ - UCA1BR1 = 0; /* 1MHz 9600 */ - /* modulation UCBRSx=0, UCBRFx=0, oversampling */ + UCA1BR0 = 6; // 1MHz 9600 (see User's Guide) + UCA1BR1 = 0; // 1MHz 9600 + // modulation UCBRSx=0, UCBRFx=0, oversampling UCA1MCTL = UCBRS_0 | UCBRF_13 | UCOS16; #else - UCA1BR0 = 9; /* 1MHz 115200 (see User's Guide) */ - UCA1BR1 = 0; /* 1MHz 115200 */ - UCA1MCTL |= UCBRS_1 | UCBRF_0; /* modulation UCBRSx=1, UCBRFx=0 */ + UCA1BR0 = 9; // 1MHz 115200 (see User's Guide) + UCA1BR1 = 0; // 1MHz 115200 + UCA1MCTL |= UCBRS_1 | UCBRF_0; // modulation UCBRSx=1, UCBRFx=0 #endif - UCA1CTL1 &= ~UCSWRST; /* initialize USCI state machine */ - UCA1IE |= UCRXIE; /* Enable USCI_A1 RX interrupt */ + UCA1CTL1 &= ~UCSWRST; // initialize USCI state machine + UCA1IE |= UCRXIE; // Enable USCI_A1 RX interrupt - return 1U; /* return success */ + return 1U; // return success } -/*..........................................................................*/ +//............................................................................ void QS_onCleanup(void) { } -/*..........................................................................*/ -QSTimeCtr QS_onGetTime(void) { /* invoked with interrupts DISABLED */ - if ((TA0CTL & TAIFG) == 0U) { /* interrupt not pending? */ +//............................................................................ +QSTimeCtr QS_onGetTime(void) { // invoked with interrupts DISABLED + if ((TA0CTL & TAIFG) == 0U) { // interrupt not pending? return QS_tickTime_ + TA0R; } - else { /* the rollover occured, but the timerA_ISR did not run yet */ + else { // the rollover occured, but the timerA_ISR did not run yet return QS_tickTime_ + (((BSP_SMCLK/8U) + BSP_TICKS_PER_SEC/2U)/BSP_TICKS_PER_SEC) + 1U + TA0R; } } -/*..........................................................................*/ +//............................................................................ void QS_onFlush(void) { uint16_t b; QF_INT_DISABLE(); - while ((b = QS_getByte()) != QS_EOD) { /* next QS byte available? */ + while ((b = QS_getByte()) != QS_EOD) { // next QS byte available? QF_INT_ENABLE(); - while ((UCA1STAT & UCBUSY) != 0U) { /* TX busy? */ + while ((UCA1STAT & UCBUSY) != 0U) { // TX busy? } - UCA1TXBUF = (uint8_t)b; /* stick the byte to the TX BUF */ + UCA1TXBUF = (uint8_t)b; // stick the byte to the TX BUF QF_INT_DISABLE(); } QF_INT_ENABLE(); } -/*..........................................................................*/ -/*! callback function to reset the target (to be implemented in the BSP) */ +//............................................................................ +//! callback function to reset the target (to be implemented in the BSP) void QS_onReset(void) { - /* write invalid password to WDT: cause a password-validation RESET */ + // write invalid password to WDT: cause a password-validation RESET WDTCTL = 0xDEAD; } -/*..........................................................................*/ -/*! callback function to execute a user command (to be implemented in BSP) */ +//............................................................................ +//! callback function to execute a user command (to be implemented in BSP) void QS_onCommand(uint8_t cmdId, uint32_t param1, uint32_t param2, uint32_t param3) { - (void)cmdId; - (void)param1; - (void)param2; - (void)param3; - QS_BEGIN_ID(COMMAND_STAT, 0U) /* app-specific record */ - QS_U8(2, cmdId); - QS_U32(8, param1); - QS_U32(8, param2); - QS_U32(8, param3); - QS_END() + Q_UNUSED_PAR(cmdId); + Q_UNUSED_PAR(param1); + Q_UNUSED_PAR(param2); + Q_UNUSED_PAR(param3); } -#endif /* Q_SPY */ +#endif // Q_SPY -/***************************************************************************** -* NOTE1: -* With the cooperative QV kernel for MSP430, it is necessary to explicitly -* turn the low-power mode OFF in the interrupt, because the return -* from the interrupt will restore the CPU status register, which will -* re-enter the low-power mode. This, in turn, will prevent the QV event-loop -* from running. -* -* NOTE2: -* One of the LEDs is used to visualize the idle loop activity. The brightness -* of the LED is proportional to the frequency of invocations of the idle loop. -* Please note that the LED is toggled with interrupts disabled, so no -* interrupt execution time contributes to the brightness of the User LED. -*/ +//============================================================================ +// NOTE1: +// With the cooperative QV kernel for MSP430, it is necessary to explicitly +// turn the low-power mode OFF in the interrupt, because the return +// from the interrupt will restore the CPU status register, which will +// re-enter the low-power mode. This, in turn, will prevent the QV event-loop +// from running. +// +// NOTE2: +// One of the LEDs is used to visualize the idle loop activity. The brightness +// of the LED is proportional to the frequency of invocations of the idle loop. +// Please note that the LED is toggled with interrupts disabled, so no +// interrupt execution time contributes to the brightness of the User LED. +// diff --git a/examples/msp430/dpp_msp-exp430f5529lp/qv/ccs-gnu/.cproject b/examples/msp430/dpp_msp-exp430f5529lp/qv/ccs-gnu/.cproject index 06bfd46a..6aa3024d 100644 --- a/examples/msp430/dpp_msp-exp430f5529lp/qv/ccs-gnu/.cproject +++ b/examples/msp430/dpp_msp-exp430f5529lp/qv/ccs-gnu/.cproject @@ -15,22 +15,25 @@ - - @@ -102,68 +105,73 @@ - - @@ -187,22 +195,25 @@ - - @@ -279,4 +292,4 @@ - + \ No newline at end of file diff --git a/examples/msp430/dpp_msp-exp430f5529lp/qv/iar/dpp-qv.ewp b/examples/msp430/dpp_msp-exp430f5529lp/qv/iar/dpp-qv.ewp index 58339245..05d5ef9c 100644 --- a/examples/msp430/dpp_msp-exp430f5529lp/qv/iar/dpp-qv.ewp +++ b/examples/msp430/dpp_msp-exp430f5529lp/qv/iar/dpp-qv.ewp @@ -61,7 +61,7 @@ + + Release + Application @@ -3465,9 +3468,6 @@ $PROJ_DIR$\..\..\philo.c - - $PROJ_DIR$\..\..\..\..\..\include\qstamp.c - $PROJ_DIR$\..\..\table.c @@ -3550,5 +3550,8 @@ $PROJ_DIR$\..\..\..\..\..\src\qs\qs_rx.c + + $PROJ_DIR$\..\..\..\..\..\src\qs\qstamp.c + diff --git a/examples/msp430/dpp_msp-exp430f5529lp/table.c b/examples/msp430/dpp_msp-exp430f5529lp/table.c index e51ee932..c3ae02f0 100644 --- a/examples/msp430/dpp_msp-exp430f5529lp/table.c +++ b/examples/msp430/dpp_msp-exp430f5529lp/table.c @@ -1,121 +1,130 @@ -/*$file${.::table.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* -* Model: dpp.qm -* File: ${.::table.c} -* -* This code has been generated by QM 5.2.4 . -* DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. -* -* SPDX-License-Identifier: GPL-3.0-or-later -* -* This generated code is open source software: you can redistribute it under -* the terms of the GNU General Public License as published by the Free -* Software Foundation. -* -* This code is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -* more details. -* -* NOTE: -* Alternatively, this generated code may be distributed under the terms -* of Quantum Leaps commercial licenses, which expressly supersede the GNU -* General Public License and are specifically designed for licensees -* interested in retaining the proprietary status of their code. -* -* Contact information: -* -* -*/ -/*$endhead${.::table.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -#include "qpc.h" -#include "dpp.h" -#include "bsp.h" +//$file${.::table.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// +// Model: dpp.qm +// File: ${.::table.c} +// +// This code has been generated by QM 5.3.0 . +// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. +// +// SPDX-License-Identifier: GPL-3.0-or-later +// +// This generated code is open source software: you can redistribute it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation. +// +// This code is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// NOTE: +// Alternatively, this generated code may be distributed under the terms +// of Quantum Leaps commercial licenses, which expressly supersede the GNU +// General Public License and are specifically designed for licensees +// interested in retaining the proprietary status of their code. +// +// Contact information: +// +// +// +//$endhead${.::table.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +#include "qpc.h" // QP/C real-time embedded framework +#include "dpp.h" // DPP Application interface +#include "bsp.h" // Board Support Package -Q_DEFINE_THIS_FILE +//$declare${AOs::Table} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/* Active object class -----------------------------------------------------*/ -/*$declare${AOs::Table} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${AOs::Table} ............................................................*/ -typedef struct { -/* protected: */ +//${AOs::Table} .............................................................. +typedef struct Table { +// protected: QActive super; -/* private: */ +// private: uint8_t fork[N_PHILO]; - uint8_t isHungry[N_PHILO]; + bool isHungry[N_PHILO]; + +// public: } Table; -/* protected: */ +extern Table Table_inst; + +// protected: static QState Table_initial(Table * const me, void const * const par); static QState Table_active(Table * const me, QEvt const * const e); static QState Table_serving(Table * const me, QEvt const * const e); static QState Table_paused(Table * const me, QEvt const * const e); -/*$enddecl${AOs::Table} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$enddecl${AOs::Table} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -#define RIGHT(n_) ((uint8_t)(((n_) + (N_PHILO - 1U)) % N_PHILO)) -#define LEFT(n_) ((uint8_t)(((n_) + 1U) % N_PHILO)) -#define FREE ((uint8_t)0) -#define USED ((uint8_t)1) +//---------------------------------------------------------------------------- +Q_DEFINE_THIS_FILE -/* Local objects -----------------------------------------------------------*/ -static Table l_table; /* the single instance of the Table active object */ +// helper function to provide the RIGHT neighbor of a Philo[n] +static inline uint8_t right(uint8_t const n) { + return (uint8_t)((n + (N_PHILO - 1U)) % N_PHILO); +} -/* Global-scope objects ----------------------------------------------------*/ -QActive * const AO_Table = &l_table.super; /* "opaque" AO pointer */ +// helper function to provide the LEFT neighbor of a Philo[n] +static inline uint8_t left(uint8_t const n) { + return (uint8_t)((n + 1U) % N_PHILO); +} -/*..........................................................................*/ -/*$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* Check for the minimum required QP version */ -#if (QP_VERSION < 700U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) -#error qpc version 7.0.0 or higher required +#define FREE ((uint8_t)0U) +#define USED ((uint8_t)1U) + +#define THINKING "thinking" +#define HUNGRY "hungry " +#define EATING "eating " + +//---------------------------------------------------------------------------- + +//$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// Check for the minimum required QP version +#if (QP_VERSION < 730U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) +#error qpc version 7.3.0 or higher required #endif -/*$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -/*$define${AOs::Table_ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//$define${Shared::Table_ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/*${AOs::Table_ctor} .......................................................*/ +//${Shared::Table_ctor} ...................................................... void Table_ctor(void) { - uint8_t n; - Table *me = &l_table; - + Table * const me = &Table_inst; QActive_ctor(&me->super, Q_STATE_CAST(&Table_initial)); - - for (n = 0U; n < N_PHILO; ++n) { + for (uint8_t n = 0U; n < N_PHILO; ++n) { me->fork[n] = FREE; - me->isHungry[n] = 0U; + me->isHungry[n] = false; } } -/*$enddef${AOs::Table_ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*$define${AOs::Table} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//$enddef${Shared::Table_ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +//$define${Shared::AO_Table} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/*${AOs::Table} ............................................................*/ +//${Shared::AO_Table} ........................................................ +QActive * const AO_Table = &Table_inst.super; +//$enddef${Shared::AO_Table} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +//$define${AOs::Table} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/*${AOs::Table::SM} ........................................................*/ +//${AOs::Table} .............................................................. +Table Table_inst; + +//${AOs::Table::SM} .......................................................... static QState Table_initial(Table * const me, void const * const par) { - /*${AOs::Table::SM::initial} */ - (void)par; /* unused parameter */ + //${AOs::Table::SM::initial} + Q_UNUSED_PAR(par); - QS_OBJ_DICTIONARY(&l_table); - - QS_SIG_DICTIONARY(DONE_SIG, (void *)0); /* global signals */ - QS_SIG_DICTIONARY(EAT_SIG, (void *)0); - QS_SIG_DICTIONARY(PAUSE_SIG, (void *)0); - QS_SIG_DICTIONARY(SERVE_SIG, (void *)0); - QS_SIG_DICTIONARY(TERMINATE_SIG, (void *)0); - - QS_SIG_DICTIONARY(HUNGRY_SIG, me); /* signal just for Table */ + #ifdef Q_SPY + Table *Table_inst = me; + QS_OBJ_DICTIONARY(Table_inst); + #endif QActive_subscribe(&me->super, DONE_SIG); QActive_subscribe(&me->super, PAUSE_SIG); QActive_subscribe(&me->super, SERVE_SIG); - QActive_subscribe(&me->super, TERMINATE_SIG); + QActive_subscribe(&me->super, TEST_SIG); for (uint8_t n = 0U; n < N_PHILO; ++n) { me->fork[n] = FREE; - me->isHungry[n] = 0U; - BSP_displayPhilStat(n, "thinking"); + me->isHungry[n] = false; + BSP_displayPhilStat(n, THINKING); } QS_FUN_DICTIONARY(&Table_active); @@ -125,17 +134,16 @@ static QState Table_initial(Table * const me, void const * const par) { return Q_TRAN(&Table_serving); } -/*${AOs::Table::SM::active} ................................................*/ +//${AOs::Table::SM::active} .................................................. static QState Table_active(Table * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${AOs::Table::SM::active::TERMINATE} */ - case TERMINATE_SIG: { - BSP_terminate(0); + //${AOs::Table::SM::active::TEST} + case TEST_SIG: { status_ = Q_HANDLED(); break; } - /*${AOs::Table::SM::active::EAT} */ + //${AOs::Table::SM::active::EAT} case EAT_SIG: { Q_ERROR(); status_ = Q_HANDLED(); @@ -149,108 +157,119 @@ static QState Table_active(Table * const me, QEvt const * const e) { return status_; } -/*${AOs::Table::SM::active::serving} .......................................*/ +//${AOs::Table::SM::active::serving} ......................................... static QState Table_serving(Table * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${AOs::Table::SM::active::serving} */ + //${AOs::Table::SM::active::serving} case Q_ENTRY_SIG: { - uint8_t n; - for (n = 0U; n < N_PHILO; ++n) { /* give permissions to eat... */ - if ((me->isHungry[n] != 0U) - && (me->fork[LEFT(n)] == FREE) + // give permissions to eat... + for (uint8_t n = 0U; n < N_PHILO; ++n) { + if (me->isHungry[n] + && (me->fork[left(n)] == FREE) && (me->fork[n] == FREE)) { - TableEvt *te; - - me->fork[LEFT(n)] = USED; + me->fork[left(n)] = USED; me->fork[n] = USED; - te = Q_NEW(TableEvt, EAT_SIG); - te->philoNum = n; - QACTIVE_PUBLISH(&te->super, &me->super); - me->isHungry[n] = 0U; - BSP_displayPhilStat(n, "eating "); + #ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, EAT_SIG, n); + #else + TableEvt *pe = Q_NEW(TableEvt, EAT_SIG); + pe->philoId = n; + #endif + QACTIVE_PUBLISH(&pe->super, &me->super); + me->isHungry[n] = false; + BSP_displayPhilStat(n, EATING); } } status_ = Q_HANDLED(); break; } - /*${AOs::Table::SM::active::serving::HUNGRY} */ + //${AOs::Table::SM::active::serving::HUNGRY} case HUNGRY_SIG: { - uint8_t n, m; + uint8_t n = Q_EVT_CAST(TableEvt)->philoId; - n = Q_EVT_CAST(TableEvt)->philoNum; - /* phil ID must be in range and he must be not hungry */ - Q_ASSERT((n < N_PHILO) && (me->isHungry[n] == 0U)); + // phil ID must be in range and he must be not hungry + Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); - BSP_displayPhilStat(n, "hungry "); - m = LEFT(n); - /*${AOs::Table::SM::active::serving::HUNGRY::[bothfree]} */ + BSP_displayPhilStat(n, HUNGRY); + uint8_t m = left(n); + //${AOs::Table::SM::active::serving::HUNGRY::[bothfree]} if ((me->fork[m] == FREE) && (me->fork[n] == FREE)) { - TableEvt *pe; me->fork[m] = USED; me->fork[n] = USED; - pe = Q_NEW(TableEvt, EAT_SIG); - pe->philoNum = n; + #ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, EAT_SIG, n); + #else + TableEvt *pe = Q_NEW(TableEvt, EAT_SIG); + pe->philoId = n; + #endif QACTIVE_PUBLISH(&pe->super, &me->super); - BSP_displayPhilStat(n, "eating "); + BSP_displayPhilStat(n, EATING); status_ = Q_HANDLED(); } - /*${AOs::Table::SM::active::serving::HUNGRY::[else]} */ + //${AOs::Table::SM::active::serving::HUNGRY::[else]} else { - me->isHungry[n] = 1U; + me->isHungry[n] = true; status_ = Q_HANDLED(); } break; } - /*${AOs::Table::SM::active::serving::DONE} */ + //${AOs::Table::SM::active::serving::DONE} case DONE_SIG: { - uint8_t n, m; - TableEvt *pe; + uint8_t n = Q_EVT_CAST(TableEvt)->philoId; - n = Q_EVT_CAST(TableEvt)->philoNum; - /* phil ID must be in range and he must be not hungry */ - Q_ASSERT((n < N_PHILO) && (me->isHungry[n] == 0U)); + // phil ID must be in range and he must be not hungry + Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); - BSP_displayPhilStat(n, "thinking"); - m = LEFT(n); - /* both forks of Phil[n] must be used */ + BSP_displayPhilStat(n, THINKING); + uint8_t m = left(n); + + // both forks of Phil[n] must be used Q_ASSERT((me->fork[n] == USED) && (me->fork[m] == USED)); me->fork[m] = FREE; me->fork[n] = FREE; - m = RIGHT(n); /* check the right neighbor */ + m = right(n); // check the right neighbor - if ((me->isHungry[m] != 0U) && (me->fork[m] == FREE)) { + if (me->isHungry[m] && (me->fork[m] == FREE)) { me->fork[n] = USED; me->fork[m] = USED; - me->isHungry[m] = 0U; - pe = Q_NEW(TableEvt, EAT_SIG); - pe->philoNum = m; + me->isHungry[m] = false; + #ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, EAT_SIG, m); + #else + TableEvt *pe = Q_NEW(TableEvt, EAT_SIG); + pe->philoId = m; + #endif QACTIVE_PUBLISH(&pe->super, &me->super); - BSP_displayPhilStat(m, "eating "); + BSP_displayPhilStat(m, EATING); } - m = LEFT(n); /* check the left neighbor */ - n = LEFT(m); /* left fork of the left neighbor */ - if ((me->isHungry[m] != 0U) && (me->fork[n] == FREE)) { + m = left(n); // check the left neighbor + n = left(m); // left fork of the left neighbor + if (me->isHungry[m] && (me->fork[n] == FREE)) { me->fork[m] = USED; me->fork[n] = USED; - me->isHungry[m] = 0U; - pe = Q_NEW(TableEvt, EAT_SIG); - pe->philoNum = m; + me->isHungry[m] = false; + #ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, EAT_SIG, m); + #else + TableEvt *pe = Q_NEW(TableEvt, EAT_SIG); + pe->philoId = m; + #endif QACTIVE_PUBLISH(&pe->super, &me->super); - BSP_displayPhilStat(m, "eating "); + BSP_displayPhilStat(m, EATING); } status_ = Q_HANDLED(); break; } - /*${AOs::Table::SM::active::serving::EAT} */ + //${AOs::Table::SM::active::serving::EAT} case EAT_SIG: { Q_ERROR(); status_ = Q_HANDLED(); break; } - /*${AOs::Table::SM::active::serving::PAUSE} */ + //${AOs::Table::SM::active::serving::PAUSE} case PAUSE_SIG: { status_ = Q_TRAN(&Table_paused); break; @@ -263,48 +282,50 @@ static QState Table_serving(Table * const me, QEvt const * const e) { return status_; } -/*${AOs::Table::SM::active::paused} ........................................*/ +//${AOs::Table::SM::active::paused} .......................................... static QState Table_paused(Table * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${AOs::Table::SM::active::paused} */ + //${AOs::Table::SM::active::paused} case Q_ENTRY_SIG: { BSP_displayPaused(1U); status_ = Q_HANDLED(); break; } - /*${AOs::Table::SM::active::paused} */ + //${AOs::Table::SM::active::paused} case Q_EXIT_SIG: { BSP_displayPaused(0U); status_ = Q_HANDLED(); break; } - /*${AOs::Table::SM::active::paused::SERVE} */ + //${AOs::Table::SM::active::paused::SERVE} case SERVE_SIG: { status_ = Q_TRAN(&Table_serving); break; } - /*${AOs::Table::SM::active::paused::HUNGRY} */ + //${AOs::Table::SM::active::paused::HUNGRY} case HUNGRY_SIG: { - uint8_t n = Q_EVT_CAST(TableEvt)->philoNum; - /* philo ID must be in range and he must be not hungry */ - Q_ASSERT((n < N_PHILO) && (me->isHungry[n] == 0U)); - me->isHungry[n] = 1U; - BSP_displayPhilStat(n, "hungry "); + uint8_t n = Q_EVT_CAST(TableEvt)->philoId; + + // philo ID must be in range and he must be not hungry + Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); + + me->isHungry[n] = true; + BSP_displayPhilStat(n, HUNGRY); status_ = Q_HANDLED(); break; } - /*${AOs::Table::SM::active::paused::DONE} */ + //${AOs::Table::SM::active::paused::DONE} case DONE_SIG: { - uint8_t n, m; + uint8_t n = Q_EVT_CAST(TableEvt)->philoId; - n = Q_EVT_CAST(TableEvt)->philoNum; - /* phil ID must be in range and he must be not hungry */ - Q_ASSERT((n < N_PHILO) && (me->isHungry[n] == 0U)); + // phil ID must be in range and he must be not hungry + Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); - BSP_displayPhilStat(n, "thinking"); - m = LEFT(n); - /* both forks of Phil[n] must be used */ + BSP_displayPhilStat(n, THINKING); + uint8_t m = left(n); + + // both forks of Phil[n] must be used Q_ASSERT((me->fork[n] == USED) && (me->fork[m] == USED)); me->fork[m] = FREE; @@ -319,4 +340,4 @@ static QState Table_paused(Table * const me, QEvt const * const e) { } return status_; } -/*$enddef${AOs::Table} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$enddef${AOs::Table} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/examples/pic32/blinky_microstick2-pic32/blinky.c b/examples/pic32/blinky_microstick2-pic32/blinky.c deleted file mode 100644 index 96c48e60..00000000 --- a/examples/pic32/blinky_microstick2-pic32/blinky.c +++ /dev/null @@ -1,121 +0,0 @@ -/***************************************************************************** -* Product: Simple Blinky example -* Last Updated for Version: 7.2.0 -* Date of the Last Update: 2022-12-22 -* -* Q u a n t u m L e a P s -* --------------------------- -* innovating embedded systems -* -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* -* -*****************************************************************************/ -#include "qpc.h" -#include "blinky.h" -#include "bsp.h" - -//Q_DEFINE_THIS_FILE - -/*..........................................................................*/ -typedef struct { /* the Blinky active object */ - QActive super; /* inherit QActive */ - - QTimeEvt timeEvt; /* private time event generator */ -} Blinky; - -static Blinky l_blinky; /* the Blinky active object */ - -QActive * const AO_Blinky = &l_blinky.super; - -/* hierarchical state machine ... */ -static QState Blinky_initial(Blinky * const me, QEvt const * const e); -static QState Blinky_off (Blinky * const me, QEvt const * const e); -static QState Blinky_on (Blinky * const me, QEvt const * const e); - -/*..........................................................................*/ -void Blinky_ctor(void) { - Blinky * const me = &l_blinky; - QActive_ctor(&me->super, Q_STATE_CAST(&Blinky_initial)); - QTimeEvt_ctorX(&me->timeEvt, &me->super, TIMEOUT_SIG, 0U); -} - -/* HSM definition ----------------------------------------------------------*/ -QState Blinky_initial(Blinky * const me, QEvt const * const e) { - (void)e; /* avoid compiler warning about unused parameter */ - - QS_OBJ_DICTIONARY(&l_blinky); - QS_OBJ_DICTIONARY(&l_blinky.timeEvt); - - QS_FUN_DICTIONARY(&Blinky_initial); - QS_FUN_DICTIONARY(&Blinky_off); - QS_FUN_DICTIONARY(&Blinky_on); - - QS_SIG_DICTIONARY(DUMMY_SIG, (void *)0); /* global signal */ - QS_SIG_DICTIONARY(TIMEOUT_SIG, me); /* signal just for Blinky */ - - /* arm the time event to expire in half a second and every half second */ - QTimeEvt_armX(&me->timeEvt, BSP_TICKS_PER_SEC/2U, BSP_TICKS_PER_SEC/2U); - return Q_TRAN(&Blinky_off); -} -/*..........................................................................*/ -QState Blinky_off(Blinky * const me, QEvt const * const e) { - QState status; - switch (e->sig) { - case Q_ENTRY_SIG: { - BSP_ledOff(); - status = Q_HANDLED(); - break; - } - case TIMEOUT_SIG: { - status = Q_TRAN(&Blinky_on); - break; - } - default: { - status = Q_SUPER(&QHsm_top); - break; - } - } - return status; -} -/*..........................................................................*/ -QState Blinky_on(Blinky * const me, QEvt const * const e) { - QState status; - switch (e->sig) { - case Q_ENTRY_SIG: { - BSP_ledOn(); - status = Q_HANDLED(); - break; - } - case TIMEOUT_SIG: { - status = Q_TRAN(&Blinky_off); - break; - } - default: { - status = Q_SUPER(&QHsm_top); - break; - } - } - return status; -} - diff --git a/examples/pic32/blinky_microstick2-pic32/blinky.h b/examples/pic32/blinky_microstick2-pic32/blinky.h deleted file mode 100644 index 5568238a..00000000 --- a/examples/pic32/blinky_microstick2-pic32/blinky.h +++ /dev/null @@ -1,48 +0,0 @@ -/***************************************************************************** -* Product: simple "Blinky" example -* Last Updated for Version: 5.4.0 -* Date of the Last Update: 2015-03-07 -* -* Q u a n t u m L e a P s -* --------------------------- -* innovating embedded systems -* -* Copyright (C) 2005 Quantum Leaps, LLC. state-machine.com. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* -* -*****************************************************************************/ -#ifndef BLINKY_H -#define BLINKY_H - -enum BlinkySignals { - DUMMY_SIG = Q_USER_SIG, - MAX_PUB_SIG, /* the last published signal */ - - TIMEOUT_SIG, - MAX_SIG /* the last signal */ -}; - -void Blinky_ctor(void); -extern QActive * const AO_Blinky; /* opaque pointer */ - -#endif /* BLINKY_H */ diff --git a/examples/pic32/blinky_microstick2-pic32/bsp.h b/examples/pic32/blinky_microstick2-pic32/bsp.h deleted file mode 100644 index 34e7571e..00000000 --- a/examples/pic32/blinky_microstick2-pic32/bsp.h +++ /dev/null @@ -1,43 +0,0 @@ -/***************************************************************************** -* Product: "Blinky" example -* Last Updated for Version: 5.6.4 -* Date of the Last Update: 2016-05-07 -* -* Q u a n t u m L e a P s -* --------------------------- -* innovating embedded systems -* -* Copyright (C) 2005 Quantum Leaps, LLC. state-machine.com. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* -* -*****************************************************************************/ -#ifndef BSP_H -#define BSP_H - -#define BSP_TICKS_PER_SEC 100U - -void BSP_init(void); -void BSP_ledOff(void); -void BSP_ledOn(void); - -#endif /* BSP_H */ diff --git a/examples/pic32/blinky_microstick2-pic32/main.c b/examples/pic32/blinky_microstick2-pic32/main.c deleted file mode 100644 index 1535c418..00000000 --- a/examples/pic32/blinky_microstick2-pic32/main.c +++ /dev/null @@ -1,60 +0,0 @@ -/***************************************************************************** -* Product: "Blinky" example -* Last updated for version 7.1.1 -* Last updated on 2022-09-22 -* -* Q u a n t u m L e a P s -* ------------------------ -* Modern Embedded Software -* -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* -* -*****************************************************************************/ -#include "qpc.h" -#include "blinky.h" -#include "bsp.h" - -Q_DEFINE_THIS_FILE - -/*..........................................................................*/ -int main() { - QF_init(); /* initialize the framework and the underlying RT kernel */ - BSP_init(); /* initialize the Board Support Package */ - - /* publish-subscribe not used, no call to QF_psInit() */ - /* dynamic event allocation not used, no call to QF_poolInit() */ - - /* instantiate and start the active objects... */ - Blinky_ctor(); - static QEvt const *l_blinkyQSto[10]; /* Event queue storage for Blinky */ - QACTIVE_START(AO_Blinky, /* AO pointer to start */ - 1U, /* QF-priority/preemption-threshold */ - l_blinkyQSto, /* storage for the AO's queue */ - Q_DIM(l_blinkyQSto), /* length of the queue [entries] */ - (void *)0, /* stack storage (not used in QK) */ - 0U, /* stack size [bytes] (not used in QK) */ - (QEvt *)0); /* initial event (or 0) */ - - return QF_run(); /* run the QF application */ -} diff --git a/examples/pic32/blinky_microstick2-pic32/qk/xc32/Makefile b/examples/pic32/blinky_microstick2-pic32/qk/xc32/Makefile deleted file mode 100644 index 17647f99..00000000 --- a/examples/pic32/blinky_microstick2-pic32/qk/xc32/Makefile +++ /dev/null @@ -1,108 +0,0 @@ -# -# There exist several targets which are by default empty and which can be -# used for execution of your targets. These targets are usually executed -# before and after some main targets. They are: -# -# .build-pre: called before 'build' target -# .build-post: called after 'build' target -# .clean-pre: called before 'clean' target -# .clean-post: called after 'clean' target -# .clobber-pre: called before 'clobber' target -# .clobber-post: called after 'clobber' target -# .all-pre: called before 'all' target -# .all-post: called after 'all' target -# .help-pre: called before 'help' target -# .help-post: called after 'help' target -# -# Targets beginning with '.' are not intended to be called on their own. -# -# Main targets can be executed directly, and they are: -# -# build build a specific configuration -# clean remove built files from a configuration -# clobber remove all built files -# all build all configurations -# help print help mesage -# -# Targets .build-impl, .clean-impl, .clobber-impl, .all-impl, and -# .help-impl are implemented in nbproject/makefile-impl.mk. -# -# Available make variables: -# -# CND_BASEDIR base directory for relative paths -# CND_DISTDIR default top distribution directory (build artifacts) -# CND_BUILDDIR default top build directory (object files, ...) -# CONF name of current configuration -# CND_ARTIFACT_DIR_${CONF} directory of build artifact (current configuration) -# CND_ARTIFACT_NAME_${CONF} name of build artifact (current configuration) -# CND_ARTIFACT_PATH_${CONF} path to build artifact (current configuration) -# CND_PACKAGE_DIR_${CONF} directory of package (current configuration) -# CND_PACKAGE_NAME_${CONF} name of package (current configuration) -# CND_PACKAGE_PATH_${CONF} path to package (current configuration) -# -# NOCDDL - - -# Environment -MKDIR=mkdir -CP=cp -CCADMIN=CCadmin -RANLIB=ranlib - - -# build -build: .build-post - -.build-pre: -# Add your pre 'build' code here... - -.build-post: .build-impl -# Add your post 'build' code here... - - -# clean -clean: .clean-post - -.clean-pre: -# Add your pre 'clean' code here... - -.clean-post: .clean-impl -# Add your post 'clean' code here... - - -# clobber -clobber: .clobber-post - -.clobber-pre: -# Add your pre 'clobber' code here... - -.clobber-post: .clobber-impl -# Add your post 'clobber' code here... - - -# all -all: .all-post - -.all-pre: -# Add your pre 'all' code here... - -.all-post: .all-impl -# Add your post 'all' code here... - - -# help -help: .help-post - -.help-pre: -# Add your pre 'help' code here... - -.help-post: .help-impl -# Add your post 'help' code here... - - - -# include project implementation makefile -include nbproject/Makefile-impl.mk - -# include project make variables -include nbproject/Makefile-variables.mk diff --git a/examples/pic32/blinky_microstick2-pic32/qk/xc32/bsp.c b/examples/pic32/blinky_microstick2-pic32/qk/xc32/bsp.c deleted file mode 100644 index 68163d65..00000000 --- a/examples/pic32/blinky_microstick2-pic32/qk/xc32/bsp.c +++ /dev/null @@ -1,155 +0,0 @@ -/***************************************************************************** -* BSP for Blinky example, Microstick II board, preemptive QK kernel, XC32 -* Last updated for version 6.5.1 -* Last updated on 2019-06-10 -* -* Q u a n t u m L e a P s -* ------------------------ -* Modern Embedded Software -* -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* -* -*****************************************************************************/ -#include "qpc.h" -#include "bsp.h" -#include "blinky.h" - -Q_DEFINE_THIS_FILE - -#ifdef Q_SPY - #error Simple Blinky Application does not provide Spy build configuration -#endif - -#pragma config FNOSC = FRCPLL /* 8 MHz */ -#pragma config FPLLIDIV = DIV_2 /* 4 MHz */ -#pragma config FPLLMUL = MUL_20 /* 80 MHz */ -#pragma config FPLLODIV = DIV_2 /* 40 MHz == FRC */ -#pragma config FWDTEN = OFF /* watchdog off */ -#pragma config FPBDIV = DIV_1 /* same peripheral clock */ - -/* #pragma config statements should precede project file includes */ -#include /* header for PIC32 device in use */ -#include - -/* system clock using FRC and PLL: 40 MHz */ -#define SYS_FREQ 40000000U -/* peripheral clock frequency */ -#define PER_HZ (SYS_FREQ / 1U) - -/* controlling the LED of Microstick II */ -#define LED_ON() (LATASET = (1U << 0)) -#define LED_OFF() (LATACLR = (1U << 0)) -#define LED_TOGGLE() (LATAINV = (1U << 0)) - -/* ISRs --------------------------------------------------------------------*/ -void __ISR(_TIMER_2_VECTOR, IPL4SOFT) tickISR(void) { - QK_ISR_ENTRY(); /* inform QK about the ISR entry */ - - IFS0CLR = _IFS0_T2IF_MASK; /* clear the interrupt source */ - - QTIMEEVT_TICK_X(0U, (void *)0); /* handle armed time events at tick rate 0 */ - - QK_ISR_EXIT(); /* inform QK about the ISR exit */ -} -/*..........................................................................*/ -/* for testing interrupt nesting and active object preemption */ -void __ISR(_EXTERNAL_0_VECTOR, IPL6SOFT) testISR(void) { - static QEvt const tout_evt = { TIMEOUT_SIG, 0U, 0U }; - - QK_ISR_ENTRY(); /* inform QK about the ISR entry */ - - IFS0CLR = _IFS0_INT0IF_MASK; /* clear the interrupt source */ - - QACTIVE_POST(AO_Blinky, &tout_evt, (void *)0); - - QK_ISR_EXIT(); /* inform QK about the ISR exit */ -} - -/*--------------------------------------------------------------------------*/ -void BSP_init(void) { - TRISA = 0x00; /* set LED pins as outputs */ - PORTA = 0x00; /* set LED drive state low */ -} -/*..........................................................................*/ -void BSP_terminate(int16_t result) { - (void)result; -} -/*..........................................................................*/ -void BSP_ledOff(void) { - LED_OFF(); -} -/*..........................................................................*/ -void BSP_ledOn(void) { - LED_ON(); -} -/*..........................................................................*/ -/* NOTE: this implementation of the assertion handler is intended only for -* debugging and MUST be changed for deployment of the application (assuming -* that you ship your production code with assertions enabled). -*/ -Q_NORETURN Q_onAssert(char const * const file, int_t const loc) { - (void)file; /* unused parameter */ - (void)loc; /* unused parameter */ - QF_INT_DISABLE(); /* make sure that interrupts are disabled */ - for (;;) { - } -} - -/*..........................................................................*/ -void QF_onStartup(void) { /* entered with interrupts locked */ - INTCONSET = _INTCON_MVEC_MASK; /* configure multi-vectored interrupts */ - - T2CON = 0x0060; /* stop timer, set up for 1:64 prescaler */ - TMR2 = 0; /* count from zero up to the period */ - PR2 = SYS_FREQ / (BSP_TICKS_PER_SEC * 64); /* set the Timer2 period */ - IFS0CLR = _IFS0_T2IF_MASK; /* clear Timer2 Interrupt Flag */ - IEC0SET = _IEC0_T2IE_MASK; /* enable Timer2 interrupt */ - T2CONSET = _T2CON_ON_MASK; /* Start Timer2 */ - - INTCONbits.INT0EP = 1; /* INT0 interrupt on positive edge */ - IEC0SET = _IEC0_INT0IE_MASK; /* enable INT0 interrupt */ - IFS0CLR = _IFS0_INT0IF_MASK; /* clear the interrupt for INT0 */ - - /* explicitly assign priorities to all interrupts... */ - /* NOTE: must match the IPLxSOFT settings in the __ISR() macros */ - IPC2bits.T2IP = 4; /* Timer2 interrupt priority, must match tickISR */ - IPC0bits.INT0IP = 6; /* set INT0 priority; must match IPL in testISR */ -} -/*..........................................................................*/ -void QF_onCleanup(void) { -} -/*..........................................................................*/ -void QK_onIdle(void) { - - /* NOTE: not enough LEDs on the Microstick II board to implement - * the idle loop activity indicator ... - */ - //LED_ON (); /* blink the IDLE LED */ - //LED_OFF(); - -#ifdef NDEBUG - _wait(); /* execute the WAIT instruction to stop the CPU */ -#endif -} - diff --git a/examples/pic32/blinky_microstick2-pic32/qk/xc32/nbproject/Makefile-dbg.mk b/examples/pic32/blinky_microstick2-pic32/qk/xc32/nbproject/Makefile-dbg.mk deleted file mode 100644 index ebcc6c32..00000000 --- a/examples/pic32/blinky_microstick2-pic32/qk/xc32/nbproject/Makefile-dbg.mk +++ /dev/null @@ -1,367 +0,0 @@ -# -# Generated Makefile - do not edit! -# -# Edit the Makefile in the project folder instead (../Makefile). Each target -# has a -pre and a -post target defined where you can add customized code. -# -# This makefile implements configuration specific macros and targets. - - -# Include project Makefile -ifeq "${IGNORE_LOCAL}" "TRUE" -# do not include local makefile. User is passing all local related variables already -else -include Makefile -# Include makefile containing local settings -ifeq "$(wildcard nbproject/Makefile-local-dbg.mk)" "nbproject/Makefile-local-dbg.mk" -include nbproject/Makefile-local-dbg.mk -endif -endif - -# Environment -MKDIR=gnumkdir -p -RM=rm -f -MV=mv -CP=cp - -# Macros -CND_CONF=dbg -ifeq ($(TYPE_IMAGE), DEBUG_RUN) -IMAGE_TYPE=debug -OUTPUT_SUFFIX=elf -DEBUGGABLE_SUFFIX=elf -FINAL_IMAGE=dist/${CND_CONF}/${IMAGE_TYPE}/xc32.${IMAGE_TYPE}.${OUTPUT_SUFFIX} -else -IMAGE_TYPE=production -OUTPUT_SUFFIX=hex -DEBUGGABLE_SUFFIX=elf -FINAL_IMAGE=dist/${CND_CONF}/${IMAGE_TYPE}/xc32.${IMAGE_TYPE}.${OUTPUT_SUFFIX} -endif - -ifeq ($(COMPARE_BUILD), true) -COMPARISON_BUILD=-mafrlcsj -else -COMPARISON_BUILD= -endif - -ifdef SUB_IMAGE_ADDRESS - -else -SUB_IMAGE_ADDRESS_COMMAND= -endif - -# Object Directory -OBJECTDIR=build/${CND_CONF}/${IMAGE_TYPE} - -# Distribution Directory -DISTDIR=dist/${CND_CONF}/${IMAGE_TYPE} - -# Source Files Quoted if spaced -SOURCEFILES_QUOTED_IF_SPACED=../../../../../src/qf/qep_hsm.c ../../../../../src/qf/qep_msm.c ../../../../../src/qf/qf_act.c ../../../../../src/qf/qf_actq.c ../../../../../src/qf/qf_defer.c ../../../../../src/qf/qf_dyn.c ../../../../../src/qf/qf_mem.c ../../../../../src/qf/qf_ps.c ../../../../../src/qf/qf_qact.c ../../../../../src/qf/qf_qeq.c ../../../../../src/qf/qf_qmact.c ../../../../../src/qf/qf_time.c ../../../../../src/qk/qk.c ../../../../../ports/pic32/qk/xc32/qk_port.c bsp.c ../../blinky.c ../../main.c ../../../../../include/qstamp.c - -# Object Files Quoted if spaced -OBJECTFILES_QUOTED_IF_SPACED=${OBJECTDIR}/_ext/820665871/qep_hsm.o ${OBJECTDIR}/_ext/820665871/qep_msm.o ${OBJECTDIR}/_ext/820665871/qf_act.o ${OBJECTDIR}/_ext/820665871/qf_actq.o ${OBJECTDIR}/_ext/820665871/qf_defer.o ${OBJECTDIR}/_ext/820665871/qf_dyn.o ${OBJECTDIR}/_ext/820665871/qf_mem.o ${OBJECTDIR}/_ext/820665871/qf_ps.o ${OBJECTDIR}/_ext/820665871/qf_qact.o ${OBJECTDIR}/_ext/820665871/qf_qeq.o ${OBJECTDIR}/_ext/820665871/qf_qmact.o ${OBJECTDIR}/_ext/820665871/qf_time.o ${OBJECTDIR}/_ext/820665876/qk.o ${OBJECTDIR}/_ext/1627782163/qk_port.o ${OBJECTDIR}/bsp.o ${OBJECTDIR}/_ext/43898991/blinky.o ${OBJECTDIR}/_ext/43898991/main.o ${OBJECTDIR}/_ext/726959463/qstamp.o -POSSIBLE_DEPFILES=${OBJECTDIR}/_ext/820665871/qep_hsm.o.d ${OBJECTDIR}/_ext/820665871/qep_msm.o.d ${OBJECTDIR}/_ext/820665871/qf_act.o.d ${OBJECTDIR}/_ext/820665871/qf_actq.o.d ${OBJECTDIR}/_ext/820665871/qf_defer.o.d ${OBJECTDIR}/_ext/820665871/qf_dyn.o.d ${OBJECTDIR}/_ext/820665871/qf_mem.o.d ${OBJECTDIR}/_ext/820665871/qf_ps.o.d ${OBJECTDIR}/_ext/820665871/qf_qact.o.d ${OBJECTDIR}/_ext/820665871/qf_qeq.o.d ${OBJECTDIR}/_ext/820665871/qf_qmact.o.d ${OBJECTDIR}/_ext/820665871/qf_time.o.d ${OBJECTDIR}/_ext/820665876/qk.o.d ${OBJECTDIR}/_ext/1627782163/qk_port.o.d ${OBJECTDIR}/bsp.o.d ${OBJECTDIR}/_ext/43898991/blinky.o.d ${OBJECTDIR}/_ext/43898991/main.o.d ${OBJECTDIR}/_ext/726959463/qstamp.o.d - -# Object Files -OBJECTFILES=${OBJECTDIR}/_ext/820665871/qep_hsm.o ${OBJECTDIR}/_ext/820665871/qep_msm.o ${OBJECTDIR}/_ext/820665871/qf_act.o ${OBJECTDIR}/_ext/820665871/qf_actq.o ${OBJECTDIR}/_ext/820665871/qf_defer.o ${OBJECTDIR}/_ext/820665871/qf_dyn.o ${OBJECTDIR}/_ext/820665871/qf_mem.o ${OBJECTDIR}/_ext/820665871/qf_ps.o ${OBJECTDIR}/_ext/820665871/qf_qact.o ${OBJECTDIR}/_ext/820665871/qf_qeq.o ${OBJECTDIR}/_ext/820665871/qf_qmact.o ${OBJECTDIR}/_ext/820665871/qf_time.o ${OBJECTDIR}/_ext/820665876/qk.o ${OBJECTDIR}/_ext/1627782163/qk_port.o ${OBJECTDIR}/bsp.o ${OBJECTDIR}/_ext/43898991/blinky.o ${OBJECTDIR}/_ext/43898991/main.o ${OBJECTDIR}/_ext/726959463/qstamp.o - -# Source Files -SOURCEFILES=../../../../../src/qf/qep_hsm.c ../../../../../src/qf/qep_msm.c ../../../../../src/qf/qf_act.c ../../../../../src/qf/qf_actq.c ../../../../../src/qf/qf_defer.c ../../../../../src/qf/qf_dyn.c ../../../../../src/qf/qf_mem.c ../../../../../src/qf/qf_ps.c ../../../../../src/qf/qf_qact.c ../../../../../src/qf/qf_qeq.c ../../../../../src/qf/qf_qmact.c ../../../../../src/qf/qf_time.c ../../../../../src/qk/qk.c ../../../../../ports/pic32/qk/xc32/qk_port.c bsp.c ../../blinky.c ../../main.c ../../../../../include/qstamp.c - - -CFLAGS= -ASFLAGS= -LDLIBSOPTIONS= - -############# Tool locations ########################################## -# If you copy a project from one host to another, the path where the # -# compiler is installed may be different. # -# If you open this project with MPLAB X in the new host, this # -# makefile will be regenerated and the paths will be corrected. # -####################################################################### -# fixDeps replaces a bunch of sed/cat/printf statements that slow down the build -FIXDEPS=fixDeps - -.build-conf: ${BUILD_SUBPROJECTS} -ifneq ($(INFORMATION_MESSAGE), ) - @echo $(INFORMATION_MESSAGE) -endif - ${MAKE} -f nbproject/Makefile-dbg.mk dist/${CND_CONF}/${IMAGE_TYPE}/xc32.${IMAGE_TYPE}.${OUTPUT_SUFFIX} - -MP_PROCESSOR_OPTION=32MX250F128B -MP_LINKER_FILE_OPTION= -# ------------------------------------------------------------------------------------ -# Rules for buildStep: assemble -ifeq ($(TYPE_IMAGE), DEBUG_RUN) -else -endif - -# ------------------------------------------------------------------------------------ -# Rules for buildStep: assembleWithPreprocess -ifeq ($(TYPE_IMAGE), DEBUG_RUN) -else -endif - -# ------------------------------------------------------------------------------------ -# Rules for buildStep: compile -ifeq ($(TYPE_IMAGE), DEBUG_RUN) -${OBJECTDIR}/_ext/820665871/qep_hsm.o: ../../../../../src/qf/qep_hsm.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/820665871" - @${RM} ${OBJECTDIR}/_ext/820665871/qep_hsm.o.d - @${RM} ${OBJECTDIR}/_ext/820665871/qep_hsm.o - @${FIXDEPS} "${OBJECTDIR}/_ext/820665871/qep_hsm.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -D__DEBUG -D__MPLAB_DEBUGGER_PK3=1 -fframe-base-loclist -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -I"../.." -I"../../../../../src" -I"../../../../../include" -I"../../../../../ports/pic32/qk/xc32" -MMD -MF "${OBJECTDIR}/_ext/820665871/qep_hsm.o.d" -o ${OBJECTDIR}/_ext/820665871/qep_hsm.o ../../../../../src/qf/qep_hsm.c -DXPRJ_dbg=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/820665871/qep_msm.o: ../../../../../src/qf/qep_msm.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/820665871" - @${RM} ${OBJECTDIR}/_ext/820665871/qep_msm.o.d - @${RM} ${OBJECTDIR}/_ext/820665871/qep_msm.o - @${FIXDEPS} "${OBJECTDIR}/_ext/820665871/qep_msm.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -D__DEBUG -D__MPLAB_DEBUGGER_PK3=1 -fframe-base-loclist -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -I"../.." -I"../../../../../src" -I"../../../../../include" -I"../../../../../ports/pic32/qk/xc32" -MMD -MF "${OBJECTDIR}/_ext/820665871/qep_msm.o.d" -o ${OBJECTDIR}/_ext/820665871/qep_msm.o ../../../../../src/qf/qep_msm.c -DXPRJ_dbg=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/820665871/qf_act.o: ../../../../../src/qf/qf_act.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/820665871" - @${RM} ${OBJECTDIR}/_ext/820665871/qf_act.o.d - @${RM} ${OBJECTDIR}/_ext/820665871/qf_act.o - @${FIXDEPS} "${OBJECTDIR}/_ext/820665871/qf_act.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -D__DEBUG -D__MPLAB_DEBUGGER_PK3=1 -fframe-base-loclist -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -I"../.." -I"../../../../../src" -I"../../../../../include" -I"../../../../../ports/pic32/qk/xc32" -MMD -MF "${OBJECTDIR}/_ext/820665871/qf_act.o.d" -o ${OBJECTDIR}/_ext/820665871/qf_act.o ../../../../../src/qf/qf_act.c -DXPRJ_dbg=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/820665871/qf_actq.o: ../../../../../src/qf/qf_actq.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/820665871" - @${RM} ${OBJECTDIR}/_ext/820665871/qf_actq.o.d - @${RM} ${OBJECTDIR}/_ext/820665871/qf_actq.o - @${FIXDEPS} "${OBJECTDIR}/_ext/820665871/qf_actq.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -D__DEBUG -D__MPLAB_DEBUGGER_PK3=1 -fframe-base-loclist -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -I"../.." -I"../../../../../src" -I"../../../../../include" -I"../../../../../ports/pic32/qk/xc32" -MMD -MF "${OBJECTDIR}/_ext/820665871/qf_actq.o.d" -o ${OBJECTDIR}/_ext/820665871/qf_actq.o ../../../../../src/qf/qf_actq.c -DXPRJ_dbg=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/820665871/qf_defer.o: ../../../../../src/qf/qf_defer.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/820665871" - @${RM} ${OBJECTDIR}/_ext/820665871/qf_defer.o.d - @${RM} ${OBJECTDIR}/_ext/820665871/qf_defer.o - @${FIXDEPS} "${OBJECTDIR}/_ext/820665871/qf_defer.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -D__DEBUG -D__MPLAB_DEBUGGER_PK3=1 -fframe-base-loclist -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -I"../.." -I"../../../../../src" -I"../../../../../include" -I"../../../../../ports/pic32/qk/xc32" -MMD -MF "${OBJECTDIR}/_ext/820665871/qf_defer.o.d" -o ${OBJECTDIR}/_ext/820665871/qf_defer.o ../../../../../src/qf/qf_defer.c -DXPRJ_dbg=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/820665871/qf_dyn.o: ../../../../../src/qf/qf_dyn.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/820665871" - @${RM} ${OBJECTDIR}/_ext/820665871/qf_dyn.o.d - @${RM} ${OBJECTDIR}/_ext/820665871/qf_dyn.o - @${FIXDEPS} "${OBJECTDIR}/_ext/820665871/qf_dyn.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -D__DEBUG -D__MPLAB_DEBUGGER_PK3=1 -fframe-base-loclist -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -I"../.." -I"../../../../../src" -I"../../../../../include" -I"../../../../../ports/pic32/qk/xc32" -MMD -MF "${OBJECTDIR}/_ext/820665871/qf_dyn.o.d" -o ${OBJECTDIR}/_ext/820665871/qf_dyn.o ../../../../../src/qf/qf_dyn.c -DXPRJ_dbg=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/820665871/qf_mem.o: ../../../../../src/qf/qf_mem.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/820665871" - @${RM} ${OBJECTDIR}/_ext/820665871/qf_mem.o.d - @${RM} ${OBJECTDIR}/_ext/820665871/qf_mem.o - @${FIXDEPS} "${OBJECTDIR}/_ext/820665871/qf_mem.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -D__DEBUG -D__MPLAB_DEBUGGER_PK3=1 -fframe-base-loclist -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -I"../.." -I"../../../../../src" -I"../../../../../include" -I"../../../../../ports/pic32/qk/xc32" -MMD -MF "${OBJECTDIR}/_ext/820665871/qf_mem.o.d" -o ${OBJECTDIR}/_ext/820665871/qf_mem.o ../../../../../src/qf/qf_mem.c -DXPRJ_dbg=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/820665871/qf_ps.o: ../../../../../src/qf/qf_ps.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/820665871" - @${RM} ${OBJECTDIR}/_ext/820665871/qf_ps.o.d - @${RM} ${OBJECTDIR}/_ext/820665871/qf_ps.o - @${FIXDEPS} "${OBJECTDIR}/_ext/820665871/qf_ps.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -D__DEBUG -D__MPLAB_DEBUGGER_PK3=1 -fframe-base-loclist -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -I"../.." -I"../../../../../src" -I"../../../../../include" -I"../../../../../ports/pic32/qk/xc32" -MMD -MF "${OBJECTDIR}/_ext/820665871/qf_ps.o.d" -o ${OBJECTDIR}/_ext/820665871/qf_ps.o ../../../../../src/qf/qf_ps.c -DXPRJ_dbg=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/820665871/qf_qact.o: ../../../../../src/qf/qf_qact.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/820665871" - @${RM} ${OBJECTDIR}/_ext/820665871/qf_qact.o.d - @${RM} ${OBJECTDIR}/_ext/820665871/qf_qact.o - @${FIXDEPS} "${OBJECTDIR}/_ext/820665871/qf_qact.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -D__DEBUG -D__MPLAB_DEBUGGER_PK3=1 -fframe-base-loclist -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -I"../.." -I"../../../../../src" -I"../../../../../include" -I"../../../../../ports/pic32/qk/xc32" -MMD -MF "${OBJECTDIR}/_ext/820665871/qf_qact.o.d" -o ${OBJECTDIR}/_ext/820665871/qf_qact.o ../../../../../src/qf/qf_qact.c -DXPRJ_dbg=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/820665871/qf_qeq.o: ../../../../../src/qf/qf_qeq.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/820665871" - @${RM} ${OBJECTDIR}/_ext/820665871/qf_qeq.o.d - @${RM} ${OBJECTDIR}/_ext/820665871/qf_qeq.o - @${FIXDEPS} "${OBJECTDIR}/_ext/820665871/qf_qeq.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -D__DEBUG -D__MPLAB_DEBUGGER_PK3=1 -fframe-base-loclist -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -I"../.." -I"../../../../../src" -I"../../../../../include" -I"../../../../../ports/pic32/qk/xc32" -MMD -MF "${OBJECTDIR}/_ext/820665871/qf_qeq.o.d" -o ${OBJECTDIR}/_ext/820665871/qf_qeq.o ../../../../../src/qf/qf_qeq.c -DXPRJ_dbg=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/820665871/qf_qmact.o: ../../../../../src/qf/qf_qmact.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/820665871" - @${RM} ${OBJECTDIR}/_ext/820665871/qf_qmact.o.d - @${RM} ${OBJECTDIR}/_ext/820665871/qf_qmact.o - @${FIXDEPS} "${OBJECTDIR}/_ext/820665871/qf_qmact.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -D__DEBUG -D__MPLAB_DEBUGGER_PK3=1 -fframe-base-loclist -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -I"../.." -I"../../../../../src" -I"../../../../../include" -I"../../../../../ports/pic32/qk/xc32" -MMD -MF "${OBJECTDIR}/_ext/820665871/qf_qmact.o.d" -o ${OBJECTDIR}/_ext/820665871/qf_qmact.o ../../../../../src/qf/qf_qmact.c -DXPRJ_dbg=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/820665871/qf_time.o: ../../../../../src/qf/qf_time.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/820665871" - @${RM} ${OBJECTDIR}/_ext/820665871/qf_time.o.d - @${RM} ${OBJECTDIR}/_ext/820665871/qf_time.o - @${FIXDEPS} "${OBJECTDIR}/_ext/820665871/qf_time.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -D__DEBUG -D__MPLAB_DEBUGGER_PK3=1 -fframe-base-loclist -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -I"../.." -I"../../../../../src" -I"../../../../../include" -I"../../../../../ports/pic32/qk/xc32" -MMD -MF "${OBJECTDIR}/_ext/820665871/qf_time.o.d" -o ${OBJECTDIR}/_ext/820665871/qf_time.o ../../../../../src/qf/qf_time.c -DXPRJ_dbg=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/820665876/qk.o: ../../../../../src/qk/qk.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/820665876" - @${RM} ${OBJECTDIR}/_ext/820665876/qk.o.d - @${RM} ${OBJECTDIR}/_ext/820665876/qk.o - @${FIXDEPS} "${OBJECTDIR}/_ext/820665876/qk.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -D__DEBUG -D__MPLAB_DEBUGGER_PK3=1 -fframe-base-loclist -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -I"../.." -I"../../../../../src" -I"../../../../../include" -I"../../../../../ports/pic32/qk/xc32" -MMD -MF "${OBJECTDIR}/_ext/820665876/qk.o.d" -o ${OBJECTDIR}/_ext/820665876/qk.o ../../../../../src/qk/qk.c -DXPRJ_dbg=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/1627782163/qk_port.o: ../../../../../ports/pic32/qk/xc32/qk_port.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/1627782163" - @${RM} ${OBJECTDIR}/_ext/1627782163/qk_port.o.d - @${RM} ${OBJECTDIR}/_ext/1627782163/qk_port.o - @${FIXDEPS} "${OBJECTDIR}/_ext/1627782163/qk_port.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -D__DEBUG -D__MPLAB_DEBUGGER_PK3=1 -fframe-base-loclist -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -I"../.." -I"../../../../../src" -I"../../../../../include" -I"../../../../../ports/pic32/qk/xc32" -MMD -MF "${OBJECTDIR}/_ext/1627782163/qk_port.o.d" -o ${OBJECTDIR}/_ext/1627782163/qk_port.o ../../../../../ports/pic32/qk/xc32/qk_port.c -DXPRJ_dbg=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/bsp.o: bsp.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}" - @${RM} ${OBJECTDIR}/bsp.o.d - @${RM} ${OBJECTDIR}/bsp.o - @${FIXDEPS} "${OBJECTDIR}/bsp.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -D__DEBUG -D__MPLAB_DEBUGGER_PK3=1 -fframe-base-loclist -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -I"../.." -I"../../../../../src" -I"../../../../../include" -I"../../../../../ports/pic32/qk/xc32" -MMD -MF "${OBJECTDIR}/bsp.o.d" -o ${OBJECTDIR}/bsp.o bsp.c -DXPRJ_dbg=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/43898991/blinky.o: ../../blinky.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/43898991" - @${RM} ${OBJECTDIR}/_ext/43898991/blinky.o.d - @${RM} ${OBJECTDIR}/_ext/43898991/blinky.o - @${FIXDEPS} "${OBJECTDIR}/_ext/43898991/blinky.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -D__DEBUG -D__MPLAB_DEBUGGER_PK3=1 -fframe-base-loclist -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -I"../.." -I"../../../../../src" -I"../../../../../include" -I"../../../../../ports/pic32/qk/xc32" -MMD -MF "${OBJECTDIR}/_ext/43898991/blinky.o.d" -o ${OBJECTDIR}/_ext/43898991/blinky.o ../../blinky.c -DXPRJ_dbg=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/43898991/main.o: ../../main.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/43898991" - @${RM} ${OBJECTDIR}/_ext/43898991/main.o.d - @${RM} ${OBJECTDIR}/_ext/43898991/main.o - @${FIXDEPS} "${OBJECTDIR}/_ext/43898991/main.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -D__DEBUG -D__MPLAB_DEBUGGER_PK3=1 -fframe-base-loclist -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -I"../.." -I"../../../../../src" -I"../../../../../include" -I"../../../../../ports/pic32/qk/xc32" -MMD -MF "${OBJECTDIR}/_ext/43898991/main.o.d" -o ${OBJECTDIR}/_ext/43898991/main.o ../../main.c -DXPRJ_dbg=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/726959463/qstamp.o: ../../../../../include/qstamp.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/726959463" - @${RM} ${OBJECTDIR}/_ext/726959463/qstamp.o.d - @${RM} ${OBJECTDIR}/_ext/726959463/qstamp.o - @${FIXDEPS} "${OBJECTDIR}/_ext/726959463/qstamp.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -D__DEBUG -D__MPLAB_DEBUGGER_PK3=1 -fframe-base-loclist -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -I"../.." -I"../../../../../src" -I"../../../../../include" -I"../../../../../ports/pic32/qk/xc32" -MMD -MF "${OBJECTDIR}/_ext/726959463/qstamp.o.d" -o ${OBJECTDIR}/_ext/726959463/qstamp.o ../../../../../include/qstamp.c -DXPRJ_dbg=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -else -${OBJECTDIR}/_ext/820665871/qep_hsm.o: ../../../../../src/qf/qep_hsm.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/820665871" - @${RM} ${OBJECTDIR}/_ext/820665871/qep_hsm.o.d - @${RM} ${OBJECTDIR}/_ext/820665871/qep_hsm.o - @${FIXDEPS} "${OBJECTDIR}/_ext/820665871/qep_hsm.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -I"../.." -I"../../../../../src" -I"../../../../../include" -I"../../../../../ports/pic32/qk/xc32" -MMD -MF "${OBJECTDIR}/_ext/820665871/qep_hsm.o.d" -o ${OBJECTDIR}/_ext/820665871/qep_hsm.o ../../../../../src/qf/qep_hsm.c -DXPRJ_dbg=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/820665871/qep_msm.o: ../../../../../src/qf/qep_msm.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/820665871" - @${RM} ${OBJECTDIR}/_ext/820665871/qep_msm.o.d - @${RM} ${OBJECTDIR}/_ext/820665871/qep_msm.o - @${FIXDEPS} "${OBJECTDIR}/_ext/820665871/qep_msm.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -I"../.." -I"../../../../../src" -I"../../../../../include" -I"../../../../../ports/pic32/qk/xc32" -MMD -MF "${OBJECTDIR}/_ext/820665871/qep_msm.o.d" -o ${OBJECTDIR}/_ext/820665871/qep_msm.o ../../../../../src/qf/qep_msm.c -DXPRJ_dbg=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/820665871/qf_act.o: ../../../../../src/qf/qf_act.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/820665871" - @${RM} ${OBJECTDIR}/_ext/820665871/qf_act.o.d - @${RM} ${OBJECTDIR}/_ext/820665871/qf_act.o - @${FIXDEPS} "${OBJECTDIR}/_ext/820665871/qf_act.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -I"../.." -I"../../../../../src" -I"../../../../../include" -I"../../../../../ports/pic32/qk/xc32" -MMD -MF "${OBJECTDIR}/_ext/820665871/qf_act.o.d" -o ${OBJECTDIR}/_ext/820665871/qf_act.o ../../../../../src/qf/qf_act.c -DXPRJ_dbg=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/820665871/qf_actq.o: ../../../../../src/qf/qf_actq.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/820665871" - @${RM} ${OBJECTDIR}/_ext/820665871/qf_actq.o.d - @${RM} ${OBJECTDIR}/_ext/820665871/qf_actq.o - @${FIXDEPS} "${OBJECTDIR}/_ext/820665871/qf_actq.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -I"../.." -I"../../../../../src" -I"../../../../../include" -I"../../../../../ports/pic32/qk/xc32" -MMD -MF "${OBJECTDIR}/_ext/820665871/qf_actq.o.d" -o ${OBJECTDIR}/_ext/820665871/qf_actq.o ../../../../../src/qf/qf_actq.c -DXPRJ_dbg=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/820665871/qf_defer.o: ../../../../../src/qf/qf_defer.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/820665871" - @${RM} ${OBJECTDIR}/_ext/820665871/qf_defer.o.d - @${RM} ${OBJECTDIR}/_ext/820665871/qf_defer.o - @${FIXDEPS} "${OBJECTDIR}/_ext/820665871/qf_defer.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -I"../.." -I"../../../../../src" -I"../../../../../include" -I"../../../../../ports/pic32/qk/xc32" -MMD -MF "${OBJECTDIR}/_ext/820665871/qf_defer.o.d" -o ${OBJECTDIR}/_ext/820665871/qf_defer.o ../../../../../src/qf/qf_defer.c -DXPRJ_dbg=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/820665871/qf_dyn.o: ../../../../../src/qf/qf_dyn.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/820665871" - @${RM} ${OBJECTDIR}/_ext/820665871/qf_dyn.o.d - @${RM} ${OBJECTDIR}/_ext/820665871/qf_dyn.o - @${FIXDEPS} "${OBJECTDIR}/_ext/820665871/qf_dyn.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -I"../.." -I"../../../../../src" -I"../../../../../include" -I"../../../../../ports/pic32/qk/xc32" -MMD -MF "${OBJECTDIR}/_ext/820665871/qf_dyn.o.d" -o ${OBJECTDIR}/_ext/820665871/qf_dyn.o ../../../../../src/qf/qf_dyn.c -DXPRJ_dbg=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/820665871/qf_mem.o: ../../../../../src/qf/qf_mem.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/820665871" - @${RM} ${OBJECTDIR}/_ext/820665871/qf_mem.o.d - @${RM} ${OBJECTDIR}/_ext/820665871/qf_mem.o - @${FIXDEPS} "${OBJECTDIR}/_ext/820665871/qf_mem.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -I"../.." -I"../../../../../src" -I"../../../../../include" -I"../../../../../ports/pic32/qk/xc32" -MMD -MF "${OBJECTDIR}/_ext/820665871/qf_mem.o.d" -o ${OBJECTDIR}/_ext/820665871/qf_mem.o ../../../../../src/qf/qf_mem.c -DXPRJ_dbg=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/820665871/qf_ps.o: ../../../../../src/qf/qf_ps.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/820665871" - @${RM} ${OBJECTDIR}/_ext/820665871/qf_ps.o.d - @${RM} ${OBJECTDIR}/_ext/820665871/qf_ps.o - @${FIXDEPS} "${OBJECTDIR}/_ext/820665871/qf_ps.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -I"../.." -I"../../../../../src" -I"../../../../../include" -I"../../../../../ports/pic32/qk/xc32" -MMD -MF "${OBJECTDIR}/_ext/820665871/qf_ps.o.d" -o ${OBJECTDIR}/_ext/820665871/qf_ps.o ../../../../../src/qf/qf_ps.c -DXPRJ_dbg=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/820665871/qf_qact.o: ../../../../../src/qf/qf_qact.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/820665871" - @${RM} ${OBJECTDIR}/_ext/820665871/qf_qact.o.d - @${RM} ${OBJECTDIR}/_ext/820665871/qf_qact.o - @${FIXDEPS} "${OBJECTDIR}/_ext/820665871/qf_qact.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -I"../.." -I"../../../../../src" -I"../../../../../include" -I"../../../../../ports/pic32/qk/xc32" -MMD -MF "${OBJECTDIR}/_ext/820665871/qf_qact.o.d" -o ${OBJECTDIR}/_ext/820665871/qf_qact.o ../../../../../src/qf/qf_qact.c -DXPRJ_dbg=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/820665871/qf_qeq.o: ../../../../../src/qf/qf_qeq.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/820665871" - @${RM} ${OBJECTDIR}/_ext/820665871/qf_qeq.o.d - @${RM} ${OBJECTDIR}/_ext/820665871/qf_qeq.o - @${FIXDEPS} "${OBJECTDIR}/_ext/820665871/qf_qeq.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -I"../.." -I"../../../../../src" -I"../../../../../include" -I"../../../../../ports/pic32/qk/xc32" -MMD -MF "${OBJECTDIR}/_ext/820665871/qf_qeq.o.d" -o ${OBJECTDIR}/_ext/820665871/qf_qeq.o ../../../../../src/qf/qf_qeq.c -DXPRJ_dbg=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/820665871/qf_qmact.o: ../../../../../src/qf/qf_qmact.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/820665871" - @${RM} ${OBJECTDIR}/_ext/820665871/qf_qmact.o.d - @${RM} ${OBJECTDIR}/_ext/820665871/qf_qmact.o - @${FIXDEPS} "${OBJECTDIR}/_ext/820665871/qf_qmact.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -I"../.." -I"../../../../../src" -I"../../../../../include" -I"../../../../../ports/pic32/qk/xc32" -MMD -MF "${OBJECTDIR}/_ext/820665871/qf_qmact.o.d" -o ${OBJECTDIR}/_ext/820665871/qf_qmact.o ../../../../../src/qf/qf_qmact.c -DXPRJ_dbg=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/820665871/qf_time.o: ../../../../../src/qf/qf_time.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/820665871" - @${RM} ${OBJECTDIR}/_ext/820665871/qf_time.o.d - @${RM} ${OBJECTDIR}/_ext/820665871/qf_time.o - @${FIXDEPS} "${OBJECTDIR}/_ext/820665871/qf_time.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -I"../.." -I"../../../../../src" -I"../../../../../include" -I"../../../../../ports/pic32/qk/xc32" -MMD -MF "${OBJECTDIR}/_ext/820665871/qf_time.o.d" -o ${OBJECTDIR}/_ext/820665871/qf_time.o ../../../../../src/qf/qf_time.c -DXPRJ_dbg=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/820665876/qk.o: ../../../../../src/qk/qk.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/820665876" - @${RM} ${OBJECTDIR}/_ext/820665876/qk.o.d - @${RM} ${OBJECTDIR}/_ext/820665876/qk.o - @${FIXDEPS} "${OBJECTDIR}/_ext/820665876/qk.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -I"../.." -I"../../../../../src" -I"../../../../../include" -I"../../../../../ports/pic32/qk/xc32" -MMD -MF "${OBJECTDIR}/_ext/820665876/qk.o.d" -o ${OBJECTDIR}/_ext/820665876/qk.o ../../../../../src/qk/qk.c -DXPRJ_dbg=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/1627782163/qk_port.o: ../../../../../ports/pic32/qk/xc32/qk_port.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/1627782163" - @${RM} ${OBJECTDIR}/_ext/1627782163/qk_port.o.d - @${RM} ${OBJECTDIR}/_ext/1627782163/qk_port.o - @${FIXDEPS} "${OBJECTDIR}/_ext/1627782163/qk_port.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -I"../.." -I"../../../../../src" -I"../../../../../include" -I"../../../../../ports/pic32/qk/xc32" -MMD -MF "${OBJECTDIR}/_ext/1627782163/qk_port.o.d" -o ${OBJECTDIR}/_ext/1627782163/qk_port.o ../../../../../ports/pic32/qk/xc32/qk_port.c -DXPRJ_dbg=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/bsp.o: bsp.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}" - @${RM} ${OBJECTDIR}/bsp.o.d - @${RM} ${OBJECTDIR}/bsp.o - @${FIXDEPS} "${OBJECTDIR}/bsp.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -I"../.." -I"../../../../../src" -I"../../../../../include" -I"../../../../../ports/pic32/qk/xc32" -MMD -MF "${OBJECTDIR}/bsp.o.d" -o ${OBJECTDIR}/bsp.o bsp.c -DXPRJ_dbg=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/43898991/blinky.o: ../../blinky.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/43898991" - @${RM} ${OBJECTDIR}/_ext/43898991/blinky.o.d - @${RM} ${OBJECTDIR}/_ext/43898991/blinky.o - @${FIXDEPS} "${OBJECTDIR}/_ext/43898991/blinky.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -I"../.." -I"../../../../../src" -I"../../../../../include" -I"../../../../../ports/pic32/qk/xc32" -MMD -MF "${OBJECTDIR}/_ext/43898991/blinky.o.d" -o ${OBJECTDIR}/_ext/43898991/blinky.o ../../blinky.c -DXPRJ_dbg=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/43898991/main.o: ../../main.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/43898991" - @${RM} ${OBJECTDIR}/_ext/43898991/main.o.d - @${RM} ${OBJECTDIR}/_ext/43898991/main.o - @${FIXDEPS} "${OBJECTDIR}/_ext/43898991/main.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -I"../.." -I"../../../../../src" -I"../../../../../include" -I"../../../../../ports/pic32/qk/xc32" -MMD -MF "${OBJECTDIR}/_ext/43898991/main.o.d" -o ${OBJECTDIR}/_ext/43898991/main.o ../../main.c -DXPRJ_dbg=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/726959463/qstamp.o: ../../../../../include/qstamp.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/726959463" - @${RM} ${OBJECTDIR}/_ext/726959463/qstamp.o.d - @${RM} ${OBJECTDIR}/_ext/726959463/qstamp.o - @${FIXDEPS} "${OBJECTDIR}/_ext/726959463/qstamp.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -I"../.." -I"../../../../../src" -I"../../../../../include" -I"../../../../../ports/pic32/qk/xc32" -MMD -MF "${OBJECTDIR}/_ext/726959463/qstamp.o.d" -o ${OBJECTDIR}/_ext/726959463/qstamp.o ../../../../../include/qstamp.c -DXPRJ_dbg=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -endif - -# ------------------------------------------------------------------------------------ -# Rules for buildStep: compileCPP -ifeq ($(TYPE_IMAGE), DEBUG_RUN) -else -endif - -# ------------------------------------------------------------------------------------ -# Rules for buildStep: link -ifeq ($(TYPE_IMAGE), DEBUG_RUN) -dist/${CND_CONF}/${IMAGE_TYPE}/xc32.${IMAGE_TYPE}.${OUTPUT_SUFFIX}: ${OBJECTFILES} nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} dist/${CND_CONF}/${IMAGE_TYPE} - ${MP_CC} $(MP_EXTRA_LD_PRE) -g -mdebugger -D__MPLAB_DEBUGGER_PK3=1 -mprocessor=$(MP_PROCESSOR_OPTION) -o dist/${CND_CONF}/${IMAGE_TYPE}/xc32.${IMAGE_TYPE}.${OUTPUT_SUFFIX} ${OBJECTFILES_QUOTED_IF_SPACED} -DXPRJ_dbg=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -mreserve=data@0x0:0x1FC -mreserve=boot@0x1FC00490:0x1FC00BEF -Wl,--defsym=__MPLAB_BUILD=1$(MP_EXTRA_LD_POST)$(MP_LINKER_FILE_OPTION),--defsym=__MPLAB_DEBUG=1,--defsym=__DEBUG=1,-D=__DEBUG_D,--defsym=__MPLAB_DEBUGGER_PK3=1,--defsym=_min_heap_size=0,--no-code-in-dinit,--no-dinit-in-serial-mem,--report-mem,--warn-section-align,--memorysummary,dist/${CND_CONF}/${IMAGE_TYPE}/memoryfile.xml - -else -dist/${CND_CONF}/${IMAGE_TYPE}/xc32.${IMAGE_TYPE}.${OUTPUT_SUFFIX}: ${OBJECTFILES} nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} dist/${CND_CONF}/${IMAGE_TYPE} - ${MP_CC} $(MP_EXTRA_LD_PRE) -mprocessor=$(MP_PROCESSOR_OPTION) -o dist/${CND_CONF}/${IMAGE_TYPE}/xc32.${IMAGE_TYPE}.${DEBUGGABLE_SUFFIX} ${OBJECTFILES_QUOTED_IF_SPACED} -DXPRJ_dbg=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -Wl,--defsym=__MPLAB_BUILD=1$(MP_EXTRA_LD_POST)$(MP_LINKER_FILE_OPTION),--defsym=_min_heap_size=0,--no-code-in-dinit,--no-dinit-in-serial-mem,--report-mem,--warn-section-align,--memorysummary,dist/${CND_CONF}/${IMAGE_TYPE}/memoryfile.xml - ${MP_CC_DIR}\\xc32-bin2hex dist/${CND_CONF}/${IMAGE_TYPE}/xc32.${IMAGE_TYPE}.${DEBUGGABLE_SUFFIX} -endif - - -# Subprojects -.build-subprojects: - - -# Subprojects -.clean-subprojects: - -# Clean Targets -.clean-conf: ${CLEAN_SUBPROJECTS} - ${RM} -r build/dbg - ${RM} -r dist/dbg - -# Enable dependency checking -.dep.inc: .depcheck-impl - -DEPFILES=$(shell mplabwildcard ${POSSIBLE_DEPFILES}) -ifneq (${DEPFILES},) -include ${DEPFILES} -endif diff --git a/examples/pic32/blinky_microstick2-pic32/qk/xc32/nbproject/Makefile-genesis.properties b/examples/pic32/blinky_microstick2-pic32/qk/xc32/nbproject/Makefile-genesis.properties deleted file mode 100644 index 78280d04..00000000 --- a/examples/pic32/blinky_microstick2-pic32/qk/xc32/nbproject/Makefile-genesis.properties +++ /dev/null @@ -1,15 +0,0 @@ -# -#Sun Apr 03 16:59:12 EDT 2022 -rel.languagetoolchain.version=2.20 -spy.languagetoolchain.version=2.20 -conf.ids=dbg,rel,spy -spy.languagetoolchain.dir=C\:\\tools\\Microchip\\xc32\\bin -configurations-xml=490c3184559756a964c38ccac5997e93 -dbg.languagetoolchain.version=2.20 -com-microchip-mplab-nbide-embedded-makeproject-MakeProject.md5=37eccb08230908d044ad3fe14e24ea9a -dbg.com-microchip-mplab-nbide-toolchainXC32-XC32LanguageToolchain.md5=af6fe09cc582a0daace7b80bb4f7bbe2 -spy.com-microchip-mplab-nbide-toolchainXC32-XC32LanguageToolchain.md5=af6fe09cc582a0daace7b80bb4f7bbe2 -rel.languagetoolchain.dir=C\:\\tools\\Microchip\\xc32\\bin -dbg.languagetoolchain.dir=C\:\\tools\\Microchip\\xc32\\bin -rel.com-microchip-mplab-nbide-toolchainXC32-XC32LanguageToolchain.md5=af6fe09cc582a0daace7b80bb4f7bbe2 -host.platform=windows diff --git a/examples/pic32/blinky_microstick2-pic32/qk/xc32/nbproject/Makefile-impl.mk b/examples/pic32/blinky_microstick2-pic32/qk/xc32/nbproject/Makefile-impl.mk deleted file mode 100644 index 45560f95..00000000 --- a/examples/pic32/blinky_microstick2-pic32/qk/xc32/nbproject/Makefile-impl.mk +++ /dev/null @@ -1,73 +0,0 @@ -# -# Generated Makefile - do not edit! -# -# Edit the Makefile in the project folder instead (../Makefile). Each target -# has a pre- and a post- target defined where you can add customization code. -# -# This makefile implements macros and targets common to all configurations. -# -# NOCDDL - - -# Building and Cleaning subprojects are done by default, but can be controlled with the SUB -# macro. If SUB=no, subprojects will not be built or cleaned. The following macro -# statements set BUILD_SUB-CONF and CLEAN_SUB-CONF to .build-reqprojects-conf -# and .clean-reqprojects-conf unless SUB has the value 'no' -SUB_no=NO -SUBPROJECTS=${SUB_${SUB}} -BUILD_SUBPROJECTS_=.build-subprojects -BUILD_SUBPROJECTS_NO= -BUILD_SUBPROJECTS=${BUILD_SUBPROJECTS_${SUBPROJECTS}} -CLEAN_SUBPROJECTS_=.clean-subprojects -CLEAN_SUBPROJECTS_NO= -CLEAN_SUBPROJECTS=${CLEAN_SUBPROJECTS_${SUBPROJECTS}} - - -# Project Name -PROJECTNAME=xc32 - -# Active Configuration -DEFAULTCONF=dbg -CONF=${DEFAULTCONF} - -# All Configurations -ALLCONFS=dbg rel spy - - -# build -.build-impl: .build-pre - ${MAKE} -f nbproject/Makefile-${CONF}.mk SUBPROJECTS=${SUBPROJECTS} .build-conf - - -# clean -.clean-impl: .clean-pre - ${MAKE} -f nbproject/Makefile-${CONF}.mk SUBPROJECTS=${SUBPROJECTS} .clean-conf - -# clobber -.clobber-impl: .clobber-pre .depcheck-impl - ${MAKE} SUBPROJECTS=${SUBPROJECTS} CONF=dbg clean - ${MAKE} SUBPROJECTS=${SUBPROJECTS} CONF=rel clean - ${MAKE} SUBPROJECTS=${SUBPROJECTS} CONF=spy clean - - - -# all -.all-impl: .all-pre .depcheck-impl - ${MAKE} SUBPROJECTS=${SUBPROJECTS} CONF=dbg build - ${MAKE} SUBPROJECTS=${SUBPROJECTS} CONF=rel build - ${MAKE} SUBPROJECTS=${SUBPROJECTS} CONF=spy build - - - -# dependency checking support -.depcheck-impl: -# @echo "# This code depends on make tool being used" >.dep.inc -# @if [ -n "${MAKE_VERSION}" ]; then \ -# echo "DEPFILES=\$$(wildcard \$$(addsuffix .d, \$${OBJECTFILES}))" >>.dep.inc; \ -# echo "ifneq (\$${DEPFILES},)" >>.dep.inc; \ -# echo "include \$${DEPFILES}" >>.dep.inc; \ -# echo "endif" >>.dep.inc; \ -# else \ -# echo ".KEEP_STATE:" >>.dep.inc; \ -# echo ".KEEP_STATE_FILE:.make.state.\$${CONF}" >>.dep.inc; \ -# fi diff --git a/examples/pic32/blinky_microstick2-pic32/qk/xc32/nbproject/Makefile-local-dbg.mk b/examples/pic32/blinky_microstick2-pic32/qk/xc32/nbproject/Makefile-local-dbg.mk deleted file mode 100644 index 24cf88be..00000000 --- a/examples/pic32/blinky_microstick2-pic32/qk/xc32/nbproject/Makefile-local-dbg.mk +++ /dev/null @@ -1,37 +0,0 @@ -# -# Generated Makefile - do not edit! -# -# -# This file contains information about the location of compilers and other tools. -# If you commmit this file into your revision control server, you will be able to -# to checkout the project and build it from the command line with make. However, -# if more than one person works on the same project, then this file might show -# conflicts since different users are bound to have compilers in different places. -# In that case you might choose to not commit this file and let MPLAB X recreate this file -# for each user. The disadvantage of not commiting this file is that you must run MPLAB X at -# least once so the file gets created and the project can be built. Finally, you can also -# avoid using this file at all if you are only building from the command line with make. -# You can invoke make with the values of the macros: -# $ makeMP_CC="/opt/microchip/mplabc30/v3.30c/bin/pic30-gcc" ... -# -SHELL=cmd.exe -PATH_TO_IDE_BIN=C:/tools/Microchip/MPLABX/mplab_platform/platform/../mplab_ide/modules/../../bin/ -# Adding MPLAB X bin directory to path. -PATH:=C:/tools/Microchip/MPLABX/mplab_platform/platform/../mplab_ide/modules/../../bin/:$(PATH) -# Path to java used to run MPLAB X when this makefile was created -MP_JAVA_PATH="C:\tools\Microchip\MPLABX\sys\java\jre1.8.0_181/bin/" -OS_CURRENT="$(shell uname -s)" -MP_CC="C:\tools\Microchip\xc32\bin\xc32-gcc.exe" -MP_CPPC="C:\tools\Microchip\xc32\bin\xc32-g++.exe" -# MP_BC is not defined -MP_AS="C:\tools\Microchip\xc32\bin\xc32-as.exe" -MP_LD="C:\tools\Microchip\xc32\bin\xc32-ld.exe" -MP_AR="C:\tools\Microchip\xc32\bin\xc32-ar.exe" -DEP_GEN=${MP_JAVA_PATH}java -jar "C:/tools/Microchip/MPLABX/mplab_platform/platform/../mplab_ide/modules/../../bin/extractobjectdependencies.jar" -MP_CC_DIR="C:\tools\Microchip\xc32\bin" -MP_CPPC_DIR="C:\tools\Microchip\xc32\bin" -# MP_BC_DIR is not defined -MP_AS_DIR="C:\tools\Microchip\xc32\bin" -MP_LD_DIR="C:\tools\Microchip\xc32\bin" -MP_AR_DIR="C:\tools\Microchip\xc32\bin" -# MP_BC_DIR is not defined diff --git a/examples/pic32/blinky_microstick2-pic32/qk/xc32/nbproject/Makefile-local-rel.mk b/examples/pic32/blinky_microstick2-pic32/qk/xc32/nbproject/Makefile-local-rel.mk deleted file mode 100644 index 24cf88be..00000000 --- a/examples/pic32/blinky_microstick2-pic32/qk/xc32/nbproject/Makefile-local-rel.mk +++ /dev/null @@ -1,37 +0,0 @@ -# -# Generated Makefile - do not edit! -# -# -# This file contains information about the location of compilers and other tools. -# If you commmit this file into your revision control server, you will be able to -# to checkout the project and build it from the command line with make. However, -# if more than one person works on the same project, then this file might show -# conflicts since different users are bound to have compilers in different places. -# In that case you might choose to not commit this file and let MPLAB X recreate this file -# for each user. The disadvantage of not commiting this file is that you must run MPLAB X at -# least once so the file gets created and the project can be built. Finally, you can also -# avoid using this file at all if you are only building from the command line with make. -# You can invoke make with the values of the macros: -# $ makeMP_CC="/opt/microchip/mplabc30/v3.30c/bin/pic30-gcc" ... -# -SHELL=cmd.exe -PATH_TO_IDE_BIN=C:/tools/Microchip/MPLABX/mplab_platform/platform/../mplab_ide/modules/../../bin/ -# Adding MPLAB X bin directory to path. -PATH:=C:/tools/Microchip/MPLABX/mplab_platform/platform/../mplab_ide/modules/../../bin/:$(PATH) -# Path to java used to run MPLAB X when this makefile was created -MP_JAVA_PATH="C:\tools\Microchip\MPLABX\sys\java\jre1.8.0_181/bin/" -OS_CURRENT="$(shell uname -s)" -MP_CC="C:\tools\Microchip\xc32\bin\xc32-gcc.exe" -MP_CPPC="C:\tools\Microchip\xc32\bin\xc32-g++.exe" -# MP_BC is not defined -MP_AS="C:\tools\Microchip\xc32\bin\xc32-as.exe" -MP_LD="C:\tools\Microchip\xc32\bin\xc32-ld.exe" -MP_AR="C:\tools\Microchip\xc32\bin\xc32-ar.exe" -DEP_GEN=${MP_JAVA_PATH}java -jar "C:/tools/Microchip/MPLABX/mplab_platform/platform/../mplab_ide/modules/../../bin/extractobjectdependencies.jar" -MP_CC_DIR="C:\tools\Microchip\xc32\bin" -MP_CPPC_DIR="C:\tools\Microchip\xc32\bin" -# MP_BC_DIR is not defined -MP_AS_DIR="C:\tools\Microchip\xc32\bin" -MP_LD_DIR="C:\tools\Microchip\xc32\bin" -MP_AR_DIR="C:\tools\Microchip\xc32\bin" -# MP_BC_DIR is not defined diff --git a/examples/pic32/blinky_microstick2-pic32/qk/xc32/nbproject/Makefile-local-spy.mk b/examples/pic32/blinky_microstick2-pic32/qk/xc32/nbproject/Makefile-local-spy.mk deleted file mode 100644 index 24cf88be..00000000 --- a/examples/pic32/blinky_microstick2-pic32/qk/xc32/nbproject/Makefile-local-spy.mk +++ /dev/null @@ -1,37 +0,0 @@ -# -# Generated Makefile - do not edit! -# -# -# This file contains information about the location of compilers and other tools. -# If you commmit this file into your revision control server, you will be able to -# to checkout the project and build it from the command line with make. However, -# if more than one person works on the same project, then this file might show -# conflicts since different users are bound to have compilers in different places. -# In that case you might choose to not commit this file and let MPLAB X recreate this file -# for each user. The disadvantage of not commiting this file is that you must run MPLAB X at -# least once so the file gets created and the project can be built. Finally, you can also -# avoid using this file at all if you are only building from the command line with make. -# You can invoke make with the values of the macros: -# $ makeMP_CC="/opt/microchip/mplabc30/v3.30c/bin/pic30-gcc" ... -# -SHELL=cmd.exe -PATH_TO_IDE_BIN=C:/tools/Microchip/MPLABX/mplab_platform/platform/../mplab_ide/modules/../../bin/ -# Adding MPLAB X bin directory to path. -PATH:=C:/tools/Microchip/MPLABX/mplab_platform/platform/../mplab_ide/modules/../../bin/:$(PATH) -# Path to java used to run MPLAB X when this makefile was created -MP_JAVA_PATH="C:\tools\Microchip\MPLABX\sys\java\jre1.8.0_181/bin/" -OS_CURRENT="$(shell uname -s)" -MP_CC="C:\tools\Microchip\xc32\bin\xc32-gcc.exe" -MP_CPPC="C:\tools\Microchip\xc32\bin\xc32-g++.exe" -# MP_BC is not defined -MP_AS="C:\tools\Microchip\xc32\bin\xc32-as.exe" -MP_LD="C:\tools\Microchip\xc32\bin\xc32-ld.exe" -MP_AR="C:\tools\Microchip\xc32\bin\xc32-ar.exe" -DEP_GEN=${MP_JAVA_PATH}java -jar "C:/tools/Microchip/MPLABX/mplab_platform/platform/../mplab_ide/modules/../../bin/extractobjectdependencies.jar" -MP_CC_DIR="C:\tools\Microchip\xc32\bin" -MP_CPPC_DIR="C:\tools\Microchip\xc32\bin" -# MP_BC_DIR is not defined -MP_AS_DIR="C:\tools\Microchip\xc32\bin" -MP_LD_DIR="C:\tools\Microchip\xc32\bin" -MP_AR_DIR="C:\tools\Microchip\xc32\bin" -# MP_BC_DIR is not defined diff --git a/examples/pic32/blinky_microstick2-pic32/qk/xc32/nbproject/Makefile-rel.mk b/examples/pic32/blinky_microstick2-pic32/qk/xc32/nbproject/Makefile-rel.mk deleted file mode 100644 index 07acc776..00000000 --- a/examples/pic32/blinky_microstick2-pic32/qk/xc32/nbproject/Makefile-rel.mk +++ /dev/null @@ -1,367 +0,0 @@ -# -# Generated Makefile - do not edit! -# -# Edit the Makefile in the project folder instead (../Makefile). Each target -# has a -pre and a -post target defined where you can add customized code. -# -# This makefile implements configuration specific macros and targets. - - -# Include project Makefile -ifeq "${IGNORE_LOCAL}" "TRUE" -# do not include local makefile. User is passing all local related variables already -else -include Makefile -# Include makefile containing local settings -ifeq "$(wildcard nbproject/Makefile-local-rel.mk)" "nbproject/Makefile-local-rel.mk" -include nbproject/Makefile-local-rel.mk -endif -endif - -# Environment -MKDIR=gnumkdir -p -RM=rm -f -MV=mv -CP=cp - -# Macros -CND_CONF=rel -ifeq ($(TYPE_IMAGE), DEBUG_RUN) -IMAGE_TYPE=debug -OUTPUT_SUFFIX=elf -DEBUGGABLE_SUFFIX=elf -FINAL_IMAGE=dist/${CND_CONF}/${IMAGE_TYPE}/xc32.${IMAGE_TYPE}.${OUTPUT_SUFFIX} -else -IMAGE_TYPE=production -OUTPUT_SUFFIX=hex -DEBUGGABLE_SUFFIX=elf -FINAL_IMAGE=dist/${CND_CONF}/${IMAGE_TYPE}/xc32.${IMAGE_TYPE}.${OUTPUT_SUFFIX} -endif - -ifeq ($(COMPARE_BUILD), true) -COMPARISON_BUILD=-mafrlcsj -else -COMPARISON_BUILD= -endif - -ifdef SUB_IMAGE_ADDRESS - -else -SUB_IMAGE_ADDRESS_COMMAND= -endif - -# Object Directory -OBJECTDIR=build/${CND_CONF}/${IMAGE_TYPE} - -# Distribution Directory -DISTDIR=dist/${CND_CONF}/${IMAGE_TYPE} - -# Source Files Quoted if spaced -SOURCEFILES_QUOTED_IF_SPACED=../../../../../src/qf/qep_hsm.c ../../../../../src/qf/qep_msm.c ../../../../../src/qf/qf_act.c ../../../../../src/qf/qf_actq.c ../../../../../src/qf/qf_defer.c ../../../../../src/qf/qf_dyn.c ../../../../../src/qf/qf_mem.c ../../../../../src/qf/qf_ps.c ../../../../../src/qf/qf_qact.c ../../../../../src/qf/qf_qeq.c ../../../../../src/qf/qf_qmact.c ../../../../../src/qf/qf_time.c ../../../../../src/qk/qk.c ../../../../../ports/pic32/qk/xc32/qk_port.c bsp.c ../../blinky.c ../../main.c ../../../../../include/qstamp.c - -# Object Files Quoted if spaced -OBJECTFILES_QUOTED_IF_SPACED=${OBJECTDIR}/_ext/820665871/qep_hsm.o ${OBJECTDIR}/_ext/820665871/qep_msm.o ${OBJECTDIR}/_ext/820665871/qf_act.o ${OBJECTDIR}/_ext/820665871/qf_actq.o ${OBJECTDIR}/_ext/820665871/qf_defer.o ${OBJECTDIR}/_ext/820665871/qf_dyn.o ${OBJECTDIR}/_ext/820665871/qf_mem.o ${OBJECTDIR}/_ext/820665871/qf_ps.o ${OBJECTDIR}/_ext/820665871/qf_qact.o ${OBJECTDIR}/_ext/820665871/qf_qeq.o ${OBJECTDIR}/_ext/820665871/qf_qmact.o ${OBJECTDIR}/_ext/820665871/qf_time.o ${OBJECTDIR}/_ext/820665876/qk.o ${OBJECTDIR}/_ext/1627782163/qk_port.o ${OBJECTDIR}/bsp.o ${OBJECTDIR}/_ext/43898991/blinky.o ${OBJECTDIR}/_ext/43898991/main.o ${OBJECTDIR}/_ext/726959463/qstamp.o -POSSIBLE_DEPFILES=${OBJECTDIR}/_ext/820665871/qep_hsm.o.d ${OBJECTDIR}/_ext/820665871/qep_msm.o.d ${OBJECTDIR}/_ext/820665871/qf_act.o.d ${OBJECTDIR}/_ext/820665871/qf_actq.o.d ${OBJECTDIR}/_ext/820665871/qf_defer.o.d ${OBJECTDIR}/_ext/820665871/qf_dyn.o.d ${OBJECTDIR}/_ext/820665871/qf_mem.o.d ${OBJECTDIR}/_ext/820665871/qf_ps.o.d ${OBJECTDIR}/_ext/820665871/qf_qact.o.d ${OBJECTDIR}/_ext/820665871/qf_qeq.o.d ${OBJECTDIR}/_ext/820665871/qf_qmact.o.d ${OBJECTDIR}/_ext/820665871/qf_time.o.d ${OBJECTDIR}/_ext/820665876/qk.o.d ${OBJECTDIR}/_ext/1627782163/qk_port.o.d ${OBJECTDIR}/bsp.o.d ${OBJECTDIR}/_ext/43898991/blinky.o.d ${OBJECTDIR}/_ext/43898991/main.o.d ${OBJECTDIR}/_ext/726959463/qstamp.o.d - -# Object Files -OBJECTFILES=${OBJECTDIR}/_ext/820665871/qep_hsm.o ${OBJECTDIR}/_ext/820665871/qep_msm.o ${OBJECTDIR}/_ext/820665871/qf_act.o ${OBJECTDIR}/_ext/820665871/qf_actq.o ${OBJECTDIR}/_ext/820665871/qf_defer.o ${OBJECTDIR}/_ext/820665871/qf_dyn.o ${OBJECTDIR}/_ext/820665871/qf_mem.o ${OBJECTDIR}/_ext/820665871/qf_ps.o ${OBJECTDIR}/_ext/820665871/qf_qact.o ${OBJECTDIR}/_ext/820665871/qf_qeq.o ${OBJECTDIR}/_ext/820665871/qf_qmact.o ${OBJECTDIR}/_ext/820665871/qf_time.o ${OBJECTDIR}/_ext/820665876/qk.o ${OBJECTDIR}/_ext/1627782163/qk_port.o ${OBJECTDIR}/bsp.o ${OBJECTDIR}/_ext/43898991/blinky.o ${OBJECTDIR}/_ext/43898991/main.o ${OBJECTDIR}/_ext/726959463/qstamp.o - -# Source Files -SOURCEFILES=../../../../../src/qf/qep_hsm.c ../../../../../src/qf/qep_msm.c ../../../../../src/qf/qf_act.c ../../../../../src/qf/qf_actq.c ../../../../../src/qf/qf_defer.c ../../../../../src/qf/qf_dyn.c ../../../../../src/qf/qf_mem.c ../../../../../src/qf/qf_ps.c ../../../../../src/qf/qf_qact.c ../../../../../src/qf/qf_qeq.c ../../../../../src/qf/qf_qmact.c ../../../../../src/qf/qf_time.c ../../../../../src/qk/qk.c ../../../../../ports/pic32/qk/xc32/qk_port.c bsp.c ../../blinky.c ../../main.c ../../../../../include/qstamp.c - - -CFLAGS= -ASFLAGS= -LDLIBSOPTIONS= - -############# Tool locations ########################################## -# If you copy a project from one host to another, the path where the # -# compiler is installed may be different. # -# If you open this project with MPLAB X in the new host, this # -# makefile will be regenerated and the paths will be corrected. # -####################################################################### -# fixDeps replaces a bunch of sed/cat/printf statements that slow down the build -FIXDEPS=fixDeps - -.build-conf: ${BUILD_SUBPROJECTS} -ifneq ($(INFORMATION_MESSAGE), ) - @echo $(INFORMATION_MESSAGE) -endif - ${MAKE} -f nbproject/Makefile-rel.mk dist/${CND_CONF}/${IMAGE_TYPE}/xc32.${IMAGE_TYPE}.${OUTPUT_SUFFIX} - -MP_PROCESSOR_OPTION=32MX250F128B -MP_LINKER_FILE_OPTION= -# ------------------------------------------------------------------------------------ -# Rules for buildStep: assemble -ifeq ($(TYPE_IMAGE), DEBUG_RUN) -else -endif - -# ------------------------------------------------------------------------------------ -# Rules for buildStep: assembleWithPreprocess -ifeq ($(TYPE_IMAGE), DEBUG_RUN) -else -endif - -# ------------------------------------------------------------------------------------ -# Rules for buildStep: compile -ifeq ($(TYPE_IMAGE), DEBUG_RUN) -${OBJECTDIR}/_ext/820665871/qep_hsm.o: ../../../../../src/qf/qep_hsm.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/820665871" - @${RM} ${OBJECTDIR}/_ext/820665871/qep_hsm.o.d - @${RM} ${OBJECTDIR}/_ext/820665871/qep_hsm.o - @${FIXDEPS} "${OBJECTDIR}/_ext/820665871/qep_hsm.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -D__DEBUG -D__MPLAB_DEBUGGER_PK3=1 -fframe-base-loclist -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -O3 -DNDEBUG -I"../.." -I"../../../../../include" -I"../../../../../src" -I"../../../../../ports/pic32/qk/xc32" -MMD -MF "${OBJECTDIR}/_ext/820665871/qep_hsm.o.d" -o ${OBJECTDIR}/_ext/820665871/qep_hsm.o ../../../../../src/qf/qep_hsm.c -DXPRJ_rel=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/820665871/qep_msm.o: ../../../../../src/qf/qep_msm.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/820665871" - @${RM} ${OBJECTDIR}/_ext/820665871/qep_msm.o.d - @${RM} ${OBJECTDIR}/_ext/820665871/qep_msm.o - @${FIXDEPS} "${OBJECTDIR}/_ext/820665871/qep_msm.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -D__DEBUG -D__MPLAB_DEBUGGER_PK3=1 -fframe-base-loclist -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -O3 -DNDEBUG -I"../.." -I"../../../../../include" -I"../../../../../src" -I"../../../../../ports/pic32/qk/xc32" -MMD -MF "${OBJECTDIR}/_ext/820665871/qep_msm.o.d" -o ${OBJECTDIR}/_ext/820665871/qep_msm.o ../../../../../src/qf/qep_msm.c -DXPRJ_rel=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/820665871/qf_act.o: ../../../../../src/qf/qf_act.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/820665871" - @${RM} ${OBJECTDIR}/_ext/820665871/qf_act.o.d - @${RM} ${OBJECTDIR}/_ext/820665871/qf_act.o - @${FIXDEPS} "${OBJECTDIR}/_ext/820665871/qf_act.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -D__DEBUG -D__MPLAB_DEBUGGER_PK3=1 -fframe-base-loclist -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -O3 -DNDEBUG -I"../.." -I"../../../../../include" -I"../../../../../src" -I"../../../../../ports/pic32/qk/xc32" -MMD -MF "${OBJECTDIR}/_ext/820665871/qf_act.o.d" -o ${OBJECTDIR}/_ext/820665871/qf_act.o ../../../../../src/qf/qf_act.c -DXPRJ_rel=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/820665871/qf_actq.o: ../../../../../src/qf/qf_actq.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/820665871" - @${RM} ${OBJECTDIR}/_ext/820665871/qf_actq.o.d - @${RM} ${OBJECTDIR}/_ext/820665871/qf_actq.o - @${FIXDEPS} "${OBJECTDIR}/_ext/820665871/qf_actq.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -D__DEBUG -D__MPLAB_DEBUGGER_PK3=1 -fframe-base-loclist -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -O3 -DNDEBUG -I"../.." -I"../../../../../include" -I"../../../../../src" -I"../../../../../ports/pic32/qk/xc32" -MMD -MF "${OBJECTDIR}/_ext/820665871/qf_actq.o.d" -o ${OBJECTDIR}/_ext/820665871/qf_actq.o ../../../../../src/qf/qf_actq.c -DXPRJ_rel=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/820665871/qf_defer.o: ../../../../../src/qf/qf_defer.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/820665871" - @${RM} ${OBJECTDIR}/_ext/820665871/qf_defer.o.d - @${RM} ${OBJECTDIR}/_ext/820665871/qf_defer.o - @${FIXDEPS} "${OBJECTDIR}/_ext/820665871/qf_defer.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -D__DEBUG -D__MPLAB_DEBUGGER_PK3=1 -fframe-base-loclist -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -O3 -DNDEBUG -I"../.." -I"../../../../../include" -I"../../../../../src" -I"../../../../../ports/pic32/qk/xc32" -MMD -MF "${OBJECTDIR}/_ext/820665871/qf_defer.o.d" -o ${OBJECTDIR}/_ext/820665871/qf_defer.o ../../../../../src/qf/qf_defer.c -DXPRJ_rel=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/820665871/qf_dyn.o: ../../../../../src/qf/qf_dyn.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/820665871" - @${RM} ${OBJECTDIR}/_ext/820665871/qf_dyn.o.d - @${RM} ${OBJECTDIR}/_ext/820665871/qf_dyn.o - @${FIXDEPS} "${OBJECTDIR}/_ext/820665871/qf_dyn.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -D__DEBUG -D__MPLAB_DEBUGGER_PK3=1 -fframe-base-loclist -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -O3 -DNDEBUG -I"../.." -I"../../../../../include" -I"../../../../../src" -I"../../../../../ports/pic32/qk/xc32" -MMD -MF "${OBJECTDIR}/_ext/820665871/qf_dyn.o.d" -o ${OBJECTDIR}/_ext/820665871/qf_dyn.o ../../../../../src/qf/qf_dyn.c -DXPRJ_rel=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/820665871/qf_mem.o: ../../../../../src/qf/qf_mem.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/820665871" - @${RM} ${OBJECTDIR}/_ext/820665871/qf_mem.o.d - @${RM} ${OBJECTDIR}/_ext/820665871/qf_mem.o - @${FIXDEPS} "${OBJECTDIR}/_ext/820665871/qf_mem.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -D__DEBUG -D__MPLAB_DEBUGGER_PK3=1 -fframe-base-loclist -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -O3 -DNDEBUG -I"../.." -I"../../../../../include" -I"../../../../../src" -I"../../../../../ports/pic32/qk/xc32" -MMD -MF "${OBJECTDIR}/_ext/820665871/qf_mem.o.d" -o ${OBJECTDIR}/_ext/820665871/qf_mem.o ../../../../../src/qf/qf_mem.c -DXPRJ_rel=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/820665871/qf_ps.o: ../../../../../src/qf/qf_ps.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/820665871" - @${RM} ${OBJECTDIR}/_ext/820665871/qf_ps.o.d - @${RM} ${OBJECTDIR}/_ext/820665871/qf_ps.o - @${FIXDEPS} "${OBJECTDIR}/_ext/820665871/qf_ps.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -D__DEBUG -D__MPLAB_DEBUGGER_PK3=1 -fframe-base-loclist -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -O3 -DNDEBUG -I"../.." -I"../../../../../include" -I"../../../../../src" -I"../../../../../ports/pic32/qk/xc32" -MMD -MF "${OBJECTDIR}/_ext/820665871/qf_ps.o.d" -o ${OBJECTDIR}/_ext/820665871/qf_ps.o ../../../../../src/qf/qf_ps.c -DXPRJ_rel=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/820665871/qf_qact.o: ../../../../../src/qf/qf_qact.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/820665871" - @${RM} ${OBJECTDIR}/_ext/820665871/qf_qact.o.d - @${RM} ${OBJECTDIR}/_ext/820665871/qf_qact.o - @${FIXDEPS} "${OBJECTDIR}/_ext/820665871/qf_qact.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -D__DEBUG -D__MPLAB_DEBUGGER_PK3=1 -fframe-base-loclist -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -O3 -DNDEBUG -I"../.." -I"../../../../../include" -I"../../../../../src" -I"../../../../../ports/pic32/qk/xc32" -MMD -MF "${OBJECTDIR}/_ext/820665871/qf_qact.o.d" -o ${OBJECTDIR}/_ext/820665871/qf_qact.o ../../../../../src/qf/qf_qact.c -DXPRJ_rel=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/820665871/qf_qeq.o: ../../../../../src/qf/qf_qeq.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/820665871" - @${RM} ${OBJECTDIR}/_ext/820665871/qf_qeq.o.d - @${RM} ${OBJECTDIR}/_ext/820665871/qf_qeq.o - @${FIXDEPS} "${OBJECTDIR}/_ext/820665871/qf_qeq.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -D__DEBUG -D__MPLAB_DEBUGGER_PK3=1 -fframe-base-loclist -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -O3 -DNDEBUG -I"../.." -I"../../../../../include" -I"../../../../../src" -I"../../../../../ports/pic32/qk/xc32" -MMD -MF "${OBJECTDIR}/_ext/820665871/qf_qeq.o.d" -o ${OBJECTDIR}/_ext/820665871/qf_qeq.o ../../../../../src/qf/qf_qeq.c -DXPRJ_rel=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/820665871/qf_qmact.o: ../../../../../src/qf/qf_qmact.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/820665871" - @${RM} ${OBJECTDIR}/_ext/820665871/qf_qmact.o.d - @${RM} ${OBJECTDIR}/_ext/820665871/qf_qmact.o - @${FIXDEPS} "${OBJECTDIR}/_ext/820665871/qf_qmact.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -D__DEBUG -D__MPLAB_DEBUGGER_PK3=1 -fframe-base-loclist -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -O3 -DNDEBUG -I"../.." -I"../../../../../include" -I"../../../../../src" -I"../../../../../ports/pic32/qk/xc32" -MMD -MF "${OBJECTDIR}/_ext/820665871/qf_qmact.o.d" -o ${OBJECTDIR}/_ext/820665871/qf_qmact.o ../../../../../src/qf/qf_qmact.c -DXPRJ_rel=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/820665871/qf_time.o: ../../../../../src/qf/qf_time.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/820665871" - @${RM} ${OBJECTDIR}/_ext/820665871/qf_time.o.d - @${RM} ${OBJECTDIR}/_ext/820665871/qf_time.o - @${FIXDEPS} "${OBJECTDIR}/_ext/820665871/qf_time.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -D__DEBUG -D__MPLAB_DEBUGGER_PK3=1 -fframe-base-loclist -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -O3 -DNDEBUG -I"../.." -I"../../../../../include" -I"../../../../../src" -I"../../../../../ports/pic32/qk/xc32" -MMD -MF "${OBJECTDIR}/_ext/820665871/qf_time.o.d" -o ${OBJECTDIR}/_ext/820665871/qf_time.o ../../../../../src/qf/qf_time.c -DXPRJ_rel=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/820665876/qk.o: ../../../../../src/qk/qk.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/820665876" - @${RM} ${OBJECTDIR}/_ext/820665876/qk.o.d - @${RM} ${OBJECTDIR}/_ext/820665876/qk.o - @${FIXDEPS} "${OBJECTDIR}/_ext/820665876/qk.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -D__DEBUG -D__MPLAB_DEBUGGER_PK3=1 -fframe-base-loclist -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -O3 -DNDEBUG -I"../.." -I"../../../../../include" -I"../../../../../src" -I"../../../../../ports/pic32/qk/xc32" -MMD -MF "${OBJECTDIR}/_ext/820665876/qk.o.d" -o ${OBJECTDIR}/_ext/820665876/qk.o ../../../../../src/qk/qk.c -DXPRJ_rel=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/1627782163/qk_port.o: ../../../../../ports/pic32/qk/xc32/qk_port.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/1627782163" - @${RM} ${OBJECTDIR}/_ext/1627782163/qk_port.o.d - @${RM} ${OBJECTDIR}/_ext/1627782163/qk_port.o - @${FIXDEPS} "${OBJECTDIR}/_ext/1627782163/qk_port.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -D__DEBUG -D__MPLAB_DEBUGGER_PK3=1 -fframe-base-loclist -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -O3 -DNDEBUG -I"../.." -I"../../../../../include" -I"../../../../../src" -I"../../../../../ports/pic32/qk/xc32" -MMD -MF "${OBJECTDIR}/_ext/1627782163/qk_port.o.d" -o ${OBJECTDIR}/_ext/1627782163/qk_port.o ../../../../../ports/pic32/qk/xc32/qk_port.c -DXPRJ_rel=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/bsp.o: bsp.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}" - @${RM} ${OBJECTDIR}/bsp.o.d - @${RM} ${OBJECTDIR}/bsp.o - @${FIXDEPS} "${OBJECTDIR}/bsp.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -D__DEBUG -D__MPLAB_DEBUGGER_PK3=1 -fframe-base-loclist -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -O3 -DNDEBUG -I"../.." -I"../../../../../include" -I"../../../../../src" -I"../../../../../ports/pic32/qk/xc32" -MMD -MF "${OBJECTDIR}/bsp.o.d" -o ${OBJECTDIR}/bsp.o bsp.c -DXPRJ_rel=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/43898991/blinky.o: ../../blinky.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/43898991" - @${RM} ${OBJECTDIR}/_ext/43898991/blinky.o.d - @${RM} ${OBJECTDIR}/_ext/43898991/blinky.o - @${FIXDEPS} "${OBJECTDIR}/_ext/43898991/blinky.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -D__DEBUG -D__MPLAB_DEBUGGER_PK3=1 -fframe-base-loclist -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -O3 -DNDEBUG -I"../.." -I"../../../../../include" -I"../../../../../src" -I"../../../../../ports/pic32/qk/xc32" -MMD -MF "${OBJECTDIR}/_ext/43898991/blinky.o.d" -o ${OBJECTDIR}/_ext/43898991/blinky.o ../../blinky.c -DXPRJ_rel=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/43898991/main.o: ../../main.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/43898991" - @${RM} ${OBJECTDIR}/_ext/43898991/main.o.d - @${RM} ${OBJECTDIR}/_ext/43898991/main.o - @${FIXDEPS} "${OBJECTDIR}/_ext/43898991/main.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -D__DEBUG -D__MPLAB_DEBUGGER_PK3=1 -fframe-base-loclist -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -O3 -DNDEBUG -I"../.." -I"../../../../../include" -I"../../../../../src" -I"../../../../../ports/pic32/qk/xc32" -MMD -MF "${OBJECTDIR}/_ext/43898991/main.o.d" -o ${OBJECTDIR}/_ext/43898991/main.o ../../main.c -DXPRJ_rel=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/726959463/qstamp.o: ../../../../../include/qstamp.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/726959463" - @${RM} ${OBJECTDIR}/_ext/726959463/qstamp.o.d - @${RM} ${OBJECTDIR}/_ext/726959463/qstamp.o - @${FIXDEPS} "${OBJECTDIR}/_ext/726959463/qstamp.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -D__DEBUG -D__MPLAB_DEBUGGER_PK3=1 -fframe-base-loclist -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -O3 -DNDEBUG -I"../.." -I"../../../../../include" -I"../../../../../src" -I"../../../../../ports/pic32/qk/xc32" -MMD -MF "${OBJECTDIR}/_ext/726959463/qstamp.o.d" -o ${OBJECTDIR}/_ext/726959463/qstamp.o ../../../../../include/qstamp.c -DXPRJ_rel=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -else -${OBJECTDIR}/_ext/820665871/qep_hsm.o: ../../../../../src/qf/qep_hsm.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/820665871" - @${RM} ${OBJECTDIR}/_ext/820665871/qep_hsm.o.d - @${RM} ${OBJECTDIR}/_ext/820665871/qep_hsm.o - @${FIXDEPS} "${OBJECTDIR}/_ext/820665871/qep_hsm.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -O3 -DNDEBUG -I"../.." -I"../../../../../include" -I"../../../../../src" -I"../../../../../ports/pic32/qk/xc32" -MMD -MF "${OBJECTDIR}/_ext/820665871/qep_hsm.o.d" -o ${OBJECTDIR}/_ext/820665871/qep_hsm.o ../../../../../src/qf/qep_hsm.c -DXPRJ_rel=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/820665871/qep_msm.o: ../../../../../src/qf/qep_msm.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/820665871" - @${RM} ${OBJECTDIR}/_ext/820665871/qep_msm.o.d - @${RM} ${OBJECTDIR}/_ext/820665871/qep_msm.o - @${FIXDEPS} "${OBJECTDIR}/_ext/820665871/qep_msm.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -O3 -DNDEBUG -I"../.." -I"../../../../../include" -I"../../../../../src" -I"../../../../../ports/pic32/qk/xc32" -MMD -MF "${OBJECTDIR}/_ext/820665871/qep_msm.o.d" -o ${OBJECTDIR}/_ext/820665871/qep_msm.o ../../../../../src/qf/qep_msm.c -DXPRJ_rel=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/820665871/qf_act.o: ../../../../../src/qf/qf_act.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/820665871" - @${RM} ${OBJECTDIR}/_ext/820665871/qf_act.o.d - @${RM} ${OBJECTDIR}/_ext/820665871/qf_act.o - @${FIXDEPS} "${OBJECTDIR}/_ext/820665871/qf_act.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -O3 -DNDEBUG -I"../.." -I"../../../../../include" -I"../../../../../src" -I"../../../../../ports/pic32/qk/xc32" -MMD -MF "${OBJECTDIR}/_ext/820665871/qf_act.o.d" -o ${OBJECTDIR}/_ext/820665871/qf_act.o ../../../../../src/qf/qf_act.c -DXPRJ_rel=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/820665871/qf_actq.o: ../../../../../src/qf/qf_actq.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/820665871" - @${RM} ${OBJECTDIR}/_ext/820665871/qf_actq.o.d - @${RM} ${OBJECTDIR}/_ext/820665871/qf_actq.o - @${FIXDEPS} "${OBJECTDIR}/_ext/820665871/qf_actq.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -O3 -DNDEBUG -I"../.." -I"../../../../../include" -I"../../../../../src" -I"../../../../../ports/pic32/qk/xc32" -MMD -MF "${OBJECTDIR}/_ext/820665871/qf_actq.o.d" -o ${OBJECTDIR}/_ext/820665871/qf_actq.o ../../../../../src/qf/qf_actq.c -DXPRJ_rel=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/820665871/qf_defer.o: ../../../../../src/qf/qf_defer.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/820665871" - @${RM} ${OBJECTDIR}/_ext/820665871/qf_defer.o.d - @${RM} ${OBJECTDIR}/_ext/820665871/qf_defer.o - @${FIXDEPS} "${OBJECTDIR}/_ext/820665871/qf_defer.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -O3 -DNDEBUG -I"../.." -I"../../../../../include" -I"../../../../../src" -I"../../../../../ports/pic32/qk/xc32" -MMD -MF "${OBJECTDIR}/_ext/820665871/qf_defer.o.d" -o ${OBJECTDIR}/_ext/820665871/qf_defer.o ../../../../../src/qf/qf_defer.c -DXPRJ_rel=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/820665871/qf_dyn.o: ../../../../../src/qf/qf_dyn.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/820665871" - @${RM} ${OBJECTDIR}/_ext/820665871/qf_dyn.o.d - @${RM} ${OBJECTDIR}/_ext/820665871/qf_dyn.o - @${FIXDEPS} "${OBJECTDIR}/_ext/820665871/qf_dyn.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -O3 -DNDEBUG -I"../.." -I"../../../../../include" -I"../../../../../src" -I"../../../../../ports/pic32/qk/xc32" -MMD -MF "${OBJECTDIR}/_ext/820665871/qf_dyn.o.d" -o ${OBJECTDIR}/_ext/820665871/qf_dyn.o ../../../../../src/qf/qf_dyn.c -DXPRJ_rel=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/820665871/qf_mem.o: ../../../../../src/qf/qf_mem.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/820665871" - @${RM} ${OBJECTDIR}/_ext/820665871/qf_mem.o.d - @${RM} ${OBJECTDIR}/_ext/820665871/qf_mem.o - @${FIXDEPS} "${OBJECTDIR}/_ext/820665871/qf_mem.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -O3 -DNDEBUG -I"../.." -I"../../../../../include" -I"../../../../../src" -I"../../../../../ports/pic32/qk/xc32" -MMD -MF "${OBJECTDIR}/_ext/820665871/qf_mem.o.d" -o ${OBJECTDIR}/_ext/820665871/qf_mem.o ../../../../../src/qf/qf_mem.c -DXPRJ_rel=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/820665871/qf_ps.o: ../../../../../src/qf/qf_ps.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/820665871" - @${RM} ${OBJECTDIR}/_ext/820665871/qf_ps.o.d - @${RM} ${OBJECTDIR}/_ext/820665871/qf_ps.o - @${FIXDEPS} "${OBJECTDIR}/_ext/820665871/qf_ps.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -O3 -DNDEBUG -I"../.." -I"../../../../../include" -I"../../../../../src" -I"../../../../../ports/pic32/qk/xc32" -MMD -MF "${OBJECTDIR}/_ext/820665871/qf_ps.o.d" -o ${OBJECTDIR}/_ext/820665871/qf_ps.o ../../../../../src/qf/qf_ps.c -DXPRJ_rel=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/820665871/qf_qact.o: ../../../../../src/qf/qf_qact.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/820665871" - @${RM} ${OBJECTDIR}/_ext/820665871/qf_qact.o.d - @${RM} ${OBJECTDIR}/_ext/820665871/qf_qact.o - @${FIXDEPS} "${OBJECTDIR}/_ext/820665871/qf_qact.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -O3 -DNDEBUG -I"../.." -I"../../../../../include" -I"../../../../../src" -I"../../../../../ports/pic32/qk/xc32" -MMD -MF "${OBJECTDIR}/_ext/820665871/qf_qact.o.d" -o ${OBJECTDIR}/_ext/820665871/qf_qact.o ../../../../../src/qf/qf_qact.c -DXPRJ_rel=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/820665871/qf_qeq.o: ../../../../../src/qf/qf_qeq.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/820665871" - @${RM} ${OBJECTDIR}/_ext/820665871/qf_qeq.o.d - @${RM} ${OBJECTDIR}/_ext/820665871/qf_qeq.o - @${FIXDEPS} "${OBJECTDIR}/_ext/820665871/qf_qeq.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -O3 -DNDEBUG -I"../.." -I"../../../../../include" -I"../../../../../src" -I"../../../../../ports/pic32/qk/xc32" -MMD -MF "${OBJECTDIR}/_ext/820665871/qf_qeq.o.d" -o ${OBJECTDIR}/_ext/820665871/qf_qeq.o ../../../../../src/qf/qf_qeq.c -DXPRJ_rel=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/820665871/qf_qmact.o: ../../../../../src/qf/qf_qmact.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/820665871" - @${RM} ${OBJECTDIR}/_ext/820665871/qf_qmact.o.d - @${RM} ${OBJECTDIR}/_ext/820665871/qf_qmact.o - @${FIXDEPS} "${OBJECTDIR}/_ext/820665871/qf_qmact.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -O3 -DNDEBUG -I"../.." -I"../../../../../include" -I"../../../../../src" -I"../../../../../ports/pic32/qk/xc32" -MMD -MF "${OBJECTDIR}/_ext/820665871/qf_qmact.o.d" -o ${OBJECTDIR}/_ext/820665871/qf_qmact.o ../../../../../src/qf/qf_qmact.c -DXPRJ_rel=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/820665871/qf_time.o: ../../../../../src/qf/qf_time.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/820665871" - @${RM} ${OBJECTDIR}/_ext/820665871/qf_time.o.d - @${RM} ${OBJECTDIR}/_ext/820665871/qf_time.o - @${FIXDEPS} "${OBJECTDIR}/_ext/820665871/qf_time.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -O3 -DNDEBUG -I"../.." -I"../../../../../include" -I"../../../../../src" -I"../../../../../ports/pic32/qk/xc32" -MMD -MF "${OBJECTDIR}/_ext/820665871/qf_time.o.d" -o ${OBJECTDIR}/_ext/820665871/qf_time.o ../../../../../src/qf/qf_time.c -DXPRJ_rel=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/820665876/qk.o: ../../../../../src/qk/qk.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/820665876" - @${RM} ${OBJECTDIR}/_ext/820665876/qk.o.d - @${RM} ${OBJECTDIR}/_ext/820665876/qk.o - @${FIXDEPS} "${OBJECTDIR}/_ext/820665876/qk.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -O3 -DNDEBUG -I"../.." -I"../../../../../include" -I"../../../../../src" -I"../../../../../ports/pic32/qk/xc32" -MMD -MF "${OBJECTDIR}/_ext/820665876/qk.o.d" -o ${OBJECTDIR}/_ext/820665876/qk.o ../../../../../src/qk/qk.c -DXPRJ_rel=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/1627782163/qk_port.o: ../../../../../ports/pic32/qk/xc32/qk_port.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/1627782163" - @${RM} ${OBJECTDIR}/_ext/1627782163/qk_port.o.d - @${RM} ${OBJECTDIR}/_ext/1627782163/qk_port.o - @${FIXDEPS} "${OBJECTDIR}/_ext/1627782163/qk_port.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -O3 -DNDEBUG -I"../.." -I"../../../../../include" -I"../../../../../src" -I"../../../../../ports/pic32/qk/xc32" -MMD -MF "${OBJECTDIR}/_ext/1627782163/qk_port.o.d" -o ${OBJECTDIR}/_ext/1627782163/qk_port.o ../../../../../ports/pic32/qk/xc32/qk_port.c -DXPRJ_rel=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/bsp.o: bsp.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}" - @${RM} ${OBJECTDIR}/bsp.o.d - @${RM} ${OBJECTDIR}/bsp.o - @${FIXDEPS} "${OBJECTDIR}/bsp.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -O3 -DNDEBUG -I"../.." -I"../../../../../include" -I"../../../../../src" -I"../../../../../ports/pic32/qk/xc32" -MMD -MF "${OBJECTDIR}/bsp.o.d" -o ${OBJECTDIR}/bsp.o bsp.c -DXPRJ_rel=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/43898991/blinky.o: ../../blinky.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/43898991" - @${RM} ${OBJECTDIR}/_ext/43898991/blinky.o.d - @${RM} ${OBJECTDIR}/_ext/43898991/blinky.o - @${FIXDEPS} "${OBJECTDIR}/_ext/43898991/blinky.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -O3 -DNDEBUG -I"../.." -I"../../../../../include" -I"../../../../../src" -I"../../../../../ports/pic32/qk/xc32" -MMD -MF "${OBJECTDIR}/_ext/43898991/blinky.o.d" -o ${OBJECTDIR}/_ext/43898991/blinky.o ../../blinky.c -DXPRJ_rel=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/43898991/main.o: ../../main.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/43898991" - @${RM} ${OBJECTDIR}/_ext/43898991/main.o.d - @${RM} ${OBJECTDIR}/_ext/43898991/main.o - @${FIXDEPS} "${OBJECTDIR}/_ext/43898991/main.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -O3 -DNDEBUG -I"../.." -I"../../../../../include" -I"../../../../../src" -I"../../../../../ports/pic32/qk/xc32" -MMD -MF "${OBJECTDIR}/_ext/43898991/main.o.d" -o ${OBJECTDIR}/_ext/43898991/main.o ../../main.c -DXPRJ_rel=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/726959463/qstamp.o: ../../../../../include/qstamp.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/726959463" - @${RM} ${OBJECTDIR}/_ext/726959463/qstamp.o.d - @${RM} ${OBJECTDIR}/_ext/726959463/qstamp.o - @${FIXDEPS} "${OBJECTDIR}/_ext/726959463/qstamp.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -O3 -DNDEBUG -I"../.." -I"../../../../../include" -I"../../../../../src" -I"../../../../../ports/pic32/qk/xc32" -MMD -MF "${OBJECTDIR}/_ext/726959463/qstamp.o.d" -o ${OBJECTDIR}/_ext/726959463/qstamp.o ../../../../../include/qstamp.c -DXPRJ_rel=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -endif - -# ------------------------------------------------------------------------------------ -# Rules for buildStep: compileCPP -ifeq ($(TYPE_IMAGE), DEBUG_RUN) -else -endif - -# ------------------------------------------------------------------------------------ -# Rules for buildStep: link -ifeq ($(TYPE_IMAGE), DEBUG_RUN) -dist/${CND_CONF}/${IMAGE_TYPE}/xc32.${IMAGE_TYPE}.${OUTPUT_SUFFIX}: ${OBJECTFILES} nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} dist/${CND_CONF}/${IMAGE_TYPE} - ${MP_CC} $(MP_EXTRA_LD_PRE) -g -mdebugger -D__MPLAB_DEBUGGER_PK3=1 -mprocessor=$(MP_PROCESSOR_OPTION) -o dist/${CND_CONF}/${IMAGE_TYPE}/xc32.${IMAGE_TYPE}.${OUTPUT_SUFFIX} ${OBJECTFILES_QUOTED_IF_SPACED} -DXPRJ_rel=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -mreserve=data@0x0:0x1FC -mreserve=boot@0x1FC00490:0x1FC00BEF -Wl,--defsym=__MPLAB_BUILD=1$(MP_EXTRA_LD_POST)$(MP_LINKER_FILE_OPTION),--defsym=__MPLAB_DEBUG=1,--defsym=__DEBUG=1,-D=__DEBUG_D,--defsym=__MPLAB_DEBUGGER_PK3=1,--defsym=_min_heap_size=0,--no-code-in-dinit,--no-dinit-in-serial-mem,--report-mem,--warn-section-align,--memorysummary,dist/${CND_CONF}/${IMAGE_TYPE}/memoryfile.xml - -else -dist/${CND_CONF}/${IMAGE_TYPE}/xc32.${IMAGE_TYPE}.${OUTPUT_SUFFIX}: ${OBJECTFILES} nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} dist/${CND_CONF}/${IMAGE_TYPE} - ${MP_CC} $(MP_EXTRA_LD_PRE) -mprocessor=$(MP_PROCESSOR_OPTION) -o dist/${CND_CONF}/${IMAGE_TYPE}/xc32.${IMAGE_TYPE}.${DEBUGGABLE_SUFFIX} ${OBJECTFILES_QUOTED_IF_SPACED} -DXPRJ_rel=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -Wl,--defsym=__MPLAB_BUILD=1$(MP_EXTRA_LD_POST)$(MP_LINKER_FILE_OPTION),--defsym=_min_heap_size=0,--no-code-in-dinit,--no-dinit-in-serial-mem,--report-mem,--warn-section-align,--memorysummary,dist/${CND_CONF}/${IMAGE_TYPE}/memoryfile.xml - ${MP_CC_DIR}\\xc32-bin2hex dist/${CND_CONF}/${IMAGE_TYPE}/xc32.${IMAGE_TYPE}.${DEBUGGABLE_SUFFIX} -endif - - -# Subprojects -.build-subprojects: - - -# Subprojects -.clean-subprojects: - -# Clean Targets -.clean-conf: ${CLEAN_SUBPROJECTS} - ${RM} -r build/rel - ${RM} -r dist/rel - -# Enable dependency checking -.dep.inc: .depcheck-impl - -DEPFILES=$(shell mplabwildcard ${POSSIBLE_DEPFILES}) -ifneq (${DEPFILES},) -include ${DEPFILES} -endif diff --git a/examples/pic32/blinky_microstick2-pic32/qk/xc32/nbproject/Makefile-spy.mk b/examples/pic32/blinky_microstick2-pic32/qk/xc32/nbproject/Makefile-spy.mk deleted file mode 100644 index 6ecd6a14..00000000 --- a/examples/pic32/blinky_microstick2-pic32/qk/xc32/nbproject/Makefile-spy.mk +++ /dev/null @@ -1,415 +0,0 @@ -# -# Generated Makefile - do not edit! -# -# Edit the Makefile in the project folder instead (../Makefile). Each target -# has a -pre and a -post target defined where you can add customized code. -# -# This makefile implements configuration specific macros and targets. - - -# Include project Makefile -ifeq "${IGNORE_LOCAL}" "TRUE" -# do not include local makefile. User is passing all local related variables already -else -include Makefile -# Include makefile containing local settings -ifeq "$(wildcard nbproject/Makefile-local-spy.mk)" "nbproject/Makefile-local-spy.mk" -include nbproject/Makefile-local-spy.mk -endif -endif - -# Environment -MKDIR=gnumkdir -p -RM=rm -f -MV=mv -CP=cp - -# Macros -CND_CONF=spy -ifeq ($(TYPE_IMAGE), DEBUG_RUN) -IMAGE_TYPE=debug -OUTPUT_SUFFIX=elf -DEBUGGABLE_SUFFIX=elf -FINAL_IMAGE=dist/${CND_CONF}/${IMAGE_TYPE}/xc32.${IMAGE_TYPE}.${OUTPUT_SUFFIX} -else -IMAGE_TYPE=production -OUTPUT_SUFFIX=hex -DEBUGGABLE_SUFFIX=elf -FINAL_IMAGE=dist/${CND_CONF}/${IMAGE_TYPE}/xc32.${IMAGE_TYPE}.${OUTPUT_SUFFIX} -endif - -ifeq ($(COMPARE_BUILD), true) -COMPARISON_BUILD=-mafrlcsj -else -COMPARISON_BUILD= -endif - -ifdef SUB_IMAGE_ADDRESS - -else -SUB_IMAGE_ADDRESS_COMMAND= -endif - -# Object Directory -OBJECTDIR=build/${CND_CONF}/${IMAGE_TYPE} - -# Distribution Directory -DISTDIR=dist/${CND_CONF}/${IMAGE_TYPE} - -# Source Files Quoted if spaced -SOURCEFILES_QUOTED_IF_SPACED=../../../../../src/qf/qep_hsm.c ../../../../../src/qf/qep_msm.c ../../../../../src/qf/qf_act.c ../../../../../src/qf/qf_actq.c ../../../../../src/qf/qf_defer.c ../../../../../src/qf/qf_dyn.c ../../../../../src/qf/qf_mem.c ../../../../../src/qf/qf_ps.c ../../../../../src/qf/qf_qact.c ../../../../../src/qf/qf_qeq.c ../../../../../src/qf/qf_qmact.c ../../../../../src/qf/qf_time.c ../../../../../src/qk/qk.c ../../../../../ports/pic32/qk/xc32/qk_port.c ../../../../../src/qs/qs.c ../../../../../src/qs/qs_64bit.c ../../../../../src/qs/qs_fp.c ../../../../../src/qs/qs_rx.c bsp.c ../../blinky.c ../../main.c ../../../../../include/qstamp.c - -# Object Files Quoted if spaced -OBJECTFILES_QUOTED_IF_SPACED=${OBJECTDIR}/_ext/820665871/qep_hsm.o ${OBJECTDIR}/_ext/820665871/qep_msm.o ${OBJECTDIR}/_ext/820665871/qf_act.o ${OBJECTDIR}/_ext/820665871/qf_actq.o ${OBJECTDIR}/_ext/820665871/qf_defer.o ${OBJECTDIR}/_ext/820665871/qf_dyn.o ${OBJECTDIR}/_ext/820665871/qf_mem.o ${OBJECTDIR}/_ext/820665871/qf_ps.o ${OBJECTDIR}/_ext/820665871/qf_qact.o ${OBJECTDIR}/_ext/820665871/qf_qeq.o ${OBJECTDIR}/_ext/820665871/qf_qmact.o ${OBJECTDIR}/_ext/820665871/qf_time.o ${OBJECTDIR}/_ext/820665876/qk.o ${OBJECTDIR}/_ext/1627782163/qk_port.o ${OBJECTDIR}/_ext/820665884/qs.o ${OBJECTDIR}/_ext/820665884/qs_64bit.o ${OBJECTDIR}/_ext/820665884/qs_fp.o ${OBJECTDIR}/_ext/820665884/qs_rx.o ${OBJECTDIR}/bsp.o ${OBJECTDIR}/_ext/43898991/blinky.o ${OBJECTDIR}/_ext/43898991/main.o ${OBJECTDIR}/_ext/726959463/qstamp.o -POSSIBLE_DEPFILES=${OBJECTDIR}/_ext/820665871/qep_hsm.o.d ${OBJECTDIR}/_ext/820665871/qep_msm.o.d ${OBJECTDIR}/_ext/820665871/qf_act.o.d ${OBJECTDIR}/_ext/820665871/qf_actq.o.d ${OBJECTDIR}/_ext/820665871/qf_defer.o.d ${OBJECTDIR}/_ext/820665871/qf_dyn.o.d ${OBJECTDIR}/_ext/820665871/qf_mem.o.d ${OBJECTDIR}/_ext/820665871/qf_ps.o.d ${OBJECTDIR}/_ext/820665871/qf_qact.o.d ${OBJECTDIR}/_ext/820665871/qf_qeq.o.d ${OBJECTDIR}/_ext/820665871/qf_qmact.o.d ${OBJECTDIR}/_ext/820665871/qf_time.o.d ${OBJECTDIR}/_ext/820665876/qk.o.d ${OBJECTDIR}/_ext/1627782163/qk_port.o.d ${OBJECTDIR}/_ext/820665884/qs.o.d ${OBJECTDIR}/_ext/820665884/qs_64bit.o.d ${OBJECTDIR}/_ext/820665884/qs_fp.o.d ${OBJECTDIR}/_ext/820665884/qs_rx.o.d ${OBJECTDIR}/bsp.o.d ${OBJECTDIR}/_ext/43898991/blinky.o.d ${OBJECTDIR}/_ext/43898991/main.o.d ${OBJECTDIR}/_ext/726959463/qstamp.o.d - -# Object Files -OBJECTFILES=${OBJECTDIR}/_ext/820665871/qep_hsm.o ${OBJECTDIR}/_ext/820665871/qep_msm.o ${OBJECTDIR}/_ext/820665871/qf_act.o ${OBJECTDIR}/_ext/820665871/qf_actq.o ${OBJECTDIR}/_ext/820665871/qf_defer.o ${OBJECTDIR}/_ext/820665871/qf_dyn.o ${OBJECTDIR}/_ext/820665871/qf_mem.o ${OBJECTDIR}/_ext/820665871/qf_ps.o ${OBJECTDIR}/_ext/820665871/qf_qact.o ${OBJECTDIR}/_ext/820665871/qf_qeq.o ${OBJECTDIR}/_ext/820665871/qf_qmact.o ${OBJECTDIR}/_ext/820665871/qf_time.o ${OBJECTDIR}/_ext/820665876/qk.o ${OBJECTDIR}/_ext/1627782163/qk_port.o ${OBJECTDIR}/_ext/820665884/qs.o ${OBJECTDIR}/_ext/820665884/qs_64bit.o ${OBJECTDIR}/_ext/820665884/qs_fp.o ${OBJECTDIR}/_ext/820665884/qs_rx.o ${OBJECTDIR}/bsp.o ${OBJECTDIR}/_ext/43898991/blinky.o ${OBJECTDIR}/_ext/43898991/main.o ${OBJECTDIR}/_ext/726959463/qstamp.o - -# Source Files -SOURCEFILES=../../../../../src/qf/qep_hsm.c ../../../../../src/qf/qep_msm.c ../../../../../src/qf/qf_act.c ../../../../../src/qf/qf_actq.c ../../../../../src/qf/qf_defer.c ../../../../../src/qf/qf_dyn.c ../../../../../src/qf/qf_mem.c ../../../../../src/qf/qf_ps.c ../../../../../src/qf/qf_qact.c ../../../../../src/qf/qf_qeq.c ../../../../../src/qf/qf_qmact.c ../../../../../src/qf/qf_time.c ../../../../../src/qk/qk.c ../../../../../ports/pic32/qk/xc32/qk_port.c ../../../../../src/qs/qs.c ../../../../../src/qs/qs_64bit.c ../../../../../src/qs/qs_fp.c ../../../../../src/qs/qs_rx.c bsp.c ../../blinky.c ../../main.c ../../../../../include/qstamp.c - - -CFLAGS= -ASFLAGS= -LDLIBSOPTIONS= - -############# Tool locations ########################################## -# If you copy a project from one host to another, the path where the # -# compiler is installed may be different. # -# If you open this project with MPLAB X in the new host, this # -# makefile will be regenerated and the paths will be corrected. # -####################################################################### -# fixDeps replaces a bunch of sed/cat/printf statements that slow down the build -FIXDEPS=fixDeps - -.build-conf: ${BUILD_SUBPROJECTS} -ifneq ($(INFORMATION_MESSAGE), ) - @echo $(INFORMATION_MESSAGE) -endif - ${MAKE} -f nbproject/Makefile-spy.mk dist/${CND_CONF}/${IMAGE_TYPE}/xc32.${IMAGE_TYPE}.${OUTPUT_SUFFIX} - -MP_PROCESSOR_OPTION=32MX250F128B -MP_LINKER_FILE_OPTION= -# ------------------------------------------------------------------------------------ -# Rules for buildStep: assemble -ifeq ($(TYPE_IMAGE), DEBUG_RUN) -else -endif - -# ------------------------------------------------------------------------------------ -# Rules for buildStep: assembleWithPreprocess -ifeq ($(TYPE_IMAGE), DEBUG_RUN) -else -endif - -# ------------------------------------------------------------------------------------ -# Rules for buildStep: compile -ifeq ($(TYPE_IMAGE), DEBUG_RUN) -${OBJECTDIR}/_ext/820665871/qep_hsm.o: ../../../../../src/qf/qep_hsm.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/820665871" - @${RM} ${OBJECTDIR}/_ext/820665871/qep_hsm.o.d - @${RM} ${OBJECTDIR}/_ext/820665871/qep_hsm.o - @${FIXDEPS} "${OBJECTDIR}/_ext/820665871/qep_hsm.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -D__DEBUG -D__MPLAB_DEBUGGER_PK3=1 -fframe-base-loclist -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -DQ_SPY -I"../../../../../include" -I"../../../../../src" -I"../../../../../ports/pic32/qk/xc32" -I"../.." -MMD -MF "${OBJECTDIR}/_ext/820665871/qep_hsm.o.d" -o ${OBJECTDIR}/_ext/820665871/qep_hsm.o ../../../../../src/qf/qep_hsm.c -DXPRJ_spy=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/820665871/qep_msm.o: ../../../../../src/qf/qep_msm.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/820665871" - @${RM} ${OBJECTDIR}/_ext/820665871/qep_msm.o.d - @${RM} ${OBJECTDIR}/_ext/820665871/qep_msm.o - @${FIXDEPS} "${OBJECTDIR}/_ext/820665871/qep_msm.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -D__DEBUG -D__MPLAB_DEBUGGER_PK3=1 -fframe-base-loclist -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -DQ_SPY -I"../../../../../include" -I"../../../../../src" -I"../../../../../ports/pic32/qk/xc32" -I"../.." -MMD -MF "${OBJECTDIR}/_ext/820665871/qep_msm.o.d" -o ${OBJECTDIR}/_ext/820665871/qep_msm.o ../../../../../src/qf/qep_msm.c -DXPRJ_spy=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/820665871/qf_act.o: ../../../../../src/qf/qf_act.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/820665871" - @${RM} ${OBJECTDIR}/_ext/820665871/qf_act.o.d - @${RM} ${OBJECTDIR}/_ext/820665871/qf_act.o - @${FIXDEPS} "${OBJECTDIR}/_ext/820665871/qf_act.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -D__DEBUG -D__MPLAB_DEBUGGER_PK3=1 -fframe-base-loclist -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -DQ_SPY -I"../../../../../include" -I"../../../../../src" -I"../../../../../ports/pic32/qk/xc32" -I"../.." -MMD -MF "${OBJECTDIR}/_ext/820665871/qf_act.o.d" -o ${OBJECTDIR}/_ext/820665871/qf_act.o ../../../../../src/qf/qf_act.c -DXPRJ_spy=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/820665871/qf_actq.o: ../../../../../src/qf/qf_actq.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/820665871" - @${RM} ${OBJECTDIR}/_ext/820665871/qf_actq.o.d - @${RM} ${OBJECTDIR}/_ext/820665871/qf_actq.o - @${FIXDEPS} "${OBJECTDIR}/_ext/820665871/qf_actq.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -D__DEBUG -D__MPLAB_DEBUGGER_PK3=1 -fframe-base-loclist -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -DQ_SPY -I"../../../../../include" -I"../../../../../src" -I"../../../../../ports/pic32/qk/xc32" -I"../.." -MMD -MF "${OBJECTDIR}/_ext/820665871/qf_actq.o.d" -o ${OBJECTDIR}/_ext/820665871/qf_actq.o ../../../../../src/qf/qf_actq.c -DXPRJ_spy=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/820665871/qf_defer.o: ../../../../../src/qf/qf_defer.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/820665871" - @${RM} ${OBJECTDIR}/_ext/820665871/qf_defer.o.d - @${RM} ${OBJECTDIR}/_ext/820665871/qf_defer.o - @${FIXDEPS} "${OBJECTDIR}/_ext/820665871/qf_defer.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -D__DEBUG -D__MPLAB_DEBUGGER_PK3=1 -fframe-base-loclist -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -DQ_SPY -I"../../../../../include" -I"../../../../../src" -I"../../../../../ports/pic32/qk/xc32" -I"../.." -MMD -MF "${OBJECTDIR}/_ext/820665871/qf_defer.o.d" -o ${OBJECTDIR}/_ext/820665871/qf_defer.o ../../../../../src/qf/qf_defer.c -DXPRJ_spy=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/820665871/qf_dyn.o: ../../../../../src/qf/qf_dyn.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/820665871" - @${RM} ${OBJECTDIR}/_ext/820665871/qf_dyn.o.d - @${RM} ${OBJECTDIR}/_ext/820665871/qf_dyn.o - @${FIXDEPS} "${OBJECTDIR}/_ext/820665871/qf_dyn.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -D__DEBUG -D__MPLAB_DEBUGGER_PK3=1 -fframe-base-loclist -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -DQ_SPY -I"../../../../../include" -I"../../../../../src" -I"../../../../../ports/pic32/qk/xc32" -I"../.." -MMD -MF "${OBJECTDIR}/_ext/820665871/qf_dyn.o.d" -o ${OBJECTDIR}/_ext/820665871/qf_dyn.o ../../../../../src/qf/qf_dyn.c -DXPRJ_spy=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/820665871/qf_mem.o: ../../../../../src/qf/qf_mem.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/820665871" - @${RM} ${OBJECTDIR}/_ext/820665871/qf_mem.o.d - @${RM} ${OBJECTDIR}/_ext/820665871/qf_mem.o - @${FIXDEPS} "${OBJECTDIR}/_ext/820665871/qf_mem.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -D__DEBUG -D__MPLAB_DEBUGGER_PK3=1 -fframe-base-loclist -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -DQ_SPY -I"../../../../../include" -I"../../../../../src" -I"../../../../../ports/pic32/qk/xc32" -I"../.." -MMD -MF "${OBJECTDIR}/_ext/820665871/qf_mem.o.d" -o ${OBJECTDIR}/_ext/820665871/qf_mem.o ../../../../../src/qf/qf_mem.c -DXPRJ_spy=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/820665871/qf_ps.o: ../../../../../src/qf/qf_ps.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/820665871" - @${RM} ${OBJECTDIR}/_ext/820665871/qf_ps.o.d - @${RM} ${OBJECTDIR}/_ext/820665871/qf_ps.o - @${FIXDEPS} "${OBJECTDIR}/_ext/820665871/qf_ps.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -D__DEBUG -D__MPLAB_DEBUGGER_PK3=1 -fframe-base-loclist -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -DQ_SPY -I"../../../../../include" -I"../../../../../src" -I"../../../../../ports/pic32/qk/xc32" -I"../.." -MMD -MF "${OBJECTDIR}/_ext/820665871/qf_ps.o.d" -o ${OBJECTDIR}/_ext/820665871/qf_ps.o ../../../../../src/qf/qf_ps.c -DXPRJ_spy=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/820665871/qf_qact.o: ../../../../../src/qf/qf_qact.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/820665871" - @${RM} ${OBJECTDIR}/_ext/820665871/qf_qact.o.d - @${RM} ${OBJECTDIR}/_ext/820665871/qf_qact.o - @${FIXDEPS} "${OBJECTDIR}/_ext/820665871/qf_qact.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -D__DEBUG -D__MPLAB_DEBUGGER_PK3=1 -fframe-base-loclist -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -DQ_SPY -I"../../../../../include" -I"../../../../../src" -I"../../../../../ports/pic32/qk/xc32" -I"../.." -MMD -MF "${OBJECTDIR}/_ext/820665871/qf_qact.o.d" -o ${OBJECTDIR}/_ext/820665871/qf_qact.o ../../../../../src/qf/qf_qact.c -DXPRJ_spy=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/820665871/qf_qeq.o: ../../../../../src/qf/qf_qeq.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/820665871" - @${RM} ${OBJECTDIR}/_ext/820665871/qf_qeq.o.d - @${RM} ${OBJECTDIR}/_ext/820665871/qf_qeq.o - @${FIXDEPS} "${OBJECTDIR}/_ext/820665871/qf_qeq.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -D__DEBUG -D__MPLAB_DEBUGGER_PK3=1 -fframe-base-loclist -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -DQ_SPY -I"../../../../../include" -I"../../../../../src" -I"../../../../../ports/pic32/qk/xc32" -I"../.." -MMD -MF "${OBJECTDIR}/_ext/820665871/qf_qeq.o.d" -o ${OBJECTDIR}/_ext/820665871/qf_qeq.o ../../../../../src/qf/qf_qeq.c -DXPRJ_spy=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/820665871/qf_qmact.o: ../../../../../src/qf/qf_qmact.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/820665871" - @${RM} ${OBJECTDIR}/_ext/820665871/qf_qmact.o.d - @${RM} ${OBJECTDIR}/_ext/820665871/qf_qmact.o - @${FIXDEPS} "${OBJECTDIR}/_ext/820665871/qf_qmact.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -D__DEBUG -D__MPLAB_DEBUGGER_PK3=1 -fframe-base-loclist -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -DQ_SPY -I"../../../../../include" -I"../../../../../src" -I"../../../../../ports/pic32/qk/xc32" -I"../.." -MMD -MF "${OBJECTDIR}/_ext/820665871/qf_qmact.o.d" -o ${OBJECTDIR}/_ext/820665871/qf_qmact.o ../../../../../src/qf/qf_qmact.c -DXPRJ_spy=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/820665871/qf_time.o: ../../../../../src/qf/qf_time.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/820665871" - @${RM} ${OBJECTDIR}/_ext/820665871/qf_time.o.d - @${RM} ${OBJECTDIR}/_ext/820665871/qf_time.o - @${FIXDEPS} "${OBJECTDIR}/_ext/820665871/qf_time.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -D__DEBUG -D__MPLAB_DEBUGGER_PK3=1 -fframe-base-loclist -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -DQ_SPY -I"../../../../../include" -I"../../../../../src" -I"../../../../../ports/pic32/qk/xc32" -I"../.." -MMD -MF "${OBJECTDIR}/_ext/820665871/qf_time.o.d" -o ${OBJECTDIR}/_ext/820665871/qf_time.o ../../../../../src/qf/qf_time.c -DXPRJ_spy=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/820665876/qk.o: ../../../../../src/qk/qk.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/820665876" - @${RM} ${OBJECTDIR}/_ext/820665876/qk.o.d - @${RM} ${OBJECTDIR}/_ext/820665876/qk.o - @${FIXDEPS} "${OBJECTDIR}/_ext/820665876/qk.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -D__DEBUG -D__MPLAB_DEBUGGER_PK3=1 -fframe-base-loclist -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -DQ_SPY -I"../../../../../include" -I"../../../../../src" -I"../../../../../ports/pic32/qk/xc32" -I"../.." -MMD -MF "${OBJECTDIR}/_ext/820665876/qk.o.d" -o ${OBJECTDIR}/_ext/820665876/qk.o ../../../../../src/qk/qk.c -DXPRJ_spy=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/1627782163/qk_port.o: ../../../../../ports/pic32/qk/xc32/qk_port.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/1627782163" - @${RM} ${OBJECTDIR}/_ext/1627782163/qk_port.o.d - @${RM} ${OBJECTDIR}/_ext/1627782163/qk_port.o - @${FIXDEPS} "${OBJECTDIR}/_ext/1627782163/qk_port.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -D__DEBUG -D__MPLAB_DEBUGGER_PK3=1 -fframe-base-loclist -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -DQ_SPY -I"../../../../../include" -I"../../../../../src" -I"../../../../../ports/pic32/qk/xc32" -I"../.." -MMD -MF "${OBJECTDIR}/_ext/1627782163/qk_port.o.d" -o ${OBJECTDIR}/_ext/1627782163/qk_port.o ../../../../../ports/pic32/qk/xc32/qk_port.c -DXPRJ_spy=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/820665884/qs.o: ../../../../../src/qs/qs.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/820665884" - @${RM} ${OBJECTDIR}/_ext/820665884/qs.o.d - @${RM} ${OBJECTDIR}/_ext/820665884/qs.o - @${FIXDEPS} "${OBJECTDIR}/_ext/820665884/qs.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -D__DEBUG -D__MPLAB_DEBUGGER_PK3=1 -fframe-base-loclist -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -DQ_SPY -I"../../../../../include" -I"../../../../../src" -I"../../../../../ports/pic32/qk/xc32" -I"../.." -MMD -MF "${OBJECTDIR}/_ext/820665884/qs.o.d" -o ${OBJECTDIR}/_ext/820665884/qs.o ../../../../../src/qs/qs.c -DXPRJ_spy=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/820665884/qs_64bit.o: ../../../../../src/qs/qs_64bit.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/820665884" - @${RM} ${OBJECTDIR}/_ext/820665884/qs_64bit.o.d - @${RM} ${OBJECTDIR}/_ext/820665884/qs_64bit.o - @${FIXDEPS} "${OBJECTDIR}/_ext/820665884/qs_64bit.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -D__DEBUG -D__MPLAB_DEBUGGER_PK3=1 -fframe-base-loclist -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -DQ_SPY -I"../../../../../include" -I"../../../../../src" -I"../../../../../ports/pic32/qk/xc32" -I"../.." -MMD -MF "${OBJECTDIR}/_ext/820665884/qs_64bit.o.d" -o ${OBJECTDIR}/_ext/820665884/qs_64bit.o ../../../../../src/qs/qs_64bit.c -DXPRJ_spy=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/820665884/qs_fp.o: ../../../../../src/qs/qs_fp.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/820665884" - @${RM} ${OBJECTDIR}/_ext/820665884/qs_fp.o.d - @${RM} ${OBJECTDIR}/_ext/820665884/qs_fp.o - @${FIXDEPS} "${OBJECTDIR}/_ext/820665884/qs_fp.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -D__DEBUG -D__MPLAB_DEBUGGER_PK3=1 -fframe-base-loclist -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -DQ_SPY -I"../../../../../include" -I"../../../../../src" -I"../../../../../ports/pic32/qk/xc32" -I"../.." -MMD -MF "${OBJECTDIR}/_ext/820665884/qs_fp.o.d" -o ${OBJECTDIR}/_ext/820665884/qs_fp.o ../../../../../src/qs/qs_fp.c -DXPRJ_spy=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/820665884/qs_rx.o: ../../../../../src/qs/qs_rx.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/820665884" - @${RM} ${OBJECTDIR}/_ext/820665884/qs_rx.o.d - @${RM} ${OBJECTDIR}/_ext/820665884/qs_rx.o - @${FIXDEPS} "${OBJECTDIR}/_ext/820665884/qs_rx.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -D__DEBUG -D__MPLAB_DEBUGGER_PK3=1 -fframe-base-loclist -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -DQ_SPY -I"../../../../../include" -I"../../../../../src" -I"../../../../../ports/pic32/qk/xc32" -I"../.." -MMD -MF "${OBJECTDIR}/_ext/820665884/qs_rx.o.d" -o ${OBJECTDIR}/_ext/820665884/qs_rx.o ../../../../../src/qs/qs_rx.c -DXPRJ_spy=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/bsp.o: bsp.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}" - @${RM} ${OBJECTDIR}/bsp.o.d - @${RM} ${OBJECTDIR}/bsp.o - @${FIXDEPS} "${OBJECTDIR}/bsp.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -D__DEBUG -D__MPLAB_DEBUGGER_PK3=1 -fframe-base-loclist -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -DQ_SPY -I"../../../../../include" -I"../../../../../src" -I"../../../../../ports/pic32/qk/xc32" -I"../.." -MMD -MF "${OBJECTDIR}/bsp.o.d" -o ${OBJECTDIR}/bsp.o bsp.c -DXPRJ_spy=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/43898991/blinky.o: ../../blinky.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/43898991" - @${RM} ${OBJECTDIR}/_ext/43898991/blinky.o.d - @${RM} ${OBJECTDIR}/_ext/43898991/blinky.o - @${FIXDEPS} "${OBJECTDIR}/_ext/43898991/blinky.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -D__DEBUG -D__MPLAB_DEBUGGER_PK3=1 -fframe-base-loclist -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -DQ_SPY -I"../../../../../include" -I"../../../../../src" -I"../../../../../ports/pic32/qk/xc32" -I"../.." -MMD -MF "${OBJECTDIR}/_ext/43898991/blinky.o.d" -o ${OBJECTDIR}/_ext/43898991/blinky.o ../../blinky.c -DXPRJ_spy=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/43898991/main.o: ../../main.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/43898991" - @${RM} ${OBJECTDIR}/_ext/43898991/main.o.d - @${RM} ${OBJECTDIR}/_ext/43898991/main.o - @${FIXDEPS} "${OBJECTDIR}/_ext/43898991/main.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -D__DEBUG -D__MPLAB_DEBUGGER_PK3=1 -fframe-base-loclist -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -DQ_SPY -I"../../../../../include" -I"../../../../../src" -I"../../../../../ports/pic32/qk/xc32" -I"../.." -MMD -MF "${OBJECTDIR}/_ext/43898991/main.o.d" -o ${OBJECTDIR}/_ext/43898991/main.o ../../main.c -DXPRJ_spy=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/726959463/qstamp.o: ../../../../../include/qstamp.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/726959463" - @${RM} ${OBJECTDIR}/_ext/726959463/qstamp.o.d - @${RM} ${OBJECTDIR}/_ext/726959463/qstamp.o - @${FIXDEPS} "${OBJECTDIR}/_ext/726959463/qstamp.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -D__DEBUG -D__MPLAB_DEBUGGER_PK3=1 -fframe-base-loclist -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -DQ_SPY -I"../../../../../include" -I"../../../../../src" -I"../../../../../ports/pic32/qk/xc32" -I"../.." -MMD -MF "${OBJECTDIR}/_ext/726959463/qstamp.o.d" -o ${OBJECTDIR}/_ext/726959463/qstamp.o ../../../../../include/qstamp.c -DXPRJ_spy=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -else -${OBJECTDIR}/_ext/820665871/qep_hsm.o: ../../../../../src/qf/qep_hsm.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/820665871" - @${RM} ${OBJECTDIR}/_ext/820665871/qep_hsm.o.d - @${RM} ${OBJECTDIR}/_ext/820665871/qep_hsm.o - @${FIXDEPS} "${OBJECTDIR}/_ext/820665871/qep_hsm.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -DQ_SPY -I"../../../../../include" -I"../../../../../src" -I"../../../../../ports/pic32/qk/xc32" -I"../.." -MMD -MF "${OBJECTDIR}/_ext/820665871/qep_hsm.o.d" -o ${OBJECTDIR}/_ext/820665871/qep_hsm.o ../../../../../src/qf/qep_hsm.c -DXPRJ_spy=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/820665871/qep_msm.o: ../../../../../src/qf/qep_msm.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/820665871" - @${RM} ${OBJECTDIR}/_ext/820665871/qep_msm.o.d - @${RM} ${OBJECTDIR}/_ext/820665871/qep_msm.o - @${FIXDEPS} "${OBJECTDIR}/_ext/820665871/qep_msm.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -DQ_SPY -I"../../../../../include" -I"../../../../../src" -I"../../../../../ports/pic32/qk/xc32" -I"../.." -MMD -MF "${OBJECTDIR}/_ext/820665871/qep_msm.o.d" -o ${OBJECTDIR}/_ext/820665871/qep_msm.o ../../../../../src/qf/qep_msm.c -DXPRJ_spy=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/820665871/qf_act.o: ../../../../../src/qf/qf_act.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/820665871" - @${RM} ${OBJECTDIR}/_ext/820665871/qf_act.o.d - @${RM} ${OBJECTDIR}/_ext/820665871/qf_act.o - @${FIXDEPS} "${OBJECTDIR}/_ext/820665871/qf_act.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -DQ_SPY -I"../../../../../include" -I"../../../../../src" -I"../../../../../ports/pic32/qk/xc32" -I"../.." -MMD -MF "${OBJECTDIR}/_ext/820665871/qf_act.o.d" -o ${OBJECTDIR}/_ext/820665871/qf_act.o ../../../../../src/qf/qf_act.c -DXPRJ_spy=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/820665871/qf_actq.o: ../../../../../src/qf/qf_actq.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/820665871" - @${RM} ${OBJECTDIR}/_ext/820665871/qf_actq.o.d - @${RM} ${OBJECTDIR}/_ext/820665871/qf_actq.o - @${FIXDEPS} "${OBJECTDIR}/_ext/820665871/qf_actq.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -DQ_SPY -I"../../../../../include" -I"../../../../../src" -I"../../../../../ports/pic32/qk/xc32" -I"../.." -MMD -MF "${OBJECTDIR}/_ext/820665871/qf_actq.o.d" -o ${OBJECTDIR}/_ext/820665871/qf_actq.o ../../../../../src/qf/qf_actq.c -DXPRJ_spy=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/820665871/qf_defer.o: ../../../../../src/qf/qf_defer.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/820665871" - @${RM} ${OBJECTDIR}/_ext/820665871/qf_defer.o.d - @${RM} ${OBJECTDIR}/_ext/820665871/qf_defer.o - @${FIXDEPS} "${OBJECTDIR}/_ext/820665871/qf_defer.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -DQ_SPY -I"../../../../../include" -I"../../../../../src" -I"../../../../../ports/pic32/qk/xc32" -I"../.." -MMD -MF "${OBJECTDIR}/_ext/820665871/qf_defer.o.d" -o ${OBJECTDIR}/_ext/820665871/qf_defer.o ../../../../../src/qf/qf_defer.c -DXPRJ_spy=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/820665871/qf_dyn.o: ../../../../../src/qf/qf_dyn.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/820665871" - @${RM} ${OBJECTDIR}/_ext/820665871/qf_dyn.o.d - @${RM} ${OBJECTDIR}/_ext/820665871/qf_dyn.o - @${FIXDEPS} "${OBJECTDIR}/_ext/820665871/qf_dyn.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -DQ_SPY -I"../../../../../include" -I"../../../../../src" -I"../../../../../ports/pic32/qk/xc32" -I"../.." -MMD -MF "${OBJECTDIR}/_ext/820665871/qf_dyn.o.d" -o ${OBJECTDIR}/_ext/820665871/qf_dyn.o ../../../../../src/qf/qf_dyn.c -DXPRJ_spy=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/820665871/qf_mem.o: ../../../../../src/qf/qf_mem.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/820665871" - @${RM} ${OBJECTDIR}/_ext/820665871/qf_mem.o.d - @${RM} ${OBJECTDIR}/_ext/820665871/qf_mem.o - @${FIXDEPS} "${OBJECTDIR}/_ext/820665871/qf_mem.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -DQ_SPY -I"../../../../../include" -I"../../../../../src" -I"../../../../../ports/pic32/qk/xc32" -I"../.." -MMD -MF "${OBJECTDIR}/_ext/820665871/qf_mem.o.d" -o ${OBJECTDIR}/_ext/820665871/qf_mem.o ../../../../../src/qf/qf_mem.c -DXPRJ_spy=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/820665871/qf_ps.o: ../../../../../src/qf/qf_ps.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/820665871" - @${RM} ${OBJECTDIR}/_ext/820665871/qf_ps.o.d - @${RM} ${OBJECTDIR}/_ext/820665871/qf_ps.o - @${FIXDEPS} "${OBJECTDIR}/_ext/820665871/qf_ps.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -DQ_SPY -I"../../../../../include" -I"../../../../../src" -I"../../../../../ports/pic32/qk/xc32" -I"../.." -MMD -MF "${OBJECTDIR}/_ext/820665871/qf_ps.o.d" -o ${OBJECTDIR}/_ext/820665871/qf_ps.o ../../../../../src/qf/qf_ps.c -DXPRJ_spy=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/820665871/qf_qact.o: ../../../../../src/qf/qf_qact.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/820665871" - @${RM} ${OBJECTDIR}/_ext/820665871/qf_qact.o.d - @${RM} ${OBJECTDIR}/_ext/820665871/qf_qact.o - @${FIXDEPS} "${OBJECTDIR}/_ext/820665871/qf_qact.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -DQ_SPY -I"../../../../../include" -I"../../../../../src" -I"../../../../../ports/pic32/qk/xc32" -I"../.." -MMD -MF "${OBJECTDIR}/_ext/820665871/qf_qact.o.d" -o ${OBJECTDIR}/_ext/820665871/qf_qact.o ../../../../../src/qf/qf_qact.c -DXPRJ_spy=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/820665871/qf_qeq.o: ../../../../../src/qf/qf_qeq.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/820665871" - @${RM} ${OBJECTDIR}/_ext/820665871/qf_qeq.o.d - @${RM} ${OBJECTDIR}/_ext/820665871/qf_qeq.o - @${FIXDEPS} "${OBJECTDIR}/_ext/820665871/qf_qeq.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -DQ_SPY -I"../../../../../include" -I"../../../../../src" -I"../../../../../ports/pic32/qk/xc32" -I"../.." -MMD -MF "${OBJECTDIR}/_ext/820665871/qf_qeq.o.d" -o ${OBJECTDIR}/_ext/820665871/qf_qeq.o ../../../../../src/qf/qf_qeq.c -DXPRJ_spy=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/820665871/qf_qmact.o: ../../../../../src/qf/qf_qmact.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/820665871" - @${RM} ${OBJECTDIR}/_ext/820665871/qf_qmact.o.d - @${RM} ${OBJECTDIR}/_ext/820665871/qf_qmact.o - @${FIXDEPS} "${OBJECTDIR}/_ext/820665871/qf_qmact.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -DQ_SPY -I"../../../../../include" -I"../../../../../src" -I"../../../../../ports/pic32/qk/xc32" -I"../.." -MMD -MF "${OBJECTDIR}/_ext/820665871/qf_qmact.o.d" -o ${OBJECTDIR}/_ext/820665871/qf_qmact.o ../../../../../src/qf/qf_qmact.c -DXPRJ_spy=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/820665871/qf_time.o: ../../../../../src/qf/qf_time.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/820665871" - @${RM} ${OBJECTDIR}/_ext/820665871/qf_time.o.d - @${RM} ${OBJECTDIR}/_ext/820665871/qf_time.o - @${FIXDEPS} "${OBJECTDIR}/_ext/820665871/qf_time.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -DQ_SPY -I"../../../../../include" -I"../../../../../src" -I"../../../../../ports/pic32/qk/xc32" -I"../.." -MMD -MF "${OBJECTDIR}/_ext/820665871/qf_time.o.d" -o ${OBJECTDIR}/_ext/820665871/qf_time.o ../../../../../src/qf/qf_time.c -DXPRJ_spy=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/820665876/qk.o: ../../../../../src/qk/qk.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/820665876" - @${RM} ${OBJECTDIR}/_ext/820665876/qk.o.d - @${RM} ${OBJECTDIR}/_ext/820665876/qk.o - @${FIXDEPS} "${OBJECTDIR}/_ext/820665876/qk.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -DQ_SPY -I"../../../../../include" -I"../../../../../src" -I"../../../../../ports/pic32/qk/xc32" -I"../.." -MMD -MF "${OBJECTDIR}/_ext/820665876/qk.o.d" -o ${OBJECTDIR}/_ext/820665876/qk.o ../../../../../src/qk/qk.c -DXPRJ_spy=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/1627782163/qk_port.o: ../../../../../ports/pic32/qk/xc32/qk_port.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/1627782163" - @${RM} ${OBJECTDIR}/_ext/1627782163/qk_port.o.d - @${RM} ${OBJECTDIR}/_ext/1627782163/qk_port.o - @${FIXDEPS} "${OBJECTDIR}/_ext/1627782163/qk_port.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -DQ_SPY -I"../../../../../include" -I"../../../../../src" -I"../../../../../ports/pic32/qk/xc32" -I"../.." -MMD -MF "${OBJECTDIR}/_ext/1627782163/qk_port.o.d" -o ${OBJECTDIR}/_ext/1627782163/qk_port.o ../../../../../ports/pic32/qk/xc32/qk_port.c -DXPRJ_spy=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/820665884/qs.o: ../../../../../src/qs/qs.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/820665884" - @${RM} ${OBJECTDIR}/_ext/820665884/qs.o.d - @${RM} ${OBJECTDIR}/_ext/820665884/qs.o - @${FIXDEPS} "${OBJECTDIR}/_ext/820665884/qs.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -DQ_SPY -I"../../../../../include" -I"../../../../../src" -I"../../../../../ports/pic32/qk/xc32" -I"../.." -MMD -MF "${OBJECTDIR}/_ext/820665884/qs.o.d" -o ${OBJECTDIR}/_ext/820665884/qs.o ../../../../../src/qs/qs.c -DXPRJ_spy=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/820665884/qs_64bit.o: ../../../../../src/qs/qs_64bit.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/820665884" - @${RM} ${OBJECTDIR}/_ext/820665884/qs_64bit.o.d - @${RM} ${OBJECTDIR}/_ext/820665884/qs_64bit.o - @${FIXDEPS} "${OBJECTDIR}/_ext/820665884/qs_64bit.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -DQ_SPY -I"../../../../../include" -I"../../../../../src" -I"../../../../../ports/pic32/qk/xc32" -I"../.." -MMD -MF "${OBJECTDIR}/_ext/820665884/qs_64bit.o.d" -o ${OBJECTDIR}/_ext/820665884/qs_64bit.o ../../../../../src/qs/qs_64bit.c -DXPRJ_spy=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/820665884/qs_fp.o: ../../../../../src/qs/qs_fp.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/820665884" - @${RM} ${OBJECTDIR}/_ext/820665884/qs_fp.o.d - @${RM} ${OBJECTDIR}/_ext/820665884/qs_fp.o - @${FIXDEPS} "${OBJECTDIR}/_ext/820665884/qs_fp.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -DQ_SPY -I"../../../../../include" -I"../../../../../src" -I"../../../../../ports/pic32/qk/xc32" -I"../.." -MMD -MF "${OBJECTDIR}/_ext/820665884/qs_fp.o.d" -o ${OBJECTDIR}/_ext/820665884/qs_fp.o ../../../../../src/qs/qs_fp.c -DXPRJ_spy=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/820665884/qs_rx.o: ../../../../../src/qs/qs_rx.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/820665884" - @${RM} ${OBJECTDIR}/_ext/820665884/qs_rx.o.d - @${RM} ${OBJECTDIR}/_ext/820665884/qs_rx.o - @${FIXDEPS} "${OBJECTDIR}/_ext/820665884/qs_rx.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -DQ_SPY -I"../../../../../include" -I"../../../../../src" -I"../../../../../ports/pic32/qk/xc32" -I"../.." -MMD -MF "${OBJECTDIR}/_ext/820665884/qs_rx.o.d" -o ${OBJECTDIR}/_ext/820665884/qs_rx.o ../../../../../src/qs/qs_rx.c -DXPRJ_spy=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/bsp.o: bsp.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}" - @${RM} ${OBJECTDIR}/bsp.o.d - @${RM} ${OBJECTDIR}/bsp.o - @${FIXDEPS} "${OBJECTDIR}/bsp.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -DQ_SPY -I"../../../../../include" -I"../../../../../src" -I"../../../../../ports/pic32/qk/xc32" -I"../.." -MMD -MF "${OBJECTDIR}/bsp.o.d" -o ${OBJECTDIR}/bsp.o bsp.c -DXPRJ_spy=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/43898991/blinky.o: ../../blinky.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/43898991" - @${RM} ${OBJECTDIR}/_ext/43898991/blinky.o.d - @${RM} ${OBJECTDIR}/_ext/43898991/blinky.o - @${FIXDEPS} "${OBJECTDIR}/_ext/43898991/blinky.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -DQ_SPY -I"../../../../../include" -I"../../../../../src" -I"../../../../../ports/pic32/qk/xc32" -I"../.." -MMD -MF "${OBJECTDIR}/_ext/43898991/blinky.o.d" -o ${OBJECTDIR}/_ext/43898991/blinky.o ../../blinky.c -DXPRJ_spy=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/43898991/main.o: ../../main.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/43898991" - @${RM} ${OBJECTDIR}/_ext/43898991/main.o.d - @${RM} ${OBJECTDIR}/_ext/43898991/main.o - @${FIXDEPS} "${OBJECTDIR}/_ext/43898991/main.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -DQ_SPY -I"../../../../../include" -I"../../../../../src" -I"../../../../../ports/pic32/qk/xc32" -I"../.." -MMD -MF "${OBJECTDIR}/_ext/43898991/main.o.d" -o ${OBJECTDIR}/_ext/43898991/main.o ../../main.c -DXPRJ_spy=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/726959463/qstamp.o: ../../../../../include/qstamp.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/726959463" - @${RM} ${OBJECTDIR}/_ext/726959463/qstamp.o.d - @${RM} ${OBJECTDIR}/_ext/726959463/qstamp.o - @${FIXDEPS} "${OBJECTDIR}/_ext/726959463/qstamp.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -DQ_SPY -I"../../../../../include" -I"../../../../../src" -I"../../../../../ports/pic32/qk/xc32" -I"../.." -MMD -MF "${OBJECTDIR}/_ext/726959463/qstamp.o.d" -o ${OBJECTDIR}/_ext/726959463/qstamp.o ../../../../../include/qstamp.c -DXPRJ_spy=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -endif - -# ------------------------------------------------------------------------------------ -# Rules for buildStep: compileCPP -ifeq ($(TYPE_IMAGE), DEBUG_RUN) -else -endif - -# ------------------------------------------------------------------------------------ -# Rules for buildStep: link -ifeq ($(TYPE_IMAGE), DEBUG_RUN) -dist/${CND_CONF}/${IMAGE_TYPE}/xc32.${IMAGE_TYPE}.${OUTPUT_SUFFIX}: ${OBJECTFILES} nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} dist/${CND_CONF}/${IMAGE_TYPE} - ${MP_CC} $(MP_EXTRA_LD_PRE) -g -mdebugger -D__MPLAB_DEBUGGER_PK3=1 -mprocessor=$(MP_PROCESSOR_OPTION) -o dist/${CND_CONF}/${IMAGE_TYPE}/xc32.${IMAGE_TYPE}.${OUTPUT_SUFFIX} ${OBJECTFILES_QUOTED_IF_SPACED} -DXPRJ_spy=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -mreserve=data@0x0:0x1FC -mreserve=boot@0x1FC00490:0x1FC00BEF -Wl,--defsym=__MPLAB_BUILD=1$(MP_EXTRA_LD_POST)$(MP_LINKER_FILE_OPTION),--defsym=__MPLAB_DEBUG=1,--defsym=__DEBUG=1,-D=__DEBUG_D,--defsym=__MPLAB_DEBUGGER_PK3=1,--defsym=_min_heap_size=0,--no-code-in-dinit,--no-dinit-in-serial-mem,--report-mem,--warn-section-align,--memorysummary,dist/${CND_CONF}/${IMAGE_TYPE}/memoryfile.xml - -else -dist/${CND_CONF}/${IMAGE_TYPE}/xc32.${IMAGE_TYPE}.${OUTPUT_SUFFIX}: ${OBJECTFILES} nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} dist/${CND_CONF}/${IMAGE_TYPE} - ${MP_CC} $(MP_EXTRA_LD_PRE) -mprocessor=$(MP_PROCESSOR_OPTION) -o dist/${CND_CONF}/${IMAGE_TYPE}/xc32.${IMAGE_TYPE}.${DEBUGGABLE_SUFFIX} ${OBJECTFILES_QUOTED_IF_SPACED} -DXPRJ_spy=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -Wl,--defsym=__MPLAB_BUILD=1$(MP_EXTRA_LD_POST)$(MP_LINKER_FILE_OPTION),--defsym=_min_heap_size=0,--no-code-in-dinit,--no-dinit-in-serial-mem,--report-mem,--warn-section-align,--memorysummary,dist/${CND_CONF}/${IMAGE_TYPE}/memoryfile.xml - ${MP_CC_DIR}\\xc32-bin2hex dist/${CND_CONF}/${IMAGE_TYPE}/xc32.${IMAGE_TYPE}.${DEBUGGABLE_SUFFIX} -endif - - -# Subprojects -.build-subprojects: - - -# Subprojects -.clean-subprojects: - -# Clean Targets -.clean-conf: ${CLEAN_SUBPROJECTS} - ${RM} -r build/spy - ${RM} -r dist/spy - -# Enable dependency checking -.dep.inc: .depcheck-impl - -DEPFILES=$(shell mplabwildcard ${POSSIBLE_DEPFILES}) -ifneq (${DEPFILES},) -include ${DEPFILES} -endif diff --git a/examples/pic32/blinky_microstick2-pic32/qk/xc32/nbproject/Makefile-variables.mk b/examples/pic32/blinky_microstick2-pic32/qk/xc32/nbproject/Makefile-variables.mk deleted file mode 100644 index 5a1eb7fc..00000000 --- a/examples/pic32/blinky_microstick2-pic32/qk/xc32/nbproject/Makefile-variables.mk +++ /dev/null @@ -1,27 +0,0 @@ -# -# Generated - do not edit! -# -# NOCDDL -# -CND_BASEDIR=`pwd` -# dbg configuration -CND_ARTIFACT_DIR_dbg=dist/dbg/production -CND_ARTIFACT_NAME_dbg=xc32.production.hex -CND_ARTIFACT_PATH_dbg=dist/dbg/production/xc32.production.hex -CND_PACKAGE_DIR_dbg=${CND_DISTDIR}/dbg/package -CND_PACKAGE_NAME_dbg=xc32.tar -CND_PACKAGE_PATH_dbg=${CND_DISTDIR}/dbg/package/xc32.tar -# rel configuration -CND_ARTIFACT_DIR_rel=dist/rel/production -CND_ARTIFACT_NAME_rel=xc32.production.hex -CND_ARTIFACT_PATH_rel=dist/rel/production/xc32.production.hex -CND_PACKAGE_DIR_rel=${CND_DISTDIR}/rel/package -CND_PACKAGE_NAME_rel=xc32.tar -CND_PACKAGE_PATH_rel=${CND_DISTDIR}/rel/package/xc32.tar -# spy configuration -CND_ARTIFACT_DIR_spy=dist/spy/production -CND_ARTIFACT_NAME_spy=xc32.production.hex -CND_ARTIFACT_PATH_spy=dist/spy/production/xc32.production.hex -CND_PACKAGE_DIR_spy=${CND_DISTDIR}/spy/package -CND_PACKAGE_NAME_spy=xc32.tar -CND_PACKAGE_PATH_spy=${CND_DISTDIR}/spy/package/xc32.tar diff --git a/examples/pic32/blinky_microstick2-pic32/qk/xc32/nbproject/Package-dbg.bash b/examples/pic32/blinky_microstick2-pic32/qk/xc32/nbproject/Package-dbg.bash deleted file mode 100644 index 29e2d1aa..00000000 --- a/examples/pic32/blinky_microstick2-pic32/qk/xc32/nbproject/Package-dbg.bash +++ /dev/null @@ -1,73 +0,0 @@ -#!/bin/bash -x - -# -# Generated - do not edit! -# - -# Macros -TOP=`pwd` -CND_CONF=dbg -CND_DISTDIR=dist -TMPDIR=build/${CND_CONF}/${IMAGE_TYPE}/tmp-packaging -TMPDIRNAME=tmp-packaging -OUTPUT_PATH=dist/${CND_CONF}/${IMAGE_TYPE}/xc32.${IMAGE_TYPE}.${OUTPUT_SUFFIX} -OUTPUT_BASENAME=xc32.${IMAGE_TYPE}.${OUTPUT_SUFFIX} -PACKAGE_TOP_DIR=xc32/ - -# Functions -function checkReturnCode -{ - rc=$? - if [ $rc != 0 ] - then - exit $rc - fi -} -function makeDirectory -# $1 directory path -# $2 permission (optional) -{ - mkdir -p "$1" - checkReturnCode - if [ "$2" != "" ] - then - chmod $2 "$1" - checkReturnCode - fi -} -function copyFileToTmpDir -# $1 from-file path -# $2 to-file path -# $3 permission -{ - cp "$1" "$2" - checkReturnCode - if [ "$3" != "" ] - then - chmod $3 "$2" - checkReturnCode - fi -} - -# Setup -cd "${TOP}" -mkdir -p ${CND_DISTDIR}/${CND_CONF}/package -rm -rf ${TMPDIR} -mkdir -p ${TMPDIR} - -# Copy files and create directories and links -cd "${TOP}" -makeDirectory ${TMPDIR}/xc32/bin -copyFileToTmpDir "${OUTPUT_PATH}" "${TMPDIR}/${PACKAGE_TOP_DIR}bin/${OUTPUT_BASENAME}" 0755 - - -# Generate tar file -cd "${TOP}" -rm -f ${CND_DISTDIR}/${CND_CONF}/package/xc32.tar -cd ${TMPDIR} -tar -vcf ../../../../${CND_DISTDIR}/${CND_CONF}/package/xc32.tar * -checkReturnCode - -# Cleanup -cd "${TOP}" -rm -rf ${TMPDIR} diff --git a/examples/pic32/blinky_microstick2-pic32/qk/xc32/nbproject/Package-rel.bash b/examples/pic32/blinky_microstick2-pic32/qk/xc32/nbproject/Package-rel.bash deleted file mode 100644 index 8e0fe709..00000000 --- a/examples/pic32/blinky_microstick2-pic32/qk/xc32/nbproject/Package-rel.bash +++ /dev/null @@ -1,73 +0,0 @@ -#!/bin/bash -x - -# -# Generated - do not edit! -# - -# Macros -TOP=`pwd` -CND_CONF=rel -CND_DISTDIR=dist -TMPDIR=build/${CND_CONF}/${IMAGE_TYPE}/tmp-packaging -TMPDIRNAME=tmp-packaging -OUTPUT_PATH=dist/${CND_CONF}/${IMAGE_TYPE}/xc32.${IMAGE_TYPE}.${OUTPUT_SUFFIX} -OUTPUT_BASENAME=xc32.${IMAGE_TYPE}.${OUTPUT_SUFFIX} -PACKAGE_TOP_DIR=xc32/ - -# Functions -function checkReturnCode -{ - rc=$? - if [ $rc != 0 ] - then - exit $rc - fi -} -function makeDirectory -# $1 directory path -# $2 permission (optional) -{ - mkdir -p "$1" - checkReturnCode - if [ "$2" != "" ] - then - chmod $2 "$1" - checkReturnCode - fi -} -function copyFileToTmpDir -# $1 from-file path -# $2 to-file path -# $3 permission -{ - cp "$1" "$2" - checkReturnCode - if [ "$3" != "" ] - then - chmod $3 "$2" - checkReturnCode - fi -} - -# Setup -cd "${TOP}" -mkdir -p ${CND_DISTDIR}/${CND_CONF}/package -rm -rf ${TMPDIR} -mkdir -p ${TMPDIR} - -# Copy files and create directories and links -cd "${TOP}" -makeDirectory ${TMPDIR}/xc32/bin -copyFileToTmpDir "${OUTPUT_PATH}" "${TMPDIR}/${PACKAGE_TOP_DIR}bin/${OUTPUT_BASENAME}" 0755 - - -# Generate tar file -cd "${TOP}" -rm -f ${CND_DISTDIR}/${CND_CONF}/package/xc32.tar -cd ${TMPDIR} -tar -vcf ../../../../${CND_DISTDIR}/${CND_CONF}/package/xc32.tar * -checkReturnCode - -# Cleanup -cd "${TOP}" -rm -rf ${TMPDIR} diff --git a/examples/pic32/blinky_microstick2-pic32/qk/xc32/nbproject/Package-spy.bash b/examples/pic32/blinky_microstick2-pic32/qk/xc32/nbproject/Package-spy.bash deleted file mode 100644 index e6524a8d..00000000 --- a/examples/pic32/blinky_microstick2-pic32/qk/xc32/nbproject/Package-spy.bash +++ /dev/null @@ -1,73 +0,0 @@ -#!/bin/bash -x - -# -# Generated - do not edit! -# - -# Macros -TOP=`pwd` -CND_CONF=spy -CND_DISTDIR=dist -TMPDIR=build/${CND_CONF}/${IMAGE_TYPE}/tmp-packaging -TMPDIRNAME=tmp-packaging -OUTPUT_PATH=dist/${CND_CONF}/${IMAGE_TYPE}/xc32.${IMAGE_TYPE}.${OUTPUT_SUFFIX} -OUTPUT_BASENAME=xc32.${IMAGE_TYPE}.${OUTPUT_SUFFIX} -PACKAGE_TOP_DIR=xc32/ - -# Functions -function checkReturnCode -{ - rc=$? - if [ $rc != 0 ] - then - exit $rc - fi -} -function makeDirectory -# $1 directory path -# $2 permission (optional) -{ - mkdir -p "$1" - checkReturnCode - if [ "$2" != "" ] - then - chmod $2 "$1" - checkReturnCode - fi -} -function copyFileToTmpDir -# $1 from-file path -# $2 to-file path -# $3 permission -{ - cp "$1" "$2" - checkReturnCode - if [ "$3" != "" ] - then - chmod $3 "$2" - checkReturnCode - fi -} - -# Setup -cd "${TOP}" -mkdir -p ${CND_DISTDIR}/${CND_CONF}/package -rm -rf ${TMPDIR} -mkdir -p ${TMPDIR} - -# Copy files and create directories and links -cd "${TOP}" -makeDirectory ${TMPDIR}/xc32/bin -copyFileToTmpDir "${OUTPUT_PATH}" "${TMPDIR}/${PACKAGE_TOP_DIR}bin/${OUTPUT_BASENAME}" 0755 - - -# Generate tar file -cd "${TOP}" -rm -f ${CND_DISTDIR}/${CND_CONF}/package/xc32.tar -cd ${TMPDIR} -tar -vcf ../../../../${CND_DISTDIR}/${CND_CONF}/package/xc32.tar * -checkReturnCode - -# Cleanup -cd "${TOP}" -rm -rf ${TMPDIR} diff --git a/examples/pic32/blinky_microstick2-pic32/qk/xc32/nbproject/configurations.xml b/examples/pic32/blinky_microstick2-pic32/qk/xc32/nbproject/configurations.xml deleted file mode 100644 index aeae7adc..00000000 --- a/examples/pic32/blinky_microstick2-pic32/qk/xc32/nbproject/configurations.xml +++ /dev/null @@ -1,759 +0,0 @@ - - - - - - - - - ../../../../../src/qf/qep_hsm.c - ../../../../../src/qf/qep_msm.c - ../../../../../src/qf/qf_act.c - ../../../../../src/qf/qf_actq.c - ../../../../../src/qf/qf_defer.c - ../../../../../src/qf/qf_dyn.c - ../../../../../src/qf/qf_mem.c - ../../../../../src/qf/qf_ps.c - ../../../../../src/qf/qf_qact.c - ../../../../../src/qf/qf_qeq.c - ../../../../../src/qf/qf_qmact.c - ../../../../../src/qf/qf_time.c - ../../../../../src/qk/qk.c - ../../../../../ports/pic32/qk/xc32/qk_port.c - - - ../../../../../src/qs/qs.c - ../../../../../src/qs/qs_64bit.c - ../../../../../src/qs/qs_fp.c - ../../../../../src/qs/qs_rx.c - - - bsp.c - ../../blinky.c - ../../blinky.h - ../../bsp.h - ../../main.c - ../../../../../include/qstamp.c - - - Makefile - - - - ../.. - ../../../../../src/qf - ../../../../../src/qv - ../../../../../include - ../../../../../src/qs - ../../../../../src/qk - ../../../../../ports/pic32/qk/xc32 - - Makefile - - - - localhost - PIC32MX250F128B - - - PKOBSKDEPlatformTool - XC32 - 2.20 - 3 - - - - - - - - - - - - - false - false - - - - - - - false - - false - - false - false - false - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - localhost - PIC32MX250F128B - - - PKOBSKDEPlatformTool - XC32 - 2.20 - 3 - - - - - - - - - - - - - false - false - - - - - - - false - - false - - false - false - false - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - localhost - PIC32MX250F128B - - - PKOBSKDEPlatformTool - XC32 - 2.20 - 3 - - - - - - - - - - - - - false - false - - - - - - - false - - false - - false - false - false - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/examples/pic32/blinky_microstick2-pic32/qk/xc32/nbproject/private/configurations.xml b/examples/pic32/blinky_microstick2-pic32/qk/xc32/nbproject/private/configurations.xml deleted file mode 100644 index 235f1d64..00000000 --- a/examples/pic32/blinky_microstick2-pic32/qk/xc32/nbproject/private/configurations.xml +++ /dev/null @@ -1,61 +0,0 @@ - - - Makefile - 0 - - - :=MPLABComm-USB-Microchip:=<vid>04D8:=<pid>8107:=<rev>0002:=<man>Microchip Technology Incorporated:=<prod>Microstick II SK:=<sn>BUR123045184:=<drv>x:=<xpt>h:=end - C:\tools\Microchip\xc32\bin - - place holder 1 - place holder 2 - - - - - true - 0 - 0 - 0 - - - - - - - C:\tools\Microchip\xc32\bin - - place holder 1 - place holder 2 - - - - - true - 0 - 0 - 0 - - - - - - :=MPLABCommUSB:=04D8:=8107:=0002:=Microchip Technology Incorporated:=Microstick II SK:=BUR123045184:=x:=en - C:\tools\Microchip\xc32\bin - - place holder 1 - place holder 2 - - - - - true - 0 - 0 - 0 - - - - - - diff --git a/examples/pic32/blinky_microstick2-pic32/qk/xc32/nbproject/private/private.properties b/examples/pic32/blinky_microstick2-pic32/qk/xc32/nbproject/private/private.properties deleted file mode 100644 index e69de29b..00000000 diff --git a/examples/pic32/blinky_microstick2-pic32/qk/xc32/nbproject/private/private.xml b/examples/pic32/blinky_microstick2-pic32/qk/xc32/nbproject/private/private.xml deleted file mode 100644 index cd3e03d7..00000000 --- a/examples/pic32/blinky_microstick2-pic32/qk/xc32/nbproject/private/private.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - diff --git a/examples/pic32/blinky_microstick2-pic32/qk/xc32/nbproject/project.properties b/examples/pic32/blinky_microstick2-pic32/qk/xc32/nbproject/project.properties deleted file mode 100644 index e69de29b..00000000 diff --git a/examples/pic32/blinky_microstick2-pic32/qk/xc32/nbproject/project.xml b/examples/pic32/blinky_microstick2-pic32/qk/xc32/nbproject/project.xml deleted file mode 100644 index 1651addf..00000000 --- a/examples/pic32/blinky_microstick2-pic32/qk/xc32/nbproject/project.xml +++ /dev/null @@ -1,43 +0,0 @@ - - - com.microchip.mplab.nbide.embedded.makeproject - - - blinky-microstick2-pic32-qk - e9bbb168-4146-4fa4-b2f4-357b75b20ee3 - 0 - c - - h - ISO-8859-1 - - - - ../.. - ../../../../../src/qf - ../../../../../src/qv - ../../../../../include - ../../../../../src/qs - ../../../../../src/qk - ../../../../../ports/pic32/qk/xc32 - - - - dbg - 2 - - - rel - 2 - - - spy - 2 - - - - false - - - - diff --git a/examples/pic32/blinky_microstick2-pic32/qv/xc32/Makefile b/examples/pic32/blinky_microstick2-pic32/qv/xc32/Makefile deleted file mode 100644 index 17647f99..00000000 --- a/examples/pic32/blinky_microstick2-pic32/qv/xc32/Makefile +++ /dev/null @@ -1,108 +0,0 @@ -# -# There exist several targets which are by default empty and which can be -# used for execution of your targets. These targets are usually executed -# before and after some main targets. They are: -# -# .build-pre: called before 'build' target -# .build-post: called after 'build' target -# .clean-pre: called before 'clean' target -# .clean-post: called after 'clean' target -# .clobber-pre: called before 'clobber' target -# .clobber-post: called after 'clobber' target -# .all-pre: called before 'all' target -# .all-post: called after 'all' target -# .help-pre: called before 'help' target -# .help-post: called after 'help' target -# -# Targets beginning with '.' are not intended to be called on their own. -# -# Main targets can be executed directly, and they are: -# -# build build a specific configuration -# clean remove built files from a configuration -# clobber remove all built files -# all build all configurations -# help print help mesage -# -# Targets .build-impl, .clean-impl, .clobber-impl, .all-impl, and -# .help-impl are implemented in nbproject/makefile-impl.mk. -# -# Available make variables: -# -# CND_BASEDIR base directory for relative paths -# CND_DISTDIR default top distribution directory (build artifacts) -# CND_BUILDDIR default top build directory (object files, ...) -# CONF name of current configuration -# CND_ARTIFACT_DIR_${CONF} directory of build artifact (current configuration) -# CND_ARTIFACT_NAME_${CONF} name of build artifact (current configuration) -# CND_ARTIFACT_PATH_${CONF} path to build artifact (current configuration) -# CND_PACKAGE_DIR_${CONF} directory of package (current configuration) -# CND_PACKAGE_NAME_${CONF} name of package (current configuration) -# CND_PACKAGE_PATH_${CONF} path to package (current configuration) -# -# NOCDDL - - -# Environment -MKDIR=mkdir -CP=cp -CCADMIN=CCadmin -RANLIB=ranlib - - -# build -build: .build-post - -.build-pre: -# Add your pre 'build' code here... - -.build-post: .build-impl -# Add your post 'build' code here... - - -# clean -clean: .clean-post - -.clean-pre: -# Add your pre 'clean' code here... - -.clean-post: .clean-impl -# Add your post 'clean' code here... - - -# clobber -clobber: .clobber-post - -.clobber-pre: -# Add your pre 'clobber' code here... - -.clobber-post: .clobber-impl -# Add your post 'clobber' code here... - - -# all -all: .all-post - -.all-pre: -# Add your pre 'all' code here... - -.all-post: .all-impl -# Add your post 'all' code here... - - -# help -help: .help-post - -.help-pre: -# Add your pre 'help' code here... - -.help-post: .help-impl -# Add your post 'help' code here... - - - -# include project implementation makefile -include nbproject/Makefile-impl.mk - -# include project make variables -include nbproject/Makefile-variables.mk diff --git a/examples/pic32/blinky_microstick2-pic32/qv/xc32/bsp.c b/examples/pic32/blinky_microstick2-pic32/qv/xc32/bsp.c deleted file mode 100644 index e40b01e7..00000000 --- a/examples/pic32/blinky_microstick2-pic32/qv/xc32/bsp.c +++ /dev/null @@ -1,165 +0,0 @@ -/***************************************************************************** -* BSP for Blinky example, Microstick II board, cooperative QV kernel, XC32 -* Last updated for version 6.5.1 -* Last updated on 2019-06-10 -* -* Q u a n t u m L e a P s -* ------------------------ -* Modern Embedded Software -* -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* -* -*****************************************************************************/ -#include "qpc.h" -#include "bsp.h" -#include "blinky.h" - -Q_DEFINE_THIS_FILE - -#ifdef Q_SPY - #error Simple Blinky Application does not provide Spy build configuration -#endif - -#pragma config FNOSC = FRCPLL /* 8 MHz */ -#pragma config FPLLIDIV = DIV_2 /* 4 MHz */ -#pragma config FPLLMUL = MUL_20 /* 80 MHz */ -#pragma config FPLLODIV = DIV_2 /* 40 MHz == FRC */ -#pragma config FWDTEN = OFF /* watchdog off */ -#pragma config FPBDIV = DIV_1 /* same peripheral clock */ - -/* #pragma config statements should precede project file includes */ -#include /* header for PIC32 device in use */ -#include - -/* system clock using FRC and PLL: 40 MHz */ -#define SYS_FREQ 40000000U -/* peripheral clock frequency */ -#define PER_HZ (SYS_FREQ / 1U) - -/* controlling the LED of Microstick II */ -#define LED_ON() (LATASET = (1U << 0)) -#define LED_OFF() (LATACLR = (1U << 0)) -#define LED_TOGGLE() (LATAINV = (1U << 0)) - -/* ISRs --------------------------------------------------------------------*/ -void __ISR(_TIMER_2_VECTOR, IPL4SOFT) tickISR(void) { - IFS0CLR = _IFS0_T2IF_MASK; /* clear the interrupt source */ - - QTIMEEVT_TICK_X(0U, (void *)0); /* handle armed time events at tick rate 0 */ -} -/*..........................................................................*/ -/* for testing interrupt nesting and active object preemption */ -void __ISR(_EXTERNAL_0_VECTOR, IPL6SOFT) testISR(void) { - static QEvt const tout_evt = { TIMEOUT_SIG, 0U, 0U }; - - IFS0CLR = _IFS0_INT0IF_MASK; /* clear the interrupt source */ - - QACTIVE_POST(AO_Blinky, &tout_evt, (void *)0); -} - -/*--------------------------------------------------------------------------*/ -void BSP_init(void) { - TRISA = 0x00; /* set LED pins as outputs */ - PORTA = 0x00; /* set LED drive state low */ -} -/*..........................................................................*/ -void BSP_terminate(int16_t result) { - (void)result; -} -/*..........................................................................*/ -void BSP_ledOff(void) { - LED_OFF(); -} -/*..........................................................................*/ -void BSP_ledOn(void) { - LED_ON(); -} -/*..........................................................................*/ -Q_NORETURN Q_onAssert(char const * const file, int_t const loc) { - (void)file; /* unused parameter */ - (void)loc; /* unused parameter */ - QF_INT_DISABLE(); /* make sure that interrupts are disabled */ - for (;;) { - } -} - -/*..........................................................................*/ -void QF_onStartup(void) { /* entered with interrupts locked */ - INTCONSET = _INTCON_MVEC_MASK; /* configure multi-vectored interrupts */ - - T2CON = 0x0060; /* stop timer, set up for 1:64 prescaler */ - TMR2 = 0; /* count from zero up to the period */ - PR2 = SYS_FREQ / (BSP_TICKS_PER_SEC * 64); /* set the Timer2 period */ - IFS0CLR = _IFS0_T2IF_MASK; /* clear Timer2 Interrupt Flag */ - IEC0SET = _IEC0_T2IE_MASK; /* enable Timer2 interrupt */ - T2CONSET = _T2CON_ON_MASK; /* Start Timer2 */ - - INTCONbits.INT0EP = 1; /* INT0 interrupt on positive edge */ - IEC0SET = _IEC0_INT0IE_MASK; /* enable INT0 interrupt */ - IFS0CLR = _IFS0_INT0IF_MASK; /* clear the interrupt for INT0 */ - - /* explicitly assign priorities to all interrupts... */ - /* NOTE: must match the IPLxSOFT settings in the __ISR() macros */ - IPC2bits.T2IP = 4; /* Timer2 interrupt priority, must match tickISR */ - IPC0bits.INT0IP = 6; /* set INT0 priority; must match IPL in testISR */ -} -/*..........................................................................*/ -void QF_onCleanup(void) { -} -/*..........................................................................*/ -void QV_onIdle(void) { /* entered with interrupts DISABLED, see NOTE01 */ - - /* NOTE: not enough LEDs on the Microstick II board to implement - * the idle loop activity indicator ... - */ - //LED_ON (); /* blink the IDLE LED, see NOTE01 */ - //LED_OFF(); - -#ifdef NDEBUG - INTCONbits.TPC = 7; /* enable the Proximity Timer for all IPLs, NOTE01 */ - IPTMR = 4; /* set the proximity timer to 4 CPU clocks */ - QF_INT_ENABLE(); /* enable CPU interrupts */ - _wait(); /* execute the WAIT instruction to stop the CPU */ - INTCONbits.TPC = 0; /* disable the Proximity Timer for all IPLs */ -#else - QF_INT_ENABLE(); /* enable interrupts, see NOTE01 */ -#endif -} -/***************************************************************************** -* NOTE01: -* The callback function QV_onIdle() is called with interrupts disabled, -* because the idle condition can be invalidated by any enabled interrupt -* that would post events. The QV_onIdle() function *must* re-enable interrupts - internally -* -* NOTE02: -* The Temporal Proximity Timer is used to prevent a race condition of -* servicing an interrupt after re-enabling interrupts and before executing -* the WAIT instruction. The Proximity Timer is enabled for all interrupt -* priority levels (see QF_onStartup()). The Proximity Timer is set to 4 -* CPU clocks right before re-enabling interrupts (with the DI instruction) -* The 4 clock ticks should be enough to execute the (DI,WAIT) instruction -* pair _atomically_. -*/ - diff --git a/examples/pic32/blinky_microstick2-pic32/qv/xc32/nbproject/Makefile-dbg.mk b/examples/pic32/blinky_microstick2-pic32/qv/xc32/nbproject/Makefile-dbg.mk deleted file mode 100644 index 14aef04d..00000000 --- a/examples/pic32/blinky_microstick2-pic32/qv/xc32/nbproject/Makefile-dbg.mk +++ /dev/null @@ -1,355 +0,0 @@ -# -# Generated Makefile - do not edit! -# -# Edit the Makefile in the project folder instead (../Makefile). Each target -# has a -pre and a -post target defined where you can add customized code. -# -# This makefile implements configuration specific macros and targets. - - -# Include project Makefile -ifeq "${IGNORE_LOCAL}" "TRUE" -# do not include local makefile. User is passing all local related variables already -else -include Makefile -# Include makefile containing local settings -ifeq "$(wildcard nbproject/Makefile-local-dbg.mk)" "nbproject/Makefile-local-dbg.mk" -include nbproject/Makefile-local-dbg.mk -endif -endif - -# Environment -MKDIR=gnumkdir -p -RM=rm -f -MV=mv -CP=cp - -# Macros -CND_CONF=dbg -ifeq ($(TYPE_IMAGE), DEBUG_RUN) -IMAGE_TYPE=debug -OUTPUT_SUFFIX=elf -DEBUGGABLE_SUFFIX=elf -FINAL_IMAGE=dist/${CND_CONF}/${IMAGE_TYPE}/xc32.${IMAGE_TYPE}.${OUTPUT_SUFFIX} -else -IMAGE_TYPE=production -OUTPUT_SUFFIX=hex -DEBUGGABLE_SUFFIX=elf -FINAL_IMAGE=dist/${CND_CONF}/${IMAGE_TYPE}/xc32.${IMAGE_TYPE}.${OUTPUT_SUFFIX} -endif - -ifeq ($(COMPARE_BUILD), true) -COMPARISON_BUILD=-mafrlcsj -else -COMPARISON_BUILD= -endif - -ifdef SUB_IMAGE_ADDRESS - -else -SUB_IMAGE_ADDRESS_COMMAND= -endif - -# Object Directory -OBJECTDIR=build/${CND_CONF}/${IMAGE_TYPE} - -# Distribution Directory -DISTDIR=dist/${CND_CONF}/${IMAGE_TYPE} - -# Source Files Quoted if spaced -SOURCEFILES_QUOTED_IF_SPACED=../../../../../src/qf/qep_hsm.c ../../../../../src/qf/qep_msm.c ../../../../../src/qf/qf_act.c ../../../../../src/qf/qf_actq.c ../../../../../src/qf/qf_defer.c ../../../../../src/qf/qf_dyn.c ../../../../../src/qf/qf_mem.c ../../../../../src/qf/qf_ps.c ../../../../../src/qf/qf_qact.c ../../../../../src/qf/qf_qeq.c ../../../../../src/qf/qf_qmact.c ../../../../../src/qf/qf_time.c ../../../../../src/qv/qv.c bsp.c ../../blinky.c ../../main.c ../../../../../include/qstamp.c - -# Object Files Quoted if spaced -OBJECTFILES_QUOTED_IF_SPACED=${OBJECTDIR}/_ext/820665871/qep_hsm.o ${OBJECTDIR}/_ext/820665871/qep_msm.o ${OBJECTDIR}/_ext/820665871/qf_act.o ${OBJECTDIR}/_ext/820665871/qf_actq.o ${OBJECTDIR}/_ext/820665871/qf_defer.o ${OBJECTDIR}/_ext/820665871/qf_dyn.o ${OBJECTDIR}/_ext/820665871/qf_mem.o ${OBJECTDIR}/_ext/820665871/qf_ps.o ${OBJECTDIR}/_ext/820665871/qf_qact.o ${OBJECTDIR}/_ext/820665871/qf_qeq.o ${OBJECTDIR}/_ext/820665871/qf_qmact.o ${OBJECTDIR}/_ext/820665871/qf_time.o ${OBJECTDIR}/_ext/820665887/qv.o ${OBJECTDIR}/bsp.o ${OBJECTDIR}/_ext/43898991/blinky.o ${OBJECTDIR}/_ext/43898991/main.o ${OBJECTDIR}/_ext/726959463/qstamp.o -POSSIBLE_DEPFILES=${OBJECTDIR}/_ext/820665871/qep_hsm.o.d ${OBJECTDIR}/_ext/820665871/qep_msm.o.d ${OBJECTDIR}/_ext/820665871/qf_act.o.d ${OBJECTDIR}/_ext/820665871/qf_actq.o.d ${OBJECTDIR}/_ext/820665871/qf_defer.o.d ${OBJECTDIR}/_ext/820665871/qf_dyn.o.d ${OBJECTDIR}/_ext/820665871/qf_mem.o.d ${OBJECTDIR}/_ext/820665871/qf_ps.o.d ${OBJECTDIR}/_ext/820665871/qf_qact.o.d ${OBJECTDIR}/_ext/820665871/qf_qeq.o.d ${OBJECTDIR}/_ext/820665871/qf_qmact.o.d ${OBJECTDIR}/_ext/820665871/qf_time.o.d ${OBJECTDIR}/_ext/820665887/qv.o.d ${OBJECTDIR}/bsp.o.d ${OBJECTDIR}/_ext/43898991/blinky.o.d ${OBJECTDIR}/_ext/43898991/main.o.d ${OBJECTDIR}/_ext/726959463/qstamp.o.d - -# Object Files -OBJECTFILES=${OBJECTDIR}/_ext/820665871/qep_hsm.o ${OBJECTDIR}/_ext/820665871/qep_msm.o ${OBJECTDIR}/_ext/820665871/qf_act.o ${OBJECTDIR}/_ext/820665871/qf_actq.o ${OBJECTDIR}/_ext/820665871/qf_defer.o ${OBJECTDIR}/_ext/820665871/qf_dyn.o ${OBJECTDIR}/_ext/820665871/qf_mem.o ${OBJECTDIR}/_ext/820665871/qf_ps.o ${OBJECTDIR}/_ext/820665871/qf_qact.o ${OBJECTDIR}/_ext/820665871/qf_qeq.o ${OBJECTDIR}/_ext/820665871/qf_qmact.o ${OBJECTDIR}/_ext/820665871/qf_time.o ${OBJECTDIR}/_ext/820665887/qv.o ${OBJECTDIR}/bsp.o ${OBJECTDIR}/_ext/43898991/blinky.o ${OBJECTDIR}/_ext/43898991/main.o ${OBJECTDIR}/_ext/726959463/qstamp.o - -# Source Files -SOURCEFILES=../../../../../src/qf/qep_hsm.c ../../../../../src/qf/qep_msm.c ../../../../../src/qf/qf_act.c ../../../../../src/qf/qf_actq.c ../../../../../src/qf/qf_defer.c ../../../../../src/qf/qf_dyn.c ../../../../../src/qf/qf_mem.c ../../../../../src/qf/qf_ps.c ../../../../../src/qf/qf_qact.c ../../../../../src/qf/qf_qeq.c ../../../../../src/qf/qf_qmact.c ../../../../../src/qf/qf_time.c ../../../../../src/qv/qv.c bsp.c ../../blinky.c ../../main.c ../../../../../include/qstamp.c - - -CFLAGS= -ASFLAGS= -LDLIBSOPTIONS= - -############# Tool locations ########################################## -# If you copy a project from one host to another, the path where the # -# compiler is installed may be different. # -# If you open this project with MPLAB X in the new host, this # -# makefile will be regenerated and the paths will be corrected. # -####################################################################### -# fixDeps replaces a bunch of sed/cat/printf statements that slow down the build -FIXDEPS=fixDeps - -.build-conf: ${BUILD_SUBPROJECTS} -ifneq ($(INFORMATION_MESSAGE), ) - @echo $(INFORMATION_MESSAGE) -endif - ${MAKE} -f nbproject/Makefile-dbg.mk dist/${CND_CONF}/${IMAGE_TYPE}/xc32.${IMAGE_TYPE}.${OUTPUT_SUFFIX} - -MP_PROCESSOR_OPTION=32MX250F128B -MP_LINKER_FILE_OPTION= -# ------------------------------------------------------------------------------------ -# Rules for buildStep: assemble -ifeq ($(TYPE_IMAGE), DEBUG_RUN) -else -endif - -# ------------------------------------------------------------------------------------ -# Rules for buildStep: assembleWithPreprocess -ifeq ($(TYPE_IMAGE), DEBUG_RUN) -else -endif - -# ------------------------------------------------------------------------------------ -# Rules for buildStep: compile -ifeq ($(TYPE_IMAGE), DEBUG_RUN) -${OBJECTDIR}/_ext/820665871/qep_hsm.o: ../../../../../src/qf/qep_hsm.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/820665871" - @${RM} ${OBJECTDIR}/_ext/820665871/qep_hsm.o.d - @${RM} ${OBJECTDIR}/_ext/820665871/qep_hsm.o - @${FIXDEPS} "${OBJECTDIR}/_ext/820665871/qep_hsm.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -D__DEBUG -D__MPLAB_DEBUGGER_PK3=1 -fframe-base-loclist -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -I"../.." -I"../../../../../src" -I"../../../../../include" -I"../../../../../ports/pic32/qv/xc32" -MMD -MF "${OBJECTDIR}/_ext/820665871/qep_hsm.o.d" -o ${OBJECTDIR}/_ext/820665871/qep_hsm.o ../../../../../src/qf/qep_hsm.c -DXPRJ_dbg=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/820665871/qep_msm.o: ../../../../../src/qf/qep_msm.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/820665871" - @${RM} ${OBJECTDIR}/_ext/820665871/qep_msm.o.d - @${RM} ${OBJECTDIR}/_ext/820665871/qep_msm.o - @${FIXDEPS} "${OBJECTDIR}/_ext/820665871/qep_msm.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -D__DEBUG -D__MPLAB_DEBUGGER_PK3=1 -fframe-base-loclist -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -I"../.." -I"../../../../../src" -I"../../../../../include" -I"../../../../../ports/pic32/qv/xc32" -MMD -MF "${OBJECTDIR}/_ext/820665871/qep_msm.o.d" -o ${OBJECTDIR}/_ext/820665871/qep_msm.o ../../../../../src/qf/qep_msm.c -DXPRJ_dbg=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/820665871/qf_act.o: ../../../../../src/qf/qf_act.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/820665871" - @${RM} ${OBJECTDIR}/_ext/820665871/qf_act.o.d - @${RM} ${OBJECTDIR}/_ext/820665871/qf_act.o - @${FIXDEPS} "${OBJECTDIR}/_ext/820665871/qf_act.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -D__DEBUG -D__MPLAB_DEBUGGER_PK3=1 -fframe-base-loclist -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -I"../.." -I"../../../../../src" -I"../../../../../include" -I"../../../../../ports/pic32/qv/xc32" -MMD -MF "${OBJECTDIR}/_ext/820665871/qf_act.o.d" -o ${OBJECTDIR}/_ext/820665871/qf_act.o ../../../../../src/qf/qf_act.c -DXPRJ_dbg=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/820665871/qf_actq.o: ../../../../../src/qf/qf_actq.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/820665871" - @${RM} ${OBJECTDIR}/_ext/820665871/qf_actq.o.d - @${RM} ${OBJECTDIR}/_ext/820665871/qf_actq.o - @${FIXDEPS} "${OBJECTDIR}/_ext/820665871/qf_actq.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -D__DEBUG -D__MPLAB_DEBUGGER_PK3=1 -fframe-base-loclist -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -I"../.." -I"../../../../../src" -I"../../../../../include" -I"../../../../../ports/pic32/qv/xc32" -MMD -MF "${OBJECTDIR}/_ext/820665871/qf_actq.o.d" -o ${OBJECTDIR}/_ext/820665871/qf_actq.o ../../../../../src/qf/qf_actq.c -DXPRJ_dbg=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/820665871/qf_defer.o: ../../../../../src/qf/qf_defer.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/820665871" - @${RM} ${OBJECTDIR}/_ext/820665871/qf_defer.o.d - @${RM} ${OBJECTDIR}/_ext/820665871/qf_defer.o - @${FIXDEPS} "${OBJECTDIR}/_ext/820665871/qf_defer.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -D__DEBUG -D__MPLAB_DEBUGGER_PK3=1 -fframe-base-loclist -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -I"../.." -I"../../../../../src" -I"../../../../../include" -I"../../../../../ports/pic32/qv/xc32" -MMD -MF "${OBJECTDIR}/_ext/820665871/qf_defer.o.d" -o ${OBJECTDIR}/_ext/820665871/qf_defer.o ../../../../../src/qf/qf_defer.c -DXPRJ_dbg=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/820665871/qf_dyn.o: ../../../../../src/qf/qf_dyn.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/820665871" - @${RM} ${OBJECTDIR}/_ext/820665871/qf_dyn.o.d - @${RM} ${OBJECTDIR}/_ext/820665871/qf_dyn.o - @${FIXDEPS} "${OBJECTDIR}/_ext/820665871/qf_dyn.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -D__DEBUG -D__MPLAB_DEBUGGER_PK3=1 -fframe-base-loclist -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -I"../.." -I"../../../../../src" -I"../../../../../include" -I"../../../../../ports/pic32/qv/xc32" -MMD -MF "${OBJECTDIR}/_ext/820665871/qf_dyn.o.d" -o ${OBJECTDIR}/_ext/820665871/qf_dyn.o ../../../../../src/qf/qf_dyn.c -DXPRJ_dbg=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/820665871/qf_mem.o: ../../../../../src/qf/qf_mem.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/820665871" - @${RM} ${OBJECTDIR}/_ext/820665871/qf_mem.o.d - @${RM} ${OBJECTDIR}/_ext/820665871/qf_mem.o - @${FIXDEPS} "${OBJECTDIR}/_ext/820665871/qf_mem.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -D__DEBUG -D__MPLAB_DEBUGGER_PK3=1 -fframe-base-loclist -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -I"../.." -I"../../../../../src" -I"../../../../../include" -I"../../../../../ports/pic32/qv/xc32" -MMD -MF "${OBJECTDIR}/_ext/820665871/qf_mem.o.d" -o ${OBJECTDIR}/_ext/820665871/qf_mem.o ../../../../../src/qf/qf_mem.c -DXPRJ_dbg=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/820665871/qf_ps.o: ../../../../../src/qf/qf_ps.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/820665871" - @${RM} ${OBJECTDIR}/_ext/820665871/qf_ps.o.d - @${RM} ${OBJECTDIR}/_ext/820665871/qf_ps.o - @${FIXDEPS} "${OBJECTDIR}/_ext/820665871/qf_ps.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -D__DEBUG -D__MPLAB_DEBUGGER_PK3=1 -fframe-base-loclist -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -I"../.." -I"../../../../../src" -I"../../../../../include" -I"../../../../../ports/pic32/qv/xc32" -MMD -MF "${OBJECTDIR}/_ext/820665871/qf_ps.o.d" -o ${OBJECTDIR}/_ext/820665871/qf_ps.o ../../../../../src/qf/qf_ps.c -DXPRJ_dbg=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/820665871/qf_qact.o: ../../../../../src/qf/qf_qact.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/820665871" - @${RM} ${OBJECTDIR}/_ext/820665871/qf_qact.o.d - @${RM} ${OBJECTDIR}/_ext/820665871/qf_qact.o - @${FIXDEPS} "${OBJECTDIR}/_ext/820665871/qf_qact.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -D__DEBUG -D__MPLAB_DEBUGGER_PK3=1 -fframe-base-loclist -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -I"../.." -I"../../../../../src" -I"../../../../../include" -I"../../../../../ports/pic32/qv/xc32" -MMD -MF "${OBJECTDIR}/_ext/820665871/qf_qact.o.d" -o ${OBJECTDIR}/_ext/820665871/qf_qact.o ../../../../../src/qf/qf_qact.c -DXPRJ_dbg=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/820665871/qf_qeq.o: ../../../../../src/qf/qf_qeq.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/820665871" - @${RM} ${OBJECTDIR}/_ext/820665871/qf_qeq.o.d - @${RM} ${OBJECTDIR}/_ext/820665871/qf_qeq.o - @${FIXDEPS} "${OBJECTDIR}/_ext/820665871/qf_qeq.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -D__DEBUG -D__MPLAB_DEBUGGER_PK3=1 -fframe-base-loclist -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -I"../.." -I"../../../../../src" -I"../../../../../include" -I"../../../../../ports/pic32/qv/xc32" -MMD -MF "${OBJECTDIR}/_ext/820665871/qf_qeq.o.d" -o ${OBJECTDIR}/_ext/820665871/qf_qeq.o ../../../../../src/qf/qf_qeq.c -DXPRJ_dbg=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/820665871/qf_qmact.o: ../../../../../src/qf/qf_qmact.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/820665871" - @${RM} ${OBJECTDIR}/_ext/820665871/qf_qmact.o.d - @${RM} ${OBJECTDIR}/_ext/820665871/qf_qmact.o - @${FIXDEPS} "${OBJECTDIR}/_ext/820665871/qf_qmact.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -D__DEBUG -D__MPLAB_DEBUGGER_PK3=1 -fframe-base-loclist -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -I"../.." -I"../../../../../src" -I"../../../../../include" -I"../../../../../ports/pic32/qv/xc32" -MMD -MF "${OBJECTDIR}/_ext/820665871/qf_qmact.o.d" -o ${OBJECTDIR}/_ext/820665871/qf_qmact.o ../../../../../src/qf/qf_qmact.c -DXPRJ_dbg=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/820665871/qf_time.o: ../../../../../src/qf/qf_time.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/820665871" - @${RM} ${OBJECTDIR}/_ext/820665871/qf_time.o.d - @${RM} ${OBJECTDIR}/_ext/820665871/qf_time.o - @${FIXDEPS} "${OBJECTDIR}/_ext/820665871/qf_time.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -D__DEBUG -D__MPLAB_DEBUGGER_PK3=1 -fframe-base-loclist -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -I"../.." -I"../../../../../src" -I"../../../../../include" -I"../../../../../ports/pic32/qv/xc32" -MMD -MF "${OBJECTDIR}/_ext/820665871/qf_time.o.d" -o ${OBJECTDIR}/_ext/820665871/qf_time.o ../../../../../src/qf/qf_time.c -DXPRJ_dbg=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/820665887/qv.o: ../../../../../src/qv/qv.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/820665887" - @${RM} ${OBJECTDIR}/_ext/820665887/qv.o.d - @${RM} ${OBJECTDIR}/_ext/820665887/qv.o - @${FIXDEPS} "${OBJECTDIR}/_ext/820665887/qv.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -D__DEBUG -D__MPLAB_DEBUGGER_PK3=1 -fframe-base-loclist -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -I"../.." -I"../../../../../src" -I"../../../../../include" -I"../../../../../ports/pic32/qv/xc32" -MMD -MF "${OBJECTDIR}/_ext/820665887/qv.o.d" -o ${OBJECTDIR}/_ext/820665887/qv.o ../../../../../src/qv/qv.c -DXPRJ_dbg=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/bsp.o: bsp.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}" - @${RM} ${OBJECTDIR}/bsp.o.d - @${RM} ${OBJECTDIR}/bsp.o - @${FIXDEPS} "${OBJECTDIR}/bsp.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -D__DEBUG -D__MPLAB_DEBUGGER_PK3=1 -fframe-base-loclist -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -I"../.." -I"../../../../../src" -I"../../../../../include" -I"../../../../../ports/pic32/qv/xc32" -MMD -MF "${OBJECTDIR}/bsp.o.d" -o ${OBJECTDIR}/bsp.o bsp.c -DXPRJ_dbg=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/43898991/blinky.o: ../../blinky.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/43898991" - @${RM} ${OBJECTDIR}/_ext/43898991/blinky.o.d - @${RM} ${OBJECTDIR}/_ext/43898991/blinky.o - @${FIXDEPS} "${OBJECTDIR}/_ext/43898991/blinky.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -D__DEBUG -D__MPLAB_DEBUGGER_PK3=1 -fframe-base-loclist -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -I"../.." -I"../../../../../src" -I"../../../../../include" -I"../../../../../ports/pic32/qv/xc32" -MMD -MF "${OBJECTDIR}/_ext/43898991/blinky.o.d" -o ${OBJECTDIR}/_ext/43898991/blinky.o ../../blinky.c -DXPRJ_dbg=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/43898991/main.o: ../../main.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/43898991" - @${RM} ${OBJECTDIR}/_ext/43898991/main.o.d - @${RM} ${OBJECTDIR}/_ext/43898991/main.o - @${FIXDEPS} "${OBJECTDIR}/_ext/43898991/main.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -D__DEBUG -D__MPLAB_DEBUGGER_PK3=1 -fframe-base-loclist -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -I"../.." -I"../../../../../src" -I"../../../../../include" -I"../../../../../ports/pic32/qv/xc32" -MMD -MF "${OBJECTDIR}/_ext/43898991/main.o.d" -o ${OBJECTDIR}/_ext/43898991/main.o ../../main.c -DXPRJ_dbg=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/726959463/qstamp.o: ../../../../../include/qstamp.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/726959463" - @${RM} ${OBJECTDIR}/_ext/726959463/qstamp.o.d - @${RM} ${OBJECTDIR}/_ext/726959463/qstamp.o - @${FIXDEPS} "${OBJECTDIR}/_ext/726959463/qstamp.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -D__DEBUG -D__MPLAB_DEBUGGER_PK3=1 -fframe-base-loclist -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -I"../.." -I"../../../../../src" -I"../../../../../include" -I"../../../../../ports/pic32/qv/xc32" -MMD -MF "${OBJECTDIR}/_ext/726959463/qstamp.o.d" -o ${OBJECTDIR}/_ext/726959463/qstamp.o ../../../../../include/qstamp.c -DXPRJ_dbg=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -else -${OBJECTDIR}/_ext/820665871/qep_hsm.o: ../../../../../src/qf/qep_hsm.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/820665871" - @${RM} ${OBJECTDIR}/_ext/820665871/qep_hsm.o.d - @${RM} ${OBJECTDIR}/_ext/820665871/qep_hsm.o - @${FIXDEPS} "${OBJECTDIR}/_ext/820665871/qep_hsm.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -I"../.." -I"../../../../../src" -I"../../../../../include" -I"../../../../../ports/pic32/qv/xc32" -MMD -MF "${OBJECTDIR}/_ext/820665871/qep_hsm.o.d" -o ${OBJECTDIR}/_ext/820665871/qep_hsm.o ../../../../../src/qf/qep_hsm.c -DXPRJ_dbg=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/820665871/qep_msm.o: ../../../../../src/qf/qep_msm.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/820665871" - @${RM} ${OBJECTDIR}/_ext/820665871/qep_msm.o.d - @${RM} ${OBJECTDIR}/_ext/820665871/qep_msm.o - @${FIXDEPS} "${OBJECTDIR}/_ext/820665871/qep_msm.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -I"../.." -I"../../../../../src" -I"../../../../../include" -I"../../../../../ports/pic32/qv/xc32" -MMD -MF "${OBJECTDIR}/_ext/820665871/qep_msm.o.d" -o ${OBJECTDIR}/_ext/820665871/qep_msm.o ../../../../../src/qf/qep_msm.c -DXPRJ_dbg=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/820665871/qf_act.o: ../../../../../src/qf/qf_act.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/820665871" - @${RM} ${OBJECTDIR}/_ext/820665871/qf_act.o.d - @${RM} ${OBJECTDIR}/_ext/820665871/qf_act.o - @${FIXDEPS} "${OBJECTDIR}/_ext/820665871/qf_act.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -I"../.." -I"../../../../../src" -I"../../../../../include" -I"../../../../../ports/pic32/qv/xc32" -MMD -MF "${OBJECTDIR}/_ext/820665871/qf_act.o.d" -o ${OBJECTDIR}/_ext/820665871/qf_act.o ../../../../../src/qf/qf_act.c -DXPRJ_dbg=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/820665871/qf_actq.o: ../../../../../src/qf/qf_actq.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/820665871" - @${RM} ${OBJECTDIR}/_ext/820665871/qf_actq.o.d - @${RM} ${OBJECTDIR}/_ext/820665871/qf_actq.o - @${FIXDEPS} "${OBJECTDIR}/_ext/820665871/qf_actq.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -I"../.." -I"../../../../../src" -I"../../../../../include" -I"../../../../../ports/pic32/qv/xc32" -MMD -MF "${OBJECTDIR}/_ext/820665871/qf_actq.o.d" -o ${OBJECTDIR}/_ext/820665871/qf_actq.o ../../../../../src/qf/qf_actq.c -DXPRJ_dbg=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/820665871/qf_defer.o: ../../../../../src/qf/qf_defer.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/820665871" - @${RM} ${OBJECTDIR}/_ext/820665871/qf_defer.o.d - @${RM} ${OBJECTDIR}/_ext/820665871/qf_defer.o - @${FIXDEPS} "${OBJECTDIR}/_ext/820665871/qf_defer.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -I"../.." -I"../../../../../src" -I"../../../../../include" -I"../../../../../ports/pic32/qv/xc32" -MMD -MF "${OBJECTDIR}/_ext/820665871/qf_defer.o.d" -o ${OBJECTDIR}/_ext/820665871/qf_defer.o ../../../../../src/qf/qf_defer.c -DXPRJ_dbg=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/820665871/qf_dyn.o: ../../../../../src/qf/qf_dyn.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/820665871" - @${RM} ${OBJECTDIR}/_ext/820665871/qf_dyn.o.d - @${RM} ${OBJECTDIR}/_ext/820665871/qf_dyn.o - @${FIXDEPS} "${OBJECTDIR}/_ext/820665871/qf_dyn.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -I"../.." -I"../../../../../src" -I"../../../../../include" -I"../../../../../ports/pic32/qv/xc32" -MMD -MF "${OBJECTDIR}/_ext/820665871/qf_dyn.o.d" -o ${OBJECTDIR}/_ext/820665871/qf_dyn.o ../../../../../src/qf/qf_dyn.c -DXPRJ_dbg=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/820665871/qf_mem.o: ../../../../../src/qf/qf_mem.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/820665871" - @${RM} ${OBJECTDIR}/_ext/820665871/qf_mem.o.d - @${RM} ${OBJECTDIR}/_ext/820665871/qf_mem.o - @${FIXDEPS} "${OBJECTDIR}/_ext/820665871/qf_mem.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -I"../.." -I"../../../../../src" -I"../../../../../include" -I"../../../../../ports/pic32/qv/xc32" -MMD -MF "${OBJECTDIR}/_ext/820665871/qf_mem.o.d" -o ${OBJECTDIR}/_ext/820665871/qf_mem.o ../../../../../src/qf/qf_mem.c -DXPRJ_dbg=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/820665871/qf_ps.o: ../../../../../src/qf/qf_ps.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/820665871" - @${RM} ${OBJECTDIR}/_ext/820665871/qf_ps.o.d - @${RM} ${OBJECTDIR}/_ext/820665871/qf_ps.o - @${FIXDEPS} "${OBJECTDIR}/_ext/820665871/qf_ps.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -I"../.." -I"../../../../../src" -I"../../../../../include" -I"../../../../../ports/pic32/qv/xc32" -MMD -MF "${OBJECTDIR}/_ext/820665871/qf_ps.o.d" -o ${OBJECTDIR}/_ext/820665871/qf_ps.o ../../../../../src/qf/qf_ps.c -DXPRJ_dbg=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/820665871/qf_qact.o: ../../../../../src/qf/qf_qact.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/820665871" - @${RM} ${OBJECTDIR}/_ext/820665871/qf_qact.o.d - @${RM} ${OBJECTDIR}/_ext/820665871/qf_qact.o - @${FIXDEPS} "${OBJECTDIR}/_ext/820665871/qf_qact.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -I"../.." -I"../../../../../src" -I"../../../../../include" -I"../../../../../ports/pic32/qv/xc32" -MMD -MF "${OBJECTDIR}/_ext/820665871/qf_qact.o.d" -o ${OBJECTDIR}/_ext/820665871/qf_qact.o ../../../../../src/qf/qf_qact.c -DXPRJ_dbg=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/820665871/qf_qeq.o: ../../../../../src/qf/qf_qeq.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/820665871" - @${RM} ${OBJECTDIR}/_ext/820665871/qf_qeq.o.d - @${RM} ${OBJECTDIR}/_ext/820665871/qf_qeq.o - @${FIXDEPS} "${OBJECTDIR}/_ext/820665871/qf_qeq.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -I"../.." -I"../../../../../src" -I"../../../../../include" -I"../../../../../ports/pic32/qv/xc32" -MMD -MF "${OBJECTDIR}/_ext/820665871/qf_qeq.o.d" -o ${OBJECTDIR}/_ext/820665871/qf_qeq.o ../../../../../src/qf/qf_qeq.c -DXPRJ_dbg=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/820665871/qf_qmact.o: ../../../../../src/qf/qf_qmact.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/820665871" - @${RM} ${OBJECTDIR}/_ext/820665871/qf_qmact.o.d - @${RM} ${OBJECTDIR}/_ext/820665871/qf_qmact.o - @${FIXDEPS} "${OBJECTDIR}/_ext/820665871/qf_qmact.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -I"../.." -I"../../../../../src" -I"../../../../../include" -I"../../../../../ports/pic32/qv/xc32" -MMD -MF "${OBJECTDIR}/_ext/820665871/qf_qmact.o.d" -o ${OBJECTDIR}/_ext/820665871/qf_qmact.o ../../../../../src/qf/qf_qmact.c -DXPRJ_dbg=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/820665871/qf_time.o: ../../../../../src/qf/qf_time.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/820665871" - @${RM} ${OBJECTDIR}/_ext/820665871/qf_time.o.d - @${RM} ${OBJECTDIR}/_ext/820665871/qf_time.o - @${FIXDEPS} "${OBJECTDIR}/_ext/820665871/qf_time.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -I"../.." -I"../../../../../src" -I"../../../../../include" -I"../../../../../ports/pic32/qv/xc32" -MMD -MF "${OBJECTDIR}/_ext/820665871/qf_time.o.d" -o ${OBJECTDIR}/_ext/820665871/qf_time.o ../../../../../src/qf/qf_time.c -DXPRJ_dbg=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/820665887/qv.o: ../../../../../src/qv/qv.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/820665887" - @${RM} ${OBJECTDIR}/_ext/820665887/qv.o.d - @${RM} ${OBJECTDIR}/_ext/820665887/qv.o - @${FIXDEPS} "${OBJECTDIR}/_ext/820665887/qv.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -I"../.." -I"../../../../../src" -I"../../../../../include" -I"../../../../../ports/pic32/qv/xc32" -MMD -MF "${OBJECTDIR}/_ext/820665887/qv.o.d" -o ${OBJECTDIR}/_ext/820665887/qv.o ../../../../../src/qv/qv.c -DXPRJ_dbg=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/bsp.o: bsp.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}" - @${RM} ${OBJECTDIR}/bsp.o.d - @${RM} ${OBJECTDIR}/bsp.o - @${FIXDEPS} "${OBJECTDIR}/bsp.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -I"../.." -I"../../../../../src" -I"../../../../../include" -I"../../../../../ports/pic32/qv/xc32" -MMD -MF "${OBJECTDIR}/bsp.o.d" -o ${OBJECTDIR}/bsp.o bsp.c -DXPRJ_dbg=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/43898991/blinky.o: ../../blinky.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/43898991" - @${RM} ${OBJECTDIR}/_ext/43898991/blinky.o.d - @${RM} ${OBJECTDIR}/_ext/43898991/blinky.o - @${FIXDEPS} "${OBJECTDIR}/_ext/43898991/blinky.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -I"../.." -I"../../../../../src" -I"../../../../../include" -I"../../../../../ports/pic32/qv/xc32" -MMD -MF "${OBJECTDIR}/_ext/43898991/blinky.o.d" -o ${OBJECTDIR}/_ext/43898991/blinky.o ../../blinky.c -DXPRJ_dbg=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/43898991/main.o: ../../main.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/43898991" - @${RM} ${OBJECTDIR}/_ext/43898991/main.o.d - @${RM} ${OBJECTDIR}/_ext/43898991/main.o - @${FIXDEPS} "${OBJECTDIR}/_ext/43898991/main.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -I"../.." -I"../../../../../src" -I"../../../../../include" -I"../../../../../ports/pic32/qv/xc32" -MMD -MF "${OBJECTDIR}/_ext/43898991/main.o.d" -o ${OBJECTDIR}/_ext/43898991/main.o ../../main.c -DXPRJ_dbg=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/726959463/qstamp.o: ../../../../../include/qstamp.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/726959463" - @${RM} ${OBJECTDIR}/_ext/726959463/qstamp.o.d - @${RM} ${OBJECTDIR}/_ext/726959463/qstamp.o - @${FIXDEPS} "${OBJECTDIR}/_ext/726959463/qstamp.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -I"../.." -I"../../../../../src" -I"../../../../../include" -I"../../../../../ports/pic32/qv/xc32" -MMD -MF "${OBJECTDIR}/_ext/726959463/qstamp.o.d" -o ${OBJECTDIR}/_ext/726959463/qstamp.o ../../../../../include/qstamp.c -DXPRJ_dbg=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -endif - -# ------------------------------------------------------------------------------------ -# Rules for buildStep: compileCPP -ifeq ($(TYPE_IMAGE), DEBUG_RUN) -else -endif - -# ------------------------------------------------------------------------------------ -# Rules for buildStep: link -ifeq ($(TYPE_IMAGE), DEBUG_RUN) -dist/${CND_CONF}/${IMAGE_TYPE}/xc32.${IMAGE_TYPE}.${OUTPUT_SUFFIX}: ${OBJECTFILES} nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} dist/${CND_CONF}/${IMAGE_TYPE} - ${MP_CC} $(MP_EXTRA_LD_PRE) -g -mdebugger -D__MPLAB_DEBUGGER_PK3=1 -mprocessor=$(MP_PROCESSOR_OPTION) -o dist/${CND_CONF}/${IMAGE_TYPE}/xc32.${IMAGE_TYPE}.${OUTPUT_SUFFIX} ${OBJECTFILES_QUOTED_IF_SPACED} -DXPRJ_dbg=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -mreserve=data@0x0:0x1FC -mreserve=boot@0x1FC00490:0x1FC00BEF -Wl,--defsym=__MPLAB_BUILD=1$(MP_EXTRA_LD_POST)$(MP_LINKER_FILE_OPTION),--defsym=__MPLAB_DEBUG=1,--defsym=__DEBUG=1,-D=__DEBUG_D,--defsym=__MPLAB_DEBUGGER_PK3=1,--defsym=_min_heap_size=0,--no-code-in-dinit,--no-dinit-in-serial-mem,--report-mem,--warn-section-align,--memorysummary,dist/${CND_CONF}/${IMAGE_TYPE}/memoryfile.xml - -else -dist/${CND_CONF}/${IMAGE_TYPE}/xc32.${IMAGE_TYPE}.${OUTPUT_SUFFIX}: ${OBJECTFILES} nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} dist/${CND_CONF}/${IMAGE_TYPE} - ${MP_CC} $(MP_EXTRA_LD_PRE) -mprocessor=$(MP_PROCESSOR_OPTION) -o dist/${CND_CONF}/${IMAGE_TYPE}/xc32.${IMAGE_TYPE}.${DEBUGGABLE_SUFFIX} ${OBJECTFILES_QUOTED_IF_SPACED} -DXPRJ_dbg=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -Wl,--defsym=__MPLAB_BUILD=1$(MP_EXTRA_LD_POST)$(MP_LINKER_FILE_OPTION),--defsym=_min_heap_size=0,--no-code-in-dinit,--no-dinit-in-serial-mem,--report-mem,--warn-section-align,--memorysummary,dist/${CND_CONF}/${IMAGE_TYPE}/memoryfile.xml - ${MP_CC_DIR}\\xc32-bin2hex dist/${CND_CONF}/${IMAGE_TYPE}/xc32.${IMAGE_TYPE}.${DEBUGGABLE_SUFFIX} -endif - - -# Subprojects -.build-subprojects: - - -# Subprojects -.clean-subprojects: - -# Clean Targets -.clean-conf: ${CLEAN_SUBPROJECTS} - ${RM} -r build/dbg - ${RM} -r dist/dbg - -# Enable dependency checking -.dep.inc: .depcheck-impl - -DEPFILES=$(shell mplabwildcard ${POSSIBLE_DEPFILES}) -ifneq (${DEPFILES},) -include ${DEPFILES} -endif diff --git a/examples/pic32/blinky_microstick2-pic32/qv/xc32/nbproject/Makefile-genesis.properties b/examples/pic32/blinky_microstick2-pic32/qv/xc32/nbproject/Makefile-genesis.properties deleted file mode 100644 index 3a286ef6..00000000 --- a/examples/pic32/blinky_microstick2-pic32/qv/xc32/nbproject/Makefile-genesis.properties +++ /dev/null @@ -1,15 +0,0 @@ -# -#Sun Apr 03 16:58:04 EDT 2022 -rel.languagetoolchain.version=2.20 -spy.languagetoolchain.version=2.20 -conf.ids=dbg,rel,spy -spy.languagetoolchain.dir=C\:\\tools\\Microchip\\xc32\\bin -configurations-xml=10f9e955cf8596c41b2b4749e1eb4175 -dbg.languagetoolchain.version=2.20 -com-microchip-mplab-nbide-embedded-makeproject-MakeProject.md5=37eccb08230908d044ad3fe14e24ea9a -dbg.com-microchip-mplab-nbide-toolchainXC32-XC32LanguageToolchain.md5=af6fe09cc582a0daace7b80bb4f7bbe2 -spy.com-microchip-mplab-nbide-toolchainXC32-XC32LanguageToolchain.md5=af6fe09cc582a0daace7b80bb4f7bbe2 -rel.languagetoolchain.dir=C\:\\tools\\Microchip\\xc32\\bin -dbg.languagetoolchain.dir=C\:\\tools\\Microchip\\xc32\\bin -rel.com-microchip-mplab-nbide-toolchainXC32-XC32LanguageToolchain.md5=af6fe09cc582a0daace7b80bb4f7bbe2 -host.platform=windows diff --git a/examples/pic32/blinky_microstick2-pic32/qv/xc32/nbproject/Makefile-impl.mk b/examples/pic32/blinky_microstick2-pic32/qv/xc32/nbproject/Makefile-impl.mk deleted file mode 100644 index 45560f95..00000000 --- a/examples/pic32/blinky_microstick2-pic32/qv/xc32/nbproject/Makefile-impl.mk +++ /dev/null @@ -1,73 +0,0 @@ -# -# Generated Makefile - do not edit! -# -# Edit the Makefile in the project folder instead (../Makefile). Each target -# has a pre- and a post- target defined where you can add customization code. -# -# This makefile implements macros and targets common to all configurations. -# -# NOCDDL - - -# Building and Cleaning subprojects are done by default, but can be controlled with the SUB -# macro. If SUB=no, subprojects will not be built or cleaned. The following macro -# statements set BUILD_SUB-CONF and CLEAN_SUB-CONF to .build-reqprojects-conf -# and .clean-reqprojects-conf unless SUB has the value 'no' -SUB_no=NO -SUBPROJECTS=${SUB_${SUB}} -BUILD_SUBPROJECTS_=.build-subprojects -BUILD_SUBPROJECTS_NO= -BUILD_SUBPROJECTS=${BUILD_SUBPROJECTS_${SUBPROJECTS}} -CLEAN_SUBPROJECTS_=.clean-subprojects -CLEAN_SUBPROJECTS_NO= -CLEAN_SUBPROJECTS=${CLEAN_SUBPROJECTS_${SUBPROJECTS}} - - -# Project Name -PROJECTNAME=xc32 - -# Active Configuration -DEFAULTCONF=dbg -CONF=${DEFAULTCONF} - -# All Configurations -ALLCONFS=dbg rel spy - - -# build -.build-impl: .build-pre - ${MAKE} -f nbproject/Makefile-${CONF}.mk SUBPROJECTS=${SUBPROJECTS} .build-conf - - -# clean -.clean-impl: .clean-pre - ${MAKE} -f nbproject/Makefile-${CONF}.mk SUBPROJECTS=${SUBPROJECTS} .clean-conf - -# clobber -.clobber-impl: .clobber-pre .depcheck-impl - ${MAKE} SUBPROJECTS=${SUBPROJECTS} CONF=dbg clean - ${MAKE} SUBPROJECTS=${SUBPROJECTS} CONF=rel clean - ${MAKE} SUBPROJECTS=${SUBPROJECTS} CONF=spy clean - - - -# all -.all-impl: .all-pre .depcheck-impl - ${MAKE} SUBPROJECTS=${SUBPROJECTS} CONF=dbg build - ${MAKE} SUBPROJECTS=${SUBPROJECTS} CONF=rel build - ${MAKE} SUBPROJECTS=${SUBPROJECTS} CONF=spy build - - - -# dependency checking support -.depcheck-impl: -# @echo "# This code depends on make tool being used" >.dep.inc -# @if [ -n "${MAKE_VERSION}" ]; then \ -# echo "DEPFILES=\$$(wildcard \$$(addsuffix .d, \$${OBJECTFILES}))" >>.dep.inc; \ -# echo "ifneq (\$${DEPFILES},)" >>.dep.inc; \ -# echo "include \$${DEPFILES}" >>.dep.inc; \ -# echo "endif" >>.dep.inc; \ -# else \ -# echo ".KEEP_STATE:" >>.dep.inc; \ -# echo ".KEEP_STATE_FILE:.make.state.\$${CONF}" >>.dep.inc; \ -# fi diff --git a/examples/pic32/blinky_microstick2-pic32/qv/xc32/nbproject/Makefile-local-dbg.mk b/examples/pic32/blinky_microstick2-pic32/qv/xc32/nbproject/Makefile-local-dbg.mk deleted file mode 100644 index 24cf88be..00000000 --- a/examples/pic32/blinky_microstick2-pic32/qv/xc32/nbproject/Makefile-local-dbg.mk +++ /dev/null @@ -1,37 +0,0 @@ -# -# Generated Makefile - do not edit! -# -# -# This file contains information about the location of compilers and other tools. -# If you commmit this file into your revision control server, you will be able to -# to checkout the project and build it from the command line with make. However, -# if more than one person works on the same project, then this file might show -# conflicts since different users are bound to have compilers in different places. -# In that case you might choose to not commit this file and let MPLAB X recreate this file -# for each user. The disadvantage of not commiting this file is that you must run MPLAB X at -# least once so the file gets created and the project can be built. Finally, you can also -# avoid using this file at all if you are only building from the command line with make. -# You can invoke make with the values of the macros: -# $ makeMP_CC="/opt/microchip/mplabc30/v3.30c/bin/pic30-gcc" ... -# -SHELL=cmd.exe -PATH_TO_IDE_BIN=C:/tools/Microchip/MPLABX/mplab_platform/platform/../mplab_ide/modules/../../bin/ -# Adding MPLAB X bin directory to path. -PATH:=C:/tools/Microchip/MPLABX/mplab_platform/platform/../mplab_ide/modules/../../bin/:$(PATH) -# Path to java used to run MPLAB X when this makefile was created -MP_JAVA_PATH="C:\tools\Microchip\MPLABX\sys\java\jre1.8.0_181/bin/" -OS_CURRENT="$(shell uname -s)" -MP_CC="C:\tools\Microchip\xc32\bin\xc32-gcc.exe" -MP_CPPC="C:\tools\Microchip\xc32\bin\xc32-g++.exe" -# MP_BC is not defined -MP_AS="C:\tools\Microchip\xc32\bin\xc32-as.exe" -MP_LD="C:\tools\Microchip\xc32\bin\xc32-ld.exe" -MP_AR="C:\tools\Microchip\xc32\bin\xc32-ar.exe" -DEP_GEN=${MP_JAVA_PATH}java -jar "C:/tools/Microchip/MPLABX/mplab_platform/platform/../mplab_ide/modules/../../bin/extractobjectdependencies.jar" -MP_CC_DIR="C:\tools\Microchip\xc32\bin" -MP_CPPC_DIR="C:\tools\Microchip\xc32\bin" -# MP_BC_DIR is not defined -MP_AS_DIR="C:\tools\Microchip\xc32\bin" -MP_LD_DIR="C:\tools\Microchip\xc32\bin" -MP_AR_DIR="C:\tools\Microchip\xc32\bin" -# MP_BC_DIR is not defined diff --git a/examples/pic32/blinky_microstick2-pic32/qv/xc32/nbproject/Makefile-local-rel.mk b/examples/pic32/blinky_microstick2-pic32/qv/xc32/nbproject/Makefile-local-rel.mk deleted file mode 100644 index 24cf88be..00000000 --- a/examples/pic32/blinky_microstick2-pic32/qv/xc32/nbproject/Makefile-local-rel.mk +++ /dev/null @@ -1,37 +0,0 @@ -# -# Generated Makefile - do not edit! -# -# -# This file contains information about the location of compilers and other tools. -# If you commmit this file into your revision control server, you will be able to -# to checkout the project and build it from the command line with make. However, -# if more than one person works on the same project, then this file might show -# conflicts since different users are bound to have compilers in different places. -# In that case you might choose to not commit this file and let MPLAB X recreate this file -# for each user. The disadvantage of not commiting this file is that you must run MPLAB X at -# least once so the file gets created and the project can be built. Finally, you can also -# avoid using this file at all if you are only building from the command line with make. -# You can invoke make with the values of the macros: -# $ makeMP_CC="/opt/microchip/mplabc30/v3.30c/bin/pic30-gcc" ... -# -SHELL=cmd.exe -PATH_TO_IDE_BIN=C:/tools/Microchip/MPLABX/mplab_platform/platform/../mplab_ide/modules/../../bin/ -# Adding MPLAB X bin directory to path. -PATH:=C:/tools/Microchip/MPLABX/mplab_platform/platform/../mplab_ide/modules/../../bin/:$(PATH) -# Path to java used to run MPLAB X when this makefile was created -MP_JAVA_PATH="C:\tools\Microchip\MPLABX\sys\java\jre1.8.0_181/bin/" -OS_CURRENT="$(shell uname -s)" -MP_CC="C:\tools\Microchip\xc32\bin\xc32-gcc.exe" -MP_CPPC="C:\tools\Microchip\xc32\bin\xc32-g++.exe" -# MP_BC is not defined -MP_AS="C:\tools\Microchip\xc32\bin\xc32-as.exe" -MP_LD="C:\tools\Microchip\xc32\bin\xc32-ld.exe" -MP_AR="C:\tools\Microchip\xc32\bin\xc32-ar.exe" -DEP_GEN=${MP_JAVA_PATH}java -jar "C:/tools/Microchip/MPLABX/mplab_platform/platform/../mplab_ide/modules/../../bin/extractobjectdependencies.jar" -MP_CC_DIR="C:\tools\Microchip\xc32\bin" -MP_CPPC_DIR="C:\tools\Microchip\xc32\bin" -# MP_BC_DIR is not defined -MP_AS_DIR="C:\tools\Microchip\xc32\bin" -MP_LD_DIR="C:\tools\Microchip\xc32\bin" -MP_AR_DIR="C:\tools\Microchip\xc32\bin" -# MP_BC_DIR is not defined diff --git a/examples/pic32/blinky_microstick2-pic32/qv/xc32/nbproject/Makefile-local-spy.mk b/examples/pic32/blinky_microstick2-pic32/qv/xc32/nbproject/Makefile-local-spy.mk deleted file mode 100644 index 24cf88be..00000000 --- a/examples/pic32/blinky_microstick2-pic32/qv/xc32/nbproject/Makefile-local-spy.mk +++ /dev/null @@ -1,37 +0,0 @@ -# -# Generated Makefile - do not edit! -# -# -# This file contains information about the location of compilers and other tools. -# If you commmit this file into your revision control server, you will be able to -# to checkout the project and build it from the command line with make. However, -# if more than one person works on the same project, then this file might show -# conflicts since different users are bound to have compilers in different places. -# In that case you might choose to not commit this file and let MPLAB X recreate this file -# for each user. The disadvantage of not commiting this file is that you must run MPLAB X at -# least once so the file gets created and the project can be built. Finally, you can also -# avoid using this file at all if you are only building from the command line with make. -# You can invoke make with the values of the macros: -# $ makeMP_CC="/opt/microchip/mplabc30/v3.30c/bin/pic30-gcc" ... -# -SHELL=cmd.exe -PATH_TO_IDE_BIN=C:/tools/Microchip/MPLABX/mplab_platform/platform/../mplab_ide/modules/../../bin/ -# Adding MPLAB X bin directory to path. -PATH:=C:/tools/Microchip/MPLABX/mplab_platform/platform/../mplab_ide/modules/../../bin/:$(PATH) -# Path to java used to run MPLAB X when this makefile was created -MP_JAVA_PATH="C:\tools\Microchip\MPLABX\sys\java\jre1.8.0_181/bin/" -OS_CURRENT="$(shell uname -s)" -MP_CC="C:\tools\Microchip\xc32\bin\xc32-gcc.exe" -MP_CPPC="C:\tools\Microchip\xc32\bin\xc32-g++.exe" -# MP_BC is not defined -MP_AS="C:\tools\Microchip\xc32\bin\xc32-as.exe" -MP_LD="C:\tools\Microchip\xc32\bin\xc32-ld.exe" -MP_AR="C:\tools\Microchip\xc32\bin\xc32-ar.exe" -DEP_GEN=${MP_JAVA_PATH}java -jar "C:/tools/Microchip/MPLABX/mplab_platform/platform/../mplab_ide/modules/../../bin/extractobjectdependencies.jar" -MP_CC_DIR="C:\tools\Microchip\xc32\bin" -MP_CPPC_DIR="C:\tools\Microchip\xc32\bin" -# MP_BC_DIR is not defined -MP_AS_DIR="C:\tools\Microchip\xc32\bin" -MP_LD_DIR="C:\tools\Microchip\xc32\bin" -MP_AR_DIR="C:\tools\Microchip\xc32\bin" -# MP_BC_DIR is not defined diff --git a/examples/pic32/blinky_microstick2-pic32/qv/xc32/nbproject/Makefile-rel.mk b/examples/pic32/blinky_microstick2-pic32/qv/xc32/nbproject/Makefile-rel.mk deleted file mode 100644 index 0a25d59d..00000000 --- a/examples/pic32/blinky_microstick2-pic32/qv/xc32/nbproject/Makefile-rel.mk +++ /dev/null @@ -1,355 +0,0 @@ -# -# Generated Makefile - do not edit! -# -# Edit the Makefile in the project folder instead (../Makefile). Each target -# has a -pre and a -post target defined where you can add customized code. -# -# This makefile implements configuration specific macros and targets. - - -# Include project Makefile -ifeq "${IGNORE_LOCAL}" "TRUE" -# do not include local makefile. User is passing all local related variables already -else -include Makefile -# Include makefile containing local settings -ifeq "$(wildcard nbproject/Makefile-local-rel.mk)" "nbproject/Makefile-local-rel.mk" -include nbproject/Makefile-local-rel.mk -endif -endif - -# Environment -MKDIR=gnumkdir -p -RM=rm -f -MV=mv -CP=cp - -# Macros -CND_CONF=rel -ifeq ($(TYPE_IMAGE), DEBUG_RUN) -IMAGE_TYPE=debug -OUTPUT_SUFFIX=elf -DEBUGGABLE_SUFFIX=elf -FINAL_IMAGE=dist/${CND_CONF}/${IMAGE_TYPE}/xc32.${IMAGE_TYPE}.${OUTPUT_SUFFIX} -else -IMAGE_TYPE=production -OUTPUT_SUFFIX=hex -DEBUGGABLE_SUFFIX=elf -FINAL_IMAGE=dist/${CND_CONF}/${IMAGE_TYPE}/xc32.${IMAGE_TYPE}.${OUTPUT_SUFFIX} -endif - -ifeq ($(COMPARE_BUILD), true) -COMPARISON_BUILD=-mafrlcsj -else -COMPARISON_BUILD= -endif - -ifdef SUB_IMAGE_ADDRESS - -else -SUB_IMAGE_ADDRESS_COMMAND= -endif - -# Object Directory -OBJECTDIR=build/${CND_CONF}/${IMAGE_TYPE} - -# Distribution Directory -DISTDIR=dist/${CND_CONF}/${IMAGE_TYPE} - -# Source Files Quoted if spaced -SOURCEFILES_QUOTED_IF_SPACED=../../../../../src/qf/qep_hsm.c ../../../../../src/qf/qep_msm.c ../../../../../src/qf/qf_act.c ../../../../../src/qf/qf_actq.c ../../../../../src/qf/qf_defer.c ../../../../../src/qf/qf_dyn.c ../../../../../src/qf/qf_mem.c ../../../../../src/qf/qf_ps.c ../../../../../src/qf/qf_qact.c ../../../../../src/qf/qf_qeq.c ../../../../../src/qf/qf_qmact.c ../../../../../src/qf/qf_time.c ../../../../../src/qv/qv.c bsp.c ../../blinky.c ../../main.c ../../../../../include/qstamp.c - -# Object Files Quoted if spaced -OBJECTFILES_QUOTED_IF_SPACED=${OBJECTDIR}/_ext/820665871/qep_hsm.o ${OBJECTDIR}/_ext/820665871/qep_msm.o ${OBJECTDIR}/_ext/820665871/qf_act.o ${OBJECTDIR}/_ext/820665871/qf_actq.o ${OBJECTDIR}/_ext/820665871/qf_defer.o ${OBJECTDIR}/_ext/820665871/qf_dyn.o ${OBJECTDIR}/_ext/820665871/qf_mem.o ${OBJECTDIR}/_ext/820665871/qf_ps.o ${OBJECTDIR}/_ext/820665871/qf_qact.o ${OBJECTDIR}/_ext/820665871/qf_qeq.o ${OBJECTDIR}/_ext/820665871/qf_qmact.o ${OBJECTDIR}/_ext/820665871/qf_time.o ${OBJECTDIR}/_ext/820665887/qv.o ${OBJECTDIR}/bsp.o ${OBJECTDIR}/_ext/43898991/blinky.o ${OBJECTDIR}/_ext/43898991/main.o ${OBJECTDIR}/_ext/726959463/qstamp.o -POSSIBLE_DEPFILES=${OBJECTDIR}/_ext/820665871/qep_hsm.o.d ${OBJECTDIR}/_ext/820665871/qep_msm.o.d ${OBJECTDIR}/_ext/820665871/qf_act.o.d ${OBJECTDIR}/_ext/820665871/qf_actq.o.d ${OBJECTDIR}/_ext/820665871/qf_defer.o.d ${OBJECTDIR}/_ext/820665871/qf_dyn.o.d ${OBJECTDIR}/_ext/820665871/qf_mem.o.d ${OBJECTDIR}/_ext/820665871/qf_ps.o.d ${OBJECTDIR}/_ext/820665871/qf_qact.o.d ${OBJECTDIR}/_ext/820665871/qf_qeq.o.d ${OBJECTDIR}/_ext/820665871/qf_qmact.o.d ${OBJECTDIR}/_ext/820665871/qf_time.o.d ${OBJECTDIR}/_ext/820665887/qv.o.d ${OBJECTDIR}/bsp.o.d ${OBJECTDIR}/_ext/43898991/blinky.o.d ${OBJECTDIR}/_ext/43898991/main.o.d ${OBJECTDIR}/_ext/726959463/qstamp.o.d - -# Object Files -OBJECTFILES=${OBJECTDIR}/_ext/820665871/qep_hsm.o ${OBJECTDIR}/_ext/820665871/qep_msm.o ${OBJECTDIR}/_ext/820665871/qf_act.o ${OBJECTDIR}/_ext/820665871/qf_actq.o ${OBJECTDIR}/_ext/820665871/qf_defer.o ${OBJECTDIR}/_ext/820665871/qf_dyn.o ${OBJECTDIR}/_ext/820665871/qf_mem.o ${OBJECTDIR}/_ext/820665871/qf_ps.o ${OBJECTDIR}/_ext/820665871/qf_qact.o ${OBJECTDIR}/_ext/820665871/qf_qeq.o ${OBJECTDIR}/_ext/820665871/qf_qmact.o ${OBJECTDIR}/_ext/820665871/qf_time.o ${OBJECTDIR}/_ext/820665887/qv.o ${OBJECTDIR}/bsp.o ${OBJECTDIR}/_ext/43898991/blinky.o ${OBJECTDIR}/_ext/43898991/main.o ${OBJECTDIR}/_ext/726959463/qstamp.o - -# Source Files -SOURCEFILES=../../../../../src/qf/qep_hsm.c ../../../../../src/qf/qep_msm.c ../../../../../src/qf/qf_act.c ../../../../../src/qf/qf_actq.c ../../../../../src/qf/qf_defer.c ../../../../../src/qf/qf_dyn.c ../../../../../src/qf/qf_mem.c ../../../../../src/qf/qf_ps.c ../../../../../src/qf/qf_qact.c ../../../../../src/qf/qf_qeq.c ../../../../../src/qf/qf_qmact.c ../../../../../src/qf/qf_time.c ../../../../../src/qv/qv.c bsp.c ../../blinky.c ../../main.c ../../../../../include/qstamp.c - - -CFLAGS= -ASFLAGS= -LDLIBSOPTIONS= - -############# Tool locations ########################################## -# If you copy a project from one host to another, the path where the # -# compiler is installed may be different. # -# If you open this project with MPLAB X in the new host, this # -# makefile will be regenerated and the paths will be corrected. # -####################################################################### -# fixDeps replaces a bunch of sed/cat/printf statements that slow down the build -FIXDEPS=fixDeps - -.build-conf: ${BUILD_SUBPROJECTS} -ifneq ($(INFORMATION_MESSAGE), ) - @echo $(INFORMATION_MESSAGE) -endif - ${MAKE} -f nbproject/Makefile-rel.mk dist/${CND_CONF}/${IMAGE_TYPE}/xc32.${IMAGE_TYPE}.${OUTPUT_SUFFIX} - -MP_PROCESSOR_OPTION=32MX250F128B -MP_LINKER_FILE_OPTION= -# ------------------------------------------------------------------------------------ -# Rules for buildStep: assemble -ifeq ($(TYPE_IMAGE), DEBUG_RUN) -else -endif - -# ------------------------------------------------------------------------------------ -# Rules for buildStep: assembleWithPreprocess -ifeq ($(TYPE_IMAGE), DEBUG_RUN) -else -endif - -# ------------------------------------------------------------------------------------ -# Rules for buildStep: compile -ifeq ($(TYPE_IMAGE), DEBUG_RUN) -${OBJECTDIR}/_ext/820665871/qep_hsm.o: ../../../../../src/qf/qep_hsm.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/820665871" - @${RM} ${OBJECTDIR}/_ext/820665871/qep_hsm.o.d - @${RM} ${OBJECTDIR}/_ext/820665871/qep_hsm.o - @${FIXDEPS} "${OBJECTDIR}/_ext/820665871/qep_hsm.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -D__DEBUG -D__MPLAB_DEBUGGER_PK3=1 -fframe-base-loclist -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -O3 -DNDEBUG -I"../.." -I"../../../../../include" -I"../../../../../src" -I"../../../../../ports/pic32/qv/xc32" -MMD -MF "${OBJECTDIR}/_ext/820665871/qep_hsm.o.d" -o ${OBJECTDIR}/_ext/820665871/qep_hsm.o ../../../../../src/qf/qep_hsm.c -DXPRJ_rel=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/820665871/qep_msm.o: ../../../../../src/qf/qep_msm.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/820665871" - @${RM} ${OBJECTDIR}/_ext/820665871/qep_msm.o.d - @${RM} ${OBJECTDIR}/_ext/820665871/qep_msm.o - @${FIXDEPS} "${OBJECTDIR}/_ext/820665871/qep_msm.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -D__DEBUG -D__MPLAB_DEBUGGER_PK3=1 -fframe-base-loclist -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -O3 -DNDEBUG -I"../.." -I"../../../../../include" -I"../../../../../src" -I"../../../../../ports/pic32/qv/xc32" -MMD -MF "${OBJECTDIR}/_ext/820665871/qep_msm.o.d" -o ${OBJECTDIR}/_ext/820665871/qep_msm.o ../../../../../src/qf/qep_msm.c -DXPRJ_rel=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/820665871/qf_act.o: ../../../../../src/qf/qf_act.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/820665871" - @${RM} ${OBJECTDIR}/_ext/820665871/qf_act.o.d - @${RM} ${OBJECTDIR}/_ext/820665871/qf_act.o - @${FIXDEPS} "${OBJECTDIR}/_ext/820665871/qf_act.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -D__DEBUG -D__MPLAB_DEBUGGER_PK3=1 -fframe-base-loclist -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -O3 -DNDEBUG -I"../.." -I"../../../../../include" -I"../../../../../src" -I"../../../../../ports/pic32/qv/xc32" -MMD -MF "${OBJECTDIR}/_ext/820665871/qf_act.o.d" -o ${OBJECTDIR}/_ext/820665871/qf_act.o ../../../../../src/qf/qf_act.c -DXPRJ_rel=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/820665871/qf_actq.o: ../../../../../src/qf/qf_actq.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/820665871" - @${RM} ${OBJECTDIR}/_ext/820665871/qf_actq.o.d - @${RM} ${OBJECTDIR}/_ext/820665871/qf_actq.o - @${FIXDEPS} "${OBJECTDIR}/_ext/820665871/qf_actq.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -D__DEBUG -D__MPLAB_DEBUGGER_PK3=1 -fframe-base-loclist -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -O3 -DNDEBUG -I"../.." -I"../../../../../include" -I"../../../../../src" -I"../../../../../ports/pic32/qv/xc32" -MMD -MF "${OBJECTDIR}/_ext/820665871/qf_actq.o.d" -o ${OBJECTDIR}/_ext/820665871/qf_actq.o ../../../../../src/qf/qf_actq.c -DXPRJ_rel=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/820665871/qf_defer.o: ../../../../../src/qf/qf_defer.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/820665871" - @${RM} ${OBJECTDIR}/_ext/820665871/qf_defer.o.d - @${RM} ${OBJECTDIR}/_ext/820665871/qf_defer.o - @${FIXDEPS} "${OBJECTDIR}/_ext/820665871/qf_defer.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -D__DEBUG -D__MPLAB_DEBUGGER_PK3=1 -fframe-base-loclist -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -O3 -DNDEBUG -I"../.." -I"../../../../../include" -I"../../../../../src" -I"../../../../../ports/pic32/qv/xc32" -MMD -MF "${OBJECTDIR}/_ext/820665871/qf_defer.o.d" -o ${OBJECTDIR}/_ext/820665871/qf_defer.o ../../../../../src/qf/qf_defer.c -DXPRJ_rel=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/820665871/qf_dyn.o: ../../../../../src/qf/qf_dyn.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/820665871" - @${RM} ${OBJECTDIR}/_ext/820665871/qf_dyn.o.d - @${RM} ${OBJECTDIR}/_ext/820665871/qf_dyn.o - @${FIXDEPS} "${OBJECTDIR}/_ext/820665871/qf_dyn.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -D__DEBUG -D__MPLAB_DEBUGGER_PK3=1 -fframe-base-loclist -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -O3 -DNDEBUG -I"../.." -I"../../../../../include" -I"../../../../../src" -I"../../../../../ports/pic32/qv/xc32" -MMD -MF "${OBJECTDIR}/_ext/820665871/qf_dyn.o.d" -o ${OBJECTDIR}/_ext/820665871/qf_dyn.o ../../../../../src/qf/qf_dyn.c -DXPRJ_rel=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/820665871/qf_mem.o: ../../../../../src/qf/qf_mem.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/820665871" - @${RM} ${OBJECTDIR}/_ext/820665871/qf_mem.o.d - @${RM} ${OBJECTDIR}/_ext/820665871/qf_mem.o - @${FIXDEPS} "${OBJECTDIR}/_ext/820665871/qf_mem.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -D__DEBUG -D__MPLAB_DEBUGGER_PK3=1 -fframe-base-loclist -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -O3 -DNDEBUG -I"../.." -I"../../../../../include" -I"../../../../../src" -I"../../../../../ports/pic32/qv/xc32" -MMD -MF "${OBJECTDIR}/_ext/820665871/qf_mem.o.d" -o ${OBJECTDIR}/_ext/820665871/qf_mem.o ../../../../../src/qf/qf_mem.c -DXPRJ_rel=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/820665871/qf_ps.o: ../../../../../src/qf/qf_ps.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/820665871" - @${RM} ${OBJECTDIR}/_ext/820665871/qf_ps.o.d - @${RM} ${OBJECTDIR}/_ext/820665871/qf_ps.o - @${FIXDEPS} "${OBJECTDIR}/_ext/820665871/qf_ps.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -D__DEBUG -D__MPLAB_DEBUGGER_PK3=1 -fframe-base-loclist -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -O3 -DNDEBUG -I"../.." -I"../../../../../include" -I"../../../../../src" -I"../../../../../ports/pic32/qv/xc32" -MMD -MF "${OBJECTDIR}/_ext/820665871/qf_ps.o.d" -o ${OBJECTDIR}/_ext/820665871/qf_ps.o ../../../../../src/qf/qf_ps.c -DXPRJ_rel=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/820665871/qf_qact.o: ../../../../../src/qf/qf_qact.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/820665871" - @${RM} ${OBJECTDIR}/_ext/820665871/qf_qact.o.d - @${RM} ${OBJECTDIR}/_ext/820665871/qf_qact.o - @${FIXDEPS} "${OBJECTDIR}/_ext/820665871/qf_qact.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -D__DEBUG -D__MPLAB_DEBUGGER_PK3=1 -fframe-base-loclist -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -O3 -DNDEBUG -I"../.." -I"../../../../../include" -I"../../../../../src" -I"../../../../../ports/pic32/qv/xc32" -MMD -MF "${OBJECTDIR}/_ext/820665871/qf_qact.o.d" -o ${OBJECTDIR}/_ext/820665871/qf_qact.o ../../../../../src/qf/qf_qact.c -DXPRJ_rel=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/820665871/qf_qeq.o: ../../../../../src/qf/qf_qeq.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/820665871" - @${RM} ${OBJECTDIR}/_ext/820665871/qf_qeq.o.d - @${RM} ${OBJECTDIR}/_ext/820665871/qf_qeq.o - @${FIXDEPS} "${OBJECTDIR}/_ext/820665871/qf_qeq.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -D__DEBUG -D__MPLAB_DEBUGGER_PK3=1 -fframe-base-loclist -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -O3 -DNDEBUG -I"../.." -I"../../../../../include" -I"../../../../../src" -I"../../../../../ports/pic32/qv/xc32" -MMD -MF "${OBJECTDIR}/_ext/820665871/qf_qeq.o.d" -o ${OBJECTDIR}/_ext/820665871/qf_qeq.o ../../../../../src/qf/qf_qeq.c -DXPRJ_rel=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/820665871/qf_qmact.o: ../../../../../src/qf/qf_qmact.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/820665871" - @${RM} ${OBJECTDIR}/_ext/820665871/qf_qmact.o.d - @${RM} ${OBJECTDIR}/_ext/820665871/qf_qmact.o - @${FIXDEPS} "${OBJECTDIR}/_ext/820665871/qf_qmact.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -D__DEBUG -D__MPLAB_DEBUGGER_PK3=1 -fframe-base-loclist -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -O3 -DNDEBUG -I"../.." -I"../../../../../include" -I"../../../../../src" -I"../../../../../ports/pic32/qv/xc32" -MMD -MF "${OBJECTDIR}/_ext/820665871/qf_qmact.o.d" -o ${OBJECTDIR}/_ext/820665871/qf_qmact.o ../../../../../src/qf/qf_qmact.c -DXPRJ_rel=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/820665871/qf_time.o: ../../../../../src/qf/qf_time.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/820665871" - @${RM} ${OBJECTDIR}/_ext/820665871/qf_time.o.d - @${RM} ${OBJECTDIR}/_ext/820665871/qf_time.o - @${FIXDEPS} "${OBJECTDIR}/_ext/820665871/qf_time.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -D__DEBUG -D__MPLAB_DEBUGGER_PK3=1 -fframe-base-loclist -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -O3 -DNDEBUG -I"../.." -I"../../../../../include" -I"../../../../../src" -I"../../../../../ports/pic32/qv/xc32" -MMD -MF "${OBJECTDIR}/_ext/820665871/qf_time.o.d" -o ${OBJECTDIR}/_ext/820665871/qf_time.o ../../../../../src/qf/qf_time.c -DXPRJ_rel=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/820665887/qv.o: ../../../../../src/qv/qv.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/820665887" - @${RM} ${OBJECTDIR}/_ext/820665887/qv.o.d - @${RM} ${OBJECTDIR}/_ext/820665887/qv.o - @${FIXDEPS} "${OBJECTDIR}/_ext/820665887/qv.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -D__DEBUG -D__MPLAB_DEBUGGER_PK3=1 -fframe-base-loclist -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -O3 -DNDEBUG -I"../.." -I"../../../../../include" -I"../../../../../src" -I"../../../../../ports/pic32/qv/xc32" -MMD -MF "${OBJECTDIR}/_ext/820665887/qv.o.d" -o ${OBJECTDIR}/_ext/820665887/qv.o ../../../../../src/qv/qv.c -DXPRJ_rel=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/bsp.o: bsp.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}" - @${RM} ${OBJECTDIR}/bsp.o.d - @${RM} ${OBJECTDIR}/bsp.o - @${FIXDEPS} "${OBJECTDIR}/bsp.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -D__DEBUG -D__MPLAB_DEBUGGER_PK3=1 -fframe-base-loclist -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -O3 -DNDEBUG -I"../.." -I"../../../../../include" -I"../../../../../src" -I"../../../../../ports/pic32/qv/xc32" -MMD -MF "${OBJECTDIR}/bsp.o.d" -o ${OBJECTDIR}/bsp.o bsp.c -DXPRJ_rel=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/43898991/blinky.o: ../../blinky.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/43898991" - @${RM} ${OBJECTDIR}/_ext/43898991/blinky.o.d - @${RM} ${OBJECTDIR}/_ext/43898991/blinky.o - @${FIXDEPS} "${OBJECTDIR}/_ext/43898991/blinky.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -D__DEBUG -D__MPLAB_DEBUGGER_PK3=1 -fframe-base-loclist -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -O3 -DNDEBUG -I"../.." -I"../../../../../include" -I"../../../../../src" -I"../../../../../ports/pic32/qv/xc32" -MMD -MF "${OBJECTDIR}/_ext/43898991/blinky.o.d" -o ${OBJECTDIR}/_ext/43898991/blinky.o ../../blinky.c -DXPRJ_rel=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/43898991/main.o: ../../main.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/43898991" - @${RM} ${OBJECTDIR}/_ext/43898991/main.o.d - @${RM} ${OBJECTDIR}/_ext/43898991/main.o - @${FIXDEPS} "${OBJECTDIR}/_ext/43898991/main.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -D__DEBUG -D__MPLAB_DEBUGGER_PK3=1 -fframe-base-loclist -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -O3 -DNDEBUG -I"../.." -I"../../../../../include" -I"../../../../../src" -I"../../../../../ports/pic32/qv/xc32" -MMD -MF "${OBJECTDIR}/_ext/43898991/main.o.d" -o ${OBJECTDIR}/_ext/43898991/main.o ../../main.c -DXPRJ_rel=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/726959463/qstamp.o: ../../../../../include/qstamp.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/726959463" - @${RM} ${OBJECTDIR}/_ext/726959463/qstamp.o.d - @${RM} ${OBJECTDIR}/_ext/726959463/qstamp.o - @${FIXDEPS} "${OBJECTDIR}/_ext/726959463/qstamp.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -D__DEBUG -D__MPLAB_DEBUGGER_PK3=1 -fframe-base-loclist -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -O3 -DNDEBUG -I"../.." -I"../../../../../include" -I"../../../../../src" -I"../../../../../ports/pic32/qv/xc32" -MMD -MF "${OBJECTDIR}/_ext/726959463/qstamp.o.d" -o ${OBJECTDIR}/_ext/726959463/qstamp.o ../../../../../include/qstamp.c -DXPRJ_rel=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -else -${OBJECTDIR}/_ext/820665871/qep_hsm.o: ../../../../../src/qf/qep_hsm.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/820665871" - @${RM} ${OBJECTDIR}/_ext/820665871/qep_hsm.o.d - @${RM} ${OBJECTDIR}/_ext/820665871/qep_hsm.o - @${FIXDEPS} "${OBJECTDIR}/_ext/820665871/qep_hsm.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -O3 -DNDEBUG -I"../.." -I"../../../../../include" -I"../../../../../src" -I"../../../../../ports/pic32/qv/xc32" -MMD -MF "${OBJECTDIR}/_ext/820665871/qep_hsm.o.d" -o ${OBJECTDIR}/_ext/820665871/qep_hsm.o ../../../../../src/qf/qep_hsm.c -DXPRJ_rel=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/820665871/qep_msm.o: ../../../../../src/qf/qep_msm.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/820665871" - @${RM} ${OBJECTDIR}/_ext/820665871/qep_msm.o.d - @${RM} ${OBJECTDIR}/_ext/820665871/qep_msm.o - @${FIXDEPS} "${OBJECTDIR}/_ext/820665871/qep_msm.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -O3 -DNDEBUG -I"../.." -I"../../../../../include" -I"../../../../../src" -I"../../../../../ports/pic32/qv/xc32" -MMD -MF "${OBJECTDIR}/_ext/820665871/qep_msm.o.d" -o ${OBJECTDIR}/_ext/820665871/qep_msm.o ../../../../../src/qf/qep_msm.c -DXPRJ_rel=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/820665871/qf_act.o: ../../../../../src/qf/qf_act.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/820665871" - @${RM} ${OBJECTDIR}/_ext/820665871/qf_act.o.d - @${RM} ${OBJECTDIR}/_ext/820665871/qf_act.o - @${FIXDEPS} "${OBJECTDIR}/_ext/820665871/qf_act.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -O3 -DNDEBUG -I"../.." -I"../../../../../include" -I"../../../../../src" -I"../../../../../ports/pic32/qv/xc32" -MMD -MF "${OBJECTDIR}/_ext/820665871/qf_act.o.d" -o ${OBJECTDIR}/_ext/820665871/qf_act.o ../../../../../src/qf/qf_act.c -DXPRJ_rel=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/820665871/qf_actq.o: ../../../../../src/qf/qf_actq.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/820665871" - @${RM} ${OBJECTDIR}/_ext/820665871/qf_actq.o.d - @${RM} ${OBJECTDIR}/_ext/820665871/qf_actq.o - @${FIXDEPS} "${OBJECTDIR}/_ext/820665871/qf_actq.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -O3 -DNDEBUG -I"../.." -I"../../../../../include" -I"../../../../../src" -I"../../../../../ports/pic32/qv/xc32" -MMD -MF "${OBJECTDIR}/_ext/820665871/qf_actq.o.d" -o ${OBJECTDIR}/_ext/820665871/qf_actq.o ../../../../../src/qf/qf_actq.c -DXPRJ_rel=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/820665871/qf_defer.o: ../../../../../src/qf/qf_defer.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/820665871" - @${RM} ${OBJECTDIR}/_ext/820665871/qf_defer.o.d - @${RM} ${OBJECTDIR}/_ext/820665871/qf_defer.o - @${FIXDEPS} "${OBJECTDIR}/_ext/820665871/qf_defer.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -O3 -DNDEBUG -I"../.." -I"../../../../../include" -I"../../../../../src" -I"../../../../../ports/pic32/qv/xc32" -MMD -MF "${OBJECTDIR}/_ext/820665871/qf_defer.o.d" -o ${OBJECTDIR}/_ext/820665871/qf_defer.o ../../../../../src/qf/qf_defer.c -DXPRJ_rel=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/820665871/qf_dyn.o: ../../../../../src/qf/qf_dyn.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/820665871" - @${RM} ${OBJECTDIR}/_ext/820665871/qf_dyn.o.d - @${RM} ${OBJECTDIR}/_ext/820665871/qf_dyn.o - @${FIXDEPS} "${OBJECTDIR}/_ext/820665871/qf_dyn.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -O3 -DNDEBUG -I"../.." -I"../../../../../include" -I"../../../../../src" -I"../../../../../ports/pic32/qv/xc32" -MMD -MF "${OBJECTDIR}/_ext/820665871/qf_dyn.o.d" -o ${OBJECTDIR}/_ext/820665871/qf_dyn.o ../../../../../src/qf/qf_dyn.c -DXPRJ_rel=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/820665871/qf_mem.o: ../../../../../src/qf/qf_mem.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/820665871" - @${RM} ${OBJECTDIR}/_ext/820665871/qf_mem.o.d - @${RM} ${OBJECTDIR}/_ext/820665871/qf_mem.o - @${FIXDEPS} "${OBJECTDIR}/_ext/820665871/qf_mem.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -O3 -DNDEBUG -I"../.." -I"../../../../../include" -I"../../../../../src" -I"../../../../../ports/pic32/qv/xc32" -MMD -MF "${OBJECTDIR}/_ext/820665871/qf_mem.o.d" -o ${OBJECTDIR}/_ext/820665871/qf_mem.o ../../../../../src/qf/qf_mem.c -DXPRJ_rel=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/820665871/qf_ps.o: ../../../../../src/qf/qf_ps.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/820665871" - @${RM} ${OBJECTDIR}/_ext/820665871/qf_ps.o.d - @${RM} ${OBJECTDIR}/_ext/820665871/qf_ps.o - @${FIXDEPS} "${OBJECTDIR}/_ext/820665871/qf_ps.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -O3 -DNDEBUG -I"../.." -I"../../../../../include" -I"../../../../../src" -I"../../../../../ports/pic32/qv/xc32" -MMD -MF "${OBJECTDIR}/_ext/820665871/qf_ps.o.d" -o ${OBJECTDIR}/_ext/820665871/qf_ps.o ../../../../../src/qf/qf_ps.c -DXPRJ_rel=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/820665871/qf_qact.o: ../../../../../src/qf/qf_qact.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/820665871" - @${RM} ${OBJECTDIR}/_ext/820665871/qf_qact.o.d - @${RM} ${OBJECTDIR}/_ext/820665871/qf_qact.o - @${FIXDEPS} "${OBJECTDIR}/_ext/820665871/qf_qact.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -O3 -DNDEBUG -I"../.." -I"../../../../../include" -I"../../../../../src" -I"../../../../../ports/pic32/qv/xc32" -MMD -MF "${OBJECTDIR}/_ext/820665871/qf_qact.o.d" -o ${OBJECTDIR}/_ext/820665871/qf_qact.o ../../../../../src/qf/qf_qact.c -DXPRJ_rel=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/820665871/qf_qeq.o: ../../../../../src/qf/qf_qeq.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/820665871" - @${RM} ${OBJECTDIR}/_ext/820665871/qf_qeq.o.d - @${RM} ${OBJECTDIR}/_ext/820665871/qf_qeq.o - @${FIXDEPS} "${OBJECTDIR}/_ext/820665871/qf_qeq.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -O3 -DNDEBUG -I"../.." -I"../../../../../include" -I"../../../../../src" -I"../../../../../ports/pic32/qv/xc32" -MMD -MF "${OBJECTDIR}/_ext/820665871/qf_qeq.o.d" -o ${OBJECTDIR}/_ext/820665871/qf_qeq.o ../../../../../src/qf/qf_qeq.c -DXPRJ_rel=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/820665871/qf_qmact.o: ../../../../../src/qf/qf_qmact.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/820665871" - @${RM} ${OBJECTDIR}/_ext/820665871/qf_qmact.o.d - @${RM} ${OBJECTDIR}/_ext/820665871/qf_qmact.o - @${FIXDEPS} "${OBJECTDIR}/_ext/820665871/qf_qmact.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -O3 -DNDEBUG -I"../.." -I"../../../../../include" -I"../../../../../src" -I"../../../../../ports/pic32/qv/xc32" -MMD -MF "${OBJECTDIR}/_ext/820665871/qf_qmact.o.d" -o ${OBJECTDIR}/_ext/820665871/qf_qmact.o ../../../../../src/qf/qf_qmact.c -DXPRJ_rel=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/820665871/qf_time.o: ../../../../../src/qf/qf_time.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/820665871" - @${RM} ${OBJECTDIR}/_ext/820665871/qf_time.o.d - @${RM} ${OBJECTDIR}/_ext/820665871/qf_time.o - @${FIXDEPS} "${OBJECTDIR}/_ext/820665871/qf_time.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -O3 -DNDEBUG -I"../.." -I"../../../../../include" -I"../../../../../src" -I"../../../../../ports/pic32/qv/xc32" -MMD -MF "${OBJECTDIR}/_ext/820665871/qf_time.o.d" -o ${OBJECTDIR}/_ext/820665871/qf_time.o ../../../../../src/qf/qf_time.c -DXPRJ_rel=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/820665887/qv.o: ../../../../../src/qv/qv.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/820665887" - @${RM} ${OBJECTDIR}/_ext/820665887/qv.o.d - @${RM} ${OBJECTDIR}/_ext/820665887/qv.o - @${FIXDEPS} "${OBJECTDIR}/_ext/820665887/qv.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -O3 -DNDEBUG -I"../.." -I"../../../../../include" -I"../../../../../src" -I"../../../../../ports/pic32/qv/xc32" -MMD -MF "${OBJECTDIR}/_ext/820665887/qv.o.d" -o ${OBJECTDIR}/_ext/820665887/qv.o ../../../../../src/qv/qv.c -DXPRJ_rel=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/bsp.o: bsp.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}" - @${RM} ${OBJECTDIR}/bsp.o.d - @${RM} ${OBJECTDIR}/bsp.o - @${FIXDEPS} "${OBJECTDIR}/bsp.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -O3 -DNDEBUG -I"../.." -I"../../../../../include" -I"../../../../../src" -I"../../../../../ports/pic32/qv/xc32" -MMD -MF "${OBJECTDIR}/bsp.o.d" -o ${OBJECTDIR}/bsp.o bsp.c -DXPRJ_rel=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/43898991/blinky.o: ../../blinky.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/43898991" - @${RM} ${OBJECTDIR}/_ext/43898991/blinky.o.d - @${RM} ${OBJECTDIR}/_ext/43898991/blinky.o - @${FIXDEPS} "${OBJECTDIR}/_ext/43898991/blinky.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -O3 -DNDEBUG -I"../.." -I"../../../../../include" -I"../../../../../src" -I"../../../../../ports/pic32/qv/xc32" -MMD -MF "${OBJECTDIR}/_ext/43898991/blinky.o.d" -o ${OBJECTDIR}/_ext/43898991/blinky.o ../../blinky.c -DXPRJ_rel=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/43898991/main.o: ../../main.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/43898991" - @${RM} ${OBJECTDIR}/_ext/43898991/main.o.d - @${RM} ${OBJECTDIR}/_ext/43898991/main.o - @${FIXDEPS} "${OBJECTDIR}/_ext/43898991/main.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -O3 -DNDEBUG -I"../.." -I"../../../../../include" -I"../../../../../src" -I"../../../../../ports/pic32/qv/xc32" -MMD -MF "${OBJECTDIR}/_ext/43898991/main.o.d" -o ${OBJECTDIR}/_ext/43898991/main.o ../../main.c -DXPRJ_rel=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/726959463/qstamp.o: ../../../../../include/qstamp.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/726959463" - @${RM} ${OBJECTDIR}/_ext/726959463/qstamp.o.d - @${RM} ${OBJECTDIR}/_ext/726959463/qstamp.o - @${FIXDEPS} "${OBJECTDIR}/_ext/726959463/qstamp.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -O3 -DNDEBUG -I"../.." -I"../../../../../include" -I"../../../../../src" -I"../../../../../ports/pic32/qv/xc32" -MMD -MF "${OBJECTDIR}/_ext/726959463/qstamp.o.d" -o ${OBJECTDIR}/_ext/726959463/qstamp.o ../../../../../include/qstamp.c -DXPRJ_rel=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -endif - -# ------------------------------------------------------------------------------------ -# Rules for buildStep: compileCPP -ifeq ($(TYPE_IMAGE), DEBUG_RUN) -else -endif - -# ------------------------------------------------------------------------------------ -# Rules for buildStep: link -ifeq ($(TYPE_IMAGE), DEBUG_RUN) -dist/${CND_CONF}/${IMAGE_TYPE}/xc32.${IMAGE_TYPE}.${OUTPUT_SUFFIX}: ${OBJECTFILES} nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} dist/${CND_CONF}/${IMAGE_TYPE} - ${MP_CC} $(MP_EXTRA_LD_PRE) -g -mdebugger -D__MPLAB_DEBUGGER_PK3=1 -mprocessor=$(MP_PROCESSOR_OPTION) -o dist/${CND_CONF}/${IMAGE_TYPE}/xc32.${IMAGE_TYPE}.${OUTPUT_SUFFIX} ${OBJECTFILES_QUOTED_IF_SPACED} -DXPRJ_rel=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -mreserve=data@0x0:0x1FC -mreserve=boot@0x1FC00490:0x1FC00BEF -Wl,--defsym=__MPLAB_BUILD=1$(MP_EXTRA_LD_POST)$(MP_LINKER_FILE_OPTION),--defsym=__MPLAB_DEBUG=1,--defsym=__DEBUG=1,-D=__DEBUG_D,--defsym=__MPLAB_DEBUGGER_PK3=1,--defsym=_min_heap_size=0,--no-code-in-dinit,--no-dinit-in-serial-mem,--report-mem,--warn-section-align,--memorysummary,dist/${CND_CONF}/${IMAGE_TYPE}/memoryfile.xml - -else -dist/${CND_CONF}/${IMAGE_TYPE}/xc32.${IMAGE_TYPE}.${OUTPUT_SUFFIX}: ${OBJECTFILES} nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} dist/${CND_CONF}/${IMAGE_TYPE} - ${MP_CC} $(MP_EXTRA_LD_PRE) -mprocessor=$(MP_PROCESSOR_OPTION) -o dist/${CND_CONF}/${IMAGE_TYPE}/xc32.${IMAGE_TYPE}.${DEBUGGABLE_SUFFIX} ${OBJECTFILES_QUOTED_IF_SPACED} -DXPRJ_rel=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -Wl,--defsym=__MPLAB_BUILD=1$(MP_EXTRA_LD_POST)$(MP_LINKER_FILE_OPTION),--defsym=_min_heap_size=0,--no-code-in-dinit,--no-dinit-in-serial-mem,--report-mem,--warn-section-align,--memorysummary,dist/${CND_CONF}/${IMAGE_TYPE}/memoryfile.xml - ${MP_CC_DIR}\\xc32-bin2hex dist/${CND_CONF}/${IMAGE_TYPE}/xc32.${IMAGE_TYPE}.${DEBUGGABLE_SUFFIX} -endif - - -# Subprojects -.build-subprojects: - - -# Subprojects -.clean-subprojects: - -# Clean Targets -.clean-conf: ${CLEAN_SUBPROJECTS} - ${RM} -r build/rel - ${RM} -r dist/rel - -# Enable dependency checking -.dep.inc: .depcheck-impl - -DEPFILES=$(shell mplabwildcard ${POSSIBLE_DEPFILES}) -ifneq (${DEPFILES},) -include ${DEPFILES} -endif diff --git a/examples/pic32/blinky_microstick2-pic32/qv/xc32/nbproject/Makefile-spy.mk b/examples/pic32/blinky_microstick2-pic32/qv/xc32/nbproject/Makefile-spy.mk deleted file mode 100644 index 96384a0e..00000000 --- a/examples/pic32/blinky_microstick2-pic32/qv/xc32/nbproject/Makefile-spy.mk +++ /dev/null @@ -1,403 +0,0 @@ -# -# Generated Makefile - do not edit! -# -# Edit the Makefile in the project folder instead (../Makefile). Each target -# has a -pre and a -post target defined where you can add customized code. -# -# This makefile implements configuration specific macros and targets. - - -# Include project Makefile -ifeq "${IGNORE_LOCAL}" "TRUE" -# do not include local makefile. User is passing all local related variables already -else -include Makefile -# Include makefile containing local settings -ifeq "$(wildcard nbproject/Makefile-local-spy.mk)" "nbproject/Makefile-local-spy.mk" -include nbproject/Makefile-local-spy.mk -endif -endif - -# Environment -MKDIR=gnumkdir -p -RM=rm -f -MV=mv -CP=cp - -# Macros -CND_CONF=spy -ifeq ($(TYPE_IMAGE), DEBUG_RUN) -IMAGE_TYPE=debug -OUTPUT_SUFFIX=elf -DEBUGGABLE_SUFFIX=elf -FINAL_IMAGE=dist/${CND_CONF}/${IMAGE_TYPE}/xc32.${IMAGE_TYPE}.${OUTPUT_SUFFIX} -else -IMAGE_TYPE=production -OUTPUT_SUFFIX=hex -DEBUGGABLE_SUFFIX=elf -FINAL_IMAGE=dist/${CND_CONF}/${IMAGE_TYPE}/xc32.${IMAGE_TYPE}.${OUTPUT_SUFFIX} -endif - -ifeq ($(COMPARE_BUILD), true) -COMPARISON_BUILD=-mafrlcsj -else -COMPARISON_BUILD= -endif - -ifdef SUB_IMAGE_ADDRESS - -else -SUB_IMAGE_ADDRESS_COMMAND= -endif - -# Object Directory -OBJECTDIR=build/${CND_CONF}/${IMAGE_TYPE} - -# Distribution Directory -DISTDIR=dist/${CND_CONF}/${IMAGE_TYPE} - -# Source Files Quoted if spaced -SOURCEFILES_QUOTED_IF_SPACED=../../../../../src/qf/qep_hsm.c ../../../../../src/qf/qep_msm.c ../../../../../src/qf/qf_act.c ../../../../../src/qf/qf_actq.c ../../../../../src/qf/qf_defer.c ../../../../../src/qf/qf_dyn.c ../../../../../src/qf/qf_mem.c ../../../../../src/qf/qf_ps.c ../../../../../src/qf/qf_qact.c ../../../../../src/qf/qf_qeq.c ../../../../../src/qf/qf_qmact.c ../../../../../src/qf/qf_time.c ../../../../../src/qv/qv.c ../../../../../src/qs/qs.c ../../../../../src/qs/qs_64bit.c ../../../../../src/qs/qs_fp.c ../../../../../src/qs/qs_rx.c bsp.c ../../blinky.c ../../main.c ../../../../../include/qstamp.c - -# Object Files Quoted if spaced -OBJECTFILES_QUOTED_IF_SPACED=${OBJECTDIR}/_ext/820665871/qep_hsm.o ${OBJECTDIR}/_ext/820665871/qep_msm.o ${OBJECTDIR}/_ext/820665871/qf_act.o ${OBJECTDIR}/_ext/820665871/qf_actq.o ${OBJECTDIR}/_ext/820665871/qf_defer.o ${OBJECTDIR}/_ext/820665871/qf_dyn.o ${OBJECTDIR}/_ext/820665871/qf_mem.o ${OBJECTDIR}/_ext/820665871/qf_ps.o ${OBJECTDIR}/_ext/820665871/qf_qact.o ${OBJECTDIR}/_ext/820665871/qf_qeq.o ${OBJECTDIR}/_ext/820665871/qf_qmact.o ${OBJECTDIR}/_ext/820665871/qf_time.o ${OBJECTDIR}/_ext/820665887/qv.o ${OBJECTDIR}/_ext/820665884/qs.o ${OBJECTDIR}/_ext/820665884/qs_64bit.o ${OBJECTDIR}/_ext/820665884/qs_fp.o ${OBJECTDIR}/_ext/820665884/qs_rx.o ${OBJECTDIR}/bsp.o ${OBJECTDIR}/_ext/43898991/blinky.o ${OBJECTDIR}/_ext/43898991/main.o ${OBJECTDIR}/_ext/726959463/qstamp.o -POSSIBLE_DEPFILES=${OBJECTDIR}/_ext/820665871/qep_hsm.o.d ${OBJECTDIR}/_ext/820665871/qep_msm.o.d ${OBJECTDIR}/_ext/820665871/qf_act.o.d ${OBJECTDIR}/_ext/820665871/qf_actq.o.d ${OBJECTDIR}/_ext/820665871/qf_defer.o.d ${OBJECTDIR}/_ext/820665871/qf_dyn.o.d ${OBJECTDIR}/_ext/820665871/qf_mem.o.d ${OBJECTDIR}/_ext/820665871/qf_ps.o.d ${OBJECTDIR}/_ext/820665871/qf_qact.o.d ${OBJECTDIR}/_ext/820665871/qf_qeq.o.d ${OBJECTDIR}/_ext/820665871/qf_qmact.o.d ${OBJECTDIR}/_ext/820665871/qf_time.o.d ${OBJECTDIR}/_ext/820665887/qv.o.d ${OBJECTDIR}/_ext/820665884/qs.o.d ${OBJECTDIR}/_ext/820665884/qs_64bit.o.d ${OBJECTDIR}/_ext/820665884/qs_fp.o.d ${OBJECTDIR}/_ext/820665884/qs_rx.o.d ${OBJECTDIR}/bsp.o.d ${OBJECTDIR}/_ext/43898991/blinky.o.d ${OBJECTDIR}/_ext/43898991/main.o.d ${OBJECTDIR}/_ext/726959463/qstamp.o.d - -# Object Files -OBJECTFILES=${OBJECTDIR}/_ext/820665871/qep_hsm.o ${OBJECTDIR}/_ext/820665871/qep_msm.o ${OBJECTDIR}/_ext/820665871/qf_act.o ${OBJECTDIR}/_ext/820665871/qf_actq.o ${OBJECTDIR}/_ext/820665871/qf_defer.o ${OBJECTDIR}/_ext/820665871/qf_dyn.o ${OBJECTDIR}/_ext/820665871/qf_mem.o ${OBJECTDIR}/_ext/820665871/qf_ps.o ${OBJECTDIR}/_ext/820665871/qf_qact.o ${OBJECTDIR}/_ext/820665871/qf_qeq.o ${OBJECTDIR}/_ext/820665871/qf_qmact.o ${OBJECTDIR}/_ext/820665871/qf_time.o ${OBJECTDIR}/_ext/820665887/qv.o ${OBJECTDIR}/_ext/820665884/qs.o ${OBJECTDIR}/_ext/820665884/qs_64bit.o ${OBJECTDIR}/_ext/820665884/qs_fp.o ${OBJECTDIR}/_ext/820665884/qs_rx.o ${OBJECTDIR}/bsp.o ${OBJECTDIR}/_ext/43898991/blinky.o ${OBJECTDIR}/_ext/43898991/main.o ${OBJECTDIR}/_ext/726959463/qstamp.o - -# Source Files -SOURCEFILES=../../../../../src/qf/qep_hsm.c ../../../../../src/qf/qep_msm.c ../../../../../src/qf/qf_act.c ../../../../../src/qf/qf_actq.c ../../../../../src/qf/qf_defer.c ../../../../../src/qf/qf_dyn.c ../../../../../src/qf/qf_mem.c ../../../../../src/qf/qf_ps.c ../../../../../src/qf/qf_qact.c ../../../../../src/qf/qf_qeq.c ../../../../../src/qf/qf_qmact.c ../../../../../src/qf/qf_time.c ../../../../../src/qv/qv.c ../../../../../src/qs/qs.c ../../../../../src/qs/qs_64bit.c ../../../../../src/qs/qs_fp.c ../../../../../src/qs/qs_rx.c bsp.c ../../blinky.c ../../main.c ../../../../../include/qstamp.c - - -CFLAGS= -ASFLAGS= -LDLIBSOPTIONS= - -############# Tool locations ########################################## -# If you copy a project from one host to another, the path where the # -# compiler is installed may be different. # -# If you open this project with MPLAB X in the new host, this # -# makefile will be regenerated and the paths will be corrected. # -####################################################################### -# fixDeps replaces a bunch of sed/cat/printf statements that slow down the build -FIXDEPS=fixDeps - -.build-conf: ${BUILD_SUBPROJECTS} -ifneq ($(INFORMATION_MESSAGE), ) - @echo $(INFORMATION_MESSAGE) -endif - ${MAKE} -f nbproject/Makefile-spy.mk dist/${CND_CONF}/${IMAGE_TYPE}/xc32.${IMAGE_TYPE}.${OUTPUT_SUFFIX} - -MP_PROCESSOR_OPTION=32MX250F128B -MP_LINKER_FILE_OPTION= -# ------------------------------------------------------------------------------------ -# Rules for buildStep: assemble -ifeq ($(TYPE_IMAGE), DEBUG_RUN) -else -endif - -# ------------------------------------------------------------------------------------ -# Rules for buildStep: assembleWithPreprocess -ifeq ($(TYPE_IMAGE), DEBUG_RUN) -else -endif - -# ------------------------------------------------------------------------------------ -# Rules for buildStep: compile -ifeq ($(TYPE_IMAGE), DEBUG_RUN) -${OBJECTDIR}/_ext/820665871/qep_hsm.o: ../../../../../src/qf/qep_hsm.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/820665871" - @${RM} ${OBJECTDIR}/_ext/820665871/qep_hsm.o.d - @${RM} ${OBJECTDIR}/_ext/820665871/qep_hsm.o - @${FIXDEPS} "${OBJECTDIR}/_ext/820665871/qep_hsm.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -D__DEBUG -D__MPLAB_DEBUGGER_PK3=1 -fframe-base-loclist -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -DQ_SPY -I"../../../../../include" -I"../../../../../src" -I"../../../../../ports/pic32/qv/xc32" -I"../.." -MMD -MF "${OBJECTDIR}/_ext/820665871/qep_hsm.o.d" -o ${OBJECTDIR}/_ext/820665871/qep_hsm.o ../../../../../src/qf/qep_hsm.c -DXPRJ_spy=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/820665871/qep_msm.o: ../../../../../src/qf/qep_msm.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/820665871" - @${RM} ${OBJECTDIR}/_ext/820665871/qep_msm.o.d - @${RM} ${OBJECTDIR}/_ext/820665871/qep_msm.o - @${FIXDEPS} "${OBJECTDIR}/_ext/820665871/qep_msm.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -D__DEBUG -D__MPLAB_DEBUGGER_PK3=1 -fframe-base-loclist -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -DQ_SPY -I"../../../../../include" -I"../../../../../src" -I"../../../../../ports/pic32/qv/xc32" -I"../.." -MMD -MF "${OBJECTDIR}/_ext/820665871/qep_msm.o.d" -o ${OBJECTDIR}/_ext/820665871/qep_msm.o ../../../../../src/qf/qep_msm.c -DXPRJ_spy=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/820665871/qf_act.o: ../../../../../src/qf/qf_act.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/820665871" - @${RM} ${OBJECTDIR}/_ext/820665871/qf_act.o.d - @${RM} ${OBJECTDIR}/_ext/820665871/qf_act.o - @${FIXDEPS} "${OBJECTDIR}/_ext/820665871/qf_act.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -D__DEBUG -D__MPLAB_DEBUGGER_PK3=1 -fframe-base-loclist -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -DQ_SPY -I"../../../../../include" -I"../../../../../src" -I"../../../../../ports/pic32/qv/xc32" -I"../.." -MMD -MF "${OBJECTDIR}/_ext/820665871/qf_act.o.d" -o ${OBJECTDIR}/_ext/820665871/qf_act.o ../../../../../src/qf/qf_act.c -DXPRJ_spy=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/820665871/qf_actq.o: ../../../../../src/qf/qf_actq.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/820665871" - @${RM} ${OBJECTDIR}/_ext/820665871/qf_actq.o.d - @${RM} ${OBJECTDIR}/_ext/820665871/qf_actq.o - @${FIXDEPS} "${OBJECTDIR}/_ext/820665871/qf_actq.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -D__DEBUG -D__MPLAB_DEBUGGER_PK3=1 -fframe-base-loclist -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -DQ_SPY -I"../../../../../include" -I"../../../../../src" -I"../../../../../ports/pic32/qv/xc32" -I"../.." -MMD -MF "${OBJECTDIR}/_ext/820665871/qf_actq.o.d" -o ${OBJECTDIR}/_ext/820665871/qf_actq.o ../../../../../src/qf/qf_actq.c -DXPRJ_spy=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/820665871/qf_defer.o: ../../../../../src/qf/qf_defer.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/820665871" - @${RM} ${OBJECTDIR}/_ext/820665871/qf_defer.o.d - @${RM} ${OBJECTDIR}/_ext/820665871/qf_defer.o - @${FIXDEPS} "${OBJECTDIR}/_ext/820665871/qf_defer.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -D__DEBUG -D__MPLAB_DEBUGGER_PK3=1 -fframe-base-loclist -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -DQ_SPY -I"../../../../../include" -I"../../../../../src" -I"../../../../../ports/pic32/qv/xc32" -I"../.." -MMD -MF "${OBJECTDIR}/_ext/820665871/qf_defer.o.d" -o ${OBJECTDIR}/_ext/820665871/qf_defer.o ../../../../../src/qf/qf_defer.c -DXPRJ_spy=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/820665871/qf_dyn.o: ../../../../../src/qf/qf_dyn.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/820665871" - @${RM} ${OBJECTDIR}/_ext/820665871/qf_dyn.o.d - @${RM} ${OBJECTDIR}/_ext/820665871/qf_dyn.o - @${FIXDEPS} "${OBJECTDIR}/_ext/820665871/qf_dyn.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -D__DEBUG -D__MPLAB_DEBUGGER_PK3=1 -fframe-base-loclist -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -DQ_SPY -I"../../../../../include" -I"../../../../../src" -I"../../../../../ports/pic32/qv/xc32" -I"../.." -MMD -MF "${OBJECTDIR}/_ext/820665871/qf_dyn.o.d" -o ${OBJECTDIR}/_ext/820665871/qf_dyn.o ../../../../../src/qf/qf_dyn.c -DXPRJ_spy=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/820665871/qf_mem.o: ../../../../../src/qf/qf_mem.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/820665871" - @${RM} ${OBJECTDIR}/_ext/820665871/qf_mem.o.d - @${RM} ${OBJECTDIR}/_ext/820665871/qf_mem.o - @${FIXDEPS} "${OBJECTDIR}/_ext/820665871/qf_mem.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -D__DEBUG -D__MPLAB_DEBUGGER_PK3=1 -fframe-base-loclist -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -DQ_SPY -I"../../../../../include" -I"../../../../../src" -I"../../../../../ports/pic32/qv/xc32" -I"../.." -MMD -MF "${OBJECTDIR}/_ext/820665871/qf_mem.o.d" -o ${OBJECTDIR}/_ext/820665871/qf_mem.o ../../../../../src/qf/qf_mem.c -DXPRJ_spy=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/820665871/qf_ps.o: ../../../../../src/qf/qf_ps.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/820665871" - @${RM} ${OBJECTDIR}/_ext/820665871/qf_ps.o.d - @${RM} ${OBJECTDIR}/_ext/820665871/qf_ps.o - @${FIXDEPS} "${OBJECTDIR}/_ext/820665871/qf_ps.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -D__DEBUG -D__MPLAB_DEBUGGER_PK3=1 -fframe-base-loclist -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -DQ_SPY -I"../../../../../include" -I"../../../../../src" -I"../../../../../ports/pic32/qv/xc32" -I"../.." -MMD -MF "${OBJECTDIR}/_ext/820665871/qf_ps.o.d" -o ${OBJECTDIR}/_ext/820665871/qf_ps.o ../../../../../src/qf/qf_ps.c -DXPRJ_spy=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/820665871/qf_qact.o: ../../../../../src/qf/qf_qact.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/820665871" - @${RM} ${OBJECTDIR}/_ext/820665871/qf_qact.o.d - @${RM} ${OBJECTDIR}/_ext/820665871/qf_qact.o - @${FIXDEPS} "${OBJECTDIR}/_ext/820665871/qf_qact.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -D__DEBUG -D__MPLAB_DEBUGGER_PK3=1 -fframe-base-loclist -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -DQ_SPY -I"../../../../../include" -I"../../../../../src" -I"../../../../../ports/pic32/qv/xc32" -I"../.." -MMD -MF "${OBJECTDIR}/_ext/820665871/qf_qact.o.d" -o ${OBJECTDIR}/_ext/820665871/qf_qact.o ../../../../../src/qf/qf_qact.c -DXPRJ_spy=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/820665871/qf_qeq.o: ../../../../../src/qf/qf_qeq.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/820665871" - @${RM} ${OBJECTDIR}/_ext/820665871/qf_qeq.o.d - @${RM} ${OBJECTDIR}/_ext/820665871/qf_qeq.o - @${FIXDEPS} "${OBJECTDIR}/_ext/820665871/qf_qeq.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -D__DEBUG -D__MPLAB_DEBUGGER_PK3=1 -fframe-base-loclist -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -DQ_SPY -I"../../../../../include" -I"../../../../../src" -I"../../../../../ports/pic32/qv/xc32" -I"../.." -MMD -MF "${OBJECTDIR}/_ext/820665871/qf_qeq.o.d" -o ${OBJECTDIR}/_ext/820665871/qf_qeq.o ../../../../../src/qf/qf_qeq.c -DXPRJ_spy=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/820665871/qf_qmact.o: ../../../../../src/qf/qf_qmact.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/820665871" - @${RM} ${OBJECTDIR}/_ext/820665871/qf_qmact.o.d - @${RM} ${OBJECTDIR}/_ext/820665871/qf_qmact.o - @${FIXDEPS} "${OBJECTDIR}/_ext/820665871/qf_qmact.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -D__DEBUG -D__MPLAB_DEBUGGER_PK3=1 -fframe-base-loclist -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -DQ_SPY -I"../../../../../include" -I"../../../../../src" -I"../../../../../ports/pic32/qv/xc32" -I"../.." -MMD -MF "${OBJECTDIR}/_ext/820665871/qf_qmact.o.d" -o ${OBJECTDIR}/_ext/820665871/qf_qmact.o ../../../../../src/qf/qf_qmact.c -DXPRJ_spy=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/820665871/qf_time.o: ../../../../../src/qf/qf_time.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/820665871" - @${RM} ${OBJECTDIR}/_ext/820665871/qf_time.o.d - @${RM} ${OBJECTDIR}/_ext/820665871/qf_time.o - @${FIXDEPS} "${OBJECTDIR}/_ext/820665871/qf_time.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -D__DEBUG -D__MPLAB_DEBUGGER_PK3=1 -fframe-base-loclist -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -DQ_SPY -I"../../../../../include" -I"../../../../../src" -I"../../../../../ports/pic32/qv/xc32" -I"../.." -MMD -MF "${OBJECTDIR}/_ext/820665871/qf_time.o.d" -o ${OBJECTDIR}/_ext/820665871/qf_time.o ../../../../../src/qf/qf_time.c -DXPRJ_spy=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/820665887/qv.o: ../../../../../src/qv/qv.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/820665887" - @${RM} ${OBJECTDIR}/_ext/820665887/qv.o.d - @${RM} ${OBJECTDIR}/_ext/820665887/qv.o - @${FIXDEPS} "${OBJECTDIR}/_ext/820665887/qv.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -D__DEBUG -D__MPLAB_DEBUGGER_PK3=1 -fframe-base-loclist -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -DQ_SPY -I"../../../../../include" -I"../../../../../src" -I"../../../../../ports/pic32/qv/xc32" -I"../.." -MMD -MF "${OBJECTDIR}/_ext/820665887/qv.o.d" -o ${OBJECTDIR}/_ext/820665887/qv.o ../../../../../src/qv/qv.c -DXPRJ_spy=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/820665884/qs.o: ../../../../../src/qs/qs.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/820665884" - @${RM} ${OBJECTDIR}/_ext/820665884/qs.o.d - @${RM} ${OBJECTDIR}/_ext/820665884/qs.o - @${FIXDEPS} "${OBJECTDIR}/_ext/820665884/qs.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -D__DEBUG -D__MPLAB_DEBUGGER_PK3=1 -fframe-base-loclist -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -DQ_SPY -I"../../../../../include" -I"../../../../../src" -I"../../../../../ports/pic32/qv/xc32" -I"../.." -MMD -MF "${OBJECTDIR}/_ext/820665884/qs.o.d" -o ${OBJECTDIR}/_ext/820665884/qs.o ../../../../../src/qs/qs.c -DXPRJ_spy=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/820665884/qs_64bit.o: ../../../../../src/qs/qs_64bit.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/820665884" - @${RM} ${OBJECTDIR}/_ext/820665884/qs_64bit.o.d - @${RM} ${OBJECTDIR}/_ext/820665884/qs_64bit.o - @${FIXDEPS} "${OBJECTDIR}/_ext/820665884/qs_64bit.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -D__DEBUG -D__MPLAB_DEBUGGER_PK3=1 -fframe-base-loclist -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -DQ_SPY -I"../../../../../include" -I"../../../../../src" -I"../../../../../ports/pic32/qv/xc32" -I"../.." -MMD -MF "${OBJECTDIR}/_ext/820665884/qs_64bit.o.d" -o ${OBJECTDIR}/_ext/820665884/qs_64bit.o ../../../../../src/qs/qs_64bit.c -DXPRJ_spy=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/820665884/qs_fp.o: ../../../../../src/qs/qs_fp.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/820665884" - @${RM} ${OBJECTDIR}/_ext/820665884/qs_fp.o.d - @${RM} ${OBJECTDIR}/_ext/820665884/qs_fp.o - @${FIXDEPS} "${OBJECTDIR}/_ext/820665884/qs_fp.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -D__DEBUG -D__MPLAB_DEBUGGER_PK3=1 -fframe-base-loclist -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -DQ_SPY -I"../../../../../include" -I"../../../../../src" -I"../../../../../ports/pic32/qv/xc32" -I"../.." -MMD -MF "${OBJECTDIR}/_ext/820665884/qs_fp.o.d" -o ${OBJECTDIR}/_ext/820665884/qs_fp.o ../../../../../src/qs/qs_fp.c -DXPRJ_spy=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/820665884/qs_rx.o: ../../../../../src/qs/qs_rx.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/820665884" - @${RM} ${OBJECTDIR}/_ext/820665884/qs_rx.o.d - @${RM} ${OBJECTDIR}/_ext/820665884/qs_rx.o - @${FIXDEPS} "${OBJECTDIR}/_ext/820665884/qs_rx.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -D__DEBUG -D__MPLAB_DEBUGGER_PK3=1 -fframe-base-loclist -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -DQ_SPY -I"../../../../../include" -I"../../../../../src" -I"../../../../../ports/pic32/qv/xc32" -I"../.." -MMD -MF "${OBJECTDIR}/_ext/820665884/qs_rx.o.d" -o ${OBJECTDIR}/_ext/820665884/qs_rx.o ../../../../../src/qs/qs_rx.c -DXPRJ_spy=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/bsp.o: bsp.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}" - @${RM} ${OBJECTDIR}/bsp.o.d - @${RM} ${OBJECTDIR}/bsp.o - @${FIXDEPS} "${OBJECTDIR}/bsp.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -D__DEBUG -D__MPLAB_DEBUGGER_PK3=1 -fframe-base-loclist -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -DQ_SPY -I"../../../../../include" -I"../../../../../src" -I"../../../../../ports/pic32/qv/xc32" -I"../.." -MMD -MF "${OBJECTDIR}/bsp.o.d" -o ${OBJECTDIR}/bsp.o bsp.c -DXPRJ_spy=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/43898991/blinky.o: ../../blinky.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/43898991" - @${RM} ${OBJECTDIR}/_ext/43898991/blinky.o.d - @${RM} ${OBJECTDIR}/_ext/43898991/blinky.o - @${FIXDEPS} "${OBJECTDIR}/_ext/43898991/blinky.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -D__DEBUG -D__MPLAB_DEBUGGER_PK3=1 -fframe-base-loclist -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -DQ_SPY -I"../../../../../include" -I"../../../../../src" -I"../../../../../ports/pic32/qv/xc32" -I"../.." -MMD -MF "${OBJECTDIR}/_ext/43898991/blinky.o.d" -o ${OBJECTDIR}/_ext/43898991/blinky.o ../../blinky.c -DXPRJ_spy=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/43898991/main.o: ../../main.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/43898991" - @${RM} ${OBJECTDIR}/_ext/43898991/main.o.d - @${RM} ${OBJECTDIR}/_ext/43898991/main.o - @${FIXDEPS} "${OBJECTDIR}/_ext/43898991/main.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -D__DEBUG -D__MPLAB_DEBUGGER_PK3=1 -fframe-base-loclist -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -DQ_SPY -I"../../../../../include" -I"../../../../../src" -I"../../../../../ports/pic32/qv/xc32" -I"../.." -MMD -MF "${OBJECTDIR}/_ext/43898991/main.o.d" -o ${OBJECTDIR}/_ext/43898991/main.o ../../main.c -DXPRJ_spy=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/726959463/qstamp.o: ../../../../../include/qstamp.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/726959463" - @${RM} ${OBJECTDIR}/_ext/726959463/qstamp.o.d - @${RM} ${OBJECTDIR}/_ext/726959463/qstamp.o - @${FIXDEPS} "${OBJECTDIR}/_ext/726959463/qstamp.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -D__DEBUG -D__MPLAB_DEBUGGER_PK3=1 -fframe-base-loclist -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -DQ_SPY -I"../../../../../include" -I"../../../../../src" -I"../../../../../ports/pic32/qv/xc32" -I"../.." -MMD -MF "${OBJECTDIR}/_ext/726959463/qstamp.o.d" -o ${OBJECTDIR}/_ext/726959463/qstamp.o ../../../../../include/qstamp.c -DXPRJ_spy=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -else -${OBJECTDIR}/_ext/820665871/qep_hsm.o: ../../../../../src/qf/qep_hsm.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/820665871" - @${RM} ${OBJECTDIR}/_ext/820665871/qep_hsm.o.d - @${RM} ${OBJECTDIR}/_ext/820665871/qep_hsm.o - @${FIXDEPS} "${OBJECTDIR}/_ext/820665871/qep_hsm.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -DQ_SPY -I"../../../../../include" -I"../../../../../src" -I"../../../../../ports/pic32/qv/xc32" -I"../.." -MMD -MF "${OBJECTDIR}/_ext/820665871/qep_hsm.o.d" -o ${OBJECTDIR}/_ext/820665871/qep_hsm.o ../../../../../src/qf/qep_hsm.c -DXPRJ_spy=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/820665871/qep_msm.o: ../../../../../src/qf/qep_msm.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/820665871" - @${RM} ${OBJECTDIR}/_ext/820665871/qep_msm.o.d - @${RM} ${OBJECTDIR}/_ext/820665871/qep_msm.o - @${FIXDEPS} "${OBJECTDIR}/_ext/820665871/qep_msm.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -DQ_SPY -I"../../../../../include" -I"../../../../../src" -I"../../../../../ports/pic32/qv/xc32" -I"../.." -MMD -MF "${OBJECTDIR}/_ext/820665871/qep_msm.o.d" -o ${OBJECTDIR}/_ext/820665871/qep_msm.o ../../../../../src/qf/qep_msm.c -DXPRJ_spy=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/820665871/qf_act.o: ../../../../../src/qf/qf_act.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/820665871" - @${RM} ${OBJECTDIR}/_ext/820665871/qf_act.o.d - @${RM} ${OBJECTDIR}/_ext/820665871/qf_act.o - @${FIXDEPS} "${OBJECTDIR}/_ext/820665871/qf_act.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -DQ_SPY -I"../../../../../include" -I"../../../../../src" -I"../../../../../ports/pic32/qv/xc32" -I"../.." -MMD -MF "${OBJECTDIR}/_ext/820665871/qf_act.o.d" -o ${OBJECTDIR}/_ext/820665871/qf_act.o ../../../../../src/qf/qf_act.c -DXPRJ_spy=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/820665871/qf_actq.o: ../../../../../src/qf/qf_actq.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/820665871" - @${RM} ${OBJECTDIR}/_ext/820665871/qf_actq.o.d - @${RM} ${OBJECTDIR}/_ext/820665871/qf_actq.o - @${FIXDEPS} "${OBJECTDIR}/_ext/820665871/qf_actq.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -DQ_SPY -I"../../../../../include" -I"../../../../../src" -I"../../../../../ports/pic32/qv/xc32" -I"../.." -MMD -MF "${OBJECTDIR}/_ext/820665871/qf_actq.o.d" -o ${OBJECTDIR}/_ext/820665871/qf_actq.o ../../../../../src/qf/qf_actq.c -DXPRJ_spy=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/820665871/qf_defer.o: ../../../../../src/qf/qf_defer.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/820665871" - @${RM} ${OBJECTDIR}/_ext/820665871/qf_defer.o.d - @${RM} ${OBJECTDIR}/_ext/820665871/qf_defer.o - @${FIXDEPS} "${OBJECTDIR}/_ext/820665871/qf_defer.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -DQ_SPY -I"../../../../../include" -I"../../../../../src" -I"../../../../../ports/pic32/qv/xc32" -I"../.." -MMD -MF "${OBJECTDIR}/_ext/820665871/qf_defer.o.d" -o ${OBJECTDIR}/_ext/820665871/qf_defer.o ../../../../../src/qf/qf_defer.c -DXPRJ_spy=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/820665871/qf_dyn.o: ../../../../../src/qf/qf_dyn.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/820665871" - @${RM} ${OBJECTDIR}/_ext/820665871/qf_dyn.o.d - @${RM} ${OBJECTDIR}/_ext/820665871/qf_dyn.o - @${FIXDEPS} "${OBJECTDIR}/_ext/820665871/qf_dyn.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -DQ_SPY -I"../../../../../include" -I"../../../../../src" -I"../../../../../ports/pic32/qv/xc32" -I"../.." -MMD -MF "${OBJECTDIR}/_ext/820665871/qf_dyn.o.d" -o ${OBJECTDIR}/_ext/820665871/qf_dyn.o ../../../../../src/qf/qf_dyn.c -DXPRJ_spy=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/820665871/qf_mem.o: ../../../../../src/qf/qf_mem.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/820665871" - @${RM} ${OBJECTDIR}/_ext/820665871/qf_mem.o.d - @${RM} ${OBJECTDIR}/_ext/820665871/qf_mem.o - @${FIXDEPS} "${OBJECTDIR}/_ext/820665871/qf_mem.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -DQ_SPY -I"../../../../../include" -I"../../../../../src" -I"../../../../../ports/pic32/qv/xc32" -I"../.." -MMD -MF "${OBJECTDIR}/_ext/820665871/qf_mem.o.d" -o ${OBJECTDIR}/_ext/820665871/qf_mem.o ../../../../../src/qf/qf_mem.c -DXPRJ_spy=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/820665871/qf_ps.o: ../../../../../src/qf/qf_ps.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/820665871" - @${RM} ${OBJECTDIR}/_ext/820665871/qf_ps.o.d - @${RM} ${OBJECTDIR}/_ext/820665871/qf_ps.o - @${FIXDEPS} "${OBJECTDIR}/_ext/820665871/qf_ps.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -DQ_SPY -I"../../../../../include" -I"../../../../../src" -I"../../../../../ports/pic32/qv/xc32" -I"../.." -MMD -MF "${OBJECTDIR}/_ext/820665871/qf_ps.o.d" -o ${OBJECTDIR}/_ext/820665871/qf_ps.o ../../../../../src/qf/qf_ps.c -DXPRJ_spy=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/820665871/qf_qact.o: ../../../../../src/qf/qf_qact.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/820665871" - @${RM} ${OBJECTDIR}/_ext/820665871/qf_qact.o.d - @${RM} ${OBJECTDIR}/_ext/820665871/qf_qact.o - @${FIXDEPS} "${OBJECTDIR}/_ext/820665871/qf_qact.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -DQ_SPY -I"../../../../../include" -I"../../../../../src" -I"../../../../../ports/pic32/qv/xc32" -I"../.." -MMD -MF "${OBJECTDIR}/_ext/820665871/qf_qact.o.d" -o ${OBJECTDIR}/_ext/820665871/qf_qact.o ../../../../../src/qf/qf_qact.c -DXPRJ_spy=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/820665871/qf_qeq.o: ../../../../../src/qf/qf_qeq.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/820665871" - @${RM} ${OBJECTDIR}/_ext/820665871/qf_qeq.o.d - @${RM} ${OBJECTDIR}/_ext/820665871/qf_qeq.o - @${FIXDEPS} "${OBJECTDIR}/_ext/820665871/qf_qeq.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -DQ_SPY -I"../../../../../include" -I"../../../../../src" -I"../../../../../ports/pic32/qv/xc32" -I"../.." -MMD -MF "${OBJECTDIR}/_ext/820665871/qf_qeq.o.d" -o ${OBJECTDIR}/_ext/820665871/qf_qeq.o ../../../../../src/qf/qf_qeq.c -DXPRJ_spy=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/820665871/qf_qmact.o: ../../../../../src/qf/qf_qmact.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/820665871" - @${RM} ${OBJECTDIR}/_ext/820665871/qf_qmact.o.d - @${RM} ${OBJECTDIR}/_ext/820665871/qf_qmact.o - @${FIXDEPS} "${OBJECTDIR}/_ext/820665871/qf_qmact.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -DQ_SPY -I"../../../../../include" -I"../../../../../src" -I"../../../../../ports/pic32/qv/xc32" -I"../.." -MMD -MF "${OBJECTDIR}/_ext/820665871/qf_qmact.o.d" -o ${OBJECTDIR}/_ext/820665871/qf_qmact.o ../../../../../src/qf/qf_qmact.c -DXPRJ_spy=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/820665871/qf_time.o: ../../../../../src/qf/qf_time.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/820665871" - @${RM} ${OBJECTDIR}/_ext/820665871/qf_time.o.d - @${RM} ${OBJECTDIR}/_ext/820665871/qf_time.o - @${FIXDEPS} "${OBJECTDIR}/_ext/820665871/qf_time.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -DQ_SPY -I"../../../../../include" -I"../../../../../src" -I"../../../../../ports/pic32/qv/xc32" -I"../.." -MMD -MF "${OBJECTDIR}/_ext/820665871/qf_time.o.d" -o ${OBJECTDIR}/_ext/820665871/qf_time.o ../../../../../src/qf/qf_time.c -DXPRJ_spy=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/820665887/qv.o: ../../../../../src/qv/qv.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/820665887" - @${RM} ${OBJECTDIR}/_ext/820665887/qv.o.d - @${RM} ${OBJECTDIR}/_ext/820665887/qv.o - @${FIXDEPS} "${OBJECTDIR}/_ext/820665887/qv.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -DQ_SPY -I"../../../../../include" -I"../../../../../src" -I"../../../../../ports/pic32/qv/xc32" -I"../.." -MMD -MF "${OBJECTDIR}/_ext/820665887/qv.o.d" -o ${OBJECTDIR}/_ext/820665887/qv.o ../../../../../src/qv/qv.c -DXPRJ_spy=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/820665884/qs.o: ../../../../../src/qs/qs.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/820665884" - @${RM} ${OBJECTDIR}/_ext/820665884/qs.o.d - @${RM} ${OBJECTDIR}/_ext/820665884/qs.o - @${FIXDEPS} "${OBJECTDIR}/_ext/820665884/qs.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -DQ_SPY -I"../../../../../include" -I"../../../../../src" -I"../../../../../ports/pic32/qv/xc32" -I"../.." -MMD -MF "${OBJECTDIR}/_ext/820665884/qs.o.d" -o ${OBJECTDIR}/_ext/820665884/qs.o ../../../../../src/qs/qs.c -DXPRJ_spy=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/820665884/qs_64bit.o: ../../../../../src/qs/qs_64bit.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/820665884" - @${RM} ${OBJECTDIR}/_ext/820665884/qs_64bit.o.d - @${RM} ${OBJECTDIR}/_ext/820665884/qs_64bit.o - @${FIXDEPS} "${OBJECTDIR}/_ext/820665884/qs_64bit.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -DQ_SPY -I"../../../../../include" -I"../../../../../src" -I"../../../../../ports/pic32/qv/xc32" -I"../.." -MMD -MF "${OBJECTDIR}/_ext/820665884/qs_64bit.o.d" -o ${OBJECTDIR}/_ext/820665884/qs_64bit.o ../../../../../src/qs/qs_64bit.c -DXPRJ_spy=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/820665884/qs_fp.o: ../../../../../src/qs/qs_fp.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/820665884" - @${RM} ${OBJECTDIR}/_ext/820665884/qs_fp.o.d - @${RM} ${OBJECTDIR}/_ext/820665884/qs_fp.o - @${FIXDEPS} "${OBJECTDIR}/_ext/820665884/qs_fp.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -DQ_SPY -I"../../../../../include" -I"../../../../../src" -I"../../../../../ports/pic32/qv/xc32" -I"../.." -MMD -MF "${OBJECTDIR}/_ext/820665884/qs_fp.o.d" -o ${OBJECTDIR}/_ext/820665884/qs_fp.o ../../../../../src/qs/qs_fp.c -DXPRJ_spy=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/820665884/qs_rx.o: ../../../../../src/qs/qs_rx.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/820665884" - @${RM} ${OBJECTDIR}/_ext/820665884/qs_rx.o.d - @${RM} ${OBJECTDIR}/_ext/820665884/qs_rx.o - @${FIXDEPS} "${OBJECTDIR}/_ext/820665884/qs_rx.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -DQ_SPY -I"../../../../../include" -I"../../../../../src" -I"../../../../../ports/pic32/qv/xc32" -I"../.." -MMD -MF "${OBJECTDIR}/_ext/820665884/qs_rx.o.d" -o ${OBJECTDIR}/_ext/820665884/qs_rx.o ../../../../../src/qs/qs_rx.c -DXPRJ_spy=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/bsp.o: bsp.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}" - @${RM} ${OBJECTDIR}/bsp.o.d - @${RM} ${OBJECTDIR}/bsp.o - @${FIXDEPS} "${OBJECTDIR}/bsp.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -DQ_SPY -I"../../../../../include" -I"../../../../../src" -I"../../../../../ports/pic32/qv/xc32" -I"../.." -MMD -MF "${OBJECTDIR}/bsp.o.d" -o ${OBJECTDIR}/bsp.o bsp.c -DXPRJ_spy=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/43898991/blinky.o: ../../blinky.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/43898991" - @${RM} ${OBJECTDIR}/_ext/43898991/blinky.o.d - @${RM} ${OBJECTDIR}/_ext/43898991/blinky.o - @${FIXDEPS} "${OBJECTDIR}/_ext/43898991/blinky.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -DQ_SPY -I"../../../../../include" -I"../../../../../src" -I"../../../../../ports/pic32/qv/xc32" -I"../.." -MMD -MF "${OBJECTDIR}/_ext/43898991/blinky.o.d" -o ${OBJECTDIR}/_ext/43898991/blinky.o ../../blinky.c -DXPRJ_spy=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/43898991/main.o: ../../main.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/43898991" - @${RM} ${OBJECTDIR}/_ext/43898991/main.o.d - @${RM} ${OBJECTDIR}/_ext/43898991/main.o - @${FIXDEPS} "${OBJECTDIR}/_ext/43898991/main.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -DQ_SPY -I"../../../../../include" -I"../../../../../src" -I"../../../../../ports/pic32/qv/xc32" -I"../.." -MMD -MF "${OBJECTDIR}/_ext/43898991/main.o.d" -o ${OBJECTDIR}/_ext/43898991/main.o ../../main.c -DXPRJ_spy=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -${OBJECTDIR}/_ext/726959463/qstamp.o: ../../../../../include/qstamp.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/726959463" - @${RM} ${OBJECTDIR}/_ext/726959463/qstamp.o.d - @${RM} ${OBJECTDIR}/_ext/726959463/qstamp.o - @${FIXDEPS} "${OBJECTDIR}/_ext/726959463/qstamp.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -DQ_SPY -I"../../../../../include" -I"../../../../../src" -I"../../../../../ports/pic32/qv/xc32" -I"../.." -MMD -MF "${OBJECTDIR}/_ext/726959463/qstamp.o.d" -o ${OBJECTDIR}/_ext/726959463/qstamp.o ../../../../../include/qstamp.c -DXPRJ_spy=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - -endif - -# ------------------------------------------------------------------------------------ -# Rules for buildStep: compileCPP -ifeq ($(TYPE_IMAGE), DEBUG_RUN) -else -endif - -# ------------------------------------------------------------------------------------ -# Rules for buildStep: link -ifeq ($(TYPE_IMAGE), DEBUG_RUN) -dist/${CND_CONF}/${IMAGE_TYPE}/xc32.${IMAGE_TYPE}.${OUTPUT_SUFFIX}: ${OBJECTFILES} nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} dist/${CND_CONF}/${IMAGE_TYPE} - ${MP_CC} $(MP_EXTRA_LD_PRE) -g -mdebugger -D__MPLAB_DEBUGGER_PK3=1 -mprocessor=$(MP_PROCESSOR_OPTION) -o dist/${CND_CONF}/${IMAGE_TYPE}/xc32.${IMAGE_TYPE}.${OUTPUT_SUFFIX} ${OBJECTFILES_QUOTED_IF_SPACED} -DXPRJ_spy=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -mreserve=data@0x0:0x1FC -mreserve=boot@0x1FC00490:0x1FC00BEF -Wl,--defsym=__MPLAB_BUILD=1$(MP_EXTRA_LD_POST)$(MP_LINKER_FILE_OPTION),--defsym=__MPLAB_DEBUG=1,--defsym=__DEBUG=1,-D=__DEBUG_D,--defsym=__MPLAB_DEBUGGER_PK3=1,--defsym=_min_heap_size=0,--no-code-in-dinit,--no-dinit-in-serial-mem,--report-mem,--warn-section-align,--memorysummary,dist/${CND_CONF}/${IMAGE_TYPE}/memoryfile.xml - -else -dist/${CND_CONF}/${IMAGE_TYPE}/xc32.${IMAGE_TYPE}.${OUTPUT_SUFFIX}: ${OBJECTFILES} nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} dist/${CND_CONF}/${IMAGE_TYPE} - ${MP_CC} $(MP_EXTRA_LD_PRE) -mprocessor=$(MP_PROCESSOR_OPTION) -o dist/${CND_CONF}/${IMAGE_TYPE}/xc32.${IMAGE_TYPE}.${DEBUGGABLE_SUFFIX} ${OBJECTFILES_QUOTED_IF_SPACED} -DXPRJ_spy=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -Wl,--defsym=__MPLAB_BUILD=1$(MP_EXTRA_LD_POST)$(MP_LINKER_FILE_OPTION),--defsym=_min_heap_size=0,--no-code-in-dinit,--no-dinit-in-serial-mem,--report-mem,--warn-section-align,--memorysummary,dist/${CND_CONF}/${IMAGE_TYPE}/memoryfile.xml - ${MP_CC_DIR}\\xc32-bin2hex dist/${CND_CONF}/${IMAGE_TYPE}/xc32.${IMAGE_TYPE}.${DEBUGGABLE_SUFFIX} -endif - - -# Subprojects -.build-subprojects: - - -# Subprojects -.clean-subprojects: - -# Clean Targets -.clean-conf: ${CLEAN_SUBPROJECTS} - ${RM} -r build/spy - ${RM} -r dist/spy - -# Enable dependency checking -.dep.inc: .depcheck-impl - -DEPFILES=$(shell mplabwildcard ${POSSIBLE_DEPFILES}) -ifneq (${DEPFILES},) -include ${DEPFILES} -endif diff --git a/examples/pic32/blinky_microstick2-pic32/qv/xc32/nbproject/Makefile-variables.mk b/examples/pic32/blinky_microstick2-pic32/qv/xc32/nbproject/Makefile-variables.mk deleted file mode 100644 index 5a1eb7fc..00000000 --- a/examples/pic32/blinky_microstick2-pic32/qv/xc32/nbproject/Makefile-variables.mk +++ /dev/null @@ -1,27 +0,0 @@ -# -# Generated - do not edit! -# -# NOCDDL -# -CND_BASEDIR=`pwd` -# dbg configuration -CND_ARTIFACT_DIR_dbg=dist/dbg/production -CND_ARTIFACT_NAME_dbg=xc32.production.hex -CND_ARTIFACT_PATH_dbg=dist/dbg/production/xc32.production.hex -CND_PACKAGE_DIR_dbg=${CND_DISTDIR}/dbg/package -CND_PACKAGE_NAME_dbg=xc32.tar -CND_PACKAGE_PATH_dbg=${CND_DISTDIR}/dbg/package/xc32.tar -# rel configuration -CND_ARTIFACT_DIR_rel=dist/rel/production -CND_ARTIFACT_NAME_rel=xc32.production.hex -CND_ARTIFACT_PATH_rel=dist/rel/production/xc32.production.hex -CND_PACKAGE_DIR_rel=${CND_DISTDIR}/rel/package -CND_PACKAGE_NAME_rel=xc32.tar -CND_PACKAGE_PATH_rel=${CND_DISTDIR}/rel/package/xc32.tar -# spy configuration -CND_ARTIFACT_DIR_spy=dist/spy/production -CND_ARTIFACT_NAME_spy=xc32.production.hex -CND_ARTIFACT_PATH_spy=dist/spy/production/xc32.production.hex -CND_PACKAGE_DIR_spy=${CND_DISTDIR}/spy/package -CND_PACKAGE_NAME_spy=xc32.tar -CND_PACKAGE_PATH_spy=${CND_DISTDIR}/spy/package/xc32.tar diff --git a/examples/pic32/blinky_microstick2-pic32/qv/xc32/nbproject/Package-dbg.bash b/examples/pic32/blinky_microstick2-pic32/qv/xc32/nbproject/Package-dbg.bash deleted file mode 100644 index 29e2d1aa..00000000 --- a/examples/pic32/blinky_microstick2-pic32/qv/xc32/nbproject/Package-dbg.bash +++ /dev/null @@ -1,73 +0,0 @@ -#!/bin/bash -x - -# -# Generated - do not edit! -# - -# Macros -TOP=`pwd` -CND_CONF=dbg -CND_DISTDIR=dist -TMPDIR=build/${CND_CONF}/${IMAGE_TYPE}/tmp-packaging -TMPDIRNAME=tmp-packaging -OUTPUT_PATH=dist/${CND_CONF}/${IMAGE_TYPE}/xc32.${IMAGE_TYPE}.${OUTPUT_SUFFIX} -OUTPUT_BASENAME=xc32.${IMAGE_TYPE}.${OUTPUT_SUFFIX} -PACKAGE_TOP_DIR=xc32/ - -# Functions -function checkReturnCode -{ - rc=$? - if [ $rc != 0 ] - then - exit $rc - fi -} -function makeDirectory -# $1 directory path -# $2 permission (optional) -{ - mkdir -p "$1" - checkReturnCode - if [ "$2" != "" ] - then - chmod $2 "$1" - checkReturnCode - fi -} -function copyFileToTmpDir -# $1 from-file path -# $2 to-file path -# $3 permission -{ - cp "$1" "$2" - checkReturnCode - if [ "$3" != "" ] - then - chmod $3 "$2" - checkReturnCode - fi -} - -# Setup -cd "${TOP}" -mkdir -p ${CND_DISTDIR}/${CND_CONF}/package -rm -rf ${TMPDIR} -mkdir -p ${TMPDIR} - -# Copy files and create directories and links -cd "${TOP}" -makeDirectory ${TMPDIR}/xc32/bin -copyFileToTmpDir "${OUTPUT_PATH}" "${TMPDIR}/${PACKAGE_TOP_DIR}bin/${OUTPUT_BASENAME}" 0755 - - -# Generate tar file -cd "${TOP}" -rm -f ${CND_DISTDIR}/${CND_CONF}/package/xc32.tar -cd ${TMPDIR} -tar -vcf ../../../../${CND_DISTDIR}/${CND_CONF}/package/xc32.tar * -checkReturnCode - -# Cleanup -cd "${TOP}" -rm -rf ${TMPDIR} diff --git a/examples/pic32/blinky_microstick2-pic32/qv/xc32/nbproject/Package-rel.bash b/examples/pic32/blinky_microstick2-pic32/qv/xc32/nbproject/Package-rel.bash deleted file mode 100644 index 8e0fe709..00000000 --- a/examples/pic32/blinky_microstick2-pic32/qv/xc32/nbproject/Package-rel.bash +++ /dev/null @@ -1,73 +0,0 @@ -#!/bin/bash -x - -# -# Generated - do not edit! -# - -# Macros -TOP=`pwd` -CND_CONF=rel -CND_DISTDIR=dist -TMPDIR=build/${CND_CONF}/${IMAGE_TYPE}/tmp-packaging -TMPDIRNAME=tmp-packaging -OUTPUT_PATH=dist/${CND_CONF}/${IMAGE_TYPE}/xc32.${IMAGE_TYPE}.${OUTPUT_SUFFIX} -OUTPUT_BASENAME=xc32.${IMAGE_TYPE}.${OUTPUT_SUFFIX} -PACKAGE_TOP_DIR=xc32/ - -# Functions -function checkReturnCode -{ - rc=$? - if [ $rc != 0 ] - then - exit $rc - fi -} -function makeDirectory -# $1 directory path -# $2 permission (optional) -{ - mkdir -p "$1" - checkReturnCode - if [ "$2" != "" ] - then - chmod $2 "$1" - checkReturnCode - fi -} -function copyFileToTmpDir -# $1 from-file path -# $2 to-file path -# $3 permission -{ - cp "$1" "$2" - checkReturnCode - if [ "$3" != "" ] - then - chmod $3 "$2" - checkReturnCode - fi -} - -# Setup -cd "${TOP}" -mkdir -p ${CND_DISTDIR}/${CND_CONF}/package -rm -rf ${TMPDIR} -mkdir -p ${TMPDIR} - -# Copy files and create directories and links -cd "${TOP}" -makeDirectory ${TMPDIR}/xc32/bin -copyFileToTmpDir "${OUTPUT_PATH}" "${TMPDIR}/${PACKAGE_TOP_DIR}bin/${OUTPUT_BASENAME}" 0755 - - -# Generate tar file -cd "${TOP}" -rm -f ${CND_DISTDIR}/${CND_CONF}/package/xc32.tar -cd ${TMPDIR} -tar -vcf ../../../../${CND_DISTDIR}/${CND_CONF}/package/xc32.tar * -checkReturnCode - -# Cleanup -cd "${TOP}" -rm -rf ${TMPDIR} diff --git a/examples/pic32/blinky_microstick2-pic32/qv/xc32/nbproject/Package-spy.bash b/examples/pic32/blinky_microstick2-pic32/qv/xc32/nbproject/Package-spy.bash deleted file mode 100644 index e6524a8d..00000000 --- a/examples/pic32/blinky_microstick2-pic32/qv/xc32/nbproject/Package-spy.bash +++ /dev/null @@ -1,73 +0,0 @@ -#!/bin/bash -x - -# -# Generated - do not edit! -# - -# Macros -TOP=`pwd` -CND_CONF=spy -CND_DISTDIR=dist -TMPDIR=build/${CND_CONF}/${IMAGE_TYPE}/tmp-packaging -TMPDIRNAME=tmp-packaging -OUTPUT_PATH=dist/${CND_CONF}/${IMAGE_TYPE}/xc32.${IMAGE_TYPE}.${OUTPUT_SUFFIX} -OUTPUT_BASENAME=xc32.${IMAGE_TYPE}.${OUTPUT_SUFFIX} -PACKAGE_TOP_DIR=xc32/ - -# Functions -function checkReturnCode -{ - rc=$? - if [ $rc != 0 ] - then - exit $rc - fi -} -function makeDirectory -# $1 directory path -# $2 permission (optional) -{ - mkdir -p "$1" - checkReturnCode - if [ "$2" != "" ] - then - chmod $2 "$1" - checkReturnCode - fi -} -function copyFileToTmpDir -# $1 from-file path -# $2 to-file path -# $3 permission -{ - cp "$1" "$2" - checkReturnCode - if [ "$3" != "" ] - then - chmod $3 "$2" - checkReturnCode - fi -} - -# Setup -cd "${TOP}" -mkdir -p ${CND_DISTDIR}/${CND_CONF}/package -rm -rf ${TMPDIR} -mkdir -p ${TMPDIR} - -# Copy files and create directories and links -cd "${TOP}" -makeDirectory ${TMPDIR}/xc32/bin -copyFileToTmpDir "${OUTPUT_PATH}" "${TMPDIR}/${PACKAGE_TOP_DIR}bin/${OUTPUT_BASENAME}" 0755 - - -# Generate tar file -cd "${TOP}" -rm -f ${CND_DISTDIR}/${CND_CONF}/package/xc32.tar -cd ${TMPDIR} -tar -vcf ../../../../${CND_DISTDIR}/${CND_CONF}/package/xc32.tar * -checkReturnCode - -# Cleanup -cd "${TOP}" -rm -rf ${TMPDIR} diff --git a/examples/pic32/blinky_microstick2-pic32/qv/xc32/nbproject/configurations.xml b/examples/pic32/blinky_microstick2-pic32/qv/xc32/nbproject/configurations.xml deleted file mode 100644 index c74467f0..00000000 --- a/examples/pic32/blinky_microstick2-pic32/qv/xc32/nbproject/configurations.xml +++ /dev/null @@ -1,758 +0,0 @@ - - - - - bsp.h - dpp.h - - - - - ../../../../../src/qf/qep_hsm.c - ../../../../../src/qf/qep_msm.c - ../../../../../src/qf/qf_act.c - ../../../../../src/qf/qf_actq.c - ../../../../../src/qf/qf_defer.c - ../../../../../src/qf/qf_dyn.c - ../../../../../src/qf/qf_mem.c - ../../../../../src/qf/qf_ps.c - ../../../../../src/qf/qf_qact.c - ../../../../../src/qf/qf_qeq.c - ../../../../../src/qf/qf_qmact.c - ../../../../../src/qf/qf_time.c - ../../../../../src/qv/qv.c - - - ../../../../../src/qs/qs.c - ../../../../../src/qs/qs_64bit.c - ../../../../../src/qs/qs_fp.c - ../../../../../src/qs/qs_rx.c - - - bsp.c - ../../blinky.c - ../../blinky.h - ../../bsp.h - ../../main.c - ../../../../../include/qstamp.c - - - Makefile - - - - ../.. - ../../../../../src/qf - ../../../../../src/qv - ../../../../../include - ../../../../../src/qs - - Makefile - - - - localhost - PIC32MX250F128B - - - PKOBSKDEPlatformTool - XC32 - 2.20 - 3 - - - - - - - - - - - - - false - false - - - - - - - false - - false - - false - false - false - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - localhost - PIC32MX250F128B - - - PKOBSKDEPlatformTool - XC32 - 2.20 - 3 - - - - - - - - - - - - - false - false - - - - - - - false - - false - - false - false - false - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - localhost - PIC32MX250F128B - - - PKOBSKDEPlatformTool - XC32 - 2.20 - 3 - - - - - - - - - - - - - false - false - - - - - - - false - - false - - false - false - false - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/examples/pic32/blinky_microstick2-pic32/qv/xc32/nbproject/private/configurations.xml b/examples/pic32/blinky_microstick2-pic32/qv/xc32/nbproject/private/configurations.xml deleted file mode 100644 index c6a22c80..00000000 --- a/examples/pic32/blinky_microstick2-pic32/qv/xc32/nbproject/private/configurations.xml +++ /dev/null @@ -1,61 +0,0 @@ - - - Makefile - 0 - - - - C:\tools\Microchip\xc32\bin - - place holder 1 - place holder 2 - - - - - true - 0 - 0 - 0 - - - - - - :=MPLABComm-USB-Microchip:=<vid>04D8:=<pid>8107:=<rev>0002:=<man>Microchip Technology Incorporated:=<prod>Microstick II SK:=<sn>BUR123045184:=<drv>x:=<xpt>h:=end - C:\tools\Microchip\xc32\bin - - place holder 1 - place holder 2 - - - - - true - 0 - 0 - 0 - - - - - - :=MPLABCommUSB:=04D8:=8107:=0002:=Microchip Technology Incorporated:=Microstick II SK:=BUR123045184:=x:=en - C:\tools\Microchip\xc32\bin - - place holder 1 - place holder 2 - - - - - true - 0 - 0 - 0 - - - - - - diff --git a/examples/pic32/blinky_microstick2-pic32/qv/xc32/nbproject/private/private.properties b/examples/pic32/blinky_microstick2-pic32/qv/xc32/nbproject/private/private.properties deleted file mode 100644 index e69de29b..00000000 diff --git a/examples/pic32/blinky_microstick2-pic32/qv/xc32/nbproject/private/private.xml b/examples/pic32/blinky_microstick2-pic32/qv/xc32/nbproject/private/private.xml deleted file mode 100644 index cd3e03d7..00000000 --- a/examples/pic32/blinky_microstick2-pic32/qv/xc32/nbproject/private/private.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - diff --git a/examples/pic32/blinky_microstick2-pic32/qv/xc32/nbproject/project.properties b/examples/pic32/blinky_microstick2-pic32/qv/xc32/nbproject/project.properties deleted file mode 100644 index e69de29b..00000000 diff --git a/examples/pic32/blinky_microstick2-pic32/qv/xc32/nbproject/project.xml b/examples/pic32/blinky_microstick2-pic32/qv/xc32/nbproject/project.xml deleted file mode 100644 index a1a3833c..00000000 --- a/examples/pic32/blinky_microstick2-pic32/qv/xc32/nbproject/project.xml +++ /dev/null @@ -1,41 +0,0 @@ - - - com.microchip.mplab.nbide.embedded.makeproject - - - blinky-microstick2-pic32-qv - e9bbb168-4146-4fa4-b2f4-357b75b20ee3 - 0 - c - - h - ISO-8859-1 - - - - ../.. - ../../../../../src/qf - ../../../../../src/qv - ../../../../../include - ../../../../../src/qs - - - - dbg - 2 - - - rel - 2 - - - spy - 2 - - - - false - - - - diff --git a/examples/pic32/dpp_microstick2-pic32/bsp.h b/examples/pic32/dpp_microstick2-pic32/bsp.h index 302e1e8c..160743a5 100644 --- a/examples/pic32/dpp_microstick2-pic32/bsp.h +++ b/examples/pic32/dpp_microstick2-pic32/bsp.h @@ -1,47 +1,51 @@ -/***************************************************************************** -* Product: DPP example -* Last updated for version 6.5.1 -* Last updated on 2019-06-10 -* -* Q u a n t u m L e a P s -* ------------------------ -* Modern Embedded Software -* -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* -* -*****************************************************************************/ -#ifndef BSP_H -#define BSP_H +//============================================================================ +// Product: Board Support Package example +// Last Updated for Version: 7.3.0 +// Date of the Last Update: 2023-08-12 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. +// +// This program is open source software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Alternatively, this program may be distributed and modified under the +// terms of Quantum Leaps commercial licenses, which expressly supersede +// the GNU General Public License and are specifically designed for +// licensees interested in retaining the proprietary status of their code. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Contact information: +// +// +//============================================================================ +#ifndef BSP_H_ +#define BSP_H_ #define BSP_TICKS_PER_SEC 100U void BSP_init(void); +void BSP_start(void); void BSP_displayPaused(uint8_t paused); void BSP_displayPhilStat(uint8_t n, char const *stat); void BSP_terminate(int16_t result); -void BSP_randomSeed(uint32_t seed); /* random seed */ -uint32_t BSP_random(void); /* pseudo-random generator */ +void BSP_randomSeed(uint32_t seed); // random seed +uint32_t BSP_random(void); // pseudo-random generator -#endif /* BSP_H */ +void BSP_ledOn(void); +void BSP_ledOff(void); + +#endif // BSP_H_ diff --git a/examples/pic32/dpp_microstick2-pic32/dpp.h b/examples/pic32/dpp_microstick2-pic32/dpp.h index accb54d9..e6d1557a 100644 --- a/examples/pic32/dpp_microstick2-pic32/dpp.h +++ b/examples/pic32/dpp_microstick2-pic32/dpp.h @@ -1,85 +1,117 @@ -/*$file${.::dpp.h} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* -* Model: dpp.qm -* File: ${.::dpp.h} -* -* This code has been generated by QM 5.2.4 . -* DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. -* -* SPDX-License-Identifier: GPL-3.0-or-later -* -* This generated code is open source software: you can redistribute it under -* the terms of the GNU General Public License as published by the Free -* Software Foundation. -* -* This code is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -* more details. -* -* NOTE: -* Alternatively, this generated code may be distributed under the terms -* of Quantum Leaps commercial licenses, which expressly supersede the GNU -* General Public License and are specifically designed for licensees -* interested in retaining the proprietary status of their code. -* -* Contact information: -* -* -*/ -/*$endhead${.::dpp.h} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -#ifndef DPP_H -#define DPP_H +//$file${.::dpp.h} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// +// Model: dpp.qm +// File: ${.::dpp.h} +// +// This code has been generated by QM 5.3.0 . +// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. +// +// SPDX-License-Identifier: GPL-3.0-or-later +// +// This generated code is open source software: you can redistribute it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation. +// +// This code is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// NOTE: +// Alternatively, this generated code may be distributed under the terms +// of Quantum Leaps commercial licenses, which expressly supersede the GNU +// General Public License and are specifically designed for licensees +// interested in retaining the proprietary status of their code. +// +// Contact information: +// +// +// +//$endhead${.::dpp.h} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +#ifndef DPP_H_ +#define DPP_H_ -enum DPPSignals { - EAT_SIG = Q_USER_SIG, /* published by Table to let a philosopher eat */ - DONE_SIG, /* published by Philosopher when done eating */ - PAUSE_SIG, /* published by BSP to pause serving forks */ - SERVE_SIG, /* published by BSP to serve re-start serving forks */ - TERMINATE_SIG, /* published by BSP to terminate the application */ - MAX_PUB_SIG, /* the last published signal */ +//$declare${Shared} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv - HUNGRY_SIG, /* posted direclty to Table from hungry Philo */ - TIMEOUT_SIG, /* used by Philosophers for time events */ - MAX_SIG /* the last signal */ +//${Shared::AppSignals} ...................................................... +enum AppSignals { + EAT_SIG = Q_USER_SIG, // published by Table to let a Philo eat + DONE_SIG, // published by Philo when done eating + PAUSE_SIG, // published by BSP to pause the application + SERVE_SIG, // published by BSP to serve re-start serving forks + TEST_SIG, // published by BSP to test the application + MAX_PUB_SIG, // the last published signal + + TIMEOUT_SIG, // posted by time event to Philo + HUNGRY_SIG, // posted by hungry Philo to Table + MAX_SIG // the last signal }; -/*$declare${Events::TableEvt} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//${Shared::produce_sig_dict} ................................................ +#ifdef Q_SPY +static inline void produce_sig_dict(void) { + QS_SIG_DICTIONARY(EAT_SIG, (void *)0); + QS_SIG_DICTIONARY(DONE_SIG, (void *)0); + QS_SIG_DICTIONARY(PAUSE_SIG, (void *)0); + QS_SIG_DICTIONARY(SERVE_SIG, (void *)0); + QS_SIG_DICTIONARY(TEST_SIG, (void *)0); -/*${Events::TableEvt} ......................................................*/ + QS_SIG_DICTIONARY(TIMEOUT_SIG, (void *)0); + QS_SIG_DICTIONARY(HUNGRY_SIG, (void *)0); +} +#endif // def Q_SPY + +//${Shared::N_PHILO} ......................................................... +#define N_PHILO ((uint8_t)5U) + +//${Shared::TableEvt} ........................................................ typedef struct { -/* protected: */ +// protected: QEvt super; -/* public: */ - uint8_t philoNum; +// public: + uint8_t philoId; } TableEvt; -/*$enddecl${Events::TableEvt} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/* number of philosophers (only 2 Philos to save RAM! */ -#define N_PHILO ((uint8_t)2) +// public: -/*$declare${AOs::Philo_ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +#ifdef QEVT_DYN_CTOR +static inline TableEvt * TableEvt_ctor(TableEvt * const me, + uint8_t id) +{ + if (me != (TableEvt *)0) { + // don't call QEvt_ctor() because the initialization of all + // QEvt attributes is already done in QF_QF_newX_() + me->philoId = id; + } + return me; +} +#endif // def QEVT_DYN_CTOR -/*${AOs::Philo_ctor} .......................................................*/ -void Philo_ctor(void); -/*$enddecl${AOs::Philo_ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*$declare${AOs::Table_ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${AOs::Table_ctor} .......................................................*/ -void Table_ctor(void); -/*$enddecl${AOs::Table_ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ - -/*$declare${AOs::AO_Philo[N_PHILO]} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${AOs::AO_Philo[N_PHILO]} ................................................*/ +//${Shared::AO_Philo[N_PHILO]} ............................................... extern QActive * const AO_Philo[N_PHILO]; -/*$enddecl${AOs::AO_Philo[N_PHILO]} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*$declare${AOs::AO_Table} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/*${AOs::AO_Table} .........................................................*/ +//${Shared::Philo_ctor} ...................................................... +void Philo_ctor(uint_fast8_t const id); + +//${Shared::AO_Table} ........................................................ extern QActive * const AO_Table; -/*$enddecl${AOs::AO_Table} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -#endif /* DPP_H */ +//${Shared::Table_ctor} ...................................................... +void Table_ctor(void); +//$enddecl${Shared} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +#ifdef QXK_H_ + +extern QXThread * const TH_XThread1; +void XThread1_ctor(void); + +extern QXThread * const TH_XThread2; +void XThread2_ctor(void); + +extern QXSemaphore TH_sema; +extern QXMutex TH_mutex; + +#endif // QXK_H_ + +#endif // DPP_H_ diff --git a/examples/pic32/dpp_microstick2-pic32/dpp.qm b/examples/pic32/dpp_microstick2-pic32/dpp.qm index 67fd0f80..ac9f2bc9 100644 --- a/examples/pic32/dpp_microstick2-pic32/dpp.qm +++ b/examples/pic32/dpp_microstick2-pic32/dpp.qm @@ -1,132 +1,210 @@ - + Dining Philosopher Problem example - - - + + + + + { + EAT_SIG = Q_USER_SIG, // published by Table to let a Philo eat + DONE_SIG, // published by Philo when done eating + PAUSE_SIG, // published by BSP to pause the application + SERVE_SIG, // published by BSP to serve re-start serving forks + TEST_SIG, // published by BSP to test the application + MAX_PUB_SIG, // the last published signal + + TIMEOUT_SIG, // posted by time event to Philo + HUNGRY_SIG, // posted by hungry Philo to Table + MAX_SIG // the last signal +}; + + + + QS_SIG_DICTIONARY(EAT_SIG, (void *)0); +QS_SIG_DICTIONARY(DONE_SIG, (void *)0); +QS_SIG_DICTIONARY(PAUSE_SIG, (void *)0); +QS_SIG_DICTIONARY(SERVE_SIG, (void *)0); +QS_SIG_DICTIONARY(TEST_SIG, (void *)0); + +QS_SIG_DICTIONARY(TIMEOUT_SIG, (void *)0); +QS_SIG_DICTIONARY(HUNGRY_SIG, (void *)0); + + + + ((uint8_t)5U) + + - - + + + + + + + if (me != (TableEvt *)0) { + // don't call QEvt_ctor() because the initialization of all + // QEvt attributes is already done in QF_QF_newX_() + me->philoId = id; +} +return me; + + + + = { + &Philo_inst[0].super, + &Philo_inst[1].super, + &Philo_inst[2].super, + &Philo_inst[3].super, + &Philo_inst[4].super +}; + + + + + + Philo * const me = &Philo_inst[id]; +QActive_ctor(&me->super, Q_STATE_CAST(&Philo_initial)); +QTimeEvt_ctorX(&me->timeEvt, &me->super, TIMEOUT_SIG, 0U), +me->id = (uint8_t)id; + + + + = &Table_inst.super; + + + + Table * const me = &Table_inst; +QActive_ctor(&me->super, Q_STATE_CAST(&Table_initial)); +for (uint8_t n = 0U; n < N_PHILO; ++n) { + me->fork[n] = FREE; + me->isHungry[n] = false; +} + + The Philo AO and the N_PHILO instances + + + + - + - static uint8_t registered = (uint8_t)0; /* starts off with 0, per C-standard */ -(void)par; /* unused parameter */ -if (registered == (uint8_t)0) { - registered = (uint8_t)1; + Q_UNUSED_PAR(par); - QS_OBJ_DICTIONARY(&l_philo[0]); - QS_OBJ_DICTIONARY(&l_philo[0].timeEvt); - QS_OBJ_DICTIONARY(&l_philo[1]); - QS_OBJ_DICTIONARY(&l_philo[1].timeEvt); - //QS_OBJ_DICTIONARY(&l_philo[2]); - //QS_OBJ_DICTIONARY(&l_philo[2].timeEvt); - //QS_OBJ_DICTIONARY(&l_philo[3]); - //QS_OBJ_DICTIONARY(&l_philo[3].timeEvt); - //QS_OBJ_DICTIONARY(&l_philo[4]); - //QS_OBJ_DICTIONARY(&l_philo[4].timeEvt); +QS_OBJ_ARR_DICTIONARY(&Philo_inst[me->id], me->id); +QS_OBJ_ARR_DICTIONARY(&Philo_inst[me->id].timeEvt, me->id); - QS_FUN_DICTIONARY(&Philo_initial); - QS_FUN_DICTIONARY(&Philo_thinking); - QS_FUN_DICTIONARY(&Philo_hungry); - QS_FUN_DICTIONARY(&Philo_eating); -} -QS_SIG_DICTIONARY(HUNGRY_SIG, me); /* signal for each Philos */ -QS_SIG_DICTIONARY(TIMEOUT_SIG, me); /* signal for each Philos */ - -QActive_subscribe(&me->super, EAT_SIG); - +QActive_subscribe(&me->super, EAT_SIG); +QActive_subscribe(&me->super, TEST_SIG); + - QTimeEvt_armX(&me->timeEvt, THINK_TIME, 0U); + QTimeEvt_armX(&me->timeEvt, think_time(), 0U); + (void)QTimeEvt_disarm(&me->timeEvt); - - + + - /* EAT or DONE must be for other Philos than this one */ -Q_ASSERT(Q_EVT_CAST(TableEvt)->philoNum != PHILO_ID(me)); - + // EAT or DONE must be for other Philos than this one +Q_ASSERT(Q_EVT_CAST(TableEvt)->philoId != me->id); + - + + + + + + + + - TableEvt *pe = Q_NEW(TableEvt, HUNGRY_SIG); -pe->philoNum = PHILO_ID(me); -QACTIVE_POST(AO_Table, &pe->super, me); + #ifdef QEVT_DYN_CTOR +TableEvt const *pe = Q_NEW(TableEvt, HUNGRY_SIG, me->id); +#else +TableEvt *pe = Q_NEW(TableEvt, HUNGRY_SIG); +pe->philoId = me->id; +#endif +QACTIVE_POST(AO_Table, &pe->super, &me->super); - + - Q_EVT_CAST(TableEvt)->philoNum == PHILO_ID(me) - - + Q_EVT_CAST(TableEvt)->philoId == me->id + + - + - /* DONE must be for other Philos than this one */ -Q_ASSERT(Q_EVT_CAST(TableEvt)->philoNum != PHILO_ID(me)); - + // DONE must be for other Philos than this one +Q_ASSERT(Q_EVT_CAST(TableEvt)->philoId != me->id); + - + - QTimeEvt_armX(&me->timeEvt, EAT_TIME, 0U); - TableEvt *pe = Q_NEW(TableEvt, DONE_SIG); -pe->philoNum = PHILO_ID(me); + QTimeEvt_armX(&me->timeEvt, eat_time(), 0U); + (void)QTimeEvt_disarm(&me->timeEvt); + +#ifdef QEVT_DYN_CTOR +TableEvt const *pe = Q_NEW(TableEvt, DONE_SIG, me->id); +#else +TableEvt *pe = Q_NEW(TableEvt, DONE_SIG); +pe->philoId = me->id; +#endif QACTIVE_PUBLISH(&pe->super, &me->super); - - + + - /* EAT or DONE must be for other Philos than this one */ -Q_ASSERT(Q_EVT_CAST(TableEvt)->philoNum != PHILO_ID(me)); - + // EAT or DONE must be for other Philos than this one +Q_ASSERT(Q_EVT_CAST(TableEvt)->philoId != me->id); + - + - + @@ -134,164 +212,171 @@ Q_ASSERT(Q_EVT_CAST(TableEvt)->philoNum != PHILO_ID(me)); - + + + - + - (void)par; /* unused parameter */ + Q_UNUSED_PAR(par); -QS_OBJ_DICTIONARY(&l_table); - -QS_SIG_DICTIONARY(DONE_SIG, (void *)0); /* global signals */ -QS_SIG_DICTIONARY(EAT_SIG, (void *)0); -QS_SIG_DICTIONARY(PAUSE_SIG, (void *)0); -QS_SIG_DICTIONARY(SERVE_SIG, (void *)0); -QS_SIG_DICTIONARY(TERMINATE_SIG, (void *)0); - -QS_SIG_DICTIONARY(HUNGRY_SIG, me); /* signal just for Table */ +#ifdef Q_SPY +Table *Table_inst = me; +QS_OBJ_DICTIONARY(Table_inst); +#endif QActive_subscribe(&me->super, DONE_SIG); QActive_subscribe(&me->super, PAUSE_SIG); QActive_subscribe(&me->super, SERVE_SIG); -QActive_subscribe(&me->super, TERMINATE_SIG); +QActive_subscribe(&me->super, TEST_SIG); for (uint8_t n = 0U; n < N_PHILO; ++n) { me->fork[n] = FREE; - me->isHungry[n] = 0U; - BSP_displayPhilStat(n, "thinking"); + me->isHungry[n] = false; + BSP_displayPhilStat(n, THINKING); } - + - - - BSP_terminate(0); - + + + Q_ERROR(); - + - uint8_t n; -for (n = 0U; n < N_PHILO; ++n) { /* give permissions to eat... */ - if ((me->isHungry[n] != 0U) - && (me->fork[LEFT(n)] == FREE) + // give permissions to eat... +for (uint8_t n = 0U; n < N_PHILO; ++n) { + if (me->isHungry[n] + && (me->fork[left(n)] == FREE) && (me->fork[n] == FREE)) { - TableEvt *te; - - me->fork[LEFT(n)] = USED; + me->fork[left(n)] = USED; me->fork[n] = USED; - te = Q_NEW(TableEvt, EAT_SIG); - te->philoNum = n; - QACTIVE_PUBLISH(&te->super, &me->super); - me->isHungry[n] = 0U; - BSP_displayPhilStat(n, "eating "); +#ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, EAT_SIG, n); +#else + TableEvt *pe = Q_NEW(TableEvt, EAT_SIG); + pe->philoId = n; +#endif + QACTIVE_PUBLISH(&pe->super, &me->super); + me->isHungry[n] = false; + BSP_displayPhilStat(n, EATING); } } - uint8_t n, m; + uint8_t n = Q_EVT_CAST(TableEvt)->philoId; -n = Q_EVT_CAST(TableEvt)->philoNum; -/* phil ID must be in range and he must be not hungry */ -Q_ASSERT((n < N_PHILO) && (me->isHungry[n] == 0U)); +// phil ID must be in range and he must be not hungry +Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); -BSP_displayPhilStat(n, "hungry "); -m = LEFT(n); +BSP_displayPhilStat(n, HUNGRY); +uint8_t m = left(n); (me->fork[m] == FREE) && (me->fork[n] == FREE) - TableEvt *pe; -me->fork[m] = USED; + me->fork[m] = USED; me->fork[n] = USED; -pe = Q_NEW(TableEvt, EAT_SIG); -pe->philoNum = n; +#ifdef QEVT_DYN_CTOR +TableEvt const *pe = Q_NEW(TableEvt, EAT_SIG, n); +#else +TableEvt *pe = Q_NEW(TableEvt, EAT_SIG); +pe->philoId = n; +#endif QACTIVE_PUBLISH(&pe->super, &me->super); -BSP_displayPhilStat(n, "eating "); - +BSP_displayPhilStat(n, EATING); + else - me->isHungry[n] = 1U; - - + me->isHungry[n] = true; + + - + - uint8_t n, m; -TableEvt *pe; + uint8_t n = Q_EVT_CAST(TableEvt)->philoId; -n = Q_EVT_CAST(TableEvt)->philoNum; -/* phil ID must be in range and he must be not hungry */ -Q_ASSERT((n < N_PHILO) && (me->isHungry[n] == 0U)); +// phil ID must be in range and he must be not hungry +Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); -BSP_displayPhilStat(n, "thinking"); -m = LEFT(n); -/* both forks of Phil[n] must be used */ +BSP_displayPhilStat(n, THINKING); +uint8_t m = left(n); + +// both forks of Phil[n] must be used Q_ASSERT((me->fork[n] == USED) && (me->fork[m] == USED)); me->fork[m] = FREE; me->fork[n] = FREE; -m = RIGHT(n); /* check the right neighbor */ +m = right(n); // check the right neighbor -if ((me->isHungry[m] != 0U) && (me->fork[m] == FREE)) { +if (me->isHungry[m] && (me->fork[m] == FREE)) { me->fork[n] = USED; me->fork[m] = USED; - me->isHungry[m] = 0U; - pe = Q_NEW(TableEvt, EAT_SIG); - pe->philoNum = m; + me->isHungry[m] = false; +#ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, EAT_SIG, m); +#else + TableEvt *pe = Q_NEW(TableEvt, EAT_SIG); + pe->philoId = m; +#endif QACTIVE_PUBLISH(&pe->super, &me->super); - BSP_displayPhilStat(m, "eating "); + BSP_displayPhilStat(m, EATING); } -m = LEFT(n); /* check the left neighbor */ -n = LEFT(m); /* left fork of the left neighbor */ -if ((me->isHungry[m] != 0U) && (me->fork[n] == FREE)) { +m = left(n); // check the left neighbor +n = left(m); // left fork of the left neighbor +if (me->isHungry[m] && (me->fork[n] == FREE)) { me->fork[m] = USED; me->fork[n] = USED; - me->isHungry[m] = 0U; - pe = Q_NEW(TableEvt, EAT_SIG); - pe->philoNum = m; + me->isHungry[m] = false; +#ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, EAT_SIG, m); +#else + TableEvt *pe = Q_NEW(TableEvt, EAT_SIG); + pe->philoId = m; +#endif QACTIVE_PUBLISH(&pe->super, &me->super); - BSP_displayPhilStat(m, "eating "); + BSP_displayPhilStat(m, EATING); } - + Q_ERROR(); - + - + - + @@ -301,171 +386,140 @@ if ((me->isHungry[m] != 0U) && (me->fork[n] == FREE)) { BSP_displayPaused(0U); - + - uint8_t n = Q_EVT_CAST(TableEvt)->philoNum; -/* philo ID must be in range and he must be not hungry */ -Q_ASSERT((n < N_PHILO) && (me->isHungry[n] == 0U)); -me->isHungry[n] = 1U; -BSP_displayPhilStat(n, "hungry "); - + uint8_t n = Q_EVT_CAST(TableEvt)->philoId; + +// philo ID must be in range and he must be not hungry +Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); + +me->isHungry[n] = true; +BSP_displayPhilStat(n, HUNGRY); + - uint8_t n, m; + uint8_t n = Q_EVT_CAST(TableEvt)->philoId; -n = Q_EVT_CAST(TableEvt)->philoNum; -/* phil ID must be in range and he must be not hungry */ -Q_ASSERT((n < N_PHILO) && (me->isHungry[n] == 0U)); +// phil ID must be in range and he must be not hungry +Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); -BSP_displayPhilStat(n, "thinking"); -m = LEFT(n); -/* both forks of Phil[n] must be used */ +BSP_displayPhilStat(n, THINKING); +uint8_t m = left(n); + +// both forks of Phil[n] must be used Q_ASSERT((me->fork[n] == USED) && (me->fork[m] == USED)); me->fork[m] = FREE; me->fork[n] = FREE; - + - + - + - + - - - - - - - uint8_t n; -Philo *me; -for (n = 0U; n < N_PHILO; ++n) { - me = &l_philo[n]; - QActive_ctor(&me->super, Q_STATE_CAST(&Philo_initial)); - QTimeEvt_ctorX(&me->timeEvt, &me->super, TIMEOUT_SIG, 0U); -} - - - - uint8_t n; -Table *me = &l_table; - -QActive_ctor(&me->super, Q_STATE_CAST(&Table_initial)); - -for (n = 0U; n < N_PHILO; ++n) { - me->fork[n] = FREE; - me->isHungry[n] = 0U; -} - - #ifndef DPP_H -#define DPP_H + #ifndef DPP_H_ +#define DPP_H_ -enum DPPSignals { - EAT_SIG = Q_USER_SIG, /* published by Table to let a philosopher eat */ - DONE_SIG, /* published by Philosopher when done eating */ - PAUSE_SIG, /* published by BSP to pause serving forks */ - SERVE_SIG, /* published by BSP to serve re-start serving forks */ - TERMINATE_SIG, /* published by BSP to terminate the application */ - MAX_PUB_SIG, /* the last published signal */ +$declare ${Shared} - HUNGRY_SIG, /* posted direclty to Table from hungry Philo */ - TIMEOUT_SIG, /* used by Philosophers for time events */ - MAX_SIG /* the last signal */ -}; +#ifdef QXK_H_ -$declare(Events::TableEvt) +extern QXThread * const TH_XThread1; +void XThread1_ctor(void); -/* number of philosophers (only 2 Philos to save RAM! */ -#define N_PHILO ((uint8_t)2) +extern QXThread * const TH_XThread2; +void XThread2_ctor(void); -$declare(AOs::Philo_ctor) -$declare(AOs::Table_ctor) +extern QXSemaphore TH_sema; +extern QXMutex TH_mutex; -$declare(AOs::AO_Philo[N_PHILO]) -$declare(AOs::AO_Table) +#endif // QXK_H_ -#endif /* DPP_H */ - +#endif // DPP_H_ - #include "qpc.h" -#include "dpp.h" -#include "bsp.h" + #include "qpc.h" // QP/C real-time embedded framework +#include "dpp.h" // DPP Application interface +#include "bsp.h" // Board Support Package +$declare ${AOs::Philo} + +//---------------------------------------------------------------------------- Q_DEFINE_THIS_FILE -/* Active object class -----------------------------------------------------*/ -$declare(AOs::Philo) +// helper function to provide a randomized think time for Philos +static QTimeEvtCtr think_time(void); // prototype +static inline QTimeEvtCtr think_time(void) { + return (QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + + (BSP_TICKS_PER_SEC/2U)); +} -/* Local objects -----------------------------------------------------------*/ -static Philo l_philo[N_PHILO]; /* storage for all Philos */ +// helper function to provide a randomized eat time for Philos +static QTimeEvtCtr eat_time(void); // prototype +static inline QTimeEvtCtr eat_time(void) { + return (QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + + BSP_TICKS_PER_SEC); +} +//---------------------------------------------------------------------------- -#define THINK_TIME \ - (QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + (BSP_TICKS_PER_SEC/2U)) -#define EAT_TIME \ - (QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + BSP_TICKS_PER_SEC) - -/* helper macro to provide the ID of Philo "me_" */ -#define PHILO_ID(me_) ((uint8_t)((me_) - l_philo)) - -/* Global objects ----------------------------------------------------------*/ -QActive * const AO_Philo[N_PHILO] = { /* "opaque" pointers to Philo AO */ - &l_philo[0].super, - &l_philo[1].super, - //&l_philo[2].super, - //&l_philo[3].super, - //&l_philo[4].super -}; - -/* Philo definition --------------------------------------------------------*/ -$define(AOs::Philo_ctor) -$define(AOs::Philo) +$define ${Shared::Philo_ctor} +$define ${Shared::AO_Philo[N_PHILO]} +$define ${AOs::Philo} - #include "qpc.h" -#include "dpp.h" -#include "bsp.h" + #include "qpc.h" // QP/C real-time embedded framework +#include "dpp.h" // DPP Application interface +#include "bsp.h" // Board Support Package +$declare ${AOs::Table} + +//---------------------------------------------------------------------------- Q_DEFINE_THIS_FILE -/* Active object class -----------------------------------------------------*/ -$declare(AOs::Table) +// helper function to provide the RIGHT neighbor of a Philo[n] +static inline uint8_t right(uint8_t const n) { + return (uint8_t)((n + (N_PHILO - 1U)) % N_PHILO); +} -#define RIGHT(n_) ((uint8_t)(((n_) + (N_PHILO - 1U)) % N_PHILO)) -#define LEFT(n_) ((uint8_t)(((n_) + 1U) % N_PHILO)) -#define FREE ((uint8_t)0) -#define USED ((uint8_t)1) +// helper function to provide the LEFT neighbor of a Philo[n] +static inline uint8_t left(uint8_t const n) { + return (uint8_t)((n + 1U) % N_PHILO); +} -/* Local objects -----------------------------------------------------------*/ -static Table l_table; /* the single instance of the Table active object */ +#define FREE ((uint8_t)0U) +#define USED ((uint8_t)1U) -/* Global-scope objects ----------------------------------------------------*/ -QActive * const AO_Table = &l_table.super; /* "opaque" AO pointer */ +#define THINKING "thinking" +#define HUNGRY "hungry " +#define EATING "eating " -/*..........................................................................*/ -$define(AOs::Table_ctor) -$define(AOs::Table) +//---------------------------------------------------------------------------- + +$define ${Shared::Table_ctor} +$define ${Shared::AO_Table} +$define ${AOs::Table} diff --git a/examples/pic32/dpp_microstick2-pic32/main.c b/examples/pic32/dpp_microstick2-pic32/main.c index 7047b71b..deac175a 100644 --- a/examples/pic32/dpp_microstick2-pic32/main.c +++ b/examples/pic32/dpp_microstick2-pic32/main.c @@ -1,80 +1,44 @@ -/***************************************************************************** -* Product: DPP example -* Last updated for version 6.4.0 -* Last updated on 2019-02-08 -* -* Q u a n t u m L e a P s -* ------------------------ -* Modern Embedded Software -* -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* -* -*****************************************************************************/ -#include "qpc.h" -#include "dpp.h" -#include "bsp.h" +//============================================================================ +// APP example +// Last updated for version 7.3.0 +// Last updated on 2023-08-09 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. +// +// This program is open source software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Alternatively, this program may be distributed and modified under the +// terms of Quantum Leaps commercial licenses, which expressly supersede +// the GNU General Public License and are specifically designed for +// licensees interested in retaining the proprietary status of their code. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Contact information: +// +// +//============================================================================ +#include "qpc.h" // QP/C real-time embedded framework +#include "dpp.h" // DPP Application interface +#include "bsp.h" // Board Support Package -Q_DEFINE_THIS_FILE - -/*..........................................................................*/ +//............................................................................ int main() { - static QEvt const *tableQueueSto[N_PHILO]; - static QEvt const *philoQueueSto[N_PHILO][N_PHILO]; - static QSubscrList subscrSto[MAX_PUB_SIG]; - static QF_MPOOL_EL(TableEvt) smlPoolSto[2*N_PHILO]; /* small pool */ - uint8_t n; - - Philo_ctor(); /* instantiate all Philosopher active objects */ - Table_ctor(); /* instantiate the Table active object */ - - QF_init(); /* initialize the framework and the underlying RT kernel */ - BSP_init(); /* initialize the Board Support Package */ - - /* initialize publish-subscribe... */ - QF_psInit(subscrSto, Q_DIM(subscrSto)); - - /* initialize event pools... */ - QF_poolInit(smlPoolSto, sizeof(smlPoolSto), sizeof(smlPoolSto[0])); - - /* start the active objects... */ - for (n = 0U; n < N_PHILO; ++n) { - QACTIVE_START(AO_Philo[n], /* AO to start */ - (uint_fast8_t)(n + 1), /* QP priority of the AO */ - philoQueueSto[n], /* event queue storage */ - Q_DIM(philoQueueSto[n]), /* queue length [events] */ - (void *)0, /* stack storage (not used) */ - 0U, /* size of the stack [bytes] */ - (QEvt *)0); /* initialization event */ - } - QACTIVE_START(AO_Table, /* AO to start */ - (uint_fast8_t)(N_PHILO + 1), /* QP priority of the AO */ - tableQueueSto, /* event queue storage */ - Q_DIM(tableQueueSto), /* queue length [events] */ - (void *)0, /* stack storage (not used) */ - 0U, /* size of the stack [bytes] */ - (QEvt *)0); /* initialization event */ - - return QF_run(); /* run the QF application */ + QF_init(); // initialize the framework and the underlying RT kernel + BSP_init(); // initialize the BSP + BSP_start(); // start the AOs/Threads + return QF_run(); // run the QF application } - diff --git a/examples/pic32/dpp_microstick2-pic32/philo.c b/examples/pic32/dpp_microstick2-pic32/philo.c index fa689f8b..eb6be531 100644 --- a/examples/pic32/dpp_microstick2-pic32/philo.c +++ b/examples/pic32/dpp_microstick2-pic32/philo.c @@ -1,154 +1,160 @@ -/*$file${.::philo.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* -* Model: dpp.qm -* File: ${.::philo.c} -* -* This code has been generated by QM 5.2.4 . -* DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. -* -* SPDX-License-Identifier: GPL-3.0-or-later -* -* This generated code is open source software: you can redistribute it under -* the terms of the GNU General Public License as published by the Free -* Software Foundation. -* -* This code is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -* more details. -* -* NOTE: -* Alternatively, this generated code may be distributed under the terms -* of Quantum Leaps commercial licenses, which expressly supersede the GNU -* General Public License and are specifically designed for licensees -* interested in retaining the proprietary status of their code. -* -* Contact information: -* -* -*/ -/*$endhead${.::philo.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -#include "qpc.h" -#include "dpp.h" -#include "bsp.h" +//$file${.::philo.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// +// Model: dpp.qm +// File: ${.::philo.c} +// +// This code has been generated by QM 5.3.0 . +// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. +// +// SPDX-License-Identifier: GPL-3.0-or-later +// +// This generated code is open source software: you can redistribute it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation. +// +// This code is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// NOTE: +// Alternatively, this generated code may be distributed under the terms +// of Quantum Leaps commercial licenses, which expressly supersede the GNU +// General Public License and are specifically designed for licensees +// interested in retaining the proprietary status of their code. +// +// Contact information: +// +// +// +//$endhead${.::philo.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +#include "qpc.h" // QP/C real-time embedded framework +#include "dpp.h" // DPP Application interface +#include "bsp.h" // Board Support Package -Q_DEFINE_THIS_FILE +//$declare${AOs::Philo} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/* Active object class -----------------------------------------------------*/ -/*$declare${AOs::Philo} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${AOs::Philo} ............................................................*/ -typedef struct { -/* protected: */ +//${AOs::Philo} .............................................................. +typedef struct Philo { +// protected: QActive super; -/* private: */ +// private: QTimeEvt timeEvt; + uint8_t id; + +// public: } Philo; -/* protected: */ +extern Philo Philo_inst[N_PHILO]; + +// protected: static QState Philo_initial(Philo * const me, void const * const par); static QState Philo_thinking(Philo * const me, QEvt const * const e); static QState Philo_hungry(Philo * const me, QEvt const * const e); static QState Philo_eating(Philo * const me, QEvt const * const e); -/*$enddecl${AOs::Philo} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$enddecl${AOs::Philo} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -/* Local objects -----------------------------------------------------------*/ -static Philo l_philo[N_PHILO]; /* storage for all Philos */ +//---------------------------------------------------------------------------- +Q_DEFINE_THIS_FILE -#define THINK_TIME \ - (QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + (BSP_TICKS_PER_SEC/2U)) -#define EAT_TIME \ - (QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + BSP_TICKS_PER_SEC) - -/* helper macro to provide the ID of Philo "me_" */ -#define PHILO_ID(me_) ((uint8_t)((me_) - l_philo)) - -/* Global objects ----------------------------------------------------------*/ -QActive * const AO_Philo[N_PHILO] = { /* "opaque" pointers to Philo AO */ - &l_philo[0].super, - &l_philo[1].super, - //&l_philo[2].super, - //&l_philo[3].super, - //&l_philo[4].super -}; - -/* Philo definition --------------------------------------------------------*/ -/*$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* Check for the minimum required QP version */ -#if (QP_VERSION < 700U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) -#error qpc version 7.0.0 or higher required -#endif -/*$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ - -/*$define${AOs::Philo_ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${AOs::Philo_ctor} .......................................................*/ -void Philo_ctor(void) { - uint8_t n; - Philo *me; - for (n = 0U; n < N_PHILO; ++n) { - me = &l_philo[n]; - QActive_ctor(&me->super, Q_STATE_CAST(&Philo_initial)); - QTimeEvt_ctorX(&me->timeEvt, &me->super, TIMEOUT_SIG, 0U); - } +// helper function to provide a randomized think time for Philos +static QTimeEvtCtr think_time(void); // prototype +static inline QTimeEvtCtr think_time(void) { + return (QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + + (BSP_TICKS_PER_SEC/2U)); } -/*$enddef${AOs::Philo_ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*$define${AOs::Philo} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/*${AOs::Philo} ............................................................*/ +// helper function to provide a randomized eat time for Philos +static QTimeEvtCtr eat_time(void); // prototype +static inline QTimeEvtCtr eat_time(void) { + return (QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + + BSP_TICKS_PER_SEC); +} +//---------------------------------------------------------------------------- -/*${AOs::Philo::SM} ........................................................*/ +//$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// Check for the minimum required QP version +#if (QP_VERSION < 730U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) +#error qpc version 7.3.0 or higher required +#endif +//$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +//$define${Shared::Philo_ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${Shared::Philo_ctor} ...................................................... +void Philo_ctor(uint_fast8_t const id) { + Philo * const me = &Philo_inst[id]; + QActive_ctor(&me->super, Q_STATE_CAST(&Philo_initial)); + QTimeEvt_ctorX(&me->timeEvt, &me->super, TIMEOUT_SIG, 0U), + me->id = (uint8_t)id; +} +//$enddef${Shared::Philo_ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +//$define${Shared::AO_Philo[N_PHILO]} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${Shared::AO_Philo[N_PHILO]} ............................................... +QActive * const AO_Philo[N_PHILO] = { + &Philo_inst[0].super, + &Philo_inst[1].super, + &Philo_inst[2].super, + &Philo_inst[3].super, + &Philo_inst[4].super +}; +//$enddef${Shared::AO_Philo[N_PHILO]} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +//$define${AOs::Philo} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${AOs::Philo} .............................................................. +Philo Philo_inst[N_PHILO]; + +//${AOs::Philo::SM} .......................................................... static QState Philo_initial(Philo * const me, void const * const par) { - /*${AOs::Philo::SM::initial} */ - static uint8_t registered = (uint8_t)0; /* starts off with 0, per C-standard */ - (void)par; /* unused parameter */ - if (registered == (uint8_t)0) { - registered = (uint8_t)1; + //${AOs::Philo::SM::initial} + Q_UNUSED_PAR(par); - QS_OBJ_DICTIONARY(&l_philo[0]); - QS_OBJ_DICTIONARY(&l_philo[0].timeEvt); - QS_OBJ_DICTIONARY(&l_philo[1]); - QS_OBJ_DICTIONARY(&l_philo[1].timeEvt); - //QS_OBJ_DICTIONARY(&l_philo[2]); - //QS_OBJ_DICTIONARY(&l_philo[2].timeEvt); - //QS_OBJ_DICTIONARY(&l_philo[3]); - //QS_OBJ_DICTIONARY(&l_philo[3].timeEvt); - //QS_OBJ_DICTIONARY(&l_philo[4]); - //QS_OBJ_DICTIONARY(&l_philo[4].timeEvt); - - QS_FUN_DICTIONARY(&Philo_initial); - QS_FUN_DICTIONARY(&Philo_thinking); - QS_FUN_DICTIONARY(&Philo_hungry); - QS_FUN_DICTIONARY(&Philo_eating); - } - QS_SIG_DICTIONARY(HUNGRY_SIG, me); /* signal for each Philos */ - QS_SIG_DICTIONARY(TIMEOUT_SIG, me); /* signal for each Philos */ + QS_OBJ_ARR_DICTIONARY(&Philo_inst[me->id], me->id); + QS_OBJ_ARR_DICTIONARY(&Philo_inst[me->id].timeEvt, me->id); QActive_subscribe(&me->super, EAT_SIG); + QActive_subscribe(&me->super, TEST_SIG); + + QS_FUN_DICTIONARY(&Philo_thinking); + QS_FUN_DICTIONARY(&Philo_hungry); + QS_FUN_DICTIONARY(&Philo_eating); + return Q_TRAN(&Philo_thinking); } -/*${AOs::Philo::SM::thinking} ..............................................*/ +//${AOs::Philo::SM::thinking} ................................................ static QState Philo_thinking(Philo * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${AOs::Philo::SM::thinking} */ + //${AOs::Philo::SM::thinking} case Q_ENTRY_SIG: { - QTimeEvt_armX(&me->timeEvt, THINK_TIME, 0U); + QTimeEvt_armX(&me->timeEvt, think_time(), 0U); status_ = Q_HANDLED(); break; } - /*${AOs::Philo::SM::thinking::TIMEOUT} */ + //${AOs::Philo::SM::thinking} + case Q_EXIT_SIG: { + (void)QTimeEvt_disarm(&me->timeEvt); + status_ = Q_HANDLED(); + break; + } + //${AOs::Philo::SM::thinking::TIMEOUT} case TIMEOUT_SIG: { status_ = Q_TRAN(&Philo_hungry); break; } - /*${AOs::Philo::SM::thinking::EAT, DONE} */ - case EAT_SIG: /* intentionally fall through */ + //${AOs::Philo::SM::thinking::EAT, DONE} + case EAT_SIG: // intentionally fall through case DONE_SIG: { - /* EAT or DONE must be for other Philos than this one */ - Q_ASSERT(Q_EVT_CAST(TableEvt)->philoNum != PHILO_ID(me)); + // EAT or DONE must be for other Philos than this one + Q_ASSERT(Q_EVT_CAST(TableEvt)->philoId != me->id); + status_ = Q_HANDLED(); + break; + } + //${AOs::Philo::SM::thinking::TEST} + case TEST_SIG: { status_ = Q_HANDLED(); break; } @@ -160,22 +166,26 @@ static QState Philo_thinking(Philo * const me, QEvt const * const e) { return status_; } -/*${AOs::Philo::SM::hungry} ................................................*/ +//${AOs::Philo::SM::hungry} .................................................. static QState Philo_hungry(Philo * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${AOs::Philo::SM::hungry} */ + //${AOs::Philo::SM::hungry} case Q_ENTRY_SIG: { + #ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, HUNGRY_SIG, me->id); + #else TableEvt *pe = Q_NEW(TableEvt, HUNGRY_SIG); - pe->philoNum = PHILO_ID(me); - QACTIVE_POST(AO_Table, &pe->super, me); + pe->philoId = me->id; + #endif + QACTIVE_POST(AO_Table, &pe->super, &me->super); status_ = Q_HANDLED(); break; } - /*${AOs::Philo::SM::hungry::EAT} */ + //${AOs::Philo::SM::hungry::EAT} case EAT_SIG: { - /*${AOs::Philo::SM::hungry::EAT::[Q_EVT_CAST(TableEvt)->philoNum=~} */ - if (Q_EVT_CAST(TableEvt)->philoNum == PHILO_ID(me)) { + //${AOs::Philo::SM::hungry::EAT::[e->philoId==me->iid]} + if (Q_EVT_CAST(TableEvt)->philoId == me->id) { status_ = Q_TRAN(&Philo_eating); } else { @@ -183,10 +193,10 @@ static QState Philo_hungry(Philo * const me, QEvt const * const e) { } break; } - /*${AOs::Philo::SM::hungry::DONE} */ + //${AOs::Philo::SM::hungry::DONE} case DONE_SIG: { - /* DONE must be for other Philos than this one */ - Q_ASSERT(Q_EVT_CAST(TableEvt)->philoNum != PHILO_ID(me)); + // DONE must be for other Philos than this one + Q_ASSERT(Q_EVT_CAST(TableEvt)->philoId != me->id); status_ = Q_HANDLED(); break; } @@ -198,34 +208,40 @@ static QState Philo_hungry(Philo * const me, QEvt const * const e) { return status_; } -/*${AOs::Philo::SM::eating} ................................................*/ +//${AOs::Philo::SM::eating} .................................................. static QState Philo_eating(Philo * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${AOs::Philo::SM::eating} */ + //${AOs::Philo::SM::eating} case Q_ENTRY_SIG: { - QTimeEvt_armX(&me->timeEvt, EAT_TIME, 0U); + QTimeEvt_armX(&me->timeEvt, eat_time(), 0U); status_ = Q_HANDLED(); break; } - /*${AOs::Philo::SM::eating} */ + //${AOs::Philo::SM::eating} case Q_EXIT_SIG: { + (void)QTimeEvt_disarm(&me->timeEvt); + + #ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, DONE_SIG, me->id); + #else TableEvt *pe = Q_NEW(TableEvt, DONE_SIG); - pe->philoNum = PHILO_ID(me); + pe->philoId = me->id; + #endif QACTIVE_PUBLISH(&pe->super, &me->super); status_ = Q_HANDLED(); break; } - /*${AOs::Philo::SM::eating::TIMEOUT} */ + //${AOs::Philo::SM::eating::TIMEOUT} case TIMEOUT_SIG: { status_ = Q_TRAN(&Philo_thinking); break; } - /*${AOs::Philo::SM::eating::EAT, DONE} */ - case EAT_SIG: /* intentionally fall through */ + //${AOs::Philo::SM::eating::EAT, DONE} + case EAT_SIG: // intentionally fall through case DONE_SIG: { - /* EAT or DONE must be for other Philos than this one */ - Q_ASSERT(Q_EVT_CAST(TableEvt)->philoNum != PHILO_ID(me)); + // EAT or DONE must be for other Philos than this one + Q_ASSERT(Q_EVT_CAST(TableEvt)->philoId != me->id); status_ = Q_HANDLED(); break; } @@ -236,4 +252,4 @@ static QState Philo_eating(Philo * const me, QEvt const * const e) { } return status_; } -/*$enddef${AOs::Philo} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$enddef${AOs::Philo} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/examples/pic32/dpp_microstick2-pic32/qk/xc32/bsp.c b/examples/pic32/dpp_microstick2-pic32/qk/xc32/bsp.c index f0c9d6af..bf9e098f 100644 --- a/examples/pic32/dpp_microstick2-pic32/qk/xc32/bsp.c +++ b/examples/pic32/dpp_microstick2-pic32/qk/xc32/bsp.c @@ -1,274 +1,387 @@ -/***************************************************************************** -* BSP for DPP example, Microstick II board, preemptive QK kernel, XC32 -* Last updated for version 6.9.1 -* Last updated on 2020-09-22 -* -* Q u a n t u m L e a P s -* ------------------------ -* Modern Embedded Software -* -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* -* -*****************************************************************************/ -#include "qpc.h" -#include "bsp.h" -#include "dpp.h" +//============================================================================ +// BSP for DPP example, Microstick II board, preemptive QK kernel, XC32 +// Last updated for version 7.3.0 +// Last updated on 2023-08-21 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. +// +// This program is open source software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Alternatively, this program may be distributed and modified under the +// terms of Quantum Leaps commercial licenses, which expressly supersede +// the GNU General Public License and are specifically designed for +// licensees interested in retaining the proprietary status of their code. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Contact information: +// +// +//============================================================================ +#include "qpc.h" // QP/C real-time embedded framework +#include "dpp.h" // DPP Application interface +#include "bsp.h" // Board Support Package Q_DEFINE_THIS_FILE -#pragma config FNOSC = FRCPLL /* 8 MHz */ -#pragma config FPLLIDIV = DIV_2 /* 4 MHz */ -#pragma config FPLLMUL = MUL_20 /* 80 MHz */ -#pragma config FPLLODIV = DIV_2 /* 40 MHz == FRC */ -#pragma config FWDTEN = OFF /* watchdog off */ -#pragma config FPBDIV = DIV_1 /* same peripheral clock */ +#pragma config FNOSC = FRCPLL // 8 MHz +#pragma config FPLLIDIV = DIV_2 // 4 MHz +#pragma config FPLLMUL = MUL_20 // 80 MHz +#pragma config FPLLODIV = DIV_2 // 40 MHz == FRC +#pragma config FWDTEN = OFF // watchdog off +#pragma config FPBDIV = DIV_1 // same peripheral clock -/* #pragma config statements should precede project file includes */ -#include /* header for PIC32 device in use */ +// #pragma config statements should precede project file includes +#include // header for PIC32 device in use #include -/* system clock using FRC and PLL: 40 MHz */ +// system clock using FRC and PLL: 40 MHz #define SYS_FREQ 40000000U -/* peripheral clock frequency */ +// peripheral clock frequency #define PER_HZ (SYS_FREQ / 1U) -/* controlling the LED of Microstick II */ -#define LED_ON() (LATASET = (1U << 0)) -#define LED_OFF() (LATACLR = (1U << 0)) -#define LED_TOGGLE() (LATAINV = (1U << 0)) +// controlling the LED of Microstick II +#define LED_ON() (LATASET = (1U << 0U)) +#define LED_OFF() (LATACLR = (1U << 0U)) +#define LED_TOGGLE() (LATAINV = (1U << 0U)) -/* Local-scope objects -----------------------------------------------------*/ -static uint32_t l_rnd; /* random seed */ +// Local-scope objects ----------------------------------------------------- +static uint32_t l_rndSeed; #ifdef Q_SPY - static uint8_t const l_tickISR = 0U; - static uint8_t const l_testISR = 0U; + // QSpy source IDs + static QSpyId const l_tickISR = {0U}; + static QSpyId const l_testISR = {0U}; - enum AppRecords { /* application-specific trace records */ - PHILO_STAT = QS_USER + enum AppRecords { // application-specific trace records + PHILO_STAT = QS_USER, + PAUSED_STAT, + CONTEXT_SW, }; -#endif +#endif // Q_SPY -/* ISRs --------------------------------------------------------------------*/ -void __ISR(_TIMER_2_VECTOR, IPL4SOFT) tickISR(void) { - QK_ISR_ENTRY(); /* inform QK about the ISR entry */ +//============================================================================ +// Error handler and ISRs... - IFS0CLR = _IFS0_T2IF_MASK; /* clear the interrupt source */ +Q_NORETURN Q_onError(char const * const module, int_t const id) { + // NOTE: this implementation of the error handler is intended only + // for debugging and MUST be changed for deployment of the application + // (assuming that you ship your production code with assertions enabled). + Q_UNUSED_PAR(module); + Q_UNUSED_PAR(id); + QS_ASSERTION(module, id, 10000U); // report assertion to QS - QTIMEEVT_TICK_X(0U, &l_tickISR); /* handle armed time events at tick rate 0 */ - - QK_ISR_EXIT(); /* inform QK about the ISR exit */ -} -/*..........................................................................*/ -/* for testing interrupt nesting and active object preemption */ -void __ISR(_EXTERNAL_0_VECTOR, IPL6SOFT) testISR(void) { - static QEvt const eat_evt = { EAT_SIG, 0U, 0U }; - - QK_ISR_ENTRY(); /* inform QK about the ISR entry */ - - IFS0CLR = _IFS0_INT0IF_MASK; /* clear the interrupt source */ - - QACTIVE_POST(AO_Table, &eat_evt, &l_testISR); - - QK_ISR_EXIT(); /* inform QK about the ISR exit */ -} - -/*--------------------------------------------------------------------------*/ -void BSP_init(void) { - TRISA = 0x00; /* set LED pins as outputs */ - PORTA = 0x00; /* set LED drive state low */ - - BSP_randomSeed(1234U); - - Q_ALLEGE(QS_INIT((void *)0) != 0); /*initialize the QS software tracing */ - QS_OBJ_DICTIONARY(&l_tickISR); - QS_OBJ_DICTIONARY(&l_testISR); - - /* setup the QS filters... */ - QS_GLB_FILTER(QS_SM_RECORDS); /* state machine records */ - QS_GLB_FILTER(QS_AO_RECORDS); /* active object records */ - QS_GLB_FILTER(QS_UA_RECORDS); /* all user records */ -} -/*..........................................................................*/ -void BSP_terminate(int16_t result) { - (void)result; -} -/*..........................................................................*/ -void BSP_displayPhilStat(uint8_t const n, char const *stat) { - (void)n; - (void)stat; - LED_TOGGLE(); - - QS_BEGIN_ID(PHILO_STAT, AO_Philo[n]->prio) /* app-specific record */ - QS_U8(1, n); /* Philosopher number */ - QS_STR(stat); /* Philosopher status */ - QS_END() -} -/*..........................................................................*/ -void BSP_displayPaused(uint8_t const paused) { - (void)paused; -} -/*..........................................................................*/ -uint32_t BSP_random(void) { /* a cheap pseudo-random-number generator */ - /* "Super-Duper" Linear Congruential Generator (LCG) - * LCG(2^32, 3*7*11*13*23, 0, seed) - */ - l_rnd = l_rnd * (3U*7U*11U*13U*23U); - return l_rnd >> 8; -} -/*..........................................................................*/ -void BSP_randomSeed(uint32_t seed) { - l_rnd = seed; -} -/*..........................................................................*/ -/* NOTE: this implementation of the assertion handler is intended only for -* debugging and MUST be changed for deployment of the application (assuming -* that you ship your production code with assertions enabled). -*/ -Q_NORETURN Q_onAssert(char const * const file, int_t const loc) { - (void)file; /* unused parameter */ - (void)loc; /* unused parameter */ - QF_INT_DISABLE(); /* make sure that interrupts are disabled */ +#ifndef NDEBUG + // for debugging, hang on in an endless loop... for (;;) { } +#else + // perform a system unlock sequence ,starting critical sequence + SYSKEY = 0x00000000U; //write invalid key to force lock + SYSKEY = 0xAA996655U; //write key1 to SYSKEY + SYSKEY = 0x556699AAU; //write key2 to SYSKEY + // set SWRST bit to arm reset + RSWRSTSET = 1U; + // read RSWRST register to trigger reset + uint32_t volatile dummy = RSWRST; + for (;;) { // explicitly "no-return" + } +#endif +} +//............................................................................ +void assert_failed(char const * const module, int_t const id); // prototype +void assert_failed(char const * const module, int_t const id) { + Q_onError(module, id); } -/*..........................................................................*/ -void QF_onStartup(void) { /* entered with interrupts locked */ - INTCONSET = _INTCON_MVEC_MASK; /* configure multi-vectored interrupts */ +// ISRs -------------------------------------------------------------------- +void __ISR(_TIMER_2_VECTOR, IPL4SOFT) tickISR(void) { + QK_ISR_ENTRY(); // inform QK about the ISR entry - T2CON = 0x0060; /* stop timer, set up for 1:64 prescaler */ - TMR2 = 0; /* count from zero up to the period */ - PR2 = SYS_FREQ / (BSP_TICKS_PER_SEC * 64); /* set the Timer2 period */ - IFS0CLR = _IFS0_T2IF_MASK; /* clear Timer2 Interrupt Flag */ - IEC0SET = _IEC0_T2IE_MASK; /* enable Timer2 interrupt */ - T2CONSET = _T2CON_ON_MASK; /* Start Timer2 */ + IFS0CLR = _IFS0_T2IF_MASK; // clear the interrupt source - INTCONbits.INT0EP = 1; /* INT0 interrupt on positive edge */ - IEC0SET = _IEC0_INT0IE_MASK; /* enable INT0 interrupt */ - IFS0CLR = _IFS0_INT0IF_MASK; /* clear the interrupt for INT0 */ + QTIMEEVT_TICK_X(0U, &l_tickISR); // handle time events at tick rate 0 - /* explicitly assign priorities to all interrupts... */ - /* NOTE: must match the IPLxSOFT settings in the __ISR() macros */ - IPC2bits.T2IP = 4; /* Timer2 interrupt priority, must match tickISR */ - IPC0bits.INT0IP = 6; /* set INT0 priority; must match IPL in testISR */ + QK_ISR_EXIT(); // inform QK about the ISR exit } -/*..........................................................................*/ +//............................................................................ +// for testing interrupt nesting and active object preemption +void __ISR(_EXTERNAL_0_VECTOR, IPL6SOFT) testISR(void) { + QK_ISR_ENTRY(); // inform QK about the ISR entry + + IFS0CLR = _IFS0_INT0IF_MASK; // clear the interrupt source + + static QEvt const eat_evt = QEVT_INITIALIZER(EAT_SIG); + QACTIVE_POST(AO_Table, &eat_evt, &l_testISR); + + QK_ISR_EXIT(); // inform QK about the ISR exit +} +//............................................................................ +#ifdef QF_ON_CONTEXT_SW +// NOTE: the context-switch callback is called with interrupts DISABLED +void QF_onContextSw(QActive *prev, QActive *next) { + QS_BEGIN_INCRIT(CONTEXT_SW, 0U) // in critical section! + QS_OBJ(prev); + QS_OBJ(next); + QS_END_INCRIT() +} +#endif // QF_ON_CONTEXT_SW + + +// BSP functions ============================================================= + +void BSP_init(void) { + TRISA = 0x00U; // set LED pins as outputs + PORTA = 0x00U; // set LED drive state low + + BSP_randomSeed(1234U); // seed the random number generator + + // initialize the QS software tracing + if (!QS_INIT((void *)0)) { + Q_ERROR(); + } + + // dictionaries... + QS_OBJ_DICTIONARY(&l_tickISR); + QS_OBJ_DICTIONARY(&l_testISR); + QS_USR_DICTIONARY(PHILO_STAT); + QS_USR_DICTIONARY(PAUSED_STAT); + QS_USR_DICTIONARY(CONTEXT_SW); + + QS_ONLY(produce_sig_dict()); + + // setup the QS filters... + QS_GLB_FILTER(QS_ALL_RECORDS); // all records + QS_GLB_FILTER(-QS_QF_TICK); // exclude the clock tick +} +//............................................................................ +void BSP_start(void) { + // initialize event pools + static QF_MPOOL_EL(TableEvt) smlPoolSto[2*N_PHILO]; + QF_poolInit(smlPoolSto, sizeof(smlPoolSto), sizeof(smlPoolSto[0])); + + // initialize publish-subscribe + static QSubscrList subscrSto[MAX_PUB_SIG]; + QActive_psInit(subscrSto, Q_DIM(subscrSto)); + + // instantiate and start AOs/threads... + + static QEvt const *philoQueueSto[N_PHILO][10]; + for (uint8_t n = 0U; n < N_PHILO; ++n) { + Philo_ctor(n); + QACTIVE_START(AO_Philo[n], + + // NOTE: set the preemption-threshold of all Philos to + // the same level, so that they cannot preempt each other. + Q_PRIO(n + 3U, N_PHILO + 2U), // QF-prio/pre-thre. + + philoQueueSto[n], // event queue storage + Q_DIM(philoQueueSto[n]), // queue length [events] + (void *)0, 0U, // no stack storage + (void *)0); // no initialization param + } + + static QEvt const *tableQueueSto[N_PHILO]; + Table_ctor(); + QACTIVE_START(AO_Table, + N_PHILO + 7U, // QP prio. of the AO + tableQueueSto, // event queue storage + Q_DIM(tableQueueSto), // queue length [events] + (void *)0, 0U, // no stack storage + (void *)0); // no initialization param +} +//............................................................................ +void BSP_terminate(int16_t result) { + Q_UNUSED_PAR(result); +} +//............................................................................ +void BSP_displayPhilStat(uint8_t const n, char const *stat) { + Q_UNUSED_PAR(n); + + if (stat[0] == 'e') { // is Philo eating? + LED_ON(); + } + else { + LED_OFF(); + } + + // app-specific record + QS_BEGIN_ID(PHILO_STAT, AO_Table->prio) + QS_U8(1, n); // Philosopher number + QS_STR(stat); // Philosopher status + QS_END() +} +//............................................................................ +void BSP_displayPaused(uint8_t const paused) { + Q_UNUSED_PAR(paused); + + // application-specific trace record + QS_BEGIN_ID(PAUSED_STAT, AO_Table->prio) + QS_U8(1, paused); // Paused status + QS_END() +} +//............................................................................ +void BSP_randomSeed(uint32_t seed) { + l_rndSeed = seed; +} +//............................................................................ +uint32_t BSP_random(void) { // a cheap pseudo-random-number generator + + // "Super-Duper" Linear Congruential Generator (LCG) + // LCG(2^32, 3*7*11*13*23, 0, seed) + uint32_t rnd = l_rndSeed * (3U*7U*11U*13U*23U); + l_rndSeed = rnd; // update for the next time + + return (rnd >> 8U); +} + + +//=========================================================================== + +void QF_onStartup(void) { + INTCONSET = _INTCON_MVEC_MASK; // configure multi-vectored interrupts + + T2CON = 0x0060U; // stop timer, set up for 1:64 prescaler + TMR2 = 0U; // count from zero up to the period + PR2 = SYS_FREQ / (BSP_TICKS_PER_SEC * 64U); // set the Timer2 period + IFS0CLR = _IFS0_T2IF_MASK; // clear Timer2 Interrupt Flag + IEC0SET = _IEC0_T2IE_MASK; // enable Timer2 interrupt + T2CONSET = _T2CON_ON_MASK; // Start Timer2 + + INTCONbits.INT0EP = 1U; // INT0 interrupt on positive edge + IEC0SET = _IEC0_INT0IE_MASK; // enable INT0 interrupt + IFS0CLR = _IFS0_INT0IF_MASK; // clear the interrupt for INT0 + + // explicitly assign priorities to all interrupts... + // NOTE: must match the IPLxSOFT settings in the __ISR() macros + IPC2bits.T2IP = 4U; // Timer2 interrupt priority, must match tickISR + IPC0bits.INT0IP = 6U; // set INT0 priority; must match IPL in testISR +} +//............................................................................ void QF_onCleanup(void) { } -/*..........................................................................*/ +//............................................................................ void QK_onIdle(void) { - /* NOTE: not enough LEDs on the Microstick II board to implement - * the idle loop activity indicator ... - */ - //LED_ON (); /* blink the IDLE LED */ + // NOTE: not enough LEDs on the Microstick II board to implement + // the idle loop activity indicator ... + //QF_INT_DISABLE(); + //LED_ON (); //LED_OFF(); + //QF_INT_ENABLE(); #ifdef Q_SPY - while (U2STAbits.UTXBF == 0) { /* TX Buffer not full? */ - uint16_t b; - + while (U2STAbits.UTXBF == 0U) { // TX Buffer not full? QF_INT_DISABLE(); - b = QS_getByte(); + uint16_t b = QS_getByte(); QF_INT_ENABLE(); - if (b == QS_EOD) { /* End-Of-Data reached? */ - break; /* break out of the loop */ + if (b != QS_EOD) { // End-Of-Data reached? + U2TXREG = b; // stick the byte to TXREG for transmission + } + else { + break; // break out of the loop } - U2TXREG = (uint8_t)b; /* stick the byte to TXREG for transmission */ } #elif defined NDEBUG - _wait(); /* execute the WAIT instruction to stop the CPU */ + _wait(); // execute the WAIT instruction to stop the CPU #endif } -/*--------------------------------------------------------------------------*/ +//============================================================================ +// QS callbacks... #ifdef Q_SPY -#define QS_BUF_SIZE 4096 -#define QS_BAUD_RATE 115200 +#define QS_BUF_SIZE 4096U +#define QS_BAUD_RATE 115200U +//............................................................................ uint8_t QS_onStartup(void const *arg) { - static uint8_t qsBuf[QS_BUF_SIZE]; /* buffer for Quantum Spy */ + Q_UNUSED_PAR(arg); - QS_initBuf(qsBuf, sizeof(qsBuf)); /* initialize the QS trace buffer */ + static uint8_t qsBuf[QS_BUF_SIZE]; // buffer for QS-TX + QS_initBuf(qsBuf, sizeof(qsBuf)); // initialize the QS-TX channel - /* initialize the UART2 for transmitting the QS trace data */ - U2RXRbits.U2RXR = 3; /* Set U2RX to RPB11, pin 22, J6-5 */ - RPB10Rbits.RPB10R = 2; /* Set U2TX to RPB10, pin 21, J6-4 */ + //TBD: implement QS-RX channel - U2STA = 0x0000U; /* use default settings of 8N1 */ - U2MODE = 0x0008U; /* enable high baud rate */ + // initialize the UART2 for transmitting the QS trace data + U2RXRbits.U2RXR = 3; // Set U2RX to RPB11, pin 22, J6-5 + RPB10Rbits.RPB10R = 2; // Set U2TX to RPB10, pin 21, J6-4 + + U2STA = 0x0000U; // use default settings of 8N1 + U2MODE = 0x0008U; // enable high baud rate U2BRG = (uint16_t)((PER_HZ / (4.0 * QS_BAUD_RATE)) - 1.0 + 0.5); U2MODEbits.UARTEN = 1; U2STAbits.UTXEN = 1; - return 1U; /* indicate successfull QS initialization */ + return 1U; // return success } -/*..........................................................................*/ +//............................................................................ void QS_onCleanup(void) { } -/*..........................................................................*/ +//............................................................................ void QS_onFlush(void) { uint16_t b; - while ((b = QS_getByte()) != QS_EOD) { /* next QS trace byte available? */ - while (U2STAbits.UTXBF) { /* TX Buffer full? */ + while ((b = QS_getByte()) != QS_EOD) { // next QS trace byte available? + while (U2STAbits.UTXBF) { // TX Buffer full? } - U2TXREG = (uint8_t)b; /* stick the byte to TXREG for transmission */ + U2TXREG = b; // stick the byte to TXREG for transmission } } -/*..........................................................................*/ -/* NOTE: works properly with interrupts enabled or disabled */ +//............................................................................ +// NOTE: works properly with interrupts enabled or disabled QSTimeCtr QS_onGetTime(void) { - return __builtin_mfc0(_CP0_COUNT, _CP0_COUNT_SELECT); + return __builtin_mfc0(_CP0_COUNT, _CP0_COUNT_SELECT); } -/*..........................................................................*/ -/*! callback function to reset the target (to be implemented in the BSP) */ +//............................................................................ +//! callback function to reset the target (to be implemented in the BSP) void QS_onReset(void) { - uint32_t dummy; - - /* perform a system unlock sequence ,starting critical sequence*/ + // perform a system unlock sequence ,starting critical sequence SYSKEY = 0x00000000; //write invalid key to force lock SYSKEY = 0xAA996655; //write key1 to SYSKEY SYSKEY = 0x556699AA; //write key2 to SYSKEY - /* set SWRST bit to arm reset */ + // set SWRST bit to arm reset RSWRSTSET = 1; - /* read RSWRST register to trigger reset */ - dummy = RSWRST; - /* prevent any unwanted code execution until reset occurs*/} -/*..........................................................................*/ -/*! callback function to execute a user command (to be implemented in BSP) */ + // read RSWRST register to trigger reset + uint32_t volatile dummy = RSWRST; + // prevent any unwanted code execution until reset occurs +} +//............................................................................ +//! callback function to execute a user command (to be implemented in BSP) void QS_onCommand(uint8_t cmdId, uint32_t param1, uint32_t param2, uint32_t param3) { - (void)cmdId; - (void)param1; - (void)param2; - (void)param3; + Q_UNUSED_PAR(cmdId); + Q_UNUSED_PAR(param1); + Q_UNUSED_PAR(param2); + Q_UNUSED_PAR(param3); } -#endif /* Q_SPY */ +#endif // Q_SPY +//---------------------------------------------------------------------------- + +//============================================================================ +// NOTE2: +// The Temporal Proximity Timer is used to prevent a race condition of +// servicing an interrupt after re-enabling interrupts and before executing +// the WAIT instruction. The Proximity Timer is enabled for all interrupt +// priority levels (see QF_onStartup()). The Proximity Timer is set to 4 +// CPU clocks right before re-enabling interrupts (with the DI instruction) +// The 4 clock ticks should be enough to execute the (DI,WAIT) instruction +// pair _atomically_. +// diff --git a/examples/pic32/dpp_microstick2-pic32/qk/xc32/nbproject/Makefile-dbg.mk b/examples/pic32/dpp_microstick2-pic32/qk/xc32/nbproject/Makefile-dbg.mk index 1661e861..8c113d9f 100644 --- a/examples/pic32/dpp_microstick2-pic32/qk/xc32/nbproject/Makefile-dbg.mk +++ b/examples/pic32/dpp_microstick2-pic32/qk/xc32/nbproject/Makefile-dbg.mk @@ -57,17 +57,17 @@ OBJECTDIR=build/${CND_CONF}/${IMAGE_TYPE} DISTDIR=dist/${CND_CONF}/${IMAGE_TYPE} # Source Files Quoted if spaced -SOURCEFILES_QUOTED_IF_SPACED=../../../../../src/qf/qep_hsm.c ../../../../../src/qf/qep_msm.c ../../../../../src/qf/qf_act.c ../../../../../src/qf/qf_actq.c ../../../../../src/qf/qf_defer.c ../../../../../src/qf/qf_dyn.c ../../../../../src/qf/qf_mem.c ../../../../../src/qf/qf_ps.c ../../../../../src/qf/qf_qact.c ../../../../../src/qf/qf_qeq.c ../../../../../src/qf/qf_qmact.c ../../../../../src/qf/qf_time.c ../../../../../src/qk/qk.c ../../../../../ports/pic32/qk/xc32/qk_port.c bsp.c ../../main.c ../../../../../include/qstamp.c ../../philo.c ../../table.c +SOURCEFILES_QUOTED_IF_SPACED=../../../../../src/qf/qep_hsm.c ../../../../../src/qf/qep_msm.c ../../../../../src/qf/qf_act.c ../../../../../src/qf/qf_actq.c ../../../../../src/qf/qf_defer.c ../../../../../src/qf/qf_dyn.c ../../../../../src/qf/qf_mem.c ../../../../../src/qf/qf_ps.c ../../../../../src/qf/qf_qact.c ../../../../../src/qf/qf_qeq.c ../../../../../src/qf/qf_qmact.c ../../../../../src/qf/qf_time.c ../../../../../src/qk/qk.c ../../../../../ports/pic32/qk/xc32/qk_port.c ../../../../../src/qs/qstamp.c bsp.c ../../main.c ../../philo.c ../../table.c # Object Files Quoted if spaced -OBJECTFILES_QUOTED_IF_SPACED=${OBJECTDIR}/_ext/820665871/qep_hsm.o ${OBJECTDIR}/_ext/820665871/qep_msm.o ${OBJECTDIR}/_ext/820665871/qf_act.o ${OBJECTDIR}/_ext/820665871/qf_actq.o ${OBJECTDIR}/_ext/820665871/qf_defer.o ${OBJECTDIR}/_ext/820665871/qf_dyn.o ${OBJECTDIR}/_ext/820665871/qf_mem.o ${OBJECTDIR}/_ext/820665871/qf_ps.o ${OBJECTDIR}/_ext/820665871/qf_qact.o ${OBJECTDIR}/_ext/820665871/qf_qeq.o ${OBJECTDIR}/_ext/820665871/qf_qmact.o ${OBJECTDIR}/_ext/820665871/qf_time.o ${OBJECTDIR}/_ext/820665876/qk.o ${OBJECTDIR}/_ext/1627782163/qk_port.o ${OBJECTDIR}/bsp.o ${OBJECTDIR}/_ext/43898991/main.o ${OBJECTDIR}/_ext/726959463/qstamp.o ${OBJECTDIR}/_ext/43898991/philo.o ${OBJECTDIR}/_ext/43898991/table.o -POSSIBLE_DEPFILES=${OBJECTDIR}/_ext/820665871/qep_hsm.o.d ${OBJECTDIR}/_ext/820665871/qep_msm.o.d ${OBJECTDIR}/_ext/820665871/qf_act.o.d ${OBJECTDIR}/_ext/820665871/qf_actq.o.d ${OBJECTDIR}/_ext/820665871/qf_defer.o.d ${OBJECTDIR}/_ext/820665871/qf_dyn.o.d ${OBJECTDIR}/_ext/820665871/qf_mem.o.d ${OBJECTDIR}/_ext/820665871/qf_ps.o.d ${OBJECTDIR}/_ext/820665871/qf_qact.o.d ${OBJECTDIR}/_ext/820665871/qf_qeq.o.d ${OBJECTDIR}/_ext/820665871/qf_qmact.o.d ${OBJECTDIR}/_ext/820665871/qf_time.o.d ${OBJECTDIR}/_ext/820665876/qk.o.d ${OBJECTDIR}/_ext/1627782163/qk_port.o.d ${OBJECTDIR}/bsp.o.d ${OBJECTDIR}/_ext/43898991/main.o.d ${OBJECTDIR}/_ext/726959463/qstamp.o.d ${OBJECTDIR}/_ext/43898991/philo.o.d ${OBJECTDIR}/_ext/43898991/table.o.d +OBJECTFILES_QUOTED_IF_SPACED=${OBJECTDIR}/_ext/820665871/qep_hsm.o ${OBJECTDIR}/_ext/820665871/qep_msm.o ${OBJECTDIR}/_ext/820665871/qf_act.o ${OBJECTDIR}/_ext/820665871/qf_actq.o ${OBJECTDIR}/_ext/820665871/qf_defer.o ${OBJECTDIR}/_ext/820665871/qf_dyn.o ${OBJECTDIR}/_ext/820665871/qf_mem.o ${OBJECTDIR}/_ext/820665871/qf_ps.o ${OBJECTDIR}/_ext/820665871/qf_qact.o ${OBJECTDIR}/_ext/820665871/qf_qeq.o ${OBJECTDIR}/_ext/820665871/qf_qmact.o ${OBJECTDIR}/_ext/820665871/qf_time.o ${OBJECTDIR}/_ext/820665876/qk.o ${OBJECTDIR}/_ext/1627782163/qk_port.o ${OBJECTDIR}/_ext/820665884/qstamp.o ${OBJECTDIR}/bsp.o ${OBJECTDIR}/_ext/43898991/main.o ${OBJECTDIR}/_ext/43898991/philo.o ${OBJECTDIR}/_ext/43898991/table.o +POSSIBLE_DEPFILES=${OBJECTDIR}/_ext/820665871/qep_hsm.o.d ${OBJECTDIR}/_ext/820665871/qep_msm.o.d ${OBJECTDIR}/_ext/820665871/qf_act.o.d ${OBJECTDIR}/_ext/820665871/qf_actq.o.d ${OBJECTDIR}/_ext/820665871/qf_defer.o.d ${OBJECTDIR}/_ext/820665871/qf_dyn.o.d ${OBJECTDIR}/_ext/820665871/qf_mem.o.d ${OBJECTDIR}/_ext/820665871/qf_ps.o.d ${OBJECTDIR}/_ext/820665871/qf_qact.o.d ${OBJECTDIR}/_ext/820665871/qf_qeq.o.d ${OBJECTDIR}/_ext/820665871/qf_qmact.o.d ${OBJECTDIR}/_ext/820665871/qf_time.o.d ${OBJECTDIR}/_ext/820665876/qk.o.d ${OBJECTDIR}/_ext/1627782163/qk_port.o.d ${OBJECTDIR}/_ext/820665884/qstamp.o.d ${OBJECTDIR}/bsp.o.d ${OBJECTDIR}/_ext/43898991/main.o.d ${OBJECTDIR}/_ext/43898991/philo.o.d ${OBJECTDIR}/_ext/43898991/table.o.d # Object Files -OBJECTFILES=${OBJECTDIR}/_ext/820665871/qep_hsm.o ${OBJECTDIR}/_ext/820665871/qep_msm.o ${OBJECTDIR}/_ext/820665871/qf_act.o ${OBJECTDIR}/_ext/820665871/qf_actq.o ${OBJECTDIR}/_ext/820665871/qf_defer.o ${OBJECTDIR}/_ext/820665871/qf_dyn.o ${OBJECTDIR}/_ext/820665871/qf_mem.o ${OBJECTDIR}/_ext/820665871/qf_ps.o ${OBJECTDIR}/_ext/820665871/qf_qact.o ${OBJECTDIR}/_ext/820665871/qf_qeq.o ${OBJECTDIR}/_ext/820665871/qf_qmact.o ${OBJECTDIR}/_ext/820665871/qf_time.o ${OBJECTDIR}/_ext/820665876/qk.o ${OBJECTDIR}/_ext/1627782163/qk_port.o ${OBJECTDIR}/bsp.o ${OBJECTDIR}/_ext/43898991/main.o ${OBJECTDIR}/_ext/726959463/qstamp.o ${OBJECTDIR}/_ext/43898991/philo.o ${OBJECTDIR}/_ext/43898991/table.o +OBJECTFILES=${OBJECTDIR}/_ext/820665871/qep_hsm.o ${OBJECTDIR}/_ext/820665871/qep_msm.o ${OBJECTDIR}/_ext/820665871/qf_act.o ${OBJECTDIR}/_ext/820665871/qf_actq.o ${OBJECTDIR}/_ext/820665871/qf_defer.o ${OBJECTDIR}/_ext/820665871/qf_dyn.o ${OBJECTDIR}/_ext/820665871/qf_mem.o ${OBJECTDIR}/_ext/820665871/qf_ps.o ${OBJECTDIR}/_ext/820665871/qf_qact.o ${OBJECTDIR}/_ext/820665871/qf_qeq.o ${OBJECTDIR}/_ext/820665871/qf_qmact.o ${OBJECTDIR}/_ext/820665871/qf_time.o ${OBJECTDIR}/_ext/820665876/qk.o ${OBJECTDIR}/_ext/1627782163/qk_port.o ${OBJECTDIR}/_ext/820665884/qstamp.o ${OBJECTDIR}/bsp.o ${OBJECTDIR}/_ext/43898991/main.o ${OBJECTDIR}/_ext/43898991/philo.o ${OBJECTDIR}/_ext/43898991/table.o # Source Files -SOURCEFILES=../../../../../src/qf/qep_hsm.c ../../../../../src/qf/qep_msm.c ../../../../../src/qf/qf_act.c ../../../../../src/qf/qf_actq.c ../../../../../src/qf/qf_defer.c ../../../../../src/qf/qf_dyn.c ../../../../../src/qf/qf_mem.c ../../../../../src/qf/qf_ps.c ../../../../../src/qf/qf_qact.c ../../../../../src/qf/qf_qeq.c ../../../../../src/qf/qf_qmact.c ../../../../../src/qf/qf_time.c ../../../../../src/qk/qk.c ../../../../../ports/pic32/qk/xc32/qk_port.c bsp.c ../../main.c ../../../../../include/qstamp.c ../../philo.c ../../table.c +SOURCEFILES=../../../../../src/qf/qep_hsm.c ../../../../../src/qf/qep_msm.c ../../../../../src/qf/qf_act.c ../../../../../src/qf/qf_actq.c ../../../../../src/qf/qf_defer.c ../../../../../src/qf/qf_dyn.c ../../../../../src/qf/qf_mem.c ../../../../../src/qf/qf_ps.c ../../../../../src/qf/qf_qact.c ../../../../../src/qf/qf_qeq.c ../../../../../src/qf/qf_qmact.c ../../../../../src/qf/qf_time.c ../../../../../src/qk/qk.c ../../../../../ports/pic32/qk/xc32/qk_port.c ../../../../../src/qs/qstamp.c bsp.c ../../main.c ../../philo.c ../../table.c CFLAGS= @@ -190,6 +190,12 @@ ${OBJECTDIR}/_ext/1627782163/qk_port.o: ../../../../../ports/pic32/qk/xc32/qk_po @${RM} ${OBJECTDIR}/_ext/1627782163/qk_port.o @${FIXDEPS} "${OBJECTDIR}/_ext/1627782163/qk_port.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -D__DEBUG -D__MPLAB_DEBUGGER_PK3=1 -fframe-base-loclist -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -I"../.." -I"../../../../../src" -I"../../../../../include" -I"../../../../../ports/pic32/qk/xc32" -MMD -MF "${OBJECTDIR}/_ext/1627782163/qk_port.o.d" -o ${OBJECTDIR}/_ext/1627782163/qk_port.o ../../../../../ports/pic32/qk/xc32/qk_port.c -DXPRJ_dbg=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 +${OBJECTDIR}/_ext/820665884/qstamp.o: ../../../../../src/qs/qstamp.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/_ext/820665884" + @${RM} ${OBJECTDIR}/_ext/820665884/qstamp.o.d + @${RM} ${OBJECTDIR}/_ext/820665884/qstamp.o + @${FIXDEPS} "${OBJECTDIR}/_ext/820665884/qstamp.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -D__DEBUG -D__MPLAB_DEBUGGER_PK3=1 -fframe-base-loclist -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -I"../.." -I"../../../../../src" -I"../../../../../include" -I"../../../../../ports/pic32/qk/xc32" -MMD -MF "${OBJECTDIR}/_ext/820665884/qstamp.o.d" -o ${OBJECTDIR}/_ext/820665884/qstamp.o ../../../../../src/qs/qstamp.c -DXPRJ_dbg=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 + ${OBJECTDIR}/bsp.o: bsp.c nbproject/Makefile-${CND_CONF}.mk @${MKDIR} "${OBJECTDIR}" @${RM} ${OBJECTDIR}/bsp.o.d @@ -202,12 +208,6 @@ ${OBJECTDIR}/_ext/43898991/main.o: ../../main.c nbproject/Makefile-${CND_CONF}. @${RM} ${OBJECTDIR}/_ext/43898991/main.o @${FIXDEPS} "${OBJECTDIR}/_ext/43898991/main.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -D__DEBUG -D__MPLAB_DEBUGGER_PK3=1 -fframe-base-loclist -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -I"../.." -I"../../../../../src" -I"../../../../../include" -I"../../../../../ports/pic32/qk/xc32" -MMD -MF "${OBJECTDIR}/_ext/43898991/main.o.d" -o ${OBJECTDIR}/_ext/43898991/main.o ../../main.c -DXPRJ_dbg=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 -${OBJECTDIR}/_ext/726959463/qstamp.o: ../../../../../include/qstamp.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/726959463" - @${RM} ${OBJECTDIR}/_ext/726959463/qstamp.o.d - @${RM} ${OBJECTDIR}/_ext/726959463/qstamp.o - @${FIXDEPS} "${OBJECTDIR}/_ext/726959463/qstamp.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -D__DEBUG -D__MPLAB_DEBUGGER_PK3=1 -fframe-base-loclist -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -I"../.." -I"../../../../../src" -I"../../../../../include" -I"../../../../../ports/pic32/qk/xc32" -MMD -MF "${OBJECTDIR}/_ext/726959463/qstamp.o.d" -o ${OBJECTDIR}/_ext/726959463/qstamp.o ../../../../../include/qstamp.c -DXPRJ_dbg=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - ${OBJECTDIR}/_ext/43898991/philo.o: ../../philo.c nbproject/Makefile-${CND_CONF}.mk @${MKDIR} "${OBJECTDIR}/_ext/43898991" @${RM} ${OBJECTDIR}/_ext/43898991/philo.o.d @@ -305,6 +305,12 @@ ${OBJECTDIR}/_ext/1627782163/qk_port.o: ../../../../../ports/pic32/qk/xc32/qk_po @${RM} ${OBJECTDIR}/_ext/1627782163/qk_port.o @${FIXDEPS} "${OBJECTDIR}/_ext/1627782163/qk_port.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -I"../.." -I"../../../../../src" -I"../../../../../include" -I"../../../../../ports/pic32/qk/xc32" -MMD -MF "${OBJECTDIR}/_ext/1627782163/qk_port.o.d" -o ${OBJECTDIR}/_ext/1627782163/qk_port.o ../../../../../ports/pic32/qk/xc32/qk_port.c -DXPRJ_dbg=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 +${OBJECTDIR}/_ext/820665884/qstamp.o: ../../../../../src/qs/qstamp.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/_ext/820665884" + @${RM} ${OBJECTDIR}/_ext/820665884/qstamp.o.d + @${RM} ${OBJECTDIR}/_ext/820665884/qstamp.o + @${FIXDEPS} "${OBJECTDIR}/_ext/820665884/qstamp.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -I"../.." -I"../../../../../src" -I"../../../../../include" -I"../../../../../ports/pic32/qk/xc32" -MMD -MF "${OBJECTDIR}/_ext/820665884/qstamp.o.d" -o ${OBJECTDIR}/_ext/820665884/qstamp.o ../../../../../src/qs/qstamp.c -DXPRJ_dbg=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 + ${OBJECTDIR}/bsp.o: bsp.c nbproject/Makefile-${CND_CONF}.mk @${MKDIR} "${OBJECTDIR}" @${RM} ${OBJECTDIR}/bsp.o.d @@ -317,12 +323,6 @@ ${OBJECTDIR}/_ext/43898991/main.o: ../../main.c nbproject/Makefile-${CND_CONF}. @${RM} ${OBJECTDIR}/_ext/43898991/main.o @${FIXDEPS} "${OBJECTDIR}/_ext/43898991/main.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -I"../.." -I"../../../../../src" -I"../../../../../include" -I"../../../../../ports/pic32/qk/xc32" -MMD -MF "${OBJECTDIR}/_ext/43898991/main.o.d" -o ${OBJECTDIR}/_ext/43898991/main.o ../../main.c -DXPRJ_dbg=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 -${OBJECTDIR}/_ext/726959463/qstamp.o: ../../../../../include/qstamp.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/726959463" - @${RM} ${OBJECTDIR}/_ext/726959463/qstamp.o.d - @${RM} ${OBJECTDIR}/_ext/726959463/qstamp.o - @${FIXDEPS} "${OBJECTDIR}/_ext/726959463/qstamp.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -I"../.." -I"../../../../../src" -I"../../../../../include" -I"../../../../../ports/pic32/qk/xc32" -MMD -MF "${OBJECTDIR}/_ext/726959463/qstamp.o.d" -o ${OBJECTDIR}/_ext/726959463/qstamp.o ../../../../../include/qstamp.c -DXPRJ_dbg=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - ${OBJECTDIR}/_ext/43898991/philo.o: ../../philo.c nbproject/Makefile-${CND_CONF}.mk @${MKDIR} "${OBJECTDIR}/_ext/43898991" @${RM} ${OBJECTDIR}/_ext/43898991/philo.o.d diff --git a/examples/pic32/dpp_microstick2-pic32/qk/xc32/nbproject/Makefile-genesis.properties b/examples/pic32/dpp_microstick2-pic32/qk/xc32/nbproject/Makefile-genesis.properties index 45ea593f..4677a5e6 100644 --- a/examples/pic32/dpp_microstick2-pic32/qk/xc32/nbproject/Makefile-genesis.properties +++ b/examples/pic32/dpp_microstick2-pic32/qk/xc32/nbproject/Makefile-genesis.properties @@ -1,10 +1,10 @@ # -#Sun Apr 10 14:42:23 EDT 2022 +#Mon Sep 04 10:35:20 EDT 2023 rel.languagetoolchain.version=2.20 spy.languagetoolchain.version=2.20 conf.ids=dbg,rel,spy spy.languagetoolchain.dir=C\:\\tools\\Microchip\\xc32\\bin -configurations-xml=04073c72f94d75f5d8e01266dd4659c9 +configurations-xml=ae302c4e7b621dd895a84c66dfe9539a dbg.languagetoolchain.version=2.20 com-microchip-mplab-nbide-embedded-makeproject-MakeProject.md5=37eccb08230908d044ad3fe14e24ea9a dbg.com-microchip-mplab-nbide-toolchainXC32-XC32LanguageToolchain.md5=af6fe09cc582a0daace7b80bb4f7bbe2 diff --git a/examples/pic32/dpp_microstick2-pic32/qk/xc32/nbproject/Makefile-rel.mk b/examples/pic32/dpp_microstick2-pic32/qk/xc32/nbproject/Makefile-rel.mk index 936b8f03..a2ca9600 100644 --- a/examples/pic32/dpp_microstick2-pic32/qk/xc32/nbproject/Makefile-rel.mk +++ b/examples/pic32/dpp_microstick2-pic32/qk/xc32/nbproject/Makefile-rel.mk @@ -57,17 +57,17 @@ OBJECTDIR=build/${CND_CONF}/${IMAGE_TYPE} DISTDIR=dist/${CND_CONF}/${IMAGE_TYPE} # Source Files Quoted if spaced -SOURCEFILES_QUOTED_IF_SPACED=../../../../../src/qf/qep_hsm.c ../../../../../src/qf/qep_msm.c ../../../../../src/qf/qf_act.c ../../../../../src/qf/qf_actq.c ../../../../../src/qf/qf_defer.c ../../../../../src/qf/qf_dyn.c ../../../../../src/qf/qf_mem.c ../../../../../src/qf/qf_ps.c ../../../../../src/qf/qf_qact.c ../../../../../src/qf/qf_qeq.c ../../../../../src/qf/qf_qmact.c ../../../../../src/qf/qf_time.c ../../../../../src/qk/qk.c ../../../../../ports/pic32/qk/xc32/qk_port.c bsp.c ../../main.c ../../../../../include/qstamp.c ../../philo.c ../../table.c +SOURCEFILES_QUOTED_IF_SPACED=../../../../../src/qf/qep_hsm.c ../../../../../src/qf/qep_msm.c ../../../../../src/qf/qf_act.c ../../../../../src/qf/qf_actq.c ../../../../../src/qf/qf_defer.c ../../../../../src/qf/qf_dyn.c ../../../../../src/qf/qf_mem.c ../../../../../src/qf/qf_ps.c ../../../../../src/qf/qf_qact.c ../../../../../src/qf/qf_qeq.c ../../../../../src/qf/qf_qmact.c ../../../../../src/qf/qf_time.c ../../../../../src/qk/qk.c ../../../../../ports/pic32/qk/xc32/qk_port.c ../../../../../src/qs/qstamp.c bsp.c ../../main.c ../../philo.c ../../table.c # Object Files Quoted if spaced -OBJECTFILES_QUOTED_IF_SPACED=${OBJECTDIR}/_ext/820665871/qep_hsm.o ${OBJECTDIR}/_ext/820665871/qep_msm.o ${OBJECTDIR}/_ext/820665871/qf_act.o ${OBJECTDIR}/_ext/820665871/qf_actq.o ${OBJECTDIR}/_ext/820665871/qf_defer.o ${OBJECTDIR}/_ext/820665871/qf_dyn.o ${OBJECTDIR}/_ext/820665871/qf_mem.o ${OBJECTDIR}/_ext/820665871/qf_ps.o ${OBJECTDIR}/_ext/820665871/qf_qact.o ${OBJECTDIR}/_ext/820665871/qf_qeq.o ${OBJECTDIR}/_ext/820665871/qf_qmact.o ${OBJECTDIR}/_ext/820665871/qf_time.o ${OBJECTDIR}/_ext/820665876/qk.o ${OBJECTDIR}/_ext/1627782163/qk_port.o ${OBJECTDIR}/bsp.o ${OBJECTDIR}/_ext/43898991/main.o ${OBJECTDIR}/_ext/726959463/qstamp.o ${OBJECTDIR}/_ext/43898991/philo.o ${OBJECTDIR}/_ext/43898991/table.o -POSSIBLE_DEPFILES=${OBJECTDIR}/_ext/820665871/qep_hsm.o.d ${OBJECTDIR}/_ext/820665871/qep_msm.o.d ${OBJECTDIR}/_ext/820665871/qf_act.o.d ${OBJECTDIR}/_ext/820665871/qf_actq.o.d ${OBJECTDIR}/_ext/820665871/qf_defer.o.d ${OBJECTDIR}/_ext/820665871/qf_dyn.o.d ${OBJECTDIR}/_ext/820665871/qf_mem.o.d ${OBJECTDIR}/_ext/820665871/qf_ps.o.d ${OBJECTDIR}/_ext/820665871/qf_qact.o.d ${OBJECTDIR}/_ext/820665871/qf_qeq.o.d ${OBJECTDIR}/_ext/820665871/qf_qmact.o.d ${OBJECTDIR}/_ext/820665871/qf_time.o.d ${OBJECTDIR}/_ext/820665876/qk.o.d ${OBJECTDIR}/_ext/1627782163/qk_port.o.d ${OBJECTDIR}/bsp.o.d ${OBJECTDIR}/_ext/43898991/main.o.d ${OBJECTDIR}/_ext/726959463/qstamp.o.d ${OBJECTDIR}/_ext/43898991/philo.o.d ${OBJECTDIR}/_ext/43898991/table.o.d +OBJECTFILES_QUOTED_IF_SPACED=${OBJECTDIR}/_ext/820665871/qep_hsm.o ${OBJECTDIR}/_ext/820665871/qep_msm.o ${OBJECTDIR}/_ext/820665871/qf_act.o ${OBJECTDIR}/_ext/820665871/qf_actq.o ${OBJECTDIR}/_ext/820665871/qf_defer.o ${OBJECTDIR}/_ext/820665871/qf_dyn.o ${OBJECTDIR}/_ext/820665871/qf_mem.o ${OBJECTDIR}/_ext/820665871/qf_ps.o ${OBJECTDIR}/_ext/820665871/qf_qact.o ${OBJECTDIR}/_ext/820665871/qf_qeq.o ${OBJECTDIR}/_ext/820665871/qf_qmact.o ${OBJECTDIR}/_ext/820665871/qf_time.o ${OBJECTDIR}/_ext/820665876/qk.o ${OBJECTDIR}/_ext/1627782163/qk_port.o ${OBJECTDIR}/_ext/820665884/qstamp.o ${OBJECTDIR}/bsp.o ${OBJECTDIR}/_ext/43898991/main.o ${OBJECTDIR}/_ext/43898991/philo.o ${OBJECTDIR}/_ext/43898991/table.o +POSSIBLE_DEPFILES=${OBJECTDIR}/_ext/820665871/qep_hsm.o.d ${OBJECTDIR}/_ext/820665871/qep_msm.o.d ${OBJECTDIR}/_ext/820665871/qf_act.o.d ${OBJECTDIR}/_ext/820665871/qf_actq.o.d ${OBJECTDIR}/_ext/820665871/qf_defer.o.d ${OBJECTDIR}/_ext/820665871/qf_dyn.o.d ${OBJECTDIR}/_ext/820665871/qf_mem.o.d ${OBJECTDIR}/_ext/820665871/qf_ps.o.d ${OBJECTDIR}/_ext/820665871/qf_qact.o.d ${OBJECTDIR}/_ext/820665871/qf_qeq.o.d ${OBJECTDIR}/_ext/820665871/qf_qmact.o.d ${OBJECTDIR}/_ext/820665871/qf_time.o.d ${OBJECTDIR}/_ext/820665876/qk.o.d ${OBJECTDIR}/_ext/1627782163/qk_port.o.d ${OBJECTDIR}/_ext/820665884/qstamp.o.d ${OBJECTDIR}/bsp.o.d ${OBJECTDIR}/_ext/43898991/main.o.d ${OBJECTDIR}/_ext/43898991/philo.o.d ${OBJECTDIR}/_ext/43898991/table.o.d # Object Files -OBJECTFILES=${OBJECTDIR}/_ext/820665871/qep_hsm.o ${OBJECTDIR}/_ext/820665871/qep_msm.o ${OBJECTDIR}/_ext/820665871/qf_act.o ${OBJECTDIR}/_ext/820665871/qf_actq.o ${OBJECTDIR}/_ext/820665871/qf_defer.o ${OBJECTDIR}/_ext/820665871/qf_dyn.o ${OBJECTDIR}/_ext/820665871/qf_mem.o ${OBJECTDIR}/_ext/820665871/qf_ps.o ${OBJECTDIR}/_ext/820665871/qf_qact.o ${OBJECTDIR}/_ext/820665871/qf_qeq.o ${OBJECTDIR}/_ext/820665871/qf_qmact.o ${OBJECTDIR}/_ext/820665871/qf_time.o ${OBJECTDIR}/_ext/820665876/qk.o ${OBJECTDIR}/_ext/1627782163/qk_port.o ${OBJECTDIR}/bsp.o ${OBJECTDIR}/_ext/43898991/main.o ${OBJECTDIR}/_ext/726959463/qstamp.o ${OBJECTDIR}/_ext/43898991/philo.o ${OBJECTDIR}/_ext/43898991/table.o +OBJECTFILES=${OBJECTDIR}/_ext/820665871/qep_hsm.o ${OBJECTDIR}/_ext/820665871/qep_msm.o ${OBJECTDIR}/_ext/820665871/qf_act.o ${OBJECTDIR}/_ext/820665871/qf_actq.o ${OBJECTDIR}/_ext/820665871/qf_defer.o ${OBJECTDIR}/_ext/820665871/qf_dyn.o ${OBJECTDIR}/_ext/820665871/qf_mem.o ${OBJECTDIR}/_ext/820665871/qf_ps.o ${OBJECTDIR}/_ext/820665871/qf_qact.o ${OBJECTDIR}/_ext/820665871/qf_qeq.o ${OBJECTDIR}/_ext/820665871/qf_qmact.o ${OBJECTDIR}/_ext/820665871/qf_time.o ${OBJECTDIR}/_ext/820665876/qk.o ${OBJECTDIR}/_ext/1627782163/qk_port.o ${OBJECTDIR}/_ext/820665884/qstamp.o ${OBJECTDIR}/bsp.o ${OBJECTDIR}/_ext/43898991/main.o ${OBJECTDIR}/_ext/43898991/philo.o ${OBJECTDIR}/_ext/43898991/table.o # Source Files -SOURCEFILES=../../../../../src/qf/qep_hsm.c ../../../../../src/qf/qep_msm.c ../../../../../src/qf/qf_act.c ../../../../../src/qf/qf_actq.c ../../../../../src/qf/qf_defer.c ../../../../../src/qf/qf_dyn.c ../../../../../src/qf/qf_mem.c ../../../../../src/qf/qf_ps.c ../../../../../src/qf/qf_qact.c ../../../../../src/qf/qf_qeq.c ../../../../../src/qf/qf_qmact.c ../../../../../src/qf/qf_time.c ../../../../../src/qk/qk.c ../../../../../ports/pic32/qk/xc32/qk_port.c bsp.c ../../main.c ../../../../../include/qstamp.c ../../philo.c ../../table.c +SOURCEFILES=../../../../../src/qf/qep_hsm.c ../../../../../src/qf/qep_msm.c ../../../../../src/qf/qf_act.c ../../../../../src/qf/qf_actq.c ../../../../../src/qf/qf_defer.c ../../../../../src/qf/qf_dyn.c ../../../../../src/qf/qf_mem.c ../../../../../src/qf/qf_ps.c ../../../../../src/qf/qf_qact.c ../../../../../src/qf/qf_qeq.c ../../../../../src/qf/qf_qmact.c ../../../../../src/qf/qf_time.c ../../../../../src/qk/qk.c ../../../../../ports/pic32/qk/xc32/qk_port.c ../../../../../src/qs/qstamp.c bsp.c ../../main.c ../../philo.c ../../table.c CFLAGS= @@ -190,6 +190,12 @@ ${OBJECTDIR}/_ext/1627782163/qk_port.o: ../../../../../ports/pic32/qk/xc32/qk_po @${RM} ${OBJECTDIR}/_ext/1627782163/qk_port.o @${FIXDEPS} "${OBJECTDIR}/_ext/1627782163/qk_port.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -D__DEBUG -D__MPLAB_DEBUGGER_PK3=1 -fframe-base-loclist -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -O3 -DNDEBUG -I"../.." -I"../../../../../include" -I"../../../../../src" -I"../../../../../ports/pic32/qk/xc32" -MMD -MF "${OBJECTDIR}/_ext/1627782163/qk_port.o.d" -o ${OBJECTDIR}/_ext/1627782163/qk_port.o ../../../../../ports/pic32/qk/xc32/qk_port.c -DXPRJ_rel=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 +${OBJECTDIR}/_ext/820665884/qstamp.o: ../../../../../src/qs/qstamp.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/_ext/820665884" + @${RM} ${OBJECTDIR}/_ext/820665884/qstamp.o.d + @${RM} ${OBJECTDIR}/_ext/820665884/qstamp.o + @${FIXDEPS} "${OBJECTDIR}/_ext/820665884/qstamp.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -D__DEBUG -D__MPLAB_DEBUGGER_PK3=1 -fframe-base-loclist -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -O3 -DNDEBUG -I"../.." -I"../../../../../include" -I"../../../../../src" -I"../../../../../ports/pic32/qk/xc32" -MMD -MF "${OBJECTDIR}/_ext/820665884/qstamp.o.d" -o ${OBJECTDIR}/_ext/820665884/qstamp.o ../../../../../src/qs/qstamp.c -DXPRJ_rel=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 + ${OBJECTDIR}/bsp.o: bsp.c nbproject/Makefile-${CND_CONF}.mk @${MKDIR} "${OBJECTDIR}" @${RM} ${OBJECTDIR}/bsp.o.d @@ -202,12 +208,6 @@ ${OBJECTDIR}/_ext/43898991/main.o: ../../main.c nbproject/Makefile-${CND_CONF}. @${RM} ${OBJECTDIR}/_ext/43898991/main.o @${FIXDEPS} "${OBJECTDIR}/_ext/43898991/main.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -D__DEBUG -D__MPLAB_DEBUGGER_PK3=1 -fframe-base-loclist -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -O3 -DNDEBUG -I"../.." -I"../../../../../include" -I"../../../../../src" -I"../../../../../ports/pic32/qk/xc32" -MMD -MF "${OBJECTDIR}/_ext/43898991/main.o.d" -o ${OBJECTDIR}/_ext/43898991/main.o ../../main.c -DXPRJ_rel=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 -${OBJECTDIR}/_ext/726959463/qstamp.o: ../../../../../include/qstamp.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/726959463" - @${RM} ${OBJECTDIR}/_ext/726959463/qstamp.o.d - @${RM} ${OBJECTDIR}/_ext/726959463/qstamp.o - @${FIXDEPS} "${OBJECTDIR}/_ext/726959463/qstamp.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -D__DEBUG -D__MPLAB_DEBUGGER_PK3=1 -fframe-base-loclist -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -O3 -DNDEBUG -I"../.." -I"../../../../../include" -I"../../../../../src" -I"../../../../../ports/pic32/qk/xc32" -MMD -MF "${OBJECTDIR}/_ext/726959463/qstamp.o.d" -o ${OBJECTDIR}/_ext/726959463/qstamp.o ../../../../../include/qstamp.c -DXPRJ_rel=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - ${OBJECTDIR}/_ext/43898991/philo.o: ../../philo.c nbproject/Makefile-${CND_CONF}.mk @${MKDIR} "${OBJECTDIR}/_ext/43898991" @${RM} ${OBJECTDIR}/_ext/43898991/philo.o.d @@ -305,6 +305,12 @@ ${OBJECTDIR}/_ext/1627782163/qk_port.o: ../../../../../ports/pic32/qk/xc32/qk_po @${RM} ${OBJECTDIR}/_ext/1627782163/qk_port.o @${FIXDEPS} "${OBJECTDIR}/_ext/1627782163/qk_port.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -O3 -DNDEBUG -I"../.." -I"../../../../../include" -I"../../../../../src" -I"../../../../../ports/pic32/qk/xc32" -MMD -MF "${OBJECTDIR}/_ext/1627782163/qk_port.o.d" -o ${OBJECTDIR}/_ext/1627782163/qk_port.o ../../../../../ports/pic32/qk/xc32/qk_port.c -DXPRJ_rel=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 +${OBJECTDIR}/_ext/820665884/qstamp.o: ../../../../../src/qs/qstamp.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/_ext/820665884" + @${RM} ${OBJECTDIR}/_ext/820665884/qstamp.o.d + @${RM} ${OBJECTDIR}/_ext/820665884/qstamp.o + @${FIXDEPS} "${OBJECTDIR}/_ext/820665884/qstamp.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -O3 -DNDEBUG -I"../.." -I"../../../../../include" -I"../../../../../src" -I"../../../../../ports/pic32/qk/xc32" -MMD -MF "${OBJECTDIR}/_ext/820665884/qstamp.o.d" -o ${OBJECTDIR}/_ext/820665884/qstamp.o ../../../../../src/qs/qstamp.c -DXPRJ_rel=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 + ${OBJECTDIR}/bsp.o: bsp.c nbproject/Makefile-${CND_CONF}.mk @${MKDIR} "${OBJECTDIR}" @${RM} ${OBJECTDIR}/bsp.o.d @@ -317,12 +323,6 @@ ${OBJECTDIR}/_ext/43898991/main.o: ../../main.c nbproject/Makefile-${CND_CONF}. @${RM} ${OBJECTDIR}/_ext/43898991/main.o @${FIXDEPS} "${OBJECTDIR}/_ext/43898991/main.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -O3 -DNDEBUG -I"../.." -I"../../../../../include" -I"../../../../../src" -I"../../../../../ports/pic32/qk/xc32" -MMD -MF "${OBJECTDIR}/_ext/43898991/main.o.d" -o ${OBJECTDIR}/_ext/43898991/main.o ../../main.c -DXPRJ_rel=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 -${OBJECTDIR}/_ext/726959463/qstamp.o: ../../../../../include/qstamp.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/726959463" - @${RM} ${OBJECTDIR}/_ext/726959463/qstamp.o.d - @${RM} ${OBJECTDIR}/_ext/726959463/qstamp.o - @${FIXDEPS} "${OBJECTDIR}/_ext/726959463/qstamp.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -O3 -DNDEBUG -I"../.." -I"../../../../../include" -I"../../../../../src" -I"../../../../../ports/pic32/qk/xc32" -MMD -MF "${OBJECTDIR}/_ext/726959463/qstamp.o.d" -o ${OBJECTDIR}/_ext/726959463/qstamp.o ../../../../../include/qstamp.c -DXPRJ_rel=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - ${OBJECTDIR}/_ext/43898991/philo.o: ../../philo.c nbproject/Makefile-${CND_CONF}.mk @${MKDIR} "${OBJECTDIR}/_ext/43898991" @${RM} ${OBJECTDIR}/_ext/43898991/philo.o.d diff --git a/examples/pic32/dpp_microstick2-pic32/qk/xc32/nbproject/Makefile-spy.mk b/examples/pic32/dpp_microstick2-pic32/qk/xc32/nbproject/Makefile-spy.mk index a097ba43..2f23cd1c 100644 --- a/examples/pic32/dpp_microstick2-pic32/qk/xc32/nbproject/Makefile-spy.mk +++ b/examples/pic32/dpp_microstick2-pic32/qk/xc32/nbproject/Makefile-spy.mk @@ -57,17 +57,17 @@ OBJECTDIR=build/${CND_CONF}/${IMAGE_TYPE} DISTDIR=dist/${CND_CONF}/${IMAGE_TYPE} # Source Files Quoted if spaced -SOURCEFILES_QUOTED_IF_SPACED=../../../../../src/qf/qep_hsm.c ../../../../../src/qf/qep_msm.c ../../../../../src/qf/qf_act.c ../../../../../src/qf/qf_actq.c ../../../../../src/qf/qf_defer.c ../../../../../src/qf/qf_dyn.c ../../../../../src/qf/qf_mem.c ../../../../../src/qf/qf_ps.c ../../../../../src/qf/qf_qact.c ../../../../../src/qf/qf_qeq.c ../../../../../src/qf/qf_qmact.c ../../../../../src/qf/qf_time.c ../../../../../src/qk/qk.c ../../../../../ports/pic32/qk/xc32/qk_port.c ../../../../../src/qs/qs.c ../../../../../src/qs/qs_64bit.c ../../../../../src/qs/qs_fp.c ../../../../../src/qs/qs_rx.c bsp.c ../../main.c ../../../../../include/qstamp.c ../../philo.c ../../table.c +SOURCEFILES_QUOTED_IF_SPACED=../../../../../src/qf/qep_hsm.c ../../../../../src/qf/qep_msm.c ../../../../../src/qf/qf_act.c ../../../../../src/qf/qf_actq.c ../../../../../src/qf/qf_defer.c ../../../../../src/qf/qf_dyn.c ../../../../../src/qf/qf_mem.c ../../../../../src/qf/qf_ps.c ../../../../../src/qf/qf_qact.c ../../../../../src/qf/qf_qeq.c ../../../../../src/qf/qf_qmact.c ../../../../../src/qf/qf_time.c ../../../../../src/qk/qk.c ../../../../../ports/pic32/qk/xc32/qk_port.c ../../../../../src/qs/qs.c ../../../../../src/qs/qs_64bit.c ../../../../../src/qs/qs_fp.c ../../../../../src/qs/qs_rx.c ../../../../../src/qs/qstamp.c bsp.c ../../main.c ../../philo.c ../../table.c # Object Files Quoted if spaced -OBJECTFILES_QUOTED_IF_SPACED=${OBJECTDIR}/_ext/820665871/qep_hsm.o ${OBJECTDIR}/_ext/820665871/qep_msm.o ${OBJECTDIR}/_ext/820665871/qf_act.o ${OBJECTDIR}/_ext/820665871/qf_actq.o ${OBJECTDIR}/_ext/820665871/qf_defer.o ${OBJECTDIR}/_ext/820665871/qf_dyn.o ${OBJECTDIR}/_ext/820665871/qf_mem.o ${OBJECTDIR}/_ext/820665871/qf_ps.o ${OBJECTDIR}/_ext/820665871/qf_qact.o ${OBJECTDIR}/_ext/820665871/qf_qeq.o ${OBJECTDIR}/_ext/820665871/qf_qmact.o ${OBJECTDIR}/_ext/820665871/qf_time.o ${OBJECTDIR}/_ext/820665876/qk.o ${OBJECTDIR}/_ext/1627782163/qk_port.o ${OBJECTDIR}/_ext/820665884/qs.o ${OBJECTDIR}/_ext/820665884/qs_64bit.o ${OBJECTDIR}/_ext/820665884/qs_fp.o ${OBJECTDIR}/_ext/820665884/qs_rx.o ${OBJECTDIR}/bsp.o ${OBJECTDIR}/_ext/43898991/main.o ${OBJECTDIR}/_ext/726959463/qstamp.o ${OBJECTDIR}/_ext/43898991/philo.o ${OBJECTDIR}/_ext/43898991/table.o -POSSIBLE_DEPFILES=${OBJECTDIR}/_ext/820665871/qep_hsm.o.d ${OBJECTDIR}/_ext/820665871/qep_msm.o.d ${OBJECTDIR}/_ext/820665871/qf_act.o.d ${OBJECTDIR}/_ext/820665871/qf_actq.o.d ${OBJECTDIR}/_ext/820665871/qf_defer.o.d ${OBJECTDIR}/_ext/820665871/qf_dyn.o.d ${OBJECTDIR}/_ext/820665871/qf_mem.o.d ${OBJECTDIR}/_ext/820665871/qf_ps.o.d ${OBJECTDIR}/_ext/820665871/qf_qact.o.d ${OBJECTDIR}/_ext/820665871/qf_qeq.o.d ${OBJECTDIR}/_ext/820665871/qf_qmact.o.d ${OBJECTDIR}/_ext/820665871/qf_time.o.d ${OBJECTDIR}/_ext/820665876/qk.o.d ${OBJECTDIR}/_ext/1627782163/qk_port.o.d ${OBJECTDIR}/_ext/820665884/qs.o.d ${OBJECTDIR}/_ext/820665884/qs_64bit.o.d ${OBJECTDIR}/_ext/820665884/qs_fp.o.d ${OBJECTDIR}/_ext/820665884/qs_rx.o.d ${OBJECTDIR}/bsp.o.d ${OBJECTDIR}/_ext/43898991/main.o.d ${OBJECTDIR}/_ext/726959463/qstamp.o.d ${OBJECTDIR}/_ext/43898991/philo.o.d ${OBJECTDIR}/_ext/43898991/table.o.d +OBJECTFILES_QUOTED_IF_SPACED=${OBJECTDIR}/_ext/820665871/qep_hsm.o ${OBJECTDIR}/_ext/820665871/qep_msm.o ${OBJECTDIR}/_ext/820665871/qf_act.o ${OBJECTDIR}/_ext/820665871/qf_actq.o ${OBJECTDIR}/_ext/820665871/qf_defer.o ${OBJECTDIR}/_ext/820665871/qf_dyn.o ${OBJECTDIR}/_ext/820665871/qf_mem.o ${OBJECTDIR}/_ext/820665871/qf_ps.o ${OBJECTDIR}/_ext/820665871/qf_qact.o ${OBJECTDIR}/_ext/820665871/qf_qeq.o ${OBJECTDIR}/_ext/820665871/qf_qmact.o ${OBJECTDIR}/_ext/820665871/qf_time.o ${OBJECTDIR}/_ext/820665876/qk.o ${OBJECTDIR}/_ext/1627782163/qk_port.o ${OBJECTDIR}/_ext/820665884/qs.o ${OBJECTDIR}/_ext/820665884/qs_64bit.o ${OBJECTDIR}/_ext/820665884/qs_fp.o ${OBJECTDIR}/_ext/820665884/qs_rx.o ${OBJECTDIR}/_ext/820665884/qstamp.o ${OBJECTDIR}/bsp.o ${OBJECTDIR}/_ext/43898991/main.o ${OBJECTDIR}/_ext/43898991/philo.o ${OBJECTDIR}/_ext/43898991/table.o +POSSIBLE_DEPFILES=${OBJECTDIR}/_ext/820665871/qep_hsm.o.d ${OBJECTDIR}/_ext/820665871/qep_msm.o.d ${OBJECTDIR}/_ext/820665871/qf_act.o.d ${OBJECTDIR}/_ext/820665871/qf_actq.o.d ${OBJECTDIR}/_ext/820665871/qf_defer.o.d ${OBJECTDIR}/_ext/820665871/qf_dyn.o.d ${OBJECTDIR}/_ext/820665871/qf_mem.o.d ${OBJECTDIR}/_ext/820665871/qf_ps.o.d ${OBJECTDIR}/_ext/820665871/qf_qact.o.d ${OBJECTDIR}/_ext/820665871/qf_qeq.o.d ${OBJECTDIR}/_ext/820665871/qf_qmact.o.d ${OBJECTDIR}/_ext/820665871/qf_time.o.d ${OBJECTDIR}/_ext/820665876/qk.o.d ${OBJECTDIR}/_ext/1627782163/qk_port.o.d ${OBJECTDIR}/_ext/820665884/qs.o.d ${OBJECTDIR}/_ext/820665884/qs_64bit.o.d ${OBJECTDIR}/_ext/820665884/qs_fp.o.d ${OBJECTDIR}/_ext/820665884/qs_rx.o.d ${OBJECTDIR}/_ext/820665884/qstamp.o.d ${OBJECTDIR}/bsp.o.d ${OBJECTDIR}/_ext/43898991/main.o.d ${OBJECTDIR}/_ext/43898991/philo.o.d ${OBJECTDIR}/_ext/43898991/table.o.d # Object Files -OBJECTFILES=${OBJECTDIR}/_ext/820665871/qep_hsm.o ${OBJECTDIR}/_ext/820665871/qep_msm.o ${OBJECTDIR}/_ext/820665871/qf_act.o ${OBJECTDIR}/_ext/820665871/qf_actq.o ${OBJECTDIR}/_ext/820665871/qf_defer.o ${OBJECTDIR}/_ext/820665871/qf_dyn.o ${OBJECTDIR}/_ext/820665871/qf_mem.o ${OBJECTDIR}/_ext/820665871/qf_ps.o ${OBJECTDIR}/_ext/820665871/qf_qact.o ${OBJECTDIR}/_ext/820665871/qf_qeq.o ${OBJECTDIR}/_ext/820665871/qf_qmact.o ${OBJECTDIR}/_ext/820665871/qf_time.o ${OBJECTDIR}/_ext/820665876/qk.o ${OBJECTDIR}/_ext/1627782163/qk_port.o ${OBJECTDIR}/_ext/820665884/qs.o ${OBJECTDIR}/_ext/820665884/qs_64bit.o ${OBJECTDIR}/_ext/820665884/qs_fp.o ${OBJECTDIR}/_ext/820665884/qs_rx.o ${OBJECTDIR}/bsp.o ${OBJECTDIR}/_ext/43898991/main.o ${OBJECTDIR}/_ext/726959463/qstamp.o ${OBJECTDIR}/_ext/43898991/philo.o ${OBJECTDIR}/_ext/43898991/table.o +OBJECTFILES=${OBJECTDIR}/_ext/820665871/qep_hsm.o ${OBJECTDIR}/_ext/820665871/qep_msm.o ${OBJECTDIR}/_ext/820665871/qf_act.o ${OBJECTDIR}/_ext/820665871/qf_actq.o ${OBJECTDIR}/_ext/820665871/qf_defer.o ${OBJECTDIR}/_ext/820665871/qf_dyn.o ${OBJECTDIR}/_ext/820665871/qf_mem.o ${OBJECTDIR}/_ext/820665871/qf_ps.o ${OBJECTDIR}/_ext/820665871/qf_qact.o ${OBJECTDIR}/_ext/820665871/qf_qeq.o ${OBJECTDIR}/_ext/820665871/qf_qmact.o ${OBJECTDIR}/_ext/820665871/qf_time.o ${OBJECTDIR}/_ext/820665876/qk.o ${OBJECTDIR}/_ext/1627782163/qk_port.o ${OBJECTDIR}/_ext/820665884/qs.o ${OBJECTDIR}/_ext/820665884/qs_64bit.o ${OBJECTDIR}/_ext/820665884/qs_fp.o ${OBJECTDIR}/_ext/820665884/qs_rx.o ${OBJECTDIR}/_ext/820665884/qstamp.o ${OBJECTDIR}/bsp.o ${OBJECTDIR}/_ext/43898991/main.o ${OBJECTDIR}/_ext/43898991/philo.o ${OBJECTDIR}/_ext/43898991/table.o # Source Files -SOURCEFILES=../../../../../src/qf/qep_hsm.c ../../../../../src/qf/qep_msm.c ../../../../../src/qf/qf_act.c ../../../../../src/qf/qf_actq.c ../../../../../src/qf/qf_defer.c ../../../../../src/qf/qf_dyn.c ../../../../../src/qf/qf_mem.c ../../../../../src/qf/qf_ps.c ../../../../../src/qf/qf_qact.c ../../../../../src/qf/qf_qeq.c ../../../../../src/qf/qf_qmact.c ../../../../../src/qf/qf_time.c ../../../../../src/qk/qk.c ../../../../../ports/pic32/qk/xc32/qk_port.c ../../../../../src/qs/qs.c ../../../../../src/qs/qs_64bit.c ../../../../../src/qs/qs_fp.c ../../../../../src/qs/qs_rx.c bsp.c ../../main.c ../../../../../include/qstamp.c ../../philo.c ../../table.c +SOURCEFILES=../../../../../src/qf/qep_hsm.c ../../../../../src/qf/qep_msm.c ../../../../../src/qf/qf_act.c ../../../../../src/qf/qf_actq.c ../../../../../src/qf/qf_defer.c ../../../../../src/qf/qf_dyn.c ../../../../../src/qf/qf_mem.c ../../../../../src/qf/qf_ps.c ../../../../../src/qf/qf_qact.c ../../../../../src/qf/qf_qeq.c ../../../../../src/qf/qf_qmact.c ../../../../../src/qf/qf_time.c ../../../../../src/qk/qk.c ../../../../../ports/pic32/qk/xc32/qk_port.c ../../../../../src/qs/qs.c ../../../../../src/qs/qs_64bit.c ../../../../../src/qs/qs_fp.c ../../../../../src/qs/qs_rx.c ../../../../../src/qs/qstamp.c bsp.c ../../main.c ../../philo.c ../../table.c CFLAGS= @@ -214,6 +214,12 @@ ${OBJECTDIR}/_ext/820665884/qs_rx.o: ../../../../../src/qs/qs_rx.c nbproject/Ma @${RM} ${OBJECTDIR}/_ext/820665884/qs_rx.o @${FIXDEPS} "${OBJECTDIR}/_ext/820665884/qs_rx.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -D__DEBUG -D__MPLAB_DEBUGGER_PK3=1 -fframe-base-loclist -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -DQ_SPY -I"../../../../../include" -I"../../../../../src" -I"../../../../../ports/pic32/qk/xc32" -I"../.." -MMD -MF "${OBJECTDIR}/_ext/820665884/qs_rx.o.d" -o ${OBJECTDIR}/_ext/820665884/qs_rx.o ../../../../../src/qs/qs_rx.c -DXPRJ_spy=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 +${OBJECTDIR}/_ext/820665884/qstamp.o: ../../../../../src/qs/qstamp.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/_ext/820665884" + @${RM} ${OBJECTDIR}/_ext/820665884/qstamp.o.d + @${RM} ${OBJECTDIR}/_ext/820665884/qstamp.o + @${FIXDEPS} "${OBJECTDIR}/_ext/820665884/qstamp.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -D__DEBUG -D__MPLAB_DEBUGGER_PK3=1 -fframe-base-loclist -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -DQ_SPY -I"../../../../../include" -I"../../../../../src" -I"../../../../../ports/pic32/qk/xc32" -I"../.." -MMD -MF "${OBJECTDIR}/_ext/820665884/qstamp.o.d" -o ${OBJECTDIR}/_ext/820665884/qstamp.o ../../../../../src/qs/qstamp.c -DXPRJ_spy=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 + ${OBJECTDIR}/bsp.o: bsp.c nbproject/Makefile-${CND_CONF}.mk @${MKDIR} "${OBJECTDIR}" @${RM} ${OBJECTDIR}/bsp.o.d @@ -226,12 +232,6 @@ ${OBJECTDIR}/_ext/43898991/main.o: ../../main.c nbproject/Makefile-${CND_CONF}. @${RM} ${OBJECTDIR}/_ext/43898991/main.o @${FIXDEPS} "${OBJECTDIR}/_ext/43898991/main.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -D__DEBUG -D__MPLAB_DEBUGGER_PK3=1 -fframe-base-loclist -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -DQ_SPY -I"../../../../../include" -I"../../../../../src" -I"../../../../../ports/pic32/qk/xc32" -I"../.." -MMD -MF "${OBJECTDIR}/_ext/43898991/main.o.d" -o ${OBJECTDIR}/_ext/43898991/main.o ../../main.c -DXPRJ_spy=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 -${OBJECTDIR}/_ext/726959463/qstamp.o: ../../../../../include/qstamp.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/726959463" - @${RM} ${OBJECTDIR}/_ext/726959463/qstamp.o.d - @${RM} ${OBJECTDIR}/_ext/726959463/qstamp.o - @${FIXDEPS} "${OBJECTDIR}/_ext/726959463/qstamp.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -D__DEBUG -D__MPLAB_DEBUGGER_PK3=1 -fframe-base-loclist -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -DQ_SPY -I"../../../../../include" -I"../../../../../src" -I"../../../../../ports/pic32/qk/xc32" -I"../.." -MMD -MF "${OBJECTDIR}/_ext/726959463/qstamp.o.d" -o ${OBJECTDIR}/_ext/726959463/qstamp.o ../../../../../include/qstamp.c -DXPRJ_spy=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - ${OBJECTDIR}/_ext/43898991/philo.o: ../../philo.c nbproject/Makefile-${CND_CONF}.mk @${MKDIR} "${OBJECTDIR}/_ext/43898991" @${RM} ${OBJECTDIR}/_ext/43898991/philo.o.d @@ -353,6 +353,12 @@ ${OBJECTDIR}/_ext/820665884/qs_rx.o: ../../../../../src/qs/qs_rx.c nbproject/Ma @${RM} ${OBJECTDIR}/_ext/820665884/qs_rx.o @${FIXDEPS} "${OBJECTDIR}/_ext/820665884/qs_rx.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -DQ_SPY -I"../../../../../include" -I"../../../../../src" -I"../../../../../ports/pic32/qk/xc32" -I"../.." -MMD -MF "${OBJECTDIR}/_ext/820665884/qs_rx.o.d" -o ${OBJECTDIR}/_ext/820665884/qs_rx.o ../../../../../src/qs/qs_rx.c -DXPRJ_spy=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 +${OBJECTDIR}/_ext/820665884/qstamp.o: ../../../../../src/qs/qstamp.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/_ext/820665884" + @${RM} ${OBJECTDIR}/_ext/820665884/qstamp.o.d + @${RM} ${OBJECTDIR}/_ext/820665884/qstamp.o + @${FIXDEPS} "${OBJECTDIR}/_ext/820665884/qstamp.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -DQ_SPY -I"../../../../../include" -I"../../../../../src" -I"../../../../../ports/pic32/qk/xc32" -I"../.." -MMD -MF "${OBJECTDIR}/_ext/820665884/qstamp.o.d" -o ${OBJECTDIR}/_ext/820665884/qstamp.o ../../../../../src/qs/qstamp.c -DXPRJ_spy=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 + ${OBJECTDIR}/bsp.o: bsp.c nbproject/Makefile-${CND_CONF}.mk @${MKDIR} "${OBJECTDIR}" @${RM} ${OBJECTDIR}/bsp.o.d @@ -365,12 +371,6 @@ ${OBJECTDIR}/_ext/43898991/main.o: ../../main.c nbproject/Makefile-${CND_CONF}. @${RM} ${OBJECTDIR}/_ext/43898991/main.o @${FIXDEPS} "${OBJECTDIR}/_ext/43898991/main.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -DQ_SPY -I"../../../../../include" -I"../../../../../src" -I"../../../../../ports/pic32/qk/xc32" -I"../.." -MMD -MF "${OBJECTDIR}/_ext/43898991/main.o.d" -o ${OBJECTDIR}/_ext/43898991/main.o ../../main.c -DXPRJ_spy=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 -${OBJECTDIR}/_ext/726959463/qstamp.o: ../../../../../include/qstamp.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/726959463" - @${RM} ${OBJECTDIR}/_ext/726959463/qstamp.o.d - @${RM} ${OBJECTDIR}/_ext/726959463/qstamp.o - @${FIXDEPS} "${OBJECTDIR}/_ext/726959463/qstamp.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -DQ_SPY -I"../../../../../include" -I"../../../../../src" -I"../../../../../ports/pic32/qk/xc32" -I"../.." -MMD -MF "${OBJECTDIR}/_ext/726959463/qstamp.o.d" -o ${OBJECTDIR}/_ext/726959463/qstamp.o ../../../../../include/qstamp.c -DXPRJ_spy=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - ${OBJECTDIR}/_ext/43898991/philo.o: ../../philo.c nbproject/Makefile-${CND_CONF}.mk @${MKDIR} "${OBJECTDIR}/_ext/43898991" @${RM} ${OBJECTDIR}/_ext/43898991/philo.o.d diff --git a/examples/pic32/dpp_microstick2-pic32/qk/xc32/nbproject/configurations.xml b/examples/pic32/dpp_microstick2-pic32/qk/xc32/nbproject/configurations.xml index 4a6839e9..c46a2665 100644 --- a/examples/pic32/dpp_microstick2-pic32/qk/xc32/nbproject/configurations.xml +++ b/examples/pic32/dpp_microstick2-pic32/qk/xc32/nbproject/configurations.xml @@ -30,6 +30,7 @@ ../../../../../src/qs/qs_64bit.c ../../../../../src/qs/qs_fp.c ../../../../../src/qs/qs_rx.c + ../../../../../src/qs/qstamp.c bsp.c ../../bsp.h ../../main.c - ../../../../../include/qstamp.c ../../philo.c ../../table.c @@ -289,6 +289,7 @@ + @@ -735,6 +736,7 @@ + diff --git a/examples/pic32/dpp_microstick2-pic32/qk/xc32/nbproject/private/configurations.xml b/examples/pic32/dpp_microstick2-pic32/qk/xc32/nbproject/private/configurations.xml index 01328964..efadbc59 100644 --- a/examples/pic32/dpp_microstick2-pic32/qk/xc32/nbproject/private/configurations.xml +++ b/examples/pic32/dpp_microstick2-pic32/qk/xc32/nbproject/private/configurations.xml @@ -4,7 +4,7 @@ 0 - + :=MPLABComm-USB-Microchip:=<vid>04D8:=<pid>8107:=<rev>0002:=<man>Microchip Technology Incorporated:=<prod>Microstick II SK:=<sn>BUR123045184:=<drv>x:=<xpt>h:=end C:\tools\Microchip\xc32\bin place holder 1 @@ -40,7 +40,7 @@ - + :=MPLABComm-USB-Microchip:=<vid>04D8:=<pid>8107:=<rev>0002:=<man>Microchip Technology Incorporated:=<prod>Microstick II SK:=<sn>BUR123045184:=<drv>x:=<xpt>h:=end C:\tools\Microchip\xc32\bin place holder 1 diff --git a/examples/pic32/dpp_microstick2-pic32/qk/xc32/nbproject/private/private.xml b/examples/pic32/dpp_microstick2-pic32/qk/xc32/nbproject/private/private.xml index 4f8159a2..bd868ccf 100644 --- a/examples/pic32/dpp_microstick2-pic32/qk/xc32/nbproject/private/private.xml +++ b/examples/pic32/dpp_microstick2-pic32/qk/xc32/nbproject/private/private.xml @@ -5,6 +5,10 @@ file:/C:/qp-dev/qpc/src/qs/qs_64bit.c + file:/C:/qp-dev/qpc/examples/pic32/dpp_microstick2-pic32/qk/xc32/bsp.c + file:/C:/qp-dev/qpc/src/qk/qk.c + file:/C:/qp-dev/qpc/examples/pic32/dpp_microstick2-pic32/main.c + file:/C:/qp-dev/qpc/ports/pic32/qk/xc32/qk_port.c diff --git a/examples/pic32/dpp_microstick2-pic32/qv/xc32/bsp.c b/examples/pic32/dpp_microstick2-pic32/qv/xc32/bsp.c index 68bd9a2e..871f451a 100644 --- a/examples/pic32/dpp_microstick2-pic32/qv/xc32/bsp.c +++ b/examples/pic32/dpp_microstick2-pic32/qv/xc32/bsp.c @@ -1,292 +1,387 @@ -/***************************************************************************** -* BSP for DPP example, Microstick II board, cooperative QV kernel, XC32 -* Last updated for version 6.9.1 -* Last updated on 2020-09-22 -* -* Q u a n t u m L e a P s -* ------------------------ -* Modern Embedded Software -* -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* -* -*****************************************************************************/ -#include "qpc.h" -#include "bsp.h" -#include "dpp.h" +//============================================================================ +// BSP for DPP example, Microstick II board, cooperative QV kernel, XC32 +// Last updated for version 7.3.0 +// Last updated on 2023-08-21 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. +// +// This program is open source software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Alternatively, this program may be distributed and modified under the +// terms of Quantum Leaps commercial licenses, which expressly supersede +// the GNU General Public License and are specifically designed for +// licensees interested in retaining the proprietary status of their code. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Contact information: +// +// +//============================================================================ +#include "qpc.h" // QP/C real-time embedded framework +#include "dpp.h" // DPP Application interface +#include "bsp.h" // Board Support Package Q_DEFINE_THIS_FILE -#pragma config FNOSC = FRCPLL /* 8 MHz */ -#pragma config FPLLIDIV = DIV_2 /* 4 MHz */ -#pragma config FPLLMUL = MUL_20 /* 80 MHz */ -#pragma config FPLLODIV = DIV_2 /* 40 MHz == FRC */ -#pragma config FWDTEN = OFF /* watchdog off */ -#pragma config FPBDIV = DIV_1 /* same peripheral clock */ +#pragma config FNOSC = FRCPLL // 8 MHz +#pragma config FPLLIDIV = DIV_2 // 4 MHz +#pragma config FPLLMUL = MUL_20 // 80 MHz +#pragma config FPLLODIV = DIV_2 // 40 MHz == FRC +#pragma config FWDTEN = OFF // watchdog off +#pragma config FPBDIV = DIV_1 // same peripheral clock -/* #pragma config statements should precede project file includes */ -#include /* header for PIC32 device in use */ +// #pragma config statements should precede project file includes +#include // header for PIC32 device in use #include -/* system clock using FRC and PLL: 40 MHz */ +// system clock using FRC and PLL: 40 MHz #define SYS_FREQ 40000000U -/* peripheral clock frequency */ +// peripheral clock frequency #define PER_HZ (SYS_FREQ / 1U) -/* controlling the LED of Microstick II */ -#define LED_ON() (LATASET = (1U << 0)) -#define LED_OFF() (LATACLR = (1U << 0)) -#define LED_TOGGLE() (LATAINV = (1U << 0)) +// controlling the LED of Microstick II +#define LED_ON() (LATASET = (1U << 0U)) +#define LED_OFF() (LATACLR = (1U << 0U)) +#define LED_TOGGLE() (LATAINV = (1U << 0U)) -/* Local-scope objects -----------------------------------------------------*/ -static uint32_t l_rnd; /* random seed */ +// Local-scope objects ----------------------------------------------------- +static uint32_t l_rndSeed; #ifdef Q_SPY - static uint8_t const l_tickISR = 0U; - static uint8_t const l_testISR = 0U; + // QSpy source IDs + static QSpyId const l_tickISR = {0U}; + static QSpyId const l_testISR = {0U}; - enum AppRecords { /* application-specific trace records */ - PHILO_STAT = QS_USER + enum AppRecords { // application-specific trace records + PHILO_STAT = QS_USER, + PAUSED_STAT, + CONTEXT_SW, }; -#endif +#endif // Q_SPY -/* ISRs --------------------------------------------------------------------*/ -void __ISR(_TIMER_2_VECTOR, IPL4SOFT) tickISR(void) { - IFS0CLR = _IFS0_T2IF_MASK; /* clear the interrupt source */ +//============================================================================ +// Error handler and ISRs... - QTIMEEVT_TICK_X(0U, &l_tickISR); /* handle armed time events at tick rate 0 */ -} -/*..........................................................................*/ -/* for testing interrupt nesting and active object preemption */ -void __ISR(_EXTERNAL_0_VECTOR, IPL6SOFT) testISR(void) { - static QEvt const eat_evt = { EAT_SIG, 0U, 0U }; +Q_NORETURN Q_onError(char const * const module, int_t const id) { + // NOTE: this implementation of the error handler is intended only + // for debugging and MUST be changed for deployment of the application + // (assuming that you ship your production code with assertions enabled). + Q_UNUSED_PAR(module); + Q_UNUSED_PAR(id); + QS_ASSERTION(module, id, 10000U); // report assertion to QS - IFS0CLR = _IFS0_INT0IF_MASK; /* clear the interrupt source */ - - QACTIVE_POST(AO_Table, &eat_evt, &l_testISR); -} - -/*--------------------------------------------------------------------------*/ -void BSP_init(void) { - TRISA = 0x00; /* set LED pins as outputs */ - PORTA = 0x00; /* set LED drive state low */ - - BSP_randomSeed(1234U); - - Q_ALLEGE(QS_INIT((void *)0) != 0); /*initialize the QS software tracing */ - QS_OBJ_DICTIONARY(&l_tickISR); - QS_OBJ_DICTIONARY(&l_testISR); - - /* setup the QS filters... */ - QS_GLB_FILTER(QS_SM_RECORDS); /* state machine records */ - QS_GLB_FILTER(QS_AO_RECORDS); /* active object records */ - QS_GLB_FILTER(QS_UA_RECORDS); /* all user records */ -} -/*..........................................................................*/ -void BSP_terminate(int16_t result) { - (void)result; -} -/*..........................................................................*/ -void BSP_displayPhilStat(uint8_t const n, char const *stat) { - (void)n; - (void)stat; - LED_TOGGLE(); - - QS_BEGIN_ID(PHILO_STAT, AO_Philo[n]->prio) /* app-specific record */ - QS_U8(1, n); /* Philosopher number */ - QS_STR(stat); /* Philosopher status */ - QS_END() -} -/*..........................................................................*/ -void BSP_displayPaused(uint8_t const paused) { - (void)paused; -} -/*..........................................................................*/ -uint32_t BSP_random(void) { /* a cheap pseudo-random-number generator */ - /* "Super-Duper" Linear Congruential Generator (LCG) - * LCG(2^32, 3*7*11*13*23, 0, seed) - */ - l_rnd = l_rnd * (3U*7U*11U*13U*23U); - return l_rnd >> 8; -} -/*..........................................................................*/ -void BSP_randomSeed(uint32_t seed) { - l_rnd = seed; -} -/*..........................................................................*/ -/* NOTE: this implementation of the assertion handler is intended only for -* debugging and MUST be changed for deployment of the application (assuming -* that you ship your production code with assertions enabled). -*/ - -Q_NORETURN Q_onAssert(char const * const file, int_t const loc) { - (void)file; /* unused parameter */ - (void)loc; /* unused parameter */ - QF_INT_DISABLE(); /* make sure that interrupts are disabled */ +#ifndef NDEBUG + // for debugging, hang on in an endless loop... for (;;) { } +#else + // perform a system unlock sequence ,starting critical sequence + SYSKEY = 0x00000000U; //write invalid key to force lock + SYSKEY = 0xAA996655U; //write key1 to SYSKEY + SYSKEY = 0x556699AAU; //write key2 to SYSKEY + // set SWRST bit to arm reset + RSWRSTSET = 1U; + // read RSWRST register to trigger reset + uint32_t volatile dummy = RSWRST; + for (;;) { // explicitly "no-return" + } +#endif +} +//............................................................................ +void assert_failed(char const * const module, int_t const id); // prototype +void assert_failed(char const * const module, int_t const id) { + Q_onError(module, id); } -/*..........................................................................*/ -void QF_onStartup(void) { /* entered with interrupts locked */ - INTCONSET = _INTCON_MVEC_MASK; /* configure multi-vectored interrupts */ +// ISRs -------------------------------------------------------------------- +void __ISR(_TIMER_2_VECTOR, IPL4SOFT) tickISR(void) { - T2CON = 0x0060; /* stop timer, set up for 1:64 prescaler */ - TMR2 = 0; /* count from zero up to the period */ - PR2 = SYS_FREQ / (BSP_TICKS_PER_SEC * 64); /* set the Timer2 period */ - IFS0CLR = _IFS0_T2IF_MASK; /* clear Timer2 Interrupt Flag */ - IEC0SET = _IEC0_T2IE_MASK; /* enable Timer2 interrupt */ - T2CONSET = _T2CON_ON_MASK; /* Start Timer2 */ + IFS0CLR = _IFS0_T2IF_MASK; // clear the interrupt source - INTCONbits.INT0EP = 1; /* INT0 interrupt on positive edge */ - IEC0SET = _IEC0_INT0IE_MASK; /* enable INT0 interrupt */ - IFS0CLR = _IFS0_INT0IF_MASK; /* clear the interrupt for INT0 */ - - /* explicitly assign priorities to all interrupts... */ - /* NOTE: must match the IPLxSOFT settings in the __ISR() macros */ - IPC2bits.T2IP = 4; /* Timer2 interrupt priority, must match tickISR */ - IPC0bits.INT0IP = 6; /* set INT0 priority; must match IPL in testISR */ + QTIMEEVT_TICK_X(0U, &l_tickISR); // handle time events at tick rate 0 } -/*..........................................................................*/ +//............................................................................ +// for testing interrupt nesting and active object preemption +void __ISR(_EXTERNAL_0_VECTOR, IPL6SOFT) testISR(void) { + IFS0CLR = _IFS0_INT0IF_MASK; // clear the interrupt source + + static QEvt const eat_evt = QEVT_INITIALIZER(EAT_SIG); + QACTIVE_POST(AO_Table, &eat_evt, &l_testISR); +} +//............................................................................ +#ifdef QF_ON_CONTEXT_SW +// NOTE: the context-switch callback is called with interrupts DISABLED +void QF_onContextSw(QActive *prev, QActive *next) { + QS_BEGIN_INCRIT(CONTEXT_SW, 0U) // in critical section! + QS_OBJ(prev); + QS_OBJ(next); + QS_END_INCRIT() +} +#endif // QF_ON_CONTEXT_SW + + +// BSP functions ============================================================= + +void BSP_init(void) { + TRISA = 0x00U; // set LED pins as outputs + PORTA = 0x00U; // set LED drive state low + + BSP_randomSeed(1234U); // seed the random number generator + + // initialize the QS software tracing + if (!QS_INIT((void *)0)) { + Q_ERROR(); + } + + // dictionaries... + QS_OBJ_DICTIONARY(&l_tickISR); + QS_OBJ_DICTIONARY(&l_testISR); + QS_USR_DICTIONARY(PHILO_STAT); + QS_USR_DICTIONARY(PAUSED_STAT); + QS_USR_DICTIONARY(CONTEXT_SW); + + QS_ONLY(produce_sig_dict()); + + // setup the QS filters... + QS_GLB_FILTER(QS_ALL_RECORDS); // all records + QS_GLB_FILTER(-QS_QF_TICK); // exclude the clock tick +} +//............................................................................ +void BSP_start(void) { + // initialize event pools + static QF_MPOOL_EL(TableEvt) smlPoolSto[2*N_PHILO]; + QF_poolInit(smlPoolSto, sizeof(smlPoolSto), sizeof(smlPoolSto[0])); + + // initialize publish-subscribe + static QSubscrList subscrSto[MAX_PUB_SIG]; + QActive_psInit(subscrSto, Q_DIM(subscrSto)); + + // instantiate and start AOs/threads... + + static QEvt const *philoQueueSto[N_PHILO][10]; + for (uint8_t n = 0U; n < N_PHILO; ++n) { + Philo_ctor(n); + QACTIVE_START(AO_Philo[n], + n + 3U, // QF-prio. + philoQueueSto[n], // event queue storage + Q_DIM(philoQueueSto[n]), // queue length [events] + (void *)0, 0U, // no stack storage + (void *)0); // no initialization param + } + + static QEvt const *tableQueueSto[N_PHILO]; + Table_ctor(); + QACTIVE_START(AO_Table, + N_PHILO + 7U, // QP prio. of the AO + tableQueueSto, // event queue storage + Q_DIM(tableQueueSto), // queue length [events] + (void *)0, 0U, // no stack storage + (void *)0); // no initialization param +} +//............................................................................ +void BSP_terminate(int16_t result) { + Q_UNUSED_PAR(result); +} +//............................................................................ +void BSP_displayPhilStat(uint8_t const n, char const *stat) { + Q_UNUSED_PAR(n); + + if (stat[0] == 'e') { // is Philo eating? + LED_ON(); + } + else { + LED_OFF(); + } + + // app-specific record + QS_BEGIN_ID(PHILO_STAT, AO_Table->prio) + QS_U8(1, n); // Philosopher number + QS_STR(stat); // Philosopher status + QS_END() +} +//............................................................................ +void BSP_displayPaused(uint8_t const paused) { + Q_UNUSED_PAR(paused); + + // application-specific trace record + QS_BEGIN_ID(PAUSED_STAT, AO_Table->prio) + QS_U8(1, paused); // Paused status + QS_END() +} +//............................................................................ +void BSP_randomSeed(uint32_t seed) { + l_rndSeed = seed; +} +//............................................................................ +uint32_t BSP_random(void) { // a cheap pseudo-random-number generator + + // "Super-Duper" Linear Congruential Generator (LCG) + // LCG(2^32, 3*7*11*13*23, 0, seed) + uint32_t rnd = l_rndSeed * (3U*7U*11U*13U*23U); + l_rndSeed = rnd; // update for the next time + + return (rnd >> 8U); +} + + +//=========================================================================== + +void QF_onStartup(void) { + INTCONSET = _INTCON_MVEC_MASK; // configure multi-vectored interrupts + + T2CON = 0x0060U; // stop timer, set up for 1:64 prescaler + TMR2 = 0U; // count from zero up to the period + PR2 = SYS_FREQ / (BSP_TICKS_PER_SEC * 64U); // set the Timer2 period + IFS0CLR = _IFS0_T2IF_MASK; // clear Timer2 Interrupt Flag + IEC0SET = _IEC0_T2IE_MASK; // enable Timer2 interrupt + T2CONSET = _T2CON_ON_MASK; // Start Timer2 + + INTCONbits.INT0EP = 1U; // INT0 interrupt on positive edge + IEC0SET = _IEC0_INT0IE_MASK; // enable INT0 interrupt + IFS0CLR = _IFS0_INT0IF_MASK; // clear the interrupt for INT0 + + // explicitly assign priorities to all interrupts... + // NOTE: must match the IPLxSOFT settings in the __ISR() macros + IPC2bits.T2IP = 4U; // Timer2 interrupt priority, must match tickISR + IPC0bits.INT0IP = 6U; // set INT0 priority; must match IPL in testISR +} +//............................................................................ void QF_onCleanup(void) { } -/*..........................................................................*/ -void QV_onIdle(void) { /* entered with interrupts DISABLED, see NOTE01 */ +//............................................................................ +void QV_onIdle(void) { // CAUTION: called with interrupts DISABLED, see NOTE1 - /* NOTE: not enough LEDs on the Microstick II board to implement - * the idle loop activity indicator ... - */ - //LED_ON (); /* blink the IDLE LED, see NOTE01 */ + // NOTE: not enough LEDs on the Microstick II board to implement + // the idle loop activity indicator ... + //LED_ON (); // blink the IDLE LED, see NOTE1 //LED_OFF(); #ifdef Q_SPY - QF_INT_ENABLE(); /* enable interrupts, see NOTE01 */ - - while (U2STAbits.UTXBF == 0) { /* TX Buffer not full? */ - uint16_t b; - + QF_INT_ENABLE(); // enable interrupts, see NOTE1 + while (U2STAbits.UTXBF == 0U) { // TX Buffer not full? QF_INT_DISABLE(); - b = QS_getByte(); + uint16_t b = QS_getByte(); QF_INT_ENABLE(); - if (b == QS_EOD) { /* End-Of-Data reached? */ - break; /* break out of the loop */ + if (b != QS_EOD) { // End-Of-Data reached? + U2TXREG = b; // stick the byte to TXREG for transmission + } + else { + break; // break out of the loop } - U2TXREG = (uint8_t)b; /* stick the byte to TXREG for transmission */ } #elif defined NDEBUG - INTCONbits.TPC = 7; /* enable the Proximity Timer for all IPLs, NOTE01 */ - IPTMR = 4; /* set the proximity timer to 4 CPU clocks */ - QF_INT_ENABLE(); /* enable CPU interrupts */ - _wait(); /* execute the WAIT instruction to stop the CPU */ - INTCONbits.TPC = 0; /* disable the Proximity Timer for all IPLs */ + INTCONbits.TPC = 7U; // enable the Proximity Timer for all IPLs, NOTE1 + IPTMR = 4U; // set the proximity timer to 4 CPU clocks + QF_INT_ENABLE(); // enable CPU interrupts + _wait(); // execute the WAIT instruction to stop the CPU + INTCONbits.TPC = 0U; // disable the Proximity Timer for all IPLs #else - QF_INT_ENABLE(); /* enable interrupts, see NOTE01 */ + QF_INT_ENABLE(); // enable interrupts, see NOTE1 #endif } -/*--------------------------------------------------------------------------*/ +//============================================================================ +// QS callbacks... #ifdef Q_SPY -#define QS_BUF_SIZE 4096 -#define QS_BAUD_RATE 115200 +#define QS_BUF_SIZE 4096U +#define QS_BAUD_RATE 115200U +//............................................................................ uint8_t QS_onStartup(void const *arg) { - static uint8_t qsBuf[QS_BUF_SIZE]; /* buffer for Quantum Spy */ + Q_UNUSED_PAR(arg); - QS_initBuf(qsBuf, sizeof(qsBuf)); /* initialize the QS trace buffer */ + static uint8_t qsBuf[QS_BUF_SIZE]; // buffer for QS-TX + QS_initBuf(qsBuf, sizeof(qsBuf)); // initialize the QS-TX channel - /* initialize the UART2 for transmitting the QS trace data */ - U2RXRbits.U2RXR = 3; /* Set U2RX to RPB11, pin 22, J6-5 */ - RPB10Rbits.RPB10R = 2; /* Set U2TX to RPB10, pin 21, J6-4 */ + //TBD: implement QS-RX channel - U2STA = 0x0000U; /* use default settings of 8N1 */ - U2MODE = 0x0008U; /* enable high baud rate */ + // initialize the UART2 for transmitting the QS trace data + U2RXRbits.U2RXR = 3; // Set U2RX to RPB11, pin 22, J6-5 + RPB10Rbits.RPB10R = 2; // Set U2TX to RPB10, pin 21, J6-4 + + U2STA = 0x0000U; // use default settings of 8N1 + U2MODE = 0x0008U; // enable high baud rate U2BRG = (uint16_t)((PER_HZ / (4.0 * QS_BAUD_RATE)) - 1.0 + 0.5); U2MODEbits.UARTEN = 1; U2STAbits.UTXEN = 1; - return 1U; /* indicate successfull QS initialization */ + return 1U; // return success } -/*..........................................................................*/ +//............................................................................ void QS_onCleanup(void) { } -/*..........................................................................*/ +//............................................................................ void QS_onFlush(void) { uint16_t b; - while ((b = QS_getByte()) != QS_EOD) { /* next QS trace byte available? */ - while (U2STAbits.UTXBF) { /* TX Buffer full? */ + while ((b = QS_getByte()) != QS_EOD) { // next QS trace byte available? + while (U2STAbits.UTXBF) { // TX Buffer full? } - U2TXREG = (uint8_t)b; /* stick the byte to TXREG for transmission */ + U2TXREG = b; // stick the byte to TXREG for transmission } } -/*..........................................................................*/ -/* NOTE: works properly with interrupts enabled or disabled */ +//............................................................................ +// NOTE: works properly with interrupts enabled or disabled QSTimeCtr QS_onGetTime(void) { - return __builtin_mfc0(_CP0_COUNT, _CP0_COUNT_SELECT); + return __builtin_mfc0(_CP0_COUNT, _CP0_COUNT_SELECT); } -/*..........................................................................*/ -/*! callback function to reset the target (to be implemented in the BSP) */ +//............................................................................ +//! callback function to reset the target (to be implemented in the BSP) void QS_onReset(void) { - uint32_t dummy; - - /* perform a system unlock sequence ,starting critical sequence*/ + // perform a system unlock sequence ,starting critical sequence SYSKEY = 0x00000000; //write invalid key to force lock SYSKEY = 0xAA996655; //write key1 to SYSKEY SYSKEY = 0x556699AA; //write key2 to SYSKEY - /* set SWRST bit to arm reset */ + // set SWRST bit to arm reset RSWRSTSET = 1; - /* read RSWRST register to trigger reset */ - dummy = RSWRST; - /* prevent any unwanted code execution until reset occurs*/} -/*..........................................................................*/ -/*! callback function to execute a user command (to be implemented in BSP) */ + // read RSWRST register to trigger reset + uint32_t volatile dummy = RSWRST; + // prevent any unwanted code execution until reset occurs +} +//............................................................................ +//! callback function to execute a user command (to be implemented in BSP) void QS_onCommand(uint8_t cmdId, uint32_t param1, uint32_t param2, uint32_t param3) { - (void)cmdId; - (void)param1; - (void)param2; - (void)param3; + Q_UNUSED_PAR(cmdId); + Q_UNUSED_PAR(param1); + Q_UNUSED_PAR(param2); + Q_UNUSED_PAR(param3); } -#endif /* Q_SPY */ +#endif // Q_SPY +//---------------------------------------------------------------------------- -/***************************************************************************** -* NOTE01: -* The callback function QV_onIdle() is called with interrupts disabled, -* because the idle condition can be invalidated by any enabled interrupt -* that would post events. The QV_onIdle() function *must* re-enable interrupts - internally -* -* NOTE02: -* The Temporal Proximity Timer is used to prevent a race condition of -* servicing an interrupt after re-enabling interrupts and before executing -* the WAIT instruction. The Proximity Timer is enabled for all interrupt -* priority levels (see QF_onStartup()). The Proximity Timer is set to 4 -* CPU clocks right before re-enabling interrupts (with the DI instruction) -* The 4 clock ticks should be enough to execute the (DI,WAIT) instruction -* pair _atomically_. -*/ +//============================================================================ +// NOTE1: +// The callback function QV_onIdle() is called with interrupts disabled, +// because the idle condition can be invalidated by any enabled interrupt +// that would post events. The QV_onIdle() function *must* re-enable interrupts +// internally +// +// NOTE2: +// The Temporal Proximity Timer is used to prevent a race condition of +// servicing an interrupt after re-enabling interrupts and before executing +// the WAIT instruction. The Proximity Timer is enabled for all interrupt +// priority levels (see QF_onStartup()). The Proximity Timer is set to 4 +// CPU clocks right before re-enabling interrupts (with the DI instruction) +// The 4 clock ticks should be enough to execute the (DI,WAIT) instruction +// pair _atomically_. +// diff --git a/examples/pic32/dpp_microstick2-pic32/qv/xc32/nbproject/Makefile-dbg.mk b/examples/pic32/dpp_microstick2-pic32/qv/xc32/nbproject/Makefile-dbg.mk index 0daac032..7cfc816d 100644 --- a/examples/pic32/dpp_microstick2-pic32/qv/xc32/nbproject/Makefile-dbg.mk +++ b/examples/pic32/dpp_microstick2-pic32/qv/xc32/nbproject/Makefile-dbg.mk @@ -57,17 +57,17 @@ OBJECTDIR=build/${CND_CONF}/${IMAGE_TYPE} DISTDIR=dist/${CND_CONF}/${IMAGE_TYPE} # Source Files Quoted if spaced -SOURCEFILES_QUOTED_IF_SPACED=../../../../../src/qf/qep_hsm.c ../../../../../src/qf/qep_msm.c ../../../../../src/qf/qf_act.c ../../../../../src/qf/qf_actq.c ../../../../../src/qf/qf_defer.c ../../../../../src/qf/qf_dyn.c ../../../../../src/qf/qf_mem.c ../../../../../src/qf/qf_ps.c ../../../../../src/qf/qf_qact.c ../../../../../src/qf/qf_qeq.c ../../../../../src/qf/qf_qmact.c ../../../../../src/qf/qf_time.c ../../../../../src/qv/qv.c bsp.c ../../main.c ../../../../../include/qstamp.c ../../philo.c ../../table.c +SOURCEFILES_QUOTED_IF_SPACED=../../../../../src/qf/qep_hsm.c ../../../../../src/qf/qep_msm.c ../../../../../src/qf/qf_act.c ../../../../../src/qf/qf_actq.c ../../../../../src/qf/qf_defer.c ../../../../../src/qf/qf_dyn.c ../../../../../src/qf/qf_mem.c ../../../../../src/qf/qf_ps.c ../../../../../src/qf/qf_qact.c ../../../../../src/qf/qf_qeq.c ../../../../../src/qf/qf_qmact.c ../../../../../src/qf/qf_time.c ../../../../../src/qv/qv.c ../../../../../src/qs/qstamp.c bsp.c ../../main.c ../../philo.c ../../table.c # Object Files Quoted if spaced -OBJECTFILES_QUOTED_IF_SPACED=${OBJECTDIR}/_ext/820665871/qep_hsm.o ${OBJECTDIR}/_ext/820665871/qep_msm.o ${OBJECTDIR}/_ext/820665871/qf_act.o ${OBJECTDIR}/_ext/820665871/qf_actq.o ${OBJECTDIR}/_ext/820665871/qf_defer.o ${OBJECTDIR}/_ext/820665871/qf_dyn.o ${OBJECTDIR}/_ext/820665871/qf_mem.o ${OBJECTDIR}/_ext/820665871/qf_ps.o ${OBJECTDIR}/_ext/820665871/qf_qact.o ${OBJECTDIR}/_ext/820665871/qf_qeq.o ${OBJECTDIR}/_ext/820665871/qf_qmact.o ${OBJECTDIR}/_ext/820665871/qf_time.o ${OBJECTDIR}/_ext/820665887/qv.o ${OBJECTDIR}/bsp.o ${OBJECTDIR}/_ext/43898991/main.o ${OBJECTDIR}/_ext/726959463/qstamp.o ${OBJECTDIR}/_ext/43898991/philo.o ${OBJECTDIR}/_ext/43898991/table.o -POSSIBLE_DEPFILES=${OBJECTDIR}/_ext/820665871/qep_hsm.o.d ${OBJECTDIR}/_ext/820665871/qep_msm.o.d ${OBJECTDIR}/_ext/820665871/qf_act.o.d ${OBJECTDIR}/_ext/820665871/qf_actq.o.d ${OBJECTDIR}/_ext/820665871/qf_defer.o.d ${OBJECTDIR}/_ext/820665871/qf_dyn.o.d ${OBJECTDIR}/_ext/820665871/qf_mem.o.d ${OBJECTDIR}/_ext/820665871/qf_ps.o.d ${OBJECTDIR}/_ext/820665871/qf_qact.o.d ${OBJECTDIR}/_ext/820665871/qf_qeq.o.d ${OBJECTDIR}/_ext/820665871/qf_qmact.o.d ${OBJECTDIR}/_ext/820665871/qf_time.o.d ${OBJECTDIR}/_ext/820665887/qv.o.d ${OBJECTDIR}/bsp.o.d ${OBJECTDIR}/_ext/43898991/main.o.d ${OBJECTDIR}/_ext/726959463/qstamp.o.d ${OBJECTDIR}/_ext/43898991/philo.o.d ${OBJECTDIR}/_ext/43898991/table.o.d +OBJECTFILES_QUOTED_IF_SPACED=${OBJECTDIR}/_ext/820665871/qep_hsm.o ${OBJECTDIR}/_ext/820665871/qep_msm.o ${OBJECTDIR}/_ext/820665871/qf_act.o ${OBJECTDIR}/_ext/820665871/qf_actq.o ${OBJECTDIR}/_ext/820665871/qf_defer.o ${OBJECTDIR}/_ext/820665871/qf_dyn.o ${OBJECTDIR}/_ext/820665871/qf_mem.o ${OBJECTDIR}/_ext/820665871/qf_ps.o ${OBJECTDIR}/_ext/820665871/qf_qact.o ${OBJECTDIR}/_ext/820665871/qf_qeq.o ${OBJECTDIR}/_ext/820665871/qf_qmact.o ${OBJECTDIR}/_ext/820665871/qf_time.o ${OBJECTDIR}/_ext/820665887/qv.o ${OBJECTDIR}/_ext/820665884/qstamp.o ${OBJECTDIR}/bsp.o ${OBJECTDIR}/_ext/43898991/main.o ${OBJECTDIR}/_ext/43898991/philo.o ${OBJECTDIR}/_ext/43898991/table.o +POSSIBLE_DEPFILES=${OBJECTDIR}/_ext/820665871/qep_hsm.o.d ${OBJECTDIR}/_ext/820665871/qep_msm.o.d ${OBJECTDIR}/_ext/820665871/qf_act.o.d ${OBJECTDIR}/_ext/820665871/qf_actq.o.d ${OBJECTDIR}/_ext/820665871/qf_defer.o.d ${OBJECTDIR}/_ext/820665871/qf_dyn.o.d ${OBJECTDIR}/_ext/820665871/qf_mem.o.d ${OBJECTDIR}/_ext/820665871/qf_ps.o.d ${OBJECTDIR}/_ext/820665871/qf_qact.o.d ${OBJECTDIR}/_ext/820665871/qf_qeq.o.d ${OBJECTDIR}/_ext/820665871/qf_qmact.o.d ${OBJECTDIR}/_ext/820665871/qf_time.o.d ${OBJECTDIR}/_ext/820665887/qv.o.d ${OBJECTDIR}/_ext/820665884/qstamp.o.d ${OBJECTDIR}/bsp.o.d ${OBJECTDIR}/_ext/43898991/main.o.d ${OBJECTDIR}/_ext/43898991/philo.o.d ${OBJECTDIR}/_ext/43898991/table.o.d # Object Files -OBJECTFILES=${OBJECTDIR}/_ext/820665871/qep_hsm.o ${OBJECTDIR}/_ext/820665871/qep_msm.o ${OBJECTDIR}/_ext/820665871/qf_act.o ${OBJECTDIR}/_ext/820665871/qf_actq.o ${OBJECTDIR}/_ext/820665871/qf_defer.o ${OBJECTDIR}/_ext/820665871/qf_dyn.o ${OBJECTDIR}/_ext/820665871/qf_mem.o ${OBJECTDIR}/_ext/820665871/qf_ps.o ${OBJECTDIR}/_ext/820665871/qf_qact.o ${OBJECTDIR}/_ext/820665871/qf_qeq.o ${OBJECTDIR}/_ext/820665871/qf_qmact.o ${OBJECTDIR}/_ext/820665871/qf_time.o ${OBJECTDIR}/_ext/820665887/qv.o ${OBJECTDIR}/bsp.o ${OBJECTDIR}/_ext/43898991/main.o ${OBJECTDIR}/_ext/726959463/qstamp.o ${OBJECTDIR}/_ext/43898991/philo.o ${OBJECTDIR}/_ext/43898991/table.o +OBJECTFILES=${OBJECTDIR}/_ext/820665871/qep_hsm.o ${OBJECTDIR}/_ext/820665871/qep_msm.o ${OBJECTDIR}/_ext/820665871/qf_act.o ${OBJECTDIR}/_ext/820665871/qf_actq.o ${OBJECTDIR}/_ext/820665871/qf_defer.o ${OBJECTDIR}/_ext/820665871/qf_dyn.o ${OBJECTDIR}/_ext/820665871/qf_mem.o ${OBJECTDIR}/_ext/820665871/qf_ps.o ${OBJECTDIR}/_ext/820665871/qf_qact.o ${OBJECTDIR}/_ext/820665871/qf_qeq.o ${OBJECTDIR}/_ext/820665871/qf_qmact.o ${OBJECTDIR}/_ext/820665871/qf_time.o ${OBJECTDIR}/_ext/820665887/qv.o ${OBJECTDIR}/_ext/820665884/qstamp.o ${OBJECTDIR}/bsp.o ${OBJECTDIR}/_ext/43898991/main.o ${OBJECTDIR}/_ext/43898991/philo.o ${OBJECTDIR}/_ext/43898991/table.o # Source Files -SOURCEFILES=../../../../../src/qf/qep_hsm.c ../../../../../src/qf/qep_msm.c ../../../../../src/qf/qf_act.c ../../../../../src/qf/qf_actq.c ../../../../../src/qf/qf_defer.c ../../../../../src/qf/qf_dyn.c ../../../../../src/qf/qf_mem.c ../../../../../src/qf/qf_ps.c ../../../../../src/qf/qf_qact.c ../../../../../src/qf/qf_qeq.c ../../../../../src/qf/qf_qmact.c ../../../../../src/qf/qf_time.c ../../../../../src/qv/qv.c bsp.c ../../main.c ../../../../../include/qstamp.c ../../philo.c ../../table.c +SOURCEFILES=../../../../../src/qf/qep_hsm.c ../../../../../src/qf/qep_msm.c ../../../../../src/qf/qf_act.c ../../../../../src/qf/qf_actq.c ../../../../../src/qf/qf_defer.c ../../../../../src/qf/qf_dyn.c ../../../../../src/qf/qf_mem.c ../../../../../src/qf/qf_ps.c ../../../../../src/qf/qf_qact.c ../../../../../src/qf/qf_qeq.c ../../../../../src/qf/qf_qmact.c ../../../../../src/qf/qf_time.c ../../../../../src/qv/qv.c ../../../../../src/qs/qstamp.c bsp.c ../../main.c ../../philo.c ../../table.c CFLAGS= @@ -184,6 +184,12 @@ ${OBJECTDIR}/_ext/820665887/qv.o: ../../../../../src/qv/qv.c nbproject/Makefile @${RM} ${OBJECTDIR}/_ext/820665887/qv.o @${FIXDEPS} "${OBJECTDIR}/_ext/820665887/qv.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -D__DEBUG -D__MPLAB_DEBUGGER_PK3=1 -fframe-base-loclist -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -I"../.." -I"../../../../../src" -I"../../../../../include" -I"../../../../../ports/pic32/qv/xc32" -MMD -MF "${OBJECTDIR}/_ext/820665887/qv.o.d" -o ${OBJECTDIR}/_ext/820665887/qv.o ../../../../../src/qv/qv.c -DXPRJ_dbg=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 +${OBJECTDIR}/_ext/820665884/qstamp.o: ../../../../../src/qs/qstamp.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/_ext/820665884" + @${RM} ${OBJECTDIR}/_ext/820665884/qstamp.o.d + @${RM} ${OBJECTDIR}/_ext/820665884/qstamp.o + @${FIXDEPS} "${OBJECTDIR}/_ext/820665884/qstamp.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -D__DEBUG -D__MPLAB_DEBUGGER_PK3=1 -fframe-base-loclist -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -I"../.." -I"../../../../../src" -I"../../../../../include" -I"../../../../../ports/pic32/qv/xc32" -MMD -MF "${OBJECTDIR}/_ext/820665884/qstamp.o.d" -o ${OBJECTDIR}/_ext/820665884/qstamp.o ../../../../../src/qs/qstamp.c -DXPRJ_dbg=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 + ${OBJECTDIR}/bsp.o: bsp.c nbproject/Makefile-${CND_CONF}.mk @${MKDIR} "${OBJECTDIR}" @${RM} ${OBJECTDIR}/bsp.o.d @@ -196,12 +202,6 @@ ${OBJECTDIR}/_ext/43898991/main.o: ../../main.c nbproject/Makefile-${CND_CONF}. @${RM} ${OBJECTDIR}/_ext/43898991/main.o @${FIXDEPS} "${OBJECTDIR}/_ext/43898991/main.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -D__DEBUG -D__MPLAB_DEBUGGER_PK3=1 -fframe-base-loclist -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -I"../.." -I"../../../../../src" -I"../../../../../include" -I"../../../../../ports/pic32/qv/xc32" -MMD -MF "${OBJECTDIR}/_ext/43898991/main.o.d" -o ${OBJECTDIR}/_ext/43898991/main.o ../../main.c -DXPRJ_dbg=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 -${OBJECTDIR}/_ext/726959463/qstamp.o: ../../../../../include/qstamp.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/726959463" - @${RM} ${OBJECTDIR}/_ext/726959463/qstamp.o.d - @${RM} ${OBJECTDIR}/_ext/726959463/qstamp.o - @${FIXDEPS} "${OBJECTDIR}/_ext/726959463/qstamp.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -D__DEBUG -D__MPLAB_DEBUGGER_PK3=1 -fframe-base-loclist -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -I"../.." -I"../../../../../src" -I"../../../../../include" -I"../../../../../ports/pic32/qv/xc32" -MMD -MF "${OBJECTDIR}/_ext/726959463/qstamp.o.d" -o ${OBJECTDIR}/_ext/726959463/qstamp.o ../../../../../include/qstamp.c -DXPRJ_dbg=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - ${OBJECTDIR}/_ext/43898991/philo.o: ../../philo.c nbproject/Makefile-${CND_CONF}.mk @${MKDIR} "${OBJECTDIR}/_ext/43898991" @${RM} ${OBJECTDIR}/_ext/43898991/philo.o.d @@ -293,6 +293,12 @@ ${OBJECTDIR}/_ext/820665887/qv.o: ../../../../../src/qv/qv.c nbproject/Makefile @${RM} ${OBJECTDIR}/_ext/820665887/qv.o @${FIXDEPS} "${OBJECTDIR}/_ext/820665887/qv.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -I"../.." -I"../../../../../src" -I"../../../../../include" -I"../../../../../ports/pic32/qv/xc32" -MMD -MF "${OBJECTDIR}/_ext/820665887/qv.o.d" -o ${OBJECTDIR}/_ext/820665887/qv.o ../../../../../src/qv/qv.c -DXPRJ_dbg=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 +${OBJECTDIR}/_ext/820665884/qstamp.o: ../../../../../src/qs/qstamp.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/_ext/820665884" + @${RM} ${OBJECTDIR}/_ext/820665884/qstamp.o.d + @${RM} ${OBJECTDIR}/_ext/820665884/qstamp.o + @${FIXDEPS} "${OBJECTDIR}/_ext/820665884/qstamp.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -I"../.." -I"../../../../../src" -I"../../../../../include" -I"../../../../../ports/pic32/qv/xc32" -MMD -MF "${OBJECTDIR}/_ext/820665884/qstamp.o.d" -o ${OBJECTDIR}/_ext/820665884/qstamp.o ../../../../../src/qs/qstamp.c -DXPRJ_dbg=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 + ${OBJECTDIR}/bsp.o: bsp.c nbproject/Makefile-${CND_CONF}.mk @${MKDIR} "${OBJECTDIR}" @${RM} ${OBJECTDIR}/bsp.o.d @@ -305,12 +311,6 @@ ${OBJECTDIR}/_ext/43898991/main.o: ../../main.c nbproject/Makefile-${CND_CONF}. @${RM} ${OBJECTDIR}/_ext/43898991/main.o @${FIXDEPS} "${OBJECTDIR}/_ext/43898991/main.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -I"../.." -I"../../../../../src" -I"../../../../../include" -I"../../../../../ports/pic32/qv/xc32" -MMD -MF "${OBJECTDIR}/_ext/43898991/main.o.d" -o ${OBJECTDIR}/_ext/43898991/main.o ../../main.c -DXPRJ_dbg=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 -${OBJECTDIR}/_ext/726959463/qstamp.o: ../../../../../include/qstamp.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/726959463" - @${RM} ${OBJECTDIR}/_ext/726959463/qstamp.o.d - @${RM} ${OBJECTDIR}/_ext/726959463/qstamp.o - @${FIXDEPS} "${OBJECTDIR}/_ext/726959463/qstamp.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -I"../.." -I"../../../../../src" -I"../../../../../include" -I"../../../../../ports/pic32/qv/xc32" -MMD -MF "${OBJECTDIR}/_ext/726959463/qstamp.o.d" -o ${OBJECTDIR}/_ext/726959463/qstamp.o ../../../../../include/qstamp.c -DXPRJ_dbg=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - ${OBJECTDIR}/_ext/43898991/philo.o: ../../philo.c nbproject/Makefile-${CND_CONF}.mk @${MKDIR} "${OBJECTDIR}/_ext/43898991" @${RM} ${OBJECTDIR}/_ext/43898991/philo.o.d diff --git a/examples/pic32/dpp_microstick2-pic32/qv/xc32/nbproject/Makefile-genesis.properties b/examples/pic32/dpp_microstick2-pic32/qv/xc32/nbproject/Makefile-genesis.properties index ce82ca05..abe8e0ac 100644 --- a/examples/pic32/dpp_microstick2-pic32/qv/xc32/nbproject/Makefile-genesis.properties +++ b/examples/pic32/dpp_microstick2-pic32/qv/xc32/nbproject/Makefile-genesis.properties @@ -1,10 +1,10 @@ # -#Sun Apr 10 14:39:24 EDT 2022 +#Mon Aug 21 16:33:34 EDT 2023 rel.languagetoolchain.version=2.20 spy.languagetoolchain.version=2.20 conf.ids=dbg,rel,spy spy.languagetoolchain.dir=C\:\\tools\\Microchip\\xc32\\bin -configurations-xml=81ece444600c50e6179ff7a988b40f60 +configurations-xml=6427ff780f4e728f65e86b925101b4dd dbg.languagetoolchain.version=2.20 com-microchip-mplab-nbide-embedded-makeproject-MakeProject.md5=37eccb08230908d044ad3fe14e24ea9a dbg.com-microchip-mplab-nbide-toolchainXC32-XC32LanguageToolchain.md5=af6fe09cc582a0daace7b80bb4f7bbe2 diff --git a/examples/pic32/dpp_microstick2-pic32/qv/xc32/nbproject/Makefile-rel.mk b/examples/pic32/dpp_microstick2-pic32/qv/xc32/nbproject/Makefile-rel.mk index 8cb1753c..410672aa 100644 --- a/examples/pic32/dpp_microstick2-pic32/qv/xc32/nbproject/Makefile-rel.mk +++ b/examples/pic32/dpp_microstick2-pic32/qv/xc32/nbproject/Makefile-rel.mk @@ -57,17 +57,17 @@ OBJECTDIR=build/${CND_CONF}/${IMAGE_TYPE} DISTDIR=dist/${CND_CONF}/${IMAGE_TYPE} # Source Files Quoted if spaced -SOURCEFILES_QUOTED_IF_SPACED=../../../../../src/qf/qep_hsm.c ../../../../../src/qf/qep_msm.c ../../../../../src/qf/qf_act.c ../../../../../src/qf/qf_actq.c ../../../../../src/qf/qf_defer.c ../../../../../src/qf/qf_dyn.c ../../../../../src/qf/qf_mem.c ../../../../../src/qf/qf_ps.c ../../../../../src/qf/qf_qact.c ../../../../../src/qf/qf_qeq.c ../../../../../src/qf/qf_qmact.c ../../../../../src/qf/qf_time.c ../../../../../src/qv/qv.c bsp.c ../../main.c ../../../../../include/qstamp.c ../../philo.c ../../table.c +SOURCEFILES_QUOTED_IF_SPACED=../../../../../src/qf/qep_hsm.c ../../../../../src/qf/qep_msm.c ../../../../../src/qf/qf_act.c ../../../../../src/qf/qf_actq.c ../../../../../src/qf/qf_defer.c ../../../../../src/qf/qf_dyn.c ../../../../../src/qf/qf_mem.c ../../../../../src/qf/qf_ps.c ../../../../../src/qf/qf_qact.c ../../../../../src/qf/qf_qeq.c ../../../../../src/qf/qf_qmact.c ../../../../../src/qf/qf_time.c ../../../../../src/qv/qv.c ../../../../../src/qs/qstamp.c bsp.c ../../main.c ../../philo.c ../../table.c # Object Files Quoted if spaced -OBJECTFILES_QUOTED_IF_SPACED=${OBJECTDIR}/_ext/820665871/qep_hsm.o ${OBJECTDIR}/_ext/820665871/qep_msm.o ${OBJECTDIR}/_ext/820665871/qf_act.o ${OBJECTDIR}/_ext/820665871/qf_actq.o ${OBJECTDIR}/_ext/820665871/qf_defer.o ${OBJECTDIR}/_ext/820665871/qf_dyn.o ${OBJECTDIR}/_ext/820665871/qf_mem.o ${OBJECTDIR}/_ext/820665871/qf_ps.o ${OBJECTDIR}/_ext/820665871/qf_qact.o ${OBJECTDIR}/_ext/820665871/qf_qeq.o ${OBJECTDIR}/_ext/820665871/qf_qmact.o ${OBJECTDIR}/_ext/820665871/qf_time.o ${OBJECTDIR}/_ext/820665887/qv.o ${OBJECTDIR}/bsp.o ${OBJECTDIR}/_ext/43898991/main.o ${OBJECTDIR}/_ext/726959463/qstamp.o ${OBJECTDIR}/_ext/43898991/philo.o ${OBJECTDIR}/_ext/43898991/table.o -POSSIBLE_DEPFILES=${OBJECTDIR}/_ext/820665871/qep_hsm.o.d ${OBJECTDIR}/_ext/820665871/qep_msm.o.d ${OBJECTDIR}/_ext/820665871/qf_act.o.d ${OBJECTDIR}/_ext/820665871/qf_actq.o.d ${OBJECTDIR}/_ext/820665871/qf_defer.o.d ${OBJECTDIR}/_ext/820665871/qf_dyn.o.d ${OBJECTDIR}/_ext/820665871/qf_mem.o.d ${OBJECTDIR}/_ext/820665871/qf_ps.o.d ${OBJECTDIR}/_ext/820665871/qf_qact.o.d ${OBJECTDIR}/_ext/820665871/qf_qeq.o.d ${OBJECTDIR}/_ext/820665871/qf_qmact.o.d ${OBJECTDIR}/_ext/820665871/qf_time.o.d ${OBJECTDIR}/_ext/820665887/qv.o.d ${OBJECTDIR}/bsp.o.d ${OBJECTDIR}/_ext/43898991/main.o.d ${OBJECTDIR}/_ext/726959463/qstamp.o.d ${OBJECTDIR}/_ext/43898991/philo.o.d ${OBJECTDIR}/_ext/43898991/table.o.d +OBJECTFILES_QUOTED_IF_SPACED=${OBJECTDIR}/_ext/820665871/qep_hsm.o ${OBJECTDIR}/_ext/820665871/qep_msm.o ${OBJECTDIR}/_ext/820665871/qf_act.o ${OBJECTDIR}/_ext/820665871/qf_actq.o ${OBJECTDIR}/_ext/820665871/qf_defer.o ${OBJECTDIR}/_ext/820665871/qf_dyn.o ${OBJECTDIR}/_ext/820665871/qf_mem.o ${OBJECTDIR}/_ext/820665871/qf_ps.o ${OBJECTDIR}/_ext/820665871/qf_qact.o ${OBJECTDIR}/_ext/820665871/qf_qeq.o ${OBJECTDIR}/_ext/820665871/qf_qmact.o ${OBJECTDIR}/_ext/820665871/qf_time.o ${OBJECTDIR}/_ext/820665887/qv.o ${OBJECTDIR}/_ext/820665884/qstamp.o ${OBJECTDIR}/bsp.o ${OBJECTDIR}/_ext/43898991/main.o ${OBJECTDIR}/_ext/43898991/philo.o ${OBJECTDIR}/_ext/43898991/table.o +POSSIBLE_DEPFILES=${OBJECTDIR}/_ext/820665871/qep_hsm.o.d ${OBJECTDIR}/_ext/820665871/qep_msm.o.d ${OBJECTDIR}/_ext/820665871/qf_act.o.d ${OBJECTDIR}/_ext/820665871/qf_actq.o.d ${OBJECTDIR}/_ext/820665871/qf_defer.o.d ${OBJECTDIR}/_ext/820665871/qf_dyn.o.d ${OBJECTDIR}/_ext/820665871/qf_mem.o.d ${OBJECTDIR}/_ext/820665871/qf_ps.o.d ${OBJECTDIR}/_ext/820665871/qf_qact.o.d ${OBJECTDIR}/_ext/820665871/qf_qeq.o.d ${OBJECTDIR}/_ext/820665871/qf_qmact.o.d ${OBJECTDIR}/_ext/820665871/qf_time.o.d ${OBJECTDIR}/_ext/820665887/qv.o.d ${OBJECTDIR}/_ext/820665884/qstamp.o.d ${OBJECTDIR}/bsp.o.d ${OBJECTDIR}/_ext/43898991/main.o.d ${OBJECTDIR}/_ext/43898991/philo.o.d ${OBJECTDIR}/_ext/43898991/table.o.d # Object Files -OBJECTFILES=${OBJECTDIR}/_ext/820665871/qep_hsm.o ${OBJECTDIR}/_ext/820665871/qep_msm.o ${OBJECTDIR}/_ext/820665871/qf_act.o ${OBJECTDIR}/_ext/820665871/qf_actq.o ${OBJECTDIR}/_ext/820665871/qf_defer.o ${OBJECTDIR}/_ext/820665871/qf_dyn.o ${OBJECTDIR}/_ext/820665871/qf_mem.o ${OBJECTDIR}/_ext/820665871/qf_ps.o ${OBJECTDIR}/_ext/820665871/qf_qact.o ${OBJECTDIR}/_ext/820665871/qf_qeq.o ${OBJECTDIR}/_ext/820665871/qf_qmact.o ${OBJECTDIR}/_ext/820665871/qf_time.o ${OBJECTDIR}/_ext/820665887/qv.o ${OBJECTDIR}/bsp.o ${OBJECTDIR}/_ext/43898991/main.o ${OBJECTDIR}/_ext/726959463/qstamp.o ${OBJECTDIR}/_ext/43898991/philo.o ${OBJECTDIR}/_ext/43898991/table.o +OBJECTFILES=${OBJECTDIR}/_ext/820665871/qep_hsm.o ${OBJECTDIR}/_ext/820665871/qep_msm.o ${OBJECTDIR}/_ext/820665871/qf_act.o ${OBJECTDIR}/_ext/820665871/qf_actq.o ${OBJECTDIR}/_ext/820665871/qf_defer.o ${OBJECTDIR}/_ext/820665871/qf_dyn.o ${OBJECTDIR}/_ext/820665871/qf_mem.o ${OBJECTDIR}/_ext/820665871/qf_ps.o ${OBJECTDIR}/_ext/820665871/qf_qact.o ${OBJECTDIR}/_ext/820665871/qf_qeq.o ${OBJECTDIR}/_ext/820665871/qf_qmact.o ${OBJECTDIR}/_ext/820665871/qf_time.o ${OBJECTDIR}/_ext/820665887/qv.o ${OBJECTDIR}/_ext/820665884/qstamp.o ${OBJECTDIR}/bsp.o ${OBJECTDIR}/_ext/43898991/main.o ${OBJECTDIR}/_ext/43898991/philo.o ${OBJECTDIR}/_ext/43898991/table.o # Source Files -SOURCEFILES=../../../../../src/qf/qep_hsm.c ../../../../../src/qf/qep_msm.c ../../../../../src/qf/qf_act.c ../../../../../src/qf/qf_actq.c ../../../../../src/qf/qf_defer.c ../../../../../src/qf/qf_dyn.c ../../../../../src/qf/qf_mem.c ../../../../../src/qf/qf_ps.c ../../../../../src/qf/qf_qact.c ../../../../../src/qf/qf_qeq.c ../../../../../src/qf/qf_qmact.c ../../../../../src/qf/qf_time.c ../../../../../src/qv/qv.c bsp.c ../../main.c ../../../../../include/qstamp.c ../../philo.c ../../table.c +SOURCEFILES=../../../../../src/qf/qep_hsm.c ../../../../../src/qf/qep_msm.c ../../../../../src/qf/qf_act.c ../../../../../src/qf/qf_actq.c ../../../../../src/qf/qf_defer.c ../../../../../src/qf/qf_dyn.c ../../../../../src/qf/qf_mem.c ../../../../../src/qf/qf_ps.c ../../../../../src/qf/qf_qact.c ../../../../../src/qf/qf_qeq.c ../../../../../src/qf/qf_qmact.c ../../../../../src/qf/qf_time.c ../../../../../src/qv/qv.c ../../../../../src/qs/qstamp.c bsp.c ../../main.c ../../philo.c ../../table.c CFLAGS= @@ -184,6 +184,12 @@ ${OBJECTDIR}/_ext/820665887/qv.o: ../../../../../src/qv/qv.c nbproject/Makefile @${RM} ${OBJECTDIR}/_ext/820665887/qv.o @${FIXDEPS} "${OBJECTDIR}/_ext/820665887/qv.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -D__DEBUG -D__MPLAB_DEBUGGER_PK3=1 -fframe-base-loclist -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -O3 -DNDEBUG -I"../.." -I"../../../../../include" -I"../../../../../src" -I"../../../../../ports/pic32/qv/xc32" -MMD -MF "${OBJECTDIR}/_ext/820665887/qv.o.d" -o ${OBJECTDIR}/_ext/820665887/qv.o ../../../../../src/qv/qv.c -DXPRJ_rel=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 +${OBJECTDIR}/_ext/820665884/qstamp.o: ../../../../../src/qs/qstamp.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/_ext/820665884" + @${RM} ${OBJECTDIR}/_ext/820665884/qstamp.o.d + @${RM} ${OBJECTDIR}/_ext/820665884/qstamp.o + @${FIXDEPS} "${OBJECTDIR}/_ext/820665884/qstamp.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -D__DEBUG -D__MPLAB_DEBUGGER_PK3=1 -fframe-base-loclist -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -O3 -DNDEBUG -I"../.." -I"../../../../../include" -I"../../../../../src" -I"../../../../../ports/pic32/qv/xc32" -MMD -MF "${OBJECTDIR}/_ext/820665884/qstamp.o.d" -o ${OBJECTDIR}/_ext/820665884/qstamp.o ../../../../../src/qs/qstamp.c -DXPRJ_rel=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 + ${OBJECTDIR}/bsp.o: bsp.c nbproject/Makefile-${CND_CONF}.mk @${MKDIR} "${OBJECTDIR}" @${RM} ${OBJECTDIR}/bsp.o.d @@ -196,12 +202,6 @@ ${OBJECTDIR}/_ext/43898991/main.o: ../../main.c nbproject/Makefile-${CND_CONF}. @${RM} ${OBJECTDIR}/_ext/43898991/main.o @${FIXDEPS} "${OBJECTDIR}/_ext/43898991/main.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -D__DEBUG -D__MPLAB_DEBUGGER_PK3=1 -fframe-base-loclist -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -O3 -DNDEBUG -I"../.." -I"../../../../../include" -I"../../../../../src" -I"../../../../../ports/pic32/qv/xc32" -MMD -MF "${OBJECTDIR}/_ext/43898991/main.o.d" -o ${OBJECTDIR}/_ext/43898991/main.o ../../main.c -DXPRJ_rel=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 -${OBJECTDIR}/_ext/726959463/qstamp.o: ../../../../../include/qstamp.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/726959463" - @${RM} ${OBJECTDIR}/_ext/726959463/qstamp.o.d - @${RM} ${OBJECTDIR}/_ext/726959463/qstamp.o - @${FIXDEPS} "${OBJECTDIR}/_ext/726959463/qstamp.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -D__DEBUG -D__MPLAB_DEBUGGER_PK3=1 -fframe-base-loclist -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -O3 -DNDEBUG -I"../.." -I"../../../../../include" -I"../../../../../src" -I"../../../../../ports/pic32/qv/xc32" -MMD -MF "${OBJECTDIR}/_ext/726959463/qstamp.o.d" -o ${OBJECTDIR}/_ext/726959463/qstamp.o ../../../../../include/qstamp.c -DXPRJ_rel=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - ${OBJECTDIR}/_ext/43898991/philo.o: ../../philo.c nbproject/Makefile-${CND_CONF}.mk @${MKDIR} "${OBJECTDIR}/_ext/43898991" @${RM} ${OBJECTDIR}/_ext/43898991/philo.o.d @@ -293,6 +293,12 @@ ${OBJECTDIR}/_ext/820665887/qv.o: ../../../../../src/qv/qv.c nbproject/Makefile @${RM} ${OBJECTDIR}/_ext/820665887/qv.o @${FIXDEPS} "${OBJECTDIR}/_ext/820665887/qv.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -O3 -DNDEBUG -I"../.." -I"../../../../../include" -I"../../../../../src" -I"../../../../../ports/pic32/qv/xc32" -MMD -MF "${OBJECTDIR}/_ext/820665887/qv.o.d" -o ${OBJECTDIR}/_ext/820665887/qv.o ../../../../../src/qv/qv.c -DXPRJ_rel=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 +${OBJECTDIR}/_ext/820665884/qstamp.o: ../../../../../src/qs/qstamp.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/_ext/820665884" + @${RM} ${OBJECTDIR}/_ext/820665884/qstamp.o.d + @${RM} ${OBJECTDIR}/_ext/820665884/qstamp.o + @${FIXDEPS} "${OBJECTDIR}/_ext/820665884/qstamp.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -O3 -DNDEBUG -I"../.." -I"../../../../../include" -I"../../../../../src" -I"../../../../../ports/pic32/qv/xc32" -MMD -MF "${OBJECTDIR}/_ext/820665884/qstamp.o.d" -o ${OBJECTDIR}/_ext/820665884/qstamp.o ../../../../../src/qs/qstamp.c -DXPRJ_rel=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 + ${OBJECTDIR}/bsp.o: bsp.c nbproject/Makefile-${CND_CONF}.mk @${MKDIR} "${OBJECTDIR}" @${RM} ${OBJECTDIR}/bsp.o.d @@ -305,12 +311,6 @@ ${OBJECTDIR}/_ext/43898991/main.o: ../../main.c nbproject/Makefile-${CND_CONF}. @${RM} ${OBJECTDIR}/_ext/43898991/main.o @${FIXDEPS} "${OBJECTDIR}/_ext/43898991/main.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -O3 -DNDEBUG -I"../.." -I"../../../../../include" -I"../../../../../src" -I"../../../../../ports/pic32/qv/xc32" -MMD -MF "${OBJECTDIR}/_ext/43898991/main.o.d" -o ${OBJECTDIR}/_ext/43898991/main.o ../../main.c -DXPRJ_rel=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 -${OBJECTDIR}/_ext/726959463/qstamp.o: ../../../../../include/qstamp.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/726959463" - @${RM} ${OBJECTDIR}/_ext/726959463/qstamp.o.d - @${RM} ${OBJECTDIR}/_ext/726959463/qstamp.o - @${FIXDEPS} "${OBJECTDIR}/_ext/726959463/qstamp.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -O3 -DNDEBUG -I"../.." -I"../../../../../include" -I"../../../../../src" -I"../../../../../ports/pic32/qv/xc32" -MMD -MF "${OBJECTDIR}/_ext/726959463/qstamp.o.d" -o ${OBJECTDIR}/_ext/726959463/qstamp.o ../../../../../include/qstamp.c -DXPRJ_rel=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - ${OBJECTDIR}/_ext/43898991/philo.o: ../../philo.c nbproject/Makefile-${CND_CONF}.mk @${MKDIR} "${OBJECTDIR}/_ext/43898991" @${RM} ${OBJECTDIR}/_ext/43898991/philo.o.d diff --git a/examples/pic32/dpp_microstick2-pic32/qv/xc32/nbproject/Makefile-spy.mk b/examples/pic32/dpp_microstick2-pic32/qv/xc32/nbproject/Makefile-spy.mk index 66e0de85..69b9779e 100644 --- a/examples/pic32/dpp_microstick2-pic32/qv/xc32/nbproject/Makefile-spy.mk +++ b/examples/pic32/dpp_microstick2-pic32/qv/xc32/nbproject/Makefile-spy.mk @@ -57,17 +57,17 @@ OBJECTDIR=build/${CND_CONF}/${IMAGE_TYPE} DISTDIR=dist/${CND_CONF}/${IMAGE_TYPE} # Source Files Quoted if spaced -SOURCEFILES_QUOTED_IF_SPACED=../../../../../src/qf/qep_hsm.c ../../../../../src/qf/qep_msm.c ../../../../../src/qf/qf_act.c ../../../../../src/qf/qf_actq.c ../../../../../src/qf/qf_defer.c ../../../../../src/qf/qf_dyn.c ../../../../../src/qf/qf_mem.c ../../../../../src/qf/qf_ps.c ../../../../../src/qf/qf_qact.c ../../../../../src/qf/qf_qeq.c ../../../../../src/qf/qf_qmact.c ../../../../../src/qf/qf_time.c ../../../../../src/qv/qv.c ../../../../../src/qs/qs.c ../../../../../src/qs/qs_64bit.c ../../../../../src/qs/qs_fp.c ../../../../../src/qs/qs_rx.c bsp.c ../../main.c ../../../../../include/qstamp.c ../../philo.c ../../table.c +SOURCEFILES_QUOTED_IF_SPACED=../../../../../src/qf/qep_hsm.c ../../../../../src/qf/qep_msm.c ../../../../../src/qf/qf_act.c ../../../../../src/qf/qf_actq.c ../../../../../src/qf/qf_defer.c ../../../../../src/qf/qf_dyn.c ../../../../../src/qf/qf_mem.c ../../../../../src/qf/qf_ps.c ../../../../../src/qf/qf_qact.c ../../../../../src/qf/qf_qeq.c ../../../../../src/qf/qf_qmact.c ../../../../../src/qf/qf_time.c ../../../../../src/qv/qv.c ../../../../../src/qs/qs.c ../../../../../src/qs/qs_64bit.c ../../../../../src/qs/qs_fp.c ../../../../../src/qs/qs_rx.c ../../../../../src/qs/qstamp.c bsp.c ../../main.c ../../philo.c ../../table.c # Object Files Quoted if spaced -OBJECTFILES_QUOTED_IF_SPACED=${OBJECTDIR}/_ext/820665871/qep_hsm.o ${OBJECTDIR}/_ext/820665871/qep_msm.o ${OBJECTDIR}/_ext/820665871/qf_act.o ${OBJECTDIR}/_ext/820665871/qf_actq.o ${OBJECTDIR}/_ext/820665871/qf_defer.o ${OBJECTDIR}/_ext/820665871/qf_dyn.o ${OBJECTDIR}/_ext/820665871/qf_mem.o ${OBJECTDIR}/_ext/820665871/qf_ps.o ${OBJECTDIR}/_ext/820665871/qf_qact.o ${OBJECTDIR}/_ext/820665871/qf_qeq.o ${OBJECTDIR}/_ext/820665871/qf_qmact.o ${OBJECTDIR}/_ext/820665871/qf_time.o ${OBJECTDIR}/_ext/820665887/qv.o ${OBJECTDIR}/_ext/820665884/qs.o ${OBJECTDIR}/_ext/820665884/qs_64bit.o ${OBJECTDIR}/_ext/820665884/qs_fp.o ${OBJECTDIR}/_ext/820665884/qs_rx.o ${OBJECTDIR}/bsp.o ${OBJECTDIR}/_ext/43898991/main.o ${OBJECTDIR}/_ext/726959463/qstamp.o ${OBJECTDIR}/_ext/43898991/philo.o ${OBJECTDIR}/_ext/43898991/table.o -POSSIBLE_DEPFILES=${OBJECTDIR}/_ext/820665871/qep_hsm.o.d ${OBJECTDIR}/_ext/820665871/qep_msm.o.d ${OBJECTDIR}/_ext/820665871/qf_act.o.d ${OBJECTDIR}/_ext/820665871/qf_actq.o.d ${OBJECTDIR}/_ext/820665871/qf_defer.o.d ${OBJECTDIR}/_ext/820665871/qf_dyn.o.d ${OBJECTDIR}/_ext/820665871/qf_mem.o.d ${OBJECTDIR}/_ext/820665871/qf_ps.o.d ${OBJECTDIR}/_ext/820665871/qf_qact.o.d ${OBJECTDIR}/_ext/820665871/qf_qeq.o.d ${OBJECTDIR}/_ext/820665871/qf_qmact.o.d ${OBJECTDIR}/_ext/820665871/qf_time.o.d ${OBJECTDIR}/_ext/820665887/qv.o.d ${OBJECTDIR}/_ext/820665884/qs.o.d ${OBJECTDIR}/_ext/820665884/qs_64bit.o.d ${OBJECTDIR}/_ext/820665884/qs_fp.o.d ${OBJECTDIR}/_ext/820665884/qs_rx.o.d ${OBJECTDIR}/bsp.o.d ${OBJECTDIR}/_ext/43898991/main.o.d ${OBJECTDIR}/_ext/726959463/qstamp.o.d ${OBJECTDIR}/_ext/43898991/philo.o.d ${OBJECTDIR}/_ext/43898991/table.o.d +OBJECTFILES_QUOTED_IF_SPACED=${OBJECTDIR}/_ext/820665871/qep_hsm.o ${OBJECTDIR}/_ext/820665871/qep_msm.o ${OBJECTDIR}/_ext/820665871/qf_act.o ${OBJECTDIR}/_ext/820665871/qf_actq.o ${OBJECTDIR}/_ext/820665871/qf_defer.o ${OBJECTDIR}/_ext/820665871/qf_dyn.o ${OBJECTDIR}/_ext/820665871/qf_mem.o ${OBJECTDIR}/_ext/820665871/qf_ps.o ${OBJECTDIR}/_ext/820665871/qf_qact.o ${OBJECTDIR}/_ext/820665871/qf_qeq.o ${OBJECTDIR}/_ext/820665871/qf_qmact.o ${OBJECTDIR}/_ext/820665871/qf_time.o ${OBJECTDIR}/_ext/820665887/qv.o ${OBJECTDIR}/_ext/820665884/qs.o ${OBJECTDIR}/_ext/820665884/qs_64bit.o ${OBJECTDIR}/_ext/820665884/qs_fp.o ${OBJECTDIR}/_ext/820665884/qs_rx.o ${OBJECTDIR}/_ext/820665884/qstamp.o ${OBJECTDIR}/bsp.o ${OBJECTDIR}/_ext/43898991/main.o ${OBJECTDIR}/_ext/43898991/philo.o ${OBJECTDIR}/_ext/43898991/table.o +POSSIBLE_DEPFILES=${OBJECTDIR}/_ext/820665871/qep_hsm.o.d ${OBJECTDIR}/_ext/820665871/qep_msm.o.d ${OBJECTDIR}/_ext/820665871/qf_act.o.d ${OBJECTDIR}/_ext/820665871/qf_actq.o.d ${OBJECTDIR}/_ext/820665871/qf_defer.o.d ${OBJECTDIR}/_ext/820665871/qf_dyn.o.d ${OBJECTDIR}/_ext/820665871/qf_mem.o.d ${OBJECTDIR}/_ext/820665871/qf_ps.o.d ${OBJECTDIR}/_ext/820665871/qf_qact.o.d ${OBJECTDIR}/_ext/820665871/qf_qeq.o.d ${OBJECTDIR}/_ext/820665871/qf_qmact.o.d ${OBJECTDIR}/_ext/820665871/qf_time.o.d ${OBJECTDIR}/_ext/820665887/qv.o.d ${OBJECTDIR}/_ext/820665884/qs.o.d ${OBJECTDIR}/_ext/820665884/qs_64bit.o.d ${OBJECTDIR}/_ext/820665884/qs_fp.o.d ${OBJECTDIR}/_ext/820665884/qs_rx.o.d ${OBJECTDIR}/_ext/820665884/qstamp.o.d ${OBJECTDIR}/bsp.o.d ${OBJECTDIR}/_ext/43898991/main.o.d ${OBJECTDIR}/_ext/43898991/philo.o.d ${OBJECTDIR}/_ext/43898991/table.o.d # Object Files -OBJECTFILES=${OBJECTDIR}/_ext/820665871/qep_hsm.o ${OBJECTDIR}/_ext/820665871/qep_msm.o ${OBJECTDIR}/_ext/820665871/qf_act.o ${OBJECTDIR}/_ext/820665871/qf_actq.o ${OBJECTDIR}/_ext/820665871/qf_defer.o ${OBJECTDIR}/_ext/820665871/qf_dyn.o ${OBJECTDIR}/_ext/820665871/qf_mem.o ${OBJECTDIR}/_ext/820665871/qf_ps.o ${OBJECTDIR}/_ext/820665871/qf_qact.o ${OBJECTDIR}/_ext/820665871/qf_qeq.o ${OBJECTDIR}/_ext/820665871/qf_qmact.o ${OBJECTDIR}/_ext/820665871/qf_time.o ${OBJECTDIR}/_ext/820665887/qv.o ${OBJECTDIR}/_ext/820665884/qs.o ${OBJECTDIR}/_ext/820665884/qs_64bit.o ${OBJECTDIR}/_ext/820665884/qs_fp.o ${OBJECTDIR}/_ext/820665884/qs_rx.o ${OBJECTDIR}/bsp.o ${OBJECTDIR}/_ext/43898991/main.o ${OBJECTDIR}/_ext/726959463/qstamp.o ${OBJECTDIR}/_ext/43898991/philo.o ${OBJECTDIR}/_ext/43898991/table.o +OBJECTFILES=${OBJECTDIR}/_ext/820665871/qep_hsm.o ${OBJECTDIR}/_ext/820665871/qep_msm.o ${OBJECTDIR}/_ext/820665871/qf_act.o ${OBJECTDIR}/_ext/820665871/qf_actq.o ${OBJECTDIR}/_ext/820665871/qf_defer.o ${OBJECTDIR}/_ext/820665871/qf_dyn.o ${OBJECTDIR}/_ext/820665871/qf_mem.o ${OBJECTDIR}/_ext/820665871/qf_ps.o ${OBJECTDIR}/_ext/820665871/qf_qact.o ${OBJECTDIR}/_ext/820665871/qf_qeq.o ${OBJECTDIR}/_ext/820665871/qf_qmact.o ${OBJECTDIR}/_ext/820665871/qf_time.o ${OBJECTDIR}/_ext/820665887/qv.o ${OBJECTDIR}/_ext/820665884/qs.o ${OBJECTDIR}/_ext/820665884/qs_64bit.o ${OBJECTDIR}/_ext/820665884/qs_fp.o ${OBJECTDIR}/_ext/820665884/qs_rx.o ${OBJECTDIR}/_ext/820665884/qstamp.o ${OBJECTDIR}/bsp.o ${OBJECTDIR}/_ext/43898991/main.o ${OBJECTDIR}/_ext/43898991/philo.o ${OBJECTDIR}/_ext/43898991/table.o # Source Files -SOURCEFILES=../../../../../src/qf/qep_hsm.c ../../../../../src/qf/qep_msm.c ../../../../../src/qf/qf_act.c ../../../../../src/qf/qf_actq.c ../../../../../src/qf/qf_defer.c ../../../../../src/qf/qf_dyn.c ../../../../../src/qf/qf_mem.c ../../../../../src/qf/qf_ps.c ../../../../../src/qf/qf_qact.c ../../../../../src/qf/qf_qeq.c ../../../../../src/qf/qf_qmact.c ../../../../../src/qf/qf_time.c ../../../../../src/qv/qv.c ../../../../../src/qs/qs.c ../../../../../src/qs/qs_64bit.c ../../../../../src/qs/qs_fp.c ../../../../../src/qs/qs_rx.c bsp.c ../../main.c ../../../../../include/qstamp.c ../../philo.c ../../table.c +SOURCEFILES=../../../../../src/qf/qep_hsm.c ../../../../../src/qf/qep_msm.c ../../../../../src/qf/qf_act.c ../../../../../src/qf/qf_actq.c ../../../../../src/qf/qf_defer.c ../../../../../src/qf/qf_dyn.c ../../../../../src/qf/qf_mem.c ../../../../../src/qf/qf_ps.c ../../../../../src/qf/qf_qact.c ../../../../../src/qf/qf_qeq.c ../../../../../src/qf/qf_qmact.c ../../../../../src/qf/qf_time.c ../../../../../src/qv/qv.c ../../../../../src/qs/qs.c ../../../../../src/qs/qs_64bit.c ../../../../../src/qs/qs_fp.c ../../../../../src/qs/qs_rx.c ../../../../../src/qs/qstamp.c bsp.c ../../main.c ../../philo.c ../../table.c CFLAGS= @@ -208,6 +208,12 @@ ${OBJECTDIR}/_ext/820665884/qs_rx.o: ../../../../../src/qs/qs_rx.c nbproject/Ma @${RM} ${OBJECTDIR}/_ext/820665884/qs_rx.o @${FIXDEPS} "${OBJECTDIR}/_ext/820665884/qs_rx.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -D__DEBUG -D__MPLAB_DEBUGGER_PK3=1 -fframe-base-loclist -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -DQ_SPY -I"../../../../../include" -I"../../../../../src" -I"../../../../../ports/pic32/qv/xc32" -I"../.." -MMD -MF "${OBJECTDIR}/_ext/820665884/qs_rx.o.d" -o ${OBJECTDIR}/_ext/820665884/qs_rx.o ../../../../../src/qs/qs_rx.c -DXPRJ_spy=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 +${OBJECTDIR}/_ext/820665884/qstamp.o: ../../../../../src/qs/qstamp.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/_ext/820665884" + @${RM} ${OBJECTDIR}/_ext/820665884/qstamp.o.d + @${RM} ${OBJECTDIR}/_ext/820665884/qstamp.o + @${FIXDEPS} "${OBJECTDIR}/_ext/820665884/qstamp.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -D__DEBUG -D__MPLAB_DEBUGGER_PK3=1 -fframe-base-loclist -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -DQ_SPY -I"../../../../../include" -I"../../../../../src" -I"../../../../../ports/pic32/qv/xc32" -I"../.." -MMD -MF "${OBJECTDIR}/_ext/820665884/qstamp.o.d" -o ${OBJECTDIR}/_ext/820665884/qstamp.o ../../../../../src/qs/qstamp.c -DXPRJ_spy=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 + ${OBJECTDIR}/bsp.o: bsp.c nbproject/Makefile-${CND_CONF}.mk @${MKDIR} "${OBJECTDIR}" @${RM} ${OBJECTDIR}/bsp.o.d @@ -220,12 +226,6 @@ ${OBJECTDIR}/_ext/43898991/main.o: ../../main.c nbproject/Makefile-${CND_CONF}. @${RM} ${OBJECTDIR}/_ext/43898991/main.o @${FIXDEPS} "${OBJECTDIR}/_ext/43898991/main.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -D__DEBUG -D__MPLAB_DEBUGGER_PK3=1 -fframe-base-loclist -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -DQ_SPY -I"../../../../../include" -I"../../../../../src" -I"../../../../../ports/pic32/qv/xc32" -I"../.." -MMD -MF "${OBJECTDIR}/_ext/43898991/main.o.d" -o ${OBJECTDIR}/_ext/43898991/main.o ../../main.c -DXPRJ_spy=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 -${OBJECTDIR}/_ext/726959463/qstamp.o: ../../../../../include/qstamp.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/726959463" - @${RM} ${OBJECTDIR}/_ext/726959463/qstamp.o.d - @${RM} ${OBJECTDIR}/_ext/726959463/qstamp.o - @${FIXDEPS} "${OBJECTDIR}/_ext/726959463/qstamp.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -D__DEBUG -D__MPLAB_DEBUGGER_PK3=1 -fframe-base-loclist -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -DQ_SPY -I"../../../../../include" -I"../../../../../src" -I"../../../../../ports/pic32/qv/xc32" -I"../.." -MMD -MF "${OBJECTDIR}/_ext/726959463/qstamp.o.d" -o ${OBJECTDIR}/_ext/726959463/qstamp.o ../../../../../include/qstamp.c -DXPRJ_spy=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - ${OBJECTDIR}/_ext/43898991/philo.o: ../../philo.c nbproject/Makefile-${CND_CONF}.mk @${MKDIR} "${OBJECTDIR}/_ext/43898991" @${RM} ${OBJECTDIR}/_ext/43898991/philo.o.d @@ -341,6 +341,12 @@ ${OBJECTDIR}/_ext/820665884/qs_rx.o: ../../../../../src/qs/qs_rx.c nbproject/Ma @${RM} ${OBJECTDIR}/_ext/820665884/qs_rx.o @${FIXDEPS} "${OBJECTDIR}/_ext/820665884/qs_rx.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -DQ_SPY -I"../../../../../include" -I"../../../../../src" -I"../../../../../ports/pic32/qv/xc32" -I"../.." -MMD -MF "${OBJECTDIR}/_ext/820665884/qs_rx.o.d" -o ${OBJECTDIR}/_ext/820665884/qs_rx.o ../../../../../src/qs/qs_rx.c -DXPRJ_spy=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 +${OBJECTDIR}/_ext/820665884/qstamp.o: ../../../../../src/qs/qstamp.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/_ext/820665884" + @${RM} ${OBJECTDIR}/_ext/820665884/qstamp.o.d + @${RM} ${OBJECTDIR}/_ext/820665884/qstamp.o + @${FIXDEPS} "${OBJECTDIR}/_ext/820665884/qstamp.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -DQ_SPY -I"../../../../../include" -I"../../../../../src" -I"../../../../../ports/pic32/qv/xc32" -I"../.." -MMD -MF "${OBJECTDIR}/_ext/820665884/qstamp.o.d" -o ${OBJECTDIR}/_ext/820665884/qstamp.o ../../../../../src/qs/qstamp.c -DXPRJ_spy=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 + ${OBJECTDIR}/bsp.o: bsp.c nbproject/Makefile-${CND_CONF}.mk @${MKDIR} "${OBJECTDIR}" @${RM} ${OBJECTDIR}/bsp.o.d @@ -353,12 +359,6 @@ ${OBJECTDIR}/_ext/43898991/main.o: ../../main.c nbproject/Makefile-${CND_CONF}. @${RM} ${OBJECTDIR}/_ext/43898991/main.o @${FIXDEPS} "${OBJECTDIR}/_ext/43898991/main.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -DQ_SPY -I"../../../../../include" -I"../../../../../src" -I"../../../../../ports/pic32/qv/xc32" -I"../.." -MMD -MF "${OBJECTDIR}/_ext/43898991/main.o.d" -o ${OBJECTDIR}/_ext/43898991/main.o ../../main.c -DXPRJ_spy=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 -${OBJECTDIR}/_ext/726959463/qstamp.o: ../../../../../include/qstamp.c nbproject/Makefile-${CND_CONF}.mk - @${MKDIR} "${OBJECTDIR}/_ext/726959463" - @${RM} ${OBJECTDIR}/_ext/726959463/qstamp.o.d - @${RM} ${OBJECTDIR}/_ext/726959463/qstamp.o - @${FIXDEPS} "${OBJECTDIR}/_ext/726959463/qstamp.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -DQ_SPY -I"../../../../../include" -I"../../../../../src" -I"../../../../../ports/pic32/qv/xc32" -I"../.." -MMD -MF "${OBJECTDIR}/_ext/726959463/qstamp.o.d" -o ${OBJECTDIR}/_ext/726959463/qstamp.o ../../../../../include/qstamp.c -DXPRJ_spy=$(CND_CONF) -no-legacy-libc $(COMPARISON_BUILD) -std=c99 - ${OBJECTDIR}/_ext/43898991/philo.o: ../../philo.c nbproject/Makefile-${CND_CONF}.mk @${MKDIR} "${OBJECTDIR}/_ext/43898991" @${RM} ${OBJECTDIR}/_ext/43898991/philo.o.d diff --git a/examples/pic32/dpp_microstick2-pic32/qv/xc32/nbproject/configurations.xml b/examples/pic32/dpp_microstick2-pic32/qv/xc32/nbproject/configurations.xml index 7f6e6b64..2ec57f44 100644 --- a/examples/pic32/dpp_microstick2-pic32/qv/xc32/nbproject/configurations.xml +++ b/examples/pic32/dpp_microstick2-pic32/qv/xc32/nbproject/configurations.xml @@ -29,6 +29,7 @@ ../../../../../src/qs/qs_64bit.c ../../../../../src/qs/qs_fp.c ../../../../../src/qs/qs_rx.c + ../../../../../src/qs/qstamp.c bsp.c ../../bsp.h ../../main.c - ../../../../../include/qstamp.c ../../philo.c ../../table.c @@ -286,6 +286,7 @@ + @@ -732,6 +733,7 @@ + diff --git a/examples/pic32/dpp_microstick2-pic32/qv/xc32/nbproject/private/configurations.xml b/examples/pic32/dpp_microstick2-pic32/qv/xc32/nbproject/private/configurations.xml index 31417c1a..e52d0e4e 100644 --- a/examples/pic32/dpp_microstick2-pic32/qv/xc32/nbproject/private/configurations.xml +++ b/examples/pic32/dpp_microstick2-pic32/qv/xc32/nbproject/private/configurations.xml @@ -4,7 +4,7 @@ 0 - + :=MPLABComm-USB-Microchip:=<vid>04D8:=<pid>8107:=<rev>0002:=<man>Microchip Technology Incorporated:=<prod>Microstick II SK:=<sn>BUR123045184:=<drv>x:=<xpt>h:=end C:\tools\Microchip\xc32\bin place holder 1 diff --git a/examples/pic32/dpp_microstick2-pic32/qv/xc32/nbproject/private/private.xml b/examples/pic32/dpp_microstick2-pic32/qv/xc32/nbproject/private/private.xml index cd3e03d7..17e0aecb 100644 --- a/examples/pic32/dpp_microstick2-pic32/qv/xc32/nbproject/private/private.xml +++ b/examples/pic32/dpp_microstick2-pic32/qv/xc32/nbproject/private/private.xml @@ -3,6 +3,9 @@ - + + file:/C:/qp-dev/qpc/src/qv/qv.c + file:/C:/qp-dev/qpc/examples/pic32/dpp_microstick2-pic32/qv/xc32/bsp.c + diff --git a/examples/pic32/dpp_microstick2-pic32/table.c b/examples/pic32/dpp_microstick2-pic32/table.c index 6a452abe..c3ae02f0 100644 --- a/examples/pic32/dpp_microstick2-pic32/table.c +++ b/examples/pic32/dpp_microstick2-pic32/table.c @@ -1,136 +1,149 @@ -/*$file${.::table.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* -* Model: dpp.qm -* File: ${.::table.c} -* -* This code has been generated by QM 5.2.4 . -* DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. -* -* SPDX-License-Identifier: GPL-3.0-or-later -* -* This generated code is open source software: you can redistribute it under -* the terms of the GNU General Public License as published by the Free -* Software Foundation. -* -* This code is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -* more details. -* -* NOTE: -* Alternatively, this generated code may be distributed under the terms -* of Quantum Leaps commercial licenses, which expressly supersede the GNU -* General Public License and are specifically designed for licensees -* interested in retaining the proprietary status of their code. -* -* Contact information: -* -* -*/ -/*$endhead${.::table.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -#include "qpc.h" -#include "dpp.h" -#include "bsp.h" +//$file${.::table.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// +// Model: dpp.qm +// File: ${.::table.c} +// +// This code has been generated by QM 5.3.0 . +// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. +// +// SPDX-License-Identifier: GPL-3.0-or-later +// +// This generated code is open source software: you can redistribute it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation. +// +// This code is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// NOTE: +// Alternatively, this generated code may be distributed under the terms +// of Quantum Leaps commercial licenses, which expressly supersede the GNU +// General Public License and are specifically designed for licensees +// interested in retaining the proprietary status of their code. +// +// Contact information: +// +// +// +//$endhead${.::table.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +#include "qpc.h" // QP/C real-time embedded framework +#include "dpp.h" // DPP Application interface +#include "bsp.h" // Board Support Package -Q_DEFINE_THIS_FILE +//$declare${AOs::Table} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/* Active object class -----------------------------------------------------*/ -/*$declare${AOs::Table} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${AOs::Table} ............................................................*/ -typedef struct { -/* protected: */ +//${AOs::Table} .............................................................. +typedef struct Table { +// protected: QActive super; -/* private: */ +// private: uint8_t fork[N_PHILO]; - uint8_t isHungry[N_PHILO]; + bool isHungry[N_PHILO]; + +// public: } Table; -/* protected: */ +extern Table Table_inst; + +// protected: static QState Table_initial(Table * const me, void const * const par); static QState Table_active(Table * const me, QEvt const * const e); static QState Table_serving(Table * const me, QEvt const * const e); static QState Table_paused(Table * const me, QEvt const * const e); -/*$enddecl${AOs::Table} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$enddecl${AOs::Table} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -#define RIGHT(n_) ((uint8_t)(((n_) + (N_PHILO - 1U)) % N_PHILO)) -#define LEFT(n_) ((uint8_t)(((n_) + 1U) % N_PHILO)) -#define FREE ((uint8_t)0) -#define USED ((uint8_t)1) +//---------------------------------------------------------------------------- +Q_DEFINE_THIS_FILE -/* Local objects -----------------------------------------------------------*/ -static Table l_table; /* the single instance of the Table active object */ +// helper function to provide the RIGHT neighbor of a Philo[n] +static inline uint8_t right(uint8_t const n) { + return (uint8_t)((n + (N_PHILO - 1U)) % N_PHILO); +} -/* Global-scope objects ----------------------------------------------------*/ -QActive * const AO_Table = &l_table.super; /* "opaque" AO pointer */ +// helper function to provide the LEFT neighbor of a Philo[n] +static inline uint8_t left(uint8_t const n) { + return (uint8_t)((n + 1U) % N_PHILO); +} -/*..........................................................................*/ -/*$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* Check for the minimum required QP version */ -#if (QP_VERSION < 700U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) -#error qpc version 7.0.0 or higher required +#define FREE ((uint8_t)0U) +#define USED ((uint8_t)1U) + +#define THINKING "thinking" +#define HUNGRY "hungry " +#define EATING "eating " + +//---------------------------------------------------------------------------- + +//$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// Check for the minimum required QP version +#if (QP_VERSION < 730U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) +#error qpc version 7.3.0 or higher required #endif -/*$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -/*$define${AOs::Table_ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//$define${Shared::Table_ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/*${AOs::Table_ctor} .......................................................*/ +//${Shared::Table_ctor} ...................................................... void Table_ctor(void) { - uint8_t n; - Table *me = &l_table; - + Table * const me = &Table_inst; QActive_ctor(&me->super, Q_STATE_CAST(&Table_initial)); - - for (n = 0U; n < N_PHILO; ++n) { + for (uint8_t n = 0U; n < N_PHILO; ++n) { me->fork[n] = FREE; - me->isHungry[n] = 0U; + me->isHungry[n] = false; } } -/*$enddef${AOs::Table_ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*$define${AOs::Table} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//$enddef${Shared::Table_ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +//$define${Shared::AO_Table} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/*${AOs::Table} ............................................................*/ +//${Shared::AO_Table} ........................................................ +QActive * const AO_Table = &Table_inst.super; +//$enddef${Shared::AO_Table} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +//$define${AOs::Table} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/*${AOs::Table::SM} ........................................................*/ +//${AOs::Table} .............................................................. +Table Table_inst; + +//${AOs::Table::SM} .......................................................... static QState Table_initial(Table * const me, void const * const par) { - /*${AOs::Table::SM::initial} */ - (void)par; /* unused parameter */ + //${AOs::Table::SM::initial} + Q_UNUSED_PAR(par); - QS_OBJ_DICTIONARY(&l_table); - - QS_SIG_DICTIONARY(DONE_SIG, (void *)0); /* global signals */ - QS_SIG_DICTIONARY(EAT_SIG, (void *)0); - QS_SIG_DICTIONARY(PAUSE_SIG, (void *)0); - QS_SIG_DICTIONARY(SERVE_SIG, (void *)0); - QS_SIG_DICTIONARY(TERMINATE_SIG, (void *)0); - - QS_SIG_DICTIONARY(HUNGRY_SIG, me); /* signal just for Table */ + #ifdef Q_SPY + Table *Table_inst = me; + QS_OBJ_DICTIONARY(Table_inst); + #endif QActive_subscribe(&me->super, DONE_SIG); QActive_subscribe(&me->super, PAUSE_SIG); QActive_subscribe(&me->super, SERVE_SIG); - QActive_subscribe(&me->super, TERMINATE_SIG); + QActive_subscribe(&me->super, TEST_SIG); for (uint8_t n = 0U; n < N_PHILO; ++n) { me->fork[n] = FREE; - me->isHungry[n] = 0U; - BSP_displayPhilStat(n, "thinking"); + me->isHungry[n] = false; + BSP_displayPhilStat(n, THINKING); } + + QS_FUN_DICTIONARY(&Table_active); + QS_FUN_DICTIONARY(&Table_serving); + QS_FUN_DICTIONARY(&Table_paused); + return Q_TRAN(&Table_serving); } -/*${AOs::Table::SM::active} ................................................*/ +//${AOs::Table::SM::active} .................................................. static QState Table_active(Table * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${AOs::Table::SM::active::TERMINATE} */ - case TERMINATE_SIG: { - BSP_terminate(0); + //${AOs::Table::SM::active::TEST} + case TEST_SIG: { status_ = Q_HANDLED(); break; } - /*${AOs::Table::SM::active::EAT} */ + //${AOs::Table::SM::active::EAT} case EAT_SIG: { Q_ERROR(); status_ = Q_HANDLED(); @@ -144,108 +157,119 @@ static QState Table_active(Table * const me, QEvt const * const e) { return status_; } -/*${AOs::Table::SM::active::serving} .......................................*/ +//${AOs::Table::SM::active::serving} ......................................... static QState Table_serving(Table * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${AOs::Table::SM::active::serving} */ + //${AOs::Table::SM::active::serving} case Q_ENTRY_SIG: { - uint8_t n; - for (n = 0U; n < N_PHILO; ++n) { /* give permissions to eat... */ - if ((me->isHungry[n] != 0U) - && (me->fork[LEFT(n)] == FREE) + // give permissions to eat... + for (uint8_t n = 0U; n < N_PHILO; ++n) { + if (me->isHungry[n] + && (me->fork[left(n)] == FREE) && (me->fork[n] == FREE)) { - TableEvt *te; - - me->fork[LEFT(n)] = USED; + me->fork[left(n)] = USED; me->fork[n] = USED; - te = Q_NEW(TableEvt, EAT_SIG); - te->philoNum = n; - QACTIVE_PUBLISH(&te->super, &me->super); - me->isHungry[n] = 0U; - BSP_displayPhilStat(n, "eating "); + #ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, EAT_SIG, n); + #else + TableEvt *pe = Q_NEW(TableEvt, EAT_SIG); + pe->philoId = n; + #endif + QACTIVE_PUBLISH(&pe->super, &me->super); + me->isHungry[n] = false; + BSP_displayPhilStat(n, EATING); } } status_ = Q_HANDLED(); break; } - /*${AOs::Table::SM::active::serving::HUNGRY} */ + //${AOs::Table::SM::active::serving::HUNGRY} case HUNGRY_SIG: { - uint8_t n, m; + uint8_t n = Q_EVT_CAST(TableEvt)->philoId; - n = Q_EVT_CAST(TableEvt)->philoNum; - /* phil ID must be in range and he must be not hungry */ - Q_ASSERT((n < N_PHILO) && (me->isHungry[n] == 0U)); + // phil ID must be in range and he must be not hungry + Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); - BSP_displayPhilStat(n, "hungry "); - m = LEFT(n); - /*${AOs::Table::SM::active::serving::HUNGRY::[bothfree]} */ + BSP_displayPhilStat(n, HUNGRY); + uint8_t m = left(n); + //${AOs::Table::SM::active::serving::HUNGRY::[bothfree]} if ((me->fork[m] == FREE) && (me->fork[n] == FREE)) { - TableEvt *pe; me->fork[m] = USED; me->fork[n] = USED; - pe = Q_NEW(TableEvt, EAT_SIG); - pe->philoNum = n; + #ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, EAT_SIG, n); + #else + TableEvt *pe = Q_NEW(TableEvt, EAT_SIG); + pe->philoId = n; + #endif QACTIVE_PUBLISH(&pe->super, &me->super); - BSP_displayPhilStat(n, "eating "); + BSP_displayPhilStat(n, EATING); status_ = Q_HANDLED(); } - /*${AOs::Table::SM::active::serving::HUNGRY::[else]} */ + //${AOs::Table::SM::active::serving::HUNGRY::[else]} else { - me->isHungry[n] = 1U; + me->isHungry[n] = true; status_ = Q_HANDLED(); } break; } - /*${AOs::Table::SM::active::serving::DONE} */ + //${AOs::Table::SM::active::serving::DONE} case DONE_SIG: { - uint8_t n, m; - TableEvt *pe; + uint8_t n = Q_EVT_CAST(TableEvt)->philoId; - n = Q_EVT_CAST(TableEvt)->philoNum; - /* phil ID must be in range and he must be not hungry */ - Q_ASSERT((n < N_PHILO) && (me->isHungry[n] == 0U)); + // phil ID must be in range and he must be not hungry + Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); - BSP_displayPhilStat(n, "thinking"); - m = LEFT(n); - /* both forks of Phil[n] must be used */ + BSP_displayPhilStat(n, THINKING); + uint8_t m = left(n); + + // both forks of Phil[n] must be used Q_ASSERT((me->fork[n] == USED) && (me->fork[m] == USED)); me->fork[m] = FREE; me->fork[n] = FREE; - m = RIGHT(n); /* check the right neighbor */ + m = right(n); // check the right neighbor - if ((me->isHungry[m] != 0U) && (me->fork[m] == FREE)) { + if (me->isHungry[m] && (me->fork[m] == FREE)) { me->fork[n] = USED; me->fork[m] = USED; - me->isHungry[m] = 0U; - pe = Q_NEW(TableEvt, EAT_SIG); - pe->philoNum = m; + me->isHungry[m] = false; + #ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, EAT_SIG, m); + #else + TableEvt *pe = Q_NEW(TableEvt, EAT_SIG); + pe->philoId = m; + #endif QACTIVE_PUBLISH(&pe->super, &me->super); - BSP_displayPhilStat(m, "eating "); + BSP_displayPhilStat(m, EATING); } - m = LEFT(n); /* check the left neighbor */ - n = LEFT(m); /* left fork of the left neighbor */ - if ((me->isHungry[m] != 0U) && (me->fork[n] == FREE)) { + m = left(n); // check the left neighbor + n = left(m); // left fork of the left neighbor + if (me->isHungry[m] && (me->fork[n] == FREE)) { me->fork[m] = USED; me->fork[n] = USED; - me->isHungry[m] = 0U; - pe = Q_NEW(TableEvt, EAT_SIG); - pe->philoNum = m; + me->isHungry[m] = false; + #ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, EAT_SIG, m); + #else + TableEvt *pe = Q_NEW(TableEvt, EAT_SIG); + pe->philoId = m; + #endif QACTIVE_PUBLISH(&pe->super, &me->super); - BSP_displayPhilStat(m, "eating "); + BSP_displayPhilStat(m, EATING); } status_ = Q_HANDLED(); break; } - /*${AOs::Table::SM::active::serving::EAT} */ + //${AOs::Table::SM::active::serving::EAT} case EAT_SIG: { Q_ERROR(); status_ = Q_HANDLED(); break; } - /*${AOs::Table::SM::active::serving::PAUSE} */ + //${AOs::Table::SM::active::serving::PAUSE} case PAUSE_SIG: { status_ = Q_TRAN(&Table_paused); break; @@ -258,48 +282,50 @@ static QState Table_serving(Table * const me, QEvt const * const e) { return status_; } -/*${AOs::Table::SM::active::paused} ........................................*/ +//${AOs::Table::SM::active::paused} .......................................... static QState Table_paused(Table * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${AOs::Table::SM::active::paused} */ + //${AOs::Table::SM::active::paused} case Q_ENTRY_SIG: { BSP_displayPaused(1U); status_ = Q_HANDLED(); break; } - /*${AOs::Table::SM::active::paused} */ + //${AOs::Table::SM::active::paused} case Q_EXIT_SIG: { BSP_displayPaused(0U); status_ = Q_HANDLED(); break; } - /*${AOs::Table::SM::active::paused::SERVE} */ + //${AOs::Table::SM::active::paused::SERVE} case SERVE_SIG: { status_ = Q_TRAN(&Table_serving); break; } - /*${AOs::Table::SM::active::paused::HUNGRY} */ + //${AOs::Table::SM::active::paused::HUNGRY} case HUNGRY_SIG: { - uint8_t n = Q_EVT_CAST(TableEvt)->philoNum; - /* philo ID must be in range and he must be not hungry */ - Q_ASSERT((n < N_PHILO) && (me->isHungry[n] == 0U)); - me->isHungry[n] = 1U; - BSP_displayPhilStat(n, "hungry "); + uint8_t n = Q_EVT_CAST(TableEvt)->philoId; + + // philo ID must be in range and he must be not hungry + Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); + + me->isHungry[n] = true; + BSP_displayPhilStat(n, HUNGRY); status_ = Q_HANDLED(); break; } - /*${AOs::Table::SM::active::paused::DONE} */ + //${AOs::Table::SM::active::paused::DONE} case DONE_SIG: { - uint8_t n, m; + uint8_t n = Q_EVT_CAST(TableEvt)->philoId; - n = Q_EVT_CAST(TableEvt)->philoNum; - /* phil ID must be in range and he must be not hungry */ - Q_ASSERT((n < N_PHILO) && (me->isHungry[n] == 0U)); + // phil ID must be in range and he must be not hungry + Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); - BSP_displayPhilStat(n, "thinking"); - m = LEFT(n); - /* both forks of Phil[n] must be used */ + BSP_displayPhilStat(n, THINKING); + uint8_t m = left(n); + + // both forks of Phil[n] must be used Q_ASSERT((me->fork[n] == USED) && (me->fork[m] == USED)); me->fork[m] = FREE; @@ -314,4 +340,4 @@ static QState Table_paused(Table * const me, QEvt const * const e) { } return status_; } -/*$enddef${AOs::Table} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$enddef${AOs::Table} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/examples/posix-win32/README.md b/examples/posix-win32/README.md new file mode 100644 index 00000000..b1582c18 --- /dev/null +++ b/examples/posix-win32/README.md @@ -0,0 +1,114 @@ +# ABOUT THE "posix-win32" EXAMPLES +The examples in the "posix-win32" directory are for the General Purpose +Operating Systems (GPOSes), such as: + +- POSIX (e.g., Linux, macOS, and RTOSes with the +POSIX subsystems, like INTEGRITY, vxWorks, etc.) +- Windows (Win32 API) + +The examples run in the standard terminal (as console applications) +and can be built with the standard C compilers available on the +respective operating systems, such as GCC, LLVM, Visual C++. The provided Makefiles support the GNU GCC toolchain. + +> **NOTE** +For Windows, the GNU GCC toolchain (MinGW) and the 'make' utility are +provided in the QTools collection, which is available from: + +- https://github.com/QuantumLeaps/qtools + +> **NOTE** +The "QP-bundle" for Windows also contains the GCC toolchain for Windows +(MinGW), the 'make' utility, and other POSIX-style extensions. + +- https://www.state-machine.com/#Downloads + + +# Single-Threaded and Multi-Threaded QP/C Ports +Each of the examples can be built with the single-threaded QP/C ports +(posix-qv or win32-qv) or multi-threaded ports (posix or win32). The choice +is made in the Makefiles, by editing the line, which defines the +`QP_PORT_DIR` symbol in the Makefile. For example, the following lines +in the Makefile select the single-threaded posix-qv port and leave the +multi-threaded posix port commented-out: + +``` +QP_PORT_DIR := $(QPC)/ports/posix-qv +#QP_PORT_DIR := $(QPC)/ports/posix +``` + +To reverse the selection, you need to move the comment '#' character. + +> **NOTE** +The single-threaded QP/C ports (posix-qv and win32-qv) are recommended for +emulating deeply-embedded software on the desktop. + +The multi-threaded QP/C ports (posix and win32) are intended for the +actual applications that run on (embedded)Linux or (embedded)Windows. + + +# Debug, Release, and Spy Build Configurations +The Makefiles and Visual Studio projects for the examples generally +support the following three build configurations: + +### Debug Configuration +This is the default build configuration, with full debugging information and +minimal optimization. To build this configuration, type: + +``` +make +``` + +To clean this build, type + +``` +make clean +``` + +The object files and the executable is located in the 'build' sub-directory. + + +### Release Configuration +This configuration is built with no debugging information and high +optimization. Single-stepping and debugging might be difficult due +to the lack of debugging information and optimized code. To build +this configuration, type: + +``` +make CONF=rel +``` + +To clean this build, type + +``` +make CONF=rel clean +``` + +The object files and the executable is located in the 'build_rel' directory. + +### Spy Configuration +This configuration is built with the QP's Q-SPY trace functionality. +The QP/Spy output is performed by a TCP/IP socket and requires launching +the QSPY host application with the -t option. To build this configuration, +type: + +``` +make CONF=spy +``` + +To clean this build, type + +``` +make CONF=spy clean +``` + +The object files and the executable are located in the 'build_spy' directory. + +> **NOTE** +Only specific examples support the Spy build configuration. The examples +that don't support it, will report an error or will fail the linking stage. + + +# Support and Contact Information +- Free discussion forum: https://sourceforge.net/p/qpc/discussion/668726/ +- Quantum Leaps website: https://www.state-machine.com +- Quantum Leaps email: info@state-machine.com diff --git a/examples/workstation/blinky/Makefile b/examples/posix-win32/blinky/Makefile similarity index 96% rename from examples/workstation/blinky/Makefile rename to examples/posix-win32/blinky/Makefile index 230ef9ea..c74690ec 100644 --- a/examples/workstation/blinky/Makefile +++ b/examples/posix-win32/blinky/Makefile @@ -1,13 +1,13 @@ ############################################################################## # Product: Makefile for QP/C for Windows and POSIX *HOSTS* -# Last updated for version 7.2.0 -# Last updated on 2022-11-13 +# Last updated for version 7.2.2 +# Last updated on 2023-02-17 # # Q u a n t u m L e a P s # ------------------------ # Modern Embedded Software # -# Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +# Copyright (C) 2005 Quantum Leaps, LLC, . # # This program is open source software: you can redistribute it and/or # modify it under the terms of the GNU General Public License as published @@ -43,7 +43,7 @@ # NOTE: # To use this Makefile on Windows, you will need the GNU make utility, which # is included in the QTools collection for Windows, see: -# http://sourceforge.net/projects/qpc/files/QTools/ +# https://github.com/QuantumLeaps/qtools # #----------------------------------------------------------------------------- @@ -240,7 +240,7 @@ CPP_DEPS_EXT := $(patsubst %.o,%.d, $(CPP_OBJS_EXT)) all: $(TARGET_EXE) $(TARGET_EXE) : $(C_OBJS_EXT) $(CPP_OBJS_EXT) - $(CC) $(CFLAGS) $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o + $(CC) $(CFLAGS) $(QPC)/src/qs/qstamp.c -o $(BIN_DIR)/qstamp.o $(LINK) $(LINKFLAGS) $(LIB_DIRS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) $(BIN_DIR)/%.d : %.c diff --git a/examples/workstation/blinky/README.md b/examples/posix-win32/blinky/README.md similarity index 87% rename from examples/workstation/blinky/README.md rename to examples/posix-win32/blinky/README.md index fe4dfad2..1982624d 100644 --- a/examples/workstation/blinky/README.md +++ b/examples/posix-win32/blinky/README.md @@ -1,9 +1,7 @@ -@page exa_workstation_blinky Example: Blinky Console +# Example: Blinky Console ![Blinky on Win32](blinky_win.png) -# Example: Blinky Console - This example corresponds to the QM Tutorial at: https://www.state-machine.com/qm/gs_tut.html diff --git a/examples/posix-win32/blinky/blinky.c b/examples/posix-win32/blinky/blinky.c new file mode 100644 index 00000000..c62d668d --- /dev/null +++ b/examples/posix-win32/blinky/blinky.c @@ -0,0 +1,194 @@ +//$file${.::blinky.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// +// Model: blinky.qm +// File: ${.::blinky.c} +// +// This code has been generated by QM 5.3.0 . +// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. +// +// SPDX-License-Identifier: GPL-3.0-or-later +// +// This generated code is open source software: you can redistribute it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation. +// +// This code is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// NOTE: +// Alternatively, this generated code may be distributed under the terms +// of Quantum Leaps commercial licenses, which expressly supersede the GNU +// General Public License and are specifically designed for licensees +// interested in retaining the proprietary status of their code. +// +// Contact information: +// +// +// +//$endhead${.::blinky.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +#include "qpc.h" + +#include "safe_std.h" // portable "safe" / facilities +#include // for exit() + +//Q_DEFINE_THIS_FILE + +#ifdef Q_SPY + #error Simple Blinky Application does not provide Spy build configuration +#endif + +enum { BSP_TICKS_PER_SEC = 100 }; + +//.......................................................................... +void BSP_ledOff(void) { + PRINTF_S("%s\n", "LED OFF"); +} +//.......................................................................... +void BSP_ledOn(void) { + PRINTF_S("%s\n", "LED ON"); +} +//.......................................................................... +Q_NORETURN Q_onError(char const * const module, int_t const id) { + FPRINTF_S(stderr, "ERROR in %s:%d", module, id); + exit(-1); +} +//.......................................................................... +void assert_failed(char const * const module, int_t const id); // prototype +void assert_failed(char const * const module, int_t const id) { + Q_onError(module, id); +} +//.......................................................................... +void QF_onStartup(void) {} +//.......................................................................... +void QF_onCleanup(void) {} +//.......................................................................... +void QF_onClockTick(void) { + QTIMEEVT_TICK_X(0U, (void *)0); // clock tick processing +} + +enum BlinkySignals { + TIMEOUT_SIG = Q_USER_SIG, + MAX_SIG +}; + +///============== ask QM to declare the Blinky class ================ +//$declare${AOs::Blinky} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${AOs::Blinky} ............................................................. +typedef struct Blinky { +// protected: + QActive super; + +// private: + QTimeEvt timeEvt; + +// public: +} Blinky; + +// public: + +// constructor +static void Blinky_ctor(Blinky * const me); +extern Blinky Blinky_inst; + +// protected: +static QState Blinky_initial(Blinky * const me, void const * const par); +static QState Blinky_off(Blinky * const me, QEvt const * const e); +static QState Blinky_on(Blinky * const me, QEvt const * const e); +//$enddecl${AOs::Blinky} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +QActive * const AO_Blinky = &Blinky_inst.super; + +int main() { + QF_init(); // initialize the framework + + Blinky_ctor(&Blinky_inst); // explicitly call the "constructor" + static QEvt const *blinky_queueSto[10]; + QACTIVE_START(AO_Blinky, + 1U, // priority + blinky_queueSto, Q_DIM(blinky_queueSto), + (void *)0, 0U, // no stack + (void *)0); // no initialization parameter + return QF_run(); // run the QF application +} + +//================ ask QM to define the Blinky class ================ +//$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// Check for the minimum required QP version +#if (QP_VERSION < 730U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) +#error qpc version 7.3.0 or higher required +#endif +//$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +//$define${AOs::Blinky} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${AOs::Blinky} ............................................................. +Blinky Blinky_inst; + +//${AOs::Blinky::ctor} ....................................................... +static void Blinky_ctor(Blinky * const me) { + QActive_ctor(&me->super, Q_STATE_CAST(&Blinky_initial)); + QTimeEvt_ctorX(&me->timeEvt, &me->super, TIMEOUT_SIG, 0U); +} + +//${AOs::Blinky::SM} ......................................................... +static QState Blinky_initial(Blinky * const me, void const * const par) { + //${AOs::Blinky::SM::initial} + (void)par; // unused parameter + QTimeEvt_armX(&me->timeEvt, + BSP_TICKS_PER_SEC/2, BSP_TICKS_PER_SEC/2); + + QS_FUN_DICTIONARY(&Blinky_off); + QS_FUN_DICTIONARY(&Blinky_on); + + return Q_TRAN(&Blinky_off); +} + +//${AOs::Blinky::SM::off} .................................................... +static QState Blinky_off(Blinky * const me, QEvt const * const e) { + QState status_; + switch (e->sig) { + //${AOs::Blinky::SM::off} + case Q_ENTRY_SIG: { + BSP_ledOff(); + status_ = Q_HANDLED(); + break; + } + //${AOs::Blinky::SM::off::TIMEOUT} + case TIMEOUT_SIG: { + status_ = Q_TRAN(&Blinky_on); + break; + } + default: { + status_ = Q_SUPER(&QHsm_top); + break; + } + } + return status_; +} + +//${AOs::Blinky::SM::on} ..................................................... +static QState Blinky_on(Blinky * const me, QEvt const * const e) { + QState status_; + switch (e->sig) { + //${AOs::Blinky::SM::on} + case Q_ENTRY_SIG: { + BSP_ledOn(); + status_ = Q_HANDLED(); + break; + } + //${AOs::Blinky::SM::on::TIMEOUT} + case TIMEOUT_SIG: { + status_ = Q_TRAN(&Blinky_off); + break; + } + default: { + status_ = Q_SUPER(&QHsm_top); + break; + } + } + return status_; +} +//$enddef${AOs::Blinky} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/examples/workstation/blinky/blinky.qm b/examples/posix-win32/blinky/blinky.qm similarity index 57% rename from examples/workstation/blinky/blinky.qm rename to examples/posix-win32/blinky/blinky.qm index 9d8cb4c9..912db307 100644 --- a/examples/workstation/blinky/blinky.qm +++ b/examples/posix-win32/blinky/blinky.qm @@ -1,5 +1,5 @@ - + Blinky example @@ -7,16 +7,22 @@ - - + + + + + // constructor + QActive_ctor(&me->super, Q_STATE_CAST(&Blinky_initial)); +QTimeEvt_ctorX(&me->timeEvt, &me->super, TIMEOUT_SIG, 0U); + Blinky state machine - (void)par; /* unused parameter */ + (void)par; // unused parameter QTimeEvt_armX(&me->timeEvt, BSP_TICKS_PER_SEC/2, BSP_TICKS_PER_SEC/2); @@ -59,10 +65,10 @@ BSP_TICKS_PER_SEC/2, BSP_TICKS_PER_SEC/2); #include "qpc.h" -#include "safe_std.h" /* portable "safe" <stdio.h>/<string.h> facilities */ -#include <stdlib.h> /* for exit() */ +#include "safe_std.h" // portable "safe" <stdio.h>/<string.h> facilities +#include <stdlib.h> // for exit() -Q_DEFINE_THIS_FILE +//Q_DEFINE_THIS_FILE #ifdef Q_SPY #error Simple Blinky Application does not provide Spy build configuration @@ -70,20 +76,31 @@ Q_DEFINE_THIS_FILE enum { BSP_TICKS_PER_SEC = 100 }; +//.......................................................................... void BSP_ledOff(void) { PRINTF_S("%s\n", "LED OFF"); } +//.......................................................................... void BSP_ledOn(void) { PRINTF_S("%s\n", "LED ON"); } -void Q_onAssert(char const * const module, int loc) { - FPRINTF_S(stderr, "Assertion failed in %s:%d", module, loc); +//.......................................................................... +Q_NORETURN Q_onError(char const * const module, int_t const id) { + FPRINTF_S(stderr, "ERROR in %s:%d", module, id); exit(-1); } +//.......................................................................... +void assert_failed(char const * const module, int_t const id); // prototype +void assert_failed(char const * const module, int_t const id) { + Q_onError(module, id); +} +//.......................................................................... void QF_onStartup(void) {} +//.......................................................................... void QF_onCleanup(void) {} +//.......................................................................... void QF_onClockTick(void) { - QTIMEEVT_TICK_X(0U, (void *)0); /* clock tick processing */ + QTIMEEVT_TICK_X(0U, (void *)0); // clock tick processing } enum BlinkySignals { @@ -91,33 +108,25 @@ enum BlinkySignals { MAX_SIG }; -//*============== ask QM to declare the Blinky class ================*/ +///============== ask QM to declare the Blinky class ================ $declare ${AOs::Blinky} QActive * const AO_Blinky = &Blinky_inst.super; -static void Blinky_ctor(void) { - Blinky *me = &Blinky_inst; - QActive_ctor(&me->super, Q_STATE_CAST(&Blinky_initial)); - QTimeEvt_ctorX(&me->timeEvt, &me->super, TIMEOUT_SIG, 0U); -} - int main() { - /* statically allocate event queue buffer for the Blinky AO */ + QF_init(); // initialize the framework + + Blinky_ctor(&Blinky_inst); // explicitly call the "constructor" static QEvt const *blinky_queueSto[10]; - - QF_init(); /* initialize the framework */ - - Blinky_ctor(); /* explicitly call the "constructor" */ QACTIVE_START(AO_Blinky, - 1U, /* priority */ + 1U, // priority blinky_queueSto, Q_DIM(blinky_queueSto), - (void *)0, 0U, /* no stack */ - (void *)0); /* no initialization parameter */ - return QF_run(); /* run the QF application */ + (void *)0, 0U, // no stack + (void *)0); // no initialization parameter + return QF_run(); // run the QF application } -/*================ ask QM to define the Blinky class ================*/ +//================ ask QM to define the Blinky class ================ $define ${AOs::Blinky} diff --git a/examples/posix-win32/blinky/blinky_win.png b/examples/posix-win32/blinky/blinky_win.png new file mode 100644 index 00000000..3cf950fe Binary files /dev/null and b/examples/posix-win32/blinky/blinky_win.png differ diff --git a/examples/workstation/calc/Makefile b/examples/posix-win32/calc/Makefile similarity index 99% rename from examples/workstation/calc/Makefile rename to examples/posix-win32/calc/Makefile index 04000496..8cb82aa4 100644 --- a/examples/workstation/calc/Makefile +++ b/examples/posix-win32/calc/Makefile @@ -242,7 +242,7 @@ CPP_DEPS_EXT := $(patsubst %.o,%.d, $(CPP_OBJS_EXT)) all: $(TARGET_EXE) $(TARGET_EXE) : $(C_OBJS_EXT) $(CPP_OBJS_EXT) - $(CC) $(CFLAGS) $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o + $(CC) $(CFLAGS) $(QPC)/src/qs/qstamp.c -o $(BIN_DIR)/qstamp.o $(LINK) $(LINKFLAGS) $(LIB_DIRS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) $(BIN_DIR)/%.d : %.c diff --git a/examples/posix-win32/calc/SM_of_Calc.png b/examples/posix-win32/calc/SM_of_Calc.png new file mode 100644 index 00000000..f680d3f9 Binary files /dev/null and b/examples/posix-win32/calc/SM_of_Calc.png differ diff --git a/examples/posix-win32/calc/bsp.c b/examples/posix-win32/calc/bsp.c new file mode 100644 index 00000000..cfe452ba --- /dev/null +++ b/examples/posix-win32/calc/bsp.c @@ -0,0 +1,125 @@ +//============================================================================ +// Product: Board Support Package (BSP) for the Calculator example +// Last updated for version 6.9.0 +// Last updated on 2020-06-24 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// This program is open source software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Alternatively, this program may be distributed and modified under the +// terms of Quantum Leaps commercial licenses, which expressly supersede +// the GNU General Public License and are specifically designed for +// licensees interested in retaining the proprietary status of their code. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Contact information: +// +// +//============================================================================ +#include "qpc.h" +#include "bsp.h" + +#include "safe_std.h" // portable "safe" / facilities +#include // for exit() + +#define DISP_WIDTH 15 + +// helper macros to "stringify" values +#define VAL(x) #x +#define STRINGIFY(x) VAL(x) + +static char l_display[DISP_WIDTH + 1]; // the calculator display +static int l_len; // number of displayed characters + +//............................................................................ +void BSP_clear(void) { + memset(l_display, ' ', DISP_WIDTH - 1); + l_display[DISP_WIDTH - 1] = '0'; + l_display[DISP_WIDTH] = '\0'; + l_len = 0; +} +//............................................................................ +void BSP_insert(int keyId) { + if (l_len == 0) { + l_display[DISP_WIDTH - 1] = (char)keyId; + ++l_len; + } + else if (l_len < (DISP_WIDTH - 1)) { + MEMMOVE_S(&l_display[0], DISP_WIDTH, &l_display[1], DISP_WIDTH - 1); + l_display[DISP_WIDTH - 1] = (char)keyId; + ++l_len; + } +} +//............................................................................ +void BSP_display(double value) { + SNPRINTF_S(l_display, Q_DIM(l_display), + "%" STRINGIFY(DISP_WIDTH) ".6g", value); +} +//............................................................................ +void BSP_display_error(char const *err) { + STRNCPY_S(l_display, DISP_WIDTH, err); +} +//............................................................................ +void BSP_negate(void) { + BSP_clear(); + l_display[DISP_WIDTH - 2] = '-'; +} +//............................................................................ +void BSP_show_display(void) { + PRINTF_S("\n[%" STRINGIFY(DISP_WIDTH) "s] ", l_display); +} +//............................................................................ +void BSP_exit(void) { + PRINTF_S("\n%s\n", "Bye! Bye!"); + fflush(stdout); + QF_onCleanup(); + exit(0); +} +//............................................................................ +double BSP_get_value(void) { + return strtod(l_display, (char **)0); +} +//............................................................................ +void BSP_message(char const *msg) { + PRINTF_S("%s", msg); +} + +//............................................................................ +void QF_onStartup(void) { + QF_consoleSetup(); +} +//............................................................................ +void QF_onCleanup(void) { + QF_consoleCleanup(); +} +//............................................................................ +void QF_onClockTick(void) { +} + +//............................................................................ +// this function is used by the QP embedded systems-friendly assertions +Q_NORETURN Q_onError(char const * const module, int_t const id) { + FPRINTF_S(stderr, "ERROR in %s:%d", module, id); + QF_onCleanup(); + exit(-1); +} +//............................................................................ +void assert_failed(char const * const module, int_t const id); // prototype +void assert_failed(char const * const module, int_t const id) { + Q_onError(module, id); +} diff --git a/examples/posix-win32/calc/bsp.h b/examples/posix-win32/calc/bsp.h new file mode 100644 index 00000000..1e5c7148 --- /dev/null +++ b/examples/posix-win32/calc/bsp.h @@ -0,0 +1,48 @@ +//============================================================================ +// Product: Board Support Package (BSP) for the Calculator example +// Last updated for version 6.5.0 +// Last updated on 2019-03-20 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// This program is open source software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Alternatively, this program may be distributed and modified under the +// terms of Quantum Leaps commercial licenses, which expressly supersede +// the GNU General Public License and are specifically designed for +// licensees interested in retaining the proprietary status of their code. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Contact information: +// +// +//============================================================================ +#ifndef BSP_H_ +#define BSP_H_ + +void BSP_clear(void); +void BSP_negate(void); +void BSP_insert(int keyId); +double BSP_get_value(void); +void BSP_display(double value); +void BSP_display_error(char const *err); +void BSP_exit(void); + +void BSP_show_display(void); +void BSP_message(char const *msg); + +#endif // BSP_H_ diff --git a/examples/workstation/calc1/calc1.c b/examples/posix-win32/calc/calc.c similarity index 65% rename from examples/workstation/calc1/calc1.c rename to examples/posix-win32/calc/calc.c index 04012fec..5ba5773f 100644 --- a/examples/workstation/calc1/calc1.c +++ b/examples/posix-win32/calc/calc.c @@ -1,36 +1,36 @@ -/*$file${.::calc1.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* -* Model: calc1.qm -* File: ${.::calc1.c} -* -* This code has been generated by QM 5.2.4 . -* DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. -* -* SPDX-License-Identifier: GPL-3.0-or-later -* -* This generated code is open source software: you can redistribute it under -* the terms of the GNU General Public License as published by the Free -* Software Foundation. -* -* This code is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -* more details. -* -* NOTE: -* Alternatively, this generated code may be distributed under the terms -* of Quantum Leaps commercial licenses, which expressly supersede the GNU -* General Public License and are specifically designed for licensees -* interested in retaining the proprietary status of their code. -* -* Contact information: -* -* -*/ -/*$endhead${.::calc1.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -#include "qpc.h" /* QP/C */ -#include "bsp.h" /* board support package */ -#include "calc1.h" /* application */ +//$file${.::calc.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// +// Model: calc.qm +// File: ${.::calc.c} +// +// This code has been generated by QM 5.3.0 . +// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. +// +// SPDX-License-Identifier: GPL-3.0-or-later +// +// This generated code is open source software: you can redistribute it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation. +// +// This code is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// NOTE: +// Alternatively, this generated code may be distributed under the terms +// of Quantum Leaps commercial licenses, which expressly supersede the GNU +// General Public License and are specifically designed for licensees +// interested in retaining the proprietary status of their code. +// +// Contact information: +// +// +// +//$endhead${.::calc.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +#include "qpc.h" // QP/C +#include "bsp.h" // board support package +#include "calc.h" // application Q_DEFINE_THIS_FILE @@ -40,40 +40,34 @@ Q_DEFINE_THIS_FILE #define KEY_MULT '*' #define KEY_DIVIDE '/' -/*$declare${SMs::Calc} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//$declare${SMs::Calc} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/*${SMs::Calc} .............................................................*/ +//${SMs::Calc} ............................................................... typedef struct Calc { -/* protected: */ +// protected: QHsm super; -/* public: */ +// public: -/* private: */ +// private: double op1; double op2; uint8_t oper1; uint8_t oper2; } Calc; -/* private: */ +// private: -/* guard function to evaluate the current expression -* taking into account the precedence of operands. -* return: true if evaluation successfull -* false when error encountered -*/ +// guard function to evaluate the current expression static bool Calc_eval(Calc * const me, double op, uint8_t oper); extern Calc Calc_inst; -/* protected: */ +// protected: static QState Calc_initial(Calc * const me, void const * const par); static QState Calc_on(Calc * const me, QEvt const * const e); -/* Error state after evaluation of an expression. -This state can be exited only throgh the inherited C (Clear) event. -*/ +// Error state after evaluation of an expression. static QState Calc_error(Calc * const me, QEvt const * const e); static QState Calc_ready(Calc * const me, QEvt const * const e); static QState Calc_result(Calc * const me, QEvt const * const e); @@ -90,34 +84,34 @@ static QState Calc_int2(Calc * const me, QEvt const * const e); static QState Calc_frac2(Calc * const me, QEvt const * const e); static QState Calc_negated2(Calc * const me, QEvt const * const e); static QState Calc_final(Calc * const me, QEvt const * const e); -/*$enddecl${SMs::Calc} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$enddecl${SMs::Calc} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -/*$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* Check for the minimum required QP version */ -#if (QP_VERSION < 700U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) -#error qpc version 7.0.0 or higher required +//$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// Check for the minimum required QP version +#if (QP_VERSION < 730U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) +#error qpc version 7.3.0 or higher required #endif -/*$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -/*$define${SMs::the_calc} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//$define${SMs::the_calc} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/*${SMs::the_calc} .........................................................*/ +//${SMs::the_calc} ........................................................... QHsm * const the_calc = &Calc_inst.super; -/*$enddef${SMs::the_calc} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*$define${SMs::Calc_ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//$enddef${SMs::the_calc} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +//$define${SMs::Calc_ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/*${SMs::Calc_ctor} ........................................................*/ +//${SMs::Calc_ctor} .......................................................... void Calc_ctor(void) { Calc *me = &Calc_inst; QHsm_ctor(&me->super, Q_STATE_CAST(&Calc_initial)); } -/*$enddef${SMs::Calc_ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*$define${SMs::Calc} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//$enddef${SMs::Calc_ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +//$define${SMs::Calc} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/*${SMs::Calc} .............................................................*/ +//${SMs::Calc} ............................................................... Calc Calc_inst; -/*${SMs::Calc::eval} .......................................................*/ +//${SMs::Calc::eval} ......................................................... static bool Calc_eval(Calc * const me, double op, uint8_t oper) @@ -131,13 +125,13 @@ static bool Calc_eval(Calc * const me, } case KEY_DIVIDE: { if ((-1e-30 < op) && (op < 1e-30)) { - BSP_display_error(" Error 0 "); /* divide by zero */ + BSP_display_error(" Error 0 "); // divide by zero return false; } me->op2 /= op; break; } - default: { /* no op2 yet */ + default: { // no op2 yet me->op2 = op; me->oper2 = oper; break; @@ -158,7 +152,7 @@ static bool Calc_eval(Calc * const me, } case KEY_DIVIDE: { if ((-1e-30 < me->op2) && (me->op2 < 1e-30)) { - BSP_display_error(" Error 0 "); /* divide by zero */ + BSP_display_error(" Error 0 "); // divide by zero return false; } me->op1 /= me->op2; @@ -173,7 +167,7 @@ static bool Calc_eval(Calc * const me, me->oper2 = KEY_NULL; result = me->op1; } - else { /* (oper == KEY_MULT) || (oper == KEY_DIV) */ + else { // (oper == KEY_MULT) || (oper == KEY_DIV) switch (me->oper2) { case KEY_MULT: { me->op2 *= op; @@ -181,13 +175,13 @@ static bool Calc_eval(Calc * const me, } case KEY_DIVIDE: { if ((-1e-30 < op) && (op < 1e-30)) { - BSP_display_error(" Error 0 "); /* divide by zero */ + BSP_display_error(" Error 0 "); // divide by zero return false; } me->op2 /= op; break; } - default: { /* oper2 not provided yet */ + default: { // oper2 not provided yet me->op2 = op; break; } @@ -197,7 +191,7 @@ static bool Calc_eval(Calc * const me, } if ((result < -99999999.0) || (99999999.0 < result)) { - BSP_display_error(" Error 1 "); /* out of range */ + BSP_display_error(" Error 1 "); // out of range return false; } if ((-0.0000001 < result) && (result < 0.0000001)) { @@ -208,42 +202,42 @@ static bool Calc_eval(Calc * const me, return true; } -/*${SMs::Calc::SM} .........................................................*/ +//${SMs::Calc::SM} ........................................................... static QState Calc_initial(Calc * const me, void const * const par) { - /*${SMs::Calc::SM::initial} */ - (void)par; /* unused parameter */ + //${SMs::Calc::SM::initial} + (void)par; // unused parameter return Q_TRAN(&Calc_on); } -/*${SMs::Calc::SM::on} .....................................................*/ +//${SMs::Calc::SM::on} ....................................................... static QState Calc_on(Calc * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${SMs::Calc::SM::on} */ + //${SMs::Calc::SM::on} case Q_ENTRY_SIG: { BSP_message("on-ENTRY;"); status_ = Q_HANDLED(); break; } - /*${SMs::Calc::SM::on} */ + //${SMs::Calc::SM::on} case Q_EXIT_SIG: { BSP_message("on-EXIT;"); status_ = Q_HANDLED(); break; } - /*${SMs::Calc::SM::on::initial} */ + //${SMs::Calc::SM::on::initial} case Q_INIT_SIG: { BSP_message("on-INIT;"); BSP_clear(); status_ = Q_TRAN(&Calc_ready); break; } - /*${SMs::Calc::SM::on::C} */ + //${SMs::Calc::SM::on::C} case C_SIG: { status_ = Q_TRAN(&Calc_on); break; } - /*${SMs::Calc::SM::on::OFF} */ + //${SMs::Calc::SM::on::OFF} case OFF_SIG: { status_ = Q_TRAN(&Calc_final); break; @@ -256,17 +250,17 @@ static QState Calc_on(Calc * const me, QEvt const * const e) { return status_; } -/*${SMs::Calc::SM::on::error} ..............................................*/ +//${SMs::Calc::SM::on::error} ................................................ static QState Calc_error(Calc * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${SMs::Calc::SM::on::error} */ + //${SMs::Calc::SM::on::error} case Q_ENTRY_SIG: { BSP_message("error-ENTRY;"); status_ = Q_HANDLED(); break; } - /*${SMs::Calc::SM::on::error} */ + //${SMs::Calc::SM::on::error} case Q_EXIT_SIG: { BSP_message("error-EXIT;"); status_ = Q_HANDLED(); @@ -280,43 +274,43 @@ static QState Calc_error(Calc * const me, QEvt const * const e) { return status_; } -/*${SMs::Calc::SM::on::ready} ..............................................*/ +//${SMs::Calc::SM::on::ready} ................................................ static QState Calc_ready(Calc * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${SMs::Calc::SM::on::ready} */ + //${SMs::Calc::SM::on::ready} case Q_ENTRY_SIG: { BSP_message("ready-ENTRY;"); me->oper2 = KEY_NULL; status_ = Q_HANDLED(); break; } - /*${SMs::Calc::SM::on::ready} */ + //${SMs::Calc::SM::on::ready} case Q_EXIT_SIG: { BSP_message("ready-EXIT;"); status_ = Q_HANDLED(); break; } - /*${SMs::Calc::SM::on::ready::initial} */ + //${SMs::Calc::SM::on::ready::initial} case Q_INIT_SIG: { BSP_message("ready-INIT;"); status_ = Q_TRAN(&Calc_begin); break; } - /*${SMs::Calc::SM::on::ready::DIGIT_0} */ + //${SMs::Calc::SM::on::ready::DIGIT_0} case DIGIT_0_SIG: { BSP_clear(); status_ = Q_TRAN(&Calc_zero1); break; } - /*${SMs::Calc::SM::on::ready::DIGIT_1_9} */ + //${SMs::Calc::SM::on::ready::DIGIT_1_9} case DIGIT_1_9_SIG: { BSP_clear(); BSP_insert(Q_EVT_CAST(CalcEvt)->key_code); status_ = Q_TRAN(&Calc_int1); break; } - /*${SMs::Calc::SM::on::ready::POINT} */ + //${SMs::Calc::SM::on::ready::POINT} case POINT_SIG: { BSP_clear(); BSP_insert((int)'0'); @@ -324,7 +318,7 @@ static QState Calc_ready(Calc * const me, QEvt const * const e) { status_ = Q_TRAN(&Calc_frac1); break; } - /*${SMs::Calc::SM::on::ready::OPER} */ + //${SMs::Calc::SM::on::ready::OPER} case OPER_SIG: { me->op1 = BSP_get_value(); me->oper1 = Q_EVT_CAST(CalcEvt)->key_code; @@ -339,17 +333,17 @@ static QState Calc_ready(Calc * const me, QEvt const * const e) { return status_; } -/*${SMs::Calc::SM::on::ready::result} ......................................*/ +//${SMs::Calc::SM::on::ready::result} ........................................ static QState Calc_result(Calc * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${SMs::Calc::SM::on::ready::result} */ + //${SMs::Calc::SM::on::ready::result} case Q_ENTRY_SIG: { BSP_message("result-ENTRY;"); status_ = Q_HANDLED(); break; } - /*${SMs::Calc::SM::on::ready::result} */ + //${SMs::Calc::SM::on::ready::result} case Q_EXIT_SIG: { BSP_message("result-EXIT;"); status_ = Q_HANDLED(); @@ -363,29 +357,29 @@ static QState Calc_result(Calc * const me, QEvt const * const e) { return status_; } -/*${SMs::Calc::SM::on::ready::begin} .......................................*/ +//${SMs::Calc::SM::on::ready::begin} ......................................... static QState Calc_begin(Calc * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${SMs::Calc::SM::on::ready::begin} */ + //${SMs::Calc::SM::on::ready::begin} case Q_ENTRY_SIG: { BSP_message("begin-ENTRY;"); status_ = Q_HANDLED(); break; } - /*${SMs::Calc::SM::on::ready::begin} */ + //${SMs::Calc::SM::on::ready::begin} case Q_EXIT_SIG: { BSP_message("begin-EXIT;"); status_ = Q_HANDLED(); break; } - /*${SMs::Calc::SM::on::ready::begin::OPER} */ + //${SMs::Calc::SM::on::ready::begin::OPER} case OPER_SIG: { - /*${SMs::Calc::SM::on::ready::begin::OPER::[e->key=='-']} */ + //${SMs::Calc::SM::on::ready::begin::OPER::[e->key=='-']} if (Q_EVT_CAST(CalcEvt)->key_code == KEY_MINUS) { status_ = Q_TRAN(&Calc_negated1); } - /*${SMs::Calc::SM::on::ready::begin::OPER::[else]} */ + //${SMs::Calc::SM::on::ready::begin::OPER::[else]} else { status_ = Q_HANDLED(); } @@ -399,36 +393,36 @@ static QState Calc_begin(Calc * const me, QEvt const * const e) { return status_; } -/*${SMs::Calc::SM::on::operand1} ...........................................*/ +//${SMs::Calc::SM::on::operand1} ............................................. static QState Calc_operand1(Calc * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${SMs::Calc::SM::on::operand1} */ + //${SMs::Calc::SM::on::operand1} case Q_ENTRY_SIG: { BSP_message("operand1-ENTRY;"); status_ = Q_HANDLED(); break; } - /*${SMs::Calc::SM::on::operand1} */ + //${SMs::Calc::SM::on::operand1} case Q_EXIT_SIG: { BSP_message("operand1-EXIT;"); status_ = Q_HANDLED(); break; } - /*${SMs::Calc::SM::on::operand1::CE} */ + //${SMs::Calc::SM::on::operand1::CE} case CE_SIG: { BSP_clear(); status_ = Q_TRAN(&Calc_ready); break; } - /*${SMs::Calc::SM::on::operand1::OPER} */ + //${SMs::Calc::SM::on::operand1::OPER} case OPER_SIG: { me->op1 = BSP_get_value(); me->oper1 = Q_EVT_CAST(CalcEvt)->key_code; status_ = Q_TRAN(&Calc_opEntered); break; } - /*${SMs::Calc::SM::on::operand1::EQUALS} */ + //${SMs::Calc::SM::on::operand1::EQUALS} case EQUALS_SIG: { status_ = Q_TRAN(&Calc_result); break; @@ -441,35 +435,35 @@ static QState Calc_operand1(Calc * const me, QEvt const * const e) { return status_; } -/*${SMs::Calc::SM::on::operand1::zero1} ....................................*/ +//${SMs::Calc::SM::on::operand1::zero1} ...................................... static QState Calc_zero1(Calc * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${SMs::Calc::SM::on::operand1::zero1} */ + //${SMs::Calc::SM::on::operand1::zero1} case Q_ENTRY_SIG: { BSP_message("zero1-ENTRY;"); status_ = Q_HANDLED(); break; } - /*${SMs::Calc::SM::on::operand1::zero1} */ + //${SMs::Calc::SM::on::operand1::zero1} case Q_EXIT_SIG: { BSP_message("zero1-EXIT;"); status_ = Q_HANDLED(); break; } - /*${SMs::Calc::SM::on::operand1::zero1::DIGIT_0} */ + //${SMs::Calc::SM::on::operand1::zero1::DIGIT_0} case DIGIT_0_SIG: { ; status_ = Q_HANDLED(); break; } - /*${SMs::Calc::SM::on::operand1::zero1::DIGIT_1_9} */ + //${SMs::Calc::SM::on::operand1::zero1::DIGIT_1_9} case DIGIT_1_9_SIG: { BSP_insert(Q_EVT_CAST(CalcEvt)->key_code); status_ = Q_TRAN(&Calc_int1); break; } - /*${SMs::Calc::SM::on::operand1::zero1::POINT} */ + //${SMs::Calc::SM::on::operand1::zero1::POINT} case POINT_SIG: { BSP_insert((int)'0'); BSP_insert((int)'.'); @@ -484,30 +478,30 @@ static QState Calc_zero1(Calc * const me, QEvt const * const e) { return status_; } -/*${SMs::Calc::SM::on::operand1::int1} .....................................*/ +//${SMs::Calc::SM::on::operand1::int1} ....................................... static QState Calc_int1(Calc * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${SMs::Calc::SM::on::operand1::int1} */ + //${SMs::Calc::SM::on::operand1::int1} case Q_ENTRY_SIG: { BSP_message("int1-ENTRY;"); status_ = Q_HANDLED(); break; } - /*${SMs::Calc::SM::on::operand1::int1} */ + //${SMs::Calc::SM::on::operand1::int1} case Q_EXIT_SIG: { BSP_message("int1-EXIT;"); status_ = Q_HANDLED(); break; } - /*${SMs::Calc::SM::on::operand1::int1::POINT} */ + //${SMs::Calc::SM::on::operand1::int1::POINT} case POINT_SIG: { BSP_insert((int)'.'); status_ = Q_TRAN(&Calc_frac1); break; } - /*${SMs::Calc::SM::on::operand1::int1::DIGIT_0, DIGIT_1_9} */ - case DIGIT_0_SIG: /* intentionally fall through */ + //${SMs::Calc::SM::on::operand1::int1::DIGIT_0, DIGIT_1_9} + case DIGIT_0_SIG: // intentionally fall through case DIGIT_1_9_SIG: { BSP_insert(Q_EVT_CAST(CalcEvt)->key_code); status_ = Q_HANDLED(); @@ -521,30 +515,30 @@ static QState Calc_int1(Calc * const me, QEvt const * const e) { return status_; } -/*${SMs::Calc::SM::on::operand1::frac1} ....................................*/ +//${SMs::Calc::SM::on::operand1::frac1} ...................................... static QState Calc_frac1(Calc * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${SMs::Calc::SM::on::operand1::frac1} */ + //${SMs::Calc::SM::on::operand1::frac1} case Q_ENTRY_SIG: { BSP_message("frac1-ENTRY;"); status_ = Q_HANDLED(); break; } - /*${SMs::Calc::SM::on::operand1::frac1} */ + //${SMs::Calc::SM::on::operand1::frac1} case Q_EXIT_SIG: { BSP_message("frac1-EXIT;"); status_ = Q_HANDLED(); break; } - /*${SMs::Calc::SM::on::operand1::frac1::POINT} */ + //${SMs::Calc::SM::on::operand1::frac1::POINT} case POINT_SIG: { ; status_ = Q_HANDLED(); break; } - /*${SMs::Calc::SM::on::operand1::frac1::DIGIT_0, DIGIT_1_9} */ - case DIGIT_0_SIG: /* intentionally fall through */ + //${SMs::Calc::SM::on::operand1::frac1::DIGIT_0, DIGIT_1_9} + case DIGIT_0_SIG: // intentionally fall through case DIGIT_1_9_SIG: { BSP_insert(Q_EVT_CAST(CalcEvt)->key_code); status_ = Q_HANDLED(); @@ -558,49 +552,49 @@ static QState Calc_frac1(Calc * const me, QEvt const * const e) { return status_; } -/*${SMs::Calc::SM::on::operand1::negated1} .................................*/ +//${SMs::Calc::SM::on::operand1::negated1} ................................... static QState Calc_negated1(Calc * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${SMs::Calc::SM::on::operand1::negated1} */ + //${SMs::Calc::SM::on::operand1::negated1} case Q_ENTRY_SIG: { BSP_message("negated1-ENTRY;"); BSP_negate(); status_ = Q_HANDLED(); break; } - /*${SMs::Calc::SM::on::operand1::negated1} */ + //${SMs::Calc::SM::on::operand1::negated1} case Q_EXIT_SIG: { BSP_message("negated1-EXIT;"); status_ = Q_HANDLED(); break; } - /*${SMs::Calc::SM::on::operand1::negated1::DIGIT_0} */ + //${SMs::Calc::SM::on::operand1::negated1::DIGIT_0} case DIGIT_0_SIG: { BSP_insert(Q_EVT_CAST(CalcEvt)->key_code); status_ = Q_TRAN(&Calc_zero1); break; } - /*${SMs::Calc::SM::on::operand1::negated1::DIGIT_1_9} */ + //${SMs::Calc::SM::on::operand1::negated1::DIGIT_1_9} case DIGIT_1_9_SIG: { BSP_insert(Q_EVT_CAST(CalcEvt)->key_code); status_ = Q_TRAN(&Calc_int1); break; } - /*${SMs::Calc::SM::on::operand1::negated1::POINT} */ + //${SMs::Calc::SM::on::operand1::negated1::POINT} case POINT_SIG: { BSP_insert(Q_EVT_CAST(CalcEvt)->key_code); status_ = Q_TRAN(&Calc_frac1); break; } - /*${SMs::Calc::SM::on::operand1::negated1::OPER} */ + //${SMs::Calc::SM::on::operand1::negated1::OPER} case OPER_SIG: { - /*${SMs::Calc::SM::on::operand1::negated1::OPER::[e->key=='-']} */ + //${SMs::Calc::SM::on::operand1::negated1::OPER::[e->key=='-']} if (Q_EVT_CAST(CalcEvt)->key_code == KEY_MINUS) { ; status_ = Q_HANDLED(); } - /*${SMs::Calc::SM::on::operand1::negated1::OPER::[else]} */ + //${SMs::Calc::SM::on::operand1::negated1::OPER::[else]} else { status_ = Q_HANDLED(); } @@ -614,36 +608,36 @@ static QState Calc_negated1(Calc * const me, QEvt const * const e) { return status_; } -/*${SMs::Calc::SM::on::opEntered} ..........................................*/ +//${SMs::Calc::SM::on::opEntered} ............................................ static QState Calc_opEntered(Calc * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${SMs::Calc::SM::on::opEntered} */ + //${SMs::Calc::SM::on::opEntered} case Q_ENTRY_SIG: { BSP_message("opEntered-ENTRY;"); status_ = Q_HANDLED(); break; } - /*${SMs::Calc::SM::on::opEntered} */ + //${SMs::Calc::SM::on::opEntered} case Q_EXIT_SIG: { BSP_message("opEntered-EXIT;"); status_ = Q_HANDLED(); break; } - /*${SMs::Calc::SM::on::opEntered::DIGIT_0} */ + //${SMs::Calc::SM::on::opEntered::DIGIT_0} case DIGIT_0_SIG: { BSP_clear(); status_ = Q_TRAN(&Calc_zero2); break; } - /*${SMs::Calc::SM::on::opEntered::DIGIT_1_9} */ + //${SMs::Calc::SM::on::opEntered::DIGIT_1_9} case DIGIT_1_9_SIG: { BSP_clear(); BSP_insert(Q_EVT_CAST(CalcEvt)->key_code); status_ = Q_TRAN(&Calc_int2); break; } - /*${SMs::Calc::SM::on::opEntered::POINT} */ + //${SMs::Calc::SM::on::opEntered::POINT} case POINT_SIG: { BSP_clear(); BSP_insert((int)'0'); @@ -651,13 +645,13 @@ static QState Calc_opEntered(Calc * const me, QEvt const * const e) { status_ = Q_TRAN(&Calc_frac2); break; } - /*${SMs::Calc::SM::on::opEntered::OPER} */ + //${SMs::Calc::SM::on::opEntered::OPER} case OPER_SIG: { - /*${SMs::Calc::SM::on::opEntered::OPER::[e->key=='-']} */ + //${SMs::Calc::SM::on::opEntered::OPER::[e->key=='-']} if (Q_EVT_CAST(CalcEvt)->key_code == KEY_MINUS) { status_ = Q_TRAN(&Calc_negated2); } - /*${SMs::Calc::SM::on::opEntered::OPER::[else]} */ + //${SMs::Calc::SM::on::opEntered::OPER::[else]} else { status_ = Q_HANDLED(); } @@ -671,47 +665,47 @@ static QState Calc_opEntered(Calc * const me, QEvt const * const e) { return status_; } -/*${SMs::Calc::SM::on::operand2} ...........................................*/ +//${SMs::Calc::SM::on::operand2} ............................................. static QState Calc_operand2(Calc * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${SMs::Calc::SM::on::operand2} */ + //${SMs::Calc::SM::on::operand2} case Q_ENTRY_SIG: { BSP_message("operand2-ENTRY;"); status_ = Q_HANDLED(); break; } - /*${SMs::Calc::SM::on::operand2} */ + //${SMs::Calc::SM::on::operand2} case Q_EXIT_SIG: { BSP_message("operand2-EXIT;"); status_ = Q_HANDLED(); break; } - /*${SMs::Calc::SM::on::operand2::CE} */ + //${SMs::Calc::SM::on::operand2::CE} case CE_SIG: { BSP_clear(); status_ = Q_TRAN(&Calc_opEntered); break; } - /*${SMs::Calc::SM::on::operand2::EQUALS} */ + //${SMs::Calc::SM::on::operand2::EQUALS} case EQUALS_SIG: { - /*${SMs::Calc::SM::on::operand2::EQUALS::[Calc_eval(me,BSP_get_value(),KE~} */ + //${SMs::Calc::SM::on::operand2::EQUALS::[Calc_eval(me,BSP_get_value(),KE~} if (Calc_eval(me, BSP_get_value(), KEY_NULL)) { status_ = Q_TRAN(&Calc_result); } - /*${SMs::Calc::SM::on::operand2::EQUALS::[else]} */ + //${SMs::Calc::SM::on::operand2::EQUALS::[else]} else { status_ = Q_TRAN(&Calc_error); } break; } - /*${SMs::Calc::SM::on::operand2::OPER} */ + //${SMs::Calc::SM::on::operand2::OPER} case OPER_SIG: { - /*${SMs::Calc::SM::on::operand2::OPER::[Calc_eval(me,BSP_get_value(),Q_~} */ + //${SMs::Calc::SM::on::operand2::OPER::[Calc_eval(me,BSP_get_value(),Q_~} if (Calc_eval(me, BSP_get_value(), Q_EVT_CAST(CalcEvt)->key_code)) { status_ = Q_TRAN(&Calc_opEntered); } - /*${SMs::Calc::SM::on::operand2::OPER::[else]} */ + //${SMs::Calc::SM::on::operand2::OPER::[else]} else { status_ = Q_TRAN(&Calc_error); } @@ -725,35 +719,35 @@ static QState Calc_operand2(Calc * const me, QEvt const * const e) { return status_; } -/*${SMs::Calc::SM::on::operand2::zero2} ....................................*/ +//${SMs::Calc::SM::on::operand2::zero2} ...................................... static QState Calc_zero2(Calc * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${SMs::Calc::SM::on::operand2::zero2} */ + //${SMs::Calc::SM::on::operand2::zero2} case Q_ENTRY_SIG: { BSP_message("zero2-ENTRY;"); status_ = Q_HANDLED(); break; } - /*${SMs::Calc::SM::on::operand2::zero2} */ + //${SMs::Calc::SM::on::operand2::zero2} case Q_EXIT_SIG: { BSP_message("zero2-EXIT;"); status_ = Q_HANDLED(); break; } - /*${SMs::Calc::SM::on::operand2::zero2::DIGIT_0} */ + //${SMs::Calc::SM::on::operand2::zero2::DIGIT_0} case DIGIT_0_SIG: { ; status_ = Q_HANDLED(); break; } - /*${SMs::Calc::SM::on::operand2::zero2::DIGIT_1_9} */ + //${SMs::Calc::SM::on::operand2::zero2::DIGIT_1_9} case DIGIT_1_9_SIG: { BSP_insert(Q_EVT_CAST(CalcEvt)->key_code); status_ = Q_TRAN(&Calc_int2); break; } - /*${SMs::Calc::SM::on::operand2::zero2::POINT} */ + //${SMs::Calc::SM::on::operand2::zero2::POINT} case POINT_SIG: { BSP_insert((int)'0'); BSP_insert((int)'.'); @@ -768,30 +762,30 @@ static QState Calc_zero2(Calc * const me, QEvt const * const e) { return status_; } -/*${SMs::Calc::SM::on::operand2::int2} .....................................*/ +//${SMs::Calc::SM::on::operand2::int2} ....................................... static QState Calc_int2(Calc * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${SMs::Calc::SM::on::operand2::int2} */ + //${SMs::Calc::SM::on::operand2::int2} case Q_ENTRY_SIG: { BSP_message("int2-ENTRY;"); status_ = Q_HANDLED(); break; } - /*${SMs::Calc::SM::on::operand2::int2} */ + //${SMs::Calc::SM::on::operand2::int2} case Q_EXIT_SIG: { BSP_message("int2-EXIT;"); status_ = Q_HANDLED(); break; } - /*${SMs::Calc::SM::on::operand2::int2::POINT} */ + //${SMs::Calc::SM::on::operand2::int2::POINT} case POINT_SIG: { BSP_insert((int)'.'); status_ = Q_TRAN(&Calc_frac2); break; } - /*${SMs::Calc::SM::on::operand2::int2::DIGIT_0, DIGIT_1_9} */ - case DIGIT_0_SIG: /* intentionally fall through */ + //${SMs::Calc::SM::on::operand2::int2::DIGIT_0, DIGIT_1_9} + case DIGIT_0_SIG: // intentionally fall through case DIGIT_1_9_SIG: { BSP_insert(Q_EVT_CAST(CalcEvt)->key_code); status_ = Q_HANDLED(); @@ -805,30 +799,30 @@ static QState Calc_int2(Calc * const me, QEvt const * const e) { return status_; } -/*${SMs::Calc::SM::on::operand2::frac2} ....................................*/ +//${SMs::Calc::SM::on::operand2::frac2} ...................................... static QState Calc_frac2(Calc * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${SMs::Calc::SM::on::operand2::frac2} */ + //${SMs::Calc::SM::on::operand2::frac2} case Q_ENTRY_SIG: { BSP_message("frac2-ENTRY;"); status_ = Q_HANDLED(); break; } - /*${SMs::Calc::SM::on::operand2::frac2} */ + //${SMs::Calc::SM::on::operand2::frac2} case Q_EXIT_SIG: { BSP_message("frac2-EXIT;"); status_ = Q_HANDLED(); break; } - /*${SMs::Calc::SM::on::operand2::frac2::POINT} */ + //${SMs::Calc::SM::on::operand2::frac2::POINT} case POINT_SIG: { ; status_ = Q_HANDLED(); break; } - /*${SMs::Calc::SM::on::operand2::frac2::DIGIT_0, DIGIT_1_9} */ - case DIGIT_0_SIG: /* intentionally fall through */ + //${SMs::Calc::SM::on::operand2::frac2::DIGIT_0, DIGIT_1_9} + case DIGIT_0_SIG: // intentionally fall through case DIGIT_1_9_SIG: { BSP_insert(Q_EVT_CAST(CalcEvt)->key_code); status_ = Q_HANDLED(); @@ -842,49 +836,49 @@ static QState Calc_frac2(Calc * const me, QEvt const * const e) { return status_; } -/*${SMs::Calc::SM::on::operand2::negated2} .................................*/ +//${SMs::Calc::SM::on::operand2::negated2} ................................... static QState Calc_negated2(Calc * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${SMs::Calc::SM::on::operand2::negated2} */ + //${SMs::Calc::SM::on::operand2::negated2} case Q_ENTRY_SIG: { BSP_message("negated2-ENTRY;"); BSP_negate(); status_ = Q_HANDLED(); break; } - /*${SMs::Calc::SM::on::operand2::negated2} */ + //${SMs::Calc::SM::on::operand2::negated2} case Q_EXIT_SIG: { BSP_message("negated2-EXIT;"); status_ = Q_HANDLED(); break; } - /*${SMs::Calc::SM::on::operand2::negated2::DIGIT_0} */ + //${SMs::Calc::SM::on::operand2::negated2::DIGIT_0} case DIGIT_0_SIG: { BSP_insert(Q_EVT_CAST(CalcEvt)->key_code); status_ = Q_TRAN(&Calc_zero2); break; } - /*${SMs::Calc::SM::on::operand2::negated2::DIGIT_1_9} */ + //${SMs::Calc::SM::on::operand2::negated2::DIGIT_1_9} case DIGIT_1_9_SIG: { BSP_insert(Q_EVT_CAST(CalcEvt)->key_code); status_ = Q_TRAN(&Calc_int2); break; } - /*${SMs::Calc::SM::on::operand2::negated2::POINT} */ + //${SMs::Calc::SM::on::operand2::negated2::POINT} case POINT_SIG: { BSP_insert(Q_EVT_CAST(CalcEvt)->key_code); status_ = Q_TRAN(&Calc_frac2); break; } - /*${SMs::Calc::SM::on::operand2::negated2::OPER} */ + //${SMs::Calc::SM::on::operand2::negated2::OPER} case OPER_SIG: { - /*${SMs::Calc::SM::on::operand2::negated2::OPER::[e->key=='-']} */ + //${SMs::Calc::SM::on::operand2::negated2::OPER::[e->key=='-']} if (Q_EVT_CAST(CalcEvt)->key_code == KEY_MINUS) { ; status_ = Q_HANDLED(); } - /*${SMs::Calc::SM::on::operand2::negated2::OPER::[else]} */ + //${SMs::Calc::SM::on::operand2::negated2::OPER::[else]} else { status_ = Q_HANDLED(); } @@ -898,11 +892,11 @@ static QState Calc_negated2(Calc * const me, QEvt const * const e) { return status_; } -/*${SMs::Calc::SM::final} ..................................................*/ +//${SMs::Calc::SM::final} .................................................... static QState Calc_final(Calc * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${SMs::Calc::SM::final} */ + //${SMs::Calc::SM::final} case Q_ENTRY_SIG: { BSP_message("final-ENTRY;"); BSP_exit(); @@ -916,4 +910,4 @@ static QState Calc_final(Calc * const me, QEvt const * const e) { } return status_; } -/*$enddef${SMs::Calc} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$enddef${SMs::Calc} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/examples/posix-win32/calc/calc.h b/examples/posix-win32/calc/calc.h new file mode 100644 index 00000000..77c8e7c1 --- /dev/null +++ b/examples/posix-win32/calc/calc.h @@ -0,0 +1,64 @@ +//$file${.::calc.h} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// +// Model: calc.qm +// File: ${.::calc.h} +// +// This code has been generated by QM 5.3.0 . +// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. +// +// SPDX-License-Identifier: GPL-3.0-or-later +// +// This generated code is open source software: you can redistribute it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation. +// +// This code is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// NOTE: +// Alternatively, this generated code may be distributed under the terms +// of Quantum Leaps commercial licenses, which expressly supersede the GNU +// General Public License and are specifically designed for licensees +// interested in retaining the proprietary status of their code. +// +// Contact information: +// +// +// +//$endhead${.::calc.h} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +#ifndef CALC_H_ +#define CALC_H_ + +enum CalcSignals { + C_SIG = Q_USER_SIG, + CE_SIG, + DIGIT_0_SIG, + DIGIT_1_9_SIG, + POINT_SIG, + OPER_SIG, + EQUALS_SIG, + OFF_SIG +}; + +//$declare${Events::CalcEvt} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${Events::CalcEvt} ......................................................... +typedef struct { +// protected: + QEvt super; + +// public: + uint8_t key_code; +} CalcEvt; +//$enddecl${Events::CalcEvt} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +//$declare${SMs::Calc_ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${SMs::Calc_ctor} .......................................................... +void Calc_ctor(void); +//$enddecl${SMs::Calc_ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +extern QHsm * const the_calc; // "opaque" pointer to calculator HSM + +#endif // CALC1_H_ diff --git a/examples/workstation/calc1/calc1.qm b/examples/posix-win32/calc/calc.qm similarity index 95% rename from examples/workstation/calc1/calc1.qm rename to examples/posix-win32/calc/calc.qm index e307fb9d..6f26a07b 100644 --- a/examples/workstation/calc1/calc1.qm +++ b/examples/posix-win32/calc/calc.qm @@ -1,5 +1,5 @@ - + Improved model of the Calculator described in Chapter 4 of PSiCC2. Improvements include: - placing the "negated1" state inside "operand1" superstate - placing the "negated2" state inside "operand2" superstate @@ -33,11 +33,11 @@ - /* guard function to evaluate the current expression + // guard function to evaluate the current expression * taking into account the precedence of operands. * return: true if evaluation successfull * false when error encountered -*/ + @@ -51,13 +51,13 @@ if ((oper == KEY_NULL) || (oper == KEY_PLUS) || (oper == KEY_MINUS)) { } case KEY_DIVIDE: { if ((-1e-30 < op) && (op < 1e-30)) { - BSP_display_error(" Error 0 "); /* divide by zero */ + BSP_display_error(" Error 0 "); // divide by zero return false; } me->op2 /= op; break; } - default: { /* no op2 yet */ + default: { // no op2 yet me->op2 = op; me->oper2 = oper; break; @@ -78,7 +78,7 @@ if ((oper == KEY_NULL) || (oper == KEY_PLUS) || (oper == KEY_MINUS)) { } case KEY_DIVIDE: { if ((-1e-30 < me->op2) && (me->op2 < 1e-30)) { - BSP_display_error(" Error 0 "); /* divide by zero */ + BSP_display_error(" Error 0 "); // divide by zero return false; } me->op1 /= me->op2; @@ -93,7 +93,7 @@ if ((oper == KEY_NULL) || (oper == KEY_PLUS) || (oper == KEY_MINUS)) { me->oper2 = KEY_NULL; result = me->op1; } -else { /* (oper == KEY_MULT) || (oper == KEY_DIV) */ +else { // (oper == KEY_MULT) || (oper == KEY_DIV) switch (me->oper2) { case KEY_MULT: { me->op2 *= op; @@ -101,13 +101,13 @@ else { /* (oper == KEY_MULT) || (oper == KEY_DIV) */ } case KEY_DIVIDE: { if ((-1e-30 < op) && (op < 1e-30)) { - BSP_display_error(" Error 0 "); /* divide by zero */ + BSP_display_error(" Error 0 "); // divide by zero return false; } me->op2 /= op; break; } - default: { /* oper2 not provided yet */ + default: { // oper2 not provided yet me->op2 = op; break; } @@ -117,7 +117,7 @@ else { /* (oper == KEY_MULT) || (oper == KEY_DIV) */ } if ((result < -99999999.0) || (99999999.0 < result)) { - BSP_display_error(" Error 1 "); /* out of range */ + BSP_display_error(" Error 1 "); // out of range return false; } if ((-0.0000001 < result) && (result < 0.0000001)) { @@ -131,7 +131,7 @@ return true; - (void)par; /* unused parameter */ + (void)par; // unused parameter @@ -162,9 +162,9 @@ BSP_clear(); - /* Error state after evaluation of an expression. + // Error state after evaluation of an expression. This state can be exited only throgh the inherited C (Clear) event. -*/ + BSP_message("error-ENTRY;"); BSP_message("error-EXIT;"); @@ -686,10 +686,10 @@ QHsm_ctor(&me->super, Q_STATE_CAST(&Calc_initial)); - - - #ifndef CALC1_H -#define CALC1_H + + + #ifndef CALC_H_ +#define CALC_H_ enum CalcSignals { C_SIG = Q_USER_SIG, @@ -705,16 +705,15 @@ enum CalcSignals { $declare${Events::CalcEvt} $declare${SMs::Calc_ctor} -extern QHsm * const the_calc; /* "opaque" pointer to calculator HSM */ +extern QHsm * const the_calc; // "opaque" pointer to calculator HSM -#endif /* CALC1_H */ - +#endif // CALC1_H_ - - - #include "qpc.h" /* QP/C */ -#include "bsp.h" /* board support package */ -#include "calc1.h" /* application */ + + + #include "qpc.h" // QP/C +#include "bsp.h" // board support package +#include "calc.h" // application Q_DEFINE_THIS_FILE diff --git a/examples/posix-win32/calc/main.c b/examples/posix-win32/calc/main.c new file mode 100644 index 00000000..1f278f15 --- /dev/null +++ b/examples/posix-win32/calc/main.c @@ -0,0 +1,134 @@ +//============================================================================ +// Product: calc1_sub Example +// Last updated for version 7.3.0 +// Last updated on 2023-07-27 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// This program is open source software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Alternatively, this program may be distributed and modified under the +// terms of Quantum Leaps commercial licenses, which expressly supersede +// the GNU General Public License and are specifically designed for +// licensees interested in retaining the proprietary status of their code. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Contact information: +// +// +//============================================================================ +#include "qpc.h" +#include "bsp.h" +#include "calc.h" + +#include "safe_std.h" // portable "safe" / facilities + +Q_DEFINE_THIS_FILE + +//............................................................................ +int main() { + + QF_init(); + QF_onStartup(); + + PRINTF_S("Calculator example, QP version: %s\n" + "Press '0' .. '9' to enter a digit\n" + "Press '.' to enter the decimal point\n" + "Press '+' to add\n" + "Press '-' to subtract or negate a number\n" + "Press '*' to multiply\n" + "Press '/' to divide\n" + "Press '=' or to get the result\n" + "Press 'c' or 'C' to Cancel\n" + "Press 'e' or 'E' to Cancel Entry\n" + "Press to quit.\n\n", + QP_VERSION_STR); + + Calc_ctor(); // explicitly instantiate the calculator object + QASM_INIT(the_calc, (void *)0, 0U); // trigger initial transition + + for (;;) { // event loop + CalcEvt e = { QEVT_INITIALIZER(0U), 0U}; // Calculator event + + BSP_show_display(); // show the display + + PRINTF_S("%s"," : "); + fflush(stdout); + e.key_code = (uint8_t)QF_consoleWaitForKey(); + PRINTF_S("%c ", (e.key_code >= ' ') ? e.key_code : 'X'); + + switch (e.key_code) { + case 'c': // intentionally fall through + case 'C': { + e.super.sig = C_SIG; + break; + } + case 'e': // intentionally fall through + case 'E': { + e.super.sig = CE_SIG; + break; + } + case '0': { + e.super.sig = DIGIT_0_SIG; + break; + } + case '1': // intentionally fall through + case '2': // intentionally fall through + case '3': // intentionally fall through + case '4': // intentionally fall through + case '5': // intentionally fall through + case '6': // intentionally fall through + case '7': // intentionally fall through + case '8': // intentionally fall through + case '9': { + e.super.sig = DIGIT_1_9_SIG; + break; + } + case '.': { + e.super.sig = POINT_SIG; + break; + } + case '+': // intentionally fall through + case '-': // intentionally fall through + case '*': // intentionally fall through + case '/': { + e.super.sig = OPER_SIG; + break; + } + case '=': // intentionally fall through + case '\r': { // Enter key + e.super.sig = EQUALS_SIG; + break; + } + case '\33': { // ESC key + e.super.sig = OFF_SIG; + break; + } + default: { + e.super.sig = 0; // invalid event + break; + } + } + + if (e.super.sig != 0) { // valid event generated? + QASM_DISPATCH(the_calc, &e.super, 0U); // dispatch event + } + } + + QF_onCleanup(); + return 0; +} diff --git a/examples/workstation/calc2/Makefile b/examples/posix-win32/calc2/Makefile similarity index 99% rename from examples/workstation/calc2/Makefile rename to examples/posix-win32/calc2/Makefile index da15efa8..f8b7de9e 100644 --- a/examples/workstation/calc2/Makefile +++ b/examples/posix-win32/calc2/Makefile @@ -245,7 +245,7 @@ CPP_DEPS_EXT := $(patsubst %.o,%.d, $(CPP_OBJS_EXT)) all: $(TARGET_EXE) $(TARGET_EXE) : $(C_OBJS_EXT) $(CPP_OBJS_EXT) - $(CC) $(CFLAGS) $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o + $(CC) $(CFLAGS) $(QPC)/src/qs/qstamp.c -o $(BIN_DIR)/qstamp.o $(LINK) $(LINKFLAGS) $(LIB_DIRS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) $(BIN_DIR)/%.d : %.c diff --git a/examples/posix-win32/calc2/bsp.c b/examples/posix-win32/calc2/bsp.c new file mode 100644 index 00000000..cfe452ba --- /dev/null +++ b/examples/posix-win32/calc2/bsp.c @@ -0,0 +1,125 @@ +//============================================================================ +// Product: Board Support Package (BSP) for the Calculator example +// Last updated for version 6.9.0 +// Last updated on 2020-06-24 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// This program is open source software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Alternatively, this program may be distributed and modified under the +// terms of Quantum Leaps commercial licenses, which expressly supersede +// the GNU General Public License and are specifically designed for +// licensees interested in retaining the proprietary status of their code. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Contact information: +// +// +//============================================================================ +#include "qpc.h" +#include "bsp.h" + +#include "safe_std.h" // portable "safe" / facilities +#include // for exit() + +#define DISP_WIDTH 15 + +// helper macros to "stringify" values +#define VAL(x) #x +#define STRINGIFY(x) VAL(x) + +static char l_display[DISP_WIDTH + 1]; // the calculator display +static int l_len; // number of displayed characters + +//............................................................................ +void BSP_clear(void) { + memset(l_display, ' ', DISP_WIDTH - 1); + l_display[DISP_WIDTH - 1] = '0'; + l_display[DISP_WIDTH] = '\0'; + l_len = 0; +} +//............................................................................ +void BSP_insert(int keyId) { + if (l_len == 0) { + l_display[DISP_WIDTH - 1] = (char)keyId; + ++l_len; + } + else if (l_len < (DISP_WIDTH - 1)) { + MEMMOVE_S(&l_display[0], DISP_WIDTH, &l_display[1], DISP_WIDTH - 1); + l_display[DISP_WIDTH - 1] = (char)keyId; + ++l_len; + } +} +//............................................................................ +void BSP_display(double value) { + SNPRINTF_S(l_display, Q_DIM(l_display), + "%" STRINGIFY(DISP_WIDTH) ".6g", value); +} +//............................................................................ +void BSP_display_error(char const *err) { + STRNCPY_S(l_display, DISP_WIDTH, err); +} +//............................................................................ +void BSP_negate(void) { + BSP_clear(); + l_display[DISP_WIDTH - 2] = '-'; +} +//............................................................................ +void BSP_show_display(void) { + PRINTF_S("\n[%" STRINGIFY(DISP_WIDTH) "s] ", l_display); +} +//............................................................................ +void BSP_exit(void) { + PRINTF_S("\n%s\n", "Bye! Bye!"); + fflush(stdout); + QF_onCleanup(); + exit(0); +} +//............................................................................ +double BSP_get_value(void) { + return strtod(l_display, (char **)0); +} +//............................................................................ +void BSP_message(char const *msg) { + PRINTF_S("%s", msg); +} + +//............................................................................ +void QF_onStartup(void) { + QF_consoleSetup(); +} +//............................................................................ +void QF_onCleanup(void) { + QF_consoleCleanup(); +} +//............................................................................ +void QF_onClockTick(void) { +} + +//............................................................................ +// this function is used by the QP embedded systems-friendly assertions +Q_NORETURN Q_onError(char const * const module, int_t const id) { + FPRINTF_S(stderr, "ERROR in %s:%d", module, id); + QF_onCleanup(); + exit(-1); +} +//............................................................................ +void assert_failed(char const * const module, int_t const id); // prototype +void assert_failed(char const * const module, int_t const id) { + Q_onError(module, id); +} diff --git a/examples/posix-win32/calc2/bsp.h b/examples/posix-win32/calc2/bsp.h new file mode 100644 index 00000000..1e5c7148 --- /dev/null +++ b/examples/posix-win32/calc2/bsp.h @@ -0,0 +1,48 @@ +//============================================================================ +// Product: Board Support Package (BSP) for the Calculator example +// Last updated for version 6.5.0 +// Last updated on 2019-03-20 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// This program is open source software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Alternatively, this program may be distributed and modified under the +// terms of Quantum Leaps commercial licenses, which expressly supersede +// the GNU General Public License and are specifically designed for +// licensees interested in retaining the proprietary status of their code. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Contact information: +// +// +//============================================================================ +#ifndef BSP_H_ +#define BSP_H_ + +void BSP_clear(void); +void BSP_negate(void); +void BSP_insert(int keyId); +double BSP_get_value(void); +void BSP_display(double value); +void BSP_display_error(char const *err); +void BSP_exit(void); + +void BSP_show_display(void); +void BSP_message(char const *msg); + +#endif // BSP_H_ diff --git a/examples/workstation/calc2/calc2.c b/examples/posix-win32/calc2/calc2.c similarity index 63% rename from examples/workstation/calc2/calc2.c rename to examples/posix-win32/calc2/calc2.c index 5a81d4ec..6cd3e41d 100644 --- a/examples/workstation/calc2/calc2.c +++ b/examples/posix-win32/calc2/calc2.c @@ -1,36 +1,36 @@ -/*$file${.::calc2.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* -* Model: calc2.qm -* File: ${.::calc2.c} -* -* This code has been generated by QM 5.2.4 . -* DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. -* -* SPDX-License-Identifier: GPL-3.0-or-later -* -* This generated code is open source software: you can redistribute it under -* the terms of the GNU General Public License as published by the Free -* Software Foundation. -* -* This code is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -* more details. -* -* NOTE: -* Alternatively, this generated code may be distributed under the terms -* of Quantum Leaps commercial licenses, which expressly supersede the GNU -* General Public License and are specifically designed for licensees -* interested in retaining the proprietary status of their code. -* -* Contact information: -* -* -*/ -/*$endhead${.::calc2.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -#include "qpc.h" /* QP/C */ -#include "bsp.h" /* board support package */ -#include "calc2.h" /* application */ +//$file${.::calc2.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// +// Model: calc2.qm +// File: ${.::calc2.c} +// +// This code has been generated by QM 5.3.0 . +// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. +// +// SPDX-License-Identifier: GPL-3.0-or-later +// +// This generated code is open source software: you can redistribute it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation. +// +// This code is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// NOTE: +// Alternatively, this generated code may be distributed under the terms +// of Quantum Leaps commercial licenses, which expressly supersede the GNU +// General Public License and are specifically designed for licensees +// interested in retaining the proprietary status of their code. +// +// Contact information: +// +// +// +//$endhead${.::calc2.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +#include "qpc.h" // QP/C +#include "bsp.h" // board support package +#include "calc2.h" // application Q_DEFINE_THIS_FILE @@ -40,40 +40,34 @@ Q_DEFINE_THIS_FILE #define KEY_MULT '*' #define KEY_DIVIDE '/' -/*$declare${SMs::Calc} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//$declare${SMs::Calc} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/*${SMs::Calc} .............................................................*/ +//${SMs::Calc} ............................................................... typedef struct Calc { -/* protected: */ +// protected: QHsm super; -/* public: */ +// public: -/* private: */ +// private: double op1; double op2; uint8_t oper1; uint8_t oper2; } Calc; -/* private: */ +// private: -/* guard function to evaluate the current expression -* taking into account the precedence of operands. -* return: true if evaluation successfull -* false when error encountered -*/ +// guard function to evaluate the current expression static bool Calc_eval(Calc * const me, double op, uint8_t oper); extern Calc Calc_inst; -/* protected: */ +// protected: static QState Calc_initial(Calc * const me, void const * const par); static QState Calc_on(Calc * const me, QEvt const * const e); -/* Error state after evaluation of an expression. -This state can be exited only throgh the inherited C (Clear) event. -*/ +// Error state after evaluation of an expression. static QState Calc_error(Calc * const me, QEvt const * const e); static QState Calc_ready(Calc * const me, QEvt const * const e); static QState Calc_result(Calc * const me, QEvt const * const e); @@ -85,40 +79,40 @@ static QState Calc_frac1(Calc * const me, QEvt const * const e); static QState Calc_negated1(Calc * const me, QEvt const * const e); static QState Calc_opEntered(Calc * const me, QEvt const * const e); static QState Calc_final(Calc * const me, QEvt const * const e); -/*$enddecl${SMs::Calc} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$enddecl${SMs::Calc} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -/*$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* Check for the minimum required QP version */ -#if (QP_VERSION < 700U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) -#error qpc version 7.0.0 or higher required +//$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// Check for the minimum required QP version +#if (QP_VERSION < 730U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) +#error qpc version 7.3.0 or higher required #endif -/*$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -/*$define${SMs::the_calc} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//$define${SMs::the_calc} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/*${SMs::the_calc} .........................................................*/ +//${SMs::the_calc} ........................................................... QHsm * const the_calc = &Calc_inst.super; -/*$enddef${SMs::the_calc} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*$define${SMs::Calc_ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//$enddef${SMs::the_calc} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +//$define${SMs::Calc_ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/*${SMs::Calc_ctor} ........................................................*/ +//${SMs::Calc_ctor} .......................................................... void Calc_ctor(void) { Calc *me = &Calc_inst; QHsm_ctor(&me->super, Q_STATE_CAST(&Calc_initial)); } -/*$enddef${SMs::Calc_ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*$define${SMs::Calc} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//$enddef${SMs::Calc_ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +//$define${SMs::Calc} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/*${SMs::Calc} .............................................................*/ +//${SMs::Calc} ............................................................... Calc Calc_inst; -/*${SMs::Calc::eval} .......................................................*/ +//${SMs::Calc::eval} ......................................................... static bool Calc_eval(Calc * const me, double op, uint8_t oper) { double result; - if (me->oper1 == KEY_NULL) { /* no op1 yet */ + if (me->oper1 == KEY_NULL) { // no op1 yet me->op1 = op; me->oper1 = oper; result = me->op1; @@ -131,13 +125,13 @@ static bool Calc_eval(Calc * const me, } case KEY_DIVIDE: { if ((-1e-30 < op) && (op < 1e-30)) { - BSP_display_error(" Error 0 "); /* divide by zero */ + BSP_display_error(" Error 0 "); // divide by zero return false; } me->op2 /= op; break; } - default: { /* no op2 yet */ + default: { // no op2 yet me->op2 = op; me->oper2 = oper; break; @@ -158,7 +152,7 @@ static bool Calc_eval(Calc * const me, } case KEY_DIVIDE: { if ((-1e-30 < me->op2) && (me->op2 < 1e-30)) { - BSP_display_error(" Error 0 "); /* divide by zero */ + BSP_display_error(" Error 0 "); // divide by zero return false; } me->op1 /= me->op2; @@ -173,7 +167,7 @@ static bool Calc_eval(Calc * const me, me->oper2 = KEY_NULL; result = me->op1; } - else { /* (oper == KEY_MULT) || (oper == KEY_DIV) */ + else { // (oper == KEY_MULT) || (oper == KEY_DIV) switch (me->oper2) { case KEY_MULT: { me->op2 *= op; @@ -181,13 +175,13 @@ static bool Calc_eval(Calc * const me, } case KEY_DIVIDE: { if ((-1e-30 < op) && (op < 1e-30)) { - BSP_display_error(" Error 0 "); /* divide by zero */ + BSP_display_error(" Error 0 "); // divide by zero return false; } me->op2 /= op; break; } - default: { /* oper2 not provided yet */ + default: { // oper2 not provided yet me->op2 = op; break; } @@ -197,7 +191,7 @@ static bool Calc_eval(Calc * const me, } if ((result < -99999999.0) || (99999999.0 < result)) { - BSP_display_error(" Error 1 "); /* out of range */ + BSP_display_error(" Error 1 "); // out of range return false; } if ((-0.0000001 < result) && (result < 0.0000001)) { @@ -208,42 +202,42 @@ static bool Calc_eval(Calc * const me, return true; } -/*${SMs::Calc::SM} .........................................................*/ +//${SMs::Calc::SM} ........................................................... static QState Calc_initial(Calc * const me, void const * const par) { - /*${SMs::Calc::SM::initial} */ - (void)par; /* unused parameter */ + //${SMs::Calc::SM::initial} + (void)par; // unused parameter return Q_TRAN(&Calc_on); } -/*${SMs::Calc::SM::on} .....................................................*/ +//${SMs::Calc::SM::on} ....................................................... static QState Calc_on(Calc * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${SMs::Calc::SM::on} */ + //${SMs::Calc::SM::on} case Q_ENTRY_SIG: { BSP_message("on-ENTRY;"); status_ = Q_HANDLED(); break; } - /*${SMs::Calc::SM::on} */ + //${SMs::Calc::SM::on} case Q_EXIT_SIG: { BSP_message("on-EXIT;"); status_ = Q_HANDLED(); break; } - /*${SMs::Calc::SM::on::initial} */ + //${SMs::Calc::SM::on::initial} case Q_INIT_SIG: { BSP_message("on-INIT;"); BSP_clear(); status_ = Q_TRAN(&Calc_ready); break; } - /*${SMs::Calc::SM::on::C} */ + //${SMs::Calc::SM::on::C} case C_SIG: { status_ = Q_TRAN(&Calc_on); break; } - /*${SMs::Calc::SM::on::OFF} */ + //${SMs::Calc::SM::on::OFF} case OFF_SIG: { status_ = Q_TRAN(&Calc_final); break; @@ -256,17 +250,17 @@ static QState Calc_on(Calc * const me, QEvt const * const e) { return status_; } -/*${SMs::Calc::SM::on::error} ..............................................*/ +//${SMs::Calc::SM::on::error} ................................................ static QState Calc_error(Calc * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${SMs::Calc::SM::on::error} */ + //${SMs::Calc::SM::on::error} case Q_ENTRY_SIG: { BSP_message("error-ENTRY;"); status_ = Q_HANDLED(); break; } - /*${SMs::Calc::SM::on::error} */ + //${SMs::Calc::SM::on::error} case Q_EXIT_SIG: { BSP_message("error-EXIT;"); status_ = Q_HANDLED(); @@ -280,11 +274,11 @@ static QState Calc_error(Calc * const me, QEvt const * const e) { return status_; } -/*${SMs::Calc::SM::on::ready} ..............................................*/ +//${SMs::Calc::SM::on::ready} ................................................ static QState Calc_ready(Calc * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${SMs::Calc::SM::on::ready} */ + //${SMs::Calc::SM::on::ready} case Q_ENTRY_SIG: { BSP_message("ready-ENTRY;"); me->oper1 = KEY_NULL; @@ -292,32 +286,32 @@ static QState Calc_ready(Calc * const me, QEvt const * const e) { status_ = Q_HANDLED(); break; } - /*${SMs::Calc::SM::on::ready} */ + //${SMs::Calc::SM::on::ready} case Q_EXIT_SIG: { BSP_message("ready-EXIT;"); status_ = Q_HANDLED(); break; } - /*${SMs::Calc::SM::on::ready::initial} */ + //${SMs::Calc::SM::on::ready::initial} case Q_INIT_SIG: { BSP_message("ready-INIT;"); status_ = Q_TRAN(&Calc_begin); break; } - /*${SMs::Calc::SM::on::ready::DIGIT_0} */ + //${SMs::Calc::SM::on::ready::DIGIT_0} case DIGIT_0_SIG: { BSP_clear(); status_ = Q_TRAN(&Calc_zero1); break; } - /*${SMs::Calc::SM::on::ready::DIGIT_1_9} */ + //${SMs::Calc::SM::on::ready::DIGIT_1_9} case DIGIT_1_9_SIG: { BSP_clear(); BSP_insert(Q_EVT_CAST(CalcEvt)->key_code); status_ = Q_TRAN(&Calc_int1); break; } - /*${SMs::Calc::SM::on::ready::POINT} */ + //${SMs::Calc::SM::on::ready::POINT} case POINT_SIG: { BSP_clear(); BSP_insert((int)'0'); @@ -325,7 +319,7 @@ static QState Calc_ready(Calc * const me, QEvt const * const e) { status_ = Q_TRAN(&Calc_frac1); break; } - /*${SMs::Calc::SM::on::ready::OPER} */ + //${SMs::Calc::SM::on::ready::OPER} case OPER_SIG: { me->op1 = BSP_get_value(); me->oper1 = Q_EVT_CAST(CalcEvt)->key_code; @@ -340,17 +334,17 @@ static QState Calc_ready(Calc * const me, QEvt const * const e) { return status_; } -/*${SMs::Calc::SM::on::ready::result} ......................................*/ +//${SMs::Calc::SM::on::ready::result} ........................................ static QState Calc_result(Calc * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${SMs::Calc::SM::on::ready::result} */ + //${SMs::Calc::SM::on::ready::result} case Q_ENTRY_SIG: { BSP_message("result-ENTRY;"); status_ = Q_HANDLED(); break; } - /*${SMs::Calc::SM::on::ready::result} */ + //${SMs::Calc::SM::on::ready::result} case Q_EXIT_SIG: { BSP_message("result-EXIT;"); status_ = Q_HANDLED(); @@ -364,29 +358,29 @@ static QState Calc_result(Calc * const me, QEvt const * const e) { return status_; } -/*${SMs::Calc::SM::on::ready::begin} .......................................*/ +//${SMs::Calc::SM::on::ready::begin} ......................................... static QState Calc_begin(Calc * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${SMs::Calc::SM::on::ready::begin} */ + //${SMs::Calc::SM::on::ready::begin} case Q_ENTRY_SIG: { BSP_message("begin-ENTRY;"); status_ = Q_HANDLED(); break; } - /*${SMs::Calc::SM::on::ready::begin} */ + //${SMs::Calc::SM::on::ready::begin} case Q_EXIT_SIG: { BSP_message("begin-EXIT;"); status_ = Q_HANDLED(); break; } - /*${SMs::Calc::SM::on::ready::begin::OPER} */ + //${SMs::Calc::SM::on::ready::begin::OPER} case OPER_SIG: { - /*${SMs::Calc::SM::on::ready::begin::OPER::[e->key=='-']} */ + //${SMs::Calc::SM::on::ready::begin::OPER::[e->key=='-']} if (Q_EVT_CAST(CalcEvt)->key_code == KEY_MINUS) { status_ = Q_TRAN(&Calc_negated1); } - /*${SMs::Calc::SM::on::ready::begin::OPER::[else]} */ + //${SMs::Calc::SM::on::ready::begin::OPER::[else]} else { status_ = Q_HANDLED(); } @@ -400,47 +394,47 @@ static QState Calc_begin(Calc * const me, QEvt const * const e) { return status_; } -/*${SMs::Calc::SM::on::operand} ............................................*/ +//${SMs::Calc::SM::on::operand} .............................................. static QState Calc_operand(Calc * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${SMs::Calc::SM::on::operand} */ + //${SMs::Calc::SM::on::operand} case Q_ENTRY_SIG: { BSP_message("operand1-ENTRY;"); status_ = Q_HANDLED(); break; } - /*${SMs::Calc::SM::on::operand} */ + //${SMs::Calc::SM::on::operand} case Q_EXIT_SIG: { BSP_message("operand1-EXIT;"); status_ = Q_HANDLED(); break; } - /*${SMs::Calc::SM::on::operand::CE} */ + //${SMs::Calc::SM::on::operand::CE} case CE_SIG: { BSP_clear(); status_ = Q_TRAN(&Calc_ready); break; } - /*${SMs::Calc::SM::on::operand::EQUALS} */ + //${SMs::Calc::SM::on::operand::EQUALS} case EQUALS_SIG: { - /*${SMs::Calc::SM::on::operand::EQUALS::[Calc_eval(me,BSP_get_value(),KE~} */ + //${SMs::Calc::SM::on::operand::EQUALS::[Calc_eval(me,BSP_get_value(),KE~} if (Calc_eval(me, BSP_get_value(), KEY_NULL)) { status_ = Q_TRAN(&Calc_result); } - /*${SMs::Calc::SM::on::operand::EQUALS::[else]} */ + //${SMs::Calc::SM::on::operand::EQUALS::[else]} else { status_ = Q_TRAN(&Calc_error); } break; } - /*${SMs::Calc::SM::on::operand::OPER} */ + //${SMs::Calc::SM::on::operand::OPER} case OPER_SIG: { - /*${SMs::Calc::SM::on::operand::OPER::[Calc_eval(me,BSP_get_value(),Q_~} */ + //${SMs::Calc::SM::on::operand::OPER::[Calc_eval(me,BSP_get_value(),Q_~} if (Calc_eval(me, BSP_get_value(), Q_EVT_CAST(CalcEvt)->key_code)) { status_ = Q_TRAN(&Calc_opEntered); } - /*${SMs::Calc::SM::on::operand::OPER::[else]} */ + //${SMs::Calc::SM::on::operand::OPER::[else]} else { status_ = Q_TRAN(&Calc_error); } @@ -454,35 +448,35 @@ static QState Calc_operand(Calc * const me, QEvt const * const e) { return status_; } -/*${SMs::Calc::SM::on::operand::zero1} .....................................*/ +//${SMs::Calc::SM::on::operand::zero1} ....................................... static QState Calc_zero1(Calc * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${SMs::Calc::SM::on::operand::zero1} */ + //${SMs::Calc::SM::on::operand::zero1} case Q_ENTRY_SIG: { BSP_message("zero1-ENTRY;"); status_ = Q_HANDLED(); break; } - /*${SMs::Calc::SM::on::operand::zero1} */ + //${SMs::Calc::SM::on::operand::zero1} case Q_EXIT_SIG: { BSP_message("zero1-EXIT;"); status_ = Q_HANDLED(); break; } - /*${SMs::Calc::SM::on::operand::zero1::DIGIT_0} */ + //${SMs::Calc::SM::on::operand::zero1::DIGIT_0} case DIGIT_0_SIG: { ; status_ = Q_HANDLED(); break; } - /*${SMs::Calc::SM::on::operand::zero1::DIGIT_1_9} */ + //${SMs::Calc::SM::on::operand::zero1::DIGIT_1_9} case DIGIT_1_9_SIG: { BSP_insert(Q_EVT_CAST(CalcEvt)->key_code); status_ = Q_TRAN(&Calc_int1); break; } - /*${SMs::Calc::SM::on::operand::zero1::POINT} */ + //${SMs::Calc::SM::on::operand::zero1::POINT} case POINT_SIG: { BSP_insert((int)'0'); BSP_insert((int)'.'); @@ -497,30 +491,30 @@ static QState Calc_zero1(Calc * const me, QEvt const * const e) { return status_; } -/*${SMs::Calc::SM::on::operand::int1} ......................................*/ +//${SMs::Calc::SM::on::operand::int1} ........................................ static QState Calc_int1(Calc * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${SMs::Calc::SM::on::operand::int1} */ + //${SMs::Calc::SM::on::operand::int1} case Q_ENTRY_SIG: { BSP_message("int1-ENTRY;"); status_ = Q_HANDLED(); break; } - /*${SMs::Calc::SM::on::operand::int1} */ + //${SMs::Calc::SM::on::operand::int1} case Q_EXIT_SIG: { BSP_message("int1-EXIT;"); status_ = Q_HANDLED(); break; } - /*${SMs::Calc::SM::on::operand::int1::POINT} */ + //${SMs::Calc::SM::on::operand::int1::POINT} case POINT_SIG: { BSP_insert((int)'.'); status_ = Q_TRAN(&Calc_frac1); break; } - /*${SMs::Calc::SM::on::operand::int1::DIGIT_0, DIGIT_1_9} */ - case DIGIT_0_SIG: /* intentionally fall through */ + //${SMs::Calc::SM::on::operand::int1::DIGIT_0, DIGIT_1_9} + case DIGIT_0_SIG: // intentionally fall through case DIGIT_1_9_SIG: { BSP_insert(Q_EVT_CAST(CalcEvt)->key_code); status_ = Q_HANDLED(); @@ -534,30 +528,30 @@ static QState Calc_int1(Calc * const me, QEvt const * const e) { return status_; } -/*${SMs::Calc::SM::on::operand::frac1} .....................................*/ +//${SMs::Calc::SM::on::operand::frac1} ....................................... static QState Calc_frac1(Calc * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${SMs::Calc::SM::on::operand::frac1} */ + //${SMs::Calc::SM::on::operand::frac1} case Q_ENTRY_SIG: { BSP_message("frac1-ENTRY;"); status_ = Q_HANDLED(); break; } - /*${SMs::Calc::SM::on::operand::frac1} */ + //${SMs::Calc::SM::on::operand::frac1} case Q_EXIT_SIG: { BSP_message("frac1-EXIT;"); status_ = Q_HANDLED(); break; } - /*${SMs::Calc::SM::on::operand::frac1::POINT} */ + //${SMs::Calc::SM::on::operand::frac1::POINT} case POINT_SIG: { ; status_ = Q_HANDLED(); break; } - /*${SMs::Calc::SM::on::operand::frac1::DIGIT_0, DIGIT_1_9} */ - case DIGIT_0_SIG: /* intentionally fall through */ + //${SMs::Calc::SM::on::operand::frac1::DIGIT_0, DIGIT_1_9} + case DIGIT_0_SIG: // intentionally fall through case DIGIT_1_9_SIG: { BSP_insert(Q_EVT_CAST(CalcEvt)->key_code); status_ = Q_HANDLED(); @@ -571,49 +565,49 @@ static QState Calc_frac1(Calc * const me, QEvt const * const e) { return status_; } -/*${SMs::Calc::SM::on::operand::negated1} ..................................*/ +//${SMs::Calc::SM::on::operand::negated1} .................................... static QState Calc_negated1(Calc * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${SMs::Calc::SM::on::operand::negated1} */ + //${SMs::Calc::SM::on::operand::negated1} case Q_ENTRY_SIG: { BSP_message("negated1-ENTRY;"); BSP_negate(); status_ = Q_HANDLED(); break; } - /*${SMs::Calc::SM::on::operand::negated1} */ + //${SMs::Calc::SM::on::operand::negated1} case Q_EXIT_SIG: { BSP_message("negated1-EXIT;"); status_ = Q_HANDLED(); break; } - /*${SMs::Calc::SM::on::operand::negated1::DIGIT_0} */ + //${SMs::Calc::SM::on::operand::negated1::DIGIT_0} case DIGIT_0_SIG: { BSP_insert(Q_EVT_CAST(CalcEvt)->key_code); status_ = Q_TRAN(&Calc_zero1); break; } - /*${SMs::Calc::SM::on::operand::negated1::DIGIT_1_9} */ + //${SMs::Calc::SM::on::operand::negated1::DIGIT_1_9} case DIGIT_1_9_SIG: { BSP_insert(Q_EVT_CAST(CalcEvt)->key_code); status_ = Q_TRAN(&Calc_int1); break; } - /*${SMs::Calc::SM::on::operand::negated1::POINT} */ + //${SMs::Calc::SM::on::operand::negated1::POINT} case POINT_SIG: { BSP_insert(Q_EVT_CAST(CalcEvt)->key_code); status_ = Q_TRAN(&Calc_frac1); break; } - /*${SMs::Calc::SM::on::operand::negated1::OPER} */ + //${SMs::Calc::SM::on::operand::negated1::OPER} case OPER_SIG: { - /*${SMs::Calc::SM::on::operand::negated1::OPER::[e->key=='-']} */ + //${SMs::Calc::SM::on::operand::negated1::OPER::[e->key=='-']} if (Q_EVT_CAST(CalcEvt)->key_code == KEY_MINUS) { ; status_ = Q_HANDLED(); } - /*${SMs::Calc::SM::on::operand::negated1::OPER::[else]} */ + //${SMs::Calc::SM::on::operand::negated1::OPER::[else]} else { status_ = Q_HANDLED(); } @@ -627,36 +621,36 @@ static QState Calc_negated1(Calc * const me, QEvt const * const e) { return status_; } -/*${SMs::Calc::SM::on::opEntered} ..........................................*/ +//${SMs::Calc::SM::on::opEntered} ............................................ static QState Calc_opEntered(Calc * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${SMs::Calc::SM::on::opEntered} */ + //${SMs::Calc::SM::on::opEntered} case Q_ENTRY_SIG: { BSP_message("opEntered-ENTRY;"); status_ = Q_HANDLED(); break; } - /*${SMs::Calc::SM::on::opEntered} */ + //${SMs::Calc::SM::on::opEntered} case Q_EXIT_SIG: { BSP_message("opEntered-EXIT;"); status_ = Q_HANDLED(); break; } - /*${SMs::Calc::SM::on::opEntered::DIGIT_0} */ + //${SMs::Calc::SM::on::opEntered::DIGIT_0} case DIGIT_0_SIG: { BSP_clear(); status_ = Q_TRAN(&Calc_zero1); break; } - /*${SMs::Calc::SM::on::opEntered::DIGIT_1_9} */ + //${SMs::Calc::SM::on::opEntered::DIGIT_1_9} case DIGIT_1_9_SIG: { BSP_clear(); BSP_insert(Q_EVT_CAST(CalcEvt)->key_code); status_ = Q_TRAN(&Calc_int1); break; } - /*${SMs::Calc::SM::on::opEntered::POINT} */ + //${SMs::Calc::SM::on::opEntered::POINT} case POINT_SIG: { BSP_clear(); BSP_insert((int)'0'); @@ -664,13 +658,13 @@ static QState Calc_opEntered(Calc * const me, QEvt const * const e) { status_ = Q_TRAN(&Calc_frac1); break; } - /*${SMs::Calc::SM::on::opEntered::OPER} */ + //${SMs::Calc::SM::on::opEntered::OPER} case OPER_SIG: { - /*${SMs::Calc::SM::on::opEntered::OPER::[e->key=='-']} */ + //${SMs::Calc::SM::on::opEntered::OPER::[e->key=='-']} if (Q_EVT_CAST(CalcEvt)->key_code == KEY_MINUS) { status_ = Q_TRAN(&Calc_negated1); } - /*${SMs::Calc::SM::on::opEntered::OPER::[else]} */ + //${SMs::Calc::SM::on::opEntered::OPER::[else]} else { status_ = Q_HANDLED(); } @@ -684,11 +678,11 @@ static QState Calc_opEntered(Calc * const me, QEvt const * const e) { return status_; } -/*${SMs::Calc::SM::final} ..................................................*/ +//${SMs::Calc::SM::final} .................................................... static QState Calc_final(Calc * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${SMs::Calc::SM::final} */ + //${SMs::Calc::SM::final} case Q_ENTRY_SIG: { BSP_message("final-ENTRY;"); BSP_exit(); @@ -702,4 +696,4 @@ static QState Calc_final(Calc * const me, QEvt const * const e) { } return status_; } -/*$enddef${SMs::Calc} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$enddef${SMs::Calc} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/examples/posix-win32/calc2/calc2.h b/examples/posix-win32/calc2/calc2.h new file mode 100644 index 00000000..803ca985 --- /dev/null +++ b/examples/posix-win32/calc2/calc2.h @@ -0,0 +1,65 @@ +//$file${.::calc2.h} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// +// Model: calc2.qm +// File: ${.::calc2.h} +// +// This code has been generated by QM 5.3.0 . +// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. +// +// SPDX-License-Identifier: GPL-3.0-or-later +// +// This generated code is open source software: you can redistribute it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation. +// +// This code is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// NOTE: +// Alternatively, this generated code may be distributed under the terms +// of Quantum Leaps commercial licenses, which expressly supersede the GNU +// General Public License and are specifically designed for licensees +// interested in retaining the proprietary status of their code. +// +// Contact information: +// +// +// +//$endhead${.::calc2.h} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +#ifndef CALC2_H +#define CALC2_H + +enum CalcSignals { + C_SIG = Q_USER_SIG, + CE_SIG, + DIGIT_0_SIG, + DIGIT_1_9_SIG, + POINT_SIG, + OPER_SIG, + EQUALS_SIG, + OFF_SIG +}; + +//$declare${Events::CalcEvt} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${Events::CalcEvt} ......................................................... +typedef struct { +// protected: + QEvt super; + +// public: + uint8_t key_code; +} CalcEvt; +//$enddecl${Events::CalcEvt} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +//$declare${SMs::Calc_ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${SMs::Calc_ctor} .......................................................... +void Calc_ctor(void); +//$enddecl${SMs::Calc_ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +extern QHsm * const the_calc; // "opaque" pointer to calculator HSM + +#endif // CALC2_H + diff --git a/examples/workstation/calc2/calc2.qm b/examples/posix-win32/calc2/calc2.qm similarity index 94% rename from examples/workstation/calc2/calc2.qm rename to examples/posix-win32/calc2/calc2.qm index 30ac26c9..fa7cee32 100644 --- a/examples/workstation/calc2/calc2.qm +++ b/examples/posix-win32/calc2/calc2.qm @@ -1,5 +1,5 @@ - + Improved model of the Calculator described in Chapter 4 of PSiCC2. Improvements include: - placing the "negated1" state inside "operand1" superstate - placing the "negated2" state inside "operand2" superstate @@ -33,17 +33,17 @@ - /* guard function to evaluate the current expression + // guard function to evaluate the current expression * taking into account the precedence of operands. * return: true if evaluation successfull * false when error encountered -*/ + double result; -if (me->oper1 == KEY_NULL) { /* no op1 yet */ +if (me->oper1 == KEY_NULL) { // no op1 yet me->op1 = op; me->oper1 = oper; result = me->op1; @@ -56,13 +56,13 @@ else if ((oper == KEY_NULL) || (oper == KEY_PLUS) || (oper == KEY_MINUS)) { } case KEY_DIVIDE: { if ((-1e-30 < op) && (op < 1e-30)) { - BSP_display_error(" Error 0 "); /* divide by zero */ + BSP_display_error(" Error 0 "); // divide by zero return false; } me->op2 /= op; break; } - default: { /* no op2 yet */ + default: { // no op2 yet me->op2 = op; me->oper2 = oper; break; @@ -83,7 +83,7 @@ else if ((oper == KEY_NULL) || (oper == KEY_PLUS) || (oper == KEY_MINUS)) { } case KEY_DIVIDE: { if ((-1e-30 < me->op2) && (me->op2 < 1e-30)) { - BSP_display_error(" Error 0 "); /* divide by zero */ + BSP_display_error(" Error 0 "); // divide by zero return false; } me->op1 /= me->op2; @@ -98,7 +98,7 @@ else if ((oper == KEY_NULL) || (oper == KEY_PLUS) || (oper == KEY_MINUS)) { me->oper2 = KEY_NULL; result = me->op1; } -else { /* (oper == KEY_MULT) || (oper == KEY_DIV) */ +else { // (oper == KEY_MULT) || (oper == KEY_DIV) switch (me->oper2) { case KEY_MULT: { me->op2 *= op; @@ -106,13 +106,13 @@ else { /* (oper == KEY_MULT) || (oper == KEY_DIV) */ } case KEY_DIVIDE: { if ((-1e-30 < op) && (op < 1e-30)) { - BSP_display_error(" Error 0 "); /* divide by zero */ + BSP_display_error(" Error 0 "); // divide by zero return false; } me->op2 /= op; break; } - default: { /* oper2 not provided yet */ + default: { // oper2 not provided yet me->op2 = op; break; } @@ -122,7 +122,7 @@ else { /* (oper == KEY_MULT) || (oper == KEY_DIV) */ } if ((result < -99999999.0) || (99999999.0 < result)) { - BSP_display_error(" Error 1 "); /* out of range */ + BSP_display_error(" Error 1 "); // out of range return false; } if ((-0.0000001 < result) && (result < 0.0000001)) { @@ -136,7 +136,7 @@ return true; - (void)par; /* unused parameter */ + (void)par; // unused parameter @@ -167,9 +167,9 @@ BSP_clear(); - /* Error state after evaluation of an expression. + // Error state after evaluation of an expression. This state can be exited only throgh the inherited C (Clear) event. -*/ + BSP_message("error-ENTRY;"); BSP_message("error-EXIT;"); @@ -552,16 +552,16 @@ enum CalcSignals { $declare${Events::CalcEvt} $declare${SMs::Calc_ctor} -extern QHsm * const the_calc; /* "opaque" pointer to calculator HSM */ +extern QHsm * const the_calc; // "opaque" pointer to calculator HSM -#endif /* CALC2_H */ +#endif // CALC2_H - #include "qpc.h" /* QP/C */ -#include "bsp.h" /* board support package */ -#include "calc2.h" /* application */ + #include "qpc.h" // QP/C +#include "bsp.h" // board support package +#include "calc2.h" // application Q_DEFINE_THIS_FILE diff --git a/examples/posix-win32/calc2/main.c b/examples/posix-win32/calc2/main.c new file mode 100644 index 00000000..8497777d --- /dev/null +++ b/examples/posix-win32/calc2/main.c @@ -0,0 +1,134 @@ +//============================================================================ +// Product: calc2 Example +// Last updated for version 7.3.0 +// Last updated on 2023-07-27 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// This program is open source software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Alternatively, this program may be distributed and modified under the +// terms of Quantum Leaps commercial licenses, which expressly supersede +// the GNU General Public License and are specifically designed for +// licensees interested in retaining the proprietary status of their code. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Contact information: +// +// +//============================================================================ +#include "qpc.h" +#include "bsp.h" +#include "calc2.h" + +#include "safe_std.h" // portable "safe" / facilities + +Q_DEFINE_THIS_FILE + +//............................................................................ +int main() { + + QF_init(); + QF_onStartup(); + + PRINTF_S("Calculator example, QP version: %s\n" + "Press '0' .. '9' to enter a digit\n" + "Press '.' to enter the decimal point\n" + "Press '+' to add\n" + "Press '-' to subtract or negate a number\n" + "Press '*' to multiply\n" + "Press '/' to divide\n" + "Press '=' or to get the result\n" + "Press 'c' or 'C' to Cancel\n" + "Press 'e' or 'E' to Cancel Entry\n" + "Press to quit.\n\n", + QP_VERSION_STR); + + Calc_ctor(); // explicitly instantiate the calculator object + QASM_INIT(the_calc, (void *)0, 0U); // trigger initial transition + + for (;;) { // event loop + CalcEvt e = { QEVT_INITIALIZER(0U), 0U}; // Calculator event + + BSP_show_display(); // show the display + + PRINTF_S("%s"," : "); + fflush(stdout); + e.key_code = (uint8_t)QF_consoleWaitForKey(); + PRINTF_S("%c ", (e.key_code >= ' ') ? e.key_code : 'X'); + + switch (e.key_code) { + case 'c': // intentionally fall through + case 'C': { + e.super.sig = C_SIG; + break; + } + case 'e': // intentionally fall through + case 'E': { + e.super.sig = CE_SIG; + break; + } + case '0': { + e.super.sig = DIGIT_0_SIG; + break; + } + case '1': // intentionally fall through + case '2': // intentionally fall through + case '3': // intentionally fall through + case '4': // intentionally fall through + case '5': // intentionally fall through + case '6': // intentionally fall through + case '7': // intentionally fall through + case '8': // intentionally fall through + case '9': { + e.super.sig = DIGIT_1_9_SIG; + break; + } + case '.': { + e.super.sig = POINT_SIG; + break; + } + case '+': // intentionally fall through + case '-': // intentionally fall through + case '*': // intentionally fall through + case '/': { + e.super.sig = OPER_SIG; + break; + } + case '=': // intentionally fall through + case '\r': { // Enter key + e.super.sig = EQUALS_SIG; + break; + } + case '\33': { // ESC key + e.super.sig = OFF_SIG; + break; + } + default: { + e.super.sig = 0; // invalid event + break; + } + } + + if (e.super.sig != 0) { // valid event generated? + QASM_DISPATCH(the_calc, &e.super, 0U); // dispatch event + } + } + + QF_onCleanup(); + return 0; +} diff --git a/examples/workstation/calc1/Makefile b/examples/posix-win32/calc_sub/Makefile similarity index 98% rename from examples/workstation/calc1/Makefile rename to examples/posix-win32/calc_sub/Makefile index 56c553ef..1ba66aab 100644 --- a/examples/workstation/calc1/Makefile +++ b/examples/posix-win32/calc_sub/Makefile @@ -49,7 +49,7 @@ #----------------------------------------------------------------------------- # project name: # -PROJECT := calc1 +PROJECT := calc_sub #----------------------------------------------------------------------------- # project directories: @@ -74,7 +74,7 @@ endif C_SRCS := \ bsp.c \ main.c \ - calc1.c + calc_sub.c # C++ source files... CPP_SRCS := @@ -242,7 +242,7 @@ CPP_DEPS_EXT := $(patsubst %.o,%.d, $(CPP_OBJS_EXT)) all: $(TARGET_EXE) $(TARGET_EXE) : $(C_OBJS_EXT) $(CPP_OBJS_EXT) - $(CC) $(CFLAGS) $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o + $(CC) $(CFLAGS) $(QPC)/src/qs/qstamp.c -o $(BIN_DIR)/qstamp.o $(LINK) $(LINKFLAGS) $(LIB_DIRS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) $(BIN_DIR)/%.d : %.c diff --git a/examples/posix-win32/calc_sub/bsp.c b/examples/posix-win32/calc_sub/bsp.c new file mode 100644 index 00000000..b72e61a9 --- /dev/null +++ b/examples/posix-win32/calc_sub/bsp.c @@ -0,0 +1,116 @@ +//============================================================================ +// Board Support Package (BSP) for the Calculator example +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +//============================================================================ +#include "qpc.h" +#include "bsp.h" + +#include "safe_std.h" // portable "safe" / facilities +#include // for exit() + +#define DISP_WIDTH 15 + +// helper macros to "stringify" values +#define VAL(x) #x +#define STRINGIFY(x) VAL(x) + +static char l_display[DISP_WIDTH + 1]; // the calculator display +static uint32_t l_len; // number of displayed characters + +//............................................................................ +void BSP_clear(void) { + memset(l_display, ' ', DISP_WIDTH - 1); + l_display[DISP_WIDTH - 1] = '0'; + l_display[DISP_WIDTH] = '\0'; + l_len = 0; +} +//............................................................................ +void BSP_insert(uint8_t keyId) { + if (l_len == 0U) { + l_display[DISP_WIDTH - 1] = (char)keyId; + ++l_len; + } + else if (l_len < (DISP_WIDTH - 1)) { + MEMMOVE_S(&l_display[0], DISP_WIDTH, &l_display[1], DISP_WIDTH - 1); + l_display[DISP_WIDTH - 1] = (char)keyId; + ++l_len; + } +} +//............................................................................ +void BSP_display(float64_t value) { + SNPRINTF_S(l_display, Q_DIM(l_display), + "%" STRINGIFY(DISP_WIDTH) ".6g", value); +} +//............................................................................ +void BSP_display_error(char const *err) { + STRNCPY_S(l_display, DISP_WIDTH, err); +} +//............................................................................ +void BSP_negate(void) { + BSP_clear(); + l_display[DISP_WIDTH - 2] = '-'; +} +//............................................................................ +void BSP_show_display(void) { + PRINTF_S("\n[%" STRINGIFY(DISP_WIDTH) "s] ", l_display); +} +//............................................................................ +void BSP_exit(void) { + PRINTF_S("\n%s\n", "Bye! Bye!"); + fflush(stdout); + QF_onCleanup(); + exit(0); +} +//............................................................................ +float64_t BSP_get_value(void) { + return strtod(l_display, (char **)0); +} +//............................................................................ +void BSP_message(char const *msg) { + PRINTF_S("%s", msg); +} + +//............................................................................ +void QF_onStartup(void) { + QF_consoleSetup(); +} +//............................................................................ +void QF_onCleanup(void) { + QF_consoleCleanup(); +} +//............................................................................ +void QF_onClockTick(void) { +} + +//............................................................................ +// this function is used by the QP embedded systems-friendly assertions +Q_NORETURN Q_onError(char const * const module, int_t const id) { + FPRINTF_S(stderr, "ERROR in %s:%d", module, id); + QF_onCleanup(); + exit(-1); +} +//............................................................................ +void assert_failed(char const * const module, int_t const id); // prototype +void assert_failed(char const * const module, int_t const id) { + Q_onError(module, id); +} diff --git a/examples/posix-win32/calc_sub/bsp.h b/examples/posix-win32/calc_sub/bsp.h new file mode 100644 index 00000000..1ce28c42 --- /dev/null +++ b/examples/posix-win32/calc_sub/bsp.h @@ -0,0 +1,39 @@ +//============================================================================ +// Board Support Package (BSP) for the Calculator example +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +//============================================================================ +#ifndef BSP_H_ +#define BSP_H_ + +void BSP_clear(void); +void BSP_negate(void); +void BSP_insert(uint8_t keyId); +float64_t BSP_get_value(void); +void BSP_display(float64_t value); +void BSP_display_error(char const *err); +void BSP_exit(void); + +void BSP_show_display(void); +void BSP_message(char const *msg); + +#endif // BSP_H_ diff --git a/examples/workstation/calc1_sub/calc1_sub.c b/examples/posix-win32/calc_sub/calc_sub.c similarity index 53% rename from examples/workstation/calc1_sub/calc1_sub.c rename to examples/posix-win32/calc_sub/calc_sub.c index f4fd2a0c..571d7c53 100644 --- a/examples/workstation/calc1_sub/calc1_sub.c +++ b/examples/posix-win32/calc_sub/calc_sub.c @@ -1,36 +1,36 @@ -/*$file${.::calc1_sub.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* -* Model: calc1_sub.qm -* File: ${.::calc1_sub.c} -* -* This code has been generated by QM 5.2.4 . -* DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. -* -* SPDX-License-Identifier: GPL-3.0-or-later -* -* This generated code is open source software: you can redistribute it under -* the terms of the GNU General Public License as published by the Free -* Software Foundation. -* -* This code is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -* more details. -* -* NOTE: -* Alternatively, this generated code may be distributed under the terms -* of Quantum Leaps commercial licenses, which expressly supersede the GNU -* General Public License and are specifically designed for licensees -* interested in retaining the proprietary status of their code. -* -* Contact information: -* -* -*/ -/*$endhead${.::calc1_sub.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -#include "qpc.h" /* QP/C */ -#include "bsp.h" /* board support package */ -#include "calc1_sub.h" /* application */ +//$file${.::calc_sub.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// +// Model: calc_sub.qm +// File: ${.::calc_sub.c} +// +// This code has been generated by QM 5.3.0 . +// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. +// +// SPDX-License-Identifier: GPL-3.0-or-later +// +// This generated code is open source software: you can redistribute it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation. +// +// This code is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// NOTE: +// Alternatively, this generated code may be distributed under the terms +// of Quantum Leaps commercial licenses, which expressly supersede the GNU +// General Public License and are specifically designed for licensees +// interested in retaining the proprietary status of their code. +// +// Contact information: +// +// +// +//$endhead${.::calc_sub.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +#include "qpc.h" // QP/C +#include "bsp.h" // board support package +#include "calc_sub.h" // application Q_DEFINE_THIS_FILE @@ -40,73 +40,67 @@ Q_DEFINE_THIS_FILE #define KEY_MULT ((uint8_t)'*') #define KEY_DIVIDE ((uint8_t)'/') -/*$declare${SMs::Calc} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//$declare${SMs::Calc} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/*${SMs::Calc} .............................................................*/ +//${SMs::Calc} ............................................................... typedef struct Calc { -/* protected: */ +// protected: QMsm super; -/* private: */ +// private: float64_t op1; float64_t op2; uint8_t oper1; uint8_t oper2; -/* public: */ +// public: -/* private submachines */ - /* exit points for submachine ${SMs::Calc::SM::operand} */ +// private submachines + // exit points for submachine ${SMs::Calc::SM::operand} struct SM_operand { QMState super; - QActionHandler const CE; /* eXit-Point segment */ + QActionHandler const CE; // eXit-Point segment } const *sub_operand; } Calc; -/* private: */ +// private: -/* guard function to evaluate the current expression -* taking into account the precedence of operands. -* return: true if evaluation successfull -* false when error encountered -*/ +// guard function to evaluate the current expression static bool Calc_eval(Calc * const me, float64_t op, uint8_t oper); extern Calc Calc_inst; -/* protected: */ +// protected: static QState Calc_initial(Calc * const me, void const * const par); static QState Calc_on (Calc * const me, QEvt const * const e); static QState Calc_on_e(Calc * const me); static QState Calc_on_x(Calc * const me); static QState Calc_on_i(Calc * const me); static QMState const Calc_on_s = { - QM_STATE_NULL, /* superstate (top) */ + QM_STATE_NULL, // superstate (top) Q_STATE_CAST(&Calc_on), Q_ACTION_CAST(&Calc_on_e), Q_ACTION_CAST(&Calc_on_x), Q_ACTION_CAST(&Calc_on_i) }; -/* Error state after evaluation of an expression. -This state can be exited only throgh the inherited C (Clear) event. -*/ +// Error state after evaluation of an expression. static QState Calc_error (Calc * const me, QEvt const * const e); static QState Calc_error_e(Calc * const me); static QState Calc_error_x(Calc * const me); static QMState const Calc_error_s = { - &Calc_on_s, /* superstate */ + &Calc_on_s, // superstate Q_STATE_CAST(&Calc_error), Q_ACTION_CAST(&Calc_error_e), Q_ACTION_CAST(&Calc_error_x), - Q_ACTION_NULL /* no initial tran. */ + Q_ACTION_NULL // no initial tran. }; static QState Calc_ready (Calc * const me, QEvt const * const e); static QState Calc_ready_e(Calc * const me); static QState Calc_ready_x(Calc * const me); static QState Calc_ready_i(Calc * const me); static QMState const Calc_ready_s = { - &Calc_on_s, /* superstate */ + &Calc_on_s, // superstate Q_STATE_CAST(&Calc_ready), Q_ACTION_CAST(&Calc_ready_e), Q_ACTION_CAST(&Calc_ready_x), @@ -116,42 +110,42 @@ static QState Calc_result (Calc * const me, QEvt const * const e); static QState Calc_result_e(Calc * const me); static QState Calc_result_x(Calc * const me); static QMState const Calc_result_s = { - &Calc_ready_s, /* superstate */ + &Calc_ready_s, // superstate Q_STATE_CAST(&Calc_result), Q_ACTION_CAST(&Calc_result_e), Q_ACTION_CAST(&Calc_result_x), - Q_ACTION_NULL /* no initial tran. */ + Q_ACTION_NULL // no initial tran. }; static QState Calc_begin (Calc * const me, QEvt const * const e); static QState Calc_begin_e(Calc * const me); static QState Calc_begin_x(Calc * const me); static QMState const Calc_begin_s = { - &Calc_ready_s, /* superstate */ + &Calc_ready_s, // superstate Q_STATE_CAST(&Calc_begin), Q_ACTION_CAST(&Calc_begin_e), Q_ACTION_CAST(&Calc_begin_x), - Q_ACTION_NULL /* no initial tran. */ + Q_ACTION_NULL // no initial tran. }; static QState Calc_opEntered (Calc * const me, QEvt const * const e); static QState Calc_opEntered_e(Calc * const me); static QState Calc_opEntered_x(Calc * const me); static QMState const Calc_opEntered_s = { - &Calc_on_s, /* superstate */ + &Calc_on_s, // superstate Q_STATE_CAST(&Calc_opEntered), Q_ACTION_CAST(&Calc_opEntered_e), Q_ACTION_CAST(&Calc_opEntered_x), - Q_ACTION_NULL /* no initial tran. */ + Q_ACTION_NULL // no initial tran. }; static QState Calc_operand1 (Calc * const me, QEvt const * const e); static QState Calc_operand1_e(Calc * const me); static QState Calc_operand1_CE(Calc * const me); static struct SM_operand const Calc_operand1_s = { { - &Calc_on_s, /* superstate */ + &Calc_on_s, // superstate Q_STATE_CAST(&Calc_operand1), Q_ACTION_CAST(&Calc_operand1_e), - Q_ACTION_NULL, /* no exit action */ - Q_ACTION_NULL /* no initial tran. */ + Q_ACTION_NULL, // no exit action + Q_ACTION_NULL // no initial tran. } ,Q_ACTION_CAST(&Calc_operand1_CE) }; @@ -160,34 +154,34 @@ static QState Calc_operand2_e(Calc * const me); static QState Calc_operand2_CE(Calc * const me); static struct SM_operand const Calc_operand2_s = { { - &Calc_on_s, /* superstate */ + &Calc_on_s, // superstate Q_STATE_CAST(&Calc_operand2), Q_ACTION_CAST(&Calc_operand2_e), - Q_ACTION_NULL, /* no exit action */ - Q_ACTION_NULL /* no initial tran. */ + Q_ACTION_NULL, // no exit action + Q_ACTION_NULL // no initial tran. } ,Q_ACTION_CAST(&Calc_operand2_CE) }; static QState Calc_final (Calc * const me, QEvt const * const e); static QState Calc_final_e(Calc * const me); static QMState const Calc_final_s = { - QM_STATE_NULL, /* superstate (top) */ + QM_STATE_NULL, // superstate (top) Q_STATE_CAST(&Calc_final), Q_ACTION_CAST(&Calc_final_e), - Q_ACTION_NULL, /* no exit action */ - Q_ACTION_NULL /* no initial tran. */ + Q_ACTION_NULL, // no exit action + Q_ACTION_NULL // no initial tran. }; -/* submachine ${SMs::Calc::SM::operand} */ +// submachine ${SMs::Calc::SM::operand} static QState Calc_operand (Calc * const me, QEvt const * const e); static QState Calc_operand_e(Calc * const me); static QState Calc_operand_x(Calc * const me); static QMState const Calc_operand_s = { - QM_STATE_NULL, /* superstate unused */ + QM_STATE_NULL, // superstate unused Q_STATE_CAST(&Calc_operand), Q_ACTION_CAST(&Calc_operand_e), Q_ACTION_CAST(&Calc_operand_x), - Q_ACTION_NULL /* no initial tran. */ + Q_ACTION_NULL // no initial tran. }; static QState Calc_operand_zero_ep(Calc * const me); static QState Calc_operand_intgr_ep(Calc * const me); @@ -197,70 +191,70 @@ static QState Calc_operand_zero (Calc * const me, QEvt const * const e); static QState Calc_operand_zero_e(Calc * const me); static QState Calc_operand_zero_x(Calc * const me); static QMState const Calc_operand_zero_s = { - &Calc_operand_s, /* superstate */ + &Calc_operand_s, // superstate Q_STATE_CAST(&Calc_operand_zero), Q_ACTION_CAST(&Calc_operand_zero_e), Q_ACTION_CAST(&Calc_operand_zero_x), - Q_ACTION_NULL /* no initial tran. */ + Q_ACTION_NULL // no initial tran. }; static QState Calc_operand_intgr (Calc * const me, QEvt const * const e); static QState Calc_operand_intgr_e(Calc * const me); static QState Calc_operand_intgr_x(Calc * const me); static QMState const Calc_operand_intgr_s = { - &Calc_operand_s, /* superstate */ + &Calc_operand_s, // superstate Q_STATE_CAST(&Calc_operand_intgr), Q_ACTION_CAST(&Calc_operand_intgr_e), Q_ACTION_CAST(&Calc_operand_intgr_x), - Q_ACTION_NULL /* no initial tran. */ + Q_ACTION_NULL // no initial tran. }; static QState Calc_operand_frac (Calc * const me, QEvt const * const e); static QState Calc_operand_frac_e(Calc * const me); static QState Calc_operand_frac_x(Calc * const me); static QMState const Calc_operand_frac_s = { - &Calc_operand_s, /* superstate */ + &Calc_operand_s, // superstate Q_STATE_CAST(&Calc_operand_frac), Q_ACTION_CAST(&Calc_operand_frac_e), Q_ACTION_CAST(&Calc_operand_frac_x), - Q_ACTION_NULL /* no initial tran. */ + Q_ACTION_NULL // no initial tran. }; static QState Calc_operand_negated (Calc * const me, QEvt const * const e); static QState Calc_operand_negated_e(Calc * const me); static QState Calc_operand_negated_x(Calc * const me); static QMState const Calc_operand_negated_s = { - &Calc_operand_s, /* superstate */ + &Calc_operand_s, // superstate Q_STATE_CAST(&Calc_operand_negated), Q_ACTION_CAST(&Calc_operand_negated_e), Q_ACTION_CAST(&Calc_operand_negated_x), - Q_ACTION_NULL /* no initial tran. */ + Q_ACTION_NULL // no initial tran. }; -/*$enddecl${SMs::Calc} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$enddecl${SMs::Calc} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -/*$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* Check for the minimum required QP version */ -#if (QP_VERSION < 700U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) -#error qpc version 7.0.0 or higher required +//$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// Check for the minimum required QP version +#if (QP_VERSION < 730U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) +#error qpc version 7.3.0 or higher required #endif -/*$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -/*$define${SMs::the_calc} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//$define${SMs::the_calc} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/*${SMs::the_calc} .........................................................*/ -QHsm * const the_calc = &Calc_inst.super.super; -/*$enddef${SMs::the_calc} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*$define${SMs::Calc_ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//${SMs::the_calc} ........................................................... +QAsm * const the_calc = &Calc_inst.super.super; +//$enddef${SMs::the_calc} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +//$define${SMs::Calc_ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/*${SMs::Calc_ctor} ........................................................*/ +//${SMs::Calc_ctor} .......................................................... void Calc_ctor(void) { Calc *me = &Calc_inst; QMsm_ctor(&me->super, Q_STATE_CAST(&Calc_initial)); } -/*$enddef${SMs::Calc_ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*$define${SMs::Calc} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//$enddef${SMs::Calc_ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +//$define${SMs::Calc} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/*${SMs::Calc} .............................................................*/ +//${SMs::Calc} ............................................................... Calc Calc_inst; -/*${SMs::Calc::eval} .......................................................*/ +//${SMs::Calc::eval} ......................................................... static bool Calc_eval(Calc * const me, float64_t op, uint8_t oper) @@ -274,13 +268,13 @@ static bool Calc_eval(Calc * const me, } case KEY_DIVIDE: { if ((-1e-30 < op) && (op < 1e-30)) { - BSP_display_error(" Error 0 "); /* divide by zero */ + BSP_display_error(" Error 0 "); // divide by zero return false; } me->op2 /= op; break; } - default: { /* no op2 yet */ + default: { // no op2 yet me->op2 = op; me->oper2 = oper; break; @@ -301,7 +295,7 @@ static bool Calc_eval(Calc * const me, } case KEY_DIVIDE: { if ((-1e-30 < me->op2) && (me->op2 < 1e-30)) { - BSP_display_error(" Error 0 "); /* divide by zero */ + BSP_display_error(" Error 0 "); // divide by zero return false; } me->op1 /= me->op2; @@ -316,7 +310,7 @@ static bool Calc_eval(Calc * const me, me->oper2 = KEY_NULL; result = me->op1; } - else { /* (oper == KEY_MULT) || (oper == KEY_DIV) */ + else { // (oper == KEY_MULT) || (oper == KEY_DIV) switch (me->oper2) { case KEY_MULT: { me->op2 *= op; @@ -324,13 +318,13 @@ static bool Calc_eval(Calc * const me, } case KEY_DIVIDE: { if ((-1e-30 < op) && (op < 1e-30)) { - BSP_display_error(" Error 0 "); /* divide by zero */ + BSP_display_error(" Error 0 "); // divide by zero return false; } me->op2 /= op; break; } - default: { /* oper2 not provided yet */ + default: { // oper2 not provided yet me->op2 = op; break; } @@ -340,7 +334,7 @@ static bool Calc_eval(Calc * const me, } if ((result < -99999999.0) || (99999999.0 < result)) { - BSP_display_error(" Error 1 "); /* out of range */ + BSP_display_error(" Error 1 "); // out of range return false; } if ((-0.0000001 < result) && (result < 0.0000001)) { @@ -351,87 +345,87 @@ static bool Calc_eval(Calc * const me, return true; } -/*${SMs::Calc::SM} .........................................................*/ +//${SMs::Calc::SM} ........................................................... static QState Calc_initial(Calc * const me, void const * const par) { static struct { QMState const *target; QActionHandler act[3]; - } const tatbl_ = { /* tran-action table */ - &Calc_on_s, /* target state */ + } const tatbl_ = { // tran-action table + &Calc_on_s, // target state { - Q_ACTION_CAST(&Calc_on_e), /* entry */ - Q_ACTION_CAST(&Calc_on_i), /* initial tran. */ - Q_ACTION_NULL /* zero terminator */ + Q_ACTION_CAST(&Calc_on_e), // entry + Q_ACTION_CAST(&Calc_on_i), // initial tran. + Q_ACTION_NULL // zero terminator } }; - /*${SMs::Calc::SM::initial} */ - (void)par; /* unused parameter */ + //${SMs::Calc::SM::initial} + (void)par; // unused parameter return QM_TRAN_INIT(&tatbl_); } -/*${SMs::Calc::SM::on} .....................................................*/ -/*${SMs::Calc::SM::on} */ +//${SMs::Calc::SM::on} ....................................................... +//${SMs::Calc::SM::on} static QState Calc_on_e(Calc * const me) { BSP_message("on-ENTRY;"); - (void)me; /* unused parameter */ + Q_UNUSED_PAR(me); return QM_ENTRY(&Calc_on_s); } -/*${SMs::Calc::SM::on} */ +//${SMs::Calc::SM::on} static QState Calc_on_x(Calc * const me) { BSP_message("on-EXIT;"); - (void)me; /* unused parameter */ + (void)me; // unused parameter return QM_EXIT(&Calc_on_s); } -/*${SMs::Calc::SM::on::initial} */ +//${SMs::Calc::SM::on::initial} static QState Calc_on_i(Calc * const me) { static struct { QMState const *target; QActionHandler act[3]; - } const tatbl_ = { /* tran-action table */ - &Calc_ready_s, /* target state */ + } const tatbl_ = { // tran-action table + &Calc_ready_s, // target state { - Q_ACTION_CAST(&Calc_ready_e), /* entry */ - Q_ACTION_CAST(&Calc_ready_i), /* initial tran. */ - Q_ACTION_NULL /* zero terminator */ + Q_ACTION_CAST(&Calc_ready_e), // entry + Q_ACTION_CAST(&Calc_ready_i), // initial tran. + Q_ACTION_NULL // zero terminator } }; - /*${SMs::Calc::SM::on::initial} */ + //${SMs::Calc::SM::on::initial} BSP_message("on-INIT;"); BSP_clear(); return QM_TRAN_INIT(&tatbl_); } -/*${SMs::Calc::SM::on} */ +//${SMs::Calc::SM::on} static QState Calc_on(Calc * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${SMs::Calc::SM::on::C} */ + //${SMs::Calc::SM::on::C} case C_SIG: { static struct { QMState const *target; QActionHandler act[4]; - } const tatbl_ = { /* tran-action table */ - &Calc_on_s, /* target state */ + } const tatbl_ = { // tran-action table + &Calc_on_s, // target state { - Q_ACTION_CAST(&Calc_on_x), /* exit */ - Q_ACTION_CAST(&Calc_on_e), /* entry */ - Q_ACTION_CAST(&Calc_on_i), /* initial tran. */ - Q_ACTION_NULL /* zero terminator */ + Q_ACTION_CAST(&Calc_on_x), // exit + Q_ACTION_CAST(&Calc_on_e), // entry + Q_ACTION_CAST(&Calc_on_i), // initial tran. + Q_ACTION_NULL // zero terminator } }; status_ = QM_TRAN(&tatbl_); break; } - /*${SMs::Calc::SM::on::OFF} */ + //${SMs::Calc::SM::on::OFF} case OFF_SIG: { static struct { QMState const *target; QActionHandler act[3]; - } const tatbl_ = { /* tran-action table */ - &Calc_final_s, /* target state */ + } const tatbl_ = { // tran-action table + &Calc_final_s, // target state { - Q_ACTION_CAST(&Calc_on_x), /* exit */ - Q_ACTION_CAST(&Calc_final_e), /* entry */ - Q_ACTION_NULL /* zero terminator */ + Q_ACTION_CAST(&Calc_on_x), // exit + Q_ACTION_CAST(&Calc_final_e), // entry + Q_ACTION_NULL // zero terminator } }; status_ = QM_TRAN(&tatbl_); @@ -445,20 +439,20 @@ static QState Calc_on(Calc * const me, QEvt const * const e) { return status_; } -/*${SMs::Calc::SM::on::error} ..............................................*/ -/*${SMs::Calc::SM::on::error} */ +//${SMs::Calc::SM::on::error} ................................................ +//${SMs::Calc::SM::on::error} static QState Calc_error_e(Calc * const me) { BSP_message("error-ENTRY;"); - (void)me; /* unused parameter */ + Q_UNUSED_PAR(me); return QM_ENTRY(&Calc_error_s); } -/*${SMs::Calc::SM::on::error} */ +//${SMs::Calc::SM::on::error} static QState Calc_error_x(Calc * const me) { BSP_message("error-EXIT;"); - (void)me; /* unused parameter */ + (void)me; // unused parameter return QM_EXIT(&Calc_error_s); } -/*${SMs::Calc::SM::on::error} */ +//${SMs::Calc::SM::on::error} static QState Calc_error(Calc * const me, QEvt const * const e) { QState status_; switch (e->sig) { @@ -467,73 +461,73 @@ static QState Calc_error(Calc * const me, QEvt const * const e) { break; } } - (void)me; /* unused parameter */ + Q_UNUSED_PAR(me); return status_; } -/*${SMs::Calc::SM::on::ready} ..............................................*/ -/*${SMs::Calc::SM::on::ready} */ +//${SMs::Calc::SM::on::ready} ................................................ +//${SMs::Calc::SM::on::ready} static QState Calc_ready_e(Calc * const me) { BSP_message("ready-ENTRY;"); me->oper2 = KEY_NULL; return QM_ENTRY(&Calc_ready_s); } -/*${SMs::Calc::SM::on::ready} */ +//${SMs::Calc::SM::on::ready} static QState Calc_ready_x(Calc * const me) { BSP_message("ready-EXIT;"); - (void)me; /* unused parameter */ + (void)me; // unused parameter return QM_EXIT(&Calc_ready_s); } -/*${SMs::Calc::SM::on::ready::initial} */ +//${SMs::Calc::SM::on::ready::initial} static QState Calc_ready_i(Calc * const me) { static struct { QMState const *target; QActionHandler act[2]; - } const tatbl_ = { /* tran-action table */ - &Calc_begin_s, /* target state */ + } const tatbl_ = { // tran-action table + &Calc_begin_s, // target state { - Q_ACTION_CAST(&Calc_begin_e), /* entry */ - Q_ACTION_NULL /* zero terminator */ + Q_ACTION_CAST(&Calc_begin_e), // entry + Q_ACTION_NULL // zero terminator } }; - /*${SMs::Calc::SM::on::ready::initial} */ + //${SMs::Calc::SM::on::ready::initial} BSP_message("ready-INIT;"); return QM_TRAN_INIT(&tatbl_); } -/*${SMs::Calc::SM::on::ready} */ +//${SMs::Calc::SM::on::ready} static QState Calc_ready(Calc * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${SMs::Calc::SM::on::ready::DIGIT_0} */ + //${SMs::Calc::SM::on::ready::DIGIT_0} case DIGIT_0_SIG: { static struct { QMState const *target; QActionHandler act[4]; - } const tatbl_ = { /* tran-action table */ - &Calc_operand_s, /* target submachine */ + } const tatbl_ = { // tran-action table + &Calc_operand_s, // target submachine { - Q_ACTION_CAST(&Calc_ready_x), /* exit */ - Q_ACTION_CAST(&Calc_operand1_e), /* entry */ - Q_ACTION_CAST(&Calc_operand_zero_ep), /* EP */ - Q_ACTION_NULL /* zero terminator */ + Q_ACTION_CAST(&Calc_ready_x), // exit + Q_ACTION_CAST(&Calc_operand1_e), // entry + Q_ACTION_CAST(&Calc_operand_zero_ep), // EP + Q_ACTION_NULL // zero terminator } }; BSP_clear(); status_ = QM_TRAN_EP(&tatbl_); break; } - /*${SMs::Calc::SM::on::ready::DIGIT_1_9} */ + //${SMs::Calc::SM::on::ready::DIGIT_1_9} case DIGIT_1_9_SIG: { static struct { QMState const *target; QActionHandler act[4]; - } const tatbl_ = { /* tran-action table */ - &Calc_operand_s, /* target submachine */ + } const tatbl_ = { // tran-action table + &Calc_operand_s, // target submachine { - Q_ACTION_CAST(&Calc_ready_x), /* exit */ - Q_ACTION_CAST(&Calc_operand1_e), /* entry */ - Q_ACTION_CAST(&Calc_operand_intgr_ep), /* EP */ - Q_ACTION_NULL /* zero terminator */ + Q_ACTION_CAST(&Calc_ready_x), // exit + Q_ACTION_CAST(&Calc_operand1_e), // entry + Q_ACTION_CAST(&Calc_operand_intgr_ep), // EP + Q_ACTION_NULL // zero terminator } }; BSP_clear(); @@ -541,18 +535,18 @@ static QState Calc_ready(Calc * const me, QEvt const * const e) { status_ = QM_TRAN_EP(&tatbl_); break; } - /*${SMs::Calc::SM::on::ready::POINT} */ + //${SMs::Calc::SM::on::ready::POINT} case POINT_SIG: { static struct { QMState const *target; QActionHandler act[4]; - } const tatbl_ = { /* tran-action table */ - &Calc_operand_s, /* target submachine */ + } const tatbl_ = { // tran-action table + &Calc_operand_s, // target submachine { - Q_ACTION_CAST(&Calc_ready_x), /* exit */ - Q_ACTION_CAST(&Calc_operand1_e), /* entry */ - Q_ACTION_CAST(&Calc_operand_frac_ep), /* EP */ - Q_ACTION_NULL /* zero terminator */ + Q_ACTION_CAST(&Calc_ready_x), // exit + Q_ACTION_CAST(&Calc_operand1_e), // entry + Q_ACTION_CAST(&Calc_operand_frac_ep), // EP + Q_ACTION_NULL // zero terminator } }; BSP_clear(); @@ -561,17 +555,17 @@ static QState Calc_ready(Calc * const me, QEvt const * const e) { status_ = QM_TRAN_EP(&tatbl_); break; } - /*${SMs::Calc::SM::on::ready::OPER} */ + //${SMs::Calc::SM::on::ready::OPER} case OPER_SIG: { static struct { QMState const *target; QActionHandler act[3]; - } const tatbl_ = { /* tran-action table */ - &Calc_opEntered_s, /* target state */ + } const tatbl_ = { // tran-action table + &Calc_opEntered_s, // target state { - Q_ACTION_CAST(&Calc_ready_x), /* exit */ - Q_ACTION_CAST(&Calc_opEntered_e), /* entry */ - Q_ACTION_NULL /* zero terminator */ + Q_ACTION_CAST(&Calc_ready_x), // exit + Q_ACTION_CAST(&Calc_opEntered_e), // entry + Q_ACTION_NULL // zero terminator } }; me->op1 = BSP_get_value(); @@ -587,20 +581,20 @@ static QState Calc_ready(Calc * const me, QEvt const * const e) { return status_; } -/*${SMs::Calc::SM::on::ready::result} ......................................*/ -/*${SMs::Calc::SM::on::ready::result} */ +//${SMs::Calc::SM::on::ready::result} ........................................ +//${SMs::Calc::SM::on::ready::result} static QState Calc_result_e(Calc * const me) { BSP_message("result-ENTRY;"); - (void)me; /* unused parameter */ + Q_UNUSED_PAR(me); return QM_ENTRY(&Calc_result_s); } -/*${SMs::Calc::SM::on::ready::result} */ +//${SMs::Calc::SM::on::ready::result} static QState Calc_result_x(Calc * const me) { BSP_message("result-EXIT;"); - (void)me; /* unused parameter */ + (void)me; // unused parameter return QM_EXIT(&Calc_result_s); } -/*${SMs::Calc::SM::on::ready::result} */ +//${SMs::Calc::SM::on::ready::result} static QState Calc_result(Calc * const me, QEvt const * const e) { QState status_; switch (e->sig) { @@ -609,47 +603,47 @@ static QState Calc_result(Calc * const me, QEvt const * const e) { break; } } - (void)me; /* unused parameter */ + Q_UNUSED_PAR(me); return status_; } -/*${SMs::Calc::SM::on::ready::begin} .......................................*/ -/*${SMs::Calc::SM::on::ready::begin} */ +//${SMs::Calc::SM::on::ready::begin} ......................................... +//${SMs::Calc::SM::on::ready::begin} static QState Calc_begin_e(Calc * const me) { BSP_message("begin-ENTRY;"); - (void)me; /* unused parameter */ + Q_UNUSED_PAR(me); return QM_ENTRY(&Calc_begin_s); } -/*${SMs::Calc::SM::on::ready::begin} */ +//${SMs::Calc::SM::on::ready::begin} static QState Calc_begin_x(Calc * const me) { BSP_message("begin-EXIT;"); - (void)me; /* unused parameter */ + (void)me; // unused parameter return QM_EXIT(&Calc_begin_s); } -/*${SMs::Calc::SM::on::ready::begin} */ +//${SMs::Calc::SM::on::ready::begin} static QState Calc_begin(Calc * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${SMs::Calc::SM::on::ready::begin::OPER} */ + //${SMs::Calc::SM::on::ready::begin::OPER} case OPER_SIG: { - /*${SMs::Calc::SM::on::ready::begin::OPER::[e->key=='-']} */ + //${SMs::Calc::SM::on::ready::begin::OPER::[e->key=='-']} if (Q_EVT_CAST(CalcEvt)->key_code == KEY_MINUS) { static struct { QMState const *target; QActionHandler act[5]; - } const tatbl_ = { /* tran-action table */ - &Calc_operand_s, /* target submachine */ + } const tatbl_ = { // tran-action table + &Calc_operand_s, // target submachine { - Q_ACTION_CAST(&Calc_begin_x), /* exit */ - Q_ACTION_CAST(&Calc_ready_x), /* exit */ - Q_ACTION_CAST(&Calc_operand1_e), /* entry */ - Q_ACTION_CAST(&Calc_operand_neg_ep), /* EP */ - Q_ACTION_NULL /* zero terminator */ + Q_ACTION_CAST(&Calc_begin_x), // exit + Q_ACTION_CAST(&Calc_ready_x), // exit + Q_ACTION_CAST(&Calc_operand1_e), // entry + Q_ACTION_CAST(&Calc_operand_neg_ep), // EP + Q_ACTION_NULL // zero terminator } }; status_ = QM_TRAN_EP(&tatbl_); } - /*${SMs::Calc::SM::on::ready::begin::OPER::[else]} */ + //${SMs::Calc::SM::on::ready::begin::OPER::[else]} else { status_ = QM_HANDLED(); } @@ -660,57 +654,57 @@ static QState Calc_begin(Calc * const me, QEvt const * const e) { break; } } - (void)me; /* unused parameter */ + Q_UNUSED_PAR(me); return status_; } -/*${SMs::Calc::SM::on::opEntered} ..........................................*/ -/*${SMs::Calc::SM::on::opEntered} */ +//${SMs::Calc::SM::on::opEntered} ............................................ +//${SMs::Calc::SM::on::opEntered} static QState Calc_opEntered_e(Calc * const me) { BSP_message("opEntered-ENTRY;"); - (void)me; /* unused parameter */ + Q_UNUSED_PAR(me); return QM_ENTRY(&Calc_opEntered_s); } -/*${SMs::Calc::SM::on::opEntered} */ +//${SMs::Calc::SM::on::opEntered} static QState Calc_opEntered_x(Calc * const me) { BSP_message("opEntered-EXIT;"); - (void)me; /* unused parameter */ + (void)me; // unused parameter return QM_EXIT(&Calc_opEntered_s); } -/*${SMs::Calc::SM::on::opEntered} */ +//${SMs::Calc::SM::on::opEntered} static QState Calc_opEntered(Calc * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${SMs::Calc::SM::on::opEntered::DIGIT_0} */ + //${SMs::Calc::SM::on::opEntered::DIGIT_0} case DIGIT_0_SIG: { static struct { QMState const *target; QActionHandler act[4]; - } const tatbl_ = { /* tran-action table */ - &Calc_operand_s, /* target submachine */ + } const tatbl_ = { // tran-action table + &Calc_operand_s, // target submachine { - Q_ACTION_CAST(&Calc_opEntered_x), /* exit */ - Q_ACTION_CAST(&Calc_operand2_e), /* entry */ - Q_ACTION_CAST(&Calc_operand_zero_ep), /* EP */ - Q_ACTION_NULL /* zero terminator */ + Q_ACTION_CAST(&Calc_opEntered_x), // exit + Q_ACTION_CAST(&Calc_operand2_e), // entry + Q_ACTION_CAST(&Calc_operand_zero_ep), // EP + Q_ACTION_NULL // zero terminator } }; BSP_clear(); status_ = QM_TRAN_EP(&tatbl_); break; } - /*${SMs::Calc::SM::on::opEntered::DIGIT_1_9} */ + //${SMs::Calc::SM::on::opEntered::DIGIT_1_9} case DIGIT_1_9_SIG: { static struct { QMState const *target; QActionHandler act[4]; - } const tatbl_ = { /* tran-action table */ - &Calc_operand_s, /* target submachine */ + } const tatbl_ = { // tran-action table + &Calc_operand_s, // target submachine { - Q_ACTION_CAST(&Calc_opEntered_x), /* exit */ - Q_ACTION_CAST(&Calc_operand2_e), /* entry */ - Q_ACTION_CAST(&Calc_operand_intgr_ep), /* EP */ - Q_ACTION_NULL /* zero terminator */ + Q_ACTION_CAST(&Calc_opEntered_x), // exit + Q_ACTION_CAST(&Calc_operand2_e), // entry + Q_ACTION_CAST(&Calc_operand_intgr_ep), // EP + Q_ACTION_NULL // zero terminator } }; BSP_clear(); @@ -718,18 +712,18 @@ static QState Calc_opEntered(Calc * const me, QEvt const * const e) { status_ = QM_TRAN_EP(&tatbl_); break; } - /*${SMs::Calc::SM::on::opEntered::POINT} */ + //${SMs::Calc::SM::on::opEntered::POINT} case POINT_SIG: { static struct { QMState const *target; QActionHandler act[4]; - } const tatbl_ = { /* tran-action table */ - &Calc_operand_s, /* target submachine */ + } const tatbl_ = { // tran-action table + &Calc_operand_s, // target submachine { - Q_ACTION_CAST(&Calc_opEntered_x), /* exit */ - Q_ACTION_CAST(&Calc_operand2_e), /* entry */ - Q_ACTION_CAST(&Calc_operand_frac_ep), /* EP */ - Q_ACTION_NULL /* zero terminator */ + Q_ACTION_CAST(&Calc_opEntered_x), // exit + Q_ACTION_CAST(&Calc_operand2_e), // entry + Q_ACTION_CAST(&Calc_operand_frac_ep), // EP + Q_ACTION_NULL // zero terminator } }; BSP_clear(); @@ -738,25 +732,25 @@ static QState Calc_opEntered(Calc * const me, QEvt const * const e) { status_ = QM_TRAN_EP(&tatbl_); break; } - /*${SMs::Calc::SM::on::opEntered::OPER} */ + //${SMs::Calc::SM::on::opEntered::OPER} case OPER_SIG: { - /*${SMs::Calc::SM::on::opEntered::OPER::[e->key=='-']} */ + //${SMs::Calc::SM::on::opEntered::OPER::[e->key=='-']} if (Q_EVT_CAST(CalcEvt)->key_code == KEY_MINUS) { static struct { QMState const *target; QActionHandler act[4]; - } const tatbl_ = { /* tran-action table */ - &Calc_operand_s, /* target submachine */ + } const tatbl_ = { // tran-action table + &Calc_operand_s, // target submachine { - Q_ACTION_CAST(&Calc_opEntered_x), /* exit */ - Q_ACTION_CAST(&Calc_operand2_e), /* entry */ - Q_ACTION_CAST(&Calc_operand_neg_ep), /* EP */ - Q_ACTION_NULL /* zero terminator */ + Q_ACTION_CAST(&Calc_opEntered_x), // exit + Q_ACTION_CAST(&Calc_operand2_e), // entry + Q_ACTION_CAST(&Calc_operand_neg_ep), // EP + Q_ACTION_NULL // zero terminator } }; status_ = QM_TRAN_EP(&tatbl_); } - /*${SMs::Calc::SM::on::opEntered::OPER::[else]} */ + //${SMs::Calc::SM::on::opEntered::OPER::[else]} else { status_ = QM_HANDLED(); } @@ -767,64 +761,64 @@ static QState Calc_opEntered(Calc * const me, QEvt const * const e) { break; } } - (void)me; /* unused parameter */ + Q_UNUSED_PAR(me); return status_; } -/*${SMs::Calc::SM::on::operand1} ...........................................*/ -/*${SMs::Calc::SM::on::operand1} */ +//${SMs::Calc::SM::on::operand1} ............................................. +//${SMs::Calc::SM::on::operand1} static QState Calc_operand1_e(Calc * const me) { - me->sub_operand = &Calc_operand1_s; /* attach submachine */ - return Calc_operand_e(me); /* enter submachine */ + me->sub_operand = &Calc_operand1_s; // attach submachine + return Calc_operand_e(me); // enter submachine } -/*${SMs::Calc::SM::on::operand1} */ +//${SMs::Calc::SM::on::operand1} static QState Calc_operand1_CE(Calc * const me) { static struct { QMState const *target; QActionHandler act[4]; - } const tatbl_ = { /* tran-action table */ - &Calc_ready_s, /* target state */ + } const tatbl_ = { // tran-action table + &Calc_ready_s, // target state { - Q_ACTION_CAST(&Calc_operand_x), /* submachine exit */ - Q_ACTION_CAST(&Calc_ready_e), /* entry */ - Q_ACTION_CAST(&Calc_ready_i), /* initial tran. */ - Q_ACTION_NULL /* zero terminator */ + Q_ACTION_CAST(&Calc_operand_x), // submachine exit + Q_ACTION_CAST(&Calc_ready_e), // entry + Q_ACTION_CAST(&Calc_ready_i), // initial tran. + Q_ACTION_NULL // zero terminator } }; - (void)me; /* unused parameter */ + Q_UNUSED_PAR(me); BSP_message("operand1:XP-CE;"); return QM_TRAN(&tatbl_); } -/*${SMs::Calc::SM::on::operand1} */ +//${SMs::Calc::SM::on::operand1} static QState Calc_operand1(Calc * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${SMs::Calc::SM::on::operand1::EQUALS} */ + //${SMs::Calc::SM::on::operand1::EQUALS} case EQUALS_SIG: { static struct { QMState const *target; QActionHandler act[3]; - } const tatbl_ = { /* tran-action table */ - &Calc_result_s, /* target state */ + } const tatbl_ = { // tran-action table + &Calc_result_s, // target state { - Q_ACTION_CAST(&Calc_ready_e), /* entry */ - Q_ACTION_CAST(&Calc_result_e), /* entry */ - Q_ACTION_NULL /* zero terminator */ + Q_ACTION_CAST(&Calc_ready_e), // entry + Q_ACTION_CAST(&Calc_result_e), // entry + Q_ACTION_NULL // zero terminator } }; status_ = QM_TRAN(&tatbl_); break; } - /*${SMs::Calc::SM::on::operand1::OPER} */ + //${SMs::Calc::SM::on::operand1::OPER} case OPER_SIG: { static struct { QMState const *target; QActionHandler act[2]; - } const tatbl_ = { /* tran-action table */ - &Calc_opEntered_s, /* target state */ + } const tatbl_ = { // tran-action table + &Calc_opEntered_s, // target state { - Q_ACTION_CAST(&Calc_opEntered_e), /* entry */ - Q_ACTION_NULL /* zero terminator */ + Q_ACTION_CAST(&Calc_opEntered_e), // entry + Q_ACTION_NULL // zero terminator } }; me->op1 = BSP_get_value(); @@ -840,94 +834,94 @@ static QState Calc_operand1(Calc * const me, QEvt const * const e) { return status_; } -/*${SMs::Calc::SM::on::operand2} ...........................................*/ -/*${SMs::Calc::SM::on::operand2} */ +//${SMs::Calc::SM::on::operand2} ............................................. +//${SMs::Calc::SM::on::operand2} static QState Calc_operand2_e(Calc * const me) { - me->sub_operand = &Calc_operand2_s; /* attach submachine */ - return Calc_operand_e(me); /* enter submachine */ + me->sub_operand = &Calc_operand2_s; // attach submachine + return Calc_operand_e(me); // enter submachine } -/*${SMs::Calc::SM::on::operand2} */ +//${SMs::Calc::SM::on::operand2} static QState Calc_operand2_CE(Calc * const me) { static struct { QMState const *target; QActionHandler act[3]; - } const tatbl_ = { /* tran-action table */ - &Calc_opEntered_s, /* target state */ + } const tatbl_ = { // tran-action table + &Calc_opEntered_s, // target state { - Q_ACTION_CAST(&Calc_operand_x), /* submachine exit */ - Q_ACTION_CAST(&Calc_opEntered_e), /* entry */ - Q_ACTION_NULL /* zero terminator */ + Q_ACTION_CAST(&Calc_operand_x), // submachine exit + Q_ACTION_CAST(&Calc_opEntered_e), // entry + Q_ACTION_NULL // zero terminator } }; - (void)me; /* unused parameter */ + Q_UNUSED_PAR(me); BSP_message("operand2:XP-CE;"); return QM_TRAN(&tatbl_); } -/*${SMs::Calc::SM::on::operand2} */ +//${SMs::Calc::SM::on::operand2} static QState Calc_operand2(Calc * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${SMs::Calc::SM::on::operand2::OPER} */ + //${SMs::Calc::SM::on::operand2::OPER} case OPER_SIG: { - /*${SMs::Calc::SM::on::operand2::OPER::[Calc_eval(me,BSP_get_value(),Q_~} */ + //${SMs::Calc::SM::on::operand2::OPER::[Calc_eval(me,BSP_get_value(),Q_~} if (Calc_eval(me, BSP_get_value(), Q_EVT_CAST(CalcEvt)->key_code)) { static struct { QMState const *target; QActionHandler act[2]; - } const tatbl_ = { /* tran-action table */ - &Calc_opEntered_s, /* target state */ + } const tatbl_ = { // tran-action table + &Calc_opEntered_s, // target state { - Q_ACTION_CAST(&Calc_opEntered_e), /* entry */ - Q_ACTION_NULL /* zero terminator */ + Q_ACTION_CAST(&Calc_opEntered_e), // entry + Q_ACTION_NULL // zero terminator } }; status_ = QM_TRAN(&tatbl_); } - /*${SMs::Calc::SM::on::operand2::OPER::[else]} */ + //${SMs::Calc::SM::on::operand2::OPER::[else]} else { static struct { QMState const *target; QActionHandler act[2]; - } const tatbl_ = { /* tran-action table */ - &Calc_error_s, /* target state */ + } const tatbl_ = { // tran-action table + &Calc_error_s, // target state { - Q_ACTION_CAST(&Calc_error_e), /* entry */ - Q_ACTION_NULL /* zero terminator */ + Q_ACTION_CAST(&Calc_error_e), // entry + Q_ACTION_NULL // zero terminator } }; status_ = QM_TRAN(&tatbl_); } break; } - /*${SMs::Calc::SM::on::operand2::EQUALS} */ + //${SMs::Calc::SM::on::operand2::EQUALS} case EQUALS_SIG: { - /*${SMs::Calc::SM::on::operand2::EQUALS::[Calc_eval(me,BSP_get_value(),KE~} */ + //${SMs::Calc::SM::on::operand2::EQUALS::[Calc_eval(me,BSP_get_value(),KE~} if (Calc_eval(me, BSP_get_value(), KEY_NULL) ) { static struct { QMState const *target; QActionHandler act[3]; - } const tatbl_ = { /* tran-action table */ - &Calc_result_s, /* target state */ + } const tatbl_ = { // tran-action table + &Calc_result_s, // target state { - Q_ACTION_CAST(&Calc_ready_e), /* entry */ - Q_ACTION_CAST(&Calc_result_e), /* entry */ - Q_ACTION_NULL /* zero terminator */ + Q_ACTION_CAST(&Calc_ready_e), // entry + Q_ACTION_CAST(&Calc_result_e), // entry + Q_ACTION_NULL // zero terminator } }; status_ = QM_TRAN(&tatbl_); } - /*${SMs::Calc::SM::on::operand2::EQUALS::[else]} */ + //${SMs::Calc::SM::on::operand2::EQUALS::[else]} else { static struct { QMState const *target; QActionHandler act[2]; - } const tatbl_ = { /* tran-action table */ - &Calc_error_s, /* target state */ + } const tatbl_ = { // tran-action table + &Calc_error_s, // target state { - Q_ACTION_CAST(&Calc_error_e), /* entry */ - Q_ACTION_NULL /* zero terminator */ + Q_ACTION_CAST(&Calc_error_e), // entry + Q_ACTION_NULL // zero terminator } }; status_ = QM_TRAN(&tatbl_); @@ -942,15 +936,15 @@ static QState Calc_operand2(Calc * const me, QEvt const * const e) { return status_; } -/*${SMs::Calc::SM::final} ..................................................*/ -/*${SMs::Calc::SM::final} */ +//${SMs::Calc::SM::final} .................................................... +//${SMs::Calc::SM::final} static QState Calc_final_e(Calc * const me) { BSP_message("final-ENTRY;"); BSP_exit(); - (void)me; /* unused parameter */ + Q_UNUSED_PAR(me); return QM_ENTRY(&Calc_final_s); } -/*${SMs::Calc::SM::final} */ +//${SMs::Calc::SM::final} static QState Calc_final(Calc * const me, QEvt const * const e) { QState status_; switch (e->sig) { @@ -959,32 +953,32 @@ static QState Calc_final(Calc * const me, QEvt const * const e) { break; } } - (void)me; /* unused parameter */ + Q_UNUSED_PAR(me); return status_; } -/*${SMs::Calc::SM::operand} ................................................*/ -/*${SMs::Calc::SM::operand} */ +//${SMs::Calc::SM::operand} .................................................. +//${SMs::Calc::SM::operand} static QState Calc_operand_e(Calc * const me) { BSP_message("operand-ENTRY;"); - (void)me; /* unused parameter */ + Q_UNUSED_PAR(me); return QM_ENTRY(&Calc_operand_s); } -/*${SMs::Calc::SM::operand} */ +//${SMs::Calc::SM::operand} static QState Calc_operand_x(Calc * const me) { BSP_message("operand-EXIT;"); return QM_SM_EXIT(&me->sub_operand->super); } -/*${SMs::Calc::SM::operand} */ +//${SMs::Calc::SM::operand} static QState Calc_operand(Calc * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${SMs::Calc::SM::operand::CE} */ + //${SMs::Calc::SM::operand::CE} case CE_SIG: { - static QMTranActTable const tatbl_ = { /* tran-action table */ - &Calc_operand_s, /* target submachine */ + static QMTranActTable const tatbl_ = { // tran-action table + &Calc_operand_s, // target submachine { - Q_ACTION_NULL /* zero terminator */ + Q_ACTION_NULL // zero terminator } }; BSP_message("operand::CE;"); @@ -999,118 +993,118 @@ static QState Calc_operand(Calc * const me, QEvt const * const e) { } return status_; } -/*${SMs::Calc::SM::operand::EP-zero} */ +//${SMs::Calc::SM::operand::EP-zero} static QState Calc_operand_zero_ep(Calc * const me) { static struct { QMState const *target; QActionHandler act[2]; - } const tatbl_ = { /* tran-action table */ - &Calc_operand_zero_s, /* target state */ + } const tatbl_ = { // tran-action table + &Calc_operand_zero_s, // target state { - Q_ACTION_CAST(&Calc_operand_zero_e), /* entry */ - Q_ACTION_NULL /* zero terminator */ + Q_ACTION_CAST(&Calc_operand_zero_e), // entry + Q_ACTION_NULL // zero terminator } }; BSP_message("operand::EP-zero;"); return QM_TRAN_EP(&tatbl_); } -/*${SMs::Calc::SM::operand::EP-intgr} */ +//${SMs::Calc::SM::operand::EP-intgr} static QState Calc_operand_intgr_ep(Calc * const me) { static struct { QMState const *target; QActionHandler act[2]; - } const tatbl_ = { /* tran-action table */ - &Calc_operand_intgr_s, /* target state */ + } const tatbl_ = { // tran-action table + &Calc_operand_intgr_s, // target state { - Q_ACTION_CAST(&Calc_operand_intgr_e), /* entry */ - Q_ACTION_NULL /* zero terminator */ + Q_ACTION_CAST(&Calc_operand_intgr_e), // entry + Q_ACTION_NULL // zero terminator } }; BSP_message("operand::EP-intgr;"); return QM_TRAN_EP(&tatbl_); } -/*${SMs::Calc::SM::operand::EP-frac} */ +//${SMs::Calc::SM::operand::EP-frac} static QState Calc_operand_frac_ep(Calc * const me) { static struct { QMState const *target; QActionHandler act[2]; - } const tatbl_ = { /* tran-action table */ - &Calc_operand_frac_s, /* target state */ + } const tatbl_ = { // tran-action table + &Calc_operand_frac_s, // target state { - Q_ACTION_CAST(&Calc_operand_frac_e), /* entry */ - Q_ACTION_NULL /* zero terminator */ + Q_ACTION_CAST(&Calc_operand_frac_e), // entry + Q_ACTION_NULL // zero terminator } }; BSP_message("operand::EP-frac;"); return QM_TRAN_EP(&tatbl_); } -/*${SMs::Calc::SM::operand::EP-neg} */ +//${SMs::Calc::SM::operand::EP-neg} static QState Calc_operand_neg_ep(Calc * const me) { static struct { QMState const *target; QActionHandler act[2]; - } const tatbl_ = { /* tran-action table */ - &Calc_operand_negated_s, /* target state */ + } const tatbl_ = { // tran-action table + &Calc_operand_negated_s, // target state { - Q_ACTION_CAST(&Calc_operand_negated_e), /* entry */ - Q_ACTION_NULL /* zero terminator */ + Q_ACTION_CAST(&Calc_operand_negated_e), // entry + Q_ACTION_NULL // zero terminator } }; BSP_message("operand::EP-neg;"); return QM_TRAN_EP(&tatbl_); } -/*${SMs::Calc::SM::operand::zero} ..........................................*/ -/*${SMs::Calc::SM::operand::zero} */ +//${SMs::Calc::SM::operand::zero} ............................................ +//${SMs::Calc::SM::operand::zero} static QState Calc_operand_zero_e(Calc * const me) { BSP_message("zero-ENTRY;"); - (void)me; /* unused parameter */ + Q_UNUSED_PAR(me); return QM_ENTRY(&Calc_operand_zero_s); } -/*${SMs::Calc::SM::operand::zero} */ +//${SMs::Calc::SM::operand::zero} static QState Calc_operand_zero_x(Calc * const me) { BSP_message("zero-EXIT;"); - (void)me; /* unused parameter */ + (void)me; // unused parameter return QM_EXIT(&Calc_operand_zero_s); } -/*${SMs::Calc::SM::operand::zero} */ +//${SMs::Calc::SM::operand::zero} static QState Calc_operand_zero(Calc * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${SMs::Calc::SM::operand::zero::DIGIT_0} */ + //${SMs::Calc::SM::operand::zero::DIGIT_0} case DIGIT_0_SIG: { ; status_ = QM_HANDLED(); break; } - /*${SMs::Calc::SM::operand::zero::DIGIT_1_9} */ + //${SMs::Calc::SM::operand::zero::DIGIT_1_9} case DIGIT_1_9_SIG: { static struct { QMState const *target; QActionHandler act[3]; - } const tatbl_ = { /* tran-action table */ - &Calc_operand_intgr_s, /* target state */ + } const tatbl_ = { // tran-action table + &Calc_operand_intgr_s, // target state { - Q_ACTION_CAST(&Calc_operand_zero_x), /* exit */ - Q_ACTION_CAST(&Calc_operand_intgr_e), /* entry */ - Q_ACTION_NULL /* zero terminator */ + Q_ACTION_CAST(&Calc_operand_zero_x), // exit + Q_ACTION_CAST(&Calc_operand_intgr_e), // entry + Q_ACTION_NULL // zero terminator } }; BSP_insert(Q_EVT_CAST(CalcEvt)->key_code); status_ = QM_TRAN(&tatbl_); break; } - /*${SMs::Calc::SM::operand::zero::POINT} */ + //${SMs::Calc::SM::operand::zero::POINT} case POINT_SIG: { static struct { QMState const *target; QActionHandler act[3]; - } const tatbl_ = { /* tran-action table */ - &Calc_operand_frac_s, /* target state */ + } const tatbl_ = { // tran-action table + &Calc_operand_frac_s, // target state { - Q_ACTION_CAST(&Calc_operand_zero_x), /* exit */ - Q_ACTION_CAST(&Calc_operand_frac_e), /* entry */ - Q_ACTION_NULL /* zero terminator */ + Q_ACTION_CAST(&Calc_operand_zero_x), // exit + Q_ACTION_CAST(&Calc_operand_frac_e), // entry + Q_ACTION_NULL // zero terminator } }; BSP_insert((uint8_t)'0'); @@ -1126,42 +1120,42 @@ static QState Calc_operand_zero(Calc * const me, QEvt const * const e) { return status_; } -/*${SMs::Calc::SM::operand::intgr} .........................................*/ -/*${SMs::Calc::SM::operand::intgr} */ +//${SMs::Calc::SM::operand::intgr} ........................................... +//${SMs::Calc::SM::operand::intgr} static QState Calc_operand_intgr_e(Calc * const me) { BSP_message("intgr-ENTRY;"); - (void)me; /* unused parameter */ + Q_UNUSED_PAR(me); return QM_ENTRY(&Calc_operand_intgr_s); } -/*${SMs::Calc::SM::operand::intgr} */ +//${SMs::Calc::SM::operand::intgr} static QState Calc_operand_intgr_x(Calc * const me) { BSP_message("intgr-EXIT;"); - (void)me; /* unused parameter */ + (void)me; // unused parameter return QM_EXIT(&Calc_operand_intgr_s); } -/*${SMs::Calc::SM::operand::intgr} */ +//${SMs::Calc::SM::operand::intgr} static QState Calc_operand_intgr(Calc * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${SMs::Calc::SM::operand::intgr::POINT} */ + //${SMs::Calc::SM::operand::intgr::POINT} case POINT_SIG: { static struct { QMState const *target; QActionHandler act[3]; - } const tatbl_ = { /* tran-action table */ - &Calc_operand_frac_s, /* target state */ + } const tatbl_ = { // tran-action table + &Calc_operand_frac_s, // target state { - Q_ACTION_CAST(&Calc_operand_intgr_x), /* exit */ - Q_ACTION_CAST(&Calc_operand_frac_e), /* entry */ - Q_ACTION_NULL /* zero terminator */ + Q_ACTION_CAST(&Calc_operand_intgr_x), // exit + Q_ACTION_CAST(&Calc_operand_frac_e), // entry + Q_ACTION_NULL // zero terminator } }; BSP_insert((uint8_t)'.'); status_ = QM_TRAN(&tatbl_); break; } - /*${SMs::Calc::SM::operand::intgr::DIGIT_0, DIGIT_1_9} */ - case DIGIT_0_SIG: /* intentionally fall through */ + //${SMs::Calc::SM::operand::intgr::DIGIT_0, DIGIT_1_9} + case DIGIT_0_SIG: // intentionally fall through case DIGIT_1_9_SIG: { BSP_insert(Q_EVT_CAST(CalcEvt)->key_code); status_ = QM_HANDLED(); @@ -1172,35 +1166,35 @@ static QState Calc_operand_intgr(Calc * const me, QEvt const * const e) { break; } } - (void)me; /* unused parameter */ + Q_UNUSED_PAR(me); return status_; } -/*${SMs::Calc::SM::operand::frac} ..........................................*/ -/*${SMs::Calc::SM::operand::frac} */ +//${SMs::Calc::SM::operand::frac} ............................................ +//${SMs::Calc::SM::operand::frac} static QState Calc_operand_frac_e(Calc * const me) { BSP_message("frac-ENTRY;"); - (void)me; /* unused parameter */ + Q_UNUSED_PAR(me); return QM_ENTRY(&Calc_operand_frac_s); } -/*${SMs::Calc::SM::operand::frac} */ +//${SMs::Calc::SM::operand::frac} static QState Calc_operand_frac_x(Calc * const me) { BSP_message("frac-EXIT;"); - (void)me; /* unused parameter */ + (void)me; // unused parameter return QM_EXIT(&Calc_operand_frac_s); } -/*${SMs::Calc::SM::operand::frac} */ +//${SMs::Calc::SM::operand::frac} static QState Calc_operand_frac(Calc * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${SMs::Calc::SM::operand::frac::POINT} */ + //${SMs::Calc::SM::operand::frac::POINT} case POINT_SIG: { ; status_ = QM_HANDLED(); break; } - /*${SMs::Calc::SM::operand::frac::DIGIT_0, DIGIT_1_9} */ - case DIGIT_0_SIG: /* intentionally fall through */ + //${SMs::Calc::SM::operand::frac::DIGIT_0, DIGIT_1_9} + case DIGIT_0_SIG: // intentionally fall through case DIGIT_1_9_SIG: { BSP_insert(Q_EVT_CAST(CalcEvt)->key_code); status_ = QM_HANDLED(); @@ -1211,87 +1205,87 @@ static QState Calc_operand_frac(Calc * const me, QEvt const * const e) { break; } } - (void)me; /* unused parameter */ + Q_UNUSED_PAR(me); return status_; } -/*${SMs::Calc::SM::operand::negated} .......................................*/ -/*${SMs::Calc::SM::operand::negated} */ +//${SMs::Calc::SM::operand::negated} ......................................... +//${SMs::Calc::SM::operand::negated} static QState Calc_operand_negated_e(Calc * const me) { BSP_message("negated-ENTRY;"); BSP_negate(); - (void)me; /* unused parameter */ + Q_UNUSED_PAR(me); return QM_ENTRY(&Calc_operand_negated_s); } -/*${SMs::Calc::SM::operand::negated} */ +//${SMs::Calc::SM::operand::negated} static QState Calc_operand_negated_x(Calc * const me) { BSP_message("negated-EXIT;"); - (void)me; /* unused parameter */ + (void)me; // unused parameter return QM_EXIT(&Calc_operand_negated_s); } -/*${SMs::Calc::SM::operand::negated} */ +//${SMs::Calc::SM::operand::negated} static QState Calc_operand_negated(Calc * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${SMs::Calc::SM::operand::negated::DIGIT_0} */ + //${SMs::Calc::SM::operand::negated::DIGIT_0} case DIGIT_0_SIG: { static struct { QMState const *target; QActionHandler act[3]; - } const tatbl_ = { /* tran-action table */ - &Calc_operand_zero_s, /* target state */ + } const tatbl_ = { // tran-action table + &Calc_operand_zero_s, // target state { - Q_ACTION_CAST(&Calc_operand_negated_x), /* exit */ - Q_ACTION_CAST(&Calc_operand_zero_e), /* entry */ - Q_ACTION_NULL /* zero terminator */ + Q_ACTION_CAST(&Calc_operand_negated_x), // exit + Q_ACTION_CAST(&Calc_operand_zero_e), // entry + Q_ACTION_NULL // zero terminator } }; BSP_insert(Q_EVT_CAST(CalcEvt)->key_code); status_ = QM_TRAN(&tatbl_); break; } - /*${SMs::Calc::SM::operand::negated::DIGIT_1_9} */ + //${SMs::Calc::SM::operand::negated::DIGIT_1_9} case DIGIT_1_9_SIG: { static struct { QMState const *target; QActionHandler act[3]; - } const tatbl_ = { /* tran-action table */ - &Calc_operand_intgr_s, /* target state */ + } const tatbl_ = { // tran-action table + &Calc_operand_intgr_s, // target state { - Q_ACTION_CAST(&Calc_operand_negated_x), /* exit */ - Q_ACTION_CAST(&Calc_operand_intgr_e), /* entry */ - Q_ACTION_NULL /* zero terminator */ + Q_ACTION_CAST(&Calc_operand_negated_x), // exit + Q_ACTION_CAST(&Calc_operand_intgr_e), // entry + Q_ACTION_NULL // zero terminator } }; BSP_insert(Q_EVT_CAST(CalcEvt)->key_code); status_ = QM_TRAN(&tatbl_); break; } - /*${SMs::Calc::SM::operand::negated::POINT} */ + //${SMs::Calc::SM::operand::negated::POINT} case POINT_SIG: { static struct { QMState const *target; QActionHandler act[3]; - } const tatbl_ = { /* tran-action table */ - &Calc_operand_frac_s, /* target state */ + } const tatbl_ = { // tran-action table + &Calc_operand_frac_s, // target state { - Q_ACTION_CAST(&Calc_operand_negated_x), /* exit */ - Q_ACTION_CAST(&Calc_operand_frac_e), /* entry */ - Q_ACTION_NULL /* zero terminator */ + Q_ACTION_CAST(&Calc_operand_negated_x), // exit + Q_ACTION_CAST(&Calc_operand_frac_e), // entry + Q_ACTION_NULL // zero terminator } }; BSP_insert(Q_EVT_CAST(CalcEvt)->key_code); status_ = QM_TRAN(&tatbl_); break; } - /*${SMs::Calc::SM::operand::negated::OPER} */ + //${SMs::Calc::SM::operand::negated::OPER} case OPER_SIG: { - /*${SMs::Calc::SM::operand::negated::OPER::[e->key=='-']} */ + //${SMs::Calc::SM::operand::negated::OPER::[e->key=='-']} if (Q_EVT_CAST(CalcEvt)->key_code == KEY_MINUS) { ; status_ = QM_HANDLED(); } - /*${SMs::Calc::SM::operand::negated::OPER::[else]} */ + //${SMs::Calc::SM::operand::negated::OPER::[else]} else { status_ = QM_HANDLED(); } @@ -1302,7 +1296,7 @@ static QState Calc_operand_negated(Calc * const me, QEvt const * const e) { break; } } - (void)me; /* unused parameter */ + Q_UNUSED_PAR(me); return status_; } -/*$enddef${SMs::Calc} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$enddef${SMs::Calc} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/examples/posix-win32/calc_sub/calc_sub.h b/examples/posix-win32/calc_sub/calc_sub.h new file mode 100644 index 00000000..3a144ec5 --- /dev/null +++ b/examples/posix-win32/calc_sub/calc_sub.h @@ -0,0 +1,64 @@ +//$file${.::calc_sub.h} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// +// Model: calc_sub.qm +// File: ${.::calc_sub.h} +// +// This code has been generated by QM 5.3.0 . +// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. +// +// SPDX-License-Identifier: GPL-3.0-or-later +// +// This generated code is open source software: you can redistribute it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation. +// +// This code is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// NOTE: +// Alternatively, this generated code may be distributed under the terms +// of Quantum Leaps commercial licenses, which expressly supersede the GNU +// General Public License and are specifically designed for licensees +// interested in retaining the proprietary status of their code. +// +// Contact information: +// +// +// +//$endhead${.::calc_sub.h} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +#ifndef CALC_SUB_H_ +#define CALC_SUB_H_ + +enum CalcSignals { + C_SIG = Q_USER_SIG, + CE_SIG, + DIGIT_0_SIG, + DIGIT_1_9_SIG, + POINT_SIG, + OPER_SIG, + EQUALS_SIG, + OFF_SIG +}; + +//$declare${Events::CalcEvt} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${Events::CalcEvt} ......................................................... +typedef struct { +// protected: + QEvt super; + +// public: + uint8_t key_code; +} CalcEvt; +//$enddecl${Events::CalcEvt} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +//$declare${SMs::Calc_ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${SMs::Calc_ctor} .......................................................... +void Calc_ctor(void); +//$enddecl${SMs::Calc_ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +extern QAsm * const the_calc; // "opaque" pointer to calculator SM + +#endif // CALC_SUB_H_ diff --git a/examples/workstation/calc1_sub/calc1_sub.qm b/examples/posix-win32/calc_sub/calc_sub.qm similarity index 94% rename from examples/workstation/calc1_sub/calc1_sub.qm rename to examples/posix-win32/calc_sub/calc_sub.qm index 792235d8..713ee74e 100644 --- a/examples/workstation/calc1_sub/calc1_sub.qm +++ b/examples/posix-win32/calc_sub/calc_sub.qm @@ -1,5 +1,5 @@ - + The improved Calculator model with QMsm state machine implementation strategy and Sub-Machines. @@ -30,11 +30,11 @@ - /* guard function to evaluate the current expression + // guard function to evaluate the current expression * taking into account the precedence of operands. * return: true if evaluation successfull * false when error encountered -*/ + @@ -48,13 +48,13 @@ if ((oper == KEY_NULL) || (oper == KEY_PLUS) || (oper == KEY_MINUS)) { } case KEY_DIVIDE: { if ((-1e-30 < op) && (op < 1e-30)) { - BSP_display_error(" Error 0 "); /* divide by zero */ + BSP_display_error(" Error 0 "); // divide by zero return false; } me->op2 /= op; break; } - default: { /* no op2 yet */ + default: { // no op2 yet me->op2 = op; me->oper2 = oper; break; @@ -75,7 +75,7 @@ if ((oper == KEY_NULL) || (oper == KEY_PLUS) || (oper == KEY_MINUS)) { } case KEY_DIVIDE: { if ((-1e-30 < me->op2) && (me->op2 < 1e-30)) { - BSP_display_error(" Error 0 "); /* divide by zero */ + BSP_display_error(" Error 0 "); // divide by zero return false; } me->op1 /= me->op2; @@ -90,7 +90,7 @@ if ((oper == KEY_NULL) || (oper == KEY_PLUS) || (oper == KEY_MINUS)) { me->oper2 = KEY_NULL; result = me->op1; } -else { /* (oper == KEY_MULT) || (oper == KEY_DIV) */ +else { // (oper == KEY_MULT) || (oper == KEY_DIV) switch (me->oper2) { case KEY_MULT: { me->op2 *= op; @@ -98,13 +98,13 @@ else { /* (oper == KEY_MULT) || (oper == KEY_DIV) */ } case KEY_DIVIDE: { if ((-1e-30 < op) && (op < 1e-30)) { - BSP_display_error(" Error 0 "); /* divide by zero */ + BSP_display_error(" Error 0 "); // divide by zero return false; } me->op2 /= op; break; } - default: { /* oper2 not provided yet */ + default: { // oper2 not provided yet me->op2 = op; break; } @@ -114,7 +114,7 @@ else { /* (oper == KEY_MULT) || (oper == KEY_DIV) */ } if ((result < -99999999.0) || (99999999.0 < result)) { - BSP_display_error(" Error 1 "); /* out of range */ + BSP_display_error(" Error 1 "); // out of range return false; } if ((-0.0000001 < result) && (result < 0.0000001)) { @@ -128,7 +128,7 @@ return true; - (void)par; /* unused parameter */ + (void)par; // unused parameter @@ -159,9 +159,9 @@ BSP_clear(); - /* Error state after evaluation of an expression. + // Error state after evaluation of an expression. This state can be exited only throgh the inherited C (Clear) event. -*/ + BSP_message("error-ENTRY;"); BSP_message("error-EXIT;"); @@ -587,8 +587,8 @@ BSP_negate(); - - Opaque pointer to the Calc HSM + + Opaque pointer to the Calc SM = &Calc_inst.super.super; @@ -600,10 +600,10 @@ QMsm_ctor(&me->super, Q_STATE_CAST(&Calc_initial)); - - - #ifndef CALC1_SUB_H -#define CALC1_SUB_H + + + #ifndef CALC_SUB_H_ +#define CALC_SUB_H_ enum CalcSignals { C_SIG = Q_USER_SIG, @@ -619,16 +619,15 @@ enum CalcSignals { $declare${Events::CalcEvt} $declare${SMs::Calc_ctor} -extern QHsm * const the_calc; /* "opaque" pointer to calculator HSM */ +extern QAsm * const the_calc; // "opaque" pointer to calculator SM -#endif /* CALC1_SUB_H */ - +#endif // CALC_SUB_H_ - - - #include "qpc.h" /* QP/C */ -#include "bsp.h" /* board support package */ -#include "calc1_sub.h" /* application */ + + + #include "qpc.h" // QP/C +#include "bsp.h" // board support package +#include "calc_sub.h" // application Q_DEFINE_THIS_FILE diff --git a/examples/workstation/calc1_sub/lint-plus/README.txt b/examples/posix-win32/calc_sub/lint-plus/README.txt similarity index 100% rename from examples/workstation/calc1_sub/lint-plus/README.txt rename to examples/posix-win32/calc_sub/lint-plus/README.txt diff --git a/examples/workstation/calc1_sub/lint-plus/lin.bat b/examples/posix-win32/calc_sub/lint-plus/lin.bat similarity index 82% rename from examples/workstation/calc1_sub/lint-plus/lin.bat rename to examples/posix-win32/calc_sub/lint-plus/lin.bat index 0d3e52e3..3a465fa5 100644 --- a/examples/workstation/calc1_sub/lint-plus/lin.bat +++ b/examples/posix-win32/calc_sub/lint-plus/lin.bat @@ -26,15 +26,15 @@ @setlocal :: usage of lin.bat -@echo Usage: lin [16bit] [-d...] [files...] +@echo Usage: lin [16bit] [-u...] files @echo examples: -@echo lin ..\table.c : use 32bit CPU (default) for linting ..\table.c -@echo lin 16bit -dQ_SPY ..\philo.c : use 16bit CPU and define Q_SPY for linting ..\philo.c -@echo lin ..\philo.c ..\table.c : use 32bit CPU for linting ..\philo.c and ..\table.c +@echo lin files : use 32bit CPU (default) for linting files +@echo lin 16bit -uQ_SPY files : use 16bit CPU and undefine Q_SPY for linting files @echo. :: NOTE: adjust to for your installation directory of PC-Lint-Plus -@set PCLP=C:\tools\lint-plus\windows\pclp64.exe +@set PCLP=C:\tools\lint-plus2\windows\pclp64.exe +@echo %PCLP% if NOT exist "%PCLP%" ( @echo The PC-Lint-Plus toolset not found. Please adjust lin.bat @@ -46,17 +46,16 @@ set QPC=..\..\..\.. set QPC_LINT=%QPC%\ports\lint-plus if "%1"=="16bit" ( - set LINTFLAGS=%QPC_LINT%\std.lnt -i%QPC_LINT%\16bit options.lnt %2 %3 %4 %5 %6 %7 %8 @echo 16bit CPU + set LINTFLAGS=%QPC_LINT%\std.lnt -i%QPC_LINT%\16bit options.lnt %2 %3 %4 %5 %6 %7 %8 ) else ( - set LINTFLAGS=%QPC_LINT%\std.lnt -i%QPC_LINT%\32bit options.lnt %1 %2 %3 %4 %6 %7 %8 @echo 32bit CPU (default) + set LINTFLAGS=%QPC_LINT%\std.lnt -i%QPC_LINT%\32bit options.lnt %1 %2 %3 %4 %5 %6 %7 ) :: cleanup @del *.log - :: linting ------------------------------------------------------------------- %PCLP% -os(lint_out.log) %LINTFLAGS% diff --git a/examples/workstation/calc1_sub/lint-plus/options.lnt b/examples/posix-win32/calc_sub/lint-plus/options.lnt similarity index 85% rename from examples/workstation/calc1_sub/lint-plus/options.lnt rename to examples/posix-win32/calc_sub/lint-plus/options.lnt index b258c8b5..e585c6d4 100644 --- a/examples/workstation/calc1_sub/lint-plus/options.lnt +++ b/examples/posix-win32/calc_sub/lint-plus/options.lnt @@ -33,22 +33,24 @@ -i.. // application includes -i%QPC%\include // QP/C public includes -i%QPC_LINT% // QP/C lint "port" --i%QPC_LINT%\qk // QP/C lint "port" to QK +-i%QPC_LINT%\qv // QP/C lint "port" to QV // standards -%QPC_LINT%\au-misra3.lnt // MISRA-C:2012 options -%QPC_LINT%\au-misra3-amd1.lnt // MISRA-C:2012 amendment 1 options -%QPC_LINT%\au-misra3-amd2.lnt // MISRA-C:2012 amendment 2 options -%QPC_LINT%\au-ds.lnt // Dan Saks recommendations -//-strong(AXJ) // Strong type checking +%QPC_LINT%\au-misra4.lnt // MISRA-C:2023 options +%QPC_LINT%\au-ds.lnt // Dan Saks recommendations +//-strong(AXJ) // Strong type checking // size/alignment options (included from ports/lint-plus/??bits) cpu.lnt // for the chosen CPU +// defined macros (might be undefined on command-line with -u) +-dQ_SPY +-dQ_UTEST +-dQP_API_VERSION=9999 // the latest API only + //============================================================================ // QP/C options for clients qpc.lnt // QP/C options --dQP_API_VERSION=9999 // the latest API only //============================================================================ // additional supporession rules for bulding this application diff --git a/examples/posix-win32/calc_sub/main.c b/examples/posix-win32/calc_sub/main.c new file mode 100644 index 00000000..9dcbf65a --- /dev/null +++ b/examples/posix-win32/calc_sub/main.c @@ -0,0 +1,134 @@ +//============================================================================ +// Product: calc1_sub Example +// Last updated for version 7.3.0 +// Last updated on 2023-07-27 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// This program is open source software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Alternatively, this program may be distributed and modified under the +// terms of Quantum Leaps commercial licenses, which expressly supersede +// the GNU General Public License and are specifically designed for +// licensees interested in retaining the proprietary status of their code. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Contact information: +// +// +//============================================================================ +#include "qpc.h" +#include "bsp.h" +#include "calc_sub.h" + +#include "safe_std.h" // portable "safe" / facilities + +Q_DEFINE_THIS_FILE + +//............................................................................ +int main(void) { + + QF_init(); + QF_onStartup(); + + PRINTF_S("Calculator example, QP version: %s\n" + "Press '0' .. '9' to enter a digit\n" + "Press '.' to enter the decimal point\n" + "Press '+' to add\n" + "Press '-' to subtract or negate a number\n" + "Press '*' to multiply\n" + "Press '/' to divide\n" + "Press '=' or to get the result\n" + "Press 'c' or 'C' to Cancel\n" + "Press 'e' or 'E' to Cancel Entry\n" + "Press to quit.\n\n", + QP_VERSION_STR); + + Calc_ctor(); // explicitly instantiate the calculator object + QASM_INIT(the_calc, (void *)0, 0U); // trigger initial transition + + for (;;) { // event loop + CalcEvt e = { QEVT_INITIALIZER(0U), 0U}; // Calculator event + + BSP_show_display(); // show the display + + PRINTF_S("%s"," : "); + fflush(stdout); + e.key_code = (uint8_t)QF_consoleWaitForKey(); + PRINTF_S("%c ", (e.key_code >= ' ') ? e.key_code : 'X'); + + switch (e.key_code) { + case 'c': // intentionally fall through + case 'C': { + e.super.sig = C_SIG; + break; + } + case 'e': // intentionally fall through + case 'E': { + e.super.sig = CE_SIG; + break; + } + case '0': { + e.super.sig = DIGIT_0_SIG; + break; + } + case '1': // intentionally fall through + case '2': // intentionally fall through + case '3': // intentionally fall through + case '4': // intentionally fall through + case '5': // intentionally fall through + case '6': // intentionally fall through + case '7': // intentionally fall through + case '8': // intentionally fall through + case '9': { + e.super.sig = DIGIT_1_9_SIG; + break; + } + case '.': { + e.super.sig = POINT_SIG; + break; + } + case '+': // intentionally fall through + case '-': // intentionally fall through + case '*': // intentionally fall through + case '/': { + e.super.sig = OPER_SIG; + break; + } + case '=': // intentionally fall through + case '\r': { // Enter key + e.super.sig = EQUALS_SIG; + break; + } + case '\33': { // ESC key + e.super.sig = OFF_SIG; + break; + } + default: { + e.super.sig = 0; // invalid event + break; + } + } + + if (e.super.sig != 0) { // valid event generated? + QASM_DISPATCH(the_calc, &e.super, 0U); // dispatch event + } + } + + QF_onCleanup(); + return 0; +} diff --git a/examples/workstation/comp/Makefile b/examples/posix-win32/comp/Makefile similarity index 99% rename from examples/workstation/comp/Makefile rename to examples/posix-win32/comp/Makefile index 379cc42f..167b4c2d 100644 --- a/examples/workstation/comp/Makefile +++ b/examples/posix-win32/comp/Makefile @@ -243,7 +243,7 @@ CPP_DEPS_EXT := $(patsubst %.o,%.d, $(CPP_OBJS_EXT)) all: $(TARGET_EXE) $(TARGET_EXE) : $(C_OBJS_EXT) $(CPP_OBJS_EXT) - $(CC) $(CFLAGS) $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o + $(CC) $(CFLAGS) $(QPC)/src/qs/qstamp.c -o $(BIN_DIR)/qstamp.o $(LINK) $(LINKFLAGS) $(LIB_DIRS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) $(BIN_DIR)/%.d : %.c diff --git a/examples/posix-win32/comp/alarm.c b/examples/posix-win32/comp/alarm.c new file mode 100644 index 00000000..13dcfc1d --- /dev/null +++ b/examples/posix-win32/comp/alarm.c @@ -0,0 +1,163 @@ +//$file${.::alarm.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// +// Model: comp.qm +// File: ${.::alarm.c} +// +// This code has been generated by QM 5.3.0 . +// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. +// +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// SPDX-License-Identifier: GPL-3.0-or-later +// +// This generated code is open source software: you can redistribute it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation. +// +// This code is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// NOTE: +// Alternatively, this generated code may be distributed under the terms +// of Quantum Leaps commercial licenses, which expressly supersede the GNU +// General Public License and are specifically designed for licensees +// interested in retaining the proprietary status of their code. +// +// Contact information: +// +// +// +//$endhead${.::alarm.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +#include "qpc.h" +#include "bsp.h" +#include "alarm.h" +#include "clock.h" + +//Q_DEFINE_THIS_FILE + +// Alarm component -------------------- +//$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// Check for the minimum required QP version +#if (QP_VERSION < 730U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) +#error qpc version 7.3.0 or higher required +#endif +//$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +//$define${Components::Alarm} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${Components::Alarm} ....................................................... + +//${Components::Alarm::ctor} ................................................. +void Alarm_ctor(Alarm * const me) { + QHsm_ctor(&me->super, Q_STATE_CAST(&Alarm_initial)); +} + +//${Components::Alarm::SM} ................................................... +QState Alarm_initial(Alarm * const me, void const * const par) { + //${Components::Alarm::SM::initial} + me->alarm_time = 12U*60U; + (void)par; // unused parameter + return Q_TRAN(&Alarm_off); +} + +//${Components::Alarm::SM::off} .............................................. +QState Alarm_off(Alarm * const me, QEvt const * const e) { + QState status_; + switch (e->sig) { + //${Components::Alarm::SM::off} + case Q_ENTRY_SIG: { + // while in the off state, the alarm is kept in decimal format + me->alarm_time = (me->alarm_time/60)*100 + me->alarm_time%60; + BSP_showTime24H("*** Alarm OFF ", me->alarm_time, 100U); + status_ = Q_HANDLED(); + break; + } + //${Components::Alarm::SM::off} + case Q_EXIT_SIG: { + // upon exit, the alarm is converted to binary format + me->alarm_time = (me->alarm_time/100U)*60U + me->alarm_time%100U; + status_ = Q_HANDLED(); + break; + } + //${Components::Alarm::SM::off::ALARM_ON} + case ALARM_ON_SIG: { + //${Components::Alarm::SM::off::ALARM_ON::[alarminrange?]} + if ((me->alarm_time / 100U < 24U) + && (me->alarm_time % 100U < 60U)) + { + status_ = Q_TRAN(&Alarm_on); + } + //${Components::Alarm::SM::off::ALARM_ON::[else]} + else { + me->alarm_time = 0U; + BSP_showTime24H("*** Alarm reset", me->alarm_time, 100U); + status_ = Q_HANDLED(); + } + break; + } + //${Components::Alarm::SM::off::ALARM_SET} + case ALARM_SET_SIG: { + // while setting, the alarm is kept in decimal format + me->alarm_time = (10U * me->alarm_time + + ((SetEvt const *)e)->digit) % 10000U; + BSP_showTime24H("*** Alarm reset ", me->alarm_time, 100U); + status_ = Q_HANDLED(); + break; + } + default: { + status_ = Q_SUPER(&QHsm_top); + break; + } + } + return status_; +} + +//${Components::Alarm::SM::on} ............................................... +QState Alarm_on(Alarm * const me, QEvt const * const e) { + QState status_; + switch (e->sig) { + //${Components::Alarm::SM::on} + case Q_ENTRY_SIG: { + BSP_showTime24H("*** Alarm ON ", me->alarm_time, 60U); + status_ = Q_HANDLED(); + break; + } + //${Components::Alarm::SM::on::ALARM_OFF} + case ALARM_OFF_SIG: { + status_ = Q_TRAN(&Alarm_off); + break; + } + //${Components::Alarm::SM::on::ALARM_SET} + case ALARM_SET_SIG: { + BSP_showMsg("*** Cannot set Alarm when it is ON"); + status_ = Q_HANDLED(); + break; + } + //${Components::Alarm::SM::on::TIME} + case TIME_SIG: { + //${Components::Alarm::SM::on::TIME::[Q_EVT_CAST(TimeEvt)->current_ti~} + if (Q_EVT_CAST(TimeEvt)->current_time == me->alarm_time) { + BSP_showMsg("ALARM!!!"); + + // asynchronously post the event to the container AO + QACTIVE_POST(APP_alarmClock, Q_NEW(QEvt, ALARM_SIG), me); + status_ = Q_HANDLED(); + } + else { + status_ = Q_UNHANDLED(); + } + break; + } + default: { + status_ = Q_SUPER(&QHsm_top); + break; + } + } + return status_; +} +//$enddef${Components::Alarm} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/examples/posix-win32/comp/alarm.h b/examples/posix-win32/comp/alarm.h new file mode 100644 index 00000000..d466112c --- /dev/null +++ b/examples/posix-win32/comp/alarm.h @@ -0,0 +1,63 @@ +//$file${.::alarm.h} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// +// Model: comp.qm +// File: ${.::alarm.h} +// +// This code has been generated by QM 5.3.0 . +// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. +// +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// SPDX-License-Identifier: GPL-3.0-or-later +// +// This generated code is open source software: you can redistribute it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation. +// +// This code is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// NOTE: +// Alternatively, this generated code may be distributed under the terms +// of Quantum Leaps commercial licenses, which expressly supersede the GNU +// General Public License and are specifically designed for licensees +// interested in retaining the proprietary status of their code. +// +// Contact information: +// +// +// +//$endhead${.::alarm.h} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +#ifndef ALARM_H_ +#define ALARM_H_ + +//$declare${Components::Alarm} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${Components::Alarm} ....................................................... +typedef struct { +// protected: + QHsm super; + +// private: + uint32_t alarm_time; +} Alarm; + +// public: +void Alarm_ctor(Alarm * const me); + +// protected: +QState Alarm_initial(Alarm * const me, void const * const par); +QState Alarm_off(Alarm * const me, QEvt const * const e); +QState Alarm_on(Alarm * const me, QEvt const * const e); +//$enddecl${Components::Alarm} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +//$declare${Components::Alarm::ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +void Alarm_ctor(Alarm * const me); +//$enddecl${Components::Alarm::ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +#endif // ALARM_H_ diff --git a/examples/posix-win32/comp/bsp.c b/examples/posix-win32/comp/bsp.c new file mode 100644 index 00000000..a244a360 --- /dev/null +++ b/examples/posix-win32/comp/bsp.c @@ -0,0 +1,145 @@ +//============================================================================ +// Product: Console-based BSP +// Last Updated for Version: 6.3.6 +// Date of the Last Update: 2018-10-14 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// This program is open source software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Alternatively, this program may be distributed and modified under the +// terms of Quantum Leaps commercial licenses, which expressly supersede +// the GNU General Public License and are specifically designed for +// licensees interested in retaining the proprietary status of their code. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Contact information: +// +// +//============================================================================ +#include "qpc.h" +#include "clock.h" +#include "bsp.h" + +#include "safe_std.h" // portable "safe" / facilities +#include // for exit() + +//Q_DEFINE_THIS_FILE + +//............................................................................ +void BSP_init(int argc, char *argv[]) { + (void)argc; // unused parameter + (void)argv; // unused parameter +} +//............................................................................ +void BSP_showMsg(char const *str) { + PRINTF_S("%s\n", str); + fflush(stdout); +} +//............................................................................ +void BSP_showTime24H(char const *str, uint32_t time, uint32_t base) { + PRINTF_S("%s, %02d:%02d\n", str, (int)(time / base), (int)(time % base)); + fflush(stdout); +} +//............................................................................ +void BSP_showTime12H(char const *str, uint32_t time, uint32_t base) { + uint32_t h = time / base; + + PRINTF_S("%s %02d:%02d %s\n", str, (h % 12) ? (h % 12) : 12, + time % base, (h / 12) ? "PM" : "AM"); + fflush(stdout); +} +//............................................................................ +void QF_onStartup(void) { + QF_setTickRate(BSP_TICKS_PER_SEC, 30); // set the desired tick rate + QF_consoleSetup(); +} +//............................................................................ +void QF_onCleanup(void) { + PRINTF_S("\n%s\n", "Bye! Bye!"); + QF_consoleCleanup(); +} +//............................................................................ +void QF_onClockTick(void) { + QTIMEEVT_TICK_X(0U, &l_clock_tick); // perform the QF clock tick processing + int key = QF_consoleGetKey(); + if (key != 0) { // any key pressed? + BSP_onKeyboardInput((uint8_t)key); + } +} +//............................................................................ +void BSP_onKeyboardInput(uint8_t key) { + switch (key) { + case 'o': { // 'o': Alarm on event? + QACTIVE_POST(APP_alarmClock, + Q_NEW(QEvt, ALARM_ON_SIG), (void *)0); + break; + } + case 'f': { // 'f': Alarm off event? + QACTIVE_POST(APP_alarmClock, + Q_NEW(QEvt, ALARM_OFF_SIG), (void *)0); + break; + } + case '1': // '1' + case '2': // '2' + case '3': // '3' + case '4': // '4' + case '5': // '5' + case '6': // '6' + case '7': // '7' + case '8': // '8' + case '9': { // '9' + SetEvt *e = Q_NEW(SetEvt, ALARM_SET_SIG); + e->digit = (uint8_t)(key - '0'); + QACTIVE_POST(APP_alarmClock, (QEvt *)e, (void *)0); + break; + } + case '0': { // '0' + SetEvt *e = Q_NEW(SetEvt, ALARM_SET_SIG); + e->digit = 0; + QACTIVE_POST(APP_alarmClock, (QEvt *)e, (void *)0); + break; + } + case 'a': { // 'a': Clock 12H event? + QACTIVE_POST(APP_alarmClock, + Q_NEW(QEvt, CLOCK_12H_SIG), (void *)0); + break; + } + case 'b': { // 'b': Clock 24H event? + QACTIVE_POST(APP_alarmClock, + Q_NEW(QEvt, CLOCK_24H_SIG), (void *)0); + break; + } + case '\33': { // ESC pressed? + QACTIVE_POST(APP_alarmClock, + Q_NEW(QEvt, TERMINATE_SIG), (void *)0); + break; + } + } +} + +//............................................................................ +Q_NORETURN Q_onError(char const * const module, int_t const id) { + FPRINTF_S(stderr, "ERROR in %s, line %d", module, id); + exit(-1); +} +//............................................................................ +void assert_failed(char const * const module, int_t const id); // prototype +void assert_failed(char const * const module, int_t const id) { + Q_onError(module, id); +} + diff --git a/examples/posix-win32/comp/bsp.h b/examples/posix-win32/comp/bsp.h new file mode 100644 index 00000000..7d78dfc5 --- /dev/null +++ b/examples/posix-win32/comp/bsp.h @@ -0,0 +1,46 @@ +//============================================================================ +// Product: Console-based BSP +// Last Updated for Version: 5.3.1 +// Date of the Last Update: 2014-10-15 +// +// Q u a n t u m L e a P s +// --------------------------- +// innovating embedded systems +// +// Copyright (C) 2005 Quantum Leaps, LLC. www.state-machine.com. +// +// This program is open source software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Alternatively, this program may be distributed and modified under the +// terms of Quantum Leaps commercial licenses, which expressly supersede +// the GNU General Public License and are specifically designed for +// licensees interested in retaining the proprietary status of their code. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Contact information: +// Web: +// +//============================================================================ +#ifndef BSP_H_ +#define BSP_H_ + +void BSP_init(int argc, char *argv[]); +void BSP_onKeyboardInput(uint8_t key); // process the keyboard scan code + +#define BSP_TICKS_PER_SEC 100U + +void BSP_showMsg(char const *str); +void BSP_showTime12H(char const *str, uint32_t time, uint32_t base); +void BSP_showTime24H(char const *str, uint32_t time, uint32_t base); + +#endif // BSP_H_ diff --git a/examples/posix-win32/comp/clock.c b/examples/posix-win32/comp/clock.c new file mode 100644 index 00000000..4931c1c9 --- /dev/null +++ b/examples/posix-win32/comp/clock.c @@ -0,0 +1,268 @@ +//$file${.::clock.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// +// Model: comp.qm +// File: ${.::clock.c} +// +// This code has been generated by QM 5.3.0 . +// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. +// +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// SPDX-License-Identifier: GPL-3.0-or-later +// +// This generated code is open source software: you can redistribute it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation. +// +// This code is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// NOTE: +// Alternatively, this generated code may be distributed under the terms +// of Quantum Leaps commercial licenses, which expressly supersede the GNU +// General Public License and are specifically designed for licensees +// interested in retaining the proprietary status of their code. +// +// Contact information: +// +// +// +//$endhead${.::clock.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +#include "qpc.h" +#include "bsp.h" +#include "alarm.h" +#include "clock.h" + +#include "safe_std.h" // portable "safe" / facilities + +Q_DEFINE_THIS_FILE + +// Active object class ----------------------------------------------------- +//$declare${Components::AlarmClock} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${Components::AlarmClock} .................................................. +typedef struct { +// protected: + QActive super; + +// private: + uint32_t current_time; + Alarm alarm; + +// public: + QTimeEvt timeEvt; +} AlarmClock; + +// protected: +static QState AlarmClock_initial(AlarmClock * const me, void const * const par); +static QState AlarmClock_timekeeping(AlarmClock * const me, QEvt const * const e); +static QState AlarmClock_mode24h(AlarmClock * const me, QEvt const * const e); +static QState AlarmClock_mode12h(AlarmClock * const me, QEvt const * const e); +static QState AlarmClock_final(AlarmClock * const me, QEvt const * const e); +//$enddecl${Components::AlarmClock} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +// Local objects ----------------------------------------------------------- +static AlarmClock l_alarmClock; // the single inst of the AO + +// Global-scope objects ---------------------------------------------------- +//$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// Check for the minimum required QP version +#if (QP_VERSION < 730U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) +#error qpc version 7.3.0 or higher required +#endif +//$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +//$define${Components::APP_alarmClock} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${Components::APP_alarmClock} .............................................. +QActive * const APP_alarmClock = &l_alarmClock.super; +//$enddef${Components::APP_alarmClock} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +//$define${Components::AlarmClock_ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${Components::AlarmClock_ctor} ............................................. +void AlarmClock_ctor(void) { + AlarmClock * const me = &l_alarmClock; + + QActive_ctor(&me->super, Q_STATE_CAST(&AlarmClock_initial)); + Alarm_ctor(&me->alarm); // orthogonal component ctor + + // private time event ctor + QTimeEvt_ctorX(&me->timeEvt, &me->super, TICK_SIG, 0U); +} +//$enddef${Components::AlarmClock_ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +//.......................................................................... +//$define${Components::AlarmClock} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${Components::AlarmClock} .................................................. + +//${Components::AlarmClock::SM} .............................................. +static QState AlarmClock_initial(AlarmClock * const me, void const * const par) { + //${Components::AlarmClock::SM::initial} + (void)par; // unused parameter + me->current_time = 0U; + + // (!) trigger the initial transition in the component + QASM_INIT((QHsm *)&me->alarm, (void *)0, me->super.prio); + return Q_TRAN(&AlarmClock_timekeeping); +} + +//${Components::AlarmClock::SM::timekeeping} ................................. +static QState AlarmClock_timekeeping(AlarmClock * const me, QEvt const * const e) { + QState status_; + switch (e->sig) { + //${Components::AlarmClock::SM::timekeeping} + case Q_ENTRY_SIG: { + // periodic timeout every second + QTimeEvt_armX(&me->timeEvt, BSP_TICKS_PER_SEC, + BSP_TICKS_PER_SEC); + status_ = Q_HANDLED(); + break; + } + //${Components::AlarmClock::SM::timekeeping} + case Q_EXIT_SIG: { + QTimeEvt_disarm(&me->timeEvt); + status_ = Q_HANDLED(); + break; + } + //${Components::AlarmClock::SM::timekeeping::initial} + case Q_INIT_SIG: { + status_ = Q_TRAN(&AlarmClock_mode24h); + break; + } + //${Components::AlarmClock::SM::timekeeping::CLOCK_24H} + case CLOCK_24H_SIG: { + status_ = Q_TRAN(&AlarmClock_mode24h); + break; + } + //${Components::AlarmClock::SM::timekeeping::CLOCK_12H} + case CLOCK_12H_SIG: { + status_ = Q_TRAN(&AlarmClock_mode12h); + break; + } + //${Components::AlarmClock::SM::timekeeping::ALARM} + case ALARM_SIG: { + BSP_showMsg("Wake up!!!"); + status_ = Q_HANDLED(); + break; + } + //${Components::AlarmClock::SM::timekeeping::ALARM_SET, ALARM_ON, ALARM_OFF} + case ALARM_SET_SIG: // intentionally fall through + case ALARM_ON_SIG: // intentionally fall through + case ALARM_OFF_SIG: { + // (!) synchronously dispatch to the orthogonal component + QASM_DISPATCH((QHsm *)&me->alarm, e, me->super.prio); + status_ = Q_HANDLED(); + break; + } + //${Components::AlarmClock::SM::timekeeping::TERMINATE} + case TERMINATE_SIG: { + BSP_showMsg("--> final"); + status_ = Q_TRAN(&AlarmClock_final); + break; + } + default: { + status_ = Q_SUPER(&QHsm_top); + break; + } + } + return status_; +} + +//${Components::AlarmClock::SM::timekeeping::mode24h} ........................ +static QState AlarmClock_mode24h(AlarmClock * const me, QEvt const * const e) { + QState status_; + switch (e->sig) { + //${Components::AlarmClock::SM::timekeeping::mode24h} + case Q_ENTRY_SIG: { + BSP_showMsg("*** 24-hour mode"); + status_ = Q_HANDLED(); + break; + } + //${Components::AlarmClock::SM::timekeeping::mode24h::TICK} + case TICK_SIG: { + // roll over in 24-hr mode? + if (++me->current_time == 24U*60U) { + me->current_time = 0U; + } + BSP_showTime24H("", me->current_time, 60U); + + // temporary synchronous event for the component + TimeEvt pe = { + QEVT_INITIALIZER(TIME_SIG), + .current_time = me->current_time + }; + // (!) synchronously dispatch to the orthogonal component + QASM_DISPATCH(&me->alarm.super, &pe.super, me->super.prio); + status_ = Q_HANDLED(); + break; + } + default: { + status_ = Q_SUPER(&AlarmClock_timekeeping); + break; + } + } + return status_; +} + +//${Components::AlarmClock::SM::timekeeping::mode12h} ........................ +static QState AlarmClock_mode12h(AlarmClock * const me, QEvt const * const e) { + QState status_; + switch (e->sig) { + //${Components::AlarmClock::SM::timekeeping::mode12h} + case Q_ENTRY_SIG: { + BSP_showMsg("*** 12-hour mode"); + status_ = Q_HANDLED(); + break; + } + //${Components::AlarmClock::SM::timekeeping::mode12h::TICK} + case TICK_SIG: { + // roll over in 12-hr mode? + if (++me->current_time == 12U*60U) { + me->current_time = 0U; + } + BSP_showTime12H("", me->current_time, 60U); + + + // temporary synchronous event for the component + TimeEvt pe = { + QEVT_INITIALIZER(TIME_SIG), + .current_time = me->current_time + }; + // (!) synchronously dispatch to the orthogonal component + QASM_DISPATCH(&me->alarm.super, &pe.super, me->super.prio); + status_ = Q_HANDLED(); + break; + } + default: { + status_ = Q_SUPER(&AlarmClock_timekeeping); + break; + } + } + return status_; +} + +//${Components::AlarmClock::SM::final} ....................................... +static QState AlarmClock_final(AlarmClock * const me, QEvt const * const e) { + QState status_; + switch (e->sig) { + //${Components::AlarmClock::SM::final} + case Q_ENTRY_SIG: { + QF_stop(); // terminate the application + status_ = Q_HANDLED(); + break; + } + default: { + status_ = Q_SUPER(&QHsm_top); + break; + } + } + return status_; +} +//$enddef${Components::AlarmClock} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/examples/posix-win32/comp/clock.h b/examples/posix-win32/comp/clock.h new file mode 100644 index 00000000..92ba34f9 --- /dev/null +++ b/examples/posix-win32/comp/clock.h @@ -0,0 +1,85 @@ +//$file${.::clock.h} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// +// Model: comp.qm +// File: ${.::clock.h} +// +// This code has been generated by QM 5.3.0 . +// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. +// +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// SPDX-License-Identifier: GPL-3.0-or-later +// +// This generated code is open source software: you can redistribute it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation. +// +// This code is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// NOTE: +// Alternatively, this generated code may be distributed under the terms +// of Quantum Leaps commercial licenses, which expressly supersede the GNU +// General Public License and are specifically designed for licensees +// interested in retaining the proprietary status of their code. +// +// Contact information: +// +// +// +//$endhead${.::clock.h} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +#ifndef CLOCK_H_ +#define CLOCK_H_ + +enum AlarmClockSignals { + TICK_SIG = Q_USER_SIG, // time tick event + ALARM_SET_SIG, // set the alarm + ALARM_ON_SIG, // turn the alarm on + ALARM_OFF_SIG, // turn the alarm off + ALARM_SIG, // alarm event from Alarm component to AlarmClock container + CLOCK_12H_SIG, // set the clock in 12H mode + CLOCK_24H_SIG, // set the clock in 24H mode + TIME_SIG, // time event sent to Alarm (contains current time) + TERMINATE_SIG // terminate the application +}; + +//$declare${Events::SetEvt} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${Events::SetEvt} .......................................................... +typedef struct { +// protected: + QEvt super; + +// public: + uint8_t digit; +} SetEvt; +//$enddecl${Events::SetEvt} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +//$declare${Events::TimeEvt} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${Events::TimeEvt} ......................................................... +typedef struct { +// protected: + QEvt super; + +// public: + uint32_t current_time; +} TimeEvt; +//$enddecl${Events::TimeEvt} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +//$declare${Components::APP_alarmClock} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${Components::APP_alarmClock} .............................................. +extern QActive * const APP_alarmClock; +//$enddecl${Components::APP_alarmClock} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +//$declare${Components::AlarmClock_ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${Components::AlarmClock_ctor} ............................................. +void AlarmClock_ctor(void); +//$enddecl${Components::AlarmClock_ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +#endif // CLOCK_H_ diff --git a/examples/workstation/comp/comp.qm b/examples/posix-win32/comp/comp.qm similarity index 79% rename from examples/workstation/comp/comp.qm rename to examples/posix-win32/comp/comp.qm index d48c26b7..daff1e66 100644 --- a/examples/workstation/comp/comp.qm +++ b/examples/posix-win32/comp/comp.qm @@ -1,5 +1,5 @@ - + "Orthogonal Component" example @@ -32,17 +32,17 @@ me->alarm_time = 12U*60U; -(void)par; /* unused parameter */ +(void)par; // unused parameter - /* while in the off state, the alarm is kept in decimal format */ + // while in the off state, the alarm is kept in decimal format me->alarm_time = (me->alarm_time/60)*100 + me->alarm_time%60; BSP_showTime24H("*** Alarm OFF ", me->alarm_time, 100U); - /* upon exit, the alarm is converted to binary format */ + // upon exit, the alarm is converted to binary format me->alarm_time = (me->alarm_time/100U)*60U + me->alarm_time%100U; @@ -69,7 +69,7 @@ BSP_showTime24H("*** Alarm reset", me->alarm_time, 100U); - /* while setting, the alarm is kept in decimal format */ + // while setting, the alarm is kept in decimal format me->alarm_time = (10U * me->alarm_time + ((SetEvt const *)e)->digit) % 10000U; BSP_showTime24H("*** Alarm reset ", me->alarm_time, 100U); @@ -105,7 +105,7 @@ BSP_showTime24H("*** Alarm reset ", me->alarm_time, 100U);Q_EVT_CAST(TimeEvt)->current_time == me->alarm_time BSP_showMsg("ALARM!!!"); -/* asynchronously post the event to the container AO */ +// asynchronously post the event to the container AO QACTIVE_POST(APP_alarmClock, Q_NEW(QEvt, ALARM_SIG), me); @@ -135,18 +135,18 @@ QACTIVE_POST(APP_alarmClock, Q_NEW(QEvt, ALARM_SIG), me); - (void)par; /* unused parameter */ + (void)par; // unused parameter me->current_time = 0U; -/* (!) trigger the initial transition in the component */ -QHSM_INIT((QHsm *)&me->alarm, (void *)0, me->super.prio); +// (!) trigger the initial transition in the component +QASM_INIT((QHsm *)&me->alarm, (void *)0, me->super.prio); - /* periodic timeout every second */ + // periodic timeout every second QTimeEvt_armX(&me->timeEvt, BSP_TICKS_PER_SEC, BSP_TICKS_PER_SEC); QTimeEvt_disarm(&me->timeEvt); @@ -177,8 +177,8 @@ QTimeEvt_armX(&me->timeEvt, BSP_TICKS_PER_SEC, - /* (!) synchronously dispatch to the orthogonal component */ -QHSM_DISPATCH((QHsm *)&me->alarm, e, me->super.prio); + // (!) synchronously dispatch to the orthogonal component +QASM_DISPATCH((QHsm *)&me->alarm, e, me->super.prio); @@ -195,18 +195,19 @@ QHSM_DISPATCH((QHsm *)&me->alarm, e, me->super.prio); BSP_showMsg("*** 24-hour mode"); - TimeEvt pe; /* temporary synchronous event for the component */ - -/* roll over in 24-hr mode? */ + // roll over in 24-hr mode? if (++me->current_time == 24U*60U) { me->current_time = 0U; } BSP_showTime24H("", me->current_time, 60U); -pe.super.sig = TIME_SIG; -pe.current_time = me->current_time; -/* (!) synchronously dispatch to the orthogonal component */ -QHSM_DISPATCH(&me->alarm.super, &pe.super, me->super.prio); +// temporary synchronous event for the component +TimeEvt pe = { + QEVT_INITIALIZER(TIME_SIG), + .current_time = me->current_time +}; +// (!) synchronously dispatch to the orthogonal component +QASM_DISPATCH(&me->alarm.super, &pe.super, me->super.prio); @@ -220,18 +221,20 @@ QHSM_DISPATCH(&me->alarm.super, &pe.super, me->super.prio);BSP_showMsg("*** 12-hour mode"); - TimeEvt pe; /* temporary synchronous event for the component */ - -/* roll over in 12-hr mode? */ + // roll over in 12-hr mode? if (++me->current_time == 12U*60U) { me->current_time = 0U; } BSP_showTime12H("", me->current_time, 60U); -pe.super.sig = TIME_SIG; -pe.current_time = me->current_time; -/* (!) synchronously dispatch to the orthogonal component */ -QHSM_DISPATCH(&me->alarm.super, &pe.super, me->super.prio); + +// temporary synchronous event for the component +TimeEvt pe = { + QEVT_INITIALIZER(TIME_SIG), + .current_time = me->current_time +}; +// (!) synchronously dispatch to the orthogonal component +QASM_DISPATCH(&me->alarm.super, &pe.super, me->super.prio); @@ -247,7 +250,7 @@ QHSM_DISPATCH(&me->alarm.super, &pe.super, me->super.prio); - QF_stop(); /* terminate the application */ + QF_stop(); // terminate the application @@ -265,9 +268,9 @@ QHSM_DISPATCH(&me->alarm.super, &pe.super, me->super.prio);AlarmClock * const me = &l_alarmClock; QActive_ctor(&me->super, Q_STATE_CAST(&AlarmClock_initial)); -Alarm_ctor(&me->alarm); /* orthogonal component ctor */ +Alarm_ctor(&me->alarm); // orthogonal component ctor -/* private time event ctor */ +// private time event ctor QTimeEvt_ctorX(&me->timeEvt, &me->super, TICK_SIG, 0U); @@ -275,15 +278,14 @@ QTimeEvt_ctorX(&me->timeEvt, &me->super, TICK_SIG, 0U); - #ifndef ALARM_H -#define ALARM_H + #ifndef ALARM_H_ +#define ALARM_H_ $declare${Components::Alarm} $declare${Components::Alarm::ctor} -#endif /* ALARM_H */ - +#endif // ALARM_H_ @@ -294,25 +296,24 @@ $declare${Components::Alarm::ctor} //Q_DEFINE_THIS_FILE -/* Alarm component --------------------*/ -$define${Components::Alarm} - +// Alarm component -------------------- +$define${Components::Alarm} - #ifndef CLOCK_H -#define CLOCK_H + #ifndef CLOCK_H_ +#define CLOCK_H_ enum AlarmClockSignals { - TICK_SIG = Q_USER_SIG, /* time tick event */ - ALARM_SET_SIG, /* set the alarm */ - ALARM_ON_SIG, /* turn the alarm on */ - ALARM_OFF_SIG, /* turn the alarm off */ - ALARM_SIG, /* alarm event from Alarm component to AlarmClock container */ - CLOCK_12H_SIG, /* set the clock in 12H mode */ - CLOCK_24H_SIG, /* set the clock in 24H mode */ - TIME_SIG, /* time event sent to Alarm (contains current time) */ - TERMINATE_SIG /* terminate the application */ + TICK_SIG = Q_USER_SIG, // time tick event + ALARM_SET_SIG, // set the alarm + ALARM_ON_SIG, // turn the alarm on + ALARM_OFF_SIG, // turn the alarm off + ALARM_SIG, // alarm event from Alarm component to AlarmClock container + CLOCK_12H_SIG, // set the clock in 12H mode + CLOCK_24H_SIG, // set the clock in 24H mode + TIME_SIG, // time event sent to Alarm (contains current time) + TERMINATE_SIG // terminate the application }; $declare${Events::SetEvt} @@ -321,8 +322,7 @@ $declare${Events::TimeEvt} $declare${Components::APP_alarmClock} $declare${Components::AlarmClock_ctor} -#endif /* CLOCK_H */ - +#endif // CLOCK_H_ @@ -331,24 +331,23 @@ $declare${Components::AlarmClock_ctor} #include "alarm.h" #include "clock.h" -#include "safe_std.h" /* portable "safe" <stdio.h>/<string.h> facilities */ +#include "safe_std.h" // portable "safe" <stdio.h>/<string.h> facilities Q_DEFINE_THIS_FILE -/* Active object class -----------------------------------------------------*/ +// Active object class ----------------------------------------------------- $declare${Components::AlarmClock} -/* Local objects -----------------------------------------------------------*/ -static AlarmClock l_alarmClock; /* the single inst of the AO */ +// Local objects ----------------------------------------------------------- +static AlarmClock l_alarmClock; // the single inst of the AO -/* Global-scope objects ----------------------------------------------------*/ +// Global-scope objects ---------------------------------------------------- $define${Components::APP_alarmClock} $define${Components::AlarmClock_ctor} -/*..........................................................................*/ -$define${Components::AlarmClock} - +//.......................................................................... +$define${Components::AlarmClock} diff --git a/examples/posix-win32/comp/main.c b/examples/posix-win32/comp/main.c new file mode 100644 index 00000000..61cee147 --- /dev/null +++ b/examples/posix-win32/comp/main.c @@ -0,0 +1,73 @@ +//============================================================================ +// Product: "Orthogonal Component" example, Console based +// Last updated for version 6.4.0 +// Last updated on 2019-02-08 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// This program is open source software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Alternatively, this program may be distributed and modified under the +// terms of Quantum Leaps commercial licenses, which expressly supersede +// the GNU General Public License and are specifically designed for +// licensees interested in retaining the proprietary status of their code. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Contact information: +// +// +//============================================================================ +#include "qpc.h" +#include "alarm.h" +#include "clock.h" +#include "bsp.h" + +#include "safe_std.h" // portable "safe" / facilities + +//Q_DEFINE_THIS_FILE + +//............................................................................ +int main(int argc, char *argv[]) { + static QEvt const *l_alarmClockQSto[10]; // queue storage for AlarmClock + static QF_MPOOL_EL(TimeEvt) l_smlPoolSto[10]; // storage for small pool + + PRINTF_S("Orthogonal Component pattern\nQP version: %s\n" + "Press 'o' to turn the Alarm ON\n" + "Press 'f' to turn the Alarm OFF\n" + "Press '0'..'9' to set the Alarm time\n" + "Press 'a' to set the Clock in 12-hour mode\n" + "Press 'b' to set the Clock in 24-hour mode\n" + "Press ESC to quit...\n", + QP_VERSION_STR); + + BSP_init(argc, argv); // initialize the BSP + + QF_init(); // initialize the framework and the underlying RT kernel + + // publish-subscribe not used, no call to QActive_psInit() + + // initialize event pools... + QF_poolInit(l_smlPoolSto, sizeof(l_smlPoolSto), sizeof(l_smlPoolSto[0])); + + // instantiate and start the active objects... + AlarmClock_ctor(); + QACTIVE_START(APP_alarmClock, 1U, + l_alarmClockQSto, Q_DIM(l_alarmClockQSto), + (void *)0, 0U, (QEvt *)0); + + return QF_run(); // run the QF application +} diff --git a/examples/workstation/defer/Makefile b/examples/posix-win32/defer/Makefile similarity index 99% rename from examples/workstation/defer/Makefile rename to examples/posix-win32/defer/Makefile index deffbdf2..6fc12fdb 100644 --- a/examples/workstation/defer/Makefile +++ b/examples/posix-win32/defer/Makefile @@ -241,7 +241,7 @@ CPP_DEPS_EXT := $(patsubst %.o,%.d, $(CPP_OBJS_EXT)) all: $(TARGET_EXE) $(TARGET_EXE) : $(C_OBJS_EXT) $(CPP_OBJS_EXT) - $(CC) $(CFLAGS) $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o + $(CC) $(CFLAGS) $(QPC)/src/qs/qstamp.c -o $(BIN_DIR)/qstamp.o $(LINK) $(LINKFLAGS) $(LIB_DIRS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) $(BIN_DIR)/%.d : %.c diff --git a/examples/posix-win32/defer/bsp.c b/examples/posix-win32/defer/bsp.c new file mode 100644 index 00000000..bf88290b --- /dev/null +++ b/examples/posix-win32/defer/bsp.c @@ -0,0 +1,119 @@ +//============================================================================ +// Product: Console-based BSP +// Last Updated for Version: 7.3.0 +// Date of the Last Update: 2023-05-25 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// This program is open source software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Alternatively, this program may be distributed and modified under the +// terms of Quantum Leaps commercial licenses, which expressly supersede +// the GNU General Public License and are specifically designed for +// licensees interested in retaining the proprietary status of their code. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Contact information: +// +// +//============================================================================ +#include "qpc.h" +#include "bsp.h" + +#include "safe_std.h" // portable "safe" / facilities +#include // for exit() + +Q_DEFINE_THIS_FILE + +#ifdef Q_SPY +static uint8_t const l_QF_onClockTick = 0; +#endif + +//............................................................................ +void BSP_init(int argc, char *argv[]) { + (void)argc; + (void)argv; + + if (QS_INIT((argc > 1) ? argv[1] : (void *)0) == 0U) { + Q_ERROR(); + } + QS_OBJ_DICTIONARY(&l_QF_onClockTick); + + // setup the QS filters... + QS_GLB_FILTER(QS_ALL_RECORDS); + QS_GLB_FILTER(-QS_QF_TICK); +} +//............................................................................ +void QF_onStartup(void) { + QF_setTickRate(BSP_TICKS_PER_SEC, 30); // set the desired tick rate + QF_consoleSetup(); +} +//............................................................................ +void QF_onCleanup(void) { + PRINTF_S("\n%s\n", "Bye! Bye!"); + QF_consoleCleanup(); +} +//............................................................................ +void QF_onClockTick(void) { + int key; + QTIMEEVT_TICK_X(0U, &l_QF_onClockTick); // perform QF clock tick processing + + QS_RX_INPUT(); // handle the QS-RX input + QS_OUTPUT(); // handle the QS output + + key = QF_consoleGetKey(); + if (key != 0) { // any key pressed? + BSP_onKeyboardInput(key); + } +} +//---------------------------------------------------------------------------- +#ifdef Q_SPY // define QS callbacks + +//............................................................................ +//! callback function to execute user commands +void QS_onCommand(uint8_t cmdId, + uint32_t param1, uint32_t param2, uint32_t param3) +{ + switch (cmdId) { + case 0U: { + break; + } + default: + break; + } + + // unused parameters + (void)param1; + (void)param2; + (void)param3; +} + +#endif // Q_SPY +//---------------------------------------------------------------------------- + +//............................................................................ +Q_NORETURN Q_onError(char const * const module, int_t const id) { + FPRINTF_S(stderr, "ERROR in %s, line %d", module, id); + QF_onCleanup(); + exit(-1); +} +//............................................................................ +void assert_failed(char const * const module, int_t const id); // prototype +void assert_failed(char const * const module, int_t const id) { + Q_onError(module, id); +} + diff --git a/examples/posix-win32/defer/bsp.h b/examples/posix-win32/defer/bsp.h new file mode 100644 index 00000000..9fa2f435 --- /dev/null +++ b/examples/posix-win32/defer/bsp.h @@ -0,0 +1,42 @@ +//============================================================================ +// Product: Console-based BSP +// Last updated for version 5.4.2 +// Last updated on 2015-06-03 +// +// Q u a n t u m L e a P s +// --------------------------- +// innovating embedded systems +// +// Copyright (C) 2005 Quantum Leaps, www.state-machine.com. +// +// This program is open source software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Alternatively, this program may be distributed and modified under the +// terms of Quantum Leaps commercial licenses, which expressly supersede +// the GNU General Public License and are specifically designed for +// licensees interested in retaining the proprietary status of their code. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Contact information: +// Web: www.state-machine.com +// +//============================================================================ +#ifndef BSP_H_ +#define BSP_H_ + +#define BSP_TICKS_PER_SEC 100U + +void BSP_init(int argc, char *argv[]); +void BSP_onKeyboardInput(uint8_t key); // process the keyboard scan code + +#endif // BSP_H_ diff --git a/examples/workstation/defer/defer.c b/examples/posix-win32/defer/defer.c similarity index 52% rename from examples/workstation/defer/defer.c rename to examples/posix-win32/defer/defer.c index d997ad9b..bc745901 100644 --- a/examples/workstation/defer/defer.c +++ b/examples/posix-win32/defer/defer.c @@ -1,104 +1,104 @@ -/*$file${.::defer.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* -* Model: defer.qm -* File: ${.::defer.c} -* -* This code has been generated by QM 5.2.4 . -* DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. -* -* SPDX-License-Identifier: GPL-3.0-or-later -* -* This generated code is open source software: you can redistribute it under -* the terms of the GNU General Public License as published by the Free -* Software Foundation. -* -* This code is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -* more details. -* -* NOTE: -* Alternatively, this generated code may be distributed under the terms -* of Quantum Leaps commercial licenses, which expressly supersede the GNU -* General Public License and are specifically designed for licensees -* interested in retaining the proprietary status of their code. -* -* Contact information: -* -* -*/ -/*$endhead${.::defer.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$file${.::defer.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// +// Model: defer.qm +// File: ${.::defer.c} +// +// This code has been generated by QM 5.3.0 . +// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. +// +// SPDX-License-Identifier: GPL-3.0-or-later +// +// This generated code is open source software: you can redistribute it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation. +// +// This code is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// NOTE: +// Alternatively, this generated code may be distributed under the terms +// of Quantum Leaps commercial licenses, which expressly supersede the GNU +// General Public License and are specifically designed for licensees +// interested in retaining the proprietary status of their code. +// +// Contact information: +// +// +// +//$endhead${.::defer.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ #include "qpc.h" #include "bsp.h" -#include "safe_std.h" /* portable "safe" / facilities */ +#include "safe_std.h" // portable "safe" / facilities -Q_DEFINE_THIS_FILE +//Q_DEFINE_THIS_FILE -/*..........................................................................*/ +//.......................................................................... enum TServerSignals { - NEW_REQUEST_SIG = Q_USER_SIG, /* the new request signal */ - RECEIVED_SIG, /* the request has been received */ - AUTHORIZED_SIG, /* the request has been authorized */ - TERMINATE_SIG /* terminate the application */ + NEW_REQUEST_SIG = Q_USER_SIG, // the new request signal + RECEIVED_SIG, // the request has been received + AUTHORIZED_SIG, // the request has been authorized + TERMINATE_SIG // terminate the application }; -/*..........................................................................*/ -/*$declare${Events::RequestEvt} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//.......................................................................... +//$declare${Events::RequestEvt} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/*${Events::RequestEvt} ....................................................*/ +//${Events::RequestEvt} ...................................................... typedef struct { -/* protected: */ +// protected: QEvt super; -/* public: */ +// public: uint8_t ref_num; } RequestEvt; -/*$enddecl${Events::RequestEvt} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$enddecl${Events::RequestEvt} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -/* Active object class -----------------------------------------------------*/ -/*$declare${Components::TServer} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +// Active object class ----------------------------------------------------- +//$declare${Components::TServer} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/*${Components::TServer} ...................................................*/ +//${Components::TServer} ..................................................... typedef struct TServer { -/* protected: */ +// protected: QActive super; -/* private: */ +// private: QEQueue requestQueue; QEvt const * requestQSto[3]; -/* public: */ +// public: RequestEvt const * activeRequest; QTimeEvt receivedEvt; QTimeEvt authorizedEvt; } TServer; -/* public: */ +// public: static void TServer_ctor(TServer * const me); extern TServer TServer_inst; -/* protected: */ +// protected: static QState TServer_initial(TServer * const me, void const * const par); static QState TServer_idle(TServer * const me, QEvt const * const e); static QState TServer_busy(TServer * const me, QEvt const * const e); static QState TServer_receiving(TServer * const me, QEvt const * const e); static QState TServer_authorizing(TServer * const me, QEvt const * const e); static QState TServer_final(TServer * const me, QEvt const * const e); -/*$enddecl${Components::TServer} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$enddecl${Components::TServer} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -/*$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* Check for the minimum required QP version */ -#if (QP_VERSION < 700U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) -#error qpc version 7.0.0 or higher required +//$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// Check for the minimum required QP version +#if (QP_VERSION < 730U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) +#error qpc version 7.3.0 or higher required #endif -/*$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -/*$define${Components::TServer} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//$define${Components::TServer} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/*${Components::TServer} ...................................................*/ +//${Components::TServer} ..................................................... TServer TServer_inst; -/*${Components::TServer::ctor} .............................................*/ +//${Components::TServer::ctor} ............................................... static void TServer_ctor(TServer * const me) { QActive_ctor(&me->super, Q_STATE_CAST(&TServer_initial)); QEQueue_init(&me->requestQueue, @@ -107,11 +107,11 @@ static void TServer_ctor(TServer * const me) { QTimeEvt_ctorX(&me->authorizedEvt, &me->super, AUTHORIZED_SIG, 0U); } -/*${Components::TServer::SM} ...............................................*/ +//${Components::TServer::SM} ................................................. static QState TServer_initial(TServer * const me, void const * const par) { - /*${Components::TServer::SM::initial} */ - (void)par; /* unused parameter */ - me->activeRequest = (RequestEvt const *)0; /* no active request yet */ + //${Components::TServer::SM::initial} + (void)par; // unused parameter + me->activeRequest = (RequestEvt const *)0; // no active request yet QS_OBJ_DICTIONARY(&TServer_inst); @@ -128,15 +128,15 @@ static QState TServer_initial(TServer * const me, void const * const par) { return Q_TRAN(&TServer_idle); } -/*${Components::TServer::SM::idle} .........................................*/ +//${Components::TServer::SM::idle} ........................................... static QState TServer_idle(TServer * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${Components::TServer::SM::idle} */ + //${Components::TServer::SM::idle} case Q_ENTRY_SIG: { PRINTF_S("%s\n", "idle-ENTRY;"); - /* recall the oldest deferred request... */ + // recall the oldest deferred request... if (QActive_recall(&me->super, &me->requestQueue)) { PRINTF_S("%s\n", "Request recalled"); } @@ -146,12 +146,11 @@ static QState TServer_idle(TServer * const me, QEvt const * const e) { status_ = Q_HANDLED(); break; } - /*${Components::TServer::SM::idle::NEW_REQUEST} */ + //${Components::TServer::SM::idle::NEW_REQUEST} case NEW_REQUEST_SIG: { - /* create and save a new reference to the request event so that - * this event will be available beyond this RTC step and won't be - * recycled. - */ + // create and save a new reference to the request event so that + // this event will be available beyond this RTC step and won't be + // recycled. Q_NEW_REF(me->activeRequest, RequestEvt); PRINTF_S("Processing request #%d\n", @@ -159,7 +158,7 @@ static QState TServer_idle(TServer * const me, QEvt const * const e) { status_ = Q_TRAN(&TServer_receiving); break; } - /*${Components::TServer::SM::idle::TERMINATE} */ + //${Components::TServer::SM::idle::TERMINATE} case TERMINATE_SIG: { status_ = Q_TRAN(&TServer_final); break; @@ -172,38 +171,37 @@ static QState TServer_idle(TServer * const me, QEvt const * const e) { return status_; } -/*${Components::TServer::SM::busy} .........................................*/ +//${Components::TServer::SM::busy} ........................................... static QState TServer_busy(TServer * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${Components::TServer::SM::busy} */ + //${Components::TServer::SM::busy} case Q_EXIT_SIG: { PRINTF_S("busy-EXIT; done processing request #%d\n", (int)me->activeRequest->ref_num); - /* delete the reference to the active request, because - * it is now processed. - */ + // delete the reference to the active request because + // it is now processed. Q_DELETE_REF(me->activeRequest); status_ = Q_HANDLED(); break; } - /*${Components::TServer::SM::busy::NEW_REQUEST} */ + //${Components::TServer::SM::busy::NEW_REQUEST} case NEW_REQUEST_SIG: { - /* defer the new request event... */ + // defer the new request event... if (QActive_defer(&me->super, &me->requestQueue, e)) { PRINTF_S("Request #%d deferred;\n", (int)Q_EVT_CAST(RequestEvt)->ref_num); } else { - /* notify the request sender that his request was denied... */ + // notify the request sender that his request was denied... PRINTF_S("Request #%d IGNORED;\n", (int)Q_EVT_CAST(RequestEvt)->ref_num); } status_ = Q_HANDLED(); break; } - /*${Components::TServer::SM::busy::TERMINATE} */ + //${Components::TServer::SM::busy::TERMINATE} case TERMINATE_SIG: { status_ = Q_TRAN(&TServer_final); break; @@ -216,28 +214,28 @@ static QState TServer_busy(TServer * const me, QEvt const * const e) { return status_; } -/*${Components::TServer::SM::busy::receiving} ..............................*/ +//${Components::TServer::SM::busy::receiving} ................................ static QState TServer_receiving(TServer * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${Components::TServer::SM::busy::receiving} */ + //${Components::TServer::SM::busy::receiving} case Q_ENTRY_SIG: { - /* inform about the first stage of processing of the request... */ + // inform about the first stage of processing of the request... PRINTF_S("receiving-ENTRY; active request: #%d\n", (int)me->activeRequest->ref_num); - /* one-shot timeout in 1 second */ + // one-shot timeout in 1 second QTimeEvt_armX(&me->receivedEvt, BSP_TICKS_PER_SEC, 0U); status_ = Q_HANDLED(); break; } - /*${Components::TServer::SM::busy::receiving} */ + //${Components::TServer::SM::busy::receiving} case Q_EXIT_SIG: { QTimeEvt_disarm(&me->receivedEvt); status_ = Q_HANDLED(); break; } - /*${Components::TServer::SM::busy::receiving::RECEIVED} */ + //${Components::TServer::SM::busy::receiving::RECEIVED} case RECEIVED_SIG: { status_ = Q_TRAN(&TServer_authorizing); break; @@ -250,28 +248,28 @@ static QState TServer_receiving(TServer * const me, QEvt const * const e) { return status_; } -/*${Components::TServer::SM::busy::authorizing} ............................*/ +//${Components::TServer::SM::busy::authorizing} .............................. static QState TServer_authorizing(TServer * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${Components::TServer::SM::busy::authorizing} */ + //${Components::TServer::SM::busy::authorizing} case Q_ENTRY_SIG: { - /* inform about the second stage of processing of the request.. */ + // inform about the second stage of processing of the request.. PRINTF_S("authorizing-ENTRY; active request: #%d\n", (int)me->activeRequest->ref_num); - /* one-shot timeout in 2 seconds */ + // one-shot timeout in 2 seconds QTimeEvt_armX(&me->authorizedEvt, 2U*BSP_TICKS_PER_SEC, 0U); status_ = Q_HANDLED(); break; } - /*${Components::TServer::SM::busy::authorizing} */ + //${Components::TServer::SM::busy::authorizing} case Q_EXIT_SIG: { QTimeEvt_disarm(&me->authorizedEvt); status_ = Q_HANDLED(); break; } - /*${Components::TServer::SM::busy::authorizing::AUTHORIZED} */ + //${Components::TServer::SM::busy::authorizing::AUTHORIZED} case AUTHORIZED_SIG: { status_ = Q_TRAN(&TServer_idle); break; @@ -284,14 +282,14 @@ static QState TServer_authorizing(TServer * const me, QEvt const * const e) { return status_; } -/*${Components::TServer::SM::final} ........................................*/ +//${Components::TServer::SM::final} .......................................... static QState TServer_final(TServer * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${Components::TServer::SM::final} */ + //${Components::TServer::SM::final} case Q_ENTRY_SIG: { PRINTF_S("%s\n", "final-ENTRY;"); - QF_stop(); /* terminate the application */ + QF_stop(); // terminate the application status_ = Q_HANDLED(); break; } @@ -302,60 +300,59 @@ static QState TServer_final(TServer * const me, QEvt const * const e) { } return status_; } -/*$enddef${Components::TServer} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$enddef${Components::TServer} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -// test harness ============================================================*/ +// test harness ============================================================ // Local-scope objects ------------------------------------------------------- -static QEvt const *l_tserverQSto[10]; /* Event queue storage for TServer */ -static QF_MPOOL_EL(RequestEvt) l_smlPoolSto[20]; /* storage for small pool */ +static QEvt const *l_tserverQSto[10]; // Event queue storage for TServer +static QF_MPOOL_EL(RequestEvt) l_smlPoolSto[20]; // storage for small pool -/*..........................................................................*/ +//.......................................................................... int main(int argc, char *argv[]) { PRINTF_S("Deferred Event state pattern\nQP version: %s\n" "Press 'n' to generate a new request\n" "Press ESC to quit...\n", QP_VERSION_STR); - QF_init(); /* initialize the framework and the underlying RTOS/OS */ + QF_init(); // initialize the framework and the underlying RTOS/OS - BSP_init(argc, argv); /* initialize the BSP */ + BSP_init(argc, argv); // initialize the BSP - /* publish-subscribe not used, no call to QF_psInit() */ + // publish-subscribe not used, no call to QF_psInit() - /* initialize event pools... */ + // initialize event pools... QF_poolInit(l_smlPoolSto, sizeof(l_smlPoolSto), sizeof(l_smlPoolSto[0])); - QS_SIG_DICTIONARY(NEW_REQUEST_SIG, (void *)0); /* global signals */ + QS_SIG_DICTIONARY(NEW_REQUEST_SIG, (void *)0); // global signals QS_SIG_DICTIONARY(RECEIVED_SIG, (void *)0); QS_SIG_DICTIONARY(AUTHORIZED_SIG, (void *)0); QS_SIG_DICTIONARY(TERMINATE_SIG, (void *)0); - /* start the active objects... */ + // start the active objects... TServer_ctor(&TServer_inst); QACTIVE_START((QActive *)&TServer_inst, 1U, l_tserverQSto, Q_DIM(l_tserverQSto), (void *)0, 0U, (void *)0); - return QF_run(); /* run the QF application */ + return QF_run(); // run the QF application } -/*..........................................................................*/ +//.......................................................................... void BSP_onKeyboardInput(uint8_t key) { switch (key) { - case 'n': { /* 'n': new request? */ - static uint8_t reqCtr = 0; /* count the requests */ + case 'n': { // 'n': new request? + static uint8_t reqCtr = 0; // count the requests RequestEvt *e = Q_NEW(RequestEvt, NEW_REQUEST_SIG); - e->ref_num = (++reqCtr); /* set the reference number */ - /* post directly to TServer active object */ + e->ref_num = (++reqCtr); // set the reference number + // post directly to TServer active object QACTIVE_POST((QActive *)&TServer_inst, (QEvt *)e, (void *)0); break; } - case '\33': { /* ESC pressed? */ - static QEvt const terminateEvt = { TERMINATE_SIG, 0U, 0U }; + case '\33': { // ESC pressed? + static QEvt const terminateEvt = QEVT_INITIALIZER(TERMINATE_SIG); QACTIVE_POST((QActive *)&TServer_inst, &terminateEvt, (void *)0); break; } } } - diff --git a/examples/workstation/defer/defer.qm b/examples/posix-win32/defer/defer.qm similarity index 75% rename from examples/workstation/defer/defer.qm rename to examples/posix-win32/defer/defer.qm index be7f17bb..7b1700fa 100644 --- a/examples/workstation/defer/defer.qm +++ b/examples/posix-win32/defer/defer.qm @@ -1,5 +1,5 @@ - + "Deferred Event" state pattern example @@ -46,8 +46,8 @@ QTimeEvt_ctorX(&me->authorizedEvt, &me->super, AUTHORIZED_SIG, 0U) - (void)par; /* unused parameter */ -me->activeRequest = (RequestEvt const *)0; /* no active request yet */ + (void)par; // unused parameter +me->activeRequest = (RequestEvt const *)0; // no active request yet QS_OBJ_DICTIONARY(&TServer_inst); @@ -62,7 +62,7 @@ QS_OBJ_DICTIONARY(&TServer_inst.requestQueue); PRINTF_S("%s\n", "idle-ENTRY;"); -/* recall the oldest deferred request... */ +// recall the oldest deferred request... if (QActive_recall(&me->super, &me->requestQueue)) { PRINTF_S("%s\n", "Request recalled"); } @@ -71,10 +71,9 @@ else { } - /* create and save a new reference to the request event so that -* this event will be available beyond this RTC step and won't be -* recycled. -*/ + // create and save a new reference to the request event so that +// this event will be available beyond this RTC step and won't be +// recycled. Q_NEW_REF(me->activeRequest, RequestEvt); PRINTF_S("Processing request #%d\n", @@ -98,19 +97,18 @@ PRINTF_S("Processing request #%d\n", PRINTF_S("busy-EXIT; done processing request #%d\n", (int)me->activeRequest->ref_num); -/* delete the reference to the active request, because -* it is now processed. -*/ +// delete the reference to the active request because +// it is now processed. Q_DELETE_REF(me->activeRequest); - /* defer the new request event... */ + // defer the new request event... if (QActive_defer(&me->super, &me->requestQueue, e)) { PRINTF_S("Request #%d deferred;\n", (int)Q_EVT_CAST(RequestEvt)->ref_num); } else { - /* notify the request sender that his request was denied... */ + // notify the request sender that his request was denied... PRINTF_S("Request #%d IGNORED;\n", (int)Q_EVT_CAST(RequestEvt)->ref_num); } @@ -126,11 +124,11 @@ else { - /* inform about the first stage of processing of the request... */ + // inform about the first stage of processing of the request... PRINTF_S("receiving-ENTRY; active request: #%d\n", (int)me->activeRequest->ref_num); -/* one-shot timeout in 1 second */ +// one-shot timeout in 1 second QTimeEvt_armX(&me->receivedEvt, BSP_TICKS_PER_SEC, 0U); QTimeEvt_disarm(&me->receivedEvt); @@ -146,11 +144,11 @@ QTimeEvt_armX(&me->receivedEvt, BSP_TICKS_PER_SEC, 0U); - /* inform about the second stage of processing of the request.. */ + // inform about the second stage of processing of the request.. PRINTF_S("authorizing-ENTRY; active request: #%d\n", (int)me->activeRequest->ref_num); -/* one-shot timeout in 2 seconds */ +// one-shot timeout in 2 seconds QTimeEvt_armX(&me->authorizedEvt, 2U*BSP_TICKS_PER_SEC, 0U); QTimeEvt_disarm(&me->authorizedEvt); @@ -171,7 +169,7 @@ QTimeEvt_armX(&me->authorizedEvt, 2U*BSP_TICKS_PER_SEC, 0U); PRINTF_S("%s\n", "final-ENTRY;"); - QF_stop(); /* terminate the application */ + QF_stop(); // terminate the application @@ -187,80 +185,79 @@ QTimeEvt_armX(&me->authorizedEvt, 2U*BSP_TICKS_PER_SEC, 0U); #include "qpc.h" #include "bsp.h" -#include "safe_std.h" /* portable "safe" <stdio.h>/<string.h> facilities */ +#include "safe_std.h" // portable "safe" <stdio.h>/<string.h> facilities -Q_DEFINE_THIS_FILE +//Q_DEFINE_THIS_FILE -/*..........................................................................*/ +//.......................................................................... enum TServerSignals { - NEW_REQUEST_SIG = Q_USER_SIG, /* the new request signal */ - RECEIVED_SIG, /* the request has been received */ - AUTHORIZED_SIG, /* the request has been authorized */ - TERMINATE_SIG /* terminate the application */ + NEW_REQUEST_SIG = Q_USER_SIG, // the new request signal + RECEIVED_SIG, // the request has been received + AUTHORIZED_SIG, // the request has been authorized + TERMINATE_SIG // terminate the application }; -/*..........................................................................*/ +//.......................................................................... $declare${Events::RequestEvt} -/* Active object class -----------------------------------------------------*/ +// Active object class ----------------------------------------------------- $declare${Components::TServer} $define${Components::TServer} -// test harness ============================================================*/ +// test harness ============================================================ // Local-scope objects ------------------------------------------------------- -static QEvt const *l_tserverQSto[10]; /* Event queue storage for TServer */ -static QF_MPOOL_EL(RequestEvt) l_smlPoolSto[20]; /* storage for small pool */ +static QEvt const *l_tserverQSto[10]; // Event queue storage for TServer +static QF_MPOOL_EL(RequestEvt) l_smlPoolSto[20]; // storage for small pool -/*..........................................................................*/ +//.......................................................................... int main(int argc, char *argv[]) { PRINTF_S("Deferred Event state pattern\nQP version: %s\n" "Press 'n' to generate a new request\n" "Press ESC to quit...\n", QP_VERSION_STR); - QF_init(); /* initialize the framework and the underlying RTOS/OS */ + QF_init(); // initialize the framework and the underlying RTOS/OS - BSP_init(argc, argv); /* initialize the BSP */ + BSP_init(argc, argv); // initialize the BSP - /* publish-subscribe not used, no call to QF_psInit() */ + // publish-subscribe not used, no call to QF_psInit() - /* initialize event pools... */ + // initialize event pools... QF_poolInit(l_smlPoolSto, sizeof(l_smlPoolSto), sizeof(l_smlPoolSto[0])); - QS_SIG_DICTIONARY(NEW_REQUEST_SIG, (void *)0); /* global signals */ + QS_SIG_DICTIONARY(NEW_REQUEST_SIG, (void *)0); // global signals QS_SIG_DICTIONARY(RECEIVED_SIG, (void *)0); QS_SIG_DICTIONARY(AUTHORIZED_SIG, (void *)0); QS_SIG_DICTIONARY(TERMINATE_SIG, (void *)0); - /* start the active objects... */ + // start the active objects... TServer_ctor(&TServer_inst); QACTIVE_START((QActive *)&TServer_inst, 1U, l_tserverQSto, Q_DIM(l_tserverQSto), (void *)0, 0U, (void *)0); - return QF_run(); /* run the QF application */ + return QF_run(); // run the QF application } -/*..........................................................................*/ +//.......................................................................... void BSP_onKeyboardInput(uint8_t key) { switch (key) { - case 'n': { /* 'n': new request? */ - static uint8_t reqCtr = 0; /* count the requests */ + case 'n': { // 'n': new request? + static uint8_t reqCtr = 0; // count the requests RequestEvt *e = Q_NEW(RequestEvt, NEW_REQUEST_SIG); - e->ref_num = (++reqCtr); /* set the reference number */ - /* post directly to TServer active object */ + e->ref_num = (++reqCtr); // set the reference number + // post directly to TServer active object QACTIVE_POST((QActive *)&TServer_inst, (QEvt *)e, (void *)0); break; } - case '\33': { /* ESC pressed? */ - static QEvt const terminateEvt = { TERMINATE_SIG, 0U, 0U }; + case '\33': { // ESC pressed? + static QEvt const terminateEvt = QEVT_INITIALIZER(TERMINATE_SIG); QACTIVE_POST((QActive *)&TServer_inst, &terminateEvt, (void *)0); break; } } -} - +} diff --git a/examples/workstation/defer/qspy200822_125414.seq b/examples/posix-win32/defer/qspy200822_125414.seq similarity index 100% rename from examples/workstation/defer/qspy200822_125414.seq rename to examples/posix-win32/defer/qspy200822_125414.seq diff --git a/examples/workstation/dpp-comp/Makefile b/examples/posix-win32/dpp/Makefile similarity index 94% rename from examples/workstation/dpp-comp/Makefile rename to examples/posix-win32/dpp/Makefile index 68232133..91ab48d7 100644 --- a/examples/workstation/dpp-comp/Makefile +++ b/examples/posix-win32/dpp/Makefile @@ -1,7 +1,7 @@ ############################################################################## # Product: Makefile for QP/C for Windows and POSIX *HOSTS* -# Last updated for version 7.2.0 -# Last updated on 2022-11-13 +# Last updated for version 7.3.0 +# Last updated on 2023-09-03 # # Q u a n t u m L e a P s # ------------------------ @@ -43,7 +43,7 @@ # NOTE: # To use this Makefile on Windows, you will need the GNU make utility, which # is included in the QTools collection for Windows, see: -# http://sourceforge.net/projects/qpc/files/QTools/ +# https://github.com/QuantumLeaps/qtools # #----------------------------------------------------------------------------- @@ -56,10 +56,10 @@ PROJECT := dpp # # list of all source directories used by this project -VPATH := . \ +VPATH := . # list of all include directories needed by this project -INCLUDES := -I. \ +INCLUDES := -I. # location of the QP/C framework (if not provided in an env. variable) ifeq ($(QPC),) @@ -85,7 +85,8 @@ LIBS := # defines... # QP_API_VERSION controls the QP API compatibility; 9999 means the latest API -DEFINES := -DQP_API_VERSION=9999 +DEFINES := -DQP_CONFIG \ + $(DEF) ifeq (,$(CONF)) CONF := dbg @@ -141,7 +142,7 @@ LIBS += -lpthread endif -#============================================================================ +#============================================================================= # Typically you should not need to change anything below this line VPATH += $(QPC)/src/qf $(QP_PORT_DIR) @@ -152,8 +153,8 @@ INCLUDES += -I$(QPC)/include -I$(QP_PORT_DIR) # # NOTE: # GNU toolset (MinGW) is included in the QTools collection for Windows, see: -# https://www.state-machine.com/qtools -# It is assumed that %QTOOLS%\bin directory is added to the PATH +# https://github.com/QuantumLeaps/qtools +# It is assumed that $(QTOOLS)/bin directory is added to the PATH # CC := gcc CPP := g++ @@ -234,6 +235,11 @@ C_DEPS_EXT := $(patsubst %.o,%.d, $(C_OBJS_EXT)) CPP_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(CPP_OBJS)) CPP_DEPS_EXT := $(patsubst %.o,%.d, $(CPP_OBJS_EXT)) +# create $(BIN_DIR) if it does not exist +ifeq ("$(wildcard $(BIN_DIR))","") +$(shell $(MKDIR) $(BIN_DIR)) +endif + #----------------------------------------------------------------------------- # rules # @@ -243,7 +249,7 @@ CPP_DEPS_EXT := $(patsubst %.o,%.d, $(CPP_OBJS_EXT)) all: $(TARGET_EXE) $(TARGET_EXE) : $(C_OBJS_EXT) $(CPP_OBJS_EXT) - $(CC) $(CFLAGS) $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o + $(CC) $(CFLAGS) $(QPC)/src/qs/qstamp.c -o $(BIN_DIR)/qstamp.o $(LINK) $(LINKFLAGS) $(LIB_DIRS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) $(BIN_DIR)/%.d : %.c diff --git a/examples/workstation/dpp/Makefile_t b/examples/posix-win32/dpp/Makefile_t similarity index 94% rename from examples/workstation/dpp/Makefile_t rename to examples/posix-win32/dpp/Makefile_t index 4e763a1e..96173ff9 100644 --- a/examples/workstation/dpp/Makefile_t +++ b/examples/posix-win32/dpp/Makefile_t @@ -1,7 +1,7 @@ ############################################################################## # Product: Makefile for QP/C for Windows and POSIX *HOSTS* (multithreaded) -# Last updated for version 7.2.0 -# Last updated on 2022-11-13 +# Last updated for version 7.3.0 +# Last updated on 2023-09-03 # # Q u a n t u m L e a P s # ------------------------ @@ -43,7 +43,7 @@ # NOTE: # To use this Makefile on Windows, you will need the GNU make utility, which # is included in the QTools collection for Windows, see: -# http://sourceforge.net/projects/qpc/files/QTools/ +# https://github.com/QuantumLeaps/qtools # #----------------------------------------------------------------------------- @@ -56,10 +56,10 @@ PROJECT := dpp # # list of all source directories used by this project -VPATH := . \ +VPATH := . # list of all include directories needed by this project -INCLUDES := -I. \ +INCLUDES := -I. # location of the QP/C framework (if not provided in an env. variable) ifeq ($(QPC),) @@ -85,7 +85,7 @@ LIBS := # defines... # QP_API_VERSION controls the QP API compatibility; 9999 means the latest API -DEFINES := -DQP_API_VERSION=9999 +DEFINES := -DQP_CONFIG ifeq (,$(CONF)) CONF := dbg @@ -141,7 +141,7 @@ LIBS += -lpthread endif -#============================================================================ +#============================================================================= # Typically you should not need to change anything below this line VPATH += $(QPC)/src/qf $(QP_PORT_DIR) @@ -152,8 +152,8 @@ INCLUDES += -I$(QPC)/include -I$(QP_PORT_DIR) # # NOTE: # GNU toolset (MinGW) is included in the QTools collection for Windows, see: -# https://www.state-machine.com/qtools -# It is assumed that %QTOOLS%\bin directory is added to the PATH +# https://github.com/QuantumLeaps/qtools +# It is assumed that $(QTOOLS)/bin directory is added to the PATH # CC := gcc CPP := g++ @@ -234,6 +234,11 @@ C_DEPS_EXT := $(patsubst %.o,%.d, $(C_OBJS_EXT)) CPP_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(CPP_OBJS)) CPP_DEPS_EXT := $(patsubst %.o,%.d, $(CPP_OBJS_EXT)) +# create $(BIN_DIR) if it does not exist +ifeq ("$(wildcard $(BIN_DIR))","") +$(shell $(MKDIR) $(BIN_DIR)) +endif + #----------------------------------------------------------------------------- # rules # @@ -243,7 +248,7 @@ CPP_DEPS_EXT := $(patsubst %.o,%.d, $(CPP_OBJS_EXT)) all: $(TARGET_EXE) $(TARGET_EXE) : $(C_OBJS_EXT) $(CPP_OBJS_EXT) - $(CC) $(CFLAGS) $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o + $(CC) $(CFLAGS) $(QPC)/src/qs/qstamp.c -o $(BIN_DIR)/qstamp.o $(LINK) $(LINKFLAGS) $(LIB_DIRS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) $(BIN_DIR)/%.d : %.c diff --git a/examples/posix-win32/dpp/bsp.c b/examples/posix-win32/dpp/bsp.c new file mode 100644 index 00000000..e9bff224 --- /dev/null +++ b/examples/posix-win32/dpp/bsp.c @@ -0,0 +1,217 @@ +//============================================================================ +// Product: BSP for DPP example (console) +// Last Updated for Version: 7.3.0 +// Date of the Last Update: 2023-09-05 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// This program is open source software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Alternatively, this program may be distributed and modified under the +// terms of Quantum Leaps commercial licenses, which expressly supersede +// the GNU General Public License and are specifically designed for +// licensees interested in retaining the proprietary status of their code. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Contact information: +// +// +//============================================================================ +#include "qpc.h" // QP/C real-time embedded framework +#include "dpp.h" // DPP Application interface +#include "bsp.h" // Board Support Package + +#include "safe_std.h" // portable "safe" / facilities +#include // for exit() + +Q_DEFINE_THIS_FILE + +// Local objects ------------------------------------------------------------- +static uint32_t l_rnd; // random seed + +#ifdef Q_SPY + enum { + PHILO_STAT = QS_USER, + PAUSED_STAT, + }; + + // QSpy source IDs + static QSpyId const l_clock_tick = { QS_AP_ID }; +#endif + +//============================================================================ +Q_NORETURN Q_onError(char const * const module, int_t const id) { + QS_ASSERTION(module, id, 10000U); // report assertion to QS + FPRINTF_S(stderr, "ERROR in %s:%d", module, id); + QF_onCleanup(); + QS_EXIT(); + exit(-1); +} +//............................................................................ +void assert_failed(char const * const module, int_t const id); // prototype +void assert_failed(char const * const module, int_t const id) { + Q_onError(module, id); +} + +//============================================================================ +void BSP_init(int argc, char *argv[]) { + Q_UNUSED_PAR(argc); + Q_UNUSED_PAR(argv); + + PRINTF_S("Dining Philosophers Problem example" + "\nQP %s\n" + "Press 'p' to pause\n" + "Press 's' to serve\n" + "Press ESC to quit...\n", + QP_VERSION_STR); + + BSP_randomSeed(1234U); + + // initialize the QS software tracing + if (QS_INIT((argc > 1) ? argv[1] : (void *)0) == 0U) { + Q_ERROR(); + } + + QS_OBJ_DICTIONARY(&l_clock_tick); + + QS_USR_DICTIONARY(PHILO_STAT); + QS_USR_DICTIONARY(PAUSED_STAT); + + QS_ONLY(produce_sig_dict()); + + // setup the QS filters... + QS_GLB_FILTER(QS_ALL_RECORDS); + QS_GLB_FILTER(-QS_QF_TICK); // exclude the tick record +} +//............................................................................ +void BSP_start(void) { + // initialize event pools + static QF_MPOOL_EL(TableEvt) smlPoolSto[2*N_PHILO]; + QF_poolInit(smlPoolSto, sizeof(smlPoolSto), sizeof(smlPoolSto[0])); + + // initialize publish-subscribe + static QSubscrList subscrSto[MAX_PUB_SIG]; + QActive_psInit(subscrSto, Q_DIM(subscrSto)); + + // instantiate and start AOs/threads... + + static QEvt const *philoQueueSto[N_PHILO][10]; + for (uint8_t n = 0U; n < N_PHILO; ++n) { + Philo_ctor(n); + QACTIVE_START(AO_Philo[n], + n + 3U, // QP prio. of the AO + philoQueueSto[n], // event queue storage + Q_DIM(philoQueueSto[n]), // queue length [events] + (void *)0, 0U, // no stack storage + (void *)0); // no initialization param + } + + static QEvt const *tableQueueSto[N_PHILO]; + Table_ctor(); + QACTIVE_START(AO_Table, + N_PHILO + 7U, // QP prio. of the AO + tableQueueSto, // event queue storage + Q_DIM(tableQueueSto), // queue length [events] + (void *)0, 0U, // no stack storage + (void *)0); // no initialization param +} +//............................................................................ +void BSP_terminate(int16_t result) { + (void)result; + QF_stop(); // stop the main "ticker thread" +} +//............................................................................ +void BSP_displayPhilStat(uint8_t n, char const *stat) { + PRINTF_S("Philosopher %2d is %s\n", (int)n, stat); + + // application-specific record + QS_BEGIN_ID(PHILO_STAT, AO_Table->prio) + QS_U8(1, n); // Philosopher number + QS_STR(stat); // Philosopher status + QS_END() +} +//............................................................................ +void BSP_displayPaused(uint8_t paused) { + PRINTF_S("Paused is %s\n", paused ? "ON" : "OFF"); +} +//............................................................................ +uint32_t BSP_random(void) { // a very cheap pseudo-random-number generator + // "Super-Duper" Linear Congruential Generator (LCG) + // LCG(2^32, 3*7*11*13*23, 0, seed) + // + l_rnd = l_rnd * (3U*7U*11U*13U*23U); + return l_rnd >> 8; +} +//............................................................................ +void BSP_randomSeed(uint32_t seed) { + l_rnd = seed; +} + +//============================================================================ +void QF_onStartup(void) { + QF_consoleSetup(); + QF_setTickRate(BSP_TICKS_PER_SEC, 10); // desired tick rate/ticker-prio +} +//............................................................................ +void QF_onCleanup(void) { + PRINTF_S("\n%s\n", "Bye! Bye!"); + QF_consoleCleanup(); +} +//............................................................................ +void QF_onClockTick(void) { + + QTIMEEVT_TICK_X(0U, &l_clock_tick); // process time events at rate 0 + + QS_RX_INPUT(); // handle the QS-RX input + QS_OUTPUT(); // handle the QS output + + switch (QF_consoleGetKey()) { + case '\33': { // ESC pressed? + BSP_terminate(0); + break; + } + case 'p': { + static QEvt const pauseEvt = QEVT_INITIALIZER(PAUSE_SIG); + QACTIVE_PUBLISH(&pauseEvt, &l_clock_tick); + break; + } + case 's': { + static QEvt const serveEvt = QEVT_INITIALIZER(SERVE_SIG); + QACTIVE_PUBLISH(&serveEvt, &l_clock_tick); + break; + } + default: { + break; + } + } +} + +//============================================================================ +#ifdef Q_SPY // define QS callbacks + +//............................................................................ +//! callback function to execute user commands +void QS_onCommand(uint8_t cmdId, + uint32_t param1, uint32_t param2, uint32_t param3) +{ + Q_UNUSED_PAR(cmdId); + Q_UNUSED_PAR(param1); + Q_UNUSED_PAR(param2); + Q_UNUSED_PAR(param3); +} + +#endif // Q_SPY diff --git a/examples/posix-win32/dpp/bsp.h b/examples/posix-win32/dpp/bsp.h new file mode 100644 index 00000000..a9b952ac --- /dev/null +++ b/examples/posix-win32/dpp/bsp.h @@ -0,0 +1,51 @@ +//============================================================================ +// Product: DPP example (console) +// Last Updated for Version: 7.3.0 +// Date of the Last Update: 2023-08-12 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. +// +// This program is open source software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Alternatively, this program may be distributed and modified under the +// terms of Quantum Leaps commercial licenses, which expressly supersede +// the GNU General Public License and are specifically designed for +// licensees interested in retaining the proprietary status of their code. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Contact information: +// +// +//============================================================================ +#ifndef BSP_H_ +#define BSP_H_ + +#define BSP_TICKS_PER_SEC 100U + +void BSP_init(int argc, char *argv[]); +void BSP_start(void); +void BSP_displayPaused(uint8_t paused); +void BSP_displayPhilStat(uint8_t n, char const *stat); +void BSP_terminate(int16_t result); + +void BSP_randomSeed(uint32_t seed); // random seed +uint32_t BSP_random(void); // pseudo-random generator + +void BSP_ledOn(void); +void BSP_ledOff(void); + +#endif // BSP_H_ diff --git a/examples/posix-win32/dpp/dpp.h b/examples/posix-win32/dpp/dpp.h new file mode 100644 index 00000000..e6d1557a --- /dev/null +++ b/examples/posix-win32/dpp/dpp.h @@ -0,0 +1,117 @@ +//$file${.::dpp.h} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// +// Model: dpp.qm +// File: ${.::dpp.h} +// +// This code has been generated by QM 5.3.0 . +// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. +// +// SPDX-License-Identifier: GPL-3.0-or-later +// +// This generated code is open source software: you can redistribute it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation. +// +// This code is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// NOTE: +// Alternatively, this generated code may be distributed under the terms +// of Quantum Leaps commercial licenses, which expressly supersede the GNU +// General Public License and are specifically designed for licensees +// interested in retaining the proprietary status of their code. +// +// Contact information: +// +// +// +//$endhead${.::dpp.h} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +#ifndef DPP_H_ +#define DPP_H_ + +//$declare${Shared} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${Shared::AppSignals} ...................................................... +enum AppSignals { + EAT_SIG = Q_USER_SIG, // published by Table to let a Philo eat + DONE_SIG, // published by Philo when done eating + PAUSE_SIG, // published by BSP to pause the application + SERVE_SIG, // published by BSP to serve re-start serving forks + TEST_SIG, // published by BSP to test the application + MAX_PUB_SIG, // the last published signal + + TIMEOUT_SIG, // posted by time event to Philo + HUNGRY_SIG, // posted by hungry Philo to Table + MAX_SIG // the last signal +}; + +//${Shared::produce_sig_dict} ................................................ +#ifdef Q_SPY +static inline void produce_sig_dict(void) { + QS_SIG_DICTIONARY(EAT_SIG, (void *)0); + QS_SIG_DICTIONARY(DONE_SIG, (void *)0); + QS_SIG_DICTIONARY(PAUSE_SIG, (void *)0); + QS_SIG_DICTIONARY(SERVE_SIG, (void *)0); + QS_SIG_DICTIONARY(TEST_SIG, (void *)0); + + QS_SIG_DICTIONARY(TIMEOUT_SIG, (void *)0); + QS_SIG_DICTIONARY(HUNGRY_SIG, (void *)0); +} +#endif // def Q_SPY + +//${Shared::N_PHILO} ......................................................... +#define N_PHILO ((uint8_t)5U) + +//${Shared::TableEvt} ........................................................ +typedef struct { +// protected: + QEvt super; + +// public: + uint8_t philoId; +} TableEvt; + +// public: + +#ifdef QEVT_DYN_CTOR +static inline TableEvt * TableEvt_ctor(TableEvt * const me, + uint8_t id) +{ + if (me != (TableEvt *)0) { + // don't call QEvt_ctor() because the initialization of all + // QEvt attributes is already done in QF_QF_newX_() + me->philoId = id; + } + return me; +} +#endif // def QEVT_DYN_CTOR + +//${Shared::AO_Philo[N_PHILO]} ............................................... +extern QActive * const AO_Philo[N_PHILO]; + +//${Shared::Philo_ctor} ...................................................... +void Philo_ctor(uint_fast8_t const id); + +//${Shared::AO_Table} ........................................................ +extern QActive * const AO_Table; + +//${Shared::Table_ctor} ...................................................... +void Table_ctor(void); +//$enddecl${Shared} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +#ifdef QXK_H_ + +extern QXThread * const TH_XThread1; +void XThread1_ctor(void); + +extern QXThread * const TH_XThread2; +void XThread2_ctor(void); + +extern QXSemaphore TH_sema; +extern QXMutex TH_mutex; + +#endif // QXK_H_ + +#endif // DPP_H_ diff --git a/examples/posix-win32/dpp/dpp.qm b/examples/posix-win32/dpp/dpp.qm new file mode 100644 index 00000000..ac9f2bc9 --- /dev/null +++ b/examples/posix-win32/dpp/dpp.qm @@ -0,0 +1,525 @@ + + + Dining Philosopher Problem example + + + + + + + { + EAT_SIG = Q_USER_SIG, // published by Table to let a Philo eat + DONE_SIG, // published by Philo when done eating + PAUSE_SIG, // published by BSP to pause the application + SERVE_SIG, // published by BSP to serve re-start serving forks + TEST_SIG, // published by BSP to test the application + MAX_PUB_SIG, // the last published signal + + TIMEOUT_SIG, // posted by time event to Philo + HUNGRY_SIG, // posted by hungry Philo to Table + MAX_SIG // the last signal +}; + + + + QS_SIG_DICTIONARY(EAT_SIG, (void *)0); +QS_SIG_DICTIONARY(DONE_SIG, (void *)0); +QS_SIG_DICTIONARY(PAUSE_SIG, (void *)0); +QS_SIG_DICTIONARY(SERVE_SIG, (void *)0); +QS_SIG_DICTIONARY(TEST_SIG, (void *)0); + +QS_SIG_DICTIONARY(TIMEOUT_SIG, (void *)0); +QS_SIG_DICTIONARY(HUNGRY_SIG, (void *)0); + + + + ((uint8_t)5U) + + + + + + + + + + if (me != (TableEvt *)0) { + // don't call QEvt_ctor() because the initialization of all + // QEvt attributes is already done in QF_QF_newX_() + me->philoId = id; +} +return me; + + + + + = { + &Philo_inst[0].super, + &Philo_inst[1].super, + &Philo_inst[2].super, + &Philo_inst[3].super, + &Philo_inst[4].super +}; + + + + + + Philo * const me = &Philo_inst[id]; +QActive_ctor(&me->super, Q_STATE_CAST(&Philo_initial)); +QTimeEvt_ctorX(&me->timeEvt, &me->super, TIMEOUT_SIG, 0U), +me->id = (uint8_t)id; + + + + = &Table_inst.super; + + + + Table * const me = &Table_inst; +QActive_ctor(&me->super, Q_STATE_CAST(&Table_initial)); +for (uint8_t n = 0U; n < N_PHILO; ++n) { + me->fork[n] = FREE; + me->isHungry[n] = false; +} + + + + + + + The Philo AO and the N_PHILO instances + + + + + + + + + + + Q_UNUSED_PAR(par); + +QS_OBJ_ARR_DICTIONARY(&Philo_inst[me->id], me->id); +QS_OBJ_ARR_DICTIONARY(&Philo_inst[me->id].timeEvt, me->id); + +QActive_subscribe(&me->super, EAT_SIG); +QActive_subscribe(&me->super, TEST_SIG); + + + + + + + QTimeEvt_armX(&me->timeEvt, think_time(), 0U); + (void)QTimeEvt_disarm(&me->timeEvt); + + + + + + + + + // EAT or DONE must be for other Philos than this one +Q_ASSERT(Q_EVT_CAST(TableEvt)->philoId != me->id); + + + + + + + + + + + + + + + + + + #ifdef QEVT_DYN_CTOR +TableEvt const *pe = Q_NEW(TableEvt, HUNGRY_SIG, me->id); +#else +TableEvt *pe = Q_NEW(TableEvt, HUNGRY_SIG); +pe->philoId = me->id; +#endif +QACTIVE_POST(AO_Table, &pe->super, &me->super); + + + + + Q_EVT_CAST(TableEvt)->philoId == me->id + + + + + + + + + + + // DONE must be for other Philos than this one +Q_ASSERT(Q_EVT_CAST(TableEvt)->philoId != me->id); + + + + + + + + + + + QTimeEvt_armX(&me->timeEvt, eat_time(), 0U); + (void)QTimeEvt_disarm(&me->timeEvt); + +#ifdef QEVT_DYN_CTOR +TableEvt const *pe = Q_NEW(TableEvt, DONE_SIG, me->id); +#else +TableEvt *pe = Q_NEW(TableEvt, DONE_SIG); +pe->philoId = me->id; +#endif +QACTIVE_PUBLISH(&pe->super, &me->super); + + + + + + + + + // EAT or DONE must be for other Philos than this one +Q_ASSERT(Q_EVT_CAST(TableEvt)->philoId != me->id); + + + + + + + + + + + + + + + + + + + + + + + + + Q_UNUSED_PAR(par); + +#ifdef Q_SPY +Table *Table_inst = me; +QS_OBJ_DICTIONARY(Table_inst); +#endif + +QActive_subscribe(&me->super, DONE_SIG); +QActive_subscribe(&me->super, PAUSE_SIG); +QActive_subscribe(&me->super, SERVE_SIG); +QActive_subscribe(&me->super, TEST_SIG); + +for (uint8_t n = 0U; n < N_PHILO; ++n) { + me->fork[n] = FREE; + me->isHungry[n] = false; + BSP_displayPhilStat(n, THINKING); +} + + + + + + + + + + + + + + + Q_ERROR(); + + + + + + + // give permissions to eat... +for (uint8_t n = 0U; n < N_PHILO; ++n) { + if (me->isHungry[n] + && (me->fork[left(n)] == FREE) + && (me->fork[n] == FREE)) + { + me->fork[left(n)] = USED; + me->fork[n] = USED; +#ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, EAT_SIG, n); +#else + TableEvt *pe = Q_NEW(TableEvt, EAT_SIG); + pe->philoId = n; +#endif + QACTIVE_PUBLISH(&pe->super, &me->super); + me->isHungry[n] = false; + BSP_displayPhilStat(n, EATING); + } +} + + + uint8_t n = Q_EVT_CAST(TableEvt)->philoId; + +// phil ID must be in range and he must be not hungry +Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); + +BSP_displayPhilStat(n, HUNGRY); +uint8_t m = left(n); + + + (me->fork[m] == FREE) && (me->fork[n] == FREE) + me->fork[m] = USED; +me->fork[n] = USED; +#ifdef QEVT_DYN_CTOR +TableEvt const *pe = Q_NEW(TableEvt, EAT_SIG, n); +#else +TableEvt *pe = Q_NEW(TableEvt, EAT_SIG); +pe->philoId = n; +#endif +QACTIVE_PUBLISH(&pe->super, &me->super); +BSP_displayPhilStat(n, EATING); + + + + + + + else + me->isHungry[n] = true; + + + + + + + + + + + uint8_t n = Q_EVT_CAST(TableEvt)->philoId; + +// phil ID must be in range and he must be not hungry +Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); + +BSP_displayPhilStat(n, THINKING); +uint8_t m = left(n); + +// both forks of Phil[n] must be used +Q_ASSERT((me->fork[n] == USED) && (me->fork[m] == USED)); + +me->fork[m] = FREE; +me->fork[n] = FREE; +m = right(n); // check the right neighbor + +if (me->isHungry[m] && (me->fork[m] == FREE)) { + me->fork[n] = USED; + me->fork[m] = USED; + me->isHungry[m] = false; +#ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, EAT_SIG, m); +#else + TableEvt *pe = Q_NEW(TableEvt, EAT_SIG); + pe->philoId = m; +#endif + QACTIVE_PUBLISH(&pe->super, &me->super); + BSP_displayPhilStat(m, EATING); +} +m = left(n); // check the left neighbor +n = left(m); // left fork of the left neighbor +if (me->isHungry[m] && (me->fork[n] == FREE)) { + me->fork[m] = USED; + me->fork[n] = USED; + me->isHungry[m] = false; +#ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, EAT_SIG, m); +#else + TableEvt *pe = Q_NEW(TableEvt, EAT_SIG); + pe->philoId = m; +#endif + QACTIVE_PUBLISH(&pe->super, &me->super); + BSP_displayPhilStat(m, EATING); +} + + + + + + + Q_ERROR(); + + + + + + + + + + + + + + + + + BSP_displayPaused(1U); + BSP_displayPaused(0U); + + + + + + + + + uint8_t n = Q_EVT_CAST(TableEvt)->philoId; + +// philo ID must be in range and he must be not hungry +Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); + +me->isHungry[n] = true; +BSP_displayPhilStat(n, HUNGRY); + + + + + + + uint8_t n = Q_EVT_CAST(TableEvt)->philoId; + +// phil ID must be in range and he must be not hungry +Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); + +BSP_displayPhilStat(n, THINKING); +uint8_t m = left(n); + +// both forks of Phil[n] must be used +Q_ASSERT((me->fork[n] == USED) && (me->fork[m] == USED)); + +me->fork[m] = FREE; +me->fork[n] = FREE; + + + + + + + + + + + + + + + + + + + + #ifndef DPP_H_ +#define DPP_H_ + +$declare ${Shared} + +#ifdef QXK_H_ + +extern QXThread * const TH_XThread1; +void XThread1_ctor(void); + +extern QXThread * const TH_XThread2; +void XThread2_ctor(void); + +extern QXSemaphore TH_sema; +extern QXMutex TH_mutex; + +#endif // QXK_H_ + +#endif // DPP_H_ + + + + #include "qpc.h" // QP/C real-time embedded framework +#include "dpp.h" // DPP Application interface +#include "bsp.h" // Board Support Package + +$declare ${AOs::Philo} + +//---------------------------------------------------------------------------- +Q_DEFINE_THIS_FILE + +// helper function to provide a randomized think time for Philos +static QTimeEvtCtr think_time(void); // prototype +static inline QTimeEvtCtr think_time(void) { + return (QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + + (BSP_TICKS_PER_SEC/2U)); +} + +// helper function to provide a randomized eat time for Philos +static QTimeEvtCtr eat_time(void); // prototype +static inline QTimeEvtCtr eat_time(void) { + return (QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + + BSP_TICKS_PER_SEC); +} +//---------------------------------------------------------------------------- + +$define ${Shared::Philo_ctor} +$define ${Shared::AO_Philo[N_PHILO]} +$define ${AOs::Philo} + + + + #include "qpc.h" // QP/C real-time embedded framework +#include "dpp.h" // DPP Application interface +#include "bsp.h" // Board Support Package + +$declare ${AOs::Table} + +//---------------------------------------------------------------------------- +Q_DEFINE_THIS_FILE + +// helper function to provide the RIGHT neighbor of a Philo[n] +static inline uint8_t right(uint8_t const n) { + return (uint8_t)((n + (N_PHILO - 1U)) % N_PHILO); +} + +// helper function to provide the LEFT neighbor of a Philo[n] +static inline uint8_t left(uint8_t const n) { + return (uint8_t)((n + 1U) % N_PHILO); +} + +#define FREE ((uint8_t)0U) +#define USED ((uint8_t)1U) + +#define THINKING "thinking" +#define HUNGRY "hungry " +#define EATING "eating " + +//---------------------------------------------------------------------------- + +$define ${Shared::Table_ctor} +$define ${Shared::AO_Table} +$define ${AOs::Table} + + + diff --git a/examples/workstation/dpp/dpp.sln b/examples/posix-win32/dpp/dpp.sln similarity index 100% rename from examples/workstation/dpp/dpp.sln rename to examples/posix-win32/dpp/dpp.sln diff --git a/examples/posix-win32/dpp/dpp.vcxproj b/examples/posix-win32/dpp/dpp.vcxproj new file mode 100644 index 00000000..c22d62a0 --- /dev/null +++ b/examples/posix-win32/dpp/dpp.vcxproj @@ -0,0 +1,412 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + QSpy64 + Win32 + + + QSpy64 + x64 + + + QSpy + x64 + + + Release + Win32 + + + QSpy + Win32 + + + Release + x64 + + + + {8CC465F7-872E-4D03-B93C-1B64858B4E11} + dpp + Win32Proj + 10.0 + + + + Application + NotSet + v142 + + + Application + NotSet + v142 + + + Application + NotSet + v142 + + + Application + NotSet + v142 + + + Application + NotSet + true + v142 + + + Application + NotSet + true + v142 + + + Application + NotSet + v142 + + + Application + NotSet + v142 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.40219.1 + $(SolutionDir)$(Configuration)\ + $(Configuration)\ + true + true + $(SolutionDir)$(Configuration)\ + $(Configuration)\ + false + false + $(SolutionDir)$(Configuration)\ + QSpy64\ + $(Configuration)\ + QSpy64\ + true + true + true + true + + + QSpy64\ + QSpy64\ + + + + Disabled + .;../../../include;../../../ports/win32-qv;%(AdditionalIncludeDirectories) + QP_CONFIG;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + false + + + Default + MultiThreaded + NotUsing + Level4 + ProgramDatabase + 4127 + Default + stdc11 + + + %(AdditionalDependencies) + %(AdditionalLibraryDirectories) + true + Console + MachineX86 + + + cmd /c "del $(OutDir)qstamp.obj" + + + + + Disabled + .;../../../include;../../../ports/win32-qv;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + false + + + Default + MultiThreaded + NotUsing + Level4 + ProgramDatabase + 4127 + Default + + + qp.lib;%(AdditionalDependencies) + %(AdditionalLibraryDirectories) + true + Console + + + cmd /c "del $(OutDir)qstamp.obj" + + + + + MaxSpeed + true + .;../../../include;../../../ports/win32-qv;%(AdditionalIncludeDirectories) + NDEBUG;QP_CONFIG;WIN32;_CONSOLE;%(PreprocessorDefinitions) + false + + + Default + MultiThreaded + true + NotUsing + Level4 + ProgramDatabase + 4127 + stdc11 + + + %(AdditionalDependencies) + %(AdditionalLibraryDirectories) + true + Console + true + true + MachineX86 + + + cmd /c "del $(OutDir)qstamp.obj" + + + + + MaxSpeed + true + .;../../../include;../../../ports/win32-qv;%(AdditionalIncludeDirectories) + NDEBUG;WIN32;_CONSOLE;%(PreprocessorDefinitions) + false + + + Default + MultiThreaded + true + NotUsing + Level4 + ProgramDatabase + 4127 + + + qp.lib;%(AdditionalDependencies) + %(AdditionalLibraryDirectories) + true + Console + true + true + + + cmd /c "del $(OutDir)qstamp.obj" + + + + + Disabled + .;../../../include;../../../ports/win32-qv;$(QTOOLS)/qspy/include;%(AdditionalIncludeDirectories) + Q_SPY;QP_CONFIG;WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + false + + + Default + MultiThreaded + NotUsing + Level4 + ProgramDatabase + 4127 + stdc11 + + + ws2_32.lib;%(AdditionalDependencies) + %(AdditionalLibraryDirectories) + true + Console + MachineX86 + + + cmd /c "del $(OutDir)qstamp.obj" + + + + + Disabled + .;../../../include;../../../ports/win32-qv;$(QTOOLS)/qspy/include;%(AdditionalIncludeDirectories) + Q_SPY;WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + false + + + Default + MultiThreaded + NotUsing + Level4 + ProgramDatabase + 4127 + + + qp.lib;ws2_32.lib;%(AdditionalDependencies) + %(AdditionalLibraryDirectories) + true + Console + + + cmd /c "del $(OutDir)qstamp.obj" + + + + + Disabled + .;../../../include;../../../ports/win32-qv;$(QTOOLS)/qspy/include;%(AdditionalIncludeDirectories) + Q_SPY;QP_CONFIG;WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + false + + + Default + MultiThreaded + NotUsing + Level4 + ProgramDatabase + 4127 + stdc11 + + + ws2_32.lib;%(AdditionalDependencies) + %(AdditionalLibraryDirectories) + true + Console + MachineX86 + + + cmd /c "del $(OutDir)qstamp.obj" + + + + + Disabled + .;../../../include;../../../ports/win32-qv;$(QTOOLS)/qspy/include;%(AdditionalIncludeDirectories) + Q_SPY;WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + false + + + Default + MultiThreaded + NotUsing + Level4 + ProgramDatabase + 4127 + + + ws2_32.lib;%(AdditionalDependencies) + %(AdditionalLibraryDirectories) + true + Console + + + cmd /c "del $(OutDir)qstamp.obj" + + + + + + true + false + false + true + + + + + + + + + + + + + + + true + true + + + true + true + + + true + true + + + true + true + + + true + true + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/workstation/qhsmtst/qhsmtst.vcxproj.filters b/examples/posix-win32/dpp/dpp.vcxproj.filters similarity index 70% rename from examples/workstation/qhsmtst/qhsmtst.vcxproj.filters rename to examples/posix-win32/dpp/dpp.vcxproj.filters index 168d02e6..398beb67 100644 --- a/examples/workstation/qhsmtst/qhsmtst.vcxproj.filters +++ b/examples/posix-win32/dpp/dpp.vcxproj.filters @@ -1,15 +1,10 @@  + - - - - QP_port - - - QP_port - + + QP @@ -46,15 +41,31 @@ QP + + QP_port + + + QP_port + + + QS + + + QS + + + QS + + + QS + + + QS + - - - QP_port - - - QP_port - + + QP_port @@ -63,11 +74,14 @@ + + {a95ae5f4-6fdc-49fe-b3d8-c693676b3410} + - {6fef7230-b720-452f-b1f6-6fe039768944} + {8bb033b0-2b6f-4f17-bc67-c29ad976a148} - {ee79d87d-043f-4f52-9525-2d3df056d571} + {7ff98771-41c0-4306-aa9a-18b8e1372f01} diff --git a/examples/posix-win32/dpp/main.c b/examples/posix-win32/dpp/main.c new file mode 100644 index 00000000..392e9100 --- /dev/null +++ b/examples/posix-win32/dpp/main.c @@ -0,0 +1,44 @@ +//============================================================================ +// APP example +// Last updated for version 7.3.0 +// Last updated on 2023-08-09 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. +// +// This program is open source software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Alternatively, this program may be distributed and modified under the +// terms of Quantum Leaps commercial licenses, which expressly supersede +// the GNU General Public License and are specifically designed for +// licensees interested in retaining the proprietary status of their code. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Contact information: +// +// +//============================================================================ +#include "qpc.h" // QP/C real-time embedded framework +#include "dpp.h" // DPP Application interface +#include "bsp.h" // Board Support Package + +//............................................................................ +int main(int argc, char *argv[]) { + QF_init(); // initialize the framework + BSP_init(argc, argv); // initialize the BSP + BSP_start(); // start the AOs/Threads + return QF_run(); // run the QF application +} diff --git a/examples/posix-win32/dpp/philo.c b/examples/posix-win32/dpp/philo.c new file mode 100644 index 00000000..eb6be531 --- /dev/null +++ b/examples/posix-win32/dpp/philo.c @@ -0,0 +1,255 @@ +//$file${.::philo.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// +// Model: dpp.qm +// File: ${.::philo.c} +// +// This code has been generated by QM 5.3.0 . +// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. +// +// SPDX-License-Identifier: GPL-3.0-or-later +// +// This generated code is open source software: you can redistribute it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation. +// +// This code is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// NOTE: +// Alternatively, this generated code may be distributed under the terms +// of Quantum Leaps commercial licenses, which expressly supersede the GNU +// General Public License and are specifically designed for licensees +// interested in retaining the proprietary status of their code. +// +// Contact information: +// +// +// +//$endhead${.::philo.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +#include "qpc.h" // QP/C real-time embedded framework +#include "dpp.h" // DPP Application interface +#include "bsp.h" // Board Support Package + +//$declare${AOs::Philo} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${AOs::Philo} .............................................................. +typedef struct Philo { +// protected: + QActive super; + +// private: + QTimeEvt timeEvt; + uint8_t id; + +// public: +} Philo; + +extern Philo Philo_inst[N_PHILO]; + +// protected: +static QState Philo_initial(Philo * const me, void const * const par); +static QState Philo_thinking(Philo * const me, QEvt const * const e); +static QState Philo_hungry(Philo * const me, QEvt const * const e); +static QState Philo_eating(Philo * const me, QEvt const * const e); +//$enddecl${AOs::Philo} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +//---------------------------------------------------------------------------- +Q_DEFINE_THIS_FILE + +// helper function to provide a randomized think time for Philos +static QTimeEvtCtr think_time(void); // prototype +static inline QTimeEvtCtr think_time(void) { + return (QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + + (BSP_TICKS_PER_SEC/2U)); +} + +// helper function to provide a randomized eat time for Philos +static QTimeEvtCtr eat_time(void); // prototype +static inline QTimeEvtCtr eat_time(void) { + return (QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + + BSP_TICKS_PER_SEC); +} +//---------------------------------------------------------------------------- + +//$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// Check for the minimum required QP version +#if (QP_VERSION < 730U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) +#error qpc version 7.3.0 or higher required +#endif +//$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +//$define${Shared::Philo_ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${Shared::Philo_ctor} ...................................................... +void Philo_ctor(uint_fast8_t const id) { + Philo * const me = &Philo_inst[id]; + QActive_ctor(&me->super, Q_STATE_CAST(&Philo_initial)); + QTimeEvt_ctorX(&me->timeEvt, &me->super, TIMEOUT_SIG, 0U), + me->id = (uint8_t)id; +} +//$enddef${Shared::Philo_ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +//$define${Shared::AO_Philo[N_PHILO]} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${Shared::AO_Philo[N_PHILO]} ............................................... +QActive * const AO_Philo[N_PHILO] = { + &Philo_inst[0].super, + &Philo_inst[1].super, + &Philo_inst[2].super, + &Philo_inst[3].super, + &Philo_inst[4].super +}; +//$enddef${Shared::AO_Philo[N_PHILO]} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +//$define${AOs::Philo} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${AOs::Philo} .............................................................. +Philo Philo_inst[N_PHILO]; + +//${AOs::Philo::SM} .......................................................... +static QState Philo_initial(Philo * const me, void const * const par) { + //${AOs::Philo::SM::initial} + Q_UNUSED_PAR(par); + + QS_OBJ_ARR_DICTIONARY(&Philo_inst[me->id], me->id); + QS_OBJ_ARR_DICTIONARY(&Philo_inst[me->id].timeEvt, me->id); + + QActive_subscribe(&me->super, EAT_SIG); + QActive_subscribe(&me->super, TEST_SIG); + + QS_FUN_DICTIONARY(&Philo_thinking); + QS_FUN_DICTIONARY(&Philo_hungry); + QS_FUN_DICTIONARY(&Philo_eating); + + return Q_TRAN(&Philo_thinking); +} + +//${AOs::Philo::SM::thinking} ................................................ +static QState Philo_thinking(Philo * const me, QEvt const * const e) { + QState status_; + switch (e->sig) { + //${AOs::Philo::SM::thinking} + case Q_ENTRY_SIG: { + QTimeEvt_armX(&me->timeEvt, think_time(), 0U); + status_ = Q_HANDLED(); + break; + } + //${AOs::Philo::SM::thinking} + case Q_EXIT_SIG: { + (void)QTimeEvt_disarm(&me->timeEvt); + status_ = Q_HANDLED(); + break; + } + //${AOs::Philo::SM::thinking::TIMEOUT} + case TIMEOUT_SIG: { + status_ = Q_TRAN(&Philo_hungry); + break; + } + //${AOs::Philo::SM::thinking::EAT, DONE} + case EAT_SIG: // intentionally fall through + case DONE_SIG: { + // EAT or DONE must be for other Philos than this one + Q_ASSERT(Q_EVT_CAST(TableEvt)->philoId != me->id); + status_ = Q_HANDLED(); + break; + } + //${AOs::Philo::SM::thinking::TEST} + case TEST_SIG: { + status_ = Q_HANDLED(); + break; + } + default: { + status_ = Q_SUPER(&QHsm_top); + break; + } + } + return status_; +} + +//${AOs::Philo::SM::hungry} .................................................. +static QState Philo_hungry(Philo * const me, QEvt const * const e) { + QState status_; + switch (e->sig) { + //${AOs::Philo::SM::hungry} + case Q_ENTRY_SIG: { + #ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, HUNGRY_SIG, me->id); + #else + TableEvt *pe = Q_NEW(TableEvt, HUNGRY_SIG); + pe->philoId = me->id; + #endif + QACTIVE_POST(AO_Table, &pe->super, &me->super); + status_ = Q_HANDLED(); + break; + } + //${AOs::Philo::SM::hungry::EAT} + case EAT_SIG: { + //${AOs::Philo::SM::hungry::EAT::[e->philoId==me->iid]} + if (Q_EVT_CAST(TableEvt)->philoId == me->id) { + status_ = Q_TRAN(&Philo_eating); + } + else { + status_ = Q_UNHANDLED(); + } + break; + } + //${AOs::Philo::SM::hungry::DONE} + case DONE_SIG: { + // DONE must be for other Philos than this one + Q_ASSERT(Q_EVT_CAST(TableEvt)->philoId != me->id); + status_ = Q_HANDLED(); + break; + } + default: { + status_ = Q_SUPER(&QHsm_top); + break; + } + } + return status_; +} + +//${AOs::Philo::SM::eating} .................................................. +static QState Philo_eating(Philo * const me, QEvt const * const e) { + QState status_; + switch (e->sig) { + //${AOs::Philo::SM::eating} + case Q_ENTRY_SIG: { + QTimeEvt_armX(&me->timeEvt, eat_time(), 0U); + status_ = Q_HANDLED(); + break; + } + //${AOs::Philo::SM::eating} + case Q_EXIT_SIG: { + (void)QTimeEvt_disarm(&me->timeEvt); + + #ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, DONE_SIG, me->id); + #else + TableEvt *pe = Q_NEW(TableEvt, DONE_SIG); + pe->philoId = me->id; + #endif + QACTIVE_PUBLISH(&pe->super, &me->super); + status_ = Q_HANDLED(); + break; + } + //${AOs::Philo::SM::eating::TIMEOUT} + case TIMEOUT_SIG: { + status_ = Q_TRAN(&Philo_thinking); + break; + } + //${AOs::Philo::SM::eating::EAT, DONE} + case EAT_SIG: // intentionally fall through + case DONE_SIG: { + // EAT or DONE must be for other Philos than this one + Q_ASSERT(Q_EVT_CAST(TableEvt)->philoId != me->id); + status_ = Q_HANDLED(); + break; + } + default: { + status_ = Q_SUPER(&QHsm_top); + break; + } + } + return status_; +} +//$enddef${AOs::Philo} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/examples/posix-win32/dpp/qp_config.h b/examples/posix-win32/dpp/qp_config.h new file mode 100644 index 00000000..f568dc03 --- /dev/null +++ b/examples/posix-win32/dpp/qp_config.h @@ -0,0 +1,51 @@ +//============================================================================ +// QP configuration file example +// Last updated for version: 7.3.0 +// Last updated on: 2023-09-02 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +//============================================================================ +#ifndef QP_CONFIG_H_ +#define QP_CONFIG_H_ + +// NOTE: +// The QP configuration takes effect only when the macro QP_CONFIG +// is defined on the command-line to the compiler for all QP source files. + +// Use the most recent QP API version +#define QP_API_VERSION 9999 + +// The maximum number of active objects in the application +#define QF_MAX_ACTIVE 64U + +// The number of system clock tick rates +#define QF_MAX_TICK_RATE 2U + +// Activate the QF QActive_stop() API +#define QF_ACTIVE_STOP + +#endif // QP_CONFIG_H_ diff --git a/examples/workstation/dpp/qview/dpp.py b/examples/posix-win32/dpp/qview/dpp.py similarity index 100% rename from examples/workstation/dpp/qview/dpp.py rename to examples/posix-win32/dpp/qview/dpp.py diff --git a/examples/workstation/dpp/qview/dpp1.py b/examples/posix-win32/dpp/qview/dpp1.py similarity index 100% rename from examples/workstation/dpp/qview/dpp1.py rename to examples/posix-win32/dpp/qview/dpp1.py diff --git a/examples/posix-win32/dpp/qview/img/BTN_DWN.gif b/examples/posix-win32/dpp/qview/img/BTN_DWN.gif new file mode 100644 index 00000000..36d8c790 Binary files /dev/null and b/examples/posix-win32/dpp/qview/img/BTN_DWN.gif differ diff --git a/examples/posix-win32/dpp/qview/img/BTN_UP.gif b/examples/posix-win32/dpp/qview/img/BTN_UP.gif new file mode 100644 index 00000000..3246ff98 Binary files /dev/null and b/examples/posix-win32/dpp/qview/img/BTN_UP.gif differ diff --git a/examples/posix-win32/dpp/qview/img/eating.gif b/examples/posix-win32/dpp/qview/img/eating.gif new file mode 100644 index 00000000..632b9d23 Binary files /dev/null and b/examples/posix-win32/dpp/qview/img/eating.gif differ diff --git a/examples/posix-win32/dpp/qview/img/hungry.gif b/examples/posix-win32/dpp/qview/img/hungry.gif new file mode 100644 index 00000000..dc144db9 Binary files /dev/null and b/examples/posix-win32/dpp/qview/img/hungry.gif differ diff --git a/examples/posix-win32/dpp/qview/img/thinking.gif b/examples/posix-win32/dpp/qview/img/thinking.gif new file mode 100644 index 00000000..ec684ee5 Binary files /dev/null and b/examples/posix-win32/dpp/qview/img/thinking.gif differ diff --git a/examples/posix-win32/dpp/qview/qview-dpp.bat b/examples/posix-win32/dpp/qview/qview-dpp.bat new file mode 100644 index 00000000..b36e43d6 --- /dev/null +++ b/examples/posix-win32/dpp/qview/qview-dpp.bat @@ -0,0 +1,8 @@ +@setlocal + +if "%QTOOLS%"=="" ( + set QTOOLS=C:\qp\qtools +) +python3 %QTOOLS%\qview\qview.py dpp.py + +@endlocal diff --git a/examples/workstation/dpp/qview/qview-dpp.lnk b/examples/posix-win32/dpp/qview/qview-dpp.lnk similarity index 100% rename from examples/workstation/dpp/qview/qview-dpp.lnk rename to examples/posix-win32/dpp/qview/qview-dpp.lnk diff --git a/examples/posix-win32/dpp/qview/qview-dpp1.bat b/examples/posix-win32/dpp/qview/qview-dpp1.bat new file mode 100644 index 00000000..8bdb9ce5 --- /dev/null +++ b/examples/posix-win32/dpp/qview/qview-dpp1.bat @@ -0,0 +1,8 @@ +@setlocal + +if "%QTOOLS%"=="" ( + set QTOOLS=C:\qp\qtools +) +python3 %QTOOLS%\qview\qview.py dpp1.py + +@endlocal diff --git a/examples/workstation/dpp/qview/qview-dpp1.lnk b/examples/posix-win32/dpp/qview/qview-dpp1.lnk similarity index 100% rename from examples/workstation/dpp/qview/qview-dpp1.lnk rename to examples/posix-win32/dpp/qview/qview-dpp1.lnk diff --git a/examples/posix-win32/dpp/table.c b/examples/posix-win32/dpp/table.c new file mode 100644 index 00000000..c3ae02f0 --- /dev/null +++ b/examples/posix-win32/dpp/table.c @@ -0,0 +1,343 @@ +//$file${.::table.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// +// Model: dpp.qm +// File: ${.::table.c} +// +// This code has been generated by QM 5.3.0 . +// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. +// +// SPDX-License-Identifier: GPL-3.0-or-later +// +// This generated code is open source software: you can redistribute it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation. +// +// This code is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// NOTE: +// Alternatively, this generated code may be distributed under the terms +// of Quantum Leaps commercial licenses, which expressly supersede the GNU +// General Public License and are specifically designed for licensees +// interested in retaining the proprietary status of their code. +// +// Contact information: +// +// +// +//$endhead${.::table.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +#include "qpc.h" // QP/C real-time embedded framework +#include "dpp.h" // DPP Application interface +#include "bsp.h" // Board Support Package + +//$declare${AOs::Table} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${AOs::Table} .............................................................. +typedef struct Table { +// protected: + QActive super; + +// private: + uint8_t fork[N_PHILO]; + bool isHungry[N_PHILO]; + +// public: +} Table; + +extern Table Table_inst; + +// protected: +static QState Table_initial(Table * const me, void const * const par); +static QState Table_active(Table * const me, QEvt const * const e); +static QState Table_serving(Table * const me, QEvt const * const e); +static QState Table_paused(Table * const me, QEvt const * const e); +//$enddecl${AOs::Table} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +//---------------------------------------------------------------------------- +Q_DEFINE_THIS_FILE + +// helper function to provide the RIGHT neighbor of a Philo[n] +static inline uint8_t right(uint8_t const n) { + return (uint8_t)((n + (N_PHILO - 1U)) % N_PHILO); +} + +// helper function to provide the LEFT neighbor of a Philo[n] +static inline uint8_t left(uint8_t const n) { + return (uint8_t)((n + 1U) % N_PHILO); +} + +#define FREE ((uint8_t)0U) +#define USED ((uint8_t)1U) + +#define THINKING "thinking" +#define HUNGRY "hungry " +#define EATING "eating " + +//---------------------------------------------------------------------------- + +//$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// Check for the minimum required QP version +#if (QP_VERSION < 730U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) +#error qpc version 7.3.0 or higher required +#endif +//$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +//$define${Shared::Table_ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${Shared::Table_ctor} ...................................................... +void Table_ctor(void) { + Table * const me = &Table_inst; + QActive_ctor(&me->super, Q_STATE_CAST(&Table_initial)); + for (uint8_t n = 0U; n < N_PHILO; ++n) { + me->fork[n] = FREE; + me->isHungry[n] = false; + } +} +//$enddef${Shared::Table_ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +//$define${Shared::AO_Table} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${Shared::AO_Table} ........................................................ +QActive * const AO_Table = &Table_inst.super; +//$enddef${Shared::AO_Table} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +//$define${AOs::Table} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${AOs::Table} .............................................................. +Table Table_inst; + +//${AOs::Table::SM} .......................................................... +static QState Table_initial(Table * const me, void const * const par) { + //${AOs::Table::SM::initial} + Q_UNUSED_PAR(par); + + #ifdef Q_SPY + Table *Table_inst = me; + QS_OBJ_DICTIONARY(Table_inst); + #endif + + QActive_subscribe(&me->super, DONE_SIG); + QActive_subscribe(&me->super, PAUSE_SIG); + QActive_subscribe(&me->super, SERVE_SIG); + QActive_subscribe(&me->super, TEST_SIG); + + for (uint8_t n = 0U; n < N_PHILO; ++n) { + me->fork[n] = FREE; + me->isHungry[n] = false; + BSP_displayPhilStat(n, THINKING); + } + + QS_FUN_DICTIONARY(&Table_active); + QS_FUN_DICTIONARY(&Table_serving); + QS_FUN_DICTIONARY(&Table_paused); + + return Q_TRAN(&Table_serving); +} + +//${AOs::Table::SM::active} .................................................. +static QState Table_active(Table * const me, QEvt const * const e) { + QState status_; + switch (e->sig) { + //${AOs::Table::SM::active::TEST} + case TEST_SIG: { + status_ = Q_HANDLED(); + break; + } + //${AOs::Table::SM::active::EAT} + case EAT_SIG: { + Q_ERROR(); + status_ = Q_HANDLED(); + break; + } + default: { + status_ = Q_SUPER(&QHsm_top); + break; + } + } + return status_; +} + +//${AOs::Table::SM::active::serving} ......................................... +static QState Table_serving(Table * const me, QEvt const * const e) { + QState status_; + switch (e->sig) { + //${AOs::Table::SM::active::serving} + case Q_ENTRY_SIG: { + // give permissions to eat... + for (uint8_t n = 0U; n < N_PHILO; ++n) { + if (me->isHungry[n] + && (me->fork[left(n)] == FREE) + && (me->fork[n] == FREE)) + { + me->fork[left(n)] = USED; + me->fork[n] = USED; + #ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, EAT_SIG, n); + #else + TableEvt *pe = Q_NEW(TableEvt, EAT_SIG); + pe->philoId = n; + #endif + QACTIVE_PUBLISH(&pe->super, &me->super); + me->isHungry[n] = false; + BSP_displayPhilStat(n, EATING); + } + } + status_ = Q_HANDLED(); + break; + } + //${AOs::Table::SM::active::serving::HUNGRY} + case HUNGRY_SIG: { + uint8_t n = Q_EVT_CAST(TableEvt)->philoId; + + // phil ID must be in range and he must be not hungry + Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); + + BSP_displayPhilStat(n, HUNGRY); + uint8_t m = left(n); + //${AOs::Table::SM::active::serving::HUNGRY::[bothfree]} + if ((me->fork[m] == FREE) && (me->fork[n] == FREE)) { + me->fork[m] = USED; + me->fork[n] = USED; + #ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, EAT_SIG, n); + #else + TableEvt *pe = Q_NEW(TableEvt, EAT_SIG); + pe->philoId = n; + #endif + QACTIVE_PUBLISH(&pe->super, &me->super); + BSP_displayPhilStat(n, EATING); + status_ = Q_HANDLED(); + } + //${AOs::Table::SM::active::serving::HUNGRY::[else]} + else { + me->isHungry[n] = true; + status_ = Q_HANDLED(); + } + break; + } + //${AOs::Table::SM::active::serving::DONE} + case DONE_SIG: { + uint8_t n = Q_EVT_CAST(TableEvt)->philoId; + + // phil ID must be in range and he must be not hungry + Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); + + BSP_displayPhilStat(n, THINKING); + uint8_t m = left(n); + + // both forks of Phil[n] must be used + Q_ASSERT((me->fork[n] == USED) && (me->fork[m] == USED)); + + me->fork[m] = FREE; + me->fork[n] = FREE; + m = right(n); // check the right neighbor + + if (me->isHungry[m] && (me->fork[m] == FREE)) { + me->fork[n] = USED; + me->fork[m] = USED; + me->isHungry[m] = false; + #ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, EAT_SIG, m); + #else + TableEvt *pe = Q_NEW(TableEvt, EAT_SIG); + pe->philoId = m; + #endif + QACTIVE_PUBLISH(&pe->super, &me->super); + BSP_displayPhilStat(m, EATING); + } + m = left(n); // check the left neighbor + n = left(m); // left fork of the left neighbor + if (me->isHungry[m] && (me->fork[n] == FREE)) { + me->fork[m] = USED; + me->fork[n] = USED; + me->isHungry[m] = false; + #ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, EAT_SIG, m); + #else + TableEvt *pe = Q_NEW(TableEvt, EAT_SIG); + pe->philoId = m; + #endif + QACTIVE_PUBLISH(&pe->super, &me->super); + BSP_displayPhilStat(m, EATING); + } + status_ = Q_HANDLED(); + break; + } + //${AOs::Table::SM::active::serving::EAT} + case EAT_SIG: { + Q_ERROR(); + status_ = Q_HANDLED(); + break; + } + //${AOs::Table::SM::active::serving::PAUSE} + case PAUSE_SIG: { + status_ = Q_TRAN(&Table_paused); + break; + } + default: { + status_ = Q_SUPER(&Table_active); + break; + } + } + return status_; +} + +//${AOs::Table::SM::active::paused} .......................................... +static QState Table_paused(Table * const me, QEvt const * const e) { + QState status_; + switch (e->sig) { + //${AOs::Table::SM::active::paused} + case Q_ENTRY_SIG: { + BSP_displayPaused(1U); + status_ = Q_HANDLED(); + break; + } + //${AOs::Table::SM::active::paused} + case Q_EXIT_SIG: { + BSP_displayPaused(0U); + status_ = Q_HANDLED(); + break; + } + //${AOs::Table::SM::active::paused::SERVE} + case SERVE_SIG: { + status_ = Q_TRAN(&Table_serving); + break; + } + //${AOs::Table::SM::active::paused::HUNGRY} + case HUNGRY_SIG: { + uint8_t n = Q_EVT_CAST(TableEvt)->philoId; + + // philo ID must be in range and he must be not hungry + Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); + + me->isHungry[n] = true; + BSP_displayPhilStat(n, HUNGRY); + status_ = Q_HANDLED(); + break; + } + //${AOs::Table::SM::active::paused::DONE} + case DONE_SIG: { + uint8_t n = Q_EVT_CAST(TableEvt)->philoId; + + // phil ID must be in range and he must be not hungry + Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); + + BSP_displayPhilStat(n, THINKING); + uint8_t m = left(n); + + // both forks of Phil[n] must be used + Q_ASSERT((me->fork[n] == USED) && (me->fork[m] == USED)); + + me->fork[m] = FREE; + me->fork[n] = FREE; + status_ = Q_HANDLED(); + break; + } + default: { + status_ = Q_SUPER(&Table_active); + break; + } + } + return status_; +} +//$enddef${AOs::Table} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/examples/workstation/dpp/Makefile b/examples/posix-win32/dpp_comp/Makefile similarity index 94% rename from examples/workstation/dpp/Makefile rename to examples/posix-win32/dpp_comp/Makefile index 68232133..91ab48d7 100644 --- a/examples/workstation/dpp/Makefile +++ b/examples/posix-win32/dpp_comp/Makefile @@ -1,7 +1,7 @@ ############################################################################## # Product: Makefile for QP/C for Windows and POSIX *HOSTS* -# Last updated for version 7.2.0 -# Last updated on 2022-11-13 +# Last updated for version 7.3.0 +# Last updated on 2023-09-03 # # Q u a n t u m L e a P s # ------------------------ @@ -43,7 +43,7 @@ # NOTE: # To use this Makefile on Windows, you will need the GNU make utility, which # is included in the QTools collection for Windows, see: -# http://sourceforge.net/projects/qpc/files/QTools/ +# https://github.com/QuantumLeaps/qtools # #----------------------------------------------------------------------------- @@ -56,10 +56,10 @@ PROJECT := dpp # # list of all source directories used by this project -VPATH := . \ +VPATH := . # list of all include directories needed by this project -INCLUDES := -I. \ +INCLUDES := -I. # location of the QP/C framework (if not provided in an env. variable) ifeq ($(QPC),) @@ -85,7 +85,8 @@ LIBS := # defines... # QP_API_VERSION controls the QP API compatibility; 9999 means the latest API -DEFINES := -DQP_API_VERSION=9999 +DEFINES := -DQP_CONFIG \ + $(DEF) ifeq (,$(CONF)) CONF := dbg @@ -141,7 +142,7 @@ LIBS += -lpthread endif -#============================================================================ +#============================================================================= # Typically you should not need to change anything below this line VPATH += $(QPC)/src/qf $(QP_PORT_DIR) @@ -152,8 +153,8 @@ INCLUDES += -I$(QPC)/include -I$(QP_PORT_DIR) # # NOTE: # GNU toolset (MinGW) is included in the QTools collection for Windows, see: -# https://www.state-machine.com/qtools -# It is assumed that %QTOOLS%\bin directory is added to the PATH +# https://github.com/QuantumLeaps/qtools +# It is assumed that $(QTOOLS)/bin directory is added to the PATH # CC := gcc CPP := g++ @@ -234,6 +235,11 @@ C_DEPS_EXT := $(patsubst %.o,%.d, $(C_OBJS_EXT)) CPP_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(CPP_OBJS)) CPP_DEPS_EXT := $(patsubst %.o,%.d, $(CPP_OBJS_EXT)) +# create $(BIN_DIR) if it does not exist +ifeq ("$(wildcard $(BIN_DIR))","") +$(shell $(MKDIR) $(BIN_DIR)) +endif + #----------------------------------------------------------------------------- # rules # @@ -243,7 +249,7 @@ CPP_DEPS_EXT := $(patsubst %.o,%.d, $(CPP_OBJS_EXT)) all: $(TARGET_EXE) $(TARGET_EXE) : $(C_OBJS_EXT) $(CPP_OBJS_EXT) - $(CC) $(CFLAGS) $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o + $(CC) $(CFLAGS) $(QPC)/src/qs/qstamp.c -o $(BIN_DIR)/qstamp.o $(LINK) $(LINKFLAGS) $(LIB_DIRS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) $(BIN_DIR)/%.d : %.c diff --git a/examples/posix-win32/dpp_comp/bsp.c b/examples/posix-win32/dpp_comp/bsp.c new file mode 100644 index 00000000..9d00b46b --- /dev/null +++ b/examples/posix-win32/dpp_comp/bsp.c @@ -0,0 +1,206 @@ +//============================================================================ +// Product: BSP for DPP example (console) +// Last Updated for Version: 7.3.0 +// Date of the Last Update: 2023-08-21 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// This program is open source software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Alternatively, this program may be distributed and modified under the +// terms of Quantum Leaps commercial licenses, which expressly supersede +// the GNU General Public License and are specifically designed for +// licensees interested in retaining the proprietary status of their code. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Contact information: +// +// +//============================================================================ +#include "qpc.h" // QP/C real-time embedded framework +#include "dpp.h" // DPP Application interface +#include "bsp.h" // Board Support Package + +#include "safe_std.h" // portable "safe" / facilities +#include // for exit() + +Q_DEFINE_THIS_FILE + +// Local objects ------------------------------------------------------------- +static uint32_t l_rnd; // random seed + +#ifdef Q_SPY + enum { + PHILO_STAT = QS_USER, + PAUSED_STAT, + }; + + // QSpy source IDs + static QSpyId const l_clock_tick = { QS_AP_ID }; +#endif + +//============================================================================ +Q_NORETURN Q_onError(char const * const module, int_t const id) { + QS_ASSERTION(module, id, 10000U); // report assertion to QS + FPRINTF_S(stderr, "ERROR in %s:%d", module, id); + QF_onCleanup(); + QS_EXIT(); + exit(-1); +} +//............................................................................ +void assert_failed(char const * const module, int_t const id); // prototype +void assert_failed(char const * const module, int_t const id) { + Q_onError(module, id); +} + +//============================================================================ +void BSP_init(int argc, char *argv[]) { + Q_UNUSED_PAR(argc); + Q_UNUSED_PAR(argv); + + PRINTF_S("Dining Philosophers Problem example" + "\nQP %s\n" + "Press 'p' to pause\n" + "Press 's' to serve\n" + "Press ESC to quit...\n", + QP_VERSION_STR); + + BSP_randomSeed(1234U); + + // initialize the QS software tracing + if (QS_INIT((argc > 1) ? argv[1] : (void *)0) == 0U) { + Q_ERROR(); + } + + QS_OBJ_DICTIONARY(&l_clock_tick); + + QS_USR_DICTIONARY(PHILO_STAT); + QS_USR_DICTIONARY(PAUSED_STAT); + + QS_ONLY(produce_sig_dict()); + + // setup the QS filters... + QS_GLB_FILTER(QS_ALL_RECORDS); + QS_GLB_FILTER(-QS_QF_TICK); // exclude the tick record +} +//............................................................................ +void BSP_start(void) { + // initialize event pools + static QF_MPOOL_EL(TableEvt) smlPoolSto[2*N_PHILO]; + QF_poolInit(smlPoolSto, sizeof(smlPoolSto), sizeof(smlPoolSto[0])); + + // initialize publish-subscribe + static QSubscrList subscrSto[MAX_PUB_SIG]; + QActive_psInit(subscrSto, Q_DIM(subscrSto)); + + // instantiate and start AOs/threads... + + static QEvt const *tableQueueSto[N_PHILO]; + Table_ctor(); + QACTIVE_START(AO_Table, + N_PHILO + 7U, // QP prio. of the AO + tableQueueSto, // event queue storage + Q_DIM(tableQueueSto), // queue length [events] + (void *)0, 0U, // no stack storage + (void *)0); // no initialization param +} +//............................................................................ +void BSP_terminate(int16_t result) { + (void)result; + QF_stop(); // stop the main "ticker thread" +} +//............................................................................ +void BSP_displayPhilStat(uint8_t n, char const *stat) { + PRINTF_S("Philosopher %2d is %s\n", (int)n, stat); + + // application-specific record + QS_BEGIN_ID(PHILO_STAT, AO_Table->prio) + QS_U8(1, n); // Philosopher number + QS_STR(stat); // Philosopher status + QS_END() +} +//............................................................................ +void BSP_displayPaused(uint8_t paused) { + PRINTF_S("Paused is %s\n", paused ? "ON" : "OFF"); +} +//............................................................................ +uint32_t BSP_random(void) { // a very cheap pseudo-random-number generator + // "Super-Duper" Linear Congruential Generator (LCG) + // LCG(2^32, 3*7*11*13*23, 0, seed) + // + l_rnd = l_rnd * (3U*7U*11U*13U*23U); + return l_rnd >> 8; +} +//............................................................................ +void BSP_randomSeed(uint32_t seed) { + l_rnd = seed; +} + +//============================================================================ +void QF_onStartup(void) { + QF_consoleSetup(); + QF_setTickRate(BSP_TICKS_PER_SEC, 10); // desired tick rate/ticker-prio +} +//............................................................................ +void QF_onCleanup(void) { + PRINTF_S("\n%s\n", "Bye! Bye!"); + QF_consoleCleanup(); +} +//............................................................................ +void QF_onClockTick(void) { + + QTIMEEVT_TICK_X(0U, &l_clock_tick); // process time events at rate 0 + + QS_RX_INPUT(); // handle the QS-RX input + QS_OUTPUT(); // handle the QS output + + switch (QF_consoleGetKey()) { + case '\33': { // ESC pressed? + BSP_terminate(0); + break; + } + case 'p': { + static QEvt const pauseEvt = QEVT_INITIALIZER(PAUSE_SIG); + QACTIVE_PUBLISH(&pauseEvt, &l_clock_tick); + break; + } + case 's': { + static QEvt const serveEvt = QEVT_INITIALIZER(SERVE_SIG); + QACTIVE_PUBLISH(&serveEvt, &l_clock_tick); + break; + } + default: { + break; + } + } +} + +//============================================================================ +#ifdef Q_SPY // define QS callbacks + +//............................................................................ +//! callback function to execute user commands +void QS_onCommand(uint8_t cmdId, + uint32_t param1, uint32_t param2, uint32_t param3) +{ + Q_UNUSED_PAR(cmdId); + Q_UNUSED_PAR(param1); + Q_UNUSED_PAR(param2); + Q_UNUSED_PAR(param3); +} + +#endif // Q_SPY diff --git a/examples/posix-win32/dpp_comp/bsp.h b/examples/posix-win32/dpp_comp/bsp.h new file mode 100644 index 00000000..a9b952ac --- /dev/null +++ b/examples/posix-win32/dpp_comp/bsp.h @@ -0,0 +1,51 @@ +//============================================================================ +// Product: DPP example (console) +// Last Updated for Version: 7.3.0 +// Date of the Last Update: 2023-08-12 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. +// +// This program is open source software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Alternatively, this program may be distributed and modified under the +// terms of Quantum Leaps commercial licenses, which expressly supersede +// the GNU General Public License and are specifically designed for +// licensees interested in retaining the proprietary status of their code. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Contact information: +// +// +//============================================================================ +#ifndef BSP_H_ +#define BSP_H_ + +#define BSP_TICKS_PER_SEC 100U + +void BSP_init(int argc, char *argv[]); +void BSP_start(void); +void BSP_displayPaused(uint8_t paused); +void BSP_displayPhilStat(uint8_t n, char const *stat); +void BSP_terminate(int16_t result); + +void BSP_randomSeed(uint32_t seed); // random seed +uint32_t BSP_random(void); // pseudo-random generator + +void BSP_ledOn(void); +void BSP_ledOff(void); + +#endif // BSP_H_ diff --git a/examples/workstation/dpp-comp/dpp-comp.qm b/examples/posix-win32/dpp_comp/dpp-comp.qm similarity index 67% rename from examples/workstation/dpp-comp/dpp-comp.qm rename to examples/posix-win32/dpp_comp/dpp-comp.qm index c49158fc..c37113b7 100644 --- a/examples/workstation/dpp-comp/dpp-comp.qm +++ b/examples/posix-win32/dpp_comp/dpp-comp.qm @@ -1,8 +1,9 @@ - + Dining Philosopher Problem example with the "Orthogonal Component" state pattern (see https://state-machine.com/doc/Pattern_Orthogonal.pdf) The model demonstrates the following features: + 1. Partitioning the application into Container and Components 2. Packages for Container (Cont) and Components (Comp) 3. External packages with speparate QM-package model files @@ -11,13 +12,73 @@ The model demonstrates the following features: 6. Component to Container communication via asynchronous event posting using the LIFO policy. + + + + + { + EAT_SIG = Q_USER_SIG, // published by Table to let a Philo eat + DONE_SIG, // published by Philo when done eating + PAUSE_SIG, // published by BSP to pause the application + SERVE_SIG, // published by BSP to serve re-start serving forks + TEST_SIG, // published by BSP to test the application + MAX_PUB_SIG, // the last published signal + + TIMEOUT_SIG, // posted by time event to Philo + HUNGRY_SIG, // posted by hungry Philo to Table + MAX_SIG // the last signal +}; + + + + QS_SIG_DICTIONARY(EAT_SIG, (void *)0); +QS_SIG_DICTIONARY(DONE_SIG, (void *)0); +QS_SIG_DICTIONARY(PAUSE_SIG, (void *)0); +QS_SIG_DICTIONARY(SERVE_SIG, (void *)0); +QS_SIG_DICTIONARY(TEST_SIG, (void *)0); + +QS_SIG_DICTIONARY(TIMEOUT_SIG, (void *)0); +QS_SIG_DICTIONARY(HUNGRY_SIG, (void *)0); + + + + ((uint8_t)5U) + + + + + + + + + + if (me != (TableEvt *)0) { + // don't call QEvt_ctor() because the initialization of all + // QEvt attributes is already done in QF_QF_newX_() + me->philoId = id; +} +return me; + + + + + = &Table_inst.super; + + + + Table *me = &Table_inst; +QActive_ctor(&me->super, Q_STATE_CAST(&Table_initial)); + +for (uint8_t n = 0U; n < N_PHILO; ++n) { + Philo_ctor(n); // create the Philo component + + me->fork[n] = FREE; + me->isHungry[n] = 0U; +} + + - - - - - @@ -32,7 +93,7 @@ The model demonstrates the following features: - (void)par; /* unused parameter */ + (void)par; // unused parameter QS_OBJ_DICTIONARY(&Table_inst); @@ -44,7 +105,7 @@ for (uint8_t n = 0U; n < N_PHILO; ++n) { me->fork[n] = FREE; me->isHungry[n] = 0U; - QHSM_INIT(SM_Philo[n], (void *)0, QS_AP_ID + n); + QASM_INIT(SM_Philo[n], (void *)0, QS_AP_ID + n); BSP_displayPhilStat(n, "thinking"); } @@ -56,7 +117,7 @@ for (uint8_t n = 0U; n < N_PHILO; ++n) { uint16_t n = Q_EVT_CAST(CompTimeEvt)->compNum; -QHSM_DISPATCH(SM_Philo[n], e, QS_AP_ID + n); +QASM_DISPATCH(SM_Philo[n], e, QS_AP_ID + n); @@ -76,19 +137,20 @@ QHSM_DISPATCH(SM_Philo[n], e, QS_AP_ID + n); - for (uint8_t n = 0U; n < N_PHILO; ++n) { /* give permissions to eat... */ + for (uint8_t n = 0U; n < N_PHILO; ++n) { // give permissions to eat... if ((me->isHungry[n] != 0U) - && (me->fork[LEFT(n)] == FREE) + && (me->fork[left(n)] == FREE) && (me->fork[n] == FREE)) { - me->fork[LEFT(n)] = USED; + me->fork[left(n)] = USED; me->fork[n] = USED; - /* synchronoulsy dispatch EAT event to the Philo component */ - TableEvt evt; - evt.super.sig = EAT_SIG; - evt.philoNum = n; - QHSM_DISPATCH(SM_Philo[n], &evt.super, QS_AP_ID + n); + // synchronously dispatch EAT event to the Philo component + TableEvt const evt = { + QEVT_INITIALIZER(EAT_SIG), + .philoId = n + }; + QASM_DISPATCH(SM_Philo[n], &evt.super, QS_AP_ID + n); me->isHungry[n] = 0U; BSP_displayPhilStat(n, "eating "); @@ -96,24 +158,25 @@ QHSM_DISPATCH(SM_Philo[n], e, QS_AP_ID + n); } - /* find the index of the Philo from the event */ -uint8_t n = Q_EVT_CAST(TableEvt)->philoNum; -/* philo ID must be in range and he must be not hungry */ + // find the index of the Philo from the event +uint8_t n = Q_EVT_CAST(TableEvt)->philoId; +// philo ID must be in range and he must be not hungry Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); BSP_displayPhilStat(n, "hungry "); -uint8_t m = LEFT(n); +uint8_t m = left(n); (me->fork[m] == FREE) && (me->fork[n] == FREE) me->fork[m] = USED; me->fork[n] = USED; -/* synchronoulsy dispatch EAT event to the Philo component */ -TableEvt evt; -evt.super.sig = EAT_SIG; -evt.philoNum = n; -QHSM_DISPATCH(SM_Philo[n], &evt.super, QS_AP_ID + n); +// synchronously dispatch EAT event to the Philo component +TableEvt const evt = { + QEVT_INITIALIZER(EAT_SIG), + .philoId = n +}; +QASM_DISPATCH(SM_Philo[n], &evt.super, QS_AP_ID + n); BSP_displayPhilStat(n, "eating "); @@ -133,43 +196,46 @@ BSP_displayPhilStat(n, "eating "); - /* find the index of the Philo from the event */ -uint8_t n = Q_EVT_CAST(TableEvt)->philoNum; -/* philo ID must be in range and he must be not hungry */ + // find the index of the Philo from the event +uint8_t n = Q_EVT_CAST(TableEvt)->philoId; +// philo ID must be in range and he must be not hungry Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); BSP_displayPhilStat(n, "thinking"); -uint8_t m = LEFT(n); -/* both forks of Phil[n] must be used */ +uint8_t m = left(n); +// both forks of Phil[n] must be used Q_ASSERT((me->fork[n] == USED) && (me->fork[m] == USED)); me->fork[m] = FREE; me->fork[n] = FREE; -m = RIGHT(n); /* check the right neighbor */ +m = right(n); // check the right neighbor -TableEvt evt; if ((me->isHungry[m] != 0U) && (me->fork[m] == FREE)) { me->fork[n] = USED; me->fork[m] = USED; me->isHungry[m] = 0U; - /* synchronoulsy dispatch EAT event to the Philo component */ - evt.super.sig = EAT_SIG; - evt.philoNum = m; - QHSM_DISPATCH(SM_Philo[m], &evt.super, QS_AP_ID + m); + // synchronously dispatch EAT event to the Philo component + TableEvt const evt = { + QEVT_INITIALIZER(EAT_SIG), + .philoId = m + }; + QASM_DISPATCH(SM_Philo[m], &evt.super, QS_AP_ID + m); BSP_displayPhilStat(m, "eating "); } -m = LEFT(n); /* check the left neighbor */ -n = LEFT(m); /* left fork of the left neighbor */ +m = left(n); // check the left neighbor +n = left(m); // left fork of the left neighbor if ((me->isHungry[m] != 0U) && (me->fork[n] == FREE)) { me->fork[m] = USED; me->fork[n] = USED; me->isHungry[m] = 0U; - /* synchronoulsy dispatch EAT event to the Philo component */ - evt.super.sig = EAT_SIG; - evt.philoNum = m; - QHSM_DISPATCH(SM_Philo[m], &evt.super, QS_AP_ID + m); + // synchronously dispatch EAT event to the Philo component + TableEvt const evt = { + QEVT_INITIALIZER(EAT_SIG), + .philoId = m + }; + QASM_DISPATCH(SM_Philo[m], &evt.super, QS_AP_ID + m); BSP_displayPhilStat(m, "eating "); } @@ -205,9 +271,9 @@ if ((me->isHungry[m] != 0U) && (me->fork[n] == FREE)) { - /* find the index of the Philo from the event */ -uint8_t n = Q_EVT_CAST(TableEvt)->philoNum; -/* philo ID must be in range and he must be not hungry */ + // find the index of the Philo from the event +uint8_t n = Q_EVT_CAST(TableEvt)->philoId; +// philo ID must be in range and he must be not hungry Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); me->isHungry[n] = 1U; @@ -218,14 +284,14 @@ BSP_displayPhilStat(n, "hungry "); - /* find the index of the Philo from the event */ -uint8_t n = Q_EVT_CAST(TableEvt)->philoNum; -/* philo ID must be in range and he must be not hungry */ + // find the index of the Philo from the event +uint8_t n = Q_EVT_CAST(TableEvt)->philoId; +// philo ID must be in range and he must be not hungry Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); BSP_displayPhilStat(n, "thinking"); -uint8_t m = LEFT(n); -/* both forks of Phil[n] must be used */ +uint8_t m = left(n); +// both forks of Phil[n] must be used Q_ASSERT((me->fork[n] == USED) && (me->fork[m] == USED)); me->fork[m] = FREE; @@ -244,21 +310,6 @@ me->fork[n] = FREE; - - - = &Table_inst.super; /* opaque pointer */ - - - - Table *me = &Table_inst; -QActive_ctor(&me->super, Q_STATE_CAST(&Table_initial)); - -for (uint8_t n = 0U; n < N_PHILO; ++n) { - me->fork[n] = FREE; - me->isHungry[n] = 0U; - Philo_ctor(n); /* create the Philo component */ -} - @@ -290,21 +341,24 @@ me->compNum = num; + + + return (uint8_t)(me - &Philo_inst[0]); + - (void)par; /* unused parameter */ + Q_UNUSED_PAR(par); #ifdef Q_SPY -uint8_t n = (uint8_t)(me - &Philo_inst[0]); -QS_OBJ_ARR_DICTIONARY(&Philo_inst[n], n); -QS_OBJ_ARR_DICTIONARY(&Philo_inst[n].timeEvt, n); +uint8_t id = (uint8_t)(me - &Philo_inst[0]); +QS_OBJ_ARR_DICTIONARY(&Philo_inst[id], id); +QS_OBJ_ARR_DICTIONARY(&Philo_inst[id].timeEvt, id); #endif -/* the following code outputs the "fun-dictionaries" only once for -* all Philo instances, as opposed to repeat them for every instance. -*/ +// the following code outputs the "fun-dictionaries" only once for +// all Philo instances, as opposed to repeat them for every instance. static bool registered = false; if (!registered) { registered = true; @@ -341,9 +395,13 @@ if (!registered) { - /* asynchronously post event to the Container */ + // asynchronously post event to the Container +#ifdef QEVT_DYN_CTOR +TableEvt const *pe = Q_NEW(TableEvt, HUNGRY_SIG, Philo_getId(me)); +#else TableEvt *pe = Q_NEW(TableEvt, HUNGRY_SIG); -pe->philoNum = (uint8_t)(me - &Philo_inst[0]); +pe->philoId = Philo_getId(me); +#endif QACTIVE_POST_LIFO(AO_Table, &pe->super); @@ -360,9 +418,13 @@ QACTIVE_POST_LIFO(AO_Table, &pe->super); QTimeEvt_armX(&me->timeEvt.super, EAT_TIME, 0U); QTimeEvt_disarm(&me->timeEvt.super); -/* asynchronously post event to the Container */ +// asynchronously post event to the Container +#ifdef QEVT_DYN_CTOR +TableEvt const *pe = Q_NEW(TableEvt, DONE_SIG, Philo_getId(me)); +#else TableEvt *pe = Q_NEW(TableEvt, DONE_SIG); -pe->philoNum = (uint8_t)(me - &Philo_inst[0]); +pe->philoId = Philo_getId(me); +#endif QACTIVE_POST_LIFO(AO_Table, &pe->super); @@ -379,13 +441,13 @@ QACTIVE_POST_LIFO(AO_Table, &pe->super); - - = { /* opaque pointers to Philo instances */ - &Philo_inst[0].super, - &Philo_inst[1].super, - &Philo_inst[2].super, - &Philo_inst[3].super, - &Philo_inst[4].super + + = { // opaque pointers to Philo instances + (QAsm *)&Philo_inst[0], + (QAsm *)&Philo_inst[1], + (QAsm *)&Philo_inst[2], + (QAsm *)&Philo_inst[3], + (QAsm *)&Philo_inst[4] }; @@ -401,35 +463,16 @@ CompTimeEvt_ctor(&me->timeEvt, AO_Table, n, TIMEOUT_SIG, 0U); - #ifndef DPP_H -#define DPP_H + #ifndef DPP_H_ +#define DPP_H_ -enum DPPSignals { - EAT_SIG = Q_USER_SIG, /* published by Table to let a philosopher eat */ - DONE_SIG, /* published by Philosopher when done eating */ - PAUSE_SIG, /* published by BSP to pause serving forks */ - SERVE_SIG, /* published by BSP to serve re-start serving forks */ - TEST_SIG, /* published by BSP to test the application */ - MAX_PUB_SIG, /* the last published signal */ - - HUNGRY_SIG, /* posted direclty to Table from hungry Philo */ - TIMEOUT_SIG, /* used by Philosophers for time events */ - MAX_SIG /* the last signal */ -}; - -enum { - N_PHILO = 5 /* number of Philos */ -}; - -$declare ${Cont::TableEvt} -$declare ${Cont::Table_ctor} -$declare ${Cont::AO_Table} +$declare ${Shared} $declare ${Comp::CompTimeEvt} $declare ${Comp::SM_Philo[N_PHILO]} $declare ${Comp::Philo_ctor} -#endif /* DPP_H */ +#endif // DPP_H_ @@ -441,13 +484,13 @@ $declare ${Comp::Philo_ctor} $declare ${Comp::Philo} -/* helper macros to provide a randomized think time for Philos */ +// helper macros to provide a randomized think time for Philos #define THINK_TIME \ (QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + (BSP_TICKS_PER_SEC/2U)) #define EAT_TIME \ (QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + BSP_TICKS_PER_SEC) -/* definition of the whole "Comp" package */ +// definition of the whole "Comp" package $define ${Comp} @@ -458,14 +501,27 @@ $define ${Comp} Q_DEFINE_THIS_FILE +// helper function to provide the RIGHT neighbor of a Philo[n] +static inline uint8_t right(uint8_t const n) { + return (uint8_t)((n + (N_PHILO - 1U)) % N_PHILO); +} + +// helper function to provide the LEFT neighbor of a Philo[n] +static inline uint8_t left(uint8_t const n) { + return (uint8_t)((n + 1U) % N_PHILO); +} + +#define FREE ((uint8_t)0U) +#define USED ((uint8_t)1U) + +#define THINKING "thinking" +#define HUNGRY "hungry " +#define EATING "eating " + $declare ${Cont::Table} -#define RIGHT(n_) ((uint8_t)(((n_) + (N_PHILO - 1U)) % N_PHILO)) -#define LEFT(n_) ((uint8_t)(((n_) + 1U) % N_PHILO)) -#define FREE ((uint8_t)0) -#define USED ((uint8_t)1) - -/* definition of the whole "Cont" package */ +$define ${Shared::Table_ctor} +$define ${Shared::AO_Table} $define ${Cont} diff --git a/examples/posix-win32/dpp_comp/dpp.h b/examples/posix-win32/dpp_comp/dpp.h new file mode 100644 index 00000000..3d73574a --- /dev/null +++ b/examples/posix-win32/dpp_comp/dpp.h @@ -0,0 +1,127 @@ +//$file${.::dpp.h} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// +// Model: dpp-comp.qm +// File: ${.::dpp.h} +// +// This code has been generated by QM 5.3.0 . +// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. +// +// SPDX-License-Identifier: GPL-3.0-or-later +// +// This generated code is open source software: you can redistribute it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation. +// +// This code is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// NOTE: +// Alternatively, this generated code may be distributed under the terms +// of Quantum Leaps commercial licenses, which expressly supersede the GNU +// General Public License and are specifically designed for licensees +// interested in retaining the proprietary status of their code. +// +// Contact information: +// +// +// +//$endhead${.::dpp.h} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +#ifndef DPP_H_ +#define DPP_H_ + +//$declare${Shared} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${Shared::AppSignals} ...................................................... +enum AppSignals { + EAT_SIG = Q_USER_SIG, // published by Table to let a Philo eat + DONE_SIG, // published by Philo when done eating + PAUSE_SIG, // published by BSP to pause the application + SERVE_SIG, // published by BSP to serve re-start serving forks + TEST_SIG, // published by BSP to test the application + MAX_PUB_SIG, // the last published signal + + TIMEOUT_SIG, // posted by time event to Philo + HUNGRY_SIG, // posted by hungry Philo to Table + MAX_SIG // the last signal +}; + +//${Shared::produce_sig_dict} ................................................ +#ifdef Q_SPY +static inline void produce_sig_dict(void) { + QS_SIG_DICTIONARY(EAT_SIG, (void *)0); + QS_SIG_DICTIONARY(DONE_SIG, (void *)0); + QS_SIG_DICTIONARY(PAUSE_SIG, (void *)0); + QS_SIG_DICTIONARY(SERVE_SIG, (void *)0); + QS_SIG_DICTIONARY(TEST_SIG, (void *)0); + + QS_SIG_DICTIONARY(TIMEOUT_SIG, (void *)0); + QS_SIG_DICTIONARY(HUNGRY_SIG, (void *)0); +} +#endif // def Q_SPY + +//${Shared::N_PHILO} ......................................................... +#define N_PHILO ((uint8_t)5U) + +//${Shared::TableEvt} ........................................................ +typedef struct { +// protected: + QEvt super; + +// public: + uint8_t philoId; +} TableEvt; + +// public: + +#ifdef QEVT_DYN_CTOR +static inline TableEvt * TableEvt_ctor(TableEvt * const me, + uint8_t id) +{ + if (me != (TableEvt *)0) { + // don't call QEvt_ctor() because the initialization of all + // QEvt attributes is already done in QF_QF_newX_() + me->philoId = id; + } + return me; +} +#endif // def QEVT_DYN_CTOR + +//${Shared::AO_Table} ........................................................ +extern QActive * const AO_Table; + +//${Shared::Table_ctor} ...................................................... +void Table_ctor(void); +//$enddecl${Shared} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +//$declare${Comp::CompTimeEvt} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${Comp::CompTimeEvt} ....................................................... +typedef struct { +// protected: + QTimeEvt super; + +// public: + uint16_t compNum; +} CompTimeEvt; + +// public: +void CompTimeEvt_ctor(CompTimeEvt * const me, + QActive * act, + uint16_t num, + enum_t const sig, + uint_fast8_t const tickRate); +//$enddecl${Comp::CompTimeEvt} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +//$declare${Comp::SM_Philo[N_PHILO]} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${Comp::SM_Philo[N_PHILO]} ................................................. +extern QAsm * const SM_Philo[N_PHILO]; +//$enddecl${Comp::SM_Philo[N_PHILO]} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +//$declare${Comp::Philo_ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${Comp::Philo_ctor} ........................................................ +void Philo_ctor(uint8_t n); +//$enddecl${Comp::Philo_ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +#endif // DPP_H_ diff --git a/examples/threadx/win32/dpp_console/vs_2019/dpp.sln b/examples/posix-win32/dpp_comp/dpp.sln similarity index 82% rename from examples/threadx/win32/dpp_console/vs_2019/dpp.sln rename to examples/posix-win32/dpp_comp/dpp.sln index 9be92de9..aa11609f 100644 --- a/examples/threadx/win32/dpp_console/vs_2019/dpp.sln +++ b/examples/posix-win32/dpp_comp/dpp.sln @@ -10,6 +10,8 @@ Global Debug|x64 = Debug|x64 QSpy|Win32 = QSpy|Win32 QSpy|x64 = QSpy|x64 + QSpy64|Win32 = QSpy64|Win32 + QSpy64|x64 = QSpy64|x64 Release|Win32 = Release|Win32 Release|x64 = Release|x64 EndGlobalSection @@ -22,6 +24,10 @@ Global {8CC465F7-872E-4D03-B93C-1B64858B4E11}.QSpy|Win32.Build.0 = QSpy|Win32 {8CC465F7-872E-4D03-B93C-1B64858B4E11}.QSpy|x64.ActiveCfg = QSpy|x64 {8CC465F7-872E-4D03-B93C-1B64858B4E11}.QSpy|x64.Build.0 = QSpy|x64 + {8CC465F7-872E-4D03-B93C-1B64858B4E11}.QSpy64|Win32.ActiveCfg = QSpy64|Win32 + {8CC465F7-872E-4D03-B93C-1B64858B4E11}.QSpy64|Win32.Build.0 = QSpy64|Win32 + {8CC465F7-872E-4D03-B93C-1B64858B4E11}.QSpy64|x64.ActiveCfg = QSpy64|x64 + {8CC465F7-872E-4D03-B93C-1B64858B4E11}.QSpy64|x64.Build.0 = QSpy64|x64 {8CC465F7-872E-4D03-B93C-1B64858B4E11}.Release|Win32.ActiveCfg = Release|Win32 {8CC465F7-872E-4D03-B93C-1B64858B4E11}.Release|Win32.Build.0 = Release|Win32 {8CC465F7-872E-4D03-B93C-1B64858B4E11}.Release|x64.ActiveCfg = Release|x64 diff --git a/examples/workstation/dpp/dpp.vcxproj b/examples/posix-win32/dpp_comp/dpp.vcxproj similarity index 99% rename from examples/workstation/dpp/dpp.vcxproj rename to examples/posix-win32/dpp_comp/dpp.vcxproj index 9aea928f..ff41f993 100644 --- a/examples/workstation/dpp/dpp.vcxproj +++ b/examples/posix-win32/dpp_comp/dpp.vcxproj @@ -149,6 +149,7 @@ ProgramDatabase 4127 Default + stdc11 %(AdditionalDependencies) @@ -203,6 +204,7 @@ Level4 ProgramDatabase 4127 + stdc11 %(AdditionalDependencies) @@ -260,6 +262,7 @@ Level4 ProgramDatabase 4127 + stdc11 ws2_32.lib;%(AdditionalDependencies) @@ -311,6 +314,7 @@ Level4 ProgramDatabase 4127 + stdc11 ws2_32.lib;%(AdditionalDependencies) diff --git a/examples/workstation/dpp/dpp.vcxproj.filters b/examples/posix-win32/dpp_comp/dpp.vcxproj.filters similarity index 100% rename from examples/workstation/dpp/dpp.vcxproj.filters rename to examples/posix-win32/dpp_comp/dpp.vcxproj.filters diff --git a/examples/posix-win32/dpp_comp/main.c b/examples/posix-win32/dpp_comp/main.c new file mode 100644 index 00000000..392e9100 --- /dev/null +++ b/examples/posix-win32/dpp_comp/main.c @@ -0,0 +1,44 @@ +//============================================================================ +// APP example +// Last updated for version 7.3.0 +// Last updated on 2023-08-09 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. +// +// This program is open source software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Alternatively, this program may be distributed and modified under the +// terms of Quantum Leaps commercial licenses, which expressly supersede +// the GNU General Public License and are specifically designed for +// licensees interested in retaining the proprietary status of their code. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Contact information: +// +// +//============================================================================ +#include "qpc.h" // QP/C real-time embedded framework +#include "dpp.h" // DPP Application interface +#include "bsp.h" // Board Support Package + +//............................................................................ +int main(int argc, char *argv[]) { + QF_init(); // initialize the framework + BSP_init(argc, argv); // initialize the BSP + BSP_start(); // start the AOs/Threads + return QF_run(); // run the QF application +} diff --git a/examples/posix-win32/dpp_comp/philo.c b/examples/posix-win32/dpp_comp/philo.c new file mode 100644 index 00000000..904b17e2 --- /dev/null +++ b/examples/posix-win32/dpp_comp/philo.c @@ -0,0 +1,238 @@ +//$file${.::philo.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// +// Model: dpp-comp.qm +// File: ${.::philo.c} +// +// This code has been generated by QM 5.3.0 . +// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. +// +// SPDX-License-Identifier: GPL-3.0-or-later +// +// This generated code is open source software: you can redistribute it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation. +// +// This code is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// NOTE: +// Alternatively, this generated code may be distributed under the terms +// of Quantum Leaps commercial licenses, which expressly supersede the GNU +// General Public License and are specifically designed for licensees +// interested in retaining the proprietary status of their code. +// +// Contact information: +// +// +// +//$endhead${.::philo.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +#include "qpc.h" +#include "dpp.h" +#include "bsp.h" + +//Q_DEFINE_THIS_FILE + +//$declare${Comp::Philo} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${Comp::Philo} ............................................................. +typedef struct Philo { +// protected: + QHsm super; + +// public: + +// private: + CompTimeEvt timeEvt; +} Philo; + +extern Philo Philo_inst[N_PHILO]; + +// public: +static inline uint8_t Philo_getId(Philo * const me) { + return (uint8_t)(me - &Philo_inst[0]); +} + +// protected: +static QState Philo_initial(Philo * const me, void const * const par); +static QState Philo_thinking(Philo * const me, QEvt const * const e); +static QState Philo_hungry(Philo * const me, QEvt const * const e); +static QState Philo_eating(Philo * const me, QEvt const * const e); +//$enddecl${Comp::Philo} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +// helper macros to provide a randomized think time for Philos +#define THINK_TIME \ + (QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + (BSP_TICKS_PER_SEC/2U)) +#define EAT_TIME \ + (QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + BSP_TICKS_PER_SEC) + +// definition of the whole "Comp" package +//$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// Check for the minimum required QP version +#if (QP_VERSION < 730U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) +#error qpc version 7.3.0 or higher required +#endif +//$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +//$define${Comp} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${Comp::CompTimeEvt} ....................................................... + +//${Comp::CompTimeEvt::ctor} ................................................. +void CompTimeEvt_ctor(CompTimeEvt * const me, + QActive * act, + uint16_t num, + enum_t const sig, + uint_fast8_t const tickRate) +{ + QTimeEvt_ctorX(&me->super, act, sig, tickRate); + me->compNum = num; +} + +//${Comp::Philo} ............................................................. +Philo Philo_inst[N_PHILO]; + +//${Comp::Philo::SM} ......................................................... +static QState Philo_initial(Philo * const me, void const * const par) { + //${Comp::Philo::SM::initial} + Q_UNUSED_PAR(par); + + #ifdef Q_SPY + uint8_t id = (uint8_t)(me - &Philo_inst[0]); + QS_OBJ_ARR_DICTIONARY(&Philo_inst[id], id); + QS_OBJ_ARR_DICTIONARY(&Philo_inst[id].timeEvt, id); + #endif + + // the following code outputs the "fun-dictionaries" only once for + // all Philo instances, as opposed to repeat them for every instance. + static bool registered = false; + if (!registered) { + registered = true; + + QS_FUN_DICTIONARY(&Philo_initial); + QS_FUN_DICTIONARY(&Philo_thinking); + QS_FUN_DICTIONARY(&Philo_hungry); + QS_FUN_DICTIONARY(&Philo_eating); + } + return Q_TRAN(&Philo_thinking); +} + +//${Comp::Philo::SM::thinking} ............................................... +static QState Philo_thinking(Philo * const me, QEvt const * const e) { + QState status_; + switch (e->sig) { + //${Comp::Philo::SM::thinking} + case Q_ENTRY_SIG: { + QTimeEvt_armX(&me->timeEvt.super, THINK_TIME, 0U); + status_ = Q_HANDLED(); + break; + } + //${Comp::Philo::SM::thinking} + case Q_EXIT_SIG: { + QTimeEvt_disarm(&me->timeEvt.super); + status_ = Q_HANDLED(); + break; + } + //${Comp::Philo::SM::thinking::TIMEOUT} + case TIMEOUT_SIG: { + status_ = Q_TRAN(&Philo_hungry); + break; + } + //${Comp::Philo::SM::thinking::TEST} + case TEST_SIG: { + status_ = Q_HANDLED(); + break; + } + default: { + status_ = Q_SUPER(&QHsm_top); + break; + } + } + return status_; +} + +//${Comp::Philo::SM::hungry} ................................................. +static QState Philo_hungry(Philo * const me, QEvt const * const e) { + QState status_; + switch (e->sig) { + //${Comp::Philo::SM::hungry} + case Q_ENTRY_SIG: { + // asynchronously post event to the Container + #ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, HUNGRY_SIG, Philo_getId(me)); + #else + TableEvt *pe = Q_NEW(TableEvt, HUNGRY_SIG); + pe->philoId = Philo_getId(me); + #endif + QACTIVE_POST_LIFO(AO_Table, &pe->super); + status_ = Q_HANDLED(); + break; + } + //${Comp::Philo::SM::hungry::EAT} + case EAT_SIG: { + status_ = Q_TRAN(&Philo_eating); + break; + } + default: { + status_ = Q_SUPER(&QHsm_top); + break; + } + } + return status_; +} + +//${Comp::Philo::SM::eating} ................................................. +static QState Philo_eating(Philo * const me, QEvt const * const e) { + QState status_; + switch (e->sig) { + //${Comp::Philo::SM::eating} + case Q_ENTRY_SIG: { + QTimeEvt_armX(&me->timeEvt.super, EAT_TIME, 0U); + status_ = Q_HANDLED(); + break; + } + //${Comp::Philo::SM::eating} + case Q_EXIT_SIG: { + QTimeEvt_disarm(&me->timeEvt.super); + + // asynchronously post event to the Container + #ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, DONE_SIG, Philo_getId(me)); + #else + TableEvt *pe = Q_NEW(TableEvt, DONE_SIG); + pe->philoId = Philo_getId(me); + #endif + QACTIVE_POST_LIFO(AO_Table, &pe->super); + status_ = Q_HANDLED(); + break; + } + //${Comp::Philo::SM::eating::TIMEOUT} + case TIMEOUT_SIG: { + status_ = Q_TRAN(&Philo_thinking); + break; + } + default: { + status_ = Q_SUPER(&QHsm_top); + break; + } + } + return status_; +} + +//${Comp::SM_Philo[N_PHILO]} ................................................. +QAsm * const SM_Philo[N_PHILO] = { // opaque pointers to Philo instances + (QAsm *)&Philo_inst[0], + (QAsm *)&Philo_inst[1], + (QAsm *)&Philo_inst[2], + (QAsm *)&Philo_inst[3], + (QAsm *)&Philo_inst[4] +}; + +//${Comp::Philo_ctor} ........................................................ +void Philo_ctor(uint8_t n) { + Philo *me = &Philo_inst[n]; + QHsm_ctor(&me->super, Q_STATE_CAST(&Philo_initial)); + CompTimeEvt_ctor(&me->timeEvt, AO_Table, n, TIMEOUT_SIG, 0U); +} +//$enddef${Comp} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/examples/posix-win32/dpp_comp/qp_config.h b/examples/posix-win32/dpp_comp/qp_config.h new file mode 100644 index 00000000..e882f403 --- /dev/null +++ b/examples/posix-win32/dpp_comp/qp_config.h @@ -0,0 +1,54 @@ +//============================================================================ +// QP configuration file example +// Last updated for version: 7.3.0 +// Last updated on: 2023-09-02 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +//============================================================================ +#ifndef QP_CONFIG_H_ +#define QP_CONFIG_H_ + +// NOTE: +// The QP configuration takes effect only when the macro QP_CONFIG +// is defined on the command-line to the compiler for all QP source files. + +// Use the most recent QP API version +#define QP_API_VERSION 9999 + +// Enable QEvt constructor for dynamic events +#define QEVT_DYN_CTOR + +// Activate the QF QActive_stop() API +#define QF_ACTIVE_STOP + +// The maximum number of active objects in the application +#define QF_MAX_ACTIVE 64U + +// The number of system clock tick rates +#define QF_MAX_TICK_RATE 2U + +#endif // QP_CONFIG_H_ diff --git a/examples/posix-win32/dpp_comp/table.c b/examples/posix-win32/dpp_comp/table.c new file mode 100644 index 00000000..bef99757 --- /dev/null +++ b/examples/posix-win32/dpp_comp/table.c @@ -0,0 +1,345 @@ +//$file${.::table.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// +// Model: dpp-comp.qm +// File: ${.::table.c} +// +// This code has been generated by QM 5.3.0 . +// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. +// +// SPDX-License-Identifier: GPL-3.0-or-later +// +// This generated code is open source software: you can redistribute it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation. +// +// This code is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// NOTE: +// Alternatively, this generated code may be distributed under the terms +// of Quantum Leaps commercial licenses, which expressly supersede the GNU +// General Public License and are specifically designed for licensees +// interested in retaining the proprietary status of their code. +// +// Contact information: +// +// +// +//$endhead${.::table.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +#include "qpc.h" +#include "dpp.h" +#include "bsp.h" + +Q_DEFINE_THIS_FILE + +// helper function to provide the RIGHT neighbor of a Philo[n] +static inline uint8_t right(uint8_t const n) { + return (uint8_t)((n + (N_PHILO - 1U)) % N_PHILO); +} + +// helper function to provide the LEFT neighbor of a Philo[n] +static inline uint8_t left(uint8_t const n) { + return (uint8_t)((n + 1U) % N_PHILO); +} + +#define FREE ((uint8_t)0U) +#define USED ((uint8_t)1U) + +#define THINKING "thinking" +#define HUNGRY "hungry " +#define EATING "eating " + +//$declare${Cont::Table} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${Cont::Table} ............................................................. +typedef struct Table { +// protected: + QActive super; + +// public: + +// private: + uint8_t fork[N_PHILO]; + uint8_t isHungry[N_PHILO]; +} Table; +extern Table Table_inst; + +// protected: +static QState Table_initial(Table * const me, void const * const par); +static QState Table_active(Table * const me, QEvt const * const e); +static QState Table_serving(Table * const me, QEvt const * const e); +static QState Table_paused(Table * const me, QEvt const * const e); +//$enddecl${Cont::Table} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +//$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// Check for the minimum required QP version +#if (QP_VERSION < 730U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) +#error qpc version 7.3.0 or higher required +#endif +//$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +//$define${Shared::Table_ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${Shared::Table_ctor} ...................................................... +void Table_ctor(void) { + Table *me = &Table_inst; + QActive_ctor(&me->super, Q_STATE_CAST(&Table_initial)); + + for (uint8_t n = 0U; n < N_PHILO; ++n) { + Philo_ctor(n); // create the Philo component + + me->fork[n] = FREE; + me->isHungry[n] = 0U; + } +} +//$enddef${Shared::Table_ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +//$define${Shared::AO_Table} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${Shared::AO_Table} ........................................................ +QActive * const AO_Table = &Table_inst.super; +//$enddef${Shared::AO_Table} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +//$define${Cont} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${Cont::Table} ............................................................. +Table Table_inst; + +//${Cont::Table::SM} ......................................................... +static QState Table_initial(Table * const me, void const * const par) { + //${Cont::Table::SM::initial} + (void)par; // unused parameter + + QS_OBJ_DICTIONARY(&Table_inst); + + QActive_subscribe(&me->super, PAUSE_SIG); + QActive_subscribe(&me->super, SERVE_SIG); + QActive_subscribe(&me->super, TEST_SIG); + + for (uint8_t n = 0U; n < N_PHILO; ++n) { + me->fork[n] = FREE; + me->isHungry[n] = 0U; + + QASM_INIT(SM_Philo[n], (void *)0, QS_AP_ID + n); + BSP_displayPhilStat(n, "thinking"); + } + + QS_FUN_DICTIONARY(&Table_active); + QS_FUN_DICTIONARY(&Table_serving); + QS_FUN_DICTIONARY(&Table_paused); + + return Q_TRAN(&Table_serving); +} + +//${Cont::Table::SM::active} ................................................. +static QState Table_active(Table * const me, QEvt const * const e) { + QState status_; + switch (e->sig) { + //${Cont::Table::SM::active::TIMEOUT} + case TIMEOUT_SIG: { + uint16_t n = Q_EVT_CAST(CompTimeEvt)->compNum; + QASM_DISPATCH(SM_Philo[n], e, QS_AP_ID + n); + status_ = Q_HANDLED(); + break; + } + //${Cont::Table::SM::active::EAT} + case EAT_SIG: { + Q_ERROR(); + status_ = Q_HANDLED(); + break; + } + //${Cont::Table::SM::active::TEST} + case TEST_SIG: { + status_ = Q_HANDLED(); + break; + } + default: { + status_ = Q_SUPER(&QHsm_top); + break; + } + } + return status_; +} + +//${Cont::Table::SM::active::serving} ........................................ +static QState Table_serving(Table * const me, QEvt const * const e) { + QState status_; + switch (e->sig) { + //${Cont::Table::SM::active::serving} + case Q_ENTRY_SIG: { + for (uint8_t n = 0U; n < N_PHILO; ++n) { // give permissions to eat... + if ((me->isHungry[n] != 0U) + && (me->fork[left(n)] == FREE) + && (me->fork[n] == FREE)) + { + me->fork[left(n)] = USED; + me->fork[n] = USED; + + // synchronously dispatch EAT event to the Philo component + TableEvt const evt = { + QEVT_INITIALIZER(EAT_SIG), + .philoId = n + }; + QASM_DISPATCH(SM_Philo[n], &evt.super, QS_AP_ID + n); + + me->isHungry[n] = 0U; + BSP_displayPhilStat(n, "eating "); + } + } + status_ = Q_HANDLED(); + break; + } + //${Cont::Table::SM::active::serving::HUNGRY} + case HUNGRY_SIG: { + // find the index of the Philo from the event + uint8_t n = Q_EVT_CAST(TableEvt)->philoId; + // philo ID must be in range and he must be not hungry + Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); + + BSP_displayPhilStat(n, "hungry "); + uint8_t m = left(n); + //${Cont::Table::SM::active::serving::HUNGRY::[bothfree]} + if ((me->fork[m] == FREE) && (me->fork[n] == FREE)) { + me->fork[m] = USED; + me->fork[n] = USED; + + // synchronously dispatch EAT event to the Philo component + TableEvt const evt = { + QEVT_INITIALIZER(EAT_SIG), + .philoId = n + }; + QASM_DISPATCH(SM_Philo[n], &evt.super, QS_AP_ID + n); + BSP_displayPhilStat(n, "eating "); + status_ = Q_HANDLED(); + } + //${Cont::Table::SM::active::serving::HUNGRY::[else]} + else { + me->isHungry[n] = 1U; + status_ = Q_HANDLED(); + } + break; + } + //${Cont::Table::SM::active::serving::DONE} + case DONE_SIG: { + // find the index of the Philo from the event + uint8_t n = Q_EVT_CAST(TableEvt)->philoId; + // philo ID must be in range and he must be not hungry + Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); + + BSP_displayPhilStat(n, "thinking"); + uint8_t m = left(n); + // both forks of Phil[n] must be used + Q_ASSERT((me->fork[n] == USED) && (me->fork[m] == USED)); + + me->fork[m] = FREE; + me->fork[n] = FREE; + m = right(n); // check the right neighbor + + if ((me->isHungry[m] != 0U) && (me->fork[m] == FREE)) { + me->fork[n] = USED; + me->fork[m] = USED; + me->isHungry[m] = 0U; + + // synchronously dispatch EAT event to the Philo component + TableEvt const evt = { + QEVT_INITIALIZER(EAT_SIG), + .philoId = m + }; + QASM_DISPATCH(SM_Philo[m], &evt.super, QS_AP_ID + m); + BSP_displayPhilStat(m, "eating "); + } + m = left(n); // check the left neighbor + n = left(m); // left fork of the left neighbor + if ((me->isHungry[m] != 0U) && (me->fork[n] == FREE)) { + me->fork[m] = USED; + me->fork[n] = USED; + me->isHungry[m] = 0U; + + // synchronously dispatch EAT event to the Philo component + TableEvt const evt = { + QEVT_INITIALIZER(EAT_SIG), + .philoId = m + }; + QASM_DISPATCH(SM_Philo[m], &evt.super, QS_AP_ID + m); + BSP_displayPhilStat(m, "eating "); + } + status_ = Q_HANDLED(); + break; + } + //${Cont::Table::SM::active::serving::EAT} + case EAT_SIG: { + Q_ERROR(); + status_ = Q_HANDLED(); + break; + } + //${Cont::Table::SM::active::serving::PAUSE} + case PAUSE_SIG: { + status_ = Q_TRAN(&Table_paused); + break; + } + default: { + status_ = Q_SUPER(&Table_active); + break; + } + } + return status_; +} + +//${Cont::Table::SM::active::paused} ......................................... +static QState Table_paused(Table * const me, QEvt const * const e) { + QState status_; + switch (e->sig) { + //${Cont::Table::SM::active::paused} + case Q_ENTRY_SIG: { + BSP_displayPaused(1U); + status_ = Q_HANDLED(); + break; + } + //${Cont::Table::SM::active::paused} + case Q_EXIT_SIG: { + BSP_displayPaused(0U); + status_ = Q_HANDLED(); + break; + } + //${Cont::Table::SM::active::paused::SERVE} + case SERVE_SIG: { + status_ = Q_TRAN(&Table_serving); + break; + } + //${Cont::Table::SM::active::paused::HUNGRY} + case HUNGRY_SIG: { + // find the index of the Philo from the event + uint8_t n = Q_EVT_CAST(TableEvt)->philoId; + // philo ID must be in range and he must be not hungry + Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); + + me->isHungry[n] = 1U; + BSP_displayPhilStat(n, "hungry "); + status_ = Q_HANDLED(); + break; + } + //${Cont::Table::SM::active::paused::DONE} + case DONE_SIG: { + // find the index of the Philo from the event + uint8_t n = Q_EVT_CAST(TableEvt)->philoId; + // philo ID must be in range and he must be not hungry + Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); + + BSP_displayPhilStat(n, "thinking"); + uint8_t m = left(n); + // both forks of Phil[n] must be used + Q_ASSERT((me->fork[n] == USED) && (me->fork[m] == USED)); + + me->fork[m] = FREE; + me->fork[n] = FREE; + status_ = Q_HANDLED(); + break; + } + default: { + status_ = Q_SUPER(&Table_active); + break; + } + } + return status_; +} +//$enddef${Cont} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/examples/workstation/history_qhsm/Makefile b/examples/posix-win32/history_qhsm/Makefile similarity index 99% rename from examples/workstation/history_qhsm/Makefile rename to examples/posix-win32/history_qhsm/Makefile index 5ad70bbf..9789a625 100644 --- a/examples/workstation/history_qhsm/Makefile +++ b/examples/posix-win32/history_qhsm/Makefile @@ -241,7 +241,7 @@ CPP_DEPS_EXT := $(patsubst %.o,%.d, $(CPP_OBJS_EXT)) all: $(TARGET_EXE) $(TARGET_EXE) : $(C_OBJS_EXT) $(CPP_OBJS_EXT) - $(CC) $(CFLAGS) $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o + $(CC) $(CFLAGS) $(QPC)/src/qs/qstamp.c -o $(BIN_DIR)/qstamp.o $(LINK) $(LINKFLAGS) $(LIB_DIRS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) $(BIN_DIR)/%.d : %.c diff --git a/examples/workstation/history_qhsm/history.c b/examples/posix-win32/history_qhsm/history.c similarity index 55% rename from examples/workstation/history_qhsm/history.c rename to examples/posix-win32/history_qhsm/history.c index dfece4c7..490bb03f 100644 --- a/examples/workstation/history_qhsm/history.c +++ b/examples/posix-win32/history_qhsm/history.c @@ -1,54 +1,54 @@ -/*$file${.::history.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* -* Model: history.qm -* File: ${.::history.c} -* -* This code has been generated by QM 5.2.4 . -* DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. -* -* SPDX-License-Identifier: GPL-3.0-or-later -* -* This generated code is open source software: you can redistribute it under -* the terms of the GNU General Public License as published by the Free -* Software Foundation. -* -* This code is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -* more details. -* -* NOTE: -* Alternatively, this generated code may be distributed under the terms -* of Quantum Leaps commercial licenses, which expressly supersede the GNU -* General Public License and are specifically designed for licensees -* interested in retaining the proprietary status of their code. -* -* Contact information: -* -* -*/ -/*$endhead${.::history.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$file${.::history.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// +// Model: history.qm +// File: ${.::history.c} +// +// This code has been generated by QM 5.3.0 . +// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. +// +// SPDX-License-Identifier: GPL-3.0-or-later +// +// This generated code is open source software: you can redistribute it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation. +// +// This code is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// NOTE: +// Alternatively, this generated code may be distributed under the terms +// of Quantum Leaps commercial licenses, which expressly supersede the GNU +// General Public License and are specifically designed for licensees +// interested in retaining the proprietary status of their code. +// +// Contact information: +// +// +// +//$endhead${.::history.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ #include "qpc.h" #include "history.h" -#include "safe_std.h" /* portable "safe" / facilities */ +#include "safe_std.h" // portable "safe" / facilities #include //Q_DEFINE_THIS_FILE -/*$declare${SMs::ToastOven} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//$declare${SMs::ToastOven} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/*${SMs::ToastOven} ........................................................*/ +//${SMs::ToastOven} .......................................................... typedef struct { -/* protected: */ +// protected: QHsm super; -/* private state histories */ +// private state histories QStateHandler hist_doorClosed; QStateHandler hist_heating; } ToastOven; -/* protected: */ +// protected: static QState ToastOven_initial(ToastOven * const me, void const * const par); static QState ToastOven_doorClosed(ToastOven * const me, QEvt const * const e); static QState ToastOven_heating(ToastOven * const me, QEvt const * const e); @@ -57,87 +57,87 @@ static QState ToastOven_baking(ToastOven * const me, QEvt const * const e); static QState ToastOven_off(ToastOven * const me, QEvt const * const e); static QState ToastOven_doorOpen(ToastOven * const me, QEvt const * const e); static QState ToastOven_final(ToastOven * const me, QEvt const * const e); -/*$enddecl${SMs::ToastOven} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$enddecl${SMs::ToastOven} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -static ToastOven l_oven; /* the only instance of the ToastOven class */ +static ToastOven l_oven; // the only instance of the ToastOven class -/* global-scope definitions -----------------------------------------*/ -QHsm * const the_oven = &l_oven.super; /* the opaque pointer */ +// global-scope definitions ----------------------------------------- +QHsm * const the_oven = &l_oven.super; // the opaque pointer -/*$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* Check for the minimum required QP version */ -#if (QP_VERSION < 700U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) -#error qpc version 7.0.0 or higher required +//$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// Check for the minimum required QP version +#if (QP_VERSION < 730U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) +#error qpc version 7.3.0 or higher required #endif -/*$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -/*$define${SMs::ToastOven_ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//$define${SMs::ToastOven_ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/*${SMs::ToastOven_ctor} ...................................................*/ +//${SMs::ToastOven_ctor} ..................................................... void ToastOven_ctor(void) { ToastOven *me = &l_oven; QHsm_ctor(&me->super, Q_STATE_CAST(&ToastOven_initial)); } -/*$enddef${SMs::ToastOven_ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*$define${SMs::ToastOven} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//$enddef${SMs::ToastOven_ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +//$define${SMs::ToastOven} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/*${SMs::ToastOven} ........................................................*/ +//${SMs::ToastOven} .......................................................... -/*${SMs::ToastOven::SM} ....................................................*/ +//${SMs::ToastOven::SM} ...................................................... static QState ToastOven_initial(ToastOven * const me, void const * const par) { - /*${SMs::ToastOven::SM::initial} */ - (void)par; /* unused parameter */ - /* state history attributes */ + //${SMs::ToastOven::SM::initial} + (void)par; // unused parameter + // state history attributes me->hist_doorClosed = Q_STATE_CAST(&ToastOven_off); me->hist_heating = Q_STATE_CAST(&ToastOven_baking); return Q_TRAN(&ToastOven_doorClosed); } -/*${SMs::ToastOven::SM::doorClosed} ........................................*/ +//${SMs::ToastOven::SM::doorClosed} .......................................... static QState ToastOven_doorClosed(ToastOven * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${SMs::ToastOven::SM::doorClosed} */ + //${SMs::ToastOven::SM::doorClosed} case Q_ENTRY_SIG: { PRINTF_S("%s;", "door-Closed"); status_ = Q_HANDLED(); break; } - /*${SMs::ToastOven::SM::doorClosed} */ + //${SMs::ToastOven::SM::doorClosed} case Q_EXIT_SIG: { - /* save shallow history */ + // save shallow history me->hist_doorClosed = QHsm_childState(Q_HSM_UPCAST(me), Q_STATE_CAST(&ToastOven_doorClosed)); status_ = Q_HANDLED(); break; } - /*${SMs::ToastOven::SM::doorClosed::initial} */ + //${SMs::ToastOven::SM::doorClosed::initial} case Q_INIT_SIG: { status_ = Q_TRAN(&ToastOven_off); break; } - /*${SMs::ToastOven::SM::doorClosed::TERMINATE} */ + //${SMs::ToastOven::SM::doorClosed::TERMINATE} case TERMINATE_SIG: { status_ = Q_TRAN(&ToastOven_final); break; } - /*${SMs::ToastOven::SM::doorClosed::OPEN} */ + //${SMs::ToastOven::SM::doorClosed::OPEN} case OPEN_SIG: { status_ = Q_TRAN(&ToastOven_doorOpen); break; } - /*${SMs::ToastOven::SM::doorClosed::TOAST} */ + //${SMs::ToastOven::SM::doorClosed::TOAST} case TOAST_SIG: { status_ = Q_TRAN(&ToastOven_toasting); break; } - /*${SMs::ToastOven::SM::doorClosed::BAKE} */ + //${SMs::ToastOven::SM::doorClosed::BAKE} case BAKE_SIG: { status_ = Q_TRAN(&ToastOven_baking); break; } - /*${SMs::ToastOven::SM::doorClosed::OFF} */ + //${SMs::ToastOven::SM::doorClosed::OFF} case OFF_SIG: { status_ = Q_TRAN(&ToastOven_off); break; @@ -150,25 +150,25 @@ static QState ToastOven_doorClosed(ToastOven * const me, QEvt const * const e) { return status_; } -/*${SMs::ToastOven::SM::doorClosed::heating} ...............................*/ +//${SMs::ToastOven::SM::doorClosed::heating} ................................. static QState ToastOven_heating(ToastOven * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${SMs::ToastOven::SM::doorClosed::heating} */ + //${SMs::ToastOven::SM::doorClosed::heating} case Q_ENTRY_SIG: { PRINTF_S("%s;", "heater-On"); status_ = Q_HANDLED(); break; } - /*${SMs::ToastOven::SM::doorClosed::heating} */ + //${SMs::ToastOven::SM::doorClosed::heating} case Q_EXIT_SIG: { PRINTF_S("%s;", "heater-Off"); - /* save deep history */ + // save deep history me->hist_heating = QHsm_state(Q_HSM_UPCAST(me)); status_ = Q_HANDLED(); break; } - /*${SMs::ToastOven::SM::doorClosed::heating::initial} */ + //${SMs::ToastOven::SM::doorClosed::heating::initial} case Q_INIT_SIG: { status_ = Q_TRAN(&ToastOven_toasting); break; @@ -181,11 +181,11 @@ static QState ToastOven_heating(ToastOven * const me, QEvt const * const e) { return status_; } -/*${SMs::ToastOven::SM::doorClosed::heating::toasting} .....................*/ +//${SMs::ToastOven::SM::doorClosed::heating::toasting} ....................... static QState ToastOven_toasting(ToastOven * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${SMs::ToastOven::SM::doorClosed::heating::toasting} */ + //${SMs::ToastOven::SM::doorClosed::heating::toasting} case Q_ENTRY_SIG: { PRINTF_S("%s;", "toasting"); status_ = Q_HANDLED(); @@ -199,11 +199,11 @@ static QState ToastOven_toasting(ToastOven * const me, QEvt const * const e) { return status_; } -/*${SMs::ToastOven::SM::doorClosed::heating::baking} .......................*/ +//${SMs::ToastOven::SM::doorClosed::heating::baking} ......................... static QState ToastOven_baking(ToastOven * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${SMs::ToastOven::SM::doorClosed::heating::baking} */ + //${SMs::ToastOven::SM::doorClosed::heating::baking} case Q_ENTRY_SIG: { PRINTF_S("%s;", "baking"); status_ = Q_HANDLED(); @@ -217,11 +217,11 @@ static QState ToastOven_baking(ToastOven * const me, QEvt const * const e) { return status_; } -/*${SMs::ToastOven::SM::doorClosed::off} ...................................*/ +//${SMs::ToastOven::SM::doorClosed::off} ..................................... static QState ToastOven_off(ToastOven * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${SMs::ToastOven::SM::doorClosed::off} */ + //${SMs::ToastOven::SM::doorClosed::off} case Q_ENTRY_SIG: { PRINTF_S("%s;", "toaster-Off"); status_ = Q_HANDLED(); @@ -235,33 +235,33 @@ static QState ToastOven_off(ToastOven * const me, QEvt const * const e) { return status_; } -/*${SMs::ToastOven::SM::doorOpen} ..........................................*/ +//${SMs::ToastOven::SM::doorOpen} ............................................ static QState ToastOven_doorOpen(ToastOven * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${SMs::ToastOven::SM::doorOpen} */ + //${SMs::ToastOven::SM::doorOpen} case Q_ENTRY_SIG: { PRINTF_S("%s;", "door-Open,lamp-On"); status_ = Q_HANDLED(); break; } - /*${SMs::ToastOven::SM::doorOpen} */ + //${SMs::ToastOven::SM::doorOpen} case Q_EXIT_SIG: { PRINTF_S("%s;", "lamp-Off"); status_ = Q_HANDLED(); break; } - /*${SMs::ToastOven::SM::doorOpen::CLOSE} */ + //${SMs::ToastOven::SM::doorOpen::CLOSE} case CLOSE_SIG: { status_ = Q_TRAN_HIST(me->hist_heating); break; } - /*${SMs::ToastOven::SM::doorOpen::TERMINATE} */ + //${SMs::ToastOven::SM::doorOpen::TERMINATE} case TERMINATE_SIG: { status_ = Q_TRAN(&ToastOven_final); break; } - /*${SMs::ToastOven::SM::doorOpen::OFF} */ + //${SMs::ToastOven::SM::doorOpen::OFF} case OFF_SIG: { status_ = Q_TRAN_HIST(me->hist_doorClosed); break; @@ -274,11 +274,11 @@ static QState ToastOven_doorOpen(ToastOven * const me, QEvt const * const e) { return status_; } -/*${SMs::ToastOven::SM::final} .............................................*/ +//${SMs::ToastOven::SM::final} ............................................... static QState ToastOven_final(ToastOven * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${SMs::ToastOven::SM::final} */ + //${SMs::ToastOven::SM::final} case Q_ENTRY_SIG: { PRINTF_S("\n%s\n", "Bye! Bye!"); QF_onCleanup(); @@ -293,4 +293,4 @@ static QState ToastOven_final(ToastOven * const me, QEvt const * const e) { } return status_; } -/*$enddef${SMs::ToastOven} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$enddef${SMs::ToastOven} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/examples/posix-win32/history_qhsm/history.h b/examples/posix-win32/history_qhsm/history.h new file mode 100644 index 00000000..7ebd8e6a --- /dev/null +++ b/examples/posix-win32/history_qhsm/history.h @@ -0,0 +1,51 @@ +//$file${.::history.h} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// +// Model: history.qm +// File: ${.::history.h} +// +// This code has been generated by QM 5.3.0 . +// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. +// +// SPDX-License-Identifier: GPL-3.0-or-later +// +// This generated code is open source software: you can redistribute it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation. +// +// This code is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// NOTE: +// Alternatively, this generated code may be distributed under the terms +// of Quantum Leaps commercial licenses, which expressly supersede the GNU +// General Public License and are specifically designed for licensees +// interested in retaining the proprietary status of their code. +// +// Contact information: +// +// +// +//$endhead${.::history.h} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +#ifndef HISTORY_H_ +#define HISTORY_H_ + +enum ToastOvenSignals { + OPEN_SIG = Q_USER_SIG, + CLOSE_SIG, + TOAST_SIG, + BAKE_SIG, + OFF_SIG, + TERMINATE_SIG // terminate the application +}; + +extern QHsm * const the_oven; // opaque pointer to the oven HSM + +//$declare${SMs::ToastOven_ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${SMs::ToastOven_ctor} ..................................................... +void ToastOven_ctor(void); +//$enddecl${SMs::ToastOven_ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +#endif // HISTORY_H_ diff --git a/examples/workstation/history_qhsm/history.qm b/examples/posix-win32/history_qhsm/history.qm similarity index 90% rename from examples/workstation/history_qhsm/history.qm rename to examples/posix-win32/history_qhsm/history.qm index c28a4a63..00b21927 100644 --- a/examples/workstation/history_qhsm/history.qm +++ b/examples/posix-win32/history_qhsm/history.qm @@ -1,5 +1,5 @@ - + Demonstration of transitions to history and deep history in QHsm-style state machines. @@ -12,7 +12,7 @@ - (void)par; /* unused parameter */ + (void)par; // unused parameter @@ -153,8 +153,8 @@ QHsm_ctor(&me->super, Q_STATE_CAST(&ToastOven_initial)); - #ifndef HISTORY_H -#define HISTORY_H + #ifndef HISTORY_H_ +#define HISTORY_H_ enum ToastOvenSignals { OPEN_SIG = Q_USER_SIG, @@ -162,32 +162,31 @@ enum ToastOvenSignals { TOAST_SIG, BAKE_SIG, OFF_SIG, - TERMINATE_SIG /* terminate the application */ + TERMINATE_SIG // terminate the application }; -extern QHsm * const the_oven; /* opaque pointer to the oven HSM */ +extern QHsm * const the_oven; // opaque pointer to the oven HSM $declare(SMs::ToastOven_ctor) -#endif /* HISTORY_H */ - +#endif // HISTORY_H_ #include "qpc.h" #include "history.h" -#include "safe_std.h" /* portable "safe" <stdio.h>/<string.h> facilities */ +#include "safe_std.h" // portable "safe" <stdio.h>/<string.h> facilities #include <stdlib.h> //Q_DEFINE_THIS_FILE $declare(SMs::ToastOven) -static ToastOven l_oven; /* the only instance of the ToastOven class */ +static ToastOven l_oven; // the only instance of the ToastOven class -/* global-scope definitions -----------------------------------------*/ -QHsm * const the_oven = &l_oven.super; /* the opaque pointer */ +// global-scope definitions ----------------------------------------- +QHsm * const the_oven = &l_oven.super; // the opaque pointer $define(SMs::ToastOven_ctor) $define(SMs::ToastOven) diff --git a/examples/posix-win32/history_qhsm/main.c b/examples/posix-win32/history_qhsm/main.c new file mode 100644 index 00000000..97ab87a6 --- /dev/null +++ b/examples/posix-win32/history_qhsm/main.c @@ -0,0 +1,102 @@ +//============================================================================ +// Product: History Example, Win32 +// Last updated for version 7.3.0 +// Last updated on 2023-06-30 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// This program is open source software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Alternatively, this program may be distributed and modified under the +// terms of Quantum Leaps commercial licenses, which expressly supersede +// the GNU General Public License and are specifically designed for +// licensees interested in retaining the proprietary status of their code. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Contact information: +// +// +//============================================================================ +#include "qpc.h" +#include "history.h" + +#include "safe_std.h" // portable "safe" / facilities +#include // for exit() + +Q_DEFINE_THIS_FILE + +//............................................................................ +int main() { + QF_init(); + QF_onStartup(); + + PRINTF_S("History state pattern\nQP version: %s\n" + "Press 'o' to OPEN the door\n" + "Press 'c' to CLOSE the door\n" + "Press 't' to start TOASTING\n" + "Press 'b' to start BAKING\n" + "Press 'f' to turn the oven OFF\n" + "Press ESC to quit...\n", + QP_VERSION_STR); + + // instantiate the ToastOven HSM and trigger the initial transition + ToastOven_ctor(); + QASM_INIT(the_oven, (void *)0, 0U); + + for (;;) { + QEvt e = QEVT_INITIALIZER(0U); + uint8_t c; + + PRINTF_S("\n", ""); + c = (uint8_t)QF_consoleWaitForKey(); + PRINTF_S("%c: ", (c >= ' ') ? c : 'X'); + + switch (c) { + case 'o': e.sig = OPEN_SIG; break; + case 'c': e.sig = CLOSE_SIG; break; + case 't': e.sig = TOAST_SIG; break; + case 'b': e.sig = BAKE_SIG; break; + case 'f': e.sig = OFF_SIG; break; + case 0x1B: e.sig = TERMINATE_SIG; break; + } + + // dispatch the event into the state machine + QASM_DISPATCH(the_oven, &e, 0U); + } + + QF_onCleanup(); + return 0; +} + +//............................................................................ +void QF_onStartup(void) { + QF_consoleSetup(); +} +//............................................................................ +void QF_onCleanup(void) { + QF_consoleCleanup(); +} +//............................................................................ +void QF_onClockTick(void) { +} + +//............................................................................ +Q_NORETURN Q_onError(char const * const module, int_t const id) { + FPRINTF_S(stderr, "ERROR in %s, line %d", module, id); + QF_onCleanup(); + exit(-1); +} diff --git a/examples/workstation/history_qmsm/Makefile b/examples/posix-win32/history_qmsm/Makefile similarity index 99% rename from examples/workstation/history_qmsm/Makefile rename to examples/posix-win32/history_qmsm/Makefile index aa821d85..7e185cbf 100644 --- a/examples/workstation/history_qmsm/Makefile +++ b/examples/posix-win32/history_qmsm/Makefile @@ -241,7 +241,7 @@ CPP_DEPS_EXT := $(patsubst %.o,%.d, $(CPP_OBJS_EXT)) all: $(TARGET_EXE) $(TARGET_EXE) : $(C_OBJS_EXT) $(CPP_OBJS_EXT) - $(CC) $(CFLAGS) $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o + $(CC) $(CFLAGS) $(QPC)/src/qs/qstamp.c -o $(BIN_DIR)/qstamp.o $(LINK) $(LINKFLAGS) $(LIB_DIRS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) $(BIN_DIR)/%.d : %.c diff --git a/examples/posix-win32/history_qmsm/history.c b/examples/posix-win32/history_qmsm/history.c new file mode 100644 index 00000000..73bdd466 --- /dev/null +++ b/examples/posix-win32/history_qmsm/history.c @@ -0,0 +1,485 @@ +//$file${.::history.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// +// Model: history.qm +// File: ${.::history.c} +// +// This code has been generated by QM 5.3.0 . +// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. +// +// SPDX-License-Identifier: GPL-3.0-or-later +// +// This generated code is open source software: you can redistribute it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation. +// +// This code is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// NOTE: +// Alternatively, this generated code may be distributed under the terms +// of Quantum Leaps commercial licenses, which expressly supersede the GNU +// General Public License and are specifically designed for licensees +// interested in retaining the proprietary status of their code. +// +// Contact information: +// +// +// +//$endhead${.::history.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +#include "qpc.h" +#include "history.h" + +#include "safe_std.h" // portable "safe" / facilities +#include + +//Q_DEFINE_THIS_FILE + +//$declare${SMs::ToastOven} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${SMs::ToastOven} .......................................................... +typedef struct { +// protected: + QMsm super; + +// private state histories + QMState const *hist_doorClosed; + QMState const *hist_heating; +} ToastOven; + +// protected: +static QState ToastOven_initial(ToastOven * const me, void const * const par); +static QState ToastOven_doorClosed (ToastOven * const me, QEvt const * const e); +static QState ToastOven_doorClosed_e(ToastOven * const me); +static QState ToastOven_doorClosed_x(ToastOven * const me); +static QState ToastOven_doorClosed_i(ToastOven * const me); +static QMState const ToastOven_doorClosed_s = { + QM_STATE_NULL, // superstate (top) + Q_STATE_CAST(&ToastOven_doorClosed), + Q_ACTION_CAST(&ToastOven_doorClosed_e), + Q_ACTION_CAST(&ToastOven_doorClosed_x), + Q_ACTION_CAST(&ToastOven_doorClosed_i) +}; +static QState ToastOven_heating (ToastOven * const me, QEvt const * const e); +static QState ToastOven_heating_e(ToastOven * const me); +static QState ToastOven_heating_x(ToastOven * const me); +static QState ToastOven_heating_i(ToastOven * const me); +static QMState const ToastOven_heating_s = { + &ToastOven_doorClosed_s, // superstate + Q_STATE_CAST(&ToastOven_heating), + Q_ACTION_CAST(&ToastOven_heating_e), + Q_ACTION_CAST(&ToastOven_heating_x), + Q_ACTION_CAST(&ToastOven_heating_i) +}; +static QState ToastOven_toasting (ToastOven * const me, QEvt const * const e); +static QState ToastOven_toasting_e(ToastOven * const me); +static QMState const ToastOven_toasting_s = { + &ToastOven_heating_s, // superstate + Q_STATE_CAST(&ToastOven_toasting), + Q_ACTION_CAST(&ToastOven_toasting_e), + Q_ACTION_NULL, // no exit action + Q_ACTION_NULL // no initial tran. +}; +static QState ToastOven_baking (ToastOven * const me, QEvt const * const e); +static QState ToastOven_baking_e(ToastOven * const me); +static QMState const ToastOven_baking_s = { + &ToastOven_heating_s, // superstate + Q_STATE_CAST(&ToastOven_baking), + Q_ACTION_CAST(&ToastOven_baking_e), + Q_ACTION_NULL, // no exit action + Q_ACTION_NULL // no initial tran. +}; +static QState ToastOven_off (ToastOven * const me, QEvt const * const e); +static QState ToastOven_off_e(ToastOven * const me); +static QMState const ToastOven_off_s = { + &ToastOven_doorClosed_s, // superstate + Q_STATE_CAST(&ToastOven_off), + Q_ACTION_CAST(&ToastOven_off_e), + Q_ACTION_NULL, // no exit action + Q_ACTION_NULL // no initial tran. +}; +static QState ToastOven_doorOpen (ToastOven * const me, QEvt const * const e); +static QState ToastOven_doorOpen_e(ToastOven * const me); +static QState ToastOven_doorOpen_x(ToastOven * const me); +static QMState const ToastOven_doorOpen_s = { + QM_STATE_NULL, // superstate (top) + Q_STATE_CAST(&ToastOven_doorOpen), + Q_ACTION_CAST(&ToastOven_doorOpen_e), + Q_ACTION_CAST(&ToastOven_doorOpen_x), + Q_ACTION_NULL // no initial tran. +}; +static QState ToastOven_final (ToastOven * const me, QEvt const * const e); +static QState ToastOven_final_e(ToastOven * const me); +static QMState const ToastOven_final_s = { + QM_STATE_NULL, // superstate (top) + Q_STATE_CAST(&ToastOven_final), + Q_ACTION_CAST(&ToastOven_final_e), + Q_ACTION_NULL, // no exit action + Q_ACTION_NULL // no initial tran. +}; +//$enddecl${SMs::ToastOven} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +static ToastOven l_oven; // the only instance of the ToastOven class + +// global-scope definitions ----------------------------------------- +QMsm * const the_oven = &l_oven.super; // the opaque pointer + +//$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// Check for the minimum required QP version +#if (QP_VERSION < 730U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) +#error qpc version 7.3.0 or higher required +#endif +//$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +//$define${SMs::ToastOven_ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${SMs::ToastOven_ctor} ..................................................... +void ToastOven_ctor(void) { + ToastOven *me = &l_oven; + QMsm_ctor(&me->super, Q_STATE_CAST(&ToastOven_initial)); +} +//$enddef${SMs::ToastOven_ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +//$define${SMs::ToastOven} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${SMs::ToastOven} .......................................................... + +//${SMs::ToastOven::SM} ...................................................... +static QState ToastOven_initial(ToastOven * const me, void const * const par) { + static struct { + QMState const *target; + QActionHandler act[3]; + } const tatbl_ = { // tran-action table + &ToastOven_doorClosed_s, // target state + { + Q_ACTION_CAST(&ToastOven_doorClosed_e), // entry + Q_ACTION_CAST(&ToastOven_doorClosed_i), // initial tran. + Q_ACTION_NULL // zero terminator + } + }; + //${SMs::ToastOven::SM::initial} + (void)par; // unused parameter + // state history attributes + me->hist_doorClosed = &ToastOven_off_s; + me->hist_heating = &ToastOven_baking_s; + return QM_TRAN_INIT(&tatbl_); +} + +//${SMs::ToastOven::SM::doorClosed} .......................................... +//${SMs::ToastOven::SM::doorClosed} +static QState ToastOven_doorClosed_e(ToastOven * const me) { + PRINTF_S("%s;", "door-Closed"); + Q_UNUSED_PAR(me); + return QM_ENTRY(&ToastOven_doorClosed_s); +} +//${SMs::ToastOven::SM::doorClosed} +static QState ToastOven_doorClosed_x(ToastOven * const me) { + // save shallow history + me->hist_doorClosed = + QMsm_childStateObj(Q_MSM_UPCAST(me), &ToastOven_doorClosed_s); + return QM_EXIT(&ToastOven_doorClosed_s); +} +//${SMs::ToastOven::SM::doorClosed::initial} +static QState ToastOven_doorClosed_i(ToastOven * const me) { + static struct { + QMState const *target; + QActionHandler act[2]; + } const tatbl_ = { // tran-action table + &ToastOven_off_s, // target state + { + Q_ACTION_CAST(&ToastOven_off_e), // entry + Q_ACTION_NULL // zero terminator + } + }; + //${SMs::ToastOven::SM::doorClosed::initial} + return QM_TRAN_INIT(&tatbl_); +} +//${SMs::ToastOven::SM::doorClosed} +static QState ToastOven_doorClosed(ToastOven * const me, QEvt const * const e) { + QState status_; + switch (e->sig) { + //${SMs::ToastOven::SM::doorClosed::TERMINATE} + case TERMINATE_SIG: { + static struct { + QMState const *target; + QActionHandler act[3]; + } const tatbl_ = { // tran-action table + &ToastOven_final_s, // target state + { + Q_ACTION_CAST(&ToastOven_doorClosed_x), // exit + Q_ACTION_CAST(&ToastOven_final_e), // entry + Q_ACTION_NULL // zero terminator + } + }; + status_ = QM_TRAN(&tatbl_); + break; + } + //${SMs::ToastOven::SM::doorClosed::OPEN} + case OPEN_SIG: { + static struct { + QMState const *target; + QActionHandler act[3]; + } const tatbl_ = { // tran-action table + &ToastOven_doorOpen_s, // target state + { + Q_ACTION_CAST(&ToastOven_doorClosed_x), // exit + Q_ACTION_CAST(&ToastOven_doorOpen_e), // entry + Q_ACTION_NULL // zero terminator + } + }; + status_ = QM_TRAN(&tatbl_); + break; + } + //${SMs::ToastOven::SM::doorClosed::TOAST} + case TOAST_SIG: { + static struct { + QMState const *target; + QActionHandler act[3]; + } const tatbl_ = { // tran-action table + &ToastOven_toasting_s, // target state + { + Q_ACTION_CAST(&ToastOven_heating_e), // entry + Q_ACTION_CAST(&ToastOven_toasting_e), // entry + Q_ACTION_NULL // zero terminator + } + }; + status_ = QM_TRAN(&tatbl_); + break; + } + //${SMs::ToastOven::SM::doorClosed::BAKE} + case BAKE_SIG: { + static struct { + QMState const *target; + QActionHandler act[3]; + } const tatbl_ = { // tran-action table + &ToastOven_baking_s, // target state + { + Q_ACTION_CAST(&ToastOven_heating_e), // entry + Q_ACTION_CAST(&ToastOven_baking_e), // entry + Q_ACTION_NULL // zero terminator + } + }; + status_ = QM_TRAN(&tatbl_); + break; + } + //${SMs::ToastOven::SM::doorClosed::OFF} + case OFF_SIG: { + static struct { + QMState const *target; + QActionHandler act[2]; + } const tatbl_ = { // tran-action table + &ToastOven_off_s, // target state + { + Q_ACTION_CAST(&ToastOven_off_e), // entry + Q_ACTION_NULL // zero terminator + } + }; + status_ = QM_TRAN(&tatbl_); + break; + } + default: { + status_ = QM_SUPER(); + break; + } + } + return status_; +} + +//${SMs::ToastOven::SM::doorClosed::heating} ................................. +//${SMs::ToastOven::SM::doorClosed::heating} +static QState ToastOven_heating_e(ToastOven * const me) { + PRINTF_S("%s;", "heater-On"); + Q_UNUSED_PAR(me); + return QM_ENTRY(&ToastOven_heating_s); +} +//${SMs::ToastOven::SM::doorClosed::heating} +static QState ToastOven_heating_x(ToastOven * const me) { + PRINTF_S("%s;", "heater-Off"); + // save deep history + me->hist_heating = QMsm_stateObj(Q_MSM_UPCAST(me)); + return QM_EXIT(&ToastOven_heating_s); +} +//${SMs::ToastOven::SM::doorClosed::heating::initial} +static QState ToastOven_heating_i(ToastOven * const me) { + static struct { + QMState const *target; + QActionHandler act[2]; + } const tatbl_ = { // tran-action table + &ToastOven_toasting_s, // target state + { + Q_ACTION_CAST(&ToastOven_toasting_e), // entry + Q_ACTION_NULL // zero terminator + } + }; + //${SMs::ToastOven::SM::doorClosed::heating::initial} + return QM_TRAN_INIT(&tatbl_); +} +//${SMs::ToastOven::SM::doorClosed::heating} +static QState ToastOven_heating(ToastOven * const me, QEvt const * const e) { + QState status_; + switch (e->sig) { + default: { + status_ = QM_SUPER(); + break; + } + } + Q_UNUSED_PAR(me); + return status_; +} + +//${SMs::ToastOven::SM::doorClosed::heating::toasting} ....................... +//${SMs::ToastOven::SM::doorClosed::heating::toasting} +static QState ToastOven_toasting_e(ToastOven * const me) { + PRINTF_S("%s;", "toasting"); + Q_UNUSED_PAR(me); + return QM_ENTRY(&ToastOven_toasting_s); +} +//${SMs::ToastOven::SM::doorClosed::heating::toasting} +static QState ToastOven_toasting(ToastOven * const me, QEvt const * const e) { + QState status_; + switch (e->sig) { + default: { + status_ = QM_SUPER(); + break; + } + } + Q_UNUSED_PAR(me); + return status_; +} + +//${SMs::ToastOven::SM::doorClosed::heating::baking} ......................... +//${SMs::ToastOven::SM::doorClosed::heating::baking} +static QState ToastOven_baking_e(ToastOven * const me) { + PRINTF_S("%s;", "baking"); + Q_UNUSED_PAR(me); + return QM_ENTRY(&ToastOven_baking_s); +} +//${SMs::ToastOven::SM::doorClosed::heating::baking} +static QState ToastOven_baking(ToastOven * const me, QEvt const * const e) { + QState status_; + switch (e->sig) { + default: { + status_ = QM_SUPER(); + break; + } + } + Q_UNUSED_PAR(me); + return status_; +} + +//${SMs::ToastOven::SM::doorClosed::off} ..................................... +//${SMs::ToastOven::SM::doorClosed::off} +static QState ToastOven_off_e(ToastOven * const me) { + PRINTF_S("%s;", "toaster-Off"); + Q_UNUSED_PAR(me); + return QM_ENTRY(&ToastOven_off_s); +} +//${SMs::ToastOven::SM::doorClosed::off} +static QState ToastOven_off(ToastOven * const me, QEvt const * const e) { + QState status_; + switch (e->sig) { + default: { + status_ = QM_SUPER(); + break; + } + } + Q_UNUSED_PAR(me); + return status_; +} + +//${SMs::ToastOven::SM::doorOpen} ............................................ +//${SMs::ToastOven::SM::doorOpen} +static QState ToastOven_doorOpen_e(ToastOven * const me) { + PRINTF_S("%s;", "door-Open,lamp-On"); + Q_UNUSED_PAR(me); + return QM_ENTRY(&ToastOven_doorOpen_s); +} +//${SMs::ToastOven::SM::doorOpen} +static QState ToastOven_doorOpen_x(ToastOven * const me) { + PRINTF_S("%s;", "lamp-Off"); + (void)me; // unused parameter + return QM_EXIT(&ToastOven_doorOpen_s); +} +//${SMs::ToastOven::SM::doorOpen} +static QState ToastOven_doorOpen(ToastOven * const me, QEvt const * const e) { + QState status_; + switch (e->sig) { + //${SMs::ToastOven::SM::doorOpen::CLOSE} + case CLOSE_SIG: { + static struct { + QMState const *target; + QActionHandler act[4]; + } const tatbl_ = { // tran-action table + &ToastOven_heating_s, // target state + { + Q_ACTION_CAST(&ToastOven_doorOpen_x), // exit + Q_ACTION_CAST(&ToastOven_doorClosed_e), // entry + Q_ACTION_CAST(&ToastOven_heating_e), // entry + Q_ACTION_NULL // zero terminator + } + }; + status_ = QM_TRAN_HIST(me->hist_heating, &tatbl_); + break; + } + //${SMs::ToastOven::SM::doorOpen::TERMINATE} + case TERMINATE_SIG: { + static struct { + QMState const *target; + QActionHandler act[3]; + } const tatbl_ = { // tran-action table + &ToastOven_final_s, // target state + { + Q_ACTION_CAST(&ToastOven_doorOpen_x), // exit + Q_ACTION_CAST(&ToastOven_final_e), // entry + Q_ACTION_NULL // zero terminator + } + }; + status_ = QM_TRAN(&tatbl_); + break; + } + //${SMs::ToastOven::SM::doorOpen::OFF} + case OFF_SIG: { + static struct { + QMState const *target; + QActionHandler act[3]; + } const tatbl_ = { // tran-action table + &ToastOven_doorClosed_s, // target state + { + Q_ACTION_CAST(&ToastOven_doorOpen_x), // exit + Q_ACTION_CAST(&ToastOven_doorClosed_e), // entry + Q_ACTION_NULL // zero terminator + } + }; + status_ = QM_TRAN_HIST(me->hist_doorClosed, &tatbl_); + break; + } + default: { + status_ = QM_SUPER(); + break; + } + } + return status_; +} + +//${SMs::ToastOven::SM::final} ............................................... +//${SMs::ToastOven::SM::final} +static QState ToastOven_final_e(ToastOven * const me) { + PRINTF_S("\n%s\n", "Bye! Bye!"); + QF_onCleanup(); + exit(0); + Q_UNUSED_PAR(me); + return QM_ENTRY(&ToastOven_final_s); +} +//${SMs::ToastOven::SM::final} +static QState ToastOven_final(ToastOven * const me, QEvt const * const e) { + QState status_; + switch (e->sig) { + default: { + status_ = QM_SUPER(); + break; + } + } + Q_UNUSED_PAR(me); + return status_; +} +//$enddef${SMs::ToastOven} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/examples/posix-win32/history_qmsm/history.h b/examples/posix-win32/history_qmsm/history.h new file mode 100644 index 00000000..84094584 --- /dev/null +++ b/examples/posix-win32/history_qmsm/history.h @@ -0,0 +1,51 @@ +//$file${.::history.h} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// +// Model: history.qm +// File: ${.::history.h} +// +// This code has been generated by QM 5.3.0 . +// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. +// +// SPDX-License-Identifier: GPL-3.0-or-later +// +// This generated code is open source software: you can redistribute it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation. +// +// This code is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// NOTE: +// Alternatively, this generated code may be distributed under the terms +// of Quantum Leaps commercial licenses, which expressly supersede the GNU +// General Public License and are specifically designed for licensees +// interested in retaining the proprietary status of their code. +// +// Contact information: +// +// +// +//$endhead${.::history.h} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +#ifndef HISTORY_H_ +#define HISTORY_H_ + +enum ToastOvenSignals { + OPEN_SIG = Q_USER_SIG, + CLOSE_SIG, + TOAST_SIG, + BAKE_SIG, + OFF_SIG, + TERMINATE_SIG // terminate the application +}; + +extern QMsm * const the_oven; // opaque pointer to the oven SM + +//$declare${SMs::ToastOven_ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${SMs::ToastOven_ctor} ..................................................... +void ToastOven_ctor(void); +//$enddecl${SMs::ToastOven_ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +#endif // HISTORY_H_ diff --git a/examples/workstation/history_qmsm/history.qm b/examples/posix-win32/history_qmsm/history.qm similarity index 90% rename from examples/workstation/history_qmsm/history.qm rename to examples/posix-win32/history_qmsm/history.qm index 777b4b77..631285b6 100644 --- a/examples/workstation/history_qmsm/history.qm +++ b/examples/posix-win32/history_qmsm/history.qm @@ -1,5 +1,5 @@ - + Demonstration of transitions to shallow history and deep history in QMsm-style state machines. @@ -12,7 +12,7 @@ - (void)par; /* unused parameter */ + (void)par; // unused parameter @@ -153,8 +153,8 @@ QMsm_ctor(&me->super, Q_STATE_CAST(&ToastOven_initial)); - #ifndef HISTORY_H -#define HISTORY_H + #ifndef HISTORY_H_ +#define HISTORY_H_ enum ToastOvenSignals { OPEN_SIG = Q_USER_SIG, @@ -162,32 +162,31 @@ enum ToastOvenSignals { TOAST_SIG, BAKE_SIG, OFF_SIG, - TERMINATE_SIG /* terminate the application */ + TERMINATE_SIG // terminate the application }; -extern QHsm * const the_oven; /* opaque pointer to the oven HSM */ +extern QMsm * const the_oven; // opaque pointer to the oven SM $declare(SMs::ToastOven_ctor) -#endif /* HISTORY_H */ - +#endif // HISTORY_H_ #include "qpc.h" #include "history.h" -#include "safe_std.h" /* portable "safe" <stdio.h>/<string.h> facilities */ +#include "safe_std.h" // portable "safe" <stdio.h>/<string.h> facilities #include <stdlib.h> //Q_DEFINE_THIS_FILE $declare(SMs::ToastOven) -static ToastOven l_oven; /* the only instance of the ToastOven class */ +static ToastOven l_oven; // the only instance of the ToastOven class -/* global-scope definitions -----------------------------------------*/ -QHsm * const the_oven = &l_oven.super.super; /* the opaque pointer */ +// global-scope definitions ----------------------------------------- +QMsm * const the_oven = &l_oven.super; // the opaque pointer $define(SMs::ToastOven_ctor) $define(SMs::ToastOven) diff --git a/examples/posix-win32/history_qmsm/main.c b/examples/posix-win32/history_qmsm/main.c new file mode 100644 index 00000000..97ab87a6 --- /dev/null +++ b/examples/posix-win32/history_qmsm/main.c @@ -0,0 +1,102 @@ +//============================================================================ +// Product: History Example, Win32 +// Last updated for version 7.3.0 +// Last updated on 2023-06-30 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// This program is open source software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Alternatively, this program may be distributed and modified under the +// terms of Quantum Leaps commercial licenses, which expressly supersede +// the GNU General Public License and are specifically designed for +// licensees interested in retaining the proprietary status of their code. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Contact information: +// +// +//============================================================================ +#include "qpc.h" +#include "history.h" + +#include "safe_std.h" // portable "safe" / facilities +#include // for exit() + +Q_DEFINE_THIS_FILE + +//............................................................................ +int main() { + QF_init(); + QF_onStartup(); + + PRINTF_S("History state pattern\nQP version: %s\n" + "Press 'o' to OPEN the door\n" + "Press 'c' to CLOSE the door\n" + "Press 't' to start TOASTING\n" + "Press 'b' to start BAKING\n" + "Press 'f' to turn the oven OFF\n" + "Press ESC to quit...\n", + QP_VERSION_STR); + + // instantiate the ToastOven HSM and trigger the initial transition + ToastOven_ctor(); + QASM_INIT(the_oven, (void *)0, 0U); + + for (;;) { + QEvt e = QEVT_INITIALIZER(0U); + uint8_t c; + + PRINTF_S("\n", ""); + c = (uint8_t)QF_consoleWaitForKey(); + PRINTF_S("%c: ", (c >= ' ') ? c : 'X'); + + switch (c) { + case 'o': e.sig = OPEN_SIG; break; + case 'c': e.sig = CLOSE_SIG; break; + case 't': e.sig = TOAST_SIG; break; + case 'b': e.sig = BAKE_SIG; break; + case 'f': e.sig = OFF_SIG; break; + case 0x1B: e.sig = TERMINATE_SIG; break; + } + + // dispatch the event into the state machine + QASM_DISPATCH(the_oven, &e, 0U); + } + + QF_onCleanup(); + return 0; +} + +//............................................................................ +void QF_onStartup(void) { + QF_consoleSetup(); +} +//............................................................................ +void QF_onCleanup(void) { + QF_consoleCleanup(); +} +//............................................................................ +void QF_onClockTick(void) { +} + +//............................................................................ +Q_NORETURN Q_onError(char const * const module, int_t const id) { + FPRINTF_S(stderr, "ERROR in %s, line %d", module, id); + QF_onCleanup(); + exit(-1); +} diff --git a/examples/workstation/history_qmsm/proj.sln b/examples/posix-win32/history_qmsm/proj.sln similarity index 100% rename from examples/workstation/history_qmsm/proj.sln rename to examples/posix-win32/history_qmsm/proj.sln diff --git a/examples/workstation/history_qmsm/proj.vcxproj b/examples/posix-win32/history_qmsm/proj.vcxproj similarity index 100% rename from examples/workstation/history_qmsm/proj.vcxproj rename to examples/posix-win32/history_qmsm/proj.vcxproj diff --git a/examples/workstation/history_qmsm/proj.vcxproj.filters b/examples/posix-win32/history_qmsm/proj.vcxproj.filters similarity index 100% rename from examples/workstation/history_qmsm/proj.vcxproj.filters rename to examples/posix-win32/history_qmsm/proj.vcxproj.filters diff --git a/examples/arm-cm/blinky_ek-tm4c123gxl/qube/Makefile b/examples/posix-win32/qhsmtst/Makefile similarity index 79% rename from examples/arm-cm/blinky_ek-tm4c123gxl/qube/Makefile rename to examples/posix-win32/qhsmtst/Makefile index eb12208d..523e8485 100644 --- a/examples/arm-cm/blinky_ek-tm4c123gxl/qube/Makefile +++ b/examples/posix-win32/qhsmtst/Makefile @@ -1,7 +1,7 @@ ############################################################################## -# Product: Makefile for Qube for Windows and POSIX *HOSTS* -# Last updated for version 7.2.0 -# Last updated on 2023-01-08 +# Product: Makefile for QEP/C for Windows and POSIX *HOSTS* +# Last updated for version 7.3.0 +# Last updated on 2023-09-02 # # Q u a n t u m L e a P s # ------------------------ @@ -33,9 +33,11 @@ ############################################################################## # # examples of invoking this Makefile: -# building configurations: qube +# building configurations: Debug (default), Release, and Spy # make +# make CONF=rel # make clean # cleanup the build +# make CONF=rel clean # cleanup the build # # NOTE: # To use this Makefile on Windows, you will need the GNU make utility, which @@ -46,29 +48,24 @@ #----------------------------------------------------------------------------- # project name: # -PROJECT := qube +PROJECT := qhsmtst #----------------------------------------------------------------------------- # project directories: # # list of all source directories used by this project -VPATH := .. +VPATH := . # list of all include directories needed by this project -INCLUDES := -I.. +INCLUDES := -I. # location of the QP/C framework (if not provided in an env. variable) ifeq ($(QPC),) -QPC := ../../../.. +QPC := ../../.. endif -QP_PORT_DIR := $(QPC)/ports/qube - -# make sure that QTOOLS env. variable is defined... -ifeq ("$(wildcard $(QTOOLS))","") -$(error QTOOLS not found. Please install QTools and define QTOOLS env. variable) -endif +QP_PORT_DIR := $(QPC)/ports/qep-only #----------------------------------------------------------------------------- # project files: @@ -76,15 +73,15 @@ endif # C source files... C_SRCS := \ - blinky.c \ main.c \ - bsp_qube.c + qhsmtst.c \ + qep_hsm.c # C++ source files... CPP_SRCS := -LIB_DIRS := -LIBS := +LIB_DIRS := +LIBS := # defines... # QP_API_VERSION controls the QP API compatibility; 9999 means the latest API @@ -94,32 +91,12 @@ ifeq (,$(CONF)) CONF := dbg endif -#----------------------------------------------------------------------------- -# add QP/C framework, the "Qube" environment: -# -C_SRCS += \ - qep_hsm.c \ - qep_msm.c \ - qf_actq.c \ - qf_defer.c \ - qf_dyn.c \ - qf_mem.c \ - qf_ps.c \ - qf_qact.c \ - qf_qeq.c \ - qf_qmact.c \ - qf_time.c \ - qube.c - -QS_SRCS := \ - qs.c \ - qs_64bit.c \ - qs_fp.c \ - qspy.c - #============================================================================ # Typically you should not need to change anything below this line +VPATH += $(QPC)/src/qf $(QP_PORT_DIR) +INCLUDES += -I$(QPC)/include -I$(QP_PORT_DIR) + #----------------------------------------------------------------------------- # GNU toolset: # @@ -151,21 +128,34 @@ else endif #----------------------------------------------------------------------------- -# only Q_SPY build configuration... +# build configurations... -BIN_DIR := $(PROJECT) +ifeq (rel, $(CONF)) # Release configuration .................................. -C_SRCS += $(QS_SRCS) -INCLUDES += -I$(QPC)/include -I$(QP_PORT_DIR) -I$(QTOOLS)/qspy/include -VPATH += $(QPC)/src/qf $(QPC)/src/qs $(QP_PORT_DIR) $(QTOOLS)/qspy/source +BIN_DIR := build_rel +# gcc options: +CFLAGS = -c -O3 -fno-pie -std=c11 -pedantic -Wall -Wextra -W \ + $(INCLUDES) $(DEFINES) -DNDEBUG + +CPPFLAGS = -c -O3 -fno-pie -std=c++11 -pedantic -Wall -Wextra \ + -fno-rtti -fno-exceptions \ + $(INCLUDES) $(DEFINES) -DNDEBUG + +else ifeq (spy, $(CONF)) # Spy configuration ................................ + +else # default Debug configuration ......................................... + +BIN_DIR := build # gcc options: CFLAGS = -c -g -O -fno-pie -std=c11 -pedantic -Wall -Wextra -W \ - $(INCLUDES) $(DEFINES) -DQ_SPY + $(INCLUDES) $(DEFINES) CPPFLAGS = -c -g -O -fno-pie -std=c++11 -pedantic -Wall -Wextra \ -fno-rtti -fno-exceptions \ - $(INCLUDES) $(DEFINES) -DQ_SPY + $(INCLUDES) $(DEFINES) + +endif # ..................................................................... ifndef GCC_OLD LINKFLAGS := -no-pie @@ -190,12 +180,12 @@ endif # rules # +.PHONY: clean show + all: $(TARGET_EXE) - $(TARGET_EXE) $(TARGET_EXE) : $(C_OBJS_EXT) $(CPP_OBJS_EXT) - $(CC) $(CFLAGS) $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o - $(LINK) $(LINKFLAGS) $(LIB_DIRS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) + $(LINK) $(LINKFLAGS) $(LIB_DIRS) -o $@ $^ $(LIBS) $(BIN_DIR)/%.d : %.c $(CC) -MM -MT $(@:.d=.o) $(CFLAGS) $< > $@ @@ -209,17 +199,18 @@ $(BIN_DIR)/%.o : %.c $(BIN_DIR)/%.o : %.cpp $(CPP) $(CPPFLAGS) $< -o $@ -.PHONY : clean show - -# include dependency files only if our goal depends on their existence +# create BIN_DIR and include dependencies only if needed ifneq ($(MAKECMDGOALS),clean) ifneq ($(MAKECMDGOALS),show) + ifneq ($(MAKECMDGOALS),debug) +ifeq ("$(wildcard $(BIN_DIR))","") +$(shell $(MKDIR) $(BIN_DIR)) +endif -include $(C_DEPS_EXT) $(CPP_DEPS_EXT) + endif endif endif -.PHONY : clean show - clean : -$(RM) $(BIN_DIR)/*.o \ $(BIN_DIR)/*.d \ diff --git a/examples/posix-win32/qhsmtst/QM-type-enum.png b/examples/posix-win32/qhsmtst/QM-type-enum.png new file mode 100644 index 00000000..b040bebb Binary files /dev/null and b/examples/posix-win32/qhsmtst/QM-type-enum.png differ diff --git a/examples/workstation/qhsmtst/SM_of_QHsmTst.png b/examples/posix-win32/qhsmtst/SM_of_QHsmTst.png similarity index 100% rename from examples/workstation/qhsmtst/SM_of_QHsmTst.png rename to examples/posix-win32/qhsmtst/SM_of_QHsmTst.png diff --git a/examples/workstation/qhsmtst/log.txt b/examples/posix-win32/qhsmtst/log.txt similarity index 97% rename from examples/workstation/qhsmtst/log.txt rename to examples/posix-win32/qhsmtst/log.txt index fa0c8bd9..5a5349bb 100644 --- a/examples/workstation/qhsmtst/log.txt +++ b/examples/posix-win32/qhsmtst/log.txt @@ -1,4 +1,4 @@ -QHsmTst example, QP 7.1.3 +QHsmTst example, QP 7.3.0 top-INIT;s-ENTRY;s2-ENTRY;s2-INIT;s21-ENTRY;s211-ENTRY; A:s21-A;s211-EXIT;s21-EXIT;s21-ENTRY;s21-INIT;s211-ENTRY; B:s21-B;s211-EXIT;s211-ENTRY; diff --git a/examples/posix-win32/qhsmtst/main.c b/examples/posix-win32/qhsmtst/main.c new file mode 100644 index 00000000..e2957fa3 --- /dev/null +++ b/examples/posix-win32/qhsmtst/main.c @@ -0,0 +1,147 @@ +//============================================================================ +// Product: QHsmTst Example +// Last updated for version 7.3.0 +// Last updated on 2023-08-15 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// This program is open source software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Alternatively, this program may be distributed and modified under the +// terms of Quantum Leaps commercial licenses, which expressly supersede +// the GNU General Public License and are specifically designed for +// licensees interested in retaining the proprietary status of their code. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Contact information: +// +// +//============================================================================ +#include "qpc.h" // QP/C framework +#include "qhsmtst.h" // QHsmTst state machine + +#include "safe_std.h" // portable "safe" / facilities +#include // for exit() + +Q_DEFINE_THIS_FILE + +// local objects ----------------------------------------------------------- +static FILE *l_outFile = (FILE *)0; +static void dispatch(QSignal sig); + +//............................................................................ +int main(int argc, char *argv[]) { + + QHsmTst_ctor(); // instantiate the QHsmTst object + + if (argc > 1) { // file name provided? + FOPEN_S(l_outFile, argv[1], "w"); + } + + if (l_outFile == (FILE *)0) { // interactive version? + l_outFile = stdout; // use the stdout as the output file + + PRINTF_S("QHsmTst example, built on %s at %s,\n" + "QP: %s.\nEnter x or X to quit...\n", + __DATE__, __TIME__, QP_VERSION_STR); + + QASM_INIT(the_sm, (void *)0, 0U); // the top-most initial tran. + + for (;;) { // event loop + PRINTF_S("\n%s", ">>>"); + char inp[4]; + scanf("%1s", inp); // input the event + + QEvt e = QEVT_INITIALIZER(0U); + if ('a' <= inp[0] && inp[0] <= 'i') { // in range? + e.sig = (QSignal)(inp[0] - 'a' + A_SIG); + } + else if ('A' <= inp[0] && inp[0] <= 'I') { // in range? + e.sig = (QSignal)(inp[0] - 'A' + A_SIG); + } + else if ((inp[0] == 'x') || (inp[0] == 'X')) { // x or X? + e.sig = TERMINATE_SIG; // terminate the interactive test + } + else { + e.sig = IGNORE_SIG; + } + + QASM_DISPATCH(the_sm, &e, 0U); // dispatch the event + } + } + else { // batch version + PRINTF_S("QHsmTst example, built on %s at %s, QP %s\n" + "output saved to %s\n", + __DATE__, __TIME__, QP_VERSION_STR, + argv[1]); + + FPRINTF_S(l_outFile, "QHsmTst example, QP %s\n", + QP_VERSION_STR); + + QASM_INIT(the_sm, (void *)0, 0U); // the top-most initial tran. + + // testing of dynamic transitions... + dispatch(A_SIG); + dispatch(B_SIG); + dispatch(D_SIG); + dispatch(E_SIG); + dispatch(I_SIG); + dispatch(F_SIG); + dispatch(I_SIG); + dispatch(I_SIG); + dispatch(F_SIG); + dispatch(A_SIG); + dispatch(B_SIG); + dispatch(D_SIG); + dispatch(D_SIG); + dispatch(E_SIG); + dispatch(G_SIG); + dispatch(H_SIG); + dispatch(H_SIG); + dispatch(C_SIG); + dispatch(G_SIG); + dispatch(C_SIG); + dispatch(C_SIG); + + fclose(l_outFile); + } + + return 0; +} +//............................................................................ +Q_NORETURN Q_onError(char const * const module, int_t const id) { + FPRINTF_S(stderr, "ERROR in %s:%d", module, id); + exit(-1); +} +//............................................................................ +void BSP_display(char const *msg) { + FPRINTF_S(l_outFile, "%s", msg); +} +//............................................................................ +void BSP_terminate(int16_t const result) { + PRINTF_S("\n%s\n", "Bye, Bye!"); + exit(result); +} +//............................................................................ +static void dispatch(QSignal sig) { + QEvt e = QEVT_INITIALIZER(0U); + Q_REQUIRE((A_SIG <= sig) && (sig <= I_SIG)); + e.sig = sig; + FPRINTF_S(l_outFile, "\n%c:", 'A' + sig - A_SIG); + QASM_DISPATCH(the_sm, &e, 0U); // dispatch the event +} + diff --git a/examples/workstation/qhsmtst/qhsmtst.c b/examples/posix-win32/qhsmtst/qhsmtst.c similarity index 57% rename from examples/workstation/qhsmtst/qhsmtst.c rename to examples/posix-win32/qhsmtst/qhsmtst.c index 4467334f..f4c513ce 100644 --- a/examples/workstation/qhsmtst/qhsmtst.c +++ b/examples/posix-win32/qhsmtst/qhsmtst.c @@ -1,48 +1,51 @@ -/*$file${.::qhsmtst.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* -* Model: qhsmtst.qm -* File: ${.::qhsmtst.c} -* -* This code has been generated by QM 5.2.4 . -* DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. -* -* SPDX-License-Identifier: GPL-3.0-or-later -* -* This generated code is open source software: you can redistribute it under -* the terms of the GNU General Public License as published by the Free -* Software Foundation. -* -* This code is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -* more details. -* -* NOTE: -* Alternatively, this generated code may be distributed under the terms -* of Quantum Leaps commercial licenses, which expressly supersede the GNU -* General Public License and are specifically designed for licensees -* interested in retaining the proprietary status of their code. -* -* Contact information: -* -* -*/ -/*$endhead${.::qhsmtst.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -#include "qpc.h" -#include "qhsmtst.h" +//$file${.::qhsmtst.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// +// Model: qhsmtst.qm +// File: ${.::qhsmtst.c} +// +// This code has been generated by QM 5.3.0 . +// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. +// +// SPDX-License-Identifier: GPL-3.0-or-later +// +// This generated code is open source software: you can redistribute it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation. +// +// This code is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// NOTE: +// Alternatively, this generated code may be distributed under the terms +// of Quantum Leaps commercial licenses, which expressly supersede the GNU +// General Public License and are specifically designed for licensees +// interested in retaining the proprietary status of their code. +// +// Contact information: +// +// +// +//$endhead${.::qhsmtst.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +#include "qpc.h" // QP/C framework +#include "qhsmtst.h" // this application -/*$declare${HSMs::QHsmTst} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//$declare${SMs::QHsmTst} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/*${HSMs::QHsmTst} .........................................................*/ -typedef struct { -/* protected: */ +//${SMs::QHsmTst} ............................................................ +typedef struct QHsmTst { +// protected: QHsm super; -/* private: */ +// private: uint8_t foo; -} QHsmTst; -/* protected: */ +// public: +} QHsmTst; +extern QHsmTst QHsmTst_inst; + +// protected: static QState QHsmTst_initial(QHsmTst * const me, void const * const par); static QState QHsmTst_s(QHsmTst * const me, QEvt const * const e); static QState QHsmTst_s1(QHsmTst * const me, QEvt const * const e); @@ -50,39 +53,51 @@ static QState QHsmTst_s11(QHsmTst * const me, QEvt const * const e); static QState QHsmTst_s2(QHsmTst * const me, QEvt const * const e); static QState QHsmTst_s21(QHsmTst * const me, QEvt const * const e); static QState QHsmTst_s211(QHsmTst * const me, QEvt const * const e); -/*$enddecl${HSMs::QHsmTst} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ - -static QHsmTst l_sm; /* the only instance of the QHsmTst class */ - -/* global-scope definitions ---------------------------------------*/ -QHsm * const the_sm = &l_sm.super; /* the opaque pointer */ - -/*$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* Check for the minimum required QP version */ -#if (QP_VERSION < 700U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) -#error qpc version 7.0.0 or higher required +//$enddecl${SMs::QHsmTst} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +//$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// Check for the minimum required QP version +#if (QP_VERSION < 730U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) +#error qpc version 7.3.0 or higher required #endif -/*$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -/*$define${HSMs::QHsmTst_ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//$define${Shared::the_sm} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/*${HSMs::QHsmTst_ctor} ....................................................*/ +//${Shared::the_sm} .......................................................... +QAsm * const the_sm = &QHsmTst_inst.super.super; +//$enddef${Shared::the_sm} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +//$define${Shared::QHsmTst_ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${Shared::QHsmTst_ctor} .................................................... void QHsmTst_ctor(void) { - QHsmTst *me = &l_sm; + QHsmTst *me = &QHsmTst_inst; QHsm_ctor(&me->super, Q_STATE_CAST(&QHsmTst_initial)); } -/*$enddef${HSMs::QHsmTst_ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*$define${HSMs::QHsmTst} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//$enddef${Shared::QHsmTst_ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +//$define${SMs::QHsmTst} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/*${HSMs::QHsmTst} .........................................................*/ +//${SMs::QHsmTst} ............................................................ +QHsmTst QHsmTst_inst; -/*${HSMs::QHsmTst::SM} .....................................................*/ +//${SMs::QHsmTst::SM} ........................................................ static QState QHsmTst_initial(QHsmTst * const me, void const * const par) { - /*${HSMs::QHsmTst::SM::initial} */ - (void)par; /* unused parameter */ + //${SMs::QHsmTst::SM::initial} + Q_UNUSED_PAR(par); me->foo = 0U; BSP_display("top-INIT;"); + QS_SIG_DICTIONARY(A_SIG, (void *)0); + QS_SIG_DICTIONARY(B_SIG, (void *)0); + QS_SIG_DICTIONARY(C_SIG, (void *)0); + QS_SIG_DICTIONARY(D_SIG, (void *)0); + QS_SIG_DICTIONARY(E_SIG, (void *)0); + QS_SIG_DICTIONARY(F_SIG, (void *)0); + QS_SIG_DICTIONARY(G_SIG, (void *)0); + QS_SIG_DICTIONARY(H_SIG, (void *)0); + QS_SIG_DICTIONARY(I_SIG, (void *)0); + QS_SIG_DICTIONARY(IGNORE_SIG, (void *)0); + QS_SIG_DICTIONARY(TERMINATE_SIG, (void *)0); + QS_FUN_DICTIONARY(&QHsmTst_s); QS_FUN_DICTIONARY(&QHsmTst_s1); QS_FUN_DICTIONARY(&QHsmTst_s11); @@ -93,31 +108,31 @@ static QState QHsmTst_initial(QHsmTst * const me, void const * const par) { return Q_TRAN(&QHsmTst_s2); } -/*${HSMs::QHsmTst::SM::s} ..................................................*/ +//${SMs::QHsmTst::SM::s} ..................................................... static QState QHsmTst_s(QHsmTst * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${HSMs::QHsmTst::SM::s} */ + //${SMs::QHsmTst::SM::s} case Q_ENTRY_SIG: { BSP_display("s-ENTRY;"); status_ = Q_HANDLED(); break; } - /*${HSMs::QHsmTst::SM::s} */ + //${SMs::QHsmTst::SM::s} case Q_EXIT_SIG: { BSP_display("s-EXIT;"); status_ = Q_HANDLED(); break; } - /*${HSMs::QHsmTst::SM::s::initial} */ + //${SMs::QHsmTst::SM::s::initial} case Q_INIT_SIG: { BSP_display("s-INIT;"); status_ = Q_TRAN(&QHsmTst_s11); break; } - /*${HSMs::QHsmTst::SM::s::I} */ + //${SMs::QHsmTst::SM::s::I} case I_SIG: { - /*${HSMs::QHsmTst::SM::s::I::[me->foo]} */ + //${SMs::QHsmTst::SM::s::I::[me->foo]} if (me->foo) { me->foo = 0U; BSP_display("s-I;"); @@ -128,15 +143,15 @@ static QState QHsmTst_s(QHsmTst * const me, QEvt const * const e) { } break; } - /*${HSMs::QHsmTst::SM::s::E} */ + //${SMs::QHsmTst::SM::s::E} case E_SIG: { BSP_display("s-E;"); status_ = Q_TRAN(&QHsmTst_s11); break; } - /*${HSMs::QHsmTst::SM::s::TERMINATE} */ + //${SMs::QHsmTst::SM::s::TERMINATE} case TERMINATE_SIG: { - BSP_exit(); + BSP_terminate(0); status_ = Q_HANDLED(); break; } @@ -148,37 +163,37 @@ static QState QHsmTst_s(QHsmTst * const me, QEvt const * const e) { return status_; } -/*${HSMs::QHsmTst::SM::s::s1} ..............................................*/ +//${SMs::QHsmTst::SM::s::s1} ................................................. static QState QHsmTst_s1(QHsmTst * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${HSMs::QHsmTst::SM::s::s1} */ + //${SMs::QHsmTst::SM::s::s1} case Q_ENTRY_SIG: { BSP_display("s1-ENTRY;"); status_ = Q_HANDLED(); break; } - /*${HSMs::QHsmTst::SM::s::s1} */ + //${SMs::QHsmTst::SM::s::s1} case Q_EXIT_SIG: { BSP_display("s1-EXIT;"); status_ = Q_HANDLED(); break; } - /*${HSMs::QHsmTst::SM::s::s1::initial} */ + //${SMs::QHsmTst::SM::s::s1::initial} case Q_INIT_SIG: { BSP_display("s1-INIT;"); status_ = Q_TRAN(&QHsmTst_s11); break; } - /*${HSMs::QHsmTst::SM::s::s1::I} */ + //${SMs::QHsmTst::SM::s::s1::I} case I_SIG: { BSP_display("s1-I;"); status_ = Q_HANDLED(); break; } - /*${HSMs::QHsmTst::SM::s::s1::D} */ + //${SMs::QHsmTst::SM::s::s1::D} case D_SIG: { - /*${HSMs::QHsmTst::SM::s::s1::D::[!me->foo]} */ + //${SMs::QHsmTst::SM::s::s1::D::[!me->foo]} if (!me->foo) { me->foo = 1U; BSP_display("s1-D;"); @@ -189,25 +204,25 @@ static QState QHsmTst_s1(QHsmTst * const me, QEvt const * const e) { } break; } - /*${HSMs::QHsmTst::SM::s::s1::A} */ + //${SMs::QHsmTst::SM::s::s1::A} case A_SIG: { BSP_display("s1-A;"); status_ = Q_TRAN(&QHsmTst_s1); break; } - /*${HSMs::QHsmTst::SM::s::s1::B} */ + //${SMs::QHsmTst::SM::s::s1::B} case B_SIG: { BSP_display("s1-B;"); status_ = Q_TRAN(&QHsmTst_s11); break; } - /*${HSMs::QHsmTst::SM::s::s1::F} */ + //${SMs::QHsmTst::SM::s::s1::F} case F_SIG: { BSP_display("s1-F;"); status_ = Q_TRAN(&QHsmTst_s211); break; } - /*${HSMs::QHsmTst::SM::s::s1::C} */ + //${SMs::QHsmTst::SM::s::s1::C} case C_SIG: { BSP_display("s1-C;"); status_ = Q_TRAN(&QHsmTst_s2); @@ -221,31 +236,31 @@ static QState QHsmTst_s1(QHsmTst * const me, QEvt const * const e) { return status_; } -/*${HSMs::QHsmTst::SM::s::s1::s11} .........................................*/ +//${SMs::QHsmTst::SM::s::s1::s11} ............................................ static QState QHsmTst_s11(QHsmTst * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${HSMs::QHsmTst::SM::s::s1::s11} */ + //${SMs::QHsmTst::SM::s::s1::s11} case Q_ENTRY_SIG: { BSP_display("s11-ENTRY;"); status_ = Q_HANDLED(); break; } - /*${HSMs::QHsmTst::SM::s::s1::s11} */ + //${SMs::QHsmTst::SM::s::s1::s11} case Q_EXIT_SIG: { BSP_display("s11-EXIT;"); status_ = Q_HANDLED(); break; } - /*${HSMs::QHsmTst::SM::s::s1::s11::H} */ + //${SMs::QHsmTst::SM::s::s1::s11::H} case H_SIG: { BSP_display("s11-H;"); status_ = Q_TRAN(&QHsmTst_s); break; } - /*${HSMs::QHsmTst::SM::s::s1::s11::D} */ + //${SMs::QHsmTst::SM::s::s1::s11::D} case D_SIG: { - /*${HSMs::QHsmTst::SM::s::s1::s11::D::[me->foo]} */ + //${SMs::QHsmTst::SM::s::s1::s11::D::[me->foo]} if (me->foo) { me->foo = 0U; BSP_display("s11-D;"); @@ -256,7 +271,7 @@ static QState QHsmTst_s11(QHsmTst * const me, QEvt const * const e) { } break; } - /*${HSMs::QHsmTst::SM::s::s1::s11::G} */ + //${SMs::QHsmTst::SM::s::s1::s11::G} case G_SIG: { BSP_display("s11-G;"); status_ = Q_TRAN(&QHsmTst_s211); @@ -270,31 +285,31 @@ static QState QHsmTst_s11(QHsmTst * const me, QEvt const * const e) { return status_; } -/*${HSMs::QHsmTst::SM::s::s2} ..............................................*/ +//${SMs::QHsmTst::SM::s::s2} ................................................. static QState QHsmTst_s2(QHsmTst * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${HSMs::QHsmTst::SM::s::s2} */ + //${SMs::QHsmTst::SM::s::s2} case Q_ENTRY_SIG: { BSP_display("s2-ENTRY;"); status_ = Q_HANDLED(); break; } - /*${HSMs::QHsmTst::SM::s::s2} */ + //${SMs::QHsmTst::SM::s::s2} case Q_EXIT_SIG: { BSP_display("s2-EXIT;"); status_ = Q_HANDLED(); break; } - /*${HSMs::QHsmTst::SM::s::s2::initial} */ + //${SMs::QHsmTst::SM::s::s2::initial} case Q_INIT_SIG: { BSP_display("s2-INIT;"); status_ = Q_TRAN(&QHsmTst_s211); break; } - /*${HSMs::QHsmTst::SM::s::s2::I} */ + //${SMs::QHsmTst::SM::s::s2::I} case I_SIG: { - /*${HSMs::QHsmTst::SM::s::s2::I::[!me->foo]} */ + //${SMs::QHsmTst::SM::s::s2::I::[!me->foo]} if (!me->foo) { me->foo = 1U; BSP_display("s2-I;"); @@ -305,13 +320,13 @@ static QState QHsmTst_s2(QHsmTst * const me, QEvt const * const e) { } break; } - /*${HSMs::QHsmTst::SM::s::s2::F} */ + //${SMs::QHsmTst::SM::s::s2::F} case F_SIG: { BSP_display("s2-F;"); status_ = Q_TRAN(&QHsmTst_s11); break; } - /*${HSMs::QHsmTst::SM::s::s2::C} */ + //${SMs::QHsmTst::SM::s::s2::C} case C_SIG: { BSP_display("s2-C;"); status_ = Q_TRAN(&QHsmTst_s1); @@ -325,41 +340,41 @@ static QState QHsmTst_s2(QHsmTst * const me, QEvt const * const e) { return status_; } -/*${HSMs::QHsmTst::SM::s::s2::s21} .........................................*/ +//${SMs::QHsmTst::SM::s::s2::s21} ............................................ static QState QHsmTst_s21(QHsmTst * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${HSMs::QHsmTst::SM::s::s2::s21} */ + //${SMs::QHsmTst::SM::s::s2::s21} case Q_ENTRY_SIG: { BSP_display("s21-ENTRY;"); status_ = Q_HANDLED(); break; } - /*${HSMs::QHsmTst::SM::s::s2::s21} */ + //${SMs::QHsmTst::SM::s::s2::s21} case Q_EXIT_SIG: { BSP_display("s21-EXIT;"); status_ = Q_HANDLED(); break; } - /*${HSMs::QHsmTst::SM::s::s2::s21::initial} */ + //${SMs::QHsmTst::SM::s::s2::s21::initial} case Q_INIT_SIG: { BSP_display("s21-INIT;"); status_ = Q_TRAN(&QHsmTst_s211); break; } - /*${HSMs::QHsmTst::SM::s::s2::s21::G} */ + //${SMs::QHsmTst::SM::s::s2::s21::G} case G_SIG: { BSP_display("s21-G;"); status_ = Q_TRAN(&QHsmTst_s1); break; } - /*${HSMs::QHsmTst::SM::s::s2::s21::A} */ + //${SMs::QHsmTst::SM::s::s2::s21::A} case A_SIG: { BSP_display("s21-A;"); status_ = Q_TRAN(&QHsmTst_s21); break; } - /*${HSMs::QHsmTst::SM::s::s2::s21::B} */ + //${SMs::QHsmTst::SM::s::s2::s21::B} case B_SIG: { BSP_display("s21-B;"); status_ = Q_TRAN(&QHsmTst_s211); @@ -373,29 +388,29 @@ static QState QHsmTst_s21(QHsmTst * const me, QEvt const * const e) { return status_; } -/*${HSMs::QHsmTst::SM::s::s2::s21::s211} ...................................*/ +//${SMs::QHsmTst::SM::s::s2::s21::s211} ...................................... static QState QHsmTst_s211(QHsmTst * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${HSMs::QHsmTst::SM::s::s2::s21::s211} */ + //${SMs::QHsmTst::SM::s::s2::s21::s211} case Q_ENTRY_SIG: { BSP_display("s211-ENTRY;"); status_ = Q_HANDLED(); break; } - /*${HSMs::QHsmTst::SM::s::s2::s21::s211} */ + //${SMs::QHsmTst::SM::s::s2::s21::s211} case Q_EXIT_SIG: { BSP_display("s211-EXIT;"); status_ = Q_HANDLED(); break; } - /*${HSMs::QHsmTst::SM::s::s2::s21::s211::H} */ + //${SMs::QHsmTst::SM::s::s2::s21::s211::H} case H_SIG: { BSP_display("s211-H;"); status_ = Q_TRAN(&QHsmTst_s); break; } - /*${HSMs::QHsmTst::SM::s::s2::s21::s211::D} */ + //${SMs::QHsmTst::SM::s::s2::s21::s211::D} case D_SIG: { BSP_display("s211-D;"); status_ = Q_TRAN(&QHsmTst_s21); @@ -408,5 +423,4 @@ static QState QHsmTst_s211(QHsmTst * const me, QEvt const * const e) { } return status_; } -/*$enddef${HSMs::QHsmTst} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ - +//$enddef${SMs::QHsmTst} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/examples/posix-win32/qhsmtst/qhsmtst.h b/examples/posix-win32/qhsmtst/qhsmtst.h new file mode 100644 index 00000000..68f96e40 --- /dev/null +++ b/examples/posix-win32/qhsmtst/qhsmtst.h @@ -0,0 +1,65 @@ +//$file${.::qhsmtst.h} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// +// Model: qhsmtst.qm +// File: ${.::qhsmtst.h} +// +// This code has been generated by QM 5.3.0 . +// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. +// +// SPDX-License-Identifier: GPL-3.0-or-later +// +// This generated code is open source software: you can redistribute it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation. +// +// This code is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// NOTE: +// Alternatively, this generated code may be distributed under the terms +// of Quantum Leaps commercial licenses, which expressly supersede the GNU +// General Public License and are specifically designed for licensees +// interested in retaining the proprietary status of their code. +// +// Contact information: +// +// +// +//$endhead${.::qhsmtst.h} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +#ifndef QHSMTST_H_ +#define QHSMTST_H_ + +//$declare${Shared} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${Shared::QHsmTstSignals} .................................................. +enum QHsmTstSignals { + A_SIG = Q_USER_SIG, + B_SIG, + C_SIG, + D_SIG, + E_SIG, + F_SIG, + G_SIG, + H_SIG, + I_SIG, + TERMINATE_SIG, + IGNORE_SIG, + MAX_SIG +}; + +//${Shared::the_sm} .......................................................... +extern QAsm * const the_sm; + +//${Shared::QHsmTst_ctor} .................................................... +void QHsmTst_ctor(void); + +//${Shared::BSP_display} ..................................................... +void BSP_display(char const * msg); + +//${Shared::BSP_terminate} ................................................... +void BSP_terminate(int16_t const result); +//$enddecl${Shared} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +#endif // QHSMTST_H_ diff --git a/examples/workstation/qhsmtst/qhsmtst.qm b/examples/posix-win32/qhsmtst/qhsmtst.qm similarity index 69% rename from examples/workstation/qhsmtst/qhsmtst.qm rename to examples/posix-win32/qhsmtst/qhsmtst.qm index 739dc9bc..3b6dee0d 100644 --- a/examples/workstation/qhsmtst/qhsmtst.qm +++ b/examples/posix-win32/qhsmtst/qhsmtst.qm @@ -1,40 +1,94 @@ - + QHsmTst is a contrived state machine from Chapter 2 of the PSiCC2 book for testing all possible transition topologies with up to 4-levels of state nesting. - - - + + + + + { + A_SIG = Q_USER_SIG, + B_SIG, + C_SIG, + D_SIG, + E_SIG, + F_SIG, + G_SIG, + H_SIG, + I_SIG, + TERMINATE_SIG, + IGNORE_SIG, + MAX_SIG +}; + + + + opaque pointer to the test SM + = &QHsmTst_inst.super.super; + + + + QHsmTst *me = &QHsmTst_inst; +QHsm_ctor(&me->super, Q_STATE_CAST(&QHsmTst_initial)); + + + + + + + + + + + + + + + Test active object - + - + + + - + - (void)par; /* unused parameter */ + Q_UNUSED_PAR(par); me->foo = 0U; -BSP_display("top-INIT;"); +BSP_display("top-INIT;"); + +QS_SIG_DICTIONARY(A_SIG, (void *)0); +QS_SIG_DICTIONARY(B_SIG, (void *)0); +QS_SIG_DICTIONARY(C_SIG, (void *)0); +QS_SIG_DICTIONARY(D_SIG, (void *)0); +QS_SIG_DICTIONARY(E_SIG, (void *)0); +QS_SIG_DICTIONARY(F_SIG, (void *)0); +QS_SIG_DICTIONARY(G_SIG, (void *)0); +QS_SIG_DICTIONARY(H_SIG, (void *)0); +QS_SIG_DICTIONARY(I_SIG, (void *)0); +QS_SIG_DICTIONARY(IGNORE_SIG, (void *)0); +QS_SIG_DICTIONARY(TERMINATE_SIG, (void *)0); - + BSP_display("s-ENTRY;"); BSP_display("s-EXIT;"); - + BSP_display("s-INIT;"); - + - + me->foo me->foo = 0U; @@ -47,41 +101,41 @@ BSP_display("s-I;"); - + BSP_display("s-E;"); - + - BSP_exit(); + BSP_terminate(0); - + BSP_display("s1-ENTRY;"); BSP_display("s1-EXIT;"); - + BSP_display("s1-INIT;"); - + BSP_display("s1-I;"); - + - + !me->foo me->foo = 1U; @@ -94,48 +148,48 @@ BSP_display("s1-D;"); - + BSP_display("s1-A;"); - + BSP_display("s1-B;"); - + BSP_display("s1-F;"); - + BSP_display("s1-C;"); - + BSP_display("s11-ENTRY;"); BSP_display("s11-EXIT;"); - + BSP_display("s11-H;"); - + - + me->foo me->foo = 0U; @@ -148,7 +202,7 @@ BSP_display("s11-D;"); - + BSP_display("s11-G;"); @@ -165,20 +219,20 @@ BSP_display("s11-D;"); - + BSP_display("s2-ENTRY;"); BSP_display("s2-EXIT;"); - + BSP_display("s2-INIT;"); - + - + !me->foo me->foo = 1U; @@ -191,64 +245,64 @@ BSP_display("s2-I;"); - + BSP_display("s2-F;"); - + BSP_display("s2-C;"); - + BSP_display("s21-ENTRY;"); BSP_display("s21-EXIT;"); - + BSP_display("s21-INIT;"); - + BSP_display("s21-G;"); - + BSP_display("s21-A;"); - + BSP_display("s21-B;"); - + BSP_display("s211-ENTRY;"); BSP_display("s211-EXIT;"); - + BSP_display("s211-H;"); - + BSP_display("s211-D;"); @@ -278,60 +332,27 @@ BSP_display("s2-I;"); - - - QHsmTst *me = &l_sm; -QHsm_ctor(&me->super, Q_STATE_CAST(&QHsmTst_initial)); - - #ifndef QHSMTST_H -#define QHSMTST_H + #ifndef QHSMTST_H_ +#define QHSMTST_H_ -enum QHsmTstSignals { - A_SIG = Q_USER_SIG, - B_SIG, - C_SIG, - D_SIG, - E_SIG, - F_SIG, - G_SIG, - H_SIG, - I_SIG, - TERMINATE_SIG, - IGNORE_SIG, - MAX_SIG -}; +$declare ${Shared} -extern QHsm * const the_sm; /* opaque pointer to the test SM */ - -$declare${HSMs::QHsmTst_ctor} - -/* BSP functions to dispaly a message and exit */ -void BSP_display(char const *msg); -void BSP_exit(void); - -#endif /* QHSMTST_H */ - +#endif // QHSMTST_H_ - #include "qpc.h" -#include "qhsmtst.h" + #include "qpc.h" // QP/C framework +#include "qhsmtst.h" // this application -$declare${HSMs::QHsmTst} - -static QHsmTst l_sm; /* the only instance of the QHsmTst class */ - -/* global-scope definitions ---------------------------------------*/ -QHsm * const the_sm = &l_sm.super; /* the opaque pointer */ - -$define${HSMs::QHsmTst_ctor} -$define${HSMs::QHsmTst} - +$declare ${SMs::QHsmTst} +$define ${Shared::the_sm} +$define ${Shared::QHsmTst_ctor} +$define ${SMs::QHsmTst} diff --git a/examples/workstation/qhsmtst/qhsmtst.sln b/examples/posix-win32/qhsmtst/qhsmtst.sln similarity index 77% rename from examples/workstation/qhsmtst/qhsmtst.sln rename to examples/posix-win32/qhsmtst/qhsmtst.sln index b2046c0b..d169cb2b 100644 --- a/examples/workstation/qhsmtst/qhsmtst.sln +++ b/examples/posix-win32/qhsmtst/qhsmtst.sln @@ -1,7 +1,6 @@ - Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Express 2013 for Windows Desktop -VisualStudioVersion = 12.0.21005.1 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.33130.400 MinimumVisualStudioVersion = 10.0.40219.1 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "qhsmtst", "qhsmtst.vcxproj", "{8CC465F7-872E-4D03-B93C-1B64858B4E11}" EndProject @@ -9,17 +8,17 @@ Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Win32 = Debug|Win32 Release|Win32 = Release|Win32 - QSpy|Win32 = QSpy|Win32 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {8CC465F7-872E-4D03-B93C-1B64858B4E11}.Debug|Win32.ActiveCfg = Debug|Win32 {8CC465F7-872E-4D03-B93C-1B64858B4E11}.Debug|Win32.Build.0 = Debug|Win32 {8CC465F7-872E-4D03-B93C-1B64858B4E11}.Release|Win32.ActiveCfg = Release|Win32 {8CC465F7-872E-4D03-B93C-1B64858B4E11}.Release|Win32.Build.0 = Release|Win32 - {8CC465F7-872E-4D03-B93C-1B64858B4E11}.QSpy|Win32.ActiveCfg = QSpy|Win32 - {8CC465F7-872E-4D03-B93C-1B64858B4E11}.QSpy|Win32.Build.0 = QSpy|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {1066B2D2-07E5-4609-BC24-168229758EE0} + EndGlobalSection EndGlobal diff --git a/examples/posix-win32/qhsmtst/qhsmtst.vcxproj b/examples/posix-win32/qhsmtst/qhsmtst.vcxproj new file mode 100644 index 00000000..375fd250 --- /dev/null +++ b/examples/posix-win32/qhsmtst/qhsmtst.vcxproj @@ -0,0 +1,120 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + {8CC465F7-872E-4D03-B93C-1B64858B4E11} + qhsmtst + Win32Proj + 10.0 + + + + Application + NotSet + true + v142 + + + Application + NotSet + v142 + + + + + + + + + + + + + <_ProjectFileVersion>10.0.40219.1 + $(SolutionDir)$(Configuration)\ + $(Configuration)\ + true + $(SolutionDir)$(Configuration)\ + $(Configuration)\ + false + + + + Disabled + .;../../../include;../../../ports/win32-dummy;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + false + + + Default + MultiThreaded + NotUsing + Level4 + ProgramDatabase + 4127 + Default + stdc11 + + + %(AdditionalDependencies) + %(AdditionalLibraryDirectories) + true + Console + MachineX86 + + + cmd /c "del $(OutDir)qstamp.obj" + + + + + MaxSpeed + true + .;../../../include;../../../ports/win32-dummy;%(AdditionalIncludeDirectories) + NDEBUG;WIN32;_CONSOLE;%(PreprocessorDefinitions) + false + + + Default + MultiThreaded + true + NotUsing + Level4 + ProgramDatabase + 4127 + + + %(AdditionalDependencies) + %(AdditionalLibraryDirectories) + true + Console + true + true + MachineX86 + + + cmd /c "del $(OutDir)qstamp.obj" + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/posix-win32/qhsmtst/qhsmtst.vcxproj.filters b/examples/posix-win32/qhsmtst/qhsmtst.vcxproj.filters new file mode 100644 index 00000000..09b06e64 --- /dev/null +++ b/examples/posix-win32/qhsmtst/qhsmtst.vcxproj.filters @@ -0,0 +1,19 @@ + + + + + + + QEP + + + + + + + + + {ee79d87d-043f-4f52-9525-2d3df056d571} + + + \ No newline at end of file diff --git a/examples/workstation/qmsmtst/Makefile b/examples/posix-win32/qmsmtst/Makefile similarity index 78% rename from examples/workstation/qmsmtst/Makefile rename to examples/posix-win32/qmsmtst/Makefile index 16338684..872005b4 100644 --- a/examples/workstation/qmsmtst/Makefile +++ b/examples/posix-win32/qmsmtst/Makefile @@ -1,7 +1,7 @@ ############################################################################## -# Product: Makefile for QP/C for Windows and POSIX *HOSTS* -# Last updated for version 7.2.0 -# Last updated on 2022-11-13 +# Product: Makefile for QEP/C for Windows and POSIX *HOSTS* +# Last updated for version 7.3.0 +# Last updated on 2023-09-02 # # Q u a n t u m L e a P s # ------------------------ @@ -36,14 +36,13 @@ # building configurations: Debug (default), Release, and Spy # make # make CONF=rel -# make CONF=spy # make clean # cleanup the build -# make CONF=spy clean # cleanup the build +# make CONF=rel clean # cleanup the build # # NOTE: # To use this Makefile on Windows, you will need the GNU make utility, which # is included in the QTools collection for Windows, see: -# http://sourceforge.net/projects/qpc/files/QTools/ +# https://github.com/QuantumLeaps/qtools # #----------------------------------------------------------------------------- @@ -56,16 +55,18 @@ PROJECT := qmsmtst # # list of all source directories used by this project -VPATH := . \ +VPATH := . # list of all include directories needed by this project -INCLUDES := -I. \ +INCLUDES := -I. # location of the QP/C framework (if not provided in an env. variable) ifeq ($(QPC),) QPC := ../../.. endif +QP_PORT_DIR := $(QPC)/ports/qep-only + #----------------------------------------------------------------------------- # project files: # @@ -73,7 +74,9 @@ endif # C source files... C_SRCS := \ main.c \ - qmsmtst.c + qmsmtst.c \ + qep_msm.c + # C++ source files... CPP_SRCS := @@ -89,56 +92,6 @@ ifeq (,$(CONF)) CONF := dbg endif -#----------------------------------------------------------------------------- -# add QP/C framework: -# -C_SRCS += \ - qep_hsm.c \ - qep_msm.c \ - qf_act.c \ - qf_actq.c \ - qf_defer.c \ - qf_dyn.c \ - qf_mem.c \ - qf_ps.c \ - qf_qact.c \ - qf_qeq.c \ - qf_qmact.c \ - qf_time.c \ - qf_port.c - -QS_SRCS := \ - qs.c \ - qs_64bit.c \ - qs_rx.c \ - qs_fp.c \ - qs_port.c - -ifeq ($(OS),Windows_NT) - -# NOTE: -# For Windows hosts, you can choose: -# - the single-threaded QP/C port (win32-qv) or -# - the multithreaded QP/C port (win32). -# -QP_PORT_DIR := $(QPC)/ports/win32-qv -#QP_PORT_DIR := $(QPC)/ports/win32 -LIBS += -lws2_32 - -else - -# NOTE: -# For POSIX hosts (Linux, MacOS), you can choose: -# - the single-threaded QP/C port (win32-qv) or -# - the multithreaded QP/C port (win32). -# -QP_PORT_DIR := $(QPC)/ports/posix-qv -#QP_PORT_DIR := $(QPC)/ports/posix - -LIBS += -lpthread - -endif - #============================================================================ # Typically you should not need to change anything below this line @@ -150,8 +103,8 @@ INCLUDES += -I$(QPC)/include -I$(QP_PORT_DIR) # # NOTE: # GNU toolset (MinGW) is included in the QTools collection for Windows, see: -# https://www.state-machine.com/qtools -# It is assumed that %QTOOLS%\bin directory is added to the PATH +# https://github.com/QuantumLeaps/qtools +# It is assumed that $(QTOOLS)/bin directory is added to the PATH # CC := gcc CPP := g++ @@ -191,19 +144,6 @@ CPPFLAGS = -c -O3 -fno-pie -std=c++11 -pedantic -Wall -Wextra \ else ifeq (spy, $(CONF)) # Spy configuration ................................ -BIN_DIR := build_spy - -C_SRCS += $(QS_SRCS) -VPATH += $(QPC)/src/qs - -# gcc options: -CFLAGS = -c -g -O -fno-pie -std=c11 -pedantic -Wall -Wextra -W \ - $(INCLUDES) $(DEFINES) -DQ_SPY - -CPPFLAGS = -c -g -O -fno-pie -std=c++11 -pedantic -Wall -Wextra \ - -fno-rtti -fno-exceptions \ - $(INCLUDES) $(DEFINES) -DQ_SPY - else # default Debug configuration ......................................... BIN_DIR := build @@ -232,6 +172,11 @@ C_DEPS_EXT := $(patsubst %.o,%.d, $(C_OBJS_EXT)) CPP_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(CPP_OBJS)) CPP_DEPS_EXT := $(patsubst %.o,%.d, $(CPP_OBJS_EXT)) +# create $(BIN_DIR) if it does not exist +ifeq ("$(wildcard $(BIN_DIR))","") +$(shell $(MKDIR) $(BIN_DIR)) +endif + #----------------------------------------------------------------------------- # rules # @@ -241,8 +186,7 @@ CPP_DEPS_EXT := $(patsubst %.o,%.d, $(CPP_OBJS_EXT)) all: $(TARGET_EXE) $(TARGET_EXE) : $(C_OBJS_EXT) $(CPP_OBJS_EXT) - $(CC) $(CFLAGS) $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o - $(LINK) $(LINKFLAGS) $(LIB_DIRS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) + $(LINK) $(LINKFLAGS) $(LIB_DIRS) -o $@ $^ $(LIBS) $(BIN_DIR)/%.d : %.c $(CC) -MM -MT $(@:.d=.o) $(CFLAGS) $< > $@ diff --git a/examples/posix-win32/qmsmtst/SM_of_QMsmTst.png b/examples/posix-win32/qmsmtst/SM_of_QMsmTst.png new file mode 100644 index 00000000..bafa6e18 Binary files /dev/null and b/examples/posix-win32/qmsmtst/SM_of_QMsmTst.png differ diff --git a/examples/workstation/qmsmtst/log.txt b/examples/posix-win32/qmsmtst/log.txt similarity index 97% rename from examples/workstation/qmsmtst/log.txt rename to examples/posix-win32/qmsmtst/log.txt index d60e7f3a..2a735af7 100644 --- a/examples/workstation/qmsmtst/log.txt +++ b/examples/posix-win32/qmsmtst/log.txt @@ -1,4 +1,4 @@ -QMsmTst example, QP 6.9.4 +QMsmTst example, QP 7.3.0 top-INIT;s-ENTRY;s2-ENTRY;s2-INIT;s21-ENTRY;s211-ENTRY; A:s21-A;s211-EXIT;s21-EXIT;s21-ENTRY;s21-INIT;s211-ENTRY; B:s21-B;s211-EXIT;s211-ENTRY; diff --git a/examples/posix-win32/qmsmtst/main.c b/examples/posix-win32/qmsmtst/main.c new file mode 100644 index 00000000..baadd4b8 --- /dev/null +++ b/examples/posix-win32/qmsmtst/main.c @@ -0,0 +1,147 @@ +//============================================================================ +// Product: QMsmTst Example +// Last updated for version 7.3.0 +// Last updated on 2023-06-30 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// This program is open source software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Alternatively, this program may be distributed and modified under the +// terms of Quantum Leaps commercial licenses, which expressly supersede +// the GNU General Public License and are specifically designed for +// licensees interested in retaining the proprietary status of their code. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Contact information: +// +// +//============================================================================ +#include "qpc.h" // QP/C framework +#include "qmsmtst.h" // QMsmTst state machine + +#include "safe_std.h" // portable "safe" / facilities +#include // for exit() + +Q_DEFINE_THIS_FILE + +// local objects ----------------------------------------------------------- +static FILE *l_outFile = (FILE *)0; +static void dispatch(QSignal sig); + +//............................................................................ +int main(int argc, char *argv[]) { + + QMsmTst_ctor(); // instantiate the QMsmTst object + + if (argc > 1) { // file name provided? + FOPEN_S(l_outFile, argv[1], "w"); + } + + if (l_outFile == (FILE *)0) { // interactive version? + l_outFile = stdout; // use the stdout as the output file + + PRINTF_S("QMsmTst example, built on %s at %s,\n" + "QP: %s.\nEnter x or X to quit...\n", + __DATE__, __TIME__, QP_VERSION_STR); + + QASM_INIT(the_sm, (void *)0, 0U); // the top-most initial tran. + + for (;;) { // event loop + PRINTF_S("\n%s", ">>>"); + char inp[4]; + scanf("%1s", inp); // input the event + + QEvt e = QEVT_INITIALIZER(0U); + if ('a' <= inp[0] && inp[0] <= 'i') { // in range? + e.sig = (QSignal)(inp[0] - 'a' + A_SIG); + } + else if ('A' <= inp[0] && inp[0] <= 'I') { // in range? + e.sig = (QSignal)(inp[0] - 'A' + A_SIG); + } + else if ((inp[0] == 'x') || (inp[0] == 'X')) { // x or X? + e.sig = TERMINATE_SIG; // terminate the interactive test + } + else { + e.sig = IGNORE_SIG; + } + + QASM_DISPATCH(the_sm, &e, 0U); // dispatch the event + } + } + else { // batch version + PRINTF_S("QMsmTst example, built on %s at %s, QP %s\n" + "output saved to %s\n", + __DATE__, __TIME__, QP_VERSION_STR, + argv[1]); + + FPRINTF_S(l_outFile, "QMsmTst example, QP %s\n", + QP_VERSION_STR); + + QASM_INIT(the_sm, (void *)0, 0U); // the top-most initial tran. + + // testing of dynamic transitions... + dispatch(A_SIG); + dispatch(B_SIG); + dispatch(D_SIG); + dispatch(E_SIG); + dispatch(I_SIG); + dispatch(F_SIG); + dispatch(I_SIG); + dispatch(I_SIG); + dispatch(F_SIG); + dispatch(A_SIG); + dispatch(B_SIG); + dispatch(D_SIG); + dispatch(D_SIG); + dispatch(E_SIG); + dispatch(G_SIG); + dispatch(H_SIG); + dispatch(H_SIG); + dispatch(C_SIG); + dispatch(G_SIG); + dispatch(C_SIG); + dispatch(C_SIG); + + fclose(l_outFile); + } + + return 0; +} +//............................................................................ +Q_NORETURN Q_onError(char const * const module, int_t const id) { + FPRINTF_S(stderr, "ERROR in %s:%d", module, id); + exit(-1); +} +//............................................................................ +void BSP_display(char const *msg) { + FPRINTF_S(l_outFile, "%s", msg); +} +//............................................................................ +void BSP_terminate(int16_t const result) { + PRINTF_S("\n%s\n", "Bye, Bye!"); + exit(result); +} +//............................................................................ +static void dispatch(QSignal sig) { + QEvt e = QEVT_INITIALIZER(0U); + Q_REQUIRE((A_SIG <= sig) && (sig <= I_SIG)); + e.sig = sig; + FPRINTF_S(l_outFile, "\n%c:", 'A' + sig - A_SIG); + QASM_DISPATCH(the_sm, &e, 0U); // dispatch the event +} + diff --git a/examples/posix-win32/qmsmtst/qmsmtst.c b/examples/posix-win32/qmsmtst/qmsmtst.c new file mode 100644 index 00000000..e9daa9b5 --- /dev/null +++ b/examples/posix-win32/qmsmtst/qmsmtst.c @@ -0,0 +1,734 @@ +//$file${.::qmsmtst.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// +// Model: qmsmtst.qm +// File: ${.::qmsmtst.c} +// +// This code has been generated by QM 5.3.0 . +// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. +// +// SPDX-License-Identifier: GPL-3.0-or-later +// +// This generated code is open source software: you can redistribute it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation. +// +// This code is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// NOTE: +// Alternatively, this generated code may be distributed under the terms +// of Quantum Leaps commercial licenses, which expressly supersede the GNU +// General Public License and are specifically designed for licensees +// interested in retaining the proprietary status of their code. +// +// Contact information: +// +// +// +//$endhead${.::qmsmtst.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +#include "qpc.h" // QP/C framework +#include "qmsmtst.h" // this application + +//$declare${SMs::QMsmTst} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${SMs::QMsmTst} ............................................................ +typedef struct QMsmTst { +// protected: + QMsm super; + +// private: + uint8_t foo; + +// public: +} QMsmTst; +extern QMsmTst QMsmTst_inst; + +// protected: +static QState QMsmTst_initial(QMsmTst * const me, void const * const par); +static QState QMsmTst_s (QMsmTst * const me, QEvt const * const e); +static QState QMsmTst_s_e(QMsmTst * const me); +static QState QMsmTst_s_x(QMsmTst * const me); +static QState QMsmTst_s_i(QMsmTst * const me); +static QMState const QMsmTst_s_s = { + QM_STATE_NULL, // superstate (top) + Q_STATE_CAST(&QMsmTst_s), + Q_ACTION_CAST(&QMsmTst_s_e), + Q_ACTION_CAST(&QMsmTst_s_x), + Q_ACTION_CAST(&QMsmTst_s_i) +}; +static QState QMsmTst_s1 (QMsmTst * const me, QEvt const * const e); +static QState QMsmTst_s1_e(QMsmTst * const me); +static QState QMsmTst_s1_x(QMsmTst * const me); +static QState QMsmTst_s1_i(QMsmTst * const me); +static QMState const QMsmTst_s1_s = { + &QMsmTst_s_s, // superstate + Q_STATE_CAST(&QMsmTst_s1), + Q_ACTION_CAST(&QMsmTst_s1_e), + Q_ACTION_CAST(&QMsmTst_s1_x), + Q_ACTION_CAST(&QMsmTst_s1_i) +}; +static QState QMsmTst_s11 (QMsmTst * const me, QEvt const * const e); +static QState QMsmTst_s11_e(QMsmTst * const me); +static QState QMsmTst_s11_x(QMsmTst * const me); +static QMState const QMsmTst_s11_s = { + &QMsmTst_s1_s, // superstate + Q_STATE_CAST(&QMsmTst_s11), + Q_ACTION_CAST(&QMsmTst_s11_e), + Q_ACTION_CAST(&QMsmTst_s11_x), + Q_ACTION_NULL // no initial tran. +}; +static QState QMsmTst_s2 (QMsmTst * const me, QEvt const * const e); +static QState QMsmTst_s2_e(QMsmTst * const me); +static QState QMsmTst_s2_x(QMsmTst * const me); +static QState QMsmTst_s2_i(QMsmTst * const me); +static QMState const QMsmTst_s2_s = { + &QMsmTst_s_s, // superstate + Q_STATE_CAST(&QMsmTst_s2), + Q_ACTION_CAST(&QMsmTst_s2_e), + Q_ACTION_CAST(&QMsmTst_s2_x), + Q_ACTION_CAST(&QMsmTst_s2_i) +}; +static QState QMsmTst_s21 (QMsmTst * const me, QEvt const * const e); +static QState QMsmTst_s21_e(QMsmTst * const me); +static QState QMsmTst_s21_x(QMsmTst * const me); +static QState QMsmTst_s21_i(QMsmTst * const me); +static QMState const QMsmTst_s21_s = { + &QMsmTst_s2_s, // superstate + Q_STATE_CAST(&QMsmTst_s21), + Q_ACTION_CAST(&QMsmTst_s21_e), + Q_ACTION_CAST(&QMsmTst_s21_x), + Q_ACTION_CAST(&QMsmTst_s21_i) +}; +static QState QMsmTst_s211 (QMsmTst * const me, QEvt const * const e); +static QState QMsmTst_s211_e(QMsmTst * const me); +static QState QMsmTst_s211_x(QMsmTst * const me); +static QMState const QMsmTst_s211_s = { + &QMsmTst_s21_s, // superstate + Q_STATE_CAST(&QMsmTst_s211), + Q_ACTION_CAST(&QMsmTst_s211_e), + Q_ACTION_CAST(&QMsmTst_s211_x), + Q_ACTION_NULL // no initial tran. +}; +//$enddecl${SMs::QMsmTst} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +//$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// Check for the minimum required QP version +#if (QP_VERSION < 730U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) +#error qpc version 7.3.0 or higher required +#endif +//$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +//$define${Shared::the_sm} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${Shared::the_sm} .......................................................... +QAsm * const the_sm = &QMsmTst_inst.super.super; +//$enddef${Shared::the_sm} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +//$define${Shared::QMsmTst_ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${Shared::QMsmTst_ctor} .................................................... +void QMsmTst_ctor(void) { + QMsmTst *me = &QMsmTst_inst; + QMsm_ctor(&me->super, Q_STATE_CAST(&QMsmTst_initial)); +} +//$enddef${Shared::QMsmTst_ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +//$define${SMs::QMsmTst} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${SMs::QMsmTst} ............................................................ +QMsmTst QMsmTst_inst; + +//${SMs::QMsmTst::SM} ........................................................ +static QState QMsmTst_initial(QMsmTst * const me, void const * const par) { + static struct { + QMState const *target; + QActionHandler act[4]; + } const tatbl_ = { // tran-action table + &QMsmTst_s2_s, // target state + { + Q_ACTION_CAST(&QMsmTst_s_e), // entry + Q_ACTION_CAST(&QMsmTst_s2_e), // entry + Q_ACTION_CAST(&QMsmTst_s2_i), // initial tran. + Q_ACTION_NULL // zero terminator + } + }; + //${SMs::QMsmTst::SM::initial} + Q_UNUSED_PAR(par); + me->foo = 0U; + BSP_display("top-INIT;"); + + QS_SIG_DICTIONARY(A_SIG, (void *)0); + QS_SIG_DICTIONARY(B_SIG, (void *)0); + QS_SIG_DICTIONARY(C_SIG, (void *)0); + QS_SIG_DICTIONARY(D_SIG, (void *)0); + QS_SIG_DICTIONARY(E_SIG, (void *)0); + QS_SIG_DICTIONARY(F_SIG, (void *)0); + QS_SIG_DICTIONARY(G_SIG, (void *)0); + QS_SIG_DICTIONARY(H_SIG, (void *)0); + QS_SIG_DICTIONARY(I_SIG, (void *)0); + QS_SIG_DICTIONARY(IGNORE_SIG, (void *)0); + QS_SIG_DICTIONARY(TERMINATE_SIG, (void *)0); + + QS_FUN_DICTIONARY(&QMsmTst_s); + QS_FUN_DICTIONARY(&QMsmTst_s1); + QS_FUN_DICTIONARY(&QMsmTst_s11); + QS_FUN_DICTIONARY(&QMsmTst_s2); + QS_FUN_DICTIONARY(&QMsmTst_s21); + QS_FUN_DICTIONARY(&QMsmTst_s211); + + return QM_TRAN_INIT(&tatbl_); +} + +//${SMs::QMsmTst::SM::s} ..................................................... +//${SMs::QMsmTst::SM::s} +static QState QMsmTst_s_e(QMsmTst * const me) { + BSP_display("s-ENTRY;"); + Q_UNUSED_PAR(me); + return QM_ENTRY(&QMsmTst_s_s); +} +//${SMs::QMsmTst::SM::s} +static QState QMsmTst_s_x(QMsmTst * const me) { + BSP_display("s-EXIT;"); + (void)me; // unused parameter + return QM_EXIT(&QMsmTst_s_s); +} +//${SMs::QMsmTst::SM::s::initial} +static QState QMsmTst_s_i(QMsmTst * const me) { + static struct { + QMState const *target; + QActionHandler act[3]; + } const tatbl_ = { // tran-action table + &QMsmTst_s11_s, // target state + { + Q_ACTION_CAST(&QMsmTst_s1_e), // entry + Q_ACTION_CAST(&QMsmTst_s11_e), // entry + Q_ACTION_NULL // zero terminator + } + }; + //${SMs::QMsmTst::SM::s::initial} + BSP_display("s-INIT;"); + return QM_TRAN_INIT(&tatbl_); +} +//${SMs::QMsmTst::SM::s} +static QState QMsmTst_s(QMsmTst * const me, QEvt const * const e) { + QState status_; + switch (e->sig) { + //${SMs::QMsmTst::SM::s::I} + case I_SIG: { + //${SMs::QMsmTst::SM::s::I::[me->foo]} + if (me->foo) { + me->foo = 0U; + BSP_display("s-I;"); + status_ = QM_HANDLED(); + } + else { + status_ = QM_UNHANDLED(); + } + break; + } + //${SMs::QMsmTst::SM::s::E} + case E_SIG: { + static struct { + QMState const *target; + QActionHandler act[3]; + } const tatbl_ = { // tran-action table + &QMsmTst_s11_s, // target state + { + Q_ACTION_CAST(&QMsmTst_s1_e), // entry + Q_ACTION_CAST(&QMsmTst_s11_e), // entry + Q_ACTION_NULL // zero terminator + } + }; + BSP_display("s-E;"); + status_ = QM_TRAN(&tatbl_); + break; + } + //${SMs::QMsmTst::SM::s::TERMINATE} + case TERMINATE_SIG: { + BSP_terminate(0); + status_ = QM_HANDLED(); + break; + } + default: { + status_ = QM_SUPER(); + break; + } + } + Q_UNUSED_PAR(me); + return status_; +} + +//${SMs::QMsmTst::SM::s::s1} ................................................. +//${SMs::QMsmTst::SM::s::s1} +static QState QMsmTst_s1_e(QMsmTst * const me) { + BSP_display("s1-ENTRY;"); + Q_UNUSED_PAR(me); + return QM_ENTRY(&QMsmTst_s1_s); +} +//${SMs::QMsmTst::SM::s::s1} +static QState QMsmTst_s1_x(QMsmTst * const me) { + BSP_display("s1-EXIT;"); + (void)me; // unused parameter + return QM_EXIT(&QMsmTst_s1_s); +} +//${SMs::QMsmTst::SM::s::s1::initial} +static QState QMsmTst_s1_i(QMsmTst * const me) { + static struct { + QMState const *target; + QActionHandler act[2]; + } const tatbl_ = { // tran-action table + &QMsmTst_s11_s, // target state + { + Q_ACTION_CAST(&QMsmTst_s11_e), // entry + Q_ACTION_NULL // zero terminator + } + }; + //${SMs::QMsmTst::SM::s::s1::initial} + BSP_display("s1-INIT;"); + return QM_TRAN_INIT(&tatbl_); +} +//${SMs::QMsmTst::SM::s::s1} +static QState QMsmTst_s1(QMsmTst * const me, QEvt const * const e) { + QState status_; + switch (e->sig) { + //${SMs::QMsmTst::SM::s::s1::I} + case I_SIG: { + BSP_display("s1-I;"); + status_ = QM_HANDLED(); + break; + } + //${SMs::QMsmTst::SM::s::s1::D} + case D_SIG: { + //${SMs::QMsmTst::SM::s::s1::D::[!me->foo]} + if (!me->foo) { + static struct { + QMState const *target; + QActionHandler act[3]; + } const tatbl_ = { // tran-action table + &QMsmTst_s_s, // target state + { + Q_ACTION_CAST(&QMsmTst_s1_x), // exit + Q_ACTION_CAST(&QMsmTst_s_i), // initial tran. + Q_ACTION_NULL // zero terminator + } + }; + me->foo = 1U; + BSP_display("s1-D;"); + status_ = QM_TRAN(&tatbl_); + } + else { + status_ = QM_UNHANDLED(); + } + break; + } + //${SMs::QMsmTst::SM::s::s1::A} + case A_SIG: { + static struct { + QMState const *target; + QActionHandler act[4]; + } const tatbl_ = { // tran-action table + &QMsmTst_s1_s, // target state + { + Q_ACTION_CAST(&QMsmTst_s1_x), // exit + Q_ACTION_CAST(&QMsmTst_s1_e), // entry + Q_ACTION_CAST(&QMsmTst_s1_i), // initial tran. + Q_ACTION_NULL // zero terminator + } + }; + BSP_display("s1-A;"); + status_ = QM_TRAN(&tatbl_); + break; + } + //${SMs::QMsmTst::SM::s::s1::B} + case B_SIG: { + static struct { + QMState const *target; + QActionHandler act[2]; + } const tatbl_ = { // tran-action table + &QMsmTst_s11_s, // target state + { + Q_ACTION_CAST(&QMsmTst_s11_e), // entry + Q_ACTION_NULL // zero terminator + } + }; + BSP_display("s1-B;"); + status_ = QM_TRAN(&tatbl_); + break; + } + //${SMs::QMsmTst::SM::s::s1::F} + case F_SIG: { + static struct { + QMState const *target; + QActionHandler act[5]; + } const tatbl_ = { // tran-action table + &QMsmTst_s211_s, // target state + { + Q_ACTION_CAST(&QMsmTst_s1_x), // exit + Q_ACTION_CAST(&QMsmTst_s2_e), // entry + Q_ACTION_CAST(&QMsmTst_s21_e), // entry + Q_ACTION_CAST(&QMsmTst_s211_e), // entry + Q_ACTION_NULL // zero terminator + } + }; + BSP_display("s1-F;"); + status_ = QM_TRAN(&tatbl_); + break; + } + //${SMs::QMsmTst::SM::s::s1::C} + case C_SIG: { + static struct { + QMState const *target; + QActionHandler act[4]; + } const tatbl_ = { // tran-action table + &QMsmTst_s2_s, // target state + { + Q_ACTION_CAST(&QMsmTst_s1_x), // exit + Q_ACTION_CAST(&QMsmTst_s2_e), // entry + Q_ACTION_CAST(&QMsmTst_s2_i), // initial tran. + Q_ACTION_NULL // zero terminator + } + }; + BSP_display("s1-C;"); + status_ = QM_TRAN(&tatbl_); + break; + } + default: { + status_ = QM_SUPER(); + break; + } + } + return status_; +} + +//${SMs::QMsmTst::SM::s::s1::s11} ............................................ +//${SMs::QMsmTst::SM::s::s1::s11} +static QState QMsmTst_s11_e(QMsmTst * const me) { + BSP_display("s11-ENTRY;"); + Q_UNUSED_PAR(me); + return QM_ENTRY(&QMsmTst_s11_s); +} +//${SMs::QMsmTst::SM::s::s1::s11} +static QState QMsmTst_s11_x(QMsmTst * const me) { + BSP_display("s11-EXIT;"); + (void)me; // unused parameter + return QM_EXIT(&QMsmTst_s11_s); +} +//${SMs::QMsmTst::SM::s::s1::s11} +static QState QMsmTst_s11(QMsmTst * const me, QEvt const * const e) { + QState status_; + switch (e->sig) { + //${SMs::QMsmTst::SM::s::s1::s11::H} + case H_SIG: { + static struct { + QMState const *target; + QActionHandler act[4]; + } const tatbl_ = { // tran-action table + &QMsmTst_s_s, // target state + { + Q_ACTION_CAST(&QMsmTst_s11_x), // exit + Q_ACTION_CAST(&QMsmTst_s1_x), // exit + Q_ACTION_CAST(&QMsmTst_s_i), // initial tran. + Q_ACTION_NULL // zero terminator + } + }; + BSP_display("s11-H;"); + status_ = QM_TRAN(&tatbl_); + break; + } + //${SMs::QMsmTst::SM::s::s1::s11::D} + case D_SIG: { + //${SMs::QMsmTst::SM::s::s1::s11::D::[me->foo]} + if (me->foo) { + static struct { + QMState const *target; + QActionHandler act[3]; + } const tatbl_ = { // tran-action table + &QMsmTst_s1_s, // target state + { + Q_ACTION_CAST(&QMsmTst_s11_x), // exit + Q_ACTION_CAST(&QMsmTst_s1_i), // initial tran. + Q_ACTION_NULL // zero terminator + } + }; + me->foo = 0U; + BSP_display("s11-D;"); + status_ = QM_TRAN(&tatbl_); + } + else { + status_ = QM_UNHANDLED(); + } + break; + } + //${SMs::QMsmTst::SM::s::s1::s11::G} + case G_SIG: { + static struct { + QMState const *target; + QActionHandler act[6]; + } const tatbl_ = { // tran-action table + &QMsmTst_s211_s, // target state + { + Q_ACTION_CAST(&QMsmTst_s11_x), // exit + Q_ACTION_CAST(&QMsmTst_s1_x), // exit + Q_ACTION_CAST(&QMsmTst_s2_e), // entry + Q_ACTION_CAST(&QMsmTst_s21_e), // entry + Q_ACTION_CAST(&QMsmTst_s211_e), // entry + Q_ACTION_NULL // zero terminator + } + }; + BSP_display("s11-G;"); + status_ = QM_TRAN(&tatbl_); + break; + } + default: { + status_ = QM_SUPER(); + break; + } + } + return status_; +} + +//${SMs::QMsmTst::SM::s::s2} ................................................. +//${SMs::QMsmTst::SM::s::s2} +static QState QMsmTst_s2_e(QMsmTst * const me) { + BSP_display("s2-ENTRY;"); + Q_UNUSED_PAR(me); + return QM_ENTRY(&QMsmTst_s2_s); +} +//${SMs::QMsmTst::SM::s::s2} +static QState QMsmTst_s2_x(QMsmTst * const me) { + BSP_display("s2-EXIT;"); + (void)me; // unused parameter + return QM_EXIT(&QMsmTst_s2_s); +} +//${SMs::QMsmTst::SM::s::s2::initial} +static QState QMsmTst_s2_i(QMsmTst * const me) { + static struct { + QMState const *target; + QActionHandler act[3]; + } const tatbl_ = { // tran-action table + &QMsmTst_s211_s, // target state + { + Q_ACTION_CAST(&QMsmTst_s21_e), // entry + Q_ACTION_CAST(&QMsmTst_s211_e), // entry + Q_ACTION_NULL // zero terminator + } + }; + //${SMs::QMsmTst::SM::s::s2::initial} + BSP_display("s2-INIT;"); + return QM_TRAN_INIT(&tatbl_); +} +//${SMs::QMsmTst::SM::s::s2} +static QState QMsmTst_s2(QMsmTst * const me, QEvt const * const e) { + QState status_; + switch (e->sig) { + //${SMs::QMsmTst::SM::s::s2::I} + case I_SIG: { + //${SMs::QMsmTst::SM::s::s2::I::[!me->foo]} + if (!me->foo) { + me->foo = 1U; + BSP_display("s2-I;"); + status_ = QM_HANDLED(); + } + else { + status_ = QM_UNHANDLED(); + } + break; + } + //${SMs::QMsmTst::SM::s::s2::F} + case F_SIG: { + static struct { + QMState const *target; + QActionHandler act[4]; + } const tatbl_ = { // tran-action table + &QMsmTst_s11_s, // target state + { + Q_ACTION_CAST(&QMsmTst_s2_x), // exit + Q_ACTION_CAST(&QMsmTst_s1_e), // entry + Q_ACTION_CAST(&QMsmTst_s11_e), // entry + Q_ACTION_NULL // zero terminator + } + }; + BSP_display("s2-F;"); + status_ = QM_TRAN(&tatbl_); + break; + } + //${SMs::QMsmTst::SM::s::s2::C} + case C_SIG: { + static struct { + QMState const *target; + QActionHandler act[4]; + } const tatbl_ = { // tran-action table + &QMsmTst_s1_s, // target state + { + Q_ACTION_CAST(&QMsmTst_s2_x), // exit + Q_ACTION_CAST(&QMsmTst_s1_e), // entry + Q_ACTION_CAST(&QMsmTst_s1_i), // initial tran. + Q_ACTION_NULL // zero terminator + } + }; + BSP_display("s2-C;"); + status_ = QM_TRAN(&tatbl_); + break; + } + default: { + status_ = QM_SUPER(); + break; + } + } + return status_; +} + +//${SMs::QMsmTst::SM::s::s2::s21} ............................................ +//${SMs::QMsmTst::SM::s::s2::s21} +static QState QMsmTst_s21_e(QMsmTst * const me) { + BSP_display("s21-ENTRY;"); + Q_UNUSED_PAR(me); + return QM_ENTRY(&QMsmTst_s21_s); +} +//${SMs::QMsmTst::SM::s::s2::s21} +static QState QMsmTst_s21_x(QMsmTst * const me) { + BSP_display("s21-EXIT;"); + (void)me; // unused parameter + return QM_EXIT(&QMsmTst_s21_s); +} +//${SMs::QMsmTst::SM::s::s2::s21::initial} +static QState QMsmTst_s21_i(QMsmTst * const me) { + static struct { + QMState const *target; + QActionHandler act[2]; + } const tatbl_ = { // tran-action table + &QMsmTst_s211_s, // target state + { + Q_ACTION_CAST(&QMsmTst_s211_e), // entry + Q_ACTION_NULL // zero terminator + } + }; + //${SMs::QMsmTst::SM::s::s2::s21::initial} + BSP_display("s21-INIT;"); + return QM_TRAN_INIT(&tatbl_); +} +//${SMs::QMsmTst::SM::s::s2::s21} +static QState QMsmTst_s21(QMsmTst * const me, QEvt const * const e) { + QState status_; + switch (e->sig) { + //${SMs::QMsmTst::SM::s::s2::s21::G} + case G_SIG: { + static struct { + QMState const *target; + QActionHandler act[5]; + } const tatbl_ = { // tran-action table + &QMsmTst_s1_s, // target state + { + Q_ACTION_CAST(&QMsmTst_s21_x), // exit + Q_ACTION_CAST(&QMsmTst_s2_x), // exit + Q_ACTION_CAST(&QMsmTst_s1_e), // entry + Q_ACTION_CAST(&QMsmTst_s1_i), // initial tran. + Q_ACTION_NULL // zero terminator + } + }; + BSP_display("s21-G;"); + status_ = QM_TRAN(&tatbl_); + break; + } + //${SMs::QMsmTst::SM::s::s2::s21::A} + case A_SIG: { + static struct { + QMState const *target; + QActionHandler act[4]; + } const tatbl_ = { // tran-action table + &QMsmTst_s21_s, // target state + { + Q_ACTION_CAST(&QMsmTst_s21_x), // exit + Q_ACTION_CAST(&QMsmTst_s21_e), // entry + Q_ACTION_CAST(&QMsmTst_s21_i), // initial tran. + Q_ACTION_NULL // zero terminator + } + }; + BSP_display("s21-A;"); + status_ = QM_TRAN(&tatbl_); + break; + } + //${SMs::QMsmTst::SM::s::s2::s21::B} + case B_SIG: { + static struct { + QMState const *target; + QActionHandler act[2]; + } const tatbl_ = { // tran-action table + &QMsmTst_s211_s, // target state + { + Q_ACTION_CAST(&QMsmTst_s211_e), // entry + Q_ACTION_NULL // zero terminator + } + }; + BSP_display("s21-B;"); + status_ = QM_TRAN(&tatbl_); + break; + } + default: { + status_ = QM_SUPER(); + break; + } + } + return status_; +} + +//${SMs::QMsmTst::SM::s::s2::s21::s211} ...................................... +//${SMs::QMsmTst::SM::s::s2::s21::s211} +static QState QMsmTst_s211_e(QMsmTst * const me) { + BSP_display("s211-ENTRY;"); + Q_UNUSED_PAR(me); + return QM_ENTRY(&QMsmTst_s211_s); +} +//${SMs::QMsmTst::SM::s::s2::s21::s211} +static QState QMsmTst_s211_x(QMsmTst * const me) { + BSP_display("s211-EXIT;"); + (void)me; // unused parameter + return QM_EXIT(&QMsmTst_s211_s); +} +//${SMs::QMsmTst::SM::s::s2::s21::s211} +static QState QMsmTst_s211(QMsmTst * const me, QEvt const * const e) { + QState status_; + switch (e->sig) { + //${SMs::QMsmTst::SM::s::s2::s21::s211::H} + case H_SIG: { + static struct { + QMState const *target; + QActionHandler act[5]; + } const tatbl_ = { // tran-action table + &QMsmTst_s_s, // target state + { + Q_ACTION_CAST(&QMsmTst_s211_x), // exit + Q_ACTION_CAST(&QMsmTst_s21_x), // exit + Q_ACTION_CAST(&QMsmTst_s2_x), // exit + Q_ACTION_CAST(&QMsmTst_s_i), // initial tran. + Q_ACTION_NULL // zero terminator + } + }; + BSP_display("s211-H;"); + status_ = QM_TRAN(&tatbl_); + break; + } + //${SMs::QMsmTst::SM::s::s2::s21::s211::D} + case D_SIG: { + static struct { + QMState const *target; + QActionHandler act[3]; + } const tatbl_ = { // tran-action table + &QMsmTst_s21_s, // target state + { + Q_ACTION_CAST(&QMsmTst_s211_x), // exit + Q_ACTION_CAST(&QMsmTst_s21_i), // initial tran. + Q_ACTION_NULL // zero terminator + } + }; + BSP_display("s211-D;"); + status_ = QM_TRAN(&tatbl_); + break; + } + default: { + status_ = QM_SUPER(); + break; + } + } + return status_; +} +//$enddef${SMs::QMsmTst} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/examples/posix-win32/qmsmtst/qmsmtst.h b/examples/posix-win32/qmsmtst/qmsmtst.h new file mode 100644 index 00000000..74f6b27b --- /dev/null +++ b/examples/posix-win32/qmsmtst/qmsmtst.h @@ -0,0 +1,65 @@ +//$file${.::qmsmtst.h} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// +// Model: qmsmtst.qm +// File: ${.::qmsmtst.h} +// +// This code has been generated by QM 5.3.0 . +// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. +// +// SPDX-License-Identifier: GPL-3.0-or-later +// +// This generated code is open source software: you can redistribute it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation. +// +// This code is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// NOTE: +// Alternatively, this generated code may be distributed under the terms +// of Quantum Leaps commercial licenses, which expressly supersede the GNU +// General Public License and are specifically designed for licensees +// interested in retaining the proprietary status of their code. +// +// Contact information: +// +// +// +//$endhead${.::qmsmtst.h} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +#ifndef QMSMTST_H_ +#define QMSMTST_H_ + +//$declare${Shared} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${Shared::QMsmTstSignals} .................................................. +enum QMsmTstSignals { + A_SIG = Q_USER_SIG, + B_SIG, + C_SIG, + D_SIG, + E_SIG, + F_SIG, + G_SIG, + H_SIG, + I_SIG, + TERMINATE_SIG, + IGNORE_SIG, + MAX_SIG +}; + +//${Shared::the_sm} .......................................................... +extern QAsm * const the_sm; + +//${Shared::QMsmTst_ctor} .................................................... +void QMsmTst_ctor(void); + +//${Shared::BSP_display} ..................................................... +void BSP_display(char const * msg); + +//${Shared::BSP_terminate} ................................................... +void BSP_terminate(int16_t const result); +//$enddecl${Shared} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +#endif // QMSMTST_H_ diff --git a/examples/workstation/qmsmtst/qmsmtst.qm b/examples/posix-win32/qmsmtst/qmsmtst.qm similarity index 82% rename from examples/workstation/qmsmtst/qmsmtst.qm rename to examples/posix-win32/qmsmtst/qmsmtst.qm index 7bf560bb..8a4eb465 100644 --- a/examples/workstation/qmsmtst/qmsmtst.qm +++ b/examples/posix-win32/qmsmtst/qmsmtst.qm @@ -1,8 +1,48 @@ - - QMsmTst is a QMsm state machine test based on the contrived state machine from Chapter 2 of the PSiCC2 book for testing all possible transition topologies with up to 4-levels of state nesting. + + QHsmTst is a contrived state machine from Chapter 2 of the PSiCC2 book for testing all possible transition topologies with up to 4-levels of state nesting. + + + + + { + A_SIG = Q_USER_SIG, + B_SIG, + C_SIG, + D_SIG, + E_SIG, + F_SIG, + G_SIG, + H_SIG, + I_SIG, + TERMINATE_SIG, + IGNORE_SIG, + MAX_SIG +}; + + + + opaque pointer to the test SM + = &QMsmTst_inst.super.super; + + + + QMsmTst *me = &QMsmTst_inst; +QMsm_ctor(&me->super, Q_STATE_CAST(&QMsmTst_initial)); + + + + + + + + + + + + @@ -10,13 +50,27 @@ Test active object + + - (void)par; /* unused parameter */ + Q_UNUSED_PAR(par); me->foo = 0U; -BSP_display("top-INIT;"); +BSP_display("top-INIT;"); + +QS_SIG_DICTIONARY(A_SIG, (void *)0); +QS_SIG_DICTIONARY(B_SIG, (void *)0); +QS_SIG_DICTIONARY(C_SIG, (void *)0); +QS_SIG_DICTIONARY(D_SIG, (void *)0); +QS_SIG_DICTIONARY(E_SIG, (void *)0); +QS_SIG_DICTIONARY(F_SIG, (void *)0); +QS_SIG_DICTIONARY(G_SIG, (void *)0); +QS_SIG_DICTIONARY(H_SIG, (void *)0); +QS_SIG_DICTIONARY(I_SIG, (void *)0); +QS_SIG_DICTIONARY(IGNORE_SIG, (void *)0); +QS_SIG_DICTIONARY(TERMINATE_SIG, (void *)0); @@ -56,7 +110,7 @@ BSP_display("s-I;"); - BSP_exit(); + BSP_terminate(0); @@ -278,60 +332,27 @@ BSP_display("s2-I;"); - - - QMsmTst *me = &l_sm; -QMsm_ctor(&me->super, Q_STATE_CAST(&QMsmTst_initial)); - - #ifndef QMSMTST_H -#define QMSMTST_H + #ifndef QMSMTST_H_ +#define QMSMTST_H_ -enum QMsmTstSignals { - A_SIG = Q_USER_SIG, - B_SIG, - C_SIG, - D_SIG, - E_SIG, - F_SIG, - G_SIG, - H_SIG, - I_SIG, - TERMINATE_SIG, - IGNORE_SIG, - MAX_SIG -}; +$declare ${Shared} -extern QHsm * const the_sm; /* opaque pointer to the test SM */ - -$declare${SMs::QMsmTst_ctor} - -/* BSP functions to dispaly a message and exit */ -void BSP_display(char const *msg); -void BSP_exit(void); - -#endif /* QMSMTST_H */ - +#endif // QMSMTST_H_ - #include "qpc.h" -#include "qmsmtst.h" + #include "qpc.h" // QP/C framework +#include "qmsmtst.h" // this application -$declare${SMs::QMsmTst} - -static QMsmTst l_sm; /* the only instance of the QMsmTst class */ - -/* global-scope definitions ---------------------------------------*/ -QHsm * const the_sm = &l_sm.super.super; /* the opaque pointer */ - -$define${SMs::QMsmTst_ctor} -$define${SMs::QMsmTst} - +$declare ${SMs::QMsmTst} +$define ${Shared::the_sm} +$define ${Shared::QMsmTst_ctor} +$define ${SMs::QMsmTst} diff --git a/examples/posix-win32/qmsmtst/qmsmtst.sln b/examples/posix-win32/qmsmtst/qmsmtst.sln new file mode 100644 index 00000000..f3b43635 --- /dev/null +++ b/examples/posix-win32/qmsmtst/qmsmtst.sln @@ -0,0 +1,24 @@ +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.33130.400 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "qmsmtst", "qmsmtst.vcxproj", "{8CC465F7-872E-4D03-B93C-1B64858B4E11}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {8CC465F7-872E-4D03-B93C-1B64858B4E11}.Debug|Win32.ActiveCfg = Debug|Win32 + {8CC465F7-872E-4D03-B93C-1B64858B4E11}.Debug|Win32.Build.0 = Debug|Win32 + {8CC465F7-872E-4D03-B93C-1B64858B4E11}.Release|Win32.ActiveCfg = Release|Win32 + {8CC465F7-872E-4D03-B93C-1B64858B4E11}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {1066B2D2-07E5-4609-BC24-168229758EE0} + EndGlobalSection +EndGlobal diff --git a/examples/posix-win32/qmsmtst/qmsmtst.vcxproj b/examples/posix-win32/qmsmtst/qmsmtst.vcxproj new file mode 100644 index 00000000..f6be1be9 --- /dev/null +++ b/examples/posix-win32/qmsmtst/qmsmtst.vcxproj @@ -0,0 +1,119 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + {8CC465F7-872E-4D03-B93C-1B64858B4E11} + qmsmtst + Win32Proj + 10.0 + + + + Application + NotSet + true + v142 + + + Application + NotSet + v142 + + + + + + + + + + + + + <_ProjectFileVersion>10.0.40219.1 + $(SolutionDir)$(Configuration)\ + $(Configuration)\ + true + $(SolutionDir)$(Configuration)\ + $(Configuration)\ + false + + + + Disabled + .;../../../include;../../../ports/win32-dummy;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + false + + + Default + MultiThreaded + NotUsing + Level4 + ProgramDatabase + 4127 + Default + stdc11 + + + %(AdditionalDependencies) + %(AdditionalLibraryDirectories) + true + Console + MachineX86 + + + cmd /c "del $(OutDir)qstamp.obj" + + + + + MaxSpeed + true + .;../../../include;../../../ports/win32-dummy;%(AdditionalIncludeDirectories) + NDEBUG;WIN32;_CONSOLE;%(PreprocessorDefinitions) + false + + + Default + MultiThreaded + true + NotUsing + Level4 + ProgramDatabase + 4127 + + + %(AdditionalDependencies) + %(AdditionalLibraryDirectories) + true + Console + true + true + MachineX86 + + + cmd /c "del $(OutDir)qstamp.obj" + + + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/posix-win32/qmsmtst/qmsmtst.vcxproj.filters b/examples/posix-win32/qmsmtst/qmsmtst.vcxproj.filters new file mode 100644 index 00000000..09c4889a --- /dev/null +++ b/examples/posix-win32/qmsmtst/qmsmtst.vcxproj.filters @@ -0,0 +1,18 @@ + + + + + + + QEP + + + + + + + + {ee79d87d-043f-4f52-9525-2d3df056d571} + + + \ No newline at end of file diff --git a/examples/workstation/reminder/Makefile b/examples/posix-win32/reminder/Makefile similarity index 99% rename from examples/workstation/reminder/Makefile rename to examples/posix-win32/reminder/Makefile index 13ca8d70..7c6d65ae 100644 --- a/examples/workstation/reminder/Makefile +++ b/examples/posix-win32/reminder/Makefile @@ -241,7 +241,7 @@ CPP_DEPS_EXT := $(patsubst %.o,%.d, $(CPP_OBJS_EXT)) all: $(TARGET_EXE) $(TARGET_EXE) : $(C_OBJS_EXT) $(CPP_OBJS_EXT) - $(CC) $(CFLAGS) $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o + $(CC) $(CFLAGS) $(QPC)/src/qs/qstamp.c -o $(BIN_DIR)/qstamp.o $(LINK) $(LINKFLAGS) $(LIB_DIRS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) $(BIN_DIR)/%.d : %.c diff --git a/examples/posix-win32/reminder/bsp.c b/examples/posix-win32/reminder/bsp.c new file mode 100644 index 00000000..fb0a02d4 --- /dev/null +++ b/examples/posix-win32/reminder/bsp.c @@ -0,0 +1,77 @@ +//============================================================================ +// Product: Console-based BSP, MinGW +// Last updated for version 5.6.0 +// Last updated on 2015-12-18 +// +// Q u a n t u m L e a P s +// --------------------------- +// innovating embedded systems +// +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// This program is open source software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Alternatively, this program may be distributed and modified under the +// terms of Quantum Leaps commercial licenses, which expressly supersede +// the GNU General Public License and are specifically designed for +// licensees interested in retaining the proprietary status of their code. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Contact information: +// +// +//============================================================================ +#include "qpc.h" +#include "bsp.h" + +#include "safe_std.h" // portable "safe" / facilities +#include + +//Q_DEFINE_THIS_FILE + +//............................................................................ +void BSP_init(int argc, char *argv[]) { + (void)argc; // unused parameter + (void)argv; // unused parameter +} +//............................................................................ +void QF_onStartup(void) { + QF_setTickRate(BSP_TICKS_PER_SEC, 30); // set the desired tick rate + QF_consoleSetup(); +} +//............................................................................ +void QF_onCleanup(void) { + PRINTF_S("\n%s\n", "Bye! Bye!"); + QF_consoleCleanup(); +} +//............................................................................ +void QF_onClockTick(void) { + QTIMEEVT_TICK_X(0U, &l_clock_tick); // perform the QF clock tick processing + + int ch = QF_consoleGetKey(); + if (ch != 0) { // any key pressed? + BSP_onKeyboardInput(ch); + } +} +//............................................................................ +Q_NORETURN Q_onError(char const * const module, int_t const id) { + FPRINTF_S(stderr, "ERROR in %s:%d", module, id); + QF_onCleanup(); + exit(-1); +} +//............................................................................ +void assert_failed(char const * const module, int_t const id); // prototype +void assert_failed(char const * const module, int_t const id) { + Q_onError(module, id); +} + diff --git a/examples/posix-win32/reminder/bsp.h b/examples/posix-win32/reminder/bsp.h new file mode 100644 index 00000000..9fa2f435 --- /dev/null +++ b/examples/posix-win32/reminder/bsp.h @@ -0,0 +1,42 @@ +//============================================================================ +// Product: Console-based BSP +// Last updated for version 5.4.2 +// Last updated on 2015-06-03 +// +// Q u a n t u m L e a P s +// --------------------------- +// innovating embedded systems +// +// Copyright (C) 2005 Quantum Leaps, www.state-machine.com. +// +// This program is open source software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Alternatively, this program may be distributed and modified under the +// terms of Quantum Leaps commercial licenses, which expressly supersede +// the GNU General Public License and are specifically designed for +// licensees interested in retaining the proprietary status of their code. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Contact information: +// Web: www.state-machine.com +// +//============================================================================ +#ifndef BSP_H_ +#define BSP_H_ + +#define BSP_TICKS_PER_SEC 100U + +void BSP_init(int argc, char *argv[]); +void BSP_onKeyboardInput(uint8_t key); // process the keyboard scan code + +#endif // BSP_H_ diff --git a/examples/posix-win32/reminder/reminder.c b/examples/posix-win32/reminder/reminder.c new file mode 100644 index 00000000..896a5d1a --- /dev/null +++ b/examples/posix-win32/reminder/reminder.c @@ -0,0 +1,249 @@ +//============================================================================ +// Product: Reminder state pattern example +// Last updated for version 7.3.0 +// Last updated on 2023-05-28 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// This program is open source software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Alternatively, this program may be distributed and modified under the +// terms of Quantum Leaps commercial licenses, which expressly supersede +// the GNU General Public License and are specifically designed for +// licensees interested in retaining the proprietary status of their code. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Contact information: +// +// +//============================================================================ +#include "qpc.h" +#include "bsp.h" + +#include "safe_std.h" // portable "safe" / facilities + +//Q_DEFINE_THIS_FILE + +//............................................................................ +enum SensorSignals { + TIMEOUT_SIG = Q_USER_SIG, // the periodic timeout signal + DATA_READY_SIG, // the invented reminder signal + TERMINATE_SIG // terminate the application +}; +//............................................................................ +typedef struct SensorTag { // the Sensor active object + QActive super; // inherit QActive + + QTimeEvt timeEvt; // private time event generator + uint16_t pollCtr; + uint16_t procCtr; +} Sensor; + + +void Sensor_ctor(Sensor * const me); + +// hierarchical state machine ... +static QState Sensor_initial (Sensor * const me, QEvt const * const e); +static QState Sensor_polling (Sensor * const me, QEvt const * const e); +static QState Sensor_processing(Sensor * const me, QEvt const * const e); +static QState Sensor_idle (Sensor * const me, QEvt const * const e); +static QState Sensor_busy (Sensor * const me, QEvt const * const e); +static QState Sensor_final (Sensor * const me, QEvt const * const e); + +//............................................................................ +void Sensor_ctor(Sensor * const me) { + QActive_ctor(&me->super, (QStateHandler)&Sensor_initial); + QTimeEvt_ctorX(&me->timeEvt, &me->super, TIMEOUT_SIG, 0U); +} + +// HSM definition ---------------------------------------------------------- +QState Sensor_initial(Sensor * const me, QEvt const * const e) { + (void)e; // unused parameter + + me->pollCtr = 0U; + me->procCtr = 0U; + + return Q_TRAN(&Sensor_polling); +} +//............................................................................ +QState Sensor_final(Sensor * const me, QEvt const * const e) { + QState status; + switch (e->sig) { + case Q_ENTRY_SIG: { + QF_stop(); // terminate the application + status = Q_HANDLED(); + break; + } + default: { + status = Q_SUPER(&QHsm_top); + break; + } + } + return status; +} +//............................................................................ +QState Sensor_polling(Sensor * const me, QEvt const * const e) { + QState status; + switch (e->sig) { + case Q_ENTRY_SIG: { + // periodic timeout in 1/2 second and every 1/2 second + QTimeEvt_armX(&me->timeEvt, + BSP_TICKS_PER_SEC/2, BSP_TICKS_PER_SEC/2); + status = Q_HANDLED(); + break; + } + case Q_EXIT_SIG: { + QTimeEvt_disarm(&me->timeEvt); + status = Q_HANDLED(); + break; + } + case Q_INIT_SIG: { + status = Q_TRAN(&Sensor_processing); + break; + } + case TIMEOUT_SIG: { + // NOTE: this constant event is statically pre-allocated. + // It can be posted/published as any other event. + // + static const QEvt reminderEvt = QEVT_INITIALIZER(DATA_READY_SIG); + + ++me->pollCtr; + PRINTF_S("polling %3d\n", me->pollCtr); + if ((me->pollCtr & 0x3U) == 0U) { // modulo 4 + QACTIVE_POST(&me->super, &reminderEvt, me); + } + status = Q_HANDLED(); + break; + } + case TERMINATE_SIG: { + status = Q_TRAN(&Sensor_final); + break; + } + default: { + status = Q_SUPER(&QHsm_top); + break; + } + } + return status; +} +//............................................................................ +QState Sensor_processing(Sensor * const me, QEvt const * const e) { + QState status; + switch (e->sig) { + case Q_INIT_SIG: { + status = Q_TRAN(&Sensor_idle); + break; + } + default: { + status = Q_SUPER(&Sensor_polling); + break; + } + } + return status; +} +//............................................................................ +QState Sensor_idle(Sensor * const me, QEvt const * const e) { + QState status; + switch (e->sig) { + case Q_ENTRY_SIG: { + PRINTF_S("%s\n", "idle-ENTRY;"); + status = Q_HANDLED(); + break; + } + case DATA_READY_SIG: { + status = Q_TRAN(&Sensor_busy); + break; + } + default: { + status = Q_SUPER(&Sensor_processing); + break; + } + } + return status; +} +//............................................................................ +QState Sensor_busy(Sensor * const me, QEvt const * const e) { + QState status; + switch (e->sig) { + case Q_ENTRY_SIG: { + PRINTF_S("%s\n", "busy-ENTRY;"); + status = Q_HANDLED(); + break; + } + case TIMEOUT_SIG: { + ++me->procCtr; + PRINTF_S("processing %3d\n", me->procCtr); + if ((me->procCtr & 0x1U) == 0U) { // modulo 2 + status = Q_TRAN(&Sensor_idle); + } + else { + status = Q_HANDLED(); + } + break; + } + default: { + status = Q_SUPER(&Sensor_processing); + break; + } + } + return status; +} + +// test harness ============================================================ + +// Local-scope objects ----------------------------------------------------- +static Sensor l_sensor; // the Sensor active object +static QEvt const *l_sensorQSto[10]; // Event queue storage for Sensor + +//............................................................................ +int main(int argc, char *argv[]) { + PRINTF_S("Reminder state pattern\nQP version: %s\n" + "Press ESC to quit...\n", + QP_VERSION_STR); + + BSP_init(argc, argv); // initialize the BSP + + QF_init(); // initialize the framework and the underlying RT kernel + + // publish-subscribe not used, no call to QActive_psInit() + // dynamic event allocation not used, no call to QF_poolInit() + + // instantiate and start the active objects... + Sensor_ctor(&l_sensor); + QACTIVE_START(&l_sensor.super, + 1U, + l_sensorQSto, Q_DIM(l_sensorQSto), + (void *)0, 0U, (QEvt *)0); + + return QF_run(); // run the QF application +} +//............................................................................ +void BSP_onKeyboardInput(uint8_t key) { + switch (key) { + case '\033': { // ESC pressed? + // NOTE: this immutable (const) event is statically pre-allocated. + // It can be posted/published as any other event. + // + static QEvt const terminateEvt = QEVT_INITIALIZER(TERMINATE_SIG); + QACTIVE_POST((QActive *)&l_sensor, &terminateEvt, (void *)0); + break; + } + default: { + break; + } + } +} diff --git a/examples/workstation/reminder2/Makefile b/examples/posix-win32/reminder2/Makefile similarity index 99% rename from examples/workstation/reminder2/Makefile rename to examples/posix-win32/reminder2/Makefile index fba8fcd5..24ea6745 100644 --- a/examples/workstation/reminder2/Makefile +++ b/examples/posix-win32/reminder2/Makefile @@ -241,7 +241,7 @@ CPP_DEPS_EXT := $(patsubst %.o,%.d, $(CPP_OBJS_EXT)) all: $(TARGET_EXE) $(TARGET_EXE) : $(C_OBJS_EXT) $(CPP_OBJS_EXT) - $(CC) $(CFLAGS) $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o + $(CC) $(CFLAGS) $(QPC)/src/qs/qstamp.c -o $(BIN_DIR)/qstamp.o $(LINK) $(LINKFLAGS) $(LIB_DIRS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) $(BIN_DIR)/%.d : %.c diff --git a/examples/posix-win32/reminder2/bsp.c b/examples/posix-win32/reminder2/bsp.c new file mode 100644 index 00000000..a32b6ccb --- /dev/null +++ b/examples/posix-win32/reminder2/bsp.c @@ -0,0 +1,77 @@ +//============================================================================ +// Product: Console-based BSP, MinGW +// Last updated for version 5.6.0 +// Last updated on 2015-12-18 +// +// Q u a n t u m L e a P s +// --------------------------- +// innovating embedded systems +// +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// This program is open source software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Alternatively, this program may be distributed and modified under the +// terms of Quantum Leaps commercial licenses, which expressly supersede +// the GNU General Public License and are specifically designed for +// licensees interested in retaining the proprietary status of their code. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Contact information: +// +// +//============================================================================ +#include "qpc.h" +#include "bsp.h" + +#include "safe_std.h" // portable "safe" / facilities +#include + +//Q_DEFINE_THIS_FILE + +//............................................................................ +void BSP_init(int argc, char *argv[]) { + (void)argc; // unused parameter + (void)argv; // unused parameter +} +//............................................................................ +void QF_onStartup(void) { + QF_setTickRate(BSP_TICKS_PER_SEC, 30); // set the desired tick rate + QF_consoleSetup(); +} +//............................................................................ +void QF_onCleanup(void) { + PRINTF_S("\n%s\n", "Bye! Bye!"); + QF_consoleCleanup(); +} +//............................................................................ +void QF_onClockTick(void) { + + QTIMEEVT_TICK_X(0U, &l_clock_tick); // QF clock tick processing + + int ch = QF_consoleGetKey(); + if (ch != 0) { // any key pressed? + BSP_onKeyboardInput(ch); + } +} +//............................................................................ +Q_NORETURN Q_onError(char const * const module, int_t const id) { + FPRINTF_S(stderr, "ERROR in %s:%d", module, id); + QF_onCleanup(); + exit(-1); +} +//............................................................................ +void assert_failed(char const * const module, int_t const id); // prototype +void assert_failed(char const * const module, int_t const id) { + Q_onError(module, id); +} diff --git a/examples/posix-win32/reminder2/bsp.h b/examples/posix-win32/reminder2/bsp.h new file mode 100644 index 00000000..9fa2f435 --- /dev/null +++ b/examples/posix-win32/reminder2/bsp.h @@ -0,0 +1,42 @@ +//============================================================================ +// Product: Console-based BSP +// Last updated for version 5.4.2 +// Last updated on 2015-06-03 +// +// Q u a n t u m L e a P s +// --------------------------- +// innovating embedded systems +// +// Copyright (C) 2005 Quantum Leaps, www.state-machine.com. +// +// This program is open source software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Alternatively, this program may be distributed and modified under the +// terms of Quantum Leaps commercial licenses, which expressly supersede +// the GNU General Public License and are specifically designed for +// licensees interested in retaining the proprietary status of their code. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Contact information: +// Web: www.state-machine.com +// +//============================================================================ +#ifndef BSP_H_ +#define BSP_H_ + +#define BSP_TICKS_PER_SEC 100U + +void BSP_init(int argc, char *argv[]); +void BSP_onKeyboardInput(uint8_t key); // process the keyboard scan code + +#endif // BSP_H_ diff --git a/examples/posix-win32/reminder2/reminder2.c b/examples/posix-win32/reminder2/reminder2.c new file mode 100644 index 00000000..8d3142df --- /dev/null +++ b/examples/posix-win32/reminder2/reminder2.c @@ -0,0 +1,238 @@ +//$file${.::reminder2.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// +// Model: reminder2.qm +// File: ${.::reminder2.c} +// +// This code has been generated by QM 5.3.0 . +// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. +// +// SPDX-License-Identifier: GPL-3.0-or-later +// +// This generated code is open source software: you can redistribute it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation. +// +// This code is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// NOTE: +// Alternatively, this generated code may be distributed under the terms +// of Quantum Leaps commercial licenses, which expressly supersede the GNU +// General Public License and are specifically designed for licensees +// interested in retaining the proprietary status of their code. +// +// Contact information: +// +// +// +//$endhead${.::reminder2.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +#include "qpc.h" +#include "bsp.h" + +#include "safe_std.h" // portable "safe" / facilities +#include + +//Q_DEFINE_THIS_FILE + +//.......................................................................... +enum ReminderSignals { + CRUNCH_SIG = Q_USER_SIG, // the invented reminder signal + ECHO_SIG, // check the responsiveness of the system + TERMINATE_SIG // terminate the application +}; + +//$declare${Events::ReminderEvt} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${Events::ReminderEvt} ..................................................... +typedef struct { +// protected: + QEvt super; + +// public: + + // the next iteration to perform + uint32_t iter; +} ReminderEvt; +//$enddecl${Events::ReminderEvt} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +//.......................................................................... +//$declare${Components::Cruncher} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${Components::Cruncher} .................................................... +typedef struct { +// protected: + QActive super; + +// private: + + // internal variable + double sum; +} Cruncher; + +// public: +static void Cruncher_ctor(Cruncher * const me); + +// protected: +static QState Cruncher_initial(Cruncher * const me, void const * const par); +static QState Cruncher_processing(Cruncher * const me, QEvt const * const e); +static QState Cruncher_final(Cruncher * const me, QEvt const * const e); +//$enddecl${Components::Cruncher} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +//$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// Check for the minimum required QP version +#if (QP_VERSION < 730U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) +#error qpc version 7.3.0 or higher required +#endif +//$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +//$define${Components::Cruncher} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${Components::Cruncher} .................................................... + +//${Components::Cruncher::ctor} .............................................. +static void Cruncher_ctor(Cruncher * const me) { + QActive_ctor(&me->super, Q_STATE_CAST(&Cruncher_initial)); +} + +//${Components::Cruncher::SM} ................................................ +static QState Cruncher_initial(Cruncher * const me, void const * const par) { + //${Components::Cruncher::SM::initial} + (void)par; // unused parameter + + QS_FUN_DICTIONARY(&Cruncher_processing); + QS_FUN_DICTIONARY(&Cruncher_final); + + return Q_TRAN(&Cruncher_processing); +} + +//${Components::Cruncher::SM::processing} .................................... +static QState Cruncher_processing(Cruncher * const me, QEvt const * const e) { + QState status_; + switch (e->sig) { + //${Components::Cruncher::SM::processing} + case Q_ENTRY_SIG: { + ReminderEvt *reminder = Q_NEW(ReminderEvt, CRUNCH_SIG); + reminder->iter = 0U; + QACTIVE_POST(&me->super, &reminder->super, me); + me->sum = 0.0; + status_ = Q_HANDLED(); + break; + } + //${Components::Cruncher::SM::processing::CRUNCH} + case CRUNCH_SIG: { + uint32_t i = Q_EVT_CAST(ReminderEvt)->iter; + uint32_t n = i; + i += 100U; + for (; n < i; ++n) { + if ((n & 1) == 0) { + me->sum += 1.0/(2*n + 1); + } + else { + me->sum -= 1.0/(2*n + 1); + } + } + //${Components::Cruncher::SM::processing::CRUNCH::[i<0x07000000U]} + if (i < 0x07000000U) { + ReminderEvt *reminder = Q_NEW(ReminderEvt, CRUNCH_SIG); + reminder->iter = i; + QACTIVE_POST(&me->super, &reminder->super, me); + status_ = Q_HANDLED(); + } + //${Components::Cruncher::SM::processing::CRUNCH::[else]} + else { + PRINTF_S("pi=%16.14f\n", 4.0 * me->sum); + status_ = Q_TRAN(&Cruncher_processing); + } + break; + } + //${Components::Cruncher::SM::processing::ECHO} + case ECHO_SIG: { + PRINTF_S("Echo! pi=%16.14f\n", 4.0 * me->sum); + status_ = Q_HANDLED(); + break; + } + //${Components::Cruncher::SM::processing::TERMINATE} + case TERMINATE_SIG: { + status_ = Q_TRAN(&Cruncher_final); + break; + } + default: { + status_ = Q_SUPER(&QHsm_top); + break; + } + } + return status_; +} + +//${Components::Cruncher::SM::final} ......................................... +static QState Cruncher_final(Cruncher * const me, QEvt const * const e) { + QState status_; + switch (e->sig) { + //${Components::Cruncher::SM::final} + case Q_ENTRY_SIG: { + PRINTF_S("%s\n", "final-ENTRY;"); + QF_stop(); // terminate the application + status_ = Q_HANDLED(); + break; + } + default: { + status_ = Q_SUPER(&QHsm_top); + break; + } + } + return status_; +} +//$enddef${Components::Cruncher} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +// test harness ============================================================ + +// Local-scope objects ----------------------------------------------------- +static Cruncher l_cruncher; // the Cruncher active object +QEvt const *l_cruncherQSto[10]; // Event queue storage for Cruncher AO +static QF_MPOOL_EL(ReminderEvt) l_smlPoolSto[20]; // storage for small pool + +//.......................................................................... +int main(int argc, char *argv[]) { + PRINTF_S("Reminder state pattern\nQP version: %s\n" + "Press 'e' to echo the current value...\n" + "Press ESC to quit...\n", + QP_VERSION_STR); + fflush(stdout); + + Cruncher_ctor(&l_cruncher); + + BSP_init(argc, argv); // initialize the BSP + + QF_init();// initialize the framework and the underlying RT kernel + + // publish-subscribe not used, no call to QF_psInit() + + QF_poolInit(l_smlPoolSto, sizeof(l_smlPoolSto), sizeof(l_smlPoolSto[0])); + + // instantiate and start the active objects... + QACTIVE_START(&l_cruncher.super, + 1U, + l_cruncherQSto, Q_DIM(l_cruncherQSto), + (void *)0, 0U, (QEvt *)0); + + return QF_run(); // run the QF application +} +//.......................................................................... +void BSP_onKeyboardInput(uint8_t key) { + switch (key) { + case 'e': { // echo the progress so far + static QEvt const echoEvt = QEVT_INITIALIZER(ECHO_SIG); + QACTIVE_POST((QActive *)&l_cruncher, &echoEvt, (void *)0); + break; + } + case '\033': { // ESC pressed? + // NOTE: this constant event is statically pre-allocated. + // It can be posted/published as any other event. + static QEvt const terminateEvt = QEVT_INITIALIZER(TERMINATE_SIG); + QACTIVE_POST((QActive *)&l_cruncher, &terminateEvt, (void *)0); + break; + } + } +} diff --git a/examples/workstation/reminder2/reminder2.qm b/examples/posix-win32/reminder2/reminder2.qm similarity index 72% rename from examples/workstation/reminder2/reminder2.qm rename to examples/posix-win32/reminder2/reminder2.qm index 90568b21..a581bb23 100644 --- a/examples/workstation/reminder2/reminder2.qm +++ b/examples/posix-win32/reminder2/reminder2.qm @@ -1,5 +1,5 @@ - + "Reminder" state pattern example #2 @@ -9,7 +9,7 @@ - /* the next iteration to perform */ + // the next iteration to perform @@ -31,7 +31,7 @@ - (void)par; /* unused parameter */ + (void)par; // unused parameter @@ -97,7 +97,7 @@ QACTIVE_POST(&me->super, &reminder->super, me); PRINTF_S("%s\n", "final-ENTRY;"); - QF_stop(); /* terminate the application */ + QF_stop(); // terminate the application @@ -113,33 +113,33 @@ QACTIVE_POST(&me->super, &reminder->super, me); #include "qpc.h" #include "bsp.h" -#include "safe_std.h" /* portable "safe" <stdio.h>/<string.h> facilities */ +#include "safe_std.h" // portable "safe" <stdio.h>/<string.h> facilities #include <stdlib.h> -Q_DEFINE_THIS_FILE +//Q_DEFINE_THIS_FILE -/*..........................................................................*/ +//.......................................................................... enum ReminderSignals { - CRUNCH_SIG = Q_USER_SIG, /* the invented reminder signal */ - ECHO_SIG, /* check the responsiveness of the system */ - TERMINATE_SIG /* terminate the application */ + CRUNCH_SIG = Q_USER_SIG, // the invented reminder signal + ECHO_SIG, // check the responsiveness of the system + TERMINATE_SIG // terminate the application }; $declare${Events::ReminderEvt} -/*..........................................................................*/ +//.......................................................................... $declare${Components::Cruncher} $define${Components::Cruncher} -/* test harness ============================================================*/ +// test harness ============================================================ -/* Local-scope objects -----------------------------------------------------*/ -static Cruncher l_cruncher; /* the Cruncher active object */ -QEvt const *l_cruncherQSto[10]; /* Event queue storage for Cruncher AO */ -static QF_MPOOL_EL(ReminderEvt) l_smlPoolSto[20]; /* storage for small pool */ +// Local-scope objects ----------------------------------------------------- +static Cruncher l_cruncher; // the Cruncher active object +QEvt const *l_cruncherQSto[10]; // Event queue storage for Cruncher AO +static QF_MPOOL_EL(ReminderEvt) l_smlPoolSto[20]; // storage for small pool -/*..........................................................................*/ +//.......................................................................... int main(int argc, char *argv[]) { PRINTF_S("Reminder state pattern\nQP version: %s\n" "Press 'e' to echo the current value...\n" @@ -149,41 +149,39 @@ int main(int argc, char *argv[]) { Cruncher_ctor(&l_cruncher); - BSP_init(argc, argv); /* initialize the BSP */ + BSP_init(argc, argv); // initialize the BSP - QF_init();/* initialize the framework and the underlying RT kernel */ + QF_init();// initialize the framework and the underlying RT kernel - /* publish-subscribe not used, no call to QF_psInit() */ + // publish-subscribe not used, no call to QF_psInit() QF_poolInit(l_smlPoolSto, sizeof(l_smlPoolSto), sizeof(l_smlPoolSto[0])); - /* instantiate and start the active objects... */ + // instantiate and start the active objects... QACTIVE_START(&l_cruncher.super, 1U, l_cruncherQSto, Q_DIM(l_cruncherQSto), (void *)0, 0U, (QEvt *)0); - return QF_run(); /* run the QF application */ + return QF_run(); // run the QF application } -/*..........................................................................*/ +//.......................................................................... void BSP_onKeyboardInput(uint8_t key) { switch (key) { - case 'e': { /* echo the progress so far */ - static QEvt const echoEvt = { ECHO_SIG, 0U, 0U }; + case 'e': { // echo the progress so far + static QEvt const echoEvt = QEVT_INITIALIZER(ECHO_SIG); QACTIVE_POST((QActive *)&l_cruncher, &echoEvt, (void *)0); break; } - case '\033': { /* ESC pressed? */ - /* NOTE: this constant event is statically pre-allocated. - * It can be posted/published as any other event. - */ - static QEvt const terminateEvt = { TERMINATE_SIG, 0U, 0U }; + case '\033': { // ESC pressed? + // NOTE: this constant event is statically pre-allocated. + // It can be posted/published as any other event. + static QEvt const terminateEvt = QEVT_INITIALIZER(TERMINATE_SIG); QACTIVE_POST((QActive *)&l_cruncher, &terminateEvt, (void *)0); break; } } -} - +} diff --git a/examples/qutest/blinky/src/blinky.c b/examples/qutest/blinky/src/blinky.c index bff0a277..3a025e54 100644 --- a/examples/qutest/blinky/src/blinky.c +++ b/examples/qutest/blinky/src/blinky.c @@ -1,91 +1,90 @@ -/*$file${src::blinky.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* -* Model: blinky.qm -* File: ${src::blinky.c} -* -* This code has been generated by QM 5.2.4 . -* DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. -* -* SPDX-License-Identifier: GPL-3.0-or-later -* -* This generated code is open source software: you can redistribute it under -* the terms of the GNU General Public License as published by the Free -* Software Foundation. -* -* This code is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -* more details. -* -* NOTE: -* Alternatively, this generated code may be distributed under the terms -* of Quantum Leaps commercial licenses, which expressly supersede the GNU -* General Public License and are specifically designed for licensees -* interested in retaining the proprietary status of their code. -* -* Contact information: -* -* -*/ -/*$endhead${src::blinky.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$file${.::blinky.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// +// Model: blinky.qm +// File: ${.::blinky.c} +// +// This code has been generated by QM 5.3.0 . +// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. +// +// SPDX-License-Identifier: GPL-3.0-or-later +// +// This generated code is open source software: you can redistribute it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation. +// +// This code is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// NOTE: +// Alternatively, this generated code may be distributed under the terms +// of Quantum Leaps commercial licenses, which expressly supersede the GNU +// General Public License and are specifically designed for licensees +// interested in retaining the proprietary status of their code. +// +// Contact information: +// +// +// +//$endhead${.::blinky.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ #include "qpc.h" #include "blinky.h" #include "bsp.h" //Q_DEFINE_THIS_MODULE("blinky") -/*************** ask QM to declare the Blinky class ******************/ -/*$declare${AOs::Blinky} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +// ask QM to declare the Blinky class... +//$declare${AOs::Blinky} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/*${AOs::Blinky} ...........................................................*/ +//${AOs::Blinky} ............................................................. typedef struct { -/* protected: */ +// protected: QActive super; -/* private: */ +// private: QTimeEvt timeEvt; } Blinky; -/* protected: */ +// protected: static QState Blinky_initial(Blinky * const me, void const * const par); static QState Blinky_off(Blinky * const me, QEvt const * const e); static QState Blinky_on(Blinky * const me, QEvt const * const e); -/*$enddecl${AOs::Blinky} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$enddecl${AOs::Blinky} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ static Blinky l_blinky; -/*$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* Check for the minimum required QP version */ -#if (QP_VERSION < 700U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) -#error qpc version 7.0.0 or higher required +//$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// Check for the minimum required QP version +#if (QP_VERSION < 730U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) +#error qpc version 7.3.0 or higher required #endif -/*$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -/*$define${AOs::AO_Blinky} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//$define${AOs::AO_Blinky} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/*${AOs::AO_Blinky} ........................................................*/ +//${AOs::AO_Blinky} .......................................................... QActive * const AO_Blinky = &l_blinky.super; -/*$enddef${AOs::AO_Blinky} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$enddef${AOs::AO_Blinky} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -/*************** ask QM to define the Blinky class ******************/ -/*$define${AOs::Blinky_ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +// ask QM to define the Blinky class... +//$define${AOs::Blinky_ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/*${AOs::Blinky_ctor} ......................................................*/ +//${AOs::Blinky_ctor} ........................................................ void Blinky_ctor(void) { Blinky *me = &l_blinky; QActive_ctor(&me->super, Q_STATE_CAST(&Blinky_initial)); QTimeEvt_ctorX(&me->timeEvt, &me->super, TIMEOUT_SIG, 0U); } -/*$enddef${AOs::Blinky_ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$enddef${AOs::Blinky_ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +//$define${AOs::Blinky} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/*$define${AOs::Blinky} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//${AOs::Blinky} ............................................................. -/*${AOs::Blinky} ...........................................................*/ - -/*${AOs::Blinky::SM} .......................................................*/ +//${AOs::Blinky::SM} ......................................................... static QState Blinky_initial(Blinky * const me, void const * const par) { - /*${AOs::Blinky::SM::initial} */ - (void)par; /* unused parameter */ + //${AOs::Blinky::SM::initial} + (void)par; // unused parameter QS_OBJ_DICTIONARY(&l_blinky); QS_OBJ_DICTIONARY(&l_blinky.timeEvt); @@ -99,17 +98,17 @@ static QState Blinky_initial(Blinky * const me, void const * const par) { return Q_TRAN(&Blinky_off); } -/*${AOs::Blinky::SM::off} ..................................................*/ +//${AOs::Blinky::SM::off} .................................................... static QState Blinky_off(Blinky * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${AOs::Blinky::SM::off} */ + //${AOs::Blinky::SM::off} case Q_ENTRY_SIG: { BSP_ledOff(); status_ = Q_HANDLED(); break; } - /*${AOs::Blinky::SM::off::TIMEOUT} */ + //${AOs::Blinky::SM::off::TIMEOUT} case TIMEOUT_SIG: { status_ = Q_TRAN(&Blinky_on); break; @@ -122,17 +121,17 @@ static QState Blinky_off(Blinky * const me, QEvt const * const e) { return status_; } -/*${AOs::Blinky::SM::on} ...................................................*/ +//${AOs::Blinky::SM::on} ..................................................... static QState Blinky_on(Blinky * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${AOs::Blinky::SM::on} */ + //${AOs::Blinky::SM::on} case Q_ENTRY_SIG: { BSP_ledOn(); status_ = Q_HANDLED(); break; } - /*${AOs::Blinky::SM::on::TIMEOUT} */ + //${AOs::Blinky::SM::on::TIMEOUT} case TIMEOUT_SIG: { status_ = Q_TRAN(&Blinky_off); break; @@ -144,5 +143,4 @@ static QState Blinky_on(Blinky * const me, QEvt const * const e) { } return status_; } -/*$enddef${AOs::Blinky} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ - +//$enddef${AOs::Blinky} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/examples/qutest/blinky/src/blinky.h b/examples/qutest/blinky/src/blinky.h index cc0c961f..9ce1bbcd 100644 --- a/examples/qutest/blinky/src/blinky.h +++ b/examples/qutest/blinky/src/blinky.h @@ -1,56 +1,56 @@ -/*$file${src::blinky.h} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* -* Model: blinky.qm -* File: ${src::blinky.h} -* -* This code has been generated by QM 5.2.4 . -* DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. -* -* SPDX-License-Identifier: GPL-3.0-or-later -* -* This generated code is open source software: you can redistribute it under -* the terms of the GNU General Public License as published by the Free -* Software Foundation. -* -* This code is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -* more details. -* -* NOTE: -* Alternatively, this generated code may be distributed under the terms -* of Quantum Leaps commercial licenses, which expressly supersede the GNU -* General Public License and are specifically designed for licensees -* interested in retaining the proprietary status of their code. -* -* Contact information: -* -* -*/ -/*$endhead${src::blinky.h} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$file${.::blinky.h} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// +// Model: blinky.qm +// File: ${.::blinky.h} +// +// This code has been generated by QM 5.3.0 . +// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. +// +// SPDX-License-Identifier: GPL-3.0-or-later +// +// This generated code is open source software: you can redistribute it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation. +// +// This code is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// NOTE: +// Alternatively, this generated code may be distributed under the terms +// of Quantum Leaps commercial licenses, which expressly supersede the GNU +// General Public License and are specifically designed for licensees +// interested in retaining the proprietary status of their code. +// +// Contact information: +// +// +// +//$endhead${.::blinky.h} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ #ifndef BLINKY_H #define BLINKY_H enum BlinkySignals { DUMMY_SIG = Q_USER_SIG, - MAX_PUB_SIG, /* the last published signal */ + MAX_PUB_SIG, // the last published signal TIMEOUT_SIG, - MAX_SIG /* the last signal */ + MAX_SIG // the last signal }; -/*$declare${AOs::Blinky_ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//$declare${AOs::Blinky_ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/*${AOs::Blinky_ctor} ......................................................*/ +//${AOs::Blinky_ctor} ........................................................ void Blinky_ctor(void); -/*$enddecl${AOs::Blinky_ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$enddecl${AOs::Blinky_ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -/*$declare${AOs::AO_Blinky} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//$declare${AOs::AO_Blinky} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/*${AOs::AO_Blinky} ........................................................*/ -/* opaque pointer to the Blinky AO */ +//${AOs::AO_Blinky} .......................................................... +// opaque pointer to the Blinky AO extern QActive * const AO_Blinky; -/*$enddecl${AOs::AO_Blinky} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$enddecl${AOs::AO_Blinky} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -#endif /* BLINKY_H */ +#endif // BLINKY_H diff --git a/examples/qutest/blinky/blinky.qm b/examples/qutest/blinky/src/blinky.qm similarity index 80% rename from examples/qutest/blinky/blinky.qm rename to examples/qutest/blinky/src/blinky.qm index 892ddedb..5444e390 100644 --- a/examples/qutest/blinky/blinky.qm +++ b/examples/qutest/blinky/src/blinky.qm @@ -1,5 +1,5 @@ - + Blinky example @@ -13,7 +13,7 @@ - (void)par; /* unused parameter */ + (void)par; // unused parameter QS_OBJ_DICTIONARY(&l_blinky); QS_OBJ_DICTIONARY(&l_blinky.timeEvt); @@ -55,7 +55,7 @@ QTimeEvt_armX(&me->timeEvt, - /* opaque pointer to the Blinky AO */ + // opaque pointer to the Blinky AO = &l_blinky.super; @@ -65,29 +65,29 @@ QActive_ctor(&me->super, Q_STATE_CAST(&Blinky_initial)); QTimeEvt_ctorX(&me->timeEvt, &me->super, TIMEOUT_SIG, 0U); - - - + + + #ifndef BLINKY_H #define BLINKY_H enum BlinkySignals { DUMMY_SIG = Q_USER_SIG, - MAX_PUB_SIG, /* the last published signal */ + MAX_PUB_SIG, // the last published signal TIMEOUT_SIG, - MAX_SIG /* the last signal */ + MAX_SIG // the last signal }; $declare${AOs::Blinky_ctor} $declare${AOs::AO_Blinky} -#endif /* BLINKY_H */ +#endif // BLINKY_H - + #include "qpc.h" #include "blinky.h" @@ -95,18 +95,16 @@ $declare${AOs::AO_Blinky} //Q_DEFINE_THIS_MODULE("blinky") -/*************** ask QM to declare the Blinky class ******************/ -$declare${AOs::Blinky} +// ask QM to declare the Blinky class... +$declare ${AOs::Blinky} static Blinky l_blinky; -$define${AOs::AO_Blinky} +$define ${AOs::AO_Blinky} -/*************** ask QM to define the Blinky class ******************/ -$define${AOs::Blinky_ctor} - -$define${AOs::Blinky} - +// ask QM to define the Blinky class... +$define ${AOs::Blinky_ctor} +$define ${AOs::Blinky} diff --git a/examples/qutest/blinky/src/bsp.c b/examples/qutest/blinky/src/bsp.c index cab0ff39..b2c621a0 100644 --- a/examples/qutest/blinky/src/bsp.c +++ b/examples/qutest/blinky/src/bsp.c @@ -1,36 +1,36 @@ -/***************************************************************************** -* Product: "Blinky" example, Win32 API -* Last Updated for Version: 7.2.0 -* Date of the Last Update: 2022-12-22 -* -* Q u a n t u m L e a P s -* --------------------------- -* innovating embedded systems -* -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* -* -*****************************************************************************/ +//============================================================================ +// Product: "Blinky" example, Win32 API +// Last Updated for Version: 7.2.0 +// Date of the Last Update: 2022-12-22 +// +// Q u a n t u m L e a P s +// --------------------------- +// innovating embedded systems +// +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// This program is open source software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Alternatively, this program may be distributed and modified under the +// terms of Quantum Leaps commercial licenses, which expressly supersede +// the GNU General Public License and are specifically designed for +// licensees interested in retaining the proprietary status of their code. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Contact information: +// +// +//============================================================================ #include "qpc.h" #include "blinky.h" #include "bsp.h" @@ -41,17 +41,17 @@ enum { LED = QS_USER }; -/*..........................................................................*/ +//............................................................................ void BSP_init() { QS_USR_DICTIONARY(LED); } -/*..........................................................................*/ +//............................................................................ void BSP_ledOff(void) { QS_BEGIN_ID(LED, AO_Blinky->prio) QS_U8(1, 0); QS_END() } -/*..........................................................................*/ +//............................................................................ void BSP_ledOn(void) { QS_BEGIN_ID(LED, AO_Blinky->prio) QS_U8(1, 1); diff --git a/examples/qutest/blinky/src/bsp.h b/examples/qutest/blinky/src/bsp.h index 7c171cce..c3ee03b4 100644 --- a/examples/qutest/blinky/src/bsp.h +++ b/examples/qutest/blinky/src/bsp.h @@ -1,38 +1,36 @@ -/***************************************************************************** -* Product: DPP example -* Last Updated for Version: 5.6.0 -* Date of the Last Update: 2015-11-22 -* -* Q u a n t u m L e a P s -* --------------------------- -* innovating embedded systems -* -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* -* -*****************************************************************************/ -#ifndef BSP_H -#define BSP_H +//============================================================================ +// Product: Board Support Package example +// Last Updated for Version: 7.3.0 +// Date of the Last Update: 2023-08-12 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +//============================================================================ +#ifndef BSP_H_ +#define BSP_H_ #define BSP_TICKS_PER_SEC 100U @@ -41,12 +39,10 @@ void BSP_displayPaused(uint8_t paused); void BSP_displayPhilStat(uint8_t n, char const *stat); void BSP_terminate(int16_t result); -void BSP_randomSeed(uint32_t seed); /* random seed */ -uint32_t BSP_random(void); /* pseudo-random generator */ +void BSP_randomSeed(uint32_t seed); // random seed +uint32_t BSP_random(void); // pseudo-random generator -/* for testing... */ -void BSP_wait4SW1(void); void BSP_ledOn(void); void BSP_ledOff(void); -#endif /* BSP_H */ +#endif // BSP_H_ diff --git a/examples/qutest/blinky/test/Makefile b/examples/qutest/blinky/test/Makefile index 8f433533..5ff4896c 100644 --- a/examples/qutest/blinky/test/Makefile +++ b/examples/qutest/blinky/test/Makefile @@ -57,11 +57,11 @@ PROJECT := test_blinky # list of all source directories used by this project VPATH := . \ -../src + ../src # list of all include directories needed by this project INCLUDES := -I. \ --I../src + -I../src # location of the QP/C framework (if not provided in an env. variable) ifeq ($(QPC),) @@ -96,8 +96,8 @@ DEFINES := # add QP/C framework: # C_SRCS += \ -qep_hsm.c \ -qep_msm.c \ + qep_hsm.c \ + qep_msm.c \ qf_act.c \ qf_actq.c \ qf_defer.c \ @@ -218,7 +218,7 @@ all : $(TARGET_EXE) run endif $(TARGET_EXE) : $(C_OBJS_EXT) $(CPP_OBJS_EXT) - $(CC) $(CFLAGS) $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o + $(CC) $(CFLAGS) $(QPC)/src/qs/qstamp.c -o $(BIN_DIR)/qstamp.o $(LINK) $(LINKFLAGS) $(LIB_DIRS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) run : $(TARGET_EXE) diff --git a/examples/qutest/blinky/test/make_efm32 b/examples/qutest/blinky/test/make_efm32 index 18664afb..09559acb 100644 --- a/examples/qutest/blinky/test/make_efm32 +++ b/examples/qutest/blinky/test/make_efm32 @@ -253,7 +253,7 @@ $(TARGET_BIN) : $(TARGET_ELF) $(FLASH) $@ $(TARGET_ELF) : $(ASM_OBJS_EXT) $(C_OBJS_EXT) $(CPP_OBJS_EXT) - $(CC) $(CFLAGS) $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o + $(CC) $(CFLAGS) $(QPC)/src/qs/qstamp.c -o $(BIN_DIR)/qstamp.o $(LINK) $(LINKFLAGS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) flash : diff --git a/examples/qutest/blinky/test/make_nucleo-h743zi b/examples/qutest/blinky/test/make_nucleo-h743zi index ca6039b4..93d05348 100644 --- a/examples/qutest/blinky/test/make_nucleo-h743zi +++ b/examples/qutest/blinky/test/make_nucleo-h743zi @@ -268,7 +268,7 @@ $(TARGET_BIN) : $(TARGET_ELF) $(SLEEP) 2 $(TARGET_ELF) : $(ASM_OBJS_EXT) $(C_OBJS_EXT) $(CPP_OBJS_EXT) - $(CC) $(CFLAGS) $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o + $(CC) $(CFLAGS) $(QPC)/src/qs/qstamp.c -o $(BIN_DIR)/qstamp.o $(LINK) $(LINKFLAGS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) flash : diff --git a/examples/qutest/blinky/test/make_nucleo-l053r8 b/examples/qutest/blinky/test/make_nucleo-l053r8 index 94b7e4af..ab4a452b 100644 --- a/examples/qutest/blinky/test/make_nucleo-l053r8 +++ b/examples/qutest/blinky/test/make_nucleo-l053r8 @@ -253,7 +253,7 @@ $(TARGET_BIN) : $(TARGET_ELF) $(SLEEP) 2 $(TARGET_ELF) : $(ASM_OBJS_EXT) $(C_OBJS_EXT) $(CPP_OBJS_EXT) - $(CC) $(CFLAGS) $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o + $(CC) $(CFLAGS) $(QPC)/src/qs/qstamp.c -o $(BIN_DIR)/qstamp.o $(LINK) $(LINKFLAGS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) flash : diff --git a/examples/qutest/blinky/test/make_tm4c123 b/examples/qutest/blinky/test/make_tm4c123 index 68e99e4a..18ea2da8 100644 --- a/examples/qutest/blinky/test/make_tm4c123 +++ b/examples/qutest/blinky/test/make_tm4c123 @@ -254,7 +254,7 @@ $(TARGET_BIN) : $(TARGET_ELF) @pause $(TARGET_ELF) : $(ASM_OBJS_EXT) $(C_OBJS_EXT) $(CPP_OBJS_EXT) - $(CC) $(CFLAGS) $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o + $(CC) $(CFLAGS) $(QPC)/src/qs/qstamp.c -o $(BIN_DIR)/qstamp.o $(LINK) $(LINKFLAGS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) flash : diff --git a/examples/qutest/blinky/test/test_blinky.c b/examples/qutest/blinky/test/test_blinky.c index ef64c8e7..b5fec6a0 100644 --- a/examples/qutest/blinky/test/test_blinky.c +++ b/examples/qutest/blinky/test/test_blinky.c @@ -1,82 +1,84 @@ -/***************************************************************************** -* Purpose: Fixture for QUTEST -* Last updated for version 7.1.1 -* Last updated on 2022-09-22 -* -* Q u a n t u m L e a P s -* ------------------------ -* Modern Embedded Software -* -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* -* -*****************************************************************************/ +//============================================================================ +// Purpose: Fixture for QUTEST +// Last updated for version 7.3.0 +// Last updated on 2025-05-25 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// This program is open source software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Alternatively, this program may be distributed and modified under the +// terms of Quantum Leaps commercial licenses, which expressly supersede +// the GNU General Public License and are specifically designed for +// licensees interested in retaining the proprietary status of their code. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Contact information: +// +// +//============================================================================ #include "qpc.h" #include "blinky.h" #include "bsp.h" Q_DEFINE_THIS_FILE -/*..........................................................................*/ +//............................................................................ int main(int argc, char *argv[]) { - QF_init(); /* initialize the framework */ + QF_init(); // initialize the framework - /* initialize the QS software tracing */ - Q_ALLEGE(QS_INIT(argc > 1 ? argv[1] : (void *)0)); + // initialize the QS software tracing + if (QS_INIT((argc > 1) ? argv[1] : (void *)0) == 0U) { + Q_ERROR(); + } - BSP_init(); /* initialize the BSP */ + BSP_init(); // initialize the BSP - /* dictionaries... */ + // dictionaries... QS_SIG_DICTIONARY(TIMEOUT_SIG, (void *)0); - /* pause execution of the test and wait for the test script to continue */ + // pause execution of the test and wait for the test script to continue QS_TEST_PAUSE(); - /* publish-subscribe not used, no call to QF_psInit() */ + // publish-subscribe not used, no call to QActive_psInit() - /* initialize event pools... */ - static QF_MPOOL_EL(QEvt) smlPoolSto[10]; /* storage for small pool*/ + // initialize event pools... + static QF_MPOOL_EL(QEvt) smlPoolSto[10]; // storage for small pool QF_poolInit(smlPoolSto, sizeof(smlPoolSto), sizeof(smlPoolSto[0])); - /* start the active objects... */ + // start the active objects... Blinky_ctor(); - static QEvt const *blinkyQSto[10]; /* event queue storage for Blinky */ + static QEvt const *blinkyQSto[10]; // event queue storage for Blinky QACTIVE_START(AO_Blinky, - 2U, /* QF-priority/preemption-threshold */ + 2U, // QF-priority/preemption-threshold blinkyQSto, Q_DIM(blinkyQSto), (void *)0, 0U, (void *)0); return QF_run(); } -/*--------------------------------------------------------------------------*/ +//---------------------------------------------------------------------------- void QS_onTestSetup(void) { } -/*..........................................................................*/ +//............................................................................ void QS_onTestTeardown(void) { } -/*..........................................................................*/ +//............................................................................ void QS_onCommand(uint8_t cmdId, uint32_t param1, uint32_t param2, uint32_t param3) { @@ -86,18 +88,18 @@ void QS_onCommand(uint8_t cmdId, Q_UNUSED_PAR(param3); } -/*..........................................................................*/ -/* host callback function to "massage" the event, if necessary */ +//............................................................................ +// host callback function to "massage" the event, if necessary void QS_onTestEvt(QEvt *e) { -#ifdef Q_HOST /* is this test compiled for a desktop Host computer? */ -#else /* this test is compiled for an embedded Target system */ +#ifdef Q_HOST // is this test compiled for a desktop Host computer? +#else // this test is compiled for an embedded Target system #endif - /* unused parameters... */ + // unused parameters... (void)e; } -/*..........................................................................*/ -/*! callback function to output the posted QP events (not used here) */ +//............................................................................ +//! callback function to output the posted QP events (not used here) void QS_onTestPost(void const *sender, QActive *recipient, QEvt const *e, bool status) { diff --git a/examples/qutest/blinky/test/test_tm4c123-arm.uvoptx b/examples/qutest/blinky/test/test_tm4c123-arm.uvoptx index a694dc4a..5f5c9904 100644 --- a/examples/qutest/blinky/test/test_tm4c123-arm.uvoptx +++ b/examples/qutest/blinky/test/test_tm4c123-arm.uvoptx @@ -295,7 +295,7 @@ 0 0 0 - ..\..\..\..\include\qstamp.c + ..\..\..\..\src\qs\qstamp.c qstamp.c 0 0 @@ -378,12 +378,12 @@ 3 - 12 + 16 1 0 0 0 - ..\..\..\..\src\qf\qf_act.c + ..\..\..\..\..\src\qf\qf_act.c qf_act.c 0 0 diff --git a/examples/qutest/blinky/test/test_tm4c123-arm.uvprojx b/examples/qutest/blinky/test/test_tm4c123-arm.uvprojx index 2482c93d..ea2a9d4d 100644 --- a/examples/qutest/blinky/test/test_tm4c123-arm.uvprojx +++ b/examples/qutest/blinky/test/test_tm4c123-arm.uvprojx @@ -336,7 +336,7 @@ 0 - Q_SPY Q_UTEST __FPU_PRESENT + Q_SPY Q_UTEST .;..\src;..\..\..\..\include;..\..\..\..\src;..\..\..\..\ports\arm-cm\qutest;..\..\..\..\3rd_party\CMSIS\Include;..\..\..\..\3rd_party\ek-tm4c123gxl @@ -410,7 +410,7 @@ qstamp.c 1 - ..\..\..\..\include\qstamp.c + ..\..\..\..\src\qs\qstamp.c @@ -450,7 +450,7 @@ qf_act.c 1 - ..\..\..\..\src\qf\qf_act.c + ..\..\..\..\..\src\qf\qf_act.c qf_actq.c diff --git a/examples/qutest/blinky/test/test_vc.vcxproj b/examples/qutest/blinky/test/test_vc.vcxproj index 671614a1..fe59ab19 100644 --- a/examples/qutest/blinky/test/test_vc.vcxproj +++ b/examples/qutest/blinky/test/test_vc.vcxproj @@ -112,6 +112,7 @@ ProgramDatabase 4127 Default + stdc11 ws2_32.lib;%(AdditionalDependencies) @@ -140,6 +141,7 @@ Level4 ProgramDatabase 4127 + stdc11 %(AdditionalDependencies) @@ -157,7 +159,7 @@ Disabled - .;../../../include;../../../ports/win32-qv;$(QTOOLS)/qspy/include;%(AdditionalIncludeDirectories) + .;../../../include;../../../ports/win32-qutest;$(QTOOLS)/qspy/include;%(AdditionalIncludeDirectories) Q_SPY;WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) false @@ -168,6 +170,7 @@ Level4 ProgramDatabase 4127 + stdc11 ws2_32.lib;%(AdditionalDependencies) diff --git a/examples/qutest/dpp-comp/src/bsp.c b/examples/qutest/dpp-comp/src/bsp.c index c085f2c8..d7cf7110 100644 --- a/examples/qutest/dpp-comp/src/bsp.c +++ b/examples/qutest/dpp-comp/src/bsp.c @@ -1,106 +1,103 @@ -/***************************************************************************** -* Product: DPP example, BSP for QUTest -* Last Updated for Version: 7.2.0 -* Date of the Last Update: 2022-12-22 -* -* Q u a n t u m L e a P s -* ------------------------ -* Modern Embedded Software -* -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* -* -*****************************************************************************/ +//============================================================================ +// Product: DPP example, BSP for QUTest +// Last Updated for Version: 7.3.0 +// Date of the Last Update: 2023-08-23 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// This program is open source software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Alternatively, this program may be distributed and modified under the +// terms of Quantum Leaps commercial licenses, which expressly supersede +// the GNU General Public License and are specifically designed for +// licensees interested in retaining the proprietary status of their code. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Contact information: +// +// +//============================================================================ #include "qpc.h" #include "dpp.h" #include "bsp.h" Q_DEFINE_THIS_MODULE("bsp") -static uint32_t l_rnd; /* random seed */ +// Local objects ------------------------------------------------------------- +static uint32_t l_rnd; // random seed + enum { BSP_CALL = QS_USER, }; -/*..........................................................................*/ -void BSP_init(int argc, char **argv) { - Q_ALLEGE(QS_INIT(argc <= 1 ? (void *)0 : argv[1]) != 0U); +//............................................................................ +void BSP_init(void) { + // initialize the QS software tracing + if (!QS_INIT((void *)0)) { + Q_ERROR(); + } QS_FUN_DICTIONARY(&BSP_displayPaused); QS_FUN_DICTIONARY(&BSP_displayPhilStat); QS_FUN_DICTIONARY(&BSP_random); QS_FUN_DICTIONARY(&BSP_randomSeed); - /* global signals */ - QS_SIG_DICTIONARY(DONE_SIG, (void *)0); - QS_SIG_DICTIONARY(EAT_SIG, (void *)0); - QS_SIG_DICTIONARY(PAUSE_SIG, (void *)0); - QS_SIG_DICTIONARY(SERVE_SIG, (void *)0); - QS_SIG_DICTIONARY(TEST_SIG, (void *)0); - QS_SIG_DICTIONARY(HUNGRY_SIG, (void *)0); - QS_SIG_DICTIONARY(HUNGRY_SIG, (void *)0); - QS_SIG_DICTIONARY(TIMEOUT_SIG, (void *)0); + QS_ONLY(produce_sig_dict()); QS_USR_DICTIONARY(BSP_CALL); BSP_randomSeed(1234U); } -/*..........................................................................*/ +//............................................................................ +void BSP_displayPhilStat(uint8_t n, char const *stat) { + QS_BEGIN_ID(BSP_CALL, 0U) // app-specific record + QS_FUN(&BSP_displayPhilStat); + QS_U8(0, n); + QS_STR(stat); + QS_END() +} +//............................................................................ void BSP_displayPaused(uint8_t paused) { QS_TEST_PROBE_DEF(&BSP_displayPaused) QS_TEST_PROBE( Q_ASSERT_ID(100, 0); ) - QS_BEGIN_ID(BSP_CALL, 0U) /* app-specific record */ + QS_BEGIN_ID(BSP_CALL, 0U) // app-specific record QS_FUN(&BSP_displayPaused); QS_U8(0, paused); QS_END() } -/*..........................................................................*/ -void BSP_displayPhilStat(uint8_t n, char const *stat) { - QS_BEGIN_ID(BSP_CALL, 0U) /* app-specific record */ - QS_FUN(&BSP_displayPhilStat); - QS_U8(0, n); - QS_STR(stat); - QS_END() -} -/*..........................................................................*/ -uint32_t BSP_random(void) { /* a very cheap pseudo-random-number generator */ +//............................................................................ +uint32_t BSP_random(void) { // a fake random-number generator QS_TEST_PROBE_DEF(&BSP_random) uint32_t rnd = 123U; QS_TEST_PROBE( rnd = qs_tp_; ) - QS_BEGIN_ID(BSP_CALL, 0U) /* app-specific record */ + QS_BEGIN_ID(BSP_CALL, 0U) // app-specific record QS_FUN(&BSP_random); QS_U32(0, rnd); QS_END() return rnd; } -/*..........................................................................*/ +//............................................................................ void BSP_randomSeed(uint32_t seed) { QS_TEST_PROBE_DEF(&BSP_randomSeed) @@ -108,7 +105,7 @@ void BSP_randomSeed(uint32_t seed) { seed = qs_tp_; ) l_rnd = seed; - QS_BEGIN_ID(BSP_CALL, 0U) /* app-specific record */ + QS_BEGIN_ID(BSP_CALL, 0U) // app-specific record QS_FUN(&BSP_randomSeed); QS_U32(0, seed); QS_END() diff --git a/examples/qutest/dpp-comp/src/bsp.h b/examples/qutest/dpp-comp/src/bsp.h index 1049ced9..c789279b 100644 --- a/examples/qutest/dpp-comp/src/bsp.h +++ b/examples/qutest/dpp-comp/src/bsp.h @@ -1,54 +1,51 @@ -/***************************************************************************** -* Product: DPP example -* Last Updated for Version: 6.2.0 -* Date of the Last Update: 2018-03-16 -* -* Q u a n t u m L e a P s -* --------------------------- -* innovating embedded systems -* -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* -* -*****************************************************************************/ -#ifndef BSP_H -#define BSP_H +//============================================================================ +// Product: DPP example +// Last Updated for Version: 7.3.0 +// Date of the Last Update: 2023-08-22 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// This program is open source software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Alternatively, this program may be distributed and modified under the +// terms of Quantum Leaps commercial licenses, which expressly supersede +// the GNU General Public License and are specifically designed for +// licensees interested in retaining the proprietary status of their code. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Contact information: +// +// +//============================================================================ +#ifndef BSP_H_ +#define BSP_H_ #define BSP_TICKS_PER_SEC 100U -void BSP_init(int argc, char **argv); +void BSP_init(void); +void BSP_start(void); void BSP_displayPaused(uint8_t paused); void BSP_displayPhilStat(uint8_t n, char const *stat); void BSP_terminate(int16_t result); -void BSP_randomSeed(uint32_t seed); /* random seed */ -uint32_t BSP_random(void); /* pseudo-random generator */ +void BSP_randomSeed(uint32_t seed); // random seed +uint32_t BSP_random(void); // pseudo-random generator -/* for testing... */ -void BSP_wait4PB1(void); void BSP_ledOn(void); void BSP_ledOff(void); -extern QActive *the_Ticker0; - -#endif /* BSP_H */ +#endif // BSP_H_ diff --git a/examples/qutest/dpp-comp/dpp-comp.qm b/examples/qutest/dpp-comp/src/dpp-comp.qm similarity index 66% rename from examples/qutest/dpp-comp/dpp-comp.qm rename to examples/qutest/dpp-comp/src/dpp-comp.qm index cb5cdd4b..c37113b7 100644 --- a/examples/qutest/dpp-comp/dpp-comp.qm +++ b/examples/qutest/dpp-comp/src/dpp-comp.qm @@ -1,5 +1,5 @@ - + Dining Philosopher Problem example with the "Orthogonal Component" state pattern (see https://state-machine.com/doc/Pattern_Orthogonal.pdf) The model demonstrates the following features: @@ -12,13 +12,73 @@ The model demonstrates the following features: 6. Component to Container communication via asynchronous event posting using the LIFO policy. + + + + + { + EAT_SIG = Q_USER_SIG, // published by Table to let a Philo eat + DONE_SIG, // published by Philo when done eating + PAUSE_SIG, // published by BSP to pause the application + SERVE_SIG, // published by BSP to serve re-start serving forks + TEST_SIG, // published by BSP to test the application + MAX_PUB_SIG, // the last published signal + + TIMEOUT_SIG, // posted by time event to Philo + HUNGRY_SIG, // posted by hungry Philo to Table + MAX_SIG // the last signal +}; + + + + QS_SIG_DICTIONARY(EAT_SIG, (void *)0); +QS_SIG_DICTIONARY(DONE_SIG, (void *)0); +QS_SIG_DICTIONARY(PAUSE_SIG, (void *)0); +QS_SIG_DICTIONARY(SERVE_SIG, (void *)0); +QS_SIG_DICTIONARY(TEST_SIG, (void *)0); + +QS_SIG_DICTIONARY(TIMEOUT_SIG, (void *)0); +QS_SIG_DICTIONARY(HUNGRY_SIG, (void *)0); + + + + ((uint8_t)5U) + + + + + + + + + + if (me != (TableEvt *)0) { + // don't call QEvt_ctor() because the initialization of all + // QEvt attributes is already done in QF_QF_newX_() + me->philoId = id; +} +return me; + + + + + = &Table_inst.super; + + + + Table *me = &Table_inst; +QActive_ctor(&me->super, Q_STATE_CAST(&Table_initial)); + +for (uint8_t n = 0U; n < N_PHILO; ++n) { + Philo_ctor(n); // create the Philo component + + me->fork[n] = FREE; + me->isHungry[n] = 0U; +} + + - - - - - @@ -33,7 +93,7 @@ The model demonstrates the following features: - (void)par; /* unused parameter */ + (void)par; // unused parameter QS_OBJ_DICTIONARY(&Table_inst); @@ -45,7 +105,7 @@ for (uint8_t n = 0U; n < N_PHILO; ++n) { me->fork[n] = FREE; me->isHungry[n] = 0U; - QHSM_INIT(SM_Philo[n], (void *)0, QS_AP_ID + n); + QASM_INIT(SM_Philo[n], (void *)0, QS_AP_ID + n); BSP_displayPhilStat(n, "thinking"); } @@ -57,7 +117,7 @@ for (uint8_t n = 0U; n < N_PHILO; ++n) { uint16_t n = Q_EVT_CAST(CompTimeEvt)->compNum; -QHSM_DISPATCH(SM_Philo[n], e, QS_AP_ID + n); +QASM_DISPATCH(SM_Philo[n], e, QS_AP_ID + n); @@ -77,19 +137,20 @@ QHSM_DISPATCH(SM_Philo[n], e, QS_AP_ID + n); - for (uint8_t n = 0U; n < N_PHILO; ++n) { /* give permissions to eat... */ + for (uint8_t n = 0U; n < N_PHILO; ++n) { // give permissions to eat... if ((me->isHungry[n] != 0U) - && (me->fork[LEFT(n)] == FREE) + && (me->fork[left(n)] == FREE) && (me->fork[n] == FREE)) { - me->fork[LEFT(n)] = USED; + me->fork[left(n)] = USED; me->fork[n] = USED; - /* synchronoulsy dispatch EAT event to the Philo component */ - TableEvt evt; - evt.super.sig = EAT_SIG; - evt.philoNum = n; - QHSM_DISPATCH(SM_Philo[n], &evt.super, QS_AP_ID + n); + // synchronously dispatch EAT event to the Philo component + TableEvt const evt = { + QEVT_INITIALIZER(EAT_SIG), + .philoId = n + }; + QASM_DISPATCH(SM_Philo[n], &evt.super, QS_AP_ID + n); me->isHungry[n] = 0U; BSP_displayPhilStat(n, "eating "); @@ -97,24 +158,25 @@ QHSM_DISPATCH(SM_Philo[n], e, QS_AP_ID + n); } - /* find the index of the Philo from the event */ -uint8_t n = Q_EVT_CAST(TableEvt)->philoNum; -/* philo ID must be in range and he must be not hungry */ + // find the index of the Philo from the event +uint8_t n = Q_EVT_CAST(TableEvt)->philoId; +// philo ID must be in range and he must be not hungry Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); BSP_displayPhilStat(n, "hungry "); -uint8_t m = LEFT(n); +uint8_t m = left(n); (me->fork[m] == FREE) && (me->fork[n] == FREE) me->fork[m] = USED; me->fork[n] = USED; -/* synchronoulsy dispatch EAT event to the Philo component */ -TableEvt evt; -evt.super.sig = EAT_SIG; -evt.philoNum = n; -QHSM_DISPATCH(SM_Philo[n], &evt.super, QS_AP_ID + n); +// synchronously dispatch EAT event to the Philo component +TableEvt const evt = { + QEVT_INITIALIZER(EAT_SIG), + .philoId = n +}; +QASM_DISPATCH(SM_Philo[n], &evt.super, QS_AP_ID + n); BSP_displayPhilStat(n, "eating "); @@ -134,43 +196,46 @@ BSP_displayPhilStat(n, "eating "); - /* find the index of the Philo from the event */ -uint8_t n = Q_EVT_CAST(TableEvt)->philoNum; -/* philo ID must be in range and he must be not hungry */ + // find the index of the Philo from the event +uint8_t n = Q_EVT_CAST(TableEvt)->philoId; +// philo ID must be in range and he must be not hungry Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); BSP_displayPhilStat(n, "thinking"); -uint8_t m = LEFT(n); -/* both forks of Phil[n] must be used */ +uint8_t m = left(n); +// both forks of Phil[n] must be used Q_ASSERT((me->fork[n] == USED) && (me->fork[m] == USED)); me->fork[m] = FREE; me->fork[n] = FREE; -m = RIGHT(n); /* check the right neighbor */ +m = right(n); // check the right neighbor -TableEvt evt; if ((me->isHungry[m] != 0U) && (me->fork[m] == FREE)) { me->fork[n] = USED; me->fork[m] = USED; me->isHungry[m] = 0U; - /* synchronoulsy dispatch EAT event to the Philo component */ - evt.super.sig = EAT_SIG; - evt.philoNum = m; - QHSM_DISPATCH(SM_Philo[m], &evt.super, QS_AP_ID + m); + // synchronously dispatch EAT event to the Philo component + TableEvt const evt = { + QEVT_INITIALIZER(EAT_SIG), + .philoId = m + }; + QASM_DISPATCH(SM_Philo[m], &evt.super, QS_AP_ID + m); BSP_displayPhilStat(m, "eating "); } -m = LEFT(n); /* check the left neighbor */ -n = LEFT(m); /* left fork of the left neighbor */ +m = left(n); // check the left neighbor +n = left(m); // left fork of the left neighbor if ((me->isHungry[m] != 0U) && (me->fork[n] == FREE)) { me->fork[m] = USED; me->fork[n] = USED; me->isHungry[m] = 0U; - /* synchronoulsy dispatch EAT event to the Philo component */ - evt.super.sig = EAT_SIG; - evt.philoNum = m; - QHSM_DISPATCH(SM_Philo[m], &evt.super, QS_AP_ID + m); + // synchronously dispatch EAT event to the Philo component + TableEvt const evt = { + QEVT_INITIALIZER(EAT_SIG), + .philoId = m + }; + QASM_DISPATCH(SM_Philo[m], &evt.super, QS_AP_ID + m); BSP_displayPhilStat(m, "eating "); } @@ -206,9 +271,9 @@ if ((me->isHungry[m] != 0U) && (me->fork[n] == FREE)) { - /* find the index of the Philo from the event */ -uint8_t n = Q_EVT_CAST(TableEvt)->philoNum; -/* philo ID must be in range and he must be not hungry */ + // find the index of the Philo from the event +uint8_t n = Q_EVT_CAST(TableEvt)->philoId; +// philo ID must be in range and he must be not hungry Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); me->isHungry[n] = 1U; @@ -219,14 +284,14 @@ BSP_displayPhilStat(n, "hungry "); - /* find the index of the Philo from the event */ -uint8_t n = Q_EVT_CAST(TableEvt)->philoNum; -/* philo ID must be in range and he must be not hungry */ + // find the index of the Philo from the event +uint8_t n = Q_EVT_CAST(TableEvt)->philoId; +// philo ID must be in range and he must be not hungry Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); BSP_displayPhilStat(n, "thinking"); -uint8_t m = LEFT(n); -/* both forks of Phil[n] must be used */ +uint8_t m = left(n); +// both forks of Phil[n] must be used Q_ASSERT((me->fork[n] == USED) && (me->fork[m] == USED)); me->fork[m] = FREE; @@ -245,21 +310,6 @@ me->fork[n] = FREE; - - - = &Table_inst.super; /* opaque pointer */ - - - - Table *me = &Table_inst; -QActive_ctor(&me->super, Q_STATE_CAST(&Table_initial)); - -for (uint8_t n = 0U; n < N_PHILO; ++n) { - me->fork[n] = FREE; - me->isHungry[n] = 0U; - Philo_ctor(n); /* create the Philo component */ -} - @@ -291,21 +341,24 @@ me->compNum = num; + + + return (uint8_t)(me - &Philo_inst[0]); + - (void)par; /* unused parameter */ + Q_UNUSED_PAR(par); #ifdef Q_SPY -uint8_t n = (uint8_t)(me - &Philo_inst[0]); -QS_OBJ_ARR_DICTIONARY(&Philo_inst[n], n); -QS_OBJ_ARR_DICTIONARY(&Philo_inst[n].timeEvt, n); +uint8_t id = (uint8_t)(me - &Philo_inst[0]); +QS_OBJ_ARR_DICTIONARY(&Philo_inst[id], id); +QS_OBJ_ARR_DICTIONARY(&Philo_inst[id].timeEvt, id); #endif -/* the following code outputs the "fun-dictionaries" only once for -* all Philo instances, as opposed to repeat them for every instance. -*/ +// the following code outputs the "fun-dictionaries" only once for +// all Philo instances, as opposed to repeat them for every instance. static bool registered = false; if (!registered) { registered = true; @@ -342,9 +395,13 @@ if (!registered) { - /* asynchronously post event to the Container */ + // asynchronously post event to the Container +#ifdef QEVT_DYN_CTOR +TableEvt const *pe = Q_NEW(TableEvt, HUNGRY_SIG, Philo_getId(me)); +#else TableEvt *pe = Q_NEW(TableEvt, HUNGRY_SIG); -pe->philoNum = (uint8_t)(me - &Philo_inst[0]); +pe->philoId = Philo_getId(me); +#endif QACTIVE_POST_LIFO(AO_Table, &pe->super); @@ -361,9 +418,13 @@ QACTIVE_POST_LIFO(AO_Table, &pe->super); QTimeEvt_armX(&me->timeEvt.super, EAT_TIME, 0U); QTimeEvt_disarm(&me->timeEvt.super); -/* asynchronously post event to the Container */ +// asynchronously post event to the Container +#ifdef QEVT_DYN_CTOR +TableEvt const *pe = Q_NEW(TableEvt, DONE_SIG, Philo_getId(me)); +#else TableEvt *pe = Q_NEW(TableEvt, DONE_SIG); -pe->philoNum = (uint8_t)(me - &Philo_inst[0]); +pe->philoId = Philo_getId(me); +#endif QACTIVE_POST_LIFO(AO_Table, &pe->super); @@ -380,13 +441,13 @@ QACTIVE_POST_LIFO(AO_Table, &pe->super); - - = { /* opaque pointers to Philo instances */ - &Philo_inst[0].super, - &Philo_inst[1].super, - &Philo_inst[2].super, - &Philo_inst[3].super, - &Philo_inst[4].super + + = { // opaque pointers to Philo instances + (QAsm *)&Philo_inst[0], + (QAsm *)&Philo_inst[1], + (QAsm *)&Philo_inst[2], + (QAsm *)&Philo_inst[3], + (QAsm *)&Philo_inst[4] }; @@ -398,41 +459,22 @@ QHsm_ctor(&me->super, Q_STATE_CAST(&Philo_initial)); CompTimeEvt_ctor(&me->timeEvt, AO_Table, n, TIMEOUT_SIG, 0U); - - - + + + - #ifndef DPP_H -#define DPP_H + #ifndef DPP_H_ +#define DPP_H_ -enum DPPSignals { - EAT_SIG = Q_USER_SIG, /* published by Table to let a philosopher eat */ - DONE_SIG, /* published by Philosopher when done eating */ - PAUSE_SIG, /* published by BSP to pause serving forks */ - SERVE_SIG, /* published by BSP to serve re-start serving forks */ - TEST_SIG, /* published by BSP to test the application */ - MAX_PUB_SIG, /* the last published signal */ - - HUNGRY_SIG, /* posted direclty to Table from hungry Philo */ - TIMEOUT_SIG, /* used by Philosophers for time events */ - MAX_SIG /* the last signal */ -}; - -enum { - N_PHILO = 5 /* number of Philos */ -}; - -$declare ${Cont::TableEvt} -$declare ${Cont::Table_ctor} -$declare ${Cont::AO_Table} +$declare ${Shared} $declare ${Comp::CompTimeEvt} $declare ${Comp::SM_Philo[N_PHILO]} $declare ${Comp::Philo_ctor} -#endif /* DPP_H */ +#endif // DPP_H_ - + #include "qpc.h" #include "dpp.h" @@ -442,16 +484,16 @@ $declare ${Comp::Philo_ctor} $declare ${Comp::Philo} -/* helper macros to provide a randomized think time for Philos */ +// helper macros to provide a randomized think time for Philos #define THINK_TIME \ (QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + (BSP_TICKS_PER_SEC/2U)) #define EAT_TIME \ (QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + BSP_TICKS_PER_SEC) -/* definition of the whole "Comp" package */ +// definition of the whole "Comp" package $define ${Comp} - + #include "qpc.h" #include "dpp.h" @@ -459,14 +501,27 @@ $define ${Comp} Q_DEFINE_THIS_FILE +// helper function to provide the RIGHT neighbor of a Philo[n] +static inline uint8_t right(uint8_t const n) { + return (uint8_t)((n + (N_PHILO - 1U)) % N_PHILO); +} + +// helper function to provide the LEFT neighbor of a Philo[n] +static inline uint8_t left(uint8_t const n) { + return (uint8_t)((n + 1U) % N_PHILO); +} + +#define FREE ((uint8_t)0U) +#define USED ((uint8_t)1U) + +#define THINKING "thinking" +#define HUNGRY "hungry " +#define EATING "eating " + $declare ${Cont::Table} -#define RIGHT(n_) ((uint8_t)(((n_) + (N_PHILO - 1U)) % N_PHILO)) -#define LEFT(n_) ((uint8_t)(((n_) + 1U) % N_PHILO)) -#define FREE ((uint8_t)0) -#define USED ((uint8_t)1) - -/* definition of the whole "Cont" package */ +$define ${Shared::Table_ctor} +$define ${Shared::AO_Table} $define ${Cont} diff --git a/examples/qutest/dpp-comp/src/dpp.h b/examples/qutest/dpp-comp/src/dpp.h index 80718cba..3d73574a 100644 --- a/examples/qutest/dpp-comp/src/dpp.h +++ b/examples/qutest/dpp-comp/src/dpp.h @@ -1,102 +1,127 @@ -/*$file${src::dpp.h} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* -* Model: dpp-comp.qm -* File: ${src::dpp.h} -* -* This code has been generated by QM 5.2.4 . -* DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. -* -* SPDX-License-Identifier: GPL-3.0-or-later -* -* This generated code is open source software: you can redistribute it under -* the terms of the GNU General Public License as published by the Free -* Software Foundation. -* -* This code is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -* more details. -* -* NOTE: -* Alternatively, this generated code may be distributed under the terms -* of Quantum Leaps commercial licenses, which expressly supersede the GNU -* General Public License and are specifically designed for licensees -* interested in retaining the proprietary status of their code. -* -* Contact information: -* -* -*/ -/*$endhead${src::dpp.h} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -#ifndef DPP_H -#define DPP_H +//$file${.::dpp.h} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// +// Model: dpp-comp.qm +// File: ${.::dpp.h} +// +// This code has been generated by QM 5.3.0 . +// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. +// +// SPDX-License-Identifier: GPL-3.0-or-later +// +// This generated code is open source software: you can redistribute it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation. +// +// This code is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// NOTE: +// Alternatively, this generated code may be distributed under the terms +// of Quantum Leaps commercial licenses, which expressly supersede the GNU +// General Public License and are specifically designed for licensees +// interested in retaining the proprietary status of their code. +// +// Contact information: +// +// +// +//$endhead${.::dpp.h} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +#ifndef DPP_H_ +#define DPP_H_ -enum DPPSignals { - EAT_SIG = Q_USER_SIG, /* published by Table to let a philosopher eat */ - DONE_SIG, /* published by Philosopher when done eating */ - PAUSE_SIG, /* published by BSP to pause serving forks */ - SERVE_SIG, /* published by BSP to serve re-start serving forks */ - TEST_SIG, /* published by BSP to test the application */ - MAX_PUB_SIG, /* the last published signal */ +//$declare${Shared} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv - HUNGRY_SIG, /* posted direclty to Table from hungry Philo */ - TIMEOUT_SIG, /* used by Philosophers for time events */ - MAX_SIG /* the last signal */ +//${Shared::AppSignals} ...................................................... +enum AppSignals { + EAT_SIG = Q_USER_SIG, // published by Table to let a Philo eat + DONE_SIG, // published by Philo when done eating + PAUSE_SIG, // published by BSP to pause the application + SERVE_SIG, // published by BSP to serve re-start serving forks + TEST_SIG, // published by BSP to test the application + MAX_PUB_SIG, // the last published signal + + TIMEOUT_SIG, // posted by time event to Philo + HUNGRY_SIG, // posted by hungry Philo to Table + MAX_SIG // the last signal }; -enum { - N_PHILO = 5 /* number of Philos */ -}; +//${Shared::produce_sig_dict} ................................................ +#ifdef Q_SPY +static inline void produce_sig_dict(void) { + QS_SIG_DICTIONARY(EAT_SIG, (void *)0); + QS_SIG_DICTIONARY(DONE_SIG, (void *)0); + QS_SIG_DICTIONARY(PAUSE_SIG, (void *)0); + QS_SIG_DICTIONARY(SERVE_SIG, (void *)0); + QS_SIG_DICTIONARY(TEST_SIG, (void *)0); -/*$declare${Cont::TableEvt} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ + QS_SIG_DICTIONARY(TIMEOUT_SIG, (void *)0); + QS_SIG_DICTIONARY(HUNGRY_SIG, (void *)0); +} +#endif // def Q_SPY -/*${Cont::TableEvt} ........................................................*/ +//${Shared::N_PHILO} ......................................................... +#define N_PHILO ((uint8_t)5U) + +//${Shared::TableEvt} ........................................................ typedef struct { -/* protected: */ +// protected: QEvt super; -/* public: */ - uint8_t philoNum; +// public: + uint8_t philoId; } TableEvt; -/*$enddecl${Cont::TableEvt} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*$declare${Cont::Table_ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/*${Cont::Table_ctor} ......................................................*/ -void Table_ctor(void); -/*$enddecl${Cont::Table_ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*$declare${Cont::AO_Table} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +// public: -/*${Cont::AO_Table} ........................................................*/ +#ifdef QEVT_DYN_CTOR +static inline TableEvt * TableEvt_ctor(TableEvt * const me, + uint8_t id) +{ + if (me != (TableEvt *)0) { + // don't call QEvt_ctor() because the initialization of all + // QEvt attributes is already done in QF_QF_newX_() + me->philoId = id; + } + return me; +} +#endif // def QEVT_DYN_CTOR + +//${Shared::AO_Table} ........................................................ extern QActive * const AO_Table; -/*$enddecl${Cont::AO_Table} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*$declare${Comp::CompTimeEvt} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//${Shared::Table_ctor} ...................................................... +void Table_ctor(void); +//$enddecl${Shared} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -/*${Comp::CompTimeEvt} .....................................................*/ +//$declare${Comp::CompTimeEvt} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${Comp::CompTimeEvt} ....................................................... typedef struct { -/* protected: */ +// protected: QTimeEvt super; -/* public: */ +// public: uint16_t compNum; } CompTimeEvt; -/* public: */ +// public: void CompTimeEvt_ctor(CompTimeEvt * const me, QActive * act, uint16_t num, enum_t const sig, uint_fast8_t const tickRate); -/*$enddecl${Comp::CompTimeEvt} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*$declare${Comp::SM_Philo[N_PHILO]} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//$enddecl${Comp::CompTimeEvt} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +//$declare${Comp::SM_Philo[N_PHILO]} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/*${Comp::SM_Philo[N_PHILO]} ...............................................*/ -extern QHsm * const SM_Philo[N_PHILO]; -/*$enddecl${Comp::SM_Philo[N_PHILO]} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*$declare${Comp::Philo_ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//${Comp::SM_Philo[N_PHILO]} ................................................. +extern QAsm * const SM_Philo[N_PHILO]; +//$enddecl${Comp::SM_Philo[N_PHILO]} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +//$declare${Comp::Philo_ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/*${Comp::Philo_ctor} ......................................................*/ +//${Comp::Philo_ctor} ........................................................ void Philo_ctor(uint8_t n); -/*$enddecl${Comp::Philo_ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$enddecl${Comp::Philo_ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -#endif /* DPP_H */ +#endif // DPP_H_ diff --git a/examples/qutest/dpp-comp/src/philo.c b/examples/qutest/dpp-comp/src/philo.c index 5bbf3e92..904b17e2 100644 --- a/examples/qutest/dpp-comp/src/philo.c +++ b/examples/qutest/dpp-comp/src/philo.c @@ -1,79 +1,85 @@ -/*$file${src::philo.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* -* Model: dpp-comp.qm -* File: ${src::philo.c} -* -* This code has been generated by QM 5.2.4 . -* DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. -* -* SPDX-License-Identifier: GPL-3.0-or-later -* -* This generated code is open source software: you can redistribute it under -* the terms of the GNU General Public License as published by the Free -* Software Foundation. -* -* This code is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -* more details. -* -* NOTE: -* Alternatively, this generated code may be distributed under the terms -* of Quantum Leaps commercial licenses, which expressly supersede the GNU -* General Public License and are specifically designed for licensees -* interested in retaining the proprietary status of their code. -* -* Contact information: -* -* -*/ -/*$endhead${src::philo.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$file${.::philo.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// +// Model: dpp-comp.qm +// File: ${.::philo.c} +// +// This code has been generated by QM 5.3.0 . +// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. +// +// SPDX-License-Identifier: GPL-3.0-or-later +// +// This generated code is open source software: you can redistribute it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation. +// +// This code is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// NOTE: +// Alternatively, this generated code may be distributed under the terms +// of Quantum Leaps commercial licenses, which expressly supersede the GNU +// General Public License and are specifically designed for licensees +// interested in retaining the proprietary status of their code. +// +// Contact information: +// +// +// +//$endhead${.::philo.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ #include "qpc.h" #include "dpp.h" #include "bsp.h" //Q_DEFINE_THIS_FILE -/*$declare${Comp::Philo} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//$declare${Comp::Philo} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/*${Comp::Philo} ...........................................................*/ +//${Comp::Philo} ............................................................. typedef struct Philo { -/* protected: */ +// protected: QHsm super; -/* public: */ +// public: -/* private: */ +// private: CompTimeEvt timeEvt; } Philo; + extern Philo Philo_inst[N_PHILO]; -/* protected: */ +// public: +static inline uint8_t Philo_getId(Philo * const me) { + return (uint8_t)(me - &Philo_inst[0]); +} + +// protected: static QState Philo_initial(Philo * const me, void const * const par); static QState Philo_thinking(Philo * const me, QEvt const * const e); static QState Philo_hungry(Philo * const me, QEvt const * const e); static QState Philo_eating(Philo * const me, QEvt const * const e); -/*$enddecl${Comp::Philo} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$enddecl${Comp::Philo} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -/* helper macros to provide a randomized think time for Philos */ +// helper macros to provide a randomized think time for Philos #define THINK_TIME \ (QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + (BSP_TICKS_PER_SEC/2U)) #define EAT_TIME \ (QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + BSP_TICKS_PER_SEC) -/* definition of the whole "Comp" package */ -/*$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* Check for the minimum required QP version */ -#if (QP_VERSION < 700U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) -#error qpc version 7.0.0 or higher required +// definition of the whole "Comp" package +//$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// Check for the minimum required QP version +#if (QP_VERSION < 730U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) +#error qpc version 7.3.0 or higher required #endif -/*$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -/*$define${Comp} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//$define${Comp} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/*${Comp::CompTimeEvt} .....................................................*/ +//${Comp::CompTimeEvt} ....................................................... -/*${Comp::CompTimeEvt::ctor} ...............................................*/ +//${Comp::CompTimeEvt::ctor} ................................................. void CompTimeEvt_ctor(CompTimeEvt * const me, QActive * act, uint16_t num, @@ -84,23 +90,22 @@ void CompTimeEvt_ctor(CompTimeEvt * const me, me->compNum = num; } -/*${Comp::Philo} ...........................................................*/ +//${Comp::Philo} ............................................................. Philo Philo_inst[N_PHILO]; -/*${Comp::Philo::SM} .......................................................*/ +//${Comp::Philo::SM} ......................................................... static QState Philo_initial(Philo * const me, void const * const par) { - /*${Comp::Philo::SM::initial} */ - (void)par; /* unused parameter */ + //${Comp::Philo::SM::initial} + Q_UNUSED_PAR(par); #ifdef Q_SPY - uint8_t n = (uint8_t)(me - &Philo_inst[0]); - QS_OBJ_ARR_DICTIONARY(&Philo_inst[n], n); - QS_OBJ_ARR_DICTIONARY(&Philo_inst[n].timeEvt, n); + uint8_t id = (uint8_t)(me - &Philo_inst[0]); + QS_OBJ_ARR_DICTIONARY(&Philo_inst[id], id); + QS_OBJ_ARR_DICTIONARY(&Philo_inst[id].timeEvt, id); #endif - /* the following code outputs the "fun-dictionaries" only once for - * all Philo instances, as opposed to repeat them for every instance. - */ + // the following code outputs the "fun-dictionaries" only once for + // all Philo instances, as opposed to repeat them for every instance. static bool registered = false; if (!registered) { registered = true; @@ -113,28 +118,28 @@ static QState Philo_initial(Philo * const me, void const * const par) { return Q_TRAN(&Philo_thinking); } -/*${Comp::Philo::SM::thinking} .............................................*/ +//${Comp::Philo::SM::thinking} ............................................... static QState Philo_thinking(Philo * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${Comp::Philo::SM::thinking} */ + //${Comp::Philo::SM::thinking} case Q_ENTRY_SIG: { QTimeEvt_armX(&me->timeEvt.super, THINK_TIME, 0U); status_ = Q_HANDLED(); break; } - /*${Comp::Philo::SM::thinking} */ + //${Comp::Philo::SM::thinking} case Q_EXIT_SIG: { QTimeEvt_disarm(&me->timeEvt.super); status_ = Q_HANDLED(); break; } - /*${Comp::Philo::SM::thinking::TIMEOUT} */ + //${Comp::Philo::SM::thinking::TIMEOUT} case TIMEOUT_SIG: { status_ = Q_TRAN(&Philo_hungry); break; } - /*${Comp::Philo::SM::thinking::TEST} */ + //${Comp::Philo::SM::thinking::TEST} case TEST_SIG: { status_ = Q_HANDLED(); break; @@ -147,20 +152,24 @@ static QState Philo_thinking(Philo * const me, QEvt const * const e) { return status_; } -/*${Comp::Philo::SM::hungry} ...............................................*/ +//${Comp::Philo::SM::hungry} ................................................. static QState Philo_hungry(Philo * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${Comp::Philo::SM::hungry} */ + //${Comp::Philo::SM::hungry} case Q_ENTRY_SIG: { - /* asynchronously post event to the Container */ + // asynchronously post event to the Container + #ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, HUNGRY_SIG, Philo_getId(me)); + #else TableEvt *pe = Q_NEW(TableEvt, HUNGRY_SIG); - pe->philoNum = (uint8_t)(me - &Philo_inst[0]); + pe->philoId = Philo_getId(me); + #endif QACTIVE_POST_LIFO(AO_Table, &pe->super); status_ = Q_HANDLED(); break; } - /*${Comp::Philo::SM::hungry::EAT} */ + //${Comp::Philo::SM::hungry::EAT} case EAT_SIG: { status_ = Q_TRAN(&Philo_eating); break; @@ -173,28 +182,32 @@ static QState Philo_hungry(Philo * const me, QEvt const * const e) { return status_; } -/*${Comp::Philo::SM::eating} ...............................................*/ +//${Comp::Philo::SM::eating} ................................................. static QState Philo_eating(Philo * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${Comp::Philo::SM::eating} */ + //${Comp::Philo::SM::eating} case Q_ENTRY_SIG: { QTimeEvt_armX(&me->timeEvt.super, EAT_TIME, 0U); status_ = Q_HANDLED(); break; } - /*${Comp::Philo::SM::eating} */ + //${Comp::Philo::SM::eating} case Q_EXIT_SIG: { QTimeEvt_disarm(&me->timeEvt.super); - /* asynchronously post event to the Container */ + // asynchronously post event to the Container + #ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, DONE_SIG, Philo_getId(me)); + #else TableEvt *pe = Q_NEW(TableEvt, DONE_SIG); - pe->philoNum = (uint8_t)(me - &Philo_inst[0]); + pe->philoId = Philo_getId(me); + #endif QACTIVE_POST_LIFO(AO_Table, &pe->super); status_ = Q_HANDLED(); break; } - /*${Comp::Philo::SM::eating::TIMEOUT} */ + //${Comp::Philo::SM::eating::TIMEOUT} case TIMEOUT_SIG: { status_ = Q_TRAN(&Philo_thinking); break; @@ -207,19 +220,19 @@ static QState Philo_eating(Philo * const me, QEvt const * const e) { return status_; } -/*${Comp::SM_Philo[N_PHILO]} ...............................................*/ -QHsm * const SM_Philo[N_PHILO] = { /* opaque pointers to Philo instances */ - &Philo_inst[0].super, - &Philo_inst[1].super, - &Philo_inst[2].super, - &Philo_inst[3].super, - &Philo_inst[4].super +//${Comp::SM_Philo[N_PHILO]} ................................................. +QAsm * const SM_Philo[N_PHILO] = { // opaque pointers to Philo instances + (QAsm *)&Philo_inst[0], + (QAsm *)&Philo_inst[1], + (QAsm *)&Philo_inst[2], + (QAsm *)&Philo_inst[3], + (QAsm *)&Philo_inst[4] }; -/*${Comp::Philo_ctor} ......................................................*/ +//${Comp::Philo_ctor} ........................................................ void Philo_ctor(uint8_t n) { Philo *me = &Philo_inst[n]; QHsm_ctor(&me->super, Q_STATE_CAST(&Philo_initial)); CompTimeEvt_ctor(&me->timeEvt, AO_Table, n, TIMEOUT_SIG, 0U); } -/*$enddef${Comp} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$enddef${Comp} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/examples/qutest/dpp-comp/src/table.c b/examples/qutest/dpp-comp/src/table.c index 037af213..bef99757 100644 --- a/examples/qutest/dpp-comp/src/table.c +++ b/examples/qutest/dpp-comp/src/table.c @@ -1,83 +1,114 @@ -/*$file${src::table.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* -* Model: dpp-comp.qm -* File: ${src::table.c} -* -* This code has been generated by QM 5.2.4 . -* DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. -* -* SPDX-License-Identifier: GPL-3.0-or-later -* -* This generated code is open source software: you can redistribute it under -* the terms of the GNU General Public License as published by the Free -* Software Foundation. -* -* This code is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -* more details. -* -* NOTE: -* Alternatively, this generated code may be distributed under the terms -* of Quantum Leaps commercial licenses, which expressly supersede the GNU -* General Public License and are specifically designed for licensees -* interested in retaining the proprietary status of their code. -* -* Contact information: -* -* -*/ -/*$endhead${src::table.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$file${.::table.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// +// Model: dpp-comp.qm +// File: ${.::table.c} +// +// This code has been generated by QM 5.3.0 . +// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. +// +// SPDX-License-Identifier: GPL-3.0-or-later +// +// This generated code is open source software: you can redistribute it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation. +// +// This code is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// NOTE: +// Alternatively, this generated code may be distributed under the terms +// of Quantum Leaps commercial licenses, which expressly supersede the GNU +// General Public License and are specifically designed for licensees +// interested in retaining the proprietary status of their code. +// +// Contact information: +// +// +// +//$endhead${.::table.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ #include "qpc.h" #include "dpp.h" #include "bsp.h" Q_DEFINE_THIS_FILE -/*$declare${Cont::Table} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +// helper function to provide the RIGHT neighbor of a Philo[n] +static inline uint8_t right(uint8_t const n) { + return (uint8_t)((n + (N_PHILO - 1U)) % N_PHILO); +} -/*${Cont::Table} ...........................................................*/ +// helper function to provide the LEFT neighbor of a Philo[n] +static inline uint8_t left(uint8_t const n) { + return (uint8_t)((n + 1U) % N_PHILO); +} + +#define FREE ((uint8_t)0U) +#define USED ((uint8_t)1U) + +#define THINKING "thinking" +#define HUNGRY "hungry " +#define EATING "eating " + +//$declare${Cont::Table} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${Cont::Table} ............................................................. typedef struct Table { -/* protected: */ +// protected: QActive super; -/* public: */ +// public: -/* private: */ +// private: uint8_t fork[N_PHILO]; uint8_t isHungry[N_PHILO]; } Table; extern Table Table_inst; -/* protected: */ +// protected: static QState Table_initial(Table * const me, void const * const par); static QState Table_active(Table * const me, QEvt const * const e); static QState Table_serving(Table * const me, QEvt const * const e); static QState Table_paused(Table * const me, QEvt const * const e); -/*$enddecl${Cont::Table} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$enddecl${Cont::Table} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -#define RIGHT(n_) ((uint8_t)(((n_) + (N_PHILO - 1U)) % N_PHILO)) -#define LEFT(n_) ((uint8_t)(((n_) + 1U) % N_PHILO)) -#define FREE ((uint8_t)0) -#define USED ((uint8_t)1) - -/* definition of the whole "Cont" package */ -/*$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* Check for the minimum required QP version */ -#if (QP_VERSION < 700U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) -#error qpc version 7.0.0 or higher required +//$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// Check for the minimum required QP version +#if (QP_VERSION < 730U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) +#error qpc version 7.3.0 or higher required #endif -/*$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -/*$define${Cont} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//$define${Shared::Table_ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/*${Cont::Table} ...........................................................*/ +//${Shared::Table_ctor} ...................................................... +void Table_ctor(void) { + Table *me = &Table_inst; + QActive_ctor(&me->super, Q_STATE_CAST(&Table_initial)); + + for (uint8_t n = 0U; n < N_PHILO; ++n) { + Philo_ctor(n); // create the Philo component + + me->fork[n] = FREE; + me->isHungry[n] = 0U; + } +} +//$enddef${Shared::Table_ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +//$define${Shared::AO_Table} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${Shared::AO_Table} ........................................................ +QActive * const AO_Table = &Table_inst.super; +//$enddef${Shared::AO_Table} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +//$define${Cont} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${Cont::Table} ............................................................. Table Table_inst; -/*${Cont::Table::SM} .......................................................*/ +//${Cont::Table::SM} ......................................................... static QState Table_initial(Table * const me, void const * const par) { - /*${Cont::Table::SM::initial} */ - (void)par; /* unused parameter */ + //${Cont::Table::SM::initial} + (void)par; // unused parameter QS_OBJ_DICTIONARY(&Table_inst); @@ -89,7 +120,7 @@ static QState Table_initial(Table * const me, void const * const par) { me->fork[n] = FREE; me->isHungry[n] = 0U; - QHSM_INIT(SM_Philo[n], (void *)0, QS_AP_ID + n); + QASM_INIT(SM_Philo[n], (void *)0, QS_AP_ID + n); BSP_displayPhilStat(n, "thinking"); } @@ -100,24 +131,24 @@ static QState Table_initial(Table * const me, void const * const par) { return Q_TRAN(&Table_serving); } -/*${Cont::Table::SM::active} ...............................................*/ +//${Cont::Table::SM::active} ................................................. static QState Table_active(Table * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${Cont::Table::SM::active::TIMEOUT} */ + //${Cont::Table::SM::active::TIMEOUT} case TIMEOUT_SIG: { uint16_t n = Q_EVT_CAST(CompTimeEvt)->compNum; - QHSM_DISPATCH(SM_Philo[n], e, QS_AP_ID + n); + QASM_DISPATCH(SM_Philo[n], e, QS_AP_ID + n); status_ = Q_HANDLED(); break; } - /*${Cont::Table::SM::active::EAT} */ + //${Cont::Table::SM::active::EAT} case EAT_SIG: { Q_ERROR(); status_ = Q_HANDLED(); break; } - /*${Cont::Table::SM::active::TEST} */ + //${Cont::Table::SM::active::TEST} case TEST_SIG: { status_ = Q_HANDLED(); break; @@ -130,25 +161,26 @@ static QState Table_active(Table * const me, QEvt const * const e) { return status_; } -/*${Cont::Table::SM::active::serving} ......................................*/ +//${Cont::Table::SM::active::serving} ........................................ static QState Table_serving(Table * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${Cont::Table::SM::active::serving} */ + //${Cont::Table::SM::active::serving} case Q_ENTRY_SIG: { - for (uint8_t n = 0U; n < N_PHILO; ++n) { /* give permissions to eat... */ + for (uint8_t n = 0U; n < N_PHILO; ++n) { // give permissions to eat... if ((me->isHungry[n] != 0U) - && (me->fork[LEFT(n)] == FREE) + && (me->fork[left(n)] == FREE) && (me->fork[n] == FREE)) { - me->fork[LEFT(n)] = USED; + me->fork[left(n)] = USED; me->fork[n] = USED; - /* synchronoulsy dispatch EAT event to the Philo component */ - TableEvt evt; - evt.super.sig = EAT_SIG; - evt.philoNum = n; - QHSM_DISPATCH(SM_Philo[n], &evt.super, QS_AP_ID + n); + // synchronously dispatch EAT event to the Philo component + TableEvt const evt = { + QEVT_INITIALIZER(EAT_SIG), + .philoId = n + }; + QASM_DISPATCH(SM_Philo[n], &evt.super, QS_AP_ID + n); me->isHungry[n] = 0U; BSP_displayPhilStat(n, "eating "); @@ -157,86 +189,90 @@ static QState Table_serving(Table * const me, QEvt const * const e) { status_ = Q_HANDLED(); break; } - /*${Cont::Table::SM::active::serving::HUNGRY} */ + //${Cont::Table::SM::active::serving::HUNGRY} case HUNGRY_SIG: { - /* find the index of the Philo from the event */ - uint8_t n = Q_EVT_CAST(TableEvt)->philoNum; - /* philo ID must be in range and he must be not hungry */ + // find the index of the Philo from the event + uint8_t n = Q_EVT_CAST(TableEvt)->philoId; + // philo ID must be in range and he must be not hungry Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); BSP_displayPhilStat(n, "hungry "); - uint8_t m = LEFT(n); - /*${Cont::Table::SM::active::serving::HUNGRY::[bothfree]} */ + uint8_t m = left(n); + //${Cont::Table::SM::active::serving::HUNGRY::[bothfree]} if ((me->fork[m] == FREE) && (me->fork[n] == FREE)) { me->fork[m] = USED; me->fork[n] = USED; - /* synchronoulsy dispatch EAT event to the Philo component */ - TableEvt evt; - evt.super.sig = EAT_SIG; - evt.philoNum = n; - QHSM_DISPATCH(SM_Philo[n], &evt.super, QS_AP_ID + n); + // synchronously dispatch EAT event to the Philo component + TableEvt const evt = { + QEVT_INITIALIZER(EAT_SIG), + .philoId = n + }; + QASM_DISPATCH(SM_Philo[n], &evt.super, QS_AP_ID + n); BSP_displayPhilStat(n, "eating "); status_ = Q_HANDLED(); } - /*${Cont::Table::SM::active::serving::HUNGRY::[else]} */ + //${Cont::Table::SM::active::serving::HUNGRY::[else]} else { me->isHungry[n] = 1U; status_ = Q_HANDLED(); } break; } - /*${Cont::Table::SM::active::serving::DONE} */ + //${Cont::Table::SM::active::serving::DONE} case DONE_SIG: { - /* find the index of the Philo from the event */ - uint8_t n = Q_EVT_CAST(TableEvt)->philoNum; - /* philo ID must be in range and he must be not hungry */ + // find the index of the Philo from the event + uint8_t n = Q_EVT_CAST(TableEvt)->philoId; + // philo ID must be in range and he must be not hungry Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); BSP_displayPhilStat(n, "thinking"); - uint8_t m = LEFT(n); - /* both forks of Phil[n] must be used */ + uint8_t m = left(n); + // both forks of Phil[n] must be used Q_ASSERT((me->fork[n] == USED) && (me->fork[m] == USED)); me->fork[m] = FREE; me->fork[n] = FREE; - m = RIGHT(n); /* check the right neighbor */ + m = right(n); // check the right neighbor - TableEvt evt; if ((me->isHungry[m] != 0U) && (me->fork[m] == FREE)) { me->fork[n] = USED; me->fork[m] = USED; me->isHungry[m] = 0U; - /* synchronoulsy dispatch EAT event to the Philo component */ - evt.super.sig = EAT_SIG; - evt.philoNum = m; - QHSM_DISPATCH(SM_Philo[m], &evt.super, QS_AP_ID + m); + // synchronously dispatch EAT event to the Philo component + TableEvt const evt = { + QEVT_INITIALIZER(EAT_SIG), + .philoId = m + }; + QASM_DISPATCH(SM_Philo[m], &evt.super, QS_AP_ID + m); BSP_displayPhilStat(m, "eating "); } - m = LEFT(n); /* check the left neighbor */ - n = LEFT(m); /* left fork of the left neighbor */ + m = left(n); // check the left neighbor + n = left(m); // left fork of the left neighbor if ((me->isHungry[m] != 0U) && (me->fork[n] == FREE)) { me->fork[m] = USED; me->fork[n] = USED; me->isHungry[m] = 0U; - /* synchronoulsy dispatch EAT event to the Philo component */ - evt.super.sig = EAT_SIG; - evt.philoNum = m; - QHSM_DISPATCH(SM_Philo[m], &evt.super, QS_AP_ID + m); + // synchronously dispatch EAT event to the Philo component + TableEvt const evt = { + QEVT_INITIALIZER(EAT_SIG), + .philoId = m + }; + QASM_DISPATCH(SM_Philo[m], &evt.super, QS_AP_ID + m); BSP_displayPhilStat(m, "eating "); } status_ = Q_HANDLED(); break; } - /*${Cont::Table::SM::active::serving::EAT} */ + //${Cont::Table::SM::active::serving::EAT} case EAT_SIG: { Q_ERROR(); status_ = Q_HANDLED(); break; } - /*${Cont::Table::SM::active::serving::PAUSE} */ + //${Cont::Table::SM::active::serving::PAUSE} case PAUSE_SIG: { status_ = Q_TRAN(&Table_paused); break; @@ -249,32 +285,32 @@ static QState Table_serving(Table * const me, QEvt const * const e) { return status_; } -/*${Cont::Table::SM::active::paused} .......................................*/ +//${Cont::Table::SM::active::paused} ......................................... static QState Table_paused(Table * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${Cont::Table::SM::active::paused} */ + //${Cont::Table::SM::active::paused} case Q_ENTRY_SIG: { BSP_displayPaused(1U); status_ = Q_HANDLED(); break; } - /*${Cont::Table::SM::active::paused} */ + //${Cont::Table::SM::active::paused} case Q_EXIT_SIG: { BSP_displayPaused(0U); status_ = Q_HANDLED(); break; } - /*${Cont::Table::SM::active::paused::SERVE} */ + //${Cont::Table::SM::active::paused::SERVE} case SERVE_SIG: { status_ = Q_TRAN(&Table_serving); break; } - /*${Cont::Table::SM::active::paused::HUNGRY} */ + //${Cont::Table::SM::active::paused::HUNGRY} case HUNGRY_SIG: { - /* find the index of the Philo from the event */ - uint8_t n = Q_EVT_CAST(TableEvt)->philoNum; - /* philo ID must be in range and he must be not hungry */ + // find the index of the Philo from the event + uint8_t n = Q_EVT_CAST(TableEvt)->philoId; + // philo ID must be in range and he must be not hungry Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); me->isHungry[n] = 1U; @@ -282,16 +318,16 @@ static QState Table_paused(Table * const me, QEvt const * const e) { status_ = Q_HANDLED(); break; } - /*${Cont::Table::SM::active::paused::DONE} */ + //${Cont::Table::SM::active::paused::DONE} case DONE_SIG: { - /* find the index of the Philo from the event */ - uint8_t n = Q_EVT_CAST(TableEvt)->philoNum; - /* philo ID must be in range and he must be not hungry */ + // find the index of the Philo from the event + uint8_t n = Q_EVT_CAST(TableEvt)->philoId; + // philo ID must be in range and he must be not hungry Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); BSP_displayPhilStat(n, "thinking"); - uint8_t m = LEFT(n); - /* both forks of Phil[n] must be used */ + uint8_t m = left(n); + // both forks of Phil[n] must be used Q_ASSERT((me->fork[n] == USED) && (me->fork[m] == USED)); me->fork[m] = FREE; @@ -306,19 +342,4 @@ static QState Table_paused(Table * const me, QEvt const * const e) { } return status_; } - -/*${Cont::AO_Table} ........................................................*/ -QActive * const AO_Table = &Table_inst.super; /* opaque pointer */ - -/*${Cont::Table_ctor} ......................................................*/ -void Table_ctor(void) { - Table *me = &Table_inst; - QActive_ctor(&me->super, Q_STATE_CAST(&Table_initial)); - - for (uint8_t n = 0U; n < N_PHILO; ++n) { - me->fork[n] = FREE; - me->isHungry[n] = 0U; - Philo_ctor(n); /* create the Philo component */ - } -} -/*$enddef${Cont} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$enddef${Cont} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/examples/qutest/dpp-comp/test_dpp/Makefile b/examples/qutest/dpp-comp/test_dpp/Makefile index c697ac80..7e5a8c91 100644 --- a/examples/qutest/dpp-comp/test_dpp/Makefile +++ b/examples/qutest/dpp-comp/test_dpp/Makefile @@ -80,7 +80,6 @@ endif # C source files... C_SRCS := \ bsp.c \ - main.c \ philo.c \ table.c \ test_dpp.c @@ -92,7 +91,7 @@ LIB_DIRS := LIBS := # defines... -DEFINES := +DEFINES := $(DEF) #----------------------------------------------------------------------------- # add QP/C framework: @@ -220,7 +219,7 @@ all : $(TARGET_EXE) run endif $(TARGET_EXE) : $(C_OBJS_EXT) $(CPP_OBJS_EXT) - $(CC) $(CFLAGS) $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o + $(CC) $(CFLAGS) $(QPC)/src/qs/qstamp.c -o $(BIN_DIR)/qstamp.o $(LINK) $(LINKFLAGS) $(LIB_DIRS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) run : $(TARGET_EXE) diff --git a/examples/qutest/dpp-comp/test_dpp/main.c b/examples/qutest/dpp-comp/test_dpp/main.c deleted file mode 100644 index 6a528457..00000000 --- a/examples/qutest/dpp-comp/test_dpp/main.c +++ /dev/null @@ -1,69 +0,0 @@ -/***************************************************************************** -* Product: DPP example -* Last updated for version 7.1.1 -* Last updated on 2022-09-22 -* -* Q u a n t u m L e a P s -* ------------------------ -* Modern Embedded Software -* -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* -* -*****************************************************************************/ -#include "qpc.h" -#include "dpp.h" -#include "bsp.h" - -Q_DEFINE_THIS_FILE - -/*..........................................................................*/ -int main(int argc, char *argv[]) { - static QEvt const *tableQueueSto[N_PHILO]; - static QSubscrList subscrSto[MAX_PUB_SIG]; - static QF_MPOOL_EL(TableEvt) smlPoolSto[2*N_PHILO]; /* small pool */ - - QF_init(); /* initialize the framework and the underlying RT kernel */ - BSP_init(argc, argv); /* initialize the Board Support Package */ - - /* pause execution of the test and wait for the test script to continue */ - QS_TEST_PAUSE(); - - /* initialize publish-subscribe... */ - QF_psInit(subscrSto, Q_DIM(subscrSto)); - - /* initialize event pools... */ - QF_poolInit(smlPoolSto, sizeof(smlPoolSto), sizeof(smlPoolSto[0])); - - Table_ctor(); /* explicit constructor or the Table AO */ - QACTIVE_START(AO_Table, /* AO to start */ - 1U, /* QF-priority/preemption-thre. */ - tableQueueSto, /* event queue storage */ - Q_DIM(tableQueueSto), /* queue length [events] */ - (void *)0, /* stack storage (not used) */ - 0U, /* size of the stack [bytes] */ - (void *)0); /* initialization param */ - - return QF_run(); /* run the QF application */ -} - diff --git a/examples/qutest/dpp-comp/test_dpp/make_efm32 b/examples/qutest/dpp-comp/test_dpp/make_efm32 index 036194a1..516bc69e 100644 --- a/examples/qutest/dpp-comp/test_dpp/make_efm32 +++ b/examples/qutest/dpp-comp/test_dpp/make_efm32 @@ -1,7 +1,7 @@ ############################################################################## # Product: Makefile for QP/C on EMF32, QUTEST, GNU-ARM -# Last Updated for Version: 7.2.0 -# Date of the Last Update: 2022-12-21 +// Last updated for version 7.3.0 +// Last updated on 2023-07-27 # # Q u a n t u m L e a P s # ------------------------ @@ -99,7 +99,6 @@ ASM_SRCS := # C source files C_SRCS := \ test_dpp.c \ - main.c \ philo.c \ table.c \ bsp.c \ @@ -255,7 +254,7 @@ $(TARGET_BIN) : $(TARGET_ELF) $(FLASH) $@ $(TARGET_ELF) : $(ASM_OBJS_EXT) $(C_OBJS_EXT) $(CPP_OBJS_EXT) - $(CC) $(CFLAGS) $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o + $(CC) $(CFLAGS) $(QPC)/src/qs/qstamp.c -o $(BIN_DIR)/qstamp.o $(LINK) $(LINKFLAGS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) flash : diff --git a/examples/qutest/dpp-comp/test_dpp/make_nucleo-l053r8 b/examples/qutest/dpp-comp/test_dpp/make_nucleo-l053r8 index d616f928..8d5846a3 100644 --- a/examples/qutest/dpp-comp/test_dpp/make_nucleo-l053r8 +++ b/examples/qutest/dpp-comp/test_dpp/make_nucleo-l053r8 @@ -1,7 +1,7 @@ ############################################################################## # Product: Makefile for QP/C on NUCLEO-L053R8 board, QUTEST, GNU-ARM -# Last Updated for Version: 7.2.0 -# Date of the Last Update: 2022-12-21 +// Last updated for version 7.3.0 +// Last updated on 2023-07-27 # # Q u a n t u m L e a P s # ------------------------ @@ -99,7 +99,6 @@ ASM_SRCS := # C source files C_SRCS := \ test_dpp.c \ - main.c \ philo.c \ table.c \ bsp.c \ @@ -255,7 +254,7 @@ $(TARGET_BIN) : $(TARGET_ELF) $(SLEEP) 2 $(TARGET_ELF) : $(ASM_OBJS_EXT) $(C_OBJS_EXT) $(CPP_OBJS_EXT) - $(CC) $(CFLAGS) $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o + $(CC) $(CFLAGS) $(QPC)/src/qs/qstamp.c -o $(BIN_DIR)/qstamp.o $(LINK) $(LINKFLAGS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) flash : diff --git a/examples/qutest/dpp-comp/test_dpp/make_posix b/examples/qutest/dpp-comp/test_dpp/make_posix index 5731bfab..5fea2375 100644 --- a/examples/qutest/dpp-comp/test_dpp/make_posix +++ b/examples/qutest/dpp-comp/test_dpp/make_posix @@ -1,7 +1,7 @@ ############################################################################## # Product: Makefile for QUTEST; QP/C on POSIX *Target* -# Last Updated for Version: 7.0.1 -# Date of the Last Update: 2022-05-23 +// Last updated for version 7.3.0 +// Last updated on 2023-07-27 # # Q u a n t u m L e a P s # ------------------------ @@ -78,7 +78,6 @@ endif # C source files... C_SRCS := \ bsp.c \ - main.c \ philo.c \ table.c \ test_dpp.c @@ -185,7 +184,7 @@ all : $(TARGET_EXE) run endif $(TARGET_EXE) : $(C_OBJS_EXT) $(CPP_OBJS_EXT) - $(CC) $(CFLAGS) $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o + $(CC) $(CFLAGS) $(QPC)/src/qs/qstamp.c -o $(BIN_DIR)/qstamp.o $(LINK) $(LINKFLAGS) $(LIB_DIRS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) # run the test fixture on a POSIX target in a loop, so that it is re-started diff --git a/examples/qutest/dpp-comp/test_dpp/make_tm4c123 b/examples/qutest/dpp-comp/test_dpp/make_tm4c123 index 2840c76b..00ea96b3 100644 --- a/examples/qutest/dpp-comp/test_dpp/make_tm4c123 +++ b/examples/qutest/dpp-comp/test_dpp/make_tm4c123 @@ -1,7 +1,7 @@ ############################################################################## # Product: Makefile for QP/C on TM4C123, QUTEST, GNU-ARM -# Last Updated for Version: 7.2.0 -# Date of the Last Update: 2022-12-21 +// Last updated for version 7.3.0 +// Last updated on 2023-07-27 # # Q u a n t u m L e a P s # ------------------------ @@ -99,7 +99,6 @@ ASM_SRCS := # C source files C_SRCS := \ test_dpp.c \ - main.c \ philo.c \ table.c \ bsp.c \ @@ -256,7 +255,7 @@ $(TARGET_BIN) : $(TARGET_ELF) @pause $(TARGET_ELF) : $(ASM_OBJS_EXT) $(C_OBJS_EXT) $(CPP_OBJS_EXT) - $(CC) $(CFLAGS) $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o + $(CC) $(CFLAGS) $(QPC)/src/qs/qstamp.c -o $(BIN_DIR)/qstamp.o $(LINK) $(LINKFLAGS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) flash : diff --git a/examples/qutest/dpp-comp/test_dpp/test_dpp.c b/examples/qutest/dpp-comp/test_dpp/test_dpp.c index 816c1b82..3910ccc8 100644 --- a/examples/qutest/dpp-comp/test_dpp/test_dpp.c +++ b/examples/qutest/dpp-comp/test_dpp/test_dpp.c @@ -1,71 +1,100 @@ -/***************************************************************************** -* Product: QUTEST fixture for the DPP components -* Last updated for: @ref qpc_7_0_0 -* Date of the Last Update: 2022-02-16 -* -* Q u a n t u m L e a P s -* ------------------------ -* Modern Embedded Software -* -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* -* -*****************************************************************************/ +//============================================================================ +// Product: QUTEST fixture for the DPP components +// Last updated for version 7.3.0 +// Last updated on 2023-08-22 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// This program is open source software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Alternatively, this program may be distributed and modified under the +// terms of Quantum Leaps commercial licenses, which expressly supersede +// the GNU General Public License and are specifically designed for +// licensees interested in retaining the proprietary status of their code. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Contact information: +// +// +//============================================================================ #include "qpc.h" #include "bsp.h" #include "dpp.h" -//#include "safe_std.h" /* portable "safe" / facilities */ +//#include "safe_std.h" // portable "safe" / facilities //Q_DEFINE_THIS_FILE -/*..........................................................................*/ +//============================================================================ +int main() { + QF_init(); // initialize the framework and the underlying RT kernel + BSP_init(); // initialize the BSP + + // pause execution of the test and wait for the test script to continue + QS_TEST_PAUSE(); + + // initialize event pools... + static QF_MPOOL_EL(TableEvt) smlPoolSto[2*N_PHILO]; // small pool + QF_poolInit(smlPoolSto, sizeof(smlPoolSto), sizeof(smlPoolSto[0])); + + // initialize publish-subscribe... + static QSubscrList subscrSto[MAX_PUB_SIG]; + QActive_psInit(subscrSto, Q_DIM(subscrSto)); + + // start the active objects... + static QEvt const *tableQueueSto[N_PHILO]; + Table_ctor(); // instantiate the Table active object + QACTIVE_START(AO_Table, // AO to start + N_PHILO + 1U, // QF-priority + tableQueueSto, // event queue storage + Q_DIM(tableQueueSto), // queue length [events] + (void *)0, // stack storage (not used) + 0U, // size of the stack [bytes] + (void *)0); // initialization param + + return QF_run(); // run the QF application +} + +//============================================================================ void QS_onTestSetup(void) { //PRINTF_S("%s\n", "QS_onTestSetup"); } void QS_onTestTeardown(void) { //PRINTF_S("%s\n", "QS_onTestTeardown"); } - -/*..........................................................................*/ -/*! callback function to execute user commands */ +//............................................................................ +// callback function to execute user commands void QS_onCommand(uint8_t cmdId, uint32_t param1, uint32_t param2, uint32_t param3) { - (void)cmdId; - (void)param1; - (void)param2; - (void)param3; + Q_UNUSED_PAR(cmdId); + Q_UNUSED_PAR(param1); + Q_UNUSED_PAR(param2); + Q_UNUSED_PAR(param3); switch (cmdId) { case 0U: { - QEvt const e_pause = { PAUSE_SIG, 0U, 0U }; - QHSM_DISPATCH(&AO_Table->super, &e_pause, 0U); + QEvt const e_pause = QEVT_INITIALIZER( PAUSE_SIG); + QASM_DISPATCH(AO_Table, &e_pause, 0U); break; } case 1U: { - QEvt const e_serve = { SERVE_SIG, 0U, 0U }; - QHSM_DISPATCH(&AO_Table->super, &e_serve, 0U); + QEvt const e_serve = QEVT_INITIALIZER(SERVE_SIG); + QASM_DISPATCH(AO_Table, &e_serve, 0U); break; } default: @@ -73,28 +102,28 @@ void QS_onCommand(uint8_t cmdId, } } -/****************************************************************************/ -/*! Host callback function to "massage" the event, if necessary */ +//============================================================================ +// Host callback function to "massage" the event, if necessary void QS_onTestEvt(QEvt *e) { (void)e; -#ifdef Q_HOST /* is this test compiled for a desktop Host computer? */ -#else /* embedded Target */ -#endif /* embedded Target */ +#ifdef Q_HOST // is this test compiled for a desktop Host computer? +#else // embedded Target +#endif // embedded Target } -/*..........................................................................*/ -/*! callback function to output the posted QP events (not used here) */ +//............................................................................ +//! callback function to output the posted QP events (not used here) void QS_onTestPost(void const *sender, QActive *recipient, QEvt const *e, bool status) { - (void)sender; - (void)status; + Q_UNUSED_PAR(sender); + Q_UNUSED_PAR(status); switch (e->sig) { case EAT_SIG: case DONE_SIG: case HUNGRY_SIG: - QS_BEGIN_ID(QUTEST_ON_POST, 0U) /* application-specific record */ + QS_BEGIN_ID(QUTEST_ON_POST, 0U) // application-specific record QS_SIG(e->sig, recipient); - QS_U8(0, Q_EVT_CAST(TableEvt)->philoNum); + QS_U8(0, Q_EVT_CAST(TableEvt)->philoId); QS_END() break; default: diff --git a/examples/qutest/dpp-comp/test_philo/Makefile b/examples/qutest/dpp-comp/test_philo/Makefile index 828b7def..907cde92 100644 --- a/examples/qutest/dpp-comp/test_philo/Makefile +++ b/examples/qutest/dpp-comp/test_philo/Makefile @@ -218,7 +218,7 @@ all : $(TARGET_EXE) run endif $(TARGET_EXE) : $(C_OBJS_EXT) $(CPP_OBJS_EXT) - $(CC) $(CFLAGS) $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o + $(CC) $(CFLAGS) $(QPC)/src/qs/qstamp.c -o $(BIN_DIR)/qstamp.o $(LINK) $(LINKFLAGS) $(LIB_DIRS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) run : $(TARGET_EXE) diff --git a/examples/qutest/dpp-comp/test_philo/test_init.py b/examples/qutest/dpp-comp/test_philo/test_init.py index b141d88c..83e50fe6 100644 --- a/examples/qutest/dpp-comp/test_philo/test_init.py +++ b/examples/qutest/dpp-comp/test_philo/test_init.py @@ -8,30 +8,30 @@ def on_reset(): continue_test() expect("===RTC===> St-Init Obj=Philo_inst[0],State=QHsm_top->Philo_thinking") expect("@timestamp BSP_CALL BSP_random *") - expect("@timestamp TE0-Arm Obj=Philo_inst[0].timeEvt,AO=Table_inst,Tim=*,Int=0") + expect("@timestamp TE0-Arm Obj=Philo_inst[0].timeEvt,AO=Table_dummy,Tim=*,Int=0") expect("===RTC===> St-Entry Obj=Philo_inst[0],State=Philo_thinking") expect("@timestamp Init===> Obj=Philo_inst[0],State=Philo_thinking") expect("===RTC===> St-Init Obj=Philo_inst[1],State=QHsm_top->Philo_thinking") expect("@timestamp BSP_CALL BSP_random *") - expect("@timestamp TE0-Arm Obj=Philo_inst[1].timeEvt,AO=Table_inst,Tim=*,Int=0") + expect("@timestamp TE0-Arm Obj=Philo_inst[1].timeEvt,AO=Table_dummy,Tim=*,Int=0") expect("===RTC===> St-Entry Obj=Philo_inst[1],State=Philo_thinking") expect("@timestamp Init===> Obj=Philo_inst[1],State=Philo_thinking") expect("===RTC===> St-Init Obj=Philo_inst[2],State=QHsm_top->Philo_thinking") expect("@timestamp BSP_CALL BSP_random *") - expect("@timestamp TE0-Arm Obj=Philo_inst[2].timeEvt,AO=Table_inst,Tim=*,Int=0") + expect("@timestamp TE0-Arm Obj=Philo_inst[2].timeEvt,AO=Table_dummy,Tim=*,Int=0") expect("===RTC===> St-Entry Obj=Philo_inst[2],State=Philo_thinking") expect("@timestamp Init===> Obj=Philo_inst[2],State=Philo_thinking") expect("===RTC===> St-Init Obj=Philo_inst[3],State=QHsm_top->Philo_thinking") expect("@timestamp BSP_CALL BSP_random *") - expect("@timestamp TE0-Arm Obj=Philo_inst[3].timeEvt,AO=Table_inst,Tim=*,Int=0") + expect("@timestamp TE0-Arm Obj=Philo_inst[3].timeEvt,AO=Table_dummy,Tim=*,Int=0") expect("===RTC===> St-Entry Obj=Philo_inst[3],State=Philo_thinking") expect("@timestamp Init===> Obj=Philo_inst[3],State=Philo_thinking") expect("===RTC===> St-Init Obj=Philo_inst[4],State=QHsm_top->Philo_thinking") expect("@timestamp BSP_CALL BSP_random *") - expect("@timestamp TE0-Arm Obj=Philo_inst[4].timeEvt,AO=Table_inst,Tim=*,Int=0") + expect("@timestamp TE0-Arm Obj=Philo_inst[4].timeEvt,AO=Table_dummy,Tim=*,Int=0") expect("===RTC===> St-Entry Obj=Philo_inst[4],State=Philo_thinking") expect("@timestamp Init===> Obj=Philo_inst[4],State=Philo_thinking") - expect("===RTC===> St-Init Obj=Table_inst,State=QHsm_top->NULL") + expect("===RTC===> St-Init Obj=Table_dummy,State=QHsm_top->NULL") expect_run() # tests... diff --git a/examples/qutest/dpp-comp/test_philo/test_philo.c b/examples/qutest/dpp-comp/test_philo/test_philo.c index 85224ad5..d19ed143 100644 --- a/examples/qutest/dpp-comp/test_philo/test_philo.c +++ b/examples/qutest/dpp-comp/test_philo/test_philo.c @@ -1,120 +1,110 @@ -/***************************************************************************** -* Product: QUTEST fixture for the DPP example -* Last updated for version 7.1.1 -* Last updated on 2022-09-22 -* -* Q u a n t u m L e a P s -* ------------------------ -* Modern Embedded Software -* -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* -* -*****************************************************************************/ +//============================================================================ +// Product: QUTEST fixture for the DPP example +// Last updated for version 7.3.0 +// Last updated on 2023-06-23 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// This program is open source software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Alternatively, this program may be distributed and modified under the +// terms of Quantum Leaps commercial licenses, which expressly supersede +// the GNU General Public License and are specifically designed for +// licensees interested in retaining the proprietary status of their code. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Contact information: +// +// +//============================================================================ #include "qpc.h" #include "bsp.h" #include "dpp.h" -//#include "safe_std.h" /* portable "safe" / facilities */ +//#include "safe_std.h" // portable "safe" / facilities Q_DEFINE_THIS_FILE -/* the dummy Table collaborator AOs... */ -static QActiveDummy Table_inst; -QActive * const AO_Table = &Table_inst.super; +// the dummy Table collaborator AOs... +static QActiveDummy Table_dummy; +QActive * const AO_Table = &Table_dummy.super; -extern QHsm * const SM_Philo[N_PHILO]; +extern QAsm * const SM_Philo[N_PHILO]; -/*..........................................................................*/ -int main(int argc, char *argv[]) { - static QSubscrList subscrSto[MAX_PUB_SIG]; - static QF_MPOOL_EL(TableEvt) smlPoolSto[2*N_PHILO]; /* small pool */ +//............................................................................ +int main() { + QF_init(); // initialize the framework and the underlying RT kernel + BSP_init(); // initialize the BSP - QF_init(); /* initialize the framework and the underlying RT kernel */ - BSP_init(argc, argv); /* initialize the Board Support Package */ + // object dictionaries... + QS_OBJ_DICTIONARY(&Table_dummy); - /* signal dictionaries */ - QS_SIG_DICTIONARY(DONE_SIG, (void *)0); - QS_SIG_DICTIONARY(EAT_SIG, (void *)0); - QS_SIG_DICTIONARY(PAUSE_SIG, (void *)0); - QS_SIG_DICTIONARY(SERVE_SIG, (void *)0); - QS_SIG_DICTIONARY(TEST_SIG, (void *)0); - QS_SIG_DICTIONARY(HUNGRY_SIG, (void *)0); - QS_SIG_DICTIONARY(TIMEOUT_SIG, (void *)0); - - QS_OBJ_DICTIONARY(&Table_inst); - - /* pause execution of the test and wait for the test script to continue */ + // pause execution of the test and wait for the test script to continue QS_TEST_PAUSE(); - /* initialize publish-subscribe... */ - QF_psInit(subscrSto, Q_DIM(subscrSto)); - - /* initialize event pools... */ + // initialize event pools... + static QF_MPOOL_EL(TableEvt) smlPoolSto[2*N_PHILO]; // small pool QF_poolInit(smlPoolSto, sizeof(smlPoolSto), sizeof(smlPoolSto[0])); - /* construct and initialize Philo HSM components */ + // initialize publish-subscribe... + static QSubscrList subscrSto[MAX_PUB_SIG]; + QActive_psInit(subscrSto, Q_DIM(subscrSto)); + + // construct and initialize Philo HSM components for (uint8_t n = 0U; n < N_PHILO; ++n) { Philo_ctor(n); - QHSM_INIT(SM_Philo[n], (void *)0, QS_AP_ID + n); + QASM_INIT(SM_Philo[n], (void *)0, QS_AP_ID + n); } - /* instantiate all dummy AOs... */ - QActiveDummy_ctor(&Table_inst); - QACTIVE_START(&Table_inst, - 1U, /* QF-priority/preemption-threshold */ + // instantiate all dummy AOs... + QActiveDummy_ctor(&Table_dummy); + QACTIVE_START(&Table_dummy, + 1U, // QF-priority/preemption-threshold (QEvt const **)0, 0U, (void *)0, 0U, (void *)0); - return QF_run(); /* run the QF application */ + return QF_run(); // run the QF application } -/*..........................................................................*/ +//============================================================================ void QS_onTestSetup(void) { //PRINTF_S("%s\n", "QS_onTestSetup"); } void QS_onTestTeardown(void) { //PRINTF_S("%s\n", "QS_onTestTeardown"); } - -/*..........................................................................*/ -/*! callback function to execute user commands */ +//............................................................................ +// callback function to execute user commands void QS_onCommand(uint8_t cmdId, uint32_t param1, uint32_t param2, uint32_t param3) { - (void)cmdId; - (void)param1; - (void)param2; - (void)param3; + Q_UNUSED_PAR(cmdId); + Q_UNUSED_PAR(param1); + Q_UNUSED_PAR(param2); + Q_UNUSED_PAR(param3); switch (cmdId) { case 0U: { - QEvt const e_pause = { PAUSE_SIG, 0U, 0U }; - QHSM_DISPATCH(&AO_Table->super, &e_pause, (uint_fast8_t)param1); + QEvt const e_pause = QEVT_INITIALIZER( PAUSE_SIG); + QASM_DISPATCH(AO_Table, &e_pause, 0U); break; } case 1U: { - QEvt const e_serve = { SERVE_SIG, 0U, 0U }; - QHSM_DISPATCH(&AO_Table->super, &e_serve, (uint_fast8_t)param1); + QEvt const e_serve = QEVT_INITIALIZER(SERVE_SIG); + QASM_DISPATCH(AO_Table, &e_serve, 0U); break; } default: @@ -122,28 +112,28 @@ void QS_onCommand(uint8_t cmdId, } } -/****************************************************************************/ -/*! Host callback function to "massage" the event, if necessary */ +//============================================================================ +// Host callback function to "massage" the event, if necessary void QS_onTestEvt(QEvt *e) { (void)e; -#ifdef Q_HOST /* is this test compiled for a desktop Host computer? */ -#else /* embedded Target */ -#endif /* embedded Target */ +#ifdef Q_HOST // is this test compiled for a desktop Host computer? +#else // embedded Target +#endif // embedded Target } -/*..........................................................................*/ -/*! callback function to output the posted QP events... */ +//............................................................................ +//! callback function to output the posted QP events (not used here) void QS_onTestPost(void const *sender, QActive *recipient, QEvt const *e, bool status) { - (void)sender; - (void)status; + Q_UNUSED_PAR(sender); + Q_UNUSED_PAR(status); switch (e->sig) { case EAT_SIG: case DONE_SIG: case HUNGRY_SIG: - QS_BEGIN_ID(QUTEST_ON_POST, 0U) /* app-specific record */ + QS_BEGIN_ID(QUTEST_ON_POST, 0U) // application-specific record QS_SIG(e->sig, recipient); - QS_U8(0, Q_EVT_CAST(TableEvt)->philoNum); + QS_U8(0, Q_EVT_CAST(TableEvt)->philoId); QS_END() break; default: diff --git a/examples/qutest/dpp-comp/test_philo/test_philo.py b/examples/qutest/dpp-comp/test_philo/test_philo.py index 1d3373b0..d767df63 100644 --- a/examples/qutest/dpp-comp/test_philo/test_philo.py +++ b/examples/qutest/dpp-comp/test_philo/test_philo.py @@ -17,12 +17,12 @@ dispatch("TIMEOUT_SIG") expect("@timestamp MP-Get Obj=EvtPool1,*") expect("@timestamp QF-New Sig=TIMEOUT_SIG,*") expect("@timestamp Disp===> Obj=Philo_inst[2],Sig=TIMEOUT_SIG,State=Philo_thinking") -expect("@timestamp TE0-Dis Obj=Philo_inst[2].timeEvt,AO=Table_inst,Tim=*,Int=0") +expect("@timestamp TE0-Dis Obj=Philo_inst[2].timeEvt,AO=Table_dummy,Tim=*,Int=0") expect("===RTC===> St-Exit Obj=Philo_inst[2],State=Philo_thinking") expect("@timestamp MP-Get Obj=EvtPool1,*") expect("@timestamp QF-New Sig=HUNGRY_SIG,*") -expect("@timestamp AO-LIFO Obj=Table_inst,Evt St-Entry Obj=Philo_inst[2],State=Philo_hungry") @@ -37,7 +37,7 @@ expect("@timestamp MP-Get Obj=EvtPool1,*") expect("@timestamp QF-New Sig=EAT_SIG,*") expect("@timestamp Disp===> Obj=Philo_inst[2],Sig=EAT_SIG,State=Philo_hungry") expect("@timestamp BSP_CALL BSP_random *") -expect("@timestamp TE0-Arm Obj=Philo_inst[2].timeEvt,AO=Table_inst,Tim=*,Int=0") +expect("@timestamp TE0-Arm Obj=Philo_inst[2].timeEvt,AO=Table_dummy,Tim=*,Int=0") expect("===RTC===> St-Entry Obj=Philo_inst[2],State=Philo_eating") expect("@timestamp ===>Tran Obj=Philo_inst[2],Sig=EAT_SIG,State=Philo_hungry->Philo_eating") expect("@timestamp QF-gc Evt Obj=Philo_inst[2],Sig=TIMEOUT_SIG,State=Philo_eating") -expect("@timestamp TE0-Dis Obj=Philo_inst[2].timeEvt,AO=Table_inst,Tim=*,Int=0") +expect("@timestamp TE0-Dis Obj=Philo_inst[2].timeEvt,AO=Table_dummy,Tim=*,Int=0") expect("@timestamp MP-Get Obj=EvtPool1,*") expect("@timestamp QF-New Sig=DONE_SIG,*") -expect("@timestamp AO-LIFO Obj=Table_inst,Evt St-Exit Obj=Philo_inst[2],State=Philo_eating") expect("@timestamp BSP_CALL BSP_random *") -expect("@timestamp TE0-Arm Obj=Philo_inst[2].timeEvt,AO=Table_inst,Tim=*,Int=0") +expect("@timestamp TE0-Arm Obj=Philo_inst[2].timeEvt,AO=Table_dummy,Tim=*,Int=0") expect("===RTC===> St-Entry Obj=Philo_inst[2],State=Philo_thinking") expect("@timestamp ===>Tran Obj=Philo_inst[2],Sig=TIMEOUT_SIG,State=Philo_eating->Philo_thinking") expect("@timestamp QF-gc Evt Obj=Philo_inst[2],Sig=TIMEOUT_SIG,State=Philo_thinking") -expect("@timestamp TE0-Dis Obj=Philo_inst[2].timeEvt,AO=Table_inst,Tim=*,Int=0") +expect("@timestamp TE0-Dis Obj=Philo_inst[2].timeEvt,AO=Table_dummy,Tim=*,Int=0") expect("===RTC===> St-Exit Obj=Philo_inst[2],State=Philo_thinking") expect("@timestamp MP-Get Obj=EvtPool1,*") expect("@timestamp QF-New Sig=HUNGRY_SIG,*") -expect("@timestamp AO-LIFO Obj=Table_inst,Evt St-Entry Obj=Philo_inst[2],State=Philo_hungry") diff --git a/examples/qutest/dpp-comp/test_table/Makefile b/examples/qutest/dpp-comp/test_table/Makefile index f0e4c6db..eb7fa502 100644 --- a/examples/qutest/dpp-comp/test_table/Makefile +++ b/examples/qutest/dpp-comp/test_table/Makefile @@ -218,7 +218,7 @@ all : $(TARGET_EXE) run endif $(TARGET_EXE) : $(C_OBJS_EXT) $(CPP_OBJS_EXT) - $(CC) $(CFLAGS) $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o + $(CC) $(CFLAGS) $(QPC)/src/qs/qstamp.c -o $(BIN_DIR)/qstamp.o $(LINK) $(LINKFLAGS) $(LIB_DIRS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) run : $(TARGET_EXE) diff --git a/examples/qutest/dpp-comp/test_table/make_tm4c123 b/examples/qutest/dpp-comp/test_table/make_tm4c123 index dc4ff3d3..b83a3e04 100644 --- a/examples/qutest/dpp-comp/test_table/make_tm4c123 +++ b/examples/qutest/dpp-comp/test_table/make_tm4c123 @@ -254,7 +254,7 @@ $(TARGET_BIN) : $(TARGET_ELF) @pause $(TARGET_ELF) : $(ASM_OBJS_EXT) $(C_OBJS_EXT) $(CPP_OBJS_EXT) - $(CC) $(CFLAGS) $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o + $(CC) $(CFLAGS) $(QPC)/src/qs/qstamp.c -o $(BIN_DIR)/qstamp.o $(LINK) $(LINKFLAGS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) flash : diff --git a/examples/qutest/dpp-comp/test_table/test_table.c b/examples/qutest/dpp-comp/test_table/test_table.c index a93883b3..0a9a0cc2 100644 --- a/examples/qutest/dpp-comp/test_table/test_table.c +++ b/examples/qutest/dpp-comp/test_table/test_table.c @@ -1,48 +1,49 @@ -/***************************************************************************** -* Product: QUTEST fixture for the DPP components -* Last updated for version 7.1.1 -* Last updated on 2022-09-22 -* -* Q u a n t u m L e a P s -* ------------------------ -* Modern Embedded Software -* -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* -* -*****************************************************************************/ +//============================================================================ +// Product: QUTEST fixture for the DPP components +// Last updated for version 7.3.0 +// Last updated on 2023-07-27 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// This program is open source software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Alternatively, this program may be distributed and modified under the +// terms of Quantum Leaps commercial licenses, which expressly supersede +// the GNU General Public License and are specifically designed for +// licensees interested in retaining the proprietary status of their code. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Contact information: +// +// +//============================================================================ #include "qpc.h" #include "bsp.h" #include "dpp.h" -//#include "safe_std.h" /* portable "safe" / facilities */ +//#include "safe_std.h" // portable "safe" / facilities -Q_DEFINE_THIS_FILE +//Q_DEFINE_THIS_FILE -/*..........................................................................*/ -/* dummy Philo HSMs... */ +//............................................................................ +// dummy Philo HSMs... static QHsmDummy l_dummyPhilo[N_PHILO]; -QHsm * const SM_Philo[N_PHILO] = { /* opaque pointers to Philo instances */ + +QAsm * const SM_Philo[N_PHILO] = { // opaque pointers to Philo instances &l_dummyPhilo[0].super, &l_dummyPhilo[1].super, &l_dummyPhilo[2].super, @@ -53,64 +54,62 @@ void Philo_ctor(uint8_t n) { QHsmDummy_ctor(&l_dummyPhilo[n]); } -/*..........................................................................*/ -int main(int argc, char *argv[]) { - static QEvt const *tableQueueSto[N_PHILO]; - static QSubscrList subscrSto[MAX_PUB_SIG]; - static QF_MPOOL_EL(TableEvt) smlPoolSto[2*N_PHILO]; /* small pool */ +//............................................................................ +int main() { + QF_init(); // initialize the framework and the underlying RT kernel + BSP_init(); // initialize the BSP - QF_init(); /* initialize the framework and the underlying RT kernel */ - BSP_init(argc, argv); /* initialize the Board Support Package */ - - /* pause execution of the test and wait for the test script to continue */ + // pause execution of the test and wait for the test script to continue QS_TEST_PAUSE(); - /* initialize publish-subscribe... */ - QF_psInit(subscrSto, Q_DIM(subscrSto)); + // initialize publish-subscribe... + static QSubscrList subscrSto[MAX_PUB_SIG]; + QActive_psInit(subscrSto, Q_DIM(subscrSto)); - /* initialize event pools... */ + // initialize event pools... + static QF_MPOOL_EL(TableEvt) smlPoolSto[2*N_PHILO]; // small pool QF_poolInit(smlPoolSto, sizeof(smlPoolSto), sizeof(smlPoolSto[0])); - /* start the active objects... */ - Table_ctor(); /* instantiate the Table active object */ - QACTIVE_START(AO_Table, /* AO to start */ - 1U, /* QF-priority/preemption-threshold */ - tableQueueSto, /* event queue storage */ - Q_DIM(tableQueueSto), /* queue length [events] */ - (void *)0, /* stack storage (not used) */ - 0U, /* size of the stack [bytes] */ - (void *)0); /* initialization param */ + // start the active objects... + static QEvt const *tableQueueSto[N_PHILO]; + Table_ctor(); // instantiate the Table active object + QACTIVE_START(AO_Table, // AO to start + 1U, // QF-priority/preemption-threshold + tableQueueSto, // event queue storage + Q_DIM(tableQueueSto), // queue length [events] + (void *)0, // stack storage (not used) + 0U, // size of the stack [bytes] + (void *)0); // initialization param - return QF_run(); /* run the QF application */ + return QF_run(); // run the QF application } -/*..........................................................................*/ +//============================================================================ void QS_onTestSetup(void) { //PRINTF_S("%s\n", "QS_onTestSetup"); } void QS_onTestTeardown(void) { //PRINTF_S("%s\n", "QS_onTestTeardown"); } - -/*..........................................................................*/ -/*! callback function to execute user commands */ +//............................................................................ +// callback function to execute user commands void QS_onCommand(uint8_t cmdId, uint32_t param1, uint32_t param2, uint32_t param3) { - (void)cmdId; - (void)param1; - (void)param2; - (void)param3; + Q_UNUSED_PAR(cmdId); + Q_UNUSED_PAR(param1); + Q_UNUSED_PAR(param2); + Q_UNUSED_PAR(param3); switch (cmdId) { case 0U: { - QEvt const e = { PAUSE_SIG, 0U, 0U }; - QHSM_DISPATCH(&AO_Table->super, &e, AO_Table->prio); + QEvt const e_pause = QEVT_INITIALIZER( PAUSE_SIG); + QASM_DISPATCH(AO_Table, &e_pause, 0U); break; } case 1U: { - QEvt const e = { SERVE_SIG, 0U, 0U }; - QHSM_DISPATCH(&AO_Table->super, &e, AO_Table->prio); + QEvt const e_serve = QEVT_INITIALIZER(SERVE_SIG); + QASM_DISPATCH(AO_Table, &e_serve, 0U); break; } default: @@ -118,28 +117,28 @@ void QS_onCommand(uint8_t cmdId, } } -/****************************************************************************/ -/*! Host callback function to "massage" the event, if necessary */ +//============================================================================ +// Host callback function to "massage" the event, if necessary void QS_onTestEvt(QEvt *e) { (void)e; -#ifdef Q_HOST /* is this test compiled for a desktop Host computer? */ -#else /* embedded Target */ -#endif /* embedded Target */ +#ifdef Q_HOST // is this test compiled for a desktop Host computer? +#else // embedded Target +#endif // embedded Target } -/*..........................................................................*/ -/*! callback function to output the posted QP events (not used here) */ +//............................................................................ +//! callback function to output the posted QP events (not used here) void QS_onTestPost(void const *sender, QActive *recipient, QEvt const *e, bool status) { - (void)sender; - (void)status; + Q_UNUSED_PAR(sender); + Q_UNUSED_PAR(status); switch (e->sig) { case EAT_SIG: case DONE_SIG: case HUNGRY_SIG: - QS_BEGIN_ID(QUTEST_ON_POST, 0U) /* app-specific record */ + QS_BEGIN_ID(QUTEST_ON_POST, 0U) // application-specific record QS_SIG(e->sig, recipient); - QS_U8(0, Q_EVT_CAST(TableEvt)->philoNum); + QS_U8(0, Q_EVT_CAST(TableEvt)->philoId); QS_END() break; default: diff --git a/examples/qutest/dpp/dpp.qm b/examples/qutest/dpp/dpp.qm deleted file mode 100644 index 218618a3..00000000 --- a/examples/qutest/dpp/dpp.qm +++ /dev/null @@ -1,456 +0,0 @@ - - - Dining Philosopher Problem example - - - - - - - - - - - - /* opaque pointers to the Philo AOs */ - = { - &Philo_inst[0].super, - &Philo_inst[1].super, - &Philo_inst[2].super, - &Philo_inst[3].super, - &Philo_inst[4].super -}; - - - - /* opaque pointer to the Table AO */ - = &Table_inst.super; - - - - - - Philo *me = &Philo_inst[n]; -QActive_ctor(&me->super, Q_STATE_CAST(&Philo_initial)); -QTimeEvt_ctorX(&me->timeEvt, &me->super, TIMEOUT_SIG, 0U); - - - - Table *me = &Table_inst; - -QActive_ctor(&me->super, Q_STATE_CAST(&Table_initial)); - -for (uint8_t n = 0U; n < N_PHILO; ++n) { - me->fork[n] = FREE; - me->isHungry[n] = 0U; -} - - - - - - - - - - - - - - - (void)par; /* unused parameter */ - -#ifdef Q_SPY -uint8_t n = PHILO_ID(me); -QS_OBJ_ARR_DICTIONARY(&Philo_inst[n], n); -QS_OBJ_ARR_DICTIONARY(&Philo_inst[n].timeEvt, n); -#endif - -QActive_subscribe(&me->super, EAT_SIG); -QActive_subscribe(&me->super, TEST_SIG); - -/* the following code outputs the "fun-dictionaries" only once for -* all Philo instances, as opposed to repeat them for every instance. -*/ -static bool registered = false; -if (!registered) { - registered = true; - - QS_FUN_DICTIONARY(&Philo_initial); - QS_FUN_DICTIONARY(&Philo_thinking); - QS_FUN_DICTIONARY(&Philo_hungry); - QS_FUN_DICTIONARY(&Philo_eating); -} - - - - - - - QTimeEvt_armX(&me->timeEvt, THINK_TIME, 0U); - QTimeEvt_disarm(&me->timeEvt); - - - - - - - - - /* EAT or DONE must be for other Philos than this one */ -Q_ASSERT_ID(10, Q_EVT_CAST(TableEvt)->philoNum != PHILO_ID(me)); - - - - - - - - - - - - TableEvt *pe = Q_NEW(TableEvt, HUNGRY_SIG); -pe->philoNum = PHILO_ID(me); -QACTIVE_POST(AO_Table, &pe->super, me); - - - - - Q_EVT_CAST(TableEvt)->philoNum == PHILO_ID(me) - - - - - - - - - - - /* DONE must be for other Philos than this one */ -Q_ASSERT_ID(20, Q_EVT_CAST(TableEvt)->philoNum != PHILO_ID(me)); - - - - - - - - - - - QTimeEvt_armX(&me->timeEvt, EAT_TIME, 0U); - TableEvt *pe = Q_NEW(TableEvt, DONE_SIG); -pe->philoNum = PHILO_ID(me); -QACTIVE_PUBLISH(&pe->super, &me->super); -QTimeEvt_disarm(&me->timeEvt); - - - - - - - - - /* EAT or DONE must be for other Philos than this one */ -Q_ASSERT_ID(30, Q_EVT_CAST(TableEvt)->philoNum != PHILO_ID(me)); - - - - - - - - - - - - - - - - - The only static instance of the Table class (Singleton pattern) - - - - - - - - - - (void)par; /* unused parameter */ - -QS_OBJ_DICTIONARY(&Table_inst); - -QActive_subscribe(&me->super, DONE_SIG); -QActive_subscribe(&me->super, PAUSE_SIG); -QActive_subscribe(&me->super, SERVE_SIG); -QActive_subscribe(&me->super, TEST_SIG); - -for (uint8_t n = 0U; n < N_PHILO; ++n) { - me->fork[n] = FREE; - me->isHungry[n] = 0U; - BSP_displayPhilStat(n, "thinking"); -} - - - - - - - - - Q_ERROR_ID(60); - - - - - - - uint8_t n; -for (n = 0U; n < N_PHILO; ++n) { /* give permissions to eat... */ - if ((me->isHungry[n] != 0U) - && (me->fork[LEFT(n)] == FREE) - && (me->fork[n] == FREE)) - { - TableEvt *te; - - me->fork[LEFT(n)] = USED; - me->fork[n] = USED; - te = Q_NEW(TableEvt, EAT_SIG); - te->philoNum = n; - QACTIVE_PUBLISH(&te->super, &me->super); - me->isHungry[n] = 0U; - BSP_displayPhilStat(n, "eating "); - } -} - - - uint8_t n, m; - -n = Q_EVT_CAST(TableEvt)->philoNum; -/* phil ID must be in range and he must be not hungry */ -Q_ASSERT_ID(40, (n < N_PHILO) && (me->isHungry[n] == 0U)); - -BSP_displayPhilStat(n, "hungry "); -m = LEFT(n); - - - (me->fork[m] == FREE) && (me->fork[n] == FREE) - TableEvt *pe; -me->fork[m] = USED; -me->fork[n] = USED; -pe = Q_NEW(TableEvt, EAT_SIG); -pe->philoNum = n; -QACTIVE_PUBLISH(&pe->super, &me->super); -BSP_displayPhilStat(n, "eating "); - - - - - - - else - me->isHungry[n] = 1U; - - - - - - - - - - - uint8_t n, m; -TableEvt *pe; - -n = Q_EVT_CAST(TableEvt)->philoNum; -/* phil ID must be in range and he must be not hungry */ -Q_ASSERT_ID(50, (n < N_PHILO) && (me->isHungry[n] == 0U)); - -BSP_displayPhilStat(n, "thinking"); -m = LEFT(n); -/* both forks of Phil[n] must be used */ -Q_ASSERT_ID(51, (me->fork[n] == USED) && (me->fork[m] == USED)); - -me->fork[m] = FREE; -me->fork[n] = FREE; -m = RIGHT(n); /* check the right neighbor */ - -if ((me->isHungry[m] != 0U) && (me->fork[m] == FREE)) { - me->fork[n] = USED; - me->fork[m] = USED; - me->isHungry[m] = 0U; - pe = Q_NEW(TableEvt, EAT_SIG); - pe->philoNum = m; - QACTIVE_PUBLISH(&pe->super, &me->super); - BSP_displayPhilStat(m, "eating "); -} -m = LEFT(n); /* check the left neighbor */ -n = LEFT(m); /* left fork of the left neighbor */ -if ((me->isHungry[m] != 0U) && (me->fork[n] == FREE)) { - me->fork[m] = USED; - me->fork[n] = USED; - me->isHungry[m] = 0U; - pe = Q_NEW(TableEvt, EAT_SIG); - pe->philoNum = m; - QACTIVE_PUBLISH(&pe->super, &me->super); - BSP_displayPhilStat(m, "eating "); -} - - - - - - - - - - - - - - - - - BSP_displayPaused(1U); - BSP_displayPaused(0U); - - - - - - - - - uint8_t n = Q_EVT_CAST(TableEvt)->philoNum; -/* philo ID must be in range and he must be not hungry */ -Q_ASSERT_ID(60, (n < N_PHILO) && (me->isHungry[n] == 0U)); -me->isHungry[n] = 1U; -BSP_displayPhilStat(n, "hungry "); - - - - - - - uint8_t n, m; - -n = Q_EVT_CAST(TableEvt)->philoNum; -/* phil ID must be in range and he must be not hungry */ -Q_ASSERT_ID(70, (n < N_PHILO) && (me->isHungry[n] == 0U)); - -BSP_displayPhilStat(n, "thinking"); -m = LEFT(n); -/* both forks of Phil[n] must be used */ -Q_ASSERT_ID(71, (me->fork[n] == USED) && (me->fork[m] == USED)); - -me->fork[m] = FREE; -me->fork[n] = FREE; - - - - - - - - - - - - - - - - - - - - #ifndef DPP_H -#define DPP_H - -enum DPPSignals { - EAT_SIG = Q_USER_SIG, /* published by Table to let a philosopher eat */ - DONE_SIG, /* published by Philosopher when done eating */ - PAUSE_SIG, /* published by BSP to pause serving forks */ - SERVE_SIG, /* published by BSP to serve re-start serving forks */ - TEST_SIG, /* published by BSP to test the application */ - MAX_PUB_SIG, /* the last published signal */ - - HUNGRY_SIG, /* posted direclty to Table from hungry Philo */ - TIMEOUT_SIG, /* used by Philosophers for time events */ - MAX_SIG /* the last signal */ -}; - -enum { - N_PHILO = 5 /* number of Philos */ -}; - -$declare ${Shared} - -#ifdef QP_INC_QXK_H_ - void Test1_ctor(void); - extern QXThread * const XT_Test1; - void Test2_ctor(void); - extern QXThread * const XT_Test2; -#endif /* QP_INC_QXK_H_ */ - -#endif /* DPP_H */ - - - - - #include "qpc.h" -#include "dpp.h" -#include "bsp.h" - -Q_DEFINE_THIS_MODULE("philo") - -/* Active object class -----------------------------------------------------*/ -$declare ${AOs::Philo} - -/* helper macros to provide a randomized think time for Philos */ -#define THINK_TIME \ - (QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + (BSP_TICKS_PER_SEC/2U)) -#define EAT_TIME \ - (QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + BSP_TICKS_PER_SEC) - -/* helper macro to provide the ID of Philo "me_" */ -#define PHILO_ID(me_) ((uint8_t)((me_) - &Philo_inst[0])) - -/* Shared objects ----------------------------------------------------------*/ -$define ${Shared::AO_Philo[N_PHILO]} -$define ${Shared::Philo_ctor} - -/* Philo definition --------------------------------------------------------*/ -$define ${AOs::Philo} - - - - #include "qpc.h" -#include "dpp.h" -#include "bsp.h" - -Q_DEFINE_THIS_MODULE("table") - -/* Active object class -----------------------------------------------------*/ -$declare ${AOs::Table} - -#define RIGHT(n_) ((uint8_t)(((n_) + (N_PHILO - 1U)) % N_PHILO)) -#define LEFT(n_) ((uint8_t)(((n_) + 1U) % N_PHILO)) -#define FREE ((uint8_t)0) -#define USED ((uint8_t)1) - -/* Shared objects ----------------------------------------------------------*/ -$define ${Shared::AO_Table} -$define ${Shared::Table_ctor} - -/*..........................................................................*/ -$define ${AOs::Table} - - - diff --git a/examples/qutest/dpp/src/bsp.c b/examples/qutest/dpp/src/bsp.c index c085f2c8..22b64f44 100644 --- a/examples/qutest/dpp/src/bsp.c +++ b/examples/qutest/dpp/src/bsp.c @@ -1,106 +1,101 @@ -/***************************************************************************** -* Product: DPP example, BSP for QUTest -* Last Updated for Version: 7.2.0 -* Date of the Last Update: 2022-12-22 -* -* Q u a n t u m L e a P s -* ------------------------ -* Modern Embedded Software -* -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* -* -*****************************************************************************/ +//============================================================================ +// Product: DPP example, BSP for QUTest +// Last Updated for Version: 7.3.0 +// Date of the Last Update: 2023-08-23 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// This program is open source software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Alternatively, this program may be distributed and modified under the +// terms of Quantum Leaps commercial licenses, which expressly supersede +// the GNU General Public License and are specifically designed for +// licensees interested in retaining the proprietary status of their code. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Contact information: +// +// +//============================================================================ #include "qpc.h" #include "dpp.h" #include "bsp.h" Q_DEFINE_THIS_MODULE("bsp") -static uint32_t l_rnd; /* random seed */ +static uint32_t l_rnd; // random seed enum { BSP_CALL = QS_USER, }; -/*..........................................................................*/ -void BSP_init(int argc, char **argv) { - Q_ALLEGE(QS_INIT(argc <= 1 ? (void *)0 : argv[1]) != 0U); +//............................................................................ +void BSP_init(void) { + BSP_randomSeed(1234U); + + // initialize the QS software tracing + if (!QS_INIT((void *)0)) { + Q_ERROR(); + } QS_FUN_DICTIONARY(&BSP_displayPaused); QS_FUN_DICTIONARY(&BSP_displayPhilStat); QS_FUN_DICTIONARY(&BSP_random); QS_FUN_DICTIONARY(&BSP_randomSeed); - /* global signals */ - QS_SIG_DICTIONARY(DONE_SIG, (void *)0); - QS_SIG_DICTIONARY(EAT_SIG, (void *)0); - QS_SIG_DICTIONARY(PAUSE_SIG, (void *)0); - QS_SIG_DICTIONARY(SERVE_SIG, (void *)0); - QS_SIG_DICTIONARY(TEST_SIG, (void *)0); - QS_SIG_DICTIONARY(HUNGRY_SIG, (void *)0); - QS_SIG_DICTIONARY(HUNGRY_SIG, (void *)0); - QS_SIG_DICTIONARY(TIMEOUT_SIG, (void *)0); + QS_ONLY(produce_sig_dict()); QS_USR_DICTIONARY(BSP_CALL); - - BSP_randomSeed(1234U); } -/*..........................................................................*/ +//............................................................................ +void BSP_displayPhilStat(uint8_t n, char const *stat) { + QS_BEGIN_ID(BSP_CALL, 0U) // app-specific record + QS_FUN(&BSP_displayPhilStat); + QS_U8(0, n); + QS_STR(stat); + QS_END() +} +//............................................................................ void BSP_displayPaused(uint8_t paused) { QS_TEST_PROBE_DEF(&BSP_displayPaused) QS_TEST_PROBE( Q_ASSERT_ID(100, 0); ) - QS_BEGIN_ID(BSP_CALL, 0U) /* app-specific record */ + QS_BEGIN_ID(BSP_CALL, 0U) // app-specific record QS_FUN(&BSP_displayPaused); QS_U8(0, paused); QS_END() } -/*..........................................................................*/ -void BSP_displayPhilStat(uint8_t n, char const *stat) { - QS_BEGIN_ID(BSP_CALL, 0U) /* app-specific record */ - QS_FUN(&BSP_displayPhilStat); - QS_U8(0, n); - QS_STR(stat); - QS_END() -} -/*..........................................................................*/ -uint32_t BSP_random(void) { /* a very cheap pseudo-random-number generator */ +//............................................................................ +uint32_t BSP_random(void) { // a fake random-number generator QS_TEST_PROBE_DEF(&BSP_random) uint32_t rnd = 123U; QS_TEST_PROBE( rnd = qs_tp_; ) - QS_BEGIN_ID(BSP_CALL, 0U) /* app-specific record */ + QS_BEGIN_ID(BSP_CALL, 0U) // app-specific record QS_FUN(&BSP_random); QS_U32(0, rnd); QS_END() return rnd; } -/*..........................................................................*/ +//............................................................................ void BSP_randomSeed(uint32_t seed) { QS_TEST_PROBE_DEF(&BSP_randomSeed) @@ -108,7 +103,7 @@ void BSP_randomSeed(uint32_t seed) { seed = qs_tp_; ) l_rnd = seed; - QS_BEGIN_ID(BSP_CALL, 0U) /* app-specific record */ + QS_BEGIN_ID(BSP_CALL, 0U) // app-specific record QS_FUN(&BSP_randomSeed); QS_U32(0, seed); QS_END() diff --git a/examples/qutest/dpp/src/bsp.h b/examples/qutest/dpp/src/bsp.h index 1049ced9..c789279b 100644 --- a/examples/qutest/dpp/src/bsp.h +++ b/examples/qutest/dpp/src/bsp.h @@ -1,54 +1,51 @@ -/***************************************************************************** -* Product: DPP example -* Last Updated for Version: 6.2.0 -* Date of the Last Update: 2018-03-16 -* -* Q u a n t u m L e a P s -* --------------------------- -* innovating embedded systems -* -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* -* -*****************************************************************************/ -#ifndef BSP_H -#define BSP_H +//============================================================================ +// Product: DPP example +// Last Updated for Version: 7.3.0 +// Date of the Last Update: 2023-08-22 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// This program is open source software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Alternatively, this program may be distributed and modified under the +// terms of Quantum Leaps commercial licenses, which expressly supersede +// the GNU General Public License and are specifically designed for +// licensees interested in retaining the proprietary status of their code. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Contact information: +// +// +//============================================================================ +#ifndef BSP_H_ +#define BSP_H_ #define BSP_TICKS_PER_SEC 100U -void BSP_init(int argc, char **argv); +void BSP_init(void); +void BSP_start(void); void BSP_displayPaused(uint8_t paused); void BSP_displayPhilStat(uint8_t n, char const *stat); void BSP_terminate(int16_t result); -void BSP_randomSeed(uint32_t seed); /* random seed */ -uint32_t BSP_random(void); /* pseudo-random generator */ +void BSP_randomSeed(uint32_t seed); // random seed +uint32_t BSP_random(void); // pseudo-random generator -/* for testing... */ -void BSP_wait4PB1(void); void BSP_ledOn(void); void BSP_ledOff(void); -extern QActive *the_Ticker0; - -#endif /* BSP_H */ +#endif // BSP_H_ diff --git a/examples/qutest/dpp/src/dpp.h b/examples/qutest/dpp/src/dpp.h index 3bac33b5..e6d1557a 100644 --- a/examples/qutest/dpp/src/dpp.h +++ b/examples/qutest/dpp/src/dpp.h @@ -1,85 +1,117 @@ -/*$file${src::dpp.h} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* -* Model: dpp.qm -* File: ${src::dpp.h} -* -* This code has been generated by QM 5.2.4 . -* DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. -* -* SPDX-License-Identifier: GPL-3.0-or-later -* -* This generated code is open source software: you can redistribute it under -* the terms of the GNU General Public License as published by the Free -* Software Foundation. -* -* This code is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -* more details. -* -* NOTE: -* Alternatively, this generated code may be distributed under the terms -* of Quantum Leaps commercial licenses, which expressly supersede the GNU -* General Public License and are specifically designed for licensees -* interested in retaining the proprietary status of their code. -* -* Contact information: -* -* -*/ -/*$endhead${src::dpp.h} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -#ifndef DPP_H -#define DPP_H +//$file${.::dpp.h} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// +// Model: dpp.qm +// File: ${.::dpp.h} +// +// This code has been generated by QM 5.3.0 . +// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. +// +// SPDX-License-Identifier: GPL-3.0-or-later +// +// This generated code is open source software: you can redistribute it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation. +// +// This code is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// NOTE: +// Alternatively, this generated code may be distributed under the terms +// of Quantum Leaps commercial licenses, which expressly supersede the GNU +// General Public License and are specifically designed for licensees +// interested in retaining the proprietary status of their code. +// +// Contact information: +// +// +// +//$endhead${.::dpp.h} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +#ifndef DPP_H_ +#define DPP_H_ -enum DPPSignals { - EAT_SIG = Q_USER_SIG, /* published by Table to let a philosopher eat */ - DONE_SIG, /* published by Philosopher when done eating */ - PAUSE_SIG, /* published by BSP to pause serving forks */ - SERVE_SIG, /* published by BSP to serve re-start serving forks */ - TEST_SIG, /* published by BSP to test the application */ - MAX_PUB_SIG, /* the last published signal */ +//$declare${Shared} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv - HUNGRY_SIG, /* posted direclty to Table from hungry Philo */ - TIMEOUT_SIG, /* used by Philosophers for time events */ - MAX_SIG /* the last signal */ +//${Shared::AppSignals} ...................................................... +enum AppSignals { + EAT_SIG = Q_USER_SIG, // published by Table to let a Philo eat + DONE_SIG, // published by Philo when done eating + PAUSE_SIG, // published by BSP to pause the application + SERVE_SIG, // published by BSP to serve re-start serving forks + TEST_SIG, // published by BSP to test the application + MAX_PUB_SIG, // the last published signal + + TIMEOUT_SIG, // posted by time event to Philo + HUNGRY_SIG, // posted by hungry Philo to Table + MAX_SIG // the last signal }; -enum { - N_PHILO = 5 /* number of Philos */ -}; +//${Shared::produce_sig_dict} ................................................ +#ifdef Q_SPY +static inline void produce_sig_dict(void) { + QS_SIG_DICTIONARY(EAT_SIG, (void *)0); + QS_SIG_DICTIONARY(DONE_SIG, (void *)0); + QS_SIG_DICTIONARY(PAUSE_SIG, (void *)0); + QS_SIG_DICTIONARY(SERVE_SIG, (void *)0); + QS_SIG_DICTIONARY(TEST_SIG, (void *)0); -/*$declare${Shared} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ + QS_SIG_DICTIONARY(TIMEOUT_SIG, (void *)0); + QS_SIG_DICTIONARY(HUNGRY_SIG, (void *)0); +} +#endif // def Q_SPY -/*${Shared::TableEvt} ......................................................*/ +//${Shared::N_PHILO} ......................................................... +#define N_PHILO ((uint8_t)5U) + +//${Shared::TableEvt} ........................................................ typedef struct { -/* protected: */ +// protected: QEvt super; -/* public: */ - uint8_t philoNum; +// public: + uint8_t philoId; } TableEvt; -/*${Shared::AO_Philo[N_PHILO]} .............................................*/ -/* opaque pointers to the Philo AOs */ +// public: + +#ifdef QEVT_DYN_CTOR +static inline TableEvt * TableEvt_ctor(TableEvt * const me, + uint8_t id) +{ + if (me != (TableEvt *)0) { + // don't call QEvt_ctor() because the initialization of all + // QEvt attributes is already done in QF_QF_newX_() + me->philoId = id; + } + return me; +} +#endif // def QEVT_DYN_CTOR + +//${Shared::AO_Philo[N_PHILO]} ............................................... extern QActive * const AO_Philo[N_PHILO]; -/*${Shared::AO_Table} ......................................................*/ -/* opaque pointer to the Table AO */ +//${Shared::Philo_ctor} ...................................................... +void Philo_ctor(uint_fast8_t const id); + +//${Shared::AO_Table} ........................................................ extern QActive * const AO_Table; -/*${Shared::Philo_ctor} ....................................................*/ -void Philo_ctor(uint8_t n); - -/*${Shared::Table_ctor} ....................................................*/ +//${Shared::Table_ctor} ...................................................... void Table_ctor(void); -/*$enddecl${Shared} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$enddecl${Shared} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -#ifdef QP_INC_QXK_H_ - void Test1_ctor(void); - extern QXThread * const XT_Test1; - void Test2_ctor(void); - extern QXThread * const XT_Test2; -#endif /* QP_INC_QXK_H_ */ +#ifdef QXK_H_ -#endif /* DPP_H */ +extern QXThread * const TH_XThread1; +void XThread1_ctor(void); +extern QXThread * const TH_XThread2; +void XThread2_ctor(void); + +extern QXSemaphore TH_sema; +extern QXMutex TH_mutex; + +#endif // QXK_H_ + +#endif // DPP_H_ diff --git a/examples/qutest/dpp/src/dpp.qm b/examples/qutest/dpp/src/dpp.qm new file mode 100644 index 00000000..ac9f2bc9 --- /dev/null +++ b/examples/qutest/dpp/src/dpp.qm @@ -0,0 +1,525 @@ + + + Dining Philosopher Problem example + + + + + + + { + EAT_SIG = Q_USER_SIG, // published by Table to let a Philo eat + DONE_SIG, // published by Philo when done eating + PAUSE_SIG, // published by BSP to pause the application + SERVE_SIG, // published by BSP to serve re-start serving forks + TEST_SIG, // published by BSP to test the application + MAX_PUB_SIG, // the last published signal + + TIMEOUT_SIG, // posted by time event to Philo + HUNGRY_SIG, // posted by hungry Philo to Table + MAX_SIG // the last signal +}; + + + + QS_SIG_DICTIONARY(EAT_SIG, (void *)0); +QS_SIG_DICTIONARY(DONE_SIG, (void *)0); +QS_SIG_DICTIONARY(PAUSE_SIG, (void *)0); +QS_SIG_DICTIONARY(SERVE_SIG, (void *)0); +QS_SIG_DICTIONARY(TEST_SIG, (void *)0); + +QS_SIG_DICTIONARY(TIMEOUT_SIG, (void *)0); +QS_SIG_DICTIONARY(HUNGRY_SIG, (void *)0); + + + + ((uint8_t)5U) + + + + + + + + + + if (me != (TableEvt *)0) { + // don't call QEvt_ctor() because the initialization of all + // QEvt attributes is already done in QF_QF_newX_() + me->philoId = id; +} +return me; + + + + + = { + &Philo_inst[0].super, + &Philo_inst[1].super, + &Philo_inst[2].super, + &Philo_inst[3].super, + &Philo_inst[4].super +}; + + + + + + Philo * const me = &Philo_inst[id]; +QActive_ctor(&me->super, Q_STATE_CAST(&Philo_initial)); +QTimeEvt_ctorX(&me->timeEvt, &me->super, TIMEOUT_SIG, 0U), +me->id = (uint8_t)id; + + + + = &Table_inst.super; + + + + Table * const me = &Table_inst; +QActive_ctor(&me->super, Q_STATE_CAST(&Table_initial)); +for (uint8_t n = 0U; n < N_PHILO; ++n) { + me->fork[n] = FREE; + me->isHungry[n] = false; +} + + + + + + + The Philo AO and the N_PHILO instances + + + + + + + + + + + Q_UNUSED_PAR(par); + +QS_OBJ_ARR_DICTIONARY(&Philo_inst[me->id], me->id); +QS_OBJ_ARR_DICTIONARY(&Philo_inst[me->id].timeEvt, me->id); + +QActive_subscribe(&me->super, EAT_SIG); +QActive_subscribe(&me->super, TEST_SIG); + + + + + + + QTimeEvt_armX(&me->timeEvt, think_time(), 0U); + (void)QTimeEvt_disarm(&me->timeEvt); + + + + + + + + + // EAT or DONE must be for other Philos than this one +Q_ASSERT(Q_EVT_CAST(TableEvt)->philoId != me->id); + + + + + + + + + + + + + + + + + + #ifdef QEVT_DYN_CTOR +TableEvt const *pe = Q_NEW(TableEvt, HUNGRY_SIG, me->id); +#else +TableEvt *pe = Q_NEW(TableEvt, HUNGRY_SIG); +pe->philoId = me->id; +#endif +QACTIVE_POST(AO_Table, &pe->super, &me->super); + + + + + Q_EVT_CAST(TableEvt)->philoId == me->id + + + + + + + + + + + // DONE must be for other Philos than this one +Q_ASSERT(Q_EVT_CAST(TableEvt)->philoId != me->id); + + + + + + + + + + + QTimeEvt_armX(&me->timeEvt, eat_time(), 0U); + (void)QTimeEvt_disarm(&me->timeEvt); + +#ifdef QEVT_DYN_CTOR +TableEvt const *pe = Q_NEW(TableEvt, DONE_SIG, me->id); +#else +TableEvt *pe = Q_NEW(TableEvt, DONE_SIG); +pe->philoId = me->id; +#endif +QACTIVE_PUBLISH(&pe->super, &me->super); + + + + + + + + + // EAT or DONE must be for other Philos than this one +Q_ASSERT(Q_EVT_CAST(TableEvt)->philoId != me->id); + + + + + + + + + + + + + + + + + + + + + + + + + Q_UNUSED_PAR(par); + +#ifdef Q_SPY +Table *Table_inst = me; +QS_OBJ_DICTIONARY(Table_inst); +#endif + +QActive_subscribe(&me->super, DONE_SIG); +QActive_subscribe(&me->super, PAUSE_SIG); +QActive_subscribe(&me->super, SERVE_SIG); +QActive_subscribe(&me->super, TEST_SIG); + +for (uint8_t n = 0U; n < N_PHILO; ++n) { + me->fork[n] = FREE; + me->isHungry[n] = false; + BSP_displayPhilStat(n, THINKING); +} + + + + + + + + + + + + + + + Q_ERROR(); + + + + + + + // give permissions to eat... +for (uint8_t n = 0U; n < N_PHILO; ++n) { + if (me->isHungry[n] + && (me->fork[left(n)] == FREE) + && (me->fork[n] == FREE)) + { + me->fork[left(n)] = USED; + me->fork[n] = USED; +#ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, EAT_SIG, n); +#else + TableEvt *pe = Q_NEW(TableEvt, EAT_SIG); + pe->philoId = n; +#endif + QACTIVE_PUBLISH(&pe->super, &me->super); + me->isHungry[n] = false; + BSP_displayPhilStat(n, EATING); + } +} + + + uint8_t n = Q_EVT_CAST(TableEvt)->philoId; + +// phil ID must be in range and he must be not hungry +Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); + +BSP_displayPhilStat(n, HUNGRY); +uint8_t m = left(n); + + + (me->fork[m] == FREE) && (me->fork[n] == FREE) + me->fork[m] = USED; +me->fork[n] = USED; +#ifdef QEVT_DYN_CTOR +TableEvt const *pe = Q_NEW(TableEvt, EAT_SIG, n); +#else +TableEvt *pe = Q_NEW(TableEvt, EAT_SIG); +pe->philoId = n; +#endif +QACTIVE_PUBLISH(&pe->super, &me->super); +BSP_displayPhilStat(n, EATING); + + + + + + + else + me->isHungry[n] = true; + + + + + + + + + + + uint8_t n = Q_EVT_CAST(TableEvt)->philoId; + +// phil ID must be in range and he must be not hungry +Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); + +BSP_displayPhilStat(n, THINKING); +uint8_t m = left(n); + +// both forks of Phil[n] must be used +Q_ASSERT((me->fork[n] == USED) && (me->fork[m] == USED)); + +me->fork[m] = FREE; +me->fork[n] = FREE; +m = right(n); // check the right neighbor + +if (me->isHungry[m] && (me->fork[m] == FREE)) { + me->fork[n] = USED; + me->fork[m] = USED; + me->isHungry[m] = false; +#ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, EAT_SIG, m); +#else + TableEvt *pe = Q_NEW(TableEvt, EAT_SIG); + pe->philoId = m; +#endif + QACTIVE_PUBLISH(&pe->super, &me->super); + BSP_displayPhilStat(m, EATING); +} +m = left(n); // check the left neighbor +n = left(m); // left fork of the left neighbor +if (me->isHungry[m] && (me->fork[n] == FREE)) { + me->fork[m] = USED; + me->fork[n] = USED; + me->isHungry[m] = false; +#ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, EAT_SIG, m); +#else + TableEvt *pe = Q_NEW(TableEvt, EAT_SIG); + pe->philoId = m; +#endif + QACTIVE_PUBLISH(&pe->super, &me->super); + BSP_displayPhilStat(m, EATING); +} + + + + + + + Q_ERROR(); + + + + + + + + + + + + + + + + + BSP_displayPaused(1U); + BSP_displayPaused(0U); + + + + + + + + + uint8_t n = Q_EVT_CAST(TableEvt)->philoId; + +// philo ID must be in range and he must be not hungry +Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); + +me->isHungry[n] = true; +BSP_displayPhilStat(n, HUNGRY); + + + + + + + uint8_t n = Q_EVT_CAST(TableEvt)->philoId; + +// phil ID must be in range and he must be not hungry +Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); + +BSP_displayPhilStat(n, THINKING); +uint8_t m = left(n); + +// both forks of Phil[n] must be used +Q_ASSERT((me->fork[n] == USED) && (me->fork[m] == USED)); + +me->fork[m] = FREE; +me->fork[n] = FREE; + + + + + + + + + + + + + + + + + + + + #ifndef DPP_H_ +#define DPP_H_ + +$declare ${Shared} + +#ifdef QXK_H_ + +extern QXThread * const TH_XThread1; +void XThread1_ctor(void); + +extern QXThread * const TH_XThread2; +void XThread2_ctor(void); + +extern QXSemaphore TH_sema; +extern QXMutex TH_mutex; + +#endif // QXK_H_ + +#endif // DPP_H_ + + + + #include "qpc.h" // QP/C real-time embedded framework +#include "dpp.h" // DPP Application interface +#include "bsp.h" // Board Support Package + +$declare ${AOs::Philo} + +//---------------------------------------------------------------------------- +Q_DEFINE_THIS_FILE + +// helper function to provide a randomized think time for Philos +static QTimeEvtCtr think_time(void); // prototype +static inline QTimeEvtCtr think_time(void) { + return (QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + + (BSP_TICKS_PER_SEC/2U)); +} + +// helper function to provide a randomized eat time for Philos +static QTimeEvtCtr eat_time(void); // prototype +static inline QTimeEvtCtr eat_time(void) { + return (QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + + BSP_TICKS_PER_SEC); +} +//---------------------------------------------------------------------------- + +$define ${Shared::Philo_ctor} +$define ${Shared::AO_Philo[N_PHILO]} +$define ${AOs::Philo} + + + + #include "qpc.h" // QP/C real-time embedded framework +#include "dpp.h" // DPP Application interface +#include "bsp.h" // Board Support Package + +$declare ${AOs::Table} + +//---------------------------------------------------------------------------- +Q_DEFINE_THIS_FILE + +// helper function to provide the RIGHT neighbor of a Philo[n] +static inline uint8_t right(uint8_t const n) { + return (uint8_t)((n + (N_PHILO - 1U)) % N_PHILO); +} + +// helper function to provide the LEFT neighbor of a Philo[n] +static inline uint8_t left(uint8_t const n) { + return (uint8_t)((n + 1U) % N_PHILO); +} + +#define FREE ((uint8_t)0U) +#define USED ((uint8_t)1U) + +#define THINKING "thinking" +#define HUNGRY "hungry " +#define EATING "eating " + +//---------------------------------------------------------------------------- + +$define ${Shared::Table_ctor} +$define ${Shared::AO_Table} +$define ${AOs::Table} + + + diff --git a/examples/qutest/dpp/src/philo.c b/examples/qutest/dpp/src/philo.c index 0e370c08..eb6be531 100644 --- a/examples/qutest/dpp/src/philo.c +++ b/examples/qutest/dpp/src/philo.c @@ -1,81 +1,98 @@ -/*$file${src::philo.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* -* Model: dpp.qm -* File: ${src::philo.c} -* -* This code has been generated by QM 5.2.4 . -* DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. -* -* SPDX-License-Identifier: GPL-3.0-or-later -* -* This generated code is open source software: you can redistribute it under -* the terms of the GNU General Public License as published by the Free -* Software Foundation. -* -* This code is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -* more details. -* -* NOTE: -* Alternatively, this generated code may be distributed under the terms -* of Quantum Leaps commercial licenses, which expressly supersede the GNU -* General Public License and are specifically designed for licensees -* interested in retaining the proprietary status of their code. -* -* Contact information: -* -* -*/ -/*$endhead${src::philo.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -#include "qpc.h" -#include "dpp.h" -#include "bsp.h" +//$file${.::philo.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// +// Model: dpp.qm +// File: ${.::philo.c} +// +// This code has been generated by QM 5.3.0 . +// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. +// +// SPDX-License-Identifier: GPL-3.0-or-later +// +// This generated code is open source software: you can redistribute it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation. +// +// This code is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// NOTE: +// Alternatively, this generated code may be distributed under the terms +// of Quantum Leaps commercial licenses, which expressly supersede the GNU +// General Public License and are specifically designed for licensees +// interested in retaining the proprietary status of their code. +// +// Contact information: +// +// +// +//$endhead${.::philo.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +#include "qpc.h" // QP/C real-time embedded framework +#include "dpp.h" // DPP Application interface +#include "bsp.h" // Board Support Package -Q_DEFINE_THIS_MODULE("philo") +//$declare${AOs::Philo} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/* Active object class -----------------------------------------------------*/ -/*$declare${AOs::Philo} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${AOs::Philo} ............................................................*/ +//${AOs::Philo} .............................................................. typedef struct Philo { -/* protected: */ +// protected: QActive super; -/* public: */ - -/* private: */ +// private: QTimeEvt timeEvt; + uint8_t id; + +// public: } Philo; + extern Philo Philo_inst[N_PHILO]; -/* protected: */ +// protected: static QState Philo_initial(Philo * const me, void const * const par); static QState Philo_thinking(Philo * const me, QEvt const * const e); static QState Philo_hungry(Philo * const me, QEvt const * const e); static QState Philo_eating(Philo * const me, QEvt const * const e); -/*$enddecl${AOs::Philo} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$enddecl${AOs::Philo} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -/* helper macros to provide a randomized think time for Philos */ -#define THINK_TIME \ - (QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + (BSP_TICKS_PER_SEC/2U)) -#define EAT_TIME \ - (QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + BSP_TICKS_PER_SEC) +//---------------------------------------------------------------------------- +Q_DEFINE_THIS_FILE -/* helper macro to provide the ID of Philo "me_" */ -#define PHILO_ID(me_) ((uint8_t)((me_) - &Philo_inst[0])) +// helper function to provide a randomized think time for Philos +static QTimeEvtCtr think_time(void); // prototype +static inline QTimeEvtCtr think_time(void) { + return (QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + + (BSP_TICKS_PER_SEC/2U)); +} -/* Shared objects ----------------------------------------------------------*/ -/*$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* Check for the minimum required QP version */ -#if (QP_VERSION < 700U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) -#error qpc version 7.0.0 or higher required +// helper function to provide a randomized eat time for Philos +static QTimeEvtCtr eat_time(void); // prototype +static inline QTimeEvtCtr eat_time(void) { + return (QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + + BSP_TICKS_PER_SEC); +} +//---------------------------------------------------------------------------- + +//$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// Check for the minimum required QP version +#if (QP_VERSION < 730U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) +#error qpc version 7.3.0 or higher required #endif -/*$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -/*$define${Shared::AO_Philo[N_PHILO]} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//$define${Shared::Philo_ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/*${Shared::AO_Philo[N_PHILO]} .............................................*/ +//${Shared::Philo_ctor} ...................................................... +void Philo_ctor(uint_fast8_t const id) { + Philo * const me = &Philo_inst[id]; + QActive_ctor(&me->super, Q_STATE_CAST(&Philo_initial)); + QTimeEvt_ctorX(&me->timeEvt, &me->super, TIMEOUT_SIG, 0U), + me->id = (uint8_t)id; +} +//$enddef${Shared::Philo_ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +//$define${Shared::AO_Philo[N_PHILO]} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${Shared::AO_Philo[N_PHILO]} ............................................... QActive * const AO_Philo[N_PHILO] = { &Philo_inst[0].super, &Philo_inst[1].super, @@ -83,78 +100,61 @@ QActive * const AO_Philo[N_PHILO] = { &Philo_inst[3].super, &Philo_inst[4].super }; -/*$enddef${Shared::AO_Philo[N_PHILO]} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*$define${Shared::Philo_ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//$enddef${Shared::AO_Philo[N_PHILO]} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +//$define${AOs::Philo} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/*${Shared::Philo_ctor} ....................................................*/ -void Philo_ctor(uint8_t n) { - Philo *me = &Philo_inst[n]; - QActive_ctor(&me->super, Q_STATE_CAST(&Philo_initial)); - QTimeEvt_ctorX(&me->timeEvt, &me->super, TIMEOUT_SIG, 0U); -} -/*$enddef${Shared::Philo_ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ - -/* Philo definition --------------------------------------------------------*/ -/*$define${AOs::Philo} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${AOs::Philo} ............................................................*/ +//${AOs::Philo} .............................................................. Philo Philo_inst[N_PHILO]; -/*${AOs::Philo::SM} ........................................................*/ +//${AOs::Philo::SM} .......................................................... static QState Philo_initial(Philo * const me, void const * const par) { - /*${AOs::Philo::SM::initial} */ - (void)par; /* unused parameter */ + //${AOs::Philo::SM::initial} + Q_UNUSED_PAR(par); - #ifdef Q_SPY - uint8_t n = PHILO_ID(me); - QS_OBJ_ARR_DICTIONARY(&Philo_inst[n], n); - QS_OBJ_ARR_DICTIONARY(&Philo_inst[n].timeEvt, n); - #endif + QS_OBJ_ARR_DICTIONARY(&Philo_inst[me->id], me->id); + QS_OBJ_ARR_DICTIONARY(&Philo_inst[me->id].timeEvt, me->id); QActive_subscribe(&me->super, EAT_SIG); QActive_subscribe(&me->super, TEST_SIG); - /* the following code outputs the "fun-dictionaries" only once for - * all Philo instances, as opposed to repeat them for every instance. - */ - static bool registered = false; - if (!registered) { - registered = true; + QS_FUN_DICTIONARY(&Philo_thinking); + QS_FUN_DICTIONARY(&Philo_hungry); + QS_FUN_DICTIONARY(&Philo_eating); - QS_FUN_DICTIONARY(&Philo_initial); - QS_FUN_DICTIONARY(&Philo_thinking); - QS_FUN_DICTIONARY(&Philo_hungry); - QS_FUN_DICTIONARY(&Philo_eating); - } return Q_TRAN(&Philo_thinking); } -/*${AOs::Philo::SM::thinking} ..............................................*/ +//${AOs::Philo::SM::thinking} ................................................ static QState Philo_thinking(Philo * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${AOs::Philo::SM::thinking} */ + //${AOs::Philo::SM::thinking} case Q_ENTRY_SIG: { - QTimeEvt_armX(&me->timeEvt, THINK_TIME, 0U); + QTimeEvt_armX(&me->timeEvt, think_time(), 0U); status_ = Q_HANDLED(); break; } - /*${AOs::Philo::SM::thinking} */ + //${AOs::Philo::SM::thinking} case Q_EXIT_SIG: { - QTimeEvt_disarm(&me->timeEvt); + (void)QTimeEvt_disarm(&me->timeEvt); status_ = Q_HANDLED(); break; } - /*${AOs::Philo::SM::thinking::TIMEOUT} */ + //${AOs::Philo::SM::thinking::TIMEOUT} case TIMEOUT_SIG: { status_ = Q_TRAN(&Philo_hungry); break; } - /*${AOs::Philo::SM::thinking::EAT, DONE} */ - case EAT_SIG: /* intentionally fall through */ + //${AOs::Philo::SM::thinking::EAT, DONE} + case EAT_SIG: // intentionally fall through case DONE_SIG: { - /* EAT or DONE must be for other Philos than this one */ - Q_ASSERT_ID(10, Q_EVT_CAST(TableEvt)->philoNum != PHILO_ID(me)); + // EAT or DONE must be for other Philos than this one + Q_ASSERT(Q_EVT_CAST(TableEvt)->philoId != me->id); + status_ = Q_HANDLED(); + break; + } + //${AOs::Philo::SM::thinking::TEST} + case TEST_SIG: { status_ = Q_HANDLED(); break; } @@ -166,22 +166,26 @@ static QState Philo_thinking(Philo * const me, QEvt const * const e) { return status_; } -/*${AOs::Philo::SM::hungry} ................................................*/ +//${AOs::Philo::SM::hungry} .................................................. static QState Philo_hungry(Philo * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${AOs::Philo::SM::hungry} */ + //${AOs::Philo::SM::hungry} case Q_ENTRY_SIG: { + #ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, HUNGRY_SIG, me->id); + #else TableEvt *pe = Q_NEW(TableEvt, HUNGRY_SIG); - pe->philoNum = PHILO_ID(me); - QACTIVE_POST(AO_Table, &pe->super, me); + pe->philoId = me->id; + #endif + QACTIVE_POST(AO_Table, &pe->super, &me->super); status_ = Q_HANDLED(); break; } - /*${AOs::Philo::SM::hungry::EAT} */ + //${AOs::Philo::SM::hungry::EAT} case EAT_SIG: { - /*${AOs::Philo::SM::hungry::EAT::[Q_EVT_CAST(TableEvt)->philoNum=~} */ - if (Q_EVT_CAST(TableEvt)->philoNum == PHILO_ID(me)) { + //${AOs::Philo::SM::hungry::EAT::[e->philoId==me->iid]} + if (Q_EVT_CAST(TableEvt)->philoId == me->id) { status_ = Q_TRAN(&Philo_eating); } else { @@ -189,10 +193,10 @@ static QState Philo_hungry(Philo * const me, QEvt const * const e) { } break; } - /*${AOs::Philo::SM::hungry::DONE} */ + //${AOs::Philo::SM::hungry::DONE} case DONE_SIG: { - /* DONE must be for other Philos than this one */ - Q_ASSERT_ID(20, Q_EVT_CAST(TableEvt)->philoNum != PHILO_ID(me)); + // DONE must be for other Philos than this one + Q_ASSERT(Q_EVT_CAST(TableEvt)->philoId != me->id); status_ = Q_HANDLED(); break; } @@ -204,35 +208,40 @@ static QState Philo_hungry(Philo * const me, QEvt const * const e) { return status_; } -/*${AOs::Philo::SM::eating} ................................................*/ +//${AOs::Philo::SM::eating} .................................................. static QState Philo_eating(Philo * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${AOs::Philo::SM::eating} */ + //${AOs::Philo::SM::eating} case Q_ENTRY_SIG: { - QTimeEvt_armX(&me->timeEvt, EAT_TIME, 0U); + QTimeEvt_armX(&me->timeEvt, eat_time(), 0U); status_ = Q_HANDLED(); break; } - /*${AOs::Philo::SM::eating} */ + //${AOs::Philo::SM::eating} case Q_EXIT_SIG: { + (void)QTimeEvt_disarm(&me->timeEvt); + + #ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, DONE_SIG, me->id); + #else TableEvt *pe = Q_NEW(TableEvt, DONE_SIG); - pe->philoNum = PHILO_ID(me); + pe->philoId = me->id; + #endif QACTIVE_PUBLISH(&pe->super, &me->super); - QTimeEvt_disarm(&me->timeEvt); status_ = Q_HANDLED(); break; } - /*${AOs::Philo::SM::eating::TIMEOUT} */ + //${AOs::Philo::SM::eating::TIMEOUT} case TIMEOUT_SIG: { status_ = Q_TRAN(&Philo_thinking); break; } - /*${AOs::Philo::SM::eating::EAT, DONE} */ - case EAT_SIG: /* intentionally fall through */ + //${AOs::Philo::SM::eating::EAT, DONE} + case EAT_SIG: // intentionally fall through case DONE_SIG: { - /* EAT or DONE must be for other Philos than this one */ - Q_ASSERT_ID(30, Q_EVT_CAST(TableEvt)->philoNum != PHILO_ID(me)); + // EAT or DONE must be for other Philos than this one + Q_ASSERT(Q_EVT_CAST(TableEvt)->philoId != me->id); status_ = Q_HANDLED(); break; } @@ -243,4 +252,4 @@ static QState Philo_eating(Philo * const me, QEvt const * const e) { } return status_; } -/*$enddef${AOs::Philo} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$enddef${AOs::Philo} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/examples/qutest/dpp/src/table.c b/examples/qutest/dpp/src/table.c index 47a78d92..c3ae02f0 100644 --- a/examples/qutest/dpp/src/table.c +++ b/examples/qutest/dpp/src/table.c @@ -1,107 +1,120 @@ -/*$file${src::table.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* -* Model: dpp.qm -* File: ${src::table.c} -* -* This code has been generated by QM 5.2.4 . -* DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. -* -* SPDX-License-Identifier: GPL-3.0-or-later -* -* This generated code is open source software: you can redistribute it under -* the terms of the GNU General Public License as published by the Free -* Software Foundation. -* -* This code is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -* more details. -* -* NOTE: -* Alternatively, this generated code may be distributed under the terms -* of Quantum Leaps commercial licenses, which expressly supersede the GNU -* General Public License and are specifically designed for licensees -* interested in retaining the proprietary status of their code. -* -* Contact information: -* -* -*/ -/*$endhead${src::table.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -#include "qpc.h" -#include "dpp.h" -#include "bsp.h" +//$file${.::table.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// +// Model: dpp.qm +// File: ${.::table.c} +// +// This code has been generated by QM 5.3.0 . +// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. +// +// SPDX-License-Identifier: GPL-3.0-or-later +// +// This generated code is open source software: you can redistribute it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation. +// +// This code is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// NOTE: +// Alternatively, this generated code may be distributed under the terms +// of Quantum Leaps commercial licenses, which expressly supersede the GNU +// General Public License and are specifically designed for licensees +// interested in retaining the proprietary status of their code. +// +// Contact information: +// +// +// +//$endhead${.::table.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +#include "qpc.h" // QP/C real-time embedded framework +#include "dpp.h" // DPP Application interface +#include "bsp.h" // Board Support Package -Q_DEFINE_THIS_MODULE("table") +//$declare${AOs::Table} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/* Active object class -----------------------------------------------------*/ -/*$declare${AOs::Table} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${AOs::Table} ............................................................*/ +//${AOs::Table} .............................................................. typedef struct Table { -/* protected: */ +// protected: QActive super; -/* public: */ - -/* private: */ +// private: uint8_t fork[N_PHILO]; - uint8_t isHungry[N_PHILO]; + bool isHungry[N_PHILO]; + +// public: } Table; + extern Table Table_inst; -/* protected: */ +// protected: static QState Table_initial(Table * const me, void const * const par); static QState Table_active(Table * const me, QEvt const * const e); static QState Table_serving(Table * const me, QEvt const * const e); static QState Table_paused(Table * const me, QEvt const * const e); -/*$enddecl${AOs::Table} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$enddecl${AOs::Table} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -#define RIGHT(n_) ((uint8_t)(((n_) + (N_PHILO - 1U)) % N_PHILO)) -#define LEFT(n_) ((uint8_t)(((n_) + 1U) % N_PHILO)) -#define FREE ((uint8_t)0) -#define USED ((uint8_t)1) +//---------------------------------------------------------------------------- +Q_DEFINE_THIS_FILE -/* Shared objects ----------------------------------------------------------*/ -/*$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* Check for the minimum required QP version */ -#if (QP_VERSION < 700U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) -#error qpc version 7.0.0 or higher required +// helper function to provide the RIGHT neighbor of a Philo[n] +static inline uint8_t right(uint8_t const n) { + return (uint8_t)((n + (N_PHILO - 1U)) % N_PHILO); +} + +// helper function to provide the LEFT neighbor of a Philo[n] +static inline uint8_t left(uint8_t const n) { + return (uint8_t)((n + 1U) % N_PHILO); +} + +#define FREE ((uint8_t)0U) +#define USED ((uint8_t)1U) + +#define THINKING "thinking" +#define HUNGRY "hungry " +#define EATING "eating " + +//---------------------------------------------------------------------------- + +//$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// Check for the minimum required QP version +#if (QP_VERSION < 730U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) +#error qpc version 7.3.0 or higher required #endif -/*$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -/*$define${Shared::AO_Table} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//$define${Shared::Table_ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/*${Shared::AO_Table} ......................................................*/ -QActive * const AO_Table = &Table_inst.super; -/*$enddef${Shared::AO_Table} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*$define${Shared::Table_ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${Shared::Table_ctor} ....................................................*/ +//${Shared::Table_ctor} ...................................................... void Table_ctor(void) { - Table *me = &Table_inst; - + Table * const me = &Table_inst; QActive_ctor(&me->super, Q_STATE_CAST(&Table_initial)); - for (uint8_t n = 0U; n < N_PHILO; ++n) { me->fork[n] = FREE; - me->isHungry[n] = 0U; + me->isHungry[n] = false; } } -/*$enddef${Shared::Table_ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$enddef${Shared::Table_ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +//$define${Shared::AO_Table} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/*..........................................................................*/ -/*$define${AOs::Table} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//${Shared::AO_Table} ........................................................ +QActive * const AO_Table = &Table_inst.super; +//$enddef${Shared::AO_Table} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +//$define${AOs::Table} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/*${AOs::Table} ............................................................*/ +//${AOs::Table} .............................................................. Table Table_inst; -/*${AOs::Table::SM} ........................................................*/ +//${AOs::Table::SM} .......................................................... static QState Table_initial(Table * const me, void const * const par) { - /*${AOs::Table::SM::initial} */ - (void)par; /* unused parameter */ + //${AOs::Table::SM::initial} + Q_UNUSED_PAR(par); - QS_OBJ_DICTIONARY(&Table_inst); + #ifdef Q_SPY + Table *Table_inst = me; + QS_OBJ_DICTIONARY(Table_inst); + #endif QActive_subscribe(&me->super, DONE_SIG); QActive_subscribe(&me->super, PAUSE_SIG); @@ -110,8 +123,8 @@ static QState Table_initial(Table * const me, void const * const par) { for (uint8_t n = 0U; n < N_PHILO; ++n) { me->fork[n] = FREE; - me->isHungry[n] = 0U; - BSP_displayPhilStat(n, "thinking"); + me->isHungry[n] = false; + BSP_displayPhilStat(n, THINKING); } QS_FUN_DICTIONARY(&Table_active); @@ -121,13 +134,18 @@ static QState Table_initial(Table * const me, void const * const par) { return Q_TRAN(&Table_serving); } -/*${AOs::Table::SM::active} ................................................*/ +//${AOs::Table::SM::active} .................................................. static QState Table_active(Table * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${AOs::Table::SM::active::EAT} */ + //${AOs::Table::SM::active::TEST} + case TEST_SIG: { + status_ = Q_HANDLED(); + break; + } + //${AOs::Table::SM::active::EAT} case EAT_SIG: { - Q_ERROR_ID(60); + Q_ERROR(); status_ = Q_HANDLED(); break; } @@ -139,102 +157,119 @@ static QState Table_active(Table * const me, QEvt const * const e) { return status_; } -/*${AOs::Table::SM::active::serving} .......................................*/ +//${AOs::Table::SM::active::serving} ......................................... static QState Table_serving(Table * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${AOs::Table::SM::active::serving} */ + //${AOs::Table::SM::active::serving} case Q_ENTRY_SIG: { - uint8_t n; - for (n = 0U; n < N_PHILO; ++n) { /* give permissions to eat... */ - if ((me->isHungry[n] != 0U) - && (me->fork[LEFT(n)] == FREE) + // give permissions to eat... + for (uint8_t n = 0U; n < N_PHILO; ++n) { + if (me->isHungry[n] + && (me->fork[left(n)] == FREE) && (me->fork[n] == FREE)) { - TableEvt *te; - - me->fork[LEFT(n)] = USED; + me->fork[left(n)] = USED; me->fork[n] = USED; - te = Q_NEW(TableEvt, EAT_SIG); - te->philoNum = n; - QACTIVE_PUBLISH(&te->super, &me->super); - me->isHungry[n] = 0U; - BSP_displayPhilStat(n, "eating "); + #ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, EAT_SIG, n); + #else + TableEvt *pe = Q_NEW(TableEvt, EAT_SIG); + pe->philoId = n; + #endif + QACTIVE_PUBLISH(&pe->super, &me->super); + me->isHungry[n] = false; + BSP_displayPhilStat(n, EATING); } } status_ = Q_HANDLED(); break; } - /*${AOs::Table::SM::active::serving::HUNGRY} */ + //${AOs::Table::SM::active::serving::HUNGRY} case HUNGRY_SIG: { - uint8_t n, m; + uint8_t n = Q_EVT_CAST(TableEvt)->philoId; - n = Q_EVT_CAST(TableEvt)->philoNum; - /* phil ID must be in range and he must be not hungry */ - Q_ASSERT_ID(40, (n < N_PHILO) && (me->isHungry[n] == 0U)); + // phil ID must be in range and he must be not hungry + Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); - BSP_displayPhilStat(n, "hungry "); - m = LEFT(n); - /*${AOs::Table::SM::active::serving::HUNGRY::[bothfree]} */ + BSP_displayPhilStat(n, HUNGRY); + uint8_t m = left(n); + //${AOs::Table::SM::active::serving::HUNGRY::[bothfree]} if ((me->fork[m] == FREE) && (me->fork[n] == FREE)) { - TableEvt *pe; me->fork[m] = USED; me->fork[n] = USED; - pe = Q_NEW(TableEvt, EAT_SIG); - pe->philoNum = n; + #ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, EAT_SIG, n); + #else + TableEvt *pe = Q_NEW(TableEvt, EAT_SIG); + pe->philoId = n; + #endif QACTIVE_PUBLISH(&pe->super, &me->super); - BSP_displayPhilStat(n, "eating "); + BSP_displayPhilStat(n, EATING); status_ = Q_HANDLED(); } - /*${AOs::Table::SM::active::serving::HUNGRY::[else]} */ + //${AOs::Table::SM::active::serving::HUNGRY::[else]} else { - me->isHungry[n] = 1U; + me->isHungry[n] = true; status_ = Q_HANDLED(); } break; } - /*${AOs::Table::SM::active::serving::DONE} */ + //${AOs::Table::SM::active::serving::DONE} case DONE_SIG: { - uint8_t n, m; - TableEvt *pe; + uint8_t n = Q_EVT_CAST(TableEvt)->philoId; - n = Q_EVT_CAST(TableEvt)->philoNum; - /* phil ID must be in range and he must be not hungry */ - Q_ASSERT_ID(50, (n < N_PHILO) && (me->isHungry[n] == 0U)); + // phil ID must be in range and he must be not hungry + Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); - BSP_displayPhilStat(n, "thinking"); - m = LEFT(n); - /* both forks of Phil[n] must be used */ - Q_ASSERT_ID(51, (me->fork[n] == USED) && (me->fork[m] == USED)); + BSP_displayPhilStat(n, THINKING); + uint8_t m = left(n); + + // both forks of Phil[n] must be used + Q_ASSERT((me->fork[n] == USED) && (me->fork[m] == USED)); me->fork[m] = FREE; me->fork[n] = FREE; - m = RIGHT(n); /* check the right neighbor */ + m = right(n); // check the right neighbor - if ((me->isHungry[m] != 0U) && (me->fork[m] == FREE)) { + if (me->isHungry[m] && (me->fork[m] == FREE)) { me->fork[n] = USED; me->fork[m] = USED; - me->isHungry[m] = 0U; - pe = Q_NEW(TableEvt, EAT_SIG); - pe->philoNum = m; + me->isHungry[m] = false; + #ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, EAT_SIG, m); + #else + TableEvt *pe = Q_NEW(TableEvt, EAT_SIG); + pe->philoId = m; + #endif QACTIVE_PUBLISH(&pe->super, &me->super); - BSP_displayPhilStat(m, "eating "); + BSP_displayPhilStat(m, EATING); } - m = LEFT(n); /* check the left neighbor */ - n = LEFT(m); /* left fork of the left neighbor */ - if ((me->isHungry[m] != 0U) && (me->fork[n] == FREE)) { + m = left(n); // check the left neighbor + n = left(m); // left fork of the left neighbor + if (me->isHungry[m] && (me->fork[n] == FREE)) { me->fork[m] = USED; me->fork[n] = USED; - me->isHungry[m] = 0U; - pe = Q_NEW(TableEvt, EAT_SIG); - pe->philoNum = m; + me->isHungry[m] = false; + #ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, EAT_SIG, m); + #else + TableEvt *pe = Q_NEW(TableEvt, EAT_SIG); + pe->philoId = m; + #endif QACTIVE_PUBLISH(&pe->super, &me->super); - BSP_displayPhilStat(m, "eating "); + BSP_displayPhilStat(m, EATING); } status_ = Q_HANDLED(); break; } - /*${AOs::Table::SM::active::serving::PAUSE} */ + //${AOs::Table::SM::active::serving::EAT} + case EAT_SIG: { + Q_ERROR(); + status_ = Q_HANDLED(); + break; + } + //${AOs::Table::SM::active::serving::PAUSE} case PAUSE_SIG: { status_ = Q_TRAN(&Table_paused); break; @@ -247,49 +282,51 @@ static QState Table_serving(Table * const me, QEvt const * const e) { return status_; } -/*${AOs::Table::SM::active::paused} ........................................*/ +//${AOs::Table::SM::active::paused} .......................................... static QState Table_paused(Table * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${AOs::Table::SM::active::paused} */ + //${AOs::Table::SM::active::paused} case Q_ENTRY_SIG: { BSP_displayPaused(1U); status_ = Q_HANDLED(); break; } - /*${AOs::Table::SM::active::paused} */ + //${AOs::Table::SM::active::paused} case Q_EXIT_SIG: { BSP_displayPaused(0U); status_ = Q_HANDLED(); break; } - /*${AOs::Table::SM::active::paused::SERVE} */ + //${AOs::Table::SM::active::paused::SERVE} case SERVE_SIG: { status_ = Q_TRAN(&Table_serving); break; } - /*${AOs::Table::SM::active::paused::HUNGRY} */ + //${AOs::Table::SM::active::paused::HUNGRY} case HUNGRY_SIG: { - uint8_t n = Q_EVT_CAST(TableEvt)->philoNum; - /* philo ID must be in range and he must be not hungry */ - Q_ASSERT_ID(60, (n < N_PHILO) && (me->isHungry[n] == 0U)); - me->isHungry[n] = 1U; - BSP_displayPhilStat(n, "hungry "); + uint8_t n = Q_EVT_CAST(TableEvt)->philoId; + + // philo ID must be in range and he must be not hungry + Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); + + me->isHungry[n] = true; + BSP_displayPhilStat(n, HUNGRY); status_ = Q_HANDLED(); break; } - /*${AOs::Table::SM::active::paused::DONE} */ + //${AOs::Table::SM::active::paused::DONE} case DONE_SIG: { - uint8_t n, m; + uint8_t n = Q_EVT_CAST(TableEvt)->philoId; - n = Q_EVT_CAST(TableEvt)->philoNum; - /* phil ID must be in range and he must be not hungry */ - Q_ASSERT_ID(70, (n < N_PHILO) && (me->isHungry[n] == 0U)); + // phil ID must be in range and he must be not hungry + Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); - BSP_displayPhilStat(n, "thinking"); - m = LEFT(n); - /* both forks of Phil[n] must be used */ - Q_ASSERT_ID(71, (me->fork[n] == USED) && (me->fork[m] == USED)); + BSP_displayPhilStat(n, THINKING); + uint8_t m = left(n); + + // both forks of Phil[n] must be used + Q_ASSERT((me->fork[n] == USED) && (me->fork[m] == USED)); me->fork[m] = FREE; me->fork[n] = FREE; @@ -303,4 +340,4 @@ static QState Table_paused(Table * const me, QEvt const * const e) { } return status_; } -/*$enddef${AOs::Table} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$enddef${AOs::Table} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/examples/qutest/dpp/test_dpp/Makefile b/examples/qutest/dpp/test_dpp/Makefile index c697ac80..1cb9a217 100644 --- a/examples/qutest/dpp/test_dpp/Makefile +++ b/examples/qutest/dpp/test_dpp/Makefile @@ -1,7 +1,7 @@ ############################################################################## # Product: Makefile for QUTEST-QP/C for Windows and POSIX *HOSTS* -# Last Updated for Version: 7.2.0 -# Date of the Last Update: 2022-12-21 +# Last Updated for Version: 7.3.0 +# Date of the Last Update: 2023-09-04 # # Q u a n t u m L e a P s # ------------------------ @@ -80,7 +80,6 @@ endif # C source files... C_SRCS := \ bsp.c \ - main.c \ philo.c \ table.c \ test_dpp.c @@ -92,7 +91,7 @@ LIB_DIRS := LIBS := # defines... -DEFINES := +DEFINES := $(DEF) #----------------------------------------------------------------------------- # add QP/C framework: @@ -126,7 +125,6 @@ LIBS += -lws2_32 else QP_PORT_DIR := $(QPC)/ports/posix-qutest -#QP_PORT_DIR := $(QPC)/ports/posix LIBS += -lpthread endif @@ -220,7 +218,7 @@ all : $(TARGET_EXE) run endif $(TARGET_EXE) : $(C_OBJS_EXT) $(CPP_OBJS_EXT) - $(CC) $(CFLAGS) $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o + $(CC) $(CFLAGS) $(QPC)/src/qs/qstamp.c -o $(BIN_DIR)/qstamp.o $(LINK) $(LINKFLAGS) $(LIB_DIRS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) run : $(TARGET_EXE) diff --git a/examples/qutest/dpp/test_dpp/main.c b/examples/qutest/dpp/test_dpp/main.c deleted file mode 100644 index 7c76a009..00000000 --- a/examples/qutest/dpp/test_dpp/main.c +++ /dev/null @@ -1,81 +0,0 @@ -/***************************************************************************** -* Product: DPP example -* Last updated for version 7.1.2 -* Last updated on 2022-10-06 -* -* Q u a n t u m L e a P s -* ------------------------ -* Modern Embedded Software -* -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* -* -*****************************************************************************/ -#include "qpc.h" -#include "dpp.h" -#include "bsp.h" - -Q_DEFINE_THIS_FILE - -/*..........................................................................*/ -int main(int argc, char *argv[]) { - static QEvt const *tableQueueSto[N_PHILO]; - static QEvt const *philoQueueSto[N_PHILO][N_PHILO]; - static QSubscrList subscrSto[MAX_PUB_SIG]; - static QF_MPOOL_EL(TableEvt) smlPoolSto[2*N_PHILO]; /* small pool */ - - QF_init(); /* initialize the framework and the underlying RT kernel */ - BSP_init(argc, argv); /* initialize the Board Support Package */ - - /* pause execution of the test and wait for the test script to continue */ - QS_TEST_PAUSE(); - - /* initialize publish-subscribe... */ - QF_psInit(subscrSto, Q_DIM(subscrSto)); - - /* initialize event pools... */ - QF_poolInit(smlPoolSto, sizeof(smlPoolSto), sizeof(smlPoolSto[0])); - - /* start the active objects... */ - for (uint8_t n = 0U; n < N_PHILO; ++n) { - Philo_ctor(n); /* instantiate all Philosopher active objects */ - QACTIVE_START(AO_Philo[n], /* AO to start */ - n + 1U, /* QF-priority */ - philoQueueSto[n], /* event queue storage */ - Q_DIM(philoQueueSto[n]), /* queue length [events] */ - (void *)0, /* stack storage (not used) */ - 0U, /* size of the stack [bytes] */ - (void *)0); /* initialization param */ - } - - Table_ctor(); /* instantiate the Table active object */ - QACTIVE_START(AO_Table, /* AO to start */ - N_PHILO + 1U, /* QF-priority */ - tableQueueSto, /* event queue storage */ - Q_DIM(tableQueueSto), /* queue length [events] */ - (void *)0, /* stack storage (not used) */ - 0U, /* size of the stack [bytes] */ - (void *)0); /* initialization param */ - - return QF_run(); /* run the QF application */ -} diff --git a/examples/qutest/dpp/test_dpp/make_efm32 b/examples/qutest/dpp/test_dpp/make_efm32 index 9b487d1a..7667b70b 100644 --- a/examples/qutest/dpp/test_dpp/make_efm32 +++ b/examples/qutest/dpp/test_dpp/make_efm32 @@ -99,7 +99,6 @@ ASM_SRCS := # C source files C_SRCS := \ test_dpp.c \ - main.c \ philo.c \ table.c \ bsp.c \ @@ -255,7 +254,7 @@ $(TARGET_BIN) : $(TARGET_ELF) $(FLASH) $@ $(TARGET_ELF) : $(ASM_OBJS_EXT) $(C_OBJS_EXT) $(CPP_OBJS_EXT) - $(CC) $(CFLAGS) $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o + $(CC) $(CFLAGS) $(QPC)/src/qs/qstamp.c -o $(BIN_DIR)/qstamp.o $(LINK) $(LINKFLAGS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) flash : diff --git a/examples/qutest/dpp/test_dpp/make_nucleo-l053r8 b/examples/qutest/dpp/test_dpp/make_nucleo-l053r8 index d616f928..22abd53d 100644 --- a/examples/qutest/dpp/test_dpp/make_nucleo-l053r8 +++ b/examples/qutest/dpp/test_dpp/make_nucleo-l053r8 @@ -99,7 +99,6 @@ ASM_SRCS := # C source files C_SRCS := \ test_dpp.c \ - main.c \ philo.c \ table.c \ bsp.c \ @@ -255,7 +254,7 @@ $(TARGET_BIN) : $(TARGET_ELF) $(SLEEP) 2 $(TARGET_ELF) : $(ASM_OBJS_EXT) $(C_OBJS_EXT) $(CPP_OBJS_EXT) - $(CC) $(CFLAGS) $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o + $(CC) $(CFLAGS) $(QPC)/src/qs/qstamp.c -o $(BIN_DIR)/qstamp.o $(LINK) $(LINKFLAGS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) flash : diff --git a/examples/qutest/dpp/test_dpp/make_posix b/examples/qutest/dpp/test_dpp/make_posix index 5731bfab..fe25a257 100644 --- a/examples/qutest/dpp/test_dpp/make_posix +++ b/examples/qutest/dpp/test_dpp/make_posix @@ -1,13 +1,13 @@ ############################################################################## # Product: Makefile for QUTEST; QP/C on POSIX *Target* -# Last Updated for Version: 7.0.1 -# Date of the Last Update: 2022-05-23 +# Last Updated for Version: 7.2.0 +# Date of the Last Update: 2022-12-21 # # Q u a n t u m L e a P s # ------------------------ # Modern Embedded Software # -# Copyright (C) 2005-2020 Quantum Leaps, LLC. All rights reserved. +# Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. # # This program is open source software: you can redistribute it and/or # modify it under the terms of the GNU General Public License as published @@ -25,7 +25,7 @@ # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License -# along with this program. If not, see . +# along with this program. If not, see . # # Contact information: # @@ -77,11 +77,10 @@ endif # C source files... C_SRCS := \ - bsp.c \ - main.c \ + test_dpp.c \ philo.c \ table.c \ - test_dpp.c + bsp.c # C++ source files... CPP_SRCS := @@ -185,7 +184,7 @@ all : $(TARGET_EXE) run endif $(TARGET_EXE) : $(C_OBJS_EXT) $(CPP_OBJS_EXT) - $(CC) $(CFLAGS) $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o + $(CC) $(CFLAGS) $(QPC)/src/qs/qstamp.c -o $(BIN_DIR)/qstamp.o $(LINK) $(LINKFLAGS) $(LIB_DIRS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) # run the test fixture on a POSIX target in a loop, so that it is re-started diff --git a/examples/qutest/dpp/test_dpp/make_tm4c123 b/examples/qutest/dpp/test_dpp/make_tm4c123 index 2840c76b..cb6ccc2c 100644 --- a/examples/qutest/dpp/test_dpp/make_tm4c123 +++ b/examples/qutest/dpp/test_dpp/make_tm4c123 @@ -1,5 +1,5 @@ ############################################################################## -# Product: Makefile for QP/C on TM4C123, QUTEST, GNU-ARM +# Product: Makefile for QUTEST; QP/C on TM4C123, GNU-ARM # Last Updated for Version: 7.2.0 # Date of the Last Update: 2022-12-21 # @@ -99,7 +99,6 @@ ASM_SRCS := # C source files C_SRCS := \ test_dpp.c \ - main.c \ philo.c \ table.c \ bsp.c \ @@ -256,7 +255,7 @@ $(TARGET_BIN) : $(TARGET_ELF) @pause $(TARGET_ELF) : $(ASM_OBJS_EXT) $(C_OBJS_EXT) $(CPP_OBJS_EXT) - $(CC) $(CFLAGS) $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o + $(CC) $(CFLAGS) $(QPC)/src/qs/qstamp.c -o $(BIN_DIR)/qstamp.o $(LINK) $(LINKFLAGS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) flash : diff --git a/examples/qutest/dpp/test_dpp/test_dpp.c b/examples/qutest/dpp/test_dpp/test_dpp.c index e8f7a246..73dbcb39 100644 --- a/examples/qutest/dpp/test_dpp/test_dpp.c +++ b/examples/qutest/dpp/test_dpp/test_dpp.c @@ -1,71 +1,112 @@ -/***************************************************************************** -* Product: QUTEST fixture for the DPP components -* Last Updated for Version: 6.9.1 -* Date of the Last Update: 2020-09-11 -* -* Q u a n t u m L e a P s -* ------------------------ -* Modern Embedded Software -* -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* -* -*****************************************************************************/ +//============================================================================ +// Product: QUTEST fixture for the DPP components +// Last updated for version 7.3.0 +// Last updated on 2023-08-22 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// This program is open source software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Alternatively, this program may be distributed and modified under the +// terms of Quantum Leaps commercial licenses, which expressly supersede +// the GNU General Public License and are specifically designed for +// licensees interested in retaining the proprietary status of their code. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Contact information: +// +// +//============================================================================ #include "qpc.h" #include "bsp.h" #include "dpp.h" -//#include "safe_std.h" /* portable "safe" / facilities */ +//#include "safe_std.h" // portable "safe" / facilities //Q_DEFINE_THIS_FILE -/*..........................................................................*/ +//============================================================================ +int main() { + QF_init(); // initialize the framework and the underlying RT kernel + BSP_init(); // initialize the BSP + + // pause execution of the test and wait for the test script to continue + QS_TEST_PAUSE(); + + // initialize event pools... + static QF_MPOOL_EL(TableEvt) smlPoolSto[2*N_PHILO]; // small pool + QF_poolInit(smlPoolSto, sizeof(smlPoolSto), sizeof(smlPoolSto[0])); + + // initialize publish-subscribe... + static QSubscrList subscrSto[MAX_PUB_SIG]; + QActive_psInit(subscrSto, Q_DIM(subscrSto)); + + // start the active objects... + static QEvt const *philoQueueSto[N_PHILO][10]; + for (uint8_t n = 0U; n < N_PHILO; ++n) { + Philo_ctor(n); // instantiate all Philosopher active objects + QACTIVE_START(AO_Philo[n], // AO to start + n + 1U, // QF-priority + philoQueueSto[n], // event queue storage + Q_DIM(philoQueueSto[n]), // queue length [events] + (void *)0, // stack storage (not used) + 0U, // size of the stack [bytes] + (void *)0); // initialization param + } + + static QEvt const *tableQueueSto[N_PHILO]; + Table_ctor(); // instantiate the Table active object + QACTIVE_START(AO_Table, // AO to start + N_PHILO + 1U, // QF-priority + tableQueueSto, // event queue storage + Q_DIM(tableQueueSto), // queue length [events] + (void *)0, // stack storage (not used) + 0U, // size of the stack [bytes] + (void *)0); // initialization param + + return QF_run(); // run the QF application +} + +//============================================================================ void QS_onTestSetup(void) { //PRINTF_S("%s\n", "QS_onTestSetup"); } void QS_onTestTeardown(void) { //PRINTF_S("%s\n", "QS_onTestTeardown"); } - -/*..........................................................................*/ -/*! callback function to execute user commands */ +//............................................................................ +// callback function to execute user commands void QS_onCommand(uint8_t cmdId, uint32_t param1, uint32_t param2, uint32_t param3) { - (void)cmdId; - (void)param1; - (void)param2; - (void)param3; + Q_UNUSED_PAR(cmdId); + Q_UNUSED_PAR(param1); + Q_UNUSED_PAR(param2); + Q_UNUSED_PAR(param3); switch (cmdId) { case 0U: { - QEvt const e_pause = { PAUSE_SIG, 0U, 0U }; - QHSM_DISPATCH(&AO_Table->super, &e_pause, 0U); + QEvt const e_pause = QEVT_INITIALIZER( PAUSE_SIG); + QASM_DISPATCH(AO_Table, &e_pause, 0U); break; } case 1U: { - QEvt const e_serve = { SERVE_SIG, 0U, 0U }; - QHSM_DISPATCH(&AO_Table->super, &e_serve, 0U); + QEvt const e_serve = QEVT_INITIALIZER(SERVE_SIG); + QASM_DISPATCH(AO_Table, &e_serve, 0U); break; } default: @@ -73,28 +114,28 @@ void QS_onCommand(uint8_t cmdId, } } -/****************************************************************************/ -/*! Host callback function to "massage" the event, if necessary */ +//============================================================================ +// Host callback function to "massage" the event, if necessary void QS_onTestEvt(QEvt *e) { (void)e; -#ifdef Q_HOST /* is this test compiled for a desktop Host computer? */ -#else /* embedded Target */ -#endif /* embedded Target */ +#ifdef Q_HOST // is this test compiled for a desktop Host computer? +#else // embedded Target +#endif // embedded Target } -/*..........................................................................*/ -/*! callback function to output the posted QP events (not used here) */ +//............................................................................ +// callback function to output the posted QP events (not used here) void QS_onTestPost(void const *sender, QActive *recipient, QEvt const *e, bool status) { - (void)sender; - (void)status; + Q_UNUSED_PAR(sender); + Q_UNUSED_PAR(status); switch (e->sig) { case EAT_SIG: case DONE_SIG: case HUNGRY_SIG: - QS_BEGIN_ID(QUTEST_ON_POST, 0U) /* application-specific record */ + QS_BEGIN_ID(QUTEST_ON_POST, 0U) // application-specific record QS_SIG(e->sig, recipient); - QS_U8(0, Q_EVT_CAST(TableEvt)->philoNum); + QS_U8(0, Q_EVT_CAST(TableEvt)->philoId); QS_END() break; default: diff --git a/examples/qutest/dpp/test_philo/Makefile b/examples/qutest/dpp/test_philo/Makefile index 828b7def..907cde92 100644 --- a/examples/qutest/dpp/test_philo/Makefile +++ b/examples/qutest/dpp/test_philo/Makefile @@ -218,7 +218,7 @@ all : $(TARGET_EXE) run endif $(TARGET_EXE) : $(C_OBJS_EXT) $(CPP_OBJS_EXT) - $(CC) $(CFLAGS) $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o + $(CC) $(CFLAGS) $(QPC)/src/qs/qstamp.c -o $(BIN_DIR)/qstamp.o $(LINK) $(LINKFLAGS) $(LIB_DIRS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) run : $(TARGET_EXE) diff --git a/examples/qutest/dpp/test_philo/make_tm4c123 b/examples/qutest/dpp/test_philo/make_tm4c123 new file mode 100644 index 00000000..4af0df70 --- /dev/null +++ b/examples/qutest/dpp/test_philo/make_tm4c123 @@ -0,0 +1,320 @@ +############################################################################## +# Product: Makefile for QP/C on TM4C123, QUTEST, GNU-ARM +# Last Updated for Version: 7.2.0 +# Date of the Last Update: 2022-12-21 +# +# Q u a n t u m L e a P s +# ------------------------ +# Modern Embedded Software +# +# Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +# +# This program is open source software: you can redistribute it and/or +# modify it under the terms of the GNU General Public License as published +# by the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Alternatively, this program may be distributed and modified under the +# terms of Quantum Leaps commercial licenses, which expressly supersede +# the GNU General Public License and are specifically designed for +# licensees interested in retaining the proprietary status of their code. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# +# Contact information: +# +# +############################################################################## +# +# examples of invoking this Makefile: +# make -f make_tm4c123 # make and run the tests in the current directory +# make -f make_tm4c123 TESTS=philo*.py # make and run the selected tests +# make -f make_tm4c123 HOST=localhost:7705 # connect to host:port +# make -f make_tm4c123 norun # only make but not run the tests +# make -f make_tm4c123 clean # cleanup the build +# +# NOTE: +# To use this Makefile on Windows, you will need the GNU make utility, which +# is included in the QTools collection for Windows, see: +# https://github.com/QuantumLeaps/qtools +# + +#----------------------------------------------------------------------------- +# project name, target name, target directory: +# +PROJECT := test_philo +TARGET := tm4c123 +TARGET_DIR := ..\..\..\..\3rd_party\ek-tm4c123gxl\qutest + +#----------------------------------------------------------------------------- +# project directories: +# + +# location of the QP/C framework (if not provided in an env. variable) +ifeq ($(QPC),) +QPC := ../../../.. +endif + +# QP port used in this project +QP_PORT_DIR := $(QPC)/ports/arm-cm/qutest + +# make sure that QTOOLS env. variable is defined... +ifeq ("$(wildcard $(QTOOLS))","") +$(error QTOOLS not found. Please install QTools and define QTOOLS env. variable) +endif + + +# list of all source directories used by this project +VPATH := . \ + ../src \ + $(TARGET_DIR) \ + $(QPC)/src/qf \ + $(QPC)/src/qs \ + $(QP_PORT_DIR) \ + $(QPC)/3rd_party/ek-tm4c123gxl \ + $(QPC)/3rd_party/ek-tm4c123gxl/gnu + +# list of all include directories needed by this project +INCLUDES = -I. \ + -I../src \ + -I$(TARGET_DIR) \ + -I$(QPC)/include \ + -I$(QP_PORT_DIR) \ + -I$(QPC)/3rd_party/CMSIS/Include \ + -I$(QPC)/3rd_party/ek-tm4c123gxl + +#----------------------------------------------------------------------------- +# project files: +# + +# assembler source files +ASM_SRCS := + +# C source files +C_SRCS := \ + bsp.c \ + philo.c \ + test_philo.c \ + system_TM4C123GH6PM.c \ + startup_TM4C123GH6PM.c + +# C++ source files +CPP_SRCS := + +OUTPUT := $(PROJECT) +LD_SCRIPT := $(TARGET_DIR)\qutest.ld + +QP_SRCS := \ + qep_hsm.c \ + qep_msm.c \ + qf_act.c \ + qf_actq.c \ + qf_defer.c \ + qf_dyn.c \ + qf_mem.c \ + qf_ps.c \ + qf_qact.c \ + qf_qeq.c \ + qf_qmact.c \ + qf_time.c \ + qs.c \ + qs_64bit.c \ + qs_rx.c \ + qs_fp.c \ + qutest.c \ + qutest_port.c + +QP_ASMS := + +LIB_DIRS := +LIBS := + +# defines +DEFINES := -DTARGET_IS_TM4C123_RB1 + +# ARM CPU, ARCH, FPU, and Float-ABI types... +# ARM_CPU: [cortex-m0 | cortex-m0plus | cortex-m1 | cortex-m3 | cortex-m4] +# ARM_FPU: [ | vfp] +# FLOAT_ABI: [ | soft | softfp | hard] +# +ARM_CPU := -mcpu=cortex-m4 +ARM_FPU := -mfpu=vfp +FLOAT_ABI := -mfloat-abi=softfp + +#----------------------------------------------------------------------------- +# GNU-ARM toolset (NOTE: You need to adjust to your machine) +# see https://developer.arm.com/open-source/gnu-toolchain/gnu-rm/downloads +# +ifeq ($(GNU_ARM),) +GNU_ARM := $(QTOOLS)/gnu_arm-none-eabi +endif + +# make sure that the GNU-ARM toolset exists... +ifeq ("$(wildcard $(GNU_ARM))","") +$(error GNU_ARM toolset not found. Please adjust the Makefile) +endif + +CC := $(GNU_ARM)/bin/arm-none-eabi-gcc +CPP := $(GNU_ARM)/bin/arm-none-eabi-g++ +AS := $(GNU_ARM)/bin/arm-none-eabi-as +LINK := $(GNU_ARM)/bin/arm-none-eabi-gcc +BIN := $(GNU_ARM)/bin/arm-none-eabi-objcopy + +#----------------------------------------------------------------------------- +# NOTE: The following symbol LMFLASH assumes that LMFlash.exe can +# be found on the PATH. You might need to adjust this symbol to the +# location of the LMFlash utility on your machine +# +ifeq ($(LMFLASH),) +FLASH := LMFlash.exe -q ek-tm4c123gxl +endif + +############################################################################## +# Typically you should not need to change anything below this line + +# basic utilities (included in QTools for Windows), see: +# https://www.state-machine.com/qtools + +MKDIR := mkdir +RM := rm + +#----------------------------------------------------------------------------- +# QUTest test script utilities (requires QTOOLS): +# +ifeq ("$(wildcard $(QUTEST))","") +QUTEST := python3 $(QTOOLS)/qutest/qutest.py +endif + +#----------------------------------------------------------------------------- +# build options +# + +# combine all the soruces... +C_SRCS += $(QP_SRCS) +ASM_SRCS += $(QP_ASMS) + +BIN_DIR := build_$(TARGET) + +ASFLAGS = -g $(ARM_CPU) $(ARM_FPU) $(ASM_CPU) $(ASM_FPU) + +CFLAGS = -c -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \ + -ffunction-sections -fdata-sections \ + -O $(INCLUDES) $(DEFINES) -DQ_SPY -DQ_UTEST + +CPPFLAGS = -c -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \ + -ffunction-sections -fdata-sections -fno-rtti -fno-exceptions \ + -O $(INCLUDES) $(DEFINES) -DQ_SPY -DQ_UTEST + + +LINKFLAGS = -T$(LD_SCRIPT) $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb \ + -specs=nosys.specs -specs=nano.specs \ + -Wl,-Map,$(BIN_DIR)/$(OUTPUT).map,--cref,--gc-sections $(LIB_DIRS) + +ASM_OBJS := $(patsubst %.s,%.o, $(notdir $(ASM_SRCS))) +C_OBJS := $(patsubst %.c,%.o, $(notdir $(C_SRCS))) +CPP_OBJS := $(patsubst %.cpp,%.o,$(notdir $(CPP_SRCS))) + +TARGET_BIN := $(BIN_DIR)/$(OUTPUT).bin +TARGET_ELF := $(BIN_DIR)/$(OUTPUT).elf +ASM_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(ASM_OBJS)) +C_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(C_OBJS)) +C_DEPS_EXT := $(patsubst %.o, %.d, $(C_OBJS_EXT)) +CPP_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(CPP_OBJS)) +CPP_DEPS_EXT := $(patsubst %.o, %.d, $(CPP_OBJS_EXT)) + +# create $(BIN_DIR) if it does not exist +ifeq ("$(wildcard $(BIN_DIR))","") +$(shell $(MKDIR) $(BIN_DIR)) +endif + +#----------------------------------------------------------------------------- +# rules +# + +.PHONY : run norun flash + +ifeq ($(MAKECMDGOALS),norun) +all : $(TARGET_BIN) +norun : all +else +all : $(TARGET_BIN) run +endif + +$(TARGET_BIN) : $(TARGET_ELF) + $(BIN) -O binary $< $@ + $(FLASH) $@ + @echo + @echo Reset the board MANUALLY! + @pause + +$(TARGET_ELF) : $(ASM_OBJS_EXT) $(C_OBJS_EXT) $(CPP_OBJS_EXT) + $(CC) $(CFLAGS) $(QPC)/src/qs/qstamp.c -o $(BIN_DIR)/qstamp.o + $(LINK) $(LINKFLAGS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) + +flash : + $(FLASH) $(TARGET_BIN) + @echo + @echo Reset the board MANUALLY! + +run : $(TARGET_BIN) + $(QUTEST) -q$(QSPY) -l$(LOG) -o$(OPT) -- $(TESTS) + +$(BIN_DIR)/%.d : %.c + $(CC) -MM -MT $(@:.d=.o) $(CFLAGS) $< > $@ + +$(BIN_DIR)/%.d : %.cpp + $(CPP) -MM -MT $(@:.d=.o) $(CPPFLAGS) $< > $@ + +$(BIN_DIR)/%.o : %.s + $(AS) $(ASFLAGS) $< -o $@ + +$(BIN_DIR)/%.o : %.c + $(CC) $(CFLAGS) $< -o $@ + +$(BIN_DIR)/%.o : %.cpp + $(CPP) $(CPPFLAGS) $< -o $@ + +.PHONY : clean show + +# include dependency files only if our goal depends on their existence +ifneq ($(MAKECMDGOALS),clean) + ifneq ($(MAKECMDGOALS),show) +-include $(C_DEPS_EXT) $(CPP_DEPS_EXT) + endif +endif + +clean : + -$(RM) $(BIN_DIR)/*.o \ + $(BIN_DIR)/*.d \ + $(BIN_DIR)/*.bin \ + $(BIN_DIR)/*.elf \ + $(BIN_DIR)/*.map + +show : + @echo PROJECT = $(PROJECT) + @echo TESTS = $(TESTS) + @echo TARGET_ELF = $(TARGET_ELF) + @echo CONF = $(CONF) + @echo VPATH = $(VPATH) + @echo C_SRCS = $(C_SRCS) + @echo CPP_SRCS = $(CPP_SRCS) + @echo ASM_SRCS = $(ASM_SRCS) + @echo C_DEPS_EXT = $(C_DEPS_EXT) + @echo C_OBJS_EXT = $(C_OBJS_EXT) + @echo CPP_DEPS_EXT = $(CPP_DEPS_EXT) + @echo CPP_OBJS_EXT = $(CPP_OBJS_EXT) + @echo ASM_OBJS_EXT = $(ASM_OBJS_EXT) + @echo LIB_DIRS = $(LIB_DIRS) + @echo LIBS = $(LIBS) + @echo DEFINES = $(DEFINES) + @echo QTOOLS = $(QTOOLS) + @echo HOST = $(HOST) + @echo QUTEST = $(QUTEST) + @echo TESTS = $(TESTS) + diff --git a/examples/qutest/dpp/test_philo/test_init.py b/examples/qutest/dpp/test_philo/test_init.py index 3b51ef4c..e1f3a089 100644 --- a/examples/qutest/dpp/test_philo/test_init.py +++ b/examples/qutest/dpp/test_philo/test_init.py @@ -13,7 +13,7 @@ def on_reset(): expect("@timestamp TE0-Arm Obj=Philo_inst[2].timeEvt,AO=Philo_inst[2],Tim=*,Int=0") expect("===RTC===> St-Entry Obj=Philo_inst[2],State=Philo_thinking") expect("@timestamp Init===> Obj=Philo_inst[2],State=Philo_thinking") - expect("===RTC===> St-Init Obj=Table_inst,State=QHsm_top->NULL") + expect("===RTC===> St-Init Obj=Table_dummy,State=QHsm_top->NULL") expect_run() # tests... diff --git a/examples/qutest/dpp/test_philo/test_philo.c b/examples/qutest/dpp/test_philo/test_philo.c index 0cdba6a8..f848ddbc 100644 --- a/examples/qutest/dpp/test_philo/test_philo.c +++ b/examples/qutest/dpp/test_philo/test_philo.c @@ -1,80 +1,79 @@ -/*============================================================================ -* Test fixture for DPP example -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ +//============================================================================ +// Test fixture for DPP example +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +//============================================================================ #include "qpc.h" #include "bsp.h" #include "dpp.h" -//#include "safe_std.h" /* portable "safe" / facilities */ +//#include "safe_std.h" // portable "safe" / facilities -Q_DEFINE_THIS_FILE +//Q_DEFINE_THIS_FILE -/* instantiate dummy collaborator AOs... */ -static QActiveDummy Table_inst; -QActive * const AO_Table = &Table_inst.super; +//============================================================================ +// instantiate Table AO as a dummy collaborator +static QActiveDummy Table_dummy; +QActive * const AO_Table = &Table_dummy.super; -/*..........................................................................*/ -int main(int argc, char *argv[]) { - static QEvt const *philoQueueSto[N_PHILO][N_PHILO]; - static QSubscrList subscrSto[MAX_PUB_SIG]; - static QF_MPOOL_EL(TableEvt) smlPoolSto[2*N_PHILO]; /* small pool */ +int main() { + QF_init(); // initialize the framework and the underlying RT kernel + BSP_init(); // initialize the BSP - QF_init(); /* initialize the framework and the underlying RT kernel */ - BSP_init(argc, argv); /* initialize the Board Support Package */ + QS_OBJ_DICTIONARY(&Table_dummy); - QS_OBJ_DICTIONARY(&Table_inst); - - /* pause execution of the test and wait for the test script to continue */ + // pause execution of the test and wait for the test script to continue QS_TEST_PAUSE(); - /* initialize publish-subscribe... */ - QF_psInit(subscrSto, Q_DIM(subscrSto)); - - /* initialize event pools... */ + // initialize event pools... + static QF_MPOOL_EL(TableEvt) smlPoolSto[2*N_PHILO]; // small pool QF_poolInit(smlPoolSto, sizeof(smlPoolSto), sizeof(smlPoolSto[0])); - /* start the AOs for testing... */ - uint8_t n = 2U; - Philo_ctor(n); /* instantiate all Philosopher active objects */ - QACTIVE_START(AO_Philo[n], /* AO to start */ - n + 1U, /* QP priority of the AO */ - philoQueueSto[n], /* event queue storage */ - Q_DIM(philoQueueSto[n]), /* queue length [events] */ - (void *)0, /* stack storage (not used) */ - 0U, /* size of the stack [bytes] */ - (void *)0); /* initialization param */ + // initialize publish-subscribe... + static QSubscrList subscrSto[MAX_PUB_SIG]; + QActive_psInit(subscrSto, Q_DIM(subscrSto)); - /* instantiate and start all dummy AOs... */ - QActiveDummy_ctor(&Table_inst); - QACTIVE_START(AO_Table, - N_PHILO + 1U, /* QP priority of the dummy */ + // start the active objects... + static QEvt const *philoQueueSto[N_PHILO][10]; + uint8_t n = 2U; + Philo_ctor(n); // instantiate all Philosopher active objects + QACTIVE_START(AO_Philo[n], // AO to start + n + 1U, // QP priority of the AO + philoQueueSto[n], // event queue storage + Q_DIM(philoQueueSto[n]), // queue length [events] + (void *)0, // stack storage (not used) + 0U, // size of the stack [bytes] + (void *)0); // initialization param + + // instantiate Table AO as a dummy collaborator + QActiveDummy_ctor(&Table_dummy); + QACTIVE_START(&Table_dummy, + N_PHILO + 1U, // QP priority of the dummy (QEvt const **)0, 0U, (void *)0, 0U, (void *)0); - return QF_run(); /* run the QF application */ + return QF_run(); // run the QF application } -/*..........................................................................*/ +//============================================================================ void QS_onTestSetup(void) { //PRINTF_S("%s\n", "QS_onTestSetup"); } @@ -82,8 +81,8 @@ void QS_onTestTeardown(void) { //PRINTF_S("%s\n", "QS_onTestTeardown"); } -/*..........................................................................*/ -/*! callback function to execute user commands */ +//............................................................................ +//! callback function to execute user commands void QS_onCommand(uint8_t cmdId, uint32_t param1, uint32_t param2, uint32_t param3) { @@ -93,16 +92,16 @@ void QS_onCommand(uint8_t cmdId, (void)param3; } -/****************************************************************************/ -/*! Host callback function to "massage" the event, if necessary */ +//============================================================================ +//! Host callback function to "massage" the event, if necessary void QS_onTestEvt(QEvt *e) { (void)e; -#ifdef Q_HOST /* is this test compiled for a desktop Host computer? */ -#else /* embedded Target */ -#endif /* embedded Target */ +#ifdef Q_HOST // is this test compiled for a desktop Host computer? +#else // embedded Target +#endif // embedded Target } -/*..........................................................................*/ -/*! callback function to output the posted QP events... */ +//............................................................................ +//! callback function to output the posted QP events... void QS_onTestPost(void const *sender, QActive *recipient, QEvt const *e, bool status) { @@ -112,9 +111,9 @@ void QS_onTestPost(void const *sender, QActive *recipient, case EAT_SIG: case DONE_SIG: case HUNGRY_SIG: - QS_BEGIN_ID(QUTEST_ON_POST, 0U) /* app-specific record */ + QS_BEGIN_ID(QUTEST_ON_POST, 0U) // app-specific record QS_SIG(e->sig, recipient); - QS_U8(0, Q_EVT_CAST(TableEvt)->philoNum); + QS_U8(0, Q_EVT_CAST(TableEvt)->philoId); QS_END() break; default: diff --git a/examples/qutest/dpp/test_philo/test_philo.py b/examples/qutest/dpp/test_philo/test_philo.py index b17aa955..8979c843 100644 --- a/examples/qutest/dpp/test_philo/test_philo.py +++ b/examples/qutest/dpp/test_philo/test_philo.py @@ -25,8 +25,8 @@ expect("@timestamp TE0-DisA Obj=Philo_inst[2].timeEvt,AO=Philo_inst[2]") expect("===RTC===> St-Exit Obj=Philo_inst[2],State=Philo_thinking") expect("@timestamp MP-Get Obj=EvtPool1,*") expect("@timestamp QF-New Sig=HUNGRY_SIG,*") -expect("@timestamp AO-Post Sdr=Philo_inst[2],Obj=Table_inst,Evt*") -expect("@timestamp QUTEST_ON_POST HUNGRY_SIG,Obj=Table_inst 2") +expect("@timestamp AO-Post Sdr=Philo_inst[2],Obj=Table_dummy,Evt*") +expect("@timestamp QUTEST_ON_POST HUNGRY_SIG,Obj=Table_dummy 2") expect("@timestamp QF-gc Evt St-Entry Obj=Philo_inst[2],State=Philo_hungry") @@ -59,12 +59,12 @@ expect("@timestamp TE0-Post Obj=Philo_inst[2].timeEvt,Sig=TIMEOUT_SIG,AO=Philo_i expect("@timestamp AO-Post Sdr=QS_RX,Obj=Philo_inst[2],Evt,*") expect("@timestamp AO-GetL Obj=Philo_inst[2],Evt") expect("@timestamp Disp===> Obj=Philo_inst[2],Sig=TIMEOUT_SIG,State=Philo_eating") +expect("@timestamp TE0-DisA Obj=Philo_inst[2].timeEvt,AO=Philo_inst[2]") expect("@timestamp MP-Get Obj=EvtPool1,*") expect("@timestamp QF-New Sig=DONE_SIG,*") expect("@timestamp QF-Pub Sdr=Philo_inst[2],Evt") expect("@timestamp QF-gc Evt") expect("@timestamp MP-Put Obj=EvtPool1,*") -expect("@timestamp TE0-DisA Obj=Philo_inst[2].timeEvt,AO=Philo_inst[2]") expect("===RTC===> St-Exit Obj=Philo_inst[2],State=Philo_eating") expect("@timestamp BSP_CALL BSP_random *") expect("@timestamp TE0-Arm Obj=Philo_inst[2].timeEvt,AO=Philo_inst[2],Tim=*,Int=0") @@ -84,8 +84,8 @@ expect("@timestamp TE0-DisA Obj=Philo_inst[2].timeEvt,AO=Philo_inst[2]") expect("===RTC===> St-Exit Obj=Philo_inst[2],State=Philo_thinking") expect("@timestamp MP-Get Obj=EvtPool1,*") expect("@timestamp QF-New Sig=HUNGRY_SIG,*") -expect("@timestamp AO-Post Sdr=Philo_inst[2],Obj=Table_inst,Evt St-Entry Obj=Philo_inst[2],State=Philo_hungry") diff --git a/examples/qutest/dpp/test_philo/test_vc.vcxproj b/examples/qutest/dpp/test_philo/test_vc.vcxproj index 9afe2df1..16ef85c5 100644 --- a/examples/qutest/dpp/test_philo/test_vc.vcxproj +++ b/examples/qutest/dpp/test_philo/test_vc.vcxproj @@ -18,6 +18,7 @@ + @@ -111,6 +112,7 @@ ProgramDatabase 4127 Default + stdc11 ws2_32.lib;%(AdditionalDependencies) @@ -139,6 +141,7 @@ Level4 ProgramDatabase 4127 + stdc11 %(AdditionalDependencies) @@ -167,6 +170,7 @@ Level4 ProgramDatabase 4127 + stdc11 ws2_32.lib;%(AdditionalDependencies) diff --git a/examples/qutest/dpp/test_philo/test_vc.vcxproj.filters b/examples/qutest/dpp/test_philo/test_vc.vcxproj.filters index c5d5ed45..5e6ddbd5 100644 --- a/examples/qutest/dpp/test_philo/test_vc.vcxproj.filters +++ b/examples/qutest/dpp/test_philo/test_vc.vcxproj.filters @@ -58,6 +58,9 @@ QP + + QP + diff --git a/examples/qutest/dpp/test_table/Makefile b/examples/qutest/dpp/test_table/Makefile index f0e4c6db..eb7fa502 100644 --- a/examples/qutest/dpp/test_table/Makefile +++ b/examples/qutest/dpp/test_table/Makefile @@ -218,7 +218,7 @@ all : $(TARGET_EXE) run endif $(TARGET_EXE) : $(C_OBJS_EXT) $(CPP_OBJS_EXT) - $(CC) $(CFLAGS) $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o + $(CC) $(CFLAGS) $(QPC)/src/qs/qstamp.c -o $(BIN_DIR)/qstamp.o $(LINK) $(LINKFLAGS) $(LIB_DIRS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) run : $(TARGET_EXE) diff --git a/examples/qutest/dpp/test_table/make_efm32 b/examples/qutest/dpp/test_table/make_efm32 index 7fe95c6e..e37bbcd7 100644 --- a/examples/qutest/dpp/test_table/make_efm32 +++ b/examples/qutest/dpp/test_table/make_efm32 @@ -253,7 +253,7 @@ $(TARGET_BIN) : $(TARGET_ELF) $(FLASH) $@ $(TARGET_ELF) : $(ASM_OBJS_EXT) $(C_OBJS_EXT) $(CPP_OBJS_EXT) - $(CC) $(CFLAGS) $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o + $(CC) $(CFLAGS) $(QPC)/src/qs/qstamp.c -o $(BIN_DIR)/qstamp.o $(LINK) $(LINKFLAGS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) flash : diff --git a/examples/qutest/dpp/test_table/make_tm4c123 b/examples/qutest/dpp/test_table/make_tm4c123 index dc4ff3d3..b83a3e04 100644 --- a/examples/qutest/dpp/test_table/make_tm4c123 +++ b/examples/qutest/dpp/test_table/make_tm4c123 @@ -254,7 +254,7 @@ $(TARGET_BIN) : $(TARGET_ELF) @pause $(TARGET_ELF) : $(ASM_OBJS_EXT) $(C_OBJS_EXT) $(CPP_OBJS_EXT) - $(CC) $(CFLAGS) $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o + $(CC) $(CFLAGS) $(QPC)/src/qs/qstamp.c -o $(BIN_DIR)/qstamp.o $(LINK) $(LINKFLAGS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) flash : diff --git a/examples/qutest/dpp/test_table/test_init.py b/examples/qutest/dpp/test_table/test_init.py index 7a5f56ff..7da2e372 100644 --- a/examples/qutest/dpp/test_table/test_init.py +++ b/examples/qutest/dpp/test_table/test_init.py @@ -7,16 +7,16 @@ def on_reset(): glb_filter(GRP_ALL) loc_filter(IDS_ALL, -IDS_AP) continue_test() - expect("===RTC===> St-Init Obj=Philo_inst[0],State=QHsm_top->NULL") - expect("@timestamp AO-Subsc Obj=Philo_inst[0],Sig=EAT_SIG") - expect("===RTC===> St-Init Obj=Philo_inst[1],State=QHsm_top->NULL") - expect("@timestamp AO-Subsc Obj=Philo_inst[1],Sig=EAT_SIG") - expect("===RTC===> St-Init Obj=Philo_inst[2],State=QHsm_top->NULL") - expect("@timestamp AO-Subsc Obj=Philo_inst[2],Sig=EAT_SIG") - expect("===RTC===> St-Init Obj=Philo_inst[3],State=QHsm_top->NULL") - expect("@timestamp AO-Subsc Obj=Philo_inst[3],Sig=EAT_SIG") - expect("===RTC===> St-Init Obj=Philo_inst[4],State=QHsm_top->NULL") - expect("@timestamp AO-Subsc Obj=Philo_inst[4],Sig=EAT_SIG") + expect("===RTC===> St-Init Obj=Philo_dummy[0],State=QHsm_top->NULL") + expect("@timestamp AO-Subsc Obj=Philo_dummy[0],Sig=EAT_SIG") + expect("===RTC===> St-Init Obj=Philo_dummy[1],State=QHsm_top->NULL") + expect("@timestamp AO-Subsc Obj=Philo_dummy[1],Sig=EAT_SIG") + expect("===RTC===> St-Init Obj=Philo_dummy[2],State=QHsm_top->NULL") + expect("@timestamp AO-Subsc Obj=Philo_dummy[2],Sig=EAT_SIG") + expect("===RTC===> St-Init Obj=Philo_dummy[3],State=QHsm_top->NULL") + expect("@timestamp AO-Subsc Obj=Philo_dummy[3],Sig=EAT_SIG") + expect("===RTC===> St-Init Obj=Philo_dummy[4],State=QHsm_top->NULL") + expect("@timestamp AO-Subsc Obj=Philo_dummy[4],Sig=EAT_SIG") expect("@timestamp AO-Subsc Obj=Table_inst,Sig=DONE_SIG") expect("@timestamp AO-Subsc Obj=Table_inst,Sig=PAUSE_SIG") expect("@timestamp AO-Subsc Obj=Table_inst,Sig=SERVE_SIG") diff --git a/examples/qutest/dpp/test_table/test_table.c b/examples/qutest/dpp/test_table/test_table.c index 199bcce7..bd168e78 100644 --- a/examples/qutest/dpp/test_table/test_table.c +++ b/examples/qutest/dpp/test_table/test_table.c @@ -1,107 +1,102 @@ -/***************************************************************************** -* Product: QUTEST fixture for the DPP components -* Last updated for version 6.4.0 -* Last updated on 2019-02-08 -* -* Q u a n t u m L e a P s -* ------------------------ -* Modern Embedded Software -* -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* -* -*****************************************************************************/ +//============================================================================ +// Product: QUTEST fixture for the DPP components +// Last updated for version 7.3.0 +// Last updated on 2023-06-23 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// This program is open source software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Alternatively, this program may be distributed and modified under the +// terms of Quantum Leaps commercial licenses, which expressly supersede +// the GNU General Public License and are specifically designed for +// licensees interested in retaining the proprietary status of their code. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Contact information: +// +// +//============================================================================ #include "qpc.h" #include "bsp.h" #include "dpp.h" -//#include "safe_std.h" /* portable "safe" / facilities */ +//#include "safe_std.h" // portable "safe" / facilities -Q_DEFINE_THIS_FILE +//Q_DEFINE_THIS_FILE -/* instantiate dummy collaborator AOs... */ -static QActiveDummy Philo_inst[N_PHILO]; +// instantiate dummy collaborator AOs... +static QActiveDummy Philo_dummy[N_PHILO]; QActive * const AO_Philo[N_PHILO] = { - &Philo_inst[0].super, - &Philo_inst[1].super, - &Philo_inst[2].super, - &Philo_inst[3].super, - &Philo_inst[4].super + &Philo_dummy[0].super, + &Philo_dummy[1].super, + &Philo_dummy[2].super, + &Philo_dummy[3].super, + &Philo_dummy[4].super }; -/*..........................................................................*/ -int main(int argc, char *argv[]) { - static QEvt const *tableQueueSto[N_PHILO]; - static QSubscrList subscrSto[MAX_PUB_SIG]; - static QF_MPOOL_EL(TableEvt) smlPoolSto[2*N_PHILO]; /* small pool */ - uint8_t n; +int main() { + QF_init(); // initialize the framework and the underlying RT kernel + BSP_init(); // initialize the BSP - QF_init(); /* initialize the framework and the underlying RT kernel */ - BSP_init(argc, argv); /* initialize the Board Support Package */ + for (uint8_t n = 0U; n < N_PHILO; ++n) { + QS_OBJ_ARR_DICTIONARY(&Philo_dummy[n], n); + } - QS_OBJ_DICTIONARY(&Philo_inst[0]); - QS_OBJ_DICTIONARY(&Philo_inst[1]); - QS_OBJ_DICTIONARY(&Philo_inst[2]); - QS_OBJ_DICTIONARY(&Philo_inst[3]); - QS_OBJ_DICTIONARY(&Philo_inst[4]); - - /* pause execution of the test and wait for the test script to continue */ + // pause execution of the test and wait for the test script to continue QS_TEST_PAUSE(); - /* initialize publish-subscribe... */ - QF_psInit(subscrSto, Q_DIM(subscrSto)); + // initialize publish-subscribe... + static QSubscrList subscrSto[MAX_PUB_SIG]; + QActive_psInit(subscrSto, Q_DIM(subscrSto)); - /* initialize event pools... */ + // initialize event pools... + static QF_MPOOL_EL(TableEvt) smlPoolSto[2*N_PHILO]; // small pool QF_poolInit(smlPoolSto, sizeof(smlPoolSto), sizeof(smlPoolSto[0])); - /* start and setup dummy AOs... - * NOTE: You need to start dummy AOs, if you wish to subscribe - * them to events. - */ - for (n = 0; n < N_PHILO; ++n) { - QActiveDummy_ctor(&Philo_inst[n]); - QACTIVE_START(AO_Philo[n], - (uint_fast8_t)(n + 1U), /* priority */ + // start and setup dummy AOs... + // NOTE: You need to start dummy AOs, if you wish to subscribe + // them to events. + // + for (uint8_t n = 0U; n < N_PHILO; ++n) { + QActiveDummy_ctor(&Philo_dummy[n]); + QACTIVE_START(&Philo_dummy[n], + (uint_fast8_t)(n + 1U), // priority (QEvt const **)0, 0U, (void *)0, 0U, (QEvt const *)0); QActive_subscribe(AO_Philo[n], EAT_SIG); } - /* start the active objects... */ - Table_ctor(); /* instantiate the Table active object */ - QACTIVE_START(AO_Table, /* AO to start */ - (uint_fast8_t)(N_PHILO + 1), /* QP priority of the AO */ - tableQueueSto, /* event queue storage */ - Q_DIM(tableQueueSto), /* queue length [events] */ - (void *)0, /* stack storage (not used) */ - 0U, /* size of the stack [bytes] */ - (void *)0); /* initialization param */ + // start the active objects... + Table_ctor(); // instantiate the Table active object + static QEvt const *tableQueueSto[N_PHILO]; + QACTIVE_START(AO_Table, // AO to start + (uint_fast8_t)(N_PHILO + 1), // QP priority of the AO + tableQueueSto, // event queue storage + Q_DIM(tableQueueSto), // queue length [events] + (void *)0, // stack storage (not used) + 0U, // size of the stack [bytes] + (void *)0); // initialization param - return QF_run(); /* run the QF application */ + return QF_run(); // run the QF application } -/*..........................................................................*/ +//............................................................................ void QS_onTestSetup(void) { //PRINTF_S("%s\n", "QS_onTestSetup"); } @@ -109,8 +104,8 @@ void QS_onTestTeardown(void) { //PRINTF_S("%s\n", "QS_onTestTeardown"); } -/*..........................................................................*/ -/*! callback function to execute user commands */ +//............................................................................ +//! callback function to execute user commands void QS_onCommand(uint8_t cmdId, uint32_t param1, uint32_t param2, uint32_t param3) { @@ -121,13 +116,13 @@ void QS_onCommand(uint8_t cmdId, switch (cmdId) { case 0U: { - QEvt const e = { PAUSE_SIG, 0U, 0U }; - QHSM_DISPATCH(&AO_Table->super, &e, AO_Table->prio); + QEvt const e = QEVT_INITIALIZER( PAUSE_SIG); + QASM_DISPATCH(AO_Table, &e, AO_Table->prio); break; } case 1U: { - QEvt const e = { SERVE_SIG, 0U, 0U }; - QHSM_DISPATCH(&AO_Table->super, &e, AO_Table->prio); + QEvt const e = QEVT_INITIALIZER(SERVE_SIG); + QASM_DISPATCH(AO_Table, &e, AO_Table->prio); break; } default: @@ -135,16 +130,16 @@ void QS_onCommand(uint8_t cmdId, } } -/****************************************************************************/ -/*! Host callback function to "massage" the event, if necessary */ +//============================================================================ +//! Host callback function to "massage" the event, if necessary void QS_onTestEvt(QEvt *e) { (void)e; -#ifdef Q_HOST /* is this test compiled for a desktop Host computer? */ -#else /* embedded Target */ -#endif /* embedded Target */ +#ifdef Q_HOST // is this test compiled for a desktop Host computer? +#else // embedded Target +#endif // embedded Target } -/*..........................................................................*/ -/*! callback function to output the posted QP events (not used here) */ +//............................................................................ +//! callback function to output the posted QP events (not used here) void QS_onTestPost(void const *sender, QActive *recipient, QEvt const *e, bool status) { @@ -154,9 +149,9 @@ void QS_onTestPost(void const *sender, QActive *recipient, case EAT_SIG: case DONE_SIG: case HUNGRY_SIG: - QS_BEGIN_ID(QUTEST_ON_POST, 0U) /* app-specific record */ + QS_BEGIN_ID(QUTEST_ON_POST, 0U) // app-specific record QS_SIG(e->sig, recipient); - QS_U8(0, Q_EVT_CAST(TableEvt)->philoNum); + QS_U8(0, Q_EVT_CAST(TableEvt)->philoId); QS_END() break; default: diff --git a/examples/qutest/dpp/test_table/test_vc.sln b/examples/qutest/dpp/test_table/test_vc.sln new file mode 100644 index 00000000..fc1e7c19 --- /dev/null +++ b/examples/qutest/dpp/test_table/test_vc.sln @@ -0,0 +1,18 @@ +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 2013 +VisualStudioVersion = 12.0.31101.0 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_vc", "test_vc.vcxproj", "{8CC465F7-872E-4D03-B93C-1B64858B4E11}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {8CC465F7-872E-4D03-B93C-1B64858B4E11}.Debug|Win32.ActiveCfg = Debug|Win32 + {8CC465F7-872E-4D03-B93C-1B64858B4E11}.Debug|Win32.Build.0 = Debug|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/examples/workstation/qhsmtst/qhsmtst.vcxproj b/examples/qutest/dpp/test_table/test_vc.vcxproj similarity index 75% rename from examples/workstation/qhsmtst/qhsmtst.vcxproj rename to examples/qutest/dpp/test_table/test_vc.vcxproj index bbcd1cb3..e1cbc464 100644 --- a/examples/workstation/qhsmtst/qhsmtst.vcxproj +++ b/examples/qutest/dpp/test_table/test_vc.vcxproj @@ -1,4 +1,4 @@ - + @@ -14,9 +14,44 @@ Win32 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {8CC465F7-872E-4D03-B93C-1B64858B4E11} - qhsmtst + test_vc Win32Proj 10.0 @@ -65,8 +100,8 @@ Disabled - .;../../../include;../../../ports/win32-qv;%(AdditionalIncludeDirectories) - WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + ../src;../../../../include;../../../../ports/win32-qutest;%(AdditionalIncludeDirectories) + Q_SPY;Q_UTEST;Q_HOST;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) false @@ -77,9 +112,10 @@ ProgramDatabase 4127 Default + stdc11 - %(AdditionalDependencies) + ws2_32.lib;%(AdditionalDependencies) %(AdditionalLibraryDirectories) true Console @@ -94,7 +130,7 @@ MaxSpeed true .;../../../include;../../../ports/win32-qv;%(AdditionalIncludeDirectories) - NDEBUG;WIN32;_CONSOLE;%(PreprocessorDefinitions) + NDEBUG;snprintf=_snprintf;WIN32;_CONSOLE;%(PreprocessorDefinitions) false @@ -105,6 +141,7 @@ Level4 ProgramDatabase 4127 + stdc11 %(AdditionalDependencies) @@ -122,7 +159,7 @@ Disabled - .;../../../include;../../../ports/win32-qv;%(AdditionalIncludeDirectories) + .;../../../include;../../../ports/win32-qv;$(QTOOLS)/qspy/include;%(AdditionalIncludeDirectories) Q_SPY;WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) false @@ -133,6 +170,7 @@ Level4 ProgramDatabase 4127 + stdc11 ws2_32.lib;%(AdditionalDependencies) @@ -145,39 +183,6 @@ cmd /c "del $(OutDir)qstamp.obj" - - - - - true - false - true - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/examples/arm-cm/blinky_ek-tm4c123gxl/qube/qube_vs.vcxproj.filters b/examples/qutest/dpp/test_table/test_vc.vcxproj.filters similarity index 56% rename from examples/arm-cm/blinky_ek-tm4c123gxl/qube/qube_vs.vcxproj.filters rename to examples/qutest/dpp/test_table/test_vc.vcxproj.filters index d1f23e55..37d9c988 100644 --- a/examples/arm-cm/blinky_ek-tm4c123gxl/qube/qube_vs.vcxproj.filters +++ b/examples/qutest/dpp/test_table/test_vc.vcxproj.filters @@ -1,13 +1,7 @@ - + - - - qube_vs - - - - + QP @@ -41,6 +35,9 @@ QP + + QP_port + QP @@ -50,28 +47,48 @@ QP + + QP + QP + + QP + + + + + QP + - - - qube_vs + + + + QP_port - - qube_vs + + QP_port - - qube_vs + + QP_port + + + QP_port - - {8a14cc5f-5520-4870-80c8-16a728dd5b06} + + {15103d7c-b0a8-453a-9329-6af825548fd7} - - {b3b54046-9fb7-4796-b157-31c169faf065} + + {68f070e7-350f-4ab4-9c94-e6029017b9a0} + + + QP_port + + \ No newline at end of file diff --git a/examples/qutest/evt_par/src/my_ao.c b/examples/qutest/evt_par/src/my_ao.c index e2cd2f0b..2902a43e 100644 --- a/examples/qutest/evt_par/src/my_ao.c +++ b/examples/qutest/evt_par/src/my_ao.c @@ -3,32 +3,32 @@ //Q_DEFINE_THIS_FILE -/* MyAO declaration --------------------------------------------------------*/ +// MyAO declaration -------------------------------------------------------- typedef struct { QActive super; -/* private: */ +// private: } MyAO; -/* protected: */ +// protected: static QState MyAO_initial(MyAO * const me, QEvt const * const e); static QState MyAO_active(MyAO * const me, QEvt const * const e); -/* Local objects -----------------------------------------------------------*/ -static MyAO l_MyAO; /* the single instance of the MyAO active object */ +// Local objects ----------------------------------------------------------- +static MyAO l_MyAO; // the single instance of the MyAO active object -/* Global-scope objects ----------------------------------------------------*/ -QActive * const AO_MyAO = &l_MyAO.super; /* "opaque" AO pointer */ +// Global-scope objects ---------------------------------------------------- +QActive * const AO_MyAO = &l_MyAO.super; // "opaque" AO pointer -/* MyAO_ctor ...............................................................*/ +// MyAO_ctor ............................................................... void MyAO_ctor(void) { MyAO *me = &l_MyAO; QActive_ctor(&me->super, Q_STATE_CAST(&MyAO_initial)); } -/* MyAO::SM ................................................................*/ +// MyAO::SM ................................................................ static QState MyAO_initial(MyAO * const me, QEvt const * const e) { - (void)e; /* unused parameter */ + (void)e; // unused parameter QS_FUN_DICTIONARY(&MyAO_initial); QS_FUN_DICTIONARY(&MyAO_active); @@ -40,7 +40,7 @@ static QState MyAO_initial(MyAO * const me, QEvt const * const e) { return Q_TRAN(&MyAO_active); } -/*${AOs::MyAO::SM::active} ................................................*/ +//${AOs::MyAO::SM::active} ................................................ static QState MyAO_active(MyAO * const me, QEvt const * const e) { QState status_; switch (e->sig) { diff --git a/examples/qutest/evt_par/src/my_app.h b/examples/qutest/evt_par/src/my_app.h index 045565ec..c92c0641 100644 --- a/examples/qutest/evt_par/src/my_app.h +++ b/examples/qutest/evt_par/src/my_app.h @@ -4,28 +4,28 @@ enum MySignals { MY_EVT0_SIG = Q_USER_SIG, MY_EVT1_SIG, - MAX_PUB_SIG, /* the last published signal */ + MAX_PUB_SIG, // the last published signal MY_EVT2_SIG, MY_EVT3_SIG, - MAX_SIG /* the last signal */ + MAX_SIG // the last signal }; typedef struct { - QEvt super; /* inherit QEvt */ + QEvt super; // inherit QEvt uint32_t u32; } MyEvt1; typedef struct { - QEvt super; /* inherit QEvt */ + QEvt super; // inherit QEvt uint32_t u32; uint16_t u16; } MyEvt2; typedef struct { - QEvt super; /* inherit QEvt */ + QEvt super; // inherit QEvt uint32_t u32; uint16_t u16; @@ -36,4 +36,4 @@ typedef struct { void MyAO_ctor(void); extern QActive * const AO_MyAO; -#endif /* MY_APP_H */ +#endif // MY_APP_H diff --git a/examples/qutest/evt_par/test/Makefile b/examples/qutest/evt_par/test/Makefile index 0f9ddc06..c04000f2 100644 --- a/examples/qutest/evt_par/test/Makefile +++ b/examples/qutest/evt_par/test/Makefile @@ -217,7 +217,7 @@ all : $(TARGET_EXE) run endif $(TARGET_EXE) : $(C_OBJS_EXT) $(CPP_OBJS_EXT) - $(CC) $(CFLAGS) $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o + $(CC) $(CFLAGS) $(QPC)/src/qs/qstamp.c -o $(BIN_DIR)/qstamp.o $(LINK) $(LINKFLAGS) $(LIB_DIRS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) run : $(TARGET_EXE) diff --git a/examples/qutest/evt_par/test/make_tm4c123 b/examples/qutest/evt_par/test/make_tm4c123 index e5774af3..88509b3e 100644 --- a/examples/qutest/evt_par/test/make_tm4c123 +++ b/examples/qutest/evt_par/test/make_tm4c123 @@ -253,7 +253,7 @@ $(TARGET_BIN) : $(TARGET_ELF) @pause $(TARGET_ELF) : $(ASM_OBJS_EXT) $(C_OBJS_EXT) $(CPP_OBJS_EXT) - $(CC) $(CFLAGS) $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o + $(CC) $(CFLAGS) $(QPC)/src/qs/qstamp.c -o $(BIN_DIR)/qstamp.o $(LINK) $(LINKFLAGS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) flash : diff --git a/examples/qutest/evt_par/test/test_evt_par.c b/examples/qutest/evt_par/test/test_evt_par.c index de876ada..03c30a2a 100644 --- a/examples/qutest/evt_par/test/test_evt_par.c +++ b/examples/qutest/evt_par/test/test_evt_par.c @@ -1,77 +1,79 @@ -/***************************************************************************** -* Purpose: example event QUTEST fixture -* Last Updated for Version: 6.3.6 -* Date of the Last Update: 2018-10-04 -* -* Q u a n t u m L e a P s -* ------------------------ -* Modern Embedded Software -* -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* -* -*****************************************************************************/ -#include "qpc.h" /* QUTest interface */ -#include "my_app.h" /* My Application */ +//============================================================================ +// Purpose: example event QUTEST fixture +// Last Updated for Version: 7.3.0 +// Date of the Last Update: 2023-05-25 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// This program is open source software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Alternatively, this program may be distributed and modified under the +// terms of Quantum Leaps commercial licenses, which expressly supersede +// the GNU General Public License and are specifically designed for +// licensees interested in retaining the proprietary status of their code. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Contact information: +// +// +//============================================================================ +#include "qpc.h" // QUTest interface +#include "my_app.h" // My Application Q_DEFINE_THIS_FILE -/*..........................................................................*/ +//............................................................................ int main(int argc, char *argv[]) { static QSubscrList subscrSto[MAX_PUB_SIG]; static QF_MPOOL_EL(MyEvt3) smlPoolSto[10]; static QEvt const *myAoQueueSto[10]; - QF_init(); /* initialize the framework */ + QF_init(); // initialize the framework - /* initialize the QS software tracing */ - Q_ALLEGE(QS_INIT(argc > 1 ? argv[1] : (void *)0)); + // initialize the QS software tracing + if (QS_INIT((argc > 1) ? argv[1] : (void *)0) == 0U) { + Q_ERROR(); + } - /* object dictionaries... */ + // object dictionaries... QS_OBJ_DICTIONARY(AO_MyAO); QS_TEST_PAUSE(); - /* initialize publish-subscribe... */ - QF_psInit(subscrSto, Q_DIM(subscrSto)); + // initialize publish-subscribe... + QActive_psInit(subscrSto, Q_DIM(subscrSto)); - /* initialize event pools... */ + // initialize event pools... QF_poolInit(smlPoolSto, sizeof(smlPoolSto), sizeof(smlPoolSto[0])); - /* start active objects... */ - MyAO_ctor(); /* instantiate the MyAO active object */ - QACTIVE_START(AO_MyAO, /* AO to start */ - (uint_fast8_t)1, /* QP priority of the AO */ - myAoQueueSto, /* event queue storage */ - Q_DIM(myAoQueueSto), /* queue length [events] */ - (void *)0, /* stack storage (not used) */ - 0U, /* size of the stack [bytes] */ - (QEvt *)0); /* initialization event */ + // start active objects... + MyAO_ctor(); // instantiate the MyAO active object + QACTIVE_START(AO_MyAO, // AO to start + (uint_fast8_t)1, // QP priority of the AO + myAoQueueSto, // event queue storage + Q_DIM(myAoQueueSto), // queue length [events] + (void *)0, // stack storage (not used) + 0U, // size of the stack [bytes] + (QEvt *)0); // initialization event - return QF_run(); /* run the QF application */ + return QF_run(); // run the QF application } -/*--------------------------------------------------------------------------*/ +//---------------------------------------------------------------------------- enum AppSpecRecords { MY_EVT0 = QS_USER, MY_EVT1, @@ -79,24 +81,24 @@ enum AppSpecRecords { MY_EVT3 }; -/*--------------------------------------------------------------------------*/ +//---------------------------------------------------------------------------- void QS_onTestSetup(void) { QS_USR_DICTIONARY(MY_EVT0); QS_USR_DICTIONARY(MY_EVT1); QS_USR_DICTIONARY(MY_EVT2); QS_USR_DICTIONARY(MY_EVT3); } -/*..........................................................................*/ +//............................................................................ void QS_onTestTeardown(void) { } -/*..........................................................................*/ +//............................................................................ void QS_onCommand(uint8_t cmdId, uint32_t param1, uint32_t param2, uint32_t param3) { - (void)param1; /* unused parameter */ - (void)param2; /* unused parameter */ - (void)param3; /* unused parameter */ + (void)param1; // unused parameter + (void)param2; // unused parameter + (void)param3; // unused parameter switch (cmdId) { case 0: { @@ -106,28 +108,28 @@ void QS_onCommand(uint8_t cmdId, break; } } -/*..........................................................................*/ -/*! callback function to "massage" the injected QP events (not used here) */ +//............................................................................ +//! callback function to "massage" the injected QP events (not used here) void QS_onTestEvt(QEvt *e) { switch (e->sig) { case MY_EVT0_SIG: - QS_BEGIN_ID(MY_EVT0, 0U) /* app-specific record */ + QS_BEGIN_ID(MY_EVT0, 0U) // app-specific record QS_END() break; case MY_EVT1_SIG: - QS_BEGIN_ID(MY_EVT1, 0U) /* app-specific record */ + QS_BEGIN_ID(MY_EVT1, 0U) // app-specific record QS_U32(0, Q_EVT_CAST(MyEvt1)->u32); QS_END() break; case MY_EVT2_SIG: - QS_BEGIN_ID(MY_EVT2, 0U) /* app-specific record */ + QS_BEGIN_ID(MY_EVT2, 0U) // app-specific record QS_U32(0, Q_EVT_CAST(MyEvt2)->u32); QS_U32(0, Q_EVT_CAST(MyEvt2)->u16); QS_END() break; case MY_EVT3_SIG: - QS_BEGIN_ID(MY_EVT3, 0U) /* app-specific record */ + QS_BEGIN_ID(MY_EVT3, 0U) // app-specific record QS_U32(0, Q_EVT_CAST(MyEvt3)->u32); QS_U32(0, Q_EVT_CAST(MyEvt3)->u16); QS_U32(0, Q_EVT_CAST(MyEvt3)->u8); @@ -135,12 +137,12 @@ void QS_onTestEvt(QEvt *e) { break; } -#ifdef Q_HOST /* is this test compiled for a desktop Host computer? */ -#else /* embedded Target */ -#endif /* embedded Target */ +#ifdef Q_HOST // is this test compiled for a desktop Host computer? +#else // embedded Target +#endif // embedded Target } -/*..........................................................................*/ -/*! callback function to output the posted QP events (not used here) */ +//............................................................................ +//! callback function to output the posted QP events (not used here) void QS_onTestPost(void const *sender, QActive *recipient, QEvt const *e, bool status) { diff --git a/examples/qutest/qhsmtst/src/qhsmtst.c b/examples/qutest/qhsmtst/src/qhsmtst.c index 5e20d3a0..f4c513ce 100644 --- a/examples/qutest/qhsmtst/src/qhsmtst.c +++ b/examples/qutest/qhsmtst/src/qhsmtst.c @@ -1,48 +1,51 @@ -/*$file${src::qhsmtst.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* -* Model: qhsmtst.qm -* File: ${src::qhsmtst.c} -* -* This code has been generated by QM 5.2.4 . -* DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. -* -* SPDX-License-Identifier: GPL-3.0-or-later -* -* This generated code is open source software: you can redistribute it under -* the terms of the GNU General Public License as published by the Free -* Software Foundation. -* -* This code is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -* more details. -* -* NOTE: -* Alternatively, this generated code may be distributed under the terms -* of Quantum Leaps commercial licenses, which expressly supersede the GNU -* General Public License and are specifically designed for licensees -* interested in retaining the proprietary status of their code. -* -* Contact information: -* -* -*/ -/*$endhead${src::qhsmtst.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -#include "qpc.h" -#include "qhsmtst.h" +//$file${.::qhsmtst.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// +// Model: qhsmtst.qm +// File: ${.::qhsmtst.c} +// +// This code has been generated by QM 5.3.0 . +// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. +// +// SPDX-License-Identifier: GPL-3.0-or-later +// +// This generated code is open source software: you can redistribute it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation. +// +// This code is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// NOTE: +// Alternatively, this generated code may be distributed under the terms +// of Quantum Leaps commercial licenses, which expressly supersede the GNU +// General Public License and are specifically designed for licensees +// interested in retaining the proprietary status of their code. +// +// Contact information: +// +// +// +//$endhead${.::qhsmtst.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +#include "qpc.h" // QP/C framework +#include "qhsmtst.h" // this application -/*$declare${HSMs::QHsmTst} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//$declare${SMs::QHsmTst} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/*${HSMs::QHsmTst} .........................................................*/ -typedef struct { -/* protected: */ +//${SMs::QHsmTst} ............................................................ +typedef struct QHsmTst { +// protected: QHsm super; -/* private: */ +// private: uint8_t foo; -} QHsmTst; -/* protected: */ +// public: +} QHsmTst; +extern QHsmTst QHsmTst_inst; + +// protected: static QState QHsmTst_initial(QHsmTst * const me, void const * const par); static QState QHsmTst_s(QHsmTst * const me, QEvt const * const e); static QState QHsmTst_s1(QHsmTst * const me, QEvt const * const e); @@ -50,50 +53,50 @@ static QState QHsmTst_s11(QHsmTst * const me, QEvt const * const e); static QState QHsmTst_s2(QHsmTst * const me, QEvt const * const e); static QState QHsmTst_s21(QHsmTst * const me, QEvt const * const e); static QState QHsmTst_s211(QHsmTst * const me, QEvt const * const e); -/*$enddecl${HSMs::QHsmTst} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ - -static QHsmTst l_hsmtst; /* the only instance of the QHsmTst class */ - -/* global-scope definitions ---------------------------------------*/ -QHsm * const the_hsm = (QHsm *)&l_hsmtst; /* the opaque pointer */ - -/*$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* Check for the minimum required QP version */ -#if (QP_VERSION < 700U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) -#error qpc version 7.0.0 or higher required +//$enddecl${SMs::QHsmTst} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +//$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// Check for the minimum required QP version +#if (QP_VERSION < 730U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) +#error qpc version 7.3.0 or higher required #endif -/*$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -/*$define${HSMs::QHsmTst_ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//$define${Shared::the_sm} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/*${HSMs::QHsmTst_ctor} ....................................................*/ +//${Shared::the_sm} .......................................................... +QAsm * const the_sm = &QHsmTst_inst.super.super; +//$enddef${Shared::the_sm} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +//$define${Shared::QHsmTst_ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${Shared::QHsmTst_ctor} .................................................... void QHsmTst_ctor(void) { - QHsmTst *me = &l_hsmtst; + QHsmTst *me = &QHsmTst_inst; QHsm_ctor(&me->super, Q_STATE_CAST(&QHsmTst_initial)); } -/*$enddef${HSMs::QHsmTst_ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*$define${HSMs::QHsmTst} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//$enddef${Shared::QHsmTst_ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +//$define${SMs::QHsmTst} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/*${HSMs::QHsmTst} .........................................................*/ +//${SMs::QHsmTst} ............................................................ +QHsmTst QHsmTst_inst; -/*${HSMs::QHsmTst::SM} .....................................................*/ +//${SMs::QHsmTst::SM} ........................................................ static QState QHsmTst_initial(QHsmTst * const me, void const * const par) { - /*${HSMs::QHsmTst::SM::initial} */ - (void)par; /* unused parameter */ + //${SMs::QHsmTst::SM::initial} + Q_UNUSED_PAR(par); me->foo = 0U; BSP_display("top-INIT;"); - QS_SIG_DICTIONARY(A_SIG, me); - QS_SIG_DICTIONARY(B_SIG, me); - QS_SIG_DICTIONARY(C_SIG, me); - QS_SIG_DICTIONARY(D_SIG, me); - QS_SIG_DICTIONARY(E_SIG, me); - QS_SIG_DICTIONARY(F_SIG, me); - QS_SIG_DICTIONARY(G_SIG, me); - QS_SIG_DICTIONARY(H_SIG, me); - QS_SIG_DICTIONARY(I_SIG, me); - QS_SIG_DICTIONARY(TERMINATE_SIG, me); - QS_SIG_DICTIONARY(IGNORE_SIG, me); + QS_SIG_DICTIONARY(A_SIG, (void *)0); + QS_SIG_DICTIONARY(B_SIG, (void *)0); + QS_SIG_DICTIONARY(C_SIG, (void *)0); + QS_SIG_DICTIONARY(D_SIG, (void *)0); + QS_SIG_DICTIONARY(E_SIG, (void *)0); + QS_SIG_DICTIONARY(F_SIG, (void *)0); + QS_SIG_DICTIONARY(G_SIG, (void *)0); + QS_SIG_DICTIONARY(H_SIG, (void *)0); + QS_SIG_DICTIONARY(I_SIG, (void *)0); + QS_SIG_DICTIONARY(IGNORE_SIG, (void *)0); + QS_SIG_DICTIONARY(TERMINATE_SIG, (void *)0); QS_FUN_DICTIONARY(&QHsmTst_s); QS_FUN_DICTIONARY(&QHsmTst_s1); @@ -105,31 +108,31 @@ static QState QHsmTst_initial(QHsmTst * const me, void const * const par) { return Q_TRAN(&QHsmTst_s2); } -/*${HSMs::QHsmTst::SM::s} ..................................................*/ +//${SMs::QHsmTst::SM::s} ..................................................... static QState QHsmTst_s(QHsmTst * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${HSMs::QHsmTst::SM::s} */ + //${SMs::QHsmTst::SM::s} case Q_ENTRY_SIG: { BSP_display("s-ENTRY;"); status_ = Q_HANDLED(); break; } - /*${HSMs::QHsmTst::SM::s} */ + //${SMs::QHsmTst::SM::s} case Q_EXIT_SIG: { BSP_display("s-EXIT;"); status_ = Q_HANDLED(); break; } - /*${HSMs::QHsmTst::SM::s::initial} */ + //${SMs::QHsmTst::SM::s::initial} case Q_INIT_SIG: { BSP_display("s-INIT;"); status_ = Q_TRAN(&QHsmTst_s11); break; } - /*${HSMs::QHsmTst::SM::s::I} */ + //${SMs::QHsmTst::SM::s::I} case I_SIG: { - /*${HSMs::QHsmTst::SM::s::I::[me->foo]} */ + //${SMs::QHsmTst::SM::s::I::[me->foo]} if (me->foo) { me->foo = 0U; BSP_display("s-I;"); @@ -140,15 +143,15 @@ static QState QHsmTst_s(QHsmTst * const me, QEvt const * const e) { } break; } - /*${HSMs::QHsmTst::SM::s::E} */ + //${SMs::QHsmTst::SM::s::E} case E_SIG: { BSP_display("s-E;"); status_ = Q_TRAN(&QHsmTst_s11); break; } - /*${HSMs::QHsmTst::SM::s::TERMINATE} */ + //${SMs::QHsmTst::SM::s::TERMINATE} case TERMINATE_SIG: { - BSP_exit(); + BSP_terminate(0); status_ = Q_HANDLED(); break; } @@ -160,37 +163,37 @@ static QState QHsmTst_s(QHsmTst * const me, QEvt const * const e) { return status_; } -/*${HSMs::QHsmTst::SM::s::s1} ..............................................*/ +//${SMs::QHsmTst::SM::s::s1} ................................................. static QState QHsmTst_s1(QHsmTst * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${HSMs::QHsmTst::SM::s::s1} */ + //${SMs::QHsmTst::SM::s::s1} case Q_ENTRY_SIG: { BSP_display("s1-ENTRY;"); status_ = Q_HANDLED(); break; } - /*${HSMs::QHsmTst::SM::s::s1} */ + //${SMs::QHsmTst::SM::s::s1} case Q_EXIT_SIG: { BSP_display("s1-EXIT;"); status_ = Q_HANDLED(); break; } - /*${HSMs::QHsmTst::SM::s::s1::initial} */ + //${SMs::QHsmTst::SM::s::s1::initial} case Q_INIT_SIG: { BSP_display("s1-INIT;"); status_ = Q_TRAN(&QHsmTst_s11); break; } - /*${HSMs::QHsmTst::SM::s::s1::I} */ + //${SMs::QHsmTst::SM::s::s1::I} case I_SIG: { BSP_display("s1-I;"); status_ = Q_HANDLED(); break; } - /*${HSMs::QHsmTst::SM::s::s1::D} */ + //${SMs::QHsmTst::SM::s::s1::D} case D_SIG: { - /*${HSMs::QHsmTst::SM::s::s1::D::[!me->foo]} */ + //${SMs::QHsmTst::SM::s::s1::D::[!me->foo]} if (!me->foo) { me->foo = 1U; BSP_display("s1-D;"); @@ -201,25 +204,25 @@ static QState QHsmTst_s1(QHsmTst * const me, QEvt const * const e) { } break; } - /*${HSMs::QHsmTst::SM::s::s1::A} */ + //${SMs::QHsmTst::SM::s::s1::A} case A_SIG: { BSP_display("s1-A;"); status_ = Q_TRAN(&QHsmTst_s1); break; } - /*${HSMs::QHsmTst::SM::s::s1::B} */ + //${SMs::QHsmTst::SM::s::s1::B} case B_SIG: { BSP_display("s1-B;"); status_ = Q_TRAN(&QHsmTst_s11); break; } - /*${HSMs::QHsmTst::SM::s::s1::F} */ + //${SMs::QHsmTst::SM::s::s1::F} case F_SIG: { BSP_display("s1-F;"); status_ = Q_TRAN(&QHsmTst_s211); break; } - /*${HSMs::QHsmTst::SM::s::s1::C} */ + //${SMs::QHsmTst::SM::s::s1::C} case C_SIG: { BSP_display("s1-C;"); status_ = Q_TRAN(&QHsmTst_s2); @@ -233,31 +236,31 @@ static QState QHsmTst_s1(QHsmTst * const me, QEvt const * const e) { return status_; } -/*${HSMs::QHsmTst::SM::s::s1::s11} .........................................*/ +//${SMs::QHsmTst::SM::s::s1::s11} ............................................ static QState QHsmTst_s11(QHsmTst * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${HSMs::QHsmTst::SM::s::s1::s11} */ + //${SMs::QHsmTst::SM::s::s1::s11} case Q_ENTRY_SIG: { BSP_display("s11-ENTRY;"); status_ = Q_HANDLED(); break; } - /*${HSMs::QHsmTst::SM::s::s1::s11} */ + //${SMs::QHsmTst::SM::s::s1::s11} case Q_EXIT_SIG: { BSP_display("s11-EXIT;"); status_ = Q_HANDLED(); break; } - /*${HSMs::QHsmTst::SM::s::s1::s11::H} */ + //${SMs::QHsmTst::SM::s::s1::s11::H} case H_SIG: { BSP_display("s11-H;"); status_ = Q_TRAN(&QHsmTst_s); break; } - /*${HSMs::QHsmTst::SM::s::s1::s11::D} */ + //${SMs::QHsmTst::SM::s::s1::s11::D} case D_SIG: { - /*${HSMs::QHsmTst::SM::s::s1::s11::D::[me->foo]} */ + //${SMs::QHsmTst::SM::s::s1::s11::D::[me->foo]} if (me->foo) { me->foo = 0U; BSP_display("s11-D;"); @@ -268,7 +271,7 @@ static QState QHsmTst_s11(QHsmTst * const me, QEvt const * const e) { } break; } - /*${HSMs::QHsmTst::SM::s::s1::s11::G} */ + //${SMs::QHsmTst::SM::s::s1::s11::G} case G_SIG: { BSP_display("s11-G;"); status_ = Q_TRAN(&QHsmTst_s211); @@ -282,31 +285,31 @@ static QState QHsmTst_s11(QHsmTst * const me, QEvt const * const e) { return status_; } -/*${HSMs::QHsmTst::SM::s::s2} ..............................................*/ +//${SMs::QHsmTst::SM::s::s2} ................................................. static QState QHsmTst_s2(QHsmTst * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${HSMs::QHsmTst::SM::s::s2} */ + //${SMs::QHsmTst::SM::s::s2} case Q_ENTRY_SIG: { BSP_display("s2-ENTRY;"); status_ = Q_HANDLED(); break; } - /*${HSMs::QHsmTst::SM::s::s2} */ + //${SMs::QHsmTst::SM::s::s2} case Q_EXIT_SIG: { BSP_display("s2-EXIT;"); status_ = Q_HANDLED(); break; } - /*${HSMs::QHsmTst::SM::s::s2::initial} */ + //${SMs::QHsmTst::SM::s::s2::initial} case Q_INIT_SIG: { BSP_display("s2-INIT;"); status_ = Q_TRAN(&QHsmTst_s211); break; } - /*${HSMs::QHsmTst::SM::s::s2::I} */ + //${SMs::QHsmTst::SM::s::s2::I} case I_SIG: { - /*${HSMs::QHsmTst::SM::s::s2::I::[!me->foo]} */ + //${SMs::QHsmTst::SM::s::s2::I::[!me->foo]} if (!me->foo) { me->foo = 1U; BSP_display("s2-I;"); @@ -317,13 +320,13 @@ static QState QHsmTst_s2(QHsmTst * const me, QEvt const * const e) { } break; } - /*${HSMs::QHsmTst::SM::s::s2::F} */ + //${SMs::QHsmTst::SM::s::s2::F} case F_SIG: { BSP_display("s2-F;"); status_ = Q_TRAN(&QHsmTst_s11); break; } - /*${HSMs::QHsmTst::SM::s::s2::C} */ + //${SMs::QHsmTst::SM::s::s2::C} case C_SIG: { BSP_display("s2-C;"); status_ = Q_TRAN(&QHsmTst_s1); @@ -337,41 +340,41 @@ static QState QHsmTst_s2(QHsmTst * const me, QEvt const * const e) { return status_; } -/*${HSMs::QHsmTst::SM::s::s2::s21} .........................................*/ +//${SMs::QHsmTst::SM::s::s2::s21} ............................................ static QState QHsmTst_s21(QHsmTst * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${HSMs::QHsmTst::SM::s::s2::s21} */ + //${SMs::QHsmTst::SM::s::s2::s21} case Q_ENTRY_SIG: { BSP_display("s21-ENTRY;"); status_ = Q_HANDLED(); break; } - /*${HSMs::QHsmTst::SM::s::s2::s21} */ + //${SMs::QHsmTst::SM::s::s2::s21} case Q_EXIT_SIG: { BSP_display("s21-EXIT;"); status_ = Q_HANDLED(); break; } - /*${HSMs::QHsmTst::SM::s::s2::s21::initial} */ + //${SMs::QHsmTst::SM::s::s2::s21::initial} case Q_INIT_SIG: { BSP_display("s21-INIT;"); status_ = Q_TRAN(&QHsmTst_s211); break; } - /*${HSMs::QHsmTst::SM::s::s2::s21::G} */ + //${SMs::QHsmTst::SM::s::s2::s21::G} case G_SIG: { BSP_display("s21-G;"); status_ = Q_TRAN(&QHsmTst_s1); break; } - /*${HSMs::QHsmTst::SM::s::s2::s21::A} */ + //${SMs::QHsmTst::SM::s::s2::s21::A} case A_SIG: { BSP_display("s21-A;"); status_ = Q_TRAN(&QHsmTst_s21); break; } - /*${HSMs::QHsmTst::SM::s::s2::s21::B} */ + //${SMs::QHsmTst::SM::s::s2::s21::B} case B_SIG: { BSP_display("s21-B;"); status_ = Q_TRAN(&QHsmTst_s211); @@ -385,29 +388,29 @@ static QState QHsmTst_s21(QHsmTst * const me, QEvt const * const e) { return status_; } -/*${HSMs::QHsmTst::SM::s::s2::s21::s211} ...................................*/ +//${SMs::QHsmTst::SM::s::s2::s21::s211} ...................................... static QState QHsmTst_s211(QHsmTst * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${HSMs::QHsmTst::SM::s::s2::s21::s211} */ + //${SMs::QHsmTst::SM::s::s2::s21::s211} case Q_ENTRY_SIG: { BSP_display("s211-ENTRY;"); status_ = Q_HANDLED(); break; } - /*${HSMs::QHsmTst::SM::s::s2::s21::s211} */ + //${SMs::QHsmTst::SM::s::s2::s21::s211} case Q_EXIT_SIG: { BSP_display("s211-EXIT;"); status_ = Q_HANDLED(); break; } - /*${HSMs::QHsmTst::SM::s::s2::s21::s211::H} */ + //${SMs::QHsmTst::SM::s::s2::s21::s211::H} case H_SIG: { BSP_display("s211-H;"); status_ = Q_TRAN(&QHsmTst_s); break; } - /*${HSMs::QHsmTst::SM::s::s2::s21::s211::D} */ + //${SMs::QHsmTst::SM::s::s2::s21::s211::D} case D_SIG: { BSP_display("s211-D;"); status_ = Q_TRAN(&QHsmTst_s21); @@ -420,4 +423,4 @@ static QState QHsmTst_s211(QHsmTst * const me, QEvt const * const e) { } return status_; } -/*$enddef${HSMs::QHsmTst} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$enddef${SMs::QHsmTst} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/examples/qutest/qhsmtst/src/qhsmtst.h b/examples/qutest/qhsmtst/src/qhsmtst.h index e18b1542..68f96e40 100644 --- a/examples/qutest/qhsmtst/src/qhsmtst.h +++ b/examples/qutest/qhsmtst/src/qhsmtst.h @@ -1,36 +1,39 @@ -/*$file${src::qhsmtst.h} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* -* Model: qhsmtst.qm -* File: ${src::qhsmtst.h} -* -* This code has been generated by QM 5.2.4 . -* DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. -* -* SPDX-License-Identifier: GPL-3.0-or-later -* -* This generated code is open source software: you can redistribute it under -* the terms of the GNU General Public License as published by the Free -* Software Foundation. -* -* This code is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -* more details. -* -* NOTE: -* Alternatively, this generated code may be distributed under the terms -* of Quantum Leaps commercial licenses, which expressly supersede the GNU -* General Public License and are specifically designed for licensees -* interested in retaining the proprietary status of their code. -* -* Contact information: -* -* -*/ -/*$endhead${src::qhsmtst.h} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -#ifndef QHSMTST_H -#define QHSMTST_H +//$file${.::qhsmtst.h} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// +// Model: qhsmtst.qm +// File: ${.::qhsmtst.h} +// +// This code has been generated by QM 5.3.0 . +// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. +// +// SPDX-License-Identifier: GPL-3.0-or-later +// +// This generated code is open source software: you can redistribute it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation. +// +// This code is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// NOTE: +// Alternatively, this generated code may be distributed under the terms +// of Quantum Leaps commercial licenses, which expressly supersede the GNU +// General Public License and are specifically designed for licensees +// interested in retaining the proprietary status of their code. +// +// Contact information: +// +// +// +//$endhead${.::qhsmtst.h} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +#ifndef QHSMTST_H_ +#define QHSMTST_H_ +//$declare${Shared} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${Shared::QHsmTstSignals} .................................................. enum QHsmTstSignals { A_SIG = Q_USER_SIG, B_SIG, @@ -46,17 +49,17 @@ enum QHsmTstSignals { MAX_SIG }; -extern QHsm * const the_hsm; /* opaque pointer to the test HSM */ +//${Shared::the_sm} .......................................................... +extern QAsm * const the_sm; -/*$declare${HSMs::QHsmTst_ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${HSMs::QHsmTst_ctor} ....................................................*/ +//${Shared::QHsmTst_ctor} .................................................... void QHsmTst_ctor(void); -/*$enddecl${HSMs::QHsmTst_ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/* BSP functions to dispaly a message and exit */ -void BSP_display(char const *msg); -void BSP_exit(void); +//${Shared::BSP_display} ..................................................... +void BSP_display(char const * msg); -#endif /* QHSMTST_H */ +//${Shared::BSP_terminate} ................................................... +void BSP_terminate(int16_t const result); +//$enddecl${Shared} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +#endif // QHSMTST_H_ diff --git a/examples/qutest/qhsmtst/qhsmtst.qm b/examples/qutest/qhsmtst/src/qhsmtst.qm similarity index 68% rename from examples/qutest/qhsmtst/qhsmtst.qm rename to examples/qutest/qhsmtst/src/qhsmtst.qm index cc0bc557..3b6dee0d 100644 --- a/examples/qutest/qhsmtst/qhsmtst.qm +++ b/examples/qutest/qhsmtst/src/qhsmtst.qm @@ -1,52 +1,94 @@ - + QHsmTst is a contrived state machine from Chapter 2 of the PSiCC2 book for testing all possible transition topologies with up to 4-levels of state nesting. - - - + + + + + { + A_SIG = Q_USER_SIG, + B_SIG, + C_SIG, + D_SIG, + E_SIG, + F_SIG, + G_SIG, + H_SIG, + I_SIG, + TERMINATE_SIG, + IGNORE_SIG, + MAX_SIG +}; + + + + opaque pointer to the test SM + = &QHsmTst_inst.super.super; + + + + QHsmTst *me = &QHsmTst_inst; +QHsm_ctor(&me->super, Q_STATE_CAST(&QHsmTst_initial)); + + + + + + + + + + + + + + + Test active object - + - + + + - + - (void)par; /* unused parameter */ + Q_UNUSED_PAR(par); me->foo = 0U; BSP_display("top-INIT;"); -QS_SIG_DICTIONARY(A_SIG, me); -QS_SIG_DICTIONARY(B_SIG, me); -QS_SIG_DICTIONARY(C_SIG, me); -QS_SIG_DICTIONARY(D_SIG, me); -QS_SIG_DICTIONARY(E_SIG, me); -QS_SIG_DICTIONARY(F_SIG, me); -QS_SIG_DICTIONARY(G_SIG, me); -QS_SIG_DICTIONARY(H_SIG, me); -QS_SIG_DICTIONARY(I_SIG, me); -QS_SIG_DICTIONARY(TERMINATE_SIG, me); -QS_SIG_DICTIONARY(IGNORE_SIG, me); +QS_SIG_DICTIONARY(A_SIG, (void *)0); +QS_SIG_DICTIONARY(B_SIG, (void *)0); +QS_SIG_DICTIONARY(C_SIG, (void *)0); +QS_SIG_DICTIONARY(D_SIG, (void *)0); +QS_SIG_DICTIONARY(E_SIG, (void *)0); +QS_SIG_DICTIONARY(F_SIG, (void *)0); +QS_SIG_DICTIONARY(G_SIG, (void *)0); +QS_SIG_DICTIONARY(H_SIG, (void *)0); +QS_SIG_DICTIONARY(I_SIG, (void *)0); +QS_SIG_DICTIONARY(IGNORE_SIG, (void *)0); +QS_SIG_DICTIONARY(TERMINATE_SIG, (void *)0); - + - + BSP_display("s-ENTRY;"); BSP_display("s-EXIT;"); - + BSP_display("s-INIT;"); - + - + me->foo me->foo = 0U; @@ -59,41 +101,41 @@ BSP_display("s-I;"); - + BSP_display("s-E;"); - + - BSP_exit(); + BSP_terminate(0); - + BSP_display("s1-ENTRY;"); BSP_display("s1-EXIT;"); - + BSP_display("s1-INIT;"); - + BSP_display("s1-I;"); - + - + !me->foo me->foo = 1U; @@ -106,48 +148,48 @@ BSP_display("s1-D;"); - + BSP_display("s1-A;"); - + BSP_display("s1-B;"); - + BSP_display("s1-F;"); - + BSP_display("s1-C;"); - + BSP_display("s11-ENTRY;"); BSP_display("s11-EXIT;"); - + BSP_display("s11-H;"); - + - + me->foo me->foo = 0U; @@ -160,7 +202,7 @@ BSP_display("s11-D;"); - + BSP_display("s11-G;"); @@ -177,20 +219,20 @@ BSP_display("s11-D;"); - + BSP_display("s2-ENTRY;"); BSP_display("s2-EXIT;"); - + BSP_display("s2-INIT;"); - + - + !me->foo me->foo = 1U; @@ -203,64 +245,64 @@ BSP_display("s2-I;"); - + BSP_display("s2-F;"); - + BSP_display("s2-C;"); - + BSP_display("s21-ENTRY;"); BSP_display("s21-EXIT;"); - + BSP_display("s21-INIT;"); - + BSP_display("s21-G;"); - + BSP_display("s21-A;"); - + BSP_display("s21-B;"); - + BSP_display("s211-ENTRY;"); BSP_display("s211-EXIT;"); - + BSP_display("s211-H;"); - + BSP_display("s211-D;"); @@ -290,59 +332,27 @@ BSP_display("s2-I;"); - - - QHsmTst *me = &l_hsmtst; -QHsm_ctor(&me->super, Q_STATE_CAST(&QHsmTst_initial)); - - - - + + + - #ifndef QHSMTST_H -#define QHSMTST_H + #ifndef QHSMTST_H_ +#define QHSMTST_H_ -enum QHsmTstSignals { - A_SIG = Q_USER_SIG, - B_SIG, - C_SIG, - D_SIG, - E_SIG, - F_SIG, - G_SIG, - H_SIG, - I_SIG, - TERMINATE_SIG, - IGNORE_SIG, - MAX_SIG -}; +$declare ${Shared} -extern QHsm * const the_hsm; /* opaque pointer to the test HSM */ - -$declare(HSMs::QHsmTst_ctor) - -/* BSP functions to dispaly a message and exit */ -void BSP_display(char const *msg); -void BSP_exit(void); - -#endif /* QHSMTST_H */ - +#endif // QHSMTST_H_ - + - #include "qpc.h" -#include "qhsmtst.h" + #include "qpc.h" // QP/C framework +#include "qhsmtst.h" // this application -$declare(HSMs::QHsmTst) - -static QHsmTst l_hsmtst; /* the only instance of the QHsmTst class */ - -/* global-scope definitions ---------------------------------------*/ -QHsm * const the_hsm = (QHsm *)&l_hsmtst; /* the opaque pointer */ - -$define(HSMs::QHsmTst_ctor) -$define(HSMs::QHsmTst) +$declare ${SMs::QHsmTst} +$define ${Shared::the_sm} +$define ${Shared::QHsmTst_ctor} +$define ${SMs::QHsmTst} diff --git a/examples/qutest/qhsmtst/test/Makefile b/examples/qutest/qhsmtst/test/Makefile index 8119e1d0..e82c9e77 100644 --- a/examples/qutest/qhsmtst/test/Makefile +++ b/examples/qutest/qhsmtst/test/Makefile @@ -217,7 +217,7 @@ all : $(TARGET_EXE) run endif $(TARGET_EXE) : $(C_OBJS_EXT) $(CPP_OBJS_EXT) - $(CC) $(CFLAGS) $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o + $(CC) $(CFLAGS) $(QPC)/src/qs/qstamp.c -o $(BIN_DIR)/qstamp.o $(LINK) $(LINKFLAGS) $(LIB_DIRS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) run : $(TARGET_EXE) diff --git a/examples/qutest/qhsmtst/test/make_efm32 b/examples/qutest/qhsmtst/test/make_efm32 index 80832a45..4337d207 100644 --- a/examples/qutest/qhsmtst/test/make_efm32 +++ b/examples/qutest/qhsmtst/test/make_efm32 @@ -252,7 +252,7 @@ $(TARGET_BIN) : $(TARGET_ELF) $(FLASH) $@ $(TARGET_ELF) : $(ASM_OBJS_EXT) $(C_OBJS_EXT) $(CPP_OBJS_EXT) - $(CC) $(CFLAGS) $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o + $(CC) $(CFLAGS) $(QPC)/src/qs/qstamp.c -o $(BIN_DIR)/qstamp.o $(LINK) $(LINKFLAGS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) flash : diff --git a/examples/qutest/qhsmtst/test/make_nucleo-l053r8 b/examples/qutest/qhsmtst/test/make_nucleo-l053r8 index c4e3c945..f4222f4b 100644 --- a/examples/qutest/qhsmtst/test/make_nucleo-l053r8 +++ b/examples/qutest/qhsmtst/test/make_nucleo-l053r8 @@ -252,7 +252,7 @@ $(TARGET_BIN) : $(TARGET_ELF) $(SLEEP) 2 $(TARGET_ELF) : $(ASM_OBJS_EXT) $(C_OBJS_EXT) $(CPP_OBJS_EXT) - $(CC) $(CFLAGS) $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o + $(CC) $(CFLAGS) $(QPC)/src/qs/qstamp.c -o $(BIN_DIR)/qstamp.o $(LINK) $(LINKFLAGS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) flash : diff --git a/examples/qutest/qhsmtst/test/make_tm4c123 b/examples/qutest/qhsmtst/test/make_tm4c123 index 39b7b31e..23302b9f 100644 --- a/examples/qutest/qhsmtst/test/make_tm4c123 +++ b/examples/qutest/qhsmtst/test/make_tm4c123 @@ -253,7 +253,7 @@ $(TARGET_BIN) : $(TARGET_ELF) @pause $(TARGET_ELF) : $(ASM_OBJS_EXT) $(C_OBJS_EXT) $(CPP_OBJS_EXT) - $(CC) $(CFLAGS) $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o + $(CC) $(CFLAGS) $(QPC)/src/qs/qstamp.c -o $(BIN_DIR)/qstamp.o $(LINK) $(LINKFLAGS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) flash : diff --git a/examples/qutest/qhsmtst/test/test_qhsm-funct.py b/examples/qutest/qhsmtst/test/test_qhsm-funct.py index fc5a96f1..c36dddfc 100644 --- a/examples/qutest/qhsmtst/test/test_qhsm-funct.py +++ b/examples/qutest/qhsmtst/test/test_qhsm-funct.py @@ -5,7 +5,7 @@ def on_reset(): expect_run() glb_filter(GRP_UA) - current_obj(OBJ_SM, "the_hsm") + current_obj(OBJ_SM, "the_sm") # tests... test("QHsmTst_init") diff --git a/examples/qutest/qhsmtst/test/test_qhsm-struct.py b/examples/qutest/qhsmtst/test/test_qhsm-struct.py index ed899c86..ded4824d 100644 --- a/examples/qutest/qhsmtst/test/test_qhsm-struct.py +++ b/examples/qutest/qhsmtst/test/test_qhsm-struct.py @@ -5,209 +5,209 @@ def on_reset(): expect_run() glb_filter(GRP_SM) - current_obj(OBJ_SM, "the_hsm") + current_obj(OBJ_SM, "the_sm") # tests... test("QHsmTst init") init() -expect("===RTC===> St-Init Obj=the_hsm,State=QHsm_top->QHsmTst_s2") -expect("===RTC===> St-Entry Obj=the_hsm,State=QHsmTst_s") -expect("===RTC===> St-Entry Obj=the_hsm,State=QHsmTst_s2") -expect("===RTC===> St-Init Obj=the_hsm,State=QHsmTst_s2->QHsmTst_s211") -expect("===RTC===> St-Entry Obj=the_hsm,State=QHsmTst_s21") -expect("===RTC===> St-Entry Obj=the_hsm,State=QHsmTst_s211") -expect("@timestamp Init===> Obj=the_hsm,State=QHsmTst_s211") +expect("===RTC===> St-Init Obj=the_sm,State=QHsm_top->QHsmTst_s2") +expect("===RTC===> St-Entry Obj=the_sm,State=QHsmTst_s") +expect("===RTC===> St-Entry Obj=the_sm,State=QHsmTst_s2") +expect("===RTC===> St-Init Obj=the_sm,State=QHsmTst_s2->QHsmTst_s211") +expect("===RTC===> St-Entry Obj=the_sm,State=QHsmTst_s21") +expect("===RTC===> St-Entry Obj=the_sm,State=QHsmTst_s211") +expect("@timestamp Init===> Obj=the_sm,State=QHsmTst_s211") expect("@timestamp Trg-Done QS_RX_EVENT") test("QHsmTst dispatch", NORESET) dispatch("A_SIG") -expect("@timestamp Disp===> Obj=the_hsm,Sig=A_SIG,State=QHsmTst_s211") -expect("===RTC===> St-Exit Obj=the_hsm,State=QHsmTst_s211") -expect("===RTC===> St-Exit Obj=the_hsm,State=QHsmTst_s21") -expect("===RTC===> St-Entry Obj=the_hsm,State=QHsmTst_s21") -expect("===RTC===> St-Init Obj=the_hsm,State=QHsmTst_s21->QHsmTst_s211") -expect("===RTC===> St-Entry Obj=the_hsm,State=QHsmTst_s211") -expect("@timestamp ===>Tran Obj=the_hsm,Sig=A_SIG,State=QHsmTst_s21->QHsmTst_s211") +expect("@timestamp Disp===> Obj=the_sm,Sig=A_SIG,State=QHsmTst_s211") +expect("===RTC===> St-Exit Obj=the_sm,State=QHsmTst_s211") +expect("===RTC===> St-Exit Obj=the_sm,State=QHsmTst_s21") +expect("===RTC===> St-Entry Obj=the_sm,State=QHsmTst_s21") +expect("===RTC===> St-Init Obj=the_sm,State=QHsmTst_s21->QHsmTst_s211") +expect("===RTC===> St-Entry Obj=the_sm,State=QHsmTst_s211") +expect("@timestamp ===>Tran Obj=the_sm,Sig=A_SIG,State=QHsmTst_s21->QHsmTst_s211") expect("@timestamp Trg-Done QS_RX_EVENT") dispatch("B_SIG") -expect("@timestamp Disp===> Obj=the_hsm,Sig=B_SIG,State=QHsmTst_s211") -expect("===RTC===> St-Exit Obj=the_hsm,State=QHsmTst_s211") -expect("===RTC===> St-Entry Obj=the_hsm,State=QHsmTst_s211") -expect("@timestamp ===>Tran Obj=the_hsm,Sig=B_SIG,State=QHsmTst_s21->QHsmTst_s211") +expect("@timestamp Disp===> Obj=the_sm,Sig=B_SIG,State=QHsmTst_s211") +expect("===RTC===> St-Exit Obj=the_sm,State=QHsmTst_s211") +expect("===RTC===> St-Entry Obj=the_sm,State=QHsmTst_s211") +expect("@timestamp ===>Tran Obj=the_sm,Sig=B_SIG,State=QHsmTst_s21->QHsmTst_s211") expect("@timestamp Trg-Done QS_RX_EVENT") dispatch("D_SIG") -expect("@timestamp Disp===> Obj=the_hsm,Sig=D_SIG,State=QHsmTst_s211") -expect("===RTC===> St-Exit Obj=the_hsm,State=QHsmTst_s211") -expect("===RTC===> St-Init Obj=the_hsm,State=QHsmTst_s21->QHsmTst_s211") -expect("===RTC===> St-Entry Obj=the_hsm,State=QHsmTst_s211") -expect("@timestamp ===>Tran Obj=the_hsm,Sig=D_SIG,State=QHsmTst_s211->QHsmTst_s211") +expect("@timestamp Disp===> Obj=the_sm,Sig=D_SIG,State=QHsmTst_s211") +expect("===RTC===> St-Exit Obj=the_sm,State=QHsmTst_s211") +expect("===RTC===> St-Init Obj=the_sm,State=QHsmTst_s21->QHsmTst_s211") +expect("===RTC===> St-Entry Obj=the_sm,State=QHsmTst_s211") +expect("@timestamp ===>Tran Obj=the_sm,Sig=D_SIG,State=QHsmTst_s211->QHsmTst_s211") expect("@timestamp Trg-Done QS_RX_EVENT") dispatch("E_SIG") -expect("@timestamp Disp===> Obj=the_hsm,Sig=E_SIG,State=QHsmTst_s211") -expect("===RTC===> St-Exit Obj=the_hsm,State=QHsmTst_s211") -expect("===RTC===> St-Exit Obj=the_hsm,State=QHsmTst_s21") -expect("===RTC===> St-Exit Obj=the_hsm,State=QHsmTst_s2") -expect("===RTC===> St-Entry Obj=the_hsm,State=QHsmTst_s1") -expect("===RTC===> St-Entry Obj=the_hsm,State=QHsmTst_s11") -expect("@timestamp ===>Tran Obj=the_hsm,Sig=E_SIG,State=QHsmTst_s->QHsmTst_s11") +expect("@timestamp Disp===> Obj=the_sm,Sig=E_SIG,State=QHsmTst_s211") +expect("===RTC===> St-Exit Obj=the_sm,State=QHsmTst_s211") +expect("===RTC===> St-Exit Obj=the_sm,State=QHsmTst_s21") +expect("===RTC===> St-Exit Obj=the_sm,State=QHsmTst_s2") +expect("===RTC===> St-Entry Obj=the_sm,State=QHsmTst_s1") +expect("===RTC===> St-Entry Obj=the_sm,State=QHsmTst_s11") +expect("@timestamp ===>Tran Obj=the_sm,Sig=E_SIG,State=QHsmTst_s->QHsmTst_s11") expect("@timestamp Trg-Done QS_RX_EVENT") dispatch("I_SIG") -expect("@timestamp Disp===> Obj=the_hsm,Sig=I_SIG,State=QHsmTst_s11") -expect("@timestamp =>Intern Obj=the_hsm,Sig=I_SIG,State=QHsmTst_s1") +expect("@timestamp Disp===> Obj=the_sm,Sig=I_SIG,State=QHsmTst_s11") +expect("@timestamp =>Intern Obj=the_sm,Sig=I_SIG,State=QHsmTst_s1") expect("@timestamp Trg-Done QS_RX_EVENT") dispatch("F_SIG") -expect("@timestamp Disp===> Obj=the_hsm,Sig=F_SIG,State=QHsmTst_s11") -expect("===RTC===> St-Exit Obj=the_hsm,State=QHsmTst_s11") -expect("===RTC===> St-Exit Obj=the_hsm,State=QHsmTst_s1") -expect("===RTC===> St-Entry Obj=the_hsm,State=QHsmTst_s2") -expect("===RTC===> St-Entry Obj=the_hsm,State=QHsmTst_s21") -expect("===RTC===> St-Entry Obj=the_hsm,State=QHsmTst_s211") -expect("@timestamp ===>Tran Obj=the_hsm,Sig=F_SIG,State=QHsmTst_s1->QHsmTst_s211") +expect("@timestamp Disp===> Obj=the_sm,Sig=F_SIG,State=QHsmTst_s11") +expect("===RTC===> St-Exit Obj=the_sm,State=QHsmTst_s11") +expect("===RTC===> St-Exit Obj=the_sm,State=QHsmTst_s1") +expect("===RTC===> St-Entry Obj=the_sm,State=QHsmTst_s2") +expect("===RTC===> St-Entry Obj=the_sm,State=QHsmTst_s21") +expect("===RTC===> St-Entry Obj=the_sm,State=QHsmTst_s211") +expect("@timestamp ===>Tran Obj=the_sm,Sig=F_SIG,State=QHsmTst_s1->QHsmTst_s211") expect("@timestamp Trg-Done QS_RX_EVENT") dispatch("I_SIG") -expect("@timestamp Disp===> Obj=the_hsm,Sig=I_SIG,State=QHsmTst_s211") -expect("@timestamp =>Intern Obj=the_hsm,Sig=I_SIG,State=QHsmTst_s2") +expect("@timestamp Disp===> Obj=the_sm,Sig=I_SIG,State=QHsmTst_s211") +expect("@timestamp =>Intern Obj=the_sm,Sig=I_SIG,State=QHsmTst_s2") expect("@timestamp Trg-Done QS_RX_EVENT") dispatch("I_SIG") -expect("@timestamp Disp===> Obj=the_hsm,Sig=I_SIG,State=QHsmTst_s211") -expect("===RTC===> St-Unhnd Obj=the_hsm,Sig=I_SIG,State=QHsmTst_s2") -expect("@timestamp =>Intern Obj=the_hsm,Sig=I_SIG,State=QHsmTst_s") +expect("@timestamp Disp===> Obj=the_sm,Sig=I_SIG,State=QHsmTst_s211") +expect("===RTC===> St-Unhnd Obj=the_sm,Sig=I_SIG,State=QHsmTst_s2") +expect("@timestamp =>Intern Obj=the_sm,Sig=I_SIG,State=QHsmTst_s") expect("@timestamp Trg-Done QS_RX_EVENT") dispatch("F_SIG") -expect("@timestamp Disp===> Obj=the_hsm,Sig=F_SIG,State=QHsmTst_s211") -expect("===RTC===> St-Exit Obj=the_hsm,State=QHsmTst_s211") -expect("===RTC===> St-Exit Obj=the_hsm,State=QHsmTst_s21") -expect("===RTC===> St-Exit Obj=the_hsm,State=QHsmTst_s2") -expect("===RTC===> St-Entry Obj=the_hsm,State=QHsmTst_s1") -expect("===RTC===> St-Entry Obj=the_hsm,State=QHsmTst_s11") -expect("@timestamp ===>Tran Obj=the_hsm,Sig=F_SIG,State=QHsmTst_s2->QHsmTst_s11") +expect("@timestamp Disp===> Obj=the_sm,Sig=F_SIG,State=QHsmTst_s211") +expect("===RTC===> St-Exit Obj=the_sm,State=QHsmTst_s211") +expect("===RTC===> St-Exit Obj=the_sm,State=QHsmTst_s21") +expect("===RTC===> St-Exit Obj=the_sm,State=QHsmTst_s2") +expect("===RTC===> St-Entry Obj=the_sm,State=QHsmTst_s1") +expect("===RTC===> St-Entry Obj=the_sm,State=QHsmTst_s11") +expect("@timestamp ===>Tran Obj=the_sm,Sig=F_SIG,State=QHsmTst_s2->QHsmTst_s11") expect("@timestamp Trg-Done QS_RX_EVENT") dispatch("A_SIG") -expect("@timestamp Disp===> Obj=the_hsm,Sig=A_SIG,State=QHsmTst_s11") -expect("===RTC===> St-Exit Obj=the_hsm,State=QHsmTst_s11") -expect("===RTC===> St-Exit Obj=the_hsm,State=QHsmTst_s1") -expect("===RTC===> St-Entry Obj=the_hsm,State=QHsmTst_s1") -expect("===RTC===> St-Init Obj=the_hsm,State=QHsmTst_s1->QHsmTst_s11") -expect("===RTC===> St-Entry Obj=the_hsm,State=QHsmTst_s11") -expect("@timestamp ===>Tran Obj=the_hsm,Sig=A_SIG,State=QHsmTst_s1->QHsmTst_s11") +expect("@timestamp Disp===> Obj=the_sm,Sig=A_SIG,State=QHsmTst_s11") +expect("===RTC===> St-Exit Obj=the_sm,State=QHsmTst_s11") +expect("===RTC===> St-Exit Obj=the_sm,State=QHsmTst_s1") +expect("===RTC===> St-Entry Obj=the_sm,State=QHsmTst_s1") +expect("===RTC===> St-Init Obj=the_sm,State=QHsmTst_s1->QHsmTst_s11") +expect("===RTC===> St-Entry Obj=the_sm,State=QHsmTst_s11") +expect("@timestamp ===>Tran Obj=the_sm,Sig=A_SIG,State=QHsmTst_s1->QHsmTst_s11") expect("@timestamp Trg-Done QS_RX_EVENT") dispatch("B_SIG") -expect("@timestamp Disp===> Obj=the_hsm,Sig=B_SIG,State=QHsmTst_s11") -expect("===RTC===> St-Exit Obj=the_hsm,State=QHsmTst_s11") -expect("===RTC===> St-Entry Obj=the_hsm,State=QHsmTst_s11") -expect("@timestamp ===>Tran Obj=the_hsm,Sig=B_SIG,State=QHsmTst_s1->QHsmTst_s11") +expect("@timestamp Disp===> Obj=the_sm,Sig=B_SIG,State=QHsmTst_s11") +expect("===RTC===> St-Exit Obj=the_sm,State=QHsmTst_s11") +expect("===RTC===> St-Entry Obj=the_sm,State=QHsmTst_s11") +expect("@timestamp ===>Tran Obj=the_sm,Sig=B_SIG,State=QHsmTst_s1->QHsmTst_s11") expect("@timestamp Trg-Done QS_RX_EVENT") dispatch("D_SIG") -expect("@timestamp Disp===> Obj=the_hsm,Sig=D_SIG,State=QHsmTst_s11") -expect("===RTC===> St-Unhnd Obj=the_hsm,Sig=D_SIG,State=QHsmTst_s11") -expect("===RTC===> St-Exit Obj=the_hsm,State=QHsmTst_s11") -expect("===RTC===> St-Exit Obj=the_hsm,State=QHsmTst_s1") -expect("===RTC===> St-Init Obj=the_hsm,State=QHsmTst_s->QHsmTst_s11") -expect("===RTC===> St-Entry Obj=the_hsm,State=QHsmTst_s1") -expect("===RTC===> St-Entry Obj=the_hsm,State=QHsmTst_s11") -expect("@timestamp ===>Tran Obj=the_hsm,Sig=D_SIG,State=QHsmTst_s1->QHsmTst_s11") +expect("@timestamp Disp===> Obj=the_sm,Sig=D_SIG,State=QHsmTst_s11") +expect("===RTC===> St-Unhnd Obj=the_sm,Sig=D_SIG,State=QHsmTst_s11") +expect("===RTC===> St-Exit Obj=the_sm,State=QHsmTst_s11") +expect("===RTC===> St-Exit Obj=the_sm,State=QHsmTst_s1") +expect("===RTC===> St-Init Obj=the_sm,State=QHsmTst_s->QHsmTst_s11") +expect("===RTC===> St-Entry Obj=the_sm,State=QHsmTst_s1") +expect("===RTC===> St-Entry Obj=the_sm,State=QHsmTst_s11") +expect("@timestamp ===>Tran Obj=the_sm,Sig=D_SIG,State=QHsmTst_s1->QHsmTst_s11") expect("@timestamp Trg-Done QS_RX_EVENT") dispatch("D_SIG") -expect("@timestamp Disp===> Obj=the_hsm,Sig=D_SIG,State=QHsmTst_s11") -expect("===RTC===> St-Exit Obj=the_hsm,State=QHsmTst_s11") -expect("===RTC===> St-Init Obj=the_hsm,State=QHsmTst_s1->QHsmTst_s11") -expect("===RTC===> St-Entry Obj=the_hsm,State=QHsmTst_s11") -expect("@timestamp ===>Tran Obj=the_hsm,Sig=D_SIG,State=QHsmTst_s11->QHsmTst_s11") +expect("@timestamp Disp===> Obj=the_sm,Sig=D_SIG,State=QHsmTst_s11") +expect("===RTC===> St-Exit Obj=the_sm,State=QHsmTst_s11") +expect("===RTC===> St-Init Obj=the_sm,State=QHsmTst_s1->QHsmTst_s11") +expect("===RTC===> St-Entry Obj=the_sm,State=QHsmTst_s11") +expect("@timestamp ===>Tran Obj=the_sm,Sig=D_SIG,State=QHsmTst_s11->QHsmTst_s11") expect("@timestamp Trg-Done QS_RX_EVENT") dispatch("E_SIG") -expect("@timestamp Disp===> Obj=the_hsm,Sig=E_SIG,State=QHsmTst_s11") -expect("===RTC===> St-Exit Obj=the_hsm,State=QHsmTst_s11") -expect("===RTC===> St-Exit Obj=the_hsm,State=QHsmTst_s1") -expect("===RTC===> St-Entry Obj=the_hsm,State=QHsmTst_s1") -expect("===RTC===> St-Entry Obj=the_hsm,State=QHsmTst_s11") -expect("@timestamp ===>Tran Obj=the_hsm,Sig=E_SIG,State=QHsmTst_s->QHsmTst_s11") +expect("@timestamp Disp===> Obj=the_sm,Sig=E_SIG,State=QHsmTst_s11") +expect("===RTC===> St-Exit Obj=the_sm,State=QHsmTst_s11") +expect("===RTC===> St-Exit Obj=the_sm,State=QHsmTst_s1") +expect("===RTC===> St-Entry Obj=the_sm,State=QHsmTst_s1") +expect("===RTC===> St-Entry Obj=the_sm,State=QHsmTst_s11") +expect("@timestamp ===>Tran Obj=the_sm,Sig=E_SIG,State=QHsmTst_s->QHsmTst_s11") expect("@timestamp Trg-Done QS_RX_EVENT") dispatch("G_SIG") -expect("@timestamp Disp===> Obj=the_hsm,Sig=G_SIG,State=QHsmTst_s11") -expect("===RTC===> St-Exit Obj=the_hsm,State=QHsmTst_s11") -expect("===RTC===> St-Exit Obj=the_hsm,State=QHsmTst_s1") -expect("===RTC===> St-Entry Obj=the_hsm,State=QHsmTst_s2") -expect("===RTC===> St-Entry Obj=the_hsm,State=QHsmTst_s21") -expect("===RTC===> St-Entry Obj=the_hsm,State=QHsmTst_s211") -expect("@timestamp ===>Tran Obj=the_hsm,Sig=G_SIG,State=QHsmTst_s11->QHsmTst_s211") +expect("@timestamp Disp===> Obj=the_sm,Sig=G_SIG,State=QHsmTst_s11") +expect("===RTC===> St-Exit Obj=the_sm,State=QHsmTst_s11") +expect("===RTC===> St-Exit Obj=the_sm,State=QHsmTst_s1") +expect("===RTC===> St-Entry Obj=the_sm,State=QHsmTst_s2") +expect("===RTC===> St-Entry Obj=the_sm,State=QHsmTst_s21") +expect("===RTC===> St-Entry Obj=the_sm,State=QHsmTst_s211") +expect("@timestamp ===>Tran Obj=the_sm,Sig=G_SIG,State=QHsmTst_s11->QHsmTst_s211") expect("@timestamp Trg-Done QS_RX_EVENT") dispatch("H_SIG") -expect("@timestamp Disp===> Obj=the_hsm,Sig=H_SIG,State=QHsmTst_s211") -expect("===RTC===> St-Exit Obj=the_hsm,State=QHsmTst_s211") -expect("===RTC===> St-Exit Obj=the_hsm,State=QHsmTst_s21") -expect("===RTC===> St-Exit Obj=the_hsm,State=QHsmTst_s2") -expect("===RTC===> St-Init Obj=the_hsm,State=QHsmTst_s->QHsmTst_s11") -expect("===RTC===> St-Entry Obj=the_hsm,State=QHsmTst_s1") -expect("===RTC===> St-Entry Obj=the_hsm,State=QHsmTst_s11") -expect("@timestamp ===>Tran Obj=the_hsm,Sig=H_SIG,State=QHsmTst_s211->QHsmTst_s11") +expect("@timestamp Disp===> Obj=the_sm,Sig=H_SIG,State=QHsmTst_s211") +expect("===RTC===> St-Exit Obj=the_sm,State=QHsmTst_s211") +expect("===RTC===> St-Exit Obj=the_sm,State=QHsmTst_s21") +expect("===RTC===> St-Exit Obj=the_sm,State=QHsmTst_s2") +expect("===RTC===> St-Init Obj=the_sm,State=QHsmTst_s->QHsmTst_s11") +expect("===RTC===> St-Entry Obj=the_sm,State=QHsmTst_s1") +expect("===RTC===> St-Entry Obj=the_sm,State=QHsmTst_s11") +expect("@timestamp ===>Tran Obj=the_sm,Sig=H_SIG,State=QHsmTst_s211->QHsmTst_s11") expect("@timestamp Trg-Done QS_RX_EVENT") dispatch("H_SIG") -expect("@timestamp Disp===> Obj=the_hsm,Sig=H_SIG,State=QHsmTst_s11") -expect("===RTC===> St-Exit Obj=the_hsm,State=QHsmTst_s11") -expect("===RTC===> St-Exit Obj=the_hsm,State=QHsmTst_s1") -expect("===RTC===> St-Init Obj=the_hsm,State=QHsmTst_s->QHsmTst_s11") -expect("===RTC===> St-Entry Obj=the_hsm,State=QHsmTst_s1") -expect("===RTC===> St-Entry Obj=the_hsm,State=QHsmTst_s11") -expect("@timestamp ===>Tran Obj=the_hsm,Sig=H_SIG,State=QHsmTst_s11->QHsmTst_s11") +expect("@timestamp Disp===> Obj=the_sm,Sig=H_SIG,State=QHsmTst_s11") +expect("===RTC===> St-Exit Obj=the_sm,State=QHsmTst_s11") +expect("===RTC===> St-Exit Obj=the_sm,State=QHsmTst_s1") +expect("===RTC===> St-Init Obj=the_sm,State=QHsmTst_s->QHsmTst_s11") +expect("===RTC===> St-Entry Obj=the_sm,State=QHsmTst_s1") +expect("===RTC===> St-Entry Obj=the_sm,State=QHsmTst_s11") +expect("@timestamp ===>Tran Obj=the_sm,Sig=H_SIG,State=QHsmTst_s11->QHsmTst_s11") expect("@timestamp Trg-Done QS_RX_EVENT") dispatch("C_SIG") -expect("@timestamp Disp===> Obj=the_hsm,Sig=C_SIG,State=QHsmTst_s11") -expect("===RTC===> St-Exit Obj=the_hsm,State=QHsmTst_s11") -expect("===RTC===> St-Exit Obj=the_hsm,State=QHsmTst_s1") -expect("===RTC===> St-Entry Obj=the_hsm,State=QHsmTst_s2") -expect("===RTC===> St-Init Obj=the_hsm,State=QHsmTst_s2->QHsmTst_s211") -expect("===RTC===> St-Entry Obj=the_hsm,State=QHsmTst_s21") -expect("===RTC===> St-Entry Obj=the_hsm,State=QHsmTst_s211") -expect("@timestamp ===>Tran Obj=the_hsm,Sig=C_SIG,State=QHsmTst_s1->QHsmTst_s211") +expect("@timestamp Disp===> Obj=the_sm,Sig=C_SIG,State=QHsmTst_s11") +expect("===RTC===> St-Exit Obj=the_sm,State=QHsmTst_s11") +expect("===RTC===> St-Exit Obj=the_sm,State=QHsmTst_s1") +expect("===RTC===> St-Entry Obj=the_sm,State=QHsmTst_s2") +expect("===RTC===> St-Init Obj=the_sm,State=QHsmTst_s2->QHsmTst_s211") +expect("===RTC===> St-Entry Obj=the_sm,State=QHsmTst_s21") +expect("===RTC===> St-Entry Obj=the_sm,State=QHsmTst_s211") +expect("@timestamp ===>Tran Obj=the_sm,Sig=C_SIG,State=QHsmTst_s1->QHsmTst_s211") expect("@timestamp Trg-Done QS_RX_EVENT") dispatch("G_SIG") -expect("@timestamp Disp===> Obj=the_hsm,Sig=G_SIG,State=QHsmTst_s211") -expect("===RTC===> St-Exit Obj=the_hsm,State=QHsmTst_s211") -expect("===RTC===> St-Exit Obj=the_hsm,State=QHsmTst_s21") -expect("===RTC===> St-Exit Obj=the_hsm,State=QHsmTst_s2") -expect("===RTC===> St-Entry Obj=the_hsm,State=QHsmTst_s1") -expect("===RTC===> St-Init Obj=the_hsm,State=QHsmTst_s1->QHsmTst_s11") -expect("===RTC===> St-Entry Obj=the_hsm,State=QHsmTst_s11") -expect("@timestamp ===>Tran Obj=the_hsm,Sig=G_SIG,State=QHsmTst_s21->QHsmTst_s11") +expect("@timestamp Disp===> Obj=the_sm,Sig=G_SIG,State=QHsmTst_s211") +expect("===RTC===> St-Exit Obj=the_sm,State=QHsmTst_s211") +expect("===RTC===> St-Exit Obj=the_sm,State=QHsmTst_s21") +expect("===RTC===> St-Exit Obj=the_sm,State=QHsmTst_s2") +expect("===RTC===> St-Entry Obj=the_sm,State=QHsmTst_s1") +expect("===RTC===> St-Init Obj=the_sm,State=QHsmTst_s1->QHsmTst_s11") +expect("===RTC===> St-Entry Obj=the_sm,State=QHsmTst_s11") +expect("@timestamp ===>Tran Obj=the_sm,Sig=G_SIG,State=QHsmTst_s21->QHsmTst_s11") expect("@timestamp Trg-Done QS_RX_EVENT") dispatch("C_SIG") -expect("@timestamp Disp===> Obj=the_hsm,Sig=C_SIG,State=QHsmTst_s11") -expect("===RTC===> St-Exit Obj=the_hsm,State=QHsmTst_s11") -expect("===RTC===> St-Exit Obj=the_hsm,State=QHsmTst_s1") -expect("===RTC===> St-Entry Obj=the_hsm,State=QHsmTst_s2") -expect("===RTC===> St-Init Obj=the_hsm,State=QHsmTst_s2->QHsmTst_s211") -expect("===RTC===> St-Entry Obj=the_hsm,State=QHsmTst_s21") -expect("===RTC===> St-Entry Obj=the_hsm,State=QHsmTst_s211") -expect("@timestamp ===>Tran Obj=the_hsm,Sig=C_SIG,State=QHsmTst_s1->QHsmTst_s211") +expect("@timestamp Disp===> Obj=the_sm,Sig=C_SIG,State=QHsmTst_s11") +expect("===RTC===> St-Exit Obj=the_sm,State=QHsmTst_s11") +expect("===RTC===> St-Exit Obj=the_sm,State=QHsmTst_s1") +expect("===RTC===> St-Entry Obj=the_sm,State=QHsmTst_s2") +expect("===RTC===> St-Init Obj=the_sm,State=QHsmTst_s2->QHsmTst_s211") +expect("===RTC===> St-Entry Obj=the_sm,State=QHsmTst_s21") +expect("===RTC===> St-Entry Obj=the_sm,State=QHsmTst_s211") +expect("@timestamp ===>Tran Obj=the_sm,Sig=C_SIG,State=QHsmTst_s1->QHsmTst_s211") expect("@timestamp Trg-Done QS_RX_EVENT") dispatch("C_SIG") -expect("@timestamp Disp===> Obj=the_hsm,Sig=C_SIG,State=QHsmTst_s211") -expect("===RTC===> St-Exit Obj=the_hsm,State=QHsmTst_s211") -expect("===RTC===> St-Exit Obj=the_hsm,State=QHsmTst_s21") -expect("===RTC===> St-Exit Obj=the_hsm,State=QHsmTst_s2") -expect("===RTC===> St-Entry Obj=the_hsm,State=QHsmTst_s1") -expect("===RTC===> St-Init Obj=the_hsm,State=QHsmTst_s1->QHsmTst_s11") -expect("===RTC===> St-Entry Obj=the_hsm,State=QHsmTst_s11") -expect("@timestamp ===>Tran Obj=the_hsm,Sig=C_SIG,State=QHsmTst_s2->QHsmTst_s11") +expect("@timestamp Disp===> Obj=the_sm,Sig=C_SIG,State=QHsmTst_s211") +expect("===RTC===> St-Exit Obj=the_sm,State=QHsmTst_s211") +expect("===RTC===> St-Exit Obj=the_sm,State=QHsmTst_s21") +expect("===RTC===> St-Exit Obj=the_sm,State=QHsmTst_s2") +expect("===RTC===> St-Entry Obj=the_sm,State=QHsmTst_s1") +expect("===RTC===> St-Init Obj=the_sm,State=QHsmTst_s1->QHsmTst_s11") +expect("===RTC===> St-Entry Obj=the_sm,State=QHsmTst_s11") +expect("@timestamp ===>Tran Obj=the_sm,Sig=C_SIG,State=QHsmTst_s2->QHsmTst_s11") expect("@timestamp Trg-Done QS_RX_EVENT") diff --git a/examples/qutest/qhsmtst/test/test_qhsm.c b/examples/qutest/qhsmtst/test/test_qhsm.c index c048aded..290bb011 100644 --- a/examples/qutest/qhsmtst/test/test_qhsm.c +++ b/examples/qutest/qhsmtst/test/test_qhsm.c @@ -1,36 +1,36 @@ -/***************************************************************************** -* Purpose: Fixture for QUTEST -* Last Updated for Version: 7.2.0 -* Date of the Last Update: 2022-12-22 -* -* Q u a n t u m L e a P s -* ------------------------ -* Modern Embedded Software -* -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* -* -*****************************************************************************/ +//============================================================================ +// Purpose: Fixture for QUTEST +// Last Updated for Version: 7.3.0 +// Date of the Last Update: 2023-08-25 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// This program is open source software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Alternatively, this program may be distributed and modified under the +// terms of Quantum Leaps commercial licenses, which expressly supersede +// the GNU General Public License and are specifically designed for +// licensees interested in retaining the proprietary status of their code. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Contact information: +// +// +//============================================================================ #include "qpc.h" #include "qhsmtst.h" @@ -40,51 +40,52 @@ enum { BSP_DISPLAY = QS_USER, }; -/*--------------------------------------------------------------------------*/ +//---------------------------------------------------------------------------- int main(int argc, char *argv[]) { - static QF_MPOOL_EL(QEvt) smlPoolSto[10]; /* small pool */ + QF_init(); // initialize the framework - QF_init(); /* initialize the framework */ + // initialize the QS software tracing + if (QS_INIT((argc > 1) ? argv[1] : (void *)0) == 0U) { + Q_ERROR(); + } - /* initialize the QS software tracing */ - Q_ALLEGE(QS_INIT(argc > 1 ? argv[1] : (void *)0)); - - /* initialize event pools... */ + // initialize event pools... + static QF_MPOOL_EL(QEvt) smlPoolSto[10]; // small pool QF_poolInit(smlPoolSto, sizeof(smlPoolSto), sizeof(smlPoolSto[0])); - /* dictionaries... */ - QS_OBJ_DICTIONARY(the_hsm); + // dictionaries... + QS_OBJ_DICTIONARY(the_sm); QS_USR_DICTIONARY(BSP_DISPLAY); - QHsmTst_ctor(); /* instantiate the QHsmTst object */ + QHsmTst_ctor(); // instantiate the QHsmTst object return QF_run(); } -/*--------------------------------------------------------------------------*/ +//---------------------------------------------------------------------------- void BSP_display(char const *msg) { - QS_BEGIN_ID(BSP_DISPLAY, 0U) /* app-specific record */ + QS_BEGIN_ID(BSP_DISPLAY, 0U) // app-specific record QS_STR(msg); QS_END() } - -/*..........................................................................*/ -void BSP_exit(void) { +//............................................................................ +void BSP_terminate(int16_t const result) { + Q_UNUSED_PAR(result); } -/*--------------------------------------------------------------------------*/ +//---------------------------------------------------------------------------- void QS_onTestSetup(void) { } -/*..........................................................................*/ +//............................................................................ void QS_onTestTeardown(void) { } -/*..........................................................................*/ +//............................................................................ void QS_onCommand(uint8_t cmdId, uint32_t param1, uint32_t param2, uint32_t param3) { - (void)param1; - (void)param2; - (void)param3; + Q_UNUSED_PAR(param1); + Q_UNUSED_PAR(param2); + Q_UNUSED_PAR(param3); //PRINTF_S(" Command id=%d param=%d\n", (int)cmdId, (int)param); switch (cmdId) { @@ -96,22 +97,22 @@ void QS_onCommand(uint8_t cmdId, } } -/*..........................................................................*/ -/* host callback function to "massage" the event, if necessary */ +//............................................................................ +// host callback function to "massage" the event, if necessary void QS_onTestEvt(QEvt *e) { (void)e; -#ifdef Q_HOST /* is this test compiled for a desktop Host computer? */ -#else /* this test is compiled for an embedded Target system */ +#ifdef Q_HOST // is this test compiled for a desktop Host computer? +#else // this test is compiled for an embedded Target system #endif } -/*..........................................................................*/ -/*! callback function to output the posted QP events (not used here) */ +//............................................................................ +//! callback function to output the posted QP events (not used here) void QS_onTestPost(void const *sender, QActive *recipient, QEvt const *e, bool status) { - (void)sender; - (void)recipient; - (void)e; - (void)status; + Q_UNUSED_PAR(sender); + Q_UNUSED_PAR(recipient); + Q_UNUSED_PAR(e); + Q_UNUSED_PAR(status); } diff --git a/examples/qutest/qmsmtst/src/qmsmtst.c b/examples/qutest/qmsmtst/src/qmsmtst.c index f87f1fc3..e9daa9b5 100644 --- a/examples/qutest/qmsmtst/src/qmsmtst.c +++ b/examples/qutest/qmsmtst/src/qmsmtst.c @@ -1,55 +1,58 @@ -/*$file${src::qmsmtst.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* -* Model: qmsmtst.qm -* File: ${src::qmsmtst.c} -* -* This code has been generated by QM 5.2.4 . -* DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. -* -* SPDX-License-Identifier: GPL-3.0-or-later -* -* This generated code is open source software: you can redistribute it under -* the terms of the GNU General Public License as published by the Free -* Software Foundation. -* -* This code is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -* more details. -* -* NOTE: -* Alternatively, this generated code may be distributed under the terms -* of Quantum Leaps commercial licenses, which expressly supersede the GNU -* General Public License and are specifically designed for licensees -* interested in retaining the proprietary status of their code. -* -* Contact information: -* -* -*/ -/*$endhead${src::qmsmtst.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -#include "qpc.h" -#include "qmsmtst.h" +//$file${.::qmsmtst.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// +// Model: qmsmtst.qm +// File: ${.::qmsmtst.c} +// +// This code has been generated by QM 5.3.0 . +// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. +// +// SPDX-License-Identifier: GPL-3.0-or-later +// +// This generated code is open source software: you can redistribute it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation. +// +// This code is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// NOTE: +// Alternatively, this generated code may be distributed under the terms +// of Quantum Leaps commercial licenses, which expressly supersede the GNU +// General Public License and are specifically designed for licensees +// interested in retaining the proprietary status of their code. +// +// Contact information: +// +// +// +//$endhead${.::qmsmtst.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +#include "qpc.h" // QP/C framework +#include "qmsmtst.h" // this application -/*$declare${SMs::QMsmTst} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//$declare${SMs::QMsmTst} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/*${SMs::QMsmTst} ..........................................................*/ -typedef struct { -/* protected: */ +//${SMs::QMsmTst} ............................................................ +typedef struct QMsmTst { +// protected: QMsm super; -/* private: */ +// private: uint8_t foo; -} QMsmTst; -/* protected: */ +// public: +} QMsmTst; +extern QMsmTst QMsmTst_inst; + +// protected: static QState QMsmTst_initial(QMsmTst * const me, void const * const par); static QState QMsmTst_s (QMsmTst * const me, QEvt const * const e); static QState QMsmTst_s_e(QMsmTst * const me); static QState QMsmTst_s_x(QMsmTst * const me); static QState QMsmTst_s_i(QMsmTst * const me); static QMState const QMsmTst_s_s = { - QM_STATE_NULL, /* superstate (top) */ + QM_STATE_NULL, // superstate (top) Q_STATE_CAST(&QMsmTst_s), Q_ACTION_CAST(&QMsmTst_s_e), Q_ACTION_CAST(&QMsmTst_s_x), @@ -60,7 +63,7 @@ static QState QMsmTst_s1_e(QMsmTst * const me); static QState QMsmTst_s1_x(QMsmTst * const me); static QState QMsmTst_s1_i(QMsmTst * const me); static QMState const QMsmTst_s1_s = { - &QMsmTst_s_s, /* superstate */ + &QMsmTst_s_s, // superstate Q_STATE_CAST(&QMsmTst_s1), Q_ACTION_CAST(&QMsmTst_s1_e), Q_ACTION_CAST(&QMsmTst_s1_x), @@ -70,18 +73,18 @@ static QState QMsmTst_s11 (QMsmTst * const me, QEvt const * const e); static QState QMsmTst_s11_e(QMsmTst * const me); static QState QMsmTst_s11_x(QMsmTst * const me); static QMState const QMsmTst_s11_s = { - &QMsmTst_s1_s, /* superstate */ + &QMsmTst_s1_s, // superstate Q_STATE_CAST(&QMsmTst_s11), Q_ACTION_CAST(&QMsmTst_s11_e), Q_ACTION_CAST(&QMsmTst_s11_x), - Q_ACTION_NULL /* no initial tran. */ + Q_ACTION_NULL // no initial tran. }; static QState QMsmTst_s2 (QMsmTst * const me, QEvt const * const e); static QState QMsmTst_s2_e(QMsmTst * const me); static QState QMsmTst_s2_x(QMsmTst * const me); static QState QMsmTst_s2_i(QMsmTst * const me); static QMState const QMsmTst_s2_s = { - &QMsmTst_s_s, /* superstate */ + &QMsmTst_s_s, // superstate Q_STATE_CAST(&QMsmTst_s2), Q_ACTION_CAST(&QMsmTst_s2_e), Q_ACTION_CAST(&QMsmTst_s2_x), @@ -92,7 +95,7 @@ static QState QMsmTst_s21_e(QMsmTst * const me); static QState QMsmTst_s21_x(QMsmTst * const me); static QState QMsmTst_s21_i(QMsmTst * const me); static QMState const QMsmTst_s21_s = { - &QMsmTst_s2_s, /* superstate */ + &QMsmTst_s2_s, // superstate Q_STATE_CAST(&QMsmTst_s21), Q_ACTION_CAST(&QMsmTst_s21_e), Q_ACTION_CAST(&QMsmTst_s21_x), @@ -102,69 +105,68 @@ static QState QMsmTst_s211 (QMsmTst * const me, QEvt const * const e); static QState QMsmTst_s211_e(QMsmTst * const me); static QState QMsmTst_s211_x(QMsmTst * const me); static QMState const QMsmTst_s211_s = { - &QMsmTst_s21_s, /* superstate */ + &QMsmTst_s21_s, // superstate Q_STATE_CAST(&QMsmTst_s211), Q_ACTION_CAST(&QMsmTst_s211_e), Q_ACTION_CAST(&QMsmTst_s211_x), - Q_ACTION_NULL /* no initial tran. */ + Q_ACTION_NULL // no initial tran. }; -/*$enddecl${SMs::QMsmTst} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ - -static QMsmTst l_msmtst; /* the only instance of the QMsmTst class */ - -/* global-scope definitions ---------------------------------------*/ -QMsm * const the_msm = (QMsm *)&l_msmtst; /* the opaque pointer */ - -/*$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* Check for the minimum required QP version */ -#if (QP_VERSION < 700U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) -#error qpc version 7.0.0 or higher required +//$enddecl${SMs::QMsmTst} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +//$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// Check for the minimum required QP version +#if (QP_VERSION < 730U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) +#error qpc version 7.3.0 or higher required #endif -/*$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -/*$define${SMs::QMsmTst_ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//$define${Shared::the_sm} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/*${SMs::QMsmTst_ctor} .....................................................*/ +//${Shared::the_sm} .......................................................... +QAsm * const the_sm = &QMsmTst_inst.super.super; +//$enddef${Shared::the_sm} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +//$define${Shared::QMsmTst_ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${Shared::QMsmTst_ctor} .................................................... void QMsmTst_ctor(void) { - QMsmTst *me = &l_msmtst; + QMsmTst *me = &QMsmTst_inst; QMsm_ctor(&me->super, Q_STATE_CAST(&QMsmTst_initial)); } -/*$enddef${SMs::QMsmTst_ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$enddef${Shared::QMsmTst_ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +//$define${SMs::QMsmTst} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/*$define${SMs::QMsmTst} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//${SMs::QMsmTst} ............................................................ +QMsmTst QMsmTst_inst; -/*${SMs::QMsmTst} ..........................................................*/ - -/*${SMs::QMsmTst::SM} ......................................................*/ +//${SMs::QMsmTst::SM} ........................................................ static QState QMsmTst_initial(QMsmTst * const me, void const * const par) { static struct { QMState const *target; QActionHandler act[4]; - } const tatbl_ = { /* tran-action table */ - &QMsmTst_s2_s, /* target state */ + } const tatbl_ = { // tran-action table + &QMsmTst_s2_s, // target state { - Q_ACTION_CAST(&QMsmTst_s_e), /* entry */ - Q_ACTION_CAST(&QMsmTst_s2_e), /* entry */ - Q_ACTION_CAST(&QMsmTst_s2_i), /* initial tran. */ - Q_ACTION_NULL /* zero terminator */ + Q_ACTION_CAST(&QMsmTst_s_e), // entry + Q_ACTION_CAST(&QMsmTst_s2_e), // entry + Q_ACTION_CAST(&QMsmTst_s2_i), // initial tran. + Q_ACTION_NULL // zero terminator } }; - /*${SMs::QMsmTst::SM::initial} */ - (void)par; /* unused parameter */ + //${SMs::QMsmTst::SM::initial} + Q_UNUSED_PAR(par); me->foo = 0U; BSP_display("top-INIT;"); - QS_SIG_DICTIONARY(A_SIG, me); - QS_SIG_DICTIONARY(B_SIG, me); - QS_SIG_DICTIONARY(C_SIG, me); - QS_SIG_DICTIONARY(D_SIG, me); - QS_SIG_DICTIONARY(E_SIG, me); - QS_SIG_DICTIONARY(F_SIG, me); - QS_SIG_DICTIONARY(G_SIG, me); - QS_SIG_DICTIONARY(H_SIG, me); - QS_SIG_DICTIONARY(I_SIG, me); - QS_SIG_DICTIONARY(TERMINATE_SIG, me); - QS_SIG_DICTIONARY(IGNORE_SIG, me); + QS_SIG_DICTIONARY(A_SIG, (void *)0); + QS_SIG_DICTIONARY(B_SIG, (void *)0); + QS_SIG_DICTIONARY(C_SIG, (void *)0); + QS_SIG_DICTIONARY(D_SIG, (void *)0); + QS_SIG_DICTIONARY(E_SIG, (void *)0); + QS_SIG_DICTIONARY(F_SIG, (void *)0); + QS_SIG_DICTIONARY(G_SIG, (void *)0); + QS_SIG_DICTIONARY(H_SIG, (void *)0); + QS_SIG_DICTIONARY(I_SIG, (void *)0); + QS_SIG_DICTIONARY(IGNORE_SIG, (void *)0); + QS_SIG_DICTIONARY(TERMINATE_SIG, (void *)0); QS_FUN_DICTIONARY(&QMsmTst_s); QS_FUN_DICTIONARY(&QMsmTst_s1); @@ -176,43 +178,43 @@ static QState QMsmTst_initial(QMsmTst * const me, void const * const par) { return QM_TRAN_INIT(&tatbl_); } -/*${SMs::QMsmTst::SM::s} ...................................................*/ -/*${SMs::QMsmTst::SM::s} */ +//${SMs::QMsmTst::SM::s} ..................................................... +//${SMs::QMsmTst::SM::s} static QState QMsmTst_s_e(QMsmTst * const me) { BSP_display("s-ENTRY;"); - (void)me; /* unused parameter */ + Q_UNUSED_PAR(me); return QM_ENTRY(&QMsmTst_s_s); } -/*${SMs::QMsmTst::SM::s} */ +//${SMs::QMsmTst::SM::s} static QState QMsmTst_s_x(QMsmTst * const me) { BSP_display("s-EXIT;"); - (void)me; /* unused parameter */ + (void)me; // unused parameter return QM_EXIT(&QMsmTst_s_s); } -/*${SMs::QMsmTst::SM::s::initial} */ +//${SMs::QMsmTst::SM::s::initial} static QState QMsmTst_s_i(QMsmTst * const me) { static struct { QMState const *target; QActionHandler act[3]; - } const tatbl_ = { /* tran-action table */ - &QMsmTst_s11_s, /* target state */ + } const tatbl_ = { // tran-action table + &QMsmTst_s11_s, // target state { - Q_ACTION_CAST(&QMsmTst_s1_e), /* entry */ - Q_ACTION_CAST(&QMsmTst_s11_e), /* entry */ - Q_ACTION_NULL /* zero terminator */ + Q_ACTION_CAST(&QMsmTst_s1_e), // entry + Q_ACTION_CAST(&QMsmTst_s11_e), // entry + Q_ACTION_NULL // zero terminator } }; - /*${SMs::QMsmTst::SM::s::initial} */ + //${SMs::QMsmTst::SM::s::initial} BSP_display("s-INIT;"); return QM_TRAN_INIT(&tatbl_); } -/*${SMs::QMsmTst::SM::s} */ +//${SMs::QMsmTst::SM::s} static QState QMsmTst_s(QMsmTst * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${SMs::QMsmTst::SM::s::I} */ + //${SMs::QMsmTst::SM::s::I} case I_SIG: { - /*${SMs::QMsmTst::SM::s::I::[me->foo]} */ + //${SMs::QMsmTst::SM::s::I::[me->foo]} if (me->foo) { me->foo = 0U; BSP_display("s-I;"); @@ -223,26 +225,26 @@ static QState QMsmTst_s(QMsmTst * const me, QEvt const * const e) { } break; } - /*${SMs::QMsmTst::SM::s::E} */ + //${SMs::QMsmTst::SM::s::E} case E_SIG: { static struct { QMState const *target; QActionHandler act[3]; - } const tatbl_ = { /* tran-action table */ - &QMsmTst_s11_s, /* target state */ + } const tatbl_ = { // tran-action table + &QMsmTst_s11_s, // target state { - Q_ACTION_CAST(&QMsmTst_s1_e), /* entry */ - Q_ACTION_CAST(&QMsmTst_s11_e), /* entry */ - Q_ACTION_NULL /* zero terminator */ + Q_ACTION_CAST(&QMsmTst_s1_e), // entry + Q_ACTION_CAST(&QMsmTst_s11_e), // entry + Q_ACTION_NULL // zero terminator } }; BSP_display("s-E;"); status_ = QM_TRAN(&tatbl_); break; } - /*${SMs::QMsmTst::SM::s::TERMINATE} */ + //${SMs::QMsmTst::SM::s::TERMINATE} case TERMINATE_SIG: { - BSP_exit(); + BSP_terminate(0); status_ = QM_HANDLED(); break; } @@ -251,62 +253,62 @@ static QState QMsmTst_s(QMsmTst * const me, QEvt const * const e) { break; } } - (void)me; /* unused parameter */ + Q_UNUSED_PAR(me); return status_; } -/*${SMs::QMsmTst::SM::s::s1} ...............................................*/ -/*${SMs::QMsmTst::SM::s::s1} */ +//${SMs::QMsmTst::SM::s::s1} ................................................. +//${SMs::QMsmTst::SM::s::s1} static QState QMsmTst_s1_e(QMsmTst * const me) { BSP_display("s1-ENTRY;"); - (void)me; /* unused parameter */ + Q_UNUSED_PAR(me); return QM_ENTRY(&QMsmTst_s1_s); } -/*${SMs::QMsmTst::SM::s::s1} */ +//${SMs::QMsmTst::SM::s::s1} static QState QMsmTst_s1_x(QMsmTst * const me) { BSP_display("s1-EXIT;"); - (void)me; /* unused parameter */ + (void)me; // unused parameter return QM_EXIT(&QMsmTst_s1_s); } -/*${SMs::QMsmTst::SM::s::s1::initial} */ +//${SMs::QMsmTst::SM::s::s1::initial} static QState QMsmTst_s1_i(QMsmTst * const me) { static struct { QMState const *target; QActionHandler act[2]; - } const tatbl_ = { /* tran-action table */ - &QMsmTst_s11_s, /* target state */ + } const tatbl_ = { // tran-action table + &QMsmTst_s11_s, // target state { - Q_ACTION_CAST(&QMsmTst_s11_e), /* entry */ - Q_ACTION_NULL /* zero terminator */ + Q_ACTION_CAST(&QMsmTst_s11_e), // entry + Q_ACTION_NULL // zero terminator } }; - /*${SMs::QMsmTst::SM::s::s1::initial} */ + //${SMs::QMsmTst::SM::s::s1::initial} BSP_display("s1-INIT;"); return QM_TRAN_INIT(&tatbl_); } -/*${SMs::QMsmTst::SM::s::s1} */ +//${SMs::QMsmTst::SM::s::s1} static QState QMsmTst_s1(QMsmTst * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${SMs::QMsmTst::SM::s::s1::I} */ + //${SMs::QMsmTst::SM::s::s1::I} case I_SIG: { BSP_display("s1-I;"); status_ = QM_HANDLED(); break; } - /*${SMs::QMsmTst::SM::s::s1::D} */ + //${SMs::QMsmTst::SM::s::s1::D} case D_SIG: { - /*${SMs::QMsmTst::SM::s::s1::D::[!me->foo]} */ + //${SMs::QMsmTst::SM::s::s1::D::[!me->foo]} if (!me->foo) { static struct { QMState const *target; QActionHandler act[3]; - } const tatbl_ = { /* tran-action table */ - &QMsmTst_s_s, /* target state */ + } const tatbl_ = { // tran-action table + &QMsmTst_s_s, // target state { - Q_ACTION_CAST(&QMsmTst_s1_x), /* exit */ - Q_ACTION_CAST(&QMsmTst_s_i), /* initial tran. */ - Q_ACTION_NULL /* zero terminator */ + Q_ACTION_CAST(&QMsmTst_s1_x), // exit + Q_ACTION_CAST(&QMsmTst_s_i), // initial tran. + Q_ACTION_NULL // zero terminator } }; me->foo = 1U; @@ -318,71 +320,71 @@ static QState QMsmTst_s1(QMsmTst * const me, QEvt const * const e) { } break; } - /*${SMs::QMsmTst::SM::s::s1::A} */ + //${SMs::QMsmTst::SM::s::s1::A} case A_SIG: { static struct { QMState const *target; QActionHandler act[4]; - } const tatbl_ = { /* tran-action table */ - &QMsmTst_s1_s, /* target state */ + } const tatbl_ = { // tran-action table + &QMsmTst_s1_s, // target state { - Q_ACTION_CAST(&QMsmTst_s1_x), /* exit */ - Q_ACTION_CAST(&QMsmTst_s1_e), /* entry */ - Q_ACTION_CAST(&QMsmTst_s1_i), /* initial tran. */ - Q_ACTION_NULL /* zero terminator */ + Q_ACTION_CAST(&QMsmTst_s1_x), // exit + Q_ACTION_CAST(&QMsmTst_s1_e), // entry + Q_ACTION_CAST(&QMsmTst_s1_i), // initial tran. + Q_ACTION_NULL // zero terminator } }; BSP_display("s1-A;"); status_ = QM_TRAN(&tatbl_); break; } - /*${SMs::QMsmTst::SM::s::s1::B} */ + //${SMs::QMsmTst::SM::s::s1::B} case B_SIG: { static struct { QMState const *target; QActionHandler act[2]; - } const tatbl_ = { /* tran-action table */ - &QMsmTst_s11_s, /* target state */ + } const tatbl_ = { // tran-action table + &QMsmTst_s11_s, // target state { - Q_ACTION_CAST(&QMsmTst_s11_e), /* entry */ - Q_ACTION_NULL /* zero terminator */ + Q_ACTION_CAST(&QMsmTst_s11_e), // entry + Q_ACTION_NULL // zero terminator } }; BSP_display("s1-B;"); status_ = QM_TRAN(&tatbl_); break; } - /*${SMs::QMsmTst::SM::s::s1::F} */ + //${SMs::QMsmTst::SM::s::s1::F} case F_SIG: { static struct { QMState const *target; QActionHandler act[5]; - } const tatbl_ = { /* tran-action table */ - &QMsmTst_s211_s, /* target state */ + } const tatbl_ = { // tran-action table + &QMsmTst_s211_s, // target state { - Q_ACTION_CAST(&QMsmTst_s1_x), /* exit */ - Q_ACTION_CAST(&QMsmTst_s2_e), /* entry */ - Q_ACTION_CAST(&QMsmTst_s21_e), /* entry */ - Q_ACTION_CAST(&QMsmTst_s211_e), /* entry */ - Q_ACTION_NULL /* zero terminator */ + Q_ACTION_CAST(&QMsmTst_s1_x), // exit + Q_ACTION_CAST(&QMsmTst_s2_e), // entry + Q_ACTION_CAST(&QMsmTst_s21_e), // entry + Q_ACTION_CAST(&QMsmTst_s211_e), // entry + Q_ACTION_NULL // zero terminator } }; BSP_display("s1-F;"); status_ = QM_TRAN(&tatbl_); break; } - /*${SMs::QMsmTst::SM::s::s1::C} */ + //${SMs::QMsmTst::SM::s::s1::C} case C_SIG: { static struct { QMState const *target; QActionHandler act[4]; - } const tatbl_ = { /* tran-action table */ - &QMsmTst_s2_s, /* target state */ + } const tatbl_ = { // tran-action table + &QMsmTst_s2_s, // target state { - Q_ACTION_CAST(&QMsmTst_s1_x), /* exit */ - Q_ACTION_CAST(&QMsmTst_s2_e), /* entry */ - Q_ACTION_CAST(&QMsmTst_s2_i), /* initial tran. */ - Q_ACTION_NULL /* zero terminator */ + Q_ACTION_CAST(&QMsmTst_s1_x), // exit + Q_ACTION_CAST(&QMsmTst_s2_e), // entry + Q_ACTION_CAST(&QMsmTst_s2_i), // initial tran. + Q_ACTION_NULL // zero terminator } }; BSP_display("s1-C;"); @@ -397,54 +399,54 @@ static QState QMsmTst_s1(QMsmTst * const me, QEvt const * const e) { return status_; } -/*${SMs::QMsmTst::SM::s::s1::s11} ..........................................*/ -/*${SMs::QMsmTst::SM::s::s1::s11} */ +//${SMs::QMsmTst::SM::s::s1::s11} ............................................ +//${SMs::QMsmTst::SM::s::s1::s11} static QState QMsmTst_s11_e(QMsmTst * const me) { BSP_display("s11-ENTRY;"); - (void)me; /* unused parameter */ + Q_UNUSED_PAR(me); return QM_ENTRY(&QMsmTst_s11_s); } -/*${SMs::QMsmTst::SM::s::s1::s11} */ +//${SMs::QMsmTst::SM::s::s1::s11} static QState QMsmTst_s11_x(QMsmTst * const me) { BSP_display("s11-EXIT;"); - (void)me; /* unused parameter */ + (void)me; // unused parameter return QM_EXIT(&QMsmTst_s11_s); } -/*${SMs::QMsmTst::SM::s::s1::s11} */ +//${SMs::QMsmTst::SM::s::s1::s11} static QState QMsmTst_s11(QMsmTst * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${SMs::QMsmTst::SM::s::s1::s11::H} */ + //${SMs::QMsmTst::SM::s::s1::s11::H} case H_SIG: { static struct { QMState const *target; QActionHandler act[4]; - } const tatbl_ = { /* tran-action table */ - &QMsmTst_s_s, /* target state */ + } const tatbl_ = { // tran-action table + &QMsmTst_s_s, // target state { - Q_ACTION_CAST(&QMsmTst_s11_x), /* exit */ - Q_ACTION_CAST(&QMsmTst_s1_x), /* exit */ - Q_ACTION_CAST(&QMsmTst_s_i), /* initial tran. */ - Q_ACTION_NULL /* zero terminator */ + Q_ACTION_CAST(&QMsmTst_s11_x), // exit + Q_ACTION_CAST(&QMsmTst_s1_x), // exit + Q_ACTION_CAST(&QMsmTst_s_i), // initial tran. + Q_ACTION_NULL // zero terminator } }; BSP_display("s11-H;"); status_ = QM_TRAN(&tatbl_); break; } - /*${SMs::QMsmTst::SM::s::s1::s11::D} */ + //${SMs::QMsmTst::SM::s::s1::s11::D} case D_SIG: { - /*${SMs::QMsmTst::SM::s::s1::s11::D::[me->foo]} */ + //${SMs::QMsmTst::SM::s::s1::s11::D::[me->foo]} if (me->foo) { static struct { QMState const *target; QActionHandler act[3]; - } const tatbl_ = { /* tran-action table */ - &QMsmTst_s1_s, /* target state */ + } const tatbl_ = { // tran-action table + &QMsmTst_s1_s, // target state { - Q_ACTION_CAST(&QMsmTst_s11_x), /* exit */ - Q_ACTION_CAST(&QMsmTst_s1_i), /* initial tran. */ - Q_ACTION_NULL /* zero terminator */ + Q_ACTION_CAST(&QMsmTst_s11_x), // exit + Q_ACTION_CAST(&QMsmTst_s1_i), // initial tran. + Q_ACTION_NULL // zero terminator } }; me->foo = 0U; @@ -456,20 +458,20 @@ static QState QMsmTst_s11(QMsmTst * const me, QEvt const * const e) { } break; } - /*${SMs::QMsmTst::SM::s::s1::s11::G} */ + //${SMs::QMsmTst::SM::s::s1::s11::G} case G_SIG: { static struct { QMState const *target; QActionHandler act[6]; - } const tatbl_ = { /* tran-action table */ - &QMsmTst_s211_s, /* target state */ + } const tatbl_ = { // tran-action table + &QMsmTst_s211_s, // target state { - Q_ACTION_CAST(&QMsmTst_s11_x), /* exit */ - Q_ACTION_CAST(&QMsmTst_s1_x), /* exit */ - Q_ACTION_CAST(&QMsmTst_s2_e), /* entry */ - Q_ACTION_CAST(&QMsmTst_s21_e), /* entry */ - Q_ACTION_CAST(&QMsmTst_s211_e), /* entry */ - Q_ACTION_NULL /* zero terminator */ + Q_ACTION_CAST(&QMsmTst_s11_x), // exit + Q_ACTION_CAST(&QMsmTst_s1_x), // exit + Q_ACTION_CAST(&QMsmTst_s2_e), // entry + Q_ACTION_CAST(&QMsmTst_s21_e), // entry + Q_ACTION_CAST(&QMsmTst_s211_e), // entry + Q_ACTION_NULL // zero terminator } }; BSP_display("s11-G;"); @@ -484,43 +486,43 @@ static QState QMsmTst_s11(QMsmTst * const me, QEvt const * const e) { return status_; } -/*${SMs::QMsmTst::SM::s::s2} ...............................................*/ -/*${SMs::QMsmTst::SM::s::s2} */ +//${SMs::QMsmTst::SM::s::s2} ................................................. +//${SMs::QMsmTst::SM::s::s2} static QState QMsmTst_s2_e(QMsmTst * const me) { BSP_display("s2-ENTRY;"); - (void)me; /* unused parameter */ + Q_UNUSED_PAR(me); return QM_ENTRY(&QMsmTst_s2_s); } -/*${SMs::QMsmTst::SM::s::s2} */ +//${SMs::QMsmTst::SM::s::s2} static QState QMsmTst_s2_x(QMsmTst * const me) { BSP_display("s2-EXIT;"); - (void)me; /* unused parameter */ + (void)me; // unused parameter return QM_EXIT(&QMsmTst_s2_s); } -/*${SMs::QMsmTst::SM::s::s2::initial} */ +//${SMs::QMsmTst::SM::s::s2::initial} static QState QMsmTst_s2_i(QMsmTst * const me) { static struct { QMState const *target; QActionHandler act[3]; - } const tatbl_ = { /* tran-action table */ - &QMsmTst_s211_s, /* target state */ + } const tatbl_ = { // tran-action table + &QMsmTst_s211_s, // target state { - Q_ACTION_CAST(&QMsmTst_s21_e), /* entry */ - Q_ACTION_CAST(&QMsmTst_s211_e), /* entry */ - Q_ACTION_NULL /* zero terminator */ + Q_ACTION_CAST(&QMsmTst_s21_e), // entry + Q_ACTION_CAST(&QMsmTst_s211_e), // entry + Q_ACTION_NULL // zero terminator } }; - /*${SMs::QMsmTst::SM::s::s2::initial} */ + //${SMs::QMsmTst::SM::s::s2::initial} BSP_display("s2-INIT;"); return QM_TRAN_INIT(&tatbl_); } -/*${SMs::QMsmTst::SM::s::s2} */ +//${SMs::QMsmTst::SM::s::s2} static QState QMsmTst_s2(QMsmTst * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${SMs::QMsmTst::SM::s::s2::I} */ + //${SMs::QMsmTst::SM::s::s2::I} case I_SIG: { - /*${SMs::QMsmTst::SM::s::s2::I::[!me->foo]} */ + //${SMs::QMsmTst::SM::s::s2::I::[!me->foo]} if (!me->foo) { me->foo = 1U; BSP_display("s2-I;"); @@ -531,36 +533,36 @@ static QState QMsmTst_s2(QMsmTst * const me, QEvt const * const e) { } break; } - /*${SMs::QMsmTst::SM::s::s2::F} */ + //${SMs::QMsmTst::SM::s::s2::F} case F_SIG: { static struct { QMState const *target; QActionHandler act[4]; - } const tatbl_ = { /* tran-action table */ - &QMsmTst_s11_s, /* target state */ + } const tatbl_ = { // tran-action table + &QMsmTst_s11_s, // target state { - Q_ACTION_CAST(&QMsmTst_s2_x), /* exit */ - Q_ACTION_CAST(&QMsmTst_s1_e), /* entry */ - Q_ACTION_CAST(&QMsmTst_s11_e), /* entry */ - Q_ACTION_NULL /* zero terminator */ + Q_ACTION_CAST(&QMsmTst_s2_x), // exit + Q_ACTION_CAST(&QMsmTst_s1_e), // entry + Q_ACTION_CAST(&QMsmTst_s11_e), // entry + Q_ACTION_NULL // zero terminator } }; BSP_display("s2-F;"); status_ = QM_TRAN(&tatbl_); break; } - /*${SMs::QMsmTst::SM::s::s2::C} */ + //${SMs::QMsmTst::SM::s::s2::C} case C_SIG: { static struct { QMState const *target; QActionHandler act[4]; - } const tatbl_ = { /* tran-action table */ - &QMsmTst_s1_s, /* target state */ + } const tatbl_ = { // tran-action table + &QMsmTst_s1_s, // target state { - Q_ACTION_CAST(&QMsmTst_s2_x), /* exit */ - Q_ACTION_CAST(&QMsmTst_s1_e), /* entry */ - Q_ACTION_CAST(&QMsmTst_s1_i), /* initial tran. */ - Q_ACTION_NULL /* zero terminator */ + Q_ACTION_CAST(&QMsmTst_s2_x), // exit + Q_ACTION_CAST(&QMsmTst_s1_e), // entry + Q_ACTION_CAST(&QMsmTst_s1_i), // initial tran. + Q_ACTION_NULL // zero terminator } }; BSP_display("s2-C;"); @@ -575,86 +577,86 @@ static QState QMsmTst_s2(QMsmTst * const me, QEvt const * const e) { return status_; } -/*${SMs::QMsmTst::SM::s::s2::s21} ..........................................*/ -/*${SMs::QMsmTst::SM::s::s2::s21} */ +//${SMs::QMsmTst::SM::s::s2::s21} ............................................ +//${SMs::QMsmTst::SM::s::s2::s21} static QState QMsmTst_s21_e(QMsmTst * const me) { BSP_display("s21-ENTRY;"); - (void)me; /* unused parameter */ + Q_UNUSED_PAR(me); return QM_ENTRY(&QMsmTst_s21_s); } -/*${SMs::QMsmTst::SM::s::s2::s21} */ +//${SMs::QMsmTst::SM::s::s2::s21} static QState QMsmTst_s21_x(QMsmTst * const me) { BSP_display("s21-EXIT;"); - (void)me; /* unused parameter */ + (void)me; // unused parameter return QM_EXIT(&QMsmTst_s21_s); } -/*${SMs::QMsmTst::SM::s::s2::s21::initial} */ +//${SMs::QMsmTst::SM::s::s2::s21::initial} static QState QMsmTst_s21_i(QMsmTst * const me) { static struct { QMState const *target; QActionHandler act[2]; - } const tatbl_ = { /* tran-action table */ - &QMsmTst_s211_s, /* target state */ + } const tatbl_ = { // tran-action table + &QMsmTst_s211_s, // target state { - Q_ACTION_CAST(&QMsmTst_s211_e), /* entry */ - Q_ACTION_NULL /* zero terminator */ + Q_ACTION_CAST(&QMsmTst_s211_e), // entry + Q_ACTION_NULL // zero terminator } }; - /*${SMs::QMsmTst::SM::s::s2::s21::initial} */ + //${SMs::QMsmTst::SM::s::s2::s21::initial} BSP_display("s21-INIT;"); return QM_TRAN_INIT(&tatbl_); } -/*${SMs::QMsmTst::SM::s::s2::s21} */ +//${SMs::QMsmTst::SM::s::s2::s21} static QState QMsmTst_s21(QMsmTst * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${SMs::QMsmTst::SM::s::s2::s21::G} */ + //${SMs::QMsmTst::SM::s::s2::s21::G} case G_SIG: { static struct { QMState const *target; QActionHandler act[5]; - } const tatbl_ = { /* tran-action table */ - &QMsmTst_s1_s, /* target state */ + } const tatbl_ = { // tran-action table + &QMsmTst_s1_s, // target state { - Q_ACTION_CAST(&QMsmTst_s21_x), /* exit */ - Q_ACTION_CAST(&QMsmTst_s2_x), /* exit */ - Q_ACTION_CAST(&QMsmTst_s1_e), /* entry */ - Q_ACTION_CAST(&QMsmTst_s1_i), /* initial tran. */ - Q_ACTION_NULL /* zero terminator */ + Q_ACTION_CAST(&QMsmTst_s21_x), // exit + Q_ACTION_CAST(&QMsmTst_s2_x), // exit + Q_ACTION_CAST(&QMsmTst_s1_e), // entry + Q_ACTION_CAST(&QMsmTst_s1_i), // initial tran. + Q_ACTION_NULL // zero terminator } }; BSP_display("s21-G;"); status_ = QM_TRAN(&tatbl_); break; } - /*${SMs::QMsmTst::SM::s::s2::s21::A} */ + //${SMs::QMsmTst::SM::s::s2::s21::A} case A_SIG: { static struct { QMState const *target; QActionHandler act[4]; - } const tatbl_ = { /* tran-action table */ - &QMsmTst_s21_s, /* target state */ + } const tatbl_ = { // tran-action table + &QMsmTst_s21_s, // target state { - Q_ACTION_CAST(&QMsmTst_s21_x), /* exit */ - Q_ACTION_CAST(&QMsmTst_s21_e), /* entry */ - Q_ACTION_CAST(&QMsmTst_s21_i), /* initial tran. */ - Q_ACTION_NULL /* zero terminator */ + Q_ACTION_CAST(&QMsmTst_s21_x), // exit + Q_ACTION_CAST(&QMsmTst_s21_e), // entry + Q_ACTION_CAST(&QMsmTst_s21_i), // initial tran. + Q_ACTION_NULL // zero terminator } }; BSP_display("s21-A;"); status_ = QM_TRAN(&tatbl_); break; } - /*${SMs::QMsmTst::SM::s::s2::s21::B} */ + //${SMs::QMsmTst::SM::s::s2::s21::B} case B_SIG: { static struct { QMState const *target; QActionHandler act[2]; - } const tatbl_ = { /* tran-action table */ - &QMsmTst_s211_s, /* target state */ + } const tatbl_ = { // tran-action table + &QMsmTst_s211_s, // target state { - Q_ACTION_CAST(&QMsmTst_s211_e), /* entry */ - Q_ACTION_NULL /* zero terminator */ + Q_ACTION_CAST(&QMsmTst_s211_e), // entry + Q_ACTION_NULL // zero terminator } }; BSP_display("s21-B;"); @@ -669,53 +671,53 @@ static QState QMsmTst_s21(QMsmTst * const me, QEvt const * const e) { return status_; } -/*${SMs::QMsmTst::SM::s::s2::s21::s211} ....................................*/ -/*${SMs::QMsmTst::SM::s::s2::s21::s211} */ +//${SMs::QMsmTst::SM::s::s2::s21::s211} ...................................... +//${SMs::QMsmTst::SM::s::s2::s21::s211} static QState QMsmTst_s211_e(QMsmTst * const me) { BSP_display("s211-ENTRY;"); - (void)me; /* unused parameter */ + Q_UNUSED_PAR(me); return QM_ENTRY(&QMsmTst_s211_s); } -/*${SMs::QMsmTst::SM::s::s2::s21::s211} */ +//${SMs::QMsmTst::SM::s::s2::s21::s211} static QState QMsmTst_s211_x(QMsmTst * const me) { BSP_display("s211-EXIT;"); - (void)me; /* unused parameter */ + (void)me; // unused parameter return QM_EXIT(&QMsmTst_s211_s); } -/*${SMs::QMsmTst::SM::s::s2::s21::s211} */ +//${SMs::QMsmTst::SM::s::s2::s21::s211} static QState QMsmTst_s211(QMsmTst * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${SMs::QMsmTst::SM::s::s2::s21::s211::H} */ + //${SMs::QMsmTst::SM::s::s2::s21::s211::H} case H_SIG: { static struct { QMState const *target; QActionHandler act[5]; - } const tatbl_ = { /* tran-action table */ - &QMsmTst_s_s, /* target state */ + } const tatbl_ = { // tran-action table + &QMsmTst_s_s, // target state { - Q_ACTION_CAST(&QMsmTst_s211_x), /* exit */ - Q_ACTION_CAST(&QMsmTst_s21_x), /* exit */ - Q_ACTION_CAST(&QMsmTst_s2_x), /* exit */ - Q_ACTION_CAST(&QMsmTst_s_i), /* initial tran. */ - Q_ACTION_NULL /* zero terminator */ + Q_ACTION_CAST(&QMsmTst_s211_x), // exit + Q_ACTION_CAST(&QMsmTst_s21_x), // exit + Q_ACTION_CAST(&QMsmTst_s2_x), // exit + Q_ACTION_CAST(&QMsmTst_s_i), // initial tran. + Q_ACTION_NULL // zero terminator } }; BSP_display("s211-H;"); status_ = QM_TRAN(&tatbl_); break; } - /*${SMs::QMsmTst::SM::s::s2::s21::s211::D} */ + //${SMs::QMsmTst::SM::s::s2::s21::s211::D} case D_SIG: { static struct { QMState const *target; QActionHandler act[3]; - } const tatbl_ = { /* tran-action table */ - &QMsmTst_s21_s, /* target state */ + } const tatbl_ = { // tran-action table + &QMsmTst_s21_s, // target state { - Q_ACTION_CAST(&QMsmTst_s211_x), /* exit */ - Q_ACTION_CAST(&QMsmTst_s21_i), /* initial tran. */ - Q_ACTION_NULL /* zero terminator */ + Q_ACTION_CAST(&QMsmTst_s211_x), // exit + Q_ACTION_CAST(&QMsmTst_s21_i), // initial tran. + Q_ACTION_NULL // zero terminator } }; BSP_display("s211-D;"); @@ -729,4 +731,4 @@ static QState QMsmTst_s211(QMsmTst * const me, QEvt const * const e) { } return status_; } -/*$enddef${SMs::QMsmTst} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$enddef${SMs::QMsmTst} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/examples/qutest/qmsmtst/src/qmsmtst.h b/examples/qutest/qmsmtst/src/qmsmtst.h index 3ee81607..74f6b27b 100644 --- a/examples/qutest/qmsmtst/src/qmsmtst.h +++ b/examples/qutest/qmsmtst/src/qmsmtst.h @@ -1,36 +1,39 @@ -/*$file${src::qmsmtst.h} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* -* Model: qmsmtst.qm -* File: ${src::qmsmtst.h} -* -* This code has been generated by QM 5.2.4 . -* DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. -* -* SPDX-License-Identifier: GPL-3.0-or-later -* -* This generated code is open source software: you can redistribute it under -* the terms of the GNU General Public License as published by the Free -* Software Foundation. -* -* This code is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -* more details. -* -* NOTE: -* Alternatively, this generated code may be distributed under the terms -* of Quantum Leaps commercial licenses, which expressly supersede the GNU -* General Public License and are specifically designed for licensees -* interested in retaining the proprietary status of their code. -* -* Contact information: -* -* -*/ -/*$endhead${src::qmsmtst.h} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -#ifndef QMSMTST_H -#define QMSMTST_H +//$file${.::qmsmtst.h} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// +// Model: qmsmtst.qm +// File: ${.::qmsmtst.h} +// +// This code has been generated by QM 5.3.0 . +// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. +// +// SPDX-License-Identifier: GPL-3.0-or-later +// +// This generated code is open source software: you can redistribute it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation. +// +// This code is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// NOTE: +// Alternatively, this generated code may be distributed under the terms +// of Quantum Leaps commercial licenses, which expressly supersede the GNU +// General Public License and are specifically designed for licensees +// interested in retaining the proprietary status of their code. +// +// Contact information: +// +// +// +//$endhead${.::qmsmtst.h} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +#ifndef QMSMTST_H_ +#define QMSMTST_H_ +//$declare${Shared} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${Shared::QMsmTstSignals} .................................................. enum QMsmTstSignals { A_SIG = Q_USER_SIG, B_SIG, @@ -46,17 +49,17 @@ enum QMsmTstSignals { MAX_SIG }; -extern QMsm * const the_msm; /* opaque pointer to the test MSM */ +//${Shared::the_sm} .......................................................... +extern QAsm * const the_sm; -/*$declare${SMs::QMsmTst_ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${SMs::QMsmTst_ctor} .....................................................*/ +//${Shared::QMsmTst_ctor} .................................................... void QMsmTst_ctor(void); -/*$enddecl${SMs::QMsmTst_ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/* BSP functions to dispaly a message and exit */ -void BSP_display(char const *msg); -void BSP_exit(void); +//${Shared::BSP_display} ..................................................... +void BSP_display(char const * msg); -#endif /* QMSMTST_H */ +//${Shared::BSP_terminate} ................................................... +void BSP_terminate(int16_t const result); +//$enddecl${Shared} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +#endif // QMSMTST_H_ diff --git a/examples/qutest/qmsmtst/qmsmtst.qm b/examples/qutest/qmsmtst/src/qmsmtst.qm similarity index 81% rename from examples/qutest/qmsmtst/qmsmtst.qm rename to examples/qutest/qmsmtst/src/qmsmtst.qm index 995415b0..8a4eb465 100644 --- a/examples/qutest/qmsmtst/qmsmtst.qm +++ b/examples/qutest/qmsmtst/src/qmsmtst.qm @@ -1,8 +1,48 @@ - - QMsmTst is a QMsm state machine test based on the contrived state machine from Chapter 2 of the PSiCC2 book for testing all possible transition topologies with up to 4-levels of state nesting. + + QHsmTst is a contrived state machine from Chapter 2 of the PSiCC2 book for testing all possible transition topologies with up to 4-levels of state nesting. + + + + + { + A_SIG = Q_USER_SIG, + B_SIG, + C_SIG, + D_SIG, + E_SIG, + F_SIG, + G_SIG, + H_SIG, + I_SIG, + TERMINATE_SIG, + IGNORE_SIG, + MAX_SIG +}; + + + + opaque pointer to the test SM + = &QMsmTst_inst.super.super; + + + + QMsmTst *me = &QMsmTst_inst; +QMsm_ctor(&me->super, Q_STATE_CAST(&QMsmTst_initial)); + + + + + + + + + + + + @@ -10,25 +50,27 @@ Test active object + + - (void)par; /* unused parameter */ + Q_UNUSED_PAR(par); me->foo = 0U; BSP_display("top-INIT;"); -QS_SIG_DICTIONARY(A_SIG, me); -QS_SIG_DICTIONARY(B_SIG, me); -QS_SIG_DICTIONARY(C_SIG, me); -QS_SIG_DICTIONARY(D_SIG, me); -QS_SIG_DICTIONARY(E_SIG, me); -QS_SIG_DICTIONARY(F_SIG, me); -QS_SIG_DICTIONARY(G_SIG, me); -QS_SIG_DICTIONARY(H_SIG, me); -QS_SIG_DICTIONARY(I_SIG, me); -QS_SIG_DICTIONARY(TERMINATE_SIG, me); -QS_SIG_DICTIONARY(IGNORE_SIG, me); +QS_SIG_DICTIONARY(A_SIG, (void *)0); +QS_SIG_DICTIONARY(B_SIG, (void *)0); +QS_SIG_DICTIONARY(C_SIG, (void *)0); +QS_SIG_DICTIONARY(D_SIG, (void *)0); +QS_SIG_DICTIONARY(E_SIG, (void *)0); +QS_SIG_DICTIONARY(F_SIG, (void *)0); +QS_SIG_DICTIONARY(G_SIG, (void *)0); +QS_SIG_DICTIONARY(H_SIG, (void *)0); +QS_SIG_DICTIONARY(I_SIG, (void *)0); +QS_SIG_DICTIONARY(IGNORE_SIG, (void *)0); +QS_SIG_DICTIONARY(TERMINATE_SIG, (void *)0); @@ -68,7 +110,7 @@ BSP_display("s-I;"); - BSP_exit(); + BSP_terminate(0); @@ -290,60 +332,27 @@ BSP_display("s2-I;"); - - - QMsmTst *me = &l_msmtst; -QMsm_ctor(&me->super, Q_STATE_CAST(&QMsmTst_initial)); - - - - + + + - #ifndef QMSMTST_H -#define QMSMTST_H + #ifndef QMSMTST_H_ +#define QMSMTST_H_ -enum QMsmTstSignals { - A_SIG = Q_USER_SIG, - B_SIG, - C_SIG, - D_SIG, - E_SIG, - F_SIG, - G_SIG, - H_SIG, - I_SIG, - TERMINATE_SIG, - IGNORE_SIG, - MAX_SIG -}; +$declare ${Shared} -extern QMsm * const the_msm; /* opaque pointer to the test MSM */ - -$declare${SMs::QMsmTst_ctor} - -/* BSP functions to dispaly a message and exit */ -void BSP_display(char const *msg); -void BSP_exit(void); - -#endif /* QMSMTST_H */ - +#endif // QMSMTST_H_ - + - #include "qpc.h" -#include "qmsmtst.h" + #include "qpc.h" // QP/C framework +#include "qmsmtst.h" // this application -$declare${SMs::QMsmTst} - -static QMsmTst l_msmtst; /* the only instance of the QMsmTst class */ - -/* global-scope definitions ---------------------------------------*/ -QMsm * const the_msm = (QMsm *)&l_msmtst; /* the opaque pointer */ - -$define${SMs::QMsmTst_ctor} - -$define${SMs::QMsmTst} +$declare ${SMs::QMsmTst} +$define ${Shared::the_sm} +$define ${Shared::QMsmTst_ctor} +$define ${SMs::QMsmTst} diff --git a/examples/qutest/qmsmtst/test/Makefile b/examples/qutest/qmsmtst/test/Makefile index b6e54645..55bdca19 100644 --- a/examples/qutest/qmsmtst/test/Makefile +++ b/examples/qutest/qmsmtst/test/Makefile @@ -217,7 +217,7 @@ all : $(TARGET_EXE) run endif $(TARGET_EXE) : $(C_OBJS_EXT) $(CPP_OBJS_EXT) - $(CC) $(CFLAGS) $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o + $(CC) $(CFLAGS) $(QPC)/src/qs/qstamp.c -o $(BIN_DIR)/qstamp.o $(LINK) $(LINKFLAGS) $(LIB_DIRS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) run : $(TARGET_EXE) diff --git a/examples/qutest/qmsmtst/test/make_efm32 b/examples/qutest/qmsmtst/test/make_efm32 index 126b0911..b80545c1 100644 --- a/examples/qutest/qmsmtst/test/make_efm32 +++ b/examples/qutest/qmsmtst/test/make_efm32 @@ -252,7 +252,7 @@ $(TARGET_BIN) : $(TARGET_ELF) $(FLASH) $@ $(TARGET_ELF) : $(ASM_OBJS_EXT) $(C_OBJS_EXT) $(CPP_OBJS_EXT) - $(CC) $(CFLAGS) $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o + $(CC) $(CFLAGS) $(QPC)/src/qs/qstamp.c -o $(BIN_DIR)/qstamp.o $(LINK) $(LINKFLAGS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) flash : diff --git a/examples/qutest/qmsmtst/test/make_nucleo-l053r8 b/examples/qutest/qmsmtst/test/make_nucleo-l053r8 index 425788b9..f5fa8cd8 100644 --- a/examples/qutest/qmsmtst/test/make_nucleo-l053r8 +++ b/examples/qutest/qmsmtst/test/make_nucleo-l053r8 @@ -252,7 +252,7 @@ $(TARGET_BIN) : $(TARGET_ELF) $(SLEEP) 2 $(TARGET_ELF) : $(ASM_OBJS_EXT) $(C_OBJS_EXT) $(CPP_OBJS_EXT) - $(CC) $(CFLAGS) $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o + $(CC) $(CFLAGS) $(QPC)/src/qs/qstamp.c -o $(BIN_DIR)/qstamp.o $(LINK) $(LINKFLAGS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) flash : diff --git a/examples/qutest/qmsmtst/test/make_tm4c123 b/examples/qutest/qmsmtst/test/make_tm4c123 index cf6fc639..5bfc84ca 100644 --- a/examples/qutest/qmsmtst/test/make_tm4c123 +++ b/examples/qutest/qmsmtst/test/make_tm4c123 @@ -253,7 +253,7 @@ $(TARGET_BIN) : $(TARGET_ELF) @pause $(TARGET_ELF) : $(ASM_OBJS_EXT) $(C_OBJS_EXT) $(CPP_OBJS_EXT) - $(CC) $(CFLAGS) $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o + $(CC) $(CFLAGS) $(QPC)/src/qs/qstamp.c -o $(BIN_DIR)/qstamp.o $(LINK) $(LINKFLAGS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) flash : diff --git a/examples/qutest/qmsmtst/test/test_qmsm-funct.py b/examples/qutest/qmsmtst/test/test_qmsm-funct.py index cbfe6fe4..0d682436 100644 --- a/examples/qutest/qmsmtst/test/test_qmsm-funct.py +++ b/examples/qutest/qmsmtst/test/test_qmsm-funct.py @@ -5,7 +5,7 @@ def on_reset(): expect_run() glb_filter(GRP_UA) - current_obj(OBJ_SM, "the_msm") + current_obj(OBJ_SM, "the_sm") # tests... test("QMsmTst_init") diff --git a/examples/qutest/qmsmtst/test/test_qmsm-struct.py b/examples/qutest/qmsmtst/test/test_qmsm-struct.py index 6bb897c8..9adea0dd 100644 --- a/examples/qutest/qmsmtst/test/test_qmsm-struct.py +++ b/examples/qutest/qmsmtst/test/test_qmsm-struct.py @@ -5,209 +5,209 @@ def on_reset(): expect_run() glb_filter(GRP_SM) - current_obj(OBJ_SM, "the_msm") + current_obj(OBJ_SM, "the_sm") # tests... test("QMsmTst init") init() -expect("===RTC===> St-Init Obj=the_msm,State=NULL->QMsmTst_s2") -expect("===RTC===> St-Entry Obj=the_msm,State=QMsmTst_s") -expect("===RTC===> St-Entry Obj=the_msm,State=QMsmTst_s2") -expect("===RTC===> St-Init Obj=the_msm,State=QMsmTst_s2->QMsmTst_s211") -expect("===RTC===> St-Entry Obj=the_msm,State=QMsmTst_s21") -expect("===RTC===> St-Entry Obj=the_msm,State=QMsmTst_s211") -expect("@timestamp Init===> Obj=the_msm,State=QMsmTst_s211") +expect("===RTC===> St-Init Obj=the_sm,State=NULL->QMsmTst_s2") +expect("===RTC===> St-Entry Obj=the_sm,State=QMsmTst_s") +expect("===RTC===> St-Entry Obj=the_sm,State=QMsmTst_s2") +expect("===RTC===> St-Init Obj=the_sm,State=QMsmTst_s2->QMsmTst_s211") +expect("===RTC===> St-Entry Obj=the_sm,State=QMsmTst_s21") +expect("===RTC===> St-Entry Obj=the_sm,State=QMsmTst_s211") +expect("@timestamp Init===> Obj=the_sm,State=QMsmTst_s211") expect("@timestamp Trg-Done QS_RX_EVENT") test("QMsmTst dispatch", NORESET) dispatch("A_SIG") -expect("@timestamp Disp===> Obj=the_msm,Sig=A_SIG,State=QMsmTst_s211") -expect("===RTC===> St-Exit Obj=the_msm,State=QMsmTst_s211") -expect("===RTC===> St-Exit Obj=the_msm,State=QMsmTst_s21") -expect("===RTC===> St-Entry Obj=the_msm,State=QMsmTst_s21") -expect("===RTC===> St-Init Obj=the_msm,State=QMsmTst_s21->QMsmTst_s211") -expect("===RTC===> St-Entry Obj=the_msm,State=QMsmTst_s211") -expect("@timestamp ===>Tran Obj=the_msm,Sig=A_SIG,State=QMsmTst_s21->QMsmTst_s211") +expect("@timestamp Disp===> Obj=the_sm,Sig=A_SIG,State=QMsmTst_s211") +expect("===RTC===> St-Exit Obj=the_sm,State=QMsmTst_s211") +expect("===RTC===> St-Exit Obj=the_sm,State=QMsmTst_s21") +expect("===RTC===> St-Entry Obj=the_sm,State=QMsmTst_s21") +expect("===RTC===> St-Init Obj=the_sm,State=QMsmTst_s21->QMsmTst_s211") +expect("===RTC===> St-Entry Obj=the_sm,State=QMsmTst_s211") +expect("@timestamp ===>Tran Obj=the_sm,Sig=A_SIG,State=QMsmTst_s21->QMsmTst_s211") expect("@timestamp Trg-Done QS_RX_EVENT") dispatch("B_SIG") -expect("@timestamp Disp===> Obj=the_msm,Sig=B_SIG,State=QMsmTst_s211") -expect("===RTC===> St-Exit Obj=the_msm,State=QMsmTst_s211") -expect("===RTC===> St-Entry Obj=the_msm,State=QMsmTst_s211") -expect("@timestamp ===>Tran Obj=the_msm,Sig=B_SIG,State=QMsmTst_s21->QMsmTst_s211") +expect("@timestamp Disp===> Obj=the_sm,Sig=B_SIG,State=QMsmTst_s211") +expect("===RTC===> St-Exit Obj=the_sm,State=QMsmTst_s211") +expect("===RTC===> St-Entry Obj=the_sm,State=QMsmTst_s211") +expect("@timestamp ===>Tran Obj=the_sm,Sig=B_SIG,State=QMsmTst_s21->QMsmTst_s211") expect("@timestamp Trg-Done QS_RX_EVENT") dispatch("D_SIG") -expect("@timestamp Disp===> Obj=the_msm,Sig=D_SIG,State=QMsmTst_s211") -expect("===RTC===> St-Exit Obj=the_msm,State=QMsmTst_s211") -expect("===RTC===> St-Init Obj=the_msm,State=QMsmTst_s21->QMsmTst_s211") -expect("===RTC===> St-Entry Obj=the_msm,State=QMsmTst_s211") -expect("@timestamp ===>Tran Obj=the_msm,Sig=D_SIG,State=QMsmTst_s211->QMsmTst_s211") +expect("@timestamp Disp===> Obj=the_sm,Sig=D_SIG,State=QMsmTst_s211") +expect("===RTC===> St-Exit Obj=the_sm,State=QMsmTst_s211") +expect("===RTC===> St-Init Obj=the_sm,State=QMsmTst_s21->QMsmTst_s211") +expect("===RTC===> St-Entry Obj=the_sm,State=QMsmTst_s211") +expect("@timestamp ===>Tran Obj=the_sm,Sig=D_SIG,State=QMsmTst_s211->QMsmTst_s211") expect("@timestamp Trg-Done QS_RX_EVENT") dispatch("E_SIG") -expect("@timestamp Disp===> Obj=the_msm,Sig=E_SIG,State=QMsmTst_s211") -expect("===RTC===> St-Exit Obj=the_msm,State=QMsmTst_s211") -expect("===RTC===> St-Exit Obj=the_msm,State=QMsmTst_s21") -expect("===RTC===> St-Exit Obj=the_msm,State=QMsmTst_s2") -expect("===RTC===> St-Entry Obj=the_msm,State=QMsmTst_s1") -expect("===RTC===> St-Entry Obj=the_msm,State=QMsmTst_s11") -expect("@timestamp ===>Tran Obj=the_msm,Sig=E_SIG,State=QMsmTst_s->QMsmTst_s11") +expect("@timestamp Disp===> Obj=the_sm,Sig=E_SIG,State=QMsmTst_s211") +expect("===RTC===> St-Exit Obj=the_sm,State=QMsmTst_s211") +expect("===RTC===> St-Exit Obj=the_sm,State=QMsmTst_s21") +expect("===RTC===> St-Exit Obj=the_sm,State=QMsmTst_s2") +expect("===RTC===> St-Entry Obj=the_sm,State=QMsmTst_s1") +expect("===RTC===> St-Entry Obj=the_sm,State=QMsmTst_s11") +expect("@timestamp ===>Tran Obj=the_sm,Sig=E_SIG,State=QMsmTst_s->QMsmTst_s11") expect("@timestamp Trg-Done QS_RX_EVENT") dispatch("I_SIG") -expect("@timestamp Disp===> Obj=the_msm,Sig=I_SIG,State=QMsmTst_s11") -expect("@timestamp =>Intern Obj=the_msm,Sig=I_SIG,State=QMsmTst_s1") +expect("@timestamp Disp===> Obj=the_sm,Sig=I_SIG,State=QMsmTst_s11") +expect("@timestamp =>Intern Obj=the_sm,Sig=I_SIG,State=QMsmTst_s1") expect("@timestamp Trg-Done QS_RX_EVENT") dispatch("F_SIG") -expect("@timestamp Disp===> Obj=the_msm,Sig=F_SIG,State=QMsmTst_s11") -expect("===RTC===> St-Exit Obj=the_msm,State=QMsmTst_s11") -expect("===RTC===> St-Exit Obj=the_msm,State=QMsmTst_s1") -expect("===RTC===> St-Entry Obj=the_msm,State=QMsmTst_s2") -expect("===RTC===> St-Entry Obj=the_msm,State=QMsmTst_s21") -expect("===RTC===> St-Entry Obj=the_msm,State=QMsmTst_s211") -expect("@timestamp ===>Tran Obj=the_msm,Sig=F_SIG,State=QMsmTst_s1->QMsmTst_s211") +expect("@timestamp Disp===> Obj=the_sm,Sig=F_SIG,State=QMsmTst_s11") +expect("===RTC===> St-Exit Obj=the_sm,State=QMsmTst_s11") +expect("===RTC===> St-Exit Obj=the_sm,State=QMsmTst_s1") +expect("===RTC===> St-Entry Obj=the_sm,State=QMsmTst_s2") +expect("===RTC===> St-Entry Obj=the_sm,State=QMsmTst_s21") +expect("===RTC===> St-Entry Obj=the_sm,State=QMsmTst_s211") +expect("@timestamp ===>Tran Obj=the_sm,Sig=F_SIG,State=QMsmTst_s1->QMsmTst_s211") expect("@timestamp Trg-Done QS_RX_EVENT") dispatch("I_SIG") -expect("@timestamp Disp===> Obj=the_msm,Sig=I_SIG,State=QMsmTst_s211") -expect("@timestamp =>Intern Obj=the_msm,Sig=I_SIG,State=QMsmTst_s2") +expect("@timestamp Disp===> Obj=the_sm,Sig=I_SIG,State=QMsmTst_s211") +expect("@timestamp =>Intern Obj=the_sm,Sig=I_SIG,State=QMsmTst_s2") expect("@timestamp Trg-Done QS_RX_EVENT") dispatch("I_SIG") -expect("@timestamp Disp===> Obj=the_msm,Sig=I_SIG,State=QMsmTst_s211") -expect("===RTC===> St-Unhnd Obj=the_msm,Sig=I_SIG,State=QMsmTst_s2") -expect("@timestamp =>Intern Obj=the_msm,Sig=I_SIG,State=QMsmTst_s") +expect("@timestamp Disp===> Obj=the_sm,Sig=I_SIG,State=QMsmTst_s211") +expect("===RTC===> St-Unhnd Obj=the_sm,Sig=I_SIG,State=QMsmTst_s2") +expect("@timestamp =>Intern Obj=the_sm,Sig=I_SIG,State=QMsmTst_s") expect("@timestamp Trg-Done QS_RX_EVENT") dispatch("F_SIG") -expect("@timestamp Disp===> Obj=the_msm,Sig=F_SIG,State=QMsmTst_s211") -expect("===RTC===> St-Exit Obj=the_msm,State=QMsmTst_s211") -expect("===RTC===> St-Exit Obj=the_msm,State=QMsmTst_s21") -expect("===RTC===> St-Exit Obj=the_msm,State=QMsmTst_s2") -expect("===RTC===> St-Entry Obj=the_msm,State=QMsmTst_s1") -expect("===RTC===> St-Entry Obj=the_msm,State=QMsmTst_s11") -expect("@timestamp ===>Tran Obj=the_msm,Sig=F_SIG,State=QMsmTst_s2->QMsmTst_s11") +expect("@timestamp Disp===> Obj=the_sm,Sig=F_SIG,State=QMsmTst_s211") +expect("===RTC===> St-Exit Obj=the_sm,State=QMsmTst_s211") +expect("===RTC===> St-Exit Obj=the_sm,State=QMsmTst_s21") +expect("===RTC===> St-Exit Obj=the_sm,State=QMsmTst_s2") +expect("===RTC===> St-Entry Obj=the_sm,State=QMsmTst_s1") +expect("===RTC===> St-Entry Obj=the_sm,State=QMsmTst_s11") +expect("@timestamp ===>Tran Obj=the_sm,Sig=F_SIG,State=QMsmTst_s2->QMsmTst_s11") expect("@timestamp Trg-Done QS_RX_EVENT") dispatch("A_SIG") -expect("@timestamp Disp===> Obj=the_msm,Sig=A_SIG,State=QMsmTst_s11") -expect("===RTC===> St-Exit Obj=the_msm,State=QMsmTst_s11") -expect("===RTC===> St-Exit Obj=the_msm,State=QMsmTst_s1") -expect("===RTC===> St-Entry Obj=the_msm,State=QMsmTst_s1") -expect("===RTC===> St-Init Obj=the_msm,State=QMsmTst_s1->QMsmTst_s11") -expect("===RTC===> St-Entry Obj=the_msm,State=QMsmTst_s11") -expect("@timestamp ===>Tran Obj=the_msm,Sig=A_SIG,State=QMsmTst_s1->QMsmTst_s11") +expect("@timestamp Disp===> Obj=the_sm,Sig=A_SIG,State=QMsmTst_s11") +expect("===RTC===> St-Exit Obj=the_sm,State=QMsmTst_s11") +expect("===RTC===> St-Exit Obj=the_sm,State=QMsmTst_s1") +expect("===RTC===> St-Entry Obj=the_sm,State=QMsmTst_s1") +expect("===RTC===> St-Init Obj=the_sm,State=QMsmTst_s1->QMsmTst_s11") +expect("===RTC===> St-Entry Obj=the_sm,State=QMsmTst_s11") +expect("@timestamp ===>Tran Obj=the_sm,Sig=A_SIG,State=QMsmTst_s1->QMsmTst_s11") expect("@timestamp Trg-Done QS_RX_EVENT") dispatch("B_SIG") -expect("@timestamp Disp===> Obj=the_msm,Sig=B_SIG,State=QMsmTst_s11") -expect("===RTC===> St-Exit Obj=the_msm,State=QMsmTst_s11") -expect("===RTC===> St-Entry Obj=the_msm,State=QMsmTst_s11") -expect("@timestamp ===>Tran Obj=the_msm,Sig=B_SIG,State=QMsmTst_s1->QMsmTst_s11") +expect("@timestamp Disp===> Obj=the_sm,Sig=B_SIG,State=QMsmTst_s11") +expect("===RTC===> St-Exit Obj=the_sm,State=QMsmTst_s11") +expect("===RTC===> St-Entry Obj=the_sm,State=QMsmTst_s11") +expect("@timestamp ===>Tran Obj=the_sm,Sig=B_SIG,State=QMsmTst_s1->QMsmTst_s11") expect("@timestamp Trg-Done QS_RX_EVENT") dispatch("D_SIG") -expect("@timestamp Disp===> Obj=the_msm,Sig=D_SIG,State=QMsmTst_s11") -expect("===RTC===> St-Unhnd Obj=the_msm,Sig=D_SIG,State=QMsmTst_s11") -expect("===RTC===> St-Exit Obj=the_msm,State=QMsmTst_s11") -expect("===RTC===> St-Exit Obj=the_msm,State=QMsmTst_s1") -expect("===RTC===> St-Init Obj=the_msm,State=QMsmTst_s->QMsmTst_s11") -expect("===RTC===> St-Entry Obj=the_msm,State=QMsmTst_s1") -expect("===RTC===> St-Entry Obj=the_msm,State=QMsmTst_s11") -expect("@timestamp ===>Tran Obj=the_msm,Sig=D_SIG,State=QMsmTst_s1->QMsmTst_s11") +expect("@timestamp Disp===> Obj=the_sm,Sig=D_SIG,State=QMsmTst_s11") +expect("===RTC===> St-Unhnd Obj=the_sm,Sig=D_SIG,State=QMsmTst_s11") +expect("===RTC===> St-Exit Obj=the_sm,State=QMsmTst_s11") +expect("===RTC===> St-Exit Obj=the_sm,State=QMsmTst_s1") +expect("===RTC===> St-Init Obj=the_sm,State=QMsmTst_s->QMsmTst_s11") +expect("===RTC===> St-Entry Obj=the_sm,State=QMsmTst_s1") +expect("===RTC===> St-Entry Obj=the_sm,State=QMsmTst_s11") +expect("@timestamp ===>Tran Obj=the_sm,Sig=D_SIG,State=QMsmTst_s1->QMsmTst_s11") expect("@timestamp Trg-Done QS_RX_EVENT") dispatch("D_SIG") -expect("@timestamp Disp===> Obj=the_msm,Sig=D_SIG,State=QMsmTst_s11") -expect("===RTC===> St-Exit Obj=the_msm,State=QMsmTst_s11") -expect("===RTC===> St-Init Obj=the_msm,State=QMsmTst_s1->QMsmTst_s11") -expect("===RTC===> St-Entry Obj=the_msm,State=QMsmTst_s11") -expect("@timestamp ===>Tran Obj=the_msm,Sig=D_SIG,State=QMsmTst_s11->QMsmTst_s11") +expect("@timestamp Disp===> Obj=the_sm,Sig=D_SIG,State=QMsmTst_s11") +expect("===RTC===> St-Exit Obj=the_sm,State=QMsmTst_s11") +expect("===RTC===> St-Init Obj=the_sm,State=QMsmTst_s1->QMsmTst_s11") +expect("===RTC===> St-Entry Obj=the_sm,State=QMsmTst_s11") +expect("@timestamp ===>Tran Obj=the_sm,Sig=D_SIG,State=QMsmTst_s11->QMsmTst_s11") expect("@timestamp Trg-Done QS_RX_EVENT") dispatch("E_SIG") -expect("@timestamp Disp===> Obj=the_msm,Sig=E_SIG,State=QMsmTst_s11") -expect("===RTC===> St-Exit Obj=the_msm,State=QMsmTst_s11") -expect("===RTC===> St-Exit Obj=the_msm,State=QMsmTst_s1") -expect("===RTC===> St-Entry Obj=the_msm,State=QMsmTst_s1") -expect("===RTC===> St-Entry Obj=the_msm,State=QMsmTst_s11") -expect("@timestamp ===>Tran Obj=the_msm,Sig=E_SIG,State=QMsmTst_s->QMsmTst_s11") +expect("@timestamp Disp===> Obj=the_sm,Sig=E_SIG,State=QMsmTst_s11") +expect("===RTC===> St-Exit Obj=the_sm,State=QMsmTst_s11") +expect("===RTC===> St-Exit Obj=the_sm,State=QMsmTst_s1") +expect("===RTC===> St-Entry Obj=the_sm,State=QMsmTst_s1") +expect("===RTC===> St-Entry Obj=the_sm,State=QMsmTst_s11") +expect("@timestamp ===>Tran Obj=the_sm,Sig=E_SIG,State=QMsmTst_s->QMsmTst_s11") expect("@timestamp Trg-Done QS_RX_EVENT") dispatch("G_SIG") -expect("@timestamp Disp===> Obj=the_msm,Sig=G_SIG,State=QMsmTst_s11") -expect("===RTC===> St-Exit Obj=the_msm,State=QMsmTst_s11") -expect("===RTC===> St-Exit Obj=the_msm,State=QMsmTst_s1") -expect("===RTC===> St-Entry Obj=the_msm,State=QMsmTst_s2") -expect("===RTC===> St-Entry Obj=the_msm,State=QMsmTst_s21") -expect("===RTC===> St-Entry Obj=the_msm,State=QMsmTst_s211") -expect("@timestamp ===>Tran Obj=the_msm,Sig=G_SIG,State=QMsmTst_s11->QMsmTst_s211") +expect("@timestamp Disp===> Obj=the_sm,Sig=G_SIG,State=QMsmTst_s11") +expect("===RTC===> St-Exit Obj=the_sm,State=QMsmTst_s11") +expect("===RTC===> St-Exit Obj=the_sm,State=QMsmTst_s1") +expect("===RTC===> St-Entry Obj=the_sm,State=QMsmTst_s2") +expect("===RTC===> St-Entry Obj=the_sm,State=QMsmTst_s21") +expect("===RTC===> St-Entry Obj=the_sm,State=QMsmTst_s211") +expect("@timestamp ===>Tran Obj=the_sm,Sig=G_SIG,State=QMsmTst_s11->QMsmTst_s211") expect("@timestamp Trg-Done QS_RX_EVENT") dispatch("H_SIG") -expect("@timestamp Disp===> Obj=the_msm,Sig=H_SIG,State=QMsmTst_s211") -expect("===RTC===> St-Exit Obj=the_msm,State=QMsmTst_s211") -expect("===RTC===> St-Exit Obj=the_msm,State=QMsmTst_s21") -expect("===RTC===> St-Exit Obj=the_msm,State=QMsmTst_s2") -expect("===RTC===> St-Init Obj=the_msm,State=QMsmTst_s->QMsmTst_s11") -expect("===RTC===> St-Entry Obj=the_msm,State=QMsmTst_s1") -expect("===RTC===> St-Entry Obj=the_msm,State=QMsmTst_s11") -expect("@timestamp ===>Tran Obj=the_msm,Sig=H_SIG,State=QMsmTst_s211->QMsmTst_s11") +expect("@timestamp Disp===> Obj=the_sm,Sig=H_SIG,State=QMsmTst_s211") +expect("===RTC===> St-Exit Obj=the_sm,State=QMsmTst_s211") +expect("===RTC===> St-Exit Obj=the_sm,State=QMsmTst_s21") +expect("===RTC===> St-Exit Obj=the_sm,State=QMsmTst_s2") +expect("===RTC===> St-Init Obj=the_sm,State=QMsmTst_s->QMsmTst_s11") +expect("===RTC===> St-Entry Obj=the_sm,State=QMsmTst_s1") +expect("===RTC===> St-Entry Obj=the_sm,State=QMsmTst_s11") +expect("@timestamp ===>Tran Obj=the_sm,Sig=H_SIG,State=QMsmTst_s211->QMsmTst_s11") expect("@timestamp Trg-Done QS_RX_EVENT") dispatch("H_SIG") -expect("@timestamp Disp===> Obj=the_msm,Sig=H_SIG,State=QMsmTst_s11") -expect("===RTC===> St-Exit Obj=the_msm,State=QMsmTst_s11") -expect("===RTC===> St-Exit Obj=the_msm,State=QMsmTst_s1") -expect("===RTC===> St-Init Obj=the_msm,State=QMsmTst_s->QMsmTst_s11") -expect("===RTC===> St-Entry Obj=the_msm,State=QMsmTst_s1") -expect("===RTC===> St-Entry Obj=the_msm,State=QMsmTst_s11") -expect("@timestamp ===>Tran Obj=the_msm,Sig=H_SIG,State=QMsmTst_s11->QMsmTst_s11") +expect("@timestamp Disp===> Obj=the_sm,Sig=H_SIG,State=QMsmTst_s11") +expect("===RTC===> St-Exit Obj=the_sm,State=QMsmTst_s11") +expect("===RTC===> St-Exit Obj=the_sm,State=QMsmTst_s1") +expect("===RTC===> St-Init Obj=the_sm,State=QMsmTst_s->QMsmTst_s11") +expect("===RTC===> St-Entry Obj=the_sm,State=QMsmTst_s1") +expect("===RTC===> St-Entry Obj=the_sm,State=QMsmTst_s11") +expect("@timestamp ===>Tran Obj=the_sm,Sig=H_SIG,State=QMsmTst_s11->QMsmTst_s11") expect("@timestamp Trg-Done QS_RX_EVENT") dispatch("C_SIG") -expect("@timestamp Disp===> Obj=the_msm,Sig=C_SIG,State=QMsmTst_s11") -expect("===RTC===> St-Exit Obj=the_msm,State=QMsmTst_s11") -expect("===RTC===> St-Exit Obj=the_msm,State=QMsmTst_s1") -expect("===RTC===> St-Entry Obj=the_msm,State=QMsmTst_s2") -expect("===RTC===> St-Init Obj=the_msm,State=QMsmTst_s2->QMsmTst_s211") -expect("===RTC===> St-Entry Obj=the_msm,State=QMsmTst_s21") -expect("===RTC===> St-Entry Obj=the_msm,State=QMsmTst_s211") -expect("@timestamp ===>Tran Obj=the_msm,Sig=C_SIG,State=QMsmTst_s1->QMsmTst_s211") +expect("@timestamp Disp===> Obj=the_sm,Sig=C_SIG,State=QMsmTst_s11") +expect("===RTC===> St-Exit Obj=the_sm,State=QMsmTst_s11") +expect("===RTC===> St-Exit Obj=the_sm,State=QMsmTst_s1") +expect("===RTC===> St-Entry Obj=the_sm,State=QMsmTst_s2") +expect("===RTC===> St-Init Obj=the_sm,State=QMsmTst_s2->QMsmTst_s211") +expect("===RTC===> St-Entry Obj=the_sm,State=QMsmTst_s21") +expect("===RTC===> St-Entry Obj=the_sm,State=QMsmTst_s211") +expect("@timestamp ===>Tran Obj=the_sm,Sig=C_SIG,State=QMsmTst_s1->QMsmTst_s211") expect("@timestamp Trg-Done QS_RX_EVENT") dispatch("G_SIG") -expect("@timestamp Disp===> Obj=the_msm,Sig=G_SIG,State=QMsmTst_s211") -expect("===RTC===> St-Exit Obj=the_msm,State=QMsmTst_s211") -expect("===RTC===> St-Exit Obj=the_msm,State=QMsmTst_s21") -expect("===RTC===> St-Exit Obj=the_msm,State=QMsmTst_s2") -expect("===RTC===> St-Entry Obj=the_msm,State=QMsmTst_s1") -expect("===RTC===> St-Init Obj=the_msm,State=QMsmTst_s1->QMsmTst_s11") -expect("===RTC===> St-Entry Obj=the_msm,State=QMsmTst_s11") -expect("@timestamp ===>Tran Obj=the_msm,Sig=G_SIG,State=QMsmTst_s21->QMsmTst_s11") +expect("@timestamp Disp===> Obj=the_sm,Sig=G_SIG,State=QMsmTst_s211") +expect("===RTC===> St-Exit Obj=the_sm,State=QMsmTst_s211") +expect("===RTC===> St-Exit Obj=the_sm,State=QMsmTst_s21") +expect("===RTC===> St-Exit Obj=the_sm,State=QMsmTst_s2") +expect("===RTC===> St-Entry Obj=the_sm,State=QMsmTst_s1") +expect("===RTC===> St-Init Obj=the_sm,State=QMsmTst_s1->QMsmTst_s11") +expect("===RTC===> St-Entry Obj=the_sm,State=QMsmTst_s11") +expect("@timestamp ===>Tran Obj=the_sm,Sig=G_SIG,State=QMsmTst_s21->QMsmTst_s11") expect("@timestamp Trg-Done QS_RX_EVENT") dispatch("C_SIG") -expect("@timestamp Disp===> Obj=the_msm,Sig=C_SIG,State=QMsmTst_s11") -expect("===RTC===> St-Exit Obj=the_msm,State=QMsmTst_s11") -expect("===RTC===> St-Exit Obj=the_msm,State=QMsmTst_s1") -expect("===RTC===> St-Entry Obj=the_msm,State=QMsmTst_s2") -expect("===RTC===> St-Init Obj=the_msm,State=QMsmTst_s2->QMsmTst_s211") -expect("===RTC===> St-Entry Obj=the_msm,State=QMsmTst_s21") -expect("===RTC===> St-Entry Obj=the_msm,State=QMsmTst_s211") -expect("@timestamp ===>Tran Obj=the_msm,Sig=C_SIG,State=QMsmTst_s1->QMsmTst_s211") +expect("@timestamp Disp===> Obj=the_sm,Sig=C_SIG,State=QMsmTst_s11") +expect("===RTC===> St-Exit Obj=the_sm,State=QMsmTst_s11") +expect("===RTC===> St-Exit Obj=the_sm,State=QMsmTst_s1") +expect("===RTC===> St-Entry Obj=the_sm,State=QMsmTst_s2") +expect("===RTC===> St-Init Obj=the_sm,State=QMsmTst_s2->QMsmTst_s211") +expect("===RTC===> St-Entry Obj=the_sm,State=QMsmTst_s21") +expect("===RTC===> St-Entry Obj=the_sm,State=QMsmTst_s211") +expect("@timestamp ===>Tran Obj=the_sm,Sig=C_SIG,State=QMsmTst_s1->QMsmTst_s211") expect("@timestamp Trg-Done QS_RX_EVENT") dispatch("C_SIG") -expect("@timestamp Disp===> Obj=the_msm,Sig=C_SIG,State=QMsmTst_s211") -expect("===RTC===> St-Exit Obj=the_msm,State=QMsmTst_s211") -expect("===RTC===> St-Exit Obj=the_msm,State=QMsmTst_s21") -expect("===RTC===> St-Exit Obj=the_msm,State=QMsmTst_s2") -expect("===RTC===> St-Entry Obj=the_msm,State=QMsmTst_s1") -expect("===RTC===> St-Init Obj=the_msm,State=QMsmTst_s1->QMsmTst_s11") -expect("===RTC===> St-Entry Obj=the_msm,State=QMsmTst_s11") -expect("@timestamp ===>Tran Obj=the_msm,Sig=C_SIG,State=QMsmTst_s2->QMsmTst_s11") +expect("@timestamp Disp===> Obj=the_sm,Sig=C_SIG,State=QMsmTst_s211") +expect("===RTC===> St-Exit Obj=the_sm,State=QMsmTst_s211") +expect("===RTC===> St-Exit Obj=the_sm,State=QMsmTst_s21") +expect("===RTC===> St-Exit Obj=the_sm,State=QMsmTst_s2") +expect("===RTC===> St-Entry Obj=the_sm,State=QMsmTst_s1") +expect("===RTC===> St-Init Obj=the_sm,State=QMsmTst_s1->QMsmTst_s11") +expect("===RTC===> St-Entry Obj=the_sm,State=QMsmTst_s11") +expect("@timestamp ===>Tran Obj=the_sm,Sig=C_SIG,State=QMsmTst_s2->QMsmTst_s11") expect("@timestamp Trg-Done QS_RX_EVENT") diff --git a/examples/qutest/qmsmtst/test/test_qmsm.c b/examples/qutest/qmsmtst/test/test_qmsm.c index 433dab41..48126093 100644 --- a/examples/qutest/qmsmtst/test/test_qmsm.c +++ b/examples/qutest/qmsmtst/test/test_qmsm.c @@ -1,36 +1,36 @@ -/***************************************************************************** -* Purpose: Fixture for QUTEST -* Last Updated for Version: 6.3.5 -* Date of the Last Update: 2018-09-16 -* -* Q u a n t u m L e a P s -* ------------------------ -* Modern Embedded Software -* -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* -* -*****************************************************************************/ +//============================================================================ +// Purpose: Fixture for QUTEST +// Last Updated for Version: 7.3.0 +// Date of the Last Update: 2023-08-25 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// This program is open source software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Alternatively, this program may be distributed and modified under the +// terms of Quantum Leaps commercial licenses, which expressly supersede +// the GNU General Public License and are specifically designed for +// licensees interested in retaining the proprietary status of their code. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Contact information: +// +// +//============================================================================ #include "qpc.h" #include "qmsmtst.h" @@ -40,51 +40,52 @@ enum { BSP_DISPLAY = QS_USER, }; -/*--------------------------------------------------------------------------*/ +//---------------------------------------------------------------------------- int main(int argc, char *argv[]) { - static QF_MPOOL_EL(QEvt) smlPoolSto[10]; /* small pool */ + QF_init(); // initialize the framework - QF_init(); /* initialize the framework */ + // initialize the QS software tracing + if (QS_INIT((argc > 1) ? argv[1] : (void *)0) == 0U) { + Q_ERROR(); + } - /* initialize the QS software tracing */ - Q_ALLEGE(QS_INIT(argc > 1 ? argv[1] : (void *)0)); - - /* initialize event pools... */ + // initialize event pools... + static QF_MPOOL_EL(QEvt) smlPoolSto[10]; // small pool QF_poolInit(smlPoolSto, sizeof(smlPoolSto), sizeof(smlPoolSto[0])); - /* dictionaries... */ - QS_OBJ_DICTIONARY(the_msm); + // dictionaries... + QS_OBJ_DICTIONARY(the_sm); QS_USR_DICTIONARY(BSP_DISPLAY); - QMsmTst_ctor(); /* instantiate the QHsmTst object */ + QMsmTst_ctor(); // instantiate the QMsmTst object return QF_run(); } -/*--------------------------------------------------------------------------*/ +//---------------------------------------------------------------------------- void BSP_display(char const *msg) { - QS_BEGIN_ID(BSP_DISPLAY, 0U) /* app-specific record */ + QS_BEGIN_ID(BSP_DISPLAY, 0U) // app-specific record QS_STR(msg); QS_END() } - -/*..........................................................................*/ -void BSP_exit(void) { +//............................................................................ +void BSP_terminate(int16_t const result) { + Q_UNUSED_PAR(result); } -/*--------------------------------------------------------------------------*/ +//---------------------------------------------------------------------------- void QS_onTestSetup(void) { } -/*..........................................................................*/ +//............................................................................ void QS_onTestTeardown(void) { } -/*..........................................................................*/ +//............................................................................ void QS_onCommand(uint8_t cmdId, uint32_t param1, uint32_t param2, uint32_t param3) { - (void)param1; - (void)param2; - (void)param3; + Q_UNUSED_PAR(param1); + Q_UNUSED_PAR(param2); + Q_UNUSED_PAR(param3); //PRINTF_S(" Command id=%d param=%d\n", (int)cmdId, (int)param); switch (cmdId) { @@ -96,22 +97,22 @@ void QS_onCommand(uint8_t cmdId, } } -/*..........................................................................*/ -/* host callback function to "massage" the event, if necessary */ +//............................................................................ +// host callback function to "massage" the event, if necessary void QS_onTestEvt(QEvt *e) { (void)e; -#ifdef Q_HOST /* is this test compiled for a desktop Host computer? */ -#else /* this test is compiled for an embedded Target system */ +#ifdef Q_HOST // is this test compiled for a desktop Host computer? +#else // this test is compiled for an embedded Target system #endif } -/*..........................................................................*/ -/*! callback function to output the posted QP events (not used here) */ +//............................................................................ +//! callback function to output the posted QP events (not used here) void QS_onTestPost(void const *sender, QActive *recipient, QEvt const *e, bool status) { - (void)sender; - (void)recipient; - (void)e; - (void)status; + Q_UNUSED_PAR(sender); + Q_UNUSED_PAR(recipient); + Q_UNUSED_PAR(e); + Q_UNUSED_PAR(status); } diff --git a/examples/qutest/self_test/test/Makefile b/examples/qutest/self_test/test/Makefile index 473c6e65..3ac1ae26 100644 --- a/examples/qutest/self_test/test/Makefile +++ b/examples/qutest/self_test/test/Makefile @@ -216,7 +216,7 @@ all : $(TARGET_EXE) run endif $(TARGET_EXE) : $(C_OBJS_EXT) $(CPP_OBJS_EXT) - $(CC) $(CFLAGS) $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o + $(CC) $(CFLAGS) $(QPC)/src/qs/qstamp.c -o $(BIN_DIR)/qstamp.o $(LINK) $(LINKFLAGS) $(LIB_DIRS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) run : $(TARGET_EXE) diff --git a/examples/qutest/self_test/test/make_efm32 b/examples/qutest/self_test/test/make_efm32 index 4f40193a..06a75937 100644 --- a/examples/qutest/self_test/test/make_efm32 +++ b/examples/qutest/self_test/test/make_efm32 @@ -1,13 +1,13 @@ ############################################################################## # Product: Makefile for QP/C on EMF32, QUTEST, GNU-ARM -# Last Updated for Version: 7.2.0 -# Date of the Last Update: 2022-12-21 +# Last Updated for Version: 7.3.0 +# Date of the Last Update: 2023-07-18 # # Q u a n t u m L e a P s # ------------------------ # Modern Embedded Software # -# Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +# Copyright (C) 2005 Quantum Leaps, LLC. # # This program is open source software: you can redistribute it and/or # modify it under the terms of the GNU General Public License as published @@ -251,7 +251,7 @@ $(TARGET_BIN) : $(TARGET_ELF) $(FLASH) $@ $(TARGET_ELF) : $(ASM_OBJS_EXT) $(C_OBJS_EXT) $(CPP_OBJS_EXT) - $(CC) $(CFLAGS) $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o + $(CC) $(CFLAGS) $(QPC)/src/qs/qstamp.c -o $(BIN_DIR)/qstamp.o $(LINK) $(LINKFLAGS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) flash : diff --git a/examples/qutest/self_test/test/make_nucleo-l053r8 b/examples/qutest/self_test/test/make_nucleo-l053r8 index cf623c26..35aecdf2 100644 --- a/examples/qutest/self_test/test/make_nucleo-l053r8 +++ b/examples/qutest/self_test/test/make_nucleo-l053r8 @@ -251,7 +251,7 @@ $(TARGET_BIN) : $(TARGET_ELF) $(SLEEP) 2 $(TARGET_ELF) : $(ASM_OBJS_EXT) $(C_OBJS_EXT) $(CPP_OBJS_EXT) - $(CC) $(CFLAGS) $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o + $(CC) $(CFLAGS) $(QPC)/src/qs/qstamp.c -o $(BIN_DIR)/qstamp.o $(LINK) $(LINKFLAGS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) flash : diff --git a/examples/qutest/self_test/test/make_posix b/examples/qutest/self_test/test/make_posix index 7a3555f5..02ddc73a 100644 --- a/examples/qutest/self_test/test/make_posix +++ b/examples/qutest/self_test/test/make_posix @@ -181,7 +181,7 @@ all : $(TARGET_EXE) run endif $(TARGET_EXE) : $(C_OBJS_EXT) $(CPP_OBJS_EXT) - $(CC) $(CFLAGS) $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o + $(CC) $(CFLAGS) $(QPC)/src/qs/qstamp.c -o $(BIN_DIR)/qstamp.o $(LINK) $(LINKFLAGS) $(LIB_DIRS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) # run the test fixture on a POSIX target in a loop, so that it is re-started diff --git a/examples/qutest/self_test/test/make_tm4c123 b/examples/qutest/self_test/test/make_tm4c123 index 791ca9f7..cc21a78b 100644 --- a/examples/qutest/self_test/test/make_tm4c123 +++ b/examples/qutest/self_test/test/make_tm4c123 @@ -252,7 +252,7 @@ $(TARGET_BIN) : $(TARGET_ELF) @pause $(TARGET_ELF) : $(ASM_OBJS_EXT) $(C_OBJS_EXT) $(CPP_OBJS_EXT) - $(CC) $(CFLAGS) $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o + $(CC) $(CFLAGS) $(QPC)/src/qs/qstamp.c -o $(BIN_DIR)/qstamp.o $(LINK) $(LINKFLAGS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) flash : diff --git a/examples/qutest/self_test/test/test_efm32.uvoptx b/examples/qutest/self_test/test/test_efm32.uvoptx index bb3582c9..abb9af65 100644 --- a/examples/qutest/self_test/test/test_efm32.uvoptx +++ b/examples/qutest/self_test/test/test_efm32.uvoptx @@ -10,7 +10,7 @@ *.s*; *.src; *.a* *.obj; *.o *.lib - *.txt; *.h; *.inc + *.txt; *.h; *.inc; *.md *.plm *.cpp 0 @@ -103,7 +103,7 @@ 1 0 0 - 3 + 4 @@ -148,24 +148,7 @@ - - - 0 - 0 - 100 - 1 -
8370
- 0 - 0 - 0 - 0 - 0 - 1 - .\test_qutest.c - - \\test_efm32\test_qutest.c\100 -
-
+ 0 @@ -247,7 +230,7 @@ 0 0 0 - ..\..\..\..\include\qstamp.c + ..\..\..\..\src\qs\qstamp.c qstamp.c 0 0 @@ -395,18 +378,6 @@ 0 0 0 - ..\..\..\..\src\qf\qf_act.c - qf_act.c - 0 - 0 - - - 3 - 13 - 1 - 0 - 0 - 0 ..\..\..\..\src\qf\qf_actq.c qf_actq.c 0 @@ -414,7 +385,7 @@ 3 - 14 + 13 1 0 0 @@ -426,7 +397,7 @@ 3 - 15 + 14 1 0 0 @@ -438,7 +409,7 @@ 3 - 16 + 15 1 0 0 @@ -450,7 +421,7 @@ 3 - 17 + 16 1 0 0 @@ -462,7 +433,7 @@ 3 - 18 + 17 1 0 0 @@ -474,7 +445,7 @@ 3 - 19 + 18 1 0 0 @@ -486,7 +457,7 @@ 3 - 20 + 19 1 0 0 @@ -498,7 +469,7 @@ 3 - 21 + 20 1 0 0 @@ -510,7 +481,7 @@ 3 - 22 + 21 1 0 0 @@ -522,7 +493,7 @@ 3 - 23 + 22 1 0 0 @@ -534,7 +505,7 @@ 3 - 24 + 23 1 0 0 @@ -546,7 +517,7 @@ 3 - 25 + 24 1 0 0 @@ -558,7 +529,7 @@ 3 - 26 + 25 1 0 0 @@ -568,6 +539,18 @@ 0 0 + + 3 + 26 + 1 + 0 + 0 + 0 + ..\..\..\..\src\qf\qf_act.c + qf_act.c + 0 + 0 + @@ -583,7 +566,7 @@ 0 0 0 - ..\..\target_efm32\qutest_port.c + ..\..\..\..\3rd_party\efm32pg1b\qutest\qutest_port.c qutest_port.c 0 0 diff --git a/examples/qutest/self_test/test/test_efm32.uvprojx b/examples/qutest/self_test/test/test_efm32.uvprojx index 3c45297a..94b1398d 100644 --- a/examples/qutest/self_test/test/test_efm32.uvprojx +++ b/examples/qutest/self_test/test/test_efm32.uvprojx @@ -10,13 +10,13 @@ test_efm32 0x4 ARM-ADS - 5060750::V5.06 update 6 (build 750)::ARMCC + 5060960::V5.06 update 7 (build 960)::.\ARMCC 0 EFM32PG1B200F256GM48 Silicon Labs - SiliconLabs.EFM32PG1B_DFP.5.5.0 + SiliconLabs.GeckoPlatform_EFM32PG1B_DFP.4.0.0 https://www.silabs.com/documents/public/cmsis-packs/ IRAM(0x20000000,0x00008000) IROM(0x00000000,0x00040000) CPUTYPE("Cortex-M4") FPU2 CLOCK(12000000) ELITTLE @@ -185,6 +185,7 @@ 0 2 0 + 0 0 0 8 @@ -324,7 +325,7 @@ 2 0 1 - 0 + 1 0 0 0 @@ -336,7 +337,7 @@ 0 - Q_SPY Q_UTEST __FPU_PRESENT + Q_SPY Q_UTEST .;..\src;..\..\..\..\include;..\..\..\..\src;..\..\..\..\ports\arm-cm\qutest;..\..\..\..\3rd_party\CMSIS\Include;..\..\..\..\3rd_party\efm32pg1b @@ -351,7 +352,7 @@ 0 1 0 - 0 + 4 Stack_Size=2048 Heap_Size=16 @@ -385,7 +386,7 @@ qstamp.c 1 - ..\..\..\..\include\qstamp.c + ..\..\..\..\src\qs\qstamp.c test_qutest.c @@ -447,11 +448,6 @@ 1 ..\..\..\..\src\qf\qep_msm.c - - qf_act.c - 1 - ..\..\..\..\src\qf\qf_act.c - qf_actq.c 1 @@ -522,6 +518,11 @@ 1 ..\..\..\..\src\qs\qutest.c + + qf_act.c + 1 + ..\..\..\..\src\qf\qf_act.c + @@ -530,7 +531,7 @@ qutest_port.c 1 - ..\..\target_efm32\qutest_port.c + ..\..\..\..\3rd_party\efm32pg1b\qutest\qutest_port.c diff --git a/examples/qutest/self_test/test/test_qutest.c b/examples/qutest/self_test/test/test_qutest.c index 7dbfeaa5..d95f9d08 100644 --- a/examples/qutest/self_test/test/test_qutest.c +++ b/examples/qutest/self_test/test/test_qutest.c @@ -1,41 +1,41 @@ -/***************************************************************************** -* Purpose: Fixture for QUTEST self-test -* Last Updated for Version: 7.2.0 -* Date of the Last Update: 2022-12-07 -* -* Q u a n t u m L e a P s -* ------------------------ -* Modern Embedded Software -* -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* -* -*****************************************************************************/ -#include "qpc.h" /* for QUTEST */ +//============================================================================ +// Purpose: Fixture for QUTEST self-test +// Last Updated for Version: 7.3.0 +// Date of the Last Update: 2023-05-25 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// This program is open source software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Alternatively, this program may be distributed and modified under the +// terms of Quantum Leaps commercial licenses, which expressly supersede +// the GNU General Public License and are specifically designed for +// licensees interested in retaining the proprietary status of their code. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Contact information: +// +// +//============================================================================ +#include "qpc.h" // for QUTEST Q_DEFINE_THIS_MODULE("test_qutest") -/*--------------------------------------------------------------------------*/ +//---------------------------------------------------------------------------- static uint8_t buffer[100]; static uint32_t myFun(void); @@ -58,18 +58,20 @@ enum UsrSig { MYSIG_SIG = Q_USER_SIG, }; -/*--------------------------------------------------------------------------*/ +//---------------------------------------------------------------------------- int main(int argc, char *argv[]) { - QF_init(); /* initialize the framework */ + QF_init(); // initialize the framework - /* initialize the QS software tracing */ - Q_ALLEGE(QS_INIT(argc > 1 ? argv[1] : (void *)0)); + // initialize the QS software tracing + if (QS_INIT((argc > 1) ? argv[1] : (void *)0) == 0U) { + Q_ERROR(); + } - /* global filter */ - QS_GLB_FILTER(QS_ALL_RECORDS); /* enable all QS records */ + // global filter + QS_GLB_FILTER(QS_ALL_RECORDS); // enable all QS records - /* dictionaries... */ + // dictionaries... QS_OBJ_DICTIONARY(buffer); QS_FUN_DICTIONARY(&myFun); QS_SIG_DICTIONARY(MYSIG_SIG, (void *)0); @@ -85,36 +87,36 @@ int main(int argc, char *argv[]) { QS_ENUM_DICTIONARY(CMD_Y, QS_CMD); QS_ENUM_DICTIONARY(CMD_Z, QS_CMD); - return QF_run(); /* run the tests */ + return QF_run(); // run the tests } -/*--------------------------------------------------------------------------*/ +//---------------------------------------------------------------------------- void QS_onTestSetup(void) { QS_BEGIN_ID(FIXTURE_SETUP, 0U) QS_END() } -/*..........................................................................*/ +//............................................................................ void QS_onTestTeardown(void) { QS_BEGIN_ID(FIXTURE_TEARDOWN, 0U) QS_END() } -/*..........................................................................*/ -/*! callback function to execute user commands */ +//............................................................................ +//! callback function to execute user commands void QS_onCommand(uint8_t cmdId, uint32_t param1, uint32_t param2, uint32_t param3) { switch (cmdId) { case CMD_A: { Q_ASSERT_ID(100, param1 != 0U); - QS_BEGIN_ID(COMMAND, 0U) /* app-specific record */ + QS_BEGIN_ID(COMMAND, 0U) // app-specific record QS_ENUM(QS_CMD, cmdId); QS_U32(0, param1); QS_END() break; } case CMD_B: { - QS_BEGIN_ID(COMMAND, 0U) /* app-specific record */ + QS_BEGIN_ID(COMMAND, 0U) // app-specific record QS_ENUM(QS_CMD, cmdId); QS_U8(0, param1); QS_STR("BAR"); @@ -126,8 +128,8 @@ void QS_onCommand(uint8_t cmdId, break; } case CMD_C: { - /* all supported data elements */ - QS_BEGIN_ID(COMMAND, 0U) /* app-specific record */ + // all supported data elements + QS_BEGIN_ID(COMMAND, 0U) // app-specific record QS_ENUM(QS_CMD, cmdId); QS_I8(10, param1); QS_U8(10, param1); @@ -136,13 +138,13 @@ void QS_onCommand(uint8_t cmdId, QS_I32(10, param3); QS_U32(10, param3); QS_END() - QS_BEGIN_ID(COMMAND, 0U) /* app-specific record */ + QS_BEGIN_ID(COMMAND, 0U) // app-specific record QS_I64(10, param3); QS_U64(10, param3); QS_F32(param1, -6.02214076E23); QS_F64(param1, -6.02214076E23); QS_END() - QS_BEGIN_ID(COMMAND, 0U) /* app-specific record */ + QS_BEGIN_ID(COMMAND, 0U) // app-specific record QS_OBJ(buffer); QS_FUN(&myFun); QS_SIG(MYSIG_SIG, (void *)0); @@ -152,15 +154,15 @@ void QS_onCommand(uint8_t cmdId, } case CMD_X: { uint32_t x = myFun(); - QS_BEGIN_ID(COMMAND, 0U) /* app-specific record */ + QS_BEGIN_ID(COMMAND, 0U) // app-specific record QS_ENUM(QS_CMD, cmdId); QS_U32(0, x); - /* ... */ + // ... QS_END() break; } case CMD_Y: { - QS_BEGIN_ID(COMMAND, 0U) /* application-specific record */ + QS_BEGIN_ID(COMMAND, 0U) // application-specific record QS_ENUM(QS_CMD, cmdId); QS_FUN(&myFun); QS_MEM(buffer, param1); @@ -171,7 +173,7 @@ void QS_onCommand(uint8_t cmdId, case CMD_Z: { float32_t f32 = (float32_t)((int32_t)param2/(float32_t)param3); float64_t f64 = -6.02214076E23; - QS_BEGIN_ID(COMMAND, 0U) /* app-specific record */ + QS_BEGIN_ID(COMMAND, 0U) // app-specific record QS_ENUM(QS_CMD, cmdId); QS_F32(param1, f32); QS_F64(param1, f64); @@ -183,16 +185,16 @@ void QS_onCommand(uint8_t cmdId, } } -/*..........................................................................*/ -/* host callback function to "massage" the event, if necessary */ +//............................................................................ +// host callback function to "massage" the event, if necessary void QS_onTestEvt(QEvt *e) { (void)e; -#ifdef Q_HOST /* is this test compiled for a desktop Host computer? */ -#else /* this test is compiled for an embedded Target system */ +#ifdef Q_HOST // is this test compiled for a desktop Host computer? +#else // this test is compiled for an embedded Target system #endif } -/*..........................................................................*/ -/*! callback function to output the posted QP events (not used here) */ +//............................................................................ +//! callback function to output the posted QP events (not used here) void QS_onTestPost(void const *sender, QActive *recipient, QEvt const *e, bool status) { @@ -202,7 +204,7 @@ void QS_onTestPost(void const *sender, QActive *recipient, Q_UNUSED_PAR(status); } -/*--------------------------------------------------------------------------*/ +//---------------------------------------------------------------------------- static uint32_t myFun(void) { QS_TEST_PROBE_DEF(&myFun) QS_TEST_PROBE( diff --git a/examples/qutest/self_test/test/test_tm4c123-arm.uvoptx b/examples/qutest/self_test/test/test_tm4c123-arm.uvoptx index 2a7ee44a..e156c8e5 100644 --- a/examples/qutest/self_test/test/test_tm4c123-arm.uvoptx +++ b/examples/qutest/self_test/test/test_tm4c123-arm.uvoptx @@ -262,7 +262,7 @@ 0 0 0 - ..\..\..\..\include\qstamp.c + ..\..\..\..\src\qs\qstamp.c qstamp.c 0 0 @@ -357,12 +357,12 @@ 3 - 8 + 16 1 0 0 0 - ..\..\..\..\src\qf\qf_act.c + ..\..\..\..\..\src\qf\qf_act.c qf_act.c 0 0 diff --git a/examples/qutest/self_test/test/test_tm4c123-arm.uvprojx b/examples/qutest/self_test/test/test_tm4c123-arm.uvprojx index b33acfe4..524fd4f5 100644 --- a/examples/qutest/self_test/test/test_tm4c123-arm.uvprojx +++ b/examples/qutest/self_test/test/test_tm4c123-arm.uvprojx @@ -336,7 +336,7 @@ 0 - Q_SPY Q_UTEST __FPU_PRESENT + Q_SPY Q_UTEST .;..\src;..\..\..\..\include;..\..\..\..\src;..\..\..\..\ports\arm-cm\qutest;..\..\..\..\3rd_party\CMSIS\Include;..\..\..\..\3rd_party\ek-tm4c123gxl @@ -385,7 +385,7 @@ qstamp.c 1 - ..\..\..\..\include\qstamp.c + ..\..\..\..\src\qs\qstamp.c test_qutest.c @@ -430,7 +430,7 @@ qf_act.c 1 - ..\..\..\..\src\qf\qf_act.c + ..\..\..\..\..\src\qf\qf_act.c qf_actq.c diff --git a/examples/qutest/start_seq/gizmo.qm b/examples/qutest/start_seq/gizmo.qm index 995e75d4..8916667c 100644 --- a/examples/qutest/start_seq/gizmo.qm +++ b/examples/qutest/start_seq/gizmo.qm @@ -1,5 +1,5 @@ - + Start sequence example @@ -22,8 +22,8 @@ - static QEvt const startEvt = { START_SIG, 0U, 0U }; -QACTIVE_POST(&me->super, &startEvt, me); /* self-post */ + static QEvt const startEvt = QEVT_INITIALIZER(START_SIG); +QACTIVE_POST(&me->super, &startEvt, me); // self-post QS_BEGIN_ID(QS_USER1, me->super.prio) @@ -69,7 +69,7 @@ QActive_ctor(&me->super, Q_STATE_CAST(&Gizmo_initial)); - /* opaque pointer to the Gizmo AO */ + // opaque pointer to the Gizmo AO = &Gizmo_inst.super; @@ -82,18 +82,18 @@ QActive_ctor(&me->super, Q_STATE_CAST(&Gizmo_initial)); enum BlinkySignals { DUMMY_SIG = Q_USER_SIG, - /* ... */ - MAX_PUB_SIG, /* the last published signal */ + // ... + MAX_PUB_SIG, // the last published signal START_SIG, - /* ... */ - MAX_SIG /* the last signal */ + // ... + MAX_SIG // the last signal }; $declare ${AOs::AO_Gizmo} $declare ${AOs::Gizmo_ctor} -#endif /* GIZMO_H_ */ +#endif // GIZMO_H_ diff --git a/examples/qutest/start_seq/src/bsp.c b/examples/qutest/start_seq/src/bsp.c index afceb2b3..de4944e8 100644 --- a/examples/qutest/start_seq/src/bsp.c +++ b/examples/qutest/start_seq/src/bsp.c @@ -1,36 +1,36 @@ -/***************************************************************************** -* Product: "Blinky" example, Win32 API -* Last Updated for Version: 7.2.0 -* Date of the Last Update: 2022-12-22 -* -* Q u a n t u m L e a P s -* --------------------------- -* innovating embedded systems -* -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* -* -*****************************************************************************/ +//============================================================================ +// Product: "Blinky" example, Win32 API +// Last Updated for Version: 7.2.0 +// Date of the Last Update: 2022-12-22 +// +// Q u a n t u m L e a P s +// --------------------------- +// innovating embedded systems +// +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// This program is open source software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Alternatively, this program may be distributed and modified under the +// terms of Quantum Leaps commercial licenses, which expressly supersede +// the GNU General Public License and are specifically designed for +// licensees interested in retaining the proprietary status of their code. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Contact information: +// +// +//============================================================================ #include "qpc.h" #include "bsp.h" #include "gizmo.h" @@ -39,20 +39,20 @@ static uint8_t status; -/*..........................................................................*/ +//............................................................................ void BSP_init() { QS_SIG_DICTIONARY(START_SIG, (void *)0); QS_OBJ_DICTIONARY(AO_Gizmo); QS_OBJ_DICTIONARY(&status); } -/*..........................................................................*/ +//............................................................................ void BSP_msg(char const *msg) { QS_BEGIN_ID(QS_USER1, 0U) QS_STR(msg); QS_END() } -/*..........................................................................*/ +//............................................................................ uint8_t BSP_getStatus(void) { return status; } diff --git a/examples/qutest/start_seq/src/bsp.h b/examples/qutest/start_seq/src/bsp.h index 763ed52d..d7ba5909 100644 --- a/examples/qutest/start_seq/src/bsp.h +++ b/examples/qutest/start_seq/src/bsp.h @@ -1,38 +1,38 @@ -/***************************************************************************** -* Product: DPP example -* Last Updated for Version: 7.2.0 -* Date of the Last Update: 2022-12-22 -* -* Q u a n t u m L e a P s -* --------------------------- -* innovating embedded systems -* -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* -* -*****************************************************************************/ -#ifndef BSP_H -#define BSP_H +//============================================================================ +// Product: DPP example +// Last Updated for Version: 7.2.0 +// Date of the Last Update: 2022-12-22 +// +// Q u a n t u m L e a P s +// --------------------------- +// innovating embedded systems +// +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// This program is open source software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Alternatively, this program may be distributed and modified under the +// terms of Quantum Leaps commercial licenses, which expressly supersede +// the GNU General Public License and are specifically designed for +// licensees interested in retaining the proprietary status of their code. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Contact information: +// +// +//============================================================================ +#ifndef BSP_H_ +#define BSP_H_ #define BSP_TICKS_PER_SEC 100U @@ -40,4 +40,4 @@ void BSP_init(void); void BSP_msg(char const *msg); uint8_t BSP_getStatus(void); -#endif /* BSP_H */ +#endif // BSP_H_ diff --git a/examples/qutest/start_seq/src/gizmo.c b/examples/qutest/start_seq/src/gizmo.c index 2e3405a0..9de39b7a 100644 --- a/examples/qutest/start_seq/src/gizmo.c +++ b/examples/qutest/start_seq/src/gizmo.c @@ -1,85 +1,85 @@ -/*$file${src::gizmo.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* -* Model: gizmo.qm -* File: ${src::gizmo.c} -* -* This code has been generated by QM 5.2.4 . -* DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. -* -* SPDX-License-Identifier: GPL-3.0-or-later -* -* This generated code is open source software: you can redistribute it under -* the terms of the GNU General Public License as published by the Free -* Software Foundation. -* -* This code is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -* more details. -* -* NOTE: -* Alternatively, this generated code may be distributed under the terms -* of Quantum Leaps commercial licenses, which expressly supersede the GNU -* General Public License and are specifically designed for licensees -* interested in retaining the proprietary status of their code. -* -* Contact information: -* -* -*/ -/*$endhead${src::gizmo.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$file${src::gizmo.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// +// Model: gizmo.qm +// File: ${src::gizmo.c} +// +// This code has been generated by QM 5.3.0 . +// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. +// +// SPDX-License-Identifier: GPL-3.0-or-later +// +// This generated code is open source software: you can redistribute it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation. +// +// This code is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// NOTE: +// Alternatively, this generated code may be distributed under the terms +// of Quantum Leaps commercial licenses, which expressly supersede the GNU +// General Public License and are specifically designed for licensees +// interested in retaining the proprietary status of their code. +// +// Contact information: +// +// +// +//$endhead${src::gizmo.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ #include "qpc.h" #include "bsp.h" #include "gizmo.h" //Q_DEFINE_THIS_MODULE("gizmo") -/*$declare${AOs::Gizmo} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//$declare${AOs::Gizmo} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/*${AOs::Gizmo} ............................................................*/ +//${AOs::Gizmo} .............................................................. typedef struct Gizmo { -/* protected: */ +// protected: QActive super; -/* public: */ +// public: } Gizmo; extern Gizmo Gizmo_inst; -/* protected: */ +// protected: static QState Gizmo_initial(Gizmo * const me, void const * const par); static QState Gizmo_init(Gizmo * const me, QEvt const * const e); static QState Gizmo_on_battery(Gizmo * const me, QEvt const * const e); static QState Gizmo_on_mains(Gizmo * const me, QEvt const * const e); -/*$enddecl${AOs::Gizmo} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$enddecl${AOs::Gizmo} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -/*$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* Check for the minimum required QP version */ -#if (QP_VERSION < 700U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) -#error qpc version 7.0.0 or higher required +//$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// Check for the minimum required QP version +#if (QP_VERSION < 730U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) +#error qpc version 7.3.0 or higher required #endif -/*$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -/*$define${AOs::AO_Gizmo} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//$define${AOs::AO_Gizmo} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/*${AOs::AO_Gizmo} .........................................................*/ +//${AOs::AO_Gizmo} ........................................................... QActive * const AO_Gizmo = &Gizmo_inst.super; -/*$enddef${AOs::AO_Gizmo} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*$define${AOs::Gizmo_ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//$enddef${AOs::AO_Gizmo} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +//$define${AOs::Gizmo_ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/*${AOs::Gizmo_ctor} .......................................................*/ +//${AOs::Gizmo_ctor} ......................................................... void Gizmo_ctor(void) { Gizmo *me = &Gizmo_inst; QActive_ctor(&me->super, Q_STATE_CAST(&Gizmo_initial)); } -/*$enddef${AOs::Gizmo_ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*$define${AOs::Gizmo} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//$enddef${AOs::Gizmo_ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +//$define${AOs::Gizmo} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/*${AOs::Gizmo} ............................................................*/ +//${AOs::Gizmo} .............................................................. Gizmo Gizmo_inst; -/*${AOs::Gizmo::SM} ........................................................*/ +//${AOs::Gizmo::SM} .......................................................... static QState Gizmo_initial(Gizmo * const me, void const * const par) { - /*${AOs::Gizmo::SM::initial} */ + //${AOs::Gizmo::SM::initial} Q_UNUSED_PAR(par); QS_FUN_DICTIONARY(&Gizmo_init); @@ -89,27 +89,27 @@ static QState Gizmo_initial(Gizmo * const me, void const * const par) { return Q_TRAN(&Gizmo_init); } -/*${AOs::Gizmo::SM::init} ..................................................*/ +//${AOs::Gizmo::SM::init} .................................................... static QState Gizmo_init(Gizmo * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${AOs::Gizmo::SM::init} */ + //${AOs::Gizmo::SM::init} case Q_ENTRY_SIG: { - static QEvt const startEvt = { START_SIG, 0U, 0U }; - QACTIVE_POST(&me->super, &startEvt, me); /* self-post */ + static QEvt const startEvt = QEVT_INITIALIZER(START_SIG); + QACTIVE_POST(&me->super, &startEvt, me); // self-post status_ = Q_HANDLED(); break; } - /*${AOs::Gizmo::SM::init::START} */ + //${AOs::Gizmo::SM::init::START} case START_SIG: { QS_BEGIN_ID(QS_USER1, me->super.prio) QS_STR("START"); QS_END() - /*${AOs::Gizmo::SM::init::START::[BSP_getStatus()]} */ + //${AOs::Gizmo::SM::init::START::[BSP_getStatus()]} if (BSP_getStatus()) { status_ = Q_TRAN(&Gizmo_on_mains); } - /*${AOs::Gizmo::SM::init::START::[else]} */ + //${AOs::Gizmo::SM::init::START::[else]} else { status_ = Q_TRAN(&Gizmo_on_battery); } @@ -123,7 +123,7 @@ static QState Gizmo_init(Gizmo * const me, QEvt const * const e) { return status_; } -/*${AOs::Gizmo::SM::on_battery} ............................................*/ +//${AOs::Gizmo::SM::on_battery} .............................................. static QState Gizmo_on_battery(Gizmo * const me, QEvt const * const e) { QState status_; switch (e->sig) { @@ -135,7 +135,7 @@ static QState Gizmo_on_battery(Gizmo * const me, QEvt const * const e) { return status_; } -/*${AOs::Gizmo::SM::on_mains} ..............................................*/ +//${AOs::Gizmo::SM::on_mains} ................................................ static QState Gizmo_on_mains(Gizmo * const me, QEvt const * const e) { QState status_; switch (e->sig) { @@ -146,4 +146,4 @@ static QState Gizmo_on_mains(Gizmo * const me, QEvt const * const e) { } return status_; } -/*$enddef${AOs::Gizmo} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$enddef${AOs::Gizmo} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/examples/qutest/start_seq/src/gizmo.h b/examples/qutest/start_seq/src/gizmo.h index 177d569f..74d2adb0 100644 --- a/examples/qutest/start_seq/src/gizmo.h +++ b/examples/qutest/start_seq/src/gizmo.h @@ -1,56 +1,56 @@ -/*$file${src::gizmo.h} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* -* Model: gizmo.qm -* File: ${src::gizmo.h} -* -* This code has been generated by QM 5.2.4 . -* DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. -* -* SPDX-License-Identifier: GPL-3.0-or-later -* -* This generated code is open source software: you can redistribute it under -* the terms of the GNU General Public License as published by the Free -* Software Foundation. -* -* This code is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -* more details. -* -* NOTE: -* Alternatively, this generated code may be distributed under the terms -* of Quantum Leaps commercial licenses, which expressly supersede the GNU -* General Public License and are specifically designed for licensees -* interested in retaining the proprietary status of their code. -* -* Contact information: -* -* -*/ -/*$endhead${src::gizmo.h} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$file${src::gizmo.h} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// +// Model: gizmo.qm +// File: ${src::gizmo.h} +// +// This code has been generated by QM 5.3.0 . +// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. +// +// SPDX-License-Identifier: GPL-3.0-or-later +// +// This generated code is open source software: you can redistribute it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation. +// +// This code is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// NOTE: +// Alternatively, this generated code may be distributed under the terms +// of Quantum Leaps commercial licenses, which expressly supersede the GNU +// General Public License and are specifically designed for licensees +// interested in retaining the proprietary status of their code. +// +// Contact information: +// +// +// +//$endhead${src::gizmo.h} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ #ifndef GIZMO_H_ #define GIZMO_H_ enum BlinkySignals { DUMMY_SIG = Q_USER_SIG, - /* ... */ - MAX_PUB_SIG, /* the last published signal */ + // ... + MAX_PUB_SIG, // the last published signal START_SIG, - /* ... */ - MAX_SIG /* the last signal */ + // ... + MAX_SIG // the last signal }; -/*$declare${AOs::AO_Gizmo} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//$declare${AOs::AO_Gizmo} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/*${AOs::AO_Gizmo} .........................................................*/ -/* opaque pointer to the Gizmo AO */ +//${AOs::AO_Gizmo} ........................................................... +// opaque pointer to the Gizmo AO extern QActive * const AO_Gizmo; -/*$enddecl${AOs::AO_Gizmo} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*$declare${AOs::Gizmo_ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//$enddecl${AOs::AO_Gizmo} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +//$declare${AOs::Gizmo_ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/*${AOs::Gizmo_ctor} .......................................................*/ +//${AOs::Gizmo_ctor} ......................................................... void Gizmo_ctor(void); -/*$enddecl${AOs::Gizmo_ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$enddecl${AOs::Gizmo_ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -#endif /* GIZMO_H_ */ +#endif // GIZMO_H_ diff --git a/examples/qutest/start_seq/test/Makefile b/examples/qutest/start_seq/test/Makefile index 23b15c7e..1cf9ed32 100644 --- a/examples/qutest/start_seq/test/Makefile +++ b/examples/qutest/start_seq/test/Makefile @@ -218,7 +218,7 @@ all : $(TARGET_EXE) run endif $(TARGET_EXE) : $(C_OBJS_EXT) $(CPP_OBJS_EXT) - $(CC) $(CFLAGS) $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o + $(CC) $(CFLAGS) $(QPC)/src/qs/qstamp.c -o $(BIN_DIR)/qstamp.o $(LINK) $(LINKFLAGS) $(LIB_DIRS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) run : $(TARGET_EXE) diff --git a/examples/qutest/start_seq/test/test_fixture.c b/examples/qutest/start_seq/test/test_fixture.c index cc11a3e5..76d34c19 100644 --- a/examples/qutest/start_seq/test/test_fixture.c +++ b/examples/qutest/start_seq/test/test_fixture.c @@ -1,81 +1,81 @@ -/***************************************************************************** -* Purpose: Fixture for QUTEST -* Last Updated for Version: 7.2.0 -* Date of the Last Update: 2022-12-22 -* -* Q u a n t u m L e a P s -* ------------------------ -* Modern Embedded Software -* -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* -* -*****************************************************************************/ +//============================================================================ +// Purpose: Fixture for QUTEST +// Last Updated for Version: 7.2.0 +// Date of the Last Update: 2022-12-22 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// This program is open source software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Alternatively, this program may be distributed and modified under the +// terms of Quantum Leaps commercial licenses, which expressly supersede +// the GNU General Public License and are specifically designed for +// licensees interested in retaining the proprietary status of their code. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Contact information: +// +// +//============================================================================ #include "qpc.h" #include "gizmo.h" #include "bsp.h" Q_DEFINE_THIS_FILE -/*..........................................................................*/ +//............................................................................ int main(int argc, char *argv[]) { - QF_init(); /* initialize the framework */ + QF_init(); // initialize the framework - /* initialize the QS software tracing */ + // initialize the QS software tracing if (QS_INIT(argc > 1 ? argv[1] : (void *)0) == 0U) { - Q_ERROR(); /* no point in continuing if QS initialzation fails */ + Q_ERROR(); // no point in continuing if QS initialzation fails } - BSP_init(); /* initialize the BSP */ + BSP_init(); // initialize the BSP - /* pause execution of the test and wait for the test script to continue */ + // pause execution of the test and wait for the test script to continue QS_TEST_PAUSE(); - /* publish-subscribe not used, no call to QF_psInit() */ + // publish-subscribe not used, no call to QActive_psInit() - /* initialize event pools... */ - static QF_MPOOL_EL(QEvt) smlPoolSto[10]; /* storage for small pool*/ + // initialize event pools... + static QF_MPOOL_EL(QEvt) smlPoolSto[10]; // storage for small pool QF_poolInit(smlPoolSto, sizeof(smlPoolSto), sizeof(smlPoolSto[0])); - /* start the active objects... */ + // start the active objects... Gizmo_ctor(); - static QEvt const *qSto[10]; /* event queue storage */ + static QEvt const *qSto[10]; // event queue storage QACTIVE_START(AO_Gizmo, - 2U, /* QF-priority/preemption-threshold */ + 2U, // QF-priority/preemption-threshold qSto, Q_DIM(qSto), (void *)0, 0U, (void *)0); return QF_run(); } -/*--------------------------------------------------------------------------*/ +//---------------------------------------------------------------------------- void QS_onTestSetup(void) { } -/*..........................................................................*/ +//............................................................................ void QS_onTestTeardown(void) { } -/*..........................................................................*/ +//............................................................................ void QS_onCommand(uint8_t cmdId, uint32_t param1, uint32_t param2, uint32_t param3) { @@ -85,13 +85,13 @@ void QS_onCommand(uint8_t cmdId, Q_UNUSED_PAR(param3); } -/*..........................................................................*/ -/* host callback function to "massage" the event, if necessary */ +//............................................................................ +// host callback function to "massage" the event, if necessary void QS_onTestEvt(QEvt *e) { Q_UNUSED_PAR(e); } -/*..........................................................................*/ -/*! callback function to output the posted QP events (not used here) */ +//............................................................................ +//! callback function to output the posted QP events (not used here) void QS_onTestPost(void const *sender, QActive *recipient, QEvt const *e, bool status) { diff --git a/examples/qutest/start_seq/test/test_tm4c123-arm.uvoptx b/examples/qutest/start_seq/test/test_tm4c123-arm.uvoptx index a694dc4a..5f5c9904 100644 --- a/examples/qutest/start_seq/test/test_tm4c123-arm.uvoptx +++ b/examples/qutest/start_seq/test/test_tm4c123-arm.uvoptx @@ -295,7 +295,7 @@ 0 0 0 - ..\..\..\..\include\qstamp.c + ..\..\..\..\src\qs\qstamp.c qstamp.c 0 0 @@ -378,12 +378,12 @@ 3 - 12 + 16 1 0 0 0 - ..\..\..\..\src\qf\qf_act.c + ..\..\..\..\..\src\qf\qf_act.c qf_act.c 0 0 diff --git a/examples/qutest/start_seq/test/test_tm4c123-arm.uvprojx b/examples/qutest/start_seq/test/test_tm4c123-arm.uvprojx index 2482c93d..5165d07f 100644 --- a/examples/qutest/start_seq/test/test_tm4c123-arm.uvprojx +++ b/examples/qutest/start_seq/test/test_tm4c123-arm.uvprojx @@ -336,7 +336,6 @@ 0 - Q_SPY Q_UTEST __FPU_PRESENT .;..\src;..\..\..\..\include;..\..\..\..\src;..\..\..\..\ports\arm-cm\qutest;..\..\..\..\3rd_party\CMSIS\Include;..\..\..\..\3rd_party\ek-tm4c123gxl @@ -410,7 +409,7 @@ qstamp.c 1 - ..\..\..\..\include\qstamp.c + ..\..\..\..\src\qs\qstamp.c @@ -450,7 +449,7 @@ qf_act.c 1 - ..\..\..\..\src\qf\qf_act.c + ..\..\..\..\..\src\qf\qf_act.c qf_actq.c diff --git a/examples/qutest/start_seq/test/test_vc.vcxproj b/examples/qutest/start_seq/test/test_vc.vcxproj index 671614a1..1aefe986 100644 --- a/examples/qutest/start_seq/test/test_vc.vcxproj +++ b/examples/qutest/start_seq/test/test_vc.vcxproj @@ -34,17 +34,17 @@ - - + +
- + @@ -112,6 +112,7 @@ ProgramDatabase 4127 Default + stdc11 ws2_32.lib;%(AdditionalDependencies) @@ -140,6 +141,7 @@ Level4 ProgramDatabase 4127 + stdc11 %(AdditionalDependencies) @@ -168,6 +170,7 @@ Level4 ProgramDatabase 4127 + stdc11 ws2_32.lib;%(AdditionalDependencies) diff --git a/examples/qutest/start_seq/test/test_vc.vcxproj.filters b/examples/qutest/start_seq/test/test_vc.vcxproj.filters index 0b3e7b1b..87d29ea9 100644 --- a/examples/qutest/start_seq/test/test_vc.vcxproj.filters +++ b/examples/qutest/start_seq/test/test_vc.vcxproj.filters @@ -1,8 +1,6 @@  - - QP @@ -61,9 +59,10 @@ QP_port + + - QP_port @@ -77,6 +76,7 @@ QP_port + diff --git a/examples/qutest/unity_basic/src/ProductionCode.c b/examples/qutest/unity_basic/src/ProductionCode.c index db128e5b..e4ec7e06 100644 --- a/examples/qutest/unity_basic/src/ProductionCode.c +++ b/examples/qutest/unity_basic/src/ProductionCode.c @@ -2,18 +2,18 @@ #include "ProductionCode.h" int Counter = 0; -int NumbersToFind[9] = { 0, 34, 55, 66, 32, 11, 1, 77, 888 }; /* some obnoxious array to search that is 1-based indexing instead of 0. */ +int NumbersToFind[9] = { 0, 34, 55, 66, 32, 11, 1, 77, 888 }; // some obnoxious array to search that is 1-based indexing instead of 0. -/* This function is supposed to search through NumbersToFind and find a particular number. - * If it finds it, the index is returned. Otherwise 0 is returned which sorta makes sense since - * NumbersToFind is indexed from 1. Unfortunately it's broken - * (and should therefore be caught by our tests) */ +// This function is supposed to search through NumbersToFind and find a particular number. +// If it finds it, the index is returned. Otherwise 0 is returned which sorta makes sense since +// NumbersToFind is indexed from 1. Unfortunately it's broken +// (and should therefore be caught by our tests) int FindFunction_WhichIsBroken(int NumberToFind) { int i = 0; - while (i < 8) /* Notice I should have been in braces */ + while (i < 8) // Notice I should have been in braces i++; - if (NumbersToFind[i] == NumberToFind) /* Yikes! I'm getting run after the loop finishes instead of during it! */ + if (NumbersToFind[i] == NumberToFind) // Yikes! I'm getting run after the loop finishes instead of during it! return i; return 0; } diff --git a/examples/qutest/unity_basic/test/Makefile b/examples/qutest/unity_basic/test/Makefile index f072ac4d..bf65deff 100644 --- a/examples/qutest/unity_basic/test/Makefile +++ b/examples/qutest/unity_basic/test/Makefile @@ -217,7 +217,7 @@ all : $(TARGET_EXE) run endif $(TARGET_EXE) : $(C_OBJS_EXT) $(CPP_OBJS_EXT) - $(CC) $(CFLAGS) $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o + $(CC) $(CFLAGS) $(QPC)/src/qs/qstamp.c -o $(BIN_DIR)/qstamp.o $(LINK) $(LINKFLAGS) $(LIB_DIRS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) run : $(TARGET_EXE) diff --git a/examples/qutest/unity_basic/test/make_efm32 b/examples/qutest/unity_basic/test/make_efm32 index 379c6b45..9549fd5c 100644 --- a/examples/qutest/unity_basic/test/make_efm32 +++ b/examples/qutest/unity_basic/test/make_efm32 @@ -252,7 +252,7 @@ $(TARGET_BIN) : $(TARGET_ELF) $(FLASH) $@ $(TARGET_ELF) : $(ASM_OBJS_EXT) $(C_OBJS_EXT) $(CPP_OBJS_EXT) - $(CC) $(CFLAGS) $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o + $(CC) $(CFLAGS) $(QPC)/src/qs/qstamp.c -o $(BIN_DIR)/qstamp.o $(LINK) $(LINKFLAGS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) flash : diff --git a/examples/qutest/unity_basic/test/make_tm4c123 b/examples/qutest/unity_basic/test/make_tm4c123 index 5c061cbe..cd3741c5 100644 --- a/examples/qutest/unity_basic/test/make_tm4c123 +++ b/examples/qutest/unity_basic/test/make_tm4c123 @@ -253,7 +253,7 @@ $(TARGET_BIN) : $(TARGET_ELF) @pause $(TARGET_ELF) : $(ASM_OBJS_EXT) $(C_OBJS_EXT) $(CPP_OBJS_EXT) - $(CC) $(CFLAGS) $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o + $(CC) $(CFLAGS) $(QPC)/src/qs/qstamp.c -o $(BIN_DIR)/qstamp.o $(LINK) $(LINKFLAGS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) flash : diff --git a/examples/qutest/unity_basic/test/test_ProductionCode.c b/examples/qutest/unity_basic/test/test_ProductionCode.c index aed9f6e5..afc7c186 100644 --- a/examples/qutest/unity_basic/test/test_ProductionCode.c +++ b/examples/qutest/unity_basic/test/test_ProductionCode.c @@ -1,92 +1,94 @@ -/***************************************************************************** -* Purpose: example QUTEST fixture for the basic example from Unity -* Last Updated for Version: 7.2.0 -* Date of the Last Update: 2022-11-30 -* -* Q u a n t u m L e a P s -* ------------------------ -* Modern Embedded Software -* -* Copyright (C) 2005-2018 Quantum Leaps, LLC. All rights reserved. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* -* -*****************************************************************************/ -#include "qpc.h" /* QUTest interface */ -#include "ProductionCode.h" /* CUT interface */ +//============================================================================ +// Purpose: example QUTEST fixture for the basic example from Unity +// Last Updated for Version: 7.3.0 +// Date of the Last Update: 2023-05-25 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005-2018 Quantum Leaps, LLC. All rights reserved. +// +// This program is open source software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Alternatively, this program may be distributed and modified under the +// terms of Quantum Leaps commercial licenses, which expressly supersede +// the GNU General Public License and are specifically designed for +// licensees interested in retaining the proprietary status of their code. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Contact information: +// +// +//============================================================================ +#include "qpc.h" // QUTest interface +#include "ProductionCode.h" // CUT interface Q_DEFINE_THIS_FILE -/*--------------------------------------------------------------------------*/ +//---------------------------------------------------------------------------- // sometimes you may want to get at local data in a module. // for example: If you plan to pass by reference, this could be useful // however, it should often be avoided extern int Counter; -/*--------------------------------------------------------------------------*/ +//---------------------------------------------------------------------------- int main(int argc, char *argv[]) { - QF_init(); /* initialize the framework */ + QF_init(); // initialize the framework - /* initialize the QS software tracing */ - Q_ALLEGE(QS_INIT(argc > 1 ? argv[1] : (void *)0)); + // initialize the QS software tracing + if (QS_INIT((argc > 1) ? argv[1] : (void *)0) == 0U) { + Q_ERROR(); + } - /* dictionaries... */ + // dictionaries... QS_FUN_DICTIONARY(&FindFunction_WhichIsBroken); QS_FUN_DICTIONARY(&FunctionWhichReturnsLocalVariable); QS_OBJ_DICTIONARY(&Counter); - /* filter setup... */ + // filter setup... QS_GLB_FILTER(QS_ALL_RECORDS); - return QF_run(); /* run the tests */ + return QF_run(); // run the tests } -/*--------------------------------------------------------------------------*/ +//---------------------------------------------------------------------------- void QS_onTestSetup(void) { } -/*..........................................................................*/ +//............................................................................ void QS_onTestTeardown(void) { } -/*..........................................................................*/ +//............................................................................ void QS_onCommand(uint8_t cmdId, uint32_t param1, uint32_t param2, uint32_t param3) { switch (cmdId) { - case 0: { /* call the CUT: FindFunction_WhichIsBroken */ + case 0: { // call the CUT: FindFunction_WhichIsBroken int ret = FindFunction_WhichIsBroken((int)param1); - QS_BEGIN_ID(QS_USER + cmdId, 0U) /* app-specific record */ - QS_FUN(&FindFunction_WhichIsBroken); /* function called */ - QS_I32(0, (int32_t)ret); /* returned value */ - QS_I16(0, (int16_t)param1); /* parameter */ + QS_BEGIN_ID(QS_USER + cmdId, 0U) // app-specific record + QS_FUN(&FindFunction_WhichIsBroken); // function called + QS_I32(0, (int32_t)ret); // returned value + QS_I16(0, (int16_t)param1); // parameter QS_END() break; } - case 1: { /* call the CUT: FunctionWhichReturnsLocalVariable */ + case 1: { // call the CUT: FunctionWhichReturnsLocalVariable int ret = FunctionWhichReturnsLocalVariable(); - QS_BEGIN_ID(QS_USER + cmdId, 0U) /* app-specific record */ - QS_FUN(&FunctionWhichReturnsLocalVariable); /* function called */ - QS_U32(QS_HEX_FMT, (uint32_t)ret); /* returned value */ + QS_BEGIN_ID(QS_USER + cmdId, 0U) // app-specific record + QS_FUN(&FunctionWhichReturnsLocalVariable); // function called + QS_U32(QS_HEX_FMT, (uint32_t)ret); // returned value QS_END() break; } @@ -94,21 +96,21 @@ void QS_onCommand(uint8_t cmdId, break; } - /* unused parameters... */ + // unused parameters... //Q_UNUSED_PAR(param1); Q_UNUSED_PAR(param2); Q_UNUSED_PAR(param3); } -/*..........................................................................*/ -/* host callback function to "massage" the event, if necessary */ +//............................................................................ +// host callback function to "massage" the event, if necessary void QS_onTestEvt(QEvt *e) { (void)e; -#ifdef Q_HOST /* is this test compiled for a desktop Host computer? */ -#else /* this test is compiled for an embedded Target system */ +#ifdef Q_HOST // is this test compiled for a desktop Host computer? +#else // this test is compiled for an embedded Target system #endif } -/*..........................................................................*/ -/*! callback function to output the posted QP events (not used here) */ +//............................................................................ +//! callback function to output the posted QP events (not used here) void QS_onTestPost(void const *sender, QActive *recipient, QEvt const *e, bool status) { diff --git a/examples/qutest/unity_basic/test_unity/TestProductionCode.c b/examples/qutest/unity_basic/test_unity/TestProductionCode.c index 404c3718..7bfc427a 100644 --- a/examples/qutest/unity_basic/test_unity/TestProductionCode.c +++ b/examples/qutest/unity_basic/test_unity/TestProductionCode.c @@ -2,14 +2,14 @@ #include "ProductionCode.h" #include "unity.h" -/* sometimes you may want to get at local data in a module. - * for example: If you plan to pass by reference, this could be useful - * however, it should often be avoided */ +// sometimes you may want to get at local data in a module. +// for example: If you plan to pass by reference, this could be useful +// however, it should often be avoided extern int Counter; void setUp(void) { - /* This is run before EACH TEST */ + // This is run before EACH TEST Counter = 0x5a5a; } @@ -19,7 +19,7 @@ void tearDown(void) void test_FindFunction_WhichIsBroken_ShouldReturnZeroIfItemIsNotInList_WhichWorksEvenInOurBrokenCode(void) { - /* All of these should pass */ + // All of these should pass TEST_ASSERT_EQUAL(0, FindFunction_WhichIsBroken(78)); TEST_ASSERT_EQUAL(0, FindFunction_WhichIsBroken(2)); TEST_ASSERT_EQUAL(0, FindFunction_WhichIsBroken(33)); @@ -29,34 +29,34 @@ void test_FindFunction_WhichIsBroken_ShouldReturnZeroIfItemIsNotInList_WhichWork void test_FindFunction_WhichIsBroken_ShouldReturnTheIndexForItemsInList_WhichWillFailBecauseOurFunctionUnderTestIsBroken(void) { - /* You should see this line fail in your test summary */ + // You should see this line fail in your test summary TEST_ASSERT_EQUAL(1, FindFunction_WhichIsBroken(34)); - /* Notice the rest of these didn't get a chance to run because the line above failed. - * Unit tests abort each test function on the first sign of trouble. - * Then NEXT test function runs as normal. */ + // Notice the rest of these didn't get a chance to run because the line above failed. + // Unit tests abort each test function on the first sign of trouble. + // Then NEXT test function runs as normal. TEST_ASSERT_EQUAL(8, FindFunction_WhichIsBroken(8888)); } void test_FunctionWhichReturnsLocalVariable_ShouldReturnTheCurrentCounterValue(void) { - /* This should be true because setUp set this up for us before this test */ + // This should be true because setUp set this up for us before this test TEST_ASSERT_EQUAL_HEX(0x5a5a, FunctionWhichReturnsLocalVariable()); - /* This should be true because we can still change our answer */ + // This should be true because we can still change our answer Counter = 0x1234; TEST_ASSERT_EQUAL_HEX(0x1234, FunctionWhichReturnsLocalVariable()); } void test_FunctionWhichReturnsLocalVariable_ShouldReturnTheCurrentCounterValueAgain(void) { - /* This should be true again because setup was rerun before this test (and after we changed it to 0x1234) */ + // This should be true again because setup was rerun before this test (and after we changed it to 0x1234) TEST_ASSERT_EQUAL_HEX(0x5a5a, FunctionWhichReturnsLocalVariable()); } void test_FunctionWhichReturnsLocalVariable_ShouldReturnCurrentCounter_ButFailsBecauseThisTestIsActuallyFlawed(void) { - /* Sometimes you get the test wrong. When that happens, you get a failure too... and a quick look should tell - * you what actually happened...which in this case was a failure to setup the initial condition. */ + // Sometimes you get the test wrong. When that happens, you get a failure too... and a quick look should tell + // you what actually happened...which in this case was a failure to setup the initial condition. TEST_ASSERT_EQUAL_HEX(0x1234, FunctionWhichReturnsLocalVariable()); } diff --git a/examples/qutest/unity_basic/test_unity/TestProductionCode_Runner.c b/examples/qutest/unity_basic/test_unity/TestProductionCode_Runner.c index 3b49af74..48f9796d 100644 --- a/examples/qutest/unity_basic/test_unity/TestProductionCode_Runner.c +++ b/examples/qutest/unity_basic/test_unity/TestProductionCode_Runner.c @@ -1,6 +1,6 @@ -/* AUTOGENERATED FILE. DO NOT EDIT. */ +// AUTOGENERATED FILE. DO NOT EDIT. -/*=======Test Runner Used To Run Each Test Below=====*/ +//=======Test Runner Used To Run Each Test Below===== #define RUN_TEST(TestFunc, TestLineNum) \ { \ Unity.CurrentTestName = #TestFunc; \ @@ -18,13 +18,13 @@ UnityConcludeTest(); \ } -/*=======Automagically Detected Files To Include=====*/ +//=======Automagically Detected Files To Include===== #include "unity.h" #include #include #include "ProductionCode.h" -/*=======External Functions This Runner Calls=====*/ +//=======External Functions This Runner Calls===== extern void setUp(void); extern void tearDown(void); extern void test_FindFunction_WhichIsBroken_ShouldReturnZeroIfItemIsNotInList_WhichWorksEvenInOurBrokenCode(void); @@ -34,7 +34,7 @@ extern void test_FunctionWhichReturnsLocalVariable_ShouldReturnTheCurrentCounter extern void test_FunctionWhichReturnsLocalVariable_ShouldReturnCurrentCounter_ButFailsBecauseThisTestIsActuallyFlawed(void); -/*=======Test Reset Option=====*/ +//=======Test Reset Option===== void resetTest(void); void resetTest(void) { @@ -43,7 +43,7 @@ void resetTest(void) } -/*=======MAIN=====*/ +//=======MAIN===== int main(void) { UnityBegin("test/TestProductionCode.c"); diff --git a/examples/qutest/unity_ledbar/printf/Makefile b/examples/qutest/unity_ledbar/printf/Makefile index c16ba233..c22aca96 100644 --- a/examples/qutest/unity_ledbar/printf/Makefile +++ b/examples/qutest/unity_ledbar/printf/Makefile @@ -175,7 +175,7 @@ all: $(TARGET_EXE) $(TARGET_EXE) $(TARGET_EXE) : $(C_OBJS_EXT) $(CPP_OBJS_EXT) - $(CC) $(CFLAGS) $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o + $(CC) $(CFLAGS) $(QPC)/src/qs/qstamp.c -o $(BIN_DIR)/qstamp.o $(LINK) $(LINKFLAGS) $(LIB_DIRS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) $(BIN_DIR)/%.d : %.c diff --git a/examples/qutest/unity_ledbar/printf/printf_LedBar.c b/examples/qutest/unity_ledbar/printf/printf_LedBar.c index ff98e7e0..74e2dbda 100644 --- a/examples/qutest/unity_ledbar/printf/printf_LedBar.c +++ b/examples/qutest/unity_ledbar/printf/printf_LedBar.c @@ -1,18 +1,18 @@ #include -#include /* for printf() */ +#include // for printf() -#include "LedBar.h" /* CUT interface */ +#include "LedBar.h" // CUT interface -/*--------------------------------------------------------------------------*/ +//---------------------------------------------------------------------------- static void trace_LedBar_percent(uint8_t percent) { uint32_t ret = LedBar_setPercent(percent); printf("LedBar_setPercent %d %d\n", ret, percent); } -/*--------------------------------------------------------------------------*/ +//---------------------------------------------------------------------------- int main(int argc, char *argv[]) { - (void)argc; /* unused parameter */ - (void)argv; /* unused parameter */ + (void)argc; // unused parameter + (void)argv; // unused parameter trace_LedBar_percent(100U); trace_LedBar_percent(19U); @@ -23,10 +23,15 @@ int main(int argc, char *argv[]) { return 0; } -/*..........................................................................*/ -#include /* for exit() */ +//............................................................................ +#include // for exit() -void Q_onAssert(char const * const module, int const loc) { - printf("Assertion in %s:%d\n", module, loc); +Q_NORETURN Q_onError(char const * const module, int_t const id) { + printf("ERROR in %s:%d\n", module, id); exit(-1); } +//............................................................................ +void assert_failed(char const * const module, int_t const id); // prototype +void assert_failed(char const * const module, int_t const id) { + Q_onError(module, id); +} diff --git a/examples/qutest/unity_ledbar/printf/spy_Led.c b/examples/qutest/unity_ledbar/printf/spy_Led.c index e6aee5c4..2961a5e3 100644 --- a/examples/qutest/unity_ledbar/printf/spy_Led.c +++ b/examples/qutest/unity_ledbar/printf/spy_Led.c @@ -1,19 +1,19 @@ #include -#include /* for printf() */ +#include // for printf() -#include "Led.h" /* original interface */ +#include "Led.h" // original interface static uint32_t led_power[MAX_LED] = { 10, 20, 10, 20, 10 }; -/*--------------------------------------------------------------------------*/ -/* turns a given LED off */ +//---------------------------------------------------------------------------- +// turns a given LED off void Led_off(uint8_t index) { printf("Led_off %d\n", index); } -/* turns a given LED on and retruns the power drawn by it in [uW] */ +// turns a given LED on and retruns the power drawn by it in [uW] uint32_t Led_on(uint8_t index) { uint32_t ret = led_power[index]; printf("Led_on %d %d\n", ret, index); diff --git a/examples/qutest/unity_ledbar/qutest/Makefile b/examples/qutest/unity_ledbar/qutest/Makefile index 8e90fdb8..0dcd0e76 100644 --- a/examples/qutest/unity_ledbar/qutest/Makefile +++ b/examples/qutest/unity_ledbar/qutest/Makefile @@ -218,7 +218,7 @@ all : $(TARGET_EXE) run endif $(TARGET_EXE) : $(C_OBJS_EXT) $(CPP_OBJS_EXT) - $(CC) $(CFLAGS) $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o + $(CC) $(CFLAGS) $(QPC)/src/qs/qstamp.c -o $(BIN_DIR)/qstamp.o $(LINK) $(LINKFLAGS) $(LIB_DIRS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) run : $(TARGET_EXE) diff --git a/examples/qutest/unity_ledbar/qutest/make_efm32 b/examples/qutest/unity_ledbar/qutest/make_efm32 index 44286f87..68f5f07a 100644 --- a/examples/qutest/unity_ledbar/qutest/make_efm32 +++ b/examples/qutest/unity_ledbar/qutest/make_efm32 @@ -253,7 +253,7 @@ $(TARGET_BIN) : $(TARGET_ELF) $(FLASH) $@ $(TARGET_ELF) : $(ASM_OBJS_EXT) $(C_OBJS_EXT) $(CPP_OBJS_EXT) - $(CC) $(CFLAGS) $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o + $(CC) $(CFLAGS) $(QPC)/src/qs/qstamp.c -o $(BIN_DIR)/qstamp.o $(LINK) $(LINKFLAGS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) flash : diff --git a/examples/qutest/unity_ledbar/qutest/make_nucleo-l053r8 b/examples/qutest/unity_ledbar/qutest/make_nucleo-l053r8 index 33071842..21c726d3 100644 --- a/examples/qutest/unity_ledbar/qutest/make_nucleo-l053r8 +++ b/examples/qutest/unity_ledbar/qutest/make_nucleo-l053r8 @@ -253,7 +253,7 @@ $(TARGET_BIN) : $(TARGET_ELF) $(SLEEP) 2 $(TARGET_ELF) : $(ASM_OBJS_EXT) $(C_OBJS_EXT) $(CPP_OBJS_EXT) - $(CC) $(CFLAGS) $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o + $(CC) $(CFLAGS) $(QPC)/src/qs/qstamp.c -o $(BIN_DIR)/qstamp.o $(LINK) $(LINKFLAGS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) flash : diff --git a/examples/qutest/unity_ledbar/qutest/make_tm4c123 b/examples/qutest/unity_ledbar/qutest/make_tm4c123 index a40b29dc..ff931a39 100644 --- a/examples/qutest/unity_ledbar/qutest/make_tm4c123 +++ b/examples/qutest/unity_ledbar/qutest/make_tm4c123 @@ -254,7 +254,7 @@ $(TARGET_BIN) : $(TARGET_ELF) @pause $(TARGET_ELF) : $(ASM_OBJS_EXT) $(C_OBJS_EXT) $(CPP_OBJS_EXT) - $(CC) $(CFLAGS) $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o + $(CC) $(CFLAGS) $(QPC)/src/qs/qstamp.c -o $(BIN_DIR)/qstamp.o $(LINK) $(LINKFLAGS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) flash : diff --git a/examples/qutest/unity_ledbar/qutest/spy_led.c b/examples/qutest/unity_ledbar/qutest/spy_led.c index 44f007a5..ae7cc3d6 100644 --- a/examples/qutest/unity_ledbar/qutest/spy_led.c +++ b/examples/qutest/unity_ledbar/qutest/spy_led.c @@ -1,13 +1,13 @@ -#include "qpc.h" /* QP/Spy */ -#include "Led.h" /* original interface */ +#include "qpc.h" // QP/Spy +#include "Led.h" // original interface static uint32_t led_power[MAX_LED] = { 10, 20, 10, 20, 10 }; -/*--------------------------------------------------------------------------*/ +//---------------------------------------------------------------------------- enum { - LED_MOD = QS_USER1 /* QS app-specific record for the LED module */ + LED_MOD = QS_USER1 // QS app-specific record for the LED module }; void Led_DICTIONARY(void) { @@ -17,24 +17,24 @@ void Led_DICTIONARY(void) { QS_OBJ_DICTIONARY(&led_power); } -/*--------------------------------------------------------------------------*/ -/* turns a given LED off */ +//---------------------------------------------------------------------------- +// turns a given LED off void Led_off(uint8_t index) { //printf("Led_off %d\n", index); - QS_BEGIN_ID(LED_MOD, 0U) /* app-specific record */ - QS_FUN(&Led_off); /* function called */ - QS_U8 (0, index); /* parameter */ + QS_BEGIN_ID(LED_MOD, 0U) // app-specific record + QS_FUN(&Led_off); // function called + QS_U8 (0, index); // parameter QS_END() } -/* turns a given LED on and retruns the power drawn by it in [uW] */ +// turns a given LED on and retruns the power drawn by it in [uW] uint32_t Led_on(uint8_t index) { - uint32_t ret = led_power[index]; /* assume */ + uint32_t ret = led_power[index]; // assume //printf("Led_on %d %d\n", ret, index); - QS_BEGIN_ID(LED_MOD, 0U) /* app-specific record */ - QS_FUN(&Led_on); /* function called */ - QS_U32(0, ret); /* value returned */ - QS_U8 (0, index); /* parameter */ + QS_BEGIN_ID(LED_MOD, 0U) // app-specific record + QS_FUN(&Led_on); // function called + QS_U32(0, ret); // value returned + QS_U8 (0, index); // parameter QS_END() return ret; diff --git a/examples/qutest/unity_ledbar/qutest/test_ledbar.c b/examples/qutest/unity_ledbar/qutest/test_ledbar.c index f412e564..f7c31d6c 100644 --- a/examples/qutest/unity_ledbar/qutest/test_ledbar.c +++ b/examples/qutest/unity_ledbar/qutest/test_ledbar.c @@ -1,47 +1,49 @@ -#include "qpc.h" /* QUTest interface */ -#include "LedBar.h" /* CUT interface */ +#include "qpc.h" // QUTest interface +#include "LedBar.h" // CUT interface Q_DEFINE_THIS_FILE -/*--------------------------------------------------------------------------*/ -void Led_DICTIONARY(void); /* dictionaries for the Led "spy " test double */ +//---------------------------------------------------------------------------- +void Led_DICTIONARY(void); // dictionaries for the Led "spy " test double -/*--------------------------------------------------------------------------*/ +//---------------------------------------------------------------------------- int main(int argc, char *argv[]) { - QF_init(); /* initialize the framework */ + QF_init(); // initialize the framework - /* initialize the QS software tracing */ - Q_ALLEGE(QS_INIT(argc > 1 ? argv[1] : (void *)0)); + // initialize the QS software tracing + if (QS_INIT((argc > 1) ? argv[1] : (void *)0) == 0U) { + Q_ERROR(); + } - /* dictionaries... */ + // dictionaries... Led_DICTIONARY(); QS_FUN_DICTIONARY(&LedBar_setPercent); - /* filter setup... */ + // filter setup... QS_GLB_FILTER(QS_ALL_RECORDS); - return QF_run(); /* run the tests */ + return QF_run(); // run the tests } -/*--------------------------------------------------------------------------*/ +//---------------------------------------------------------------------------- void QS_onTestSetup(void) { } -/*..........................................................................*/ +//............................................................................ void QS_onTestTeardown(void) { } -/*..........................................................................*/ +//............................................................................ void QS_onCommand(uint8_t cmdId, uint32_t param1, uint32_t param2, uint32_t param3) { switch (cmdId) { - case 0: { /* call LedBar_setPercent()... */ + case 0: { // call LedBar_setPercent()... uint32_t ret = LedBar_setPercent((uint8_t)param1); - QS_BEGIN_ID(QS_USER + cmdId, 0U) /* app-specific record */ - QS_FUN(&LedBar_setPercent); /* function called */ - QS_U32(0, ret); /* value returned */ - QS_U8 (0, (uint8_t)param1); /* parameter */ + QS_BEGIN_ID(QS_USER + cmdId, 0U) // app-specific record + QS_FUN(&LedBar_setPercent); // function called + QS_U32(0, ret); // value returned + QS_U8 (0, (uint8_t)param1); // parameter QS_END() break; } @@ -49,20 +51,20 @@ void QS_onCommand(uint8_t cmdId, break; } - /* unused parametrers... */ + // unused parametrers... (void)param2; (void)param3; } -/*..........................................................................*/ -/* host callback function to "massage" the event, if necessary */ +//............................................................................ +// host callback function to "massage" the event, if necessary void QS_onTestEvt(QEvt *e) { (void)e; -#ifdef Q_HOST /* is this test compiled for a desktop Host computer? */ -#else /* this test is compiled for an embedded Target system */ +#ifdef Q_HOST // is this test compiled for a desktop Host computer? +#else // this test is compiled for an embedded Target system #endif } -/*..........................................................................*/ -/*! callback function to output the posted QP events (not used here) */ +//............................................................................ +//! callback function to output the posted QP events (not used here) void QS_onTestPost(void const *sender, QActive *recipient, QEvt const *e, bool status) { diff --git a/examples/qutest/unity_ledbar/src/Led.h b/examples/qutest/unity_ledbar/src/Led.h index 246c36a9..a272854b 100644 --- a/examples/qutest/unity_ledbar/src/Led.h +++ b/examples/qutest/unity_ledbar/src/Led.h @@ -3,10 +3,10 @@ enum { MAX_LED = 5 }; -/* turns a given LED on and retruns the power drawn by it in uW */ +// turns a given LED on and retruns the power drawn by it in uW uint32_t Led_on(uint8_t index); -/* turns a given LED off */ +// turns a given LED off void Led_off(uint8_t index); -#endif /* LED_H */ \ No newline at end of file +#endif // LED_H diff --git a/examples/qutest/unity_ledbar/src/LedBar.c b/examples/qutest/unity_ledbar/src/LedBar.c index 7dc6fe2b..2877d4e1 100644 --- a/examples/qutest/unity_ledbar/src/LedBar.c +++ b/examples/qutest/unity_ledbar/src/LedBar.c @@ -2,42 +2,42 @@ #include "LedBar.h" #include "Led.h" -#include "qassert.h" /* for embedded systems-friendly assertions */ +#include "qsafe.h" // QP Functional Safety (FuSa) System Q_DEFINE_THIS_MODULE("LedBar") -/* - Example sequence diagram for the LedBar_setPercent() implementation: - - +----------+ +-----+ - | LedBar | | LED | - +----------+ +-----+ - | | - +-+ Led_on(0) | - | |------------->| - | | | - | | Led_on(1) | - | |------------->| - | | | - | | Led_on(2) | - | |------------->| - | | | - | | Led_off(3) | - | |------------->| - | | | - | | Led_off(4) | - | |------------->| - | | | - +-+ | - | | -*/ +// +// Example sequence diagram for the LedBar_setPercent() implementation: +// +// +----------+ +-----+ +// | LedBar | | LED | +// +----------+ +-----+ +// | | +// +-+ Led_on(0) | +// | |------------->| +// | | | +// | | Led_on(1) | +// | |------------->| +// | | | +// | | Led_on(2) | +// | |------------->| +// | | | +// | | Led_off(3) | +// | |------------->| +// | | | +// | | Led_off(4) | +// | |------------->| +// | | | +// +-+ | +// | | +// uint32_t LedBar_setPercent(uint8_t const percent) { uint8_t const n_on = (uint8_t)((percent * MAX_LED) / 100U); - /*! @pre percent must not exceed 100 */ + //! @pre percent must not exceed 100 Q_REQUIRE_ID(100, n_on <= MAX_LED); - uint32_t p = 0U; /* power draw in [uW] */ + uint32_t p = 0U; // power draw in [uW] uint8_t i; for (i = 0U; i < n_on; ++i) { p += Led_on(i); diff --git a/examples/qutest/unity_ledbar/src/LedBar.h b/examples/qutest/unity_ledbar/src/LedBar.h index 249daab7..62bdc268 100644 --- a/examples/qutest/unity_ledbar/src/LedBar.h +++ b/examples/qutest/unity_ledbar/src/LedBar.h @@ -1,9 +1,9 @@ #ifndef LEDBAR_H #define LEDBAR_H -/* displays the percentage on the LED bar -* and returns the total power drawn by the LEDs in uW. -*/ +// displays the percentage on the LED bar +// and returns the total power drawn by the LEDs in uW. +// uint32_t LedBar_setPercent(uint8_t percent); -#endif /* LEDBAR_H */ \ No newline at end of file +#endif // LEDBAR_H diff --git a/examples/qutest/unity_ledbar/test/TestLedBar.c b/examples/qutest/unity_ledbar/test/TestLedBar.c index 533a1e69..74e86d5f 100644 --- a/examples/qutest/unity_ledbar/test/TestLedBar.c +++ b/examples/qutest/unity_ledbar/test/TestLedBar.c @@ -4,11 +4,11 @@ #include "MockLed.h" void setUp(void) { - /* This is run before EACH TEST */ + // This is run before EACH TEST } void tearDown(void) { - /* This is run after EACH TEST */ + // This is run after EACH TEST } void test_LedBar_0_percent_all_off(void) { @@ -32,10 +32,10 @@ void test_LedBar_100_percent_all_on(void) { } void test_LedBar_200_percent_ASSERT(void) { - /* NOTE: Here we EXPECT breaking the internal assertion inside CUT. - * But Unity does not provide a mechanism to verify that and - * to PASS the test, so this test will FAIL... - */ + // NOTE: Here we EXPECT breaking the internal assertion inside CUT. + // But Unity does not provide a mechanism to verify that and + // to PASS the test, so this test will FAIL... + // TEST_ASSERT(LedBar_setPercent(200U)); } @@ -79,14 +79,21 @@ void test_LedBar_99_percent_four_on(void) { TEST_ASSERT_EQUAL(60U, LedBar_setPercent(99U)); } -/* assertion handler... */ -void Q_onAssert(char const * const module, int const loc) { - (void)module; - UNITY_TEST_FAIL(loc, "ASSERTION"); +// error handler... +Q_NORETURN Q_onError(char const * const module, int_t const id) { + Q_UNUSED_PAR(module); + Q_UNUSED_PAR(id); + + UNITY_TEST_FAIL(loc, "ERROR"); +} +//............................................................................ +void assert_failed(char const * const module, int_t const id); // prototype +void assert_failed(char const * const module, int_t const id) { + Q_onError(module, id); } -/* NOTE: -* The Mock example requires a specific "test runner", which -* is provided in the file TestLedBar_Runner.c. -*/ +// NOTE: +// The Mock example requires a specific "test runner", which +// is provided in the file TestLedBar_Runner.c. +// diff --git a/examples/qutest/unity_ledbar/test/TestLedBar_Runner.c b/examples/qutest/unity_ledbar/test/TestLedBar_Runner.c index 5d8eadf6..02db23d0 100644 --- a/examples/qutest/unity_ledbar/test/TestLedBar_Runner.c +++ b/examples/qutest/unity_ledbar/test/TestLedBar_Runner.c @@ -1,13 +1,13 @@ -/* AUTOGENERATED FILE. DO NOT EDIT. */ +// AUTOGENERATED FILE. DO NOT EDIT. -/*=======Automagically Detected Files To Include=====*/ +//=======Automagically Detected Files To Include===== #include "unity.h" #include "cmock.h" #include "LedBar.h" #include #include "MockLed.h" -/*=======External Functions This Runner Calls=====*/ +//=======External Functions This Runner Calls===== extern void setUp(void); extern void tearDown(void); extern void test_LedBar_0_percent_all_off(void); @@ -19,7 +19,7 @@ extern void test_LedBar_50_percent_two_on(void); extern void test_LedBar_99_percent_four_on(void); -/*=======Mock Management=====*/ +//=======Mock Management===== static void CMock_Init(void) { MockLed_Init(); @@ -33,7 +33,7 @@ static void CMock_Destroy(void) MockLed_Destroy(); } -/*=======Test Reset Options=====*/ +//=======Test Reset Options===== void resetTest(void); void resetTest(void) { @@ -49,7 +49,7 @@ void verifyTest(void) CMock_Verify(); } -/*=======Test Runner Used To Run Each Test=====*/ +//=======Test Runner Used To Run Each Test===== static void run_test(UnityTestFunction func, const char* name, UNITY_LINE_TYPE line_num) { Unity.CurrentTestName = name; @@ -77,7 +77,7 @@ static void run_test(UnityTestFunction func, const char* name, UNITY_LINE_TYPE l UnityConcludeTest(); } -/*=======MAIN=====*/ +//=======MAIN===== int main(void) { UnityBegin("TestLedBar.c"); diff --git a/examples/qutest/unity_ledbar/test/mocks/MockLed.c b/examples/qutest/unity_ledbar/test/mocks/MockLed.c index 1d5e146d..bafd4639 100644 --- a/examples/qutest/unity_ledbar/test/mocks/MockLed.c +++ b/examples/qutest/unity_ledbar/test/mocks/MockLed.c @@ -1,4 +1,4 @@ -/* AUTOGENERATED FILE. DO NOT EDIT. */ +// AUTOGENERATED FILE. DO NOT EDIT. #include #include #include diff --git a/examples/qutest/unity_ledbar/test/mocks/MockLed.h b/examples/qutest/unity_ledbar/test/mocks/MockLed.h index 49491f12..7725dbed 100644 --- a/examples/qutest/unity_ledbar/test/mocks/MockLed.h +++ b/examples/qutest/unity_ledbar/test/mocks/MockLed.h @@ -1,11 +1,11 @@ -/* AUTOGENERATED FILE. DO NOT EDIT. */ +// AUTOGENERATED FILE. DO NOT EDIT. #ifndef _MOCKLED_H #define _MOCKLED_H #include "unity.h" #include "Led.h" -/* Ignore the following warnings, since we are copying code */ +// Ignore the following warnings, since we are copying code #if defined(__GNUC__) && !defined(__ICC) && !defined(__TMS470__) #if __GNUC__ > 4 || (__GNUC__ == 4 && (__GNUC_MINOR__ > 6 || (__GNUC_MINOR__ == 6 && __GNUC_PATCHLEVEL__ > 0))) #pragma GCC diagnostic push diff --git a/examples/qutest/unity_ledbar/trace/Makefile b/examples/qutest/unity_ledbar/trace/Makefile index dc8df341..19276ded 100644 --- a/examples/qutest/unity_ledbar/trace/Makefile +++ b/examples/qutest/unity_ledbar/trace/Makefile @@ -252,7 +252,7 @@ all: $(TARGET_EXE) $(TARGET_EXE) $(TARGET_EXE) : $(C_OBJS_EXT) $(CPP_OBJS_EXT) - $(CC) $(CFLAGS) $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o + $(CC) $(CFLAGS) $(QPC)/src/qs/qstamp.c -o $(BIN_DIR)/qstamp.o $(LINK) $(LINKFLAGS) $(LIB_DIRS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) $(BIN_DIR)/%.d : %.c diff --git a/examples/qutest/unity_ledbar/trace/spy_Led.c b/examples/qutest/unity_ledbar/trace/spy_Led.c index 44f007a5..ae7cc3d6 100644 --- a/examples/qutest/unity_ledbar/trace/spy_Led.c +++ b/examples/qutest/unity_ledbar/trace/spy_Led.c @@ -1,13 +1,13 @@ -#include "qpc.h" /* QP/Spy */ -#include "Led.h" /* original interface */ +#include "qpc.h" // QP/Spy +#include "Led.h" // original interface static uint32_t led_power[MAX_LED] = { 10, 20, 10, 20, 10 }; -/*--------------------------------------------------------------------------*/ +//---------------------------------------------------------------------------- enum { - LED_MOD = QS_USER1 /* QS app-specific record for the LED module */ + LED_MOD = QS_USER1 // QS app-specific record for the LED module }; void Led_DICTIONARY(void) { @@ -17,24 +17,24 @@ void Led_DICTIONARY(void) { QS_OBJ_DICTIONARY(&led_power); } -/*--------------------------------------------------------------------------*/ -/* turns a given LED off */ +//---------------------------------------------------------------------------- +// turns a given LED off void Led_off(uint8_t index) { //printf("Led_off %d\n", index); - QS_BEGIN_ID(LED_MOD, 0U) /* app-specific record */ - QS_FUN(&Led_off); /* function called */ - QS_U8 (0, index); /* parameter */ + QS_BEGIN_ID(LED_MOD, 0U) // app-specific record + QS_FUN(&Led_off); // function called + QS_U8 (0, index); // parameter QS_END() } -/* turns a given LED on and retruns the power drawn by it in [uW] */ +// turns a given LED on and retruns the power drawn by it in [uW] uint32_t Led_on(uint8_t index) { - uint32_t ret = led_power[index]; /* assume */ + uint32_t ret = led_power[index]; // assume //printf("Led_on %d %d\n", ret, index); - QS_BEGIN_ID(LED_MOD, 0U) /* app-specific record */ - QS_FUN(&Led_on); /* function called */ - QS_U32(0, ret); /* value returned */ - QS_U8 (0, index); /* parameter */ + QS_BEGIN_ID(LED_MOD, 0U) // app-specific record + QS_FUN(&Led_on); // function called + QS_U32(0, ret); // value returned + QS_U8 (0, index); // parameter QS_END() return ret; diff --git a/examples/qutest/unity_ledbar/trace/trace_LedBar.c b/examples/qutest/unity_ledbar/trace/trace_LedBar.c index b82098ad..fb1ae2b7 100644 --- a/examples/qutest/unity_ledbar/trace/trace_LedBar.c +++ b/examples/qutest/unity_ledbar/trace/trace_LedBar.c @@ -1,35 +1,37 @@ -#include "qpc.h" /* QP/Spy */ -#include "LedBar.h" /* CUT interface */ +#include "qpc.h" // QP/Spy +#include "LedBar.h" // CUT interface Q_DEFINE_THIS_FILE -/*--------------------------------------------------------------------------*/ -void Led_DICTIONARY(void); /* dictionaries for the Led "spy " test double */ +//---------------------------------------------------------------------------- +void Led_DICTIONARY(void); // dictionaries for the Led "spy " test double static void trace_LedBar_percent(uint8_t percent) { uint32_t ret = LedBar_setPercent(percent); //printf("LedBar_setPercent %d %d\n", ret, percent); - QS_BEGIN_ID(QS_USER, 0U) /* app-specific record */ - QS_FUN(&LedBar_setPercent); /* function called */ - QS_U32(0, ret); /* value returned */ - QS_U8 (0, percent); /* parameter */ + QS_BEGIN_ID(QS_USER, 0U) // app-specific record + QS_FUN(&LedBar_setPercent); // function called + QS_U32(0, ret); // value returned + QS_U8 (0, percent); // parameter QS_END() - QS_FLUSH(); /* output trace buffer to the host */ + QS_FLUSH(); // output trace buffer to the host } -/*--------------------------------------------------------------------------*/ +//---------------------------------------------------------------------------- int main(int argc, char *argv[]) { - QF_init(); /* initialize the framework */ + QF_init(); // initialize the framework - /* initialize the QS software tracing */ - Q_ALLEGE(QS_INIT(argc > 1 ? argv[1] : (void *)0)); + // initialize the QS software tracing + if (QS_INIT((argc > 1) ? argv[1] : (void *)0) == 0U) { + Q_ERROR(); + } - /* produce dictionaries... */ + // produce dictionaries... Led_DICTIONARY(); QS_FUN_DICTIONARY(&LedBar_setPercent); - /* filter setup... */ + // filter setup... QS_GLB_FILTER(QS_ALL_RECORDS); trace_LedBar_percent(100U); @@ -42,33 +44,38 @@ int main(int argc, char *argv[]) { return 0; } -/*--------------------------------------------------------------------------*/ -/* callback functions for QP/Spy... */ +//---------------------------------------------------------------------------- +// callback functions for QP/Spy... void QS_onCommand(uint8_t cmdId, uint32_t param1, uint32_t param2, uint32_t param3) { - /* unused parametrers... */ + // unused parametrers... (void)cmdId; (void)param1; (void)param2; (void)param3; } -/*..........................................................................*/ +//............................................................................ void QF_onStartup(void) { } -/*..........................................................................*/ +//............................................................................ void QF_onCleanup(void) { } -/*..........................................................................*/ +//............................................................................ void QF_onClockTick(void) { } -/*..........................................................................*/ -#include /* for exit() */ +//............................................................................ +#include // for exit() -void Q_onAssert(char const * const module, int const loc) { - //printf("Assertion in %s:%d\n", module, loc); - QS_ASSERTION(module, loc, 1000U); /* report assertion to QS */ +Q_NORETURN Q_onError(char const * const module, int_t const id) { + //printf("ERROR in %s:%d\n", module, id); + QS_ASSERTION(module, id, 1000U); // report assertion to QS QF_onCleanup(); QS_EXIT(); exit(-1); } +//............................................................................ +void assert_failed(char const * const module, int_t const id); // prototype +void assert_failed(char const * const module, int_t const id) { + Q_onError(module, id); +} diff --git a/examples/qutest/unity_ledbar2/qutest/Makefile b/examples/qutest/unity_ledbar2/qutest/Makefile index 43f60f75..4f0fb263 100644 --- a/examples/qutest/unity_ledbar2/qutest/Makefile +++ b/examples/qutest/unity_ledbar2/qutest/Makefile @@ -219,7 +219,7 @@ all : $(TARGET_EXE) run endif $(TARGET_EXE) : $(C_OBJS_EXT) $(CPP_OBJS_EXT) - $(CC) $(CFLAGS) $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o + $(CC) $(CFLAGS) $(QPC)/src/qs/qstamp.c -o $(BIN_DIR)/qstamp.o $(LINK) $(LINKFLAGS) $(LIB_DIRS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) run : $(TARGET_EXE) diff --git a/examples/qutest/unity_ledbar2/qutest/make_nucleo-l053r8 b/examples/qutest/unity_ledbar2/qutest/make_nucleo-l053r8 index 8a1b075e..2e45d970 100644 --- a/examples/qutest/unity_ledbar2/qutest/make_nucleo-l053r8 +++ b/examples/qutest/unity_ledbar2/qutest/make_nucleo-l053r8 @@ -254,7 +254,7 @@ $(TARGET_BIN) : $(TARGET_ELF) $(SLEEP) 2 $(TARGET_ELF) : $(ASM_OBJS_EXT) $(C_OBJS_EXT) $(CPP_OBJS_EXT) - $(CC) $(CFLAGS) $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o + $(CC) $(CFLAGS) $(QPC)/src/qs/qstamp.c -o $(BIN_DIR)/qstamp.o $(LINK) $(LINKFLAGS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) flash : diff --git a/examples/qutest/unity_ledbar2/qutest/spy_led.c b/examples/qutest/unity_ledbar2/qutest/spy_led.c index 44f007a5..ae7cc3d6 100644 --- a/examples/qutest/unity_ledbar2/qutest/spy_led.c +++ b/examples/qutest/unity_ledbar2/qutest/spy_led.c @@ -1,13 +1,13 @@ -#include "qpc.h" /* QP/Spy */ -#include "Led.h" /* original interface */ +#include "qpc.h" // QP/Spy +#include "Led.h" // original interface static uint32_t led_power[MAX_LED] = { 10, 20, 10, 20, 10 }; -/*--------------------------------------------------------------------------*/ +//---------------------------------------------------------------------------- enum { - LED_MOD = QS_USER1 /* QS app-specific record for the LED module */ + LED_MOD = QS_USER1 // QS app-specific record for the LED module }; void Led_DICTIONARY(void) { @@ -17,24 +17,24 @@ void Led_DICTIONARY(void) { QS_OBJ_DICTIONARY(&led_power); } -/*--------------------------------------------------------------------------*/ -/* turns a given LED off */ +//---------------------------------------------------------------------------- +// turns a given LED off void Led_off(uint8_t index) { //printf("Led_off %d\n", index); - QS_BEGIN_ID(LED_MOD, 0U) /* app-specific record */ - QS_FUN(&Led_off); /* function called */ - QS_U8 (0, index); /* parameter */ + QS_BEGIN_ID(LED_MOD, 0U) // app-specific record + QS_FUN(&Led_off); // function called + QS_U8 (0, index); // parameter QS_END() } -/* turns a given LED on and retruns the power drawn by it in [uW] */ +// turns a given LED on and retruns the power drawn by it in [uW] uint32_t Led_on(uint8_t index) { - uint32_t ret = led_power[index]; /* assume */ + uint32_t ret = led_power[index]; // assume //printf("Led_on %d %d\n", ret, index); - QS_BEGIN_ID(LED_MOD, 0U) /* app-specific record */ - QS_FUN(&Led_on); /* function called */ - QS_U32(0, ret); /* value returned */ - QS_U8 (0, index); /* parameter */ + QS_BEGIN_ID(LED_MOD, 0U) // app-specific record + QS_FUN(&Led_on); // function called + QS_U32(0, ret); // value returned + QS_U8 (0, index); // parameter QS_END() return ret; diff --git a/examples/qutest/unity_ledbar2/qutest/spy_spi.c b/examples/qutest/unity_ledbar2/qutest/spy_spi.c index 31791035..835a4588 100644 --- a/examples/qutest/unity_ledbar2/qutest/spy_spi.c +++ b/examples/qutest/unity_ledbar2/qutest/spy_spi.c @@ -1,17 +1,17 @@ -#include "qpc.h" /* QUTest interface */ -#include "Led.h" /* original interface */ +#include "qpc.h" // QUTest interface +#include "Led.h" // original interface //Q_DEFINE_THIS_FILE enum { - SPI_MOD = QS_USER2 /* QS app-specific record for the SPI module */ + SPI_MOD = QS_USER2 // QS app-specific record for the SPI module }; void SPI_beginTransaction(void); void SPI_transfer(uint32_t data); void SPI_endTransaction(void); -/*--------------------------------------------------------------------------*/ +//---------------------------------------------------------------------------- void Spi_DICTIONARY(void) { QS_FUN_DICTIONARY(&SPI_beginTransaction); QS_FUN_DICTIONARY(&SPI_transfer); @@ -19,22 +19,22 @@ void Spi_DICTIONARY(void) { QS_USR_DICTIONARY(SPI_MOD); } -/*--------------------------------------------------------------------------*/ +//---------------------------------------------------------------------------- void SPI_beginTransaction(void) { - QS_BEGIN_ID(SPI_MOD, 0U) /* app-specific record */ - QS_FUN(&SPI_beginTransaction); /* function called */ + QS_BEGIN_ID(SPI_MOD, 0U) // app-specific record + QS_FUN(&SPI_beginTransaction); // function called QS_END() } void SPI_transfer(uint32_t data) { - QS_BEGIN_ID(SPI_MOD, 0U) /* app-specific record */ - QS_FUN(&SPI_transfer); /* function called */ - QS_U32(0, data); /* parameter */ + QS_BEGIN_ID(SPI_MOD, 0U) // app-specific record + QS_FUN(&SPI_transfer); // function called + QS_U32(0, data); // parameter QS_END() } void SPI_endTransaction(void) { - QS_BEGIN_ID(SPI_MOD, 0U) /* app-specific record */ - QS_FUN(&SPI_endTransaction); /* function called */ + QS_BEGIN_ID(SPI_MOD, 0U) // app-specific record + QS_FUN(&SPI_endTransaction); // function called QS_END() } diff --git a/examples/qutest/unity_ledbar2/qutest/test_ledbar2.c b/examples/qutest/unity_ledbar2/qutest/test_ledbar2.c index c67244d5..55eb61f6 100644 --- a/examples/qutest/unity_ledbar2/qutest/test_ledbar2.c +++ b/examples/qutest/unity_ledbar2/qutest/test_ledbar2.c @@ -1,49 +1,51 @@ -#include "qpc.h" /* QUTest interface */ -#include "LedBar2.h" /* CUT interface */ +#include "qpc.h" // QUTest interface +#include "LedBar2.h" // CUT interface Q_DEFINE_THIS_FILE -/*--------------------------------------------------------------------------*/ -void Led_DICTIONARY(void); /* dictionaries for the Led "spy " test double */ -void Spi_DICTIONARY(void); /* dictionaries for the SPI "spy " test double */ +//---------------------------------------------------------------------------- +void Led_DICTIONARY(void); // dictionaries for the Led "spy " test double +void Spi_DICTIONARY(void); // dictionaries for the SPI "spy " test double -/*--------------------------------------------------------------------------*/ +//---------------------------------------------------------------------------- int main(int argc, char *argv[]) { - QF_init(); /* initialize the framework */ + QF_init(); // initialize the framework - /* initialize the QS software tracing */ - Q_ALLEGE(QS_INIT(argc > 1 ? argv[1] : (void *)0)); + // initialize the QS software tracing + if (QS_INIT((argc > 1) ? argv[1] : (void *)0) == 0U) { + Q_ERROR(); + } - /* dictionaries... */ + // dictionaries... Led_DICTIONARY(); Spi_DICTIONARY(); QS_FUN_DICTIONARY(&LedBar2_setPercent); - /* filter setup... */ + // filter setup... QS_GLB_FILTER(QS_ALL_RECORDS); - return QF_run(); /* run the tests */ + return QF_run(); // run the tests } -/*--------------------------------------------------------------------------*/ +//---------------------------------------------------------------------------- void QS_onTestSetup(void) { } -/*..........................................................................*/ +//............................................................................ void QS_onTestTeardown(void) { } -/*..........................................................................*/ +//............................................................................ void QS_onCommand(uint8_t cmdId, uint32_t param1, uint32_t param2, uint32_t param3) { switch (cmdId) { - case 0: { /* call LedBar2_setPercent */ + case 0: { // call LedBar2_setPercent uint32_t ret = LedBar2_setPercent((uint8_t)param1); - QS_BEGIN_ID(QS_USER + cmdId, 0U) /* app-specific record */ - QS_FUN(&LedBar2_setPercent); /* function called */ - QS_U32(0, ret); /* value returned */ - QS_U8 (0, (uint8_t)param1); /* parameter */ + QS_BEGIN_ID(QS_USER + cmdId, 0U) // app-specific record + QS_FUN(&LedBar2_setPercent); // function called + QS_U32(0, ret); // value returned + QS_U8 (0, (uint8_t)param1); // parameter QS_END() break; } @@ -51,20 +53,20 @@ void QS_onCommand(uint8_t cmdId, break; } - /* unused parametrers... */ + // unused parametrers... (void)param2; (void)param3; } -/*..........................................................................*/ -/* host callback function to "massage" the event, if necessary */ +//............................................................................ +// host callback function to "massage" the event, if necessary void QS_onTestEvt(QEvt *e) { (void)e; -#ifdef Q_HOST /* is this test compiled for a desktop Host computer? */ -#else /* this test is compiled for an embedded Target system */ +#ifdef Q_HOST // is this test compiled for a desktop Host computer? +#else // this test is compiled for an embedded Target system #endif } -/*..........................................................................*/ -/*! callback function to output the posted QP events (not used here) */ +//............................................................................ +//! callback function to output the posted QP events (not used here) void QS_onTestPost(void const *sender, QActive *recipient, QEvt const *e, bool status) { diff --git a/examples/qutest/unity_ledbar2/src/Led.h b/examples/qutest/unity_ledbar2/src/Led.h index 246c36a9..a272854b 100644 --- a/examples/qutest/unity_ledbar2/src/Led.h +++ b/examples/qutest/unity_ledbar2/src/Led.h @@ -3,10 +3,10 @@ enum { MAX_LED = 5 }; -/* turns a given LED on and retruns the power drawn by it in uW */ +// turns a given LED on and retruns the power drawn by it in uW uint32_t Led_on(uint8_t index); -/* turns a given LED off */ +// turns a given LED off void Led_off(uint8_t index); -#endif /* LED_H */ \ No newline at end of file +#endif // LED_H diff --git a/examples/qutest/unity_ledbar2/src/LedBar2.c b/examples/qutest/unity_ledbar2/src/LedBar2.c index 87479fe6..ef106d24 100644 --- a/examples/qutest/unity_ledbar2/src/LedBar2.c +++ b/examples/qutest/unity_ledbar2/src/LedBar2.c @@ -3,51 +3,51 @@ #include "Led.h" #include "Spi.h" -#include "qassert.h" /* for embedded systems-friendly assertions */ +#include "qsafe.h" // QP Functional Safety (FuSa) System Q_DEFINE_THIS_MODULE("LedBar2") -/* - Example sequence diagram for the LedBar2_setPercent() implementation: - - +----------+ +-----+ +------+ - | LedBar2 | | LED | | SPI | - +----------+ +-----+ +------+ - | | | - +-+ SPI_beginTransaction() | - | |------------------------>| - | | | | - | | Led_on(0) | | - | |------------->| | - | | SPI_transfer(pwr) | - | |------------------------>| - | | | | - | | Led_on(1) | | - | |------------->| | - | | | | - | | SPI_transfer(pwr) | - | |------------------------>| - | | SPI_endTransaction() | - | |------------------------>| - | | | | - | | Led_off(2) | | - | |------------->| | - | | | | - | | Led_off(3) | | - | |------------->| | - | | | | - | | Led_off(4) | | - | |------------->| | - +-+ | | - | | | -*/ +// +// Example sequence diagram for the LedBar2_setPercent() implementation: +// +// +----------+ +-----+ +------+ +// | LedBar2 | | LED | | SPI | +// +----------+ +-----+ +------+ +// | | | +// +-+ SPI_beginTransaction() | +// | |------------------------>| +// | | | | +// | | Led_on(0) | | +// | |------------->| | +// | | SPI_transfer(pwr) | +// | |------------------------>| +// | | | | +// | | Led_on(1) | | +// | |------------->| | +// | | | | +// | | SPI_transfer(pwr) | +// | |------------------------>| +// | | SPI_endTransaction() | +// | |------------------------>| +// | | | | +// | | Led_off(2) | | +// | |------------->| | +// | | | | +// | | Led_off(3) | | +// | |------------->| | +// | | | | +// | | Led_off(4) | | +// | |------------->| | +// +-+ | | +// | | | +// uint32_t LedBar2_setPercent(uint8_t const percent) { uint8_t const n_on = (uint8_t)((percent * MAX_LED) / 100U); - /*! @pre percent must not exceed 100 */ + //! @pre percent must not exceed 100 Q_REQUIRE_ID(100, n_on <= MAX_LED); - uint32_t p = 0U; /* power draw in [uW] */ + uint32_t p = 0U; // power draw in [uW] uint8_t i; if (n_on > 0U) { SPI_beginTransaction(); diff --git a/examples/qutest/unity_ledbar2/src/LedBar2.h b/examples/qutest/unity_ledbar2/src/LedBar2.h index 63620f70..617a1003 100644 --- a/examples/qutest/unity_ledbar2/src/LedBar2.h +++ b/examples/qutest/unity_ledbar2/src/LedBar2.h @@ -1,9 +1,9 @@ #ifndef LEDBAR2_H #define LEDBAR2_H -/* displays the percentage on the LED bar -* and returns the total power drawn by the LEDs in uW. -*/ +// displays the percentage on the LED bar +// and returns the total power drawn by the LEDs in uW. +// uint32_t LedBar2_setPercent(uint8_t percent); -#endif /* LEDBAR2_H */ \ No newline at end of file +#endif // LEDBAR2_H diff --git a/examples/qutest/unity_ledbar2/src/Spi.h b/examples/qutest/unity_ledbar2/src/Spi.h index 88f5c10f..741e4bd4 100644 --- a/examples/qutest/unity_ledbar2/src/Spi.h +++ b/examples/qutest/unity_ledbar2/src/Spi.h @@ -5,4 +5,4 @@ void SPI_beginTransaction(void); void SPI_transfer(uint32_t data); void SPI_endTransaction(void); -#endif /* SPI_H */ \ No newline at end of file +#endif // SPI_H diff --git a/examples/qutest/unity_ledbar2/test/TestLedBar2.c b/examples/qutest/unity_ledbar2/test/TestLedBar2.c index 3b4fe3a1..6499a19f 100644 --- a/examples/qutest/unity_ledbar2/test/TestLedBar2.c +++ b/examples/qutest/unity_ledbar2/test/TestLedBar2.c @@ -5,11 +5,11 @@ #include "MockSpi.h" void setUp(void) { - /* This is run before EACH TEST */ + // This is run before EACH TEST } void tearDown(void) { - /* This is run after EACH TEST */ + // This is run after EACH TEST } void test_LedBar_0_percent_all_off(void) { @@ -41,10 +41,10 @@ void test_LedBar_100_percent_all_on(void) } void test_LedBar_200_percent_ASSERT(void) { - /* NOTE: Here we EXPECT breaking the internal assertion inside CUT. - * But Unity does not provide a mechanism to verify that and - * to PASS the test, so this test will FAIL... - */ + // NOTE: Here we EXPECT breaking the internal assertion inside CUT. + // But Unity does not provide a mechanism to verify that and + // to PASS the test, so this test will FAIL... + // TEST_ASSERT(LedBar2_setPercent(200U)); } @@ -102,14 +102,16 @@ void test_LedBar_99_percent_four_on_FLAWED(void) { TEST_ASSERT_EQUAL(60U, LedBar2_setPercent(99U)); } -/* assertion handler... */ -void Q_onAssert(char const * const module, int const loc) { - (void)module; - UNITY_TEST_FAIL(loc, "ASSERTION"); +// error handler... +Q_NORETURN Q_onError(char const * const module, int_t const id) { + Q_UNUSED_PAR(module); + Q_UNUSED_PAR(id); + + UNITY_TEST_FAIL(loc, "ERROR"); } -/* NOTE: -* The Mock example requires a specific "test runner", which -* is provided in the file TestLedBar_Runner.c. -*/ +// NOTE: +// The Mock example requires a specific "test runner", which +// is provided in the file TestLedBar_Runner.c. +// diff --git a/examples/qutest/unity_ledbar2/test/TestLedBar2_Runner.c b/examples/qutest/unity_ledbar2/test/TestLedBar2_Runner.c index f247d599..10ff9063 100644 --- a/examples/qutest/unity_ledbar2/test/TestLedBar2_Runner.c +++ b/examples/qutest/unity_ledbar2/test/TestLedBar2_Runner.c @@ -1,6 +1,6 @@ -/* AUTOGENERATED FILE. DO NOT EDIT. */ +// AUTOGENERATED FILE. DO NOT EDIT. -/*=======Automagically Detected Files To Include=====*/ +//=======Automagically Detected Files To Include===== #include "unity.h" #include "cmock.h" #include "LedBar2.h" @@ -8,7 +8,7 @@ #include "MockLed.h" #include "MockSpi.h" -/*=======External Functions This Runner Calls=====*/ +//=======External Functions This Runner Calls===== extern void setUp(void); extern void tearDown(void); extern void test_LedBar_0_percent_all_off(void); @@ -20,7 +20,7 @@ extern void test_LedBar_50_percent_two_on_FLAWED(void); extern void test_LedBar_99_percent_four_on_FLAWED(void); -/*=======Mock Management=====*/ +//=======Mock Management===== static void CMock_Init(void) { MockLed_Init(); @@ -37,7 +37,7 @@ static void CMock_Destroy(void) MockSpi_Destroy(); } -/*=======Test Reset Options=====*/ +//=======Test Reset Options===== void resetTest(void); void resetTest(void) { @@ -53,7 +53,7 @@ void verifyTest(void) CMock_Verify(); } -/*=======Test Runner Used To Run Each Test=====*/ +//=======Test Runner Used To Run Each Test===== static void run_test(UnityTestFunction func, const char* name, UNITY_LINE_TYPE line_num) { Unity.CurrentTestName = name; @@ -81,7 +81,7 @@ static void run_test(UnityTestFunction func, const char* name, UNITY_LINE_TYPE l UnityConcludeTest(); } -/*=======MAIN=====*/ +//=======MAIN===== int main(void) { UnityBegin("TestLedBar2.c"); diff --git a/examples/qutest/unity_ledbar2/test/mocks/MockLed.c b/examples/qutest/unity_ledbar2/test/mocks/MockLed.c index 1d5e146d..bafd4639 100644 --- a/examples/qutest/unity_ledbar2/test/mocks/MockLed.c +++ b/examples/qutest/unity_ledbar2/test/mocks/MockLed.c @@ -1,4 +1,4 @@ -/* AUTOGENERATED FILE. DO NOT EDIT. */ +// AUTOGENERATED FILE. DO NOT EDIT. #include #include #include diff --git a/examples/qutest/unity_ledbar2/test/mocks/MockLed.h b/examples/qutest/unity_ledbar2/test/mocks/MockLed.h index 49491f12..7725dbed 100644 --- a/examples/qutest/unity_ledbar2/test/mocks/MockLed.h +++ b/examples/qutest/unity_ledbar2/test/mocks/MockLed.h @@ -1,11 +1,11 @@ -/* AUTOGENERATED FILE. DO NOT EDIT. */ +// AUTOGENERATED FILE. DO NOT EDIT. #ifndef _MOCKLED_H #define _MOCKLED_H #include "unity.h" #include "Led.h" -/* Ignore the following warnings, since we are copying code */ +// Ignore the following warnings, since we are copying code #if defined(__GNUC__) && !defined(__ICC) && !defined(__TMS470__) #if __GNUC__ > 4 || (__GNUC__ == 4 && (__GNUC_MINOR__ > 6 || (__GNUC_MINOR__ == 6 && __GNUC_PATCHLEVEL__ > 0))) #pragma GCC diagnostic push diff --git a/examples/qutest/unity_ledbar2/test/mocks/MockSpi.c b/examples/qutest/unity_ledbar2/test/mocks/MockSpi.c index d80cb646..e70a14ae 100644 --- a/examples/qutest/unity_ledbar2/test/mocks/MockSpi.c +++ b/examples/qutest/unity_ledbar2/test/mocks/MockSpi.c @@ -1,4 +1,4 @@ -/* AUTOGENERATED FILE. DO NOT EDIT. */ +// AUTOGENERATED FILE. DO NOT EDIT. #include #include #include diff --git a/examples/qutest/unity_ledbar2/test/mocks/MockSpi.h b/examples/qutest/unity_ledbar2/test/mocks/MockSpi.h index c701396e..abef69e0 100644 --- a/examples/qutest/unity_ledbar2/test/mocks/MockSpi.h +++ b/examples/qutest/unity_ledbar2/test/mocks/MockSpi.h @@ -1,11 +1,11 @@ -/* AUTOGENERATED FILE. DO NOT EDIT. */ +// AUTOGENERATED FILE. DO NOT EDIT. #ifndef _MOCKSPI_H #define _MOCKSPI_H #include "unity.h" #include "Spi.h" -/* Ignore the following warnings, since we are copying code */ +// Ignore the following warnings, since we are copying code #if defined(__GNUC__) && !defined(__ICC) && !defined(__TMS470__) #if __GNUC__ > 4 || (__GNUC__ == 4 && (__GNUC_MINOR__ > 6 || (__GNUC_MINOR__ == 6 && __GNUC_PATCHLEVEL__ > 0))) #pragma GCC diagnostic push diff --git a/examples/qutest/unity_mock/src/Led.h b/examples/qutest/unity_mock/src/Led.h index 246c36a9..a272854b 100644 --- a/examples/qutest/unity_mock/src/Led.h +++ b/examples/qutest/unity_mock/src/Led.h @@ -3,10 +3,10 @@ enum { MAX_LED = 5 }; -/* turns a given LED on and retruns the power drawn by it in uW */ +// turns a given LED on and retruns the power drawn by it in uW uint32_t Led_on(uint8_t index); -/* turns a given LED off */ +// turns a given LED off void Led_off(uint8_t index); -#endif /* LED_H */ \ No newline at end of file +#endif // LED_H diff --git a/examples/qutest/unity_mock/src/LedBar.c b/examples/qutest/unity_mock/src/LedBar.c index 174dfe24..de203fcc 100644 --- a/examples/qutest/unity_mock/src/LedBar.c +++ b/examples/qutest/unity_mock/src/LedBar.c @@ -2,35 +2,35 @@ #include "LedBar.h" #include "Led.h" -/* - Example sequence diagram for the LedBar_setPercent() implementation: - - +----------+ +------+ +------+ +------+ +------+ +------+ - | LedBar | |LED[0]| |LED[1]| |LED[2]| |LED[3]| |LED[4]| - +----------+ +------+ +------+ +------+ +------+ +------+ - | | | | | | - +-+ Led_on() | | | | | - | |------------->| | | | | - | | | | | | | - | | Led_on() | | | | | - | |----------------------->| | | | - | | | | | | | - | | Led_on() | | | | | - | |--------------------------------->| | | - | | | | | | | - | | Led_off() | | | | | - | |------------------------------------------->| | - | | | | | | | - | | Led_off() | | | | | - | |----------------------------------------------------->| - | | | | | | | - +-+ | | | | | - | | | | | | -*/ +// +// Example sequence diagram for the LedBar_setPercent() implementation: +// +// +----------+ +------+ +------+ +------+ +------+ +------+ +// | LedBar | |LED[0]| |LED[1]| |LED[2]| |LED[3]| |LED[4]| +// +----------+ +------+ +------+ +------+ +------+ +------+ +// | | | | | | +// +-+ Led_on() | | | | | +// | |------------->| | | | | +// | | | | | | | +// | | Led_on() | | | | | +// | |----------------------->| | | | +// | | | | | | | +// | | Led_on() | | | | | +// | |--------------------------------->| | | +// | | | | | | | +// | | Led_off() | | | | | +// | |------------------------------------------->| | +// | | | | | | | +// | | Led_off() | | | | | +// | |----------------------------------------------------->| +// | | | | | | | +// +-+ | | | | | +// | | | | | | +// uint32_t LedBar_setPercent(uint8_t percent) { uint8_t n = (uint8_t)((percent * MAX_LED) / 100); uint8_t i; - uint32_t p = 0U; /* power draw in uW */ + uint32_t p = 0U; // power draw in uW for (i = 0U; i < n; ++i) { p += Led_on(i); } diff --git a/examples/qutest/unity_mock/src/LedBar.h b/examples/qutest/unity_mock/src/LedBar.h index 249daab7..62bdc268 100644 --- a/examples/qutest/unity_mock/src/LedBar.h +++ b/examples/qutest/unity_mock/src/LedBar.h @@ -1,9 +1,9 @@ #ifndef LEDBAR_H #define LEDBAR_H -/* displays the percentage on the LED bar -* and returns the total power drawn by the LEDs in uW. -*/ +// displays the percentage on the LED bar +// and returns the total power drawn by the LEDs in uW. +// uint32_t LedBar_setPercent(uint8_t percent); -#endif /* LEDBAR_H */ \ No newline at end of file +#endif // LEDBAR_H diff --git a/examples/qutest/unity_mock/test/Makefile b/examples/qutest/unity_mock/test/Makefile index 960da1bd..479817a6 100644 --- a/examples/qutest/unity_mock/test/Makefile +++ b/examples/qutest/unity_mock/test/Makefile @@ -218,7 +218,7 @@ all : $(TARGET_EXE) run endif $(TARGET_EXE) : $(C_OBJS_EXT) $(CPP_OBJS_EXT) - $(CC) $(CFLAGS) $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o + $(CC) $(CFLAGS) $(QPC)/src/qs/qstamp.c -o $(BIN_DIR)/qstamp.o $(LINK) $(LINKFLAGS) $(LIB_DIRS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) run : $(TARGET_EXE) diff --git a/examples/qutest/unity_mock/test/make_efm32 b/examples/qutest/unity_mock/test/make_efm32 index 9bc2fa87..e7d79977 100644 --- a/examples/qutest/unity_mock/test/make_efm32 +++ b/examples/qutest/unity_mock/test/make_efm32 @@ -253,7 +253,7 @@ $(TARGET_BIN) : $(TARGET_ELF) $(FLASH) $@ $(TARGET_ELF) : $(ASM_OBJS_EXT) $(C_OBJS_EXT) $(CPP_OBJS_EXT) - $(CC) $(CFLAGS) $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o + $(CC) $(CFLAGS) $(QPC)/src/qs/qstamp.c -o $(BIN_DIR)/qstamp.o $(LINK) $(LINKFLAGS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) flash : diff --git a/examples/qutest/unity_mock/test/make_tm4c123 b/examples/qutest/unity_mock/test/make_tm4c123 index 618a9554..874d6027 100644 --- a/examples/qutest/unity_mock/test/make_tm4c123 +++ b/examples/qutest/unity_mock/test/make_tm4c123 @@ -254,7 +254,7 @@ $(TARGET_BIN) : $(TARGET_ELF) @pause $(TARGET_ELF) : $(ASM_OBJS_EXT) $(C_OBJS_EXT) $(CPP_OBJS_EXT) - $(CC) $(CFLAGS) $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o + $(CC) $(CFLAGS) $(QPC)/src/qs/qstamp.c -o $(BIN_DIR)/qstamp.o $(LINK) $(LINKFLAGS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) flash : diff --git a/examples/qutest/unity_mock/test/spy_Led.c b/examples/qutest/unity_mock/test/spy_Led.c index d20c2923..fb2d3026 100644 --- a/examples/qutest/unity_mock/test/spy_Led.c +++ b/examples/qutest/unity_mock/test/spy_Led.c @@ -1,50 +1,50 @@ -/***************************************************************************** -* Purpose: example QUTEST "spy" test double implementation -* Last Updated for Version: 6.3.6 -* Date of the Last Update: 2018-10-11 -* -* Q u a n t u m L e a P s -* ------------------------ -* Modern Embedded Software -* -* Copyright (C) 2005-2018 Quantum Leaps, LLC. All rights reserved. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* -* -*****************************************************************************/ -#include "qpc.h" /* QUTest interface */ -#include "Led.h" /* original interface */ +//============================================================================ +// Purpose: example QUTEST "spy" test double implementation +// Last Updated for Version: 6.3.6 +// Date of the Last Update: 2018-10-11 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005-2018 Quantum Leaps, LLC. All rights reserved. +// +// This program is open source software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Alternatively, this program may be distributed and modified under the +// terms of Quantum Leaps commercial licenses, which expressly supersede +// the GNU General Public License and are specifically designed for +// licensees interested in retaining the proprietary status of their code. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Contact information: +// +// +//============================================================================ +#include "qpc.h" // QUTest interface +#include "Led.h" // original interface //Q_DEFINE_THIS_FILE enum { - LED_MOD = QS_USER1 /* QS app-specific record for the LED module */ + LED_MOD = QS_USER1 // QS app-specific record for the LED module }; static uint32_t led_power[MAX_LED] = { 10, 20, 10, 20, 10 }; -/*--------------------------------------------------------------------------*/ +//---------------------------------------------------------------------------- void Led_DICTIONARY(void) { QS_FUN_DICTIONARY(&Led_on); QS_FUN_DICTIONARY(&Led_off); @@ -52,29 +52,29 @@ void Led_DICTIONARY(void) { QS_OBJ_DICTIONARY(&led_power); } -/*--------------------------------------------------------------------------*/ -/* turns a given LED off */ +//---------------------------------------------------------------------------- +// turns a given LED off void Led_off(uint8_t index) { - QS_BEGIN_ID(LED_MOD, 0U) /* app-specific record */ - QS_FUN(&Led_off); /* function called */ - QS_U8 (0, index); /* parameter */ + QS_BEGIN_ID(LED_MOD, 0U) // app-specific record + QS_FUN(&Led_off); // function called + QS_U8 (0, index); // parameter QS_END() } -/* turns a given LED on and retruns the power drawn by it in uW */ +// turns a given LED on and retruns the power drawn by it in uW uint32_t Led_on(uint8_t index) { QS_TEST_PROBE_DEF(&Led_on) - uint32_t ret = led_power[index]; /* assume */ + uint32_t ret = led_power[index]; // assume - /* tweak the returned power draw from the test probe */ + // tweak the returned power draw from the test probe QS_TEST_PROBE( ret = (uint32_t)qs_tp_; ) - QS_BEGIN_ID(LED_MOD, 0U) /* app-specific record */ - QS_FUN(&Led_on); /* function called */ - QS_U32(0, ret); /* value returned */ - QS_U8 (0, index); /* parameter */ + QS_BEGIN_ID(LED_MOD, 0U) // app-specific record + QS_FUN(&Led_on); // function called + QS_U32(0, ret); // value returned + QS_U8 (0, index); // parameter QS_END() return ret; diff --git a/examples/qutest/unity_mock/test/test_LedBar.c b/examples/qutest/unity_mock/test/test_LedBar.c index 04e87471..9a1c9113 100644 --- a/examples/qutest/unity_mock/test/test_LedBar.c +++ b/examples/qutest/unity_mock/test/test_LedBar.c @@ -1,80 +1,82 @@ -/***************************************************************************** -* Purpose: example QUTEST fixture for the mock example from Unity -* Last Updated for Version: 6.3.6 -* Date of the Last Update: 2018-10-11 -* -* Q u a n t u m L e a P s -* ------------------------ -* Modern Embedded Software -* -* Copyright (C) 2005-2018 Quantum Leaps, LLC. All rights reserved. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* -* -*****************************************************************************/ -#include "qpc.h" /* QUTest interface */ -#include "LedBar.h" /* CUT interface */ +//============================================================================ +// Purpose: example QUTEST fixture for the mock example from Unity +// Last Updated for Version: 7.3.0 +// Date of the Last Update: 2023-05-25 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005-2018 Quantum Leaps, LLC. All rights reserved. +// +// This program is open source software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Alternatively, this program may be distributed and modified under the +// terms of Quantum Leaps commercial licenses, which expressly supersede +// the GNU General Public License and are specifically designed for +// licensees interested in retaining the proprietary status of their code. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Contact information: +// +// +//============================================================================ +#include "qpc.h" // QUTest interface +#include "LedBar.h" // CUT interface Q_DEFINE_THIS_FILE -/*--------------------------------------------------------------------------*/ -void Led_DICTIONARY(void); /* dictionaries for the Led "spy " test double */ +//---------------------------------------------------------------------------- +void Led_DICTIONARY(void); // dictionaries for the Led "spy " test double -/*--------------------------------------------------------------------------*/ +//---------------------------------------------------------------------------- int main(int argc, char *argv[]) { - QF_init(); /* initialize the framework */ + QF_init(); // initialize the framework - /* initialize the QS software tracing */ - Q_ALLEGE(QS_INIT(argc > 1 ? argv[1] : (void *)0)); + // initialize the QS software tracing + if (QS_INIT((argc > 1) ? argv[1] : (void *)0) == 0U) { + Q_ERROR(); + } - /* dictionaries... */ + // dictionaries... Led_DICTIONARY(); QS_FUN_DICTIONARY(&LedBar_setPercent); - /* filter setup... */ + // filter setup... QS_GLB_FILTER(QS_ALL_RECORDS); - return QF_run(); /* run the tests */ + return QF_run(); // run the tests } -/*--------------------------------------------------------------------------*/ +//---------------------------------------------------------------------------- void QS_onTestSetup(void) { } -/*..........................................................................*/ +//............................................................................ void QS_onTestTeardown(void) { } -/*..........................................................................*/ +//............................................................................ void QS_onCommand(uint8_t cmdId, uint32_t param1, uint32_t param2, uint32_t param3) { switch (cmdId) { - case 0: { /* call the CUT: LedBar_setPercent */ + case 0: { // call the CUT: LedBar_setPercent uint32_t ret = LedBar_setPercent((uint8_t)param1); - QS_BEGIN_ID(QS_USER + cmdId, 0U) /* app-specific record */ - QS_FUN(&LedBar_setPercent); /* function called */ - QS_U32(0, ret); /* value returned */ - QS_U8 (0, (uint8_t)param1); /* parameter */ + QS_BEGIN_ID(QS_USER + cmdId, 0U) // app-specific record + QS_FUN(&LedBar_setPercent); // function called + QS_U32(0, ret); // value returned + QS_U8 (0, (uint8_t)param1); // parameter QS_END() break; } @@ -82,21 +84,21 @@ void QS_onCommand(uint8_t cmdId, break; } - /* unused parametrers... */ + // unused parametrers... //(void)param1; (void)param2; (void)param3; } -/*..........................................................................*/ -/* host callback function to "massage" the event, if necessary */ +//............................................................................ +// host callback function to "massage" the event, if necessary void QS_onTestEvt(QEvt *e) { (void)e; -#ifdef Q_HOST /* is this test compiled for a desktop Host computer? */ -#else /* this test is compiled for an embedded Target system */ +#ifdef Q_HOST // is this test compiled for a desktop Host computer? +#else // this test is compiled for an embedded Target system #endif } -/*..........................................................................*/ -/*! callback function to output the posted QP events (not used here) */ +//............................................................................ +//! callback function to output the posted QP events (not used here) void QS_onTestPost(void const *sender, QActive *recipient, QEvt const *e, bool status) { diff --git a/examples/qutest/unity_mock/test_unity/TestLedBar.c b/examples/qutest/unity_mock/test_unity/TestLedBar.c index 9e74bcbb..dc66567b 100644 --- a/examples/qutest/unity_mock/test_unity/TestLedBar.c +++ b/examples/qutest/unity_mock/test_unity/TestLedBar.c @@ -5,12 +5,12 @@ void setUp(void) { - /* This is run before EACH TEST */ + // This is run before EACH TEST } void tearDown(void) { - /* This is run after EACH TEST */ + // This is run after EACH TEST } void test_LedBar_0_percent_all_off(void) @@ -80,8 +80,8 @@ void test_LedBar_99_percent_four_on(void) } -/* NOTE: -* The Mock example requires a specific "test runner", which -* is provided in the file TestLedBar_Runner.c. -*/ +// NOTE: +// The Mock example requires a specific "test runner", which +// is provided in the file TestLedBar_Runner.c. +// diff --git a/examples/qutest/unity_mock/test_unity/TestLedBar_Runner.c b/examples/qutest/unity_mock/test_unity/TestLedBar_Runner.c index d9e480a6..f4d17159 100644 --- a/examples/qutest/unity_mock/test_unity/TestLedBar_Runner.c +++ b/examples/qutest/unity_mock/test_unity/TestLedBar_Runner.c @@ -1,13 +1,13 @@ -/* AUTOGENERATED FILE. DO NOT EDIT. */ +// AUTOGENERATED FILE. DO NOT EDIT. -/*=======Automagically Detected Files To Include=====*/ +//=======Automagically Detected Files To Include===== #include "unity.h" #include "cmock.h" #include "LedBar.h" #include #include "MockLed.h" -/*=======External Functions This Runner Calls=====*/ +//=======External Functions This Runner Calls===== extern void setUp(void); extern void tearDown(void); extern void test_LedBar_0_percent_all_off(void); @@ -18,7 +18,7 @@ extern void test_LedBar_50_percent_two_on(void); extern void test_LedBar_99_percent_four_on(void); -/*=======Mock Management=====*/ +//=======Mock Management===== static void CMock_Init(void) { MockLed_Init(); @@ -32,7 +32,7 @@ static void CMock_Destroy(void) MockLed_Destroy(); } -/*=======Test Reset Options=====*/ +//=======Test Reset Options===== void resetTest(void); void resetTest(void) { @@ -48,7 +48,7 @@ void verifyTest(void) CMock_Verify(); } -/*=======Test Runner Used To Run Each Test=====*/ +//=======Test Runner Used To Run Each Test===== static void run_test(UnityTestFunction func, const char* name, UNITY_LINE_TYPE line_num) { Unity.CurrentTestName = name; @@ -76,7 +76,7 @@ static void run_test(UnityTestFunction func, const char* name, UNITY_LINE_TYPE l UnityConcludeTest(); } -/*=======MAIN=====*/ +//=======MAIN===== int main(void) { UnityBegin("TestLedBar.c"); diff --git a/examples/qutest/unity_mock/test_unity/mocks/MockLed.c b/examples/qutest/unity_mock/test_unity/mocks/MockLed.c index 1d5e146d..bafd4639 100644 --- a/examples/qutest/unity_mock/test_unity/mocks/MockLed.c +++ b/examples/qutest/unity_mock/test_unity/mocks/MockLed.c @@ -1,4 +1,4 @@ -/* AUTOGENERATED FILE. DO NOT EDIT. */ +// AUTOGENERATED FILE. DO NOT EDIT. #include #include #include diff --git a/examples/qutest/unity_mock/test_unity/mocks/MockLed.h b/examples/qutest/unity_mock/test_unity/mocks/MockLed.h index 49491f12..7725dbed 100644 --- a/examples/qutest/unity_mock/test_unity/mocks/MockLed.h +++ b/examples/qutest/unity_mock/test_unity/mocks/MockLed.h @@ -1,11 +1,11 @@ -/* AUTOGENERATED FILE. DO NOT EDIT. */ +// AUTOGENERATED FILE. DO NOT EDIT. #ifndef _MOCKLED_H #define _MOCKLED_H #include "unity.h" #include "Led.h" -/* Ignore the following warnings, since we are copying code */ +// Ignore the following warnings, since we are copying code #if defined(__GNUC__) && !defined(__ICC) && !defined(__TMS470__) #if __GNUC__ > 4 || (__GNUC__ == 4 && (__GNUC_MINOR__ > 6 || (__GNUC_MINOR__ == 6 && __GNUC_PATCHLEVEL__ > 0))) #pragma GCC diagnostic push diff --git a/examples/qutest/unity_strlen/qutest/Makefile b/examples/qutest/unity_strlen/qutest/Makefile index 32f1befe..14f1a7ef 100644 --- a/examples/qutest/unity_strlen/qutest/Makefile +++ b/examples/qutest/unity_strlen/qutest/Makefile @@ -217,7 +217,7 @@ all : $(TARGET_EXE) run endif $(TARGET_EXE) : $(C_OBJS_EXT) $(CPP_OBJS_EXT) - $(CC) $(CFLAGS) $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o + $(CC) $(CFLAGS) $(QPC)/src/qs/qstamp.c -o $(BIN_DIR)/qstamp.o $(LINK) $(LINKFLAGS) $(LIB_DIRS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) run : $(TARGET_EXE) diff --git a/examples/qutest/unity_strlen/qutest/make_efm32 b/examples/qutest/unity_strlen/qutest/make_efm32 index c8abc0c0..c02a4018 100644 --- a/examples/qutest/unity_strlen/qutest/make_efm32 +++ b/examples/qutest/unity_strlen/qutest/make_efm32 @@ -252,7 +252,7 @@ $(TARGET_BIN) : $(TARGET_ELF) $(FLASH) $@ $(TARGET_ELF) : $(ASM_OBJS_EXT) $(C_OBJS_EXT) $(CPP_OBJS_EXT) - $(CC) $(CFLAGS) $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o + $(CC) $(CFLAGS) $(QPC)/src/qs/qstamp.c -o $(BIN_DIR)/qstamp.o $(LINK) $(LINKFLAGS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) flash : diff --git a/examples/qutest/unity_strlen/qutest/make_nucleo-l053r8 b/examples/qutest/unity_strlen/qutest/make_nucleo-l053r8 index c8d204a6..603fee15 100644 --- a/examples/qutest/unity_strlen/qutest/make_nucleo-l053r8 +++ b/examples/qutest/unity_strlen/qutest/make_nucleo-l053r8 @@ -252,7 +252,7 @@ $(TARGET_BIN) : $(TARGET_ELF) $(SLEEP) 2 $(TARGET_ELF) : $(ASM_OBJS_EXT) $(C_OBJS_EXT) $(CPP_OBJS_EXT) - $(CC) $(CFLAGS) $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o + $(CC) $(CFLAGS) $(QPC)/src/qs/qstamp.c -o $(BIN_DIR)/qstamp.o $(LINK) $(LINKFLAGS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) flash : diff --git a/examples/qutest/unity_strlen/qutest/make_tm4c123 b/examples/qutest/unity_strlen/qutest/make_tm4c123 index e0311e41..580678cd 100644 --- a/examples/qutest/unity_strlen/qutest/make_tm4c123 +++ b/examples/qutest/unity_strlen/qutest/make_tm4c123 @@ -253,7 +253,7 @@ $(TARGET_BIN) : $(TARGET_ELF) @pause $(TARGET_ELF) : $(ASM_OBJS_EXT) $(C_OBJS_EXT) $(CPP_OBJS_EXT) - $(CC) $(CFLAGS) $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o + $(CC) $(CFLAGS) $(QPC)/src/qs/qstamp.c -o $(BIN_DIR)/qstamp.o $(LINK) $(LINKFLAGS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) flash : diff --git a/examples/qutest/unity_strlen/qutest/test_strlen.c b/examples/qutest/unity_strlen/qutest/test_strlen.c index 728ca970..705b3e9c 100644 --- a/examples/qutest/unity_strlen/qutest/test_strlen.c +++ b/examples/qutest/unity_strlen/qutest/test_strlen.c @@ -1,81 +1,83 @@ -/***************************************************************************** -* Purpose: example QUTEST fixture for the mock example from Unity -* Last updated for: @ref qpc_7_0_0 -* Date of the Last Update: 2022-03-12 -* -* Q u a n t u m L e a P s -* ------------------------ -* Modern Embedded Software -* -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* -* -*****************************************************************************/ -#include "qpc.h" /* QUTest interface */ -#include "my_strlen.h" /* CUT interface */ +//============================================================================ +// Purpose: example QUTEST fixture for the mock example from Unity +// Last updated for: @ref qpc_7_3_0 +// Date of the Last Update: 2023-05-25 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// This program is open source software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Alternatively, this program may be distributed and modified under the +// terms of Quantum Leaps commercial licenses, which expressly supersede +// the GNU General Public License and are specifically designed for +// licensees interested in retaining the proprietary status of their code. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Contact information: +// +// +//============================================================================ +#include "qpc.h" // QUTest interface +#include "my_strlen.h" // CUT interface Q_DEFINE_THIS_FILE -/*--------------------------------------------------------------------------*/ +//---------------------------------------------------------------------------- static char string[128]; -/*--------------------------------------------------------------------------*/ +//---------------------------------------------------------------------------- int main(int argc, char *argv[]) { - QF_init(); /* initialize the framework */ + QF_init(); // initialize the framework - /* initialize the QS software tracing */ - Q_ALLEGE(QS_INIT(argc > 1 ? argv[1] : (void *)0)); + // initialize the QS software tracing + if (QS_INIT((argc > 1) ? argv[1] : (void *)0) == 0U) { + Q_ERROR(); + } - /* dictionaries... */ + // dictionaries... QS_FUN_DICTIONARY(&my_strlen); QS_OBJ_DICTIONARY(string); - /* filter setup... */ + // filter setup... QS_GLB_FILTER(QS_ALL_RECORDS); QS_setCurrObj(AP_OBJ, string); - return QF_run(); /* run the tests */ + return QF_run(); // run the tests } -/*--------------------------------------------------------------------------*/ +//---------------------------------------------------------------------------- void QS_onTestSetup(void) { } -/*..........................................................................*/ +//............................................................................ void QS_onTestTeardown(void) { } -/*..........................................................................*/ +//............................................................................ void QS_onCommand(uint8_t cmdId, uint32_t param1, uint32_t param2, uint32_t param3) { switch (cmdId) { - case 0: { /* call the CUT: my_strlen(string) */ + case 0: { // call the CUT: my_strlen(string) uint16_t ret = my_strlen(string); - QS_BEGIN_ID(QS_USER + cmdId, 0U) /* app-specific record */ - QS_FUN(&my_strlen); /* function called */ - QS_U16(0, ret); /* value returned */ - QS_STR(string); /* the current string */ + QS_BEGIN_ID(QS_USER + cmdId, 0U) // app-specific record + QS_FUN(&my_strlen); // function called + QS_U16(0, ret); // value returned + QS_STR(string); // the current string QS_END() break; } @@ -83,21 +85,21 @@ void QS_onCommand(uint8_t cmdId, break; } - /* unused parameters... */ + // unused parameters... (void)param1; (void)param2; (void)param3; } -/*..........................................................................*/ -/* host callback function to "massage" the event, if necessary */ +//............................................................................ +// host callback function to "massage" the event, if necessary void QS_onTestEvt(QEvt *e) { (void)e; -#ifdef Q_HOST /* is this test compiled for a desktop Host computer? */ -#else /* this test is compiled for an embedded Target system */ +#ifdef Q_HOST // is this test compiled for a desktop Host computer? +#else // this test is compiled for an embedded Target system #endif } -/*..........................................................................*/ -/*! callback function to output the posted QP events (not used here) */ +//............................................................................ +//! callback function to output the posted QP events (not used here) void QS_onTestPost(void const *sender, QActive *recipient, QEvt const *e, bool status) { diff --git a/examples/qutest/unity_strlen/src/my_strlen.h b/examples/qutest/unity_strlen/src/my_strlen.h index 4dbf1fac..e27caf8a 100644 --- a/examples/qutest/unity_strlen/src/my_strlen.h +++ b/examples/qutest/unity_strlen/src/my_strlen.h @@ -5,4 +5,4 @@ uint16_t my_strlen(char const *str); -#endif /* MY_STRLEN_H */ +#endif // MY_STRLEN_H diff --git a/examples/qutest/unity_strlen/test/TestStrLen.c b/examples/qutest/unity_strlen/test/TestStrLen.c index b0774256..b7c13e4e 100644 --- a/examples/qutest/unity_strlen/test/TestStrLen.c +++ b/examples/qutest/unity_strlen/test/TestStrLen.c @@ -1,17 +1,17 @@ -#include "unity.h" /* Unit testing harness (Unity) */ -#include "my_strlen.h" /* Code/Component Under Test (CUT) */ +#include "unity.h" // Unit testing harness (Unity) +#include "my_strlen.h" // Code/Component Under Test (CUT) void setUp(void) { - /* set stuff up here */ + // set stuff up here } void tearDown(void) { - /* clean stuff up here */ + // clean stuff up here } void test_my_strlen_0_for_empty_string(void) { - uint16_t len = my_strlen(""); /* call the CUT */ - TEST_ASSERT_EQUAL(0U, len); /* verify test "assertion" */ + uint16_t len = my_strlen(""); // call the CUT + TEST_ASSERT_EQUAL(0U, len); // verify test "assertion" } void test_my_strlen_n_for_various_strings(void) { @@ -24,7 +24,7 @@ void test_my_strlen_n_for_unprintable_chars(void) { TEST_ASSERT_EQUAL(3U, my_strlen("\a\b\n")); } -/* not needed when using generate_test_runner.rb */ +// not needed when using generate_test_runner.rb int main(void) { UNITY_BEGIN(); RUN_TEST(test_my_strlen_0_for_empty_string); diff --git a/examples/qwin-gui/README.md b/examples/qwin-gui/README.md new file mode 100644 index 00000000..d67f7685 --- /dev/null +++ b/examples/qwin-gui/README.md @@ -0,0 +1,82 @@ +![QTools Collection](https://www.state-machine.com/img/qwin_banner.jpg) + +# About this Directory +This directory contains examples that illustrate the "Dual Targeting" +approach to developing embedded software. Specifically, the examples +run on Windows GUI, but large portions of the code are actually for +deeply embedded boards. + + +# What is "Dual Targeting"? +When developing embedded code for devices with non-trivial user interfaces, +it often pays off to build a prototype (virtual prototype) of the embedded +system on a PC. The strategy is called "dual targeting", because you develop +software on one machine (e.g., Windows PC) and run it on a deeply embedded +target, as well as on the PC. Dual targeting is the main strategy for +avoiding the "target system bottleneck" in the agile embedded software +development. + +> **NOTE** +*Please note that dual targeting does not mean that the embedded device has +anything to do with the PC or Windows. Neither it means that the simulation +must be cycle-exact with the embedded target CPU. Instead, dual targeting +simply means that from day one, your embedded code (typically in C or C++) +is designed to run on at least two platforms: the final target hardware and +your PC. All you really need for this is two C/C++ compilers: one for the PC +and another for the embedded device.* + + +# About QWin™ GUI Prototyping Toolkit +QWin™ is a free GUI toolkit for prototyping embedded systems on Windows in the +C or C++ programming language, including building realistic embedded front panels +consisting of LCD displays (both graphic and segmented), LEDs, buttons, knobs, +sliders, etc. The implementation is based on the raw Win32 API to provide simple +direct mapping to C/C++ for easy integration with your embedded code. + + +> **NOTE** +_The problem of building GUI prototypes of embedded devices on the desktop +is very common, yet it seems that most developers try to use C#, .NET, +VisualBasic or other such environments to build prototypes of their embedded +devices. The main shortcoming of all such solutions is that they don't provide +direct binding to C/C++, which complicates the build process and the debugging +of the C/C++ code on the host._ + + +# QWin™ Code +QWin™ is included in the QP/C and QP/C++ frameworks (in the `\ports\win32` +and `\ports\win32-qv` directories), where `` stands for the +installation directory of the qpc or the qpcpp framework. + from the QTools Collection._ + + +# QWin™ Features +Currently QWin™ provides the following facilities: + +* Graphic displays (pixel-addressable) such as graphical LCDs, OLEDs, etc. + with up to 24-bit color +* Segmented displays such as segment LCDs, and segment LEDs with generic, + custom bitmaps for the segments. +* Owner-drawn buttons with custom “depressed” and “released” bitmaps and capable + of generating separate events when depressed and when released. + +Additionally, the provided code shows how to handle input sources: +* Keyboard events +* Mouse move events and mouse-wheel events + + +# QWin™ Documentation +QWin™ GUI Prototyping Toolkit is described in the pplication Note: +[QWIN GUI Kit for Prototyping Embedded Systems on Windows](https://www.state-machine.com/doc/AN_QWin-GUI.pdf). + +[![AppNote: QWIN GUI Kit for Prototyping Embedded Systems](https://www.state-machine.com/img/qwin_an.jpg)](https://www.state-machine.com/doc/AN_QWin-GUI.pdf) + + +# Licensing +The QWin is licensed under the permissive MIT license +(see top-level comments in the files `qwin_gui.h` and `qwin_gui.c`) + + +# Contact information: +- https://www.state-machine.com +- info@state-machine.com diff --git a/examples/arm-cm/dpp_efm32-slstk3401a/win32-gui/Res/BTN_DWN.bmp b/examples/qwin-gui/dpp-gui/Res/BTN_DWN.bmp similarity index 100% rename from examples/arm-cm/dpp_efm32-slstk3401a/win32-gui/Res/BTN_DWN.bmp rename to examples/qwin-gui/dpp-gui/Res/BTN_DWN.bmp diff --git a/examples/arm-cm/dpp_efm32-slstk3401a/win32-gui/Res/BTN_UP.bmp b/examples/qwin-gui/dpp-gui/Res/BTN_UP.bmp similarity index 100% rename from examples/arm-cm/dpp_efm32-slstk3401a/win32-gui/Res/BTN_UP.bmp rename to examples/qwin-gui/dpp-gui/Res/BTN_UP.bmp diff --git a/examples/arm-cm/dpp_efm32-slstk3401a/win32-gui/Res/eating.bmp b/examples/qwin-gui/dpp-gui/Res/eating.bmp similarity index 100% rename from examples/arm-cm/dpp_efm32-slstk3401a/win32-gui/Res/eating.bmp rename to examples/qwin-gui/dpp-gui/Res/eating.bmp diff --git a/examples/arm-cm/dpp_efm32-slstk3401a/win32-gui/Res/hungry.bmp b/examples/qwin-gui/dpp-gui/Res/hungry.bmp similarity index 100% rename from examples/arm-cm/dpp_efm32-slstk3401a/win32-gui/Res/hungry.bmp rename to examples/qwin-gui/dpp-gui/Res/hungry.bmp diff --git a/examples/arm-cm/dpp_efm32-slstk3401a/win32-gui/Res/qp.ico b/examples/qwin-gui/dpp-gui/Res/qp.ico similarity index 100% rename from examples/arm-cm/dpp_efm32-slstk3401a/win32-gui/Res/qp.ico rename to examples/qwin-gui/dpp-gui/Res/qp.ico diff --git a/examples/arm-cm/dpp_efm32-slstk3401a/win32-gui/Res/thinking.bmp b/examples/qwin-gui/dpp-gui/Res/thinking.bmp similarity index 100% rename from examples/arm-cm/dpp_efm32-slstk3401a/win32-gui/Res/thinking.bmp rename to examples/qwin-gui/dpp-gui/Res/thinking.bmp diff --git a/examples/arm-cm/dpp_efm32-slstk3401a/win32-gui/Resource.rc b/examples/qwin-gui/dpp-gui/Resource.rc similarity index 100% rename from examples/arm-cm/dpp_efm32-slstk3401a/win32-gui/Resource.rc rename to examples/qwin-gui/dpp-gui/Resource.rc diff --git a/examples/qwin-gui/dpp-gui/bsp.c b/examples/qwin-gui/dpp-gui/bsp.c new file mode 100644 index 00000000..dece3f0b --- /dev/null +++ b/examples/qwin-gui/dpp-gui/bsp.c @@ -0,0 +1,379 @@ +//============================================================================ +// Product: DPP example, Win32-GUI +// Last updated for version: 7.3.0 +// Date of the Last Update: 2023-08-21 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// This program is open source software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Alternatively, this program may be distributed and modified under the +// terms of Quantum Leaps commercial licenses, which expressly supersede +// the GNU General Public License and are specifically designed for +// licensees interested in retaining the proprietary status of their code. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Contact information: +// +// +//============================================================================ +#include "qpc.h" +#include "dpp.h" +#include "bsp.h" + +#include "qwin_gui.h" // QWIN GUI +#include "resource.h" // GUI resource IDs generated by the resource editior + +#include "safe_std.h" // portable "safe" / facilities + +Q_DEFINE_THIS_FILE + +// local variables --------------------------------------------------------- +static HINSTANCE l_hInst; // this application instance +static HWND l_hWnd; // main window handle +static LPSTR l_cmdLine; // the command line string + +static SegmentDisplay l_philos; // SegmentDisplay to show Philo status +static OwnerDrawnButton l_pauseBtn; // owner-drawn button + +static unsigned l_rnd; // random seed + +#ifdef Q_SPY + enum { + PHILO_STAT = QS_USER + }; + static uint8_t const l_clock_tick = 0U; +#endif + +//............................................................................ +Q_NORETURN Q_onError(char const * const module, int_t const id) { + char message[80]; + QF_stop(); // stop ticking + + QS_ASSERTION(module, id, 10000U); // report assertion to QS + SNPRINTF_S(message, Q_DIM(message) - 1U, + "Assertion failed in module %s location %d", module, id); + MessageBox(l_hWnd, message, "!!! ASSERTION !!!", + MB_OK | MB_ICONEXCLAMATION | MB_APPLMODAL); + PostQuitMessage(-1); +} +//............................................................................ +void assert_failed(char const * const module, int_t const id); // prototype +void assert_failed(char const * const module, int_t const id) { + Q_onError(module, id); +} + +// Local functions --------------------------------------------------------- +static LRESULT CALLBACK WndProc(HWND hWnd, UINT iMsg, + WPARAM wParam, LPARAM lParam); + +//............................................................................ +// thread function for running the application main_gui() +static DWORD WINAPI appThread(LPVOID par) { + (void)par; // unused parameter + return (DWORD)main_gui(); // run the QF application +} + +//---------------------------------------------------------------------------- +int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, + LPSTR cmdLine, int iCmdShow) +{ + HWND hWnd; + MSG msg; + + (void)hPrevInst; // unused parameter + + l_hInst = hInst; // save the application instance + l_cmdLine = cmdLine; // save the command line string + + //AllocConsole(); + + // create the main custom dialog window + hWnd = CreateCustDialog(hInst, IDD_APPLICATION, NULL, + &WndProc, "MY_CLASS"); + ShowWindow(hWnd, iCmdShow); // show the main window + + // enter the message loop... + while (GetMessage(&msg, NULL, 0, 0)) { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + + //FreeConsole(); + BSP_terminate(0); + + return msg.wParam; +} + +//............................................................................ +static LRESULT CALLBACK WndProc(HWND hWnd, UINT iMsg, + WPARAM wParam, LPARAM lParam) +{ + switch (iMsg) { + + // Perform initialization upon cration of the main dialog window + // NOTE: Any child-windows are NOT created yet at this time, so + // the GetDlgItem() function can't be used (it will return NULL). + // + case WM_CREATE: { + l_hWnd = hWnd; // save the window handle + + // initialize the owner-drawn buttons... + // NOTE: must be done *before* the first drawing of the buttons, + // so WM_INITDIALOG is too late. + // + OwnerDrawnButton_init(&l_pauseBtn, IDC_PAUSE, + LoadBitmap(l_hInst, MAKEINTRESOURCE(IDB_BTN_UP)), + LoadBitmap(l_hInst, MAKEINTRESOURCE(IDB_BTN_DWN)), + LoadCursor(NULL, IDC_HAND)); + return 0; + } + + // Perform initialization after all child windows have been created + case WM_INITDIALOG: { + + SegmentDisplay_init(&l_philos, + N_PHILO, // N_PHILO "segments" for the Philos + 3U); // 3 bitmaps (for thinking/hungry/eating) + SegmentDisplay_initSegment(&l_philos, 0U, IDC_PHILO_0); + SegmentDisplay_initSegment(&l_philos, 1U, IDC_PHILO_1); + SegmentDisplay_initSegment(&l_philos, 2U, IDC_PHILO_2); + SegmentDisplay_initSegment(&l_philos, 3U, IDC_PHILO_3); + SegmentDisplay_initSegment(&l_philos, 4U, IDC_PHILO_4); + SegmentDisplay_initBitmap(&l_philos, + 0U, LoadBitmap(l_hInst, MAKEINTRESOURCE(IDB_THINKING))); + SegmentDisplay_initBitmap(&l_philos, + 1U, LoadBitmap(l_hInst, MAKEINTRESOURCE(IDB_HUNGRY))); + SegmentDisplay_initBitmap(&l_philos, + 2U, LoadBitmap(l_hInst, MAKEINTRESOURCE(IDB_EATING))); + + // --> QP: spawn the application thread to run main_gui() + if (CreateThread(NULL, 0, &appThread, NULL, 0, NULL) + == (HANDLE)0) + { + Q_ERROR(); + } + SetDlgItemTextA(hWnd, IDC_EDIT1, "Edit1"); + SetDlgItemTextA(hWnd, IDC_EDIT2, "Edit2"); + return 0; + } + + case WM_DESTROY: { + PostQuitMessage(0); + return 0; + } + + // commands from child controls and menus... + case WM_COMMAND: { + switch (wParam) { + case IDOK: + case IDCANCEL: { + PostQuitMessage(0); + break; + } + case IDC_PAUSE: { // owner-drawn button(s) + SetFocus(hWnd); + break; + } + case IDC_BUTTON1: { // regular button + char buf[32]; + GetDlgItemTextA(hWnd, IDC_EDIT1, buf, sizeof(buf)); + SetDlgItemTextA(hWnd, IDC_EDIT2, buf); + break; + } + } + return 0; + } + + // drawing of owner-drawn buttons... + case WM_DRAWITEM: { + LPDRAWITEMSTRUCT pdis = (LPDRAWITEMSTRUCT)lParam; + switch (pdis->CtlID) { + case IDC_PAUSE: { // PAUSE owner-drawn button + switch (OwnerDrawnButton_draw(&l_pauseBtn,pdis)) { + case BTN_DEPRESSED: { + static QEvt const pe = QEVT_INITIALIZER( PAUSE_SIG); + QACTIVE_POST(AO_Table, &pe, (void *)0); + break; + } + case BTN_RELEASED: { + static QEvt const se = QEVT_INITIALIZER(SERVE_SIG); + QACTIVE_POST(AO_Table, &se, (void *)0); + break; + } + default: { + break; + } + } + break; + } + } + return 0; + } + + // mouse input... + case WM_MOUSEWHEEL: { + return 0; + } + + // keyboard input... + case WM_KEYDOWN: { + return 0; + } + } + return DefWindowProc(hWnd, iMsg, wParam, lParam) ; +} +//............................................................................ +void QF_onStartup(void) { + QF_setTickRate(BSP_TICKS_PER_SEC, 30); // set the desired tick rate +} +//............................................................................ +void QF_onCleanup(void) { +} +//............................................................................ +void QF_onClockTick(void) { + QTIMEEVT_TICK_X(0U, &l_clock_tick); // QF clock tick processing + + QS_RX_INPUT(); // handle the QS-RX input + QS_OUTPUT(); // handle the QS output +} + +//............................................................................ +void BSP_init(void) { + if (!QS_INIT(l_cmdLine)) { // QS initialization failed? + MessageBox(l_hWnd, + "Cannot connect to QSPY via TCP/IP\n" + "Please make sure that 'qspy -t' is running", + "QS_INIT() Error", + MB_OK | MB_ICONEXCLAMATION | MB_APPLMODAL); + } + + // send the QS dictionaries... + QS_OBJ_DICTIONARY(&l_clock_tick); + QS_USR_DICTIONARY(PHILO_STAT); + + // setup the QS filters... + QS_GLB_FILTER(QS_ALL_RECORDS); + QS_GLB_FILTER(-QS_QF_TICK); +} +//............................................................................ +void BSP_start(void) { + // initialize event pools + static QF_MPOOL_EL(TableEvt) smlPoolSto[2*N_PHILO]; + QF_poolInit(smlPoolSto, sizeof(smlPoolSto), sizeof(smlPoolSto[0])); + + // initialize publish-subscribe + static QSubscrList subscrSto[MAX_PUB_SIG]; + QActive_psInit(subscrSto, Q_DIM(subscrSto)); + + // instantiate and start AOs/threads... + + static QEvt const *philoQueueSto[N_PHILO][10]; + for (uint8_t n = 0U; n < N_PHILO; ++n) { + Philo_ctor(n); + QACTIVE_START(AO_Philo[n], + n + 3U, // QF-prio/pthre. see NOTE1 + philoQueueSto[n], // event queue storage + Q_DIM(philoQueueSto[n]), // queue length [events] + (void *)0, 0U, // no stack storage + (void *)0); // no initialization param + } + + static QEvt const *tableQueueSto[N_PHILO]; + Table_ctor(); + QACTIVE_START(AO_Table, + N_PHILO + 7U, // QP prio. of the AO + tableQueueSto, // event queue storage + Q_DIM(tableQueueSto), // queue length [events] + (void *)0, 0U, // no stack storage + (void *)0); // no initialization param +} +//............................................................................ +void BSP_terminate(int16_t result) { + QF_stop(); // stop the main QF application + + // cleanup all QWIN resources... + OwnerDrawnButton_xtor(&l_pauseBtn); // cleanup the l_pauseBtn resources + SegmentDisplay_xtor(&l_philos); // cleanup the l_philos resources + + // end the main dialog + EndDialog(l_hWnd, result); +} +//............................................................................ +void BSP_displayPhilStat(uint8_t n, char const *stat) { + UINT bitmapNum = 0; + + Q_REQUIRE(n < N_PHILO); + + switch (stat[0]) { + case 't': bitmapNum = 0U; break; + case 'h': bitmapNum = 1U; break; + case 'e': bitmapNum = 2U; break; + default: Q_ERROR(); break; + } + // set the "segment" # n to the bitmap # 'bitmapNum' + SegmentDisplay_setSegment(&l_philos, (UINT)n, bitmapNum); + + QS_BEGIN_ID(PHILO_STAT, AO_Philo[n]->prio) // app-specific record + QS_U8(1, n); // Philosopher number + QS_STR(stat); // Philosopher status + QS_END() +} +//............................................................................ +void BSP_displayPaused(uint8_t paused) { + char buf[16]; + LoadString(l_hInst, + (paused != 0U) ? IDS_PAUSED : IDS_RUNNING, buf, Q_DIM(buf)); + SetDlgItemText(l_hWnd, IDC_PAUSED, buf); +} +//............................................................................ +uint32_t BSP_random(void) { // a very cheap pseudo-random-number generator + // "Super-Duper" Linear Congruential Generator (LCG) + // LCG(2^32, 3*7*11*13*23, 0, seed) + // + l_rnd = l_rnd * (3U*7U*11U*13U*23U); + return l_rnd >> 8; +} +//............................................................................ +void BSP_randomSeed(uint32_t seed) { + l_rnd = seed; +} + + +//---------------------------------------------------------------------------- +#ifdef Q_SPY // define QS callbacks + +//! callback function to execute user commands +void QS_onCommand(uint8_t cmdId, + uint32_t param1, uint32_t param2, uint32_t param3) +{ + switch (cmdId) { + case 0U: { + break; + } + default: + break; + } + + // unused parameters + (void)param1; + (void)param2; + (void)param3; +} + +#endif // Q_SPY +//---------------------------------------------------------------------------- diff --git a/examples/qwin-gui/dpp-gui/bsp.h b/examples/qwin-gui/dpp-gui/bsp.h new file mode 100644 index 00000000..da73dbfd --- /dev/null +++ b/examples/qwin-gui/dpp-gui/bsp.h @@ -0,0 +1,49 @@ +//============================================================================ +// Product: Board Support Package example +// Last Updated for Version: 7.3.0 +// Date of the Last Update: 2023-08-12 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +//============================================================================ +#ifndef BSP_H_ +#define BSP_H_ + +#define BSP_TICKS_PER_SEC 100U + +void BSP_init(void); +void BSP_start(void); +void BSP_displayPaused(uint8_t paused); +void BSP_displayPhilStat(uint8_t n, char const *stat); +void BSP_terminate(int16_t result); + +void BSP_randomSeed(uint32_t seed); // random seed +uint32_t BSP_random(void); // pseudo-random generator + +void BSP_ledOn(void); +void BSP_ledOff(void); + +#endif // BSP_H_ diff --git a/examples/arm-cm/dpp_efm32-slstk3401a/win32-gui/dpp-gui.sln b/examples/qwin-gui/dpp-gui/dpp-gui.sln similarity index 85% rename from examples/arm-cm/dpp_efm32-slstk3401a/win32-gui/dpp-gui.sln rename to examples/qwin-gui/dpp-gui/dpp-gui.sln index cf9de4da..4e30c6e7 100644 --- a/examples/arm-cm/dpp_efm32-slstk3401a/win32-gui/dpp-gui.sln +++ b/examples/qwin-gui/dpp-gui/dpp-gui.sln @@ -7,14 +7,11 @@ EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Win32 = Debug|Win32 - QSpy|Win32 = QSpy|Win32 Release|Win32 = Release|Win32 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {79027B25-0949-4F66-9765-4EFBCBBEFB94}.Debug|Win32.ActiveCfg = Debug|Win32 {79027B25-0949-4F66-9765-4EFBCBBEFB94}.Debug|Win32.Build.0 = Debug|Win32 - {79027B25-0949-4F66-9765-4EFBCBBEFB94}.QSpy|Win32.ActiveCfg = Release|Win32 - {79027B25-0949-4F66-9765-4EFBCBBEFB94}.QSpy|Win32.Build.0 = Release|Win32 {79027B25-0949-4F66-9765-4EFBCBBEFB94}.Release|Win32.ActiveCfg = Release|Win32 {79027B25-0949-4F66-9765-4EFBCBBEFB94}.Release|Win32.Build.0 = Release|Win32 EndGlobalSection diff --git a/examples/arm-cm/dpp_efm32-slstk3401a/win32-gui/dpp-gui.vcxproj b/examples/qwin-gui/dpp-gui/dpp-gui.vcxproj similarity index 84% rename from examples/arm-cm/dpp_efm32-slstk3401a/win32-gui/dpp-gui.vcxproj rename to examples/qwin-gui/dpp-gui/dpp-gui.vcxproj index 98cb9087..cec81850 100644 --- a/examples/arm-cm/dpp_efm32-slstk3401a/win32-gui/dpp-gui.vcxproj +++ b/examples/qwin-gui/dpp-gui/dpp-gui.vcxproj @@ -64,7 +64,7 @@ MaxSpeed OnlyExplicitInline - .;..;../../../../include;../../../../ports/win32-qv;%(AdditionalIncludeDirectories) + .;../../../include;../../../ports/win32-qv;%(AdditionalIncludeDirectories) NDEBUG;QWIN_GUI;_WINDOWS;%(PreprocessorDefinitions) false @@ -79,6 +79,7 @@ Level3 true Default + stdc11 NDEBUG;%(PreprocessorDefinitions) @@ -115,7 +116,7 @@ Disabled - .;..;../../../../include;../../../../ports/win32-qv;%(AdditionalIncludeDirectories) + .;../../../include;../../../ports/win32-qv;%(AdditionalIncludeDirectories) QWIN_GUI;_DEBUG;_WINDOWS;%(PreprocessorDefinitions) false @@ -134,6 +135,7 @@ Default + stdc11 _DEBUG;%(PreprocessorDefinitions) @@ -163,46 +165,46 @@ - - + + true true - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + %(AdditionalIncludeDirectories) %(PreprocessorDefinitions) %(AdditionalIncludeDirectories) %(PreprocessorDefinitions) - - - - - - - - + + + + + + + - + @@ -217,4 +219,4 @@ - \ No newline at end of file +
diff --git a/examples/arm-cm/dpp_efm32-slstk3401a/win32-gui/dpp-gui.vcxproj.filters b/examples/qwin-gui/dpp-gui/dpp-gui.vcxproj.filters similarity index 98% rename from examples/arm-cm/dpp_efm32-slstk3401a/win32-gui/dpp-gui.vcxproj.filters rename to examples/qwin-gui/dpp-gui/dpp-gui.vcxproj.filters index 6701200d..8f77ed35 100644 --- a/examples/arm-cm/dpp_efm32-slstk3401a/win32-gui/dpp-gui.vcxproj.filters +++ b/examples/qwin-gui/dpp-gui/dpp-gui.vcxproj.filters @@ -4,7 +4,6 @@ - QP_port @@ -50,6 +49,7 @@ QP + diff --git a/examples/qwin-gui/dpp-gui/dpp.h b/examples/qwin-gui/dpp-gui/dpp.h new file mode 100644 index 00000000..e6d1557a --- /dev/null +++ b/examples/qwin-gui/dpp-gui/dpp.h @@ -0,0 +1,117 @@ +//$file${.::dpp.h} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// +// Model: dpp.qm +// File: ${.::dpp.h} +// +// This code has been generated by QM 5.3.0 . +// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. +// +// SPDX-License-Identifier: GPL-3.0-or-later +// +// This generated code is open source software: you can redistribute it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation. +// +// This code is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// NOTE: +// Alternatively, this generated code may be distributed under the terms +// of Quantum Leaps commercial licenses, which expressly supersede the GNU +// General Public License and are specifically designed for licensees +// interested in retaining the proprietary status of their code. +// +// Contact information: +// +// +// +//$endhead${.::dpp.h} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +#ifndef DPP_H_ +#define DPP_H_ + +//$declare${Shared} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${Shared::AppSignals} ...................................................... +enum AppSignals { + EAT_SIG = Q_USER_SIG, // published by Table to let a Philo eat + DONE_SIG, // published by Philo when done eating + PAUSE_SIG, // published by BSP to pause the application + SERVE_SIG, // published by BSP to serve re-start serving forks + TEST_SIG, // published by BSP to test the application + MAX_PUB_SIG, // the last published signal + + TIMEOUT_SIG, // posted by time event to Philo + HUNGRY_SIG, // posted by hungry Philo to Table + MAX_SIG // the last signal +}; + +//${Shared::produce_sig_dict} ................................................ +#ifdef Q_SPY +static inline void produce_sig_dict(void) { + QS_SIG_DICTIONARY(EAT_SIG, (void *)0); + QS_SIG_DICTIONARY(DONE_SIG, (void *)0); + QS_SIG_DICTIONARY(PAUSE_SIG, (void *)0); + QS_SIG_DICTIONARY(SERVE_SIG, (void *)0); + QS_SIG_DICTIONARY(TEST_SIG, (void *)0); + + QS_SIG_DICTIONARY(TIMEOUT_SIG, (void *)0); + QS_SIG_DICTIONARY(HUNGRY_SIG, (void *)0); +} +#endif // def Q_SPY + +//${Shared::N_PHILO} ......................................................... +#define N_PHILO ((uint8_t)5U) + +//${Shared::TableEvt} ........................................................ +typedef struct { +// protected: + QEvt super; + +// public: + uint8_t philoId; +} TableEvt; + +// public: + +#ifdef QEVT_DYN_CTOR +static inline TableEvt * TableEvt_ctor(TableEvt * const me, + uint8_t id) +{ + if (me != (TableEvt *)0) { + // don't call QEvt_ctor() because the initialization of all + // QEvt attributes is already done in QF_QF_newX_() + me->philoId = id; + } + return me; +} +#endif // def QEVT_DYN_CTOR + +//${Shared::AO_Philo[N_PHILO]} ............................................... +extern QActive * const AO_Philo[N_PHILO]; + +//${Shared::Philo_ctor} ...................................................... +void Philo_ctor(uint_fast8_t const id); + +//${Shared::AO_Table} ........................................................ +extern QActive * const AO_Table; + +//${Shared::Table_ctor} ...................................................... +void Table_ctor(void); +//$enddecl${Shared} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +#ifdef QXK_H_ + +extern QXThread * const TH_XThread1; +void XThread1_ctor(void); + +extern QXThread * const TH_XThread2; +void XThread2_ctor(void); + +extern QXSemaphore TH_sema; +extern QXMutex TH_mutex; + +#endif // QXK_H_ + +#endif // DPP_H_ diff --git a/examples/qwin-gui/dpp-gui/dpp.qm b/examples/qwin-gui/dpp-gui/dpp.qm new file mode 100644 index 00000000..ac9f2bc9 --- /dev/null +++ b/examples/qwin-gui/dpp-gui/dpp.qm @@ -0,0 +1,525 @@ + + + Dining Philosopher Problem example + + + + + + + { + EAT_SIG = Q_USER_SIG, // published by Table to let a Philo eat + DONE_SIG, // published by Philo when done eating + PAUSE_SIG, // published by BSP to pause the application + SERVE_SIG, // published by BSP to serve re-start serving forks + TEST_SIG, // published by BSP to test the application + MAX_PUB_SIG, // the last published signal + + TIMEOUT_SIG, // posted by time event to Philo + HUNGRY_SIG, // posted by hungry Philo to Table + MAX_SIG // the last signal +}; + + + + QS_SIG_DICTIONARY(EAT_SIG, (void *)0); +QS_SIG_DICTIONARY(DONE_SIG, (void *)0); +QS_SIG_DICTIONARY(PAUSE_SIG, (void *)0); +QS_SIG_DICTIONARY(SERVE_SIG, (void *)0); +QS_SIG_DICTIONARY(TEST_SIG, (void *)0); + +QS_SIG_DICTIONARY(TIMEOUT_SIG, (void *)0); +QS_SIG_DICTIONARY(HUNGRY_SIG, (void *)0); + + + + ((uint8_t)5U) + + + + + + + + + + if (me != (TableEvt *)0) { + // don't call QEvt_ctor() because the initialization of all + // QEvt attributes is already done in QF_QF_newX_() + me->philoId = id; +} +return me; + + + + + = { + &Philo_inst[0].super, + &Philo_inst[1].super, + &Philo_inst[2].super, + &Philo_inst[3].super, + &Philo_inst[4].super +}; + + + + + + Philo * const me = &Philo_inst[id]; +QActive_ctor(&me->super, Q_STATE_CAST(&Philo_initial)); +QTimeEvt_ctorX(&me->timeEvt, &me->super, TIMEOUT_SIG, 0U), +me->id = (uint8_t)id; + + + + = &Table_inst.super; + + + + Table * const me = &Table_inst; +QActive_ctor(&me->super, Q_STATE_CAST(&Table_initial)); +for (uint8_t n = 0U; n < N_PHILO; ++n) { + me->fork[n] = FREE; + me->isHungry[n] = false; +} + + + + + + + The Philo AO and the N_PHILO instances + + + + + + + + + + + Q_UNUSED_PAR(par); + +QS_OBJ_ARR_DICTIONARY(&Philo_inst[me->id], me->id); +QS_OBJ_ARR_DICTIONARY(&Philo_inst[me->id].timeEvt, me->id); + +QActive_subscribe(&me->super, EAT_SIG); +QActive_subscribe(&me->super, TEST_SIG); + + + + + + + QTimeEvt_armX(&me->timeEvt, think_time(), 0U); + (void)QTimeEvt_disarm(&me->timeEvt); + + + + + + + + + // EAT or DONE must be for other Philos than this one +Q_ASSERT(Q_EVT_CAST(TableEvt)->philoId != me->id); + + + + + + + + + + + + + + + + + + #ifdef QEVT_DYN_CTOR +TableEvt const *pe = Q_NEW(TableEvt, HUNGRY_SIG, me->id); +#else +TableEvt *pe = Q_NEW(TableEvt, HUNGRY_SIG); +pe->philoId = me->id; +#endif +QACTIVE_POST(AO_Table, &pe->super, &me->super); + + + + + Q_EVT_CAST(TableEvt)->philoId == me->id + + + + + + + + + + + // DONE must be for other Philos than this one +Q_ASSERT(Q_EVT_CAST(TableEvt)->philoId != me->id); + + + + + + + + + + + QTimeEvt_armX(&me->timeEvt, eat_time(), 0U); + (void)QTimeEvt_disarm(&me->timeEvt); + +#ifdef QEVT_DYN_CTOR +TableEvt const *pe = Q_NEW(TableEvt, DONE_SIG, me->id); +#else +TableEvt *pe = Q_NEW(TableEvt, DONE_SIG); +pe->philoId = me->id; +#endif +QACTIVE_PUBLISH(&pe->super, &me->super); + + + + + + + + + // EAT or DONE must be for other Philos than this one +Q_ASSERT(Q_EVT_CAST(TableEvt)->philoId != me->id); + + + + + + + + + + + + + + + + + + + + + + + + + Q_UNUSED_PAR(par); + +#ifdef Q_SPY +Table *Table_inst = me; +QS_OBJ_DICTIONARY(Table_inst); +#endif + +QActive_subscribe(&me->super, DONE_SIG); +QActive_subscribe(&me->super, PAUSE_SIG); +QActive_subscribe(&me->super, SERVE_SIG); +QActive_subscribe(&me->super, TEST_SIG); + +for (uint8_t n = 0U; n < N_PHILO; ++n) { + me->fork[n] = FREE; + me->isHungry[n] = false; + BSP_displayPhilStat(n, THINKING); +} + + + + + + + + + + + + + + + Q_ERROR(); + + + + + + + // give permissions to eat... +for (uint8_t n = 0U; n < N_PHILO; ++n) { + if (me->isHungry[n] + && (me->fork[left(n)] == FREE) + && (me->fork[n] == FREE)) + { + me->fork[left(n)] = USED; + me->fork[n] = USED; +#ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, EAT_SIG, n); +#else + TableEvt *pe = Q_NEW(TableEvt, EAT_SIG); + pe->philoId = n; +#endif + QACTIVE_PUBLISH(&pe->super, &me->super); + me->isHungry[n] = false; + BSP_displayPhilStat(n, EATING); + } +} + + + uint8_t n = Q_EVT_CAST(TableEvt)->philoId; + +// phil ID must be in range and he must be not hungry +Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); + +BSP_displayPhilStat(n, HUNGRY); +uint8_t m = left(n); + + + (me->fork[m] == FREE) && (me->fork[n] == FREE) + me->fork[m] = USED; +me->fork[n] = USED; +#ifdef QEVT_DYN_CTOR +TableEvt const *pe = Q_NEW(TableEvt, EAT_SIG, n); +#else +TableEvt *pe = Q_NEW(TableEvt, EAT_SIG); +pe->philoId = n; +#endif +QACTIVE_PUBLISH(&pe->super, &me->super); +BSP_displayPhilStat(n, EATING); + + + + + + + else + me->isHungry[n] = true; + + + + + + + + + + + uint8_t n = Q_EVT_CAST(TableEvt)->philoId; + +// phil ID must be in range and he must be not hungry +Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); + +BSP_displayPhilStat(n, THINKING); +uint8_t m = left(n); + +// both forks of Phil[n] must be used +Q_ASSERT((me->fork[n] == USED) && (me->fork[m] == USED)); + +me->fork[m] = FREE; +me->fork[n] = FREE; +m = right(n); // check the right neighbor + +if (me->isHungry[m] && (me->fork[m] == FREE)) { + me->fork[n] = USED; + me->fork[m] = USED; + me->isHungry[m] = false; +#ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, EAT_SIG, m); +#else + TableEvt *pe = Q_NEW(TableEvt, EAT_SIG); + pe->philoId = m; +#endif + QACTIVE_PUBLISH(&pe->super, &me->super); + BSP_displayPhilStat(m, EATING); +} +m = left(n); // check the left neighbor +n = left(m); // left fork of the left neighbor +if (me->isHungry[m] && (me->fork[n] == FREE)) { + me->fork[m] = USED; + me->fork[n] = USED; + me->isHungry[m] = false; +#ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, EAT_SIG, m); +#else + TableEvt *pe = Q_NEW(TableEvt, EAT_SIG); + pe->philoId = m; +#endif + QACTIVE_PUBLISH(&pe->super, &me->super); + BSP_displayPhilStat(m, EATING); +} + + + + + + + Q_ERROR(); + + + + + + + + + + + + + + + + + BSP_displayPaused(1U); + BSP_displayPaused(0U); + + + + + + + + + uint8_t n = Q_EVT_CAST(TableEvt)->philoId; + +// philo ID must be in range and he must be not hungry +Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); + +me->isHungry[n] = true; +BSP_displayPhilStat(n, HUNGRY); + + + + + + + uint8_t n = Q_EVT_CAST(TableEvt)->philoId; + +// phil ID must be in range and he must be not hungry +Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); + +BSP_displayPhilStat(n, THINKING); +uint8_t m = left(n); + +// both forks of Phil[n] must be used +Q_ASSERT((me->fork[n] == USED) && (me->fork[m] == USED)); + +me->fork[m] = FREE; +me->fork[n] = FREE; + + + + + + + + + + + + + + + + + + + + #ifndef DPP_H_ +#define DPP_H_ + +$declare ${Shared} + +#ifdef QXK_H_ + +extern QXThread * const TH_XThread1; +void XThread1_ctor(void); + +extern QXThread * const TH_XThread2; +void XThread2_ctor(void); + +extern QXSemaphore TH_sema; +extern QXMutex TH_mutex; + +#endif // QXK_H_ + +#endif // DPP_H_ + + + + #include "qpc.h" // QP/C real-time embedded framework +#include "dpp.h" // DPP Application interface +#include "bsp.h" // Board Support Package + +$declare ${AOs::Philo} + +//---------------------------------------------------------------------------- +Q_DEFINE_THIS_FILE + +// helper function to provide a randomized think time for Philos +static QTimeEvtCtr think_time(void); // prototype +static inline QTimeEvtCtr think_time(void) { + return (QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + + (BSP_TICKS_PER_SEC/2U)); +} + +// helper function to provide a randomized eat time for Philos +static QTimeEvtCtr eat_time(void); // prototype +static inline QTimeEvtCtr eat_time(void) { + return (QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + + BSP_TICKS_PER_SEC); +} +//---------------------------------------------------------------------------- + +$define ${Shared::Philo_ctor} +$define ${Shared::AO_Philo[N_PHILO]} +$define ${AOs::Philo} + + + + #include "qpc.h" // QP/C real-time embedded framework +#include "dpp.h" // DPP Application interface +#include "bsp.h" // Board Support Package + +$declare ${AOs::Table} + +//---------------------------------------------------------------------------- +Q_DEFINE_THIS_FILE + +// helper function to provide the RIGHT neighbor of a Philo[n] +static inline uint8_t right(uint8_t const n) { + return (uint8_t)((n + (N_PHILO - 1U)) % N_PHILO); +} + +// helper function to provide the LEFT neighbor of a Philo[n] +static inline uint8_t left(uint8_t const n) { + return (uint8_t)((n + 1U) % N_PHILO); +} + +#define FREE ((uint8_t)0U) +#define USED ((uint8_t)1U) + +#define THINKING "thinking" +#define HUNGRY "hungry " +#define EATING "eating " + +//---------------------------------------------------------------------------- + +$define ${Shared::Table_ctor} +$define ${Shared::AO_Table} +$define ${AOs::Table} + + + diff --git a/examples/qwin-gui/dpp-gui/main.c b/examples/qwin-gui/dpp-gui/main.c new file mode 100644 index 00000000..cfcfaf07 --- /dev/null +++ b/examples/qwin-gui/dpp-gui/main.c @@ -0,0 +1,44 @@ +//============================================================================ +// APP example +// Last updated for version 7.3.0 +// Last updated on 2023-08-09 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. +// +// This program is open source software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Alternatively, this program may be distributed and modified under the +// terms of Quantum Leaps commercial licenses, which expressly supersede +// the GNU General Public License and are specifically designed for +// licensees interested in retaining the proprietary status of their code. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Contact information: +// +// +//============================================================================ +#include "qpc.h" // QP/C real-time embedded framework +#include "dpp.h" // DPP Application interface +#include "bsp.h" // Board Support Package + +//............................................................................ +int main() { + QF_init(); // initialize the framework and the underlying RT kernel + BSP_init(); // initialize the BSP + BSP_start(); // start the AOs/Threads + return QF_run(); // run the QF application +} diff --git a/examples/qwin-gui/dpp-gui/philo.c b/examples/qwin-gui/dpp-gui/philo.c new file mode 100644 index 00000000..eb6be531 --- /dev/null +++ b/examples/qwin-gui/dpp-gui/philo.c @@ -0,0 +1,255 @@ +//$file${.::philo.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// +// Model: dpp.qm +// File: ${.::philo.c} +// +// This code has been generated by QM 5.3.0 . +// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. +// +// SPDX-License-Identifier: GPL-3.0-or-later +// +// This generated code is open source software: you can redistribute it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation. +// +// This code is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// NOTE: +// Alternatively, this generated code may be distributed under the terms +// of Quantum Leaps commercial licenses, which expressly supersede the GNU +// General Public License and are specifically designed for licensees +// interested in retaining the proprietary status of their code. +// +// Contact information: +// +// +// +//$endhead${.::philo.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +#include "qpc.h" // QP/C real-time embedded framework +#include "dpp.h" // DPP Application interface +#include "bsp.h" // Board Support Package + +//$declare${AOs::Philo} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${AOs::Philo} .............................................................. +typedef struct Philo { +// protected: + QActive super; + +// private: + QTimeEvt timeEvt; + uint8_t id; + +// public: +} Philo; + +extern Philo Philo_inst[N_PHILO]; + +// protected: +static QState Philo_initial(Philo * const me, void const * const par); +static QState Philo_thinking(Philo * const me, QEvt const * const e); +static QState Philo_hungry(Philo * const me, QEvt const * const e); +static QState Philo_eating(Philo * const me, QEvt const * const e); +//$enddecl${AOs::Philo} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +//---------------------------------------------------------------------------- +Q_DEFINE_THIS_FILE + +// helper function to provide a randomized think time for Philos +static QTimeEvtCtr think_time(void); // prototype +static inline QTimeEvtCtr think_time(void) { + return (QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + + (BSP_TICKS_PER_SEC/2U)); +} + +// helper function to provide a randomized eat time for Philos +static QTimeEvtCtr eat_time(void); // prototype +static inline QTimeEvtCtr eat_time(void) { + return (QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + + BSP_TICKS_PER_SEC); +} +//---------------------------------------------------------------------------- + +//$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// Check for the minimum required QP version +#if (QP_VERSION < 730U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) +#error qpc version 7.3.0 or higher required +#endif +//$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +//$define${Shared::Philo_ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${Shared::Philo_ctor} ...................................................... +void Philo_ctor(uint_fast8_t const id) { + Philo * const me = &Philo_inst[id]; + QActive_ctor(&me->super, Q_STATE_CAST(&Philo_initial)); + QTimeEvt_ctorX(&me->timeEvt, &me->super, TIMEOUT_SIG, 0U), + me->id = (uint8_t)id; +} +//$enddef${Shared::Philo_ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +//$define${Shared::AO_Philo[N_PHILO]} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${Shared::AO_Philo[N_PHILO]} ............................................... +QActive * const AO_Philo[N_PHILO] = { + &Philo_inst[0].super, + &Philo_inst[1].super, + &Philo_inst[2].super, + &Philo_inst[3].super, + &Philo_inst[4].super +}; +//$enddef${Shared::AO_Philo[N_PHILO]} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +//$define${AOs::Philo} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${AOs::Philo} .............................................................. +Philo Philo_inst[N_PHILO]; + +//${AOs::Philo::SM} .......................................................... +static QState Philo_initial(Philo * const me, void const * const par) { + //${AOs::Philo::SM::initial} + Q_UNUSED_PAR(par); + + QS_OBJ_ARR_DICTIONARY(&Philo_inst[me->id], me->id); + QS_OBJ_ARR_DICTIONARY(&Philo_inst[me->id].timeEvt, me->id); + + QActive_subscribe(&me->super, EAT_SIG); + QActive_subscribe(&me->super, TEST_SIG); + + QS_FUN_DICTIONARY(&Philo_thinking); + QS_FUN_DICTIONARY(&Philo_hungry); + QS_FUN_DICTIONARY(&Philo_eating); + + return Q_TRAN(&Philo_thinking); +} + +//${AOs::Philo::SM::thinking} ................................................ +static QState Philo_thinking(Philo * const me, QEvt const * const e) { + QState status_; + switch (e->sig) { + //${AOs::Philo::SM::thinking} + case Q_ENTRY_SIG: { + QTimeEvt_armX(&me->timeEvt, think_time(), 0U); + status_ = Q_HANDLED(); + break; + } + //${AOs::Philo::SM::thinking} + case Q_EXIT_SIG: { + (void)QTimeEvt_disarm(&me->timeEvt); + status_ = Q_HANDLED(); + break; + } + //${AOs::Philo::SM::thinking::TIMEOUT} + case TIMEOUT_SIG: { + status_ = Q_TRAN(&Philo_hungry); + break; + } + //${AOs::Philo::SM::thinking::EAT, DONE} + case EAT_SIG: // intentionally fall through + case DONE_SIG: { + // EAT or DONE must be for other Philos than this one + Q_ASSERT(Q_EVT_CAST(TableEvt)->philoId != me->id); + status_ = Q_HANDLED(); + break; + } + //${AOs::Philo::SM::thinking::TEST} + case TEST_SIG: { + status_ = Q_HANDLED(); + break; + } + default: { + status_ = Q_SUPER(&QHsm_top); + break; + } + } + return status_; +} + +//${AOs::Philo::SM::hungry} .................................................. +static QState Philo_hungry(Philo * const me, QEvt const * const e) { + QState status_; + switch (e->sig) { + //${AOs::Philo::SM::hungry} + case Q_ENTRY_SIG: { + #ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, HUNGRY_SIG, me->id); + #else + TableEvt *pe = Q_NEW(TableEvt, HUNGRY_SIG); + pe->philoId = me->id; + #endif + QACTIVE_POST(AO_Table, &pe->super, &me->super); + status_ = Q_HANDLED(); + break; + } + //${AOs::Philo::SM::hungry::EAT} + case EAT_SIG: { + //${AOs::Philo::SM::hungry::EAT::[e->philoId==me->iid]} + if (Q_EVT_CAST(TableEvt)->philoId == me->id) { + status_ = Q_TRAN(&Philo_eating); + } + else { + status_ = Q_UNHANDLED(); + } + break; + } + //${AOs::Philo::SM::hungry::DONE} + case DONE_SIG: { + // DONE must be for other Philos than this one + Q_ASSERT(Q_EVT_CAST(TableEvt)->philoId != me->id); + status_ = Q_HANDLED(); + break; + } + default: { + status_ = Q_SUPER(&QHsm_top); + break; + } + } + return status_; +} + +//${AOs::Philo::SM::eating} .................................................. +static QState Philo_eating(Philo * const me, QEvt const * const e) { + QState status_; + switch (e->sig) { + //${AOs::Philo::SM::eating} + case Q_ENTRY_SIG: { + QTimeEvt_armX(&me->timeEvt, eat_time(), 0U); + status_ = Q_HANDLED(); + break; + } + //${AOs::Philo::SM::eating} + case Q_EXIT_SIG: { + (void)QTimeEvt_disarm(&me->timeEvt); + + #ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, DONE_SIG, me->id); + #else + TableEvt *pe = Q_NEW(TableEvt, DONE_SIG); + pe->philoId = me->id; + #endif + QACTIVE_PUBLISH(&pe->super, &me->super); + status_ = Q_HANDLED(); + break; + } + //${AOs::Philo::SM::eating::TIMEOUT} + case TIMEOUT_SIG: { + status_ = Q_TRAN(&Philo_thinking); + break; + } + //${AOs::Philo::SM::eating::EAT, DONE} + case EAT_SIG: // intentionally fall through + case DONE_SIG: { + // EAT or DONE must be for other Philos than this one + Q_ASSERT(Q_EVT_CAST(TableEvt)->philoId != me->id); + status_ = Q_HANDLED(); + break; + } + default: { + status_ = Q_SUPER(&QHsm_top); + break; + } + } + return status_; +} +//$enddef${AOs::Philo} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/examples/arm-cm/dpp_efm32-slstk3401a/win32-gui/resource.h b/examples/qwin-gui/dpp-gui/resource.h similarity index 100% rename from examples/arm-cm/dpp_efm32-slstk3401a/win32-gui/resource.h rename to examples/qwin-gui/dpp-gui/resource.h diff --git a/examples/qwin-gui/dpp-gui/table.c b/examples/qwin-gui/dpp-gui/table.c new file mode 100644 index 00000000..c3ae02f0 --- /dev/null +++ b/examples/qwin-gui/dpp-gui/table.c @@ -0,0 +1,343 @@ +//$file${.::table.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// +// Model: dpp.qm +// File: ${.::table.c} +// +// This code has been generated by QM 5.3.0 . +// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. +// +// SPDX-License-Identifier: GPL-3.0-or-later +// +// This generated code is open source software: you can redistribute it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation. +// +// This code is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// NOTE: +// Alternatively, this generated code may be distributed under the terms +// of Quantum Leaps commercial licenses, which expressly supersede the GNU +// General Public License and are specifically designed for licensees +// interested in retaining the proprietary status of their code. +// +// Contact information: +// +// +// +//$endhead${.::table.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +#include "qpc.h" // QP/C real-time embedded framework +#include "dpp.h" // DPP Application interface +#include "bsp.h" // Board Support Package + +//$declare${AOs::Table} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${AOs::Table} .............................................................. +typedef struct Table { +// protected: + QActive super; + +// private: + uint8_t fork[N_PHILO]; + bool isHungry[N_PHILO]; + +// public: +} Table; + +extern Table Table_inst; + +// protected: +static QState Table_initial(Table * const me, void const * const par); +static QState Table_active(Table * const me, QEvt const * const e); +static QState Table_serving(Table * const me, QEvt const * const e); +static QState Table_paused(Table * const me, QEvt const * const e); +//$enddecl${AOs::Table} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +//---------------------------------------------------------------------------- +Q_DEFINE_THIS_FILE + +// helper function to provide the RIGHT neighbor of a Philo[n] +static inline uint8_t right(uint8_t const n) { + return (uint8_t)((n + (N_PHILO - 1U)) % N_PHILO); +} + +// helper function to provide the LEFT neighbor of a Philo[n] +static inline uint8_t left(uint8_t const n) { + return (uint8_t)((n + 1U) % N_PHILO); +} + +#define FREE ((uint8_t)0U) +#define USED ((uint8_t)1U) + +#define THINKING "thinking" +#define HUNGRY "hungry " +#define EATING "eating " + +//---------------------------------------------------------------------------- + +//$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// Check for the minimum required QP version +#if (QP_VERSION < 730U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) +#error qpc version 7.3.0 or higher required +#endif +//$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +//$define${Shared::Table_ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${Shared::Table_ctor} ...................................................... +void Table_ctor(void) { + Table * const me = &Table_inst; + QActive_ctor(&me->super, Q_STATE_CAST(&Table_initial)); + for (uint8_t n = 0U; n < N_PHILO; ++n) { + me->fork[n] = FREE; + me->isHungry[n] = false; + } +} +//$enddef${Shared::Table_ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +//$define${Shared::AO_Table} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${Shared::AO_Table} ........................................................ +QActive * const AO_Table = &Table_inst.super; +//$enddef${Shared::AO_Table} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +//$define${AOs::Table} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${AOs::Table} .............................................................. +Table Table_inst; + +//${AOs::Table::SM} .......................................................... +static QState Table_initial(Table * const me, void const * const par) { + //${AOs::Table::SM::initial} + Q_UNUSED_PAR(par); + + #ifdef Q_SPY + Table *Table_inst = me; + QS_OBJ_DICTIONARY(Table_inst); + #endif + + QActive_subscribe(&me->super, DONE_SIG); + QActive_subscribe(&me->super, PAUSE_SIG); + QActive_subscribe(&me->super, SERVE_SIG); + QActive_subscribe(&me->super, TEST_SIG); + + for (uint8_t n = 0U; n < N_PHILO; ++n) { + me->fork[n] = FREE; + me->isHungry[n] = false; + BSP_displayPhilStat(n, THINKING); + } + + QS_FUN_DICTIONARY(&Table_active); + QS_FUN_DICTIONARY(&Table_serving); + QS_FUN_DICTIONARY(&Table_paused); + + return Q_TRAN(&Table_serving); +} + +//${AOs::Table::SM::active} .................................................. +static QState Table_active(Table * const me, QEvt const * const e) { + QState status_; + switch (e->sig) { + //${AOs::Table::SM::active::TEST} + case TEST_SIG: { + status_ = Q_HANDLED(); + break; + } + //${AOs::Table::SM::active::EAT} + case EAT_SIG: { + Q_ERROR(); + status_ = Q_HANDLED(); + break; + } + default: { + status_ = Q_SUPER(&QHsm_top); + break; + } + } + return status_; +} + +//${AOs::Table::SM::active::serving} ......................................... +static QState Table_serving(Table * const me, QEvt const * const e) { + QState status_; + switch (e->sig) { + //${AOs::Table::SM::active::serving} + case Q_ENTRY_SIG: { + // give permissions to eat... + for (uint8_t n = 0U; n < N_PHILO; ++n) { + if (me->isHungry[n] + && (me->fork[left(n)] == FREE) + && (me->fork[n] == FREE)) + { + me->fork[left(n)] = USED; + me->fork[n] = USED; + #ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, EAT_SIG, n); + #else + TableEvt *pe = Q_NEW(TableEvt, EAT_SIG); + pe->philoId = n; + #endif + QACTIVE_PUBLISH(&pe->super, &me->super); + me->isHungry[n] = false; + BSP_displayPhilStat(n, EATING); + } + } + status_ = Q_HANDLED(); + break; + } + //${AOs::Table::SM::active::serving::HUNGRY} + case HUNGRY_SIG: { + uint8_t n = Q_EVT_CAST(TableEvt)->philoId; + + // phil ID must be in range and he must be not hungry + Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); + + BSP_displayPhilStat(n, HUNGRY); + uint8_t m = left(n); + //${AOs::Table::SM::active::serving::HUNGRY::[bothfree]} + if ((me->fork[m] == FREE) && (me->fork[n] == FREE)) { + me->fork[m] = USED; + me->fork[n] = USED; + #ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, EAT_SIG, n); + #else + TableEvt *pe = Q_NEW(TableEvt, EAT_SIG); + pe->philoId = n; + #endif + QACTIVE_PUBLISH(&pe->super, &me->super); + BSP_displayPhilStat(n, EATING); + status_ = Q_HANDLED(); + } + //${AOs::Table::SM::active::serving::HUNGRY::[else]} + else { + me->isHungry[n] = true; + status_ = Q_HANDLED(); + } + break; + } + //${AOs::Table::SM::active::serving::DONE} + case DONE_SIG: { + uint8_t n = Q_EVT_CAST(TableEvt)->philoId; + + // phil ID must be in range and he must be not hungry + Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); + + BSP_displayPhilStat(n, THINKING); + uint8_t m = left(n); + + // both forks of Phil[n] must be used + Q_ASSERT((me->fork[n] == USED) && (me->fork[m] == USED)); + + me->fork[m] = FREE; + me->fork[n] = FREE; + m = right(n); // check the right neighbor + + if (me->isHungry[m] && (me->fork[m] == FREE)) { + me->fork[n] = USED; + me->fork[m] = USED; + me->isHungry[m] = false; + #ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, EAT_SIG, m); + #else + TableEvt *pe = Q_NEW(TableEvt, EAT_SIG); + pe->philoId = m; + #endif + QACTIVE_PUBLISH(&pe->super, &me->super); + BSP_displayPhilStat(m, EATING); + } + m = left(n); // check the left neighbor + n = left(m); // left fork of the left neighbor + if (me->isHungry[m] && (me->fork[n] == FREE)) { + me->fork[m] = USED; + me->fork[n] = USED; + me->isHungry[m] = false; + #ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, EAT_SIG, m); + #else + TableEvt *pe = Q_NEW(TableEvt, EAT_SIG); + pe->philoId = m; + #endif + QACTIVE_PUBLISH(&pe->super, &me->super); + BSP_displayPhilStat(m, EATING); + } + status_ = Q_HANDLED(); + break; + } + //${AOs::Table::SM::active::serving::EAT} + case EAT_SIG: { + Q_ERROR(); + status_ = Q_HANDLED(); + break; + } + //${AOs::Table::SM::active::serving::PAUSE} + case PAUSE_SIG: { + status_ = Q_TRAN(&Table_paused); + break; + } + default: { + status_ = Q_SUPER(&Table_active); + break; + } + } + return status_; +} + +//${AOs::Table::SM::active::paused} .......................................... +static QState Table_paused(Table * const me, QEvt const * const e) { + QState status_; + switch (e->sig) { + //${AOs::Table::SM::active::paused} + case Q_ENTRY_SIG: { + BSP_displayPaused(1U); + status_ = Q_HANDLED(); + break; + } + //${AOs::Table::SM::active::paused} + case Q_EXIT_SIG: { + BSP_displayPaused(0U); + status_ = Q_HANDLED(); + break; + } + //${AOs::Table::SM::active::paused::SERVE} + case SERVE_SIG: { + status_ = Q_TRAN(&Table_serving); + break; + } + //${AOs::Table::SM::active::paused::HUNGRY} + case HUNGRY_SIG: { + uint8_t n = Q_EVT_CAST(TableEvt)->philoId; + + // philo ID must be in range and he must be not hungry + Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); + + me->isHungry[n] = true; + BSP_displayPhilStat(n, HUNGRY); + status_ = Q_HANDLED(); + break; + } + //${AOs::Table::SM::active::paused::DONE} + case DONE_SIG: { + uint8_t n = Q_EVT_CAST(TableEvt)->philoId; + + // phil ID must be in range and he must be not hungry + Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); + + BSP_displayPhilStat(n, THINKING); + uint8_t m = left(n); + + // both forks of Phil[n] must be used + Q_ASSERT((me->fork[n] == USED) && (me->fork[m] == USED)); + + me->fork[m] = FREE; + me->fork[n] = FREE; + status_ = Q_HANDLED(); + break; + } + default: { + status_ = Q_SUPER(&Table_active); + break; + } + } + return status_; +} +//$enddef${AOs::Table} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/examples/arm-cm/game_efm32-slstk3401a/win32-gui/Res/BOARD.bmp b/examples/qwin-gui/game-gui/Res/BOARD.bmp similarity index 100% rename from examples/arm-cm/game_efm32-slstk3401a/win32-gui/Res/BOARD.bmp rename to examples/qwin-gui/game-gui/Res/BOARD.bmp diff --git a/examples/arm-cm/game_efm32-slstk3401a/win32-gui/Res/BTN_DWN.bmp b/examples/qwin-gui/game-gui/Res/BTN_DWN.bmp similarity index 100% rename from examples/arm-cm/game_efm32-slstk3401a/win32-gui/Res/BTN_DWN.bmp rename to examples/qwin-gui/game-gui/Res/BTN_DWN.bmp diff --git a/examples/arm-cm/game_efm32-slstk3401a/win32-gui/Res/BTN_UP.bmp b/examples/qwin-gui/game-gui/Res/BTN_UP.bmp similarity index 100% rename from examples/arm-cm/game_efm32-slstk3401a/win32-gui/Res/BTN_UP.bmp rename to examples/qwin-gui/game-gui/Res/BTN_UP.bmp diff --git a/examples/arm-cm/game_efm32-slstk3401a/win32-gui/Res/LCD.bmp b/examples/qwin-gui/game-gui/Res/LCD.bmp similarity index 100% rename from examples/arm-cm/game_efm32-slstk3401a/win32-gui/Res/LCD.bmp rename to examples/qwin-gui/game-gui/Res/LCD.bmp diff --git a/examples/arm-cm/game_efm32-slstk3401a/win32-gui/Res/LED_OFF.bmp b/examples/qwin-gui/game-gui/Res/LED_OFF.bmp similarity index 100% rename from examples/arm-cm/game_efm32-slstk3401a/win32-gui/Res/LED_OFF.bmp rename to examples/qwin-gui/game-gui/Res/LED_OFF.bmp diff --git a/examples/arm-cm/game_efm32-slstk3401a/win32-gui/Res/LED_ON.bmp b/examples/qwin-gui/game-gui/Res/LED_ON.bmp similarity index 100% rename from examples/arm-cm/game_efm32-slstk3401a/win32-gui/Res/LED_ON.bmp rename to examples/qwin-gui/game-gui/Res/LED_ON.bmp diff --git a/examples/arm-cm/game_efm32-slstk3401a/win32-gui/Res/qp.ico b/examples/qwin-gui/game-gui/Res/qp.ico similarity index 100% rename from examples/arm-cm/game_efm32-slstk3401a/win32-gui/Res/qp.ico rename to examples/qwin-gui/game-gui/Res/qp.ico diff --git a/examples/arm-cm/game_efm32-slstk3401a/win32-gui/Res/seg.bmp b/examples/qwin-gui/game-gui/Res/seg.bmp similarity index 100% rename from examples/arm-cm/game_efm32-slstk3401a/win32-gui/Res/seg.bmp rename to examples/qwin-gui/game-gui/Res/seg.bmp diff --git a/examples/arm-cm/game_efm32-slstk3401a/win32-gui/Res/seg0.bmp b/examples/qwin-gui/game-gui/Res/seg0.bmp similarity index 100% rename from examples/arm-cm/game_efm32-slstk3401a/win32-gui/Res/seg0.bmp rename to examples/qwin-gui/game-gui/Res/seg0.bmp diff --git a/examples/arm-cm/game_efm32-slstk3401a/win32-gui/Res/seg1.bmp b/examples/qwin-gui/game-gui/Res/seg1.bmp similarity index 100% rename from examples/arm-cm/game_efm32-slstk3401a/win32-gui/Res/seg1.bmp rename to examples/qwin-gui/game-gui/Res/seg1.bmp diff --git a/examples/arm-cm/game_efm32-slstk3401a/win32-gui/Res/seg2.bmp b/examples/qwin-gui/game-gui/Res/seg2.bmp similarity index 100% rename from examples/arm-cm/game_efm32-slstk3401a/win32-gui/Res/seg2.bmp rename to examples/qwin-gui/game-gui/Res/seg2.bmp diff --git a/examples/arm-cm/game_efm32-slstk3401a/win32-gui/Res/seg3.bmp b/examples/qwin-gui/game-gui/Res/seg3.bmp similarity index 100% rename from examples/arm-cm/game_efm32-slstk3401a/win32-gui/Res/seg3.bmp rename to examples/qwin-gui/game-gui/Res/seg3.bmp diff --git a/examples/arm-cm/game_efm32-slstk3401a/win32-gui/Res/seg4.bmp b/examples/qwin-gui/game-gui/Res/seg4.bmp similarity index 100% rename from examples/arm-cm/game_efm32-slstk3401a/win32-gui/Res/seg4.bmp rename to examples/qwin-gui/game-gui/Res/seg4.bmp diff --git a/examples/arm-cm/game_efm32-slstk3401a/win32-gui/Res/seg5.bmp b/examples/qwin-gui/game-gui/Res/seg5.bmp similarity index 100% rename from examples/arm-cm/game_efm32-slstk3401a/win32-gui/Res/seg5.bmp rename to examples/qwin-gui/game-gui/Res/seg5.bmp diff --git a/examples/arm-cm/game_efm32-slstk3401a/win32-gui/Res/seg6.bmp b/examples/qwin-gui/game-gui/Res/seg6.bmp similarity index 100% rename from examples/arm-cm/game_efm32-slstk3401a/win32-gui/Res/seg6.bmp rename to examples/qwin-gui/game-gui/Res/seg6.bmp diff --git a/examples/arm-cm/game_efm32-slstk3401a/win32-gui/Res/seg7.bmp b/examples/qwin-gui/game-gui/Res/seg7.bmp similarity index 100% rename from examples/arm-cm/game_efm32-slstk3401a/win32-gui/Res/seg7.bmp rename to examples/qwin-gui/game-gui/Res/seg7.bmp diff --git a/examples/arm-cm/game_efm32-slstk3401a/win32-gui/Res/seg8.bmp b/examples/qwin-gui/game-gui/Res/seg8.bmp similarity index 100% rename from examples/arm-cm/game_efm32-slstk3401a/win32-gui/Res/seg8.bmp rename to examples/qwin-gui/game-gui/Res/seg8.bmp diff --git a/examples/arm-cm/game_efm32-slstk3401a/win32-gui/Res/seg9.bmp b/examples/qwin-gui/game-gui/Res/seg9.bmp similarity index 100% rename from examples/arm-cm/game_efm32-slstk3401a/win32-gui/Res/seg9.bmp rename to examples/qwin-gui/game-gui/Res/seg9.bmp diff --git a/examples/arm-cm/game_efm32-slstk3401a/win32-gui/Resource.rc b/examples/qwin-gui/game-gui/Resource.rc similarity index 100% rename from examples/arm-cm/game_efm32-slstk3401a/win32-gui/Resource.rc rename to examples/qwin-gui/game-gui/Resource.rc diff --git a/examples/qwin-gui/game-gui/bsp.c b/examples/qwin-gui/game-gui/bsp.c new file mode 100644 index 00000000..19e87782 --- /dev/null +++ b/examples/qwin-gui/game-gui/bsp.c @@ -0,0 +1,880 @@ +//============================================================================ +// Product: "Fly 'n' Shoot" game example, EFM32-SLSTK3401A, Win32-GUI +// Last updated for version 7.3.0 +// Last updated on 2023-08-16 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// This program is open source software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Alternatively, this program may be distributed and modified under the +// terms of Quantum Leaps commercial licenses, which expressly supersede +// the GNU General Public License and are specifically designed for +// licensees interested in retaining the proprietary status of their code. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Contact information: +// +// +//============================================================================ +#include "qpc.h" +#include "game.h" +#include "bsp.h" + +#include "qwin_gui.h" // QWIN GUI +#include "resource.h" // GUI resource IDs generated by the resource editior + +#include "safe_std.h" // portable "safe" / facilities + +Q_DEFINE_THIS_FILE + +// local variables --------------------------------------------------------- +static HINSTANCE l_hInst; // this application instance +static HWND l_hWnd; // main window handle +static LPSTR l_cmdLine; // the command line string + +static GraphicDisplay l_lcd; // LCD display on EFM32-SLSTK3401A +static SegmentDisplay l_userLED0; // USER LED0 on EFM32-SLSTK3401A +static SegmentDisplay l_userLED1; // USER LED1 on EFM32-SLSTK3401A +static SegmentDisplay l_scoreBoard; // segment display for the score +static OwnerDrawnButton l_userBtn0; // USER Button0 on EFM32-SLSTK3401A +static OwnerDrawnButton l_userBtn1; // USER Button1 on EFM32-SLSTK3401A + +// (R,G,B) colors for the LCD display +static BYTE const c_onColor[3] = { 0x07U, 0x07U, 0x07U }; // dark gray +static BYTE const c_offColor[3] = { 0xA0U, 0xA0U, 0xA0U }; // light gray + +// LCD geometry and frame buffer +static uint32_t l_fb[BSP_SCREEN_HEIGHT + 1][BSP_SCREEN_WIDTH / 32U]; + +// the walls buffer +static uint32_t l_walls[GAME_TUNNEL_HEIGHT + 1][BSP_SCREEN_WIDTH / 32U]; + +static unsigned l_rnd; // random seed + +static void paintBits(uint8_t x, uint8_t y, uint8_t const *bits, uint8_t h); +static void paintBitsClear(uint8_t x, uint8_t y, + uint8_t const *bits, uint8_t h); +#ifdef Q_SPY + enum QSUserRecords { + PLAYER_TRIGGER = QS_USER, + COMMAND_STAT + }; + + // QSpy source IDs + static QSpyId const l_clock_tick = { 0U }; + static QSpyId const l_player = { 0U }; +#endif + +// Local functions --------------------------------------------------------- +static LRESULT CALLBACK WndProc(HWND hWnd, UINT iMsg, + WPARAM wParam, LPARAM lParam); + +//............................................................................ +static void playerTrigger(void) { + static QEvt const fireEvt = QEVT_INITIALIZER(PLAYER_TRIGGER_SIG); + QACTIVE_PUBLISH(&fireEvt, &l_player); +} + +//---------------------------------------------------------------------------- +void QF_onStartup(void) { + QF_setTickRate(BSP_TICKS_PER_SEC, 30); // set the desired tick rate +} +//............................................................................ +void QF_onCleanup(void) { +} +//............................................................................ +void QF_onClockTick(void) { + static QEvt const tickEvt = QEVT_INITIALIZER(TIME_TICK_SIG); + QTIMEEVT_TICK_X(0U, &l_clock_tick); // process time events for rate 0 + QACTIVE_PUBLISH(&tickEvt, &l_clock_tick); // publish the tick event + + QS_RX_INPUT(); // handle the QS-RX input + QS_OUTPUT(); // handle the QS output +} + +//............................................................................ +Q_NORETURN Q_onError(char const * const module, int_t const id) { + QF_stop(); // stop ticking + + QS_ASSERTION(module, id, 10000U); // report assertion to QS + + char message[80]; + SNPRINTF_S(message, Q_DIM(message) - 1, + "Assertion failed in module %s location %d", module, id); + MessageBox(l_hWnd, message, "!!! ASSERTION !!!", + MB_OK | MB_ICONEXCLAMATION | MB_APPLMODAL); + PostQuitMessage(-1); +} +//............................................................................ +void assert_failed(char const * const module, int_t const id); // prototype +void assert_failed(char const * const module, int_t const id) { + Q_onError(module, id); +} + +//............................................................................ +void BSP_init(void) { + if (QS_INIT(l_cmdLine) == 0U) { // QS initialization failed? + MessageBox(l_hWnd, + "Cannot connect to QSPY via TCP/IP\n" + "Please make sure that 'qspy -t' is running", + "QS_INIT() Error", + MB_OK | MB_ICONEXCLAMATION | MB_APPLMODAL); + } + + // send the QS dictionaries... + QS_OBJ_DICTIONARY(&l_clock_tick); + QS_OBJ_DICTIONARY(&l_player); + QS_USR_DICTIONARY(PLAYER_TRIGGER); + + // setup the QS filters... + QS_GLB_FILTER(QS_ALL_RECORDS); + QS_GLB_FILTER(-QS_QF_TICK); +} +//............................................................................ +void BSP_terminate(int16_t result) { + QF_stop(); // stop the main QF application and the ticker thread + + // cleanup all QWIN resources... + OwnerDrawnButton_xtor(&l_userBtn0); // cleanup the l_userBtn0 resources + OwnerDrawnButton_xtor(&l_userBtn1); // cleanup the l_userBtn1 resources + SegmentDisplay_xtor(&l_userLED0); // cleanup the l_userLED0 resources + SegmentDisplay_xtor(&l_userLED1); // cleanup the l_userLED1 resources + SegmentDisplay_xtor(&l_scoreBoard); // cleanup the scoreBoard resources + GraphicDisplay_xtor(&l_lcd); // cleanup the l_lcd resources + + // end the main dialog + EndDialog(l_hWnd, result); +} +//............................................................................ +void BSP_updateScreen(void) { + UINT x, y; + + // turn LED1 on + SegmentDisplay_setSegment(&l_userLED1, 0U, 1U); + + // map the LCD pixels to the GraphicDisplay pixels... + for (y = 0; y < BSP_SCREEN_HEIGHT; ++y) { + for (x = 0; x < BSP_SCREEN_WIDTH; ++x) { + uint32_t bits = l_fb[y][x >> 5]; + if ((bits & (1U << (x & 0x1FU))) != 0U) { + GraphicDisplay_setPixel(&l_lcd, x, y, c_onColor); + } + else { + GraphicDisplay_clearPixel(&l_lcd, x, y); + } + } + } + + GraphicDisplay_redraw(&l_lcd); // redraw the updated display + + // turn LED1 off + SegmentDisplay_setSegment(&l_userLED1, 0U, 0U); +} +//............................................................................ +void BSP_clearFB() { + uint_fast8_t y; + for (y = 0U; y < BSP_SCREEN_HEIGHT; ++y) { + l_fb[y][0] = 0U; + l_fb[y][1] = 0U; + l_fb[y][2] = 0U; + l_fb[y][3] = 0U; + } +} +//............................................................................ +void BSP_clearWalls() { + uint_fast8_t y; + for (y = 0U; y < GAME_TUNNEL_HEIGHT; ++y) { + l_walls[y][0] = 0U; + l_walls[y][1] = 0U; + l_walls[y][2] = 0U; + l_walls[y][3] = 0U; + } +} +//............................................................................ +bool BSP_isThrottle(void) { // is the throttle button depressed? + return OwnerDrawnButton_isDepressed(&l_userBtn1) != 0; +} +//............................................................................ +void BSP_paintString(uint8_t x, uint8_t y, char const *str) { + static uint8_t const font5x7[95][7] = { + { 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U }, // + { 0x04U, 0x04U, 0x04U, 0x04U, 0x00U, 0x00U, 0x04U }, // ! + { 0x0AU, 0x0AU, 0x0AU, 0x00U, 0x00U, 0x00U, 0x00U }, // " + { 0x0AU, 0x0AU, 0x1FU, 0x0AU, 0x1FU, 0x0AU, 0x0AU }, // # + { 0x04U, 0x1EU, 0x05U, 0x0EU, 0x14U, 0x0FU, 0x04U }, // $ + { 0x03U, 0x13U, 0x08U, 0x04U, 0x02U, 0x19U, 0x18U }, // % + { 0x06U, 0x09U, 0x05U, 0x02U, 0x15U, 0x09U, 0x16U }, // & + { 0x06U, 0x04U, 0x02U, 0x00U, 0x00U, 0x00U, 0x00U }, // ' + { 0x08U, 0x04U, 0x02U, 0x02U, 0x02U, 0x04U, 0x08U }, // ( + { 0x02U, 0x04U, 0x08U, 0x08U, 0x08U, 0x04U, 0x02U }, // ) + { 0x00U, 0x04U, 0x15U, 0x0EU, 0x15U, 0x04U, 0x00U }, // * + { 0x00U, 0x04U, 0x04U, 0x1FU, 0x04U, 0x04U, 0x00U }, // + + { 0x00U, 0x00U, 0x00U, 0x00U, 0x06U, 0x04U, 0x02U }, // , + { 0x00U, 0x00U, 0x00U, 0x1FU, 0x00U, 0x00U, 0x00U }, // - + { 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x06U, 0x06U }, // . + { 0x00U, 0x10U, 0x08U, 0x04U, 0x02U, 0x01U, 0x00U }, // / + { 0x0EU, 0x11U, 0x19U, 0x15U, 0x13U, 0x11U, 0x0EU }, // 0 + { 0x04U, 0x06U, 0x04U, 0x04U, 0x04U, 0x04U, 0x0EU }, // 1 + { 0x0EU, 0x11U, 0x10U, 0x08U, 0x04U, 0x02U, 0x1FU }, // 2 + { 0x1FU, 0x08U, 0x04U, 0x08U, 0x10U, 0x11U, 0x0EU }, // 3 + { 0x08U, 0x0CU, 0x0AU, 0x09U, 0x1FU, 0x08U, 0x08U }, // 4 + { 0x1FU, 0x01U, 0x0FU, 0x10U, 0x10U, 0x11U, 0x0EU }, // 5 + { 0x0CU, 0x02U, 0x01U, 0x0FU, 0x11U, 0x11U, 0x0EU }, // 6 + { 0x1FU, 0x10U, 0x08U, 0x04U, 0x02U, 0x02U, 0x02U }, // 7 + { 0x0EU, 0x11U, 0x11U, 0x0EU, 0x11U, 0x11U, 0x0EU }, // 8 + { 0x0EU, 0x11U, 0x11U, 0x1EU, 0x10U, 0x08U, 0x06U }, // 9 + { 0x00U, 0x06U, 0x06U, 0x00U, 0x06U, 0x06U, 0x00U }, // : + { 0x00U, 0x06U, 0x06U, 0x00U, 0x06U, 0x04U, 0x02U }, // ; + { 0x08U, 0x04U, 0x02U, 0x01U, 0x02U, 0x04U, 0x08U }, // < + { 0x00U, 0x00U, 0x1FU, 0x00U, 0x1FU, 0x00U, 0x00U }, // = + { 0x02U, 0x04U, 0x08U, 0x10U, 0x08U, 0x04U, 0x02U }, // > + { 0x0EU, 0x11U, 0x10U, 0x08U, 0x04U, 0x00U, 0x04U }, // ? + { 0x0EU, 0x11U, 0x10U, 0x16U, 0x15U, 0x15U, 0x0EU }, // @ + { 0x0EU, 0x11U, 0x11U, 0x11U, 0x1FU, 0x11U, 0x11U }, // A + { 0x0FU, 0x11U, 0x11U, 0x0FU, 0x11U, 0x11U, 0x0FU }, // B + { 0x0EU, 0x11U, 0x01U, 0x01U, 0x01U, 0x11U, 0x0EU }, // C + { 0x07U, 0x09U, 0x11U, 0x11U, 0x11U, 0x09U, 0x07U }, // D + { 0x1FU, 0x01U, 0x01U, 0x0FU, 0x01U, 0x01U, 0x1FU }, // E + { 0x1FU, 0x01U, 0x01U, 0x0FU, 0x01U, 0x01U, 0x01U }, // F + { 0x0EU, 0x11U, 0x01U, 0x1DU, 0x11U, 0x11U, 0x1EU }, // G + { 0x11U, 0x11U, 0x11U, 0x1FU, 0x11U, 0x11U, 0x11U }, // H + { 0x0EU, 0x04U, 0x04U, 0x04U, 0x04U, 0x04U, 0x0EU }, // I + { 0x1CU, 0x08U, 0x08U, 0x08U, 0x08U, 0x09U, 0x06U }, // J + { 0x11U, 0x09U, 0x05U, 0x03U, 0x05U, 0x09U, 0x11U }, // K + { 0x01U, 0x01U, 0x01U, 0x01U, 0x01U, 0x01U, 0x1FU }, // L + { 0x11U, 0x1BU, 0x15U, 0x15U, 0x11U, 0x11U, 0x11U }, // M + { 0x11U, 0x11U, 0x13U, 0x15U, 0x19U, 0x11U, 0x11U }, // N + { 0x0EU, 0x11U, 0x11U, 0x11U, 0x11U, 0x11U, 0x0EU }, // O + { 0x0FU, 0x11U, 0x11U, 0x0FU, 0x01U, 0x01U, 0x01U }, // P + { 0x0EU, 0x11U, 0x11U, 0x11U, 0x15U, 0x09U, 0x16U }, // Q + { 0x0FU, 0x11U, 0x11U, 0x0FU, 0x05U, 0x09U, 0x11U }, // R + { 0x1EU, 0x01U, 0x01U, 0x0EU, 0x10U, 0x10U, 0x0FU }, // S + { 0x1FU, 0x04U, 0x04U, 0x04U, 0x04U, 0x04U, 0x04U }, // T + { 0x11U, 0x11U, 0x11U, 0x11U, 0x11U, 0x11U, 0x0EU }, // U + { 0x11U, 0x11U, 0x11U, 0x11U, 0x11U, 0x0AU, 0x04U }, // V + { 0x11U, 0x11U, 0x11U, 0x15U, 0x15U, 0x15U, 0x0AU }, // W + { 0x11U, 0x11U, 0x0AU, 0x04U, 0x0AU, 0x11U, 0x11U }, // X + { 0x11U, 0x11U, 0x11U, 0x0AU, 0x04U, 0x04U, 0x04U }, // Y + { 0x1FU, 0x10U, 0x08U, 0x04U, 0x02U, 0x01U, 0x1FU }, // Z + { 0x0EU, 0x02U, 0x02U, 0x02U, 0x02U, 0x02U, 0x0EU }, // [ + { 0x00U, 0x01U, 0x02U, 0x04U, 0x08U, 0x10U, 0x00U }, // `\` + { 0x0EU, 0x08U, 0x08U, 0x08U, 0x08U, 0x08U, 0x0EU }, // ] + { 0x04U, 0x0AU, 0x11U, 0x00U, 0x00U, 0x00U, 0x00U }, // ^ + { 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x1FU }, // _ + { 0x02U, 0x04U, 0x08U, 0x00U, 0x00U, 0x00U, 0x00U }, // ` + { 0x00U, 0x00U, 0x0EU, 0x10U, 0x1EU, 0x11U, 0x1EU }, // a + { 0x01U, 0x01U, 0x0DU, 0x13U, 0x11U, 0x11U, 0x0FU }, // b + { 0x00U, 0x00U, 0x0EU, 0x01U, 0x01U, 0x11U, 0x0EU }, // c + { 0x10U, 0x10U, 0x16U, 0x19U, 0x11U, 0x11U, 0x1EU }, // d + { 0x00U, 0x00U, 0x0EU, 0x11U, 0x1FU, 0x01U, 0x0EU }, // e + { 0x0CU, 0x12U, 0x02U, 0x07U, 0x02U, 0x02U, 0x02U }, // f + { 0x00U, 0x1EU, 0x11U, 0x11U, 0x1EU, 0x10U, 0x0EU }, // g + { 0x01U, 0x01U, 0x0DU, 0x13U, 0x11U, 0x11U, 0x11U }, // h + { 0x04U, 0x00U, 0x06U, 0x04U, 0x04U, 0x04U, 0x0EU }, // i + { 0x08U, 0x00U, 0x0CU, 0x08U, 0x08U, 0x09U, 0x06U }, // j + { 0x01U, 0x01U, 0x09U, 0x05U, 0x03U, 0x05U, 0x09U }, // k + { 0x06U, 0x04U, 0x04U, 0x04U, 0x04U, 0x04U, 0x0EU }, // l + { 0x00U, 0x00U, 0x0BU, 0x15U, 0x15U, 0x11U, 0x11U }, // m + { 0x00U, 0x00U, 0x0DU, 0x13U, 0x11U, 0x11U, 0x11U }, // n + { 0x00U, 0x00U, 0x0EU, 0x11U, 0x11U, 0x11U, 0x0EU }, // o + { 0x00U, 0x00U, 0x0FU, 0x11U, 0x0FU, 0x01U, 0x01U }, // p + { 0x00U, 0x00U, 0x16U, 0x19U, 0x1EU, 0x10U, 0x10U }, // q + { 0x00U, 0x00U, 0x0DU, 0x13U, 0x01U, 0x01U, 0x01U }, // r + { 0x00U, 0x00U, 0x0EU, 0x01U, 0x0EU, 0x10U, 0x0FU }, // s + { 0x02U, 0x02U, 0x07U, 0x02U, 0x02U, 0x12U, 0x0CU }, // t + { 0x00U, 0x00U, 0x11U, 0x11U, 0x11U, 0x19U, 0x16U }, // u + { 0x00U, 0x00U, 0x11U, 0x11U, 0x11U, 0x0AU, 0x04U }, // v + { 0x00U, 0x00U, 0x11U, 0x11U, 0x15U, 0x15U, 0x0AU }, // w + { 0x00U, 0x00U, 0x11U, 0x0AU, 0x04U, 0x0AU, 0x11U }, // x + { 0x00U, 0x00U, 0x11U, 0x11U, 0x1EU, 0x10U, 0x0EU }, // y + { 0x00U, 0x00U, 0x1FU, 0x08U, 0x04U, 0x02U, 0x1FU }, // z + { 0x08U, 0x04U, 0x04U, 0x02U, 0x04U, 0x04U, 0x08U }, // { + { 0x04U, 0x04U, 0x04U, 0x04U, 0x04U, 0x04U, 0x04U }, // | + { 0x02U, 0x04U, 0x04U, 0x08U, 0x04U, 0x04U, 0x02U }, // } + { 0x02U, 0x15U, 0x08U, 0x00U, 0x00U, 0x00U, 0x00U }, // ~ + }; + + for (; *str != '\0'; ++str, x += 6) { + uint8_t const *ch = &font5x7[*str - ' '][0]; + paintBitsClear(x, y, ch, 7); + } +} + +//========================================================================== +typedef struct { // the auxiliary structure to hold const bitmaps + uint8_t const *bits; // the bits in the bitmap + uint8_t height; // the height of the bitmap +} Bitmap; + +// bitmap of the Ship: +// +// x.... +// xxx.. +// xxxxx +// +static uint8_t const ship_bits[] = { + 0x01U, 0x07U, 0x1FU +}; + +// bitmap of the Missile: +// +// xxxx +// +static uint8_t const missile_bits[] = { + 0x0FU +}; + +// bitmap of the Mine type-1: +// +// .x. +// xxx +// .x. +// +static uint8_t const mine1_bits[] = { + 0x02U, 0x07U, 0x02U +}; + +// bitmap of the Mine type-2: +// +// x..x +// .xx. +// .xx. +// x..x +// +static uint8_t const mine2_bits[] = { + 0x09U, 0x06U, 0x06U, 0x09U +}; + +// Mine type-2 is nastier than Mine type-1. The type-2 mine can +// hit the Ship with any of its "tentacles". However, it can be +// destroyed by the Missile only by hitting its center, defined as +// the following bitmap: +// +// .... +// .xx. +// .xx. +// +static uint8_t const mine2_missile_bits[] = { + 0x00U, 0x06U, 0x06U +}; + +// +// The bitmap of the explosion stage 0: +// +// ....... +// ...x... +// ..x.x.. +// ...x... +// +static uint8_t const explosion0_bits[] = { + 0x00U, 0x08U, 0x14U, 0x08U +}; + +// +// The bitmap of the explosion stage 1: +// +// ....... +// ..x.x.. +// ...x... +// ..x.x.. +// +static uint8_t const explosion1_bits[] = { + 0x00U, 0x14U, 0x08U, 0x14U +}; + +// +// The bitmap of the explosion stage 2: +// +// .x...x. +// ..x.x.. +// ...x... +// ..x.x.. +// .x...x. +// +static uint8_t const explosion2_bits[] = { + 0x11U, 0x0AU, 0x04U, 0x0AU, 0x11U +}; + +// +// The bitmap of the explosion stage 3: +// +// x..x..x +// .x.x.x. +// ..x.x.. +// xx.x.xx +// ..x.x.. +// .x.x.x. +// x..x..x +// +static uint8_t const explosion3_bits[] = { + 0x49, 0x2A, 0x14, 0x6B, 0x14, 0x2A, 0x49 +}; + +static Bitmap const l_bitmap[MAX_BMP] = { + { ship_bits, Q_DIM(ship_bits) }, + { missile_bits, Q_DIM(missile_bits) }, + { mine1_bits, Q_DIM(mine1_bits) }, + { mine2_bits, Q_DIM(mine2_bits) }, + { mine2_missile_bits, Q_DIM(mine2_missile_bits) }, + { explosion0_bits, Q_DIM(explosion0_bits) }, + { explosion1_bits, Q_DIM(explosion1_bits) }, + { explosion2_bits, Q_DIM(explosion2_bits) }, + { explosion3_bits, Q_DIM(explosion3_bits) } +}; + +//............................................................................ +void BSP_paintBitmap(uint8_t x, uint8_t y, uint8_t bmp_id) { + Bitmap const *bmp = &l_bitmap[bmp_id]; + paintBits(x, y, bmp->bits, bmp->height); +} +//............................................................................ +void BSP_advanceWalls(uint8_t top, uint8_t bottom) { + uint_fast8_t y; + for (y = 0U; y < GAME_TUNNEL_HEIGHT; ++y) { + // shift the walls one pixel to the left + l_walls[y][0] = (l_walls[y][0] >> 1) | (l_walls[y][1] << 31); + l_walls[y][1] = (l_walls[y][1] >> 1) | (l_walls[y][2] << 31); + l_walls[y][2] = (l_walls[y][2] >> 1) | (l_walls[y][3] << 31); + l_walls[y][3] = (l_walls[y][3] >> 1); + + // add new column of walls at the end + if (y <= top) { + l_walls[y][3] |= (1U << 31); + } + if (y >= (GAME_TUNNEL_HEIGHT - bottom)) { + l_walls[y][3] |= (1U << 31); + } + + // copy the walls to the frame buffer + l_fb[y][0] = l_walls[y][0]; + l_fb[y][1] = l_walls[y][1]; + l_fb[y][2] = l_walls[y][2]; + l_fb[y][3] = l_walls[y][3]; + } +} +//............................................................................ +bool BSP_doBitmapsOverlap(uint8_t bmp_id1, uint8_t x1, uint8_t y1, + uint8_t bmp_id2, uint8_t x2, uint8_t y2) +{ + uint8_t y; + uint8_t y0; + uint8_t h; + uint32_t bits1; + uint32_t bits2; + Bitmap const *bmp1; + Bitmap const *bmp2; + + Q_REQUIRE((bmp_id1 < Q_DIM(l_bitmap)) && (bmp_id2 < Q_DIM(l_bitmap))); + + // are the bitmaps close enough in x? + if (x1 >= x2) { + if (x1 > x2 + 8U) { + return false; + } + x1 -= x2; + x2 = 0U; + } + else { + if (x2 > x1 + 8U) { + return false; + } + x2 -= x1; + x1 = 0U; + } + + bmp1 = &l_bitmap[bmp_id1]; + bmp2 = &l_bitmap[bmp_id2]; + if ((y1 <= y2) && (y1 + bmp1->height > y2)) { + y0 = y2 - y1; + h = y1 + bmp1->height - y2; + if (h > bmp2->height) { + h = bmp2->height; + } + for (y = 0; y < h; ++y) { // scan over the overlapping rows + bits1 = ((uint32_t)bmp1->bits[y + y0] << x1); + bits2 = ((uint32_t)bmp2->bits[y] << x2); + if ((bits1 & bits2) != 0U) { // do the bits overlap? + return true; // yes! + } + } + } + else { + if ((y1 > y2) && (y2 + bmp2->height > y1)) { + y0 = y1 - y2; + h = y2 + bmp2->height - y1; + if (h > bmp1->height) { + h = bmp1->height; + } + for (y = 0; y < h; ++y) { // scan over the overlapping rows + bits1 = ((uint32_t)bmp1->bits[y] << x1); + bits2 = ((uint32_t)bmp2->bits[y + y0] << x2); + if ((bits1 & bits2) != 0U) { // do the bits overlap? + return true; // yes! + } + } + } + } + return false; // the bitmaps do not overlap +} +//............................................................................ +bool BSP_isWallHit(uint8_t bmp_id, uint8_t x, uint8_t y) { + Bitmap const *bmp = &l_bitmap[bmp_id]; + uint32_t shft = (x & 0x1FU); + uint32_t *walls = &l_walls[y][x >> 5]; + for (y = 0; y < bmp->height; ++y, walls += (BSP_SCREEN_WIDTH >> 5)) { + if (*walls & ((uint32_t)bmp->bits[y] << shft)) { + return true; + } + if (shft > 24U) { + if (*(walls + 1) & ((uint32_t)bmp->bits[y] >> (32U - shft))) { + return true; + } + } + } + return false; +} + +//............................................................................ +void BSP_updateScore(uint16_t score) { + uint8_t seg[5]; + char str[5]; + + if (score == 0U) { + BSP_paintString(1U, BSP_SCREEN_HEIGHT - 8U, "SCORE:"); + } + + seg[0] = score % 10U; score /= 10U; + seg[1] = score % 10U; score /= 10U; + seg[2] = score % 10U; score /= 10U; + seg[3] = score % 10U; + + // update the SCORE area on the screeen + str[0] = seg[3] + '0'; + str[1] = seg[2] + '0'; + str[2] = seg[1] + '0'; + str[3] = seg[0] + '0'; + str[4] = '\0'; + BSP_paintString(6U*6U, BSP_SCREEN_HEIGHT - 8U, str); + + // update the score in the l_scoreBoard SegmentDisplay + SegmentDisplay_setSegment(&l_scoreBoard, 0U, (UINT)seg[0]); + SegmentDisplay_setSegment(&l_scoreBoard, 1U, (UINT)seg[1]); + SegmentDisplay_setSegment(&l_scoreBoard, 2U, (UINT)seg[2]); + SegmentDisplay_setSegment(&l_scoreBoard, 3U, (UINT)seg[3]); +} +//............................................................................ +void BSP_displayOn(void) { + SegmentDisplay_setSegment(&l_userLED0, 0U, 1U); +} +//............................................................................ +void BSP_displayOff(void) { + SegmentDisplay_setSegment(&l_userLED0, 0U, 0U); + GraphicDisplay_clear(&l_lcd); + GraphicDisplay_redraw(&l_lcd); +} +//............................................................................ +uint32_t BSP_random(void) { // a very cheap pseudo-random-number generator + // "Super-Duper" Linear Congruential Generator (LCG) + // LCG(2^32, 3*7*11*13*23, 0, seed) + // + l_rnd = l_rnd * (3U*7U*11U*13U*23U); + return l_rnd >> 8; +} +//............................................................................ +void BSP_randomSeed(uint32_t seed) { + l_rnd = seed; +} + +//---------------------------------------------------------------------------- +//............................................................................ +static void paintBits(uint8_t x, uint8_t y, uint8_t const *bits, uint8_t h) { + uint32_t *fb = &l_fb[y][x >> 5]; + uint32_t shft = (x & 0x1FU); + for (y = 0; y < h; ++y, fb += (BSP_SCREEN_WIDTH >> 5)) { + *fb |= ((uint32_t)bits[y] << shft); + if (shft > 24U) { + *(fb + 1) |= ((uint32_t)bits[y] >> (32U - shft)); + } + } +} +//............................................................................ +static void paintBitsClear(uint8_t x, uint8_t y, + uint8_t const *bits, uint8_t h) +{ + uint32_t *fb = &l_fb[y][x >> 5]; + uint32_t shft = (x & 0x1FU); + uint32_t mask1 = ~((uint32_t)0xFFU << shft); + uint32_t mask2; + if (shft > 24U) { + mask2 = ~(0xFFU >> (32U - shft)); + } + for (y = 0; y < h; ++y, fb += (BSP_SCREEN_WIDTH >> 5)) { + *fb = ((*fb & mask1) | ((uint32_t)bits[y] << shft)); + if (shft > 24U) { + *(fb + 1) = ((*(fb + 1) & mask2) + | ((uint32_t)bits[y] >> (32U - shft))); + } + } +} + +//............................................................................ +// thread function for running the application main_gui() +static DWORD WINAPI appThread(LPVOID par) { + (void)par; // unused parameter + return (DWORD)main_gui(); // run the QF application +} + +//---------------------------------------------------------------------------- +int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, + LPSTR cmdLine, int iCmdShow) +{ + HWND hWnd; + MSG msg; + + (void)hPrevInst; // unused parameter + + l_hInst = hInst; // save the application instance + l_cmdLine = cmdLine; // save the command line string + + //AllocConsole(); + + // create the main custom dialog window + hWnd = CreateCustDialog(hInst, IDD_APPLICATION, NULL, + &WndProc, "MY_CLASS"); + ShowWindow(hWnd, iCmdShow); // show the main window + + // enter the message loop... + while (GetMessage(&msg, NULL, 0, 0)) { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + + //FreeConsole(); + BSP_terminate(0); + + return msg.wParam; +} + +//............................................................................ +static LRESULT CALLBACK WndProc(HWND hWnd, UINT iMsg, + WPARAM wParam, LPARAM lParam) +{ + switch (iMsg) { + + // Perform initialization upon cration of the main dialog window + // NOTE: Any child-windows are NOT created yet at this time, so + // the GetDlgItem() function can't be used (it will return NULL). + // + case WM_CREATE: { + l_hWnd = hWnd; // save the window handle + + // initialize the owner-drawn buttons... + // NOTE: must be done *before* the first drawing of the buttons, + // so WM_INITDIALOG is too late. + // + OwnerDrawnButton_init(&l_userBtn0, IDC_USER0, + LoadBitmap(l_hInst, MAKEINTRESOURCE(IDB_BTN_UP)), + LoadBitmap(l_hInst, MAKEINTRESOURCE(IDB_BTN_DWN)), + LoadCursor(NULL, IDC_HAND)); + OwnerDrawnButton_init(&l_userBtn1, IDC_USER1, + LoadBitmap(l_hInst, MAKEINTRESOURCE(IDB_BTN_UP)), + LoadBitmap(l_hInst, MAKEINTRESOURCE(IDB_BTN_DWN)), + LoadCursor(NULL, IDC_HAND)); + return 0; + } + + // Perform initialization after all child windows have been created + case WM_INITDIALOG: { + GraphicDisplay_init(&l_lcd, 128, 128, IDC_LCD, c_offColor); + + SegmentDisplay_init(&l_userLED0, + 1U, // 1 "segment" (the LED0 itself) + 2U); // 2 bitmaps (for LED0 OFF/ON states) + SegmentDisplay_initSegment(&l_userLED0, 0U, IDC_LED0); + SegmentDisplay_initBitmap(&l_userLED0, + 0U, LoadBitmap(l_hInst, MAKEINTRESOURCE(IDB_LED_OFF))); + SegmentDisplay_initBitmap(&l_userLED0, + 1U, LoadBitmap(l_hInst, MAKEINTRESOURCE(IDB_LED_ON))); + + SegmentDisplay_init(&l_userLED1, + 1U, // 1 "segment" (the LED1 itself) + 2U); // 2 bitmaps (for LED1 OFF/ON states) + SegmentDisplay_initSegment(&l_userLED1, 0U, IDC_LED1); + SegmentDisplay_initBitmap(&l_userLED1, + 0U, LoadBitmap(l_hInst, MAKEINTRESOURCE(IDB_LED_OFF))); + SegmentDisplay_initBitmap(&l_userLED1, + 1U, LoadBitmap(l_hInst, MAKEINTRESOURCE(IDB_LED_ON))); + + SegmentDisplay_init(&l_scoreBoard, + 4U, // 4 "segments" (digits 0-3) + 10U); // 10 bitmaps (for 0-9 states) + SegmentDisplay_initSegment(&l_scoreBoard, 0U, IDC_SEG0); + SegmentDisplay_initSegment(&l_scoreBoard, 1U, IDC_SEG1); + SegmentDisplay_initSegment(&l_scoreBoard, 2U, IDC_SEG2); + SegmentDisplay_initSegment(&l_scoreBoard, 3U, IDC_SEG3); + SegmentDisplay_initBitmap(&l_scoreBoard, + 0U, LoadBitmap(l_hInst, MAKEINTRESOURCE(IDB_SEG0))); + SegmentDisplay_initBitmap(&l_scoreBoard, + 1U, LoadBitmap(l_hInst, MAKEINTRESOURCE(IDB_SEG1))); + SegmentDisplay_initBitmap(&l_scoreBoard, + 2U, LoadBitmap(l_hInst, MAKEINTRESOURCE(IDB_SEG2))); + SegmentDisplay_initBitmap(&l_scoreBoard, + 3U, LoadBitmap(l_hInst, MAKEINTRESOURCE(IDB_SEG3))); + SegmentDisplay_initBitmap(&l_scoreBoard, + 4U, LoadBitmap(l_hInst, MAKEINTRESOURCE(IDB_SEG4))); + SegmentDisplay_initBitmap(&l_scoreBoard, + 5U, LoadBitmap(l_hInst, MAKEINTRESOURCE(IDB_SEG5))); + SegmentDisplay_initBitmap(&l_scoreBoard, + 6U, LoadBitmap(l_hInst, MAKEINTRESOURCE(IDB_SEG6))); + SegmentDisplay_initBitmap(&l_scoreBoard, + 7U, LoadBitmap(l_hInst, MAKEINTRESOURCE(IDB_SEG7))); + SegmentDisplay_initBitmap(&l_scoreBoard, + 8U, LoadBitmap(l_hInst, MAKEINTRESOURCE(IDB_SEG8))); + SegmentDisplay_initBitmap(&l_scoreBoard, + 9U, LoadBitmap(l_hInst, MAKEINTRESOURCE(IDB_SEG9))); + + BSP_updateScore(0U); + + // --> QP: spawn the application thread to run main_gui() + if (CreateThread(NULL, 0, &appThread, NULL, 0, NULL) + == (HANDLE)0) + { + Q_ERROR(); + } + return 0; + } + + case WM_DESTROY: { + OutputDebugString("DESTROY\n"); + PostQuitMessage(0); + return 0; + } + + // commands from child controls and menus... + case WM_COMMAND: { + switch (wParam) { + case IDOK: + case IDCANCEL: { + OutputDebugString("QUIT\n"); + PostQuitMessage(0); + break; + } + case IDC_USER0: // owner-drawn buttons... + case IDC_USER1: { + SetFocus(hWnd); + break; + } + } + return 0; + } + + // drawing of owner-drawn buttons... + case WM_DRAWITEM: { + LPDRAWITEMSTRUCT pdis = (LPDRAWITEMSTRUCT)lParam; + switch (pdis->CtlID) { + case IDC_USER0: { // owner-drawn Button0 + OutputDebugString("USER0\n"); + switch (OwnerDrawnButton_draw(&l_userBtn0, pdis)) { + case BTN_DEPRESSED: { + playerTrigger(); + SegmentDisplay_setSegment(&l_userLED0, 0U, 1U); + break; + } + case BTN_RELEASED: { + SegmentDisplay_setSegment(&l_userLED0, 0U, 0U); + break; + } + default: { + break; + } + } + break; + } + case IDC_USER1: { // owner-drawn Button1 + OutputDebugString("USER1\n"); + switch (OwnerDrawnButton_draw(&l_userBtn1, pdis)) { + case BTN_DEPRESSED: { + break; + } + case BTN_RELEASED: { + break; + } + default: { + break; + } + } + break; + } + } + return 0; + } + + // mouse wheel input... + case WM_MOUSEWHEEL: { + OutputDebugString("MOUSEWHEEL\n"); + return 0; + } + + // keyboard input... + case WM_KEYDOWN: { + OutputDebugString("KEYDOWN\n"); + switch (wParam) { + case VK_SPACE: + playerTrigger(); + OwnerDrawnButton_set(&l_userBtn0, 1); + break; + } + return 0; + } + + case WM_KEYUP: { + OutputDebugString("KEYUP\n"); + switch (wParam) { + case VK_SPACE: + OwnerDrawnButton_set(&l_userBtn0, 0); + break; + } + return 0; + } + } + return DefWindowProc(hWnd, iMsg, wParam, lParam); +} + +//---------------------------------------------------------------------------- +#ifdef Q_SPY // define QS callbacks + +//! callback function to execute user commands +void QS_onCommand(uint8_t cmdId, + uint32_t param1, uint32_t param2, uint32_t param3) +{ + switch (cmdId) { + case 0U: { + break; + } + default: + break; + } + + // unused parameters + (void)param1; + (void)param2; + (void)param3; +} + +#endif // Q_SPY +//---------------------------------------------------------------------------- diff --git a/examples/qwin-gui/game-gui/bsp.h b/examples/qwin-gui/game-gui/bsp.h new file mode 100644 index 00000000..7c3e38e3 --- /dev/null +++ b/examples/qwin-gui/game-gui/bsp.h @@ -0,0 +1,65 @@ +//============================================================================ +// Product: "Fly 'n' Shoot" game example on EFM32-SLSTK3401A board +// Last updated for version 7.3.0 +// Last updated on 2023-06-29 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// This program is open source software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Alternatively, this program may be distributed and modified under the +// terms of Quantum Leaps commercial licenses, which expressly supersede +// the GNU General Public License and are specifically designed for +// licensees interested in retaining the proprietary status of their code. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Contact information: +// +// +//============================================================================ +#ifndef BSP_H_ +#define BSP_H_ + +#define BSP_TICKS_PER_SEC 33U +#define BSP_SCREEN_WIDTH 128U +#define BSP_SCREEN_HEIGHT 128U + +void BSP_init(void); +void BSP_terminate(int16_t result); + +void BSP_updateScreen(void); +void BSP_clearFB(void); +void BSP_clearWalls(void); +void BSP_paintString(uint8_t x, uint8_t y, char const *str); +void BSP_paintBitmap(uint8_t x, uint8_t y, uint8_t bmp_id); +void BSP_advanceWalls(uint8_t top, uint8_t bottom); +void BSP_updateScore(uint16_t score); + +bool BSP_isThrottle(void); // is the throttle button depressed? +bool BSP_doBitmapsOverlap(uint8_t bmp_id1, uint8_t x1, uint8_t y1, + uint8_t bmp_id2, uint8_t x2, uint8_t y2); +bool BSP_isWallHit(uint8_t bmp_id, uint8_t x, uint8_t y); + +void BSP_displayOn(void); +void BSP_displayOff(void); + +void BSP_randomSeed(uint32_t seed); // random seed +uint32_t BSP_random(void); // pseudo-random generator + +extern QActive *const the_Ticker0; // "Ticker" AO for tick rate 0 + +#endif // BSP_H_ diff --git a/examples/arm-cm/game_efm32-slstk3401a/win32-gui/game-gui.sln b/examples/qwin-gui/game-gui/game-gui.sln similarity index 78% rename from examples/arm-cm/game_efm32-slstk3401a/win32-gui/game-gui.sln rename to examples/qwin-gui/game-gui/game-gui.sln index 0c56fc3a..95f56a59 100644 --- a/examples/arm-cm/game_efm32-slstk3401a/win32-gui/game-gui.sln +++ b/examples/qwin-gui/game-gui/game-gui.sln @@ -7,14 +7,11 @@ EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Win32 = Debug|Win32 - QSpy|Win32 = QSpy|Win32 Release|Win32 = Release|Win32 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution - {79027B25-0949-4F66-9765-4EFBCBBEFB94}.Debug|Win32.ActiveCfg = Release|Win32 - {79027B25-0949-4F66-9765-4EFBCBBEFB94}.Debug|Win32.Build.0 = Release|Win32 - {79027B25-0949-4F66-9765-4EFBCBBEFB94}.QSpy|Win32.ActiveCfg = QSpy|Win32 - {79027B25-0949-4F66-9765-4EFBCBBEFB94}.QSpy|Win32.Build.0 = QSpy|Win32 + {79027B25-0949-4F66-9765-4EFBCBBEFB94}.Debug|Win32.ActiveCfg = Debug|Win32 + {79027B25-0949-4F66-9765-4EFBCBBEFB94}.Debug|Win32.Build.0 = Debug|Win32 {79027B25-0949-4F66-9765-4EFBCBBEFB94}.Release|Win32.ActiveCfg = Release|Win32 {79027B25-0949-4F66-9765-4EFBCBBEFB94}.Release|Win32.Build.0 = Release|Win32 EndGlobalSection diff --git a/examples/arm-cm/game_efm32-slstk3401a/win32-gui/game-gui.vcxproj b/examples/qwin-gui/game-gui/game-gui.vcxproj similarity index 84% rename from examples/arm-cm/game_efm32-slstk3401a/win32-gui/game-gui.vcxproj rename to examples/qwin-gui/game-gui/game-gui.vcxproj index 733cd122..1e186efd 100644 --- a/examples/arm-cm/game_efm32-slstk3401a/win32-gui/game-gui.vcxproj +++ b/examples/qwin-gui/game-gui/game-gui.vcxproj @@ -64,7 +64,7 @@ MaxSpeed OnlyExplicitInline - .;..;../../../../include;../../../../ports/win32-qv;%(AdditionalIncludeDirectories) + .;../../../include;../../../ports/win32-qv;%(AdditionalIncludeDirectories) NDEBUG;QWIN_GUI;_WINDOWS;%(PreprocessorDefinitions) false @@ -79,6 +79,7 @@ Level3 true Default + stdc11 NDEBUG;%(PreprocessorDefinitions) @@ -115,7 +116,7 @@ Disabled - .;..;../../../../include;../../../../ports/win32-qv;%(AdditionalIncludeDirectories) + .;../../../include;../../../ports/win32-qv;%(AdditionalIncludeDirectories) QWIN_GUI;_DEBUG;_WINDOWS;%(PreprocessorDefinitions) false @@ -134,6 +135,7 @@ Default + stdc11 _DEBUG;%(PreprocessorDefinitions) @@ -163,49 +165,49 @@ - - + + true true - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + %(AdditionalIncludeDirectories) %(PreprocessorDefinitions) %(AdditionalIncludeDirectories) %(PreprocessorDefinitions) + - - - - - - - + + + + + + + - + @@ -237,4 +239,4 @@ - \ No newline at end of file + diff --git a/examples/arm-cm/game_efm32-slstk3401a/win32-gui/game-gui.vcxproj.filters b/examples/qwin-gui/game-gui/game-gui.vcxproj.filters similarity index 99% rename from examples/arm-cm/game_efm32-slstk3401a/win32-gui/game-gui.vcxproj.filters rename to examples/qwin-gui/game-gui/game-gui.vcxproj.filters index 4fb90046..ba710d73 100644 --- a/examples/arm-cm/game_efm32-slstk3401a/win32-gui/game-gui.vcxproj.filters +++ b/examples/qwin-gui/game-gui/game-gui.vcxproj.filters @@ -2,7 +2,6 @@ - @@ -53,6 +52,7 @@ QP + diff --git a/examples/qwin-gui/game-gui/game.h b/examples/qwin-gui/game-gui/game.h new file mode 100644 index 00000000..2b48bd58 --- /dev/null +++ b/examples/qwin-gui/game-gui/game.h @@ -0,0 +1,160 @@ +//$file${.::game.h} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// +// Model: game.qm +// File: ${.::game.h} +// +// This code has been generated by QM 5.3.0 . +// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. +// +// SPDX-License-Identifier: GPL-3.0-or-later +// +// This generated code is open source software: you can redistribute it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation. +// +// This code is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// NOTE: +// Alternatively, this generated code may be distributed under the terms +// of Quantum Leaps commercial licenses, which expressly supersede the GNU +// General Public License and are specifically designed for licensees +// interested in retaining the proprietary status of their code. +// +// Contact information: +// +// +// +//$endhead${.::game.h} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +#ifndef GAME_H +#define GAME_H + +enum GameSignals { // signals used in the game + TIME_TICK_SIG = Q_USER_SIG, // published from tick ISR + PLAYER_TRIGGER_SIG, // published by Player (ISR) to trigger the Missile + PLAYER_QUIT_SIG, // published by Player (ISR) to quit the game + GAME_OVER_SIG, // published by Ship when it finishes exploding + + // insert other published signals here ... + MAX_PUB_SIG, // the last published signal + + PLAYER_SHIP_UP_SIG, // posted by Player (ISR) to Ship to move it up + PLAYER_SHIP_DOWN_SIG, // posted by Player (ISR) to Ship to let if fall + + BLINK_TIMEOUT_SIG, // signal for Tunnel's blink timeout event + SCREEN_TIMEOUT_SIG, // signal for Tunnel's screen timeout event + + TAKE_OFF_SIG, // from Tunnel to Ship to grant permission to take off + HIT_WALL_SIG, // from Tunnel to Ship when Ship hits the wall + HIT_MINE_SIG, // from Mine to Ship or Missile when it hits the mine + SHIP_IMG_SIG, // from Ship to the Tunnel to draw and check for hits + MISSILE_IMG_SIG, // from Missile the Tunnel to draw and check for hits + MINE_IMG_SIG, // sent by Mine to the Tunnel to draw the mine + MISSILE_FIRE_SIG, // sent by Ship to the Missile to fire + DESTROYED_MINE_SIG, // from Missile to Ship when Missile destroyed Mine + EXPLOSION_SIG, // from any exploding object to render the explosion + MINE_PLANT_SIG, // from Tunnel to the Mine to plant it + MINE_DISABLED_SIG, // from Mine to Tunnel when it becomes disabled + MINE_RECYCLE_SIG, // sent by Tunnel to Mine to recycle the mine + SCORE_SIG, // from Ship to Tunnel to adjust game level based on score + + MAX_SIG // the last signal (keep always last) +}; + +#define GAME_TUNNEL_WIDTH BSP_SCREEN_WIDTH +#define GAME_TUNNEL_HEIGHT (BSP_SCREEN_HEIGHT - 10U) +#define GAME_MINES_MAX 5U +#define GAME_MINES_DIST_MIN 10U +#define GAME_SPEED_X 1U +#define GAME_MISSILE_SPEED_X 2U +#define GAME_SHIP_X 10U +#define GAME_SHIP_Y (GAME_TUNNEL_HEIGHT / 2U) +#define GAME_WALLS_GAP_Y 50U +#define GAME_WALLS_MIN_GAP_Y 20U + +enum GameBitmapIds { + SHIP_BMP, + MISSILE_BMP, + MINE1_BMP, + MINE2_BMP, + MINE2_MISSILE_BMP, + EXPLOSION0_BMP, + EXPLOSION1_BMP, + EXPLOSION2_BMP, + EXPLOSION3_BMP, + MAX_BMP +}; + +// declare shared facilities +//$declare${Shared} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${Shared::ObjectPosEvt} .................................................... +typedef struct { +// protected: + QEvt super; + +// public: + uint8_t x; + uint8_t y; +} ObjectPosEvt; + +//${Shared::ObjectImageEvt} .................................................. +typedef struct { +// protected: + QEvt super; + +// public: + uint8_t x; + int8_t y; + uint8_t bmp; +} ObjectImageEvt; + +//${Shared::MineEvt} ......................................................... +typedef struct { +// protected: + QEvt super; + +// public: + uint8_t id; +} MineEvt; + +//${Shared::ScoreEvt} ........................................................ +typedef struct { +// protected: + QEvt super; + +// public: + uint16_t score; +} ScoreEvt; + +//${Shared::AO_Tunnel} ....................................................... +// opaque AO pointer +extern QActive * const AO_Tunnel; + +//${Shared::AO_Ship} ......................................................... +// opaque AO pointer +extern QActive * const AO_Ship; + +//${Shared::AO_Missile} ...................................................... +// opaque AO pointer +extern QActive * const AO_Missile; + +//${Shared::Tunnel_ctor_call} ................................................ +void Tunnel_ctor_call(void); + +//${Shared::Ship_ctor_call} .................................................. +void Ship_ctor_call(void); + +//${Shared::Missile_ctor_call} ............................................... +void Missile_ctor_call(void); + +//${Shared::Mine1_ctor_call} ................................................. +QHsm * Mine1_ctor_call(uint8_t id); + +//${Shared::Mine2_ctor_call} ................................................. +QHsm * Mine2_ctor_call(uint8_t id); +//$enddecl${Shared} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +#endif // GAME_H diff --git a/examples/qwin-gui/game-gui/game.qm b/examples/qwin-gui/game-gui/game.qm new file mode 100644 index 00000000..4256eb9b --- /dev/null +++ b/examples/qwin-gui/game-gui/game.qm @@ -0,0 +1,1458 @@ + + + "Fly 'n' Shoot" game model from Chapters 1 & 9 of PSiCC2 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + // opaque AO pointer + = &Tunnel_inst.super; + + + + // opaque AO pointer + = &Ship_inst.super; + + + + // opaque AO pointer + = &Missile_inst.super; + + + + Tunnel_ctor(&Tunnel_inst); + + + + Ship_ctor(&Ship_inst); + + + + Missile_ctor(&Missile_inst); + + + + + + Q_REQUIRE(id < GAME_MINES_MAX); +Mine1_ctor(&Mine1_inst[id]); +return &Mine1_inst[id].super; + + + + + + Q_REQUIRE(id < GAME_MINES_MAX); +Mine2_ctor(&Mine2_inst[id]); +return &Mine2_inst[id].super; + + + + + + + Tunnel Active Object + + + + + + + + + + + + + + + + + + + + + + + + + static instance (Singleton) + + + + uint32_t rnd; + +rnd = (BSP_random() & 0xFFU); + +// reduce the top wall thickness 18.75% of the time +if ((rnd < 48U) && (me->wall_thickness_top > 0U)) { + --me->wall_thickness_top; +} + +// reduce the bottom wall thickness 18.75% of the time +if ((rnd > 208U) && (me->wall_thickness_bottom > 0U)) { + --me->wall_thickness_bottom; +} + +rnd = (BSP_random() & 0xFFU); + +// grow the bottom wall thickness 19.14% of the time +if ((rnd < 49U) + && ((GAME_TUNNEL_HEIGHT + - me->wall_thickness_top + - me->wall_thickness_bottom) > me->wall_gap)) +{ + ++me->wall_thickness_bottom; +} + +// grow the top wall thickness 19.14% of the time +if ((rnd > 207U) + && ((GAME_TUNNEL_HEIGHT + - me->wall_thickness_top + - me->wall_thickness_bottom) > me->wall_gap)) +{ + ++me->wall_thickness_top; +} + +// advance the Tunnel by 1 game step to the left +// and copy the Tunnel layer to the main frame buffer +BSP_advanceWalls(me->wall_thickness_top, me->wall_thickness_bottom); + + + + uint32_t rnd = (BSP_random() & 0xFFU); + +if (me->last_mine_x > 0U) { + --me->last_mine_x; // shift the last Mine 1 position to the left +} +// last mine far enough? +if ((me->last_mine_x + GAME_MINES_DIST_MIN < GAME_TUNNEL_WIDTH) + && (rnd < 8U)) // place the mines only 5% of the time +{ + uint8_t n; + for (n = 0U; n < Q_DIM(me->mines); ++n) { //look for disabled mines + if (me->mines[n] == (QHsm *)0) { + break; + } + } + if (n < Q_DIM(me->mines)) { // a disabled Mine found? + rnd = (BSP_random() & 0xFFFFU); + + if ((rnd & 1U) == 0U) { // choose the type of the mine + me->mines[n] = me->mine1_pool[n]; + } + else { + me->mines[n] = me->mine2_pool[n]; + } + + // new Mine is planted by the end of the tunnel + me->last_mine_x = GAME_TUNNEL_WIDTH - 8U; + + // choose a random y-position for the Mine in the Tunnel + rnd %= (GAME_TUNNEL_HEIGHT + - me->wall_thickness_top + - me->wall_thickness_bottom - 4U); + me->last_mine_y = (uint8_t)(me->wall_thickness_top + 2U + rnd); + + ObjectPosEvt ope; // event to dispatch to the Mine + QEvt_ctor(&ope.super, MINE_PLANT_SIG); + ope.x = me->last_mine_x; + ope.y = me->last_mine_y; + // direct dispatch + QASM_DISPATCH(me->mines[n], &ope.super, me->super.prio); + } +} + + + + + + for (uint8_t n = 0U; n < GAME_MINES_MAX; ++n) { + if (me->mines[n] != (QHsm *)0) { // is the mine used? + QASM_DISPATCH(me->mines[n], e, me->super.prio); + } +} + + + + constructor + uint8_t n; +QActive_ctor(&me->super, Q_STATE_CAST(&Tunnel_initial)); +QTimeEvt_ctorX(&me->blinkTimeEvt, &me->super, BLINK_TIMEOUT_SIG, 0U); +QTimeEvt_ctorX(&me->screenTimeEvt, &me->super, SCREEN_TIMEOUT_SIG, 0U); +for (n = 0; n < GAME_MINES_MAX; ++n) { + me->mine1_pool[n] = Mine1_ctor_call(n); // instantiate Mine1 + me->mine2_pool[n] = Mine2_ctor_call(n); // instantiate Mine2 + me->mines[n] = (QHsm *)0; // mine 'n' is unused +} +me->last_mine_x = 0; // the last mine at the right edge of the tunnel +me->last_mine_y = 0; + + + + + + uint8_t n; +for (n = 0U; n < GAME_MINES_MAX; ++n) { + QASM_INIT(me->mine1_pool[n], (void *)0, me->super.prio); + QASM_INIT(me->mine2_pool[n], (void *)0, me->super.prio); +} +BSP_randomSeed(1234); // seed the pseudo-random generator + +QActive_subscribe(&me->super, TIME_TICK_SIG); +QActive_subscribe(&me->super, PLAYER_TRIGGER_SIG); +QActive_subscribe(&me->super, PLAYER_QUIT_SIG); + +// object dictionaries... +QS_OBJ_DICTIONARY(&Tunnel_inst.blinkTimeEvt); +QS_OBJ_DICTIONARY(&Tunnel_inst.screenTimeEvt); + +// local signals... +QS_SIG_DICTIONARY(BLINK_TIMEOUT_SIG, me); +QS_SIG_DICTIONARY(SCREEN_TIMEOUT_SIG, me); +QS_SIG_DICTIONARY(SHIP_IMG_SIG, me); +QS_SIG_DICTIONARY(MISSILE_IMG_SIG, me); +QS_SIG_DICTIONARY(MINE_IMG_SIG, me); +QS_SIG_DICTIONARY(MINE_DISABLED_SIG, me); +QS_SIG_DICTIONARY(EXPLOSION_SIG, me); +QS_SIG_DICTIONARY(SCORE_SIG, me); + +(void)par; // unused parameter + + + + + + + + + Q_ASSERT((Q_EVT_CAST(MineEvt)->id < GAME_MINES_MAX) + && (me->mines[Q_EVT_CAST(MineEvt)->id] != (QHsm *)0)); +me->mines[Q_EVT_CAST(MineEvt)->id] = (QHsm *)0; + + + + + + + + + + + + + QTimeEvt_armX(&me->blinkTimeEvt, BSP_TICKS_PER_SEC/2U, + BSP_TICKS_PER_SEC/2U); +QTimeEvt_armX(&me->screenTimeEvt, BSP_TICKS_PER_SEC*5U, 0U); +me->blink_ctr = 0U; +BSP_paintString(24U, (GAME_TUNNEL_HEIGHT / 2U) - 8U, "Quantum LeAps"); +BSP_paintString(16U, (GAME_TUNNEL_HEIGHT / 2U) + 0U, "state-machine.com"); + +BSP_paintString(1U, GAME_TUNNEL_HEIGHT - 18U, "Fire missile: BTN0"); +BSP_paintString(1U, GAME_TUNNEL_HEIGHT - 10U, "Fly ship up: BTN1"); + +BSP_updateScreen(); + QTimeEvt_disarm(&me->blinkTimeEvt); +QTimeEvt_disarm(&me->screenTimeEvt); + + + + + + + + + me->blink_ctr ^= 1U; // toggle the blink counter + + + me->blink_ctr == 0U + BSP_paintString(24U + 8U*6U, (GAME_TUNNEL_HEIGHT / 2U) - 8U, "LeAps"); +BSP_updateScreen(); + + + + + + + else + BSP_paintString(24U + 8U*6U, (GAME_TUNNEL_HEIGHT / 2U) - 8U, "LeaPs"); +BSP_updateScreen(); + + + + + + + + + + + + + + + + me->last_mine_x = 0U; // last mine at right edge of the tunnel +me->last_mine_y = 0U; +// set the tunnel properties... +me->wall_thickness_top = 0U; +me->wall_thickness_bottom = 0U; +me->wall_gap = GAME_WALLS_GAP_Y; + +// clear the tunnel walls +BSP_clearWalls(); + +QTimeEvt_armX(&me->blinkTimeEvt, BSP_TICKS_PER_SEC/2U, + BSP_TICKS_PER_SEC/2U); // every 1/2 sec +QTimeEvt_armX(&me->screenTimeEvt, BSP_TICKS_PER_SEC*20U, 0U); + +me->blink_ctr = 0U; // init the blink counter + QTimeEvt_disarm(&me->blinkTimeEvt); +QTimeEvt_disarm(&me->screenTimeEvt); + + + me->blink_ctr ^= 1U; // toggle the blink cunter + + + + + + + + + + + + + Tunnel_advance(me); +if (me->blink_ctr != 0U) { + // add the text bitmap into the frame buffer + BSP_paintString((GAME_TUNNEL_WIDTH - 10U*6U)/2U, + (GAME_TUNNEL_HEIGHT - 4U)/2U, + "Press BTN0"); +} +BSP_updateScreen(); + + + + + + + + + + + + + + + + + + static QEvt const takeoff = QEVT_INITIALIZER(TAKE_OFF_SIG); +me->wall_gap = GAME_WALLS_GAP_Y; +QACTIVE_POST(AO_Ship, &takeoff, me); // post the TAKEOFF sig + static QEvt const recycle = QEVT_INITIALIZER(MINE_RECYCLE_SIG); +Tunnel_dispatchToAllMines(me, &recycle); // recycle all Mines + + + // render this frame on the display +BSP_updateScreen(); +Tunnel_advance(me); +Tunnel_plantMine(me); +Tunnel_dispatchToAllMines(me, e); + + + + + + + uint8_t x = Q_EVT_CAST(ObjectImageEvt)->x; +int8_t y = Q_EVT_CAST(ObjectImageEvt)->y; +uint8_t bmp = Q_EVT_CAST(ObjectImageEvt)->bmp; + +// did the Ship/Missile hit the tunnel wall? +if (BSP_isWallHit(bmp, x, y)) { + static QEvt const hit = QEVT_INITIALIZER(HIT_WALL_SIG); + QACTIVE_POST(AO_Ship, &hit, me); +} +BSP_paintBitmap(x, y, bmp); +Tunnel_dispatchToAllMines(me, e); // let Mines check for hits + + + + + + + uint8_t x = Q_EVT_CAST(ObjectImageEvt)->x; +int8_t y = Q_EVT_CAST(ObjectImageEvt)->y; +uint8_t bmp = Q_EVT_CAST(ObjectImageEvt)->bmp; + +// did the Ship/Missile hit the tunnel wall? +if (BSP_isWallHit(bmp, x, y)) { + static QEvt const hit = QEVT_INITIALIZER(HIT_WALL_SIG); + QACTIVE_POST(AO_Missile, &hit, me); +} +BSP_paintBitmap(x, y, bmp); +Tunnel_dispatchToAllMines(me, e); // let Mines check for hits + + + + + + + BSP_paintBitmap(Q_EVT_CAST(ObjectImageEvt)->x, + Q_EVT_CAST(ObjectImageEvt)->y, + Q_EVT_CAST(ObjectImageEvt)->bmp); + + + + + + + BSP_paintBitmap(Q_EVT_CAST(ObjectImageEvt)->x, + Q_EVT_CAST(ObjectImageEvt)->y, + Q_EVT_CAST(ObjectImageEvt)->bmp); + + + + + + + BSP_updateScore(Q_EVT_CAST(ScoreEvt)->score); +// increase difficulty of the game: +// the tunnel gets narrower as the score goes up +me->wall_gap = (uint8_t)(GAME_WALLS_GAP_Y + - Q_EVT_CAST(ScoreEvt)->score/100U); +if (me->wall_gap < GAME_WALLS_MIN_GAP_Y) { + me->wall_gap = GAME_WALLS_MIN_GAP_Y; +} + + + + + + + BSP_clearWalls(); +BSP_updateScore(Q_EVT_CAST(ScoreEvt)->score); +BSP_updateScreen(); + + + + + + + + + + + + QTimeEvt_armX(&me->blinkTimeEvt, BSP_TICKS_PER_SEC/2U, + BSP_TICKS_PER_SEC/2U); // every 1/2 sec +QTimeEvt_armX(&me->screenTimeEvt, BSP_TICKS_PER_SEC*5U, 0U); +me->blink_ctr = 0U; +BSP_paintString((GAME_TUNNEL_WIDTH - 6U * 9U) / 2U, + (GAME_TUNNEL_HEIGHT / 2U) - 4U, + "Game Over"); +BSP_updateScreen(); + QTimeEvt_disarm(&me->blinkTimeEvt); +QTimeEvt_disarm(&me->screenTimeEvt); +BSP_updateScore(0); // update the score on the display + + + me->blink_ctr ^= 1U; // toggle the blink counter +BSP_paintString((GAME_TUNNEL_WIDTH - 6U*9U) / 2U, + (GAME_TUNNEL_HEIGHT / 2U) - 4U, + ((me->blink_ctr == 0U) + ? "Game Over" + : " ")); +BSP_updateScreen(); + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + BSP_displayOff(); // power down the display +QTimeEvt_armX(&me->screenTimeEvt, BSP_TICKS_PER_SEC*3U, 0U); + QTimeEvt_disarm(&me->screenTimeEvt); +BSP_displayOn(); // power up the display + + + + + + + + + + + + + + uint32_t rnd = BSP_random(); +// clear the screen frame buffer +BSP_clearFB(); +BSP_paintString((uint8_t)(rnd % (GAME_TUNNEL_WIDTH - 10U*6U)), + (uint8_t) (rnd % (GAME_TUNNEL_HEIGHT - 8U)), + "Press BTN0"); +BSP_updateScreen(); +QTimeEvt_armX(&me->screenTimeEvt, BSP_TICKS_PER_SEC/2U, 0U); + QTimeEvt_disarm(&me->screenTimeEvt); +BSP_clearFB(); +BSP_updateScreen(); + + + + + + + + + + + + + + + + + + // clear the screen +BSP_clearFB(); +BSP_updateScreen(); +QF_stop(); // stop QF and cleanup + + + + + + + + + + Ship Active Object + + + + + vertical position of the ship in the 8s2 fixed-point notation. + + + + + + + + static instance (Singleton) + + + + constructor + QActive_ctor(&me->super, Q_STATE_CAST(&Ship_initial)); +me->x = GAME_SHIP_X; +me->y = (GAME_SHIP_Y << 2); + + + + + + (void)par; // usused parameter + +QActive_subscribe(&me->super, TIME_TICK_SIG); +QActive_subscribe(&me->super, PLAYER_TRIGGER_SIG); + +// local signals... +//QS_SIG_DICTIONARY(PLAYER_SHIP_MOVE_SIG, me); +QS_SIG_DICTIONARY(TAKE_OFF_SIG, me); +QS_SIG_DICTIONARY(HIT_WALL_SIG, me); +QS_SIG_DICTIONARY(HIT_MINE_SIG, me); +QS_SIG_DICTIONARY(DESTROYED_MINE_SIG, me); + + + + + + + + + + + + + + + + + + + + + + + + + ScoreEvt *sev; +me->score = 0U; // reset the score +sev = Q_NEW(ScoreEvt, SCORE_SIG); +sev->score = me->score; +QACTIVE_POST(AO_Tunnel, (QEvt *)sev, me); + +// lauch the ship from the initial position +me->x = GAME_SHIP_X; +me->y = (GAME_SHIP_Y << 2); + + + ObjectImageEvt *oie; + +if (BSP_isThrottle()) { + if (me->y > 0) { + me->y -= 1U; + } +} +else { + if (me->y < (GAME_TUNNEL_HEIGHT << 2)) { + me->y += 1U; + } +} + +// tell the Tunnel to draw the Ship and test for hits +oie = Q_NEW(ObjectImageEvt, SHIP_IMG_SIG); +oie->x = me->x; +oie->y = (uint8_t)(me->y >> 2); +oie->bmp = SHIP_BMP; +QACTIVE_POST(AO_Tunnel, (QEvt *)oie, me); + +++me->score; // increment the score for surviving another tick + +if ((me->score % 10U) == 0U) { // is the score "round"? + ScoreEvt *sev = Q_NEW(ScoreEvt, SCORE_SIG); + sev->score = me->score; + QACTIVE_POST(AO_Tunnel, (QEvt *)sev, me); +} + + + + + + + ObjectPosEvt *ope = Q_NEW(ObjectPosEvt, MISSILE_FIRE_SIG); +ope->x = me->x; +ope->y = (me->y >> 2) + SHIP_HEIGHT - 1U; +QACTIVE_POST(AO_Missile, (QEvt *)ope, me); + + + + + + + me->score += Q_EVT_CAST(ScoreEvt)->score; +// the score will be sent to the Tunnel by the next TIME_TICK + + + + + + + + + + + + + + + + + + + + + + + me->exp_ctr = 0U; + + + + + me->exp_ctr < 15U + ObjectImageEvt *oie; +++me->exp_ctr; +// tell the Tunnel to draw the current stage of Explosion +oie = Q_NEW(ObjectImageEvt, EXPLOSION_SIG); +oie->bmp = EXPLOSION0_BMP + (me->exp_ctr >> 2); +oie->x = me->x; // x of explosion +oie->y = (int8_t)((int)(me->y >> 2) - 4U + SHIP_HEIGHT); +QACTIVE_POST(AO_Tunnel, (QEvt *)oie, me); + + + + + + + + ScoreEvt *gameOver = Q_NEW(ScoreEvt, GAME_OVER_SIG); +gameOver->score = me->score; +QACTIVE_POST(AO_Tunnel, (QEvt *)gameOver, me); + + + + + + + + + + + + + + + + + + + + Missile Active Object + + + + + + + + + static instance (Singleton) + + + + constructor + QActive_ctor(&me->super, Q_STATE_CAST(&Missile_initial)); + + + + + + (void)par; // unused parameter +QActive_subscribe(&me->super, TIME_TICK_SIG); + +// local signals +QS_SIG_DICTIONARY(MISSILE_FIRE_SIG, me); +QS_SIG_DICTIONARY(HIT_WALL_SIG, me); +QS_SIG_DICTIONARY(DESTROYED_MINE_SIG, me); + + + + + + + + + me->x = Q_EVT_CAST(ObjectPosEvt)->x; +me->y = Q_EVT_CAST(ObjectPosEvt)->y; + + + + + + + + + + + + + me->x + GAME_MISSILE_SPEED_X < GAME_TUNNEL_WIDTH + ObjectImageEvt *oie; +me->x += GAME_MISSILE_SPEED_X; +//tell the Tunnel to draw the Missile and test for wall hits +oie = Q_NEW(ObjectImageEvt, MISSILE_IMG_SIG); +oie->x = me->x; +oie->y = me->y; +oie->bmp = MISSILE_BMP; +QACTIVE_POST(AO_Tunnel, (QEvt *)oie, me); + + + + + + + + + + + + + + + + + + + + + + + + QACTIVE_POST(AO_Ship, e, me); + + + + + + + + + me->exp_ctr = 0U; + + + + + (me->x >= GAME_SPEED_X) && (me->exp_ctr < 15U) + ObjectImageEvt *oie; + +++me->exp_ctr; // advance the explosion counter +me->x -= GAME_SPEED_X; // move the explosion by one step + +// tell the Tunnel to render the current stage of Explosion +oie = Q_NEW(ObjectImageEvt, EXPLOSION_SIG); +oie->x = me->x + 3U; // x-pos of explosion +oie->y = (int8_t)((int)me->y - 4U); // y-pos +oie->bmp = EXPLOSION0_BMP + (me->exp_ctr >> 2); +QACTIVE_POST(AO_Tunnel, (QEvt *)oie, me); + + + + + + + + + + + + + + + + + + + + + + + + + The Mine1 orthogonal component + + + + + + + + + static instances (Singletons) + + + + constructor + // superclass' ctor +QHsm_ctor(&me->super, Q_STATE_CAST(&Mine1_initial)); + + + + + + static uint8_t dict_sent; + +if (!dict_sent) { + QS_OBJ_DICTIONARY(&Mine1_inst[0]); + QS_OBJ_DICTIONARY(&Mine1_inst[1]); + QS_OBJ_DICTIONARY(&Mine1_inst[2]); + QS_OBJ_DICTIONARY(&Mine1_inst[3]); + QS_OBJ_DICTIONARY(&Mine1_inst[4]); + + QS_FUN_DICTIONARY(&Mine1_initial);//fun. dictionaries for Mine1 HSM + QS_FUN_DICTIONARY(&Mine1_unused); + QS_FUN_DICTIONARY(&Mine1_used); + QS_FUN_DICTIONARY(&Mine1_planted); + QS_FUN_DICTIONARY(&Mine1_exploding); + + dict_sent = 1U; +} +// local signals +QS_SIG_DICTIONARY(MINE_PLANT_SIG, me); +QS_SIG_DICTIONARY(MINE_DISABLED_SIG, me); +QS_SIG_DICTIONARY(MINE_RECYCLE_SIG, me); +QS_SIG_DICTIONARY(SHIP_IMG_SIG, me); +QS_SIG_DICTIONARY(MISSILE_IMG_SIG, me); + +(void)par; // unused parameter + + + + + + + + + me->x = Q_EVT_CAST(ObjectPosEvt)->x; +me->y = Q_EVT_CAST(ObjectPosEvt)->y; + + + + + + + + + // tell the Tunnel that this mine is becoming disabled +MineEvt *mev = Q_NEW(MineEvt, MINE_DISABLED_SIG); +mev->id = MINE_ID(me); +QACTIVE_POST(AO_Tunnel, (QEvt *)mev, me); + + + + + + + + + + + + + me->x >= GAME_SPEED_X + ObjectImageEvt *oie; +me->x -= GAME_SPEED_X; // move the mine 1 step +// tell the Tunnel to draw the Mine +oie = Q_NEW(ObjectImageEvt, MINE_IMG_SIG); +oie->x = me->x; +oie->y = me->y; +oie->bmp = MINE1_BMP; +QACTIVE_POST(AO_Tunnel, (QEvt *)oie, me); + + + + + + + + + + + + + + + + + + uint8_t x = Q_EVT_CAST(ObjectImageEvt)->x; +uint8_t y = Q_EVT_CAST(ObjectImageEvt)->y; +uint8_t bmp = Q_EVT_CAST(ObjectImageEvt)->bmp; + + + BSP_doBitmapsOverlap(MINE1_BMP, me->x, me->y, bmp, x, y) + static MineEvt const mine1_hit = { + QEVT_INITIALIZER(HIT_MINE_SIG), // the QEvt base instance + 1U // type of the mine (1 for Mine type-1) +}; +QACTIVE_POST(AO_Ship, (QEvt *)&mine1_hit, me); +// go straight to 'disabled' and let the Ship do the exploding + + + + + + + + + + + uint8_t x = Q_EVT_CAST(ObjectImageEvt)->x; +uint8_t y = Q_EVT_CAST(ObjectImageEvt)->y; +uint8_t bmp = Q_EVT_CAST(ObjectImageEvt)->bmp; + + + BSP_doBitmapsOverlap(MINE1_BMP, me->x, me->y, bmp, x, y) + static ScoreEvt const mine1_destroyed = { + QEVT_INITIALIZER(DESTROYED_MINE_SIG), // the QEvt base instance + 25U // score for destroying Mine type-1 +}; +QACTIVE_POST(AO_Missile, (QEvt *)&mine1_destroyed, me); + + + + + + + + + + + + + me->exp_ctr = 0U; + + + + + (me->x >= GAME_SPEED_X) && (me->exp_ctr < 15) + ObjectImageEvt *oie; +++me->exp_ctr; // advance the explosion counter +me->x -= GAME_SPEED_X; // move explosion by 1 step + +// tell the Game to render the current stage of Explosion +oie = Q_NEW(ObjectImageEvt, EXPLOSION_SIG); +oie->x = me->x + 1U; // x of explosion +oie->y = (int8_t)((int)me->y - 4 + 2); // y of explosion +oie->bmp = EXPLOSION0_BMP + (me->exp_ctr >> 2); +QACTIVE_POST(AO_Tunnel, (QEvt *)oie, me); + + + + + + + + + + + + + + + + + + + + + + + + + + + + + The Mine2 orthogonal component + + + + + + + + + static instances (Singletons) + + + + constructor + // superclass' ctor +QHsm_ctor(&me->super, Q_STATE_CAST(&Mine2_initial)); + + + + + + static uint8_t dict_sent; + +if (!dict_sent) { + // object dictionaries for Mine2 pool... + QS_OBJ_DICTIONARY(&Mine2_inst[0]); + QS_OBJ_DICTIONARY(&Mine2_inst[1]); + QS_OBJ_DICTIONARY(&Mine2_inst[2]); + QS_OBJ_DICTIONARY(&Mine2_inst[3]); + QS_OBJ_DICTIONARY(&Mine2_inst[4]); + + //function dictionaries for Mine2 HSM... + QS_FUN_DICTIONARY(&Mine2_initial); + QS_FUN_DICTIONARY(&Mine2_unused); + QS_FUN_DICTIONARY(&Mine2_used); + QS_FUN_DICTIONARY(&Mine2_planted); + QS_FUN_DICTIONARY(&Mine2_exploding); + + dict_sent = 1U; +} +// local signals... +QS_SIG_DICTIONARY(MINE_PLANT_SIG, me); +QS_SIG_DICTIONARY(MINE_DISABLED_SIG, me); +QS_SIG_DICTIONARY(MINE_RECYCLE_SIG, me); +QS_SIG_DICTIONARY(SHIP_IMG_SIG, me); +QS_SIG_DICTIONARY(MISSILE_IMG_SIG, me); + +(void)par; // unused parameter + + + + + + + + + me->x = Q_EVT_CAST(ObjectPosEvt)->x; +me->y = Q_EVT_CAST(ObjectPosEvt)->y; + + + + + + + + + // tell the Tunnel that this mine is becoming disabled +MineEvt *mev = Q_NEW(MineEvt, MINE_DISABLED_SIG); +mev->id = MINE_ID(me); +QACTIVE_POST(AO_Tunnel, (QEvt *)mev, me); + + + + + + + + + + + + + me->x >= GAME_SPEED_X + ObjectImageEvt *oie; + me->x -= GAME_SPEED_X; // move the mine 1 step +// tell the Tunnel to draw the Mine +oie = Q_NEW(ObjectImageEvt, MINE_IMG_SIG); +oie->x = me->x; +oie->y = me->y; +oie->bmp = MINE2_BMP; +QACTIVE_POST(AO_Tunnel, (QEvt *)oie, me); + + + + + + + + + + + + + + + + + + uint8_t x = Q_EVT_CAST(ObjectImageEvt)->x; +uint8_t y = Q_EVT_CAST(ObjectImageEvt)->y; +uint8_t bmp = Q_EVT_CAST(ObjectImageEvt)->bmp; + + + BSP_doBitmapsOverlap(MINE2_BMP, me->x, me->y, bmp, x, y) + static MineEvt const mine1_hit = { + QEVT_INITIALIZER(HIT_MINE_SIG), // the QEvt base instance + 2U // type of the mine (2 for Mine type-2) +}; +QACTIVE_POST(AO_Ship, (QEvt *)&mine1_hit, me); +// go straight to 'disabled' and let the Ship do the exploding + + + + + + + + + + + uint8_t x = Q_EVT_CAST(ObjectImageEvt)->x; +uint8_t y = Q_EVT_CAST(ObjectImageEvt)->y; +uint8_t bmp = Q_EVT_CAST(ObjectImageEvt)->bmp; + + + BSP_doBitmapsOverlap(MINE2_MISSILE_BMP, me->x, me->y, bmp, x, y) + // NOTE: Mine type-2 is nastier than Mine type-1. +// The type-2 mine can hit the Ship with any of its +// "tentacles". However, it can be destroyed by the +// Missile only by hitting its center, defined as +// a smaller bitmap MINE2_MISSILE_BMP. +static ScoreEvt const mine2_destroyed = { + QEVT_INITIALIZER(DESTROYED_MINE_SIG), // the QEvt base instance + 45U // score for destroying Mine type-2 +}; +QACTIVE_POST(AO_Missile, (QEvt *)&mine2_destroyed, me); + + + + + + + + + + + + + me->exp_ctr = 0U; + + + + + (me->x >= GAME_SPEED_X) && (me->exp_ctr < 15U) + ObjectImageEvt *oie; +++me->exp_ctr; // advance the explosion counter + me->x -= GAME_SPEED_X; // move explosion by 1 step + +// tell the Game to render the current stage of Explosion +oie = Q_NEW(ObjectImageEvt, EXPLOSION_SIG); +oie->x = me->x + 1U; // x of explosion +oie->y = (int8_t)((int)me->y - 4 + 2); // y of explosion +oie->bmp = EXPLOSION0_BMP + (me->exp_ctr >> 2); +QACTIVE_POST(AO_Tunnel, (QEvt *)oie, me); + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #ifndef GAME_H +#define GAME_H + +enum GameSignals { // signals used in the game + TIME_TICK_SIG = Q_USER_SIG, // published from tick ISR + PLAYER_TRIGGER_SIG, // published by Player (ISR) to trigger the Missile + PLAYER_QUIT_SIG, // published by Player (ISR) to quit the game + GAME_OVER_SIG, // published by Ship when it finishes exploding + + // insert other published signals here ... + MAX_PUB_SIG, // the last published signal + + PLAYER_SHIP_UP_SIG, // posted by Player (ISR) to Ship to move it up + PLAYER_SHIP_DOWN_SIG, // posted by Player (ISR) to Ship to let if fall + + BLINK_TIMEOUT_SIG, // signal for Tunnel's blink timeout event + SCREEN_TIMEOUT_SIG, // signal for Tunnel's screen timeout event + + TAKE_OFF_SIG, // from Tunnel to Ship to grant permission to take off + HIT_WALL_SIG, // from Tunnel to Ship when Ship hits the wall + HIT_MINE_SIG, // from Mine to Ship or Missile when it hits the mine + SHIP_IMG_SIG, // from Ship to the Tunnel to draw and check for hits + MISSILE_IMG_SIG, // from Missile the Tunnel to draw and check for hits + MINE_IMG_SIG, // sent by Mine to the Tunnel to draw the mine + MISSILE_FIRE_SIG, // sent by Ship to the Missile to fire + DESTROYED_MINE_SIG, // from Missile to Ship when Missile destroyed Mine + EXPLOSION_SIG, // from any exploding object to render the explosion + MINE_PLANT_SIG, // from Tunnel to the Mine to plant it + MINE_DISABLED_SIG, // from Mine to Tunnel when it becomes disabled + MINE_RECYCLE_SIG, // sent by Tunnel to Mine to recycle the mine + SCORE_SIG, // from Ship to Tunnel to adjust game level based on score + + MAX_SIG // the last signal (keep always last) +}; + +#define GAME_TUNNEL_WIDTH BSP_SCREEN_WIDTH +#define GAME_TUNNEL_HEIGHT (BSP_SCREEN_HEIGHT - 10U) +#define GAME_MINES_MAX 5U +#define GAME_MINES_DIST_MIN 10U +#define GAME_SPEED_X 1U +#define GAME_MISSILE_SPEED_X 2U +#define GAME_SHIP_X 10U +#define GAME_SHIP_Y (GAME_TUNNEL_HEIGHT / 2U) +#define GAME_WALLS_GAP_Y 50U +#define GAME_WALLS_MIN_GAP_Y 20U + +enum GameBitmapIds { + SHIP_BMP, + MISSILE_BMP, + MINE1_BMP, + MINE2_BMP, + MINE2_MISSILE_BMP, + EXPLOSION0_BMP, + EXPLOSION1_BMP, + EXPLOSION2_BMP, + EXPLOSION3_BMP, + MAX_BMP +}; + +// declare shared facilities +$declare ${Shared} + +#endif // GAME_H + + + + #include "qpc.h" +#include "bsp.h" +#include "game.h" + +// Q_DEFINE_THIS_FILE + +// local objects ----------------------------------------------------------- +$declare ${AOs::Missile} + +// Public-scope objects ---------------------------------------------------- +$define ${Shared::AO_Missile} + +// Active object definition ------------------------------------------------ +$define ${Shared::Missile_ctor_call} +$define ${AOs::Missile} + + + + #include "qpc.h" +#include "bsp.h" +#include "game.h" + +// Q_DEFINE_THIS_FILE + +#define SHIP_WIDTH 5 +#define SHIP_HEIGHT 3 + +// encapsulated delcaration of the Ship active object ---------------------- +$declare ${AOs::Ship} + +// Public-scope objects ---------------------------------------------------- +$define ${Shared::AO_Ship} + +// Active object definition ------------------------------------------------ +$define ${Shared::Ship_ctor_call} +$define ${AOs::Ship} + + + + #include "qpc.h" +#include "bsp.h" +#include "game.h" + +Q_DEFINE_THIS_FILE + +// local objects ----------------------------------------------------------- +$declare ${AOs::Tunnel} + +// Public-scope objects ---------------------------------------------------- +$define ${Shared::AO_Tunnel} + +// Active object definition ================================================ +$define ${Shared::Tunnel_ctor_call} +$define ${AOs::Tunnel} + + + + #include "qpc.h" +#include "bsp.h" +#include "game.h" + +Q_DEFINE_THIS_FILE + +// encapsulated delcaration of the Mine1 HSM ------------------------------- +$declare ${AOs::Mine1} + +// helper macro to provide the ID of this mine +#define MINE_ID(me_) ((uint8_t)((me_) - &Mine1_inst[0])) + +// Mine1 class definition -------------------------------------------------- +$define ${Shared::Mine1_ctor_call} +$define ${AOs::Mine1} + + + + #include "qpc.h" +#include "bsp.h" +#include "game.h" + +Q_DEFINE_THIS_FILE + +// encapsulated delcaration of the Mine2 HSM ------------------------------- +$declare ${AOs::Mine2} + +// helper macro to provide the ID of this mine +#define MINE_ID(me_) ((uint8_t)((me_) - &Mine2_inst[0])) + +// Mine2 class definition -------------------------------------------------- +$define ${Shared::Mine2_ctor_call} +$define ${AOs::Mine2} + + + diff --git a/examples/qwin-gui/game-gui/main.c b/examples/qwin-gui/game-gui/main.c new file mode 100644 index 00000000..2c04c6f8 --- /dev/null +++ b/examples/qwin-gui/game-gui/main.c @@ -0,0 +1,124 @@ +//============================================================================ +// Product: "Fly 'n' Shoot" game example for Windows +// Last updated for version 7.3.0 +// Last updated on 2023-09-06 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// This program is open source software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Alternatively, this program may be distributed and modified under the +// terms of Quantum Leaps commercial licenses, which expressly supersede +// the GNU General Public License and are specifically designed for +// licensees interested in retaining the proprietary status of their code. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Contact information: +// +// +//============================================================================ +#include "qpc.h" +#include "bsp.h" +#include "game.h" + +//Q_DEFINE_THIS_FILE + +// "fudge factor" for Windows, see NOTE1 +enum { WIN_FUDGE_FACTOR = 10 }; + +//............................................................................ +int main() { + QF_init(); // initialize the framework and the underlying RT kernel + BSP_init(); // initialize the Board Support Package + + // init publish-subscribe... + static QSubscrList subscrSto[MAX_PUB_SIG]; + QActive_psInit(subscrSto, Q_DIM(subscrSto)); + + // initialize the event pools... + + //static QF_MPOOL_EL(QEvt) smlPoolSto[10*WIN_FUDGE_FACTOR]; + //QF_poolInit(smlPoolSto, sizeof(smlPoolSto), sizeof(smlPoolSto[0])); + // NOTE: + // After new rounding up, the "small" memory pool has the same block-size + // as the next "medium" pool. If such "small" pool is initialized, + // the next "medium" pool will casuse an assertion (the same block-size + // pool already exists). + + static QF_MPOOL_EL(ObjectImageEvt) + medPoolSto[(2*GAME_MINES_MAX + 10)*WIN_FUDGE_FACTOR]; + QF_poolInit(medPoolSto, sizeof(medPoolSto), sizeof(medPoolSto[0])); + + // object dictionaries for AOs... + QS_OBJ_DICTIONARY(AO_Missile); + QS_OBJ_DICTIONARY(AO_Ship); + QS_OBJ_DICTIONARY(AO_Tunnel); + + // signal dictionaries for globally published events... + QS_SIG_DICTIONARY(TIME_TICK_SIG, (void *)0); + QS_SIG_DICTIONARY(PLAYER_TRIGGER_SIG, (void *)0); + QS_SIG_DICTIONARY(PLAYER_QUIT_SIG, (void *)0); + QS_SIG_DICTIONARY(GAME_OVER_SIG, (void *)0); + + // start the active objects... + static QEvt const *tunnelQueueSto[(GAME_MINES_MAX + 5)*WIN_FUDGE_FACTOR]; + Tunnel_ctor_call(); + QACTIVE_START(AO_Tunnel, + 1U, // QP priority + tunnelQueueSto, Q_DIM(tunnelQueueSto), // evt queue + (void *)0, 0U, // no per-thread stack + (QEvt *)0); // no initialization event + + static QEvt const *shipQueueSto[3*WIN_FUDGE_FACTOR]; + Ship_ctor_call(); + QACTIVE_START(AO_Ship, + 2U, // QP priority + shipQueueSto, Q_DIM(shipQueueSto), // evt queue + (void *)0, 0U, // no per-thread stack + (QEvt *)0); // no initialization event + + static QEvt const *missileQueueSto[2*WIN_FUDGE_FACTOR]; + Missile_ctor_call(); + QACTIVE_START(AO_Missile, + 3U, // QP priority + missileQueueSto, Q_DIM(missileQueueSto), // evt queue + (void *)0, 0U, // no per-thread stack + (QEvt *)0); // no initialization event + + return QF_run(); // run the QF application +} + +//============================================================================ +// NOTE1: +// Windows is not a deterministic real-time system, which means that the +// system can occasionally and unexpectedly "choke and freeze" for a number +// of seconds. The designers of Windows have dealt with these sort of issues +// by massively oversizing the resources available to the applications. For +// example, the default Windows GUI message queues size is 10,000 entries, +// which can dynamically grow to an even larger number. Also the stacks of +// Win32 threads can dynamically grow to several megabytes. +// +// In contrast, the event queues, event pools, and stack size inside the +// real-time embedded (RTE) systems can be (and must be) much smaller, +// because you typically can put an upper bound on the real-time behavior +// and the resulting delays. +// +// To be able to run the unmodified applications designed originally for +// RTE systems on Windows, and to reduce the odds of resource shortages in +// this case, the generous WIN_FUDGE_FACTOR is used to oversize the +// event queues and event pools. +// diff --git a/examples/arm-cm/game_efm32-slstk3401a/win32-gui/make.bat b/examples/qwin-gui/game-gui/make.bat similarity index 100% rename from examples/arm-cm/game_efm32-slstk3401a/win32-gui/make.bat rename to examples/qwin-gui/game-gui/make.bat diff --git a/examples/qwin-gui/game-gui/mine1.c b/examples/qwin-gui/game-gui/mine1.c new file mode 100644 index 00000000..c5d0bed7 --- /dev/null +++ b/examples/qwin-gui/game-gui/mine1.c @@ -0,0 +1,282 @@ +//$file${.::mine1.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// +// Model: game.qm +// File: ${.::mine1.c} +// +// This code has been generated by QM 5.3.0 . +// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. +// +// SPDX-License-Identifier: GPL-3.0-or-later +// +// This generated code is open source software: you can redistribute it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation. +// +// This code is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// NOTE: +// Alternatively, this generated code may be distributed under the terms +// of Quantum Leaps commercial licenses, which expressly supersede the GNU +// General Public License and are specifically designed for licensees +// interested in retaining the proprietary status of their code. +// +// Contact information: +// +// +// +//$endhead${.::mine1.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +#include "qpc.h" +#include "bsp.h" +#include "game.h" + +Q_DEFINE_THIS_FILE + +// encapsulated delcaration of the Mine1 HSM ------------------------------- +//$declare${AOs::Mine1} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${AOs::Mine1} .............................................................. +typedef struct Mine1 { +// protected: + QHsm super; + +// private: + uint8_t x; + uint8_t y; + +// public: + uint8_t exp_ctr; +} Mine1; + +// public: +static void Mine1_ctor(Mine1 * const me); +extern Mine1 Mine1_inst[GAME_MINES_MAX]; + +// protected: +static QState Mine1_initial(Mine1 * const me, void const * const par); +static QState Mine1_unused(Mine1 * const me, QEvt const * const e); +static QState Mine1_used(Mine1 * const me, QEvt const * const e); +static QState Mine1_planted(Mine1 * const me, QEvt const * const e); +static QState Mine1_exploding(Mine1 * const me, QEvt const * const e); +//$enddecl${AOs::Mine1} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +// helper macro to provide the ID of this mine +#define MINE_ID(me_) ((uint8_t)((me_) - &Mine1_inst[0])) + +// Mine1 class definition -------------------------------------------------- +//$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// Check for the minimum required QP version +#if (QP_VERSION < 730U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) +#error qpc version 7.3.0 or higher required +#endif +//$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +//$define${Shared::Mine1_ctor_call} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${Shared::Mine1_ctor_call} ................................................. +QHsm * Mine1_ctor_call(uint8_t id) { + Q_REQUIRE(id < GAME_MINES_MAX); + Mine1_ctor(&Mine1_inst[id]); + return &Mine1_inst[id].super; +} +//$enddef${Shared::Mine1_ctor_call} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +//$define${AOs::Mine1} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${AOs::Mine1} .............................................................. +Mine1 Mine1_inst[GAME_MINES_MAX]; + +//${AOs::Mine1::ctor} ........................................................ +static void Mine1_ctor(Mine1 * const me) { + // superclass' ctor + QHsm_ctor(&me->super, Q_STATE_CAST(&Mine1_initial)); +} + +//${AOs::Mine1::SM} .......................................................... +static QState Mine1_initial(Mine1 * const me, void const * const par) { + //${AOs::Mine1::SM::initial} + static uint8_t dict_sent; + + if (!dict_sent) { + QS_OBJ_DICTIONARY(&Mine1_inst[0]); + QS_OBJ_DICTIONARY(&Mine1_inst[1]); + QS_OBJ_DICTIONARY(&Mine1_inst[2]); + QS_OBJ_DICTIONARY(&Mine1_inst[3]); + QS_OBJ_DICTIONARY(&Mine1_inst[4]); + + QS_FUN_DICTIONARY(&Mine1_initial);//fun. dictionaries for Mine1 HSM + QS_FUN_DICTIONARY(&Mine1_unused); + QS_FUN_DICTIONARY(&Mine1_used); + QS_FUN_DICTIONARY(&Mine1_planted); + QS_FUN_DICTIONARY(&Mine1_exploding); + + dict_sent = 1U; + } + // local signals + QS_SIG_DICTIONARY(MINE_PLANT_SIG, me); + QS_SIG_DICTIONARY(MINE_DISABLED_SIG, me); + QS_SIG_DICTIONARY(MINE_RECYCLE_SIG, me); + QS_SIG_DICTIONARY(SHIP_IMG_SIG, me); + QS_SIG_DICTIONARY(MISSILE_IMG_SIG, me); + + (void)par; // unused parameter + return Q_TRAN(&Mine1_unused); +} + +//${AOs::Mine1::SM::unused} .................................................. +static QState Mine1_unused(Mine1 * const me, QEvt const * const e) { + QState status_; + switch (e->sig) { + //${AOs::Mine1::SM::unused::MINE_PLANT} + case MINE_PLANT_SIG: { + me->x = Q_EVT_CAST(ObjectPosEvt)->x; + me->y = Q_EVT_CAST(ObjectPosEvt)->y; + status_ = Q_TRAN(&Mine1_planted); + break; + } + default: { + status_ = Q_SUPER(&QHsm_top); + break; + } + } + return status_; +} + +//${AOs::Mine1::SM::used} .................................................... +static QState Mine1_used(Mine1 * const me, QEvt const * const e) { + QState status_; + switch (e->sig) { + //${AOs::Mine1::SM::used} + case Q_EXIT_SIG: { + // tell the Tunnel that this mine is becoming disabled + MineEvt *mev = Q_NEW(MineEvt, MINE_DISABLED_SIG); + mev->id = MINE_ID(me); + QACTIVE_POST(AO_Tunnel, (QEvt *)mev, me); + status_ = Q_HANDLED(); + break; + } + //${AOs::Mine1::SM::used::MINE_RECYCLE} + case MINE_RECYCLE_SIG: { + status_ = Q_TRAN(&Mine1_unused); + break; + } + default: { + status_ = Q_SUPER(&QHsm_top); + break; + } + } + return status_; +} + +//${AOs::Mine1::SM::used::planted} ........................................... +static QState Mine1_planted(Mine1 * const me, QEvt const * const e) { + QState status_; + switch (e->sig) { + //${AOs::Mine1::SM::used::planted::TIME_TICK} + case TIME_TICK_SIG: { + //${AOs::Mine1::SM::used::planted::TIME_TICK::[me->x>=GAME_SPEED_X]} + if (me->x >= GAME_SPEED_X) { + ObjectImageEvt *oie; + me->x -= GAME_SPEED_X; // move the mine 1 step + // tell the Tunnel to draw the Mine + oie = Q_NEW(ObjectImageEvt, MINE_IMG_SIG); + oie->x = me->x; + oie->y = me->y; + oie->bmp = MINE1_BMP; + QACTIVE_POST(AO_Tunnel, (QEvt *)oie, me); + status_ = Q_HANDLED(); + } + //${AOs::Mine1::SM::used::planted::TIME_TICK::[else]} + else { + status_ = Q_TRAN(&Mine1_unused); + } + break; + } + //${AOs::Mine1::SM::used::planted::SHIP_IMG} + case SHIP_IMG_SIG: { + uint8_t x = Q_EVT_CAST(ObjectImageEvt)->x; + uint8_t y = Q_EVT_CAST(ObjectImageEvt)->y; + uint8_t bmp = Q_EVT_CAST(ObjectImageEvt)->bmp; + //${AOs::Mine1::SM::used::planted::SHIP_IMG::[collisionwithMINE1_BMP?]} + if (BSP_doBitmapsOverlap(MINE1_BMP, me->x, me->y, bmp, x, y)) { + static MineEvt const mine1_hit = { + QEVT_INITIALIZER(HIT_MINE_SIG), // the QEvt base instance + 1U // type of the mine (1 for Mine type-1) + }; + QACTIVE_POST(AO_Ship, (QEvt *)&mine1_hit, me); + // go straight to 'disabled' and let the Ship do the exploding + status_ = Q_TRAN(&Mine1_unused); + } + else { + status_ = Q_UNHANDLED(); + } + break; + } + //${AOs::Mine1::SM::used::planted::MISSILE_IMG} + case MISSILE_IMG_SIG: { + uint8_t x = Q_EVT_CAST(ObjectImageEvt)->x; + uint8_t y = Q_EVT_CAST(ObjectImageEvt)->y; + uint8_t bmp = Q_EVT_CAST(ObjectImageEvt)->bmp; + //${AOs::Mine1::SM::used::planted::MISSILE_IMG::[collisionwithMINE1_BMP?]} + if (BSP_doBitmapsOverlap(MINE1_BMP, me->x, me->y, bmp, x, y)) { + static ScoreEvt const mine1_destroyed = { + QEVT_INITIALIZER(DESTROYED_MINE_SIG), // the QEvt base instance + 25U // score for destroying Mine type-1 + }; + QACTIVE_POST(AO_Missile, (QEvt *)&mine1_destroyed, me); + status_ = Q_TRAN(&Mine1_exploding); + } + else { + status_ = Q_UNHANDLED(); + } + break; + } + default: { + status_ = Q_SUPER(&Mine1_used); + break; + } + } + return status_; +} + +//${AOs::Mine1::SM::used::exploding} ......................................... +static QState Mine1_exploding(Mine1 * const me, QEvt const * const e) { + QState status_; + switch (e->sig) { + //${AOs::Mine1::SM::used::exploding} + case Q_ENTRY_SIG: { + me->exp_ctr = 0U; + status_ = Q_HANDLED(); + break; + } + //${AOs::Mine1::SM::used::exploding::TIME_TICK} + case TIME_TICK_SIG: { + //${AOs::Mine1::SM::used::exploding::TIME_TICK::[stillonscreen?]} + if ((me->x >= GAME_SPEED_X) && (me->exp_ctr < 15)) { + ObjectImageEvt *oie; + ++me->exp_ctr; // advance the explosion counter + me->x -= GAME_SPEED_X; // move explosion by 1 step + + // tell the Game to render the current stage of Explosion + oie = Q_NEW(ObjectImageEvt, EXPLOSION_SIG); + oie->x = me->x + 1U; // x of explosion + oie->y = (int8_t)((int)me->y - 4 + 2); // y of explosion + oie->bmp = EXPLOSION0_BMP + (me->exp_ctr >> 2); + QACTIVE_POST(AO_Tunnel, (QEvt *)oie, me); + status_ = Q_HANDLED(); + } + //${AOs::Mine1::SM::used::exploding::TIME_TICK::[else]} + else { + status_ = Q_TRAN(&Mine1_unused); + } + break; + } + default: { + status_ = Q_SUPER(&Mine1_used); + break; + } + } + return status_; +} +//$enddef${AOs::Mine1} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/examples/qwin-gui/game-gui/mine2.c b/examples/qwin-gui/game-gui/mine2.c new file mode 100644 index 00000000..27f7d629 --- /dev/null +++ b/examples/qwin-gui/game-gui/mine2.c @@ -0,0 +1,289 @@ +//$file${.::mine2.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// +// Model: game.qm +// File: ${.::mine2.c} +// +// This code has been generated by QM 5.3.0 . +// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. +// +// SPDX-License-Identifier: GPL-3.0-or-later +// +// This generated code is open source software: you can redistribute it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation. +// +// This code is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// NOTE: +// Alternatively, this generated code may be distributed under the terms +// of Quantum Leaps commercial licenses, which expressly supersede the GNU +// General Public License and are specifically designed for licensees +// interested in retaining the proprietary status of their code. +// +// Contact information: +// +// +// +//$endhead${.::mine2.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +#include "qpc.h" +#include "bsp.h" +#include "game.h" + +Q_DEFINE_THIS_FILE + +// encapsulated delcaration of the Mine2 HSM ------------------------------- +//$declare${AOs::Mine2} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${AOs::Mine2} .............................................................. +typedef struct Mine2 { +// protected: + QHsm super; + +// private: + uint8_t x; + uint8_t y; + +// public: + uint8_t exp_ctr; +} Mine2; + +// public: +static void Mine2_ctor(Mine2 * const me); +extern Mine2 Mine2_inst[GAME_MINES_MAX]; + +// protected: +static QState Mine2_initial(Mine2 * const me, void const * const par); +static QState Mine2_unused(Mine2 * const me, QEvt const * const e); +static QState Mine2_used(Mine2 * const me, QEvt const * const e); +static QState Mine2_planted(Mine2 * const me, QEvt const * const e); +static QState Mine2_exploding(Mine2 * const me, QEvt const * const e); +//$enddecl${AOs::Mine2} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +// helper macro to provide the ID of this mine +#define MINE_ID(me_) ((uint8_t)((me_) - &Mine2_inst[0])) + +// Mine2 class definition -------------------------------------------------- +//$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// Check for the minimum required QP version +#if (QP_VERSION < 730U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) +#error qpc version 7.3.0 or higher required +#endif +//$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +//$define${Shared::Mine2_ctor_call} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${Shared::Mine2_ctor_call} ................................................. +QHsm * Mine2_ctor_call(uint8_t id) { + Q_REQUIRE(id < GAME_MINES_MAX); + Mine2_ctor(&Mine2_inst[id]); + return &Mine2_inst[id].super; +} +//$enddef${Shared::Mine2_ctor_call} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +//$define${AOs::Mine2} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${AOs::Mine2} .............................................................. +Mine2 Mine2_inst[GAME_MINES_MAX]; + +//${AOs::Mine2::ctor} ........................................................ +static void Mine2_ctor(Mine2 * const me) { + // superclass' ctor + QHsm_ctor(&me->super, Q_STATE_CAST(&Mine2_initial)); +} + +//${AOs::Mine2::SM} .......................................................... +static QState Mine2_initial(Mine2 * const me, void const * const par) { + //${AOs::Mine2::SM::initial} + static uint8_t dict_sent; + + if (!dict_sent) { + // object dictionaries for Mine2 pool... + QS_OBJ_DICTIONARY(&Mine2_inst[0]); + QS_OBJ_DICTIONARY(&Mine2_inst[1]); + QS_OBJ_DICTIONARY(&Mine2_inst[2]); + QS_OBJ_DICTIONARY(&Mine2_inst[3]); + QS_OBJ_DICTIONARY(&Mine2_inst[4]); + + //function dictionaries for Mine2 HSM... + QS_FUN_DICTIONARY(&Mine2_initial); + QS_FUN_DICTIONARY(&Mine2_unused); + QS_FUN_DICTIONARY(&Mine2_used); + QS_FUN_DICTIONARY(&Mine2_planted); + QS_FUN_DICTIONARY(&Mine2_exploding); + + dict_sent = 1U; + } + // local signals... + QS_SIG_DICTIONARY(MINE_PLANT_SIG, me); + QS_SIG_DICTIONARY(MINE_DISABLED_SIG, me); + QS_SIG_DICTIONARY(MINE_RECYCLE_SIG, me); + QS_SIG_DICTIONARY(SHIP_IMG_SIG, me); + QS_SIG_DICTIONARY(MISSILE_IMG_SIG, me); + + (void)par; // unused parameter + return Q_TRAN(&Mine2_unused); +} + +//${AOs::Mine2::SM::unused} .................................................. +static QState Mine2_unused(Mine2 * const me, QEvt const * const e) { + QState status_; + switch (e->sig) { + //${AOs::Mine2::SM::unused::MINE_PLANT} + case MINE_PLANT_SIG: { + me->x = Q_EVT_CAST(ObjectPosEvt)->x; + me->y = Q_EVT_CAST(ObjectPosEvt)->y; + status_ = Q_TRAN(&Mine2_planted); + break; + } + default: { + status_ = Q_SUPER(&QHsm_top); + break; + } + } + return status_; +} + +//${AOs::Mine2::SM::used} .................................................... +static QState Mine2_used(Mine2 * const me, QEvt const * const e) { + QState status_; + switch (e->sig) { + //${AOs::Mine2::SM::used} + case Q_EXIT_SIG: { + // tell the Tunnel that this mine is becoming disabled + MineEvt *mev = Q_NEW(MineEvt, MINE_DISABLED_SIG); + mev->id = MINE_ID(me); + QACTIVE_POST(AO_Tunnel, (QEvt *)mev, me); + status_ = Q_HANDLED(); + break; + } + //${AOs::Mine2::SM::used::MINE_RECYCLE} + case MINE_RECYCLE_SIG: { + status_ = Q_TRAN(&Mine2_unused); + break; + } + default: { + status_ = Q_SUPER(&QHsm_top); + break; + } + } + return status_; +} + +//${AOs::Mine2::SM::used::planted} ........................................... +static QState Mine2_planted(Mine2 * const me, QEvt const * const e) { + QState status_; + switch (e->sig) { + //${AOs::Mine2::SM::used::planted::TIME_TICK} + case TIME_TICK_SIG: { + //${AOs::Mine2::SM::used::planted::TIME_TICK::[me->x>=GAME_SPEED_X]} + if (me->x >= GAME_SPEED_X) { + ObjectImageEvt *oie; + me->x -= GAME_SPEED_X; // move the mine 1 step + // tell the Tunnel to draw the Mine + oie = Q_NEW(ObjectImageEvt, MINE_IMG_SIG); + oie->x = me->x; + oie->y = me->y; + oie->bmp = MINE2_BMP; + QACTIVE_POST(AO_Tunnel, (QEvt *)oie, me); + status_ = Q_HANDLED(); + } + //${AOs::Mine2::SM::used::planted::TIME_TICK::[else]} + else { + status_ = Q_TRAN(&Mine2_unused); + } + break; + } + //${AOs::Mine2::SM::used::planted::SHIP_IMG} + case SHIP_IMG_SIG: { + uint8_t x = Q_EVT_CAST(ObjectImageEvt)->x; + uint8_t y = Q_EVT_CAST(ObjectImageEvt)->y; + uint8_t bmp = Q_EVT_CAST(ObjectImageEvt)->bmp; + //${AOs::Mine2::SM::used::planted::SHIP_IMG::[collisionwithMINE2_BMP?]} + if (BSP_doBitmapsOverlap(MINE2_BMP, me->x, me->y, bmp, x, y)) { + static MineEvt const mine1_hit = { + QEVT_INITIALIZER(HIT_MINE_SIG), // the QEvt base instance + 2U // type of the mine (2 for Mine type-2) + }; + QACTIVE_POST(AO_Ship, (QEvt *)&mine1_hit, me); + // go straight to 'disabled' and let the Ship do the exploding + status_ = Q_TRAN(&Mine2_unused); + } + else { + status_ = Q_UNHANDLED(); + } + break; + } + //${AOs::Mine2::SM::used::planted::MISSILE_IMG} + case MISSILE_IMG_SIG: { + uint8_t x = Q_EVT_CAST(ObjectImageEvt)->x; + uint8_t y = Q_EVT_CAST(ObjectImageEvt)->y; + uint8_t bmp = Q_EVT_CAST(ObjectImageEvt)->bmp; + //${AOs::Mine2::SM::used::planted::MISSILE_IMG::[collisionwithMINE2_MISSILE_BMP?~} + if (BSP_doBitmapsOverlap(MINE2_MISSILE_BMP, me->x, me->y, bmp, x, y)) { + // NOTE: Mine type-2 is nastier than Mine type-1. + // The type-2 mine can hit the Ship with any of its + // "tentacles". However, it can be destroyed by the + // Missile only by hitting its center, defined as + // a smaller bitmap MINE2_MISSILE_BMP. + static ScoreEvt const mine2_destroyed = { + QEVT_INITIALIZER(DESTROYED_MINE_SIG), // the QEvt base instance + 45U // score for destroying Mine type-2 + }; + QACTIVE_POST(AO_Missile, (QEvt *)&mine2_destroyed, me); + status_ = Q_TRAN(&Mine2_exploding); + } + else { + status_ = Q_UNHANDLED(); + } + break; + } + default: { + status_ = Q_SUPER(&Mine2_used); + break; + } + } + return status_; +} + +//${AOs::Mine2::SM::used::exploding} ......................................... +static QState Mine2_exploding(Mine2 * const me, QEvt const * const e) { + QState status_; + switch (e->sig) { + //${AOs::Mine2::SM::used::exploding} + case Q_ENTRY_SIG: { + me->exp_ctr = 0U; + status_ = Q_HANDLED(); + break; + } + //${AOs::Mine2::SM::used::exploding::TIME_TICK} + case TIME_TICK_SIG: { + //${AOs::Mine2::SM::used::exploding::TIME_TICK::[stillonscreen?]} + if ((me->x >= GAME_SPEED_X) && (me->exp_ctr < 15U)) { + ObjectImageEvt *oie; + ++me->exp_ctr; // advance the explosion counter + me->x -= GAME_SPEED_X; // move explosion by 1 step + + // tell the Game to render the current stage of Explosion + oie = Q_NEW(ObjectImageEvt, EXPLOSION_SIG); + oie->x = me->x + 1U; // x of explosion + oie->y = (int8_t)((int)me->y - 4 + 2); // y of explosion + oie->bmp = EXPLOSION0_BMP + (me->exp_ctr >> 2); + QACTIVE_POST(AO_Tunnel, (QEvt *)oie, me); + status_ = Q_HANDLED(); + } + //${AOs::Mine2::SM::used::exploding::TIME_TICK::[else]} + else { + status_ = Q_TRAN(&Mine2_unused); + } + break; + } + default: { + status_ = Q_SUPER(&Mine2_used); + break; + } + } + return status_; +} +//$enddef${AOs::Mine2} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/examples/qwin-gui/game-gui/missile.c b/examples/qwin-gui/game-gui/missile.c new file mode 100644 index 00000000..5b39b99c --- /dev/null +++ b/examples/qwin-gui/game-gui/missile.c @@ -0,0 +1,216 @@ +//$file${.::missile.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// +// Model: game.qm +// File: ${.::missile.c} +// +// This code has been generated by QM 5.3.0 . +// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. +// +// SPDX-License-Identifier: GPL-3.0-or-later +// +// This generated code is open source software: you can redistribute it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation. +// +// This code is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// NOTE: +// Alternatively, this generated code may be distributed under the terms +// of Quantum Leaps commercial licenses, which expressly supersede the GNU +// General Public License and are specifically designed for licensees +// interested in retaining the proprietary status of their code. +// +// Contact information: +// +// +// +//$endhead${.::missile.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +#include "qpc.h" +#include "bsp.h" +#include "game.h" + +// Q_DEFINE_THIS_FILE + +// local objects ----------------------------------------------------------- +//$declare${AOs::Missile} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${AOs::Missile} ............................................................ +typedef struct Missile { +// protected: + QActive super; + +// private: + uint8_t x; + uint8_t y; + uint8_t exp_ctr; + +// public: +} Missile; + +// public: +static void Missile_ctor(Missile * const me); +extern Missile Missile_inst; + +// protected: +static QState Missile_initial(Missile * const me, void const * const par); +static QState Missile_armed(Missile * const me, QEvt const * const e); +static QState Missile_flying(Missile * const me, QEvt const * const e); +static QState Missile_exploding(Missile * const me, QEvt const * const e); +//$enddecl${AOs::Missile} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +// Public-scope objects ---------------------------------------------------- +//$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// Check for the minimum required QP version +#if (QP_VERSION < 730U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) +#error qpc version 7.3.0 or higher required +#endif +//$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +//$define${Shared::AO_Missile} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${Shared::AO_Missile} ...................................................... +QActive * const AO_Missile = &Missile_inst.super; +//$enddef${Shared::AO_Missile} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +// Active object definition ------------------------------------------------ +//$define${Shared::Missile_ctor_call} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${Shared::Missile_ctor_call} ............................................... +void Missile_ctor_call(void) { + Missile_ctor(&Missile_inst); +} +//$enddef${Shared::Missile_ctor_call} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +//$define${AOs::Missile} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${AOs::Missile} ............................................................ +Missile Missile_inst; + +//${AOs::Missile::ctor} ...................................................... +static void Missile_ctor(Missile * const me) { + QActive_ctor(&me->super, Q_STATE_CAST(&Missile_initial)); +} + +//${AOs::Missile::SM} ........................................................ +static QState Missile_initial(Missile * const me, void const * const par) { + //${AOs::Missile::SM::initial} + (void)par; // unused parameter + QActive_subscribe(&me->super, TIME_TICK_SIG); + + // local signals + QS_SIG_DICTIONARY(MISSILE_FIRE_SIG, me); + QS_SIG_DICTIONARY(HIT_WALL_SIG, me); + QS_SIG_DICTIONARY(DESTROYED_MINE_SIG, me); + + QS_FUN_DICTIONARY(&Missile_armed); + QS_FUN_DICTIONARY(&Missile_flying); + QS_FUN_DICTIONARY(&Missile_exploding); + + return Q_TRAN(&Missile_armed); +} + +//${AOs::Missile::SM::armed} ................................................. +static QState Missile_armed(Missile * const me, QEvt const * const e) { + QState status_; + switch (e->sig) { + //${AOs::Missile::SM::armed::MISSILE_FIRE} + case MISSILE_FIRE_SIG: { + me->x = Q_EVT_CAST(ObjectPosEvt)->x; + me->y = Q_EVT_CAST(ObjectPosEvt)->y; + status_ = Q_TRAN(&Missile_flying); + break; + } + default: { + status_ = Q_SUPER(&QHsm_top); + break; + } + } + return status_; +} + +//${AOs::Missile::SM::flying} ................................................ +static QState Missile_flying(Missile * const me, QEvt const * const e) { + QState status_; + switch (e->sig) { + //${AOs::Missile::SM::flying::TIME_TICK} + case TIME_TICK_SIG: { + //${AOs::Missile::SM::flying::TIME_TICK::[me->x+GAME_MISSILE_SPEED_Xx + GAME_MISSILE_SPEED_X < GAME_TUNNEL_WIDTH) { + ObjectImageEvt *oie; + me->x += GAME_MISSILE_SPEED_X; + //tell the Tunnel to draw the Missile and test for wall hits + oie = Q_NEW(ObjectImageEvt, MISSILE_IMG_SIG); + oie->x = me->x; + oie->y = me->y; + oie->bmp = MISSILE_BMP; + QACTIVE_POST(AO_Tunnel, (QEvt *)oie, me); + status_ = Q_HANDLED(); + } + //${AOs::Missile::SM::flying::TIME_TICK::[else]} + else { + status_ = Q_TRAN(&Missile_armed); + } + break; + } + //${AOs::Missile::SM::flying::HIT_WALL} + case HIT_WALL_SIG: { + status_ = Q_TRAN(&Missile_exploding); + break; + } + //${AOs::Missile::SM::flying::DESTROYED_MINE} + case DESTROYED_MINE_SIG: { + QACTIVE_POST(AO_Ship, e, me); + status_ = Q_TRAN(&Missile_armed); + break; + } + default: { + status_ = Q_SUPER(&QHsm_top); + break; + } + } + return status_; +} + +//${AOs::Missile::SM::exploding} ............................................. +static QState Missile_exploding(Missile * const me, QEvt const * const e) { + QState status_; + switch (e->sig) { + //${AOs::Missile::SM::exploding} + case Q_ENTRY_SIG: { + me->exp_ctr = 0U; + status_ = Q_HANDLED(); + break; + } + //${AOs::Missile::SM::exploding::TIME_TICK} + case TIME_TICK_SIG: { + //${AOs::Missile::SM::exploding::TIME_TICK::[(me->x>=GAME_SPEED_X)&&(me->exp~} + if ((me->x >= GAME_SPEED_X) && (me->exp_ctr < 15U)) { + ObjectImageEvt *oie; + + ++me->exp_ctr; // advance the explosion counter + me->x -= GAME_SPEED_X; // move the explosion by one step + + // tell the Tunnel to render the current stage of Explosion + oie = Q_NEW(ObjectImageEvt, EXPLOSION_SIG); + oie->x = me->x + 3U; // x-pos of explosion + oie->y = (int8_t)((int)me->y - 4U); // y-pos + oie->bmp = EXPLOSION0_BMP + (me->exp_ctr >> 2); + QACTIVE_POST(AO_Tunnel, (QEvt *)oie, me); + status_ = Q_HANDLED(); + } + //${AOs::Missile::SM::exploding::TIME_TICK::[else]} + else { + status_ = Q_TRAN(&Missile_armed); + } + break; + } + default: { + status_ = Q_SUPER(&QHsm_top); + break; + } + } + return status_; +} +//$enddef${AOs::Missile} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/examples/arm-cm/game_efm32-slstk3401a/win32-gui/resource.h b/examples/qwin-gui/game-gui/resource.h similarity index 100% rename from examples/arm-cm/game_efm32-slstk3401a/win32-gui/resource.h rename to examples/qwin-gui/game-gui/resource.h diff --git a/examples/qwin-gui/game-gui/ship.c b/examples/qwin-gui/game-gui/ship.c new file mode 100644 index 00000000..ae6c8bf7 --- /dev/null +++ b/examples/qwin-gui/game-gui/ship.c @@ -0,0 +1,284 @@ +//$file${.::ship.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// +// Model: game.qm +// File: ${.::ship.c} +// +// This code has been generated by QM 5.3.0 . +// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. +// +// SPDX-License-Identifier: GPL-3.0-or-later +// +// This generated code is open source software: you can redistribute it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation. +// +// This code is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// NOTE: +// Alternatively, this generated code may be distributed under the terms +// of Quantum Leaps commercial licenses, which expressly supersede the GNU +// General Public License and are specifically designed for licensees +// interested in retaining the proprietary status of their code. +// +// Contact information: +// +// +// +//$endhead${.::ship.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +#include "qpc.h" +#include "bsp.h" +#include "game.h" + +// Q_DEFINE_THIS_FILE + +#define SHIP_WIDTH 5 +#define SHIP_HEIGHT 3 + +// encapsulated delcaration of the Ship active object ---------------------- +//$declare${AOs::Ship} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${AOs::Ship} ............................................................... +typedef struct Ship { +// protected: + QActive super; + +// private: + uint8_t x; + uint16_t y; + uint8_t exp_ctr; + uint16_t score; + +// public: +} Ship; + +// public: +static void Ship_ctor(Ship * const me); +extern Ship Ship_inst; + +// protected: +static QState Ship_initial(Ship * const me, void const * const par); +static QState Ship_active(Ship * const me, QEvt const * const e); +static QState Ship_parked(Ship * const me, QEvt const * const e); +static QState Ship_flying(Ship * const me, QEvt const * const e); +static QState Ship_exploding(Ship * const me, QEvt const * const e); +//$enddecl${AOs::Ship} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +// Public-scope objects ---------------------------------------------------- +//$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// Check for the minimum required QP version +#if (QP_VERSION < 730U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) +#error qpc version 7.3.0 or higher required +#endif +//$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +//$define${Shared::AO_Ship} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${Shared::AO_Ship} ......................................................... +QActive * const AO_Ship = &Ship_inst.super; +//$enddef${Shared::AO_Ship} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +// Active object definition ------------------------------------------------ +//$define${Shared::Ship_ctor_call} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${Shared::Ship_ctor_call} .................................................. +void Ship_ctor_call(void) { + Ship_ctor(&Ship_inst); +} +//$enddef${Shared::Ship_ctor_call} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +//$define${AOs::Ship} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${AOs::Ship} ............................................................... +Ship Ship_inst; + +//${AOs::Ship::ctor} ......................................................... +static void Ship_ctor(Ship * const me) { + QActive_ctor(&me->super, Q_STATE_CAST(&Ship_initial)); + me->x = GAME_SHIP_X; + me->y = (GAME_SHIP_Y << 2); +} + +//${AOs::Ship::SM} ........................................................... +static QState Ship_initial(Ship * const me, void const * const par) { + //${AOs::Ship::SM::initial} + (void)par; // usused parameter + + QActive_subscribe(&me->super, TIME_TICK_SIG); + QActive_subscribe(&me->super, PLAYER_TRIGGER_SIG); + + // local signals... + //QS_SIG_DICTIONARY(PLAYER_SHIP_MOVE_SIG, me); + QS_SIG_DICTIONARY(TAKE_OFF_SIG, me); + QS_SIG_DICTIONARY(HIT_WALL_SIG, me); + QS_SIG_DICTIONARY(HIT_MINE_SIG, me); + QS_SIG_DICTIONARY(DESTROYED_MINE_SIG, me); + + QS_FUN_DICTIONARY(&Ship_active); + QS_FUN_DICTIONARY(&Ship_parked); + QS_FUN_DICTIONARY(&Ship_flying); + QS_FUN_DICTIONARY(&Ship_exploding); + + return Q_TRAN(&Ship_active); +} + +//${AOs::Ship::SM::active} ................................................... +static QState Ship_active(Ship * const me, QEvt const * const e) { + QState status_; + switch (e->sig) { + //${AOs::Ship::SM::active::initial} + case Q_INIT_SIG: { + status_ = Q_TRAN(&Ship_parked); + break; + } + default: { + status_ = Q_SUPER(&QHsm_top); + break; + } + } + return status_; +} + +//${AOs::Ship::SM::active::parked} ........................................... +static QState Ship_parked(Ship * const me, QEvt const * const e) { + QState status_; + switch (e->sig) { + //${AOs::Ship::SM::active::parked::TAKE_OFF} + case TAKE_OFF_SIG: { + status_ = Q_TRAN(&Ship_flying); + break; + } + default: { + status_ = Q_SUPER(&Ship_active); + break; + } + } + return status_; +} + +//${AOs::Ship::SM::active::flying} ........................................... +static QState Ship_flying(Ship * const me, QEvt const * const e) { + QState status_; + switch (e->sig) { + //${AOs::Ship::SM::active::flying} + case Q_ENTRY_SIG: { + ScoreEvt *sev; + me->score = 0U; // reset the score + sev = Q_NEW(ScoreEvt, SCORE_SIG); + sev->score = me->score; + QACTIVE_POST(AO_Tunnel, (QEvt *)sev, me); + + // lauch the ship from the initial position + me->x = GAME_SHIP_X; + me->y = (GAME_SHIP_Y << 2); + status_ = Q_HANDLED(); + break; + } + //${AOs::Ship::SM::active::flying::TIME_TICK} + case TIME_TICK_SIG: { + ObjectImageEvt *oie; + + if (BSP_isThrottle()) { + if (me->y > 0) { + me->y -= 1U; + } + } + else { + if (me->y < (GAME_TUNNEL_HEIGHT << 2)) { + me->y += 1U; + } + } + + // tell the Tunnel to draw the Ship and test for hits + oie = Q_NEW(ObjectImageEvt, SHIP_IMG_SIG); + oie->x = me->x; + oie->y = (uint8_t)(me->y >> 2); + oie->bmp = SHIP_BMP; + QACTIVE_POST(AO_Tunnel, (QEvt *)oie, me); + + ++me->score; // increment the score for surviving another tick + + if ((me->score % 10U) == 0U) { // is the score "round"? + ScoreEvt *sev = Q_NEW(ScoreEvt, SCORE_SIG); + sev->score = me->score; + QACTIVE_POST(AO_Tunnel, (QEvt *)sev, me); + } + status_ = Q_HANDLED(); + break; + } + //${AOs::Ship::SM::active::flying::PLAYER_TRIGGER} + case PLAYER_TRIGGER_SIG: { + ObjectPosEvt *ope = Q_NEW(ObjectPosEvt, MISSILE_FIRE_SIG); + ope->x = me->x; + ope->y = (me->y >> 2) + SHIP_HEIGHT - 1U; + QACTIVE_POST(AO_Missile, (QEvt *)ope, me); + status_ = Q_HANDLED(); + break; + } + //${AOs::Ship::SM::active::flying::DESTROYED_MINE} + case DESTROYED_MINE_SIG: { + me->score += Q_EVT_CAST(ScoreEvt)->score; + // the score will be sent to the Tunnel by the next TIME_TICK + status_ = Q_HANDLED(); + break; + } + //${AOs::Ship::SM::active::flying::HIT_WALL} + case HIT_WALL_SIG: { + status_ = Q_TRAN(&Ship_exploding); + break; + } + //${AOs::Ship::SM::active::flying::HIT_MINE} + case HIT_MINE_SIG: { + status_ = Q_TRAN(&Ship_exploding); + break; + } + default: { + status_ = Q_SUPER(&Ship_active); + break; + } + } + return status_; +} + +//${AOs::Ship::SM::active::exploding} ........................................ +static QState Ship_exploding(Ship * const me, QEvt const * const e) { + QState status_; + switch (e->sig) { + //${AOs::Ship::SM::active::exploding} + case Q_ENTRY_SIG: { + me->exp_ctr = 0U; + status_ = Q_HANDLED(); + break; + } + //${AOs::Ship::SM::active::exploding::TIME_TICK} + case TIME_TICK_SIG: { + //${AOs::Ship::SM::active::exploding::TIME_TICK::[me->exp_ctr<15U]} + if (me->exp_ctr < 15U) { + ObjectImageEvt *oie; + ++me->exp_ctr; + // tell the Tunnel to draw the current stage of Explosion + oie = Q_NEW(ObjectImageEvt, EXPLOSION_SIG); + oie->bmp = EXPLOSION0_BMP + (me->exp_ctr >> 2); + oie->x = me->x; // x of explosion + oie->y = (int8_t)((int)(me->y >> 2) - 4U + SHIP_HEIGHT); + QACTIVE_POST(AO_Tunnel, (QEvt *)oie, me); + status_ = Q_HANDLED(); + } + //${AOs::Ship::SM::active::exploding::TIME_TICK::[else]} + else { + ScoreEvt *gameOver = Q_NEW(ScoreEvt, GAME_OVER_SIG); + gameOver->score = me->score; + QACTIVE_POST(AO_Tunnel, (QEvt *)gameOver, me); + status_ = Q_TRAN(&Ship_parked); + } + break; + } + default: { + status_ = Q_SUPER(&Ship_active); + break; + } + } + return status_; +} +//$enddef${AOs::Ship} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/examples/qwin-gui/game-gui/tunnel.c b/examples/qwin-gui/game-gui/tunnel.c new file mode 100644 index 00000000..c9e2fce9 --- /dev/null +++ b/examples/qwin-gui/game-gui/tunnel.c @@ -0,0 +1,684 @@ +//$file${.::tunnel.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// +// Model: game.qm +// File: ${.::tunnel.c} +// +// This code has been generated by QM 5.3.0 . +// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. +// +// SPDX-License-Identifier: GPL-3.0-or-later +// +// This generated code is open source software: you can redistribute it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation. +// +// This code is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// NOTE: +// Alternatively, this generated code may be distributed under the terms +// of Quantum Leaps commercial licenses, which expressly supersede the GNU +// General Public License and are specifically designed for licensees +// interested in retaining the proprietary status of their code. +// +// Contact information: +// +// +// +//$endhead${.::tunnel.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +#include "qpc.h" +#include "bsp.h" +#include "game.h" + +Q_DEFINE_THIS_FILE + +// local objects ----------------------------------------------------------- +//$declare${AOs::Tunnel} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${AOs::Tunnel} ............................................................. +typedef struct Tunnel { +// protected: + QActive super; + +// private: + QTimeEvt blinkTimeEvt; + QTimeEvt screenTimeEvt; + QHsm * mines[GAME_MINES_MAX]; + QHsm * mine1_pool[GAME_MINES_MAX]; + QHsm * mine2_pool[GAME_MINES_MAX]; + uint8_t blink_ctr; + uint8_t last_mine_x; + uint8_t last_mine_y; + uint8_t wall_thickness_top; + uint8_t wall_thickness_bottom; + uint8_t wall_gap; + +// public: +} Tunnel; + +// private: +static void Tunnel_advance(Tunnel * const me); +static void Tunnel_plantMine(Tunnel * const me); +static void Tunnel_dispatchToAllMines(Tunnel * const me, + QEvt const * e); + +// public: +static void Tunnel_ctor(Tunnel * const me); +extern Tunnel Tunnel_inst; + +// protected: +static QState Tunnel_initial(Tunnel * const me, void const * const par); +static QState Tunnel_active(Tunnel * const me, QEvt const * const e); +static QState Tunnel_show_logo(Tunnel * const me, QEvt const * const e); +static QState Tunnel_demo(Tunnel * const me, QEvt const * const e); +static QState Tunnel_playing(Tunnel * const me, QEvt const * const e); +static QState Tunnel_game_over(Tunnel * const me, QEvt const * const e); +static QState Tunnel_screen_saver(Tunnel * const me, QEvt const * const e); +static QState Tunnel_screen_saver_hide(Tunnel * const me, QEvt const * const e); +static QState Tunnel_screen_saver_show(Tunnel * const me, QEvt const * const e); +static QState Tunnel_final(Tunnel * const me, QEvt const * const e); +//$enddecl${AOs::Tunnel} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +// Public-scope objects ---------------------------------------------------- +//$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// Check for the minimum required QP version +#if (QP_VERSION < 730U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) +#error qpc version 7.3.0 or higher required +#endif +//$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +//$define${Shared::AO_Tunnel} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${Shared::AO_Tunnel} ....................................................... +QActive * const AO_Tunnel = &Tunnel_inst.super; +//$enddef${Shared::AO_Tunnel} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +// Active object definition ================================================ +//$define${Shared::Tunnel_ctor_call} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${Shared::Tunnel_ctor_call} ................................................ +void Tunnel_ctor_call(void) { + Tunnel_ctor(&Tunnel_inst); +} +//$enddef${Shared::Tunnel_ctor_call} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +//$define${AOs::Tunnel} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${AOs::Tunnel} ............................................................. +Tunnel Tunnel_inst; + +//${AOs::Tunnel::advance} .................................................... +static void Tunnel_advance(Tunnel * const me) { + uint32_t rnd; + + rnd = (BSP_random() & 0xFFU); + + // reduce the top wall thickness 18.75% of the time + if ((rnd < 48U) && (me->wall_thickness_top > 0U)) { + --me->wall_thickness_top; + } + + // reduce the bottom wall thickness 18.75% of the time + if ((rnd > 208U) && (me->wall_thickness_bottom > 0U)) { + --me->wall_thickness_bottom; + } + + rnd = (BSP_random() & 0xFFU); + + // grow the bottom wall thickness 19.14% of the time + if ((rnd < 49U) + && ((GAME_TUNNEL_HEIGHT + - me->wall_thickness_top + - me->wall_thickness_bottom) > me->wall_gap)) + { + ++me->wall_thickness_bottom; + } + + // grow the top wall thickness 19.14% of the time + if ((rnd > 207U) + && ((GAME_TUNNEL_HEIGHT + - me->wall_thickness_top + - me->wall_thickness_bottom) > me->wall_gap)) + { + ++me->wall_thickness_top; + } + + // advance the Tunnel by 1 game step to the left + // and copy the Tunnel layer to the main frame buffer + BSP_advanceWalls(me->wall_thickness_top, me->wall_thickness_bottom); +} + +//${AOs::Tunnel::plantMine} .................................................. +static void Tunnel_plantMine(Tunnel * const me) { + uint32_t rnd = (BSP_random() & 0xFFU); + + if (me->last_mine_x > 0U) { + --me->last_mine_x; // shift the last Mine 1 position to the left + } + // last mine far enough? + if ((me->last_mine_x + GAME_MINES_DIST_MIN < GAME_TUNNEL_WIDTH) + && (rnd < 8U)) // place the mines only 5% of the time + { + uint8_t n; + for (n = 0U; n < Q_DIM(me->mines); ++n) { //look for disabled mines + if (me->mines[n] == (QHsm *)0) { + break; + } + } + if (n < Q_DIM(me->mines)) { // a disabled Mine found? + rnd = (BSP_random() & 0xFFFFU); + + if ((rnd & 1U) == 0U) { // choose the type of the mine + me->mines[n] = me->mine1_pool[n]; + } + else { + me->mines[n] = me->mine2_pool[n]; + } + + // new Mine is planted by the end of the tunnel + me->last_mine_x = GAME_TUNNEL_WIDTH - 8U; + + // choose a random y-position for the Mine in the Tunnel + rnd %= (GAME_TUNNEL_HEIGHT + - me->wall_thickness_top + - me->wall_thickness_bottom - 4U); + me->last_mine_y = (uint8_t)(me->wall_thickness_top + 2U + rnd); + + ObjectPosEvt ope; // event to dispatch to the Mine + QEvt_ctor(&ope.super, MINE_PLANT_SIG); + ope.x = me->last_mine_x; + ope.y = me->last_mine_y; + // direct dispatch + QASM_DISPATCH(me->mines[n], &ope.super, me->super.prio); + } + } +} + +//${AOs::Tunnel::dispatchToAllMines} ......................................... +static void Tunnel_dispatchToAllMines(Tunnel * const me, + QEvt const * e) +{ + for (uint8_t n = 0U; n < GAME_MINES_MAX; ++n) { + if (me->mines[n] != (QHsm *)0) { // is the mine used? + QASM_DISPATCH(me->mines[n], e, me->super.prio); + } + } +} + +//${AOs::Tunnel::ctor} ....................................................... +static void Tunnel_ctor(Tunnel * const me) { + uint8_t n; + QActive_ctor(&me->super, Q_STATE_CAST(&Tunnel_initial)); + QTimeEvt_ctorX(&me->blinkTimeEvt, &me->super, BLINK_TIMEOUT_SIG, 0U); + QTimeEvt_ctorX(&me->screenTimeEvt, &me->super, SCREEN_TIMEOUT_SIG, 0U); + for (n = 0; n < GAME_MINES_MAX; ++n) { + me->mine1_pool[n] = Mine1_ctor_call(n); // instantiate Mine1 + me->mine2_pool[n] = Mine2_ctor_call(n); // instantiate Mine2 + me->mines[n] = (QHsm *)0; // mine 'n' is unused + } + me->last_mine_x = 0; // the last mine at the right edge of the tunnel + me->last_mine_y = 0; +} + +//${AOs::Tunnel::SM} ......................................................... +static QState Tunnel_initial(Tunnel * const me, void const * const par) { + //${AOs::Tunnel::SM::initial} + uint8_t n; + for (n = 0U; n < GAME_MINES_MAX; ++n) { + QASM_INIT(me->mine1_pool[n], (void *)0, me->super.prio); + QASM_INIT(me->mine2_pool[n], (void *)0, me->super.prio); + } + BSP_randomSeed(1234); // seed the pseudo-random generator + + QActive_subscribe(&me->super, TIME_TICK_SIG); + QActive_subscribe(&me->super, PLAYER_TRIGGER_SIG); + QActive_subscribe(&me->super, PLAYER_QUIT_SIG); + + // object dictionaries... + QS_OBJ_DICTIONARY(&Tunnel_inst.blinkTimeEvt); + QS_OBJ_DICTIONARY(&Tunnel_inst.screenTimeEvt); + + // local signals... + QS_SIG_DICTIONARY(BLINK_TIMEOUT_SIG, me); + QS_SIG_DICTIONARY(SCREEN_TIMEOUT_SIG, me); + QS_SIG_DICTIONARY(SHIP_IMG_SIG, me); + QS_SIG_DICTIONARY(MISSILE_IMG_SIG, me); + QS_SIG_DICTIONARY(MINE_IMG_SIG, me); + QS_SIG_DICTIONARY(MINE_DISABLED_SIG, me); + QS_SIG_DICTIONARY(EXPLOSION_SIG, me); + QS_SIG_DICTIONARY(SCORE_SIG, me); + + (void)par; // unused parameter + + QS_FUN_DICTIONARY(&Tunnel_active); + QS_FUN_DICTIONARY(&Tunnel_show_logo); + QS_FUN_DICTIONARY(&Tunnel_demo); + QS_FUN_DICTIONARY(&Tunnel_playing); + QS_FUN_DICTIONARY(&Tunnel_game_over); + QS_FUN_DICTIONARY(&Tunnel_screen_saver); + QS_FUN_DICTIONARY(&Tunnel_screen_saver_hide); + QS_FUN_DICTIONARY(&Tunnel_screen_saver_show); + QS_FUN_DICTIONARY(&Tunnel_final); + + return Q_TRAN(&Tunnel_show_logo); +} + +//${AOs::Tunnel::SM::active} ................................................. +static QState Tunnel_active(Tunnel * const me, QEvt const * const e) { + QState status_; + switch (e->sig) { + //${AOs::Tunnel::SM::active::MINE_DISABLED} + case MINE_DISABLED_SIG: { + Q_ASSERT((Q_EVT_CAST(MineEvt)->id < GAME_MINES_MAX) + && (me->mines[Q_EVT_CAST(MineEvt)->id] != (QHsm *)0)); + me->mines[Q_EVT_CAST(MineEvt)->id] = (QHsm *)0; + status_ = Q_HANDLED(); + break; + } + //${AOs::Tunnel::SM::active::PLAYER_QUIT} + case PLAYER_QUIT_SIG: { + status_ = Q_TRAN(&Tunnel_final); + break; + } + default: { + status_ = Q_SUPER(&QHsm_top); + break; + } + } + return status_; +} + +//${AOs::Tunnel::SM::active::show_logo} ...................................... +static QState Tunnel_show_logo(Tunnel * const me, QEvt const * const e) { + QState status_; + switch (e->sig) { + //${AOs::Tunnel::SM::active::show_logo} + case Q_ENTRY_SIG: { + QTimeEvt_armX(&me->blinkTimeEvt, BSP_TICKS_PER_SEC/2U, + BSP_TICKS_PER_SEC/2U); + QTimeEvt_armX(&me->screenTimeEvt, BSP_TICKS_PER_SEC*5U, 0U); + me->blink_ctr = 0U; + BSP_paintString(24U, (GAME_TUNNEL_HEIGHT / 2U) - 8U, "Quantum LeAps"); + BSP_paintString(16U, (GAME_TUNNEL_HEIGHT / 2U) + 0U, "state-machine.com"); + + BSP_paintString(1U, GAME_TUNNEL_HEIGHT - 18U, "Fire missile: BTN0"); + BSP_paintString(1U, GAME_TUNNEL_HEIGHT - 10U, "Fly ship up: BTN1"); + + BSP_updateScreen(); + status_ = Q_HANDLED(); + break; + } + //${AOs::Tunnel::SM::active::show_logo} + case Q_EXIT_SIG: { + QTimeEvt_disarm(&me->blinkTimeEvt); + QTimeEvt_disarm(&me->screenTimeEvt); + status_ = Q_HANDLED(); + break; + } + //${AOs::Tunnel::SM::active::show_logo::SCREEN_TIMEOUT} + case SCREEN_TIMEOUT_SIG: { + status_ = Q_TRAN(&Tunnel_demo); + break; + } + //${AOs::Tunnel::SM::active::show_logo::BLINK_TIMEOUT} + case BLINK_TIMEOUT_SIG: { + me->blink_ctr ^= 1U; // toggle the blink counter + //${AOs::Tunnel::SM::active::show_logo::BLINK_TIMEOUT::[me->blink_ctr==0U]} + if (me->blink_ctr == 0U) { + BSP_paintString(24U + 8U*6U, (GAME_TUNNEL_HEIGHT / 2U) - 8U, "LeAps"); + BSP_updateScreen(); + status_ = Q_HANDLED(); + } + //${AOs::Tunnel::SM::active::show_logo::BLINK_TIMEOUT::[else]} + else { + BSP_paintString(24U + 8U*6U, (GAME_TUNNEL_HEIGHT / 2U) - 8U, "LeaPs"); + BSP_updateScreen(); + status_ = Q_HANDLED(); + } + break; + } + default: { + status_ = Q_SUPER(&Tunnel_active); + break; + } + } + return status_; +} + +//${AOs::Tunnel::SM::active::demo} ........................................... +static QState Tunnel_demo(Tunnel * const me, QEvt const * const e) { + QState status_; + switch (e->sig) { + //${AOs::Tunnel::SM::active::demo} + case Q_ENTRY_SIG: { + me->last_mine_x = 0U; // last mine at right edge of the tunnel + me->last_mine_y = 0U; + // set the tunnel properties... + me->wall_thickness_top = 0U; + me->wall_thickness_bottom = 0U; + me->wall_gap = GAME_WALLS_GAP_Y; + + // clear the tunnel walls + BSP_clearWalls(); + + QTimeEvt_armX(&me->blinkTimeEvt, BSP_TICKS_PER_SEC/2U, + BSP_TICKS_PER_SEC/2U); // every 1/2 sec + QTimeEvt_armX(&me->screenTimeEvt, BSP_TICKS_PER_SEC*20U, 0U); + + me->blink_ctr = 0U; // init the blink counter + status_ = Q_HANDLED(); + break; + } + //${AOs::Tunnel::SM::active::demo} + case Q_EXIT_SIG: { + QTimeEvt_disarm(&me->blinkTimeEvt); + QTimeEvt_disarm(&me->screenTimeEvt); + status_ = Q_HANDLED(); + break; + } + //${AOs::Tunnel::SM::active::demo::BLINK_TIMEOUT} + case BLINK_TIMEOUT_SIG: { + me->blink_ctr ^= 1U; // toggle the blink cunter + status_ = Q_HANDLED(); + break; + } + //${AOs::Tunnel::SM::active::demo::SCREEN_TIMEOUT} + case SCREEN_TIMEOUT_SIG: { + status_ = Q_TRAN(&Tunnel_screen_saver); + break; + } + //${AOs::Tunnel::SM::active::demo::TIME_TICK} + case TIME_TICK_SIG: { + Tunnel_advance(me); + if (me->blink_ctr != 0U) { + // add the text bitmap into the frame buffer + BSP_paintString((GAME_TUNNEL_WIDTH - 10U*6U)/2U, + (GAME_TUNNEL_HEIGHT - 4U)/2U, + "Press BTN0"); + } + BSP_updateScreen(); + status_ = Q_HANDLED(); + break; + } + //${AOs::Tunnel::SM::active::demo::PLAYER_TRIGGER} + case PLAYER_TRIGGER_SIG: { + status_ = Q_TRAN(&Tunnel_playing); + break; + } + default: { + status_ = Q_SUPER(&Tunnel_active); + break; + } + } + return status_; +} + +//${AOs::Tunnel::SM::active::playing} ........................................ +static QState Tunnel_playing(Tunnel * const me, QEvt const * const e) { + QState status_; + switch (e->sig) { + //${AOs::Tunnel::SM::active::playing} + case Q_ENTRY_SIG: { + static QEvt const takeoff = QEVT_INITIALIZER(TAKE_OFF_SIG); + me->wall_gap = GAME_WALLS_GAP_Y; + QACTIVE_POST(AO_Ship, &takeoff, me); // post the TAKEOFF sig + status_ = Q_HANDLED(); + break; + } + //${AOs::Tunnel::SM::active::playing} + case Q_EXIT_SIG: { + static QEvt const recycle = QEVT_INITIALIZER(MINE_RECYCLE_SIG); + Tunnel_dispatchToAllMines(me, &recycle); // recycle all Mines + status_ = Q_HANDLED(); + break; + } + //${AOs::Tunnel::SM::active::playing::TIME_TICK} + case TIME_TICK_SIG: { + // render this frame on the display + BSP_updateScreen(); + Tunnel_advance(me); + Tunnel_plantMine(me); + Tunnel_dispatchToAllMines(me, e); + status_ = Q_HANDLED(); + break; + } + //${AOs::Tunnel::SM::active::playing::SHIP_IMG} + case SHIP_IMG_SIG: { + uint8_t x = Q_EVT_CAST(ObjectImageEvt)->x; + int8_t y = Q_EVT_CAST(ObjectImageEvt)->y; + uint8_t bmp = Q_EVT_CAST(ObjectImageEvt)->bmp; + + // did the Ship/Missile hit the tunnel wall? + if (BSP_isWallHit(bmp, x, y)) { + static QEvt const hit = QEVT_INITIALIZER(HIT_WALL_SIG); + QACTIVE_POST(AO_Ship, &hit, me); + } + BSP_paintBitmap(x, y, bmp); + Tunnel_dispatchToAllMines(me, e); // let Mines check for hits + status_ = Q_HANDLED(); + break; + } + //${AOs::Tunnel::SM::active::playing::MISSILE_IMG} + case MISSILE_IMG_SIG: { + uint8_t x = Q_EVT_CAST(ObjectImageEvt)->x; + int8_t y = Q_EVT_CAST(ObjectImageEvt)->y; + uint8_t bmp = Q_EVT_CAST(ObjectImageEvt)->bmp; + + // did the Ship/Missile hit the tunnel wall? + if (BSP_isWallHit(bmp, x, y)) { + static QEvt const hit = QEVT_INITIALIZER(HIT_WALL_SIG); + QACTIVE_POST(AO_Missile, &hit, me); + } + BSP_paintBitmap(x, y, bmp); + Tunnel_dispatchToAllMines(me, e); // let Mines check for hits + status_ = Q_HANDLED(); + break; + } + //${AOs::Tunnel::SM::active::playing::MINE_IMG} + case MINE_IMG_SIG: { + BSP_paintBitmap(Q_EVT_CAST(ObjectImageEvt)->x, + Q_EVT_CAST(ObjectImageEvt)->y, + Q_EVT_CAST(ObjectImageEvt)->bmp); + status_ = Q_HANDLED(); + break; + } + //${AOs::Tunnel::SM::active::playing::EXPLOSION} + case EXPLOSION_SIG: { + BSP_paintBitmap(Q_EVT_CAST(ObjectImageEvt)->x, + Q_EVT_CAST(ObjectImageEvt)->y, + Q_EVT_CAST(ObjectImageEvt)->bmp); + status_ = Q_HANDLED(); + break; + } + //${AOs::Tunnel::SM::active::playing::SCORE} + case SCORE_SIG: { + BSP_updateScore(Q_EVT_CAST(ScoreEvt)->score); + // increase difficulty of the game: + // the tunnel gets narrower as the score goes up + me->wall_gap = (uint8_t)(GAME_WALLS_GAP_Y + - Q_EVT_CAST(ScoreEvt)->score/100U); + if (me->wall_gap < GAME_WALLS_MIN_GAP_Y) { + me->wall_gap = GAME_WALLS_MIN_GAP_Y; + } + status_ = Q_HANDLED(); + break; + } + //${AOs::Tunnel::SM::active::playing::GAME_OVER} + case GAME_OVER_SIG: { + BSP_clearWalls(); + BSP_updateScore(Q_EVT_CAST(ScoreEvt)->score); + BSP_updateScreen(); + status_ = Q_TRAN(&Tunnel_game_over); + break; + } + default: { + status_ = Q_SUPER(&Tunnel_active); + break; + } + } + return status_; +} + +//${AOs::Tunnel::SM::active::game_over} ...................................... +static QState Tunnel_game_over(Tunnel * const me, QEvt const * const e) { + QState status_; + switch (e->sig) { + //${AOs::Tunnel::SM::active::game_over} + case Q_ENTRY_SIG: { + QTimeEvt_armX(&me->blinkTimeEvt, BSP_TICKS_PER_SEC/2U, + BSP_TICKS_PER_SEC/2U); // every 1/2 sec + QTimeEvt_armX(&me->screenTimeEvt, BSP_TICKS_PER_SEC*5U, 0U); + me->blink_ctr = 0U; + BSP_paintString((GAME_TUNNEL_WIDTH - 6U * 9U) / 2U, + (GAME_TUNNEL_HEIGHT / 2U) - 4U, + "Game Over"); + BSP_updateScreen(); + status_ = Q_HANDLED(); + break; + } + //${AOs::Tunnel::SM::active::game_over} + case Q_EXIT_SIG: { + QTimeEvt_disarm(&me->blinkTimeEvt); + QTimeEvt_disarm(&me->screenTimeEvt); + BSP_updateScore(0); // update the score on the display + status_ = Q_HANDLED(); + break; + } + //${AOs::Tunnel::SM::active::game_over::BLINK_TIMEOUT} + case BLINK_TIMEOUT_SIG: { + me->blink_ctr ^= 1U; // toggle the blink counter + BSP_paintString((GAME_TUNNEL_WIDTH - 6U*9U) / 2U, + (GAME_TUNNEL_HEIGHT / 2U) - 4U, + ((me->blink_ctr == 0U) + ? "Game Over" + : " ")); + BSP_updateScreen(); + status_ = Q_HANDLED(); + break; + } + //${AOs::Tunnel::SM::active::game_over::SCREEN_TIMEOUT} + case SCREEN_TIMEOUT_SIG: { + status_ = Q_TRAN(&Tunnel_demo); + break; + } + default: { + status_ = Q_SUPER(&Tunnel_active); + break; + } + } + return status_; +} + +//${AOs::Tunnel::SM::active::screen_saver} ................................... +static QState Tunnel_screen_saver(Tunnel * const me, QEvt const * const e) { + QState status_; + switch (e->sig) { + //${AOs::Tunnel::SM::active::screen_saver::initial} + case Q_INIT_SIG: { + status_ = Q_TRAN(&Tunnel_screen_saver_hide); + break; + } + //${AOs::Tunnel::SM::active::screen_saver::PLAYER_TRIGGER} + case PLAYER_TRIGGER_SIG: { + status_ = Q_TRAN(&Tunnel_demo); + break; + } + default: { + status_ = Q_SUPER(&Tunnel_active); + break; + } + } + return status_; +} + +//${AOs::Tunnel::SM::active::screen_saver::screen_saver_hide} ................ +static QState Tunnel_screen_saver_hide(Tunnel * const me, QEvt const * const e) { + QState status_; + switch (e->sig) { + //${AOs::Tunnel::SM::active::screen_saver::screen_saver_hide} + case Q_ENTRY_SIG: { + BSP_displayOff(); // power down the display + QTimeEvt_armX(&me->screenTimeEvt, BSP_TICKS_PER_SEC*3U, 0U); + status_ = Q_HANDLED(); + break; + } + //${AOs::Tunnel::SM::active::screen_saver::screen_saver_hide} + case Q_EXIT_SIG: { + QTimeEvt_disarm(&me->screenTimeEvt); + BSP_displayOn(); // power up the display + status_ = Q_HANDLED(); + break; + } + //${AOs::Tunnel::SM::active::screen_saver::screen_saver_hid~::SCREEN_TIMEOUT} + case SCREEN_TIMEOUT_SIG: { + status_ = Q_TRAN(&Tunnel_screen_saver_show); + break; + } + default: { + status_ = Q_SUPER(&Tunnel_screen_saver); + break; + } + } + return status_; +} + +//${AOs::Tunnel::SM::active::screen_saver::screen_saver_show} ................ +static QState Tunnel_screen_saver_show(Tunnel * const me, QEvt const * const e) { + QState status_; + switch (e->sig) { + //${AOs::Tunnel::SM::active::screen_saver::screen_saver_show} + case Q_ENTRY_SIG: { + uint32_t rnd = BSP_random(); + // clear the screen frame buffer + BSP_clearFB(); + BSP_paintString((uint8_t)(rnd % (GAME_TUNNEL_WIDTH - 10U*6U)), + (uint8_t) (rnd % (GAME_TUNNEL_HEIGHT - 8U)), + "Press BTN0"); + BSP_updateScreen(); + QTimeEvt_armX(&me->screenTimeEvt, BSP_TICKS_PER_SEC/2U, 0U); + status_ = Q_HANDLED(); + break; + } + //${AOs::Tunnel::SM::active::screen_saver::screen_saver_show} + case Q_EXIT_SIG: { + QTimeEvt_disarm(&me->screenTimeEvt); + BSP_clearFB(); + BSP_updateScreen(); + status_ = Q_HANDLED(); + break; + } + //${AOs::Tunnel::SM::active::screen_saver::screen_saver_sho~::SCREEN_TIMEOUT} + case SCREEN_TIMEOUT_SIG: { + status_ = Q_TRAN(&Tunnel_screen_saver_hide); + break; + } + default: { + status_ = Q_SUPER(&Tunnel_screen_saver); + break; + } + } + return status_; +} + +//${AOs::Tunnel::SM::final} .................................................. +static QState Tunnel_final(Tunnel * const me, QEvt const * const e) { + QState status_; + switch (e->sig) { + //${AOs::Tunnel::SM::final} + case Q_ENTRY_SIG: { + // clear the screen + BSP_clearFB(); + BSP_updateScreen(); + QF_stop(); // stop QF and cleanup + status_ = Q_HANDLED(); + break; + } + default: { + status_ = Q_SUPER(&QHsm_top); + break; + } + } + return status_; +} +//$enddef${AOs::Tunnel} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/examples/threadx/arm-cm/dpp_ek-tm4c123gxl/bsp.c b/examples/threadx/arm-cm/dpp_ek-tm4c123gxl/bsp.c index fde77268..d6db6926 100644 --- a/examples/threadx/arm-cm/dpp_ek-tm4c123gxl/bsp.c +++ b/examples/threadx/arm-cm/dpp_ek-tm4c123gxl/bsp.c @@ -1,516 +1,435 @@ -/***************************************************************************** -* Product: DPP example, EK-TM4C123GXL board, ThreadX kernel -* Last updated for version 7.2.0 -* Last updated on 2022-12-17 -* -* Q u a n t u m L e a P s -* ------------------------ -* Modern Embedded Software -* -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* -* -*****************************************************************************/ -#include "qpc.h" -#include "dpp.h" -#include "bsp.h" +//============================================================================ +// DPP example, EK-TM4C123GXL board, ThreadX RTOS +// Last updated for version 7.3.0 +// Last updated on 2023-08-30 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +//============================================================================ +#include "qpc.h" // QP/C real-time embedded framework +#include "dpp.h" // DPP Application interface +#include "bsp.h" // Board Support Package -#include "TM4C123GH6PM.h" /* the device specific header (TI) */ -#include "rom.h" /* the built-in ROM functions (TI) */ -#include "sysctl.h" /* system control driver (TI) */ -#include "gpio.h" /* GPIO driver (TI) */ -/* add other drivers if necessary... */ +#include "TM4C123GH6PM.h" // the device specific header (TI) +#include "rom.h" // the built-in ROM functions (TI) +#include "sysctl.h" // system control driver (TI) +#include "gpio.h" // GPIO driver (TI) +// add other drivers if necessary... -Q_DEFINE_THIS_FILE /* define the name of this file for assertions */ +Q_DEFINE_THIS_FILE // define the name of this file for assertions -/* prototypes of ISRs defined in this BSP ----------------------------------*/ -void UART0_IRQHandler(void); +// Local-scope defines ----------------------------------------------------- +#define LED_RED (1U << 1U) +#define LED_GREEN (1U << 3U) +#define LED_BLUE (1U << 2U) -/* Local-scope objects -----------------------------------------------------*/ -#define LED_RED (1U << 1) -#define LED_GREEN (1U << 3) -#define LED_BLUE (1U << 2) +#define BTN_SW1 (1U << 4U) +#define BTN_SW2 (1U << 0U) -#define BTN_SW1 (1U << 4) -#define BTN_SW2 (1U << 0) - -static uint32_t l_rnd; /* random seed */ -static TX_TIMER l_tick_timer; /* ThreadX timer to call QTIMEEVT_TICK_X() */ +static uint32_t l_rndSeed; +static TX_TIMER l_tick_timer; // ThreadX timer to call QTIMEEVT_TICK_X() #ifdef Q_SPY - /* QSpy source IDs */ + // QSpy source IDs static QSpyId const l_clock_tick = { QS_AP_ID }; + // ThreadX "idle" thread for QS output, see NOTE1 + static TX_THREAD idle_thread; + static ULONG idle_thread_stack[100]; + #define UART_BAUD_RATE 115200U - #define UART_FR_TXFE (1U << 7) - #define UART_FR_RXFE (1U << 4) + #define UART_FR_TXFE (1U << 7U) + #define UART_FR_RXFE (1U << 4U) #define UART_TXFIFO_DEPTH 16U - enum AppRecords { /* application-specific trace records */ + enum AppRecords { // application-specific trace records PHILO_STAT = QS_USER, PAUSED_STAT, - COMMAND_STAT }; #endif -/* ISRs used in the application ==========================================*/ +static TX_TIMER l_tick_timer; // ThreadX timer to call QTIMEEVT_TICK_X() +static VOID timer_expiration(ULONG id); +static VOID timer_expiration(ULONG id) { + QTIMEEVT_TICK_X(id, &l_clock_tick); // QF clock tick processing +} +//============================================================================ +// Error handler + +Q_NORETURN Q_onError(char const * const module, int_t const id) { + // NOTE: this implementation of the error handler is intended only + // for debugging and MUST be changed for deployment of the application + // (assuming that you ship your production code with assertions enabled). + Q_UNUSED_PAR(module); + Q_UNUSED_PAR(id); + QS_ASSERTION(module, id, 10000U); // report assertion to QS + +#ifndef NDEBUG + // light up all LEDs + GPIOF_AHB->DATA_Bits[LED_GREEN | LED_RED | LED_BLUE] = 0xFFU; + // for debugging, hang on in an endless loop... + for (;;) { + } +#else + NVIC_SystemReset(); + for (;;) { // explicitly "no-return" + } +#endif +} +//............................................................................ +void assert_failed(char const * const module, int_t const id); // prototype +void assert_failed(char const * const module, int_t const id) { + Q_onError(module, id); +} + +// ISRs and ThreadX IRS callbacks used in the application ==================== + +//............................................................................ #ifdef Q_SPY -/* -* ISR for receiving bytes from the QSPY Back-End -* NOTE: This ISR is "QF-unaware" meaning that it does not interact with -* the QF/QK and is not disabled. Such ISRs don't need to call QK_ISR_ENTRY/ -* QK_ISR_EXIT and they cannot post or publish events. -*/ -void UART0_IRQHandler(void) { - uint32_t status = UART0->RIS; /* get the raw interrupt status */ - UART0->ICR = status; /* clear the asserted interrupts */ - while ((UART0->FR & UART_FR_RXFE) == 0) { /* while RX FIFO NOT empty */ +//............................................................................ +static void idle_thread_fun(ULONG thread_input); // prototype +static void idle_thread_fun(ULONG thread_input) { // see NOTE1 + for (;;) { + QF_CRIT_STAT + + QF_CRIT_ENTRY(); + QS_rxParse(); // parse all the received bytes + QF_CRIT_EXIT(); + + if ((UART0->FR & UART_FR_TXFE) != 0U) { // TX done? + uint16_t fifo = UART_TXFIFO_DEPTH; // max bytes we can accept + + QF_CRIT_ENTRY(); + uint8_t const *block = QS_getBlock(&fifo); + QF_CRIT_EXIT(); + + while (fifo-- != 0U) { // any bytes in the block? + UART0->DR = *block++; // put into the FIFO + } + } + + // no blocking in this "idle" thread; see NOTE1 + } +} + +//............................................................................ +// ISR for receiving bytes from the QSPY Back-End +// NOTE: This ISR is "kernel-unaware" meaning that it does not interact with +// the or QP and is not disabled. Such ISRs don't cannot call any +// ThreadX or QP APIs. +void UART0_IRQHandler(void); // prototype +void UART0_IRQHandler(void) { + uint32_t status = UART0->RIS; // get the raw interrupt status + UART0->ICR = status; // clear the asserted interrupts + + while ((UART0->FR & UART_FR_RXFE) == 0U) { // while RX FIFO NOT empty uint32_t b = UART0->DR; QS_RX_PUT(b); } } -#else -void UART0_IRQHandler(void) {} -#endif -/* MPU setup for TM4C123GXL MCU */ -static void TM4C123GXL_MPU_setup(void) { - /* The following MPU configuration contains the general TM4C memory map. - * - * Please note that the actual TM4C MCUs provide much less Flash and SRAM - * than the maximums configured here. This means that actual MCUs have - * unmapped memory regions (e.g., beyond the actual SRAM). Attempts to - * access these regions causes the HardFault exception, which is the - * desired behavior. - */ - static struct { - uint32_t rbar; - uint32_t rasr; - } const mpu_setup[] = { - { /* region #0: Flash: base=0x0000'0000, size=512M=2^(28+1) */ - 0x00000000U /* base address */ - | MPU_RBAR_VALID_Msk /* valid region */ - | (MPU_RBAR_REGION_Msk & 0U), /* region #0 */ - (28U << MPU_RASR_SIZE_Pos) /* 2^(18+1) region */ - | (0x6U << MPU_RASR_AP_Pos) /* PA:ro/UA:ro */ - | (1U << MPU_RASR_C_Pos) /* C=1 */ - | MPU_RASR_ENABLE_Msk /* region enable */ - }, +#endif // Q_SPY - { /* region #1: SRAM: base=0x2000'0000, size=512M=2^(28+1) */ - 0x20000000U /* base address */ - | MPU_RBAR_VALID_Msk /* valid region */ - | (MPU_RBAR_REGION_Msk & 1U), /* region #1 */ - (28U << MPU_RASR_SIZE_Pos) /* 2^(28+1) region */ - | (0x3U << MPU_RASR_AP_Pos) /* PA:rw/UA:rw */ - | (1U << MPU_RASR_XN_Pos) /* XN=1 */ - | (1U << MPU_RASR_S_Pos) /* S=1 */ - | (1U << MPU_RASR_C_Pos) /* C=1 */ - | MPU_RASR_ENABLE_Msk /* region enable */ - }, +// BSP functions =========================================================== +void BSP_init(void) { + // Configure the MPU to prevent NULL-pointer dereferencing ... + MPU->RBAR = 0x0U // base address (NULL) + | MPU_RBAR_VALID_Msk // valid region + | (MPU_RBAR_REGION_Msk & 7U); // region #7 + MPU->RASR = (7U << MPU_RASR_SIZE_Pos) // 2^(7+1) region + | (0x0U << MPU_RASR_AP_Pos) // no-access region + | MPU_RASR_ENABLE_Msk; // region enable + MPU->CTRL = MPU_CTRL_PRIVDEFENA_Msk // enable background region + | MPU_CTRL_ENABLE_Msk; // enable the MPU + __ISB(); + __DSB(); - /* region #3: (not configured) */ - { MPU_RBAR_VALID_Msk | (MPU_RBAR_REGION_Msk & 2U), 0U }, - - { /* region #3: Peripherals: base=0x4000'0000, size=512M=2^(28+1) */ - 0x40000000U /* base address */ - | MPU_RBAR_VALID_Msk /* valid region */ - | (MPU_RBAR_REGION_Msk & 3U), /* region #3 */ - (28U << MPU_RASR_SIZE_Pos) /* 2^(28+1) region */ - | (0x3U << MPU_RASR_AP_Pos) /* PA:rw/UA:rw */ - | (1U << MPU_RASR_XN_Pos) /* XN=1 */ - | (1U << MPU_RASR_S_Pos) /* S=1 */ - | (1U << MPU_RASR_B_Pos) /* B=1 */ - | MPU_RASR_ENABLE_Msk /* region enable */ - }, - - { /* region #4: Priv. Periph: base=0xE000'0000, size=512M=2^(28+1) */ - 0xE0000000U /* base address */ - | MPU_RBAR_VALID_Msk /* valid region */ - | (MPU_RBAR_REGION_Msk & 4U), /* region #4 */ - (28U << MPU_RASR_SIZE_Pos) /* 2^(28+1) region */ - | (0x3U << MPU_RASR_AP_Pos) /* PA:rw/UA:rw */ - | (1U << MPU_RASR_XN_Pos) /* XN=1 */ - | (1U << MPU_RASR_S_Pos) /* S=1 */ - | (1U << MPU_RASR_B_Pos) /* B=1 */ - | MPU_RASR_ENABLE_Msk /* region enable */ - }, - - { /* region #5: Ext RAM: base=0x6000'0000, size=1G=2^(29+1) */ - 0x60000000U /* base address */ - | MPU_RBAR_VALID_Msk /* valid region */ - | (MPU_RBAR_REGION_Msk & 5U), /* region #5 */ - (29U << MPU_RASR_SIZE_Pos) /* 2^(28+1) region */ - | (0x3U << MPU_RASR_AP_Pos) /* PA:rw/UA:rw */ - | (1U << MPU_RASR_XN_Pos) /* XN=1 */ - | (1U << MPU_RASR_S_Pos) /* S=1 */ - | (1U << MPU_RASR_B_Pos) /* B=1 */ - | MPU_RASR_ENABLE_Msk /* region enable */ - }, - - { /* region #6: Ext Dev: base=0xA000'0000, size=1G=2^(29+1) */ - 0xA0000000U /* base address */ - | MPU_RBAR_VALID_Msk /* valid region */ - | (MPU_RBAR_REGION_Msk & 6U), /* region #6 */ - (29U << MPU_RASR_SIZE_Pos) /* 2^(28+1) region */ - | (0x3U << MPU_RASR_AP_Pos) /* PA:rw/UA:rw */ - | (1U << MPU_RASR_XN_Pos) /* XN=1 */ - | (1U << MPU_RASR_S_Pos) /* S=1 */ - | (1U << MPU_RASR_B_Pos) /* B=1 */ - | MPU_RASR_ENABLE_Msk /* region enable */ - }, - - { /* region #7: NULL-pointer: base=0x000'0000, size=512B */ - 0x00000000U /* base address */ - | MPU_RBAR_VALID_Msk /* valid region */ - | (MPU_RBAR_REGION_Msk & 7U), /* region #7 */ - (8U << MPU_RASR_SIZE_Pos) /* 2^(8+1)=512B region */ - | (0x0U << MPU_RASR_AP_Pos) /* PA:na/UA:na */ - | (1U << MPU_RASR_XN_Pos) /* XN=1 */ - | MPU_RASR_ENABLE_Msk /* region enable */ - }, - }; - - /* enable the MemManage_Handler for MPU exception */ + // enable the MemManage_Handler for MPU exception SCB->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk; - __DSB(); - MPU->CTRL = 0U; /* disable the MPU */ - for (uint_fast8_t n = 0U; n < Q_DIM(mpu_setup); ++n) { - MPU->RBAR = mpu_setup[n].rbar; - MPU->RASR = mpu_setup[n].rasr; - } - MPU->CTRL = MPU_CTRL_ENABLE_Msk; /* enable the MPU */ - __ISB(); - __DSB(); -} - -/*..........................................................................*/ -void BSP_init(void) { - /* setup the MPU... */ - TM4C123GXL_MPU_setup(); - - /* NOTE: SystemInit() already called from the startup code - * but SystemCoreClock needs to be updated - */ + // NOTE: SystemInit() has been already called from the startup code + // but SystemCoreClock needs to be updated SystemCoreClockUpdate(); - /* NOTE The VFP (Floating Point Unit) unit is configured by the RTOS */ + // NOTE: VFP (hardware Floating Point) unit is configured by ThreadX - /* enable clock for to the peripherals used by this application... */ - SYSCTL->RCGCGPIO |= (1U << 5); /* enable Run mode for GPIOF */ - SYSCTL->GPIOHBCTL |= (1U << 5); /* enable AHB for GPIOF */ + // enable clock for to the peripherals used by this application... + SYSCTL->RCGCGPIO |= (1U << 5U); // enable Run mode for GPIOF + SYSCTL->GPIOHBCTL |= (1U << 5U); // enable AHB for GPIOF __ISB(); __DSB(); - /* configure LEDs (digital output) */ + // configure LEDs (digital output) GPIOF_AHB->DIR |= (LED_RED | LED_BLUE | LED_GREEN); GPIOF_AHB->DEN |= (LED_RED | LED_BLUE | LED_GREEN); GPIOF_AHB->DATA_Bits[LED_RED | LED_BLUE | LED_GREEN] = 0U; - /* configure switches... */ + // configure switches... - /* unlock access to the SW2 pin because it is PROTECTED */ - GPIOF_AHB->LOCK = 0x4C4F434BU; /* unlock GPIOCR register for SW2 */ - /* commit the write (cast const away) */ + // unlock access to the SW2 pin because it is PROTECTED + GPIOF_AHB->LOCK = 0x4C4F434BU; // unlock GPIOCR register for SW2 + // commit the write (cast const away) *(uint32_t volatile *)&GPIOF_AHB->CR = 0x01U; - GPIOF_AHB->DIR &= ~(BTN_SW1 | BTN_SW2); /* input */ - GPIOF_AHB->DEN |= (BTN_SW1 | BTN_SW2); /* digital enable */ - GPIOF_AHB->PUR |= (BTN_SW1 | BTN_SW2); /* pull-up resistor enable */ + GPIOF_AHB->DIR &= ~(BTN_SW1 | BTN_SW2); // input + GPIOF_AHB->DEN |= (BTN_SW1 | BTN_SW2); // digital enable + GPIOF_AHB->PUR |= (BTN_SW1 | BTN_SW2); // pull-up resistor enable *(uint32_t volatile *)&GPIOF_AHB->CR = 0x00U; - GPIOF_AHB->LOCK = 0x0; /* lock GPIOCR register for SW2 */ + GPIOF_AHB->LOCK = 0x0; // lock GPIOCR register for SW2 - /* seed the random number generator */ + // seed the random number generator BSP_randomSeed(1234U); - /* initialize the QS software tracing... */ + // initialize the QS software tracing... if (QS_INIT((void *)0) == 0U) { Q_ERROR(); } + + // dictionaries... QS_OBJ_DICTIONARY(&l_clock_tick); QS_USR_DICTIONARY(PHILO_STAT); QS_USR_DICTIONARY(PAUSED_STAT); - QS_USR_DICTIONARY(COMMAND_STAT); - /* setup the QS filters... */ - QS_GLB_FILTER(QS_ALL_RECORDS); /* all records */ - QS_GLB_FILTER(-QS_QF_TICK); /* exclude the clock tick */ + QS_ONLY(produce_sig_dict()); + + // setup the QS filters... + QS_GLB_FILTER(QS_ALL_RECORDS); // all records + QS_GLB_FILTER(-QS_QF_TICK); // exclude the clock tick } -/*..........................................................................*/ +//............................................................................ void BSP_displayPhilStat(uint8_t n, char const *stat) { + Q_UNUSED_PAR(n); + GPIOF_AHB->DATA_Bits[LED_GREEN] = ((stat[0] == 'e') ? LED_GREEN : 0U); - QS_BEGIN_ID(PHILO_STAT, AO_Philo[n]->prio) /* app-specific record */ - QS_U8(1, n); /* Philosopher number */ - QS_STR(stat); /* Philosopher status */ + // app-specific trace record... + QS_BEGIN_ID(PHILO_STAT, AO_Table->prio) + QS_U8(1, n); // Philosopher number + QS_STR(stat); // Philosopher status QS_END() } -/*..........................................................................*/ -void BSP_displayPaused(uint8_t paused) { +//............................................................................ +void BSP_displayPaused(uint8_t const paused) { GPIOF_AHB->DATA_Bits[LED_BLUE] = ((paused != 0U) ? LED_BLUE : 0U); - QS_BEGIN_ID(PAUSED_STAT, 0U) /* app-specific record */ - QS_U8(1, paused); /* Paused status */ + // application-specific trace record + QS_BEGIN_ID(PAUSED_STAT, AO_Table->prio) + QS_U8(1, paused); // Paused status QS_END() } -/*..........................................................................*/ -uint32_t BSP_random(void) { /* a very cheap pseudo-random-number generator */ - /* Some flating point code is to exercise the VFP... */ +//............................................................................ +void BSP_randomSeed(uint32_t const seed) { + l_rndSeed = seed; +} +//............................................................................ +uint32_t BSP_random(void) { // a very cheap pseudo-random-number generator + // Some flating point code is to exercise the VFP... float volatile x = 3.1415926F; x = x + 2.7182818F; - /* "Super-Duper" Linear Congruential Generator (LCG) - * LCG(2^32, 3*7*11*13*23, 0, seed) - */ - l_rnd = l_rnd * (3U*7U*11U*13U*23U); + // NOTE: l_rndSeed is SHARED among the Philo AOs, but does not need + // to be protected because all Philos have the same ThreadX preemption + // threshold, so they cannot preempt each other. + uint32_t rnd = l_rndSeed * (3U*7U*11U*13U*23U); + l_rndSeed = rnd; // set for the next time - return l_rnd >> 8; + return (rnd >> 8); } -/*..........................................................................*/ -void BSP_randomSeed(uint32_t seed) { - l_rnd = seed; +//............................................................................ +void BSP_ledOn(void) { + GPIOF_AHB->DATA_Bits[LED_RED] = 0xFFU; } -/*..........................................................................*/ +//............................................................................ +void BSP_ledOff(void) { + GPIOF_AHB->DATA_Bits[LED_RED] = 0x00U; +} +//............................................................................ void BSP_terminate(int16_t result) { - (void)result; + Q_UNUSED_PAR(result); } +// QF callbacks ============================================================ -#ifdef Q_SPY - /* ThreadX "idle" thread for QS output, see NOTE1 */ - static TX_THREAD idle_thread; - static void idle_thread_fun(ULONG thread_input); - static ULONG idle_thread_stack[64]; -#endif - -/* QF callbacks ============================================================*/ -static VOID timer_expiration(ULONG id) { - QTIMEEVT_TICK_X(id, &l_clock_tick); /* perform the QF clock tick processing */ -} -/*..........................................................................*/ +//............................................................................ void QF_onStartup(void) { - /* - * NOTE: - * This application uses the ThreadX timer to periodically call - * the QTimeEvt_tick_(0) function. Here, only the clock tick rate of 0 - * is used, but other timers can be used to call QTimeEvt_tick_() for - * other clock tick rates, if needed. - * - * The choice of a ThreadX timer is not the only option. Applications - * might choose to call QTIMEEVT_TICK_X() directly from timer interrupts - * or from active object(s). - */ - Q_ALLEGE(tx_timer_create(&l_tick_timer, /* ThreadX timer object */ - (CHAR *)"QP-tick", /* name of the timer */ - &timer_expiration, /* expiration function */ - 0U, /* expiration function input (tick rate) */ - 1U, /* initial ticks */ - 1U, /* reschedule ticks */ - TX_AUTO_ACTIVATE) /* automatically activate timer */ - == TX_SUCCESS); + + // NOTE: + // This application uses the ThreadX timer to periodically call + // the QTimeEvt_tick_(0) function. Here, only the clock tick rate of 0 + // is used, but other timers can be used to call QTimeEvt_tick_() for + // other clock tick rates, if needed. + // + // The choice of a ThreadX timer is not the only option. Applications + // might choose to call QTIMEEVT_TICK_X() directly from timer interrupts + // or from active object(s). + // + UINT tx_err = tx_timer_create(&l_tick_timer, // ThreadX timer object + (CHAR *)"TICK0", // name of the timer + &timer_expiration, // expiration function + 0U, // expiration function input (tick rate) + 1U, // initial ticks + 1U, // reschedule ticks + TX_AUTO_ACTIVATE); + Q_ASSERT(tx_err == TX_SUCCESS); #ifdef Q_SPY - NVIC_EnableIRQ(UART0_IRQn); /* UART0 interrupt used for QS-RX */ + NVIC_EnableIRQ(UART0_IRQn); // UART0 interrupt used for QS-RX - /* start a ThreadX "idle" thread. See NOTE1... */ - Q_ALLEGE(tx_thread_create(&idle_thread, /* thread control block */ - (CHAR *)("idle"), /* thread name */ - &idle_thread_fun, /* thread function */ - 0LU, /* thread input (unsued) */ - idle_thread_stack, /* stack start */ - sizeof(idle_thread_stack), /* stack size in bytes */ - TX_MAX_PRIORITIES - 1U, /* ThreadX priority (LOWEST possible), NOTE1 */ - TX_MAX_PRIORITIES - 1U, /* preemption threshold disabled */ + // start a ThreadX "idle" thread. See NOTE1... + tx_err = tx_thread_create(&idle_thread, // thread control block + (CHAR *)("idle"), // thread name + &idle_thread_fun, // thread function + 0LU, // thread input (unsued) + idle_thread_stack, // stack start + sizeof(idle_thread_stack), // stack size in bytes + TX_MAX_PRIORITIES - 1U, // ThreadX priority (LOWEST possible), NOTE1 + TX_MAX_PRIORITIES - 1U, // preemption threshold disabled TX_NO_TIME_SLICE, - TX_AUTO_START) - == TX_SUCCESS); -#endif /* Q_SPY */ + TX_AUTO_START); + Q_ASSERT(tx_err == TX_SUCCESS); +#endif // Q_SPY } -/*..........................................................................*/ +//............................................................................ void QF_onCleanup(void) { } -/*..........................................................................*/ -Q_NORETURN Q_onAssert(char const * const module, int_t const loc) { - /* - * NOTE: add here your application-specific error handling - */ - (void)module; - (void)loc; - QS_ASSERTION(module, loc, 10000U); /* report assertion to QS */ - -#ifndef NDEBUG - /* light up all LEDs */ - GPIOF_AHB->DATA_Bits[LED_GREEN | LED_RED | LED_BLUE] = 0xFFU; - /* for debugging, hang on in an endless loop... */ - for (;;) { - } -#endif - - NVIC_SystemReset(); -} - -/* QS callbacks ============================================================*/ +// QS callbacks -------------------------------------------------------------- #ifdef Q_SPY -/*..........................................................................*/ -static void idle_thread_fun(ULONG thread_input) { /* see NOTE1 */ - for (;;) { - QS_rxParse(); /* parse all the received bytes */ - - if ((UART0->FR & UART_FR_TXFE) != 0U) { /* TX done? */ - uint16_t fifo = UART_TXFIFO_DEPTH; /* max bytes we can accept */ - uint8_t const *block; - QF_CRIT_STAT_TYPE intStat; - - QF_CRIT_ENTRY(intStat); - block = QS_getBlock(&fifo); /* try to get next block to transmit */ - QF_CRIT_EXIT(intStat); - - while (fifo-- != 0U) { /* any bytes in the block? */ - UART0->DR = *block++; /* put into the FIFO */ - } - } - - /* no blocking in this "idle" thread; see NOTE1 */ - } -} - -/*..........................................................................*/ +//............................................................................ uint8_t QS_onStartup(void const *arg) { - static uint8_t qsTxBuf[2*1024]; /* buffer for QS transmit channel */ - static uint8_t qsRxBuf[100]; /* buffer for QS receive channel */ + Q_UNUSED_PAR(arg); - QS_initBuf (qsTxBuf, sizeof(qsTxBuf)); + static uint8_t qsTxBuf[2*1024]; // buffer for QS-TX channel + QS_initBuf(qsTxBuf, sizeof(qsTxBuf)); + + static uint8_t qsRxBuf[100]; // buffer for QS-RX channel QS_rxInitBuf(qsRxBuf, sizeof(qsRxBuf)); - /* enable clock for UART0 and GPIOA (used by UART0 pins) */ - SYSCTL->RCGCUART |= (1U << 0); /* enable Run mode for UART0 */ - SYSCTL->RCGCGPIO |= (1U << 0); /* enable Run mode for GPIOA */ + // enable clock for UART0 and GPIOA (used by UART0 pins) + SYSCTL->RCGCUART |= (1U << 0U); // enable Run mode for UART0 + SYSCTL->RCGCGPIO |= (1U << 0U); // enable Run mode for GPIOA - /* configure UART0 pins for UART operation */ - uint32_t tmp = (1U << 0) | (1U << 1); + // configure UART0 pins for UART operation + uint32_t tmp = (1U << 0U) | (1U << 1U); GPIOA->DIR &= ~tmp; GPIOA->SLR &= ~tmp; GPIOA->ODR &= ~tmp; GPIOA->PUR &= ~tmp; GPIOA->PDR &= ~tmp; - GPIOA->AMSEL &= ~tmp; /* disable analog function on the pins */ - GPIOA->AFSEL |= tmp; /* enable ALT function on the pins */ - GPIOA->DEN |= tmp; /* enable digital I/O on the pins */ + GPIOA->AMSEL &= ~tmp; // disable analog function on the pins + GPIOA->AFSEL |= tmp; // enable ALT function on the pins + GPIOA->DEN |= tmp; // enable digital I/O on the pins GPIOA->PCTL &= ~0x00U; GPIOA->PCTL |= 0x11U; - /* configure the UART for the desired baud rate, 8-N-1 operation */ + // configure the UART for the desired baud rate, 8-N-1 operation tmp = (((SystemCoreClock * 8U) / UART_BAUD_RATE) + 1U) / 2U; UART0->IBRD = tmp / 64U; UART0->FBRD = tmp % 64U; - UART0->LCRH = (0x3U << 5); /* configure 8-N-1 operation */ - UART0->LCRH |= (0x1U << 4); /* enable FIFOs */ - UART0->CTL = (1U << 0) /* UART enable */ - | (1U << 8) /* UART TX enable */ - | (1U << 9); /* UART RX enable */ + UART0->LCRH = (0x3U << 5U); // configure 8-N-1 operation + UART0->LCRH |= (0x1U << 4U); // enable FIFOs + UART0->CTL = (1U << 0U) // UART enable + | (1U << 8U) // UART TX enable + | (1U << 9U); // UART RX enable - /* configure UART interrupts (for the RX channel) */ - UART0->IM |= (1U << 4) | (1U << 6); /* enable RX and RX-TO interrupt */ - UART0->IFLS |= (0x2U << 2); /* interrupt on RX FIFO half-full */ - /* NOTE: do not enable the UART0 interrupt yet. Wait till QF_onStartup() */ + // configure UART interrupts (for the RX channel) + UART0->IM |= (1U << 4U) | (1U << 6U); // enable RX and RX-TO interrupt + UART0->IFLS |= (0x2U << 2U); // interrupt on RX FIFO half-full + // NOTE: do not enable the UART0 interrupt yet. Wait till QF_onStartup() - /* configure TIMER5 to produce QS time stamp */ - SYSCTL->RCGCTIMER |= (1U << 5); /* enable run mode for Timer5 */ - TIMER5->CTL = 0U; /* disable Timer1 output */ - TIMER5->CFG = 0x0U; /* 32-bit configuration */ - TIMER5->TAMR = (1U << 4) | 0x02; /* up-counting periodic mode */ - TIMER5->TAILR= 0xFFFFFFFFU; /* timer interval */ - TIMER5->ICR = 0x1U; /* TimerA timeout flag bit clears*/ - TIMER5->CTL |= (1U << 0); /* enable TimerA module */ + // configure TIMER5 to produce QS time stamp + SYSCTL->RCGCTIMER |= (1U << 5U); // enable run mode for Timer5 + TIMER5->CTL = 0U; // disable Timer1 output + TIMER5->CFG = 0x0U; // 32-bit configuration + TIMER5->TAMR = (1U << 4U) | 0x02U; // up-counting periodic mode + TIMER5->TAILR= 0xFFFFFFFFU; // timer interval + TIMER5->ICR = 0x1U; // TimerA timeout flag bit clears + TIMER5->CTL |= (1U << 0U); // enable TimerA module - return 1U; /* return success */ + return 1U; // return success } -/*..........................................................................*/ +//............................................................................ void QS_onCleanup(void) { } -/*..........................................................................*/ -QSTimeCtr QS_onGetTime(void) { /* NOTE: invoked with interrupts DISABLED */ +//............................................................................ +QSTimeCtr QS_onGetTime(void) { // NOTE: invoked with interrupts DISABLED return TIMER5->TAV; } -/*..........................................................................*/ +//............................................................................ void QS_onFlush(void) { - while (true) { - /* try to get next byte to transmit */ - QF_CRIT_STAT_TYPE intStat; - - QF_CRIT_ENTRY(intStat); + for (;;) { + QF_CRIT_STAT + QF_CRIT_ENTRY(); uint16_t b = QS_getByte(); - QF_CRIT_EXIT(intStat); + QF_CRIT_EXIT(); - if (b != QS_EOD) { /* NOT end-of-data */ - /* busy-wait as long as TX FIFO has data to transmit */ - while ((UART0->FR & UART_FR_TXFE) == 0) { + if (b != QS_EOD) { // NOT end-of-data + // busy-wait as long as TXE not set + while ((UART0->FR & UART_FR_TXFE) == 0U) { } - /* place the byte in the UART DR register */ + // place the byte in the UART DR register UART0->DR = b; } else { - break; /* break out of the loop */ + break; // break out of the loop } } } -/*..........................................................................*/ -/*! callback function to reset the target (to be implemented in the BSP) */ +//............................................................................ +//! callback function to reset the target (to be implemented in the BSP) void QS_onReset(void) { NVIC_SystemReset(); } -/*..........................................................................*/ -/*! callback function to execute a user command (to be implemented in BSP) */ +//............................................................................ void QS_onCommand(uint8_t cmdId, uint32_t param1, uint32_t param2, uint32_t param3) { - QS_BEGIN_ID(COMMAND_STAT, 0U) /* app-specific record */ - QS_U8(2, cmdId); - QS_U32(8, param1); - QS_U32(8, param2); - QS_U32(8, param3); - QS_END() + Q_UNUSED_PAR(cmdId); + Q_UNUSED_PAR(param1); + Q_UNUSED_PAR(param2); + Q_UNUSED_PAR(param3); } -#endif /* Q_SPY */ -/*--------------------------------------------------------------------------*/ +#endif // Q_SPY +//---------------------------------------------------------------------------- -/*============================================================================ -* NOTE1: -* ThreadX apparently does not have a concpet of an "idle" thread, but -* it can be emulated by a regular, but NON-BLOCKING ThreadX thread of -* the lowest priority. -* -* In the Q_SPY configuration, this "idle" thread is uded to perform -* the QS data output to the host. This is not the only choice available, and -* other applications might choose to peform the QS output some other way. -*/ +//============================================================================ +// NOTE1: +// ThreadX apparently does not have a concept of an "idle" thread, but +// it can be emulated by a regular, but NON-BLOCKING ThreadX thread of +// the lowest priority. +// +// In the Q_SPY configuration, this "idle" thread is used to perform +// the QS data output to the host. This is not the only choice available, and +// other applications might choose to perform the QS output some other way. +// diff --git a/examples/threadx/arm-cm/dpp_ek-tm4c123gxl/bsp.h b/examples/threadx/arm-cm/dpp_ek-tm4c123gxl/bsp.h index b699e5ba..d1ededad 100644 --- a/examples/threadx/arm-cm/dpp_ek-tm4c123gxl/bsp.h +++ b/examples/threadx/arm-cm/dpp_ek-tm4c123gxl/bsp.h @@ -1,38 +1,36 @@ -/***************************************************************************** -* Product: DPP example, ThreadX -* Last Updated for Version: 6.3.8 -* Date of the Last Update: 2019-01-30 -* -* Q u a n t u m L e a P s -* ------------------------ -* Modern Embedded Software -* -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* -* -*****************************************************************************/ -#ifndef BSP_H -#define BSP_H +//============================================================================ +// Product: DPP example, ThreadX +// Last updated for version 7.3.0 +// Last updated on 2023-08-30 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +//============================================================================ +#ifndef BSP_H_ +#define BSP_H_ #define BSP_TICKS_PER_SEC TX_TIMER_TICKS_PER_SECOND @@ -41,7 +39,11 @@ void BSP_displayPaused(uint8_t paused); void BSP_displayPhilStat(uint8_t n, char const *stat); void BSP_terminate(int16_t result); -void BSP_randomSeed(uint32_t seed); /* random seed */ -uint32_t BSP_random(void); /* pseudo-random generator */ +void BSP_randomSeed(uint32_t seed); // random seed +uint32_t BSP_random(void); // pseudo-random generator + +void BSP_ledOn(void); +void BSP_ledOff(void); + +#endif // BSP_H_ -#endif /* BSP_H */ diff --git a/examples/threadx/arm-cm/dpp_ek-tm4c123gxl/dpp.h b/examples/threadx/arm-cm/dpp_ek-tm4c123gxl/dpp.h index c45cc7c6..e6d1557a 100644 --- a/examples/threadx/arm-cm/dpp_ek-tm4c123gxl/dpp.h +++ b/examples/threadx/arm-cm/dpp_ek-tm4c123gxl/dpp.h @@ -1,94 +1,117 @@ -/*$file${.::dpp.h} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* -* Model: dpp.qm -* File: ${.::dpp.h} -* -* This code has been generated by QM 5.2.4 . -* DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. -* -* SPDX-License-Identifier: GPL-3.0-or-later -* -* This generated code is open source software: you can redistribute it under -* the terms of the GNU General Public License as published by the Free -* Software Foundation. -* -* This code is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -* more details. -* -* NOTE: -* Alternatively, this generated code may be distributed under the terms -* of Quantum Leaps commercial licenses, which expressly supersede the GNU -* General Public License and are specifically designed for licensees -* interested in retaining the proprietary status of their code. -* -* Contact information: -* -* -*/ -/*$endhead${.::dpp.h} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -#ifndef DPP_H -#define DPP_H +//$file${.::dpp.h} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// +// Model: dpp.qm +// File: ${.::dpp.h} +// +// This code has been generated by QM 5.3.0 . +// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. +// +// SPDX-License-Identifier: GPL-3.0-or-later +// +// This generated code is open source software: you can redistribute it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation. +// +// This code is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// NOTE: +// Alternatively, this generated code may be distributed under the terms +// of Quantum Leaps commercial licenses, which expressly supersede the GNU +// General Public License and are specifically designed for licensees +// interested in retaining the proprietary status of their code. +// +// Contact information: +// +// +// +//$endhead${.::dpp.h} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +#ifndef DPP_H_ +#define DPP_H_ -enum DPPSignals { - EAT_SIG = Q_USER_SIG, /* published by Table to let a philosopher eat */ - DONE_SIG, /* published by Philosopher when done eating */ - PAUSE_SIG, /* published by BSP to pause serving forks */ - SERVE_SIG, /* published by BSP to serve re-start serving forks */ - TEST_SIG, /* published by BSP to test the application */ - MAX_PUB_SIG, /* the last published signal */ +//$declare${Shared} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv - HUNGRY_SIG, /* posted direclty to Table from hungry Philo */ - TIMEOUT_SIG, /* used by Philosophers for time events */ - MAX_SIG /* the last signal */ +//${Shared::AppSignals} ...................................................... +enum AppSignals { + EAT_SIG = Q_USER_SIG, // published by Table to let a Philo eat + DONE_SIG, // published by Philo when done eating + PAUSE_SIG, // published by BSP to pause the application + SERVE_SIG, // published by BSP to serve re-start serving forks + TEST_SIG, // published by BSP to test the application + MAX_PUB_SIG, // the last published signal + + TIMEOUT_SIG, // posted by time event to Philo + HUNGRY_SIG, // posted by hungry Philo to Table + MAX_SIG // the last signal }; -/*$declare${Events::TableEvt} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//${Shared::produce_sig_dict} ................................................ +#ifdef Q_SPY +static inline void produce_sig_dict(void) { + QS_SIG_DICTIONARY(EAT_SIG, (void *)0); + QS_SIG_DICTIONARY(DONE_SIG, (void *)0); + QS_SIG_DICTIONARY(PAUSE_SIG, (void *)0); + QS_SIG_DICTIONARY(SERVE_SIG, (void *)0); + QS_SIG_DICTIONARY(TEST_SIG, (void *)0); -/*${Events::TableEvt} ......................................................*/ + QS_SIG_DICTIONARY(TIMEOUT_SIG, (void *)0); + QS_SIG_DICTIONARY(HUNGRY_SIG, (void *)0); +} +#endif // def Q_SPY + +//${Shared::N_PHILO} ......................................................... +#define N_PHILO ((uint8_t)5U) + +//${Shared::TableEvt} ........................................................ typedef struct { -/* protected: */ +// protected: QEvt super; -/* public: */ - uint8_t philoNum; +// public: + uint8_t philoId; } TableEvt; -/*$enddecl${Events::TableEvt} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/* number of philosophers */ -#define N_PHILO ((uint8_t)5) +// public: -/*$declare${AOs::Philo_ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +#ifdef QEVT_DYN_CTOR +static inline TableEvt * TableEvt_ctor(TableEvt * const me, + uint8_t id) +{ + if (me != (TableEvt *)0) { + // don't call QEvt_ctor() because the initialization of all + // QEvt attributes is already done in QF_QF_newX_() + me->philoId = id; + } + return me; +} +#endif // def QEVT_DYN_CTOR -/*${AOs::Philo_ctor} .......................................................*/ -void Philo_ctor(void); -/*$enddecl${AOs::Philo_ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*$declare${AOs::AO_Philo[N_PHILO]} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${AOs::AO_Philo[N_PHILO]} ................................................*/ -/* opaque pointers to the Philo AOs */ +//${Shared::AO_Philo[N_PHILO]} ............................................... extern QActive * const AO_Philo[N_PHILO]; -/*$enddecl${AOs::AO_Philo[N_PHILO]} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*$declare${AOs::Table_ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//${Shared::Philo_ctor} ...................................................... +void Philo_ctor(uint_fast8_t const id); -/*${AOs::Table_ctor} .......................................................*/ -void Table_ctor(void); -/*$enddecl${AOs::Table_ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*$declare${AOs::AO_Table} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${AOs::AO_Table} .........................................................*/ -/* opaque pointer to the Table AO */ +//${Shared::AO_Table} ........................................................ extern QActive * const AO_Table; -/*$enddecl${AOs::AO_Table} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -#ifdef QP_INC_QXK_H_ - void Test1_ctor(void); - extern QXThread * const XT_Test1; - void Test2_ctor(void); - extern QXThread * const XT_Test2; -#endif /* QP_INC_QXK_H_ */ +//${Shared::Table_ctor} ...................................................... +void Table_ctor(void); +//$enddecl${Shared} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -#endif /* DPP_H */ +#ifdef QXK_H_ +extern QXThread * const TH_XThread1; +void XThread1_ctor(void); + +extern QXThread * const TH_XThread2; +void XThread2_ctor(void); + +extern QXSemaphore TH_sema; +extern QXMutex TH_mutex; + +#endif // QXK_H_ + +#endif // DPP_H_ diff --git a/examples/threadx/arm-cm/dpp_ek-tm4c123gxl/dpp.qm b/examples/threadx/arm-cm/dpp_ek-tm4c123gxl/dpp.qm index 79ff1da8..ac9f2bc9 100644 --- a/examples/threadx/arm-cm/dpp_ek-tm4c123gxl/dpp.qm +++ b/examples/threadx/arm-cm/dpp_ek-tm4c123gxl/dpp.qm @@ -1,131 +1,210 @@ - + Dining Philosopher Problem example - - - + + + + + { + EAT_SIG = Q_USER_SIG, // published by Table to let a Philo eat + DONE_SIG, // published by Philo when done eating + PAUSE_SIG, // published by BSP to pause the application + SERVE_SIG, // published by BSP to serve re-start serving forks + TEST_SIG, // published by BSP to test the application + MAX_PUB_SIG, // the last published signal + + TIMEOUT_SIG, // posted by time event to Philo + HUNGRY_SIG, // posted by hungry Philo to Table + MAX_SIG // the last signal +}; + + + + QS_SIG_DICTIONARY(EAT_SIG, (void *)0); +QS_SIG_DICTIONARY(DONE_SIG, (void *)0); +QS_SIG_DICTIONARY(PAUSE_SIG, (void *)0); +QS_SIG_DICTIONARY(SERVE_SIG, (void *)0); +QS_SIG_DICTIONARY(TEST_SIG, (void *)0); + +QS_SIG_DICTIONARY(TIMEOUT_SIG, (void *)0); +QS_SIG_DICTIONARY(HUNGRY_SIG, (void *)0); + + + + ((uint8_t)5U) + + - - + + + + + + + if (me != (TableEvt *)0) { + // don't call QEvt_ctor() because the initialization of all + // QEvt attributes is already done in QF_QF_newX_() + me->philoId = id; +} +return me; + + + + = { + &Philo_inst[0].super, + &Philo_inst[1].super, + &Philo_inst[2].super, + &Philo_inst[3].super, + &Philo_inst[4].super +}; + + + + + + Philo * const me = &Philo_inst[id]; +QActive_ctor(&me->super, Q_STATE_CAST(&Philo_initial)); +QTimeEvt_ctorX(&me->timeEvt, &me->super, TIMEOUT_SIG, 0U), +me->id = (uint8_t)id; + + + + = &Table_inst.super; + + + + Table * const me = &Table_inst; +QActive_ctor(&me->super, Q_STATE_CAST(&Table_initial)); +for (uint8_t n = 0U; n < N_PHILO; ++n) { + me->fork[n] = FREE; + me->isHungry[n] = false; +} + + The Philo AO and the N_PHILO instances + + + + - + - static uint8_t registered = (uint8_t)0; /* starts off with 0, per C-standard */ -(void)par; /* unused parameter */ -if (registered == (uint8_t)0) { - registered = (uint8_t)1; + Q_UNUSED_PAR(par); - QS_OBJ_DICTIONARY(&l_philo[0].timeEvt); - QS_OBJ_DICTIONARY(&l_philo[1].timeEvt); - QS_OBJ_DICTIONARY(&l_philo[2].timeEvt); - QS_OBJ_DICTIONARY(&l_philo[3].timeEvt); - QS_OBJ_DICTIONARY(&l_philo[4].timeEvt); - - QS_FUN_DICTIONARY(&Philo_initial); - QS_FUN_DICTIONARY(&Philo_thinking); - QS_FUN_DICTIONARY(&Philo_hungry); - QS_FUN_DICTIONARY(&Philo_eating); -} -QS_SIG_DICTIONARY(HUNGRY_SIG, me); /* signal for each Philos */ -QS_SIG_DICTIONARY(TIMEOUT_SIG, me); /* signal for each Philos */ +QS_OBJ_ARR_DICTIONARY(&Philo_inst[me->id], me->id); +QS_OBJ_ARR_DICTIONARY(&Philo_inst[me->id].timeEvt, me->id); QActive_subscribe(&me->super, EAT_SIG); QActive_subscribe(&me->super, TEST_SIG); - + - QTimeEvt_armX(&me->timeEvt, THINK_TIME, 0U); - QTimeEvt_disarm(&me->timeEvt); + QTimeEvt_armX(&me->timeEvt, think_time(), 0U); + (void)QTimeEvt_disarm(&me->timeEvt); - - + + - /* EAT or DONE must be for other Philos than this one */ -Q_ASSERT_ID(10, Q_EVT_CAST(TableEvt)->philoNum != PHILO_ID(me)); - + // EAT or DONE must be for other Philos than this one +Q_ASSERT(Q_EVT_CAST(TableEvt)->philoId != me->id); + - + + + + + + + - + - TableEvt *pe = Q_NEW(TableEvt, HUNGRY_SIG); -pe->philoNum = PHILO_ID(me); -QACTIVE_POST(AO_Table, &pe->super, me); + #ifdef QEVT_DYN_CTOR +TableEvt const *pe = Q_NEW(TableEvt, HUNGRY_SIG, me->id); +#else +TableEvt *pe = Q_NEW(TableEvt, HUNGRY_SIG); +pe->philoId = me->id; +#endif +QACTIVE_POST(AO_Table, &pe->super, &me->super); - + - Q_EVT_CAST(TableEvt)->philoNum == PHILO_ID(me) - - + Q_EVT_CAST(TableEvt)->philoId == me->id + + - + - /* DONE must be for other Philos than this one */ -Q_ASSERT_ID(20, Q_EVT_CAST(TableEvt)->philoNum != PHILO_ID(me)); - + // DONE must be for other Philos than this one +Q_ASSERT(Q_EVT_CAST(TableEvt)->philoId != me->id); + - + - QTimeEvt_armX(&me->timeEvt, EAT_TIME, 0U); - TableEvt *pe = Q_NEW(TableEvt, DONE_SIG); -pe->philoNum = PHILO_ID(me); -QACTIVE_PUBLISH(&pe->super, &me->super); -QTimeEvt_disarm(&me->timeEvt); + QTimeEvt_armX(&me->timeEvt, eat_time(), 0U); + (void)QTimeEvt_disarm(&me->timeEvt); + +#ifdef QEVT_DYN_CTOR +TableEvt const *pe = Q_NEW(TableEvt, DONE_SIG, me->id); +#else +TableEvt *pe = Q_NEW(TableEvt, DONE_SIG); +pe->philoId = me->id; +#endif +QACTIVE_PUBLISH(&pe->super, &me->super); - - + + - /* EAT or DONE must be for other Philos than this one */ -Q_ASSERT_ID(30, Q_EVT_CAST(TableEvt)->philoNum != PHILO_ID(me)); - + // EAT or DONE must be for other Philos than this one +Q_ASSERT(Q_EVT_CAST(TableEvt)->philoId != me->id); + - + - + @@ -133,149 +212,171 @@ Q_ASSERT_ID(30, Q_EVT_CAST(TableEvt)->philoNum != PHILO_ID(me)); - + + + - + - - uint8_t n; -(void)par; /* unused parameter */ + + Q_UNUSED_PAR(par); -QS_SIG_DICTIONARY(DONE_SIG, (void *)0); /* global signals */ -QS_SIG_DICTIONARY(EAT_SIG, (void *)0); -QS_SIG_DICTIONARY(PAUSE_SIG, (void *)0); -QS_SIG_DICTIONARY(SERVE_SIG, (void *)0); -QS_SIG_DICTIONARY(TEST_SIG, (void *)0); - -QS_SIG_DICTIONARY(HUNGRY_SIG, me); /* signal just for Table */ +#ifdef Q_SPY +Table *Table_inst = me; +QS_OBJ_DICTIONARY(Table_inst); +#endif QActive_subscribe(&me->super, DONE_SIG); QActive_subscribe(&me->super, PAUSE_SIG); QActive_subscribe(&me->super, SERVE_SIG); QActive_subscribe(&me->super, TEST_SIG); -for (n = 0U; n < N_PHILO; ++n) { +for (uint8_t n = 0U; n < N_PHILO; ++n) { me->fork[n] = FREE; - me->isHungry[n] = 0U; - BSP_displayPhilStat(n, "thinking"); + me->isHungry[n] = false; + BSP_displayPhilStat(n, THINKING); } - + + + + + + + - Q_ERROR_ID(60); - - + Q_ERROR(); + + - uint8_t n; -for (n = 0U; n < N_PHILO; ++n) { /* give permissions to eat... */ - if ((me->isHungry[n] != 0U) - && (me->fork[LEFT(n)] == FREE) + // give permissions to eat... +for (uint8_t n = 0U; n < N_PHILO; ++n) { + if (me->isHungry[n] + && (me->fork[left(n)] == FREE) && (me->fork[n] == FREE)) { - TableEvt *te; - - me->fork[LEFT(n)] = USED; + me->fork[left(n)] = USED; me->fork[n] = USED; - te = Q_NEW(TableEvt, EAT_SIG); - te->philoNum = n; - QACTIVE_PUBLISH(&te->super, &me->super); - me->isHungry[n] = 0U; - BSP_displayPhilStat(n, "eating "); +#ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, EAT_SIG, n); +#else + TableEvt *pe = Q_NEW(TableEvt, EAT_SIG); + pe->philoId = n; +#endif + QACTIVE_PUBLISH(&pe->super, &me->super); + me->isHungry[n] = false; + BSP_displayPhilStat(n, EATING); } } - uint8_t n, m; + uint8_t n = Q_EVT_CAST(TableEvt)->philoId; -n = Q_EVT_CAST(TableEvt)->philoNum; -/* phil ID must be in range and he must be not hungry */ -Q_ASSERT_ID(40, (n < N_PHILO) && (me->isHungry[n] == 0U)); +// phil ID must be in range and he must be not hungry +Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); -BSP_displayPhilStat(n, "hungry "); -m = LEFT(n); +BSP_displayPhilStat(n, HUNGRY); +uint8_t m = left(n); (me->fork[m] == FREE) && (me->fork[n] == FREE) - TableEvt *pe; -me->fork[m] = USED; + me->fork[m] = USED; me->fork[n] = USED; -pe = Q_NEW(TableEvt, EAT_SIG); -pe->philoNum = n; +#ifdef QEVT_DYN_CTOR +TableEvt const *pe = Q_NEW(TableEvt, EAT_SIG, n); +#else +TableEvt *pe = Q_NEW(TableEvt, EAT_SIG); +pe->philoId = n; +#endif QACTIVE_PUBLISH(&pe->super, &me->super); -BSP_displayPhilStat(n, "eating "); - +BSP_displayPhilStat(n, EATING); + else - me->isHungry[n] = 1U; - - + me->isHungry[n] = true; + + - + - uint8_t n, m; -TableEvt *pe; + uint8_t n = Q_EVT_CAST(TableEvt)->philoId; -n = Q_EVT_CAST(TableEvt)->philoNum; -/* phil ID must be in range and he must be not hungry */ -Q_ASSERT_ID(50, (n < N_PHILO) && (me->isHungry[n] == 0U)); +// phil ID must be in range and he must be not hungry +Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); -BSP_displayPhilStat(n, "thinking"); -m = LEFT(n); -/* both forks of Phil[n] must be used */ -Q_ASSERT_ID(51, (me->fork[n] == USED) && (me->fork[m] == USED)); +BSP_displayPhilStat(n, THINKING); +uint8_t m = left(n); + +// both forks of Phil[n] must be used +Q_ASSERT((me->fork[n] == USED) && (me->fork[m] == USED)); me->fork[m] = FREE; me->fork[n] = FREE; -m = RIGHT(n); /* check the right neighbor */ +m = right(n); // check the right neighbor -if ((me->isHungry[m] != 0U) && (me->fork[m] == FREE)) { +if (me->isHungry[m] && (me->fork[m] == FREE)) { me->fork[n] = USED; me->fork[m] = USED; - me->isHungry[m] = 0U; - pe = Q_NEW(TableEvt, EAT_SIG); - pe->philoNum = m; + me->isHungry[m] = false; +#ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, EAT_SIG, m); +#else + TableEvt *pe = Q_NEW(TableEvt, EAT_SIG); + pe->philoId = m; +#endif QACTIVE_PUBLISH(&pe->super, &me->super); - BSP_displayPhilStat(m, "eating "); + BSP_displayPhilStat(m, EATING); } -m = LEFT(n); /* check the left neighbor */ -n = LEFT(m); /* left fork of the left neighbor */ -if ((me->isHungry[m] != 0U) && (me->fork[n] == FREE)) { +m = left(n); // check the left neighbor +n = left(m); // left fork of the left neighbor +if (me->isHungry[m] && (me->fork[n] == FREE)) { me->fork[m] = USED; me->fork[n] = USED; - me->isHungry[m] = 0U; - pe = Q_NEW(TableEvt, EAT_SIG); - pe->philoNum = m; + me->isHungry[m] = false; +#ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, EAT_SIG, m); +#else + TableEvt *pe = Q_NEW(TableEvt, EAT_SIG); + pe->philoId = m; +#endif QACTIVE_PUBLISH(&pe->super, &me->super); - BSP_displayPhilStat(m, "eating "); + BSP_displayPhilStat(m, EATING); } - + + + + Q_ERROR(); + + + + - - + + - + @@ -284,187 +385,141 @@ if ((me->isHungry[m] != 0U) && (me->fork[n] == FREE)) { BSP_displayPaused(1U); BSP_displayPaused(0U); - - + + - uint8_t n = Q_EVT_CAST(TableEvt)->philoNum; -/* philo ID must be in range and he must be not hungry */ -Q_ASSERT_ID(60, (n < N_PHILO) && (me->isHungry[n] == 0U)); -me->isHungry[n] = 1U; -BSP_displayPhilStat(n, "hungry "); - + uint8_t n = Q_EVT_CAST(TableEvt)->philoId; + +// philo ID must be in range and he must be not hungry +Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); + +me->isHungry[n] = true; +BSP_displayPhilStat(n, HUNGRY); + - uint8_t n, m; + uint8_t n = Q_EVT_CAST(TableEvt)->philoId; -n = Q_EVT_CAST(TableEvt)->philoNum; -/* phil ID must be in range and he must be not hungry */ -Q_ASSERT_ID(70, (n < N_PHILO) && (me->isHungry[n] == 0U)); +// phil ID must be in range and he must be not hungry +Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); -BSP_displayPhilStat(n, "thinking"); -m = LEFT(n); -/* both forks of Phil[n] must be used */ -Q_ASSERT_ID(71, (me->fork[n] == USED) && (me->fork[m] == USED)); +BSP_displayPhilStat(n, THINKING); +uint8_t m = left(n); + +// both forks of Phil[n] must be used +Q_ASSERT((me->fork[n] == USED) && (me->fork[m] == USED)); me->fork[m] = FREE; me->fork[n] = FREE; - + - + - + - + - - - /* opaque pointers to the Philo AOs */ - = { - &l_philo[0].super, - &l_philo[1].super, - &l_philo[2].super, - &l_philo[3].super, - &l_philo[4].super -}; - - - - /* opaque pointer to the Table AO */ - = &l_table.super; - - - - uint8_t n; -Philo *me; -for (n = 0U; n < N_PHILO; ++n) { - me = &l_philo[n]; - QActive_ctor(&me->super, Q_STATE_CAST(&Philo_initial)); - QTimeEvt_ctorX(&me->timeEvt, &me->super, TIMEOUT_SIG, 0U); -} - - - - uint8_t n; -Table *me = &l_table; - -QActive_ctor(&me->super, Q_STATE_CAST(&Table_initial)); - -for (n = 0U; n < N_PHILO; ++n) { - me->fork[n] = FREE; - me->isHungry[n] = 0U; -} - - #ifndef DPP_H -#define DPP_H + #ifndef DPP_H_ +#define DPP_H_ -enum DPPSignals { - EAT_SIG = Q_USER_SIG, /* published by Table to let a philosopher eat */ - DONE_SIG, /* published by Philosopher when done eating */ - PAUSE_SIG, /* published by BSP to pause serving forks */ - SERVE_SIG, /* published by BSP to serve re-start serving forks */ - TEST_SIG, /* published by BSP to test the application */ - MAX_PUB_SIG, /* the last published signal */ +$declare ${Shared} - HUNGRY_SIG, /* posted direclty to Table from hungry Philo */ - TIMEOUT_SIG, /* used by Philosophers for time events */ - MAX_SIG /* the last signal */ -}; +#ifdef QXK_H_ -$declare${Events::TableEvt} +extern QXThread * const TH_XThread1; +void XThread1_ctor(void); -/* number of philosophers */ -#define N_PHILO ((uint8_t)5) +extern QXThread * const TH_XThread2; +void XThread2_ctor(void); -$declare${AOs::Philo_ctor} -$declare${AOs::AO_Philo[N_PHILO]} +extern QXSemaphore TH_sema; +extern QXMutex TH_mutex; -$declare${AOs::Table_ctor} -$declare${AOs::AO_Table} +#endif // QXK_H_ -#ifdef QP_INC_QXK_H_ - void Test1_ctor(void); - extern QXThread * const XT_Test1; - void Test2_ctor(void); - extern QXThread * const XT_Test2; -#endif /* QP_INC_QXK_H_ */ - -#endif /* DPP_H */ - +#endif // DPP_H_ - #include "qpc.h" -#include "dpp.h" -#include "bsp.h" + #include "qpc.h" // QP/C real-time embedded framework +#include "dpp.h" // DPP Application interface +#include "bsp.h" // Board Support Package -Q_DEFINE_THIS_MODULE("philo") +$declare ${AOs::Philo} -/* Active object class -----------------------------------------------------*/ -$declare${AOs::Philo} +//---------------------------------------------------------------------------- +Q_DEFINE_THIS_FILE -/* Local objects -----------------------------------------------------------*/ -static Philo l_philo[N_PHILO]; /* storage for all Philos */ +// helper function to provide a randomized think time for Philos +static QTimeEvtCtr think_time(void); // prototype +static inline QTimeEvtCtr think_time(void) { + return (QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + + (BSP_TICKS_PER_SEC/2U)); +} -#define THINK_TIME \ - (QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + (BSP_TICKS_PER_SEC/2U)) -#define EAT_TIME \ - (QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + BSP_TICKS_PER_SEC) +// helper function to provide a randomized eat time for Philos +static QTimeEvtCtr eat_time(void); // prototype +static inline QTimeEvtCtr eat_time(void) { + return (QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + + BSP_TICKS_PER_SEC); +} +//---------------------------------------------------------------------------- -/* helper macro to provide the ID of Philo "me_" */ -#define PHILO_ID(me_) ((uint8_t)((me_) - l_philo)) - -/* Global objects ----------------------------------------------------------*/ -$define${AOs::AO_Philo[N_PHILO]} - -/* Philo definition --------------------------------------------------------*/ -$define${AOs::Philo_ctor} -$define${AOs::Philo} - +$define ${Shared::Philo_ctor} +$define ${Shared::AO_Philo[N_PHILO]} +$define ${AOs::Philo} - #include "qpc.h" -#include "dpp.h" -#include "bsp.h" + #include "qpc.h" // QP/C real-time embedded framework +#include "dpp.h" // DPP Application interface +#include "bsp.h" // Board Support Package -Q_DEFINE_THIS_MODULE("table") +$declare ${AOs::Table} -/* Active object class -----------------------------------------------------*/ -$declare${AOs::Table} +//---------------------------------------------------------------------------- +Q_DEFINE_THIS_FILE -#define RIGHT(n_) ((uint8_t)(((n_) + (N_PHILO - 1U)) % N_PHILO)) -#define LEFT(n_) ((uint8_t)(((n_) + 1U) % N_PHILO)) -#define FREE ((uint8_t)0) -#define USED ((uint8_t)1) +// helper function to provide the RIGHT neighbor of a Philo[n] +static inline uint8_t right(uint8_t const n) { + return (uint8_t)((n + (N_PHILO - 1U)) % N_PHILO); +} -/* Local objects -----------------------------------------------------------*/ -static Table l_table; /* the single instance of the Table active object */ +// helper function to provide the LEFT neighbor of a Philo[n] +static inline uint8_t left(uint8_t const n) { + return (uint8_t)((n + 1U) % N_PHILO); +} -/* Global-scope objects ----------------------------------------------------*/ -$define${AOs::AO_Table} +#define FREE ((uint8_t)0U) +#define USED ((uint8_t)1U) -/*..........................................................................*/ -$define${AOs::Table_ctor} -$define${AOs::Table} - +#define THINKING "thinking" +#define HUNGRY "hungry " +#define EATING "eating " + +//---------------------------------------------------------------------------- + +$define ${Shared::Table_ctor} +$define ${Shared::AO_Table} +$define ${AOs::Table} diff --git a/examples/threadx/arm-cm/dpp_ek-tm4c123gxl/ek-tm4c123gxl.jpg b/examples/threadx/arm-cm/dpp_ek-tm4c123gxl/ek-tm4c123gxl.jpg new file mode 100644 index 00000000..5ed6188c Binary files /dev/null and b/examples/threadx/arm-cm/dpp_ek-tm4c123gxl/ek-tm4c123gxl.jpg differ diff --git a/examples/threadx/arm-cm/dpp_ek-tm4c123gxl/iar/dpp.ewd b/examples/threadx/arm-cm/dpp_ek-tm4c123gxl/iar/dpp.ewd index 1587ed94..69698eab 100644 --- a/examples/threadx/arm-cm/dpp_ek-tm4c123gxl/iar/dpp.ewd +++ b/examples/threadx/arm-cm/dpp_ek-tm4c123gxl/iar/dpp.ewd @@ -11,7 +11,7 @@ C-SPY 2 - 28 + 32 1 1 - - + + + + + @@ -486,7 +498,7 @@ IJET_ID 2 - 8 + 9 1 1 + + + + + + + + + + + + + @@ -916,7 +980,7 @@ LMIFTDI_ID 2 - 2 + 3 1 1 + + + + + + + NULINK_ID + 2 + + 0 + 1 + 1 + + + @@ -974,7 +1072,7 @@ STLINK_ID 2 - 4 + 8 1 1 + + + + @@ -1185,7 +1300,7 @@ XDS100_ID 2 - 6 + 9 1 1 + + + + @@ -1362,6 +1493,18 @@ $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin 0 + + $TOOLKIT_DIR$\plugins\rtos\FreeRtos\FreeRtosArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin2.ENU.ewplugin + 0 + $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin 0 @@ -1371,11 +1514,15 @@ 0 - $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9.ewplugin 0 - $TOOLKIT_DIR$\plugins\rtos\TI-RTOS\tirtosplugin.ewplugin + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9BE.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin 0 @@ -1391,11 +1538,11 @@ 0 - $EW_DIR$\common\plugins\CodeCoverage\CodeCoverage.ENU.ewplugin - 1 + $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + 0 - $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + $EW_DIR$\common\plugins\TargetAccessServer\TargetAccessServer.ENU.ewplugin 0 @@ -1414,7 +1561,7 @@ C-SPY 2 - 28 + 32 1 0 - - + + + + + @@ -1889,7 +2048,7 @@ IJET_ID 2 - 8 + 9 1 0 + + + + + + + + + + + + + @@ -2319,7 +2530,7 @@ LMIFTDI_ID 2 - 2 + 3 1 0 + + + + + + + NULINK_ID + 2 + + 0 + 1 + 0 + + + @@ -2377,7 +2622,7 @@ STLINK_ID 2 - 4 + 8 1 0 + + + + @@ -2588,7 +2850,7 @@ XDS100_ID 2 - 6 + 9 1 0 + + + + @@ -2765,6 +3043,18 @@ $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin 0 + + $TOOLKIT_DIR$\plugins\rtos\FreeRtos\FreeRtosArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin2.ENU.ewplugin + 0 + $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin 0 @@ -2774,11 +3064,15 @@ 0 - $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9.ewplugin 0 - $TOOLKIT_DIR$\plugins\rtos\TI-RTOS\tirtosplugin.ewplugin + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9BE.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin 0 @@ -2794,11 +3088,11 @@ 0 - $EW_DIR$\common\plugins\CodeCoverage\CodeCoverage.ENU.ewplugin - 1 + $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + 0 - $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + $EW_DIR$\common\plugins\TargetAccessServer\TargetAccessServer.ENU.ewplugin 0 @@ -2817,7 +3111,7 @@ C-SPY 2 - 28 + 32 1 1 - - + + + + + @@ -3292,7 +3598,7 @@ IJET_ID 2 - 8 + 9 1 1 + + + + + + + + + + + + + @@ -3722,7 +4080,7 @@ LMIFTDI_ID 2 - 2 + 3 1 1 + + + + + + + NULINK_ID + 2 + + 0 + 1 + 1 + + + @@ -3780,7 +4172,7 @@ STLINK_ID 2 - 4 + 8 1 1 + + + + @@ -3991,7 +4400,7 @@ XDS100_ID 2 - 6 + 9 1 1 + + + + @@ -4168,6 +4593,18 @@ $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin 0 + + $TOOLKIT_DIR$\plugins\rtos\FreeRtos\FreeRtosArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin2.ENU.ewplugin + 0 + $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin 0 @@ -4177,11 +4614,15 @@ 0 - $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9.ewplugin 0 - $TOOLKIT_DIR$\plugins\rtos\TI-RTOS\tirtosplugin.ewplugin + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9BE.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin 0 @@ -4197,11 +4638,11 @@ 0 - $EW_DIR$\common\plugins\CodeCoverage\CodeCoverage.ENU.ewplugin - 1 + $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + 0 - $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + $EW_DIR$\common\plugins\TargetAccessServer\TargetAccessServer.ENU.ewplugin 0 diff --git a/examples/threadx/arm-cm/dpp_ek-tm4c123gxl/iar/dpp.ewp b/examples/threadx/arm-cm/dpp_ek-tm4c123gxl/iar/dpp.ewp index 8915a6d9..78db9d37 100644 --- a/examples/threadx/arm-cm/dpp_ek-tm4c123gxl/iar/dpp.ewp +++ b/examples/threadx/arm-cm/dpp_ek-tm4c123gxl/iar/dpp.ewp @@ -11,12 +11,12 @@ General 3 - 33 + 35 1 1 + + + @@ -672,7 +684,7 @@ ILINK 0 - 25 + 27 1 1 + + + + @@ -1063,12 +1091,12 @@ General 3 - 33 + 35 1 0 + + + @@ -1724,7 +1764,7 @@ ILINK 0 - 25 + 27 1 0 + + + + @@ -2115,12 +2171,12 @@ General 3 - 33 + 35 1 1 + + + @@ -2776,7 +2844,7 @@ ILINK 0 - 25 + 27 1 1 + + + + @@ -3177,9 +3261,6 @@ $PROJ_DIR$\..\philo.c - - $PROJ_DIR$\..\..\..\..\..\include\qstamp.c - $PROJ_DIR$\..\table.c @@ -3271,6 +3352,9 @@ $PROJ_DIR$\..\..\..\..\..\src\qs\qs_rx.c + + $PROJ_DIR$\..\..\..\..\..\src\qs\qstamp.c + ThreadX diff --git a/examples/threadx/arm-cm/dpp_ek-tm4c123gxl/iar/dpp.icf b/examples/threadx/arm-cm/dpp_ek-tm4c123gxl/iar/dpp.icf index 0fdfc4b3..ee7abef3 100644 --- a/examples/threadx/arm-cm/dpp_ek-tm4c123gxl/iar/dpp.icf +++ b/examples/threadx/arm-cm/dpp_ek-tm4c123gxl/iar/dpp.icf @@ -9,7 +9,7 @@ define symbol __ICFEDIT_region_ROM_end__ = 0x0003FFFF; define symbol __ICFEDIT_region_RAM_start__ = 0x20000000; define symbol __ICFEDIT_region_RAM_end__ = 0x20007FFF; /*-Sizes-*/ -define symbol __ICFEDIT_size_cstack__ = 2048; +define symbol __ICFEDIT_size_cstack__ = 1024; define symbol __ICFEDIT_size_heap__ = 0; /**** End of ICF editor section. ###ICF###*/ @@ -25,5 +25,5 @@ do not initialize { section .noinit }; place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec }; place in ROM_region { readonly }; -place at start of RAM_region {block CSTACK }; +place at start of RAM_region {block CSTACK }; /* <== Quantum Leaps */ place in RAM_region { readwrite, block HEAP }; \ No newline at end of file diff --git a/examples/threadx/arm-cm/dpp_ek-tm4c123gxl/main.c b/examples/threadx/arm-cm/dpp_ek-tm4c123gxl/main.c index 83ce7825..539523c4 100644 --- a/examples/threadx/arm-cm/dpp_ek-tm4c123gxl/main.c +++ b/examples/threadx/arm-cm/dpp_ek-tm4c123gxl/main.c @@ -1,95 +1,88 @@ -/***************************************************************************** -* Last updated for: @ref qpc_7_0_0 -* Last updated on 2021-12-05 -* -* Q u a n t u m L e a P s -* ------------------------ -* Modern Embedded Software -* -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* -* -*****************************************************************************/ -#include "qpc.h" -#include "dpp.h" -#include "bsp.h" +//============================================================================ +// QP example for ThreadX +// Last updated for: @ref qpc_7_3_0 +// Last updated on 2023-08-22 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// This program is open source software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Alternatively, this program may be distributed and modified under the +// terms of Quantum Leaps commercial licenses, which expressly supersede +// the GNU General Public License and are specifically designed for +// licensees interested in retaining the proprietary status of their code. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Contact information: +// +// +//============================================================================ +#include "qpc.h" // QP/C real-time embedded framework +#include "dpp.h" // DPP Application interface +#include "bsp.h" // Board Support Package -Q_DEFINE_THIS_FILE +//Q_DEFINE_THIS_FILE -/* Local-scope objects -----------------------------------------------------*/ -static QEvt const *l_tableQueueSto[N_PHILO]; -static QEvt const *l_philoQueueSto[N_PHILO][N_PHILO]; -static QSubscrList l_subscrSto[MAX_PUB_SIG]; - -static union SmallEvents { - void *e0; /* minimum event size */ - uint8_t e1[sizeof(TableEvt)]; - /* ... other event types to go into this pool */ -} l_smlPoolSto[2*N_PHILO + 10]; /* storage for the small event pool */ - -static ULONG l_philoStk[N_PHILO][256]; /* stacks for the Philosophers */ -static ULONG l_tableStk[256]; /* stack for the Table */ - -/*..........................................................................*/ +//............................................................................ int main() { - Philo_ctor(); /* instantiate all Philosopher active objects */ - Table_ctor(); /* instantiate the Table active object */ tx_kernel_enter(); - return 0; /* tx_kernel_enter() does not return */ + return 0; // tx_kernel_enter() does not return } -/*..........................................................................*/ +//............................................................................ void tx_application_define(void *first_unused_memory) { - uint8_t n; + Q_UNUSED_PAR(first_unused_memory); - (void)first_unused_memory; /* unused parameter */ + QF_init(); // initialize the framework + BSP_init(); // initialize the Board Support Package - BSP_init(); /* initialize the Board Support Package */ - QF_init(); /* initialize the framework and the underlying RT kernel */ + static QSubscrList l_subscrSto[MAX_PUB_SIG]; + QActive_psInit(l_subscrSto, Q_DIM(l_subscrSto)); // init publish-subscribe - QF_psInit(l_subscrSto, Q_DIM(l_subscrSto)); /* init publish-subscribe */ + // initialize event pools... + static QF_MPOOL_EL(TableEvt) smlPoolSto[2*N_PHILO]; + QF_poolInit(smlPoolSto, sizeof(smlPoolSto), sizeof(smlPoolSto[0])); - /* initialize event pools... */ - QF_poolInit(l_smlPoolSto, sizeof(l_smlPoolSto), sizeof(l_smlPoolSto[0])); + // start the active objects/threads... - QS_OBJ_DICTIONARY(l_smlPoolSto); - QS_OBJ_DICTIONARY(AO_Table); - QS_OBJ_DICTIONARY(AO_Philo[0]); - QS_OBJ_DICTIONARY(AO_Philo[1]); - QS_OBJ_DICTIONARY(AO_Philo[2]); - QS_OBJ_DICTIONARY(AO_Philo[3]); - QS_OBJ_DICTIONARY(AO_Philo[4]); - - for (n = 0; n < N_PHILO; ++n) { /* start the active objects... */ + static QEvt const *philoQueueSto[N_PHILO][10]; + static ULONG philoStk[N_PHILO][200]; // stacks for the Philosophers + for (uint8_t n = 0U; n < N_PHILO; ++n) { + Philo_ctor(n); // instantiate the Philo AO QActive_setAttr(AO_Philo[n], THREAD_NAME_ATTR, "Philo"); - QACTIVE_START(AO_Philo[n], (uint8_t)(n + 1), - l_philoQueueSto[n], Q_DIM(l_philoQueueSto[n]), - l_philoStk[n], sizeof(l_philoStk[n]), (QEvt *)0); + QACTIVE_START(AO_Philo[n], + + // NOTE: set the preemption-threshold of all Philos to + // the same level, so that they cannot preempt each other. + Q_PRIO(n + 1U, N_PHILO), // QF-prio/pre-thre. + + philoQueueSto[n], Q_DIM(philoQueueSto[n]), + philoStk[n], sizeof(philoStk[n]), + (void *)0); } + static QEvt const *tableQueueSto[N_PHILO]; + static ULONG tableStk[200]; // stack for the Table + Table_ctor(); // instantiate the Table AO QActive_setAttr(AO_Table, THREAD_NAME_ATTR, "Table"); - QACTIVE_START(AO_Table, (uint8_t)(N_PHILO + 1), - l_tableQueueSto, Q_DIM(l_tableQueueSto), - l_tableStk, sizeof(l_tableStk), (QEvt *)0); + QACTIVE_START(AO_Table, + N_PHILO + 1U, + tableQueueSto, Q_DIM(tableQueueSto), + tableStk, sizeof(tableStk), + (void *)0); (void)QF_run(); } diff --git a/examples/threadx/arm-cm/dpp_ek-tm4c123gxl/philo.c b/examples/threadx/arm-cm/dpp_ek-tm4c123gxl/philo.c index 919e39d6..eb6be531 100644 --- a/examples/threadx/arm-cm/dpp_ek-tm4c123gxl/philo.c +++ b/examples/threadx/arm-cm/dpp_ek-tm4c123gxl/philo.c @@ -1,160 +1,160 @@ -/*$file${.::philo.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* -* Model: dpp.qm -* File: ${.::philo.c} -* -* This code has been generated by QM 5.2.4 . -* DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. -* -* SPDX-License-Identifier: GPL-3.0-or-later -* -* This generated code is open source software: you can redistribute it under -* the terms of the GNU General Public License as published by the Free -* Software Foundation. -* -* This code is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -* more details. -* -* NOTE: -* Alternatively, this generated code may be distributed under the terms -* of Quantum Leaps commercial licenses, which expressly supersede the GNU -* General Public License and are specifically designed for licensees -* interested in retaining the proprietary status of their code. -* -* Contact information: -* -* -*/ -/*$endhead${.::philo.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -#include "qpc.h" -#include "dpp.h" -#include "bsp.h" +//$file${.::philo.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// +// Model: dpp.qm +// File: ${.::philo.c} +// +// This code has been generated by QM 5.3.0 . +// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. +// +// SPDX-License-Identifier: GPL-3.0-or-later +// +// This generated code is open source software: you can redistribute it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation. +// +// This code is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// NOTE: +// Alternatively, this generated code may be distributed under the terms +// of Quantum Leaps commercial licenses, which expressly supersede the GNU +// General Public License and are specifically designed for licensees +// interested in retaining the proprietary status of their code. +// +// Contact information: +// +// +// +//$endhead${.::philo.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +#include "qpc.h" // QP/C real-time embedded framework +#include "dpp.h" // DPP Application interface +#include "bsp.h" // Board Support Package -Q_DEFINE_THIS_MODULE("philo") +//$declare${AOs::Philo} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/* Active object class -----------------------------------------------------*/ -/*$declare${AOs::Philo} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${AOs::Philo} ............................................................*/ -typedef struct { -/* protected: */ +//${AOs::Philo} .............................................................. +typedef struct Philo { +// protected: QActive super; -/* private: */ +// private: QTimeEvt timeEvt; + uint8_t id; + +// public: } Philo; -/* protected: */ +extern Philo Philo_inst[N_PHILO]; + +// protected: static QState Philo_initial(Philo * const me, void const * const par); static QState Philo_thinking(Philo * const me, QEvt const * const e); static QState Philo_hungry(Philo * const me, QEvt const * const e); static QState Philo_eating(Philo * const me, QEvt const * const e); -/*$enddecl${AOs::Philo} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$enddecl${AOs::Philo} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -/* Local objects -----------------------------------------------------------*/ -static Philo l_philo[N_PHILO]; /* storage for all Philos */ +//---------------------------------------------------------------------------- +Q_DEFINE_THIS_FILE -#define THINK_TIME \ - (QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + (BSP_TICKS_PER_SEC/2U)) -#define EAT_TIME \ - (QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + BSP_TICKS_PER_SEC) - -/* helper macro to provide the ID of Philo "me_" */ -#define PHILO_ID(me_) ((uint8_t)((me_) - l_philo)) - -/* Global objects ----------------------------------------------------------*/ -/*$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* Check for the minimum required QP version */ -#if (QP_VERSION < 700U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) -#error qpc version 7.0.0 or higher required -#endif -/*$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ - -/*$define${AOs::AO_Philo[N_PHILO]} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${AOs::AO_Philo[N_PHILO]} ................................................*/ -QActive * const AO_Philo[N_PHILO] = { - &l_philo[0].super, - &l_philo[1].super, - &l_philo[2].super, - &l_philo[3].super, - &l_philo[4].super -}; -/*$enddef${AOs::AO_Philo[N_PHILO]} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ - -/* Philo definition --------------------------------------------------------*/ -/*$define${AOs::Philo_ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${AOs::Philo_ctor} .......................................................*/ -void Philo_ctor(void) { - uint8_t n; - Philo *me; - for (n = 0U; n < N_PHILO; ++n) { - me = &l_philo[n]; - QActive_ctor(&me->super, Q_STATE_CAST(&Philo_initial)); - QTimeEvt_ctorX(&me->timeEvt, &me->super, TIMEOUT_SIG, 0U); - } +// helper function to provide a randomized think time for Philos +static QTimeEvtCtr think_time(void); // prototype +static inline QTimeEvtCtr think_time(void) { + return (QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + + (BSP_TICKS_PER_SEC/2U)); } -/*$enddef${AOs::Philo_ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*$define${AOs::Philo} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/*${AOs::Philo} ............................................................*/ +// helper function to provide a randomized eat time for Philos +static QTimeEvtCtr eat_time(void); // prototype +static inline QTimeEvtCtr eat_time(void) { + return (QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + + BSP_TICKS_PER_SEC); +} +//---------------------------------------------------------------------------- -/*${AOs::Philo::SM} ........................................................*/ +//$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// Check for the minimum required QP version +#if (QP_VERSION < 730U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) +#error qpc version 7.3.0 or higher required +#endif +//$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +//$define${Shared::Philo_ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${Shared::Philo_ctor} ...................................................... +void Philo_ctor(uint_fast8_t const id) { + Philo * const me = &Philo_inst[id]; + QActive_ctor(&me->super, Q_STATE_CAST(&Philo_initial)); + QTimeEvt_ctorX(&me->timeEvt, &me->super, TIMEOUT_SIG, 0U), + me->id = (uint8_t)id; +} +//$enddef${Shared::Philo_ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +//$define${Shared::AO_Philo[N_PHILO]} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${Shared::AO_Philo[N_PHILO]} ............................................... +QActive * const AO_Philo[N_PHILO] = { + &Philo_inst[0].super, + &Philo_inst[1].super, + &Philo_inst[2].super, + &Philo_inst[3].super, + &Philo_inst[4].super +}; +//$enddef${Shared::AO_Philo[N_PHILO]} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +//$define${AOs::Philo} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${AOs::Philo} .............................................................. +Philo Philo_inst[N_PHILO]; + +//${AOs::Philo::SM} .......................................................... static QState Philo_initial(Philo * const me, void const * const par) { - /*${AOs::Philo::SM::initial} */ - static uint8_t registered = (uint8_t)0; /* starts off with 0, per C-standard */ - (void)par; /* unused parameter */ - if (registered == (uint8_t)0) { - registered = (uint8_t)1; + //${AOs::Philo::SM::initial} + Q_UNUSED_PAR(par); - QS_OBJ_DICTIONARY(&l_philo[0].timeEvt); - QS_OBJ_DICTIONARY(&l_philo[1].timeEvt); - QS_OBJ_DICTIONARY(&l_philo[2].timeEvt); - QS_OBJ_DICTIONARY(&l_philo[3].timeEvt); - QS_OBJ_DICTIONARY(&l_philo[4].timeEvt); - - QS_FUN_DICTIONARY(&Philo_initial); - QS_FUN_DICTIONARY(&Philo_thinking); - QS_FUN_DICTIONARY(&Philo_hungry); - QS_FUN_DICTIONARY(&Philo_eating); - } - QS_SIG_DICTIONARY(HUNGRY_SIG, me); /* signal for each Philos */ - QS_SIG_DICTIONARY(TIMEOUT_SIG, me); /* signal for each Philos */ + QS_OBJ_ARR_DICTIONARY(&Philo_inst[me->id], me->id); + QS_OBJ_ARR_DICTIONARY(&Philo_inst[me->id].timeEvt, me->id); QActive_subscribe(&me->super, EAT_SIG); QActive_subscribe(&me->super, TEST_SIG); + + QS_FUN_DICTIONARY(&Philo_thinking); + QS_FUN_DICTIONARY(&Philo_hungry); + QS_FUN_DICTIONARY(&Philo_eating); + return Q_TRAN(&Philo_thinking); } -/*${AOs::Philo::SM::thinking} ..............................................*/ +//${AOs::Philo::SM::thinking} ................................................ static QState Philo_thinking(Philo * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${AOs::Philo::SM::thinking} */ + //${AOs::Philo::SM::thinking} case Q_ENTRY_SIG: { - QTimeEvt_armX(&me->timeEvt, THINK_TIME, 0U); + QTimeEvt_armX(&me->timeEvt, think_time(), 0U); status_ = Q_HANDLED(); break; } - /*${AOs::Philo::SM::thinking} */ + //${AOs::Philo::SM::thinking} case Q_EXIT_SIG: { - QTimeEvt_disarm(&me->timeEvt); + (void)QTimeEvt_disarm(&me->timeEvt); status_ = Q_HANDLED(); break; } - /*${AOs::Philo::SM::thinking::TIMEOUT} */ + //${AOs::Philo::SM::thinking::TIMEOUT} case TIMEOUT_SIG: { status_ = Q_TRAN(&Philo_hungry); break; } - /*${AOs::Philo::SM::thinking::EAT, DONE} */ - case EAT_SIG: /* intentionally fall through */ + //${AOs::Philo::SM::thinking::EAT, DONE} + case EAT_SIG: // intentionally fall through case DONE_SIG: { - /* EAT or DONE must be for other Philos than this one */ - Q_ASSERT_ID(10, Q_EVT_CAST(TableEvt)->philoNum != PHILO_ID(me)); + // EAT or DONE must be for other Philos than this one + Q_ASSERT(Q_EVT_CAST(TableEvt)->philoId != me->id); + status_ = Q_HANDLED(); + break; + } + //${AOs::Philo::SM::thinking::TEST} + case TEST_SIG: { status_ = Q_HANDLED(); break; } @@ -166,22 +166,26 @@ static QState Philo_thinking(Philo * const me, QEvt const * const e) { return status_; } -/*${AOs::Philo::SM::hungry} ................................................*/ +//${AOs::Philo::SM::hungry} .................................................. static QState Philo_hungry(Philo * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${AOs::Philo::SM::hungry} */ + //${AOs::Philo::SM::hungry} case Q_ENTRY_SIG: { + #ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, HUNGRY_SIG, me->id); + #else TableEvt *pe = Q_NEW(TableEvt, HUNGRY_SIG); - pe->philoNum = PHILO_ID(me); - QACTIVE_POST(AO_Table, &pe->super, me); + pe->philoId = me->id; + #endif + QACTIVE_POST(AO_Table, &pe->super, &me->super); status_ = Q_HANDLED(); break; } - /*${AOs::Philo::SM::hungry::EAT} */ + //${AOs::Philo::SM::hungry::EAT} case EAT_SIG: { - /*${AOs::Philo::SM::hungry::EAT::[Q_EVT_CAST(TableEvt)->philoNum=~} */ - if (Q_EVT_CAST(TableEvt)->philoNum == PHILO_ID(me)) { + //${AOs::Philo::SM::hungry::EAT::[e->philoId==me->iid]} + if (Q_EVT_CAST(TableEvt)->philoId == me->id) { status_ = Q_TRAN(&Philo_eating); } else { @@ -189,10 +193,10 @@ static QState Philo_hungry(Philo * const me, QEvt const * const e) { } break; } - /*${AOs::Philo::SM::hungry::DONE} */ + //${AOs::Philo::SM::hungry::DONE} case DONE_SIG: { - /* DONE must be for other Philos than this one */ - Q_ASSERT_ID(20, Q_EVT_CAST(TableEvt)->philoNum != PHILO_ID(me)); + // DONE must be for other Philos than this one + Q_ASSERT(Q_EVT_CAST(TableEvt)->philoId != me->id); status_ = Q_HANDLED(); break; } @@ -204,35 +208,40 @@ static QState Philo_hungry(Philo * const me, QEvt const * const e) { return status_; } -/*${AOs::Philo::SM::eating} ................................................*/ +//${AOs::Philo::SM::eating} .................................................. static QState Philo_eating(Philo * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${AOs::Philo::SM::eating} */ + //${AOs::Philo::SM::eating} case Q_ENTRY_SIG: { - QTimeEvt_armX(&me->timeEvt, EAT_TIME, 0U); + QTimeEvt_armX(&me->timeEvt, eat_time(), 0U); status_ = Q_HANDLED(); break; } - /*${AOs::Philo::SM::eating} */ + //${AOs::Philo::SM::eating} case Q_EXIT_SIG: { + (void)QTimeEvt_disarm(&me->timeEvt); + + #ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, DONE_SIG, me->id); + #else TableEvt *pe = Q_NEW(TableEvt, DONE_SIG); - pe->philoNum = PHILO_ID(me); + pe->philoId = me->id; + #endif QACTIVE_PUBLISH(&pe->super, &me->super); - QTimeEvt_disarm(&me->timeEvt); status_ = Q_HANDLED(); break; } - /*${AOs::Philo::SM::eating::TIMEOUT} */ + //${AOs::Philo::SM::eating::TIMEOUT} case TIMEOUT_SIG: { status_ = Q_TRAN(&Philo_thinking); break; } - /*${AOs::Philo::SM::eating::EAT, DONE} */ - case EAT_SIG: /* intentionally fall through */ + //${AOs::Philo::SM::eating::EAT, DONE} + case EAT_SIG: // intentionally fall through case DONE_SIG: { - /* EAT or DONE must be for other Philos than this one */ - Q_ASSERT_ID(30, Q_EVT_CAST(TableEvt)->philoNum != PHILO_ID(me)); + // EAT or DONE must be for other Philos than this one + Q_ASSERT(Q_EVT_CAST(TableEvt)->philoId != me->id); status_ = Q_HANDLED(); break; } @@ -243,5 +252,4 @@ static QState Philo_eating(Philo * const me, QEvt const * const e) { } return status_; } -/*$enddef${AOs::Philo} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ - +//$enddef${AOs::Philo} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/examples/threadx/arm-cm/dpp_ek-tm4c123gxl/table.c b/examples/threadx/arm-cm/dpp_ek-tm4c123gxl/table.c index d655896e..c3ae02f0 100644 --- a/examples/threadx/arm-cm/dpp_ek-tm4c123gxl/table.c +++ b/examples/threadx/arm-cm/dpp_ek-tm4c123gxl/table.c @@ -1,124 +1,130 @@ -/*$file${.::table.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* -* Model: dpp.qm -* File: ${.::table.c} -* -* This code has been generated by QM 5.2.4 . -* DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. -* -* SPDX-License-Identifier: GPL-3.0-or-later -* -* This generated code is open source software: you can redistribute it under -* the terms of the GNU General Public License as published by the Free -* Software Foundation. -* -* This code is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -* more details. -* -* NOTE: -* Alternatively, this generated code may be distributed under the terms -* of Quantum Leaps commercial licenses, which expressly supersede the GNU -* General Public License and are specifically designed for licensees -* interested in retaining the proprietary status of their code. -* -* Contact information: -* -* -*/ -/*$endhead${.::table.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -#include "qpc.h" -#include "dpp.h" -#include "bsp.h" +//$file${.::table.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// +// Model: dpp.qm +// File: ${.::table.c} +// +// This code has been generated by QM 5.3.0 . +// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. +// +// SPDX-License-Identifier: GPL-3.0-or-later +// +// This generated code is open source software: you can redistribute it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation. +// +// This code is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// NOTE: +// Alternatively, this generated code may be distributed under the terms +// of Quantum Leaps commercial licenses, which expressly supersede the GNU +// General Public License and are specifically designed for licensees +// interested in retaining the proprietary status of their code. +// +// Contact information: +// +// +// +//$endhead${.::table.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +#include "qpc.h" // QP/C real-time embedded framework +#include "dpp.h" // DPP Application interface +#include "bsp.h" // Board Support Package -Q_DEFINE_THIS_MODULE("table") +//$declare${AOs::Table} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/* Active object class -----------------------------------------------------*/ -/*$declare${AOs::Table} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${AOs::Table} ............................................................*/ -typedef struct { -/* protected: */ +//${AOs::Table} .............................................................. +typedef struct Table { +// protected: QActive super; -/* private: */ +// private: uint8_t fork[N_PHILO]; - uint8_t isHungry[N_PHILO]; + bool isHungry[N_PHILO]; + +// public: } Table; -/* protected: */ +extern Table Table_inst; + +// protected: static QState Table_initial(Table * const me, void const * const par); static QState Table_active(Table * const me, QEvt const * const e); static QState Table_serving(Table * const me, QEvt const * const e); static QState Table_paused(Table * const me, QEvt const * const e); -/*$enddecl${AOs::Table} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$enddecl${AOs::Table} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -#define RIGHT(n_) ((uint8_t)(((n_) + (N_PHILO - 1U)) % N_PHILO)) -#define LEFT(n_) ((uint8_t)(((n_) + 1U) % N_PHILO)) -#define FREE ((uint8_t)0) -#define USED ((uint8_t)1) +//---------------------------------------------------------------------------- +Q_DEFINE_THIS_FILE -/* Local objects -----------------------------------------------------------*/ -static Table l_table; /* the single instance of the Table active object */ +// helper function to provide the RIGHT neighbor of a Philo[n] +static inline uint8_t right(uint8_t const n) { + return (uint8_t)((n + (N_PHILO - 1U)) % N_PHILO); +} -/* Global-scope objects ----------------------------------------------------*/ -/*$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* Check for the minimum required QP version */ -#if (QP_VERSION < 700U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) -#error qpc version 7.0.0 or higher required +// helper function to provide the LEFT neighbor of a Philo[n] +static inline uint8_t left(uint8_t const n) { + return (uint8_t)((n + 1U) % N_PHILO); +} + +#define FREE ((uint8_t)0U) +#define USED ((uint8_t)1U) + +#define THINKING "thinking" +#define HUNGRY "hungry " +#define EATING "eating " + +//---------------------------------------------------------------------------- + +//$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// Check for the minimum required QP version +#if (QP_VERSION < 730U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) +#error qpc version 7.3.0 or higher required #endif -/*$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -/*$define${AOs::AO_Table} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//$define${Shared::Table_ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/*${AOs::AO_Table} .........................................................*/ -QActive * const AO_Table = &l_table.super; -/*$enddef${AOs::AO_Table} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ - -/*..........................................................................*/ -/*$define${AOs::Table_ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${AOs::Table_ctor} .......................................................*/ +//${Shared::Table_ctor} ...................................................... void Table_ctor(void) { - uint8_t n; - Table *me = &l_table; - + Table * const me = &Table_inst; QActive_ctor(&me->super, Q_STATE_CAST(&Table_initial)); - - for (n = 0U; n < N_PHILO; ++n) { + for (uint8_t n = 0U; n < N_PHILO; ++n) { me->fork[n] = FREE; - me->isHungry[n] = 0U; + me->isHungry[n] = false; } } -/*$enddef${AOs::Table_ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*$define${AOs::Table} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//$enddef${Shared::Table_ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +//$define${Shared::AO_Table} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/*${AOs::Table} ............................................................*/ +//${Shared::AO_Table} ........................................................ +QActive * const AO_Table = &Table_inst.super; +//$enddef${Shared::AO_Table} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +//$define${AOs::Table} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/*${AOs::Table::SM} ........................................................*/ +//${AOs::Table} .............................................................. +Table Table_inst; + +//${AOs::Table::SM} .......................................................... static QState Table_initial(Table * const me, void const * const par) { - /*${AOs::Table::SM::initial} */ - uint8_t n; - (void)par; /* unused parameter */ + //${AOs::Table::SM::initial} + Q_UNUSED_PAR(par); - QS_SIG_DICTIONARY(DONE_SIG, (void *)0); /* global signals */ - QS_SIG_DICTIONARY(EAT_SIG, (void *)0); - QS_SIG_DICTIONARY(PAUSE_SIG, (void *)0); - QS_SIG_DICTIONARY(SERVE_SIG, (void *)0); - QS_SIG_DICTIONARY(TEST_SIG, (void *)0); - - QS_SIG_DICTIONARY(HUNGRY_SIG, me); /* signal just for Table */ + #ifdef Q_SPY + Table *Table_inst = me; + QS_OBJ_DICTIONARY(Table_inst); + #endif QActive_subscribe(&me->super, DONE_SIG); QActive_subscribe(&me->super, PAUSE_SIG); QActive_subscribe(&me->super, SERVE_SIG); QActive_subscribe(&me->super, TEST_SIG); - for (n = 0U; n < N_PHILO; ++n) { + for (uint8_t n = 0U; n < N_PHILO; ++n) { me->fork[n] = FREE; - me->isHungry[n] = 0U; - BSP_displayPhilStat(n, "thinking"); + me->isHungry[n] = false; + BSP_displayPhilStat(n, THINKING); } QS_FUN_DICTIONARY(&Table_active); @@ -128,13 +134,18 @@ static QState Table_initial(Table * const me, void const * const par) { return Q_TRAN(&Table_serving); } -/*${AOs::Table::SM::active} ................................................*/ +//${AOs::Table::SM::active} .................................................. static QState Table_active(Table * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${AOs::Table::SM::active::EAT} */ + //${AOs::Table::SM::active::TEST} + case TEST_SIG: { + status_ = Q_HANDLED(); + break; + } + //${AOs::Table::SM::active::EAT} case EAT_SIG: { - Q_ERROR_ID(60); + Q_ERROR(); status_ = Q_HANDLED(); break; } @@ -146,102 +157,119 @@ static QState Table_active(Table * const me, QEvt const * const e) { return status_; } -/*${AOs::Table::SM::active::serving} .......................................*/ +//${AOs::Table::SM::active::serving} ......................................... static QState Table_serving(Table * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${AOs::Table::SM::active::serving} */ + //${AOs::Table::SM::active::serving} case Q_ENTRY_SIG: { - uint8_t n; - for (n = 0U; n < N_PHILO; ++n) { /* give permissions to eat... */ - if ((me->isHungry[n] != 0U) - && (me->fork[LEFT(n)] == FREE) + // give permissions to eat... + for (uint8_t n = 0U; n < N_PHILO; ++n) { + if (me->isHungry[n] + && (me->fork[left(n)] == FREE) && (me->fork[n] == FREE)) { - TableEvt *te; - - me->fork[LEFT(n)] = USED; + me->fork[left(n)] = USED; me->fork[n] = USED; - te = Q_NEW(TableEvt, EAT_SIG); - te->philoNum = n; - QACTIVE_PUBLISH(&te->super, &me->super); - me->isHungry[n] = 0U; - BSP_displayPhilStat(n, "eating "); + #ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, EAT_SIG, n); + #else + TableEvt *pe = Q_NEW(TableEvt, EAT_SIG); + pe->philoId = n; + #endif + QACTIVE_PUBLISH(&pe->super, &me->super); + me->isHungry[n] = false; + BSP_displayPhilStat(n, EATING); } } status_ = Q_HANDLED(); break; } - /*${AOs::Table::SM::active::serving::HUNGRY} */ + //${AOs::Table::SM::active::serving::HUNGRY} case HUNGRY_SIG: { - uint8_t n, m; + uint8_t n = Q_EVT_CAST(TableEvt)->philoId; - n = Q_EVT_CAST(TableEvt)->philoNum; - /* phil ID must be in range and he must be not hungry */ - Q_ASSERT_ID(40, (n < N_PHILO) && (me->isHungry[n] == 0U)); + // phil ID must be in range and he must be not hungry + Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); - BSP_displayPhilStat(n, "hungry "); - m = LEFT(n); - /*${AOs::Table::SM::active::serving::HUNGRY::[bothfree]} */ + BSP_displayPhilStat(n, HUNGRY); + uint8_t m = left(n); + //${AOs::Table::SM::active::serving::HUNGRY::[bothfree]} if ((me->fork[m] == FREE) && (me->fork[n] == FREE)) { - TableEvt *pe; me->fork[m] = USED; me->fork[n] = USED; - pe = Q_NEW(TableEvt, EAT_SIG); - pe->philoNum = n; + #ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, EAT_SIG, n); + #else + TableEvt *pe = Q_NEW(TableEvt, EAT_SIG); + pe->philoId = n; + #endif QACTIVE_PUBLISH(&pe->super, &me->super); - BSP_displayPhilStat(n, "eating "); + BSP_displayPhilStat(n, EATING); status_ = Q_HANDLED(); } - /*${AOs::Table::SM::active::serving::HUNGRY::[else]} */ + //${AOs::Table::SM::active::serving::HUNGRY::[else]} else { - me->isHungry[n] = 1U; + me->isHungry[n] = true; status_ = Q_HANDLED(); } break; } - /*${AOs::Table::SM::active::serving::DONE} */ + //${AOs::Table::SM::active::serving::DONE} case DONE_SIG: { - uint8_t n, m; - TableEvt *pe; + uint8_t n = Q_EVT_CAST(TableEvt)->philoId; - n = Q_EVT_CAST(TableEvt)->philoNum; - /* phil ID must be in range and he must be not hungry */ - Q_ASSERT_ID(50, (n < N_PHILO) && (me->isHungry[n] == 0U)); + // phil ID must be in range and he must be not hungry + Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); - BSP_displayPhilStat(n, "thinking"); - m = LEFT(n); - /* both forks of Phil[n] must be used */ - Q_ASSERT_ID(51, (me->fork[n] == USED) && (me->fork[m] == USED)); + BSP_displayPhilStat(n, THINKING); + uint8_t m = left(n); + + // both forks of Phil[n] must be used + Q_ASSERT((me->fork[n] == USED) && (me->fork[m] == USED)); me->fork[m] = FREE; me->fork[n] = FREE; - m = RIGHT(n); /* check the right neighbor */ + m = right(n); // check the right neighbor - if ((me->isHungry[m] != 0U) && (me->fork[m] == FREE)) { + if (me->isHungry[m] && (me->fork[m] == FREE)) { me->fork[n] = USED; me->fork[m] = USED; - me->isHungry[m] = 0U; - pe = Q_NEW(TableEvt, EAT_SIG); - pe->philoNum = m; + me->isHungry[m] = false; + #ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, EAT_SIG, m); + #else + TableEvt *pe = Q_NEW(TableEvt, EAT_SIG); + pe->philoId = m; + #endif QACTIVE_PUBLISH(&pe->super, &me->super); - BSP_displayPhilStat(m, "eating "); + BSP_displayPhilStat(m, EATING); } - m = LEFT(n); /* check the left neighbor */ - n = LEFT(m); /* left fork of the left neighbor */ - if ((me->isHungry[m] != 0U) && (me->fork[n] == FREE)) { + m = left(n); // check the left neighbor + n = left(m); // left fork of the left neighbor + if (me->isHungry[m] && (me->fork[n] == FREE)) { me->fork[m] = USED; me->fork[n] = USED; - me->isHungry[m] = 0U; - pe = Q_NEW(TableEvt, EAT_SIG); - pe->philoNum = m; + me->isHungry[m] = false; + #ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, EAT_SIG, m); + #else + TableEvt *pe = Q_NEW(TableEvt, EAT_SIG); + pe->philoId = m; + #endif QACTIVE_PUBLISH(&pe->super, &me->super); - BSP_displayPhilStat(m, "eating "); + BSP_displayPhilStat(m, EATING); } status_ = Q_HANDLED(); break; } - /*${AOs::Table::SM::active::serving::PAUSE} */ + //${AOs::Table::SM::active::serving::EAT} + case EAT_SIG: { + Q_ERROR(); + status_ = Q_HANDLED(); + break; + } + //${AOs::Table::SM::active::serving::PAUSE} case PAUSE_SIG: { status_ = Q_TRAN(&Table_paused); break; @@ -254,49 +282,51 @@ static QState Table_serving(Table * const me, QEvt const * const e) { return status_; } -/*${AOs::Table::SM::active::paused} ........................................*/ +//${AOs::Table::SM::active::paused} .......................................... static QState Table_paused(Table * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${AOs::Table::SM::active::paused} */ + //${AOs::Table::SM::active::paused} case Q_ENTRY_SIG: { BSP_displayPaused(1U); status_ = Q_HANDLED(); break; } - /*${AOs::Table::SM::active::paused} */ + //${AOs::Table::SM::active::paused} case Q_EXIT_SIG: { BSP_displayPaused(0U); status_ = Q_HANDLED(); break; } - /*${AOs::Table::SM::active::paused::SERVE} */ + //${AOs::Table::SM::active::paused::SERVE} case SERVE_SIG: { status_ = Q_TRAN(&Table_serving); break; } - /*${AOs::Table::SM::active::paused::HUNGRY} */ + //${AOs::Table::SM::active::paused::HUNGRY} case HUNGRY_SIG: { - uint8_t n = Q_EVT_CAST(TableEvt)->philoNum; - /* philo ID must be in range and he must be not hungry */ - Q_ASSERT_ID(60, (n < N_PHILO) && (me->isHungry[n] == 0U)); - me->isHungry[n] = 1U; - BSP_displayPhilStat(n, "hungry "); + uint8_t n = Q_EVT_CAST(TableEvt)->philoId; + + // philo ID must be in range and he must be not hungry + Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); + + me->isHungry[n] = true; + BSP_displayPhilStat(n, HUNGRY); status_ = Q_HANDLED(); break; } - /*${AOs::Table::SM::active::paused::DONE} */ + //${AOs::Table::SM::active::paused::DONE} case DONE_SIG: { - uint8_t n, m; + uint8_t n = Q_EVT_CAST(TableEvt)->philoId; - n = Q_EVT_CAST(TableEvt)->philoNum; - /* phil ID must be in range and he must be not hungry */ - Q_ASSERT_ID(70, (n < N_PHILO) && (me->isHungry[n] == 0U)); + // phil ID must be in range and he must be not hungry + Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); - BSP_displayPhilStat(n, "thinking"); - m = LEFT(n); - /* both forks of Phil[n] must be used */ - Q_ASSERT_ID(71, (me->fork[n] == USED) && (me->fork[m] == USED)); + BSP_displayPhilStat(n, THINKING); + uint8_t m = left(n); + + // both forks of Phil[n] must be used + Q_ASSERT((me->fork[n] == USED) && (me->fork[m] == USED)); me->fork[m] = FREE; me->fork[n] = FREE; @@ -310,5 +340,4 @@ static QState Table_paused(Table * const me, QEvt const * const e) { } return status_; } -/*$enddef${AOs::Table} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ - +//$enddef${AOs::Table} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/examples/threadx/arm-cm/dpp_stm32f429-discovery/bsp.c b/examples/threadx/arm-cm/dpp_stm32f429-discovery/bsp.c index 15a218e2..69c192c0 100644 --- a/examples/threadx/arm-cm/dpp_stm32f429-discovery/bsp.c +++ b/examples/threadx/arm-cm/dpp_stm32f429-discovery/bsp.c @@ -1,50 +1,48 @@ -/***************************************************************************** -* Product: "DPP example, STM32F429 Discovery board, ThreadX kernel -* Last updated for: @ref qpc_7_0_0 -* Last updated on 2021-12-03 -* -* Q u a n t u m L e a P s -* ------------------------ -* Modern Embedded Software -* -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* -* -*****************************************************************************/ -#include "qpc.h" -#include "dpp.h" -#include "bsp.h" +//============================================================================ +// DPP example, STM32F429 Discovery board, ThreadX kernel +// Last updated for version 7.3.0 +// Last updated on 2023-08-30 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +//============================================================================ +#include "qpc.h" // QP/C real-time embedded framework +#include "dpp.h" // DPP Application interface +#include "bsp.h" // Board Support Package -#include "stm32f4xx.h" /* CMSIS-compliant header file for the MCU used */ +#include "stm32f4xx.h" // CMSIS-compliant header file for the MCU used #include "stm32f4xx_exti.h" #include "stm32f4xx_gpio.h" #include "stm32f4xx_rcc.h" #include "stm32f4xx_usart.h" -/* add other drivers if necessary... */ +// add other drivers if necessary... Q_DEFINE_THIS_FILE -/* Local-scope defines -----------------------------------------------------*/ +// Local-scope defines ----------------------------------------------------- #define LED_GPIO_PORT GPIOD #define LED_GPIO_CLK RCC_AHB1Periph_GPIOD @@ -57,49 +55,143 @@ Q_DEFINE_THIS_FILE #define BTN_GPIO_CLK RCC_AHB1Periph_GPIOA #define BTN_B1 GPIO_Pin_0 -static uint32_t l_rnd; /* random seed */ -static TX_TIMER l_tick_timer; /* ThreadX timer to call QTIMEEVT_TICK_X() */ +static uint32_t l_rndSeed; +static TX_TIMER l_tick_timer; // ThreadX timer to call QTIMEEVT_TICK_X() #ifdef Q_SPY + + // QSpy source IDs + static QSpyId const l_clock_tick = { QS_AP_ID }; + + // ThreadX "idle" thread for QS output, see NOTE1 + static TX_THREAD idle_thread; + static ULONG idle_thread_stack[100]; + QSTimeCtr QS_tickTime_; QSTimeCtr QS_tickPeriod_; - enum AppRecords { /* application-specific trace records */ + enum AppRecords { // application-specific trace records PHILO_STAT = QS_USER, - COMMAND_STAT + PAUSED_STAT, }; - /* QSpy source IDs */ - static QSpyId const l_clock_tick = { QS_AP_ID }; #endif -/* ISRs used in the application ==========================================*/ +static TX_TIMER l_tick_timer; // ThreadX timer to call QTIMEEVT_TICK_X() +static VOID timer_expiration(ULONG id); +static VOID timer_expiration(ULONG id) { + QTIMEEVT_TICK_X(id, &l_clock_tick); // QF clock tick processing #ifdef Q_SPY -/* -* ISR for receiving bytes from the QSPY Back-End -* NOTE: This ISR is "QF-unaware" meaning that it does not interact with -* the QF/QK and is not disabled. Such ISRs don't need to call QK_ISR_ENTRY/ -* QK_ISR_EXIT and they cannot post or publish events. -*/ -//TBD... + uint32_t volatile tmp = SysTick->CTRL; // clear SysTick_CTRL_COUNTFLAG + QS_tickTime_ += QS_tickPeriod_; // account for the clock rollover #endif +} -/* BSP functions ===========================================================*/ +//============================================================================ +// Error handler + +Q_NORETURN Q_onError(char const * const module, int_t const id) { + // NOTE: this implementation of the error handler is intended only + // for debugging and MUST be changed for deployment of the application + // (assuming that you ship your production code with assertions enabled). + Q_UNUSED_PAR(module); + Q_UNUSED_PAR(id); + QS_ASSERTION(module, id, 10000U); // report assertion to QS + +#ifndef NDEBUG + // turn LED on + LED_GPIO_PORT->BSRRL = LED4_PIN; + // for debugging, hang on in an endless loop... + for (;;) { + } +#else + NVIC_SystemReset(); + for (;;) { // explicitly "no-return" + } +#endif +} +//............................................................................ +void assert_failed(char const * const module, int_t const id); // prototype +void assert_failed(char const * const module, int_t const id) { + Q_onError(module, id); +} + +// ISRs and ThreadX IRS callbacks used in the application ==================== + +//............................................................................ +#ifdef Q_SPY + +//............................................................................ +static void idle_thread_fun(ULONG thread_input); // prototype +static void idle_thread_fun(ULONG thread_input) { // see NOTE1 + for (;;) { + QF_CRIT_STAT + + QF_CRIT_ENTRY(); + // turn the LED6 on an off to visualize the QS activity + LED_GPIO_PORT->BSRRL = LED6_PIN; // turn LED on + __NOP(); // wait a little to actually see the LED glow + __NOP(); + __NOP(); + __NOP(); + LED_GPIO_PORT->BSRRH = LED6_PIN; // turn LED off + + QS_rxParse(); // parse all the received bytes + QF_CRIT_EXIT(); + + if ((USART2->SR & 0x80U) != 0U) { // is TXE empty? + QF_CRIT_ENTRY(); + uint16_t b = QS_getByte(); + QF_CRIT_EXIT(); + + if (b != QS_EOD) { // not End-Of-Data? + USART2->DR = b; // put into the DR register + } + } + + // no blocking in this "idle" thread; see NOTE1 + } +} + +//............................................................................ +// ISR for receiving bytes from the QSPY Back-End +// NOTE: This ISR is "kernel-unaware" meaning that it does not interact with +// the or QP and is not disabled. Such ISRs don't cannot call any +// ThreadX or QP APIs. +// +//TBD... + +#endif // Q_SPY + +// BSP functions =========================================================== void BSP_init(void) { - GPIO_InitTypeDef GPIO_struct; + // Configure the MPU to prevent NULL-pointer dereferencing ... + MPU->RBAR = 0x0U // base address (NULL) + | MPU_RBAR_VALID_Msk // valid region + | (MPU_RBAR_REGION_Msk & 7U); // region #7 + MPU->RASR = (7U << MPU_RASR_SIZE_Pos) // 2^(7+1) region + | (0x0U << MPU_RASR_AP_Pos) // no-access region + | MPU_RASR_ENABLE_Msk; // region enable + MPU->CTRL = MPU_CTRL_PRIVDEFENA_Msk // enable background region + | MPU_CTRL_ENABLE_Msk; // enable the MPU + __ISB(); + __DSB(); - /* NOTE: SystemInit() already called from the startup code - * but SystemCoreClock needs to be updated - */ + // enable the MemManage_Handler for MPU exception + SCB->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk; + + // NOTE: SystemInit() has been already called from the startup code + // but SystemCoreClock needs to be updated SystemCoreClockUpdate(); - /* NOTE The VFP (Floating Point Unit) unit is configured by the RTOS */ + // NOTE: VFP (hardware Floating Point) unit is configured by ThreadX - /* Initialize thr port for the LEDs */ + // Initialize port for the LEDs RCC_AHB1PeriphClockCmd(LED_GPIO_CLK , ENABLE); - /* GPIO Configuration for the LEDs... */ + // GPIO Configuration for the LEDs... + GPIO_InitTypeDef GPIO_struct; GPIO_struct.GPIO_Mode = GPIO_Mode_OUT; GPIO_struct.GPIO_OType = GPIO_OType_PP; GPIO_struct.GPIO_PuPd = GPIO_PuPd_UP; @@ -107,24 +199,24 @@ void BSP_init(void) { GPIO_struct.GPIO_Pin = LED3_PIN; GPIO_Init(LED_GPIO_PORT, &GPIO_struct); - LED_GPIO_PORT->BSRRH = LED3_PIN; /* turn LED off */ + LED_GPIO_PORT->BSRRH = LED3_PIN; // turn LED off GPIO_struct.GPIO_Pin = LED4_PIN; GPIO_Init(LED_GPIO_PORT, &GPIO_struct); - LED_GPIO_PORT->BSRRH = LED4_PIN; /* turn LED off */ + LED_GPIO_PORT->BSRRH = LED4_PIN; // turn LED off GPIO_struct.GPIO_Pin = LED5_PIN; GPIO_Init(LED_GPIO_PORT, &GPIO_struct); - LED_GPIO_PORT->BSRRH = LED5_PIN; /* turn LED off */ + LED_GPIO_PORT->BSRRH = LED5_PIN; // turn LED off GPIO_struct.GPIO_Pin = LED6_PIN; GPIO_Init(LED_GPIO_PORT, &GPIO_struct); - LED_GPIO_PORT->BSRRH = LED6_PIN; /* turn LED off */ + LED_GPIO_PORT->BSRRH = LED6_PIN; // turn LED off - /* Initialize thr port for Button */ + // Initialize thr port for Button RCC_AHB1PeriphClockCmd(BTN_GPIO_CLK , ENABLE); - /* GPIO Configuration for the Button... */ + // GPIO Configuration for the Button... GPIO_struct.GPIO_Pin = BTN_B1; GPIO_struct.GPIO_Mode = GPIO_Mode_IN; GPIO_struct.GPIO_OType = GPIO_OType_PP; @@ -132,187 +224,158 @@ void BSP_init(void) { GPIO_struct.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(BTN_GPIO_PORT, &GPIO_struct); - /* seed the random number generator */ + // seed the random number generator BSP_randomSeed(1234U); - if (QS_INIT((void *)0) == 0U) { /* initialize the QS software tracing */ + // initialize the QS software tracing... + if (QS_INIT((void *)0) == 0U) { Q_ERROR(); } - QS_USR_DICTIONARY(PHILO_STAT); - QS_USR_DICTIONARY(COMMAND_STAT); - /* setup the QS filters... */ - QS_GLB_FILTER(QS_ALL_RECORDS); - QS_GLB_FILTER(-QS_QF_TICK); + // dictionaries... + QS_OBJ_DICTIONARY(&l_clock_tick); + QS_USR_DICTIONARY(PHILO_STAT); + QS_USR_DICTIONARY(PAUSED_STAT); + + QS_ONLY(produce_sig_dict()); + + // setup the QS filters... + QS_GLB_FILTER(QS_ALL_RECORDS); // all records + QS_GLB_FILTER(-QS_QF_TICK); // exclude the clock tick } -/*..........................................................................*/ +//............................................................................ void BSP_displayPhilStat(uint8_t n, char const *stat) { - /* exercise the FPU with some floating point computations */ - float volatile x; - x = 3.1415926F; - x = x + 2.7182818F; + Q_UNUSED_PAR(n); if (stat[0] == 'h') { - LED_GPIO_PORT->BSRRL = LED3_PIN; /* turn LED on */ + LED_GPIO_PORT->BSRRL = LED3_PIN; // turn LED on } else { - LED_GPIO_PORT->BSRRH = LED3_PIN; /* turn LED off */ + LED_GPIO_PORT->BSRRH = LED3_PIN; // turn LED off } if (stat[0] == 'e') { - LED_GPIO_PORT->BSRRL = LED5_PIN; /* turn LED on */ + LED_GPIO_PORT->BSRRL = LED5_PIN; // turn LED on } else { - LED_GPIO_PORT->BSRRH = LED5_PIN; /* turn LED on */ + LED_GPIO_PORT->BSRRH = LED5_PIN; // turn LED on } - (void)n; /* unused parameter (in all but Spy build configuration) */ - QS_BEGIN_ID(PHILO_STAT, AO_Philo[n]->prio) /* app-specific record */ - QS_U8(1, n); /* Philosopher number */ - QS_STR(stat); /* Philosopher status */ + // app-specific trace record... + QS_BEGIN_ID(PHILO_STAT, AO_Table->prio) + QS_U8(1, n); // Philosopher number + QS_STR(stat); // Philosopher status QS_END() } -/*..........................................................................*/ -void BSP_displayPaused(uint8_t paused) { +//............................................................................ +void BSP_displayPaused(uint8_t const paused) { if (paused) { - LED_GPIO_PORT->BSRRL = LED4_PIN; /* turn LED on */ + LED_GPIO_PORT->BSRRL = LED4_PIN; // turn LED on } else { - LED_GPIO_PORT->BSRRH = LED4_PIN; /* turn LED on */ + LED_GPIO_PORT->BSRRH = LED4_PIN; // turn LED off } -} -/*..........................................................................*/ -uint32_t BSP_random(void) { /* a very cheap pseudo-random-number generator */ - /* "Super-Duper" Linear Congruential Generator (LCG) - * LCG(2^32, 3*7*11*13*23, 0, seed) - */ - l_rnd = l_rnd * (3U*7U*11U*13U*23U); - return l_rnd >> 8; + // application-specific trace record + QS_BEGIN_ID(PAUSED_STAT, AO_Table->prio) + QS_U8(1, paused); // Paused status + QS_END() } -/*..........................................................................*/ -void BSP_randomSeed(uint32_t seed) { - l_rnd = seed; +//............................................................................ +void BSP_randomSeed(uint32_t const seed) { + l_rndSeed = seed; } -/*..........................................................................*/ +//............................................................................ +uint32_t BSP_random(void) { // a very cheap pseudo-random-number generator + // Some flating point code is to exercise the VFP... + float volatile x = 3.1415926F; + x = x + 2.7182818F; + + // NOTE: l_rndSeed is SHARED among the Philo AOs, but does not need + // to be protected because all Philos have the same ThreadX preemption + // threshold, so they cannot preempt each other. + uint32_t rnd = l_rndSeed * (3U*7U*11U*13U*23U); + l_rndSeed = rnd; // set for the next time + + return (rnd >> 8); +} +//............................................................................ +void BSP_ledOn(void) { + LED_GPIO_PORT->BSRRL = LED3_PIN; +} +//............................................................................ +void BSP_ledOff(void) { + LED_GPIO_PORT->BSRRH = LED3_PIN; +} +//............................................................................ void BSP_terminate(int16_t result) { (void)result; } +// QF callbacks ============================================================ -#ifdef Q_SPY - /* ThreadX "idle" thread for QS output, see NOTE1 */ - static TX_THREAD idle_thread; - static void idle_thread_fun(ULONG thread_input); - static ULONG idle_thread_stack[64]; -#endif - -/* QF callbacks ============================================================*/ -static VOID timer_expiration(ULONG id) { - QTIMEEVT_TICK_X(id, &l_clock_tick); /* perform the QF clock tick processing */ -} -/*..........................................................................*/ +//............................................................................ void QF_onStartup(void) { - /* - * NOTE: - * This application uses the ThreadX timer to periodically call - * the QTimeEvt_tick_(0) function. Here, only the clock tick rate of 0 - * is used, but other timers can be used to call QTimeEvt_tick_() for - * other clock tick rates, if needed. - * - * The choice of a ThreadX timer is not the only option. Applications - * might choose to call QTIMEEVT_TICK_X() directly from timer interrupts - * or from active object(s). - */ - Q_ALLEGE(tx_timer_create(&l_tick_timer, /* ThreadX timer object */ - (CHAR *)"QP-tick", /* name of the timer */ - &timer_expiration, /* expiration function */ - 0U, /* expiration function input (tick rate) */ - 1U, /* initial ticks */ - 1U, /* reschedule ticks */ - TX_AUTO_ACTIVATE) /* automatically activate timer */ - == TX_SUCCESS); + + // NOTE: + // This application uses the ThreadX timer to periodically call + // the QTimeEvt_tick_(0) function. Here, only the clock tick rate of 0 + // is used, but other timers can be used to call QTimeEvt_tick_() for + // other clock tick rates, if needed. + // + // The choice of a ThreadX timer is not the only option. Applications + // might choose to call QTIMEEVT_TICK_X() directly from timer interrupts + // or from active object(s). + // + UINT tx_err = tx_timer_create(&l_tick_timer, // ThreadX timer object + (CHAR *)"TICK0", // name of the timer + &timer_expiration, // expiration function + 0U, // expiration function input (tick rate) + 1U, // initial ticks + 1U, // reschedule ticks + TX_AUTO_ACTIVATE); + Q_ASSERT(tx_err == TX_SUCCESS); #ifdef Q_SPY //TBD: enable the UART ISR for receiving bytes... - /* start a ThreadX "idle" thread. See NOTE1... */ - Q_ALLEGE(tx_thread_create(&idle_thread, /* thread control block */ - (CHAR *)("idle"), /* thread name */ - &idle_thread_fun, /* thread function */ - 0LU, /* thread input (unsued) */ - idle_thread_stack, /* stack start */ - sizeof(idle_thread_stack), /* stack size in bytes */ - TX_MAX_PRIORITIES - 1U, /* ThreadX priority (LOWEST possible), NOTE1 */ - TX_MAX_PRIORITIES - 1U, /* preemption threshold disabled */ + // start a ThreadX "idle" thread. See NOTE1... + tx_err = tx_thread_create(&idle_thread, // thread control block + (CHAR *)("idle"), // thread name + &idle_thread_fun, // thread function + 0LU, // thread input (unsued) + idle_thread_stack, // stack start + sizeof(idle_thread_stack), // stack size in bytes + TX_MAX_PRIORITIES - 1U, // ThreadX priority (LOWEST possible), NOTE1 + TX_MAX_PRIORITIES - 1U, // preemption threshold disabled TX_NO_TIME_SLICE, - TX_AUTO_START) - == TX_SUCCESS); -#endif /* Q_SPY */ + TX_AUTO_START); + Q_ASSERT(tx_err == TX_SUCCESS); +#endif // Q_SPY } -/*..........................................................................*/ +//............................................................................ void QF_onCleanup(void) { } -/*..........................................................................*/ -Q_NORETURN Q_onAssert(char const * const module, int_t const loc) { - /* - * NOTE: add here your application-specific error handling - */ - (void)module; - (void)loc; - QS_ASSERTION(module, loc, 10000U); /* report assertion to QS */ - NVIC_SystemReset(); -} - -/* QS callbacks ============================================================*/ +// QS callbacks -------------------------------------------------------------- #ifdef Q_SPY -/*..........................................................................*/ -static void idle_thread_fun(ULONG thread_input) { /* see NOTE1 */ - for (;;) { - QS_rxParse(); /* parse all the received bytes */ - - /* turn the LED6 on an off to visualize the QS activity */ - LED_GPIO_PORT->BSRRL = LED6_PIN; /* turn LED on */ - __NOP(); /* wait a little to actually see the LED glow */ - __NOP(); - __NOP(); - __NOP(); - LED_GPIO_PORT->BSRRH = LED6_PIN; /* turn LED off */ - - if ((USART2->SR & 0x80U) != 0U) { /* is TXE empty? */ - uint16_t b; - QF_CRIT_STAT_TYPE intStat; - - QF_CRIT_ENTRY(intStat); - b = QS_getByte(); - QF_CRIT_EXIT(intStat); - - if (b != QS_EOD) { /* not End-Of-Data? */ - USART2->DR = (b & 0xFFU); /* put into the DR register */ - } - } - - /* no blocking in this "idle" thread; see NOTE1 */ - } -} - -/*..........................................................................*/ +//............................................................................ uint8_t QS_onStartup(void const *arg) { - static uint8_t qsBuf[2*1024]; /* buffer for Quantum Spy */ - GPIO_InitTypeDef GPIO_struct; - USART_InitTypeDef USART_struct; + Q_UNUSED_PAR(arg); - (void)arg; /* avoid the "unused parameter" compiler warning */ - QS_initBuf(qsBuf, sizeof(qsBuf)); + static uint8_t qsTxBuf[2*1024]; // buffer for QS-TX channel + QS_initBuf(qsTxBuf, sizeof(qsTxBuf)); - /* enable peripheral clock for USART2 */ + //TBD initialize the QS-RX channel... + + // enable peripheral clock for USART2 RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE); - /* GPIOA clock enable */ + // GPIOA clock enable RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); - /* GPIOA Configuration: USART2 TX on PA2 */ + // GPIOA Configuration: USART2 TX on PA2 + GPIO_InitTypeDef GPIO_struct; GPIO_struct.GPIO_Pin = GPIO_Pin_2; GPIO_struct.GPIO_Mode = GPIO_Mode_AF; GPIO_struct.GPIO_Speed = GPIO_Speed_50MHz; @@ -320,11 +383,12 @@ uint8_t QS_onStartup(void const *arg) { GPIO_struct.GPIO_PuPd = GPIO_PuPd_UP ; GPIO_Init(GPIOA, &GPIO_struct); - /* Connect USART2 pins to AF2 */ - GPIO_PinAFConfig(GPIOA, GPIO_PinSource2, GPIO_AF_USART2); /* TX = PA2 */ - GPIO_PinAFConfig(GPIOA, GPIO_PinSource3, GPIO_AF_USART2); /* RX = PA3 */ + // Connect USART2 pins to AF2 + GPIO_PinAFConfig(GPIOA, GPIO_PinSource2, GPIO_AF_USART2); // TX = PA2 + GPIO_PinAFConfig(GPIOA, GPIO_PinSource3, GPIO_AF_USART2); // RX = PA3 - USART_struct.USART_BaudRate = 115200; + USART_InitTypeDef USART_struct; + USART_struct.USART_BaudRate = 115200U; USART_struct.USART_WordLength = USART_WordLength_8b; USART_struct.USART_StopBits = USART_StopBits_1; USART_struct.USART_Parity = USART_Parity_No; @@ -334,75 +398,72 @@ uint8_t QS_onStartup(void const *arg) { USART_Cmd(USART2, ENABLE); // enable USART2 - /* configure UART interrupts (for the RX channel) */ + // configure UART interrupts (for the RX channel) //TBD... QS_tickPeriod_ = SystemCoreClock / BSP_TICKS_PER_SEC; - QS_tickTime_ = QS_tickPeriod_; /* to start the timestamp at zero */ + QS_tickTime_ = QS_tickPeriod_; // to start the timestamp at zero - return 1U; /* return success */ + return 1U; // return success } -/*..........................................................................*/ +//............................................................................ void QS_onCleanup(void) { } -/*..........................................................................*/ -QSTimeCtr QS_onGetTime(void) { /* NOTE: invoked with interrupts DISABLED */ - if ((SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk) == 0) { /* not set? */ +//............................................................................ +QSTimeCtr QS_onGetTime(void) { // NOTE: invoked with interrupts DISABLED + if ((SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk) == 0) { // not set? return QS_tickTime_ - (QSTimeCtr)SysTick->VAL; } - else { /* the rollover occured, but the SysTick_ISR did not run yet */ + else { // the rollover occured, but the SysTick_ISR did not run yet return QS_tickTime_ + QS_tickPeriod_ - (QSTimeCtr)SysTick->VAL; } } -/*..........................................................................*/ +//............................................................................ void QS_onFlush(void) { - uint16_t b; - QF_CRIT_STAT_TYPE intStat; + for (;;) { + QF_CRIT_STAT + QF_CRIT_ENTRY(); + uint16_t b = QS_getByte(); + QF_CRIT_EXIT(); - QF_CRIT_ENTRY(intStat); - while ((b = QS_getByte()) != QS_EOD) { /* while not End-Of-Data... */ - QF_CRIT_EXIT(intStat); - while ((USART2->SR & USART_FLAG_TXE) == 0) { /* while TXE not empty */ + if (b != QS_EOD) { // NOT end-of-data + // busy-wait as long as TXE not set + while ((USART2->SR & USART_FLAG_TXE) == 0U) { + } + // place the byte in the UART DR register + USART2->DR = b; + } + else { + break; // break out of the loop } - USART2->DR = (b & 0xFFU); /* put into the DR register */ - QF_CRIT_ENTRY(intStat); } - QF_CRIT_EXIT(intStat); } -/*..........................................................................*/ -/*! callback function to reset the target (to be implemented in the BSP) */ +//............................................................................ +//! callback function to reset the target (to be implemented in the BSP) void QS_onReset(void) { NVIC_SystemReset(); } -/*..........................................................................*/ -/*! callback function to execute a user command (to be implemented in BSP) */ +//............................................................................ void QS_onCommand(uint8_t cmdId, uint32_t param1, uint32_t param2, uint32_t param3) { - (void)cmdId; - (void)param1; - (void)param2; - (void)param3; - - QS_BEGIN_ID(COMMAND_STAT, 0U) /* app-specific record */ - QS_U8(2, cmdId); - QS_U32(8, param1); - QS_U32(8, param2); - QS_U32(8, param3); - QS_END() + Q_UNUSED_PAR(cmdId); + Q_UNUSED_PAR(param1); + Q_UNUSED_PAR(param2); + Q_UNUSED_PAR(param3); } -#endif /* Q_SPY */ -/*--------------------------------------------------------------------------*/ +#endif // Q_SPY +//---------------------------------------------------------------------------- -/***************************************************************************** -* NOTE1: -* ThreadX apparently does not have a concpet of an "idle" thread, but -* it can be emulated by a regular, but NON-BLOCKING ThreadX thread of -* the lowest priority. -* -* In the Q_SPY configuration, this "idle" thread is uded to perform -* the QS data output to the host. This is not the only choice available, and -* other applications might choose to peform the QS output some other way. -*/ +//============================================================================ +// NOTE1: +// ThreadX apparently does not have a concept of an "idle" thread, but +// it can be emulated by a regular, but NON-BLOCKING ThreadX thread of +// the lowest priority. +// +// In the Q_SPY configuration, this "idle" thread is used to perform +// the QS data output to the host. This is not the only choice available, and +// other applications might choose to perform the QS output some other way. +// diff --git a/examples/threadx/arm-cm/dpp_stm32f429-discovery/bsp.h b/examples/threadx/arm-cm/dpp_stm32f429-discovery/bsp.h index b699e5ba..d1ededad 100644 --- a/examples/threadx/arm-cm/dpp_stm32f429-discovery/bsp.h +++ b/examples/threadx/arm-cm/dpp_stm32f429-discovery/bsp.h @@ -1,38 +1,36 @@ -/***************************************************************************** -* Product: DPP example, ThreadX -* Last Updated for Version: 6.3.8 -* Date of the Last Update: 2019-01-30 -* -* Q u a n t u m L e a P s -* ------------------------ -* Modern Embedded Software -* -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* -* -*****************************************************************************/ -#ifndef BSP_H -#define BSP_H +//============================================================================ +// Product: DPP example, ThreadX +// Last updated for version 7.3.0 +// Last updated on 2023-08-30 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +//============================================================================ +#ifndef BSP_H_ +#define BSP_H_ #define BSP_TICKS_PER_SEC TX_TIMER_TICKS_PER_SECOND @@ -41,7 +39,11 @@ void BSP_displayPaused(uint8_t paused); void BSP_displayPhilStat(uint8_t n, char const *stat); void BSP_terminate(int16_t result); -void BSP_randomSeed(uint32_t seed); /* random seed */ -uint32_t BSP_random(void); /* pseudo-random generator */ +void BSP_randomSeed(uint32_t seed); // random seed +uint32_t BSP_random(void); // pseudo-random generator + +void BSP_ledOn(void); +void BSP_ledOff(void); + +#endif // BSP_H_ -#endif /* BSP_H */ diff --git a/examples/threadx/arm-cm/dpp_stm32f429-discovery/dpp.h b/examples/threadx/arm-cm/dpp_stm32f429-discovery/dpp.h index c45cc7c6..e6d1557a 100644 --- a/examples/threadx/arm-cm/dpp_stm32f429-discovery/dpp.h +++ b/examples/threadx/arm-cm/dpp_stm32f429-discovery/dpp.h @@ -1,94 +1,117 @@ -/*$file${.::dpp.h} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* -* Model: dpp.qm -* File: ${.::dpp.h} -* -* This code has been generated by QM 5.2.4 . -* DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. -* -* SPDX-License-Identifier: GPL-3.0-or-later -* -* This generated code is open source software: you can redistribute it under -* the terms of the GNU General Public License as published by the Free -* Software Foundation. -* -* This code is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -* more details. -* -* NOTE: -* Alternatively, this generated code may be distributed under the terms -* of Quantum Leaps commercial licenses, which expressly supersede the GNU -* General Public License and are specifically designed for licensees -* interested in retaining the proprietary status of their code. -* -* Contact information: -* -* -*/ -/*$endhead${.::dpp.h} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -#ifndef DPP_H -#define DPP_H +//$file${.::dpp.h} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// +// Model: dpp.qm +// File: ${.::dpp.h} +// +// This code has been generated by QM 5.3.0 . +// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. +// +// SPDX-License-Identifier: GPL-3.0-or-later +// +// This generated code is open source software: you can redistribute it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation. +// +// This code is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// NOTE: +// Alternatively, this generated code may be distributed under the terms +// of Quantum Leaps commercial licenses, which expressly supersede the GNU +// General Public License and are specifically designed for licensees +// interested in retaining the proprietary status of their code. +// +// Contact information: +// +// +// +//$endhead${.::dpp.h} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +#ifndef DPP_H_ +#define DPP_H_ -enum DPPSignals { - EAT_SIG = Q_USER_SIG, /* published by Table to let a philosopher eat */ - DONE_SIG, /* published by Philosopher when done eating */ - PAUSE_SIG, /* published by BSP to pause serving forks */ - SERVE_SIG, /* published by BSP to serve re-start serving forks */ - TEST_SIG, /* published by BSP to test the application */ - MAX_PUB_SIG, /* the last published signal */ +//$declare${Shared} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv - HUNGRY_SIG, /* posted direclty to Table from hungry Philo */ - TIMEOUT_SIG, /* used by Philosophers for time events */ - MAX_SIG /* the last signal */ +//${Shared::AppSignals} ...................................................... +enum AppSignals { + EAT_SIG = Q_USER_SIG, // published by Table to let a Philo eat + DONE_SIG, // published by Philo when done eating + PAUSE_SIG, // published by BSP to pause the application + SERVE_SIG, // published by BSP to serve re-start serving forks + TEST_SIG, // published by BSP to test the application + MAX_PUB_SIG, // the last published signal + + TIMEOUT_SIG, // posted by time event to Philo + HUNGRY_SIG, // posted by hungry Philo to Table + MAX_SIG // the last signal }; -/*$declare${Events::TableEvt} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//${Shared::produce_sig_dict} ................................................ +#ifdef Q_SPY +static inline void produce_sig_dict(void) { + QS_SIG_DICTIONARY(EAT_SIG, (void *)0); + QS_SIG_DICTIONARY(DONE_SIG, (void *)0); + QS_SIG_DICTIONARY(PAUSE_SIG, (void *)0); + QS_SIG_DICTIONARY(SERVE_SIG, (void *)0); + QS_SIG_DICTIONARY(TEST_SIG, (void *)0); -/*${Events::TableEvt} ......................................................*/ + QS_SIG_DICTIONARY(TIMEOUT_SIG, (void *)0); + QS_SIG_DICTIONARY(HUNGRY_SIG, (void *)0); +} +#endif // def Q_SPY + +//${Shared::N_PHILO} ......................................................... +#define N_PHILO ((uint8_t)5U) + +//${Shared::TableEvt} ........................................................ typedef struct { -/* protected: */ +// protected: QEvt super; -/* public: */ - uint8_t philoNum; +// public: + uint8_t philoId; } TableEvt; -/*$enddecl${Events::TableEvt} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/* number of philosophers */ -#define N_PHILO ((uint8_t)5) +// public: -/*$declare${AOs::Philo_ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +#ifdef QEVT_DYN_CTOR +static inline TableEvt * TableEvt_ctor(TableEvt * const me, + uint8_t id) +{ + if (me != (TableEvt *)0) { + // don't call QEvt_ctor() because the initialization of all + // QEvt attributes is already done in QF_QF_newX_() + me->philoId = id; + } + return me; +} +#endif // def QEVT_DYN_CTOR -/*${AOs::Philo_ctor} .......................................................*/ -void Philo_ctor(void); -/*$enddecl${AOs::Philo_ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*$declare${AOs::AO_Philo[N_PHILO]} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${AOs::AO_Philo[N_PHILO]} ................................................*/ -/* opaque pointers to the Philo AOs */ +//${Shared::AO_Philo[N_PHILO]} ............................................... extern QActive * const AO_Philo[N_PHILO]; -/*$enddecl${AOs::AO_Philo[N_PHILO]} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*$declare${AOs::Table_ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//${Shared::Philo_ctor} ...................................................... +void Philo_ctor(uint_fast8_t const id); -/*${AOs::Table_ctor} .......................................................*/ -void Table_ctor(void); -/*$enddecl${AOs::Table_ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*$declare${AOs::AO_Table} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${AOs::AO_Table} .........................................................*/ -/* opaque pointer to the Table AO */ +//${Shared::AO_Table} ........................................................ extern QActive * const AO_Table; -/*$enddecl${AOs::AO_Table} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -#ifdef QP_INC_QXK_H_ - void Test1_ctor(void); - extern QXThread * const XT_Test1; - void Test2_ctor(void); - extern QXThread * const XT_Test2; -#endif /* QP_INC_QXK_H_ */ +//${Shared::Table_ctor} ...................................................... +void Table_ctor(void); +//$enddecl${Shared} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -#endif /* DPP_H */ +#ifdef QXK_H_ +extern QXThread * const TH_XThread1; +void XThread1_ctor(void); + +extern QXThread * const TH_XThread2; +void XThread2_ctor(void); + +extern QXSemaphore TH_sema; +extern QXMutex TH_mutex; + +#endif // QXK_H_ + +#endif // DPP_H_ diff --git a/examples/threadx/arm-cm/dpp_stm32f429-discovery/dpp.qm b/examples/threadx/arm-cm/dpp_stm32f429-discovery/dpp.qm index 79ff1da8..ac9f2bc9 100644 --- a/examples/threadx/arm-cm/dpp_stm32f429-discovery/dpp.qm +++ b/examples/threadx/arm-cm/dpp_stm32f429-discovery/dpp.qm @@ -1,131 +1,210 @@ - + Dining Philosopher Problem example - - - + + + + + { + EAT_SIG = Q_USER_SIG, // published by Table to let a Philo eat + DONE_SIG, // published by Philo when done eating + PAUSE_SIG, // published by BSP to pause the application + SERVE_SIG, // published by BSP to serve re-start serving forks + TEST_SIG, // published by BSP to test the application + MAX_PUB_SIG, // the last published signal + + TIMEOUT_SIG, // posted by time event to Philo + HUNGRY_SIG, // posted by hungry Philo to Table + MAX_SIG // the last signal +}; + + + + QS_SIG_DICTIONARY(EAT_SIG, (void *)0); +QS_SIG_DICTIONARY(DONE_SIG, (void *)0); +QS_SIG_DICTIONARY(PAUSE_SIG, (void *)0); +QS_SIG_DICTIONARY(SERVE_SIG, (void *)0); +QS_SIG_DICTIONARY(TEST_SIG, (void *)0); + +QS_SIG_DICTIONARY(TIMEOUT_SIG, (void *)0); +QS_SIG_DICTIONARY(HUNGRY_SIG, (void *)0); + + + + ((uint8_t)5U) + + - - + + + + + + + if (me != (TableEvt *)0) { + // don't call QEvt_ctor() because the initialization of all + // QEvt attributes is already done in QF_QF_newX_() + me->philoId = id; +} +return me; + + + + = { + &Philo_inst[0].super, + &Philo_inst[1].super, + &Philo_inst[2].super, + &Philo_inst[3].super, + &Philo_inst[4].super +}; + + + + + + Philo * const me = &Philo_inst[id]; +QActive_ctor(&me->super, Q_STATE_CAST(&Philo_initial)); +QTimeEvt_ctorX(&me->timeEvt, &me->super, TIMEOUT_SIG, 0U), +me->id = (uint8_t)id; + + + + = &Table_inst.super; + + + + Table * const me = &Table_inst; +QActive_ctor(&me->super, Q_STATE_CAST(&Table_initial)); +for (uint8_t n = 0U; n < N_PHILO; ++n) { + me->fork[n] = FREE; + me->isHungry[n] = false; +} + + The Philo AO and the N_PHILO instances + + + + - + - static uint8_t registered = (uint8_t)0; /* starts off with 0, per C-standard */ -(void)par; /* unused parameter */ -if (registered == (uint8_t)0) { - registered = (uint8_t)1; + Q_UNUSED_PAR(par); - QS_OBJ_DICTIONARY(&l_philo[0].timeEvt); - QS_OBJ_DICTIONARY(&l_philo[1].timeEvt); - QS_OBJ_DICTIONARY(&l_philo[2].timeEvt); - QS_OBJ_DICTIONARY(&l_philo[3].timeEvt); - QS_OBJ_DICTIONARY(&l_philo[4].timeEvt); - - QS_FUN_DICTIONARY(&Philo_initial); - QS_FUN_DICTIONARY(&Philo_thinking); - QS_FUN_DICTIONARY(&Philo_hungry); - QS_FUN_DICTIONARY(&Philo_eating); -} -QS_SIG_DICTIONARY(HUNGRY_SIG, me); /* signal for each Philos */ -QS_SIG_DICTIONARY(TIMEOUT_SIG, me); /* signal for each Philos */ +QS_OBJ_ARR_DICTIONARY(&Philo_inst[me->id], me->id); +QS_OBJ_ARR_DICTIONARY(&Philo_inst[me->id].timeEvt, me->id); QActive_subscribe(&me->super, EAT_SIG); QActive_subscribe(&me->super, TEST_SIG); - + - QTimeEvt_armX(&me->timeEvt, THINK_TIME, 0U); - QTimeEvt_disarm(&me->timeEvt); + QTimeEvt_armX(&me->timeEvt, think_time(), 0U); + (void)QTimeEvt_disarm(&me->timeEvt); - - + + - /* EAT or DONE must be for other Philos than this one */ -Q_ASSERT_ID(10, Q_EVT_CAST(TableEvt)->philoNum != PHILO_ID(me)); - + // EAT or DONE must be for other Philos than this one +Q_ASSERT(Q_EVT_CAST(TableEvt)->philoId != me->id); + - + + + + + + + - + - TableEvt *pe = Q_NEW(TableEvt, HUNGRY_SIG); -pe->philoNum = PHILO_ID(me); -QACTIVE_POST(AO_Table, &pe->super, me); + #ifdef QEVT_DYN_CTOR +TableEvt const *pe = Q_NEW(TableEvt, HUNGRY_SIG, me->id); +#else +TableEvt *pe = Q_NEW(TableEvt, HUNGRY_SIG); +pe->philoId = me->id; +#endif +QACTIVE_POST(AO_Table, &pe->super, &me->super); - + - Q_EVT_CAST(TableEvt)->philoNum == PHILO_ID(me) - - + Q_EVT_CAST(TableEvt)->philoId == me->id + + - + - /* DONE must be for other Philos than this one */ -Q_ASSERT_ID(20, Q_EVT_CAST(TableEvt)->philoNum != PHILO_ID(me)); - + // DONE must be for other Philos than this one +Q_ASSERT(Q_EVT_CAST(TableEvt)->philoId != me->id); + - + - QTimeEvt_armX(&me->timeEvt, EAT_TIME, 0U); - TableEvt *pe = Q_NEW(TableEvt, DONE_SIG); -pe->philoNum = PHILO_ID(me); -QACTIVE_PUBLISH(&pe->super, &me->super); -QTimeEvt_disarm(&me->timeEvt); + QTimeEvt_armX(&me->timeEvt, eat_time(), 0U); + (void)QTimeEvt_disarm(&me->timeEvt); + +#ifdef QEVT_DYN_CTOR +TableEvt const *pe = Q_NEW(TableEvt, DONE_SIG, me->id); +#else +TableEvt *pe = Q_NEW(TableEvt, DONE_SIG); +pe->philoId = me->id; +#endif +QACTIVE_PUBLISH(&pe->super, &me->super); - - + + - /* EAT or DONE must be for other Philos than this one */ -Q_ASSERT_ID(30, Q_EVT_CAST(TableEvt)->philoNum != PHILO_ID(me)); - + // EAT or DONE must be for other Philos than this one +Q_ASSERT(Q_EVT_CAST(TableEvt)->philoId != me->id); + - + - + @@ -133,149 +212,171 @@ Q_ASSERT_ID(30, Q_EVT_CAST(TableEvt)->philoNum != PHILO_ID(me)); - + + + - + - - uint8_t n; -(void)par; /* unused parameter */ + + Q_UNUSED_PAR(par); -QS_SIG_DICTIONARY(DONE_SIG, (void *)0); /* global signals */ -QS_SIG_DICTIONARY(EAT_SIG, (void *)0); -QS_SIG_DICTIONARY(PAUSE_SIG, (void *)0); -QS_SIG_DICTIONARY(SERVE_SIG, (void *)0); -QS_SIG_DICTIONARY(TEST_SIG, (void *)0); - -QS_SIG_DICTIONARY(HUNGRY_SIG, me); /* signal just for Table */ +#ifdef Q_SPY +Table *Table_inst = me; +QS_OBJ_DICTIONARY(Table_inst); +#endif QActive_subscribe(&me->super, DONE_SIG); QActive_subscribe(&me->super, PAUSE_SIG); QActive_subscribe(&me->super, SERVE_SIG); QActive_subscribe(&me->super, TEST_SIG); -for (n = 0U; n < N_PHILO; ++n) { +for (uint8_t n = 0U; n < N_PHILO; ++n) { me->fork[n] = FREE; - me->isHungry[n] = 0U; - BSP_displayPhilStat(n, "thinking"); + me->isHungry[n] = false; + BSP_displayPhilStat(n, THINKING); } - + + + + + + + - Q_ERROR_ID(60); - - + Q_ERROR(); + + - uint8_t n; -for (n = 0U; n < N_PHILO; ++n) { /* give permissions to eat... */ - if ((me->isHungry[n] != 0U) - && (me->fork[LEFT(n)] == FREE) + // give permissions to eat... +for (uint8_t n = 0U; n < N_PHILO; ++n) { + if (me->isHungry[n] + && (me->fork[left(n)] == FREE) && (me->fork[n] == FREE)) { - TableEvt *te; - - me->fork[LEFT(n)] = USED; + me->fork[left(n)] = USED; me->fork[n] = USED; - te = Q_NEW(TableEvt, EAT_SIG); - te->philoNum = n; - QACTIVE_PUBLISH(&te->super, &me->super); - me->isHungry[n] = 0U; - BSP_displayPhilStat(n, "eating "); +#ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, EAT_SIG, n); +#else + TableEvt *pe = Q_NEW(TableEvt, EAT_SIG); + pe->philoId = n; +#endif + QACTIVE_PUBLISH(&pe->super, &me->super); + me->isHungry[n] = false; + BSP_displayPhilStat(n, EATING); } } - uint8_t n, m; + uint8_t n = Q_EVT_CAST(TableEvt)->philoId; -n = Q_EVT_CAST(TableEvt)->philoNum; -/* phil ID must be in range and he must be not hungry */ -Q_ASSERT_ID(40, (n < N_PHILO) && (me->isHungry[n] == 0U)); +// phil ID must be in range and he must be not hungry +Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); -BSP_displayPhilStat(n, "hungry "); -m = LEFT(n); +BSP_displayPhilStat(n, HUNGRY); +uint8_t m = left(n); (me->fork[m] == FREE) && (me->fork[n] == FREE) - TableEvt *pe; -me->fork[m] = USED; + me->fork[m] = USED; me->fork[n] = USED; -pe = Q_NEW(TableEvt, EAT_SIG); -pe->philoNum = n; +#ifdef QEVT_DYN_CTOR +TableEvt const *pe = Q_NEW(TableEvt, EAT_SIG, n); +#else +TableEvt *pe = Q_NEW(TableEvt, EAT_SIG); +pe->philoId = n; +#endif QACTIVE_PUBLISH(&pe->super, &me->super); -BSP_displayPhilStat(n, "eating "); - +BSP_displayPhilStat(n, EATING); + else - me->isHungry[n] = 1U; - - + me->isHungry[n] = true; + + - + - uint8_t n, m; -TableEvt *pe; + uint8_t n = Q_EVT_CAST(TableEvt)->philoId; -n = Q_EVT_CAST(TableEvt)->philoNum; -/* phil ID must be in range and he must be not hungry */ -Q_ASSERT_ID(50, (n < N_PHILO) && (me->isHungry[n] == 0U)); +// phil ID must be in range and he must be not hungry +Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); -BSP_displayPhilStat(n, "thinking"); -m = LEFT(n); -/* both forks of Phil[n] must be used */ -Q_ASSERT_ID(51, (me->fork[n] == USED) && (me->fork[m] == USED)); +BSP_displayPhilStat(n, THINKING); +uint8_t m = left(n); + +// both forks of Phil[n] must be used +Q_ASSERT((me->fork[n] == USED) && (me->fork[m] == USED)); me->fork[m] = FREE; me->fork[n] = FREE; -m = RIGHT(n); /* check the right neighbor */ +m = right(n); // check the right neighbor -if ((me->isHungry[m] != 0U) && (me->fork[m] == FREE)) { +if (me->isHungry[m] && (me->fork[m] == FREE)) { me->fork[n] = USED; me->fork[m] = USED; - me->isHungry[m] = 0U; - pe = Q_NEW(TableEvt, EAT_SIG); - pe->philoNum = m; + me->isHungry[m] = false; +#ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, EAT_SIG, m); +#else + TableEvt *pe = Q_NEW(TableEvt, EAT_SIG); + pe->philoId = m; +#endif QACTIVE_PUBLISH(&pe->super, &me->super); - BSP_displayPhilStat(m, "eating "); + BSP_displayPhilStat(m, EATING); } -m = LEFT(n); /* check the left neighbor */ -n = LEFT(m); /* left fork of the left neighbor */ -if ((me->isHungry[m] != 0U) && (me->fork[n] == FREE)) { +m = left(n); // check the left neighbor +n = left(m); // left fork of the left neighbor +if (me->isHungry[m] && (me->fork[n] == FREE)) { me->fork[m] = USED; me->fork[n] = USED; - me->isHungry[m] = 0U; - pe = Q_NEW(TableEvt, EAT_SIG); - pe->philoNum = m; + me->isHungry[m] = false; +#ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, EAT_SIG, m); +#else + TableEvt *pe = Q_NEW(TableEvt, EAT_SIG); + pe->philoId = m; +#endif QACTIVE_PUBLISH(&pe->super, &me->super); - BSP_displayPhilStat(m, "eating "); + BSP_displayPhilStat(m, EATING); } - + + + + Q_ERROR(); + + + + - - + + - + @@ -284,187 +385,141 @@ if ((me->isHungry[m] != 0U) && (me->fork[n] == FREE)) { BSP_displayPaused(1U); BSP_displayPaused(0U); - - + + - uint8_t n = Q_EVT_CAST(TableEvt)->philoNum; -/* philo ID must be in range and he must be not hungry */ -Q_ASSERT_ID(60, (n < N_PHILO) && (me->isHungry[n] == 0U)); -me->isHungry[n] = 1U; -BSP_displayPhilStat(n, "hungry "); - + uint8_t n = Q_EVT_CAST(TableEvt)->philoId; + +// philo ID must be in range and he must be not hungry +Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); + +me->isHungry[n] = true; +BSP_displayPhilStat(n, HUNGRY); + - uint8_t n, m; + uint8_t n = Q_EVT_CAST(TableEvt)->philoId; -n = Q_EVT_CAST(TableEvt)->philoNum; -/* phil ID must be in range and he must be not hungry */ -Q_ASSERT_ID(70, (n < N_PHILO) && (me->isHungry[n] == 0U)); +// phil ID must be in range and he must be not hungry +Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); -BSP_displayPhilStat(n, "thinking"); -m = LEFT(n); -/* both forks of Phil[n] must be used */ -Q_ASSERT_ID(71, (me->fork[n] == USED) && (me->fork[m] == USED)); +BSP_displayPhilStat(n, THINKING); +uint8_t m = left(n); + +// both forks of Phil[n] must be used +Q_ASSERT((me->fork[n] == USED) && (me->fork[m] == USED)); me->fork[m] = FREE; me->fork[n] = FREE; - + - + - + - + - - - /* opaque pointers to the Philo AOs */ - = { - &l_philo[0].super, - &l_philo[1].super, - &l_philo[2].super, - &l_philo[3].super, - &l_philo[4].super -}; - - - - /* opaque pointer to the Table AO */ - = &l_table.super; - - - - uint8_t n; -Philo *me; -for (n = 0U; n < N_PHILO; ++n) { - me = &l_philo[n]; - QActive_ctor(&me->super, Q_STATE_CAST(&Philo_initial)); - QTimeEvt_ctorX(&me->timeEvt, &me->super, TIMEOUT_SIG, 0U); -} - - - - uint8_t n; -Table *me = &l_table; - -QActive_ctor(&me->super, Q_STATE_CAST(&Table_initial)); - -for (n = 0U; n < N_PHILO; ++n) { - me->fork[n] = FREE; - me->isHungry[n] = 0U; -} - - #ifndef DPP_H -#define DPP_H + #ifndef DPP_H_ +#define DPP_H_ -enum DPPSignals { - EAT_SIG = Q_USER_SIG, /* published by Table to let a philosopher eat */ - DONE_SIG, /* published by Philosopher when done eating */ - PAUSE_SIG, /* published by BSP to pause serving forks */ - SERVE_SIG, /* published by BSP to serve re-start serving forks */ - TEST_SIG, /* published by BSP to test the application */ - MAX_PUB_SIG, /* the last published signal */ +$declare ${Shared} - HUNGRY_SIG, /* posted direclty to Table from hungry Philo */ - TIMEOUT_SIG, /* used by Philosophers for time events */ - MAX_SIG /* the last signal */ -}; +#ifdef QXK_H_ -$declare${Events::TableEvt} +extern QXThread * const TH_XThread1; +void XThread1_ctor(void); -/* number of philosophers */ -#define N_PHILO ((uint8_t)5) +extern QXThread * const TH_XThread2; +void XThread2_ctor(void); -$declare${AOs::Philo_ctor} -$declare${AOs::AO_Philo[N_PHILO]} +extern QXSemaphore TH_sema; +extern QXMutex TH_mutex; -$declare${AOs::Table_ctor} -$declare${AOs::AO_Table} +#endif // QXK_H_ -#ifdef QP_INC_QXK_H_ - void Test1_ctor(void); - extern QXThread * const XT_Test1; - void Test2_ctor(void); - extern QXThread * const XT_Test2; -#endif /* QP_INC_QXK_H_ */ - -#endif /* DPP_H */ - +#endif // DPP_H_ - #include "qpc.h" -#include "dpp.h" -#include "bsp.h" + #include "qpc.h" // QP/C real-time embedded framework +#include "dpp.h" // DPP Application interface +#include "bsp.h" // Board Support Package -Q_DEFINE_THIS_MODULE("philo") +$declare ${AOs::Philo} -/* Active object class -----------------------------------------------------*/ -$declare${AOs::Philo} +//---------------------------------------------------------------------------- +Q_DEFINE_THIS_FILE -/* Local objects -----------------------------------------------------------*/ -static Philo l_philo[N_PHILO]; /* storage for all Philos */ +// helper function to provide a randomized think time for Philos +static QTimeEvtCtr think_time(void); // prototype +static inline QTimeEvtCtr think_time(void) { + return (QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + + (BSP_TICKS_PER_SEC/2U)); +} -#define THINK_TIME \ - (QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + (BSP_TICKS_PER_SEC/2U)) -#define EAT_TIME \ - (QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + BSP_TICKS_PER_SEC) +// helper function to provide a randomized eat time for Philos +static QTimeEvtCtr eat_time(void); // prototype +static inline QTimeEvtCtr eat_time(void) { + return (QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + + BSP_TICKS_PER_SEC); +} +//---------------------------------------------------------------------------- -/* helper macro to provide the ID of Philo "me_" */ -#define PHILO_ID(me_) ((uint8_t)((me_) - l_philo)) - -/* Global objects ----------------------------------------------------------*/ -$define${AOs::AO_Philo[N_PHILO]} - -/* Philo definition --------------------------------------------------------*/ -$define${AOs::Philo_ctor} -$define${AOs::Philo} - +$define ${Shared::Philo_ctor} +$define ${Shared::AO_Philo[N_PHILO]} +$define ${AOs::Philo} - #include "qpc.h" -#include "dpp.h" -#include "bsp.h" + #include "qpc.h" // QP/C real-time embedded framework +#include "dpp.h" // DPP Application interface +#include "bsp.h" // Board Support Package -Q_DEFINE_THIS_MODULE("table") +$declare ${AOs::Table} -/* Active object class -----------------------------------------------------*/ -$declare${AOs::Table} +//---------------------------------------------------------------------------- +Q_DEFINE_THIS_FILE -#define RIGHT(n_) ((uint8_t)(((n_) + (N_PHILO - 1U)) % N_PHILO)) -#define LEFT(n_) ((uint8_t)(((n_) + 1U) % N_PHILO)) -#define FREE ((uint8_t)0) -#define USED ((uint8_t)1) +// helper function to provide the RIGHT neighbor of a Philo[n] +static inline uint8_t right(uint8_t const n) { + return (uint8_t)((n + (N_PHILO - 1U)) % N_PHILO); +} -/* Local objects -----------------------------------------------------------*/ -static Table l_table; /* the single instance of the Table active object */ +// helper function to provide the LEFT neighbor of a Philo[n] +static inline uint8_t left(uint8_t const n) { + return (uint8_t)((n + 1U) % N_PHILO); +} -/* Global-scope objects ----------------------------------------------------*/ -$define${AOs::AO_Table} +#define FREE ((uint8_t)0U) +#define USED ((uint8_t)1U) -/*..........................................................................*/ -$define${AOs::Table_ctor} -$define${AOs::Table} - +#define THINKING "thinking" +#define HUNGRY "hungry " +#define EATING "eating " + +//---------------------------------------------------------------------------- + +$define ${Shared::Table_ctor} +$define ${Shared::AO_Table} +$define ${AOs::Table} diff --git a/examples/threadx/arm-cm/dpp_stm32f429-discovery/iar/dpp.ewd b/examples/threadx/arm-cm/dpp_stm32f429-discovery/iar/dpp.ewd index 314779dd..7ca73910 100644 --- a/examples/threadx/arm-cm/dpp_stm32f429-discovery/iar/dpp.ewd +++ b/examples/threadx/arm-cm/dpp_stm32f429-discovery/iar/dpp.ewd @@ -11,7 +11,7 @@ C-SPY 2 - 28 + 32 1 1 - - + + + + + @@ -486,7 +498,7 @@ IJET_ID 2 - 8 + 9 1 1 + + + + + + + + + + + + + @@ -916,7 +980,7 @@ LMIFTDI_ID 2 - 2 + 3 1 1 + + + + + + + NULINK_ID + 2 + + 0 + 1 + 1 + + + @@ -974,7 +1072,7 @@ STLINK_ID 2 - 4 + 8 1 1 + + + + @@ -1185,7 +1300,7 @@ XDS100_ID 2 - 6 + 9 1 1 + + + + @@ -1362,6 +1493,18 @@ $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin 0 + + $TOOLKIT_DIR$\plugins\rtos\FreeRtos\FreeRtosArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin2.ENU.ewplugin + 0 + $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin 0 @@ -1371,11 +1514,15 @@ 0 - $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9.ewplugin 0 - $TOOLKIT_DIR$\plugins\rtos\TI-RTOS\tirtosplugin.ewplugin + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9BE.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin 0 @@ -1391,11 +1538,11 @@ 0 - $EW_DIR$\common\plugins\CodeCoverage\CodeCoverage.ENU.ewplugin - 1 + $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + 0 - $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + $EW_DIR$\common\plugins\TargetAccessServer\TargetAccessServer.ENU.ewplugin 0 @@ -1414,7 +1561,7 @@ C-SPY 2 - 28 + 32 1 0 - - + + + + + @@ -1889,7 +2048,7 @@ IJET_ID 2 - 8 + 9 1 0 + + + + + + + + + + + + + @@ -2319,7 +2530,7 @@ LMIFTDI_ID 2 - 2 + 3 1 0 + + + + + + + NULINK_ID + 2 + + 0 + 1 + 0 + + + @@ -2377,7 +2622,7 @@ STLINK_ID 2 - 4 + 8 1 0 + + + + @@ -2588,7 +2850,7 @@ XDS100_ID 2 - 6 + 9 1 0 + + + + @@ -2765,6 +3043,18 @@ $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin 0 + + $TOOLKIT_DIR$\plugins\rtos\FreeRtos\FreeRtosArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin2.ENU.ewplugin + 0 + $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin 0 @@ -2774,11 +3064,15 @@ 0 - $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9.ewplugin 0 - $TOOLKIT_DIR$\plugins\rtos\TI-RTOS\tirtosplugin.ewplugin + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9BE.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin 0 @@ -2794,11 +3088,11 @@ 0 - $EW_DIR$\common\plugins\CodeCoverage\CodeCoverage.ENU.ewplugin - 1 + $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + 0 - $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + $EW_DIR$\common\plugins\TargetAccessServer\TargetAccessServer.ENU.ewplugin 0 @@ -2817,7 +3111,7 @@ C-SPY 2 - 28 + 32 1 1 - - + + + + + @@ -3292,7 +3598,7 @@ IJET_ID 2 - 8 + 9 1 1 + + + + + + + + + + + + + @@ -3722,7 +4080,7 @@ LMIFTDI_ID 2 - 2 + 3 1 1 + + + + + + + NULINK_ID + 2 + + 0 + 1 + 1 + + + @@ -3780,7 +4172,7 @@ STLINK_ID 2 - 4 + 8 1 1 + + + + @@ -3991,7 +4400,7 @@ XDS100_ID 2 - 6 + 9 1 1 + + + + @@ -4168,6 +4593,18 @@ $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin 0 + + $TOOLKIT_DIR$\plugins\rtos\FreeRtos\FreeRtosArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin2.ENU.ewplugin + 0 + $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin 0 @@ -4177,11 +4614,15 @@ 0 - $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9.ewplugin 0 - $TOOLKIT_DIR$\plugins\rtos\TI-RTOS\tirtosplugin.ewplugin + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9BE.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin 0 @@ -4197,11 +4638,11 @@ 0 - $EW_DIR$\common\plugins\CodeCoverage\CodeCoverage.ENU.ewplugin - 1 + $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + 0 - $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + $EW_DIR$\common\plugins\TargetAccessServer\TargetAccessServer.ENU.ewplugin 0 diff --git a/examples/threadx/arm-cm/dpp_stm32f429-discovery/iar/dpp.ewp b/examples/threadx/arm-cm/dpp_stm32f429-discovery/iar/dpp.ewp index 14675f19..bd19213f 100644 --- a/examples/threadx/arm-cm/dpp_stm32f429-discovery/iar/dpp.ewp +++ b/examples/threadx/arm-cm/dpp_stm32f429-discovery/iar/dpp.ewp @@ -11,12 +11,12 @@ General 3 - 33 + 35 1 1 + + + @@ -673,7 +685,7 @@ ILINK 0 - 25 + 27 1 1 + + + + @@ -1064,12 +1092,12 @@ General 3 - 33 + 35 1 0 + + + @@ -1726,7 +1766,7 @@ ILINK 0 - 25 + 27 1 0 + + + + @@ -2117,12 +2173,12 @@ General 3 - 33 + 35 1 1 + + + @@ -2779,7 +2847,7 @@ ILINK 0 - 25 + 27 1 1 + + + + @@ -3161,7 +3245,6 @@ - Debug Release @@ -3182,7 +3265,7 @@ $PROJ_DIR$\..\philo.c - $PROJ_DIR$\..\..\..\..\..\include\qstamp.c + $PROJ_DIR$\..\..\..\..\..\src\qs\qstamp.c $PROJ_DIR$\..\table.c diff --git a/examples/threadx/arm-cm/dpp_stm32f429-discovery/iar/dpp.icf b/examples/threadx/arm-cm/dpp_stm32f429-discovery/iar/dpp.icf index 371a08a7..f37e484f 100644 --- a/examples/threadx/arm-cm/dpp_stm32f429-discovery/iar/dpp.icf +++ b/examples/threadx/arm-cm/dpp_stm32f429-discovery/iar/dpp.icf @@ -9,11 +9,10 @@ define symbol __ICFEDIT_region_ROM_end__ = 0x080FFFFF; define symbol __ICFEDIT_region_RAM_start__ = 0x20000000; define symbol __ICFEDIT_region_RAM_end__ = 0x2001FFFF; /*-Sizes-*/ -define symbol __ICFEDIT_size_cstack__ = 512; +define symbol __ICFEDIT_size_cstack__ = 1024; define symbol __ICFEDIT_size_heap__ = 0; /**** End of ICF editor section. ###ICF###*/ - define memory mem with size = 4G; define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__]; define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__]; @@ -25,7 +24,6 @@ initialize by copy { readwrite }; do not initialize { section .noinit }; place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec }; - place in ROM_region { readonly }; -place at start of RAM_region {block CSTACK }; +place at start of RAM_region {block CSTACK }; /* <== Quantum Leaps */ place in RAM_region { readwrite, block HEAP }; \ No newline at end of file diff --git a/examples/threadx/arm-cm/dpp_stm32f429-discovery/main.c b/examples/threadx/arm-cm/dpp_stm32f429-discovery/main.c index 83ce7825..539523c4 100644 --- a/examples/threadx/arm-cm/dpp_stm32f429-discovery/main.c +++ b/examples/threadx/arm-cm/dpp_stm32f429-discovery/main.c @@ -1,95 +1,88 @@ -/***************************************************************************** -* Last updated for: @ref qpc_7_0_0 -* Last updated on 2021-12-05 -* -* Q u a n t u m L e a P s -* ------------------------ -* Modern Embedded Software -* -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* -* -*****************************************************************************/ -#include "qpc.h" -#include "dpp.h" -#include "bsp.h" +//============================================================================ +// QP example for ThreadX +// Last updated for: @ref qpc_7_3_0 +// Last updated on 2023-08-22 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// This program is open source software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Alternatively, this program may be distributed and modified under the +// terms of Quantum Leaps commercial licenses, which expressly supersede +// the GNU General Public License and are specifically designed for +// licensees interested in retaining the proprietary status of their code. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Contact information: +// +// +//============================================================================ +#include "qpc.h" // QP/C real-time embedded framework +#include "dpp.h" // DPP Application interface +#include "bsp.h" // Board Support Package -Q_DEFINE_THIS_FILE +//Q_DEFINE_THIS_FILE -/* Local-scope objects -----------------------------------------------------*/ -static QEvt const *l_tableQueueSto[N_PHILO]; -static QEvt const *l_philoQueueSto[N_PHILO][N_PHILO]; -static QSubscrList l_subscrSto[MAX_PUB_SIG]; - -static union SmallEvents { - void *e0; /* minimum event size */ - uint8_t e1[sizeof(TableEvt)]; - /* ... other event types to go into this pool */ -} l_smlPoolSto[2*N_PHILO + 10]; /* storage for the small event pool */ - -static ULONG l_philoStk[N_PHILO][256]; /* stacks for the Philosophers */ -static ULONG l_tableStk[256]; /* stack for the Table */ - -/*..........................................................................*/ +//............................................................................ int main() { - Philo_ctor(); /* instantiate all Philosopher active objects */ - Table_ctor(); /* instantiate the Table active object */ tx_kernel_enter(); - return 0; /* tx_kernel_enter() does not return */ + return 0; // tx_kernel_enter() does not return } -/*..........................................................................*/ +//............................................................................ void tx_application_define(void *first_unused_memory) { - uint8_t n; + Q_UNUSED_PAR(first_unused_memory); - (void)first_unused_memory; /* unused parameter */ + QF_init(); // initialize the framework + BSP_init(); // initialize the Board Support Package - BSP_init(); /* initialize the Board Support Package */ - QF_init(); /* initialize the framework and the underlying RT kernel */ + static QSubscrList l_subscrSto[MAX_PUB_SIG]; + QActive_psInit(l_subscrSto, Q_DIM(l_subscrSto)); // init publish-subscribe - QF_psInit(l_subscrSto, Q_DIM(l_subscrSto)); /* init publish-subscribe */ + // initialize event pools... + static QF_MPOOL_EL(TableEvt) smlPoolSto[2*N_PHILO]; + QF_poolInit(smlPoolSto, sizeof(smlPoolSto), sizeof(smlPoolSto[0])); - /* initialize event pools... */ - QF_poolInit(l_smlPoolSto, sizeof(l_smlPoolSto), sizeof(l_smlPoolSto[0])); + // start the active objects/threads... - QS_OBJ_DICTIONARY(l_smlPoolSto); - QS_OBJ_DICTIONARY(AO_Table); - QS_OBJ_DICTIONARY(AO_Philo[0]); - QS_OBJ_DICTIONARY(AO_Philo[1]); - QS_OBJ_DICTIONARY(AO_Philo[2]); - QS_OBJ_DICTIONARY(AO_Philo[3]); - QS_OBJ_DICTIONARY(AO_Philo[4]); - - for (n = 0; n < N_PHILO; ++n) { /* start the active objects... */ + static QEvt const *philoQueueSto[N_PHILO][10]; + static ULONG philoStk[N_PHILO][200]; // stacks for the Philosophers + for (uint8_t n = 0U; n < N_PHILO; ++n) { + Philo_ctor(n); // instantiate the Philo AO QActive_setAttr(AO_Philo[n], THREAD_NAME_ATTR, "Philo"); - QACTIVE_START(AO_Philo[n], (uint8_t)(n + 1), - l_philoQueueSto[n], Q_DIM(l_philoQueueSto[n]), - l_philoStk[n], sizeof(l_philoStk[n]), (QEvt *)0); + QACTIVE_START(AO_Philo[n], + + // NOTE: set the preemption-threshold of all Philos to + // the same level, so that they cannot preempt each other. + Q_PRIO(n + 1U, N_PHILO), // QF-prio/pre-thre. + + philoQueueSto[n], Q_DIM(philoQueueSto[n]), + philoStk[n], sizeof(philoStk[n]), + (void *)0); } + static QEvt const *tableQueueSto[N_PHILO]; + static ULONG tableStk[200]; // stack for the Table + Table_ctor(); // instantiate the Table AO QActive_setAttr(AO_Table, THREAD_NAME_ATTR, "Table"); - QACTIVE_START(AO_Table, (uint8_t)(N_PHILO + 1), - l_tableQueueSto, Q_DIM(l_tableQueueSto), - l_tableStk, sizeof(l_tableStk), (QEvt *)0); + QACTIVE_START(AO_Table, + N_PHILO + 1U, + tableQueueSto, Q_DIM(tableQueueSto), + tableStk, sizeof(tableStk), + (void *)0); (void)QF_run(); } diff --git a/examples/threadx/arm-cm/dpp_stm32f429-discovery/philo.c b/examples/threadx/arm-cm/dpp_stm32f429-discovery/philo.c index 919e39d6..eb6be531 100644 --- a/examples/threadx/arm-cm/dpp_stm32f429-discovery/philo.c +++ b/examples/threadx/arm-cm/dpp_stm32f429-discovery/philo.c @@ -1,160 +1,160 @@ -/*$file${.::philo.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* -* Model: dpp.qm -* File: ${.::philo.c} -* -* This code has been generated by QM 5.2.4 . -* DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. -* -* SPDX-License-Identifier: GPL-3.0-or-later -* -* This generated code is open source software: you can redistribute it under -* the terms of the GNU General Public License as published by the Free -* Software Foundation. -* -* This code is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -* more details. -* -* NOTE: -* Alternatively, this generated code may be distributed under the terms -* of Quantum Leaps commercial licenses, which expressly supersede the GNU -* General Public License and are specifically designed for licensees -* interested in retaining the proprietary status of their code. -* -* Contact information: -* -* -*/ -/*$endhead${.::philo.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -#include "qpc.h" -#include "dpp.h" -#include "bsp.h" +//$file${.::philo.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// +// Model: dpp.qm +// File: ${.::philo.c} +// +// This code has been generated by QM 5.3.0 . +// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. +// +// SPDX-License-Identifier: GPL-3.0-or-later +// +// This generated code is open source software: you can redistribute it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation. +// +// This code is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// NOTE: +// Alternatively, this generated code may be distributed under the terms +// of Quantum Leaps commercial licenses, which expressly supersede the GNU +// General Public License and are specifically designed for licensees +// interested in retaining the proprietary status of their code. +// +// Contact information: +// +// +// +//$endhead${.::philo.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +#include "qpc.h" // QP/C real-time embedded framework +#include "dpp.h" // DPP Application interface +#include "bsp.h" // Board Support Package -Q_DEFINE_THIS_MODULE("philo") +//$declare${AOs::Philo} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/* Active object class -----------------------------------------------------*/ -/*$declare${AOs::Philo} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${AOs::Philo} ............................................................*/ -typedef struct { -/* protected: */ +//${AOs::Philo} .............................................................. +typedef struct Philo { +// protected: QActive super; -/* private: */ +// private: QTimeEvt timeEvt; + uint8_t id; + +// public: } Philo; -/* protected: */ +extern Philo Philo_inst[N_PHILO]; + +// protected: static QState Philo_initial(Philo * const me, void const * const par); static QState Philo_thinking(Philo * const me, QEvt const * const e); static QState Philo_hungry(Philo * const me, QEvt const * const e); static QState Philo_eating(Philo * const me, QEvt const * const e); -/*$enddecl${AOs::Philo} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$enddecl${AOs::Philo} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -/* Local objects -----------------------------------------------------------*/ -static Philo l_philo[N_PHILO]; /* storage for all Philos */ +//---------------------------------------------------------------------------- +Q_DEFINE_THIS_FILE -#define THINK_TIME \ - (QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + (BSP_TICKS_PER_SEC/2U)) -#define EAT_TIME \ - (QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + BSP_TICKS_PER_SEC) - -/* helper macro to provide the ID of Philo "me_" */ -#define PHILO_ID(me_) ((uint8_t)((me_) - l_philo)) - -/* Global objects ----------------------------------------------------------*/ -/*$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* Check for the minimum required QP version */ -#if (QP_VERSION < 700U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) -#error qpc version 7.0.0 or higher required -#endif -/*$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ - -/*$define${AOs::AO_Philo[N_PHILO]} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${AOs::AO_Philo[N_PHILO]} ................................................*/ -QActive * const AO_Philo[N_PHILO] = { - &l_philo[0].super, - &l_philo[1].super, - &l_philo[2].super, - &l_philo[3].super, - &l_philo[4].super -}; -/*$enddef${AOs::AO_Philo[N_PHILO]} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ - -/* Philo definition --------------------------------------------------------*/ -/*$define${AOs::Philo_ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${AOs::Philo_ctor} .......................................................*/ -void Philo_ctor(void) { - uint8_t n; - Philo *me; - for (n = 0U; n < N_PHILO; ++n) { - me = &l_philo[n]; - QActive_ctor(&me->super, Q_STATE_CAST(&Philo_initial)); - QTimeEvt_ctorX(&me->timeEvt, &me->super, TIMEOUT_SIG, 0U); - } +// helper function to provide a randomized think time for Philos +static QTimeEvtCtr think_time(void); // prototype +static inline QTimeEvtCtr think_time(void) { + return (QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + + (BSP_TICKS_PER_SEC/2U)); } -/*$enddef${AOs::Philo_ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*$define${AOs::Philo} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/*${AOs::Philo} ............................................................*/ +// helper function to provide a randomized eat time for Philos +static QTimeEvtCtr eat_time(void); // prototype +static inline QTimeEvtCtr eat_time(void) { + return (QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + + BSP_TICKS_PER_SEC); +} +//---------------------------------------------------------------------------- -/*${AOs::Philo::SM} ........................................................*/ +//$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// Check for the minimum required QP version +#if (QP_VERSION < 730U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) +#error qpc version 7.3.0 or higher required +#endif +//$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +//$define${Shared::Philo_ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${Shared::Philo_ctor} ...................................................... +void Philo_ctor(uint_fast8_t const id) { + Philo * const me = &Philo_inst[id]; + QActive_ctor(&me->super, Q_STATE_CAST(&Philo_initial)); + QTimeEvt_ctorX(&me->timeEvt, &me->super, TIMEOUT_SIG, 0U), + me->id = (uint8_t)id; +} +//$enddef${Shared::Philo_ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +//$define${Shared::AO_Philo[N_PHILO]} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${Shared::AO_Philo[N_PHILO]} ............................................... +QActive * const AO_Philo[N_PHILO] = { + &Philo_inst[0].super, + &Philo_inst[1].super, + &Philo_inst[2].super, + &Philo_inst[3].super, + &Philo_inst[4].super +}; +//$enddef${Shared::AO_Philo[N_PHILO]} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +//$define${AOs::Philo} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${AOs::Philo} .............................................................. +Philo Philo_inst[N_PHILO]; + +//${AOs::Philo::SM} .......................................................... static QState Philo_initial(Philo * const me, void const * const par) { - /*${AOs::Philo::SM::initial} */ - static uint8_t registered = (uint8_t)0; /* starts off with 0, per C-standard */ - (void)par; /* unused parameter */ - if (registered == (uint8_t)0) { - registered = (uint8_t)1; + //${AOs::Philo::SM::initial} + Q_UNUSED_PAR(par); - QS_OBJ_DICTIONARY(&l_philo[0].timeEvt); - QS_OBJ_DICTIONARY(&l_philo[1].timeEvt); - QS_OBJ_DICTIONARY(&l_philo[2].timeEvt); - QS_OBJ_DICTIONARY(&l_philo[3].timeEvt); - QS_OBJ_DICTIONARY(&l_philo[4].timeEvt); - - QS_FUN_DICTIONARY(&Philo_initial); - QS_FUN_DICTIONARY(&Philo_thinking); - QS_FUN_DICTIONARY(&Philo_hungry); - QS_FUN_DICTIONARY(&Philo_eating); - } - QS_SIG_DICTIONARY(HUNGRY_SIG, me); /* signal for each Philos */ - QS_SIG_DICTIONARY(TIMEOUT_SIG, me); /* signal for each Philos */ + QS_OBJ_ARR_DICTIONARY(&Philo_inst[me->id], me->id); + QS_OBJ_ARR_DICTIONARY(&Philo_inst[me->id].timeEvt, me->id); QActive_subscribe(&me->super, EAT_SIG); QActive_subscribe(&me->super, TEST_SIG); + + QS_FUN_DICTIONARY(&Philo_thinking); + QS_FUN_DICTIONARY(&Philo_hungry); + QS_FUN_DICTIONARY(&Philo_eating); + return Q_TRAN(&Philo_thinking); } -/*${AOs::Philo::SM::thinking} ..............................................*/ +//${AOs::Philo::SM::thinking} ................................................ static QState Philo_thinking(Philo * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${AOs::Philo::SM::thinking} */ + //${AOs::Philo::SM::thinking} case Q_ENTRY_SIG: { - QTimeEvt_armX(&me->timeEvt, THINK_TIME, 0U); + QTimeEvt_armX(&me->timeEvt, think_time(), 0U); status_ = Q_HANDLED(); break; } - /*${AOs::Philo::SM::thinking} */ + //${AOs::Philo::SM::thinking} case Q_EXIT_SIG: { - QTimeEvt_disarm(&me->timeEvt); + (void)QTimeEvt_disarm(&me->timeEvt); status_ = Q_HANDLED(); break; } - /*${AOs::Philo::SM::thinking::TIMEOUT} */ + //${AOs::Philo::SM::thinking::TIMEOUT} case TIMEOUT_SIG: { status_ = Q_TRAN(&Philo_hungry); break; } - /*${AOs::Philo::SM::thinking::EAT, DONE} */ - case EAT_SIG: /* intentionally fall through */ + //${AOs::Philo::SM::thinking::EAT, DONE} + case EAT_SIG: // intentionally fall through case DONE_SIG: { - /* EAT or DONE must be for other Philos than this one */ - Q_ASSERT_ID(10, Q_EVT_CAST(TableEvt)->philoNum != PHILO_ID(me)); + // EAT or DONE must be for other Philos than this one + Q_ASSERT(Q_EVT_CAST(TableEvt)->philoId != me->id); + status_ = Q_HANDLED(); + break; + } + //${AOs::Philo::SM::thinking::TEST} + case TEST_SIG: { status_ = Q_HANDLED(); break; } @@ -166,22 +166,26 @@ static QState Philo_thinking(Philo * const me, QEvt const * const e) { return status_; } -/*${AOs::Philo::SM::hungry} ................................................*/ +//${AOs::Philo::SM::hungry} .................................................. static QState Philo_hungry(Philo * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${AOs::Philo::SM::hungry} */ + //${AOs::Philo::SM::hungry} case Q_ENTRY_SIG: { + #ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, HUNGRY_SIG, me->id); + #else TableEvt *pe = Q_NEW(TableEvt, HUNGRY_SIG); - pe->philoNum = PHILO_ID(me); - QACTIVE_POST(AO_Table, &pe->super, me); + pe->philoId = me->id; + #endif + QACTIVE_POST(AO_Table, &pe->super, &me->super); status_ = Q_HANDLED(); break; } - /*${AOs::Philo::SM::hungry::EAT} */ + //${AOs::Philo::SM::hungry::EAT} case EAT_SIG: { - /*${AOs::Philo::SM::hungry::EAT::[Q_EVT_CAST(TableEvt)->philoNum=~} */ - if (Q_EVT_CAST(TableEvt)->philoNum == PHILO_ID(me)) { + //${AOs::Philo::SM::hungry::EAT::[e->philoId==me->iid]} + if (Q_EVT_CAST(TableEvt)->philoId == me->id) { status_ = Q_TRAN(&Philo_eating); } else { @@ -189,10 +193,10 @@ static QState Philo_hungry(Philo * const me, QEvt const * const e) { } break; } - /*${AOs::Philo::SM::hungry::DONE} */ + //${AOs::Philo::SM::hungry::DONE} case DONE_SIG: { - /* DONE must be for other Philos than this one */ - Q_ASSERT_ID(20, Q_EVT_CAST(TableEvt)->philoNum != PHILO_ID(me)); + // DONE must be for other Philos than this one + Q_ASSERT(Q_EVT_CAST(TableEvt)->philoId != me->id); status_ = Q_HANDLED(); break; } @@ -204,35 +208,40 @@ static QState Philo_hungry(Philo * const me, QEvt const * const e) { return status_; } -/*${AOs::Philo::SM::eating} ................................................*/ +//${AOs::Philo::SM::eating} .................................................. static QState Philo_eating(Philo * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${AOs::Philo::SM::eating} */ + //${AOs::Philo::SM::eating} case Q_ENTRY_SIG: { - QTimeEvt_armX(&me->timeEvt, EAT_TIME, 0U); + QTimeEvt_armX(&me->timeEvt, eat_time(), 0U); status_ = Q_HANDLED(); break; } - /*${AOs::Philo::SM::eating} */ + //${AOs::Philo::SM::eating} case Q_EXIT_SIG: { + (void)QTimeEvt_disarm(&me->timeEvt); + + #ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, DONE_SIG, me->id); + #else TableEvt *pe = Q_NEW(TableEvt, DONE_SIG); - pe->philoNum = PHILO_ID(me); + pe->philoId = me->id; + #endif QACTIVE_PUBLISH(&pe->super, &me->super); - QTimeEvt_disarm(&me->timeEvt); status_ = Q_HANDLED(); break; } - /*${AOs::Philo::SM::eating::TIMEOUT} */ + //${AOs::Philo::SM::eating::TIMEOUT} case TIMEOUT_SIG: { status_ = Q_TRAN(&Philo_thinking); break; } - /*${AOs::Philo::SM::eating::EAT, DONE} */ - case EAT_SIG: /* intentionally fall through */ + //${AOs::Philo::SM::eating::EAT, DONE} + case EAT_SIG: // intentionally fall through case DONE_SIG: { - /* EAT or DONE must be for other Philos than this one */ - Q_ASSERT_ID(30, Q_EVT_CAST(TableEvt)->philoNum != PHILO_ID(me)); + // EAT or DONE must be for other Philos than this one + Q_ASSERT(Q_EVT_CAST(TableEvt)->philoId != me->id); status_ = Q_HANDLED(); break; } @@ -243,5 +252,4 @@ static QState Philo_eating(Philo * const me, QEvt const * const e) { } return status_; } -/*$enddef${AOs::Philo} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ - +//$enddef${AOs::Philo} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/examples/threadx/arm-cm/dpp_stm32f429-discovery/table.c b/examples/threadx/arm-cm/dpp_stm32f429-discovery/table.c index d655896e..c3ae02f0 100644 --- a/examples/threadx/arm-cm/dpp_stm32f429-discovery/table.c +++ b/examples/threadx/arm-cm/dpp_stm32f429-discovery/table.c @@ -1,124 +1,130 @@ -/*$file${.::table.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* -* Model: dpp.qm -* File: ${.::table.c} -* -* This code has been generated by QM 5.2.4 . -* DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. -* -* SPDX-License-Identifier: GPL-3.0-or-later -* -* This generated code is open source software: you can redistribute it under -* the terms of the GNU General Public License as published by the Free -* Software Foundation. -* -* This code is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -* more details. -* -* NOTE: -* Alternatively, this generated code may be distributed under the terms -* of Quantum Leaps commercial licenses, which expressly supersede the GNU -* General Public License and are specifically designed for licensees -* interested in retaining the proprietary status of their code. -* -* Contact information: -* -* -*/ -/*$endhead${.::table.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -#include "qpc.h" -#include "dpp.h" -#include "bsp.h" +//$file${.::table.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// +// Model: dpp.qm +// File: ${.::table.c} +// +// This code has been generated by QM 5.3.0 . +// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. +// +// SPDX-License-Identifier: GPL-3.0-or-later +// +// This generated code is open source software: you can redistribute it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation. +// +// This code is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// NOTE: +// Alternatively, this generated code may be distributed under the terms +// of Quantum Leaps commercial licenses, which expressly supersede the GNU +// General Public License and are specifically designed for licensees +// interested in retaining the proprietary status of their code. +// +// Contact information: +// +// +// +//$endhead${.::table.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +#include "qpc.h" // QP/C real-time embedded framework +#include "dpp.h" // DPP Application interface +#include "bsp.h" // Board Support Package -Q_DEFINE_THIS_MODULE("table") +//$declare${AOs::Table} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/* Active object class -----------------------------------------------------*/ -/*$declare${AOs::Table} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${AOs::Table} ............................................................*/ -typedef struct { -/* protected: */ +//${AOs::Table} .............................................................. +typedef struct Table { +// protected: QActive super; -/* private: */ +// private: uint8_t fork[N_PHILO]; - uint8_t isHungry[N_PHILO]; + bool isHungry[N_PHILO]; + +// public: } Table; -/* protected: */ +extern Table Table_inst; + +// protected: static QState Table_initial(Table * const me, void const * const par); static QState Table_active(Table * const me, QEvt const * const e); static QState Table_serving(Table * const me, QEvt const * const e); static QState Table_paused(Table * const me, QEvt const * const e); -/*$enddecl${AOs::Table} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$enddecl${AOs::Table} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -#define RIGHT(n_) ((uint8_t)(((n_) + (N_PHILO - 1U)) % N_PHILO)) -#define LEFT(n_) ((uint8_t)(((n_) + 1U) % N_PHILO)) -#define FREE ((uint8_t)0) -#define USED ((uint8_t)1) +//---------------------------------------------------------------------------- +Q_DEFINE_THIS_FILE -/* Local objects -----------------------------------------------------------*/ -static Table l_table; /* the single instance of the Table active object */ +// helper function to provide the RIGHT neighbor of a Philo[n] +static inline uint8_t right(uint8_t const n) { + return (uint8_t)((n + (N_PHILO - 1U)) % N_PHILO); +} -/* Global-scope objects ----------------------------------------------------*/ -/*$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* Check for the minimum required QP version */ -#if (QP_VERSION < 700U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) -#error qpc version 7.0.0 or higher required +// helper function to provide the LEFT neighbor of a Philo[n] +static inline uint8_t left(uint8_t const n) { + return (uint8_t)((n + 1U) % N_PHILO); +} + +#define FREE ((uint8_t)0U) +#define USED ((uint8_t)1U) + +#define THINKING "thinking" +#define HUNGRY "hungry " +#define EATING "eating " + +//---------------------------------------------------------------------------- + +//$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// Check for the minimum required QP version +#if (QP_VERSION < 730U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) +#error qpc version 7.3.0 or higher required #endif -/*$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -/*$define${AOs::AO_Table} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//$define${Shared::Table_ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/*${AOs::AO_Table} .........................................................*/ -QActive * const AO_Table = &l_table.super; -/*$enddef${AOs::AO_Table} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ - -/*..........................................................................*/ -/*$define${AOs::Table_ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${AOs::Table_ctor} .......................................................*/ +//${Shared::Table_ctor} ...................................................... void Table_ctor(void) { - uint8_t n; - Table *me = &l_table; - + Table * const me = &Table_inst; QActive_ctor(&me->super, Q_STATE_CAST(&Table_initial)); - - for (n = 0U; n < N_PHILO; ++n) { + for (uint8_t n = 0U; n < N_PHILO; ++n) { me->fork[n] = FREE; - me->isHungry[n] = 0U; + me->isHungry[n] = false; } } -/*$enddef${AOs::Table_ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*$define${AOs::Table} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//$enddef${Shared::Table_ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +//$define${Shared::AO_Table} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/*${AOs::Table} ............................................................*/ +//${Shared::AO_Table} ........................................................ +QActive * const AO_Table = &Table_inst.super; +//$enddef${Shared::AO_Table} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +//$define${AOs::Table} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/*${AOs::Table::SM} ........................................................*/ +//${AOs::Table} .............................................................. +Table Table_inst; + +//${AOs::Table::SM} .......................................................... static QState Table_initial(Table * const me, void const * const par) { - /*${AOs::Table::SM::initial} */ - uint8_t n; - (void)par; /* unused parameter */ + //${AOs::Table::SM::initial} + Q_UNUSED_PAR(par); - QS_SIG_DICTIONARY(DONE_SIG, (void *)0); /* global signals */ - QS_SIG_DICTIONARY(EAT_SIG, (void *)0); - QS_SIG_DICTIONARY(PAUSE_SIG, (void *)0); - QS_SIG_DICTIONARY(SERVE_SIG, (void *)0); - QS_SIG_DICTIONARY(TEST_SIG, (void *)0); - - QS_SIG_DICTIONARY(HUNGRY_SIG, me); /* signal just for Table */ + #ifdef Q_SPY + Table *Table_inst = me; + QS_OBJ_DICTIONARY(Table_inst); + #endif QActive_subscribe(&me->super, DONE_SIG); QActive_subscribe(&me->super, PAUSE_SIG); QActive_subscribe(&me->super, SERVE_SIG); QActive_subscribe(&me->super, TEST_SIG); - for (n = 0U; n < N_PHILO; ++n) { + for (uint8_t n = 0U; n < N_PHILO; ++n) { me->fork[n] = FREE; - me->isHungry[n] = 0U; - BSP_displayPhilStat(n, "thinking"); + me->isHungry[n] = false; + BSP_displayPhilStat(n, THINKING); } QS_FUN_DICTIONARY(&Table_active); @@ -128,13 +134,18 @@ static QState Table_initial(Table * const me, void const * const par) { return Q_TRAN(&Table_serving); } -/*${AOs::Table::SM::active} ................................................*/ +//${AOs::Table::SM::active} .................................................. static QState Table_active(Table * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${AOs::Table::SM::active::EAT} */ + //${AOs::Table::SM::active::TEST} + case TEST_SIG: { + status_ = Q_HANDLED(); + break; + } + //${AOs::Table::SM::active::EAT} case EAT_SIG: { - Q_ERROR_ID(60); + Q_ERROR(); status_ = Q_HANDLED(); break; } @@ -146,102 +157,119 @@ static QState Table_active(Table * const me, QEvt const * const e) { return status_; } -/*${AOs::Table::SM::active::serving} .......................................*/ +//${AOs::Table::SM::active::serving} ......................................... static QState Table_serving(Table * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${AOs::Table::SM::active::serving} */ + //${AOs::Table::SM::active::serving} case Q_ENTRY_SIG: { - uint8_t n; - for (n = 0U; n < N_PHILO; ++n) { /* give permissions to eat... */ - if ((me->isHungry[n] != 0U) - && (me->fork[LEFT(n)] == FREE) + // give permissions to eat... + for (uint8_t n = 0U; n < N_PHILO; ++n) { + if (me->isHungry[n] + && (me->fork[left(n)] == FREE) && (me->fork[n] == FREE)) { - TableEvt *te; - - me->fork[LEFT(n)] = USED; + me->fork[left(n)] = USED; me->fork[n] = USED; - te = Q_NEW(TableEvt, EAT_SIG); - te->philoNum = n; - QACTIVE_PUBLISH(&te->super, &me->super); - me->isHungry[n] = 0U; - BSP_displayPhilStat(n, "eating "); + #ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, EAT_SIG, n); + #else + TableEvt *pe = Q_NEW(TableEvt, EAT_SIG); + pe->philoId = n; + #endif + QACTIVE_PUBLISH(&pe->super, &me->super); + me->isHungry[n] = false; + BSP_displayPhilStat(n, EATING); } } status_ = Q_HANDLED(); break; } - /*${AOs::Table::SM::active::serving::HUNGRY} */ + //${AOs::Table::SM::active::serving::HUNGRY} case HUNGRY_SIG: { - uint8_t n, m; + uint8_t n = Q_EVT_CAST(TableEvt)->philoId; - n = Q_EVT_CAST(TableEvt)->philoNum; - /* phil ID must be in range and he must be not hungry */ - Q_ASSERT_ID(40, (n < N_PHILO) && (me->isHungry[n] == 0U)); + // phil ID must be in range and he must be not hungry + Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); - BSP_displayPhilStat(n, "hungry "); - m = LEFT(n); - /*${AOs::Table::SM::active::serving::HUNGRY::[bothfree]} */ + BSP_displayPhilStat(n, HUNGRY); + uint8_t m = left(n); + //${AOs::Table::SM::active::serving::HUNGRY::[bothfree]} if ((me->fork[m] == FREE) && (me->fork[n] == FREE)) { - TableEvt *pe; me->fork[m] = USED; me->fork[n] = USED; - pe = Q_NEW(TableEvt, EAT_SIG); - pe->philoNum = n; + #ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, EAT_SIG, n); + #else + TableEvt *pe = Q_NEW(TableEvt, EAT_SIG); + pe->philoId = n; + #endif QACTIVE_PUBLISH(&pe->super, &me->super); - BSP_displayPhilStat(n, "eating "); + BSP_displayPhilStat(n, EATING); status_ = Q_HANDLED(); } - /*${AOs::Table::SM::active::serving::HUNGRY::[else]} */ + //${AOs::Table::SM::active::serving::HUNGRY::[else]} else { - me->isHungry[n] = 1U; + me->isHungry[n] = true; status_ = Q_HANDLED(); } break; } - /*${AOs::Table::SM::active::serving::DONE} */ + //${AOs::Table::SM::active::serving::DONE} case DONE_SIG: { - uint8_t n, m; - TableEvt *pe; + uint8_t n = Q_EVT_CAST(TableEvt)->philoId; - n = Q_EVT_CAST(TableEvt)->philoNum; - /* phil ID must be in range and he must be not hungry */ - Q_ASSERT_ID(50, (n < N_PHILO) && (me->isHungry[n] == 0U)); + // phil ID must be in range and he must be not hungry + Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); - BSP_displayPhilStat(n, "thinking"); - m = LEFT(n); - /* both forks of Phil[n] must be used */ - Q_ASSERT_ID(51, (me->fork[n] == USED) && (me->fork[m] == USED)); + BSP_displayPhilStat(n, THINKING); + uint8_t m = left(n); + + // both forks of Phil[n] must be used + Q_ASSERT((me->fork[n] == USED) && (me->fork[m] == USED)); me->fork[m] = FREE; me->fork[n] = FREE; - m = RIGHT(n); /* check the right neighbor */ + m = right(n); // check the right neighbor - if ((me->isHungry[m] != 0U) && (me->fork[m] == FREE)) { + if (me->isHungry[m] && (me->fork[m] == FREE)) { me->fork[n] = USED; me->fork[m] = USED; - me->isHungry[m] = 0U; - pe = Q_NEW(TableEvt, EAT_SIG); - pe->philoNum = m; + me->isHungry[m] = false; + #ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, EAT_SIG, m); + #else + TableEvt *pe = Q_NEW(TableEvt, EAT_SIG); + pe->philoId = m; + #endif QACTIVE_PUBLISH(&pe->super, &me->super); - BSP_displayPhilStat(m, "eating "); + BSP_displayPhilStat(m, EATING); } - m = LEFT(n); /* check the left neighbor */ - n = LEFT(m); /* left fork of the left neighbor */ - if ((me->isHungry[m] != 0U) && (me->fork[n] == FREE)) { + m = left(n); // check the left neighbor + n = left(m); // left fork of the left neighbor + if (me->isHungry[m] && (me->fork[n] == FREE)) { me->fork[m] = USED; me->fork[n] = USED; - me->isHungry[m] = 0U; - pe = Q_NEW(TableEvt, EAT_SIG); - pe->philoNum = m; + me->isHungry[m] = false; + #ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, EAT_SIG, m); + #else + TableEvt *pe = Q_NEW(TableEvt, EAT_SIG); + pe->philoId = m; + #endif QACTIVE_PUBLISH(&pe->super, &me->super); - BSP_displayPhilStat(m, "eating "); + BSP_displayPhilStat(m, EATING); } status_ = Q_HANDLED(); break; } - /*${AOs::Table::SM::active::serving::PAUSE} */ + //${AOs::Table::SM::active::serving::EAT} + case EAT_SIG: { + Q_ERROR(); + status_ = Q_HANDLED(); + break; + } + //${AOs::Table::SM::active::serving::PAUSE} case PAUSE_SIG: { status_ = Q_TRAN(&Table_paused); break; @@ -254,49 +282,51 @@ static QState Table_serving(Table * const me, QEvt const * const e) { return status_; } -/*${AOs::Table::SM::active::paused} ........................................*/ +//${AOs::Table::SM::active::paused} .......................................... static QState Table_paused(Table * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${AOs::Table::SM::active::paused} */ + //${AOs::Table::SM::active::paused} case Q_ENTRY_SIG: { BSP_displayPaused(1U); status_ = Q_HANDLED(); break; } - /*${AOs::Table::SM::active::paused} */ + //${AOs::Table::SM::active::paused} case Q_EXIT_SIG: { BSP_displayPaused(0U); status_ = Q_HANDLED(); break; } - /*${AOs::Table::SM::active::paused::SERVE} */ + //${AOs::Table::SM::active::paused::SERVE} case SERVE_SIG: { status_ = Q_TRAN(&Table_serving); break; } - /*${AOs::Table::SM::active::paused::HUNGRY} */ + //${AOs::Table::SM::active::paused::HUNGRY} case HUNGRY_SIG: { - uint8_t n = Q_EVT_CAST(TableEvt)->philoNum; - /* philo ID must be in range and he must be not hungry */ - Q_ASSERT_ID(60, (n < N_PHILO) && (me->isHungry[n] == 0U)); - me->isHungry[n] = 1U; - BSP_displayPhilStat(n, "hungry "); + uint8_t n = Q_EVT_CAST(TableEvt)->philoId; + + // philo ID must be in range and he must be not hungry + Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); + + me->isHungry[n] = true; + BSP_displayPhilStat(n, HUNGRY); status_ = Q_HANDLED(); break; } - /*${AOs::Table::SM::active::paused::DONE} */ + //${AOs::Table::SM::active::paused::DONE} case DONE_SIG: { - uint8_t n, m; + uint8_t n = Q_EVT_CAST(TableEvt)->philoId; - n = Q_EVT_CAST(TableEvt)->philoNum; - /* phil ID must be in range and he must be not hungry */ - Q_ASSERT_ID(70, (n < N_PHILO) && (me->isHungry[n] == 0U)); + // phil ID must be in range and he must be not hungry + Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); - BSP_displayPhilStat(n, "thinking"); - m = LEFT(n); - /* both forks of Phil[n] must be used */ - Q_ASSERT_ID(71, (me->fork[n] == USED) && (me->fork[m] == USED)); + BSP_displayPhilStat(n, THINKING); + uint8_t m = left(n); + + // both forks of Phil[n] must be used + Q_ASSERT((me->fork[n] == USED) && (me->fork[m] == USED)); me->fork[m] = FREE; me->fork[n] = FREE; @@ -310,5 +340,4 @@ static QState Table_paused(Table * const me, QEvt const * const e) { } return status_; } -/*$enddef${AOs::Table} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ - +//$enddef${AOs::Table} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/examples/threadx/win32/README.txt b/examples/threadx/win32/README.txt deleted file mode 100644 index 7fe3dfe7..00000000 --- a/examples/threadx/win32/README.txt +++ /dev/null @@ -1,12 +0,0 @@ -This directory contains examples for QP-ThreadX port running -on top of Windows (with the Win32 API). The examples use the -following ports: - -1. Unmodified QP-port to ThreadX (qpc\ports\threadx) -2. Unmodified ThreadX port to Win32 (qpc\3rd_party\threadx\ports\win32) - -The example demonstrates QP/Spy software tracing (the QSpy build -configuration). The QP/Spy tracing uses TCP/IP for the data transport. - -Quantum Leaps, -2021-12-05 \ No newline at end of file diff --git a/examples/threadx/win32/dpp_console/bsp.c b/examples/threadx/win32/dpp_console/bsp.c deleted file mode 100644 index 2c73ced2..00000000 --- a/examples/threadx/win32/dpp_console/bsp.c +++ /dev/null @@ -1,467 +0,0 @@ -/***************************************************************************** -* Product: DPP example, ThreadX kernel, Win32 emulation, console app. -* Last updated for: @ref qpc_7_0_0 -* Last updated on 2021-12-03 -* -* Q u a n t u m L e a P s -* ------------------------ -* Modern Embedded Software -* -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* -* -*****************************************************************************/ -/* Win32 configuration macros needed for proper WinSock includes */ -#define WIN32_LEAN_AND_MEAN -#define _WIN32_WINNT 0x0501 - -#include "qpc.h" -#include "dpp.h" -#include "bsp.h" - -#include /* for printf_s() */ -#include /* for exit() */ -#include /* for keyboard input */ - -Q_DEFINE_THIS_FILE - -/* Local-scope objects -----------------------------------------------------*/ -static uint32_t l_rnd; /* random seed */ -static TX_TIMER l_tick_timer; /* ThreadX timer to call QTIMEEVT_TICK_X() */ - -#ifdef Q_SPY - - enum AppRecords { /* application-specific trace records */ - PHILO_STAT = QS_USER, - COMMAND_STAT - }; - - /* QSpy source IDs */ - static QSpyId const l_clock_tick = { QS_AP_ID }; - static void QS_rx_input(void); - static void QS_output(void); -#endif - -/*..........................................................................*/ -void BSP_init(void) { - printf_s("Dining Philosophers Problem example\n" - "QP port to ThreadX\n" - "ThreadX port to Win32\n" - "QP %s\n" - "Press 'p' to pause\n" - "Press 's' to serve\n" - "Press 'x' to quit...\n", - QP_VERSION_STR); - - /* seed the random number generator */ - BSP_randomSeed(1234U); - - if (QS_INIT((void *)0) == 0U) { /* initialize the QS software tracing */ - Q_ERROR(); - } - QS_USR_DICTIONARY(PHILO_STAT); - QS_USR_DICTIONARY(COMMAND_STAT); - - /* setup the QS filters... */ - QS_GLB_FILTER(QS_ALL_RECORDS); - QS_GLB_FILTER(-QS_QF_TICK); -} -/*..........................................................................*/ -void BSP_displayPhilStat(uint8_t n, char const *stat) { - printf("Philo[%d] is %s\n", (int)n, stat); - - QS_BEGIN_ID(PHILO_STAT, AO_Philo[n]->prio) /* app-specific record */ - QS_U8(1, n); /* Philosopher number */ - QS_STR(stat); /* Philosopher status */ - QS_END() -} -/*..........................................................................*/ -void BSP_displayPaused(uint8_t paused) { - printf("%s\n", paused ? "PAUSED" : "SERVING"); -} -/*..........................................................................*/ -uint32_t BSP_random(void) { /* a very cheap pseudo-random-number generator */ - uint32_t rnd; - - /* Some flating point code is to exercise the VFP... */ - float volatile x = 3.1415926F; - x = x + 2.7182818F; - - /* "Super-Duper" Linear Congruential Generator (LCG) - * LCG(2^32, 3*7*11*13*23, 0, seed) - */ - rnd = l_rnd * (3U*7U*11U*13U*23U); - l_rnd = rnd; /* set for the next time */ - - return (rnd >> 8); -} -/*..........................................................................*/ -void BSP_randomSeed(uint32_t seed) { - l_rnd = seed; -} -/*..........................................................................*/ -void BSP_terminate(int16_t result) { - (void)result; -} - -/* QF callbacks ============================================================*/ -static VOID timer_expiration(ULONG id) { - (void)id; /* unused parameter */ - - QTIMEEVT_TICK_X(0U, &l_clock_tick); /* perform the QF clock tick processing */ - - /* handle keyborad input... */ - if (_kbhit()) { - int ch = _getwch(); - switch (ch) { - case 'p': { - QACTIVE_PUBLISH(Q_NEW(QEvt, PAUSE_SIG), &l_clock_tick); - break; - } - case 's': { - QACTIVE_PUBLISH(Q_NEW(QEvt, SERVE_SIG), &l_clock_tick); - break; - } - case 'x': { - QF_stop(); - break; - } - default: { - break; - } - } - } - - /* also in case of Win32, perform here QS RX/TX... */ - QS_RX_INPUT(); /* handle the QS-RX input */ - QS_OUTPUT(); /* handle the QS-TX output */ -} -/*..........................................................................*/ -void QF_onStartup(void) { - /* - * NOTE: - * This application uses the ThreadX timer to periodically call - * the QTimeEvt_tick_(0) function. Here, only the clock tick rate of 0 - * is used, but other timers can be used to call QTimeEvt_tick_() for - * other clock tick rates, if needed. - * - * The choice of a ThreadX timer is not the only option. Applications - * might choose to call QTIMEEVT_TICK_X() directly from timer interrupts - * or from active object(s). - */ - Q_ALLEGE(tx_timer_create(&l_tick_timer, /* ThreadX timer object */ - (CHAR *)"QP-tick", /* name of the timer */ - &timer_expiration, /* expiration function */ - 0U, /* expiration function input (tick rate) */ - 1U, /* initial ticks */ - 1U, /* reschedule ticks */ - TX_AUTO_ACTIVATE) /* automatically activate timer */ - == TX_SUCCESS); -} -/*..........................................................................*/ -void QF_onCleanup(void) { -#ifdef Q_SPY - QS_onCleanup(); -#endif - exit(0); -} - -/*..........................................................................*/ -Q_NORETURN Q_onAssert(char const * const module, int_t const loc) { - printf("Assertion failed in %s:%d\n", module, loc); - QS_ASSERTION(module, loc, 10000U); /* report assertion to QS */ -} - -/* QS callbacks ============================================================*/ -#ifdef Q_SPY - -#include "qs_pkg.h" /* QS package-scope interface for QS_rxPriv_ */ -#include /* for TCP/IP transport used by QS */ - -#define QS_TX_SIZE (8*1024) -#define QS_RX_SIZE (2*1024) -#define QS_TX_CHUNK QS_TX_SIZE -#define QS_TIMEOUT_MS 10 - -/* local variables .........................................................*/ -static SOCKET l_sock = INVALID_SOCKET; - -/*..........................................................................*/ -uint8_t QS_onStartup(void const* arg) { - static uint8_t qsBuf[QS_TX_SIZE]; /* buffer for QS-TX channel */ - static uint8_t qsRxBuf[QS_RX_SIZE]; /* buffer for QS-RX channel */ - char hostName[128]; - char const* serviceName = "6601"; /* default QSPY server port */ - char const* src; - char* dst; - int status; - - struct addrinfo* result = NULL; - struct addrinfo* rp = NULL; - struct addrinfo hints; - BOOL sockopt_bool; - ULONG ioctl_opt; - WSADATA wsaData; - - /* initialize the QS transmit and receive buffers */ - QS_initBuf(qsBuf, sizeof(qsBuf)); - QS_rxInitBuf(qsRxBuf, sizeof(qsRxBuf)); - - /* initialize Windows sockets version 2.2 */ - if (WSAStartup(MAKEWORD(2, 2), &wsaData) != NO_ERROR) { - fprintf_s(stderr, " ERROR %s\n", - "Windows Sockets cannot be initialized"); - goto error; - } - - /* extract hostName from 'arg' (hostName:port_remote)... */ - src = (arg != (void*)0) - ? (char const*)arg - : "localhost"; /* default QSPY host */ - dst = hostName; - while ((*src != '\0') - && (*src != ':') - && (dst < &hostName[sizeof(hostName) - 1])) - { - *dst++ = *src++; - } - *dst = '\0'; /* zero-terminate hostName */ - - /* extract serviceName from 'arg' (hostName:serviceName)... */ - if (*src == ':') { - serviceName = src + 1; - } - - memset(&hints, 0, sizeof(hints)); - hints.ai_family = AF_INET; - hints.ai_socktype = SOCK_STREAM; - hints.ai_protocol = IPPROTO_TCP; - status = getaddrinfo(hostName, serviceName, &hints, &result); - if (status != 0) { - fprintf_s(stderr, - " ERROR cannot resolve host Name=%s:%s,Err=%d\n", - hostName, serviceName, status); - goto error; - } - - for (rp = result; rp != NULL; rp = rp->ai_next) { - l_sock = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol); - if (l_sock != INVALID_SOCKET) { - if (connect(l_sock, rp->ai_addr, (int)rp->ai_addrlen) - == SOCKET_ERROR) - { - closesocket(l_sock); - l_sock = INVALID_SOCKET; - } - break; - } - } - - freeaddrinfo(result); - - /* socket could not be opened & connected? */ - if (l_sock == INVALID_SOCKET) { - fprintf_s(stderr, " ERROR cannot connect to QSPY at " - "host=%s:%s\n", - hostName, serviceName); - goto error; - } - - /* set the socket to non-blocking mode */ - ioctl_opt = 1; - if (ioctlsocket(l_sock, FIONBIO, &ioctl_opt) != NO_ERROR) { - fprintf_s(stderr, " ERROR %s WASErr=%d\n,", - "Failed to set non-blocking socket", WSAGetLastError()); - goto error; - } - - /* configure the socket to reuse the address and not to linger */ - sockopt_bool = TRUE; - setsockopt(l_sock, SOL_SOCKET, SO_REUSEADDR, - (const char*)&sockopt_bool, sizeof(sockopt_bool)); - sockopt_bool = TRUE; - setsockopt(l_sock, SOL_SOCKET, SO_DONTLINGER, - (const char*)&sockopt_bool, sizeof(sockopt_bool)); - QS_onFlush(); - - return 1U; /* success */ - -error: - return 0U; /* failure */ -} -/*..........................................................................*/ -void QS_onCleanup(void) { - if (l_sock != INVALID_SOCKET) { - closesocket(l_sock); - l_sock = INVALID_SOCKET; - } - WSACleanup(); - printf_s(" Disconnected from QSPY\n"); -} -/*..........................................................................*/ -void QS_onReset(void) { - QS_onCleanup(); - exit(0); -} -/*..........................................................................*/ -void QS_onFlush(void) { - uint16_t nBytes; - uint8_t const* data; - QS_CRIT_STAT_ - - if (l_sock == INVALID_SOCKET) { /* socket NOT initialized? */ - fprintf_s(stderr, " ERROR %s\n", - "invalid TCP socket"); - return; - } - - nBytes = QS_TX_CHUNK; - QS_CRIT_E_(); - while ((data = QS_getBlock(&nBytes)) != (uint8_t*)0) { - QS_CRIT_X_(); - for (;;) { /* for-ever until break or return */ - int nSent = send(l_sock, (char const*)data, (int)nBytes, 0); - if (nSent == SOCKET_ERROR) { /* sending failed? */ - int err = WSAGetLastError(); - if (err == WSAEWOULDBLOCK) { - /* sleep for the timeout and then loop back - * to send() the SAME data again - */ - Sleep(QS_TIMEOUT_MS); - } - else { /* some other socket error... */ - fprintf_s(stderr, " ERROR %s WASErr=%d\n", - "sending data over TCP", err); - return; - } - } - else if (nSent < (int)nBytes) { /* sent fewer than requested? */ - Sleep(QS_TIMEOUT_MS); /* sleep for the timeout */ - /* adjust the data and loop back to send() the rest */ - data += nSent; - nBytes -= (uint16_t)nSent; - } - else { - break; /* break out of the for-ever loop */ - } - } - /* set nBytes for the next call to QS_getBlock() */ - nBytes = QS_TX_CHUNK; - QS_CRIT_E_(); - } - QS_CRIT_X_(); -} -/*..........................................................................*/ -QSTimeCtr QS_onGetTime(void) { - LARGE_INTEGER time; - QueryPerformanceCounter(&time); - return (QSTimeCtr)time.QuadPart; -} -/*..........................................................................*/ -/*! callback function to execute a user command (to be implemented in BSP) */ -void QS_onCommand(uint8_t cmdId, - uint32_t param1, uint32_t param2, uint32_t param3) -{ - (void)cmdId; - (void)param1; - (void)param2; - (void)param3; - QS_BEGIN_ID(COMMAND_STAT, 0U) /* app-specific record */ - QS_U8(2, cmdId); - QS_U32(8, param1); - QS_U32(8, param2); - QS_U32(8, param3); - QS_END() -} - -/*..........................................................................*/ -static void QS_output(void) { - uint16_t nBytes; - uint8_t const* data; - QS_CRIT_STAT_ - - if (l_sock == INVALID_SOCKET) { /* socket NOT initialized? */ - fprintf_s(stderr, " ERROR %s\n", - "invalid TCP socket"); - return; - } - - nBytes = QS_TX_CHUNK; - QS_CRIT_E_(); - if ((data = QS_getBlock(&nBytes)) != (uint8_t*)0) { - QS_CRIT_X_(); - for (;;) { /* for-ever until break or return */ - int nSent = send(l_sock, (char const*)data, (int)nBytes, 0); - if (nSent == SOCKET_ERROR) { /* sending failed? */ - int err = WSAGetLastError(); - if (err == WSAEWOULDBLOCK) { - /* sleep for the timeout and then loop back - * to send() the SAME data again - */ - Sleep(QS_TIMEOUT_MS); - } - else { /* some other socket error... */ - fprintf_s(stderr, " ERROR sending data over TCP," - "WASErr=%d\n", err); - return; - } - } - else if (nSent < (int)nBytes) { /* sent fewer than requested? */ - Sleep(QS_TIMEOUT_MS); /* sleep for the timeout */ - /* adjust the data and loop back to send() the rest */ - data += nSent; - nBytes -= (uint16_t)nSent; - } - else { - break; - } - } - } - else { - QS_CRIT_X_(); - } -} -/*..........................................................................*/ -static void QS_rx_input(void) { - int status = recv(l_sock, (char*)QS_rxPriv_.buf, (int)QS_rxPriv_.end, 0); - if (status > 0) { /* any data received? */ - QS_rxPriv_.tail = 0U; - QS_rxPriv_.head = status; /* # bytes received */ - QS_rxParse(); /* parse all received bytes */ - } -} - -#endif /* Q_SPY */ -/*--------------------------------------------------------------------------*/ - -/***************************************************************************** -* NOTE1: -* This application uses the ThreadX thread of the lowest priority to perform -* the QS data output to the host. This is not the only choice available, and -* other applications might choose to peform the QS output some other way. -* -* The lowest-priority thread does not block, so in effect, it becomes the -* idle loop. This presents no problems to ThreadX - its idle task in the -* scheduler does not need to run. -*/ - diff --git a/examples/threadx/win32/dpp_console/bsp.h b/examples/threadx/win32/dpp_console/bsp.h deleted file mode 100644 index b699e5ba..00000000 --- a/examples/threadx/win32/dpp_console/bsp.h +++ /dev/null @@ -1,47 +0,0 @@ -/***************************************************************************** -* Product: DPP example, ThreadX -* Last Updated for Version: 6.3.8 -* Date of the Last Update: 2019-01-30 -* -* Q u a n t u m L e a P s -* ------------------------ -* Modern Embedded Software -* -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* -* -*****************************************************************************/ -#ifndef BSP_H -#define BSP_H - -#define BSP_TICKS_PER_SEC TX_TIMER_TICKS_PER_SECOND - -void BSP_init(void); -void BSP_displayPaused(uint8_t paused); -void BSP_displayPhilStat(uint8_t n, char const *stat); -void BSP_terminate(int16_t result); - -void BSP_randomSeed(uint32_t seed); /* random seed */ -uint32_t BSP_random(void); /* pseudo-random generator */ - -#endif /* BSP_H */ diff --git a/examples/threadx/win32/dpp_console/dpp.h b/examples/threadx/win32/dpp_console/dpp.h deleted file mode 100644 index c45cc7c6..00000000 --- a/examples/threadx/win32/dpp_console/dpp.h +++ /dev/null @@ -1,94 +0,0 @@ -/*$file${.::dpp.h} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* -* Model: dpp.qm -* File: ${.::dpp.h} -* -* This code has been generated by QM 5.2.4 . -* DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. -* -* SPDX-License-Identifier: GPL-3.0-or-later -* -* This generated code is open source software: you can redistribute it under -* the terms of the GNU General Public License as published by the Free -* Software Foundation. -* -* This code is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -* more details. -* -* NOTE: -* Alternatively, this generated code may be distributed under the terms -* of Quantum Leaps commercial licenses, which expressly supersede the GNU -* General Public License and are specifically designed for licensees -* interested in retaining the proprietary status of their code. -* -* Contact information: -* -* -*/ -/*$endhead${.::dpp.h} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -#ifndef DPP_H -#define DPP_H - -enum DPPSignals { - EAT_SIG = Q_USER_SIG, /* published by Table to let a philosopher eat */ - DONE_SIG, /* published by Philosopher when done eating */ - PAUSE_SIG, /* published by BSP to pause serving forks */ - SERVE_SIG, /* published by BSP to serve re-start serving forks */ - TEST_SIG, /* published by BSP to test the application */ - MAX_PUB_SIG, /* the last published signal */ - - HUNGRY_SIG, /* posted direclty to Table from hungry Philo */ - TIMEOUT_SIG, /* used by Philosophers for time events */ - MAX_SIG /* the last signal */ -}; - -/*$declare${Events::TableEvt} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${Events::TableEvt} ......................................................*/ -typedef struct { -/* protected: */ - QEvt super; - -/* public: */ - uint8_t philoNum; -} TableEvt; -/*$enddecl${Events::TableEvt} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ - -/* number of philosophers */ -#define N_PHILO ((uint8_t)5) - -/*$declare${AOs::Philo_ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${AOs::Philo_ctor} .......................................................*/ -void Philo_ctor(void); -/*$enddecl${AOs::Philo_ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*$declare${AOs::AO_Philo[N_PHILO]} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${AOs::AO_Philo[N_PHILO]} ................................................*/ -/* opaque pointers to the Philo AOs */ -extern QActive * const AO_Philo[N_PHILO]; -/*$enddecl${AOs::AO_Philo[N_PHILO]} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ - -/*$declare${AOs::Table_ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${AOs::Table_ctor} .......................................................*/ -void Table_ctor(void); -/*$enddecl${AOs::Table_ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*$declare${AOs::AO_Table} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${AOs::AO_Table} .........................................................*/ -/* opaque pointer to the Table AO */ -extern QActive * const AO_Table; -/*$enddecl${AOs::AO_Table} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ - -#ifdef QP_INC_QXK_H_ - void Test1_ctor(void); - extern QXThread * const XT_Test1; - void Test2_ctor(void); - extern QXThread * const XT_Test2; -#endif /* QP_INC_QXK_H_ */ - -#endif /* DPP_H */ - diff --git a/examples/threadx/win32/dpp_console/dpp.qm b/examples/threadx/win32/dpp_console/dpp.qm deleted file mode 100644 index 79ff1da8..00000000 --- a/examples/threadx/win32/dpp_console/dpp.qm +++ /dev/null @@ -1,470 +0,0 @@ - - - Dining Philosopher Problem example - - - - - - - - - - - - - - - - - - - - - static uint8_t registered = (uint8_t)0; /* starts off with 0, per C-standard */ -(void)par; /* unused parameter */ -if (registered == (uint8_t)0) { - registered = (uint8_t)1; - - QS_OBJ_DICTIONARY(&l_philo[0].timeEvt); - QS_OBJ_DICTIONARY(&l_philo[1].timeEvt); - QS_OBJ_DICTIONARY(&l_philo[2].timeEvt); - QS_OBJ_DICTIONARY(&l_philo[3].timeEvt); - QS_OBJ_DICTIONARY(&l_philo[4].timeEvt); - - QS_FUN_DICTIONARY(&Philo_initial); - QS_FUN_DICTIONARY(&Philo_thinking); - QS_FUN_DICTIONARY(&Philo_hungry); - QS_FUN_DICTIONARY(&Philo_eating); -} -QS_SIG_DICTIONARY(HUNGRY_SIG, me); /* signal for each Philos */ -QS_SIG_DICTIONARY(TIMEOUT_SIG, me); /* signal for each Philos */ - -QActive_subscribe(&me->super, EAT_SIG); -QActive_subscribe(&me->super, TEST_SIG); - - - - - - - QTimeEvt_armX(&me->timeEvt, THINK_TIME, 0U); - QTimeEvt_disarm(&me->timeEvt); - - - - - - - - - /* EAT or DONE must be for other Philos than this one */ -Q_ASSERT_ID(10, Q_EVT_CAST(TableEvt)->philoNum != PHILO_ID(me)); - - - - - - - - - - - - TableEvt *pe = Q_NEW(TableEvt, HUNGRY_SIG); -pe->philoNum = PHILO_ID(me); -QACTIVE_POST(AO_Table, &pe->super, me); - - - - - Q_EVT_CAST(TableEvt)->philoNum == PHILO_ID(me) - - - - - - - - - - - /* DONE must be for other Philos than this one */ -Q_ASSERT_ID(20, Q_EVT_CAST(TableEvt)->philoNum != PHILO_ID(me)); - - - - - - - - - - - QTimeEvt_armX(&me->timeEvt, EAT_TIME, 0U); - TableEvt *pe = Q_NEW(TableEvt, DONE_SIG); -pe->philoNum = PHILO_ID(me); -QACTIVE_PUBLISH(&pe->super, &me->super); -QTimeEvt_disarm(&me->timeEvt); - - - - - - - - - /* EAT or DONE must be for other Philos than this one */ -Q_ASSERT_ID(30, Q_EVT_CAST(TableEvt)->philoNum != PHILO_ID(me)); - - - - - - - - - - - - - - - - - - - - - - - uint8_t n; -(void)par; /* unused parameter */ - -QS_SIG_DICTIONARY(DONE_SIG, (void *)0); /* global signals */ -QS_SIG_DICTIONARY(EAT_SIG, (void *)0); -QS_SIG_DICTIONARY(PAUSE_SIG, (void *)0); -QS_SIG_DICTIONARY(SERVE_SIG, (void *)0); -QS_SIG_DICTIONARY(TEST_SIG, (void *)0); - -QS_SIG_DICTIONARY(HUNGRY_SIG, me); /* signal just for Table */ - -QActive_subscribe(&me->super, DONE_SIG); -QActive_subscribe(&me->super, PAUSE_SIG); -QActive_subscribe(&me->super, SERVE_SIG); -QActive_subscribe(&me->super, TEST_SIG); - -for (n = 0U; n < N_PHILO; ++n) { - me->fork[n] = FREE; - me->isHungry[n] = 0U; - BSP_displayPhilStat(n, "thinking"); -} - - - - - - - - - Q_ERROR_ID(60); - - - - - - - uint8_t n; -for (n = 0U; n < N_PHILO; ++n) { /* give permissions to eat... */ - if ((me->isHungry[n] != 0U) - && (me->fork[LEFT(n)] == FREE) - && (me->fork[n] == FREE)) - { - TableEvt *te; - - me->fork[LEFT(n)] = USED; - me->fork[n] = USED; - te = Q_NEW(TableEvt, EAT_SIG); - te->philoNum = n; - QACTIVE_PUBLISH(&te->super, &me->super); - me->isHungry[n] = 0U; - BSP_displayPhilStat(n, "eating "); - } -} - - - uint8_t n, m; - -n = Q_EVT_CAST(TableEvt)->philoNum; -/* phil ID must be in range and he must be not hungry */ -Q_ASSERT_ID(40, (n < N_PHILO) && (me->isHungry[n] == 0U)); - -BSP_displayPhilStat(n, "hungry "); -m = LEFT(n); - - - (me->fork[m] == FREE) && (me->fork[n] == FREE) - TableEvt *pe; -me->fork[m] = USED; -me->fork[n] = USED; -pe = Q_NEW(TableEvt, EAT_SIG); -pe->philoNum = n; -QACTIVE_PUBLISH(&pe->super, &me->super); -BSP_displayPhilStat(n, "eating "); - - - - - - - else - me->isHungry[n] = 1U; - - - - - - - - - - - uint8_t n, m; -TableEvt *pe; - -n = Q_EVT_CAST(TableEvt)->philoNum; -/* phil ID must be in range and he must be not hungry */ -Q_ASSERT_ID(50, (n < N_PHILO) && (me->isHungry[n] == 0U)); - -BSP_displayPhilStat(n, "thinking"); -m = LEFT(n); -/* both forks of Phil[n] must be used */ -Q_ASSERT_ID(51, (me->fork[n] == USED) && (me->fork[m] == USED)); - -me->fork[m] = FREE; -me->fork[n] = FREE; -m = RIGHT(n); /* check the right neighbor */ - -if ((me->isHungry[m] != 0U) && (me->fork[m] == FREE)) { - me->fork[n] = USED; - me->fork[m] = USED; - me->isHungry[m] = 0U; - pe = Q_NEW(TableEvt, EAT_SIG); - pe->philoNum = m; - QACTIVE_PUBLISH(&pe->super, &me->super); - BSP_displayPhilStat(m, "eating "); -} -m = LEFT(n); /* check the left neighbor */ -n = LEFT(m); /* left fork of the left neighbor */ -if ((me->isHungry[m] != 0U) && (me->fork[n] == FREE)) { - me->fork[m] = USED; - me->fork[n] = USED; - me->isHungry[m] = 0U; - pe = Q_NEW(TableEvt, EAT_SIG); - pe->philoNum = m; - QACTIVE_PUBLISH(&pe->super, &me->super); - BSP_displayPhilStat(m, "eating "); -} - - - - - - - - - - - - - - - - - BSP_displayPaused(1U); - BSP_displayPaused(0U); - - - - - - - - - uint8_t n = Q_EVT_CAST(TableEvt)->philoNum; -/* philo ID must be in range and he must be not hungry */ -Q_ASSERT_ID(60, (n < N_PHILO) && (me->isHungry[n] == 0U)); -me->isHungry[n] = 1U; -BSP_displayPhilStat(n, "hungry "); - - - - - - - uint8_t n, m; - -n = Q_EVT_CAST(TableEvt)->philoNum; -/* phil ID must be in range and he must be not hungry */ -Q_ASSERT_ID(70, (n < N_PHILO) && (me->isHungry[n] == 0U)); - -BSP_displayPhilStat(n, "thinking"); -m = LEFT(n); -/* both forks of Phil[n] must be used */ -Q_ASSERT_ID(71, (me->fork[n] == USED) && (me->fork[m] == USED)); - -me->fork[m] = FREE; -me->fork[n] = FREE; - - - - - - - - - - - - - - - - - /* opaque pointers to the Philo AOs */ - = { - &l_philo[0].super, - &l_philo[1].super, - &l_philo[2].super, - &l_philo[3].super, - &l_philo[4].super -}; - - - - /* opaque pointer to the Table AO */ - = &l_table.super; - - - - uint8_t n; -Philo *me; -for (n = 0U; n < N_PHILO; ++n) { - me = &l_philo[n]; - QActive_ctor(&me->super, Q_STATE_CAST(&Philo_initial)); - QTimeEvt_ctorX(&me->timeEvt, &me->super, TIMEOUT_SIG, 0U); -} - - - - uint8_t n; -Table *me = &l_table; - -QActive_ctor(&me->super, Q_STATE_CAST(&Table_initial)); - -for (n = 0U; n < N_PHILO; ++n) { - me->fork[n] = FREE; - me->isHungry[n] = 0U; -} - - - - - - - #ifndef DPP_H -#define DPP_H - -enum DPPSignals { - EAT_SIG = Q_USER_SIG, /* published by Table to let a philosopher eat */ - DONE_SIG, /* published by Philosopher when done eating */ - PAUSE_SIG, /* published by BSP to pause serving forks */ - SERVE_SIG, /* published by BSP to serve re-start serving forks */ - TEST_SIG, /* published by BSP to test the application */ - MAX_PUB_SIG, /* the last published signal */ - - HUNGRY_SIG, /* posted direclty to Table from hungry Philo */ - TIMEOUT_SIG, /* used by Philosophers for time events */ - MAX_SIG /* the last signal */ -}; - -$declare${Events::TableEvt} - -/* number of philosophers */ -#define N_PHILO ((uint8_t)5) - -$declare${AOs::Philo_ctor} -$declare${AOs::AO_Philo[N_PHILO]} - -$declare${AOs::Table_ctor} -$declare${AOs::AO_Table} - -#ifdef QP_INC_QXK_H_ - void Test1_ctor(void); - extern QXThread * const XT_Test1; - void Test2_ctor(void); - extern QXThread * const XT_Test2; -#endif /* QP_INC_QXK_H_ */ - -#endif /* DPP_H */ - - - - - #include "qpc.h" -#include "dpp.h" -#include "bsp.h" - -Q_DEFINE_THIS_MODULE("philo") - -/* Active object class -----------------------------------------------------*/ -$declare${AOs::Philo} - -/* Local objects -----------------------------------------------------------*/ -static Philo l_philo[N_PHILO]; /* storage for all Philos */ - -#define THINK_TIME \ - (QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + (BSP_TICKS_PER_SEC/2U)) -#define EAT_TIME \ - (QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + BSP_TICKS_PER_SEC) - -/* helper macro to provide the ID of Philo "me_" */ -#define PHILO_ID(me_) ((uint8_t)((me_) - l_philo)) - -/* Global objects ----------------------------------------------------------*/ -$define${AOs::AO_Philo[N_PHILO]} - -/* Philo definition --------------------------------------------------------*/ -$define${AOs::Philo_ctor} -$define${AOs::Philo} - - - - - #include "qpc.h" -#include "dpp.h" -#include "bsp.h" - -Q_DEFINE_THIS_MODULE("table") - -/* Active object class -----------------------------------------------------*/ -$declare${AOs::Table} - -#define RIGHT(n_) ((uint8_t)(((n_) + (N_PHILO - 1U)) % N_PHILO)) -#define LEFT(n_) ((uint8_t)(((n_) + 1U) % N_PHILO)) -#define FREE ((uint8_t)0) -#define USED ((uint8_t)1) - -/* Local objects -----------------------------------------------------------*/ -static Table l_table; /* the single instance of the Table active object */ - -/* Global-scope objects ----------------------------------------------------*/ -$define${AOs::AO_Table} - -/*..........................................................................*/ -$define${AOs::Table_ctor} -$define${AOs::Table} - - - - diff --git a/examples/threadx/win32/dpp_console/main.c b/examples/threadx/win32/dpp_console/main.c deleted file mode 100644 index 83ce7825..00000000 --- a/examples/threadx/win32/dpp_console/main.c +++ /dev/null @@ -1,95 +0,0 @@ -/***************************************************************************** -* Last updated for: @ref qpc_7_0_0 -* Last updated on 2021-12-05 -* -* Q u a n t u m L e a P s -* ------------------------ -* Modern Embedded Software -* -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* -* -*****************************************************************************/ -#include "qpc.h" -#include "dpp.h" -#include "bsp.h" - -Q_DEFINE_THIS_FILE - -/* Local-scope objects -----------------------------------------------------*/ -static QEvt const *l_tableQueueSto[N_PHILO]; -static QEvt const *l_philoQueueSto[N_PHILO][N_PHILO]; -static QSubscrList l_subscrSto[MAX_PUB_SIG]; - -static union SmallEvents { - void *e0; /* minimum event size */ - uint8_t e1[sizeof(TableEvt)]; - /* ... other event types to go into this pool */ -} l_smlPoolSto[2*N_PHILO + 10]; /* storage for the small event pool */ - -static ULONG l_philoStk[N_PHILO][256]; /* stacks for the Philosophers */ -static ULONG l_tableStk[256]; /* stack for the Table */ - -/*..........................................................................*/ -int main() { - Philo_ctor(); /* instantiate all Philosopher active objects */ - Table_ctor(); /* instantiate the Table active object */ - tx_kernel_enter(); - return 0; /* tx_kernel_enter() does not return */ -} -/*..........................................................................*/ -void tx_application_define(void *first_unused_memory) { - uint8_t n; - - (void)first_unused_memory; /* unused parameter */ - - BSP_init(); /* initialize the Board Support Package */ - QF_init(); /* initialize the framework and the underlying RT kernel */ - - QF_psInit(l_subscrSto, Q_DIM(l_subscrSto)); /* init publish-subscribe */ - - /* initialize event pools... */ - QF_poolInit(l_smlPoolSto, sizeof(l_smlPoolSto), sizeof(l_smlPoolSto[0])); - - QS_OBJ_DICTIONARY(l_smlPoolSto); - QS_OBJ_DICTIONARY(AO_Table); - QS_OBJ_DICTIONARY(AO_Philo[0]); - QS_OBJ_DICTIONARY(AO_Philo[1]); - QS_OBJ_DICTIONARY(AO_Philo[2]); - QS_OBJ_DICTIONARY(AO_Philo[3]); - QS_OBJ_DICTIONARY(AO_Philo[4]); - - for (n = 0; n < N_PHILO; ++n) { /* start the active objects... */ - QActive_setAttr(AO_Philo[n], THREAD_NAME_ATTR, "Philo"); - QACTIVE_START(AO_Philo[n], (uint8_t)(n + 1), - l_philoQueueSto[n], Q_DIM(l_philoQueueSto[n]), - l_philoStk[n], sizeof(l_philoStk[n]), (QEvt *)0); - } - - QActive_setAttr(AO_Table, THREAD_NAME_ATTR, "Table"); - QACTIVE_START(AO_Table, (uint8_t)(N_PHILO + 1), - l_tableQueueSto, Q_DIM(l_tableQueueSto), - l_tableStk, sizeof(l_tableStk), (QEvt *)0); - - (void)QF_run(); -} diff --git a/examples/threadx/win32/dpp_console/philo.c b/examples/threadx/win32/dpp_console/philo.c deleted file mode 100644 index 919e39d6..00000000 --- a/examples/threadx/win32/dpp_console/philo.c +++ /dev/null @@ -1,247 +0,0 @@ -/*$file${.::philo.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* -* Model: dpp.qm -* File: ${.::philo.c} -* -* This code has been generated by QM 5.2.4 . -* DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. -* -* SPDX-License-Identifier: GPL-3.0-or-later -* -* This generated code is open source software: you can redistribute it under -* the terms of the GNU General Public License as published by the Free -* Software Foundation. -* -* This code is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -* more details. -* -* NOTE: -* Alternatively, this generated code may be distributed under the terms -* of Quantum Leaps commercial licenses, which expressly supersede the GNU -* General Public License and are specifically designed for licensees -* interested in retaining the proprietary status of their code. -* -* Contact information: -* -* -*/ -/*$endhead${.::philo.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -#include "qpc.h" -#include "dpp.h" -#include "bsp.h" - -Q_DEFINE_THIS_MODULE("philo") - -/* Active object class -----------------------------------------------------*/ -/*$declare${AOs::Philo} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${AOs::Philo} ............................................................*/ -typedef struct { -/* protected: */ - QActive super; - -/* private: */ - QTimeEvt timeEvt; -} Philo; - -/* protected: */ -static QState Philo_initial(Philo * const me, void const * const par); -static QState Philo_thinking(Philo * const me, QEvt const * const e); -static QState Philo_hungry(Philo * const me, QEvt const * const e); -static QState Philo_eating(Philo * const me, QEvt const * const e); -/*$enddecl${AOs::Philo} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ - -/* Local objects -----------------------------------------------------------*/ -static Philo l_philo[N_PHILO]; /* storage for all Philos */ - -#define THINK_TIME \ - (QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + (BSP_TICKS_PER_SEC/2U)) -#define EAT_TIME \ - (QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + BSP_TICKS_PER_SEC) - -/* helper macro to provide the ID of Philo "me_" */ -#define PHILO_ID(me_) ((uint8_t)((me_) - l_philo)) - -/* Global objects ----------------------------------------------------------*/ -/*$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* Check for the minimum required QP version */ -#if (QP_VERSION < 700U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) -#error qpc version 7.0.0 or higher required -#endif -/*$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ - -/*$define${AOs::AO_Philo[N_PHILO]} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${AOs::AO_Philo[N_PHILO]} ................................................*/ -QActive * const AO_Philo[N_PHILO] = { - &l_philo[0].super, - &l_philo[1].super, - &l_philo[2].super, - &l_philo[3].super, - &l_philo[4].super -}; -/*$enddef${AOs::AO_Philo[N_PHILO]} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ - -/* Philo definition --------------------------------------------------------*/ -/*$define${AOs::Philo_ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${AOs::Philo_ctor} .......................................................*/ -void Philo_ctor(void) { - uint8_t n; - Philo *me; - for (n = 0U; n < N_PHILO; ++n) { - me = &l_philo[n]; - QActive_ctor(&me->super, Q_STATE_CAST(&Philo_initial)); - QTimeEvt_ctorX(&me->timeEvt, &me->super, TIMEOUT_SIG, 0U); - } -} -/*$enddef${AOs::Philo_ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*$define${AOs::Philo} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${AOs::Philo} ............................................................*/ - -/*${AOs::Philo::SM} ........................................................*/ -static QState Philo_initial(Philo * const me, void const * const par) { - /*${AOs::Philo::SM::initial} */ - static uint8_t registered = (uint8_t)0; /* starts off with 0, per C-standard */ - (void)par; /* unused parameter */ - if (registered == (uint8_t)0) { - registered = (uint8_t)1; - - QS_OBJ_DICTIONARY(&l_philo[0].timeEvt); - QS_OBJ_DICTIONARY(&l_philo[1].timeEvt); - QS_OBJ_DICTIONARY(&l_philo[2].timeEvt); - QS_OBJ_DICTIONARY(&l_philo[3].timeEvt); - QS_OBJ_DICTIONARY(&l_philo[4].timeEvt); - - QS_FUN_DICTIONARY(&Philo_initial); - QS_FUN_DICTIONARY(&Philo_thinking); - QS_FUN_DICTIONARY(&Philo_hungry); - QS_FUN_DICTIONARY(&Philo_eating); - } - QS_SIG_DICTIONARY(HUNGRY_SIG, me); /* signal for each Philos */ - QS_SIG_DICTIONARY(TIMEOUT_SIG, me); /* signal for each Philos */ - - QActive_subscribe(&me->super, EAT_SIG); - QActive_subscribe(&me->super, TEST_SIG); - return Q_TRAN(&Philo_thinking); -} - -/*${AOs::Philo::SM::thinking} ..............................................*/ -static QState Philo_thinking(Philo * const me, QEvt const * const e) { - QState status_; - switch (e->sig) { - /*${AOs::Philo::SM::thinking} */ - case Q_ENTRY_SIG: { - QTimeEvt_armX(&me->timeEvt, THINK_TIME, 0U); - status_ = Q_HANDLED(); - break; - } - /*${AOs::Philo::SM::thinking} */ - case Q_EXIT_SIG: { - QTimeEvt_disarm(&me->timeEvt); - status_ = Q_HANDLED(); - break; - } - /*${AOs::Philo::SM::thinking::TIMEOUT} */ - case TIMEOUT_SIG: { - status_ = Q_TRAN(&Philo_hungry); - break; - } - /*${AOs::Philo::SM::thinking::EAT, DONE} */ - case EAT_SIG: /* intentionally fall through */ - case DONE_SIG: { - /* EAT or DONE must be for other Philos than this one */ - Q_ASSERT_ID(10, Q_EVT_CAST(TableEvt)->philoNum != PHILO_ID(me)); - status_ = Q_HANDLED(); - break; - } - default: { - status_ = Q_SUPER(&QHsm_top); - break; - } - } - return status_; -} - -/*${AOs::Philo::SM::hungry} ................................................*/ -static QState Philo_hungry(Philo * const me, QEvt const * const e) { - QState status_; - switch (e->sig) { - /*${AOs::Philo::SM::hungry} */ - case Q_ENTRY_SIG: { - TableEvt *pe = Q_NEW(TableEvt, HUNGRY_SIG); - pe->philoNum = PHILO_ID(me); - QACTIVE_POST(AO_Table, &pe->super, me); - status_ = Q_HANDLED(); - break; - } - /*${AOs::Philo::SM::hungry::EAT} */ - case EAT_SIG: { - /*${AOs::Philo::SM::hungry::EAT::[Q_EVT_CAST(TableEvt)->philoNum=~} */ - if (Q_EVT_CAST(TableEvt)->philoNum == PHILO_ID(me)) { - status_ = Q_TRAN(&Philo_eating); - } - else { - status_ = Q_UNHANDLED(); - } - break; - } - /*${AOs::Philo::SM::hungry::DONE} */ - case DONE_SIG: { - /* DONE must be for other Philos than this one */ - Q_ASSERT_ID(20, Q_EVT_CAST(TableEvt)->philoNum != PHILO_ID(me)); - status_ = Q_HANDLED(); - break; - } - default: { - status_ = Q_SUPER(&QHsm_top); - break; - } - } - return status_; -} - -/*${AOs::Philo::SM::eating} ................................................*/ -static QState Philo_eating(Philo * const me, QEvt const * const e) { - QState status_; - switch (e->sig) { - /*${AOs::Philo::SM::eating} */ - case Q_ENTRY_SIG: { - QTimeEvt_armX(&me->timeEvt, EAT_TIME, 0U); - status_ = Q_HANDLED(); - break; - } - /*${AOs::Philo::SM::eating} */ - case Q_EXIT_SIG: { - TableEvt *pe = Q_NEW(TableEvt, DONE_SIG); - pe->philoNum = PHILO_ID(me); - QACTIVE_PUBLISH(&pe->super, &me->super); - QTimeEvt_disarm(&me->timeEvt); - status_ = Q_HANDLED(); - break; - } - /*${AOs::Philo::SM::eating::TIMEOUT} */ - case TIMEOUT_SIG: { - status_ = Q_TRAN(&Philo_thinking); - break; - } - /*${AOs::Philo::SM::eating::EAT, DONE} */ - case EAT_SIG: /* intentionally fall through */ - case DONE_SIG: { - /* EAT or DONE must be for other Philos than this one */ - Q_ASSERT_ID(30, Q_EVT_CAST(TableEvt)->philoNum != PHILO_ID(me)); - status_ = Q_HANDLED(); - break; - } - default: { - status_ = Q_SUPER(&QHsm_top); - break; - } - } - return status_; -} -/*$enddef${AOs::Philo} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ - diff --git a/examples/threadx/win32/dpp_console/table.c b/examples/threadx/win32/dpp_console/table.c deleted file mode 100644 index d655896e..00000000 --- a/examples/threadx/win32/dpp_console/table.c +++ /dev/null @@ -1,314 +0,0 @@ -/*$file${.::table.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* -* Model: dpp.qm -* File: ${.::table.c} -* -* This code has been generated by QM 5.2.4 . -* DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. -* -* SPDX-License-Identifier: GPL-3.0-or-later -* -* This generated code is open source software: you can redistribute it under -* the terms of the GNU General Public License as published by the Free -* Software Foundation. -* -* This code is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -* more details. -* -* NOTE: -* Alternatively, this generated code may be distributed under the terms -* of Quantum Leaps commercial licenses, which expressly supersede the GNU -* General Public License and are specifically designed for licensees -* interested in retaining the proprietary status of their code. -* -* Contact information: -* -* -*/ -/*$endhead${.::table.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -#include "qpc.h" -#include "dpp.h" -#include "bsp.h" - -Q_DEFINE_THIS_MODULE("table") - -/* Active object class -----------------------------------------------------*/ -/*$declare${AOs::Table} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${AOs::Table} ............................................................*/ -typedef struct { -/* protected: */ - QActive super; - -/* private: */ - uint8_t fork[N_PHILO]; - uint8_t isHungry[N_PHILO]; -} Table; - -/* protected: */ -static QState Table_initial(Table * const me, void const * const par); -static QState Table_active(Table * const me, QEvt const * const e); -static QState Table_serving(Table * const me, QEvt const * const e); -static QState Table_paused(Table * const me, QEvt const * const e); -/*$enddecl${AOs::Table} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ - -#define RIGHT(n_) ((uint8_t)(((n_) + (N_PHILO - 1U)) % N_PHILO)) -#define LEFT(n_) ((uint8_t)(((n_) + 1U) % N_PHILO)) -#define FREE ((uint8_t)0) -#define USED ((uint8_t)1) - -/* Local objects -----------------------------------------------------------*/ -static Table l_table; /* the single instance of the Table active object */ - -/* Global-scope objects ----------------------------------------------------*/ -/*$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* Check for the minimum required QP version */ -#if (QP_VERSION < 700U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) -#error qpc version 7.0.0 or higher required -#endif -/*$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ - -/*$define${AOs::AO_Table} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${AOs::AO_Table} .........................................................*/ -QActive * const AO_Table = &l_table.super; -/*$enddef${AOs::AO_Table} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ - -/*..........................................................................*/ -/*$define${AOs::Table_ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${AOs::Table_ctor} .......................................................*/ -void Table_ctor(void) { - uint8_t n; - Table *me = &l_table; - - QActive_ctor(&me->super, Q_STATE_CAST(&Table_initial)); - - for (n = 0U; n < N_PHILO; ++n) { - me->fork[n] = FREE; - me->isHungry[n] = 0U; - } -} -/*$enddef${AOs::Table_ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*$define${AOs::Table} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${AOs::Table} ............................................................*/ - -/*${AOs::Table::SM} ........................................................*/ -static QState Table_initial(Table * const me, void const * const par) { - /*${AOs::Table::SM::initial} */ - uint8_t n; - (void)par; /* unused parameter */ - - QS_SIG_DICTIONARY(DONE_SIG, (void *)0); /* global signals */ - QS_SIG_DICTIONARY(EAT_SIG, (void *)0); - QS_SIG_DICTIONARY(PAUSE_SIG, (void *)0); - QS_SIG_DICTIONARY(SERVE_SIG, (void *)0); - QS_SIG_DICTIONARY(TEST_SIG, (void *)0); - - QS_SIG_DICTIONARY(HUNGRY_SIG, me); /* signal just for Table */ - - QActive_subscribe(&me->super, DONE_SIG); - QActive_subscribe(&me->super, PAUSE_SIG); - QActive_subscribe(&me->super, SERVE_SIG); - QActive_subscribe(&me->super, TEST_SIG); - - for (n = 0U; n < N_PHILO; ++n) { - me->fork[n] = FREE; - me->isHungry[n] = 0U; - BSP_displayPhilStat(n, "thinking"); - } - - QS_FUN_DICTIONARY(&Table_active); - QS_FUN_DICTIONARY(&Table_serving); - QS_FUN_DICTIONARY(&Table_paused); - - return Q_TRAN(&Table_serving); -} - -/*${AOs::Table::SM::active} ................................................*/ -static QState Table_active(Table * const me, QEvt const * const e) { - QState status_; - switch (e->sig) { - /*${AOs::Table::SM::active::EAT} */ - case EAT_SIG: { - Q_ERROR_ID(60); - status_ = Q_HANDLED(); - break; - } - default: { - status_ = Q_SUPER(&QHsm_top); - break; - } - } - return status_; -} - -/*${AOs::Table::SM::active::serving} .......................................*/ -static QState Table_serving(Table * const me, QEvt const * const e) { - QState status_; - switch (e->sig) { - /*${AOs::Table::SM::active::serving} */ - case Q_ENTRY_SIG: { - uint8_t n; - for (n = 0U; n < N_PHILO; ++n) { /* give permissions to eat... */ - if ((me->isHungry[n] != 0U) - && (me->fork[LEFT(n)] == FREE) - && (me->fork[n] == FREE)) - { - TableEvt *te; - - me->fork[LEFT(n)] = USED; - me->fork[n] = USED; - te = Q_NEW(TableEvt, EAT_SIG); - te->philoNum = n; - QACTIVE_PUBLISH(&te->super, &me->super); - me->isHungry[n] = 0U; - BSP_displayPhilStat(n, "eating "); - } - } - status_ = Q_HANDLED(); - break; - } - /*${AOs::Table::SM::active::serving::HUNGRY} */ - case HUNGRY_SIG: { - uint8_t n, m; - - n = Q_EVT_CAST(TableEvt)->philoNum; - /* phil ID must be in range and he must be not hungry */ - Q_ASSERT_ID(40, (n < N_PHILO) && (me->isHungry[n] == 0U)); - - BSP_displayPhilStat(n, "hungry "); - m = LEFT(n); - /*${AOs::Table::SM::active::serving::HUNGRY::[bothfree]} */ - if ((me->fork[m] == FREE) && (me->fork[n] == FREE)) { - TableEvt *pe; - me->fork[m] = USED; - me->fork[n] = USED; - pe = Q_NEW(TableEvt, EAT_SIG); - pe->philoNum = n; - QACTIVE_PUBLISH(&pe->super, &me->super); - BSP_displayPhilStat(n, "eating "); - status_ = Q_HANDLED(); - } - /*${AOs::Table::SM::active::serving::HUNGRY::[else]} */ - else { - me->isHungry[n] = 1U; - status_ = Q_HANDLED(); - } - break; - } - /*${AOs::Table::SM::active::serving::DONE} */ - case DONE_SIG: { - uint8_t n, m; - TableEvt *pe; - - n = Q_EVT_CAST(TableEvt)->philoNum; - /* phil ID must be in range and he must be not hungry */ - Q_ASSERT_ID(50, (n < N_PHILO) && (me->isHungry[n] == 0U)); - - BSP_displayPhilStat(n, "thinking"); - m = LEFT(n); - /* both forks of Phil[n] must be used */ - Q_ASSERT_ID(51, (me->fork[n] == USED) && (me->fork[m] == USED)); - - me->fork[m] = FREE; - me->fork[n] = FREE; - m = RIGHT(n); /* check the right neighbor */ - - if ((me->isHungry[m] != 0U) && (me->fork[m] == FREE)) { - me->fork[n] = USED; - me->fork[m] = USED; - me->isHungry[m] = 0U; - pe = Q_NEW(TableEvt, EAT_SIG); - pe->philoNum = m; - QACTIVE_PUBLISH(&pe->super, &me->super); - BSP_displayPhilStat(m, "eating "); - } - m = LEFT(n); /* check the left neighbor */ - n = LEFT(m); /* left fork of the left neighbor */ - if ((me->isHungry[m] != 0U) && (me->fork[n] == FREE)) { - me->fork[m] = USED; - me->fork[n] = USED; - me->isHungry[m] = 0U; - pe = Q_NEW(TableEvt, EAT_SIG); - pe->philoNum = m; - QACTIVE_PUBLISH(&pe->super, &me->super); - BSP_displayPhilStat(m, "eating "); - } - status_ = Q_HANDLED(); - break; - } - /*${AOs::Table::SM::active::serving::PAUSE} */ - case PAUSE_SIG: { - status_ = Q_TRAN(&Table_paused); - break; - } - default: { - status_ = Q_SUPER(&Table_active); - break; - } - } - return status_; -} - -/*${AOs::Table::SM::active::paused} ........................................*/ -static QState Table_paused(Table * const me, QEvt const * const e) { - QState status_; - switch (e->sig) { - /*${AOs::Table::SM::active::paused} */ - case Q_ENTRY_SIG: { - BSP_displayPaused(1U); - status_ = Q_HANDLED(); - break; - } - /*${AOs::Table::SM::active::paused} */ - case Q_EXIT_SIG: { - BSP_displayPaused(0U); - status_ = Q_HANDLED(); - break; - } - /*${AOs::Table::SM::active::paused::SERVE} */ - case SERVE_SIG: { - status_ = Q_TRAN(&Table_serving); - break; - } - /*${AOs::Table::SM::active::paused::HUNGRY} */ - case HUNGRY_SIG: { - uint8_t n = Q_EVT_CAST(TableEvt)->philoNum; - /* philo ID must be in range and he must be not hungry */ - Q_ASSERT_ID(60, (n < N_PHILO) && (me->isHungry[n] == 0U)); - me->isHungry[n] = 1U; - BSP_displayPhilStat(n, "hungry "); - status_ = Q_HANDLED(); - break; - } - /*${AOs::Table::SM::active::paused::DONE} */ - case DONE_SIG: { - uint8_t n, m; - - n = Q_EVT_CAST(TableEvt)->philoNum; - /* phil ID must be in range and he must be not hungry */ - Q_ASSERT_ID(70, (n < N_PHILO) && (me->isHungry[n] == 0U)); - - BSP_displayPhilStat(n, "thinking"); - m = LEFT(n); - /* both forks of Phil[n] must be used */ - Q_ASSERT_ID(71, (me->fork[n] == USED) && (me->fork[m] == USED)); - - me->fork[m] = FREE; - me->fork[n] = FREE; - status_ = Q_HANDLED(); - break; - } - default: { - status_ = Q_SUPER(&Table_active); - break; - } - } - return status_; -} -/*$enddef${AOs::Table} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ - diff --git a/examples/threadx/win32/dpp_console/vs_2019/dpp.vcxproj b/examples/threadx/win32/dpp_console/vs_2019/dpp.vcxproj deleted file mode 100644 index 3655f843..00000000 --- a/examples/threadx/win32/dpp_console/vs_2019/dpp.vcxproj +++ /dev/null @@ -1,534 +0,0 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - QSpy - x64 - - - Release - Win32 - - - QSpy - Win32 - - - Release - x64 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - {8CC465F7-872E-4D03-B93C-1B64858B4E11} - dpp - Win32Proj - 10.0 - - - - Application - NotSet - v142 - - - Application - NotSet - v142 - - - Application - NotSet - true - v142 - - - Application - NotSet - true - v142 - - - Application - NotSet - v142 - - - Application - NotSet - v142 - - - - - - - - - - - - - - - - - - - - - - - - - <_ProjectFileVersion>10.0.40219.1 - $(SolutionDir)$(Configuration)\ - $(Configuration)\ - true - true - $(SolutionDir)$(Configuration)\ - $(Configuration)\ - false - false - $(SolutionDir)$(Configuration)\ - $(Configuration)\ - true - true - - - - Disabled - ..;../../../../../include;../../../../../src;../../../../../ports/threadx;../../../../../3rd_party/threadx/common/inc/;../../../../../3rd_party/threadx/ports/win32/vs_2019/inc;%(AdditionalIncludeDirectories) - WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - false - - - Default - MultiThreaded - NotUsing - Level4 - ProgramDatabase - 4127 - Default - - - %(AdditionalDependencies) - %(AdditionalLibraryDirectories) - true - Console - MachineX86 - - - cmd /c "del $(OutDir)qstamp.obj" - - - - - Disabled - ..;../../../../../include;../../../../../src;../../../../../ports/threadx;../../../../../3rd_party/threadx/common/inc/;../../../../../3rd_party/threadx/ports/win32/vs_2019/inc;%(AdditionalIncludeDirectories) - WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - false - - - Default - MultiThreaded - NotUsing - Level4 - ProgramDatabase - 4127 - Default - - - %(AdditionalDependencies) - %(AdditionalLibraryDirectories) - true - Console - - - cmd /c "del $(OutDir)qstamp.obj" - - - - - MaxSpeed - true - ..;../../../../../include;../../../../../src;../../../../../ports/threadx;../../../../../3rd_party/threadx/common/inc/;../../../../../3rd_party/threadx/ports/win32/vs_2019/inc;%(AdditionalIncludeDirectories) - NDEBUG;WIN32;_CONSOLE;%(PreprocessorDefinitions) - false - - - Default - MultiThreaded - true - NotUsing - Level4 - ProgramDatabase - 4127 - - - %(AdditionalDependencies) - %(AdditionalLibraryDirectories) - true - Console - true - true - MachineX86 - - - cmd /c "del $(OutDir)qstamp.obj" - - - - - MaxSpeed - true - ..;../../../../../include;../../../../../src;../../../../../ports/threadx;../../../../../3rd_party/threadx/common/inc/;../../../../../3rd_party/threadx/ports/win32/vs_2019/inc;%(AdditionalIncludeDirectories) - NDEBUG;WIN32;_CONSOLE;%(PreprocessorDefinitions) - false - - - Default - MultiThreaded - true - NotUsing - Level4 - ProgramDatabase - 4127 - - - %(AdditionalDependencies) - %(AdditionalLibraryDirectories) - true - Console - true - true - - - cmd /c "del $(OutDir)qstamp.obj" - - - - - Disabled - ..;../../../../../include;../../../../../src;../../../../../ports/threadx;../../../../../3rd_party/threadx/common/inc/;../../../../../3rd_party/threadx/ports/win32/vs_2019/inc;%(AdditionalIncludeDirectories) - Q_SPY;WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - false - - - Default - MultiThreaded - NotUsing - Level4 - ProgramDatabase - 4127 - - - ws2_32.lib;%(AdditionalDependencies) - %(AdditionalLibraryDirectories) - true - Console - MachineX86 - - - cmd /c "del $(OutDir)qstamp.obj" - - - - - Disabled - ..;../../../../../include;../../../../../src;../../../../../ports/threadx;../../../../../3rd_party/threadx/common/inc/;../../../../../3rd_party/threadx/ports/win32/vs_2019/inc;%(AdditionalIncludeDirectories) - Q_SPY;WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - false - - - Default - MultiThreaded - NotUsing - Level4 - ProgramDatabase - 4127 - - - ws2_32.lib;%(AdditionalDependencies) - %(AdditionalLibraryDirectories) - true - Console - - - cmd /c "del $(OutDir)qstamp.obj" - - - - - - \ No newline at end of file diff --git a/examples/threadx/win32/dpp_console/vs_2019/dpp.vcxproj.filters b/examples/threadx/win32/dpp_console/vs_2019/dpp.vcxproj.filters deleted file mode 100644 index 3414516c..00000000 --- a/examples/threadx/win32/dpp_console/vs_2019/dpp.vcxproj.filters +++ /dev/null @@ -1,687 +0,0 @@ - - - - - Application - - - Application - - - Application - - - Application - - - Application - - - QP - - - QP - - - QP - - - QP - - - QP - - - QP - - - QP - - - QP - - - QP - - - QP - - - QP_port - - - ThreadX\port - - - ThreadX\port - - - ThreadX\port - - - ThreadX\port - - - ThreadX\port - - - ThreadX\port - - - ThreadX\port - - - ThreadX\port - - - ThreadX\common - - - ThreadX\common - - - ThreadX\common - - - ThreadX\common - - - ThreadX\common - - - ThreadX\common - - - ThreadX\common - - - ThreadX\common - - - ThreadX\common - - - ThreadX\common - - - ThreadX\common - - - ThreadX\common - - - ThreadX\common - - - ThreadX\common - - - ThreadX\common - - - ThreadX\common - - - ThreadX\common - - - ThreadX\common - - - ThreadX\common - - - ThreadX\common - - - ThreadX\common - - - ThreadX\common - - - ThreadX\common - - - ThreadX\common - - - ThreadX\common - - - ThreadX\common - - - ThreadX\common - - - ThreadX\common - - - ThreadX\common - - - ThreadX\common - - - ThreadX\common - - - ThreadX\common - - - ThreadX\common - - - ThreadX\common - - - ThreadX\common - - - ThreadX\common - - - ThreadX\common - - - ThreadX\common - - - ThreadX\common - - - ThreadX\common - - - ThreadX\common - - - ThreadX\common - - - ThreadX\common - - - ThreadX\common - - - ThreadX\common - - - ThreadX\common - - - ThreadX\common - - - ThreadX\common - - - ThreadX\common - - - ThreadX\common - - - ThreadX\common - - - ThreadX\common - - - ThreadX\common - - - ThreadX\common - - - ThreadX\common - - - ThreadX\common - - - ThreadX\common - - - ThreadX\common - - - ThreadX\common - - - ThreadX\common - - - ThreadX\common - - - ThreadX\common - - - ThreadX\common - - - ThreadX\common - - - ThreadX\common - - - ThreadX\common - - - ThreadX\common - - - ThreadX\common - - - ThreadX\common - - - ThreadX\common - - - ThreadX\common - - - ThreadX\common - - - ThreadX\common - - - ThreadX\common - - - ThreadX\common - - - ThreadX\common - - - ThreadX\common - - - ThreadX\common - - - ThreadX\common - - - ThreadX\common - - - ThreadX\common - - - ThreadX\common - - - ThreadX\common - - - ThreadX\common - - - ThreadX\common - - - ThreadX\common - - - ThreadX\common - - - ThreadX\common - - - ThreadX\common - - - ThreadX\common - - - ThreadX\common - - - ThreadX\common - - - ThreadX\common - - - ThreadX\common - - - ThreadX\common - - - ThreadX\common - - - ThreadX\common - - - ThreadX\common - - - ThreadX\common - - - ThreadX\common - - - ThreadX\common - - - ThreadX\common - - - ThreadX\common - - - ThreadX\common - - - ThreadX\common - - - ThreadX\common - - - ThreadX\common - - - ThreadX\common - - - ThreadX\common - - - ThreadX\common - - - ThreadX\common - - - ThreadX\common - - - ThreadX\common - - - ThreadX\common - - - ThreadX\common - - - ThreadX\common - - - ThreadX\common - - - ThreadX\common - - - ThreadX\common - - - ThreadX\common - - - ThreadX\common - - - ThreadX\common - - - ThreadX\common - - - ThreadX\common - - - ThreadX\common - - - ThreadX\common - - - ThreadX\common - - - ThreadX\common - - - ThreadX\common - - - ThreadX\common - - - ThreadX\common - - - ThreadX\common - - - ThreadX\common - - - ThreadX\common - - - ThreadX\common - - - ThreadX\common - - - ThreadX\common - - - ThreadX\common - - - ThreadX\common - - - ThreadX\common - - - ThreadX\common - - - ThreadX\common - - - ThreadX\common - - - ThreadX\common - - - ThreadX\common - - - ThreadX\common - - - ThreadX\common - - - ThreadX\common - - - ThreadX\common - - - ThreadX\common - - - ThreadX\common - - - ThreadX\common - - - ThreadX\common - - - ThreadX\common - - - ThreadX\common - - - ThreadX\common - - - ThreadX\common - - - ThreadX\common - - - ThreadX\common - - - ThreadX\common - - - ThreadX\common - - - ThreadX\common - - - ThreadX\common - - - ThreadX\common - - - ThreadX\common - - - ThreadX\common - - - ThreadX\common - - - ThreadX\common - - - ThreadX\common - - - ThreadX\common - - - ThreadX\common - - - ThreadX\common - - - ThreadX\common - - - ThreadX\common - - - ThreadX\common - - - ThreadX\common - - - ThreadX\common - - - ThreadX\common - - - ThreadX\common - - - ThreadX\common - - - ThreadX\common - - - ThreadX\common - - - ThreadX\common - - - ThreadX\common - - - ThreadX\common - - - QS - - - QS - - - QS - - - QS - - - QP - - - - - Application - - - Application - - - QP_port - - - QP_port - - - QP_port - - - - - {0b727001-144d-4617-8d15-1011a12cf288} - - - {add14520-3b44-49c7-9197-b6768f97aa7d} - - - {e9a217a4-2a5e-4ccb-af7d-1ffe6428b16d} - - - {d400d7ba-8989-4140-b470-7c572d97558d} - - - {503258f0-f0c5-424d-8c86-efbe718de482} - - - {4df73fc6-8803-490a-8491-c7e8a5324783} - - - {b3aab5be-7f8a-4001-8984-76daf785424f} - - - \ No newline at end of file diff --git a/examples/uc-os2/arm-cm/dpp_ek-tm4c123gxl/app_cfg.h b/examples/uc-os2/arm-cm/dpp_ek-tm4c123gxl/app_cfg.h index 411393e8..ebd46b34 100644 --- a/examples/uc-os2/arm-cm/dpp_ek-tm4c123gxl/app_cfg.h +++ b/examples/uc-os2/arm-cm/dpp_ek-tm4c123gxl/app_cfg.h @@ -1,81 +1,81 @@ -/*============================================================================ -* -* Quantum Leaps, LLC. www.state-machine.com -* Customized for EK-TM4C123GXL (ARM Cortex-M4F) -* 2020-06-08 -*===========================================================================*/ -/* -********************************************************************************************************* -* EXAMPLE CODE -* -* This file is provided as an example on how to use Micrium products. -* -* Please feel free to use any application code labeled as 'EXAMPLE CODE' in -* your application products. Example code may be used as is, in whole or in -* part, or may be used as a reference only. This file can be modified as -* required to meet the end-product requirements. -* -********************************************************************************************************* -*/ +//============================================================================ +// +// Quantum Leaps, LLC. www.state-machine.com +// Customized for EK-TM4C123GXL (ARM Cortex-M4F) +// 2020-06-08 +// =========================================================================== +// +//============================================================================*************************** +// EXAMPLE CODE +// +// This file is provided as an example on how to use Micrium products. +// +// Please feel free to use any application code labeled as 'EXAMPLE CODE' in +// your application products. Example code may be used as is, in whole or in +// part, or may be used as a reference only. This file can be modified as +// required to meet the end-product requirements. +// +//============================================================================*************************** +// -/* -********************************************************************************************************* -* -* APPLICATION CONFIGURATION -* -* EXAMPLE CODE -* -* Filename : app_cfg.h -********************************************************************************************************* -*/ +// +//============================================================================*************************** +// +// APPLICATION CONFIGURATION +// +// EXAMPLE CODE +// +// Filename : app_cfg.h +//============================================================================*************************** +// #ifndef _APP_CFG_H_ #define _APP_CFG_H_ -/* -********************************************************************************************************* -* INCLUDE FILES -********************************************************************************************************* -*/ +// +//============================================================================*************************** +// INCLUDE FILES +//============================================================================*************************** +// #include #include -/* -********************************************************************************************************* -* MODULE ENABLE / DISABLE -********************************************************************************************************* -*/ +// +//============================================================================*************************** +// MODULE ENABLE / DISABLE +//============================================================================*************************** +// -/* -********************************************************************************************************* -* TASK PRIORITIES -********************************************************************************************************* -*/ +// +//============================================================================*************************** +// TASK PRIORITIES +//============================================================================*************************** +// #define APP_CFG_STARTUP_TASK_PRIO 3u #define OS_TASK_TMR_PRIO (OS_LOWEST_PRIO - 2u) -/* -********************************************************************************************************* -* TASK STACK SIZES -* Size of the task stacks (# of OS_STK entries) -********************************************************************************************************* -*/ +// +//============================================================================*************************** +// TASK STACK SIZES +// Size of the task stacks (# of OS_STK entries) +//============================================================================*************************** +// #define APP_CFG_STARTUP_TASK_STK_SIZE 128u -/* -********************************************************************************************************* -* TRACE / DEBUG CONFIGURATION -********************************************************************************************************* -*/ +// +//============================================================================*************************** +// TRACE / DEBUG CONFIGURATION +//============================================================================*************************** +// #ifndef TRACE_LEVEL_OFF #define TRACE_LEVEL_OFF 0u @@ -96,18 +96,18 @@ #define APP_TRACE_DBG(x) ((APP_TRACE_LEVEL >= TRACE_LEVEL_DBG) ? (void)(APP_TRACE x) : (void)0) -/* -********************************************************************************************************* -* CPU PORT CONFIGURATION -********************************************************************************************************* -*/ +// +//============================================================================*************************** +// CPU PORT CONFIGURATION +//============================================================================*************************** +// #define CPU_CFG_KA_IPL_BOUNDARY 4u #define CPU_CFG_NVIC_PRIO_BITS 3u -/* -********************************************************************************************************* -* MODULE END -********************************************************************************************************* -*/ +// +//============================================================================*************************** +// MODULE END +//============================================================================*************************** +// -#endif /* End of module include. */ +#endif // End of module include. diff --git a/examples/uc-os2/arm-cm/dpp_ek-tm4c123gxl/armclang/dpp.uvoptx b/examples/uc-os2/arm-cm/dpp_ek-tm4c123gxl/armclang/dpp.uvoptx index 1f01d058..d4cef862 100644 --- a/examples/uc-os2/arm-cm/dpp_ek-tm4c123gxl/armclang/dpp.uvoptx +++ b/examples/uc-os2/arm-cm/dpp_ek-tm4c123gxl/armclang/dpp.uvoptx @@ -492,6 +492,10 @@ BIN\lmidk-agdi.dll + + 0 + DLGUARM + 0 ARMRTXEVENTFLAGS @@ -605,7 +609,7 @@ 0 0 0 - ..\..\..\..\..\include\qstamp.c + ..\..\..\..\..\src\qs\qstamp.c qstamp.c 0 0 @@ -946,42 +950,6 @@ 0 0 - - 4 - 29 - 5 - 0 - 0 - 0 - ..\..\..\..\..\ports\uc-os2\qep_port.h - qep_port.h - 0 - 0 - - - 4 - 30 - 5 - 0 - 0 - 0 - ..\..\..\..\..\ports\uc-os2\qf_port.h - qf_port.h - 0 - 0 - - - 4 - 31 - 5 - 0 - 0 - 0 - ..\..\..\..\..\ports\uc-os2\qs_port.h - qs_port.h - 0 - 0 - @@ -992,7 +960,7 @@ 0 5 - 32 + 29 1 0 0 @@ -1004,7 +972,7 @@ 5 - 33 + 30 1 0 0 @@ -1016,7 +984,7 @@ 5 - 34 + 31 1 0 0 @@ -1028,7 +996,7 @@ 5 - 35 + 32 1 0 0 @@ -1048,7 +1016,7 @@ 0 6 - 36 + 33 1 0 0 @@ -1060,7 +1028,7 @@ 6 - 37 + 34 1 0 0 @@ -1072,7 +1040,7 @@ 6 - 38 + 35 1 0 0 @@ -1084,7 +1052,7 @@ 6 - 39 + 36 1 0 0 @@ -1096,7 +1064,7 @@ 6 - 40 + 37 1 0 0 @@ -1108,7 +1076,7 @@ 6 - 41 + 38 1 0 0 @@ -1120,7 +1088,7 @@ 6 - 42 + 39 1 0 0 @@ -1132,7 +1100,7 @@ 6 - 43 + 40 1 0 0 @@ -1144,7 +1112,7 @@ 6 - 44 + 41 1 0 0 @@ -1156,7 +1124,7 @@ 6 - 45 + 42 1 0 0 @@ -1176,7 +1144,7 @@ 0 7 - 46 + 43 1 0 0 @@ -1188,7 +1156,7 @@ 7 - 47 + 44 5 0 0 @@ -1200,7 +1168,7 @@ 7 - 48 + 45 2 0 0 @@ -1212,7 +1180,7 @@ 7 - 49 + 46 1 0 0 diff --git a/examples/uc-os2/arm-cm/dpp_ek-tm4c123gxl/armclang/dpp.uvprojx b/examples/uc-os2/arm-cm/dpp_ek-tm4c123gxl/armclang/dpp.uvprojx index 23653a6d..716c72d7 100644 --- a/examples/uc-os2/arm-cm/dpp_ek-tm4c123gxl/armclang/dpp.uvprojx +++ b/examples/uc-os2/arm-cm/dpp_ek-tm4c123gxl/armclang/dpp.uvprojx @@ -337,7 +337,7 @@ 0 - __FPU_PRESENT + ..;..\..\..\..\..\include;..\..\..\..\..\ports\uc-os2;..\..\..\..\..\3rd_party\uC-OS2\Source;..\..\..\..\..\3rd_party\uC-OS2\Ports\ARM-Cortex-M\ARMv7-M\ARM;..\..\..\..\..\3rd_party\CMSIS\Include;..\..\..\..\..\3rd_party\ek-tm4c123gxl @@ -391,7 +391,7 @@ qstamp.c 1 - ..\..\..\..\..\include\qstamp.c + ..\..\..\..\..\src\qs\qstamp.c main.c @@ -538,21 +538,6 @@ 1 ..\..\..\..\..\ports\uc-os2\qf_port.c - - qep_port.h - 5 - ..\..\..\..\..\ports\uc-os2\qep_port.h - - - qf_port.h - 5 - ..\..\..\..\..\ports\uc-os2\qf_port.h - - - qs_port.h - 5 - ..\..\..\..\..\ports\uc-os2\qs_port.h - @@ -1062,7 +1047,7 @@ 0 - NDEBUG __FPU_PRESENT + NDEBUG ..;..\..\..\..\..\include;..\..\..\..\..\ports\uc-os2;..\..\..\..\..\3rd_party\uC-OS2\Source;..\..\..\..\..\3rd_party\uC-OS2\Ports\ARM-Cortex-M\ARMv7-M\ARM;..\..\..\..\..\3rd_party\CMSIS\Include;..\..\..\..\..\3rd_party\ek-tm4c123gxl @@ -1116,7 +1101,7 @@ qstamp.c 1 - ..\..\..\..\..\include\qstamp.c + ..\..\..\..\..\src\qs\qstamp.c main.c @@ -1263,21 +1248,6 @@ 1 ..\..\..\..\..\ports\uc-os2\qf_port.c - - qep_port.h - 5 - ..\..\..\..\..\ports\uc-os2\qep_port.h - - - qf_port.h - 5 - ..\..\..\..\..\ports\uc-os2\qf_port.h - - - qs_port.h - 5 - ..\..\..\..\..\ports\uc-os2\qs_port.h - @@ -1787,7 +1757,7 @@ 0 - Q_SPY __FPU_PRESENT + Q_SPY ..;..\..\..\..\..\include;..\..\..\..\..\ports\uc-os2;..\..\..\..\..\3rd_party\uC-OS2\Source;..\..\..\..\..\3rd_party\uC-OS2\Ports\ARM-Cortex-M\ARMv7-M\ARM;..\..\..\..\..\3rd_party\CMSIS\Include;..\..\..\..\..\3rd_party\ek-tm4c123gxl @@ -1841,7 +1811,7 @@ qstamp.c 1 - ..\..\..\..\..\include\qstamp.c + ..\..\..\..\..\src\qs\qstamp.c main.c @@ -1988,21 +1958,6 @@ 1 ..\..\..\..\..\ports\uc-os2\qf_port.c - - qep_port.h - 5 - ..\..\..\..\..\ports\uc-os2\qep_port.h - - - qf_port.h - 5 - ..\..\..\..\..\ports\uc-os2\qf_port.h - - - qs_port.h - 5 - ..\..\..\..\..\ports\uc-os2\qs_port.h - diff --git a/examples/uc-os2/arm-cm/dpp_ek-tm4c123gxl/bsp.c b/examples/uc-os2/arm-cm/dpp_ek-tm4c123gxl/bsp.c index ba3fdff0..1a69b35a 100644 --- a/examples/uc-os2/arm-cm/dpp_ek-tm4c123gxl/bsp.c +++ b/examples/uc-os2/arm-cm/dpp_ek-tm4c123gxl/bsp.c @@ -1,526 +1,492 @@ -/***************************************************************************** -* Product: DPP example, EK-TM4C123GLX board, uC/OS-II RTOS -* Last updated for version 7.2.0 -* Last updated on 2022-12-17 -* -* Q u a n t u m L e a P s -* ------------------------ -* Modern Embedded Software -* -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* -* -*****************************************************************************/ -#include "qpc.h" -#include "dpp.h" -#include "bsp.h" +//============================================================================ +// Product: DPP example, EK-TM4C123GLX board, uC/OS-II RTOS +// Last updated for @ref qpc_7_3_0 +// Last updated on 2023-08-22 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +//============================================================================ +#include "qpc.h" // QP/C real-time embedded framework +#include "dpp.h" // DPP Application interface +#include "bsp.h" // Board Support Package -#include "TM4C123GH6PM.h" /* the device specific header (TI) */ -#include "rom.h" /* the built-in ROM functions (TI) */ -#include "sysctl.h" /* system control driver (TI) */ -#include "gpio.h" /* GPIO driver (TI) */ -/* add other drivers if necessary... */ +#include "TM4C123GH6PM.h" // the device specific header (TI) +#include "rom.h" // the built-in ROM functions (TI) +#include "sysctl.h" // system control driver (TI) +#include "gpio.h" // GPIO driver (TI) +// add other drivers if necessary... Q_DEFINE_THIS_FILE -/* Local-scope objects -----------------------------------------------------*/ -/* LEDs on the board */ -#define LED_RED (1U << 1) -#define LED_GREEN (1U << 3) -#define LED_BLUE (1U << 2) +// Local-scope objects ----------------------------------------------------- +// LEDs on the board +#define LED_RED (1U << 1U) +#define LED_GREEN (1U << 3U) +#define LED_BLUE (1U << 2U) -/* Buttons on the board */ -#define BTN_SW1 (1U << 4) -#define BTN_SW2 (1U << 0) +// Buttons on the board +#define BTN_SW1 (1U << 4U) +#define BTN_SW2 (1U << 0U) -static uint32_t l_rnd; /* random seed */ +static uint32_t l_rndSeed; #ifdef Q_SPY - /* QSpy source IDs */ + // QSpy source IDs static QSpyId const l_tickHook = { 0U }; static QSpyId const l_GPIOPortA_IRQHandler = { 0U }; #define UART_BAUD_RATE 115200U - #define UART_FR_TXFE (1U << 7) - #define UART_FR_RXFE (1U << 4) + #define UART_FR_TXFE (1U << 7U) + #define UART_FR_RXFE (1U << 4U) #define UART_TXFIFO_DEPTH 16U - enum AppRecords { /* application-specific trace records */ + enum AppRecords { // application-specific trace records PHILO_STAT = QS_USER, PAUSED_STAT, - COMMAND_STAT }; #endif -/* ISRs used in the application ==========================================*/ -/* example ISR handler for uCOS-II */ -void GPIOPortA_IRQHandler(void); -void GPIOPortA_IRQHandler(void) { -#if OS_CRITICAL_METHOD == 3u /* Allocate storage for CPU status register */ - OS_CPU_SR cpu_sr; -#endif +//============================================================================ +// Error handler and ISRs... - OS_ENTER_CRITICAL(); - OSIntEnter(); /* Tell uC/OS-II that we are starting an ISR */ - OS_EXIT_CRITICAL(); +Q_NORETURN Q_onError(char const * const module, int_t const id) { + // NOTE: this implementation of the error handler is intended only + // for debugging and MUST be changed for deployment of the application + // (assuming that you ship your production code with assertions enabled). + Q_UNUSED_PAR(module); + Q_UNUSED_PAR(id); + QS_ASSERTION(module, id, 10000U); // report assertion to QS - /* perform the application work... */ - QACTIVE_POST(AO_Table, Q_NEW(QEvt, MAX_SIG), /* for testing... */ - &l_GPIOPortA_IRQHandler); - - OSIntExit(); /* Tell uC/OS-II that we are leaving the ISR */ -} - -/* uCOS-II application hooks ===============================================*/ -void App_TaskCreateHook (OS_TCB *ptcb) { (void)ptcb; } -void App_TaskDelHook (OS_TCB *ptcb) { (void)ptcb; } -/*..........................................................................*/ -void App_TaskIdleHook(void) { -#if OS_CRITICAL_METHOD == 3u /* Allocate storage for CPU status register */ - OS_CPU_SR cpu_sr; -#endif - - /* toggle LED2 on and then off, see NOTE01 */ - OS_ENTER_CRITICAL(); - GPIOF_AHB->DATA_Bits[LED_BLUE] = 0xFFU; /* turn the LED on */ - GPIOF_AHB->DATA_Bits[LED_BLUE] = 0x00U; /* turn the LED off */ - OS_EXIT_CRITICAL(); - -#ifdef Q_SPY - if ((UART0->FR & UART_FR_TXFE) != 0) { /* TX done? */ - uint16_t fifo = UART_TXFIFO_DEPTH; /* max bytes we can accept */ - uint8_t const *block; - - OS_EXIT_CRITICAL(); - block = QS_getBlock(&fifo); /* try to get next block to transmit */ - OS_EXIT_CRITICAL(); - - while (fifo-- != 0) { /* any bytes in the block? */ - UART0->DR = *block++; /* put into the FIFO */ - } +#ifndef NDEBUG + // light up all LEDs + GPIOF_AHB->DATA_Bits[LED_GREEN | LED_RED | LED_BLUE] = 0xFFU; + for (;;) { // for debugging, hang on in an endless loop... + } +#else + NVIC_SystemReset(); + for (;;) { // explicitly "no-return" } -#elif defined NDEBUG - /* Put the CPU and peripherals to the low-power mode. - * you might need to customize the clock management for your application, - * see the datasheet for your particular Cortex-M3 MCU. - */ - __WFI(); /* Wait-For-Interrupt */ #endif } -/*..........................................................................*/ -void App_TaskReturnHook (OS_TCB *ptcb) { (void)ptcb; } -void App_TaskStatHook (void) {} -void App_TaskSwHook (void) {} -void App_TCBInitHook (OS_TCB *ptcb) { (void)ptcb; } -/*..........................................................................*/ +//............................................................................ +void assert_failed(char const * const module, int_t const id); // prototype +void assert_failed(char const * const module, int_t const id) { + Q_onError(module, id); +} + +// uCOS-II application hooks =============================================== + void App_TimeTickHook(void) { - QTIMEEVT_TICK_X(0U, &l_tickHook); /* process time events for rate 0 */ + QTIMEEVT_TICK_X(0U, &l_tickHook); // time events at rate 0 - /* Perform the debouncing of buttons. The algorithm for debouncing - * adapted from the book "Embedded Systems Dictionary" by Jack Ganssle - * and Michael Barr, page 71. - */ - /* state of the button debouncing, see below */ - static struct ButtonsDebouncing { + // Perform the debouncing of buttons. The algorithm for debouncing + // adapted from the book "Embedded Systems Dictionary" by Jack Ganssle + // and Michael Barr, page 71. + static struct { uint32_t depressed; uint32_t previous; } buttons = { 0U, 0U }; - uint32_t current = ~GPIOF_AHB->DATA_Bits[BTN_SW1 | BTN_SW2]; /* read SW1&SW2 */ - uint32_t tmp = buttons.depressed; /* save debounced depressed buttons */ - buttons.depressed |= (buttons.previous & current); /* set depressed */ - buttons.depressed &= (buttons.previous | current); /* clear released */ - buttons.previous = current; /* update the history */ - tmp ^= buttons.depressed; /* changed debounced depressed */ - if ((tmp & BTN_SW1) != 0U) { /* debounced SW1 state changed? */ - if ((buttons.depressed & BTN_SW1) != 0U) { /* is SW1 depressed? */ - static QEvt const pauseEvt = { PAUSE_SIG, 0U, 0U}; + uint32_t current = ~GPIOF_AHB->DATA_Bits[BTN_SW1 | BTN_SW2]; + uint32_t tmp = buttons.depressed; // save debounced depressed buttons + buttons.depressed |= (buttons.previous & current); // set depressed + buttons.depressed &= (buttons.previous | current); // clear released + buttons.previous = current; // update the history + tmp ^= buttons.depressed; // changed debounced depressed + current = buttons.depressed; + + if ((tmp & BTN_SW1) != 0U) { // debounced SW1 state changed? + if ((current & BTN_SW1) != 0U) { // is SW1 depressed? + static QEvt const pauseEvt = QEVT_INITIALIZER(PAUSE_SIG); QACTIVE_PUBLISH(&pauseEvt, &l_tickHook); } - else { /* the button is released */ - static QEvt const serveEvt = { SERVE_SIG, 0U, 0U}; + else { // the button is released + static QEvt const serveEvt = QEVT_INITIALIZER(SERVE_SIG); QACTIVE_PUBLISH(&serveEvt, &l_tickHook); } } } +//............................................................................ +void App_TaskCreateHook (OS_TCB *ptcb) { (void)ptcb; } +void App_TaskDelHook (OS_TCB *ptcb) { (void)ptcb; } +//............................................................................ +void App_TaskIdleHook(void) { + // toggle the User LED on and then off, see NOTE3 + QF_CRIT_STAT + QF_CRIT_ENTRY(); + GPIOF_AHB->DATA_Bits[LED_BLUE] = 0xFFU; // turn the Blue LED on + GPIOF_AHB->DATA_Bits[LED_BLUE] = 0U; // turn the Blue LED off + QF_CRIT_EXIT(); -/* BSP functions ===========================================================*/ -/* MPU setup for TM4C123GXL MCU */ -static void TM4C123GXL_MPU_setup(void) { - /* The following MPU configuration contains the general TM4C memory map. - * - * Please note that the actual TM4C MCUs provide much less Flash and SRAM - * than the maximums configured here. This means that actual MCUs have - * unmapped memory regions (e.g., beyond the actual SRAM). Attempts to - * access these regions causes the HardFault exception, which is the - * desired behavior. - */ - static struct { - uint32_t rbar; - uint32_t rasr; - } const mpu_setup[] = { - { /* region #0: Flash: base=0x0000'0000, size=512M=2^(28+1) */ - 0x00000000U /* base address */ - | MPU_RBAR_VALID_Msk /* valid region */ - | (MPU_RBAR_REGION_Msk & 0U), /* region #0 */ - (28U << MPU_RASR_SIZE_Pos) /* 2^(18+1) region */ - | (0x6U << MPU_RASR_AP_Pos) /* PA:ro/UA:ro */ - | (1U << MPU_RASR_C_Pos) /* C=1 */ - | MPU_RASR_ENABLE_Msk /* region enable */ - }, + // Some floating point code is to exercise the VFP... + float volatile x = 1.73205F; + x = x * 1.73205F; - { /* region #1: SRAM: base=0x2000'0000, size=512M=2^(28+1) */ - 0x20000000U /* base address */ - | MPU_RBAR_VALID_Msk /* valid region */ - | (MPU_RBAR_REGION_Msk & 1U), /* region #1 */ - (28U << MPU_RASR_SIZE_Pos) /* 2^(28+1) region */ - | (0x3U << MPU_RASR_AP_Pos) /* PA:rw/UA:rw */ - | (1U << MPU_RASR_XN_Pos) /* XN=1 */ - | (1U << MPU_RASR_S_Pos) /* S=1 */ - | (1U << MPU_RASR_C_Pos) /* C=1 */ - | MPU_RASR_ENABLE_Msk /* region enable */ - }, +#ifdef Q_SPY + QF_CRIT_ENTRY(); + QS_rxParse(); // parse all the received bytes + QF_CRIT_EXIT(); - /* region #3: (not configured) */ - { MPU_RBAR_VALID_Msk | (MPU_RBAR_REGION_Msk & 2U), 0U }, + if ((UART0->FR & UART_FR_TXFE) != 0U) { // TX done? + uint16_t fifo = UART_TXFIFO_DEPTH; // max bytes we can accept - { /* region #3: Peripherals: base=0x4000'0000, size=512M=2^(28+1) */ - 0x40000000U /* base address */ - | MPU_RBAR_VALID_Msk /* valid region */ - | (MPU_RBAR_REGION_Msk & 3U), /* region #3 */ - (28U << MPU_RASR_SIZE_Pos) /* 2^(28+1) region */ - | (0x3U << MPU_RASR_AP_Pos) /* PA:rw/UA:rw */ - | (1U << MPU_RASR_XN_Pos) /* XN=1 */ - | (1U << MPU_RASR_S_Pos) /* S=1 */ - | (1U << MPU_RASR_B_Pos) /* B=1 */ - | MPU_RASR_ENABLE_Msk /* region enable */ - }, + QF_CRIT_ENTRY(); + uint8_t const *block = QS_getBlock(&fifo); + QF_CRIT_EXIT(); - { /* region #4: Priv. Periph: base=0xE000'0000, size=512M=2^(28+1) */ - 0xE0000000U /* base address */ - | MPU_RBAR_VALID_Msk /* valid region */ - | (MPU_RBAR_REGION_Msk & 4U), /* region #4 */ - (28U << MPU_RASR_SIZE_Pos) /* 2^(28+1) region */ - | (0x3U << MPU_RASR_AP_Pos) /* PA:rw/UA:rw */ - | (1U << MPU_RASR_XN_Pos) /* XN=1 */ - | (1U << MPU_RASR_S_Pos) /* S=1 */ - | (1U << MPU_RASR_B_Pos) /* B=1 */ - | MPU_RASR_ENABLE_Msk /* region enable */ - }, + while (fifo-- != 0U) { // any bytes in the block? + UART0->DR = *block++; // put into the FIFO + } + } +#elif defined NDEBUG + // Put the CPU and peripherals to the low-power mode. + // you might need to customize the clock management for your application, + // see the datasheet for your particular Cortex-M MCU. + __WFI(); // Wait-For-Interrupt +#endif +} +//............................................................................ +void App_TaskReturnHook (OS_TCB *ptcb) { (void)ptcb; } +void App_TaskStatHook (void) {} +void App_TaskSwHook (void) {} +void App_TCBInitHook (OS_TCB *ptcb) { (void)ptcb; } - { /* region #5: Ext RAM: base=0x6000'0000, size=1G=2^(29+1) */ - 0x60000000U /* base address */ - | MPU_RBAR_VALID_Msk /* valid region */ - | (MPU_RBAR_REGION_Msk & 5U), /* region #5 */ - (29U << MPU_RASR_SIZE_Pos) /* 2^(28+1) region */ - | (0x3U << MPU_RASR_AP_Pos) /* PA:rw/UA:rw */ - | (1U << MPU_RASR_XN_Pos) /* XN=1 */ - | (1U << MPU_RASR_S_Pos) /* S=1 */ - | (1U << MPU_RASR_B_Pos) /* B=1 */ - | MPU_RASR_ENABLE_Msk /* region enable */ - }, +// ISRs used in the application ============================================ - { /* region #6: Ext Dev: base=0xA000'0000, size=1G=2^(29+1) */ - 0xA0000000U /* base address */ - | MPU_RBAR_VALID_Msk /* valid region */ - | (MPU_RBAR_REGION_Msk & 6U), /* region #6 */ - (29U << MPU_RASR_SIZE_Pos) /* 2^(28+1) region */ - | (0x3U << MPU_RASR_AP_Pos) /* PA:rw/UA:rw */ - | (1U << MPU_RASR_XN_Pos) /* XN=1 */ - | (1U << MPU_RASR_S_Pos) /* S=1 */ - | (1U << MPU_RASR_B_Pos) /* B=1 */ - | MPU_RASR_ENABLE_Msk /* region enable */ - }, +#ifdef Q_SPY +// ISR for receiving bytes from the QSPY Back-End +// NOTE: This ISR is "kernel-unaware" meaning that it does not interact with +// the QF/RTOS and is not disabled. Such ISRs cannot post or publish events. - { /* region #7: NULL-pointer: base=0x000'0000, size=512B */ - 0x00000000U /* base address */ - | MPU_RBAR_VALID_Msk /* valid region */ - | (MPU_RBAR_REGION_Msk & 7U), /* region #7 */ - (8U << MPU_RASR_SIZE_Pos) /* 2^(8+1)=512B region */ - | (0x0U << MPU_RASR_AP_Pos) /* PA:na/UA:na */ - | (1U << MPU_RASR_XN_Pos) /* XN=1 */ - | MPU_RASR_ENABLE_Msk /* region enable */ - }, - }; +void UART0_IRQHandler(void); // prototype +void UART0_IRQHandler(void) { + uint32_t status = UART0->RIS; // get the raw interrupt status + UART0->ICR = status; // clear the asserted interrupts - /* enable the MemManage_Handler for MPU exception */ + while ((UART0->FR & UART_FR_RXFE) == 0U) { // while RX FIFO NOT empty + uint8_t b = (uint8_t)UART0->DR; + QS_rxPut(b); + } +} +#endif // Q_SPY + + +//============================================================================ +// BSP functions... + +void BSP_init(void) { + // Configure the MPU to prevent NULL-pointer dereferencing ... + MPU->RBAR = 0x0U // base address (NULL) + | MPU_RBAR_VALID_Msk // valid region + | (MPU_RBAR_REGION_Msk & 7U); // region #7 + MPU->RASR = (7U << MPU_RASR_SIZE_Pos) // 2^(7+1) region + | (0x0U << MPU_RASR_AP_Pos) // no-access region + | MPU_RASR_ENABLE_Msk; // region enable + MPU->CTRL = MPU_CTRL_PRIVDEFENA_Msk // enable background region + | MPU_CTRL_ENABLE_Msk; // enable the MPU + __ISB(); + __DSB(); + + // enable the MemManage_Handler for MPU exception SCB->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk; - __DSB(); - MPU->CTRL = 0U; /* disable the MPU */ - for (uint_fast8_t n = 0U; n < Q_DIM(mpu_setup); ++n) { - MPU->RBAR = mpu_setup[n].rbar; - MPU->RASR = mpu_setup[n].rasr; - } - MPU->CTRL = MPU_CTRL_ENABLE_Msk; /* enable the MPU */ - __ISB(); - __DSB(); -} - -/*..........................................................................*/ -void BSP_init(void) { - /* setup the MPU... */ - TM4C123GXL_MPU_setup(); - - /* NOTE: SystemInit() already called from the startup code - * but SystemCoreClock needs to be updated - */ + // NOTE: SystemInit() has been already called from the startup code + // but SystemCoreClock needs to be updated SystemCoreClockUpdate(); - /* enable clock for to the peripherals used by this application... */ - SYSCTL->RCGCGPIO |= (1U << 5); /* enable Run mode for GPIOF */ - SYSCTL->GPIOHBCTL |= (1U << 5); /* enable AHB for GPIOF */ + // NOTE: The VFP (hardware Floating Point) unit is configured by the RTOS + + // enable clock for to the peripherals used by this application... + SYSCTL->RCGCGPIO |= (1U << 5U); // enable Run mode for GPIOF + SYSCTL->GPIOHBCTL |= (1U << 5U); // enable AHB for GPIOF __ISB(); __DSB(); - /* configure LEDs (digital output) */ + // configure LEDs (digital output) GPIOF_AHB->DIR |= (LED_RED | LED_BLUE | LED_GREEN); GPIOF_AHB->DEN |= (LED_RED | LED_BLUE | LED_GREEN); GPIOF_AHB->DATA_Bits[LED_RED | LED_BLUE | LED_GREEN] = 0U; - /* configure switches... */ + // configure switches... - /* unlock access to the SW2 pin because it is PROTECTED */ - GPIOF_AHB->LOCK = 0x4C4F434BU; /* unlock GPIOCR register for SW2 */ - /* commit the write (cast const away) */ + // unlock access to the SW2 pin because it is PROTECTED + GPIOF_AHB->LOCK = 0x4C4F434BU; // unlock GPIOCR register for SW2 + // commit the write (cast const away) *(uint32_t volatile *)&GPIOF_AHB->CR = 0x01U; - GPIOF_AHB->DIR &= ~(BTN_SW1 | BTN_SW2); /* input */ - GPIOF_AHB->DEN |= (BTN_SW1 | BTN_SW2); /* digital enable */ - GPIOF_AHB->PUR |= (BTN_SW1 | BTN_SW2); /* pull-up resistor enable */ + GPIOF_AHB->DIR &= ~(BTN_SW1 | BTN_SW2); // input + GPIOF_AHB->DEN |= (BTN_SW1 | BTN_SW2); // digital enable + GPIOF_AHB->PUR |= (BTN_SW1 | BTN_SW2); // pull-up resistor enable *(uint32_t volatile *)&GPIOF_AHB->CR = 0x00U; - GPIOF_AHB->LOCK = 0x0; /* lock GPIOCR register for SW2 */ + GPIOF_AHB->LOCK = 0x0; // lock GPIOCR register for SW2 - /* seed the random number generator */ + // seed the random number generator BSP_randomSeed(1234U); - /* initialize the QS software tracing... */ - if (QS_INIT((void *)0) == 0U) { + // initialize the QS software tracing... + if (!QS_INIT((void *)0)) { Q_ERROR(); } + + // dictionaries... QS_OBJ_DICTIONARY(&l_tickHook); QS_OBJ_DICTIONARY(&l_GPIOPortA_IRQHandler); QS_USR_DICTIONARY(PHILO_STAT); QS_USR_DICTIONARY(PAUSED_STAT); - QS_USR_DICTIONARY(COMMAND_STAT); - /* setup the QS filters... */ - QS_GLB_FILTER(QS_ALL_RECORDS); /* all records */ - QS_GLB_FILTER(-QS_QF_TICK); /* exclude the clock tick */ + QS_ONLY(produce_sig_dict()); + + // setup the QS filters... + QS_GLB_FILTER(QS_ALL_RECORDS); // all records + QS_GLB_FILTER(-QS_QF_TICK); // exclude the clock tick } -/*..........................................................................*/ +//............................................................................ +void BSP_start(void) { + // initialize event pools + static QF_MPOOL_EL(TableEvt) smlPoolSto[2*N_PHILO]; + QF_poolInit(smlPoolSto, sizeof(smlPoolSto), sizeof(smlPoolSto[0])); + + // initialize publish-subscribe + static QSubscrList subscrSto[MAX_PUB_SIG]; + QActive_psInit(subscrSto, Q_DIM(subscrSto)); + + // instantiate and start AOs/threads... + + static QEvt const *philoQueueSto[N_PHILO][10]; + static OS_STK philoStack[N_PHILO][128]; // stacks for the Philos + for (uint8_t n = 0U; n < N_PHILO; ++n) { + Philo_ctor(n); + QACTIVE_START(AO_Philo[n], + n + 3U, // QF-prio. of the AO + philoQueueSto[n], // event queue storage + Q_DIM(philoQueueSto[n]), // queue length [events] + philoStack[n], // private stack for uC/OS-II + sizeof(philoStack[n]), // stack size [bytes] + (void *)0); // no initialization param + } + + static QEvt const *tableQueueSto[N_PHILO]; + static OS_STK tableStack[128]; // stack for the Table + Table_ctor(); + QACTIVE_START(AO_Table, + N_PHILO + 7U, // QP prio. of the AO + tableQueueSto, // event queue storage + Q_DIM(tableQueueSto), // queue length [events] + tableStack, // private stack for uC/OS-II + sizeof(tableStack), // stack size [bytes] + (void *)0); // no initialization param +} +//............................................................................ void BSP_displayPhilStat(uint8_t n, char const *stat) { - /* exercise the FPU with some floating point computations */ - /* NOTE: this code can be only called from a task that created with - * the option OS_TASK_OPT_SAVE_FP. - */ - float volatile x = 3.1415926F; - x = x + 2.7182818F; + Q_UNUSED_PAR(n); GPIOF_AHB->DATA_Bits[LED_GREEN] = ((stat[0] == 'e') ? LED_GREEN : 0U); - QS_BEGIN_ID(PHILO_STAT, AO_Philo[n]->prio) /* app-specific record */ - QS_U8(1, n); /* Philosopher number */ - QS_STR(stat); /* Philosopher status */ + // app-specific trace record... + QS_BEGIN_ID(PHILO_STAT, AO_Table->prio) + QS_U8(1, n); // Philosopher number + QS_STR(stat); // Philosopher status QS_END() } -/*..........................................................................*/ -void BSP_displayPaused(uint8_t paused) { +//............................................................................ +void BSP_displayPaused(uint8_t const paused) { GPIOF_AHB->DATA_Bits[LED_BLUE] = ((paused != 0U) ? LED_BLUE : 0U); - QS_BEGIN_ID(PAUSED_STAT, 0U) /* app-specific record */ - QS_U8(1, paused); /* Paused status */ + // application-specific trace record + QS_BEGIN_ID(PAUSED_STAT, AO_Table->prio) + QS_U8(1, paused); // Paused status QS_END() } -/*..........................................................................*/ -uint32_t BSP_random(void) { /* a very cheap pseudo-random-number generator */ - /* "Super-Duper" Linear Congruential Generator (LCG) - * LCG(2^32, 3*7*11*13*23, 0, seed) - */ - l_rnd = l_rnd * (3U*7U*11U*13U*23U); - return l_rnd >> 8; +//............................................................................ +void BSP_randomSeed(uint32_t const seed) { + l_rndSeed = seed; } -/*..........................................................................*/ -void BSP_randomSeed(uint32_t seed) { - l_rnd = seed; +//............................................................................ +uint32_t BSP_random(void) { // a very cheap pseudo-random-number generator + // Some floating point code is to exercise the VFP... + float volatile x = 3.1415926F; + x = x + 2.7182818F; + + OSSchedLock(); // lock uC-OS2 scheduler + // "Super-Duper" Linear Congruential Generator (LCG) + // LCG(2^32, 3*7*11*13*23, 0, seed) + uint32_t rnd = l_rndSeed * (3U*7U*11U*13U*23U); + l_rndSeed = rnd; // set for the next time + OSSchedUnlock(); // unlock uC-OS2 scheduler + + return (rnd >> 8U); } -/*..........................................................................*/ +//............................................................................ +void BSP_ledOn(void) { + GPIOF_AHB->DATA_Bits[LED_RED] = 0xFFU; +} +//............................................................................ +void BSP_ledOff(void) { + GPIOF_AHB->DATA_Bits[LED_RED] = 0x00U; +} +//............................................................................ void BSP_terminate(int16_t result) { - (void)result; + Q_UNUSED_PAR(result); } -/* QF callbacks ============================================================*/ +//============================================================================ +// QF callbacks... void QF_onStartup(void) { - /* set up the SysTick timer to fire at BSP_TICKS_PER_SEC rate - * NOTE: do NOT call OS_CPU_SysTickInit() from uC/OS-II - */ + // set up the SysTick timer to fire at BSP_TICKS_PER_SEC rate + // NOTE: do NOT call OS_CPU_SysTickInit() from uC/OS-II SysTick_Config(SystemCoreClock / BSP_TICKS_PER_SEC); - /* set priorities of ALL ISRs used in the system, see NOTE1 */ - NVIC_SetPriority(SysTick_IRQn, CPU_CFG_KA_IPL_BOUNDARY + 1U); - NVIC_SetPriority(GPIOA_IRQn, CPU_CFG_KA_IPL_BOUNDARY); - /* ... */ + // assign all priority bits for preemption-prio. and none to sub-prio. + NVIC_SetPriorityGrouping(0U); - /* enable IRQs in the NVIC... */ + // set priorities of ALL ISRs used in the system, see NOTE1 + NVIC_SetPriority(UART0_IRQn, 0U); // kernel unaware interrupt + NVIC_SetPriority(SysTick_IRQn, CPU_CFG_KA_IPL_BOUNDARY + 0U); + NVIC_SetPriority(GPIOA_IRQn, CPU_CFG_KA_IPL_BOUNDARY + 1U); + // ... + + // enable IRQs in the NVIC... NVIC_EnableIRQ(GPIOA_IRQn); - /* ... */ + +#ifdef Q_SPY + NVIC_EnableIRQ(UART0_IRQn); // UART interrupt used for QS-RX +#endif } -/*..........................................................................*/ +//............................................................................ void QF_onCleanup(void) { } -/*..........................................................................*/ -Q_NORETURN Q_onAssert(char const * const module, int_t const loc) { - /* - * NOTE: add here your application-specific error handling - */ - (void)module; - (void)loc; - QS_ASSERTION(module, loc, 10000U); /* report assertion to QS */ - -#ifndef NDEBUG - /* light up all LEDs */ - GPIOF_AHB->DATA_Bits[LED_GREEN | LED_RED | LED_BLUE] = 0xFFU; - /* for debugging, hang on in an endless loop... */ - for (;;) { - } -#endif - - NVIC_SystemReset(); -} - -/* QS callbacks ============================================================*/ +// QS callbacks ============================================================ #ifdef Q_SPY -/*..........................................................................*/ + +//............................................................................ uint8_t QS_onStartup(void const *arg) { Q_UNUSED_PAR(arg); - static uint8_t qsTxBuf[2*1024]; /* buffer for QS-TX channel */ - static uint8_t qsRxBuf[100]; /* buffer for QS-RX channel */ + static uint8_t qsTxBuf[2*1024]; // buffer for QS-TX channel + QS_initBuf(qsTxBuf, sizeof(qsTxBuf)); - QS_initBuf (qsTxBuf, sizeof(qsTxBuf)); + static uint8_t qsRxBuf[100]; // buffer for QS-RX channel QS_rxInitBuf(qsRxBuf, sizeof(qsRxBuf)); - /* enable clock for UART0 and GPIOA (used by UART0 pins) */ - SYSCTL->RCGCUART |= (1U << 0); /* enable Run mode for UART0 */ - SYSCTL->RCGCGPIO |= (1U << 0); /* enable Run mode for GPIOA */ + // enable clock for UART0 and GPIOA (used by UART0 pins) + SYSCTL->RCGCUART |= (1U << 0U); // enable Run mode for UART0 + SYSCTL->RCGCGPIO |= (1U << 0U); // enable Run mode for GPIOA - /* configure UART0 pins for UART operation */ - uint32_t tmp = (1U << 0) | (1U << 1); + // configure UART0 pins for UART operation + uint32_t tmp = (1U << 0U) | (1U << 1U); GPIOA->DIR &= ~tmp; GPIOA->SLR &= ~tmp; GPIOA->ODR &= ~tmp; GPIOA->PUR &= ~tmp; GPIOA->PDR &= ~tmp; - GPIOA->AMSEL &= ~tmp; /* disable analog function on the pins */ - GPIOA->AFSEL |= tmp; /* enable ALT function on the pins */ - GPIOA->DEN |= tmp; /* enable digital I/O on the pins */ + GPIOA->AMSEL &= ~tmp; // disable analog function on the pins + GPIOA->AFSEL |= tmp; // enable ALT function on the pins + GPIOA->DEN |= tmp; // enable digital I/O on the pins GPIOA->PCTL &= ~0x00U; GPIOA->PCTL |= 0x11U; - /* configure the UART for the desired baud rate, 8-N-1 operation */ + // configure the UART for the desired baud rate, 8-N-1 operation tmp = (((SystemCoreClock * 8U) / UART_BAUD_RATE) + 1U) / 2U; UART0->IBRD = tmp / 64U; UART0->FBRD = tmp % 64U; - UART0->LCRH = (0x3U << 5); /* configure 8-N-1 operation */ - UART0->LCRH |= (0x1U << 4); /* enable FIFOs */ - UART0->CTL = (1U << 0) /* UART enable */ - | (1U << 8) /* UART TX enable */ - | (1U << 9); /* UART RX enable */ + UART0->LCRH = (0x3U << 5U); // configure 8-N-1 operation + UART0->LCRH |= (0x1U << 4U); // enable FIFOs + UART0->CTL = (1U << 0U) // UART enable + | (1U << 8U) // UART TX enable + | (1U << 9U); // UART RX enable - /* configure UART interrupts (for the RX channel) */ - UART0->IM |= (1U << 4) | (1U << 6); /* enable RX and RX-TO interrupt */ - UART0->IFLS |= (0x2U << 2); /* interrupt on RX FIFO half-full */ - /* NOTE: do not enable the UART0 interrupt yet. Wait till QF_onStartup() */ + // configure UART interrupts (for the RX channel) + UART0->IM |= (1U << 4U) | (1U << 6U); // enable RX and RX-TO interrupt + UART0->IFLS |= (0x2U << 2U); // interrupt on RX FIFO half-full + // NOTE: do not enable the UART0 interrupt yet. Wait till QF_onStartup() - /* configure TIMER5 to produce QS time stamp */ - SYSCTL->RCGCTIMER |= (1U << 5); /* enable run mode for Timer5 */ - TIMER5->CTL = 0U; /* disable Timer1 output */ - TIMER5->CFG = 0x0U; /* 32-bit configuration */ - TIMER5->TAMR = (1U << 4) | 0x02; /* up-counting periodic mode */ - TIMER5->TAILR= 0xFFFFFFFFU; /* timer interval */ - TIMER5->ICR = 0x1U; /* TimerA timeout flag bit clears*/ - TIMER5->CTL |= (1U << 0); /* enable TimerA module */ + // configure TIMER5 to produce QS time stamp + SYSCTL->RCGCTIMER |= (1U << 5U); // enable run mode for Timer5 + TIMER5->CTL = 0U; // disable Timer1 output + TIMER5->CFG = 0x0U; // 32-bit configuration + TIMER5->TAMR = (1U << 4U) | 0x02U; // up-counting periodic mode + TIMER5->TAILR= 0xFFFFFFFFU; // timer interval + TIMER5->ICR = 0x1U; // TimerA timeout flag bit clears + TIMER5->CTL |= (1U << 0U); // enable TimerA module - return 1U; /* return success */ + return 1U; // return success } -/*..........................................................................*/ +//............................................................................ void QS_onCleanup(void) { } -/*..........................................................................*/ -QSTimeCtr QS_onGetTime(void) { /* NOTE: invoked with interrupts DISABLED */ +//............................................................................ +QSTimeCtr QS_onGetTime(void) { // NOTE: invoked with interrupts DISABLED return TIMER5->TAV; } -/*..........................................................................*/ +//............................................................................ void QS_onFlush(void) { - while (true) { -#if OS_CRITICAL_METHOD == 3u /* Allocate storage for CPU status register */ - OS_CPU_SR cpu_sr = 0u; -#endif - /* try to get next byte to transmit */ - OS_EXIT_CRITICAL(); - uint16_t b = QS_getByte(); - OS_EXIT_CRITICAL(); + for (;;) { + QF_CRIT_STAT - if (b != QS_EOD) { /* NOT end-of-data */ - /* busy-wait as long as TX FIFO has data to transmit */ - while ((UART0->FR & UART_FR_TXFE) == 0) { + // try to get next byte to transmit + QF_CRIT_ENTRY(); + uint16_t b = QS_getByte(); + QF_CRIT_EXIT(); + + if (b != QS_EOD) { // NOT end-of-data + // busy-wait as long as TX FIFO has data to transmit + while ((UART0->FR & UART_FR_TXFE) == 0U) { } - /* place the byte in the UART DR register */ - UART0->DR = b; + UART0->DR = b; // put into the DR register } else { - break; /* break out of the loop */ + break; // break out of the loop } } } -/*..........................................................................*/ -/*! callback function to reset the target (to be implemented in the BSP) */ +//............................................................................ +//! callback function to reset the target (to be implemented in the BSP) void QS_onReset(void) { NVIC_SystemReset(); } -/*..........................................................................*/ -/*! callback function to execute a user command (to be implemented in BSP) */ +//............................................................................ void QS_onCommand(uint8_t cmdId, uint32_t param1, uint32_t param2, uint32_t param3) { - QS_BEGIN_ID(COMMAND_STAT, 0U) /* app-specific record */ - QS_U8(2, cmdId); - QS_U32(8, param1); - QS_U32(8, param2); - QS_U32(8, param3); - QS_END() + Q_UNUSED_PAR(cmdId); + Q_UNUSED_PAR(param1); + Q_UNUSED_PAR(param2); + Q_UNUSED_PAR(param3); } -#endif /* Q_SPY */ -/*--------------------------------------------------------------------------*/ +#endif // Q_SPY +//---------------------------------------------------------------------------- + +//============================================================================ +// NOTE1: +// All ISRs that make system calls MUST be prioritized as "kernel-aware". +// On Cortex-M3/4/7 this means ISR priorities with numerical values higher +// or equal CPU_CFG_KA_IPL_BOUNDARY. -/***************************************************************************** -* NOTE1: -* All ISRs that make system calls MUST be prioritized as "kernel-aware". -* On Cortex-M3/4/7 this means ISR priorities with numerical values higher -* or equal CPU_CFG_KA_IPL_BOUNDARY. -*/ diff --git a/examples/uc-os2/arm-cm/dpp_ek-tm4c123gxl/bsp.h b/examples/uc-os2/arm-cm/dpp_ek-tm4c123gxl/bsp.h index 9d2ce441..2a2042ec 100644 --- a/examples/uc-os2/arm-cm/dpp_ek-tm4c123gxl/bsp.h +++ b/examples/uc-os2/arm-cm/dpp_ek-tm4c123gxl/bsp.h @@ -1,47 +1,51 @@ -/***************************************************************************** -* Product: BSP for DPP with uC/OS-II RTOS -* Last Updated for Version: 6.3.8 -* Date of the Last Update: 2019-01-30 -* -* Q u a n t u m L e a P s -* ------------------------ -* Modern Embedded Software -* -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* -* -*****************************************************************************/ -#ifndef BSP_H -#define BSP_H +//============================================================================ +// Product: BSP for DPP with uC/OS-II RTOS +// Last Updated for Version: 7.3.0 +// Date of the Last Update: 2023-06-27 +// +// Q u a n t u m L e a P s +// --------------------------- +// innovating embedded systems +// +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// This program is open source software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Alternatively, this program may be distributed and modified under the +// terms of Quantum Leaps commercial licenses, which expressly supersede +// the GNU General Public License and are specifically designed for +// licensees interested in retaining the proprietary status of their code. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Contact information: +// +// +//============================================================================ +#ifndef BSP_H_ +#define BSP_H_ #define BSP_TICKS_PER_SEC OS_TICKS_PER_SEC void BSP_init(void); +void BSP_start(void); void BSP_displayPaused(uint8_t paused); void BSP_displayPhilStat(uint8_t n, char const *stat); void BSP_terminate(int16_t result); -void BSP_randomSeed(uint32_t seed); /* random seed */ -uint32_t BSP_random(void); /* pseudo-random generator */ +void BSP_randomSeed(uint32_t seed); // random seed +uint32_t BSP_random(void); // pseudo-random generator -#endif /* BSP_H */ +void BSP_ledOn(void); +void BSP_ledOff(void); + +#endif // BSP_H_ diff --git a/examples/uc-os2/arm-cm/dpp_ek-tm4c123gxl/dpp.h b/examples/uc-os2/arm-cm/dpp_ek-tm4c123gxl/dpp.h index da094c2c..e6d1557a 100644 --- a/examples/uc-os2/arm-cm/dpp_ek-tm4c123gxl/dpp.h +++ b/examples/uc-os2/arm-cm/dpp_ek-tm4c123gxl/dpp.h @@ -1,92 +1,117 @@ -/*$file${.::dpp.h} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* -* Model: dpp.qm -* File: ${.::dpp.h} -* -* This code has been generated by QM 5.2.4 . -* DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. -* -* SPDX-License-Identifier: GPL-3.0-or-later -* -* This generated code is open source software: you can redistribute it under -* the terms of the GNU General Public License as published by the Free -* Software Foundation. -* -* This code is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -* more details. -* -* NOTE: -* Alternatively, this generated code may be distributed under the terms -* of Quantum Leaps commercial licenses, which expressly supersede the GNU -* General Public License and are specifically designed for licensees -* interested in retaining the proprietary status of their code. -* -* Contact information: -* -* -*/ -/*$endhead${.::dpp.h} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -#ifndef DPP_H -#define DPP_H +//$file${.::dpp.h} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// +// Model: dpp.qm +// File: ${.::dpp.h} +// +// This code has been generated by QM 5.3.0 . +// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. +// +// SPDX-License-Identifier: GPL-3.0-or-later +// +// This generated code is open source software: you can redistribute it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation. +// +// This code is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// NOTE: +// Alternatively, this generated code may be distributed under the terms +// of Quantum Leaps commercial licenses, which expressly supersede the GNU +// General Public License and are specifically designed for licensees +// interested in retaining the proprietary status of their code. +// +// Contact information: +// +// +// +//$endhead${.::dpp.h} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +#ifndef DPP_H_ +#define DPP_H_ -enum DPPSignals { - EAT_SIG = Q_USER_SIG, /* published by Table to let a philosopher eat */ - DONE_SIG, /* published by Philosopher when done eating */ - PAUSE_SIG, /* published by BSP to pause serving forks */ - SERVE_SIG, /* published by BSP to serve re-start serving forks */ - TEST_SIG, /* published by BSP to test the application */ - MAX_PUB_SIG, /* the last published signal */ +//$declare${Shared} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv - HUNGRY_SIG, /* posted direclty to Table from hungry Philo */ - TIMEOUT_SIG, /* used by Philosophers for time events */ - MAX_SIG /* the last signal */ +//${Shared::AppSignals} ...................................................... +enum AppSignals { + EAT_SIG = Q_USER_SIG, // published by Table to let a Philo eat + DONE_SIG, // published by Philo when done eating + PAUSE_SIG, // published by BSP to pause the application + SERVE_SIG, // published by BSP to serve re-start serving forks + TEST_SIG, // published by BSP to test the application + MAX_PUB_SIG, // the last published signal + + TIMEOUT_SIG, // posted by time event to Philo + HUNGRY_SIG, // posted by hungry Philo to Table + MAX_SIG // the last signal }; -/*$declare${Events::TableEvt} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//${Shared::produce_sig_dict} ................................................ +#ifdef Q_SPY +static inline void produce_sig_dict(void) { + QS_SIG_DICTIONARY(EAT_SIG, (void *)0); + QS_SIG_DICTIONARY(DONE_SIG, (void *)0); + QS_SIG_DICTIONARY(PAUSE_SIG, (void *)0); + QS_SIG_DICTIONARY(SERVE_SIG, (void *)0); + QS_SIG_DICTIONARY(TEST_SIG, (void *)0); -/*${Events::TableEvt} ......................................................*/ + QS_SIG_DICTIONARY(TIMEOUT_SIG, (void *)0); + QS_SIG_DICTIONARY(HUNGRY_SIG, (void *)0); +} +#endif // def Q_SPY + +//${Shared::N_PHILO} ......................................................... +#define N_PHILO ((uint8_t)5U) + +//${Shared::TableEvt} ........................................................ typedef struct { -/* protected: */ +// protected: QEvt super; -/* public: */ - uint8_t philoNum; +// public: + uint8_t philoId; } TableEvt; -/*$enddecl${Events::TableEvt} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/* number of philosophers */ -#define N_PHILO ((uint8_t)5) +// public: -/*$declare${AOs::Philo_ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +#ifdef QEVT_DYN_CTOR +static inline TableEvt * TableEvt_ctor(TableEvt * const me, + uint8_t id) +{ + if (me != (TableEvt *)0) { + // don't call QEvt_ctor() because the initialization of all + // QEvt attributes is already done in QF_QF_newX_() + me->philoId = id; + } + return me; +} +#endif // def QEVT_DYN_CTOR -/*${AOs::Philo_ctor} .......................................................*/ -void Philo_ctor(void); -/*$enddecl${AOs::Philo_ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*$declare${AOs::AO_Philo[N_PHILO]} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${AOs::AO_Philo[N_PHILO]} ................................................*/ +//${Shared::AO_Philo[N_PHILO]} ............................................... extern QActive * const AO_Philo[N_PHILO]; -/*$enddecl${AOs::AO_Philo[N_PHILO]} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*$declare${AOs::Table_ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//${Shared::Philo_ctor} ...................................................... +void Philo_ctor(uint_fast8_t const id); -/*${AOs::Table_ctor} .......................................................*/ -void Table_ctor(void); -/*$enddecl${AOs::Table_ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*$declare${AOs::AO_Table} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${AOs::AO_Table} .........................................................*/ +//${Shared::AO_Table} ........................................................ extern QActive * const AO_Table; -/*$enddecl${AOs::AO_Table} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -#ifdef QP_INC_QXK_H_ - void Test1_ctor(void); - extern QXThread * const XT_Test1; - void Test2_ctor(void); - extern QXThread * const XT_Test2; -#endif /* QP_INC_QXK_H_ */ +//${Shared::Table_ctor} ...................................................... +void Table_ctor(void); +//$enddecl${Shared} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -#endif /* DPP_H */ +#ifdef QXK_H_ +extern QXThread * const TH_XThread1; +void XThread1_ctor(void); + +extern QXThread * const TH_XThread2; +void XThread2_ctor(void); + +extern QXSemaphore TH_sema; +extern QXMutex TH_mutex; + +#endif // QXK_H_ + +#endif // DPP_H_ diff --git a/examples/uc-os2/arm-cm/dpp_ek-tm4c123gxl/dpp.qm b/examples/uc-os2/arm-cm/dpp_ek-tm4c123gxl/dpp.qm index b78ede00..ac9f2bc9 100644 --- a/examples/uc-os2/arm-cm/dpp_ek-tm4c123gxl/dpp.qm +++ b/examples/uc-os2/arm-cm/dpp_ek-tm4c123gxl/dpp.qm @@ -1,141 +1,210 @@ - + Dining Philosopher Problem example - - - + + + + + { + EAT_SIG = Q_USER_SIG, // published by Table to let a Philo eat + DONE_SIG, // published by Philo when done eating + PAUSE_SIG, // published by BSP to pause the application + SERVE_SIG, // published by BSP to serve re-start serving forks + TEST_SIG, // published by BSP to test the application + MAX_PUB_SIG, // the last published signal + + TIMEOUT_SIG, // posted by time event to Philo + HUNGRY_SIG, // posted by hungry Philo to Table + MAX_SIG // the last signal +}; + + + + QS_SIG_DICTIONARY(EAT_SIG, (void *)0); +QS_SIG_DICTIONARY(DONE_SIG, (void *)0); +QS_SIG_DICTIONARY(PAUSE_SIG, (void *)0); +QS_SIG_DICTIONARY(SERVE_SIG, (void *)0); +QS_SIG_DICTIONARY(TEST_SIG, (void *)0); + +QS_SIG_DICTIONARY(TIMEOUT_SIG, (void *)0); +QS_SIG_DICTIONARY(HUNGRY_SIG, (void *)0); + + + + ((uint8_t)5U) + + - - + + + + + + + if (me != (TableEvt *)0) { + // don't call QEvt_ctor() because the initialization of all + // QEvt attributes is already done in QF_QF_newX_() + me->philoId = id; +} +return me; + + + + = { + &Philo_inst[0].super, + &Philo_inst[1].super, + &Philo_inst[2].super, + &Philo_inst[3].super, + &Philo_inst[4].super +}; + + + + + + Philo * const me = &Philo_inst[id]; +QActive_ctor(&me->super, Q_STATE_CAST(&Philo_initial)); +QTimeEvt_ctorX(&me->timeEvt, &me->super, TIMEOUT_SIG, 0U), +me->id = (uint8_t)id; + + + + = &Table_inst.super; + + + + Table * const me = &Table_inst; +QActive_ctor(&me->super, Q_STATE_CAST(&Table_initial)); +for (uint8_t n = 0U; n < N_PHILO; ++n) { + me->fork[n] = FREE; + me->isHungry[n] = false; +} + + The Philo AO and the N_PHILO instances + + + + - + - static uint8_t registered = (uint8_t)0; /* starts off with 0, per C-standard */ -(void)par; /* unused parameter */ -if (registered == (uint8_t)0) { - registered = (uint8_t)1; + Q_UNUSED_PAR(par); - QS_OBJ_DICTIONARY(&l_philo[0]); - QS_OBJ_DICTIONARY(&l_philo[0].timeEvt); - QS_OBJ_DICTIONARY(&l_philo[1]); - QS_OBJ_DICTIONARY(&l_philo[1].timeEvt); - QS_OBJ_DICTIONARY(&l_philo[2]); - QS_OBJ_DICTIONARY(&l_philo[2].timeEvt); - QS_OBJ_DICTIONARY(&l_philo[3]); - QS_OBJ_DICTIONARY(&l_philo[3].timeEvt); - QS_OBJ_DICTIONARY(&l_philo[4]); - QS_OBJ_DICTIONARY(&l_philo[4].timeEvt); - - QS_FUN_DICTIONARY(&Philo_initial); - QS_FUN_DICTIONARY(&Philo_thinking); - QS_FUN_DICTIONARY(&Philo_hungry); - QS_FUN_DICTIONARY(&Philo_eating); -} -QS_SIG_DICTIONARY(HUNGRY_SIG, me); /* signal for each Philos */ -QS_SIG_DICTIONARY(TIMEOUT_SIG, me); /* signal for each Philos */ +QS_OBJ_ARR_DICTIONARY(&Philo_inst[me->id], me->id); +QS_OBJ_ARR_DICTIONARY(&Philo_inst[me->id].timeEvt, me->id); QActive_subscribe(&me->super, EAT_SIG); QActive_subscribe(&me->super, TEST_SIG); - + - QTimeEvt_armX(&me->timeEvt, THINK_TIME, 0U); - QTimeEvt_disarm(&me->timeEvt); + QTimeEvt_armX(&me->timeEvt, think_time(), 0U); + (void)QTimeEvt_disarm(&me->timeEvt); - - + + - /* EAT or DONE must be for other Philos than this one */ -Q_ASSERT(Q_EVT_CAST(TableEvt)->philoNum != PHILO_ID(me)); - + // EAT or DONE must be for other Philos than this one +Q_ASSERT(Q_EVT_CAST(TableEvt)->philoId != me->id); + - + - + - + - TableEvt *pe = Q_NEW(TableEvt, HUNGRY_SIG); -pe->philoNum = PHILO_ID(me); -QACTIVE_POST(AO_Table, &pe->super, me); + #ifdef QEVT_DYN_CTOR +TableEvt const *pe = Q_NEW(TableEvt, HUNGRY_SIG, me->id); +#else +TableEvt *pe = Q_NEW(TableEvt, HUNGRY_SIG); +pe->philoId = me->id; +#endif +QACTIVE_POST(AO_Table, &pe->super, &me->super); - + - Q_EVT_CAST(TableEvt)->philoNum == PHILO_ID(me) - - + Q_EVT_CAST(TableEvt)->philoId == me->id + + - + - /* DONE must be for other Philos than this one */ -Q_ASSERT(Q_EVT_CAST(TableEvt)->philoNum != PHILO_ID(me)); - + // DONE must be for other Philos than this one +Q_ASSERT(Q_EVT_CAST(TableEvt)->philoId != me->id); + - + - QTimeEvt_armX(&me->timeEvt, EAT_TIME, 0U); - TableEvt *pe = Q_NEW(TableEvt, DONE_SIG); -pe->philoNum = PHILO_ID(me); + QTimeEvt_armX(&me->timeEvt, eat_time(), 0U); + (void)QTimeEvt_disarm(&me->timeEvt); + +#ifdef QEVT_DYN_CTOR +TableEvt const *pe = Q_NEW(TableEvt, DONE_SIG, me->id); +#else +TableEvt *pe = Q_NEW(TableEvt, DONE_SIG); +pe->philoId = me->id; +#endif QACTIVE_PUBLISH(&pe->super, &me->super); - - + + - /* EAT or DONE must be for other Philos than this one */ -Q_ASSERT(Q_EVT_CAST(TableEvt)->philoNum != PHILO_ID(me)); - + // EAT or DONE must be for other Philos than this one +Q_ASSERT(Q_EVT_CAST(TableEvt)->philoId != me->id); + - + - + @@ -143,22 +212,19 @@ Q_ASSERT(Q_EVT_CAST(TableEvt)->philoNum != PHILO_ID(me)); - + + + - + - (void)par; /* unused parameter */ + Q_UNUSED_PAR(par); -QS_OBJ_DICTIONARY(&l_table); - -QS_SIG_DICTIONARY(DONE_SIG, (void *)0); /* global signals */ -QS_SIG_DICTIONARY(EAT_SIG, (void *)0); -QS_SIG_DICTIONARY(PAUSE_SIG, (void *)0); -QS_SIG_DICTIONARY(SERVE_SIG, (void *)0); -QS_SIG_DICTIONARY(TEST_SIG, (void *)0); - -QS_SIG_DICTIONARY(HUNGRY_SIG, me); /* signal just for Table */ +#ifdef Q_SPY +Table *Table_inst = me; +QS_OBJ_DICTIONARY(Table_inst); +#endif QActive_subscribe(&me->super, DONE_SIG); QActive_subscribe(&me->super, PAUSE_SIG); @@ -167,10 +233,10 @@ QActive_subscribe(&me->super, TEST_SIG); for (uint8_t n = 0U; n < N_PHILO; ++n) { me->fork[n] = FREE; - me->isHungry[n] = 0U; - BSP_displayPhilStat(n, "thinking"); + me->isHungry[n] = false; + BSP_displayPhilStat(n, THINKING); } - + @@ -178,128 +244,139 @@ for (uint8_t n = 0U; n < N_PHILO; ++n) { - + Q_ERROR(); - + - uint8_t n; -for (n = 0U; n < N_PHILO; ++n) { /* give permissions to eat... */ - if ((me->isHungry[n] != 0U) - && (me->fork[LEFT(n)] == FREE) + // give permissions to eat... +for (uint8_t n = 0U; n < N_PHILO; ++n) { + if (me->isHungry[n] + && (me->fork[left(n)] == FREE) && (me->fork[n] == FREE)) { - TableEvt *te; - - me->fork[LEFT(n)] = USED; + me->fork[left(n)] = USED; me->fork[n] = USED; - te = Q_NEW(TableEvt, EAT_SIG); - te->philoNum = n; - QACTIVE_PUBLISH(&te->super, &me->super); - me->isHungry[n] = 0U; - BSP_displayPhilStat(n, "eating "); +#ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, EAT_SIG, n); +#else + TableEvt *pe = Q_NEW(TableEvt, EAT_SIG); + pe->philoId = n; +#endif + QACTIVE_PUBLISH(&pe->super, &me->super); + me->isHungry[n] = false; + BSP_displayPhilStat(n, EATING); } } - uint8_t n, m; + uint8_t n = Q_EVT_CAST(TableEvt)->philoId; -n = Q_EVT_CAST(TableEvt)->philoNum; -/* phil ID must be in range and he must be not hungry */ -Q_ASSERT((n < N_PHILO) && (me->isHungry[n] == 0U)); +// phil ID must be in range and he must be not hungry +Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); -BSP_displayPhilStat(n, "hungry "); -m = LEFT(n); +BSP_displayPhilStat(n, HUNGRY); +uint8_t m = left(n); (me->fork[m] == FREE) && (me->fork[n] == FREE) - TableEvt *pe; -me->fork[m] = USED; + me->fork[m] = USED; me->fork[n] = USED; -pe = Q_NEW(TableEvt, EAT_SIG); -pe->philoNum = n; +#ifdef QEVT_DYN_CTOR +TableEvt const *pe = Q_NEW(TableEvt, EAT_SIG, n); +#else +TableEvt *pe = Q_NEW(TableEvt, EAT_SIG); +pe->philoId = n; +#endif QACTIVE_PUBLISH(&pe->super, &me->super); -BSP_displayPhilStat(n, "eating "); - +BSP_displayPhilStat(n, EATING); + else - me->isHungry[n] = 1U; - - + me->isHungry[n] = true; + + - + - uint8_t n, m; -TableEvt *pe; + uint8_t n = Q_EVT_CAST(TableEvt)->philoId; -n = Q_EVT_CAST(TableEvt)->philoNum; -/* phil ID must be in range and he must be not hungry */ -Q_ASSERT((n < N_PHILO) && (me->isHungry[n] == 0U)); +// phil ID must be in range and he must be not hungry +Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); -BSP_displayPhilStat(n, "thinking"); -m = LEFT(n); -/* both forks of Phil[n] must be used */ +BSP_displayPhilStat(n, THINKING); +uint8_t m = left(n); + +// both forks of Phil[n] must be used Q_ASSERT((me->fork[n] == USED) && (me->fork[m] == USED)); me->fork[m] = FREE; me->fork[n] = FREE; -m = RIGHT(n); /* check the right neighbor */ +m = right(n); // check the right neighbor -if ((me->isHungry[m] != 0U) && (me->fork[m] == FREE)) { +if (me->isHungry[m] && (me->fork[m] == FREE)) { me->fork[n] = USED; me->fork[m] = USED; - me->isHungry[m] = 0U; - pe = Q_NEW(TableEvt, EAT_SIG); - pe->philoNum = m; + me->isHungry[m] = false; +#ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, EAT_SIG, m); +#else + TableEvt *pe = Q_NEW(TableEvt, EAT_SIG); + pe->philoId = m; +#endif QACTIVE_PUBLISH(&pe->super, &me->super); - BSP_displayPhilStat(m, "eating "); + BSP_displayPhilStat(m, EATING); } -m = LEFT(n); /* check the left neighbor */ -n = LEFT(m); /* left fork of the left neighbor */ -if ((me->isHungry[m] != 0U) && (me->fork[n] == FREE)) { +m = left(n); // check the left neighbor +n = left(m); // left fork of the left neighbor +if (me->isHungry[m] && (me->fork[n] == FREE)) { me->fork[m] = USED; me->fork[n] = USED; - me->isHungry[m] = 0U; - pe = Q_NEW(TableEvt, EAT_SIG); - pe->philoNum = m; + me->isHungry[m] = false; +#ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, EAT_SIG, m); +#else + TableEvt *pe = Q_NEW(TableEvt, EAT_SIG); + pe->philoId = m; +#endif QACTIVE_PUBLISH(&pe->super, &me->super); - BSP_displayPhilStat(m, "eating "); + BSP_displayPhilStat(m, EATING); } - + Q_ERROR(); - + - + - + @@ -309,178 +386,140 @@ if ((me->isHungry[m] != 0U) && (me->fork[n] == FREE)) { BSP_displayPaused(0U); - + - uint8_t n = Q_EVT_CAST(TableEvt)->philoNum; -/* philo ID must be in range and he must be not hungry */ -Q_ASSERT((n < N_PHILO) && (me->isHungry[n] == 0U)); -me->isHungry[n] = 1U; -BSP_displayPhilStat(n, "hungry "); - + uint8_t n = Q_EVT_CAST(TableEvt)->philoId; + +// philo ID must be in range and he must be not hungry +Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); + +me->isHungry[n] = true; +BSP_displayPhilStat(n, HUNGRY); + - uint8_t n, m; + uint8_t n = Q_EVT_CAST(TableEvt)->philoId; -n = Q_EVT_CAST(TableEvt)->philoNum; -/* phil ID must be in range and he must be not hungry */ -Q_ASSERT((n < N_PHILO) && (me->isHungry[n] == 0U)); +// phil ID must be in range and he must be not hungry +Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); -BSP_displayPhilStat(n, "thinking"); -m = LEFT(n); -/* both forks of Phil[n] must be used */ +BSP_displayPhilStat(n, THINKING); +uint8_t m = left(n); + +// both forks of Phil[n] must be used Q_ASSERT((me->fork[n] == USED) && (me->fork[m] == USED)); me->fork[m] = FREE; me->fork[n] = FREE; - + - + - + - + - - - - - - - uint8_t n; -Philo *me; -for (n = 0U; n < N_PHILO; ++n) { - me = &l_philo[n]; - QActive_ctor(&me->super, Q_STATE_CAST(&Philo_initial)); - QTimeEvt_ctorX(&me->timeEvt, &me->super, TIMEOUT_SIG, 0U); -} - - - - uint8_t n; -Table *me = &l_table; - -QActive_ctor(&me->super, Q_STATE_CAST(&Table_initial)); - -for (n = 0U; n < N_PHILO; ++n) { - me->fork[n] = FREE; - me->isHungry[n] = 0U; -} - - #ifndef DPP_H -#define DPP_H + #ifndef DPP_H_ +#define DPP_H_ -enum DPPSignals { - EAT_SIG = Q_USER_SIG, /* published by Table to let a philosopher eat */ - DONE_SIG, /* published by Philosopher when done eating */ - PAUSE_SIG, /* published by BSP to pause serving forks */ - SERVE_SIG, /* published by BSP to serve re-start serving forks */ - TEST_SIG, /* published by BSP to test the application */ - MAX_PUB_SIG, /* the last published signal */ +$declare ${Shared} - HUNGRY_SIG, /* posted direclty to Table from hungry Philo */ - TIMEOUT_SIG, /* used by Philosophers for time events */ - MAX_SIG /* the last signal */ -}; +#ifdef QXK_H_ -$declare(Events::TableEvt) +extern QXThread * const TH_XThread1; +void XThread1_ctor(void); -/* number of philosophers */ -#define N_PHILO ((uint8_t)5) +extern QXThread * const TH_XThread2; +void XThread2_ctor(void); -$declare(AOs::Philo_ctor) -$declare(AOs::AO_Philo[N_PHILO]) +extern QXSemaphore TH_sema; +extern QXMutex TH_mutex; -$declare(AOs::Table_ctor) -$declare(AOs::AO_Table) +#endif // QXK_H_ -#ifdef QP_INC_QXK_H_ - void Test1_ctor(void); - extern QXThread * const XT_Test1; - void Test2_ctor(void); - extern QXThread * const XT_Test2; -#endif /* QP_INC_QXK_H_ */ - -#endif /* DPP_H */ - +#endif // DPP_H_ - #include "qpc.h" -#include "dpp.h" -#include "bsp.h" + #include "qpc.h" // QP/C real-time embedded framework +#include "dpp.h" // DPP Application interface +#include "bsp.h" // Board Support Package +$declare ${AOs::Philo} + +//---------------------------------------------------------------------------- Q_DEFINE_THIS_FILE -/* Active object class -----------------------------------------------------*/ -$declare(AOs::Philo) +// helper function to provide a randomized think time for Philos +static QTimeEvtCtr think_time(void); // prototype +static inline QTimeEvtCtr think_time(void) { + return (QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + + (BSP_TICKS_PER_SEC/2U)); +} -/* Local objects -----------------------------------------------------------*/ -static Philo l_philo[N_PHILO]; /* storage for all Philos */ +// helper function to provide a randomized eat time for Philos +static QTimeEvtCtr eat_time(void); // prototype +static inline QTimeEvtCtr eat_time(void) { + return (QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + + BSP_TICKS_PER_SEC); +} +//---------------------------------------------------------------------------- -#define THINK_TIME \ - (QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + (BSP_TICKS_PER_SEC/2U)) -#define EAT_TIME \ - (QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + BSP_TICKS_PER_SEC) - -/* helper macro to provide the ID of Philo "me_" */ -#define PHILO_ID(me_) ((uint8_t)((me_) - l_philo)) - -/* Global objects ----------------------------------------------------------*/ -QActive * const AO_Philo[N_PHILO] = { /* "opaque" pointers to Philo AO */ - &l_philo[0].super, - &l_philo[1].super, - &l_philo[2].super, - &l_philo[3].super, - &l_philo[4].super -}; - -/* Philo definition --------------------------------------------------------*/ -$define(AOs::Philo_ctor) -$define(AOs::Philo) +$define ${Shared::Philo_ctor} +$define ${Shared::AO_Philo[N_PHILO]} +$define ${AOs::Philo} - #include "qpc.h" -#include "dpp.h" -#include "bsp.h" + #include "qpc.h" // QP/C real-time embedded framework +#include "dpp.h" // DPP Application interface +#include "bsp.h" // Board Support Package +$declare ${AOs::Table} + +//---------------------------------------------------------------------------- Q_DEFINE_THIS_FILE -/* Active object class -----------------------------------------------------*/ -$declare(AOs::Table) +// helper function to provide the RIGHT neighbor of a Philo[n] +static inline uint8_t right(uint8_t const n) { + return (uint8_t)((n + (N_PHILO - 1U)) % N_PHILO); +} -#define RIGHT(n_) ((uint8_t)(((n_) + (N_PHILO - 1U)) % N_PHILO)) -#define LEFT(n_) ((uint8_t)(((n_) + 1U) % N_PHILO)) -#define FREE ((uint8_t)0) -#define USED ((uint8_t)1) +// helper function to provide the LEFT neighbor of a Philo[n] +static inline uint8_t left(uint8_t const n) { + return (uint8_t)((n + 1U) % N_PHILO); +} -/* Local objects -----------------------------------------------------------*/ -static Table l_table; /* the single instance of the Table active object */ +#define FREE ((uint8_t)0U) +#define USED ((uint8_t)1U) -/* Global-scope objects ----------------------------------------------------*/ -QActive * const AO_Table = &l_table.super; /* "opaque" AO pointer */ +#define THINKING "thinking" +#define HUNGRY "hungry " +#define EATING "eating " -/*..........................................................................*/ -$define(AOs::Table_ctor) -$define(AOs::Table) +//---------------------------------------------------------------------------- + +$define ${Shared::Table_ctor} +$define ${Shared::AO_Table} +$define ${AOs::Table} diff --git a/examples/uc-os2/arm-cm/dpp_ek-tm4c123gxl/ek-tm4c123gxl.jpg b/examples/uc-os2/arm-cm/dpp_ek-tm4c123gxl/ek-tm4c123gxl.jpg new file mode 100644 index 00000000..5ed6188c Binary files /dev/null and b/examples/uc-os2/arm-cm/dpp_ek-tm4c123gxl/ek-tm4c123gxl.jpg differ diff --git a/examples/uc-os2/arm-cm/dpp_ek-tm4c123gxl/gnu/Makefile b/examples/uc-os2/arm-cm/dpp_ek-tm4c123gxl/gnu/Makefile index d23827d9..21a57af1 100644 --- a/examples/uc-os2/arm-cm/dpp_ek-tm4c123gxl/gnu/Makefile +++ b/examples/uc-os2/arm-cm/dpp_ek-tm4c123gxl/gnu/Makefile @@ -147,7 +147,7 @@ LIB_DIRS := LIBS := # defines -DEFINES := -DTARGET_IS_TM4C123_RB1 -D__FPU_PRESENT +DEFINES := # ARM CPU, ARCH, FPU, and Float-ABI types... # ARM_CPU: [cortex-m0 | cortex-m0plus | cortex-m1 | cortex-m3 | cortex-m4] @@ -157,7 +157,7 @@ DEFINES := -DTARGET_IS_TM4C123_RB1 -D__FPU_PRESENT ARM_CPU := -mcpu=cortex-m4 ARM_FPU := -mfpu=vfp FLOAT_ABI := -mfloat-abi=softfp -ASM_FPU := -defsym=__FPU_PRESENT=1 +ASM_FPU := #----------------------------------------------------------------------------- # GNU-ARM toolset (NOTE: You need to adjust to your machine) @@ -276,7 +276,7 @@ $(TARGET_BIN): $(TARGET_ELF) $(BIN) -O binary $< $@ $(TARGET_ELF) : $(ASM_OBJS_EXT) $(C_OBJS_EXT) $(CPP_OBJS_EXT) - $(CC) $(CFLAGS) $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o + $(CC) $(CFLAGS) $(QPC)/src/qs/qstamp.c -o $(BIN_DIR)/qstamp.o $(LINK) $(LINKFLAGS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) $(BIN_DIR)/%.d : %.c diff --git a/examples/uc-os2/arm-cm/dpp_ek-tm4c123gxl/iar/dpp.ewd b/examples/uc-os2/arm-cm/dpp_ek-tm4c123gxl/iar/dpp.ewd index ddd7d8b4..13d732d4 100644 --- a/examples/uc-os2/arm-cm/dpp_ek-tm4c123gxl/iar/dpp.ewd +++ b/examples/uc-os2/arm-cm/dpp_ek-tm4c123gxl/iar/dpp.ewd @@ -11,7 +11,7 @@ C-SPY 2 - 28 + 32 1 1 - - + + + + + @@ -486,7 +498,7 @@ IJET_ID 2 - 8 + 9 1 1 + + + + + + + + + + + + + @@ -916,7 +980,7 @@ LMIFTDI_ID 2 - 2 + 3 1 1 + + + + + + + NULINK_ID + 2 + + 0 + 1 + 1 + + + @@ -974,7 +1072,7 @@ STLINK_ID 2 - 4 + 8 1 1 + + + + @@ -1185,7 +1300,7 @@ XDS100_ID 2 - 6 + 9 1 1 + + + + @@ -1362,6 +1493,18 @@ $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin 0 + + $TOOLKIT_DIR$\plugins\rtos\FreeRtos\FreeRtosArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin2.ENU.ewplugin + 0 + $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin 0 @@ -1371,11 +1514,15 @@ 0 - $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9.ewplugin 0 - $TOOLKIT_DIR$\plugins\rtos\TI-RTOS\tirtosplugin.ewplugin + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9BE.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin 0 @@ -1391,11 +1538,11 @@ 0 - $EW_DIR$\common\plugins\CodeCoverage\CodeCoverage.ENU.ewplugin - 1 + $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + 0 - $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + $EW_DIR$\common\plugins\TargetAccessServer\TargetAccessServer.ENU.ewplugin 0 @@ -1414,7 +1561,7 @@ C-SPY 2 - 28 + 32 1 0 - - + + + + + @@ -1889,7 +2048,7 @@ IJET_ID 2 - 8 + 9 1 0 + + + + + + + + + + + + + @@ -2319,7 +2530,7 @@ LMIFTDI_ID 2 - 2 + 3 1 0 + + + + + + + NULINK_ID + 2 + + 0 + 1 + 0 + + + @@ -2377,7 +2622,7 @@ STLINK_ID 2 - 4 + 8 1 0 + + + + @@ -2588,7 +2850,7 @@ XDS100_ID 2 - 6 + 9 1 0 + + + + @@ -2765,6 +3043,18 @@ $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin 0 + + $TOOLKIT_DIR$\plugins\rtos\FreeRtos\FreeRtosArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin2.ENU.ewplugin + 0 + $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin 0 @@ -2774,11 +3064,15 @@ 0 - $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9.ewplugin 0 - $TOOLKIT_DIR$\plugins\rtos\TI-RTOS\tirtosplugin.ewplugin + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9BE.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin 0 @@ -2794,11 +3088,11 @@ 0 - $EW_DIR$\common\plugins\CodeCoverage\CodeCoverage.ENU.ewplugin - 1 + $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + 0 - $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + $EW_DIR$\common\plugins\TargetAccessServer\TargetAccessServer.ENU.ewplugin 0 @@ -2817,7 +3111,7 @@ C-SPY 2 - 28 + 32 1 1 - - + + + + + @@ -3292,7 +3598,7 @@ IJET_ID 2 - 8 + 9 1 1 + + + + + + + + + + + + + @@ -3722,7 +4080,7 @@ LMIFTDI_ID 2 - 2 + 3 1 1 + + + + + + + NULINK_ID + 2 + + 0 + 1 + 1 + + + @@ -3780,7 +4172,7 @@ STLINK_ID 2 - 4 + 8 1 1 + + + + @@ -3991,7 +4400,7 @@ XDS100_ID 2 - 6 + 9 1 1 + + + + @@ -4168,6 +4593,18 @@ $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin 0 + + $TOOLKIT_DIR$\plugins\rtos\FreeRtos\FreeRtosArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin2.ENU.ewplugin + 0 + $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin 0 @@ -4177,11 +4614,15 @@ 0 - $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9.ewplugin 0 - $TOOLKIT_DIR$\plugins\rtos\TI-RTOS\tirtosplugin.ewplugin + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9BE.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin 0 @@ -4197,11 +4638,11 @@ 0 - $EW_DIR$\common\plugins\CodeCoverage\CodeCoverage.ENU.ewplugin - 1 + $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + 0 - $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + $EW_DIR$\common\plugins\TargetAccessServer\TargetAccessServer.ENU.ewplugin 0 diff --git a/examples/uc-os2/arm-cm/dpp_ek-tm4c123gxl/iar/dpp.ewp b/examples/uc-os2/arm-cm/dpp_ek-tm4c123gxl/iar/dpp.ewp index ff62fd45..aa635079 100644 --- a/examples/uc-os2/arm-cm/dpp_ek-tm4c123gxl/iar/dpp.ewp +++ b/examples/uc-os2/arm-cm/dpp_ek-tm4c123gxl/iar/dpp.ewp @@ -11,12 +11,12 @@ General 3 - 33 + 35 1 1 + + + @@ -212,10 +224,6 @@ CCOptimizationNoSizeConstraints 0 - @@ -1064,12 +1088,12 @@ General 3 - 33 + 35 1 0 + + + @@ -1268,7 +1304,6 @@ @@ -2118,12 +2169,12 @@ General 3 - 33 + 35 1 1 + + + @@ -2322,7 +2385,6 @@ @@ -3162,14 +3240,14 @@ - - Debug - Application $PROJ_DIR$\..\app_cfg.h + + $PROJ_DIR$\..\..\..\..\..\ports\uc-os2\app_cfg.h + $PROJ_DIR$\..\bsp.c @@ -3186,10 +3264,10 @@ $PROJ_DIR$\..\os_cfg.h - $PROJ_DIR$\..\philo.c + $PROJ_DIR$\..\..\..\..\..\ports\uc-os2\os_cfg.h - $PROJ_DIR$\..\..\..\..\..\include\qstamp.c + $PROJ_DIR$\..\philo.c $PROJ_DIR$\..\table.c @@ -3257,24 +3335,9 @@ QP_port - - $PROJ_DIR$\..\..\..\..\..\ports\uc-os2\app_cfg.h - - - $PROJ_DIR$\..\..\..\..\..\ports\uc-os2\os_cfg.h - - - $PROJ_DIR$\..\..\..\..\..\ports\uc-os2\qep_port.h - $PROJ_DIR$\..\..\..\..\..\ports\uc-os2\qf_port.c - - $PROJ_DIR$\..\..\..\..\..\ports\uc-os2\qf_port.h - - - $PROJ_DIR$\..\..\..\..\..\ports\uc-os2\qs_port.h - QS @@ -3295,7 +3358,7 @@ $PROJ_DIR$\..\..\..\..\..\src\qs\qs_rx.c - $PROJ_DIR$\..\..\..\..\..\src\qs\qutest.c + $PROJ_DIR$\..\..\..\..\..\src\qs\qstamp.c diff --git a/examples/uc-os2/arm-cm/dpp_ek-tm4c123gxl/iar/dpp.icf b/examples/uc-os2/arm-cm/dpp_ek-tm4c123gxl/iar/dpp.icf index da0bc053..37b18acc 100644 --- a/examples/uc-os2/arm-cm/dpp_ek-tm4c123gxl/iar/dpp.icf +++ b/examples/uc-os2/arm-cm/dpp_ek-tm4c123gxl/iar/dpp.icf @@ -9,7 +9,7 @@ define symbol __ICFEDIT_region_ROM_end__ = 0x0003FFFF; define symbol __ICFEDIT_region_RAM_start__ = 0x20000000; define symbol __ICFEDIT_region_RAM_end__ = 0x20007FFF; /*-Sizes-*/ -define symbol __ICFEDIT_size_cstack__ = 512; +define symbol __ICFEDIT_size_cstack__ = 1024; define symbol __ICFEDIT_size_heap__ = 0; /**** End of ICF editor section. ###ICF###*/ diff --git a/examples/uc-os2/arm-cm/dpp_ek-tm4c123gxl/main.c b/examples/uc-os2/arm-cm/dpp_ek-tm4c123gxl/main.c index 7de57c20..cfcfaf07 100644 --- a/examples/uc-os2/arm-cm/dpp_ek-tm4c123gxl/main.c +++ b/examples/uc-os2/arm-cm/dpp_ek-tm4c123gxl/main.c @@ -1,96 +1,44 @@ -/***************************************************************************** -* Product: DPP example, uC/OS-II -* Last updated for version 6.9.3 -* Last updated on 2021-04-08 -* -* Q u a n t u m L e a P s -* ------------------------ -* Modern Embedded Software -* -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* -* -*****************************************************************************/ -#include "qpc.h" -#include "dpp.h" -#include "bsp.h" +//============================================================================ +// APP example +// Last updated for version 7.3.0 +// Last updated on 2023-08-09 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. +// +// This program is open source software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Alternatively, this program may be distributed and modified under the +// terms of Quantum Leaps commercial licenses, which expressly supersede +// the GNU General Public License and are specifically designed for +// licensees interested in retaining the proprietary status of their code. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Contact information: +// +// +//============================================================================ +#include "qpc.h" // QP/C real-time embedded framework +#include "dpp.h" // DPP Application interface +#include "bsp.h" // Board Support Package -Q_DEFINE_THIS_FILE - -/*..........................................................................*/ +//............................................................................ int main() { - static QEvt const *tableQueueSto[N_PHILO]; - static QEvt const *philoQueueSto[N_PHILO][N_PHILO]; - - static OS_STK philoStk[N_PHILO][160]; /* stacks for the Philosophers */ - static OS_STK tableStk[200]; /* stack for the Table */ - - static QSubscrList subscrSto[MAX_PUB_SIG]; - static QF_MPOOL_EL(TableEvt) smlPoolSto[2*N_PHILO]; /* event pool */ - uint8_t n; - - /* in C you need to explicitly instantiate all AOs... */ - Philo_ctor(); - Table_ctor(); - - QF_init(); /* initialize the framework and the underlying RT kernel */ - BSP_init(); /* initialize the Board Support Package */ - - /* init publish-subscribe */ - QF_psInit(subscrSto, Q_DIM(subscrSto)); - - /* initialize event pools... */ - QF_poolInit(smlPoolSto, sizeof(smlPoolSto), sizeof(smlPoolSto[0])); - - /* start the active objects... */ - /* CAUTION: - * Make sure to configure **SUFFICIENT** number of uC/OS-II tasks and - * message queues in "os_cfg.h" for all your active objects!!! - */ - for (n = 0U; n < N_PHILO; ++n) { - /* NOTE: provide uC/OS-II task attributes for the AO's task */ - QActive_setAttr(AO_Philo[n], OS_TASK_OPT_STK_CHK, 0); - QActive_setAttr(AO_Philo[n], TASK_NAME_ATTR, "Philo"); - QACTIVE_START(AO_Philo[n], - n + 1U, /* QP priority */ - philoQueueSto[n], /* storage for the AO's queue */ - Q_DIM(philoQueueSto[n]), /* queue's length [entries] */ - philoStk[n], /* stack storage */ - sizeof(philoStk[n]), /* sack size [bytes] */ - (void *)0); /* initialization event */ - } - - /* NOTE: provide uC/OS-II task attributes for the AO's task */ - QActive_setAttr(AO_Table, OS_TASK_OPT_STK_CLR | OS_TASK_OPT_STK_CHK, 0); - QActive_setAttr(AO_Table, TASK_NAME_ATTR, "Table"); - QACTIVE_START(AO_Table, - N_PHILO + 1U, /* QP priority */ - tableQueueSto, /* storage for the AO's queue */ - Q_DIM(tableQueueSto), /* queue's length [entries] */ - tableStk, /* stack storage */ - sizeof(tableStk), /* sack size [bytes] */ - (void *)0); /* initialization event */ - - return QF_run(); /* run the QF application */ + QF_init(); // initialize the framework and the underlying RT kernel + BSP_init(); // initialize the BSP + BSP_start(); // start the AOs/Threads + return QF_run(); // run the QF application } - diff --git a/examples/uc-os2/arm-cm/dpp_ek-tm4c123gxl/os_cfg.h b/examples/uc-os2/arm-cm/dpp_ek-tm4c123gxl/os_cfg.h index 07fa17f7..cda6c964 100644 --- a/examples/uc-os2/arm-cm/dpp_ek-tm4c123gxl/os_cfg.h +++ b/examples/uc-os2/arm-cm/dpp_ek-tm4c123gxl/os_cfg.h @@ -1,154 +1,154 @@ -/* -********************************************************************************************************* -* uC/OS-II -* The Real-Time Kernel -* -* Copyright 1992-2020 Silicon Laboratories Inc. www.silabs.com -* -* SPDX-License-Identifier: APACHE-2.0 -* -* This software is subject to an open source license and is distributed by -* Silicon Laboratories Inc. pursuant to the terms of the Apache License, -* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. -* -********************************************************************************************************* -*/ +// +//============================================================================*************************** +// uC/OS-II +// The Real-Time Kernel +// +// Copyright 1992-2020 Silicon Laboratories Inc. www.silabs.com +// +// SPDX-License-Identifier: APACHE-2.0 +// +// This software is subject to an open source license and is distributed by +// Silicon Laboratories Inc. pursuant to the terms of the Apache License, +// Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +// +//============================================================================*************************** +// -/* -********************************************************************************************************* -* -* uC/OS-II Configuration File for V2.9x -* -* Filename : os_cfg.h -* Version : V2.93.00 -********************************************************************************************************* -*/ +// +//============================================================================*************************** +// +// uC/OS-II Configuration File for V2.9x +// +// Filename : os_cfg.h +// Version : V2.93.00 +//============================================================================*************************** +// #ifndef OS_CFG_H #define OS_CFG_H - /* ---------------------- MISCELLANEOUS ----------------------- */ -#define OS_APP_HOOKS_EN 1u /* Application-defined hooks are called from the uC/OS-II hooks */ -#define OS_ARG_CHK_EN 1u /* Enable (1) or Disable (0) argument checking */ -#define OS_CPU_HOOKS_EN 1u /* uC/OS-II hooks are found in the processor port files */ + // ---------------------- MISCELLANEOUS ----------------------- +#define OS_APP_HOOKS_EN 1u // Application-defined hooks are called from the uC/OS-II hooks +#define OS_ARG_CHK_EN 1u // Enable (1) or Disable (0) argument checking +#define OS_CPU_HOOKS_EN 1u // uC/OS-II hooks are found in the processor port files -#define OS_DEBUG_EN 1u /* Enable(1) debug variables */ +#define OS_DEBUG_EN 1u // Enable(1) debug variables -#define OS_EVENT_MULTI_EN 0u /* Include code for OSEventPendMulti() */ -#define OS_EVENT_NAME_EN 1u /* Enable names for Sem, Mutex, Mbox and Q */ +#define OS_EVENT_MULTI_EN 0u // Include code for OSEventPendMulti() +#define OS_EVENT_NAME_EN 1u // Enable names for Sem, Mutex, Mbox and Q -#define OS_LOWEST_PRIO 63u /* Defines the lowest priority that can be assigned ... */ - /* ... MUST NEVER be higher than 254! */ +#define OS_LOWEST_PRIO 63u // Defines the lowest priority that can be assigned ... + // ... MUST NEVER be higher than 254! -#define OS_MAX_EVENTS 10u /* Max. number of event control blocks in your application */ -#define OS_MAX_FLAGS 5u /* Max. number of Event Flag Groups in your application */ -#define OS_MAX_MEM_PART 5u /* Max. number of memory partitions */ -#define OS_MAX_QS 20u /* Max. number of queue control blocks in your application */ -#define OS_MAX_TASKS 20u /* Max. number of tasks in your application, MUST be >= 2 */ +#define OS_MAX_EVENTS 10u // Max. number of event control blocks in your application +#define OS_MAX_FLAGS 5u // Max. number of Event Flag Groups in your application +#define OS_MAX_MEM_PART 5u // Max. number of memory partitions +#define OS_MAX_QS 20u // Max. number of queue control blocks in your application +#define OS_MAX_TASKS 20u // Max. number of tasks in your application, MUST be >= 2 -#define OS_SCHED_LOCK_EN 1u /* Include code for OSSchedLock() and OSSchedUnlock() */ +#define OS_SCHED_LOCK_EN 1u // Include code for OSSchedLock() and OSSchedUnlock() -#define OS_TICK_STEP_EN 1u /* Enable tick stepping feature for uC/OS-View */ -#define OS_TICKS_PER_SEC 100u /* Set the number of ticks in one second */ +#define OS_TICK_STEP_EN 1u // Enable tick stepping feature for uC/OS-View +#define OS_TICKS_PER_SEC 100u // Set the number of ticks in one second -#define OS_TLS_TBL_SIZE 0u /* Size of Thread-Local Storage Table */ +#define OS_TLS_TBL_SIZE 0u // Size of Thread-Local Storage Table - /* --------------------- TASK STACK SIZE ---------------------- */ -#define OS_TASK_TMR_STK_SIZE 128u /* Timer task stack size (# of OS_STK wide entries) */ -#define OS_TASK_STAT_STK_SIZE 128u /* Statistics task stack size (# of OS_STK wide entries) */ -#define OS_TASK_IDLE_STK_SIZE 128u /* Idle task stack size (# of OS_STK wide entries) */ + // --------------------- TASK STACK SIZE ---------------------- +#define OS_TASK_TMR_STK_SIZE 128u // Timer task stack size (# of OS_STK wide entries) +#define OS_TASK_STAT_STK_SIZE 128u // Statistics task stack size (# of OS_STK wide entries) +#define OS_TASK_IDLE_STK_SIZE 128u // Idle task stack size (# of OS_STK wide entries) - /* --------------------- TASK MANAGEMENT ---------------------- */ -#define OS_TASK_CHANGE_PRIO_EN 0u /* Include code for OSTaskChangePrio() */ -#define OS_TASK_CREATE_EN 1u /* Include code for OSTaskCreate() */ -#define OS_TASK_CREATE_EXT_EN 1u /* Include code for OSTaskCreateExt() */ -#define OS_TASK_DEL_EN 1u /* Include code for OSTaskDel() */ -#define OS_TASK_NAME_EN 1u /* Enable task names */ -#define OS_TASK_PROFILE_EN 1u /* Include variables in OS_TCB for profiling */ -#define OS_TASK_QUERY_EN 1u /* Include code for OSTaskQuery() */ -#define OS_TASK_REG_TBL_SIZE 1u /* Size of task variables array (#of INT32U entries) */ -#define OS_TASK_STAT_EN 1u /* Enable (1) or Disable(0) the statistics task */ -#define OS_TASK_STAT_STK_CHK_EN 1u /* Check task stacks from statistic task */ -#define OS_TASK_SUSPEND_EN 1u /* Include code for OSTaskSuspend() and OSTaskResume() */ -#define OS_TASK_SW_HOOK_EN 1u /* Include code for OSTaskSwHook() */ + // --------------------- TASK MANAGEMENT ---------------------- +#define OS_TASK_CHANGE_PRIO_EN 0u // Include code for OSTaskChangePrio() +#define OS_TASK_CREATE_EN 1u // Include code for OSTaskCreate() +#define OS_TASK_CREATE_EXT_EN 1u // Include code for OSTaskCreateExt() +#define OS_TASK_DEL_EN 1u // Include code for OSTaskDel() +#define OS_TASK_NAME_EN 1u // Enable task names +#define OS_TASK_PROFILE_EN 1u // Include variables in OS_TCB for profiling +#define OS_TASK_QUERY_EN 1u // Include code for OSTaskQuery() +#define OS_TASK_REG_TBL_SIZE 1u // Size of task variables array (#of INT32U entries) +#define OS_TASK_STAT_EN 1u // Enable (1) or Disable(0) the statistics task +#define OS_TASK_STAT_STK_CHK_EN 1u // Check task stacks from statistic task +#define OS_TASK_SUSPEND_EN 1u // Include code for OSTaskSuspend() and OSTaskResume() +#define OS_TASK_SW_HOOK_EN 1u // Include code for OSTaskSwHook() - /* ----------------------- EVENT FLAGS ------------------------ */ -#define OS_FLAG_EN 1u /* Enable (1) or Disable (0) code generation for EVENT FLAGS */ -#define OS_FLAG_ACCEPT_EN 1u /* Include code for OSFlagAccept() */ -#define OS_FLAG_DEL_EN 1u /* Include code for OSFlagDel() */ -#define OS_FLAG_NAME_EN 1u /* Enable names for event flag group */ -#define OS_FLAG_QUERY_EN 1u /* Include code for OSFlagQuery() */ -#define OS_FLAG_WAIT_CLR_EN 1u /* Include code for Wait on Clear EVENT FLAGS */ -#define OS_FLAGS_NBITS 16u /* Size in #bits of OS_FLAGS data type (8, 16 or 32) */ + // ----------------------- EVENT FLAGS ------------------------ +#define OS_FLAG_EN 1u // Enable (1) or Disable (0) code generation for EVENT FLAGS +#define OS_FLAG_ACCEPT_EN 1u // Include code for OSFlagAccept() +#define OS_FLAG_DEL_EN 1u // Include code for OSFlagDel() +#define OS_FLAG_NAME_EN 1u // Enable names for event flag group +#define OS_FLAG_QUERY_EN 1u // Include code for OSFlagQuery() +#define OS_FLAG_WAIT_CLR_EN 1u // Include code for Wait on Clear EVENT FLAGS +#define OS_FLAGS_NBITS 16u // Size in #bits of OS_FLAGS data type (8, 16 or 32) - /* -------------------- MESSAGE MAILBOXES --------------------- */ -#define OS_MBOX_EN 1u /* Enable (1) or Disable (0) code generation for MAILBOXES */ -#define OS_MBOX_ACCEPT_EN 1u /* Include code for OSMboxAccept() */ -#define OS_MBOX_DEL_EN 1u /* Include code for OSMboxDel() */ -#define OS_MBOX_PEND_ABORT_EN 1u /* Include code for OSMboxPendAbort() */ -#define OS_MBOX_POST_EN 1u /* Include code for OSMboxPost() */ -#define OS_MBOX_POST_OPT_EN 1u /* Include code for OSMboxPostOpt() */ -#define OS_MBOX_QUERY_EN 1u /* Include code for OSMboxQuery() */ + // -------------------- MESSAGE MAILBOXES --------------------- +#define OS_MBOX_EN 1u // Enable (1) or Disable (0) code generation for MAILBOXES +#define OS_MBOX_ACCEPT_EN 1u // Include code for OSMboxAccept() +#define OS_MBOX_DEL_EN 1u // Include code for OSMboxDel() +#define OS_MBOX_PEND_ABORT_EN 1u // Include code for OSMboxPendAbort() +#define OS_MBOX_POST_EN 1u // Include code for OSMboxPost() +#define OS_MBOX_POST_OPT_EN 1u // Include code for OSMboxPostOpt() +#define OS_MBOX_QUERY_EN 1u // Include code for OSMboxQuery() - /* --------------------- MEMORY MANAGEMENT -------------------- */ -#define OS_MEM_EN 1u /* Enable (1) or Disable (0) code generation for MEMORY MANAGER */ -#define OS_MEM_NAME_EN 1u /* Enable memory partition names */ -#define OS_MEM_QUERY_EN 1u /* Include code for OSMemQuery() */ + // --------------------- MEMORY MANAGEMENT -------------------- +#define OS_MEM_EN 1u // Enable (1) or Disable (0) code generation for MEMORY MANAGER +#define OS_MEM_NAME_EN 1u // Enable memory partition names +#define OS_MEM_QUERY_EN 1u // Include code for OSMemQuery() - /* ---------------- MUTUAL EXCLUSION SEMAPHORES --------------- */ -#define OS_MUTEX_EN 1u /* Enable (1) or Disable (0) code generation for MUTEX */ -#define OS_MUTEX_ACCEPT_EN 1u /* Include code for OSMutexAccept() */ -#define OS_MUTEX_DEL_EN 1u /* Include code for OSMutexDel() */ -#define OS_MUTEX_QUERY_EN 1u /* Include code for OSMutexQuery() */ + // ---------------- MUTUAL EXCLUSION SEMAPHORES --------------- +#define OS_MUTEX_EN 1u // Enable (1) or Disable (0) code generation for MUTEX +#define OS_MUTEX_ACCEPT_EN 1u // Include code for OSMutexAccept() +#define OS_MUTEX_DEL_EN 1u // Include code for OSMutexDel() +#define OS_MUTEX_QUERY_EN 1u // Include code for OSMutexQuery() - /* ---------------------- MESSAGE QUEUES ---------------------- */ -#define OS_Q_EN 1u /* Enable (1) or Disable (0) code generation for QUEUES */ -#define OS_Q_ACCEPT_EN 1u /* Include code for OSQAccept() */ -#define OS_Q_DEL_EN 1u /* Include code for OSQDel() */ -#define OS_Q_FLUSH_EN 1u /* Include code for OSQFlush() */ -#define OS_Q_PEND_ABORT_EN 1u /* Include code for OSQPendAbort() */ -#define OS_Q_POST_EN 1u /* Include code for OSQPost() */ -#define OS_Q_POST_FRONT_EN 1u /* Include code for OSQPostFront() */ -#define OS_Q_POST_OPT_EN 1u /* Include code for OSQPostOpt() */ -#define OS_Q_QUERY_EN 1u /* Include code for OSQQuery() */ + // ---------------------- MESSAGE QUEUES ---------------------- +#define OS_Q_EN 1u // Enable (1) or Disable (0) code generation for QUEUES +#define OS_Q_ACCEPT_EN 1u // Include code for OSQAccept() +#define OS_Q_DEL_EN 1u // Include code for OSQDel() +#define OS_Q_FLUSH_EN 1u // Include code for OSQFlush() +#define OS_Q_PEND_ABORT_EN 1u // Include code for OSQPendAbort() +#define OS_Q_POST_EN 1u // Include code for OSQPost() +#define OS_Q_POST_FRONT_EN 1u // Include code for OSQPostFront() +#define OS_Q_POST_OPT_EN 1u // Include code for OSQPostOpt() +#define OS_Q_QUERY_EN 1u // Include code for OSQQuery() - /* ------------------------ SEMAPHORES ------------------------ */ -#define OS_SEM_EN 1u /* Enable (1) or Disable (0) code generation for SEMAPHORES */ -#define OS_SEM_ACCEPT_EN 1u /* Include code for OSSemAccept() */ -#define OS_SEM_DEL_EN 1u /* Include code for OSSemDel() */ -#define OS_SEM_PEND_ABORT_EN 1u /* Include code for OSSemPendAbort() */ -#define OS_SEM_QUERY_EN 1u /* Include code for OSSemQuery() */ -#define OS_SEM_SET_EN 1u /* Include code for OSSemSet() */ + // ------------------------ SEMAPHORES ------------------------ +#define OS_SEM_EN 1u // Enable (1) or Disable (0) code generation for SEMAPHORES +#define OS_SEM_ACCEPT_EN 1u // Include code for OSSemAccept() +#define OS_SEM_DEL_EN 1u // Include code for OSSemDel() +#define OS_SEM_PEND_ABORT_EN 1u // Include code for OSSemPendAbort() +#define OS_SEM_QUERY_EN 1u // Include code for OSSemQuery() +#define OS_SEM_SET_EN 1u // Include code for OSSemSet() - /* --------------------- TIME MANAGEMENT ---------------------- */ -#define OS_TIME_DLY_HMSM_EN 1u /* Include code for OSTimeDlyHMSM() */ -#define OS_TIME_DLY_RESUME_EN 1u /* Include code for OSTimeDlyResume() */ -#define OS_TIME_GET_SET_EN 1u /* Include code for OSTimeGet() and OSTimeSet() */ -#define OS_TIME_TICK_HOOK_EN 1u /* Include code for OSTimeTickHook() */ + // --------------------- TIME MANAGEMENT ---------------------- +#define OS_TIME_DLY_HMSM_EN 1u // Include code for OSTimeDlyHMSM() +#define OS_TIME_DLY_RESUME_EN 1u // Include code for OSTimeDlyResume() +#define OS_TIME_GET_SET_EN 1u // Include code for OSTimeGet() and OSTimeSet() +#define OS_TIME_TICK_HOOK_EN 1u // Include code for OSTimeTickHook() - /* --------------------- TIMER MANAGEMENT --------------------- */ -#define OS_TMR_EN 1u /* Enable (1) or Disable (0) code generation for TIMERS */ -#define OS_TMR_CFG_MAX 16u /* Maximum number of timers */ -#define OS_TMR_CFG_NAME_EN 1u /* Determine timer names */ -#define OS_TMR_CFG_WHEEL_SIZE 7u /* Size of timer wheel (#Spokes) */ -#define OS_TMR_CFG_TICKS_PER_SEC 10u /* Rate at which timer management task runs (Hz) */ + // --------------------- TIMER MANAGEMENT --------------------- +#define OS_TMR_EN 1u // Enable (1) or Disable (0) code generation for TIMERS +#define OS_TMR_CFG_MAX 16u // Maximum number of timers +#define OS_TMR_CFG_NAME_EN 1u // Determine timer names +#define OS_TMR_CFG_WHEEL_SIZE 7u // Size of timer wheel (#Spokes) +#define OS_TMR_CFG_TICKS_PER_SEC 10u // Rate at which timer management task runs (Hz) - /* ---------------------- TRACE RECORDER ---------------------- */ -#define OS_TRACE_EN 0u /* Enable (1) or Disable (0) uC/OS-II Trace instrumentation */ -#define OS_TRACE_API_ENTER_EN 0u /* Enable (1) or Disable (0) uC/OS-II Trace API enter instrum. */ -#define OS_TRACE_API_EXIT_EN 0u /* Enable (1) or Disable (0) uC/OS-II Trace API exit instrum. */ + // ---------------------- TRACE RECORDER ---------------------- +#define OS_TRACE_EN 0u // Enable (1) or Disable (0) uC/OS-II Trace instrumentation +#define OS_TRACE_API_ENTER_EN 0u // Enable (1) or Disable (0) uC/OS-II Trace API enter instrum. +#define OS_TRACE_API_EXIT_EN 0u // Enable (1) or Disable (0) uC/OS-II Trace API exit instrum. #endif diff --git a/examples/uc-os2/arm-cm/dpp_ek-tm4c123gxl/philo.c b/examples/uc-os2/arm-cm/dpp_ek-tm4c123gxl/philo.c index 7614912a..eb6be531 100644 --- a/examples/uc-os2/arm-cm/dpp_ek-tm4c123gxl/philo.c +++ b/examples/uc-os2/arm-cm/dpp_ek-tm4c123gxl/philo.c @@ -1,165 +1,159 @@ -/*$file${.::philo.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* -* Model: dpp.qm -* File: ${.::philo.c} -* -* This code has been generated by QM 5.2.4 . -* DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. -* -* SPDX-License-Identifier: GPL-3.0-or-later -* -* This generated code is open source software: you can redistribute it under -* the terms of the GNU General Public License as published by the Free -* Software Foundation. -* -* This code is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -* more details. -* -* NOTE: -* Alternatively, this generated code may be distributed under the terms -* of Quantum Leaps commercial licenses, which expressly supersede the GNU -* General Public License and are specifically designed for licensees -* interested in retaining the proprietary status of their code. -* -* Contact information: -* -* -*/ -/*$endhead${.::philo.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -#include "qpc.h" -#include "dpp.h" -#include "bsp.h" +//$file${.::philo.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// +// Model: dpp.qm +// File: ${.::philo.c} +// +// This code has been generated by QM 5.3.0 . +// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. +// +// SPDX-License-Identifier: GPL-3.0-or-later +// +// This generated code is open source software: you can redistribute it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation. +// +// This code is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// NOTE: +// Alternatively, this generated code may be distributed under the terms +// of Quantum Leaps commercial licenses, which expressly supersede the GNU +// General Public License and are specifically designed for licensees +// interested in retaining the proprietary status of their code. +// +// Contact information: +// +// +// +//$endhead${.::philo.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +#include "qpc.h" // QP/C real-time embedded framework +#include "dpp.h" // DPP Application interface +#include "bsp.h" // Board Support Package -Q_DEFINE_THIS_FILE +//$declare${AOs::Philo} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/* Active object class -----------------------------------------------------*/ -/*$declare${AOs::Philo} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${AOs::Philo} ............................................................*/ -typedef struct { -/* protected: */ +//${AOs::Philo} .............................................................. +typedef struct Philo { +// protected: QActive super; -/* private: */ +// private: QTimeEvt timeEvt; + uint8_t id; + +// public: } Philo; -/* protected: */ +extern Philo Philo_inst[N_PHILO]; + +// protected: static QState Philo_initial(Philo * const me, void const * const par); static QState Philo_thinking(Philo * const me, QEvt const * const e); static QState Philo_hungry(Philo * const me, QEvt const * const e); static QState Philo_eating(Philo * const me, QEvt const * const e); -/*$enddecl${AOs::Philo} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$enddecl${AOs::Philo} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -/* Local objects -----------------------------------------------------------*/ -static Philo l_philo[N_PHILO]; /* storage for all Philos */ +//---------------------------------------------------------------------------- +Q_DEFINE_THIS_FILE -#define THINK_TIME \ - (QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + (BSP_TICKS_PER_SEC/2U)) -#define EAT_TIME \ - (QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + BSP_TICKS_PER_SEC) - -/* helper macro to provide the ID of Philo "me_" */ -#define PHILO_ID(me_) ((uint8_t)((me_) - l_philo)) - -/* Global objects ----------------------------------------------------------*/ -QActive * const AO_Philo[N_PHILO] = { /* "opaque" pointers to Philo AO */ - &l_philo[0].super, - &l_philo[1].super, - &l_philo[2].super, - &l_philo[3].super, - &l_philo[4].super -}; - -/* Philo definition --------------------------------------------------------*/ -/*$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* Check for the minimum required QP version */ -#if (QP_VERSION < 700U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) -#error qpc version 7.0.0 or higher required -#endif -/*$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ - -/*$define${AOs::Philo_ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${AOs::Philo_ctor} .......................................................*/ -void Philo_ctor(void) { - uint8_t n; - Philo *me; - for (n = 0U; n < N_PHILO; ++n) { - me = &l_philo[n]; - QActive_ctor(&me->super, Q_STATE_CAST(&Philo_initial)); - QTimeEvt_ctorX(&me->timeEvt, &me->super, TIMEOUT_SIG, 0U); - } +// helper function to provide a randomized think time for Philos +static QTimeEvtCtr think_time(void); // prototype +static inline QTimeEvtCtr think_time(void) { + return (QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + + (BSP_TICKS_PER_SEC/2U)); } -/*$enddef${AOs::Philo_ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*$define${AOs::Philo} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/*${AOs::Philo} ............................................................*/ +// helper function to provide a randomized eat time for Philos +static QTimeEvtCtr eat_time(void); // prototype +static inline QTimeEvtCtr eat_time(void) { + return (QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + + BSP_TICKS_PER_SEC); +} +//---------------------------------------------------------------------------- -/*${AOs::Philo::SM} ........................................................*/ +//$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// Check for the minimum required QP version +#if (QP_VERSION < 730U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) +#error qpc version 7.3.0 or higher required +#endif +//$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +//$define${Shared::Philo_ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${Shared::Philo_ctor} ...................................................... +void Philo_ctor(uint_fast8_t const id) { + Philo * const me = &Philo_inst[id]; + QActive_ctor(&me->super, Q_STATE_CAST(&Philo_initial)); + QTimeEvt_ctorX(&me->timeEvt, &me->super, TIMEOUT_SIG, 0U), + me->id = (uint8_t)id; +} +//$enddef${Shared::Philo_ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +//$define${Shared::AO_Philo[N_PHILO]} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${Shared::AO_Philo[N_PHILO]} ............................................... +QActive * const AO_Philo[N_PHILO] = { + &Philo_inst[0].super, + &Philo_inst[1].super, + &Philo_inst[2].super, + &Philo_inst[3].super, + &Philo_inst[4].super +}; +//$enddef${Shared::AO_Philo[N_PHILO]} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +//$define${AOs::Philo} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${AOs::Philo} .............................................................. +Philo Philo_inst[N_PHILO]; + +//${AOs::Philo::SM} .......................................................... static QState Philo_initial(Philo * const me, void const * const par) { - /*${AOs::Philo::SM::initial} */ - static uint8_t registered = (uint8_t)0; /* starts off with 0, per C-standard */ - (void)par; /* unused parameter */ - if (registered == (uint8_t)0) { - registered = (uint8_t)1; + //${AOs::Philo::SM::initial} + Q_UNUSED_PAR(par); - QS_OBJ_DICTIONARY(&l_philo[0]); - QS_OBJ_DICTIONARY(&l_philo[0].timeEvt); - QS_OBJ_DICTIONARY(&l_philo[1]); - QS_OBJ_DICTIONARY(&l_philo[1].timeEvt); - QS_OBJ_DICTIONARY(&l_philo[2]); - QS_OBJ_DICTIONARY(&l_philo[2].timeEvt); - QS_OBJ_DICTIONARY(&l_philo[3]); - QS_OBJ_DICTIONARY(&l_philo[3].timeEvt); - QS_OBJ_DICTIONARY(&l_philo[4]); - QS_OBJ_DICTIONARY(&l_philo[4].timeEvt); - - QS_FUN_DICTIONARY(&Philo_initial); - QS_FUN_DICTIONARY(&Philo_thinking); - QS_FUN_DICTIONARY(&Philo_hungry); - QS_FUN_DICTIONARY(&Philo_eating); - } - QS_SIG_DICTIONARY(HUNGRY_SIG, me); /* signal for each Philos */ - QS_SIG_DICTIONARY(TIMEOUT_SIG, me); /* signal for each Philos */ + QS_OBJ_ARR_DICTIONARY(&Philo_inst[me->id], me->id); + QS_OBJ_ARR_DICTIONARY(&Philo_inst[me->id].timeEvt, me->id); QActive_subscribe(&me->super, EAT_SIG); QActive_subscribe(&me->super, TEST_SIG); + + QS_FUN_DICTIONARY(&Philo_thinking); + QS_FUN_DICTIONARY(&Philo_hungry); + QS_FUN_DICTIONARY(&Philo_eating); + return Q_TRAN(&Philo_thinking); } -/*${AOs::Philo::SM::thinking} ..............................................*/ +//${AOs::Philo::SM::thinking} ................................................ static QState Philo_thinking(Philo * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${AOs::Philo::SM::thinking} */ + //${AOs::Philo::SM::thinking} case Q_ENTRY_SIG: { - QTimeEvt_armX(&me->timeEvt, THINK_TIME, 0U); + QTimeEvt_armX(&me->timeEvt, think_time(), 0U); status_ = Q_HANDLED(); break; } - /*${AOs::Philo::SM::thinking} */ + //${AOs::Philo::SM::thinking} case Q_EXIT_SIG: { - QTimeEvt_disarm(&me->timeEvt); + (void)QTimeEvt_disarm(&me->timeEvt); status_ = Q_HANDLED(); break; } - /*${AOs::Philo::SM::thinking::TIMEOUT} */ + //${AOs::Philo::SM::thinking::TIMEOUT} case TIMEOUT_SIG: { status_ = Q_TRAN(&Philo_hungry); break; } - /*${AOs::Philo::SM::thinking::EAT, DONE} */ - case EAT_SIG: /* intentionally fall through */ + //${AOs::Philo::SM::thinking::EAT, DONE} + case EAT_SIG: // intentionally fall through case DONE_SIG: { - /* EAT or DONE must be for other Philos than this one */ - Q_ASSERT(Q_EVT_CAST(TableEvt)->philoNum != PHILO_ID(me)); + // EAT or DONE must be for other Philos than this one + Q_ASSERT(Q_EVT_CAST(TableEvt)->philoId != me->id); status_ = Q_HANDLED(); break; } - /*${AOs::Philo::SM::thinking::TEST} */ + //${AOs::Philo::SM::thinking::TEST} case TEST_SIG: { status_ = Q_HANDLED(); break; @@ -172,22 +166,26 @@ static QState Philo_thinking(Philo * const me, QEvt const * const e) { return status_; } -/*${AOs::Philo::SM::hungry} ................................................*/ +//${AOs::Philo::SM::hungry} .................................................. static QState Philo_hungry(Philo * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${AOs::Philo::SM::hungry} */ + //${AOs::Philo::SM::hungry} case Q_ENTRY_SIG: { + #ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, HUNGRY_SIG, me->id); + #else TableEvt *pe = Q_NEW(TableEvt, HUNGRY_SIG); - pe->philoNum = PHILO_ID(me); - QACTIVE_POST(AO_Table, &pe->super, me); + pe->philoId = me->id; + #endif + QACTIVE_POST(AO_Table, &pe->super, &me->super); status_ = Q_HANDLED(); break; } - /*${AOs::Philo::SM::hungry::EAT} */ + //${AOs::Philo::SM::hungry::EAT} case EAT_SIG: { - /*${AOs::Philo::SM::hungry::EAT::[Q_EVT_CAST(TableEvt)->philoNum=~} */ - if (Q_EVT_CAST(TableEvt)->philoNum == PHILO_ID(me)) { + //${AOs::Philo::SM::hungry::EAT::[e->philoId==me->iid]} + if (Q_EVT_CAST(TableEvt)->philoId == me->id) { status_ = Q_TRAN(&Philo_eating); } else { @@ -195,10 +193,10 @@ static QState Philo_hungry(Philo * const me, QEvt const * const e) { } break; } - /*${AOs::Philo::SM::hungry::DONE} */ + //${AOs::Philo::SM::hungry::DONE} case DONE_SIG: { - /* DONE must be for other Philos than this one */ - Q_ASSERT(Q_EVT_CAST(TableEvt)->philoNum != PHILO_ID(me)); + // DONE must be for other Philos than this one + Q_ASSERT(Q_EVT_CAST(TableEvt)->philoId != me->id); status_ = Q_HANDLED(); break; } @@ -210,34 +208,40 @@ static QState Philo_hungry(Philo * const me, QEvt const * const e) { return status_; } -/*${AOs::Philo::SM::eating} ................................................*/ +//${AOs::Philo::SM::eating} .................................................. static QState Philo_eating(Philo * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${AOs::Philo::SM::eating} */ + //${AOs::Philo::SM::eating} case Q_ENTRY_SIG: { - QTimeEvt_armX(&me->timeEvt, EAT_TIME, 0U); + QTimeEvt_armX(&me->timeEvt, eat_time(), 0U); status_ = Q_HANDLED(); break; } - /*${AOs::Philo::SM::eating} */ + //${AOs::Philo::SM::eating} case Q_EXIT_SIG: { + (void)QTimeEvt_disarm(&me->timeEvt); + + #ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, DONE_SIG, me->id); + #else TableEvt *pe = Q_NEW(TableEvt, DONE_SIG); - pe->philoNum = PHILO_ID(me); + pe->philoId = me->id; + #endif QACTIVE_PUBLISH(&pe->super, &me->super); status_ = Q_HANDLED(); break; } - /*${AOs::Philo::SM::eating::TIMEOUT} */ + //${AOs::Philo::SM::eating::TIMEOUT} case TIMEOUT_SIG: { status_ = Q_TRAN(&Philo_thinking); break; } - /*${AOs::Philo::SM::eating::EAT, DONE} */ - case EAT_SIG: /* intentionally fall through */ + //${AOs::Philo::SM::eating::EAT, DONE} + case EAT_SIG: // intentionally fall through case DONE_SIG: { - /* EAT or DONE must be for other Philos than this one */ - Q_ASSERT(Q_EVT_CAST(TableEvt)->philoNum != PHILO_ID(me)); + // EAT or DONE must be for other Philos than this one + Q_ASSERT(Q_EVT_CAST(TableEvt)->philoId != me->id); status_ = Q_HANDLED(); break; } @@ -248,4 +252,4 @@ static QState Philo_eating(Philo * const me, QEvt const * const e) { } return status_; } -/*$enddef${AOs::Philo} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$enddef${AOs::Philo} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/examples/uc-os2/arm-cm/dpp_ek-tm4c123gxl/table.c b/examples/uc-os2/arm-cm/dpp_ek-tm4c123gxl/table.c index d14c29d4..c3ae02f0 100644 --- a/examples/uc-os2/arm-cm/dpp_ek-tm4c123gxl/table.c +++ b/examples/uc-os2/arm-cm/dpp_ek-tm4c123gxl/table.c @@ -1,111 +1,120 @@ -/*$file${.::table.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* -* Model: dpp.qm -* File: ${.::table.c} -* -* This code has been generated by QM 5.2.4 . -* DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. -* -* SPDX-License-Identifier: GPL-3.0-or-later -* -* This generated code is open source software: you can redistribute it under -* the terms of the GNU General Public License as published by the Free -* Software Foundation. -* -* This code is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -* more details. -* -* NOTE: -* Alternatively, this generated code may be distributed under the terms -* of Quantum Leaps commercial licenses, which expressly supersede the GNU -* General Public License and are specifically designed for licensees -* interested in retaining the proprietary status of their code. -* -* Contact information: -* -* -*/ -/*$endhead${.::table.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -#include "qpc.h" -#include "dpp.h" -#include "bsp.h" +//$file${.::table.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// +// Model: dpp.qm +// File: ${.::table.c} +// +// This code has been generated by QM 5.3.0 . +// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. +// +// SPDX-License-Identifier: GPL-3.0-or-later +// +// This generated code is open source software: you can redistribute it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation. +// +// This code is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// NOTE: +// Alternatively, this generated code may be distributed under the terms +// of Quantum Leaps commercial licenses, which expressly supersede the GNU +// General Public License and are specifically designed for licensees +// interested in retaining the proprietary status of their code. +// +// Contact information: +// +// +// +//$endhead${.::table.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +#include "qpc.h" // QP/C real-time embedded framework +#include "dpp.h" // DPP Application interface +#include "bsp.h" // Board Support Package -Q_DEFINE_THIS_FILE +//$declare${AOs::Table} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/* Active object class -----------------------------------------------------*/ -/*$declare${AOs::Table} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${AOs::Table} ............................................................*/ -typedef struct { -/* protected: */ +//${AOs::Table} .............................................................. +typedef struct Table { +// protected: QActive super; -/* private: */ +// private: uint8_t fork[N_PHILO]; - uint8_t isHungry[N_PHILO]; + bool isHungry[N_PHILO]; + +// public: } Table; -/* protected: */ +extern Table Table_inst; + +// protected: static QState Table_initial(Table * const me, void const * const par); static QState Table_active(Table * const me, QEvt const * const e); static QState Table_serving(Table * const me, QEvt const * const e); static QState Table_paused(Table * const me, QEvt const * const e); -/*$enddecl${AOs::Table} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$enddecl${AOs::Table} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -#define RIGHT(n_) ((uint8_t)(((n_) + (N_PHILO - 1U)) % N_PHILO)) -#define LEFT(n_) ((uint8_t)(((n_) + 1U) % N_PHILO)) -#define FREE ((uint8_t)0) -#define USED ((uint8_t)1) +//---------------------------------------------------------------------------- +Q_DEFINE_THIS_FILE -/* Local objects -----------------------------------------------------------*/ -static Table l_table; /* the single instance of the Table active object */ +// helper function to provide the RIGHT neighbor of a Philo[n] +static inline uint8_t right(uint8_t const n) { + return (uint8_t)((n + (N_PHILO - 1U)) % N_PHILO); +} -/* Global-scope objects ----------------------------------------------------*/ -QActive * const AO_Table = &l_table.super; /* "opaque" AO pointer */ +// helper function to provide the LEFT neighbor of a Philo[n] +static inline uint8_t left(uint8_t const n) { + return (uint8_t)((n + 1U) % N_PHILO); +} -/*..........................................................................*/ -/*$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* Check for the minimum required QP version */ -#if (QP_VERSION < 700U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) -#error qpc version 7.0.0 or higher required +#define FREE ((uint8_t)0U) +#define USED ((uint8_t)1U) + +#define THINKING "thinking" +#define HUNGRY "hungry " +#define EATING "eating " + +//---------------------------------------------------------------------------- + +//$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// Check for the minimum required QP version +#if (QP_VERSION < 730U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) +#error qpc version 7.3.0 or higher required #endif -/*$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -/*$define${AOs::Table_ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//$define${Shared::Table_ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/*${AOs::Table_ctor} .......................................................*/ +//${Shared::Table_ctor} ...................................................... void Table_ctor(void) { - uint8_t n; - Table *me = &l_table; - + Table * const me = &Table_inst; QActive_ctor(&me->super, Q_STATE_CAST(&Table_initial)); - - for (n = 0U; n < N_PHILO; ++n) { + for (uint8_t n = 0U; n < N_PHILO; ++n) { me->fork[n] = FREE; - me->isHungry[n] = 0U; + me->isHungry[n] = false; } } -/*$enddef${AOs::Table_ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*$define${AOs::Table} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//$enddef${Shared::Table_ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +//$define${Shared::AO_Table} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/*${AOs::Table} ............................................................*/ +//${Shared::AO_Table} ........................................................ +QActive * const AO_Table = &Table_inst.super; +//$enddef${Shared::AO_Table} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +//$define${AOs::Table} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/*${AOs::Table::SM} ........................................................*/ +//${AOs::Table} .............................................................. +Table Table_inst; + +//${AOs::Table::SM} .......................................................... static QState Table_initial(Table * const me, void const * const par) { - /*${AOs::Table::SM::initial} */ - (void)par; /* unused parameter */ + //${AOs::Table::SM::initial} + Q_UNUSED_PAR(par); - QS_OBJ_DICTIONARY(&l_table); - - QS_SIG_DICTIONARY(DONE_SIG, (void *)0); /* global signals */ - QS_SIG_DICTIONARY(EAT_SIG, (void *)0); - QS_SIG_DICTIONARY(PAUSE_SIG, (void *)0); - QS_SIG_DICTIONARY(SERVE_SIG, (void *)0); - QS_SIG_DICTIONARY(TEST_SIG, (void *)0); - - QS_SIG_DICTIONARY(HUNGRY_SIG, me); /* signal just for Table */ + #ifdef Q_SPY + Table *Table_inst = me; + QS_OBJ_DICTIONARY(Table_inst); + #endif QActive_subscribe(&me->super, DONE_SIG); QActive_subscribe(&me->super, PAUSE_SIG); @@ -114,8 +123,8 @@ static QState Table_initial(Table * const me, void const * const par) { for (uint8_t n = 0U; n < N_PHILO; ++n) { me->fork[n] = FREE; - me->isHungry[n] = 0U; - BSP_displayPhilStat(n, "thinking"); + me->isHungry[n] = false; + BSP_displayPhilStat(n, THINKING); } QS_FUN_DICTIONARY(&Table_active); @@ -125,16 +134,16 @@ static QState Table_initial(Table * const me, void const * const par) { return Q_TRAN(&Table_serving); } -/*${AOs::Table::SM::active} ................................................*/ +//${AOs::Table::SM::active} .................................................. static QState Table_active(Table * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${AOs::Table::SM::active::TEST} */ + //${AOs::Table::SM::active::TEST} case TEST_SIG: { status_ = Q_HANDLED(); break; } - /*${AOs::Table::SM::active::EAT} */ + //${AOs::Table::SM::active::EAT} case EAT_SIG: { Q_ERROR(); status_ = Q_HANDLED(); @@ -148,108 +157,119 @@ static QState Table_active(Table * const me, QEvt const * const e) { return status_; } -/*${AOs::Table::SM::active::serving} .......................................*/ +//${AOs::Table::SM::active::serving} ......................................... static QState Table_serving(Table * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${AOs::Table::SM::active::serving} */ + //${AOs::Table::SM::active::serving} case Q_ENTRY_SIG: { - uint8_t n; - for (n = 0U; n < N_PHILO; ++n) { /* give permissions to eat... */ - if ((me->isHungry[n] != 0U) - && (me->fork[LEFT(n)] == FREE) + // give permissions to eat... + for (uint8_t n = 0U; n < N_PHILO; ++n) { + if (me->isHungry[n] + && (me->fork[left(n)] == FREE) && (me->fork[n] == FREE)) { - TableEvt *te; - - me->fork[LEFT(n)] = USED; + me->fork[left(n)] = USED; me->fork[n] = USED; - te = Q_NEW(TableEvt, EAT_SIG); - te->philoNum = n; - QACTIVE_PUBLISH(&te->super, &me->super); - me->isHungry[n] = 0U; - BSP_displayPhilStat(n, "eating "); + #ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, EAT_SIG, n); + #else + TableEvt *pe = Q_NEW(TableEvt, EAT_SIG); + pe->philoId = n; + #endif + QACTIVE_PUBLISH(&pe->super, &me->super); + me->isHungry[n] = false; + BSP_displayPhilStat(n, EATING); } } status_ = Q_HANDLED(); break; } - /*${AOs::Table::SM::active::serving::HUNGRY} */ + //${AOs::Table::SM::active::serving::HUNGRY} case HUNGRY_SIG: { - uint8_t n, m; + uint8_t n = Q_EVT_CAST(TableEvt)->philoId; - n = Q_EVT_CAST(TableEvt)->philoNum; - /* phil ID must be in range and he must be not hungry */ - Q_ASSERT((n < N_PHILO) && (me->isHungry[n] == 0U)); + // phil ID must be in range and he must be not hungry + Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); - BSP_displayPhilStat(n, "hungry "); - m = LEFT(n); - /*${AOs::Table::SM::active::serving::HUNGRY::[bothfree]} */ + BSP_displayPhilStat(n, HUNGRY); + uint8_t m = left(n); + //${AOs::Table::SM::active::serving::HUNGRY::[bothfree]} if ((me->fork[m] == FREE) && (me->fork[n] == FREE)) { - TableEvt *pe; me->fork[m] = USED; me->fork[n] = USED; - pe = Q_NEW(TableEvt, EAT_SIG); - pe->philoNum = n; + #ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, EAT_SIG, n); + #else + TableEvt *pe = Q_NEW(TableEvt, EAT_SIG); + pe->philoId = n; + #endif QACTIVE_PUBLISH(&pe->super, &me->super); - BSP_displayPhilStat(n, "eating "); + BSP_displayPhilStat(n, EATING); status_ = Q_HANDLED(); } - /*${AOs::Table::SM::active::serving::HUNGRY::[else]} */ + //${AOs::Table::SM::active::serving::HUNGRY::[else]} else { - me->isHungry[n] = 1U; + me->isHungry[n] = true; status_ = Q_HANDLED(); } break; } - /*${AOs::Table::SM::active::serving::DONE} */ + //${AOs::Table::SM::active::serving::DONE} case DONE_SIG: { - uint8_t n, m; - TableEvt *pe; + uint8_t n = Q_EVT_CAST(TableEvt)->philoId; - n = Q_EVT_CAST(TableEvt)->philoNum; - /* phil ID must be in range and he must be not hungry */ - Q_ASSERT((n < N_PHILO) && (me->isHungry[n] == 0U)); + // phil ID must be in range and he must be not hungry + Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); - BSP_displayPhilStat(n, "thinking"); - m = LEFT(n); - /* both forks of Phil[n] must be used */ + BSP_displayPhilStat(n, THINKING); + uint8_t m = left(n); + + // both forks of Phil[n] must be used Q_ASSERT((me->fork[n] == USED) && (me->fork[m] == USED)); me->fork[m] = FREE; me->fork[n] = FREE; - m = RIGHT(n); /* check the right neighbor */ + m = right(n); // check the right neighbor - if ((me->isHungry[m] != 0U) && (me->fork[m] == FREE)) { + if (me->isHungry[m] && (me->fork[m] == FREE)) { me->fork[n] = USED; me->fork[m] = USED; - me->isHungry[m] = 0U; - pe = Q_NEW(TableEvt, EAT_SIG); - pe->philoNum = m; + me->isHungry[m] = false; + #ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, EAT_SIG, m); + #else + TableEvt *pe = Q_NEW(TableEvt, EAT_SIG); + pe->philoId = m; + #endif QACTIVE_PUBLISH(&pe->super, &me->super); - BSP_displayPhilStat(m, "eating "); + BSP_displayPhilStat(m, EATING); } - m = LEFT(n); /* check the left neighbor */ - n = LEFT(m); /* left fork of the left neighbor */ - if ((me->isHungry[m] != 0U) && (me->fork[n] == FREE)) { + m = left(n); // check the left neighbor + n = left(m); // left fork of the left neighbor + if (me->isHungry[m] && (me->fork[n] == FREE)) { me->fork[m] = USED; me->fork[n] = USED; - me->isHungry[m] = 0U; - pe = Q_NEW(TableEvt, EAT_SIG); - pe->philoNum = m; + me->isHungry[m] = false; + #ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, EAT_SIG, m); + #else + TableEvt *pe = Q_NEW(TableEvt, EAT_SIG); + pe->philoId = m; + #endif QACTIVE_PUBLISH(&pe->super, &me->super); - BSP_displayPhilStat(m, "eating "); + BSP_displayPhilStat(m, EATING); } status_ = Q_HANDLED(); break; } - /*${AOs::Table::SM::active::serving::EAT} */ + //${AOs::Table::SM::active::serving::EAT} case EAT_SIG: { Q_ERROR(); status_ = Q_HANDLED(); break; } - /*${AOs::Table::SM::active::serving::PAUSE} */ + //${AOs::Table::SM::active::serving::PAUSE} case PAUSE_SIG: { status_ = Q_TRAN(&Table_paused); break; @@ -262,48 +282,50 @@ static QState Table_serving(Table * const me, QEvt const * const e) { return status_; } -/*${AOs::Table::SM::active::paused} ........................................*/ +//${AOs::Table::SM::active::paused} .......................................... static QState Table_paused(Table * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${AOs::Table::SM::active::paused} */ + //${AOs::Table::SM::active::paused} case Q_ENTRY_SIG: { BSP_displayPaused(1U); status_ = Q_HANDLED(); break; } - /*${AOs::Table::SM::active::paused} */ + //${AOs::Table::SM::active::paused} case Q_EXIT_SIG: { BSP_displayPaused(0U); status_ = Q_HANDLED(); break; } - /*${AOs::Table::SM::active::paused::SERVE} */ + //${AOs::Table::SM::active::paused::SERVE} case SERVE_SIG: { status_ = Q_TRAN(&Table_serving); break; } - /*${AOs::Table::SM::active::paused::HUNGRY} */ + //${AOs::Table::SM::active::paused::HUNGRY} case HUNGRY_SIG: { - uint8_t n = Q_EVT_CAST(TableEvt)->philoNum; - /* philo ID must be in range and he must be not hungry */ - Q_ASSERT((n < N_PHILO) && (me->isHungry[n] == 0U)); - me->isHungry[n] = 1U; - BSP_displayPhilStat(n, "hungry "); + uint8_t n = Q_EVT_CAST(TableEvt)->philoId; + + // philo ID must be in range and he must be not hungry + Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); + + me->isHungry[n] = true; + BSP_displayPhilStat(n, HUNGRY); status_ = Q_HANDLED(); break; } - /*${AOs::Table::SM::active::paused::DONE} */ + //${AOs::Table::SM::active::paused::DONE} case DONE_SIG: { - uint8_t n, m; + uint8_t n = Q_EVT_CAST(TableEvt)->philoId; - n = Q_EVT_CAST(TableEvt)->philoNum; - /* phil ID must be in range and he must be not hungry */ - Q_ASSERT((n < N_PHILO) && (me->isHungry[n] == 0U)); + // phil ID must be in range and he must be not hungry + Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); - BSP_displayPhilStat(n, "thinking"); - m = LEFT(n); - /* both forks of Phil[n] must be used */ + BSP_displayPhilStat(n, THINKING); + uint8_t m = left(n); + + // both forks of Phil[n] must be used Q_ASSERT((me->fork[n] == USED) && (me->fork[m] == USED)); me->fork[m] = FREE; @@ -318,4 +340,4 @@ static QState Table_paused(Table * const me, QEvt const * const e) { } return status_; } -/*$enddef${AOs::Table} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$enddef${AOs::Table} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/examples/uc-os2/arm-cm/dpp_nucleo-l053r8/README.txt b/examples/uc-os2/arm-cm/dpp_nucleo-l053r8/README.txt index 4d225598..bfa78475 100644 --- a/examples/uc-os2/arm-cm/dpp_nucleo-l053r8/README.txt +++ b/examples/uc-os2/arm-cm/dpp_nucleo-l053r8/README.txt @@ -30,7 +30,13 @@ The output is generated at 115200 baud rate. Here is an example invocation of the QSPY host application to receive the QS data from NUCLEO-L053R8: -qspy -cCOM2 +qspy -c COM2 The actual COM port number might be different on your Windows machine. Please check the Device Manager to find the COM port number. + +**NOTE** +The Spy build configuration overflows one of the Philo[] stacks +and the application ends up hitting an assertion. The NUCLEO-L053R8 +board has not enough RAM to size the uC-OS2 stacks and QS buffers +adequately. \ No newline at end of file diff --git a/examples/uc-os2/arm-cm/dpp_nucleo-l053r8/app_cfg.h b/examples/uc-os2/arm-cm/dpp_nucleo-l053r8/app_cfg.h index 4bcf3284..daca743d 100644 --- a/examples/uc-os2/arm-cm/dpp_nucleo-l053r8/app_cfg.h +++ b/examples/uc-os2/arm-cm/dpp_nucleo-l053r8/app_cfg.h @@ -1,81 +1,81 @@ -/*============================================================================ -* -* Quantum Leaps, LLC. www.state-machine.com -* Customized for NUCLEO-L053R8 (ARM Cortex-M0+) -* 2020-06-08 -*===========================================================================*/ -/* -********************************************************************************************************* -* EXAMPLE CODE -* -* This file is provided as an example on how to use Micrium products. -* -* Please feel free to use any application code labeled as 'EXAMPLE CODE' in -* your application products. Example code may be used as is, in whole or in -* part, or may be used as a reference only. This file can be modified as -* required to meet the end-product requirements. -* -********************************************************************************************************* -*/ +//============================================================================ +// +// Quantum Leaps, LLC. www.state-machine.com +// Customized for NUCLEO-L053R8 (ARM Cortex-M0+) +// 2020-06-08 +// =========================================================================== +// +//============================================================================*************************** +// EXAMPLE CODE +// +// This file is provided as an example on how to use Micrium products. +// +// Please feel free to use any application code labeled as 'EXAMPLE CODE' in +// your application products. Example code may be used as is, in whole or in +// part, or may be used as a reference only. This file can be modified as +// required to meet the end-product requirements. +// +//============================================================================*************************** +// -/* -********************************************************************************************************* -* -* APPLICATION CONFIGURATION -* -* EXAMPLE CODE -* -* Filename : app_cfg.h -********************************************************************************************************* -*/ +// +//============================================================================*************************** +// +// APPLICATION CONFIGURATION +// +// EXAMPLE CODE +// +// Filename : app_cfg.h +//============================================================================*************************** +// #ifndef _APP_CFG_H_ #define _APP_CFG_H_ -/* -********************************************************************************************************* -* INCLUDE FILES -********************************************************************************************************* -*/ +// +//============================================================================*************************** +// INCLUDE FILES +//============================================================================*************************** +// #include #include -/* -********************************************************************************************************* -* MODULE ENABLE / DISABLE -********************************************************************************************************* -*/ +// +//============================================================================*************************** +// MODULE ENABLE / DISABLE +//============================================================================*************************** +// -/* -********************************************************************************************************* -* TASK PRIORITIES -********************************************************************************************************* -*/ +// +//============================================================================*************************** +// TASK PRIORITIES +//============================================================================*************************** +// #define APP_CFG_STARTUP_TASK_PRIO 3u #define OS_TASK_TMR_PRIO (OS_LOWEST_PRIO - 2u) -/* -********************************************************************************************************* -* TASK STACK SIZES -* Size of the task stacks (# of OS_STK entries) -********************************************************************************************************* -*/ +// +//============================================================================*************************** +// TASK STACK SIZES +// Size of the task stacks (# of OS_STK entries) +//============================================================================*************************** +// #define APP_CFG_STARTUP_TASK_STK_SIZE 128u -/* -********************************************************************************************************* -* TRACE / DEBUG CONFIGURATION -********************************************************************************************************* -*/ +// +//============================================================================*************************** +// TRACE / DEBUG CONFIGURATION +//============================================================================*************************** +// #ifndef TRACE_LEVEL_OFF #define TRACE_LEVEL_OFF 0u @@ -96,18 +96,18 @@ #define APP_TRACE_DBG(x) ((APP_TRACE_LEVEL >= TRACE_LEVEL_DBG) ? (void)(APP_TRACE x) : (void)0) -/* -********************************************************************************************************* -* CPU PORT CONFIGURATION -********************************************************************************************************* -*/ -/* #define CPU_CFG_KA_IPL_BOUNDARY 4u */ +// +//============================================================================*************************** +// CPU PORT CONFIGURATION +//============================================================================*************************** +// +// #define CPU_CFG_KA_IPL_BOUNDARY 4u #define CPU_CFG_NVIC_PRIO_BITS 2u -/* -********************************************************************************************************* -* MODULE END -********************************************************************************************************* -*/ +// +//============================================================================*************************** +// MODULE END +//============================================================================*************************** +// -#endif /* End of module include. */ +#endif // End of module include. diff --git a/examples/uc-os2/arm-cm/dpp_nucleo-l053r8/armclang/dpp.uvoptx b/examples/uc-os2/arm-cm/dpp_nucleo-l053r8/armclang/dpp.uvoptx index 7e258407..75a651d4 100644 --- a/examples/uc-os2/arm-cm/dpp_nucleo-l053r8/armclang/dpp.uvoptx +++ b/examples/uc-os2/arm-cm/dpp_nucleo-l053r8/armclang/dpp.uvoptx @@ -512,7 +512,7 @@ 1 0 0 - 5 + 6 @@ -529,7 +529,7 @@ 0 ST-LINKIII-KEIL_SWO - -U -O207 -SF10000 -C0 -A0 -I0 -HNlocalhost -HP7184 -P1 -N00("ARM CoreSight SW-DP (ARM Core") -D00(0BC11477) -L00(0) -TO131090 -TC10000000 -TT10000000 -TP21 -TDS8007 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -FO7 -FD20000000 -FC1000 -FN1 -FF0STM32L0xx_64.FLM -FS08000000 -FL010000 -FP0($$Device:STM32L053R8Tx$CMSIS\Flash\STM32L0xx_64.FLM) + -U-O207 -O207 -SF10000 -C0 -A0 -I0 -HNlocalhost -HP7184 -P1 -N00("ARM CoreSight SW-DP (ARM Core") -D00(0BC11477) -L00(0) -TO131090 -TC10000000 -TT10000000 -TP21 -TDS8007 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -FO7 -FD20000000 -FC1000 -FN1 -FF0STM32L0xx_64.FLM -FS08000000 -FL010000 -FP0($$Device:STM32L053R8Tx$CMSIS\Flash\STM32L0xx_64.FLM) 0 @@ -562,7 +562,31 @@ - + + + 0 + 0 + 71 + 1 +
134242364
+ 0 + 0 + 0 + 0 + 0 + 1 + ..\bsp.c + + \\dpp\../bsp.c\71 +
+
+ + + 0 + 1 + QActive_registry_ + + 1 @@ -656,7 +680,7 @@ 0 0 0 - ..\..\..\..\..\include\qstamp.c + ..\..\..\..\..\src\qs\qstamp.c qstamp.c 0 0 @@ -980,30 +1004,6 @@ 0 0 0 - ..\..\..\..\..\ports\uc-os2\qep_port.h - qep_port.h - 0 - 0 - - - 4 - 28 - 5 - 0 - 0 - 0 - ..\..\..\..\..\ports\uc-os2\qf_port.h - qf_port.h - 0 - 0 - - - 4 - 29 - 5 - 0 - 0 - 0 ..\..\..\..\..\ports\uc-os2\qs_port.h qs_port.h 0 @@ -1019,7 +1019,7 @@ 0 5 - 30 + 28 1 0 0 @@ -1031,7 +1031,7 @@ 5 - 31 + 29 1 0 0 @@ -1043,7 +1043,7 @@ 5 - 32 + 30 1 0 0 @@ -1055,7 +1055,7 @@ 5 - 33 + 31 1 0 0 @@ -1075,7 +1075,7 @@ 0 6 - 34 + 32 1 0 0 @@ -1087,7 +1087,7 @@ 6 - 35 + 33 1 0 0 @@ -1099,7 +1099,7 @@ 6 - 36 + 34 1 0 0 @@ -1111,7 +1111,7 @@ 6 - 37 + 35 1 0 0 @@ -1123,7 +1123,7 @@ 6 - 38 + 36 1 0 0 @@ -1135,7 +1135,7 @@ 6 - 39 + 37 1 0 0 @@ -1147,7 +1147,7 @@ 6 - 40 + 38 1 0 0 @@ -1159,7 +1159,7 @@ 6 - 41 + 39 1 0 0 @@ -1171,7 +1171,7 @@ 6 - 42 + 40 1 0 0 @@ -1183,7 +1183,7 @@ 6 - 43 + 41 1 0 0 @@ -1203,7 +1203,7 @@ 0 7 - 44 + 42 1 0 0 @@ -1215,7 +1215,7 @@ 7 - 45 + 43 5 0 0 @@ -1227,7 +1227,7 @@ 7 - 46 + 44 2 0 0 @@ -1239,7 +1239,7 @@ 7 - 47 + 45 1 0 0 diff --git a/examples/uc-os2/arm-cm/dpp_nucleo-l053r8/armclang/dpp.uvprojx b/examples/uc-os2/arm-cm/dpp_nucleo-l053r8/armclang/dpp.uvprojx index 38da9b51..23516910 100644 --- a/examples/uc-os2/arm-cm/dpp_nucleo-l053r8/armclang/dpp.uvprojx +++ b/examples/uc-os2/arm-cm/dpp_nucleo-l053r8/armclang/dpp.uvprojx @@ -391,7 +391,7 @@ qstamp.c 1 - ..\..\..\..\..\include\qstamp.c + ..\..\..\..\..\src\qs\qstamp.c main.c @@ -528,16 +528,6 @@ 1 ..\..\..\..\..\ports\uc-os2\qf_port.c - - qep_port.h - 5 - ..\..\..\..\..\ports\uc-os2\qep_port.h - - - qf_port.h - 5 - ..\..\..\..\..\ports\uc-os2\qf_port.h - qs_port.h 5 @@ -1106,7 +1096,7 @@ qstamp.c 1 - ..\..\..\..\..\include\qstamp.c + ..\..\..\..\..\src\qs\qstamp.c main.c @@ -1243,16 +1233,6 @@ 1 ..\..\..\..\..\ports\uc-os2\qf_port.c - - qep_port.h - 5 - ..\..\..\..\..\ports\uc-os2\qep_port.h - - - qf_port.h - 5 - ..\..\..\..\..\ports\uc-os2\qf_port.h - qs_port.h 5 @@ -1440,7 +1420,7 @@ dpp-spy 0x4 ARM-ADS - 6130001::V6.13.1::.\ARMCLANG + 6160000::V6.16::ARMCLANG 1 @@ -1743,7 +1723,7 @@ 0 - 7 + 1 0 0 1 @@ -1821,7 +1801,7 @@ qstamp.c 1 - ..\..\..\..\..\include\qstamp.c + ..\..\..\..\..\src\qs\qstamp.c main.c @@ -1958,16 +1938,6 @@ 1 ..\..\..\..\..\ports\uc-os2\qf_port.c - - qep_port.h - 5 - ..\..\..\..\..\ports\uc-os2\qep_port.h - - - qf_port.h - 5 - ..\..\..\..\..\ports\uc-os2\qf_port.h - qs_port.h 5 diff --git a/examples/uc-os2/arm-cm/dpp_nucleo-l053r8/bsp.c b/examples/uc-os2/arm-cm/dpp_nucleo-l053r8/bsp.c index ca478923..356aee77 100644 --- a/examples/uc-os2/arm-cm/dpp_nucleo-l053r8/bsp.c +++ b/examples/uc-os2/arm-cm/dpp_nucleo-l053r8/bsp.c @@ -1,272 +1,362 @@ -/***************************************************************************** -* Product: DPP example, NUCLEO-L053R8 board, uC/OS-II RTOS -* Last updated for version 6.9.3 -* Last updated on 2021-03-03 -* -* Q u a n t u m L e a P s -* ------------------------ -* Modern Embedded Software -* -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* -* -*****************************************************************************/ -#include "qpc.h" -#include "dpp.h" -#include "bsp.h" +//============================================================================ +// Product: DPP example, NUCLEO-L053R8 board, uC/OS-II RTOS +// Last updated for: @ref qpc_7_3_0 +// Last updated on 2023-08-22 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// This program is open source software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Alternatively, this program may be distributed and modified under the +// terms of Quantum Leaps commercial licenses, which expressly supersede +// the GNU General Public License and are specifically designed for +// licensees interested in retaining the proprietary status of their code. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Contact information: +// +// +//============================================================================ +#include "qpc.h" // QP/C real-time embedded framework +#include "dpp.h" // DPP Application interface +#include "bsp.h" // Board Support Package -#include "stm32l0xx.h" /* CMSIS-compliant header file for the MCU used */ -/* add other drivers if necessary... */ +#include "stm32l0xx.h" // CMSIS-compliant header file for the MCU used +// add other drivers if necessary... Q_DEFINE_THIS_FILE -/* Local-scope defines -----------------------------------------------------*/ -/* LED pins available on the board (just one user LED LD2--Green on PA.5) */ -#define LED_LD2 (1U << 5) +// Local-scope defines ----------------------------------------------------- +// LED pins available on the board (just one user LED LD2--Green on PA.5) +#define LD2_PIN 5U -/* Button pins available on the board (just one user Button B1 on PC.13) */ -#define BTN_B1 (1U << 13) +// Button pins available on the board (just one user Button B1 on PC.13) +#define B1_PIN 13U - -static uint32_t l_rnd; /* random seed */ +static uint32_t l_rndSeed; #ifdef Q_SPY - QSTimeCtr QS_tickTime_; - QSTimeCtr QS_tickPeriod_; - /* QSpy source IDs */ + // QSpy source IDs static QSpyId const l_tickHook = { 0U }; - enum AppRecords { /* application-specific trace records */ + static QSTimeCtr QS_tickTime_; + static QSTimeCtr QS_tickPeriod_; + + enum AppRecords { // application-specific trace records PHILO_STAT = QS_USER, + PAUSED_STAT, }; #endif -/* ISRs used in the application ==========================================*/ -/* uCOS-II application hooks ===============================================*/ -void App_TaskCreateHook (OS_TCB *ptcb) { (void)ptcb; } -void App_TaskDelHook (OS_TCB *ptcb) { (void)ptcb; } -/*..........................................................................*/ -void App_TaskIdleHook(void) { -#if OS_CRITICAL_METHOD == 3u /* Allocate storage for CPU status register */ - OS_CPU_SR cpu_sr; -#endif +//============================================================================ +// Error handler and ISRs... - /* toggle LED2 on and then off, see NOTE01 */ - OS_ENTER_CRITICAL(); - //GPIOA->BSRR |= (LED_LD2); /* turn LED[n] on */ - //GPIOA->BSRR |= (LED_LD2 << 16); /* turn LED[n] off */ - OS_EXIT_CRITICAL(); +Q_NORETURN Q_onError(char const * const module, int_t const id) { + // NOTE: this implementation of the error handler is intended only + // for debugging and MUST be changed for deployment of the application + // (assuming that you ship your production code with assertions enabled). + Q_UNUSED_PAR(module); + Q_UNUSED_PAR(id); + QS_ASSERTION(module, id, 10000U); // report assertion to QS + +#ifndef NDEBUG + // light up the LED + GPIOA->BSRR = (1U << LD2_PIN); + for (;;) { // for debugging, hang on in an endless loop... + } +#else + NVIC_SystemReset(); + for (;;) { // explicitly "no-return" + } +#endif +} +//............................................................................ +void assert_failed(char const * const module, int_t const id); // prototype +void assert_failed(char const * const module, int_t const id) { + Q_onError(module, id); +} + +// uCOS-II application hooks =============================================== + +void App_TimeTickHook(void) { + + QTIMEEVT_TICK_X(0U, &l_tickHook); // time events at rate 0 + + // Perform the debouncing of buttons. The algorithm for debouncing + // adapted from the book "Embedded Systems Dictionary" by Jack Ganssle + // and Michael Barr, page 71. + static struct { + uint32_t depressed; + uint32_t previous; + } buttons = { 0U, 0U }; + + uint32_t current = ~GPIOC->IDR; // read Port C with state of Button B1 + uint32_t tmp = buttons.depressed; // save the depressed buttons + buttons.depressed |= (buttons.previous & current); // set depressed + buttons.depressed &= (buttons.previous | current); // clear released + buttons.previous = current; // update the history + tmp ^= buttons.depressed; // changed debounced depressed + current = buttons.depressed; + + if ((tmp & (1U << B1_PIN)) != 0U) { // debounced B1 state changed? + if ((current & (1U << B1_PIN)) != 0U) { // is B1 depressed? + static QEvt const pauseEvt = QEVT_INITIALIZER(PAUSE_SIG); + QACTIVE_PUBLISH(&pauseEvt, &l_tickHook); + } + else { // the button is released + static QEvt const serveEvt = QEVT_INITIALIZER(SERVE_SIG); + QACTIVE_PUBLISH(&serveEvt, &l_tickHook); + } + } #ifdef Q_SPY - if ((USART2->ISR & 0x0080U) != 0) { /* is TXE empty? */ - uint16_t b; + tmp = SysTick->CTRL; // clear CTRL_COUNTFLAG + QS_tickTime_ += QS_tickPeriod_; // account for the clock rollover +#endif - OS_ENTER_CRITICAL(); - b = QS_getByte(); - OS_EXIT_CRITICAL(); +} +//............................................................................ +void App_TaskCreateHook (OS_TCB *ptcb) { (void)ptcb; } +void App_TaskDelHook (OS_TCB *ptcb) { (void)ptcb; } +//............................................................................ +void App_TaskIdleHook(void) { + // toggle the User LED on and then off, see NOTE3 + QF_CRIT_STAT + QF_CRIT_ENTRY(); + // not enough LEDs for this feature + QF_CRIT_EXIT(); - if (b != QS_EOD) { /* not End-Of-Data? */ - USART2->TDR = (b & 0xFFU); /* put into the DR register */ +#ifdef Q_SPY + QF_CRIT_ENTRY(); + QS_rxParse(); // parse all the received bytes + QF_CRIT_EXIT(); + + if ((USART2->ISR & 0x0080U) != 0U) { // is TXE empty? + + QF_CRIT_ENTRY(); + uint16_t b = QS_getByte(); + QF_CRIT_EXIT(); + + if (b != QS_EOD) { // not End-Of-Data? + USART2->TDR = b; } } #elif defined NDEBUG - /* Put the CPU and peripherals to the low-power mode. - * you might need to customize the clock management for your application, - * see the datasheet for your particular Cortex-M3 MCU. - */ - __WFI(); /* Wait-For-Interrupt */ + // Put the CPU and peripherals to the low-power mode. + // you might need to customize the clock management for your application, + // see the datasheet for your particular Cortex-M MCU. + __WFI(); // Wait-For-Interrupt #endif } -/*..........................................................................*/ +//............................................................................ void App_TaskReturnHook (OS_TCB *ptcb) { (void)ptcb; } void App_TaskStatHook (void) {} void App_TaskSwHook (void) {} void App_TCBInitHook (OS_TCB *ptcb) { (void)ptcb; } -/*..........................................................................*/ -void App_TimeTickHook(void) { - /* state of the button debouncing, see below */ - static struct ButtonsDebouncing { - uint32_t depressed; - uint32_t previous; - } buttons = { 0U, 0U }; - uint32_t current; - uint32_t tmp; + +// ISRs used in the application ============================================ #ifdef Q_SPY - { - tmp = SysTick->CTRL; /* clear CTRL_COUNTFLAG */ - QS_tickTime_ += QS_tickPeriod_; /* account for the clock rollover */ - } -#endif +// ISR for receiving bytes from the QSPY Back-End +// NOTE: This ISR is "kernel-unaware" meaning that it does not interact with +// the QF/RTOS and is not disabled. Such ISRs cannot post or publish events. - QTIMEEVT_TICK_X(0U, &l_tickHook); /* process time events for rate 0 */ - //QACTIVE_POST(the_Ticker0, 0, &l_tickHook); /* post to Ticker0 */ - - /* Perform the debouncing of buttons. The algorithm for debouncing - * adapted from the book "Embedded Systems Dictionary" by Jack Ganssle - * and Michael Barr, page 71. - */ - current = ~GPIOC->IDR; /* read Port C with the state of Button B1 */ - tmp = buttons.depressed; /* save the debounced depressed buttons */ - buttons.depressed |= (buttons.previous & current); /* set depressed */ - buttons.depressed &= (buttons.previous | current); /* clear released */ - buttons.previous = current; /* update the history */ - tmp ^= buttons.depressed; /* changed debounced depressed */ - if ((tmp & BTN_B1) != 0U) { /* debounced B1 state changed? */ - if ((buttons.depressed & BTN_B1) != 0U) { /* is B1 depressed? */ - static QEvt const pauseEvt = { PAUSE_SIG, 0U, 0U}; - QACTIVE_PUBLISH(&pauseEvt, &l_tickHook); - } - else { /* the button is released */ - static QEvt const serveEvt = { SERVE_SIG, 0U, 0U}; - QACTIVE_PUBLISH(&serveEvt, &l_tickHook); - } +void USART2_IRQHandler(void); // prototype +void USART2_IRQHandler(void) { // used in QS-RX (kernel UNAWARE interrutp) + // is RX register NOT empty? + if ((USART2->ISR & (1U << 5)) != 0) { + uint32_t b = USART2->RDR; + QS_RX_PUT(b); } } +#endif // Q_SPY -/* BSP functions ===========================================================*/ +// BSP functions =========================================================== void BSP_init(void) { - /* NOTE: SystemInit() has been already called from the startup code - * but SystemCoreClock needs to be updated - */ + // Configure the MPU to prevent NULL-pointer dereferencing ... + MPU->RBAR = 0x0U // base address (NULL) + | MPU_RBAR_VALID_Msk // valid region + | (MPU_RBAR_REGION_Msk & 7U); // region #7 + MPU->RASR = (7U << MPU_RASR_SIZE_Pos) // 2^(7+1) region + | (0x0U << MPU_RASR_AP_Pos) // no-access region + | MPU_RASR_ENABLE_Msk; // region enable + MPU->CTRL = MPU_CTRL_PRIVDEFENA_Msk // enable background region + | MPU_CTRL_ENABLE_Msk; // enable the MPU + __ISB(); + __DSB(); + + // NOTE: SystemInit() has been already called from the startup code + // but SystemCoreClock needs to be updated SystemCoreClockUpdate(); - /* enable GPIOA clock port for the LED LD2 */ - RCC->IOPENR |= (1U << 0); + // enable GPIOA clock port for the LED LD2 + RCC->IOPENR |= (1U << 0U); - /* configure LED (PA.5) pin as push-pull output, no pull-up, pull-down */ - GPIOA->MODER &= ~((3U << 2*5)); - GPIOA->MODER |= ((1U << 2*5)); - GPIOA->OTYPER &= ~((1U << 5)); - GPIOA->OSPEEDR &= ~((3U << 2*5)); - GPIOA->OSPEEDR |= ((1U << 2*5)); - GPIOA->PUPDR &= ~((3U << 2*5)); + // configure LED (PA.5) pin as push-pull output, no pull-up, pull-down + GPIOA->MODER &= ~((3U << 2U*LD2_PIN)); + GPIOA->MODER |= ((1U << 2U*LD2_PIN)); + GPIOA->OTYPER &= ~((1U << LD2_PIN)); + GPIOA->OSPEEDR &= ~((3U << 2U*LD2_PIN)); + GPIOA->OSPEEDR |= ((1U << 2U*LD2_PIN)); + GPIOA->PUPDR &= ~((3U << 2U*LD2_PIN)); - /* enable GPIOC clock port for the Button B1 */ - RCC->IOPENR |= (1U << 2); + // enable GPIOC clock port for the Button B1 + RCC->IOPENR |= (1U << 2U); - /* configure Button (PC.13) pins as input, no pull-up, pull-down */ - GPIOC->MODER &= ~(3U << 2*13); - GPIOC->OSPEEDR &= ~(3U << 2*13); - GPIOC->OSPEEDR |= (1U << 2*13); - GPIOC->PUPDR &= ~(3U << 2*13); + // configure Button (PC.13) pins as input, no pull-up, pull-down + GPIOC->MODER &= ~(3U << 2U*B1_PIN); + GPIOC->OSPEEDR &= ~(3U << 2U*B1_PIN); + GPIOC->OSPEEDR |= (1U << 2U*B1_PIN); + GPIOC->PUPDR &= ~(3U << 2U*B1_PIN); - BSP_randomSeed(1234U); /* seed the random number generator */ + // seed the random number generator + BSP_randomSeed(1234U); - /* initialize the QS software tracing... */ - if (QS_INIT((void *)0) == 0U) { + // initialize the QS software tracing... + if (!QS_INIT((void *)0)) { Q_ERROR(); } + + // dictionaries... QS_OBJ_DICTIONARY(&l_tickHook); QS_USR_DICTIONARY(PHILO_STAT); + QS_USR_DICTIONARY(PAUSED_STAT); - /* setup the QS filters... */ - QS_GLB_FILTER(QS_SM_RECORDS); - QS_GLB_FILTER(QS_UA_RECORDS); + QS_ONLY(produce_sig_dict()); + + // setup the QS filters... + QS_GLB_FILTER(QS_ALL_RECORDS); // all records + QS_GLB_FILTER(-QS_QF_TICK); // exclude the clock tick } -/*..........................................................................*/ +//............................................................................ +void BSP_start(void) { + // initialize event pools + static QF_MPOOL_EL(TableEvt) smlPoolSto[2*N_PHILO]; + QF_poolInit(smlPoolSto, sizeof(smlPoolSto), sizeof(smlPoolSto[0])); + + // initialize publish-subscribe + static QSubscrList subscrSto[MAX_PUB_SIG]; + QActive_psInit(subscrSto, Q_DIM(subscrSto)); + + // start AOs/threads... + + static QEvt const *philoQueueSto[N_PHILO][10]; + static OS_STK philoStack[N_PHILO][72]; // stacks for the Philos + for (uint8_t n = 0U; n < N_PHILO; ++n) { + Philo_ctor(n); + QACTIVE_START(AO_Philo[n], + n + 1U, // QF-prio. of the AO + philoQueueSto[n], // event queue storage + Q_DIM(philoQueueSto[n]), // queue length [events] + philoStack[n], // private stack for uC/OS-II + sizeof(philoStack[n]), // stack size [bytes] + (void *)0); // no initialization param + } + + static QEvt const *tableQueueSto[N_PHILO]; + static OS_STK tableStack[80]; // stack for the Table + Table_ctor(); + QACTIVE_START(AO_Table, + N_PHILO + 1U, // QP prio. of the AO + tableQueueSto, // event queue storage + Q_DIM(tableQueueSto), // queue length [events] + tableStack, // private stack for uC/OS-II + sizeof(tableStack), // stack size [bytes] + (void *)0); // no initialization param +} +//............................................................................ void BSP_displayPhilStat(uint8_t n, char const *stat) { - if (stat[0] == 'h') { - GPIOA->BSRR |= LED_LD2; /* turn LED on */ + Q_UNUSED_PAR(n); + + if (stat[0] == 'e') { + GPIOA->BSRR = (1U << B1_PIN); // turn LED on } else { - GPIOA->BSRR |= (LED_LD2 << 16); /* turn LED off */ + GPIOA->BSRR = (1U << (B1_PIN + 16U)); // turn LED off } - QS_BEGIN_ID(PHILO_STAT, AO_Philo[n]->prio) /* app-specific record */ - QS_U8(1, n); /* Philosopher number */ - QS_STR(stat); /* Philosopher status */ + // app-specific trace record... + QS_BEGIN_ID(PHILO_STAT, AO_Table->prio) + QS_U8(1, n); // Philosopher number + QS_STR(stat); // Philosopher status QS_END() } -/*..........................................................................*/ -void BSP_displayPaused(uint8_t paused) { - /* not enough LEDs to implement this feature */ +//............................................................................ +void BSP_displayPaused(uint8_t const paused) { + // not enough LEDs to implement this feature if (paused != 0U) { - //GPIOA->BSRR |= (LED_LD2); /* turn LED[n] on */ + //GPIOA->BSRR = (LED_LD2); // turn LED[n] on } else { - //GPIOA->BSRR |= (LED_LD2 << 16); /* turn LED[n] off */ + //GPIOA->BSRR = (LED_LD2 << 16U); // turn LED[n] off } + + // application-specific trace record + QS_BEGIN_ID(PAUSED_STAT, AO_Table->prio) + QS_U8(1, paused); // Paused status + QS_END() } -/*..........................................................................*/ -uint32_t BSP_random(void) { /* a very cheap pseudo-random-number generator */ - /* "Super-Duper" Linear Congruential Generator (LCG) - * LCG(2^32, 3*7*11*13*23, 0, seed) - */ - l_rnd = l_rnd * (3U*7U*11U*13U*23U); - return l_rnd >> 8; -} -/*..........................................................................*/ +//............................................................................ void BSP_randomSeed(uint32_t seed) { - l_rnd = seed; + l_rndSeed = seed; } -/*..........................................................................*/ +//............................................................................ +uint32_t BSP_random(void) { // a very cheap pseudo-random-number generator + + OSSchedLock(); // lock uC-OS2 scheduler + // "Super-Duper" Linear Congruential Generator (LCG) + // LCG(2^32, 3*7*11*13*23, 0, seed) + uint32_t rnd = l_rndSeed * (3U*7U*11U*13U*23U); + l_rndSeed = rnd; // set for the next time + OSSchedUnlock(); // unlock uC-OS2 scheduler + + return (rnd >> 8U); +} +//............................................................................ void BSP_terminate(int16_t result) { - (void)result; + Q_UNUSED_PAR(result); } -/* QF callbacks ============================================================*/ +//============================================================================ +// QF callbacks... void QF_onStartup(void) { - /* set up the SysTick timer to fire at BSP_TICKS_PER_SEC rate - * NOTE: do NOT call OS_CPU_SysTickInit() from uC/OS-II - */ + // set up the SysTick timer to fire at BSP_TICKS_PER_SEC rate + // NOTE: do NOT call OS_CPU_SysTickInit() from uC/OS-II SysTick_Config(SystemCoreClock / BSP_TICKS_PER_SEC); - /* set priorities of ALL ISRs used in the system */ + // set priorities of ALL ISRs used in the system NVIC_SetPriority(SysTick_IRQn, 1U); - /* ... */ + // ... - /* enable IRQs in the NVIC... */ - /* ... */ + // enable IRQs in the NVIC... + // ... + +#ifdef Q_SPY + NVIC_EnableIRQ(USART2_IRQn); // UART2 interrupt used for QS-RX +#endif } -/*..........................................................................*/ +//............................................................................ void QF_onCleanup(void) { } -/*..........................................................................*/ -Q_NORETURN Q_onAssert(char const * const module, int_t const loc) { - /* - * NOTE: add here your application-specific error handling - */ - (void)module; - (void)loc; - QS_ASSERTION(module, loc, 10000U); /* report assertion to QS */ - -#ifndef NDEBUG - /* wait until button B1 is pressed... */ - while ((GPIOC->IDR & BTN_B1) != 0U) { - GPIOA->BSRR |= (LED_LD2); /* turn LED2 on */ - GPIOA->BSRR |= (LED_LD2 << 16); /* turn LED2 off */ - } -#endif - - NVIC_SystemReset(); -} - -/* QS callbacks ============================================================*/ +// QS callbacks ============================================================ #ifdef Q_SPY -/*..........................................................................*/ +//............................................................................ #define __DIV(__PCLK, __BAUD) (((__PCLK / 4) *25)/(__BAUD)) #define __DIVMANT(__PCLK, __BAUD) (__DIV(__PCLK, __BAUD)/100) #define __DIVFRAQ(__PCLK, __BAUD) \ @@ -275,88 +365,99 @@ Q_NORETURN Q_onAssert(char const * const module, int_t const loc) { #define __USART_BRR(__PCLK, __BAUD) \ ((__DIVMANT(__PCLK, __BAUD) << 4)|(__DIVFRAQ(__PCLK, __BAUD) & 0x0F)) -/*..........................................................................*/ -uint8_t QS_onStartup(void const *arg) { - static uint8_t qsBuf[1024]; /* buffer for Quantum Spy */ +// USART2 pins PA.2 and PA.3 +#define USART2_TX_PIN 2U +#define USART2_RX_PIN 3U - (void)arg; /* avoid the "unused parameter" compiler warning */ +//............................................................................ +uint8_t QS_onStartup(void const *arg) { + Q_UNUSED_PAR(arg); + + static uint8_t qsBuf[800]; // buffer for Quantum Spy QS_initBuf(qsBuf, sizeof(qsBuf)); - /* enable peripheral clock for USART2 */ - RCC->IOPENR |= ( 1ul << 0); /* Enable GPIOA clock */ - RCC->APB1ENR |= ( 1ul << 17); /* Enable USART#2 clock */ + static uint8_t qsRxBuf[100]; // buffer for QS-RX channel + QS_rxInitBuf(qsRxBuf, sizeof(qsRxBuf)); - /* Configure PA3 to USART2_RX, PA2 to USART2_TX */ - GPIOA->AFR[0] &= ~((15ul << 4* 3) | (15ul << 4* 2) ); - GPIOA->AFR[0] |= (( 4ul << 4* 3) | ( 4ul << 4* 2) ); - GPIOA->MODER &= ~(( 3ul << 2* 3) | ( 3ul << 2* 2) ); - GPIOA->MODER |= (( 2ul << 2* 3) | ( 2ul << 2* 2) ); + // enable peripheral clock for USART2 + RCC->IOPENR |= ( 1U << 0U); // Enable GPIOA clock for USART pins + RCC->APB1ENR |= ( 1U << 17U); // Enable USART#2 clock - USART2->BRR = __USART_BRR(SystemCoreClock, 115200ul); /* baud rate */ - USART2->CR3 = 0x0000; /* no flow control */ - USART2->CR2 = 0x0000; /* 1 stop bit */ - USART2->CR1 = ((1ul << 2) | /* enable RX */ - (1ul << 3) | /* enable TX */ - (0ul << 12) | /* 8 data bits */ - (0ul << 28) | /* 8 data bits */ - (1ul << 0) ); /* enable USART */ + // Configure PA3 to USART2_RX, PA2 to USART2_TX + GPIOA->AFR[0] &= ~((15U << 4U*USART2_RX_PIN) | (15U << 4U*USART2_TX_PIN)); + GPIOA->AFR[0] |= (( 4U << 4U*USART2_RX_PIN) | ( 4U << 4U*USART2_TX_PIN)); + GPIOA->MODER &= ~(( 3U << 2U*USART2_RX_PIN) | ( 3U << 2U*USART2_TX_PIN)); + GPIOA->MODER |= (( 2U << 2U*USART2_RX_PIN) | ( 2U << 2U*USART2_TX_PIN)); + + USART2->BRR = __USART_BRR(SystemCoreClock, 115200U); // baud rate + USART2->CR3 = 0x0000U | // no flow control + (1U << 12U); // disable overrun detection (OVRDIS) + USART2->CR2 = 0x0000U; // 1 stop bit + USART2->CR1 = ((1U << 2U) | // enable RX + (1U << 3U) | // enable TX + (1U << 5U) | // enable RX interrupt + (0U << 12U) | // 8 data bits + (0U << 28U) | // 8 data bits + (1U << 0U)); // enable USART QS_tickPeriod_ = SystemCoreClock / BSP_TICKS_PER_SEC; - QS_tickTime_ = QS_tickPeriod_; /* to start the timestamp at zero */ + QS_tickTime_ = QS_tickPeriod_; // to start the timestamp at zero - return 1U; /* return success */ + return 1U; // return success } -/*..........................................................................*/ +//............................................................................ void QS_onCleanup(void) { } -/*..........................................................................*/ -QSTimeCtr QS_onGetTime(void) { /* NOTE: invoked with interrupts DISABLED */ - if ((SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk) == 0) { /* not set? */ +//............................................................................ +QSTimeCtr QS_onGetTime(void) { // NOTE: invoked with interrupts DISABLED + if ((SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk) == 0U) { // not set? return QS_tickTime_ - (QSTimeCtr)SysTick->VAL; } - else { /* the rollover occured, but the SysTick_ISR did not run yet */ + else { // the rollover occured, but the SysTick_ISR did not run yet return QS_tickTime_ + QS_tickPeriod_ - (QSTimeCtr)SysTick->VAL; } } -/*..........................................................................*/ +//............................................................................ void QS_onFlush(void) { - uint16_t b; -#if OS_CRITICAL_METHOD == 3u /* Allocate storage for CPU status register */ - OS_CPU_SR cpu_sr; -#endif + for (;;) { + QF_CRIT_STAT - OS_ENTER_CRITICAL(); - while ((b = QS_getByte()) != QS_EOD) { /* while not End-Of-Data... */ - OS_EXIT_CRITICAL(); - while ((USART2->ISR & 0x0080U) == 0U) { /* while TXE not empty */ + QF_CRIT_ENTRY(); + uint16_t b = QS_getByte(); + QF_CRIT_EXIT(); + + if (b != QS_EOD) { // NOT end-of-data + // busy-wait as long as TX has data to transmit + while ((USART2->ISR & 0x0080U) == 0U) { + } + USART2->TDR = b; // put into the TDR register + } + else { + break; // break out of the loop } - USART2->TDR = (b & 0xFFU); /* put into the DR register */ - OS_ENTER_CRITICAL(); } - OS_EXIT_CRITICAL(); } -/*..........................................................................*/ -/*! callback function to reset the target (to be implemented in the BSP) */ +//............................................................................ +//! callback function to reset the target (to be implemented in the BSP) void QS_onReset(void) { NVIC_SystemReset(); } -/*..........................................................................*/ -/*! callback function to execute a user command (to be implemented in BSP) */ +//............................................................................ void QS_onCommand(uint8_t cmdId, uint32_t param1, uint32_t param2, uint32_t param3) { - (void)cmdId; - (void)param1; - (void)param2; - (void)param3; + Q_UNUSED_PAR(cmdId); + Q_UNUSED_PAR(param1); + Q_UNUSED_PAR(param2); + Q_UNUSED_PAR(param3); } -#endif /* Q_SPY */ -/*--------------------------------------------------------------------------*/ +#endif // Q_SPY +//---------------------------------------------------------------------------- -/***************************************************************************** -* NOTE01: -* Usually, one of the LEDs is used to visualize the idle loop activity. -* However, the board has not enough LEDs (only one, actually), so this -* feature is disabled. -*/ +//============================================================================ +// NOTE01: +// Usually, one of the LEDs is used to visualize the idle loop activity. +// However, the board has not enough LEDs (only one, actually), so this +// feature is disabled. +// diff --git a/examples/uc-os2/arm-cm/dpp_nucleo-l053r8/bsp.h b/examples/uc-os2/arm-cm/dpp_nucleo-l053r8/bsp.h index 9d2ce441..2a2042ec 100644 --- a/examples/uc-os2/arm-cm/dpp_nucleo-l053r8/bsp.h +++ b/examples/uc-os2/arm-cm/dpp_nucleo-l053r8/bsp.h @@ -1,47 +1,51 @@ -/***************************************************************************** -* Product: BSP for DPP with uC/OS-II RTOS -* Last Updated for Version: 6.3.8 -* Date of the Last Update: 2019-01-30 -* -* Q u a n t u m L e a P s -* ------------------------ -* Modern Embedded Software -* -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* -* -*****************************************************************************/ -#ifndef BSP_H -#define BSP_H +//============================================================================ +// Product: BSP for DPP with uC/OS-II RTOS +// Last Updated for Version: 7.3.0 +// Date of the Last Update: 2023-06-27 +// +// Q u a n t u m L e a P s +// --------------------------- +// innovating embedded systems +// +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// This program is open source software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Alternatively, this program may be distributed and modified under the +// terms of Quantum Leaps commercial licenses, which expressly supersede +// the GNU General Public License and are specifically designed for +// licensees interested in retaining the proprietary status of their code. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Contact information: +// +// +//============================================================================ +#ifndef BSP_H_ +#define BSP_H_ #define BSP_TICKS_PER_SEC OS_TICKS_PER_SEC void BSP_init(void); +void BSP_start(void); void BSP_displayPaused(uint8_t paused); void BSP_displayPhilStat(uint8_t n, char const *stat); void BSP_terminate(int16_t result); -void BSP_randomSeed(uint32_t seed); /* random seed */ -uint32_t BSP_random(void); /* pseudo-random generator */ +void BSP_randomSeed(uint32_t seed); // random seed +uint32_t BSP_random(void); // pseudo-random generator -#endif /* BSP_H */ +void BSP_ledOn(void); +void BSP_ledOff(void); + +#endif // BSP_H_ diff --git a/examples/uc-os2/arm-cm/dpp_nucleo-l053r8/dpp.h b/examples/uc-os2/arm-cm/dpp_nucleo-l053r8/dpp.h index da094c2c..e6d1557a 100644 --- a/examples/uc-os2/arm-cm/dpp_nucleo-l053r8/dpp.h +++ b/examples/uc-os2/arm-cm/dpp_nucleo-l053r8/dpp.h @@ -1,92 +1,117 @@ -/*$file${.::dpp.h} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* -* Model: dpp.qm -* File: ${.::dpp.h} -* -* This code has been generated by QM 5.2.4 . -* DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. -* -* SPDX-License-Identifier: GPL-3.0-or-later -* -* This generated code is open source software: you can redistribute it under -* the terms of the GNU General Public License as published by the Free -* Software Foundation. -* -* This code is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -* more details. -* -* NOTE: -* Alternatively, this generated code may be distributed under the terms -* of Quantum Leaps commercial licenses, which expressly supersede the GNU -* General Public License and are specifically designed for licensees -* interested in retaining the proprietary status of their code. -* -* Contact information: -* -* -*/ -/*$endhead${.::dpp.h} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -#ifndef DPP_H -#define DPP_H +//$file${.::dpp.h} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// +// Model: dpp.qm +// File: ${.::dpp.h} +// +// This code has been generated by QM 5.3.0 . +// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. +// +// SPDX-License-Identifier: GPL-3.0-or-later +// +// This generated code is open source software: you can redistribute it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation. +// +// This code is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// NOTE: +// Alternatively, this generated code may be distributed under the terms +// of Quantum Leaps commercial licenses, which expressly supersede the GNU +// General Public License and are specifically designed for licensees +// interested in retaining the proprietary status of their code. +// +// Contact information: +// +// +// +//$endhead${.::dpp.h} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +#ifndef DPP_H_ +#define DPP_H_ -enum DPPSignals { - EAT_SIG = Q_USER_SIG, /* published by Table to let a philosopher eat */ - DONE_SIG, /* published by Philosopher when done eating */ - PAUSE_SIG, /* published by BSP to pause serving forks */ - SERVE_SIG, /* published by BSP to serve re-start serving forks */ - TEST_SIG, /* published by BSP to test the application */ - MAX_PUB_SIG, /* the last published signal */ +//$declare${Shared} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv - HUNGRY_SIG, /* posted direclty to Table from hungry Philo */ - TIMEOUT_SIG, /* used by Philosophers for time events */ - MAX_SIG /* the last signal */ +//${Shared::AppSignals} ...................................................... +enum AppSignals { + EAT_SIG = Q_USER_SIG, // published by Table to let a Philo eat + DONE_SIG, // published by Philo when done eating + PAUSE_SIG, // published by BSP to pause the application + SERVE_SIG, // published by BSP to serve re-start serving forks + TEST_SIG, // published by BSP to test the application + MAX_PUB_SIG, // the last published signal + + TIMEOUT_SIG, // posted by time event to Philo + HUNGRY_SIG, // posted by hungry Philo to Table + MAX_SIG // the last signal }; -/*$declare${Events::TableEvt} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//${Shared::produce_sig_dict} ................................................ +#ifdef Q_SPY +static inline void produce_sig_dict(void) { + QS_SIG_DICTIONARY(EAT_SIG, (void *)0); + QS_SIG_DICTIONARY(DONE_SIG, (void *)0); + QS_SIG_DICTIONARY(PAUSE_SIG, (void *)0); + QS_SIG_DICTIONARY(SERVE_SIG, (void *)0); + QS_SIG_DICTIONARY(TEST_SIG, (void *)0); -/*${Events::TableEvt} ......................................................*/ + QS_SIG_DICTIONARY(TIMEOUT_SIG, (void *)0); + QS_SIG_DICTIONARY(HUNGRY_SIG, (void *)0); +} +#endif // def Q_SPY + +//${Shared::N_PHILO} ......................................................... +#define N_PHILO ((uint8_t)5U) + +//${Shared::TableEvt} ........................................................ typedef struct { -/* protected: */ +// protected: QEvt super; -/* public: */ - uint8_t philoNum; +// public: + uint8_t philoId; } TableEvt; -/*$enddecl${Events::TableEvt} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/* number of philosophers */ -#define N_PHILO ((uint8_t)5) +// public: -/*$declare${AOs::Philo_ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +#ifdef QEVT_DYN_CTOR +static inline TableEvt * TableEvt_ctor(TableEvt * const me, + uint8_t id) +{ + if (me != (TableEvt *)0) { + // don't call QEvt_ctor() because the initialization of all + // QEvt attributes is already done in QF_QF_newX_() + me->philoId = id; + } + return me; +} +#endif // def QEVT_DYN_CTOR -/*${AOs::Philo_ctor} .......................................................*/ -void Philo_ctor(void); -/*$enddecl${AOs::Philo_ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*$declare${AOs::AO_Philo[N_PHILO]} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${AOs::AO_Philo[N_PHILO]} ................................................*/ +//${Shared::AO_Philo[N_PHILO]} ............................................... extern QActive * const AO_Philo[N_PHILO]; -/*$enddecl${AOs::AO_Philo[N_PHILO]} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*$declare${AOs::Table_ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//${Shared::Philo_ctor} ...................................................... +void Philo_ctor(uint_fast8_t const id); -/*${AOs::Table_ctor} .......................................................*/ -void Table_ctor(void); -/*$enddecl${AOs::Table_ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*$declare${AOs::AO_Table} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${AOs::AO_Table} .........................................................*/ +//${Shared::AO_Table} ........................................................ extern QActive * const AO_Table; -/*$enddecl${AOs::AO_Table} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -#ifdef QP_INC_QXK_H_ - void Test1_ctor(void); - extern QXThread * const XT_Test1; - void Test2_ctor(void); - extern QXThread * const XT_Test2; -#endif /* QP_INC_QXK_H_ */ +//${Shared::Table_ctor} ...................................................... +void Table_ctor(void); +//$enddecl${Shared} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -#endif /* DPP_H */ +#ifdef QXK_H_ +extern QXThread * const TH_XThread1; +void XThread1_ctor(void); + +extern QXThread * const TH_XThread2; +void XThread2_ctor(void); + +extern QXSemaphore TH_sema; +extern QXMutex TH_mutex; + +#endif // QXK_H_ + +#endif // DPP_H_ diff --git a/examples/uc-os2/arm-cm/dpp_nucleo-l053r8/dpp.qm b/examples/uc-os2/arm-cm/dpp_nucleo-l053r8/dpp.qm index 93a66374..ac9f2bc9 100644 --- a/examples/uc-os2/arm-cm/dpp_nucleo-l053r8/dpp.qm +++ b/examples/uc-os2/arm-cm/dpp_nucleo-l053r8/dpp.qm @@ -1,141 +1,210 @@ - + Dining Philosopher Problem example - - - + + + + + { + EAT_SIG = Q_USER_SIG, // published by Table to let a Philo eat + DONE_SIG, // published by Philo when done eating + PAUSE_SIG, // published by BSP to pause the application + SERVE_SIG, // published by BSP to serve re-start serving forks + TEST_SIG, // published by BSP to test the application + MAX_PUB_SIG, // the last published signal + + TIMEOUT_SIG, // posted by time event to Philo + HUNGRY_SIG, // posted by hungry Philo to Table + MAX_SIG // the last signal +}; + + + + QS_SIG_DICTIONARY(EAT_SIG, (void *)0); +QS_SIG_DICTIONARY(DONE_SIG, (void *)0); +QS_SIG_DICTIONARY(PAUSE_SIG, (void *)0); +QS_SIG_DICTIONARY(SERVE_SIG, (void *)0); +QS_SIG_DICTIONARY(TEST_SIG, (void *)0); + +QS_SIG_DICTIONARY(TIMEOUT_SIG, (void *)0); +QS_SIG_DICTIONARY(HUNGRY_SIG, (void *)0); + + + + ((uint8_t)5U) + + - - + + + + + + + if (me != (TableEvt *)0) { + // don't call QEvt_ctor() because the initialization of all + // QEvt attributes is already done in QF_QF_newX_() + me->philoId = id; +} +return me; + + + + = { + &Philo_inst[0].super, + &Philo_inst[1].super, + &Philo_inst[2].super, + &Philo_inst[3].super, + &Philo_inst[4].super +}; + + + + + + Philo * const me = &Philo_inst[id]; +QActive_ctor(&me->super, Q_STATE_CAST(&Philo_initial)); +QTimeEvt_ctorX(&me->timeEvt, &me->super, TIMEOUT_SIG, 0U), +me->id = (uint8_t)id; + + + + = &Table_inst.super; + + + + Table * const me = &Table_inst; +QActive_ctor(&me->super, Q_STATE_CAST(&Table_initial)); +for (uint8_t n = 0U; n < N_PHILO; ++n) { + me->fork[n] = FREE; + me->isHungry[n] = false; +} + + The Philo AO and the N_PHILO instances + + + + - + - static uint8_t registered = (uint8_t)0; /* starts off with 0, per C-standard */ -(void)par; /* unused parameter */ -if (registered == (uint8_t)0) { - registered = (uint8_t)1; + Q_UNUSED_PAR(par); - QS_OBJ_DICTIONARY(&l_philo[0]); - QS_OBJ_DICTIONARY(&l_philo[0].timeEvt); - QS_OBJ_DICTIONARY(&l_philo[1]); - QS_OBJ_DICTIONARY(&l_philo[1].timeEvt); - QS_OBJ_DICTIONARY(&l_philo[2]); - QS_OBJ_DICTIONARY(&l_philo[2].timeEvt); - QS_OBJ_DICTIONARY(&l_philo[3]); - QS_OBJ_DICTIONARY(&l_philo[3].timeEvt); - QS_OBJ_DICTIONARY(&l_philo[4]); - QS_OBJ_DICTIONARY(&l_philo[4].timeEvt); - - QS_FUN_DICTIONARY(&Philo_initial); - QS_FUN_DICTIONARY(&Philo_thinking); - QS_FUN_DICTIONARY(&Philo_hungry); - QS_FUN_DICTIONARY(&Philo_eating); -} -QS_SIG_DICTIONARY(HUNGRY_SIG, me); /* signal for each Philos */ -QS_SIG_DICTIONARY(TIMEOUT_SIG, me); /* signal for each Philos */ +QS_OBJ_ARR_DICTIONARY(&Philo_inst[me->id], me->id); +QS_OBJ_ARR_DICTIONARY(&Philo_inst[me->id].timeEvt, me->id); QActive_subscribe(&me->super, EAT_SIG); QActive_subscribe(&me->super, TEST_SIG); - + - QTimeEvt_armX(&me->timeEvt, THINK_TIME, 0U); - QTimeEvt_disarm(&me->timeEvt); + QTimeEvt_armX(&me->timeEvt, think_time(), 0U); + (void)QTimeEvt_disarm(&me->timeEvt); - - + + - /* EAT or DONE must be for other Philos than this one */ -Q_ASSERT(Q_EVT_CAST(TableEvt)->philoNum != PHILO_ID(me)); - + // EAT or DONE must be for other Philos than this one +Q_ASSERT(Q_EVT_CAST(TableEvt)->philoId != me->id); + - + - + - + - TableEvt *pe = Q_NEW(TableEvt, HUNGRY_SIG); -pe->philoNum = PHILO_ID(me); -QACTIVE_POST(AO_Table, &pe->super, me); + #ifdef QEVT_DYN_CTOR +TableEvt const *pe = Q_NEW(TableEvt, HUNGRY_SIG, me->id); +#else +TableEvt *pe = Q_NEW(TableEvt, HUNGRY_SIG); +pe->philoId = me->id; +#endif +QACTIVE_POST(AO_Table, &pe->super, &me->super); - + - Q_EVT_CAST(TableEvt)->philoNum == PHILO_ID(me) - - + Q_EVT_CAST(TableEvt)->philoId == me->id + + - + - /* DONE must be for other Philos than this one */ -Q_ASSERT(Q_EVT_CAST(TableEvt)->philoNum != PHILO_ID(me)); - + // DONE must be for other Philos than this one +Q_ASSERT(Q_EVT_CAST(TableEvt)->philoId != me->id); + - + - QTimeEvt_armX(&me->timeEvt, EAT_TIME, 0U); - TableEvt *pe = Q_NEW(TableEvt, DONE_SIG); -pe->philoNum = PHILO_ID(me); + QTimeEvt_armX(&me->timeEvt, eat_time(), 0U); + (void)QTimeEvt_disarm(&me->timeEvt); + +#ifdef QEVT_DYN_CTOR +TableEvt const *pe = Q_NEW(TableEvt, DONE_SIG, me->id); +#else +TableEvt *pe = Q_NEW(TableEvt, DONE_SIG); +pe->philoId = me->id; +#endif QACTIVE_PUBLISH(&pe->super, &me->super); - - + + - /* EAT or DONE must be for other Philos than this one */ -Q_ASSERT(Q_EVT_CAST(TableEvt)->philoNum != PHILO_ID(me)); - + // EAT or DONE must be for other Philos than this one +Q_ASSERT(Q_EVT_CAST(TableEvt)->philoId != me->id); + - + - + @@ -143,21 +212,19 @@ Q_ASSERT(Q_EVT_CAST(TableEvt)->philoNum != PHILO_ID(me)); - + + + - + - (void)par; /* unused parameter */ + Q_UNUSED_PAR(par); -QS_OBJ_DICTIONARY(&l_table); - -QS_SIG_DICTIONARY(DONE_SIG, (void *)0); /* global signals */ -QS_SIG_DICTIONARY(EAT_SIG, (void *)0); -QS_SIG_DICTIONARY(PAUSE_SIG, (void *)0); -QS_SIG_DICTIONARY(SERVE_SIG, (void *)0); -QS_SIG_DICTIONARY(TEST_SIG, (void *)0); -QS_SIG_DICTIONARY(HUNGRY_SIG, me); /* signal just for Table */ +#ifdef Q_SPY +Table *Table_inst = me; +QS_OBJ_DICTIONARY(Table_inst); +#endif QActive_subscribe(&me->super, DONE_SIG); QActive_subscribe(&me->super, PAUSE_SIG); @@ -166,10 +233,10 @@ QActive_subscribe(&me->super, TEST_SIG); for (uint8_t n = 0U; n < N_PHILO; ++n) { me->fork[n] = FREE; - me->isHungry[n] = 0U; - BSP_displayPhilStat(n, "thinking"); + me->isHungry[n] = false; + BSP_displayPhilStat(n, THINKING); } - + @@ -177,128 +244,139 @@ for (uint8_t n = 0U; n < N_PHILO; ++n) { - + Q_ERROR(); - + - uint8_t n; -for (n = 0U; n < N_PHILO; ++n) { /* give permissions to eat... */ - if ((me->isHungry[n] != 0U) - && (me->fork[LEFT(n)] == FREE) + // give permissions to eat... +for (uint8_t n = 0U; n < N_PHILO; ++n) { + if (me->isHungry[n] + && (me->fork[left(n)] == FREE) && (me->fork[n] == FREE)) { - TableEvt *te; - - me->fork[LEFT(n)] = USED; + me->fork[left(n)] = USED; me->fork[n] = USED; - te = Q_NEW(TableEvt, EAT_SIG); - te->philoNum = n; - QACTIVE_PUBLISH(&te->super, &me->super); - me->isHungry[n] = 0U; - BSP_displayPhilStat(n, "eating "); +#ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, EAT_SIG, n); +#else + TableEvt *pe = Q_NEW(TableEvt, EAT_SIG); + pe->philoId = n; +#endif + QACTIVE_PUBLISH(&pe->super, &me->super); + me->isHungry[n] = false; + BSP_displayPhilStat(n, EATING); } } - uint8_t n, m; + uint8_t n = Q_EVT_CAST(TableEvt)->philoId; -n = Q_EVT_CAST(TableEvt)->philoNum; -/* phil ID must be in range and he must be not hungry */ -Q_ASSERT((n < N_PHILO) && (me->isHungry[n] == 0U)); +// phil ID must be in range and he must be not hungry +Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); -BSP_displayPhilStat(n, "hungry "); -m = LEFT(n); +BSP_displayPhilStat(n, HUNGRY); +uint8_t m = left(n); (me->fork[m] == FREE) && (me->fork[n] == FREE) - TableEvt *pe; -me->fork[m] = USED; + me->fork[m] = USED; me->fork[n] = USED; -pe = Q_NEW(TableEvt, EAT_SIG); -pe->philoNum = n; +#ifdef QEVT_DYN_CTOR +TableEvt const *pe = Q_NEW(TableEvt, EAT_SIG, n); +#else +TableEvt *pe = Q_NEW(TableEvt, EAT_SIG); +pe->philoId = n; +#endif QACTIVE_PUBLISH(&pe->super, &me->super); -BSP_displayPhilStat(n, "eating "); - +BSP_displayPhilStat(n, EATING); + else - me->isHungry[n] = 1U; - - + me->isHungry[n] = true; + + - + - uint8_t n, m; -TableEvt *pe; + uint8_t n = Q_EVT_CAST(TableEvt)->philoId; -n = Q_EVT_CAST(TableEvt)->philoNum; -/* phil ID must be in range and he must be not hungry */ -Q_ASSERT((n < N_PHILO) && (me->isHungry[n] == 0U)); +// phil ID must be in range and he must be not hungry +Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); -BSP_displayPhilStat(n, "thinking"); -m = LEFT(n); -/* both forks of Phil[n] must be used */ +BSP_displayPhilStat(n, THINKING); +uint8_t m = left(n); + +// both forks of Phil[n] must be used Q_ASSERT((me->fork[n] == USED) && (me->fork[m] == USED)); me->fork[m] = FREE; me->fork[n] = FREE; -m = RIGHT(n); /* check the right neighbor */ +m = right(n); // check the right neighbor -if ((me->isHungry[m] != 0U) && (me->fork[m] == FREE)) { +if (me->isHungry[m] && (me->fork[m] == FREE)) { me->fork[n] = USED; me->fork[m] = USED; - me->isHungry[m] = 0U; - pe = Q_NEW(TableEvt, EAT_SIG); - pe->philoNum = m; + me->isHungry[m] = false; +#ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, EAT_SIG, m); +#else + TableEvt *pe = Q_NEW(TableEvt, EAT_SIG); + pe->philoId = m; +#endif QACTIVE_PUBLISH(&pe->super, &me->super); - BSP_displayPhilStat(m, "eating "); + BSP_displayPhilStat(m, EATING); } -m = LEFT(n); /* check the left neighbor */ -n = LEFT(m); /* left fork of the left neighbor */ -if ((me->isHungry[m] != 0U) && (me->fork[n] == FREE)) { +m = left(n); // check the left neighbor +n = left(m); // left fork of the left neighbor +if (me->isHungry[m] && (me->fork[n] == FREE)) { me->fork[m] = USED; me->fork[n] = USED; - me->isHungry[m] = 0U; - pe = Q_NEW(TableEvt, EAT_SIG); - pe->philoNum = m; + me->isHungry[m] = false; +#ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, EAT_SIG, m); +#else + TableEvt *pe = Q_NEW(TableEvt, EAT_SIG); + pe->philoId = m; +#endif QACTIVE_PUBLISH(&pe->super, &me->super); - BSP_displayPhilStat(m, "eating "); + BSP_displayPhilStat(m, EATING); } - + Q_ERROR(); - + - + - + @@ -308,178 +386,140 @@ if ((me->isHungry[m] != 0U) && (me->fork[n] == FREE)) { BSP_displayPaused(0U); - + - uint8_t n = Q_EVT_CAST(TableEvt)->philoNum; -/* philo ID must be in range and he must be not hungry */ -Q_ASSERT((n < N_PHILO) && (me->isHungry[n] == 0U)); -me->isHungry[n] = 1U; -BSP_displayPhilStat(n, "hungry "); - + uint8_t n = Q_EVT_CAST(TableEvt)->philoId; + +// philo ID must be in range and he must be not hungry +Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); + +me->isHungry[n] = true; +BSP_displayPhilStat(n, HUNGRY); + - uint8_t n, m; + uint8_t n = Q_EVT_CAST(TableEvt)->philoId; -n = Q_EVT_CAST(TableEvt)->philoNum; -/* phil ID must be in range and he must be not hungry */ -Q_ASSERT((n < N_PHILO) && (me->isHungry[n] == 0U)); +// phil ID must be in range and he must be not hungry +Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); -BSP_displayPhilStat(n, "thinking"); -m = LEFT(n); -/* both forks of Phil[n] must be used */ +BSP_displayPhilStat(n, THINKING); +uint8_t m = left(n); + +// both forks of Phil[n] must be used Q_ASSERT((me->fork[n] == USED) && (me->fork[m] == USED)); me->fork[m] = FREE; me->fork[n] = FREE; - + - + - + - + - - - - - - - uint8_t n; -Philo *me; -for (n = 0U; n < N_PHILO; ++n) { - me = &l_philo[n]; - QActive_ctor(&me->super, Q_STATE_CAST(&Philo_initial)); - QTimeEvt_ctorX(&me->timeEvt, &me->super, TIMEOUT_SIG, 0U); -} - - - - uint8_t n; -Table *me = &l_table; - -QActive_ctor(&me->super, Q_STATE_CAST(&Table_initial)); - -for (n = 0U; n < N_PHILO; ++n) { - me->fork[n] = FREE; - me->isHungry[n] = 0U; -} - - #ifndef DPP_H -#define DPP_H + #ifndef DPP_H_ +#define DPP_H_ -enum DPPSignals { - EAT_SIG = Q_USER_SIG, /* published by Table to let a philosopher eat */ - DONE_SIG, /* published by Philosopher when done eating */ - PAUSE_SIG, /* published by BSP to pause serving forks */ - SERVE_SIG, /* published by BSP to serve re-start serving forks */ - TEST_SIG, /* published by BSP to test the application */ - MAX_PUB_SIG, /* the last published signal */ +$declare ${Shared} - HUNGRY_SIG, /* posted direclty to Table from hungry Philo */ - TIMEOUT_SIG, /* used by Philosophers for time events */ - MAX_SIG /* the last signal */ -}; +#ifdef QXK_H_ -$declare(Events::TableEvt) +extern QXThread * const TH_XThread1; +void XThread1_ctor(void); -/* number of philosophers */ -#define N_PHILO ((uint8_t)5) +extern QXThread * const TH_XThread2; +void XThread2_ctor(void); -$declare(AOs::Philo_ctor) -$declare(AOs::AO_Philo[N_PHILO]) +extern QXSemaphore TH_sema; +extern QXMutex TH_mutex; -$declare(AOs::Table_ctor) -$declare(AOs::AO_Table) +#endif // QXK_H_ -#ifdef QP_INC_QXK_H_ - void Test1_ctor(void); - extern QXThread * const XT_Test1; - void Test2_ctor(void); - extern QXThread * const XT_Test2; -#endif /* QP_INC_QXK_H_ */ - -#endif /* DPP_H */ - +#endif // DPP_H_ - #include "qpc.h" -#include "dpp.h" -#include "bsp.h" + #include "qpc.h" // QP/C real-time embedded framework +#include "dpp.h" // DPP Application interface +#include "bsp.h" // Board Support Package +$declare ${AOs::Philo} + +//---------------------------------------------------------------------------- Q_DEFINE_THIS_FILE -/* Active object class -----------------------------------------------------*/ -$declare(AOs::Philo) +// helper function to provide a randomized think time for Philos +static QTimeEvtCtr think_time(void); // prototype +static inline QTimeEvtCtr think_time(void) { + return (QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + + (BSP_TICKS_PER_SEC/2U)); +} -/* Local objects -----------------------------------------------------------*/ -static Philo l_philo[N_PHILO]; /* storage for all Philos */ +// helper function to provide a randomized eat time for Philos +static QTimeEvtCtr eat_time(void); // prototype +static inline QTimeEvtCtr eat_time(void) { + return (QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + + BSP_TICKS_PER_SEC); +} +//---------------------------------------------------------------------------- -#define THINK_TIME \ - (QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + (BSP_TICKS_PER_SEC/2U)) -#define EAT_TIME \ - (QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + BSP_TICKS_PER_SEC) - -/* helper macro to provide the ID of Philo "me_" */ -#define PHILO_ID(me_) ((uint8_t)((me_) - l_philo)) - -/* Global objects ----------------------------------------------------------*/ -QActive * const AO_Philo[N_PHILO] = { /* "opaque" pointers to Philo AO */ - &l_philo[0].super, - &l_philo[1].super, - &l_philo[2].super, - &l_philo[3].super, - &l_philo[4].super -}; - -/* Philo definition --------------------------------------------------------*/ -$define(AOs::Philo_ctor) -$define(AOs::Philo) +$define ${Shared::Philo_ctor} +$define ${Shared::AO_Philo[N_PHILO]} +$define ${AOs::Philo} - #include "qpc.h" -#include "dpp.h" -#include "bsp.h" + #include "qpc.h" // QP/C real-time embedded framework +#include "dpp.h" // DPP Application interface +#include "bsp.h" // Board Support Package +$declare ${AOs::Table} + +//---------------------------------------------------------------------------- Q_DEFINE_THIS_FILE -/* Active object class -----------------------------------------------------*/ -$declare(AOs::Table) +// helper function to provide the RIGHT neighbor of a Philo[n] +static inline uint8_t right(uint8_t const n) { + return (uint8_t)((n + (N_PHILO - 1U)) % N_PHILO); +} -#define RIGHT(n_) ((uint8_t)(((n_) + (N_PHILO - 1U)) % N_PHILO)) -#define LEFT(n_) ((uint8_t)(((n_) + 1U) % N_PHILO)) -#define FREE ((uint8_t)0) -#define USED ((uint8_t)1) +// helper function to provide the LEFT neighbor of a Philo[n] +static inline uint8_t left(uint8_t const n) { + return (uint8_t)((n + 1U) % N_PHILO); +} -/* Local objects -----------------------------------------------------------*/ -static Table l_table; /* the single instance of the Table active object */ +#define FREE ((uint8_t)0U) +#define USED ((uint8_t)1U) -/* Global-scope objects ----------------------------------------------------*/ -QActive * const AO_Table = &l_table.super; /* "opaque" AO pointer */ +#define THINKING "thinking" +#define HUNGRY "hungry " +#define EATING "eating " -/*..........................................................................*/ -$define(AOs::Table_ctor) -$define(AOs::Table) +//---------------------------------------------------------------------------- + +$define ${Shared::Table_ctor} +$define ${Shared::AO_Table} +$define ${AOs::Table} diff --git a/examples/uc-os2/arm-cm/dpp_nucleo-l053r8/gnu/Makefile b/examples/uc-os2/arm-cm/dpp_nucleo-l053r8/gnu/Makefile index 7f6b54d8..3198515e 100644 --- a/examples/uc-os2/arm-cm/dpp_nucleo-l053r8/gnu/Makefile +++ b/examples/uc-os2/arm-cm/dpp_nucleo-l053r8/gnu/Makefile @@ -219,11 +219,11 @@ ASFLAGS = -g $(ARM_CPU) $(ARM_FPU) $(ASM_CPU) $(ASM_FPU) CFLAGS = -c -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \ -ffunction-sections -fdata-sections \ - -O2 $(INCLUDES) $(DEFINES) -DQ_SPY + -O $(INCLUDES) $(DEFINES) -DQ_SPY CPPFLAGS = -c -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \ -ffunction-sections -fdata-sections -fno-rtti -fno-exceptions \ - -O2 $(INCLUDES) $(DEFINES) -DQ_SPY + -O $(INCLUDES) $(DEFINES) -DQ_SPY else # default Debug configuration .......................................... @@ -233,11 +233,11 @@ ASFLAGS = -g $(ARM_CPU) $(ARM_FPU) $(ASM_CPU) $(ASM_FPU) CFLAGS = -c -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \ -ffunction-sections -fdata-sections \ - -O2 $(INCLUDES) $(DEFINES) + -O $(INCLUDES) $(DEFINES) CPPFLAGS = -c -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \ -ffunction-sections -fdata-sections -fno-rtti -fno-exceptions \ - -O2 $(INCLUDES) $(DEFINES) + -O $(INCLUDES) $(DEFINES) endif # ...................................................................... @@ -275,7 +275,7 @@ $(TARGET_BIN): $(TARGET_ELF) $(BIN) -O binary $< $@ $(TARGET_ELF) : $(ASM_OBJS_EXT) $(C_OBJS_EXT) $(CPP_OBJS_EXT) - $(CC) $(CFLAGS) $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o + $(CC) $(CFLAGS) $(QPC)/src/qs/qstamp.c -o $(BIN_DIR)/qstamp.o $(LINK) $(LINKFLAGS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) $(BIN_DIR)/%.d : %.c diff --git a/examples/uc-os2/arm-cm/dpp_nucleo-l053r8/iar/dpp.ewd b/examples/uc-os2/arm-cm/dpp_nucleo-l053r8/iar/dpp.ewd index 1a137bd4..a1af8f65 100644 --- a/examples/uc-os2/arm-cm/dpp_nucleo-l053r8/iar/dpp.ewd +++ b/examples/uc-os2/arm-cm/dpp_nucleo-l053r8/iar/dpp.ewd @@ -88,7 +88,7 @@
- - $TOOLKIT_DIR$\plugins\rtos\HWRTOSplugin\HWRTOSplugin.ewplugin - 0 - $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin.ENU.ewplugin 0 @@ -1436,30 +1509,22 @@ $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin 0 - - $TOOLKIT_DIR$\plugins\rtos\RemedyRtosViewer\RemedyRtosViewer.ewplugin - 0 - $TOOLKIT_DIR$\plugins\rtos\SafeRTOS\SafeRTOSPlugin.ewplugin 0 - $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm8.ewplugin + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9.ewplugin 0 - $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm8BE.ewplugin + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9BE.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin 0 - - $TOOLKIT_DIR$\plugins\rtos\TI-RTOS\tirtosplugin.ewplugin - 0 - $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-286-KA-CSpy.ewplugin 0 @@ -1573,7 +1638,7 @@ - - $TOOLKIT_DIR$\plugins\rtos\HWRTOSplugin\HWRTOSplugin.ewplugin - 0 - $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin.ENU.ewplugin 0 @@ -2921,30 +3059,22 @@ $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin 0 - - $TOOLKIT_DIR$\plugins\rtos\RemedyRtosViewer\RemedyRtosViewer.ewplugin - 0 - $TOOLKIT_DIR$\plugins\rtos\SafeRTOS\SafeRTOSPlugin.ewplugin 0 - $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm8.ewplugin + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9.ewplugin 0 - $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm8BE.ewplugin + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9BE.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin 0 - - $TOOLKIT_DIR$\plugins\rtos\TI-RTOS\tirtosplugin.ewplugin - 0 - $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-286-KA-CSpy.ewplugin 0 @@ -3058,7 +3188,7 @@ - - $TOOLKIT_DIR$\plugins\rtos\HWRTOSplugin\HWRTOSplugin.ewplugin - 0 - $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin.ENU.ewplugin 0 @@ -4406,30 +4609,22 @@ $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin 0 - - $TOOLKIT_DIR$\plugins\rtos\RemedyRtosViewer\RemedyRtosViewer.ewplugin - 0 - $TOOLKIT_DIR$\plugins\rtos\SafeRTOS\SafeRTOSPlugin.ewplugin 0 - $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm8.ewplugin + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9.ewplugin 0 - $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm8BE.ewplugin + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9BE.ewplugin 0 $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin 0 - - $TOOLKIT_DIR$\plugins\rtos\TI-RTOS\tirtosplugin.ewplugin - 0 - $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-286-KA-CSpy.ewplugin 0 diff --git a/examples/uc-os2/arm-cm/dpp_nucleo-l053r8/iar/dpp.ewp b/examples/uc-os2/arm-cm/dpp_nucleo-l053r8/iar/dpp.ewp index 1901aa88..79547d2b 100644 --- a/examples/uc-os2/arm-cm/dpp_nucleo-l053r8/iar/dpp.ewp +++ b/examples/uc-os2/arm-cm/dpp_nucleo-l053r8/iar/dpp.ewp @@ -11,12 +11,12 @@ General 3 - 33 + 35 1 1 + + + @@ -673,7 +685,7 @@ ILINK 0 - 25 + 27 1 1 + + + + @@ -1064,12 +1092,12 @@ General 3 - 33 + 35 1 0 + + + @@ -1727,7 +1767,7 @@ ILINK 0 - 25 + 27 1 0 + + + + @@ -2118,12 +2174,12 @@ General 3 - 33 + 35 1 1 + + + @@ -2322,7 +2390,6 @@ @@ -3185,9 +3268,6 @@ $PROJ_DIR$\..\philo.c - - $PROJ_DIR$\..\..\..\..\..\include\qstamp.c - $PROJ_DIR$\..\table.c @@ -3248,24 +3328,9 @@ QP_port - - $PROJ_DIR$\..\..\..\..\..\ports\uc-os2\app_cfg.h - - - $PROJ_DIR$\..\..\..\..\..\ports\uc-os2\os_cfg.h - - - $PROJ_DIR$\..\..\..\..\..\ports\uc-os2\qep_port.h - $PROJ_DIR$\..\..\..\..\..\ports\uc-os2\qf_port.c - - $PROJ_DIR$\..\..\..\..\..\ports\uc-os2\qf_port.h - - - $PROJ_DIR$\..\..\..\..\..\ports\uc-os2\qs_port.h - QS @@ -3286,7 +3351,7 @@ $PROJ_DIR$\..\..\..\..\..\src\qs\qs_rx.c - $PROJ_DIR$\..\..\..\..\..\src\qs\qutest.c + $PROJ_DIR$\..\..\..\..\..\src\qs\qstamp.c diff --git a/examples/uc-os2/arm-cm/dpp_nucleo-l053r8/iar/dpp.icf b/examples/uc-os2/arm-cm/dpp_nucleo-l053r8/iar/dpp.icf index 1acff018..9cf38ef5 100644 --- a/examples/uc-os2/arm-cm/dpp_nucleo-l053r8/iar/dpp.icf +++ b/examples/uc-os2/arm-cm/dpp_nucleo-l053r8/iar/dpp.icf @@ -9,7 +9,7 @@ define symbol __ICFEDIT_region_ROM_end__ = 0x0800FFFF; define symbol __ICFEDIT_region_RAM_start__ = 0x20000000; define symbol __ICFEDIT_region_RAM_end__ = 0x20001FFF; /*-Sizes-*/ -define symbol __ICFEDIT_size_cstack__ = 2048; +define symbol __ICFEDIT_size_cstack__ = 1024; define symbol __ICFEDIT_size_heap__ = 0; /**** End of ICF editor section. ###ICF###*/ diff --git a/examples/uc-os2/arm-cm/dpp_nucleo-l053r8/main.c b/examples/uc-os2/arm-cm/dpp_nucleo-l053r8/main.c index 7ab7a842..cfcfaf07 100644 --- a/examples/uc-os2/arm-cm/dpp_nucleo-l053r8/main.c +++ b/examples/uc-os2/arm-cm/dpp_nucleo-l053r8/main.c @@ -1,94 +1,44 @@ -/***************************************************************************** -* Product: DPP example, uC/OS-II -* Last updated for version 6.8.1 -* Last updated on 2020-06-08 -* -* Q u a n t u m L e a P s -* ------------------------ -* Modern Embedded Software -* -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* -* -*****************************************************************************/ -#include "qpc.h" -#include "dpp.h" -#include "bsp.h" +//============================================================================ +// APP example +// Last updated for version 7.3.0 +// Last updated on 2023-08-09 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. +// +// This program is open source software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Alternatively, this program may be distributed and modified under the +// terms of Quantum Leaps commercial licenses, which expressly supersede +// the GNU General Public License and are specifically designed for +// licensees interested in retaining the proprietary status of their code. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Contact information: +// +// +//============================================================================ +#include "qpc.h" // QP/C real-time embedded framework +#include "dpp.h" // DPP Application interface +#include "bsp.h" // Board Support Package -Q_DEFINE_THIS_FILE - -/*..........................................................................*/ +//............................................................................ int main() { - static QEvt const *tableQueueSto[N_PHILO]; - static QEvt const *philoQueueSto[N_PHILO][N_PHILO]; - - static OS_STK philoStk[N_PHILO][100]; /* stacks for the Philosophers */ - static OS_STK tableStk[128]; /* stack for the Table */ - - static QSubscrList subscrSto[MAX_PUB_SIG]; - static QF_MPOOL_EL(TableEvt) smlPoolSto[2*N_PHILO]; /* event pool */ - uint8_t n; - - /* in C you need to explicitly instantiate all AOs... */ - Philo_ctor(); - Table_ctor(); - - QF_init(); /* initialize the framework and the underlying RT kernel */ - BSP_init(); /* initialize the Board Support Package */ - - /* init publish-subscribe */ - QF_psInit(subscrSto, Q_DIM(subscrSto)); - - /* initialize event pools... */ - QF_poolInit(smlPoolSto, sizeof(smlPoolSto), sizeof(smlPoolSto[0])); - - /* start the active objects... */ - /* CAUTION: - * Make sure to configure **SUFFICIENT** number of uC/OS-II tasks and - * message queues in "os_cfg.h" for all your active objects!!! - */ - for (n = 0U; n < N_PHILO; ++n) { - /* NOTE: provide uC/OS-II task attributes for the AO's task */ - QActive_setAttr(AO_Philo[n], OS_TASK_OPT_STK_CHK, 0); - QACTIVE_START(AO_Philo[n], - n + 1U, /* QP priority */ - philoQueueSto[n], /* storage for the AO's queue */ - Q_DIM(philoQueueSto[n]), /* queue's length [entries] */ - philoStk[n], /* stack storage */ - sizeof(philoStk[n]), /* sack size [bytes] */ - (QEvt const *)0); /* initialization event */ - } - - /* NOTE: provide uC/OS-II task attributes for the AO's task */ - QActive_setAttr(AO_Table, OS_TASK_OPT_STK_CLR | OS_TASK_OPT_STK_CHK, 0); - QACTIVE_START(AO_Table, - N_PHILO + 1U, /* QP priority */ - tableQueueSto, /* storage for the AO's queue */ - Q_DIM(tableQueueSto), /* queue's length [entries] */ - tableStk, /* stack storage */ - sizeof(tableStk), /* sack size [bytes] */ - (QEvt const *)0); /* initialization event */ - - return QF_run(); /* run the QF application */ + QF_init(); // initialize the framework and the underlying RT kernel + BSP_init(); // initialize the BSP + BSP_start(); // start the AOs/Threads + return QF_run(); // run the QF application } - diff --git a/examples/uc-os2/arm-cm/dpp_nucleo-l053r8/os_cfg.h b/examples/uc-os2/arm-cm/dpp_nucleo-l053r8/os_cfg.h index 495075ed..70c997d7 100644 --- a/examples/uc-os2/arm-cm/dpp_nucleo-l053r8/os_cfg.h +++ b/examples/uc-os2/arm-cm/dpp_nucleo-l053r8/os_cfg.h @@ -1,154 +1,154 @@ -/* -********************************************************************************************************* -* uC/OS-II -* The Real-Time Kernel -* -* Copyright 1992-2020 Silicon Laboratories Inc. www.silabs.com -* -* SPDX-License-Identifier: APACHE-2.0 -* -* This software is subject to an open source license and is distributed by -* Silicon Laboratories Inc. pursuant to the terms of the Apache License, -* Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. -* -********************************************************************************************************* -*/ +// +//============================================================================*************************** +// uC/OS-II +// The Real-Time Kernel +// +// Copyright 1992-2020 Silicon Laboratories Inc. www.silabs.com +// +// SPDX-License-Identifier: APACHE-2.0 +// +// This software is subject to an open source license and is distributed by +// Silicon Laboratories Inc. pursuant to the terms of the Apache License, +// Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. +// +//============================================================================*************************** +// -/* -********************************************************************************************************* -* -* uC/OS-II Configuration File for V2.9x -* -* Filename : os_cfg.h -* Version : V2.93.00 -********************************************************************************************************* -*/ +// +//============================================================================*************************** +// +// uC/OS-II Configuration File for V2.9x +// +// Filename : os_cfg.h +// Version : V2.93.00 +//============================================================================*************************** +// #ifndef OS_CFG_H #define OS_CFG_H - /* ---------------------- MISCELLANEOUS ----------------------- */ -#define OS_APP_HOOKS_EN 1u /* Application-defined hooks are called from the uC/OS-II hooks */ -#define OS_ARG_CHK_EN 1u /* Enable (1) or Disable (0) argument checking */ -#define OS_CPU_HOOKS_EN 1u /* uC/OS-II hooks are found in the processor port files */ + // ---------------------- MISCELLANEOUS ----------------------- +#define OS_APP_HOOKS_EN 1u // Application-defined hooks are called from the uC/OS-II hooks +#define OS_ARG_CHK_EN 1u // Enable (1) or Disable (0) argument checking +#define OS_CPU_HOOKS_EN 1u // uC/OS-II hooks are found in the processor port files -#define OS_DEBUG_EN 1u /* Enable(1) debug variables */ +#define OS_DEBUG_EN 1u // Enable(1) debug variables -#define OS_EVENT_MULTI_EN 0u /* Include code for OSEventPendMulti() */ -#define OS_EVENT_NAME_EN 1u /* Enable names for Sem, Mutex, Mbox and Q */ +#define OS_EVENT_MULTI_EN 0u // Include code for OSEventPendMulti() +#define OS_EVENT_NAME_EN 1u // Enable names for Sem, Mutex, Mbox and Q -#define OS_LOWEST_PRIO 8u /* Defines the lowest priority that can be assigned ... */ - /* ... MUST NEVER be higher than 254! */ +#define OS_LOWEST_PRIO 8u // Defines the lowest priority that can be assigned ... + // ... MUST NEVER be higher than 254! -#define OS_MAX_EVENTS 8u /* Max. number of event control blocks in your application */ -#define OS_MAX_FLAGS 0u /* Max. number of Event Flag Groups in your application */ -#define OS_MAX_MEM_PART 3u /* Max. number of memory partitions */ -#define OS_MAX_QS 6u /* Max. number of queue control blocks in your application */ -#define OS_MAX_TASKS 6u /* Max. number of tasks in your application, MUST be >= 2 */ +#define OS_MAX_EVENTS 8u // Max. number of event control blocks in your application +#define OS_MAX_FLAGS 0u // Max. number of Event Flag Groups in your application +#define OS_MAX_MEM_PART 3u // Max. number of memory partitions +#define OS_MAX_QS 6u // Max. number of queue control blocks in your application +#define OS_MAX_TASKS 6u // Max. number of tasks in your application, MUST be >= 2 -#define OS_SCHED_LOCK_EN 1u /* Include code for OSSchedLock() and OSSchedUnlock() */ +#define OS_SCHED_LOCK_EN 1u // Include code for OSSchedLock() and OSSchedUnlock() -#define OS_TICK_STEP_EN 1u /* Enable tick stepping feature for uC/OS-View */ -#define OS_TICKS_PER_SEC 100u /* Set the number of ticks in one second */ +#define OS_TICK_STEP_EN 1u // Enable tick stepping feature for uC/OS-View +#define OS_TICKS_PER_SEC 100u // Set the number of ticks in one second -#define OS_TLS_TBL_SIZE 0u /* Size of Thread-Local Storage Table */ +#define OS_TLS_TBL_SIZE 0u // Size of Thread-Local Storage Table - /* --------------------- TASK STACK SIZE ---------------------- */ -#define OS_TASK_TMR_STK_SIZE 100u /* Timer task stack size (# of OS_STK wide entries) */ -#define OS_TASK_STAT_STK_SIZE 100u /* Statistics task stack size (# of OS_STK wide entries) */ -#define OS_TASK_IDLE_STK_SIZE 100u /* Idle task stack size (# of OS_STK wide entries) */ + // --------------------- TASK STACK SIZE ---------------------- +#define OS_TASK_TMR_STK_SIZE 100u // Timer task stack size (# of OS_STK wide entries) +#define OS_TASK_STAT_STK_SIZE 100u // Statistics task stack size (# of OS_STK wide entries) +#define OS_TASK_IDLE_STK_SIZE 100u // Idle task stack size (# of OS_STK wide entries) - /* --------------------- TASK MANAGEMENT ---------------------- */ -#define OS_TASK_CHANGE_PRIO_EN 0u /* Include code for OSTaskChangePrio() */ -#define OS_TASK_CREATE_EN 1u /* Include code for OSTaskCreate() */ -#define OS_TASK_CREATE_EXT_EN 1u /* Include code for OSTaskCreateExt() */ -#define OS_TASK_DEL_EN 1u /* Include code for OSTaskDel() */ -#define OS_TASK_NAME_EN 1u /* Enable task names */ -#define OS_TASK_PROFILE_EN 1u /* Include variables in OS_TCB for profiling */ -#define OS_TASK_QUERY_EN 1u /* Include code for OSTaskQuery() */ -#define OS_TASK_REG_TBL_SIZE 1u /* Size of task variables array (#of INT32U entries) */ -#define OS_TASK_STAT_EN 1u /* Enable (1) or Disable(0) the statistics task */ -#define OS_TASK_STAT_STK_CHK_EN 1u /* Check task stacks from statistic task */ -#define OS_TASK_SUSPEND_EN 1u /* Include code for OSTaskSuspend() and OSTaskResume() */ -#define OS_TASK_SW_HOOK_EN 1u /* Include code for OSTaskSwHook() */ + // --------------------- TASK MANAGEMENT ---------------------- +#define OS_TASK_CHANGE_PRIO_EN 0u // Include code for OSTaskChangePrio() +#define OS_TASK_CREATE_EN 1u // Include code for OSTaskCreate() +#define OS_TASK_CREATE_EXT_EN 1u // Include code for OSTaskCreateExt() +#define OS_TASK_DEL_EN 1u // Include code for OSTaskDel() +#define OS_TASK_NAME_EN 1u // Enable task names +#define OS_TASK_PROFILE_EN 1u // Include variables in OS_TCB for profiling +#define OS_TASK_QUERY_EN 1u // Include code for OSTaskQuery() +#define OS_TASK_REG_TBL_SIZE 1u // Size of task variables array (#of INT32U entries) +#define OS_TASK_STAT_EN 1u // Enable (1) or Disable(0) the statistics task +#define OS_TASK_STAT_STK_CHK_EN 1u // Check task stacks from statistic task +#define OS_TASK_SUSPEND_EN 1u // Include code for OSTaskSuspend() and OSTaskResume() +#define OS_TASK_SW_HOOK_EN 1u // Include code for OSTaskSwHook() - /* ----------------------- EVENT FLAGS ------------------------ */ -#define OS_FLAG_EN 0u /* Enable (1) or Disable (0) code generation for EVENT FLAGS */ -#define OS_FLAG_ACCEPT_EN 1u /* Include code for OSFlagAccept() */ -#define OS_FLAG_DEL_EN 1u /* Include code for OSFlagDel() */ -#define OS_FLAG_NAME_EN 1u /* Enable names for event flag group */ -#define OS_FLAG_QUERY_EN 1u /* Include code for OSFlagQuery() */ -#define OS_FLAG_WAIT_CLR_EN 1u /* Include code for Wait on Clear EVENT FLAGS */ -#define OS_FLAGS_NBITS 16u /* Size in #bits of OS_FLAGS data type (8, 16 or 32) */ + // ----------------------- EVENT FLAGS ------------------------ +#define OS_FLAG_EN 0u // Enable (1) or Disable (0) code generation for EVENT FLAGS +#define OS_FLAG_ACCEPT_EN 1u // Include code for OSFlagAccept() +#define OS_FLAG_DEL_EN 1u // Include code for OSFlagDel() +#define OS_FLAG_NAME_EN 1u // Enable names for event flag group +#define OS_FLAG_QUERY_EN 1u // Include code for OSFlagQuery() +#define OS_FLAG_WAIT_CLR_EN 1u // Include code for Wait on Clear EVENT FLAGS +#define OS_FLAGS_NBITS 16u // Size in #bits of OS_FLAGS data type (8, 16 or 32) - /* -------------------- MESSAGE MAILBOXES --------------------- */ -#define OS_MBOX_EN 0u /* Enable (1) or Disable (0) code generation for MAILBOXES */ -#define OS_MBOX_ACCEPT_EN 1u /* Include code for OSMboxAccept() */ -#define OS_MBOX_DEL_EN 1u /* Include code for OSMboxDel() */ -#define OS_MBOX_PEND_ABORT_EN 1u /* Include code for OSMboxPendAbort() */ -#define OS_MBOX_POST_EN 1u /* Include code for OSMboxPost() */ -#define OS_MBOX_POST_OPT_EN 1u /* Include code for OSMboxPostOpt() */ -#define OS_MBOX_QUERY_EN 1u /* Include code for OSMboxQuery() */ + // -------------------- MESSAGE MAILBOXES --------------------- +#define OS_MBOX_EN 0u // Enable (1) or Disable (0) code generation for MAILBOXES +#define OS_MBOX_ACCEPT_EN 1u // Include code for OSMboxAccept() +#define OS_MBOX_DEL_EN 1u // Include code for OSMboxDel() +#define OS_MBOX_PEND_ABORT_EN 1u // Include code for OSMboxPendAbort() +#define OS_MBOX_POST_EN 1u // Include code for OSMboxPost() +#define OS_MBOX_POST_OPT_EN 1u // Include code for OSMboxPostOpt() +#define OS_MBOX_QUERY_EN 1u // Include code for OSMboxQuery() - /* --------------------- MEMORY MANAGEMENT -------------------- */ -#define OS_MEM_EN 1u /* Enable (1) or Disable (0) code generation for MEMORY MANAGER */ -#define OS_MEM_NAME_EN 1u /* Enable memory partition names */ -#define OS_MEM_QUERY_EN 1u /* Include code for OSMemQuery() */ + // --------------------- MEMORY MANAGEMENT -------------------- +#define OS_MEM_EN 1u // Enable (1) or Disable (0) code generation for MEMORY MANAGER +#define OS_MEM_NAME_EN 1u // Enable memory partition names +#define OS_MEM_QUERY_EN 1u // Include code for OSMemQuery() - /* ---------------- MUTUAL EXCLUSION SEMAPHORES --------------- */ -#define OS_MUTEX_EN 1u /* Enable (1) or Disable (0) code generation for MUTEX */ -#define OS_MUTEX_ACCEPT_EN 1u /* Include code for OSMutexAccept() */ -#define OS_MUTEX_DEL_EN 1u /* Include code for OSMutexDel() */ -#define OS_MUTEX_QUERY_EN 1u /* Include code for OSMutexQuery() */ + // ---------------- MUTUAL EXCLUSION SEMAPHORES --------------- +#define OS_MUTEX_EN 1u // Enable (1) or Disable (0) code generation for MUTEX +#define OS_MUTEX_ACCEPT_EN 1u // Include code for OSMutexAccept() +#define OS_MUTEX_DEL_EN 1u // Include code for OSMutexDel() +#define OS_MUTEX_QUERY_EN 1u // Include code for OSMutexQuery() - /* ---------------------- MESSAGE QUEUES ---------------------- */ -#define OS_Q_EN 1u /* Enable (1) or Disable (0) code generation for QUEUES */ -#define OS_Q_ACCEPT_EN 1u /* Include code for OSQAccept() */ -#define OS_Q_DEL_EN 1u /* Include code for OSQDel() */ -#define OS_Q_FLUSH_EN 1u /* Include code for OSQFlush() */ -#define OS_Q_PEND_ABORT_EN 1u /* Include code for OSQPendAbort() */ -#define OS_Q_POST_EN 1u /* Include code for OSQPost() */ -#define OS_Q_POST_FRONT_EN 1u /* Include code for OSQPostFront() */ -#define OS_Q_POST_OPT_EN 1u /* Include code for OSQPostOpt() */ -#define OS_Q_QUERY_EN 1u /* Include code for OSQQuery() */ + // ---------------------- MESSAGE QUEUES ---------------------- +#define OS_Q_EN 1u // Enable (1) or Disable (0) code generation for QUEUES +#define OS_Q_ACCEPT_EN 1u // Include code for OSQAccept() +#define OS_Q_DEL_EN 1u // Include code for OSQDel() +#define OS_Q_FLUSH_EN 1u // Include code for OSQFlush() +#define OS_Q_PEND_ABORT_EN 1u // Include code for OSQPendAbort() +#define OS_Q_POST_EN 1u // Include code for OSQPost() +#define OS_Q_POST_FRONT_EN 1u // Include code for OSQPostFront() +#define OS_Q_POST_OPT_EN 1u // Include code for OSQPostOpt() +#define OS_Q_QUERY_EN 1u // Include code for OSQQuery() - /* ------------------------ SEMAPHORES ------------------------ */ -#define OS_SEM_EN 0u /* Enable (1) or Disable (0) code generation for SEMAPHORES */ -#define OS_SEM_ACCEPT_EN 1u /* Include code for OSSemAccept() */ -#define OS_SEM_DEL_EN 1u /* Include code for OSSemDel() */ -#define OS_SEM_PEND_ABORT_EN 1u /* Include code for OSSemPendAbort() */ -#define OS_SEM_QUERY_EN 1u /* Include code for OSSemQuery() */ -#define OS_SEM_SET_EN 1u /* Include code for OSSemSet() */ + // ------------------------ SEMAPHORES ------------------------ +#define OS_SEM_EN 0u // Enable (1) or Disable (0) code generation for SEMAPHORES +#define OS_SEM_ACCEPT_EN 1u // Include code for OSSemAccept() +#define OS_SEM_DEL_EN 1u // Include code for OSSemDel() +#define OS_SEM_PEND_ABORT_EN 1u // Include code for OSSemPendAbort() +#define OS_SEM_QUERY_EN 1u // Include code for OSSemQuery() +#define OS_SEM_SET_EN 1u // Include code for OSSemSet() - /* --------------------- TIME MANAGEMENT ---------------------- */ -#define OS_TIME_DLY_HMSM_EN 0u /* Include code for OSTimeDlyHMSM() */ -#define OS_TIME_DLY_RESUME_EN 1u /* Include code for OSTimeDlyResume() */ -#define OS_TIME_GET_SET_EN 1u /* Include code for OSTimeGet() and OSTimeSet() */ -#define OS_TIME_TICK_HOOK_EN 1u /* Include code for OSTimeTickHook() */ + // --------------------- TIME MANAGEMENT ---------------------- +#define OS_TIME_DLY_HMSM_EN 0u // Include code for OSTimeDlyHMSM() +#define OS_TIME_DLY_RESUME_EN 1u // Include code for OSTimeDlyResume() +#define OS_TIME_GET_SET_EN 1u // Include code for OSTimeGet() and OSTimeSet() +#define OS_TIME_TICK_HOOK_EN 1u // Include code for OSTimeTickHook() - /* --------------------- TIMER MANAGEMENT --------------------- */ -#define OS_TMR_EN 0u /* Enable (1) or Disable (0) code generation for TIMERS */ -#define OS_TMR_CFG_MAX 16u /* Maximum number of timers */ -#define OS_TMR_CFG_NAME_EN 1u /* Determine timer names */ -#define OS_TMR_CFG_WHEEL_SIZE 7u /* Size of timer wheel (#Spokes) */ -#define OS_TMR_CFG_TICKS_PER_SEC 10u /* Rate at which timer management task runs (Hz) */ + // --------------------- TIMER MANAGEMENT --------------------- +#define OS_TMR_EN 0u // Enable (1) or Disable (0) code generation for TIMERS +#define OS_TMR_CFG_MAX 16u // Maximum number of timers +#define OS_TMR_CFG_NAME_EN 1u // Determine timer names +#define OS_TMR_CFG_WHEEL_SIZE 7u // Size of timer wheel (#Spokes) +#define OS_TMR_CFG_TICKS_PER_SEC 10u // Rate at which timer management task runs (Hz) - /* ---------------------- TRACE RECORDER ---------------------- */ -#define OS_TRACE_EN 0u /* Enable (1) or Disable (0) uC/OS-II Trace instrumentation */ -#define OS_TRACE_API_ENTER_EN 0u /* Enable (1) or Disable (0) uC/OS-II Trace API enter instrum. */ -#define OS_TRACE_API_EXIT_EN 0u /* Enable (1) or Disable (0) uC/OS-II Trace API exit instrum. */ + // ---------------------- TRACE RECORDER ---------------------- +#define OS_TRACE_EN 0u // Enable (1) or Disable (0) uC/OS-II Trace instrumentation +#define OS_TRACE_API_ENTER_EN 0u // Enable (1) or Disable (0) uC/OS-II Trace API enter instrum. +#define OS_TRACE_API_EXIT_EN 0u // Enable (1) or Disable (0) uC/OS-II Trace API exit instrum. #endif diff --git a/examples/uc-os2/arm-cm/dpp_nucleo-l053r8/philo.c b/examples/uc-os2/arm-cm/dpp_nucleo-l053r8/philo.c index 7614912a..eb6be531 100644 --- a/examples/uc-os2/arm-cm/dpp_nucleo-l053r8/philo.c +++ b/examples/uc-os2/arm-cm/dpp_nucleo-l053r8/philo.c @@ -1,165 +1,159 @@ -/*$file${.::philo.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* -* Model: dpp.qm -* File: ${.::philo.c} -* -* This code has been generated by QM 5.2.4 . -* DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. -* -* SPDX-License-Identifier: GPL-3.0-or-later -* -* This generated code is open source software: you can redistribute it under -* the terms of the GNU General Public License as published by the Free -* Software Foundation. -* -* This code is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -* more details. -* -* NOTE: -* Alternatively, this generated code may be distributed under the terms -* of Quantum Leaps commercial licenses, which expressly supersede the GNU -* General Public License and are specifically designed for licensees -* interested in retaining the proprietary status of their code. -* -* Contact information: -* -* -*/ -/*$endhead${.::philo.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -#include "qpc.h" -#include "dpp.h" -#include "bsp.h" +//$file${.::philo.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// +// Model: dpp.qm +// File: ${.::philo.c} +// +// This code has been generated by QM 5.3.0 . +// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. +// +// SPDX-License-Identifier: GPL-3.0-or-later +// +// This generated code is open source software: you can redistribute it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation. +// +// This code is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// NOTE: +// Alternatively, this generated code may be distributed under the terms +// of Quantum Leaps commercial licenses, which expressly supersede the GNU +// General Public License and are specifically designed for licensees +// interested in retaining the proprietary status of their code. +// +// Contact information: +// +// +// +//$endhead${.::philo.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +#include "qpc.h" // QP/C real-time embedded framework +#include "dpp.h" // DPP Application interface +#include "bsp.h" // Board Support Package -Q_DEFINE_THIS_FILE +//$declare${AOs::Philo} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/* Active object class -----------------------------------------------------*/ -/*$declare${AOs::Philo} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${AOs::Philo} ............................................................*/ -typedef struct { -/* protected: */ +//${AOs::Philo} .............................................................. +typedef struct Philo { +// protected: QActive super; -/* private: */ +// private: QTimeEvt timeEvt; + uint8_t id; + +// public: } Philo; -/* protected: */ +extern Philo Philo_inst[N_PHILO]; + +// protected: static QState Philo_initial(Philo * const me, void const * const par); static QState Philo_thinking(Philo * const me, QEvt const * const e); static QState Philo_hungry(Philo * const me, QEvt const * const e); static QState Philo_eating(Philo * const me, QEvt const * const e); -/*$enddecl${AOs::Philo} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$enddecl${AOs::Philo} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -/* Local objects -----------------------------------------------------------*/ -static Philo l_philo[N_PHILO]; /* storage for all Philos */ +//---------------------------------------------------------------------------- +Q_DEFINE_THIS_FILE -#define THINK_TIME \ - (QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + (BSP_TICKS_PER_SEC/2U)) -#define EAT_TIME \ - (QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + BSP_TICKS_PER_SEC) - -/* helper macro to provide the ID of Philo "me_" */ -#define PHILO_ID(me_) ((uint8_t)((me_) - l_philo)) - -/* Global objects ----------------------------------------------------------*/ -QActive * const AO_Philo[N_PHILO] = { /* "opaque" pointers to Philo AO */ - &l_philo[0].super, - &l_philo[1].super, - &l_philo[2].super, - &l_philo[3].super, - &l_philo[4].super -}; - -/* Philo definition --------------------------------------------------------*/ -/*$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* Check for the minimum required QP version */ -#if (QP_VERSION < 700U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) -#error qpc version 7.0.0 or higher required -#endif -/*$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ - -/*$define${AOs::Philo_ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${AOs::Philo_ctor} .......................................................*/ -void Philo_ctor(void) { - uint8_t n; - Philo *me; - for (n = 0U; n < N_PHILO; ++n) { - me = &l_philo[n]; - QActive_ctor(&me->super, Q_STATE_CAST(&Philo_initial)); - QTimeEvt_ctorX(&me->timeEvt, &me->super, TIMEOUT_SIG, 0U); - } +// helper function to provide a randomized think time for Philos +static QTimeEvtCtr think_time(void); // prototype +static inline QTimeEvtCtr think_time(void) { + return (QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + + (BSP_TICKS_PER_SEC/2U)); } -/*$enddef${AOs::Philo_ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*$define${AOs::Philo} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/*${AOs::Philo} ............................................................*/ +// helper function to provide a randomized eat time for Philos +static QTimeEvtCtr eat_time(void); // prototype +static inline QTimeEvtCtr eat_time(void) { + return (QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + + BSP_TICKS_PER_SEC); +} +//---------------------------------------------------------------------------- -/*${AOs::Philo::SM} ........................................................*/ +//$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// Check for the minimum required QP version +#if (QP_VERSION < 730U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) +#error qpc version 7.3.0 or higher required +#endif +//$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +//$define${Shared::Philo_ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${Shared::Philo_ctor} ...................................................... +void Philo_ctor(uint_fast8_t const id) { + Philo * const me = &Philo_inst[id]; + QActive_ctor(&me->super, Q_STATE_CAST(&Philo_initial)); + QTimeEvt_ctorX(&me->timeEvt, &me->super, TIMEOUT_SIG, 0U), + me->id = (uint8_t)id; +} +//$enddef${Shared::Philo_ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +//$define${Shared::AO_Philo[N_PHILO]} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${Shared::AO_Philo[N_PHILO]} ............................................... +QActive * const AO_Philo[N_PHILO] = { + &Philo_inst[0].super, + &Philo_inst[1].super, + &Philo_inst[2].super, + &Philo_inst[3].super, + &Philo_inst[4].super +}; +//$enddef${Shared::AO_Philo[N_PHILO]} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +//$define${AOs::Philo} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${AOs::Philo} .............................................................. +Philo Philo_inst[N_PHILO]; + +//${AOs::Philo::SM} .......................................................... static QState Philo_initial(Philo * const me, void const * const par) { - /*${AOs::Philo::SM::initial} */ - static uint8_t registered = (uint8_t)0; /* starts off with 0, per C-standard */ - (void)par; /* unused parameter */ - if (registered == (uint8_t)0) { - registered = (uint8_t)1; + //${AOs::Philo::SM::initial} + Q_UNUSED_PAR(par); - QS_OBJ_DICTIONARY(&l_philo[0]); - QS_OBJ_DICTIONARY(&l_philo[0].timeEvt); - QS_OBJ_DICTIONARY(&l_philo[1]); - QS_OBJ_DICTIONARY(&l_philo[1].timeEvt); - QS_OBJ_DICTIONARY(&l_philo[2]); - QS_OBJ_DICTIONARY(&l_philo[2].timeEvt); - QS_OBJ_DICTIONARY(&l_philo[3]); - QS_OBJ_DICTIONARY(&l_philo[3].timeEvt); - QS_OBJ_DICTIONARY(&l_philo[4]); - QS_OBJ_DICTIONARY(&l_philo[4].timeEvt); - - QS_FUN_DICTIONARY(&Philo_initial); - QS_FUN_DICTIONARY(&Philo_thinking); - QS_FUN_DICTIONARY(&Philo_hungry); - QS_FUN_DICTIONARY(&Philo_eating); - } - QS_SIG_DICTIONARY(HUNGRY_SIG, me); /* signal for each Philos */ - QS_SIG_DICTIONARY(TIMEOUT_SIG, me); /* signal for each Philos */ + QS_OBJ_ARR_DICTIONARY(&Philo_inst[me->id], me->id); + QS_OBJ_ARR_DICTIONARY(&Philo_inst[me->id].timeEvt, me->id); QActive_subscribe(&me->super, EAT_SIG); QActive_subscribe(&me->super, TEST_SIG); + + QS_FUN_DICTIONARY(&Philo_thinking); + QS_FUN_DICTIONARY(&Philo_hungry); + QS_FUN_DICTIONARY(&Philo_eating); + return Q_TRAN(&Philo_thinking); } -/*${AOs::Philo::SM::thinking} ..............................................*/ +//${AOs::Philo::SM::thinking} ................................................ static QState Philo_thinking(Philo * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${AOs::Philo::SM::thinking} */ + //${AOs::Philo::SM::thinking} case Q_ENTRY_SIG: { - QTimeEvt_armX(&me->timeEvt, THINK_TIME, 0U); + QTimeEvt_armX(&me->timeEvt, think_time(), 0U); status_ = Q_HANDLED(); break; } - /*${AOs::Philo::SM::thinking} */ + //${AOs::Philo::SM::thinking} case Q_EXIT_SIG: { - QTimeEvt_disarm(&me->timeEvt); + (void)QTimeEvt_disarm(&me->timeEvt); status_ = Q_HANDLED(); break; } - /*${AOs::Philo::SM::thinking::TIMEOUT} */ + //${AOs::Philo::SM::thinking::TIMEOUT} case TIMEOUT_SIG: { status_ = Q_TRAN(&Philo_hungry); break; } - /*${AOs::Philo::SM::thinking::EAT, DONE} */ - case EAT_SIG: /* intentionally fall through */ + //${AOs::Philo::SM::thinking::EAT, DONE} + case EAT_SIG: // intentionally fall through case DONE_SIG: { - /* EAT or DONE must be for other Philos than this one */ - Q_ASSERT(Q_EVT_CAST(TableEvt)->philoNum != PHILO_ID(me)); + // EAT or DONE must be for other Philos than this one + Q_ASSERT(Q_EVT_CAST(TableEvt)->philoId != me->id); status_ = Q_HANDLED(); break; } - /*${AOs::Philo::SM::thinking::TEST} */ + //${AOs::Philo::SM::thinking::TEST} case TEST_SIG: { status_ = Q_HANDLED(); break; @@ -172,22 +166,26 @@ static QState Philo_thinking(Philo * const me, QEvt const * const e) { return status_; } -/*${AOs::Philo::SM::hungry} ................................................*/ +//${AOs::Philo::SM::hungry} .................................................. static QState Philo_hungry(Philo * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${AOs::Philo::SM::hungry} */ + //${AOs::Philo::SM::hungry} case Q_ENTRY_SIG: { + #ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, HUNGRY_SIG, me->id); + #else TableEvt *pe = Q_NEW(TableEvt, HUNGRY_SIG); - pe->philoNum = PHILO_ID(me); - QACTIVE_POST(AO_Table, &pe->super, me); + pe->philoId = me->id; + #endif + QACTIVE_POST(AO_Table, &pe->super, &me->super); status_ = Q_HANDLED(); break; } - /*${AOs::Philo::SM::hungry::EAT} */ + //${AOs::Philo::SM::hungry::EAT} case EAT_SIG: { - /*${AOs::Philo::SM::hungry::EAT::[Q_EVT_CAST(TableEvt)->philoNum=~} */ - if (Q_EVT_CAST(TableEvt)->philoNum == PHILO_ID(me)) { + //${AOs::Philo::SM::hungry::EAT::[e->philoId==me->iid]} + if (Q_EVT_CAST(TableEvt)->philoId == me->id) { status_ = Q_TRAN(&Philo_eating); } else { @@ -195,10 +193,10 @@ static QState Philo_hungry(Philo * const me, QEvt const * const e) { } break; } - /*${AOs::Philo::SM::hungry::DONE} */ + //${AOs::Philo::SM::hungry::DONE} case DONE_SIG: { - /* DONE must be for other Philos than this one */ - Q_ASSERT(Q_EVT_CAST(TableEvt)->philoNum != PHILO_ID(me)); + // DONE must be for other Philos than this one + Q_ASSERT(Q_EVT_CAST(TableEvt)->philoId != me->id); status_ = Q_HANDLED(); break; } @@ -210,34 +208,40 @@ static QState Philo_hungry(Philo * const me, QEvt const * const e) { return status_; } -/*${AOs::Philo::SM::eating} ................................................*/ +//${AOs::Philo::SM::eating} .................................................. static QState Philo_eating(Philo * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${AOs::Philo::SM::eating} */ + //${AOs::Philo::SM::eating} case Q_ENTRY_SIG: { - QTimeEvt_armX(&me->timeEvt, EAT_TIME, 0U); + QTimeEvt_armX(&me->timeEvt, eat_time(), 0U); status_ = Q_HANDLED(); break; } - /*${AOs::Philo::SM::eating} */ + //${AOs::Philo::SM::eating} case Q_EXIT_SIG: { + (void)QTimeEvt_disarm(&me->timeEvt); + + #ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, DONE_SIG, me->id); + #else TableEvt *pe = Q_NEW(TableEvt, DONE_SIG); - pe->philoNum = PHILO_ID(me); + pe->philoId = me->id; + #endif QACTIVE_PUBLISH(&pe->super, &me->super); status_ = Q_HANDLED(); break; } - /*${AOs::Philo::SM::eating::TIMEOUT} */ + //${AOs::Philo::SM::eating::TIMEOUT} case TIMEOUT_SIG: { status_ = Q_TRAN(&Philo_thinking); break; } - /*${AOs::Philo::SM::eating::EAT, DONE} */ - case EAT_SIG: /* intentionally fall through */ + //${AOs::Philo::SM::eating::EAT, DONE} + case EAT_SIG: // intentionally fall through case DONE_SIG: { - /* EAT or DONE must be for other Philos than this one */ - Q_ASSERT(Q_EVT_CAST(TableEvt)->philoNum != PHILO_ID(me)); + // EAT or DONE must be for other Philos than this one + Q_ASSERT(Q_EVT_CAST(TableEvt)->philoId != me->id); status_ = Q_HANDLED(); break; } @@ -248,4 +252,4 @@ static QState Philo_eating(Philo * const me, QEvt const * const e) { } return status_; } -/*$enddef${AOs::Philo} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$enddef${AOs::Philo} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/examples/uc-os2/arm-cm/dpp_nucleo-l053r8/stm32-nucleo-l053r8.jpg b/examples/uc-os2/arm-cm/dpp_nucleo-l053r8/stm32-nucleo-l053r8.jpg new file mode 100644 index 00000000..1c7c4159 Binary files /dev/null and b/examples/uc-os2/arm-cm/dpp_nucleo-l053r8/stm32-nucleo-l053r8.jpg differ diff --git a/examples/uc-os2/arm-cm/dpp_nucleo-l053r8/table.c b/examples/uc-os2/arm-cm/dpp_nucleo-l053r8/table.c index c8fb3c37..c3ae02f0 100644 --- a/examples/uc-os2/arm-cm/dpp_nucleo-l053r8/table.c +++ b/examples/uc-os2/arm-cm/dpp_nucleo-l053r8/table.c @@ -1,110 +1,120 @@ -/*$file${.::table.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* -* Model: dpp.qm -* File: ${.::table.c} -* -* This code has been generated by QM 5.2.4 . -* DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. -* -* SPDX-License-Identifier: GPL-3.0-or-later -* -* This generated code is open source software: you can redistribute it under -* the terms of the GNU General Public License as published by the Free -* Software Foundation. -* -* This code is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -* more details. -* -* NOTE: -* Alternatively, this generated code may be distributed under the terms -* of Quantum Leaps commercial licenses, which expressly supersede the GNU -* General Public License and are specifically designed for licensees -* interested in retaining the proprietary status of their code. -* -* Contact information: -* -* -*/ -/*$endhead${.::table.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -#include "qpc.h" -#include "dpp.h" -#include "bsp.h" +//$file${.::table.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// +// Model: dpp.qm +// File: ${.::table.c} +// +// This code has been generated by QM 5.3.0 . +// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. +// +// SPDX-License-Identifier: GPL-3.0-or-later +// +// This generated code is open source software: you can redistribute it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation. +// +// This code is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// NOTE: +// Alternatively, this generated code may be distributed under the terms +// of Quantum Leaps commercial licenses, which expressly supersede the GNU +// General Public License and are specifically designed for licensees +// interested in retaining the proprietary status of their code. +// +// Contact information: +// +// +// +//$endhead${.::table.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +#include "qpc.h" // QP/C real-time embedded framework +#include "dpp.h" // DPP Application interface +#include "bsp.h" // Board Support Package -Q_DEFINE_THIS_FILE +//$declare${AOs::Table} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/* Active object class -----------------------------------------------------*/ -/*$declare${AOs::Table} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${AOs::Table} ............................................................*/ -typedef struct { -/* protected: */ +//${AOs::Table} .............................................................. +typedef struct Table { +// protected: QActive super; -/* private: */ +// private: uint8_t fork[N_PHILO]; - uint8_t isHungry[N_PHILO]; + bool isHungry[N_PHILO]; + +// public: } Table; -/* protected: */ +extern Table Table_inst; + +// protected: static QState Table_initial(Table * const me, void const * const par); static QState Table_active(Table * const me, QEvt const * const e); static QState Table_serving(Table * const me, QEvt const * const e); static QState Table_paused(Table * const me, QEvt const * const e); -/*$enddecl${AOs::Table} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$enddecl${AOs::Table} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -#define RIGHT(n_) ((uint8_t)(((n_) + (N_PHILO - 1U)) % N_PHILO)) -#define LEFT(n_) ((uint8_t)(((n_) + 1U) % N_PHILO)) -#define FREE ((uint8_t)0) -#define USED ((uint8_t)1) +//---------------------------------------------------------------------------- +Q_DEFINE_THIS_FILE -/* Local objects -----------------------------------------------------------*/ -static Table l_table; /* the single instance of the Table active object */ +// helper function to provide the RIGHT neighbor of a Philo[n] +static inline uint8_t right(uint8_t const n) { + return (uint8_t)((n + (N_PHILO - 1U)) % N_PHILO); +} -/* Global-scope objects ----------------------------------------------------*/ -QActive * const AO_Table = &l_table.super; /* "opaque" AO pointer */ +// helper function to provide the LEFT neighbor of a Philo[n] +static inline uint8_t left(uint8_t const n) { + return (uint8_t)((n + 1U) % N_PHILO); +} -/*..........................................................................*/ -/*$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* Check for the minimum required QP version */ -#if (QP_VERSION < 700U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) -#error qpc version 7.0.0 or higher required +#define FREE ((uint8_t)0U) +#define USED ((uint8_t)1U) + +#define THINKING "thinking" +#define HUNGRY "hungry " +#define EATING "eating " + +//---------------------------------------------------------------------------- + +//$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// Check for the minimum required QP version +#if (QP_VERSION < 730U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) +#error qpc version 7.3.0 or higher required #endif -/*$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -/*$define${AOs::Table_ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//$define${Shared::Table_ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/*${AOs::Table_ctor} .......................................................*/ +//${Shared::Table_ctor} ...................................................... void Table_ctor(void) { - uint8_t n; - Table *me = &l_table; - + Table * const me = &Table_inst; QActive_ctor(&me->super, Q_STATE_CAST(&Table_initial)); - - for (n = 0U; n < N_PHILO; ++n) { + for (uint8_t n = 0U; n < N_PHILO; ++n) { me->fork[n] = FREE; - me->isHungry[n] = 0U; + me->isHungry[n] = false; } } -/*$enddef${AOs::Table_ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*$define${AOs::Table} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//$enddef${Shared::Table_ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +//$define${Shared::AO_Table} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/*${AOs::Table} ............................................................*/ +//${Shared::AO_Table} ........................................................ +QActive * const AO_Table = &Table_inst.super; +//$enddef${Shared::AO_Table} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +//$define${AOs::Table} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/*${AOs::Table::SM} ........................................................*/ +//${AOs::Table} .............................................................. +Table Table_inst; + +//${AOs::Table::SM} .......................................................... static QState Table_initial(Table * const me, void const * const par) { - /*${AOs::Table::SM::initial} */ - (void)par; /* unused parameter */ + //${AOs::Table::SM::initial} + Q_UNUSED_PAR(par); - QS_OBJ_DICTIONARY(&l_table); - - QS_SIG_DICTIONARY(DONE_SIG, (void *)0); /* global signals */ - QS_SIG_DICTIONARY(EAT_SIG, (void *)0); - QS_SIG_DICTIONARY(PAUSE_SIG, (void *)0); - QS_SIG_DICTIONARY(SERVE_SIG, (void *)0); - QS_SIG_DICTIONARY(TEST_SIG, (void *)0); - QS_SIG_DICTIONARY(HUNGRY_SIG, me); /* signal just for Table */ + #ifdef Q_SPY + Table *Table_inst = me; + QS_OBJ_DICTIONARY(Table_inst); + #endif QActive_subscribe(&me->super, DONE_SIG); QActive_subscribe(&me->super, PAUSE_SIG); @@ -113,8 +123,8 @@ static QState Table_initial(Table * const me, void const * const par) { for (uint8_t n = 0U; n < N_PHILO; ++n) { me->fork[n] = FREE; - me->isHungry[n] = 0U; - BSP_displayPhilStat(n, "thinking"); + me->isHungry[n] = false; + BSP_displayPhilStat(n, THINKING); } QS_FUN_DICTIONARY(&Table_active); @@ -124,16 +134,16 @@ static QState Table_initial(Table * const me, void const * const par) { return Q_TRAN(&Table_serving); } -/*${AOs::Table::SM::active} ................................................*/ +//${AOs::Table::SM::active} .................................................. static QState Table_active(Table * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${AOs::Table::SM::active::TEST} */ + //${AOs::Table::SM::active::TEST} case TEST_SIG: { status_ = Q_HANDLED(); break; } - /*${AOs::Table::SM::active::EAT} */ + //${AOs::Table::SM::active::EAT} case EAT_SIG: { Q_ERROR(); status_ = Q_HANDLED(); @@ -147,108 +157,119 @@ static QState Table_active(Table * const me, QEvt const * const e) { return status_; } -/*${AOs::Table::SM::active::serving} .......................................*/ +//${AOs::Table::SM::active::serving} ......................................... static QState Table_serving(Table * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${AOs::Table::SM::active::serving} */ + //${AOs::Table::SM::active::serving} case Q_ENTRY_SIG: { - uint8_t n; - for (n = 0U; n < N_PHILO; ++n) { /* give permissions to eat... */ - if ((me->isHungry[n] != 0U) - && (me->fork[LEFT(n)] == FREE) + // give permissions to eat... + for (uint8_t n = 0U; n < N_PHILO; ++n) { + if (me->isHungry[n] + && (me->fork[left(n)] == FREE) && (me->fork[n] == FREE)) { - TableEvt *te; - - me->fork[LEFT(n)] = USED; + me->fork[left(n)] = USED; me->fork[n] = USED; - te = Q_NEW(TableEvt, EAT_SIG); - te->philoNum = n; - QACTIVE_PUBLISH(&te->super, &me->super); - me->isHungry[n] = 0U; - BSP_displayPhilStat(n, "eating "); + #ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, EAT_SIG, n); + #else + TableEvt *pe = Q_NEW(TableEvt, EAT_SIG); + pe->philoId = n; + #endif + QACTIVE_PUBLISH(&pe->super, &me->super); + me->isHungry[n] = false; + BSP_displayPhilStat(n, EATING); } } status_ = Q_HANDLED(); break; } - /*${AOs::Table::SM::active::serving::HUNGRY} */ + //${AOs::Table::SM::active::serving::HUNGRY} case HUNGRY_SIG: { - uint8_t n, m; + uint8_t n = Q_EVT_CAST(TableEvt)->philoId; - n = Q_EVT_CAST(TableEvt)->philoNum; - /* phil ID must be in range and he must be not hungry */ - Q_ASSERT((n < N_PHILO) && (me->isHungry[n] == 0U)); + // phil ID must be in range and he must be not hungry + Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); - BSP_displayPhilStat(n, "hungry "); - m = LEFT(n); - /*${AOs::Table::SM::active::serving::HUNGRY::[bothfree]} */ + BSP_displayPhilStat(n, HUNGRY); + uint8_t m = left(n); + //${AOs::Table::SM::active::serving::HUNGRY::[bothfree]} if ((me->fork[m] == FREE) && (me->fork[n] == FREE)) { - TableEvt *pe; me->fork[m] = USED; me->fork[n] = USED; - pe = Q_NEW(TableEvt, EAT_SIG); - pe->philoNum = n; + #ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, EAT_SIG, n); + #else + TableEvt *pe = Q_NEW(TableEvt, EAT_SIG); + pe->philoId = n; + #endif QACTIVE_PUBLISH(&pe->super, &me->super); - BSP_displayPhilStat(n, "eating "); + BSP_displayPhilStat(n, EATING); status_ = Q_HANDLED(); } - /*${AOs::Table::SM::active::serving::HUNGRY::[else]} */ + //${AOs::Table::SM::active::serving::HUNGRY::[else]} else { - me->isHungry[n] = 1U; + me->isHungry[n] = true; status_ = Q_HANDLED(); } break; } - /*${AOs::Table::SM::active::serving::DONE} */ + //${AOs::Table::SM::active::serving::DONE} case DONE_SIG: { - uint8_t n, m; - TableEvt *pe; + uint8_t n = Q_EVT_CAST(TableEvt)->philoId; - n = Q_EVT_CAST(TableEvt)->philoNum; - /* phil ID must be in range and he must be not hungry */ - Q_ASSERT((n < N_PHILO) && (me->isHungry[n] == 0U)); + // phil ID must be in range and he must be not hungry + Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); - BSP_displayPhilStat(n, "thinking"); - m = LEFT(n); - /* both forks of Phil[n] must be used */ + BSP_displayPhilStat(n, THINKING); + uint8_t m = left(n); + + // both forks of Phil[n] must be used Q_ASSERT((me->fork[n] == USED) && (me->fork[m] == USED)); me->fork[m] = FREE; me->fork[n] = FREE; - m = RIGHT(n); /* check the right neighbor */ + m = right(n); // check the right neighbor - if ((me->isHungry[m] != 0U) && (me->fork[m] == FREE)) { + if (me->isHungry[m] && (me->fork[m] == FREE)) { me->fork[n] = USED; me->fork[m] = USED; - me->isHungry[m] = 0U; - pe = Q_NEW(TableEvt, EAT_SIG); - pe->philoNum = m; + me->isHungry[m] = false; + #ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, EAT_SIG, m); + #else + TableEvt *pe = Q_NEW(TableEvt, EAT_SIG); + pe->philoId = m; + #endif QACTIVE_PUBLISH(&pe->super, &me->super); - BSP_displayPhilStat(m, "eating "); + BSP_displayPhilStat(m, EATING); } - m = LEFT(n); /* check the left neighbor */ - n = LEFT(m); /* left fork of the left neighbor */ - if ((me->isHungry[m] != 0U) && (me->fork[n] == FREE)) { + m = left(n); // check the left neighbor + n = left(m); // left fork of the left neighbor + if (me->isHungry[m] && (me->fork[n] == FREE)) { me->fork[m] = USED; me->fork[n] = USED; - me->isHungry[m] = 0U; - pe = Q_NEW(TableEvt, EAT_SIG); - pe->philoNum = m; + me->isHungry[m] = false; + #ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, EAT_SIG, m); + #else + TableEvt *pe = Q_NEW(TableEvt, EAT_SIG); + pe->philoId = m; + #endif QACTIVE_PUBLISH(&pe->super, &me->super); - BSP_displayPhilStat(m, "eating "); + BSP_displayPhilStat(m, EATING); } status_ = Q_HANDLED(); break; } - /*${AOs::Table::SM::active::serving::EAT} */ + //${AOs::Table::SM::active::serving::EAT} case EAT_SIG: { Q_ERROR(); status_ = Q_HANDLED(); break; } - /*${AOs::Table::SM::active::serving::PAUSE} */ + //${AOs::Table::SM::active::serving::PAUSE} case PAUSE_SIG: { status_ = Q_TRAN(&Table_paused); break; @@ -261,48 +282,50 @@ static QState Table_serving(Table * const me, QEvt const * const e) { return status_; } -/*${AOs::Table::SM::active::paused} ........................................*/ +//${AOs::Table::SM::active::paused} .......................................... static QState Table_paused(Table * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${AOs::Table::SM::active::paused} */ + //${AOs::Table::SM::active::paused} case Q_ENTRY_SIG: { BSP_displayPaused(1U); status_ = Q_HANDLED(); break; } - /*${AOs::Table::SM::active::paused} */ + //${AOs::Table::SM::active::paused} case Q_EXIT_SIG: { BSP_displayPaused(0U); status_ = Q_HANDLED(); break; } - /*${AOs::Table::SM::active::paused::SERVE} */ + //${AOs::Table::SM::active::paused::SERVE} case SERVE_SIG: { status_ = Q_TRAN(&Table_serving); break; } - /*${AOs::Table::SM::active::paused::HUNGRY} */ + //${AOs::Table::SM::active::paused::HUNGRY} case HUNGRY_SIG: { - uint8_t n = Q_EVT_CAST(TableEvt)->philoNum; - /* philo ID must be in range and he must be not hungry */ - Q_ASSERT((n < N_PHILO) && (me->isHungry[n] == 0U)); - me->isHungry[n] = 1U; - BSP_displayPhilStat(n, "hungry "); + uint8_t n = Q_EVT_CAST(TableEvt)->philoId; + + // philo ID must be in range and he must be not hungry + Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); + + me->isHungry[n] = true; + BSP_displayPhilStat(n, HUNGRY); status_ = Q_HANDLED(); break; } - /*${AOs::Table::SM::active::paused::DONE} */ + //${AOs::Table::SM::active::paused::DONE} case DONE_SIG: { - uint8_t n, m; + uint8_t n = Q_EVT_CAST(TableEvt)->philoId; - n = Q_EVT_CAST(TableEvt)->philoNum; - /* phil ID must be in range and he must be not hungry */ - Q_ASSERT((n < N_PHILO) && (me->isHungry[n] == 0U)); + // phil ID must be in range and he must be not hungry + Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); - BSP_displayPhilStat(n, "thinking"); - m = LEFT(n); - /* both forks of Phil[n] must be used */ + BSP_displayPhilStat(n, THINKING); + uint8_t m = left(n); + + // both forks of Phil[n] must be used Q_ASSERT((me->fork[n] == USED) && (me->fork[m] == USED)); me->fork[m] = FREE; @@ -317,4 +340,4 @@ static QState Table_paused(Table * const me, QEvt const * const e) { } return status_; } -/*$enddef${AOs::Table} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$enddef${AOs::Table} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/examples/workstation/README.txt b/examples/workstation/README.txt deleted file mode 100644 index 876876f9..00000000 --- a/examples/workstation/README.txt +++ /dev/null @@ -1,106 +0,0 @@ -ABOUT THE "Workstation" EXAMPLES -================================ -The examples in the "workstation" directory can be built on any workstation -(Windows, Linux, and MacOS). The provided Makefiles support the -GNU GCC toolchain. - -*** NOTE *** -For Windows, the make utility and the GNU GCC toolchain (MinGW) are provided -in the QTools collection, which is available for a separate download from: - -http://sourceforge.net/projects/qpc/files/QTools/ - -*** NOTE *** -The code can be also built with other tools as well, such as the -Microsoft Visual Studio 2013 and newer. - - -The QP/C Code -============= -For Windows, the QP/C framework used in the examples comes pre-compiled -into a library. - -For POSIX platforms (Linux and MacOS), the QP/C framework is built from -sources in every provided project. - - -Single-Threaded and Multi-Threaded QP/C Ports ---------------------------------------------- -Each of the examples can be linked to either the single-threaded QP/C ports -(win32-qv or posix-qv) or multi-threaded ports (win32 or posix). The choice -is made in the Makefiles, by editing the line, which defines the -QP_PORT_DIR symbol. For example, the following lines select the win32-qv -port and leave the win32 port commented-out: - -QP_PORT_DIR := $(QPC)/ports/win32-qv -#QP_PORT_DIR := $(QPC)/ports/win32 - -To reverse the selection, you need to move the comment '#' character. - -*** NOTE *** -The single-threaded QP/C ports (win32-qv and posix-qv) are recommended for -emulating software intended for deeply-embedded targets. - -The multi-threaded QP/C ports (win32 and posix) are intended for the -actual applications that run on (embedded)Windows or (embedded)Linux. - - -Debug, Release, and Spy Build Configurations -============================================ -The Makefiles for the examples generally support the following three build -configurations: - -Debug Configuration -------------------- -This is the default build configuration, with full debugging information and -minimal optimization. To build this configuration, type: - -make - -To clean this build, type - -make clean - -The object files and the executable is located in the 'build' sub-directory. - - -Release Configuration ---------------------- -This configuration is built with no debugging information and high -optimization. Single-stepping and debugging might be difficult due -to the lack of debugging information and optimized code. To build -this configuration, type: - -make CONF=rel - -To clean this build, type - -make CONF=rel clean - -The object files and the executable is located in the 'build_rel' directory. - -Spy Configuration ------------------ -This configuration is built with the QP's Q-SPY trace functionality. -The QP/Spy output is performed by a TCP/IP socket and requires launching -the QSPY host application with the -t option. To build this configuration, -type: - -make CONF=spy - -To clean this build, type - -make CONF=spy clean - -The object files and the executable are located in the 'build_spy' directory. - -*** NOTE *** -Only specific examples support the Spy build configuration. The examples -that don't support it, will report an error or will fail the linking stage. - - -Support and Contact Information -=============================== -https://sourceforge.net/p/qpc/discussion/668726/ -https://www.state-machine.com -info@state-machine.com diff --git a/examples/workstation/blinky/blinky.c b/examples/workstation/blinky/blinky.c deleted file mode 100644 index 7b3f4362..00000000 --- a/examples/workstation/blinky/blinky.c +++ /dev/null @@ -1,180 +0,0 @@ -/*$file${.::blinky.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* -* Model: blinky.qm -* File: ${.::blinky.c} -* -* This code has been generated by QM 5.2.4 . -* DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. -* -* SPDX-License-Identifier: GPL-3.0-or-later -* -* This generated code is open source software: you can redistribute it under -* the terms of the GNU General Public License as published by the Free -* Software Foundation. -* -* This code is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -* more details. -* -* NOTE: -* Alternatively, this generated code may be distributed under the terms -* of Quantum Leaps commercial licenses, which expressly supersede the GNU -* General Public License and are specifically designed for licensees -* interested in retaining the proprietary status of their code. -* -* Contact information: -* -* -*/ -/*$endhead${.::blinky.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -#include "qpc.h" - -#include "safe_std.h" /* portable "safe" / facilities */ -#include /* for exit() */ - -Q_DEFINE_THIS_FILE - -#ifdef Q_SPY - #error Simple Blinky Application does not provide Spy build configuration -#endif - -enum { BSP_TICKS_PER_SEC = 100 }; - -void BSP_ledOff(void) { - PRINTF_S("%s\n", "LED OFF"); -} -void BSP_ledOn(void) { - PRINTF_S("%s\n", "LED ON"); -} -void Q_onAssert(char const * const module, int loc) { - FPRINTF_S(stderr, "Assertion failed in %s:%d", module, loc); - exit(-1); -} -void QF_onStartup(void) {} -void QF_onCleanup(void) {} -void QF_onClockTick(void) { - QTIMEEVT_TICK_X(0U, (void *)0); /* clock tick processing */ -} - -enum BlinkySignals { - TIMEOUT_SIG = Q_USER_SIG, - MAX_SIG -}; - -//*============== ask QM to declare the Blinky class ================*/ -/*$declare${AOs::Blinky} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${AOs::Blinky} ...........................................................*/ -typedef struct Blinky { -/* protected: */ - QActive super; - -/* public: */ - -/* private: */ - QTimeEvt timeEvt; -} Blinky; -extern Blinky Blinky_inst; - -/* protected: */ -static QState Blinky_initial(Blinky * const me, void const * const par); -static QState Blinky_off(Blinky * const me, QEvt const * const e); -static QState Blinky_on(Blinky * const me, QEvt const * const e); -/*$enddecl${AOs::Blinky} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ - -QActive * const AO_Blinky = &Blinky_inst.super; - -static void Blinky_ctor(void) { - Blinky *me = &Blinky_inst; - QActive_ctor(&me->super, Q_STATE_CAST(&Blinky_initial)); - QTimeEvt_ctorX(&me->timeEvt, &me->super, TIMEOUT_SIG, 0U); -} - -int main() { - /* statically allocate event queue buffer for the Blinky AO */ - static QEvt const *blinky_queueSto[10]; - - QF_init(); /* initialize the framework */ - - Blinky_ctor(); /* explicitly call the "constructor" */ - QACTIVE_START(AO_Blinky, - 1U, /* priority */ - blinky_queueSto, Q_DIM(blinky_queueSto), - (void *)0, 0U, /* no stack */ - (void *)0); /* no initialization parameter */ - return QF_run(); /* run the QF application */ -} - -/*================ ask QM to define the Blinky class ================*/ -/*$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* Check for the minimum required QP version */ -#if (QP_VERSION < 700U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) -#error qpc version 7.0.0 or higher required -#endif -/*$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ - -/*$define${AOs::Blinky} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${AOs::Blinky} ...........................................................*/ -Blinky Blinky_inst; - -/*${AOs::Blinky::SM} .......................................................*/ -static QState Blinky_initial(Blinky * const me, void const * const par) { - /*${AOs::Blinky::SM::initial} */ - (void)par; /* unused parameter */ - QTimeEvt_armX(&me->timeEvt, - BSP_TICKS_PER_SEC/2, BSP_TICKS_PER_SEC/2); - - QS_FUN_DICTIONARY(&Blinky_off); - QS_FUN_DICTIONARY(&Blinky_on); - - return Q_TRAN(&Blinky_off); -} - -/*${AOs::Blinky::SM::off} ..................................................*/ -static QState Blinky_off(Blinky * const me, QEvt const * const e) { - QState status_; - switch (e->sig) { - /*${AOs::Blinky::SM::off} */ - case Q_ENTRY_SIG: { - BSP_ledOff(); - status_ = Q_HANDLED(); - break; - } - /*${AOs::Blinky::SM::off::TIMEOUT} */ - case TIMEOUT_SIG: { - status_ = Q_TRAN(&Blinky_on); - break; - } - default: { - status_ = Q_SUPER(&QHsm_top); - break; - } - } - return status_; -} - -/*${AOs::Blinky::SM::on} ...................................................*/ -static QState Blinky_on(Blinky * const me, QEvt const * const e) { - QState status_; - switch (e->sig) { - /*${AOs::Blinky::SM::on} */ - case Q_ENTRY_SIG: { - BSP_ledOn(); - status_ = Q_HANDLED(); - break; - } - /*${AOs::Blinky::SM::on::TIMEOUT} */ - case TIMEOUT_SIG: { - status_ = Q_TRAN(&Blinky_off); - break; - } - default: { - status_ = Q_SUPER(&QHsm_top); - break; - } - } - return status_; -} -/*$enddef${AOs::Blinky} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ diff --git a/examples/workstation/blinky/blinky_win.png b/examples/workstation/blinky/blinky_win.png deleted file mode 100644 index 1771e886..00000000 Binary files a/examples/workstation/blinky/blinky_win.png and /dev/null differ diff --git a/examples/workstation/calc/bsp.c b/examples/workstation/calc/bsp.c deleted file mode 100644 index a5d72f23..00000000 --- a/examples/workstation/calc/bsp.c +++ /dev/null @@ -1,155 +0,0 @@ -/***************************************************************************** -* Product: Board Support Package (BSP) for the Calculator example -* Last updated for version 6.9.0 -* Last updated on 2020-06-24 -* -* Q u a n t u m L e a P s -* ------------------------ -* Modern Embedded Software -* -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* -* -*****************************************************************************/ -#include "qpc.h" -#include "bsp.h" - -#include "safe_std.h" /* portable "safe" / facilities */ -#include /* for exit() */ - -#define DISP_WIDTH 15 - -/* helper macros to "stringify" values */ -#define VAL(x) #x -#define STRINGIFY(x) VAL(x) - -static char l_display[DISP_WIDTH + 1]; /* the calculator display */ -static int l_len; /* number of displayed characters */ - -/*..........................................................................*/ -void BSP_clear(void) { - memset(l_display, ' ', DISP_WIDTH - 1); - l_display[DISP_WIDTH - 1] = '0'; - l_display[DISP_WIDTH] = '\0'; - l_len = 0; -} -/*..........................................................................*/ -void BSP_insert(int keyId) { - if (l_len == 0) { - l_display[DISP_WIDTH - 1] = (char)keyId; - ++l_len; - } - else if (l_len < (DISP_WIDTH - 1)) { - MEMMOVE_S(&l_display[0], DISP_WIDTH, &l_display[1], DISP_WIDTH - 1); - l_display[DISP_WIDTH - 1] = (char)keyId; - ++l_len; - } -} -/*..........................................................................*/ -void BSP_negate(void) { - BSP_clear(); - l_display[DISP_WIDTH - 2] = '-'; -} -/*..........................................................................*/ -void BSP_display(void) { - PRINTF_S("\n[%" STRINGIFY(DISP_WIDTH) "s] ", l_display); -} -/*..........................................................................*/ -void BSP_exit(void) { - PRINTF_S("\n%s\n", "Bye! Bye!"); - fflush(stdout); - QF_onCleanup(); - exit(0); -} -/*..........................................................................*/ -double BSP_get_value(void) { - return strtod(l_display, (char **)0); -} -/*..........................................................................*/ -int BSP_eval(double operand1, int oper, double operand2) { - int ok = 1; - double result = 0.0; - switch (oper) { - case KEY_PLUS: { - result = operand1 + operand2; - break; - } - case KEY_MINUS: { - result = operand1 - operand2; - break; - } - case KEY_MULT: { - result = operand1 * operand2; - break; - } - case KEY_DIVIDE: { - if ((operand2 < -1e-30) || (1e-30 < operand2)) { - result = operand1 / operand2; - } - else { - /* error: divide by zero */ - STRNCPY_S(l_display, DISP_WIDTH, " Error 0 "); - ok = 0; - } - break; - } - } - if (ok) { - if ((-0.000001 < result) && (result < 0.000001)) { - result = 0.0; - } - if ((-99999999.0 < result) && (result < 99999999.0)) { - SNPRINTF_S(l_display, DISP_WIDTH, "%10.7g", result); - } - else { - /* error: out of range */ - STRNCPY_S(l_display, DISP_WIDTH, " Error 1 "); - ok = 0; - } - } - return ok; -} -/*..........................................................................*/ -void BSP_message(char const *msg) { - PRINTF_S("%s", msg); -} - -/*..........................................................................*/ -void QF_onStartup(void) { - QF_consoleSetup(); -} -/*..........................................................................*/ -void QF_onCleanup(void) { - QF_consoleCleanup(); -} -/*..........................................................................*/ -void QF_onClockTick(void) { -} - -/*..........................................................................*/ -/* this function is used by the QP embedded systems-friendly assertions */ -Q_NORETURN Q_onAssert(char const * const module, int_t const loc) { - FPRINTF_S(stderr, "Assertion failed in %s:%d", module, loc); - QF_onCleanup(); - exit(-1); -} diff --git a/examples/workstation/calc/bsp.h b/examples/workstation/calc/bsp.h deleted file mode 100644 index 6a1f006f..00000000 --- a/examples/workstation/calc/bsp.h +++ /dev/null @@ -1,46 +0,0 @@ -/***************************************************************************** -* Product: Board Support Package (BSP) for the Calculator example -* Last Updated for Version: 4.0.00 -* Date of the Last Update: Apr 07, 2008 -* -* Q u a n t u m L e a P s -* --------------------------- -* innovating embedded systems -* -* Copyright (C)-2008 Quantum Leaps, LLC. All rights reserved. -* -* This software may be distributed and modified under the terms of the GNU -* General Public License version 2 (GPL) as published by the Free Software -* Foundation and appearing in the file GPL.TXT included in the packaging of -* this file. Please note that GPL Section 2[b] requires that all works based -* on this software must also be made publicly available under the terms of -* the GPL ("Copyleft"). -* -* Alternatively, this software may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GPL and are specifically designed for licensees interested in -* retaining the proprietary status of their code. -* -* Contact information: -* Quantum Leaps Web site: http://www.quantum-leaps.com -* e-mail: info@quantum-leaps.com -*****************************************************************************/ -#ifndef BSP_H -#define BSP_H - -#define KEY_PLUS '+' -#define KEY_MINUS '-' -#define KEY_MULT '*' -#define KEY_DIVIDE '/' - -void BSP_clear (void); -void BSP_negate(void); -void BSP_insert(int keyId); -double BSP_get_value(void); -int BSP_eval(double operand1, int oper, double operand2); -void BSP_exit(void); - -void BSP_display(void); -void BSP_message(char const *state); - -#endif /* BSP_H */ diff --git a/examples/workstation/calc/calc.c b/examples/workstation/calc/calc.c deleted file mode 100644 index f043852d..00000000 --- a/examples/workstation/calc/calc.c +++ /dev/null @@ -1,833 +0,0 @@ -/*$file${.::calc.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* -* Model: calc.qm -* File: ${.::calc.c} -* -* This code has been generated by QM 5.2.4 . -* DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. -* -* SPDX-License-Identifier: GPL-3.0-or-later -* -* This generated code is open source software: you can redistribute it under -* the terms of the GNU General Public License as published by the Free -* Software Foundation. -* -* This code is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -* more details. -* -* NOTE: -* Alternatively, this generated code may be distributed under the terms -* of Quantum Leaps commercial licenses, which expressly supersede the GNU -* General Public License and are specifically designed for licensees -* interested in retaining the proprietary status of their code. -* -* Contact information: -* -* -*/ -/*$endhead${.::calc.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -#include "qpc.h" /* QP/C */ -#include "bsp.h" /* board support package */ -#include "calc.h" /* application */ - -/*$declare${SMs::Calc} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${SMs::Calc} .............................................................*/ -typedef struct { -/* protected: */ - QHsm super; - -/* private: */ - double operand1; - uint8_t operator; -} Calc; - -/* protected: */ -static QState Calc_initial(Calc * const me, void const * const par); -static QState Calc_on(Calc * const me, QEvt const * const e); -static QState Calc_error(Calc * const me, QEvt const * const e); -static QState Calc_negated1(Calc * const me, QEvt const * const e); -static QState Calc_ready(Calc * const me, QEvt const * const e); -static QState Calc_result(Calc * const me, QEvt const * const e); -static QState Calc_begin(Calc * const me, QEvt const * const e); -static QState Calc_operand1(Calc * const me, QEvt const * const e); -static QState Calc_zero1(Calc * const me, QEvt const * const e); -static QState Calc_int1(Calc * const me, QEvt const * const e); -static QState Calc_frac1(Calc * const me, QEvt const * const e); -static QState Calc_opEntered(Calc * const me, QEvt const * const e); -static QState Calc_negated2(Calc * const me, QEvt const * const e); -static QState Calc_operand2(Calc * const me, QEvt const * const e); -static QState Calc_zero2(Calc * const me, QEvt const * const e); -static QState Calc_int2(Calc * const me, QEvt const * const e); -static QState Calc_frac2(Calc * const me, QEvt const * const e); -static QState Calc_final(Calc * const me, QEvt const * const e); -/*$enddecl${SMs::Calc} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ - -static Calc l_calc; /* the only instance of the Calc class */ - -/* global-scope definitions ---------------------------------------*/ -QHsm * const the_calc = &l_calc.super; /* "opaque" pointer to MSM */ - -/*$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* Check for the minimum required QP version */ -#if (QP_VERSION < 700U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) -#error qpc version 7.0.0 or higher required -#endif -/*$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ - -/*$define${SMs::Calc_ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${SMs::Calc_ctor} ........................................................*/ -void Calc_ctor(void) { - Calc *me = &l_calc; - QHsm_ctor(&me->super, Q_STATE_CAST(&Calc_initial)); -} -/*$enddef${SMs::Calc_ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*$define${SMs::Calc} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${SMs::Calc} .............................................................*/ - -/*${SMs::Calc::SM} .........................................................*/ -static QState Calc_initial(Calc * const me, void const * const par) { - /*${SMs::Calc::SM::initial} */ - BSP_clear(); - (void)par; /* unused parameter */ - - QS_FUN_DICTIONARY(&Calc_on); - QS_FUN_DICTIONARY(&Calc_error); - QS_FUN_DICTIONARY(&Calc_negated1); - QS_FUN_DICTIONARY(&Calc_ready); - QS_FUN_DICTIONARY(&Calc_result); - QS_FUN_DICTIONARY(&Calc_begin); - QS_FUN_DICTIONARY(&Calc_operand1); - QS_FUN_DICTIONARY(&Calc_zero1); - QS_FUN_DICTIONARY(&Calc_int1); - QS_FUN_DICTIONARY(&Calc_frac1); - QS_FUN_DICTIONARY(&Calc_opEntered); - QS_FUN_DICTIONARY(&Calc_negated2); - QS_FUN_DICTIONARY(&Calc_operand2); - QS_FUN_DICTIONARY(&Calc_zero2); - QS_FUN_DICTIONARY(&Calc_int2); - QS_FUN_DICTIONARY(&Calc_frac2); - QS_FUN_DICTIONARY(&Calc_final); - - return Q_TRAN(&Calc_on); -} - -/*${SMs::Calc::SM::on} .....................................................*/ -static QState Calc_on(Calc * const me, QEvt const * const e) { - QState status_; - switch (e->sig) { - /*${SMs::Calc::SM::on} */ - case Q_ENTRY_SIG: { - BSP_message("on-ENTRY;"); - status_ = Q_HANDLED(); - break; - } - /*${SMs::Calc::SM::on} */ - case Q_EXIT_SIG: { - BSP_message("on-EXIT;"); - status_ = Q_HANDLED(); - break; - } - /*${SMs::Calc::SM::on::initial} */ - case Q_INIT_SIG: { - BSP_message("on-INIT;"); - status_ = Q_TRAN(&Calc_ready); - break; - } - /*${SMs::Calc::SM::on::C} */ - case C_SIG: { - BSP_clear(); - status_ = Q_TRAN(&Calc_on); - break; - } - /*${SMs::Calc::SM::on::OFF} */ - case OFF_SIG: { - status_ = Q_TRAN(&Calc_final); - break; - } - default: { - status_ = Q_SUPER(&QHsm_top); - break; - } - } - return status_; -} - -/*${SMs::Calc::SM::on::error} ..............................................*/ -static QState Calc_error(Calc * const me, QEvt const * const e) { - QState status_; - switch (e->sig) { - /*${SMs::Calc::SM::on::error} */ - case Q_ENTRY_SIG: { - BSP_message("error-ENTRY;"); - status_ = Q_HANDLED(); - break; - } - /*${SMs::Calc::SM::on::error} */ - case Q_EXIT_SIG: { - BSP_message("error-EXIT;"); - status_ = Q_HANDLED(); - break; - } - default: { - status_ = Q_SUPER(&Calc_on); - break; - } - } - return status_; -} - -/*${SMs::Calc::SM::on::negated1} ...........................................*/ -static QState Calc_negated1(Calc * const me, QEvt const * const e) { - QState status_; - switch (e->sig) { - /*${SMs::Calc::SM::on::negated1} */ - case Q_ENTRY_SIG: { - BSP_message("negated1-ENTRY;"); - BSP_negate(); - status_ = Q_HANDLED(); - break; - } - /*${SMs::Calc::SM::on::negated1} */ - case Q_EXIT_SIG: { - BSP_message("negated1-EXIT;"); - status_ = Q_HANDLED(); - break; - } - /*${SMs::Calc::SM::on::negated1::DIGIT_0} */ - case DIGIT_0_SIG: { - BSP_insert(Q_EVT_CAST(CalcEvt)->key_code); - status_ = Q_TRAN(&Calc_zero1); - break; - } - /*${SMs::Calc::SM::on::negated1::DIGIT_1_9} */ - case DIGIT_1_9_SIG: { - BSP_insert(Q_EVT_CAST(CalcEvt)->key_code); - status_ = Q_TRAN(&Calc_int1); - break; - } - /*${SMs::Calc::SM::on::negated1::POINT} */ - case POINT_SIG: { - BSP_insert(Q_EVT_CAST(CalcEvt)->key_code); - status_ = Q_TRAN(&Calc_frac1); - break; - } - /*${SMs::Calc::SM::on::negated1::OPER} */ - case OPER_SIG: { - /*${SMs::Calc::SM::on::negated1::OPER::[e->key=='-']} */ - if (Q_EVT_CAST(CalcEvt)->key_code == KEY_MINUS) { - ; - status_ = Q_HANDLED(); - } - /*${SMs::Calc::SM::on::negated1::OPER::[else]} */ - else { - status_ = Q_HANDLED(); - } - break; - } - /*${SMs::Calc::SM::on::negated1::CE} */ - case CE_SIG: { - BSP_clear(); - status_ = Q_TRAN(&Calc_begin); - break; - } - default: { - status_ = Q_SUPER(&Calc_on); - break; - } - } - return status_; -} - -/*${SMs::Calc::SM::on::ready} ..............................................*/ -static QState Calc_ready(Calc * const me, QEvt const * const e) { - QState status_; - switch (e->sig) { - /*${SMs::Calc::SM::on::ready} */ - case Q_ENTRY_SIG: { - BSP_message("ready-ENTRY;"); - status_ = Q_HANDLED(); - break; - } - /*${SMs::Calc::SM::on::ready} */ - case Q_EXIT_SIG: { - BSP_message("ready-EXIT;"); - status_ = Q_HANDLED(); - break; - } - /*${SMs::Calc::SM::on::ready::initial} */ - case Q_INIT_SIG: { - BSP_message("ready-INIT;"); - status_ = Q_TRAN(&Calc_begin); - break; - } - /*${SMs::Calc::SM::on::ready::DIGIT_0} */ - case DIGIT_0_SIG: { - BSP_clear(); - status_ = Q_TRAN(&Calc_zero1); - break; - } - /*${SMs::Calc::SM::on::ready::DIGIT_1_9} */ - case DIGIT_1_9_SIG: { - BSP_clear(); - BSP_insert(Q_EVT_CAST(CalcEvt)->key_code); - status_ = Q_TRAN(&Calc_int1); - break; - } - /*${SMs::Calc::SM::on::ready::POINT} */ - case POINT_SIG: { - BSP_clear(); - BSP_insert((int)'0'); - BSP_insert((int)'.'); - status_ = Q_TRAN(&Calc_frac1); - break; - } - /*${SMs::Calc::SM::on::ready::OPER} */ - case OPER_SIG: { - me->operand1 = BSP_get_value(); - me->operator = Q_EVT_CAST(CalcEvt)->key_code; - status_ = Q_TRAN(&Calc_opEntered); - break; - } - default: { - status_ = Q_SUPER(&Calc_on); - break; - } - } - return status_; -} - -/*${SMs::Calc::SM::on::ready::result} ......................................*/ -static QState Calc_result(Calc * const me, QEvt const * const e) { - QState status_; - switch (e->sig) { - /*${SMs::Calc::SM::on::ready::result} */ - case Q_ENTRY_SIG: { - BSP_message("result-ENTRY;"); - status_ = Q_HANDLED(); - break; - } - /*${SMs::Calc::SM::on::ready::result} */ - case Q_EXIT_SIG: { - BSP_message("result-EXIT;"); - status_ = Q_HANDLED(); - break; - } - default: { - status_ = Q_SUPER(&Calc_ready); - break; - } - } - return status_; -} - -/*${SMs::Calc::SM::on::ready::begin} .......................................*/ -static QState Calc_begin(Calc * const me, QEvt const * const e) { - QState status_; - switch (e->sig) { - /*${SMs::Calc::SM::on::ready::begin} */ - case Q_ENTRY_SIG: { - BSP_message("begin-ENTRY;"); - status_ = Q_HANDLED(); - break; - } - /*${SMs::Calc::SM::on::ready::begin} */ - case Q_EXIT_SIG: { - BSP_message("begin-EXIT;"); - status_ = Q_HANDLED(); - break; - } - /*${SMs::Calc::SM::on::ready::begin::OPER} */ - case OPER_SIG: { - /*${SMs::Calc::SM::on::ready::begin::OPER::[e->key=='-']} */ - if (Q_EVT_CAST(CalcEvt)->key_code == KEY_MINUS) { - status_ = Q_TRAN(&Calc_negated1); - } - /*${SMs::Calc::SM::on::ready::begin::OPER::[else]} */ - else { - status_ = Q_HANDLED(); - } - break; - } - default: { - status_ = Q_SUPER(&Calc_ready); - break; - } - } - return status_; -} - -/*${SMs::Calc::SM::on::operand1} ...........................................*/ -static QState Calc_operand1(Calc * const me, QEvt const * const e) { - QState status_; - switch (e->sig) { - /*${SMs::Calc::SM::on::operand1} */ - case Q_ENTRY_SIG: { - BSP_message("operand1-ENTRY;"); - status_ = Q_HANDLED(); - break; - } - /*${SMs::Calc::SM::on::operand1} */ - case Q_EXIT_SIG: { - BSP_message("operand1-EXIT;"); - status_ = Q_HANDLED(); - break; - } - /*${SMs::Calc::SM::on::operand1::CE} */ - case CE_SIG: { - BSP_clear(); - status_ = Q_TRAN(&Calc_begin); - break; - } - /*${SMs::Calc::SM::on::operand1::OPER} */ - case OPER_SIG: { - me->operand1 = BSP_get_value(); - me->operator = Q_EVT_CAST(CalcEvt)->key_code; - status_ = Q_TRAN(&Calc_opEntered); - break; - } - /*${SMs::Calc::SM::on::operand1::EQUALS} */ - case EQUALS_SIG: { - status_ = Q_TRAN(&Calc_result); - break; - } - default: { - status_ = Q_SUPER(&Calc_on); - break; - } - } - return status_; -} - -/*${SMs::Calc::SM::on::operand1::zero1} ....................................*/ -static QState Calc_zero1(Calc * const me, QEvt const * const e) { - QState status_; - switch (e->sig) { - /*${SMs::Calc::SM::on::operand1::zero1} */ - case Q_ENTRY_SIG: { - BSP_message("zero1-ENTRY;"); - status_ = Q_HANDLED(); - break; - } - /*${SMs::Calc::SM::on::operand1::zero1} */ - case Q_EXIT_SIG: { - BSP_message("zero1-EXIT;"); - status_ = Q_HANDLED(); - break; - } - /*${SMs::Calc::SM::on::operand1::zero1::DIGIT_0} */ - case DIGIT_0_SIG: { - ; - status_ = Q_HANDLED(); - break; - } - /*${SMs::Calc::SM::on::operand1::zero1::DIGIT_1_9} */ - case DIGIT_1_9_SIG: { - BSP_insert(Q_EVT_CAST(CalcEvt)->key_code); - status_ = Q_TRAN(&Calc_int1); - break; - } - /*${SMs::Calc::SM::on::operand1::zero1::POINT} */ - case POINT_SIG: { - BSP_insert((int)'0'); - BSP_insert((int)'.'); - status_ = Q_TRAN(&Calc_frac1); - break; - } - default: { - status_ = Q_SUPER(&Calc_operand1); - break; - } - } - return status_; -} - -/*${SMs::Calc::SM::on::operand1::int1} .....................................*/ -static QState Calc_int1(Calc * const me, QEvt const * const e) { - QState status_; - switch (e->sig) { - /*${SMs::Calc::SM::on::operand1::int1} */ - case Q_ENTRY_SIG: { - BSP_message("int1-ENTRY;"); - status_ = Q_HANDLED(); - break; - } - /*${SMs::Calc::SM::on::operand1::int1} */ - case Q_EXIT_SIG: { - BSP_message("int1-EXIT;"); - status_ = Q_HANDLED(); - break; - } - /*${SMs::Calc::SM::on::operand1::int1::POINT} */ - case POINT_SIG: { - BSP_insert((int)'.'); - status_ = Q_TRAN(&Calc_frac1); - break; - } - /*${SMs::Calc::SM::on::operand1::int1::DIGIT_0, DIGIT_1_9} */ - case DIGIT_0_SIG: /* intentionally fall through */ - case DIGIT_1_9_SIG: { - BSP_insert(Q_EVT_CAST(CalcEvt)->key_code); - status_ = Q_HANDLED(); - break; - } - default: { - status_ = Q_SUPER(&Calc_operand1); - break; - } - } - return status_; -} - -/*${SMs::Calc::SM::on::operand1::frac1} ....................................*/ -static QState Calc_frac1(Calc * const me, QEvt const * const e) { - QState status_; - switch (e->sig) { - /*${SMs::Calc::SM::on::operand1::frac1} */ - case Q_ENTRY_SIG: { - BSP_message("frac1-ENTRY;"); - status_ = Q_HANDLED(); - break; - } - /*${SMs::Calc::SM::on::operand1::frac1} */ - case Q_EXIT_SIG: { - BSP_message("frac1-EXIT;"); - status_ = Q_HANDLED(); - break; - } - /*${SMs::Calc::SM::on::operand1::frac1::POINT} */ - case POINT_SIG: { - ; - status_ = Q_HANDLED(); - break; - } - /*${SMs::Calc::SM::on::operand1::frac1::DIGIT_0, DIGIT_1_9} */ - case DIGIT_0_SIG: /* intentionally fall through */ - case DIGIT_1_9_SIG: { - BSP_insert(Q_EVT_CAST(CalcEvt)->key_code); - status_ = Q_HANDLED(); - break; - } - default: { - status_ = Q_SUPER(&Calc_operand1); - break; - } - } - return status_; -} - -/*${SMs::Calc::SM::on::opEntered} ..........................................*/ -static QState Calc_opEntered(Calc * const me, QEvt const * const e) { - QState status_; - switch (e->sig) { - /*${SMs::Calc::SM::on::opEntered} */ - case Q_ENTRY_SIG: { - BSP_message("opEntered-ENTRY;"); - status_ = Q_HANDLED(); - break; - } - /*${SMs::Calc::SM::on::opEntered} */ - case Q_EXIT_SIG: { - BSP_message("opEntered-EXIT;"); - status_ = Q_HANDLED(); - break; - } - /*${SMs::Calc::SM::on::opEntered::DIGIT_0} */ - case DIGIT_0_SIG: { - BSP_clear(); - status_ = Q_TRAN(&Calc_zero2); - break; - } - /*${SMs::Calc::SM::on::opEntered::DIGIT_1_9} */ - case DIGIT_1_9_SIG: { - BSP_clear(); - BSP_insert(Q_EVT_CAST(CalcEvt)->key_code); - status_ = Q_TRAN(&Calc_int2); - break; - } - /*${SMs::Calc::SM::on::opEntered::POINT} */ - case POINT_SIG: { - BSP_clear(); - BSP_insert((int)'0'); - BSP_insert((int)'.'); - status_ = Q_TRAN(&Calc_frac2); - break; - } - /*${SMs::Calc::SM::on::opEntered::OPER} */ - case OPER_SIG: { - /*${SMs::Calc::SM::on::opEntered::OPER::[e->key=='-']} */ - if (Q_EVT_CAST(CalcEvt)->key_code == KEY_MINUS) { - status_ = Q_TRAN(&Calc_negated2); - } - /*${SMs::Calc::SM::on::opEntered::OPER::[else]} */ - else { - status_ = Q_HANDLED(); - } - break; - } - default: { - status_ = Q_SUPER(&Calc_on); - break; - } - } - return status_; -} - -/*${SMs::Calc::SM::on::negated2} ...........................................*/ -static QState Calc_negated2(Calc * const me, QEvt const * const e) { - QState status_; - switch (e->sig) { - /*${SMs::Calc::SM::on::negated2} */ - case Q_ENTRY_SIG: { - BSP_message("negated2-ENTRY;"); - BSP_negate(); - status_ = Q_HANDLED(); - break; - } - /*${SMs::Calc::SM::on::negated2} */ - case Q_EXIT_SIG: { - BSP_message("negated2-EXIT;"); - status_ = Q_HANDLED(); - break; - } - /*${SMs::Calc::SM::on::negated2::DIGIT_0} */ - case DIGIT_0_SIG: { - BSP_insert(Q_EVT_CAST(CalcEvt)->key_code); - status_ = Q_TRAN(&Calc_zero2); - break; - } - /*${SMs::Calc::SM::on::negated2::DIGIT_1_9} */ - case DIGIT_1_9_SIG: { - BSP_insert(Q_EVT_CAST(CalcEvt)->key_code); - status_ = Q_TRAN(&Calc_int2); - break; - } - /*${SMs::Calc::SM::on::negated2::POINT} */ - case POINT_SIG: { - BSP_insert(Q_EVT_CAST(CalcEvt)->key_code); - status_ = Q_TRAN(&Calc_frac2); - break; - } - /*${SMs::Calc::SM::on::negated2::OPER} */ - case OPER_SIG: { - /*${SMs::Calc::SM::on::negated2::OPER::[e->key=='-']} */ - if (Q_EVT_CAST(CalcEvt)->key_code == KEY_MINUS) { - ; - status_ = Q_HANDLED(); - } - /*${SMs::Calc::SM::on::negated2::OPER::[else]} */ - else { - status_ = Q_HANDLED(); - } - break; - } - /*${SMs::Calc::SM::on::negated2::CE} */ - case CE_SIG: { - BSP_clear(); - status_ = Q_TRAN(&Calc_opEntered); - break; - } - default: { - status_ = Q_SUPER(&Calc_on); - break; - } - } - return status_; -} - -/*${SMs::Calc::SM::on::operand2} ...........................................*/ -static QState Calc_operand2(Calc * const me, QEvt const * const e) { - QState status_; - switch (e->sig) { - /*${SMs::Calc::SM::on::operand2} */ - case Q_ENTRY_SIG: { - BSP_message("operand2-ENTRY;"); - status_ = Q_HANDLED(); - break; - } - /*${SMs::Calc::SM::on::operand2} */ - case Q_EXIT_SIG: { - BSP_message("operand2-EXIT;"); - status_ = Q_HANDLED(); - break; - } - /*${SMs::Calc::SM::on::operand2::CE} */ - case CE_SIG: { - BSP_clear(); - status_ = Q_TRAN(&Calc_opEntered); - break; - } - /*${SMs::Calc::SM::on::operand2::EQUALS} */ - case EQUALS_SIG: { - /*${SMs::Calc::SM::on::operand2::EQUALS::[BSP_eval()]} */ - if (BSP_eval(me->operand1, me->operator, BSP_get_value())) { - status_ = Q_TRAN(&Calc_result); - } - /*${SMs::Calc::SM::on::operand2::EQUALS::[else]} */ - else { - status_ = Q_TRAN(&Calc_error); - } - break; - } - /*${SMs::Calc::SM::on::operand2::OPER} */ - case OPER_SIG: { - /*${SMs::Calc::SM::on::operand2::OPER::[BSP_eval()]} */ - if (BSP_eval(me->operand1, me->operator, BSP_get_value())) { - me->operand1 = BSP_get_value(); - me->operator = Q_EVT_CAST(CalcEvt)->key_code; - status_ = Q_TRAN(&Calc_opEntered); - } - /*${SMs::Calc::SM::on::operand2::OPER::[else]} */ - else { - status_ = Q_TRAN(&Calc_error); - } - break; - } - default: { - status_ = Q_SUPER(&Calc_on); - break; - } - } - return status_; -} - -/*${SMs::Calc::SM::on::operand2::zero2} ....................................*/ -static QState Calc_zero2(Calc * const me, QEvt const * const e) { - QState status_; - switch (e->sig) { - /*${SMs::Calc::SM::on::operand2::zero2} */ - case Q_ENTRY_SIG: { - BSP_message("zero2-ENTRY;"); - status_ = Q_HANDLED(); - break; - } - /*${SMs::Calc::SM::on::operand2::zero2} */ - case Q_EXIT_SIG: { - BSP_message("zero2-EXIT;"); - status_ = Q_HANDLED(); - break; - } - /*${SMs::Calc::SM::on::operand2::zero2::DIGIT_0} */ - case DIGIT_0_SIG: { - ; - status_ = Q_HANDLED(); - break; - } - /*${SMs::Calc::SM::on::operand2::zero2::DIGIT_1_9} */ - case DIGIT_1_9_SIG: { - BSP_insert(Q_EVT_CAST(CalcEvt)->key_code); - status_ = Q_TRAN(&Calc_int2); - break; - } - /*${SMs::Calc::SM::on::operand2::zero2::POINT} */ - case POINT_SIG: { - BSP_insert((int)'0'); - BSP_insert((int)'.'); - status_ = Q_TRAN(&Calc_frac2); - break; - } - default: { - status_ = Q_SUPER(&Calc_operand2); - break; - } - } - return status_; -} - -/*${SMs::Calc::SM::on::operand2::int2} .....................................*/ -static QState Calc_int2(Calc * const me, QEvt const * const e) { - QState status_; - switch (e->sig) { - /*${SMs::Calc::SM::on::operand2::int2} */ - case Q_ENTRY_SIG: { - BSP_message("int2-ENTRY;"); - status_ = Q_HANDLED(); - break; - } - /*${SMs::Calc::SM::on::operand2::int2} */ - case Q_EXIT_SIG: { - BSP_message("int2-EXIT;"); - status_ = Q_HANDLED(); - break; - } - /*${SMs::Calc::SM::on::operand2::int2::POINT} */ - case POINT_SIG: { - BSP_insert((int)'.'); - status_ = Q_TRAN(&Calc_frac2); - break; - } - /*${SMs::Calc::SM::on::operand2::int2::DIGIT_0, DIGIT_1_9} */ - case DIGIT_0_SIG: /* intentionally fall through */ - case DIGIT_1_9_SIG: { - BSP_insert(Q_EVT_CAST(CalcEvt)->key_code); - status_ = Q_HANDLED(); - break; - } - default: { - status_ = Q_SUPER(&Calc_operand2); - break; - } - } - return status_; -} - -/*${SMs::Calc::SM::on::operand2::frac2} ....................................*/ -static QState Calc_frac2(Calc * const me, QEvt const * const e) { - QState status_; - switch (e->sig) { - /*${SMs::Calc::SM::on::operand2::frac2} */ - case Q_ENTRY_SIG: { - BSP_message("frac2-ENTRY;"); - status_ = Q_HANDLED(); - break; - } - /*${SMs::Calc::SM::on::operand2::frac2} */ - case Q_EXIT_SIG: { - BSP_message("frac2-EXIT;"); - status_ = Q_HANDLED(); - break; - } - /*${SMs::Calc::SM::on::operand2::frac2::POINT} */ - case POINT_SIG: { - ; - status_ = Q_HANDLED(); - break; - } - /*${SMs::Calc::SM::on::operand2::frac2::DIGIT_0, DIGIT_1_9} */ - case DIGIT_0_SIG: /* intentionally fall through */ - case DIGIT_1_9_SIG: { - BSP_insert(Q_EVT_CAST(CalcEvt)->key_code); - status_ = Q_HANDLED(); - break; - } - default: { - status_ = Q_SUPER(&Calc_operand2); - break; - } - } - return status_; -} - -/*${SMs::Calc::SM::final} ..................................................*/ -static QState Calc_final(Calc * const me, QEvt const * const e) { - QState status_; - switch (e->sig) { - /*${SMs::Calc::SM::final} */ - case Q_ENTRY_SIG: { - BSP_message("final-ENTRY;"); - BSP_exit(); - status_ = Q_HANDLED(); - break; - } - default: { - status_ = Q_SUPER(&QHsm_top); - break; - } - } - return status_; -} -/*$enddef${SMs::Calc} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ diff --git a/examples/workstation/calc/calc.h b/examples/workstation/calc/calc.h deleted file mode 100644 index 015561dd..00000000 --- a/examples/workstation/calc/calc.h +++ /dev/null @@ -1,65 +0,0 @@ -/*$file${.::calc.h} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* -* Model: calc.qm -* File: ${.::calc.h} -* -* This code has been generated by QM 5.2.4 . -* DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. -* -* SPDX-License-Identifier: GPL-3.0-or-later -* -* This generated code is open source software: you can redistribute it under -* the terms of the GNU General Public License as published by the Free -* Software Foundation. -* -* This code is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -* more details. -* -* NOTE: -* Alternatively, this generated code may be distributed under the terms -* of Quantum Leaps commercial licenses, which expressly supersede the GNU -* General Public License and are specifically designed for licensees -* interested in retaining the proprietary status of their code. -* -* Contact information: -* -* -*/ -/*$endhead${.::calc.h} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -#ifndef CALC_H -#define CALC_H - -enum CalcSignals { - C_SIG = Q_USER_SIG, - CE_SIG, - DIGIT_0_SIG, - DIGIT_1_9_SIG, - POINT_SIG, - OPER_SIG, - EQUALS_SIG, - OFF_SIG -}; - -/*$declare${Events::CalcEvt} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${Events::CalcEvt} .......................................................*/ -typedef struct { -/* protected: */ - QEvt super; - -/* public: */ - uint8_t key_code; -} CalcEvt; -/*$enddecl${Events::CalcEvt} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*$declare${SMs::Calc_ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${SMs::Calc_ctor} ........................................................*/ -void Calc_ctor(void); -/*$enddecl${SMs::Calc_ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ - -extern QHsm * const the_calc; /* "opaque" pointer to calculator MSM */ - -#endif /* CALC_H */ - diff --git a/examples/workstation/calc/calc.qm b/examples/workstation/calc/calc.qm deleted file mode 100644 index 5f6ffbe2..00000000 --- a/examples/workstation/calc/calc.qm +++ /dev/null @@ -1,631 +0,0 @@ - - - Calc is the model of the Calculator described in Chapter 4 of PSiCC2 - - - - - - - - - - - - - - - Calculator state machine - - - - - - - - - BSP_clear(); -(void)par; /* unused parameter */ - - - - - - - BSP_message("on-ENTRY;"); - BSP_message("on-EXIT;"); - - - BSP_message("on-INIT;"); - - - - - - - BSP_clear(); - - - - - - - - - - - - - BSP_message("error-ENTRY;"); - BSP_message("error-EXIT;"); - - - - - - - - BSP_message("negated1-ENTRY;"); -BSP_negate(); - BSP_message("negated1-EXIT;"); - - - BSP_insert(Q_EVT_CAST(CalcEvt)->key_code); - - - - - - - BSP_insert(Q_EVT_CAST(CalcEvt)->key_code); - - - - - - - BSP_insert(Q_EVT_CAST(CalcEvt)->key_code); - - - - - - - - - else - - - - - - - Q_EVT_CAST(CalcEvt)->key_code == KEY_MINUS - ; - - - - - - - - - - - BSP_clear(); - - - - - - - - - - - - BSP_message("ready-ENTRY;"); - BSP_message("ready-EXIT;"); - - - BSP_message("ready-INIT;"); - - - - - - - BSP_clear(); - - - - - - - BSP_clear(); -BSP_insert(Q_EVT_CAST(CalcEvt)->key_code); - - - - - - - BSP_clear(); -BSP_insert((int)'0'); -BSP_insert((int)'.'); - - - - - - - me->operand1 = BSP_get_value(); -me->operator = Q_EVT_CAST(CalcEvt)->key_code; - - - - - - - BSP_message("result-ENTRY;"); - BSP_message("result-EXIT;"); - - - - - - - - BSP_message("begin-ENTRY;"); - BSP_message("begin-EXIT;"); - - - - - Q_EVT_CAST(CalcEvt)->key_code == KEY_MINUS - - - - - - - else - - - - - - - - - - - - - - - - - - - - - BSP_message("operand1-ENTRY;"); - BSP_message("operand1-EXIT;"); - - - BSP_clear(); - - - - - - - me->operand1 = BSP_get_value(); -me->operator = Q_EVT_CAST(CalcEvt)->key_code; - - - - - - - - - - - - - BSP_message("zero1-ENTRY;"); - BSP_message("zero1-EXIT;"); - - - ; - - - - - - - BSP_insert(Q_EVT_CAST(CalcEvt)->key_code); - - - - - - - BSP_insert((int)'0'); -BSP_insert((int)'.'); - - - - - - - - - - - - BSP_message("int1-ENTRY;"); - BSP_message("int1-EXIT;"); - - - BSP_insert((int)'.'); - - - - - - - BSP_insert(Q_EVT_CAST(CalcEvt)->key_code); - - - - - - - - - - - - BSP_message("frac1-ENTRY;"); - BSP_message("frac1-EXIT;"); - - - ; - - - - - - - BSP_insert(Q_EVT_CAST(CalcEvt)->key_code); - - - - - - - - - - - - - - - - - BSP_message("opEntered-ENTRY;"); - BSP_message("opEntered-EXIT;"); - - - BSP_clear(); - - - - - - - BSP_clear(); -BSP_insert(Q_EVT_CAST(CalcEvt)->key_code); - - - - - - - BSP_clear(); -BSP_insert((int)'0'); -BSP_insert((int)'.'); - - - - - - - - - Q_EVT_CAST(CalcEvt)->key_code == KEY_MINUS - - - - - - - else - - - - - - - - - - - - - - - - BSP_message("negated2-ENTRY;"); -BSP_negate(); - BSP_message("negated2-EXIT;"); - - - BSP_insert(Q_EVT_CAST(CalcEvt)->key_code); - - - - - - - BSP_insert(Q_EVT_CAST(CalcEvt)->key_code); - - - - - - - BSP_insert(Q_EVT_CAST(CalcEvt)->key_code); - - - - - - - - - else - - - - - - - Q_EVT_CAST(CalcEvt)->key_code == KEY_MINUS - ; - - - - - - - - - - - BSP_clear(); - - - - - - - - - - - - BSP_message("operand2-ENTRY;"); - BSP_message("operand2-EXIT;"); - - - BSP_clear(); - - - - - - - - - else - - - - - - - BSP_eval(me->operand1, me->operator, BSP_get_value()) - - - - - - - - - - - - - else - - - - - - - BSP_eval(me->operand1, me->operator, BSP_get_value()) - me->operand1 = BSP_get_value(); -me->operator = Q_EVT_CAST(CalcEvt)->key_code; - - - - - - - - - - - BSP_message("zero2-ENTRY;"); - BSP_message("zero2-EXIT;"); - - - ; - - - - - - - BSP_insert(Q_EVT_CAST(CalcEvt)->key_code); - - - - - - - BSP_insert((int)'0'); -BSP_insert((int)'.'); - - - - - - - - - - - - BSP_message("int2-ENTRY;"); - BSP_message("int2-EXIT;"); - - - BSP_insert((int)'.'); - - - - - - - BSP_insert(Q_EVT_CAST(CalcEvt)->key_code); - - - - - - - - - - - - BSP_message("frac2-ENTRY;"); - BSP_message("frac2-EXIT;"); - - - ; - - - - - - - BSP_insert(Q_EVT_CAST(CalcEvt)->key_code); - - - - - - - - - - - - - - - - - - - - - - BSP_message("final-ENTRY;"); -BSP_exit(); - - - - - - - - - - constructor - Calc *me = &l_calc; -QHsm_ctor(&me->super, Q_STATE_CAST(&Calc_initial)); - - - - - - - #ifndef CALC_H -#define CALC_H - -enum CalcSignals { - C_SIG = Q_USER_SIG, - CE_SIG, - DIGIT_0_SIG, - DIGIT_1_9_SIG, - POINT_SIG, - OPER_SIG, - EQUALS_SIG, - OFF_SIG -}; - -$declare(Events::CalcEvt) -$declare(SMs::Calc_ctor) - -extern QHsm * const the_calc; /* "opaque" pointer to calculator MSM */ - -#endif /* CALC_H */ - - - - - #include "qpc.h" /* QP/C */ -#include "bsp.h" /* board support package */ -#include "calc.h" /* application */ - -$declare(SMs::Calc) - -static Calc l_calc; /* the only instance of the Calc class */ - -/* global-scope definitions ---------------------------------------*/ -QHsm * const the_calc = &l_calc.super; /* "opaque" pointer to MSM */ - -$define(SMs::Calc_ctor) -$define(SMs::Calc) - - - diff --git a/examples/workstation/calc/main.c b/examples/workstation/calc/main.c deleted file mode 100644 index b65220ed..00000000 --- a/examples/workstation/calc/main.c +++ /dev/null @@ -1,134 +0,0 @@ -/***************************************************************************** -* Product: calc Example -* Last updated for version 6.9.1 -* Last updated on 2020-09-11 -* -* Q u a n t u m L e a P s -* ------------------------ -* Modern Embedded Software -* -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* -* -*****************************************************************************/ -#include "qpc.h" -#include "bsp.h" -#include "calc.h" - -#include "safe_std.h" /* portable "safe" / facilities */ - -Q_DEFINE_THIS_FILE - -/*..........................................................................*/ -int main() { - - QF_init(); - QF_onStartup(); - - PRINTF_S("Calculator example, QP version: %s\n" - "Press '0' .. '9' to enter a digit\n" - "Press '.' to enter the decimal point\n" - "Press '+' to add\n" - "Press '-' to subtract or negate a number\n" - "Press '*' to multiply\n" - "Press '/' to divide\n" - "Press '=' or to get the result\n" - "Press 'c' or 'C' to Cancel\n" - "Press 'e' or 'E' to Cancel Entry\n" - "Press to quit.\n\n", - QP_VERSION_STR); - - Calc_ctor(); /* explicitly instantiate the calculator object */ - QHSM_INIT(the_calc, (void *)0, 0U); /* trigger initial transition */ - - for (;;) { /* event loop */ - CalcEvt e; /* Calculator event */ - - BSP_display(); /* show the display */ - - PRINTF_S("%s", " : "); - fflush(stdout); - e.key_code = (uint8_t)QF_consoleWaitForKey(); - PRINTF_S("%c ", (e.key_code >= ' ') ? e.key_code : 'X'); - - switch (e.key_code) { - case 'c': /* intentionally fall through */ - case 'C': { - e.super.sig = C_SIG; - break; - } - case 'e': /* intentionally fall through */ - case 'E': { - e.super.sig = CE_SIG; - break; - } - case '0': { - e.super.sig = DIGIT_0_SIG; - break; - } - case '1': /* intentionally fall through */ - case '2': /* intentionally fall through */ - case '3': /* intentionally fall through */ - case '4': /* intentionally fall through */ - case '5': /* intentionally fall through */ - case '6': /* intentionally fall through */ - case '7': /* intentionally fall through */ - case '8': /* intentionally fall through */ - case '9': { - e.super.sig = DIGIT_1_9_SIG; - break; - } - case '.': { - e.super.sig = POINT_SIG; - break; - } - case '+': /* intentionally fall through */ - case '-': /* intentionally fall through */ - case '*': /* intentionally fall through */ - case '/': { - e.super.sig = OPER_SIG; - break; - } - case '=': /* intentionally fall through */ - case '\r': { /* Enter key */ - e.super.sig = EQUALS_SIG; - break; - } - case '\33': { /* ESC key */ - e.super.sig = OFF_SIG; - break; - } - default: { - e.super.sig = 0; /* invalid event */ - break; - } - } - - if (e.super.sig != 0) { /* valid event generated? */ - QHSM_DISPATCH(the_calc, &e.super, 0U); /* dispatch event */ - } - } - - QF_onCleanup(); - return 0; -} diff --git a/examples/workstation/calc1/SM_of_Calc.png b/examples/workstation/calc1/SM_of_Calc.png deleted file mode 100644 index d8995407..00000000 Binary files a/examples/workstation/calc1/SM_of_Calc.png and /dev/null differ diff --git a/examples/workstation/calc1/bsp.c b/examples/workstation/calc1/bsp.c deleted file mode 100644 index 54d3f3bc..00000000 --- a/examples/workstation/calc1/bsp.c +++ /dev/null @@ -1,120 +0,0 @@ -/***************************************************************************** -* Product: Board Support Package (BSP) for the Calculator example -* Last updated for version 6.9.0 -* Last updated on 2020-06-24 -* -* Q u a n t u m L e a P s -* ------------------------ -* Modern Embedded Software -* -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* -* -*****************************************************************************/ -#include "qpc.h" -#include "bsp.h" - -#include "safe_std.h" /* portable "safe" / facilities */ -#include /* for exit() */ - -#define DISP_WIDTH 15 - -/* helper macros to "stringify" values */ -#define VAL(x) #x -#define STRINGIFY(x) VAL(x) - -static char l_display[DISP_WIDTH + 1]; /* the calculator display */ -static int l_len; /* number of displayed characters */ - -/*..........................................................................*/ -void BSP_clear(void) { - memset(l_display, ' ', DISP_WIDTH - 1); - l_display[DISP_WIDTH - 1] = '0'; - l_display[DISP_WIDTH] = '\0'; - l_len = 0; -} -/*..........................................................................*/ -void BSP_insert(int keyId) { - if (l_len == 0) { - l_display[DISP_WIDTH - 1] = (char)keyId; - ++l_len; - } - else if (l_len < (DISP_WIDTH - 1)) { - MEMMOVE_S(&l_display[0], DISP_WIDTH, &l_display[1], DISP_WIDTH - 1); - l_display[DISP_WIDTH - 1] = (char)keyId; - ++l_len; - } -} -/*..........................................................................*/ -void BSP_display(double value) { - SNPRINTF_S(l_display, Q_DIM(l_display), - "%" STRINGIFY(DISP_WIDTH) ".6g", value); -} -/*..........................................................................*/ -void BSP_display_error(char const *err) { - STRNCPY_S(l_display, DISP_WIDTH, err); -} -/*..........................................................................*/ -void BSP_negate(void) { - BSP_clear(); - l_display[DISP_WIDTH - 2] = '-'; -} -/*..........................................................................*/ -void BSP_show_display(void) { - PRINTF_S("\n[%" STRINGIFY(DISP_WIDTH) "s] ", l_display); -} -/*..........................................................................*/ -void BSP_exit(void) { - PRINTF_S("\n%s\n", "Bye! Bye!"); - fflush(stdout); - QF_onCleanup(); - exit(0); -} -/*..........................................................................*/ -double BSP_get_value(void) { - return strtod(l_display, (char **)0); -} -/*..........................................................................*/ -void BSP_message(char const *msg) { - PRINTF_S("%s", msg); -} - -/*..........................................................................*/ -void QF_onStartup(void) { - QF_consoleSetup(); -} -/*..........................................................................*/ -void QF_onCleanup(void) { - QF_consoleCleanup(); -} -/*..........................................................................*/ -void QF_onClockTick(void) { -} - -/*..........................................................................*/ -/* this function is used by the QP embedded systems-friendly assertions */ -Q_NORETURN Q_onAssert(char const * const module, int_t const loc) { - FPRINTF_S(stderr, "Assertion failed in %s:%d", module, loc); - QF_onCleanup(); - exit(-1); -} diff --git a/examples/workstation/calc1/bsp.h b/examples/workstation/calc1/bsp.h deleted file mode 100644 index 7b9e469a..00000000 --- a/examples/workstation/calc1/bsp.h +++ /dev/null @@ -1,48 +0,0 @@ -/***************************************************************************** -* Product: Board Support Package (BSP) for the Calculator example -* Last updated for version 6.5.0 -* Last updated on 2019-03-20 -* -* Q u a n t u m L e a P s -* ------------------------ -* Modern Embedded Software -* -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* -* -*****************************************************************************/ -#ifndef BSP_H -#define BSP_H - -void BSP_clear(void); -void BSP_negate(void); -void BSP_insert(int keyId); -double BSP_get_value(void); -void BSP_display(double value); -void BSP_display_error(char const *err); -void BSP_exit(void); - -void BSP_show_display(void); -void BSP_message(char const *msg); - -#endif /* BSP_H */ diff --git a/examples/workstation/calc1/calc1.h b/examples/workstation/calc1/calc1.h deleted file mode 100644 index 1505072e..00000000 --- a/examples/workstation/calc1/calc1.h +++ /dev/null @@ -1,65 +0,0 @@ -/*$file${.::calc1.h} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* -* Model: calc1.qm -* File: ${.::calc1.h} -* -* This code has been generated by QM 5.2.4 . -* DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. -* -* SPDX-License-Identifier: GPL-3.0-or-later -* -* This generated code is open source software: you can redistribute it under -* the terms of the GNU General Public License as published by the Free -* Software Foundation. -* -* This code is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -* more details. -* -* NOTE: -* Alternatively, this generated code may be distributed under the terms -* of Quantum Leaps commercial licenses, which expressly supersede the GNU -* General Public License and are specifically designed for licensees -* interested in retaining the proprietary status of their code. -* -* Contact information: -* -* -*/ -/*$endhead${.::calc1.h} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -#ifndef CALC1_H -#define CALC1_H - -enum CalcSignals { - C_SIG = Q_USER_SIG, - CE_SIG, - DIGIT_0_SIG, - DIGIT_1_9_SIG, - POINT_SIG, - OPER_SIG, - EQUALS_SIG, - OFF_SIG -}; - -/*$declare${Events::CalcEvt} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${Events::CalcEvt} .......................................................*/ -typedef struct { -/* protected: */ - QEvt super; - -/* public: */ - uint8_t key_code; -} CalcEvt; -/*$enddecl${Events::CalcEvt} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*$declare${SMs::Calc_ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${SMs::Calc_ctor} ........................................................*/ -void Calc_ctor(void); -/*$enddecl${SMs::Calc_ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ - -extern QHsm * const the_calc; /* "opaque" pointer to calculator HSM */ - -#endif /* CALC1_H */ - diff --git a/examples/workstation/calc1/main.c b/examples/workstation/calc1/main.c deleted file mode 100644 index 58f2b646..00000000 --- a/examples/workstation/calc1/main.c +++ /dev/null @@ -1,134 +0,0 @@ -/***************************************************************************** -* Product: calc1_sub Example -* Last updated for version 6.9.1 -* Last updated on 2020-09-11 -* -* Q u a n t u m L e a P s -* ------------------------ -* Modern Embedded Software -* -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* -* -*****************************************************************************/ -#include "qpc.h" -#include "bsp.h" -#include "calc1.h" - -#include "safe_std.h" /* portable "safe" / facilities */ - -Q_DEFINE_THIS_FILE - -/*..........................................................................*/ -int main() { - - QF_init(); - QF_onStartup(); - - PRINTF_S("Calculator example, QP version: %s\n" - "Press '0' .. '9' to enter a digit\n" - "Press '.' to enter the decimal point\n" - "Press '+' to add\n" - "Press '-' to subtract or negate a number\n" - "Press '*' to multiply\n" - "Press '/' to divide\n" - "Press '=' or to get the result\n" - "Press 'c' or 'C' to Cancel\n" - "Press 'e' or 'E' to Cancel Entry\n" - "Press to quit.\n\n", - QP_VERSION_STR); - - Calc_ctor(); /* explicitly instantiate the calculator object */ - QHSM_INIT(the_calc, (void *)0, 0U); /* trigger initial transition */ - - for (;;) { /* event loop */ - CalcEvt e; /* Calculator event */ - - BSP_show_display(); /* show the display */ - - PRINTF_S("%s"," : "); - fflush(stdout); - e.key_code = (uint8_t)QF_consoleWaitForKey(); - PRINTF_S("%c ", (e.key_code >= ' ') ? e.key_code : 'X'); - - switch (e.key_code) { - case 'c': /* intentionally fall through */ - case 'C': { - e.super.sig = C_SIG; - break; - } - case 'e': /* intentionally fall through */ - case 'E': { - e.super.sig = CE_SIG; - break; - } - case '0': { - e.super.sig = DIGIT_0_SIG; - break; - } - case '1': /* intentionally fall through */ - case '2': /* intentionally fall through */ - case '3': /* intentionally fall through */ - case '4': /* intentionally fall through */ - case '5': /* intentionally fall through */ - case '6': /* intentionally fall through */ - case '7': /* intentionally fall through */ - case '8': /* intentionally fall through */ - case '9': { - e.super.sig = DIGIT_1_9_SIG; - break; - } - case '.': { - e.super.sig = POINT_SIG; - break; - } - case '+': /* intentionally fall through */ - case '-': /* intentionally fall through */ - case '*': /* intentionally fall through */ - case '/': { - e.super.sig = OPER_SIG; - break; - } - case '=': /* intentionally fall through */ - case '\r': { /* Enter key */ - e.super.sig = EQUALS_SIG; - break; - } - case '\33': { /* ESC key */ - e.super.sig = OFF_SIG; - break; - } - default: { - e.super.sig = 0; /* invalid event */ - break; - } - } - - if (e.super.sig != 0) { /* valid event generated? */ - QHSM_DISPATCH(the_calc, &e.super, 0U); /* dispatch event */ - } - } - - QF_onCleanup(); - return 0; -} diff --git a/examples/workstation/calc1_sub/.clang-tidy b/examples/workstation/calc1_sub/.clang-tidy deleted file mode 100644 index 09bd03da..00000000 --- a/examples/workstation/calc1_sub/.clang-tidy +++ /dev/null @@ -1,2 +0,0 @@ -Checks: 'cert-*,' -WarningsAsErrors: true diff --git a/examples/workstation/calc1_sub/Makefile b/examples/workstation/calc1_sub/Makefile deleted file mode 100644 index f9744dad..00000000 --- a/examples/workstation/calc1_sub/Makefile +++ /dev/null @@ -1,291 +0,0 @@ -############################################################################## -# Product: Makefile for QP/C for Windows and POSIX *HOSTS* -# Last updated for version 7.2.0 -# Last updated on 2022-11-13 -# -# Q u a n t u m L e a P s -# ------------------------ -# Modern Embedded Software -# -# Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -# -# This program is open source software: you can redistribute it and/or -# modify it under the terms of the GNU General Public License as published -# by the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# Alternatively, this program may be distributed and modified under the -# terms of Quantum Leaps commercial licenses, which expressly supersede -# the GNU General Public License and are specifically designed for -# licensees interested in retaining the proprietary status of their code. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . -# -# Contact information: -# -# -############################################################################## -# -# examples of invoking this Makefile: -# building configurations: Debug (default), Release, and Spy -# make -# make CONF=rel -# make CONF=spy -# make clean # cleanup the build -# make CONF=spy clean # cleanup the build -# -# NOTE: -# To use this Makefile on Windows, you will need the GNU make utility, which -# is included in the QTools collection for Windows, see: -# http://sourceforge.net/projects/qpc/files/QTools/ -# - -#----------------------------------------------------------------------------- -# project name: -# -PROJECT := calc1_sub - -#----------------------------------------------------------------------------- -# project directories: -# - -# list of all source directories used by this project -VPATH := . \ - -# list of all include directories needed by this project -INCLUDES := -I. \ - -# location of the QP/C framework (if not provided in an env. variable) -ifeq ($(QPC),) -QPC := ../../.. -endif - -#----------------------------------------------------------------------------- -# project files: -# - -# C source files... -C_SRCS := \ - bsp.c \ - main.c \ - calc1_sub.c - -# C++ source files... -CPP_SRCS := - -LIB_DIRS := -LIBS := - -# defines... -# QP_API_VERSION controls the QP API compatibility; 9999 means the latest API -DEFINES := -DQP_API_VERSION=9999 - -ifeq (,$(CONF)) - CONF := dbg -endif - -#----------------------------------------------------------------------------- -# add QP/C framework: -# -C_SRCS += \ - qep_hsm.c \ - qep_msm.c \ - qf_act.c \ - qf_actq.c \ - qf_defer.c \ - qf_dyn.c \ - qf_mem.c \ - qf_ps.c \ - qf_qact.c \ - qf_qeq.c \ - qf_qmact.c \ - qf_time.c \ - qf_port.c - -QS_SRCS := \ - qs.c \ - qs_64bit.c \ - qs_rx.c \ - qs_fp.c \ - qs_port.c - -ifeq ($(OS),Windows_NT) - -# NOTE: -# For Windows hosts, you can choose: -# - the single-threaded QP/C port (win32-qv) or -# - the multithreaded QP/C port (win32). -# -QP_PORT_DIR := $(QPC)/ports/win32-qv -#QP_PORT_DIR := $(QPC)/ports/win32 -LIBS += -lws2_32 - -else - -# NOTE: -# For POSIX hosts (Linux, MacOS), you can choose: -# - the single-threaded QP/C port (win32-qv) or -# - the multithreaded QP/C port (win32). -# -QP_PORT_DIR := $(QPC)/ports/posix-qv -#QP_PORT_DIR := $(QPC)/ports/posix - -LIBS += -lpthread - -endif - -#============================================================================ -# Typically you should not need to change anything below this line - -VPATH += $(QPC)/src/qf $(QP_PORT_DIR) -INCLUDES += -I$(QPC)/include -I$(QP_PORT_DIR) - -#----------------------------------------------------------------------------- -# GNU toolset: -# -# NOTE: -# GNU toolset (MinGW) is included in the QTools collection for Windows, see: -# https://www.state-machine.com/qtools -# It is assumed that %QTOOLS%\bin directory is added to the PATH -# -CC := gcc -CPP := g++ -LINK := gcc # for C programs -#LINK := g++ # for C++ programs - -#----------------------------------------------------------------------------- -# basic utilities (depends on the OS this Makefile runs on): -# -ifeq ($(OS),Windows_NT) - MKDIR := mkdir - RM := rm - TARGET_EXT := .exe -else ifeq ($(OSTYPE),cygwin) - MKDIR := mkdir -p - RM := rm -f - TARGET_EXT := .exe -else - MKDIR := mkdir -p - RM := rm -f - TARGET_EXT := -endif - -#----------------------------------------------------------------------------- -# build configurations... - -ifeq (rel, $(CONF)) # Release configuration .................................. - -BIN_DIR := build_rel -# gcc options: -CFLAGS = -c -O3 -fno-pie -std=c11 -pedantic -Wall -Wextra -W \ - $(INCLUDES) $(DEFINES) -DNDEBUG - -CPPFLAGS = -c -O3 -fno-pie -std=c++11 -pedantic -Wall -Wextra \ - -fno-rtti -fno-exceptions \ - $(INCLUDES) $(DEFINES) -DNDEBUG - -else ifeq (spy, $(CONF)) # Spy configuration ................................ - -BIN_DIR := build_spy - -C_SRCS += $(QS_SRCS) -VPATH += $(QPC)/src/qs - -# gcc options: -CFLAGS = -c -g -O -fno-pie -std=c11 -pedantic -Wall -Wextra -W \ - $(INCLUDES) $(DEFINES) -DQ_SPY - -CPPFLAGS = -c -g -O -fno-pie -std=c++11 -pedantic -Wall -Wextra \ - -fno-rtti -fno-exceptions \ - $(INCLUDES) $(DEFINES) -DQ_SPY - -else # default Debug configuration ......................................... - -BIN_DIR := build - -# gcc options: -CFLAGS = -c -g -O -fno-pie -std=c11 -pedantic -Wall -Wextra -W \ - $(INCLUDES) $(DEFINES) - -CPPFLAGS = -c -g -O -fno-pie -std=c++11 -pedantic -Wall -Wextra \ - -fno-rtti -fno-exceptions \ - $(INCLUDES) $(DEFINES) - -endif # ..................................................................... - -ifndef GCC_OLD - LINKFLAGS := -no-pie -endif - -#----------------------------------------------------------------------------- -C_OBJS := $(patsubst %.c,%.o, $(C_SRCS)) -CPP_OBJS := $(patsubst %.cpp,%.o, $(CPP_SRCS)) - -TARGET_EXE := $(BIN_DIR)/$(PROJECT)$(TARGET_EXT) -C_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(C_OBJS)) -C_DEPS_EXT := $(patsubst %.o,%.d, $(C_OBJS_EXT)) -CPP_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(CPP_OBJS)) -CPP_DEPS_EXT := $(patsubst %.o,%.d, $(CPP_OBJS_EXT)) - -#----------------------------------------------------------------------------- -# rules -# - -.PHONY: clean show - -all: $(TARGET_EXE) - -$(TARGET_EXE) : $(C_OBJS_EXT) $(CPP_OBJS_EXT) - $(CC) $(CFLAGS) $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o - $(LINK) $(LINKFLAGS) $(LIB_DIRS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) - -$(BIN_DIR)/%.d : %.c - $(CC) -MM -MT $(@:.d=.o) $(CFLAGS) $< > $@ - -$(BIN_DIR)/%.d : %.cpp - $(CPP) -MM -MT $(@:.d=.o) $(CPPFLAGS) $< > $@ - -$(BIN_DIR)/%.o : %.c - $(CC) $(CFLAGS) $< -o $@ - -$(BIN_DIR)/%.o : %.cpp - $(CPP) $(CPPFLAGS) $< -o $@ - -# create BIN_DIR and include dependencies only if needed -ifneq ($(MAKECMDGOALS),clean) - ifneq ($(MAKECMDGOALS),show) - ifneq ($(MAKECMDGOALS),debug) -ifeq ("$(wildcard $(BIN_DIR))","") -$(shell $(MKDIR) $(BIN_DIR)) -endif --include $(C_DEPS_EXT) $(CPP_DEPS_EXT) - endif - endif -endif - -clean : - -$(RM) $(BIN_DIR)/*.o \ - $(BIN_DIR)/*.d \ - $(TARGET_EXE) - -show : - @echo PROJECT = $(PROJECT) - @echo TARGET_EXE = $(TARGET_EXE) - @echo VPATH = $(VPATH) - @echo C_SRCS = $(C_SRCS) - @echo CPP_SRCS = $(CPP_SRCS) - @echo C_DEPS_EXT = $(C_DEPS_EXT) - @echo C_OBJS_EXT = $(C_OBJS_EXT) - @echo C_DEPS_EXT = $(C_DEPS_EXT) - @echo CPP_DEPS_EXT = $(CPP_DEPS_EXT) - @echo CPP_OBJS_EXT = $(CPP_OBJS_EXT) - @echo LIB_DIRS = $(LIB_DIRS) - @echo LIBS = $(LIBS) - @echo DEFINES = $(DEFINES) - diff --git a/examples/workstation/calc1_sub/bsp.c b/examples/workstation/calc1_sub/bsp.c deleted file mode 100644 index b530f28f..00000000 --- a/examples/workstation/calc1_sub/bsp.c +++ /dev/null @@ -1,111 +0,0 @@ -/*============================================================================ -* Board Support Package (BSP) for the Calculator example -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -#include "qpc.h" -#include "bsp.h" - -#include "safe_std.h" /* portable "safe" / facilities */ -#include /* for exit() */ - -#define DISP_WIDTH 15 - -/* helper macros to "stringify" values */ -#define VAL(x) #x -#define STRINGIFY(x) VAL(x) - -static char l_display[DISP_WIDTH + 1]; /* the calculator display */ -static uint32_t l_len; /* number of displayed characters */ - -/*..........................................................................*/ -void BSP_clear(void) { - memset(l_display, ' ', DISP_WIDTH - 1); - l_display[DISP_WIDTH - 1] = '0'; - l_display[DISP_WIDTH] = '\0'; - l_len = 0; -} -/*..........................................................................*/ -void BSP_insert(uint8_t keyId) { - if (l_len == 0U) { - l_display[DISP_WIDTH - 1] = (char)keyId; - ++l_len; - } - else if (l_len < (DISP_WIDTH - 1)) { - MEMMOVE_S(&l_display[0], DISP_WIDTH, &l_display[1], DISP_WIDTH - 1); - l_display[DISP_WIDTH - 1] = (char)keyId; - ++l_len; - } -} -/*..........................................................................*/ -void BSP_display(float64_t value) { - SNPRINTF_S(l_display, Q_DIM(l_display), - "%" STRINGIFY(DISP_WIDTH) ".6g", value); -} -/*..........................................................................*/ -void BSP_display_error(char const *err) { - STRNCPY_S(l_display, DISP_WIDTH, err); -} -/*..........................................................................*/ -void BSP_negate(void) { - BSP_clear(); - l_display[DISP_WIDTH - 2] = '-'; -} -/*..........................................................................*/ -void BSP_show_display(void) { - PRINTF_S("\n[%" STRINGIFY(DISP_WIDTH) "s] ", l_display); -} -/*..........................................................................*/ -void BSP_exit(void) { - PRINTF_S("\n%s\n", "Bye! Bye!"); - fflush(stdout); - QF_onCleanup(); - exit(0); -} -/*..........................................................................*/ -float64_t BSP_get_value(void) { - return strtod(l_display, (char **)0); -} -/*..........................................................................*/ -void BSP_message(char const *msg) { - PRINTF_S("%s", msg); -} - -/*..........................................................................*/ -void QF_onStartup(void) { - QF_consoleSetup(); -} -/*..........................................................................*/ -void QF_onCleanup(void) { - QF_consoleCleanup(); -} -/*..........................................................................*/ -void QF_onClockTick(void) { -} - -/*..........................................................................*/ -/* this function is used by the QP embedded systems-friendly assertions */ -Q_NORETURN Q_onAssert(char const * const module, int_t const loc) { - FPRINTF_S(stderr, "Assertion failed in %s:%d", module, loc); - QF_onCleanup(); - exit(-1); -} diff --git a/examples/workstation/calc1_sub/bsp.h b/examples/workstation/calc1_sub/bsp.h deleted file mode 100644 index d23d13f5..00000000 --- a/examples/workstation/calc1_sub/bsp.h +++ /dev/null @@ -1,39 +0,0 @@ -/*============================================================================ -* Board Support Package (BSP) for the Calculator example -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -#ifndef BSP_H -#define BSP_H - -void BSP_clear(void); -void BSP_negate(void); -void BSP_insert(uint8_t keyId); -float64_t BSP_get_value(void); -void BSP_display(float64_t value); -void BSP_display_error(char const *err); -void BSP_exit(void); - -void BSP_show_display(void); -void BSP_message(char const *msg); - -#endif /* BSP_H */ diff --git a/examples/workstation/calc1_sub/calc1_sub.h b/examples/workstation/calc1_sub/calc1_sub.h deleted file mode 100644 index 549daf04..00000000 --- a/examples/workstation/calc1_sub/calc1_sub.h +++ /dev/null @@ -1,65 +0,0 @@ -/*$file${.::calc1_sub.h} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* -* Model: calc1_sub.qm -* File: ${.::calc1_sub.h} -* -* This code has been generated by QM 5.2.4 . -* DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. -* -* SPDX-License-Identifier: GPL-3.0-or-later -* -* This generated code is open source software: you can redistribute it under -* the terms of the GNU General Public License as published by the Free -* Software Foundation. -* -* This code is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -* more details. -* -* NOTE: -* Alternatively, this generated code may be distributed under the terms -* of Quantum Leaps commercial licenses, which expressly supersede the GNU -* General Public License and are specifically designed for licensees -* interested in retaining the proprietary status of their code. -* -* Contact information: -* -* -*/ -/*$endhead${.::calc1_sub.h} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -#ifndef CALC1_SUB_H -#define CALC1_SUB_H - -enum CalcSignals { - C_SIG = Q_USER_SIG, - CE_SIG, - DIGIT_0_SIG, - DIGIT_1_9_SIG, - POINT_SIG, - OPER_SIG, - EQUALS_SIG, - OFF_SIG -}; - -/*$declare${Events::CalcEvt} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${Events::CalcEvt} .......................................................*/ -typedef struct { -/* protected: */ - QEvt super; - -/* public: */ - uint8_t key_code; -} CalcEvt; -/*$enddecl${Events::CalcEvt} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*$declare${SMs::Calc_ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${SMs::Calc_ctor} ........................................................*/ -void Calc_ctor(void); -/*$enddecl${SMs::Calc_ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ - -extern QHsm * const the_calc; /* "opaque" pointer to calculator HSM */ - -#endif /* CALC1_SUB_H */ - diff --git a/examples/workstation/calc1_sub/main.c b/examples/workstation/calc1_sub/main.c deleted file mode 100644 index 6681ba08..00000000 --- a/examples/workstation/calc1_sub/main.c +++ /dev/null @@ -1,134 +0,0 @@ -/***************************************************************************** -* Product: calc1_sub Example -* Last updated for version 6.9.1 -* Last updated on 2020-09-11 -* -* Q u a n t u m L e a P s -* ------------------------ -* Modern Embedded Software -* -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* -* -*****************************************************************************/ -#include "qpc.h" -#include "bsp.h" -#include "calc1_sub.h" - -#include "safe_std.h" /* portable "safe" / facilities */ - -Q_DEFINE_THIS_FILE - -/*..........................................................................*/ -int main(void) { - - QF_init(); - QF_onStartup(); - - PRINTF_S("Calculator example, QP version: %s\n" - "Press '0' .. '9' to enter a digit\n" - "Press '.' to enter the decimal point\n" - "Press '+' to add\n" - "Press '-' to subtract or negate a number\n" - "Press '*' to multiply\n" - "Press '/' to divide\n" - "Press '=' or to get the result\n" - "Press 'c' or 'C' to Cancel\n" - "Press 'e' or 'E' to Cancel Entry\n" - "Press to quit.\n\n", - QP_VERSION_STR); - - Calc_ctor(); /* explicitly instantiate the calculator object */ - QHSM_INIT(the_calc, (void *)0, 0U); /* trigger initial transition */ - - for (;;) { /* event loop */ - CalcEvt e; /* Calculator event */ - - BSP_show_display(); /* show the display */ - - PRINTF_S("%s"," : "); - fflush(stdout); - e.key_code = (uint8_t)QF_consoleWaitForKey(); - PRINTF_S("%c ", (e.key_code >= ' ') ? e.key_code : 'X'); - - switch (e.key_code) { - case 'c': /* intentionally fall through */ - case 'C': { - e.super.sig = C_SIG; - break; - } - case 'e': /* intentionally fall through */ - case 'E': { - e.super.sig = CE_SIG; - break; - } - case '0': { - e.super.sig = DIGIT_0_SIG; - break; - } - case '1': /* intentionally fall through */ - case '2': /* intentionally fall through */ - case '3': /* intentionally fall through */ - case '4': /* intentionally fall through */ - case '5': /* intentionally fall through */ - case '6': /* intentionally fall through */ - case '7': /* intentionally fall through */ - case '8': /* intentionally fall through */ - case '9': { - e.super.sig = DIGIT_1_9_SIG; - break; - } - case '.': { - e.super.sig = POINT_SIG; - break; - } - case '+': /* intentionally fall through */ - case '-': /* intentionally fall through */ - case '*': /* intentionally fall through */ - case '/': { - e.super.sig = OPER_SIG; - break; - } - case '=': /* intentionally fall through */ - case '\r': { /* Enter key */ - e.super.sig = EQUALS_SIG; - break; - } - case '\33': { /* ESC key */ - e.super.sig = OFF_SIG; - break; - } - default: { - e.super.sig = 0; /* invalid event */ - break; - } - } - - if (e.super.sig != 0) { /* valid event generated? */ - QHSM_DISPATCH(the_calc, &e.super, 0U); /* dispatch event */ - } - } - - QF_onCleanup(); - return 0; -} diff --git a/examples/workstation/calc2/bsp.c b/examples/workstation/calc2/bsp.c deleted file mode 100644 index 54d3f3bc..00000000 --- a/examples/workstation/calc2/bsp.c +++ /dev/null @@ -1,120 +0,0 @@ -/***************************************************************************** -* Product: Board Support Package (BSP) for the Calculator example -* Last updated for version 6.9.0 -* Last updated on 2020-06-24 -* -* Q u a n t u m L e a P s -* ------------------------ -* Modern Embedded Software -* -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* -* -*****************************************************************************/ -#include "qpc.h" -#include "bsp.h" - -#include "safe_std.h" /* portable "safe" / facilities */ -#include /* for exit() */ - -#define DISP_WIDTH 15 - -/* helper macros to "stringify" values */ -#define VAL(x) #x -#define STRINGIFY(x) VAL(x) - -static char l_display[DISP_WIDTH + 1]; /* the calculator display */ -static int l_len; /* number of displayed characters */ - -/*..........................................................................*/ -void BSP_clear(void) { - memset(l_display, ' ', DISP_WIDTH - 1); - l_display[DISP_WIDTH - 1] = '0'; - l_display[DISP_WIDTH] = '\0'; - l_len = 0; -} -/*..........................................................................*/ -void BSP_insert(int keyId) { - if (l_len == 0) { - l_display[DISP_WIDTH - 1] = (char)keyId; - ++l_len; - } - else if (l_len < (DISP_WIDTH - 1)) { - MEMMOVE_S(&l_display[0], DISP_WIDTH, &l_display[1], DISP_WIDTH - 1); - l_display[DISP_WIDTH - 1] = (char)keyId; - ++l_len; - } -} -/*..........................................................................*/ -void BSP_display(double value) { - SNPRINTF_S(l_display, Q_DIM(l_display), - "%" STRINGIFY(DISP_WIDTH) ".6g", value); -} -/*..........................................................................*/ -void BSP_display_error(char const *err) { - STRNCPY_S(l_display, DISP_WIDTH, err); -} -/*..........................................................................*/ -void BSP_negate(void) { - BSP_clear(); - l_display[DISP_WIDTH - 2] = '-'; -} -/*..........................................................................*/ -void BSP_show_display(void) { - PRINTF_S("\n[%" STRINGIFY(DISP_WIDTH) "s] ", l_display); -} -/*..........................................................................*/ -void BSP_exit(void) { - PRINTF_S("\n%s\n", "Bye! Bye!"); - fflush(stdout); - QF_onCleanup(); - exit(0); -} -/*..........................................................................*/ -double BSP_get_value(void) { - return strtod(l_display, (char **)0); -} -/*..........................................................................*/ -void BSP_message(char const *msg) { - PRINTF_S("%s", msg); -} - -/*..........................................................................*/ -void QF_onStartup(void) { - QF_consoleSetup(); -} -/*..........................................................................*/ -void QF_onCleanup(void) { - QF_consoleCleanup(); -} -/*..........................................................................*/ -void QF_onClockTick(void) { -} - -/*..........................................................................*/ -/* this function is used by the QP embedded systems-friendly assertions */ -Q_NORETURN Q_onAssert(char const * const module, int_t const loc) { - FPRINTF_S(stderr, "Assertion failed in %s:%d", module, loc); - QF_onCleanup(); - exit(-1); -} diff --git a/examples/workstation/calc2/bsp.h b/examples/workstation/calc2/bsp.h deleted file mode 100644 index 7b9e469a..00000000 --- a/examples/workstation/calc2/bsp.h +++ /dev/null @@ -1,48 +0,0 @@ -/***************************************************************************** -* Product: Board Support Package (BSP) for the Calculator example -* Last updated for version 6.5.0 -* Last updated on 2019-03-20 -* -* Q u a n t u m L e a P s -* ------------------------ -* Modern Embedded Software -* -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* -* -*****************************************************************************/ -#ifndef BSP_H -#define BSP_H - -void BSP_clear(void); -void BSP_negate(void); -void BSP_insert(int keyId); -double BSP_get_value(void); -void BSP_display(double value); -void BSP_display_error(char const *err); -void BSP_exit(void); - -void BSP_show_display(void); -void BSP_message(char const *msg); - -#endif /* BSP_H */ diff --git a/examples/workstation/calc2/calc2.h b/examples/workstation/calc2/calc2.h deleted file mode 100644 index 8c0fa25e..00000000 --- a/examples/workstation/calc2/calc2.h +++ /dev/null @@ -1,65 +0,0 @@ -/*$file${.::calc2.h} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* -* Model: calc2.qm -* File: ${.::calc2.h} -* -* This code has been generated by QM 5.2.4 . -* DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. -* -* SPDX-License-Identifier: GPL-3.0-or-later -* -* This generated code is open source software: you can redistribute it under -* the terms of the GNU General Public License as published by the Free -* Software Foundation. -* -* This code is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -* more details. -* -* NOTE: -* Alternatively, this generated code may be distributed under the terms -* of Quantum Leaps commercial licenses, which expressly supersede the GNU -* General Public License and are specifically designed for licensees -* interested in retaining the proprietary status of their code. -* -* Contact information: -* -* -*/ -/*$endhead${.::calc2.h} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -#ifndef CALC2_H -#define CALC2_H - -enum CalcSignals { - C_SIG = Q_USER_SIG, - CE_SIG, - DIGIT_0_SIG, - DIGIT_1_9_SIG, - POINT_SIG, - OPER_SIG, - EQUALS_SIG, - OFF_SIG -}; - -/*$declare${Events::CalcEvt} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${Events::CalcEvt} .......................................................*/ -typedef struct { -/* protected: */ - QEvt super; - -/* public: */ - uint8_t key_code; -} CalcEvt; -/*$enddecl${Events::CalcEvt} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*$declare${SMs::Calc_ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${SMs::Calc_ctor} ........................................................*/ -void Calc_ctor(void); -/*$enddecl${SMs::Calc_ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ - -extern QHsm * const the_calc; /* "opaque" pointer to calculator HSM */ - -#endif /* CALC2_H */ - diff --git a/examples/workstation/calc2/main.c b/examples/workstation/calc2/main.c deleted file mode 100644 index e57bf4d3..00000000 --- a/examples/workstation/calc2/main.c +++ /dev/null @@ -1,134 +0,0 @@ -/***************************************************************************** -* Product: calc2 Example -* Last updated for version 6.9.3 -* Last updated on 2021-03-18 -* -* Q u a n t u m L e a P s -* ------------------------ -* Modern Embedded Software -* -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* -* -*****************************************************************************/ -#include "qpc.h" -#include "bsp.h" -#include "calc2.h" - -#include "safe_std.h" /* portable "safe" / facilities */ - -Q_DEFINE_THIS_FILE - -/*..........................................................................*/ -int main() { - - QF_init(); - QF_onStartup(); - - PRINTF_S("Calculator example, QP version: %s\n" - "Press '0' .. '9' to enter a digit\n" - "Press '.' to enter the decimal point\n" - "Press '+' to add\n" - "Press '-' to subtract or negate a number\n" - "Press '*' to multiply\n" - "Press '/' to divide\n" - "Press '=' or to get the result\n" - "Press 'c' or 'C' to Cancel\n" - "Press 'e' or 'E' to Cancel Entry\n" - "Press to quit.\n\n", - QP_VERSION_STR); - - Calc_ctor(); /* explicitly instantiate the calculator object */ - QHSM_INIT(the_calc, (void *)0, 0U); /* trigger initial transition */ - - for (;;) { /* event loop */ - CalcEvt e; /* Calculator event */ - - BSP_show_display(); /* show the display */ - - PRINTF_S("%s"," : "); - fflush(stdout); - e.key_code = (uint8_t)QF_consoleWaitForKey(); - PRINTF_S("%c ", (e.key_code >= ' ') ? e.key_code : 'X'); - - switch (e.key_code) { - case 'c': /* intentionally fall through */ - case 'C': { - e.super.sig = C_SIG; - break; - } - case 'e': /* intentionally fall through */ - case 'E': { - e.super.sig = CE_SIG; - break; - } - case '0': { - e.super.sig = DIGIT_0_SIG; - break; - } - case '1': /* intentionally fall through */ - case '2': /* intentionally fall through */ - case '3': /* intentionally fall through */ - case '4': /* intentionally fall through */ - case '5': /* intentionally fall through */ - case '6': /* intentionally fall through */ - case '7': /* intentionally fall through */ - case '8': /* intentionally fall through */ - case '9': { - e.super.sig = DIGIT_1_9_SIG; - break; - } - case '.': { - e.super.sig = POINT_SIG; - break; - } - case '+': /* intentionally fall through */ - case '-': /* intentionally fall through */ - case '*': /* intentionally fall through */ - case '/': { - e.super.sig = OPER_SIG; - break; - } - case '=': /* intentionally fall through */ - case '\r': { /* Enter key */ - e.super.sig = EQUALS_SIG; - break; - } - case '\33': { /* ESC key */ - e.super.sig = OFF_SIG; - break; - } - default: { - e.super.sig = 0; /* invalid event */ - break; - } - } - - if (e.super.sig != 0) { /* valid event generated? */ - QHSM_DISPATCH(the_calc, &e.super, 0U); /* dispatch event */ - } - } - - QF_onCleanup(); - return 0; -} diff --git a/examples/workstation/comp/alarm.c b/examples/workstation/comp/alarm.c deleted file mode 100644 index daa60d3c..00000000 --- a/examples/workstation/comp/alarm.c +++ /dev/null @@ -1,159 +0,0 @@ -/*$file${.::alarm.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* -* Model: comp.qm -* File: ${.::alarm.c} -* -* This code has been generated by QM 5.2.4 . -* DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. -* -* SPDX-License-Identifier: GPL-3.0-or-later -* -* This generated code is open source software: you can redistribute it under -* the terms of the GNU General Public License as published by the Free -* Software Foundation. -* -* This code is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -* more details. -* -* NOTE: -* Alternatively, this generated code may be distributed under the terms -* of Quantum Leaps commercial licenses, which expressly supersede the GNU -* General Public License and are specifically designed for licensees -* interested in retaining the proprietary status of their code. -* -* Contact information: -* -* -*/ -/*$endhead${.::alarm.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -#include "qpc.h" -#include "bsp.h" -#include "alarm.h" -#include "clock.h" - -//Q_DEFINE_THIS_FILE - -/* Alarm component --------------------*/ -/*$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* Check for the minimum required QP version */ -#if (QP_VERSION < 700U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) -#error qpc version 7.0.0 or higher required -#endif -/*$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ - -/*$define${Components::Alarm} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${Components::Alarm} .....................................................*/ - -/*${Components::Alarm::ctor} ...............................................*/ -void Alarm_ctor(Alarm * const me) { - QHsm_ctor(&me->super, Q_STATE_CAST(&Alarm_initial)); -} - -/*${Components::Alarm::SM} .................................................*/ -QState Alarm_initial(Alarm * const me, void const * const par) { - /*${Components::Alarm::SM::initial} */ - me->alarm_time = 12U*60U; - (void)par; /* unused parameter */ - return Q_TRAN(&Alarm_off); -} - -/*${Components::Alarm::SM::off} ............................................*/ -QState Alarm_off(Alarm * const me, QEvt const * const e) { - QState status_; - switch (e->sig) { - /*${Components::Alarm::SM::off} */ - case Q_ENTRY_SIG: { - /* while in the off state, the alarm is kept in decimal format */ - me->alarm_time = (me->alarm_time/60)*100 + me->alarm_time%60; - BSP_showTime24H("*** Alarm OFF ", me->alarm_time, 100U); - status_ = Q_HANDLED(); - break; - } - /*${Components::Alarm::SM::off} */ - case Q_EXIT_SIG: { - /* upon exit, the alarm is converted to binary format */ - me->alarm_time = (me->alarm_time/100U)*60U + me->alarm_time%100U; - status_ = Q_HANDLED(); - break; - } - /*${Components::Alarm::SM::off::ALARM_ON} */ - case ALARM_ON_SIG: { - /*${Components::Alarm::SM::off::ALARM_ON::[alarminrange?]} */ - if ((me->alarm_time / 100U < 24U) - && (me->alarm_time % 100U < 60U)) - { - status_ = Q_TRAN(&Alarm_on); - } - /*${Components::Alarm::SM::off::ALARM_ON::[else]} */ - else { - me->alarm_time = 0U; - BSP_showTime24H("*** Alarm reset", me->alarm_time, 100U); - status_ = Q_HANDLED(); - } - break; - } - /*${Components::Alarm::SM::off::ALARM_SET} */ - case ALARM_SET_SIG: { - /* while setting, the alarm is kept in decimal format */ - me->alarm_time = (10U * me->alarm_time - + ((SetEvt const *)e)->digit) % 10000U; - BSP_showTime24H("*** Alarm reset ", me->alarm_time, 100U); - status_ = Q_HANDLED(); - break; - } - default: { - status_ = Q_SUPER(&QHsm_top); - break; - } - } - return status_; -} - -/*${Components::Alarm::SM::on} .............................................*/ -QState Alarm_on(Alarm * const me, QEvt const * const e) { - QState status_; - switch (e->sig) { - /*${Components::Alarm::SM::on} */ - case Q_ENTRY_SIG: { - BSP_showTime24H("*** Alarm ON ", me->alarm_time, 60U); - status_ = Q_HANDLED(); - break; - } - /*${Components::Alarm::SM::on::ALARM_OFF} */ - case ALARM_OFF_SIG: { - status_ = Q_TRAN(&Alarm_off); - break; - } - /*${Components::Alarm::SM::on::ALARM_SET} */ - case ALARM_SET_SIG: { - BSP_showMsg("*** Cannot set Alarm when it is ON"); - status_ = Q_HANDLED(); - break; - } - /*${Components::Alarm::SM::on::TIME} */ - case TIME_SIG: { - /*${Components::Alarm::SM::on::TIME::[Q_EVT_CAST(TimeEvt)->current_ti~} */ - if (Q_EVT_CAST(TimeEvt)->current_time == me->alarm_time) { - BSP_showMsg("ALARM!!!"); - - /* asynchronously post the event to the container AO */ - QACTIVE_POST(APP_alarmClock, Q_NEW(QEvt, ALARM_SIG), me); - status_ = Q_HANDLED(); - } - else { - status_ = Q_UNHANDLED(); - } - break; - } - default: { - status_ = Q_SUPER(&QHsm_top); - break; - } - } - return status_; -} -/*$enddef${Components::Alarm} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ - diff --git a/examples/workstation/comp/alarm.h b/examples/workstation/comp/alarm.h deleted file mode 100644 index 0b6c4b2e..00000000 --- a/examples/workstation/comp/alarm.h +++ /dev/null @@ -1,59 +0,0 @@ -/*$file${.::alarm.h} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* -* Model: comp.qm -* File: ${.::alarm.h} -* -* This code has been generated by QM 5.2.4 . -* DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. -* -* SPDX-License-Identifier: GPL-3.0-or-later -* -* This generated code is open source software: you can redistribute it under -* the terms of the GNU General Public License as published by the Free -* Software Foundation. -* -* This code is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -* more details. -* -* NOTE: -* Alternatively, this generated code may be distributed under the terms -* of Quantum Leaps commercial licenses, which expressly supersede the GNU -* General Public License and are specifically designed for licensees -* interested in retaining the proprietary status of their code. -* -* Contact information: -* -* -*/ -/*$endhead${.::alarm.h} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -#ifndef ALARM_H -#define ALARM_H - -/*$declare${Components::Alarm} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${Components::Alarm} .....................................................*/ -typedef struct { -/* protected: */ - QHsm super; - -/* private: */ - uint32_t alarm_time; -} Alarm; - -/* public: */ -void Alarm_ctor(Alarm * const me); - -/* protected: */ -QState Alarm_initial(Alarm * const me, void const * const par); -QState Alarm_off(Alarm * const me, QEvt const * const e); -QState Alarm_on(Alarm * const me, QEvt const * const e); -/*$enddecl${Components::Alarm} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ - -/*$declare${Components::Alarm::ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -void Alarm_ctor(Alarm * const me); -/*$enddecl${Components::Alarm::ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ - -#endif /* ALARM_H */ - diff --git a/examples/workstation/comp/bsp.c b/examples/workstation/comp/bsp.c deleted file mode 100644 index 8a291c28..00000000 --- a/examples/workstation/comp/bsp.c +++ /dev/null @@ -1,140 +0,0 @@ -/***************************************************************************** -* Product: Console-based BSP -* Last Updated for Version: 6.3.6 -* Date of the Last Update: 2018-10-14 -* -* Q u a n t u m L e a P s -* ------------------------ -* Modern Embedded Software -* -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* -* -*****************************************************************************/ -#include "qpc.h" -#include "clock.h" -#include "bsp.h" - -#include "safe_std.h" /* portable "safe" / facilities */ -#include /* for exit() */ - -//Q_DEFINE_THIS_FILE - -/*..........................................................................*/ -void BSP_init(int argc, char *argv[]) { - (void)argc; /* unused parameter */ - (void)argv; /* unused parameter */ -} -/*..........................................................................*/ -void BSP_showMsg(char const *str) { - PRINTF_S("%s\n", str); - fflush(stdout); -} -/*..........................................................................*/ -void BSP_showTime24H(char const *str, uint32_t time, uint32_t base) { - PRINTF_S("%s, %02d:%02d\n", str, (int)(time / base), (int)(time % base)); - fflush(stdout); -} -/*..........................................................................*/ -void BSP_showTime12H(char const *str, uint32_t time, uint32_t base) { - uint32_t h = time / base; - - PRINTF_S("%s %02d:%02d %s\n", str, (h % 12) ? (h % 12) : 12, - time % base, (h / 12) ? "PM" : "AM"); - fflush(stdout); -} -/*..........................................................................*/ -void QF_onStartup(void) { - QF_setTickRate(BSP_TICKS_PER_SEC, 30); /* set the desired tick rate */ - QF_consoleSetup(); -} -/*..........................................................................*/ -void QF_onCleanup(void) { - PRINTF_S("\n%s\n", "Bye! Bye!"); - QF_consoleCleanup(); -} -/*..........................................................................*/ -void QF_onClockTick(void) { - QTIMEEVT_TICK_X(0U, &l_clock_tick); /* perform the QF clock tick processing */ - int key = QF_consoleGetKey(); - if (key != 0) { /* any key pressed? */ - BSP_onKeyboardInput((uint8_t)key); - } -} -/*..........................................................................*/ -void BSP_onKeyboardInput(uint8_t key) { - switch (key) { - case 'o': { /* 'o': Alarm on event? */ - QACTIVE_POST(APP_alarmClock, - Q_NEW(QEvt, ALARM_ON_SIG), (void *)0); - break; - } - case 'f': { /* 'f': Alarm off event? */ - QACTIVE_POST(APP_alarmClock, - Q_NEW(QEvt, ALARM_OFF_SIG), (void *)0); - break; - } - case '1': /* '1' */ - case '2': /* '2' */ - case '3': /* '3' */ - case '4': /* '4' */ - case '5': /* '5' */ - case '6': /* '6' */ - case '7': /* '7' */ - case '8': /* '8' */ - case '9': { /* '9' */ - SetEvt *e = Q_NEW(SetEvt, ALARM_SET_SIG); - e->digit = (uint8_t)(key - '0'); - QACTIVE_POST(APP_alarmClock, (QEvt *)e, (void *)0); - break; - } - case '0': { /* '0' */ - SetEvt *e = Q_NEW(SetEvt, ALARM_SET_SIG); - e->digit = 0; - QACTIVE_POST(APP_alarmClock, (QEvt *)e, (void *)0); - break; - } - case 'a': { /* 'a': Clock 12H event? */ - QACTIVE_POST(APP_alarmClock, - Q_NEW(QEvt, CLOCK_12H_SIG), (void *)0); - break; - } - case 'b': { /* 'b': Clock 24H event? */ - QACTIVE_POST(APP_alarmClock, - Q_NEW(QEvt, CLOCK_24H_SIG), (void *)0); - break; - } - case '\33': { /* ESC pressed? */ - QACTIVE_POST(APP_alarmClock, - Q_NEW(QEvt, TERMINATE_SIG), (void *)0); - break; - } - } -} - -/*..........................................................................*/ -Q_NORETURN Q_onAssert(char const * const file, int_t const line) { - FPRINTF_S(stderr, "Assertion failed in %s, line %d", file, line); - exit(-1); -} - diff --git a/examples/workstation/comp/bsp.h b/examples/workstation/comp/bsp.h deleted file mode 100644 index 0a59bcf3..00000000 --- a/examples/workstation/comp/bsp.h +++ /dev/null @@ -1,46 +0,0 @@ -/***************************************************************************** -* Product: Console-based BSP, MinGW -* Last Updated for Version: 5.3.1 -* Date of the Last Update: 2014-10-15 -* -* Q u a n t u m L e a P s -* --------------------------- -* innovating embedded systems -* -* Copyright (C) 2005 Quantum Leaps, LLC. www.state-machine.com. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* Web: -* -*****************************************************************************/ -#ifndef BSP_H -#define BSP_H - -void BSP_init(int argc, char *argv[]); -void BSP_onKeyboardInput(uint8_t key); /* process the keyboard scan code */ - -#define BSP_TICKS_PER_SEC 100U - -void BSP_showMsg(char const *str); -void BSP_showTime12H(char const *str, uint32_t time, uint32_t base); -void BSP_showTime24H(char const *str, uint32_t time, uint32_t base); - -#endif /* BSP_H */ diff --git a/examples/workstation/comp/clock.c b/examples/workstation/comp/clock.c deleted file mode 100644 index 47fb829d..00000000 --- a/examples/workstation/comp/clock.c +++ /dev/null @@ -1,261 +0,0 @@ -/*$file${.::clock.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* -* Model: comp.qm -* File: ${.::clock.c} -* -* This code has been generated by QM 5.2.4 . -* DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. -* -* SPDX-License-Identifier: GPL-3.0-or-later -* -* This generated code is open source software: you can redistribute it under -* the terms of the GNU General Public License as published by the Free -* Software Foundation. -* -* This code is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -* more details. -* -* NOTE: -* Alternatively, this generated code may be distributed under the terms -* of Quantum Leaps commercial licenses, which expressly supersede the GNU -* General Public License and are specifically designed for licensees -* interested in retaining the proprietary status of their code. -* -* Contact information: -* -* -*/ -/*$endhead${.::clock.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -#include "qpc.h" -#include "bsp.h" -#include "alarm.h" -#include "clock.h" - -#include "safe_std.h" /* portable "safe" / facilities */ - -Q_DEFINE_THIS_FILE - -/* Active object class -----------------------------------------------------*/ -/*$declare${Components::AlarmClock} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${Components::AlarmClock} ................................................*/ -typedef struct { -/* protected: */ - QActive super; - -/* private: */ - uint32_t current_time; - Alarm alarm; - -/* public: */ - QTimeEvt timeEvt; -} AlarmClock; - -/* protected: */ -static QState AlarmClock_initial(AlarmClock * const me, void const * const par); -static QState AlarmClock_timekeeping(AlarmClock * const me, QEvt const * const e); -static QState AlarmClock_mode24h(AlarmClock * const me, QEvt const * const e); -static QState AlarmClock_mode12h(AlarmClock * const me, QEvt const * const e); -static QState AlarmClock_final(AlarmClock * const me, QEvt const * const e); -/*$enddecl${Components::AlarmClock} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ - -/* Local objects -----------------------------------------------------------*/ -static AlarmClock l_alarmClock; /* the single inst of the AO */ - -/* Global-scope objects ----------------------------------------------------*/ -/*$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* Check for the minimum required QP version */ -#if (QP_VERSION < 700U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) -#error qpc version 7.0.0 or higher required -#endif -/*$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ - -/*$define${Components::APP_alarmClock} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${Components::APP_alarmClock} ............................................*/ -QActive * const APP_alarmClock = &l_alarmClock.super; -/*$enddef${Components::APP_alarmClock} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ - -/*$define${Components::AlarmClock_ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${Components::AlarmClock_ctor} ...........................................*/ -void AlarmClock_ctor(void) { - AlarmClock * const me = &l_alarmClock; - - QActive_ctor(&me->super, Q_STATE_CAST(&AlarmClock_initial)); - Alarm_ctor(&me->alarm); /* orthogonal component ctor */ - - /* private time event ctor */ - QTimeEvt_ctorX(&me->timeEvt, &me->super, TICK_SIG, 0U); -} -/*$enddef${Components::AlarmClock_ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ - -/*..........................................................................*/ -/*$define${Components::AlarmClock} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${Components::AlarmClock} ................................................*/ - -/*${Components::AlarmClock::SM} ............................................*/ -static QState AlarmClock_initial(AlarmClock * const me, void const * const par) { - /*${Components::AlarmClock::SM::initial} */ - (void)par; /* unused parameter */ - me->current_time = 0U; - - /* (!) trigger the initial transition in the component */ - QHSM_INIT((QHsm *)&me->alarm, (void *)0, me->super.prio); - return Q_TRAN(&AlarmClock_timekeeping); -} - -/*${Components::AlarmClock::SM::timekeeping} ...............................*/ -static QState AlarmClock_timekeeping(AlarmClock * const me, QEvt const * const e) { - QState status_; - switch (e->sig) { - /*${Components::AlarmClock::SM::timekeeping} */ - case Q_ENTRY_SIG: { - /* periodic timeout every second */ - QTimeEvt_armX(&me->timeEvt, BSP_TICKS_PER_SEC, - BSP_TICKS_PER_SEC); - status_ = Q_HANDLED(); - break; - } - /*${Components::AlarmClock::SM::timekeeping} */ - case Q_EXIT_SIG: { - QTimeEvt_disarm(&me->timeEvt); - status_ = Q_HANDLED(); - break; - } - /*${Components::AlarmClock::SM::timekeeping::initial} */ - case Q_INIT_SIG: { - status_ = Q_TRAN(&AlarmClock_mode24h); - break; - } - /*${Components::AlarmClock::SM::timekeeping::CLOCK_24H} */ - case CLOCK_24H_SIG: { - status_ = Q_TRAN(&AlarmClock_mode24h); - break; - } - /*${Components::AlarmClock::SM::timekeeping::CLOCK_12H} */ - case CLOCK_12H_SIG: { - status_ = Q_TRAN(&AlarmClock_mode12h); - break; - } - /*${Components::AlarmClock::SM::timekeeping::ALARM} */ - case ALARM_SIG: { - BSP_showMsg("Wake up!!!"); - status_ = Q_HANDLED(); - break; - } - /*${Components::AlarmClock::SM::timekeeping::ALARM_SET, ALARM_ON, ALARM_OFF} */ - case ALARM_SET_SIG: /* intentionally fall through */ - case ALARM_ON_SIG: /* intentionally fall through */ - case ALARM_OFF_SIG: { - /* (!) synchronously dispatch to the orthogonal component */ - QHSM_DISPATCH((QHsm *)&me->alarm, e, me->super.prio); - status_ = Q_HANDLED(); - break; - } - /*${Components::AlarmClock::SM::timekeeping::TERMINATE} */ - case TERMINATE_SIG: { - BSP_showMsg("--> final"); - status_ = Q_TRAN(&AlarmClock_final); - break; - } - default: { - status_ = Q_SUPER(&QHsm_top); - break; - } - } - return status_; -} - -/*${Components::AlarmClock::SM::timekeeping::mode24h} ......................*/ -static QState AlarmClock_mode24h(AlarmClock * const me, QEvt const * const e) { - QState status_; - switch (e->sig) { - /*${Components::AlarmClock::SM::timekeeping::mode24h} */ - case Q_ENTRY_SIG: { - BSP_showMsg("*** 24-hour mode"); - status_ = Q_HANDLED(); - break; - } - /*${Components::AlarmClock::SM::timekeeping::mode24h::TICK} */ - case TICK_SIG: { - TimeEvt pe; /* temporary synchronous event for the component */ - - /* roll over in 24-hr mode? */ - if (++me->current_time == 24U*60U) { - me->current_time = 0U; - } - BSP_showTime24H("", me->current_time, 60U); - pe.super.sig = TIME_SIG; - pe.current_time = me->current_time; - - /* (!) synchronously dispatch to the orthogonal component */ - QHSM_DISPATCH(&me->alarm.super, &pe.super, me->super.prio); - status_ = Q_HANDLED(); - break; - } - default: { - status_ = Q_SUPER(&AlarmClock_timekeeping); - break; - } - } - return status_; -} - -/*${Components::AlarmClock::SM::timekeeping::mode12h} ......................*/ -static QState AlarmClock_mode12h(AlarmClock * const me, QEvt const * const e) { - QState status_; - switch (e->sig) { - /*${Components::AlarmClock::SM::timekeeping::mode12h} */ - case Q_ENTRY_SIG: { - BSP_showMsg("*** 12-hour mode"); - status_ = Q_HANDLED(); - break; - } - /*${Components::AlarmClock::SM::timekeeping::mode12h::TICK} */ - case TICK_SIG: { - TimeEvt pe; /* temporary synchronous event for the component */ - - /* roll over in 12-hr mode? */ - if (++me->current_time == 12U*60U) { - me->current_time = 0U; - } - BSP_showTime12H("", me->current_time, 60U); - pe.super.sig = TIME_SIG; - pe.current_time = me->current_time; - - /* (!) synchronously dispatch to the orthogonal component */ - QHSM_DISPATCH(&me->alarm.super, &pe.super, me->super.prio); - status_ = Q_HANDLED(); - break; - } - default: { - status_ = Q_SUPER(&AlarmClock_timekeeping); - break; - } - } - return status_; -} - -/*${Components::AlarmClock::SM::final} .....................................*/ -static QState AlarmClock_final(AlarmClock * const me, QEvt const * const e) { - QState status_; - switch (e->sig) { - /*${Components::AlarmClock::SM::final} */ - case Q_ENTRY_SIG: { - QF_stop(); /* terminate the application */ - status_ = Q_HANDLED(); - break; - } - default: { - status_ = Q_SUPER(&QHsm_top); - break; - } - } - return status_; -} -/*$enddef${Components::AlarmClock} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ - diff --git a/examples/workstation/comp/clock.h b/examples/workstation/comp/clock.h deleted file mode 100644 index 6ec4438f..00000000 --- a/examples/workstation/comp/clock.h +++ /dev/null @@ -1,81 +0,0 @@ -/*$file${.::clock.h} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* -* Model: comp.qm -* File: ${.::clock.h} -* -* This code has been generated by QM 5.2.4 . -* DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. -* -* SPDX-License-Identifier: GPL-3.0-or-later -* -* This generated code is open source software: you can redistribute it under -* the terms of the GNU General Public License as published by the Free -* Software Foundation. -* -* This code is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -* more details. -* -* NOTE: -* Alternatively, this generated code may be distributed under the terms -* of Quantum Leaps commercial licenses, which expressly supersede the GNU -* General Public License and are specifically designed for licensees -* interested in retaining the proprietary status of their code. -* -* Contact information: -* -* -*/ -/*$endhead${.::clock.h} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -#ifndef CLOCK_H -#define CLOCK_H - -enum AlarmClockSignals { - TICK_SIG = Q_USER_SIG, /* time tick event */ - ALARM_SET_SIG, /* set the alarm */ - ALARM_ON_SIG, /* turn the alarm on */ - ALARM_OFF_SIG, /* turn the alarm off */ - ALARM_SIG, /* alarm event from Alarm component to AlarmClock container */ - CLOCK_12H_SIG, /* set the clock in 12H mode */ - CLOCK_24H_SIG, /* set the clock in 24H mode */ - TIME_SIG, /* time event sent to Alarm (contains current time) */ - TERMINATE_SIG /* terminate the application */ -}; - -/*$declare${Events::SetEvt} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${Events::SetEvt} ........................................................*/ -typedef struct { -/* protected: */ - QEvt super; - -/* public: */ - uint8_t digit; -} SetEvt; -/*$enddecl${Events::SetEvt} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*$declare${Events::TimeEvt} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${Events::TimeEvt} .......................................................*/ -typedef struct { -/* protected: */ - QEvt super; - -/* public: */ - uint32_t current_time; -} TimeEvt; -/*$enddecl${Events::TimeEvt} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ - -/*$declare${Components::APP_alarmClock} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${Components::APP_alarmClock} ............................................*/ -extern QActive * const APP_alarmClock; -/*$enddecl${Components::APP_alarmClock} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*$declare${Components::AlarmClock_ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${Components::AlarmClock_ctor} ...........................................*/ -void AlarmClock_ctor(void); -/*$enddecl${Components::AlarmClock_ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ - -#endif /* CLOCK_H */ - diff --git a/examples/workstation/comp/main.c b/examples/workstation/comp/main.c deleted file mode 100644 index b4bbd950..00000000 --- a/examples/workstation/comp/main.c +++ /dev/null @@ -1,73 +0,0 @@ -/***************************************************************************** -* Product: "Orthogonal Component" example, Console based -* Last updated for version 6.4.0 -* Last updated on 2019-02-08 -* -* Q u a n t u m L e a P s -* ------------------------ -* Modern Embedded Software -* -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* -* -*****************************************************************************/ -#include "qpc.h" -#include "alarm.h" -#include "clock.h" -#include "bsp.h" - -#include "safe_std.h" /* portable "safe" / facilities */ - -Q_DEFINE_THIS_FILE - -/*..........................................................................*/ -int main(int argc, char *argv[]) { - static QEvt const *l_alarmClockQSto[10]; /* queue storage for AlarmClock */ - static QF_MPOOL_EL(TimeEvt) l_smlPoolSto[10]; /* storage for small pool */ - - PRINTF_S("Orthogonal Component pattern\nQP version: %s\n" - "Press 'o' to turn the Alarm ON\n" - "Press 'f' to turn the Alarm OFF\n" - "Press '0'..'9' to set the Alarm time\n" - "Press 'a' to set the Clock in 12-hour mode\n" - "Press 'b' to set the Clock in 24-hour mode\n" - "Press ESC to quit...\n", - QP_VERSION_STR); - - BSP_init(argc, argv); /* initialize the BSP */ - - QF_init(); /* initialize the framework and the underlying RT kernel */ - - /* publish-subscribe not used, no call to QF_psInit() */ - - /* initialize event pools... */ - QF_poolInit(l_smlPoolSto, sizeof(l_smlPoolSto), sizeof(l_smlPoolSto[0])); - - /* instantiate and start the active objects... */ - AlarmClock_ctor(); - QACTIVE_START(APP_alarmClock, 1U, - l_alarmClockQSto, Q_DIM(l_alarmClockQSto), - (void *)0, 0U, (QEvt *)0); - - return QF_run(); /* run the QF application */ -} diff --git a/examples/workstation/defer/bsp.c b/examples/workstation/defer/bsp.c deleted file mode 100644 index 6b68e5d9..00000000 --- a/examples/workstation/defer/bsp.c +++ /dev/null @@ -1,112 +0,0 @@ -/***************************************************************************** -* Product: Console-based BSP -* Last Updated for Version: 6.9.1 -* Date of the Last Update: 2020-09-21 -* -* Q u a n t u m L e a P s -* ------------------------ -* Modern Embedded Software -* -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* -* -*****************************************************************************/ -#include "qpc.h" -#include "bsp.h" - -#include "safe_std.h" /* portable "safe" / facilities */ -#include /* for exit() */ - -Q_DEFINE_THIS_FILE - -#ifdef Q_SPY -static uint8_t const l_QF_onClockTick = 0; -#endif - -/*..........................................................................*/ -void BSP_init(int argc, char *argv[]) { - (void)argc; - (void)argv; - Q_ALLEGE(QS_INIT(argc > 1 ? argv[1] : (void *)0)); - - QS_OBJ_DICTIONARY(&l_QF_onClockTick); - - // setup the QS filters... - QS_GLB_FILTER(QS_ALL_RECORDS); - QS_GLB_FILTER(-QS_QF_TICK); -} -/*..........................................................................*/ -void QF_onStartup(void) { - QF_setTickRate(BSP_TICKS_PER_SEC, 30); /* set the desired tick rate */ - QF_consoleSetup(); -} -/*..........................................................................*/ -void QF_onCleanup(void) { - PRINTF_S("\n%s\n", "Bye! Bye!"); - QF_consoleCleanup(); -} -/*..........................................................................*/ -void QF_onClockTick(void) { - int key; - QTIMEEVT_TICK_X(0U, &l_QF_onClockTick); /* perform QF clock tick processing */ - - QS_RX_INPUT(); /* handle the QS-RX input */ - QS_OUTPUT(); /* handle the QS output */ - - key = QF_consoleGetKey(); - if (key != 0) { /* any key pressed? */ - BSP_onKeyboardInput(key); - } -} -/*--------------------------------------------------------------------------*/ -#ifdef Q_SPY /* define QS callbacks */ - -/*..........................................................................*/ -/*! callback function to execute user commands */ -void QS_onCommand(uint8_t cmdId, - uint32_t param1, uint32_t param2, uint32_t param3) -{ - switch (cmdId) { - case 0U: { - break; - } - default: - break; - } - - /* unused parameters */ - (void)param1; - (void)param2; - (void)param3; -} - -#endif /* Q_SPY */ -/*--------------------------------------------------------------------------*/ - -/*..........................................................................*/ -Q_NORETURN Q_onAssert(char const * const file, int_t const line) { - FPRINTF_S(stderr, "Assertion failed in %s, line %d", file, line); - QF_onCleanup(); - exit(-1); -} - diff --git a/examples/workstation/defer/bsp.h b/examples/workstation/defer/bsp.h deleted file mode 100644 index 678eefe8..00000000 --- a/examples/workstation/defer/bsp.h +++ /dev/null @@ -1,42 +0,0 @@ -/***************************************************************************** -* Product: Console-based BSP -* Last updated for version 5.4.2 -* Last updated on 2015-06-03 -* -* Q u a n t u m L e a P s -* --------------------------- -* innovating embedded systems -* -* Copyright (C) 2005 Quantum Leaps, www.state-machine.com. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* Web: www.state-machine.com -* -*****************************************************************************/ -#ifndef BSP_H -#define BSP_H - -#define BSP_TICKS_PER_SEC 100U - -void BSP_init(int argc, char *argv[]); -void BSP_onKeyboardInput(uint8_t key); /* process the keyboard scan code */ - -#endif /* BSP_H */ diff --git a/examples/workstation/defer/qspy200822_125414.bin b/examples/workstation/defer/qspy200822_125414.bin deleted file mode 100644 index ad5a7015..00000000 Binary files a/examples/workstation/defer/qspy200822_125414.bin and /dev/null differ diff --git a/examples/workstation/dpp-comp/bsp.c b/examples/workstation/dpp-comp/bsp.c deleted file mode 100644 index 6943086f..00000000 --- a/examples/workstation/dpp-comp/bsp.c +++ /dev/null @@ -1,191 +0,0 @@ -/***************************************************************************** -* Product: DPP example (console) -* Last Updated for Version: 7.2.0 -* Date of the Last Update: 2022-12-22 -* -* Q u a n t u m L e a P s -* ------------------------ -* Modern Embedded Software -* -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* -* -*****************************************************************************/ -#include "qpc.h" -#include "dpp.h" -#include "bsp.h" - -#include "safe_std.h" /* portable "safe" / facilities */ -#include /* for exit() */ - -Q_DEFINE_THIS_FILE - -/* local variables ---------------------------------------------------------*/ -static uint32_t l_rnd; /* random seed */ - -#ifdef Q_SPY - enum { - PHILO_STAT = QS_USER - }; - - /* QSpy source IDs */ - static QSpyId const l_clock_tick = { 0U }; -#endif - -/*..........................................................................*/ -void BSP_init(int argc, char *argv[]) { - (void)argc; - (void)argv; - - PRINTF_S("Dining Philosophers Problem example" - "\nQP %s\n" - "Press 'p' to pause\n" - "Press 's' to serve\n" - "Press ESC to quit...\n", - QP_VERSION_STR); - - BSP_randomSeed(1234U); - - Q_ALLEGE(QS_INIT((argc > 1) ? argv[1] : (void *)0)); - - QS_OBJ_DICTIONARY(&l_clock_tick); /* must be called *after* QF_init() */ - QS_USR_DICTIONARY(PHILO_STAT); - - /* global signals */ - QS_SIG_DICTIONARY(DONE_SIG, (void *)0); - QS_SIG_DICTIONARY(EAT_SIG, (void *)0); - QS_SIG_DICTIONARY(PAUSE_SIG, (void *)0); - QS_SIG_DICTIONARY(SERVE_SIG, (void *)0); - QS_SIG_DICTIONARY(TEST_SIG, (void *)0); - QS_SIG_DICTIONARY(HUNGRY_SIG, (void *)0); - QS_SIG_DICTIONARY(HUNGRY_SIG, (void *)0); - QS_SIG_DICTIONARY(TIMEOUT_SIG, (void *)0); - - /* setup the QS filters... */ - QS_GLB_FILTER(QS_ALL_RECORDS); - QS_LOC_FILTER(QS_ALL_IDS); - QS_GLB_FILTER(-QS_QF_TICK); -} -/*..........................................................................*/ -void BSP_terminate(int16_t result) { - (void)result; - QF_stop(); /* stop the main "ticker thread" */ -} -/*..........................................................................*/ -void BSP_displayPhilStat(uint8_t n, char const *stat) { - PRINTF_S("Philosopher %2d is %s\n", (int)n, stat); - - /* application-specific record */ - QS_BEGIN_ID(PHILO_STAT, AO_Table->prio) - QS_U8(1, n); /* Philosopher number */ - QS_STR(stat); /* Philosopher status */ - QS_END() -} -/*..........................................................................*/ -void BSP_displayPaused(uint8_t paused) { - PRINTF_S("Paused is %s\n", paused ? "ON" : "OFF"); -} -/*..........................................................................*/ -uint32_t BSP_random(void) { /* a very cheap pseudo-random-number generator */ - /* "Super-Duper" Linear Congruential Generator (LCG) - * LCG(2^32, 3*7*11*13*23, 0, seed) - */ - l_rnd = l_rnd * (3U*7U*11U*13U*23U); - return l_rnd >> 8; -} -/*..........................................................................*/ -void BSP_randomSeed(uint32_t seed) { - l_rnd = seed; -} - -/****************************************************************************/ -/*..........................................................................*/ -void QF_onStartup(void) { - QF_consoleSetup(); - QF_setTickRate(BSP_TICKS_PER_SEC, 50); /* desired tick rate/ticker-prio */ -} -/*..........................................................................*/ -void QF_onCleanup(void) { - PRINTF_S("\n%s\n", "Bye! Bye!"); - QF_consoleCleanup(); -} -/*..........................................................................*/ -void QF_onClockTick(void) { - QTIMEEVT_TICK_X(0U, &l_clock_tick); /* perform the QF clock tick processing */ - - QS_RX_INPUT(); /* handle the QS-RX input */ - QS_OUTPUT(); /* handle the QS output */ - - switch (QF_consoleGetKey()) { - case '\33': { /* see if the ESC key pressed */ - BSP_terminate(0); - break; - } - case 'p': { - QACTIVE_PUBLISH(Q_NEW(QEvt, PAUSE_SIG), &l_clock_tick); - break; - } - case 's': { - QACTIVE_PUBLISH(Q_NEW(QEvt, SERVE_SIG), &l_clock_tick); - break; - } - default: { - break; - } - } -} - -/*--------------------------------------------------------------------------*/ -#ifdef Q_SPY /* define QS callbacks */ - -/*..........................................................................*/ -/*! callback function to execute user commands */ -void QS_onCommand(uint8_t cmdId, - uint32_t param1, uint32_t param2, uint32_t param3) -{ - switch (cmdId) { - case 0U: { - break; - } - default: - break; - } - - /* unused parameters */ - (void)param1; - (void)param2; - (void)param3; -} - -#endif /* Q_SPY */ -/*--------------------------------------------------------------------------*/ - -/*..........................................................................*/ -Q_NORETURN Q_onAssert(char const * const module, int_t const loc) { - QS_ASSERTION(module, loc, 10000U); /* report assertion to QS */ - FPRINTF_S(stderr, "Assertion failed in %s:%d", module, loc); - QF_onCleanup(); - QS_EXIT(); - exit(-1); -} - diff --git a/examples/workstation/dpp-comp/bsp.h b/examples/workstation/dpp-comp/bsp.h deleted file mode 100644 index ef10c819..00000000 --- a/examples/workstation/dpp-comp/bsp.h +++ /dev/null @@ -1,48 +0,0 @@ -/***************************************************************************** -* Product: DPP example -* Last Updated for Version: 4.5.02 -* Date of the Last Update: Jul 04, 2012 -* -* Q u a n t u m L e a P s -* --------------------------- -* innovating embedded systems -* -* Copyright (C)-2012 Quantum Leaps, LLC. All rights reserved. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* Quantum Leaps Web sites: http://www.quantum-leaps.com -* -* e-mail: info@quantum-leaps.com -*****************************************************************************/ -#ifndef BSP_H -#define BSP_H - -#define BSP_TICKS_PER_SEC 50U - -void BSP_init(int argc, char *argv[]); -void BSP_displayPaused(uint8_t paused); -void BSP_displayPhilStat(uint8_t n, char const *stat); -void BSP_terminate(int16_t result); - -void BSP_randomSeed(uint32_t seed); /* random seed */ -uint32_t BSP_random(void); /* pseudo-random generator */ - -#endif /* BSP_H */ diff --git a/examples/workstation/dpp-comp/dpp.h b/examples/workstation/dpp-comp/dpp.h deleted file mode 100644 index 1495abf8..00000000 --- a/examples/workstation/dpp-comp/dpp.h +++ /dev/null @@ -1,102 +0,0 @@ -/*$file${.::dpp.h} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* -* Model: dpp-comp.qm -* File: ${.::dpp.h} -* -* This code has been generated by QM 5.2.4 . -* DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. -* -* SPDX-License-Identifier: GPL-3.0-or-later -* -* This generated code is open source software: you can redistribute it under -* the terms of the GNU General Public License as published by the Free -* Software Foundation. -* -* This code is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -* more details. -* -* NOTE: -* Alternatively, this generated code may be distributed under the terms -* of Quantum Leaps commercial licenses, which expressly supersede the GNU -* General Public License and are specifically designed for licensees -* interested in retaining the proprietary status of their code. -* -* Contact information: -* -* -*/ -/*$endhead${.::dpp.h} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -#ifndef DPP_H -#define DPP_H - -enum DPPSignals { - EAT_SIG = Q_USER_SIG, /* published by Table to let a philosopher eat */ - DONE_SIG, /* published by Philosopher when done eating */ - PAUSE_SIG, /* published by BSP to pause serving forks */ - SERVE_SIG, /* published by BSP to serve re-start serving forks */ - TEST_SIG, /* published by BSP to test the application */ - MAX_PUB_SIG, /* the last published signal */ - - HUNGRY_SIG, /* posted direclty to Table from hungry Philo */ - TIMEOUT_SIG, /* used by Philosophers for time events */ - MAX_SIG /* the last signal */ -}; - -enum { - N_PHILO = 5 /* number of Philos */ -}; - -/*$declare${Cont::TableEvt} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${Cont::TableEvt} ........................................................*/ -typedef struct { -/* protected: */ - QEvt super; - -/* public: */ - uint8_t philoNum; -} TableEvt; -/*$enddecl${Cont::TableEvt} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*$declare${Cont::Table_ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${Cont::Table_ctor} ......................................................*/ -void Table_ctor(void); -/*$enddecl${Cont::Table_ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*$declare${Cont::AO_Table} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${Cont::AO_Table} ........................................................*/ -extern QActive * const AO_Table; -/*$enddecl${Cont::AO_Table} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ - -/*$declare${Comp::CompTimeEvt} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${Comp::CompTimeEvt} .....................................................*/ -typedef struct { -/* protected: */ - QTimeEvt super; - -/* public: */ - uint16_t compNum; -} CompTimeEvt; - -/* public: */ -void CompTimeEvt_ctor(CompTimeEvt * const me, - QActive * act, - uint16_t num, - enum_t const sig, - uint_fast8_t const tickRate); -/*$enddecl${Comp::CompTimeEvt} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*$declare${Comp::SM_Philo[N_PHILO]} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${Comp::SM_Philo[N_PHILO]} ...............................................*/ -extern QHsm * const SM_Philo[N_PHILO]; -/*$enddecl${Comp::SM_Philo[N_PHILO]} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*$declare${Comp::Philo_ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${Comp::Philo_ctor} ......................................................*/ -void Philo_ctor(uint8_t n); -/*$enddecl${Comp::Philo_ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ - -#endif /* DPP_H */ diff --git a/examples/workstation/dpp-comp/main.c b/examples/workstation/dpp-comp/main.c deleted file mode 100644 index b95ca5c0..00000000 --- a/examples/workstation/dpp-comp/main.c +++ /dev/null @@ -1,90 +0,0 @@ -/***************************************************************************** -* Product: DPP example for Windows -* Last updated for version 7.1.1 -* Last updated on 2022-09-22 -* -* Q u a n t u m L e a P s -* ------------------------ -* Modern Embedded Software -* -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* -* -*****************************************************************************/ -#include "qpc.h" -#include "dpp.h" -#include "bsp.h" - -Q_DEFINE_THIS_FILE - -/* "fudge factor" for Windows, see NOTE1 */ -enum { WIN_FUDGE_FACTOR = 10 }; - -/*..........................................................................*/ -int main(int argc, char *argv[]) { - static QEvt const *tableQueueSto[N_PHILO*WIN_FUDGE_FACTOR]; - static QSubscrList subscrSto[MAX_PUB_SIG]; - static QF_MPOOL_EL(TableEvt) smlPoolSto[2*N_PHILO*WIN_FUDGE_FACTOR]; - - Table_ctor(); /* instantiate the Table active object */ - - QF_init(); /* initialize the framework and the underlying RT kernel */ - BSP_init(argc, argv); /* initialize the Board Support Package */ - - /* initialize publish-subscribe... */ - QF_psInit(subscrSto, Q_DIM(subscrSto)); - - /* initialize event pools... */ - QF_poolInit(smlPoolSto, sizeof(smlPoolSto), sizeof(smlPoolSto[0])); - - QACTIVE_START(AO_Table, /* AO to start */ - 1U, /* QF-priority/preemption-thre. */ - tableQueueSto, /* event queue storage */ - Q_DIM(tableQueueSto), /* queue length [events] */ - (void *)0, /* stack storage (not used) */ - 0U, /* size of the stack [bytes] */ - (QEvt *)0); /* initialization event */ - - return QF_run(); /* run the QF application */ -} - -/***************************************************************************** -* NOTE1: -* Windows is not a deterministic real-time system, which means that the -* system can occasionally and unexpectedly "choke and freeze" for a number -* of seconds. The designers of Windows have dealt with these sort of issues -* by massively oversizing the resources available to the applications. For -* example, the default Windows GUI message queues size is 10,000 entries, -* which can dynamically grow to an even larger number. Also the stacks of -* Win32 threads can dynamically grow to several megabytes. -* -* In contrast, the event queues, event pools, and stack size inside the -* real-time embedded (RTE) systems can be (and must be) much smaller, -* because you typically can put an upper bound on the real-time behavior -* and the resulting delays. -* -* To be able to run the unmodified applications designed originally for -* RTE systems on Windows, and to reduce the odds of resource shortages in -* this case, the generous WIN_FUDGE_FACTOR is used to oversize the -* event queues and event pools. -*/ diff --git a/examples/workstation/dpp-comp/philo.c b/examples/workstation/dpp-comp/philo.c deleted file mode 100644 index 1ddf399f..00000000 --- a/examples/workstation/dpp-comp/philo.c +++ /dev/null @@ -1,225 +0,0 @@ -/*$file${.::philo.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* -* Model: dpp-comp.qm -* File: ${.::philo.c} -* -* This code has been generated by QM 5.2.4 . -* DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. -* -* SPDX-License-Identifier: GPL-3.0-or-later -* -* This generated code is open source software: you can redistribute it under -* the terms of the GNU General Public License as published by the Free -* Software Foundation. -* -* This code is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -* more details. -* -* NOTE: -* Alternatively, this generated code may be distributed under the terms -* of Quantum Leaps commercial licenses, which expressly supersede the GNU -* General Public License and are specifically designed for licensees -* interested in retaining the proprietary status of their code. -* -* Contact information: -* -* -*/ -/*$endhead${.::philo.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -#include "qpc.h" -#include "dpp.h" -#include "bsp.h" - -//Q_DEFINE_THIS_FILE - -/*$declare${Comp::Philo} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${Comp::Philo} ...........................................................*/ -typedef struct Philo { -/* protected: */ - QHsm super; - -/* public: */ - -/* private: */ - CompTimeEvt timeEvt; -} Philo; -extern Philo Philo_inst[N_PHILO]; - -/* protected: */ -static QState Philo_initial(Philo * const me, void const * const par); -static QState Philo_thinking(Philo * const me, QEvt const * const e); -static QState Philo_hungry(Philo * const me, QEvt const * const e); -static QState Philo_eating(Philo * const me, QEvt const * const e); -/*$enddecl${Comp::Philo} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ - -/* helper macros to provide a randomized think time for Philos */ -#define THINK_TIME \ - (QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + (BSP_TICKS_PER_SEC/2U)) -#define EAT_TIME \ - (QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + BSP_TICKS_PER_SEC) - -/* definition of the whole "Comp" package */ -/*$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* Check for the minimum required QP version */ -#if (QP_VERSION < 700U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) -#error qpc version 7.0.0 or higher required -#endif -/*$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ - -/*$define${Comp} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${Comp::CompTimeEvt} .....................................................*/ - -/*${Comp::CompTimeEvt::ctor} ...............................................*/ -void CompTimeEvt_ctor(CompTimeEvt * const me, - QActive * act, - uint16_t num, - enum_t const sig, - uint_fast8_t const tickRate) -{ - QTimeEvt_ctorX(&me->super, act, sig, tickRate); - me->compNum = num; -} - -/*${Comp::Philo} ...........................................................*/ -Philo Philo_inst[N_PHILO]; - -/*${Comp::Philo::SM} .......................................................*/ -static QState Philo_initial(Philo * const me, void const * const par) { - /*${Comp::Philo::SM::initial} */ - (void)par; /* unused parameter */ - - #ifdef Q_SPY - uint8_t n = (uint8_t)(me - &Philo_inst[0]); - QS_OBJ_ARR_DICTIONARY(&Philo_inst[n], n); - QS_OBJ_ARR_DICTIONARY(&Philo_inst[n].timeEvt, n); - #endif - - /* the following code outputs the "fun-dictionaries" only once for - * all Philo instances, as opposed to repeat them for every instance. - */ - static bool registered = false; - if (!registered) { - registered = true; - - QS_FUN_DICTIONARY(&Philo_initial); - QS_FUN_DICTIONARY(&Philo_thinking); - QS_FUN_DICTIONARY(&Philo_hungry); - QS_FUN_DICTIONARY(&Philo_eating); - } - return Q_TRAN(&Philo_thinking); -} - -/*${Comp::Philo::SM::thinking} .............................................*/ -static QState Philo_thinking(Philo * const me, QEvt const * const e) { - QState status_; - switch (e->sig) { - /*${Comp::Philo::SM::thinking} */ - case Q_ENTRY_SIG: { - QTimeEvt_armX(&me->timeEvt.super, THINK_TIME, 0U); - status_ = Q_HANDLED(); - break; - } - /*${Comp::Philo::SM::thinking} */ - case Q_EXIT_SIG: { - QTimeEvt_disarm(&me->timeEvt.super); - status_ = Q_HANDLED(); - break; - } - /*${Comp::Philo::SM::thinking::TIMEOUT} */ - case TIMEOUT_SIG: { - status_ = Q_TRAN(&Philo_hungry); - break; - } - /*${Comp::Philo::SM::thinking::TEST} */ - case TEST_SIG: { - status_ = Q_HANDLED(); - break; - } - default: { - status_ = Q_SUPER(&QHsm_top); - break; - } - } - return status_; -} - -/*${Comp::Philo::SM::hungry} ...............................................*/ -static QState Philo_hungry(Philo * const me, QEvt const * const e) { - QState status_; - switch (e->sig) { - /*${Comp::Philo::SM::hungry} */ - case Q_ENTRY_SIG: { - /* asynchronously post event to the Container */ - TableEvt *pe = Q_NEW(TableEvt, HUNGRY_SIG); - pe->philoNum = (uint8_t)(me - &Philo_inst[0]); - QACTIVE_POST_LIFO(AO_Table, &pe->super); - status_ = Q_HANDLED(); - break; - } - /*${Comp::Philo::SM::hungry::EAT} */ - case EAT_SIG: { - status_ = Q_TRAN(&Philo_eating); - break; - } - default: { - status_ = Q_SUPER(&QHsm_top); - break; - } - } - return status_; -} - -/*${Comp::Philo::SM::eating} ...............................................*/ -static QState Philo_eating(Philo * const me, QEvt const * const e) { - QState status_; - switch (e->sig) { - /*${Comp::Philo::SM::eating} */ - case Q_ENTRY_SIG: { - QTimeEvt_armX(&me->timeEvt.super, EAT_TIME, 0U); - status_ = Q_HANDLED(); - break; - } - /*${Comp::Philo::SM::eating} */ - case Q_EXIT_SIG: { - QTimeEvt_disarm(&me->timeEvt.super); - - /* asynchronously post event to the Container */ - TableEvt *pe = Q_NEW(TableEvt, DONE_SIG); - pe->philoNum = (uint8_t)(me - &Philo_inst[0]); - QACTIVE_POST_LIFO(AO_Table, &pe->super); - status_ = Q_HANDLED(); - break; - } - /*${Comp::Philo::SM::eating::TIMEOUT} */ - case TIMEOUT_SIG: { - status_ = Q_TRAN(&Philo_thinking); - break; - } - default: { - status_ = Q_SUPER(&QHsm_top); - break; - } - } - return status_; -} - -/*${Comp::SM_Philo[N_PHILO]} ...............................................*/ -QHsm * const SM_Philo[N_PHILO] = { /* opaque pointers to Philo instances */ - &Philo_inst[0].super, - &Philo_inst[1].super, - &Philo_inst[2].super, - &Philo_inst[3].super, - &Philo_inst[4].super -}; - -/*${Comp::Philo_ctor} ......................................................*/ -void Philo_ctor(uint8_t n) { - Philo *me = &Philo_inst[n]; - QHsm_ctor(&me->super, Q_STATE_CAST(&Philo_initial)); - CompTimeEvt_ctor(&me->timeEvt, AO_Table, n, TIMEOUT_SIG, 0U); -} -/*$enddef${Comp} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ diff --git a/examples/workstation/dpp-comp/table.c b/examples/workstation/dpp-comp/table.c deleted file mode 100644 index b7506b0e..00000000 --- a/examples/workstation/dpp-comp/table.c +++ /dev/null @@ -1,324 +0,0 @@ -/*$file${.::table.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* -* Model: dpp-comp.qm -* File: ${.::table.c} -* -* This code has been generated by QM 5.2.4 . -* DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. -* -* SPDX-License-Identifier: GPL-3.0-or-later -* -* This generated code is open source software: you can redistribute it under -* the terms of the GNU General Public License as published by the Free -* Software Foundation. -* -* This code is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -* more details. -* -* NOTE: -* Alternatively, this generated code may be distributed under the terms -* of Quantum Leaps commercial licenses, which expressly supersede the GNU -* General Public License and are specifically designed for licensees -* interested in retaining the proprietary status of their code. -* -* Contact information: -* -* -*/ -/*$endhead${.::table.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -#include "qpc.h" -#include "dpp.h" -#include "bsp.h" - -Q_DEFINE_THIS_FILE - -/*$declare${Cont::Table} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${Cont::Table} ...........................................................*/ -typedef struct Table { -/* protected: */ - QActive super; - -/* public: */ - -/* private: */ - uint8_t fork[N_PHILO]; - uint8_t isHungry[N_PHILO]; -} Table; -extern Table Table_inst; - -/* protected: */ -static QState Table_initial(Table * const me, void const * const par); -static QState Table_active(Table * const me, QEvt const * const e); -static QState Table_serving(Table * const me, QEvt const * const e); -static QState Table_paused(Table * const me, QEvt const * const e); -/*$enddecl${Cont::Table} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ - -#define RIGHT(n_) ((uint8_t)(((n_) + (N_PHILO - 1U)) % N_PHILO)) -#define LEFT(n_) ((uint8_t)(((n_) + 1U) % N_PHILO)) -#define FREE ((uint8_t)0) -#define USED ((uint8_t)1) - -/* definition of the whole "Cont" package */ -/*$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* Check for the minimum required QP version */ -#if (QP_VERSION < 700U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) -#error qpc version 7.0.0 or higher required -#endif -/*$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ - -/*$define${Cont} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${Cont::Table} ...........................................................*/ -Table Table_inst; - -/*${Cont::Table::SM} .......................................................*/ -static QState Table_initial(Table * const me, void const * const par) { - /*${Cont::Table::SM::initial} */ - (void)par; /* unused parameter */ - - QS_OBJ_DICTIONARY(&Table_inst); - - QActive_subscribe(&me->super, PAUSE_SIG); - QActive_subscribe(&me->super, SERVE_SIG); - QActive_subscribe(&me->super, TEST_SIG); - - for (uint8_t n = 0U; n < N_PHILO; ++n) { - me->fork[n] = FREE; - me->isHungry[n] = 0U; - - QHSM_INIT(SM_Philo[n], (void *)0, QS_AP_ID + n); - BSP_displayPhilStat(n, "thinking"); - } - - QS_FUN_DICTIONARY(&Table_active); - QS_FUN_DICTIONARY(&Table_serving); - QS_FUN_DICTIONARY(&Table_paused); - - return Q_TRAN(&Table_serving); -} - -/*${Cont::Table::SM::active} ...............................................*/ -static QState Table_active(Table * const me, QEvt const * const e) { - QState status_; - switch (e->sig) { - /*${Cont::Table::SM::active::TIMEOUT} */ - case TIMEOUT_SIG: { - uint16_t n = Q_EVT_CAST(CompTimeEvt)->compNum; - QHSM_DISPATCH(SM_Philo[n], e, QS_AP_ID + n); - status_ = Q_HANDLED(); - break; - } - /*${Cont::Table::SM::active::EAT} */ - case EAT_SIG: { - Q_ERROR(); - status_ = Q_HANDLED(); - break; - } - /*${Cont::Table::SM::active::TEST} */ - case TEST_SIG: { - status_ = Q_HANDLED(); - break; - } - default: { - status_ = Q_SUPER(&QHsm_top); - break; - } - } - return status_; -} - -/*${Cont::Table::SM::active::serving} ......................................*/ -static QState Table_serving(Table * const me, QEvt const * const e) { - QState status_; - switch (e->sig) { - /*${Cont::Table::SM::active::serving} */ - case Q_ENTRY_SIG: { - for (uint8_t n = 0U; n < N_PHILO; ++n) { /* give permissions to eat... */ - if ((me->isHungry[n] != 0U) - && (me->fork[LEFT(n)] == FREE) - && (me->fork[n] == FREE)) - { - me->fork[LEFT(n)] = USED; - me->fork[n] = USED; - - /* synchronoulsy dispatch EAT event to the Philo component */ - TableEvt evt; - evt.super.sig = EAT_SIG; - evt.philoNum = n; - QHSM_DISPATCH(SM_Philo[n], &evt.super, QS_AP_ID + n); - - me->isHungry[n] = 0U; - BSP_displayPhilStat(n, "eating "); - } - } - status_ = Q_HANDLED(); - break; - } - /*${Cont::Table::SM::active::serving::HUNGRY} */ - case HUNGRY_SIG: { - /* find the index of the Philo from the event */ - uint8_t n = Q_EVT_CAST(TableEvt)->philoNum; - /* philo ID must be in range and he must be not hungry */ - Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); - - BSP_displayPhilStat(n, "hungry "); - uint8_t m = LEFT(n); - /*${Cont::Table::SM::active::serving::HUNGRY::[bothfree]} */ - if ((me->fork[m] == FREE) && (me->fork[n] == FREE)) { - me->fork[m] = USED; - me->fork[n] = USED; - - /* synchronoulsy dispatch EAT event to the Philo component */ - TableEvt evt; - evt.super.sig = EAT_SIG; - evt.philoNum = n; - QHSM_DISPATCH(SM_Philo[n], &evt.super, QS_AP_ID + n); - BSP_displayPhilStat(n, "eating "); - status_ = Q_HANDLED(); - } - /*${Cont::Table::SM::active::serving::HUNGRY::[else]} */ - else { - me->isHungry[n] = 1U; - status_ = Q_HANDLED(); - } - break; - } - /*${Cont::Table::SM::active::serving::DONE} */ - case DONE_SIG: { - /* find the index of the Philo from the event */ - uint8_t n = Q_EVT_CAST(TableEvt)->philoNum; - /* philo ID must be in range and he must be not hungry */ - Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); - - BSP_displayPhilStat(n, "thinking"); - uint8_t m = LEFT(n); - /* both forks of Phil[n] must be used */ - Q_ASSERT((me->fork[n] == USED) && (me->fork[m] == USED)); - - me->fork[m] = FREE; - me->fork[n] = FREE; - m = RIGHT(n); /* check the right neighbor */ - - TableEvt evt; - if ((me->isHungry[m] != 0U) && (me->fork[m] == FREE)) { - me->fork[n] = USED; - me->fork[m] = USED; - me->isHungry[m] = 0U; - - /* synchronoulsy dispatch EAT event to the Philo component */ - evt.super.sig = EAT_SIG; - evt.philoNum = m; - QHSM_DISPATCH(SM_Philo[m], &evt.super, QS_AP_ID + m); - BSP_displayPhilStat(m, "eating "); - } - m = LEFT(n); /* check the left neighbor */ - n = LEFT(m); /* left fork of the left neighbor */ - if ((me->isHungry[m] != 0U) && (me->fork[n] == FREE)) { - me->fork[m] = USED; - me->fork[n] = USED; - me->isHungry[m] = 0U; - - /* synchronoulsy dispatch EAT event to the Philo component */ - evt.super.sig = EAT_SIG; - evt.philoNum = m; - QHSM_DISPATCH(SM_Philo[m], &evt.super, QS_AP_ID + m); - BSP_displayPhilStat(m, "eating "); - } - status_ = Q_HANDLED(); - break; - } - /*${Cont::Table::SM::active::serving::EAT} */ - case EAT_SIG: { - Q_ERROR(); - status_ = Q_HANDLED(); - break; - } - /*${Cont::Table::SM::active::serving::PAUSE} */ - case PAUSE_SIG: { - status_ = Q_TRAN(&Table_paused); - break; - } - default: { - status_ = Q_SUPER(&Table_active); - break; - } - } - return status_; -} - -/*${Cont::Table::SM::active::paused} .......................................*/ -static QState Table_paused(Table * const me, QEvt const * const e) { - QState status_; - switch (e->sig) { - /*${Cont::Table::SM::active::paused} */ - case Q_ENTRY_SIG: { - BSP_displayPaused(1U); - status_ = Q_HANDLED(); - break; - } - /*${Cont::Table::SM::active::paused} */ - case Q_EXIT_SIG: { - BSP_displayPaused(0U); - status_ = Q_HANDLED(); - break; - } - /*${Cont::Table::SM::active::paused::SERVE} */ - case SERVE_SIG: { - status_ = Q_TRAN(&Table_serving); - break; - } - /*${Cont::Table::SM::active::paused::HUNGRY} */ - case HUNGRY_SIG: { - /* find the index of the Philo from the event */ - uint8_t n = Q_EVT_CAST(TableEvt)->philoNum; - /* philo ID must be in range and he must be not hungry */ - Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); - - me->isHungry[n] = 1U; - BSP_displayPhilStat(n, "hungry "); - status_ = Q_HANDLED(); - break; - } - /*${Cont::Table::SM::active::paused::DONE} */ - case DONE_SIG: { - /* find the index of the Philo from the event */ - uint8_t n = Q_EVT_CAST(TableEvt)->philoNum; - /* philo ID must be in range and he must be not hungry */ - Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); - - BSP_displayPhilStat(n, "thinking"); - uint8_t m = LEFT(n); - /* both forks of Phil[n] must be used */ - Q_ASSERT((me->fork[n] == USED) && (me->fork[m] == USED)); - - me->fork[m] = FREE; - me->fork[n] = FREE; - status_ = Q_HANDLED(); - break; - } - default: { - status_ = Q_SUPER(&Table_active); - break; - } - } - return status_; -} - -/*${Cont::AO_Table} ........................................................*/ -QActive * const AO_Table = &Table_inst.super; /* opaque pointer */ - -/*${Cont::Table_ctor} ......................................................*/ -void Table_ctor(void) { - Table *me = &Table_inst; - QActive_ctor(&me->super, Q_STATE_CAST(&Table_initial)); - - for (uint8_t n = 0U; n < N_PHILO; ++n) { - me->fork[n] = FREE; - me->isHungry[n] = 0U; - Philo_ctor(n); /* create the Philo component */ - } -} -/*$enddef${Cont} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ diff --git a/examples/workstation/dpp-gui/README.txt b/examples/workstation/dpp-gui/README.txt deleted file mode 100644 index bda792fe..00000000 --- a/examples/workstation/dpp-gui/README.txt +++ /dev/null @@ -1,10 +0,0 @@ -The Win32 GUI emulation of the Dining Philosopers Problem (DPP) example -for the EFM32-SLSTK3401A board from Silicon Labs is now located in the -directory: - -examples\arm-cm\dpp_efm32-slstk3401a\win32-gui\ - - -This co-location of the Win32 emulation with the embedded code running -on the actual board demonstrates better the "dual targeting" development -approach. \ No newline at end of file diff --git a/examples/workstation/dpp/Makefile_clang b/examples/workstation/dpp/Makefile_clang deleted file mode 100644 index babf08ab..00000000 --- a/examples/workstation/dpp/Makefile_clang +++ /dev/null @@ -1,287 +0,0 @@ -############################################################################## -# Product: Makefile for QP/C for Windows and POSIX *HOSTS* -# Last updated for version 7.2.0 -# Last updated on 2022-11-13 -# -# Q u a n t u m L e a P s -# ------------------------ -# Modern Embedded Software -# -# Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -# -# This program is open source software: you can redistribute it and/or -# modify it under the terms of the GNU General Public License as published -# by the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# Alternatively, this program may be distributed and modified under the -# terms of Quantum Leaps commercial licenses, which expressly supersede -# the GNU General Public License and are specifically designed for -# licensees interested in retaining the proprietary status of their code. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . -# -# Contact information: -# -# -############################################################################## -# -# examples of invoking this Makefile: -# building configurations: Debug (default), Release, and Spy -# make -# make CONF=rel -# make CONF=spy -# make clean # cleanup the build -# make CONF=spy clean # cleanup the build -# -# NOTE: -# To use this Makefile on Windows, you will need the GNU make utility, which -# is included in the QTools collection for Windows, see: -# http://sourceforge.net/projects/qpc/files/QTools/ -# - -#----------------------------------------------------------------------------- -# project name: -# -PROJECT := dpp - -#----------------------------------------------------------------------------- -# project directories: -# - -# list of all source directories used by this project -VPATH := . \ - -# list of all include directories needed by this project -INCLUDES := -I. \ - -# location of the QP/C framework (if not provided in an env. variable) -ifeq ($(QPC),) -QPC := ../../.. -endif - -#----------------------------------------------------------------------------- -# project files: -# - -# C source files... -C_SRCS := \ - bsp.c \ - main.c \ - philo.c \ - table.c - -# C++ source files... -CPP_SRCS := - -LIB_DIRS := -LIBS := - -# defines... -# QP_API_VERSION controls the QP API compatibility; 9999 means the latest API -DEFINES := -DQP_API_VERSION=9999 - -ifeq (,$(CONF)) - CONF := dbg -endif - -#----------------------------------------------------------------------------- -# add QP/C framework: -# -C_SRCS += \ - qep_hsm.c \ - qep_msm.c \ - qf_act.c \ - qf_actq.c \ - qf_defer.c \ - qf_dyn.c \ - qf_mem.c \ - qf_ps.c \ - qf_qact.c \ - qf_qeq.c \ - qf_qmact.c \ - qf_time.c \ - qf_port.c - -QS_SRCS := \ - qs.c \ - qs_64bit.c \ - qs_rx.c \ - qs_fp.c \ - qs_port.c - -ifeq ($(OS),Windows_NT) - -# NOTE: -# For Windows hosts, you can choose: -# - the single-threaded QP/C port (win32-qv) or -# - the multithreaded QP/C port (win32). -# -QP_PORT_DIR := $(QPC)/ports/win32-qv -#QP_PORT_DIR := $(QPC)/ports/win32 -LIBS += -lws2_32 - -else - -# NOTE: -# For POSIX hosts (Linux, MacOS), you can choose: -# - the single-threaded QP/C port (win32-qv) or -# - the multithreaded QP/C port (win32). -# -QP_PORT_DIR := $(QPC)/ports/posix-qv -#QP_PORT_DIR := $(QPC)/ports/posix - -LIBS += -lpthread - -endif - -#============================================================================ -# Typically you should not need to change anything below this line - -VPATH += $(QPC)/src/qf $(QP_PORT_DIR) -INCLUDES += -I$(QPC)/include -I$(QP_PORT_DIR) - -#----------------------------------------------------------------------------- -# GNU toolset: -# -# NOTE: -# GNU toolset (MinGW) is included in the QTools collection for Windows, see: -# https://www.state-machine.com/qtools -# It is assumed that %QTOOLS%\bin directory is added to the PATH -# -CC := clang -CPP := clang -LINK := clang -v - -#----------------------------------------------------------------------------- -# basic utilities (depends on the OS this Makefile runs on): -# -ifeq ($(OS),Windows_NT) - MKDIR := mkdir - RM := rm - TARGET_EXT := .exe -else ifeq ($(OSTYPE),cygwin) - MKDIR := mkdir -p - RM := rm -f - TARGET_EXT := .exe -else - MKDIR := mkdir -p - RM := rm -f - TARGET_EXT := -endif - -#----------------------------------------------------------------------------- -# build configurations... - -ifeq (rel, $(CONF)) # Release configuration .................................. - -BIN_DIR := build_rel -# gcc options: -CFLAGS = -c -O3 -std=c11 -pedantic -Wall -Wextra -W \ - $(INCLUDES) $(DEFINES) -DNDEBUG - -CPPFLAGS = -c -O3 -std=c++11 -pedantic -Wall -Wextra \ - -fno-rtti -fno-exceptions \ - $(INCLUDES) $(DEFINES) -DNDEBUG - -else ifeq (spy, $(CONF)) # Spy configuration ................................ - -BIN_DIR := build_spy - -C_SRCS += $(QS_SRCS) -VPATH += $(QPC)/src/qs - -# gcc options: -CFLAGS = -c -g -O -std=c11 -pedantic -Wall -Wextra -W \ - $(INCLUDES) $(DEFINES) -DQ_SPY - -CPPFLAGS = -c -g -O -std=c++11 -pedantic -Wall -Wextra \ - -fno-rtti -fno-exceptions \ - $(INCLUDES) $(DEFINES) -DQ_SPY - -else # default Debug configuration ......................................... - -BIN_DIR := build - -# gcc options: -CFLAGS = -c -g -O -std=c11 -pedantic -Wall -Wextra -W \ - $(INCLUDES) $(DEFINES) - -CPPFLAGS = -c -g -O -std=c++11 -pedantic -Wall -Wextra \ - -fno-rtti -fno-exceptions \ - $(INCLUDES) $(DEFINES) - -endif # ..................................................................... - -#----------------------------------------------------------------------------- -C_OBJS := $(patsubst %.c,%.o, $(C_SRCS)) -CPP_OBJS := $(patsubst %.cpp,%.o, $(CPP_SRCS)) - -TARGET_EXE := $(BIN_DIR)/$(PROJECT)$(TARGET_EXT) -C_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(C_OBJS)) -C_DEPS_EXT := $(patsubst %.o,%.d, $(C_OBJS_EXT)) -CPP_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(CPP_OBJS)) -CPP_DEPS_EXT := $(patsubst %.o,%.d, $(CPP_OBJS_EXT)) - -#----------------------------------------------------------------------------- -# rules -# - -.PHONY: clean show - -all: $(TARGET_EXE) - -$(TARGET_EXE) : $(C_OBJS_EXT) $(CPP_OBJS_EXT) - $(CC) $(CFLAGS) $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o - $(LINK) $(LINKFLAGS) $(LIB_DIRS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) - -$(BIN_DIR)/%.d : %.c - $(CC) -MM -MT $(@:.d=.o) $(CFLAGS) $< > $@ - -$(BIN_DIR)/%.d : %.cpp - $(CPP) -MM -MT $(@:.d=.o) $(CPPFLAGS) $< > $@ - -$(BIN_DIR)/%.o : %.c - $(CC) $(CFLAGS) $< -o $@ - -$(BIN_DIR)/%.o : %.cpp - $(CPP) $(CPPFLAGS) $< -o $@ - -# create BIN_DIR and include dependencies only if needed -ifneq ($(MAKECMDGOALS),clean) - ifneq ($(MAKECMDGOALS),show) - ifneq ($(MAKECMDGOALS),debug) -ifeq ("$(wildcard $(BIN_DIR))","") -$(shell $(MKDIR) $(BIN_DIR)) -endif --include $(C_DEPS_EXT) $(CPP_DEPS_EXT) - endif - endif -endif - -clean : - -$(RM) $(BIN_DIR)/*.o \ - $(BIN_DIR)/*.d \ - $(TARGET_EXE) - -show : - @echo PROJECT = $(PROJECT) - @echo TARGET_EXE = $(TARGET_EXE) - @echo VPATH = $(VPATH) - @echo C_SRCS = $(C_SRCS) - @echo CPP_SRCS = $(CPP_SRCS) - @echo C_DEPS_EXT = $(C_DEPS_EXT) - @echo C_OBJS_EXT = $(C_OBJS_EXT) - @echo C_DEPS_EXT = $(C_DEPS_EXT) - @echo CPP_DEPS_EXT = $(CPP_DEPS_EXT) - @echo CPP_OBJS_EXT = $(CPP_OBJS_EXT) - @echo LIB_DIRS = $(LIB_DIRS) - @echo LIBS = $(LIBS) - @echo DEFINES = $(DEFINES) - diff --git a/examples/workstation/dpp/bsp.c b/examples/workstation/dpp/bsp.c deleted file mode 100644 index 7b8c7426..00000000 --- a/examples/workstation/dpp/bsp.c +++ /dev/null @@ -1,190 +0,0 @@ -/***************************************************************************** -* Product: DPP example (console) -* Last Updated for Version: 6.9.3 -* Date of the Last Update: 2021-03-02 -* -* Q u a n t u m L e a P s -* ------------------------ -* Modern Embedded Software -* -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* -* -*****************************************************************************/ -#include "qpc.h" -#include "dpp.h" -#include "bsp.h" - -#include "safe_std.h" /* portable "safe" / facilities */ -#include /* for exit() */ - -Q_DEFINE_THIS_FILE - -/* local variables ---------------------------------------------------------*/ -static uint32_t l_rnd; /* random seed */ - -#ifdef Q_SPY - enum { - PHILO_STAT = QS_USER - }; - - /* QSpy source IDs */ - static QSpyId const l_clock_tick = { QS_AP_ID }; -#endif - -/*..........................................................................*/ -void BSP_init(int argc, char *argv[]) { - (void)argc; - (void)argv; - - PRINTF_S("Dining Philosophers Problem example" - "\nQP %s\n" - "Press 'p' to pause\n" - "Press 's' to serve\n" - "Press ESC to quit...\n", - QP_VERSION_STR); - - BSP_randomSeed(1234U); - - Q_ALLEGE(QS_INIT((argc > 1) ? argv[1] : (void *)0)); - - /* global signals */ - QS_SIG_DICTIONARY(DONE_SIG, (void *)0); - QS_SIG_DICTIONARY(EAT_SIG, (void *)0); - QS_SIG_DICTIONARY(PAUSE_SIG, (void *)0); - QS_SIG_DICTIONARY(SERVE_SIG, (void *)0); - QS_SIG_DICTIONARY(TEST_SIG, (void *)0); - QS_SIG_DICTIONARY(HUNGRY_SIG, (void *)0); - QS_SIG_DICTIONARY(HUNGRY_SIG, (void *)0); - QS_SIG_DICTIONARY(TIMEOUT_SIG, (void *)0); - - QS_OBJ_DICTIONARY(&l_clock_tick); /* must be called *after* QF_init() */ - QS_USR_DICTIONARY(PHILO_STAT); - - /* setup the QS filters... */ - QS_GLB_FILTER(QS_ALL_RECORDS); - QS_GLB_FILTER(-QS_QF_TICK); -} -/*..........................................................................*/ -void BSP_terminate(int16_t result) { - (void)result; - QF_stop(); /* stop the main "ticker thread" */ -} -/*..........................................................................*/ -void BSP_displayPhilStat(uint8_t n, char const *stat) { - PRINTF_S("Philosopher %2d is %s\n", (int)n, stat); - - /* application-specific record */ - QS_BEGIN_ID(PHILO_STAT, AO_Philo[n]->prio) - QS_U8(1, n); /* Philosopher number */ - QS_STR(stat); /* Philosopher status */ - QS_END() -} -/*..........................................................................*/ -void BSP_displayPaused(uint8_t paused) { - PRINTF_S("Paused is %s\n", paused ? "ON" : "OFF"); -} -/*..........................................................................*/ -uint32_t BSP_random(void) { /* a very cheap pseudo-random-number generator */ - /* "Super-Duper" Linear Congruential Generator (LCG) - * LCG(2^32, 3*7*11*13*23, 0, seed) - */ - l_rnd = l_rnd * (3U*7U*11U*13U*23U); - return l_rnd >> 8; -} -/*..........................................................................*/ -void BSP_randomSeed(uint32_t seed) { - l_rnd = seed; -} - -/****************************************************************************/ -/*..........................................................................*/ -void QF_onStartup(void) { - QF_consoleSetup(); - QF_setTickRate(BSP_TICKS_PER_SEC, 50); /* desired tick rate/ticker-prio */ -} -/*..........................................................................*/ -void QF_onCleanup(void) { - PRINTF_S("\n%s\n", "Bye! Bye!"); - QF_consoleCleanup(); -} -/*..........................................................................*/ -void QF_onClockTick(void) { - QTIMEEVT_TICK_X(0U, &l_clock_tick); /* perform the QF clock tick processing */ - - QS_RX_INPUT(); /* handle the QS-RX input */ - QS_OUTPUT(); /* handle the QS output */ - - switch (QF_consoleGetKey()) { - case '\33': { /* see if the ESC key pressed */ - BSP_terminate(0); - break; - } - case 'p': { - QACTIVE_PUBLISH(Q_NEW(QEvt, PAUSE_SIG), &l_clock_tick); - break; - } - case 's': { - QACTIVE_PUBLISH(Q_NEW(QEvt, SERVE_SIG), &l_clock_tick); - break; - } - default: { - break; - } - } -} - -/*--------------------------------------------------------------------------*/ -#ifdef Q_SPY /* define QS callbacks */ - -/*..........................................................................*/ -/*! callback function to execute user commands */ -void QS_onCommand(uint8_t cmdId, - uint32_t param1, uint32_t param2, uint32_t param3) -{ - switch (cmdId) { - case 0U: { - break; - } - default: - break; - } - - /* unused parameters */ - (void)param1; - (void)param2; - (void)param3; -} - -#endif /* Q_SPY */ -/*--------------------------------------------------------------------------*/ - -/*..........................................................................*/ -Q_NORETURN Q_onAssert(char const * const module, int_t const loc) { - QS_ASSERTION(module, loc, 10000U); /* report assertion to QS */ - FPRINTF_S(stderr, "Assertion failed in %s:%d", module, loc); - QF_onCleanup(); - QS_EXIT(); - exit(-1); -} - diff --git a/examples/workstation/dpp/bsp.h b/examples/workstation/dpp/bsp.h deleted file mode 100644 index ef10c819..00000000 --- a/examples/workstation/dpp/bsp.h +++ /dev/null @@ -1,48 +0,0 @@ -/***************************************************************************** -* Product: DPP example -* Last Updated for Version: 4.5.02 -* Date of the Last Update: Jul 04, 2012 -* -* Q u a n t u m L e a P s -* --------------------------- -* innovating embedded systems -* -* Copyright (C)-2012 Quantum Leaps, LLC. All rights reserved. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* Quantum Leaps Web sites: http://www.quantum-leaps.com -* -* e-mail: info@quantum-leaps.com -*****************************************************************************/ -#ifndef BSP_H -#define BSP_H - -#define BSP_TICKS_PER_SEC 50U - -void BSP_init(int argc, char *argv[]); -void BSP_displayPaused(uint8_t paused); -void BSP_displayPhilStat(uint8_t n, char const *stat); -void BSP_terminate(int16_t result); - -void BSP_randomSeed(uint32_t seed); /* random seed */ -uint32_t BSP_random(void); /* pseudo-random generator */ - -#endif /* BSP_H */ diff --git a/examples/workstation/dpp/dpp.h b/examples/workstation/dpp/dpp.h deleted file mode 100644 index bbca41ff..00000000 --- a/examples/workstation/dpp/dpp.h +++ /dev/null @@ -1,85 +0,0 @@ -/*$file${.::dpp.h} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* -* Model: dpp.qm -* File: ${.::dpp.h} -* -* This code has been generated by QM 5.2.4 . -* DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. -* -* SPDX-License-Identifier: GPL-3.0-or-later -* -* This generated code is open source software: you can redistribute it under -* the terms of the GNU General Public License as published by the Free -* Software Foundation. -* -* This code is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -* more details. -* -* NOTE: -* Alternatively, this generated code may be distributed under the terms -* of Quantum Leaps commercial licenses, which expressly supersede the GNU -* General Public License and are specifically designed for licensees -* interested in retaining the proprietary status of their code. -* -* Contact information: -* -* -*/ -/*$endhead${.::dpp.h} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -#ifndef DPP_H -#define DPP_H - -enum DPPSignals { - EAT_SIG = Q_USER_SIG, /* published by Table to let a philosopher eat */ - DONE_SIG, /* published by Philosopher when done eating */ - PAUSE_SIG, /* published by BSP to pause serving forks */ - SERVE_SIG, /* published by BSP to serve re-start serving forks */ - TEST_SIG, /* published by BSP to test the application */ - MAX_PUB_SIG, /* the last published signal */ - - HUNGRY_SIG, /* posted direclty to Table from hungry Philo */ - TIMEOUT_SIG, /* used by Philosophers for time events */ - MAX_SIG /* the last signal */ -}; - -enum { - N_PHILO = 5 /* number of Philos */ -}; - -/*$declare${Shared} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${Shared::TableEvt} ......................................................*/ -typedef struct { -/* protected: */ - QEvt super; - -/* public: */ - uint8_t philoNum; -} TableEvt; - -/*${Shared::AO_Philo[N_PHILO]} .............................................*/ -/* opaque pointers to the Philo AOs */ -extern QActive * const AO_Philo[N_PHILO]; - -/*${Shared::AO_Table} ......................................................*/ -/* opaque pointer to the Table AO */ -extern QActive * const AO_Table; - -/*${Shared::Philo_ctor} ....................................................*/ -void Philo_ctor(uint8_t n); - -/*${Shared::Table_ctor} ....................................................*/ -void Table_ctor(void); -/*$enddecl${Shared} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ - -#ifdef QP_INC_QXK_H_ - void Test1_ctor(void); - extern QXThread * const XT_Test1; - void Test2_ctor(void); - extern QXThread * const XT_Test2; -#endif /* QP_INC_QXK_H_ */ - -#endif /* DPP_H */ - diff --git a/examples/workstation/dpp/dpp.qm b/examples/workstation/dpp/dpp.qm deleted file mode 100644 index 5cb89d69..00000000 --- a/examples/workstation/dpp/dpp.qm +++ /dev/null @@ -1,456 +0,0 @@ - - - Dining Philosopher Problem example - - - - - - - - - - - - /* opaque pointers to the Philo AOs */ - = { - &Philo_inst[0].super, - &Philo_inst[1].super, - &Philo_inst[2].super, - &Philo_inst[3].super, - &Philo_inst[4].super -}; - - - - /* opaque pointer to the Table AO */ - = &Table_inst.super; - - - - - - Philo *me = &Philo_inst[n]; -QActive_ctor(&me->super, Q_STATE_CAST(&Philo_initial)); -QTimeEvt_ctorX(&me->timeEvt, &me->super, TIMEOUT_SIG, 0U); - - - - Table *me = &Table_inst; - -QActive_ctor(&me->super, Q_STATE_CAST(&Table_initial)); - -for (uint8_t n = 0U; n < N_PHILO; ++n) { - me->fork[n] = FREE; - me->isHungry[n] = 0U; -} - - - - - - - - - - - - - - - (void)par; /* unused parameter */ - -#ifdef Q_SPY -uint8_t n = PHILO_ID(me); -QS_OBJ_ARR_DICTIONARY(&Philo_inst[n], n); -QS_OBJ_ARR_DICTIONARY(&Philo_inst[n].timeEvt, n); -#endif - -QActive_subscribe(&me->super, EAT_SIG); -QActive_subscribe(&me->super, TEST_SIG); - -/* the following code outputs the "fun-dictionaries" only once for -* all Philo instances, as opposed to repeat them for every instance. -*/ -static bool registered = false; -if (!registered) { - registered = true; - - QS_FUN_DICTIONARY(&Philo_initial); - QS_FUN_DICTIONARY(&Philo_thinking); - QS_FUN_DICTIONARY(&Philo_hungry); - QS_FUN_DICTIONARY(&Philo_eating); -} - - - - - - - QTimeEvt_armX(&me->timeEvt, THINK_TIME, 0U); - QTimeEvt_disarm(&me->timeEvt); - - - - - - - - - /* EAT or DONE must be for other Philos than this one */ -Q_ASSERT_ID(10, Q_EVT_CAST(TableEvt)->philoNum != PHILO_ID(me)); - - - - - - - - - - - - TableEvt *pe = Q_NEW(TableEvt, HUNGRY_SIG); -pe->philoNum = PHILO_ID(me); -QACTIVE_POST(AO_Table, &pe->super, me); - - - - - Q_EVT_CAST(TableEvt)->philoNum == PHILO_ID(me) - - - - - - - - - - - /* DONE must be for other Philos than this one */ -Q_ASSERT_ID(20, Q_EVT_CAST(TableEvt)->philoNum != PHILO_ID(me)); - - - - - - - - - - - QTimeEvt_armX(&me->timeEvt, EAT_TIME, 0U); - TableEvt *pe = Q_NEW(TableEvt, DONE_SIG); -pe->philoNum = PHILO_ID(me); -QACTIVE_PUBLISH(&pe->super, &me->super); -QTimeEvt_disarm(&me->timeEvt); - - - - - - - - - /* EAT or DONE must be for other Philos than this one */ -Q_ASSERT_ID(30, Q_EVT_CAST(TableEvt)->philoNum != PHILO_ID(me)); - - - - - - - - - - - - - - - - - The only static instance of the Table class (Singleton pattern) - - - - - - - - - - (void)par; /* unused parameter */ - -QS_OBJ_DICTIONARY(&Table_inst); - -QActive_subscribe(&me->super, DONE_SIG); -QActive_subscribe(&me->super, PAUSE_SIG); -QActive_subscribe(&me->super, SERVE_SIG); -QActive_subscribe(&me->super, TEST_SIG); - -for (uint8_t n = 0U; n < N_PHILO; ++n) { - me->fork[n] = FREE; - me->isHungry[n] = 0U; - BSP_displayPhilStat(n, "thinking"); -} - - - - - - - - - Q_ERROR_ID(60); - - - - - - - uint8_t n; -for (n = 0U; n < N_PHILO; ++n) { /* give permissions to eat... */ - if ((me->isHungry[n] != 0U) - && (me->fork[LEFT(n)] == FREE) - && (me->fork[n] == FREE)) - { - TableEvt *te; - - me->fork[LEFT(n)] = USED; - me->fork[n] = USED; - te = Q_NEW(TableEvt, EAT_SIG); - te->philoNum = n; - QACTIVE_PUBLISH(&te->super, &me->super); - me->isHungry[n] = 0U; - BSP_displayPhilStat(n, "eating "); - } -} - - - uint8_t n, m; - -n = Q_EVT_CAST(TableEvt)->philoNum; -/* phil ID must be in range and he must be not hungry */ -Q_ASSERT_ID(40, (n < N_PHILO) && (me->isHungry[n] == 0U)); - -BSP_displayPhilStat(n, "hungry "); -m = LEFT(n); - - - (me->fork[m] == FREE) && (me->fork[n] == FREE) - TableEvt *pe; -me->fork[m] = USED; -me->fork[n] = USED; -pe = Q_NEW(TableEvt, EAT_SIG); -pe->philoNum = n; -QACTIVE_PUBLISH(&pe->super, &me->super); -BSP_displayPhilStat(n, "eating "); - - - - - - - else - me->isHungry[n] = 1U; - - - - - - - - - - - uint8_t n, m; -TableEvt *pe; - -n = Q_EVT_CAST(TableEvt)->philoNum; -/* phil ID must be in range and he must be not hungry */ -Q_ASSERT_ID(50, (n < N_PHILO) && (me->isHungry[n] == 0U)); - -BSP_displayPhilStat(n, "thinking"); -m = LEFT(n); -/* both forks of Phil[n] must be used */ -Q_ASSERT_ID(51, (me->fork[n] == USED) && (me->fork[m] == USED)); - -me->fork[m] = FREE; -me->fork[n] = FREE; -m = RIGHT(n); /* check the right neighbor */ - -if ((me->isHungry[m] != 0U) && (me->fork[m] == FREE)) { - me->fork[n] = USED; - me->fork[m] = USED; - me->isHungry[m] = 0U; - pe = Q_NEW(TableEvt, EAT_SIG); - pe->philoNum = m; - QACTIVE_PUBLISH(&pe->super, &me->super); - BSP_displayPhilStat(m, "eating "); -} -m = LEFT(n); /* check the left neighbor */ -n = LEFT(m); /* left fork of the left neighbor */ -if ((me->isHungry[m] != 0U) && (me->fork[n] == FREE)) { - me->fork[m] = USED; - me->fork[n] = USED; - me->isHungry[m] = 0U; - pe = Q_NEW(TableEvt, EAT_SIG); - pe->philoNum = m; - QACTIVE_PUBLISH(&pe->super, &me->super); - BSP_displayPhilStat(m, "eating "); -} - - - - - - - - - - - - - - - - - BSP_displayPaused(1U); - BSP_displayPaused(0U); - - - - - - - - - uint8_t n = Q_EVT_CAST(TableEvt)->philoNum; -/* philo ID must be in range and he must be not hungry */ -Q_ASSERT_ID(60, (n < N_PHILO) && (me->isHungry[n] == 0U)); -me->isHungry[n] = 1U; -BSP_displayPhilStat(n, "hungry "); - - - - - - - uint8_t n, m; - -n = Q_EVT_CAST(TableEvt)->philoNum; -/* phil ID must be in range and he must be not hungry */ -Q_ASSERT_ID(70, (n < N_PHILO) && (me->isHungry[n] == 0U)); - -BSP_displayPhilStat(n, "thinking"); -m = LEFT(n); -/* both forks of Phil[n] must be used */ -Q_ASSERT_ID(71, (me->fork[n] == USED) && (me->fork[m] == USED)); - -me->fork[m] = FREE; -me->fork[n] = FREE; - - - - - - - - - - - - - - - - - - - - #ifndef DPP_H -#define DPP_H - -enum DPPSignals { - EAT_SIG = Q_USER_SIG, /* published by Table to let a philosopher eat */ - DONE_SIG, /* published by Philosopher when done eating */ - PAUSE_SIG, /* published by BSP to pause serving forks */ - SERVE_SIG, /* published by BSP to serve re-start serving forks */ - TEST_SIG, /* published by BSP to test the application */ - MAX_PUB_SIG, /* the last published signal */ - - HUNGRY_SIG, /* posted direclty to Table from hungry Philo */ - TIMEOUT_SIG, /* used by Philosophers for time events */ - MAX_SIG /* the last signal */ -}; - -enum { - N_PHILO = 5 /* number of Philos */ -}; - -$declare ${Shared} - -#ifdef QP_INC_QXK_H_ - void Test1_ctor(void); - extern QXThread * const XT_Test1; - void Test2_ctor(void); - extern QXThread * const XT_Test2; -#endif /* QP_INC_QXK_H_ */ - -#endif /* DPP_H */ - - - - - #include "qpc.h" -#include "dpp.h" -#include "bsp.h" - -Q_DEFINE_THIS_MODULE("philo") - -/* Active object class -----------------------------------------------------*/ -$declare ${AOs::Philo} - -/* helper macros to provide a randomized think time for Philos */ -#define THINK_TIME \ - (QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + (BSP_TICKS_PER_SEC/2U)) -#define EAT_TIME \ - (QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + BSP_TICKS_PER_SEC) - -/* helper macro to provide the ID of Philo "me_" */ -#define PHILO_ID(me_) ((uint8_t)((me_) - &Philo_inst[0])) - -/* Shared objects ----------------------------------------------------------*/ -$define ${Shared::AO_Philo[N_PHILO]} -$define ${Shared::Philo_ctor} - -/* Philo definition --------------------------------------------------------*/ -$define ${AOs::Philo} - - - - #include "qpc.h" -#include "dpp.h" -#include "bsp.h" - -Q_DEFINE_THIS_MODULE("table") - -/* Active object class -----------------------------------------------------*/ -$declare ${AOs::Table} - -#define RIGHT(n_) ((uint8_t)(((n_) + (N_PHILO - 1U)) % N_PHILO)) -#define LEFT(n_) ((uint8_t)(((n_) + 1U) % N_PHILO)) -#define FREE ((uint8_t)0) -#define USED ((uint8_t)1) - -/* Shared objects ----------------------------------------------------------*/ -$define ${Shared::AO_Table} -$define ${Shared::Table_ctor} - -/*..........................................................................*/ -$define ${AOs::Table} - - - diff --git a/examples/workstation/dpp/main.c b/examples/workstation/dpp/main.c deleted file mode 100644 index 57008dd4..00000000 --- a/examples/workstation/dpp/main.c +++ /dev/null @@ -1,102 +0,0 @@ -/***************************************************************************** -* Product: DPP example for Windows -* Last updated for version 7.1.2 -* Last updated on 2022-10-06 -* -* Q u a n t u m L e a P s -* ------------------------ -* Modern Embedded Software -* -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* -* -*****************************************************************************/ -#include "qpc.h" -#include "dpp.h" -#include "bsp.h" - -Q_DEFINE_THIS_FILE - -/* "fudge factor" for Windows, see NOTE1 */ -enum { WIN_FUDGE_FACTOR = 10 }; - -/*..........................................................................*/ -int main(int argc, char *argv[]) { - static QEvt const *tableQueueSto[N_PHILO*WIN_FUDGE_FACTOR]; - static QEvt const *philoQueueSto[N_PHILO][N_PHILO*WIN_FUDGE_FACTOR]; - static QSubscrList subscrSto[MAX_PUB_SIG]; - static QF_MPOOL_EL(TableEvt) smlPoolSto[2*N_PHILO*WIN_FUDGE_FACTOR]; - - QF_init(); /* initialize the framework and the underlying RT kernel */ - BSP_init(argc, argv); /* initialize the Board Support Package */ - - /* initialize publish-subscribe... */ - QF_psInit(subscrSto, Q_DIM(subscrSto)); - - /* initialize event pools... */ - QF_poolInit(smlPoolSto, sizeof(smlPoolSto), sizeof(smlPoolSto[0])); - - /* start the active objects... */ - for (uint8_t n = 0U; n < N_PHILO; ++n) { - Philo_ctor(n); /* instantiate all Philosopher active objects */ - QACTIVE_START(AO_Philo[n], /* AO to start */ - n + 2U, /* QF-priority */ - philoQueueSto[n], /* event queue storage */ - Q_DIM(philoQueueSto[n]), /* queue length [events] */ - (void *)0, /* stack storage (not used) */ - 0U, /* size of the stack [bytes] */ - (void *)0); /* initialization param */ - } - - Table_ctor(); /* instantiate the Table active object */ - QACTIVE_START(AO_Table, /* AO to start */ - N_PHILO + 2U, /* QF-priority */ - tableQueueSto, /* event queue storage */ - Q_DIM(tableQueueSto), /* queue length [events] */ - (void *)0, /* stack storage (not used) */ - 0U, /* size of the stack [bytes] */ - (void *)0); /* initialization param */ - - return QF_run(); /* run the QF application */ -} - -/***************************************************************************** -* NOTE1: -* Windows is not a deterministic real-time system, which means that the -* system can occasionally and unexpectedly "choke and freeze" for a number -* of seconds. The designers of Windows have dealt with these sort of issues -* by massively oversizing the resources available to the applications. For -* example, the default Windows GUI message queues size is 10,000 entries, -* which can dynamically grow to an even larger number. Also the stacks of -* Win32 threads can dynamically grow to several megabytes. -* -* In contrast, the event queues, event pools, and stack size inside the -* real-time embedded (RTE) systems can be (and must be) much smaller, -* because you typically can put an upper bound on the real-time behavior -* and the resulting delays. -* -* To be able to run the unmodified applications designed originally for -* RTE systems on Windows, and to reduce the odds of resource shortages in -* this case, the generous WIN_FUDGE_FACTOR is used to oversize the -* event queues and event pools. -*/ diff --git a/examples/workstation/dpp/philo.c b/examples/workstation/dpp/philo.c deleted file mode 100644 index 4cd1e47b..00000000 --- a/examples/workstation/dpp/philo.c +++ /dev/null @@ -1,246 +0,0 @@ -/*$file${.::philo.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* -* Model: dpp.qm -* File: ${.::philo.c} -* -* This code has been generated by QM 5.2.4 . -* DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. -* -* SPDX-License-Identifier: GPL-3.0-or-later -* -* This generated code is open source software: you can redistribute it under -* the terms of the GNU General Public License as published by the Free -* Software Foundation. -* -* This code is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -* more details. -* -* NOTE: -* Alternatively, this generated code may be distributed under the terms -* of Quantum Leaps commercial licenses, which expressly supersede the GNU -* General Public License and are specifically designed for licensees -* interested in retaining the proprietary status of their code. -* -* Contact information: -* -* -*/ -/*$endhead${.::philo.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -#include "qpc.h" -#include "dpp.h" -#include "bsp.h" - -Q_DEFINE_THIS_MODULE("philo") - -/* Active object class -----------------------------------------------------*/ -/*$declare${AOs::Philo} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${AOs::Philo} ............................................................*/ -typedef struct Philo { -/* protected: */ - QActive super; - -/* public: */ - -/* private: */ - QTimeEvt timeEvt; -} Philo; -extern Philo Philo_inst[N_PHILO]; - -/* protected: */ -static QState Philo_initial(Philo * const me, void const * const par); -static QState Philo_thinking(Philo * const me, QEvt const * const e); -static QState Philo_hungry(Philo * const me, QEvt const * const e); -static QState Philo_eating(Philo * const me, QEvt const * const e); -/*$enddecl${AOs::Philo} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ - -/* helper macros to provide a randomized think time for Philos */ -#define THINK_TIME \ - (QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + (BSP_TICKS_PER_SEC/2U)) -#define EAT_TIME \ - (QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + BSP_TICKS_PER_SEC) - -/* helper macro to provide the ID of Philo "me_" */ -#define PHILO_ID(me_) ((uint8_t)((me_) - &Philo_inst[0])) - -/* Shared objects ----------------------------------------------------------*/ -/*$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* Check for the minimum required QP version */ -#if (QP_VERSION < 700U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) -#error qpc version 7.0.0 or higher required -#endif -/*$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ - -/*$define${Shared::AO_Philo[N_PHILO]} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${Shared::AO_Philo[N_PHILO]} .............................................*/ -QActive * const AO_Philo[N_PHILO] = { - &Philo_inst[0].super, - &Philo_inst[1].super, - &Philo_inst[2].super, - &Philo_inst[3].super, - &Philo_inst[4].super -}; -/*$enddef${Shared::AO_Philo[N_PHILO]} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*$define${Shared::Philo_ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${Shared::Philo_ctor} ....................................................*/ -void Philo_ctor(uint8_t n) { - Philo *me = &Philo_inst[n]; - QActive_ctor(&me->super, Q_STATE_CAST(&Philo_initial)); - QTimeEvt_ctorX(&me->timeEvt, &me->super, TIMEOUT_SIG, 0U); -} -/*$enddef${Shared::Philo_ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ - -/* Philo definition --------------------------------------------------------*/ -/*$define${AOs::Philo} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${AOs::Philo} ............................................................*/ -Philo Philo_inst[N_PHILO]; - -/*${AOs::Philo::SM} ........................................................*/ -static QState Philo_initial(Philo * const me, void const * const par) { - /*${AOs::Philo::SM::initial} */ - (void)par; /* unused parameter */ - - #ifdef Q_SPY - uint8_t n = PHILO_ID(me); - QS_OBJ_ARR_DICTIONARY(&Philo_inst[n], n); - QS_OBJ_ARR_DICTIONARY(&Philo_inst[n].timeEvt, n); - #endif - - QActive_subscribe(&me->super, EAT_SIG); - QActive_subscribe(&me->super, TEST_SIG); - - /* the following code outputs the "fun-dictionaries" only once for - * all Philo instances, as opposed to repeat them for every instance. - */ - static bool registered = false; - if (!registered) { - registered = true; - - QS_FUN_DICTIONARY(&Philo_initial); - QS_FUN_DICTIONARY(&Philo_thinking); - QS_FUN_DICTIONARY(&Philo_hungry); - QS_FUN_DICTIONARY(&Philo_eating); - } - return Q_TRAN(&Philo_thinking); -} - -/*${AOs::Philo::SM::thinking} ..............................................*/ -static QState Philo_thinking(Philo * const me, QEvt const * const e) { - QState status_; - switch (e->sig) { - /*${AOs::Philo::SM::thinking} */ - case Q_ENTRY_SIG: { - QTimeEvt_armX(&me->timeEvt, THINK_TIME, 0U); - status_ = Q_HANDLED(); - break; - } - /*${AOs::Philo::SM::thinking} */ - case Q_EXIT_SIG: { - QTimeEvt_disarm(&me->timeEvt); - status_ = Q_HANDLED(); - break; - } - /*${AOs::Philo::SM::thinking::TIMEOUT} */ - case TIMEOUT_SIG: { - status_ = Q_TRAN(&Philo_hungry); - break; - } - /*${AOs::Philo::SM::thinking::EAT, DONE} */ - case EAT_SIG: /* intentionally fall through */ - case DONE_SIG: { - /* EAT or DONE must be for other Philos than this one */ - Q_ASSERT_ID(10, Q_EVT_CAST(TableEvt)->philoNum != PHILO_ID(me)); - status_ = Q_HANDLED(); - break; - } - default: { - status_ = Q_SUPER(&QHsm_top); - break; - } - } - return status_; -} - -/*${AOs::Philo::SM::hungry} ................................................*/ -static QState Philo_hungry(Philo * const me, QEvt const * const e) { - QState status_; - switch (e->sig) { - /*${AOs::Philo::SM::hungry} */ - case Q_ENTRY_SIG: { - TableEvt *pe = Q_NEW(TableEvt, HUNGRY_SIG); - pe->philoNum = PHILO_ID(me); - QACTIVE_POST(AO_Table, &pe->super, me); - status_ = Q_HANDLED(); - break; - } - /*${AOs::Philo::SM::hungry::EAT} */ - case EAT_SIG: { - /*${AOs::Philo::SM::hungry::EAT::[Q_EVT_CAST(TableEvt)->philoNum=~} */ - if (Q_EVT_CAST(TableEvt)->philoNum == PHILO_ID(me)) { - status_ = Q_TRAN(&Philo_eating); - } - else { - status_ = Q_UNHANDLED(); - } - break; - } - /*${AOs::Philo::SM::hungry::DONE} */ - case DONE_SIG: { - /* DONE must be for other Philos than this one */ - Q_ASSERT_ID(20, Q_EVT_CAST(TableEvt)->philoNum != PHILO_ID(me)); - status_ = Q_HANDLED(); - break; - } - default: { - status_ = Q_SUPER(&QHsm_top); - break; - } - } - return status_; -} - -/*${AOs::Philo::SM::eating} ................................................*/ -static QState Philo_eating(Philo * const me, QEvt const * const e) { - QState status_; - switch (e->sig) { - /*${AOs::Philo::SM::eating} */ - case Q_ENTRY_SIG: { - QTimeEvt_armX(&me->timeEvt, EAT_TIME, 0U); - status_ = Q_HANDLED(); - break; - } - /*${AOs::Philo::SM::eating} */ - case Q_EXIT_SIG: { - TableEvt *pe = Q_NEW(TableEvt, DONE_SIG); - pe->philoNum = PHILO_ID(me); - QACTIVE_PUBLISH(&pe->super, &me->super); - QTimeEvt_disarm(&me->timeEvt); - status_ = Q_HANDLED(); - break; - } - /*${AOs::Philo::SM::eating::TIMEOUT} */ - case TIMEOUT_SIG: { - status_ = Q_TRAN(&Philo_thinking); - break; - } - /*${AOs::Philo::SM::eating::EAT, DONE} */ - case EAT_SIG: /* intentionally fall through */ - case DONE_SIG: { - /* EAT or DONE must be for other Philos than this one */ - Q_ASSERT_ID(30, Q_EVT_CAST(TableEvt)->philoNum != PHILO_ID(me)); - status_ = Q_HANDLED(); - break; - } - default: { - status_ = Q_SUPER(&QHsm_top); - break; - } - } - return status_; -} -/*$enddef${AOs::Philo} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ diff --git a/examples/workstation/dpp/table.c b/examples/workstation/dpp/table.c deleted file mode 100644 index 4daf8d20..00000000 --- a/examples/workstation/dpp/table.c +++ /dev/null @@ -1,306 +0,0 @@ -/*$file${.::table.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* -* Model: dpp.qm -* File: ${.::table.c} -* -* This code has been generated by QM 5.2.4 . -* DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. -* -* SPDX-License-Identifier: GPL-3.0-or-later -* -* This generated code is open source software: you can redistribute it under -* the terms of the GNU General Public License as published by the Free -* Software Foundation. -* -* This code is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -* more details. -* -* NOTE: -* Alternatively, this generated code may be distributed under the terms -* of Quantum Leaps commercial licenses, which expressly supersede the GNU -* General Public License and are specifically designed for licensees -* interested in retaining the proprietary status of their code. -* -* Contact information: -* -* -*/ -/*$endhead${.::table.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -#include "qpc.h" -#include "dpp.h" -#include "bsp.h" - -Q_DEFINE_THIS_MODULE("table") - -/* Active object class -----------------------------------------------------*/ -/*$declare${AOs::Table} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${AOs::Table} ............................................................*/ -typedef struct Table { -/* protected: */ - QActive super; - -/* public: */ - -/* private: */ - uint8_t fork[N_PHILO]; - uint8_t isHungry[N_PHILO]; -} Table; -extern Table Table_inst; - -/* protected: */ -static QState Table_initial(Table * const me, void const * const par); -static QState Table_active(Table * const me, QEvt const * const e); -static QState Table_serving(Table * const me, QEvt const * const e); -static QState Table_paused(Table * const me, QEvt const * const e); -/*$enddecl${AOs::Table} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ - -#define RIGHT(n_) ((uint8_t)(((n_) + (N_PHILO - 1U)) % N_PHILO)) -#define LEFT(n_) ((uint8_t)(((n_) + 1U) % N_PHILO)) -#define FREE ((uint8_t)0) -#define USED ((uint8_t)1) - -/* Shared objects ----------------------------------------------------------*/ -/*$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* Check for the minimum required QP version */ -#if (QP_VERSION < 700U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) -#error qpc version 7.0.0 or higher required -#endif -/*$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ - -/*$define${Shared::AO_Table} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${Shared::AO_Table} ......................................................*/ -QActive * const AO_Table = &Table_inst.super; -/*$enddef${Shared::AO_Table} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*$define${Shared::Table_ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${Shared::Table_ctor} ....................................................*/ -void Table_ctor(void) { - Table *me = &Table_inst; - - QActive_ctor(&me->super, Q_STATE_CAST(&Table_initial)); - - for (uint8_t n = 0U; n < N_PHILO; ++n) { - me->fork[n] = FREE; - me->isHungry[n] = 0U; - } -} -/*$enddef${Shared::Table_ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ - -/*..........................................................................*/ -/*$define${AOs::Table} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${AOs::Table} ............................................................*/ -Table Table_inst; - -/*${AOs::Table::SM} ........................................................*/ -static QState Table_initial(Table * const me, void const * const par) { - /*${AOs::Table::SM::initial} */ - (void)par; /* unused parameter */ - - QS_OBJ_DICTIONARY(&Table_inst); - - QActive_subscribe(&me->super, DONE_SIG); - QActive_subscribe(&me->super, PAUSE_SIG); - QActive_subscribe(&me->super, SERVE_SIG); - QActive_subscribe(&me->super, TEST_SIG); - - for (uint8_t n = 0U; n < N_PHILO; ++n) { - me->fork[n] = FREE; - me->isHungry[n] = 0U; - BSP_displayPhilStat(n, "thinking"); - } - - QS_FUN_DICTIONARY(&Table_active); - QS_FUN_DICTIONARY(&Table_serving); - QS_FUN_DICTIONARY(&Table_paused); - - return Q_TRAN(&Table_serving); -} - -/*${AOs::Table::SM::active} ................................................*/ -static QState Table_active(Table * const me, QEvt const * const e) { - QState status_; - switch (e->sig) { - /*${AOs::Table::SM::active::EAT} */ - case EAT_SIG: { - Q_ERROR_ID(60); - status_ = Q_HANDLED(); - break; - } - default: { - status_ = Q_SUPER(&QHsm_top); - break; - } - } - return status_; -} - -/*${AOs::Table::SM::active::serving} .......................................*/ -static QState Table_serving(Table * const me, QEvt const * const e) { - QState status_; - switch (e->sig) { - /*${AOs::Table::SM::active::serving} */ - case Q_ENTRY_SIG: { - uint8_t n; - for (n = 0U; n < N_PHILO; ++n) { /* give permissions to eat... */ - if ((me->isHungry[n] != 0U) - && (me->fork[LEFT(n)] == FREE) - && (me->fork[n] == FREE)) - { - TableEvt *te; - - me->fork[LEFT(n)] = USED; - me->fork[n] = USED; - te = Q_NEW(TableEvt, EAT_SIG); - te->philoNum = n; - QACTIVE_PUBLISH(&te->super, &me->super); - me->isHungry[n] = 0U; - BSP_displayPhilStat(n, "eating "); - } - } - status_ = Q_HANDLED(); - break; - } - /*${AOs::Table::SM::active::serving::HUNGRY} */ - case HUNGRY_SIG: { - uint8_t n, m; - - n = Q_EVT_CAST(TableEvt)->philoNum; - /* phil ID must be in range and he must be not hungry */ - Q_ASSERT_ID(40, (n < N_PHILO) && (me->isHungry[n] == 0U)); - - BSP_displayPhilStat(n, "hungry "); - m = LEFT(n); - /*${AOs::Table::SM::active::serving::HUNGRY::[bothfree]} */ - if ((me->fork[m] == FREE) && (me->fork[n] == FREE)) { - TableEvt *pe; - me->fork[m] = USED; - me->fork[n] = USED; - pe = Q_NEW(TableEvt, EAT_SIG); - pe->philoNum = n; - QACTIVE_PUBLISH(&pe->super, &me->super); - BSP_displayPhilStat(n, "eating "); - status_ = Q_HANDLED(); - } - /*${AOs::Table::SM::active::serving::HUNGRY::[else]} */ - else { - me->isHungry[n] = 1U; - status_ = Q_HANDLED(); - } - break; - } - /*${AOs::Table::SM::active::serving::DONE} */ - case DONE_SIG: { - uint8_t n, m; - TableEvt *pe; - - n = Q_EVT_CAST(TableEvt)->philoNum; - /* phil ID must be in range and he must be not hungry */ - Q_ASSERT_ID(50, (n < N_PHILO) && (me->isHungry[n] == 0U)); - - BSP_displayPhilStat(n, "thinking"); - m = LEFT(n); - /* both forks of Phil[n] must be used */ - Q_ASSERT_ID(51, (me->fork[n] == USED) && (me->fork[m] == USED)); - - me->fork[m] = FREE; - me->fork[n] = FREE; - m = RIGHT(n); /* check the right neighbor */ - - if ((me->isHungry[m] != 0U) && (me->fork[m] == FREE)) { - me->fork[n] = USED; - me->fork[m] = USED; - me->isHungry[m] = 0U; - pe = Q_NEW(TableEvt, EAT_SIG); - pe->philoNum = m; - QACTIVE_PUBLISH(&pe->super, &me->super); - BSP_displayPhilStat(m, "eating "); - } - m = LEFT(n); /* check the left neighbor */ - n = LEFT(m); /* left fork of the left neighbor */ - if ((me->isHungry[m] != 0U) && (me->fork[n] == FREE)) { - me->fork[m] = USED; - me->fork[n] = USED; - me->isHungry[m] = 0U; - pe = Q_NEW(TableEvt, EAT_SIG); - pe->philoNum = m; - QACTIVE_PUBLISH(&pe->super, &me->super); - BSP_displayPhilStat(m, "eating "); - } - status_ = Q_HANDLED(); - break; - } - /*${AOs::Table::SM::active::serving::PAUSE} */ - case PAUSE_SIG: { - status_ = Q_TRAN(&Table_paused); - break; - } - default: { - status_ = Q_SUPER(&Table_active); - break; - } - } - return status_; -} - -/*${AOs::Table::SM::active::paused} ........................................*/ -static QState Table_paused(Table * const me, QEvt const * const e) { - QState status_; - switch (e->sig) { - /*${AOs::Table::SM::active::paused} */ - case Q_ENTRY_SIG: { - BSP_displayPaused(1U); - status_ = Q_HANDLED(); - break; - } - /*${AOs::Table::SM::active::paused} */ - case Q_EXIT_SIG: { - BSP_displayPaused(0U); - status_ = Q_HANDLED(); - break; - } - /*${AOs::Table::SM::active::paused::SERVE} */ - case SERVE_SIG: { - status_ = Q_TRAN(&Table_serving); - break; - } - /*${AOs::Table::SM::active::paused::HUNGRY} */ - case HUNGRY_SIG: { - uint8_t n = Q_EVT_CAST(TableEvt)->philoNum; - /* philo ID must be in range and he must be not hungry */ - Q_ASSERT_ID(60, (n < N_PHILO) && (me->isHungry[n] == 0U)); - me->isHungry[n] = 1U; - BSP_displayPhilStat(n, "hungry "); - status_ = Q_HANDLED(); - break; - } - /*${AOs::Table::SM::active::paused::DONE} */ - case DONE_SIG: { - uint8_t n, m; - - n = Q_EVT_CAST(TableEvt)->philoNum; - /* phil ID must be in range and he must be not hungry */ - Q_ASSERT_ID(70, (n < N_PHILO) && (me->isHungry[n] == 0U)); - - BSP_displayPhilStat(n, "thinking"); - m = LEFT(n); - /* both forks of Phil[n] must be used */ - Q_ASSERT_ID(71, (me->fork[n] == USED) && (me->fork[m] == USED)); - - me->fork[m] = FREE; - me->fork[n] = FREE; - status_ = Q_HANDLED(); - break; - } - default: { - status_ = Q_SUPER(&Table_active); - break; - } - } - return status_; -} -/*$enddef${AOs::Table} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ diff --git a/examples/workstation/game-gui/README.txt b/examples/workstation/game-gui/README.txt deleted file mode 100644 index bfca80d9..00000000 --- a/examples/workstation/game-gui/README.txt +++ /dev/null @@ -1,13 +0,0 @@ -The Win32 GUI emulation of the "Fly 'n' Shoot" game example for the -EFM32-SLSTK3401A board from Silicon Labs is now located in the directory: - -examples\arm-cm\game_efm32-slstk3401a\win32-gui\ - -**** -NOTE: The EFM32-SLSTK3401A board replaces the EK-LM3S811 board, which -has been discontinued. -**** - -This co-location of the Win32 emulation with the embedded code running -on the actual board demonstrates better the "dual targeting" development -approach. \ No newline at end of file diff --git a/examples/workstation/history_qhsm/history.h b/examples/workstation/history_qhsm/history.h deleted file mode 100644 index 0e191687..00000000 --- a/examples/workstation/history_qhsm/history.h +++ /dev/null @@ -1,52 +0,0 @@ -/*$file${.::history.h} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* -* Model: history.qm -* File: ${.::history.h} -* -* This code has been generated by QM 5.2.4 . -* DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. -* -* SPDX-License-Identifier: GPL-3.0-or-later -* -* This generated code is open source software: you can redistribute it under -* the terms of the GNU General Public License as published by the Free -* Software Foundation. -* -* This code is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -* more details. -* -* NOTE: -* Alternatively, this generated code may be distributed under the terms -* of Quantum Leaps commercial licenses, which expressly supersede the GNU -* General Public License and are specifically designed for licensees -* interested in retaining the proprietary status of their code. -* -* Contact information: -* -* -*/ -/*$endhead${.::history.h} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -#ifndef HISTORY_H -#define HISTORY_H - -enum ToastOvenSignals { - OPEN_SIG = Q_USER_SIG, - CLOSE_SIG, - TOAST_SIG, - BAKE_SIG, - OFF_SIG, - TERMINATE_SIG /* terminate the application */ -}; - -extern QHsm * const the_oven; /* opaque pointer to the oven HSM */ - -/*$declare${SMs::ToastOven_ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${SMs::ToastOven_ctor} ...................................................*/ -void ToastOven_ctor(void); -/*$enddecl${SMs::ToastOven_ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ - -#endif /* HISTORY_H */ - diff --git a/examples/workstation/history_qhsm/main.c b/examples/workstation/history_qhsm/main.c deleted file mode 100644 index 7bd179a6..00000000 --- a/examples/workstation/history_qhsm/main.c +++ /dev/null @@ -1,102 +0,0 @@ -/***************************************************************************** -* Product: History Example, Win32 -* Last updated for version 6.9.1 -* Last updated on 2020-09-11 -* -* Q u a n t u m L e a P s -* ------------------------ -* Modern Embedded Software -* -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* -* -*****************************************************************************/ -#include "qpc.h" -#include "history.h" - -#include "safe_std.h" /* portable "safe" / facilities */ -#include /* for exit() */ - -Q_DEFINE_THIS_FILE - -/*..........................................................................*/ -int main() { - QF_init(); - QF_onStartup(); - - PRINTF_S("History state pattern\nQP version: %s\n" - "Press 'o' to OPEN the door\n" - "Press 'c' to CLOSE the door\n" - "Press 't' to start TOASTING\n" - "Press 'b' to start BAKING\n" - "Press 'f' to turn the oven OFF\n" - "Press ESC to quit...\n", - QP_VERSION_STR); - - /* instantiate the ToastOven HSM and trigger the initial transition */ - ToastOven_ctor(); - QHSM_INIT(the_oven, (void *)0, 0U); - - for (;;) { - QEvt e; - uint8_t c; - - PRINTF_S("\n", ""); - c = (uint8_t)QF_consoleWaitForKey(); - PRINTF_S("%c: ", (c >= ' ') ? c : 'X'); - - switch (c) { - case 'o': e.sig = OPEN_SIG; break; - case 'c': e.sig = CLOSE_SIG; break; - case 't': e.sig = TOAST_SIG; break; - case 'b': e.sig = BAKE_SIG; break; - case 'f': e.sig = OFF_SIG; break; - case 0x1B: e.sig = TERMINATE_SIG; break; - } - - /* dispatch the event into the state machine */ - QHSM_DISPATCH(the_oven, &e, 0U); - } - - QF_onCleanup(); - return 0; -} - -/*..........................................................................*/ -void QF_onStartup(void) { - QF_consoleSetup(); -} -/*..........................................................................*/ -void QF_onCleanup(void) { - QF_consoleCleanup(); -} -/*..........................................................................*/ -void QF_onClockTick(void) { -} - -/*..........................................................................*/ -Q_NORETURN Q_onAssert(char const * const file, int_t const line) { - FPRINTF_S(stderr, "Assertion failed in %s, line %d", file, line); - QF_onCleanup(); - exit(-1); -} diff --git a/examples/workstation/history_qmsm/history.c b/examples/workstation/history_qmsm/history.c deleted file mode 100644 index f4308067..00000000 --- a/examples/workstation/history_qmsm/history.c +++ /dev/null @@ -1,485 +0,0 @@ -/*$file${.::history.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* -* Model: history.qm -* File: ${.::history.c} -* -* This code has been generated by QM 5.2.4 . -* DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. -* -* SPDX-License-Identifier: GPL-3.0-or-later -* -* This generated code is open source software: you can redistribute it under -* the terms of the GNU General Public License as published by the Free -* Software Foundation. -* -* This code is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -* more details. -* -* NOTE: -* Alternatively, this generated code may be distributed under the terms -* of Quantum Leaps commercial licenses, which expressly supersede the GNU -* General Public License and are specifically designed for licensees -* interested in retaining the proprietary status of their code. -* -* Contact information: -* -* -*/ -/*$endhead${.::history.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -#include "qpc.h" -#include "history.h" - -#include "safe_std.h" /* portable "safe" / facilities */ -#include - -//Q_DEFINE_THIS_FILE - -/*$declare${SMs::ToastOven} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${SMs::ToastOven} ........................................................*/ -typedef struct { -/* protected: */ - QMsm super; - -/* private state histories */ - QMState const *hist_doorClosed; - QMState const *hist_heating; -} ToastOven; - -/* protected: */ -static QState ToastOven_initial(ToastOven * const me, void const * const par); -static QState ToastOven_doorClosed (ToastOven * const me, QEvt const * const e); -static QState ToastOven_doorClosed_e(ToastOven * const me); -static QState ToastOven_doorClosed_x(ToastOven * const me); -static QState ToastOven_doorClosed_i(ToastOven * const me); -static QMState const ToastOven_doorClosed_s = { - QM_STATE_NULL, /* superstate (top) */ - Q_STATE_CAST(&ToastOven_doorClosed), - Q_ACTION_CAST(&ToastOven_doorClosed_e), - Q_ACTION_CAST(&ToastOven_doorClosed_x), - Q_ACTION_CAST(&ToastOven_doorClosed_i) -}; -static QState ToastOven_heating (ToastOven * const me, QEvt const * const e); -static QState ToastOven_heating_e(ToastOven * const me); -static QState ToastOven_heating_x(ToastOven * const me); -static QState ToastOven_heating_i(ToastOven * const me); -static QMState const ToastOven_heating_s = { - &ToastOven_doorClosed_s, /* superstate */ - Q_STATE_CAST(&ToastOven_heating), - Q_ACTION_CAST(&ToastOven_heating_e), - Q_ACTION_CAST(&ToastOven_heating_x), - Q_ACTION_CAST(&ToastOven_heating_i) -}; -static QState ToastOven_toasting (ToastOven * const me, QEvt const * const e); -static QState ToastOven_toasting_e(ToastOven * const me); -static QMState const ToastOven_toasting_s = { - &ToastOven_heating_s, /* superstate */ - Q_STATE_CAST(&ToastOven_toasting), - Q_ACTION_CAST(&ToastOven_toasting_e), - Q_ACTION_NULL, /* no exit action */ - Q_ACTION_NULL /* no initial tran. */ -}; -static QState ToastOven_baking (ToastOven * const me, QEvt const * const e); -static QState ToastOven_baking_e(ToastOven * const me); -static QMState const ToastOven_baking_s = { - &ToastOven_heating_s, /* superstate */ - Q_STATE_CAST(&ToastOven_baking), - Q_ACTION_CAST(&ToastOven_baking_e), - Q_ACTION_NULL, /* no exit action */ - Q_ACTION_NULL /* no initial tran. */ -}; -static QState ToastOven_off (ToastOven * const me, QEvt const * const e); -static QState ToastOven_off_e(ToastOven * const me); -static QMState const ToastOven_off_s = { - &ToastOven_doorClosed_s, /* superstate */ - Q_STATE_CAST(&ToastOven_off), - Q_ACTION_CAST(&ToastOven_off_e), - Q_ACTION_NULL, /* no exit action */ - Q_ACTION_NULL /* no initial tran. */ -}; -static QState ToastOven_doorOpen (ToastOven * const me, QEvt const * const e); -static QState ToastOven_doorOpen_e(ToastOven * const me); -static QState ToastOven_doorOpen_x(ToastOven * const me); -static QMState const ToastOven_doorOpen_s = { - QM_STATE_NULL, /* superstate (top) */ - Q_STATE_CAST(&ToastOven_doorOpen), - Q_ACTION_CAST(&ToastOven_doorOpen_e), - Q_ACTION_CAST(&ToastOven_doorOpen_x), - Q_ACTION_NULL /* no initial tran. */ -}; -static QState ToastOven_final (ToastOven * const me, QEvt const * const e); -static QState ToastOven_final_e(ToastOven * const me); -static QMState const ToastOven_final_s = { - QM_STATE_NULL, /* superstate (top) */ - Q_STATE_CAST(&ToastOven_final), - Q_ACTION_CAST(&ToastOven_final_e), - Q_ACTION_NULL, /* no exit action */ - Q_ACTION_NULL /* no initial tran. */ -}; -/*$enddecl${SMs::ToastOven} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ - -static ToastOven l_oven; /* the only instance of the ToastOven class */ - -/* global-scope definitions -----------------------------------------*/ -QHsm * const the_oven = &l_oven.super.super; /* the opaque pointer */ - -/*$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* Check for the minimum required QP version */ -#if (QP_VERSION < 700U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) -#error qpc version 7.0.0 or higher required -#endif -/*$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ - -/*$define${SMs::ToastOven_ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${SMs::ToastOven_ctor} ...................................................*/ -void ToastOven_ctor(void) { - ToastOven *me = &l_oven; - QMsm_ctor(&me->super, Q_STATE_CAST(&ToastOven_initial)); -} -/*$enddef${SMs::ToastOven_ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*$define${SMs::ToastOven} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${SMs::ToastOven} ........................................................*/ - -/*${SMs::ToastOven::SM} ....................................................*/ -static QState ToastOven_initial(ToastOven * const me, void const * const par) { - static struct { - QMState const *target; - QActionHandler act[3]; - } const tatbl_ = { /* tran-action table */ - &ToastOven_doorClosed_s, /* target state */ - { - Q_ACTION_CAST(&ToastOven_doorClosed_e), /* entry */ - Q_ACTION_CAST(&ToastOven_doorClosed_i), /* initial tran. */ - Q_ACTION_NULL /* zero terminator */ - } - }; - /*${SMs::ToastOven::SM::initial} */ - (void)par; /* unused parameter */ - /* state history attributes */ - me->hist_doorClosed = &ToastOven_off_s; - me->hist_heating = &ToastOven_baking_s; - return QM_TRAN_INIT(&tatbl_); -} - -/*${SMs::ToastOven::SM::doorClosed} ........................................*/ -/*${SMs::ToastOven::SM::doorClosed} */ -static QState ToastOven_doorClosed_e(ToastOven * const me) { - PRINTF_S("%s;", "door-Closed"); - (void)me; /* unused parameter */ - return QM_ENTRY(&ToastOven_doorClosed_s); -} -/*${SMs::ToastOven::SM::doorClosed} */ -static QState ToastOven_doorClosed_x(ToastOven * const me) { - /* save shallow history */ - me->hist_doorClosed = - QMsm_childStateObj(Q_HSM_UPCAST(me), &ToastOven_doorClosed_s); - return QM_EXIT(&ToastOven_doorClosed_s); -} -/*${SMs::ToastOven::SM::doorClosed::initial} */ -static QState ToastOven_doorClosed_i(ToastOven * const me) { - static struct { - QMState const *target; - QActionHandler act[2]; - } const tatbl_ = { /* tran-action table */ - &ToastOven_off_s, /* target state */ - { - Q_ACTION_CAST(&ToastOven_off_e), /* entry */ - Q_ACTION_NULL /* zero terminator */ - } - }; - /*${SMs::ToastOven::SM::doorClosed::initial} */ - return QM_TRAN_INIT(&tatbl_); -} -/*${SMs::ToastOven::SM::doorClosed} */ -static QState ToastOven_doorClosed(ToastOven * const me, QEvt const * const e) { - QState status_; - switch (e->sig) { - /*${SMs::ToastOven::SM::doorClosed::TERMINATE} */ - case TERMINATE_SIG: { - static struct { - QMState const *target; - QActionHandler act[3]; - } const tatbl_ = { /* tran-action table */ - &ToastOven_final_s, /* target state */ - { - Q_ACTION_CAST(&ToastOven_doorClosed_x), /* exit */ - Q_ACTION_CAST(&ToastOven_final_e), /* entry */ - Q_ACTION_NULL /* zero terminator */ - } - }; - status_ = QM_TRAN(&tatbl_); - break; - } - /*${SMs::ToastOven::SM::doorClosed::OPEN} */ - case OPEN_SIG: { - static struct { - QMState const *target; - QActionHandler act[3]; - } const tatbl_ = { /* tran-action table */ - &ToastOven_doorOpen_s, /* target state */ - { - Q_ACTION_CAST(&ToastOven_doorClosed_x), /* exit */ - Q_ACTION_CAST(&ToastOven_doorOpen_e), /* entry */ - Q_ACTION_NULL /* zero terminator */ - } - }; - status_ = QM_TRAN(&tatbl_); - break; - } - /*${SMs::ToastOven::SM::doorClosed::TOAST} */ - case TOAST_SIG: { - static struct { - QMState const *target; - QActionHandler act[3]; - } const tatbl_ = { /* tran-action table */ - &ToastOven_toasting_s, /* target state */ - { - Q_ACTION_CAST(&ToastOven_heating_e), /* entry */ - Q_ACTION_CAST(&ToastOven_toasting_e), /* entry */ - Q_ACTION_NULL /* zero terminator */ - } - }; - status_ = QM_TRAN(&tatbl_); - break; - } - /*${SMs::ToastOven::SM::doorClosed::BAKE} */ - case BAKE_SIG: { - static struct { - QMState const *target; - QActionHandler act[3]; - } const tatbl_ = { /* tran-action table */ - &ToastOven_baking_s, /* target state */ - { - Q_ACTION_CAST(&ToastOven_heating_e), /* entry */ - Q_ACTION_CAST(&ToastOven_baking_e), /* entry */ - Q_ACTION_NULL /* zero terminator */ - } - }; - status_ = QM_TRAN(&tatbl_); - break; - } - /*${SMs::ToastOven::SM::doorClosed::OFF} */ - case OFF_SIG: { - static struct { - QMState const *target; - QActionHandler act[2]; - } const tatbl_ = { /* tran-action table */ - &ToastOven_off_s, /* target state */ - { - Q_ACTION_CAST(&ToastOven_off_e), /* entry */ - Q_ACTION_NULL /* zero terminator */ - } - }; - status_ = QM_TRAN(&tatbl_); - break; - } - default: { - status_ = QM_SUPER(); - break; - } - } - return status_; -} - -/*${SMs::ToastOven::SM::doorClosed::heating} ...............................*/ -/*${SMs::ToastOven::SM::doorClosed::heating} */ -static QState ToastOven_heating_e(ToastOven * const me) { - PRINTF_S("%s;", "heater-On"); - (void)me; /* unused parameter */ - return QM_ENTRY(&ToastOven_heating_s); -} -/*${SMs::ToastOven::SM::doorClosed::heating} */ -static QState ToastOven_heating_x(ToastOven * const me) { - PRINTF_S("%s;", "heater-Off"); - /* save deep history */ - me->hist_heating = QMsm_stateObj(Q_HSM_UPCAST(me)); - return QM_EXIT(&ToastOven_heating_s); -} -/*${SMs::ToastOven::SM::doorClosed::heating::initial} */ -static QState ToastOven_heating_i(ToastOven * const me) { - static struct { - QMState const *target; - QActionHandler act[2]; - } const tatbl_ = { /* tran-action table */ - &ToastOven_toasting_s, /* target state */ - { - Q_ACTION_CAST(&ToastOven_toasting_e), /* entry */ - Q_ACTION_NULL /* zero terminator */ - } - }; - /*${SMs::ToastOven::SM::doorClosed::heating::initial} */ - return QM_TRAN_INIT(&tatbl_); -} -/*${SMs::ToastOven::SM::doorClosed::heating} */ -static QState ToastOven_heating(ToastOven * const me, QEvt const * const e) { - QState status_; - switch (e->sig) { - default: { - status_ = QM_SUPER(); - break; - } - } - (void)me; /* unused parameter */ - return status_; -} - -/*${SMs::ToastOven::SM::doorClosed::heating::toasting} .....................*/ -/*${SMs::ToastOven::SM::doorClosed::heating::toasting} */ -static QState ToastOven_toasting_e(ToastOven * const me) { - PRINTF_S("%s;", "toasting"); - (void)me; /* unused parameter */ - return QM_ENTRY(&ToastOven_toasting_s); -} -/*${SMs::ToastOven::SM::doorClosed::heating::toasting} */ -static QState ToastOven_toasting(ToastOven * const me, QEvt const * const e) { - QState status_; - switch (e->sig) { - default: { - status_ = QM_SUPER(); - break; - } - } - (void)me; /* unused parameter */ - return status_; -} - -/*${SMs::ToastOven::SM::doorClosed::heating::baking} .......................*/ -/*${SMs::ToastOven::SM::doorClosed::heating::baking} */ -static QState ToastOven_baking_e(ToastOven * const me) { - PRINTF_S("%s;", "baking"); - (void)me; /* unused parameter */ - return QM_ENTRY(&ToastOven_baking_s); -} -/*${SMs::ToastOven::SM::doorClosed::heating::baking} */ -static QState ToastOven_baking(ToastOven * const me, QEvt const * const e) { - QState status_; - switch (e->sig) { - default: { - status_ = QM_SUPER(); - break; - } - } - (void)me; /* unused parameter */ - return status_; -} - -/*${SMs::ToastOven::SM::doorClosed::off} ...................................*/ -/*${SMs::ToastOven::SM::doorClosed::off} */ -static QState ToastOven_off_e(ToastOven * const me) { - PRINTF_S("%s;", "toaster-Off"); - (void)me; /* unused parameter */ - return QM_ENTRY(&ToastOven_off_s); -} -/*${SMs::ToastOven::SM::doorClosed::off} */ -static QState ToastOven_off(ToastOven * const me, QEvt const * const e) { - QState status_; - switch (e->sig) { - default: { - status_ = QM_SUPER(); - break; - } - } - (void)me; /* unused parameter */ - return status_; -} - -/*${SMs::ToastOven::SM::doorOpen} ..........................................*/ -/*${SMs::ToastOven::SM::doorOpen} */ -static QState ToastOven_doorOpen_e(ToastOven * const me) { - PRINTF_S("%s;", "door-Open,lamp-On"); - (void)me; /* unused parameter */ - return QM_ENTRY(&ToastOven_doorOpen_s); -} -/*${SMs::ToastOven::SM::doorOpen} */ -static QState ToastOven_doorOpen_x(ToastOven * const me) { - PRINTF_S("%s;", "lamp-Off"); - (void)me; /* unused parameter */ - return QM_EXIT(&ToastOven_doorOpen_s); -} -/*${SMs::ToastOven::SM::doorOpen} */ -static QState ToastOven_doorOpen(ToastOven * const me, QEvt const * const e) { - QState status_; - switch (e->sig) { - /*${SMs::ToastOven::SM::doorOpen::CLOSE} */ - case CLOSE_SIG: { - static struct { - QMState const *target; - QActionHandler act[4]; - } const tatbl_ = { /* tran-action table */ - &ToastOven_heating_s, /* target state */ - { - Q_ACTION_CAST(&ToastOven_doorOpen_x), /* exit */ - Q_ACTION_CAST(&ToastOven_doorClosed_e), /* entry */ - Q_ACTION_CAST(&ToastOven_heating_e), /* entry */ - Q_ACTION_NULL /* zero terminator */ - } - }; - status_ = QM_TRAN_HIST(me->hist_heating, &tatbl_); - break; - } - /*${SMs::ToastOven::SM::doorOpen::TERMINATE} */ - case TERMINATE_SIG: { - static struct { - QMState const *target; - QActionHandler act[3]; - } const tatbl_ = { /* tran-action table */ - &ToastOven_final_s, /* target state */ - { - Q_ACTION_CAST(&ToastOven_doorOpen_x), /* exit */ - Q_ACTION_CAST(&ToastOven_final_e), /* entry */ - Q_ACTION_NULL /* zero terminator */ - } - }; - status_ = QM_TRAN(&tatbl_); - break; - } - /*${SMs::ToastOven::SM::doorOpen::OFF} */ - case OFF_SIG: { - static struct { - QMState const *target; - QActionHandler act[3]; - } const tatbl_ = { /* tran-action table */ - &ToastOven_doorClosed_s, /* target state */ - { - Q_ACTION_CAST(&ToastOven_doorOpen_x), /* exit */ - Q_ACTION_CAST(&ToastOven_doorClosed_e), /* entry */ - Q_ACTION_NULL /* zero terminator */ - } - }; - status_ = QM_TRAN_HIST(me->hist_doorClosed, &tatbl_); - break; - } - default: { - status_ = QM_SUPER(); - break; - } - } - return status_; -} - -/*${SMs::ToastOven::SM::final} .............................................*/ -/*${SMs::ToastOven::SM::final} */ -static QState ToastOven_final_e(ToastOven * const me) { - PRINTF_S("\n%s\n", "Bye! Bye!"); - QF_onCleanup(); - exit(0); - (void)me; /* unused parameter */ - return QM_ENTRY(&ToastOven_final_s); -} -/*${SMs::ToastOven::SM::final} */ -static QState ToastOven_final(ToastOven * const me, QEvt const * const e) { - QState status_; - switch (e->sig) { - default: { - status_ = QM_SUPER(); - break; - } - } - (void)me; /* unused parameter */ - return status_; -} -/*$enddef${SMs::ToastOven} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ diff --git a/examples/workstation/history_qmsm/history.h b/examples/workstation/history_qmsm/history.h deleted file mode 100644 index 0e191687..00000000 --- a/examples/workstation/history_qmsm/history.h +++ /dev/null @@ -1,52 +0,0 @@ -/*$file${.::history.h} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* -* Model: history.qm -* File: ${.::history.h} -* -* This code has been generated by QM 5.2.4 . -* DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. -* -* SPDX-License-Identifier: GPL-3.0-or-later -* -* This generated code is open source software: you can redistribute it under -* the terms of the GNU General Public License as published by the Free -* Software Foundation. -* -* This code is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -* more details. -* -* NOTE: -* Alternatively, this generated code may be distributed under the terms -* of Quantum Leaps commercial licenses, which expressly supersede the GNU -* General Public License and are specifically designed for licensees -* interested in retaining the proprietary status of their code. -* -* Contact information: -* -* -*/ -/*$endhead${.::history.h} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -#ifndef HISTORY_H -#define HISTORY_H - -enum ToastOvenSignals { - OPEN_SIG = Q_USER_SIG, - CLOSE_SIG, - TOAST_SIG, - BAKE_SIG, - OFF_SIG, - TERMINATE_SIG /* terminate the application */ -}; - -extern QHsm * const the_oven; /* opaque pointer to the oven HSM */ - -/*$declare${SMs::ToastOven_ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${SMs::ToastOven_ctor} ...................................................*/ -void ToastOven_ctor(void); -/*$enddecl${SMs::ToastOven_ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ - -#endif /* HISTORY_H */ - diff --git a/examples/workstation/history_qmsm/main.c b/examples/workstation/history_qmsm/main.c deleted file mode 100644 index 0f35febe..00000000 --- a/examples/workstation/history_qmsm/main.c +++ /dev/null @@ -1,102 +0,0 @@ -/***************************************************************************** -* Product: History Example, Win32 -* Last updated for version 6.9.1 -* Last updated on 2020-09-11 -* -* Q u a n t u m L e a P s -* ------------------------ -* Modern Embedded Software -* -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* -* -*****************************************************************************/ -#include "qpc.h" -#include "history.h" - -#include "safe_std.h" /* portable "safe" / facilities */ -#include /* for exit() */ - -Q_DEFINE_THIS_FILE - -/*..........................................................................*/ -int main() { - QF_init(); - QF_onStartup(); - - PRINTF_S("History state pattern\nQP version: %s\n" - "Press 'o' to OPEN the door\n" - "Press 'c' to CLOSE the door\n" - "Press 't' to start TOASTING\n" - "Press 'b' to start BAKING\n" - "Press 'f' to turn the oven OFF\n" - "Press ESC to quit...\n", - QP_VERSION_STR); - - /* instantiate the ToastOven HSM and trigger the initial transition */ - ToastOven_ctor(); - QHSM_INIT(the_oven, (void *)0, 0U); - - for (;;) { - QEvt e; - uint8_t c; - - PRINTF_S("%c", '\n'); - c = (uint8_t)QF_consoleWaitForKey(); - PRINTF_S("%c: ", (c >= ' ') ? c : 'X'); - - switch (c) { - case 'o': e.sig = OPEN_SIG; break; - case 'c': e.sig = CLOSE_SIG; break; - case 't': e.sig = TOAST_SIG; break; - case 'b': e.sig = BAKE_SIG; break; - case 'f': e.sig = OFF_SIG; break; - case 0x1B: e.sig = TERMINATE_SIG; break; - } - - /* dispatch the event into the state machine */ - QHSM_DISPATCH(the_oven, &e, 0U); - } - - QF_onCleanup(); - return 0; -} - -/*..........................................................................*/ -void QF_onStartup(void) { - QF_consoleSetup(); -} -/*..........................................................................*/ -void QF_onCleanup(void) { - QF_consoleCleanup(); -} -/*..........................................................................*/ -void QF_onClockTick(void) { -} - -/*..........................................................................*/ -Q_NORETURN Q_onAssert(char const * const file, int_t const line) { - FPRINTF_S(stderr, "Assertion failed in %s, line %d", file, line); - QF_onCleanup(); - exit(-1); -} diff --git a/examples/workstation/qhsmtst/main.c b/examples/workstation/qhsmtst/main.c deleted file mode 100644 index 2305893a..00000000 --- a/examples/workstation/qhsmtst/main.c +++ /dev/null @@ -1,201 +0,0 @@ -/***************************************************************************** -* Product: QHsmTst Example -* Last updated for: @ref qpc_7_0_0 -* Last updated on: 2021-12-18 -* -* Q u a n t u m L e a P s -* ------------------------ -* Modern Embedded Software -* -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* -* -*****************************************************************************/ -#include "qpc.h" -#include "qhsmtst.h" - -#include "safe_std.h" /* portable "safe" / facilities */ -#include - -Q_DEFINE_THIS_FILE - -/* local objects -----------------------------------------------------------*/ -static FILE *l_outFile = (FILE *)0; -static void dispatch(QSignal sig); - -/*..........................................................................*/ -int main(int argc, char *argv[]) { - - QF_init(); - QF_onStartup(); - - QHsmTst_ctor(); /* instantiate the QHsmTst object */ - - Q_ALLEGE(QS_INIT((void *)0)); - QS_OBJ_DICTIONARY(the_sm); - QS_SIG_DICTIONARY(A_SIG, (void *)0); - QS_SIG_DICTIONARY(B_SIG, (void *)0); - QS_SIG_DICTIONARY(C_SIG, (void *)0); - QS_SIG_DICTIONARY(D_SIG, (void *)0); - QS_SIG_DICTIONARY(E_SIG, (void *)0); - QS_SIG_DICTIONARY(F_SIG, (void *)0); - QS_SIG_DICTIONARY(G_SIG, (void *)0); - QS_SIG_DICTIONARY(H_SIG, (void *)0); - QS_SIG_DICTIONARY(I_SIG, (void *)0); - QS_GLB_FILTER(QS_ALL_RECORDS); - QS_GLB_FILTER(-QS_QF_TICK); - - if (argc > 1) { /* file name provided? */ - l_outFile = fopen(argv[1], "w"); - } - - if (l_outFile == (FILE *)0) { /* interactive version? */ - l_outFile = stdout; /* use the stdout as the output file */ - - PRINTF_S("QHsmTst example, built on %s at %s,\n" - "QP: %s.\nPress ESC to quit...\n", - __DATE__, __TIME__, QP_VERSION_STR); - - QHSM_INIT(the_sm, (void *)0, 0U); /* the top-most initial tran. */ - - for (;;) { /* event loop */ - QEvt e; - int c; - - PRINTF_S("\n", ""); - QS_OUTPUT(); /* handle the QS output */ - - c = (uint8_t)QF_consoleWaitForKey(); - PRINTF_S("%c: ", (c >= ' ') ? c : 'X'); - - if ('a' <= c && c <= 'i') { /* in range? */ - e.sig = (QSignal)(c - 'a' + A_SIG); - } - else if ('A' <= c && c <= 'I') { /* in range? */ - e.sig = (QSignal)(c - 'A' + A_SIG); - } - else if (c == '\33') { /* the ESC key? */ - e.sig = TERMINATE_SIG; /* terminate the interactive test */ - } - else { - e.sig = IGNORE_SIG; - } - - QHSM_DISPATCH(the_sm, &e, 0U); /* dispatch the event */ - } - } - else { /* batch version */ - PRINTF_S("QHsmTst example, built on %s at %s, QP %s\n" - "output saved to %s\n", - __DATE__, __TIME__, QP_VERSION_STR, - argv[1]); - - FPRINTF_S(l_outFile, "QHsmTst example, QP %s\n", - QP_VERSION_STR); - - QHSM_INIT(the_sm, (void *)0, 0U); /* the top-most initial tran. */ - - /* testing of dynamic transitions... */ - dispatch(A_SIG); - dispatch(B_SIG); - dispatch(D_SIG); - dispatch(E_SIG); - dispatch(I_SIG); - dispatch(F_SIG); - dispatch(I_SIG); - dispatch(I_SIG); - dispatch(F_SIG); - dispatch(A_SIG); - dispatch(B_SIG); - dispatch(D_SIG); - dispatch(D_SIG); - dispatch(E_SIG); - dispatch(G_SIG); - dispatch(H_SIG); - dispatch(H_SIG); - dispatch(C_SIG); - dispatch(G_SIG); - dispatch(C_SIG); - dispatch(C_SIG); - - fclose(l_outFile); - } - - QF_onCleanup(); - return 0; -} -/*..........................................................................*/ -Q_NORETURN Q_onAssert(char const * const module, int_t const loc) { - FPRINTF_S(stderr, "Assertion failed in %s:%d\n", module, loc); - QF_onCleanup(); - exit(-1); -} -/*..........................................................................*/ -void BSP_display(char const *msg) { - FPRINTF_S(l_outFile, "%s", msg); -} -/*..........................................................................*/ -void BSP_exit(void) { - PRINTF_S("\n%s\n", "Bye, Bye!"); - QF_onCleanup(); - exit(0); -} -/*..........................................................................*/ -static void dispatch(QSignal sig) { - QEvt e; - Q_REQUIRE((A_SIG <= sig) && (sig <= I_SIG)); - e.sig = sig; - FPRINTF_S(l_outFile, "\n%c:", 'A' + sig - A_SIG); - QHSM_DISPATCH(the_sm, &e, 0U); /* dispatch the event */ - QS_OUTPUT(); /* handle the QS output */ -} - -/*--------------------------------------------------------------------------*/ -void QF_onStartup(void) { - QF_consoleSetup(); -} -/*..........................................................................*/ -void QF_onCleanup(void) { - QF_consoleCleanup(); -} -/*..........................................................................*/ -void QF_onClockTick(void) { -} - -/*--------------------------------------------------------------------------*/ -#ifdef Q_SPY /* define QS callbacks */ - -/*! callback function to execute user commands (dummy definition) */ -void QS_onCommand(uint8_t cmdId, - uint32_t param1, uint32_t param2, uint32_t param3) -{ - /* unused parameters */ - (void)cmdId; - (void)param1; - (void)param2; - (void)param3; -} - -#endif /* Q_SPY */ -/*--------------------------------------------------------------------------*/ - diff --git a/examples/workstation/qhsmtst/qhsmtst.h b/examples/workstation/qhsmtst/qhsmtst.h deleted file mode 100644 index c35bb600..00000000 --- a/examples/workstation/qhsmtst/qhsmtst.h +++ /dev/null @@ -1,62 +0,0 @@ -/*$file${.::qhsmtst.h} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* -* Model: qhsmtst.qm -* File: ${.::qhsmtst.h} -* -* This code has been generated by QM 5.2.4 . -* DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. -* -* SPDX-License-Identifier: GPL-3.0-or-later -* -* This generated code is open source software: you can redistribute it under -* the terms of the GNU General Public License as published by the Free -* Software Foundation. -* -* This code is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -* more details. -* -* NOTE: -* Alternatively, this generated code may be distributed under the terms -* of Quantum Leaps commercial licenses, which expressly supersede the GNU -* General Public License and are specifically designed for licensees -* interested in retaining the proprietary status of their code. -* -* Contact information: -* -* -*/ -/*$endhead${.::qhsmtst.h} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -#ifndef QHSMTST_H -#define QHSMTST_H - -enum QHsmTstSignals { - A_SIG = Q_USER_SIG, - B_SIG, - C_SIG, - D_SIG, - E_SIG, - F_SIG, - G_SIG, - H_SIG, - I_SIG, - TERMINATE_SIG, - IGNORE_SIG, - MAX_SIG -}; - -extern QHsm * const the_sm; /* opaque pointer to the test SM */ - -/*$declare${HSMs::QHsmTst_ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${HSMs::QHsmTst_ctor} ....................................................*/ -void QHsmTst_ctor(void); -/*$enddecl${HSMs::QHsmTst_ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ - -/* BSP functions to dispaly a message and exit */ -void BSP_display(char const *msg); -void BSP_exit(void); - -#endif /* QHSMTST_H */ - diff --git a/examples/workstation/qmsmtst/main.c b/examples/workstation/qmsmtst/main.c deleted file mode 100644 index 6d452ded..00000000 --- a/examples/workstation/qmsmtst/main.c +++ /dev/null @@ -1,201 +0,0 @@ -/***************************************************************************** -* Product: QMsmTst Example -* Last updated for: @ref qpc_7_0_0 -* Last updated on: 2021-12-18 -* -* Q u a n t u m L e a P s -* ------------------------ -* Modern Embedded Software -* -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* -* -*****************************************************************************/ -#include "qpc.h" -#include "qmsmtst.h" - -#include "safe_std.h" /* portable "safe" / facilities */ -#include - -Q_DEFINE_THIS_FILE - -/* local objects -----------------------------------------------------------*/ -static FILE *l_outFile = (FILE *)0; -static void dispatch(QSignal sig); - -/*..........................................................................*/ -int main(int argc, char *argv[]) { - - QF_init(); - QF_onStartup(); - - QMsmTst_ctor(); /* instantiate the QMsmTst object */ - - Q_ALLEGE(QS_INIT((void *)0)); - QS_OBJ_DICTIONARY(the_sm); - QS_SIG_DICTIONARY(A_SIG, (void *)0); - QS_SIG_DICTIONARY(B_SIG, (void *)0); - QS_SIG_DICTIONARY(C_SIG, (void *)0); - QS_SIG_DICTIONARY(D_SIG, (void *)0); - QS_SIG_DICTIONARY(E_SIG, (void *)0); - QS_SIG_DICTIONARY(F_SIG, (void *)0); - QS_SIG_DICTIONARY(G_SIG, (void *)0); - QS_SIG_DICTIONARY(H_SIG, (void *)0); - QS_SIG_DICTIONARY(I_SIG, (void *)0); - QS_GLB_FILTER(QS_ALL_RECORDS); - QS_GLB_FILTER(-QS_QF_TICK); - - if (argc > 1) { /* file name provided? */ - l_outFile = fopen(argv[1], "w"); - } - - if (l_outFile == (FILE *)0) { /* interactive version? */ - l_outFile = stdout; /* use the stdout as the output file */ - - PRINTF_S("QMsmTst example, built on %s at %s,\n" - "QP: %s.\nPress ESC to quit...\n", - __DATE__, __TIME__, QP_VERSION_STR); - - QHSM_INIT(the_sm, (void *)0, 0U); /* the top-most initial tran. */ - - for (;;) { /* event loop */ - QEvt e; - int c; - - PRINTF_S("\n", ""); - QS_OUTPUT(); /* handle the QS output */ - - c = (uint8_t)QF_consoleWaitForKey(); - PRINTF_S("%c: ", (c >= ' ') ? c : 'X'); - - if ('a' <= c && c <= 'i') { /* in range? */ - e.sig = (QSignal)(c - 'a' + A_SIG); - } - else if ('A' <= c && c <= 'I') { /* in range? */ - e.sig = (QSignal)(c - 'A' + A_SIG); - } - else if (c == '\33') { /* the ESC key? */ - e.sig = TERMINATE_SIG; /* terminate the interactive test */ - } - else { - e.sig = IGNORE_SIG; - } - - QHSM_DISPATCH(the_sm, &e, 0U); /* dispatch the event */ - } - } - else { /* batch version */ - PRINTF_S("QMsmTst example, built on %s at %s, QP %s\n" - "output saved to %s\n", - __DATE__, __TIME__, QP_VERSION_STR, - argv[1]); - - FPRINTF_S(l_outFile, "QMsmTst example, QP %s\n", - QP_VERSION_STR); - - QHSM_INIT(the_sm, (void *)0, 0U); /* the top-most initial tran. */ - - /* testing of dynamic transitions... */ - dispatch(A_SIG); - dispatch(B_SIG); - dispatch(D_SIG); - dispatch(E_SIG); - dispatch(I_SIG); - dispatch(F_SIG); - dispatch(I_SIG); - dispatch(I_SIG); - dispatch(F_SIG); - dispatch(A_SIG); - dispatch(B_SIG); - dispatch(D_SIG); - dispatch(D_SIG); - dispatch(E_SIG); - dispatch(G_SIG); - dispatch(H_SIG); - dispatch(H_SIG); - dispatch(C_SIG); - dispatch(G_SIG); - dispatch(C_SIG); - dispatch(C_SIG); - - fclose(l_outFile); - } - - QF_onCleanup(); - return 0; -} -/*..........................................................................*/ -Q_NORETURN Q_onAssert(char const * const module, int_t const loc) { - FPRINTF_S(stderr, "Assertion failed in %s:%d\n", module, loc); - QF_onCleanup(); - exit(-1); -} -/*..........................................................................*/ -void BSP_display(char const *msg) { - FPRINTF_S(l_outFile, "%s", msg); -} -/*..........................................................................*/ -void BSP_exit(void) { - PRINTF_S("\n%s\n", "Bye, Bye!"); - QF_onCleanup(); - exit(0); -} -/*..........................................................................*/ -static void dispatch(QSignal sig) { - QEvt e; - Q_REQUIRE((A_SIG <= sig) && (sig <= I_SIG)); - e.sig = sig; - FPRINTF_S(l_outFile, "\n%c:", 'A' + sig - A_SIG); - QHSM_DISPATCH(the_sm, &e, 0U); /* dispatch the event */ - QS_OUTPUT(); /* handle the QS output */ -} - -/*--------------------------------------------------------------------------*/ -void QF_onStartup(void) { - QF_consoleSetup(); -} -/*..........................................................................*/ -void QF_onCleanup(void) { - QF_consoleCleanup(); -} -/*..........................................................................*/ -void QF_onClockTick(void) { -} - -/*--------------------------------------------------------------------------*/ -#ifdef Q_SPY /* define QS callbacks */ - -/*! callback function to execute user commands (dummy definition) */ -void QS_onCommand(uint8_t cmdId, - uint32_t param1, uint32_t param2, uint32_t param3) -{ - /* unused parameters */ - (void)cmdId; - (void)param1; - (void)param2; - (void)param3; -} - -#endif /* Q_SPY */ -/*--------------------------------------------------------------------------*/ - diff --git a/examples/workstation/qmsmtst/qmsmtst.c b/examples/workstation/qmsmtst/qmsmtst.c deleted file mode 100644 index 772bbe06..00000000 --- a/examples/workstation/qmsmtst/qmsmtst.c +++ /dev/null @@ -1,720 +0,0 @@ -/*$file${.::qmsmtst.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* -* Model: qmsmtst.qm -* File: ${.::qmsmtst.c} -* -* This code has been generated by QM 5.2.4 . -* DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. -* -* SPDX-License-Identifier: GPL-3.0-or-later -* -* This generated code is open source software: you can redistribute it under -* the terms of the GNU General Public License as published by the Free -* Software Foundation. -* -* This code is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -* more details. -* -* NOTE: -* Alternatively, this generated code may be distributed under the terms -* of Quantum Leaps commercial licenses, which expressly supersede the GNU -* General Public License and are specifically designed for licensees -* interested in retaining the proprietary status of their code. -* -* Contact information: -* -* -*/ -/*$endhead${.::qmsmtst.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -#include "qpc.h" -#include "qmsmtst.h" - -/*$declare${SMs::QMsmTst} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${SMs::QMsmTst} ..........................................................*/ -typedef struct { -/* protected: */ - QMsm super; - -/* private: */ - uint8_t foo; -} QMsmTst; - -/* protected: */ -static QState QMsmTst_initial(QMsmTst * const me, void const * const par); -static QState QMsmTst_s (QMsmTst * const me, QEvt const * const e); -static QState QMsmTst_s_e(QMsmTst * const me); -static QState QMsmTst_s_x(QMsmTst * const me); -static QState QMsmTst_s_i(QMsmTst * const me); -static QMState const QMsmTst_s_s = { - QM_STATE_NULL, /* superstate (top) */ - Q_STATE_CAST(&QMsmTst_s), - Q_ACTION_CAST(&QMsmTst_s_e), - Q_ACTION_CAST(&QMsmTst_s_x), - Q_ACTION_CAST(&QMsmTst_s_i) -}; -static QState QMsmTst_s1 (QMsmTst * const me, QEvt const * const e); -static QState QMsmTst_s1_e(QMsmTst * const me); -static QState QMsmTst_s1_x(QMsmTst * const me); -static QState QMsmTst_s1_i(QMsmTst * const me); -static QMState const QMsmTst_s1_s = { - &QMsmTst_s_s, /* superstate */ - Q_STATE_CAST(&QMsmTst_s1), - Q_ACTION_CAST(&QMsmTst_s1_e), - Q_ACTION_CAST(&QMsmTst_s1_x), - Q_ACTION_CAST(&QMsmTst_s1_i) -}; -static QState QMsmTst_s11 (QMsmTst * const me, QEvt const * const e); -static QState QMsmTst_s11_e(QMsmTst * const me); -static QState QMsmTst_s11_x(QMsmTst * const me); -static QMState const QMsmTst_s11_s = { - &QMsmTst_s1_s, /* superstate */ - Q_STATE_CAST(&QMsmTst_s11), - Q_ACTION_CAST(&QMsmTst_s11_e), - Q_ACTION_CAST(&QMsmTst_s11_x), - Q_ACTION_NULL /* no initial tran. */ -}; -static QState QMsmTst_s2 (QMsmTst * const me, QEvt const * const e); -static QState QMsmTst_s2_e(QMsmTst * const me); -static QState QMsmTst_s2_x(QMsmTst * const me); -static QState QMsmTst_s2_i(QMsmTst * const me); -static QMState const QMsmTst_s2_s = { - &QMsmTst_s_s, /* superstate */ - Q_STATE_CAST(&QMsmTst_s2), - Q_ACTION_CAST(&QMsmTst_s2_e), - Q_ACTION_CAST(&QMsmTst_s2_x), - Q_ACTION_CAST(&QMsmTst_s2_i) -}; -static QState QMsmTst_s21 (QMsmTst * const me, QEvt const * const e); -static QState QMsmTst_s21_e(QMsmTst * const me); -static QState QMsmTst_s21_x(QMsmTst * const me); -static QState QMsmTst_s21_i(QMsmTst * const me); -static QMState const QMsmTst_s21_s = { - &QMsmTst_s2_s, /* superstate */ - Q_STATE_CAST(&QMsmTst_s21), - Q_ACTION_CAST(&QMsmTst_s21_e), - Q_ACTION_CAST(&QMsmTst_s21_x), - Q_ACTION_CAST(&QMsmTst_s21_i) -}; -static QState QMsmTst_s211 (QMsmTst * const me, QEvt const * const e); -static QState QMsmTst_s211_e(QMsmTst * const me); -static QState QMsmTst_s211_x(QMsmTst * const me); -static QMState const QMsmTst_s211_s = { - &QMsmTst_s21_s, /* superstate */ - Q_STATE_CAST(&QMsmTst_s211), - Q_ACTION_CAST(&QMsmTst_s211_e), - Q_ACTION_CAST(&QMsmTst_s211_x), - Q_ACTION_NULL /* no initial tran. */ -}; -/*$enddecl${SMs::QMsmTst} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ - -static QMsmTst l_sm; /* the only instance of the QMsmTst class */ - -/* global-scope definitions ---------------------------------------*/ -QHsm * const the_sm = &l_sm.super.super; /* the opaque pointer */ - -/*$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* Check for the minimum required QP version */ -#if (QP_VERSION < 700U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) -#error qpc version 7.0.0 or higher required -#endif -/*$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ - -/*$define${SMs::QMsmTst_ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${SMs::QMsmTst_ctor} .....................................................*/ -void QMsmTst_ctor(void) { - QMsmTst *me = &l_sm; - QMsm_ctor(&me->super, Q_STATE_CAST(&QMsmTst_initial)); -} -/*$enddef${SMs::QMsmTst_ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*$define${SMs::QMsmTst} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${SMs::QMsmTst} ..........................................................*/ - -/*${SMs::QMsmTst::SM} ......................................................*/ -static QState QMsmTst_initial(QMsmTst * const me, void const * const par) { - static struct { - QMState const *target; - QActionHandler act[4]; - } const tatbl_ = { /* tran-action table */ - &QMsmTst_s2_s, /* target state */ - { - Q_ACTION_CAST(&QMsmTst_s_e), /* entry */ - Q_ACTION_CAST(&QMsmTst_s2_e), /* entry */ - Q_ACTION_CAST(&QMsmTst_s2_i), /* initial tran. */ - Q_ACTION_NULL /* zero terminator */ - } - }; - /*${SMs::QMsmTst::SM::initial} */ - (void)par; /* unused parameter */ - me->foo = 0U; - BSP_display("top-INIT;"); - - QS_FUN_DICTIONARY(&QMsmTst_s); - QS_FUN_DICTIONARY(&QMsmTst_s1); - QS_FUN_DICTIONARY(&QMsmTst_s11); - QS_FUN_DICTIONARY(&QMsmTst_s2); - QS_FUN_DICTIONARY(&QMsmTst_s21); - QS_FUN_DICTIONARY(&QMsmTst_s211); - - return QM_TRAN_INIT(&tatbl_); -} - -/*${SMs::QMsmTst::SM::s} ...................................................*/ -/*${SMs::QMsmTst::SM::s} */ -static QState QMsmTst_s_e(QMsmTst * const me) { - BSP_display("s-ENTRY;"); - (void)me; /* unused parameter */ - return QM_ENTRY(&QMsmTst_s_s); -} -/*${SMs::QMsmTst::SM::s} */ -static QState QMsmTst_s_x(QMsmTst * const me) { - BSP_display("s-EXIT;"); - (void)me; /* unused parameter */ - return QM_EXIT(&QMsmTst_s_s); -} -/*${SMs::QMsmTst::SM::s::initial} */ -static QState QMsmTst_s_i(QMsmTst * const me) { - static struct { - QMState const *target; - QActionHandler act[3]; - } const tatbl_ = { /* tran-action table */ - &QMsmTst_s11_s, /* target state */ - { - Q_ACTION_CAST(&QMsmTst_s1_e), /* entry */ - Q_ACTION_CAST(&QMsmTst_s11_e), /* entry */ - Q_ACTION_NULL /* zero terminator */ - } - }; - /*${SMs::QMsmTst::SM::s::initial} */ - BSP_display("s-INIT;"); - return QM_TRAN_INIT(&tatbl_); -} -/*${SMs::QMsmTst::SM::s} */ -static QState QMsmTst_s(QMsmTst * const me, QEvt const * const e) { - QState status_; - switch (e->sig) { - /*${SMs::QMsmTst::SM::s::I} */ - case I_SIG: { - /*${SMs::QMsmTst::SM::s::I::[me->foo]} */ - if (me->foo) { - me->foo = 0U; - BSP_display("s-I;"); - status_ = QM_HANDLED(); - } - else { - status_ = QM_UNHANDLED(); - } - break; - } - /*${SMs::QMsmTst::SM::s::E} */ - case E_SIG: { - static struct { - QMState const *target; - QActionHandler act[3]; - } const tatbl_ = { /* tran-action table */ - &QMsmTst_s11_s, /* target state */ - { - Q_ACTION_CAST(&QMsmTst_s1_e), /* entry */ - Q_ACTION_CAST(&QMsmTst_s11_e), /* entry */ - Q_ACTION_NULL /* zero terminator */ - } - }; - BSP_display("s-E;"); - status_ = QM_TRAN(&tatbl_); - break; - } - /*${SMs::QMsmTst::SM::s::TERMINATE} */ - case TERMINATE_SIG: { - BSP_exit(); - status_ = QM_HANDLED(); - break; - } - default: { - status_ = QM_SUPER(); - break; - } - } - (void)me; /* unused parameter */ - return status_; -} - -/*${SMs::QMsmTst::SM::s::s1} ...............................................*/ -/*${SMs::QMsmTst::SM::s::s1} */ -static QState QMsmTst_s1_e(QMsmTst * const me) { - BSP_display("s1-ENTRY;"); - (void)me; /* unused parameter */ - return QM_ENTRY(&QMsmTst_s1_s); -} -/*${SMs::QMsmTst::SM::s::s1} */ -static QState QMsmTst_s1_x(QMsmTst * const me) { - BSP_display("s1-EXIT;"); - (void)me; /* unused parameter */ - return QM_EXIT(&QMsmTst_s1_s); -} -/*${SMs::QMsmTst::SM::s::s1::initial} */ -static QState QMsmTst_s1_i(QMsmTst * const me) { - static struct { - QMState const *target; - QActionHandler act[2]; - } const tatbl_ = { /* tran-action table */ - &QMsmTst_s11_s, /* target state */ - { - Q_ACTION_CAST(&QMsmTst_s11_e), /* entry */ - Q_ACTION_NULL /* zero terminator */ - } - }; - /*${SMs::QMsmTst::SM::s::s1::initial} */ - BSP_display("s1-INIT;"); - return QM_TRAN_INIT(&tatbl_); -} -/*${SMs::QMsmTst::SM::s::s1} */ -static QState QMsmTst_s1(QMsmTst * const me, QEvt const * const e) { - QState status_; - switch (e->sig) { - /*${SMs::QMsmTst::SM::s::s1::I} */ - case I_SIG: { - BSP_display("s1-I;"); - status_ = QM_HANDLED(); - break; - } - /*${SMs::QMsmTst::SM::s::s1::D} */ - case D_SIG: { - /*${SMs::QMsmTst::SM::s::s1::D::[!me->foo]} */ - if (!me->foo) { - static struct { - QMState const *target; - QActionHandler act[3]; - } const tatbl_ = { /* tran-action table */ - &QMsmTst_s_s, /* target state */ - { - Q_ACTION_CAST(&QMsmTst_s1_x), /* exit */ - Q_ACTION_CAST(&QMsmTst_s_i), /* initial tran. */ - Q_ACTION_NULL /* zero terminator */ - } - }; - me->foo = 1U; - BSP_display("s1-D;"); - status_ = QM_TRAN(&tatbl_); - } - else { - status_ = QM_UNHANDLED(); - } - break; - } - /*${SMs::QMsmTst::SM::s::s1::A} */ - case A_SIG: { - static struct { - QMState const *target; - QActionHandler act[4]; - } const tatbl_ = { /* tran-action table */ - &QMsmTst_s1_s, /* target state */ - { - Q_ACTION_CAST(&QMsmTst_s1_x), /* exit */ - Q_ACTION_CAST(&QMsmTst_s1_e), /* entry */ - Q_ACTION_CAST(&QMsmTst_s1_i), /* initial tran. */ - Q_ACTION_NULL /* zero terminator */ - } - }; - BSP_display("s1-A;"); - status_ = QM_TRAN(&tatbl_); - break; - } - /*${SMs::QMsmTst::SM::s::s1::B} */ - case B_SIG: { - static struct { - QMState const *target; - QActionHandler act[2]; - } const tatbl_ = { /* tran-action table */ - &QMsmTst_s11_s, /* target state */ - { - Q_ACTION_CAST(&QMsmTst_s11_e), /* entry */ - Q_ACTION_NULL /* zero terminator */ - } - }; - BSP_display("s1-B;"); - status_ = QM_TRAN(&tatbl_); - break; - } - /*${SMs::QMsmTst::SM::s::s1::F} */ - case F_SIG: { - static struct { - QMState const *target; - QActionHandler act[5]; - } const tatbl_ = { /* tran-action table */ - &QMsmTst_s211_s, /* target state */ - { - Q_ACTION_CAST(&QMsmTst_s1_x), /* exit */ - Q_ACTION_CAST(&QMsmTst_s2_e), /* entry */ - Q_ACTION_CAST(&QMsmTst_s21_e), /* entry */ - Q_ACTION_CAST(&QMsmTst_s211_e), /* entry */ - Q_ACTION_NULL /* zero terminator */ - } - }; - BSP_display("s1-F;"); - status_ = QM_TRAN(&tatbl_); - break; - } - /*${SMs::QMsmTst::SM::s::s1::C} */ - case C_SIG: { - static struct { - QMState const *target; - QActionHandler act[4]; - } const tatbl_ = { /* tran-action table */ - &QMsmTst_s2_s, /* target state */ - { - Q_ACTION_CAST(&QMsmTst_s1_x), /* exit */ - Q_ACTION_CAST(&QMsmTst_s2_e), /* entry */ - Q_ACTION_CAST(&QMsmTst_s2_i), /* initial tran. */ - Q_ACTION_NULL /* zero terminator */ - } - }; - BSP_display("s1-C;"); - status_ = QM_TRAN(&tatbl_); - break; - } - default: { - status_ = QM_SUPER(); - break; - } - } - return status_; -} - -/*${SMs::QMsmTst::SM::s::s1::s11} ..........................................*/ -/*${SMs::QMsmTst::SM::s::s1::s11} */ -static QState QMsmTst_s11_e(QMsmTst * const me) { - BSP_display("s11-ENTRY;"); - (void)me; /* unused parameter */ - return QM_ENTRY(&QMsmTst_s11_s); -} -/*${SMs::QMsmTst::SM::s::s1::s11} */ -static QState QMsmTst_s11_x(QMsmTst * const me) { - BSP_display("s11-EXIT;"); - (void)me; /* unused parameter */ - return QM_EXIT(&QMsmTst_s11_s); -} -/*${SMs::QMsmTst::SM::s::s1::s11} */ -static QState QMsmTst_s11(QMsmTst * const me, QEvt const * const e) { - QState status_; - switch (e->sig) { - /*${SMs::QMsmTst::SM::s::s1::s11::H} */ - case H_SIG: { - static struct { - QMState const *target; - QActionHandler act[4]; - } const tatbl_ = { /* tran-action table */ - &QMsmTst_s_s, /* target state */ - { - Q_ACTION_CAST(&QMsmTst_s11_x), /* exit */ - Q_ACTION_CAST(&QMsmTst_s1_x), /* exit */ - Q_ACTION_CAST(&QMsmTst_s_i), /* initial tran. */ - Q_ACTION_NULL /* zero terminator */ - } - }; - BSP_display("s11-H;"); - status_ = QM_TRAN(&tatbl_); - break; - } - /*${SMs::QMsmTst::SM::s::s1::s11::D} */ - case D_SIG: { - /*${SMs::QMsmTst::SM::s::s1::s11::D::[me->foo]} */ - if (me->foo) { - static struct { - QMState const *target; - QActionHandler act[3]; - } const tatbl_ = { /* tran-action table */ - &QMsmTst_s1_s, /* target state */ - { - Q_ACTION_CAST(&QMsmTst_s11_x), /* exit */ - Q_ACTION_CAST(&QMsmTst_s1_i), /* initial tran. */ - Q_ACTION_NULL /* zero terminator */ - } - }; - me->foo = 0U; - BSP_display("s11-D;"); - status_ = QM_TRAN(&tatbl_); - } - else { - status_ = QM_UNHANDLED(); - } - break; - } - /*${SMs::QMsmTst::SM::s::s1::s11::G} */ - case G_SIG: { - static struct { - QMState const *target; - QActionHandler act[6]; - } const tatbl_ = { /* tran-action table */ - &QMsmTst_s211_s, /* target state */ - { - Q_ACTION_CAST(&QMsmTst_s11_x), /* exit */ - Q_ACTION_CAST(&QMsmTst_s1_x), /* exit */ - Q_ACTION_CAST(&QMsmTst_s2_e), /* entry */ - Q_ACTION_CAST(&QMsmTst_s21_e), /* entry */ - Q_ACTION_CAST(&QMsmTst_s211_e), /* entry */ - Q_ACTION_NULL /* zero terminator */ - } - }; - BSP_display("s11-G;"); - status_ = QM_TRAN(&tatbl_); - break; - } - default: { - status_ = QM_SUPER(); - break; - } - } - return status_; -} - -/*${SMs::QMsmTst::SM::s::s2} ...............................................*/ -/*${SMs::QMsmTst::SM::s::s2} */ -static QState QMsmTst_s2_e(QMsmTst * const me) { - BSP_display("s2-ENTRY;"); - (void)me; /* unused parameter */ - return QM_ENTRY(&QMsmTst_s2_s); -} -/*${SMs::QMsmTst::SM::s::s2} */ -static QState QMsmTst_s2_x(QMsmTst * const me) { - BSP_display("s2-EXIT;"); - (void)me; /* unused parameter */ - return QM_EXIT(&QMsmTst_s2_s); -} -/*${SMs::QMsmTst::SM::s::s2::initial} */ -static QState QMsmTst_s2_i(QMsmTst * const me) { - static struct { - QMState const *target; - QActionHandler act[3]; - } const tatbl_ = { /* tran-action table */ - &QMsmTst_s211_s, /* target state */ - { - Q_ACTION_CAST(&QMsmTst_s21_e), /* entry */ - Q_ACTION_CAST(&QMsmTst_s211_e), /* entry */ - Q_ACTION_NULL /* zero terminator */ - } - }; - /*${SMs::QMsmTst::SM::s::s2::initial} */ - BSP_display("s2-INIT;"); - return QM_TRAN_INIT(&tatbl_); -} -/*${SMs::QMsmTst::SM::s::s2} */ -static QState QMsmTst_s2(QMsmTst * const me, QEvt const * const e) { - QState status_; - switch (e->sig) { - /*${SMs::QMsmTst::SM::s::s2::I} */ - case I_SIG: { - /*${SMs::QMsmTst::SM::s::s2::I::[!me->foo]} */ - if (!me->foo) { - me->foo = 1U; - BSP_display("s2-I;"); - status_ = QM_HANDLED(); - } - else { - status_ = QM_UNHANDLED(); - } - break; - } - /*${SMs::QMsmTst::SM::s::s2::F} */ - case F_SIG: { - static struct { - QMState const *target; - QActionHandler act[4]; - } const tatbl_ = { /* tran-action table */ - &QMsmTst_s11_s, /* target state */ - { - Q_ACTION_CAST(&QMsmTst_s2_x), /* exit */ - Q_ACTION_CAST(&QMsmTst_s1_e), /* entry */ - Q_ACTION_CAST(&QMsmTst_s11_e), /* entry */ - Q_ACTION_NULL /* zero terminator */ - } - }; - BSP_display("s2-F;"); - status_ = QM_TRAN(&tatbl_); - break; - } - /*${SMs::QMsmTst::SM::s::s2::C} */ - case C_SIG: { - static struct { - QMState const *target; - QActionHandler act[4]; - } const tatbl_ = { /* tran-action table */ - &QMsmTst_s1_s, /* target state */ - { - Q_ACTION_CAST(&QMsmTst_s2_x), /* exit */ - Q_ACTION_CAST(&QMsmTst_s1_e), /* entry */ - Q_ACTION_CAST(&QMsmTst_s1_i), /* initial tran. */ - Q_ACTION_NULL /* zero terminator */ - } - }; - BSP_display("s2-C;"); - status_ = QM_TRAN(&tatbl_); - break; - } - default: { - status_ = QM_SUPER(); - break; - } - } - return status_; -} - -/*${SMs::QMsmTst::SM::s::s2::s21} ..........................................*/ -/*${SMs::QMsmTst::SM::s::s2::s21} */ -static QState QMsmTst_s21_e(QMsmTst * const me) { - BSP_display("s21-ENTRY;"); - (void)me; /* unused parameter */ - return QM_ENTRY(&QMsmTst_s21_s); -} -/*${SMs::QMsmTst::SM::s::s2::s21} */ -static QState QMsmTst_s21_x(QMsmTst * const me) { - BSP_display("s21-EXIT;"); - (void)me; /* unused parameter */ - return QM_EXIT(&QMsmTst_s21_s); -} -/*${SMs::QMsmTst::SM::s::s2::s21::initial} */ -static QState QMsmTst_s21_i(QMsmTst * const me) { - static struct { - QMState const *target; - QActionHandler act[2]; - } const tatbl_ = { /* tran-action table */ - &QMsmTst_s211_s, /* target state */ - { - Q_ACTION_CAST(&QMsmTst_s211_e), /* entry */ - Q_ACTION_NULL /* zero terminator */ - } - }; - /*${SMs::QMsmTst::SM::s::s2::s21::initial} */ - BSP_display("s21-INIT;"); - return QM_TRAN_INIT(&tatbl_); -} -/*${SMs::QMsmTst::SM::s::s2::s21} */ -static QState QMsmTst_s21(QMsmTst * const me, QEvt const * const e) { - QState status_; - switch (e->sig) { - /*${SMs::QMsmTst::SM::s::s2::s21::G} */ - case G_SIG: { - static struct { - QMState const *target; - QActionHandler act[5]; - } const tatbl_ = { /* tran-action table */ - &QMsmTst_s1_s, /* target state */ - { - Q_ACTION_CAST(&QMsmTst_s21_x), /* exit */ - Q_ACTION_CAST(&QMsmTst_s2_x), /* exit */ - Q_ACTION_CAST(&QMsmTst_s1_e), /* entry */ - Q_ACTION_CAST(&QMsmTst_s1_i), /* initial tran. */ - Q_ACTION_NULL /* zero terminator */ - } - }; - BSP_display("s21-G;"); - status_ = QM_TRAN(&tatbl_); - break; - } - /*${SMs::QMsmTst::SM::s::s2::s21::A} */ - case A_SIG: { - static struct { - QMState const *target; - QActionHandler act[4]; - } const tatbl_ = { /* tran-action table */ - &QMsmTst_s21_s, /* target state */ - { - Q_ACTION_CAST(&QMsmTst_s21_x), /* exit */ - Q_ACTION_CAST(&QMsmTst_s21_e), /* entry */ - Q_ACTION_CAST(&QMsmTst_s21_i), /* initial tran. */ - Q_ACTION_NULL /* zero terminator */ - } - }; - BSP_display("s21-A;"); - status_ = QM_TRAN(&tatbl_); - break; - } - /*${SMs::QMsmTst::SM::s::s2::s21::B} */ - case B_SIG: { - static struct { - QMState const *target; - QActionHandler act[2]; - } const tatbl_ = { /* tran-action table */ - &QMsmTst_s211_s, /* target state */ - { - Q_ACTION_CAST(&QMsmTst_s211_e), /* entry */ - Q_ACTION_NULL /* zero terminator */ - } - }; - BSP_display("s21-B;"); - status_ = QM_TRAN(&tatbl_); - break; - } - default: { - status_ = QM_SUPER(); - break; - } - } - return status_; -} - -/*${SMs::QMsmTst::SM::s::s2::s21::s211} ....................................*/ -/*${SMs::QMsmTst::SM::s::s2::s21::s211} */ -static QState QMsmTst_s211_e(QMsmTst * const me) { - BSP_display("s211-ENTRY;"); - (void)me; /* unused parameter */ - return QM_ENTRY(&QMsmTst_s211_s); -} -/*${SMs::QMsmTst::SM::s::s2::s21::s211} */ -static QState QMsmTst_s211_x(QMsmTst * const me) { - BSP_display("s211-EXIT;"); - (void)me; /* unused parameter */ - return QM_EXIT(&QMsmTst_s211_s); -} -/*${SMs::QMsmTst::SM::s::s2::s21::s211} */ -static QState QMsmTst_s211(QMsmTst * const me, QEvt const * const e) { - QState status_; - switch (e->sig) { - /*${SMs::QMsmTst::SM::s::s2::s21::s211::H} */ - case H_SIG: { - static struct { - QMState const *target; - QActionHandler act[5]; - } const tatbl_ = { /* tran-action table */ - &QMsmTst_s_s, /* target state */ - { - Q_ACTION_CAST(&QMsmTst_s211_x), /* exit */ - Q_ACTION_CAST(&QMsmTst_s21_x), /* exit */ - Q_ACTION_CAST(&QMsmTst_s2_x), /* exit */ - Q_ACTION_CAST(&QMsmTst_s_i), /* initial tran. */ - Q_ACTION_NULL /* zero terminator */ - } - }; - BSP_display("s211-H;"); - status_ = QM_TRAN(&tatbl_); - break; - } - /*${SMs::QMsmTst::SM::s::s2::s21::s211::D} */ - case D_SIG: { - static struct { - QMState const *target; - QActionHandler act[3]; - } const tatbl_ = { /* tran-action table */ - &QMsmTst_s21_s, /* target state */ - { - Q_ACTION_CAST(&QMsmTst_s211_x), /* exit */ - Q_ACTION_CAST(&QMsmTst_s21_i), /* initial tran. */ - Q_ACTION_NULL /* zero terminator */ - } - }; - BSP_display("s211-D;"); - status_ = QM_TRAN(&tatbl_); - break; - } - default: { - status_ = QM_SUPER(); - break; - } - } - return status_; -} -/*$enddef${SMs::QMsmTst} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ - diff --git a/examples/workstation/qmsmtst/qmsmtst.h b/examples/workstation/qmsmtst/qmsmtst.h deleted file mode 100644 index 57ef458b..00000000 --- a/examples/workstation/qmsmtst/qmsmtst.h +++ /dev/null @@ -1,62 +0,0 @@ -/*$file${.::qmsmtst.h} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* -* Model: qmsmtst.qm -* File: ${.::qmsmtst.h} -* -* This code has been generated by QM 5.2.4 . -* DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. -* -* SPDX-License-Identifier: GPL-3.0-or-later -* -* This generated code is open source software: you can redistribute it under -* the terms of the GNU General Public License as published by the Free -* Software Foundation. -* -* This code is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -* more details. -* -* NOTE: -* Alternatively, this generated code may be distributed under the terms -* of Quantum Leaps commercial licenses, which expressly supersede the GNU -* General Public License and are specifically designed for licensees -* interested in retaining the proprietary status of their code. -* -* Contact information: -* -* -*/ -/*$endhead${.::qmsmtst.h} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -#ifndef QMSMTST_H -#define QMSMTST_H - -enum QMsmTstSignals { - A_SIG = Q_USER_SIG, - B_SIG, - C_SIG, - D_SIG, - E_SIG, - F_SIG, - G_SIG, - H_SIG, - I_SIG, - TERMINATE_SIG, - IGNORE_SIG, - MAX_SIG -}; - -extern QHsm * const the_sm; /* opaque pointer to the test SM */ - -/*$declare${SMs::QMsmTst_ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${SMs::QMsmTst_ctor} .....................................................*/ -void QMsmTst_ctor(void); -/*$enddecl${SMs::QMsmTst_ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ - -/* BSP functions to dispaly a message and exit */ -void BSP_display(char const *msg); -void BSP_exit(void); - -#endif /* QMSMTST_H */ - diff --git a/examples/workstation/reminder/bsp.c b/examples/workstation/reminder/bsp.c deleted file mode 100644 index 088f69e8..00000000 --- a/examples/workstation/reminder/bsp.c +++ /dev/null @@ -1,74 +0,0 @@ -/***************************************************************************** -* Product: Console-based BSP, MinGW -* Last updated for version 5.6.0 -* Last updated on 2015-12-18 -* -* Q u a n t u m L e a P s -* --------------------------- -* innovating embedded systems -* -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* -* -*****************************************************************************/ -#include "qpc.h" -#include "bsp.h" - -#include "safe_std.h" /* portable "safe" / facilities */ -#include - -//Q_DEFINE_THIS_FILE - -/*..........................................................................*/ -void BSP_init(int argc, char *argv[]) { - (void)argc; /* unused parameter */ - (void)argv; /* unused parameter */ -} -/*..........................................................................*/ -void QF_onStartup(void) { - QF_setTickRate(BSP_TICKS_PER_SEC, 30); /* set the desired tick rate */ - QF_consoleSetup(); -} -/*..........................................................................*/ -void QF_onCleanup(void) { - PRINTF_S("\n%s\n", "Bye! Bye!"); - QF_consoleCleanup(); -} -/*..........................................................................*/ -void QF_onClockTick(void) { - int ch; - - QTIMEEVT_TICK_X(0U, &l_clock_tick); /* perform the QF clock tick processing */ - - ch = QF_consoleGetKey(); - if (ch != 0) { /* any key pressed? */ - BSP_onKeyboardInput(ch); - } -} -/*..........................................................................*/ -Q_NORETURN Q_onAssert(char const * const module, int_t const loc) { - FPRINTF_S(stderr, "Assertion failed in %s:%d", module, loc); - QF_onCleanup(); - exit(-1); -} - diff --git a/examples/workstation/reminder/bsp.h b/examples/workstation/reminder/bsp.h deleted file mode 100644 index 678eefe8..00000000 --- a/examples/workstation/reminder/bsp.h +++ /dev/null @@ -1,42 +0,0 @@ -/***************************************************************************** -* Product: Console-based BSP -* Last updated for version 5.4.2 -* Last updated on 2015-06-03 -* -* Q u a n t u m L e a P s -* --------------------------- -* innovating embedded systems -* -* Copyright (C) 2005 Quantum Leaps, www.state-machine.com. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* Web: www.state-machine.com -* -*****************************************************************************/ -#ifndef BSP_H -#define BSP_H - -#define BSP_TICKS_PER_SEC 100U - -void BSP_init(int argc, char *argv[]); -void BSP_onKeyboardInput(uint8_t key); /* process the keyboard scan code */ - -#endif /* BSP_H */ diff --git a/examples/workstation/reminder/reminder.c b/examples/workstation/reminder/reminder.c deleted file mode 100644 index f7b5940e..00000000 --- a/examples/workstation/reminder/reminder.c +++ /dev/null @@ -1,245 +0,0 @@ -/***************************************************************************** -* Product: Reminder state pattern example -* Last updated for version 6.8.0 -* Last updated on 2020-04-01 -* -* Q u a n t u m L e a P s -* ------------------------ -* Modern Embedded Software -* -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* -* -*****************************************************************************/ -#include "qpc.h" -#include "bsp.h" - -#include "safe_std.h" /* portable "safe" / facilities */ - -Q_DEFINE_THIS_FILE - -/*..........................................................................*/ -enum SensorSignals { - TIMEOUT_SIG = Q_USER_SIG, /* the periodic timeout signal */ - DATA_READY_SIG, /* the invented reminder signal */ - TERMINATE_SIG /* terminate the application */ -}; -/*..........................................................................*/ -typedef struct SensorTag { /* the Sensor active object */ - QActive super; /* inherit QActive */ - - QTimeEvt timeEvt; /* private time event generator */ - uint16_t pollCtr; - uint16_t procCtr; -} Sensor; - - -void Sensor_ctor(Sensor * const me); - -/* hierarchical state machine ... */ -static QState Sensor_initial (Sensor * const me, QEvt const * const e); -static QState Sensor_polling (Sensor * const me, QEvt const * const e); -static QState Sensor_processing(Sensor * const me, QEvt const * const e); -static QState Sensor_idle (Sensor * const me, QEvt const * const e); -static QState Sensor_busy (Sensor * const me, QEvt const * const e); -static QState Sensor_final (Sensor * const me, QEvt const * const e); - -/*..........................................................................*/ -void Sensor_ctor(Sensor * const me) { - QActive_ctor(&me->super, (QStateHandler)&Sensor_initial); - QTimeEvt_ctorX(&me->timeEvt, &me->super, TIMEOUT_SIG, 0U); -} - -/* HSM definition ----------------------------------------------------------*/ -QState Sensor_initial(Sensor * const me, QEvt const * const e) { - (void)e; /* unused parameter */ - - me->pollCtr = 0U; - me->procCtr = 0U; - - return Q_TRAN(&Sensor_polling); -} -/*..........................................................................*/ -QState Sensor_final(Sensor * const me, QEvt const * const e) { - QState status; - switch (e->sig) { - case Q_ENTRY_SIG: { - QF_stop(); /* terminate the application */ - status = Q_HANDLED(); - break; - } - default: { - status = Q_SUPER(&QHsm_top); - break; - } - } - return status; -} -/*..........................................................................*/ -QState Sensor_polling(Sensor * const me, QEvt const * const e) { - QState status; - switch (e->sig) { - case Q_ENTRY_SIG: { - /* periodic timeout in 1/2 second and every 1/2 second */ - QTimeEvt_armX(&me->timeEvt, BSP_TICKS_PER_SEC/2, BSP_TICKS_PER_SEC/2); - status = Q_HANDLED(); - break; - } - case Q_EXIT_SIG: { - QTimeEvt_disarm(&me->timeEvt); - status = Q_HANDLED(); - break; - } - case Q_INIT_SIG: { - status = Q_TRAN(&Sensor_processing); - break; - } - case TIMEOUT_SIG: { - /* NOTE: this constant event is statically pre-allocated. - * It can be posted/published as any other event. - */ - static const QEvt reminderEvt = { DATA_READY_SIG, 0U, 0U }; - - ++me->pollCtr; - PRINTF_S("polling %3d\n", me->pollCtr); - if ((me->pollCtr & 0x3U) == 0U) { /* modulo 4 */ - QACTIVE_POST(&me->super, &reminderEvt, me); - } - status = Q_HANDLED(); - break; - } - case TERMINATE_SIG: { - status = Q_TRAN(&Sensor_final); - break; - } - default: { - status = Q_SUPER(&QHsm_top); - break; - } - } - return status; -} -/*..........................................................................*/ -QState Sensor_processing(Sensor * const me, QEvt const * const e) { - QState status; - switch (e->sig) { - case Q_INIT_SIG: { - status = Q_TRAN(&Sensor_idle); - break; - } - default: { - status = Q_SUPER(&Sensor_polling); - break; - } - } - return status; -} -/*..........................................................................*/ -QState Sensor_idle(Sensor * const me, QEvt const * const e) { - QState status; - switch (e->sig) { - case Q_ENTRY_SIG: { - PRINTF_S("%s\n", "idle-ENTRY;"); - status = Q_HANDLED(); - break; - } - case DATA_READY_SIG: { - status = Q_TRAN(&Sensor_busy); - break; - } - default: { - status = Q_SUPER(&Sensor_processing); - break; - } - } - return status; -} -/*..........................................................................*/ -QState Sensor_busy(Sensor * const me, QEvt const * const e) { - QState status; - switch (e->sig) { - case Q_ENTRY_SIG: { - PRINTF_S("%s\n", "busy-ENTRY;"); - status = Q_HANDLED(); - break; - } - case TIMEOUT_SIG: { - ++me->procCtr; - PRINTF_S("processing %3d\n", me->procCtr); - if ((me->procCtr & 0x1U) == 0U) { /* modulo 2 */ - status = Q_TRAN(&Sensor_idle); - } - else { - status = Q_HANDLED(); - } - break; - } - default: { - status = Q_SUPER(&Sensor_processing); - break; - } - } - return status; -} - -/* test harness ============================================================*/ - -/* Local-scope objects -----------------------------------------------------*/ -static Sensor l_sensor; /* the Sensor active object */ -static QEvt const *l_sensorQSto[10]; /* Event queue storage for Sensor */ - -/*..........................................................................*/ -int main(int argc, char *argv[]) { - PRINTF_S("Reminder state pattern\nQP version: %s\n" - "Press ESC to quit...\n", - QP_VERSION_STR); - - BSP_init(argc, argv); /* initialize the BSP */ - - QF_init(); /* initialize the framework and the underlying RT kernel */ - - /* publish-subscribe not used, no call to QF_psInit() */ - /* dynamic event allocation not used, no call to QF_poolInit() */ - - /* instantiate and start the active objects... */ - Sensor_ctor(&l_sensor); - QACTIVE_START(&l_sensor.super, - 1U, - l_sensorQSto, Q_DIM(l_sensorQSto), - (void *)0, 0U, (QEvt *)0); - - return QF_run(); /* run the QF application */ -} -/*..........................................................................*/ -void BSP_onKeyboardInput(uint8_t key) { - switch (key) { - case '\033': { /* ESC pressed? */ - /* NOTE: this constant event is statically pre-allocated. - * It can be posted/published as any other event. - */ - static QEvt const terminateEvt = { TERMINATE_SIG, 0U, 0U }; - QACTIVE_POST((QActive *)&l_sensor, &terminateEvt, (void *)0); - break; - } - } -} diff --git a/examples/workstation/reminder2/bsp.c b/examples/workstation/reminder2/bsp.c deleted file mode 100644 index 088f69e8..00000000 --- a/examples/workstation/reminder2/bsp.c +++ /dev/null @@ -1,74 +0,0 @@ -/***************************************************************************** -* Product: Console-based BSP, MinGW -* Last updated for version 5.6.0 -* Last updated on 2015-12-18 -* -* Q u a n t u m L e a P s -* --------------------------- -* innovating embedded systems -* -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* -* -*****************************************************************************/ -#include "qpc.h" -#include "bsp.h" - -#include "safe_std.h" /* portable "safe" / facilities */ -#include - -//Q_DEFINE_THIS_FILE - -/*..........................................................................*/ -void BSP_init(int argc, char *argv[]) { - (void)argc; /* unused parameter */ - (void)argv; /* unused parameter */ -} -/*..........................................................................*/ -void QF_onStartup(void) { - QF_setTickRate(BSP_TICKS_PER_SEC, 30); /* set the desired tick rate */ - QF_consoleSetup(); -} -/*..........................................................................*/ -void QF_onCleanup(void) { - PRINTF_S("\n%s\n", "Bye! Bye!"); - QF_consoleCleanup(); -} -/*..........................................................................*/ -void QF_onClockTick(void) { - int ch; - - QTIMEEVT_TICK_X(0U, &l_clock_tick); /* perform the QF clock tick processing */ - - ch = QF_consoleGetKey(); - if (ch != 0) { /* any key pressed? */ - BSP_onKeyboardInput(ch); - } -} -/*..........................................................................*/ -Q_NORETURN Q_onAssert(char const * const module, int_t const loc) { - FPRINTF_S(stderr, "Assertion failed in %s:%d", module, loc); - QF_onCleanup(); - exit(-1); -} - diff --git a/examples/workstation/reminder2/bsp.h b/examples/workstation/reminder2/bsp.h deleted file mode 100644 index 678eefe8..00000000 --- a/examples/workstation/reminder2/bsp.h +++ /dev/null @@ -1,42 +0,0 @@ -/***************************************************************************** -* Product: Console-based BSP -* Last updated for version 5.4.2 -* Last updated on 2015-06-03 -* -* Q u a n t u m L e a P s -* --------------------------- -* innovating embedded systems -* -* Copyright (C) 2005 Quantum Leaps, www.state-machine.com. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* Web: www.state-machine.com -* -*****************************************************************************/ -#ifndef BSP_H -#define BSP_H - -#define BSP_TICKS_PER_SEC 100U - -void BSP_init(int argc, char *argv[]); -void BSP_onKeyboardInput(uint8_t key); /* process the keyboard scan code */ - -#endif /* BSP_H */ diff --git a/examples/workstation/reminder2/reminder2.c b/examples/workstation/reminder2/reminder2.c deleted file mode 100644 index f9bf08d5..00000000 --- a/examples/workstation/reminder2/reminder2.c +++ /dev/null @@ -1,240 +0,0 @@ -/*$file${.::reminder2.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* -* Model: reminder2.qm -* File: ${.::reminder2.c} -* -* This code has been generated by QM 5.2.4 . -* DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. -* -* SPDX-License-Identifier: GPL-3.0-or-later -* -* This generated code is open source software: you can redistribute it under -* the terms of the GNU General Public License as published by the Free -* Software Foundation. -* -* This code is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -* more details. -* -* NOTE: -* Alternatively, this generated code may be distributed under the terms -* of Quantum Leaps commercial licenses, which expressly supersede the GNU -* General Public License and are specifically designed for licensees -* interested in retaining the proprietary status of their code. -* -* Contact information: -* -* -*/ -/*$endhead${.::reminder2.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -#include "qpc.h" -#include "bsp.h" - -#include "safe_std.h" /* portable "safe" / facilities */ -#include - -Q_DEFINE_THIS_FILE - -/*..........................................................................*/ -enum ReminderSignals { - CRUNCH_SIG = Q_USER_SIG, /* the invented reminder signal */ - ECHO_SIG, /* check the responsiveness of the system */ - TERMINATE_SIG /* terminate the application */ -}; - -/*$declare${Events::ReminderEvt} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${Events::ReminderEvt} ...................................................*/ -typedef struct { -/* protected: */ - QEvt super; - -/* public: */ - - /* the next iteration to perform */ - uint32_t iter; -} ReminderEvt; -/*$enddecl${Events::ReminderEvt} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ - -/*..........................................................................*/ -/*$declare${Components::Cruncher} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${Components::Cruncher} ..................................................*/ -typedef struct { -/* protected: */ - QActive super; - -/* private: */ - - // internal variable - double sum; -} Cruncher; - -/* public: */ -static void Cruncher_ctor(Cruncher * const me); - -/* protected: */ -static QState Cruncher_initial(Cruncher * const me, void const * const par); -static QState Cruncher_processing(Cruncher * const me, QEvt const * const e); -static QState Cruncher_final(Cruncher * const me, QEvt const * const e); -/*$enddecl${Components::Cruncher} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ - -/*$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* Check for the minimum required QP version */ -#if (QP_VERSION < 700U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) -#error qpc version 7.0.0 or higher required -#endif -/*$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ - -/*$define${Components::Cruncher} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${Components::Cruncher} ..................................................*/ - -/*${Components::Cruncher::ctor} ............................................*/ -static void Cruncher_ctor(Cruncher * const me) { - QActive_ctor(&me->super, Q_STATE_CAST(&Cruncher_initial)); -} - -/*${Components::Cruncher::SM} ..............................................*/ -static QState Cruncher_initial(Cruncher * const me, void const * const par) { - /*${Components::Cruncher::SM::initial} */ - (void)par; /* unused parameter */ - - QS_FUN_DICTIONARY(&Cruncher_processing); - QS_FUN_DICTIONARY(&Cruncher_final); - - return Q_TRAN(&Cruncher_processing); -} - -/*${Components::Cruncher::SM::processing} ..................................*/ -static QState Cruncher_processing(Cruncher * const me, QEvt const * const e) { - QState status_; - switch (e->sig) { - /*${Components::Cruncher::SM::processing} */ - case Q_ENTRY_SIG: { - ReminderEvt *reminder = Q_NEW(ReminderEvt, CRUNCH_SIG); - reminder->iter = 0U; - QACTIVE_POST(&me->super, &reminder->super, me); - me->sum = 0.0; - status_ = Q_HANDLED(); - break; - } - /*${Components::Cruncher::SM::processing::CRUNCH} */ - case CRUNCH_SIG: { - uint32_t i = Q_EVT_CAST(ReminderEvt)->iter; - uint32_t n = i; - i += 100U; - for (; n < i; ++n) { - if ((n & 1) == 0) { - me->sum += 1.0/(2*n + 1); - } - else { - me->sum -= 1.0/(2*n + 1); - } - } - /*${Components::Cruncher::SM::processing::CRUNCH::[i<0x07000000U]} */ - if (i < 0x07000000U) { - ReminderEvt *reminder = Q_NEW(ReminderEvt, CRUNCH_SIG); - reminder->iter = i; - QACTIVE_POST(&me->super, &reminder->super, me); - status_ = Q_HANDLED(); - } - /*${Components::Cruncher::SM::processing::CRUNCH::[else]} */ - else { - PRINTF_S("pi=%16.14f\n", 4.0 * me->sum); - status_ = Q_TRAN(&Cruncher_processing); - } - break; - } - /*${Components::Cruncher::SM::processing::ECHO} */ - case ECHO_SIG: { - PRINTF_S("Echo! pi=%16.14f\n", 4.0 * me->sum); - status_ = Q_HANDLED(); - break; - } - /*${Components::Cruncher::SM::processing::TERMINATE} */ - case TERMINATE_SIG: { - status_ = Q_TRAN(&Cruncher_final); - break; - } - default: { - status_ = Q_SUPER(&QHsm_top); - break; - } - } - return status_; -} - -/*${Components::Cruncher::SM::final} .......................................*/ -static QState Cruncher_final(Cruncher * const me, QEvt const * const e) { - QState status_; - switch (e->sig) { - /*${Components::Cruncher::SM::final} */ - case Q_ENTRY_SIG: { - PRINTF_S("%s\n", "final-ENTRY;"); - QF_stop(); /* terminate the application */ - status_ = Q_HANDLED(); - break; - } - default: { - status_ = Q_SUPER(&QHsm_top); - break; - } - } - return status_; -} -/*$enddef${Components::Cruncher} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ - -/* test harness ============================================================*/ - -/* Local-scope objects -----------------------------------------------------*/ -static Cruncher l_cruncher; /* the Cruncher active object */ -QEvt const *l_cruncherQSto[10]; /* Event queue storage for Cruncher AO */ -static QF_MPOOL_EL(ReminderEvt) l_smlPoolSto[20]; /* storage for small pool */ - -/*..........................................................................*/ -int main(int argc, char *argv[]) { - PRINTF_S("Reminder state pattern\nQP version: %s\n" - "Press 'e' to echo the current value...\n" - "Press ESC to quit...\n", - QP_VERSION_STR); - fflush(stdout); - - Cruncher_ctor(&l_cruncher); - - BSP_init(argc, argv); /* initialize the BSP */ - - QF_init();/* initialize the framework and the underlying RT kernel */ - - /* publish-subscribe not used, no call to QF_psInit() */ - - QF_poolInit(l_smlPoolSto, sizeof(l_smlPoolSto), sizeof(l_smlPoolSto[0])); - - /* instantiate and start the active objects... */ - QACTIVE_START(&l_cruncher.super, - 1U, - l_cruncherQSto, Q_DIM(l_cruncherQSto), - (void *)0, 0U, (QEvt *)0); - - return QF_run(); /* run the QF application */ -} -/*..........................................................................*/ -void BSP_onKeyboardInput(uint8_t key) { - switch (key) { - case 'e': { /* echo the progress so far */ - static QEvt const echoEvt = { ECHO_SIG, 0U, 0U }; - QACTIVE_POST((QActive *)&l_cruncher, &echoEvt, (void *)0); - break; - } - case '\033': { /* ESC pressed? */ - /* NOTE: this constant event is statically pre-allocated. - * It can be posted/published as any other event. - */ - static QEvt const terminateEvt = { TERMINATE_SIG, 0U, 0U }; - QACTIVE_POST((QActive *)&l_cruncher, &terminateEvt, (void *)0); - break; - } - } -} - diff --git a/examples/workstation/reminder2/reminder2_.c b/examples/workstation/reminder2/reminder2_.c deleted file mode 100644 index b7153ee4..00000000 --- a/examples/workstation/reminder2/reminder2_.c +++ /dev/null @@ -1,199 +0,0 @@ -/***************************************************************************** -* Product: Reminder2 state pattern example -* Last updated for version 6.4.0 -* Last updated on 2019-02-08 -* -* Q u a n t u m L e a P s -* ------------------------ -* Modern Embedded Software -* -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* -* -*****************************************************************************/ -#include "qpc.h" -#include "bsp.h" - -#include "safe_std.h" /* portable "safe" / facilities */ -#include - -Q_DEFINE_THIS_FILE - -/*..........................................................................*/ -enum ReminderSignals { - CRUNCH_SIG = Q_USER_SIG, /* the invented reminder signal */ - ECHO_SIG, /* check the responsiveness of the system */ - TERMINATE_SIG /* terminate the application */ -}; - -typedef struct ReminderEvtTag { - QEvt super; - uint32_t iter; /* the next iteration to perform */ -} ReminderEvt; - -/*..........................................................................*/ -typedef struct { /* the Cruncher active object */ - QActive super; /* inherit QActive */ - double sum; /* internal variable */ -} Cruncher; - -void Cruncher_ctor(Cruncher * const me); - -/* hierarchical state machine ... */ -static QState Cruncher_initial (Cruncher * const me, QEvt const * const e); -static QState Cruncher_processing(Cruncher * const me, QEvt const * const e); -static QState Cruncher_final (Cruncher * const me, QEvt const * const e); - -/*--------------------------------------------------------------------------*/ -void Cruncher_ctor(Cruncher * const me) { - QActive_ctor(&me->super, Q_STATE_CAST(&Cruncher_initial)); -} -/*..........................................................................*/ -QState Cruncher_initial(Cruncher * const me, QEvt const * const e) { - (void)e; /* unused parameter */ - return Q_TRAN(&Cruncher_processing); -} -/*..........................................................................*/ -QState Cruncher_processing(Cruncher * const me, QEvt const * const e) { - QState status; - switch (e->sig) { - case Q_ENTRY_SIG: { - ReminderEvt *reminder = Q_NEW(ReminderEvt, CRUNCH_SIG); - reminder->iter = 0U; - QACTIVE_POST((QActive *)me, (QEvt const *)reminder, me); - me->sum = 0.0; - status = Q_HANDLED(); - break; - } - case CRUNCH_SIG: { - uint32_t i = ((ReminderEvt const *)e)->iter; - uint32_t n = i; - i += 100U; - for (; n < i; ++n) { - if ((n & 1U) == 0U) { - me->sum += 1.0/(2*n + 1); - } - else { - me->sum -= 1.0/(2*n + 1); - } - } - if (i < 0x07000000U) { - ReminderEvt *reminder = Q_NEW(ReminderEvt, CRUNCH_SIG); - reminder->iter = i; - QACTIVE_POST((QActive *)me, (QEvt const *)reminder, me); - status = Q_HANDLED(); - } - else { - PRINTF_S("pi=%16.14f\n", 4.0*me->sum); - fflush(stdout); - status = Q_TRAN(&Cruncher_processing); - } - break; - } - case ECHO_SIG: { - PRINTF_S("Echo! pi=%16.14f\n", 4.0*me->sum); - fflush(stdout); - status = Q_HANDLED(); - break; - } - case TERMINATE_SIG: { - status = Q_TRAN(&Cruncher_final); - break; - } - default: { - status = Q_SUPER(&QHsm_top); - break; - } - } - return status; -} -/*..........................................................................*/ -QState Cruncher_final(Cruncher * const me, QEvt const * const e) { - QState status; - switch (e->sig) { - case Q_ENTRY_SIG: { - PRINTF_S("%s\n", "final-ENTRY;"); - fflush(stdout); - QF_stop(); /* terminate the application */ - status = Q_HANDLED(); - break; - } - default: { - status = Q_SUPER(&QHsm_top); - break; - } - } - return status; -} - -/* test harness ============================================================*/ - -/* Local-scope objects -----------------------------------------------------*/ -static Cruncher l_cruncher; /* the Cruncher active object */ -QEvt const *l_cruncherQSto[10]; /* Event queue storage for Cruncher AO */ -static QF_MPOOL_EL(ReminderEvt) l_smlPoolSto[20]; /* storage for small pool */ - -/*..........................................................................*/ -int main(int argc, char *argv[]) { - PRINTF_S("Reminder state pattern\nQP version: %s\n" - "Press 'e' to echo the current value...\n" - "Press ESC to quit...\n", - QP_VERSION_STR); - fflush(stdout); - - Cruncher_ctor(&l_cruncher); - - BSP_init(argc, argv); /* initialize the BSP */ - - QF_init();/* initialize the framework and the underlying RT kernel */ - - /* publish-subscribe not used, no call to QF_psInit() */ - - QF_poolInit(l_smlPoolSto, sizeof(l_smlPoolSto), sizeof(l_smlPoolSto[0])); - - /* instantiate and start the active objects... */ - QACTIVE_START(&l_cruncher.super, - 1U, - l_cruncherQSto, Q_DIM(l_cruncherQSto), - (void *)0, 0U, (QEvt *)0); - - return QF_run(); /* run the QF application */ -} -/*..........................................................................*/ -void BSP_onKeyboardInput(uint8_t key) { - switch (key) { - case 'e': { - static QEvt const echoEvt = { ECHO_SIG, 0U, 0U }; - QACTIVE_POST((QActive *)&l_cruncher, &echoEvt, (void *)0); - break; - } - case '\033': { /* ESC pressed? */ - /* NOTE: this constant event is statically pre-allocated. - * It can be posted/published as any other event. - */ - static QEvt const terminateEvt = { TERMINATE_SIG, 0U, 0U }; - QACTIVE_POST((QActive *)&l_cruncher, &terminateEvt, (void *)0); - break; - } - } -} diff --git a/examples/zephyr/blinky/CMakeLists.txt b/examples/zephyr/blinky/CMakeLists.txt index f9f14e7e..294f9ba8 100644 --- a/examples/zephyr/blinky/CMakeLists.txt +++ b/examples/zephyr/blinky/CMakeLists.txt @@ -28,6 +28,7 @@ option(QSPY "QSPY software tracing" OFF) zephyr_include_directories( ${QPC_DIR}/include ${QPC_DIR}/zephyr + ./src ) target_sources(app PRIVATE ${QPC_DIR}/src/qf/qep_hsm.c @@ -56,7 +57,7 @@ target_sources(app PRIVATE ${QPC_DIR}/src/qs/qs_fp.c ${QPC_DIR}/src/qs/qutest.c ${QPC_DIR}/src/qs/qs_64bit.c - ${QPC_DIR}/include/qstamp.c + ${QPC_DIR}/src/qs/qstamp.c ) endif() diff --git a/examples/zephyr/blinky/README.md b/examples/zephyr/blinky/README.md index 0481f490..f5bd96cd 100644 --- a/examples/zephyr/blinky/README.md +++ b/examples/zephyr/blinky/README.md @@ -33,7 +33,7 @@ nucleo_h743zi To flush the board, type: ``` -west flush +west flash ``` # Sample Output diff --git a/examples/zephyr/blinky/src/blinky.c b/examples/zephyr/blinky/src/blinky.c index faddc4ed..43ad9df4 100644 --- a/examples/zephyr/blinky/src/blinky.c +++ b/examples/zephyr/blinky/src/blinky.c @@ -1,72 +1,83 @@ -/*============================================================================ -* QP/C Real-Time Embedded Framework (RTEF) -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2022-08-24 -* @version Last updated for: Zephyr 3.1.99 and @ref qpc_7_1_0 -* -* @file -* @brief Blinky example -*/ -#include "qpc.h" -#include "blinky.h" -#include "bsp.h" +//============================================================================ +// Product: "Blinky" example +// Last updated for version 7.3.0 +// Last updated on 2023-08-15 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// This program is open source software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Alternatively, this program may be distributed and modified under the +// terms of Quantum Leaps commercial licenses, which expressly supersede +// the GNU General Public License and are specifically designed for +// licensees interested in retaining the proprietary status of their code. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Contact information: +// +// +//============================================================================ +#include "qpc.h" // QP/C real-time embedded framework +#include "blinky.h" // Blinky Application interface +#include "bsp.h" // Board Support Package + +#ifdef Q_SPY +#error The Simple Blinky Application does not support Spy build configuration +#endif //Q_DEFINE_THIS_FILE -/*..........................................................................*/ -typedef struct { /* the Blinky active object */ - QActive super; /* inherit QActive */ +//............................................................................ +// Blinky class... +typedef struct { +// protected: + QActive super; // inherit QActive - QTimeEvt timeEvt; /* private time event generator */ +// private: + QTimeEvt timeEvt; // private time event generator } Blinky; +extern Blinky Blinky_inst; // the Blinky active object -static Blinky l_blinky; /* the Blinky active object */ +// protected: +static QState Blinky_initial(Blinky * const me, void const * const par); +static QState Blinky_off(Blinky * const me, QEvt const * const e); +static QState Blinky_on(Blinky * const me, QEvt const * const e); -QActive * const AO_Blinky = &l_blinky.super; +//---------------------------------------------------------------------------- +Blinky Blinky_inst; +QActive * const AO_Blinky = &Blinky_inst.super; -/* hierarchical state machine ... */ -static QState Blinky_initial(Blinky * const me, QEvt const * const e); -static QState Blinky_off (Blinky * const me, QEvt const * const e); -static QState Blinky_on (Blinky * const me, QEvt const * const e); - -/*..........................................................................*/ +//............................................................................ void Blinky_ctor(void) { - Blinky * const me = &l_blinky; + Blinky * const me = &Blinky_inst; QActive_ctor(&me->super, Q_STATE_CAST(&Blinky_initial)); QTimeEvt_ctorX(&me->timeEvt, &me->super, TIMEOUT_SIG, 0U); } -/* HSM definition ----------------------------------------------------------*/ -QState Blinky_initial(Blinky * const me, QEvt const * const e) { - (void)e; /* avoid compiler warning about unused parameter */ +// HSM definition ---------------------------------------------------------- +QState Blinky_initial(Blinky * const me, void const * const par) { + Q_UNUSED_PAR(par); - /* arm the time event to expire in half a second and every half second */ + // arm the time event to expire in half a second and every half second QTimeEvt_armX(&me->timeEvt, BSP_TICKS_PER_SEC/2U, BSP_TICKS_PER_SEC/2U); + return Q_TRAN(&Blinky_off); } -/*..........................................................................*/ +//............................................................................ QState Blinky_off(Blinky * const me, QEvt const * const e) { QState status; switch (e->sig) { @@ -86,7 +97,7 @@ QState Blinky_off(Blinky * const me, QEvt const * const e) { } return status; } -/*..........................................................................*/ +//............................................................................ QState Blinky_on(Blinky * const me, QEvt const * const e) { QState status; switch (e->sig) { diff --git a/examples/zephyr/blinky/src/blinky.h b/examples/zephyr/blinky/src/blinky.h index 205833a8..c50ddd72 100644 --- a/examples/zephyr/blinky/src/blinky.h +++ b/examples/zephyr/blinky/src/blinky.h @@ -1,47 +1,48 @@ -/*============================================================================ -* QP/C Real-Time Embedded Framework (RTEF) -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2022-08-24 -* @version Last updated for: Zephyr 3.1.99 and @ref qpc_7_1_0 -* -* @file -* @brief Blinky example -*/ -#ifndef BLINKY_H -#define BLINKY_H +//============================================================================ +// Product: "Blinky" example +// Last updated for version 7.2.0 +// Last updated on 2023-01-08 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// This program is open source software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Alternatively, this program may be distributed and modified under the +// terms of Quantum Leaps commercial licenses, which expressly supersede +// the GNU General Public License and are specifically designed for +// licensees interested in retaining the proprietary status of their code. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Contact information: +// +// +//============================================================================ +#ifndef BLINKY_H_ +#define BLINKY_H_ enum BlinkySignals { DUMMY_SIG = Q_USER_SIG, - MAX_PUB_SIG, /* the last published signal */ + MAX_PUB_SIG, // the last published signal TIMEOUT_SIG, - MAX_SIG /* the last signal */ + MAX_SIG // the last signal }; void Blinky_ctor(void); -extern QActive * const AO_Blinky; /* opaque pointer */ - -#endif /* BLINKY_H */ +extern QActive * const AO_Blinky; // opaque pointer +#endif // BLINKY_H_ diff --git a/examples/zephyr/blinky/src/bsp.c b/examples/zephyr/blinky/src/bsp.c index 46328ddd..fbe73333 100644 --- a/examples/zephyr/blinky/src/bsp.c +++ b/examples/zephyr/blinky/src/bsp.c @@ -1,40 +1,46 @@ -/*============================================================================ -* QP/C Real-Time Embedded Framework (RTEF) -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2022-08-24 -* @version Last updated for: Zephyr 3.1.99 and @ref qpc_7_1_0 -* -* @file -* @brief BSP for Zephyr, Blinky example -*/ -#include "qpc.h" -#include "bsp.h" +//============================================================================ +// Product: Blinky example, Zephyr RTOS kernel +// Last updated for: @ref qpc_7_3_0 +// Last updated on 2023-08-24 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. +// +// This program is open source software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Alternatively, this program may be distributed and modified under the +// terms of Quantum Leaps commercial licenses, which expressly supersede +// the GNU General Public License and are specifically designed for +// licensees interested in retaining the proprietary status of their code. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Contact information: +// +// +//============================================================================ +#include "qpc.h" // QP/C real-time embedded framework +#include "blinky.h" // Blinky Application interface +#include "bsp.h" // Board Support Package #include #include -/* other drivers, if necessary ... */ +// add other drivers if necessary... + +// The devicetree node identifier for the "led0" alias. +#define LED0_NODE DT_ALIAS(led0) #ifdef Q_SPY #error Simple Blinky Application does not provide Spy build configuration @@ -42,55 +48,92 @@ Q_DEFINE_THIS_FILE -/* The devicetree node identifier for the "led0" alias. */ -#define LED0_NODE DT_ALIAS(led0) - +// Local-scope objects ----------------------------------------------------- static struct gpio_dt_spec const l_led0 = GPIO_DT_SPEC_GET(LED0_NODE, gpios); -static struct k_timer QF_tick_timer; +static struct k_timer zephyr_tick_timer; -/*..........................................................................*/ -static void QF_tick_function(struct k_timer *tid) { - (void)tid; /* unused parameter */ - QTIMEEVT_TICK_X(0U, (void *)0); +//============================================================================ +// Error handler + +Q_NORETURN Q_onError(char const * const module, int_t const id) { + // NOTE: this implementation of the assertion handler is intended only + // for debugging and MUST be changed for deployment of the application + // (assuming that you ship your production code with assertions enabled). + Q_UNUSED_PAR(module); + Q_UNUSED_PAR(id); + QS_ASSERTION(module, id, 10000U); + Q_PRINTK("\nERROR in %s:%d\n", module, id); + +#ifndef NDEBUG + k_panic(); // debug build: halt the system for error search... +#else + sys_reboot(SYS_REBOOT_COLD); // release build: reboot the system +#endif + for (;;) { // explicitly no-return + } } -/*..........................................................................*/ +//............................................................................ +void assert_failed(char const * const module, int_t const id); // prototype +void assert_failed(char const * const module, int_t const id) { + Q_onError(module, id); +} + +//............................................................................ +static void zephyr_tick_function(struct k_timer *tid); // prototype +static void zephyr_tick_function(struct k_timer *tid) { + Q_UNUSED_PAR(tid); + + QTIMEEVT_TICK_X(0U, &timerID); +} + +//============================================================================ + void BSP_init(void) { int ret = gpio_pin_configure_dt(&l_led0, GPIO_OUTPUT_ACTIVE); Q_ASSERT(ret >= 0); - k_timer_init(&QF_tick_timer, &QF_tick_function, NULL); + k_timer_init(&zephyr_tick_timer, &zephyr_tick_function, NULL); } -/*..........................................................................*/ +//............................................................................ +void BSP_start(void) { + // initialize event pools + static QF_MPOOL_EL(QEvt) smlPoolSto[10]; + QF_poolInit(smlPoolSto, sizeof(smlPoolSto), sizeof(smlPoolSto[0])); + + // initialize publish-subscribe + static QSubscrList subscrSto[MAX_PUB_SIG]; + QActive_psInit(subscrSto, Q_DIM(subscrSto)); + + // instantiate and start AOs/threads... + + static QEvt const *blinkyQueueSto[10]; + static K_THREAD_STACK_DEFINE(blinkyStack, 1024); + Blinky_ctor(); + QACTIVE_START(AO_Blinky, + 1U, // QP prio. of the AO + blinkyQueueSto, // event queue storage + Q_DIM(blinkyQueueSto), // queue length [events] + blinkyStack, // private stack for embOS + K_THREAD_STACK_SIZEOF(blinkyStack), // stack size [Zephyr] + (void *)0); // no initialization param +} +//............................................................................ void BSP_ledOn(void) { - printk("BSP_ledOn\n"); gpio_pin_set_dt(&l_led0, true); } -/*..........................................................................*/ +//............................................................................ void BSP_ledOff(void) { - printk("BSP_ledOff\n"); gpio_pin_set_dt(&l_led0, false); } -/* QF callbacks ============================================================*/ +//============================================================================ +// QF callbacks... void QF_onStartup(void) { - k_timer_start(&QF_tick_timer, K_MSEC(1), K_MSEC(1)); - printk("QF_onStartup\n"); + k_timer_start(&zephyr_tick_timer, K_MSEC(1), K_MSEC(1)); + Q_PRINTK("QF_onStartup\n"); } -/*..........................................................................*/ +//............................................................................ void QF_onCleanup(void) { - printk("QF_onCleanup\n"); + Q_PRINTK("QF_onCleanup\n"); } -/*..........................................................................*/ -Q_NORETURN Q_onAssert(char const * const module, int_t const loc) { - /* - * NOTE: add here your application-specific error handling - */ - printk("\nASSERTION in %s:%d\n", module, loc); - QS_ASSERTION(module, loc, 10000U); /* report assertion to QS */ -#ifndef NDEBUG - k_panic(); /* debug build: halt the system for error search... */ -#else - sys_reboot(SYS_REBOOT_COLD); /* release build: reboot the system */ -#endif -} diff --git a/examples/zephyr/blinky/src/bsp.h b/examples/zephyr/blinky/src/bsp.h index d251cc75..8b869e6a 100644 --- a/examples/zephyr/blinky/src/bsp.h +++ b/examples/zephyr/blinky/src/bsp.h @@ -1,42 +1,49 @@ -/*============================================================================ -* QP/C Real-Time Embedded Framework (RTEF) -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2022-08-24 -* @version Last updated for: Zephyr 3.1.99 and @ref qpc_7_1_0 -* -* @file -* @brief BSP for Zephyr, Blinky example -*/ -#ifndef BSP_H -#define BSP_H +//============================================================================ +// Product: Board Support Package example +// Last Updated for Version: 7.3.0 +// Date of the Last Update: 2023-08-12 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +//============================================================================ +#ifndef BSP_H_ +#define BSP_H_ #define BSP_TICKS_PER_SEC 1000U void BSP_init(void); +void BSP_start(void); +void BSP_displayPaused(uint8_t paused); +void BSP_displayPhilStat(uint8_t n, char const *stat); +void BSP_terminate(int16_t result); + +void BSP_randomSeed(uint32_t seed); // random seed +uint32_t BSP_random(void); // pseudo-random generator + void BSP_ledOn(void); void BSP_ledOff(void); -#endif /* BSP_H */ - +#endif // BSP_H_ diff --git a/examples/zephyr/blinky/src/main.c b/examples/zephyr/blinky/src/main.c index 336753d7..185ed8dc 100644 --- a/examples/zephyr/blinky/src/main.c +++ b/examples/zephyr/blinky/src/main.c @@ -1,64 +1,44 @@ -/*============================================================================ -* QP/C Real-Time Embedded Framework (RTEF) -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2022-08-24 -* @version Last updated for: Zephyr 3.1.99 and @ref qpc_7_1_0 -* -* @file -* @brief main() for Zephyr, Blinky example -*/ -#include "qpc.h" -#include "blinky.h" -#include "bsp.h" - -Q_DEFINE_THIS_FILE - -/*..........................................................................*/ -static QEvt const *l_blinkyQSto[10]; /* event queue storage for Blinky */ -K_THREAD_STACK_DEFINE(l_blinkyStack, 1024); /* stack storage for Blinky */ +//============================================================================ +// APP example +// Last updated for version 7.3.0 +// Last updated on 2023-08-09 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. +// +// This program is open source software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Alternatively, this program may be distributed and modified under the +// terms of Quantum Leaps commercial licenses, which expressly supersede +// the GNU General Public License and are specifically designed for +// licensees interested in retaining the proprietary status of their code. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Contact information: +// +// +//============================================================================ +#include "qpc.h" // QP/C real-time embedded framework +#include "blinky.h" // Blinky Application interface +#include "bsp.h" // Board Support Package +//............................................................................ int main() { - - QF_init(); /* initialize the framework and the underlying RT kernel */ - BSP_init(); /* initialize the Board Support Package */ - - /* publish-subscribe not used, no call to QF_psInit() */ - /* dynamic event allocation not used, no call to QF_poolInit() */ - - /* instantiate and start the active objects... */ - Blinky_ctor(); - QActive_setAttr(AO_Blinky, - 0, /* thread options */ - "Blinky"); /* thread name */ - QACTIVE_START(AO_Blinky, /* AO pointer to start */ - 1U, /* unique QP priority of the AO */ - l_blinkyQSto, /* storage for the AO's queue */ - Q_DIM(l_blinkyQSto), /* length of the queue [entries] */ - (void *)l_blinkyStack, /* stack storage */ - K_THREAD_STACK_SIZEOF(l_blinkyStack), /* stack size [bytes] */ - (void *)0); /* initial event (or 0) */ - - return QF_run(); /* run the QF application */ + QF_init(); // initialize the framework and the underlying RT kernel + BSP_init(); // initialize the BSP + BSP_start(); // start the AOs/Threads + return QF_run(); // run the QF application } diff --git a/examples/zephyr/blinky/src/qp_config.h b/examples/zephyr/blinky/src/qp_config.h new file mode 100644 index 00000000..0aeffde2 --- /dev/null +++ b/examples/zephyr/blinky/src/qp_config.h @@ -0,0 +1,41 @@ +//============================================================================ +// QP configuration file example +// Last updated for version: 7.3.0 +// Last updated on: 2023-09-02 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +//============================================================================ +#ifndef QP_CONFIG_H_ +#define QP_CONFIG_H_ + +// NOTE: +// The QP configuration takes effect only when the macro QP_CONFIG +// is defined on the command-line to the compiler for all QP source files. + +#define QF_MAX_ACTIVE 64U + +#endif // QP_CONFIG_H_ diff --git a/examples/zephyr/dpp/CMakeLists.txt b/examples/zephyr/dpp/CMakeLists.txt index e778705f..8cc6d019 100644 --- a/examples/zephyr/dpp/CMakeLists.txt +++ b/examples/zephyr/dpp/CMakeLists.txt @@ -29,6 +29,7 @@ option(QSPY "QSPY software tracing" OFF) zephyr_include_directories( ${QPC_DIR}/include ${QPC_DIR}/zephyr + ./src ) target_sources(app PRIVATE ${QPC_DIR}/src/qf/qep_hsm.c @@ -57,7 +58,7 @@ target_sources(app PRIVATE ${QPC_DIR}/src/qs/qs_fp.c ${QPC_DIR}/src/qs/qutest.c ${QPC_DIR}/src/qs/qs_64bit.c - ${QPC_DIR}/include/qstamp.c + ${QPC_DIR}/src/qs/qstamp.c ) endif() diff --git a/examples/zephyr/dpp/README.md b/examples/zephyr/dpp/README.md index 3c5a984f..752832a9 100644 --- a/examples/zephyr/dpp/README.md +++ b/examples/zephyr/dpp/README.md @@ -47,6 +47,6 @@ QP/Spy is configured. # Flashing the Board To flush the board, type: ``` -west flush +west flash ``` diff --git a/examples/zephyr/dpp/dpp.qm b/examples/zephyr/dpp/dpp.qm deleted file mode 100644 index 27670b13..00000000 --- a/examples/zephyr/dpp/dpp.qm +++ /dev/null @@ -1,487 +0,0 @@ - - - Dining Philosopher Problem example - - - - - - - - - - - - - - - - - The array of static insts of the Philo class (Singleton pattern) - - - - - - - - static uint8_t registered = (uint8_t)0; /* starts off with 0, per C-standard */ -(void)par; /* unused parameter */ -if (registered == (uint8_t)0) { - registered = (uint8_t)1; - - QS_OBJ_DICTIONARY(&Philo_inst[0]); - QS_OBJ_DICTIONARY(&Philo_inst[0].timeEvt); - QS_OBJ_DICTIONARY(&Philo_inst[1]); - QS_OBJ_DICTIONARY(&Philo_inst[1].timeEvt); - QS_OBJ_DICTIONARY(&Philo_inst[2]); - QS_OBJ_DICTIONARY(&Philo_inst[2].timeEvt); - QS_OBJ_DICTIONARY(&Philo_inst[3]); - QS_OBJ_DICTIONARY(&Philo_inst[3].timeEvt); - QS_OBJ_DICTIONARY(&Philo_inst[4]); - QS_OBJ_DICTIONARY(&Philo_inst[4].timeEvt); - - QS_FUN_DICTIONARY(&Philo_initial); - QS_FUN_DICTIONARY(&Philo_thinking); - QS_FUN_DICTIONARY(&Philo_hungry); - QS_FUN_DICTIONARY(&Philo_eating); -} -QS_SIG_DICTIONARY(HUNGRY_SIG, me); /* signal for each Philos */ -QS_SIG_DICTIONARY(TIMEOUT_SIG, me); /* signal for each Philos */ - -QActive_subscribe(&me->super, EAT_SIG); -QActive_subscribe(&me->super, TEST_SIG); - - - - - - - QTimeEvt_armX(&me->timeEvt, THINK_TIME, 0U); - QTimeEvt_disarm(&me->timeEvt); - - - - - - - - - /* EAT or DONE must be for other Philos than this one */ -Q_ASSERT(Q_EVT_CAST(TableEvt)->philoNum != PHILO_ID(me)); - - - - - - - - - - - - - - - - - - TableEvt *pe = Q_NEW(TableEvt, HUNGRY_SIG); -pe->philoNum = PHILO_ID(me); -QACTIVE_POST(AO_Table, &pe->super, me); - - - - - Q_EVT_CAST(TableEvt)->philoNum == PHILO_ID(me) - - - - - - - - - - - /* DONE must be for other Philos than this one */ -Q_ASSERT(Q_EVT_CAST(TableEvt)->philoNum != PHILO_ID(me)); - - - - - - - - - - - QTimeEvt_armX(&me->timeEvt, EAT_TIME, 0U); - TableEvt *pe = Q_NEW(TableEvt, DONE_SIG); -pe->philoNum = PHILO_ID(me); -QACTIVE_PUBLISH(&pe->super, &me->super); - - - - - - - - - /* EAT or DONE must be for other Philos than this one */ -Q_ASSERT(Q_EVT_CAST(TableEvt)->philoNum != PHILO_ID(me)); - - - - - - - - - - - - - - - - - The only static inst of the Table class (Singleton pattern) - - - - - - - - - - uint8_t n; -(void)par; /* unused parameter */ - -QS_OBJ_DICTIONARY(&Table_inst); - -QS_SIG_DICTIONARY(DONE_SIG, (void *)0); /* global signals */ -QS_SIG_DICTIONARY(EAT_SIG, (void *)0); -QS_SIG_DICTIONARY(PAUSE_SIG, (void *)0); -QS_SIG_DICTIONARY(SERVE_SIG, (void *)0); -QS_SIG_DICTIONARY(TEST_SIG, (void *)0); - -QS_SIG_DICTIONARY(HUNGRY_SIG, me); /* signal just for Table */ - -QActive_subscribe(&me->super, DONE_SIG); -QActive_subscribe(&me->super, PAUSE_SIG); -QActive_subscribe(&me->super, SERVE_SIG); -QActive_subscribe(&me->super, TEST_SIG); - -for (n = 0U; n < N_PHILO; ++n) { - me->fork[n] = FREE; - me->isHungry[n] = 0U; - BSP_displayPhilStat(n, "thinking"); -} - - - - - - - - - - - - - - - Q_ERROR(); - - - - - - - uint8_t n; -for (n = 0U; n < N_PHILO; ++n) { /* give permissions to eat... */ - if ((me->isHungry[n] != 0U) - && (me->fork[LEFT(n)] == FREE) - && (me->fork[n] == FREE)) - { - TableEvt *te; - - me->fork[LEFT(n)] = USED; - me->fork[n] = USED; - te = Q_NEW(TableEvt, EAT_SIG); - te->philoNum = n; - QACTIVE_PUBLISH(&te->super, &me->super); - me->isHungry[n] = 0U; - BSP_displayPhilStat(n, "eating "); - } -} - - - uint8_t n, m; - -n = Q_EVT_CAST(TableEvt)->philoNum; -/* phil ID must be in range and he must be not hungry */ -Q_ASSERT((n < N_PHILO) && (me->isHungry[n] == 0U)); - -BSP_displayPhilStat(n, "hungry "); -m = LEFT(n); - - - (me->fork[m] == FREE) && (me->fork[n] == FREE) - TableEvt *pe; -me->fork[m] = USED; -me->fork[n] = USED; -pe = Q_NEW(TableEvt, EAT_SIG); -pe->philoNum = n; -QACTIVE_PUBLISH(&pe->super, &me->super); -BSP_displayPhilStat(n, "eating "); - - - - - - - else - me->isHungry[n] = 1U; - - - - - - - - - - - uint8_t n, m; -TableEvt *pe; - -n = Q_EVT_CAST(TableEvt)->philoNum; -/* phil ID must be in range and he must be not hungry */ -Q_ASSERT((n < N_PHILO) && (me->isHungry[n] == 0U)); - -BSP_displayPhilStat(n, "thinking"); -m = LEFT(n); -/* both forks of Phil[n] must be used */ -Q_ASSERT((me->fork[n] == USED) && (me->fork[m] == USED)); - -me->fork[m] = FREE; -me->fork[n] = FREE; -m = RIGHT(n); /* check the right neighbor */ - -if ((me->isHungry[m] != 0U) && (me->fork[m] == FREE)) { - me->fork[n] = USED; - me->fork[m] = USED; - me->isHungry[m] = 0U; - pe = Q_NEW(TableEvt, EAT_SIG); - pe->philoNum = m; - QACTIVE_PUBLISH(&pe->super, &me->super); - BSP_displayPhilStat(m, "eating "); -} -m = LEFT(n); /* check the left neighbor */ -n = LEFT(m); /* left fork of the left neighbor */ -if ((me->isHungry[m] != 0U) && (me->fork[n] == FREE)) { - me->fork[m] = USED; - me->fork[n] = USED; - me->isHungry[m] = 0U; - pe = Q_NEW(TableEvt, EAT_SIG); - pe->philoNum = m; - QACTIVE_PUBLISH(&pe->super, &me->super); - BSP_displayPhilStat(m, "eating "); -} - - - - - - - Q_ERROR(); - - - - - - - - - - - - - - - - - BSP_displayPaused(1U); - BSP_displayPaused(0U); - - - - - - - - - uint8_t n = Q_EVT_CAST(TableEvt)->philoNum; -/* philo ID must be in range and he must be not hungry */ -Q_ASSERT((n < N_PHILO) && (me->isHungry[n] == 0U)); -me->isHungry[n] = 1U; -BSP_displayPhilStat(n, "hungry "); - - - - - - - uint8_t n, m; - -n = Q_EVT_CAST(TableEvt)->philoNum; -/* phil ID must be in range and he must be not hungry */ -Q_ASSERT((n < N_PHILO) && (me->isHungry[n] == 0U)); - -BSP_displayPhilStat(n, "thinking"); -m = LEFT(n); -/* both forks of Phil[n] must be used */ -Q_ASSERT((me->fork[n] == USED) && (me->fork[m] == USED)); - -me->fork[m] = FREE; -me->fork[n] = FREE; - - - - - - - - - - - - - - - - - = { /* "opaque" pointers to Philo AO */ - &Philo_inst[0].super, - &Philo_inst[1].super, - &Philo_inst[2].super, - &Philo_inst[3].super, - &Philo_inst[4].super -}; - - - - = &Table_inst.super; /* "opaque" pointer to Table AO */ - - - - uint8_t n; -Philo *me; -for (n = 0U; n < N_PHILO; ++n) { - me = &Philo_inst[n]; - QActive_ctor(&me->super, Q_STATE_CAST(&Philo_initial)); - QTimeEvt_ctorX(&me->timeEvt, &me->super, TIMEOUT_SIG, 0U); -} - - - - Table *me = &Table_inst; -uint8_t n; - -QActive_ctor(&me->super, Q_STATE_CAST(&Table_initial)); - -for (n = 0U; n < N_PHILO; ++n) { - me->fork[n] = FREE; - me->isHungry[n] = 0U; -} - - - - - - - #ifndef DPP_H -#define DPP_H - -enum DPPSignals { - EAT_SIG = Q_USER_SIG, /* published by Table to let a philosopher eat */ - DONE_SIG, /* published by Philosopher when done eating */ - PAUSE_SIG, /* published by BSP to pause serving forks */ - SERVE_SIG, /* published by BSP to serve re-start serving forks */ - TEST_SIG, /* published by BSP to test the application */ - MAX_PUB_SIG, /* the last published signal */ - - HUNGRY_SIG, /* posted direclty to Table from hungry Philo */ - TIMEOUT_SIG, /* used by Philosophers for time events */ - MAX_SIG /* the last signal */ -}; - -$declare(Events::TableEvt) - -/* number of philosophers */ -#define N_PHILO ((uint8_t)5) - -$declare(AOs::Philo_ctor) -$declare(AOs::AO_Philo[N_PHILO]) - -$declare(AOs::Table_ctor) -$declare(AOs::AO_Table) - -#ifdef QP_INC_QXK_H_ - void Test1_ctor(void); - extern QXThread * const XT_Test1; - void Test2_ctor(void); - extern QXThread * const XT_Test2; -#endif /* QP_INC_QXK_H_ */ - -#endif /* DPP_H */ - - - - - #include "qpc.h" -#include "dpp.h" -#include "bsp.h" - -Q_DEFINE_THIS_FILE - -/* Active object class -----------------------------------------------------*/ -$declare${AOs::Philo} - -#define THINK_TIME \ - (QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + (BSP_TICKS_PER_SEC/2U)) -#define EAT_TIME \ - (QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + BSP_TICKS_PER_SEC) - -/* helper macro to provide the ID of Philo "me_" */ -#define PHILO_ID(me_) ((uint8_t)((me_) - &Philo_inst[0])) - -$define${AOs::AO_Philo[N_PHILO]} -$define${AOs::Philo_ctor} -$define${AOs::Philo} - - - - #include "qpc.h" -#include "dpp.h" -#include "bsp.h" - -Q_DEFINE_THIS_FILE - -/* Active object class -----------------------------------------------------*/ -$declare${AOs::Table} - -#define RIGHT(n_) ((uint8_t)(((n_) + (N_PHILO - 1U)) % N_PHILO)) -#define LEFT(n_) ((uint8_t)(((n_) + 1U) % N_PHILO)) -#define FREE ((uint8_t)0) -#define USED ((uint8_t)1) - -$define${AOs::AO_Table} -$define${AOs::Table_ctor} -$define${AOs::Table} - - - diff --git a/examples/zephyr/dpp/src/bsp.c b/examples/zephyr/dpp/src/bsp.c index 7589c9e4..5c4c5753 100644 --- a/examples/zephyr/dpp/src/bsp.c +++ b/examples/zephyr/dpp/src/bsp.c @@ -1,196 +1,248 @@ -/*============================================================================ -* QP/C Real-Time Embedded Framework (RTEF) -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2022-08-24 -* @version Last updated for: Zephyr 3.1.99 and @ref qpc_7_1_0 -* -* @file -* @brief BSP for Zephyr, DPP example -*/ -#include "qpc.h" -#include "dpp.h" -#include "bsp.h" +//============================================================================ +// Product: "Dining Philosophers Problem" example, Zephyr RTOS kernel +// Last updated for: @ref qpc_7_3_0 +// Last updated on 2023-08-24 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. +// +// This program is open source software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Alternatively, this program may be distributed and modified under the +// terms of Quantum Leaps commercial licenses, which expressly supersede +// the GNU General Public License and are specifically designed for +// licensees interested in retaining the proprietary status of their code. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Contact information: +// +// +//============================================================================ +#include "qpc.h" // QP/C real-time embedded framework +#include "dpp.h" // DPP Application interface +#include "bsp.h" // Board Support Package #include #include -/* other drivers, if necessary ... */ +// add other drivers if necessary... + +// The devicetree node identifier for the "led0" alias. +#define LED0_NODE DT_ALIAS(led0) Q_DEFINE_THIS_FILE -/* The devicetree node identifier for the "led0" alias. */ -#define LED0_NODE DT_ALIAS(led0) - -/* Local-scope objects -----------------------------------------------------*/ +// Local-scope objects ----------------------------------------------------- static struct gpio_dt_spec const l_led0 = GPIO_DT_SPEC_GET(LED0_NODE, gpios); -static struct k_timer QF_tick_timer; -static uint32_t l_rnd; /* random seed */ +static struct k_timer zephyr_tick_timer; +static uint32_t l_rnd; // random seed #ifdef Q_SPY - /* QSpy source IDs */ + // QSpy source IDs static QSpyId const timerID = { 0U }; - enum AppRecords { /* application-specific trace records */ + enum AppRecords { // application-specific trace records PHILO_STAT = QS_USER, PAUSED_STAT, - COMMAND_STAT, - TEST_MSG }; #endif -/*..........................................................................*/ -static void QF_tick_function(struct k_timer *tid) { - (void)tid; /* unused parameter */ +//============================================================================ +// Error handler + +Q_NORETURN Q_onError(char const * const module, int_t const id) { + // NOTE: this implementation of the assertion handler is intended only + // for debugging and MUST be changed for deployment of the application + // (assuming that you ship your production code with assertions enabled). + Q_UNUSED_PAR(module); + Q_UNUSED_PAR(id); + QS_ASSERTION(module, id, 10000U); + Q_PRINTK("\nERROR in %s:%d\n", module, id); + +#ifndef NDEBUG + k_panic(); // debug build: halt the system for error search... +#else + sys_reboot(SYS_REBOOT_COLD); // release build: reboot the system +#endif + for (;;) { // explicitly no-return + } +} +//............................................................................ +void assert_failed(char const * const module, int_t const id); // prototype +void assert_failed(char const * const module, int_t const id) { + Q_onError(module, id); +} + +//............................................................................ +static void zephyr_tick_function(struct k_timer *tid); // prototype +static void zephyr_tick_function(struct k_timer *tid) { + Q_UNUSED_PAR(tid); + QTIMEEVT_TICK_X(0U, &timerID); } -/*..........................................................................*/ + +//============================================================================ + void BSP_init(void) { int ret = gpio_pin_configure_dt(&l_led0, GPIO_OUTPUT_ACTIVE); Q_ASSERT(ret >= 0); - k_timer_init(&QF_tick_timer, &QF_tick_function, NULL); + k_timer_init(&zephyr_tick_timer, &zephyr_tick_function, NULL); - //... BSP_randomSeed(1234U); - if (QS_INIT((void *)0) == 0) { /* initialize the QS software tracing */ + // initialize the QS software tracing... + if (QS_INIT((void *)0) == 0) { Q_ERROR(); } - /* object dictionaries... */ - QS_OBJ_DICTIONARY(AO_Table); - for (int n = 0; n < N_PHILO; ++n) { - QS_OBJ_ARR_DICTIONARY(AO_Philo[n], n); - } - QS_OBJ_DICTIONARY(&timerID); + QS_USR_DICTIONARY(PHILO_STAT); QS_USR_DICTIONARY(PAUSED_STAT); - QS_USR_DICTIONARY(COMMAND_STAT); - QS_USR_DICTIONARY(TEST_MSG); - /* setup the QS filters... */ - QS_GLB_FILTER(QS_SM_RECORDS); /* state machine records */ - QS_GLB_FILTER(QS_AO_RECORDS); /* active object records */ - QS_GLB_FILTER(QS_UA_RECORDS); /* all user records */ - QS_GLB_FILTER(TEST_MSG); + QS_ONLY(produce_sig_dict()); + + // setup the QS filters... + QS_GLB_FILTER(QS_ALL_RECORDS); // all records + QS_GLB_FILTER(-QS_QF_TICK); // exclude the clock tick } -/*..........................................................................*/ +//............................................................................ +void BSP_start(void) { + // initialize event pools + static QF_MPOOL_EL(TableEvt) smlPoolSto[2*N_PHILO]; + QF_poolInit(smlPoolSto, sizeof(smlPoolSto), sizeof(smlPoolSto[0])); + + // initialize publish-subscribe + static QSubscrList subscrSto[MAX_PUB_SIG]; + QActive_psInit(subscrSto, Q_DIM(subscrSto)); + + // instantiate and start AOs/threads... + + static QEvt const *philoQueueSto[N_PHILO][10]; + static K_THREAD_STACK_DEFINE(philoStack[N_PHILO], 512); + for (uint8_t n = 0U; n < N_PHILO; ++n) { + Philo_ctor(n); + QACTIVE_START(AO_Philo[n], + n + 3U, // QF-prio. of the AO + philoQueueSto[n], // event queue storage + Q_DIM(philoQueueSto[n]), // queue length [events] + philoStack[n], // private stack for embOS + K_THREAD_STACK_SIZEOF(philoStack[n]), // stack size [Zephyr] + (void *)0); // no initialization param + } + + static QEvt const *tableQueueSto[N_PHILO]; + static K_THREAD_STACK_DEFINE(tableStack, 1024); + Table_ctor(); + QACTIVE_START(AO_Table, + N_PHILO + 7U, // QP prio. of the AO + tableQueueSto, // event queue storage + Q_DIM(tableQueueSto), // queue length [events] + tableStack, // private stack for embOS + K_THREAD_STACK_SIZEOF(tableStack), // stack size [Zephyr] + (void *)0); // no initialization param +} +//............................................................................ void BSP_ledOn(void) { gpio_pin_set_dt(&l_led0, true); } -/*..........................................................................*/ +//............................................................................ void BSP_ledOff(void) { gpio_pin_set_dt(&l_led0, false); } -/*..........................................................................*/ +//............................................................................ void BSP_displayPhilStat(uint8_t n, char const *stat) { + Q_UNUSED_PAR(n); + if (stat[0] == 'e') { BSP_ledOn(); } else { BSP_ledOff(); } - printk("Philo[%d]->%s\n", n, stat); + Q_PRINTK("Philo[%d]->%s\n", n, stat); - QS_BEGIN_ID(PHILO_STAT, AO_Philo[n]->prio) /* app-specific record */ - QS_U8(1, n); /* Philosopher number */ - QS_STR(stat); /* Philosopher status */ - QS_END() /* application-specific record end */ + // app-specific record + QS_BEGIN_ID(PHILO_STAT, AO_Philo[n]->prio) + QS_U8(1, n); // Philosopher number + QS_STR(stat); // Philosopher status + QS_END() } -/*..........................................................................*/ +//............................................................................ void BSP_displayPaused(uint8_t paused) { - if (paused != 0U) { - //BSP_LED_On(LED2); + if (paused) { + //BSP_ledOn(); } else { - //BSP_LED_Off(LED2); + //BSP_ledOff(); } -} -/*..........................................................................*/ -uint32_t BSP_random(void) { /* a very cheap pseudo-random-number generator */ - uint32_t rnd; - /* Some flating point code is to exercise the VFP... */ + QS_BEGIN_ID(PAUSED_STAT, 0U) // app-specific record + QS_U8(1, paused); // Paused status + QS_END() +} +//............................................................................ +uint32_t BSP_random(void) { // a very cheap pseudo-random-number generator + // exercise the FPU with some floating point computations + // NOTE: this code can be only called from a task that created with + // the option OS_TASK_OPT_SAVE_FP. float volatile x = 3.1415926F; x = x + 2.7182818F; - /* "Super-Duper" Linear Congruential Generator (LCG) - * LCG(2^32, 3*7*11*13*23, 0, seed) - */ - rnd = l_rnd * (3U*7U*11U*13U*23U); - l_rnd = rnd; /* set for the next time */ + // "Super-Duper" Linear Congruential Generator (LCG) + // LCG(2^32, 3*7*11*13*23, 0, seed) + // + uint32_t rnd = l_rnd * (3U*7U*11U*13U*23U); + l_rnd = rnd; // set for the next time return (rnd >> 8); } -/*..........................................................................*/ +//............................................................................ void BSP_randomSeed(uint32_t seed) { l_rnd = seed; } -/*..........................................................................*/ +//............................................................................ void BSP_terminate(int16_t result) { - (void)result; + Q_UNUSED_PAR(result); } -/* QF callbacks ============================================================*/ +//============================================================================ +// QF callbacks... void QF_onStartup(void) { - k_timer_start(&QF_tick_timer, K_MSEC(1), K_MSEC(1)); + k_timer_start(&zephyr_tick_timer, K_MSEC(1), K_MSEC(1)); Q_PRINTK("QF_onStartup\n"); } -/*..........................................................................*/ +//............................................................................ void QF_onCleanup(void) { Q_PRINTK("QF_onCleanup\n"); } -/*..........................................................................*/ -Q_NORETURN Q_onAssert(char const * const module, int_t const loc) { - /* - * NOTE: add here your application-specific error handling - */ - printk("\nASSERTION in %s:%d\n", module, loc); - QS_ASSERTION(module, loc, 10000U); /* report assertion to QS */ -#ifndef NDEBUG - k_panic(); /* debug build: halt the system for error search... */ -#else - sys_reboot(SYS_REBOOT_COLD); /* release build: reboot the system */ -#endif -} - -/* QS callbacks ============================================================*/ +// QS callbacks ============================================================== #ifdef Q_SPY #include -/* select the Zephyr shell UART -* NOTE: you can change this to other UART peripheral if desired -*/ +// select the Zephyr shell UART +// NOTE: you can change this to other UART peripheral if desired static struct device const *uart_dev = DEVICE_DT_GET(DT_CHOSEN(zephyr_shell_uart)); -/*..........................................................................*/ +//............................................................................ static void uart_cb(const struct device *dev, void *user_data) { if (!uart_irq_update(uart_dev)) { return; @@ -204,68 +256,70 @@ static void uart_cb(const struct device *dev, void *user_data) { } } } -/*..........................................................................*/ +//............................................................................ uint8_t QS_onStartup(void const *arg) { - static uint8_t qsTxBuf[1024]; /* buffer for QS-TX channel */ - static uint8_t qsRxBuf[256]; /* buffer for QS-RX channel */ + Q_UNUSED_PAR(arg); Q_REQUIRE(uart_dev != (struct device *)0); + static uint8_t qsTxBuf[2*1024]; // buffer for QS-TX channel QS_initBuf (qsTxBuf, sizeof(qsTxBuf)); + + static uint8_t qsRxBuf[128]; // buffer for QS-RX channel QS_rxInitBuf(qsRxBuf, sizeof(qsRxBuf)); // configure interrupt and callback to receive data uart_irq_callback_user_data_set(uart_dev, &uart_cb, (void *)0); uart_irq_rx_enable(uart_dev); - return 1U; /* return success */ + return 1U; // return success } -/*..........................................................................*/ +//............................................................................ void QS_onCleanup(void) { } -/*..........................................................................*/ -QSTimeCtr QS_onGetTime(void) { /* NOTE: invoked with interrupts DISABLED */ +//............................................................................ +QSTimeCtr QS_onGetTime(void) { // NOTE: invoked with interrupts DISABLED return k_cycle_get_32(); } -/*..........................................................................*/ +//............................................................................ void QS_onFlush(void) { - uint16_t len = 0xFFFFU; /* to get as many bytes as available */ + uint16_t len = 0xFFFFU; // to get as many bytes as available uint8_t const *buf; while ((buf = QS_getBlock(&len)) != (uint8_t*)0) { for (; len != 0U; --len, ++buf) { uart_poll_out(uart_dev, *buf); } - len = 0xFFFFU; /* to get as many bytes as available */ + len = 0xFFFFU; // to get as many bytes as available } } -/*..........................................................................*/ +//............................................................................ void QS_doOutput(void) { - uint16_t len = 0xFFFFU; /* big number to get all available bytes */ + uint16_t len = 0xFFFFU; // big number to get all available bytes - QS_CRIT_STAT_ - QS_CRIT_E_(); + QF_CRIT_STAT + QF_CRIT_ENTRY(); uint8_t const *buf = QS_getBlock(&len); - QS_CRIT_X_(); + QF_CRIT_EXIT(); - /* transmit the bytes via the UART... */ + // transmit the bytes via the UART... for (; len != 0U; --len, ++buf) { uart_poll_out(uart_dev, *buf); } } -/*..........................................................................*/ -/*! callback function to reset the target (to be implemented in the BSP) */ +//............................................................................ +//! callback function to reset the target (to be implemented in the BSP) void QS_onReset(void) { sys_reboot(SYS_REBOOT_COLD); } -/*..........................................................................*/ -/*! callback function to execute a user command (to be implemented in BSP) */ +//............................................................................ void QS_onCommand(uint8_t cmdId, uint32_t param1, uint32_t param2, uint32_t param3) { - (void)cmdId; - (void)param1; - (void)param2; - (void)param3; + Q_UNUSED_PAR(cmdId); + Q_UNUSED_PAR(param1); + Q_UNUSED_PAR(param2); + Q_UNUSED_PAR(param3); } -#endif /* Q_SPY */ +#endif // Q_SPY + diff --git a/examples/zephyr/dpp/src/bsp.h b/examples/zephyr/dpp/src/bsp.h index 1f2fa8f5..8b869e6a 100644 --- a/examples/zephyr/dpp/src/bsp.h +++ b/examples/zephyr/dpp/src/bsp.h @@ -1,53 +1,49 @@ -/*============================================================================ -* QP/C Real-Time Embedded Framework (RTEF) -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2022-08-24 -* @version Last updated for: Zephyr 3.1.99 and @ref qpc_7_1_0 -* -* @file -* @brief BSP for Zephyr, DPP example -*/ -#ifndef BSP_H -#define BSP_H +//============================================================================ +// Product: Board Support Package example +// Last Updated for Version: 7.3.0 +// Date of the Last Update: 2023-08-12 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +//============================================================================ +#ifndef BSP_H_ +#define BSP_H_ #define BSP_TICKS_PER_SEC 1000U void BSP_init(void); +void BSP_start(void); void BSP_displayPaused(uint8_t paused); void BSP_displayPhilStat(uint8_t n, char const *stat); void BSP_terminate(int16_t result); -void BSP_randomSeed(uint32_t seed); /* random seed */ -uint32_t BSP_random(void); /* pseudo-random generator */ +void BSP_randomSeed(uint32_t seed); // random seed +uint32_t BSP_random(void); // pseudo-random generator -/* for testing... */ -void BSP_wait4PB1(void); void BSP_ledOn(void); void BSP_ledOff(void); -extern QTicker ticker0; - -#endif /* BSP_H */ - +#endif // BSP_H_ diff --git a/examples/zephyr/dpp/src/dpp.h b/examples/zephyr/dpp/src/dpp.h index 7866c757..e6d1557a 100644 --- a/examples/zephyr/dpp/src/dpp.h +++ b/examples/zephyr/dpp/src/dpp.h @@ -1,92 +1,117 @@ -/*$file${src::dpp.h} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* -* Model: dpp.qm -* File: ${src::dpp.h} -* -* This code has been generated by QM 5.2.4 . -* DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. -* -* SPDX-License-Identifier: GPL-3.0-or-later -* -* This generated code is open source software: you can redistribute it under -* the terms of the GNU General Public License as published by the Free -* Software Foundation. -* -* This code is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -* more details. -* -* NOTE: -* Alternatively, this generated code may be distributed under the terms -* of Quantum Leaps commercial licenses, which expressly supersede the GNU -* General Public License and are specifically designed for licensees -* interested in retaining the proprietary status of their code. -* -* Contact information: -* -* -*/ -/*$endhead${src::dpp.h} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -#ifndef DPP_H -#define DPP_H +//$file${.::dpp.h} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// +// Model: dpp.qm +// File: ${.::dpp.h} +// +// This code has been generated by QM 5.3.0 . +// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. +// +// SPDX-License-Identifier: GPL-3.0-or-later +// +// This generated code is open source software: you can redistribute it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation. +// +// This code is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// NOTE: +// Alternatively, this generated code may be distributed under the terms +// of Quantum Leaps commercial licenses, which expressly supersede the GNU +// General Public License and are specifically designed for licensees +// interested in retaining the proprietary status of their code. +// +// Contact information: +// +// +// +//$endhead${.::dpp.h} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +#ifndef DPP_H_ +#define DPP_H_ -enum DPPSignals { - EAT_SIG = Q_USER_SIG, /* published by Table to let a philosopher eat */ - DONE_SIG, /* published by Philosopher when done eating */ - PAUSE_SIG, /* published by BSP to pause serving forks */ - SERVE_SIG, /* published by BSP to serve re-start serving forks */ - TEST_SIG, /* published by BSP to test the application */ - MAX_PUB_SIG, /* the last published signal */ +//$declare${Shared} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv - HUNGRY_SIG, /* posted direclty to Table from hungry Philo */ - TIMEOUT_SIG, /* used by Philosophers for time events */ - MAX_SIG /* the last signal */ +//${Shared::AppSignals} ...................................................... +enum AppSignals { + EAT_SIG = Q_USER_SIG, // published by Table to let a Philo eat + DONE_SIG, // published by Philo when done eating + PAUSE_SIG, // published by BSP to pause the application + SERVE_SIG, // published by BSP to serve re-start serving forks + TEST_SIG, // published by BSP to test the application + MAX_PUB_SIG, // the last published signal + + TIMEOUT_SIG, // posted by time event to Philo + HUNGRY_SIG, // posted by hungry Philo to Table + MAX_SIG // the last signal }; -/*$declare${Events::TableEvt} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//${Shared::produce_sig_dict} ................................................ +#ifdef Q_SPY +static inline void produce_sig_dict(void) { + QS_SIG_DICTIONARY(EAT_SIG, (void *)0); + QS_SIG_DICTIONARY(DONE_SIG, (void *)0); + QS_SIG_DICTIONARY(PAUSE_SIG, (void *)0); + QS_SIG_DICTIONARY(SERVE_SIG, (void *)0); + QS_SIG_DICTIONARY(TEST_SIG, (void *)0); -/*${Events::TableEvt} ......................................................*/ + QS_SIG_DICTIONARY(TIMEOUT_SIG, (void *)0); + QS_SIG_DICTIONARY(HUNGRY_SIG, (void *)0); +} +#endif // def Q_SPY + +//${Shared::N_PHILO} ......................................................... +#define N_PHILO ((uint8_t)5U) + +//${Shared::TableEvt} ........................................................ typedef struct { -/* protected: */ +// protected: QEvt super; -/* public: */ - uint8_t philoNum; +// public: + uint8_t philoId; } TableEvt; -/*$enddecl${Events::TableEvt} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/* number of philosophers */ -#define N_PHILO ((uint8_t)5) +// public: -/*$declare${AOs::Philo_ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +#ifdef QEVT_DYN_CTOR +static inline TableEvt * TableEvt_ctor(TableEvt * const me, + uint8_t id) +{ + if (me != (TableEvt *)0) { + // don't call QEvt_ctor() because the initialization of all + // QEvt attributes is already done in QF_QF_newX_() + me->philoId = id; + } + return me; +} +#endif // def QEVT_DYN_CTOR -/*${AOs::Philo_ctor} .......................................................*/ -void Philo_ctor(void); -/*$enddecl${AOs::Philo_ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*$declare${AOs::AO_Philo[N_PHILO]} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${AOs::AO_Philo[N_PHILO]} ................................................*/ +//${Shared::AO_Philo[N_PHILO]} ............................................... extern QActive * const AO_Philo[N_PHILO]; -/*$enddecl${AOs::AO_Philo[N_PHILO]} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*$declare${AOs::Table_ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//${Shared::Philo_ctor} ...................................................... +void Philo_ctor(uint_fast8_t const id); -/*${AOs::Table_ctor} .......................................................*/ -void Table_ctor(void); -/*$enddecl${AOs::Table_ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*$declare${AOs::AO_Table} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${AOs::AO_Table} .........................................................*/ +//${Shared::AO_Table} ........................................................ extern QActive * const AO_Table; -/*$enddecl${AOs::AO_Table} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -#ifdef QP_INC_QXK_H_ - void Test1_ctor(void); - extern QXThread * const XT_Test1; - void Test2_ctor(void); - extern QXThread * const XT_Test2; -#endif /* QP_INC_QXK_H_ */ +//${Shared::Table_ctor} ...................................................... +void Table_ctor(void); +//$enddecl${Shared} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -#endif /* DPP_H */ +#ifdef QXK_H_ +extern QXThread * const TH_XThread1; +void XThread1_ctor(void); + +extern QXThread * const TH_XThread2; +void XThread2_ctor(void); + +extern QXSemaphore TH_sema; +extern QXMutex TH_mutex; + +#endif // QXK_H_ + +#endif // DPP_H_ diff --git a/examples/zephyr/dpp/src/dpp.qm b/examples/zephyr/dpp/src/dpp.qm new file mode 100644 index 00000000..ac9f2bc9 --- /dev/null +++ b/examples/zephyr/dpp/src/dpp.qm @@ -0,0 +1,525 @@ + + + Dining Philosopher Problem example + + + + + + + { + EAT_SIG = Q_USER_SIG, // published by Table to let a Philo eat + DONE_SIG, // published by Philo when done eating + PAUSE_SIG, // published by BSP to pause the application + SERVE_SIG, // published by BSP to serve re-start serving forks + TEST_SIG, // published by BSP to test the application + MAX_PUB_SIG, // the last published signal + + TIMEOUT_SIG, // posted by time event to Philo + HUNGRY_SIG, // posted by hungry Philo to Table + MAX_SIG // the last signal +}; + + + + QS_SIG_DICTIONARY(EAT_SIG, (void *)0); +QS_SIG_DICTIONARY(DONE_SIG, (void *)0); +QS_SIG_DICTIONARY(PAUSE_SIG, (void *)0); +QS_SIG_DICTIONARY(SERVE_SIG, (void *)0); +QS_SIG_DICTIONARY(TEST_SIG, (void *)0); + +QS_SIG_DICTIONARY(TIMEOUT_SIG, (void *)0); +QS_SIG_DICTIONARY(HUNGRY_SIG, (void *)0); + + + + ((uint8_t)5U) + + + + + + + + + + if (me != (TableEvt *)0) { + // don't call QEvt_ctor() because the initialization of all + // QEvt attributes is already done in QF_QF_newX_() + me->philoId = id; +} +return me; + + + + + = { + &Philo_inst[0].super, + &Philo_inst[1].super, + &Philo_inst[2].super, + &Philo_inst[3].super, + &Philo_inst[4].super +}; + + + + + + Philo * const me = &Philo_inst[id]; +QActive_ctor(&me->super, Q_STATE_CAST(&Philo_initial)); +QTimeEvt_ctorX(&me->timeEvt, &me->super, TIMEOUT_SIG, 0U), +me->id = (uint8_t)id; + + + + = &Table_inst.super; + + + + Table * const me = &Table_inst; +QActive_ctor(&me->super, Q_STATE_CAST(&Table_initial)); +for (uint8_t n = 0U; n < N_PHILO; ++n) { + me->fork[n] = FREE; + me->isHungry[n] = false; +} + + + + + + + The Philo AO and the N_PHILO instances + + + + + + + + + + + Q_UNUSED_PAR(par); + +QS_OBJ_ARR_DICTIONARY(&Philo_inst[me->id], me->id); +QS_OBJ_ARR_DICTIONARY(&Philo_inst[me->id].timeEvt, me->id); + +QActive_subscribe(&me->super, EAT_SIG); +QActive_subscribe(&me->super, TEST_SIG); + + + + + + + QTimeEvt_armX(&me->timeEvt, think_time(), 0U); + (void)QTimeEvt_disarm(&me->timeEvt); + + + + + + + + + // EAT or DONE must be for other Philos than this one +Q_ASSERT(Q_EVT_CAST(TableEvt)->philoId != me->id); + + + + + + + + + + + + + + + + + + #ifdef QEVT_DYN_CTOR +TableEvt const *pe = Q_NEW(TableEvt, HUNGRY_SIG, me->id); +#else +TableEvt *pe = Q_NEW(TableEvt, HUNGRY_SIG); +pe->philoId = me->id; +#endif +QACTIVE_POST(AO_Table, &pe->super, &me->super); + + + + + Q_EVT_CAST(TableEvt)->philoId == me->id + + + + + + + + + + + // DONE must be for other Philos than this one +Q_ASSERT(Q_EVT_CAST(TableEvt)->philoId != me->id); + + + + + + + + + + + QTimeEvt_armX(&me->timeEvt, eat_time(), 0U); + (void)QTimeEvt_disarm(&me->timeEvt); + +#ifdef QEVT_DYN_CTOR +TableEvt const *pe = Q_NEW(TableEvt, DONE_SIG, me->id); +#else +TableEvt *pe = Q_NEW(TableEvt, DONE_SIG); +pe->philoId = me->id; +#endif +QACTIVE_PUBLISH(&pe->super, &me->super); + + + + + + + + + // EAT or DONE must be for other Philos than this one +Q_ASSERT(Q_EVT_CAST(TableEvt)->philoId != me->id); + + + + + + + + + + + + + + + + + + + + + + + + + Q_UNUSED_PAR(par); + +#ifdef Q_SPY +Table *Table_inst = me; +QS_OBJ_DICTIONARY(Table_inst); +#endif + +QActive_subscribe(&me->super, DONE_SIG); +QActive_subscribe(&me->super, PAUSE_SIG); +QActive_subscribe(&me->super, SERVE_SIG); +QActive_subscribe(&me->super, TEST_SIG); + +for (uint8_t n = 0U; n < N_PHILO; ++n) { + me->fork[n] = FREE; + me->isHungry[n] = false; + BSP_displayPhilStat(n, THINKING); +} + + + + + + + + + + + + + + + Q_ERROR(); + + + + + + + // give permissions to eat... +for (uint8_t n = 0U; n < N_PHILO; ++n) { + if (me->isHungry[n] + && (me->fork[left(n)] == FREE) + && (me->fork[n] == FREE)) + { + me->fork[left(n)] = USED; + me->fork[n] = USED; +#ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, EAT_SIG, n); +#else + TableEvt *pe = Q_NEW(TableEvt, EAT_SIG); + pe->philoId = n; +#endif + QACTIVE_PUBLISH(&pe->super, &me->super); + me->isHungry[n] = false; + BSP_displayPhilStat(n, EATING); + } +} + + + uint8_t n = Q_EVT_CAST(TableEvt)->philoId; + +// phil ID must be in range and he must be not hungry +Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); + +BSP_displayPhilStat(n, HUNGRY); +uint8_t m = left(n); + + + (me->fork[m] == FREE) && (me->fork[n] == FREE) + me->fork[m] = USED; +me->fork[n] = USED; +#ifdef QEVT_DYN_CTOR +TableEvt const *pe = Q_NEW(TableEvt, EAT_SIG, n); +#else +TableEvt *pe = Q_NEW(TableEvt, EAT_SIG); +pe->philoId = n; +#endif +QACTIVE_PUBLISH(&pe->super, &me->super); +BSP_displayPhilStat(n, EATING); + + + + + + + else + me->isHungry[n] = true; + + + + + + + + + + + uint8_t n = Q_EVT_CAST(TableEvt)->philoId; + +// phil ID must be in range and he must be not hungry +Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); + +BSP_displayPhilStat(n, THINKING); +uint8_t m = left(n); + +// both forks of Phil[n] must be used +Q_ASSERT((me->fork[n] == USED) && (me->fork[m] == USED)); + +me->fork[m] = FREE; +me->fork[n] = FREE; +m = right(n); // check the right neighbor + +if (me->isHungry[m] && (me->fork[m] == FREE)) { + me->fork[n] = USED; + me->fork[m] = USED; + me->isHungry[m] = false; +#ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, EAT_SIG, m); +#else + TableEvt *pe = Q_NEW(TableEvt, EAT_SIG); + pe->philoId = m; +#endif + QACTIVE_PUBLISH(&pe->super, &me->super); + BSP_displayPhilStat(m, EATING); +} +m = left(n); // check the left neighbor +n = left(m); // left fork of the left neighbor +if (me->isHungry[m] && (me->fork[n] == FREE)) { + me->fork[m] = USED; + me->fork[n] = USED; + me->isHungry[m] = false; +#ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, EAT_SIG, m); +#else + TableEvt *pe = Q_NEW(TableEvt, EAT_SIG); + pe->philoId = m; +#endif + QACTIVE_PUBLISH(&pe->super, &me->super); + BSP_displayPhilStat(m, EATING); +} + + + + + + + Q_ERROR(); + + + + + + + + + + + + + + + + + BSP_displayPaused(1U); + BSP_displayPaused(0U); + + + + + + + + + uint8_t n = Q_EVT_CAST(TableEvt)->philoId; + +// philo ID must be in range and he must be not hungry +Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); + +me->isHungry[n] = true; +BSP_displayPhilStat(n, HUNGRY); + + + + + + + uint8_t n = Q_EVT_CAST(TableEvt)->philoId; + +// phil ID must be in range and he must be not hungry +Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); + +BSP_displayPhilStat(n, THINKING); +uint8_t m = left(n); + +// both forks of Phil[n] must be used +Q_ASSERT((me->fork[n] == USED) && (me->fork[m] == USED)); + +me->fork[m] = FREE; +me->fork[n] = FREE; + + + + + + + + + + + + + + + + + + + + #ifndef DPP_H_ +#define DPP_H_ + +$declare ${Shared} + +#ifdef QXK_H_ + +extern QXThread * const TH_XThread1; +void XThread1_ctor(void); + +extern QXThread * const TH_XThread2; +void XThread2_ctor(void); + +extern QXSemaphore TH_sema; +extern QXMutex TH_mutex; + +#endif // QXK_H_ + +#endif // DPP_H_ + + + + #include "qpc.h" // QP/C real-time embedded framework +#include "dpp.h" // DPP Application interface +#include "bsp.h" // Board Support Package + +$declare ${AOs::Philo} + +//---------------------------------------------------------------------------- +Q_DEFINE_THIS_FILE + +// helper function to provide a randomized think time for Philos +static QTimeEvtCtr think_time(void); // prototype +static inline QTimeEvtCtr think_time(void) { + return (QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + + (BSP_TICKS_PER_SEC/2U)); +} + +// helper function to provide a randomized eat time for Philos +static QTimeEvtCtr eat_time(void); // prototype +static inline QTimeEvtCtr eat_time(void) { + return (QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + + BSP_TICKS_PER_SEC); +} +//---------------------------------------------------------------------------- + +$define ${Shared::Philo_ctor} +$define ${Shared::AO_Philo[N_PHILO]} +$define ${AOs::Philo} + + + + #include "qpc.h" // QP/C real-time embedded framework +#include "dpp.h" // DPP Application interface +#include "bsp.h" // Board Support Package + +$declare ${AOs::Table} + +//---------------------------------------------------------------------------- +Q_DEFINE_THIS_FILE + +// helper function to provide the RIGHT neighbor of a Philo[n] +static inline uint8_t right(uint8_t const n) { + return (uint8_t)((n + (N_PHILO - 1U)) % N_PHILO); +} + +// helper function to provide the LEFT neighbor of a Philo[n] +static inline uint8_t left(uint8_t const n) { + return (uint8_t)((n + 1U) % N_PHILO); +} + +#define FREE ((uint8_t)0U) +#define USED ((uint8_t)1U) + +#define THINKING "thinking" +#define HUNGRY "hungry " +#define EATING "eating " + +//---------------------------------------------------------------------------- + +$define ${Shared::Table_ctor} +$define ${Shared::AO_Table} +$define ${AOs::Table} + + + diff --git a/examples/zephyr/dpp/src/main.c b/examples/zephyr/dpp/src/main.c index ffe674e9..deac175a 100644 --- a/examples/zephyr/dpp/src/main.c +++ b/examples/zephyr/dpp/src/main.c @@ -1,85 +1,44 @@ -/*============================================================================ -* QP/C Real-Time Embedded Framework (RTEF) -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2022-08-24 -* @version Last updated for: Zephyr 3.1.99 and @ref qpc_7_1_0 -* -* @file -* @brief main() for Zephyr, DPP example -*/ -#include "qpc.h" -#include "dpp.h" -#include "bsp.h" +//============================================================================ +// APP example +// Last updated for version 7.3.0 +// Last updated on 2023-08-09 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. +// +// This program is open source software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Alternatively, this program may be distributed and modified under the +// terms of Quantum Leaps commercial licenses, which expressly supersede +// the GNU General Public License and are specifically designed for +// licensees interested in retaining the proprietary status of their code. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Contact information: +// +// +//============================================================================ +#include "qpc.h" // QP/C real-time embedded framework +#include "dpp.h" // DPP Application interface +#include "bsp.h" // Board Support Package -Q_DEFINE_THIS_FILE - -/*..........................................................................*/ -static QEvt const *tableQueueSto[10]; -K_THREAD_STACK_DEFINE(tableStack, 1024); /* stack storage */ - -static QEvt const *philoQueueSto[N_PHILO][10]; -K_THREAD_STACK_DEFINE(philoStack[N_PHILO], 512); /* stack storage */ - -static QSubscrList subscrSto[MAX_PUB_SIG]; -static QF_MPOOL_EL(TableEvt) smlPoolSto[2*N_PHILO]; /* small pool */ - -int main(void) { - QF_init(); /* initialize the framework and the underlying RT kernel */ - BSP_init(); /* initialize the Board Support Package */ - - /* initialize publish-subscribe... */ - QF_psInit(subscrSto, Q_DIM(subscrSto)); - - /* initialize event pools... */ - QF_poolInit(smlPoolSto, sizeof(smlPoolSto), sizeof(smlPoolSto[0])); - - /* start the active objects... */ - Philo_ctor(); /* instantiate all Philosopher active objects */ - for (uint8_t n = 0U; n < N_PHILO; ++n) { - QActive_setAttr(AO_Philo[n], - 0, /* thread options */ - "Philo"); /* thread name */ - QACTIVE_START(AO_Philo[n], /* AO to start */ - (uint_fast8_t)(n + 1), /* QP priority of the AO */ - philoQueueSto[n], /* event queue storage */ - Q_DIM(philoQueueSto[n]), /* queue length [events] */ - (void *)philoStack[n], /* stack storage */ - K_THREAD_STACK_SIZEOF(philoStack[n]), /* stack size [bytes] */ - (void *)0); /* initialization param */ - } - Table_ctor(); /* instantiate the Table active object */ - QActive_setAttr(AO_Table, - 0, /* thread options */ - "Table"); /* thread name */ - QACTIVE_START(AO_Table, /* AO to start */ - (uint_fast8_t)(N_PHILO + 1), /* QP priority of the AO */ - tableQueueSto, /* event queue storage */ - Q_DIM(tableQueueSto), /* queue length [events] */ - (void *)tableStack, /* stack storage */ - K_THREAD_STACK_SIZEOF(tableStack), /* stack size [bytes] */ - (void *)0); /* initialization param */ - - return QF_run(); /* run the QF application */ +//............................................................................ +int main() { + QF_init(); // initialize the framework and the underlying RT kernel + BSP_init(); // initialize the BSP + BSP_start(); // start the AOs/Threads + return QF_run(); // run the QF application } diff --git a/examples/zephyr/dpp/src/philo.c b/examples/zephyr/dpp/src/philo.c index e16efa06..eb6be531 100644 --- a/examples/zephyr/dpp/src/philo.c +++ b/examples/zephyr/dpp/src/philo.c @@ -1,167 +1,159 @@ -/*$file${src::philo.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* -* Model: dpp.qm -* File: ${src::philo.c} -* -* This code has been generated by QM 5.2.4 . -* DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. -* -* SPDX-License-Identifier: GPL-3.0-or-later -* -* This generated code is open source software: you can redistribute it under -* the terms of the GNU General Public License as published by the Free -* Software Foundation. -* -* This code is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -* more details. -* -* NOTE: -* Alternatively, this generated code may be distributed under the terms -* of Quantum Leaps commercial licenses, which expressly supersede the GNU -* General Public License and are specifically designed for licensees -* interested in retaining the proprietary status of their code. -* -* Contact information: -* -* -*/ -/*$endhead${src::philo.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -#include "qpc.h" -#include "dpp.h" -#include "bsp.h" +//$file${.::philo.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// +// Model: dpp.qm +// File: ${.::philo.c} +// +// This code has been generated by QM 5.3.0 . +// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. +// +// SPDX-License-Identifier: GPL-3.0-or-later +// +// This generated code is open source software: you can redistribute it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation. +// +// This code is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// NOTE: +// Alternatively, this generated code may be distributed under the terms +// of Quantum Leaps commercial licenses, which expressly supersede the GNU +// General Public License and are specifically designed for licensees +// interested in retaining the proprietary status of their code. +// +// Contact information: +// +// +// +//$endhead${.::philo.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +#include "qpc.h" // QP/C real-time embedded framework +#include "dpp.h" // DPP Application interface +#include "bsp.h" // Board Support Package -Q_DEFINE_THIS_FILE +//$declare${AOs::Philo} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/* Active object class -----------------------------------------------------*/ -/*$declare${AOs::Philo} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${AOs::Philo} ............................................................*/ +//${AOs::Philo} .............................................................. typedef struct Philo { -/* protected: */ +// protected: QActive super; -/* public: */ - -/* private: */ +// private: QTimeEvt timeEvt; + uint8_t id; + +// public: } Philo; + extern Philo Philo_inst[N_PHILO]; -/* protected: */ +// protected: static QState Philo_initial(Philo * const me, void const * const par); static QState Philo_thinking(Philo * const me, QEvt const * const e); static QState Philo_hungry(Philo * const me, QEvt const * const e); static QState Philo_eating(Philo * const me, QEvt const * const e); -/*$enddecl${AOs::Philo} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$enddecl${AOs::Philo} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -#define THINK_TIME \ - (QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + (BSP_TICKS_PER_SEC/2U)) -#define EAT_TIME \ - (QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + BSP_TICKS_PER_SEC) +//---------------------------------------------------------------------------- +Q_DEFINE_THIS_FILE -/* helper macro to provide the ID of Philo "me_" */ -#define PHILO_ID(me_) ((uint8_t)((me_) - &Philo_inst[0])) +// helper function to provide a randomized think time for Philos +static QTimeEvtCtr think_time(void); // prototype +static inline QTimeEvtCtr think_time(void) { + return (QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + + (BSP_TICKS_PER_SEC/2U)); +} -/*$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* Check for the minimum required QP version */ -#if (QP_VERSION < 700U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) -#error qpc version 7.0.0 or higher required +// helper function to provide a randomized eat time for Philos +static QTimeEvtCtr eat_time(void); // prototype +static inline QTimeEvtCtr eat_time(void) { + return (QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + + BSP_TICKS_PER_SEC); +} +//---------------------------------------------------------------------------- + +//$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// Check for the minimum required QP version +#if (QP_VERSION < 730U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) +#error qpc version 7.3.0 or higher required #endif -/*$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -/*$define${AOs::AO_Philo[N_PHILO]} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//$define${Shared::Philo_ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/*${AOs::AO_Philo[N_PHILO]} ................................................*/ -QActive * const AO_Philo[N_PHILO] = { /* "opaque" pointers to Philo AO */ +//${Shared::Philo_ctor} ...................................................... +void Philo_ctor(uint_fast8_t const id) { + Philo * const me = &Philo_inst[id]; + QActive_ctor(&me->super, Q_STATE_CAST(&Philo_initial)); + QTimeEvt_ctorX(&me->timeEvt, &me->super, TIMEOUT_SIG, 0U), + me->id = (uint8_t)id; +} +//$enddef${Shared::Philo_ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +//$define${Shared::AO_Philo[N_PHILO]} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${Shared::AO_Philo[N_PHILO]} ............................................... +QActive * const AO_Philo[N_PHILO] = { &Philo_inst[0].super, &Philo_inst[1].super, &Philo_inst[2].super, &Philo_inst[3].super, &Philo_inst[4].super }; -/*$enddef${AOs::AO_Philo[N_PHILO]} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*$define${AOs::Philo_ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//$enddef${Shared::AO_Philo[N_PHILO]} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +//$define${AOs::Philo} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/*${AOs::Philo_ctor} .......................................................*/ -void Philo_ctor(void) { - uint8_t n; - Philo *me; - for (n = 0U; n < N_PHILO; ++n) { - me = &Philo_inst[n]; - QActive_ctor(&me->super, Q_STATE_CAST(&Philo_initial)); - QTimeEvt_ctorX(&me->timeEvt, &me->super, TIMEOUT_SIG, 0U); - } -} -/*$enddef${AOs::Philo_ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*$define${AOs::Philo} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${AOs::Philo} ............................................................*/ +//${AOs::Philo} .............................................................. Philo Philo_inst[N_PHILO]; -/*${AOs::Philo::SM} ........................................................*/ +//${AOs::Philo::SM} .......................................................... static QState Philo_initial(Philo * const me, void const * const par) { - /*${AOs::Philo::SM::initial} */ - static uint8_t registered = (uint8_t)0; /* starts off with 0, per C-standard */ - (void)par; /* unused parameter */ - if (registered == (uint8_t)0) { - registered = (uint8_t)1; + //${AOs::Philo::SM::initial} + Q_UNUSED_PAR(par); - QS_OBJ_DICTIONARY(&Philo_inst[0]); - QS_OBJ_DICTIONARY(&Philo_inst[0].timeEvt); - QS_OBJ_DICTIONARY(&Philo_inst[1]); - QS_OBJ_DICTIONARY(&Philo_inst[1].timeEvt); - QS_OBJ_DICTIONARY(&Philo_inst[2]); - QS_OBJ_DICTIONARY(&Philo_inst[2].timeEvt); - QS_OBJ_DICTIONARY(&Philo_inst[3]); - QS_OBJ_DICTIONARY(&Philo_inst[3].timeEvt); - QS_OBJ_DICTIONARY(&Philo_inst[4]); - QS_OBJ_DICTIONARY(&Philo_inst[4].timeEvt); - - QS_FUN_DICTIONARY(&Philo_initial); - QS_FUN_DICTIONARY(&Philo_thinking); - QS_FUN_DICTIONARY(&Philo_hungry); - QS_FUN_DICTIONARY(&Philo_eating); - } - QS_SIG_DICTIONARY(HUNGRY_SIG, me); /* signal for each Philos */ - QS_SIG_DICTIONARY(TIMEOUT_SIG, me); /* signal for each Philos */ + QS_OBJ_ARR_DICTIONARY(&Philo_inst[me->id], me->id); + QS_OBJ_ARR_DICTIONARY(&Philo_inst[me->id].timeEvt, me->id); QActive_subscribe(&me->super, EAT_SIG); QActive_subscribe(&me->super, TEST_SIG); + + QS_FUN_DICTIONARY(&Philo_thinking); + QS_FUN_DICTIONARY(&Philo_hungry); + QS_FUN_DICTIONARY(&Philo_eating); + return Q_TRAN(&Philo_thinking); } -/*${AOs::Philo::SM::thinking} ..............................................*/ +//${AOs::Philo::SM::thinking} ................................................ static QState Philo_thinking(Philo * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${AOs::Philo::SM::thinking} */ + //${AOs::Philo::SM::thinking} case Q_ENTRY_SIG: { - QTimeEvt_armX(&me->timeEvt, THINK_TIME, 0U); + QTimeEvt_armX(&me->timeEvt, think_time(), 0U); status_ = Q_HANDLED(); break; } - /*${AOs::Philo::SM::thinking} */ + //${AOs::Philo::SM::thinking} case Q_EXIT_SIG: { - QTimeEvt_disarm(&me->timeEvt); + (void)QTimeEvt_disarm(&me->timeEvt); status_ = Q_HANDLED(); break; } - /*${AOs::Philo::SM::thinking::TIMEOUT} */ + //${AOs::Philo::SM::thinking::TIMEOUT} case TIMEOUT_SIG: { status_ = Q_TRAN(&Philo_hungry); break; } - /*${AOs::Philo::SM::thinking::EAT, DONE} */ - case EAT_SIG: /* intentionally fall through */ + //${AOs::Philo::SM::thinking::EAT, DONE} + case EAT_SIG: // intentionally fall through case DONE_SIG: { - /* EAT or DONE must be for other Philos than this one */ - Q_ASSERT(Q_EVT_CAST(TableEvt)->philoNum != PHILO_ID(me)); + // EAT or DONE must be for other Philos than this one + Q_ASSERT(Q_EVT_CAST(TableEvt)->philoId != me->id); status_ = Q_HANDLED(); break; } - /*${AOs::Philo::SM::thinking::TEST} */ + //${AOs::Philo::SM::thinking::TEST} case TEST_SIG: { status_ = Q_HANDLED(); break; @@ -174,22 +166,26 @@ static QState Philo_thinking(Philo * const me, QEvt const * const e) { return status_; } -/*${AOs::Philo::SM::hungry} ................................................*/ +//${AOs::Philo::SM::hungry} .................................................. static QState Philo_hungry(Philo * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${AOs::Philo::SM::hungry} */ + //${AOs::Philo::SM::hungry} case Q_ENTRY_SIG: { + #ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, HUNGRY_SIG, me->id); + #else TableEvt *pe = Q_NEW(TableEvt, HUNGRY_SIG); - pe->philoNum = PHILO_ID(me); - QACTIVE_POST(AO_Table, &pe->super, me); + pe->philoId = me->id; + #endif + QACTIVE_POST(AO_Table, &pe->super, &me->super); status_ = Q_HANDLED(); break; } - /*${AOs::Philo::SM::hungry::EAT} */ + //${AOs::Philo::SM::hungry::EAT} case EAT_SIG: { - /*${AOs::Philo::SM::hungry::EAT::[Q_EVT_CAST(TableEvt)->philoNum=~} */ - if (Q_EVT_CAST(TableEvt)->philoNum == PHILO_ID(me)) { + //${AOs::Philo::SM::hungry::EAT::[e->philoId==me->iid]} + if (Q_EVT_CAST(TableEvt)->philoId == me->id) { status_ = Q_TRAN(&Philo_eating); } else { @@ -197,10 +193,10 @@ static QState Philo_hungry(Philo * const me, QEvt const * const e) { } break; } - /*${AOs::Philo::SM::hungry::DONE} */ + //${AOs::Philo::SM::hungry::DONE} case DONE_SIG: { - /* DONE must be for other Philos than this one */ - Q_ASSERT(Q_EVT_CAST(TableEvt)->philoNum != PHILO_ID(me)); + // DONE must be for other Philos than this one + Q_ASSERT(Q_EVT_CAST(TableEvt)->philoId != me->id); status_ = Q_HANDLED(); break; } @@ -212,34 +208,40 @@ static QState Philo_hungry(Philo * const me, QEvt const * const e) { return status_; } -/*${AOs::Philo::SM::eating} ................................................*/ +//${AOs::Philo::SM::eating} .................................................. static QState Philo_eating(Philo * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${AOs::Philo::SM::eating} */ + //${AOs::Philo::SM::eating} case Q_ENTRY_SIG: { - QTimeEvt_armX(&me->timeEvt, EAT_TIME, 0U); + QTimeEvt_armX(&me->timeEvt, eat_time(), 0U); status_ = Q_HANDLED(); break; } - /*${AOs::Philo::SM::eating} */ + //${AOs::Philo::SM::eating} case Q_EXIT_SIG: { + (void)QTimeEvt_disarm(&me->timeEvt); + + #ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, DONE_SIG, me->id); + #else TableEvt *pe = Q_NEW(TableEvt, DONE_SIG); - pe->philoNum = PHILO_ID(me); + pe->philoId = me->id; + #endif QACTIVE_PUBLISH(&pe->super, &me->super); status_ = Q_HANDLED(); break; } - /*${AOs::Philo::SM::eating::TIMEOUT} */ + //${AOs::Philo::SM::eating::TIMEOUT} case TIMEOUT_SIG: { status_ = Q_TRAN(&Philo_thinking); break; } - /*${AOs::Philo::SM::eating::EAT, DONE} */ - case EAT_SIG: /* intentionally fall through */ + //${AOs::Philo::SM::eating::EAT, DONE} + case EAT_SIG: // intentionally fall through case DONE_SIG: { - /* EAT or DONE must be for other Philos than this one */ - Q_ASSERT(Q_EVT_CAST(TableEvt)->philoNum != PHILO_ID(me)); + // EAT or DONE must be for other Philos than this one + Q_ASSERT(Q_EVT_CAST(TableEvt)->philoId != me->id); status_ = Q_HANDLED(); break; } @@ -250,4 +252,4 @@ static QState Philo_eating(Philo * const me, QEvt const * const e) { } return status_; } -/*$enddef${AOs::Philo} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$enddef${AOs::Philo} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/examples/zephyr/dpp/src/qp_config.h b/examples/zephyr/dpp/src/qp_config.h new file mode 100644 index 00000000..0aeffde2 --- /dev/null +++ b/examples/zephyr/dpp/src/qp_config.h @@ -0,0 +1,41 @@ +//============================================================================ +// QP configuration file example +// Last updated for version: 7.3.0 +// Last updated on: 2023-09-02 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +//============================================================================ +#ifndef QP_CONFIG_H_ +#define QP_CONFIG_H_ + +// NOTE: +// The QP configuration takes effect only when the macro QP_CONFIG +// is defined on the command-line to the compiler for all QP source files. + +#define QF_MAX_ACTIVE 64U + +#endif // QP_CONFIG_H_ diff --git a/examples/zephyr/dpp/src/table.c b/examples/zephyr/dpp/src/table.c index 1743e79a..c3ae02f0 100644 --- a/examples/zephyr/dpp/src/table.c +++ b/examples/zephyr/dpp/src/table.c @@ -1,124 +1,130 @@ -/*$file${src::table.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* -* Model: dpp.qm -* File: ${src::table.c} -* -* This code has been generated by QM 5.2.4 . -* DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. -* -* SPDX-License-Identifier: GPL-3.0-or-later -* -* This generated code is open source software: you can redistribute it under -* the terms of the GNU General Public License as published by the Free -* Software Foundation. -* -* This code is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -* more details. -* -* NOTE: -* Alternatively, this generated code may be distributed under the terms -* of Quantum Leaps commercial licenses, which expressly supersede the GNU -* General Public License and are specifically designed for licensees -* interested in retaining the proprietary status of their code. -* -* Contact information: -* -* -*/ -/*$endhead${src::table.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -#include "qpc.h" -#include "dpp.h" -#include "bsp.h" +//$file${.::table.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// +// Model: dpp.qm +// File: ${.::table.c} +// +// This code has been generated by QM 5.3.0 . +// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. +// +// SPDX-License-Identifier: GPL-3.0-or-later +// +// This generated code is open source software: you can redistribute it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation. +// +// This code is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// NOTE: +// Alternatively, this generated code may be distributed under the terms +// of Quantum Leaps commercial licenses, which expressly supersede the GNU +// General Public License and are specifically designed for licensees +// interested in retaining the proprietary status of their code. +// +// Contact information: +// +// +// +//$endhead${.::table.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +#include "qpc.h" // QP/C real-time embedded framework +#include "dpp.h" // DPP Application interface +#include "bsp.h" // Board Support Package -Q_DEFINE_THIS_FILE +//$declare${AOs::Table} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/* Active object class -----------------------------------------------------*/ -/*$declare${AOs::Table} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${AOs::Table} ............................................................*/ +//${AOs::Table} .............................................................. typedef struct Table { -/* protected: */ +// protected: QActive super; -/* public: */ - -/* private: */ +// private: uint8_t fork[N_PHILO]; - uint8_t isHungry[N_PHILO]; + bool isHungry[N_PHILO]; + +// public: } Table; + extern Table Table_inst; -/* protected: */ +// protected: static QState Table_initial(Table * const me, void const * const par); static QState Table_active(Table * const me, QEvt const * const e); static QState Table_serving(Table * const me, QEvt const * const e); static QState Table_paused(Table * const me, QEvt const * const e); -/*$enddecl${AOs::Table} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$enddecl${AOs::Table} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -#define RIGHT(n_) ((uint8_t)(((n_) + (N_PHILO - 1U)) % N_PHILO)) -#define LEFT(n_) ((uint8_t)(((n_) + 1U) % N_PHILO)) -#define FREE ((uint8_t)0) -#define USED ((uint8_t)1) +//---------------------------------------------------------------------------- +Q_DEFINE_THIS_FILE -/*$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* Check for the minimum required QP version */ -#if (QP_VERSION < 700U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) -#error qpc version 7.0.0 or higher required +// helper function to provide the RIGHT neighbor of a Philo[n] +static inline uint8_t right(uint8_t const n) { + return (uint8_t)((n + (N_PHILO - 1U)) % N_PHILO); +} + +// helper function to provide the LEFT neighbor of a Philo[n] +static inline uint8_t left(uint8_t const n) { + return (uint8_t)((n + 1U) % N_PHILO); +} + +#define FREE ((uint8_t)0U) +#define USED ((uint8_t)1U) + +#define THINKING "thinking" +#define HUNGRY "hungry " +#define EATING "eating " + +//---------------------------------------------------------------------------- + +//$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// Check for the minimum required QP version +#if (QP_VERSION < 730U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) +#error qpc version 7.3.0 or higher required #endif -/*$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -/*$define${AOs::AO_Table} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//$define${Shared::Table_ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/*${AOs::AO_Table} .........................................................*/ -QActive * const AO_Table = &Table_inst.super; /* "opaque" pointer to Table AO */ -/*$enddef${AOs::AO_Table} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*$define${AOs::Table_ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${AOs::Table_ctor} .......................................................*/ +//${Shared::Table_ctor} ...................................................... void Table_ctor(void) { - Table *me = &Table_inst; - uint8_t n; - + Table * const me = &Table_inst; QActive_ctor(&me->super, Q_STATE_CAST(&Table_initial)); - - for (n = 0U; n < N_PHILO; ++n) { + for (uint8_t n = 0U; n < N_PHILO; ++n) { me->fork[n] = FREE; - me->isHungry[n] = 0U; + me->isHungry[n] = false; } } -/*$enddef${AOs::Table_ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*$define${AOs::Table} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//$enddef${Shared::Table_ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +//$define${Shared::AO_Table} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/*${AOs::Table} ............................................................*/ +//${Shared::AO_Table} ........................................................ +QActive * const AO_Table = &Table_inst.super; +//$enddef${Shared::AO_Table} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +//$define${AOs::Table} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${AOs::Table} .............................................................. Table Table_inst; -/*${AOs::Table::SM} ........................................................*/ +//${AOs::Table::SM} .......................................................... static QState Table_initial(Table * const me, void const * const par) { - /*${AOs::Table::SM::initial} */ - uint8_t n; - (void)par; /* unused parameter */ + //${AOs::Table::SM::initial} + Q_UNUSED_PAR(par); - QS_OBJ_DICTIONARY(&Table_inst); - - QS_SIG_DICTIONARY(DONE_SIG, (void *)0); /* global signals */ - QS_SIG_DICTIONARY(EAT_SIG, (void *)0); - QS_SIG_DICTIONARY(PAUSE_SIG, (void *)0); - QS_SIG_DICTIONARY(SERVE_SIG, (void *)0); - QS_SIG_DICTIONARY(TEST_SIG, (void *)0); - - QS_SIG_DICTIONARY(HUNGRY_SIG, me); /* signal just for Table */ + #ifdef Q_SPY + Table *Table_inst = me; + QS_OBJ_DICTIONARY(Table_inst); + #endif QActive_subscribe(&me->super, DONE_SIG); QActive_subscribe(&me->super, PAUSE_SIG); QActive_subscribe(&me->super, SERVE_SIG); QActive_subscribe(&me->super, TEST_SIG); - for (n = 0U; n < N_PHILO; ++n) { + for (uint8_t n = 0U; n < N_PHILO; ++n) { me->fork[n] = FREE; - me->isHungry[n] = 0U; - BSP_displayPhilStat(n, "thinking"); + me->isHungry[n] = false; + BSP_displayPhilStat(n, THINKING); } QS_FUN_DICTIONARY(&Table_active); @@ -128,16 +134,16 @@ static QState Table_initial(Table * const me, void const * const par) { return Q_TRAN(&Table_serving); } -/*${AOs::Table::SM::active} ................................................*/ +//${AOs::Table::SM::active} .................................................. static QState Table_active(Table * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${AOs::Table::SM::active::TEST} */ + //${AOs::Table::SM::active::TEST} case TEST_SIG: { status_ = Q_HANDLED(); break; } - /*${AOs::Table::SM::active::EAT} */ + //${AOs::Table::SM::active::EAT} case EAT_SIG: { Q_ERROR(); status_ = Q_HANDLED(); @@ -151,108 +157,119 @@ static QState Table_active(Table * const me, QEvt const * const e) { return status_; } -/*${AOs::Table::SM::active::serving} .......................................*/ +//${AOs::Table::SM::active::serving} ......................................... static QState Table_serving(Table * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${AOs::Table::SM::active::serving} */ + //${AOs::Table::SM::active::serving} case Q_ENTRY_SIG: { - uint8_t n; - for (n = 0U; n < N_PHILO; ++n) { /* give permissions to eat... */ - if ((me->isHungry[n] != 0U) - && (me->fork[LEFT(n)] == FREE) + // give permissions to eat... + for (uint8_t n = 0U; n < N_PHILO; ++n) { + if (me->isHungry[n] + && (me->fork[left(n)] == FREE) && (me->fork[n] == FREE)) { - TableEvt *te; - - me->fork[LEFT(n)] = USED; + me->fork[left(n)] = USED; me->fork[n] = USED; - te = Q_NEW(TableEvt, EAT_SIG); - te->philoNum = n; - QACTIVE_PUBLISH(&te->super, &me->super); - me->isHungry[n] = 0U; - BSP_displayPhilStat(n, "eating "); + #ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, EAT_SIG, n); + #else + TableEvt *pe = Q_NEW(TableEvt, EAT_SIG); + pe->philoId = n; + #endif + QACTIVE_PUBLISH(&pe->super, &me->super); + me->isHungry[n] = false; + BSP_displayPhilStat(n, EATING); } } status_ = Q_HANDLED(); break; } - /*${AOs::Table::SM::active::serving::HUNGRY} */ + //${AOs::Table::SM::active::serving::HUNGRY} case HUNGRY_SIG: { - uint8_t n, m; + uint8_t n = Q_EVT_CAST(TableEvt)->philoId; - n = Q_EVT_CAST(TableEvt)->philoNum; - /* phil ID must be in range and he must be not hungry */ - Q_ASSERT((n < N_PHILO) && (me->isHungry[n] == 0U)); + // phil ID must be in range and he must be not hungry + Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); - BSP_displayPhilStat(n, "hungry "); - m = LEFT(n); - /*${AOs::Table::SM::active::serving::HUNGRY::[bothfree]} */ + BSP_displayPhilStat(n, HUNGRY); + uint8_t m = left(n); + //${AOs::Table::SM::active::serving::HUNGRY::[bothfree]} if ((me->fork[m] == FREE) && (me->fork[n] == FREE)) { - TableEvt *pe; me->fork[m] = USED; me->fork[n] = USED; - pe = Q_NEW(TableEvt, EAT_SIG); - pe->philoNum = n; + #ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, EAT_SIG, n); + #else + TableEvt *pe = Q_NEW(TableEvt, EAT_SIG); + pe->philoId = n; + #endif QACTIVE_PUBLISH(&pe->super, &me->super); - BSP_displayPhilStat(n, "eating "); + BSP_displayPhilStat(n, EATING); status_ = Q_HANDLED(); } - /*${AOs::Table::SM::active::serving::HUNGRY::[else]} */ + //${AOs::Table::SM::active::serving::HUNGRY::[else]} else { - me->isHungry[n] = 1U; + me->isHungry[n] = true; status_ = Q_HANDLED(); } break; } - /*${AOs::Table::SM::active::serving::DONE} */ + //${AOs::Table::SM::active::serving::DONE} case DONE_SIG: { - uint8_t n, m; - TableEvt *pe; + uint8_t n = Q_EVT_CAST(TableEvt)->philoId; - n = Q_EVT_CAST(TableEvt)->philoNum; - /* phil ID must be in range and he must be not hungry */ - Q_ASSERT((n < N_PHILO) && (me->isHungry[n] == 0U)); + // phil ID must be in range and he must be not hungry + Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); - BSP_displayPhilStat(n, "thinking"); - m = LEFT(n); - /* both forks of Phil[n] must be used */ + BSP_displayPhilStat(n, THINKING); + uint8_t m = left(n); + + // both forks of Phil[n] must be used Q_ASSERT((me->fork[n] == USED) && (me->fork[m] == USED)); me->fork[m] = FREE; me->fork[n] = FREE; - m = RIGHT(n); /* check the right neighbor */ + m = right(n); // check the right neighbor - if ((me->isHungry[m] != 0U) && (me->fork[m] == FREE)) { + if (me->isHungry[m] && (me->fork[m] == FREE)) { me->fork[n] = USED; me->fork[m] = USED; - me->isHungry[m] = 0U; - pe = Q_NEW(TableEvt, EAT_SIG); - pe->philoNum = m; + me->isHungry[m] = false; + #ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, EAT_SIG, m); + #else + TableEvt *pe = Q_NEW(TableEvt, EAT_SIG); + pe->philoId = m; + #endif QACTIVE_PUBLISH(&pe->super, &me->super); - BSP_displayPhilStat(m, "eating "); + BSP_displayPhilStat(m, EATING); } - m = LEFT(n); /* check the left neighbor */ - n = LEFT(m); /* left fork of the left neighbor */ - if ((me->isHungry[m] != 0U) && (me->fork[n] == FREE)) { + m = left(n); // check the left neighbor + n = left(m); // left fork of the left neighbor + if (me->isHungry[m] && (me->fork[n] == FREE)) { me->fork[m] = USED; me->fork[n] = USED; - me->isHungry[m] = 0U; - pe = Q_NEW(TableEvt, EAT_SIG); - pe->philoNum = m; + me->isHungry[m] = false; + #ifdef QEVT_DYN_CTOR + TableEvt const *pe = Q_NEW(TableEvt, EAT_SIG, m); + #else + TableEvt *pe = Q_NEW(TableEvt, EAT_SIG); + pe->philoId = m; + #endif QACTIVE_PUBLISH(&pe->super, &me->super); - BSP_displayPhilStat(m, "eating "); + BSP_displayPhilStat(m, EATING); } status_ = Q_HANDLED(); break; } - /*${AOs::Table::SM::active::serving::EAT} */ + //${AOs::Table::SM::active::serving::EAT} case EAT_SIG: { Q_ERROR(); status_ = Q_HANDLED(); break; } - /*${AOs::Table::SM::active::serving::PAUSE} */ + //${AOs::Table::SM::active::serving::PAUSE} case PAUSE_SIG: { status_ = Q_TRAN(&Table_paused); break; @@ -265,48 +282,50 @@ static QState Table_serving(Table * const me, QEvt const * const e) { return status_; } -/*${AOs::Table::SM::active::paused} ........................................*/ +//${AOs::Table::SM::active::paused} .......................................... static QState Table_paused(Table * const me, QEvt const * const e) { QState status_; switch (e->sig) { - /*${AOs::Table::SM::active::paused} */ + //${AOs::Table::SM::active::paused} case Q_ENTRY_SIG: { BSP_displayPaused(1U); status_ = Q_HANDLED(); break; } - /*${AOs::Table::SM::active::paused} */ + //${AOs::Table::SM::active::paused} case Q_EXIT_SIG: { BSP_displayPaused(0U); status_ = Q_HANDLED(); break; } - /*${AOs::Table::SM::active::paused::SERVE} */ + //${AOs::Table::SM::active::paused::SERVE} case SERVE_SIG: { status_ = Q_TRAN(&Table_serving); break; } - /*${AOs::Table::SM::active::paused::HUNGRY} */ + //${AOs::Table::SM::active::paused::HUNGRY} case HUNGRY_SIG: { - uint8_t n = Q_EVT_CAST(TableEvt)->philoNum; - /* philo ID must be in range and he must be not hungry */ - Q_ASSERT((n < N_PHILO) && (me->isHungry[n] == 0U)); - me->isHungry[n] = 1U; - BSP_displayPhilStat(n, "hungry "); + uint8_t n = Q_EVT_CAST(TableEvt)->philoId; + + // philo ID must be in range and he must be not hungry + Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); + + me->isHungry[n] = true; + BSP_displayPhilStat(n, HUNGRY); status_ = Q_HANDLED(); break; } - /*${AOs::Table::SM::active::paused::DONE} */ + //${AOs::Table::SM::active::paused::DONE} case DONE_SIG: { - uint8_t n, m; + uint8_t n = Q_EVT_CAST(TableEvt)->philoId; - n = Q_EVT_CAST(TableEvt)->philoNum; - /* phil ID must be in range and he must be not hungry */ - Q_ASSERT((n < N_PHILO) && (me->isHungry[n] == 0U)); + // phil ID must be in range and he must be not hungry + Q_ASSERT((n < N_PHILO) && (!me->isHungry[n])); - BSP_displayPhilStat(n, "thinking"); - m = LEFT(n); - /* both forks of Phil[n] must be used */ + BSP_displayPhilStat(n, THINKING); + uint8_t m = left(n); + + // both forks of Phil[n] must be used Q_ASSERT((me->fork[n] == USED) && (me->fork[m] == USED)); me->fork[m] = FREE; @@ -321,4 +340,4 @@ static QState Table_paused(Table * const me, QEvt const * const e) { } return status_; } -/*$enddef${AOs::Table} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$enddef${AOs::Table} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/include/qassert.h b/include/qassert.h deleted file mode 100644 index b8de1642..00000000 --- a/include/qassert.h +++ /dev/null @@ -1,407 +0,0 @@ -/*$file${include::qassert.h} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* -* Model: qpc.qm -* File: ${include::qassert.h} -* -* This code has been generated by QM 5.2.4 . -* DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. -* -* This code is covered by the following QP license: -* License # : LicenseRef-QL-dual -* Issued to : Any user of the QP/C real-time embedded framework -* Framework(s) : qpc -* Support ends : 2023-12-31 -* License scope: -* -* Copyright (C) 2005 Quantum Leaps, LLC . -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -*/ -/*$endhead${include::qassert.h} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*!* @file -* @brief Customizable and memory-efficient Design by Contract (DbC) -* for embedded systems -* -* @note -* This header file can be used in C, C++, and mixed C/C++ programs. -* -* @note -* The preprocessor switch #Q_NASSERT disables checking assertions. -* However, it is generally __not__ advisable to disable assertions, -* __especially__ in the production code. Instead, the assertion handler -* Q_onAssert() should be very carefully designed and tested. -*/ -#ifndef QP_INC_QASSERT_H_ -#define QP_INC_QASSERT_H_ - -#ifdef __cplusplus - extern "C" { -#endif - -/*$declare${DbC} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${DbC::Q_NORETURN} .......................................................*/ -#ifndef Q_NORETURN -/*! No-return function specifier for the Q_onAssert() callback function. -* -* The `Q_NORETURN` macro is supposed to be defined in the QP/C port -* (file `qep_port.h`). If such definition is NOT porvided, the default -* definition assumes only `void` type returned from Q_onAssert(). -* -* @tr{PQA01_4} -*/ -#define Q_NORETURN void -#endif /* ndef Q_NORETURN */ - -/*${DbC::Q_DEFINE_THIS_FILE} ...............................................*/ -/*! Define the file name (with `__FILE__`) for assertions in this file -* -* @details -* Macro to be placed at the top of each C/C++ module to define the -* single instance of the file name string to be used in reporting -* assertions in this module. -* -* @note -* The file name string literal is defined by means of the standard -* preprocessor macro `__FILE__`. However, please note that, depending -* on the compiler, the `__FILE__` macro might contain the whole path name -* to the file, which might be inconvenient to log assertions. -* -* @attention -* This macro should **not** be terminated by a semicolon. -* -* @sa Q_DEFINE_THIS_MODULE() -*/ -#define Q_DEFINE_THIS_FILE Q_DEFINE_THIS_MODULE(__FILE__) - -/*${DbC::Q_DEFINE_THIS_MODULE} .............................................*/ -#ifndef Q_NASSERT -/*! Define the user-specified module name for assertions in this file. -* -* @details -* Macro to be placed at the top of each C/C++ module to define the -* single instance of the module name string to be used in reporting -* assertions in this module. This macro takes the user-supplied parameter -* `name_` instead of `__FILE__` to precisely control the name of the -* module. -* -* @param[in] name_ string constant representing the module name -* -* @note -* This macro should **not** be terminated by a semicolon. -*/ -#define Q_DEFINE_THIS_MODULE(name_) \ - static char const Q_this_module_[] = name_; -#endif /* ndef Q_NASSERT */ - -/*${DbC::Q_DEFINE_THIS_MODULE} .............................................*/ -#ifdef Q_NASSERT -/*! inactive version of Q_DEFINE_THIS_MODULE() */ -#define Q_DEFINE_THIS_MODULE(name_) -#endif /* def Q_NASSERT */ - -/*${DbC::Q_ASSERT_ID} ......................................................*/ -#ifndef Q_NASSERT -/*! General purpose assertion with user-specified ID number. -* -* @details -* Makes sure the `test_` parameter is TRUE. Calls the Q_onAssert() -* callback if the `test_` evaluates to FALSE. This assertion takes the -* user-supplied parameter `id_` to identify the location of this -* assertion within the file. This avoids the volatility of using line -* numbers, which change whenever a line of code is added or removed -* upstream from the assertion. -* -* @param[in] id_ ID number (unique within the module) of the assertion -* @param[in] expr_ Boolean expression to check -* -* @note -* The `test_` expression is **not** evaluated if assertions are -* disabled with the ::Q_NASSERT switch. -*/ -#define Q_ASSERT_ID(id_, expr_) ((expr_) \ - ? ((void)0) : Q_onAssert(&Q_this_module_[0], (id_))) -#endif /* ndef Q_NASSERT */ - -/*${DbC::Q_ASSERT_ID} ......................................................*/ -#ifdef Q_NASSERT -/*! inactive version of Q_ASSERT_ID() */ -#define Q_ASSERT_ID(id_, expr_) ((void)0) -#endif /* def Q_NASSERT */ - -/*${DbC::Q_ERROR_ID} .......................................................*/ -#ifndef Q_NASSERT -/*! Assertion with user-specified ID for a wrong path through the code -* -* @details -* Calls the Q_onAssert() callback if ever executed. This assertion -* takes the user-supplied parameter `id_` to identify the location of -* this assertion within the file. This avoids the volatility of using -* line numbers, which change whenever a line of code is added or removed -* upstream from the assertion. -* -* @param[in] id_ ID number (unique within the module) of the assertion -* -* @note -* Does noting if assertions are disabled with the ::Q_NASSERT switch. -*/ -#define Q_ERROR_ID(id_) Q_onAssert(&Q_this_module_[0], (id_)) -#endif /* ndef Q_NASSERT */ - -/*${DbC::Q_ERROR_ID} .......................................................*/ -#ifdef Q_NASSERT -/*! inactive version of Q_ERROR_ID() */ -#define Q_ERROR_ID(id_) ((void)0) -#endif /* def Q_NASSERT */ - -/*${DbC::Q_ALLEGE_ID} ......................................................*/ -#ifndef Q_NASSERT -/*! General purpose assertion with user-specified ID number that -* **always** evaluates the `expr_` expression. -* -* @details -* Like the Q_ASSERT_ID() macro, except it **always** evaluates the -* `expr_` expression even when assertions are disabled with the -* ::Q_NASSERT macro. However, when the ::Q_NASSERT macro is defined, the -* Q_onAssert() callback is **not** called, even if `expr_` evaluates -* to FALSE. -* -* @param[in] id_ ID number (unique within the module) of the assertion -* @param[in] expr_ Boolean expression to check -*/ -#define Q_ALLEGE_ID(id_, expr_) Q_ASSERT_ID((id_), (expr_)) -#endif /* ndef Q_NASSERT */ - -/*${DbC::Q_ALLEGE_ID} ......................................................*/ -#ifdef Q_NASSERT -/*! inactive version of Q_ALLEGE_ID() -* -* @attention -* The expression `expr_` **is** executed. -*/ -#define Q_ALLEGE_ID(id_, expr_) ((void)(expr_)) -#endif /* def Q_NASSERT */ - -/*${DbC::Q_REQUIRE_ID} .....................................................*/ -/*! Assertion for checking preconditions. -* -* @details -* This macro is equivalent to Q_ASSERT_ID(), except the name provides a better -* documentation of the intention of this assertion. -* -* @param[in] id_ ID number (unique within the module) of the assertion -* @param[in] expr_ Boolean expression -*/ -#define Q_REQUIRE_ID(id_, expr_) Q_ASSERT_ID((id_), (expr_)) - -/*${DbC::Q_REQUIRE} ........................................................*/ -/*! Assertion for checking preconditions (based on __LINE__). -* -* @details -* Equivalent to Q_ASSERT(), except the name provides a better documentation -* of the intention of this assertion. -* -* @param[in] expr_ Boolean expression -*/ -#define Q_REQUIRE(expr_) Q_REQUIRE_ID(__LINE__, (expr_)) - -/*${DbC::Q_ENSURE_ID} ......................................................*/ -/*! Assertion for checking postconditions. -* -* @details -* This macro is equivalent to Q_ASSERT_ID(), except the name provides a better -* documentation of the intention of this assertion. -* -* @param[in] id_ ID number (unique within the module) of the assertion -* @param[in] expr_ Boolean expression -*/ -#define Q_ENSURE_ID(id_, expr_) Q_ASSERT_ID((id_), (expr_)) - -/*${DbC::Q_ENSURE} .........................................................*/ -/*! Assertion for checking postconditions. -* -* @details -* Equivalent to Q_ASSERT(), except the name provides a better documentation -* of the intention of this assertion. -* -* @param[in] expr_ Boolean expression -*/ -#define Q_ENSURE(expr_) Q_ENSURE_ID(__LINE__, (expr_)) - -/*${DbC::Q_INVARIANT_ID} ...................................................*/ -/*! Assertion for checking invariants. -* -* @details -* Equivalent to Q_ASSERT(), except the name provides a better documentation -* of the intention of this assertion. -* -* @param[in] id_ ID number (unique within the module) of the assertion -* @param[in] expr_ Boolean expression -*/ -#define Q_INVARIANT_ID(id_, expr_) Q_ASSERT_ID((id_), (expr_)) - -/*${DbC::Q_INVARIANT} ......................................................*/ -/*! Assertion for checking invariants. -* -* @details -* Equivalent to Q_ASSERT(), except the name provides a better documentation -* of the intention of this assertion. -* -* @param[in] expr_ Boolean expression -*/ -#define Q_INVARIANT(expr_) Q_INVARIANT_ID(__LINE__, (expr_)) - -/*${DbC::Q_ASSERT} .........................................................*/ -/*! Assertion for a wrong path through the code (based on __LINE__) -* -* @details -* Calls the Q_onAssert() callback if ever executed. -* -* @note -* This macro identifies the problem location with the line number, -* which might change as the code is modified. -* -* @sa Q_ASSERT_ID() -*/ -#define Q_ASSERT(expr_) Q_ASSERT_ID(__LINE__, (expr_)) - -/*${DbC::Q_ERROR} ..........................................................*/ -/*! Assertion for a wrong path through the code -* -* @details -* Calls the Q_onAssert() callback if ever executed. -* -* @note -* This macro identifies the problem location with the line number, -* which might change as the code is modified. -* -* @sa Q_ERROR_ID() -*/ -#define Q_ERROR() Q_ERROR_ID(__LINE__) - -/*${DbC::Q_ALLEGE} .........................................................*/ -/*! General purpose assertion with user-specified ID number that -* **always** evaluates the `expr_` expression. -* -* @details -* Like the Q_ASSERT_ID() macro, except it **always** evaluates the -* `expr_` expression even when assertions are disabled with the -* ::Q_NASSERT macro. However, when the ::Q_NASSERT macro is defined, the -* Q_onAssert() callback is **not** called, even if `expr_` evaluates -* to FALSE. -* -* @param[in] expr_ Boolean expression to check -* -* @sa Q_ALLEGE_ID() -*/ -#define Q_ALLEGE(expr_) Q_ALLEGE_ID(__LINE__, (expr_)) - -/*${DbC::Q_ASSERT_STATIC} ..................................................*/ -/*! Static (compile-time) assertion. -* -* @details -* This type of assertion deliberately causes a compile-time error when -* the `expr_` Boolean expression evaluates to FALSE. The macro exploits -* the fact that in C/C++ a dimension of an array cannot be negative. -* The compile-time assertion has no runtime side effects. -* -* @param[in] expr_ Compile-time Boolean expression -* -* @note -* The static assertion macro is provided for backwards compatibility with -* older C standards. Newer C11 supports `_Static_assert()`, which should -* be used instead of Q_ASSERT_STATIC(). -*/ -#define Q_ASSERT_STATIC(expr_) extern char Q_static_assert_[(expr_) ? 1 : -1] - -/*${DbC::Q_ASSERT_COMPILE} .................................................*/ -/*! Static (compile-time) assertion. -* -* @deprecated -* Use Q_ASSERT_STATIC() or better yet `_Static_assert()` instead. -*/ -#define Q_ASSERT_COMPILE(expr_) Q_ASSERT_STATIC(expr_) - -/*${DbC::int_t} ............................................................*/ -#ifndef QP_VERSION -/*! typedef for assertions-ids and line numbers in assertions. -* -* @details -* This typedef specifies integer type for exclusive use in assertions. -* Use of this type, rather than plain 'int', is in compliance -* with the MISRA-C 2012 Dir 4.6 (adv). -*/ -typedef int int_t; -#endif /* ndef QP_VERSION */ - -/*${DbC::Q_onAssert} .......................................................*/ -/*! Callback function invoked in case of an assertion failure. -* -* @details -* This is an application-specific callback function needs to be defined in -* the application to perform the clean system shutdown and perhaps a reset. -* The Q_onAssert() function is the last line of defense after the -* system failure and its implementation shouild be very **carefully** -* designed and **tested** under various fault conditions, including but -* not limited to: stack overflow, stack corruption, or calling Q_onAssert() -* from an interrupt. - -* @param[in] module name of the file/module in which the assertion failed -* (constant, zero-terminated C string) -* @param[in] location location of the assertion within the module. This could -* be a line number or a user-specified ID-number. -* -* @returns -* This callback function should **not return** (see ::Q_NORETURN), -* as continuation after an assertion failure does not make sense. -* -* @note -* It is typically a **bad idea** to implement Q_onAssert() as an endless -* loop that ties up the CPU. During debuggin, Q_onAssert() is an ideal -* place to put a breakpoint. -* -* @tr{PQA01_4} -* -* Called by the following: Q_ASSERT_ID(), Q_ERROR_ID(), Q_REQUIRE_ID(), -* Q_ENSURE_ID(), Q_INVARIANT_ID() and Q_ALLEGE_ID() as well as: -* Q_ASSERT(), Q_ERROR(), Q_REQUIRE(), Q_ENSURE(), Q_INVARIANT(), -* and Q_ALLEGE(). -*/ -Q_NORETURN Q_onAssert( - char const * module, - int_t location); - -/*${DbC::Q_DIM} ............................................................*/ -#ifndef QP_VERSION -/*! Helper macro to calculate static dimension of a 1-dim `array_` -* -* @param array_ 1-dimensional array -* @returns the length of the array (number of elements it can hold) -*/ -#define Q_DIM(array_) (sizeof(array_) / sizeof((array_)[0U])) -#endif /* ndef QP_VERSION */ -/*$enddecl${DbC} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ - -#ifdef __cplusplus - } -#endif - -#endif /* QP_INC_QASSERT_H_ */ diff --git a/include/qep.h b/include/qep.h deleted file mode 100644 index a810b612..00000000 --- a/include/qep.h +++ /dev/null @@ -1,1161 +0,0 @@ -/*$file${include::qep.h} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* -* Model: qpc.qm -* File: ${include::qep.h} -* -* This code has been generated by QM 5.2.4 . -* DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. -* -* This code is covered by the following QP license: -* License # : LicenseRef-QL-dual -* Issued to : Any user of the QP/C real-time embedded framework -* Framework(s) : qpc -* Support ends : 2023-12-31 -* License scope: -* -* Copyright (C) 2005 Quantum Leaps, LLC . -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -*/ -/*$endhead${include::qep.h} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*! @file -* @brief QEP/C platform-independent public interface. -* -* @tr{RQP001} @tr{RQP101} -*/ -#ifndef QP_INC_QEP_H_ -#define QP_INC_QEP_H_ - -/*==========================================================================*/ -/*! The current QP version as an unsigned number -* -* @details -* ::QP_VERSION is a decimal constant, where XX is a 1-digit or 2-digit -* major version number, Y is a 1-digit minor version number, and Z is -* a 1-digit release number. -*/ -#define QP_VERSION 721U - -/*! The current QP version as a zero terminated string literal. -* -* @details -* ::QP_VERSION_STR is of the form "XX.Y.Z", where XX is a 1-or 2-digit -* major version number, Y is a 1-digit minor version number, and Z is -* a 1-digit release number. -*/ -#define QP_VERSION_STR "7.2.1" - -/*! Encrypted current QP release (7.2.1) and date (2023-01-15) */ -#define QP_RELEASE 0x76D739FEU - -/*==========================================================================*/ -/*$declare${glob-types} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${glob-types::int_t} .....................................................*/ -/*! alias for line numbers in assertions and return from QF_run() */ -typedef int int_t; - -/*${glob-types::enum_t} ....................................................*/ -/*! alias for enumerations used for event signals */ -typedef int enum_t; - -/*${glob-types::float32_t} .................................................*/ -/*! alias for IEEE 754 32-bit floating point number, -* MISRA-C 2012 Dir 4.6(A) -* -* @note -* QP does not use floating-point types anywhere in the internal -* implementation, except in QS software tracing, where utilities for -* output of floating-point numbers are provided for application-specific -* trace records. -*/ -typedef float float32_t; - -/*${glob-types::float64_t} .................................................*/ -/*! alias for IEEE 754 64-bit floating point number, -* MISRA-C 2012 Dir 4.6(A) -* -* @note -* QP does not use floating-point types anywhere in the internal -* implementation, except in QS software tracing, where utilities for -* output of floating-point numbers are provided for application-specific -* trace records. -*/ -typedef double float64_t; -/*$enddecl${glob-types} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*$declare${QEP-config} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${QEP-config::Q_SIGNAL_SIZE} .............................................*/ -#ifndef Q_SIGNAL_SIZE -/*! The size (in bytes) of the signal of an event. Valid values: -* 1U, 2U, or 4U; default 2U -* -* @details -* This macro can be defined in the QEP port file (qep_port.h) to -* configure the ::QSignal type. When the macro is not defined, the -* default of 2 bytes is applied. -*/ -#define Q_SIGNAL_SIZE 2U -#endif /* ndef Q_SIGNAL_SIZE */ -/*$enddecl${QEP-config} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ - -/*==========================================================================*/ -/*$declare${QEP} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${QEP::QP_versionStr[8]} .................................................*/ -/*! the current QP version number string in ROM, based on #QP_VERSION_STR */ -extern char const QP_versionStr[8]; - -/*${QEP::QSignal} ..........................................................*/ -#if (Q_SIGNAL_SIZE == 2U) -/*! ::QSignal represents the signal of an event -* -* @details -* The relationship between an event and a signal is as follows. A signal -* in UML is the specification of an asynchronous stimulus that triggers -* reactions, and as such is an essential part of an event. (The signal -* conveys the type of the occurrence--what happened?) However, an event -* can also contain additional quantitative information about the -* occurrence in form of event parameters. -*/ -typedef uint16_t QSignal; -#endif /* (Q_SIGNAL_SIZE == 2U) */ - -/*${QEP::QSignal} ..........................................................*/ -#if (Q_SIGNAL_SIZE == 1U) -typedef uint8_t QSignal; -#endif /* (Q_SIGNAL_SIZE == 1U) */ - -/*${QEP::QSignal} ..........................................................*/ -#if (Q_SIGNAL_SIZE == 4U) -typedef uint32_t QSignal; -#endif /* (Q_SIGNAL_SIZE == 4U) */ - -/*${QEP::QEvt} .............................................................*/ -/*! @brief Event class -* @class QEvt -* -* @details -* ::QEvt represents events without parameters and serves as the base class -* for derivation of events with parameters. -* -* @tr{RQP001} @tr{RQP004} -* @tr{AQP210} -* -* @usage -* The following example illustrates how to add an event parameter by -* derivation of the ::QEvt class. Please note that the ::QEvt member -* super is defined as the FIRST member of the derived struct. -* @include qep_qevt.c -*/ -typedef struct { -/* public: */ - - /*! Signal of the event. - * @public @memberof QEvt - * - * @tr{RQP002} - */ - QSignal sig; - -/* private: */ - - /*! Pool ID (==0 for immutable event) - * @private @memberof QEvt - * - * @tr{RQP003} - */ - uint8_t poolId_; - - /*! Reference counter (for mutable events) - * @private @memberof QEvt - * - * @tr{RQP003} - */ - uint8_t volatile refCtr_; -} QEvt; - -/* public: */ - -#ifdef Q_EVT_CTOR -/*! Custom event constructor -* @public @memberof QEvt -* @note -* Available only when the macro #Q_EVT_CTOR is defined -* @tr{RQP005} -*/ -void QEvt_ctor(QEvt * const me, - enum_t const sig); -#endif /* def Q_EVT_CTOR */ - -/*${QEP::QStateRet} ........................................................*/ -/*! All possible values returned from state/action handlers -* -* @note -* The order matters for algorithmic correctness. -*/ -enum QStateRet { - /* unhandled and need to "bubble up" */ - Q_RET_SUPER, /*!< event passed to superstate to handle */ - Q_RET_SUPER_SUB, /*!< event passed to submachine superstate */ - Q_RET_UNHANDLED, /*!< event unhandled due to a guard */ - - /* handled and do not need to "bubble up" */ - Q_RET_HANDLED, /*!< event handled (internal transition) */ - Q_RET_IGNORED, /*!< event silently ignored (bubbled up to top) */ - - /* entry/exit */ - Q_RET_ENTRY, /*!< state entry action executed */ - Q_RET_EXIT, /*!< state exit action executed */ - - /* no side effects */ - Q_RET_NULL, /*!< return value without any effect */ - - /* transitions need to execute transition-action table in ::QMsm */ - Q_RET_TRAN, /*!< regular transition */ - Q_RET_TRAN_INIT, /*!< initial transition in a state or submachine */ - Q_RET_TRAN_EP, /*!< entry-point transition into a submachine */ - - /* transitions that additionally clobber me->state */ - Q_RET_TRAN_HIST, /*!< transition to history of a given state */ - Q_RET_TRAN_XP /*!< exit-point transition out of a submachine */ -}; - -/*${QEP::QState} ...........................................................*/ -/*! Type returned from state-handler functions */ -typedef enum QStateRet QState; - -/*${QEP::QStateHandler} ....................................................*/ -/*! Pointer to a state-handler function. */ -typedef QState (* QStateHandler )(void * const me, QEvt const * const e); - -/*${QEP::QActionHandler} ...................................................*/ -/*! Pointer to an action-handler function. */ -typedef QState (* QActionHandler )(void * const me); - -/*${QEP::QXThread} .........................................................*/ -/* forward declaration */ -struct QXThread; - -/*${QEP::QXThreadHandler} ..................................................*/ -/*! Pointer to an eXthended thread handler function */ -typedef void (* QXThreadHandler )(struct QXThread * const me); - -/*${QEP::QMState} ..........................................................*/ -/*! @brief State object for the ::QMsm class (QM State Machine). -* -* @details -* This class groups together the attributes of a ::QMsm state, such as the -* parent state (state nesting), the associated state handler function and -* the exit action handler function. These attributes are used inside the -* QMsm_dispatch() and QMsm_init() functions. -* -* @tr{RQP104} -* -* @attention -* The ::QMState class is only intended for the QM code generator and should -* not be used in hand-crafted code. -*/ -typedef struct QMState { - struct QMState const *superstate; /*!< superstate of this state */ - QStateHandler const stateHandler; /*!< state handler function */ - QActionHandler const entryAction; /*!< entry action handler function */ - QActionHandler const exitAction; /*!< exit action handler function */ - QActionHandler const initAction; /*!< init action handler function */ -} QMState; - -/*${QEP::QMTranActTable} ...................................................*/ -/*! @brief Transition-Action Table for the ::QMsm State Machine. */ -typedef struct QMTranActTable { - QMState const *target; /*!< target of the transition */ - QActionHandler const act[1]; /*!< array of actions */ -} QMTranActTable; - -/*${QEP::QHsmAttr} .........................................................*/ -/*! @brief Attribute of for the ::QHsm class (Hierarchical State Machine). -* -* @details -* This union represents possible values stored in the 'state' and 'temp' -* attributes of the ::QHsm class. -*/ -union QHsmAttr { - QStateHandler fun; /*!< @private pointer to a state-handler */ - QActionHandler act; /*!< @private pointer to an action-handler */ - QXThreadHandler thr; /*!< @private pointer to an thread-handler */ - QMTranActTable const *tatbl; /*!< @private transition-action table */ - struct QMState const *obj; /*!< @private pointer to QMState object */ -}; - -/*${QEP::QHSM_MAX_NEST_DEPTH_} .............................................*/ -/*! maximum depth of state nesting in a HSM (including the top level), -* must be >= 3 -*/ -enum { QHSM_MAX_NEST_DEPTH_ = 6}; - -/*${QEP::QReservedSig} .....................................................*/ -/*! Reserved signals by the HSM-style state machine -* implementation strategy. -*/ -enum QReservedSig { - Q_EMPTY_SIG, /*!< signal to execute the default case */ - Q_ENTRY_SIG, /*!< signal for coding entry actions */ - Q_EXIT_SIG, /*!< signal for coding exit actions */ - Q_INIT_SIG, /*!< signal for coding initial transitions */ - Q_USER_SIG /*!< offset for the user signals (QP Application) */ -}; - -/*${QEP::QHsm} .............................................................*/ -/*! @brief Hierarchical State Machine class -* @class QHsm -* -* @details -* QHsm represents a Hierarchical State Machine (HSM) with full support for -* hierarchical nesting of states, entry/exit actions, initial transitions, -* and transitions to history in any composite state. This class is designed -* for ease of manual coding of HSMs in C, but it is also supported by the -* QM modeling tool.
-* -* QHsm is also the base class for the QMsm state machine, which provides -* a superior efficiency, but requires the use of the QM modeling tool to -* generate code. -* -* @note -* QHsm is not intended to be instantiated directly, but rather serves as the -* abstract base class for derivation of state machines in the QP application. -* -* @tr{RQP103} -* @tr{AQP211} -* -* @usage -* The following example illustrates how to derive a state machine class -* from QHsm. Please note that the QHsm member `super` is defined as the -* FIRST member of the derived class. -* @include qep_qhsm.c -*/ -typedef struct { -/* private: */ - - /*! Virtual pointer - * @private @memberof QHsm - * - * @tr{RQP102} - */ - struct QHsmVtable const * vptr; - -/* protected: */ - - /*! Current active state (state-variable). - * @private @memberof QHsm - */ - union QHsmAttr state; - - /*! Temporary: target/act-table, etc. - * @private @memberof QHsm - */ - union QHsmAttr temp; -} QHsm; - -/* public: */ - -/*! Tests if a given state is part of the current active state -* configuration in ::QHsm subclasses. -* @public @memberof QHsm -* -* @details -* Tests if a state machine derived from QHsm is-in a given state. -* -* @note For a HSM, to "be in a state" means also to be in a superstate of -* of the state. -* -* @param[in] me current instance pointer (see @ref oop) -* @param[in] state pointer to the state-handler function to be tested -* -* @returns -*'true' if the HSM "is in" the `state` and 'false' otherwise -* -* @tr{RQP103} -* @tr{RQP120S} -*/ -bool QHsm_isIn(QHsm * const me, - QStateHandler const state); - -/*! Obtain the current active state from a HSM (read only). -* @public @memberof QHsm -* -* @param[in] me current instance pointer (see @ref oop) -* -* @returns the current active state of the QHsm class -* -* @note -* This function is used in QM for auto-generating code for state history. -*/ -static inline QStateHandler QHsm_state(QHsm * const me) { - return me->state.fun; -} - -/*! Obtain the current active child state of a given parent in ::QHsm -* @public @memberof QHsm -* -* @details -* Finds the child state of the given `parent`, such that this child state -* is an ancestor of the currently active state. The main purpose of this -* function is to support **shallow history** transitions in state machines -* derived from QHsm. -* -* @param[in] me current instance pointer (see @ref oop) -* @param[in] parent pointer to the state-handler function -* -* @returns -* the child of a given `parent` state, which is an ancestor of the current -* active state. For the corner case when the currently active state is the -* given `parent` state, function returns the `parent` state. -* -* @note -* this function is designed to be called during state transitions, so it -* does not necessarily start in a stable state configuration. -* However, the function establishes stable state configuration upon exit. -* -* @tr{RQP103} -* @tr{RQP120H} -*/ -QStateHandler QHsm_childState(QHsm * const me, - QStateHandler const parent); - -/* protected: */ - -/*! Protected "constructor" of ::QHsm -* @protected @memberof QHsm -* -* @details -* Performs the first step of HSM initialization by assigning the initial -* pseudostate to the currently active state of the state machine. -* -* @param[in,out] me current instance pointer (see @ref oop) -* @param[in] initial pointer to the top-most initial state-handler -* function in the derived state machine -* -* @note Must be called only by the constructors of the derived state -* machines. -* -* @note Must be called only ONCE before QHSM_INIT(). -* -* @usage -* The following example illustrates how to invoke QHsm_ctor() in the -* "constructor" of a derived state machine: -* @include qep_qhsm_ctor.c -* -* @tr{RQP103} -*/ -void QHsm_ctor(QHsm * const me, - QStateHandler const initial); - -/*! The top-state of QHsm. -* @protected @memberof QHsm -* -* @details -* QHsm_top() is the ultimate root of state hierarchy in all HSMs derived -* from ::QHsm. -* -* @param[in] me current instance pointer (see @ref oop) -* @param[in] e pointer to the event to be dispatched to the FSM -* -* @returns -* Always returns ::Q_RET_IGNORED, which means that the top state ignores -* all events. -* -* @note The parameters to this state handler are not used. They are provided -* for conformance with the state-handler function signature ::QStateHandler. -* -* @tr{RQP103} @tr{RQP120T} -*/ -QState QHsm_top(QHsm const * const me, - QEvt const * const e); - -/*! Implementation of the top-most initial tran. in ::QHsm. -* @protected @memberof QHsm -* -* @details -* Executes the top-most initial transition in a HSM. -* -* @param[in,out] me current instance pointer (see @ref oop) -* @param[in] e pointer to an extra parameter (might be NULL) -* @param[in] qs_id QS-id of this state machine (for QS local filter) -* -* @note Must be called only ONCE after the QHsm_ctor(). -* -* @tr{RQP103} @tr{RQP120I} @tr{RQP120D} -*/ -void QHsm_init_(QHsm * const me, - void const * const e, - uint_fast8_t const qs_id); - -/*! Implementation of dispatching events to a ::QHsm -* @protected @memberof QHsm -* -* @details -* Dispatches an event for processing to a hierarchical state machine (HSM). -* The processing of an event represents one run-to-completion (RTC) step. -* -* @param[in,out] me current instance pointer (see @ref oop) -* @param[in] e pointer to the event to be dispatched to the HSM -* @param[in] qs_id QS-id of this state machine (for QS local filter) -* -* @note -* This function should be called only via the virtual table (see -* QHSM_DISPATCH()) and should NOT be called directly in the applications. -* -* @tr{RQP103} -* @tr{RQP120A} @tr{RQP120B} @tr{RQP120C} @tr{RQP120D} @tr{RQP120E} -*/ -void QHsm_dispatch_(QHsm * const me, - QEvt const * const e, - uint_fast8_t const qs_id); - -/* private: */ - -#ifdef Q_SPY -/*! Implementation of getting the state handler in a ::QHsm subclass -* @private @memberof QHsm -*/ -QStateHandler QHsm_getStateHandler_(QHsm * const me); -#endif /* def Q_SPY */ - -/*! Helper function to execute transition sequence in a hierarchical state -* machine (HSM). -* @private @memberof QHsm -* -* @param[in,out] path array of pointers to state-handler functions -* to execute the entry actions -* @param[in] qs_id QS-id of this state machine (for QS local filter) -* -* @returns -* the depth of the entry path stored in the `path` parameter. -* -* @tr{RQP103} -* @tr{RQP120E} @tr{RQP120F} -*/ -int_fast8_t QHsm_tran_(QHsm * const me, - QStateHandler * const path, - uint_fast8_t const qs_id); - -/*! Helper function to execute entry into a given state in a -* hierarchical state machine (HSM). -* @private @memberof QHsm -* -* @param[in] state state handler function -* @param[in] qs_id QS-id of this state machine (for QS local filter) -*/ -void QHsm_state_entry_(QHsm * const me, - QStateHandler const state, - uint_fast8_t const qs_id); - -/*! Helper function to execute exit from a given state in a -* hierarchical state machine (HSM). -* @private @memberof QHsm -* -* @param[in] state state handler function -* @param[in] qs_id QS-id of this state machine (for QS local filter) -* -* @returns -* 'true' if the exit action has been found in the state and -* 'flase' otherwise. -*/ -bool QHsm_state_exit_(QHsm * const me, - QStateHandler const state, - uint_fast8_t const qs_id); - -/*${QEP::QHsmVtable} .......................................................*/ -/*! @brief Virtual table for the ::QHsm class. -* -* @tr{RQP102} -*/ -struct QHsmVtable { - /*! Triggers the top-most initial transition in the HSM. */ - void (*init)(QHsm * const me, void const * const e, - uint_fast8_t const qs_id); - - /*! Dispatches an event to the HSM. */ - void (*dispatch)(QHsm * const me, QEvt const * const e, - uint_fast8_t const qs_id); - -#ifdef Q_SPY - /*! Get the current state handler of the HSM. */ - QStateHandler (*getStateHandler)(QHsm * const me); -#endif /* Q_SPY */ -}; - -/*${QEP::QMsm} .............................................................*/ -/*! @brief QM state machine implementation strategy -* @class QMsm -* @extends QHsm -* -* @details -* QMsm (QM State Machine) provides a more efficient state machine -* implementation strategy than ::QHsm, but requires the use of the QM -* modeling tool, but are the fastest and need the least run-time -* support (the smallest event-processor taking up the least code space). -* -* @note -* QMsm is not intended to be instantiated directly, but rather serves -* as the abstrace base class for derivation of state machines in the -* application code. -* -* @tr{RQP104} -* -* @usage -* The following example illustrates how to derive a state machine class -* from QMsm. Please note that the QMsm member `super` is defined -* as the *first* member of the derived struct. -* @include qep_qmsm.c -*/ -typedef struct { -/* protected: */ - QHsm super; -} QMsm; - -/* public: */ - -/*! Tests if a given state is part of the current active state -* configuration in a MSM. -* @public @memberof QMsm -* -* @details -* Tests if a state machine derived from QMsm is-in a given state. -* -* @note -* For a MSM, to "be-in" a state means also to "be-in" a superstate of -* of the state. -* -* @param[in] me current instance pointer (see @ref oop) -* @param[in] state pointer to the QMState object that corresponds to the -* tested state. -* @returns -* 'true' if the MSM "is in" the `state` and 'false' otherwise -*/ -bool QMsm_isInState(QMsm const * const me, - QMState const * const state); - -/*! Obtain the current active state from a MSM (read only) -* @public @memberof QMsm -* -* @param[in] me current instance pointer (see @ref oop) -* -* @returns the current active state-object -* -* @note -* This function is used in QM for auto-generating code for state history -*/ -QMState const * QMsm_stateObj(QHsm const * const me); - -/*! Obtain the current active child state of a given parent in ::QMsm -* @public @memberof QMsm -* -* @details -* Finds the child state of the given @c parent, such that this child state -* is an ancestor of the currently active state. The main purpose of this -* function is to support **shallow history** transitions in state machines -* derived from QMsm. -* -* @param[in] me current instance pointer (see @ref oop) -* @param[in] parent pointer to the state-handler object -* -* @returns -* the child of a given @c parent state, which is an ancestor of -* the currently active state. For the corner case when the currently active -* state is the given @c parent state, function returns the @c parent state. -* -* @sa QMsm_childStateObj() -*/ -QMState const * QMsm_childStateObj( - QHsm const * const me, - QMState const * const parent); - -/* protected: */ - -/*! Constructor of ::QMsm -* @protected @memberof QMsm -* -* @details -* Performs the first step of QMsm initialization by assigning the initial -* pseudostate to the currently active state of the state machine. -* -* @param[in,out] me current instance pointer (see @ref oop) -* @param[in] initial the top-most initial transition for the MSM. -* -* @note -* Must be called only ONCE before QHSM_INIT(). -* -* @note -* QMsm inherits QHsm, so by the @ref oop convention it should call the -* constructor of the superclass, i.e., QHsm_ctor(). However, this would pull -* in the QHsmVtable, which in turn will pull in the code for QHsm_init_() and -* QHsm_dispatch_() implemetations. To avoid this code size penalty, in case -* ::QHsm is not used in a given project, the QMsm_ctor() performs direct -* intitialization of the Vtable, which avoids pulling in the code for QMsm. -* -* @usage -* The following example illustrates how to invoke QMsm_ctor() in the -* "constructor" of a derived state machine: -* @include qep_qmsm_ctor.c -*/ -void QMsm_ctor(QMsm * const me, - QStateHandler const initial); - -/* public: */ - -/*! Implementation of the top-most initial tran. in ::QMsm. -* @private @memberof QMsm -* -* @details -* Executes the top-most initial transition in a MSM. -* -* @param[in,out] me current instance pointer (see @ref oop) -* @param[in] e pointer to an extra parameter (might be NULL) -* @param[in] qs_id QS-id of this state machine (for QS local filter) -* -* @note -* This function should be called only via the virtual table (see -* QHSM_INIT()) and should NOT be called directly in the applications. -*/ -void QMsm_init_( - QHsm * const me, - void const * const e, - uint_fast8_t const qs_id); - -/* private: */ - -/*! Implementation of dispatching events to a ::QMsm -* @private @memberof QMsm -* -* @details -* Dispatches an event for processing to a meta state machine (MSM). -* The processing of an event represents one run-to-completion (RTC) step. -* -* @param[in,out] me current instance pointer (see @ref oop) -* @param[in] e pointer to the event to be dispatched to the MSM -* @param[in] qs_id QS-id of this state machine (for QS local filter) -* -* @note -* This function should be called only via the virtual table (see -* QHSM_DISPATCH()) and should NOT be called directly in the applications. -*/ -void QMsm_dispatch_( - QHsm * const me, - QEvt const * const e, - uint_fast8_t const qs_id); - -/* public: */ - -#ifdef Q_SPY -/*! Implementation of getting the state handler in a ::QMsm subclass -* @public @memberof QMsm -*/ -QStateHandler QMsm_getStateHandler_(QHsm * const me); -#endif /* def Q_SPY */ - -/* private: */ - -/*! Execute transition-action table -* @private @memberof QMsm -* -* @details -* Helper function to execute transition sequence in a transition-action table. -* -* @param[in,out] me current instance pointer (see @ref oop) -* @param[in] tatbl pointer to the transition-action table -* @param[in] qs_id QS-id of this state machine (for QS local filter) -* -* @returns -* status of the last action from the transition-action table. -* -* @note -* This function is for internal use inside the QEP event processor and -* should **not** be called directly from the applications. -*/ -QState QMsm_execTatbl_( - QHsm * const me, - QMTranActTable const * const tatbl, - uint_fast8_t const qs_id); - -/*! Exit the current state up to the explicit transition source -* @private @memberof QMsm -* -* @details -* Static helper function to exit the current state configuration to the -* transition source, which in a hierarchical state machine might be a -* superstate of the current state. -* -* @param[in,out] me current instance pointer (see @ref oop) -* @param[in] cs pointer to the current state -* @param[in] ts pointer to the transition source state -* @param[in] qs_id QS-id of this state machine (for QS local filter) -*/ -void QMsm_exitToTranSource_( - QHsm * const me, - QMState const * const cs, - QMState const * const ts, - uint_fast8_t const qs_id); - -/*! Enter history of a composite state -* @private @memberof QMsm -* -* @details -* Static helper function to execute the segment of transition to history -* after entering the composite state and -* -* @param[in,out] me current instance pointer (see @ref oop) -* @param[in] hist pointer to the history substate -* @param[in] qs_id QS-id of this state machine (for QS local filter) -* -* @returns -* #Q_RET_TRAN_INIT, if an initial transition has been executed in the last -* entered state or #Q_RET_NULL if no such transition was taken. -*/ -QState QMsm_enterHistory_( - QHsm * const me, - QMState const *const hist, - uint_fast8_t const qs_id); -/*$enddecl${QEP} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ - -/*==========================================================================*/ -/*$declare${QEP-macros} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${QEP-macros::QHSM_INIT} .................................................*/ -#ifdef Q_SPY -/*! Virtual call to the top-most initial transition in a HSM. -* -* @param[in,out] me_ current instance pointer (see @ref oop) -* @param[in] par_ pointer the optional initialization parameter -* @param[in] qs_id_ QS local filter ID (used only when Q_SPY is defined) -* -* @note Must be called only ONCE after the SM "constructor". -* -* @tr{RQP102} -* -* @usage -* The following example illustrates how to initialize a SM, and dispatch -* events to it: -* @include qep_qhsm_use.c -*/ -#define QHSM_INIT(me_, par_, qs_id_) do { \ - Q_ASSERT((me_)->vptr); \ - (*(me_)->vptr->init)((me_), (par_), (qs_id_)); \ -} while (false) -#endif /* def Q_SPY */ - -/*${QEP-macros::QHSM_INIT} .................................................*/ -#ifndef Q_SPY -#define QHSM_INIT(me_, par_, dummy) do { \ - Q_ASSERT((me_)->vptr); \ - (*(me_)->vptr->init)((me_), (par_), 0U); \ -} while (false) -#endif /* ndef Q_SPY */ - -/*${QEP-macros::QHSM_DISPATCH} .............................................*/ -#ifdef Q_SPY -/*! Virtual call to dispatch an event to a HSM -* -* @details -* Processes one event at a time in Run-to-Completion fashion. -* -* @param[in,out] me_ current instance pointer (see @ref oop) -* @param[in] e_ constant pointer the ::QEvt or a class -* derived from ::QEvt (see @ref oop) -* @param[in] qs_id_ QS local filter ID (used only when Q_SPY is defined) -* -* @note Must be called after the "constructor" and after QHSM_INIT(). -* -* @tr{RQP102} -*/ -#define QHSM_DISPATCH(me_, e_, qs_id_) \ - ((*(me_)->vptr->dispatch)((me_), (e_), (qs_id_))) -#endif /* def Q_SPY */ - -/*${QEP-macros::QHSM_DISPATCH} .............................................*/ -#ifndef Q_SPY -#define QHSM_DISPATCH(me_, e_, dummy) \ - ((*(me_)->vptr->dispatch)((me_), (e_), 0U)) -#endif /* ndef Q_SPY */ - -/*${QEP-macros::Q_HSM_UPCAST} ..............................................*/ -/*! Perform upcast from a subclass of ::QHsm to the base class ::QHsm -* -* @details -* Upcasting from a subclass to superclass is a very frequent and **safe** -* operation in object-oriented programming and object-oriented languages -* (such as C++) perform such upcasting automatically. However, OOP is -* implemented in C just as a set of coding conventions (see @ref oop), -* and the C compiler does not "know" that certain types are related by -* inheritance. Therefore for C, the upcast must be performed explicitly. -* Unfortunately, pointer casting violates the advisory MISRA-C 2012 -* Rule 11.3(req) "A cast shall not be performed between a pointer to object -* type and a pointer to a different object type". This macro encapsulates -* this deviation and provides a descriptive name for the reason of this cast. -*/ -#define Q_HSM_UPCAST(ptr_) ((QHsm *)(ptr_)) - -/*${QEP-macros::Q_TRAN} ....................................................*/ -/*! Perform upcast from a subclass of ::QHsm to the base class ::QHsm -* -* @details -* Upcasting from a subclass to superclass is a very frequent and **safe** -* operation in object-oriented programming and object-oriented languages -* (such as C++) perform such upcasting automatically. However, OOP is -* implemented in C just as a set of coding conventions (see @ref oop), -* and the C compiler does not "know" that certain types are related by -* inheritance. Therefore for C, the upcast must be performed explicitly. -* Unfortunately, pointer casting violates the advisory MISRA-C 2012 -* Rule 11.3(req) "A cast shall not be performed between a pointer to object -* type and a pointer to a different object type". This macro encapsulates -* this deviation and provides a descriptive name for the reason of this cast. -*/ -#define Q_TRAN(target_) \ - ((Q_HSM_UPCAST(me))->temp.fun = Q_STATE_CAST(target_), Q_RET_TRAN) - -/*${QEP-macros::Q_TRAN_HIST} ...............................................*/ -/*! Macro to call in a state-handler when it executes a transition -* to history. Applicable only to HSMs. -* -* @tr{RQP103} @tr{RQP120H} -* -* @usage -* @include qep_qhist.c -*/ -#define Q_TRAN_HIST(hist_) \ - ((Q_HSM_UPCAST(me))->temp.fun = (hist_), Q_RET_TRAN_HIST) - -/*${QEP-macros::Q_SUPER} ...................................................*/ -/*! Macro to call in a state-handler when it designates the superstate -* of a given state. Applicable only to ::QHsm subclasses. -* -* @tr{RQP103} -* -* @usage -* @include qep_qsuper.c -*/ -#define Q_SUPER(super_) \ - ((Q_HSM_UPCAST(me))->temp.fun = Q_STATE_CAST(super_), Q_RET_SUPER) - -/*${QEP-macros::Q_HANDLED} .................................................*/ -/*! Macro to call in a state-handler when it handles an event. -* @tr{RQP103} @tr{RQP120B} @tr{RQP120C} -*/ -#define Q_HANDLED() (Q_RET_HANDLED) - -/*${QEP-macros::Q_UNHANDLED} ...............................................*/ -/*! Macro to call in a state-handler when it attempts to handle -* an event but a guard condition evaluates to 'false' and there is no other -* explicit way of handling the event. Applicable only to ::QHsm subclasses. -*/ -#define Q_UNHANDLED() (Q_RET_UNHANDLED) - -/*${QEP-macros::Q_ACTION_NULL} .............................................*/ -/*! Macro to provide strictly-typed zero-action to terminate action lists -*! in the transition-action-tables -*/ -#define Q_ACTION_NULL ((QActionHandler)0) - -/*${QEP-macros::Q_EVT_CAST} ................................................*/ -/*! Perform downcast of an event onto a subclass of ::QEvt `class_` -* -* @details -* This macro encapsulates the downcast of ::QEvt pointers, which violates -* MISRA-C 2012 Rule 11.3(R) "A cast shall not be performed between a -* pointer to object type and a pointer to a different object type". This -* macro helps to localize this deviation. -* -* @param class_ a subclass of ::QEvt -* -* @tr{RQP003} -* @tr{PQA11_3} -*/ -#define Q_EVT_CAST(class_) ((class_ const *)(e)) - -/*${QEP-macros::Q_STATE_CAST} ..............................................*/ -/*! Perform cast to ::QStateHandler. -* @details -* This macro encapsulates the cast of a specific state handler function -* pointer to ::QStateHandler, which violates MISRA:C-2012 Rule 11.1(req) -* "Conversions shall not be performed between a pointer to function and -* any other type". This macro helps to localize this deviation. -* -* @tr{PQP11_1} @tr{PQA11_1} -* -* @usage -* @include qep_qhsm_ctor.c -*/ -#define Q_STATE_CAST(handler_) ((QStateHandler)(handler_)) - -/*${QEP-macros::Q_ACTION_CAST} .............................................*/ -/*! Perform cast to ::QActionHandler. -* @details -* This macro encapsulates the cast of a specific action handler function -* pointer to ::QActionHandler, which violates MISRA:C-2012 Rule 11.1(R) -* "Conversions shall not be performed between a pointer to function and -* any other type". This macro helps to localize this deviation. -* -* @tr{PQP11_1} @tr{PQA11_1} -*/ -#define Q_ACTION_CAST(action_) ((QActionHandler)(action_)) - -/*${QEP-macros::Q_UNUSED_PAR} ..............................................*/ -/*! Helper macro to clearly mark unused parameters of functions. */ -#define Q_UNUSED_PAR(par_) ((void)(par_)) - -/*${QEP-macros::Q_DIM} .....................................................*/ -/*! Helper macro to calculate static dimension of a 1-dim `array_` -* -* @param array_ 1-dimensional array -* @returns the length of the array (number of elements it can hold) -*/ -#define Q_DIM(array_) (sizeof(array_) / sizeof((array_)[0U])) - -/*${QEP-macros::Q_UINT2PTR_CAST} ...........................................*/ -/*! Perform cast from unsigned integer `uint_` to pointer of type `type_` -* -* @details -* This macro encapsulates the cast to (type_ *), which QP ports or -* application might use to access embedded hardware registers. -* Such uses can trigger PC-Lint "Note 923: cast from int to pointer" -* and this macro helps to encapsulate this deviation. -*/ -#define Q_UINT2PTR_CAST(type_, uint_) ((type_ *)(uint_)) - -/*${QEP-macros::QEVT_INITIALIZER} ..........................................*/ -/*! Initializer of static constant QEvt instances -* -* @details -* This macro encapsulates the ugly casting of enumerated signals -* to QSignal and constants for QEvt.poolID and QEvt.refCtr_. -*/ -#define QEVT_INITIALIZER(sig_) { (QSignal)(sig_), 0U, 0U } - -/*${QEP-macros::QM_ENTRY} ..................................................*/ -#ifdef Q_SPY -/*! Macro to call in a QM action-handler when it executes -* an entry action. Applicable only to ::QMsm subclasses. -*/ -#define QM_ENTRY(state_) \ - ((Q_HSM_UPCAST(me))->temp.obj = (state_), Q_RET_ENTRY) -#endif /* def Q_SPY */ - -/*${QEP-macros::QM_ENTRY} ..................................................*/ -#ifndef Q_SPY -#define QM_ENTRY(dummy) (Q_RET_ENTRY) -#endif /* ndef Q_SPY */ - -/*${QEP-macros::QM_EXIT} ...................................................*/ -#ifdef Q_SPY -/*! Macro to call in a QM action-handler when it executes -* an exit action. Applicable only to ::QMsm subclasses. -*/ -#define QM_EXIT(state_) \ - ((Q_HSM_UPCAST(me))->temp.obj = (state_), Q_RET_EXIT) -#endif /* def Q_SPY */ - -/*${QEP-macros::QM_EXIT} ...................................................*/ -#ifndef Q_SPY -#define QM_EXIT(dummy) (Q_RET_EXIT) -#endif /* ndef Q_SPY */ - -/*${QEP-macros::QM_SM_EXIT} ................................................*/ -/*! Macro to call in a QM submachine exit-handler. -* Applicable only to subclasses of ::QMsm. -*/ -#define QM_SM_EXIT(state_) \ - ((Q_HSM_UPCAST(me))->temp.obj = (state_), Q_RET_EXIT) - -/*${QEP-macros::QM_TRAN} ...................................................*/ -/*! Macro to call in a QM state-handler when it executes a regular -* transition. Applicable only to ::QMsm subclasses. -*/ -#define QM_TRAN(tatbl_) ((Q_HSM_UPCAST(me))->temp.tatbl \ - = (struct QMTranActTable const *)(tatbl_), Q_RET_TRAN) - -/*${QEP-macros::QM_TRAN_INIT} ..............................................*/ -/*! Macro to call in a QM state-handler when it executes an initial -* transition. Applicable only to ::QMsm subclasses. -*/ -#define QM_TRAN_INIT(tatbl_) ((Q_HSM_UPCAST(me))->temp.tatbl \ - = (struct QMTranActTable const *)(tatbl_), Q_RET_TRAN_INIT) - -/*${QEP-macros::QM_TRAN_HIST} ..............................................*/ -/*! Macro to call in a QM state-handler when it executes a transition -* to history. Applicable only to ::QMsm subclasses. -*/ -#define QM_TRAN_HIST(history_, tatbl_) \ - ((((Q_HSM_UPCAST(me))->state.obj = (history_)), \ - ((Q_HSM_UPCAST(me))->temp.tatbl = \ - (struct QMTranActTable const *)(tatbl_))), \ - Q_RET_TRAN_HIST) - -/*${QEP-macros::QM_TRAN_EP} ................................................*/ -/*! Macro to call in a QM state-handler when it executes a transition -* to the submachine via an entry point. -*/ -#define QM_TRAN_EP(tatbl_) ((Q_HSM_UPCAST(me))->temp.tatbl \ - = (struct QMTranActTable const *)(tatbl_), Q_RET_TRAN_EP) - -/*${QEP-macros::QM_TRAN_XP} ................................................*/ -/*! Macro to call in a QM state-handler when it executes a transition -* to exit point. Applicable only to ::QMsm subclasses. -*/ -#define QM_TRAN_XP(xp_, tatbl_) \ - ((((Q_HSM_UPCAST(me))->state.act = (xp_)), \ - ((Q_HSM_UPCAST(me))->temp.tatbl = \ - (struct QMTranActTable const *)(tatbl_))), \ - Q_RET_TRAN_XP) - -/*${QEP-macros::QM_HANDLED} ................................................*/ -/*! Macro to call in a QM state-handler when it handled an event. -* Applicable only to ::QMsm subclasses. -*/ -#define QM_HANDLED() (Q_RET_HANDLED) - -/*${QEP-macros::QM_UNHANDLED} ..............................................*/ -/*! Macro to call in a QM state-handler when when it attempts to -* handle an event but a guard condition evaluates to 'false' and there is -* no other explicit way of handling the event. Applicable only to -* ::QMsm subclasses. -*/ -#define QM_UNHANDLED() (Q_RET_UNHANDLED) - -/*${QEP-macros::QM_SUPER} ..................................................*/ -/*! Macro to call in a QM state-handler when it designates the -* superstate to handle an event. Applicable only to QMSMs. -*/ -#define QM_SUPER() (Q_RET_SUPER) - -/*${QEP-macros::QM_SUPER_SUB} ..............................................*/ -/*! Macro to call in a QM submachine-handler when it designates the -* host state to handle an event. Applicable only to subclasses of ::QMsm. -*/ -#define QM_SUPER_SUB(host_) \ - ((Q_HSM_UPCAST(me))->temp.obj = (host_), Q_RET_SUPER_SUB) - -/*${QEP-macros::QM_STATE_NULL} .............................................*/ -/*! Macro to provide strictly-typed zero-state to use for submachines. -*! Applicable to subclasses of ::QMsm. -*/ -#define QM_STATE_NULL ((QMState *)0) -/*$enddecl${QEP-macros} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ - -#endif /* QP_INC_QEP_H_ */ diff --git a/include/qequeue.h b/include/qequeue.h index 276dbe7d..3aa01a0d 100644 --- a/include/qequeue.h +++ b/include/qequeue.h @@ -1,75 +1,53 @@ -/*$file${include::qequeue.h} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* -* Model: qpc.qm -* File: ${include::qequeue.h} -* -* This code has been generated by QM 5.2.4 . -* DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. -* -* This code is covered by the following QP license: -* License # : LicenseRef-QL-dual -* Issued to : Any user of the QP/C real-time embedded framework -* Framework(s) : qpc -* Support ends : 2023-12-31 -* License scope: -* -* Copyright (C) 2005 Quantum Leaps, LLC . -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -*/ -/*$endhead${include::qequeue.h} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*! @file -* @brief QP natvie, platform-independent, thread-safe event queue interface -* @details -* This header file must be included in all QF ports that use native QF -* event queue for active objects. Also, this file needs to be included -* in the QP/C library when the application uses QActive_defer()/ -* QActive_recall(). Finally, this file is also needed when the "raw" -* thread-safe queues are used for communication between active objects -* and non-framework entities, such as ISRs, device drivers, or legacy -* code. -*/ -#ifndef QP_INC_QEQUEUE_H_ -#define QP_INC_QEQUEUE_H_ +//$file${include::qequeue.h} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// +// Model: qpc.qm +// File: ${include::qequeue.h} +// +// This code has been generated by QM 5.3.0 . +// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. +// +// This code is covered by the following QP license: +// License # : LicenseRef-QL-dual +// Issued to : Any user of the QP/C real-time embedded framework +// Framework(s) : qpc +// Support ends : 2024-12-31 +// License scope: +// +// Copyright (C) 2005 Quantum Leaps, LLC . +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +// +//$endhead${include::qequeue.h} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +#ifndef QEQUEUE_H_ +#define QEQUEUE_H_ #ifndef QF_EQUEUE_CTR_SIZE - - /*! The size [bytes] of the ring-buffer counters used in the - * native QF event queue implementation. Valid values: 1U, 2U, or 4U; - * default 1U. - * @details - * This macro can be defined in the QF port file (qf_port.h) to - * configure the ::QEQueueCtr type. Here the macro is not defined so the - * default of 1 byte is chosen. - */ #define QF_EQUEUE_CTR_SIZE 1U #endif -#if (QF_EQUEUE_CTR_SIZE == 1U) - /*! The data type to store the ring-buffer counters based on - * the macro #QF_EQUEUE_CTR_SIZE. - * @details - * The dynamic range of this data type determines the maximum length - * of the ring buffer managed by the native QF event queue. - */ +#if (QF_EQUEUE_CTR_SIZE == 1U) typedef uint8_t QEQueueCtr; #elif (QF_EQUEUE_CTR_SIZE == 2U) typedef uint16_t QEQueueCtr; @@ -79,269 +57,76 @@ #error "QF_EQUEUE_CTR_SIZE defined incorrectly, expected 1U, 2U, or 4U" #endif -/*==========================================================================*/ -/*$declare${QF::QEQueue} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +struct QEvt; // forward declaration -/*${QF::QEQueue} ...........................................................*/ -/*! @brief Native QF Event Queue -* @class QEQueue -* -* @details -* This class describes the native QF event queue, which can be used as -* the event queue for active objects, or as a simple "raw" event queue for -* thread-safe event passing among non-framework entities, such as ISRs, -* device drivers, or other third-party components.
-* -* The native QF event queue is configured by defining the macro -* #QF_EQUEUE_TYPE as ::QEQueue in the specific QF port header file.
-*
-* The ::QEQueue structure contains only data members for managing an event -* queue, but does not contain the storage for the queue buffer, which must -* be provided externally during the queue initialization.
-*
-* The event queue can store only event pointers, not the whole events. The -* internal implementation uses the standard ring-buffer plus one external -* location that optimizes the queue operation for the most frequent case -* of empty queue.
-*
-* The ::QEQueue structure is used with two sets of functions. One set is for -* the active object event queue, which might need to block the active object -* task when the event queue is empty and might need to unblock it when -* events are posted to the queue. The interface for the native active object -* event queue consists of the following functions: QActive_post(), -* QActive_postLIFO(), and QActive_get_(). Additionally the function -* QEQueue_init() is used to initialize the queue.
-*
-* The other set of functions, uses ::QEQueue as a simple "raw" event -* queue to pass events between entities other than active objects, such as -* ISRs. The "raw" event queue is not capable of blocking on the get() -* operation, but is still thread-safe because it uses QF critical section -* to protect its integrity. The interface for the "raw" thread-safe queue -* consists of the following functions: QEQueue_post(), -* QEQueue_postLIFO(), and QEQueue_get(). Additionally the function -* QEQueue_init() is used to initialize the queue. -* -*
ote Most event queue operations (both the active object queues and -* the "raw" queues) internally use the QF critical section. You should be -* careful not to invoke those operations from other critical sections when -* nesting of critical sections is not supported. -* -* @sa ::QEQueue for the description of the data members -*/ -typedef struct { -/* private: */ +//$declare${QF::QEQueue} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv - /*! pointer to event at the front of the queue. - * @private @memberof QEQueue - * - * @details - * All incoming and outgoing events pass through the frontEvt location. - * When the queue is empty (which is most of the time), the extra - * frontEvt location allows to bypass the ring buffer altogether, - * greatly optimizing the performance of the queue. Only bursts of events - * engage the ring buffer. - * - *
ote The additional role of this attribute is to indicate the empty - * status of the queue. The queue is empty when frontEvt is NULL. - */ - QEvt const * volatile frontEvt; +//${QF::QEQueue} ............................................................. +//! @class QEQueue +typedef struct QEQueue { +// private: - /*! pointer to the start of the ring buffer - * @private @memberof QEQueue - */ - QEvt const ** ring; + //! @private @memberof QEQueue + struct QEvt const * volatile frontEvt; - /*! offset of the end of the ring buffer from the start of the buffer - * @private @memberof QEQueue - */ + //! @private @memberof QEQueue + struct QEvt const ** ring; + + //! @private @memberof QEQueue QEQueueCtr end; - /*! offset to where next event will be inserted into the buffer - * @private @memberof QEQueue - */ + //! @private @memberof QEQueue QEQueueCtr volatile head; - /*! offset of where next event will be extracted from the buffer - * @private @memberof QEQueue - */ + //! @private @memberof QEQueue QEQueueCtr volatile tail; - /*! number of free events in the ring buffer - * @private @memberof QEQueue - */ + //! @private @memberof QEQueue QEQueueCtr volatile nFree; - /*! Minimum number of free events ever in the ring buffer. - * @private @memberof QEQueue - * - * @details - * This attribute remembers the low-watermark of the ring buffer, - * which provides a valuable information for sizing event queues. - * @sa QF_getQueueMargin(). - */ + //! @private @memberof QEQueue QEQueueCtr nMin; + +// public: } QEQueue; +extern QEQueue QEQueue_dummy; -/* public: */ +// public: -/*! Initialize the native QF event queue. -* @public @memberof QEQueue -* -* @details -* Initialize the event queue by giving it the storage for the ring buffer. -* -* @param[in,out] me current instance pointer (see @ref oop) -* @param[in] qSto an array of pointers to ::QEvt to sereve as the -* ring buffer for the event queue -* @param[in] qLen the length of the `qSto` buffer (in ::QEvt pointers) -* -* @note The actual capacity of the queue is qLen + 1, because of the extra -* location forntEvt. -* -* @note -* This function is also used to initialize the event queues of active -* objects in the built-int QV and QK kernels, as well as other -* QP ports to OSes/RTOSes that do provide a suitable message queue. -*/ +//! @public @memberof QEQueue void QEQueue_init(QEQueue * const me, - QEvt const ** const qSto, + struct QEvt const ** const qSto, uint_fast16_t const qLen); -/*! Post an event to the "raw" thread-safe event queue (FIFO). -* @public @memberof QEQueue -* -* @details -* Post an event to the "raw" thread-safe event queue using the -* First-In-First-Out (FIFO) order. -* -* @param[in,out] me current instance pointer (see @ref oop) -* @param[in] e pointer to the event to be posted to the queue -* @param[in] margin number of required free slots in the queue after -* posting the event. The special value #QF_NO_MARGIN -* means that this function will assert if posting -* @note -* The #QF_NO_MARGIN value of the `margin` parameter is special and -* denotes situation when the post() operation is assumed to succeed (event -* delivery guarantee). An assertion fires, when the event cannot be -* delivered in this case. -* -* @returns 'true' (success) when the posting succeeded with the provided -* margin and 'false' (failure) when the posting fails. -* -* @note This function can be called from any task context or ISR context. -* -* @sa QEQueue_postLIFO(), QEQueue_get() -*/ +//! @public @memberof QEQueue bool QEQueue_post(QEQueue * const me, - QEvt const * const e, + struct QEvt const * const e, uint_fast16_t const margin, uint_fast8_t const qs_id); -/*! Post an event to the "raw" thread-safe event queue (LIFO). -* @public @memberof QEQueue -* -* @details -* Post an event to the "raw" thread-safe event queue using the -* Last-In-First-Out (LIFO) order. -* -* @param[in,out] me current instance pointer (see @ref oop) -* @param[in] e pointer to the event to be posted to the queue -* -* @attention -* The LIFO policy should be used only with great __caution__, because -* it alters the order of events in the queue. -* -* @note -* This function can be called from any task context or ISR context. -* -* @note -* this function is used for the "raw" thread-safe queues and __not__ -* for the queues of active objects. -* -* @sa -* QEQueue_post(), QEQueue_get(), QActive_defer() -*/ +//! @public @memberof QEQueue void QEQueue_postLIFO(QEQueue * const me, - QEvt const * const e, + struct QEvt const * const e, uint_fast8_t const qs_id); -/*! Obtain an event from the "raw" thread-safe queue. -* @public @memberof QEQueue -* -* @details -* Retrieves an event from the front of the "raw" thread-safe queue and -* returns a pointer to this event to the caller. -* -* @param[in,out] me current instance pointer (see @ref oop) -* -* @returns -* pointer to event at the front of the queue, if the queue is -* not empty and NULL if the queue is empty. -* -* @note -* this function is used for the "raw" thread-safe queues and __not__ -* for the queues of active objects. -* -* @sa -* QEQueue_post(), QEQueue_postLIFO(), QActive_recall() -*/ -QEvt const * QEQueue_get(QEQueue * const me, +//! @public @memberof QEQueue +struct QEvt const * QEQueue_get(QEQueue * const me, uint_fast8_t const qs_id); -/*! "raw" thread-safe QF event queue operation for obtaining the number -* of free entries still available in the queue. -* @public @memberof QEQueue -* -* @details -* This operation needs to be used with caution because the number of free -* entries can change unexpectedly. The main intent for using this operation -* is in conjunction with event deferral. In this case the queue is accessed -* only from a single thread (by a single AO), so the number of free -* entries cannot change unexpectedly. -* -* @param[in] me current instance pointer (see @ref oop) -* -* @returns the current number of free slots in the queue. -*/ +//! @public @memberof QEQueue static inline QEQueueCtr QEQueue_getNFree(QEQueue const * const me) { return me->nFree; } -/*! "raw" thread-safe QF event queue operation for obtaining the minimum -* number of free entries ever in the queue (a.k.a. "low-watermark"). -* @public @memberof QEQueue -* -* @details -* This operation needs to be used with caution because the "low-watermark" -* can change unexpectedly. The main intent for using this operation is to -* get an idea of queue usage to size the queue adequately. -* -* @param[in] me current instance pointer (see @ref oop) -* -* @returns the minimum number of free entries ever in the queue since init. -*/ +//! @public @memberof QEQueue static inline QEQueueCtr QEQueue_getNMin(QEQueue const * const me) { return me->nMin; } -/*! "raw" thread-safe QF event queue operation to find out if the queue -* is empty. -* @public @memberof QEQueue -* -* @details -* This operation needs to be used with caution because the queue status -* can change unexpectedly. The main intent for using this operation is in -* conjunction with event deferral. In this case the queue is accessed only -* from a single thread (by a single AO), so no other entity can post -* events to the queue. -* -* @param[in] me_ current instance pointer (see @ref oop) -* -* @returns 'true' if the queue is current empty and 'false' otherwise. -*/ +//! @public @memberof QEQueue static inline bool QEQueue_isEmpty(QEQueue const * const me) { - return me->frontEvt == (QEvt *)0; + return me->frontEvt == (struct QEvt *)0; } -/*$enddecl${QF::QEQueue} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$enddecl${QF::QEQueue} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -#endif /* QP_INC_QEQUEUE_H_ */ +#endif // QEQUEUE_H_ diff --git a/include/qf.h b/include/qf.h deleted file mode 100644 index e3c6b50c..00000000 --- a/include/qf.h +++ /dev/null @@ -1,2047 +0,0 @@ -/*$file${include::qf.h} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* -* Model: qpc.qm -* File: ${include::qf.h} -* -* This code has been generated by QM 5.2.4 . -* DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. -* -* This code is covered by the following QP license: -* License # : LicenseRef-QL-dual -* Issued to : Any user of the QP/C real-time embedded framework -* Framework(s) : qpc -* Support ends : 2023-12-31 -* License scope: -* -* Copyright (C) 2005 Quantum Leaps, LLC . -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -*/ -/*$endhead${include::qf.h} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*! @file -* @brief QF/C platform-independent public interface. -*/ -#ifndef QP_INC_QF_H_ -#define QP_INC_QF_H_ - -/*==========================================================================*/ -/*$declare${QF-config} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${QF-config::QF_MAX_ACTIVE} ..............................................*/ -#ifndef QF_MAX_ACTIVE -/*! Maximum number of active objects (configurable value in qf_port.h) -* Valid values: [1U..64U]; default 32U -*/ -#define QF_MAX_ACTIVE 32U -#endif /* ndef QF_MAX_ACTIVE */ - -/*${QF-config::QF_MAX_ACTIVE exceeds the maximu~} ..........................*/ -#if (QF_MAX_ACTIVE > 64U) -#error QF_MAX_ACTIVE exceeds the maximum of 64U; -#endif /* (QF_MAX_ACTIVE > 64U) */ - -/*${QF-config::QF_MAX_TICK_RATE} ...........................................*/ -#ifndef QF_MAX_TICK_RATE -/*! Maximum number of clock rates (configurable value in qf_port.h) -* Valid values: [0U..15U]; default 1U -*/ -#define QF_MAX_TICK_RATE 1U -#endif /* ndef QF_MAX_TICK_RATE */ - -/*${QF-config::QF_MAX_TICK_RATE exceeds the max~} ..........................*/ -#if (QF_MAX_TICK_RATE > 15U) -#error QF_MAX_TICK_RATE exceeds the maximum of 15U; -#endif /* (QF_MAX_TICK_RATE > 15U) */ - -/*${QF-config::QF_MAX_EPOOL} ...............................................*/ -#ifndef QF_MAX_EPOOL -/*! Maximum number of event pools (configurable value in qf_port.h) -* Valid values: [0U..15U]; default 3U -* -* @note -* #QF_MAX_EPOOL set to zero means that dynamic events are NOT configured -* and should not be used in the application. -*/ -#define QF_MAX_EPOOL 3U -#endif /* ndef QF_MAX_EPOOL */ - -/*${QF-config::QF_MAX_EPOOL exceeds the maximum~} ..........................*/ -#if (QF_MAX_EPOOL > 15U) -#error QF_MAX_EPOOL exceeds the maximum of 15U; -#endif /* (QF_MAX_EPOOL > 15U) */ - -/*${QF-config::QF_TIMEEVT_CTR_SIZE} ........................................*/ -#ifndef QF_TIMEEVT_CTR_SIZE -/*! Size of the QTimeEvt counter (configurable value in qf_port.h) -* Valid values: 1U, 2U, or 4U; default 4U -*/ -#define QF_TIMEEVT_CTR_SIZE 4U -#endif /* ndef QF_TIMEEVT_CTR_SIZE */ - -/*${QF-config::QF_TIMEEVT_CTR_SIZE defined inco~} ..........................*/ -#if (QF_TIMEEVT_CTR_SIZE != 1U) && (QF_TIMEEVT_CTR_SIZE != 2U) && (QF_TIMEEVT_CTR_SIZE != 4U) -#error QF_TIMEEVT_CTR_SIZE defined incorrectly, expected 1U, 2U, or 4U; -#endif /* (QF_TIMEEVT_CTR_SIZE != 1U) && (QF_TIMEEVT_CTR_SIZE != 2U) && (QF_TIMEEVT_CTR_SIZE != 4U) */ - -/*${QF-config::QF_EVENT_SIZ_SIZE} ..........................................*/ -#ifndef QF_EVENT_SIZ_SIZE -/*! Size of the event-size (configurable value in qf_port.h) -* Valid values: 1U, 2U, or 4U; default 2U -*/ -#define QF_EVENT_SIZ_SIZE 2U -#endif /* ndef QF_EVENT_SIZ_SIZE */ - -/*${QF-config::QF_EVENT_SIZ_SIZE defined incorr~} ..........................*/ -#if (QF_EVENT_SIZ_SIZE != 1U) && (QF_EVENT_SIZ_SIZE != 2U) && (QF_EVENT_SIZ_SIZE != 4U) -#error QF_EVENT_SIZ_SIZE defined incorrectly, expected 1U, 2U, or 4U; -#endif /* (QF_EVENT_SIZ_SIZE != 1U) && (QF_EVENT_SIZ_SIZE != 2U) && (QF_EVENT_SIZ_SIZE != 4U) */ -/*$enddecl${QF-config} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ - -/*==========================================================================*/ -/*$declare${QF-types} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${QF-types::QPSetBits} ...................................................*/ -#if (8U < QF_MAX_ACTIVE) && (QF_MAX_ACTIVE <= 16U) -/*! bitmask for the internal representation of QPSet elements */ -typedef uint16_t QPSetBits; -#endif /* (8U < QF_MAX_ACTIVE) && (QF_MAX_ACTIVE <= 16U) */ - -/*${QF-types::QPSetBits} ...................................................*/ -#if (16 < QF_MAX_ACTIVE) -typedef uint32_t QPSetBits; -#endif /* (16 < QF_MAX_ACTIVE) */ - -/*${QF-types::QPSetBits} ...................................................*/ -#if (QF_MAX_ACTIVE <= 8U) -typedef uint8_t QPSetBits; -#endif /* (QF_MAX_ACTIVE <= 8U) */ - -/*${QF-types::QTimeEvtCtr} .................................................*/ -#if (QF_TIMEEVT_CTR_SIZE == 2U) -/*! Data type to store the block-size defined based on the macro -* #QF_TIMEEVT_CTR_SIZE. -* -* @details -* The dynamic range of this data type determines the maximum block -* size that can be managed by the pool. -*/ -typedef uint16_t QTimeEvtCtr; -#endif /* (QF_TIMEEVT_CTR_SIZE == 2U) */ - -/*${QF-types::QTimeEvtCtr} .................................................*/ -#if (QF_TIMEEVT_CTR_SIZE == 4U) -typedef uint32_t QTimeEvtCtr; -#endif /* (QF_TIMEEVT_CTR_SIZE == 4U) */ - -/*${QF-types::QTimeEvtCtr} .................................................*/ -#if (QF_TIMEEVT_CTR_SIZE == 1U) -typedef uint8_t QTimeEvtCtr; -#endif /* (QF_TIMEEVT_CTR_SIZE == 1U) */ - -/*${QF-types::QF_LOG2} .....................................................*/ -#ifndef QF_LOG2 -/*! Log-base-2 calculation when hardware acceleration -* is NOT provided (#QF_LOG2 not defined). -*/ -uint_fast8_t QF_LOG2(QPSetBits x); -#endif /* ndef QF_LOG2 */ - -/*${QF-types::QPrioSpec} ...................................................*/ -/*! Priority specification for Active Objects in QP -* -* @details -* Active Object priorities in QP are integer numbers in the range -* [1..#QF_MAX_ACTIVE], whereas the special priority number 0 is reserved -* for the lowest-priority idle thread. The QP framework uses the *direct* -* priority numbering, in which higher numerical values denote higher urgency. -* For example, an AO with priority 32 has higher urgency than an AO with -* priority 23. -* -* ::QPrioSpec allows an application developer to assign **two** -* priorities to a given AO (see also Q_PRIO()): -* -* 1. The "QF-priority", which resides in the least-significant byte -* of the ::QPrioSpec data type. The "QF-priority" must be **unique** -* for each thread in the system and higher numerical values represent -* higher urgency (direct pirority numbering). -* -* 2. The "preemption-threshold" priority, which resides in the most- -* significant byte of the ::QPrioSpec data type. The second priority -* cannot be lower than the "QF-priority", but does NOT need to be -* unuque. -* -* In the QP native preemptive kernels, like QK and QXK, the "preemption- -* threshold" priority is used as to implement the "preemption-threshold -* scheduling" (PTS). It determines the conditions under which a given -* thread can be *preempted* by other threads. Specifically, a given -* thread can be preempted only by another thread with a *higher* -* priority than the "preemption-threshold" of the original thread. -* -* ![QF-priority and preemption-threshold relations](qp-prio.png) -* -* @note -* For backwards-compatibility, ::QPrioSpec data type might contain only -* the "QF-priority" component (and the "preemption-threshold" component -* left at zero). In that case, the "preemption-threshold" will be assumed -* to be the same as the "QF-priority". This corresponds exactly to the -* previous semantics of AO priority. -* -* @remark -* When QP runs on top of 3rd-party kernels/RTOSes or general-purpose -* operating systems, sthe second priority can have different meaning, -* depending on the specific RTOS/GPOS used. -*/ -typedef uint16_t QPrioSpec; - -/*${QF-types::QSchedStatus} ................................................*/ -/*! The scheduler lock status used in some real-time kernels */ -typedef uint_fast16_t QSchedStatus; - -/*${QF-types::QPSet} .......................................................*/ -/*! @brief Priority Set of up to #QF_MAX_ACTIVE elements -* @class QPSet -* -* @details -* The priority set represents the set of active objects that are ready to -* run and need to be considered by the scheduling algorithm. The set is -* capable of storing up to #QF_MAX_ACTIVE priority levels, which can be -* configured in the rage 1..64, inclusive. -*/ -typedef struct { -/* public: */ - -#if (QF_MAX_ACTIVE <= 32) - /*! bitmask with a bit for each element */ - QPSetBits volatile bits; -#endif /* (QF_MAX_ACTIVE <= 32) */ - -#if (32 < QF_MAX_ACTIVE) - /*! bitmasks with a bit for each element */ - QPSetBits volatile bits[2]; -#endif /* (32 < QF_MAX_ACTIVE) */ -} QPSet; - -/* public: */ - -/*! Make the priority set empty */ -static inline void QPSet_setEmpty(QPSet * const me) { - #if (QF_MAX_ACTIVE <= 32) - me->bits = 0U; - #else - me->bits[0] = 0U; - me->bits[1] = 0U; - #endif -} - -/*! Return 'true' if the priority set is empty */ -static inline bool QPSet_isEmpty(QPSet const * const me) { - #if (QF_MAX_ACTIVE <= 32) - return (me->bits == 0U); - #else - return (me->bits[0] == 0U) ? (me->bits[1] == 0U) : false; - #endif -} - -/*! Return 'true' if the priority set is NOT empty */ -static inline bool QPSet_notEmpty(QPSet const * const me) { - #if (QF_MAX_ACTIVE <= 32) - return (me->bits != 0U); - #else - return (me->bits[0] != 0U) ? true : (me->bits[1] != 0U); - #endif -} - -/*! Return 'true' if the priority set has the element n. */ -static inline bool QPSet_hasElement(QPSet const * const me, - uint_fast8_t const n) -{ - #if (QF_MAX_ACTIVE <= 32U) - return (me->bits & (1U << (n - 1U))) != 0U; - #else - return (n <= 32U) - ? ((me->bits[0] & ((uint32_t)1U << (n - 1U))) != 0U) - : ((me->bits[1] & ((uint32_t)1U << (n - 33U))) != 0U); - #endif -} - -/*! insert element `n` into the set (n = 1..::QF_MAX_ACTIVE) */ -static inline void QPSet_insert(QPSet * const me, - uint_fast8_t const n) -{ - #if (QF_MAX_ACTIVE <= 32U) - me->bits = (me->bits | (1U << (n - 1U))); - #else - if (n <= 32U) { - me->bits[0] = (me->bits[0] | ((uint32_t)1U << (n - 1U))); - } - else { - me->bits[1] = (me->bits[1] | ((uint32_t)1U << (n - 33U))); - } - #endif -} - -/*! Remove element `n` from the set (n = 1U..::QF_MAX_ACTIVE) */ -static inline void QPSet_remove(QPSet * const me, - uint_fast8_t const n) -{ - #if (QF_MAX_ACTIVE <= 32U) - me->bits = (me->bits & - (QPSetBits)(~((QPSetBits)1U << (n - 1U)))); - #else - if (n <= 32U) { - (me->bits[0] = (me->bits[0] & ~((uint32_t)1U << (n - 1U)))); - } - else { - (me->bits[1] = (me->bits[1] & ~((uint32_t)1U << (n - 33U)))); - } - #endif -} - -/*! Find the maximum element in the set, returns zero if the set is empty */ -static inline uint_fast8_t QPSet_findMax(QPSet const * const me) { - #if (QF_MAX_ACTIVE <= 32) - return QF_LOG2(me->bits); - #else - return (me->bits[1] != 0U) - ? (QF_LOG2(me->bits[1]) + 32U) - : (QF_LOG2(me->bits[0])); - #endif -} - -/*${QF-types::QSubscrList} .................................................*/ -/*! Subscriber List (for publish-subscribe) -* -* @details -* This data type represents a set of Active Objects that subscribe to -* a given signal. The set is represented as priority-set, where each -* bit corresponds to the unique QF-priority of an AO (see ::QPrioSpec). -*/ -typedef QPSet QSubscrList; -/*$enddecl${QF-types} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*$declare${QF::QActive} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${QF::QActive} ...........................................................*/ -/*! @brief Active object class (based on the QHsm implementation strategy) -* @class QActive -* @extends QHsm -* -* @details -* Active objects are encapsulated tasks (each containing an event queue and -* a state machine) that communicate with one another asynchronously by -* sending and receiving events. Within an active object, events are -* processed in a run-to-completion (RTC) fashion, while QF encapsulates -* all the details of thread-safe event exchange and queuing.
-* -* QActive represents an active object that uses the QHsm-style -* implementation strategy for state machines. This strategy is tailored -* to manual coding, but it is also supported by the QM modeling tool. -* The resulting code is slower than in the ::QMsm-style implementation -* strategy. -* -* @note -* QActive is not intended to be instantiated directly, but rather serves -* as the abstract base class for derivation of active objects in the -* applications. -* -* @sa QMActive -* -* @usage -* The following example illustrates how to derive an active object from -* QActive. -* @include qf_qactive.c -*/ -typedef struct QActive { -/* protected: */ - QHsm super; - -/* private: */ - -#ifdef QF_EQUEUE_TYPE - /*! OS-dependent event-queue type - * @private @memberof QActive - * - * @details - * The type of the queue depends on the underlying operating system or - * a kernel. Many kernels support "message queues" that can be adapted - * to deliver QF events to the active object. Alternatively, QF provides - * a native event queue implementation that can be used as well. - * - * @note - * The native QF event queue is configured by defining the macro - * #QF_EQUEUE_TYPE as ::QEQueue. - */ - QF_EQUEUE_TYPE eQueue; -#endif /* def QF_EQUEUE_TYPE */ - -#ifdef QF_OS_OBJECT_TYPE - /*! OS-dependent per-thread object - * @private @memberof QActive - * - * @details - * This data might be used in various ways, depending on the QF port. - * In some ports me->osObject is used to block the calling thread when - * the native QF queue is empty. In other QF ports the OS-dependent - * object might be used differently. - */ - QF_OS_OBJECT_TYPE osObject; -#endif /* def QF_OS_OBJECT_TYPE */ - -#ifdef QF_THREAD_TYPE - /*! OS-dependent representation of the thread of the active object - * @private @memberof QActive - * - * @details - * This data might be used in various ways, depending on the QF port. - * In some ports me->thread is used store the thread handle. In other ports - * me->thread can be a pointer to the Thread-Local-Storage (TLS). - */ - QF_THREAD_TYPE thread; -#endif /* def QF_THREAD_TYPE */ - -/* public: */ - - /*! QF-priority [1..#QF_MAX_ACTIVE] of this AO. - * @private @memberof QActive - * @sa ::QPrioSpec - */ - uint8_t prio; - - /*! preemption-threshold [1..#QF_MAX_ACTIVE] of this AO. - * @private @memberof QActive - * @sa ::QPrioSpec - */ - uint8_t pthre; - -/* private: */ -} QActive; - -/* protected: */ - -/*! ::QActive constructor (abstract base class) -* @protected @memberof QActive -*/ -void QActive_ctor(QActive * const me, - QStateHandler const initial); - -/* private: */ - -/*! Starts execution of an active object and registers the object -* with the framework -* @private @memberof QActive -* -* @details -* Starts execution of the AO and registers the AO with the framework. -* -* @param[in] prioSpec priority specification for the AO (See ::QPrioSpec) -* @param[in] qSto pointer to the storage for the ring buffer of the -* event queue -* @param[in] qLen length of the event queue [# ::QEvt* pointers] -* @param[in] stkSto pointer to the stack storage (might be NULL) -* @param[in] stkSize stack size [bytes] -* @param[in] par pointer to an extra parameter (might be NULL) -* -* @usage -* The following example shows starting an AO when a per-task stack -* is needed: -* @include qf_start.c -*/ -void QActive_start_(QActive * const me, - QPrioSpec const prioSpec, - QEvt const * * const qSto, - uint_fast16_t const qLen, - void * const stkSto, - uint_fast16_t const stkSize, - void const * const par); - -/* protected: */ - -#ifdef QF_ACTIVE_STOP -/*! Stops execution of an active object and removes it from the -* framework's supervision -* @protected @memberof QActive -* -* @attention -* QActive_stop() must be called only from the AO that is about -* to stop its execution. By that time, any pointers or references -* to the AO are considered invalid (dangling) and it becomes -* illegal for the rest of the application to post events to the AO. -*/ -void QActive_stop(QActive * const me); -#endif /* def QF_ACTIVE_STOP */ - -/* private: */ - -/*! Posts an event `e` directly to the event queue of the active object -* using the First-In-First-Out (FIFO) policy. -* @private @memberof QActive -* -* @details -* Direct event posting is the simplest asynchronous communication -* method available in QF. -* -* @param[in] e pointer to the event to be posted -* @param[in] margin number of required free slots in the queue -* after posting the event or ::QF_NO_MARGIN. -* @param[in] sender pointer to a sender object (used in QS only) -* -* @returns -* 'true' (success) if the posting succeeded (with the provided margin) -* and 'false' (failure) when the posting fails. -* -* @attention -* For `margin` == ::QF_NO_MARGIN, this function will assert internally -* if the event posting fails. In that case, it is unnecessary to check -* the retrun value from this function. -* -* @note -* This function might be implemented differently in various QP/C++ -* ports. The provided implementation assumes that the ::QEQueue -* class is used for the ::QActive event queue. -* -* @usage -* @include qf_post.cpp -* -* @sa -* QActive_postLIFO() -*/ -bool QActive_post_(QActive * const me, - QEvt const * const e, - uint_fast16_t const margin, - void const * const sender); - -/*! Posts an event `e` directly to the event queue of the active object -* using the Last-In-First-Out (LIFO) policy. -* @private @memberof QActive -* -* @details -* The LIFO policy should be used only for self-posting and with caution, -* because it alters order of events in the queue. -* -* @param[in] e pointer to the event to be posted -* -* @attention -* This function asserts internally if the posting fails. -* -* @note -* This function might be implemented differently in various QP/C++ -* ports. The provided implementation assumes that the ::QEQueue -* class is used for the QActive event queue. -* -* @sa -* QActive_post() -*/ -void QActive_postLIFO_(QActive * const me, - QEvt const * const e); - -/*! Get an event from the event queue of an active object -* @private @memberof QActive -* -* @details -* The behavior of this function depends on the kernel used in the -* QF port. For built-in kernels (Vanilla or QK) the function can be -* called only when the queue is not empty, so it doesn't block. For -* a blocking kernel/OS the function can block and wait for delivery -* of an event. -* -* @returns -* A pointer to the received event. The returned pointer is guaranteed -* to be valid (can't be NULL). -* -* @note -* This function might be implemented differently in various QP/C++ -* ports. The provided implementation assumes that the ::QEQueue -* class is used for the QActive event queue. -*/ -QEvt const * QActive_get_(QActive * const me); - -/* public: */ - -/*! Subscribes for delivery of signal `sig` to the active object -* @public @memberof QActive -* -* @details -* This function is part of the Publish-Subscribe event delivery -* mechanism available in QF. Subscribing to an event means that the -* framework will start posting all published events with a given signal -* `sig` to the event queue of the active object. -* -* @param[in] sig event signal to subscribe -* -* The following example shows how the Table active object subscribes -* to three signals in the initial transition: -* @include qf_subscribe.cpp -* -* @sa -* QActive_publish_(), QActive_unsubscribe(), and -* QActive_unsubscribeAll() -*/ -void QActive_subscribe(QActive const * const me, - enum_t const sig); - -/*! Unsubscribes from the delivery of signal `sig` to the active object -* @public @memberof QActive -* -* @details -* This function is part of the Publish-Subscribe event delivery -* mechanism available in QF. Un-subscribing from an event means that -* the framework will stop posting published events with a given signal -* `sig` to the event queue of the active object. -* -* @param[in] sig event signal to unsubscribe -* -* @note -* Due to the latency of event queues, an active object should NOT -* assume that a given signal `sig` will never be dispatched to the -* state machine of the active object after un-subscribing from that -* signal. The event might be already in the queue, or just about to -* be posted and the un-subscribe operation will not flush such events. -* -* @note -* Un-subscribing from a signal that has never been subscribed in the -* first place is considered an error and QF will raise an assertion. -* -* @sa -* QActive_publish_(), QActive_subscribe(), and -* QActive_unsubscribeAll() -*/ -void QActive_unsubscribe(QActive const * const me, - enum_t const sig); - -/*! Unsubscribes from the delivery of all signals to the active object -* @public @memberof QActive -* -* @details -* This function is part of the Publish-Subscribe event delivery -* mechanism available in QF. Un-subscribing from all events means that -* the framework will stop posting any published events to the event -* queue of the active object. -* -* @note -* Due to the latency of event queues, an active object should NOT -* assume that no events will ever be dispatched to the state machine of -* the active object after un-subscribing from all events. -* The events might be already in the queue, or just about to be posted -* and the un-subscribe operation will not flush such events. Also, the -* alternative event-delivery mechanisms, such as direct event posting or -* time events, can be still delivered to the event queue of the active -* object. -* -* @sa -* QActive_publish_(), QActive_subscribe(), and QActive_unsubscribe() -*/ -void QActive_unsubscribeAll(QActive const * const me); - -/*! Publish event to all subscribers of a given signal `e->sig` -* @static @public @memberof QActive -* -* @details -* This function posts (using the FIFO policy) the event @a e to **all** -* active objects that have subscribed to the signal @a e->sig, which is -* called _multicasting_. The multicasting performed in this function is -* very efficient based on reference-counting inside the published event -* ("zero-copy" event multicasting). This function is designed to be -* callable from any part of the system, including ISRs, device drivers, -* and active objects. -* -* @note -* To avoid any unexpected re-ordering of events posted into AO queues, -* the event multicasting is performed with scheduler **locked**. -* However, the scheduler is locked only up to the priority level of -* the highest-priority subscriber, so any AOs of even higher priority, -* which did not subscribe to this event are *not* affected. -*/ -void QActive_psInit( - QSubscrList * const subscrSto, - enum_t const maxSignal); - -/* private: */ - -/*! Publish event to all subscribers of a given signal `e->sig` -* @static @private @memberof QActive -* -* @details -* This function posts (using the FIFO policy) the event @a e to **all** -* active objects that have subscribed to the signal @a e->sig, which is -* called _multicasting_. The multicasting performed in this function is -* very efficient based on reference-counting inside the published event -* ("zero-copy" event multicasting). This function is designed to be -* callable from any part of the system, including ISRs, device drivers, -* and active objects. -* -* @note -* To avoid any unexpected re-ordering of events posted into AO queues, -* the event multicasting is performed with scheduler **locked**. -* However, the scheduler is locked only up to the priority level of -* the highest-priority subscriber, so any AOs of even higher priority, -* which did not subscribe to this event are *not* affected. -*/ -void QActive_publish_( - QEvt const * const e, - void const * const sender, - uint_fast8_t const qs_id); - -/* protected: */ - -/*! Defer an event to a given separate event queue -* @protected @memberof QActive -* -* @details -* This function is part of the event deferral support. An active object -* uses this function to defer an event `e` to the QF-supported native -* event queue `eq`. QF correctly accounts for another outstanding -* reference to the event and will not recycle the event at the end of -* the RTC step. Later, the active object might recall one event at a -* time from the event queue. -* -* @param[in] eq pointer to a "raw" thread-safe queue to recall -* an event from. -* @param[in] e pointer to the event to be deferred -* -* @returns -* 'true' (success) when the event could be deferred and 'false' -* (failure) if event deferral failed due to overflowing the queue. -* -* An active object can use multiple event queues to defer events of -* different kinds. -* -* @sa -* QActive_recall(), ::QEQueue, QActive_flushDeferred() -*/ -bool QActive_defer(QActive const * const me, - QEQueue * const eq, - QEvt const * const e); - -/*! Recall a deferred event from a given event queue -* @protected @memberof QActive -* -* @details -* This function is part of the event deferral support. An active object -* uses this function to recall a deferred event from a given QF -* event queue. Recalling an event means that it is removed from the -* deferred event queue `eq` and posted (LIFO) to the event queue of -* the active object. -* -* @param[in] eq pointer to a "raw" thread-safe queue to recall -* an event from. -* -* @returns -* 'true' if an event has been recalled and 'false' if not. -* -* @note -* An active object can use multiple event queues to defer events of -* different kinds. -* -* @sa -* QActive_recall(), QActive_postLIFO_(), ::QEQueue -*/ -bool QActive_recall(QActive * const me, - QEQueue * const eq); - -/*! Flush the specified deferred queue 'eq' -* @protected @memberof QActive -* -* @details -* This function is part of the event deferral support. An active object -* can use this function to flush a given QF event queue. The function -* makes sure that the events are not leaked. -* -* @param[in] eq pointer to a "raw" thread-safe queue to flush. -* -* @returns -* the number of events actually flushed from the queue. -* -* @sa -* QActive_defer(), QActive_recall(), ::QEQueue -*/ -uint_fast16_t QActive_flushDeferred(QActive const * const me, - QEQueue * const eq); - -/* public: */ - -/*! Generic setting of additional attributes (useful in QP ports) -* @public @memberof QActive -*/ -void QActive_setAttr(QActive * const me, - uint32_t attr1, - void const * attr2); - -/* private: */ - -/*! Thread routine for executing an active object `act` -* @private @memberof QActive -*/ -void QActive_thread_(QActive * act); - -/* protected: */ - -/*! Register this active object to be managed by the framework -* @protected @memberof QActive -* -* @details -* This function adds a given active object to the active objects -* managed by the QF framework. It should not be called by the -* application directly, only through the function QActive::start(). -* -* @note -* The priority of the active object a should be set before calling -* this function. -* -* @sa QActive_unregister_() -*/ -void QActive_register_(QActive * const me); - -/*! Un-register the active object from the framework -* @protected @memberof QActive -* -* @details -* This function un-registers a given active object from the active objects -* managed by the QF framework. It should not be called by the QP ports. -* -* @param[in] me pointer to the active object to remove from the -* framework. -* -* @note -* The active object that is removed from the framework can no longer -* participate in any event exchange. -* -* @sa QActive_register_() -*/ -void QActive_unregister_(QActive * const me); - -/* private: */ - -#ifdef QF_ISR_API -/*! the "FromISR" variant used in the QP port to "FreeRTOS" -* @private @memberof QActive -*/ -bool QActive_postFromISR_(QActive * const me, - QEvt const * const e, - uint_fast16_t const margin, - void * par, - void const * const sender); -#endif /* def QF_ISR_API */ - -/* public: */ - -#ifdef QF_ISR_API -/*! the "FromISR" variant used in the QP port to "FreeRTOS" -* @private @memberof QActive -*/ -void QActive_publishFromISR_( - QEvt const * e, - void * par, - void const * sender); -#endif /* def QF_ISR_API */ - -/*! Internal array of registered active objects -* @static @private @memberof QActive -*/ -extern QActive * QActive_active_[QF_MAX_ACTIVE + 1U]; - -/*! pointer to the array of all subscriber AOs for a given event signal. -* @static @private @memberof QActive -*/ -extern QSubscrList * QActive_subscrList_; - -/*! The maximum published signal (the size of the subscrList_ array) -* @static @private @memberof QActive -*/ -extern enum_t QActive_maxPubSignal_; - -/*! Internal array of registered active objects -* @static @private @memberof QActive -*/ -extern QActive * QActive_registry_[QF_MAX_ACTIVE + 1U]; -/*$enddecl${QF::QActive} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*$declare${QF::QActiveVtable} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${QF::QActiveVtable} .....................................................*/ -/*! @brief Virtual table for the QActive class */ -typedef struct QActiveVtable { - struct QHsmVtable super; /*!< @protected inherits ::QHsmVtable */ - - /*! @private virtual function to start the AO/thread - * @sa QACTIVE_START() - */ - void (*start)(QActive * const me, QPrioSpec prio, - QEvt const * * const qSto, uint_fast16_t const qLen, - void * const stkSto, uint_fast16_t const stkSize, - void const * const par); - - /*! @private virtual function to asynchronously post (FIFO) - * an event to the AO - * @sa QACTIVE_POST() and QACTIVE_POST_X() - */ - bool (*post)(QActive * const me, QEvt const * const e, - uint_fast16_t const margin, void const * const sender); - - /*! @private virtual function to asynchronously post (LIFO) - * an event to the AO - * @sa QACTIVE_POST_LIFO() - */ - void (*postLIFO)(QActive * const me, QEvt const * const e); - -} QActiveVtable; -/*$enddecl${QF::QActiveVtable} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*$declare${QF::QMActive} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${QF::QMActive} ..........................................................*/ -/*! @brief Active object class (based on QMsm implementation strategy) -* @class QMActive -* @extends QActive -* -* @details -* ::QMActive represents an active object that uses the ::QMsm style state -* machine implementation strategy. This strategy requires the use of the -* QM modeling tool to generate state machine code automatically, but the -* code is faster than in the ::QHsm style implementation strategy and needs -* less run-time support (smaller event-processor). -* -* @note -* ::QMActive is not intended to be instantiated directly, but rather serves -* as the base class for derivation of active objects in the application. -* -* @tr{AQP214} -* -* @usage -* The following example illustrates how to derive an active object from -* ::QMActive. Please note that the ::QActive member @c super is defined as -* the **first** member of the derived struct (see @ref oop). -* @include qf_qmactive.c -*/ -typedef struct { -/* protected: */ - QActive super; -} QMActive; - -/* protected: */ - -/*! Constructor of ::QMActive class. -* @protected @memberof QMActive -* -* @details -* Performs the first step of active object initialization by assigning -* the virtual pointer and calling the superclass constructor. -* -* @param[in,out] me current instance pointer (see @ref oop) -* @param[in] initial pointer to the event to be dispatched to the MSM -* -* @note Must be called only ONCE before QHSM_INIT(). -* -* @sa QHsm_ctor() -*/ -void QMActive_ctor(QMActive * const me, - QStateHandler const initial); -/*$enddecl${QF::QMActive} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*$declare${QF::QMActiveVtable} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${QF::QMActiveVtable} ....................................................*/ -/*! @brief Virtual Table for the ::QMActive class (inherited -* from ::QActiveVtable) -* -* @note -* ::QMActive inherits ::QActive exactly, without adding any new virtual -* functions and therefore, ::QMActiveVtable is typedef'ed as ::QActiveVtable. -*/ -typedef QActiveVtable QMActiveVtable; -/*$enddecl${QF::QMActiveVtable} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*$declare${QF::QTimeEvt} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${QF::QTimeEvt} ..........................................................*/ -/*! @brief Time Event class -* @class QTimeEvt -* @extends QEvt -* -* @details -* Time events are special QF events equipped with the notion of time passage. -* The basic usage model of the time events is as follows. An active object -* allocates one or more ::QTimeEvt objects (provides the storage for them). -* When the active object needs to arrange for a timeout, it arms one of its -* time events to fire either just once (one-shot) or periodically. Each time -* event times out independently from the others, so a QF application can make -* multiple parallel timeout requests (from the same or different active -* objects). When QF detects that the appropriate moment has arrived, it -* inserts the time event directly into the recipient's event queue. The -* recipient then processes the time event just like any other event. -* -* Time events, as any other QF events derive from the ::QEvt base class. -* Typically, you will use a time event as-is, but you can also further -* derive more specialized time events from it by adding some more data -* members and/or specialized functions that operate on the specialized -* time events. -* -* Internally, the armed time events are organized into linked lists--one -* list for every supported ticking rate. These linked lists are scanned in -* every invocation of the QTIMEEVT_TICK_X() macro. Only armed (timing out) -* time events are in the list, so only armed time events consume CPU cycles. -* -* @sa ::QTimeEvt for the description of the data members -* -* @tr{AQP215} -* -* @note -* QF manages the time events in the QTIMEEVT_TICK_X() macro, which must -* be called periodically, from the clock tick ISR or from other periodic -* source. QTIMEEVT_TICK_X() caYou might also use the special ::QTicker -* active object. -* -* @note -* Even though ::QTimeEvt is a subclass of ::QEvt, ::QTimeEvt instances can NOT -* be allocated dynamically from event pools. In other words, it is illegal to -* allocate ::QTimeEvt instances with the Q_NEW() or Q_NEW_X() macros. -*/ -typedef struct QTimeEvt { -/* protected: */ - QEvt super; - -/* private: */ - - /*! link to the next time event in the list - * @private @memberof QTimeEvt - */ - struct QTimeEvt * volatile next; - - /*! The active object that receives the time events - * @private @memberof QTimeEvt - */ - void * volatile act; - - /*! Internal down-counter of the time event. - * @private @memberof QTimeEvt - * - * @details - * The down-counter is decremented by 1 in every QTimeEvt_tick_() call. - * The time event fires (gets posted or published) when the down-counter - * reaches zero. - */ - QTimeEvtCtr volatile ctr; - - /*! Interval for periodic time event (zero for one-shot time event) - * @private @memberof QTimeEvt - * - * @details - * The value of the interval is re-loaded to the internal down-counter - * when the time event expires, so that the time event keeps timing out - * periodically. - */ - QTimeEvtCtr interval; - -/* public: */ -} QTimeEvt; - -/* public: */ - -/*! The extended "constructor" to initialize a Time Event. -* @public @memberof QTimeEvt -* -* @details -* When creating a time event, you must commit it to a specific active object -* `act`, tick rate `tickRate` and event signal `sig`. You cannot change -* these attributes later. -* -* @param[in,out] me current instance pointer (see @ref oop) -* @param[in] act pointer to the active object associated with this -* time event. The time event will post itself to this AO. -* @param[in] sig signal to associate with this time event. -* @param[in] tickRate system clock tick rate to associate with this -* time event in the range [0..15]. -* -* @note You should call the constructor exactly once for every Time Event -* object **before** arming the Time Event. The ideal place for initializing -* the time event(s) associated with a given AO is the AO's constructor. -*/ -void QTimeEvt_ctorX(QTimeEvt * const me, - QActive * const act, - enum_t const sig, - uint_fast8_t const tickRate); - -/*! Arm a time event (one shot or periodic) for direct event posting. -* @public @memberof QTimeEvt -* -* @details -* Arms a time event to fire in a specified number of clock ticks and with -* a specified interval. If the interval is zero, the time event is armed for -* one shot ('one-shot' time event). When the timeout expires, the time event -* gets directly posted (using the FIFO policy) into the event queue of the -* host active object. After posting, a one-shot time event gets automatically -* disarmed while a periodic time event (interval != 0) is automatically -* re-armed. -* -* A time event can be disarmed at any time by calling QTimeEvt_disarm(). -* Also, a time event can be re-armed to fire in a different number of clock -* ticks by calling the QTimeEvt_rearm(). -* -* @param[in,out] me current instance pointer (see @ref oop) -* @param[in] nTicks number of clock ticks (at the associated rate) -* to rearm the time event with. -* @param[in] interval interval (in clock ticks) for periodic time event. -* -* @attention -* Arming an already armed time event is __not__ allowed and is considered -* a programming error. The QP/C framework will assert if it detects an -* attempt to arm an already armed time event. -* -* @usage -* The following example shows how to arm a periodic time event as well as -* one-shot time event from a state machine of an active object: -* @include qf_tevt.c -*/ -void QTimeEvt_armX(QTimeEvt * const me, - QTimeEvtCtr const nTicks, - QTimeEvtCtr const interval); - -/*! Disarm a time event. -* @public @memberof QTimeEvt -* -* @details -* Disarm the time event so it can be safely reused. -* -* @param[in,out] me current instance pointer (see @ref oop) -* -* @returns -* 'true' if the time event was truly disarmed, that is, it was running. -* The return of 'false' means that the time event was not truly disarmed, -* because it was not running. The 'false' return is only possible for one- -* shot time events that have been automatically disarmed upon expiration. -* In this case the 'false' return means that the time event has already -* been posted or published and should be expected in the active object's -* state machine. -* -* @note -* there is no harm in disarming an already disarmed time event -*/ -bool QTimeEvt_disarm(QTimeEvt * const me); - -/*! Rearm a time event. -* @public @memberof QTimeEvt -* -* @details -* Rearms a time event with a new number of clock ticks. This function can -* be used to adjust the current period of a periodic time event or to -* prevent a one-shot time event from expiring (e.g., a watchdog time event). -* Rearming a periodic timer leaves the interval unchanged and is a convenient -* method to adjust the phasing of a periodic time event. -* -* @param[in,out] me current instance pointer (see @ref oop) -* @param[in] nTicks number of clock ticks (at the associated rate) -* to rearm the time event with. -* -* @returns -* 'true' if the time event was running as it was re-armed. The 'false' -* return means that the time event was not truly rearmed because it was -* not running. The 'false' return is only possible for one-shot time events -* that have been automatically disarmed upon expiration. In this case the -* 'false' return means that the time event has already been posted or -* published and should be expected in the active object's state machine. -*/ -bool QTimeEvt_rearm(QTimeEvt * const me, - QTimeEvtCtr const nTicks); - -/*! Check the "was disarmed" status of a time event. -* @public @memberof QTimeEvt -* -* @details -* Useful for checking whether a one-shot time event was disarmed in the -* QTimeEvt_disarm() operation. -* -* @param[in,out] me current instance pointer (see @ref oop) -* -* @returns -* 'true' if the time event was truly disarmed in the last QTimeEvt_disarm() -* operation. The 'false' return means that the time event was not truly -* disarmed, because it was not running at that time. The 'false' return is -* only possible for one-shot time events that have been automatically disarmed -* upon expiration. In this case the 'false' return means that the time event -* has already been posted or published and should be expected in the active -* object's event queue. -* -* @note -* This function has a **side effect** of setting the "was disarmed" status, -* which means that the second and subsequent times this function is called -* the function will return 'true'. -*/ -bool QTimeEvt_wasDisarmed(QTimeEvt * const me); - -/*! Get the current value of the down-counter of a time event. -* @public @memberof QTimeEvt -* -* @details -* Useful for checking how many clock ticks (at the tick rate associated -* with the time event) remain until the time event expires. -* -* @param[in,out] me current instance pointer (see @ref oop) -* -* @returns -* For an armed time event, the function returns the current value of the -* down-counter of the given time event. If the time event is not armed, -* the function returns 0. -* -* @note -* The function is thread-safe. -*/ -QTimeEvtCtr QTimeEvt_currCtr(QTimeEvt const * const me); - -/*! Processes all armed time events at every clock tick. -* @static @private @memberof QTimeEvt -* -* @details -* This internal helper function processes all armed ::QTimeEvt objects -* associated wit the tick rate `tickRate`. -* -* This function must be called periodically from a time-tick ISR or from -* a task so that QF can manage the timeout events assigned to the given -* system clock tick rate. -* -* @param[in] tickRate clock tick rate serviced in this call [1..15]. -* @param[in] sender pointer to a sender object (only for QS tracing) -* -* @note -* this function should be called only via the macro QTIMEEVT_TICK_X() -* -* @note -* the calls to QTimeEvt_tick_() with different `tickRate` parameter can -* preempt each other. For example, higher clock tick rates might be -* serviced from interrupts while others from tasks (active objects). -* -* @sa ::QTimeEvt. -*/ -void QTimeEvt_tick_( - uint_fast8_t const tickRate, - void const * const sender); - -#ifdef Q_UTEST -/*! Processes one clock tick for QUTest */ -void QTimeEvt_tick1_( - uint_fast8_t const tickRate, - void const * const sender); -#endif /* def Q_UTEST */ - -/*! Returns 'true' if there are no armed time events at a given tick rate. -* @static @public @memberof QTimeEvt -* -* @details -* Find out if any time events are armed at the given clock tick rate. -* -* @param[in] tickRate system clock tick rate to find out about. -* -* @returns -* 'true' if no time events are armed at the given tick rate and -* 'false' otherwise. -* -* @note -* This function should be called in critical section. -*/ -bool QTimeEvt_noActive(uint_fast8_t const tickRate); - -/*! heads of linked lists of time events, one for every clock tick rate */ -extern QTimeEvt QTimeEvt_timeEvtHead_[QF_MAX_TICK_RATE]; -/*$enddecl${QF::QTimeEvt} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*$declare${QF::QTicker} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${QF::QTicker} ...........................................................*/ -/*! @brief "Ticker" Active Object class -* @class QTicker -* @extends QActive -* -* @details -* QTicker is an efficient active object specialized to process QF system -* clock tick at a specified tick rate [0..#QF_MAX_TICK_RATE]. -* Placing system clock tick processing in an active object allows you -* to remove the non-deterministic QTIMEEVT_TICK_X() processing from the -* interrupt level and move it into the thread-level, where you can prioritize -* it as low as you wish. -* -* @usage -* The following example illustrates use of QTicker active objects: -* @include qf_ticker.c -*/ -typedef struct { -/* protected: */ - QActive super; -} QTicker; - -/* public: */ - -/*! Constructor of the QTicker Active Object class -* @public @memberof QTicker -*/ -void QTicker_ctor(QTicker * const me, - uint_fast8_t const tickRate); - -/* private: */ - -/*! initialization (override) -* @private @memberof QTicker -*/ -void QTicker_init_( - QHsm * const me, - void const * const par, - uint_fast8_t const qs_id); - -/*! dispatching (override) -* @private @memberof QTicker -*/ -void QTicker_dispatch_( - QHsm * const me, - QEvt const * const e, - uint_fast8_t const qs_id); - -/* public: */ - -/*! post (override) -* @private @memberof QTicker -*/ -bool QTicker_post_( - QActive * const me, - QEvt const * const e, - uint_fast16_t const margin, - void const * const sender); - -/*! post-LIFO (override) -* @private @memberof QTicker -*/ -void QTicker_postLIFO_( - QActive * const me, - QEvt const * const e); -/*$enddecl${QF::QTicker} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ - -/*$declare${QF::QF-base} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${QF::QF-base::Attr} .....................................................*/ -/*! @brief QF active object framework -* @class QF -*/ -typedef struct QF_Attr { - uint8_t dummy; /*< dummy attribute */ -} QF; - -/*${QF::QF-base::intLock_} .................................................*/ -/*! Interrupt lock up-down counter (used in some QF ports ) -* @static @private @memberof QF -*/ -extern uint_fast8_t volatile QF_intLock_; - -/*${QF::QF-base::intNest_} .................................................*/ -/*! Interrupt nesting up-down counter (used in some QF ports ) -* @static @private @memberof QF -*/ -extern uint_fast8_t volatile QF_intNest_; - -/*${QF::QF-base::init} .....................................................*/ -/*! QF initialization -* @static @public @memberof QF -* -* @details -* Initializes QF and must be called exactly once before any other QF -* function. Typcially, QF_init() is called from main() even before -* initializing the Board Support Package (BSP). -* -* @note -* QF_init() clears the internal QF variables, so that the framework -* can start correctly even if the startup code fails to clear the -* uninitialized data (as is required by the C Standard). -*/ -void QF_init(void); - -/*${QF::QF-base::stop} .....................................................*/ -/*! Function invoked by the application layer to stop the QF -* application and return control to the OS/Kernel. -* @static @public @memberof QF -* -* @details -* This function stops the QF application. After calling this function, -* QF attempts to gracefully stop the application. This graceful shutdown -* might take some time to complete. The typical use of this function is -* for terminating the QF application to return back to the operating -* system or for handling fatal errors that require shutting down -* (and possibly re-setting) the system. -* -* @attention -* After calling QF_stop() the application must terminate and cannot -* continue. In particular, QF_stop() is **not** intended to be followed -* by a call to QF_init() to "resurrect" the application. -* -* @sa QF_onCleanup() -*/ -void QF_stop(void); - -/*${QF::QF-base::run} ......................................................*/ -/*! Transfers control to QF to run the application. -* @static @public @memberof QF -* -* @details -* QF_run() is typically called from your startup code after you initialize -* the QF and start at least one active object with QACTIVE_START(). -* -* @returns -* In QK, the QF_run() does not return. -*/ -int_t QF_run(void); - -/*${QF::QF-base::psInit} ...................................................*/ -/*! initialization of publish-subscribe -* -* @deprecated -* @sa QActive_psInit() -*/ -static inline void QF_psInit( - QSubscrList * const subscrSto, - enum_t const maxSignal) -{ - QActive_psInit(subscrSto, maxSignal); -} - -/*${QF::QF-base::getQueueMin} ..............................................*/ -/*! This function returns the minimum of free entries of -* the given event queue. -* @static @public @memberof QF -* -* @details -* Queries the minimum of free ever present in the given event queue of -* an active object with priority `prio`, since the active object -* was started. -* -* @note -* This function is available only when the native QF event queue -* implementation is used. Requesting the queue minimum of an unused -* priority level raises an assertion in the QF. (A priority level becomes -* used in QF after the call to the QActive_register_() function.) -* -* @param[in] prio Priority of the active object, whose queue is queried -* -* @returns -* the minimum of free ever present in the given event queue of an active -* object with priority `prio`, since the active object was started. -*/ -uint_fast16_t QF_getQueueMin(uint_fast8_t const prio); - -/*${QF::QF-base::onStartup} ................................................*/ -/*! Startup QF callback. -* @static @public @memberof QF -* -* @details -* The purpose of the QF_onStartup() callback is to configure and enable -* hardware interrupts. The callback is invoked from QF_run(), right before -* starting the underlying real-time kernel. By that time, the application -* is considered ready to receive and service interrupts. -* -* This function is application-specific and is not implemented in QF, but -* rather in the Board Support Package (BSP) for the given application. -*/ -void QF_onStartup(void); - -/*${QF::QF-base::onCleanup} ................................................*/ -/*! Cleanup QF callback. -* @static @public @memberof QF -* -* @details -* QF_onCleanup() is called in some QF ports before QF returns to the -* underlying real-time kernel or operating system. -* -* This function is strongly platform-specific and is not implemented in -* the QF, but either in the QF port or in the Board Support Package (BSP) -* for the given application. Some QF ports might not require implementing -* QF_onCleanup() at all, because many embedded applications don't have -* anything to exit to. -* -* @sa QF_stop() -*/ -void QF_onCleanup(void); -/*$enddecl${QF::QF-base} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*$declare${QF::QF-dyn} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${QF::QF-dyn::poolInit} ..................................................*/ -/*! Event pool initialization for dynamic allocation of events. -* @static @public @memberof QF -* -* @details -* This function initializes one event pool at a time and must be called -* exactly once for each event pool before the pool can be used. -* -* @param[in] poolSto pointer to the storage for the event pool -* @param[in] poolSize size of the storage for the pool in bytes -* @param[in] evtSize the block-size of the pool in bytes, which determines -* the maximum size of events that can be allocated from the pool. -* -* @attention -* You might initialize many event pools by making many consecutive calls -* to the QF_poolInit() function. However, for the simplicity of the internal -* implementation, you must initialize event pools in the **ascending order** -* of the event size. -* -* Many RTOSes provide fixed block-size heaps, a.k.a. memory pools that can -* be adapted for QF event pools. In case such support is missing, QF provides -* a native QF event pool implementation. The macro #QF_EPOOL_TYPE_ determines -* the type of event pool used by a particular QF port. See structure ::QMPool -* for more information. -* -* @note The actual number of events available in the pool might be actually -* less than (`poolSize` / `evtSize`) due to the internal alignment -* of the blocks that the pool might perform. You can always check the -* capacity of the pool by calling QF_getPoolMin(). -* -* @note The dynamic allocation of events is optional, meaning that you -* might choose not to use dynamic events. In that case calling QF_poolInit() -* and using up memory for the memory blocks is unnecessary. -* -* @sa QF initialization example for QF_init() -*/ -void QF_poolInit( - void * const poolSto, - uint_fast32_t const poolSize, - uint_fast16_t const evtSize); - -/*${QF::QF-dyn::poolGetMaxBlockSize} .......................................*/ -/*! Obtain the block size of any registered event pools. -* @static @public @memberof QF -* -* @details -* Obtain the block size of any registered event pools -*/ -uint_fast16_t QF_poolGetMaxBlockSize(void); - -/*${QF::QF-dyn::getPoolMin} ................................................*/ -/*! Obtain the minimum of free entries of the given event pool. -* @static @public @memberof QF -* -* @details -* This function obtains the minimum number of free blocks in the given -* event pool since this pool has been initialized by a call to QF_poolInit(). -* -* @param[in] poolId event pool ID in the range 1..QF_maxPool_, where -* QF_maxPool_ is the number of event pools initialized -* with the function QF_poolInit(). -* -* @returns -* the minimum number of unused blocks in the given event pool. -*/ -uint_fast16_t QF_getPoolMin(uint_fast8_t const poolId); - -/*${QF::QF-dyn::newX_} .....................................................*/ -/*! Internal QF implementation of creating new dynamic event. -* @static @private @memberof QF -* -* @details -* Allocates an event dynamically from one of the QF event pools. -* -* @param[in] evtSize the size (in bytes) of the event to allocate -* @param[in] margin the number of un-allocated events still available -* in a given event pool after the allocation completes. -* The special value ::QF_NO_MARGIN means that this function -* will assert if allocation fails. -* @param[in] sig the signal to be assigned to the allocated event -* -* @returns -* pointer to the newly allocated event. This pointer can be NULL only if -* margin != #QF_NO_MARGIN and the event cannot be allocated with the -* specified margin still available in the given pool. -* -* @note -* The internal QF function QF_newX_() raises an assertion when the -* `margin` parameter is #QF_NO_MARGIN and allocation of the event turns -* out to be impossible due to event pool depletion, or incorrect (too big) -* size of the requested event. -* -* @note -* The application code should not call this function directly. -* The only allowed use is thorough the macros Q_NEW() or Q_NEW_X(). -*/ -QEvt * QF_newX_( - uint_fast16_t const evtSize, - uint_fast16_t const margin, - enum_t const sig); - -/*${QF::QF-dyn::gc} ........................................................*/ -/*! Recycle a dynamic event -* @static @private @memberof QF -* -* @details -* This function implements a simple garbage collector for the dynamic events. -* Only dynamic events are candidates for recycling. (A dynamic event is one -* that is allocated from an event pool, which is determined as non-zero -* e->poolId_ attribute.) Next, the function decrements the reference counter -* of the event (e->refCtr_), and recycles the event only if the counter drops -* to zero (meaning that no more references are outstanding for this event). -* The dynamic event is recycled by returning it to the pool from which -* it was originally allocated. -* -* @param[in] e pointer to the event to recycle -* -* @note -* QF invokes the garbage collector at all appropriate contexts, when -* an event can become garbage (automatic garbage collection), so the -* application code should have no need to call QF_gc() directly. The QF_gc() -* function is exposed only for special cases when your application sends -* dynamic events to the "raw" thread-safe queues (see ::QEQueue). Such -* queues are processed outside of QF and the automatic garbage collection -* is **NOT** performed for these events. In this case you need to call -* QF_gc() explicitly. -*/ -void QF_gc(QEvt const * const e); - -/*${QF::QF-dyn::newRef_} ...................................................*/ -/*! Internal QF implementation of creating new event reference. -* @static @private @memberof QF -* -* @details -* Creates and returns a new reference to the current event e -* -* @param[in] e pointer to the current event -* @param[in] evtRef the event reference -* -* @returns -* the newly created reference to the event `e` -* -* @note -* The application code should not call this function directly. -* The only allowed use is thorough the macro Q_NEW_REF(). -*/ -QEvt const * QF_newRef_( - QEvt const * const e, - void const * const evtRef); - -/*${QF::QF-dyn::deleteRef_} ................................................*/ -/*! Internal QF implementation of deleting event reference. -* @static @private @memberof QF -* -* @details -* Deletes an existing reference to the event e -* -* @param[in] evtRef the event reference -* -* @note -* The application code should not call this function directly. -* The only allowed use is thorough the macro Q_DELETE_REF(). -*/ -void QF_deleteRef_(void const * const evtRef); -/*$enddecl${QF::QF-dyn} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*$declare${QF::QF-extern-C} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${QF::QF-extern-C::onContextSw} ..........................................*/ -#ifdef QF_ON_CONTEXT_SW -/*! QF context switch callback used in built-in kernels (QV, QK, QXK) -* @static @public @memberof QF -* -* @details -* This callback function provides a mechanism to perform additional -* custom operations when one of the built-in kernels switches context -* from one thread to another. -* -* @param[in] prev pointer to the previous thread (active object) -* (prev==0 means that `prev` was the idle loop) -* @param[in] next pointer to the next thread (active object) -* (next==0) means that `next` is the idle loop) -* @attention -* QF_onContextSw() is invoked with interrupts **disabled** and must also -* return with interrupts **disabled**. -* -* @note -* This callback is enabled by defining the macro #QF_ON_CONTEXT_SW. -* -* @include qf_oncontextsw.c -*/ -void QF_onContextSw( - QActive * prev, - QActive * next); -#endif /* def QF_ON_CONTEXT_SW */ -/*$enddecl${QF::QF-extern-C} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ - -/*==========================================================================*/ -/*$declare${QF-macros} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${QF-macros::QF_NO_MARGIN} ...............................................*/ -/*! Special value of margin that causes asserting failure in case -* event allocation or event posting fails -*/ -#define QF_NO_MARGIN ((uint_fast16_t)0xFFFFU) - -/*${QF-macros::Q_PRIO} .....................................................*/ -/*! Create a ::QPrioSpec object to specify priorty of an AO or a thread */ -#define Q_PRIO(prio_, pthre_) ((QPrioSpec)((prio_) | ((pthre_) << 8U))) - -/*${QF-macros::Q_NEW} ......................................................*/ -#ifndef Q_EVT_CTOR -/*! Allocate a dynamic event (case when ::QEvt is a POD) -* -* @details -* The macro calls the internal QF function QF::newX_() with -* margin == ::QF_NO_MARGIN, which causes an assertion when the event -* cannot be successfully allocated. -* -* @param[in] evtT_ event type (class name) of the event to allocate -* @param[in] sig_ signal to assign to the newly allocated event -* -* @returns a valid event pointer cast to the type `evtT_`. -* -* @note -* If #Q_EVT_CTOR is defined, the Q_NEW() macro becomes variadic and -* takes all the arguments needed by the constructor of the event -* class being allocated. The constructor is then called by means -* of the placement-new operator. -* -* @usage -* The following example illustrates dynamic allocation of an event: -* @include qf_post.c -*/ -#define Q_NEW(evtT_, sig_) ((evtT_ *)QF_newX_((uint_fast16_t)sizeof(evtT_), \ - QF_NO_MARGIN, (enum_t)(sig_))) -#endif /* ndef Q_EVT_CTOR */ - -/*${QF-macros::Q_NEW} ......................................................*/ -#ifdef Q_EVT_CTOR -/*! Asserting allocate a dynamic event -* (case when ::QEvt is not a POD) -*/ -#define Q_NEW(evtT_, sig_, ...) \ - (evtT_##_ctor((evtT_ *)QF_newX_((uint_fast16_t)sizeof(evtT_), \ - QF_NO_MARGIN, (sig_)), (enum_t)(sig_), ##__VA_ARGS__)) -#endif /* def Q_EVT_CTOR */ - -/*${QF-macros::Q_NEW_X} ....................................................*/ -#ifndef Q_EVT_CTOR -/*! Non-asserting allocate a dynamic event (case when ::QEvt is a POD). -* -* @details -* This macro allocates a new event and sets the pointer `e_`, while -* leaving at least `margin_` of events still available in the pool -* -* @param[out] e_ pointer to the newly allocated event -* @param[in] evtT_ event type (class name) of the event to allocate -* @param[in] margin_ number of events that must remain available -* in the given pool after this allocation. The -* special value ::QF_NO_MARGIN causes asserting -* failure in case event allocation fails. -* @param[in] sig_ signal to assign to the newly allocated event -* -* @returns an event pointer cast to the type `evtT_` or NULL if the -* event cannot be allocated with the specified `margin`. -* -* @note -* If #Q_EVT_CTOR is defined, the Q_NEW_X() macro becomes variadic and -* takes all the arguments needed by the constructor of the event -* class being allocated. The constructor is then called by means -* of the placement-new operator. -* -* @usage -* The following example illustrates dynamic allocation of an event: -* @include qf_postx.c -*/ -#define Q_NEW_X(e_, evtT_, margin_, sig_) ((e_) = \ - (evtT_ *)QF_newX_((uint_fast16_t)sizeof(evtT_), \ - (margin_), (enum_t)(sig_))) -#endif /* ndef Q_EVT_CTOR */ - -/*${QF-macros::Q_NEW_X} ....................................................*/ -#ifdef Q_EVT_CTOR -/*! Non-asserting allocate a dynamic event -* (case when ::QEvt is not a POD) -*/ -#define Q_NEW_X(e_, evtT_, margin_, sig_, ...) do { \ - (e_) = (evtT_ *)QF_newX_((uint_fast16_t)sizeof(evtT_), \ - (margin_), (enum_t)(sig_));\ - if ((e_) != (evtT_ *)0) { \ - evtT_##_ctor((e_), (enum_t)(sig_), ##__VA_ARGS__); \ - } \ - } while (false) -#endif /* def Q_EVT_CTOR */ - -/*${QF-macros::Q_NEW_REF} ..................................................*/ -/*! Create a new reference of the current event `e` -* -* @details -* The current event processed by an active object is available only for -* the duration of the run-to-completion (RTC) step. After that step, the -* current event is no longer available and the framework might recycle -* (garbage-collect) the event. The macro Q_NEW_REF() explicitly creates -* a new reference to the current event that can be stored and used beyond -* the current RTC step, until the reference is explicitly recycled by -* means of the macro Q_DELETE_REF(). -* -* @param[in,out] evtRef_ event reference to create -* @param[in] evtT_ event type (class name) of the event reference -* -* @usage -* The example **defer** in the directory `examples/win32/defer` illustrates -* the use of Q_NEW_REF() -* -* @sa Q_DELETE_REF() -*/ -#define Q_NEW_REF(evtRef_, evtT_) \ - ((evtRef_) = (evtT_ const *)QF_newRef_(e, (evtRef_))) - -/*${QF-macros::Q_DELETE_REF} ...............................................*/ -/*! Delete the event reference -* -* @details -* Every event reference created with the macro Q_NEW_REF() needs to be -* eventually deleted by means of the macro Q_DELETE_REF() to avoid leaking -* the event. -* -* @param[in,out] evtRef_ event reference to delete -* -* @usage -* The example **defer** in the directory `examples/win32/defer` illustrates -* the use of Q_DELETE_REF() -* -* @sa Q_NEW_REF() -*/ -#define Q_DELETE_REF(evtRef_) do { \ - QF_deleteRef_((evtRef_)); \ - (evtRef_) = (void *)0; \ -} while (false) - -/*${QF-macros::QACTIVE_START} ..............................................*/ -/*! Virtual call to start an active object. -* -* @details -* Starts execution of the AO and registers the AO with the framework. -* -* @param[in,out] me_ current instance pointer (see @ref oop) -* @param[in] prioSpec_ priority specification for the Active Object -* @param[in] qSto_ pointer to the storage for the ring buffer of the -* event queue (used only with the built-in ::QEQueue) -* @param[in] qLen_ length of the event queue (in events) -* @param[in] stkSto_ pointer to the stack storage (used only when -* per-AO stack is needed) -* @param[in] stkSize_ stack size (in bytes) -* @param[in] par_ pointer to the additional port-specific parameter(s) -* (might be NULL). -* @usage -* @include qf_start.c -*/ -#define QACTIVE_START(me_, prioSpec_, qSto_, qLen_, stkSto_, stkSize_, par_) do { \ - Q_ASSERT((Q_HSM_UPCAST(me_))->vptr); \ - (*((QActiveVtable const *)((Q_HSM_UPCAST(me_))->vptr))->start)( \ - (QActive *)(me_), (prioSpec_), \ - (qSto_), (qLen_), (stkSto_), (stkSize_), (par_)); \ -} while (false) - -/*${QF-macros::QACTIVE_POST} ...............................................*/ -#ifdef Q_SPY -/*! Invoke the direct event posting facility QActive_post_() -* -* @details -* This macro asserts if the queue overflows and cannot accept the event. -* -* @param[in,out] me_ current instance pointer (see @ref oop) -* @param[in] e_ pointer to the event to post -* @param[in] sender_ pointer to the sender object. -* -* @note -* The `sendedr_` parameter is actually only used when QS tracing -* is enabled (macro #Q_SPY is defined). When QS software tracing is -* disenabled, the QACTIVE_POST() macro does not pass the `sender_` -* parameter, so the overhead of passing this extra parameter is entirely -* avoided. -* -* @note the pointer to the sender object is not necessarily a pointer -* to an active object. In fact, if QACTIVE_POST() is called from an -* interrupt or other context, you can create a unique object just to -* unambiguously identify the sender of the event. -* -* @sa QActive_post_() -*/ -#define QACTIVE_POST(me_, e_, sender_) \ - ((void)(*((QActiveVtable const *)((Q_HSM_UPCAST(me_))->vptr))->post)(\ - (me_), (e_), QF_NO_MARGIN, (sender_))) -#endif /* def Q_SPY */ - -/*${QF-macros::QACTIVE_POST} ...............................................*/ -#ifndef Q_SPY -#define QACTIVE_POST(me_, e_, dummy) \ - ((void)(*((QActiveVtable const *)((Q_HSM_UPCAST(me_))->vptr))->post)(\ - (me_), (e_), QF_NO_MARGIN, (void *)0)) -#endif /* ndef Q_SPY */ - -/*${QF-macros::QACTIVE_POST_X} .............................................*/ -#ifdef Q_SPY -/*! Invoke the direct event posting facility QActive_post_() -* without delivery guarantee -* -* @details -* This macro does not assert if the queue overflows and cannot accept -* the event with the specified margin of free slots remaining. -* -* @param[in,out] me_ current instance pointer (see @ref oop) -* @param[in] e_ pointer to the event to post -* @param[in] margin_ the minimum free slots in the queue, which -* must still be available after posting the event. -* The special value ::QF_NO_MARGIN causes -* asserting failure in case event posting fails. -* @param[in] sender_ pointer to the sender object. -* -* @returns -* 'true' if the posting succeeded, and 'false' if the posting -* failed due to insufficient margin of free entries available in -* the queue. -* -* @note -* The `sender_` parameter is actually only used when QS tracing -* is enabled (macro #Q_SPY is defined). When QS software tracing is -* disabled, the POST_X() macro does not pass the `sender_` parameter, -* so the overhead of passing this extra parameter is entirely avoided. -* -* @note -* The pointer to the sender object is not necessarily a pointer -* to an active object. In fact, if POST_X() is called from an -* interrupt or other context, you can create a unique object just to -* unambiguously identify the sender of the event. -* -* @usage -* @include qf_postx.c -*/ -#define QACTIVE_POST_X(me_, e_, margin_, sender_) \ - ((*((QActiveVtable const *)((Q_HSM_UPCAST(me_))->vptr))->post)((me_),\ - (e_), (margin_), (sender_))) -#endif /* def Q_SPY */ - -/*${QF-macros::QACTIVE_POST_X} .............................................*/ -#ifndef Q_SPY -#define QACTIVE_POST_X(me_, e_, margin_, dummy) \ - ((*((QActiveVtable const *)((Q_HSM_UPCAST(me_))->vptr))->post)((me_),\ - (e_), (margin_), (void *)0)) -#endif /* ndef Q_SPY */ - -/*${QF-macros::QACTIVE_POST_LIFO} ..........................................*/ -/*! Virtual call to post an event to an active object using the -* Last-In-First-Out (LIFO) policy. -* -* @param[in,out] me_ current instance pointer (see @ref oop) -* @param[in] e_ pointer to the event to post -*/ -#define QACTIVE_POST_LIFO(me_, e_) \ - ((*((QActiveVtable const *)((Q_HSM_UPCAST(me_))->vptr))->postLIFO)( \ - (me_), (e_))) - -/*${QF-macros::QACTIVE_PUBLISH} ............................................*/ -#ifdef Q_SPY -/*! Publish an event to all subscriber Active Objects. -* -* @details -* If #Q_SPY is defined, this macro calls QActive_publish_() with -* the `sender_` parameter to identify the publisher of the event. -* Otherwise, `sender_` is not used. -* -* @param[in] e_ pointer to the posted event -* @param[in] sender_ pointer to the sender object (actually used -* only when #Q_SPY is defined) -* -* @note -* The pointer to the `sender_` object is not necessarily a pointer -* to an active object. In fact, if QACTIVE_PUBLISH() is called from an -* interrupt or other context, you can create a unique object just to -* unambiguously identify the sender of the event. -* -* @sa QActive_publish_() -*/ -#define QACTIVE_PUBLISH(e_, sender_) \ - (QActive_publish_((e_), (void const *)(sender_), (sender_)->prio)) -#endif /* def Q_SPY */ - -/*${QF-macros::QACTIVE_PUBLISH} ............................................*/ -#ifndef Q_SPY -#define QACTIVE_PUBLISH(e_, dummy) (QActive_publish_((e_), (void *)0, 0U)) -#endif /* ndef Q_SPY */ - -/*${QF-macros::QTIMEEVT_TICK_X} ............................................*/ -#ifdef Q_SPY -/*! Invoke the system clock tick processing QTimeEvt_tick_() -* -* @details -* This macro is the recommended way of invoking clock tick processing, -* because it provides the vital information for software tracing and -* avoids any overhead when the tracing is disabled. -* -* @param[in] tickRate_ clock tick rate to be serviced through this call -* @param[in] sender_ pointer to the sender object. This parameter -* is actually only used when QS software tracing is enabled -* (macro #Q_SPY is defined) -* @note -* When QS software tracing is disabled, the macro calls QTimeEvt_tick_() -* without the `sender` parameter, so the overhead of passing this -* extra parameter is entirely avoided. -* -* @note -* The pointer to the sender object is not necessarily a pointer -* to an active object. In fact, when QTIMEEVT_TICK_X() is called from -* an interrupt, you would create a unique object just to unambiguously -* identify the ISR as the sender of the time events. -* -* @sa QTimeEvt_tick_() -*/ -#define QTIMEEVT_TICK_X(tickRate_, sender_) \ - (QTimeEvt_tick_((tickRate_), (sender_))) -#endif /* def Q_SPY */ - -/*${QF-macros::QTIMEEVT_TICK_X} ............................................*/ -#ifndef Q_SPY -#define QTIMEEVT_TICK_X(tickRate_, dummy) \ - (QTimeEvt_tick_((tickRate_), (void *)0)) -#endif /* ndef Q_SPY */ - -/*${QF-macros::QTIMEEVT_TICK} ..............................................*/ -/*! Invoke the system clock tick processing -* for tick rate 0 -*/ -#define QTIMEEVT_TICK(sender_) QTIMEEVT_TICK_X(0U, (sender_)) - -/*${QF-macros::QF_CRIT_EXIT_NOP} ...........................................*/ -#ifndef QF_CRIT_EXIT_NOP -/*! No-operation for exiting a critical section -* -* @details -* In some QF ports the critical section exit takes effect only on the -* next machine instruction. If this next instruction is another entry -* to a critical section, the critical section won't be really exited, -* but rather the two adjecent critical sections would be merged. -* The QF_CRIT_EXIT_NOP() macro contains minimal code required to -* prevent such merging of critical sections in such merging of -* critical sections in QF ports, in which it can occur. -*/ -#define QF_CRIT_EXIT_NOP() ((void)0) -#endif /* ndef QF_CRIT_EXIT_NOP */ - -/*${QF-macros::QF_TICK_X} ..................................................*/ -/*! Invoke the system clock tick processing -* -* @deprecated -* superseded by QTIMEEVT_TICK_X() -*/ -#define QF_TICK_X(tickRate_, sender_) QTIMEEVT_TICK_X((tickRate_), (sender_)) - -/*${QF-macros::QF_TICK} ....................................................*/ -/*! Invoke the system clock tick processing for tick rate 0 -* -* @deprecated -* superseded by QTIMEEVT_TICK() -*/ -#define QF_TICK(sender_) QTIMEEVT_TICK(sender_) - -/*${QF-macros::QF_PUBLISH} .................................................*/ -/*! Publish an event to all subscriber Active Objects. -* -* @deprecated -* superseded by QACTIVE_PUBLISH() -*/ -#define QF_PUBLISH(e_, sender_) QACTIVE_PUBLISH((e_), (sender_)) -/*$enddecl${QF-macros} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ - -#endif /* QP_INC_QF_H_ */ diff --git a/include/qf_pkg.h b/include/qf_pkg.h deleted file mode 100644 index 53143839..00000000 --- a/include/qf_pkg.h +++ /dev/null @@ -1,193 +0,0 @@ -/*$file${include::qf_pkg.h} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* -* Model: qpc.qm -* File: ${include::qf_pkg.h} -* -* This code has been generated by QM 5.2.4 . -* DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. -* -* This code is covered by the following QP license: -* License # : LicenseRef-QL-dual -* Issued to : Any user of the QP/C real-time embedded framework -* Framework(s) : qpc -* Support ends : 2023-12-31 -* License scope: -* -* Copyright (C) 2005 Quantum Leaps, LLC . -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -*/ -/*$endhead${include::qf_pkg.h} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*! @file -* @brief Internal (package scope) QF/C interface. -*/ -#ifndef QP_INC_QF_PKG_H_ -#define QP_INC_QF_PKG_H_ - -/*==========================================================================*/ -/*$declare${QF::QF-pkg} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${QF::QF-pkg::ePool_[QF_MAX_EPOOL]} ......................................*/ -#if (QF_MAX_EPOOL > 0U) -/*! array of event pools managed by QF */ -extern QF_EPOOL_TYPE_ QF_ePool_[QF_MAX_EPOOL]; -#endif /* (QF_MAX_EPOOL > 0U) */ - -/*${QF::QF-pkg::maxPool_} ..................................................*/ -/*! number of initialized event pools */ -extern uint_fast8_t QF_maxPool_; - -/*${QF::QF-pkg::readySet_} .................................................*/ -/*! "Ready-set" of all threads used in the built-in kernels -* @static @private @memberof QF -*/ -extern QPSet QF_readySet_; - -/*${QF::QF-pkg::bzero} .....................................................*/ -/*! Clear a specified region of memory to zero. -* @static @public @memberof QF -* -* @details -* Clears a memory buffer by writing zeros byte-by-byte. -* -* @param[in] start pointer to the beginning of a memory buffer. -* @param[in] len length of the memory buffer to clear (in bytes) -* -* @note The main application of this function is clearing the internal QF -* variables upon startup. This is done to avoid problems with non-standard -* startup code provided with some compilers and toolsets (e.g., TI DSPs or -* Microchip MPLAB), which does not zero the uninitialized variables, as -* required by the ANSI C standard. -*/ -void QF_bzero( - void * const start, - uint_fast16_t const len); -/*$enddecl${QF::QF-pkg} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ - -/*==========================================================================*/ -/* QF-specific critical section */ -#ifndef QF_CRIT_STAT_TYPE - /*! This is an internal macro for defining the critical section - * status type. */ - /** - * @details - * The purpose of this macro is to enable writing the same code for the - * case when critical section status type is defined and when it is not. - * If the macro #QF_CRIT_STAT_TYPE is defined, this internal macro - * provides the definition of the critical section status variable. - * Otherwise this macro is empty. - * @sa #QF_CRIT_STAT_TYPE - */ - #define QF_CRIT_STAT_ - - /*! This is an internal macro for entering a critical section. */ - /** - * @details - * The purpose of this macro is to enable writing the same code for the - * case when critical section status type is defined and when it is not. - * If the macro #QF_CRIT_STAT_TYPE is defined, this internal macro - * invokes QF_CRIT_ENTRY() passing the key variable as the parameter. - * Otherwise QF_CRIT_ENTRY() is invoked with a dummy parameter. - * @sa QF_CRIT_ENTRY() - */ - #define QF_CRIT_E_() QF_CRIT_ENTRY(dummy) - - /*! This is an internal macro for exiting a critical section. */ - /** - * @details - * The purpose of this macro is to enable writing the same code for the - * case when critical section status type is defined and when it is not. - * If the macro #QF_CRIT_STAT_TYPE is defined, this internal macro - * invokes #QF_CRIT_EXIT passing the key variable as the parameter. - * Otherwise #QF_CRIT_EXIT is invoked with a dummy parameter. - * @sa #QF_CRIT_EXIT - */ - #define QF_CRIT_X_() QF_CRIT_EXIT(dummy) - -#elif (!defined QF_CRIT_STAT_) - #define QF_CRIT_STAT_ QF_CRIT_STAT_TYPE critStat_; - #define QF_CRIT_E_() QF_CRIT_ENTRY(critStat_) - #define QF_CRIT_X_() QF_CRIT_EXIT(critStat_) -#endif - -/*==========================================================================*/ -/* Assertions inside the critical section */ -#ifdef Q_NASSERT /* Q_NASSERT defined--assertion checking disabled */ - - #define Q_ASSERT_CRIT_(id_, test_) ((void)0) - #define Q_REQUIRE_CRIT_(id_, test_) ((void)0) - #define Q_ERROR_CRIT_(id_) ((void)0) - -#else /* Q_NASSERT not defined--assertion checking enabled */ - - #define Q_ASSERT_CRIT_(id_, test_) do { \ - if ((test_)) {} else { \ - QF_CRIT_X_(); \ - Q_onAssert(&Q_this_module_[0], (int_t)(id_)); \ - } \ - } while (false) - - #define Q_REQUIRE_CRIT_(id_, test_) Q_ASSERT_CRIT_((id_), (test_)) - - #define Q_ERROR_CRIT_(id_) do { \ - QF_CRIT_X_(); \ - Q_onAssert(&Q_this_module_[0], (int_t)(id_)); \ - } while (false) - -#endif /* Q_NASSERT */ - -/*==========================================================================*/ - -/* The following bitmasks are for the fields of the @c refCtr_ attribute -* of the QTimeEvt struct (inherited from QEvt). This attribute is NOT used -* for reference counting in time events, because the @c poolId_ attribute -* is zero ("immutable events"). -*/ -#define QTE_IS_LINKED (1U << 7U) -#define QTE_WAS_DISARMED (1U << 6U) -#define QTE_TICK_RATE 0x0FU - -/*! @brief structure representing a free block in the Native QF Memory Pool */ -typedef struct QFreeBlock { - struct QFreeBlock * volatile next; -} QFreeBlock; - -/* internal helper macros ==================================================*/ - -/*! increment the refCtr of a const event (requires casting `const` away) -* @private @memberof QEvt -* -* @tr{PQP11_8} -*/ -static inline void QEvt_refCtr_inc_(QEvt const *me) { - ++((QEvt *)me)->refCtr_; -} - -/*! decrement the refCtr of a const event (requires casting `const` away) -* @private @memberof QEvt -* -* @tr{PQP11_8} -*/ -static inline void QEvt_refCtr_dec_(QEvt const *me) { - --((QEvt *)me)->refCtr_; -} - -#endif /* QP_INC_QF_PKG_H_ */ diff --git a/include/qk.h b/include/qk.h index b6b2927b..fc75a4d0 100644 --- a/include/qk.h +++ b/include/qk.h @@ -1,202 +1,138 @@ -/*$file${include::qk.h} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* -* Model: qpc.qm -* File: ${include::qk.h} -* -* This code has been generated by QM 5.2.4 . -* DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. -* -* This code is covered by the following QP license: -* License # : LicenseRef-QL-dual -* Issued to : Any user of the QP/C real-time embedded framework -* Framework(s) : qpc -* Support ends : 2023-12-31 -* License scope: -* -* Copyright (C) 2005 Quantum Leaps, LLC . -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -*/ -/*$endhead${include::qk.h} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*! @file -* @brief QK/C (preemptive non-blocking kernel) platform-independent -* public interface. -*/ -#ifndef QP_INC_QK_H_ -#define QP_INC_QK_H_ +//$file${include::qk.h} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// +// Model: qpc.qm +// File: ${include::qk.h} +// +// This code has been generated by QM 5.3.0 . +// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. +// +// This code is covered by the following QP license: +// License # : LicenseRef-QL-dual +// Issued to : Any user of the QP/C real-time embedded framework +// Framework(s) : qpc +// Support ends : 2024-12-31 +// License scope: +// +// Copyright (C) 2005 Quantum Leaps, LLC . +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +// +//$endhead${include::qk.h} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +#ifndef QK_H_ +#define QK_H_ -/*==========================================================================*/ -/* QF configuration for QK -- data members of the QActive class... */ +//$declare${QK::QK} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/* QK event-queue used for AOs */ -#define QF_EQUEUE_TYPE QEQueue - -/* QK thread type used for AOs -* QK uses this member to store the private Thread-Local Storage pointer. -*/ -#define QF_THREAD_TYPE void* - -#include "qequeue.h" /* QK kernel uses the native QP event queue */ -#include "qmpool.h" /* QK kernel uses the native QP memory pool */ -#include "qf.h" /* QF framework integrates directly with QK */ - -/*==========================================================================*/ -/*$declare${QK::QK-base} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${QK::QK-base::Attr} .....................................................*/ -/*! @brief QK preemptive non-blocking kernel -* @class QK -*/ -typedef struct QK_Attr { - uint8_t volatile actPrio; /*!< QF prio of the active AO */ - uint8_t volatile nextPrio; /*!< QF prio of the next AO to execute */ - uint8_t volatile actThre; /*!< active preemption-threshold */ - uint8_t volatile lockCeil; /*!< lock preemption-ceiling (0==no-lock) */ - uint8_t volatile lockHolder; /*!< QF prio of the AO holding the lock */ +//${QK::QK} .................................................................. +// @class QK +typedef struct QK { + //! @cond INTERNAL + uint8_t dummy; + //! @endcond } QK; +//$enddecl${QK::QK} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -/*${QK::QK-base::attr_} ....................................................*/ -/*! attributes of the QK kernel */ -extern QK QK_attr_; +//$declare${QK::QSchedStatus} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/*${QK::QK-base::schedLock} ................................................*/ -/*! QK selective scheduler lock -* -* @details -* This function locks the QK scheduler to the specified ceiling. -* -* @param[in] ceiling preemption ceiling to which the QK scheduler -* needs to be locked -* -* @returns -* The previous QK Scheduler lock status, which is to be used to unlock -* the scheduler by restoring its previous lock status in -* QK_schedUnlock(). -* -* @note -* QK_schedLock() must be always followed by the corresponding -* QK_schedUnlock(). -* -* @sa QK_schedUnlock() -* -* @usage -* The following example shows how to lock and unlock the QK scheduler: -* @include qk_lock.c -*/ +//${QK::QSchedStatus} ........................................................ +typedef uint_fast16_t QSchedStatus; +//$enddecl${QK::QSchedStatus} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +//$declare${QK::QK-base} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${QK::QK-base::Attr} ....................................................... +//! @class QK_Attr +typedef struct { +// public: + + //! @memberof QK_Attr + QPSet readySet; + +#ifndef Q_UNSAFE + //! @memberof QK_Attr + QPSet readySet_dis; +#endif // ndef Q_UNSAFE + + //! @memberof QK_Attr + uint_fast8_t volatile actPrio; + + //! @memberof QK_Attr + uint_fast8_t volatile nextPrio; + + //! @memberof QK_Attr + uint_fast8_t volatile actThre; + +// private: + + //! @memberof QK_Attr + uint_fast8_t volatile lockCeil; + +// public: + + //! @memberof QK_Attr + uint_fast8_t volatile lockHolder; + + //! @memberof QK_Attr + uint_fast8_t volatile intNest; +} QK_Attr; + +//${QK::QK-base::priv_} ...................................................... +//! @static @private @memberof QK +extern QK_Attr QK_priv_; + +//${QK::QK-base::schedLock} .................................................. +//! @static @public @memberof QK QSchedStatus QK_schedLock(uint_fast8_t const ceiling); -/*${QK::QK-base::schedUnlock} ..............................................*/ -/*! QK selective scheduler unlock -* -* @details -* This function unlocks the QK scheduler to the previous status. -* -* @param[in] stat previous QK Scheduler lock status returned from -* QK_schedLock() -* @note -* QK_schedUnlock() must always follow the corresponding -* QK_schedLock(). -* -* @sa QK_schedLock() -* -* @usage -* The following example shows how to lock and unlock the QK scheduler: -* @include qk_lock.c -*/ +//${QK::QK-base::schedUnlock} ................................................ +//! @static @public @memberof QK void QK_schedUnlock(QSchedStatus const stat); -/*${QK::QK-base::onIdle} ...................................................*/ -/*! QK idle callback (customized in BSPs for QK) -* @static @public @memberof QK -* -* @details -* QK_onIdle() is called continuously by the QK idle loop. This callback -* gives the application an opportunity to enter a power-saving CPU mode, -* or perform some other idle processing. -* -* @note -* QK_onIdle() is invoked with interrupts enabled and must also return with -* interrupts enabled. -*/ +//${QK::QK-base::onIdle} ..................................................... +//! @static @public @memberof QK void QK_onIdle(void); -/*$enddecl${QK::QK-base} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*$declare${QK::QK-extern-C} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/*${QK::QK-extern-C::sched_} ...............................................*/ -/*! QK scheduler finds the highest-priority AO ready to run -* @static @private @memberof QK -* -* @details -* The QK scheduler finds out the priority of the highest-priority AO -* that (1) has events to process and (2) has priority that is above the -* current priority. -* -* @returns -* The QF-priority of the next active object to activate, or zero -* if no activation of AO is needed. -* -* @attention -* QK_sched_() must be always called with interrupts **disabled** and -* returns with interrupts **disabled**. -*/ +//${QK::QK-base::sched_} ..................................................... +//! @static @private @memberof QK uint_fast8_t QK_sched_(void); -/*${QK::QK-extern-C::activate_} ............................................*/ -/*! QK activator activates the next active object. The activated AO preempts -* the currently executing AOs. -* @static @private @memberof QK -* -* @details -* QK_activate_() activates ready-to run AOs that are above the initial -* preemption-threshold. -* -* @attention -* QK_activate_() must be always called with interrupts **disabled** and -* returns with interrupts **disabled**. -*/ +//${QK::QK-base::activate_} .................................................. +//! @static @private @memberof QK void QK_activate_(void); -/*$enddecl${QK::QK-extern-C} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$enddecl${QK::QK-base} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -/*==========================================================================*/ -/* interface used only inside QF, but not in applications */ +//============================================================================ +// interface used only for internal implementation, but not in applications #ifdef QP_IMPL -/* QK-specific scheduler locking and event queue... */ -/*$declare${QK-impl} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/*${QK-impl::QK_ISR_CONTEXT_} ..............................................*/ -#ifndef QK_ISR_CONTEXT_ -/*! Internal macro that reports the execution context (ISR vs. thread) -* -* @returns true if the code executes in the ISR context and false -* otherwise -*/ -#define QK_ISR_CONTEXT_() (QF_intNest_ != 0U) -#endif /* ndef QK_ISR_CONTEXT_ */ +//$declare${QK-impl} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/*${QK-impl::QF_SCHED_STAT_} ...............................................*/ -/*! QK scheduler lock status */ +//${QK-impl::QF_SCHED_STAT_} ................................................. #define QF_SCHED_STAT_ QSchedStatus lockStat_; -/*${QK-impl::QF_SCHED_LOCK_} ...............................................*/ -/*! QK selective scheduler locking */ +//${QK-impl::QF_SCHED_LOCK_} ................................................. #define QF_SCHED_LOCK_(ceil_) do { \ if (QK_ISR_CONTEXT_()) { \ lockStat_ = 0xFFU; \ @@ -205,52 +141,64 @@ void QK_activate_(void); } \ } while (false) -/*${QK-impl::QF_SCHED_UNLOCK_} .............................................*/ -/*! QK selective scheduler unlocking */ +//${QK-impl::QF_SCHED_UNLOCK_} ............................................... #define QF_SCHED_UNLOCK_() do { \ if (lockStat_ != 0xFFU) { \ QK_schedUnlock(lockStat_); \ } \ } while (false) -/*${QK-impl::QACTIVE_EQUEUE_WAIT_} .........................................*/ -/*! QK native event queue waiting */ +//${QK-impl::QACTIVE_EQUEUE_WAIT_} ........................................... #define QACTIVE_EQUEUE_WAIT_(me_) \ - (Q_ASSERT_ID(110, (me_)->eQueue.frontEvt != (QEvt *)0)) + Q_ASSERT_INCRIT(320, (me_)->eQueue.frontEvt != (QEvt *)0) -/*${QK-impl::QACTIVE_EQUEUE_SIGNAL_} .......................................*/ -/*! QK native event queue signaling */ +//${QK-impl::QACTIVE_EQUEUE_SIGNAL_} ......................................... +#ifndef Q_UNSAFE #define QACTIVE_EQUEUE_SIGNAL_(me_) do { \ - QPSet_insert(&QF_readySet_, (uint_fast8_t)(me_)->prio); \ + QPSet_insert(&QK_priv_.readySet, (uint_fast8_t)(me_)->prio); \ + QPSet_update_(&QK_priv_.readySet, &QK_priv_.readySet_dis); \ if (!QK_ISR_CONTEXT_()) { \ if (QK_sched_() != 0U) { \ QK_activate_(); \ } \ } \ } while (false) -/*$enddecl${QK-impl} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +#endif // ndef Q_UNSAFE -/* Native QF event pool operations... */ -/*$declare${QF-QMPool-impl} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//${QK-impl::QACTIVE_EQUEUE_SIGNAL_} ......................................... +#ifdef Q_UNSAFE +#define QACTIVE_EQUEUE_SIGNAL_(me_) do { \ + QPSet_insert(&QK_priv_.readySet, (uint_fast8_t)(me_)->prio); \ + if (!QK_ISR_CONTEXT_()) { \ + if (QK_sched_() != 0U) { \ + QK_activate_(); \ + } \ + } \ +} while (false) +#endif // def Q_UNSAFE +//$enddecl${QK-impl} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -/*${QF-QMPool-impl::QF_EPOOL_TYPE_} ........................................*/ +//$declare${QF_EPOOL-impl} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${QF_EPOOL-impl::QF_EPOOL_TYPE_} ........................................... #define QF_EPOOL_TYPE_ QMPool -/*${QF-QMPool-impl::QF_EPOOL_INIT_} ........................................*/ +//${QF_EPOOL-impl::QF_EPOOL_INIT_} ........................................... #define QF_EPOOL_INIT_(p_, poolSto_, poolSize_, evtSize_) \ (QMPool_init(&(p_), (poolSto_), (poolSize_), (evtSize_))) -/*${QF-QMPool-impl::QF_EPOOL_EVENT_SIZE_} ..................................*/ +//${QF_EPOOL-impl::QF_EPOOL_EVENT_SIZE_} ..................................... #define QF_EPOOL_EVENT_SIZE_(p_) ((uint_fast16_t)(p_).blockSize) -/*${QF-QMPool-impl::QF_EPOOL_GET_} .........................................*/ +//${QF_EPOOL-impl::QF_EPOOL_GET_} ............................................ #define QF_EPOOL_GET_(p_, e_, m_, qs_id_) \ ((e_) = (QEvt *)QMPool_get(&(p_), (m_), (qs_id_))) -/*${QF-QMPool-impl::QF_EPOOL_PUT_} .........................................*/ +//${QF_EPOOL-impl::QF_EPOOL_PUT_} ............................................ #define QF_EPOOL_PUT_(p_, e_, qs_id_) \ (QMPool_put(&(p_), (e_), (qs_id_))) -/*$enddecl${QF-QMPool-impl} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -#endif /* QP_IMPL */ +//$enddecl${QF_EPOOL-impl} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -#endif /* QP_INC_QK_H_ */ +#endif // QP_IMPL + +#endif // QK_H_ diff --git a/include/qmpool.h b/include/qmpool.h index b76cc2b1..e48594f8 100644 --- a/include/qmpool.h +++ b/include/qmpool.h @@ -1,65 +1,58 @@ -/*$file${include::qmpool.h} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* -* Model: qpc.qm -* File: ${include::qmpool.h} -* -* This code has been generated by QM 5.2.4 . -* DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. -* -* This code is covered by the following QP license: -* License # : LicenseRef-QL-dual -* Issued to : Any user of the QP/C real-time embedded framework -* Framework(s) : qpc -* Support ends : 2023-12-31 -* License scope: -* -* Copyright (C) 2005 Quantum Leaps, LLC . -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -*/ -/*$endhead${include::qmpool.h} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*! @file -* @brief QP native, platform-independent memory pool ::QMPool interface. -*/ -#ifndef QP_INC_QMPOOL_H_ -#define QP_INC_QMPOOL_H_ +//$file${include::qmpool.h} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// +// Model: qpc.qm +// File: ${include::qmpool.h} +// +// This code has been generated by QM 5.3.0 . +// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. +// +// This code is covered by the following QP license: +// License # : LicenseRef-QL-dual +// Issued to : Any user of the QP/C real-time embedded framework +// Framework(s) : qpc +// Support ends : 2024-12-31 +// License scope: +// +// Copyright (C) 2005 Quantum Leaps, LLC . +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +// +//$endhead${include::qmpool.h} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +#ifndef QMPOOL_H_ +#define QMPOOL_H_ -/*==========================================================================*/ #ifndef QF_MPOOL_SIZ_SIZE - /*! macro to override the default ::QMPoolSize size [bytes]. - * Valid values 1U, 2U, or 4U; default 2U - */ #define QF_MPOOL_SIZ_SIZE 2U #endif -#if (QF_MPOOL_SIZ_SIZE == 1U) +#ifndef QF_MPOOL_CTR_SIZE + #define QF_MPOOL_CTR_SIZE 2U +#endif - /*! The data type to store the block-size based on the macro - * #QF_MPOOL_SIZ_SIZE. - * @details - * The dynamic range of this data type determines the maximum size - * of blocks that can be managed by the native QF event pool. - */ +#if (QF_MPOOL_SIZ_SIZE == 1U) typedef uint8_t QMPoolSize; #elif (QF_MPOOL_SIZ_SIZE == 2U) - typedef uint16_t QMPoolSize; #elif (QF_MPOOL_SIZ_SIZE == 4U) typedef uint32_t QMPoolSize; @@ -67,21 +60,7 @@ #error "QF_MPOOL_SIZ_SIZE defined incorrectly, expected 1U, 2U, or 4U" #endif -/*==========================================================================*/ -#ifndef QF_MPOOL_CTR_SIZE - /*! macro to override the default ::QMPoolCtr size [bytes]. - * Valid values 1U, 2U, or 4U; default 2U - */ - #define QF_MPOOL_CTR_SIZE 2U -#endif #if (QF_MPOOL_CTR_SIZE == 1U) - - /*! The data type to store the block-counter based on the macro - * #QF_MPOOL_CTR_SIZE. - * @details - * The dynamic range of this data type determines the maximum number - * of blocks that can be stored in the pool. - */ typedef uint8_t QMPoolCtr; #elif (QF_MPOOL_CTR_SIZE == 2U) typedef uint16_t QMPoolCtr; @@ -91,191 +70,73 @@ #error "QF_MPOOL_CTR_SIZE defined incorrectly, expected 1U, 2U, or 4U" #endif -/*! Memory pool element to allocate correctly aligned storage -* for QMPool class. -* @param[in] evType_ event type (name of the subclass of QEvt) -*/ -#define QF_MPOOL_EL(evType_) \ - struct { void *sto_[((sizeof(evType_) - 1U)/sizeof(void*)) + 1U]; } +#define QF_MPOOL_EL(evType_) struct { \ + QFreeBlock sto_[((sizeof(evType_) - 1U) \ + / sizeof(QFreeBlock)) + 1U]; } -/*==========================================================================*/ -/*$declare${QF::QMPool} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//$declare${QF::QFreeBlock} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/*${QF::QMPool} ............................................................*/ -/*! @brief Native QF Memory Pool -* @class QMPool -* -* @details -* A fixed block-size memory pool is a very fast and efficient data -* structure for dynamic allocation of fixed block-size chunks of memory. -* A memory pool offers fast and deterministic allocation and recycling of -* memory blocks and is not subject to fragmenation.
-* -* The ::QMPool class describes the native QF memory pool, which can be used as -* the event pool for dynamic event allocation, or as a fast, deterministic -* fixed block-size heap for any other objects in your application. -* -* @note -* ::QMPool contains only data members for managing a memory pool, but -* does not contain the pool storage, which must be provided externally -* during the pool initialization. -* -* @note -* The native QF event pool is configured by defining the macro -* #QF_EPOOL_TYPE_ as ::QMPool in the specific QF port header file. -*/ +//${QF::QFreeBlock} .......................................................... +//! @struct QFreeBlock +typedef struct QFreeBlock { +// private: + + //! @private @memberof QFreeBlock + struct QFreeBlock * next; + +#ifndef Q_UNSAFE + //! @private @memberof QFreeBlock + uintptr_t next_dis; +#endif // ndef Q_UNSAFE +} QFreeBlock; +//$enddecl${QF::QFreeBlock} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +//$declare${QF::QMPool} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${QF::QMPool} .............................................................. +//! @class QMPool typedef struct { -/* private: */ +// private: - /*! start of the memory managed by this memory pool - * @private @memberof QMPool - */ - void * start; + //! @private @memberof QMPool + QFreeBlock * start; - /*! end of the memory managed by this memory pool - * @private @memberof QMPool - */ - void * end; + //! @private @memberof QMPool + QFreeBlock * end; - /*! head of linked list of free blocks - * @private @memberof QMPool - */ - void * volatile free_head; + //! @private @memberof QMPool + QFreeBlock * volatile free_head; - /*! maximum block size (in bytes) - * @private @memberof QMPool - */ + //! @private @memberof QMPool QMPoolSize blockSize; - /*! total number of blocks - * @private @memberof QMPool - */ + //! @private @memberof QMPool QMPoolCtr nTot; - /*! number of free blocks remaining - * @private @memberof QMPool - */ + //! @private @memberof QMPool QMPoolCtr volatile nFree; - /*! minimum number of free blocks ever present in this pool - * @private @memberof QMPool - * - * @details - * this attribute remembers the low watermark of the pool, which - * provides a valuable information for sizing event pools. - * @sa QF_getPoolMin(). - */ + //! @private @memberof QMPool QMPoolCtr nMin; } QMPool; -/* public: */ +// public: -/*! Initializes the native QF memory pool -* @public @memberof QMPool -* -* @details -* Initialize a fixed block-size memory pool by providing it with the pool -* memory to manage, size of this memory, and the block size. -* -* @param[in,out] me current instance pointer (see @ref oop) -* @param[in] poolSto pointer to the memory buffer for pool storage -* @param[in] poolSize size of the storage buffer in bytes -* @param[in] blockSize fixed-size of the memory blocks in bytes -* -* @attention -* The caller of QMPool::init() must make sure that the `poolSto` -* pointer is properly **aligned**. In particular, it must be possible to -* efficiently store a pointer at the location pointed to by `poolSto`. -* Internally, the QMPool_init() function rounds up the block size -* `blockSize` so that it can fit an integer number of pointers. -* This is done to achieve proper alignment of the blocks within the pool. -* -* @note -* Due to the rounding of block size the actual capacity of the pool might -* be less than (`poolSize` / `blockSize`). You can check the capacity -* of the pool by calling the QF_getPoolMin() function. -* -* @note -* This function is **not** protected by a critical section, because -* it is intended to be called only during the initialization of the system, -* when interrupts are not allowed yet. -* -* @note -* Many QF ports use memory pools to implement the event pools. -* -* @usage -* The following example illustrates how to invoke QMPool_init(): -* @include qmp_init.c -*/ +//! @public @memberof QMPool void QMPool_init(QMPool * const me, void * const poolSto, - uint_fast32_t poolSize, - uint_fast16_t blockSize); + uint_fast32_t const poolSize, + uint_fast16_t const blockSize); -/*! Obtains a memory block from a memory pool. -* @public @memberof QMPool -* -* @details -* The function allocates a memory block from the pool and returns a pointer -* to the block back to the caller. -* -* @param[in,out] me current instance pointer (see @ref oop) -* @param[in] margin the minimum number of unused blocks still available -* in the pool after the allocation. -* -* @returns -* A pointer to a memory block or NULL if no more blocks are available in -* the memory pool. -* -* @note -* This function can be called from any task level or ISR level. -* -* @note -* The memory pool `me` must be initialized before any events can -* be requested from it. Also, the QMPool_get() function uses internally a -* QF critical section, so you should be careful not to call it from within -* a critical section when nesting of critical section is not supported. -* -* @attention -* An allocated block must be later returned back to the **same** pool -* from which it has been allocated. -* -* @sa QMPool_put() -* -* @usage -* The following example illustrates how to use QMPool_get(): -* @include qmp_use.c -*/ +//! @public @memberof QMPool void * QMPool_get(QMPool * const me, uint_fast16_t const margin, uint_fast8_t const qs_id); -/*! Recycles a memory block back to a memory pool. -* @public @memberof QMPool -* -* @details -* Recycle a memory block to the fixed block-size memory pool. -* -* @param[in,out] me current instance pointer (see @ref oop) -* @param[in] b pointer to the memory block that is being recycled -* -* @attention -* The recycled block must be allocated from the **same** memory pool -* to which it is returned. -* -* @note -* This function can be called from any task level or ISR level. -* -* @sa -* QMPool_get() -* -* @usage -* The following example illustrates how to use QMPool_put(): -* @include qmp_use.c -*/ +//! @public @memberof QMPool void QMPool_put(QMPool * const me, - void * const b, + void * const block, uint_fast8_t const qs_id); -/*$enddecl${QF::QMPool} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$enddecl${QF::QMPool} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -#endif /* QP_INC_QMPOOL_H_ */ +#endif // QMPOOL_H_ diff --git a/include/qp.h b/include/qp.h new file mode 100644 index 00000000..4c544b00 --- /dev/null +++ b/include/qp.h @@ -0,0 +1,1265 @@ +//$file${include::qp.h} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// +// Model: qpc.qm +// File: ${include::qp.h} +// +// This code has been generated by QM 5.3.0 . +// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. +// +// This code is covered by the following QP license: +// License # : LicenseRef-QL-dual +// Issued to : Any user of the QP/C real-time embedded framework +// Framework(s) : qpc +// Support ends : 2024-12-31 +// License scope: +// +// Copyright (C) 2005 Quantum Leaps, LLC . +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +// +//$endhead${include::qp.h} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +#ifndef QP_H_ +#define QP_H_ + +//============================================================================ +#define QP_VERSION 730U +#define QP_VERSION_STR "7.3.0" + +//! Encrypted current QP release (7.3.0) and date (2023-09-12) +#define QP_RELEASE 0x765D9D25U + +//============================================================================ +//! @cond INTERNAL + +#ifndef Q_SIGNAL_SIZE +#define Q_SIGNAL_SIZE 2U +#endif + +#ifndef QF_MAX_ACTIVE +#define QF_MAX_ACTIVE 32U +#endif + +#if (QF_MAX_ACTIVE > 64U) +#error QF_MAX_ACTIVE exceeds the maximum of 64U; +#endif + +#ifndef QF_MAX_TICK_RATE +#define QF_MAX_TICK_RATE 1U +#endif + +#if (QF_MAX_TICK_RATE > 15U) +#error QF_MAX_TICK_RATE exceeds the maximum of 15U; +#endif + +#ifndef QF_MAX_EPOOL +#define QF_MAX_EPOOL 3U +#endif + +#if (QF_MAX_EPOOL > 15U) +#error QF_MAX_EPOOL exceeds the maximum of 15U; +#endif + +#ifndef QF_TIMEEVT_CTR_SIZE +#define QF_TIMEEVT_CTR_SIZE 4U +#endif + +#if (QF_TIMEEVT_CTR_SIZE > 4U) +#error QF_TIMEEVT_CTR_SIZE defined incorrectly, expected 1U, 2U, or 4U; +#endif + +#ifndef QF_EVENT_SIZ_SIZE +#define QF_EVENT_SIZ_SIZE 2U +#endif + +#if (QF_EVENT_SIZ_SIZE > 4U) +#error QF_EVENT_SIZ_SIZE defined incorrectly, expected 1U, 2U, or 4U; +#endif + +//! @endcond +//============================================================================ + +//$declare${glob-types} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${glob-types::int_t} ....................................................... +typedef int int_t; + +//${glob-types::enum_t} ...................................................... +typedef int enum_t; + +//${glob-types::float32_t} ................................................... +typedef float float32_t; + +//${glob-types::float64_t} ................................................... +typedef double float64_t; +//$enddecl${glob-types} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +//$declare${QEP} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${QEP::QP_versionStr[8]} ................................................... +//! the current QP version number string in ROM, based on #QP_VERSION_STR +extern char const QP_versionStr[8]; + +//${QEP::QSignal} ............................................................ +#if (Q_SIGNAL_SIZE == 1U) +typedef uint8_t QSignal; +#endif // (Q_SIGNAL_SIZE == 1U) + +//${QEP::QSignal} ............................................................ +#if (Q_SIGNAL_SIZE == 2U) +typedef uint16_t QSignal; +#endif // (Q_SIGNAL_SIZE == 2U) + +//${QEP::QSignal} ............................................................ +#if (Q_SIGNAL_SIZE == 4U) +typedef uint32_t QSignal; +#endif // (Q_SIGNAL_SIZE == 4U) + +//${QEP::QEVT_MARKER} ........................................................ +#define QEVT_MARKER 0xE0U + +//${QEP::QEVT_DYNAMIC} ....................................................... +#define QEVT_DYNAMIC 0U + +//${QEP::QEvt} ............................................................... +// ! @class QEvt +typedef struct QEvt { +// public: + + //! @public @memberof QEvt + QSignal sig; + +// private: + + //! @private @memberof QEvt + uint8_t volatile refCtr_; + + //! @private @memberof QEvt + uint8_t evtTag_; +} QEvt; + +extern QEvt const QEvt_reserved_[4]; + +// public: + +//! @public @memberof QEvt +static inline QEvt * QEvt_ctor(QEvt * const me, + enum_t const sig) +{ + if (sig != QEVT_DYNAMIC) { + me->sig = (QSignal)sig; + me->refCtr_ = 0U; + me->evtTag_ = QEVT_MARKER; + } + return me; +} + +// private: + +//! @private @memberof QEvt +static inline bool QEvt_verify_(QEvt const * const me) { + return (me != (QEvt const *)0) + && ((me->evtTag_ & 0xF0U) == QEVT_MARKER); +} + +//! @private @memberof QEvt +static inline uint_fast8_t QEvt_getPoolId_(QEvt const * const me) { + return (uint_fast8_t)me->evtTag_ & 0x0FU; +} + +//${QEP::QStateRet} .......................................................... +//! All possible values returned from state/action handlers +//! @note +//! The order of enumeration matters for algorithmic correctness. +enum QStateRet { + // unhandled and need to "bubble up" + Q_RET_SUPER, //!< event passed to superstate to handle + Q_RET_SUPER_SUB, //!< event passed to submachine superstate + Q_RET_UNHANDLED, //!< event unhandled due to a guard + + // handled and do not need to "bubble up" + Q_RET_HANDLED, //!< event handled (internal transition) + Q_RET_IGNORED, //!< event silently ignored (bubbled up to top) + + // entry/exit + Q_RET_ENTRY, //!< state entry action executed + Q_RET_EXIT, //!< state exit action executed + + // no side effects + Q_RET_NULL, //!< return value without any effect + + // transitions need to execute transition-action table in ::QMsm + Q_RET_TRAN, //!< regular transition + Q_RET_TRAN_INIT, //!< initial transition in a state or submachine + Q_RET_TRAN_EP, //!< entry-point transition into a submachine + + // transitions that additionally clobber me->state + Q_RET_TRAN_HIST, //!< transition to history of a given state + Q_RET_TRAN_XP //!< exit-point transition out of a submachine +}; + +//${QEP::QState} ............................................................. +typedef enum QStateRet QState; + +//${QEP::QStateHandler} ...................................................... +typedef QState (* QStateHandler )(void * const me, QEvt const * const e); + +//${QEP::QActionHandler} ..................................................... +typedef QState (* QActionHandler )(void * const me); + +//${QEP::QXThread} ........................................................... +// forward declaration +struct QXThread; + +//${QEP::QXThreadHandler} .................................................... +typedef void (* QXThreadHandler )(struct QXThread * const me); + +//${QEP::QMState} ............................................................ +typedef struct QMState { + struct QMState const *superstate; //!< @private @memberof QMState + QStateHandler const stateHandler; //!< @private @memberof QMState + QActionHandler const entryAction; //!< @private @memberof QMState + QActionHandler const exitAction; //!< @private @memberof QMState + QActionHandler const initAction; //!< @private @memberof QMState +} QMState; + +//${QEP::QMTranActTable} ..................................................... +typedef struct QMTranActTable { + QMState const *target; //!< @private @memberof QMTranActTable + QActionHandler const act[1]; //!< @private @memberof QMTranActTable +} QMTranActTable; + +//${QEP::QReservedSig} ....................................................... +//! Reserved signals by the QHsm-style state machine implementation +enum QReservedSig { + Q_EMPTY_SIG, //!< signal to execute the default case + Q_ENTRY_SIG, //!< signal for coding entry actions + Q_EXIT_SIG, //!< signal for coding exit actions + Q_INIT_SIG, //!< signal for coding initial transitions + Q_USER_SIG //!< offset for the user signals (QP Application) +}; + +//${QEP::QAsmAttr} ........................................................... +union QAsmAttr { + QStateHandler fun; //!< @private @memberof QAsmAttr + QActionHandler act; //!< @private @memberof QAsmAttr + QXThreadHandler thr; //!< @private @memberof QAsmAttr + QMTranActTable const *tatbl; //!< @private @memberof QAsmAttr + struct QMState const *obj; //!< @private @memberof QAsmAttr +#ifndef Q_UNSAFE + uintptr_t uint; //!< @private @memberof QAsmAttr +#endif +}; + +//${QEP::QAsm} ............................................................... +//! @class QAsm +typedef struct { +// private: + + //! @protected @memberof QAsm + struct QAsmVtable const * vptr; + +// protected: + + //! @protected @memberof QAsm + union QAsmAttr state; + + //! @protected @memberof QAsm + union QAsmAttr temp; +} QAsm; + +// protected: + +//! @protected @memberof QAsm +void QAsm_ctor(QAsm * const me); + +//${QEP::QAsmVtable} ......................................................... +struct QAsmVtable { + void (*init)(QAsm * const me, void const * const e, + uint_fast8_t const qs_id); + void (*dispatch)(QAsm * const me, QEvt const * const e, + uint_fast8_t const qs_id); +#ifdef Q_SPY + QStateHandler (*getStateHandler)(QAsm * const me); +#endif // Q_SPY +}; + +//${QEP::QHsm} ............................................................... +//! @class QHsm +//! @extends QAsm +typedef struct { +// protected: + QAsm super; +} QHsm; + +// protected: + +//! @protected @memberof QHsm +void QHsm_ctor(QHsm * const me, + QStateHandler const initial); + +// private: + +//! @private @memberof QHsm +void QHsm_init_( + QAsm * const me, + void const * const e, + uint_fast8_t const qs_id); + +//! @private @memberof QHsm +void QHsm_dispatch_( + QAsm * const me, + QEvt const * const e, + uint_fast8_t const qs_id); + +#ifdef Q_SPY +//! @private @memberof QHsm +QStateHandler QHsm_getStateHandler_(QAsm * const me); +#endif // def Q_SPY + +// public: + +//! @public @memberof QHsm +bool QHsm_isIn(QHsm * const me, + QStateHandler const state); + +//! @public @memberof QHsm +static inline QStateHandler QHsm_state(QHsm const * const me) { + return me->super.state.fun; +} + +//! @public @memberof QHsm +QStateHandler QHsm_childState(QHsm * const me, + QStateHandler const parent); + +// private: + +//! @private @memberof QHsm +int_fast8_t QHsm_tran_( + QAsm * const me, + QStateHandler * const path, + uint_fast8_t const qs_id); + +// protected: + +//! @protected @memberof QAsm +QState QHsm_top(QHsm const * const me, + QEvt const * const e); + +//${QEP::QMsm} ............................................................... +//! @class QMsm +//! @extends QAsm +typedef struct { +// protected: + QAsm super; +} QMsm; + +// protected: + +//! @protected @memberof QMsm +void QMsm_ctor(QMsm * const me, + QStateHandler const initial); + +// public: + +//! @private @memberof QMsm +void QMsm_init_( + QAsm * const me, + void const * const e, + uint_fast8_t const qs_id); + +// private: + +//! @private @memberof QMsm +void QMsm_dispatch_( + QAsm * const me, + QEvt const * const e, + uint_fast8_t const qs_id); + +// public: + +#ifdef Q_SPY +//! @public @memberof QMsm +static inline QStateHandler QMsm_getStateHandler_(QAsm * const me) { + return me->state.obj->stateHandler; +} +#endif // def Q_SPY + +//! @public @memberof QMsm +bool QMsm_isInState(QMsm const * const me, + QMState const * const stateObj); + +//! @public @memberof QMsm +static inline QMState const * QMsm_stateObj(QMsm * const me) { + return me->super.state.obj; +} + +//! @public @memberof QMsm +QMState const * QMsm_childStateObj(QMsm const * const me, + QMState const * const parent); + +// private: + +//! @private @memberof QMsm +QState QMsm_execTatbl_( + QAsm * const me, + QMTranActTable const * const tatbl, + uint_fast8_t const qs_id); + +//! @private @memberof QMsm +void QMsm_exitToTranSource_( + QAsm * const me, + QMState const * const cs, + QMState const * const ts, + uint_fast8_t const qs_id); + +//! @private @memberof QMsm +QState QMsm_enterHistory_( + QAsm * const me, + QMState const *const hist, + uint_fast8_t const qs_id); +//$enddecl${QEP} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +//$declare${QEP-macros} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${QEP-macros::QEVT_INITIALIZER} ............................................ +#define QEVT_INITIALIZER(sig_) { (QSignal)(sig_), 0U, QEVT_MARKER } + +//${QEP-macros::QASM_INIT} ................................................... +#ifdef Q_SPY +#define QASM_INIT(me_, par_, qs_id_) do { \ + Q_ASSERT(((QAsm *)(me_))->vptr); \ + (*((QAsm *)(me_))->vptr->init)((QAsm *)(me_), (par_), (qs_id_)); \ +} while (false) +#endif // def Q_SPY + +//${QEP-macros::QASM_INIT} ................................................... +#ifndef Q_SPY +#define QASM_INIT(me_, par_, dummy) do { \ + Q_ASSERT(((QAsm *)(me_))->vptr); \ + (*((QAsm *)(me_))->vptr->init)((QAsm *)(me_), (par_), 0); \ +} while (false) +#endif // ndef Q_SPY + +//${QEP-macros::QASM_DISPATCH} ............................................... +#ifdef Q_SPY +#define QASM_DISPATCH(me_, e_, qs_id_) \ + (*((QAsm *)(me_))->vptr->dispatch)((QAsm *)(me_), (e_), (qs_id_)) +#endif // def Q_SPY + +//${QEP-macros::QASM_DISPATCH} ............................................... +#ifndef Q_SPY +#define QASM_DISPATCH(me_, e_, dummy) \ + (*((QAsm *)(me_))->vptr->dispatch)((QAsm *)(me_), (e_), 0U) +#endif // ndef Q_SPY + +//${QEP-macros::Q_ASM_UPCAST} ................................................ +#define Q_ASM_UPCAST(ptr_) ((QAsm *)(ptr_)) + +//${QEP-macros::Q_HSM_UPCAST} ................................................ +#define Q_HSM_UPCAST(ptr_) ((QHsm *)(ptr_)) + +//${QEP-macros::Q_MSM_UPCAST} ................................................ +#define Q_MSM_UPCAST(ptr_) ((QMsm *)(ptr_)) + +//${QEP-macros::Q_TRAN} ...................................................... +#define Q_TRAN(target_) \ + ((Q_ASM_UPCAST(me))->temp.fun = Q_STATE_CAST(target_), \ + (QState)Q_RET_TRAN) + +//${QEP-macros::Q_TRAN_HIST} ................................................. +#define Q_TRAN_HIST(hist_) \ + ((Q_ASM_UPCAST(me))->temp.fun = (hist_), \ + (QState)Q_RET_TRAN_HIST) + +//${QEP-macros::Q_SUPER} ..................................................... +#define Q_SUPER(super_) \ + ((Q_ASM_UPCAST(me))->temp.fun = Q_STATE_CAST(super_), \ + (QState)Q_RET_SUPER) + +//${QEP-macros::Q_HANDLED} ................................................... +#define Q_HANDLED() ((QState)Q_RET_HANDLED) + +//${QEP-macros::Q_UNHANDLED} ................................................. +#define Q_UNHANDLED() ((QState)Q_RET_UNHANDLED) + +//${QEP-macros::Q_ACTION_NULL} ............................................... +#define Q_ACTION_NULL ((QActionHandler)0) + +//${QEP-macros::Q_EVT_CAST} .................................................. +#define Q_EVT_CAST(class_) ((class_ const *)(e)) + +//${QEP-macros::Q_STATE_CAST} ................................................ +#define Q_STATE_CAST(handler_) ((QStateHandler)(handler_)) + +//${QEP-macros::Q_ACTION_CAST} ............................................... +#define Q_ACTION_CAST(action_) ((QActionHandler)(action_)) + +//${QEP-macros::Q_UNUSED_PAR} ................................................ +#define Q_UNUSED_PAR(par_) ((void)(par_)) + +//${QEP-macros::Q_DIM} ....................................................... +#define Q_DIM(array_) (sizeof(array_) / sizeof((array_)[0U])) + +//${QEP-macros::Q_UINT2PTR_CAST} ............................................. +#define Q_UINT2PTR_CAST(type_, uint_) ((type_ *)(uint_)) + +//${QEP-macros::QM_ENTRY} .................................................... +#ifdef Q_SPY +#define QM_ENTRY(state_) \ + ((Q_ASM_UPCAST(me))->temp.obj = (state_), \ + (QState)Q_RET_ENTRY) +#endif // def Q_SPY + +//${QEP-macros::QM_ENTRY} .................................................... +#ifndef Q_SPY +#define QM_ENTRY(dummy) ((QState)Q_RET_ENTRY) +#endif // ndef Q_SPY + +//${QEP-macros::QM_EXIT} ..................................................... +#ifdef Q_SPY +#define QM_EXIT(state_) \ + ((Q_ASM_UPCAST(me))->temp.obj = (state_), \ + (QState)Q_RET_EXIT) +#endif // def Q_SPY + +//${QEP-macros::QM_EXIT} ..................................................... +#ifndef Q_SPY +#define QM_EXIT(dummy) ((QState)Q_RET_EXIT) +#endif // ndef Q_SPY + +//${QEP-macros::QM_SM_EXIT} .................................................. +#define QM_SM_EXIT(state_) \ + ((Q_ASM_UPCAST(me))->temp.obj = (state_), \ + (QState)Q_RET_EXIT) + +//${QEP-macros::QM_TRAN} ..................................................... +#define QM_TRAN(tatbl_) ((Q_ASM_UPCAST(me))->temp.tatbl \ + = (struct QMTranActTable const *)(tatbl_), \ + (QState)Q_RET_TRAN) + +//${QEP-macros::QM_TRAN_INIT} ................................................ +#define QM_TRAN_INIT(tatbl_) ((Q_ASM_UPCAST(me))->temp.tatbl \ + = (struct QMTranActTable const *)(tatbl_), \ + (QState)Q_RET_TRAN_INIT) + +//${QEP-macros::QM_TRAN_HIST} ................................................ +#define QM_TRAN_HIST(history_, tatbl_) \ + ((((Q_ASM_UPCAST(me))->state.obj = (history_)), \ + ((Q_ASM_UPCAST(me))->temp.tatbl = \ + (struct QMTranActTable const *)(tatbl_))), \ + (QState)Q_RET_TRAN_HIST) + +//${QEP-macros::QM_TRAN_EP} .................................................. +#define QM_TRAN_EP(tatbl_) ((Q_ASM_UPCAST(me))->temp.tatbl \ + = (struct QMTranActTable const *)(tatbl_), \ + (QState)Q_RET_TRAN_EP) + +//${QEP-macros::QM_TRAN_XP} .................................................. +#define QM_TRAN_XP(xp_, tatbl_) \ + ((((Q_ASM_UPCAST(me))->state.act = (xp_)), \ + ((Q_ASM_UPCAST(me))->temp.tatbl = \ + (struct QMTranActTable const *)(tatbl_))), \ + (QState)Q_RET_TRAN_XP) + +//${QEP-macros::QM_HANDLED} .................................................. +#define QM_HANDLED() ((QState)Q_RET_HANDLED) + +//${QEP-macros::QM_UNHANDLED} ................................................ +#define QM_UNHANDLED() ((QState)Q_RET_UNHANDLED) + +//${QEP-macros::QM_SUPER} .................................................... +#define QM_SUPER() ((QState)Q_RET_SUPER) + +//${QEP-macros::QM_SUPER_SUB} ................................................ +#define QM_SUPER_SUB(host_) \ + ((Q_ASM_UPCAST(me))->temp.obj = (host_), \ + (QState)Q_RET_SUPER_SUB) + +//${QEP-macros::QM_STATE_NULL} ............................................... +#define QM_STATE_NULL ((QMState *)0) +//$enddecl${QEP-macros} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +//$declare${QF::types} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${QF::types::QPrioSpec} .................................................... +typedef uint16_t QPrioSpec; + +//${QF::types::QTimeEvtCtr} .................................................. +#if (QF_TIMEEVT_CTR_SIZE == 1U) +typedef uint8_t QTimeEvtCtr; +#endif // (QF_TIMEEVT_CTR_SIZE == 1U) + +//${QF::types::QTimeEvtCtr} .................................................. +#if (QF_TIMEEVT_CTR_SIZE == 2U) +typedef uint16_t QTimeEvtCtr; +#endif // (QF_TIMEEVT_CTR_SIZE == 2U) + +//${QF::types::QTimeEvtCtr} .................................................. +#if (QF_TIMEEVT_CTR_SIZE == 4U) +typedef uint32_t QTimeEvtCtr; +#endif // (QF_TIMEEVT_CTR_SIZE == 4U) + +//${QF::types::QPSetBits} .................................................... +#if (QF_MAX_ACTIVE <= 8U) +typedef uint8_t QPSetBits; +#endif // (QF_MAX_ACTIVE <= 8U) + +//${QF::types::QPSetBits} .................................................... +#if (8U < QF_MAX_ACTIVE) && (QF_MAX_ACTIVE <= 16U) +typedef uint16_t QPSetBits; +#endif // (8U < QF_MAX_ACTIVE) && (QF_MAX_ACTIVE <= 16U) + +//${QF::types::QPSetBits} .................................................... +#if (16U < QF_MAX_ACTIVE) +typedef uint32_t QPSetBits; +#endif // (16U < QF_MAX_ACTIVE) + +//${QF::types::QF_LOG2} ...................................................... +#ifndef QF_LOG2 +uint_fast8_t QF_LOG2(QPSetBits const bitmask); +#endif // ndef QF_LOG2 + +//${QF::types::QPSet} ........................................................ +//! @class QPSet +typedef struct { +// private: + + //! @private @memberof QPSet + QPSetBits bits[((QF_MAX_ACTIVE + (8U*sizeof(QPSetBits))) - 1U)/(8U*sizeof(QPSetBits))]; +} QPSet; + +// public: + +//! @public @memberof QPSet +static inline void QPSet_setEmpty(QPSet * const me) { + me->bits[0] = 0U; + #if (QF_MAX_ACTIVE > 32) + me->bits[1] = 0U; + #endif +} + +//! @public @memberof QPSet +static inline bool QPSet_isEmpty(QPSet const * const me) { + #if (QF_MAX_ACTIVE <= 32U) + return (me->bits[0] == 0U); + #else + return (me->bits[0] == 0U) ? (me->bits[1] == 0U) : false; + #endif +} + +//! @public @memberof QPSet +static inline bool QPSet_notEmpty(QPSet const * const me) { + #if (QF_MAX_ACTIVE <= 32U) + return (me->bits[0] != 0U); + #else + return (me->bits[0] != 0U) ? true : (me->bits[1] != 0U); + #endif +} + +//! @public @memberof QPSet +static inline bool QPSet_hasElement(QPSet const * const me, + uint_fast8_t const n) +{ + #if (QF_MAX_ACTIVE <= 32U) + return (me->bits[0] & ((QPSetBits)1U << (n - 1U))) != 0U; + #else + return (n <= 32U) + ? ((me->bits[0] & ((QPSetBits)1U << (n - 1U))) != 0U) + : ((me->bits[1] & ((QPSetBits)1U << (n - 33U))) != 0U); + #endif +} + +//! @public @memberof QPSet +static inline void QPSet_insert(QPSet * const me, + uint_fast8_t const n) +{ + #if (QF_MAX_ACTIVE <= 32U) + me->bits[0] = (me->bits[0] | ((QPSetBits)1U << (n - 1U))); + #else + if (n <= 32U) { + me->bits[0] = (me->bits[0] | ((QPSetBits)1U << (n - 1U))); + } + else { + me->bits[1] = (me->bits[1] | ((QPSetBits)1U << (n - 33U))); + } + #endif +} + +//! @public @memberof QPSet +static inline void QPSet_remove(QPSet * const me, + uint_fast8_t const n) +{ + #if (QF_MAX_ACTIVE <= 32U) + me->bits[0] = (me->bits[0] & (QPSetBits)(~((QPSetBits)1U << (n - 1U)))); + #else + if (n <= 32U) { + (me->bits[0] = (me->bits[0] & ~((QPSetBits)1U << (n - 1U)))); + } + else { + (me->bits[1] = (me->bits[1] & ~((QPSetBits)1U << (n - 33U)))); + } + #endif +} + +//! @public @memberof QPSet +static inline uint_fast8_t QPSet_findMax(QPSet const * const me) { + #if (QF_MAX_ACTIVE <= 32U) + return QF_LOG2(me->bits[0]); + #else + return (me->bits[1] != 0U) + ? (QF_LOG2(me->bits[1]) + 32U) + : (QF_LOG2(me->bits[0])); + #endif +} + +// private: + +#ifndef Q_UNSAFE +//! @private @memberof QPSet +static inline void QPSet_update_(QPSet const * const me, + QPSet * const dis) +{ + dis->bits[0] = ~me->bits[0]; + #if (QF_MAX_ACTIVE > 32U) + dis->bits[1] = ~me->bits[1]; + #endif +} +#endif // ndef Q_UNSAFE + +#ifndef Q_UNSAFE +//! @private @memberof QPSet +static inline bool QPSet_verify_(QPSet const * const me, + QPSet const * const dis) +{ + #if (QF_MAX_ACTIVE <= 32U) + return me->bits[0] == (QPSetBits)(~dis->bits[0]); + #else + return (me->bits[0] == (QPSetBits)(~dis->bits[0])) + && (me->bits[1] == (QPSetBits)(~dis->bits[1])); + #endif +} +#endif // ndef Q_UNSAFE + +//${QF::types::QSubscrList} .................................................. +// @struct QSubscrList +typedef struct { +// private: + + //! @private @memberof QSubscrList + QPSet set; + +#ifndef Q_UNSAFE + //! @private @memberof QSubscrList + QPSet set_dis; +#endif // ndef Q_UNSAFE +} QSubscrList; + +//${QF::types::QEQueue} ...................................................... +struct QEQueue; +//$enddecl${QF::types} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +//$declare${QF::QActive} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${QF::QActive} ............................................................. +//! @class QActive +//! @extends QAsm +typedef struct QActive { +// protected: + QAsm super; + +#ifdef QACTIVE_EQUEUE_TYPE + //! @private @memberof QActive + QACTIVE_EQUEUE_TYPE eQueue; +#endif // def QACTIVE_EQUEUE_TYPE + +#ifdef QACTIVE_OS_OBJ_TYPE + //! @private @memberof QActive + QACTIVE_OS_OBJ_TYPE osObject; +#endif // def QACTIVE_OS_OBJ_TYPE + +#ifdef QACTIVE_THREAD_TYPE + //! @private @memberof QActive + QACTIVE_THREAD_TYPE thread; +#endif // def QACTIVE_THREAD_TYPE + + //! @private @memberof QActive + uint8_t prio; + + //! @private @memberof QActive + uint8_t pthre; + +// private: +} QActive; + +//! @static @private @memberof QActive +extern QActive * QActive_registry_[QF_MAX_ACTIVE + 1U]; + +//! @static @private @memberof QActive +extern QSubscrList * QActive_subscrList_; + +//! @static @private @memberof QActive +extern enum_t QActive_maxPubSignal_; + +// protected: + +//! @protected @memberof QActive +void QActive_ctor(QActive * const me, + QStateHandler const initial); + +// public: + +//! @public @memberof QActive +void QActive_setAttr(QActive * const me, + uint32_t attr1, + void const * attr2); + +// private: + +//! @private @memberof QActive +void QActive_start_(QActive * const me, + QPrioSpec const prioSpec, + QEvt const * * const qSto, + uint_fast16_t const qLen, + void * const stkSto, + uint_fast16_t const stkSize, + void const * const par); + +// protected: + +#ifdef QACTIVE_CAN_STOP +//! @protected @memberof QActive +void QActive_stop(QActive * const me); +#endif // def QACTIVE_CAN_STOP + +// private: + +//! @private @memberof QActive +void QActive_register_(QActive * const me); + +//! @private @memberof QActive +void QActive_unregister_(QActive * const me); + +//! @private @memberof QActive +bool QActive_post_(QActive * const me, + QEvt const * const e, + uint_fast16_t const margin, + void const * const sender); + +//! @private @memberof QActive +void QActive_postLIFO_(QActive * const me, + QEvt const * const e); + +//! @private @memberof QActive +QEvt const * QActive_get_(QActive * const me); + +// public: + +//! @static @public @memberof QActive +void QActive_psInit( + QSubscrList * const subscrSto, + enum_t const maxSignal); + +// private: + +//! @static @private @memberof QActive +void QActive_publish_( + QEvt const * const e, + void const * const sender, + uint_fast8_t const qs_id); + +// protected: + +//! @protected @memberof QActive +void QActive_subscribe(QActive const * const me, + enum_t const sig); + +//! @protected @memberof QActive +void QActive_unsubscribe(QActive const * const me, + enum_t const sig); + +//! @protected @memberof QActive +void QActive_unsubscribeAll(QActive const * const me); + +//! @protected @memberof QActive +bool QActive_defer(QActive const * const me, + struct QEQueue * const eq, + QEvt const * const e); + +//! @protected @memberof QActive +bool QActive_recall(QActive * const me, + struct QEQueue * const eq); + +//! @protected @memberof QActive +uint_fast16_t QActive_flushDeferred(QActive const * const me, + struct QEQueue * const eq); + +// private: + +//! @private @memberof QActive +void QActive_evtLoop_(QActive * const me); +//$enddecl${QF::QActive} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +//$declare${QF::QMActive} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${QF::QMActive} ............................................................ +//! @class QMActive +//! @extends QActive +typedef struct { +// protected: + QActive super; +} QMActive; + +// protected: + +//! @protected @memberof QMActive +void QMActive_ctor(QMActive * const me, + QStateHandler const initial); +//$enddecl${QF::QMActive} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +//$declare${QF::QTimeEvt} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${QF::QTimeEvt} ............................................................ +//! @class QTimeEvt +// @extends QEvt +typedef struct QTimeEvt { +// protected: + QEvt super; + +// private: + + //! @private @memberof QTimeEvt + struct QTimeEvt * volatile next; + + //! @private @memberof QTimeEvt + void * volatile act; + + //! @private @memberof QTimeEvt + QTimeEvtCtr volatile ctr; + + //! @private @memberof QTimeEvt + QTimeEvtCtr interval; +} QTimeEvt; + +//! @static @private @memberof QTimeEvt +extern QTimeEvt QTimeEvt_timeEvtHead_[QF_MAX_TICK_RATE]; + +// public: + +//! @public @memberof QTimeEvt +void QTimeEvt_ctorX(QTimeEvt * const me, + QActive * const act, + enum_t const sig, + uint_fast8_t const tickRate); + +//! @public @memberof QTimeEvt +void QTimeEvt_armX(QTimeEvt * const me, + QTimeEvtCtr const nTicks, + QTimeEvtCtr const interval); + +//! @public @memberof QTimeEvt +bool QTimeEvt_disarm(QTimeEvt * const me); + +//! @public @memberof QTimeEvt +bool QTimeEvt_rearm(QTimeEvt * const me, + QTimeEvtCtr const nTicks); + +//! @public @memberof QTimeEvt +bool QTimeEvt_wasDisarmed(QTimeEvt * const me); + +//! @public @memberof QTimeEvt +QTimeEvtCtr QTimeEvt_currCtr(QTimeEvt const * const me); + +//! @static @private @memberof QTimeEvt +void QTimeEvt_tick_( + uint_fast8_t const tickRate, + void const * const sender); + +// private: + +#ifdef Q_UTEST +//! @static @private @memberof QTimeEvt +void QTimeEvt_tick1_( + uint_fast8_t const tickRate, + void const * const sender); +#endif // def Q_UTEST + +// public: + +//! @static @public @memberof QTimeEvt +bool QTimeEvt_noActive(uint_fast8_t const tickRate); +//$enddecl${QF::QTimeEvt} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +//$declare${QF::QTicker} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${QF::QTicker} ............................................................. +//! @class QTicker +// @extends QActive +typedef struct { +// protected: + QActive super; +} QTicker; + +// public: + +//! @public @memberof QTicker +void QTicker_ctor(QTicker * const me, + uint_fast8_t const tickRate); + +// private: + +//! @private @memberof QTicker +void QTicker_init_( + QAsm * const me, + void const * const par, + uint_fast8_t const qs_id); + +//! @private @memberof QTicker +void QTicker_dispatch_( + QAsm * const me, + QEvt const * const e, + uint_fast8_t const qs_id); + +//! @private @memberof QTicker +void QTicker_trig_( + QActive * const me, + void const * const sender); +//$enddecl${QF::QTicker} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +//$declare${QF::QF-base} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${QF::QF-base::init} ....................................................... +//! @static @public @memberof QF +void QF_init(void); + +//${QF::QF-base::stop} ....................................................... +//! @static @public @memberof QF +void QF_stop(void); + +//${QF::QF-base::run} ........................................................ +//! @static @public @memberof QF +int_t QF_run(void); + +//${QF::QF-base::getQueueMin} ................................................ +//! @static @public @memberof QF +uint_fast16_t QF_getQueueMin(uint_fast8_t const prio); + +//${QF::QF-base::onStartup} .................................................. +//! @static @public @memberof QF +void QF_onStartup(void); + +//${QF::QF-base::onCleanup} .................................................. +//! @static @public @memberof QF +void QF_onCleanup(void); + +//${QF::QF-base::onContextSw} ................................................ +#ifdef QF_ON_CONTEXT_SW +//! @static @public @memberof QF +void QF_onContextSw( + QActive * prev, + QActive * next); +#endif // def QF_ON_CONTEXT_SW +//$enddecl${QF::QF-base} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +//$declare${QF::QF-dyn} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${QF::QF-dyn::poolInit} .................................................... +//! @static @public @memberof QF +void QF_poolInit( + void * const poolSto, + uint_fast32_t const poolSize, + uint_fast16_t const evtSize); + +//${QF::QF-dyn::poolGetMaxBlockSize} ......................................... +//! @static @public @memberof QF +uint_fast16_t QF_poolGetMaxBlockSize(void); + +//${QF::QF-dyn::getPoolMin} .................................................. +//! @static @public @memberof QF +uint_fast16_t QF_getPoolMin(uint_fast8_t const poolId); + +//${QF::QF-dyn::newX_} ....................................................... +//! @static @private @memberof QF +QEvt * QF_newX_( + uint_fast16_t const evtSize, + uint_fast16_t const margin, + enum_t const sig); + +//${QF::QF-dyn::gc} .......................................................... +//! @static @public @memberof QF +void QF_gc(QEvt const * const e); + +//${QF::QF-dyn::newRef_} ..................................................... +//! @static @private @memberof QF +QEvt const * QF_newRef_( + QEvt const * const e, + void const * const evtRef); + +//${QF::QF-dyn::deleteRef_} .................................................. +//! @static @private @memberof QF +void QF_deleteRef_(void const * const evtRef); + +//${QF::QF-dyn::gcFromISR} ................................................... +//! @static @public @memberof QF +void QF_gcFromISR(QEvt const * const e); +//$enddecl${QF::QF-dyn} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +//$declare${QF-macros} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${QF-macros::QF_NO_MARGIN} ................................................. +#define QF_NO_MARGIN ((uint_fast16_t)0xFFFFU) + +//${QF-macros::Q_PRIO} ....................................................... +#define Q_PRIO(prio_, pthre_) ((QPrioSpec)((prio_) | ((pthre_) << 8U))) + +//${QF-macros::Q_NEW} ........................................................ +#ifndef QEVT_DYN_CTOR +#define Q_NEW(evtT_, sig_) ((evtT_ *)QF_newX_((uint_fast16_t)sizeof(evtT_), \ + QF_NO_MARGIN, (enum_t)(sig_))) +#endif // ndef QEVT_DYN_CTOR + +//${QF-macros::Q_NEW} ........................................................ +#ifdef QEVT_DYN_CTOR +#define Q_NEW(evtT_, sig_, ...) \ + (evtT_##_ctor((evtT_ *)QF_newX_((uint_fast16_t)sizeof(evtT_), \ + QF_NO_MARGIN, (sig_)), __VA_ARGS__)) +#endif // def QEVT_DYN_CTOR + +//${QF-macros::Q_NEW_X} ...................................................... +#ifndef QEVT_DYN_CTOR +#define Q_NEW_X(evtT_, margin_, sig_) \ + (evtT_ *)QF_newX_((uint_fast16_t)sizeof(evtT_), \ + (margin_), (enum_t)(sig_))) +#endif // ndef QEVT_DYN_CTOR + +//${QF-macros::Q_NEW_X} ...................................................... +#ifdef QEVT_DYN_CTOR +#define Q_NEW_X(evtT_, margin_, sig_, ...) \ + (evtT_##_ctor((evtT_ *)QF_newX_((uint_fast16_t)sizeof(evtT_), \ + (margin_), (sig_)), __VA_ARGS__)) +#endif // def QEVT_DYN_CTOR + +//${QF-macros::Q_NEW_REF} .................................................... +#define Q_NEW_REF(evtRef_, evtT_) \ + ((evtRef_) = (evtT_ const *)QF_newRef_(e, (evtRef_))) + +//${QF-macros::Q_DELETE_REF} ................................................. +#define Q_DELETE_REF(evtRef_) do { \ + QF_deleteRef_((evtRef_)); \ + (evtRef_) = (void *)0; \ +} while (false) + +//${QF-macros::QACTIVE_START} ................................................ +#define QACTIVE_START(me_, prioSpec_, qSto_, qLen_, stkSto_, stkSize_, par_) \ + (QActive_start_((QActive *)(me_), (prioSpec_), \ + (qSto_), (qLen_), (stkSto_), (stkSize_), (par_))) + +//${QF-macros::QACTIVE_POST} ................................................. +#ifdef Q_SPY +#define QACTIVE_POST(me_, e_, sender_) \ + ((void)QActive_post_((me_), (e_), QF_NO_MARGIN, (sender_))) +#endif // def Q_SPY + +//${QF-macros::QACTIVE_POST} ................................................. +#ifndef Q_SPY +#define QACTIVE_POST(me_, e_, dummy) \ + ((void)QActive_post_((me_), (e_), QF_NO_MARGIN, (void *)0)) +#endif // ndef Q_SPY + +//${QF-macros::QACTIVE_POST_X} ............................................... +#ifdef Q_SPY +#define QACTIVE_POST_X(me_, e_, margin_, sender_) \ + (QActive_post_((me_), (e_), (margin_), (sender_))) +#endif // def Q_SPY + +//${QF-macros::QACTIVE_POST_X} ............................................... +#ifndef Q_SPY +#define QACTIVE_POST_X(me_, e_, margin_, dummy) \ + (QActive_post_((me_), (e_), (margin_), (void *)0)) +#endif // ndef Q_SPY + +//${QF-macros::QACTIVE_POST_LIFO} ............................................ +#define QACTIVE_POST_LIFO(me_, e_) \ + (QActive_postLIFO_((me_), (e_))) + +//${QF-macros::QACTIVE_PUBLISH} .............................................. +#ifdef Q_SPY +#define QACTIVE_PUBLISH(e_, sender_) \ + (QActive_publish_((e_), (void const *)(sender_), (sender_)->prio)) +#endif // def Q_SPY + +//${QF-macros::QACTIVE_PUBLISH} .............................................. +#ifndef Q_SPY +#define QACTIVE_PUBLISH(e_, dummy) (QActive_publish_((e_), (void *)0, 0U)) +#endif // ndef Q_SPY + +//${QF-macros::QTIMEEVT_TICK_X} .............................................. +#ifdef Q_SPY +#define QTIMEEVT_TICK_X(tickRate_, sender_) (QTimeEvt_tick_((tickRate_), (sender_))) +#endif // def Q_SPY + +//${QF-macros::QTIMEEVT_TICK_X} .............................................. +#ifndef Q_SPY +#define QTIMEEVT_TICK_X(tickRate_, dummy) (QTimeEvt_tick_((tickRate_), (void *)0)) +#endif // ndef Q_SPY + +//${QF-macros::QTIMEEVT_TICK} ................................................ +#define QTIMEEVT_TICK(sender_) QTIMEEVT_TICK_X(0U, (sender_)) + +//${QF-macros::QTICKER_TRIG} ................................................. +#ifdef Q_SPY +#define QTICKER_TRIG(ticker_, sender_) (QTicker_trig_((ticker_), (sender_))) +#endif // def Q_SPY + +//${QF-macros::QTICKER_TRIG} ................................................. +#ifndef Q_SPY +#define QTICKER_TRIG(ticker_, sender_) (QTicker_trig_((ticker_), (void *)0)) +#endif // ndef Q_SPY + +//${QF-macros::QF_CRIT_EXIT_NOP} ............................................. +#ifndef QF_CRIT_EXIT_NOP +#define QF_CRIT_EXIT_NOP() ((void)0) +#endif // ndef QF_CRIT_EXIT_NOP + +//${QF-macros::QF_TICK_X} .................................................... +#define QF_TICK_X(tickRate_, sender_) QTIMEEVT_TICK_X((tickRate_), (sender_)) + +//${QF-macros::QF_TICK} ...................................................... +#define QF_TICK(sender_) QTIMEEVT_TICK(sender_) + +//${QF-macros::QF_PUBLISH} ................................................... +#define QF_PUBLISH(e_, sender_) QACTIVE_PUBLISH((e_), (sender_)) + +//${QF-macros::QF_MEM_SYS} ................................................... +#ifndef QF_MEM_SYS +#define QF_MEM_SYS() ((void)0) +#endif // ndef QF_MEM_SYS + +//${QF-macros::QF_MEM_APP} ................................................... +#ifndef QF_MEM_APP +#define QF_MEM_APP() ((void)0) +#endif // ndef QF_MEM_APP +//$enddecl${QF-macros} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +#endif // QP_H_ diff --git a/include/qp_pkg.h b/include/qp_pkg.h new file mode 100644 index 00000000..9dc4c0b6 --- /dev/null +++ b/include/qp_pkg.h @@ -0,0 +1,99 @@ +//$file${include::qp_pkg.h} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// +// Model: qpc.qm +// File: ${include::qp_pkg.h} +// +// This code has been generated by QM 5.3.0 . +// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. +// +// This code is covered by the following QP license: +// License # : LicenseRef-QL-dual +// Issued to : Any user of the QP/C real-time embedded framework +// Framework(s) : qpc +// Support ends : 2024-12-31 +// License scope: +// +// Copyright (C) 2005 Quantum Leaps, LLC . +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +// +//$endhead${include::qp_pkg.h} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +#ifndef QP_PKG_H_ +#define QP_PKG_H_ + +//$declare${QF::QF-pkg} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${QF::QF-pkg::Attr} ........................................................ +//! @class QF_Attr +typedef struct { +// private: + +#if (QF_MAX_EPOOL > 0U) + //! @private @memberof QF_Attr + QF_EPOOL_TYPE_ ePool_[QF_MAX_EPOOL]; +#endif // (QF_MAX_EPOOL > 0U) + +#if (QF_MAX_EPOOL > 0U) + //! @private @memberof QF_Attr + uint_fast8_t maxPool_; +#endif // (QF_MAX_EPOOL > 0U) + +#if (QF_MAX_EPOOL == 0U) + //! @private @memberof QF_Attr + uint8_t dummy; +#endif // (QF_MAX_EPOOL == 0U) +} QF_Attr; + +//${QF::QF-pkg::priv_} ....................................................... +//! @static @private @memberof QF +extern QF_Attr QF_priv_; + +//${QF::QF-pkg::bzero_} ...................................................... +//! @static @private @memberof QF +void QF_bzero_( + void * const start, + uint_fast16_t const len); +//$enddecl${QF::QF-pkg} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +// Bitmasks are for the QTimeEvt::refCtr_ attribute (inherited from ::QEvt). +// In ::QTimeEvt this attribute is NOT used for reference counting. +#define QTE_IS_LINKED (1U << 7U) +#define QTE_WAS_DISARMED (1U << 6U) +#define QTE_TICK_RATE 0x0FU + +//! @private @memberof QEvt +static inline void QEvt_refCtr_inc_(QEvt const *me) { + ++((QEvt *)me)->refCtr_; +} + +//! @private @memberof QEvt +static inline void QEvt_refCtr_dec_(QEvt const *me) { + --((QEvt *)me)->refCtr_; +} + +#define QACTIVE_CAST_(ptr_) ((QActive *)(ptr_)) +#define Q_UINTPTR_CAST_(ptr_) ((uintptr_t)(ptr_)) + +#endif // QP_PKG_H_ diff --git a/include/qpc.h b/include/qpc.h index f9028c52..2d89f1c2 100644 --- a/include/qpc.h +++ b/include/qpc.h @@ -1,133 +1,175 @@ -/*$file${include::qpc.h} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* -* Model: qpc.qm -* File: ${include::qpc.h} -* -* This code has been generated by QM 5.2.4 . -* DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. -* -* This code is covered by the following QP license: -* License # : LicenseRef-QL-dual -* Issued to : Any user of the QP/C real-time embedded framework -* Framework(s) : qpc -* Support ends : 2023-12-31 -* License scope: -* -* Copyright (C) 2005 Quantum Leaps, LLC . -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -*/ -/*$endhead${include::qpc.h} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*! @file -* @brief QP/C public interface including backwards-compatibility layer -* @details -* This header file must be included directly or indirectly -* in all application modules (*.c files) that use QP/C. -*/ -#ifndef QP_INC_QPC_H_ -#define QP_INC_QPC_H_ +//$file${include::qpc.h} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// +// Model: qpc.qm +// File: ${include::qpc.h} +// +// This code has been generated by QM 5.3.0 . +// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. +// +// This code is covered by the following QP license: +// License # : LicenseRef-QL-dual +// Issued to : Any user of the QP/C real-time embedded framework +// Framework(s) : qpc +// Support ends : 2024-12-31 +// License scope: +// +// Copyright (C) 2005 Quantum Leaps, LLC . +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +// +//$endhead${include::qpc.h} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +#ifndef QPC_H_ +#define QPC_H_ #ifdef __cplusplus extern "C" { #endif -/*==========================================================================*/ -#include "qf_port.h" /* QF/C port from the port directory */ -#include "qassert.h" /* QP embedded systems-friendly assertions */ - -#ifdef Q_SPY /* software tracing enabled? */ - #include "qs_port.h" /* QS/C port from the port directory */ +//============================================================================ +#include "qp_port.h" // QP port from the port directory +#include "qsafe.h" // QP Functional Safety (FuSa) Subsystem +#ifdef Q_SPY // software tracing enabled? + #include "qs_port.h" // QS/C port from the port directory #else - #include "qs_dummy.h" /* QS/C dummy (inactive) interface */ + #include "qs_dummy.h" // QS/C dummy (inactive) interface #endif -/*==========================================================================*/ - +//============================================================================ #ifndef QP_API_VERSION -/*! Specifies the backwards compatibility with the QP/C API version. -* @details -* For example, QP_API_VERSION==691 will cause generating the compatibility -* layer with QP/C version 6.9.1 and newer, but not older than 6.9.1. -* QP_API_VERSION==0 causes generation of the maximum currently supported -* backwards compatibility. This is the default.
-*
-* Conversely, QP_API_VERSION==9999 means that no compatibility layer should -* be generated. This setting is useful for checking if an application -* complies with the latest QP/C API. -*/ #define QP_API_VERSION 0 -#endif /* #ifndef QP_API_VERSION */ +#endif // #ifndef QP_API_VERSION -/*==========================================================================*/ -/* QP API compatibility layer... */ +//============================================================================ +// QP API compatibility layer... -#if (QP_API_VERSION < 700) +#if (QP_API_VERSION < 730) -/*! @deprecated plain 'char' is no longer forbidden in MISRA-C 2012 */ +//! @deprecated plain 'char' is no longer forbidden in MISRA-C:2023 typedef char char_t; -/*==========================================================================*/ +//! @deprecated assertion failure handler +//! Use Q_onError() instead. +#define Q_onAssert(module_, id_) Q_onError(module_, id_) + +//! @deprecated #Q_NASSERT preprocessor switch to disable QP assertions +#ifdef Q_NASSERT + + // #Q_UNSAFE now replaces the functionality of Q_NASSERT + #define Q_UNSAFE + + //! @deprecated general purpose assertion with user-specified ID + //! number that **always** evaluates the `expr_` expression. + #define Q_ALLEGE_ID(id_, expr_) ((void)(expr_)) + +#else // QP FuSa Subsystem enabled + + //! @deprecated general purpose assertion with user-specified ID + //! number that **always** evaluates the `expr_` expression. + //! @note + //! The use of this macro is no longer recommended. + #define Q_ALLEGE_ID(id_, expr_) if (!(expr_)) { \ + QF_CRIT_STAT \ + QF_CRIT_ENTRY(); \ + Q_onError(&Q_this_module_[0], (id_)); \ + QF_CRIT_EXIT(); \ + } else ((void)0) + +#endif + +//! @deprecated general purpose assertion without ID number +//! that **always** evaluates the `expr_` expression. +//! Instead of ID number, this macro is based on the standard +//! `__LINE__` macro. +//! +//! @note The use of this macro is no longer recommended. +#define Q_ALLEGE(expr_) Q_ALLEGE_ID(__LINE__, (expr_)) + +//! Static (compile-time) assertion. +//! @deprecated +//! Use Q_ASSERT_STATIC() or better yet `_Static_assert()` instead. +#define Q_ASSERT_COMPILE(expr_) Q_ASSERT_STATIC(expr_) + +//! @static @public @memberof QF +//! @deprecated +static inline void QF_psInit( + QSubscrList * const subscrSto, + enum_t const maxSignal) +{ + QActive_psInit(subscrSto, maxSignal); +} + +//! @deprecated instead use: QASM_INIT() +#define QHSM_INIT(me_, par_, qs_id_) QASM_INIT((me_), (par_), (qs_id_)) + +//! @deprecated instead use: QASM_DISPATCH() +#define QHSM_DISPATCH(me_, e_, qs_id_) QASM_DISPATCH((me_), (e_), (qs_id_)) + +//============================================================================ #if (QP_API_VERSION < 691) -/*! @deprecated enable the QS global filter */ +//! @deprecated enable the QS global filter #define QS_FILTER_ON(rec_) QS_GLB_FILTER((rec_)) -/*! @deprecated disable the QS global filter */ +//! @deprecated disable the QS global filter #define QS_FILTER_OFF(rec_) QS_GLB_FILTER(-(rec_)) -/*! @deprecated enable the QS local filter for SM (state machine) object */ +//! @deprecated enable the QS local filter for SM (state machine) object #define QS_FILTER_SM_OBJ(obj_) ((void)0) -/*! @deprecated enable the QS local filter for AO (active objects) */ +//! @deprecated enable the QS local filter for AO (active objects) #define QS_FILTER_AO_OBJ(obj_) ((void)0) -/*! @deprecated enable the QS local filter for MP (memory pool) object */ +//! @deprecated enable the QS local filter for MP (memory pool) object #define QS_FILTER_MP_OBJ(obj_) ((void)0) -/*! @deprecated enable the QS local filter for EQ (event queue) object */ +//! @deprecated enable the QS local filter for EQ (event queue) object #define QS_FILTER_EQ_OBJ(obj_) ((void)0) -/*! @deprecated enable the QS local filter for TE (time event) object */ +//! @deprecated enable the QS local filter for TE (time event) object #define QS_FILTER_TE_OBJ(obj_) ((void)0) #ifdef Q_SPY -/*! @deprecated local Filter for a generic application object `obj_`. */ -#define QS_FILTER_AP_OBJ(obj_) (QS_priv_.locFilter_AP = (obj_)) +//! @deprecated local Filter for a generic application object `obj_`. +#define QS_FILTER_AP_OBJ(obj_) (QS_filt_.loc_AP = (obj_)) -/*! @deprecated begin of a user QS record, instead use QS_BEGIN_ID() */ -#define QS_BEGIN(rec_, obj_) \ - if (((QS_priv_.glbFilter[(uint_fast8_t)(rec_) >> 3U] \ - & (1U << ((uint_fast8_t)(rec_) & 7U))) != 0U) \ - && ((QS_priv_.locFilter_AP == (void *)0) \ - || (QS_priv_.locFilter_AP == (obj_)))) \ - { \ - QS_CRIT_STAT_ \ - QS_CRIT_E_(); \ - QS_beginRec_((uint_fast8_t)(rec_)); \ +//! @deprecated begin of a user QS record, instead use QS_BEGIN_ID() +#define QS_BEGIN(rec_, obj_) \ + if (((QS_filt_.glb[(uint_fast8_t)(rec_) >> 3U] \ + & (1U << ((uint_fast8_t)(rec_) & 7U))) != 0U) \ + && ((QS_priv_.locFilter_AP == (void *)0) \ + || (QS_priv_.locFilter_AP == (obj_)))) \ + { \ + QS_CRIT_STAT \ + QS_CRIT_ENTRY(); \ + QS_beginRec_((uint_fast8_t)(rec_)); \ QS_TIME_PRE_(); { -/*! @deprecated Output formatted uint32_t to the QS record */ +//! @deprecated Output formatted uint32_t to the QS record #define QS_U32_HEX(width_, data_) \ (QS_u32_fmt_((uint8_t)(((width_) << 4)) | QS_HEX_FMT, (data_))) @@ -139,31 +181,29 @@ typedef char char_t; #endif -/*==========================================================================*/ +//============================================================================ #if (QP_API_VERSION < 660) -/*! @deprecated casting to QXThreadHandler -* instead use: the new signature of QXThreadHandler and don't cast -*/ +//! @deprecated casting to QXThreadHandler +//! instead use: the new signature of QXThreadHandler and don't cast #define Q_XTHREAD_CAST(handler_) ((QXThreadHandler)(handler_)) -/*==========================================================================*/ +//============================================================================ #if (QP_API_VERSION < 580) -/*! @deprecated call to the QMSM_INIT() operation; instead use: QHSM_INIT() */ -#define QMSM_INIT(me_, e_) QHSM_INIT((me_), (e_)) +//! @deprecated instead use: QASM_INIT() +#define QMSM_INIT(me_, par_, qs_id_) QASM_INIT((me_), (par_), (qs_id_)) -/*! @deprecated call to the QMSM_DISPATCH() operation; -* instead use: QHSM_DISPATCH() */ -#define QMSM_DISPATCH(me_, e_) QHSM_DISPATCH((me_), (e_), 0U) +//! @deprecated instead use: QASM_DISPATCH() +#define QMSM_DISPATCH(me_, e_, qs_id_) QASM_DISPATCH((me_), (e_), (qs_id_)) -#endif /* QP_API_VERSION < 580 */ -#endif /* QP_API_VERSION < 660 */ -#endif /* QP_API_VERSION < 691 */ -#endif /* QP_API_VERSION < 700 */ +#endif // QP_API_VERSION < 580 +#endif // QP_API_VERSION < 660 +#endif // QP_API_VERSION < 691 +#endif // QP_API_VERSION < 700 #ifdef __cplusplus } #endif -#endif /* QP_INC_QPC_H_ */ +#endif // QPC_H_ diff --git a/include/qs.h b/include/qs.h index f3361b9c..d4921857 100644 --- a/include/qs.h +++ b/include/qs.h @@ -1,1704 +1,975 @@ -/*$file${include::qs.h} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* -* Model: qpc.qm -* File: ${include::qs.h} -* -* This code has been generated by QM 5.2.4 . -* DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. -* -* This code is covered by the following QP license: -* License # : LicenseRef-QL-dual -* Issued to : Any user of the QP/C real-time embedded framework -* Framework(s) : qpc -* Support ends : 2023-12-31 -* License scope: -* -* Copyright (C) 2005 Quantum Leaps, LLC . -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -*/ -/*$endhead${include::qs.h} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*! @file -* @brief QS/C platform-independent public interface. -*/ -#ifndef QP_INC_QS_H_ -#define QP_INC_QS_H_ +//$file${include::qs.h} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// +// Model: qpc.qm +// File: ${include::qs.h} +// +// This code has been generated by QM 5.3.0 . +// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. +// +// This code is covered by the following QP license: +// License # : LicenseRef-QL-dual +// Issued to : Any user of the QP/C real-time embedded framework +// Framework(s) : qpc +// Support ends : 2024-12-31 +// License scope: +// +// Copyright (C) 2005 Quantum Leaps, LLC . +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +// +//$endhead${include::qs.h} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +#ifndef QS_H_ +#define QS_H_ #ifndef Q_SPY - #error "Q_SPY must be defined to include qs.h" +#error "Q_SPY must be defined to include qs.h" #endif -/*==========================================================================*/ -/*$declare${QS-config} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//============================================================================ +//! @cond INTERNAL -/*${QS-config::QS_CTR_SIZE} ................................................*/ #ifndef QS_CTR_SIZE -/*! The size [bytes] of the internal QS buffer-counters. Valid values: 2U or 4U; -* default 2U. -* -* @details -* This macro can be defined in the QS port file (qs_port.h) to -* configure the ::QSCtr type. Here the macro is not defined so the -* default of 2 byte is chosen. -*/ #define QS_CTR_SIZE 2U -#endif /* ndef QS_CTR_SIZE */ +#endif -/*${QS-config::QS_CTR_SIZE defined incorrectly,~} ..........................*/ -#if (QS_CTR_SIZE != 2U) && (QS_CTR_SIZE != 4U) -#error QS_CTR_SIZE defined incorrectly, expected 2U or 4U; -#endif /* (QS_CTR_SIZE != 2U) && (QS_CTR_SIZE != 4U) */ - -/*${QS-config::QS_TIME_SIZE} ...............................................*/ #ifndef QS_TIME_SIZE -/*! The size [bytes] of the QS time stamp. Valid values: 1U, 2U, or 4U; -* default 4U. -* -* @details -* This macro can be defined in the QS port file (qs_port.h) to -* configure the ::QSTimeCtr type. Here the macro is not defined so the -* default of 4 byte is chosen. -*/ #define QS_TIME_SIZE 4U -#endif /* ndef QS_TIME_SIZE */ +#endif -/*${QS-config::QS_TIME_SIZE defined incorrectly~} ..........................*/ -#if (QS_TIME_SIZE != 1U) && (QS_TIME_SIZE != 2U) && (QS_TIME_SIZE != 4U) -#error QS_TIME_SIZE defined incorrectly, expected 1U, 2U, or 4U; -#endif /* (QS_TIME_SIZE != 1U) && (QS_TIME_SIZE != 2U) && (QS_TIME_SIZE != 4U) */ -/*$enddecl${QS-config} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//! @endcond +//============================================================================ -/*==========================================================================*/ -/*$declare${QS} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//$declare${QS::types} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/*${QS::QSCtr} .............................................................*/ -#if (QS_CTR_SIZE == 2U) -/*! QS ring buffer counter and offset type */ -typedef uint_fast16_t QSCtr; -#endif /* (QS_CTR_SIZE == 2U) */ +//${QS::types::QS} ........................................................... +//! @class QS +typedef struct QS { + //! @cond INTERNAL + uint8_t dummy; + //! @endcond +} QS; -/*${QS::QSCtr} .............................................................*/ -#if (QS_CTR_SIZE == 4U) -typedef uint_fast32_t QSCtr; -#endif /* (QS_CTR_SIZE == 4U) */ - -/*${QS::QSTimeCtr} .........................................................*/ -#if (QS_TIME_SIZE == 4U) -/*! QS time stamp type, which determines the dynamic range of QS time stamps */ -typedef uint32_t QSTimeCtr; -#endif /* (QS_TIME_SIZE == 4U) */ - -/*${QS::QSTimeCtr} .........................................................*/ -#if (QS_TIME_SIZE == 2U) -typedef uint16_t QSTimeCtr; -#endif /* (QS_TIME_SIZE == 2U) */ - -/*${QS::QSTimeCtr} .........................................................*/ -#if (QS_TIME_SIZE == 1U) -typedef uint8_t QSTimeCtr; -#endif /* (QS_TIME_SIZE == 1U) */ - -/*${QS::QSFun} .............................................................*/ -#if (QS_FUN_PTR_SIZE == 4U) -/*! QS function pointer type (for serializing function pointers) */ -typedef uint32_t QSFun; -#endif /* (QS_FUN_PTR_SIZE == 4U) */ - -/*${QS::QSFun} .............................................................*/ -#if (QS_FUN_PTR_SIZE == 8U) -typedef uint64_t QSFun; -#endif /* (QS_FUN_PTR_SIZE == 8U) */ - -/*${QS::QSFun} .............................................................*/ -#if (QS_FUN_PTR_SIZE == 2U) -typedef uint16_t QSFun; -#endif /* (QS_FUN_PTR_SIZE == 2U) */ - -/*${QS::QSFun} .............................................................*/ -#if (QS_FUN_PTR_SIZE == 1U) -typedef uint8_t QSFun; -#endif /* (QS_FUN_PTR_SIZE == 1U) */ - -/*${QS::QSpyPre} ...........................................................*/ -/*! QS pre-defined record types (TX channel) -* @static @public @memberof QS_tx -* -* @details -* This enumeration specifies the record types used in the QP components. -* You can specify your own record types starting from ::QS_USER offset. -* Currently, the maximum of all records cannot exceed 125. -* -* @note -* The QS records labeled as "not maskable" are always enabled and cannot -* be turend off with the QS_GLB_FILTER() macro. Other QS trace records -* can be disabled by means of the "global filters" -* -* @sa QS_GLB_FILTER() macro -*/ +//${QS::types::QSpyPre} ...................................................... +//! @static @public @memberof QS +//! pre-defined QS record IDs enum QSpyPre { - /* [0] QS session (not maskable) */ - QS_EMPTY, /*!< QS record for cleanly starting a session */ + // [0] QS session (not maskable) + QS_EMPTY, //!< QS record for cleanly starting a session - /* [1] SM records */ - QS_QEP_STATE_ENTRY, /*!< a state was entered */ - QS_QEP_STATE_EXIT, /*!< a state was exited */ - QS_QEP_STATE_INIT, /*!< an initial transition was taken in a state */ - QS_QEP_INIT_TRAN, /*!< the top-most initial transition was taken */ - QS_QEP_INTERN_TRAN, /*!< an internal transition was taken */ - QS_QEP_TRAN, /*!< a regular transition was taken */ - QS_QEP_IGNORED, /*!< an event was ignored (silently discarded) */ - QS_QEP_DISPATCH, /*!< an event was dispatched (begin of RTC step) */ - QS_QEP_UNHANDLED, /*!< an event was un-handled due to a guard */ + // [1] SM records + QS_QEP_STATE_ENTRY, //!< a state was entered + QS_QEP_STATE_EXIT, //!< a state was exited + QS_QEP_STATE_INIT, //!< an initial transition was taken in a state + QS_QEP_INIT_TRAN, //!< the top-most initial transition was taken + QS_QEP_INTERN_TRAN, //!< an internal transition was taken + QS_QEP_TRAN, //!< a regular transition was taken + QS_QEP_IGNORED, //!< an event was ignored (silently discarded) + QS_QEP_DISPATCH, //!< an event was dispatched (begin of RTC step) + QS_QEP_UNHANDLED, //!< an event was un-handled due to a guard - /* [10] Active Object (AO) records */ - QS_QF_ACTIVE_DEFER, /*!< AO deferred an event */ - QS_QF_ACTIVE_RECALL, /*!< AO recalled an event */ - QS_QF_ACTIVE_SUBSCRIBE, /*!< an AO subscribed to an event */ - QS_QF_ACTIVE_UNSUBSCRIBE, /*!< an AO unsubscribed to an event */ - QS_QF_ACTIVE_POST, /*!< an event was posted (FIFO) directly to AO */ - QS_QF_ACTIVE_POST_LIFO, /*!< an event was posted (LIFO) directly to AO */ - QS_QF_ACTIVE_GET, /*!< AO got an event and its queue is not empty */ - QS_QF_ACTIVE_GET_LAST,/*!< AO got an event and its queue is empty */ - QS_QF_ACTIVE_RECALL_ATTEMPT, /*!< AO attempted to recall an event */ + // [10] Active Object (AO) records + QS_QF_ACTIVE_DEFER, //!< AO deferred an event + QS_QF_ACTIVE_RECALL, //!< AO recalled an event + QS_QF_ACTIVE_SUBSCRIBE, //!< an AO subscribed to an event + QS_QF_ACTIVE_UNSUBSCRIBE, //!< an AO unsubscribed to an event + QS_QF_ACTIVE_POST, //!< an event was posted (FIFO) directly to AO + QS_QF_ACTIVE_POST_LIFO, //!< an event was posted (LIFO) directly to AO + QS_QF_ACTIVE_GET, //!< AO got an event and its queue is not empty + QS_QF_ACTIVE_GET_LAST,//!< AO got an event and its queue is empty + QS_QF_ACTIVE_RECALL_ATTEMPT, //!< AO attempted to recall an event - /* [19] Event Queue (EQ) records */ - QS_QF_EQUEUE_POST, /*!< an event was posted (FIFO) to a raw queue */ - QS_QF_EQUEUE_POST_LIFO, /*!< an event was posted (LIFO) to a raw queue */ - QS_QF_EQUEUE_GET, /*!< get an event and queue still not empty */ - QS_QF_EQUEUE_GET_LAST,/*!< get the last event from the queue */ + // [19] Event Queue (EQ) records + QS_QF_EQUEUE_POST, //!< an event was posted (FIFO) to a raw queue + QS_QF_EQUEUE_POST_LIFO, //!< an event was posted (LIFO) to a raw queue + QS_QF_EQUEUE_GET, //!< get an event and queue still not empty + QS_QF_EQUEUE_GET_LAST,//!< get the last event from the queue - /* [23] Framework (QF) records */ - QS_QF_NEW_ATTEMPT, /*!< an attempt to allocate an event failed */ + // [23] Framework (QF) records + QS_QF_NEW_ATTEMPT, //!< an attempt to allocate an event failed - /* [24] Memory Pool (MP) records */ - QS_QF_MPOOL_GET, /*!< a memory block was removed from memory pool */ - QS_QF_MPOOL_PUT, /*!< a memory block was returned to memory pool */ + // [24] Memory Pool (MP) records + QS_QF_MPOOL_GET, //!< a memory block was removed from memory pool + QS_QF_MPOOL_PUT, //!< a memory block was returned to memory pool - /* [26] Additional Framework (QF) records */ - QS_QF_PUBLISH, /*!< an event was published to active objects */ - QS_QF_NEW_REF, /*!< new event reference was created */ - QS_QF_NEW, /*!< new event was created */ - QS_QF_GC_ATTEMPT, /*!< garbage collection attempt */ - QS_QF_GC, /*!< garbage collection */ - QS_QF_TICK, /*!< QTimeEvt_tick_() was called */ + // [26] Additional Framework (QF) records + QS_QF_PUBLISH, //!< an event was published to active objects + QS_QF_NEW_REF, //!< new event reference was created + QS_QF_NEW, //!< new event was created + QS_QF_GC_ATTEMPT, //!< garbage collection attempt + QS_QF_GC, //!< garbage collection + QS_QF_TICK, //!< QTimeEvt tick was called - /* [32] Time Event (TE) records */ - QS_QF_TIMEEVT_ARM, /*!< a time event was armed */ - QS_QF_TIMEEVT_AUTO_DISARM, /*!< a time event expired and was disarmed */ - QS_QF_TIMEEVT_DISARM_ATTEMPT,/*!< attempt to disarm a disarmed QTimeEvt */ - QS_QF_TIMEEVT_DISARM, /*!< true disarming of an armed time event */ - QS_QF_TIMEEVT_REARM, /*!< rearming of a time event */ - QS_QF_TIMEEVT_POST, /*!< a time event posted itself directly to an AO */ + // [32] Time Event (TE) records + QS_QF_TIMEEVT_ARM, //!< a time event was armed + QS_QF_TIMEEVT_AUTO_DISARM, //!< a time event expired and was disarmed + QS_QF_TIMEEVT_DISARM_ATTEMPT,//!< attempt to disarm a disarmed QTimeEvt + QS_QF_TIMEEVT_DISARM, //!< true disarming of an armed time event + QS_QF_TIMEEVT_REARM, //!< rearming of a time event + QS_QF_TIMEEVT_POST, //!< a time event posted itself directly to an AO - /* [38] Additional Framework (QF) records */ - QS_QF_DELETE_REF, /*!< an event reference is about to be deleted */ - QS_QF_CRIT_ENTRY, /*!< critical section was entered */ - QS_QF_CRIT_EXIT, /*!< critical section was exited */ - QS_QF_ISR_ENTRY, /*!< an ISR was entered */ - QS_QF_ISR_EXIT, /*!< an ISR was exited */ - QS_QF_INT_DISABLE, /*!< interrupts were disabled */ - QS_QF_INT_ENABLE, /*!< interrupts were enabled */ + // [38] Additional Framework (QF) records + QS_QF_DELETE_REF, //!< an event reference is about to be deleted + QS_QF_CRIT_ENTRY, //!< critical section was entered + QS_QF_CRIT_EXIT, //!< critical section was exited + QS_QF_ISR_ENTRY, //!< an ISR was entered + QS_QF_ISR_EXIT, //!< an ISR was exited + QS_QF_INT_DISABLE, //!< interrupts were disabled + QS_QF_INT_ENABLE, //!< interrupts were enabled - /* [45] Additional Active Object (AO) records */ - QS_QF_ACTIVE_POST_ATTEMPT,/*!< attempt to post an evt to AO failed */ + // [45] Additional Active Object (AO) records + QS_QF_ACTIVE_POST_ATTEMPT,//!< attempt to post an evt to AO failed - /* [46] Additional Event Queue (EQ) records */ - QS_QF_EQUEUE_POST_ATTEMPT,/*!< attempt to post evt to QEQueue failed */ + // [46] Additional Event Queue (EQ) records + QS_QF_EQUEUE_POST_ATTEMPT,//!< attempt to post evt to QEQueue failed - /* [47] Additional Memory Pool (MP) records */ - QS_QF_MPOOL_GET_ATTEMPT, /*!< attempt to get a memory block failed */ + // [47] Additional Memory Pool (MP) records + QS_QF_MPOOL_GET_ATTEMPT, //!< attempt to get a memory block failed - /* [48] Scheduler (SC) records */ - QS_SCHED_PREEMPT, /*!< scheduler asynchronously preempted a task */ - QS_SCHED_RESTORE, /*!< scheduler restored preempted task */ - QS_SCHED_LOCK, /*!< scheduler was locked */ - QS_SCHED_UNLOCK, /*!< scheduler was unlocked */ - QS_SCHED_NEXT, /*!< scheduler started new task */ - QS_SCHED_IDLE, /*!< scheduler restored the idle task */ + // [48] Scheduler (SC) records + QS_SCHED_PREEMPT, //!< scheduler asynchronously preempted a task + QS_SCHED_RESTORE, //!< scheduler restored preempted task + QS_SCHED_LOCK, //!< scheduler was locked + QS_SCHED_UNLOCK, //!< scheduler was unlocked + QS_SCHED_NEXT, //!< scheduler started next task + QS_SCHED_IDLE, //!< scheduler restored the idle task - /* [54] Miscellaneous QS records (not maskable) */ - QS_ENUM_DICT, /*!< enumeration dictionary entry */ + // [54] Miscellaneous QS records (not maskable) + QS_ENUM_DICT, //!< enumeration dictionary entry - /* [55] Additional QEP records */ - QS_QEP_TRAN_HIST, /*!< a tran to history was taken */ - QS_QEP_TRAN_EP, /*!< a tran to entry point into a submachine */ - QS_QEP_TRAN_XP, /*!< a tran to exit point out of a submachine */ + // [55] Additional QEP records + QS_QEP_TRAN_HIST, //!< a tran to history was taken + QS_QEP_TRAN_EP, //!< a tran to entry point into a submachine + QS_QEP_TRAN_XP, //!< a tran to exit point out of a submachine - /* [58] Miscellaneous QS records (not maskable) */ - QS_TEST_PAUSED, /*!< test has been paused */ - QS_TEST_PROBE_GET, /*!< reports that Test-Probe has been used */ - QS_SIG_DICT, /*!< signal dictionary entry */ - QS_OBJ_DICT, /*!< object dictionary entry */ - QS_FUN_DICT, /*!< function dictionary entry */ - QS_USR_DICT, /*!< user QS record dictionary entry */ - QS_TARGET_INFO, /*!< reports the Target information */ - QS_TARGET_DONE, /*!< reports completion of a user callback */ - QS_RX_STATUS, /*!< reports QS data receive status */ - QS_QUERY_DATA, /*!< reports the data from "current object" query */ - QS_PEEK_DATA, /*!< reports the data from the PEEK query */ - QS_ASSERT_FAIL, /*!< assertion failed in the code */ - QS_QF_RUN, /*!< QF_run() was entered */ + // [58] Miscellaneous QS records (not maskable) + QS_TEST_PAUSED, //!< test has been paused + QS_TEST_PROBE_GET, //!< reports that Test-Probe has been used + QS_SIG_DICT, //!< signal dictionary entry + QS_OBJ_DICT, //!< object dictionary entry + QS_FUN_DICT, //!< function dictionary entry + QS_USR_DICT, //!< user QS record dictionary entry + QS_TARGET_INFO, //!< reports the Target information + QS_TARGET_DONE, //!< reports completion of a user callback + QS_RX_STATUS, //!< reports QS data receive status + QS_QUERY_DATA, //!< reports the data from "current object" query + QS_PEEK_DATA, //!< reports the data from the PEEK query + QS_ASSERT_FAIL, //!< assertion failed in the code + QS_QF_RUN, //!< QF_run() was entered - /* [71] Semaphore (SEM) records */ - QS_SEM_TAKE, /*!< a semaphore was taken by a thread */ - QS_SEM_BLOCK, /*!< a semaphore blocked a thread */ - QS_SEM_SIGNAL, /*!< a semaphore was signaled */ - QS_SEM_BLOCK_ATTEMPT, /*!< a semaphore blocked was attempted */ + // [71] Semaphore (SEM) records + QS_SEM_TAKE, //!< a semaphore was taken by a thread + QS_SEM_BLOCK, //!< a semaphore blocked a thread + QS_SEM_SIGNAL, //!< a semaphore was signaled + QS_SEM_BLOCK_ATTEMPT, //!< a semaphore blocked was attempted - /* [75] Mutex (MTX) records */ - QS_MTX_LOCK, /*!< a mutex was locked */ - QS_MTX_BLOCK, /*!< a mutex blocked a thread */ - QS_MTX_UNLOCK, /*!< a mutex was unlocked */ - QS_MTX_LOCK_ATTEMPT, /*!< a mutex lock was attempted */ - QS_MTX_BLOCK_ATTEMPT, /*!< a mutex blocking was attempted */ - QS_MTX_UNLOCK_ATTEMPT,/*!< a mutex unlock was attempted */ + // [75] Mutex (MTX) records + QS_MTX_LOCK, //!< a mutex was locked + QS_MTX_BLOCK, //!< a mutex blocked a thread + QS_MTX_UNLOCK, //!< a mutex was unlocked + QS_MTX_LOCK_ATTEMPT, //!< a mutex lock was attempted + QS_MTX_BLOCK_ATTEMPT, //!< a mutex blocking was attempted + QS_MTX_UNLOCK_ATTEMPT,//!< a mutex unlock was attempted - /* [81] */ - QS_PRE_MAX /*!< the number of predefined signals */ + // [81] + QS_PRE_MAX //!< the # predefined signals }; -/*${QS::QSpyGroups} ........................................................*/ -/*! QS record groups for QS_GLB_FILTER() -* @static @public @memberof QS_tx -*/ +//${QS::types::QSpyGroups} ................................................... +//! @static @public @memberof QS +//! QS-TX record groups for QS_GLB_FILTER() enum QSpyGroups { - QS_ALL_RECORDS = 0xF0,/*!< all maskable QS records */ - QS_SM_RECORDS, /*!< State Machine QS records */ - QS_AO_RECORDS, /*!< Active Object QS records */ - QS_EQ_RECORDS, /*!< Event Queues QS records */ - QS_MP_RECORDS, /*!< Memory Pools QS records */ - QS_TE_RECORDS, /*!< Time Events QS records */ - QS_QF_RECORDS, /*!< QF QS records */ - QS_SC_RECORDS, /*!< Scheduler QS records */ - QS_SEM_RECORDS, /*!< Semaphore QS records */ - QS_MTX_RECORDS, /*!< Mutex QS records */ - QS_U0_RECORDS, /*!< User Group 100-104 records */ - QS_U1_RECORDS, /*!< User Group 105-109 records */ - QS_U2_RECORDS, /*!< User Group 110-114 records */ - QS_U3_RECORDS, /*!< User Group 115-119 records */ - QS_U4_RECORDS, /*!< User Group 120-124 records */ - QS_UA_RECORDS /*!< All User records */ + QS_ALL_RECORDS = 0xF0,//!< all maskable QS records + QS_SM_RECORDS, //!< State Machine QS records + QS_AO_RECORDS, //!< Active Object QS records + QS_EQ_RECORDS, //!< Event Queues QS records + QS_MP_RECORDS, //!< Memory Pools QS records + QS_TE_RECORDS, //!< Time Events QS records + QS_QF_RECORDS, //!< QF QS records + QS_SC_RECORDS, //!< Scheduler QS records + QS_SEM_RECORDS, //!< Semaphore QS records + QS_MTX_RECORDS, //!< Mutex QS records + QS_U0_RECORDS, //!< User Group 100-104 records + QS_U1_RECORDS, //!< User Group 105-109 records + QS_U2_RECORDS, //!< User Group 110-114 records + QS_U3_RECORDS, //!< User Group 115-119 records + QS_U4_RECORDS, //!< User Group 120-124 records + QS_UA_RECORDS //!< All User records }; -/*${QS::QSpyUserOffsets} ...................................................*/ -/*! QS user record group offsets for QS_GLB_FILTER() -* @static @public @memberof QS_tx -*/ +//${QS::types::QSpyUserOffsets} .............................................. +//! @static @public @memberof QS +//! QS user record group offsets for QS_GLB_FILTER() enum QSpyUserOffsets { - QS_USER = 100, /*!< the first record available to QS users */ - QS_USER0 = (enum_t)QS_USER, /*!< offset for User Group 0 */ - QS_USER1 = (enum_t)QS_USER0 + 5, /*!< offset for User Group 1 */ - QS_USER2 = (enum_t)QS_USER1 + 5, /*!< offset for User Group 2 */ - QS_USER3 = (enum_t)QS_USER2 + 5, /*!< offset for User Group 3 */ - QS_USER4 = (enum_t)QS_USER3 + 5 /*!< offset for User Group 4 */ + QS_USER = 100, //!< the first record available to QS users + QS_USER0 = QS_USER, //!< offset for User Group 0 + QS_USER1 = (enum_t)QS_USER0 + 5, //!< offset for User Group 1 + QS_USER2 = (enum_t)QS_USER1 + 5, //!< offset for User Group 2 + QS_USER3 = (enum_t)QS_USER2 + 5, //!< offset for User Group 3 + QS_USER4 = (enum_t)QS_USER3 + 5 //!< offset for User Group 4 }; -/*${QS::QSpyIdOffsets} .....................................................*/ -/*! QS ID offsets for QS_LOC_FILTER() -* @static @public @memberof QS_tx -*/ +//${QS::types::QSpyIdOffsets} ................................................ +//! @static @public @memberof QS +//! QS ID offsets for QS_LOC_FILTER() enum QSpyIdOffsets { - QS_AO_ID = 0, /*!< offset for AO priorities */ - QS_EP_ID = 64, /*!< offset for event-pool IDs */ - QS_EQ_ID = 80, /*!< offset for event-queue IDs */ - QS_AP_ID = 96 /*!< offset for Application-specific IDs */ + QS_AO_ID = 0, //!< offset for AO priorities + QS_EP_ID = 64, //!< offset for event-pool IDs + QS_EQ_ID = 80, //!< offset for event-queue IDs + QS_AP_ID = 96 //!< offset for Application-specific IDs }; -/*${QS::QSpyIdGroups} ......................................................*/ -/*! QS ID groups for QS_LOC_FILTER() -* @static @public @memberof QS_tx -*/ +//${QS::types::QSpyIdGroups} ................................................. +//! @static @public @memberof QS +//! QS ID groups for QS_LOC_FILTER() enum QSpyIdGroups { - QS_ALL_IDS = 0xF0, /*!< all QS IDs */ - QS_AO_IDS = (0x80 + (enum_t)QS_AO_ID), /*!< AO IDs (priorities) */ - QS_EP_IDS = (0x80 + (enum_t)QS_EP_ID), /*!< event-pool IDs */ - QS_EQ_IDS = (0x80 + (enum_t)QS_EQ_ID), /*!< event-queue IDs */ - QS_AP_IDS = (0x80 + (enum_t)QS_AP_ID) /*!< Application-specific IDs */ + QS_ALL_IDS = 0xF0, //!< all QS IDs + QS_AO_IDS = 0x80 + (enum_t)QS_AO_ID, //!< AO IDs (priorities) + QS_EP_IDS = 0x80 + (enum_t)QS_EP_ID, //!< event-pool IDs + QS_EQ_IDS = 0x80 + (enum_t)QS_EQ_ID, //!< event-queue IDs + QS_AP_IDS = 0x80 + (enum_t)QS_AP_ID //!< Application-specific IDs }; -/*${QS::QSpyFunPtr} ........................................................*/ -/*! function pointer type for QS_fun_dict_pre_() -* @static @private @memberof QS_tx -*/ -typedef void (* QSpyFunPtr )(void); - -/*${QS::QSpyId} ............................................................*/ -/*! @brief QS ID type for applying local filtering -* @static @public @memberof QS_tx -*/ +//${QS::types::QSpyId} ....................................................... +//! @struct QSpyId typedef struct { uint8_t prio; } QSpyId; -/*${QS::QS-tx::tx} .........................................................*/ -/*! @brief Software tracing, output QS-TX -* -* @details -* This class groups together QS services. -*/ +//${QS::types::QSpyFunPtr} ................................................... +//! @static @private @memberof QS +typedef void (* QSpyFunPtr )(void); + +//${QS::types::QSCtr} ........................................................ +#if (QS_CTR_SIZE == 2U) +typedef uint16_t QSCtr; +#endif // (QS_CTR_SIZE == 2U) + +//${QS::types::QSCtr} ........................................................ +#if (QS_CTR_SIZE == 4U) +typedef uint32_t QSCtr; +#endif // (QS_CTR_SIZE == 4U) + +//${QS::types::QSTimeCtr} .................................................... +#if (QS_TIME_SIZE == 2U) +typedef uint16_t QSTimeCtr; +#endif // (QS_TIME_SIZE == 2U) + +//${QS::types::QSTimeCtr} .................................................... +#if (QS_TIME_SIZE == 4U) +typedef uint32_t QSTimeCtr; +#endif // (QS_TIME_SIZE == 4U) + +//${QS::types::QSFun} ........................................................ +#if (QS_FUN_PTR_SIZE == 2U) +typedef uint16_t QSFun; +#endif // (QS_FUN_PTR_SIZE == 2U) + +//${QS::types::QSFun} ........................................................ +#if (QS_FUN_PTR_SIZE == 4U) +typedef uint32_t QSFun; +#endif // (QS_FUN_PTR_SIZE == 4U) + +//${QS::types::QSFun} ........................................................ +#if (QS_FUN_PTR_SIZE == 8U) +typedef uint64_t QSFun; +#endif // (QS_FUN_PTR_SIZE == 8U) +//$enddecl${QS::types} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +//$declare${QS::filters} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${QS::filters::Filter} ..................................................... +//! @struct QS_Filter typedef struct { -/* public: */ +// public: + uint8_t glb[16]; + uint8_t loc[16]; +} QS_Filter; - /*! global on/off QS filter */ - uint8_t glbFilter[16]; +//${QS::filters::filt_} ...................................................... +//! @static @private @memberof QS +extern QS_Filter QS_filt_; +//$enddecl${QS::filters} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +//$declare${QS-macros} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv - /*! local on/off QS filter */ - uint8_t locFilter[16]; +//${QS-macros::QS_INIT} ...................................................... +#define QS_INIT(arg_) (QS_onStartup(arg_)) - /*! @deprecated old local QS filter */ - void const * locFilter_AP; +//${QS-macros::QS_EXIT} ...................................................... +#define QS_EXIT() (QS_onCleanup()) - /*! pointer to the start of the QS-TX ring buffer */ +//${QS-macros::QS_OUTPUT} .................................................... +#define QS_OUTPUT() (QS_output()) + +//${QS-macros::QS_RX_INPUT} .................................................. +#define QS_RX_INPUT() (QS_rx_input()) + +//${QS-macros::QS_GLB_FILTER} ................................................ +#define QS_GLB_FILTER(rec_) (QS_glbFilter_((int_fast16_t)(rec_))) + +//${QS-macros::QS_LOC_FILTER} ................................................ +#define QS_LOC_FILTER(qs_id_) (QS_locFilter_((int_fast16_t)(qs_id_))) + +//${QS-macros::QS_BEGIN_ID} .................................................. +#define QS_BEGIN_ID(rec_, qs_id_) \ +if (QS_GLB_CHECK_(rec_) && QS_LOC_CHECK_(qs_id_)) { \ + QS_CRIT_STAT \ + QS_CRIT_ENTRY(); \ + QS_MEM_SYS(); \ + QS_beginRec_((uint_fast8_t)(rec_)); \ + QS_TIME_PRE_(); { + +//${QS-macros::QS_END} ....................................................... +#define QS_END() } \ + QS_endRec_(); \ + QS_MEM_APP(); \ + QS_CRIT_EXIT(); \ +} + +//${QS-macros::QS_FLUSH} ..................................................... +#define QS_FLUSH() (QS_onFlush()) + +//${QS-macros::QS_BEGIN_INCRIT} .............................................. +#define QS_BEGIN_INCRIT(rec_, qs_id_) \ +if (QS_GLB_CHECK_(rec_) && QS_LOC_CHECK_(qs_id_)) { \ + QS_beginRec_((uint_fast8_t)(rec_)); \ + QS_TIME_PRE_(); { + +//${QS-macros::QS_END_INCRIT} ................................................ +#define QS_END_INCRIT() } \ + QS_endRec_(); \ +} + +//${QS-macros::QS_GLB_CHECK_} ................................................ +#define QS_GLB_CHECK_(rec_) \ + (((uint_fast8_t)QS_filt_.glb[(uint_fast8_t)(rec_) >> 3U] \ + & ((uint_fast8_t)1U << ((uint_fast8_t)(rec_) & 7U))) != 0U) + +//${QS-macros::QS_LOC_CHECK_} ................................................ +#define QS_LOC_CHECK_(qs_id_) \ + (((uint_fast8_t)QS_filt_.loc[(uint_fast8_t)(qs_id_) >> 3U] \ + & ((uint_fast8_t)1U << ((uint_fast8_t)(qs_id_) & 7U))) != 0U) + +//${QS-macros::QS_REC_DONE} .................................................. +#ifndef QS_REC_DONE +#define QS_REC_DONE() ((void)0) +#endif // ndef QS_REC_DONE + +//${QS-macros::QS_I8} ........................................................ +#define QS_I8(width_, data_) \ + (QS_u8_fmt_((uint8_t)(((width_) << 4U) & 0x7U) | (uint8_t)QS_I8_ENUM_T, \ + (data_))) + +//${QS-macros::QS_U8} ........................................................ +#define QS_U8(width_, data_) \ + (QS_u8_fmt_((uint8_t)(((width_) << 4)) | (uint8_t)QS_U8_T, (data_))) + +//${QS-macros::QS_I16} ....................................................... +#define QS_I16(width_, data_) \ + (QS_u16_fmt_((uint8_t)(((width_) << 4)) | (uint8_t)QS_I16_T, (data_))) + +//${QS-macros::QS_U16} ....................................................... +#define QS_U16(width_, data_) \ + (QS_u16_fmt_((uint8_t)(((width_) << 4)) | (uint8_t)QS_U16_T, (data_))) + +//${QS-macros::QS_I32} ....................................................... +#define QS_I32(width_, data_) \ + (QS_u32_fmt_((uint8_t)(((width_) << 4)) | (uint8_t)QS_I32_T, (data_))) + +//${QS-macros::QS_U32} ....................................................... +#define QS_U32(width_, data_) \ + (QS_u32_fmt_((uint8_t)(((width_) << 4)) | (uint8_t)QS_U32_T, (data_))) + +//${QS-macros::QS_I64} ....................................................... +#define QS_I64(width_, data_) \ + (QS_u64_fmt_((uint8_t)(((width_) << 4)) | (uint8_t)QS_I64_T, (data_))) + +//${QS-macros::QS_U64} ....................................................... +#define QS_U64(width_, data_) \ + (QS_u64_fmt_((uint8_t)(((width_) << 4)) | (uint8_t)QS_U64_T, (data_))) + +//${QS-macros::QS_F32} ....................................................... +#define QS_F32(width_, data_) \ + (QS_f32_fmt_((uint8_t)(((width_) << 4)) | (uint8_t)QS_F32_T, (data_))) + +//${QS-macros::QS_F64} ....................................................... +#define QS_F64(width_, data_) \ + (QS_f64_fmt_((uint8_t)(((width_) << 4)) | (uint8_t)QS_F64_T, (data_))) + +//${QS-macros::QS_STR} ....................................................... +#define QS_STR(str_) (QS_str_fmt_((str_))) + +//${QS-macros::QS_MEM} ....................................................... +#define QS_MEM(mem_, size_) (QS_mem_fmt_((mem_), (size_))) + +//${QS-macros::QS_ENUM} ...................................................... +#define QS_ENUM(group_, value_) \ + (QS_u8_fmt_((uint8_t)(0x80U | ((group_) << 4U)) | (uint8_t)QS_I8_ENUM_T,\ + (uint8_t)(value_))) + +//${QS-macros::QS_TIME_PRE_} ................................................. +#if (QS_TIME_SIZE == 2U) +#define QS_TIME_PRE_() (QS_u16_raw_(QS_onGetTime())) +#endif // (QS_TIME_SIZE == 2U) + +//${QS-macros::QS_TIME_PRE_} ................................................. +#if (QS_TIME_SIZE == 4U) +#define QS_TIME_PRE_() (QS_u32_raw_(QS_onGetTime())) +#endif // (QS_TIME_SIZE == 4U) + +//${QS-macros::QS_OBJ} ....................................................... +#if (QS_OBJ_PTR_SIZE == 2U) +#define QS_OBJ(obj_) (QS_u16_fmt_(QS_OBJ_T, (uint16_t)(obj_))) +#endif // (QS_OBJ_PTR_SIZE == 2U) + +//${QS-macros::QS_OBJ} ....................................................... +#if (QS_OBJ_PTR_SIZE == 4U) +#define QS_OBJ(obj_) (QS_u32_fmt_(QS_OBJ_T, (uint32_t)(obj_))) +#endif // (QS_OBJ_PTR_SIZE == 4U) + +//${QS-macros::QS_OBJ} ....................................................... +#if (QS_OBJ_PTR_SIZE == 8U) +#define QS_OBJ(obj_) (QS_u64_fmt_(QS_OBJ_T, (uint64_t)(obj_))) +#endif // (QS_OBJ_PTR_SIZE == 8U) + +//${QS-macros::QS_FUN} ....................................................... +#if (QS_FUN_PTR_SIZE == 2U) +#define QS_FUN(fun_) (QS_u16_fmt_(QS_FUN_T, (uint16_t)(fun_))) +#endif // (QS_FUN_PTR_SIZE == 2U) + +//${QS-macros::QS_FUN} ....................................................... +#if (QS_FUN_PTR_SIZE == 4U) +#define QS_FUN(fun_) (QS_u32_fmt_(QS_FUN_T, (uint32_t)(fun_))) +#endif // (QS_FUN_PTR_SIZE == 4U) + +//${QS-macros::QS_FUN} ....................................................... +#if (QS_FUN_PTR_SIZE == 8U) +#define QS_FUN(fun_) (QS_u64_fmt_(QS_FUN_T, (uint64_t)(fun_))) +#endif // (QS_FUN_PTR_SIZE == 8U) + +//${QS-macros::QS_SIG} ....................................................... +#if (Q_SIGNAL_SIZE == 1U) +#define QS_SIG(sig_, obj_) \ + QS_u8_fmt_(QS_SIG_T, (sig_)); \ + QS_obj_raw_(obj_) +#endif // (Q_SIGNAL_SIZE == 1U) + +//${QS-macros::QS_SIG} ....................................................... +#if (Q_SIGNAL_SIZE == 2U) +#define QS_SIG(sig_, obj_) \ + QS_u16_fmt_(QS_SIG_T, (sig_)); \ + QS_obj_raw_(obj_) +#endif // (Q_SIGNAL_SIZE == 2U) + +//${QS-macros::QS_SIG} ....................................................... +#if (Q_SIGNAL_SIZE == 4U) +#define QS_SIG(sig_, obj_) \ + QS_u32_fmt_(QS_SIG_T, (sig_)); \ + QS_obj_raw_(obj_) +#endif // (Q_SIGNAL_SIZE == 4U) + +//${QS-macros::QS_SIG_DICTIONARY} ............................................ +#define QS_SIG_DICTIONARY(sig_, obj_) \ + (QS_sig_dict_pre_((QSignal)(sig_), (obj_), #sig_)) + +//${QS-macros::QS_OBJ_DICTIONARY} ............................................ +#define QS_OBJ_DICTIONARY(obj_) \ + (QS_obj_dict_pre_((obj_), #obj_)) + +//${QS-macros::QS_OBJ_ARR_DICTIONARY} ........................................ +#define QS_OBJ_ARR_DICTIONARY(obj_, idx_) \ + (QS_obj_arr_dict_pre_((obj_), (idx_), #obj_)) + +//${QS-macros::QS_FUN_DICTIONARY} ............................................ +#define QS_FUN_DICTIONARY(fun_) \ + (QS_fun_dict_pre_((void (*)(void))(fun_), #fun_)) + +//${QS-macros::QS_USR_DICTIONARY} ............................................ +#define QS_USR_DICTIONARY(rec_) \ + (QS_usr_dict_pre_((rec_), #rec_)) + +//${QS-macros::QS_ENUM_DICTIONARY} ........................................... +#define QS_ENUM_DICTIONARY(value_, group_) \ + (QS_enum_dict_pre_((value_), (group_), #value_)) + +//${QS-macros::QS_RX_PUT} .................................................... +#define QS_RX_PUT(b_) (QS_rxPut((b_))) + +//${QS-macros::QS_TR_CRIT_ENTRY} ............................................. +#define QS_TR_CRIT_ENTRY() + +//${QS-macros::QS_TR_CRIT_EXIT} .............................................. +#define QS_TR_CRIT_EXIT() + +//${QS-macros::QS_TR_ISR_ENTRY} .............................................. +#define QS_TR_ISR_ENTRY(isrnest, prio) do { \ + QS_BEGIN_PRE_(QS_QF_ISR_ENTRY, 0U) \ + QS_TIME_PRE_(); \ + QS_2u8_raw_(isrnest, prio); \ + QS_END_PRE_() \ +} + +//${QS-macros::QS_TR_ISR_EXIT} ............................................... +void QS_TR_ISR_EXIT( + uint_fast8_t isrnest, + uint_fast8_t prio); + +//${QS-macros::QS_ONLY} ...................................................... +#define QS_ONLY(code_) (code_) + +//${QS-macros::QS_ASSERTION} ................................................. +#define QS_ASSERTION(module_, id_, delay_) \ + (QS_assertion_pre_((module_), (id_), (delay_))) + +//${QS-macros::QS_EOD} ....................................................... +#define QS_EOD ((uint16_t)0xFFFFU) + +//${QS-macros::QS_CMD} ....................................................... +#define QS_CMD ((uint8_t)7U) + +//${QS-macros::QS_HEX_FMT} ................................................... +#define QS_HEX_FMT ((uint8_t)0x0FU) + +//${QS-macros::QS_CRIT_STAT} ................................................. +#ifndef QS_CRIT_STAT +#define QS_CRIT_STAT QF_CRIT_STAT +#endif // ndef QS_CRIT_STAT + +//${QS-macros::QS_CRIT_ENTRY} ................................................ +#ifndef QS_CRIT_ENTRY +#define QS_CRIT_ENTRY() QF_CRIT_ENTRY() +#endif // ndef QS_CRIT_ENTRY + +//${QS-macros::QS_CRIT_EXIT} ................................................. +#ifndef QS_CRIT_EXIT +#define QS_CRIT_EXIT() QF_CRIT_EXIT() +#endif // ndef QS_CRIT_EXIT + +//${QS-macros::QS_MEM_SYS} ................................................... +#ifndef QS_MEM_SYS +#define QS_MEM_SYS() QF_MEM_SYS() +#endif // ndef QS_MEM_SYS + +//${QS-macros::QS_MEM_APP} ................................................... +#ifndef QS_MEM_APP +#define QS_MEM_APP() QF_MEM_APP() +#endif // ndef QS_MEM_APP +//$enddecl${QS-macros} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +//============================================================================ +//! @cond INTERNAL + +typedef struct { + void const * locFilter_AP; //!< @deprecated uint8_t * buf; - - /*! offset of the end of the ring buffer */ QSCtr end; - - /*! offset to where next byte will be inserted */ QSCtr volatile head; - - /*! offset of where next record will be extracted */ QSCtr volatile tail; - - /*! number of bytes currently in the ring buffer */ QSCtr volatile used; - - /*! sequence number of the last inserted QS record */ uint8_t volatile seq; - - /*! checksum of the currently inserted record */ uint8_t volatile chksum; - - /*! critical section nesting level */ uint8_t volatile critNest; - - /* flags for internal use */ uint8_t flags; -} QS_tx; +} QS_Attr; -/*${QS::QS-tx::preType} ....................................................*/ -/*! Enumerates data elements for app-specific trace records */ -enum QS_preType { - QS_I8_ENUM_T, /*!< signed 8-bit integer or enum format */ - QS_U8_T, /*!< unsigned 8-bit integer format */ - QS_I16_T, /*!< signed 16-bit integer format */ - QS_U16_T, /*!< unsigned 16-bit integer format */ - QS_I32_T, /*!< signed 32-bit integer format */ - QS_U32_T, /*!< unsigned 32-bit integer format */ - QS_F32_T, /*!< 32-bit floating point format */ - QS_F64_T, /*!< 64-bit floating point format */ - QS_STR_T, /*!< zero-terminated ASCII string format */ - QS_MEM_T, /*!< up to 255-bytes memory block format */ - QS_SIG_T, /*!< event signal format */ - QS_OBJ_T, /*!< object pointer format */ - QS_FUN_T, /*!< function pointer format */ - QS_I64_T, /*!< signed 64-bit integer format */ - QS_U64_T /*!< unsigned 64-bit integer format */ -}; +extern QS_Attr QS_priv_; -/*${QS::QS-tx::priv_} ......................................................*/ -/*! the only instance of the QS-TX object (Singleton) */ -extern QS_tx QS_priv_; - -/*${QS::QS-tx::initBuf} ....................................................*/ -/*! Initialize the QS-TX data buffer -* @static @public @memberof QS_tx -* -* @details -* This function should be called from QS_onStartup() to provide -* QS with the data buffer. The first argument `sto` is the address -* of the memory block, and the second argument `stoSize` is the size -* of this block [in bytes]. Currently the size of the QS buffer cannot -* exceed 64KB. -* -* @param[in] sto pointer to the storage for the transmit buffer -* @param[in] stoSize size in [bytes] of the storage buffer -* -* @remark -* QS can work with quite small data buffers, but you will start losing -* data if the buffer is too small for the bursts of tracing activity. -* The right size of the buffer depends on the data production rate and -* the data output rate. QS offers flexible filtering to reduce the data -* production rate. -* -* @note -* If the data output rate cannot keep up with the production rate, -* QS will start overwriting the older data with newer data. This is -* consistent with the "last-is-best" QS policy. The record sequence -* counters and check sums on each record allow the QSPY host utility -* to easily detect any data loss. -*/ -void QS_initBuf( - uint8_t * const sto, - uint_fast32_t const stoSize); - -/*${QS::QS-tx::getByte} ....................................................*/ -/*! Byte-oriented interface to the QS-TX data buffer -* @static @public @memberof QS_tx -* -* @details -* This function delivers one byte at a time from the QS data buffer. -* -* @returns -* the byte in the least-significant 8-bits of the 16-bit return -* value if the byte is available. If no more data is available at the -* time, the function returns ::QS_EOD (End-Of-Data). -* -* @note -* QS_getByte() is NOT protected with a critical section. -*/ -uint16_t QS_getByte(void); - -/*${QS::QS-tx::getBlock} ...................................................*/ -/*! Block-oriented interface to the QS-TX data buffer -* @static @public @memberof QS_tx -* -* @details -* This function delivers a contiguous block of data from the QS data -* buffer. The function returns the pointer to the beginning of the -* block, and writes the number of bytes in the block to the location -* pointed to by `pNbytes`. The argument `pNbytes` is also used as -* input to provide the maximum size of the data block that the caller -* can accept. -* -* @param[in,out] pNbytes pointer to the number of bytes to send. -* On input, `pNbytes` specifies the maximum number -* of bytes that the function can provide. -* On output, `pNbytes` contains the actual number -* of bytes available. -* @returns -* if data is available, the function returns pointer to the -* contiguous block of data and sets the value pointed to by `pNbytes` -* to the # available bytes. If data is available at the time the -* function is called, the function returns NULL pointer and sets the -* value pointed to by `pNbytes` to zero. -* -* @note -* Only the NULL return from QS_getBlock() indicates that the QS -* buffer is empty at the time of the call. The non-NULL return often -* means that the block is at the end of the buffer and you need to call -* QS_getBlock() again to obtain the rest of the data that -* "wrapped around" to the beginning of the QS data buffer. -* -* @note QS_getBlock() is **not** protected with a critical section. -*/ -uint8_t const * QS_getBlock(uint16_t * const pNbytes); - -/*${QS::QS-tx::glbFilter_} .................................................*/ -/*! Set/clear the global Filter for a given QS record or a group -* of records -* @static @public @memberof QS_tx -* -* @details -* This function sets up the QS filter to enable record types specified -* in the `filter` parameter. The value #QS_ALL_RECORDS specifies to -* filter-in all records. This function should be called indirectly -* through the macro QS_GLB_FILTER() -* -* @param[in] filter the QS record-d or group to enable in the filter, -* if positive or disable, if negative. The record-id -* numbers must be in the range -127..127. -* @note -* Filtering based on the record-type is only the first layer of -* filtering. The second layer is based on the object-type. Both filter -* layers must be enabled for the QS record to be inserted in the -* QS buffer. -* -* @sa QS_locFilter_() -*/ void QS_glbFilter_(int_fast16_t const filter); - -/*${QS::QS-tx::locFilter_} .................................................*/ -/*! Set/clear the local Filter for a given object-id -* or a group of object-ids -* @static @public @memberof QS_tx -* -* @details -* This function sets up the local QS filter to enable or disable the -* given QS object-id or a group of object-ids @a filter. -* This function should be called indirectly through the macro -* QS_LOC_FILTER() -* -* @param[in] filter the QS object-id or group to enable in the filter, -* if positive or disable, if negative. The qs_id numbers -* must be in the range 1..127. -* @note -* Filtering based on the object-id (local filter) is the second layer -* of filtering. The first layer is based on the QS record-type (global -* filter). Both filter layers must be enabled for the QS record to be -* inserted into the QS buffer. -* -* @sa QS_glbFilter_() -*/ void QS_locFilter_(int_fast16_t const filter); -/*${QS::QS-tx::doOutput} ...................................................*/ -/*! Perform the QS-TX output (implemented in some QS ports) -* @static @public @memberof QS_tx -*/ -void QS_doOutput(void); - -/*${QS::QS-tx::beginRec_} ..................................................*/ -/*! Mark the begin of a QS record `rec` -* @static @private @memberof QS_tx -* -* @details -* This function must be called at the beginning of each QS record. -* This function should be called indirectly through the macro QS_BEGIN_ID(), -* or QS_BEGIN_NOCRIT(), depending if it's called in a normal code or from -* a critical section. -*/ void QS_beginRec_(uint_fast8_t const rec); - -/*${QS::QS-tx::endRec_} ....................................................*/ -/*! Mark the end of a QS record `rec` -* @static @private @memberof QS_tx -* -* @details -* This function must be called at the end of each QS record. -* This function should be called indirectly through the macro QS_END(), -* or QS_END_NOCRIT(), depending if it's called in a normal code or from -* a critical section. -*/ void QS_endRec_(void); -/*${QS::QS-tx::u8_raw_} ....................................................*/ -/*! output uint8_t data element without format information -* @static @private @memberof QS_tx -*/ void QS_u8_raw_(uint8_t const d); - -/*${QS::QS-tx::2u8_raw_} ...................................................*/ -/*! output two uint8_t data elements without format information -* @static @private @memberof QS_tx -*/ void QS_2u8_raw_( uint8_t const d1, uint8_t const d2); - -/*${QS::QS-tx::u16_raw_} ...................................................*/ -/*! output uint16_t data element without format information -* @static @private @memberof QS_tx -*/ void QS_u16_raw_(uint16_t const d); - -/*${QS::QS-tx::u32_raw_} ...................................................*/ -/*! output uint32_t data element without format information -* @static @private @memberof QS_tx -*/ void QS_u32_raw_(uint32_t const d); - -/*${QS::QS-tx::obj_raw_} ...................................................*/ -/*! Output obj pointer data element without format information -* @static @private @memberof QS_tx -* -* @note This function is only to be used through macros, never in the -* client code directly. -*/ +void QS_u64_raw_(uint64_t const d); void QS_obj_raw_(void const * const obj); - -/*${QS::QS-tx::str_raw_} ...................................................*/ -/*! Output raw zero-terminated string element (without format information) -* @static @private @memberof QS_tx -* -* @note This function is only to be used through macros, never in the -* client code directly. -*/ void QS_str_raw_(char const * const str); -/*${QS::QS-tx::u8_fmt_} ....................................................*/ -/*! Output uint8_t data element with format information -* @static @private @memberof QS_tx -* -* @details -* @note This function is only to be used through macros, never in the -* client code directly. -*/ void QS_u8_fmt_( uint8_t const format, uint8_t const d); - -/*${QS::QS-tx::u16_fmt_} ...................................................*/ -/*! output uint16_t data element with format information -* @static @private @memberof QS_tx -* -* @details -* This function is only to be used through macros, never in the -* client code directly. -*/ void QS_u16_fmt_( uint8_t const format, uint16_t const d); - -/*${QS::QS-tx::u32_fmt_} ...................................................*/ -/*! Output uint32_t data element with format information -* @static @private @memberof QS_tx -* -* @note This function is only to be used through macros, never in the -* client code directly. -*/ void QS_u32_fmt_( uint8_t const format, uint32_t const d); - -/*${QS::QS-tx::str_fmt_} ...................................................*/ -/*! Output formatted zero-terminated ASCII string to the QS record -* @static @private @memberof QS_tx -*/ +void QS_u64_fmt_( + uint8_t const format, + uint64_t const d); +void QS_f32_fmt_( + uint8_t const format, + float32_t const f); +void QS_f64_fmt_( + uint8_t const format, + float64_t const d); void QS_str_fmt_(char const * const str); - -/*${QS::QS-tx::mem_fmt_} ...................................................*/ -/*! Output formatted memory block of up to 255 bytes to the QS record -* @static @private @memberof QS_tx -*/ void QS_mem_fmt_( uint8_t const * const blk, uint8_t const size); -/*${QS::QS-tx::sig_dict_pre_} ..............................................*/ -/*! Output predefined signal-dictionary record -* @static @private @memberof QS_tx -* -* @note This function is only to be used through macro QS_SIG_DICTIONARY() -*/ void QS_sig_dict_pre_( - enum_t const sig, + QSignal const sig, void const * const obj, char const * const name); - -/*${QS::QS-tx::obj_dict_pre_} ..............................................*/ -/*! Output predefined object-dictionary record -* @static @private @memberof QS_tx -* -* @note This function is only to be used through macro QS_OBJ_DICTIONARY() -*/ void QS_obj_dict_pre_( void const * const obj, char const * const name); - -/*${QS::QS-tx::obj_arr_dict_pre_} ..........................................*/ -/*! Output predefined object-array dictionary record -* @static @private @memberof QS_tx -* -* @note This function is only to be used through macro QS_OBJ_ARR_DICTIONARY() -*/ void QS_obj_arr_dict_pre_( void const * const obj, uint_fast16_t const idx, char const * const name); - -/*${QS::QS-tx::fun_dict_pre_} ..............................................*/ -/*! Output predefined function-dictionary record -* @static @private @memberof QS_tx -* -* @note This function is only to be used through macro QS_FUN_DICTIONARY() -*/ void QS_fun_dict_pre_( QSpyFunPtr const fun, char const * const name); - -/*${QS::QS-tx::usr_dict_pre_} ..............................................*/ -/*! Output predefined user-dictionary record -* @static @private @memberof QS_tx -* -* @note This function is only to be used through macro QS_USR_DICTIONARY() -*/ void QS_usr_dict_pre_( enum_t const rec, char const * const name); - -/*${QS::QS-tx::enum_dict_pre_} .............................................*/ -/*! Output predefined enum-dictionary record -* @static @private @memberof QS_tx -* -* @note This function is only to be used through macro QS_ENUM_DICTIONARY() -*/ void QS_enum_dict_pre_( enum_t const value, uint8_t const group, char const * const name); -/*${QS::QS-tx::ASSERTION} ..................................................*/ -/*! Output the predefined assertion failure trace record -* @static @public @memberof QS_tx -* -* @details -* This trace record is intended to use from the Q_onAssert() callback. -*/ -void QS_ASSERTION( +void QS_assertion_pre_( char const * const module, - int_t const loc, + int_t const id, uint32_t const delay); -/*${QS::QS-tx::target_info_pre_} ...........................................*/ -/*! Helper function to output the predefined Target-info trace record -* @static @private @memberof QS_tx -*/ void QS_target_info_pre_(uint8_t const isReset); -/*${QS::QS-tx::onStartup} ..................................................*/ -/*! Callback to startup the QS facility -* @static @public @memberof QS_tx -*/ +//! @endcond +//============================================================================ + +//$declare${QS::QS-TX} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${QS::QS-TX::preType} ...................................................... +//! Enumerates data elements for app-specific trace records +enum QS_preType { + QS_I8_ENUM_T, //!< signed 8-bit integer or enum format + QS_U8_T, //!< unsigned 8-bit integer format + QS_I16_T, //!< signed 16-bit integer format + QS_U16_T, //!< unsigned 16-bit integer format + QS_I32_T, //!< signed 32-bit integer format + QS_U32_T, //!< unsigned 32-bit integer format + QS_F32_T, //!< 32-bit floating point format + QS_F64_T, //!< 64-bit floating point format + QS_STR_T, //!< zero-terminated ASCII string format + QS_MEM_T, //!< up to 255-bytes memory block format + QS_SIG_T, //!< event signal format + QS_OBJ_T, //!< object pointer format + QS_FUN_T, //!< function pointer format + QS_I64_T, //!< signed 64-bit integer format + QS_U64_T //!< unsigned 64-bit integer format +}; + +//${QS::QS-TX::initBuf} ...................................................... +//! @static @public @memberof QS +void QS_initBuf( + uint8_t * const sto, + uint_fast32_t const stoSize); + +//${QS::QS-TX::getByte} ...................................................... +//! @static @public @memberof QS +uint16_t QS_getByte(void); + +//${QS::QS-TX::getBlock} ..................................................... +//! @static @public @memberof QS +uint8_t const * QS_getBlock(uint16_t * const pNbytes); + +//${QS::QS-TX::doOutput} ..................................................... +//! @static @public @memberof QS +void QS_doOutput(void); + +//${QS::QS-TX::onStartup} .................................................... +//! @static @public @memberof QS uint8_t QS_onStartup(void const * arg); -/*${QS::QS-tx::onCleanup} ..................................................*/ -/*! Callback to cleanup the QS facility -* @static @public @memberof QS_tx -*/ +//${QS::QS-TX::onCleanup} .................................................... +//! @static @public @memberof QS void QS_onCleanup(void); -/*${QS::QS-tx::onFlush} ....................................................*/ -/*! Callback to flush the QS trace data to the host -* @static @public @memberof QS_tx -*/ +//${QS::QS-TX::onFlush} ...................................................... +//! @static @public @memberof QS void QS_onFlush(void); -/*${QS::QS-tx::onGetTime} ..................................................*/ -/*! Callback to obtain a timestamp for a QS record -* @static @public @memberof QS_tx -*/ +//${QS::QS-TX::onGetTime} .................................................... +//! @static @public @memberof QS QSTimeCtr QS_onGetTime(void); +//$enddecl${QS::QS-TX} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -/*${QS::QS-tx-64bit::u64_raw_} .............................................*/ -/*! Output uint64_t data element without format information -* @static @private @memberof QS_tx -*/ -void QS_u64_raw_(uint64_t d); +//============================================================================ +//! @cond INTERNAL -/*${QS::QS-tx-64bit::u64_fmt_} .............................................*/ -/*! Output uint64_t data element with format information -* @static @private @memberof QS_tx -* -* @sa QS_U64(), QS_I64() -*/ -void QS_u64_fmt_( - uint8_t format, - uint64_t d); - -/*${QS::QS-tx-fp::f32_fmt_} ................................................*/ -/*! Output 32-bit floating point data element with format information -* @static @private @memberof QS_tx -* -* @sa QS_F32() -*/ -void QS_f32_fmt_( - uint8_t const format, - float32_t const d); - -/*${QS::QS-tx-fp::f64_fmt_} ................................................*/ -/*! Output 64-bit floating point data element with format information -* @static @private @memberof QS_tx -* -* @sa QS_F64() -*/ -void QS_f64_fmt_( - uint8_t const format, - float64_t const d); - -/*${QS::QS-rx::rx} .........................................................*/ -/*! @brief QS software tracing parameters for QS input (QS-RX) */ typedef struct { -/* public: */ void * currObj[8]; uint8_t * buf; QSCtr end; QSCtr volatile head; QSCtr volatile tail; - #ifdef Q_UTEST bool inTestLoop; -#endif /* def Q_UTEST */ -} QS_rx; +#endif +} QS_RxAttr; -/*${QS::QS-rx::rxPriv_} ....................................................*/ -/*! the only instance of the QS-RX object (Singleton) -* @static @private @memberof QS_rx -*/ -extern QS_rx QS_rxPriv_; +//! @static @private @memberof QS +extern QS_RxAttr QS_rxPriv_; -/*${QS::QS-rx::QSpyObjKind} ................................................*/ -/*! Kinds of objects used in QS_setCurrObj() and QS_queryCurrObj() -* @static @public @memberof QS_rx -*/ +//! @endcond +//============================================================================ + +//$declare${QS::QS-RX} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${QS::QS-RX::QSpyObjKind} .................................................. +//! @static @public @memberof QS +//! Kinds of objects used in QS-RX enum QS_QSpyObjKind { - SM_OBJ, /*!< state machine object */ - AO_OBJ, /*!< active object */ - MP_OBJ, /*!< event pool object */ - EQ_OBJ, /*!< raw queue object */ - TE_OBJ, /*!< time event object */ - AP_OBJ, /*!< generic Application-specific object */ + SM_OBJ, //!< state machine object + AO_OBJ, //!< active object + MP_OBJ, //!< event pool object + EQ_OBJ, //!< raw queue object + TE_OBJ, //!< time event object + AP_OBJ, //!< generic Application-specific object MAX_OBJ }; -/*${QS::QS-rx::OSpyObjCombnation} ..........................................*/ -/*! Object combinations for QS_setCurrObj() and QS_queryCurrObj() -* @static @public @memberof QS_rx -*/ -enum QS_OSpyObjCombnation { - SM_AO_OBJ = (enum_t)MAX_OBJ /*!< combination of SM and AO */ +//${QS::QS-RX::OSpyObjComb} .................................................. +//! @static @public @memberof QS +//! Object combinations for QS-RX +enum QS_OSpyObjComb { + SM_AO_OBJ = (enum_t)MAX_OBJ //!< combination of SM and AO }; -/*${QS::QS-rx::rxInitBuf} ..................................................*/ -/*! Initialize the QS-RX data buffer -* @static @public @memberof QS_rx -* -* @details -* This function should be called from QS::onStartup() to provide QS-RX -* with the receive data buffer. -* -* @param[in] sto pointer to the memory block for input buffer -* @param[in] stoSize the size of this block [bytes]. The size of the -* QS-RX buffer cannot exceed 64KB. -* -* @note -* QS-RX can work with quite small data buffers, but you will start -* losing data if the buffer is not drained fast enough (e.g., in the -* idle task). -* -* @note -* If the data input rate exceeds the QS-RX processing rate, the data -* will be lost, but the QS protocol will notice that: -* (1) that the checksum in the incomplete QS records will fail; and -* (2) the sequence counter in QS records will show discontinuities. -* -* The QS-RX channel will report any data errors by sending the -* QS_RX_DATA_ERROR trace record. -*/ +//${QS::QS-RX::rxInitBuf} .................................................... +//! @static @public @memberof QS void QS_rxInitBuf( uint8_t * const sto, uint16_t const stoSize); -/*${QS::QS-rx::rxPut} ......................................................*/ -/*! Put one byte into the QS-RX lock-free buffer -* @static @public @memberof QS_rx -*/ +//${QS::QS-RX::rxPut} ........................................................ +//! @static @public @memberof QS static inline bool QS_rxPut(uint8_t const b) { + // NOTE: does not need critical section + // But requires system-level memory access (QF_MEM_SYS()). + QSCtr head = QS_rxPriv_.head + 1U; if (head == QS_rxPriv_.end) { head = 0U; } - if (head != QS_rxPriv_.tail) { /* buffer NOT full? */ + if (head != QS_rxPriv_.tail) { // buffer NOT full? QS_rxPriv_.buf[QS_rxPriv_.head] = b; - QS_rxPriv_.head = head; /* update the head to a *valid* index */ - return true; /* byte placed in the buffer */ + QS_rxPriv_.head = head; // update the head to a *valid* index + return true; // byte placed in the buffer } else { - return false; /* byte NOT placed in the buffer */ + return false; // byte NOT placed in the buffer } } -/*${QS::QS-rx::rxGetNfree} .................................................*/ -/*! Obtain the number of free bytes in the QS-RX data buffer -* @static @public @memberof QS_rx -* -* @details -* This function is intended to be called from the ISR that reads the -* QS-RX bytes from the QSPY application. The function returns the -* conservative number of free bytes currently available in the buffer, -* assuming that the head pointer is not being moved concurrently. -* The tail pointer might be moving, meaning that bytes can be -* concurrently removed from the buffer. -*/ -uint16_t QS_rxGetNfree(void); - -/*${QS::QS-rx::doInput} ....................................................*/ -/*! Perform the QS-RX input (implemented in some QS ports) -* @static @public @memberof QS_rx -*/ -void QS_doInput(void); - -/*${QS::QS-rx::setCurrObj} .................................................*/ -/*! Set the "current object" in the Target -* @static @public @memberof QS_rx -* -* @details -* This function sets the "current object" in the Target. -*/ -void QS_setCurrObj( - uint8_t const obj_kind, - void * const obj_ptr); - -/*${QS::QS-rx::queryCurrObj} ...............................................*/ -/*! Query the "current object" in the Target -* @static @public @memberof QS_rx -* -* @details -* This function programmatically generates the response to the query for -* a "current object". -*/ -void QS_queryCurrObj(uint8_t const obj_kind); - -/*${QS::QS-rx::rxParse} ....................................................*/ -/*! Parse all bytes present in the QS-RX data buffer -* @static @public @memberof QS_rx -*/ +//${QS::QS-RX::rxParse} ...................................................... +//! @static @public @memberof QS void QS_rxParse(void); -/*${QS::QS-rx::rxHandleGoodFrame_} .........................................*/ -/*! internal function to handle incoming (QS-RX) packet -* @static @private @memberof QS_rx -*/ -void QS_rxHandleGoodFrame_(uint8_t const state); +//${QS::QS-RX::rxGetNfree} ................................................... +//! @static @public @memberof QS +uint16_t QS_rxGetNfree(void); -/*${QS::QS-rx::onReset} ....................................................*/ -/*! callback function to reset the Target (to be implemented in the BSP) -* @static @public @memberof QS_rx -*/ +//${QS::QS-RX::doInput} ...................................................... +//! @static @public @memberof QS +void QS_doInput(void); + +//${QS::QS-RX::onReset} ...................................................... +//! @static @public @memberof QS void QS_onReset(void); -/*${QS::QS-rx::onCommand} ..................................................*/ -/*! Callback function to execute user commands (to be implemented in BSP) -* @static @public @memberof QS_rx -*/ +//${QS::QS-RX::onCommand} .................................................... +//! @static @public @memberof QS void QS_onCommand( uint8_t cmdId, uint32_t param1, uint32_t param2, uint32_t param3); +//$enddecl${QS::QS-RX} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -/*${QS::QS-rx::RX_PUT} .....................................................*/ -/*! Put one byte into the QS RX lock-free buffer -* @static @public @memberof QS_rx -*/ -bool QS_RX_PUT(uint8_t const b); -/*$enddecl${QS} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ - -/*==========================================================================*/ -/*$declare${QS-macros} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${QS-macros::QS_INIT} ....................................................*/ -/*! Initialize the QS facility -* -* @details -* This macro provides an indirection layer to invoke the QS initialization -* routine if #Q_SPY is defined, or do nothing if #Q_SPY is not defined. -* @sa QS_onStartup(), example of setting up a QS filter in -* QS_GLB_FILTER() -*/ -#define QS_INIT(arg_) (QS_onStartup(arg_)) - -/*${QS-macros::QS_EXIT} ....................................................*/ -/*! Cleanup the QS facility -* -* @details -* This macro provides an indirection layer to invoke the QS cleanup -* routine if #Q_SPY is defined, or do nothing if #Q_SPY is not defined. -* @sa QS_onCleanup() -*/ -#define QS_EXIT() (QS_onCleanup()) - -/*${QS-macros::QS_OUTPUT} ..................................................*/ -/*! macro to handle the QS output from the application -* -* @note -* If this macro is used, the application must define QS_output(). -*/ -#define QS_OUTPUT() (QS_output()) - -/*${QS-macros::QS_RX_INPUT} ................................................*/ -/*! macro to handle the QS-RX input to the application -* -* @note -* If this macro is used, the application must define QS_doInput(). -*/ -#define QS_RX_INPUT() (QS_rx_input()) - -/*${QS-macros::QS_GLB_FILTER} ..............................................*/ -/*! Global Filter ON for a given record type `rec_` -* -* @details -* This macro provides an indirection layer to call QS_filterOn() -* if #Q_SPY is defined, or do nothing if #Q_SPY is not defined. -* -* @sa -* - enum QSpyGroups - QS record groups that can be used as `rec_` -* - enum QSpyPre - predefined QS records that can be used as `rec_` -* -* @usage -* The following example shows how to use QS filters: -* @include qs_filter.c -*/ -#define QS_GLB_FILTER(rec_) (QS_glbFilter_((int_fast16_t)(rec_))) - -/*${QS-macros::QS_LOC_FILTER} ..............................................*/ -/*! Local Filter for a given state machine object `qs_id` -* -* @details -* This macro provides an indirection layer to call QS_locFilter_() -* if #Q_SPY is defined, or do nothing if #Q_SPY is not defined. -* -* @sa -* - enum QSpyIdGroups - QS ID groups that can be used as `qs_id_` -* - enum QSpyIdOffsets - QS ID offsets for `qs_id_` (e.g., QS_AP_IDS + 5) -* -* The following example shows how to use QS filters: -* @include qs_filter.c -*/ -#define QS_LOC_FILTER(qs_id_) (QS_locFilter_((int_fast16_t)(qs_id_))) - -/*${QS-macros::QS_BEGIN_ID} ................................................*/ -/*! Begin an application-specific QS record with entering critical section -* -* @details -* The following example shows how to build a user QS record using the -* macros QS_BEGIN_ID(), QS_END(), and the formatted output macros: -* QS_U8(), QS_STR(), etc. -* -* @note -* Must always be used in pair with QS_END() -* -* @include qs_ap.c -*/ -#define QS_BEGIN_ID(rec_, qs_id_) \ -if (QS_GLB_CHECK_(rec_) && QS_LOC_CHECK_(qs_id_)) { \ - QS_CRIT_STAT_ \ - QS_CRIT_E_(); \ - QS_beginRec_((uint_fast8_t)(rec_)); \ - QS_TIME_PRE_(); { - -/*${QS-macros::QS_END} .....................................................*/ -/*! End an application-specific QS record with exiting critical section. -* -* @sa example for QS_BEGIN_ID() -* @note Must always be used in pair with QS_BEGIN_ID() -*/ -#define QS_END() } \ - QS_endRec_(); \ - QS_CRIT_X_(); \ -} - -/*${QS-macros::QS_FLUSH} ...................................................*/ -/*! Flush the QS trace data to the host -* -* @details -* This macro invokes the QS_flush() platform-dependent callback -* function to flush the QS trace buffer to the host. The function -* typically busy-waits until all the data in the buffer is sent to -* the host. This is acceptable only in the initial transient. -*/ -#define QS_FLUSH() (QS_onFlush()) - -/*${QS-macros::QS_BEGIN_NOCRIT} ............................................*/ -/*! Begin an application-specific QS record WITHOUT entering critical section */ -#define QS_BEGIN_NOCRIT(rec_, qs_id_) \ -if (QS_GLB_CHECK_(rec_) && QS_LOC_CHECK_(qs_id_)) { \ - QS_beginRec_((uint_fast8_t)(rec_)); \ - QS_TIME_PRE_(); { - -/*${QS-macros::QS_END_NOCRIT} ..............................................*/ -/*! End an application-specific QS record WITHOUT exiting critical section */ -#define QS_END_NOCRIT() } \ - QS_endRec_();\ -} - -/*${QS-macros::QS_GLB_CHECK_} ..............................................*/ -/*! Helper macro for checking the global QS filter */ -#define QS_GLB_CHECK_(rec_) \ - (((uint_fast8_t)QS_priv_.glbFilter[(uint_fast8_t)(rec_) >> 3U] \ - & ((uint_fast8_t)1U << ((uint_fast8_t)(rec_) & 7U))) != 0U) - -/*${QS-macros::QS_LOC_CHECK_} ..............................................*/ -/*! Helper macro for checking the local QS filter */ -#define QS_LOC_CHECK_(qs_id_) \ - (((uint_fast8_t)QS_priv_.locFilter[(uint_fast8_t)(qs_id_) >> 3U] \ - & ((uint_fast8_t)1U << ((uint_fast8_t)(qs_id_) & 7U))) != 0U) - -/*${QS-macros::QS_REC_DONE} ................................................*/ -#ifndef QS_REC_DONE -/*! Macro to execute user code when a QS record is produced -* -* @note -* This is a dummy definition in case this macro is undefined. -*/ -#define QS_REC_DONE() ((void)0) -#endif /* ndef QS_REC_DONE */ - -/*${QS-macros::QS_I8} ......................................................*/ -/*! Output formatted int8_t to the QS record */ -#define QS_I8(width_, data_) \ - (QS_u8_fmt_((uint8_t)(((width_) << 4U) & 0x7U) | (uint8_t)QS_I8_ENUM_T, \ - (data_))) - -/*${QS-macros::QS_U8} ......................................................*/ -/*! Output formatted uint8_t to the QS record */ -#define QS_U8(width_, data_) \ - (QS_u8_fmt_((uint8_t)(((width_) << 4)) | (uint8_t)QS_U8_T, (data_))) - -/*${QS-macros::QS_I16} .....................................................*/ -/*! Output formatted int16_t to the QS record */ -#define QS_I16(width_, data_) \ - (QS_u16_fmt_((uint8_t)(((width_) << 4)) | (uint8_t)QS_I16_T, (data_))) - -/*${QS-macros::QS_U16} .....................................................*/ -/*! Output formatted uint16_t to the QS record */ -#define QS_U16(width_, data_) \ - (QS_u16_fmt_((uint8_t)(((width_) << 4)) | (uint8_t)QS_U16_T, (data_))) - -/*${QS-macros::QS_I32} .....................................................*/ -/*! Output formatted int32_t to the QS record */ -#define QS_I32(width_, data_) \ - (QS_u32_fmt_((uint8_t)(((width_) << 4)) | (uint8_t)QS_I32_T, (data_))) - -/*${QS-macros::QS_U32} .....................................................*/ -/*! Output formatted uint32_t to the QS record */ -#define QS_U32(width_, data_) \ - (QS_u32_fmt_((uint8_t)(((width_) << 4)) | (uint8_t)QS_U32_T, (data_))) - -/*${QS-macros::QS_I64} .....................................................*/ -/*! Output formatted int64_t to the QS record */ -#define QS_I64(width_, data_) \ - (QS_u64_fmt_((uint8_t)(((width_) << 4)) | (uint8_t)QS_I64_T, (data_))) - -/*${QS-macros::QS_U64} .....................................................*/ -/*! Output formatted uint64_t to the QS record */ -#define QS_U64(width_, data_) \ - (QS_u64_fmt_((uint8_t)(((width_) << 4)) | (uint8_t)QS_U64_T, (data_))) - -/*${QS-macros::QS_F32} .....................................................*/ -/*! Output formatted 32-bit floating point number to the QS record */ -#define QS_F32(width_, data_) \ - (QS_f32_fmt_((uint8_t)(((width_) << 4)) | (uint8_t)QS_F32_T, (data_))) - -/*${QS-macros::QS_F64} .....................................................*/ -/*! Output formatted 64-bit floating point number to the QS record */ -#define QS_F64(width_, data_) \ - (QS_f64_fmt_((uint8_t)(((width_) << 4)) | (uint8_t)QS_F64_T, (data_))) - -/*${QS-macros::QS_STR} .....................................................*/ -/*! Output formatted zero-terminated ASCII string to the QS record */ -#define QS_STR(str_) (QS_str_fmt_((str_))) - -/*${QS-macros::QS_MEM} .....................................................*/ -/*! Output formatted memory block of up to 255 bytes to the QS record */ -#define QS_MEM(mem_, size_) (QS_mem_fmt_((mem_), (size_))) - -/*${QS-macros::QS_ENUM} ....................................................*/ -/*! Output formatted enumeration to the QS record */ -#define QS_ENUM(group_, value_) \ - (QS_u8_fmt_((uint8_t)(0x80U | ((group_) << 4U)) | (uint8_t)QS_I8_ENUM_T,\ - (uint8_t)(value_))) - -/*${QS-macros::QS_TIME_PRE_} ...............................................*/ -#if (QS_TIME_SIZE == 4U) -/*! Output time stamp to a QS record (used in predefined -* and application-specific trace records) -*/ -#define QS_TIME_PRE_() (QS_u32_raw_(QS_onGetTime())) -#endif /* (QS_TIME_SIZE == 4U) */ - -/*${QS-macros::QS_TIME_PRE_} ...............................................*/ -#if (QS_TIME_SIZE == 2U) -#define QS_TIME_PRE_() (QS_u16_raw_(QS_onGetTime())) -#endif /* (QS_TIME_SIZE == 2U) */ - -/*${QS-macros::QS_TIME_PRE_} ...............................................*/ -#if (QS_TIME_SIZE == 1U) -#define QS_TIME_PRE_() (QS_u8_raw_(QS_onGetTime())) -#endif /* (QS_TIME_SIZE == 1U) */ - -/*${QS-macros::QS_OBJ} .....................................................*/ -#if (QS_OBJ_PTR_SIZE == 4U) -/*! Output formatted object pointer to the QS record */ -#define QS_OBJ(obj_) (QS_u32_fmt_(QS_OBJ_T, (uint32_t)(obj_))) -#endif /* (QS_OBJ_PTR_SIZE == 4U) */ - -/*${QS-macros::QS_OBJ} .....................................................*/ -#if (QS_OBJ_PTR_SIZE == 2U) -#define QS_OBJ(obj_) (QS_u16_fmt_(QS_OBJ_T, (uint16_t)(obj_))) -#endif /* (QS_OBJ_PTR_SIZE == 2U) */ - -/*${QS-macros::QS_OBJ} .....................................................*/ -#if (QS_OBJ_PTR_SIZE == 1U) -#define QS_OBJ(obj_) (QS_u8_fmt_(QS_OBJ_T, (uint8_t)(obj_))) -#endif /* (QS_OBJ_PTR_SIZE == 1U) */ - -/*${QS-macros::QS_OBJ} .....................................................*/ -#if (QS_OBJ_PTR_SIZE == 8U) -#define QS_OBJ(obj_) (QS_u64_fmt_(QS_OBJ_T, (uint64_t)(obj_))) -#endif /* (QS_OBJ_PTR_SIZE == 8U) */ - -/*${QS-macros::QS_FUN} .....................................................*/ -#if (QS_FUN_PTR_SIZE == 4U) -/* Output formatted function pointer to the QS record */ -#define QS_FUN(fun_) (QS_u32_fmt_(QS_FUN_T, (uint32_t)(fun_))) -#endif /* (QS_FUN_PTR_SIZE == 4U) */ - -/*${QS-macros::QS_FUN} .....................................................*/ -#if (QS_FUN_PTR_SIZE == 2U) -#define QS_FUN(fun_) (QS_u16_fmt_(QS_FUN_T, (uint16_t)(fun_))) -#endif /* (QS_FUN_PTR_SIZE == 2U) */ - -/*${QS-macros::QS_FUN} .....................................................*/ -#if (QS_FUN_PTR_SIZE == 1U) -#define QS_FUN(fun_) (QS_u8_fmt_(QS_FUN_T, (uint8_t)(fun_))) -#endif /* (QS_FUN_PTR_SIZE == 1U) */ - -/*${QS-macros::QS_FUN} .....................................................*/ -#if (QS_FUN_PTR_SIZE == 8U) -#define QS_FUN(fun_) (QS_u64_fmt_(QS_FUN_T, (uint64_t)(fun_))) -#endif /* (QS_FUN_PTR_SIZE == 8U) */ - -/*${QS-macros::QS_SIG} .....................................................*/ -#if (Q_SIGNAL_SIZE == 4U) -/*! Output formatted event signal (of type ::QSignal) and -* the state machine object to the user QS record -*/ -#define QS_SIG(sig_, obj_) \ - QS_u32_fmt_(QS_SIG_T, (sig_)); \ - QS_obj_raw_(obj_) -#endif /* (Q_SIGNAL_SIZE == 4U) */ - -/*${QS-macros::QS_SIG} .....................................................*/ -#if (Q_SIGNAL_SIZE == 2U) -#define QS_SIG(sig_, obj_) \ - QS_u16_fmt_(QS_SIG_T, (sig_)); \ - QS_obj_raw_(obj_) -#endif /* (Q_SIGNAL_SIZE == 2U) */ - -/*${QS-macros::QS_SIG} .....................................................*/ -#if (Q_SIGNAL_SIZE == 1U) -#define QS_SIG(sig_, obj_) \ - QS_u8_fmt_(QS_SIG_T, (sig_)); \ - QS_obj_raw_(obj_) -#endif /* (Q_SIGNAL_SIZE == 1U) */ - -/*${QS-macros::QS_SIG_DICTIONARY} ..........................................*/ -/*! Output QS signal dictionary record -* -* @details -* A signal dictionary record associates the numerical value of the signal -* and the binary address of the state machine that consumes that signal -* with the human-readable name of the signal. -* -* @param[in] sig_ event signal (typically enumerated, e.g. `TIMEOUT_SIG`) -* @param[in] obj_ pointer to the associated state machine object -* (might be `(void*)0` for globally recognized signals) -* -* A signal dictionary entry is associated with both the signal value `sig_` -* and the state machine `obj_`, because signals are required to be unique -* only within a given state machine and therefore the same numerical values -* can represent different signals in different state machines. -* -* For the "global" signals that have the same meaning in many state machines -* (such as globally published signals), you can specify a signal dictionary -* entry with the `obj_` parameter set to `(void*)0`. -* -* The following example shows the definition of signal dictionary entries -* in the initial transition of the Table active object. Please note that -* signals HUNGRY_SIG and DONE_SIG are associated with the Table state -* machine only ("me" `obj_` pointer). The EAT_SIG signal, on the other -* hand, is global (0 `obj_` pointer): -* @include qs_sigDic.c -* -* The following QSpy log example shows the signal dictionary records -* generated from the Table initial transition and subsequent records that -* show human-readable names of the signals: -* @include qs_sigLog.txt -*/ -#define QS_SIG_DICTIONARY(sig_, obj_) \ - (QS_sig_dict_pre_((sig_), (obj_), #sig_)) - -/*${QS-macros::QS_OBJ_DICTIONARY} ..........................................*/ -/*! Output object dictionary record -* -* @details -* An object dictionary record associates the binary address of an object -* in the target's memory with the human-readable name of the object. -* -* @param[in] obj_ pointer to the object (any object) -* -* The following example shows the definition of object dictionary entry -* for the Table active object: -* @include qs_objDic.c -*/ -#define QS_OBJ_DICTIONARY(obj_) \ - (QS_obj_dict_pre_((obj_), #obj_)) - -/*${QS-macros::QS_OBJ_ARR_DICTIONARY} ......................................*/ -/*! Output object-array dictionary record -* -* @details -* An object array dictionary record associates the binary address of the -* object element in the target's memory with the human-readable name -* of the object. -* -* @param[in] obj_ pointer to the object (any object) -* @param[in] idx_ array index -* -* The following example shows the definition of object array dictionary -* for `Philo::inst[n]` and `Philo::inst[n].m_timeEvt`: -* @include qs_objArrDic.c -*/ -#define QS_OBJ_ARR_DICTIONARY(obj_, idx_) \ - (QS_obj_arr_dict_pre_((obj_), (idx_), #obj_)) - -/*${QS-macros::QS_FUN_DICTIONARY} ..........................................*/ -/*! Output function dictionary record -* -* @details -* A function dictionary record associates the binary address of a function -* in the target's memory with the human-readable name of the function. -* -* Providing a function dictionary QS record can vastly improve readability -* of the QS log, because instead of dealing with cryptic machine addresses -* the QSpy host utility can display human-readable function names. -* -* The example from #QS_SIG_DICTIONARY shows the definition of a function -* dictionary. -*/ -#define QS_FUN_DICTIONARY(fun_) \ - (QS_fun_dict_pre_((void (*)(void))(fun_), #fun_)) - -/*${QS-macros::QS_USR_DICTIONARY} ..........................................*/ -/*! Output user QS record dictionary record -* -* @details -* A user QS record dictionary record associates the numerical value of a -* user record with the human-readable identifier. -*/ -#define QS_USR_DICTIONARY(rec_) \ - (QS_usr_dict_pre_((rec_), #rec_)) - -/*${QS-macros::QS_ENUM_DICTIONARY} .........................................*/ -/*! Output enumeration dictionary record -* -* @details -* An enum QS record dictionary record associates the numerical value of -* an enumeration with the human-readable identifier. -*/ -#define QS_ENUM_DICTIONARY(value_, group_) \ - (QS_enum_dict_pre_((value_), (group_), #value_)) - -/*${QS-macros::QF_QS_CRIT_ENTRY} ...........................................*/ -/*! Output the critical section entry record */ -void QF_QS_CRIT_ENTRY(void); - -/*${QS-macros::QF_QS_CRIT_EXIT} ............................................*/ -/*! Output the critical section exit record */ -void QF_QS_CRIT_EXIT(void); - -/*${QS-macros::QF_QS_ISR_ENTRY} ............................................*/ -/*! Output the interrupt entry record */ -void QF_QS_ISR_ENTRY( - uint_fast8_t const isrnest, - uint_fast8_t const prio_); - -/*${QS-macros::QF_QS_ISR_EXIT} .............................................*/ -/*! Output the ISR exit trace record */ -void QF_QS_ISR_EXIT( - uint_fast8_t isrnest, - uint_fast8_t prio); - -/*${QS-macros::QF_QS_ACTION} ...............................................*/ -/*! Execute an action that is only necessary for QS output */ -#define QF_QS_ACTION(act_) (act_) - -/*${QS-macros::QS_EOD} .....................................................*/ -/*! Constant representing End-Of-Data condition returned from the -* QS_getByte() function. -*/ -#define QS_EOD ((uint16_t)0xFFFFU) - -/*${QS-macros::QS_CMD} .....................................................*/ -/*! Constant representing command enumeration group -* in QS_ENUM_DICTIONARY() and QS_ENUM() -* @sa QS_onCommand() -*/ -#define QS_CMD ((uint8_t)7U) - -/*${QS-macros::QS_HEX_FMT} .................................................*/ -/*! Constant representing HEX format for the "width" filed -* in QS_U8(), QS_U16(), QS_U32(), and QS_U64(). -*/ -#define QS_HEX_FMT ((uint8_t)0x0FU) -/*$enddecl${QS-macros} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ - -/*==========================================================================*/ -/* Facilities for QS critical section */ - -/* QS-specific critical section */ -#ifdef QS_CRIT_ENTRY /* separate QS critical section defined? */ - -#ifndef QS_CRIT_STAT_TYPE - #define QS_CRIT_STAT_ - #define QS_CRIT_E_() QS_CRIT_ENTRY(dummy) - #define QS_CRIT_X_() QS_CRIT_EXIT(dummy); QS_REC_DONE() -#else - #define QS_CRIT_STAT_ QS_CRIT_STAT_TYPE critStat_; - #define QS_CRIT_E_() QS_CRIT_ENTRY(critStat_) - #define QS_CRIT_X_() QS_CRIT_EXIT(critStat_); QS_REC_DONE() -#endif /* QS_CRIT_STAT_TYPE */ - -#else /* separate QS critical section not defined--use the QF definition */ - -#ifndef QF_CRIT_STAT_TYPE - /*! This is an internal macro for defining the critical section - * status type. - * @details - * The purpose of this macro is to enable writing the same code for the - * case when critical section status type is defined and when it is not. - * If the macro #QF_CRIT_STAT_TYPE is defined, this internal macro - * provides the definition of the critical section status variable. - * Otherwise this macro is empty. - * @sa #QF_CRIT_STAT_TYPE - */ - #define QS_CRIT_STAT_ - - /*! This is an internal macro for entering a critical section. - * @details - * The purpose of this macro is to enable writing the same code for the - * case when critical section status type is defined and when it is not. - * If the macro #QF_CRIT_STAT_TYPE is defined, this internal macro - * invokes QF_CRIT_ENTRY() passing the key variable as the parameter. - * Otherwise QF_CRIT_ENTRY() is invoked with a dummy parameter. - * @sa QF_CRIT_ENTRY() - */ - #define QS_CRIT_E_() QF_CRIT_ENTRY(dummy) - - /*! This is an internal macro for exiting a critical section. - * @details - * The purpose of this macro is to enable writing the same code for the - * case when critical section status type is defined and when it is not. - * If the macro #QF_CRIT_STAT_TYPE is defined, this internal macro - * invokes QF_CRIT_EXIT() passing the key variable as the parameter. - * Otherwise QF_CRIT_EXIT() is invoked with a dummy parameter. - * @sa QF_CRIT_EXIT() - */ - #define QS_CRIT_X_() QF_CRIT_EXIT(dummy); QS_REC_DONE() - -#elif (!defined QS_CRIT_STAT_) - - #define QS_CRIT_STAT_ QF_CRIT_STAT_TYPE critStat_; - #define QS_CRIT_E_() QF_CRIT_ENTRY(critStat_) - #define QS_CRIT_X_() QF_CRIT_EXIT(critStat_); QS_REC_DONE() - -#endif /* simple unconditional interrupt disabling used */ - -#endif /* separate QS critical section not defined */ - -/*==========================================================================*/ -/* Macros for use in QUTest only */ +//============================================================================ #ifdef Q_UTEST -/*$declare${QUTest} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//$declare${QS::QUTest} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/*${QUTest::QS::TProbe} ....................................................*/ -/*! @brief Test Probe attributes */ +//${QS::QUTest::TProbe} ...................................................... +// @struct TProbe struct QS_TProbe { QSFun addr; uint32_t data; uint8_t idx; }; -/*${QUTest::QS::TestData} ..................................................*/ -/*! @brief QUTest data */ -struct QS_TestData { - struct QS_TProbe tpBuf[16]; /*!< buffer of Test-Probes received so far */ - uint8_t tpNum; /*!< current number of Test-Probes */ - QSTimeCtr testTime; /*!< test time (tick counter) */ -}; - -/*${QUTest::QS::testData} ..................................................*/ -/*! QUTest data */ -extern struct QS_TestData QS_testData; - -/*${QUTest::QS::test_pause_} ...............................................*/ -/*! internal function to pause test and enter the test event loop */ -void QS_test_pause_(void); - -/*${QUTest::QS::getTestProbe_} .............................................*/ -/*! get the test probe data for the given API */ -uint32_t QS_getTestProbe_(QSpyFunPtr const api); - -/*${QUTest::QS::onTestSetup} ...............................................*/ -/*! callback to setup a unit test inside the Target */ +//${QS::QUTest::onTestSetup} ................................................. +//! @static @public @memberof QS void QS_onTestSetup(void); -/*${QUTest::QS::onTestTeardown} ............................................*/ -/*! callback to teardown after a unit test inside the Target */ +//${QS::QUTest::onTestTeardown} .............................................. +//! @static @public @memberof QS void QS_onTestTeardown(void); -/*${QUTest::QS::onTestEvt} .................................................*/ -/*! callback to "massage" the test event before dispatching/posting it */ +//${QS::QUTest::onTestEvt} ................................................... +//! @static @public @memberof QS void QS_onTestEvt(QEvt * e); -/*${QUTest::QS::onTestPost} ................................................*/ -/*! callback to examine an event that is about to be posted */ +//${QS::QUTest::onTestPost} .................................................. +//! @static @public @memberof QS void QS_onTestPost( void const * sender, QActive * recipient, QEvt const * e, bool status); -/*${QUTest::QS::onTestLoop} ................................................*/ -/*! callback to run the test loop */ +//${QS::QUTest::onTestLoop} .................................................. +//! @static @public @memberof QS void QS_onTestLoop(void); +//$enddecl${QS::QUTest} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -/*${QUTest::QUTEST_ON_POST} ................................................*/ -/*! record-ID for posting events */ #define QUTEST_ON_POST 124 -/*$enddecl${QUTest} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*--------------------------------------------------------------------------*/ -/* QP-stub for QUTest -* NOTE: The QP-stub is needed for unit testing QP applications, -* but might NOT be needed for testing QP itself. -*/ -#if Q_UTEST != 0 -/*$declare${QUTest-stub::QS} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//============================================================================ +//! @cond INTERNAL -/*${QUTest-stub::QS::processTestEvts_} .....................................*/ -/*! internal function to process posted events during test */ -void QS_processTestEvts_(void); -/*$enddecl${QUTest-stub::QS} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*$declare${QUTest-stub::QHsmDummy} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${QUTest-stub::QHsmDummy} ................................................*/ -/*! @brief QHsmDummy class -* @class QHsmDummy -* @extends QHsm -* -* @details -* ::QHsmDummy is a test double for the role of "Orthogonal Components" -* HSM objects in QUTest unit testing. -*/ typedef struct { -/* protected: */ - QHsm super; + struct QS_TProbe tpBuf[16]; + uint8_t tpNum; + QSTimeCtr testTime; + QPSet readySet; + QPSet readySet_dis; + uint_fast8_t intLock; +} QSTestAttr; + +extern QSTestAttr QS_tstPriv_; + +void QS_test_pause_(void); +uint32_t QS_getTestProbe_(QSpyFunPtr const api); + +//! @endcond +//============================================================================ + +// QP-stub for QUTest +// NOTE: The QP-stub is needed for unit testing QP applications, +// but might NOT be needed for testing QP itself. +#if (Q_UTEST != 0) + +//$declare${QS::QUTest-stub::QHsmDummy} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${QS::QUTest-stub::QHsmDummy} .............................................. +//! @class QHsmDummy +//! @extends QHsm +typedef struct { +// protected: + QAsm super; } QHsmDummy; -/* public: */ +// public: -/*! Constructor of the QHsmDummy HSM class -* @public @memberof QHsmDummy -*/ +//! @public @memberof QHsmDummy void QHsmDummy_ctor(QHsmDummy * const me); -/*! override for QHsm_init_() -* @private @memberof QHsmDummy -*/ +//! @private @memberof QHsmDummy void QHsmDummy_init_( - QHsm * const me, + QAsm * const me, void const * const par, uint_fast8_t const qs_id); -/*! override for QHsm_dispatch_() -* @private @memberof QHsmDummy -*/ +// private: + +//! @private @memberof QHsmDummy void QHsmDummy_dispatch_( - QHsm * const me, + QAsm * const me, QEvt const * const e, uint_fast8_t const qs_id); -/*$enddecl${QUTest-stub::QHsmDummy} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*$declare${QUTest-stub::QActiveDummy} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//$enddecl${QS::QUTest-stub::QHsmDummy} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +//$declare${QS::QUTest-stub::QActiveDummy} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/*${QUTest-stub::QActiveDummy} .............................................*/ -/*! @brief QActiveDummy Object class -* @class QActiveDummy -* @extends QActive -* -* @details -* QActiveDummy is a test double for the role of collaborating active -* objects in QUTest unit testing. -*/ +//${QS::QUTest-stub::QActiveDummy} ........................................... +//! @class QActiveDummy +//! @extends QActive typedef struct { -/* protected: */ +// protected: QActive super; } QActiveDummy; -/* public: */ +// public: -/*! Constructor of the QActiveDummy Active Object class -* @public @memberof QActiveDummy -*/ +//! @public @memberof QActiveDummy void QActiveDummy_ctor(QActiveDummy * const me); -/*! override for QHsm_init_() -* @private @memberof QActiveDummy -*/ +// private: + +//! @private @memberof QActiveDummy void QActiveDummy_init_( - QHsm * const me, + QAsm * const me, void const * const par, uint_fast8_t const qs_id); -/*! override for QHsm_dispatch_() -* @private @memberof QActiveDummy -*/ +//! @private @memberof QActiveDummy void QActiveDummy_dispatch_( - QHsm * const me, + QAsm * const me, QEvt const * const e, uint_fast8_t const qs_id); -/*! override for QActive_start_() -* @private @memberof QActiveDummy -*/ -void QActiveDummy_start_( - QActive * const me, - QPrioSpec const prioSpec, - QEvt const * * const qSto, - uint_fast16_t const qLen, - void * const stkSto, - uint_fast16_t const stkSize, - void const * const par); - -/*! override for QActive_post_() -* @private @memberof QActiveDummy -*/ -bool QActiveDummy_post_( +//! @private @memberof QActiveDummy +bool QActiveDummy_fakePost_( QActive * const me, QEvt const * const e, uint_fast16_t const margin, void const * const sender); -/*! override for QActive_postLIFO_() -* @private @memberof QActiveDummy -*/ -void QActiveDummy_postLIFO_( +//! @private @memberof QActiveDummy +void QActiveDummy_fakePostLIFO_( QActive * const me, QEvt const * const e); -/*$enddecl${QUTest-stub::QActiveDummy} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -#endif /* Q_UTEST != 0 */ +//$enddecl${QS::QUTest-stub::QActiveDummy} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +#endif // Q_UTEST != 0 -/*! QS macro to define the Test-Probe for a given `fun_` */ #define QS_TEST_PROBE_DEF(fun_) \ uint32_t const qs_tp_ = QS_getTestProbe_((void (*)(void))(fun_)); -/*! QS macro to apply a Test-Probe */ #define QS_TEST_PROBE(code_) \ if (qs_tp_ != 0U) { code_ } -/*! QS macro to apply a Test-Probe */ #define QS_TEST_PROBE_ID(id_, code_) \ if (qs_tp_ == (uint32_t)(id_)) { code_ } -/*! QS macro to pause test execution and enter the test event-loop */ #define QS_TEST_PAUSE() (QS_test_pause_()) -#else /* Q_UTEST not defined */ +#else // Q_UTEST not defined -/* dummy definitions when not building for QUTEST */ +// dummy definitions when not building for QUTEST #define QS_TEST_PROBE_DEF(fun_) #define QS_TEST_PROBE(code_) #define QS_TEST_PROBE_ID(id_, code_) #define QS_TEST_PAUSE() ((void)0) -#endif /* Q_UTEST */ +#endif // Q_UTEST -#endif /* def QP_INC_QS_H_ */ +#endif // QS_H_ diff --git a/include/qs_dummy.h b/include/qs_dummy.h index 37ac26b0..648b0fff 100644 --- a/include/qs_dummy.h +++ b/include/qs_dummy.h @@ -1,52 +1,56 @@ -/*$file${include::qs_dummy.h} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* -* Model: qpc.qm -* File: ${include::qs_dummy.h} -* -* This code has been generated by QM 5.2.4 . -* DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. -* -* This code is covered by the following QP license: -* License # : LicenseRef-QL-dual -* Issued to : Any user of the QP/C real-time embedded framework -* Framework(s) : qpc -* Support ends : 2023-12-31 -* License scope: -* -* Copyright (C) 2005 Quantum Leaps, LLC . -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -*/ -/*$endhead${include::qs_dummy.h} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*! @file -* @brief Dummy definitions of the QS macros that avoid code generation from -* the QS instrumentation. -*/ -#ifndef QP_INC_QS_DUMMY_H_ -#define QP_INC_QS_DUMMY_H_ +//$file${include::qs_dummy.h} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// +// Model: qpc.qm +// File: ${include::qs_dummy.h} +// +// This code has been generated by QM 5.3.0 . +// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. +// +// This code is covered by the following QP license: +// License # : LicenseRef-QL-dual +// Issued to : Any user of the QP/C real-time embedded framework +// Framework(s) : qpc +// Support ends : 2024-12-31 +// License scope: +// +// Copyright (C) 2005 Quantum Leaps, LLC . +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +// +//$endhead${include::qs_dummy.h} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +#ifndef QS_DUMMY_H_ +#define QS_DUMMY_H_ #ifdef Q_SPY #error "Q_SPY must NOT be defined to include qs_dummy.h" #endif +#ifdef Q_UTEST + #error "Q_UTEST must NOT be defined to include qs_dummy.h" +#endif + #define QS_INIT(arg_) ((uint8_t)1U) #define QS_EXIT() ((void)0) #define QS_DUMP() ((void)0) @@ -58,8 +62,8 @@ #define QS_BEGIN_ID(rec_, qs_id_) if (false) { #define QS_END() } -#define QS_BEGIN_NOCRIT(rec_, qs_id_) if (false) { -#define QS_END_NOCRIT() } +#define QS_BEGIN_INCRIT(rec_, qs_id_) if (false) { +#define QS_END_INCRIT() } #define QS_I8(width_, data_) ((void)0) #define QS_U8(width_, data_) ((void)0) @@ -94,16 +98,14 @@ #define QS_OUTPUT() ((void)0) #define QS_RX_INPUT() ((void)0) +#define QS_ONLY(code_) ((void)0) -/*==========================================================================*/ -/* internal QS macros used only in the QP components */ - +//============================================================================ +// interface used only for internal implementation, but not in applications #ifdef QP_IMPL - /* predefined QS trace records */ + // predefined QS trace records #define QS_BEGIN_PRE_(rec_, qs_id_) if (false) { - #define QS_END_PRE_() } - #define QS_BEGIN_NOCRIT_PRE_(rec_, qs_id_) if (false) { - #define QS_END_NOCRIT_PRE_() } + #define QS_END_PRE_() } #define QS_U8_PRE_(data_) ((void)0) #define QS_2U8_PRE_(data1_, data2_) ((void)0) #define QS_U16_PRE_(data_) ((void)0) @@ -118,12 +120,17 @@ #define QS_MPS_PRE_(size_) ((void)0) #define QS_TEC_PRE_(ctr_) ((void)0) - #define QS_CRIT_STAT_ - #define QF_QS_CRIT_ENTRY() ((void)0) - #define QF_QS_CRIT_EXIT() ((void)0) - #define QF_QS_ISR_ENTRY(isrnest_, prio_) ((void)0) - #define QF_QS_ISR_EXIT(isrnest_, prio_) ((void)0) - #define QF_QS_ACTION(act_) ((void)0) -#endif /* QP_IMPL */ + #define QS_CRIT_STAT + #define QS_CRIT_ENTRY() ((void)0) + #define QS_CRIT_EXIT() ((void)0) -#endif /* QP_INC_QS_DUMMY_H_ */ + #define QS_MEM_SYS() ((void)0) + #define QS_MEM_APP() ((void)0) + + #define QS_TR_CRIT_ENTRY() ((void)0) + #define QS_TR_CRIT_EXIT() ((void)0) + #define QS_TR_ISR_ENTRY(isrnest_, prio_) ((void)0) + #define QS_TR_ISR_EXIT(isrnest_, prio_) ((void)0) +#endif // QP_IMPL + +#endif // QS_DUMMY_H_ diff --git a/include/qs_pkg.h b/include/qs_pkg.h index 13dbf974..71bdcd4b 100644 --- a/include/qs_pkg.h +++ b/include/qs_pkg.h @@ -1,156 +1,93 @@ -/*$file${include::qs_pkg.h} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* -* Model: qpc.qm -* File: ${include::qs_pkg.h} -* -* This code has been generated by QM 5.2.4 . -* DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. -* -* This code is covered by the following QP license: -* License # : LicenseRef-QL-dual -* Issued to : Any user of the QP/C real-time embedded framework -* Framework(s) : qpc -* Support ends : 2023-12-31 -* License scope: -* -* Copyright (C) 2005 Quantum Leaps, LLC . -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -*/ -/*$endhead${include::qs_pkg.h} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*! @file -* @brief Internal (package scope) QS/C interface. -*/ -#ifndef QP_INC_QS_PKG_H_ -#define QP_INC_QS_PKG_H_ +//$file${include::qs_pkg.h} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// +// Model: qpc.qm +// File: ${include::qs_pkg.h} +// +// This code has been generated by QM 5.3.0 . +// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. +// +// This code is covered by the following QP license: +// License # : LicenseRef-QL-dual +// Issued to : Any user of the QP/C real-time embedded framework +// Framework(s) : qpc +// Support ends : 2024-12-31 +// License scope: +// +// Copyright (C) 2005 Quantum Leaps, LLC . +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +// +//$endhead${include::qs_pkg.h} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +#ifndef QS_PKG_H_ +#define QS_PKG_H_ -/*==========================================================================*/ +//============================================================================ +//! @cond INTERNAL -/*! QS received record types (RX channel) -* @details -* This enumeration specifies the record types for the QS receive channel -*/ +//! QS received record types (RX channel) enum QSpyRxRecords { - QS_RX_INFO, /*!< query Target info (ver, config, tstamp) */ - QS_RX_COMMAND, /*!< execute a user-defined command in the Target */ - QS_RX_RESET, /*!< reset the Target */ - QS_RX_TICK, /*!< call QTIMEEVT_TICK_X() in the Target */ - QS_RX_PEEK, /*!< peek Target memory */ - QS_RX_POKE, /*!< poke Target memory */ - QS_RX_FILL, /*!< fill Target memory */ - QS_RX_TEST_SETUP, /*!< test setup */ - QS_RX_TEST_TEARDOWN, /*!< test teardown */ - QS_RX_TEST_PROBE, /*!< set a Test-Probe in the Target */ - QS_RX_GLB_FILTER, /*!< set global filters in the Target */ - QS_RX_LOC_FILTER, /*!< set local filters in the Target */ - QS_RX_AO_FILTER, /*!< set local AO filter in the Target */ - QS_RX_CURR_OBJ, /*!< set the "current-object" in the Target */ - QS_RX_TEST_CONTINUE, /*!< continue a test after QS_TEST_PAUSE() */ - QS_RX_QUERY_CURR, /*!< query the "current object" in the Target */ - QS_RX_EVENT /*!< inject an event to the Target */ + QS_RX_INFO, //!< query Target info (ver, config, tstamp) + QS_RX_COMMAND, //!< execute a user-defined command in the Target + QS_RX_RESET, //!< reset the Target + QS_RX_TICK, //!< call system clock tick in the Target + QS_RX_PEEK, //!< peek Target memory + QS_RX_POKE, //!< poke Target memory + QS_RX_FILL, //!< fill Target memory + QS_RX_TEST_SETUP, //!< test setup + QS_RX_TEST_TEARDOWN, //!< test teardown + QS_RX_TEST_PROBE, //!< set a Test-Probe in the Target + QS_RX_GLB_FILTER, //!< set global filters in the Target + QS_RX_LOC_FILTER, //!< set local filters in the Target + QS_RX_AO_FILTER, //!< set local AO filter in the Target + QS_RX_CURR_OBJ, //!< set the "current-object" in the Target + QS_RX_TEST_CONTINUE, //!< continue a test after QS_TEST_PAUSE() + QS_RX_QUERY_CURR, //!< query the "current object" in the Target + QS_RX_EVENT //!< inject an event to the Target }; -/*==========================================================================*/ -/*! Frame character of the QS output protocol */ -#define QS_FRAME (0x7EU) +//---------------------------------------------------------------------------- +#define QS_FRAME 0x7EU +#define QS_ESC 0x7DU +#define QS_ESC_XOR 0x20U +#define QS_GOOD_CHKSUM 0xFFU -/*! Escape character of the QS output protocol */ -#define QS_ESC (0x7DU) - -/*! The expected checksum value over a correct QS record */ -#define QS_GOOD_CHKSUM (0xFFU) - -/*! Escape modifier of the QS output protocol */ -/** -* @details -* The escaped byte is XOR-ed with the escape modifier before it is inserted -* into the QS buffer. -*/ -#define QS_ESC_XOR (0x20U) - -/*==========================================================================*/ -/*! Internal QS macro to begin a predefined QS record with -* entering critical section. -* -* @note This macro is intended to use only inside QP components and NOT -* at the application level. -* @sa QS_BEGIN_ID() -*/ -#define QS_BEGIN_PRE_(rec_, qs_id_) \ - if (QS_GLB_CHECK_(rec_) && QS_LOC_CHECK_(qs_id_)) { \ - QS_CRIT_E_(); \ - QS_beginRec_((uint_fast8_t)(rec_)); - -/*! Internal QS macro to end a predefined QS record with -* exiting critical section. -* -* @note This macro is intended to use only inside QP components and NOT -* at the application level. -* @sa QS_END() -*/ -#define QS_END_PRE_() \ - QS_endRec_(); \ - QS_CRIT_X_(); \ - } - -/*! Internal macro to begin a predefined QS record without -* entering critical section. -* -* @note This macro is intended to use only inside QP components and NOT -* at the application level. -* @sa QS_BEGIN_NOCRIT() -*/ -#define QS_BEGIN_NOCRIT_PRE_(rec_, qs_id_) \ +//---------------------------------------------------------------------------- +#define QS_BEGIN_PRE_(rec_, qs_id_) \ if (QS_GLB_CHECK_(rec_) && QS_LOC_CHECK_(qs_id_)) { \ QS_beginRec_((uint_fast8_t)(rec_)); +#define QS_END_PRE_() QS_endRec_(); } -/*! Internal QS macro to end a predefined QS record without -* exiting critical section -* -* @note This macro is intended to use only inside QP components and NOT -* at the application level. @sa #QS_END_NOCRIT -*/ -#define QS_END_NOCRIT_PRE_() QS_endRec_(); } - -/*! Internal QS macro to output a predefined uint8_t data element */ #define QS_U8_PRE_(data_) (QS_u8_raw_((uint8_t)(data_))) - -/*! Internal QS macro to output 2 predefined uint8_t data elements */ #define QS_2U8_PRE_(data1_, data2_) \ (QS_2u8_raw_((uint8_t)(data1_), (uint8_t)(data2_))) - -/*! Internal QS macro to output an predefined uint16_t data element */ #define QS_U16_PRE_(data_) (QS_u16_raw_((uint16_t)(data_))) - -/*! Internal QS macro to output a predefined uint32_t data element */ #define QS_U32_PRE_(data_) (QS_u32_raw_((uint32_t)(data_))) - -/*! Internal QS macro to output a predefined zero-terminated string element */ #define QS_STR_PRE_(msg_) (QS_str_raw_((msg_))) +#define QS_OBJ_PRE_(obj_) (QS_obj_raw_(obj_)) #if (!defined Q_SIGNAL_SIZE || (Q_SIGNAL_SIZE == 1U)) - /*! Internal macro to output an unformatted event signal data element */ - /** - * @note the size of the pointer depends on the macro #Q_SIGNAL_SIZE. - */ #define QS_SIG_PRE_(sig_) (QS_u8_raw_((uint8_t)sig_)) #elif (Q_SIGNAL_SIZE == 2U) #define QS_SIG_PRE_(sig_) (QS_u16_raw_((uint16_t)sig_)) @@ -158,97 +95,58 @@ enum QSpyRxRecords { #define QS_SIG_PRE_(sig_) (QS_u32_raw_((uint32_t)sig_)) #endif -#define QS_OBJ_PRE_(obj_) (QS_obj_raw_(obj_)) - -#if (!defined QS_FUN_PTR_SIZE || (QS_FUN_PTR_SIZE == 1U)) - #define QS_FUN_PRE_(fun_) (QS_u8_raw_((uint8_t)(fun_))) -#elif (QS_FUN_PTR_SIZE == 2U) +#if (!defined QS_FUN_PTR_SIZE || (QS_FUN_PTR_SIZE == 2U)) #define QS_FUN_PRE_(fun_) (QS_u16_raw_((uint16_t)(fun_))) #elif (QS_FUN_PTR_SIZE == 4U) #define QS_FUN_PRE_(fun_) (QS_u32_raw_((uint32_t)(fun_))) #elif (QS_FUN_PTR_SIZE == 8U) #define QS_FUN_PRE_(fun_) (QS_u64_raw_((uint64_t)(fun_))) #else - /*! Internal macro to output an unformatted function pointer */ - /** @note the size of the pointer depends on the macro #QS_FUN_PTR_SIZE. - * If the size is not defined the size of pointer is assumed 4-bytes. - */ #define QS_FUN_PRE_(fun_) (QS_u32_raw_((uint32_t)(fun_))) #endif -/*==========================================================================*/ +//---------------------------------------------------------------------------- #if (!defined QF_EQUEUE_CTR_SIZE || (QF_EQUEUE_CTR_SIZE == 1U)) - - /*! Internal QS macro to output an unformatted event queue counter - * data element. */ - /** - * @note the counter size depends on the macro #QF_EQUEUE_CTR_SIZE. - */ - #define QS_EQC_PRE_(ctr_) QS_u8_raw_((uint8_t)(ctr_)) + #define QS_EQC_PRE_(ctr_) QS_u8_raw_((uint8_t)(ctr_)) #elif (QF_EQUEUE_CTR_SIZE == 2U) - #define QS_EQC_PRE_(ctr_) QS_u16_raw_((uint16_t)(ctr_)) + #define QS_EQC_PRE_(ctr_) QS_u16_raw_((uint16_t)(ctr_)) #elif (QF_EQUEUE_CTR_SIZE == 4U) - #define QS_EQC_PRE_(ctr_) QS_u32_raw_((uint32_t)(ctr_)) + #define QS_EQC_PRE_(ctr_) QS_u32_raw_((uint32_t)(ctr_)) #endif #if (!defined QF_EVENT_SIZ_SIZE || (QF_EVENT_SIZ_SIZE == 1U)) - - /*! Internal QS macro to output an unformatted event size - * data element. */ - /** - * @note the event size depends on the macro #QF_EVENT_SIZ_SIZE. - */ - #define QS_EVS_PRE_(size_) QS_u8_raw_((uint8_t)(size_)) + #define QS_EVS_PRE_(size_) QS_u8_raw_((uint8_t)(size_)) #elif (QF_EVENT_SIZ_SIZE == 2U) - #define QS_EVS_PRE_(size_) QS_u16_raw_((uint16_t)(size_)) + #define QS_EVS_PRE_(size_) QS_u16_raw_((uint16_t)(size_)) #elif (QF_EVENT_SIZ_SIZE == 4U) - #define QS_EVS_PRE_(size_) QS_u32_raw_((uint32_t)(size_)) + #define QS_EVS_PRE_(size_) QS_u32_raw_((uint32_t)(size_)) #endif #if (!defined QF_MPOOL_SIZ_SIZE || (QF_MPOOL_SIZ_SIZE == 1U)) - - /*! Internal QS macro to output an unformatted memory pool - * block-size data element */ - /** - * @note the block-size depends on the macro #QF_MPOOL_SIZ_SIZE. - */ - #define QS_MPS_PRE_(size_) QS_u8_raw_((uint8_t)(size_)) + #define QS_MPS_PRE_(size_) QS_u8_raw_((uint8_t)(size_)) #elif (QF_MPOOL_SIZ_SIZE == 2U) - #define QS_MPS_PRE_(size_) QS_u16_raw_((uint16_t)(size_)) + #define QS_MPS_PRE_(size_) QS_u16_raw_((uint16_t)(size_)) #elif (QF_MPOOL_SIZ_SIZE == 4U) - #define QS_MPS_PRE_(size_) QS_u32_raw_((uint32_t)(size_)) + #define QS_MPS_PRE_(size_) QS_u32_raw_((uint32_t)(size_)) #endif #if (!defined QF_MPOOL_CTR_SIZE || (QF_MPOOL_CTR_SIZE == 1U)) - - /*! Internal QS macro to output an unformatted memory pool - * block-counter data element. */ - /** - * @note the counter size depends on the macro #QF_MPOOL_CTR_SIZE. - */ - #define QS_MPC_PRE_(ctr_) QS_u8_raw_((uint8_t)(ctr_)) + #define QS_MPC_PRE_(ctr_) QS_u8_raw_((uint8_t)(ctr_)) #elif (QF_MPOOL_CTR_SIZE == 2U) - #define QS_MPC_PRE_(ctr_) QS_u16_raw_((uint16_t)(ctr_)) + #define QS_MPC_PRE_(ctr_) QS_u16_raw_((uint16_t)(ctr_)) #elif (QF_MPOOL_CTR_SIZE == 4U) - #define QS_MPC_PRE_(ctr_) QS_u32_raw_((uint16_t)(ctr_)) + #define QS_MPC_PRE_(ctr_) QS_u32_raw_((uint16_t)(ctr_)) #endif #if (!defined QF_TIMEEVT_CTR_SIZE || (QF_TIMEEVT_CTR_SIZE == 1U)) - - /*! Internal QS macro to output an unformatted time event - * tick-counter data element */ - /** - * @note the counter size depends on the macro #QF_TIMEEVT_CTR_SIZE. - */ - #define QS_TEC_PRE_(ctr_) QS_u8_raw_((uint8_t)(ctr_)) + #define QS_TEC_PRE_(ctr_) QS_u8_raw_((uint8_t)(ctr_)) #elif (QF_TIMEEVT_CTR_SIZE == 2U) - #define QS_TEC_PRE_(ctr_) QS_u16_raw_((uint16_t)(ctr_)) + #define QS_TEC_PRE_(ctr_) QS_u16_raw_((uint16_t)(ctr_)) #elif (QF_TIMEEVT_CTR_SIZE == 4U) - #define QS_TEC_PRE_(ctr_) QS_u32_raw_((uint32_t)(ctr_)) + #define QS_TEC_PRE_(ctr_) QS_u32_raw_((uint32_t)(ctr_)) #endif -/*==========================================================================*/ -/*! Internal QS macro to insert an un-escaped byte into the QS buffer */ +//---------------------------------------------------------------------------- #define QS_INSERT_BYTE_(b_) \ buf[head] = (b_); \ ++head; \ @@ -256,7 +154,6 @@ enum QSpyRxRecords { head = 0U; \ } -/*! Internal QS macro to insert an escaped byte into the QS buffer */ #define QS_INSERT_ESC_BYTE_(b_) \ chksum = (uint8_t)(chksum + (b_)); \ if (((b_) != QS_FRAME) && ((b_) != QS_ESC)) { \ @@ -268,4 +165,12 @@ enum QSpyRxRecords { ++QS_priv_.used; \ } -#endif /* QP_INC_QS_PKG_H_ */ +//---------------------------------------------------------------------------- +#if (defined Q_UTEST) && (Q_UTEST != 0) +void QS_processTestEvts_(void); +#endif // Q_UTEST != 0 + +//! @endcond +//============================================================================ + +#endif // QS_PKG_H_ diff --git a/include/qsafe.h b/include/qsafe.h new file mode 100644 index 00000000..39ebb11c --- /dev/null +++ b/include/qsafe.h @@ -0,0 +1,181 @@ +//$file${include::qsafe.h} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// +// Model: qpc.qm +// File: ${include::qsafe.h} +// +// This code has been generated by QM 5.3.0 . +// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. +// +// This code is covered by the following QP license: +// License # : LicenseRef-QL-dual +// Issued to : Any user of the QP/C real-time embedded framework +// Framework(s) : qpc +// Support ends : 2024-12-31 +// License scope: +// +// Copyright (C) 2005 Quantum Leaps, LLC . +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +// +//$endhead${include::qsafe.h} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +#ifndef QSAFE_H_ +#define QSAFE_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +// QF-FuSa enabled =========================================================== +#ifndef Q_UNSAFE + +#ifndef QF_CRIT_STAT +#define QF_CRIT_STAT +#endif + +#ifndef QF_CRIT_ENTRY +#define QF_CRIT_ENTRY() ((void)0) +#endif + +#ifndef QF_CRIT_EXIT +#define QF_CRIT_EXIT() ((void)0) +#endif + +//$declare${QP-FuSa::enabled} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${QP-FuSa::enabled::Q_DEFINE_THIS_MODULE} .................................. +#define Q_DEFINE_THIS_MODULE(name_) \ + static char const Q_this_module_[] = name_; + +//${QP-FuSa::enabled::Q_ASSERT_INCRIT} ....................................... +#define Q_ASSERT_INCRIT(id_, expr_) \ + ((expr_) ? ((void)0) : Q_onError(&Q_this_module_[0], (id_))) + +//${QP-FuSa::enabled::Q_ERROR_INCRIT} ........................................ +#define Q_ERROR_INCRIT(id_) \ + (Q_onError(&Q_this_module_[0], (id_))) + +//${QP-FuSa::enabled::Q_ASSERT_ID} ........................................... +#define Q_ASSERT_ID(id_, expr_) do { \ + QF_CRIT_STAT \ + QF_CRIT_ENTRY(); \ + (expr_) ? ((void)0) : Q_onError(&Q_this_module_[0], (id_)); \ + QF_CRIT_EXIT(); \ +} while (false) + +//${QP-FuSa::enabled::Q_ERROR_ID} ............................................ +#define Q_ERROR_ID(id_) do { \ + QF_CRIT_STAT \ + QF_CRIT_ENTRY(); \ + Q_onError(&Q_this_module_[0], (id_)); \ + QF_CRIT_EXIT(); \ +} while (false) +//$enddecl${QP-FuSa::enabled} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +// QF-FuSa disabled ========================================================== +#else +//$declare${QP-FuSa::disabled} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${QP-FuSa::disabled::Q_DEFINE_THIS_MODULE} ................................. +#define Q_DEFINE_THIS_MODULE(name_) + +//${QP-FuSa::disabled::Q_ASSERT_INCRIT} ...................................... +#define Q_ASSERT_INCRIT(id_, expr_) ((void)0) + +//${QP-FuSa::disabled::Q_ERROR_INCRIT} ....................................... +#define Q_ERROR_INCRIT(id_) ((void)0) + +//${QP-FuSa::disabled::Q_ASSERT_ID} .......................................... +#define Q_ASSERT_ID(id_, expr_) ((void)0) + +//${QP-FuSa::disabled::Q_ERROR_ID} ........................................... +#define Q_ERROR_ID(id_) ((void)0) +//$enddecl${QP-FuSa::disabled} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +#endif + +//============================================================================ +//$declare1${QP-FuSa} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${QP-FuSa::Q_DEFINE_THIS_FILE} ............................................. +#define Q_DEFINE_THIS_FILE Q_DEFINE_THIS_MODULE(__FILE__) + +//${QP-FuSa::Q_ASSERT} ....................................................... +#define Q_ASSERT(expr_) Q_ASSERT_ID(__LINE__, (expr_)) + +//${QP-FuSa::Q_ERROR} ........................................................ +#define Q_ERROR() Q_ERROR_ID(__LINE__) + +//${QP-FuSa::Q_REQUIRE_ID} ................................................... +#define Q_REQUIRE_ID(id_, expr_) Q_ASSERT_ID((id_), (expr_)) + +//${QP-FuSa::Q_REQUIRE} ...................................................... +#define Q_REQUIRE(expr_) Q_ASSERT(expr_) + +//${QP-FuSa::Q_REQUIRE_INCRIT} ............................................... +#define Q_REQUIRE_INCRIT(id_, expr_) Q_ASSERT_INCRIT((id_), (expr_)) + +//${QP-FuSa::Q_ENSURE_ID} .................................................... +#define Q_ENSURE_ID(id_, expr_) Q_ASSERT_ID((id_), (expr_)) + +//${QP-FuSa::Q_ENSURE} ....................................................... +#define Q_ENSURE(expr_) Q_ASSERT(expr_) + +//${QP-FuSa::Q_ENSURE_INCRIT} ................................................ +#define Q_ENSURE_INCRIT(id_, expr_) Q_ASSERT_INCRIT((id_), (expr_)) + +//${QP-FuSa::Q_INVARIANT_ID} ................................................. +#define Q_INVARIANT_ID(id_, expr_) Q_ASSERT_ID((id_), (expr_)) + +//${QP-FuSa::Q_INVARIANT} .................................................... +#define Q_INVARIANT(expr_) Q_ASSERT(expr_) + +//${QP-FuSa::Q_ASSERT_STATIC} ................................................ +#define Q_ASSERT_STATIC(expr_) extern char Q_static_assert_[(expr_) ? 1 : -1] + +//${QP-FuSa::Q_NORETURN} ..................................................... +#ifndef Q_NORETURN +#define Q_NORETURN _Noreturn void +#endif // ndef Q_NORETURN + +//${QP-FuSa::int_t} .......................................................... +#ifndef QP_VERSION +typedef int int_t; +#endif // ndef QP_VERSION + +//${QP-FuSa::Q_onError} ...................................................... +Q_NORETURN Q_onError( + char const * const module, + int_t const id); + +//${QP-FuSa::Q_DIM} .......................................................... +#ifndef QP_VERSION +#define Q_DIM(array_) (sizeof(array_) / sizeof((array_)[0U])) +#endif // ndef QP_VERSION +//$enddecl${QP-FuSa} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +#ifdef __cplusplus +} +#endif + +#endif // QSAFE_H_ diff --git a/include/qstamp.c b/include/qstamp.c deleted file mode 100644 index dd69a217..00000000 --- a/include/qstamp.c +++ /dev/null @@ -1,34 +0,0 @@ -/*============================================================================ -* QP/C Real-Time Embedded Framework (RTEF) -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! @file -* @brief Application build time-stamp -* @deprecated -* File `include/qstamp.c` is kept only for backwards compatibility. -* Instead, please use file `src/qs/qstamp.c`. -*/ -#include "qstamp.h" - -char const Q_BUILD_DATE[12] = __DATE__; -char const Q_BUILD_TIME[9] = __TIME__; diff --git a/include/qstamp.h b/include/qstamp.h index 1185b280..5f9a925a 100644 --- a/include/qstamp.h +++ b/include/qstamp.h @@ -1,48 +1,49 @@ -/*$file${include::qstamp.h} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* -* Model: qpc.qm -* File: ${include::qstamp.h} -* -* This code has been generated by QM 5.2.4 . -* DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. -* -* This code is covered by the following QP license: -* License # : LicenseRef-QL-dual -* Issued to : Any user of the QP/C real-time embedded framework -* Framework(s) : qpc -* Support ends : 2023-12-31 -* License scope: -* -* Copyright (C) 2005 Quantum Leaps, LLC . -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -*/ -/*$endhead${include::qstamp.h} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*! @file -* @brief Application build time-stamp interface -*/ -#ifndef QP_INC_QSTAMP_H_ -#define QP_INC_QSTAMP_H_ +//$file${include::qstamp.h} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// +// Model: qpc.qm +// File: ${include::qstamp.h} +// +// This code has been generated by QM 5.3.0 . +// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. +// +// This code is covered by the following QP license: +// License # : LicenseRef-QL-dual +// Issued to : Any user of the QP/C real-time embedded framework +// Framework(s) : qpc +// Support ends : 2024-12-31 +// License scope: +// +// Copyright (C) 2005 Quantum Leaps, LLC . +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +// +//$endhead${include::qstamp.h} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +#ifndef QSTAMP_H_ +#define QSTAMP_H_ extern char const Q_BUILD_DATE[12]; extern char const Q_BUILD_TIME[9]; -#endif /* QP_INC_QSTAMP_H_ */ +#endif // QSTAMP_H_ diff --git a/include/qv.h b/include/qv.h index 53034693..8f228fb3 100644 --- a/include/qv.h +++ b/include/qv.h @@ -1,142 +1,138 @@ -/*$file${include::qv.h} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* -* Model: qpc.qm -* File: ${include::qv.h} -* -* This code has been generated by QM 5.2.4 . -* DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. -* -* This code is covered by the following QP license: -* License # : LicenseRef-QL-dual -* Issued to : Any user of the QP/C real-time embedded framework -* Framework(s) : qpc -* Support ends : 2023-12-31 -* License scope: -* -* Copyright (C) 2005 Quantum Leaps, LLC . -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -*/ -/*$endhead${include::qv.h} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*! @file -* @brief QV/C (cooperative "Vanilla" kernel) platform-independent -* public interface -*/ -#ifndef QP_INC_QV_H_ -#define QP_INC_QV_H_ +//$file${include::qv.h} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// +// Model: qpc.qm +// File: ${include::qv.h} +// +// This code has been generated by QM 5.3.0 . +// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. +// +// This code is covered by the following QP license: +// License # : LicenseRef-QL-dual +// Issued to : Any user of the QP/C real-time embedded framework +// Framework(s) : qpc +// Support ends : 2024-12-31 +// License scope: +// +// Copyright (C) 2005 Quantum Leaps, LLC . +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +// +//$endhead${include::qv.h} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +#ifndef QV_H_ +#define QV_H_ -/*==========================================================================*/ -/* QF customization for QV -- data members of the QActive class... */ +//$declare${QV::QV} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/* QV event-queue used for AOs */ -#define QF_EQUEUE_TYPE QEQueue +//${QV::QV} .................................................................. +// @class QV +typedef struct QV { + //! @cond INTERNAL + uint8_t dummy; + //! @endcond +} QV; +//$enddecl${QV::QV} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -/*==========================================================================*/ -#include "qequeue.h" /* QV kernel uses the native QP event queue */ -#include "qmpool.h" /* QV kernel uses the native QP memory pool */ -#include "qf.h" /* QF framework integrates directly with QV */ +//$declare${QV::QV-base} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${QV::QV-base::Attr} ....................................................... +//! @class QV_Attr +typedef struct { +// public: + + //! @memberof QV_Attr + QPSet readySet; + +#ifndef Q_UNSAFE + //! @memberof QV_Attr + QPSet readySet_dis; +#endif // ndef Q_UNSAFE +} QV_Attr; + +//${QV::QV-base::priv_} ...................................................... +//! @static @private @memberof QV +extern QV_Attr QV_priv_; + +//${QV::QV-base::onIdle} ..................................................... +//! @static @public @memberof QV +void QV_onIdle(void); +//$enddecl${QV::QV-base} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ //============================================================================ -/*$declare${QV::QV-base} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${QV::QV-base::Attr} .....................................................*/ -/*! @brief QV cooperative kernel -* @class QV -*/ -typedef struct QV_Attr { - uint8_t dummy; /*< dummy attribute */ -} QV; - -/*${QV::QV-base::onIdle} ...................................................*/ -/*! QV idle callback (customized in BSPs) -* @static @public @memberof QV -* -* @details -* QV_onIdle() is called by the cooperative QV kernel (from QF_run()) when -* the scheduler detects that no events are available for active objects -* (the idle condition). This callback gives the application an opportunity -* to enter a power-saving CPU mode, or perform some other idle processing -* (such as QS software tracing output). -* -* @note -* QV_onIdle() is invoked with interrupts **DISABLED** because the idle -* condition can be asynchronously changed at any time by an interrupt. -* QV_onIdle() MUST enable the interrupts internally, but not before -* putting the CPU into the low-power mode. (Ideally, enabling interrupts and -* low-power mode should happen atomically). At the very least, the function -* MUST enable interrupts, otherwise interrupts will remain disabled -* permanently. -*/ -void QV_onIdle(void); -/*$enddecl${QV::QV-base} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ - -/*==========================================================================*/ -/* interface used only inside QF, but not in applications */ +// interface used only for internal implementation, but not in applications #ifdef QP_IMPL -/* QV-specific scheduler locking and event queue... */ -/*$declare${QV-impl} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/*${QV-impl::QF_SCHED_STAT_} ...............................................*/ -/*! QV scheduler lock status (not needed in QV) */ +//$declare${QV-impl} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${QV-impl::QF_SCHED_STAT_} ................................................. #define QF_SCHED_STAT_ -/*${QV-impl::QF_SCHED_LOCK_} ...............................................*/ -/*! QV scheduler locking (not needed in QV) */ +//${QV-impl::QF_SCHED_LOCK_} ................................................. #define QF_SCHED_LOCK_(dummy) ((void)0) -/*${QV-impl::QF_SCHED_UNLOCK_} .............................................*/ -/*! QV scheduler unlocking (not needed in QV) */ +//${QV-impl::QF_SCHED_UNLOCK_} ............................................... #define QF_SCHED_UNLOCK_() ((void)0) -/*${QV-impl::QACTIVE_EQUEUE_WAIT_} .........................................*/ +//${QV-impl::QACTIVE_EQUEUE_WAIT_} ........................................... #define QACTIVE_EQUEUE_WAIT_(me_) \ - Q_ASSERT_ID(0, (me_)->eQueue.frontEvt != (QEvt *)0) + Q_ASSERT_INCRIT(310, (me_)->eQueue.frontEvt != (QEvt *)0) -/*${QV-impl::QACTIVE_EQUEUE_SIGNAL_} .......................................*/ -/*! QV native event queue signaling */ +//${QV-impl::QACTIVE_EQUEUE_SIGNAL_} ......................................... +#ifndef Q_UNSAFE #define QACTIVE_EQUEUE_SIGNAL_(me_) \ - QPSet_insert(&QF_readySet_, (uint_fast8_t)(me_)->prio) -/*$enddecl${QV-impl} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ + QPSet_insert(&QV_priv_.readySet, (uint_fast8_t)(me_)->prio); \ + QPSet_update_(&QV_priv_.readySet, &QV_priv_.readySet_dis) +#endif // ndef Q_UNSAFE -/* Native QF event pool operations... */ -/*$declare${QF-QMPool-impl} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//${QV-impl::QACTIVE_EQUEUE_SIGNAL_} ......................................... +#ifdef Q_UNSAFE +#define QACTIVE_EQUEUE_SIGNAL_(me_) \ + QPSet_insert(&QV_priv_.readySet, (uint_fast8_t)(me_)->prio) +#endif // def Q_UNSAFE +//$enddecl${QV-impl} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -/*${QF-QMPool-impl::QF_EPOOL_TYPE_} ........................................*/ +//$declare${QF_EPOOL-impl} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${QF_EPOOL-impl::QF_EPOOL_TYPE_} ........................................... #define QF_EPOOL_TYPE_ QMPool -/*${QF-QMPool-impl::QF_EPOOL_INIT_} ........................................*/ +//${QF_EPOOL-impl::QF_EPOOL_INIT_} ........................................... #define QF_EPOOL_INIT_(p_, poolSto_, poolSize_, evtSize_) \ (QMPool_init(&(p_), (poolSto_), (poolSize_), (evtSize_))) -/*${QF-QMPool-impl::QF_EPOOL_EVENT_SIZE_} ..................................*/ +//${QF_EPOOL-impl::QF_EPOOL_EVENT_SIZE_} ..................................... #define QF_EPOOL_EVENT_SIZE_(p_) ((uint_fast16_t)(p_).blockSize) -/*${QF-QMPool-impl::QF_EPOOL_GET_} .........................................*/ +//${QF_EPOOL-impl::QF_EPOOL_GET_} ............................................ #define QF_EPOOL_GET_(p_, e_, m_, qs_id_) \ ((e_) = (QEvt *)QMPool_get(&(p_), (m_), (qs_id_))) -/*${QF-QMPool-impl::QF_EPOOL_PUT_} .........................................*/ +//${QF_EPOOL-impl::QF_EPOOL_PUT_} ............................................ #define QF_EPOOL_PUT_(p_, e_, qs_id_) \ (QMPool_put(&(p_), (e_), (qs_id_))) -/*$enddecl${QF-QMPool-impl} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -#endif /* QP_IMPL */ +//$enddecl${QF_EPOOL-impl} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -#endif /* QP_INC_QV_H_ */ +#endif // QP_IMPL + +#endif // QV_H_ diff --git a/include/qxk.h b/include/qxk.h index a8f3af6b..f82b8b7b 100644 --- a/include/qxk.h +++ b/include/qxk.h @@ -1,903 +1,293 @@ -/*$file${include::qxk.h} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* -* Model: qpc.qm -* File: ${include::qxk.h} -* -* This code has been generated by QM 5.2.4 . -* DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. -* -* This code is covered by the following QP license: -* License # : LicenseRef-QL-dual -* Issued to : Any user of the QP/C real-time embedded framework -* Framework(s) : qpc -* Support ends : 2023-12-31 -* License scope: -* -* Copyright (C) 2005 Quantum Leaps, LLC . -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -*/ -/*$endhead${include::qxk.h} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*! @file -* @brief QXK/C (preemptive dual-mode kernel) platform-independent -* public interface. -*/ -#ifndef QP_INC_QXK_H_ -#define QP_INC_QXK_H_ +//$file${include::qxk.h} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// +// Model: qpc.qm +// File: ${include::qxk.h} +// +// This code has been generated by QM 5.3.0 . +// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. +// +// This code is covered by the following QP license: +// License # : LicenseRef-QL-dual +// Issued to : Any user of the QP/C real-time embedded framework +// Framework(s) : qpc +// Support ends : 2024-12-31 +// License scope: +// +// Copyright (C) 2005 Quantum Leaps, LLC . +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +// +//$endhead${include::qxk.h} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +#ifndef QXK_H_ +#define QXK_H_ -/*==========================================================================*/ -/* QF configuration for QXK -- data members of the QActive class... */ +//$declare${QXK::QXK} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/* QXK event-queue used for AOs */ -#define QF_EQUEUE_TYPE QEQueue +//${QXK::QXK} ................................................................ +// @class QXK +typedef struct QXK { + //! @cond INTERNAL + uint8_t dummy; + //! @endcond +} QXK; +//$enddecl${QXK::QXK} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -/* QXK OS-object used to store the private stack pointer for extended threads. -* (The private stack pointer is NULL for basic-threads). -*/ -#define QF_OS_OBJECT_TYPE void* +//$declare${QXK::QSchedStatus} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/* QXK thread type used to store the private Thread-Local Storage pointer */ -#define QF_THREAD_TYPE void* +//${QXK::QSchedStatus} ....................................................... +typedef uint_fast16_t QSchedStatus; +//$enddecl${QXK::QSchedStatus} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -/*! Access Thread-Local Storage (TLS) and cast it on the given `type_` */ -#define QXK_TLS(type_) ((type_)QXK_current()->thread) +//$declare${QXK::QXTHREAD_NO_TIMEOUT} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/*==========================================================================*/ -#include "qequeue.h" /* QXK kernel uses the native QP event queue */ -#include "qmpool.h" /* QXK kernel uses the native QP memory pool */ -#include "qf.h" /* QF framework integrates directly with QXK */ +//${QXK::QXTHREAD_NO_TIMEOUT} ................................................ +#define QXTHREAD_NO_TIMEOUT ((QTimeEvtCtr)0) +//$enddecl${QXK::QXTHREAD_NO_TIMEOUT} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -/*==========================================================================*/ -/*$declare${QXK::QXK-base} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//$declare${QXK::QXK-base} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/*${QXK::QXK-base::onIdle} .................................................*/ -/*! QXK idle callback (customized in BSPs for QXK) -* @static @public @memberof QXK -* -* @details -* QXK_onIdle() is called continuously by the QXK idle thread. This callback -* gives the application an opportunity to enter a power-saving CPU mode, -* or perform some other idle processing. -* -* @note -* QXK_onIdle() is invoked with interrupts enabled and must also return with -* interrupts enabled. -*/ +//${QXK::QXK-base::Attr} ..................................................... +//! @class QXK_Attr +typedef struct { +// public: + + //! @memberof QXK_Attr + struct QActive * volatile curr; + + //! @memberof QXK_Attr + struct QActive * volatile next; + + //! @memberof QXK_Attr + struct QActive * volatile prev; + + //! @memberof QXK_Attr + uint_fast8_t volatile actPrio; + + //! @memberof QXK_Attr + uint_fast8_t volatile lockCeil; + + //! @memberof QXK_Attr + uint_fast8_t volatile lockHolder; + + //! @memberof QXK_Attr + QPSet readySet; + +#ifndef Q_UNSAFE + //! @memberof QXK_Attr + QPSet readySet_dis; +#endif // ndef Q_UNSAFE +} QXK_Attr; + +//${QXK::QXK-base::priv_} .................................................... +//! @static @private @memberof QXK +extern QXK_Attr QXK_priv_; + +//${QXK::QXK-base::onIdle} ................................................... +//! @static @public @memberof QXK void QXK_onIdle(void); -/*${QXK::QXK-base::schedLock} ..............................................*/ -/*! QXK Scheduler lock -* @static @public @memberof QXK -* -* @details -* This function locks the QXK scheduler to the specified ceiling. -* -* @param[in] ceiling preemption ceiling to which the QXK scheduler -* needs to be locked -* -* @returns -* The previous QXK Scheduler lock status, which is to be used to unlock -* the scheduler by restoring its previous lock status in -* QXK_schedUnlock(). -* -* @note -* A QXK scheduler can be locked from both basic threads (AOs) and -* extended threads and the scheduler locks can nest. -* -* @note -* QXK_schedLock() must be always followed by the corresponding -* QXK_schedUnlock(). -* -* @attention -* QXK will fire an assertion if a thread holding the lock attempts -* to block. -* -* @sa QXK_schedUnlock() -* -* @usage -* The following example shows how to lock and unlock the QXK scheduler: -* @include qxk_lock.c -*/ +//${QXK::QXK-base::schedLock} ................................................ +//! @static @public @memberof QXK QSchedStatus QXK_schedLock(uint_fast8_t const ceiling); -/*${QXK::QXK-base::schedUnlock} ............................................*/ -/*! QXK Scheduler unlock -* @static @public @memberof QXK -* -* @details -* This function unlocks the QXK scheduler to the previous status. -* -* @param[in] stat previous QXK Scheduler lock status returned from -* QXK_schedLock() -* -* @note -* A QXK scheduler can be locked from both basic threads (AOs) and -* extended threads and the scheduler locks can nest. -* -* @note -* QXK_schedUnlock() must always follow the corresponding QXK_schedLock(). -* -* @sa QXK_schedLock() -* -* @usage -* The following example shows how to lock and unlock the QXK scheduler: -* @include qxk_lock.c -*/ +//${QXK::QXK-base::schedUnlock} .............................................. +//! @static @public @memberof QXK void QXK_schedUnlock(QSchedStatus const stat); -/*${QXK::QXK-base::Timeouts} ...............................................*/ -/*! timeout signals for extended threads */ -enum QXK_Timeouts { - QXK_DELAY_SIG = 1, - QXK_TIMEOUT_SIG -}; -/*$enddecl${QXK::QXK-base} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*$declare${QXK::QXK-extern-C} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${QXK::QXK-extern-C::Attr} ...............................................*/ -/*! @brief The QXK kernel class -* @class QXK -* -* @note -* The order and alignment of the data members in this struct might -* be important in QXK ports, where the members might be accessed -* in assembly. -*/ -typedef struct QXK_Attr { - struct QActive * volatile curr; /*!< current thread (NULL=basic) */ - struct QActive * volatile next; /*!< next thread to run */ - struct QActive * volatile prev; /*!< previous thread */ - uint8_t volatile actPrio; /*!< QF-prio of the active AO */ - uint8_t volatile lockCeil; /*!< lock-ceiling (0==no-lock) */ - uint8_t volatile lockHolder; /*!< prio of the lock holder */ -} QXK; - -/*${QXK::QXK-extern-C::attr_} ..............................................*/ -/*! attributes of the QXK kernel */ -extern QXK QXK_attr_; - -/*${QXK::QXK-extern-C::sched_} .............................................*/ -/*! QXK scheduler finds the highest-priority thread ready to run -* @static @private @memberof QXK -* -* @details -* The QXK scheduler finds the priority of the highest-priority thread -* that is ready to run. -* -* @returns -* the 1-based priority of the the thread (basic or extended) run next, -* or zero if no eligible thread is found. -* -* @attention -* QXK_sched_() must be always called with interrupts **disabled** and -* returns with interrupts **disabled**. -*/ -uint_fast8_t QXK_sched_(void); - -/*${QXK::QXK-extern-C::activate_} ..........................................*/ -/*! QXK activator activates the next active object. The activated AO -* preempts the currently executing AOs. -* @static @private @memberof QXK -* -* @details -* QXK_activate_() activates ready-to run AOs that are above the initial -* active priority (QXK_attr_.actPrio). -* -* @attention -* QXK_activate_() must be always called with interrupts **disabled** and -* returns with interrupts **disabled**. -*/ -void QXK_activate_(void); - -/*${QXK::QXK-extern-C::current} ............................................*/ -/*! obtain the currently executing active-object/thread -* @static @public @memberof QXK -* -* @returns -* pointer to the currently executing active-object/thread -*/ +//${QXK::QXK-base::current} .................................................. +//! @static @public @memberof QXK QActive * QXK_current(void); -/*${QXK::QXK-extern-C::stackInit_} .........................................*/ -/*! initialize the private stack of a given AO (defined in QXK port) */ -void QXK_stackInit_( - void * thr, - QXThreadHandler const handler, - void * const stkSto, - uint_fast16_t const stkSize); +//${QXK::QXK-base::sched_} ................................................... +//! @static @private @memberof QXK +uint_fast8_t QXK_sched_(void); -/*${QXK::QXK-extern-C::contextSw} ..........................................*/ -#if defined(Q_SPY) || defined(QF_ON_CONTEXT_SW) -/*! QXK context switch management -* @static @public @memberof QXK -* -* @details -* This function performs software tracing (if #Q_SPY is defined) -* and calls QF_onContextSw() (if #QF_ON_CONTEXT_SW is defined) -* -* @param[in] next pointer to the next thread (NULL for basic-thread) -* -* @attention -* QXK_contextSw() is invoked with interrupts **disabled** and must also -* return with interrupts **disabled**. -*/ -void QXK_contextSw(QActive * const next); -#endif /* defined(Q_SPY) || defined(QF_ON_CONTEXT_SW) */ -/*$enddecl${QXK::QXK-extern-C} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*$declare${QXK::QXThread} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//${QXK::QXK-base::activate_} ................................................ +//! @static @private @memberof QXK +void QXK_activate_(void); -/*${QXK::QXThread} .........................................................*/ -/*! @brief eXtended (blocking) thread of the QXK preemptive kernel -* @class QXThread -* @extends QActive -* -* @details -* ::QXThread represents the eXtended (blocking) thread of the QXK -* kernel. Each extended thread in the application must be represented -* by the corresponding ::QXThread instance -* -* @note -* Typically, ::QXThread is instantiated directly in the application code. -* The customization of the thread occurs in the QXThread_ctor(), where you -* provide the thread-handler function as the parameter. -* -* @usage -* The following example illustrates how to instantiate and use an extended -* thread in your application. -* @include qxk_thread.c -*/ +//${QXK::QXK-base::contextSw_} ............................................... +//! @static @public @memberof QXK +void QXK_contextSw_(QActive * const next); + +//${QXK::QXK-base::threadExit_} .............................................. +//! @static @private @memberof QXK +void QXK_threadExit_(void); +//$enddecl${QXK::QXK-base} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +//$declare${QXK::QXThread} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${QXK::QXThread} ........................................................... +//! @class QXThread +//! @extends QActive typedef struct QXThread { -/* protected: */ +// protected: QActive super; -/* private: */ +// private: - /*! time event to handle blocking timeouts */ + //! @private @memberof QXThread QTimeEvt timeEvt; } QXThread; -/* public: */ +//! @static @private @memberof QXThread +//! dummy static member to force QM to generate 'struct QXThread' +extern QXThread const * QXThread_dummy; -/*! constructor of an extended-thread -* @public @memberof QXThread -* -* @details -* Performs the first step of QXThread initialization by assigning the -* thread-handler function and the tick rate at which it will handle -* the timeouts. -* -* @param[in,out] me current instance pointer (see @ref oop) -* @param[in] handler the thread-handler function -* @param[in] tickRate the ticking rate for timeouts in this thread -* (see QXThread_delay() and QTIMEEVT_TICK_X()) -* -* @note -* Must be called only ONCE before QXTHREAD_START(). -* -* @usage -* The following example illustrates how to invoke QXThread_ctor() in the -* main() function -* -* @include -* qxk_thread_ctor.c -*/ +// public: + +//! @public @memberof QXThread void QXThread_ctor(QXThread * const me, QXThreadHandler const handler, uint_fast8_t const tickRate); -/*! delay (block) the current extended thread for a specified # ticks -* @static @public @memberof QXThread -* -* @details -* Blocking delay for the number of clock tick at the associated tick rate. -* -* @param[in] nTicks number of clock ticks (at the associated rate) -* to wait for the event to arrive. -* @note -* For the delay to work, the QTIMEEVT_TICK_X() macro needs to be called -* periodically at the associated clock tick rate. -* -* @sa QXThread_ctor() -* @sa QTIMEEVT_TICK_X() -*/ -bool QXThread_delay(uint_fast16_t const nTicks); +//! @public @memberof QXThread +bool QXThread_delay(QTimeEvtCtr const nTicks); -/*! cancel the delay -* @public @memberof QXThread -* -* @details -* Cancel the blocking delay and cause return from the QXThread_delay() -* function. -* -* @returns -* "true" if the thread was actually blocked on QXThread_delay() and -* "false" otherwise. -*/ +//! @public @memberof QXThread bool QXThread_delayCancel(QXThread * const me); -/*! obtain a message from the private message queue (block if no messages) -* @static @public @memberof QXThread -* -* @details -* The QXThread_queueGet() operation allows the calling extended thread to -* receive QP events directly into its own built-in event queue from an ISR, -* basic thread (AO), or another extended thread. -* -* If QXThread_queueGet() is called when no events are present in the -* thread's private event queue, the operation blocks the current extended -* thread until either an event is received, or a user-specified timeout -* expires. -* -* @param[in] nTicks number of clock ticks (at the associated rate) -* to wait for the event to arrive. The value of -* ::QXTHREAD_NO_TIMEOUT indicates that no timeout will -* occur and the queue will block indefinitely. -* @returns -* A pointer to the event. If the pointer is not NULL, the event was delivered. -* Otherwise the event pointer of NULL indicates that the queue has timed out. -*/ -QEvt const * QXThread_queueGet(uint_fast16_t const nTicks); +//! @static @public @memberof QXThread +QEvt const * QXThread_queueGet(QTimeEvtCtr const nTicks); -/* protected: */ +// private: -/*! Overrides QHsm_init_() */ -void QXThread_init_( - QHsm * const me, - void const * const par, - uint_fast8_t const qs_id); - -/*! Overrides QHsm_dispatch_() */ -void QXThread_dispatch_( - QHsm * const me, - QEvt const * const e, - uint_fast8_t const qs_id); - -/*! start QXThread private implementation -* @private @memberof QXThread -* -* @details -* Starts execution of an extended thread and registers it with the framework. -* The extended thread becomes ready-to-run immediately and is scheduled -* if the QXK is already running. -* -* @param[in,out] me current instance pointer (see @ref oop) -* @param[in] prio QF-priority of the thread, but no preemption- -* threshold. See also ::QPrioSpec. -* @param[in] qSto pointer to the storage for the ring buffer of the -* event queue. This cold be NULL, if this extended -* thread does not use the built-in event queue. -* @param[in] qLen length of the event queue [in events], -* or zero if queue not used -* @param[in] stkSto pointer to the stack storage (must be provided) -* @param[in] stkSize stack size [in bytes] (must not be zero) -* @param[in] par pointer to an extra parameter (might be NULL). -* -* @note -* Currently, extended trheads in QXK do NOT support preemption-threshold. -* The `prio` must NOT provide preemption-threshold and this function -* will assert it in the precondition. -* -* @usage -* QXThread_start_() should NOT be called directly, only via the macro -* QXTHREAD_START(). The following example shows starting an extended -* thread: -* @include qxk_start.c -*/ -void QXThread_start_( - QActive * const me, - QPrioSpec const prioSpec, - QEvt const * * const qSto, - uint_fast16_t const qLen, - void * const stkSto, - uint_fast16_t const stkSize, - void const * const par); - -/*! post to the QXThread event queue private implementation -* @private @memberof QXThread -* -* @details -* Direct event posting is the simplest asynchronous communication method -* available in QF. The following example illustrates how the Philo active -* object posts directly the HUNGRY event to the Table active object. -*
-* The parameter `margin` specifies the minimum number of free slots in -* the queue that must be available for posting to succeed. The function -* returns 1 (success) if the posting succeeded (with the provided margin) -* and 0 (failure) when the posting fails. -* -* @param[in,out] me current instance pointer (see @ref oop) -* @param[in] e pointer to the event to be posted -* @param[in] margin number of required free slots in the queue after -* posting the event. The special value #QF_NO_MARGIN -* means that this function will assert if posting fails. -* @param[in] sender pointer to a sender object (used only for QS tracing). -* -* @returns -* 'true' (success) if the posting succeeded (with the provided margin) and -* 'false' (failure) when the posting fails. -* -* @note -* Should be called only via the macro QXTHREAD_POST_X(). -* -* @note -* The #QF_NO_MARGIN value of the `margin` parameter is special and -* denotes situation when the post() operation is assumed to succeed -* (event delivery guarantee). An assertion fires, when the event cannot -* be delivered in this case. -* -* @note -* For compatibility with the V-table from the superclass ::QActive, the -* me-pointer is typed as pointing to QActive. However, the `me` pointer -* here actually points to the QXThread subclass. Therefore the downcast -* (QXThread *)me is always correct. -*/ -bool QXThread_post_( - QActive * const me, - QEvt const * const e, - uint_fast16_t const margin, - void const * const sender); - -/*! post to the QXThread event queue (LIFO) private implementation -* @private @memberof QXThread -* -* @details -* Last-In-First-Out (LIFO) policy is not supported for extened threads. -* -* @param[in] me current instance pointer (see @ref oop) -* @param[in] e pointer to the event to post to the queue -* -* @sa -* QActive_postLIFO_() -*/ -void QXThread_postLIFO_( - QActive * const me, - QEvt const * const e); - -/* private: */ - -/*! block QXThread private implementation -* @private @memberof QXThread -* -* @details -* Internal implementation of blocking the given extended thread. -* -* @note -* Must be called from within a critical section -*/ +//! @private @memberof QXThread void QXThread_block_(QXThread const * const me); -/*! unblock QXThread private implementation -* @private @memberof QXThread -* -* @details -* Internal implementation of un-blocking the given extended thread. -* -* @note -* must be called from within a critical section -*/ +//! @private @memberof QXThread void QXThread_unblock_(QXThread const * const me); -/*! arm internal time event private implementation -* @private @memberof QXThread -* -* @details -* Internal implementation of arming the private time event for a given -* timeout at a given system tick rate. -* -* @note -* Must be called from within a critical section -*/ +//! @private @memberof QXThread +void QXThread_timeout_(QActive * const act); + +//! @private @memberof QXThread void QXThread_teArm_(QXThread * const me, enum_t const sig, - uint_fast16_t const nTicks); + QTimeEvtCtr const nTicks); -/*! disarm internal time event private implementation -* @private @memberof QXThread -* -* @details -* Internal implementation of disarming the private time event. -* -* @note -* Must be called from within a critical section -*/ +//! @private @memberof QXThread bool QXThread_teDisarm_(QXThread * const me); -/*! dummy static to force generation of "struct QXThread" */ -extern QXThread const * QXThread_dummy; -/*$enddecl${QXK::QXThread} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*$declare${QXK::QXThreadVtable} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +// public: -/*${QXK::QXThreadVtable} ...................................................*/ -/*! @brief Virtual Table for the ::QXThread class -* (inherited from ::QActiveVtable) -* -* @note -* ::QXThread inherits ::QActive without adding any new virtual -* functions and therefore, ::QXThreadVtable is typedef'ed as ::QActiveVtable. -*/ -typedef QActiveVtable QXThreadVtable; -/*$enddecl${QXK::QXThreadVtable} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*$declare${QXK::QXSemaphore} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//! @private @memberof QXThread +void QXThread_stackInit_( + QActive * const me, + QXThreadHandler const handler, + void * const stkSto, + uint_fast16_t const stkSize); +//$enddecl${QXK::QXThread} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -/*${QXK::QXSemaphore} ......................................................*/ -/*! @brief Counting Semaphore of the QXK preemptive kernel -* @class QXSemaphore -* -* @details -* ::QXSemaphore is a blocking mechanism intended primarily for signaling -* @ref ::QXThread "extended threads". The semaphore is initialized with -* the maximum count (see QXSemaphore_init()), which allows you to create -* a binary semaphore (when the maximum count is 1) and -* counting semaphore when the maximum count is > 1. -* -* @usage -* The following example illustrates how to instantiate and use the semaphore -* in your application. -* @include qxk_sema.c -*/ +//$declare${QXK::QXSemaphore} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${QXK::QXSemaphore} ........................................................ +//! @class QXSemaphore typedef struct { -/* private: */ +// private: - /*! set of extended threads waiting on this semaphore */ + //! @private @memberof QXSemaphore QPSet waitSet; - /*! semaphore up-down counter */ + //! @private @memberof QXSemaphore uint8_t volatile count; - /*! maximum value of the semaphore counter */ + //! @private @memberof QXSemaphore uint8_t max_count; } QXSemaphore; -/* public: */ +// public: -/*! initialize the counting semaphore -* @public @memberof QXSemaphore -* -* @details -* Initializes a semaphore with the specified count and maximum count. -* If the semaphore is used for resource sharing, both the initial count -* and maximum count should be set to the number of identical resources -* guarded by the semaphore. If the semaphore is used as a signaling -* mechanism, the initial count should set to 0 and maximum count to 1 -* (binary semaphore). -* -* @param[in,out] me current instance pointer (see @ref oop) -* @param[in] count initial value of the semaphore counter -* @param[in] max_count maximum value of the semaphore counter. -* The purpose of the max_count is to limit the counter -* so that the semaphore cannot unblock more times than -* the maximum. -* -* @note -* QXSemaphore_init() must be called **before** the semaphore can be used -* (signaled or waited on). -*/ +//! @public @memberof QXSemaphore void QXSemaphore_init(QXSemaphore * const me, uint_fast8_t const count, uint_fast8_t const max_count); -/*! wait (block) on the semaphore -* @public @memberof QXSemaphore -* -* @details -* When an extended thread calls QXSemaphore_wait() and the value of the -* semaphore counter is greater than 0, QXSemaphore_wait() decrements the -* semaphore counter and returns (true) to its caller. However, if the value -* of the semaphore counter is 0, the function places the calling thread in -* the waiting list for the semaphore. The thread waits until the semaphore -* is signaled by calling QXSemaphore_signal(), or the specified timeout -* expires. If the semaphore is signaled before the timeout expires, QXK -* resumes the highest-priority extended thread waiting for the semaphore. -* -* @param[in,out] me current instance pointer (see @ref oop) -* @param[in] nTicks number of clock ticks (at the associated rate) -* to wait for the semaphore. The value of -* ::QXTHREAD_NO_TIMEOUT indicates that no timeout will -* occur and the semaphore will wait indefinitely. -* -* @returns -* 'true' if the semaphore has been signaled and 'false' if a timeout -* occurred. -* -* @note -* Multiple extended threads can wait for a given semaphore. -*/ +//! @public @memberof QXSemaphore bool QXSemaphore_wait(QXSemaphore * const me, - uint_fast16_t const nTicks); + QTimeEvtCtr const nTicks); -/*! try wait on the semaphore (non-blocking) -* @public @memberof QXSemaphore -* -* @details -* This function checks if the semaphore counter is greater than 0, -* in which case the counter is decremented. -* -* @param[in,out] me current instance pointer (see @ref oop) -* -* @returns -* 'true' if the semaphore has count available and 'false' NOT available. -* -* @note -* This function can be called from any context, including ISRs and basic -* threads (active objects). -*/ +//! @public @memberof QXSemaphore bool QXSemaphore_tryWait(QXSemaphore * const me); -/*! signal (unblock) the semaphore -* @public @memberof QXSemaphore -* -* @details -* If the semaphore counter value is 0 or more, it is incremented, and -* this function returns to its caller. If the extended threads are waiting -* for the semaphore to be signaled, QXSemaphore_signal() removes the highest- -* priority thread waiting for the semaphore from the waiting list and makes -* this thread ready-to-run. The QXK scheduler is then called to determine if -* the awakened thread is now the highest-priority thread that is ready-to-run. -* -* @param[in,out] me current instance pointer (see @ref oop) -* -* @returns -* 'true' when the semaphore signaled and 'false' when the semaphore count -* exceeded the maximum. -* -* @note -* A semaphore can be signaled from many places, including from ISRs, basic -* threads (AOs), and extended threads. -*/ +//! @public @memberof QXSemaphore bool QXSemaphore_signal(QXSemaphore * const me); -/*$enddecl${QXK::QXSemaphore} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*$declare${QXK::QXMutex} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//$enddecl${QXK::QXSemaphore} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -/*${QXK::QXMutex} ..........................................................*/ -/*! @brief Blocking Mutex the QXK preemptive kernel -* @class QXMutex -* -* @details -* ::QXMutex is a blocking mutual exclusion mechanism that can also apply -* the **priority-ceiling protocol** to avoid unbounded priority inversion -* (if initialized with a non-zero ceiling priority, see QXMutex_init()). -* In that case, ::QXMutex requires its own uinque QP priority level, which -* cannot be used by any thread or any other ::QXMutex. -* If initialized with preemption-ceiling of zero, ::QXMutex does **not** -* use the priority-ceiling protocol and does not require a unique QP -* priority (see QXMutex_init()). -* ::QXMutex is **recursive** (re-entrant), which means that it can be locked -* multiple times (up to 255 levels) by the *same* thread without causing -* deadlock. -* ::QXMutex is primarily intended for the @ref ::QXThread -* "extened (blocking) threads", but can also be used by the @ref ::QActive -* "basic threads" through the non-blocking QXMutex_tryLock() API. -* -* @note -* ::QXMutex should be used in situations when at least one of the extended -* threads contending for the mutex blocks while holding the mutex (between -* the QXMutex_lock() and QXMutex_unlock() operations). If no blocking is -* needed while holding the mutex, the more efficient non-blocking mechanism -* of @ref srs_qxk_schedLock() "selective QXK scheduler locking" should be used -* instead. @ref srs_qxk_schedLock() "Selective scheduler locking" is available -* for both @ref ::QActive "basic threads" and @ref ::QXThread "extended -* threads", so it is applicable to situations where resources are shared -* among all these threads. -* -* @usage -* The following example illustrates how to instantiate and use the mutex -* in your application. -* @include qxk_mutex.c -*/ +//$declare${QXK::QXMutex} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${QXK::QXMutex} ............................................................ +//! @class QXMutex typedef struct { -/* private: */ +// private: - /*! active object used as a placeholder AO for this mutex - * in QActive_registry_[] - */ + //! @private @memberof QXMutex QActive ao; - /*! set of extended-threads waiting on this mutex */ + //! @private @memberof QXMutex QPSet waitSet; } QXMutex; -/* public: */ +// public: -/*! initialize the QXK priority-ceiling mutex ::QXMutex -* @public @memberof QXMutex -* -* @details -* Initialize the QXK priority ceiling mutex. -* -* @param[in,out] me current instance pointer (see @ref oop) -* @param[in] prioSpec the priority specification for the mutex -* (See also ::QPrioSpec). This value might -* also be zero. -* @note -* `prioSpec == 0` means that the priority-ceiling protocol shall **not** -* be used by this mutex. Such mutex will **not** change (boost) the -* priority of the holding threads.
-* -* Conversely, `prioSpec != 0` means that the priority-ceiling protocol -* shall be used by this mutex. Such mutex **will** temporarily boost -* the priority and priority-threshold of the holding thread to the -* priority specification in `prioSpec` (see ::QPrioSpec). -* -* @usage -* @include qxk_mutex.c -*/ +//! @public @memberof QXMutex void QXMutex_init(QXMutex * const me, QPrioSpec const prioSpec); -/*! lock the QXK priority-ceiling mutex ::QXMutex -* @public @memberof QXMutex -* -* @param[in,out] me current instance pointer (see @ref oop) -* @param[in] nTicks number of clock ticks (at the associated rate) -* to wait for the mutex. The value of -* ::QXTHREAD_NO_TIMEOUT indicates that no timeout will -* occur and the mutex could block indefinitely. -* @returns -* 'true' if the mutex has been acquired and 'false' if a timeout occurred. -* -* @note -* The mutex locks are allowed to nest, meaning that the same extended thread -* can lock the same mutex multiple times (< 255). However, each call to -* QXMutex_lock() must be balanced by the matching call to QXMutex_unlock(). -* -* @usage -* @include qxk_mutex.c -*/ +//! @public @memberof QXMutex bool QXMutex_lock(QXMutex * const me, - uint_fast16_t const nTicks); + QTimeEvtCtr const nTicks); -/*! try to lock the QXK priority-ceiling mutex ::QXMutex -* @public @memberof QXMutex -* -* @param[in,out] me current instance pointer (see @ref oop) -* -* @returns -* 'true' if the mutex was successfully locked and 'false' if the mutex was -* unavailable and was NOT locked. -* -* @note -* This function **can** be called from both basic threads (active objects) -* and extended threads. -* -* @note -* The mutex locks are allowed to nest, meaning that the same extended thread -* can lock the same mutex multiple times (<= 255). However, each successful -* call to QXMutex_tryLock() must be balanced by the matching call to -* QXMutex_unlock(). -*/ +//! @public @memberof QXMutex bool QXMutex_tryLock(QXMutex * const me); -/*! unlock the QXK priority-ceiling mutex ::QXMutex -* @public @memberof QXMutex -*! -* @param[in,out] me current instance pointer (see @ref oop) -* -* @note -* This function **can** be called from both basic threads (active objects) -* and extended threads. -* -* @note -* The mutex locks are allowed to nest, meaning that the same extended thread -* can lock the same mutex multiple times (<= 225). However, each call to -* QXMutex_lock() or a *successful* call to QXMutex_tryLock() must be -* balanced by the matching call to QXMutex_unlock(). -* -* @usage -* @include qxk_mutex.c -*/ +//! @public @memberof QXMutex void QXMutex_unlock(QXMutex * const me); -/*$enddecl${QXK::QXMutex} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*$declare${QXK-macros} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//$enddecl${QXK::QXMutex} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -/*${QXK-macros::QXTHREAD_START} ............................................*/ -/*! Virtual call to start an extened thread -* -* @details -* Starts execution of the thread and registers the AO with the framework. -* -* @param[in,out] me_ current instance pointer (see @ref oop) -* @param[in] prioSpec_ priority specification at which to start the -* extended thread (see ::QPrioSpec) -* @param[in] qSto_ pointer to the storage for the ring buffer of the -* event queue (used only with the built-in ::QEQueue) -* @param[in] qLen_ length of the event queue (in events) -* @param[in] stkSto_ pointer to the stack storage (used only when -* per-AO stack is needed) -* @param[in] stkSize_ stack size (in bytes) -* @param[in] par_ pointer to the additional port-specific parameter(s) -* (might be NULL). -* @usage -* @include qxk_start.c -*/ -#define QXTHREAD_START(me_, prioSpec_, qSto_, qLen_, stkSto_, stkSize_, par_) \ -do { \ - Q_ASSERT((me_)->super.super.vptr); \ - ((*((QActiveVtable const *)((me_)->super.super.vptr))->start)( \ - &(me_)->super, (prioSpec_), (QEvt const **)(qSto_), (qLen_), \ - (stkSto_), (stkSize_), (par_))); \ -} while (false) +//$declare${QXK-macros} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/*${QXK-macros::QXTHREAD_NO_TIMEOUT} .......................................*/ -/*! No-timeout when blocking on semaphores, mutextes, and queues */ -#define QXTHREAD_NO_TIMEOUT ((uint_fast16_t)0) +//${QXK-macros::QXTHREAD_START} .............................................. +#define QXTHREAD_START(me_, prioSpec_, qSto_, qLen_, stkSto_, stkSize_, par_) QACTIVE_START((me_), (prioSpec_), (qSto_), (qLen_), \ + (stkSto_), (stkSize_), (par_)) -/*${QXK-macros::QXTHREAD_POST_X} ...........................................*/ -/*! Asynchronous posting events to the event queue of an eXtended thread -* @details -* This macro does not assert if the queue overflows and cannot accept -* the event with the specified margin of free slots remaining. -* -* @param[in,out] me_ current instance pointer (see @ref oop) -* @param[in] e_ pointer to the event to post -* @param[in] margin_ the minimum free slots in the queue, which -* must still be available after posting the event. -* The special value #QF_NO_MARGIN causes asserting -* failure in case event allocation fails. -* @param[in] sender_ pointer to the sender object (used in QS tracing) -* -* @returns -* 'true' if the posting succeeded, and 'false' if the posting failed due -* to insufficient margin of free slots available in the queue. -* -* @note -* The `sender_` parameter is actually only used when QS tracing is enabled -* (macro #Q_SPY is defined). When QS software tracing is disabled, the -* QXTHREAD_POST_X() macro does not pass the `sender_` parameter, so the -* overhead of passing this extra argument is entirely avoided. -* -* @note -* The pointer to the sender object is not necessarily a pointer to an -* active object. In fact, if QXTHREAD_POST_X() is called from an interrupt -* or other context, you can create a unique object just to unambiguously -* identify the sender of the event. -* -* @usage -* @include qf_postx.c -*/ +//${QXK-macros::QXTHREAD_POST_X} ............................................. #define QXTHREAD_POST_X(me_, e_, margin_, sender_) \ QACTIVE_POST_X(&(me_)->super, (e_), (margin_), (sender_)) -/*$enddecl${QXK-macros} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$enddecl${QXK-macros} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -/*==========================================================================*/ -/* interface used only inside QP implementation, but not in applications */ +//============================================================================ +// interface used only for internal implementation, but not in applications #ifdef QP_IMPL -/* QXK implementation... */ -/*$declare${QXK-impl} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/*${QXK-impl::QXK_ISR_CONTEXT_} ............................................*/ -#ifndef QXK_ISR_CONTEXT_ -/*! Internal macro that reports the execution context (ISR vs. thread) -* -* @returns true if the code executes in the ISR context and false -* otherwise -*/ -#define QXK_ISR_CONTEXT_() (QF_intNest_ != 0U) -#endif /* ndef QXK_ISR_CONTEXT_ */ +//$declare${QXK-impl} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/*${QXK-impl::QF_SCHED_STAT_} ..............................................*/ -/*! QXK scheduler lock status */ +//${QXK-impl::QF_SCHED_STAT_} ................................................ #define QF_SCHED_STAT_ QSchedStatus lockStat_; -/*${QXK-impl::QF_SCHED_LOCK_} ..............................................*/ -/*! QXK selective scheduler locking */ +//${QXK-impl::QF_SCHED_LOCK_} ................................................ #define QF_SCHED_LOCK_(ceil_) do { \ if (QXK_ISR_CONTEXT_()) { \ lockStat_ = 0xFFU; \ @@ -906,94 +296,102 @@ do { \ } \ } while (false) -/*${QXK-impl::QF_SCHED_UNLOCK_} ............................................*/ -/*! QXK selective scheduler unlocking */ +//${QXK-impl::QF_SCHED_UNLOCK_} .............................................. #define QF_SCHED_UNLOCK_() do { \ if (lockStat_ != 0xFFU) { \ QXK_schedUnlock(lockStat_); \ } \ } while (false) -/*${QXK-impl::QACTIVE_EQUEUE_WAIT_} ........................................*/ -/*! QXK native event queue waiting */ +//${QXK-impl::QACTIVE_EQUEUE_WAIT_} .......................................... #define QACTIVE_EQUEUE_WAIT_(me_) \ - (Q_ASSERT_ID(110, (me_)->eQueue.frontEvt != (QEvt *)0)) + Q_ASSERT_INCRIT(310, (me_)->eQueue.frontEvt != (QEvt *)0) -/*${QXK-impl::QACTIVE_EQUEUE_SIGNAL_} ......................................*/ -/*! QXK native event queue signaling */ +//${QXK-impl::QACTIVE_EQUEUE_SIGNAL_} ........................................ +#ifndef Q_UNSAFE #define QACTIVE_EQUEUE_SIGNAL_(me_) do { \ - QPSet_insert(&QF_readySet_, (uint_fast8_t)(me_)->prio); \ + QPSet_insert(&QXK_priv_.readySet, (uint_fast8_t)(me_)->prio); \ + QPSet_update_(&QXK_priv_.readySet, &QXK_priv_.readySet_dis); \ if (!QXK_ISR_CONTEXT_()) { \ if (QXK_sched_() != 0U) { \ QXK_activate_(); \ } \ } \ } while (false) +#endif // ndef Q_UNSAFE -/*${QXK-impl::QXK_PTR_CAST_} ...............................................*/ -/*! internal macro to encapsulate casting of pointers for MISRA deviations -* -* @details -* This macro is specifically and exclusively used for casting pointers -* that are never de-referenced, but only used for internal bookkeeping and -* checking (via assertions) the correct operation of the QXK kernel. -* Such pointer casting is not compliant with MISRA-2012-Rule 11.3(req) -* as well as other messages (e.g., PC-Lint-Plus warning 826). -* Defining this specific macro for this purpose allows to selectively -* disable the warnings for this particular case. -*/ +//${QXK-impl::QACTIVE_EQUEUE_SIGNAL_} ........................................ +#ifdef Q_UNSAFE +#define QACTIVE_EQUEUE_SIGNAL_(me_) do { \ + QPSet_insert(&QXK_priv_.readySet, (uint_fast8_t)(me_)->prio); \ + if (!QXK_ISR_CONTEXT_()) { \ + if (QXK_sched_() != 0U) { \ + QXK_activate_(); \ + } \ + } \ +} while (false) +#endif // def Q_UNSAFE + +//${QXK-impl::QXTHREAD_EQUEUE_SIGNAL_} ....................................... +#ifndef Q_UNSAFE +#define QXTHREAD_EQUEUE_SIGNAL_(me_) do { \ + if (me->super.temp.obj == QXK_PTR_CAST_(QMState*, &me->eQueue)) { \ + (void)QXThread_teDisarm_(QXTHREAD_CAST_(me)); \ + QPSet_insert(&QXK_priv_.readySet, (uint_fast8_t)me->prio); \ + QPSet_update_(&QXK_priv_.readySet, &QXK_priv_.readySet_dis); \ + if (!QXK_ISR_CONTEXT_()) { \ + (void)QXK_sched_(); \ + } \ + } \ +} while (false) +#endif // ndef Q_UNSAFE + +//${QXK-impl::QXTHREAD_EQUEUE_SIGNAL_} ....................................... +#ifdef Q_UNSAFE +#define QXTHREAD_EQUEUE_SIGNAL_(me_) do { \ + if (me->super.temp.obj == QXK_PTR_CAST_(QMState*, &me->eQueue)) { \ + (void)QXThread_teDisarm_(QXTHREAD_CAST_(me)); \ + QPSet_insert(&QXK_priv_.readySet, (uint_fast8_t)me->prio); \ + if (!QXK_ISR_CONTEXT_()) { \ + (void)QXK_sched_(); \ + } \ + } \ +} while (false) +#endif // def Q_UNSAFE + +//${QXK-impl::QXK_PTR_CAST_} ................................................. #define QXK_PTR_CAST_(type_, ptr_) ((type_)(ptr_)) -/*${QXK-impl::QXTHREAD_CAST_} ..............................................*/ -/*! internal macro to encapsulate casting of pointers for MISRA deviations -* -* @details -* This macro is specifically and exclusively used for downcasting pointers -* to QActive to pointers to QXThread in situations when it is known -* that such downcasting is correct.However, such pointer casting is not -* compliant with MISRA-2012-Rule 11.3(req) as well as other messages (e.g., -* PC-Lint-Plus warning 826). Defining this specific macro for this purpose -* allows to selectively disable the warnings for this particular case. -*/ +//${QXK-impl::QXTHREAD_CAST_} ................................................ #define QXTHREAD_CAST_(ptr_) ((QXThread *)(ptr_)) +//$enddecl${QXK-impl} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -/*${QXK-impl::QXK_threadExit_} .............................................*/ -/*! called when QXThread exits -* @private @memberof QXThread -* -* @details -* Called when the extended-thread handler function returns. -* -* @note -* Most thread handler functions are structured as endless loops that never -* return. But it is also possible to structure threads as one-shot functions -* that perform their job and return. In that case this function peforms -* cleanup after the thread. -*/ -void QXK_threadExit_(void); -/*$enddecl${QXK-impl} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$declare${QF_EPOOL-impl} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/* Native QF event pool operations... */ -/*$declare${QF-QMPool-impl} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${QF-QMPool-impl::QF_EPOOL_TYPE_} ........................................*/ +//${QF_EPOOL-impl::QF_EPOOL_TYPE_} ........................................... #define QF_EPOOL_TYPE_ QMPool -/*${QF-QMPool-impl::QF_EPOOL_INIT_} ........................................*/ +//${QF_EPOOL-impl::QF_EPOOL_INIT_} ........................................... #define QF_EPOOL_INIT_(p_, poolSto_, poolSize_, evtSize_) \ (QMPool_init(&(p_), (poolSto_), (poolSize_), (evtSize_))) -/*${QF-QMPool-impl::QF_EPOOL_EVENT_SIZE_} ..................................*/ +//${QF_EPOOL-impl::QF_EPOOL_EVENT_SIZE_} ..................................... #define QF_EPOOL_EVENT_SIZE_(p_) ((uint_fast16_t)(p_).blockSize) -/*${QF-QMPool-impl::QF_EPOOL_GET_} .........................................*/ +//${QF_EPOOL-impl::QF_EPOOL_GET_} ............................................ #define QF_EPOOL_GET_(p_, e_, m_, qs_id_) \ ((e_) = (QEvt *)QMPool_get(&(p_), (m_), (qs_id_))) -/*${QF-QMPool-impl::QF_EPOOL_PUT_} .........................................*/ +//${QF_EPOOL-impl::QF_EPOOL_PUT_} ............................................ #define QF_EPOOL_PUT_(p_, e_, qs_id_) \ (QMPool_put(&(p_), (e_), (qs_id_))) -/*$enddecl${QF-QMPool-impl} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -#endif /* QP_IMPL */ +//$enddecl${QF_EPOOL-impl} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -#endif /* QP_INC_QXK_H_ */ +enum QXK_TimeoutSigs { + QXK_DELAY_SIG = 1, + QXK_TIMEOUT_SIG +}; + +#endif // QP_IMPL + +#endif // QXK_H_ diff --git a/ports/arm-cm/qk/armclang/qep_port.h b/ports/arm-cm/qk/armclang/qep_port.h deleted file mode 100644 index feab46d8..00000000 --- a/ports/arm-cm/qk/armclang/qep_port.h +++ /dev/null @@ -1,43 +0,0 @@ -/*============================================================================ -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2022-04-09 -* @version Last updated for: @ref qpc_7_0_0 -* -* @file -* @brief QEP/C port, ARM-Clang/LLVM compiler -*/ -#ifndef QEP_PORT_H -#define QEP_PORT_H - -/*! no-return function specifier (ARM-Clang/LLVM compiler) */ -#define Q_NORETURN __attribute__ ((noreturn)) void - -#include /* Exact-width types. WG14/N843 C99 Standard */ -#include /* Boolean type. WG14/N843 C99 Standard */ - -#include "qep.h" /* QEP platform-independent public interface */ - -#endif /* QEP_PORT_H */ - diff --git a/ports/arm-cm/qk/armclang/qf_port.h b/ports/arm-cm/qk/armclang/qf_port.h deleted file mode 100644 index 0dae5d5e..00000000 --- a/ports/arm-cm/qk/armclang/qf_port.h +++ /dev/null @@ -1,147 +0,0 @@ -/*============================================================================ -* QF/C port to ARM Cortex-M, QK, ARM-CLANG -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2022-04-09 -* @version Last updated for: @ref qpc_7_0_0 -* -* @file -* @brief QF/C port to Cortex-M, preemptive QK kernel, ARM-CLANG toolset -*/ -#ifndef QF_PORT_H -#define QF_PORT_H - -/* The maximum number of system clock tick rates */ -#define QF_MAX_TICK_RATE 2U - -/* QF interrupt disable/enable and log2()... */ -#if (__ARM_ARCH == 6) /* Cortex-M0/M0+/M1(v6-M, v6S-M)? */ - - /* The maximum number of active objects in the application, see NOTE1 */ - #define QF_MAX_ACTIVE 16U - - /* Cortex-M0/M0+/M1(v6-M, v6S-M) interrupt disabling policy, see NOTE2 */ - #define QF_INT_DISABLE() __asm volatile ("cpsid i") - #define QF_INT_ENABLE() __asm volatile ("cpsie i") - - /* QF critical section entry/exit (unconditional interrupt disabling) */ - /*#define QF_CRIT_STAT_TYPE not defined */ - #define QF_CRIT_ENTRY(dummy) QF_INT_DISABLE() - #define QF_CRIT_EXIT(dummy) QF_INT_ENABLE() - - /* CMSIS threshold for "QF-aware" interrupts, see NOTE2 and NOTE4 */ - #define QF_AWARE_ISR_CMSIS_PRI 0 - - /* hand-optimized LOG2 in assembly for Cortex-M0/M0+/M1(v6-M, v6S-M) */ - #define QF_LOG2(n_) QF_qlog2((uint32_t)(n_)) - -#else /* Cortex-M3/M4/M7 */ - - /* The maximum number of active objects in the application, see NOTE1 */ - #define QF_MAX_ACTIVE 32U - - /* Cortex-M3/M4/M7 alternative interrupt disabling with PRIMASK */ - #define QF_PRIMASK_DISABLE() __asm volatile ("cpsid i") - #define QF_PRIMASK_ENABLE() __asm volatile ("cpsie i") - - /* Cortex-M3/M4/M7 interrupt disabling policy, see NOTE3 and NOTE4 */ - #define QF_INT_DISABLE() __asm volatile (\ - "cpsid i\n" "msr BASEPRI,%0\n" "cpsie i" :: "r" (QF_BASEPRI) : ) - #define QF_INT_ENABLE() __asm volatile (\ - "msr BASEPRI,%0" :: "r" (0) : ) - - /* QF critical section entry/exit (unconditional interrupt disabling) */ - /*#define QF_CRIT_STAT_TYPE not defined */ - #define QF_CRIT_ENTRY(dummy) QF_INT_DISABLE() - #define QF_CRIT_EXIT(dummy) QF_INT_ENABLE() - - /* BASEPRI threshold for "QF-aware" interrupts, see NOTE3 */ - #define QF_BASEPRI 0x3F - - /* CMSIS threshold for "QF-aware" interrupts, see NOTE5 */ - #define QF_AWARE_ISR_CMSIS_PRI (QF_BASEPRI >> (8 - __NVIC_PRIO_BITS)) - - /* Cortex-M3/M4/M7 provide the CLZ instruction for fast LOG2 */ - #define QF_LOG2(n_) (32 - (uint_fast8_t)__builtin_clz((unsigned)(n_))) - -#endif - -#define QF_CRIT_EXIT_NOP() __asm volatile ("isb") - -#include "qep_port.h" /* QEP port */ - -#if (__ARM_ARCH == 6) /* Cortex-M0/M0+/M1(v6-M, v6S-M)? */ - /* hand-optimized quick LOG2 in assembly */ - uint_fast8_t QF_qlog2(uint32_t x); -#endif /* Cortex-M0/M0+/M1(v6-M, v6S-M) */ - -#include "qk_port.h" /* QK preemptive kernel port */ -#include "qf.h" /* QF platform-independent public interface */ - -/***************************************************************************** -* NOTE1: -* The maximum number of active objects QF_MAX_ACTIVE can be increased -* up to 64, if necessary. Here it is set to a lower level to save some RAM. -* -* NOTE2: -* On Cortex-M0/M0+/M1 (architecture v6-M, v6S-M), the interrupt disabling -* policy uses the PRIMASK register to disable interrupts globally. The -* QF_AWARE_ISR_CMSIS_PRI level is zero, meaning that all interrupts are -* "QF-aware". -* -* NOTE3: -* On Cortex-M3/M4/M7, the interrupt disable/enable policy uses the BASEPRI -* register (which is not implemented in Cortex-M0/M0+/M1) to disable -* interrupts only with priority lower than the threshold specified by the -* QF_BASEPRI macro. The interrupts with priorities above QF_BASEPRI (i.e., -* with numerical priority values lower than QF_BASEPRI) are NOT disabled in -* this method. These free-running interrupts have very low ("zero") latency, -* but they are not allowed to call any QF services, because QF is unaware -* of them ("QF-unaware" interrutps). Consequently, only interrupts with -* numerical values of priorities eqal to or higher than QF_BASEPRI -* ("QF-aware" interrupts ), can call QF services. -* -* NOTE4: -* The QF_AWARE_ISR_CMSIS_PRI macro is useful as an offset for enumerating -* the "QF-aware" interrupt priorities in the applications, whereas the -* numerical values of the "QF-aware" interrupts must be greater or equal to -* QF_AWARE_ISR_CMSIS_PRI. The values based on QF_AWARE_ISR_CMSIS_PRI can be -* passed directly to the CMSIS function NVIC_SetPriority(), which shifts -* them by (8 - __NVIC_PRIO_BITS) into the correct bit position, while -* __NVIC_PRIO_BITS is the CMSIS macro defining the number of implemented -* priority bits in the NVIC. Please note that the macro QF_AWARE_ISR_CMSIS_PRI -* is intended only for applications and is not used inside the QF port, which -* remains generic and not dependent on the number of implemented priority bits -* implemented in the NVIC. -* -* NOTE5: -* The selective disabling of "QF-aware" interrupts with the BASEPRI register -* has a problem on ARM Cortex-M7 core r0p1 (see ARM-EPM-064408, errata -* 837070). The workaround recommended by ARM is to surround MSR BASEPRI with -* the CPSID i/CPSIE i pair, which is implemented in the QF_INT_DISABLE() -* macro. This workaround works also for Cortex-M3/M4 cores. -*/ - -#endif /* QF_PORT_H */ - diff --git a/ports/arm-cm/qk/armclang/qk_port.c b/ports/arm-cm/qk/armclang/qk_port.c index 43bb4c09..5b0ad7ab 100644 --- a/ports/arm-cm/qk/armclang/qk_port.c +++ b/ports/arm-cm/qk/armclang/qk_port.c @@ -1,288 +1,278 @@ -/*============================================================================ -* QP/C Real-Time Embedded Framework (RTEF) -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2023-01-14 -* @version Last updated for: @ref qpc_7_2_1 -* -* @file -* @brief QK/C port to ARM Cortex-M, ARM-CLANG toolset -*/ -/* This QK port is part of the internal QP implementation */ -#define QP_IMPL 1U -#include "qf_port.h" +//============================================================================ +// QP/C Real-Time Embedded Framework (RTEF) +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +//============================================================================ +//! @date Last updated on: 2023-08-17 +//! @version Last updated for: @ref qpc_7_3_0 +//! +//! @file +//! @brief QK/C port to ARM Cortex-M, ARM-CLANG -/* prototypes --------------------------------------------------------------*/ +#define QP_IMPL 1U +#include "qp_port.h" + +// prototypes ---------------------------------------------------------------- void PendSV_Handler(void); -#ifdef QK_USE_IRQ_HANDLER /* if use IRQ... */ +#ifdef QK_USE_IRQ_HANDLER // if use IRQ... void QK_USE_IRQ_HANDLER(void); -#else /* use default (NMI) */ +#else // use default (NMI) void NMI_Handler(void); #endif -#define SCnSCB_ICTR ((uint32_t volatile *)0xE000E004U) -#define SCB_SYSPRI ((uint32_t volatile *)0xE000ED14U) +#define SCB_SYSPRI ((uint32_t volatile *)0xE000ED18U) #define NVIC_EN ((uint32_t volatile *)0xE000E100U) -#define NVIC_IP ((uint8_t volatile *)0xE000E400U) +#define NVIC_IP ((uint32_t volatile *)0xE000E400U) +#define SCB_CPACR *((uint32_t volatile *)0xE000ED88U) #define FPU_FPCCR *((uint32_t volatile *)0xE000EF34U) #define NVIC_PEND 0xE000E200 -#define NVIC_ICSR 0xE000ED04 +#define SCB_ICSR 0xE000ED04 -/* helper macros to "stringify" values */ +// helper macros to "stringify" values #define VAL(x) #x #define STRINGIFY(x) VAL(x) -/*..........................................................................*/ -/* Initialize the exception priorities and IRQ priorities to safe values. -* -* Description: -* On ARMv7-M or higher, this QK port disables interrupts by means of the -* BASEPRI register. However, this method cannot disable interrupt -* priority zero, which is the default for all interrupts out of reset. -* The following code changes the SysTick priority and all IRQ priorities -* to the safe value QF_BASEPRI, which the QF critical section can disable. -* This avoids breaching of the QF critical sections in case the -* application programmer forgets to explicitly set priorities of all -* "kernel aware" interrupts. -* -* The interrupt priorities established in QK_init() can be later -* changed by the application-level code. -*/ +//............................................................................ +// Initialize the exception priorities and IRQ priorities to safe values. +// +// Description: +// On ARMv7-M or higher, this QK port disables interrupts by means of the +// BASEPRI register. However, this method cannot disable interrupt +// priority zero, which is the default for all interrupts out of reset. +// The following code changes the SysTick priority and all IRQ priorities +// to the safe value QF_BASEPRI, which the QF critical section can disable. +// This avoids breaching of the QF critical sections in case the +// application programmer forgets to explicitly set priorities of all +// "kernel aware" interrupts. +// +// The interrupt priorities established in QK_init() can be later +// changed by the application-level code. void QK_init(void) { -#if (__ARM_ARCH != 6) /*--------- if ARMv7-M and higher... */ +#if (__ARM_ARCH != 6) //--------- if ARMv7-M and higher... - /* set exception priorities to QF_BASEPRI... - * SCB_SYSPRI1: Usage-fault, Bus-fault, Memory-fault - */ - SCB_SYSPRI[1] = (SCB_SYSPRI[1] - | (QF_BASEPRI << 16U) | (QF_BASEPRI << 8U) | QF_BASEPRI); - - /* SCB_SYSPRI2: SVCall */ + // SCB_SYSPRI[2]: SysTick SCB_SYSPRI[2] = (SCB_SYSPRI[2] | (QF_BASEPRI << 24U)); - /* SCB_SYSPRI3: SysTick, PendSV, Debug */ - SCB_SYSPRI[3] = (SCB_SYSPRI[3] - | (QF_BASEPRI << 24U) | (QF_BASEPRI << 16U) | QF_BASEPRI); - - /* set all implemented IRQ priories to QF_BASEPRI... */ - uint8_t nprio = (8U + ((*SCnSCB_ICTR & 0x7U) << 3U)) * 4U; - for (uint8_t n = 0U; n < nprio; ++n) { - NVIC_IP[n] = QF_BASEPRI; + // set all 240 possible IRQ priories to QF_BASEPRI... + for (uint_fast8_t n = 0U; n < (240U/sizeof(uint32_t)); ++n) { + NVIC_IP[n] = (QF_BASEPRI << 24U) | (QF_BASEPRI << 16U) + | (QF_BASEPRI << 8U) | QF_BASEPRI; } -#endif /*--------- ARMv7-M or higher */ +#endif //--------- ARMv7-M or higher - /* SCB_SYSPRI3: PendSV set to priority 0xFF (lowest) */ - SCB_SYSPRI[3] = (SCB_SYSPRI[3] | (0xFFU << 16U)); + // SCB_SYSPRI[2]: PendSV set to priority 0xFF (lowest) + SCB_SYSPRI[2] = (SCB_SYSPRI[2] | (0xFFU << 16U)); -#ifdef QK_USE_IRQ_NUM /*--------- QK IRQ specified? */ - /* The QK port is configured to use a given ARM Cortex-M IRQ # - * to return to thread mode (default is to use the NMI exception) - */ - NVIC_IP[QK_USE_IRQ_NUM] = 0U; /* priority 0 (highest) */ +#ifdef QK_USE_IRQ_NUM //--------- QK IRQ specified? + // The QK port is configured to use a given ARM Cortex-M IRQ # + // to return to thread mode (default is to use the NMI exception) + NVIC_IP[QK_USE_IRQ_NUM] = 0U; // priority 0 (highest) NVIC_EN[QK_USE_IRQ_NUM >> 5U] = (1U << (QK_USE_IRQ_NUM & 0x1FU)); -#endif /*--------- QK IRQ specified */ +#endif //--------- QK IRQ specified -#if (__ARM_FP != 0) /*--------- if VFP available... */ - /* configure the FPU for QK */ - FPU_FPCCR |= (1U << 30U) /* automatic FPU state preservation (ASPEN) */ - | (1U << 31U); /* lazy stacking (LSPEN) */ -#endif /*--------- VFP available */ +#ifdef __ARM_FP //--------- if VFP available... + // make sure that the FPU is enabled by seting CP10 & CP11 Full Access + SCB_CPACR = (SCB_CPACR | ((3UL << 20U) | (3UL << 22U))); + + // FPU automatic state preservation (ASPEN) lazy stacking (LSPEN) + FPU_FPCCR = (FPU_FPCCR | (1U << 30U) | (1U << 31U)); +#endif //--------- VFP available } -/*..........................................................................*/ -/* The PendSV_Handler exception is used for handling the asynchronous -* preemption in QK. The use of the PendSV exception is the recommended and -* the most efficient method for performing context switches with ARM Cortex-M. -* -* The PendSV exception should have the lowest priority in the whole system -* (0xFF, see QK_init). All other exceptions and interrupts should have higher -* priority. For example, for NVIC with 2 priority bits all interrupts and -* exceptions must have numerical value of priority lower than 0xC0. In this -* case the interrupt priority levels available to your applications are (in -* the order from the lowest urgency to the highest urgency): 0x80, 0x40, 0x00. -* -* Also, *all* "kernel aware" ISRs in the QK application must call the -* QK_ISR_EXIT() macro, which triggers PendSV when it detects a need for -* a context switch or asynchronous preemption. -* -* Due to tail-chaining and its lowest priority, the PendSV exception will be -* entered immediately after the exit from the *last* nested interrupt (or -* exception). In QK, this is exactly the time when the QK activator needs to -* handle the asynchronous preemption. -*/ +//............................................................................ +// The PendSV_Handler exception is used for handling the asynchronous +// preemption in QK. The use of the PendSV exception is the recommended and +// the most efficient method for performing context switches with ARM Cortex-M. +// +// The PendSV exception should have the lowest priority in the whole system +// (0xFF, see QK_init). All other exceptions and interrupts should have higher +// priority. For example, for NVIC with 2 priority bits all interrupts and +// exceptions must have numerical value of priority lower than 0xC0. In this +// case the interrupt priority levels available to your applications are (in +// the order from the lowest urgency to the highest urgency): 0x80, 0x40, 0x00. +// +// Also, *all* "kernel aware" ISRs in the QK application must call the +// QK_ISR_EXIT() macro, which triggers PendSV when it detects a need for +// a context switch or asynchronous preemption. +// +// Due to tail-chaining and its lowest priority, the PendSV exception will be +// entered immediately after the exit from the *last* nested interrupt (or +// exception). In QK, this is exactly the time when the QK activator needs to +// handle the asynchronous preemption. __attribute__ ((naked)) void PendSV_Handler(void) { __asm volatile ( + " PUSH {r0,lr} \n" // save EXC_RETURN + stack-aligner - /* Prepare constants in registers before entering critical section */ - " LDR r3,=" STRINGIFY(NVIC_ICSR) "\n" /* Interrupt Control and State */ - " MOVS r1,#1 \n" - " LSLS r1,r1,#27 \n" /* r0 := (1 << 27) (UNPENDSVSET bit) */ - - /*<<<<<<<<<<<<<<<<<<<<<<< CRITICAL SECTION BEGIN <<<<<<<<<<<<<<<<<<<<<<<<*/ -#if (__ARM_ARCH == 6) /*--------- if ARMv6-M... */ - " CPSID i \n" /* disable interrupts (set PRIMASK) */ -#else /* ARMv7-M and higher */ -#if (__ARM_FP != 0) /*--------- if VFP available... */ - " PUSH {r0,lr} \n" /* ... push lr plus stack-aligner */ -#endif /*--------- VFP available */ + //<<<<<<<<<<<<<<<<<<<<<<< CRITICAL SECTION BEGIN <<<<<<<<<<<<<<<<<<<<<<<< +#if (__ARM_ARCH == 6) //--------- if ARMv6-M... + " CPSID i \n" // disable interrupts (set PRIMASK) +#else // ARMv7-M and higher " MOVS r0,#" STRINGIFY(QF_BASEPRI) "\n" - " CPSID i \n" /* disable interrupts with BASEPRI */ - " MSR BASEPRI,r0 \n" /* apply the Cortex-M7 erraturm */ - " CPSIE i \n" /* 837070, see SDEN-1068427. */ -#endif /*--------- ARMv7-M and higher */ + " CPSID i \n" // disable interrupts with BASEPRI + " MSR BASEPRI,r0 \n" // apply the Cortex-M7 erraturm + " CPSIE i \n" // 837070, see SDEN-1068427. +#endif //--------- ARMv7-M and higher - /* The PendSV exception handler can be preempted by an interrupt, - * which might pend PendSV exception again. The following write to - * ICSR[27] un-pends any such spurious instance of PendSV. - */ - " STR r1,[r3] \n" /* ICSR[27] := 1 (unpend PendSV) */ +#ifdef QF_MEM_ISOLATE + " LDR r0,=QF_onMemSys \n" + " BLX r0 \n" // call QF_onMemSys() +#endif - /* The QK activator must be called in a Thread mode, while this code - * executes in the Handler mode of the PendSV exception. The switch - * to the Thread mode is accomplished by returning from PendSV using - * a fabricated exception stack frame, where the return address is - * QK_activate_(). - * - * NOTE: the QK activator is called with interrupts DISABLED and also - * returns with interrupts DISABLED. - */ - " LSRS r3,r1,#3 \n" /* r3 := (r1 >> 3), set the T bit (new xpsr) */ - " LDR r2,=QK_activate_ \n" /* address of QK_activate_ */ - " SUBS r2,r2,#1 \n" /* align Thumb-address at halfword (new pc) */ - " LDR r1,=QK_thread_ret \n" /* return address after the call (new lr) */ + // The PendSV exception handler can be preempted by an interrupt, + // which might pend PendSV exception again. The following write to + // ICSR[27] un-pends any such spurious instance of PendSV. + " LDR r2,=" STRINGIFY(SCB_ICSR) "\n" // Interrupt Control and State + " MOVS r1,#1 \n" + " LSLS r1,r1,#27 \n" // r1 := (1 << 27) (UNPENDSVSET bit) + " STR r1,[r2] \n" // ICSR[27] := 1 (unpend PendSV) - " SUB sp,sp,#8*4 \n" /* reserve space for exception stack frame */ - " ADD r0,sp,#5*4 \n" /* r0 := 5 registers below the SP */ - " STM r0!,{r1-r3} \n" /* save xpsr,pc,lr */ + // The QK activator must be called in a Thread mode, while this code + // executes in the Handler mode of the PendSV exception. The switch + // to the Thread mode is accomplished by returning from PendSV using + // a fabricated exception stack frame, where the return address is + // QK_activate_(). + // + // NOTE: the QK activator is called with interrupts DISABLED and also + // returns with interrupts DISABLED. + " LSRS r3,r1,#3 \n" // r3 := (r1 >> 3), set T bit (new xpsr) + " LDR r2,=QK_activate_ \n" // address of QK_activate_ + " SUBS r2,r2,#1 \n" // align Thumb-address at halfword (new pc) + " LDR r1,=QK_thread_ret \n" // return address after the call (new lr) + + " SUB sp,sp,#8*4 \n" // reserve space for exception stack frame + " ADD r0,sp,#5*4 \n" // r0 := 5 registers below the SP + " STM r0!,{r1-r3} \n" // save xpsr,pc,lr " MOVS r0,#6 \n" - " MVNS r0,r0 \n" /* r0 := ~6 == 0xFFFFFFF9 */ -#if (__ARM_ARCH != 6) /*--------- if ARMv7-M and higher... */ - " DSB \n" /* ARM Erratum 838869 */ -#endif /*--------- ARMv7-M and higher */ - " BX r0 \n" /* exception-return to the QK activator */ + " MVNS r0,r0 \n" // r0 := ~6 == 0xFFFFFFF9 +#if (__ARM_ARCH != 6) //--------- if ARMv7-M and higher... + " DSB \n" // ARM Erratum 838869 +#endif //--------- ARMv7-M and higher + " BX r0 \n" // exception-return to the QK activator ); } -/*==========================================================================*/ -/* QK_thread_ret is a helper function executed when the QXK activator returns. -* -* NOTE: QK_thread_ret does not execute in the PendSV context! -* NOTE: QK_thread_ret is entered with interrupts DISABLED. -*/ +//============================================================================ +// QK_thread_ret is a helper function executed when the QXK activator returns. +// +// NOTE: QK_thread_ret does not execute in the PendSV context! +// NOTE: QK_thread_ret is entered with interrupts DISABLED. __attribute__ ((naked, used)) void QK_thread_ret(void) { __asm volatile ( - /* After the QK activator returns, we need to resume the preempted - * thread. However, this must be accomplished by a return-from-exception, - * while we are still in the thread context. The switch to the exception - * context is accomplished by triggering the NMI exception or the selected - * IRQ (if macro #QK_USE_IRQ_NUM is defined). - */ + // After the QK activator returns, we need to resume the preempted + // thread. However, this must be accomplished by a return-from-exception, + // while we are still in the thread context. The switch to the exception + // context is accomplished by triggering the NMI exception or the selected + // IRQ (if macro #QK_USE_IRQ_NUM is defined). - /* before triggering the NMI/IRQ, make sure that the VFP stack frame - * will NOT be used... - */ -#if (__ARM_FP != 0) /*--------- if VFP available... */ - /* make sure that the VFP stack frame will NOT be used */ - " MRS r0,CONTROL \n" /* r0 := CONTROL */ - " BICS r0,r0,#4 \n" /* r0 := r0 & ~4 (FPCA bit) */ - " MSR CONTROL,r0 \n" /* CONTROL := r0 (clear CONTROL[2] FPCA bit) */ - " ISB \n" /* ISB after MSR CONTROL (ARM AN321,Sect.4.16) */ -#endif /*--------- VFP available */ + // before triggering the NMI/IRQ, make sure that the VFP stack frame + // will NOT be used... +#ifdef __ARM_FP //--------- if VFP available... + // make sure that the VFP stack frame will NOT be used + " MRS r0,CONTROL \n" // r0 := CONTROL + " BICS r0,r0,#4 \n" // r0 := r0 & ~4 (FPCA bit) + " MSR CONTROL,r0 \n" // CONTROL := r0 (clear CONTROL[2] FPCA bit) + " ISB \n" // ISB after MSR CONTROL (ARM AN321,Sect.4.16) +#endif //--------- VFP available -#ifndef QK_USE_IRQ_NUM /*--------- IRQ NOT defined, use NMI by default */ - " LDR r0,=" STRINGIFY(NVIC_ICSR) "\n" /* Interrupt Control and State */ +#ifdef QF_MEM_ISOLATE + " LDR r0,=QF_onMemApp \n" + " BLX r0 \n" // call QF_onMemApp() +#endif + +#ifndef QK_USE_IRQ_NUM //--------- IRQ NOT defined, use NMI by default + " LDR r0,=" STRINGIFY(SCB_ICSR) "\n" // Interrupt Control and State " MOVS r1,#1 \n" - " LSLS r1,r1,#31 \n" /* r1 := (1 << 31) (NMI bit) */ - " STR r1,[r0] \n" /* ICSR[31] := 1 (pend NMI) */ + " LSLS r1,r1,#31 \n" // r1 := (1 << 31) (NMI bit) + " STR r1,[r0] \n" // ICSR[31] := 1 (pend NMI) -#else /*--------- use the selected IRQ */ +#else //--------- use the selected IRQ " LDR r0,=" STRINGIFY(NVIC_PEND + ((QK_USE_IRQ_NUM >> 5) << 2)) "\n" " MOVS r1,#1 \n" - " LSLS r1,r1,#" STRINGIFY(QK_USE_IRQ_NUM & 0x1F) "\n" /* r1 := IRQ bit */ - " STR r1,[r0] \n" /* pend the IRQ */ + " LSLS r1,r1,#" STRINGIFY(QK_USE_IRQ_NUM & 0x1F) "\n" // r1 := IRQ bit + " STR r1,[r0] \n" // pend the IRQ - /* now enable interrupts so that pended IRQ can be entered */ -#if (__ARM_ARCH == 6) /*--------- if ARMv6-M... */ - " CPSIE i \n" /* enable interrupts (clear PRIMASK) */ -#else /*--------- ARMv7-M and higher */ + // now enable interrupts so that pended IRQ can be entered +#if (__ARM_ARCH == 6) //--------- if ARMv6-M... + " CPSIE i \n" // enable interrupts (clear PRIMASK) +#else //--------- ARMv7-M and higher " MOVS r0,#0 \n" - " MSR BASEPRI,r0 \n" /* enable interrupts (clear BASEPRI) */ -#endif /*--------- ARMv7-M and higher */ -#endif /*--------- use IRQ */ + " MSR BASEPRI,r0 \n" // enable interrupts (clear BASEPRI) +#endif //--------- ARMv7-M and higher +#endif //--------- use IRQ - /* NOTE! interrupts are still disabled when NMI is used */ - " B . \n" /* wait for preemption by NMI/IRQ */ + // NOTE! interrupts are still disabled when NMI is used + " B . \n" // wait for preemption by NMI/IRQ ); } -/*==========================================================================*/ -/* This exception handler is used for returning back to the preempted thread. -* The exception handler simply removes its own interrupt stack frame from -* the stack (MSP) and returns to the preempted task using the interrupt -* stack frame that must be at the top of the stack. -*/ +//============================================================================ +// This exception handler is used for returning back to the preempted thread. +// The exception handler simply removes its own interrupt stack frame from +// the stack (MSP) and returns to the preempted task using the interrupt +// stack frame that must be at the top of the stack. __attribute__ ((naked)) -#ifndef QK_USE_IRQ_NUM /*--------- IRQ NOT defined, use NMI by default */ +#ifndef QK_USE_IRQ_NUM //--------- IRQ NOT defined, use NMI by default -/* NOTE: The NMI_Handler() is entered with interrupts still disabled! */ +// NOTE: The NMI_Handler() is entered with interrupts still disabled! void NMI_Handler(void) { __asm volatile ( - /* enable interrupts */ -#if (__ARM_ARCH == 6) /*--------- if ARMv6-M... */ - " CPSIE i \n" /* enable interrupts (clear PRIMASK) */ -#else /*--------- ARMv7-M and higher */ + // enable interrupts +#if (__ARM_ARCH == 6) //--------- if ARMv6-M... + " CPSIE i \n" // enable interrupts (clear PRIMASK) +#else //--------- ARMv7-M and higher " MOVS r0,#0 \n" - " MSR BASEPRI,r0 \n" /* enable interrupts (clear BASEPRI) */ -#endif /*--------- ARMv7-M and higher */ + " MSR BASEPRI,r0 \n" // enable interrupts (clear BASEPRI) +#endif //--------- ARMv7-M and higher ); -#else /*--------- use the selected IRQ */ +#else //--------- use the selected IRQ -/* NOTE: The IRQ Handler is entered with interrupts enabled */ +// NOTE: The IRQ Handler is entered with interrupts enabled void QK_USE_IRQ_HANDLER(void) { -#endif /*--------- use IRQ */ +#endif //--------- use IRQ __asm volatile ( - " ADD sp,sp,#(8*4) \n" /* remove one 8-register exception frame */ + " ADD sp,sp,#(8*4) \n" // remove one 8-register exception frame -#if (__ARM_FP != 0) /*--------- if VFP available... */ - " POP {r0,lr} \n" /* pop stack aligner and EXC_RETURN to LR */ - " DSB \n" /* ARM Erratum 838869 */ -#endif /*--------- VFP available */ - " BX lr \n" /* return to the preempted task */ + " POP {r0,r1} \n" // pop stack aligner and EXC_RETURN to r1 + " DSB \n" // ARM Erratum 838869 + " BX r1 \n" // return to the preempted task ); } -/*==========================================================================*/ -#if (__ARM_ARCH == 6) /* if ARMv6-M... */ +//============================================================================ +#if (__ARM_ARCH == 6) // if ARMv6-M... -/* hand-optimized quick LOG2 in assembly (no CLZ instruction in ARMv6-M) */ +// hand-optimized quick LOG2 in assembly (no CLZ instruction in ARMv6-M) __attribute__ ((naked)) uint_fast8_t QF_qlog2(uint32_t x) { __asm volatile ( @@ -316,5 +306,5 @@ __asm volatile ( ); } -#endif /* ARMv6-M */ +#endif // ARMv6-M diff --git a/ports/arm-cm/qk/armclang/qk_port.h b/ports/arm-cm/qk/armclang/qk_port.h deleted file mode 100644 index 3903a935..00000000 --- a/ports/arm-cm/qk/armclang/qk_port.h +++ /dev/null @@ -1,95 +0,0 @@ -/*============================================================================ -* QP/C Real-Time Embedded Framework (RTEF) -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2022-12-18 -* @version Last updated for: @ref qpc_7_2_0 -* -* @file -* @brief QK/C port to ARM Cortex-M, ARM-CLANG toolset -*/ -#ifndef QK_PORT_H -#define QK_PORT_H - -/* determination if the code executes in the ISR context */ -#define QK_ISR_CONTEXT_() (QK_get_IPSR() != 0U) - -__attribute__((always_inline)) -static inline uint32_t QK_get_IPSR(void) { - uint32_t regIPSR; - __asm volatile ("mrs %0,ipsr" : "=r" (regIPSR)); - return regIPSR; -} - -/* QK ISR entry and exit */ -#define QK_ISR_ENTRY() ((void)0) - -#define QK_ISR_EXIT() do { \ - QF_INT_DISABLE(); \ - if (QK_sched_() != 0U) { \ - *Q_UINT2PTR_CAST(uint32_t, 0xE000ED04U) = (1U << 28U);\ - } \ - QF_INT_ENABLE(); \ - QK_ARM_ERRATUM_838869(); \ -} while (false) - -#if (__ARM_ARCH == 6) /* ARMv6-M? */ - #define QK_ARM_ERRATUM_838869() ((void)0) -#else /* ARMv7-M or higher */ - /* The following macro implements the recommended workaround for the - * ARM Erratum 838869. Specifically, for Cortex-M3/M4/M7 the DSB - * (memory barrier) instruction needs to be added before exiting an ISR. - */ - #define QK_ARM_ERRATUM_838869() \ - __asm volatile ("dsb" ::: "memory") -#endif - -/* Use a given ARM Cortex-M IRQ to return to thread mode (default NMI) -* -* NOTE: -* If you need the NMI for other purposes, you can define the macros -* QK_USE_IRQ_NUM and QK_USE_IRQ_HANDLER to use thus specified IRQ -* instead of the NMI (the IRQ should not be used for anything else). -* These two macros can be defined on the command line to the compiler -* and are actually needed only to compile the qk_port.c file. -*/ -//#define QK_USE_IRQ_NUM 25 -//#define QK_USE_IRQ_HANDLER CRYPTO_IRQHandler - -/* initialization of the QK kernel */ -#define QK_INIT() QK_init() -void QK_init(void); -void QK_thread_ret(void); - -#if (__ARM_FP != 0) /* if VFP available... */ -/* When the FPU is configured, clear the FPCA bit in the CONTROL register -* to prevent wasting the stack space for the FPU context. -*/ -#define QK_START() __asm volatile ("msr CONTROL,%0" :: "r" (0) : ) -#endif - -#include "qk.h" /* QK platform-independent public interface */ - -#endif /* QK_PORT_H */ - diff --git a/ports/arm-cm/qk/armclang/qp_port.h b/ports/arm-cm/qk/armclang/qp_port.h new file mode 100644 index 00000000..1b75806f --- /dev/null +++ b/ports/arm-cm/qk/armclang/qp_port.h @@ -0,0 +1,239 @@ +//============================================================================ +// QP/C Real-Time Embedded Framework (RTEF) +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC . +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +//============================================================================ +//! @date Last updated on: 2023-09-07 +//! @version Last updated for: @ref qpc_7_3_0 +//! +//! @file +//! @brief QP/C port to ARM Cortex-M, preemptive QK kernel, ARM-CLANG + +#ifndef QP_PORT_H_ +#define QP_PORT_H_ + +#include // Exact-width types. WG14/N843 C99 Standard +#include // Boolean type. WG14/N843 C99 Standard + +#ifdef QP_CONFIG +#include "qp_config.h" // external QP configuration +#endif + +// no-return function specifier (C11 Standard) +#define Q_NORETURN _Noreturn void + +// QF configuration for QK -- data members of the QActive class... + +// QK event-queue used for AOs +#define QACTIVE_EQUEUE_TYPE QEQueue + +// QF "thread" type used to store the MPU settings in the AO +#define QACTIVE_THREAD_TYPE void const * + +// QF interrupt disable/enable and log2()... +#if (__ARM_ARCH == 6) // ARMv6-M? + + // Cortex-M0/M0+/M1(v6-M, v6S-M) interrupt disabling policy, see NOTE2 + #define QF_INT_DISABLE() __asm volatile ("cpsid i" ::: "memory") + #define QF_INT_ENABLE() __asm volatile ("cpsie i" ::: "memory") + + // QF critical section (save and restore interrupt status), see NOTE2 + #define QF_CRIT_STAT uint32_t primask_; + #define QF_CRIT_ENTRY() __asm volatile (\ + "mrs %0,PRIMASK\n" "cpsid i" : "=r" (primask_) :: "memory") + #define QF_CRIT_EXIT() __asm volatile (\ + "msr PRIMASK,%0" :: "r" (primask_) : "memory") + + // CMSIS threshold for "QF-aware" interrupts, see NOTE2 and NOTE4 + #define QF_AWARE_ISR_CMSIS_PRI 0 + + // hand-optimized LOG2 in assembly for Cortex-M0/M0+/M1(v6-M, v6S-M) + #define QF_LOG2(n_) QF_qlog2((uint32_t)(n_)) + +#else // ARMv7-M or higher + + // ARMv7-M or higher alternative interrupt disabling with PRIMASK + #define QF_PRIMASK_DISABLE() __asm volatile ("cpsid i" ::: "memory") + #define QF_PRIMASK_ENABLE() __asm volatile ("cpsie i" ::: "memory") + + // ARMv7-M or higher interrupt disabling policy, see NOTE3 and NOTE4 + #define QF_INT_DISABLE() __asm volatile (\ + "cpsid i\n" "msr BASEPRI,%0\n" "cpsie i" \ + :: "r" (QF_BASEPRI) : "memory") + #define QF_INT_ENABLE() __asm volatile (\ + "msr BASEPRI,%0" :: "r" (0) : "memory") + + // QF critical section (save and restore interrupt status), see NOTE5 + #define QF_CRIT_STAT uint32_t basepri_; + #define QF_CRIT_ENTRY() do { \ + __asm volatile ("mrs %0,BASEPRI" : "=r" (basepri_) :: "memory"); \ + __asm volatile ("cpsid i\n msr BASEPRI,%0\n cpsie i" \ + :: "r" (QF_BASEPRI) : "memory"); \ + } while (false) + #define QF_CRIT_EXIT() \ + __asm volatile ("msr BASEPRI,%0" :: "r" (basepri_) : "memory") + + // BASEPRI threshold for "QF-aware" interrupts, see NOTE3 + #define QF_BASEPRI 0x3F + + // CMSIS threshold for "QF-aware" interrupts, see NOTE5 + #define QF_AWARE_ISR_CMSIS_PRI (QF_BASEPRI >> (8 - __NVIC_PRIO_BITS)) + + // ARMv7-M or higher provide the CLZ instruction for fast LOG2 + #define QF_LOG2(n_) ((uint_fast8_t)(32 - __builtin_clz((unsigned)(n_)))) + +#endif + +#define QF_CRIT_EXIT_NOP() __asm volatile ("isb" ::: "memory") + +#if (__ARM_ARCH == 6) // ARMv6-M? + // hand-optimized quick LOG2 in assembly + uint_fast8_t QF_qlog2(uint32_t x); +#endif // ARMv7-M or higher + +// Memory isolation ---------------------------------------------------------- +#ifdef QF_MEM_ISOLATE + + // Memory isolation requires the context-switch + #define QF_ON_CONTEXT_SW 1U + + // Memory System setting + #define QF_MEM_SYS() QF_onMemSys() + + // Memory Application setting + #define QF_MEM_APP() QF_onMemApp() + + // callback functions for memory settings (provided by applications) + void QF_onMemSys(void); + void QF_onMemApp(void); + +#endif // def QF_MEM_ISOLATE + +// determination if the code executes in the ISR context +#define QK_ISR_CONTEXT_() (QK_get_IPSR() != 0U) + +__attribute__((always_inline)) +static inline uint32_t QK_get_IPSR(void) { + uint32_t regIPSR; + __asm volatile ("mrs %0,ipsr" : "=r" (regIPSR)); + return regIPSR; +} + +// QK ISR entry and exit +#define QK_ISR_ENTRY() ((void)0) + +#ifdef QF_MEM_ISOLATE + #define QK_ISR_EXIT() do { \ + QF_INT_DISABLE(); \ + QF_MEM_SYS(); \ + if (QK_sched_() != 0U) { \ + *Q_UINT2PTR_CAST(uint32_t, 0xE000ED04U) = (1U << 28U);\ + } \ + QF_MEM_APP(); \ + QF_INT_ENABLE(); \ + QK_ARM_ERRATUM_838869(); \ + } while (false) +#else + #define QK_ISR_EXIT() do { \ + QF_INT_DISABLE(); \ + if (QK_sched_() != 0U) { \ + *Q_UINT2PTR_CAST(uint32_t, 0xE000ED04U) = (1U << 28U);\ + } \ + QF_INT_ENABLE(); \ + QK_ARM_ERRATUM_838869(); \ + } while (false) +#endif + +#if (__ARM_ARCH == 6) // ARMv6-M? + #define QK_ARM_ERRATUM_838869() ((void)0) +#else // ARMv7-M or higher + // The following macro implements the recommended workaround for the + // ARM Erratum 838869. Specifically, for Cortex-M3/M4/M7 the DSB + // (memory barrier) instruction needs to be added before exiting an ISR. + #define QK_ARM_ERRATUM_838869() \ + __asm volatile ("dsb" ::: "memory") + +#endif // ARMv6-M + +// initialization of the QK kernel +#define QK_INIT() QK_init() +void QK_init(void); +void QK_thread_ret(void); + +#ifdef __ARM_FP //--------- if VFP available... +// When the FPU is configured, clear the FPCA bit in the CONTROL register +// to prevent wasting the stack space for the FPU context. +#define QK_START() __asm volatile ("msr CONTROL,%0" :: "r" (0) : ) +#endif + +// include files ------------------------------------------------------------- +#include "qequeue.h" // QK kernel uses the native QP event queue +#include "qmpool.h" // QK kernel uses the native QP memory pool +#include "qp.h" // QP framework +#include "qk.h" // QK kernel + +//============================================================================ +// NOTE2: +// On Cortex-M0/M0+/M1 (architecture v6-M, v6S-M), the interrupt disabling +// policy uses the PRIMASK register to disable interrupts globally. The +// QF_AWARE_ISR_CMSIS_PRI level is zero, meaning that all interrupts are +// "QF-aware". +// +// NOTE3: +// On ARMv7-M or higher, the interrupt disable/enable policy uses the BASEPRI +// register (which is not implemented in Cortex-M0/M0+/M1) to disable +// interrupts only with priority lower than the threshold specified by the +// QF_BASEPRI macro. The interrupts with priorities above QF_BASEPRI (i.e., +// with numerical priority values lower than QF_BASEPRI) are NOT disabled in +// this method. These free-running interrupts have very low ("zero") latency, +// but they are not allowed to call any QF services, because QF is unaware +// of them ("QF-unaware" interrupts). Consequently, only interrupts with +// numerical values of priorities equal to or higher than QF_BASEPRI +// ("QF-aware" interrupts ), can call QF services. +// +// NOTE4: +// The QF_AWARE_ISR_CMSIS_PRI macro is useful as an offset for enumerating +// the "QF-aware" interrupt priorities in the applications, whereas the +// numerical values of the "QF-aware" interrupts must be greater or equal to +// QF_AWARE_ISR_CMSIS_PRI. The values based on QF_AWARE_ISR_CMSIS_PRI can be +// passed directly to the CMSIS function NVIC_SetPriority(), which shifts +// them by (8 - __NVIC_PRIO_BITS) into the correct bit position, while +// __NVIC_PRIO_BITS is the CMSIS macro defining the number of implemented +// priority bits in the NVIC. Please note that the macro QF_AWARE_ISR_CMSIS_PRI +// is intended only for applications and is not used inside the QF port, which +// remains generic and not dependent on the number of implemented priority bits +// implemented in the NVIC. +// +// NOTE5: +// The selective disabling of "QF-aware" interrupts with the BASEPRI register +// has a problem on ARM Cortex-M7 core r0p1 (see ARM-EPM-064408, errata +// 837070). The workaround recommended by ARM is to surround MSR BASEPRI with +// the CPSID i/CPSIE i pair, which is implemented in the QF_INT_DISABLE() +// macro. This workaround works also for Cortex-M3/M4 cores. + +#endif // QP_PORT_H_ + diff --git a/ports/arm-cm/qk/armclang/qs_port.h b/ports/arm-cm/qk/armclang/qs_port.h index e8b00882..92ec4663 100644 --- a/ports/arm-cm/qk/armclang/qs_port.h +++ b/ports/arm-cm/qk/armclang/qs_port.h @@ -1,60 +1,61 @@ -/*============================================================================ -* QP/C Real-Time Embedded Framework (RTEF) -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2022-06-12 -* @version Last updated for: @ref qpc_7_0_1 -* -* @file -* @brief QS/C port to a 32-bit CPU and a generic C99 compiler. -* @description -* This is an example of a QP/C port with the documentation for the -* configuration macros and includes. -*/ -#ifndef QS_PORT_H -#define QS_PORT_H +//============================================================================ +// QP/C Real-Time Embedded Framework (RTEF) +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +//============================================================================ +//! @date Last updated on: 2023-08-16 +//! @version Last updated for: @ref qpc_7_3_0 +//! +//! @file +//! @brief QS/C port to a 32-bit CPU and a generic C11 compiler. -/* QS time-stamp size in bytes */ -#define QS_TIME_SIZE 4 +#ifndef QS_PORT_H_ +#define QS_PORT_H_ -/* object pointer size in bytes */ -#define QS_OBJ_PTR_SIZE 4 +// QS time-stamp size in bytes +#define QS_TIME_SIZE 4U -/* function pointer size in bytes */ -#define QS_FUN_PTR_SIZE 4 +// object pointer size in bytes +#define QS_OBJ_PTR_SIZE 4U -/*==========================================================================*/ -/* NOTE: QS might be used with or without other QP components, in which -* case the separate definitions of the macros QF_CRIT_STAT_TYPE, -* QF_CRIT_ENTRY, and QF_CRIT_EXIT are needed. In this port QS is configured -* to be used with the other QP component, by simply including "qf_port.h" -* *before* "qs.h". -*/ -#ifndef QF_PORT_H -#include "qf_port.h" /* use QS with QF */ +// function pointer size in bytes +#define QS_FUN_PTR_SIZE 4U + +//============================================================================ +// NOTE: QS might be used with or without other QP components, in which +// case the separate definitions of the macros QF_CRIT_STAT, QF_CRIT_ENTRY(), +// and QF_CRIT_EXIT() are needed. In this port QS is configured to be used +// with the other QP component, by simply including "qp_port.h" +//*before* "qs.h". +#ifndef QP_PORT_H_ +#include "qp_port.h" // use QS with QF #endif -#include "qs.h" /* QS platform-independent public interface */ +#include "qs.h" // QS platform-independent public interface + +#endif // QS_PORT_H_ -#endif /* QS_PORT_H */ diff --git a/ports/arm-cm/qk/gnu/qep_port.h b/ports/arm-cm/qk/gnu/qep_port.h deleted file mode 100644 index 5ff325e4..00000000 --- a/ports/arm-cm/qk/gnu/qep_port.h +++ /dev/null @@ -1,44 +0,0 @@ -/*============================================================================ -* QEP/C port to ARM Cortex-M, GNU-ARM -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2022-04-09 -* @version Last updated for: @ref qpc_7_0_0 -* -* @file -* @brief QEP/C port, GNU-ARM compiler -*/ -#ifndef QEP_PORT_H -#define QEP_PORT_H - -/*! no-return function specifier (GCC-ARM compiler) */ -#define Q_NORETURN __attribute__ ((noreturn)) void - -#include /* Exact-width types. WG14/N843 C99 Standard */ -#include /* Boolean type. WG14/N843 C99 Standard */ - -#include "qep.h" /* QEP platform-independent public interface */ - -#endif /* QEP_PORT_H */ - diff --git a/ports/arm-cm/qk/gnu/qf_port.h b/ports/arm-cm/qk/gnu/qf_port.h deleted file mode 100644 index 34738617..00000000 --- a/ports/arm-cm/qk/gnu/qf_port.h +++ /dev/null @@ -1,147 +0,0 @@ -/*============================================================================ -* QF/C port to ARM Cortex-M, QK, GNU-ARM -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2022-04-09 -* @version Last updated for: @ref qpc_7_0_0 -* -* @file -* @brief QF/C port to Cortex-M, preemptive QK kernel, GNU-ARM toolset -*/ -#ifndef QF_PORT_H -#define QF_PORT_H - -/* The maximum number of system clock tick rates */ -#define QF_MAX_TICK_RATE 2U - -/* QF interrupt disable/enable and log2()... */ -#if (__ARM_ARCH == 6) /* Cortex-M0/M0+/M1(v6-M, v6S-M)? */ - - /* The maximum number of active objects in the application, see NOTE1 */ - #define QF_MAX_ACTIVE 16U - - /* Cortex-M0/M0+/M1(v6-M, v6S-M) interrupt disabling policy, see NOTE2 */ - #define QF_INT_DISABLE() __asm volatile ("cpsid i") - #define QF_INT_ENABLE() __asm volatile ("cpsie i") - - /* QF critical section entry/exit (unconditional interrupt disabling) */ - /*#define QF_CRIT_STAT_TYPE not defined */ - #define QF_CRIT_ENTRY(dummy) QF_INT_DISABLE() - #define QF_CRIT_EXIT(dummy) QF_INT_ENABLE() - - /* CMSIS threshold for "QF-aware" interrupts, see NOTE2 and NOTE4 */ - #define QF_AWARE_ISR_CMSIS_PRI 0 - - /* hand-optimized LOG2 in assembly for Cortex-M0/M0+/M1(v6-M, v6S-M) */ - #define QF_LOG2(n_) QF_qlog2((uint32_t)(n_)) - -#else /* Cortex-M3/M4/M7 */ - - /* The maximum number of active objects in the application, see NOTE1 */ - #define QF_MAX_ACTIVE 32U - - /* Cortex-M3/M4/M7 alternative interrupt disabling with PRIMASK */ - #define QF_PRIMASK_DISABLE() __asm volatile ("cpsid i") - #define QF_PRIMASK_ENABLE() __asm volatile ("cpsie i") - - /* Cortex-M3/M4/M7 interrupt disabling policy, see NOTE3 and NOTE4 */ - #define QF_INT_DISABLE() __asm volatile (\ - "cpsid i\n" "msr BASEPRI,%0\n" "cpsie i" :: "r" (QF_BASEPRI) : ) - #define QF_INT_ENABLE() __asm volatile (\ - "msr BASEPRI,%0" :: "r" (0) : ) - - /* QF critical section entry/exit (unconditional interrupt disabling) */ - /*#define QF_CRIT_STAT_TYPE not defined */ - #define QF_CRIT_ENTRY(dummy) QF_INT_DISABLE() - #define QF_CRIT_EXIT(dummy) QF_INT_ENABLE() - - /* BASEPRI threshold for "QF-aware" interrupts, see NOTE3 */ - #define QF_BASEPRI 0x3F - - /* CMSIS threshold for "QF-aware" interrupts, see NOTE5 */ - #define QF_AWARE_ISR_CMSIS_PRI (QF_BASEPRI >> (8 - __NVIC_PRIO_BITS)) - - /* Cortex-M3/M4/M7 provide the CLZ instruction for fast LOG2 */ - #define QF_LOG2(n_) ((uint_fast8_t)(32U - __builtin_clz((unsigned)(n_)))) - -#endif - -#define QF_CRIT_EXIT_NOP() __asm volatile ("isb") - -#include "qep_port.h" /* QEP port */ - -#if (__ARM_ARCH == 6) /* ARMv6-M? */ - /* hand-optimized quick LOG2 in assembly */ - uint_fast8_t QF_qlog2(uint32_t x); -#endif /* ARMv7-M or higher */ - -#include "qk_port.h" /* QK preemptive kernel port */ -#include "qf.h" /* QF platform-independent public interface */ - -/***************************************************************************** -* NOTE1: -* The maximum number of active objects QF_MAX_ACTIVE can be increased -* up to 64U, if necessary. Here it is set to a lower level to save some RAM. -* -* NOTE2: -* On Cortex-M0/M0+/M1 (architecture v6-M, v6S-M), the interrupt disabling -* policy uses the PRIMASK register to disable interrupts globally. The -* QF_AWARE_ISR_CMSIS_PRI level is zero, meaning that all interrupts are -* "QF-aware". -* -* NOTE3: -* On Cortex-M3/M4/M7, the interrupt disable/enable policy uses the BASEPRI -* register (which is not implemented in Cortex-M0/M0+/M1) to disable -* interrupts only with priority lower than the threshold specified by the -* QF_BASEPRI macro. The interrupts with priorities above QF_BASEPRI (i.e., -* with numerical priority values lower than QF_BASEPRI) are NOT disabled in -* this method. These free-running interrupts have very low ("zero") latency, -* but they are not allowed to call any QF services, because QF is unaware -* of them ("QF-unaware" interrutps). Consequently, only interrupts with -* numerical values of priorities eqal to or higher than QF_BASEPRI -* ("QF-aware" interrupts ), can call QF services. -* -* NOTE4: -* The QF_AWARE_ISR_CMSIS_PRI macro is useful as an offset for enumerating -* the "QF-aware" interrupt priorities in the applications, whereas the -* numerical values of the "QF-aware" interrupts must be greater or equal to -* QF_AWARE_ISR_CMSIS_PRI. The values based on QF_AWARE_ISR_CMSIS_PRI can be -* passed directly to the CMSIS function NVIC_SetPriority(), which shifts -* them by (8 - __NVIC_PRIO_BITS) into the correct bit position, while -* __NVIC_PRIO_BITS is the CMSIS macro defining the number of implemented -* priority bits in the NVIC. Please note that the macro QF_AWARE_ISR_CMSIS_PRI -* is intended only for applications and is not used inside the QF port, which -* remains generic and not dependent on the number of implemented priority bits -* implemented in the NVIC. -* -* NOTE5: -* The selective disabling of "QF-aware" interrupts with the BASEPRI register -* has a problem on ARM Cortex-M7 core r0p1 (see ARM-EPM-064408, errata -* 837070). The workaround recommended by ARM is to surround MSR BASEPRI with -* the CPSID i/CPSIE i pair, which is implemented in the QF_INT_DISABLE() -* macro. This workaround works also for Cortex-M3/M4 cores. -*/ - -#endif /* QF_PORT_H */ - diff --git a/ports/arm-cm/qk/gnu/qk_port.c b/ports/arm-cm/qk/gnu/qk_port.c index bc1c4fe4..24bd2611 100644 --- a/ports/arm-cm/qk/gnu/qk_port.c +++ b/ports/arm-cm/qk/gnu/qk_port.c @@ -1,299 +1,287 @@ -/*============================================================================ -* QP/C Real-Time Embedded Framework (RTEF) -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2023-01-14 -* @version Last updated for: @ref qpc_7_2_1 -* -* @file -* @brief QK/C port to ARM Cortex-M, GNU-ARM toolset -*/ -/* This QK port is part of the internal QP implementation */ -#define QP_IMPL 1U -#include "qf_port.h" +//============================================================================ +// QP/C Real-Time Embedded Framework (RTEF) +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +//============================================================================ +//! @date Last updated on: 2023-08-16 +//! @version Last updated for: @ref qpc_7_3_0 +//! +//! @file +//! @brief QK/C port to ARM Cortex-M, GNU-ARM -/* prototypes --------------------------------------------------------------*/ +#define QP_IMPL 1U +#include "qp_port.h" + +// prototypes ---------------------------------------------------------------- void PendSV_Handler(void); -#ifdef QK_USE_IRQ_HANDLER /* if use IRQ... */ +#ifdef QK_USE_IRQ_HANDLER // if use IRQ... void QK_USE_IRQ_HANDLER(void); -#else /* use default (NMI) */ +#else // use default (NMI) void NMI_Handler(void); #endif -#define SCnSCB_ICTR ((uint32_t volatile *)0xE000E004U) -#define SCB_SYSPRI ((uint32_t volatile *)0xE000ED14U) +#define SCB_SYSPRI ((uint32_t volatile *)0xE000ED18U) #define NVIC_EN ((uint32_t volatile *)0xE000E100U) -#define NVIC_IP ((uint8_t volatile *)0xE000E400U) +#define NVIC_IP ((uint32_t volatile *)0xE000E400U) +#define SCB_CPACR *((uint32_t volatile *)0xE000ED88U) #define FPU_FPCCR *((uint32_t volatile *)0xE000EF34U) #define NVIC_PEND 0xE000E200 -#define NVIC_ICSR 0xE000ED04 +#define SCB_ICSR 0xE000ED04 -/* helper macros to "stringify" values */ +// helper macros to "stringify" values #define VAL(x) #x #define STRINGIFY(x) VAL(x) -/*..........................................................................*/ -/* Initialize the exception priorities and IRQ priorities to safe values. -* -* Description: -* On ARMv7-M or higher, this QK port disables interrupts by means of the -* BASEPRI register. However, this method cannot disable interrupt -* priority zero, which is the default for all interrupts out of reset. -* The following code changes the SysTick priority and all IRQ priorities -* to the safe value QF_BASEPRI, which the QF critical section can disable. -* This avoids breaching of the QF critical sections in case the -* application programmer forgets to explicitly set priorities of all -* "kernel aware" interrupts. -* -* The interrupt priorities established in QK_init() can be later -* changed by the application-level code. -*/ +//............................................................................ +// Initialize the exception priorities and IRQ priorities to safe values. +// +// Description: +// On ARMv7-M or higher, this QK port disables interrupts by means of the +// BASEPRI register. However, this method cannot disable interrupt +// priority zero, which is the default for all interrupts out of reset. +// The following code changes the SysTick priority and all IRQ priorities +// to the safe value QF_BASEPRI, which the QF critical section can disable. +// This avoids breaching of the QF critical sections in case the +// application programmer forgets to explicitly set priorities of all +// "kernel aware" interrupts. +// +// The interrupt priorities established in QK_init() can be later +// changed by the application-level code. void QK_init(void) { -#if (__ARM_ARCH != 6) /*--------- if ARMv7-M and higher... */ +#if (__ARM_ARCH != 6) //--------- if ARMv7-M and higher... - /* set exception priorities to QF_BASEPRI... - * SCB_SYSPRI1: Usage-fault, Bus-fault, Memory-fault - */ - SCB_SYSPRI[1] = (SCB_SYSPRI[1] - | (QF_BASEPRI << 16U) | (QF_BASEPRI << 8U) | QF_BASEPRI); - - /* SCB_SYSPRI2: SVCall */ + // SCB_SYSPRI[2]: SysTick SCB_SYSPRI[2] = (SCB_SYSPRI[2] | (QF_BASEPRI << 24U)); - /* SCB_SYSPRI3: SysTick, PendSV, Debug */ - SCB_SYSPRI[3] = (SCB_SYSPRI[3] - | (QF_BASEPRI << 24U) | (QF_BASEPRI << 16U) | QF_BASEPRI); - - /* set all implemented IRQ priories to QF_BASEPRI... */ - uint8_t nprio = (8U + ((*SCnSCB_ICTR & 0x7U) << 3U)) * 4U; - for (uint8_t n = 0U; n < nprio; ++n) { - NVIC_IP[n] = QF_BASEPRI; + // set all 240 possible IRQ priories to QF_BASEPRI... + for (uint_fast8_t n = 0U; n < (240U/sizeof(uint32_t)); ++n) { + NVIC_IP[n] = (QF_BASEPRI << 24U) | (QF_BASEPRI << 16U) + | (QF_BASEPRI << 8U) | QF_BASEPRI; } -#endif /*--------- ARMv7-M or higher */ +#endif //--------- ARMv7-M or higher - /* SCB_SYSPRI3: PendSV set to priority 0xFF (lowest) */ - SCB_SYSPRI[3] = (SCB_SYSPRI[3] | (0xFFU << 16U)); + // SCB_SYSPRI[2]: PendSV set to priority 0xFF (lowest) + SCB_SYSPRI[2] = (SCB_SYSPRI[2] | (0xFFU << 16U)); -#ifdef QK_USE_IRQ_NUM /*--------- QK IRQ specified? */ - /* The QK port is configured to use a given ARM Cortex-M IRQ # - * to return to thread mode (default is to use the NMI exception) - */ - NVIC_IP[QK_USE_IRQ_NUM] = 0U; /* priority 0 (highest) */ +#ifdef QK_USE_IRQ_NUM //--------- QK IRQ specified? + // The QK port is configured to use a given ARM Cortex-M IRQ # + // to return to thread mode (default is to use the NMI exception) + NVIC_IP[QK_USE_IRQ_NUM] = 0U; // priority 0 (highest) NVIC_EN[QK_USE_IRQ_NUM >> 5U] = (1U << (QK_USE_IRQ_NUM & 0x1FU)); -#endif /*--------- QK IRQ specified */ +#endif //--------- QK IRQ specified -#if (__ARM_FP != 0) /*--------- if VFP available... */ - /* configure the FPU for QK */ - FPU_FPCCR |= (1U << 30U) /* automatic FPU state preservation (ASPEN) */ - | (1U << 31U); /* lazy stacking (LSPEN) */ -#endif /*--------- VFP available */ +#ifdef __ARM_FP //--------- if VFP available... + // make sure that the FPU is enabled by seting CP10 & CP11 Full Access + SCB_CPACR = (SCB_CPACR | ((3UL << 20U) | (3UL << 22U))); + + // FPU automatic state preservation (ASPEN) lazy stacking (LSPEN) + FPU_FPCCR = (FPU_FPCCR | (1U << 30U) | (1U << 31U)); +#endif //--------- VFP available } -/*..........................................................................*/ -/* The PendSV_Handler exception is used for handling the asynchronous -* preemption in QK. The use of the PendSV exception is the recommended and -* the most efficient method for performing context switches with ARM Cortex-M. -* -* The PendSV exception should have the lowest priority in the whole system -* (0xFF, see QK_init). All other exceptions and interrupts should have higher -* priority. For example, for NVIC with 2 priority bits all interrupts and -* exceptions must have numerical value of priority lower than 0xC0. In this -* case the interrupt priority levels available to your applications are (in -* the order from the lowest urgency to the highest urgency): 0x80, 0x40, 0x00. -* -* Also, *all* "kernel aware" ISRs in the QK application must call the -* QK_ISR_EXIT() macro, which triggers PendSV when it detects a need for -* a context switch or asynchronous preemption. -* -* Due to tail-chaining and its lowest priority, the PendSV exception will be -* entered immediately after the exit from the *last* nested interrupt (or -* exception). In QK, this is exactly the time when the QK activator needs to -* handle the asynchronous preemption. -* -* NOTE: -* The inline GNU assembler does not accept mnemonics MOVS, LSRS and ADDS, -* but for ARMv6-M the mnemonics MOV, LSR and ADD always set the condition -* flags in the PSR. -*/ +//............................................................................ +// The PendSV_Handler exception is used for handling the asynchronous +// preemption in QK. The use of the PendSV exception is the recommended and +// the most efficient method for performing context switches with ARM Cortex-M. +// +// The PendSV exception should have the lowest priority in the whole system +// (0xFF, see QK_init). All other exceptions and interrupts should have higher +// priority. For example, for NVIC with 2 priority bits all interrupts and +// exceptions must have numerical value of priority lower than 0xC0. In this +// case the interrupt priority levels available to your applications are (in +// the order from the lowest urgency to the highest urgency): 0x80, 0x40, 0x00. +// +// Also, *all* "kernel aware" ISRs in the QK application must call the +// QK_ISR_EXIT() macro, which triggers PendSV when it detects a need for +// a context switch or asynchronous preemption. +// +// Due to tail-chaining and its lowest priority, the PendSV exception will be +// entered immediately after the exit from the *last* nested interrupt (or +// exception). In QK, this is exactly the time when the QK activator needs to +// handle the asynchronous preemption. +// +// NOTE: +// The inline GNU assembler does not accept mnemonics MOVS, LSRS and ADDS, +// but for ARMv6-M the mnemonics MOV, LSR and ADD always set the condition +// flags in the PSR. __attribute__ ((naked, optimize("-fno-stack-protector"))) void PendSV_Handler(void) { __asm volatile ( + " PUSH {r0,lr} \n" // save EXC_RETURN + stack-aligner - /* Prepare constants in registers before entering critical section */ - " LDR r3,=" STRINGIFY(NVIC_ICSR) "\n" /* Interrupt Control and State */ - " MOV r1,#1 \n" - " LSL r1,r1,#27 \n" /* r0 := (1 << 27) (UNPENDSVSET bit) */ - - /*<<<<<<<<<<<<<<<<<<<<<<< CRITICAL SECTION BEGIN <<<<<<<<<<<<<<<<<<<<<<<<*/ -#if (__ARM_ARCH == 6) /*--------- if ARMv6-M... */ - " CPSID i \n" /* disable interrupts (set PRIMASK) */ -#else /* ARMv7-M and higher */ -#if (__ARM_FP != 0) /*--------- if VFP available... */ - " PUSH {r0,lr} \n" /* ... push lr plus stack-aligner */ -#endif /*--------- VFP available */ + //<<<<<<<<<<<<<<<<<<<<<<< CRITICAL SECTION BEGIN <<<<<<<<<<<<<<<<<<<<<<<< +#if (__ARM_ARCH == 6) //--------- if ARMv6-M... + " CPSID i \n" // disable interrupts (set PRIMASK) +#else // ARMv7-M and higher " MOV r0,#" STRINGIFY(QF_BASEPRI) "\n" - " CPSID i \n" /* disable interrupts with BASEPRI */ - " MSR BASEPRI,r0 \n" /* apply the Cortex-M7 erraturm */ - " CPSIE i \n" /* 837070, see SDEN-1068427. */ -#endif /*--------- ARMv7-M and higher */ + " CPSID i \n" // disable interrupts with BASEPRI + " MSR BASEPRI,r0 \n" // apply the Cortex-M7 erraturm + " CPSIE i \n" // 837070, see SDEN-1068427. +#endif //--------- ARMv7-M and higher - /* The PendSV exception handler can be preempted by an interrupt, - * which might pend PendSV exception again. The following write to - * ICSR[27] un-pends any such spurious instance of PendSV. - */ - " STR r1,[r3] \n" /* ICSR[27] := 1 (unpend PendSV) */ +#ifdef QF_MEM_ISOLATE + " LDR r0,=QF_onMemSys \n" + " BLX r0 \n" // call QF_onMemSys() +#endif - /* The QK activator must be called in a Thread mode, while this code - * executes in the Handler mode of the PendSV exception. The switch - * to the Thread mode is accomplished by returning from PendSV using - * a fabricated exception stack frame, where the return address is - * QK_activate_(). - * - * NOTE: the QK activator is called with interrupts DISABLED and also - * returns with interrupts DISABLED. - */ - " LSR r3,r1,#3 \n" /* r3 := (r1 >> 3), set the T bit (new xpsr) */ - " LDR r2,=QK_activate_ \n" /* address of QK_activate_ */ - " SUB r2,r2,#1 \n" /* align Thumb-address at halfword (new pc) */ - " LDR r1,=QK_thread_ret \n" /* return address after the call (new lr) */ + // The PendSV exception handler can be preempted by an interrupt, + // which might pend PendSV exception again. The following write to + // ICSR[27] un-pends any such spurious instance of PendSV. + " LDR r2,=" STRINGIFY(SCB_ICSR) "\n" // Interrupt Control and State + " MOV r1,#1 \n" + " LSL r1,r1,#27 \n" // r1 := (1 << 27) (UNPENDSVSET bit) + " STR r1,[r2] \n" // ICSR[27] := 1 (unpend PendSV) - " SUB sp,sp,#8*4 \n" /* reserve space for exception stack frame */ - " ADD r0,sp,#5*4 \n" /* r0 := 5 registers below the SP */ - " STM r0!,{r1-r3} \n" /* save xpsr,pc,lr */ + // The QK activator must be called in a Thread mode, while this code + // executes in the Handler mode of the PendSV exception. The switch + // to the Thread mode is accomplished by returning from PendSV using + // a fabricated exception stack frame, where the return address is + // QK_activate_(). + // + // NOTE: the QK activator is called with interrupts DISABLED and also + // returns with interrupts DISABLED. + " LSR r3,r1,#3 \n" // r3 := (r1 >> 3), set T bit (new xpsr) + " LDR r2,=QK_activate_ \n" // address of QK_activate_ + " SUB r2,r2,#1 \n" // align Thumb-address at halfword (new pc) + " LDR r1,=QK_thread_ret \n" // return address after the call (new lr) + + " SUB sp,sp,#8*4 \n" // reserve space for exception stack frame + " ADD r0,sp,#5*4 \n" // r0 := 5 registers below the SP + " STM r0!,{r1-r3} \n" // save xpsr,pc,lr " MOV r0,#6 \n" - " MVN r0,r0 \n" /* r0 := ~6 == 0xFFFFFFF9 */ -#if (__ARM_ARCH != 6) /*--------- if ARMv7-M and higher... */ - " DSB \n" /* ARM Erratum 838869 */ -#endif /*--------- ARMv7-M and higher */ - " BX r0 \n" /* exception-return to the QK activator */ + " MVN r0,r0 \n" // r0 := ~6 == 0xFFFFFFF9 +#if (__ARM_ARCH != 6) //--------- if ARMv7-M and higher... + " DSB \n" // ARM Erratum 838869 +#endif //--------- ARMv7-M and higher + " BX r0 \n" // exception-return to the QK activator ); } -/*==========================================================================*/ -/* QK_thread_ret is a helper function executed when the QXK activator returns. -* -* NOTE: QK_thread_ret does not execute in the PendSV context! -* NOTE: QK_thread_ret is entered with interrupts DISABLED. -*/ +//============================================================================ +// QK_thread_ret is a helper function executed when the QXK activator returns. +// +// NOTE: QK_thread_ret does not execute in the PendSV context! +// NOTE: QK_thread_ret is entered with interrupts DISABLED. __attribute__ ((naked, used, optimize("-fno-stack-protector"))) void QK_thread_ret(void) { __asm volatile ( - /* After the QK activator returns, we need to resume the preempted - * thread. However, this must be accomplished by a return-from-exception, - * while we are still in the thread context. The switch to the exception - * context is accomplished by triggering the NMI exception or the selected - * IRQ (if macro #QK_USE_IRQ_NUM is defined). - */ + // After the QK activator returns, we need to resume the preempted + // thread. However, this must be accomplished by a return-from-exception, + // while we are still in the thread context. The switch to the exception + // context is accomplished by triggering the NMI exception or the selected + // IRQ (if macro #QK_USE_IRQ_NUM is defined). - /* before triggering the NMI/IRQ, make sure that the VFP stack frame - * will NOT be used... - */ -#if (__ARM_FP != 0) /*--------- if VFP available... */ - /* make sure that the VFP stack frame will NOT be used */ - " MRS r0,CONTROL \n" /* r0 := CONTROL */ - " BIC r0,r0,#4 \n" /* r0 := r0 & ~4 (FPCA bit) */ - " MSR CONTROL,r0 \n" /* CONTROL := r0 (clear CONTROL[2] FPCA bit) */ - " ISB \n" /* ISB after MSR CONTROL (ARM AN321,Sect.4.16) */ -#endif /*--------- VFP available */ + // before triggering the NMI/IRQ, make sure that the VFP stack frame + // will NOT be used... +#ifdef __ARM_FP //--------- if VFP available... + // make sure that the VFP stack frame will NOT be used + " MRS r0,CONTROL \n" // r0 := CONTROL + " BIC r0,r0,#4 \n" // r0 := r0 & ~4 (FPCA bit) + " MSR CONTROL,r0 \n" // CONTROL := r0 (clear CONTROL[2] FPCA bit) + " ISB \n" // ISB after MSR CONTROL (ARM AN321,Sect.4.16) +#endif //--------- VFP available -#ifndef QK_USE_IRQ_NUM /*--------- IRQ NOT defined, use NMI by default */ - " LDR r0,=" STRINGIFY(NVIC_ICSR) "\n" /* Interrupt Control and State */ +#ifdef QF_MEM_ISOLATE + " LDR r0,=QF_onMemApp \n" + " BLX r0 \n" // call QF_onMemApp() +#endif + +#ifndef QK_USE_IRQ_NUM //--------- IRQ NOT defined, use NMI by default + " LDR r0,=" STRINGIFY(SCB_ICSR) "\n" // Interrupt Control and State " MOV r1,#1 \n" - " LSL r1,r1,#31 \n" /* r1 := (1 << 31) (NMI bit) */ - " STR r1,[r0] \n" /* ICSR[31] := 1 (pend NMI) */ + " LSL r1,r1,#31 \n" // r1 := (1 << 31) (NMI bit) + " STR r1,[r0] \n" // ICSR[31] := 1 (pend NMI) -#else /*--------- use the selected IRQ */ +#else //--------- use the selected IRQ " LDR r0,=" STRINGIFY(NVIC_PEND + ((QK_USE_IRQ_NUM >> 5) << 2)) "\n" " MOV r1,#1 \n" - " LSL r1,r1,#" STRINGIFY(QK_USE_IRQ_NUM & 0x1F) "\n" /* r1 := IRQ bit */ - " STR r1,[r0] \n" /* pend the IRQ */ + " LSL r1,r1,#" STRINGIFY(QK_USE_IRQ_NUM & 0x1F) "\n" // r1 := IRQ bit + " STR r1,[r0] \n" // pend the IRQ - /* now enable interrupts so that pended IRQ can be entered */ -#if (__ARM_ARCH == 6) /*--------- if ARMv6-M... */ - " CPSIE i \n" /* enable interrupts (clear PRIMASK) */ -#else /*--------- ARMv7-M and higher */ + // now enable interrupts so that pended IRQ can be entered +#if (__ARM_ARCH == 6) //--------- if ARMv6-M... + " CPSIE i \n" // enable interrupts (clear PRIMASK) +#else //--------- ARMv7-M and higher " MOV r0,#0 \n" - " MSR BASEPRI,r0 \n" /* enable interrupts (clear BASEPRI) */ -#endif /*--------- ARMv7-M and higher */ -#endif /*--------- use IRQ */ + " MSR BASEPRI,r0 \n" // enable interrupts (clear BASEPRI) +#endif //--------- ARMv7-M and higher +#endif //--------- use IRQ - /* NOTE! interrupts are still disabled when NMI is used */ - " B . \n" /* wait for preemption by NMI/IRQ */ + // NOTE! interrupts are still disabled when NMI is used + " B . \n" // wait for preemption by NMI/IRQ ); } -/*==========================================================================*/ -/* This exception handler is used for returning back to the preempted thread. -* The exception handler simply removes its own interrupt stack frame from -* the stack (MSP) and returns to the preempted task using the interrupt -* stack frame that must be at the top of the stack. -*/ +//============================================================================ +// This exception handler is used for returning back to the preempted thread. +// The exception handler simply removes its own interrupt stack frame from +// the stack (MSP) and returns to the preempted task using the interrupt +// stack frame that must be at the top of the stack. __attribute__ ((naked, optimize("-fno-stack-protector"))) -#ifndef QK_USE_IRQ_NUM /*--------- IRQ NOT defined, use NMI by default */ +#ifndef QK_USE_IRQ_NUM //--------- IRQ NOT defined, use NMI by default -/* NOTE: The NMI_Handler() is entered with interrupts still disabled! */ +// NOTE: The NMI_Handler() is entered with interrupts still disabled! void NMI_Handler(void) { __asm volatile ( - /* enable interrupts */ -#if (__ARM_ARCH == 6) /*--------- if ARMv6-M... */ - " CPSIE i \n" /* enable interrupts (clear PRIMASK) */ -#else /*--------- ARMv7-M and higher */ + // enable interrupts +#if (__ARM_ARCH == 6) //--------- if ARMv6-M... + " CPSIE i \n" // enable interrupts (clear PRIMASK) +#else //--------- ARMv7-M and higher " MOV r0,#0 \n" - " MSR BASEPRI,r0 \n" /* enable interrupts (clear BASEPRI) */ -#endif /*--------- ARMv7-M and higher */ + " MSR BASEPRI,r0 \n" // enable interrupts (clear BASEPRI) +#endif //--------- ARMv7-M and higher ); -#else /*--------- use the selected IRQ */ +#else //--------- use the selected IRQ -/* NOTE: The IRQ Handler is entered with interrupts enabled */ +// NOTE: The IRQ Handler is entered with interrupts enabled void QK_USE_IRQ_HANDLER(void) { -#endif /*--------- use IRQ */ +#endif //--------- use IRQ __asm volatile ( - " ADD sp,sp,#(8*4) \n" /* remove one 8-register exception frame */ + " ADD sp,sp,#(8*4) \n" // remove one 8-register exception frame -#if (__ARM_FP != 0) /*--------- if VFP available... */ - " POP {r0,lr} \n" /* pop stack aligner and EXC_RETURN to LR */ - " DSB \n" /* ARM Erratum 838869 */ -#endif /*--------- VFP available */ - " BX lr \n" /* return to the preempted task */ + " POP {r0,r1} \n" // pop stack aligner and EXC_RETURN to r1 + " DSB \n" // ARM Erratum 838869 + " BX r1 \n" // return to the preempted task ); } -/*==========================================================================*/ -#if (__ARM_ARCH == 6) /* if ARMv6-M... */ +//============================================================================ +#if (__ARM_ARCH == 6) // if ARMv6-M... -/* hand-optimized quick LOG2 in assembly (no CLZ instruction in ARMv6-M) */ -/* -* NOTE: -* The inline GNU assembler does not accept mnemonics MOVS, LSRS and ADDS, -* but for ARMv6-M the mnemonics MOV, LSR and ADD always set the condition -* flags in the PSR. -*/ +// hand-optimized quick LOG2 in assembly (no CLZ instruction in ARMv6-M) +// NOTE: +// The inline GNU assembler does not accept mnemonics MOVS, LSRS and ADDS, +// but for ARMv6-M the mnemonics MOV, LSR and ADD always set the condition +// flags in the PSR. __attribute__ ((naked, optimize("-fno-stack-protector"))) uint_fast8_t QF_qlog2(uint32_t x) { __asm volatile ( @@ -327,5 +315,5 @@ __asm volatile ( ); } -#endif /* ARMv6-M */ +#endif // ARMv6-M diff --git a/ports/arm-cm/qk/gnu/qk_port.h b/ports/arm-cm/qk/gnu/qk_port.h deleted file mode 100644 index 842dab26..00000000 --- a/ports/arm-cm/qk/gnu/qk_port.h +++ /dev/null @@ -1,95 +0,0 @@ -/*============================================================================ -* QK/C port to ARM Cortex-M, GNU-ARM -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2022-12-18 -* @version Last updated for: @ref qpc_7_2_0 -* -* @file -* @brief QK/C port to ARM Cortex-M, GNU-ARM toolset -*/ -#ifndef QK_PORT_H -#define QK_PORT_H - -/* determination if the code executes in the ISR context */ -#define QK_ISR_CONTEXT_() (QK_get_IPSR() != 0U) - -__attribute__((always_inline)) -static inline uint32_t QK_get_IPSR(void) { - uint32_t regIPSR; - __asm volatile ("mrs %0,ipsr" : "=r" (regIPSR)); - return regIPSR; -} - -/* QK ISR entry and exit */ -#define QK_ISR_ENTRY() ((void)0) - -#define QK_ISR_EXIT() do { \ - QF_INT_DISABLE(); \ - if (QK_sched_() != 0U) { \ - *Q_UINT2PTR_CAST(uint32_t, 0xE000ED04U) = (1U << 28U);\ - } \ - QF_INT_ENABLE(); \ - QK_ARM_ERRATUM_838869(); \ -} while (false) - -#if (__ARM_ARCH == 6) /* ARMv6-M? */ - #define QK_ARM_ERRATUM_838869() ((void)0) -#else /* ARMv7-M or higher */ - /* The following macro implements the recommended workaround for the - * ARM Erratum 838869. Specifically, for Cortex-M3/M4/M7 the DSB - * (memory barrier) instruction needs to be added before exiting an ISR. - */ - #define QK_ARM_ERRATUM_838869() \ - __asm volatile ("dsb" ::: "memory") -#endif - -/* Use a given ARM Cortex-M IRQ to return to thread mode (default NMI) -* -* NOTE: -* If you need the NMI for other purposes, you can define the macros -* QK_USE_IRQ_NUM and QK_USE_IRQ_HANDLER to use thus specified IRQ -* instead of the NMI (the IRQ should not be used for anything else). -* These two macros can be defined on the command line to the compiler -* and are actually needed only to compile the qk_port.c file. -*/ -//#define QK_USE_IRQ_NUM 25 -//#define QK_USE_IRQ_HANDLER CRYPTO_IRQHandler - -/* initialization of the QK kernel */ -#define QK_INIT() QK_init() -void QK_init(void); -void QK_thread_ret(void); - -#if (__ARM_FP != 0) /* if VFP available... */ -/* When the FPU is configured, clear the FPCA bit in the CONTROL register -* to prevent wasting the stack space for the FPU context. -*/ -#define QK_START() __asm volatile ("msr CONTROL,%0" :: "r" (0) : ) -#endif - -#include "qk.h" /* QK platform-independent public interface */ - -#endif /* QK_PORT_H */ - diff --git a/ports/arm-cm/qk/gnu/qp_port.h b/ports/arm-cm/qk/gnu/qp_port.h new file mode 100644 index 00000000..ed924630 --- /dev/null +++ b/ports/arm-cm/qk/gnu/qp_port.h @@ -0,0 +1,239 @@ +//============================================================================ +// QP/C Real-Time Embedded Framework (RTEF) +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +//============================================================================ +//! @date Last updated on: 2023-09-07 +//! @version Last updated for: @ref qpc_7_3_0 +//! +//! @file +//! @brief QP/C port to ARM Cortex-M, preemptive QK kernel, GNU-ARM + +#ifndef QP_PORT_H_ +#define QP_PORT_H_ + +#include // Exact-width types. WG14/N843 C99 Standard +#include // Boolean type. WG14/N843 C99 Standard + +#ifdef QP_CONFIG +#include "qp_config.h" // external QP configuration +#endif + +// no-return function specifier (C11 Standard) +#define Q_NORETURN _Noreturn void + +// QF configuration for QK -- data members of the QActive class... + +// QK event-queue used for AOs +#define QACTIVE_EQUEUE_TYPE QEQueue + +// QF "thread" type used to store the MPU settings in the AO +#define QACTIVE_THREAD_TYPE void const * + +// QF interrupt disable/enable and log2()... +#if (__ARM_ARCH == 6) // ARMv6-M? + + // Cortex-M0/M0+/M1(v6-M, v6S-M) interrupt disabling policy, see NOTE2 + #define QF_INT_DISABLE() __asm volatile ("cpsid i" ::: "memory") + #define QF_INT_ENABLE() __asm volatile ("cpsie i" ::: "memory") + + // QF critical section (save and restore interrupt status), see NOTE2 + #define QF_CRIT_STAT uint32_t primask_; + #define QF_CRIT_ENTRY() __asm volatile (\ + "mrs %0,PRIMASK\n" "cpsid i" : "=r" (primask_) :: "memory") + #define QF_CRIT_EXIT() __asm volatile (\ + "msr PRIMASK,%0" :: "r" (primask_) : "memory") + + // CMSIS threshold for "QF-aware" interrupts, see NOTE2 and NOTE4 + #define QF_AWARE_ISR_CMSIS_PRI 0 + + // hand-optimized LOG2 in assembly for Cortex-M0/M0+/M1(v6-M, v6S-M) + #define QF_LOG2(n_) QF_qlog2((uint32_t)(n_)) + +#else // ARMv7-M or higher + + // ARMv7-M or higher alternative interrupt disabling with PRIMASK + #define QF_PRIMASK_DISABLE() __asm volatile ("cpsid i" ::: "memory") + #define QF_PRIMASK_ENABLE() __asm volatile ("cpsie i" ::: "memory") + + // ARMv7-M or higher interrupt disabling policy, see NOTE3 and NOTE4 + #define QF_INT_DISABLE() __asm volatile (\ + "cpsid i\n" "msr BASEPRI,%0\n" "cpsie i" \ + :: "r" (QF_BASEPRI) : "memory") + #define QF_INT_ENABLE() __asm volatile (\ + "msr BASEPRI,%0" :: "r" (0) : "memory") + + // QF critical section (save and restore interrupt status), see NOTE5 + #define QF_CRIT_STAT uint32_t basepri_; + #define QF_CRIT_ENTRY() do { \ + __asm volatile ("mrs %0,BASEPRI" : "=r" (basepri_) :: "memory"); \ + __asm volatile ("cpsid i\n msr BASEPRI,%0\n cpsie i" \ + :: "r" (QF_BASEPRI) : "memory"); \ + } while (false) + #define QF_CRIT_EXIT() \ + __asm volatile ("msr BASEPRI,%0" :: "r" (basepri_) : "memory") + + // BASEPRI threshold for "QF-aware" interrupts, see NOTE3 + #define QF_BASEPRI 0x3F + + // CMSIS threshold for "QF-aware" interrupts, see NOTE5 + #define QF_AWARE_ISR_CMSIS_PRI (QF_BASEPRI >> (8 - __NVIC_PRIO_BITS)) + + // ARMv7-M or higher provide the CLZ instruction for fast LOG2 + #define QF_LOG2(n_) ((uint_fast8_t)(32 - __builtin_clz((unsigned)(n_)))) + +#endif + +#define QF_CRIT_EXIT_NOP() __asm volatile ("isb" ::: "memory") + +#if (__ARM_ARCH == 6) // ARMv6-M? + // hand-optimized quick LOG2 in assembly + uint_fast8_t QF_qlog2(uint32_t x); +#endif // ARMv7-M or higher + +// Memory isolation ---------------------------------------------------------- +#ifdef QF_MEM_ISOLATE + + // Memory isolation requires the context-switch + #define QF_ON_CONTEXT_SW 1U + + // Memory System setting + #define QF_MEM_SYS() QF_onMemSys() + + // Memory Application setting + #define QF_MEM_APP() QF_onMemApp() + + // callback functions for memory settings (provided by applications) + void QF_onMemSys(void); + void QF_onMemApp(void); + +#endif // def QF_MEM_ISOLATE + +// determination if the code executes in the ISR context +#define QK_ISR_CONTEXT_() (QK_get_IPSR() != 0U) + +__attribute__((always_inline)) +static inline uint32_t QK_get_IPSR(void) { + uint32_t regIPSR; + __asm volatile ("mrs %0,ipsr" : "=r" (regIPSR)); + return regIPSR; +} + +// QK ISR entry and exit +#define QK_ISR_ENTRY() ((void)0) + +#ifdef QF_MEM_ISOLATE + #define QK_ISR_EXIT() do { \ + QF_INT_DISABLE(); \ + QF_MEM_SYS(); \ + if (QK_sched_() != 0U) { \ + *Q_UINT2PTR_CAST(uint32_t, 0xE000ED04U) = (1U << 28U);\ + } \ + QF_MEM_APP(); \ + QF_INT_ENABLE(); \ + QK_ARM_ERRATUM_838869(); \ + } while (false) +#else + #define QK_ISR_EXIT() do { \ + QF_INT_DISABLE(); \ + if (QK_sched_() != 0U) { \ + *Q_UINT2PTR_CAST(uint32_t, 0xE000ED04U) = (1U << 28U);\ + } \ + QF_INT_ENABLE(); \ + QK_ARM_ERRATUM_838869(); \ + } while (false) +#endif + +#if (__ARM_ARCH == 6) // ARMv6-M? + #define QK_ARM_ERRATUM_838869() ((void)0) +#else // ARMv7-M or higher + // The following macro implements the recommended workaround for the + // ARM Erratum 838869. Specifically, for Cortex-M3/M4/M7 the DSB + // (memory barrier) instruction needs to be added before exiting an ISR. + #define QK_ARM_ERRATUM_838869() \ + __asm volatile ("dsb" ::: "memory") + +#endif // ARMv6-M + +// initialization of the QK kernel +#define QK_INIT() QK_init() +void QK_init(void); +void QK_thread_ret(void); + +#ifdef __ARM_FP //--------- if VFP available... +// When the FPU is configured, clear the FPCA bit in the CONTROL register +// to prevent wasting the stack space for the FPU context. +#define QK_START() __asm volatile ("msr CONTROL,%0" :: "r" (0) : ) +#endif + +// include files ------------------------------------------------------------- +#include "qequeue.h" // QK kernel uses the native QP event queue +#include "qmpool.h" // QK kernel uses the native QP memory pool +#include "qp.h" // QP framework +#include "qk.h" // QK kernel + +//============================================================================ +// NOTE2: +// On Cortex-M0/M0+/M1 (architecture v6-M, v6S-M), the interrupt disabling +// policy uses the PRIMASK register to disable interrupts globally. The +// QF_AWARE_ISR_CMSIS_PRI level is zero, meaning that all interrupts are +// "QF-aware". +// +// NOTE3: +// On ARMv7-M or higher, the interrupt disable/enable policy uses the BASEPRI +// register (which is not implemented in Cortex-M0/M0+/M1) to disable +// interrupts only with priority lower than the threshold specified by the +// QF_BASEPRI macro. The interrupts with priorities above QF_BASEPRI (i.e., +// with numerical priority values lower than QF_BASEPRI) are NOT disabled in +// this method. These free-running interrupts have very low ("zero") latency, +// but they are not allowed to call any QF services, because QF is unaware +// of them ("QF-unaware" interrupts). Consequently, only interrupts with +// numerical values of priorities equal to or higher than QF_BASEPRI +// ("QF-aware" interrupts ), can call QF services. +// +// NOTE4: +// The QF_AWARE_ISR_CMSIS_PRI macro is useful as an offset for enumerating +// the "QF-aware" interrupt priorities in the applications, whereas the +// numerical values of the "QF-aware" interrupts must be greater or equal to +// QF_AWARE_ISR_CMSIS_PRI. The values based on QF_AWARE_ISR_CMSIS_PRI can be +// passed directly to the CMSIS function NVIC_SetPriority(), which shifts +// them by (8 - __NVIC_PRIO_BITS) into the correct bit position, while +// __NVIC_PRIO_BITS is the CMSIS macro defining the number of implemented +// priority bits in the NVIC. Please note that the macro QF_AWARE_ISR_CMSIS_PRI +// is intended only for applications and is not used inside the QF port, which +// remains generic and not dependent on the number of implemented priority bits +// implemented in the NVIC. +// +// NOTE5: +// The selective disabling of "QF-aware" interrupts with the BASEPRI register +// has a problem on ARM Cortex-M7 core r0p1 (see ARM-EPM-064408, errata +// 837070). The workaround recommended by ARM is to surround MSR BASEPRI with +// the CPSID i/CPSIE i pair, which is implemented in the QF_INT_DISABLE() +// macro. This workaround works also for Cortex-M3/M4 cores. + +#endif // QP_PORT_H_ + diff --git a/ports/arm-cm/qk/gnu/qs_port.h b/ports/arm-cm/qk/gnu/qs_port.h index e8b00882..92ec4663 100644 --- a/ports/arm-cm/qk/gnu/qs_port.h +++ b/ports/arm-cm/qk/gnu/qs_port.h @@ -1,60 +1,61 @@ -/*============================================================================ -* QP/C Real-Time Embedded Framework (RTEF) -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2022-06-12 -* @version Last updated for: @ref qpc_7_0_1 -* -* @file -* @brief QS/C port to a 32-bit CPU and a generic C99 compiler. -* @description -* This is an example of a QP/C port with the documentation for the -* configuration macros and includes. -*/ -#ifndef QS_PORT_H -#define QS_PORT_H +//============================================================================ +// QP/C Real-Time Embedded Framework (RTEF) +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +//============================================================================ +//! @date Last updated on: 2023-08-16 +//! @version Last updated for: @ref qpc_7_3_0 +//! +//! @file +//! @brief QS/C port to a 32-bit CPU and a generic C11 compiler. -/* QS time-stamp size in bytes */ -#define QS_TIME_SIZE 4 +#ifndef QS_PORT_H_ +#define QS_PORT_H_ -/* object pointer size in bytes */ -#define QS_OBJ_PTR_SIZE 4 +// QS time-stamp size in bytes +#define QS_TIME_SIZE 4U -/* function pointer size in bytes */ -#define QS_FUN_PTR_SIZE 4 +// object pointer size in bytes +#define QS_OBJ_PTR_SIZE 4U -/*==========================================================================*/ -/* NOTE: QS might be used with or without other QP components, in which -* case the separate definitions of the macros QF_CRIT_STAT_TYPE, -* QF_CRIT_ENTRY, and QF_CRIT_EXIT are needed. In this port QS is configured -* to be used with the other QP component, by simply including "qf_port.h" -* *before* "qs.h". -*/ -#ifndef QF_PORT_H -#include "qf_port.h" /* use QS with QF */ +// function pointer size in bytes +#define QS_FUN_PTR_SIZE 4U + +//============================================================================ +// NOTE: QS might be used with or without other QP components, in which +// case the separate definitions of the macros QF_CRIT_STAT, QF_CRIT_ENTRY(), +// and QF_CRIT_EXIT() are needed. In this port QS is configured to be used +// with the other QP component, by simply including "qp_port.h" +//*before* "qs.h". +#ifndef QP_PORT_H_ +#include "qp_port.h" // use QS with QF #endif -#include "qs.h" /* QS platform-independent public interface */ +#include "qs.h" // QS platform-independent public interface + +#endif // QS_PORT_H_ -#endif /* QS_PORT_H */ diff --git a/ports/arm-cm/qk/iar/qep_port.h b/ports/arm-cm/qk/iar/qep_port.h deleted file mode 100644 index eb838a52..00000000 --- a/ports/arm-cm/qk/iar/qep_port.h +++ /dev/null @@ -1,45 +0,0 @@ -/*============================================================================ -* QP/C Real-Time Embedded Framework (RTEF) -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2022-04-09 -* @version Last updated for: @ref qpc_7_0_0 -* -* @file -* @brief QEP/C port, generic IAR compiler -*/ -#ifndef QEP_PORT_H -#define QEP_PORT_H - -/*! no-return function specifier (IAR compiler) */ -#define Q_NORETURN __noreturn void - - -#include /* Exact-width types. WG14/N843 C99 Standard */ -#include /* Boolean type. WG14/N843 C99 Standard */ - -#include "qep.h" /* QEP platform-independent public interface */ - -#endif /* QEP_PORT_H */ - diff --git a/ports/arm-cm/qk/iar/qf_port.h b/ports/arm-cm/qk/iar/qf_port.h deleted file mode 100644 index 393b2a0d..00000000 --- a/ports/arm-cm/qk/iar/qf_port.h +++ /dev/null @@ -1,150 +0,0 @@ -/*============================================================================ -* QP/C Real-Time Embedded Framework (RTEF) -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2022-04-09 -* @version Last updated for: @ref qpc_7_0_0 -* -* @file -* @brief QF/C port to Cortex-M, preemptive QK kernel, IAR-ARM toolset -*/ -#ifndef QF_PORT_H -#define QF_PORT_H - -/* The maximum number of system clock tick rates */ -#define QF_MAX_TICK_RATE 2U - -/* QF interrupt disable/enable and log2()... */ -#if (__ARM_ARCH == 6) /* Cortex-M0/M0+/M1(v6-M, v6S-M)? */ - - /* The maximum number of active objects in the application, see NOTE1 */ - #define QF_MAX_ACTIVE 16U - - /* Cortex-M0/M0+/M1(v6-M, v6S-M) interrupt disabling policy, see NOTE2 */ - #define QF_INT_DISABLE() __disable_interrupt() - #define QF_INT_ENABLE() __enable_interrupt() - - /* QF critical section entry/exit (unconditional interrupt disabling) */ - /*#define QF_CRIT_STAT_TYPE not defined */ - #define QF_CRIT_ENTRY(dummy) QF_INT_DISABLE() - #define QF_CRIT_EXIT(dummy) QF_INT_ENABLE() - - /* CMSIS threshold for "QF-aware" interrupts, see NOTE2 and NOTE4 */ - #define QF_AWARE_ISR_CMSIS_PRI 0 - - /* hand-optimized LOG2 in assembly for Cortex-M0/M0+/M1(v6-M, v6S-M) */ - #define QF_LOG2(n_) QF_qlog2((uint32_t)(n_)) - -#else /* Cortex-M3/M4/M7 */ - - /* The maximum number of active objects in the application, see NOTE1 */ - #define QF_MAX_ACTIVE 32U - - /* Cortex-M3/M4/M7 alternative interrupt disabling with PRIMASK */ - #define QF_PRIMASK_DISABLE() __disable_interrupt() - #define QF_PRIMASK_ENABLE() __enable_interrupt() - - /* Cortex-M3/M4/M7 interrupt disabling policy, see NOTE3 and NOTE4 */ - #define QF_INT_DISABLE() do { \ - QF_PRIMASK_DISABLE(); \ - __set_BASEPRI(QF_BASEPRI); \ - QF_PRIMASK_ENABLE(); \ - } while (false) - #define QF_INT_ENABLE() __set_BASEPRI(0U) - - /* QF critical section entry/exit (unconditional interrupt disabling) */ - /*#define QF_CRIT_STAT_TYPE not defined */ - #define QF_CRIT_ENTRY(dummy) QF_INT_DISABLE() - #define QF_CRIT_EXIT(dummy) QF_INT_ENABLE() - - /* BASEPRI threshold for "QF-aware" interrupts, see NOTE3 */ - #define QF_BASEPRI 0x3F - - /* CMSIS threshold for "QF-aware" interrupts, see NOTE5 */ - #define QF_AWARE_ISR_CMSIS_PRI (QF_BASEPRI >> (8 - __NVIC_PRIO_BITS)) - - /* Cortex-M3/M4/M7 provide the CLZ instruction for fast LOG2 */ - #define QF_LOG2(n_) ((uint_fast8_t)(32U - __CLZ((unsigned long)(n_)))) - -#endif - -#define QF_CRIT_EXIT_NOP() __ISB() - -#include /* IAR intrinsic functions */ -#include "qep_port.h" /* QEP port */ - -#if (__ARM_ARCH == 6) /* Cortex-M0/M0+/M1(v6-M, v6S-M)? */ - /* hand-optimized quick LOG2 in assembly */ - uint_fast8_t QF_qlog2(uint32_t x); -#endif /* Cortex-M0/M0+/M1(v6-M, v6S-M) */ - -#include "qk_port.h" /* QK preemptive kernel port */ -#include "qf.h" /* QF platform-independent public interface */ - -/***************************************************************************** -* NOTE1: -* The maximum number of active objects QF_MAX_ACTIVE can be increased -* up to 64U, if necessary. Here it is set to a lower level to save some RAM. -* -* NOTE2: -* On Cortex-M0/M0+/M1 (architecture v6-M, v6S-M), the interrupt disabling -* policy uses the PRIMASK register to disable interrupts globally. The -* QF_AWARE_ISR_CMSIS_PRI level is zero, meaning that all interrupts are -* "QF-aware". -* -* NOTE3: -* On Cortex-M3/M4/M7, the interrupt disable/enable policy uses the BASEPRI -* register (which is not implemented in Cortex-M0/M0+/M1) to disable -* interrupts only with priority lower than the threshold specified by the -* QF_BASEPRI macro. The interrupts with priorities above QF_BASEPRI (i.e., -* with numerical priority values lower than QF_BASEPRI) are NOT disabled in -* this method. These free-running interrupts have very low ("zero") latency, -* but they are not allowed to call any QF services, because QF is unaware -* of them ("QF-unaware" interrutps). Consequently, only interrupts with -* numerical values of priorities eqal to or higher than QF_BASEPRI -* ("QF-aware" interrupts ), can call QF services. -* -* NOTE4: -* The QF_AWARE_ISR_CMSIS_PRI macro is useful as an offset for enumerating -* the "QF-aware" interrupt priorities in the applications, whereas the -* numerical values of the "QF-aware" interrupts must be greater or equal to -* QF_AWARE_ISR_CMSIS_PRI. The values based on QF_AWARE_ISR_CMSIS_PRI can be -* passed directly to the CMSIS function NVIC_SetPriority(), which shifts -* them by (8 - __NVIC_PRIO_BITS) into the correct bit position, while -* __NVIC_PRIO_BITS is the CMSIS macro defining the number of implemented -* priority bits in the NVIC. Please note that the macro QF_AWARE_ISR_CMSIS_PRI -* is intended only for applications and is not used inside the QF port, which -* remains generic and not dependent on the number of implemented priority bits -* implemented in the NVIC. -* -* NOTE5: -* The selective disabling of "QF-aware" interrupts with the BASEPRI register -* has a problem on ARM Cortex-M7 core r0p1 (see ARM-EPM-064408, errata -* 837070). The workaround recommended by ARM is to surround MSR BASEPRI with -* the CPSID i/CPSIE i pair, which is implemented in the QF_INT_DISABLE() -* macro. This workaround works also for Cortex-M3/M4 cores. -*/ - -#endif /* QF_PORT_H */ - diff --git a/ports/arm-cm/qk/iar/qk_port.c b/ports/arm-cm/qk/iar/qk_port.c index fa858d29..2c8fd39e 100644 --- a/ports/arm-cm/qk/iar/qk_port.c +++ b/ports/arm-cm/qk/iar/qk_port.c @@ -1,288 +1,278 @@ -/*============================================================================ -* QP/C Real-Time Embedded Framework (RTEF) -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2023-01-14 -* @version Last updated for: @ref qpc_7_2_1 -* -* @file -* @brief QK/C port to ARM Cortex-M, IAR-ARM toolset -*/ -/* This QK port is part of the internal QP implementation */ -#define QP_IMPL 1U -#include "qf_port.h" +//============================================================================ +// QP/C Real-Time Embedded Framework (RTEF) +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +//============================================================================ +//! @date Last updated on: 2023-08-16 +//! @version Last updated for: @ref qpc_7_3_0 +//! +//! @file +//! @brief QK/C port to ARM Cortex-M, IAR-ARM -/* prototypes --------------------------------------------------------------*/ +#define QP_IMPL 1U +#include "qp_port.h" + +// prototypes ---------------------------------------------------------------- void PendSV_Handler(void); -#ifdef QK_USE_IRQ_HANDLER /* if use IRQ... */ +#ifdef QK_USE_IRQ_HANDLER // if use IRQ... void QK_USE_IRQ_HANDLER(void); -#else /* use default (NMI) */ +#else // use default (NMI) void NMI_Handler(void); #endif -#define SCnSCB_ICTR ((uint32_t volatile *)0xE000E004U) -#define SCB_SYSPRI ((uint32_t volatile *)0xE000ED14U) +#define SCB_SYSPRI ((uint32_t volatile *)0xE000ED18U) #define NVIC_EN ((uint32_t volatile *)0xE000E100U) -#define NVIC_IP ((uint8_t volatile *)0xE000E400U) +#define NVIC_IP ((uint32_t volatile *)0xE000E400U) +#define SCB_CPACR *((uint32_t volatile *)0xE000ED88U) #define FPU_FPCCR *((uint32_t volatile *)0xE000EF34U) #define NVIC_PEND 0xE000E200 -#define NVIC_ICSR 0xE000ED04 +#define SCB_ICSR 0xE000ED04 -/* helper macros to "stringify" values */ +// helper macros to "stringify" values #define VAL(x) #x #define STRINGIFY(x) VAL(x) -/*..........................................................................*/ -/* Initialize the exception priorities and IRQ priorities to safe values. -* -* Description: -* On ARMv7-M or higher, this QK port disables interrupts by means of the -* BASEPRI register. However, this method cannot disable interrupt -* priority zero, which is the default for all interrupts out of reset. -* The following code changes the SysTick priority and all IRQ priorities -* to the safe value QF_BASEPRI, which the QF critical section can disable. -* This avoids breaching of the QF critical sections in case the -* application programmer forgets to explicitly set priorities of all -* "kernel aware" interrupts. -* -* The interrupt priorities established in QK_init() can be later -* changed by the application-level code. -*/ +//............................................................................ +// Initialize the exception priorities and IRQ priorities to safe values. +// +// Description: +// On ARMv7-M or higher, this QK port disables interrupts by means of the +// BASEPRI register. However, this method cannot disable interrupt +// priority zero, which is the default for all interrupts out of reset. +// The following code changes the SysTick priority and all IRQ priorities +// to the safe value QF_BASEPRI, which the QF critical section can disable. +// This avoids breaching of the QF critical sections in case the +// application programmer forgets to explicitly set priorities of all +// "kernel aware" interrupts. +// +// The interrupt priorities established in QK_init() can be later +// changed by the application-level code. void QK_init(void) { -#if (__ARM_ARCH != 6) /*--------- if ARMv7-M and higher... */ +#if (__ARM_ARCH != 6) //--------- if ARMv7-M and higher... - /* set exception priorities to QF_BASEPRI... - * SCB_SYSPRI1: Usage-fault, Bus-fault, Memory-fault - */ - SCB_SYSPRI[1] = (SCB_SYSPRI[1] - | (QF_BASEPRI << 16U) | (QF_BASEPRI << 8U) | QF_BASEPRI); - - /* SCB_SYSPRI2: SVCall */ + // SCB_SYSPRI[2]: SysTick SCB_SYSPRI[2] = (SCB_SYSPRI[2] | (QF_BASEPRI << 24U)); - /* SCB_SYSPRI3: SysTick, PendSV, Debug */ - SCB_SYSPRI[3] = (SCB_SYSPRI[3] - | (QF_BASEPRI << 24U) | (QF_BASEPRI << 16U) | QF_BASEPRI); - - /* set all implemented IRQ priories to QF_BASEPRI... */ - uint8_t nprio = (8U + ((*SCnSCB_ICTR & 0x7U) << 3U)) * 4U; - for (uint8_t n = 0U; n < nprio; ++n) { - NVIC_IP[n] = QF_BASEPRI; + // set all 240 possible IRQ priories to QF_BASEPRI... + for (uint_fast8_t n = 0U; n < (240U/sizeof(uint32_t)); ++n) { + NVIC_IP[n] = (QF_BASEPRI << 24U) | (QF_BASEPRI << 16U) + | (QF_BASEPRI << 8U) | QF_BASEPRI; } -#endif /*--------- ARMv7-M or higher */ +#endif //--------- ARMv7-M or higher - /* SCB_SYSPRI3: PendSV set to priority 0xFF (lowest) */ - SCB_SYSPRI[3] = (SCB_SYSPRI[3] | (0xFFU << 16U)); + // SCB_SYSPRI[2]: PendSV set to priority 0xFF (lowest) + SCB_SYSPRI[2] = (SCB_SYSPRI[2] | (0xFFU << 16U)); -#ifdef QK_USE_IRQ_NUM /*--------- QK IRQ specified? */ - /* The QK port is configured to use a given ARM Cortex-M IRQ # - * to return to thread mode (default is to use the NMI exception) - */ - NVIC_IP[QK_USE_IRQ_NUM] = 0U; /* priority 0 (highest) */ +#ifdef QK_USE_IRQ_NUM //--------- QK IRQ specified? + // The QK port is configured to use a given ARM Cortex-M IRQ # + // to return to thread mode (default is to use the NMI exception) + NVIC_IP[QK_USE_IRQ_NUM] = 0U; // priority 0 (highest) NVIC_EN[QK_USE_IRQ_NUM >> 5U] = (1U << (QK_USE_IRQ_NUM & 0x1FU)); -#endif /*--------- QK IRQ specified */ +#endif //--------- QK IRQ specified -#if (__ARM_FP != 0) /*--------- if VFP available... */ - /* configure the FPU for QK */ - FPU_FPCCR |= (1U << 30U) /* automatic FPU state preservation (ASPEN) */ - | (1U << 31U); /* lazy stacking (LSPEN) */ -#endif /*--------- VFP available */ +#ifdef __ARM_FP //--------- if VFP available... + // make sure that the FPU is enabled by seting CP10 & CP11 Full Access + SCB_CPACR = (SCB_CPACR | ((3UL << 20U) | (3UL << 22U))); + + // FPU automatic state preservation (ASPEN) lazy stacking (LSPEN) + FPU_FPCCR = (FPU_FPCCR | (1U << 30U) | (1U << 31U)); +#endif //--------- VFP available } -/*..........................................................................*/ -/* The PendSV_Handler exception is used for handling the asynchronous -* preemption in QK. The use of the PendSV exception is the recommended and -* the most efficient method for performing context switches with ARM Cortex-M. -* -* The PendSV exception should have the lowest priority in the whole system -* (0xFF, see QK_init). All other exceptions and interrupts should have higher -* priority. For example, for NVIC with 2 priority bits all interrupts and -* exceptions must have numerical value of priority lower than 0xC0. In this -* case the interrupt priority levels available to your applications are (in -* the order from the lowest urgency to the highest urgency): 0x80, 0x40, 0x00. -* -* Also, *all* "kernel aware" ISRs in the QK application must call the -* QK_ISR_EXIT() macro, which triggers PendSV when it detects a need for -* a context switch or asynchronous preemption. -* -* Due to tail-chaining and its lowest priority, the PendSV exception will be -* entered immediately after the exit from the *last* nested interrupt (or -* exception). In QK, this is exactly the time when the QK activator needs to -* handle the asynchronous preemption. -*/ +//............................................................................ +// The PendSV_Handler exception is used for handling the asynchronous +// preemption in QK. The use of the PendSV exception is the recommended and +// the most efficient method for performing context switches with ARM Cortex-M. +// +// The PendSV exception should have the lowest priority in the whole system +// (0xFF, see QK_init). All other exceptions and interrupts should have higher +// priority. For example, for NVIC with 2 priority bits all interrupts and +// exceptions must have numerical value of priority lower than 0xC0. In this +// case the interrupt priority levels available to your applications are (in +// the order from the lowest urgency to the highest urgency): 0x80, 0x40, 0x00. +// +// Also, *all* "kernel aware" ISRs in the QK application must call the +// QK_ISR_EXIT() macro, which triggers PendSV when it detects a need for +// a context switch or asynchronous preemption. +// +// Due to tail-chaining and its lowest priority, the PendSV exception will be +// entered immediately after the exit from the *last* nested interrupt (or +// exception). In QK, this is exactly the time when the QK activator needs to +// handle the asynchronous preemption. __stackless void PendSV_Handler(void) { __asm volatile ( + " PUSH {r0,lr} \n" // save EXC_RETURN + stack-aligner - /* Prepare constants in registers before entering critical section */ - " LDR r3,=" STRINGIFY(NVIC_ICSR) "\n" /* Interrupt Control and State */ - " MOVS r1,#1 \n" - " LSLS r1,r1,#27 \n" /* r0 := (1 << 27) (UNPENDSVSET bit) */ - - /*<<<<<<<<<<<<<<<<<<<<<<< CRITICAL SECTION BEGIN <<<<<<<<<<<<<<<<<<<<<<<<*/ -#if (__ARM_ARCH == 6) /*--------- if ARMv6-M... */ - " CPSID i \n" /* disable interrupts (set PRIMASK) */ -#else /* ARMv7-M and higher */ -#if (__ARM_FP != 0) /*--------- if VFP available... */ - " PUSH {r0,lr} \n" /* ... push lr plus stack-aligner */ -#endif /*--------- VFP available */ + //<<<<<<<<<<<<<<<<<<<<<<< CRITICAL SECTION BEGIN <<<<<<<<<<<<<<<<<<<<<<<< +#if (__ARM_ARCH == 6) //--------- if ARMv6-M... + " CPSID i \n" // disable interrupts (set PRIMASK) +#else // ARMv7-M and higher " MOVS r0,#" STRINGIFY(QF_BASEPRI) "\n" - " CPSID i \n" /* disable interrupts with BASEPRI */ - " MSR BASEPRI,r0 \n" /* apply the Cortex-M7 erraturm */ - " CPSIE i \n" /* 837070, see SDEN-1068427. */ -#endif /*--------- ARMv7-M and higher */ + " CPSID i \n" // disable interrupts with BASEPRI + " MSR BASEPRI,r0 \n" // apply the Cortex-M7 erraturm + " CPSIE i \n" // 837070, see SDEN-1068427. +#endif //--------- ARMv7-M and higher - /* The PendSV exception handler can be preempted by an interrupt, - * which might pend PendSV exception again. The following write to - * ICSR[27] un-pends any such spurious instance of PendSV. - */ - " STR r1,[r3] \n" /* ICSR[27] := 1 (unpend PendSV) */ +#ifdef QF_MEM_ISOLATE + " LDR r0,=QF_onMemSys \n" + " BLX r0 \n" // call QF_onMemSys() +#endif - /* The QK activator must be called in a Thread mode, while this code - * executes in the Handler mode of the PendSV exception. The switch - * to the Thread mode is accomplished by returning from PendSV using - * a fabricated exception stack frame, where the return address is - * QK_activate_(). - * - * NOTE: the QK activator is called with interrupts DISABLED and also - * returns with interrupts DISABLED. - */ - " LSRS r3,r1,#3 \n" /* r3 := (r1 >> 3), set the T bit (new xpsr) */ - " LDR r2,=QK_activate_ \n" /* address of QK_activate_ */ - " SUBS r2,r2,#1 \n" /* align Thumb-address at halfword (new pc) */ - " LDR r1,=QK_thread_ret \n" /* return address after the call (new lr) */ + // The PendSV exception handler can be preempted by an interrupt, + // which might pend PendSV exception again. The following write to + // ICSR[27] un-pends any such spurious instance of PendSV. + " LDR r2,=" STRINGIFY(SCB_ICSR) "\n" // Interrupt Control and State + " MOVS r1,#1 \n" + " LSLS r1,r1,#27 \n" // r1 := (1 << 27) (UNPENDSVSET bit) + " STR r1,[r2] \n" // ICSR[27] := 1 (unpend PendSV) - " SUB sp,sp,#8*4 \n" /* reserve space for exception stack frame */ - " ADD r0,sp,#5*4 \n" /* r0 := 5 registers below the SP */ - " STM r0!,{r1-r3} \n" /* save xpsr,pc,lr */ + // The QK activator must be called in a Thread mode, while this code + // executes in the Handler mode of the PendSV exception. The switch + // to the Thread mode is accomplished by returning from PendSV using + // a fabricated exception stack frame, where the return address is + // QK_activate_(). + // + // NOTE: the QK activator is called with interrupts DISABLED and also + // returns with interrupts DISABLED. + " LSRS r3,r1,#3 \n" // r3 := (r1 >> 3), set T bit (new xpsr) + " LDR r2,=QK_activate_ \n" // address of QK_activate_ + " SUBS r2,r2,#1 \n" // align Thumb-address at halfword (new pc) + " LDR r1,=QK_thread_ret \n" // return address after the call (new lr) + + " SUB sp,sp,#8*4 \n" // reserve space for exception stack frame + " ADD r0,sp,#5*4 \n" // r0 := 5 registers below the SP + " STM r0!,{r1-r3} \n" // save xpsr,pc,lr " MOVS r0,#6 \n" - " MVNS r0,r0 \n" /* r0 := ~6 == 0xFFFFFFF9 */ -#if (__ARM_ARCH != 6) /*--------- if ARMv7-M and higher... */ - " DSB \n" /* ARM Erratum 838869 */ -#endif /*--------- ARMv7-M and higher */ - " BX r0 \n" /* exception-return to the QK activator */ + " MVNS r0,r0 \n" // r0 := ~6 == 0xFFFFFFF9 +#if (__ARM_ARCH != 6) //--------- if ARMv7-M and higher... + " DSB \n" // ARM Erratum 838869 +#endif //--------- ARMv7-M and higher + " BX r0 \n" // exception-return to the QK activator ); } -/*==========================================================================*/ -/* QK_thread_ret is a helper function executed when the QXK activator returns. -* -* NOTE: QK_thread_ret does not execute in the PendSV context! -* NOTE: QK_thread_ret is entered with interrupts DISABLED. -*/ +//============================================================================ +// QK_thread_ret is a helper function executed when the QXK activator returns. +// +// NOTE: QK_thread_ret does not execute in the PendSV context! +// NOTE: QK_thread_ret is entered with interrupts DISABLED. __stackless void QK_thread_ret(void) { __asm volatile ( - /* After the QK activator returns, we need to resume the preempted - * thread. However, this must be accomplished by a return-from-exception, - * while we are still in the thread context. The switch to the exception - * context is accomplished by triggering the NMI exception or the selected - * IRQ (if macro #QK_USE_IRQ_NUM is defined). - */ + // After the QK activator returns, we need to resume the preempted + // thread. However, this must be accomplished by a return-from-exception, + // while we are still in the thread context. The switch to the exception + // context is accomplished by triggering the NMI exception or the selected + // IRQ (if macro #QK_USE_IRQ_NUM is defined). - /* before triggering the NMI/IRQ, make sure that the VFP stack frame - * will NOT be used... - */ -#if (__ARM_FP != 0) /*--------- if VFP available... */ - /* make sure that the VFP stack frame will NOT be used */ - " MRS r0,CONTROL \n" /* r0 := CONTROL */ - " BICS r0,r0,#4 \n" /* r0 := r0 & ~4 (FPCA bit) */ - " MSR CONTROL,r0 \n" /* CONTROL := r0 (clear CONTROL[2] FPCA bit) */ - " ISB \n" /* ISB after MSR CONTROL (ARM AN321,Sect.4.16) */ -#endif /*--------- VFP available */ + // before triggering the NMI/IRQ, make sure that the VFP stack frame + // will NOT be used... +#ifdef __ARM_FP //--------- if VFP available... + // make sure that the VFP stack frame will NOT be used + " MRS r0,CONTROL \n" // r0 := CONTROL + " BICS r0,r0,#4 \n" // r0 := r0 & ~4 (FPCA bit) + " MSR CONTROL,r0 \n" // CONTROL := r0 (clear CONTROL[2] FPCA bit) + " ISB \n" // ISB after MSR CONTROL (ARM AN321,Sect.4.16) +#endif //--------- VFP available -#ifndef QK_USE_IRQ_NUM /*--------- IRQ NOT defined, use NMI by default */ - " LDR r0,=" STRINGIFY(NVIC_ICSR) "\n" /* Interrupt Control and State */ +#ifdef QF_MEM_ISOLATE + " LDR r0,=QF_onMemApp \n" + " BLX r0 \n" // call QF_onMemApp() +#endif + +#ifndef QK_USE_IRQ_NUM //--------- IRQ NOT defined, use NMI by default + " LDR r0,=" STRINGIFY(SCB_ICSR) "\n" // Interrupt Control and State " MOVS r1,#1 \n" - " LSLS r1,r1,#31 \n" /* r1 := (1 << 31) (NMI bit) */ - " STR r1,[r0] \n" /* ICSR[31] := 1 (pend NMI) */ + " LSLS r1,r1,#31 \n" // r1 := (1 << 31) (NMI bit) + " STR r1,[r0] \n" // ICSR[31] := 1 (pend NMI) -#else /*--------- use the selected IRQ */ +#else //--------- use the selected IRQ " LDR r0,=" STRINGIFY(NVIC_PEND + ((QK_USE_IRQ_NUM >> 5) << 2)) "\n" " MOVS r1,#1 \n" - " LSLS r1,r1,#" STRINGIFY(QK_USE_IRQ_NUM & 0x1F) "\n" /* r1 := IRQ bit */ - " STR r1,[r0] \n" /* pend the IRQ */ + " LSLS r1,r1,#" STRINGIFY(QK_USE_IRQ_NUM & 0x1F) "\n" // r1 := IRQ bit + " STR r1,[r0] \n" // pend the IRQ - /* now enable interrupts so that pended IRQ can be entered */ -#if (__ARM_ARCH == 6) /*--------- if ARMv6-M... */ - " CPSIE i \n" /* enable interrupts (clear PRIMASK) */ -#else /*--------- ARMv7-M and higher */ + // now enable interrupts so that pended IRQ can be entered +#if (__ARM_ARCH == 6) //--------- if ARMv6-M... + " CPSIE i \n" // enable interrupts (clear PRIMASK) +#else //--------- ARMv7-M and higher " MOVS r0,#0 \n" - " MSR BASEPRI,r0 \n" /* enable interrupts (clear BASEPRI) */ -#endif /*--------- ARMv7-M and higher */ -#endif /*--------- use IRQ */ + " MSR BASEPRI,r0 \n" // enable interrupts (clear BASEPRI) +#endif //--------- ARMv7-M and higher +#endif //--------- use IRQ - /* NOTE! interrupts are still disabled when NMI is used */ - " B . \n" /* wait for preemption by NMI/IRQ */ + // NOTE! interrupts are still disabled when NMI is used + " B . \n" // wait for preemption by NMI/IRQ ); } -/*==========================================================================*/ -/* This exception handler is used for returning back to the preempted thread. -* The exception handler simply removes its own interrupt stack frame from -* the stack (MSP) and returns to the preempted task using the interrupt -* stack frame that must be at the top of the stack. -*/ +//============================================================================ +// This exception handler is used for returning back to the preempted thread. +// The exception handler simply removes its own interrupt stack frame from +// the stack (MSP) and returns to the preempted task using the interrupt +// stack frame that must be at the top of the stack. __stackless -#ifndef QK_USE_IRQ_NUM /*--------- IRQ NOT defined, use NMI by default */ +#ifndef QK_USE_IRQ_NUM //--------- IRQ NOT defined, use NMI by default -/* NOTE: The NMI_Handler() is entered with interrupts still disabled! */ +// NOTE: The NMI_Handler() is entered with interrupts still disabled! void NMI_Handler(void) { __asm volatile ( - /* enable interrupts */ -#if (__ARM_ARCH == 6) /*--------- if ARMv6-M... */ - " CPSIE i \n" /* enable interrupts (clear PRIMASK) */ -#else /*--------- ARMv7-M and higher */ + // enable interrupts +#if (__ARM_ARCH == 6) //--------- if ARMv6-M... + " CPSIE i \n" // enable interrupts (clear PRIMASK) +#else //--------- ARMv7-M and higher " MOVS r0,#0 \n" - " MSR BASEPRI,r0 \n" /* enable interrupts (clear BASEPRI) */ -#endif /*--------- ARMv7-M and higher */ + " MSR BASEPRI,r0 \n" // enable interrupts (clear BASEPRI) +#endif //--------- ARMv7-M and higher ); -#else /*--------- use the selected IRQ */ +#else //--------- use the selected IRQ -/* NOTE: The IRQ Handler is entered with interrupts enabled */ +// NOTE: The IRQ Handler is entered with interrupts enabled void QK_USE_IRQ_HANDLER(void) { -#endif /*--------- use IRQ */ +#endif //--------- use IRQ __asm volatile ( - " ADD sp,sp,#(8*4) \n" /* remove one 8-register exception frame */ + " ADD sp,sp,#(8*4) \n" // remove one 8-register exception frame -#if (__ARM_FP != 0) /*--------- if VFP available... */ - " POP {r0,lr} \n" /* pop stack aligner and EXC_RETURN to LR */ - " DSB \n" /* ARM Erratum 838869 */ -#endif /*--------- VFP available */ - " BX lr \n" /* return to the preempted task */ + " POP {r0,r1} \n" // pop stack aligner and EXC_RETURN to r1 + " DSB \n" // ARM Erratum 838869 + " BX r1 \n" // return to the preempted task ); } -/*==========================================================================*/ -#if (__ARM_ARCH == 6) /* if ARMv6-M... */ +//============================================================================ +#if (__ARM_ARCH == 6) // if ARMv6-M... -/* hand-optimized quick LOG2 in assembly (no CLZ instruction in ARMv6-M) */ +// hand-optimized quick LOG2 in assembly (no CLZ instruction in ARMv6-M) uint_fast8_t QF_qlog2(uint32_t x) { static uint8_t const log2LUT[16] = { 0U, 1U, 2U, 2U, 3U, 3U, 3U, 3U, @@ -315,5 +305,5 @@ __asm volatile ( return n + log2LUT[x]; } -#endif /* ARMv6-M */ +#endif // ARMv6-M diff --git a/ports/arm-cm/qk/iar/qk_port.h b/ports/arm-cm/qk/iar/qk_port.h deleted file mode 100644 index eaa0bccc..00000000 --- a/ports/arm-cm/qk/iar/qk_port.h +++ /dev/null @@ -1,87 +0,0 @@ -/*============================================================================ -* QP/C Real-Time Embedded Framework (RTEF) -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2022-12-18 -* @version Last updated for: @ref qpc_7_2_0 -* -* @file -* @brief QK/C port to ARM Cortex-M, IAR-ARM toolset -*/ -#ifndef QK_PORT_H -#define QK_PORT_H - -/* determination if the code executes in the ISR context */ -#define QK_ISR_CONTEXT_() (__get_IPSR() != 0U) - -/* QK interrupt entry and exit */ -#define QK_ISR_ENTRY() ((void)0) - -#define QK_ISR_EXIT() do { \ - QF_INT_DISABLE(); \ - if (QK_sched_() != 0U) { \ - *Q_UINT2PTR_CAST(uint32_t, 0xE000ED04U) = (1U << 28U);\ - } \ - QF_INT_ENABLE(); \ - QK_ARM_ERRATUM_838869(); \ -} while (false) - -#if (__ARM_ARCH == 6) /* ARMv6-M? */ - #define QK_ARM_ERRATUM_838869() ((void)0) -#else /* ARMv7-M or higher */ - /* The following macro implements the recommended workaround for the - * ARM Erratum 838869. Specifically, for Cortex-M3/M4/M7 the DSB - * (memory barrier) instruction needs to be added before exiting an ISR. - */ - #define QK_ARM_ERRATUM_838869() __DSB() -#endif - -/* Use a given ARM Cortex-M IRQ to return to thread mode (default NMI) -* -* NOTE: -* If you need the NMI for other purposes, you can define the macros -* QK_USE_IRQ_NUM and QK_USE_IRQ_HANDLER to use thus specified IRQ -* instead of the NMI (the IRQ should not be used for anything else). -* These two macros can be defined on the command line to the compiler -* and are actually needed only to compile the qk_port.c file. -*/ -//#define QK_USE_IRQ_NUM 25 -//#define QK_USE_IRQ_HANDLER CRYPTO_IRQHandler - -/* initialization of the QK kernel */ -#define QK_INIT() QK_init() -void QK_init(void); -void QK_thread_ret(void); - -#if (__ARM_FP != 0) /* if VFP available... */ -/* When the FPU is configured, clear the FPCA bit in the CONTROL register -* to prevent wasting the stack space for the FPU context. -*/ -#define QK_START() __set_CONTROL(0U) -#endif - -#include "qk.h" /* QK platform-independent public interface */ - -#endif /* QK_PORT_H */ - diff --git a/ports/arm-cm/qk/iar/qp_port.h b/ports/arm-cm/qk/iar/qp_port.h new file mode 100644 index 00000000..013b9f6b --- /dev/null +++ b/ports/arm-cm/qk/iar/qp_port.h @@ -0,0 +1,232 @@ +//============================================================================ +// QP/C Real-Time Embedded Framework (RTEF) +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +//============================================================================ +//! @date Last updated on: 2023-09-07 +//! @version Last updated for: @ref qpc_7_3_0 +//! +//! @file +//! @brief QP/C port to ARM Cortex-M, preemptive QK kernel, IAR-ARM + +#ifndef QP_PORT_H_ +#define QP_PORT_H_ + +#include // Exact-width types. WG14/N843 C99 Standard +#include // Boolean type. WG14/N843 C99 Standard +#include // IAR intrinsic functions + +#ifdef QP_CONFIG +#include "qp_config.h" // external QP configuration +#endif + +// no-return function specifier (C11 Standard) +#define Q_NORETURN _Noreturn void + +// QF configuration for QK -- data members of the QActive class... + +// QK event-queue used for AOs +#define QACTIVE_EQUEUE_TYPE QEQueue + +// QF "thread" type used to store the MPU settings in the AO +#define QACTIVE_THREAD_TYPE void const * + +// QF interrupt disable/enable and log2()... +#if (__ARM_ARCH == 6) // ARMv6-M? + + // Cortex-M0/M0+/M1(v6-M, v6S-M) interrupt disabling policy, see NOTE2 + #define QF_INT_DISABLE() __disable_interrupt() + #define QF_INT_ENABLE() __enable_interrupt() + + // QF critical section entry/exit (save and restore interrupt status) + #define QF_CRIT_STAT unsigned long primask_; + #define QF_CRIT_ENTRY() do { \ + (primask_) = __get_PRIMASK(); \ + QF_INT_DISABLE(); \ + } while (false) + #define QF_CRIT_EXIT() __set_PRIMASK((primask_)) + + // CMSIS threshold for "QF-aware" interrupts, see NOTE2 and NOTE4 + #define QF_AWARE_ISR_CMSIS_PRI 0 + + // hand-optimized LOG2 in assembly for Cortex-M0/M0+/M1(v6-M, v6S-M) + #define QF_LOG2(n_) QF_qlog2((uint32_t)(n_)) + +#else // ARMv7-M or higher + + // ARMv7-M or higher alternative interrupt disabling with PRIMASK + #define QF_PRIMASK_DISABLE() __disable_interrupt() + #define QF_PRIMASK_ENABLE() __enable_interrupt() + + // ARMv7-M or higher interrupt disabling policy, see NOTE3 and NOTE4 + #define QF_INT_DISABLE() do { \ + QF_PRIMASK_DISABLE(); \ + __set_BASEPRI(QF_BASEPRI); \ + QF_PRIMASK_ENABLE(); \ + } while (false) + #define QF_INT_ENABLE() __set_BASEPRI(0U) + + // QF critical section entry/exit (save and restore interrupt status) + #define QF_CRIT_STAT unsigned long basepri_; + #define QF_CRIT_ENTRY() do { \ + basepri_ = __get_BASEPRI(); \ + QF_INT_DISABLE(); \ + } while (false) + #define QF_CRIT_EXIT() __set_BASEPRI((basepri_)) + + // BASEPRI threshold for "QF-aware" interrupts, see NOTE3 + #define QF_BASEPRI 0x3F + + // CMSIS threshold for "QF-aware" interrupts, see NOTE5 + #define QF_AWARE_ISR_CMSIS_PRI (QF_BASEPRI >> (8 - __NVIC_PRIO_BITS)) + + // ARMv7-M or higher provide the CLZ instruction for fast LOG2 + #define QF_LOG2(n_) ((uint_fast8_t)(32U - __CLZ((unsigned long)(n_)))) + +#endif + +#define QF_CRIT_EXIT_NOP() __ISB() + +#if (__ARM_ARCH == 6) // ARMv6-M? + // hand-optimized quick LOG2 in assembly + uint_fast8_t QF_qlog2(uint32_t x); +#endif // ARMv7-M or higher + +// Memory isolation ---------------------------------------------------------- +#ifdef QF_MEM_ISOLATE + + // Memory isolation requires the context-switch + #define QF_ON_CONTEXT_SW 1U + + // Memory System setting + #define QF_MEM_SYS() QF_onMemSys() + + // Memory Application setting + #define QF_MEM_APP() QF_onMemApp() + + // callback functions for memory settings (provided by applications) + void QF_onMemSys(void); + void QF_onMemApp(void); + +#endif // def QF_MEM_ISOLATE + +// determination if the code executes in the ISR context +#define QK_ISR_CONTEXT_() (__get_IPSR() != 0U) + +// QK ISR entry and exit +#define QK_ISR_ENTRY() ((void)0) + +#ifdef QF_MEM_ISOLATE + #define QK_ISR_EXIT() do { \ + QF_INT_DISABLE(); \ + QF_MEM_SYS(); \ + if (QK_sched_() != 0U) { \ + *Q_UINT2PTR_CAST(uint32_t, 0xE000ED04U) = (1U << 28U);\ + } \ + QF_MEM_APP(); \ + QF_INT_ENABLE(); \ + QK_ARM_ERRATUM_838869(); \ + } while (false) +#else + #define QK_ISR_EXIT() do { \ + QF_INT_DISABLE(); \ + if (QK_sched_() != 0U) { \ + *Q_UINT2PTR_CAST(uint32_t, 0xE000ED04U) = (1U << 28U);\ + } \ + QF_INT_ENABLE(); \ + QK_ARM_ERRATUM_838869(); \ + } while (false) +#endif + +#if (__ARM_ARCH == 6) // ARMv6-M? + #define QK_ARM_ERRATUM_838869() ((void)0) +#else // ARMv7-M or higher + // The following macro implements the recommended workaround for the + // ARM Erratum 838869. Specifically, for Cortex-M3/M4/M7 the DSB + // (memory barrier) instruction needs to be added before exiting an ISR. + #define QK_ARM_ERRATUM_838869() __DSB() + +#endif // ARMv6-M + +// initialization of the QK kernel +#define QK_INIT() QK_init() +void QK_init(void); +void QK_thread_ret(void); + +#ifdef __ARM_FP //--------- if VFP available... +// When the FPU is configured, clear the FPCA bit in the CONTROL register +// to prevent wasting the stack space for the FPU context. +#define QK_START() __set_CONTROL(0U) +#endif + +// include files ------------------------------------------------------------- +#include "qequeue.h" // QK kernel uses the native QP event queue +#include "qmpool.h" // QK kernel uses the native QP memory pool +#include "qp.h" // QP framework +#include "qk.h" // QK kernel + +//============================================================================ +// NOTE2: +// On Cortex-M0/M0+/M1 (architecture v6-M, v6S-M), the interrupt disabling +// policy uses the PRIMASK register to disable interrupts globally. The +// QF_AWARE_ISR_CMSIS_PRI level is zero, meaning that all interrupts are +// "QF-aware". +// +// NOTE3: +// On ARMv7-M or higher, the interrupt disable/enable policy uses the BASEPRI +// register (which is not implemented in Cortex-M0/M0+/M1) to disable +// interrupts only with priority lower than the threshold specified by the +// QF_BASEPRI macro. The interrupts with priorities above QF_BASEPRI (i.e., +// with numerical priority values lower than QF_BASEPRI) are NOT disabled in +// this method. These free-running interrupts have very low ("zero") latency, +// but they are not allowed to call any QF services, because QF is unaware +// of them ("QF-unaware" interrupts). Consequently, only interrupts with +// numerical values of priorities equal to or higher than QF_BASEPRI +// ("QF-aware" interrupts ), can call QF services. +// +// NOTE4: +// The QF_AWARE_ISR_CMSIS_PRI macro is useful as an offset for enumerating +// the "QF-aware" interrupt priorities in the applications, whereas the +// numerical values of the "QF-aware" interrupts must be greater or equal to +// QF_AWARE_ISR_CMSIS_PRI. The values based on QF_AWARE_ISR_CMSIS_PRI can be +// passed directly to the CMSIS function NVIC_SetPriority(), which shifts +// them by (8 - __NVIC_PRIO_BITS) into the correct bit position, while +// __NVIC_PRIO_BITS is the CMSIS macro defining the number of implemented +// priority bits in the NVIC. Please note that the macro QF_AWARE_ISR_CMSIS_PRI +// is intended only for applications and is not used inside the QF port, which +// remains generic and not dependent on the number of implemented priority bits +// implemented in the NVIC. +// +// NOTE5: +// The selective disabling of "QF-aware" interrupts with the BASEPRI register +// has a problem on ARM Cortex-M7 core r0p1 (see ARM-EPM-064408, errata +// 837070). The workaround recommended by ARM is to surround MSR BASEPRI with +// the CPSID i/CPSIE i pair, which is implemented in the QF_INT_DISABLE() +// macro. This workaround works also for Cortex-M3/M4 cores. + +#endif // QP_PORT_H_ + diff --git a/ports/arm-cm/qk/iar/qs_port.h b/ports/arm-cm/qk/iar/qs_port.h index e8b00882..92ec4663 100644 --- a/ports/arm-cm/qk/iar/qs_port.h +++ b/ports/arm-cm/qk/iar/qs_port.h @@ -1,60 +1,61 @@ -/*============================================================================ -* QP/C Real-Time Embedded Framework (RTEF) -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2022-06-12 -* @version Last updated for: @ref qpc_7_0_1 -* -* @file -* @brief QS/C port to a 32-bit CPU and a generic C99 compiler. -* @description -* This is an example of a QP/C port with the documentation for the -* configuration macros and includes. -*/ -#ifndef QS_PORT_H -#define QS_PORT_H +//============================================================================ +// QP/C Real-Time Embedded Framework (RTEF) +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +//============================================================================ +//! @date Last updated on: 2023-08-16 +//! @version Last updated for: @ref qpc_7_3_0 +//! +//! @file +//! @brief QS/C port to a 32-bit CPU and a generic C11 compiler. -/* QS time-stamp size in bytes */ -#define QS_TIME_SIZE 4 +#ifndef QS_PORT_H_ +#define QS_PORT_H_ -/* object pointer size in bytes */ -#define QS_OBJ_PTR_SIZE 4 +// QS time-stamp size in bytes +#define QS_TIME_SIZE 4U -/* function pointer size in bytes */ -#define QS_FUN_PTR_SIZE 4 +// object pointer size in bytes +#define QS_OBJ_PTR_SIZE 4U -/*==========================================================================*/ -/* NOTE: QS might be used with or without other QP components, in which -* case the separate definitions of the macros QF_CRIT_STAT_TYPE, -* QF_CRIT_ENTRY, and QF_CRIT_EXIT are needed. In this port QS is configured -* to be used with the other QP component, by simply including "qf_port.h" -* *before* "qs.h". -*/ -#ifndef QF_PORT_H -#include "qf_port.h" /* use QS with QF */ +// function pointer size in bytes +#define QS_FUN_PTR_SIZE 4U + +//============================================================================ +// NOTE: QS might be used with or without other QP components, in which +// case the separate definitions of the macros QF_CRIT_STAT, QF_CRIT_ENTRY(), +// and QF_CRIT_EXIT() are needed. In this port QS is configured to be used +// with the other QP component, by simply including "qp_port.h" +//*before* "qs.h". +#ifndef QP_PORT_H_ +#include "qp_port.h" // use QS with QF #endif -#include "qs.h" /* QS platform-independent public interface */ +#include "qs.h" // QS platform-independent public interface + +#endif // QS_PORT_H_ -#endif /* QS_PORT_H */ diff --git a/ports/arm-cm/qutest/qep_port.h b/ports/arm-cm/qutest/qep_port.h deleted file mode 100644 index 12e9074b..00000000 --- a/ports/arm-cm/qutest/qep_port.h +++ /dev/null @@ -1,41 +0,0 @@ -/*============================================================================ -* QP/C Real-Time Embedded Framework (RTEF) -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2022-04-09 -* @version Last updated for: @ref qpc_7_0_0 -* -* @file -* @brief QEP/C port, generic C99 compiler -*/ -#ifndef QEP_PORT_H -#define QEP_PORT_H - -#include /* Exact-width types. WG14/N843 C99 Standard */ -#include /* Boolean type. WG14/N843 C99 Standard */ - -#include "qep.h" /* QEP platform-independent public interface */ - -#endif /* QEP_PORT_H */ - diff --git a/ports/arm-cm/qutest/qf_port.h b/ports/arm-cm/qutest/qf_port.h deleted file mode 100644 index 2d19d0ae..00000000 --- a/ports/arm-cm/qutest/qf_port.h +++ /dev/null @@ -1,92 +0,0 @@ -/*============================================================================ -* QP/C Real-Time Embedded Framework (RTEF) -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2022-11-11 -* @version Last updated for: @ref qpc_7_1_3 -* -* @file -* @brief QF/C port to Cortex-M, QUTEST unit test harness, generic C99 compiler -*/ -#ifndef QF_PORT_H -#define QF_PORT_H - -/* QUTEST event queue and thread types */ -#define QF_EQUEUE_TYPE QEQueue -/*#define QF_OS_OBJECT_TYPE */ -/*#define QF_THREAD_TYPE */ - -/* The maximum number of active objects in the application */ -#define QF_MAX_ACTIVE 32U - -/* The number of system clock tick rates */ -#define QF_MAX_TICK_RATE 2U - -/* QF interrupt disable/enable */ -#define QF_INT_DISABLE() (++QF_intLock_) -#define QF_INT_ENABLE() (--QF_intLock_) - -/* QF critical section */ -/* QF_CRIT_STAT_TYPE not defined */ -#define QF_CRIT_ENTRY(dummy) QF_INT_DISABLE() -#define QF_CRIT_EXIT(dummy) QF_INT_ENABLE() - -/* QF_LOG2 not defined -- use the internal LOG2() implementation */ - -#include "qep_port.h" /* QEP port */ -#include "qequeue.h" /* QUTEST port uses QEQueue event-queue */ -#include "qmpool.h" /* QUTEST port uses QMPool memory-pool */ -#include "qf.h" /* QF platform-independent public interface */ - -/****************************************************************************/ -/* interface used only inside QF implementation, but not in applications */ -#ifdef QP_IMPL - - /* QUTEST scheduler locking (not used) */ - #define QF_SCHED_STAT_ - #define QF_SCHED_LOCK_(dummy) ((void)0) - #define QF_SCHED_UNLOCK_() ((void)0) - - /* native event queue operations */ - #define QACTIVE_EQUEUE_WAIT_(me_) \ - Q_ASSERT_ID(0, (me_)->eQueue.frontEvt != (QEvt *)0) - #define QACTIVE_EQUEUE_SIGNAL_(me_) \ - QPSet_insert(&QF_readySet_, (uint_fast8_t)(me_)->prio) - - /* native QF event pool operations */ - #define QF_EPOOL_TYPE_ QMPool - #define QF_EPOOL_INIT_(p_, poolSto_, poolSize_, evtSize_) \ - (QMPool_init(&(p_), (poolSto_), (poolSize_), (evtSize_))) - #define QF_EPOOL_EVENT_SIZE_(p_) ((uint_fast16_t)(p_).blockSize) - #define QF_EPOOL_GET_(p_, e_, m_, qs_id_) \ - ((e_) = (QEvt *)QMPool_get(&(p_), (m_), (qs_id_))) - #define QF_EPOOL_PUT_(p_, e_, qs_id_) \ - (QMPool_put(&(p_), (e_), (qs_id_))) - - #include "qf_pkg.h" /* internal QF interface */ - -#endif /* QP_IMPL */ - - -#endif /* QF_PORT_H */ diff --git a/ports/arm-cm/qutest/qp_port.h b/ports/arm-cm/qutest/qp_port.h new file mode 100644 index 00000000..0febfc48 --- /dev/null +++ b/ports/arm-cm/qutest/qp_port.h @@ -0,0 +1,100 @@ +//============================================================================ +// QP/C Real-Time Embedded Framework (RTEF) +// Copyright (C) 2005 Quantum Leaps, LLC . +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +//============================================================================ +//! @date Last updated on: 2023-09-07 +//! @version Last updated for: @ref qpc_7_3_0 +//! +//! @file +//! @brief QP/C "port" for QUTEST unit test harness, generic C99 + +#ifndef QP_PORT_H_ +#define QP_PORT_H_ + +#include // Exact-width types. WG14/N843 C99 Standard +#include // Boolean type. WG14/N843 C99 Standard + +#ifdef QP_CONFIG +#include "qp_config.h" // external QP configuration +#endif + +// no-return function specifier (C11 Standard) +#define Q_NORETURN _Noreturn void + +// QUTest event queue and thread types +#define QACTIVE_EQUEUE_TYPE QEQueue +// QACTIVE_OS_OBJ_TYPE not used in this port +// QACTIVE_THREAD_TYPE not used in this port + +// QF interrupt disable/enable +#define QF_INT_DISABLE() (++QS_tstPriv_.intLock) +#define QF_INT_ENABLE() (--QS_tstPriv_.intLock) + +// QF critical section +#define QF_CRIT_STAT +#define QF_CRIT_ENTRY() QF_INT_DISABLE() +#define QF_CRIT_EXIT() QF_INT_ENABLE() + +// QF_LOG2 not defined -- use the internal LOG2() implementation + +// include files ------------------------------------------------------------- +#include "qequeue.h" // QUTest port uses QEQueue event-queue +#include "qmpool.h" // QUTest port uses QMPool memory-pool +#include "qp.h" // QP platform-independent public interface + +//============================================================================ +// interface used only inside QF implementation, but not in applications +#ifdef QP_IMPL + + // QUTest scheduler locking (not used) + #define QF_SCHED_STAT_ + #define QF_SCHED_LOCK_(dummy) ((void)0) + #define QF_SCHED_UNLOCK_() ((void)0) + + // native event queue operations + #define QACTIVE_EQUEUE_WAIT_(me_) \ + Q_ASSERT_INCRIT(310, (me_)->eQueue.frontEvt != (QEvt *)0) + +#ifndef Q_UNSAFE + #define QACTIVE_EQUEUE_SIGNAL_(me_) \ + QPSet_insert(&QS_tstPriv_.readySet, (uint_fast8_t)(me_)->prio); \ + QPSet_update_(&QS_tstPriv_.readySet, &QS_tstPriv_.readySet_dis) +#else + #define QACTIVE_EQUEUE_SIGNAL_(me_) \ + QPSet_insert(&QF_readySet_, (uint_fast8_t)(me_)->prio) +#endif + + // native QF event pool operations + #define QF_EPOOL_TYPE_ QMPool + #define QF_EPOOL_INIT_(p_, poolSto_, poolSize_, evtSize_) \ + (QMPool_init(&(p_), (poolSto_), (poolSize_), (evtSize_))) + #define QF_EPOOL_EVENT_SIZE_(p_) ((uint_fast16_t)(p_).blockSize) + #define QF_EPOOL_GET_(p_, e_, m_, qs_id_) \ + ((e_) = (QEvt *)QMPool_get(&(p_), (m_), (qs_id_))) + #define QF_EPOOL_PUT_(p_, e_, qs_id_) \ + (QMPool_put(&(p_), (e_), (qs_id_))) + +#endif // QP_IMPL + +#endif // QP_PORT_H_ + diff --git a/ports/arm-cm/qutest/qs_port.h b/ports/arm-cm/qutest/qs_port.h index e8b00882..78a4666a 100644 --- a/ports/arm-cm/qutest/qs_port.h +++ b/ports/arm-cm/qutest/qs_port.h @@ -1,60 +1,56 @@ -/*============================================================================ -* QP/C Real-Time Embedded Framework (RTEF) -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2022-06-12 -* @version Last updated for: @ref qpc_7_0_1 -* -* @file -* @brief QS/C port to a 32-bit CPU and a generic C99 compiler. -* @description -* This is an example of a QP/C port with the documentation for the -* configuration macros and includes. -*/ -#ifndef QS_PORT_H -#define QS_PORT_H +//============================================================================ +// QP/C Real-Time Embedded Framework (RTEF) +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +//============================================================================ +//! @date Last updated on: 2023-08-16 +//! @version Last updated for: @ref qpc_7_3_0 +//! +//! @file +//! @brief QS/C port to a 32-bit CPU and a generic C11 compiler. -/* QS time-stamp size in bytes */ -#define QS_TIME_SIZE 4 +#ifndef QS_PORT_H_ +#define QS_PORT_H_ -/* object pointer size in bytes */ -#define QS_OBJ_PTR_SIZE 4 +// QS time-stamp size in bytes +#define QS_TIME_SIZE 4U -/* function pointer size in bytes */ -#define QS_FUN_PTR_SIZE 4 +// object pointer size in bytes +#define QS_OBJ_PTR_SIZE 4U -/*==========================================================================*/ -/* NOTE: QS might be used with or without other QP components, in which -* case the separate definitions of the macros QF_CRIT_STAT_TYPE, -* QF_CRIT_ENTRY, and QF_CRIT_EXIT are needed. In this port QS is configured -* to be used with the other QP component, by simply including "qf_port.h" -* *before* "qs.h". -*/ -#ifndef QF_PORT_H -#include "qf_port.h" /* use QS with QF */ +// function pointer size in bytes +#define QS_FUN_PTR_SIZE 4U + +//============================================================================ +// NOTE: QS might be used with or without other QP components, in which +// case the separate definitions of the macros QF_CRIT_STAT, QF_CRIT_ENTRY(), +// and QF_CRIT_EXIT() are needed. In this port QS is configured to be used +// with the other QP component, by simply including "qp_port.h" +//*before* "qs.h". +#ifndef QP_PORT_H_ +#include "qp_port.h" // use QS with QP #endif -#include "qs.h" /* QS platform-independent public interface */ +#include "qs.h" // QS platform-independent public interface + +#endif // QS_PORT_H_ -#endif /* QS_PORT_H */ diff --git a/ports/arm-cm/qv/armclang/qep_port.h b/ports/arm-cm/qv/armclang/qep_port.h deleted file mode 100644 index c1eb162f..00000000 --- a/ports/arm-cm/qv/armclang/qep_port.h +++ /dev/null @@ -1,44 +0,0 @@ -/*============================================================================ -* QP/C Real-Time Embedded Framework (RTEF) -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2022-04-09 -* @version Last updated for: @ref qpc_7_0_0 -* -* @file -* @brief QEP/C port, ARM-Clang/LLVM compiler -*/ -#ifndef QEP_PORT_H -#define QEP_PORT_H - -/*! no-return function specifier (ARM-Clang/LLVM compiler) */ -#define Q_NORETURN __attribute__ ((noreturn)) void - -#include /* Exact-width types. WG14/N843 C99 Standard */ -#include /* Boolean type. WG14/N843 C99 Standard */ - -#include "qep.h" /* QEP platform-independent public interface */ - -#endif /* QEP_PORT_H */ - diff --git a/ports/arm-cm/qv/armclang/qf_port.h b/ports/arm-cm/qv/armclang/qf_port.h deleted file mode 100644 index 9ca2d3aa..00000000 --- a/ports/arm-cm/qv/armclang/qf_port.h +++ /dev/null @@ -1,147 +0,0 @@ -/*============================================================================ -* QP/C Real-Time Embedded Framework (RTEF) -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2022-04-09 -* @version Last updated for: @ref qpc_7_0_0 -* -* @file -* @brief QF/C port to Cortex-M, cooperative QV kernel, ARM-CLANG toolset -*/ -#ifndef QF_PORT_H -#define QF_PORT_H - -/* The maximum number of system clock tick rates */ -#define QF_MAX_TICK_RATE 2U - -/* QF interrupt disable/enable and log2()... */ -#if (__ARM_ARCH == 6) /* Cortex-M0/M0+/M1(v6-M, v6S-M)? */ - - /* The maximum number of active objects in the application, see NOTE1 */ - #define QF_MAX_ACTIVE 8U - - /* Cortex-M0/M0+/M1(v6-M, v6S-M) interrupt disabling policy, see NOTE2 */ - #define QF_INT_DISABLE() __asm volatile ("cpsid i") - #define QF_INT_ENABLE() __asm volatile ("cpsie i") - - /* QF critical section entry/exit (unconditional interrupt disabling) */ - /*#define QF_CRIT_STAT_TYPE not defined */ - #define QF_CRIT_ENTRY(dummy) QF_INT_DISABLE() - #define QF_CRIT_EXIT(dummy) QF_INT_ENABLE() - - /* CMSIS threshold for "QF-aware" interrupts, see NOTE2 and NOTE4 */ - #define QF_AWARE_ISR_CMSIS_PRI 0 - - /* hand-optimized LOG2 in assembly for Cortex-M0/M0+/M1(v6-M, v6S-M) */ - #define QF_LOG2(n_) QF_qlog2((uint32_t)(n_)) - -#else /* Cortex-M3/M4/M7 */ - - /* The maximum number of active objects in the application, see NOTE1 */ - #define QF_MAX_ACTIVE 16U - - /* Cortex-M3/M4/M7 alternative interrupt disabling with PRIMASK */ - #define QF_PRIMASK_DISABLE() __asm volatile ("cpsid i") - #define QF_PRIMASK_ENABLE() __asm volatile ("cpsie i") - - /* Cortex-M3/M4/M7 interrupt disabling policy, see NOTE3 and NOTE4 */ - #define QF_INT_DISABLE() __asm volatile (\ - "cpsid i\n" "msr BASEPRI,%0\n" "cpsie i" :: "r" (QF_BASEPRI) : ) - #define QF_INT_ENABLE() __asm volatile (\ - "msr BASEPRI,%0" :: "r" (0) : ) - - /* QF critical section entry/exit (unconditional interrupt disabling) */ - /*#define QF_CRIT_STAT_TYPE not defined */ - #define QF_CRIT_ENTRY(dummy) QF_INT_DISABLE() - #define QF_CRIT_EXIT(dummy) QF_INT_ENABLE() - - /* BASEPRI threshold for "QF-aware" interrupts, see NOTE3 */ - #define QF_BASEPRI 0x3F - - /* CMSIS threshold for "QF-aware" interrupts, see NOTE5 */ - #define QF_AWARE_ISR_CMSIS_PRI (QF_BASEPRI >> (8 - __NVIC_PRIO_BITS)) - - /* Cortex-M3/M4/M7 provide the CLZ instruction for fast LOG2 */ - #define QF_LOG2(n_) ((uint_fast8_t)(32 - __builtin_clz((unsigned)(n_)))) - -#endif - -#define QF_CRIT_EXIT_NOP() __asm volatile ("isb") - -#include "qep_port.h" /* QEP port */ - -#if (__ARM_ARCH == 6) /* ARMv6-M? */ - /* hand-optimized quick LOG2 in assembly */ - uint_fast8_t QF_qlog2(uint32_t x); -#endif /* ARMv7-M or higher */ - -#include "qv_port.h" /* QV cooperative kernel port */ -#include "qf.h" /* QF platform-independent public interface */ - -/***************************************************************************** -* NOTE1: -* The maximum number of active objects QF_MAX_ACTIVE can be increased -* up to 64U, if necessary. Here it is set to a lower level to save some RAM. -* -* NOTE2: -* On Cortex-M0/M0+/M1 (architecture v6-M, v6S-M), the interrupt disabling -* policy uses the PRIMASK register to disable interrupts globally. The -* QF_AWARE_ISR_CMSIS_PRI level is zero, meaning that all interrupts are -* "QF-aware". -* -* NOTE3: -* On Cortex-M3/M4/M7, the interrupt disable/enable policy uses the BASEPRI -* register (which is not implemented in Cortex-M0/M0+/M1) to disable -* interrupts only with priority lower than the threshold specified by the -* QF_BASEPRI macro. The interrupts with priorities above QF_BASEPRI (i.e., -* with numerical priority values lower than QF_BASEPRI) are NOT disabled in -* this method. These free-running interrupts have very low ("zero") latency, -* but they are not allowed to call any QF services, because QF is unaware -* of them ("QF-unaware" interrutps). Consequently, only interrupts with -* numerical values of priorities eqal to or higher than QF_BASEPRI -* ("QF-aware" interrupts ), can call QF services. -* -* NOTE4: -* The QF_AWARE_ISR_CMSIS_PRI macro is useful as an offset for enumerating -* the "QF-aware" interrupt priorities in the applications, whereas the -* numerical values of the "QF-aware" interrupts must be greater or equal to -* QF_AWARE_ISR_CMSIS_PRI. The values based on QF_AWARE_ISR_CMSIS_PRI can be -* passed directly to the CMSIS function NVIC_SetPriority(), which shifts -* them by (8 - __NVIC_PRIO_BITS) into the correct bit position, while -* __NVIC_PRIO_BITS is the CMSIS macro defining the number of implemented -* priority bits in the NVIC. Please note that the macro QF_AWARE_ISR_CMSIS_PRI -* is intended only for applications and is not used inside the QF port, which -* remains generic and not dependent on the number of implemented priority bits -* implemented in the NVIC. -* -* NOTE5: -* The selective disabling of "QF-aware" interrupts with the BASEPRI register -* has a problem on ARM Cortex-M7 core r0p1 (see ARM-EPM-064408, errata -* 837070). The workaround recommended by ARM is to surround MSR BASEPRI with -* the CPSID i/CPSIE i pair, which is implemented in the QF_INT_DISABLE() -* macro. This workaround works also for Cortex-M3/M4 cores. -*/ - -#endif /* QF_PORT_H */ - diff --git a/ports/arm-cm/qv/armclang/qp_port.h b/ports/arm-cm/qv/armclang/qp_port.h new file mode 100644 index 00000000..914a1132 --- /dev/null +++ b/ports/arm-cm/qv/armclang/qp_port.h @@ -0,0 +1,224 @@ +//============================================================================ +// QP/C Real-Time Embedded Framework (RTEF) +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +//============================================================================ +//! @date Last updated on: 2023-09-07 +//! @version Last updated for: @ref qpc_7_3_0 +//! +//! @file +//! @brief QP/C port to ARM Cortex-M, cooperative QV kernel, ARM-CLANG + +#ifndef QP_PORT_H_ +#define QP_PORT_H_ + +#include // Exact-width types. WG14/N843 C99 Standard +#include // Boolean type. WG14/N843 C99 Standard + +#ifdef QP_CONFIG +#include "qp_config.h" // external QP configuration +#endif + +// no-return function specifier (C11 Standard) +#define Q_NORETURN _Noreturn void + +// QF configuration for QV -- data members of the QActive class... + +// QV event-queue used for AOs +#define QACTIVE_EQUEUE_TYPE QEQueue + +// QF "thread" type used to store the MPU settings in the AO +#define QACTIVE_THREAD_TYPE void const * + +// QF interrupt disable/enable and log2()... +#if (__ARM_ARCH == 6) // ARMv6-M? + + // Cortex-M0/M0+/M1(v6-M, v6S-M) interrupt disabling policy, see NOTE2 + #define QF_INT_DISABLE() __asm volatile ("cpsid i" ::: "memory") + #define QF_INT_ENABLE() __asm volatile ("cpsie i" ::: "memory") + + // QF critical section (save and restore interrupt status), see NOTE2 + #define QF_CRIT_STAT uint32_t primask_; + #define QF_CRIT_ENTRY() __asm volatile (\ + "mrs %0,PRIMASK\n" "cpsid i" : "=r" (primask_) :: "memory") + #define QF_CRIT_EXIT() __asm volatile (\ + "msr PRIMASK,%0" :: "r" (primask_) : "memory") + + // CMSIS threshold for "QF-aware" interrupts, see NOTE2 and NOTE4 + #define QF_AWARE_ISR_CMSIS_PRI 0 + + // hand-optimized LOG2 in assembly for Cortex-M0/M0+/M1(v6-M, v6S-M) + #define QF_LOG2(n_) QF_qlog2((uint32_t)(n_)) + +#else // ARMv7-M or higher + + // ARMv7-M or higher alternative interrupt disabling with PRIMASK + #define QF_PRIMASK_DISABLE() __asm volatile ("cpsid i" ::: "memory") + #define QF_PRIMASK_ENABLE() __asm volatile ("cpsie i" ::: "memory") + + // ARMv7-M or higher interrupt disabling policy, see NOTE3 and NOTE4 + #define QF_INT_DISABLE() __asm volatile (\ + "cpsid i\n" "msr BASEPRI,%0\n" "cpsie i" \ + :: "r" (QF_BASEPRI) : "memory") + #define QF_INT_ENABLE() __asm volatile (\ + "msr BASEPRI,%0" :: "r" (0) : "memory") + + // QF critical section (save and restore interrupt status), see NOTE5 + #define QF_CRIT_STAT uint32_t basepri_; + #define QF_CRIT_ENTRY() do { \ + __asm volatile ("mrs %0,BASEPRI" : "=r" (basepri_) :: "memory"); \ + __asm volatile ("cpsid i\n msr BASEPRI,%0\n cpsie i" \ + :: "r" (QF_BASEPRI) : "memory"); \ + } while (false) + #define QF_CRIT_EXIT() \ + __asm volatile ("msr BASEPRI,%0" :: "r" (basepri_) : "memory") + + // BASEPRI threshold for "QF-aware" interrupts, see NOTE3 + #define QF_BASEPRI 0x3F + + // CMSIS threshold for "QF-aware" interrupts, see NOTE5 + #define QF_AWARE_ISR_CMSIS_PRI (QF_BASEPRI >> (8 - __NVIC_PRIO_BITS)) + + // ARMv7-M or higher provide the CLZ instruction for fast LOG2 + #define QF_LOG2(n_) ((uint_fast8_t)(32 - __builtin_clz((unsigned)(n_)))) + +#endif + +#define QF_CRIT_EXIT_NOP() __asm volatile ("isb" ::: "memory") + +#if (__ARM_ARCH == 6) // ARMv6-M? + // hand-optimized quick LOG2 in assembly + uint_fast8_t QF_qlog2(uint32_t x); +#endif // ARMv7-M or higher + +// Memory isolation ---------------------------------------------------------- +#ifdef QF_MEM_ISOLATE + + // Memory isolation requires the context-switch + #define QF_ON_CONTEXT_SW 1U + + // Memory System setting + #define QF_MEM_SYS() QF_onMemSys() + + // Memory Application setting + #define QF_MEM_APP() QF_onMemApp() + + // callback functions for memory settings (provided by applications) + void QF_onMemSys(void); + void QF_onMemApp(void); + +#endif // def QF_MEM_ISOLATE + +// determination if the code executes in the ISR context +#if (__ARM_ARCH == 6) // ARMv6-M? + + // macro to put the CPU to sleep inside QV_onIdle() + #define QV_CPU_SLEEP() do { \ + __asm volatile ("wfi"::: "memory"); \ + QF_MEM_APP(); \ + QF_INT_ENABLE(); \ + } while (false) + + #define QV_ARM_ERRATUM_838869() ((void)0) + +#else // ARMv7-M or higher + + // macro to put the CPU to sleep inside QV_onIdle() + #define QV_CPU_SLEEP() do { \ + QF_PRIMASK_DISABLE(); \ + QF_MEM_APP(); \ + QF_INT_ENABLE(); \ + __asm volatile ("wfi" ::: "memory"); \ + QF_PRIMASK_ENABLE(); \ + } while (false) + + // The following macro implements the recommended workaround for the + // ARM Erratum 838869. Specifically, for Cortex-M3/M4/M7 the DSB + // (memory barrier) instruction needs to be added before exiting an ISR. + // This macro should be inserted at the end of ISRs. + #define QV_ARM_ERRATUM_838869() \ + __asm volatile ("dsb 0xf" ::: "memory") + +#endif + +// initialization of the QV kernel +#define QV_INIT() QV_init() +void QV_init(void); + +#ifdef __ARM_FP //--------- if VFP available... +// When the FPU is configured, clear the FPCA bit in the CONTROL register +// to prevent wasting the stack space for the FPU context. +#define QV_START() __asm volatile ("msr CONTROL,%0" :: "r" (0) : "memory") +#endif + +// include files ------------------------------------------------------------- +#include "qequeue.h" // QV kernel uses the native QP event queue +#include "qmpool.h" // QV kernel uses the native QP memory pool +#include "qp.h" // QP framework +#include "qv.h" // QV kernel + +//============================================================================ +// NOTE2: +// On Cortex-M0/M0+/M1 (architecture v6-M, v6S-M), the interrupt disabling +// policy uses the PRIMASK register to disable interrupts globally. The +// QF_AWARE_ISR_CMSIS_PRI level is zero, meaning that all interrupts are +// "QF-aware". +// +// NOTE3: +// On ARMv7-M or higher, the interrupt disable/enable policy uses the BASEPRI +// register (which is not implemented in Cortex-M0/M0+/M1) to disable +// interrupts only with priority lower than the threshold specified by the +// QF_BASEPRI macro. The interrupts with priorities above QF_BASEPRI (i.e., +// with numerical priority values lower than QF_BASEPRI) are NOT disabled in +// this method. These free-running interrupts have very low ("zero") latency, +// but they are not allowed to call any QF services, because QF is unaware +// of them ("QF-unaware" interrupts). Consequently, only interrupts with +// numerical values of priorities equal to or higher than QF_BASEPRI +// ("QF-aware" interrupts ), can call QF services. +// +// NOTE4: +// The QF_AWARE_ISR_CMSIS_PRI macro is useful as an offset for enumerating +// the "QF-aware" interrupt priorities in the applications, whereas the +// numerical values of the "QF-aware" interrupts must be greater or equal to +// QF_AWARE_ISR_CMSIS_PRI. The values based on QF_AWARE_ISR_CMSIS_PRI can be +// passed directly to the CMSIS function NVIC_SetPriority(), which shifts +// them by (8 - __NVIC_PRIO_BITS) into the correct bit position, while +// __NVIC_PRIO_BITS is the CMSIS macro defining the number of implemented +// priority bits in the NVIC. Please note that the macro QF_AWARE_ISR_CMSIS_PRI +// is intended only for applications and is not used inside the QF port, which +// remains generic and not dependent on the number of implemented priority bits +// implemented in the NVIC. +// +// NOTE5: +// The selective disabling of "QF-aware" interrupts with the BASEPRI register +// has a problem on ARM Cortex-M7 core r0p1 (see ARM-EPM-064408, errata +// 837070). The workaround recommended by ARM is to surround MSR BASEPRI with +// the CPSID i/CPSIE i pair, which is implemented in the QF_INT_DISABLE() +// macro. This workaround works also for Cortex-M3/M4 cores. + +#endif // QP_PORT_H_ + diff --git a/ports/arm-cm/qv/armclang/qs_port.h b/ports/arm-cm/qv/armclang/qs_port.h index e8b00882..92ec4663 100644 --- a/ports/arm-cm/qv/armclang/qs_port.h +++ b/ports/arm-cm/qv/armclang/qs_port.h @@ -1,60 +1,61 @@ -/*============================================================================ -* QP/C Real-Time Embedded Framework (RTEF) -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2022-06-12 -* @version Last updated for: @ref qpc_7_0_1 -* -* @file -* @brief QS/C port to a 32-bit CPU and a generic C99 compiler. -* @description -* This is an example of a QP/C port with the documentation for the -* configuration macros and includes. -*/ -#ifndef QS_PORT_H -#define QS_PORT_H +//============================================================================ +// QP/C Real-Time Embedded Framework (RTEF) +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +//============================================================================ +//! @date Last updated on: 2023-08-16 +//! @version Last updated for: @ref qpc_7_3_0 +//! +//! @file +//! @brief QS/C port to a 32-bit CPU and a generic C11 compiler. -/* QS time-stamp size in bytes */ -#define QS_TIME_SIZE 4 +#ifndef QS_PORT_H_ +#define QS_PORT_H_ -/* object pointer size in bytes */ -#define QS_OBJ_PTR_SIZE 4 +// QS time-stamp size in bytes +#define QS_TIME_SIZE 4U -/* function pointer size in bytes */ -#define QS_FUN_PTR_SIZE 4 +// object pointer size in bytes +#define QS_OBJ_PTR_SIZE 4U -/*==========================================================================*/ -/* NOTE: QS might be used with or without other QP components, in which -* case the separate definitions of the macros QF_CRIT_STAT_TYPE, -* QF_CRIT_ENTRY, and QF_CRIT_EXIT are needed. In this port QS is configured -* to be used with the other QP component, by simply including "qf_port.h" -* *before* "qs.h". -*/ -#ifndef QF_PORT_H -#include "qf_port.h" /* use QS with QF */ +// function pointer size in bytes +#define QS_FUN_PTR_SIZE 4U + +//============================================================================ +// NOTE: QS might be used with or without other QP components, in which +// case the separate definitions of the macros QF_CRIT_STAT, QF_CRIT_ENTRY(), +// and QF_CRIT_EXIT() are needed. In this port QS is configured to be used +// with the other QP component, by simply including "qp_port.h" +//*before* "qs.h". +#ifndef QP_PORT_H_ +#include "qp_port.h" // use QS with QF #endif -#include "qs.h" /* QS platform-independent public interface */ +#include "qs.h" // QS platform-independent public interface + +#endif // QS_PORT_H_ -#endif /* QS_PORT_H */ diff --git a/ports/arm-cm/qv/armclang/qv_port.c b/ports/arm-cm/qv/armclang/qv_port.c index 87af3117..a9c223e7 100644 --- a/ports/arm-cm/qv/armclang/qv_port.c +++ b/ports/arm-cm/qv/armclang/qv_port.c @@ -1,99 +1,89 @@ -/*============================================================================ -* QP/C Real-Time Embedded Framework (RTEF) -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2022-12-18 -* @version Last updated for: @ref qpc_7_2_0 -* -* @file -* @brief QV/C port to ARM Cortex-M, ARM-CLANG toolset -*/ -/* This QV port is part of the internal QP implementation */ -#define QP_IMPL 1U -#include "qf_port.h" +//============================================================================ +// QP/C Real-Time Embedded Framework (RTEF) +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +//============================================================================ +//! @date Last updated on: 2023-08-17 +//! @version Last updated for: @ref qpc_7_3_0 +//! +//! @file +//! @brief QV/C port to ARM Cortex-M, ARM-CLANG -#define SCnSCB_ICTR ((uint32_t volatile *)0xE000E004U) -#define SCB_SYSPRI ((uint32_t volatile *)0xE000ED14U) +#define QP_IMPL 1U +#include "qp_port.h" + +#define SCB_SYSPRI ((uint32_t volatile *)0xE000ED18U) #define NVIC_IP ((uint32_t volatile *)0xE000E400U) +#define SCB_CPACR *((uint32_t volatile *)0xE000ED88U) #define FPU_FPCCR *((uint32_t volatile *)0xE000EF34U) -/*..........................................................................*/ -/* -* Initialize the exception priorities and IRQ priorities to safe values. -* -* Description: -* On ARMv7-M or higher, this QK port disables interrupts by means of the -* BASEPRI register. However, this method cannot disable interrupt -* priority zero, which is the default for all interrupts out of reset. -* The following code changes the SysTick priority and all IRQ priorities -* to the safe value QF_BASEPRI, which the QF critical section can disable. -* This avoids breaching of the QF critical sections in case the -* application programmer forgets to explicitly set priorities of all -* "kernel aware" interrupts. -* -* The interrupt priorities established in QV_init() can be later -* changed by the application-level code. -*/ +//............................................................................ +// Initialize the exception priorities and IRQ priorities to safe values. +// +// Description: +// On ARMv7-M or higher, this QK port disables interrupts by means of the +// BASEPRI register. However, this method cannot disable interrupt +// priority zero, which is the default for all interrupts out of reset. +// The following code changes the SysTick priority and all IRQ priorities +// to the safe value QF_BASEPRI, which the QF critical section can disable. +// This avoids breaching of the QF critical sections in case the +// application programmer forgets to explicitly set priorities of all +// "kernel aware" interrupts. +// +// The interrupt priorities established in QV_init() can be later +// changed by the application-level code. void QV_init(void) { -#if (__ARM_ARCH != 6) /*--------- if ARMv7-M and higher... */ +#if (__ARM_ARCH != 6) //--------- if ARMv7-M and higher... - /* set exception priorities to QF_BASEPRI... - * SCB_SYSPRI1: Usage-fault, Bus-fault, Memory-fault - */ - SCB_SYSPRI[1] = (SCB_SYSPRI[1] - | (QF_BASEPRI << 16U) | (QF_BASEPRI << 8U) | QF_BASEPRI); - - /* SCB_SYSPRI2: SVCall */ + // SCB_SYSPRI[2]: SysTick SCB_SYSPRI[2] = (SCB_SYSPRI[2] | (QF_BASEPRI << 24U)); - /* SCB_SYSPRI3: SysTick, PendSV, Debug */ - SCB_SYSPRI[3] = (SCB_SYSPRI[3] - | (QF_BASEPRI << 24U) | (QF_BASEPRI << 16U) | QF_BASEPRI); - - /* set all implemented IRQ priories to QF_BASEPRI... */ - uint8_t nprio = (8U + ((*SCnSCB_ICTR & 0x7U) << 3U)) * 4U; - for (uint8_t n = 0U; n < nprio; ++n) { - NVIC_IP[n] = QF_BASEPRI; + // set all 240 possible IRQ priories to QF_BASEPRI... + for (uint_fast8_t n = 0U; n < (240U/sizeof(uint32_t)); ++n) { + NVIC_IP[n] = (QF_BASEPRI << 24U) | (QF_BASEPRI << 16U) + | (QF_BASEPRI << 8U) | QF_BASEPRI; } -#endif /*--------- ARMv7-M or higher */ +#endif //--------- ARMv7-M or higher - /* SCB_SYSPRI3: PendSV set to priority 0xFF (lowest) */ - SCB_SYSPRI[3] = (SCB_SYSPRI[3] | (0xFFU << 16U)); +#ifdef __ARM_FP //--------- if VFP available... + // make sure that the FPU is enabled by seting CP10 & CP11 Full Access + SCB_CPACR = (SCB_CPACR | ((3UL << 20U) | (3UL << 22U))); -#if (__ARM_FP != 0) /*--------- if VFP available... */ - /* configure the FPU for QK */ - FPU_FPCCR |= (1U << 30U) /* automatic FPU state preservation (ASPEN) */ - | (1U << 31U); /* lazy stacking (LSPEN) */ -#endif /*--------- VFP available */ + // FPU automatic state preservation (ASPEN) lazy stacking (LSPEN) + FPU_FPCCR = (FPU_FPCCR | (1U << 30U) | (1U << 31U)); +#endif //--------- VFP available } -/*==========================================================================*/ -#if (__ARM_ARCH == 6) /* if ARMv6-M... */ +//============================================================================ +#if (__ARM_ARCH == 6) // if ARMv6-M... -/* hand-optimized quick LOG2 in assembly (no CLZ instruction in ARMv6-M) */ +// hand-optimized quick LOG2 in assembly (no CLZ instruction in ARMv6-M) __attribute__ ((naked)) uint_fast8_t QF_qlog2(uint32_t x) { __asm volatile ( @@ -127,5 +117,5 @@ __asm volatile ( ); } -#endif /* ARMv6-M */ +#endif // ARMv6-M diff --git a/ports/arm-cm/qv/armclang/qv_port.h b/ports/arm-cm/qv/armclang/qv_port.h deleted file mode 100644 index da3ec8cb..00000000 --- a/ports/arm-cm/qv/armclang/qv_port.h +++ /dev/null @@ -1,79 +0,0 @@ -/*============================================================================ -* QP/C Real-Time Embedded Framework (RTEF) -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2022-12-18 -* @version Last updated for: @ref qpc_7_2_0 -* -* @file -* @brief QV/C port to ARM Cortex-M, ARM-CLANG/LLVM toolset -*/ -#ifndef QV_PORT_H -#define QV_PORT_H - -#if (__ARM_ARCH == 6) /* ARMv6-M? */ - - /* macro to put the CPU to sleep inside QV_onIdle() */ - #define QV_CPU_SLEEP() do { \ - __asm volatile ("wfi"); \ - QF_INT_ENABLE(); \ - } while (false) - - #define QV_ARM_ERRATUM_838869() ((void)0) - -#else /* ARMv7-M or higher */ - - /* macro to put the CPU to sleep inside QV_onIdle() */ - #define QV_CPU_SLEEP() do { \ - QF_PRIMASK_DISABLE(); \ - QF_INT_ENABLE(); \ - __asm volatile ("wfi"); \ - QF_PRIMASK_ENABLE(); \ - } while (false) - - /* The following macro implements the recommended workaround for the - * ARM Erratum 838869. Specifically, for Cortex-M3/M4/M7 the DSB - * (memory barrier) instruction needs to be added before exiting an ISR. - * This macro should be inserted at the end of ISRs. - */ - #define QV_ARM_ERRATUM_838869() \ - __asm volatile ("dsb 0xf" ::: "memory") - -#endif - -/* initialization of the QV kernel */ -#define QV_INIT() QV_init() -void QV_init(void); - -#if (__ARM_FP != 0) /* if VFP available... */ -/* When the FPU is configured, clear the FPCA bit in the CONTROL register -* to prevent wasting the stack space for the FPU context. -*/ -#define QV_START() __asm volatile ("msr CONTROL,%0" :: "r" (0) : ) -#endif - -#include "qv.h" /* QV platform-independent public interface */ - -#endif /* QV_PORT_H */ - diff --git a/ports/arm-cm/qv/gnu/qep_port.h b/ports/arm-cm/qv/gnu/qep_port.h deleted file mode 100644 index 67577b76..00000000 --- a/ports/arm-cm/qv/gnu/qep_port.h +++ /dev/null @@ -1,44 +0,0 @@ -/*============================================================================ -* QP/C Real-Time Embedded Framework (RTEF) -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2022-04-09 -* @version Last updated for: @ref qpc_7_0_0 -* -* @file -* @brief QEP/C port, GNU-ARM compiler -*/ -#ifndef QEP_PORT_H -#define QEP_PORT_H - -/*! no-return function specifier (GCC-ARM compiler) */ -#define Q_NORETURN __attribute__ ((noreturn)) void - -#include /* Exact-width types. WG14/N843 C99 Standard */ -#include /* Boolean type. WG14/N843 C99 Standard */ - -#include "qep.h" /* QEP platform-independent public interface */ - -#endif /* QEP_PORT_H */ - diff --git a/ports/arm-cm/qv/gnu/qf_port.h b/ports/arm-cm/qv/gnu/qf_port.h deleted file mode 100644 index 35148d76..00000000 --- a/ports/arm-cm/qv/gnu/qf_port.h +++ /dev/null @@ -1,147 +0,0 @@ -/*============================================================================ -* QP/C Real-Time Embedded Framework (RTEF) -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2022-04-09 -* @version Last updated for: @ref qpc_7_0_0 -* -* @file -* @brief QF/C port to Cortex-M, cooperative QV kernel, GNU-ARM toolset -*/ -#ifndef QF_PORT_H -#define QF_PORT_H - -/* The maximum number of system clock tick rates */ -#define QF_MAX_TICK_RATE 2U - -/* QF interrupt disable/enable and log2()... */ -#if (__ARM_ARCH == 6) /* ARMv6-M, v6S-M)? */ - - /* The maximum number of active objects in the application, see NOTE1 */ - #define QF_MAX_ACTIVE 16U - - /* Cortex-M0/M0+/M1(v6-M, v6S-M) interrupt disabling policy, see NOTE2 */ - #define QF_INT_DISABLE() __asm volatile ("cpsid i") - #define QF_INT_ENABLE() __asm volatile ("cpsie i") - - /* QF critical section entry/exit (unconditional interrupt disabling) */ - /*#define QF_CRIT_STAT_TYPE not defined */ - #define QF_CRIT_ENTRY(dummy) QF_INT_DISABLE() - #define QF_CRIT_EXIT(dummy) QF_INT_ENABLE() - - /* CMSIS threshold for "QF-aware" interrupts, see NOTE2 and NOTE4 */ - #define QF_AWARE_ISR_CMSIS_PRI 0 - - /* hand-optimized LOG2 in assembly for Cortex-M0/M0+/M1(v6-M, v6S-M) */ - #define QF_LOG2(n_) QF_qlog2((uint32_t)(n_)) - -#else /* ARMv7-M and higher */ - - /* The maximum number of active objects in the application, see NOTE1 */ - #define QF_MAX_ACTIVE 32U - - /* Cortex-M3/M4/M7 alternative interrupt disabling with PRIMASK */ - #define QF_PRIMASK_DISABLE() __asm volatile ("cpsid i") - #define QF_PRIMASK_ENABLE() __asm volatile ("cpsie i") - - /* Cortex-M3/M4/M7 interrupt disabling policy, see NOTE3 and NOTE4 */ - #define QF_INT_DISABLE() __asm volatile (\ - "cpsid i\n" "msr BASEPRI,%0\n" "cpsie i" :: "r" (QF_BASEPRI) : ) - #define QF_INT_ENABLE() __asm volatile (\ - "msr BASEPRI,%0" :: "r" (0) : ) - - /* QF critical section entry/exit (unconditional interrupt disabling) */ - /*#define QF_CRIT_STAT_TYPE not defined */ - #define QF_CRIT_ENTRY(dummy) QF_INT_DISABLE() - #define QF_CRIT_EXIT(dummy) QF_INT_ENABLE() - - /* BASEPRI threshold for "QF-aware" interrupts, see NOTE3 */ - #define QF_BASEPRI 0x3F - - /* CMSIS threshold for "QF-aware" interrupts, see NOTE5 */ - #define QF_AWARE_ISR_CMSIS_PRI (QF_BASEPRI >> (8 - __NVIC_PRIO_BITS)) - - /* Cortex-M3/M4/M7 provide the CLZ instruction for fast LOG2 */ - #define QF_LOG2(n_) ((uint_fast8_t)(32U - __builtin_clz((unsigned)(n_)))) - -#endif - -#define QF_CRIT_EXIT_NOP() __asm volatile ("isb") - -#include "qep_port.h" /* QEP port */ - -#if (__ARM_ARCH == 6) /* ARMv6-M? */ - /* hand-optimized quick LOG2 in assembly */ - uint_fast8_t QF_qlog2(uint32_t x); -#endif /* ARMv7-M or higher */ - -#include "qv_port.h" /* QV cooperative kernel port */ -#include "qf.h" /* QF platform-independent public interface */ - -/***************************************************************************** -* NOTE1: -* The maximum number of active objects QF_MAX_ACTIVE can be increased -* up to 64U, if necessary. Here it is set to a lower level to save some RAM. -* -* NOTE2: -* On Cortex-M0/M0+/M1 (architecture v6-M, v6S-M), the interrupt disabling -* policy uses the PRIMASK register to disable interrupts globally. The -* QF_AWARE_ISR_CMSIS_PRI level is zero, meaning that all interrupts are -* "QF-aware". -* -* NOTE3: -* On Cortex-M3/M4/M7, the interrupt disable/enable policy uses the BASEPRI -* register (which is not implemented in Cortex-M0/M0+/M1) to disable -* interrupts only with priority lower than the threshold specified by the -* QF_BASEPRI macro. The interrupts with priorities above QF_BASEPRI (i.e., -* with numerical priority values lower than QF_BASEPRI) are NOT disabled in -* this method. These free-running interrupts have very low ("zero") latency, -* but they are not allowed to call any QF services, because QF is unaware -* of them ("QF-unaware" interrutps). Consequently, only interrupts with -* numerical values of priorities eqal to or higher than QF_BASEPRI -* ("QF-aware" interrupts ), can call QF services. -* -* NOTE4: -* The QF_AWARE_ISR_CMSIS_PRI macro is useful as an offset for enumerating -* the "QF-aware" interrupt priorities in the applications, whereas the -* numerical values of the "QF-aware" interrupts must be greater or equal to -* QF_AWARE_ISR_CMSIS_PRI. The values based on QF_AWARE_ISR_CMSIS_PRI can be -* passed directly to the CMSIS function NVIC_SetPriority(), which shifts -* them by (8 - __NVIC_PRIO_BITS) into the correct bit position, while -* __NVIC_PRIO_BITS is the CMSIS macro defining the number of implemented -* priority bits in the NVIC. Please note that the macro QF_AWARE_ISR_CMSIS_PRI -* is intended only for applications and is not used inside the QF port, which -* remains generic and not dependent on the number of implemented priority bits -* implemented in the NVIC. -* -* NOTE5: -* The selective disabling of "QF-aware" interrupts with the BASEPRI register -* has a problem on ARM Cortex-M7 core r0p1 (see ARM-EPM-064408, errata -* 837070). The workaround recommended by ARM is to surround MSR BASEPRI with -* the CPSID i/CPSIE i pair, which is implemented in the QF_INT_DISABLE() -* macro. This workaround works also for Cortex-M3/M4 cores. -*/ - -#endif /* QF_PORT_H */ - diff --git a/ports/arm-cm/qv/gnu/qp_port.h b/ports/arm-cm/qv/gnu/qp_port.h new file mode 100644 index 00000000..83f84740 --- /dev/null +++ b/ports/arm-cm/qv/gnu/qp_port.h @@ -0,0 +1,224 @@ +//============================================================================ +// QP/C Real-Time Embedded Framework (RTEF) +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +//============================================================================ +//! @date Last updated on: 2023-09-07 +//! @version Last updated for: @ref qpc_7_3_0 +//! +//! @file +//! @brief QP/C port to ARM Cortex-M, cooperative QV kernel, GNU-ARM + +#ifndef QP_PORT_H_ +#define QP_PORT_H_ + +#include // Exact-width types. WG14/N843 C99 Standard +#include // Boolean type. WG14/N843 C99 Standard + +#ifdef QP_CONFIG +#include "qp_config.h" // external QP configuration +#endif + +// no-return function specifier (C11 Standard) +#define Q_NORETURN _Noreturn void + +// QF configuration for QV -- data members of the QActive class... + +// QV event-queue used for AOs +#define QACTIVE_EQUEUE_TYPE QEQueue + +// QF "thread" type used to store the MPU settings in the AO +#define QACTIVE_THREAD_TYPE void const * + +// QF interrupt disable/enable and log2()... +#if (__ARM_ARCH == 6) // ARMv6-M? + + // Cortex-M0/M0+/M1(v6-M, v6S-M) interrupt disabling policy, see NOTE2 + #define QF_INT_DISABLE() __asm volatile ("cpsid i" ::: "memory") + #define QF_INT_ENABLE() __asm volatile ("cpsie i" ::: "memory") + + // QF critical section (save and restore interrupt status), see NOTE2 + #define QF_CRIT_STAT uint32_t primask_; + #define QF_CRIT_ENTRY() __asm volatile (\ + "mrs %0,PRIMASK\n" "cpsid i" : "=r" (primask_) :: "memory") + #define QF_CRIT_EXIT() __asm volatile (\ + "msr PRIMASK,%0" :: "r" (primask_) : "memory") + + // CMSIS threshold for "QF-aware" interrupts, see NOTE2 and NOTE4 + #define QF_AWARE_ISR_CMSIS_PRI 0 + + // hand-optimized LOG2 in assembly for Cortex-M0/M0+/M1(v6-M, v6S-M) + #define QF_LOG2(n_) QF_qlog2((uint32_t)(n_)) + +#else // ARMv7-M or higher + + // ARMv7-M or higher alternative interrupt disabling with PRIMASK + #define QF_PRIMASK_DISABLE() __asm volatile ("cpsid i" ::: "memory") + #define QF_PRIMASK_ENABLE() __asm volatile ("cpsie i" ::: "memory") + + // ARMv7-M or higher interrupt disabling policy, see NOTE3 and NOTE4 + #define QF_INT_DISABLE() __asm volatile (\ + "cpsid i\n" "msr BASEPRI,%0\n" "cpsie i" \ + :: "r" (QF_BASEPRI) : "memory") + #define QF_INT_ENABLE() __asm volatile (\ + "msr BASEPRI,%0" :: "r" (0) : "memory") + + // QF critical section (save and restore interrupt status), see NOTE5 + #define QF_CRIT_STAT uint32_t basepri_; + #define QF_CRIT_ENTRY() do { \ + __asm volatile ("mrs %0,BASEPRI" : "=r" (basepri_) :: "memory"); \ + __asm volatile ("cpsid i\n msr BASEPRI,%0\n cpsie i" \ + :: "r" (QF_BASEPRI) : "memory"); \ + } while (false) + #define QF_CRIT_EXIT() \ + __asm volatile ("msr BASEPRI,%0" :: "r" (basepri_) : "memory") + + // BASEPRI threshold for "QF-aware" interrupts, see NOTE3 + #define QF_BASEPRI 0x3F + + // CMSIS threshold for "QF-aware" interrupts, see NOTE5 + #define QF_AWARE_ISR_CMSIS_PRI (QF_BASEPRI >> (8 - __NVIC_PRIO_BITS)) + + // ARMv7-M or higher provide the CLZ instruction for fast LOG2 + #define QF_LOG2(n_) ((uint_fast8_t)(32 - __builtin_clz((unsigned)(n_)))) + +#endif + +#define QF_CRIT_EXIT_NOP() __asm volatile ("isb" ::: "memory") + +#if (__ARM_ARCH == 6) // ARMv6-M? + // hand-optimized quick LOG2 in assembly + uint_fast8_t QF_qlog2(uint32_t x); +#endif // ARMv7-M or higher + +// Memory isolation ---------------------------------------------------------- +#ifdef QF_MEM_ISOLATE + + // Memory isolation requires the context-switch + #define QF_ON_CONTEXT_SW 1U + + // Memory System setting + #define QF_MEM_SYS() QF_onMemSys() + + // Memory Application setting + #define QF_MEM_APP() QF_onMemApp() + + // callback functions for memory settings (provided by applications) + void QF_onMemSys(void); + void QF_onMemApp(void); + +#endif // def QF_MEM_ISOLATE + +// determination if the code executes in the ISR context +#if (__ARM_ARCH == 6) // ARMv6-M? + + // macro to put the CPU to sleep inside QV_onIdle() + #define QV_CPU_SLEEP() do { \ + __asm volatile ("wfi"::: "memory"); \ + QF_MEM_APP(); \ + QF_INT_ENABLE(); \ + } while (false) + + #define QV_ARM_ERRATUM_838869() ((void)0) + +#else // ARMv7-M or higher + + // macro to put the CPU to sleep inside QV_onIdle() + #define QV_CPU_SLEEP() do { \ + QF_PRIMASK_DISABLE(); \ + QF_MEM_APP(); \ + QF_INT_ENABLE(); \ + __asm volatile ("wfi" ::: "memory"); \ + QF_PRIMASK_ENABLE(); \ + } while (false) + + // The following macro implements the recommended workaround for the + // ARM Erratum 838869. Specifically, for Cortex-M3/M4/M7 the DSB + // (memory barrier) instruction needs to be added before exiting an ISR. + // This macro should be inserted at the end of ISRs. + #define QV_ARM_ERRATUM_838869() \ + __asm volatile ("dsb" ::: "memory") + +#endif + +// initialization of the QV kernel +#define QV_INIT() QV_init() +void QV_init(void); + +#ifdef __ARM_FP //--------- if VFP available... +// When the FPU is configured, clear the FPCA bit in the CONTROL register +// to prevent wasting the stack space for the FPU context. +#define QV_START() __asm volatile ("msr CONTROL,%0" :: "r" (0) : "memory") +#endif + +// include files ------------------------------------------------------------- +#include "qequeue.h" // QV kernel uses the native QP event queue +#include "qmpool.h" // QV kernel uses the native QP memory pool +#include "qp.h" // QP framework +#include "qv.h" // QV kernel + +//============================================================================ +// NOTE2: +// On Cortex-M0/M0+/M1 (architecture v6-M, v6S-M), the interrupt disabling +// policy uses the PRIMASK register to disable interrupts globally. The +// QF_AWARE_ISR_CMSIS_PRI level is zero, meaning that all interrupts are +// "QF-aware". +// +// NOTE3: +// On ARMv7-M or higher, the interrupt disable/enable policy uses the BASEPRI +// register (which is not implemented in Cortex-M0/M0+/M1) to disable +// interrupts only with priority lower than the threshold specified by the +// QF_BASEPRI macro. The interrupts with priorities above QF_BASEPRI (i.e., +// with numerical priority values lower than QF_BASEPRI) are NOT disabled in +// this method. These free-running interrupts have very low ("zero") latency, +// but they are not allowed to call any QF services, because QF is unaware +// of them ("QF-unaware" interrupts). Consequently, only interrupts with +// numerical values of priorities equal to or higher than QF_BASEPRI +// ("QF-aware" interrupts ), can call QF services. +// +// NOTE4: +// The QF_AWARE_ISR_CMSIS_PRI macro is useful as an offset for enumerating +// the "QF-aware" interrupt priorities in the applications, whereas the +// numerical values of the "QF-aware" interrupts must be greater or equal to +// QF_AWARE_ISR_CMSIS_PRI. The values based on QF_AWARE_ISR_CMSIS_PRI can be +// passed directly to the CMSIS function NVIC_SetPriority(), which shifts +// them by (8 - __NVIC_PRIO_BITS) into the correct bit position, while +// __NVIC_PRIO_BITS is the CMSIS macro defining the number of implemented +// priority bits in the NVIC. Please note that the macro QF_AWARE_ISR_CMSIS_PRI +// is intended only for applications and is not used inside the QF port, which +// remains generic and not dependent on the number of implemented priority bits +// implemented in the NVIC. +// +// NOTE5: +// The selective disabling of "QF-aware" interrupts with the BASEPRI register +// has a problem on ARM Cortex-M7 core r0p1 (see ARM-EPM-064408, errata +// 837070). The workaround recommended by ARM is to surround MSR BASEPRI with +// the CPSID i/CPSIE i pair, which is implemented in the QF_INT_DISABLE() +// macro. This workaround works also for Cortex-M3/M4 cores. + +#endif // QP_PORT_H_ + diff --git a/ports/arm-cm/qv/gnu/qs_port.h b/ports/arm-cm/qv/gnu/qs_port.h index e8b00882..92ec4663 100644 --- a/ports/arm-cm/qv/gnu/qs_port.h +++ b/ports/arm-cm/qv/gnu/qs_port.h @@ -1,60 +1,61 @@ -/*============================================================================ -* QP/C Real-Time Embedded Framework (RTEF) -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2022-06-12 -* @version Last updated for: @ref qpc_7_0_1 -* -* @file -* @brief QS/C port to a 32-bit CPU and a generic C99 compiler. -* @description -* This is an example of a QP/C port with the documentation for the -* configuration macros and includes. -*/ -#ifndef QS_PORT_H -#define QS_PORT_H +//============================================================================ +// QP/C Real-Time Embedded Framework (RTEF) +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +//============================================================================ +//! @date Last updated on: 2023-08-16 +//! @version Last updated for: @ref qpc_7_3_0 +//! +//! @file +//! @brief QS/C port to a 32-bit CPU and a generic C11 compiler. -/* QS time-stamp size in bytes */ -#define QS_TIME_SIZE 4 +#ifndef QS_PORT_H_ +#define QS_PORT_H_ -/* object pointer size in bytes */ -#define QS_OBJ_PTR_SIZE 4 +// QS time-stamp size in bytes +#define QS_TIME_SIZE 4U -/* function pointer size in bytes */ -#define QS_FUN_PTR_SIZE 4 +// object pointer size in bytes +#define QS_OBJ_PTR_SIZE 4U -/*==========================================================================*/ -/* NOTE: QS might be used with or without other QP components, in which -* case the separate definitions of the macros QF_CRIT_STAT_TYPE, -* QF_CRIT_ENTRY, and QF_CRIT_EXIT are needed. In this port QS is configured -* to be used with the other QP component, by simply including "qf_port.h" -* *before* "qs.h". -*/ -#ifndef QF_PORT_H -#include "qf_port.h" /* use QS with QF */ +// function pointer size in bytes +#define QS_FUN_PTR_SIZE 4U + +//============================================================================ +// NOTE: QS might be used with or without other QP components, in which +// case the separate definitions of the macros QF_CRIT_STAT, QF_CRIT_ENTRY(), +// and QF_CRIT_EXIT() are needed. In this port QS is configured to be used +// with the other QP component, by simply including "qp_port.h" +//*before* "qs.h". +#ifndef QP_PORT_H_ +#include "qp_port.h" // use QS with QF #endif -#include "qs.h" /* QS platform-independent public interface */ +#include "qs.h" // QS platform-independent public interface + +#endif // QS_PORT_H_ -#endif /* QS_PORT_H */ diff --git a/ports/arm-cm/qv/gnu/qv_port.c b/ports/arm-cm/qv/gnu/qv_port.c index 5300c3b1..b02ca6a9 100644 --- a/ports/arm-cm/qv/gnu/qv_port.c +++ b/ports/arm-cm/qv/gnu/qv_port.c @@ -1,104 +1,93 @@ -/*============================================================================ -* QP/C Real-Time Embedded Framework (RTEF) -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2022-12-18 -* @version Last updated for: @ref qpc_7_2_0 -* -* @file -* @brief QV/C port to ARM Cortex-M, GNU-ARM toolset -*/ -/* This QV port is part of the internal QP implementation */ -#define QP_IMPL 1U -#include "qf_port.h" +//============================================================================ +// QP/C Real-Time Embedded Framework (RTEF) +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +//============================================================================ +//! @date Last updated on: 2023-08-17 +//! @version Last updated for: @ref qpc_7_3_0 +//! +//! @file +//! @brief QV/C port to ARM Cortex-M, GNU-ARM -#define SCnSCB_ICTR ((uint32_t volatile *)0xE000E004U) -#define SCB_SYSPRI ((uint32_t volatile *)0xE000ED14U) +#define QP_IMPL 1U +#include "qp_port.h" + +#define SCB_SYSPRI ((uint32_t volatile *)0xE000ED18U) #define NVIC_IP ((uint32_t volatile *)0xE000E400U) +#define SCB_CPACR *((uint32_t volatile *)0xE000ED88U) #define FPU_FPCCR *((uint32_t volatile *)0xE000EF34U) -/*..........................................................................*/ -/* Initialize the exception priorities and IRQ priorities to safe values. -* -* Description: -* On ARMv7-M or higher, this QK port disables interrupts by means of the -* BASEPRI register. However, this method cannot disable interrupt -* priority zero, which is the default for all interrupts out of reset. -* The following code changes the SysTick priority and all IRQ priorities -* to the safe value QF_BASEPRI, which the QF critical section can disable. -* This avoids breaching of the QF critical sections in case the -* application programmer forgets to explicitly set priorities of all -* "kernel aware" interrupts. -* -* The interrupt priorities established in QV_init() can be later -* changed by the application-level code. -*/ +//............................................................................ +// Initialize the exception priorities and IRQ priorities to safe values. +// +// Description: +// On ARMv7-M or higher, this QK port disables interrupts by means of the +// BASEPRI register. However, this method cannot disable interrupt +// priority zero, which is the default for all interrupts out of reset. +// The following code changes the SysTick priority and all IRQ priorities +// to the safe value QF_BASEPRI, which the QF critical section can disable. +// This avoids breaching of the QF critical sections in case the +// application programmer forgets to explicitly set priorities of all +// "kernel aware" interrupts. +// +// The interrupt priorities established in QV_init() can be later +// changed by the application-level code. void QV_init(void) { -#if (__ARM_ARCH != 6) /*--------- if ARMv7-M and higher... */ +#if (__ARM_ARCH != 6) //--------- if ARMv7-M and higher... - /* set exception priorities to QF_BASEPRI... - * SCB_SYSPRI1: Usage-fault, Bus-fault, Memory-fault - */ - SCB_SYSPRI[1] = (SCB_SYSPRI[1] - | (QF_BASEPRI << 16U) | (QF_BASEPRI << 8U) | QF_BASEPRI); - - /* SCB_SYSPRI2: SVCall */ + // SCB_SYSPRI[2]: SysTick SCB_SYSPRI[2] = (SCB_SYSPRI[2] | (QF_BASEPRI << 24U)); - /* SCB_SYSPRI3: SysTick, PendSV, Debug */ - SCB_SYSPRI[3] = (SCB_SYSPRI[3] - | (QF_BASEPRI << 24U) | (QF_BASEPRI << 16U) | QF_BASEPRI); - - /* set all implemented IRQ priories to QF_BASEPRI... */ - uint8_t nprio = (8U + ((*SCnSCB_ICTR & 0x7U) << 3U)) * 4U; - for (uint8_t n = 0U; n < nprio; ++n) { - NVIC_IP[n] = QF_BASEPRI; + // set all 240 possible IRQ priories to QF_BASEPRI... + for (uint_fast8_t n = 0U; n < (240U/sizeof(uint32_t)); ++n) { + NVIC_IP[n] = (QF_BASEPRI << 24U) | (QF_BASEPRI << 16U) + | (QF_BASEPRI << 8U) | QF_BASEPRI; } -#endif /*--------- ARMv7-M or higher */ +#endif //--------- ARMv7-M or higher - /* SCB_SYSPRI3: PendSV set to priority 0xFF (lowest) */ - SCB_SYSPRI[3] = (SCB_SYSPRI[3] | (0xFFU << 16U)); +#ifdef __ARM_FP //--------- if VFP available... + // make sure that the FPU is enabled by seting CP10 & CP11 Full Access + SCB_CPACR = (SCB_CPACR | ((3UL << 20U) | (3UL << 22U))); -#if (__ARM_FP != 0) /*--------- if VFP available... */ - /* configure the FPU for QK */ - FPU_FPCCR |= (1U << 30U) /* automatic FPU state preservation (ASPEN) */ - | (1U << 31U); /* lazy stacking (LSPEN) */ -#endif /*--------- VFP available */ + // FPU automatic state preservation (ASPEN) lazy stacking (LSPEN) + FPU_FPCCR = (FPU_FPCCR | (1U << 30U) | (1U << 31U)); +#endif //--------- VFP available } -/*==========================================================================*/ -#if (__ARM_ARCH == 6) /* if ARMv6-M... */ +//============================================================================ +#if (__ARM_ARCH == 6) // if ARMv6-M... -/* hand-optimized quick LOG2 in assembly (no CLZ instruction in ARMv6-M) */ -/* -* NOTE: -* The inline GNU assembler does not accept mnemonics MOVS, LSRS and ADDS, -* but for ARMv6-M the mnemonics MOV, LSR and ADD always set the condition -* flags in the PSR. -*/ +// hand-optimized quick LOG2 in assembly (no CLZ instruction in ARMv6-M) +// NOTE: +// The inline GNU assembler does not accept mnemonics MOVS, LSRS and ADDS, +// but for ARMv6-M the mnemonics MOV, LSR and ADD always set the condition +// flags in the PSR. __attribute__ ((naked, optimize("-fno-stack-protector"))) uint_fast8_t QF_qlog2(uint32_t x) { __asm volatile ( @@ -132,5 +121,5 @@ __asm volatile ( ); } -#endif /* ARMv6-M */ +#endif // ARMv6-M diff --git a/ports/arm-cm/qv/gnu/qv_port.h b/ports/arm-cm/qv/gnu/qv_port.h deleted file mode 100644 index fb989564..00000000 --- a/ports/arm-cm/qv/gnu/qv_port.h +++ /dev/null @@ -1,79 +0,0 @@ -/*============================================================================ -* QP/C Real-Time Embedded Framework (RTEF) -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2022-12-18 -* @version Last updated for: @ref qpc_7_2_0 -* -* @file -* @brief QV/C port to ARM Cortex-M, GNU-ARM toolset -*/ -#ifndef QV_PORT_H -#define QV_PORT_H - -#if (__ARM_ARCH == 6) /* ARMv6-M? */ - - /* macro to put the CPU to sleep inside QV_onIdle() */ - #define QV_CPU_SLEEP() do { \ - __asm volatile ("wfi"); \ - QF_INT_ENABLE(); \ - } while (false) - - #define QV_ARM_ERRATUM_838869() ((void)0) - -#else /* ARMv7-M or higher */ - - /* macro to put the CPU to sleep inside QV_onIdle() */ - #define QV_CPU_SLEEP() do { \ - QF_PRIMASK_DISABLE(); \ - QF_INT_ENABLE(); \ - __asm volatile ("wfi"); \ - QF_PRIMASK_ENABLE(); \ - } while (false) - - /* The following macro implements the recommended workaround for the - * ARM Erratum 838869. Specifically, for Cortex-M3/M4/M7 the DSB - * (memory barrier) instruction needs to be added before exiting an ISR. - * This macro should be inserted at the end of ISRs. - */ - #define QV_ARM_ERRATUM_838869() \ - __asm volatile ("dsb 0xf" ::: "memory") - -#endif - -/* initialization of the QV kernel */ -#define QV_INIT() QV_init() -void QV_init(void); - -#if (__ARM_FP != 0) /* if VFP available... */ -/* When the FPU is configured, clear the FPCA bit in the CONTROL register -* to prevent wasting the stack space for the FPU context. -*/ -#define QV_START() __asm volatile ("msr CONTROL,%0" :: "r" (0) : ) -#endif - -#include "qv.h" /* QV platform-independent public interface */ - -#endif /* QV_PORT_H */ - diff --git a/ports/arm-cm/qv/iar/qep_port.h b/ports/arm-cm/qv/iar/qep_port.h deleted file mode 100644 index 3c327118..00000000 --- a/ports/arm-cm/qv/iar/qep_port.h +++ /dev/null @@ -1,43 +0,0 @@ -/*============================================================================ -* QP/C Real-Time Embedded Framework (RTEF) -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2022-06-12 -* @version Last updated for: @ref qpc_7_0_1 -* -* @file -* @brief QEP/C port, generic IAR compiler -*/ -#ifndef QEP_PORT_H -#define QEP_PORT_H - -/*! no-return function specifier (IAR compiler) */ -#define Q_NORETURN __noreturn void - -#include /* Exact-width types. WG14/N843 C99 Standard */ -#include /* Boolean type. WG14/N843 C99 Standard */ - -#include "qep.h" /* QEP platform-independent public interface */ - -#endif /* QEP_PORT_H */ diff --git a/ports/arm-cm/qv/iar/qf_port.h b/ports/arm-cm/qv/iar/qf_port.h deleted file mode 100644 index 78b8d35b..00000000 --- a/ports/arm-cm/qv/iar/qf_port.h +++ /dev/null @@ -1,150 +0,0 @@ -/*============================================================================ -* QP/C Real-Time Embedded Framework (RTEF) -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2022-06-12 -* @version Last updated for: @ref qpc_7_0_1 -* -* @file -* @brief QF/C port to Cortex-M, cooperative QV kernel, IAR-ARM toolset -*/ -#ifndef QF_PORT_H -#define QF_PORT_H - -/* The maximum number of system clock tick rates */ -#define QF_MAX_TICK_RATE 2U - -/* QF interrupt disable/enable and log2()... */ -#if (__ARM_ARCH == 6) /* Cortex-M0/M0+/M1(v6-M, v6S-M)? */ - - /* The maximum number of active objects in the application, see NOTE1 */ - #define QF_MAX_ACTIVE 16U - - /* Cortex-M0/M0+/M1(v6-M, v6S-M) interrupt disabling policy, see NOTE2 */ - #define QF_INT_DISABLE() __disable_interrupt() - #define QF_INT_ENABLE() __enable_interrupt() - - /* QF critical section entry/exit (unconditional interrupt disabling) */ - /*#define QF_CRIT_STAT_TYPE not defined */ - #define QF_CRIT_ENTRY(dummy) QF_INT_DISABLE() - #define QF_CRIT_EXIT(dummy) QF_INT_ENABLE() - - /* CMSIS threshold for "QF-aware" interrupts, see NOTE2 and NOTE4 */ - #define QF_AWARE_ISR_CMSIS_PRI 0 - - /* hand-optimized LOG2 in assembly for Cortex-M0/M0+/M1(v6-M, v6S-M) */ - #define QF_LOG2(n_) QF_qlog2((uint32_t)(n_)) - -#else /* Cortex-M3/M4/M7 */ - - /* The maximum number of active objects in the application, see NOTE1 */ - #define QF_MAX_ACTIVE 32U - - /* Cortex-M3/M4/M7 alternative interrupt disabling with PRIMASK */ - #define QF_PRIMASK_DISABLE() __disable_interrupt() - #define QF_PRIMASK_ENABLE() __enable_interrupt() - - /* Cortex-M3/M4/M7 interrupt disabling policy, see NOTE3 and NOTE4 */ - #define QF_INT_DISABLE() do { \ - QF_PRIMASK_DISABLE(); \ - __set_BASEPRI(QF_BASEPRI); \ - QF_PRIMASK_ENABLE(); \ - } while (false) - #define QF_INT_ENABLE() __set_BASEPRI(0U) - - /* QF critical section entry/exit (unconditional interrupt disabling) */ - /*#define QF_CRIT_STAT_TYPE not defined */ - #define QF_CRIT_ENTRY(dummy) QF_INT_DISABLE() - #define QF_CRIT_EXIT(dummy) QF_INT_ENABLE() - - /* BASEPRI threshold for "QF-aware" interrupts, see NOTE3 */ - #define QF_BASEPRI 0x3F - - /* CMSIS threshold for "QF-aware" interrupts, see NOTE5 */ - #define QF_AWARE_ISR_CMSIS_PRI (QF_BASEPRI >> (8 - __NVIC_PRIO_BITS)) - - /* Cortex-M3/M4/M7 provide the CLZ instruction for fast LOG2 */ - #define QF_LOG2(n_) ((uint_fast8_t)(32U - __CLZ((unsigned long)(n_)))) - -#endif - -#define QF_CRIT_EXIT_NOP() __ISB() - -#include /* IAR intrinsic functions */ -#include "qep_port.h" /* QEP port */ - -#if (__ARM_ARCH == 6) /* Cortex-M0/M0+/M1(v6-M, v6S-M)? */ - /* hand-optimized quick LOG2 in assembly */ - uint_fast8_t QF_qlog2(uint32_t x); -#endif /* Cortex-M0/M0+/M1(v6-M, v6S-M) */ - -#include "qv_port.h" /* QV cooperative kernel port */ -#include "qf.h" /* QF platform-independent public interface */ - -/***************************************************************************** -* NOTE1: -* The maximum number of active objects QF_MAX_ACTIVE can be increased -* up to 64, if necessary. Here it is set to a lower level to save some RAM. -* -* NOTE2: -* On Cortex-M0/M0+/M1 (architecture v6-M, v6S-M), the interrupt disabling -* policy uses the PRIMASK register to disable interrupts globally. The -* QF_AWARE_ISR_CMSIS_PRI level is zero, meaning that all interrupts are -* "QF-aware". -* -* NOTE3: -* On Cortex-M3/M4/M7, the interrupt disable/enable policy uses the BASEPRI -* register (which is not implemented in Cortex-M0/M0+/M1) to disable -* interrupts only with priority lower than the threshold specified by the -* QF_BASEPRI macro. The interrupts with priorities above QF_BASEPRI (i.e., -* with numerical priority values lower than QF_BASEPRI) are NOT disabled in -* this method. These free-running interrupts have very low ("zero") latency, -* but they are not allowed to call any QF services, because QF is unaware -* of them ("QF-unaware" interrutps). Consequently, only interrupts with -* numerical values of priorities eqal to or higher than QF_BASEPRI -* ("QF-aware" interrupts ), can call QF services. -* -* NOTE4: -* The QF_AWARE_ISR_CMSIS_PRI macro is useful as an offset for enumerating -* the "QF-aware" interrupt priorities in the applications, whereas the -* numerical values of the "QF-aware" interrupts must be greater or equal to -* QF_AWARE_ISR_CMSIS_PRI. The values based on QF_AWARE_ISR_CMSIS_PRI can be -* passed directly to the CMSIS function NVIC_SetPriority(), which shifts -* them by (8 - __NVIC_PRIO_BITS) into the correct bit position, while -* __NVIC_PRIO_BITS is the CMSIS macro defining the number of implemented -* priority bits in the NVIC. Please note that the macro QF_AWARE_ISR_CMSIS_PRI -* is intended only for applications and is not used inside the QF port, which -* remains generic and not dependent on the number of implemented priority bits -* implemented in the NVIC. -* -* NOTE5: -* The selective disabling of "QF-aware" interrupts with the BASEPRI register -* has a problem on ARM Cortex-M7 core r0p1 (see ARM-EPM-064408, errata -* 837070). The workaround recommended by ARM is to surround MSR BASEPRI with -* the CPSID i/CPSIE i pair, which is implemented in the QF_INT_DISABLE() -* macro. This workaround works also for Cortex-M3/M4 cores. -*/ - -#endif /* QF_PORT_H */ - diff --git a/ports/arm-cm/qv/iar/qp_port.h b/ports/arm-cm/qv/iar/qp_port.h new file mode 100644 index 00000000..7fce6e7a --- /dev/null +++ b/ports/arm-cm/qv/iar/qp_port.h @@ -0,0 +1,224 @@ +//============================================================================ +// QP/C Real-Time Embedded Framework (RTEF) +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +//============================================================================ +//! @date Last updated on: 2023-09-07 +//! @version Last updated for: @ref qpc_7_3_0 +//! +//! @file +//! @brief QP/C port to ARM Cortex-M, cooperative QV kernel, IAR-ARM + +#ifndef QP_PORT_H_ +#define QP_PORT_H_ + +#include // Exact-width types. WG14/N843 C99 Standard +#include // Boolean type. WG14/N843 C99 Standard +#include // IAR intrinsic functions + +#ifdef QP_CONFIG +#include "qp_config.h" // external QP configuration +#endif + +// no-return function specifier (C11 Standard) +#define Q_NORETURN _Noreturn void + +// QF configuration for QV -- data members of the QActive class... + +// QV event-queue used for AOs +#define QACTIVE_EQUEUE_TYPE QEQueue + +// QF "thread" type used to store the MPU settings in the AO +#define QACTIVE_THREAD_TYPE void const * + +// QF interrupt disable/enable and log2()... +#if (__ARM_ARCH == 6) // ARMv6-M? + + // Cortex-M0/M0+/M1(v6-M, v6S-M) interrupt disabling policy, see NOTE2 + #define QF_INT_DISABLE() __disable_interrupt() + #define QF_INT_ENABLE() __enable_interrupt() + + // QF critical section entry/exit (save and restore interrupt status) + #define QF_CRIT_STAT unsigned long primask_; + #define QF_CRIT_ENTRY() do { \ + (primask_) = __get_PRIMASK(); \ + QF_INT_DISABLE(); \ + } while (false) + #define QF_CRIT_EXIT() __set_PRIMASK((primask_)) + + // CMSIS threshold for "QF-aware" interrupts, see NOTE2 and NOTE4 + #define QF_AWARE_ISR_CMSIS_PRI 0 + + // hand-optimized LOG2 in assembly for Cortex-M0/M0+/M1(v6-M, v6S-M) + #define QF_LOG2(n_) QF_qlog2((uint32_t)(n_)) + +#else // ARMv7-M or higher + + // ARMv7-M or higher alternative interrupt disabling with PRIMASK + #define QF_PRIMASK_DISABLE() __disable_interrupt() + #define QF_PRIMASK_ENABLE() __enable_interrupt() + + // ARMv7-M or higher interrupt disabling policy, see NOTE3 and NOTE4 + #define QF_INT_DISABLE() do { \ + QF_PRIMASK_DISABLE(); \ + __set_BASEPRI(QF_BASEPRI); \ + QF_PRIMASK_ENABLE(); \ + } while (false) + #define QF_INT_ENABLE() __set_BASEPRI(0U) + + // QF critical section entry/exit (save and restore interrupt status) + #define QF_CRIT_STAT unsigned long basepri_; + #define QF_CRIT_ENTRY() do { \ + basepri_ = __get_BASEPRI(); \ + QF_INT_DISABLE(); \ + } while (false) + #define QF_CRIT_EXIT() __set_BASEPRI((basepri_)) + + // BASEPRI threshold for "QF-aware" interrupts, see NOTE3 + #define QF_BASEPRI 0x3F + + // CMSIS threshold for "QF-aware" interrupts, see NOTE5 + #define QF_AWARE_ISR_CMSIS_PRI (QF_BASEPRI >> (8 - __NVIC_PRIO_BITS)) + + // ARMv7-M or higher provide the CLZ instruction for fast LOG2 + #define QF_LOG2(n_) ((uint_fast8_t)(32U - __CLZ((unsigned long)(n_)))) + +#endif + +#define QF_CRIT_EXIT_NOP() __asm volatile ("isb" ::: "memory") + +#if (__ARM_ARCH == 6) // ARMv6-M? + // hand-optimized quick LOG2 in assembly + uint_fast8_t QF_qlog2(uint32_t x); +#endif // ARMv7-M or higher + +// Memory isolation ---------------------------------------------------------- +#ifdef QF_MEM_ISOLATE + + // Memory isolation requires the context-switch + #define QF_ON_CONTEXT_SW 1U + + // Memory System setting + #define QF_MEM_SYS() QF_onMemSys() + + // Memory Application setting + #define QF_MEM_APP() QF_onMemApp() + + // callback functions for memory settings (provided by applications) + void QF_onMemSys(void); + void QF_onMemApp(void); + +#endif // def QF_MEM_ISOLATE + +// determination if the code executes in the ISR context +#if (__ARM_ARCH == 6) // ARMv6-M? + + // macro to put the CPU to sleep inside QV_onIdle() + #define QV_CPU_SLEEP() do { \ + __WFI(); \ + QF_MEM_APP(); \ + QF_INT_ENABLE(); \ + } while (false) + + #define QV_ARM_ERRATUM_838869() ((void)0) + +#else // ARMv7-M or higher + + // macro to put the CPU to sleep inside QV_onIdle() + #define QV_CPU_SLEEP() do { \ + QF_PRIMASK_DISABLE(); \ + QF_MEM_APP(); \ + QF_INT_ENABLE(); \ + __WFI(); \ + QF_PRIMASK_ENABLE(); \ + } while (false) + + // The following macro implements the recommended workaround for the + // ARM Erratum 838869. Specifically, for Cortex-M3/M4/M7 the DSB + // (memory barrier) instruction needs to be added before exiting an ISR. + // This macro should be inserted at the end of ISRs. + #define QV_ARM_ERRATUM_838869() __DSB() + +#endif + +// initialization of the QV kernel +#define QV_INIT() QV_init() +void QV_init(void); + +#ifdef __ARM_FP //--------- if VFP available... +// When the FPU is configured, clear the FPCA bit in the CONTROL register +// to prevent wasting the stack space for the FPU context. +#define QV_START() __set_CONTROL(0U) +#endif + +// include files ------------------------------------------------------------- +#include "qequeue.h" // QV kernel uses the native QP event queue +#include "qmpool.h" // QV kernel uses the native QP memory pool +#include "qp.h" // QP framework +#include "qv.h" // QV kernel + +//============================================================================ +// NOTE2: +// On Cortex-M0/M0+/M1 (architecture v6-M, v6S-M), the interrupt disabling +// policy uses the PRIMASK register to disable interrupts globally. The +// QF_AWARE_ISR_CMSIS_PRI level is zero, meaning that all interrupts are +// "QF-aware". +// +// NOTE3: +// On ARMv7-M or higher, the interrupt disable/enable policy uses the BASEPRI +// register (which is not implemented in Cortex-M0/M0+/M1) to disable +// interrupts only with priority lower than the threshold specified by the +// QF_BASEPRI macro. The interrupts with priorities above QF_BASEPRI (i.e., +// with numerical priority values lower than QF_BASEPRI) are NOT disabled in +// this method. These free-running interrupts have very low ("zero") latency, +// but they are not allowed to call any QF services, because QF is unaware +// of them ("QF-unaware" interrupts). Consequently, only interrupts with +// numerical values of priorities equal to or higher than QF_BASEPRI +// ("QF-aware" interrupts ), can call QF services. +// +// NOTE4: +// The QF_AWARE_ISR_CMSIS_PRI macro is useful as an offset for enumerating +// the "QF-aware" interrupt priorities in the applications, whereas the +// numerical values of the "QF-aware" interrupts must be greater or equal to +// QF_AWARE_ISR_CMSIS_PRI. The values based on QF_AWARE_ISR_CMSIS_PRI can be +// passed directly to the CMSIS function NVIC_SetPriority(), which shifts +// them by (8 - __NVIC_PRIO_BITS) into the correct bit position, while +// __NVIC_PRIO_BITS is the CMSIS macro defining the number of implemented +// priority bits in the NVIC. Please note that the macro QF_AWARE_ISR_CMSIS_PRI +// is intended only for applications and is not used inside the QF port, which +// remains generic and not dependent on the number of implemented priority bits +// implemented in the NVIC. +// +// NOTE5: +// The selective disabling of "QF-aware" interrupts with the BASEPRI register +// has a problem on ARM Cortex-M7 core r0p1 (see ARM-EPM-064408, errata +// 837070). The workaround recommended by ARM is to surround MSR BASEPRI with +// the CPSID i/CPSIE i pair, which is implemented in the QF_INT_DISABLE() +// macro. This workaround works also for Cortex-M3/M4 cores. + +#endif // QP_PORT_H_ + diff --git a/ports/arm-cm/qv/iar/qs_port.h b/ports/arm-cm/qv/iar/qs_port.h index e8b00882..92ec4663 100644 --- a/ports/arm-cm/qv/iar/qs_port.h +++ b/ports/arm-cm/qv/iar/qs_port.h @@ -1,60 +1,61 @@ -/*============================================================================ -* QP/C Real-Time Embedded Framework (RTEF) -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2022-06-12 -* @version Last updated for: @ref qpc_7_0_1 -* -* @file -* @brief QS/C port to a 32-bit CPU and a generic C99 compiler. -* @description -* This is an example of a QP/C port with the documentation for the -* configuration macros and includes. -*/ -#ifndef QS_PORT_H -#define QS_PORT_H +//============================================================================ +// QP/C Real-Time Embedded Framework (RTEF) +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +//============================================================================ +//! @date Last updated on: 2023-08-16 +//! @version Last updated for: @ref qpc_7_3_0 +//! +//! @file +//! @brief QS/C port to a 32-bit CPU and a generic C11 compiler. -/* QS time-stamp size in bytes */ -#define QS_TIME_SIZE 4 +#ifndef QS_PORT_H_ +#define QS_PORT_H_ -/* object pointer size in bytes */ -#define QS_OBJ_PTR_SIZE 4 +// QS time-stamp size in bytes +#define QS_TIME_SIZE 4U -/* function pointer size in bytes */ -#define QS_FUN_PTR_SIZE 4 +// object pointer size in bytes +#define QS_OBJ_PTR_SIZE 4U -/*==========================================================================*/ -/* NOTE: QS might be used with or without other QP components, in which -* case the separate definitions of the macros QF_CRIT_STAT_TYPE, -* QF_CRIT_ENTRY, and QF_CRIT_EXIT are needed. In this port QS is configured -* to be used with the other QP component, by simply including "qf_port.h" -* *before* "qs.h". -*/ -#ifndef QF_PORT_H -#include "qf_port.h" /* use QS with QF */ +// function pointer size in bytes +#define QS_FUN_PTR_SIZE 4U + +//============================================================================ +// NOTE: QS might be used with or without other QP components, in which +// case the separate definitions of the macros QF_CRIT_STAT, QF_CRIT_ENTRY(), +// and QF_CRIT_EXIT() are needed. In this port QS is configured to be used +// with the other QP component, by simply including "qp_port.h" +//*before* "qs.h". +#ifndef QP_PORT_H_ +#include "qp_port.h" // use QS with QF #endif -#include "qs.h" /* QS platform-independent public interface */ +#include "qs.h" // QS platform-independent public interface + +#endif // QS_PORT_H_ -#endif /* QS_PORT_H */ diff --git a/ports/arm-cm/qv/iar/qv_port.c b/ports/arm-cm/qv/iar/qv_port.c index 16f7f8c1..375614d8 100644 --- a/ports/arm-cm/qv/iar/qv_port.c +++ b/ports/arm-cm/qv/iar/qv_port.c @@ -1,98 +1,89 @@ -/*============================================================================ -* QP/C Real-Time Embedded Framework (RTEF) -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2022-12-18 -* @version Last updated for: @ref qpc_7_2_0 -* -* @file -* @brief QV/C port to ARM Cortex-M, IAR-ARM toolset -*/ -/* This QV port is part of the internal QP implementation */ -#define QP_IMPL 1U -#include "qf_port.h" +//============================================================================ +// QP/C Real-Time Embedded Framework (RTEF) +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +//============================================================================ +//! @date Last updated on: 2023-08-17 +//! @version Last updated for: @ref qpc_7_3_0 +//! +//! @file +//! @brief QV/C port to ARM Cortex-M, IAR-ARM -#define SCnSCB_ICTR ((uint32_t volatile *)0xE000E004U) -#define SCB_SYSPRI ((uint32_t volatile *)0xE000ED14U) +#define QP_IMPL 1U +#include "qp_port.h" + +#define SCB_SYSPRI ((uint32_t volatile *)0xE000ED18U) #define NVIC_IP ((uint32_t volatile *)0xE000E400U) +#define SCB_CPACR *((uint32_t volatile *)0xE000ED88U) #define FPU_FPCCR *((uint32_t volatile *)0xE000EF34U) -/*..........................................................................*/ -/* Initialize the exception priorities and IRQ priorities to safe values. -* -* Description: -* On ARMv7-M or higher, this QK port disables interrupts by means of the -* BASEPRI register. However, this method cannot disable interrupt -* priority zero, which is the default for all interrupts out of reset. -* The following code changes the SysTick priority and all IRQ priorities -* to the safe value QF_BASEPRI, which the QF critical section can disable. -* This avoids breaching of the QF critical sections in case the -* application programmer forgets to explicitly set priorities of all -* "kernel aware" interrupts. -* -* The interrupt priorities established in QV_init() can be later -* changed by the application-level code. -*/ +//.......................................................................... +// Initialize the exception priorities and IRQ priorities to safe values. +// +// Description: +// On ARMv7-M or higher, this QK port disables interrupts by means of the +// BASEPRI register. However, this method cannot disable interrupt +// priority zero, which is the default for all interrupts out of reset. +// The following code changes the SysTick priority and all IRQ priorities +// to the safe value QF_BASEPRI, which the QF critical section can disable. +// This avoids breaching of the QF critical sections in case the +// application programmer forgets to explicitly set priorities of all +// "kernel aware" interrupts. +// +// The interrupt priorities established in QV_init() can be later +// changed by the application-level code. void QV_init(void) { -#if (__ARM_ARCH != 6) /*--------- if ARMv7-M and higher... */ +#if (__ARM_ARCH != 6) //--------- if ARMv7-M and higher... - /* set exception priorities to QF_BASEPRI... - * SCB_SYSPRI1: Usage-fault, Bus-fault, Memory-fault - */ - SCB_SYSPRI[1] = (SCB_SYSPRI[1] - | (QF_BASEPRI << 16U) | (QF_BASEPRI << 8U) | QF_BASEPRI); - - /* SCB_SYSPRI2: SVCall */ + // SCB_SYSPRI[2]: SysTick SCB_SYSPRI[2] = (SCB_SYSPRI[2] | (QF_BASEPRI << 24U)); - /* SCB_SYSPRI3: SysTick, PendSV, Debug */ - SCB_SYSPRI[3] = (SCB_SYSPRI[3] - | (QF_BASEPRI << 24U) | (QF_BASEPRI << 16U) | QF_BASEPRI); - - /* set all implemented IRQ priories to QF_BASEPRI... */ - uint8_t nprio = (8U + ((*SCnSCB_ICTR & 0x7U) << 3U)) * 4U; - for (uint8_t n = 0U; n < nprio; ++n) { - NVIC_IP[n] = QF_BASEPRI; + // set all 240 possible IRQ priories to QF_BASEPRI... + for (uint_fast8_t n = 0U; n < (240U/sizeof(uint32_t)); ++n) { + NVIC_IP[n] = (QF_BASEPRI << 24U) | (QF_BASEPRI << 16U) + | (QF_BASEPRI << 8U) | QF_BASEPRI; } -#endif /*--------- ARMv7-M or higher */ +#endif //--------- ARMv7-M or higher - /* SCB_SYSPRI3: PendSV set to priority 0xFF (lowest) */ - SCB_SYSPRI[3] = (SCB_SYSPRI[3] | (0xFFU << 16U)); +#ifdef __ARM_FP //--------- if VFP available... + // make sure that the FPU is enabled by seting CP10 & CP11 Full Access + SCB_CPACR = (SCB_CPACR | ((3UL << 20U) | (3UL << 22U))); -#if (__ARM_FP != 0) /*--------- if VFP available... */ - /* configure the FPU for QK */ - FPU_FPCCR |= (1U << 30U) /* automatic FPU state preservation (ASPEN) */ - | (1U << 31U); /* lazy stacking (LSPEN) */ -#endif /*--------- VFP available */ + // FPU automatic state preservation (ASPEN) lazy stacking (LSPEN) + FPU_FPCCR = (FPU_FPCCR | (1U << 30U) | (1U << 31U)); +#endif //--------- VFP available } -/*==========================================================================*/ -#if (__ARM_ARCH == 6) /* if ARMv6-M... */ +//============================================================================ +#if (__ARM_ARCH == 6) // if ARMv6-M... -/* hand-optimized quick LOG2 in assembly (no CLZ instruction in ARMv6-M) */ +// hand-optimized quick LOG2 in assembly (no CLZ instruction in ARMv6-M) uint_fast8_t QF_qlog2(uint32_t x) { static uint8_t const log2LUT[16] = { 0U, 1U, 2U, 2U, 3U, 3U, 3U, 3U, @@ -125,5 +116,5 @@ __asm volatile ( return n + log2LUT[x]; } -#endif /* ARMv6-M */ +#endif // ARMv6-M diff --git a/ports/arm-cm/qv/iar/qv_port.h b/ports/arm-cm/qv/iar/qv_port.h deleted file mode 100644 index ddd28754..00000000 --- a/ports/arm-cm/qv/iar/qv_port.h +++ /dev/null @@ -1,78 +0,0 @@ -/*============================================================================ -* QP/C Real-Time Embedded Framework (RTEF) -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2022-12-18 -* @version Last updated for: @ref qpc_7_2_0 -* -* @file -* @brief QV/C port to ARM Cortex-M, IAR-ARM toolset -*/ -#ifndef QV_PORT_H -#define QV_PORT_H - -#if (__ARM_ARCH == 6) /* ARMv6-M? */ - - /* macro to put the CPU to sleep inside QV_onIdle() */ - #define QV_CPU_SLEEP() do { \ - __WFI(); \ - QF_INT_ENABLE(); \ - } while (false) - - #define QV_ARM_ERRATUM_838869() ((void)0) - -#else /* ARMv7-M or higher */ - - /* macro to put the CPU to sleep inside QV_onIdle() */ - #define QV_CPU_SLEEP() do { \ - QF_PRIMASK_DISABLE(); \ - QF_INT_ENABLE(); \ - __WFI(); \ - QF_PRIMASK_ENABLE(); \ - } while (false) - - /* The following macro implements the recommended workaround for the - * ARM Erratum 838869. Specifically, for Cortex-M3/M4/M7 the DSB - * (memory barrier) instruction needs to be added before exiting an ISR. - * This macro should be inserted at the end of ISRs. - */ - #define QV_ARM_ERRATUM_838869() __DSB() - -#endif - -/* initialization of the QV kernel */ -#define QV_INIT() QV_init() -void QV_init(void); - -#if (__ARM_FP != 0) /* if VFP available... */ -/* When the FPU is configured, clear the FPCA bit in the CONTROL register -* to prevent wasting the stack space for the FPU context. -*/ -#define QV_START() __set_CONTROL(0U) -#endif - -#include "qv.h" /* QV platform-independent public interface */ - -#endif /* QV_PORT_H */ - diff --git a/ports/arm-cm/qxk/armclang/qep_port.h b/ports/arm-cm/qxk/armclang/qep_port.h deleted file mode 100644 index c1eb162f..00000000 --- a/ports/arm-cm/qxk/armclang/qep_port.h +++ /dev/null @@ -1,44 +0,0 @@ -/*============================================================================ -* QP/C Real-Time Embedded Framework (RTEF) -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2022-04-09 -* @version Last updated for: @ref qpc_7_0_0 -* -* @file -* @brief QEP/C port, ARM-Clang/LLVM compiler -*/ -#ifndef QEP_PORT_H -#define QEP_PORT_H - -/*! no-return function specifier (ARM-Clang/LLVM compiler) */ -#define Q_NORETURN __attribute__ ((noreturn)) void - -#include /* Exact-width types. WG14/N843 C99 Standard */ -#include /* Boolean type. WG14/N843 C99 Standard */ - -#include "qep.h" /* QEP platform-independent public interface */ - -#endif /* QEP_PORT_H */ - diff --git a/ports/arm-cm/qxk/armclang/qf_port.h b/ports/arm-cm/qxk/armclang/qf_port.h deleted file mode 100644 index ca494b21..00000000 --- a/ports/arm-cm/qxk/armclang/qf_port.h +++ /dev/null @@ -1,153 +0,0 @@ -/*============================================================================ -* QP/C Real-Time Embedded Framework (RTEF) -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2022-06-30 -* @version Last updated for: @ref qpc_7_0_1 -* -* @file -* @brief QF/C port to Cortex-M, dual-mode QXK kernel, ARM-CLANG toolset -*/ -#ifndef QF_PORT_H -#define QF_PORT_H - -/* The maximum number of system clock tick rates */ -#define QF_MAX_TICK_RATE 2U - -/* QF interrupt disable/enable and log2()... */ -#if (__ARM_ARCH == 6) /* Cortex-M0/M0+/M1(v6-M, v6S-M)? */ - - /* The maximum number of active objects in the application, see NOTE1 */ - #define QF_MAX_ACTIVE 16U - - /* Cortex-M0/M0+/M1(v6-M, v6S-M) interrupt disabling policy, see NOTE2 */ - #define QF_INT_DISABLE() __asm volatile ("cpsid i") - #define QF_INT_ENABLE() __asm volatile ("cpsie i") - - /* QF critical section (save and restore interrupt status), see NOTE2 */ - #define QF_CRIT_STAT_TYPE uint32_t - #define QF_CRIT_ENTRY(primask_) \ - __asm volatile ("mrs %0,PRIMASK\n" "cpsid i" : "=r" (primask_) ::) - #define QF_CRIT_EXIT(primask_) \ - __asm volatile ("msr PRIMASK,%0" :: "r" (primask_) : ) - - /* CMSIS threshold for "QF-aware" interrupts, see NOTE2 and NOTE4 */ - #define QF_AWARE_ISR_CMSIS_PRI 0 - - /* hand-optimized LOG2 in assembly for Cortex-M0/M0+/M1(v6-M, v6S-M) */ - #define QF_LOG2(n_) QF_qlog2((uint32_t)(n_)) - -#else /* Cortex-M3/M4/M7 */ - - /* The maximum number of active objects in the application, see NOTE1 */ - #define QF_MAX_ACTIVE 32U - - /* Cortex-M3/M4/M7 alternative interrupt disabling with PRIMASK */ - #define QF_PRIMASK_DISABLE() __asm volatile ("cpsid i") - #define QF_PRIMASK_ENABLE() __asm volatile ("cpsie i") - - /* Cortex-M3/M4/M7 interrupt disabling policy, see NOTE3 and NOTE4 */ - #define QF_INT_DISABLE() __asm volatile (\ - "cpsid i\n" "msr BASEPRI,%0\n" "cpsie i" :: "r" (QF_BASEPRI) : ) - #define QF_INT_ENABLE() __asm volatile (\ - "msr BASEPRI,%0" :: "r" (0) : ) - - /* QF critical section (save and restore interrupt status), see NOTE5 */ - #define QF_CRIT_STAT_TYPE uint32_t - #define QF_CRIT_ENTRY(basepri_) do { \ - __asm volatile ("mrs %0,BASEPRI" : "=r" (basepri_) :: ); \ - __asm volatile ("cpsid i\n msr BASEPRI,%0\n cpsie i" \ - :: "r" (QF_BASEPRI) : ); \ - } while (false) - #define QF_CRIT_EXIT(basepri_) \ - __asm volatile ("msr BASEPRI,%0" :: "r" (basepri_) : ) - - /* BASEPRI threshold for "QF-aware" interrupts, see NOTE3 */ - #define QF_BASEPRI 0x3F - - /* CMSIS threshold for "QF-aware" interrupts, see NOTE5 */ - #define QF_AWARE_ISR_CMSIS_PRI (QF_BASEPRI >> (8 - __NVIC_PRIO_BITS)) - - /* Cortex-M3/M4/M7 provide the CLZ instruction for fast LOG2 */ - #define QF_LOG2(n_) ((uint_fast8_t)(32 - __builtin_clz((unsigned)(n_)))) - -#endif - -#define QF_CRIT_EXIT_NOP() __asm volatile ("isb") - -#include "qep_port.h" /* QEP port */ - -#if (__ARM_ARCH == 6) /* Cortex-M0/M0+/M1(v6-M, v6S-M)? */ - /* hand-optimized quick LOG2 in assembly */ - uint_fast8_t QF_qlog2(uint32_t x); -#endif /* Cortex-M0/M0+/M1(v6-M, v6S-M) */ - -#include "qxk_port.h" /* QXK dual-mode kernel port */ - -/***************************************************************************** -* NOTE1: -* The maximum number of active objects QF_MAX_ACTIVE can be increased -* up to 64U, if necessary. Here it is set to a lower level to save some RAM. -* -* NOTE2: -* On Cortex-M0/M0+/M1 (architecture v6-M, v6S-M), the interrupt disabling -* policy uses the PRIMASK register to disable interrupts globally. The -* QF_AWARE_ISR_CMSIS_PRI level is zero, meaning that all interrupts are -* "QF-aware". -* -* NOTE3: -* On Cortex-M3/M4/M7, the interrupt disable/enable policy uses the BASEPRI -* register (which is not implemented in Cortex-M0/M0+/M1) to disable -* interrupts only with priority lower than the threshold specified by the -* QF_BASEPRI macro. The interrupts with priorities above QF_BASEPRI (i.e., -* with numerical priority values lower than QF_BASEPRI) are NOT disabled in -* this method. These free-running interrupts have very low ("zero") latency, -* but they are not allowed to call any QF services, because QF is unaware -* of them ("QF-unaware" interrutps). Consequently, only interrupts with -* numerical values of priorities eqal to or higher than QF_BASEPRI -* ("QF-aware" interrupts ), can call QF services. -* -* NOTE4: -* The QF_AWARE_ISR_CMSIS_PRI macro is useful as an offset for enumerating -* the "QF-aware" interrupt priorities in the applications, whereas the -* numerical values of the "QF-aware" interrupts must be greater or equal to -* QF_AWARE_ISR_CMSIS_PRI. The values based on QF_AWARE_ISR_CMSIS_PRI can be -* passed directly to the CMSIS function NVIC_SetPriority(), which shifts -* them by (8 - __NVIC_PRIO_BITS) into the correct bit position, while -* __NVIC_PRIO_BITS is the CMSIS macro defining the number of implemented -* priority bits in the NVIC. Please note that the macro QF_AWARE_ISR_CMSIS_PRI -* is intended only for applications and is not used inside the QF port, which -* remains generic and not dependent on the number of implemented priority bits -* implemented in the NVIC. -* -* NOTE5: -* The selective disabling of "QF-aware" interrupts with the BASEPRI register -* has a problem on ARM Cortex-M7 core r0p1 (see ARM-EPM-064408, errata -* 837070). The workaround recommended by ARM is to surround MSR BASEPRI with -* the CPSID i/CPSIE i pair, which is implemented in the QF_INT_DISABLE() -* macro. This workaround works also for Cortex-M3/M4 cores. -*/ - -#endif /* QF_PORT_H */ - diff --git a/ports/arm-cm/qxk/armclang/qp_port.h b/ports/arm-cm/qxk/armclang/qp_port.h new file mode 100644 index 00000000..3e0f5f6e --- /dev/null +++ b/ports/arm-cm/qxk/armclang/qp_port.h @@ -0,0 +1,247 @@ +//============================================================================ +// QP/C Real-Time Embedded Framework (RTEF) +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC . +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +//============================================================================ +//! @date Last updated on: 2023-09-07 +//! @version Last updated for: @ref qpc_7_3_0 +//! +//! @file +//! @brief QP/C port to ARM Cortex-M, dual-mode QXK kernel, ARM-CLANG + +#ifndef QP_PORT_H_ +#define QP_PORT_H_ + +#include // Exact-width types. WG14/N843 C99 Standard +#include // Boolean type. WG14/N843 C99 Standard + +#ifdef QP_CONFIG +#include "qp_config.h" // external QP configuration +#endif + +// no-return function specifier (C11 Standard) +#define Q_NORETURN _Noreturn void + +// QF configuration for QXK -- data members of the QActive class... + +// QXK event-queue type used for AOs and eXtended threads. +#define QACTIVE_EQUEUE_TYPE QEQueue + +// QXK OS-Object type used for the private stack pointer for eXtended threads. +// (The private stack pointer is NULL for basic-threads). +#define QACTIVE_OS_OBJ_TYPE void* + +// QF "thread" type used to store the MPU settings in the AO +#define QACTIVE_THREAD_TYPE void const * + +// QF interrupt disable/enable and log2()... +#if (__ARM_ARCH == 6) // ARMv6-M? + + // Cortex-M0/M0+/M1(v6-M, v6S-M) interrupt disabling policy, see NOTE2 + #define QF_INT_DISABLE() __asm volatile ("cpsid i" ::: "memory") + #define QF_INT_ENABLE() __asm volatile ("cpsie i" ::: "memory") + + // QF critical section (save and restore interrupt status), see NOTE2 + #define QF_CRIT_STAT uint32_t primask_; + #define QF_CRIT_ENTRY() __asm volatile (\ + "mrs %0,PRIMASK\n" "cpsid i" : "=r" (primask_) :: "memory") + #define QF_CRIT_EXIT() __asm volatile (\ + "msr PRIMASK,%0" :: "r" (primask_) : "memory") + + // CMSIS threshold for "QF-aware" interrupts, see NOTE2 and NOTE4 + #define QF_AWARE_ISR_CMSIS_PRI 0 + + // hand-optimized LOG2 in assembly for Cortex-M0/M0+/M1(v6-M, v6S-M) + #define QF_LOG2(n_) QF_qlog2((uint32_t)(n_)) + +#else // ARMv7-M or higher + + // ARMv7-M or higher alternative interrupt disabling with PRIMASK + #define QF_PRIMASK_DISABLE() __asm volatile ("cpsid i" ::: "memory") + #define QF_PRIMASK_ENABLE() __asm volatile ("cpsie i" ::: "memory") + + // ARMv7-M or higher interrupt disabling policy, see NOTE3 and NOTE4 + #define QF_INT_DISABLE() __asm volatile (\ + "cpsid i\n" "msr BASEPRI,%0\n" "cpsie i" \ + :: "r" (QF_BASEPRI) : "memory") + #define QF_INT_ENABLE() __asm volatile (\ + "msr BASEPRI,%0" :: "r" (0) : "memory") + + // QF critical section (save and restore interrupt status), see NOTE5 + #define QF_CRIT_STAT uint32_t basepri_; + #define QF_CRIT_ENTRY() do { \ + __asm volatile ("mrs %0,BASEPRI" : "=r" (basepri_) :: "memory"); \ + __asm volatile ("cpsid i\n msr BASEPRI,%0\n cpsie i" \ + :: "r" (QF_BASEPRI) : "memory"); \ + } while (false) + #define QF_CRIT_EXIT() \ + __asm volatile ("msr BASEPRI,%0" :: "r" (basepri_) : "memory") + + // BASEPRI threshold for "QF-aware" interrupts, see NOTE3 + #define QF_BASEPRI 0x3F + + // CMSIS threshold for "QF-aware" interrupts, see NOTE5 + #define QF_AWARE_ISR_CMSIS_PRI (QF_BASEPRI >> (8 - __NVIC_PRIO_BITS)) + + // ARMv7-M or higher provide the CLZ instruction for fast LOG2 + #define QF_LOG2(n_) ((uint_fast8_t)(32 - __builtin_clz((unsigned)(n_)))) + +#endif + +#define QF_CRIT_EXIT_NOP() __asm volatile ("isb" ::: "memory") + +#if (__ARM_ARCH == 6) // ARMv6-M? + // hand-optimized quick LOG2 in assembly + uint_fast8_t QF_qlog2(uint32_t x); +#endif // ARMv7-M or higher + +// Memory isolation ---------------------------------------------------------- +#ifdef QF_MEM_ISOLATE + + // Memory isolation requires the context-switch + #define QF_ON_CONTEXT_SW 1U + + // Memory System setting + #define QF_MEM_SYS() QF_onMemSys() + + // Memory Application setting + #define QF_MEM_APP() QF_onMemApp() + + // callback functions for memory settings (provided by applications) + void QF_onMemSys(void); + void QF_onMemApp(void); + +#endif // def QF_MEM_ISOLATE + +// determination if the code executes in the ISR context +#define QXK_ISR_CONTEXT_() (QXK_get_IPSR() != 0U) + +__attribute__((always_inline)) +static inline uint32_t QXK_get_IPSR(void) { + uint32_t regIPSR; + __asm volatile ("mrs %0,ipsr" : "=r" (regIPSR)); + return regIPSR; +} + +// trigger the PendSV exception to perform the context switch +#define QXK_CONTEXT_SWITCH_() \ + *Q_UINT2PTR_CAST(uint32_t, 0xE000ED04U) = (1U << 28U) + +// QXK ISR entry and exit +#define QXK_ISR_ENTRY() ((void)0) + +#ifdef QF_MEM_ISOLATE + #define QXK_ISR_EXIT() do { \ + QF_INT_DISABLE(); \ + QF_MEM_SYS(); \ + if (QXK_sched_() != 0U) { \ + *Q_UINT2PTR_CAST(uint32_t, 0xE000ED04U) = (1U << 28U);\ + } \ + QF_MEM_APP(); \ + QF_INT_ENABLE(); \ + QXK_ARM_ERRATUM_838869(); \ + } while (false) +#else + #define QXK_ISR_EXIT() do { \ + QF_INT_DISABLE(); \ + if (QXK_sched_() != 0U) { \ + *Q_UINT2PTR_CAST(uint32_t, 0xE000ED04U) = (1U << 28U);\ + } \ + QF_INT_ENABLE(); \ + QXK_ARM_ERRATUM_838869(); \ + } while (false) +#endif + +#if (__ARM_ARCH == 6) // ARMv6-M? + #define QXK_ARM_ERRATUM_838869() ((void)0) +#else // ARMv7-M or higher + // The following macro implements the recommended workaround for the + // ARM Erratum 838869. Specifically, for Cortex-M3/M4/M7 the DSB + // (memory barrier) instruction needs to be added before exiting an ISR. + #define QXK_ARM_ERRATUM_838869() \ + __asm volatile ("dsb" ::: "memory") + +#endif // ARMv6-M + +// initialization of the QXK kernel +#define QXK_INIT() QXK_init() +void QXK_init(void); +void QXK_thread_ret(void); + +#ifdef __ARM_FP //--------- if VFP available... +// When the FPU is configured, clear the FPCA bit in the CONTROL register +// to prevent wasting the stack space for the FPU context. +#define QXK_START() __asm volatile ("msr CONTROL,%0" :: "r" (0) : ) +#endif + +// include files ------------------------------------------------------------- +#include "qequeue.h" // QXK kernel uses the native QP event queue +#include "qmpool.h" // QXK kernel uses the native QP memory pool +#include "qp.h" // QP framework +#include "qxk.h" // QXK kernel + +//============================================================================ +// NOTE2: +// On Cortex-M0/M0+/M1 (architecture v6-M, v6S-M), the interrupt disabling +// policy uses the PRIMASK register to disable interrupts globally. The +// QF_AWARE_ISR_CMSIS_PRI level is zero, meaning that all interrupts are +// "QF-aware". +// +// NOTE3: +// On ARMv7-M or higher, the interrupt disable/enable policy uses the BASEPRI +// register (which is not implemented in Cortex-M0/M0+/M1) to disable +// interrupts only with priority lower than the threshold specified by the +// QF_BASEPRI macro. The interrupts with priorities above QF_BASEPRI (i.e., +// with numerical priority values lower than QF_BASEPRI) are NOT disabled in +// this method. These free-running interrupts have very low ("zero") latency, +// but they are not allowed to call any QF services, because QF is unaware +// of them ("QF-unaware" interrupts). Consequently, only interrupts with +// numerical values of priorities equal to or higher than QF_BASEPRI +// ("QF-aware" interrupts ), can call QF services. +// +// NOTE4: +// The QF_AWARE_ISR_CMSIS_PRI macro is useful as an offset for enumerating +// the "QF-aware" interrupt priorities in the applications, whereas the +// numerical values of the "QF-aware" interrupts must be greater or equal to +// QF_AWARE_ISR_CMSIS_PRI. The values based on QF_AWARE_ISR_CMSIS_PRI can be +// passed directly to the CMSIS function NVIC_SetPriority(), which shifts +// them by (8 - __NVIC_PRIO_BITS) into the correct bit position, while +// __NVIC_PRIO_BITS is the CMSIS macro defining the number of implemented +// priority bits in the NVIC. Please note that the macro QF_AWARE_ISR_CMSIS_PRI +// is intended only for applications and is not used inside the QF port, which +// remains generic and not dependent on the number of implemented priority bits +// implemented in the NVIC. +// +// NOTE5: +// The selective disabling of "QF-aware" interrupts with the BASEPRI register +// has a problem on ARM Cortex-M7 core r0p1 (see ARM-EPM-064408, errata +// 837070). The workaround recommended by ARM is to surround MSR BASEPRI with +// the CPSID i/CPSIE i pair, which is implemented in the QF_INT_DISABLE() +// macro. This workaround works also for Cortex-M3/M4 cores. + +#endif // QP_PORT_H_ + diff --git a/ports/arm-cm/qxk/armclang/qs_port.h b/ports/arm-cm/qxk/armclang/qs_port.h index e8b00882..92ec4663 100644 --- a/ports/arm-cm/qxk/armclang/qs_port.h +++ b/ports/arm-cm/qxk/armclang/qs_port.h @@ -1,60 +1,61 @@ -/*============================================================================ -* QP/C Real-Time Embedded Framework (RTEF) -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2022-06-12 -* @version Last updated for: @ref qpc_7_0_1 -* -* @file -* @brief QS/C port to a 32-bit CPU and a generic C99 compiler. -* @description -* This is an example of a QP/C port with the documentation for the -* configuration macros and includes. -*/ -#ifndef QS_PORT_H -#define QS_PORT_H +//============================================================================ +// QP/C Real-Time Embedded Framework (RTEF) +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +//============================================================================ +//! @date Last updated on: 2023-08-16 +//! @version Last updated for: @ref qpc_7_3_0 +//! +//! @file +//! @brief QS/C port to a 32-bit CPU and a generic C11 compiler. -/* QS time-stamp size in bytes */ -#define QS_TIME_SIZE 4 +#ifndef QS_PORT_H_ +#define QS_PORT_H_ -/* object pointer size in bytes */ -#define QS_OBJ_PTR_SIZE 4 +// QS time-stamp size in bytes +#define QS_TIME_SIZE 4U -/* function pointer size in bytes */ -#define QS_FUN_PTR_SIZE 4 +// object pointer size in bytes +#define QS_OBJ_PTR_SIZE 4U -/*==========================================================================*/ -/* NOTE: QS might be used with or without other QP components, in which -* case the separate definitions of the macros QF_CRIT_STAT_TYPE, -* QF_CRIT_ENTRY, and QF_CRIT_EXIT are needed. In this port QS is configured -* to be used with the other QP component, by simply including "qf_port.h" -* *before* "qs.h". -*/ -#ifndef QF_PORT_H -#include "qf_port.h" /* use QS with QF */ +// function pointer size in bytes +#define QS_FUN_PTR_SIZE 4U + +//============================================================================ +// NOTE: QS might be used with or without other QP components, in which +// case the separate definitions of the macros QF_CRIT_STAT, QF_CRIT_ENTRY(), +// and QF_CRIT_EXIT() are needed. In this port QS is configured to be used +// with the other QP component, by simply including "qp_port.h" +//*before* "qs.h". +#ifndef QP_PORT_H_ +#include "qp_port.h" // use QS with QF #endif -#include "qs.h" /* QS platform-independent public interface */ +#include "qs.h" // QS platform-independent public interface + +#endif // QS_PORT_H_ -#endif /* QS_PORT_H */ diff --git a/ports/arm-cm/qxk/armclang/qxk_port.c b/ports/arm-cm/qxk/armclang/qxk_port.c index e17e1316..65df6cf7 100644 --- a/ports/arm-cm/qxk/armclang/qxk_port.c +++ b/ports/arm-cm/qxk/armclang/qxk_port.c @@ -1,605 +1,608 @@ -/*============================================================================ -* QP/C Real-Time Embedded Framework (RTEF) -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2023-01-14 -* @version Last updated for: @ref qpc_7_2_1 -* -* @file -* @brief QXK/C port to ARM Cortex-M, ARM-CLANG toolset -*/ -/* This QXK port is part of the internal QP implementation */ +//============================================================================ +// QP/C Real-Time Embedded Framework (RTEF) +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +//============================================================================ +//! @date Last updated on: 2023-08-16 +//! @version Last updated for: @ref qpc_7_3_0 +//! +//! @file +//! @brief QXK/C port to ARM Cortex-M, ARM-CLANG + #define QP_IMPL 1U -#include "qf_port.h" -#include "qf_pkg.h" -#include "qassert.h" +#include "qp_port.h" +#include "qp_pkg.h" +#include "qsafe.h" // QP Functional Safety (FuSa) System -#include /* for offsetof() */ +#include // for offsetof() -/* prototypes --------------------------------------------------------------*/ -void PendSV_Handler(void); -#ifdef QXK_USE_IRQ_HANDLER /* if use IRQ... */ -void QXK_USE_IRQ_HANDLER(void); -#else /* use default (NMI) */ -void NMI_Handler(void); -#endif +//============================================================================ +// NOTE: keep in synch with struct QXK_Attr in "qxk.h" !!! +#define QXK_CURR 0 +#define QXK_NEXT 4 +#define QXK_ACT_PRIO 12 -#define SCnSCB_ICTR ((uint32_t volatile *)0xE000E004U) -#define SCB_SYSPRI ((uint32_t volatile *)0xE000ED14U) -#define NVIC_EN ((uint32_t volatile *)0xE000E100U) -#define NVIC_IP ((uint8_t volatile *)0xE000E400U) -#define FPU_FPCCR *((uint32_t volatile *)0xE000EF34U) -#define NVIC_PEND 0xE000E200 -#define NVIC_ICSR 0xE000ED04 +// make sure that the offsets match the QXK declaration in "qxk.h" +_Static_assert(QXK_CURR == offsetof(QXK_Attr, curr), + "QXK_Attr.curr at unexpected offset"); +_Static_assert(QXK_NEXT == offsetof(QXK_Attr, next), + "QXK_Attr.next at unexpected offset"); +_Static_assert(QXK_ACT_PRIO == offsetof(QXK_Attr, actPrio), + "QXK_Attr.actPrio at unexpected offset"); -/*..........................................................................*/ -/* Initialize the exception priorities and IRQ priorities to safe values. -* -* Description: -* On ARMv7-M or higher, this QXK port disables interrupts by means of the -* BASEPRI register. However, this method cannot disable interrupt -* priority zero, which is the default for all interrupts out of reset. -* The following code changes the SysTick priority and all IRQ priorities -* to the safe value QF_BASEPRI, which the QF critical section can disable. -* This avoids breaching of the QF critical sections in case the -* application programmer forgets to explicitly set priorities of all -* "kernel aware" interrupts. -* -* The interrupt priorities established in QXK_init() can be later -* changed by the application-level code. -*/ -void QXK_init(void) { +// offsets within struct QActive; NOTE: keep in synch with "qp.h" !!! +#define QACTIVE_OSOBJ 28 +#define QACTIVE_PRIO 36 -#if (__ARM_ARCH != 6) /*--------- if ARMv7-M and higher... */ +// make sure that the offsets match the QActvie declaration in "qp.h" +_Static_assert(QACTIVE_OSOBJ == offsetof(QActive, osObject), + "QActive.osObject at unexpected offset"); +_Static_assert(QACTIVE_PRIO == offsetof(QActive, prio), + "QActive.prio at unexpected offset"); - /* set exception priorities to QF_BASEPRI... - * SCB_SYSPRI1: Usage-fault, Bus-fault, Memory-fault - */ - SCB_SYSPRI[1] = (SCB_SYSPRI[1] - | (QF_BASEPRI << 16U) | (QF_BASEPRI << 8U) | QF_BASEPRI); +// helper macros to "stringify" values +#define VAL(x) #x +#define STRINGIFY(x) VAL(x) - /* SCB_SYSPRI2: SVCall */ - SCB_SYSPRI[2] = (SCB_SYSPRI[2] | (QF_BASEPRI << 24U)); - - /* SCB_SYSPRI3: SysTick, PendSV, Debug */ - SCB_SYSPRI[3] = (SCB_SYSPRI[3] - | (QF_BASEPRI << 24U) | (QF_BASEPRI << 16U) | QF_BASEPRI); - - /* set all implemented IRQ priories to QF_BASEPRI... */ - uint8_t nprio = (8U + ((*SCnSCB_ICTR & 0x7U) << 3U)) * 4U; - for (uint8_t n = 0U; n < nprio; ++n) { - NVIC_IP[n] = QF_BASEPRI; - } - -#endif /*--------- ARMv7-M or higher */ - - /* SCB_SYSPRI3: PendSV set to priority 0xFF (lowest) */ - SCB_SYSPRI[3] = (SCB_SYSPRI[3] | (0xFFU << 16U)); - -#ifdef QXK_USE_IRQ_NUM /*--------- QXK IRQ specified? */ - /* The QXK port is configured to use a given ARM Cortex-M IRQ # - * to return to thread mode (default is to use the NMI exception) - */ - NVIC_IP[QXK_USE_IRQ_NUM] = 0U; /* priority 0 (highest) */ - NVIC_EN[QXK_USE_IRQ_NUM >> 5U] = (1U << (QXK_USE_IRQ_NUM & 0x1FU)); -#endif /*--------- QXK IRQ specified */ - -#if (__ARM_FP != 0) /*--------- if VFP available... */ - /* configure the FPU for QK */ - FPU_FPCCR |= (1U << 30U) /* automatic FPU state preservation (ASPEN) */ - | (1U << 31U); /* lazy stacking (LSPEN) */ -#endif /*--------- VFP available */ -} - -/*==========================================================================*/ -/* Initialize the private stack of an extended QXK thread. -* -* NOTE: the function aligns the stack to the 8-byte boundary for compatibility -* with the AAPCS. Additionally, the function pre-fills the stack with the -* known bit pattern (0xDEADBEEF). -* -* NOTE: QXK_stackInit_() must be called before the QXK kernel is made aware -* of this thread. In that case the kernel cannot use the thread yet, so no -* critical section is needed. -*/ -void QXK_stackInit_(void *thr, QXThreadHandler const handler, +//============================================================================ +// Initialize the private stack of an extended QXK thread. +// +// NOTE +// The function aligns the stack to the 8-byte boundary for compatibility +// with the AAPCS. Additionally, the function pre-fills the stack with the +// known bit pattern (0xDEADBEEF). +// +// NOTE: QXK_stackInit_() must be called before the QXK kernel is made aware +// of this thread. In that case the kernel cannot use the thread yet, so no +// critical section is needed. +void QXThread_stackInit_(QActive *me, QXThreadHandler const handler, void * const stkSto, uint_fast16_t const stkSize) { - /* round down the stack top to the 8-byte boundary - * NOTE: ARM Cortex-M stack grows down from hi -> low memory - */ + // round down the stack top to the 8-byte boundary + // NOTE: ARM Cortex-M stack grows down from hi -> low memory uint32_t *sp = (uint32_t *)((((uint32_t)stkSto + stkSize) >> 3U) << 3U); uint32_t *sp_limit; - /* synthesize the ARM Cortex-M exception stack frame...*/ - *(--sp) = (1U << 24); /* xPSR (just the THUMB bit) */ - *(--sp) = (uint32_t)handler; /* PC (the thread handler) */ - *(--sp) = (uint32_t)&QXK_threadExit_; /* LR (exit from thread) */ - *(--sp) = 0x0000000CU; /* R12 */ - *(--sp) = 0x00000003U; /* R3 */ - *(--sp) = 0x00000002U; /* R2 */ - *(--sp) = 0x00000001U; /* R1 */ - *(--sp) = (uint32_t)thr; /* R0 parameter to the handler (thread object) */ - *(--sp) = 0x0000000BU; /* R11 */ - *(--sp) = 0x0000000AU; /* R10 */ - *(--sp) = 0x00000009U; /* R9 */ - *(--sp) = 0x00000008U; /* R8 */ - *(--sp) = 0x00000007U; /* R7 */ - *(--sp) = 0x00000006U; /* R6 */ - *(--sp) = 0x00000005U; /* R5 */ - *(--sp) = 0x00000004U; /* R4 */ + // synthesize the ARM Cortex-M exception stack frame... + *(--sp) = (1U << 24); // xPSR (just the THUMB bit) + *(--sp) = (uint32_t)handler; // PC (the thread handler) + *(--sp) = (uint32_t)&QXK_threadExit_; // LR (exit from thread) + *(--sp) = 0x0000000CU; // R12 + *(--sp) = 0x00000003U; // R3 + *(--sp) = 0x00000002U; // R2 + *(--sp) = 0x00000001U; // R1 + *(--sp) = (uint32_t)me; // R0 parameter to handler (thread object) + *(--sp) = 0x0000000BU; // R11 + *(--sp) = 0x0000000AU; // R10 + *(--sp) = 0x00000009U; // R9 + *(--sp) = 0x00000008U; // R8 + *(--sp) = 0x00000007U; // R7 + *(--sp) = 0x00000006U; // R6 + *(--sp) = 0x00000005U; // R5 + *(--sp) = 0x00000004U; // R4 -#if (__ARM_FP != 0) /* if VFP available... */ - *(--sp) = 0xFFFFFFFDU; /* exception return with VFP state */ - *(--sp) = 0xAAAAAAAAU; /* stack "aligner" */ -#endif /* VFP available */ +#ifdef __ARM_FP //--------- if VFP available... + *(--sp) = 0xFFFFFFFDU; // exception return with VFP state + *(--sp) = 0xAAAAAAAAU; // stack "aligner" +#endif // VFP available - /* save the top of the stack in the thread's attribute */ - ((QActive *)thr)->osObject = sp; + // save the top of the stack in the thread's attribute + me->osObject = sp; - /* pre-fill the unused part of the stack with 0xDEADBEEF */ + // pre-fill the unused part of the stack with 0xDEADBEEF sp_limit = (uint32_t *)(((((uint32_t)stkSto - 1U) >> 3U) + 1U) << 3U); for (; sp >= sp_limit; --sp) { *sp = 0xDEADBEEFU; } } -/* NOTE: keep in synch with struct QXK_Attr in "qxk.h" !!! */ -#define QXK_CURR 0 -#define QXK_NEXT 4 -#define QXK_ACT_PRIO 12 +// prototypes ---------------------------------------------------------------- +void PendSV_Handler(void); +#ifdef QXK_USE_IRQ_HANDLER // if use IRQ... +void QXK_USE_IRQ_HANDLER(void); +#else // use default (NMI) +void NMI_Handler(void); +#endif -/* make sure that the offsets match the QXK declaration in "qxk.h" */ -Q_ASSERT_STATIC(QXK_CURR == offsetof(QXK, curr)); -Q_ASSERT_STATIC(QXK_NEXT == offsetof(QXK, next)); -Q_ASSERT_STATIC(QXK_ACT_PRIO == offsetof(QXK, actPrio)); +#define SCB_SYSPRI ((uint32_t volatile *)0xE000ED18U) +#define NVIC_EN ((uint32_t volatile *)0xE000E100U) +#define NVIC_IP ((uint32_t volatile *)0xE000E400U) +#define SCB_CPACR *((uint32_t volatile *)0xE000ED88U) +#define FPU_FPCCR *((uint32_t volatile *)0xE000EF34U) +#define NVIC_PEND 0xE000E200 +#define SCB_ICSR 0xE000ED04 -/* offsets within struct QActive; NOTE: keep in synch with "qf.h" !!! */ -#define QACTIVE_OSOBJ 28 -#define QACTIVE_PRIO 36 +//............................................................................ +// Initialize the exception priorities and IRQ priorities to safe values. +// +// Description: +// On ARMv7-M or higher, this QXK port disables interrupts by means of the +// BASEPRI register. However, this method cannot disable interrupt +// priority zero, which is the default for all interrupts out of reset. +// The following code changes the SysTick priority and all IRQ priorities +// to the safe value QF_BASEPRI, which the QF critical section can disable. +// This avoids breaching of the QF critical sections in case the +// application programmer forgets to explicitly set priorities of all +// "kernel aware" interrupts. +// +// The interrupt priorities established in QXK_init() can be later +// changed by the application-level code. +void QXK_init(void) { -/* make sure that the offsets match the QXK declaration in "qf.h" */ -Q_ASSERT_STATIC(QACTIVE_OSOBJ == offsetof(QActive, osObject)); -Q_ASSERT_STATIC(QACTIVE_PRIO == offsetof(QActive, prio)); +#if (__ARM_ARCH != 6) //--------- if ARMv7-M and higher... -/* helper macros to "stringify" values */ -#define VAL(x) #x -#define STRINGIFY(x) VAL(x) + // SCB_SYSPRI[2]: SysTick + SCB_SYSPRI[2] = (SCB_SYSPRI[2] | (QF_BASEPRI << 24U)); -/*==========================================================================*/ -/* The PendSV_Handler exception handler is used for performing asynchronous -* preemption in QXK. The use of the PendSV exception is the recommended and -* most efficient method for performing context switches in ARM Cortex-M. -* -* The PendSV exception should have the lowest interrupt priority in the system -* (0xFF, see QXK_init()). All other exceptions and interrupts should have -* higher interrupt priority. -* -* Also, *all* "kernel aware" ISRs in the QXK application must call the -* QXK_ISR_EXIT() macro, which triggers PendSV when it detects a need for -* asynchronous preemption. -* -* Due to tail-chaining and its lowest priority, the PendSV exception will be -* entered immediately after the exit from the *last* nested interrupt (or -* exception). In QXK, this is exactly the time when the QXK activator needs to -* handle the asynchronous preemption. -*/ + // set all 240 possible IRQ priories to QF_BASEPRI... + for (uint_fast8_t n = 0U; n < (240U/sizeof(uint32_t)); ++n) { + NVIC_IP[n] = (QF_BASEPRI << 24U) | (QF_BASEPRI << 16U) + | (QF_BASEPRI << 8U) | QF_BASEPRI; + } + +#endif //--------- ARMv7-M or higher + + // SCB_SYSPRI[2]: PendSV set to priority 0xFF (lowest) + SCB_SYSPRI[2] = (SCB_SYSPRI[2] | (0xFFU << 16U)); + +#ifdef QXK_USE_IRQ_NUM //--------- QXK IRQ specified? + // The QXK port is configured to use a given ARM Cortex-M IRQ # + // to return to thread mode (default is to use the NMI exception) + NVIC_IP[QXK_USE_IRQ_NUM] = 0U; // priority 0 (highest) + NVIC_EN[QXK_USE_IRQ_NUM >> 5U] = (1U << (QXK_USE_IRQ_NUM & 0x1FU)); +#endif //--------- QXK IRQ specified + +#ifdef __ARM_FP //--------- if VFP available... + // make sure that the FPU is enabled by seting CP10 & CP11 Full Access + SCB_CPACR = (SCB_CPACR | ((3UL << 20U) | (3UL << 22U))); + + // FPU automatic state preservation (ASPEN) lazy stacking (LSPEN) + FPU_FPCCR = (FPU_FPCCR | (1U << 30U) | (1U << 31U)); +#endif //--------- VFP available +} + +//============================================================================ +// The PendSV_Handler exception handler is used for performing asynchronous +// preemption in QXK. The use of the PendSV exception is the recommended and +// most efficient method for performing context switches in ARM Cortex-M. +// +// The PendSV exception should have the lowest interrupt priority in the system +// (0xFF, see QXK_init()). All other exceptions and interrupts should have +// higher interrupt priority. +// +// Also, *all* "kernel aware" ISRs in the QXK application must call the +// QXK_ISR_EXIT() macro, which triggers PendSV when it detects a need for +// asynchronous preemption. +// +// Due to tail-chaining and its lowest priority, the PendSV exception will be +// entered immediately after the exit from the *last* nested interrupt (or +// exception). In QXK, this is exactly the time when the QXK activator needs to +// handle the asynchronous preemption. __attribute__ ((naked)) void PendSV_Handler(void) { __asm volatile ( - /* Prepare constants in registers before entering critical section */ - " LDR r3,=QXK_attr_ \n" - " LDR r2,=" STRINGIFY(NVIC_ICSR) "\n" /* Interrupt Control and State */ - " MOVS r1,#1 \n" - " LSLS r1,r1,#27 \n" /* r0 := (1 << 27) (UNPENDSVSET bit) */ - - /*<<<<<<<<<<<<<<<<<<<<<<< CRITICAL SECTION BEGIN <<<<<<<<<<<<<<<<<<<<<<<<*/ -#if (__ARM_ARCH == 6) /* if ARMv6-M... */ - " CPSID i \n" /* disable interrupts (set PRIMASK) */ -#else /* ARMv7-M or higher */ + //<<<<<<<<<<<<<<<<<<<<<<< CRITICAL SECTION BEGIN <<<<<<<<<<<<<<<<<<<<<<<< +#if (__ARM_ARCH == 6) // if ARMv6-M... + " CPSID i \n" // disable interrupts (set PRIMASK) +#else // ARMv7-M or higher " MOVS r0,#" STRINGIFY(QF_BASEPRI) "\n" - " CPSID i \n" /* selectively disable interrupts with BASEPRI */ - " MSR BASEPRI,r0 \n" /* apply the workaround the Cortex-M7 erratum */ - " CPSIE i \n" /* 837070, see SDEN-1068427. */ -#endif /* ARMv7-M or higher */ + " CPSID i \n" // selectively disable interrupts with BASEPRI + " MSR BASEPRI,r0 \n" // apply the workaround the Cortex-M7 erratum + " CPSIE i \n" // 837070, see SDEN-1068427. +#endif // ARMv7-M or higher - /* The PendSV exception handler can be preempted by an interrupt, - * which might pend PendSV exception again. The following write to - * ICSR[27] un-pends any such spurious instance of PendSV. - */ - " STR r1,[r2] \n" /* ICSR[27] := 1 (unpend PendSV) */ +#ifdef QF_MEM_ISOLATE + " PUSH {r0,lr} \n" // save the "aligner" and the EXC_RETURN value + " LDR r0,=QF_onMemSys \n" + " BLX r0 \n" // call QF_onMemSys() + " POP {r0,r1} \n" // restore the aligner + lr into r1 + " MOV lr,r1 \n" // restore EXC_RETURN into lr +#endif - /* Check QXK_attr_.next, which contains the pointer to the next thread - * to run, which is set in QXK_ISR_EXIT(). This pointer must not be NULL. - */ - " LDR r0,[r3,#" STRINGIFY(QXK_NEXT) "]\n" /* r1 := QXK_attr_.next */ - " CMP r0,#0 \n" /* is (QXK_attr_.next == 0)? */ - " BEQ PendSV_return \n" /* branch if (QXK_attr_.next == 0) */ + // The PendSV exception handler can be preempted by an interrupt, + // which might pend PendSV exception again. The following write to + // ICSR[27] un-pends any such spurious instance of PendSV. + " MOVS r1,#1 \n" + " LSLS r1,r1,#27 \n" // r0 := (1 << 27) (UNPENDSVSET bit) + " LDR r2,=" STRINGIFY(SCB_ICSR) "\n" // Interrupt Control and State + " STR r1,[r2] \n" // ICSR[27] := 1 (unpend PendSV) - /* Load pointers into registers... */ - " MOV r12,r0 \n" /* save QXK_attr_.next in r12 */ - " LDR r2,[r0,#" STRINGIFY(QACTIVE_OSOBJ) "]\n" /* r2 := QXK_attr_.next->osObject */ - " LDR r1,[r3,#" STRINGIFY(QXK_CURR) "]\n" /* r1 := QXK_attr_.curr */ + // Check QXK_priv_.next, which contains the pointer to the next thread + // to run, which is set in QXK_ISR_EXIT(). This pointer must not be NULL. + " LDR r3,=QXK_priv_ \n" + " LDR r0,[r3,#" STRINGIFY(QXK_NEXT) "]\n" // r1 := QXK_priv_.next + " CMP r0,#0 \n" // is (QXK_priv_.next == 0)? + " BEQ PendSV_return \n" // branch if (QXK_priv_.next == 0) - " CMP r1,#0 \n" /* (QXK_attr_.curr != 0)? */ - " BNE PendSV_save_ex \n" /* branch if (current thread is extended) */ + // Load pointers into registers... + " MOV r12,r0 \n" // save QXK_priv_.next in r12 + " LDR r2,[r0,#" STRINGIFY(QACTIVE_OSOBJ) "]\n" // r2 := QXK_priv_.next->osObject + " LDR r1,[r3,#" STRINGIFY(QXK_CURR) "]\n" // r1 := QXK_priv_.curr - " CMP r2,#0 \n" /* (QXK_attr_.next->osObject != 0)? */ - " BNE PendSV_save_ao \n" /* branch if (next tread is extended) */ + " CMP r1,#0 \n" // (QXK_priv_.curr != 0)? + " BNE PendSV_save_ex \n" // branch if (current thread is extended) + + " CMP r2,#0 \n" // (QXK_priv_.next->osObject != 0)? + " BNE PendSV_save_ao \n" // branch if (next tread is extended) "PendSV_activate: \n" -#if (__ARM_FP != 0) /* if VFP available... */ - " TST lr,#(1 << 4) \n" /* is it return with the VFP exception frame? */ - " IT EQ \n" /* if lr[4] is zero... */ - " VSTMDBEQ sp!,{s16-s31} \n" /* ... save VFP registers s16..s31 */ - " PUSH {r0,lr} \n" /* save the "aligner" and the EXC_RETURN value */ -#endif /* VFP available */ - /* The QXK activator must be called in a thread context, while this code - * executes in the handler context of the PendSV exception. The switch - * to the Thread mode is accomplished by returning from PendSV using - * a fabricated exception stack frame, where the return address is - * QXK_activate_(). - * - * NOTE: the QXK activator is called with interrupts DISABLED and also - * it returns with interrupts DISABLED. - */ +#ifdef __ARM_FP //--------- if VFP available... + " TST lr,#(1 << 4) \n" // is it return with the VFP exception frame? + " IT EQ \n" // if lr[4] is zero... + " VSTMDBEQ sp!,{s16-s31} \n" // ... save VFP registers s16..s31 + " PUSH {r0,lr} \n" // save the "aligner" and the EXC_RETURN value +#endif // VFP available + // The QXK activator must be called in a thread context, while this code + // executes in the handler context of the PendSV exception. The switch + // to the Thread mode is accomplished by returning from PendSV using + // a fabricated exception stack frame, where the return address is + // QXK_activate_(). + // + // NOTE: the QXK activator is called with interrupts DISABLED and also + // it returns with interrupts DISABLED. " MOVS r3,#1 \n" - " LSLS r3,r3,#24 \n" /* r3 := (1 << 24), set the T bit (new xpsr) */ - " LDR r2,=QXK_activate_\n" /* address of QXK_activate_ */ - " SUBS r2,r2,#1 \n" /* align Thumb-address at half-word (new pc) */ - " LDR r1,=QXK_thread_ret\n" /* return address after the call (new lr) */ + " LSLS r3,r3,#24 \n" // r3 := (1 << 24), set T bit (new xpsr) + " LDR r2,=QXK_activate_\n" // address of QXK_activate_ + " SUBS r2,r2,#1 \n" // align Thumb-address at half-word (new pc) + " LDR r1,=QXK_thread_ret\n" // return address after the call (new lr) - " SUB sp,sp,#(8*4) \n" /* reserve space for exception stack frame */ - " ADD r0,sp,#(5*4) \n" /* r0 := 5 registers below the top of stack */ - " STM r0!,{r1-r3} \n" /* save xpsr,pc,lr */ + " SUB sp,sp,#(8*4) \n" // reserve space for exception stack frame + " ADD r0,sp,#(5*4) \n" // r0 := 5 registers below the top of stack + " STM r0!,{r1-r3} \n" // save xpsr,pc,lr " MOVS r0,#6 \n" - " MVNS r0,r0 \n" /* r0 := ~6 == 0xFFFFFFF9 */ -#if (__ARM_ARCH != 6) /* ARMv7-M or higher */ - " DSB \n" /* ARM Erratum 838869 */ -#endif /* ARMv7-M or higher */ - " BX r0 \n" /* exception-return to the QXK activator */ + " MVNS r0,r0 \n" // r0 := ~6 == 0xFFFFFFF9 +#if (__ARM_ARCH != 6) // ARMv7-M or higher + " DSB \n" // ARM Erratum 838869 +#endif // ARMv7-M or higher + " BX r0 \n" // exception-return to the QXK activator - /*========================================================================= - * Saving AO-thread before crossing to eXtended-thread - * expected register contents: - * r0 -> QXK_attr_.next / basic-thread - * r1 -> QXK_attr_.curr / basic-thread - * r2 -> QXK_attr_.next->osObject (SP) - * r3 -> &QXK_attr_ - * r12 -> QXK_attr_.next / basic-thread - */ + //======================================================================== + // Saving AO-thread before crossing to eXtended-thread + // expected register contents: + // r0 -> QXK_priv_.next / basic-thread + // r1 -> QXK_priv_.curr / basic-thread + // r2 -> QXK_priv_.next->osObject (SP) + // r3 -> &QXK_priv_ + // r12 -> QXK_priv_.next / basic-thread "PendSV_save_ao: \n" -#if (__ARM_ARCH == 6) /* if ARMv6-M... */ - " SUB sp,sp,#(8*4) \n" /* make room for 8 registers r4-r11 */ - " MOV r0,sp \n" /* r0 := temporary stack pointer */ - " STMIA r0!,{r4-r7} \n" /* save the low registers */ - " MOV r4,r8 \n" /* move the high registers to low registers... */ +#if (__ARM_ARCH == 6) // if ARMv6-M... + " SUB sp,sp,#(8*4) \n" // make room for 8 registers r4-r11 + " MOV r0,sp \n" // r0 := temporary stack pointer + " STMIA r0!,{r4-r7} \n" // save the low registers + " MOV r4,r8 \n" // move the high registers to low registers... " MOV r5,r9 \n" " MOV r6,r10 \n" " MOV r7,r11 \n" - " STMIA r0!,{r4-r7} \n" /* save the high registers */ - " MOV r0,r12 \n" /* restore QXK_attr_.next in r0 */ -#else /* ARMv7-M or higher */ - " PUSH {r4-r11} \n" /* save r4-r11 on top of the exception frame */ -#if (__ARM_FP != 0) /* if VFP available... */ - " TST lr,#(1 << 4) \n" /* is it return with the VFP exception frame? */ - " IT EQ \n" /* if lr[4] is zero... */ - " VSTMDBEQ sp!,{s16-s31} \n" /* ... save VFP registers s16..s31 */ - " PUSH {r0,lr} \n" /* save the "aligner" and the EXC_RETURN value */ -#endif /* VFP available */ -#endif /* ARMv7-M or higher */ + " STMIA r0!,{r4-r7} \n" // save the high registers + " MOV r0,r12 \n" // restore QXK_priv_.next in r0 +#else // ARMv7-M or higher + " PUSH {r4-r11} \n" // save r4-r11 on top of the exception frame +#ifdef __ARM_FP //--------- if VFP available... + " TST lr,#(1 << 4) \n" // is it return with the VFP exception frame? + " IT EQ \n" // if lr[4] is zero... + " VSTMDBEQ sp!,{s16-s31} \n" // ... save VFP registers s16..s31 + " PUSH {r0,lr} \n" // save the "aligner" and the EXC_RETURN value +#endif // VFP available +#endif // ARMv7-M or higher " CMP r2,#0 \n" - " BNE PendSV_restore_ex\n" /* branch if (QXK_attr_.next->osObject != 0) */ - /* otherwise continue to restoring next AO-thread... */ + " BNE PendSV_restore_ex\n" // branch if (QXK_priv_.next->osObject != 0) + // otherwise continue to restoring next AO-thread... - /*------------------------------------------------------------------------- - * Restoring AO-thread after crossing from eXtended-thread - * expected register contents: - * r1 -> QXK_attr_.curr / basic-thread - * r2 -> QXK_attr_.next->osObject (SP) - * r3 -> &QXK_attr_ - * r12 -> QXK_attr_.next / basic-thread - */ + //------------------------------------------------------------------------ + // Restoring AO-thread after crossing from eXtended-thread + // expected register contents: + // r1 -> QXK_priv_.curr / basic-thread + // r2 -> QXK_priv_.next->osObject (SP) + // r3 -> &QXK_priv_ + // r12 -> QXK_priv_.next / basic-thread "PendSV_restore_ao: \n" - /* don NOT clear QXK_attr_.curr or QXK_attr_.next, - * as they might be needed for AO activation - */ + // don NOT clear QXK_priv_.curr or QXK_priv_.next, + // as they might be needed for AO activation -#if (__ARM_ARCH == 6) /* if ARMv6-M... */ - " MOV r0,sp \n" /* r0 := top of stack */ +#if (__ARM_ARCH == 6) // if ARMv6-M... + " MOV r0,sp \n" // r0 := top of stack " MOV r2,r0 \n" - " ADDS r2,r2,#(4*4) \n" /* point r2 to the 4 high registers r7-r11 */ - " LDMIA r2!,{r4-r7} \n" /* pop the 4 high registers into low registers */ - " MOV r8,r4 \n" /* move low registers into high registers */ + " ADDS r2,r2,#(4*4) \n" // point r2 to the 4 high registers r7-r11 + " LDMIA r2!,{r4-r7} \n" // pop the 4 high registers into low registers + " MOV r8,r4 \n" // move low registers into high registers " MOV r9,r5 \n" " MOV r10,r6 \n" " MOV r11,r7 \n" - " LDMIA r0!,{r4-r7} \n" /* pop the low registers */ - " ADD sp,sp,#(8*4) \n" /* remove 8 registers from the stack */ + " LDMIA r0!,{r4-r7} \n" // pop the low registers + " ADD sp,sp,#(8*4) \n" // remove 8 registers from the stack " MOVS r2,#6 \n" - " MVNS r2,r2 \n" /* r2 := ~6 == 0xFFFFFFF9 */ - " MOV lr,r2 \n" /* make sure MSP is used */ -#else /* ARMv7-M or higher */ -#if (__ARM_FP != 0) /* if VFP available... */ - " POP {r0,lr} \n" /* restore alighner and EXC_RETURN into lr */ - " DSB \n" /* ARM Erratum 838869 */ - " TST lr,#(1 << 4) \n" /* is it return to the VFP exception frame? */ - " IT EQ \n" /* if EXC_RETURN[4] is zero... */ - " VLDMIAEQ sp!,{s16-s31} \n" /* ... restore VFP registers s16..s31 */ + " MVNS r2,r2 \n" // r2 := ~6 == 0xFFFFFFF9 + " MOV lr,r2 \n" // make sure MSP is used +#else // ARMv7-M or higher +#ifdef __ARM_FP //--------- if VFP available... + " POP {r0,lr} \n" // restore alighner and EXC_RETURN into lr + " DSB \n" // ARM Erratum 838869 + " TST lr,#(1 << 4) \n" // is it return to the VFP exception frame? + " IT EQ \n" // if EXC_RETURN[4] is zero... + " VLDMIAEQ sp!,{s16-s31} \n" // ... restore VFP registers s16..s31 #else - " BIC lr,lr,#(1 << 2) \n" /* make sure MSP is used */ -#endif /* VFP available */ - " POP {r4-r11} \n" /* restore r4-r11 from the next thread's stack */ -#endif /* ARMv7-M or higher */ + " BIC lr,lr,#(1 << 2) \n" // make sure MSP is used +#endif // VFP available + " POP {r4-r11} \n" // restore r4-r11 from the next thread's stack +#endif // ARMv7-M or higher - " MOV r0,r12 \n" /* r0 := QXK_attr_.next */ - " MOVS r2,#" STRINGIFY(QACTIVE_PRIO) "\n" /* r2 := offset of .prio */ - " LDRB r0,[r0,r2] \n" /* r0 := QXK_attr_.next->prio */ - " LDRB r2,[r3,#" STRINGIFY(QXK_ACT_PRIO) "]\n" /* r2 := QXK_attr_.actPrio */ + " MOV r0,r12 \n" // r0 := QXK_priv_.next + " MOVS r2,#" STRINGIFY(QACTIVE_PRIO) "\n" // r2 := offset of .prio + " LDRB r0,[r0,r2] \n" // r0 := QXK_priv_.next->prio + " LDR r2,[r3,#" STRINGIFY(QXK_ACT_PRIO) "]\n" // r2 := QXK_priv_.actPrio " CMP r2,r0 \n" - " BCC PendSV_activate \n" /* if (next->prio > actPrio) activate the next AO */ + " BCC PendSV_activate \n" // if (next->prio > actPrio) activate the next AO - /* otherwise no activation needed... */ + // otherwise no activation needed... " MOVS r0,#0 \n" - " STR r0,[r3,#" STRINGIFY(QXK_CURR) "]\n" /* QXK_attr_.curr := 0 */ - " STR r0,[r3,#" STRINGIFY(QXK_NEXT) "]\n" /* QXK_attr_.next := 0 */ + " STR r0,[r3,#" STRINGIFY(QXK_CURR) "]\n" // QXK_priv_.curr := 0 + " STR r0,[r3,#" STRINGIFY(QXK_NEXT) "]\n" // QXK_priv_.next := 0 #if defined(Q_SPY) || defined(QF_ON_CONTEXT_SW) - " MOVS r0,#0 \n" /* r0 := 0 (next is basic) */ - " PUSH {r3,lr} \n" /* save QXK_attr_ + exception lr */ - " LDR r3,=QXK_contextSw \n" - " BLX r3 \n" /* call QXK_contextSw() */ - " POP {r0,r1} \n" /* restore the aligner + lr into r1 */ - " MOV lr,r1 \n" /* restore the exception lr */ -#endif /* defined(Q_SPY) || defined(QF_ON_CONTEXT_SW) */ + " MOVS r0,#0 \n" // r0 := 0 (next is basic) + " PUSH {r0,lr} \n" // save the aligner + EXC_RETURN + " LDR r3,=QXK_contextSw_ \n" + " BLX r3 \n" // call QXK_contextSw_() +#ifdef QF_MEM_ISOLATE + " LDR r3,=QF_onMemApp \n" + " BLX r3 \n" // call QF_onMemApp() +#endif + " POP {r0,r1} \n" // restore the aligner + EXC_RETURN + " MOV lr,r1 \n" // restore EXC_RETURN into lr +#endif // defined(Q_SPY) || defined(QF_ON_CONTEXT_SW) - /* re-enable interrupts and return from PendSV */ + // re-enable interrupts and return from PendSV "PendSV_return: \n" -#if (__ARM_ARCH == 6) /* if ARMv6-M... */ - " CPSIE i \n" /* enable interrupts (clear PRIMASK) */ -#else /* ARMv7-M or higher */ +#if (__ARM_ARCH == 6) // if ARMv6-M... + " CPSIE i \n" // enable interrupts (clear PRIMASK) +#else // ARMv7-M or higher " MOVS r0,#0 \n" - " MSR BASEPRI,r0 \n" /* enable interrupts (clear BASEPRI) */ - " DSB \n" /* ARM Erratum 838869 */ -#endif /* ARMv7-M or higher */ - /*>>>>>>>>>>>>>>>>>>>>>>>> CRITICAL SECTION END >>>>>>>>>>>>>>>>>>>>>>>>>*/ - " BX lr \n" /* return to the preempted AO-thread */ + " MSR BASEPRI,r0 \n" // enable interrupts (clear BASEPRI) + " DSB \n" // ARM Erratum 838869 +#endif // ARMv7-M or higher + //>>>>>>>>>>>>>>>>>>>>>>>> CRITICAL SECTION END >>>>>>>>>>>>>>>>>>>>>>>>> + " BX lr \n" // return to the preempted AO-thread - /*------------------------------------------------------------------------- - * Saving extended-thread - * expected register contents: - * r0 -> QXK_attr_.next / basic-thread - * r1 -> QXK_attr_.curr / basic-thread - * r2 -> QXK_attr_.next->osObject (SP) - * r3 -> &QXK_attr_ - * r12 -> QXK_attr_.next / basic-thread - */ + //------------------------------------------------------------------------ + // Saving extended-thread + // expected register contents: + // r0 -> QXK_priv_.next / basic-thread + // r1 -> QXK_priv_.curr / basic-thread + // r2 -> QXK_priv_.next->osObject (SP) + // r3 -> &QXK_priv_ + // r12 -> QXK_priv_.next / basic-thread "PendSV_save_ex: \n" - " MRS r0,PSP \n" /* r0 := Process Stack Pointer */ -#if (__ARM_ARCH == 6) /* if ARMv6-M... */ - " SUBS r0,r0,#(8*4) \n" /* make room for 8 registers r4-r11 */ - " MOVS r1,r0 \n" /* r1 := temporary PSP (do not clobber r0!) */ - " STMIA r1!,{r4-r7} \n" /* save the low registers */ - " MOV r4,r8 \n" /* move the high registers to low registers... */ + " MRS r0,PSP \n" // r0 := Process Stack Pointer +#if (__ARM_ARCH == 6) // if ARMv6-M... + " SUBS r0,r0,#(8*4) \n" // make room for 8 registers r4-r11 + " MOVS r1,r0 \n" // r1 := temporary PSP (do not clobber r0!) + " STMIA r1!,{r4-r7} \n" // save the low registers + " MOV r4,r8 \n" // move the high registers to low registers... " MOV r5,r9 \n" " MOV r6,r10 \n" " MOV r7,r11 \n" - " STMIA r1!,{r4-r7} \n" /* save the high registers */ - /* NOTE: at this point r0 holds the top of stack */ + " STMIA r1!,{r4-r7} \n" // save the high registers + // NOTE: at this point r0 holds the top of stack - " LDR r1,[r3,#" STRINGIFY(QXK_CURR) "]\n" /* r1 := QXK_attr_.curr (restore value) */ -#else /* ARMv7-M or higher */ - " ISB \n" /* reset pipeline after fetching PSP */ - " STMDB r0!,{r4-r11} \n" /* save r4-r11 on top of the exception frame */ -#if (__ARM_FP != 0) /* if VFP available... */ - " TST lr,#(1 << 4) \n" /* is it return with the VFP exception frame? */ - " IT EQ \n" /* if lr[4] is zero... */ - " VSTMDBEQ r0!,{s16-s31} \n" /* ... save VFP registers s16..s31 */ - " STMDB r0!,{r1,lr} \n" /* save the "aligner" and the EXC_RETURN value */ -#endif /* VFP available */ -#endif /* ARMv7-M or higher */ + " LDR r1,[r3,#" STRINGIFY(QXK_CURR) "]\n" // r1 := QXK_priv_.curr (restore value) +#else // ARMv7-M or higher + " ISB \n" // reset pipeline after fetching PSP + " STMDB r0!,{r4-r11} \n" // save r4-r11 on top of the exception frame +#ifdef __ARM_FP //--------- if VFP available... + " TST lr,#(1 << 4) \n" // is it return with the VFP exception frame? + " IT EQ \n" // if lr[4] is zero... + " VSTMDBEQ r0!,{s16-s31} \n" // ... save VFP registers s16..s31 + " STMDB r0!,{r1,lr} \n" // save the "aligner" and the EXC_RETURN value +#endif // VFP available +#endif // ARMv7-M or higher - /* store the SP of the current extended-thread */ - " STR r0,[r1,#" STRINGIFY(QACTIVE_OSOBJ) "]\n" /* QXK_attr_.curr->osObject := r0 */ - " MOV r0,r12 \n" /* QXK_attr_.next (restore value) */ + // store the SP of the current extended-thread + " STR r0,[r1,#" STRINGIFY(QACTIVE_OSOBJ) "]\n" // QXK_priv_.curr->osObject := r0 + " MOV r0,r12 \n" // QXK_priv_.next (restore value) " CMP r2,#0 \n" - " BEQ PendSV_restore_ao\n" /* branch if (QXK_attr_.next->osObject == 0) */ - /* otherwise continue to restoring next extended-thread... */ + " BEQ PendSV_restore_ao\n" // branch if (QXK_priv_.next->osObject == 0) + // otherwise continue to restoring next extended-thread... - /*------------------------------------------------------------------------- - * Restoring extended-thread - * expected register contents: - * r0 -> QXK_attr_.next / basic-thread - * r1 -> QXK_attr_.curr / basic-thread - * r2 -> QXK_attr_.next->osObject (SP) - * r3 -> &QXK_attr_ - * r12 -> QXK_attr_.next / basic-thread - */ + //------------------------------------------------------------------------ + // Restoring extended-thread + // expected register contents: + // r0 -> QXK_priv_.next / basic-thread + // r1 -> QXK_priv_.curr / basic-thread + // r2 -> QXK_priv_.next->osObject (SP) + // r3 -> &QXK_priv_ + // r12 -> QXK_priv_.next / basic-thread "PendSV_restore_ex: \n" -#if defined(Q_SPY) || defined(QF_ON_CONTEXT_SW) - " MOV r0,r12 \n" /* r0 := next */ - " PUSH {r3,lr} \n" /* save QXK_attr_ + exception lr */ - " LDR r3,=QXK_contextSw \n" - " BLX r3 \n" /* call QXK_contextSw() */ - " POP {r0,r1} \n" /* restore the aligner + lr into r1 */ - " MOV lr,r1 \n" /* restore the exception lr */ - " MOVS r3,r0 \n" /* restore the saved QXK_attr_ in r3 */ - - /* restore the AAPCS-clobbered registers after a functin call... */ - " LDR r0,[r3,#" STRINGIFY(QXK_NEXT) "]\n" /* r0 := QXK_attr_.next */ - " LDR r2,[r0,#" STRINGIFY(QACTIVE_OSOBJ) "]\n" /* r2 := QXK_attr_.curr->osObject */ -#endif /* defined(Q_SPY) || defined(QF_ON_CONTEXT_SW) */ - - " STR r0,[r3,#" STRINGIFY(QXK_CURR) "]\n" /* QXK_attr_.curr := r0 (QXK_attr_.next) */ + " STR r0,[r3,#" STRINGIFY(QXK_CURR) "]\n" // QXK_priv_.curr := r0 (QXK_priv_.next) " MOVS r0,#0 \n" - " STR r0,[r3,#" STRINGIFY(QXK_NEXT) "]\n" /* QXK_attr_.next := 0 */ + " STR r0,[r3,#" STRINGIFY(QXK_NEXT) "]\n" // QXK_priv_.next := 0 - /* exit the critical section */ -#if (__ARM_ARCH == 6) /* if ARMv6-M... */ - " CPSIE i \n" /* enable interrupts (clear PRIMASK) */ +#if defined(Q_SPY) || defined(QF_ON_CONTEXT_SW) + " MOV r0,r12 \n" // r0 := next + " PUSH {r0-r2,lr} \n" // save next, osObject, EXC_RETURN + " LDR r3,=QXK_contextSw_ \n" + " BLX r3 \n" // call QXK_contextSw_() +#ifdef QF_MEM_ISOLATE + " LDR r3,=QF_onMemApp \n" + " BLX r3 \n" // call QF_onMemApp() +#endif + " POP {r0-r3} \n" // restore next, osObject, EXC_RETURN + " MOV lr,r3 \n" // restore the EXC_RETURN into lr +#endif // defined(Q_SPY) || defined(QF_ON_CONTEXT_SW) - " MOVS r0,r2 \n" /* r2 := top of stack */ - " ADDS r0,r0,#(4*4) \n" /* point r0 to the 4 high registers r7-r11 */ - " LDMIA r0!,{r4-r7} \n" /* pop the 4 high registers into low registers */ - " MOV r8,r4 \n" /* move low registers into high registers */ + + // exit the critical section +#if (__ARM_ARCH == 6) // if ARMv6-M... + " CPSIE i \n" // enable interrupts (clear PRIMASK) + + " MOVS r0,r2 \n" // r2 := top of stack + " ADDS r0,r0,#(4*4) \n" // point r0 to the 4 high registers r7-r11 + " LDMIA r0!,{r4-r7} \n" // pop the 4 high registers into low registers + " MOV r8,r4 \n" // move low registers into high registers " MOV r9,r5 \n" " MOV r10,r6 \n" " MOV r11,r7 \n" - " LDMIA r2!,{r4-r7} \n" /* pop the low registers */ - " MOVS r2,r0 \n" /* r2 := holds the new top of stack */ + " LDMIA r2!,{r4-r7} \n" // pop the low registers + " MOVS r2,r0 \n" // r2 := holds the new top of stack " MOVS r1,#2 \n" - " MVNS r1,r1 \n" /* r1 := ~2 == 0xFFFFFFFD */ - " MOV lr,r1 \n" /* make sure PSP is used */ -#else /* ARMv7-M or higher */ + " MVNS r1,r1 \n" // r1 := ~2 == 0xFFFFFFFD + " MOV lr,r1 \n" // make sure PSP is used +#else // ARMv7-M or higher " MOVS r1,#0 \n" - " MSR BASEPRI,r1 \n" /* enable interrupts (clear BASEPRI) */ -#if (__ARM_FP != 0) /* if VFP available... */ - " LDMIA r2!,{r1,lr} \n" /* restore aligner and EXC_RETURN into lr */ - " TST lr,#(1 << 4) \n" /* is it return to the VFP exception frame? */ - " IT EQ \n" /* if lr[4] is zero... */ - " VLDMIAEQ r2!,{s16-s31} \n" /* ... restore VFP registers s16..s31 */ + " MSR BASEPRI,r1 \n" // enable interrupts (clear BASEPRI) +#ifdef __ARM_FP //--------- if VFP available... + " LDMIA r2!,{r1,lr} \n" // restore aligner and EXC_RETURN into lr + " TST lr,#(1 << 4) \n" // is it return to the VFP exception frame? + " IT EQ \n" // if lr[4] is zero... + " VLDMIAEQ r2!,{s16-s31} \n" // ... restore VFP registers s16..s31 #else - " ORR lr,lr,#(1 << 2) \n" /* make sure PSP is used */ -#endif /* VFP available */ - " LDMIA r2!,{r4-r11} \n" /* restore r4-r11 from the next thread's stack */ -#endif /* ARMv7-M or higher */ + " ORR lr,lr,#(1 << 2) \n" // make sure PSP is used +#endif // VFP available + " LDMIA r2!,{r4-r11} \n" // restore r4-r11 from the next thread's stack +#endif // ARMv7-M or higher - /* set the PSP to the next thread's SP */ - " MSR PSP,r2 \n" /* Process Stack Pointer := r2 */ + // set the PSP to the next thread's SP + " MSR PSP,r2 \n" // Process Stack Pointer := r2 -#if (__ARM_ARCH != 6) /* if ARMv7-M or higher... */ - " DSB \n" /* ARM Erratum 838869 */ -#endif /* ARMv7-M or higher */ - " BX lr \n" /* return to the next extended-thread */ +#if (__ARM_ARCH != 6) // if ARMv7-M or higher... + " DSB \n" // ARM Erratum 838869 +#endif // ARMv7-M or higher + " BX lr \n" // return to the next extended-thread ); } -/*==========================================================================*/ -/* QXK_thread_ret is a helper function executed when the QXK activator returns. -* -* NOTE: QXK_thread_ret does not execute in the PendSV context! -* NOTE: QXK_thread_ret is entered with interrupts DISABLED. -*/ +//============================================================================ +// QXK_thread_ret is a helper function executed when the QXK activator returns. +// +// NOTE: QXK_thread_ret does not execute in the PendSV context! +// NOTE: QXK_thread_ret is entered with interrupts DISABLED. __attribute__ ((naked, used)) void QXK_thread_ret(void) { __asm volatile ( - /* After the QXK activator returns, we need to resume the preempted - * thread. However, this must be accomplished by a return-from-exception, - * while we are still in the thread context. The switch to the exception - * context is accomplished by triggering the NMI exception or the selected - * IRQ (if macro #QXK_USE_IRQ_NUM is defined). - */ + // After the QXK activator returns, we need to resume the preempted + // thread. However, this must be accomplished by a return-from-exception, + // while we are still in the thread context. The switch to the exception + // context is accomplished by triggering the NMI exception or the selected + // IRQ (if macro #QXK_USE_IRQ_NUM is defined). - /* before triggering the NMI/IRQ, make sure that the VFP stack frame - * will NOT be used... - */ -#if (__ARM_FP != 0) /*--------- if VFP available... */ - /* make sure that the VFP stack frame will NOT be used */ - " MRS r0,CONTROL \n" /* r0 := CONTROL */ - " BICS r0,r0,#4 \n" /* r0 := r0 & ~4 (FPCA bit) */ - " MSR CONTROL,r0 \n" /* CONTROL := r0 (clear CONTROL[2] FPCA bit) */ - " ISB \n" /* ISB after MSR CONTROL (ARM AN321,Sect.4.16) */ -#endif /*--------- VFP available */ + // before triggering the NMI/IRQ, make sure that the VFP stack frame + // will NOT be used... +#ifdef __ARM_FP //--------- if VFP available... + // make sure that the VFP stack frame will NOT be used + " MRS r0,CONTROL \n" // r0 := CONTROL + " BICS r0,r0,#4 \n" // r0 := r0 & ~4 (FPCA bit) + " MSR CONTROL,r0 \n" // CONTROL := r0 (clear CONTROL[2] FPCA bit) + " ISB \n" // ISB after MSR CONTROL (ARM AN321,Sect.4.16) +#endif //--------- VFP available -#ifndef QXK_USE_IRQ_NUM /*--------- IRQ NOT defined, use NMI by default */ - " LDR r0,=" STRINGIFY(NVIC_ICSR) "\n" /* Interrupt Control and State */ +#ifdef QF_MEM_ISOLATE + " PUSH {r0,lr} \n" // save the aligner + EXC_RETURN + " LDR r0,=QF_onMemApp \n" + " BLX r0 \n" // call QF_onMemApp() + " POP {r0,r1} \n" // restore the aligner + EXC_RETURN + " MOV lr,r1 \n" // restore EXC_RETURN into lr +#endif + +#ifndef QXK_USE_IRQ_NUM //--------- IRQ NOT defined, use NMI by default + " LDR r0,=" STRINGIFY(SCB_ICSR) "\n" // Interrupt Control and State " MOVS r1,#1 \n" - " LSLS r1,r1,#31 \n" /* r1 := (1 << 31) (NMI bit) */ - " STR r1,[r0] \n" /* ICSR[31] := 1 (pend NMI) */ + " LSLS r1,r1,#31 \n" // r1 := (1 << 31) (NMI bit) + " STR r1,[r0] \n" // ICSR[31] := 1 (pend NMI) -#else /*--------- use the selected IRQ */ +#else //--------- use the selected IRQ " LDR r0,=" STRINGIFY(NVIC_PEND + ((QXK_USE_IRQ_NUM >> 5) << 2)) "\n" " MOVS r1,#1 \n" - " LSLS r1,r1,#" STRINGIFY(QXK_USE_IRQ_NUM & 0x1F) "\n" /* r1 := IRQ bit */ - " STR r1,[r0] \n" /* pend the IRQ */ + " LSLS r1,r1,#" STRINGIFY(QXK_USE_IRQ_NUM & 0x1F) "\n" // r1 := IRQ bit + " STR r1,[r0] \n" // pend the IRQ - /* now enable interrupts so that pended IRQ can be entered */ -#if (__ARM_ARCH == 6) /*--------- if ARMv6-M... */ - " CPSIE i \n" /* enable interrupts (clear PRIMASK) */ -#else /*--------- ARMv7-M and higher */ + // now enable interrupts so that pended IRQ can be entered +#if (__ARM_ARCH == 6) //--------- if ARMv6-M... + " CPSIE i \n" // enable interrupts (clear PRIMASK) +#else //--------- ARMv7-M and higher " MOVS r0,#0 \n" - " MSR BASEPRI,r0 \n" /* enable interrupts (clear BASEPRI) */ -#endif /*--------- ARMv7-M and higher */ -#endif /*--------- use IRQ */ + " MSR BASEPRI,r0 \n" // enable interrupts (clear BASEPRI) +#endif //--------- ARMv7-M and higher +#endif //--------- use IRQ - /* NOTE! interrupts are still disabled when NMI is used */ - " B . \n" /* wait for preemption by NMI/IRQ */ + // NOTE! interrupts are still disabled when NMI is used + " B . \n" // wait for preemption by NMI/IRQ ); } -/*==========================================================================*/ -/* This exception handler is used for returning back to the preempted thread. -* The exception handler simply removes its own interrupt stack frame from -* the stack (MSP) and returns to the preempted task using the interrupt -* stack frame that must be at the top of the stack. -*/ +//============================================================================ +// This exception handler is used for returning back to the preempted thread. +// The exception handler simply removes its own interrupt stack frame from +// the stack (MSP) and returns to the preempted task using the interrupt +// stack frame that must be at the top of the stack. __attribute__ ((naked)) -#ifndef QXK_USE_IRQ_NUM /*--------- IRQ NOT defined, use NMI by default */ +#ifndef QXK_USE_IRQ_NUM //--------- IRQ NOT defined, use NMI by default -/* NOTE: The NMI_Handler() is entered with interrupts still disabled! */ +// NOTE: The NMI_Handler() is entered with interrupts still disabled! void NMI_Handler(void) { __asm volatile ( - /* enable interrupts */ -#if (__ARM_ARCH == 6) /*--------- if ARMv6-M... */ - " CPSIE i \n" /* enable interrupts (clear PRIMASK) */ -#else /*--------- ARMv7-M and higher */ + // enable interrupts +#if (__ARM_ARCH == 6) //--------- if ARMv6-M... + " CPSIE i \n" // enable interrupts (clear PRIMASK) +#else //--------- ARMv7-M and higher " MOVS r0,#0 \n" - " MSR BASEPRI,r0 \n" /* enable interrupts (clear BASEPRI) */ -#endif /*--------- ARMv7-M and higher */ + " MSR BASEPRI,r0 \n" // enable interrupts (clear BASEPRI) +#endif //--------- ARMv7-M and higher ); -#else /*--------- use the selected IRQ */ +#else //--------- use the selected IRQ -/* NOTE: The IRQ Handler is entered with interrupts enabled */ +// NOTE: The IRQ Handler is entered with interrupts enabled void QXK_USE_IRQ_HANDLER(void) { -#endif /*--------- use IRQ */ +#endif //--------- use IRQ __asm volatile ( - " ADD sp,sp,#(8*4) \n" /* remove one 8-register exception frame */ + " ADD sp,sp,#(8*4) \n" // remove one 8-register exception frame -#if (__ARM_FP != 0) /*--------- if VFP available... */ - " POP {r0,lr} \n" /* restore alighner and EXC_RETURN into lr */ - " DSB \n" /* ARM Erratum 838869 */ - " TST lr,#(1 << 4) \n" /* is it return to the VFP exception frame? */ - " IT EQ \n" /* if EXC_RETURN[4] is zero... */ - " VLDMIAEQ sp!,{s16-s31} \n" /* ... restore VFP registers s16..s31 */ -#endif /*--------- VFP available */ - " BX lr \n" /* return to the preempted task */ +#ifdef __ARM_FP //--------- if VFP available... + " POP {r0,lr} \n" // restore alighner and EXC_RETURN into lr + " DSB \n" // ARM Erratum 838869 + " TST lr,#(1 << 4) \n" // is it return to the VFP exception frame? + " IT EQ \n" // if EXC_RETURN[4] is zero... + " VLDMIAEQ sp!,{s16-s31} \n" // ... restore VFP registers s16..s31 +#endif //--------- VFP available + " BX lr \n" // return to the preempted task ); } -/*==========================================================================*/ -#if (__ARM_ARCH == 6) /* if ARMv6-M... */ +//============================================================================ +#if (__ARM_ARCH == 6) // if ARMv6-M... -/* hand-optimized quick LOG2 in assembly (no CLZ instruction in ARMv6-M) */ +// hand-optimized quick LOG2 in assembly (no CLZ instruction in ARMv6-M) __attribute__ ((naked)) uint_fast8_t QF_qlog2(uint32_t x) { __asm volatile ( @@ -633,5 +636,5 @@ __asm volatile ( ); } -#endif /* ARMv6-M */ +#endif // ARMv6-M diff --git a/ports/arm-cm/qxk/armclang/qxk_port.h b/ports/arm-cm/qxk/armclang/qxk_port.h deleted file mode 100644 index 1211ac52..00000000 --- a/ports/arm-cm/qxk/armclang/qxk_port.h +++ /dev/null @@ -1,99 +0,0 @@ -/*============================================================================ -* QP/C Real-Time Embedded Framework (RTEF) -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2022-12-18 -* @version Last updated for: @ref qpc_7_2_0 -* -* @file -* @brief QXK/C port to ARM Cortex-M, ARM-CLANG compiler -*/ -#ifndef QXK_PORT_H -#define QXK_PORT_H - -/* determination if the code executes in the ISR context */ -#define QXK_ISR_CONTEXT_() (QXK_get_IPSR() != 0U) - -__attribute__((always_inline)) -static inline uint32_t QXK_get_IPSR(void) { - uint32_t regIPSR; - __asm volatile ("mrs %0,ipsr" : "=r" (regIPSR)); - return regIPSR; -} - -/* trigger the PendSV exception to pefrom the context switch */ -#define QXK_CONTEXT_SWITCH_() \ - *Q_UINT2PTR_CAST(uint32_t, 0xE000ED04U) = (1U << 28U) - -/* QXK ISR entry and exit */ -#define QXK_ISR_ENTRY() ((void)0) - -#define QXK_ISR_EXIT() do { \ - QF_INT_DISABLE(); \ - if (QXK_sched_() != 0U) { \ - QXK_CONTEXT_SWITCH_(); \ - } \ - QF_INT_ENABLE(); \ - QXK_ARM_ERRATUM_838869(); \ -} while (false) - -#if (__ARM_ARCH == 6) /* ARMv6-M? */ - #define QXK_ARM_ERRATUM_838869() ((void)0) -#else /* ARMv7-M or higher */ - /* The following macro implements the recommended workaround for the - * ARM Erratum 838869. Specifically, for Cortex-M3/M4/M7 the DSB - * (memory barrier) instruction needs to be added before exiting an ISR. - */ - #define QXK_ARM_ERRATUM_838869() \ - __asm volatile ("dsb" ::: "memory") -#endif /* ARMv6-M */ - -/* Use a given ARM Cortex-M IRQ to return to thread mode (default NMI) -* -* NOTE: -* If you need the NMI for other purposes, you can define the macros -* QXK_USE_IRQ_NUM and QXK_USE_IRQ_HANDLER to use thus specified IRQ -* instead of the NMI (the IRQ should not be used for anything else). -* These two macros can be defined on the command line to the compiler -* and are actually needed only to compile the qxk_port.c file. -*/ -//#define QXK_USE_IRQ_NUM 25 -//#define QXK_USE_IRQ_HANDLER CRYPTO_IRQHandler - -/* initialization of the QXK kernel */ -#define QXK_INIT() QXK_init() -void QXK_init(void); -void QXK_thread_ret(void); - -#if (__ARM_FP != 0) /* if VFP available... */ -/* When the FPU is configured, clear the FPCA bit in the CONTROL register -* to prevent wasting the stack space for the FPU context. -*/ -#define QXK_START() __asm volatile ("msr CONTROL,%0" :: "r" (0) : ) -#endif - -#include "qxk.h" /* QXK platform-independent public interface */ - -#endif /* QXK_PORT_H */ - diff --git a/ports/arm-cm/qxk/gnu/qep_port.h b/ports/arm-cm/qxk/gnu/qep_port.h deleted file mode 100644 index 67577b76..00000000 --- a/ports/arm-cm/qxk/gnu/qep_port.h +++ /dev/null @@ -1,44 +0,0 @@ -/*============================================================================ -* QP/C Real-Time Embedded Framework (RTEF) -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2022-04-09 -* @version Last updated for: @ref qpc_7_0_0 -* -* @file -* @brief QEP/C port, GNU-ARM compiler -*/ -#ifndef QEP_PORT_H -#define QEP_PORT_H - -/*! no-return function specifier (GCC-ARM compiler) */ -#define Q_NORETURN __attribute__ ((noreturn)) void - -#include /* Exact-width types. WG14/N843 C99 Standard */ -#include /* Boolean type. WG14/N843 C99 Standard */ - -#include "qep.h" /* QEP platform-independent public interface */ - -#endif /* QEP_PORT_H */ - diff --git a/ports/arm-cm/qxk/gnu/qf_port.h b/ports/arm-cm/qxk/gnu/qf_port.h deleted file mode 100644 index c2ba3c92..00000000 --- a/ports/arm-cm/qxk/gnu/qf_port.h +++ /dev/null @@ -1,153 +0,0 @@ -/*============================================================================ -* QP/C Real-Time Embedded Framework (RTEF) -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2022-06-30 -* @version Last updated for: @ref qpc_7_0_1 -* -* @file -* @brief QF/C port to Cortex-M, dual-mode QXK kernel, GNU-ARM toolset -*/ -#ifndef QF_PORT_H -#define QF_PORT_H - -/* The maximum number of system clock tick rates */ -#define QF_MAX_TICK_RATE 2U - -/* QF interrupt disable/enable and log2()... */ -#if (__ARM_ARCH == 6) /* Cortex-M0/M0+/M1(v6-M, v6S-M)? */ - - /* The maximum number of active objects in the application, see NOTE1 */ - #define QF_MAX_ACTIVE 16U - - /* Cortex-M0/M0+/M1(v6-M, v6S-M) interrupt disabling policy, see NOTE2 */ - #define QF_INT_DISABLE() __asm volatile ("cpsid i") - #define QF_INT_ENABLE() __asm volatile ("cpsie i") - - /* QF critical section (save and restore interrupt status), see NOTE2 */ - #define QF_CRIT_STAT_TYPE uint32_t - #define QF_CRIT_ENTRY(primask_) \ - __asm volatile ("mrs %0,PRIMASK\n" "cpsid i" : "=r" (primask_) ::) - #define QF_CRIT_EXIT(primask_) \ - __asm volatile ("msr PRIMASK,%0" :: "r" (primask_) : ) - - /* CMSIS threshold for "QF-aware" interrupts, see NOTE2 and NOTE4 */ - #define QF_AWARE_ISR_CMSIS_PRI 0 - - /* hand-optimized LOG2 in assembly for Cortex-M0/M0+/M1(v6-M, v6S-M) */ - #define QF_LOG2(n_) QF_qlog2((uint32_t)(n_)) - -#else /* Cortex-M3/M4/M7 */ - - /* The maximum number of active objects in the application, see NOTE1 */ - #define QF_MAX_ACTIVE 32U - - /* Cortex-M3/M4/M7 alternative interrupt disabling with PRIMASK */ - #define QF_PRIMASK_DISABLE() __asm volatile ("cpsid i") - #define QF_PRIMASK_ENABLE() __asm volatile ("cpsie i") - - /* Cortex-M3/M4/M7 interrupt disabling policy, see NOTE3 and NOTE4 */ - #define QF_INT_DISABLE() __asm volatile (\ - "cpsid i\n" "msr BASEPRI,%0\n" "cpsie i" :: "r" (QF_BASEPRI) : ) - #define QF_INT_ENABLE() __asm volatile (\ - "msr BASEPRI,%0" :: "r" (0) : ) - - /* QF critical section (save and restore interrupt status), see NOTE5 */ - #define QF_CRIT_STAT_TYPE uint32_t - #define QF_CRIT_ENTRY(basepri_) do { \ - __asm volatile ("mrs %0,BASEPRI" : "=r" (basepri_) :: ); \ - __asm volatile ("cpsid i\n msr BASEPRI,%0\n cpsie i" \ - :: "r" (QF_BASEPRI) : ); \ - } while (false) - #define QF_CRIT_EXIT(basepri_) \ - __asm volatile ("msr BASEPRI,%0" :: "r" (basepri_) : ) - - /* BASEPRI threshold for "QF-aware" interrupts, see NOTE3 */ - #define QF_BASEPRI 0x3F - - /* CMSIS threshold for "QF-aware" interrupts, see NOTE5 */ - #define QF_AWARE_ISR_CMSIS_PRI (QF_BASEPRI >> (8 - __NVIC_PRIO_BITS)) - - /* Cortex-M3/M4/M7 provide the CLZ instruction for fast LOG2 */ - #define QF_LOG2(n_) ((uint_fast8_t)(32U - __builtin_clz((unsigned)(n_)))) - -#endif - -#define QF_CRIT_EXIT_NOP() __asm volatile ("isb") - -#include "qep_port.h" /* QEP port */ - -#if (__ARM_ARCH == 6) /* Cortex-M0/M0+/M1(v6-M, v6S-M)? */ - /* hand-optimized quick LOG2 in assembly */ - uint_fast8_t QF_qlog2(uint32_t x); -#endif /* Cortex-M0/M0+/M1(v6-M, v6S-M) */ - -#include "qxk_port.h" /* QXK dual-mode kernel port */ - -/***************************************************************************** -* NOTE1: -* The maximum number of active objects QF_MAX_ACTIVE can be increased -* up to 64U, if necessary. Here it is set to a lower level to save some RAM. -* -* NOTE2: -* On Cortex-M0/M0+/M1 (architecture v6-M, v6S-M), the interrupt disabling -* policy uses the PRIMASK register to disable interrupts globally. The -* QF_AWARE_ISR_CMSIS_PRI level is zero, meaning that all interrupts are -* "QF-aware". -* -* NOTE3: -* On Cortex-M3/M4/M7, the interrupt disable/enable policy uses the BASEPRI -* register (which is not implemented in Cortex-M0/M0+/M1) to disable -* interrupts only with priority lower than the threshold specified by the -* QF_BASEPRI macro. The interrupts with priorities above QF_BASEPRI (i.e., -* with numerical priority values lower than QF_BASEPRI) are NOT disabled in -* this method. These free-running interrupts have very low ("zero") latency, -* but they are not allowed to call any QF services, because QF is unaware -* of them ("QF-unaware" interrutps). Consequently, only interrupts with -* numerical values of priorities eqal to or higher than QF_BASEPRI -* ("QF-aware" interrupts ), can call QF services. -* -* NOTE4: -* The QF_AWARE_ISR_CMSIS_PRI macro is useful as an offset for enumerating -* the "QF-aware" interrupt priorities in the applications, whereas the -* numerical values of the "QF-aware" interrupts must be greater or equal to -* QF_AWARE_ISR_CMSIS_PRI. The values based on QF_AWARE_ISR_CMSIS_PRI can be -* passed directly to the CMSIS function NVIC_SetPriority(), which shifts -* them by (8 - __NVIC_PRIO_BITS) into the correct bit position, while -* __NVIC_PRIO_BITS is the CMSIS macro defining the number of implemented -* priority bits in the NVIC. Please note that the macro QF_AWARE_ISR_CMSIS_PRI -* is intended only for applications and is not used inside the QF port, which -* remains generic and not dependent on the number of implemented priority bits -* implemented in the NVIC. -* -* NOTE5: -* The selective disabling of "QF-aware" interrupts with the BASEPRI register -* has a problem on ARM Cortex-M7 core r0p1 (see ARM-EPM-064408, errata -* 837070). The workaround recommended by ARM is to surround MSR BASEPRI with -* the CPSID i/CPSIE i pair, which is implemented in the QF_INT_DISABLE() -* macro. This workaround works also for Cortex-M3/M4 cores. -*/ - -#endif /* QF_PORT_H */ - diff --git a/ports/arm-cm/qxk/gnu/qp_port.h b/ports/arm-cm/qxk/gnu/qp_port.h new file mode 100644 index 00000000..97556f4f --- /dev/null +++ b/ports/arm-cm/qxk/gnu/qp_port.h @@ -0,0 +1,247 @@ +//============================================================================ +// QP/C Real-Time Embedded Framework (RTEF) +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC . +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +//============================================================================ +//! @date Last updated on: 2023-09-07 +//! @version Last updated for: @ref qpc_7_3_0 +//! +//! @file +//! @brief QP/C port to ARM Cortex-M, dual-mode QXK kernel, GNU-ARM + +#ifndef QP_PORT_H_ +#define QP_PORT_H_ + +#include // Exact-width types. WG14/N843 C99 Standard +#include // Boolean type. WG14/N843 C99 Standard + +#ifdef QP_CONFIG +#include "qp_config.h" // external QP configuration +#endif + +// no-return function specifier (C11 Standard) +#define Q_NORETURN _Noreturn void + +// QF configuration for QXK -- data members of the QActive class... + +// QActive event-queue type used for AOs and eXtended threads. +#define QACTIVE_EQUEUE_TYPE QEQueue + +// QActive OS-Object type used for the private stack pointer for eXtended threads. +// (The private stack pointer is NULL for basic-threads). +#define QACTIVE_OS_OBJ_TYPE void* + +// QActive "thread" type used to store the MPU settings in the AO +#define QACTIVE_THREAD_TYPE void const * + +// QF interrupt disable/enable and log2()... +#if (__ARM_ARCH == 6) // ARMv6-M? + + // Cortex-M0/M0+/M1(v6-M, v6S-M) interrupt disabling policy, see NOTE2 + #define QF_INT_DISABLE() __asm volatile ("cpsid i" ::: "memory") + #define QF_INT_ENABLE() __asm volatile ("cpsie i" ::: "memory") + + // QF critical section (save and restore interrupt status), see NOTE2 + #define QF_CRIT_STAT uint32_t primask_; + #define QF_CRIT_ENTRY() __asm volatile (\ + "mrs %0,PRIMASK\n" "cpsid i" : "=r" (primask_) :: "memory") + #define QF_CRIT_EXIT() __asm volatile (\ + "msr PRIMASK,%0" :: "r" (primask_) : "memory") + + // CMSIS threshold for "QF-aware" interrupts, see NOTE2 and NOTE4 + #define QF_AWARE_ISR_CMSIS_PRI 0 + + // hand-optimized LOG2 in assembly for Cortex-M0/M0+/M1(v6-M, v6S-M) + #define QF_LOG2(n_) QF_qlog2((uint32_t)(n_)) + +#else // ARMv7-M or higher + + // ARMv7-M or higher alternative interrupt disabling with PRIMASK + #define QF_PRIMASK_DISABLE() __asm volatile ("cpsid i" ::: "memory") + #define QF_PRIMASK_ENABLE() __asm volatile ("cpsie i" ::: "memory") + + // ARMv7-M or higher interrupt disabling policy, see NOTE3 and NOTE4 + #define QF_INT_DISABLE() __asm volatile (\ + "cpsid i\n" "msr BASEPRI,%0\n" "cpsie i" \ + :: "r" (QF_BASEPRI) : "memory") + #define QF_INT_ENABLE() __asm volatile (\ + "msr BASEPRI,%0" :: "r" (0) : "memory") + + // QF critical section (save and restore interrupt status), see NOTE5 + #define QF_CRIT_STAT uint32_t basepri_; + #define QF_CRIT_ENTRY() do { \ + __asm volatile ("mrs %0,BASEPRI" : "=r" (basepri_) :: "memory"); \ + __asm volatile ("cpsid i\n msr BASEPRI,%0\n cpsie i" \ + :: "r" (QF_BASEPRI) : "memory"); \ + } while (false) + #define QF_CRIT_EXIT() \ + __asm volatile ("msr BASEPRI,%0" :: "r" (basepri_) : "memory") + + // BASEPRI threshold for "QF-aware" interrupts, see NOTE3 + #define QF_BASEPRI 0x3F + + // CMSIS threshold for "QF-aware" interrupts, see NOTE5 + #define QF_AWARE_ISR_CMSIS_PRI (QF_BASEPRI >> (8 - __NVIC_PRIO_BITS)) + + // ARMv7-M or higher provide the CLZ instruction for fast LOG2 + #define QF_LOG2(n_) ((uint_fast8_t)(32 - __builtin_clz((unsigned)(n_)))) + +#endif + +#define QF_CRIT_EXIT_NOP() __asm volatile ("isb" ::: "memory") + +#if (__ARM_ARCH == 6) // ARMv6-M? + // hand-optimized quick LOG2 in assembly + uint_fast8_t QF_qlog2(uint32_t x); +#endif // ARMv7-M or higher + +// Memory isolation ---------------------------------------------------------- +#ifdef QF_MEM_ISOLATE + + // Memory isolation requires the context-switch + #define QF_ON_CONTEXT_SW 1U + + // Memory System setting + #define QF_MEM_SYS() QF_onMemSys() + + // Memory Application setting + #define QF_MEM_APP() QF_onMemApp() + + // callback functions for memory settings (provided by applications) + void QF_onMemSys(void); + void QF_onMemApp(void); + +#endif // def QF_MEM_ISOLATE + +// determination if the code executes in the ISR context +#define QXK_ISR_CONTEXT_() (QXK_get_IPSR() != 0U) + +__attribute__((always_inline)) +static inline uint32_t QXK_get_IPSR(void) { + uint32_t regIPSR; + __asm volatile ("mrs %0,ipsr" : "=r" (regIPSR)); + return regIPSR; +} + +// trigger the PendSV exception to perform the context switch +#define QXK_CONTEXT_SWITCH_() \ + *Q_UINT2PTR_CAST(uint32_t, 0xE000ED04U) = (1U << 28U) + +// QXK ISR entry and exit +#define QXK_ISR_ENTRY() ((void)0) + +#ifdef QF_MEM_ISOLATE + #define QXK_ISR_EXIT() do { \ + QF_INT_DISABLE(); \ + QF_MEM_SYS(); \ + if (QXK_sched_() != 0U) { \ + *Q_UINT2PTR_CAST(uint32_t, 0xE000ED04U) = (1U << 28U);\ + } \ + QF_MEM_APP(); \ + QF_INT_ENABLE(); \ + QXK_ARM_ERRATUM_838869(); \ + } while (false) +#else + #define QXK_ISR_EXIT() do { \ + QF_INT_DISABLE(); \ + if (QXK_sched_() != 0U) { \ + *Q_UINT2PTR_CAST(uint32_t, 0xE000ED04U) = (1U << 28U);\ + } \ + QF_INT_ENABLE(); \ + QXK_ARM_ERRATUM_838869(); \ + } while (false) +#endif + +#if (__ARM_ARCH == 6) // ARMv6-M? + #define QXK_ARM_ERRATUM_838869() ((void)0) +#else // ARMv7-M or higher + // The following macro implements the recommended workaround for the + // ARM Erratum 838869. Specifically, for Cortex-M3/M4/M7 the DSB + // (memory barrier) instruction needs to be added before exiting an ISR. + #define QXK_ARM_ERRATUM_838869() \ + __asm volatile ("dsb" ::: "memory") + +#endif // ARMv6-M + +// initialization of the QXK kernel +#define QXK_INIT() QXK_init() +void QXK_init(void); +void QXK_thread_ret(void); + +#ifdef __ARM_FP //--------- if VFP available... +// When the FPU is configured, clear the FPCA bit in the CONTROL register +// to prevent wasting the stack space for the FPU context. +#define QXK_START() __asm volatile ("msr CONTROL,%0" :: "r" (0) : ) +#endif + +// include files ------------------------------------------------------------- +#include "qequeue.h" // QXK kernel uses the native QP event queue +#include "qmpool.h" // QXK kernel uses the native QP memory pool +#include "qp.h" // QP framework +#include "qxk.h" // QXK kernel + +//============================================================================ +// NOTE2: +// On Cortex-M0/M0+/M1 (architecture v6-M, v6S-M), the interrupt disabling +// policy uses the PRIMASK register to disable interrupts globally. The +// QF_AWARE_ISR_CMSIS_PRI level is zero, meaning that all interrupts are +// "QF-aware". +// +// NOTE3: +// On ARMv7-M or higher, the interrupt disable/enable policy uses the BASEPRI +// register (which is not implemented in Cortex-M0/M0+/M1) to disable +// interrupts only with priority lower than the threshold specified by the +// QF_BASEPRI macro. The interrupts with priorities above QF_BASEPRI (i.e., +// with numerical priority values lower than QF_BASEPRI) are NOT disabled in +// this method. These free-running interrupts have very low ("zero") latency, +// but they are not allowed to call any QF services, because QF is unaware +// of them ("QF-unaware" interrupts). Consequently, only interrupts with +// numerical values of priorities equal to or higher than QF_BASEPRI +// ("QF-aware" interrupts ), can call QF services. +// +// NOTE4: +// The QF_AWARE_ISR_CMSIS_PRI macro is useful as an offset for enumerating +// the "QF-aware" interrupt priorities in the applications, whereas the +// numerical values of the "QF-aware" interrupts must be greater or equal to +// QF_AWARE_ISR_CMSIS_PRI. The values based on QF_AWARE_ISR_CMSIS_PRI can be +// passed directly to the CMSIS function NVIC_SetPriority(), which shifts +// them by (8 - __NVIC_PRIO_BITS) into the correct bit position, while +// __NVIC_PRIO_BITS is the CMSIS macro defining the number of implemented +// priority bits in the NVIC. Please note that the macro QF_AWARE_ISR_CMSIS_PRI +// is intended only for applications and is not used inside the QF port, which +// remains generic and not dependent on the number of implemented priority bits +// implemented in the NVIC. +// +// NOTE5: +// The selective disabling of "QF-aware" interrupts with the BASEPRI register +// has a problem on ARM Cortex-M7 core r0p1 (see ARM-EPM-064408, errata +// 837070). The workaround recommended by ARM is to surround MSR BASEPRI with +// the CPSID i/CPSIE i pair, which is implemented in the QF_INT_DISABLE() +// macro. This workaround works also for Cortex-M3/M4 cores. + +#endif // QP_PORT_H_ + diff --git a/ports/arm-cm/qxk/gnu/qs_port.h b/ports/arm-cm/qxk/gnu/qs_port.h index e8b00882..016fa909 100644 --- a/ports/arm-cm/qxk/gnu/qs_port.h +++ b/ports/arm-cm/qxk/gnu/qs_port.h @@ -1,60 +1,61 @@ -/*============================================================================ -* QP/C Real-Time Embedded Framework (RTEF) -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2022-06-12 -* @version Last updated for: @ref qpc_7_0_1 -* -* @file -* @brief QS/C port to a 32-bit CPU and a generic C99 compiler. -* @description -* This is an example of a QP/C port with the documentation for the -* configuration macros and includes. -*/ -#ifndef QS_PORT_H -#define QS_PORT_H +//============================================================================ +// QP/C Real-Time Embedded Framework (RTEF) +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +//============================================================================ +//! @date Last updated on: 2023-08-16 +//! @version Last updated for: @ref qpc_7_3_0 +//! +//! @file +//! @brief QS/C port to a 32-bit CPU and a generic C11 compiler. -/* QS time-stamp size in bytes */ -#define QS_TIME_SIZE 4 +#ifndef QS_PORT_H_ +#define QS_PORT_H_ -/* object pointer size in bytes */ -#define QS_OBJ_PTR_SIZE 4 +// QS time-stamp size in bytes +#define QS_TIME_SIZE 4U -/* function pointer size in bytes */ -#define QS_FUN_PTR_SIZE 4 +// object pointer size in bytes +#define QS_OBJ_PTR_SIZE 4U -/*==========================================================================*/ -/* NOTE: QS might be used with or without other QP components, in which -* case the separate definitions of the macros QF_CRIT_STAT_TYPE, -* QF_CRIT_ENTRY, and QF_CRIT_EXIT are needed. In this port QS is configured -* to be used with the other QP component, by simply including "qf_port.h" -* *before* "qs.h". -*/ -#ifndef QF_PORT_H -#include "qf_port.h" /* use QS with QF */ +// function pointer size in bytes +#define QS_FUN_PTR_SIZE 4U + +//============================================================================ +// NOTE: QS might be used with or without other QP components, in which +// case the separate definitions of the macros QF_CRIT_STAT, QF_CRIT_ENTRY(), +// and QF_CRIT_EXIT() are needed. In this port QS is configured to be used +// with the other QP component, by simply including "qp_port.h" +//*before* "qs.h". +#ifndef QP_PORT_H_ +#include "qp_port.h" // use QS with QP #endif -#include "qs.h" /* QS platform-independent public interface */ +#include "qs.h" // QS platform-independent public interface + +#endif // QS_PORT_H_ -#endif /* QS_PORT_H */ diff --git a/ports/arm-cm/qxk/gnu/qxk_port.c b/ports/arm-cm/qxk/gnu/qxk_port.c index fafe3dab..663733cc 100644 --- a/ports/arm-cm/qxk/gnu/qxk_port.c +++ b/ports/arm-cm/qxk/gnu/qxk_port.c @@ -1,616 +1,617 @@ -/*============================================================================ -* QP/C Real-Time Embedded Framework (RTEF) -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2023-01-14 -* @version Last updated for: @ref qpc_7_2_1 -* -* @file -* @brief QXK/C port to ARM Cortex-M, GNU-ARM toolset -*/ -/* This QXK port is part of the internal QP implementation */ +//============================================================================ +// QP/C Real-Time Embedded Framework (RTEF) +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +//============================================================================ +//! @date Last updated on: 2023-08-16 +//! @version Last updated for: @ref qpc_7_3_0 +//! +//! @file +//! @brief QXK/C port to ARM Cortex-M, GNU-ARM + #define QP_IMPL 1U -#include "qf_port.h" -#include "qf_pkg.h" -#include "qassert.h" +#include "qp_port.h" +#include "qp_pkg.h" +#include "qsafe.h" // QP Functional Safety (FuSa) System -#include /* for offsetof() */ +#include // for offsetof() -/* prototypes --------------------------------------------------------------*/ -void PendSV_Handler(void); -#ifdef QXK_USE_IRQ_HANDLER /* if use IRQ... */ -void QXK_USE_IRQ_HANDLER(void); -#else /* use default (NMI) */ -void NMI_Handler(void); -#endif +//============================================================================ +// NOTE: keep in synch with struct QXK_Attr in "qxk.h" !!! +#define QXK_CURR 0 +#define QXK_NEXT 4 +#define QXK_ACT_PRIO 12 -#define SCnSCB_ICTR ((uint32_t volatile *)0xE000E004U) -#define SCB_SYSPRI ((uint32_t volatile *)0xE000ED14U) -#define NVIC_EN ((uint32_t volatile *)0xE000E100U) -#define NVIC_IP ((uint8_t volatile *)0xE000E400U) -#define FPU_FPCCR *((uint32_t volatile *)0xE000EF34U) -#define NVIC_PEND 0xE000E200 -#define NVIC_ICSR 0xE000ED04 +// make sure that the offsets match the QXK declaration in "qxk.h" +_Static_assert(QXK_CURR == offsetof(QXK_Attr, curr), + "QXK_Attr.curr at unexpected offset"); +_Static_assert(QXK_NEXT == offsetof(QXK_Attr, next), + "QXK_Attr.next at unexpected offset"); +_Static_assert(QXK_ACT_PRIO == offsetof(QXK_Attr, actPrio), + "QXK_Attr.actPrio at unexpected offset"); -/*..........................................................................*/ -/* Initialize the exception priorities and IRQ priorities to safe values. -* -* Description: -* On ARMv7-M or higher, this QXK port disables interrupts by means of the -* BASEPRI register. However, this method cannot disable interrupt -* priority zero, which is the default for all interrupts out of reset. -* The following code changes the SysTick priority and all IRQ priorities -* to the safe value QF_BASEPRI, which the QF critical section can disable. -* This avoids breaching of the QF critical sections in case the -* application programmer forgets to explicitly set priorities of all -* "kernel aware" interrupts. -* -* The interrupt priorities established in QXK_init() can be later -* changed by the application-level code. -*/ -void QXK_init(void) { +// offsets within struct QActive; NOTE: keep in synch with "qp.h" !!! +#define QACTIVE_OSOBJ 28 +#define QACTIVE_PRIO 36 -#if (__ARM_ARCH != 6) /*--------- if ARMv7-M and higher... */ +// make sure that the offsets match the QActvie declaration in "qp.h" +_Static_assert(QACTIVE_OSOBJ == offsetof(QActive, osObject), + "QActive.osObject at unexpected offset"); +_Static_assert(QACTIVE_PRIO == offsetof(QActive, prio), + "QActive.prio at unexpected offset"); - /* set exception priorities to QF_BASEPRI... - * SCB_SYSPRI1: Usage-fault, Bus-fault, Memory-fault - */ - SCB_SYSPRI[1] = (SCB_SYSPRI[1] - | (QF_BASEPRI << 16U) | (QF_BASEPRI << 8U) | QF_BASEPRI); +// helper macros to "stringify" values +#define VAL(x) #x +#define STRINGIFY(x) VAL(x) - /* SCB_SYSPRI2: SVCall */ - SCB_SYSPRI[2] = (SCB_SYSPRI[2] | (QF_BASEPRI << 24U)); - - /* SCB_SYSPRI3: SysTick, PendSV, Debug */ - SCB_SYSPRI[3] = (SCB_SYSPRI[3] - | (QF_BASEPRI << 24U) | (QF_BASEPRI << 16U) | QF_BASEPRI); - - /* set all implemented IRQ priories to QF_BASEPRI... */ - uint8_t nprio = (8U + ((*SCnSCB_ICTR & 0x7U) << 3U)) * 4U; - for (uint8_t n = 0U; n < nprio; ++n) { - NVIC_IP[n] = QF_BASEPRI; - } - -#endif /*--------- ARMv7-M or higher */ - - /* SCB_SYSPRI3: PendSV set to priority 0xFF (lowest) */ - SCB_SYSPRI[3] = (SCB_SYSPRI[3] | (0xFFU << 16U)); - -#ifdef QXK_USE_IRQ_NUM /*--------- QXK IRQ specified? */ - /* The QXK port is configured to use a given ARM Cortex-M IRQ # - * to return to thread mode (default is to use the NMI exception) - */ - NVIC_IP[QXK_USE_IRQ_NUM] = 0U; /* priority 0 (highest) */ - NVIC_EN[QXK_USE_IRQ_NUM >> 5U] = (1U << (QXK_USE_IRQ_NUM & 0x1FU)); -#endif /*--------- QXK IRQ specified */ - -#if (__ARM_FP != 0) /*--------- if VFP available... */ - /* configure the FPU for QK */ - FPU_FPCCR |= (1U << 30U) /* automatic FPU state preservation (ASPEN) */ - | (1U << 31U); /* lazy stacking (LSPEN) */ -#endif /*--------- VFP available */ -} - -/*==========================================================================*/ -/* Initialize the private stack of an extended QXK thread. -* -* NOTE: the function aligns the stack to the 8-byte boundary for compatibility -* with the AAPCS. Additionally, the function pre-fills the stack with the -* known bit pattern (0xDEADBEEF). -* -* NOTE: QXK_stackInit_() must be called before the QXK kernel is made aware -* of this thread. In that case the kernel cannot use the thread yet, so no -* critical section is needed. -*/ -void QXK_stackInit_(void *thr, QXThreadHandler const handler, +//============================================================================ +// Initialize the private stack of an extended QXK thread. +// +// NOTE +// The function aligns the stack to the 8-byte boundary for compatibility +// with the AAPCS. Additionally, the function pre-fills the stack with the +// known bit pattern (0xDEADBEEF). +// +// NOTE: QXK_stackInit_() must be called before the QXK kernel is made aware +// of this thread. In that case the kernel cannot use the thread yet, so no +// critical section is needed. +void QXThread_stackInit_(QActive *me, QXThreadHandler const handler, void * const stkSto, uint_fast16_t const stkSize) { - /* round down the stack top to the 8-byte boundary - * NOTE: ARM Cortex-M stack grows down from hi -> low memory - */ + // round down the stack top to the 8-byte boundary + // NOTE: ARM Cortex-M stack grows down from hi -> low memory uint32_t *sp = (uint32_t *)((((uint32_t)stkSto + stkSize) >> 3U) << 3U); uint32_t *sp_limit; - /* synthesize the ARM Cortex-M exception stack frame...*/ - *(--sp) = (1U << 24); /* xPSR (just the THUMB bit) */ - *(--sp) = (uint32_t)handler; /* PC (the thread handler) */ - *(--sp) = (uint32_t)&QXK_threadExit_; /* LR (exit from thread) */ - *(--sp) = 0x0000000CU; /* R12 */ - *(--sp) = 0x00000003U; /* R3 */ - *(--sp) = 0x00000002U; /* R2 */ - *(--sp) = 0x00000001U; /* R1 */ - *(--sp) = (uint32_t)thr; /* R0 parameter to the handler (thread object) */ - *(--sp) = 0x0000000BU; /* R11 */ - *(--sp) = 0x0000000AU; /* R10 */ - *(--sp) = 0x00000009U; /* R9 */ - *(--sp) = 0x00000008U; /* R8 */ - *(--sp) = 0x00000007U; /* R7 */ - *(--sp) = 0x00000006U; /* R6 */ - *(--sp) = 0x00000005U; /* R5 */ - *(--sp) = 0x00000004U; /* R4 */ + // synthesize the ARM Cortex-M exception stack frame... + *(--sp) = (1U << 24); // xPSR (just the THUMB bit) + *(--sp) = (uint32_t)handler; // PC (the thread handler) + *(--sp) = (uint32_t)&QXK_threadExit_; // LR (exit from thread) + *(--sp) = 0x0000000CU; // R12 + *(--sp) = 0x00000003U; // R3 + *(--sp) = 0x00000002U; // R2 + *(--sp) = 0x00000001U; // R1 + *(--sp) = (uint32_t)me; // R0 parameter to handler (thread object) + *(--sp) = 0x0000000BU; // R11 + *(--sp) = 0x0000000AU; // R10 + *(--sp) = 0x00000009U; // R9 + *(--sp) = 0x00000008U; // R8 + *(--sp) = 0x00000007U; // R7 + *(--sp) = 0x00000006U; // R6 + *(--sp) = 0x00000005U; // R5 + *(--sp) = 0x00000004U; // R4 -#if (__ARM_FP != 0) /* if VFP available... */ - *(--sp) = 0xFFFFFFFDU; /* exception return with VFP state */ - *(--sp) = 0xAAAAAAAAU; /* stack "aligner" */ -#endif /* VFP available */ +#ifdef __ARM_FP //--------- if VFP available... + *(--sp) = 0xFFFFFFFDU; // exception return with VFP state + *(--sp) = 0xAAAAAAAAU; // stack "aligner" +#endif // VFP available - /* save the top of the stack in the thread's attribute */ - ((QActive *)thr)->osObject = sp; + // save the top of the stack in the thread's attribute + me->osObject = sp; - /* pre-fill the unused part of the stack with 0xDEADBEEF */ + // pre-fill the unused part of the stack with 0xDEADBEEF sp_limit = (uint32_t *)(((((uint32_t)stkSto - 1U) >> 3U) + 1U) << 3U); for (; sp >= sp_limit; --sp) { *sp = 0xDEADBEEFU; } } -/* NOTE: keep in synch with struct QXK_Attr in "qxk.h" !!! */ -#define QXK_CURR 0 -#define QXK_NEXT 4 -#define QXK_ACT_PRIO 12 +// prototypes ---------------------------------------------------------------- +void PendSV_Handler(void); +#ifdef QXK_USE_IRQ_HANDLER // if use IRQ... +void QXK_USE_IRQ_HANDLER(void); +#else // use default (NMI) +void NMI_Handler(void); +#endif -/* make sure that the offsets match the QXK declaration in "qxk.h" */ -Q_ASSERT_STATIC(QXK_CURR == offsetof(QXK, curr)); -Q_ASSERT_STATIC(QXK_NEXT == offsetof(QXK, next)); -Q_ASSERT_STATIC(QXK_ACT_PRIO == offsetof(QXK, actPrio)); +#define SCB_SYSPRI ((uint32_t volatile *)0xE000ED18U) +#define NVIC_EN ((uint32_t volatile *)0xE000E100U) +#define NVIC_IP ((uint32_t volatile *)0xE000E400U) +#define SCB_CPACR *((uint32_t volatile *)0xE000ED88U) +#define FPU_FPCCR *((uint32_t volatile *)0xE000EF34U) +#define NVIC_PEND 0xE000E200 +#define SCB_ICSR 0xE000ED04 -/* offsets within struct QActive; NOTE: keep in synch with "qf.h" !!! */ -#define QACTIVE_OSOBJ 28 -#define QACTIVE_PRIO 36 +//............................................................................ +// Initialize the exception priorities and IRQ priorities to safe values. +// +// Description: +// On ARMv7-M or higher, this QXK port disables interrupts by means of the +// BASEPRI register. However, this method cannot disable interrupt +// priority zero, which is the default for all interrupts out of reset. +// The following code changes the SysTick priority and all IRQ priorities +// to the safe value QF_BASEPRI, which the QF critical section can disable. +// This avoids breaching of the QF critical sections in case the +// application programmer forgets to explicitly set priorities of all +// "kernel aware" interrupts. +// +// The interrupt priorities established in QXK_init() can be later +// changed by the application-level code. +void QXK_init(void) { -/* make sure that the offsets match the QXK declaration in "qf.h" */ -Q_ASSERT_STATIC(QACTIVE_OSOBJ == offsetof(QActive, osObject)); -Q_ASSERT_STATIC(QACTIVE_PRIO == offsetof(QActive, prio)); +#if (__ARM_ARCH != 6) //--------- if ARMv7-M and higher... -/* helper macros to "stringify" values */ -#define VAL(x) #x -#define STRINGIFY(x) VAL(x) + // SCB_SYSPRI[2]: SysTick + SCB_SYSPRI[2] = (SCB_SYSPRI[2] | (QF_BASEPRI << 24U)); -/*==========================================================================*/ -/* The PendSV_Handler exception handler is used for performing asynchronous -* preemption in QXK. The use of the PendSV exception is the recommended and -* most efficient method for performing context switches in ARM Cortex-M. -* -* The PendSV exception should have the lowest interrupt priority in the system -* (0xFF, see QXK_init()). All other exceptions and interrupts should have -* higher interrupt priority. -* -* Also, *all* "kernel aware" ISRs in the QXK application must call the -* QXK_ISR_EXIT() macro, which triggers PendSV when it detects a need for -* asynchronous preemption. -* -* Due to tail-chaining and its lowest priority, the PendSV exception will be -* entered immediately after the exit from the *last* nested interrupt (or -* exception). In QXK, this is exactly the time when the QXK activator needs to -* handle the asynchronous preemption. -* -* NOTE: -* The inline GNU assembler does not accept mnemonics MOVS, LSRS and ADDS, -* but for Cortex-M0/M0+/M1 the mnemonics MOV, LSR and ADD always set the -* condition flags in the PSR. -*/ + // set all 240 possible IRQ priories to QF_BASEPRI... + for (uint_fast8_t n = 0U; n < (240U/sizeof(uint32_t)); ++n) { + NVIC_IP[n] = (QF_BASEPRI << 24U) | (QF_BASEPRI << 16U) + | (QF_BASEPRI << 8U) | QF_BASEPRI; + } + +#endif //--------- ARMv7-M or higher + + // SCB_SYSPRI[2]: PendSV set to priority 0xFF (lowest) + SCB_SYSPRI[2] = (SCB_SYSPRI[2] | (0xFFU << 16U)); + +#ifdef QXK_USE_IRQ_NUM //--------- QXK IRQ specified? + // The QXK port is configured to use a given ARM Cortex-M IRQ # + // to return to thread mode (default is to use the NMI exception) + NVIC_IP[QXK_USE_IRQ_NUM] = 0U; // priority 0 (highest) + NVIC_EN[QXK_USE_IRQ_NUM >> 5U] = (1U << (QXK_USE_IRQ_NUM & 0x1FU)); +#endif //--------- QXK IRQ specified + +#ifdef __ARM_FP //--------- if VFP available... + // make sure that the FPU is enabled by seting CP10 & CP11 Full Access + SCB_CPACR = (SCB_CPACR | ((3UL << 20U) | (3UL << 22U))); + + // FPU automatic state preservation (ASPEN) lazy stacking (LSPEN) + FPU_FPCCR = (FPU_FPCCR | (1U << 30U) | (1U << 31U)); +#endif //--------- VFP available +} + +//============================================================================ +// The PendSV_Handler exception handler is used for performing asynchronous +// preemption in QXK. The use of the PendSV exception is the recommended and +// most efficient method for performing context switches in ARM Cortex-M. +// +// The PendSV exception should have the lowest interrupt priority in the system +// (0xFF, see QXK_init()). All other exceptions and interrupts should have +// higher interrupt priority. +// +// Also, *all* "kernel aware" ISRs in the QXK application must call the +// QXK_ISR_EXIT() macro, which triggers PendSV when it detects a need for +// asynchronous preemption. +// +// Due to tail-chaining and its lowest priority, the PendSV exception will be +// entered immediately after the exit from the *last* nested interrupt (or +// exception). In QXK, this is exactly the time when the QXK activator needs to +// handle the asynchronous preemption. +// +// NOTE: +// The inline GNU assembler does not accept mnemonics MOVS, LSRS and ADDS, +// but for Cortex-M0/M0+/M1 the mnemonics MOV, LSR and ADD always set the +// condition flags in the PSR. __attribute__ ((naked, optimize("-fno-stack-protector"))) void PendSV_Handler(void) { __asm volatile ( - /* Prepare constants in registers before entering critical section */ - " LDR r3,=QXK_attr_ \n" - " LDR r2,=" STRINGIFY(NVIC_ICSR) "\n" /* Interrupt Control and State */ - " MOV r1,#1 \n" - " LSL r1,r1,#27 \n" /* r0 := (1 << 27) (UNPENDSVSET bit) */ - - /*<<<<<<<<<<<<<<<<<<<<<<< CRITICAL SECTION BEGIN <<<<<<<<<<<<<<<<<<<<<<<<*/ -#if (__ARM_ARCH == 6) /* if ARMv6-M... */ - " CPSID i \n" /* disable interrupts (set PRIMASK) */ -#else /* ARMv7-M or higher */ + //<<<<<<<<<<<<<<<<<<<<<<< CRITICAL SECTION BEGIN <<<<<<<<<<<<<<<<<<<<<<<< +#if (__ARM_ARCH == 6) // if ARMv6-M... + " CPSID i \n" // disable interrupts (set PRIMASK) +#else // ARMv7-M or higher " MOV r0,#" STRINGIFY(QF_BASEPRI) "\n" - " CPSID i \n" /* selectively disable interrupts with BASEPRI */ - " MSR BASEPRI,r0 \n" /* apply the workaround the Cortex-M7 erratum */ - " CPSIE i \n" /* 837070, see SDEN-1068427. */ -#endif /* ARMv7-M or higher */ + " CPSID i \n" // selectively disable interrupts with BASEPRI + " MSR BASEPRI,r0 \n" // apply the workaround the Cortex-M7 erratum + " CPSIE i \n" // 837070, see SDEN-1068427. +#endif // ARMv7-M or higher - /* The PendSV exception handler can be preempted by an interrupt, - * which might pend PendSV exception again. The following write to - * ICSR[27] un-pends any such spurious instance of PendSV. - */ - " STR r1,[r2] \n" /* ICSR[27] := 1 (unpend PendSV) */ +#ifdef QF_MEM_ISOLATE + " PUSH {r0,lr} \n" // save the "aligner" and the EXC_RETURN value + " LDR r0,=QF_onMemSys \n" + " BLX r0 \n" // call QF_onMemSys() + " POP {r0,r1} \n" // restore the aligner + lr into r1 + " MOV lr,r1 \n" // restore EXC_RETURN into lr +#endif - /* Check QXK_attr_.next, which contains the pointer to the next thread - * to run, which is set in QXK_ISR_EXIT(). This pointer must not be NULL. - */ - " LDR r0,[r3,#" STRINGIFY(QXK_NEXT) "]\n" /* r1 := QXK_attr_.next */ - " CMP r0,#0 \n" /* is (QXK_attr_.next == 0)? */ - " BEQ PendSV_return \n" /* branch if (QXK_attr_.next == 0) */ + // The PendSV exception handler can be preempted by an interrupt, + // which might pend PendSV exception again. The following write to + // ICSR[27] un-pends any such spurious instance of PendSV. + " MOV r1,#1 \n" + " LSL r1,r1,#27 \n" // r0 := (1 << 27) (UNPENDSVSET bit) + " LDR r2,=" STRINGIFY(SCB_ICSR) "\n" // Interrupt Control and State + " STR r1,[r2] \n" // ICSR[27] := 1 (unpend PendSV) - /* Load pointers into registers... */ - " MOV r12,r0 \n" /* save QXK_attr_.next in r12 */ - " LDR r2,[r0,#" STRINGIFY(QACTIVE_OSOBJ) "]\n" /* r2 := QXK_attr_.next->osObject */ - " LDR r1,[r3,#" STRINGIFY(QXK_CURR) "]\n" /* r1 := QXK_attr_.curr */ + // Check QXK_priv_.next, which contains the pointer to the next thread + // to run, which is set in QXK_ISR_EXIT(). This pointer must not be NULL. + " LDR r3,=QXK_priv_ \n" + " LDR r0,[r3,#" STRINGIFY(QXK_NEXT) "]\n" // r1 := QXK_priv_.next + " CMP r0,#0 \n" // is (QXK_priv_.next == 0)? + " BEQ PendSV_return \n" // branch if (QXK_priv_.next == 0) - " CMP r1,#0 \n" /* (QXK_attr_.curr != 0)? */ - " BNE PendSV_save_ex \n" /* branch if (current thread is extended) */ + // Load pointers into registers... + " MOV r12,r0 \n" // save QXK_priv_.next in r12 + " LDR r2,[r0,#" STRINGIFY(QACTIVE_OSOBJ) "]\n" // r2 := QXK_priv_.next->osObject + " LDR r1,[r3,#" STRINGIFY(QXK_CURR) "]\n" // r1 := QXK_priv_.curr - " CMP r2,#0 \n" /* (QXK_attr_.next->osObject != 0)? */ - " BNE PendSV_save_ao \n" /* branch if (next tread is extended) */ + " CMP r1,#0 \n" // (QXK_priv_.curr != 0)? + " BNE PendSV_save_ex \n" // branch if (current thread is extended) + + " CMP r2,#0 \n" // (QXK_priv_.next->osObject != 0)? + " BNE PendSV_save_ao \n" // branch if (next tread is extended) "PendSV_activate: \n" -#if (__ARM_FP != 0) /* if VFP available... */ - " TST lr,#(1 << 4) \n" /* is it return with the VFP exception frame? */ - " IT EQ \n" /* if lr[4] is zero... */ - " VSTMDBEQ sp!,{s16-s31} \n" /* ... save VFP registers s16..s31 */ - " PUSH {r0,lr} \n" /* save the "aligner" and the EXC_RETURN value */ -#endif /* VFP available */ - /* The QXK activator must be called in a thread context, while this code - * executes in the handler context of the PendSV exception. The switch - * to the Thread mode is accomplished by returning from PendSV using - * a fabricated exception stack frame, where the return address is - * QXK_activate_(). - * - * NOTE: the QXK activator is called with interrupts DISABLED and also - * it returns with interrupts DISABLED. - */ +#ifdef __ARM_FP //--------- if VFP available... + " TST lr,#(1 << 4) \n" // is it return with the VFP exception frame? + " IT EQ \n" // if lr[4] is zero... + " VSTMDBEQ sp!,{s16-s31} \n" // ... save VFP registers s16..s31 + " PUSH {r0,lr} \n" // save the "aligner" and the EXC_RETURN value +#endif // VFP available + // The QXK activator must be called in a thread context, while this code + // executes in the handler context of the PendSV exception. The switch + // to the Thread mode is accomplished by returning from PendSV using + // a fabricated exception stack frame, where the return address is + // QXK_activate_(). + // + // NOTE: the QXK activator is called with interrupts DISABLED and also + // it returns with interrupts DISABLED. " MOV r3,#1 \n" - " LSL r3,r3,#24 \n" /* r3 := (1 << 24), set the T bit (new xpsr) */ - " LDR r2,=QXK_activate_\n" /* address of QXK_activate_ */ - " SUB r2,r2,#1 \n" /* align Thumb-address at half-word (new pc) */ - " LDR r1,=QXK_thread_ret\n" /* return address after the call (new lr) */ + " LSL r3,r3,#24 \n" // r3 := (1 << 24), set T bit (new xpsr) + " LDR r2,=QXK_activate_\n" // address of QXK_activate_ + " SUB r2,r2,#1 \n" // align Thumb-address at half-word (new pc) + " LDR r1,=QXK_thread_ret\n" // return address after the call (new lr) - " SUB sp,sp,#(8*4) \n" /* reserve space for exception stack frame */ - " ADD r0,sp,#(5*4) \n" /* r0 := 5 registers below the top of stack */ - " STM r0!,{r1-r3} \n" /* save xpsr,pc,lr */ + " SUB sp,sp,#(8*4) \n" // reserve space for exception stack frame + " ADD r0,sp,#(5*4) \n" // r0 := 5 registers below the top of stack + " STM r0!,{r1-r3} \n" // save xpsr,pc,lr " MOV r0,#6 \n" - " MVN r0,r0 \n" /* r0 := ~6 == 0xFFFFFFF9 */ -#if (__ARM_ARCH != 6) /* ARMv7-M or higher */ - " DSB \n" /* ARM Erratum 838869 */ -#endif /* ARMv7-M or higher */ - " BX r0 \n" /* exception-return to the QXK activator */ + " MVN r0,r0 \n" // r0 := ~6 == 0xFFFFFFF9 +#if (__ARM_ARCH != 6) // ARMv7-M or higher + " DSB \n" // ARM Erratum 838869 +#endif // ARMv7-M or higher + " BX r0 \n" // exception-return to the QXK activator - /*========================================================================= - * Saving AO-thread before crossing to eXtended-thread - * expected register contents: - * r0 -> QXK_attr_.next / basic-thread - * r1 -> QXK_attr_.curr / basic-thread - * r2 -> QXK_attr_.next->osObject (SP) - * r3 -> &QXK_attr_ - * r12 -> QXK_attr_.next / basic-thread - */ + //======================================================================== + // Saving AO-thread before crossing to eXtended-thread + // expected register contents: + // r0 -> QXK_priv_.next / basic-thread + // r1 -> QXK_priv_.curr / basic-thread + // r2 -> QXK_priv_.next->osObject (SP) + // r3 -> &QXK_priv_ + // r12 -> QXK_priv_.next / basic-thread "PendSV_save_ao: \n" -#if (__ARM_ARCH == 6) /* if ARMv6-M... */ - " SUB sp,sp,#(8*4) \n" /* make room for 8 registers r4-r11 */ - " MOV r0,sp \n" /* r0 := temporary stack pointer */ - " STMIA r0!,{r4-r7} \n" /* save the low registers */ - " MOV r4,r8 \n" /* move the high registers to low registers... */ +#if (__ARM_ARCH == 6) // if ARMv6-M... + " SUB sp,sp,#(8*4) \n" // make room for 8 registers r4-r11 + " MOV r0,sp \n" // r0 := temporary stack pointer + " STMIA r0!,{r4-r7} \n" // save the low registers + " MOV r4,r8 \n" // move the high registers to low registers... " MOV r5,r9 \n" " MOV r6,r10 \n" " MOV r7,r11 \n" - " STMIA r0!,{r4-r7} \n" /* save the high registers */ - " MOV r0,r12 \n" /* restore QXK_attr_.next in r0 */ -#else /* ARMv7-M or higher */ - " PUSH {r4-r11} \n" /* save r4-r11 on top of the exception frame */ -#if (__ARM_FP != 0) /* if VFP available... */ - " TST lr,#(1 << 4) \n" /* is it return with the VFP exception frame? */ - " IT EQ \n" /* if lr[4] is zero... */ - " VSTMDBEQ sp!,{s16-s31} \n" /* ... save VFP registers s16..s31 */ - " PUSH {r0,lr} \n" /* save the "aligner" and the EXC_RETURN value */ -#endif /* VFP available */ -#endif /* ARMv7-M or higher */ + " STMIA r0!,{r4-r7} \n" // save the high registers + " MOV r0,r12 \n" // restore QXK_priv_.next in r0 +#else // ARMv7-M or higher + " PUSH {r4-r11} \n" // save r4-r11 on top of the exception frame +#ifdef __ARM_FP //--------- if VFP available... + " TST lr,#(1 << 4) \n" // is it return with the VFP exception frame? + " IT EQ \n" // if lr[4] is zero... + " VSTMDBEQ sp!,{s16-s31} \n" // ... save VFP registers s16..s31 + " PUSH {r0,lr} \n" // save the "aligner" and the EXC_RETURN value +#endif // VFP available +#endif // ARMv7-M or higher " CMP r2,#0 \n" - " BNE PendSV_restore_ex\n" /* branch if (QXK_attr_.next->osObject != 0) */ - /* otherwise continue to restoring next AO-thread... */ + " BNE PendSV_restore_ex\n" // branch if (QXK_priv_.next->osObject != 0) + // otherwise continue to restoring next AO-thread... - /*------------------------------------------------------------------------- - * Restoring AO-thread after crossing from eXtended-thread - * expected register contents: - * r1 -> QXK_attr_.curr / basic-thread - * r2 -> QXK_attr_.next->osObject (SP) - * r3 -> &QXK_attr_ - * r12 -> QXK_attr_.next / basic-thread - */ + //------------------------------------------------------------------------ + // Restoring AO-thread after crossing from eXtended-thread + // expected register contents: + // r1 -> QXK_priv_.curr / basic-thread + // r2 -> QXK_priv_.next->osObject (SP) + // r3 -> &QXK_priv_ + // r12 -> QXK_priv_.next / basic-thread "PendSV_restore_ao: \n" - /* don NOT clear QXK_attr_.curr or QXK_attr_.next, - * as they might be needed for AO activation - */ + // don NOT clear QXK_priv_.curr or QXK_priv_.next, + // as they might be needed for AO activation -#if (__ARM_ARCH == 6) /* if ARMv6-M... */ - " MOV r0,sp \n" /* r0 := top of stack */ +#if (__ARM_ARCH == 6) // if ARMv6-M... + " MOV r0,sp \n" // r0 := top of stack " MOV r2,r0 \n" - " ADD r2,r2,#(4*4) \n" /* point r2 to the 4 high registers r7-r11 */ - " LDMIA r2!,{r4-r7} \n" /* pop the 4 high registers into low registers */ - " MOV r8,r4 \n" /* move low registers into high registers */ + " ADD r2,r2,#(4*4) \n" // point r2 to the 4 high registers r7-r11 + " LDMIA r2!,{r4-r7} \n" // pop the 4 high registers into low registers + " MOV r8,r4 \n" // move low registers into high registers " MOV r9,r5 \n" " MOV r10,r6 \n" " MOV r11,r7 \n" - " LDMIA r0!,{r4-r7} \n" /* pop the low registers */ - " ADD sp,sp,#(8*4) \n" /* remove 8 registers from the stack */ + " LDMIA r0!,{r4-r7} \n" // pop the low registers + " ADD sp,sp,#(8*4) \n" // remove 8 registers from the stack " MOV r2,#6 \n" - " MVN r2,r2 \n" /* r2 := ~6 == 0xFFFFFFF9 */ - " MOV lr,r2 \n" /* make sure MSP is used */ -#else /* ARMv7-M or higher */ -#if (__ARM_FP != 0) /* if VFP available... */ - " POP {r0,lr} \n" /* restore alighner and EXC_RETURN into lr */ - " DSB \n" /* ARM Erratum 838869 */ - " TST lr,#(1 << 4) \n" /* is it return to the VFP exception frame? */ - " IT EQ \n" /* if EXC_RETURN[4] is zero... */ - " VLDMIAEQ sp!,{s16-s31} \n" /* ... restore VFP registers s16..s31 */ + " MVN r2,r2 \n" // r2 := ~6 == 0xFFFFFFF9 + " MOV lr,r2 \n" // make sure MSP is used +#else // ARMv7-M or higher +#ifdef __ARM_FP //--------- if VFP available... + " POP {r0,lr} \n" // restore alighner and EXC_RETURN into lr + " DSB \n" // ARM Erratum 838869 + " TST lr,#(1 << 4) \n" // is it return to the VFP exception frame? + " IT EQ \n" // if EXC_RETURN[4] is zero... + " VLDMIAEQ sp!,{s16-s31} \n" // ... restore VFP registers s16..s31 #else - " BIC lr,lr,#(1 << 2) \n" /* make sure MSP is used */ -#endif /* VFP available */ - " POP {r4-r11} \n" /* restore r4-r11 from the next thread's stack */ -#endif /* ARMv7-M or higher */ + " BIC lr,lr,#(1 << 2) \n" // make sure MSP is used +#endif // VFP available + " POP {r4-r11} \n" // restore r4-r11 from the next thread's stack +#endif // ARMv7-M or higher - " MOV r0,r12 \n" /* r0 := QXK_attr_.next */ - " MOV r2,#" STRINGIFY(QACTIVE_PRIO) "\n" /* r2 := offset of .prio */ - " LDRB r0,[r0,r2] \n" /* r0 := QXK_attr_.next->prio */ - " LDRB r2,[r3,#" STRINGIFY(QXK_ACT_PRIO) "]\n" /* r2 := QXK_attr_.actPrio */ + " MOV r0,r12 \n" // r0 := QXK_priv_.next + " MOV r2,#" STRINGIFY(QACTIVE_PRIO) "\n" // r2 := offset of .prio + " LDRB r0,[r0,r2] \n" // r0 := QXK_priv_.next->prio + " LDR r2,[r3,#" STRINGIFY(QXK_ACT_PRIO) "]\n" // r2 := QXK_priv_.actPrio " CMP r2,r0 \n" - " BCC PendSV_activate \n" /* if (next->prio > actPrio) activate the next AO */ + " BCC PendSV_activate \n" // if (next->prio > actPrio) activate the next AO - /* otherwise no activation needed... */ + // otherwise no activation needed... " MOV r0,#0 \n" - " STR r0,[r3,#" STRINGIFY(QXK_CURR) "]\n" /* QXK_attr_.curr := 0 */ - " STR r0,[r3,#" STRINGIFY(QXK_NEXT) "]\n" /* QXK_attr_.next := 0 */ + " STR r0,[r3,#" STRINGIFY(QXK_CURR) "]\n" // QXK_priv_.curr := 0 + " STR r0,[r3,#" STRINGIFY(QXK_NEXT) "]\n" // QXK_priv_.next := 0 #if defined(Q_SPY) || defined(QF_ON_CONTEXT_SW) - " MOV r0,#0 \n" /* r0 := 0 (next is basic) */ - " PUSH {r3,lr} \n" /* save QXK_attr_ + exception lr */ - " LDR r3,=QXK_contextSw \n" - " BLX r3 \n" /* call QXK_contextSw() */ - " POP {r0,r1} \n" /* restore the aligner + lr into r1 */ - " MOV lr,r1 \n" /* restore the exception lr */ -#endif /* defined(Q_SPY) || defined(QF_ON_CONTEXT_SW) */ + " MOV r0,#0 \n" // r0 := 0 (next is basic) + " PUSH {r0,lr} \n" // save the aligner + EXC_RETURN + " LDR r3,=QXK_contextSw_ \n" + " BLX r3 \n" // call QXK_contextSw_() +#ifdef QF_MEM_ISOLATE + " LDR r3,=QF_onMemApp \n" + " BLX r3 \n" // call QF_onMemApp() +#endif + " POP {r0,r1} \n" // restore the aligner + EXC_RETURN + " MOV lr,r1 \n" // restore EXC_RETURN into lr +#endif // defined(Q_SPY) || defined(QF_ON_CONTEXT_SW) - /* re-enable interrupts and return from PendSV */ + // re-enable interrupts and return from PendSV "PendSV_return: \n" -#if (__ARM_ARCH == 6) /* if ARMv6-M... */ - " CPSIE i \n" /* enable interrupts (clear PRIMASK) */ -#else /* ARMv7-M or higher */ +#if (__ARM_ARCH == 6) // if ARMv6-M... + " CPSIE i \n" // enable interrupts (clear PRIMASK) +#else // ARMv7-M or higher " MOV r0,#0 \n" - " MSR BASEPRI,r0 \n" /* enable interrupts (clear BASEPRI) */ - " DSB \n" /* ARM Erratum 838869 */ -#endif /* ARMv7-M or higher */ - /*>>>>>>>>>>>>>>>>>>>>>>>> CRITICAL SECTION END >>>>>>>>>>>>>>>>>>>>>>>>>*/ - " BX lr \n" /* return to the preempted AO-thread */ + " MSR BASEPRI,r0 \n" // enable interrupts (clear BASEPRI) + " DSB \n" // ARM Erratum 838869 +#endif // ARMv7-M or higher + //>>>>>>>>>>>>>>>>>>>>>>>> CRITICAL SECTION END >>>>>>>>>>>>>>>>>>>>>>>>> + " BX lr \n" // return to the preempted AO-thread - /*------------------------------------------------------------------------- - * Saving extended-thread - * expected register contents: - * r0 -> QXK_attr_.next / basic-thread - * r1 -> QXK_attr_.curr / basic-thread - * r2 -> QXK_attr_.next->osObject (SP) - * r3 -> &QXK_attr_ - * r12 -> QXK_attr_.next / basic-thread - */ + //------------------------------------------------------------------------ + // Saving extended-thread + // expected register contents: + // r0 -> QXK_priv_.next / basic-thread + // r1 -> QXK_priv_.curr / basic-thread + // r2 -> QXK_priv_.next->osObject (SP) + // r3 -> &QXK_priv_ + // r12 -> QXK_priv_.next / basic-thread "PendSV_save_ex: \n" - " MRS r0,PSP \n" /* r0 := Process Stack Pointer */ -#if (__ARM_ARCH == 6) /* if ARMv6-M... */ - " SUB r0,r0,#(8*4) \n" /* make room for 8 registers r4-r11 */ - " MOV r1,r0 \n" /* r1 := temporary PSP (do not clobber r0!) */ - " STMIA r1!,{r4-r7} \n" /* save the low registers */ - " MOV r4,r8 \n" /* move the high registers to low registers... */ + " MRS r0,PSP \n" // r0 := Process Stack Pointer +#if (__ARM_ARCH == 6) // if ARMv6-M... + " SUB r0,r0,#(8*4) \n" // make room for 8 registers r4-r11 + " MOV r1,r0 \n" // r1 := temporary PSP (do not clobber r0!) + " STMIA r1!,{r4-r7} \n" // save the low registers + " MOV r4,r8 \n" // move the high registers to low registers... " MOV r5,r9 \n" " MOV r6,r10 \n" " MOV r7,r11 \n" - " STMIA r1!,{r4-r7} \n" /* save the high registers */ - /* NOTE: at this point r0 holds the top of stack */ + " STMIA r1!,{r4-r7} \n" // save the high registers + // NOTE: at this point r0 holds the top of stack - " LDR r1,[r3,#" STRINGIFY(QXK_CURR) "]\n" /* r1 := QXK_attr_.curr (restore value) */ -#else /* ARMv7-M or higher */ - " ISB \n" /* reset pipeline after fetching PSP */ - " STMDB r0!,{r4-r11} \n" /* save r4-r11 on top of the exception frame */ -#if (__ARM_FP != 0) /* if VFP available... */ - " TST lr,#(1 << 4) \n" /* is it return with the VFP exception frame? */ - " IT EQ \n" /* if lr[4] is zero... */ - " VSTMDBEQ r0!,{s16-s31} \n" /* ... save VFP registers s16..s31 */ - " STMDB r0!,{r1,lr} \n" /* save the "aligner" and the EXC_RETURN value */ -#endif /* VFP available */ -#endif /* ARMv7-M or higher */ + " LDR r1,[r3,#" STRINGIFY(QXK_CURR) "]\n" // r1 := QXK_priv_.curr (restore value) +#else // ARMv7-M or higher + " ISB \n" // reset pipeline after fetching PSP + " STMDB r0!,{r4-r11} \n" // save r4-r11 on top of the exception frame +#ifdef __ARM_FP //--------- if VFP available... + " TST lr,#(1 << 4) \n" // is it return with the VFP exception frame? + " IT EQ \n" // if lr[4] is zero... + " VSTMDBEQ r0!,{s16-s31} \n" // ... save VFP registers s16..s31 + " STMDB r0!,{r1,lr} \n" // save the "aligner" and the EXC_RETURN value +#endif // VFP available +#endif // ARMv7-M or higher - /* store the SP of the current extended-thread */ - " STR r0,[r1,#" STRINGIFY(QACTIVE_OSOBJ) "]\n" /* QXK_attr_.curr->osObject := r0 */ - " MOV r0,r12 \n" /* QXK_attr_.next (restore value) */ + // store the SP of the current extended-thread + " STR r0,[r1,#" STRINGIFY(QACTIVE_OSOBJ) "]\n" // QXK_priv_.curr->osObject := r0 + " MOV r0,r12 \n" // QXK_priv_.next (restore value) " CMP r2,#0 \n" - " BEQ PendSV_restore_ao\n" /* branch if (QXK_attr_.next->osObject == 0) */ - /* otherwise continue to restoring next extended-thread... */ + " BEQ PendSV_restore_ao\n" // branch if (QXK_priv_.next->osObject == 0) + // otherwise continue to restoring next extended-thread... - /*------------------------------------------------------------------------- - * Restoring extended-thread - * expected register contents: - * r0 -> QXK_attr_.next / basic-thread - * r1 -> QXK_attr_.curr / basic-thread - * r2 -> QXK_attr_.next->osObject (SP) - * r3 -> &QXK_attr_ - * r12 -> QXK_attr_.next / basic-thread - */ + //------------------------------------------------------------------------ + // Restoring extended-thread + // expected register contents: + // r0 -> QXK_priv_.next / basic-thread + // r1 -> QXK_priv_.curr / basic-thread + // r2 -> QXK_priv_.next->osObject (SP) + // r3 -> &QXK_priv_ + // r12 -> QXK_priv_.next / basic-thread "PendSV_restore_ex: \n" -#if defined(Q_SPY) || defined(QF_ON_CONTEXT_SW) - " MOV r0,r12 \n" /* r0 := next */ - " PUSH {r3,lr} \n" /* save QXK_attr_ + exception lr */ - " LDR r3,=QXK_contextSw \n" - " BLX r3 \n" /* call QXK_contextSw() */ - " POP {r0,r1} \n" /* restore the aligner + lr into r1 */ - " MOV lr,r1 \n" /* restore the exception lr */ - " MOV r3,r0 \n" /* restore the saved QXK_attr_ in r3 */ - - /* restore the AAPCS-clobbered registers after a functin call... */ - " LDR r0,[r3,#" STRINGIFY(QXK_NEXT) "]\n" /* r0 := QXK_attr_.next */ - " LDR r2,[r0,#" STRINGIFY(QACTIVE_OSOBJ) "]\n" /* r2 := QXK_attr_.curr->osObject */ -#endif /* defined(Q_SPY) || defined(QF_ON_CONTEXT_SW) */ - - " STR r0,[r3,#" STRINGIFY(QXK_CURR) "]\n" /* QXK_attr_.curr := r0 (QXK_attr_.next) */ + " STR r0,[r3,#" STRINGIFY(QXK_CURR) "]\n" // QXK_priv_.curr := r0 (QXK_priv_.next) " MOV r0,#0 \n" - " STR r0,[r3,#" STRINGIFY(QXK_NEXT) "]\n" /* QXK_attr_.next := 0 */ + " STR r0,[r3,#" STRINGIFY(QXK_NEXT) "]\n" // QXK_priv_.next := 0 - /* exit the critical section */ -#if (__ARM_ARCH == 6) /* if ARMv6-M... */ - " CPSIE i \n" /* enable interrupts (clear PRIMASK) */ +#if defined(Q_SPY) || defined(QF_ON_CONTEXT_SW) + " MOV r0,r12 \n" // r0 := next + " PUSH {r0-r2,lr} \n" // save next, osObject, EXC_RETURN + " LDR r3,=QXK_contextSw_ \n" + " BLX r3 \n" // call QXK_contextSw_() +#ifdef QF_MEM_ISOLATE + " LDR r3,=QF_onMemApp \n" + " BLX r3 \n" // call QF_onMemApp() +#endif + " POP {r0-r3} \n" // restore next, osObject, EXC_RETURN + " MOV lr,r3 \n" // restore the EXC_RETURN into lr +#endif // defined(Q_SPY) || defined(QF_ON_CONTEXT_SW) - " MOV r0,r2 \n" /* r2 := top of stack */ - " ADD r0,r0,#(4*4) \n" /* point r0 to the 4 high registers r7-r11 */ - " LDMIA r0!,{r4-r7} \n" /* pop the 4 high registers into low registers */ - " MOV r8,r4 \n" /* move low registers into high registers */ + + // exit the critical section +#if (__ARM_ARCH == 6) // if ARMv6-M... + " CPSIE i \n" // enable interrupts (clear PRIMASK) + + " MOV r0,r2 \n" // r2 := top of stack + " ADD r0,r0,#(4*4) \n" // point r0 to the 4 high registers r7-r11 + " LDMIA r0!,{r4-r7} \n" // pop the 4 high registers into low registers + " MOV r8,r4 \n" // move low registers into high registers " MOV r9,r5 \n" " MOV r10,r6 \n" " MOV r11,r7 \n" - " LDMIA r2!,{r4-r7} \n" /* pop the low registers */ - " MOV r2,r0 \n" /* r2 := holds the new top of stack */ + " LDMIA r2!,{r4-r7} \n" // pop the low registers + " MOV r2,r0 \n" // r2 := holds the new top of stack " MOV r1,#2 \n" - " MVN r1,r1 \n" /* r1 := ~2 == 0xFFFFFFFD */ - " MOV lr,r1 \n" /* make sure PSP is used */ -#else /* ARMv7-M or higher */ + " MVN r1,r1 \n" // r1 := ~2 == 0xFFFFFFFD + " MOV lr,r1 \n" // make sure PSP is used +#else // ARMv7-M or higher " MOV r1,#0 \n" - " MSR BASEPRI,r1 \n" /* enable interrupts (clear BASEPRI) */ -#if (__ARM_FP != 0) /* if VFP available... */ - " LDMIA r2!,{r1,lr} \n" /* restore aligner and EXC_RETURN into lr */ - " TST lr,#(1 << 4) \n" /* is it return to the VFP exception frame? */ - " IT EQ \n" /* if lr[4] is zero... */ - " VLDMIAEQ r2!,{s16-s31} \n" /* ... restore VFP registers s16..s31 */ + " MSR BASEPRI,r1 \n" // enable interrupts (clear BASEPRI) +#ifdef __ARM_FP //--------- if VFP available... + " LDMIA r2!,{r1,lr} \n" // restore aligner and EXC_RETURN into lr + " TST lr,#(1 << 4) \n" // is it return to the VFP exception frame? + " IT EQ \n" // if lr[4] is zero... + " VLDMIAEQ r2!,{s16-s31} \n" // ... restore VFP registers s16..s31 #else - " ORR lr,lr,#(1 << 2) \n" /* make sure PSP is used */ -#endif /* VFP available */ - " LDMIA r2!,{r4-r11} \n" /* restore r4-r11 from the next thread's stack */ -#endif /* ARMv7-M or higher */ + " ORR lr,lr,#(1 << 2) \n" // make sure PSP is used +#endif // VFP available + " LDMIA r2!,{r4-r11} \n" // restore r4-r11 from the next thread's stack +#endif // ARMv7-M or higher - /* set the PSP to the next thread's SP */ - " MSR PSP,r2 \n" /* Process Stack Pointer := r2 */ + // set the PSP to the next thread's SP + " MSR PSP,r2 \n" // Process Stack Pointer := r2 -#if (__ARM_ARCH != 6) /* if ARMv7-M or higher... */ - " DSB \n" /* ARM Erratum 838869 */ -#endif /* ARMv7-M or higher */ - " BX lr \n" /* return to the next extended-thread */ +#if (__ARM_ARCH != 6) // if ARMv7-M or higher... + " DSB \n" // ARM Erratum 838869 +#endif // ARMv7-M or higher + " BX lr \n" // return to the next extended-thread ); } -/*==========================================================================*/ -/* QXK_thread_ret is a helper function executed when the QXK activator returns. -* -* NOTE: QXK_thread_ret does not execute in the PendSV context! -* NOTE: QXK_thread_ret is entered with interrupts DISABLED. -*/ +//============================================================================ +// QXK_thread_ret is a helper function executed when the QXK activator returns. +// +// NOTE: QXK_thread_ret does not execute in the PendSV context! +// NOTE: QXK_thread_ret is entered with interrupts DISABLED. __attribute__ ((naked, used, optimize("-fno-stack-protector"))) void QXK_thread_ret(void) { __asm volatile ( - /* After the QXK activator returns, we need to resume the preempted - * thread. However, this must be accomplished by a return-from-exception, - * while we are still in the thread context. The switch to the exception - * context is accomplished by triggering the NMI exception or the selected - * IRQ (if macro #QXK_USE_IRQ_NUM is defined). - */ + // After the QXK activator returns, we need to resume the preempted + // thread. However, this must be accomplished by a return-from-exception, + // while we are still in the thread context. The switch to the exception + // context is accomplished by triggering the NMI exception or the selected + // IRQ (if macro #QXK_USE_IRQ_NUM is defined). - /* before triggering the NMI/IRQ, make sure that the VFP stack frame - * will NOT be used... - */ -#if (__ARM_FP != 0) /*--------- if VFP available... */ - /* make sure that the VFP stack frame will NOT be used */ - " MRS r0,CONTROL \n" /* r0 := CONTROL */ - " BIC r0,r0,#4 \n" /* r0 := r0 & ~4 (FPCA bit) */ - " MSR CONTROL,r0 \n" /* CONTROL := r0 (clear CONTROL[2] FPCA bit) */ - " ISB \n" /* ISB after MSR CONTROL (ARM AN321,Sect.4.16) */ -#endif /*--------- VFP available */ + // before triggering the NMI/IRQ, make sure that the VFP stack frame + // will NOT be used... +#ifdef __ARM_FP //--------- if VFP available... + // make sure that the VFP stack frame will NOT be used + " MRS r0,CONTROL \n" // r0 := CONTROL + " BIC r0,r0,#4 \n" // r0 := r0 & ~4 (FPCA bit) + " MSR CONTROL,r0 \n" // CONTROL := r0 (clear CONTROL[2] FPCA bit) + " ISB \n" // ISB after MSR CONTROL (ARM AN321,Sect.4.16) +#endif //--------- VFP available -#ifndef QXK_USE_IRQ_NUM /*--------- IRQ NOT defined, use NMI by default */ - " LDR r0,=" STRINGIFY(NVIC_ICSR) "\n" /* Interrupt Control and State */ +#ifdef QF_MEM_ISOLATE + " PUSH {r0,lr} \n" // save the aligner + EXC_RETURN + " LDR r0,=QF_onMemApp \n" + " BLX r0 \n" // call QF_onMemApp() + " POP {r0,r1} \n" // restore the aligner + EXC_RETURN + " MOV lr,r1 \n" // restore EXC_RETURN into lr +#endif + +#ifndef QXK_USE_IRQ_NUM //--------- IRQ NOT defined, use NMI by default + " LDR r0,=" STRINGIFY(SCB_ICSR) "\n" // Interrupt Control and State " MOV r1,#1 \n" - " LSL r1,r1,#31 \n" /* r1 := (1 << 31) (NMI bit) */ - " STR r1,[r0] \n" /* ICSR[31] := 1 (pend NMI) */ + " LSL r1,r1,#31 \n" // r1 := (1 << 31) (NMI bit) + " STR r1,[r0] \n" // ICSR[31] := 1 (pend NMI) -#else /*--------- use the selected IRQ */ +#else //--------- use the selected IRQ " LDR r0,=" STRINGIFY(NVIC_PEND + ((QXK_USE_IRQ_NUM >> 5) << 2)) "\n" " MOV r1,#1 \n" - " LSL r1,r1,#" STRINGIFY(QXK_USE_IRQ_NUM & 0x1F) "\n" /* r1 := IRQ bit */ - " STR r1,[r0] \n" /* pend the IRQ */ + " LSL r1,r1,#" STRINGIFY(QXK_USE_IRQ_NUM & 0x1F) "\n" // r1 := IRQ bit + " STR r1,[r0] \n" // pend the IRQ - /* now enable interrupts so that pended IRQ can be entered */ -#if (__ARM_ARCH == 6) /*--------- if ARMv6-M... */ - " CPSIE i \n" /* enable interrupts (clear PRIMASK) */ -#else /*--------- ARMv7-M and higher */ + // now enable interrupts so that pended IRQ can be entered +#if (__ARM_ARCH == 6) //--------- if ARMv6-M... + " CPSIE i \n" // enable interrupts (clear PRIMASK) +#else //--------- ARMv7-M and higher " MOV r0,#0 \n" - " MSR BASEPRI,r0 \n" /* enable interrupts (clear BASEPRI) */ -#endif /*--------- ARMv7-M and higher */ -#endif /*--------- use IRQ */ + " MSR BASEPRI,r0 \n" // enable interrupts (clear BASEPRI) +#endif //--------- ARMv7-M and higher +#endif //--------- use IRQ - /* NOTE! interrupts are still disabled when NMI is used */ - " B . \n" /* wait for preemption by NMI/IRQ */ + // NOTE! interrupts are still disabled when NMI is used + " B . \n" // wait for preemption by NMI/IRQ ); } -/*==========================================================================*/ -/* This exception handler is used for returning back to the preempted thread. -* The exception handler simply removes its own interrupt stack frame from -* the stack (MSP) and returns to the preempted task using the interrupt -* stack frame that must be at the top of the stack. -*/ +//============================================================================ +// This exception handler is used for returning back to the preempted thread. +// The exception handler simply removes its own interrupt stack frame from +// the stack (MSP) and returns to the preempted task using the interrupt +// stack frame that must be at the top of the stack. __attribute__ ((naked, optimize("-fno-stack-protector"))) -#ifndef QXK_USE_IRQ_NUM /*--------- IRQ NOT defined, use NMI by default */ +#ifndef QXK_USE_IRQ_NUM //--------- IRQ NOT defined, use NMI by default -/* NOTE: The NMI_Handler() is entered with interrupts still disabled! */ +// NOTE: The NMI_Handler() is entered with interrupts still disabled! void NMI_Handler(void) { __asm volatile ( - /* enable interrupts */ -#if (__ARM_ARCH == 6) /*--------- if ARMv6-M... */ - " CPSIE i \n" /* enable interrupts (clear PRIMASK) */ -#else /*--------- ARMv7-M and higher */ + // enable interrupts +#if (__ARM_ARCH == 6) //--------- if ARMv6-M... + " CPSIE i \n" // enable interrupts (clear PRIMASK) +#else //--------- ARMv7-M and higher " MOV r0,#0 \n" - " MSR BASEPRI,r0 \n" /* enable interrupts (clear BASEPRI) */ -#endif /*--------- ARMv7-M and higher */ + " MSR BASEPRI,r0 \n" // enable interrupts (clear BASEPRI) +#endif //--------- ARMv7-M and higher ); -#else /*--------- use the selected IRQ */ +#else //--------- use the selected IRQ -/* NOTE: The IRQ Handler is entered with interrupts enabled */ +// NOTE: The IRQ Handler is entered with interrupts enabled void QXK_USE_IRQ_HANDLER(void) { -#endif /*--------- use IRQ */ +#endif //--------- use IRQ __asm volatile ( - " ADD sp,sp,#(8*4) \n" /* remove one 8-register exception frame */ + " ADD sp,sp,#(8*4) \n" // remove one 8-register exception frame -#if (__ARM_FP != 0) /*--------- if VFP available... */ - " POP {r0,lr} \n" /* restore alighner and EXC_RETURN into lr */ - " DSB \n" /* ARM Erratum 838869 */ - " TST lr,#(1 << 4) \n" /* is it return to the VFP exception frame? */ - " IT EQ \n" /* if EXC_RETURN[4] is zero... */ - " VLDMIAEQ sp!,{s16-s31} \n" /* ... restore VFP registers s16..s31 */ -#endif /*--------- VFP available */ - " BX lr \n" /* return to the preempted task */ +#ifdef __ARM_FP //--------- if VFP available... + " POP {r0,lr} \n" // restore alighner and EXC_RETURN into lr + " DSB \n" // ARM Erratum 838869 + " TST lr,#(1 << 4) \n" // is it return to the VFP exception frame? + " IT EQ \n" // if EXC_RETURN[4] is zero... + " VLDMIAEQ sp!,{s16-s31} \n" // ... restore VFP registers s16..s31 +#endif //--------- VFP available + " BX lr \n" // return to the preempted task ); } -/*==========================================================================*/ -#if (__ARM_ARCH == 6) /* if ARMv6-M... */ +//============================================================================ +#if (__ARM_ARCH == 6) // if ARMv6-M... -/* hand-optimized quick LOG2 in assembly (no CLZ instruction in ARMv6-M) */ -/* -* NOTE: -* The inline GNU assembler does not accept mnemonics MOVS, LSRS and ADDS, -* but for ARMv6-M the mnemonics MOV, LSR and ADD always set the condition -* flags in the PSR. -*/ +// hand-optimized quick LOG2 in assembly (no CLZ instruction in ARMv6-M) +// NOTE: +// The inline GNU assembler does not accept mnemonics MOVS, LSRS and ADDS, +// but for ARMv6-M the mnemonics MOV, LSR and ADD always set the condition +// flags in the PSR. __attribute__ ((naked, optimize("-fno-stack-protector"))) uint_fast8_t QF_qlog2(uint32_t x) { __asm volatile ( @@ -644,5 +645,5 @@ __asm volatile ( ); } -#endif /* ARMv6-M */ +#endif // ARMv6-M diff --git a/ports/arm-cm/qxk/gnu/qxk_port.h b/ports/arm-cm/qxk/gnu/qxk_port.h deleted file mode 100644 index d6c2bdf6..00000000 --- a/ports/arm-cm/qxk/gnu/qxk_port.h +++ /dev/null @@ -1,99 +0,0 @@ -/*============================================================================ -* QP/C Real-Time Embedded Framework (RTEF) -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2022-12-18 -* @version Last updated for: @ref qpc_7_2_0 -* -* @file -* @brief QXK/C port to ARM Cortex-M, GNU-ARM compiler -*/ -#ifndef QXK_PORT_H -#define QXK_PORT_H - -/* determination if the code executes in the ISR context */ -#define QXK_ISR_CONTEXT_() (QXK_get_IPSR() != 0U) - -__attribute__((always_inline)) -static inline uint32_t QXK_get_IPSR(void) { - uint32_t regIPSR; - __asm volatile ("mrs %0,ipsr" : "=r" (regIPSR)); - return regIPSR; -} - -/* trigger the PendSV exception to pefrom the context switch */ -#define QXK_CONTEXT_SWITCH_() \ - *Q_UINT2PTR_CAST(uint32_t, 0xE000ED04U) = (1U << 28U) - -/* QXK ISR entry and exit */ -#define QXK_ISR_ENTRY() ((void)0) - -#define QXK_ISR_EXIT() do { \ - QF_INT_DISABLE(); \ - if (QXK_sched_() != 0U) { \ - QXK_CONTEXT_SWITCH_(); \ - } \ - QF_INT_ENABLE(); \ - QXK_ARM_ERRATUM_838869(); \ -} while (false) - -#if (__ARM_ARCH == 6) /* ARMv6-M? */ - #define QXK_ARM_ERRATUM_838869() ((void)0) -#else /* Cortex-M3/M4/M7 (v7-M) */ - /* The following macro implements the recommended workaround for the - * ARM Erratum 838869. Specifically, for Cortex-M3/M4/M7 the DSB - * (memory barrier) instruction needs to be added before exiting an ISR. - */ - #define QXK_ARM_ERRATUM_838869() \ - __asm volatile ("dsb" ::: "memory") -#endif /* ARMv6-M */ - -/* Use a given ARM Cortex-M IRQ to return to thread mode (default NMI) -* -* NOTE: -* If you need the NMI for other purposes, you can define the macros -* QXK_USE_IRQ_NUM and QXK_USE_IRQ_HANDLER to use thus specified IRQ -* instead of the NMI (the IRQ should not be used for anything else). -* These two macros can be defined on the command line to the compiler -* and are actually needed only to compile the qxk_port.c file. -*/ -//#define QXK_USE_IRQ_NUM 25 -//#define QXK_USE_IRQ_HANDLER CRYPTO_IRQHandler - -/* initialization of the QXK kernel */ -#define QXK_INIT() QXK_init() -void QXK_init(void); -void QXK_thread_ret(void); - -#if (__ARM_FP != 0) /* if VFP available... */ -/* When the FPU is configured, clear the FPCA bit in the CONTROL register -* to prevent wasting the stack space for the FPU context. -*/ -#define QXK_START() __asm volatile ("msr CONTROL,%0" :: "r" (0) : ) -#endif - -#include "qxk.h" /* QXK platform-independent public interface */ - -#endif /* QXK_PORT_H */ - diff --git a/ports/arm-cm/qxk/iar/qep_port.h b/ports/arm-cm/qxk/iar/qep_port.h deleted file mode 100644 index eb838a52..00000000 --- a/ports/arm-cm/qxk/iar/qep_port.h +++ /dev/null @@ -1,45 +0,0 @@ -/*============================================================================ -* QP/C Real-Time Embedded Framework (RTEF) -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2022-04-09 -* @version Last updated for: @ref qpc_7_0_0 -* -* @file -* @brief QEP/C port, generic IAR compiler -*/ -#ifndef QEP_PORT_H -#define QEP_PORT_H - -/*! no-return function specifier (IAR compiler) */ -#define Q_NORETURN __noreturn void - - -#include /* Exact-width types. WG14/N843 C99 Standard */ -#include /* Boolean type. WG14/N843 C99 Standard */ - -#include "qep.h" /* QEP platform-independent public interface */ - -#endif /* QEP_PORT_H */ - diff --git a/ports/arm-cm/qxk/iar/qf_port.h b/ports/arm-cm/qxk/iar/qf_port.h deleted file mode 100644 index 66cdf8d6..00000000 --- a/ports/arm-cm/qxk/iar/qf_port.h +++ /dev/null @@ -1,155 +0,0 @@ -/*============================================================================ -* QP/C Real-Time Embedded Framework (RTEF) -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2022-06-30 -* @version Last updated for: @ref qpc_7_0_1 -* -* @file -* @brief QF/C port to Cortex-M, preemptive dual-mode QXK kernel, IAR-ARM -*/ -#ifndef QF_PORT_H -#define QF_PORT_H - -/* The maximum number of system clock tick rates */ -#define QF_MAX_TICK_RATE 2U - -/* QF interrupt disable/enable and log2()... */ -#if (__ARM_ARCH == 6) /* Cortex-M0/M0+/M1(v6-M, v6S-M)? */ - - /* The maximum number of active objects in the application, see NOTE1 */ - #define QF_MAX_ACTIVE 16U - - /* Cortex-M0/M0+/M1(v6-M, v6S-M) interrupt disabling policy, see NOTE2 */ - #define QF_INT_DISABLE() __disable_interrupt() - #define QF_INT_ENABLE() __enable_interrupt() - - /* QF critical section entry/exit (save and restore interrupt status) */ - #define QF_CRIT_STAT_TYPE unsigned long - #define QF_CRIT_ENTRY(primask_) do { \ - (primask_) = __get_PRIMASK(); \ - QF_INT_DISABLE(); \ - } while (false) - #define QF_CRIT_EXIT(primask_) __set_PRIMASK((primask_)) - - /* CMSIS threshold for "QF-aware" interrupts, see NOTE2 and NOTE4 */ - #define QF_AWARE_ISR_CMSIS_PRI 0 - - /* hand-optimized LOG2 in assembly for Cortex-M0/M0+/M1(v6-M, v6S-M) */ - #define QF_LOG2(n_) QF_qlog2((uint32_t)(n_)) - -#else /* Cortex-M3/M4/M7 */ - - /* The maximum number of active objects in the application, see NOTE1 */ - #define QF_MAX_ACTIVE 32U - - /* Cortex-M3/M4/M7 alternative interrupt disabling with PRIMASK */ - #define QF_PRIMASK_DISABLE() __disable_interrupt() - #define QF_PRIMASK_ENABLE() __enable_interrupt() - - /* Cortex-M3/M4/M7 interrupt disabling policy, see NOTE3 and NOTE4 */ - #define QF_INT_DISABLE() do { \ - QF_PRIMASK_DISABLE(); \ - __set_BASEPRI(QF_BASEPRI); \ - QF_PRIMASK_ENABLE(); \ - } while (false) - #define QF_INT_ENABLE() __set_BASEPRI(0U) - - /* QF critical section entry/exit (save and restore interrupt status) */ - #define QF_CRIT_STAT_TYPE unsigned long - #define QF_CRIT_ENTRY(basepri_) do {\ - (basepri_) = __get_BASEPRI(); \ - QF_INT_DISABLE(); \ - } while (false) - #define QF_CRIT_EXIT(basepri_) __set_BASEPRI((basepri_)) - - /* BASEPRI threshold for "QF-aware" interrupts, see NOTE3 */ - #define QF_BASEPRI 0x3F - - /* CMSIS threshold for "QF-aware" interrupts, see NOTE5 */ - #define QF_AWARE_ISR_CMSIS_PRI (QF_BASEPRI >> (8 - __NVIC_PRIO_BITS)) - - /* Cortex-M3/M4/M7 provide the CLZ instruction for fast LOG2 */ - #define QF_LOG2(n_) ((uint_fast8_t)(32U - __CLZ((unsigned long)(n_)))) - -#endif - -#define QF_CRIT_EXIT_NOP() __ISB() - -#include /* IAR intrinsic functions */ -#include "qep_port.h" /* QEP port */ - -#if (__ARM_ARCH == 6) /* Cortex-M0/M0+/M1(v6-M, v6S-M)? */ - /* hand-optimized quick LOG2 in assembly */ - uint_fast8_t QF_qlog2(uint32_t x); -#endif /* Cortex-M0/M0+/M1(v6-M, v6S-M) */ - -#include "qxk_port.h" /* QXK dual-mode kernel port */ - -/***************************************************************************** -* NOTE1: -* The maximum number of active objects QF_MAX_ACTIVE can be increased -* up to 64U, if necessary. Here it is set to a lower level to save some RAM. -* -* NOTE2: -* On Cortex-M0/M0+/M1 (architecture v6-M, v6S-M), the interrupt disabling -* policy uses the PRIMASK register to disable interrupts globally. The -* QF_AWARE_ISR_CMSIS_PRI level is zero, meaning that all interrupts are -* "QF-aware". -* -* NOTE3: -* On Cortex-M3/M4/M7, the interrupt disable/enable policy uses the BASEPRI -* register (which is not implemented in Cortex-M0/M0+/M1) to disable -* interrupts only with priority lower than the threshold specified by the -* QF_BASEPRI macro. The interrupts with priorities above QF_BASEPRI (i.e., -* with numerical priority values lower than QF_BASEPRI) are NOT disabled in -* this method. These free-running interrupts have very low ("zero") latency, -* but they are not allowed to call any QF services, because QF is unaware -* of them ("QF-unaware" interrutps). Consequently, only interrupts with -* numerical values of priorities eqal to or higher than QF_BASEPRI -* ("QF-aware" interrupts ), can call QF services. -* -* NOTE4: -* The QF_AWARE_ISR_CMSIS_PRI macro is useful as an offset for enumerating -* the "QF-aware" interrupt priorities in the applications, whereas the -* numerical values of the "QF-aware" interrupts must be greater or equal to -* QF_AWARE_ISR_CMSIS_PRI. The values based on QF_AWARE_ISR_CMSIS_PRI can be -* passed directly to the CMSIS function NVIC_SetPriority(), which shifts -* them by (8 - __NVIC_PRIO_BITS) into the correct bit position, while -* __NVIC_PRIO_BITS is the CMSIS macro defining the number of implemented -* priority bits in the NVIC. Please note that the macro QF_AWARE_ISR_CMSIS_PRI -* is intended only for applications and is not used inside the QF port, which -* remains generic and not dependent on the number of implemented priority bits -* implemented in the NVIC. -* -* NOTE5: -* The selective disabling of "QF-aware" interrupts with the BASEPRI register -* has a problem on ARM Cortex-M7 core r0p1 (see ARM-EPM-064408, errata -* 837070). The workaround recommended by ARM is to surround MSR BASEPRI with -* the CPSID i/CPSIE i pair, which is implemented in the QF_INT_DISABLE() -* macro. This workaround works also for Cortex-M3/M4 cores. -*/ - -#endif /* QF_PORT_H */ - diff --git a/ports/arm-cm/qxk/iar/qp_port.h b/ports/arm-cm/qxk/iar/qp_port.h new file mode 100644 index 00000000..a0f000e0 --- /dev/null +++ b/ports/arm-cm/qxk/iar/qp_port.h @@ -0,0 +1,240 @@ +//============================================================================ +// QP/C Real-Time Embedded Framework (RTEF) +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC . +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +//============================================================================ +//! @date Last updated on: 2023-09-07 +//! @version Last updated for: @ref qpc_7_3_0 +//! +//! @file +//! @brief QP/C port to ARM Cortex-M, dual-mode QXK kernel, IAR-ARM + +#ifndef QP_PORT_H_ +#define QP_PORT_H_ + +#include // Exact-width types. WG14/N843 C99 Standard +#include // Boolean type. WG14/N843 C99 Standard +#include // IAR intrinsic functions + +#ifdef QP_CONFIG +#include "qp_config.h" // external QP configuration +#endif + +// no-return function specifier (C11 Standard) +#define Q_NORETURN _Noreturn void + +// QF configuration for QXK -- data members of the QActive class... + +// QXK event-queue type used for AOs and eXtended threads. +#define QACTIVE_EQUEUE_TYPE QEQueue + +// QXK OS-Object type used for the private stack pointer for eXtended threads. +// (The private stack pointer is NULL for basic-threads). +#define QACTIVE_OS_OBJ_TYPE void* + +// QF "thread" type used to store the MPU settings in the AO +#define QACTIVE_THREAD_TYPE void const * + +// QF interrupt disable/enable and log2()... +#if (__ARM_ARCH == 6) // ARMv6-M? + + // Cortex-M0/M0+/M1(v6-M, v6S-M) interrupt disabling policy, see NOTE2 + #define QF_INT_DISABLE() __disable_interrupt() + #define QF_INT_ENABLE() __enable_interrupt() + + // QF critical section entry/exit (save and restore interrupt status) + #define QF_CRIT_STAT unsigned long primask_; + #define QF_CRIT_ENTRY() do { \ + (primask_) = __get_PRIMASK(); \ + QF_INT_DISABLE(); \ + } while (false) + #define QF_CRIT_EXIT() __set_PRIMASK((primask_)) + + // CMSIS threshold for "QF-aware" interrupts, see NOTE2 and NOTE4 + #define QF_AWARE_ISR_CMSIS_PRI 0 + + // hand-optimized LOG2 in assembly for Cortex-M0/M0+/M1(v6-M, v6S-M) + #define QF_LOG2(n_) QF_qlog2((uint32_t)(n_)) + +#else // ARMv7-M or higher + + // ARMv7-M or higher alternative interrupt disabling with PRIMASK + #define QF_PRIMASK_DISABLE() __disable_interrupt() + #define QF_PRIMASK_ENABLE() __enable_interrupt() + + // ARMv7-M or higher interrupt disabling policy, see NOTE3 and NOTE4 + #define QF_INT_DISABLE() do { \ + QF_PRIMASK_DISABLE(); \ + __set_BASEPRI(QF_BASEPRI); \ + QF_PRIMASK_ENABLE(); \ + } while (false) + #define QF_INT_ENABLE() __set_BASEPRI(0U) + + // QF critical section entry/exit (save and restore interrupt status) + #define QF_CRIT_STAT unsigned long basepri_; + #define QF_CRIT_ENTRY() do { \ + basepri_ = __get_BASEPRI(); \ + QF_INT_DISABLE(); \ + } while (false) + #define QF_CRIT_EXIT() __set_BASEPRI((basepri_)) + + // BASEPRI threshold for "QF-aware" interrupts, see NOTE3 + #define QF_BASEPRI 0x3F + + // CMSIS threshold for "QF-aware" interrupts, see NOTE5 + #define QF_AWARE_ISR_CMSIS_PRI (QF_BASEPRI >> (8 - __NVIC_PRIO_BITS)) + + // ARMv7-M or higher provide the CLZ instruction for fast LOG2 + #define QF_LOG2(n_) ((uint_fast8_t)(32U - __CLZ((unsigned long)(n_)))) + +#endif + +#define QF_CRIT_EXIT_NOP() __ISB() + +#if (__ARM_ARCH == 6) // ARMv6-M? + // hand-optimized quick LOG2 in assembly + uint_fast8_t QF_qlog2(uint32_t x); +#endif // ARMv7-M or higher + +// Memory isolation ---------------------------------------------------------- +#ifdef QF_MEM_ISOLATE + + // Memory isolation requires the context-switch + #define QF_ON_CONTEXT_SW 1U + + // Memory System setting + #define QF_MEM_SYS() QF_onMemSys() + + // Memory Application setting + #define QF_MEM_APP() QF_onMemApp() + + // callback functions for memory settings (provided by applications) + void QF_onMemSys(void); + void QF_onMemApp(void); + +#endif // def QF_MEM_ISOLATE + +// determination if the code executes in the ISR context +#define QXK_ISR_CONTEXT_() (__get_IPSR() != 0U) + +// trigger the PendSV exception to perform the context switch +#define QXK_CONTEXT_SWITCH_() \ + *Q_UINT2PTR_CAST(uint32_t, 0xE000ED04U) = (1U << 28U) + +// QXK ISR entry and exit +#define QXK_ISR_ENTRY() ((void)0) + +#ifdef QF_MEM_ISOLATE + #define QXK_ISR_EXIT() do { \ + QF_INT_DISABLE(); \ + QF_MEM_SYS(); \ + if (QXK_sched_() != 0U) { \ + *Q_UINT2PTR_CAST(uint32_t, 0xE000ED04U) = (1U << 28U);\ + } \ + QF_MEM_APP(); \ + QF_INT_ENABLE(); \ + QXK_ARM_ERRATUM_838869(); \ + } while (false) +#else + #define QXK_ISR_EXIT() do { \ + QF_INT_DISABLE(); \ + if (QXK_sched_() != 0U) { \ + *Q_UINT2PTR_CAST(uint32_t, 0xE000ED04U) = (1U << 28U);\ + } \ + QF_INT_ENABLE(); \ + QXK_ARM_ERRATUM_838869(); \ + } while (false) +#endif + +#if (__ARM_ARCH == 6) // ARMv6-M? + #define QXK_ARM_ERRATUM_838869() ((void)0) +#else // ARMv7-M or higher + // The following macro implements the recommended workaround for the + // ARM Erratum 838869. Specifically, for Cortex-M3/M4/M7 the DSB + // (memory barrier) instruction needs to be added before exiting an ISR. + #define QXK_ARM_ERRATUM_838869() __DSB() + +#endif // ARMv6-M + +// initialization of the QXK kernel +#define QXK_INIT() QXK_init() +void QXK_init(void); +void QXK_thread_ret(void); + +#ifdef __ARM_FP //--------- if VFP available... +// When the FPU is configured, clear the FPCA bit in the CONTROL register +// to prevent wasting the stack space for the FPU context. +#define QXK_START() __set_CONTROL(0U) +#endif + +// include files ------------------------------------------------------------- +#include "qequeue.h" // QXK kernel uses the native QP event queue +#include "qmpool.h" // QXK kernel uses the native QP memory pool +#include "qp.h" // QP framework +#include "qxk.h" // QXK kernel + +//============================================================================ +// NOTE2: +// On Cortex-M0/M0+/M1 (architecture v6-M, v6S-M), the interrupt disabling +// policy uses the PRIMASK register to disable interrupts globally. The +// QF_AWARE_ISR_CMSIS_PRI level is zero, meaning that all interrupts are +// "QF-aware". +// +// NOTE3: +// On ARMv7-M or higher, the interrupt disable/enable policy uses the BASEPRI +// register (which is not implemented in Cortex-M0/M0+/M1) to disable +// interrupts only with priority lower than the threshold specified by the +// QF_BASEPRI macro. The interrupts with priorities above QF_BASEPRI (i.e., +// with numerical priority values lower than QF_BASEPRI) are NOT disabled in +// this method. These free-running interrupts have very low ("zero") latency, +// but they are not allowed to call any QF services, because QF is unaware +// of them ("QF-unaware" interrupts). Consequently, only interrupts with +// numerical values of priorities equal to or higher than QF_BASEPRI +// ("QF-aware" interrupts ), can call QF services. +// +// NOTE4: +// The QF_AWARE_ISR_CMSIS_PRI macro is useful as an offset for enumerating +// the "QF-aware" interrupt priorities in the applications, whereas the +// numerical values of the "QF-aware" interrupts must be greater or equal to +// QF_AWARE_ISR_CMSIS_PRI. The values based on QF_AWARE_ISR_CMSIS_PRI can be +// passed directly to the CMSIS function NVIC_SetPriority(), which shifts +// them by (8 - __NVIC_PRIO_BITS) into the correct bit position, while +// __NVIC_PRIO_BITS is the CMSIS macro defining the number of implemented +// priority bits in the NVIC. Please note that the macro QF_AWARE_ISR_CMSIS_PRI +// is intended only for applications and is not used inside the QF port, which +// remains generic and not dependent on the number of implemented priority bits +// implemented in the NVIC. +// +// NOTE5: +// The selective disabling of "QF-aware" interrupts with the BASEPRI register +// has a problem on ARM Cortex-M7 core r0p1 (see ARM-EPM-064408, errata +// 837070). The workaround recommended by ARM is to surround MSR BASEPRI with +// the CPSID i/CPSIE i pair, which is implemented in the QF_INT_DISABLE() +// macro. This workaround works also for Cortex-M3/M4 cores. + +#endif // QP_PORT_H_ + diff --git a/ports/arm-cm/qxk/iar/qs_port.h b/ports/arm-cm/qxk/iar/qs_port.h index e8b00882..92ec4663 100644 --- a/ports/arm-cm/qxk/iar/qs_port.h +++ b/ports/arm-cm/qxk/iar/qs_port.h @@ -1,60 +1,61 @@ -/*============================================================================ -* QP/C Real-Time Embedded Framework (RTEF) -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2022-06-12 -* @version Last updated for: @ref qpc_7_0_1 -* -* @file -* @brief QS/C port to a 32-bit CPU and a generic C99 compiler. -* @description -* This is an example of a QP/C port with the documentation for the -* configuration macros and includes. -*/ -#ifndef QS_PORT_H -#define QS_PORT_H +//============================================================================ +// QP/C Real-Time Embedded Framework (RTEF) +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +//============================================================================ +//! @date Last updated on: 2023-08-16 +//! @version Last updated for: @ref qpc_7_3_0 +//! +//! @file +//! @brief QS/C port to a 32-bit CPU and a generic C11 compiler. -/* QS time-stamp size in bytes */ -#define QS_TIME_SIZE 4 +#ifndef QS_PORT_H_ +#define QS_PORT_H_ -/* object pointer size in bytes */ -#define QS_OBJ_PTR_SIZE 4 +// QS time-stamp size in bytes +#define QS_TIME_SIZE 4U -/* function pointer size in bytes */ -#define QS_FUN_PTR_SIZE 4 +// object pointer size in bytes +#define QS_OBJ_PTR_SIZE 4U -/*==========================================================================*/ -/* NOTE: QS might be used with or without other QP components, in which -* case the separate definitions of the macros QF_CRIT_STAT_TYPE, -* QF_CRIT_ENTRY, and QF_CRIT_EXIT are needed. In this port QS is configured -* to be used with the other QP component, by simply including "qf_port.h" -* *before* "qs.h". -*/ -#ifndef QF_PORT_H -#include "qf_port.h" /* use QS with QF */ +// function pointer size in bytes +#define QS_FUN_PTR_SIZE 4U + +//============================================================================ +// NOTE: QS might be used with or without other QP components, in which +// case the separate definitions of the macros QF_CRIT_STAT, QF_CRIT_ENTRY(), +// and QF_CRIT_EXIT() are needed. In this port QS is configured to be used +// with the other QP component, by simply including "qp_port.h" +//*before* "qs.h". +#ifndef QP_PORT_H_ +#include "qp_port.h" // use QS with QF #endif -#include "qs.h" /* QS platform-independent public interface */ +#include "qs.h" // QS platform-independent public interface + +#endif // QS_PORT_H_ -#endif /* QS_PORT_H */ diff --git a/ports/arm-cm/qxk/iar/qxk_port.c b/ports/arm-cm/qxk/iar/qxk_port.c index ca3eae76..d3823277 100644 --- a/ports/arm-cm/qxk/iar/qxk_port.c +++ b/ports/arm-cm/qxk/iar/qxk_port.c @@ -1,605 +1,608 @@ -/*============================================================================ -* QP/C Real-Time Embedded Framework (RTEF) -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2023-01-14 -* @version Last updated for: @ref qpc_7_2_1 -* -* @file -* @brief QXK/C port to ARM Cortex-M, IAR-ARM toolset -*/ -/* This QXK port is part of the internal QP implementation */ +//============================================================================ +// QP/C Real-Time Embedded Framework (RTEF) +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +//============================================================================ +//! @date Last updated on: 2023-08-16 +//! @version Last updated for: @ref qpc_7_3_0 +//! +//! @file +//! @brief QXK/C port to ARM Cortex-M, IAR-ARM + #define QP_IMPL 1U -#include "qf_port.h" -#include "qf_pkg.h" -#include "qassert.h" +#include "qp_port.h" +#include "qp_pkg.h" +#include "qsafe.h" // QP Functional Safety (FuSa) System -#include /* for offsetof() */ +#include // for offsetof() -/* prototypes --------------------------------------------------------------*/ -void PendSV_Handler(void); -#ifdef QXK_USE_IRQ_HANDLER /* if use IRQ... */ -void QXK_USE_IRQ_HANDLER(void); -#else /* use default (NMI) */ -void NMI_Handler(void); -#endif +//============================================================================ +// NOTE: keep in synch with struct QXK_Attr in "qxk.h" !!! +#define QXK_CURR 0 +#define QXK_NEXT 4 +#define QXK_ACT_PRIO 12 -#define SCnSCB_ICTR ((uint32_t volatile *)0xE000E004U) -#define SCB_SYSPRI ((uint32_t volatile *)0xE000ED14U) -#define NVIC_EN ((uint32_t volatile *)0xE000E100U) -#define NVIC_IP ((uint8_t volatile *)0xE000E400U) -#define FPU_FPCCR *((uint32_t volatile *)0xE000EF34U) -#define NVIC_PEND 0xE000E200 -#define NVIC_ICSR 0xE000ED04 +// make sure that the offsets match the QXK declaration in "qxk.h" +_Static_assert(QXK_CURR == offsetof(QXK_Attr, curr), + "QXK_Attr.curr at unexpected offset"); +_Static_assert(QXK_NEXT == offsetof(QXK_Attr, next), + "QXK_Attr.next at unexpected offset"); +_Static_assert(QXK_ACT_PRIO == offsetof(QXK_Attr, actPrio), + "QXK_Attr.actPrio at unexpected offset"); -/*..........................................................................*/ -/* Initialize the exception priorities and IRQ priorities to safe values. -* -* Description: -* On ARMv7-M or higher, this QXK port disables interrupts by means of the -* BASEPRI register. However, this method cannot disable interrupt -* priority zero, which is the default for all interrupts out of reset. -* The following code changes the SysTick priority and all IRQ priorities -* to the safe value QF_BASEPRI, which the QF critical section can disable. -* This avoids breaching of the QF critical sections in case the -* application programmer forgets to explicitly set priorities of all -* "kernel aware" interrupts. -* -* The interrupt priorities established in QXK_init() can be later -* changed by the application-level code. -*/ -void QXK_init(void) { +// offsets within struct QActive; NOTE: keep in synch with "qp.h" !!! +#define QACTIVE_OSOBJ 28 +#define QACTIVE_PRIO 36 -#if (__ARM_ARCH != 6) /*--------- if ARMv7-M and higher... */ +// make sure that the offsets match the QActvie declaration in "qp.h" +_Static_assert(QACTIVE_OSOBJ == offsetof(QActive, osObject), + "QActive.osObject at unexpected offset"); +_Static_assert(QACTIVE_PRIO == offsetof(QActive, prio), + "QActive.prio at unexpected offset"); - /* set exception priorities to QF_BASEPRI... - * SCB_SYSPRI1: Usage-fault, Bus-fault, Memory-fault - */ - SCB_SYSPRI[1] = (SCB_SYSPRI[1] - | (QF_BASEPRI << 16U) | (QF_BASEPRI << 8U) | QF_BASEPRI); +// helper macros to "stringify" values +#define VAL(x) #x +#define STRINGIFY(x) VAL(x) - /* SCB_SYSPRI2: SVCall */ - SCB_SYSPRI[2] = (SCB_SYSPRI[2] | (QF_BASEPRI << 24U)); - - /* SCB_SYSPRI3: SysTick, PendSV, Debug */ - SCB_SYSPRI[3] = (SCB_SYSPRI[3] - | (QF_BASEPRI << 24U) | (QF_BASEPRI << 16U) | QF_BASEPRI); - - /* set all implemented IRQ priories to QF_BASEPRI... */ - uint8_t nprio = (8U + ((*SCnSCB_ICTR & 0x7U) << 3U)) * 4U; - for (uint8_t n = 0U; n < nprio; ++n) { - NVIC_IP[n] = QF_BASEPRI; - } - -#endif /*--------- ARMv7-M or higher */ - - /* SCB_SYSPRI3: PendSV set to priority 0xFF (lowest) */ - SCB_SYSPRI[3] = (SCB_SYSPRI[3] | (0xFFU << 16U)); - -#ifdef QXK_USE_IRQ_NUM /*--------- QXK IRQ specified? */ - /* The QXK port is configured to use a given ARM Cortex-M IRQ # - * to return to thread mode (default is to use the NMI exception) - */ - NVIC_IP[QXK_USE_IRQ_NUM] = 0U; /* priority 0 (highest) */ - NVIC_EN[QXK_USE_IRQ_NUM >> 5U] = (1U << (QXK_USE_IRQ_NUM & 0x1FU)); -#endif /*--------- QXK IRQ specified */ - -#if (__ARM_FP != 0) /*--------- if VFP available... */ - /* configure the FPU for QK */ - FPU_FPCCR |= (1U << 30U) /* automatic FPU state preservation (ASPEN) */ - | (1U << 31U); /* lazy stacking (LSPEN) */ -#endif /*--------- VFP available */ -} - -/*==========================================================================*/ -/* Initialize the private stack of an extended QXK thread. -* -* NOTE: the function aligns the stack to the 8-byte boundary for compatibility -* with the AAPCS. Additionally, the function pre-fills the stack with the -* known bit pattern (0xDEADBEEF). -* -* NOTE: QXK_stackInit_() must be called before the QXK kernel is made aware -* of this thread. In that case the kernel cannot use the thread yet, so no -* critical section is needed. -*/ -void QXK_stackInit_(void *thr, QXThreadHandler const handler, +//============================================================================ +// Initialize the private stack of an extended QXK thread. +// +// NOTE +// The function aligns the stack to the 8-byte boundary for compatibility +// with the AAPCS. Additionally, the function pre-fills the stack with the +// known bit pattern (0xDEADBEEF). +// +// NOTE: QXK_stackInit_() must be called before the QXK kernel is made aware +// of this thread. In that case the kernel cannot use the thread yet, so no +// critical section is needed. +void QXThread_stackInit_(QActive *me, QXThreadHandler const handler, void * const stkSto, uint_fast16_t const stkSize) { - /* round down the stack top to the 8-byte boundary - * NOTE: ARM Cortex-M stack grows down from hi -> low memory - */ + // round down the stack top to the 8-byte boundary + // NOTE: ARM Cortex-M stack grows down from hi -> low memory uint32_t *sp = (uint32_t *)((((uint32_t)stkSto + stkSize) >> 3U) << 3U); uint32_t *sp_limit; - /* synthesize the ARM Cortex-M exception stack frame...*/ - *(--sp) = (1U << 24); /* xPSR (just the THUMB bit) */ - *(--sp) = (uint32_t)handler; /* PC (the thread handler) */ - *(--sp) = (uint32_t)&QXK_threadExit_; /* LR (exit from thread) */ - *(--sp) = 0x0000000CU; /* R12 */ - *(--sp) = 0x00000003U; /* R3 */ - *(--sp) = 0x00000002U; /* R2 */ - *(--sp) = 0x00000001U; /* R1 */ - *(--sp) = (uint32_t)thr; /* R0 parameter to the handler (thread object) */ - *(--sp) = 0x0000000BU; /* R11 */ - *(--sp) = 0x0000000AU; /* R10 */ - *(--sp) = 0x00000009U; /* R9 */ - *(--sp) = 0x00000008U; /* R8 */ - *(--sp) = 0x00000007U; /* R7 */ - *(--sp) = 0x00000006U; /* R6 */ - *(--sp) = 0x00000005U; /* R5 */ - *(--sp) = 0x00000004U; /* R4 */ + // synthesize the ARM Cortex-M exception stack frame... + *(--sp) = (1U << 24); // xPSR (just the THUMB bit) + *(--sp) = (uint32_t)handler; // PC (the thread handler) + *(--sp) = (uint32_t)&QXK_threadExit_; // LR (exit from thread) + *(--sp) = 0x0000000CU; // R12 + *(--sp) = 0x00000003U; // R3 + *(--sp) = 0x00000002U; // R2 + *(--sp) = 0x00000001U; // R1 + *(--sp) = (uint32_t)me; // R0 parameter to handler (thread object) + *(--sp) = 0x0000000BU; // R11 + *(--sp) = 0x0000000AU; // R10 + *(--sp) = 0x00000009U; // R9 + *(--sp) = 0x00000008U; // R8 + *(--sp) = 0x00000007U; // R7 + *(--sp) = 0x00000006U; // R6 + *(--sp) = 0x00000005U; // R5 + *(--sp) = 0x00000004U; // R4 -#if (__ARM_FP != 0) /* if VFP available... */ - *(--sp) = 0xFFFFFFFDU; /* exception return with VFP state */ - *(--sp) = 0xAAAAAAAAU; /* stack "aligner" */ -#endif /* VFP available */ +#ifdef __ARM_FP //--------- if VFP available... + *(--sp) = 0xFFFFFFFDU; // exception return with VFP state + *(--sp) = 0xAAAAAAAAU; // stack "aligner" +#endif // VFP available - /* save the top of the stack in the thread's attribute */ - ((QActive *)thr)->osObject = sp; + // save the top of the stack in the thread's attribute + me->osObject = sp; - /* pre-fill the unused part of the stack with 0xDEADBEEF */ + // pre-fill the unused part of the stack with 0xDEADBEEF sp_limit = (uint32_t *)(((((uint32_t)stkSto - 1U) >> 3U) + 1U) << 3U); for (; sp >= sp_limit; --sp) { *sp = 0xDEADBEEFU; } } -/* NOTE: keep in synch with struct QXK_Attr in "qxk.h" !!! */ -#define QXK_CURR 0 -#define QXK_NEXT 4 -#define QXK_ACT_PRIO 12 +// prototypes ---------------------------------------------------------------- +void PendSV_Handler(void); +#ifdef QXK_USE_IRQ_HANDLER // if use IRQ... +void QXK_USE_IRQ_HANDLER(void); +#else // use default (NMI) +void NMI_Handler(void); +#endif -/* make sure that the offsets match the QXK declaration in "qxk.h" */ -Q_ASSERT_STATIC(QXK_CURR == offsetof(QXK, curr)); -Q_ASSERT_STATIC(QXK_NEXT == offsetof(QXK, next)); -Q_ASSERT_STATIC(QXK_ACT_PRIO == offsetof(QXK, actPrio)); +#define SCB_SYSPRI ((uint32_t volatile *)0xE000ED18U) +#define NVIC_EN ((uint32_t volatile *)0xE000E100U) +#define NVIC_IP ((uint32_t volatile *)0xE000E400U) +#define SCB_CPACR *((uint32_t volatile *)0xE000ED88U) +#define FPU_FPCCR *((uint32_t volatile *)0xE000EF34U) +#define NVIC_PEND 0xE000E200 +#define SCB_ICSR 0xE000ED04 -/* offsets within struct QActive; NOTE: keep in synch with "qf.h" !!! */ -#define QACTIVE_OSOBJ 28 -#define QACTIVE_PRIO 36 +//............................................................................ +// Initialize the exception priorities and IRQ priorities to safe values. +// +// Description: +// On ARMv7-M or higher, this QXK port disables interrupts by means of the +// BASEPRI register. However, this method cannot disable interrupt +// priority zero, which is the default for all interrupts out of reset. +// The following code changes the SysTick priority and all IRQ priorities +// to the safe value QF_BASEPRI, which the QF critical section can disable. +// This avoids breaching of the QF critical sections in case the +// application programmer forgets to explicitly set priorities of all +// "kernel aware" interrupts. +// +// The interrupt priorities established in QXK_init() can be later +// changed by the application-level code. +void QXK_init(void) { -/* make sure that the offsets match the QXK declaration in "qf.h" */ -Q_ASSERT_STATIC(QACTIVE_OSOBJ == offsetof(QActive, osObject)); -Q_ASSERT_STATIC(QACTIVE_PRIO == offsetof(QActive, prio)); +#if (__ARM_ARCH != 6) //--------- if ARMv7-M and higher... -/* helper macros to "stringify" values */ -#define VAL(x) #x -#define STRINGIFY(x) VAL(x) + // SCB_SYSPRI[2]: SysTick + SCB_SYSPRI[2] = (SCB_SYSPRI[2] | (QF_BASEPRI << 24U)); -/*==========================================================================*/ -/* The PendSV_Handler exception handler is used for performing asynchronous -* preemption in QXK. The use of the PendSV exception is the recommended and -* most efficient method for performing context switches in ARM Cortex-M. -* -* The PendSV exception should have the lowest interrupt priority in the system -* (0xFF, see QXK_init()). All other exceptions and interrupts should have -* higher interrupt priority. -* -* Also, *all* "kernel aware" ISRs in the QXK application must call the -* QXK_ISR_EXIT() macro, which triggers PendSV when it detects a need for -* asynchronous preemption. -* -* Due to tail-chaining and its lowest priority, the PendSV exception will be -* entered immediately after the exit from the *last* nested interrupt (or -* exception). In QXK, this is exactly the time when the QXK activator needs to -* handle the asynchronous preemption. -*/ + // set all 240 possible IRQ priories to QF_BASEPRI... + for (uint_fast8_t n = 0U; n < (240U/sizeof(uint32_t)); ++n) { + NVIC_IP[n] = (QF_BASEPRI << 24U) | (QF_BASEPRI << 16U) + | (QF_BASEPRI << 8U) | QF_BASEPRI; + } + +#endif //--------- ARMv7-M or higher + + // SCB_SYSPRI[2]: PendSV set to priority 0xFF (lowest) + SCB_SYSPRI[2] = (SCB_SYSPRI[2] | (0xFFU << 16U)); + +#ifdef QXK_USE_IRQ_NUM //--------- QXK IRQ specified? + // The QXK port is configured to use a given ARM Cortex-M IRQ # + // to return to thread mode (default is to use the NMI exception) + NVIC_IP[QXK_USE_IRQ_NUM] = 0U; // priority 0 (highest) + NVIC_EN[QXK_USE_IRQ_NUM >> 5U] = (1U << (QXK_USE_IRQ_NUM & 0x1FU)); +#endif //--------- QXK IRQ specified + +#ifdef __ARM_FP //--------- if VFP available... + // make sure that the FPU is enabled by seting CP10 & CP11 Full Access + SCB_CPACR = (SCB_CPACR | ((3UL << 20U) | (3UL << 22U))); + + // FPU automatic state preservation (ASPEN) lazy stacking (LSPEN) + FPU_FPCCR = (FPU_FPCCR | (1U << 30U) | (1U << 31U)); +#endif //--------- VFP available +} + +//============================================================================ +// The PendSV_Handler exception handler is used for performing asynchronous +// preemption in QXK. The use of the PendSV exception is the recommended and +// most efficient method for performing context switches in ARM Cortex-M. +// +// The PendSV exception should have the lowest interrupt priority in the system +// (0xFF, see QXK_init()). All other exceptions and interrupts should have +// higher interrupt priority. +// +// Also, *all* "kernel aware" ISRs in the QXK application must call the +// QXK_ISR_EXIT() macro, which triggers PendSV when it detects a need for +// asynchronous preemption. +// +// Due to tail-chaining and its lowest priority, the PendSV exception will be +// entered immediately after the exit from the *last* nested interrupt (or +// exception). In QXK, this is exactly the time when the QXK activator needs to +// handle the asynchronous preemption. __stackless void PendSV_Handler(void) { __asm volatile ( - /* Prepare constants in registers before entering critical section */ - " LDR r3,=QXK_attr_ \n" - " LDR r2,=" STRINGIFY(NVIC_ICSR) "\n" /* Interrupt Control and State */ - " MOVS r1,#1 \n" - " LSLS r1,r1,#27 \n" /* r0 := (1 << 27) (UNPENDSVSET bit) */ - - /*<<<<<<<<<<<<<<<<<<<<<<< CRITICAL SECTION BEGIN <<<<<<<<<<<<<<<<<<<<<<<<*/ -#if (__ARM_ARCH == 6) /* if ARMv6-M... */ - " CPSID i \n" /* disable interrupts (set PRIMASK) */ -#else /* ARMv7-M or higher */ + //<<<<<<<<<<<<<<<<<<<<<<< CRITICAL SECTION BEGIN <<<<<<<<<<<<<<<<<<<<<<<< +#if (__ARM_ARCH == 6) // if ARMv6-M... + " CPSID i \n" // disable interrupts (set PRIMASK) +#else // ARMv7-M or higher " MOVS r0,#" STRINGIFY(QF_BASEPRI) "\n" - " CPSID i \n" /* selectively disable interrupts with BASEPRI */ - " MSR BASEPRI,r0 \n" /* apply the workaround the Cortex-M7 erratum */ - " CPSIE i \n" /* 837070, see SDEN-1068427. */ -#endif /* ARMv7-M or higher */ + " CPSID i \n" // selectively disable interrupts with BASEPRI + " MSR BASEPRI,r0 \n" // apply the workaround the Cortex-M7 erratum + " CPSIE i \n" // 837070, see SDEN-1068427. +#endif // ARMv7-M or higher - /* The PendSV exception handler can be preempted by an interrupt, - * which might pend PendSV exception again. The following write to - * ICSR[27] un-pends any such spurious instance of PendSV. - */ - " STR r1,[r2] \n" /* ICSR[27] := 1 (unpend PendSV) */ +#ifdef QF_MEM_ISOLATE + " PUSH {r0,lr} \n" // save the "aligner" and the EXC_RETURN value + " LDR r0,=QF_onMemSys \n" + " BLX r0 \n" // call QF_onMemSys() + " POP {r0,r1} \n" // restore the aligner + lr into r1 + " MOV lr,r1 \n" // restore EXC_RETURN into lr +#endif - /* Check QXK_attr_.next, which contains the pointer to the next thread - * to run, which is set in QXK_ISR_EXIT(). This pointer must not be NULL. - */ - " LDR r0,[r3,#" STRINGIFY(QXK_NEXT) "]\n" /* r1 := QXK_attr_.next */ - " CMP r0,#0 \n" /* is (QXK_attr_.next == 0)? */ - " BEQ PendSV_return \n" /* branch if (QXK_attr_.next == 0) */ + // The PendSV exception handler can be preempted by an interrupt, + // which might pend PendSV exception again. The following write to + // ICSR[27] un-pends any such spurious instance of PendSV. + " MOVS r1,#1 \n" + " LSLS r1,r1,#27 \n" // r0 := (1 << 27) (UNPENDSVSET bit) + " LDR r2,=" STRINGIFY(SCB_ICSR) "\n" // Interrupt Control and State + " STR r1,[r2] \n" // ICSR[27] := 1 (unpend PendSV) - /* Load pointers into registers... */ - " MOV r12,r0 \n" /* save QXK_attr_.next in r12 */ - " LDR r2,[r0,#" STRINGIFY(QACTIVE_OSOBJ) "]\n" /* r2 := QXK_attr_.next->osObject */ - " LDR r1,[r3,#" STRINGIFY(QXK_CURR) "]\n" /* r1 := QXK_attr_.curr */ + // Check QXK_priv_.next, which contains the pointer to the next thread + // to run, which is set in QXK_ISR_EXIT(). This pointer must not be NULL. + " LDR r3,=QXK_priv_ \n" + " LDR r0,[r3,#" STRINGIFY(QXK_NEXT) "]\n" // r1 := QXK_priv_.next + " CMP r0,#0 \n" // is (QXK_priv_.next == 0)? + " BEQ PendSV_return \n" // branch if (QXK_priv_.next == 0) - " CMP r1,#0 \n" /* (QXK_attr_.curr != 0)? */ - " BNE PendSV_save_ex \n" /* branch if (current thread is extended) */ + // Load pointers into registers... + " MOV r12,r0 \n" // save QXK_priv_.next in r12 + " LDR r2,[r0,#" STRINGIFY(QACTIVE_OSOBJ) "]\n" // r2 := QXK_priv_.next->osObject + " LDR r1,[r3,#" STRINGIFY(QXK_CURR) "]\n" // r1 := QXK_priv_.curr - " CMP r2,#0 \n" /* (QXK_attr_.next->osObject != 0)? */ - " BNE PendSV_save_ao \n" /* branch if (next tread is extended) */ + " CMP r1,#0 \n" // (QXK_priv_.curr != 0)? + " BNE PendSV_save_ex \n" // branch if (current thread is extended) + + " CMP r2,#0 \n" // (QXK_priv_.next->osObject != 0)? + " BNE PendSV_save_ao \n" // branch if (next tread is extended) "PendSV_activate: \n" -#if (__ARM_FP != 0) /* if VFP available... */ - " TST lr,#(1 << 4) \n" /* is it return with the VFP exception frame? */ - " IT EQ \n" /* if lr[4] is zero... */ - " VSTMDBEQ sp!,{s16-s31} \n" /* ... save VFP registers s16..s31 */ - " PUSH {r0,lr} \n" /* save the "aligner" and the EXC_RETURN value */ -#endif /* VFP available */ - /* The QXK activator must be called in a thread context, while this code - * executes in the handler context of the PendSV exception. The switch - * to the Thread mode is accomplished by returning from PendSV using - * a fabricated exception stack frame, where the return address is - * QXK_activate_(). - * - * NOTE: the QXK activator is called with interrupts DISABLED and also - * it returns with interrupts DISABLED. - */ +#ifdef __ARM_FP //--------- if VFP available... + " TST lr,#(1 << 4) \n" // is it return with the VFP exception frame? + " IT EQ \n" // if lr[4] is zero... + " VSTMDBEQ sp!,{s16-s31} \n" // ... save VFP registers s16..s31 + " PUSH {r0,lr} \n" // save the "aligner" and the EXC_RETURN value +#endif // VFP available + // The QXK activator must be called in a thread context, while this code + // executes in the handler context of the PendSV exception. The switch + // to the Thread mode is accomplished by returning from PendSV using + // a fabricated exception stack frame, where the return address is + // QXK_activate_(). + // + // NOTE: the QXK activator is called with interrupts DISABLED and also + // it returns with interrupts DISABLED. " MOVS r3,#1 \n" - " LSLS r3,r3,#24 \n" /* r3 := (1 << 24), set the T bit (new xpsr) */ - " LDR r2,=QXK_activate_\n" /* address of QXK_activate_ */ - " SUBS r2,r2,#1 \n" /* align Thumb-address at half-word (new pc) */ - " LDR r1,=QXK_thread_ret\n" /* return address after the call (new lr) */ + " LSLS r3,r3,#24 \n" // r3 := (1 << 24), set T bit (new xpsr) + " LDR r2,=QXK_activate_\n" // address of QXK_activate_ + " SUBS r2,r2,#1 \n" // align Thumb-address at half-word (new pc) + " LDR r1,=QXK_thread_ret\n" // return address after the call (new lr) - " SUB sp,sp,#(8*4) \n" /* reserve space for exception stack frame */ - " ADD r0,sp,#(5*4) \n" /* r0 := 5 registers below the top of stack */ - " STM r0!,{r1-r3} \n" /* save xpsr,pc,lr */ + " SUB sp,sp,#(8*4) \n" // reserve space for exception stack frame + " ADD r0,sp,#(5*4) \n" // r0 := 5 registers below the top of stack + " STM r0!,{r1-r3} \n" // save xpsr,pc,lr " MOVS r0,#6 \n" - " MVNS r0,r0 \n" /* r0 := ~6 == 0xFFFFFFF9 */ -#if (__ARM_ARCH != 6) /* ARMv7-M or higher */ - " DSB \n" /* ARM Erratum 838869 */ -#endif /* ARMv7-M or higher */ - " BX r0 \n" /* exception-return to the QXK activator */ + " MVNS r0,r0 \n" // r0 := ~6 == 0xFFFFFFF9 +#if (__ARM_ARCH != 6) // ARMv7-M or higher + " DSB \n" // ARM Erratum 838869 +#endif // ARMv7-M or higher + " BX r0 \n" // exception-return to the QXK activator - /*========================================================================= - * Saving AO-thread before crossing to eXtended-thread - * expected register contents: - * r0 -> QXK_attr_.next / basic-thread - * r1 -> QXK_attr_.curr / basic-thread - * r2 -> QXK_attr_.next->osObject (SP) - * r3 -> &QXK_attr_ - * r12 -> QXK_attr_.next / basic-thread - */ + //======================================================================== + // Saving AO-thread before crossing to eXtended-thread + // expected register contents: + // r0 -> QXK_priv_.next / basic-thread + // r1 -> QXK_priv_.curr / basic-thread + // r2 -> QXK_priv_.next->osObject (SP) + // r3 -> &QXK_priv_ + // r12 -> QXK_priv_.next / basic-thread "PendSV_save_ao: \n" -#if (__ARM_ARCH == 6) /* if ARMv6-M... */ - " SUB sp,sp,#(8*4) \n" /* make room for 8 registers r4-r11 */ - " MOV r0,sp \n" /* r0 := temporary stack pointer */ - " STMIA r0!,{r4-r7} \n" /* save the low registers */ - " MOV r4,r8 \n" /* move the high registers to low registers... */ +#if (__ARM_ARCH == 6) // if ARMv6-M... + " SUB sp,sp,#(8*4) \n" // make room for 8 registers r4-r11 + " MOV r0,sp \n" // r0 := temporary stack pointer + " STMIA r0!,{r4-r7} \n" // save the low registers + " MOV r4,r8 \n" // move the high registers to low registers... " MOV r5,r9 \n" " MOV r6,r10 \n" " MOV r7,r11 \n" - " STMIA r0!,{r4-r7} \n" /* save the high registers */ - " MOV r0,r12 \n" /* restore QXK_attr_.next in r0 */ -#else /* ARMv7-M or higher */ - " PUSH {r4-r11} \n" /* save r4-r11 on top of the exception frame */ -#if (__ARM_FP != 0) /* if VFP available... */ - " TST lr,#(1 << 4) \n" /* is it return with the VFP exception frame? */ - " IT EQ \n" /* if lr[4] is zero... */ - " VSTMDBEQ sp!,{s16-s31} \n" /* ... save VFP registers s16..s31 */ - " PUSH {r0,lr} \n" /* save the "aligner" and the EXC_RETURN value */ -#endif /* VFP available */ -#endif /* ARMv7-M or higher */ + " STMIA r0!,{r4-r7} \n" // save the high registers + " MOV r0,r12 \n" // restore QXK_priv_.next in r0 +#else // ARMv7-M or higher + " PUSH {r4-r11} \n" // save r4-r11 on top of the exception frame +#ifdef __ARM_FP //--------- if VFP available... + " TST lr,#(1 << 4) \n" // is it return with the VFP exception frame? + " IT EQ \n" // if lr[4] is zero... + " VSTMDBEQ sp!,{s16-s31} \n" // ... save VFP registers s16..s31 + " PUSH {r0,lr} \n" // save the "aligner" and the EXC_RETURN value +#endif // VFP available +#endif // ARMv7-M or higher " CMP r2,#0 \n" - " BNE PendSV_restore_ex\n" /* branch if (QXK_attr_.next->osObject != 0) */ - /* otherwise continue to restoring next AO-thread... */ + " BNE PendSV_restore_ex\n" // branch if (QXK_priv_.next->osObject != 0) + // otherwise continue to restoring next AO-thread... - /*------------------------------------------------------------------------- - * Restoring AO-thread after crossing from eXtended-thread - * expected register contents: - * r1 -> QXK_attr_.curr / basic-thread - * r2 -> QXK_attr_.next->osObject (SP) - * r3 -> &QXK_attr_ - * r12 -> QXK_attr_.next / basic-thread - */ + //------------------------------------------------------------------------ + // Restoring AO-thread after crossing from eXtended-thread + // expected register contents: + // r1 -> QXK_priv_.curr / basic-thread + // r2 -> QXK_priv_.next->osObject (SP) + // r3 -> &QXK_priv_ + // r12 -> QXK_priv_.next / basic-thread "PendSV_restore_ao: \n" - /* don NOT clear QXK_attr_.curr or QXK_attr_.next, - * as they might be needed for AO activation - */ + // don NOT clear QXK_priv_.curr or QXK_priv_.next, + // as they might be needed for AO activation -#if (__ARM_ARCH == 6) /* if ARMv6-M... */ - " MOV r0,sp \n" /* r0 := top of stack */ +#if (__ARM_ARCH == 6) // if ARMv6-M... + " MOV r0,sp \n" // r0 := top of stack " MOV r2,r0 \n" - " ADDS r2,r2,#(4*4) \n" /* point r2 to the 4 high registers r7-r11 */ - " LDMIA r2!,{r4-r7} \n" /* pop the 4 high registers into low registers */ - " MOV r8,r4 \n" /* move low registers into high registers */ + " ADDS r2,r2,#(4*4) \n" // point r2 to the 4 high registers r7-r11 + " LDMIA r2!,{r4-r7} \n" // pop the 4 high registers into low registers + " MOV r8,r4 \n" // move low registers into high registers " MOV r9,r5 \n" " MOV r10,r6 \n" " MOV r11,r7 \n" - " LDMIA r0!,{r4-r7} \n" /* pop the low registers */ - " ADD sp,sp,#(8*4) \n" /* remove 8 registers from the stack */ + " LDMIA r0!,{r4-r7} \n" // pop the low registers + " ADD sp,sp,#(8*4) \n" // remove 8 registers from the stack " MOVS r2,#6 \n" - " MVNS r2,r2 \n" /* r2 := ~6 == 0xFFFFFFF9 */ - " MOV lr,r2 \n" /* make sure MSP is used */ -#else /* ARMv7-M or higher */ -#if (__ARM_FP != 0) /* if VFP available... */ - " POP {r0,lr} \n" /* restore alighner and EXC_RETURN into lr */ - " DSB \n" /* ARM Erratum 838869 */ - " TST lr,#(1 << 4) \n" /* is it return to the VFP exception frame? */ - " IT EQ \n" /* if EXC_RETURN[4] is zero... */ - " VLDMIAEQ sp!,{s16-s31} \n" /* ... restore VFP registers s16..s31 */ + " MVNS r2,r2 \n" // r2 := ~6 == 0xFFFFFFF9 + " MOV lr,r2 \n" // make sure MSP is used +#else // ARMv7-M or higher +#ifdef __ARM_FP //--------- if VFP available... + " POP {r0,lr} \n" // restore alighner and EXC_RETURN into lr + " DSB \n" // ARM Erratum 838869 + " TST lr,#(1 << 4) \n" // is it return to the VFP exception frame? + " IT EQ \n" // if EXC_RETURN[4] is zero... + " VLDMIAEQ sp!,{s16-s31} \n" // ... restore VFP registers s16..s31 #else - " BIC lr,lr,#(1 << 2) \n" /* make sure MSP is used */ -#endif /* VFP available */ - " POP {r4-r11} \n" /* restore r4-r11 from the next thread's stack */ -#endif /* ARMv7-M or higher */ + " BIC lr,lr,#(1 << 2) \n" // make sure MSP is used +#endif // VFP available + " POP {r4-r11} \n" // restore r4-r11 from the next thread's stack +#endif // ARMv7-M or higher - " MOV r0,r12 \n" /* r0 := QXK_attr_.next */ - " MOVS r2,#" STRINGIFY(QACTIVE_PRIO) "\n" /* r2 := offset of .prio */ - " LDRB r0,[r0,r2] \n" /* r0 := QXK_attr_.next->prio */ - " LDRB r2,[r3,#" STRINGIFY(QXK_ACT_PRIO) "]\n" /* r2 := QXK_attr_.actPrio */ + " MOV r0,r12 \n" // r0 := QXK_priv_.next + " MOVS r2,#" STRINGIFY(QACTIVE_PRIO) "\n" // r2 := offset of .prio + " LDRB r0,[r0,r2] \n" // r0 := QXK_priv_.next->prio + " LDR r2,[r3,#" STRINGIFY(QXK_ACT_PRIO) "]\n" // r2 := QXK_priv_.actPrio " CMP r2,r0 \n" - " BCC PendSV_activate \n" /* if (next->prio > actPrio) activate the next AO */ + " BCC PendSV_activate \n" // if (next->prio > actPrio) activate the next AO - /* otherwise no activation needed... */ + // otherwise no activation needed... " MOVS r0,#0 \n" - " STR r0,[r3,#" STRINGIFY(QXK_CURR) "]\n" /* QXK_attr_.curr := 0 */ - " STR r0,[r3,#" STRINGIFY(QXK_NEXT) "]\n" /* QXK_attr_.next := 0 */ + " STR r0,[r3,#" STRINGIFY(QXK_CURR) "]\n" // QXK_priv_.curr := 0 + " STR r0,[r3,#" STRINGIFY(QXK_NEXT) "]\n" // QXK_priv_.next := 0 #if defined(Q_SPY) || defined(QF_ON_CONTEXT_SW) - " MOVS r0,#0 \n" /* r0 := 0 (next is basic) */ - " PUSH {r3,lr} \n" /* save QXK_attr_ + exception lr */ - " LDR r3,=QXK_contextSw \n" - " BLX r3 \n" /* call QXK_contextSw() */ - " POP {r0,r1} \n" /* restore the aligner + lr into r1 */ - " MOV lr,r1 \n" /* restore the exception lr */ -#endif /* defined(Q_SPY) || defined(QF_ON_CONTEXT_SW) */ + " MOVS r0,#0 \n" // r0 := 0 (next is basic) + " PUSH {r0,lr} \n" // save the aligner + EXC_RETURN + " LDR r3,=QXK_contextSw_ \n" + " BLX r3 \n" // call QXK_contextSw_() +#ifdef QF_MEM_ISOLATE + " LDR r3,=QF_onMemApp \n" + " BLX r3 \n" // call QF_onMemApp() +#endif + " POP {r0,r1} \n" // restore the aligner + EXC_RETURN + " MOV lr,r1 \n" // restore EXC_RETURN into lr +#endif // defined(Q_SPY) || defined(QF_ON_CONTEXT_SW) - /* re-enable interrupts and return from PendSV */ + // re-enable interrupts and return from PendSV "PendSV_return: \n" -#if (__ARM_ARCH == 6) /* if ARMv6-M... */ - " CPSIE i \n" /* enable interrupts (clear PRIMASK) */ -#else /* ARMv7-M or higher */ +#if (__ARM_ARCH == 6) // if ARMv6-M... + " CPSIE i \n" // enable interrupts (clear PRIMASK) +#else // ARMv7-M or higher " MOVS r0,#0 \n" - " MSR BASEPRI,r0 \n" /* enable interrupts (clear BASEPRI) */ - " DSB \n" /* ARM Erratum 838869 */ -#endif /* ARMv7-M or higher */ - /*>>>>>>>>>>>>>>>>>>>>>>>> CRITICAL SECTION END >>>>>>>>>>>>>>>>>>>>>>>>>*/ - " BX lr \n" /* return to the preempted AO-thread */ + " MSR BASEPRI,r0 \n" // enable interrupts (clear BASEPRI) + " DSB \n" // ARM Erratum 838869 +#endif // ARMv7-M or higher + //>>>>>>>>>>>>>>>>>>>>>>>> CRITICAL SECTION END >>>>>>>>>>>>>>>>>>>>>>>>> + " BX lr \n" // return to the preempted AO-thread - /*------------------------------------------------------------------------- - * Saving extended-thread - * expected register contents: - * r0 -> QXK_attr_.next / basic-thread - * r1 -> QXK_attr_.curr / basic-thread - * r2 -> QXK_attr_.next->osObject (SP) - * r3 -> &QXK_attr_ - * r12 -> QXK_attr_.next / basic-thread - */ + //------------------------------------------------------------------------ + // Saving extended-thread + // expected register contents: + // r0 -> QXK_priv_.next / basic-thread + // r1 -> QXK_priv_.curr / basic-thread + // r2 -> QXK_priv_.next->osObject (SP) + // r3 -> &QXK_priv_ + // r12 -> QXK_priv_.next / basic-thread "PendSV_save_ex: \n" - " MRS r0,PSP \n" /* r0 := Process Stack Pointer */ -#if (__ARM_ARCH == 6) /* if ARMv6-M... */ - " SUBS r0,r0,#(8*4) \n" /* make room for 8 registers r4-r11 */ - " MOVS r1,r0 \n" /* r1 := temporary PSP (do not clobber r0!) */ - " STMIA r1!,{r4-r7} \n" /* save the low registers */ - " MOV r4,r8 \n" /* move the high registers to low registers... */ + " MRS r0,PSP \n" // r0 := Process Stack Pointer +#if (__ARM_ARCH == 6) // if ARMv6-M... + " SUBS r0,r0,#(8*4) \n" // make room for 8 registers r4-r11 + " MOVS r1,r0 \n" // r1 := temporary PSP (do not clobber r0!) + " STMIA r1!,{r4-r7} \n" // save the low registers + " MOV r4,r8 \n" // move the high registers to low registers... " MOV r5,r9 \n" " MOV r6,r10 \n" " MOV r7,r11 \n" - " STMIA r1!,{r4-r7} \n" /* save the high registers */ - /* NOTE: at this point r0 holds the top of stack */ + " STMIA r1!,{r4-r7} \n" // save the high registers + // NOTE: at this point r0 holds the top of stack - " LDR r1,[r3,#" STRINGIFY(QXK_CURR) "]\n" /* r1 := QXK_attr_.curr (restore value) */ -#else /* ARMv7-M or higher */ - " ISB \n" /* reset pipeline after fetching PSP */ - " STMDB r0!,{r4-r11} \n" /* save r4-r11 on top of the exception frame */ -#if (__ARM_FP != 0) /* if VFP available... */ - " TST lr,#(1 << 4) \n" /* is it return with the VFP exception frame? */ - " IT EQ \n" /* if lr[4] is zero... */ - " VSTMDBEQ r0!,{s16-s31} \n" /* ... save VFP registers s16..s31 */ - " STMDB r0!,{r1,lr} \n" /* save the "aligner" and the EXC_RETURN value */ -#endif /* VFP available */ -#endif /* ARMv7-M or higher */ + " LDR r1,[r3,#" STRINGIFY(QXK_CURR) "]\n" // r1 := QXK_priv_.curr (restore value) +#else // ARMv7-M or higher + " ISB \n" // reset pipeline after fetching PSP + " STMDB r0!,{r4-r11} \n" // save r4-r11 on top of the exception frame +#ifdef __ARM_FP //--------- if VFP available... + " TST lr,#(1 << 4) \n" // is it return with the VFP exception frame? + " IT EQ \n" // if lr[4] is zero... + " VSTMDBEQ r0!,{s16-s31} \n" // ... save VFP registers s16..s31 + " STMDB r0!,{r1,lr} \n" // save the "aligner" and the EXC_RETURN value +#endif // VFP available +#endif // ARMv7-M or higher - /* store the SP of the current extended-thread */ - " STR r0,[r1,#" STRINGIFY(QACTIVE_OSOBJ) "]\n" /* QXK_attr_.curr->osObject := r0 */ - " MOV r0,r12 \n" /* QXK_attr_.next (restore value) */ + // store the SP of the current extended-thread + " STR r0,[r1,#" STRINGIFY(QACTIVE_OSOBJ) "]\n" // QXK_priv_.curr->osObject := r0 + " MOV r0,r12 \n" // QXK_priv_.next (restore value) " CMP r2,#0 \n" - " BEQ PendSV_restore_ao\n" /* branch if (QXK_attr_.next->osObject == 0) */ - /* otherwise continue to restoring next extended-thread... */ + " BEQ PendSV_restore_ao\n" // branch if (QXK_priv_.next->osObject == 0) + // otherwise continue to restoring next extended-thread... - /*------------------------------------------------------------------------- - * Restoring extended-thread - * expected register contents: - * r0 -> QXK_attr_.next / basic-thread - * r1 -> QXK_attr_.curr / basic-thread - * r2 -> QXK_attr_.next->osObject (SP) - * r3 -> &QXK_attr_ - * r12 -> QXK_attr_.next / basic-thread - */ + //------------------------------------------------------------------------ + // Restoring extended-thread + // expected register contents: + // r0 -> QXK_priv_.next / basic-thread + // r1 -> QXK_priv_.curr / basic-thread + // r2 -> QXK_priv_.next->osObject (SP) + // r3 -> &QXK_priv_ + // r12 -> QXK_priv_.next / basic-thread "PendSV_restore_ex: \n" -#if defined(Q_SPY) || defined(QF_ON_CONTEXT_SW) - " MOV r0,r12 \n" /* r0 := next */ - " PUSH {r3,lr} \n" /* save QXK_attr_ + exception lr */ - " LDR r3,=QXK_contextSw \n" - " BLX r3 \n" /* call QXK_contextSw() */ - " POP {r0,r1} \n" /* restore the aligner + lr into r1 */ - " MOV lr,r1 \n" /* restore the exception lr */ - " MOVS r3,r0 \n" /* restore the saved QXK_attr_ in r3 */ - - /* restore the AAPCS-clobbered registers after a functin call... */ - " LDR r0,[r3,#" STRINGIFY(QXK_NEXT) "]\n" /* r0 := QXK_attr_.next */ - " LDR r2,[r0,#" STRINGIFY(QACTIVE_OSOBJ) "]\n" /* r2 := QXK_attr_.curr->osObject */ -#endif /* defined(Q_SPY) || defined(QF_ON_CONTEXT_SW) */ - - " STR r0,[r3,#" STRINGIFY(QXK_CURR) "]\n" /* QXK_attr_.curr := r0 (QXK_attr_.next) */ + " STR r0,[r3,#" STRINGIFY(QXK_CURR) "]\n" // QXK_priv_.curr := r0 (QXK_priv_.next) " MOVS r0,#0 \n" - " STR r0,[r3,#" STRINGIFY(QXK_NEXT) "]\n" /* QXK_attr_.next := 0 */ + " STR r0,[r3,#" STRINGIFY(QXK_NEXT) "]\n" // QXK_priv_.next := 0 - /* exit the critical section */ -#if (__ARM_ARCH == 6) /* if ARMv6-M... */ - " CPSIE i \n" /* enable interrupts (clear PRIMASK) */ +#if defined(Q_SPY) || defined(QF_ON_CONTEXT_SW) + " MOV r0,r12 \n" // r0 := next + " PUSH {r0-r2,lr} \n" // save next, osObject, EXC_RETURN + " LDR r3,=QXK_contextSw_ \n" + " BLX r3 \n" // call QXK_contextSw_() +#ifdef QF_MEM_ISOLATE + " LDR r3,=QF_onMemApp \n" + " BLX r3 \n" // call QF_onMemApp() +#endif + " POP {r0-r3} \n" // restore next, osObject, EXC_RETURN + " MOV lr,r3 \n" // restore the EXC_RETURN into lr +#endif // defined(Q_SPY) || defined(QF_ON_CONTEXT_SW) - " MOVS r0,r2 \n" /* r2 := top of stack */ - " ADDS r0,r0,#(4*4) \n" /* point r0 to the 4 high registers r7-r11 */ - " LDMIA r0!,{r4-r7} \n" /* pop the 4 high registers into low registers */ - " MOV r8,r4 \n" /* move low registers into high registers */ + + // exit the critical section +#if (__ARM_ARCH == 6) // if ARMv6-M... + " CPSIE i \n" // enable interrupts (clear PRIMASK) + + " MOVS r0,r2 \n" // r2 := top of stack + " ADDS r0,r0,#(4*4) \n" // point r0 to the 4 high registers r7-r11 + " LDMIA r0!,{r4-r7} \n" // pop the 4 high registers into low registers + " MOV r8,r4 \n" // move low registers into high registers " MOV r9,r5 \n" " MOV r10,r6 \n" " MOV r11,r7 \n" - " LDMIA r2!,{r4-r7} \n" /* pop the low registers */ - " MOVS r2,r0 \n" /* r2 := holds the new top of stack */ + " LDMIA r2!,{r4-r7} \n" // pop the low registers + " MOVS r2,r0 \n" // r2 := holds the new top of stack " MOVS r1,#2 \n" - " MVNS r1,r1 \n" /* r1 := ~2 == 0xFFFFFFFD */ - " MOV lr,r1 \n" /* make sure PSP is used */ -#else /* ARMv7-M or higher */ + " MVNS r1,r1 \n" // r1 := ~2 == 0xFFFFFFFD + " MOV lr,r1 \n" // make sure PSP is used +#else // ARMv7-M or higher " MOVS r1,#0 \n" - " MSR BASEPRI,r1 \n" /* enable interrupts (clear BASEPRI) */ -#if (__ARM_FP != 0) /* if VFP available... */ - " LDMIA r2!,{r1,lr} \n" /* restore aligner and EXC_RETURN into lr */ - " TST lr,#(1 << 4) \n" /* is it return to the VFP exception frame? */ - " IT EQ \n" /* if lr[4] is zero... */ - " VLDMIAEQ r2!,{s16-s31} \n" /* ... restore VFP registers s16..s31 */ + " MSR BASEPRI,r1 \n" // enable interrupts (clear BASEPRI) +#ifdef __ARM_FP //--------- if VFP available... + " LDMIA r2!,{r1,lr} \n" // restore aligner and EXC_RETURN into lr + " TST lr,#(1 << 4) \n" // is it return to the VFP exception frame? + " IT EQ \n" // if lr[4] is zero... + " VLDMIAEQ r2!,{s16-s31} \n" // ... restore VFP registers s16..s31 #else - " ORR lr,lr,#(1 << 2) \n" /* make sure PSP is used */ -#endif /* VFP available */ - " LDMIA r2!,{r4-r11} \n" /* restore r4-r11 from the next thread's stack */ -#endif /* ARMv7-M or higher */ + " ORR lr,lr,#(1 << 2) \n" // make sure PSP is used +#endif // VFP available + " LDMIA r2!,{r4-r11} \n" // restore r4-r11 from the next thread's stack +#endif // ARMv7-M or higher - /* set the PSP to the next thread's SP */ - " MSR PSP,r2 \n" /* Process Stack Pointer := r2 */ + // set the PSP to the next thread's SP + " MSR PSP,r2 \n" // Process Stack Pointer := r2 -#if (__ARM_ARCH != 6) /* if ARMv7-M or higher... */ - " DSB \n" /* ARM Erratum 838869 */ -#endif /* ARMv7-M or higher */ - " BX lr \n" /* return to the next extended-thread */ +#if (__ARM_ARCH != 6) // if ARMv7-M or higher... + " DSB \n" // ARM Erratum 838869 +#endif // ARMv7-M or higher + " BX lr \n" // return to the next extended-thread ); } -/*==========================================================================*/ -/* QXK_thread_ret is a helper function executed when the QXK activator returns. -* -* NOTE: QXK_thread_ret does not execute in the PendSV context! -* NOTE: QXK_thread_ret is entered with interrupts DISABLED. -*/ +//============================================================================ +// QXK_thread_ret is a helper function executed when the QXK activator returns. +// +// NOTE: QXK_thread_ret does not execute in the PendSV context! +// NOTE: QXK_thread_ret is entered with interrupts DISABLED. __stackless void QXK_thread_ret(void) { __asm volatile ( - /* After the QXK activator returns, we need to resume the preempted - * thread. However, this must be accomplished by a return-from-exception, - * while we are still in the thread context. The switch to the exception - * context is accomplished by triggering the NMI exception or the selected - * IRQ (if macro #QXK_USE_IRQ_NUM is defined). - */ + // After the QXK activator returns, we need to resume the preempted + // thread. However, this must be accomplished by a return-from-exception, + // while we are still in the thread context. The switch to the exception + // context is accomplished by triggering the NMI exception or the selected + // IRQ (if macro #QXK_USE_IRQ_NUM is defined). - /* before triggering the NMI/IRQ, make sure that the VFP stack frame - * will NOT be used... - */ -#if (__ARM_FP != 0) /*--------- if VFP available... */ - /* make sure that the VFP stack frame will NOT be used */ - " MRS r0,CONTROL \n" /* r0 := CONTROL */ - " BICS r0,r0,#4 \n" /* r0 := r0 & ~4 (FPCA bit) */ - " MSR CONTROL,r0 \n" /* CONTROL := r0 (clear CONTROL[2] FPCA bit) */ - " ISB \n" /* ISB after MSR CONTROL (ARM AN321,Sect.4.16) */ -#endif /*--------- VFP available */ + // before triggering the NMI/IRQ, make sure that the VFP stack frame + // will NOT be used... +#ifdef __ARM_FP //--------- if VFP available... + // make sure that the VFP stack frame will NOT be used + " MRS r0,CONTROL \n" // r0 := CONTROL + " BICS r0,r0,#4 \n" // r0 := r0 & ~4 (FPCA bit) + " MSR CONTROL,r0 \n" // CONTROL := r0 (clear CONTROL[2] FPCA bit) + " ISB \n" // ISB after MSR CONTROL (ARM AN321,Sect.4.16) +#endif //--------- VFP available -#ifndef QXK_USE_IRQ_NUM /*--------- IRQ NOT defined, use NMI by default */ - " LDR r0,=" STRINGIFY(NVIC_ICSR) "\n" /* Interrupt Control and State */ +#ifdef QF_MEM_ISOLATE + " PUSH {r0,lr} \n" // save the aligner + EXC_RETURN + " LDR r0,=QF_onMemApp \n" + " BLX r0 \n" // call QF_onMemApp() + " POP {r0,r1} \n" // restore the aligner + EXC_RETURN + " MOV lr,r1 \n" // restore EXC_RETURN into lr +#endif + +#ifndef QXK_USE_IRQ_NUM //--------- IRQ NOT defined, use NMI by default + " LDR r0,=" STRINGIFY(SCB_ICSR) "\n" // Interrupt Control and State " MOVS r1,#1 \n" - " LSLS r1,r1,#31 \n" /* r1 := (1 << 31) (NMI bit) */ - " STR r1,[r0] \n" /* ICSR[31] := 1 (pend NMI) */ + " LSLS r1,r1,#31 \n" // r1 := (1 << 31) (NMI bit) + " STR r1,[r0] \n" // ICSR[31] := 1 (pend NMI) -#else /*--------- use the selected IRQ */ +#else //--------- use the selected IRQ " LDR r0,=" STRINGIFY(NVIC_PEND + ((QXK_USE_IRQ_NUM >> 5) << 2)) "\n" " MOVS r1,#1 \n" - " LSLS r1,r1,#" STRINGIFY(QXK_USE_IRQ_NUM & 0x1F) "\n" /* r1 := IRQ bit */ - " STR r1,[r0] \n" /* pend the IRQ */ + " LSLS r1,r1,#" STRINGIFY(QXK_USE_IRQ_NUM & 0x1F) "\n" // r1 := IRQ bit + " STR r1,[r0] \n" // pend the IRQ - /* now enable interrupts so that pended IRQ can be entered */ -#if (__ARM_ARCH == 6) /*--------- if ARMv6-M... */ - " CPSIE i \n" /* enable interrupts (clear PRIMASK) */ -#else /*--------- ARMv7-M and higher */ + // now enable interrupts so that pended IRQ can be entered +#if (__ARM_ARCH == 6) //--------- if ARMv6-M... + " CPSIE i \n" // enable interrupts (clear PRIMASK) +#else //--------- ARMv7-M and higher " MOVS r0,#0 \n" - " MSR BASEPRI,r0 \n" /* enable interrupts (clear BASEPRI) */ -#endif /*--------- ARMv7-M and higher */ -#endif /*--------- use IRQ */ + " MSR BASEPRI,r0 \n" // enable interrupts (clear BASEPRI) +#endif //--------- ARMv7-M and higher +#endif //--------- use IRQ - /* NOTE! interrupts are still disabled when NMI is used */ - " B . \n" /* wait for preemption by NMI/IRQ */ + // NOTE! interrupts are still disabled when NMI is used + " B . \n" // wait for preemption by NMI/IRQ ); } -/*==========================================================================*/ -/* This exception handler is used for returning back to the preempted thread. -* The exception handler simply removes its own interrupt stack frame from -* the stack (MSP) and returns to the preempted task using the interrupt -* stack frame that must be at the top of the stack. -*/ +//============================================================================ +// This exception handler is used for returning back to the preempted thread. +// The exception handler simply removes its own interrupt stack frame from +// the stack (MSP) and returns to the preempted task using the interrupt +// stack frame that must be at the top of the stack. __stackless -#ifndef QXK_USE_IRQ_NUM /*--------- IRQ NOT defined, use NMI by default */ +#ifndef QXK_USE_IRQ_NUM //--------- IRQ NOT defined, use NMI by default -/* NOTE: The NMI_Handler() is entered with interrupts still disabled! */ +// NOTE: The NMI_Handler() is entered with interrupts still disabled! void NMI_Handler(void) { __asm volatile ( - /* enable interrupts */ -#if (__ARM_ARCH == 6) /*--------- if ARMv6-M... */ - " CPSIE i \n" /* enable interrupts (clear PRIMASK) */ -#else /*--------- ARMv7-M and higher */ + // enable interrupts +#if (__ARM_ARCH == 6) //--------- if ARMv6-M... + " CPSIE i \n" // enable interrupts (clear PRIMASK) +#else //--------- ARMv7-M and higher " MOVS r0,#0 \n" - " MSR BASEPRI,r0 \n" /* enable interrupts (clear BASEPRI) */ -#endif /*--------- ARMv7-M and higher */ + " MSR BASEPRI,r0 \n" // enable interrupts (clear BASEPRI) +#endif //--------- ARMv7-M and higher ); -#else /*--------- use the selected IRQ */ +#else //--------- use the selected IRQ -/* NOTE: The IRQ Handler is entered with interrupts enabled */ +// NOTE: The IRQ Handler is entered with interrupts enabled void QXK_USE_IRQ_HANDLER(void) { -#endif /*--------- use IRQ */ +#endif //--------- use IRQ __asm volatile ( - " ADD sp,sp,#(8*4) \n" /* remove one 8-register exception frame */ + " ADD sp,sp,#(8*4) \n" // remove one 8-register exception frame -#if (__ARM_FP != 0) /*--------- if VFP available... */ - " POP {r0,lr} \n" /* restore alighner and EXC_RETURN into lr */ - " DSB \n" /* ARM Erratum 838869 */ - " TST lr,#(1 << 4) \n" /* is it return to the VFP exception frame? */ - " IT EQ \n" /* if EXC_RETURN[4] is zero... */ - " VLDMIAEQ sp!,{s16-s31} \n" /* ... restore VFP registers s16..s31 */ -#endif /*--------- VFP available */ - " BX lr \n" /* return to the preempted task */ +#ifdef __ARM_FP //--------- if VFP available... + " POP {r0,lr} \n" // restore alighner and EXC_RETURN into lr + " DSB \n" // ARM Erratum 838869 + " TST lr,#(1 << 4) \n" // is it return to the VFP exception frame? + " IT EQ \n" // if EXC_RETURN[4] is zero... + " VLDMIAEQ sp!,{s16-s31} \n" // ... restore VFP registers s16..s31 +#endif //--------- VFP available + " BX lr \n" // return to the preempted task ); } -/*==========================================================================*/ -#if (__ARM_ARCH == 6) /* if ARMv6-M... */ +//============================================================================ +#if (__ARM_ARCH == 6) // if ARMv6-M... -/* hand-optimized quick LOG2 in assembly (no CLZ instruction in ARMv6-M) */ +// hand-optimized quick LOG2 in assembly (no CLZ instruction in ARMv6-M) uint_fast8_t QF_qlog2(uint32_t x) { static uint8_t const log2LUT[16] = { 0U, 1U, 2U, 2U, 3U, 3U, 3U, 3U, @@ -632,5 +635,5 @@ __asm volatile ( return n + log2LUT[x]; } -#endif /* ARMv6-M */ +#endif // ARMv6-M diff --git a/ports/arm-cm/qxk/iar/qxk_port.h b/ports/arm-cm/qxk/iar/qxk_port.h deleted file mode 100644 index ff5ce794..00000000 --- a/ports/arm-cm/qxk/iar/qxk_port.h +++ /dev/null @@ -1,91 +0,0 @@ -/*============================================================================ -* QP/C Real-Time Embedded Framework (RTEF) -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2022-12-18 -* @version Last updated for: @ref qpc_7_2_0 -* -* @file -* @brief QXK/C port to ARM Cortex-M, IAR-ARM compiler -*/ -#ifndef QXK_PORT_H -#define QXK_PORT_H - -/* determination if the code executes in the ISR context */ -#define QXK_ISR_CONTEXT_() (__get_IPSR() != 0U) - -/* trigger the PendSV exception to perform the context switch */ -#define QXK_CONTEXT_SWITCH_() \ - *Q_UINT2PTR_CAST(uint32_t, 0xE000ED04U) = (1U << 28U) - -/* QXK ISR entry and exit */ -#define QXK_ISR_ENTRY() ((void)0) - -#define QXK_ISR_EXIT() do { \ - QF_INT_DISABLE(); \ - if (QXK_sched_() != 0U) { \ - QXK_CONTEXT_SWITCH_(); \ - } \ - QF_INT_ENABLE(); \ - QXK_ARM_ERRATUM_838869(); \ -} while (false) - -#if (__CORE__ == __ARM6M__) /* ARMv6-M? */ - #define QXK_ARM_ERRATUM_838869() ((void)0) -#else /* Cortex-M3/M4/M7 (v7-M) */ - /* The following macro implements the recommended workaround for the - * ARM Erratum 838869. Specifically, for Cortex-M3/M4/M7 the DSB - * (memory barrier) instruction needs to be added before exiting an ISR. - */ - #define QXK_ARM_ERRATUM_838869() __DSB() -#endif /* ARMv6-M */ - -/* Use a given ARM Cortex-M IRQ to return to thread mode (default NMI) -* -* NOTE: -* If you need the NMI for other purposes, you can define the macros -* QXK_USE_IRQ_NUM and QXK_USE_IRQ_HANDLER to use thus specified IRQ -* instead of the NMI (the IRQ should not be used for anything else). -* These two macros can be defined on the command line to the compiler -* and are actually needed only to compile the qxk_port.c file. -*/ -//#define QXK_USE_IRQ_NUM 25 -//#define QXK_USE_IRQ_HANDLER CRYPTO_IRQHandler - -/* initialization of the QXK kernel */ -#define QXK_INIT() QXK_init() -void QXK_init(void); -void QXK_thread_ret(void); - -#if (__ARM_FP != 0) /* if VFP available... */ -/* When the FPU is configured, clear the FPCA bit in the CONTROL register -* to prevent wasting the stack space for the FPU context. -*/ -#define QXK_START() __set_CONTROL(0U) -#endif - -#include "qxk.h" /* QXK platform-independent public interface */ - -#endif /* QXK_PORT_H */ - diff --git a/ports/arm-cr/qk/gnu/qep_port.h b/ports/arm-cr/qk/gnu/qep_port.h deleted file mode 100644 index 6d17e338..00000000 --- a/ports/arm-cr/qk/gnu/qep_port.h +++ /dev/null @@ -1,39 +0,0 @@ -/*============================================================================ -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2022-07-30 -* @version Last updated for: @ref qpc_7_0_1 -* -* @file -* @brief QEP/C port, generic C99 compiler -*/ -#ifndef QEP_PORT_H -#define QEP_PORT_H - -#include /* Exact-width types. WG14/N843 C99 Standard */ -#include /* Boolean type. WG14/N843 C99 Standard */ - -#include "qep.h" /* QEP platform-independent public interface */ - -#endif /* QEP_PORT_H */ diff --git a/ports/arm-cr/qk/gnu/qf_port.h b/ports/arm-cr/qk/gnu/qf_port.h deleted file mode 100644 index a03016f6..00000000 --- a/ports/arm-cr/qk/gnu/qf_port.h +++ /dev/null @@ -1,94 +0,0 @@ -/*============================================================================ -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2022-07-30 -* @version Last updated for: @ref qpc_7_0_1 -* -* @file -* @brief QF/C port to Cortex-R, preemptive QK kernel, GNU-ARM toolset -*/ -#ifndef QF_PORT_H -#define QF_PORT_H - -/* The maximum number of active objects in the application, see NOTE1 */ -#define QF_MAX_ACTIVE 32U - -/* The maximum number of system clock tick rates */ -#define QF_MAX_TICK_RATE 2U - -/* QF interrupt disable/enable, see NOTE2 */ -#ifdef __thumb__ /* THUMB mode? */ - - #define QF_INT_DISABLE() __asm volatile ("cpsid i") - #define QF_INT_ENABLE() __asm volatile ("cpsie i") - #define QF_INT_ENABLE_ALL() __asm volatile ("cpsie if") - -#elif (defined __arm__) /* ARM mode? */ - - #define QF_INT_DISABLE() \ - __asm volatile ("MSR cpsr_c,#(0x1F | 0x80)" ::: "cc") - #define QF_INT_ENABLE() \ - __asm volatile ("MSR cpsr_c,#(0x1F)" ::: "cc") - #define QF_INT_ENABLE_ALL() \ - __asm volatile ("MSR cpsr_c,#(0x1F | 0x80 | 0x40)" ::: "cc") -#else - #error Incorrect CPU mode. Must be either __arm__ or __thumb__. -#endif - -/* Cortex-R provide the CLZ instruction for fast LOG2 */ -#define QF_LOG2(n_) ((uint8_t)(32U - __builtin_clz(n_))) - -/* QF critical section entry/exit, see NOTE3 */ -#define QF_CRIT_STAT_TYPE uint32_t -#define QF_CRIT_ENTRY(stat_) do { \ - __asm volatile ("MRS %0,cpsr" : "=r" (stat_) :: "cc"); \ - QF_INT_DISABLE(); \ -} while (false) -#define QF_CRIT_EXIT(stat_) \ - __asm volatile ("MSR cpsr_c,%0" :: "r" (stat_) : "cc") -#define QF_CRIT_EXIT_NOP() __asm volatile ("ISB") - -#include "qep_port.h" /* QEP port */ -#include "qk_port.h" /* QK port */ -#include "qf.h" /* QF platform-independent public interface */ - -/***************************************************************************** -* NOTE1: -* The maximum number of active objects QF_MAX_ACTIVE can be increased -* up to 63, if necessary. Here it is set to a lower level to save some RAM. -* -* NOTE2: -* The FIQ-type interrupts are NEVER disabled in this port, so the FIQ is -* a "kernel-unaware" interrupt. If the FIQ is ever used in the application, -* it must be an "ARM FIQ"-type function. For this to work, the FIQ -* stack needs to be initialized. -* -* NOTE3: -* This port implements the "save and restore" interrupt status policy, -* which again never disables the FIQ-type interrupts. This policy allows -* for nesting critical sections, which is necessary inside IRQ-type -* interrupts that run with interrupts (IRQ) disabled. -*/ - -#endif /* QF_PORT_H */ diff --git a/ports/arm-cr/qk/gnu/qk_port.h b/ports/arm-cr/qk/gnu/qk_port.h deleted file mode 100644 index 0f0dff18..00000000 --- a/ports/arm-cr/qk/gnu/qk_port.h +++ /dev/null @@ -1,105 +0,0 @@ -/*============================================================================ -* QP/C Real-Time Embedded Framework (RTEF) -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2022-10-02 -* @version Last updated for: @ref qpc_7_1_2 -* -* @file -* @brief QK/C port to ARM Cortex-R, GNU-ARM toolset -*/ -#ifndef QK_PORT_H -#define QK_PORT_H - -/* QK-specific Interrupt Request handler BEGIN */ -#ifdef __FPU_PRESENT -#define QK_IRQ_BEGIN(name_) \ - void name_(void) \ - __attribute__ ((interrupt ("irq"))); \ - __attribute__ ((naked)) void name_(void) { \ - __asm volatile (" SUB LR, LR, #4\n" \ - " SRSDB #31!\n" \ - " CPS #31\n" \ - " PUSH {R0-R3, R12}"); \ - __asm(" FMRX R12, FPSCR\n" \ - " STMFD SP!, {R12}\n" \ - " FMRX R12, FPEXC\n" \ - " STMFD SP!, {R12}\n" \ - " FSTMDBD SP!, {D0-D7}"); \ - __asm(" AND R3, SP, #4\n" \ - " SUB SP, SP, R3\n" \ - " PUSH {R3, LR}\n"); \ - ++QF_intNest_; { -#else -#define QK_IRQ_BEGIN(name_) \ - void name_(void) \ - __attribute__ ((target ("arm"))); \ - __attribute__ ((naked)) void name_(void) { \ - __asm volatile (" SUB LR, LR, #4\n" \ - " SRSDB #31!\n" \ - " CPS #31\n" \ - " PUSH {R0-R3, R12}"); \ - __asm(" AND R3, SP, #4\n" \ - " SUB SP, SP, R3\n" \ - " PUSH {R3, LR}\n"); \ - ++QF_intNest_; { -#endif - -/* QK-specific Interrupt Request handler END */ -#ifdef __FPU_PRESENT -#define QK_IRQ_END() \ - } --QF_intNest_; \ - if (QF_intNest_ == 0U) { \ - if (QK_sched_() != 0U) { \ - QK_activate_(); \ - } \ - } \ - __asm volatile (" POP {R3, LR}\n" \ - " ADD SP, SP, R3"); \ - __asm(" FLDMIAD SP!, {D0-D7}\n" \ - " LDMFD SP!, {R12}\n" \ - " FMXR FPEXC, R12 \n" \ - " LDMFD SP!, {R12} \n" \ - " FMXR FPSCR, R12"); \ - __asm(" POP {R0-R3, R12}\n" \ - " RFEIA SP!"); \ -} -#else -#define QK_IRQ_END() \ - } --QF_intNest_; \ - if (QF_intNest_ == 0U) { \ - if (QK_sched_() != 0U) { \ - QK_activate_(); \ - } \ - } \ - __asm volatile (" POP {R3, LR}\n" \ - " ADD SP, SP, R3"); \ - __asm volatile (" POP {R0-R3, R12}\n" \ - " RFEIA SP!"); \ -} -#endif - -#include "qk.h" /* QK platform-independent public interface */ - -#endif /* QK_PORT_H */ diff --git a/ports/arm-cr/qk/gnu/qp_port.h b/ports/arm-cr/qk/gnu/qp_port.h new file mode 100644 index 00000000..d1f5ad44 --- /dev/null +++ b/ports/arm-cr/qk/gnu/qp_port.h @@ -0,0 +1,180 @@ +//============================================================================ +// QP/C Real-Time Embedded Framework (RTEF) +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +//============================================================================ +//! @date Last updated on: 2023-09-07 +//! @version Last updated for: @ref qpc_7_3_0 +//! +//! @file +//! @brief QP/C port to ARM Cortex-R, preemptive QK kernel, GNU-ARM + +#ifndef QP_PORT_H_ +#define QP_PORT_H_ + +#include // Exact-width types. WG14/N843 C99 Standard +#include // Boolean type. WG14/N843 C99 Standard + +#ifdef QP_CONFIG +#include "qp_config.h" // external QP configuration +#endif + +// no-return function specifier (C11 Standard) +#define Q_NORETURN _Noreturn void + +// QF configuration for QK -- data members of the QActive class... + +// QK event-queue used for AOs +#define QACTIVE_EQUEUE_TYPE QEQueue + +// QF interrupt disable/enable, see NOTE2 +#ifdef __thumb__ // THUMB mode? + + #define QF_INT_DISABLE() __asm volatile ("cpsid i") + #define QF_INT_ENABLE() __asm volatile ("cpsie i") + #define QF_INT_ENABLE_ALL() __asm volatile ("cpsie if") + +#elif (defined __arm__) // ARM mode? + + #define QF_INT_DISABLE() \ + __asm volatile ("MSR cpsr_c,#(0x1F | 0x80)" ::: "cc") + #define QF_INT_ENABLE() \ + __asm volatile ("MSR cpsr_c,#(0x1F)" ::: "cc") + #define QF_INT_ENABLE_ALL() \ + __asm volatile ("MSR cpsr_c,#(0x1F | 0x80 | 0x40)" ::: "cc") +#else + #error Incorrect CPU mode. Must be either __arm__ or __thumb__. +#endif + +// Cortex-R provide the CLZ instruction for fast LOG2 +#define QF_LOG2(n_) ((uint8_t)(32U - __builtin_clz(n_))) + +// QF critical section entry/exit, see NOTE3 +#define QF_CRIT_STAT uint32_t cpsr_; +#define QF_CRIT_ENTRY() do { \ + __asm volatile ("MRS %0,cpsr" : "=r" (cpsr_) :: "cc"); \ + QF_INT_DISABLE(); \ +} while (false) + +#define QF_CRIT_EXIT() \ + __asm volatile ("MSR cpsr_c,%0" :: "r" (cpsr_) : "cc") + +#define QF_CRIT_EXIT_NOP() __asm volatile ("ISB") + +// Check if the code executes in the ISR context +#define QK_ISR_CONTEXT_() (QK_priv_.intNest != 0U) + +// QK-specific Interrupt Request handler BEGIN +#ifdef __ARM_FP +#define QK_IRQ_BEGIN(name_) \ + void name_(void) \ + __attribute__ ((interrupt ("irq"))); \ + __attribute__ ((naked)) void name_(void) { \ + __asm volatile (" SUB LR, LR, #4\n" \ + " SRSDB #31!\n" \ + " CPS #31\n" \ + " PUSH {R0-R3, R12}"); \ + __asm(" FMRX R12, FPSCR\n" \ + " STMFD SP!, {R12}\n" \ + " FMRX R12, FPEXC\n" \ + " STMFD SP!, {R12}\n" \ + " FSTMDBD SP!, {D0-D7}"); \ + __asm(" AND R3, SP, #4\n" \ + " SUB SP, SP, R3\n" \ + " PUSH {R3, LR}\n"); \ + ++QK_priv_.intNest; { +#else +#define QK_IRQ_BEGIN(name_) \ + void name_(void) \ + __attribute__ ((target ("arm"))); \ + __attribute__ ((naked)) void name_(void) { \ + __asm volatile (" SUB LR, LR, #4\n" \ + " SRSDB #31!\n" \ + " CPS #31\n" \ + " PUSH {R0-R3, R12}"); \ + __asm(" AND R3, SP, #4\n" \ + " SUB SP, SP, R3\n" \ + " PUSH {R3, LR}\n"); \ + ++QK_priv_.intNest; { +#endif + +// QK-specific Interrupt Request handler END +#ifdef __ARM_FP +#define QK_IRQ_END() \ + } --QK_priv_.intNest; \ + if (QK_priv_.intNest == 0U) { \ + if (QK_sched_() != 0U) { \ + QK_activate_(); \ + } \ + } \ + __asm volatile (" POP {R3, LR}\n" \ + " ADD SP, SP, R3"); \ + __asm(" FLDMIAD SP!, {D0-D7}\n" \ + " LDMFD SP!, {R12}\n" \ + " FMXR FPEXC, R12 \n" \ + " LDMFD SP!, {R12} \n" \ + " FMXR FPSCR, R12"); \ + __asm(" POP {R0-R3, R12}\n" \ + " RFEIA SP!"); \ +} +#else +#define QK_IRQ_END() \ + } --QK_priv_.intNest; \ + if (QK_priv_.intNest == 0U) { \ + if (QK_sched_() != 0U) { \ + QK_activate_(); \ + } \ + } \ + __asm volatile (" POP {R3, LR}\n" \ + " ADD SP, SP, R3"); \ + __asm volatile (" POP {R0-R3, R12}\n" \ + " RFEIA SP!"); \ +} +#endif + +// include files ------------------------------------------------------------- +#include "qequeue.h" // QK kernel uses the native QP event queue +#include "qmpool.h" // QK kernel uses the native QP memory pool +#include "qp.h" // QP framework +#include "qk.h" // QK kernel + +//============================================================================ +// NOTE2: +// The FIQ-type interrupts are NEVER disabled in this port, so the FIQ is +// a "kernel-unaware" interrupt. If the FIQ is ever used in the application, +// it must be an "ARM FIQ"-type function. For this to work, the FIQ +// stack needs to be initialized. +// +// NOTE3: +// This port implements the "save and restore" interrupt status policy, +// which again never disables the FIQ-type interrupts. This policy allows +// for nesting critical sections, which is necessary inside IRQ-type +// interrupts that run with interrupts (IRQ) disabled. +// + +#endif // QP_PORT_H_ + diff --git a/ports/arm-cr/qk/gnu/qs_port.h b/ports/arm-cr/qk/gnu/qs_port.h index e8b00882..206b7e4c 100644 --- a/ports/arm-cr/qk/gnu/qs_port.h +++ b/ports/arm-cr/qk/gnu/qs_port.h @@ -1,60 +1,56 @@ -/*============================================================================ -* QP/C Real-Time Embedded Framework (RTEF) -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2022-06-12 -* @version Last updated for: @ref qpc_7_0_1 -* -* @file -* @brief QS/C port to a 32-bit CPU and a generic C99 compiler. -* @description -* This is an example of a QP/C port with the documentation for the -* configuration macros and includes. -*/ -#ifndef QS_PORT_H -#define QS_PORT_H +//============================================================================ +// QP/C Real-Time Embedded Framework (RTEF) +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +//============================================================================ +//! @date Last updated on: 2023-08-16 +//! @version Last updated for: @ref qpc_7_3_0 +//! +//! @file +//! @brief QS/C port to a 32-bit CPU and a generic C11 compiler. -/* QS time-stamp size in bytes */ -#define QS_TIME_SIZE 4 +#ifndef QS_PORT_H_ +#define QS_PORT_H_ -/* object pointer size in bytes */ -#define QS_OBJ_PTR_SIZE 4 +// QS time-stamp size in bytes +#define QS_TIME_SIZE 4U -/* function pointer size in bytes */ -#define QS_FUN_PTR_SIZE 4 +// object pointer size in bytes +#define QS_OBJ_PTR_SIZE 4U -/*==========================================================================*/ -/* NOTE: QS might be used with or without other QP components, in which -* case the separate definitions of the macros QF_CRIT_STAT_TYPE, -* QF_CRIT_ENTRY, and QF_CRIT_EXIT are needed. In this port QS is configured -* to be used with the other QP component, by simply including "qf_port.h" -* *before* "qs.h". -*/ -#ifndef QF_PORT_H -#include "qf_port.h" /* use QS with QF */ +// function pointer size in bytes +#define QS_FUN_PTR_SIZE 4U + +//============================================================================ +// NOTE: QS might be used with or without other QP components, in which +// case the separate definitions of the macros QF_CRIT_STAT, QF_CRIT_ENTRY(), +// and QF_CRIT_EXIT() are needed. In this port QS is configured to be used +// with the other QP component, by simply including "qp_port.h" +//*before* "qs.h". +#ifndef QP_PORT_H_ +#include "qp_port.h" // use QS with QF #endif -#include "qs.h" /* QS platform-independent public interface */ +#include "qs.h" // QS platform-independent public interface + +#endif // QS_PORT_H_ -#endif /* QS_PORT_H */ diff --git a/ports/arm-cr/qk/iar/qep_port.h b/ports/arm-cr/qk/iar/qep_port.h deleted file mode 100644 index a6607ff9..00000000 --- a/ports/arm-cr/qk/iar/qep_port.h +++ /dev/null @@ -1,40 +0,0 @@ -/*============================================================================ -* QP/C Real-Time Embedded Framework (RTEF) -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2022-07-30 -* @version Last updated for: @ref qpc_7_0_1 -* -* @file -* @brief QEP/C port, generic C99 compiler -*/ -#ifndef QEP_PORT_H -#define QEP_PORT_H - -#include /* Exact-width types. WG14/N843 C99 Standard */ -#include /* Boolean type. WG14/N843 C99 Standard */ - -#include "qep.h" /* QEP platform-independent public interface */ - -#endif /* QEP_PORT_H */ diff --git a/ports/arm-cr/qk/iar/qf_port.h b/ports/arm-cr/qk/iar/qf_port.h deleted file mode 100644 index a47b4df6..00000000 --- a/ports/arm-cr/qk/iar/qf_port.h +++ /dev/null @@ -1,81 +0,0 @@ -/*============================================================================ -* QP/C Real-Time Embedded Framework (RTEF) -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2022-07-30 -* @version Last updated for: @ref qpc_7_0_1 -* -* @file -* @brief QF/C port to Cortex-R, preemptive QK kernel, IAR-ARM toolset -*/ -#ifndef QF_PORT_H -#define QF_PORT_H - -/* The maximum number of active objects in the application, see NOTE1 */ -#define QF_MAX_ACTIVE 32U - -/* The maximum number of system clock tick rates */ -#define QF_MAX_TICK_RATE 2U - -/* QF interrupt disable/enable, see NOTE2 */ -#define QF_INT_DISABLE() __disable_irq() -#define QF_INT_ENABLE() __enable_irq() -#define QF_INT_ENABLE_ALL() __enable_interrupt() - -/* Cortex-R provide the CLZ instruction for fast LOG2 */ -#define QF_LOG2(n_) ((uint8_t)(32U - __CLZ(n_))) - -/* QF critical section entry/exit, see NOTE3 */ -#define QF_CRIT_STAT_TYPE uint32_t -#define QF_CRIT_ENTRY(status_) do { \ - (status_) = __get_CPSR(); \ - QF_INT_DISABLE(); \ -} while (false) -#define QF_CRIT_EXIT(status_) __set_CPSR((status_)) -#define QF_CRIT_EXIT_NOP() __ISB() - -#include /* IAR intrinsic functions */ -#include "qep_port.h" /* QEP port */ -#include "qk_port.h" /* QK port */ -#include "qf.h" /* QF platform-independent public interface */ - -/***************************************************************************** -* NOTE1: -* The maximum number of active objects QF_MAX_ACTIVE can be increased -* up to 63, if necessary. Here it is set to a lower level to save some RAM. -* -* NOTE2: -* The FIQ-type interrupts are NEVER disabled in this port, so the FIQ is -* a "kernel-unaware" interrupt. If the FIQ is ever used in the application, -* it must be an "__arm __fiq"-type function. For this to work, the FIQ -* stack needs to be initialized. -* -* NOTE3: -* This port implements the "save and restore" interrupt status policy, -* which again never disables the FIQ-type interrupts. This policy allows -* for nesting critical sections, which is necessary inside IRQ-type -* interrupts that run with interrupts (IRQ) disabled. -*/ - -#endif /* QF_PORT_H */ diff --git a/ports/arm-cr/qk/iar/qk_port.h b/ports/arm-cr/qk/iar/qk_port.h deleted file mode 100644 index aa15a450..00000000 --- a/ports/arm-cr/qk/iar/qk_port.h +++ /dev/null @@ -1,101 +0,0 @@ -/*============================================================================ -* QP/C Real-Time Embedded Framework (RTEF) -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2022-10-02 -* @version Last updated for: @ref qpc_7_1_2 -* -* @file -* @brief QK/C port to ARM Cortex-R, IAR-ARM toolset -*/ -#ifndef QK_PORT_H -#define QK_PORT_H - -/* QK-specific Interrupt Request handler BEGIN */ -#ifdef __ARMVFP__ -#define QK_IRQ_BEGIN(name_) \ - __stackless __arm void name_(void) { \ - __asm(" SUB LR, LR, #4\n" \ - " SRSDB #31!\n" \ - " CPS #31\n" \ - " PUSH {R0-R3, R12}"); \ - __asm(" FMRX R12, FPSCR\n" \ - " STMFD SP!, {R12}\n" \ - " FMRX R12, FPEXC\n" \ - " STMFD SP!, {R12}\n" \ - " FSTMDBD SP!, {D0-D7}"); \ - __asm(" AND R3, SP, #4\n" \ - " SUB SP, SP, R3\n" \ - " PUSH {R3, LR}\n"); \ - ++QF_intNest_; { -#else -#define QK_IRQ_BEGIN(name_) \ - __stackless __arm void name_(void) { \ - __asm(" SUB LR, LR, #4\n" \ - " SRSDB #31!\n" \ - " CPS #31\n" \ - " PUSH {R0-R3, R12}"); \ - __asm(" AND R3, SP, #4\n" \ - " SUB SP, SP, R3\n" \ - " PUSH {R3, LR}\n"); \ - ++QF_intNest_; { -#endif - -/* QK-specific Interrupt Request handler END */ -#ifdef __ARMVFP__ -#define QK_IRQ_END() \ - } --QF_intNest_; \ - if (QF_intNest_ == 0U) { \ - if (QK_sched_() != 0U) { \ - QK_activate_(); \ - } \ - } \ - __asm(" POP {R3, LR}\n" \ - " ADD SP, SP, R3"); \ - __asm(" FLDMIAD SP!, {D0-D7}\n" \ - " LDMFD SP!, {R12}\n" \ - " FMXR FPEXC, R12 \n" \ - " LDMFD SP!, {R12} \n" \ - " FMXR FPSCR, R12"); \ - __asm(" POP {R0-R3, R12}\n" \ - " RFEIA SP!"); \ -} -#else -#define QK_IRQ_END() \ - } --QF_intNest_; \ - if (QF_intNest_ == 0U) { \ - if (QK_sched_() != 0U) { \ - QK_activate_(); \ - } \ - } \ - __asm(" POP {R3, LR}\n" \ - " ADD SP, SP, R3"); \ - __asm(" POP {R0-R3, R12}\n" \ - " RFEIA SP!"); \ -} -#endif - -#include "qk.h" /* QK platform-independent public interface */ - -#endif /* QK_PORT_H */ diff --git a/ports/arm-cr/qk/iar/qp_port.h b/ports/arm-cr/qk/iar/qp_port.h new file mode 100644 index 00000000..4edfd0e9 --- /dev/null +++ b/ports/arm-cr/qk/iar/qp_port.h @@ -0,0 +1,160 @@ +//============================================================================ +// QP/C Real-Time Embedded Framework (RTEF) +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +//============================================================================ +//! @date Last updated on: 2023-09-07 +//! @version Last updated for: @ref qpc_7_3_0 +//! +//! @file +//! @brief QP/C port to ARM Cortex-R, preemptive QK kernel, IAR-ARM + +#ifndef QP_PORT_H_ +#define QP_PORT_H_ + +#include // Exact-width types. WG14/N843 C99 Standard +#include // Boolean type. WG14/N843 C99 Standard +#include // IAR intrinsic functions + +#ifdef QP_CONFIG +#include "qp_config.h" // external QP configuration +#endif + +// no-return function specifier (C11 Standard) +#define Q_NORETURN _Noreturn void + +// QF configuration for QK -- data members of the QActive class... + +// QK event-queue used for AOs +#define QACTIVE_EQUEUE_TYPE QEQueue + +// QF interrupt disable/enable, see NOTE2 +#define QF_INT_DISABLE() __disable_irq() +#define QF_INT_ENABLE() __enable_irq() +#define QF_INT_ENABLE_ALL() __enable_interrupt() + +// Cortex-R provide the CLZ instruction for fast LOG2 +#define QF_LOG2(n_) ((uint8_t)(32U - __CLZ(n_))) + +// QF critical section entry/exit, see NOTE3 +#define QF_CRIT_STAT uint32_t cpsr_; +#define QF_CRIT_ENTRY() do { \ + cpsr_ = __get_CPSR(); \ + QF_INT_DISABLE(); \ +} while (false) +#define QF_CRIT_EXIT() __set_CPSR(cpsr_) +#define QF_CRIT_EXIT_NOP() __ISB() + +// Check if the code executes in the ISR context +#define QK_ISR_CONTEXT_() (QK_priv_.intNest != 0U) + +// QK-specific Interrupt Request handler BEGIN +#ifdef __ARMVFP__ +#define QK_IRQ_BEGIN(name_) \ + __stackless __arm void name_(void) { \ + __asm(" SUB LR, LR, #4\n" \ + " SRSDB #31!\n" \ + " CPS #31\n" \ + " PUSH {R0-R3, R12}"); \ + __asm(" FMRX R12, FPSCR\n" \ + " STMFD SP!, {R12}\n" \ + " FMRX R12, FPEXC\n" \ + " STMFD SP!, {R12}\n" \ + " FSTMDBD SP!, {D0-D7}"); \ + __asm(" AND R3, SP, #4\n" \ + " SUB SP, SP, R3\n" \ + " PUSH {R3, LR}\n"); \ + ++QK_priv_.intNest; { +#else +#define QK_IRQ_BEGIN(name_) \ + __stackless __arm void name_(void) { \ + __asm(" SUB LR, LR, #4\n" \ + " SRSDB #31!\n" \ + " CPS #31\n" \ + " PUSH {R0-R3, R12}"); \ + __asm(" AND R3, SP, #4\n" \ + " SUB SP, SP, R3\n" \ + " PUSH {R3, LR}\n"); \ + ++QK_priv_.intNest; { +#endif + +// QK-specific Interrupt Request handler END +#ifdef __ARMVFP__ +#define QK_IRQ_END() \ + } --QK_priv_.intNest; \ + if (QK_priv_.intNest == 0U) { \ + if (QK_sched_() != 0U) { \ + QK_activate_(); \ + } \ + } \ + __asm(" POP {R3, LR}\n" \ + " ADD SP, SP, R3"); \ + __asm(" FLDMIAD SP!, {D0-D7}\n" \ + " LDMFD SP!, {R12}\n" \ + " FMXR FPEXC, R12 \n" \ + " LDMFD SP!, {R12} \n" \ + " FMXR FPSCR, R12"); \ + __asm(" POP {R0-R3, R12}\n" \ + " RFEIA SP!"); \ +} +#else +#define QK_IRQ_END() \ + } --QK_priv_.intNest; \ + if (QK_priv_.intNest == 0U) { \ + if (QK_sched_() != 0U) { \ + QK_activate_(); \ + } \ + } \ + __asm(" POP {R3, LR}\n" \ + " ADD SP, SP, R3"); \ + __asm(" POP {R0-R3, R12}\n" \ + " RFEIA SP!"); \ +} +#endif + +// include files ------------------------------------------------------------- +#include "qequeue.h" // QK kernel uses the native QP event queue +#include "qmpool.h" // QK kernel uses the native QP memory pool +#include "qp.h" // QP framework +#include "qk.h" // QK kernel + +//============================================================================ +// NOTE2: +// The FIQ-type interrupts are NEVER disabled in this port, so the FIQ is +// a "kernel-unaware" interrupt. If the FIQ is ever used in the application, +// it must be an "__arm __fiq"-type function. For this to work, the FIQ +// stack needs to be initialized. +// +// NOTE3: +// This port implements the "save and restore" interrupt status policy, +// which again never disables the FIQ-type interrupts. This policy allows +// for nesting critical sections, which is necessary inside IRQ-type +// interrupts that run with interrupts (IRQ) disabled. +// + +#endif // QP_PORT_H_ + diff --git a/ports/arm-cr/qk/iar/qs_port.h b/ports/arm-cr/qk/iar/qs_port.h index e8b00882..206b7e4c 100644 --- a/ports/arm-cr/qk/iar/qs_port.h +++ b/ports/arm-cr/qk/iar/qs_port.h @@ -1,60 +1,56 @@ -/*============================================================================ -* QP/C Real-Time Embedded Framework (RTEF) -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2022-06-12 -* @version Last updated for: @ref qpc_7_0_1 -* -* @file -* @brief QS/C port to a 32-bit CPU and a generic C99 compiler. -* @description -* This is an example of a QP/C port with the documentation for the -* configuration macros and includes. -*/ -#ifndef QS_PORT_H -#define QS_PORT_H +//============================================================================ +// QP/C Real-Time Embedded Framework (RTEF) +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +//============================================================================ +//! @date Last updated on: 2023-08-16 +//! @version Last updated for: @ref qpc_7_3_0 +//! +//! @file +//! @brief QS/C port to a 32-bit CPU and a generic C11 compiler. -/* QS time-stamp size in bytes */ -#define QS_TIME_SIZE 4 +#ifndef QS_PORT_H_ +#define QS_PORT_H_ -/* object pointer size in bytes */ -#define QS_OBJ_PTR_SIZE 4 +// QS time-stamp size in bytes +#define QS_TIME_SIZE 4U -/* function pointer size in bytes */ -#define QS_FUN_PTR_SIZE 4 +// object pointer size in bytes +#define QS_OBJ_PTR_SIZE 4U -/*==========================================================================*/ -/* NOTE: QS might be used with or without other QP components, in which -* case the separate definitions of the macros QF_CRIT_STAT_TYPE, -* QF_CRIT_ENTRY, and QF_CRIT_EXIT are needed. In this port QS is configured -* to be used with the other QP component, by simply including "qf_port.h" -* *before* "qs.h". -*/ -#ifndef QF_PORT_H -#include "qf_port.h" /* use QS with QF */ +// function pointer size in bytes +#define QS_FUN_PTR_SIZE 4U + +//============================================================================ +// NOTE: QS might be used with or without other QP components, in which +// case the separate definitions of the macros QF_CRIT_STAT, QF_CRIT_ENTRY(), +// and QF_CRIT_EXIT() are needed. In this port QS is configured to be used +// with the other QP component, by simply including "qp_port.h" +//*before* "qs.h". +#ifndef QP_PORT_H_ +#include "qp_port.h" // use QS with QF #endif -#include "qs.h" /* QS platform-independent public interface */ +#include "qs.h" // QS platform-independent public interface + +#endif // QS_PORT_H_ -#endif /* QS_PORT_H */ diff --git a/ports/arm-cr/qk/ti/qep_port.h b/ports/arm-cr/qk/ti/qep_port.h deleted file mode 100644 index a6607ff9..00000000 --- a/ports/arm-cr/qk/ti/qep_port.h +++ /dev/null @@ -1,40 +0,0 @@ -/*============================================================================ -* QP/C Real-Time Embedded Framework (RTEF) -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2022-07-30 -* @version Last updated for: @ref qpc_7_0_1 -* -* @file -* @brief QEP/C port, generic C99 compiler -*/ -#ifndef QEP_PORT_H -#define QEP_PORT_H - -#include /* Exact-width types. WG14/N843 C99 Standard */ -#include /* Boolean type. WG14/N843 C99 Standard */ - -#include "qep.h" /* QEP platform-independent public interface */ - -#endif /* QEP_PORT_H */ diff --git a/ports/arm-cr/qk/ti/qf_port.h b/ports/arm-cr/qk/ti/qf_port.h deleted file mode 100644 index f0dc26bc..00000000 --- a/ports/arm-cr/qk/ti/qf_port.h +++ /dev/null @@ -1,90 +0,0 @@ -/*============================================================================ - -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2022-07-30 -* @version Last updated for: @ref qpc_7_0_1 -* -* @file -* @brief QF/C port to Cortex-R, preemptive QK kernel, TI-ARM toolset -*/ -#ifndef QF_PORT_H -#define QF_PORT_H - -/* The maximum number of active objects in the application, see NOTE1 */ -#define QF_MAX_ACTIVE 32U - -/* The maximum number of system clock tick rates */ -#define QF_MAX_TICK_RATE 2U - -/* QF interrupt disable/enable, see NOTE2 */ -#ifdef __16bis__ - #define QF_INT_DISABLE() __asm(" CPSID i") - #define QF_INT_ENABLE() __asm(" CPSIE i") - #define QF_INT_ENABLE_ALL() __asm(" CPSIE if") -#else - #define QF_INT_DISABLE() _disable_IRQ() - #define QF_INT_ENABLE() _enable_IRQ() - #define QF_INT_ENABLE_ALL() _enable_interrupts() -#endif - -/* Cortex-R provide the CLZ instruction for fast LOG2 */ -#define QF_LOG2(n_) ((uint8_t)(32U - __clz(n_))) - -/* QF critical section entry/exit, see NOTE3 */ -#define QF_CRIT_STAT_TYPE uint32_t -#define QF_CRIT_ENTRY(status_) do { \ - (status_) = _get_CPSR(); \ - QF_INT_DISABLE(); \ -} while (false) -#define QF_CRIT_EXIT(status_) do { \ - if (((status_) & (1U << 7)) == 0) { \ - QF_INT_ENABLE(); \ - } \ -} while (false) -#define QF_CRIT_EXIT_NOP() __asm(" ISB") - -#include "qep_port.h" /* QEP port */ -#include "qk_port.h" /* QK port */ -#include "qf.h" /* QF platform-independent public interface */ - -/***************************************************************************** -* NOTE1: -* The maximum number of active objects QF_MAX_ACTIVE can be increased -* up to 63, if necessary. Here it is set to a lower level to save some RAM. -* -* NOTE2: -* The FIQ-type interrupts are NEVER disabled in this port, so the FIQ is -* a "kernel-unaware" interrupt. If the FIQ is ever used in the application, -* it must be an "ARM FIQ"-type function. For this to work, the FIQ -* stack needs to be initialized. -* -* NOTE3: -* This port implements the "save and restore" interrupt status policy, -* which again never disables the FIQ-type interrupts. This policy allows -* for nesting critical sections, which is necessary inside IRQ-type -* interrupts that run with interrupts (IRQ) disabled. -*/ - -#endif /* QF_PORT_H */ diff --git a/ports/arm-cr/qk/ti/qk_port.h b/ports/arm-cr/qk/ti/qk_port.h deleted file mode 100644 index 74bf67ad..00000000 --- a/ports/arm-cr/qk/ti/qk_port.h +++ /dev/null @@ -1,84 +0,0 @@ -/*============================================================================ -* QP/C Real-Time Embedded Framework (RTEF) -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2022-10-02 -* @version Last updated for: @ref qpc_7_1_2 -* -* @file -* @brief QK/C port to ARM Cortex-R, TI-ARM toolset -*/ -#ifndef QK_PORT_H -#define QK_PORT_H - -/* QK-specific Interrupt Request handler BEGIN */ -#define QK_IRQ_BEGIN(name_) \ - void name_(void); \ - __asm(" .def " #name_ "\n" \ - " .arm\n" \ - " .align 4\n" \ - " .armfunc " #name_ "\n" \ - #name_":\n" \ - " SUB LR, LR, #4\n" \ - " SRSDB #31!\n" \ - " CPS #31\n" \ - " PUSH {R0-R3, R12}\n" \ - " .if __TI_VFPV3D16_SUPPORT__ = 1\n" \ - " FMRX R12, FPSCR\n" \ - " STMFD SP!, {R12}\n" \ - " FMRX R12, FPEXC\n" \ - " STMFD SP!, {R12}\n" \ - " FSTMDBD SP!, {D0-D7}\n" \ - " .endif\n" \ - " AND R3, SP, #4\n" \ - " SUB SP, SP, R3\n" \ - " PUSH {R3, LR}\n" \ - " BLX " #name_ "_isr\n" \ - " POP {R3, LR}\n" \ - " ADD SP, SP, R3\n" \ - " .if __TI_VFPV3D16_SUPPORT__ = 1\n" \ - " FLDMIAD SP!, {D0-D7}\n" \ - " LDMFD SP!, {R12}\n" \ - " FMXR FPEXC, R12 \n" \ - " LDMFD SP!, {R12} \n" \ - " FMXR FPSCR, R12\n" \ - " .endif\n" \ - " POP {R0-R3, R12}\n" \ - " RFEIA SP!\n"); \ - void name_ ## _isr(void) { \ - ++QF_intNest_; { - -/* QK-specific Interrupt Request handler END */ -#define QK_IRQ_END() \ - } --QF_intNest_; \ - if (QF_intNest_ == 0U) { \ - if (QK_sched_() != 0U) { \ - QK_activate_(); \ - } \ - } \ -} - -#include "qk.h" /* QK platform-independent public interface */ - -#endif /* QK_PORT_H */ diff --git a/ports/arm-cr/qk/ti/qp_port.h b/ports/arm-cr/qk/ti/qp_port.h new file mode 100644 index 00000000..b6906f41 --- /dev/null +++ b/ports/arm-cr/qk/ti/qp_port.h @@ -0,0 +1,152 @@ +//============================================================================ +// QP/C Real-Time Embedded Framework (RTEF) +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +//============================================================================ +//! @date Last updated on: 2023-09-07 +//! @version Last updated for: @ref qpc_7_3_0 +//! +//! @file +//! @brief QP/C port to ARM Cortex-R, preemptive QK kernel, TI-ARM + +#ifndef QP_PORT_H_ +#define QP_PORT_H_ + +#include // Exact-width types. WG14/N843 C99 Standard +#include // Boolean type. WG14/N843 C99 Standard + +#ifdef QP_CONFIG +#include "qp_config.h" // external QP configuration +#endif + +// no-return function specifier (C11 Standard) +#define Q_NORETURN _Noreturn void + +// QF configuration for QK -- data members of the QActive class... + +// QK event-queue used for AOs +#define QACTIVE_EQUEUE_TYPE QEQueue + +// QF interrupt disable/enable, see NOTE2 +#ifdef __16bis__ + #define QF_INT_DISABLE() __asm(" CPSID i") + #define QF_INT_ENABLE() __asm(" CPSIE i") + #define QF_INT_ENABLE_ALL() __asm(" CPSIE if") +#else + #define QF_INT_DISABLE() _disable_IRQ() + #define QF_INT_ENABLE() _enable_IRQ() + #define QF_INT_ENABLE_ALL() _enable_interrupts() +#endif + +// Cortex-R provide the CLZ instruction for fast LOG2 +#define QF_LOG2(n_) ((uint8_t)(32U - __clz(n_))) + +// QF critical section entry/exit, see NOTE3 +#define QF_CRIT_STAT uint32_t cpsr_; +#define QF_CRIT_ENTRY() do { \ + cpsr_ = _get_CPSR(); \ + QF_INT_DISABLE(); \ +} while (false) +#define QF_CRIT_EXIT() do { \ + if ((cpsr_ & (1U << 7U)) == 0U) { \ + QF_INT_ENABLE(); \ + } \ +} while (false) +#define QF_CRIT_EXIT_NOP() __asm(" ISB") + +// Check if the code executes in the ISR context +#define QK_ISR_CONTEXT_() (QK_priv_.intNest != 0U) + +// QK-specific Interrupt Request handler BEGIN +#define QK_IRQ_BEGIN(name_) \ + void name_(void); \ + __asm(" .def " #name_ "\n" \ + " .arm\n" \ + " .align 4\n" \ + " .armfunc " #name_ "\n" \ + #name_":\n" \ + " SUB LR, LR, #4\n" \ + " SRSDB #31!\n" \ + " CPS #31\n" \ + " PUSH {R0-R3, R12}\n" \ + " .if __TI_VFPV3D16_SUPPORT__ = 1\n" \ + " FMRX R12, FPSCR\n" \ + " STMFD SP!, {R12}\n" \ + " FMRX R12, FPEXC\n" \ + " STMFD SP!, {R12}\n" \ + " FSTMDBD SP!, {D0-D7}\n" \ + " .endif\n" \ + " AND R3, SP, #4\n" \ + " SUB SP, SP, R3\n" \ + " PUSH {R3, LR}\n" \ + " BLX " #name_ "_isr\n" \ + " POP {R3, LR}\n" \ + " ADD SP, SP, R3\n" \ + " .if __TI_VFPV3D16_SUPPORT__ = 1\n" \ + " FLDMIAD SP!, {D0-D7}\n" \ + " LDMFD SP!, {R12}\n" \ + " FMXR FPEXC, R12 \n" \ + " LDMFD SP!, {R12} \n" \ + " FMXR FPSCR, R12\n" \ + " .endif\n" \ + " POP {R0-R3, R12}\n" \ + " RFEIA SP!\n"); \ + void name_ ## _isr(void) { \ + ++QK_priv_.intNest; { + +// QK-specific Interrupt Request handler END +#define QK_IRQ_END() \ + } --QK_priv_.intNest; \ + if (QK_priv_.intNest == 0U) { \ + if (QK_sched_() != 0U) { \ + QK_activate_(); \ + } \ + } \ +} + +// include files ------------------------------------------------------------- +#include "qequeue.h" // QK kernel uses the native QP event queue +#include "qmpool.h" // QK kernel uses the native QP memory pool +#include "qp.h" // QP framework +#include "qk.h" // QK kernel + +//============================================================================ +// NOTE2: +// The FIQ-type interrupts are NEVER disabled in this port, so the FIQ is +// a "kernel-unaware" interrupt. If the FIQ is ever used in the application, +// it must be an "ARM FIQ"-type function. For this to work, the FIQ +// stack needs to be initialized. +// +// NOTE3: +// This port implements the "save and restore" interrupt status policy, +// which again never disables the FIQ-type interrupts. This policy allows +// for nesting critical sections, which is necessary inside IRQ-type +// interrupts that run with interrupts (IRQ) disabled. +// + +#endif // QP_PORT_H_ + diff --git a/ports/arm-cr/qk/ti/qs_port.h b/ports/arm-cr/qk/ti/qs_port.h index e8b00882..206b7e4c 100644 --- a/ports/arm-cr/qk/ti/qs_port.h +++ b/ports/arm-cr/qk/ti/qs_port.h @@ -1,60 +1,56 @@ -/*============================================================================ -* QP/C Real-Time Embedded Framework (RTEF) -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2022-06-12 -* @version Last updated for: @ref qpc_7_0_1 -* -* @file -* @brief QS/C port to a 32-bit CPU and a generic C99 compiler. -* @description -* This is an example of a QP/C port with the documentation for the -* configuration macros and includes. -*/ -#ifndef QS_PORT_H -#define QS_PORT_H +//============================================================================ +// QP/C Real-Time Embedded Framework (RTEF) +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +//============================================================================ +//! @date Last updated on: 2023-08-16 +//! @version Last updated for: @ref qpc_7_3_0 +//! +//! @file +//! @brief QS/C port to a 32-bit CPU and a generic C11 compiler. -/* QS time-stamp size in bytes */ -#define QS_TIME_SIZE 4 +#ifndef QS_PORT_H_ +#define QS_PORT_H_ -/* object pointer size in bytes */ -#define QS_OBJ_PTR_SIZE 4 +// QS time-stamp size in bytes +#define QS_TIME_SIZE 4U -/* function pointer size in bytes */ -#define QS_FUN_PTR_SIZE 4 +// object pointer size in bytes +#define QS_OBJ_PTR_SIZE 4U -/*==========================================================================*/ -/* NOTE: QS might be used with or without other QP components, in which -* case the separate definitions of the macros QF_CRIT_STAT_TYPE, -* QF_CRIT_ENTRY, and QF_CRIT_EXIT are needed. In this port QS is configured -* to be used with the other QP component, by simply including "qf_port.h" -* *before* "qs.h". -*/ -#ifndef QF_PORT_H -#include "qf_port.h" /* use QS with QF */ +// function pointer size in bytes +#define QS_FUN_PTR_SIZE 4U + +//============================================================================ +// NOTE: QS might be used with or without other QP components, in which +// case the separate definitions of the macros QF_CRIT_STAT, QF_CRIT_ENTRY(), +// and QF_CRIT_EXIT() are needed. In this port QS is configured to be used +// with the other QP component, by simply including "qp_port.h" +//*before* "qs.h". +#ifndef QP_PORT_H_ +#include "qp_port.h" // use QS with QF #endif -#include "qs.h" /* QS platform-independent public interface */ +#include "qs.h" // QS platform-independent public interface + +#endif // QS_PORT_H_ -#endif /* QS_PORT_H */ diff --git a/ports/arm-cr/qv/gnu/qep_port.h b/ports/arm-cr/qv/gnu/qep_port.h deleted file mode 100644 index a6607ff9..00000000 --- a/ports/arm-cr/qv/gnu/qep_port.h +++ /dev/null @@ -1,40 +0,0 @@ -/*============================================================================ -* QP/C Real-Time Embedded Framework (RTEF) -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2022-07-30 -* @version Last updated for: @ref qpc_7_0_1 -* -* @file -* @brief QEP/C port, generic C99 compiler -*/ -#ifndef QEP_PORT_H -#define QEP_PORT_H - -#include /* Exact-width types. WG14/N843 C99 Standard */ -#include /* Boolean type. WG14/N843 C99 Standard */ - -#include "qep.h" /* QEP platform-independent public interface */ - -#endif /* QEP_PORT_H */ diff --git a/ports/arm-cr/qv/gnu/qf_port.h b/ports/arm-cr/qv/gnu/qf_port.h deleted file mode 100644 index db10281d..00000000 --- a/ports/arm-cr/qv/gnu/qf_port.h +++ /dev/null @@ -1,95 +0,0 @@ -/*============================================================================ -* QP/C Real-Time Embedded Framework (RTEF) -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2022-07-30 -* @version Last updated for: @ref qpc_7_0_1 -* -* @file -* @brief QF/C port to Cortex-R, cooperative QV kernel, GNU-ARM toolset -*/ -#ifndef QF_PORT_H -#define QF_PORT_H - -/* The maximum number of active objects in the application, see NOTE1 */ -#define QF_MAX_ACTIVE 32U - -/* The maximum number of system clock tick rates */ -#define QF_MAX_TICK_RATE 2U - -/* QF interrupt disable/enable, see NOTE2 */ -#ifdef __thumb__ /* THUMB mode? */ - - #define QF_INT_DISABLE() __asm volatile ("cpsid i") - #define QF_INT_ENABLE() __asm volatile ("cpsie i") - #define QF_INT_ENABLE_ALL() __asm volatile ("cpsie if") - -#elif (defined __arm__) /* ARM mode? */ - - #define QF_INT_DISABLE() \ - __asm volatile ("MSR cpsr_c,#(0x1F | 0x80)" ::: "cc") - #define QF_INT_ENABLE() \ - __asm volatile ("MSR cpsr_c,#(0x1F)" ::: "cc") - #define QF_INT_ENABLE_ALL() \ - __asm volatile ("MSR cpsr_c,#(0x1F | 0x80 | 0x40)" ::: "cc") -#else - #error Incorrect CPU mode. Must be either __arm__ or __thumb__. -#endif - -/* Cortex-R provide the CLZ instruction for fast LOG2 */ -#define QF_LOG2(n_) ((uint8_t)(32U - __builtin_clz(n_))) - -/* QF critical section entry/exit, see NOTE3 */ -#define QF_CRIT_STAT_TYPE uint32_t -#define QF_CRIT_ENTRY(stat_) do { \ - __asm volatile ("MRS %0,cpsr" : "=r" (stat_) :: "cc"); \ - QF_INT_DISABLE(); \ -} while (false) -#define QF_CRIT_EXIT(stat_) \ - __asm volatile ("MSR cpsr_c,%0" :: "r" (stat_) : "cc") -#define QF_CRIT_EXIT_NOP() __asm volatile ("ISB") - -#include "qep_port.h" /* QEP port */ -#include "qv_port.h" /* QV port */ -#include "qf.h" /* QF platform-independent public interface */ - -/***************************************************************************** -* NOTE1: -* The maximum number of active objects QF_MAX_ACTIVE can be increased -* up to 63, if necessary. Here it is set to a lower level to save some RAM. -* -* NOTE2: -* The FIQ-type interrupts are NEVER disabled in this port, so the FIQ is -* a "kernel-unaware" interrupt. If the FIQ is ever used in the application, -* it must be an "ARM FIQ"-type function. For this to work, the FIQ -* stack needs to be initialized. -* -* NOTE3: -* This port implements the "save and restore" interrupt status policy, -* which again never disables the FIQ-type interrupts. This policy allows -* for nesting critical sections, which is necessary inside IRQ-type -* interrupts that run with interrupts (IRQ) disabled. -*/ - -#endif /* QF_PORT_H */ diff --git a/ports/arm-cr/qv/gnu/qp_port.h b/ports/arm-cr/qv/gnu/qp_port.h new file mode 100644 index 00000000..89ac11de --- /dev/null +++ b/ports/arm-cr/qv/gnu/qp_port.h @@ -0,0 +1,115 @@ +//============================================================================ +// QP/C Real-Time Embedded Framework (RTEF) +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +//============================================================================ +//! @date Last updated on: 2023-09-07 +//! @version Last updated for: @ref qpc_7_3_0 +//! +//! @file +//! @brief QP/C port to ARM Cortex-R, cooperative QV kernel, GNU-ARM + +#ifndef QP_PORT_H_ +#define QP_PORT_H_ + +#include // Exact-width types. WG14/N843 C99 Standard +#include // Boolean type. WG14/N843 C99 Standard + +#ifdef QP_CONFIG +#include "qp_config.h" // external QP configuration +#endif + +// no-return function specifier (GNU-ARM compiler) +#define Q_NORETURN __attribute__ ((noreturn)) void + +// QF configuration for QV -- data members of the QActive class... + +// QV event-queue used for AOs +#define QACTIVE_EQUEUE_TYPE QEQueue + +// QF interrupt disable/enable, see NOTE2 +#ifdef __thumb__ // THUMB mode? + + #define QF_INT_DISABLE() __asm volatile ("cpsid i") + #define QF_INT_ENABLE() __asm volatile ("cpsie i") + #define QF_INT_ENABLE_ALL() __asm volatile ("cpsie if") + +#elif (defined __arm__) // ARM mode? + + #define QF_INT_DISABLE() \ + __asm volatile ("MSR cpsr_c,#(0x1F | 0x80)" ::: "cc") + #define QF_INT_ENABLE() \ + __asm volatile ("MSR cpsr_c,#(0x1F)" ::: "cc") + #define QF_INT_ENABLE_ALL() \ + __asm volatile ("MSR cpsr_c,#(0x1F | 0x80 | 0x40)" ::: "cc") +#else + #error Incorrect CPU mode. Must be either __arm__ or __thumb__. +#endif + +// Cortex-R provide the CLZ instruction for fast LOG2 +#define QF_LOG2(n_) ((uint8_t)(32U - __builtin_clz(n_))) + +// QF critical section entry/exit, see NOTE3 +#define QF_CRIT_STAT uint32_t cpsr_; +#define QF_CRIT_ENTRY() do { \ + __asm volatile ("MRS %0,cpsr" : "=r" (cpsr_) :: "cc"); \ + QF_INT_DISABLE(); \ +} while (false) + +#define QF_CRIT_EXIT() \ + __asm volatile ("MSR cpsr_c,%0" :: "r" (cpsr_) : "cc") + +#define QF_CRIT_EXIT_NOP() __asm volatile ("ISB") + +// macro to put the CPU to sleep inside QV_onIdle() +#define QV_CPU_SLEEP() do { \ + __asm volatile ("WFI"); \ + QF_INT_ENABLE(); \ +} while (false) + +// include files ------------------------------------------------------------- +#include "qequeue.h" // QV kernel uses the native QP event queue +#include "qmpool.h" // QV kernel uses the native QP memory pool +#include "qp.h" // QP framework +#include "qv.h" // QV kernel + +//============================================================================ +// NOTE2: +// The FIQ-type interrupts are NEVER disabled in this port, so the FIQ is +// a "kernel-unaware" interrupt. If the FIQ is ever used in the application, +// it must be an "ARM FIQ"-type function. For this to work, the FIQ +// stack needs to be initialized. +// +// NOTE3: +// This port implements the "save and restore" interrupt status policy, +// which again never disables the FIQ-type interrupts. This policy allows +// for nesting critical sections, which is necessary inside IRQ-type +// interrupts that run with interrupts (IRQ) disabled. +// + +#endif // QP_PORT_H_ + diff --git a/ports/arm-cr/qv/gnu/qs_port.h b/ports/arm-cr/qv/gnu/qs_port.h index e8b00882..206b7e4c 100644 --- a/ports/arm-cr/qv/gnu/qs_port.h +++ b/ports/arm-cr/qv/gnu/qs_port.h @@ -1,60 +1,56 @@ -/*============================================================================ -* QP/C Real-Time Embedded Framework (RTEF) -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2022-06-12 -* @version Last updated for: @ref qpc_7_0_1 -* -* @file -* @brief QS/C port to a 32-bit CPU and a generic C99 compiler. -* @description -* This is an example of a QP/C port with the documentation for the -* configuration macros and includes. -*/ -#ifndef QS_PORT_H -#define QS_PORT_H +//============================================================================ +// QP/C Real-Time Embedded Framework (RTEF) +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +//============================================================================ +//! @date Last updated on: 2023-08-16 +//! @version Last updated for: @ref qpc_7_3_0 +//! +//! @file +//! @brief QS/C port to a 32-bit CPU and a generic C11 compiler. -/* QS time-stamp size in bytes */ -#define QS_TIME_SIZE 4 +#ifndef QS_PORT_H_ +#define QS_PORT_H_ -/* object pointer size in bytes */ -#define QS_OBJ_PTR_SIZE 4 +// QS time-stamp size in bytes +#define QS_TIME_SIZE 4U -/* function pointer size in bytes */ -#define QS_FUN_PTR_SIZE 4 +// object pointer size in bytes +#define QS_OBJ_PTR_SIZE 4U -/*==========================================================================*/ -/* NOTE: QS might be used with or without other QP components, in which -* case the separate definitions of the macros QF_CRIT_STAT_TYPE, -* QF_CRIT_ENTRY, and QF_CRIT_EXIT are needed. In this port QS is configured -* to be used with the other QP component, by simply including "qf_port.h" -* *before* "qs.h". -*/ -#ifndef QF_PORT_H -#include "qf_port.h" /* use QS with QF */ +// function pointer size in bytes +#define QS_FUN_PTR_SIZE 4U + +//============================================================================ +// NOTE: QS might be used with or without other QP components, in which +// case the separate definitions of the macros QF_CRIT_STAT, QF_CRIT_ENTRY(), +// and QF_CRIT_EXIT() are needed. In this port QS is configured to be used +// with the other QP component, by simply including "qp_port.h" +//*before* "qs.h". +#ifndef QP_PORT_H_ +#include "qp_port.h" // use QS with QF #endif -#include "qs.h" /* QS platform-independent public interface */ +#include "qs.h" // QS platform-independent public interface + +#endif // QS_PORT_H_ -#endif /* QS_PORT_H */ diff --git a/ports/arm-cr/qv/gnu/qv_port.h b/ports/arm-cr/qv/gnu/qv_port.h deleted file mode 100644 index 3033d20c..00000000 --- a/ports/arm-cr/qv/gnu/qv_port.h +++ /dev/null @@ -1,43 +0,0 @@ -/*============================================================================ -* QP/C Real-Time Embedded Framework (RTEF) -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2022-07-30 -* @version Last updated for: @ref qpc_7_0_1 -* -* @file -* @brief QV/C port to ARM Cortex-R, GNU-ARM toolset -*/ -#ifndef QV_PORT_H -#define QV_PORT_H - -/* macro to put the CPU to sleep inside QV_onIdle() */ -#define QV_CPU_SLEEP() do { \ - __asm volatile ("WFI"); \ - QF_INT_ENABLE(); \ -} while (false) - -#include "qv.h" /* QV platform-independent public interface */ - -#endif /* QV_PORT_H */ diff --git a/ports/arm-cr/qv/iar/qep_port.h b/ports/arm-cr/qv/iar/qep_port.h deleted file mode 100644 index a6607ff9..00000000 --- a/ports/arm-cr/qv/iar/qep_port.h +++ /dev/null @@ -1,40 +0,0 @@ -/*============================================================================ -* QP/C Real-Time Embedded Framework (RTEF) -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2022-07-30 -* @version Last updated for: @ref qpc_7_0_1 -* -* @file -* @brief QEP/C port, generic C99 compiler -*/ -#ifndef QEP_PORT_H -#define QEP_PORT_H - -#include /* Exact-width types. WG14/N843 C99 Standard */ -#include /* Boolean type. WG14/N843 C99 Standard */ - -#include "qep.h" /* QEP platform-independent public interface */ - -#endif /* QEP_PORT_H */ diff --git a/ports/arm-cr/qv/iar/qf_port.h b/ports/arm-cr/qv/iar/qf_port.h deleted file mode 100644 index efff9a99..00000000 --- a/ports/arm-cr/qv/iar/qf_port.h +++ /dev/null @@ -1,81 +0,0 @@ -/*============================================================================ -* QP/C Real-Time Embedded Framework (RTEF) -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2022-07-30 -* @version Last updated for: @ref qpc_7_0_1 -* -* @file -* @brief QF/C port to Cortex-R, cooperative QV kernel, IAR-ARM toolset -*/ -#ifndef QF_PORT_H -#define QF_PORT_H - -/* The maximum number of active objects in the application, see NOTE1 */ -#define QF_MAX_ACTIVE 32U - -/* The maximum number of system clock tick rates */ -#define QF_MAX_TICK_RATE 2U - -/* QF interrupt disable/enable, see NOTE2 */ -#define QF_INT_DISABLE() __disable_irq() -#define QF_INT_ENABLE() __enable_irq() -#define QF_INT_ENABLE_ALL() __enable_interrupt() - -/* Cortex-R provide the CLZ instruction for fast LOG2 */ -#define QF_LOG2(n_) ((uint8_t)(32U - __CLZ(n_))) - -/* QF critical section entry/exit, see NOTE3 */ -#define QF_CRIT_STAT_TYPE uint32_t -#define QF_CRIT_ENTRY(status_) do { \ - (status_) = __get_CPSR(); \ - QF_INT_DISABLE(); \ -} while (false) -#define QF_CRIT_EXIT(status_) __set_CPSR((status_)) -#define QF_CRIT_EXIT_NOP() __ISB() - -#include /* IAR intrinsic functions */ -#include "qep_port.h" /* QEP port */ -#include "qv_port.h" /* QV port */ -#include "qf.h" /* QF platform-independent public interface */ - -/***************************************************************************** -* NOTE1: -* The maximum number of active objects QF_MAX_ACTIVE can be increased -* up to 63, if necessary. Here it is set to a lower level to save some RAM. -* -* NOTE2: -* The FIQ-type interrupts are NEVER disabled in this port, so the FIQ is -* a "kernel-unaware" interrupt. If the FIQ is ever used in the application, -* it must be an "__arm __fiq"-type function. For this to work, the FIQ -* stack needs to be initialized. -* -* NOTE3: -* This port implements the "save and restore" interrupt status policy, -* which again never disables the FIQ-type interrupts. This policy allows -* for nesting critical sections, which is necessary inside IRQ-type -* interrupts that run with interrupts (IRQ) disabled. -*/ - -#endif /* QF_PORT_H */ diff --git a/ports/arm-cr/qv/iar/qp_port.h b/ports/arm-cr/qv/iar/qp_port.h new file mode 100644 index 00000000..81c1365b --- /dev/null +++ b/ports/arm-cr/qv/iar/qp_port.h @@ -0,0 +1,99 @@ +//============================================================================ +// QP/C Real-Time Embedded Framework (RTEF) +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +//============================================================================ +//! @date Last updated on: 2023-09-07 +//! @version Last updated for: @ref qpc_7_3_0 +//! +//! @file +//! @brief QP/C port to Cortex-R, cooperative QV kernel, IAR-ARM + +#ifndef QP_PORT_H_ +#define QP_PORT_H_ + +#include // Exact-width types. WG14/N843 C99 Standard +#include // Boolean type. WG14/N843 C99 Standard +#include // IAR intrinsic functions + +#ifdef QP_CONFIG +#include "qp_config.h" // external QP configuration +#endif + +// no-return function specifier (IAR-ARM compiler) +#define Q_NORETURN __noreturn void + +// QF configuration for QV -- data members of the QActive class... + +// QV event-queue used for AOs +#define QACTIVE_EQUEUE_TYPE QEQueue + +// QF interrupt disable/enable, see NOTE2 +#define QF_INT_DISABLE() __disable_irq() +#define QF_INT_ENABLE() __enable_irq() +#define QF_INT_ENABLE_ALL() __enable_interrupt() + +// Cortex-R provide the CLZ instruction for fast LOG2 +#define QF_LOG2(n_) ((uint8_t)(32U - __CLZ(n_))) + +// QF critical section entry/exit, see NOTE3 +#define QF_CRIT_STAT uint32_t cpsr_; +#define QF_CRIT_ENTRY() do { \ + cpsr_ = __get_CPSR(); \ + QF_INT_DISABLE(); \ +} while (false) +#define QF_CRIT_EXIT() __set_CPSR(cpsr_) +#define QF_CRIT_EXIT_NOP() __ISB() + +// macro to put the CPU to sleep inside QV_onIdle() +#define QV_CPU_SLEEP() do { \ + __WFI(); \ + QF_INT_ENABLE(); \ +} while (false) + +// include files ------------------------------------------------------------- +#include "qequeue.h" // QV kernel uses the native QP event queue +#include "qmpool.h" // QV kernel uses the native QP memory pool +#include "qp.h" // QP framework +#include "qv.h" // QV kernel + +//============================================================================ +// NOTE2: +// The FIQ-type interrupts are NEVER disabled in this port, so the FIQ is +// a "kernel-unaware" interrupt. If the FIQ is ever used in the application, +// it must be an "__arm __fiq"-type function. For this to work, the FIQ +// stack needs to be initialized. +// +// NOTE3: +// This port implements the "save and restore" interrupt status policy, +// which again never disables the FIQ-type interrupts. This policy allows +// for nesting critical sections, which is necessary inside IRQ-type +// interrupts that run with interrupts (IRQ) disabled. +// + +#endif // QP_PORT_H_ + diff --git a/ports/arm-cr/qv/iar/qs_port.h b/ports/arm-cr/qv/iar/qs_port.h index e8b00882..206b7e4c 100644 --- a/ports/arm-cr/qv/iar/qs_port.h +++ b/ports/arm-cr/qv/iar/qs_port.h @@ -1,60 +1,56 @@ -/*============================================================================ -* QP/C Real-Time Embedded Framework (RTEF) -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2022-06-12 -* @version Last updated for: @ref qpc_7_0_1 -* -* @file -* @brief QS/C port to a 32-bit CPU and a generic C99 compiler. -* @description -* This is an example of a QP/C port with the documentation for the -* configuration macros and includes. -*/ -#ifndef QS_PORT_H -#define QS_PORT_H +//============================================================================ +// QP/C Real-Time Embedded Framework (RTEF) +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +//============================================================================ +//! @date Last updated on: 2023-08-16 +//! @version Last updated for: @ref qpc_7_3_0 +//! +//! @file +//! @brief QS/C port to a 32-bit CPU and a generic C11 compiler. -/* QS time-stamp size in bytes */ -#define QS_TIME_SIZE 4 +#ifndef QS_PORT_H_ +#define QS_PORT_H_ -/* object pointer size in bytes */ -#define QS_OBJ_PTR_SIZE 4 +// QS time-stamp size in bytes +#define QS_TIME_SIZE 4U -/* function pointer size in bytes */ -#define QS_FUN_PTR_SIZE 4 +// object pointer size in bytes +#define QS_OBJ_PTR_SIZE 4U -/*==========================================================================*/ -/* NOTE: QS might be used with or without other QP components, in which -* case the separate definitions of the macros QF_CRIT_STAT_TYPE, -* QF_CRIT_ENTRY, and QF_CRIT_EXIT are needed. In this port QS is configured -* to be used with the other QP component, by simply including "qf_port.h" -* *before* "qs.h". -*/ -#ifndef QF_PORT_H -#include "qf_port.h" /* use QS with QF */ +// function pointer size in bytes +#define QS_FUN_PTR_SIZE 4U + +//============================================================================ +// NOTE: QS might be used with or without other QP components, in which +// case the separate definitions of the macros QF_CRIT_STAT, QF_CRIT_ENTRY(), +// and QF_CRIT_EXIT() are needed. In this port QS is configured to be used +// with the other QP component, by simply including "qp_port.h" +//*before* "qs.h". +#ifndef QP_PORT_H_ +#include "qp_port.h" // use QS with QF #endif -#include "qs.h" /* QS platform-independent public interface */ +#include "qs.h" // QS platform-independent public interface + +#endif // QS_PORT_H_ -#endif /* QS_PORT_H */ diff --git a/ports/arm-cr/qv/iar/qv_port.h b/ports/arm-cr/qv/iar/qv_port.h deleted file mode 100644 index e597402d..00000000 --- a/ports/arm-cr/qv/iar/qv_port.h +++ /dev/null @@ -1,43 +0,0 @@ -/*============================================================================ -* QP/C Real-Time Embedded Framework (RTEF) -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2022-07-30 -* @version Last updated for: @ref qpc_7_0_1 -* -* @file -* @brief QV/C port to ARM Cortex-R, IAR-ARM toolset -*/ -#ifndef QV_PORT_H -#define QV_PORT_H - -/* macro to put the CPU to sleep inside QV_onIdle() */ -#define QV_CPU_SLEEP() do { \ - __WFI(); \ - QF_INT_ENABLE(); \ -} while (false) - -#include "qv.h" /* QV platform-independent public interface */ - -#endif /* QV_PORT_H */ diff --git a/ports/arm-cr/qv/ti/qep_port.h b/ports/arm-cr/qv/ti/qep_port.h deleted file mode 100644 index a6607ff9..00000000 --- a/ports/arm-cr/qv/ti/qep_port.h +++ /dev/null @@ -1,40 +0,0 @@ -/*============================================================================ -* QP/C Real-Time Embedded Framework (RTEF) -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2022-07-30 -* @version Last updated for: @ref qpc_7_0_1 -* -* @file -* @brief QEP/C port, generic C99 compiler -*/ -#ifndef QEP_PORT_H -#define QEP_PORT_H - -#include /* Exact-width types. WG14/N843 C99 Standard */ -#include /* Boolean type. WG14/N843 C99 Standard */ - -#include "qep.h" /* QEP platform-independent public interface */ - -#endif /* QEP_PORT_H */ diff --git a/ports/arm-cr/qv/ti/qf_port.h b/ports/arm-cr/qv/ti/qf_port.h deleted file mode 100644 index 5f47722c..00000000 --- a/ports/arm-cr/qv/ti/qf_port.h +++ /dev/null @@ -1,90 +0,0 @@ -/*============================================================================ -* QP/C Real-Time Embedded Framework (RTEF) -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2022-07-30 -* @version Last updated for: @ref qpc_7_0_1 -* -* @file -* @brief QF/C port to Cortex-R, cooperative QV kernel, TI-ARM toolset -*/ -#ifndef QF_PORT_H -#define QF_PORT_H - -/* The maximum number of active objects in the application, see NOTE1 */ -#define QF_MAX_ACTIVE 32U - -/* The maximum number of system clock tick rates */ -#define QF_MAX_TICK_RATE 2U - -/* QF interrupt disable/enable, see NOTE2 */ -#ifdef __16bis__ - #define QF_INT_DISABLE() __asm(" CPSID i") - #define QF_INT_ENABLE() __asm(" CPSIE i") - #define QF_INT_ENABLE_ALL() __asm(" CPSIE if") -#else - #define QF_INT_DISABLE() _disable_IRQ() - #define QF_INT_ENABLE() _enable_IRQ() - #define QF_INT_ENABLE_ALL() _enable_interrupts() -#endif - -/* Cortex-R provide the CLZ instruction for fast LOG2 */ -#define QF_LOG2(n_) ((uint8_t)(32U - __clz(n_))) - -/* QF critical section entry/exit, see NOTE3 */ -#define QF_CRIT_STAT_TYPE uint32_t -#define QF_CRIT_ENTRY(status_) do { \ - (status_) = _get_CPSR(); \ - QF_INT_DISABLE(); \ -} while (false) -#define QF_CRIT_EXIT(status_) do { \ - if (((status_) & (1U << 7)) == 0) { \ - QF_INT_ENABLE(); \ - } \ -} while (false) -#define QF_CRIT_EXIT_NOP() __asm(" ISB") - -#include "qep_port.h" /* QEP port */ -#include "qv_port.h" /* QV port */ -#include "qf.h" /* QF platform-independent public interface */ - -/***************************************************************************** -* NOTE1: -* The maximum number of active objects QF_MAX_ACTIVE can be increased -* up to 63, if necessary. Here it is set to a lower level to save some RAM. -* -* NOTE2: -* The FIQ-type interrupts are NEVER disabled in this port, so the FIQ is -* a "kernel-unaware" interrupt. If the FIQ is ever used in the application, -* it must be an "ARM FIQ"-type function. For this to work, the FIQ -* stack needs to be initialized. -* -* NOTE3: -* This port implements the "save and restore" interrupt status policy, -* which again never disables the FIQ-type interrupts. This policy allows -* for nesting critical sections, which is necessary inside IRQ-type -* interrupts that run with interrupts (IRQ) disabled. -*/ - -#endif /* QF_PORT_H */ diff --git a/ports/arm-cr/qv/ti/qp_port.h b/ports/arm-cr/qv/ti/qp_port.h new file mode 100644 index 00000000..b8bb588f --- /dev/null +++ b/ports/arm-cr/qv/ti/qp_port.h @@ -0,0 +1,108 @@ +//============================================================================ +// QP/C Real-Time Embedded Framework (RTEF) +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +//============================================================================ +//! @date Last updated on: 2023-09-07 +//! @version Last updated for: @ref qpc_7_3_0 +//! +//! @file +//! @brief QP/C port to ARM Cortex-R, cooperative QV kernel, TI-ARM + +#ifndef QP_PORT_H_ +#define QP_PORT_H_ + +#include // Exact-width types. WG14/N843 C99 Standard +#include // Boolean type. WG14/N843 C99 Standard + +#ifdef QP_CONFIG +#include "qp_config.h" // external QP configuration +#endif + +// no-return function specifier (C11 Standard) +#define Q_NORETURN _Noreturn void + +// QF configuration for QV -- data members of the QActive class... + +// QV event-queue used for AOs +#define QACTIVE_EQUEUE_TYPE QEQueue + +// QF interrupt disable/enable, see NOTE2 +#ifdef __16bis__ + #define QF_INT_DISABLE() __asm(" CPSID i") + #define QF_INT_ENABLE() __asm(" CPSIE i") + #define QF_INT_ENABLE_ALL() __asm(" CPSIE if") +#else + #define QF_INT_DISABLE() _disable_IRQ() + #define QF_INT_ENABLE() _enable_IRQ() + #define QF_INT_ENABLE_ALL() _enable_interrupts() +#endif + +// Cortex-R provide the CLZ instruction for fast LOG2 +#define QF_LOG2(n_) ((uint8_t)(32U - __clz(n_))) + +// QF critical section entry/exit, see NOTE3 +#define QF_CRIT_STAT uint32_t cpsr_; +#define QF_CRIT_ENTRY() do { \ + cpsr_ = _get_CPSR(); \ + QF_INT_DISABLE(); \ +} while (false) +#define QF_CRIT_EXIT() do { \ + if ((cpsr_ & (1U << 7U)) == 0U) { \ + QF_INT_ENABLE(); \ + } \ +} while (false) +#define QF_CRIT_EXIT_NOP() __asm(" ISB") + +// macro to put the CPU to sleep inside QV_onIdle() +#define QV_CPU_SLEEP() do { \ + __wfi(); \ + QF_INT_ENABLE(); \ +} while (false) + +// include files ------------------------------------------------------------- +#include "qequeue.h" // QV kernel uses the native QP event queue +#include "qmpool.h" // QV kernel uses the native QP memory pool +#include "qp.h" // QP framework +#include "qv.h" // QV kernel + +//============================================================================ +// NOTE2: +// The FIQ-type interrupts are NEVER disabled in this port, so the FIQ is +// a "kernel-unaware" interrupt. If the FIQ is ever used in the application, +// it must be an "ARM FIQ"-type function. For this to work, the FIQ +// stack needs to be initialized. +// +// NOTE3: +// This port implements the "save and restore" interrupt status policy, +// which again never disables the FIQ-type interrupts. This policy allows +// for nesting critical sections, which is necessary inside IRQ-type +// interrupts that run with interrupts (IRQ) disabled. +// + +#endif // QP_PORT_H_ + diff --git a/ports/arm-cr/qv/ti/qs_port.h b/ports/arm-cr/qv/ti/qs_port.h index e8b00882..206b7e4c 100644 --- a/ports/arm-cr/qv/ti/qs_port.h +++ b/ports/arm-cr/qv/ti/qs_port.h @@ -1,60 +1,56 @@ -/*============================================================================ -* QP/C Real-Time Embedded Framework (RTEF) -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2022-06-12 -* @version Last updated for: @ref qpc_7_0_1 -* -* @file -* @brief QS/C port to a 32-bit CPU and a generic C99 compiler. -* @description -* This is an example of a QP/C port with the documentation for the -* configuration macros and includes. -*/ -#ifndef QS_PORT_H -#define QS_PORT_H +//============================================================================ +// QP/C Real-Time Embedded Framework (RTEF) +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +//============================================================================ +//! @date Last updated on: 2023-08-16 +//! @version Last updated for: @ref qpc_7_3_0 +//! +//! @file +//! @brief QS/C port to a 32-bit CPU and a generic C11 compiler. -/* QS time-stamp size in bytes */ -#define QS_TIME_SIZE 4 +#ifndef QS_PORT_H_ +#define QS_PORT_H_ -/* object pointer size in bytes */ -#define QS_OBJ_PTR_SIZE 4 +// QS time-stamp size in bytes +#define QS_TIME_SIZE 4U -/* function pointer size in bytes */ -#define QS_FUN_PTR_SIZE 4 +// object pointer size in bytes +#define QS_OBJ_PTR_SIZE 4U -/*==========================================================================*/ -/* NOTE: QS might be used with or without other QP components, in which -* case the separate definitions of the macros QF_CRIT_STAT_TYPE, -* QF_CRIT_ENTRY, and QF_CRIT_EXIT are needed. In this port QS is configured -* to be used with the other QP component, by simply including "qf_port.h" -* *before* "qs.h". -*/ -#ifndef QF_PORT_H -#include "qf_port.h" /* use QS with QF */ +// function pointer size in bytes +#define QS_FUN_PTR_SIZE 4U + +//============================================================================ +// NOTE: QS might be used with or without other QP components, in which +// case the separate definitions of the macros QF_CRIT_STAT, QF_CRIT_ENTRY(), +// and QF_CRIT_EXIT() are needed. In this port QS is configured to be used +// with the other QP component, by simply including "qp_port.h" +//*before* "qs.h". +#ifndef QP_PORT_H_ +#include "qp_port.h" // use QS with QF #endif -#include "qs.h" /* QS platform-independent public interface */ +#include "qs.h" // QS platform-independent public interface + +#endif // QS_PORT_H_ -#endif /* QS_PORT_H */ diff --git a/ports/arm-cr/qv/ti/qv_port.h b/ports/arm-cr/qv/ti/qv_port.h deleted file mode 100644 index 42a1f197..00000000 --- a/ports/arm-cr/qv/ti/qv_port.h +++ /dev/null @@ -1,43 +0,0 @@ -/*============================================================================ -* QP/C Real-Time Embedded Framework (RTEF) -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2022-07-30 -* @version Last updated for: @ref qpc_7_0_1 -* -* @file -* @brief QV/C port to ARM Cortex-R, TI-ARM toolset -*/ -#ifndef QV_PORT_H -#define QV_PORT_H - -/* macro to put the CPU to sleep inside QV_onIdle() */ -#define QV_CPU_SLEEP() do { \ - __wfi(); \ - QF_INT_ENABLE(); \ -} while (false) - -#include "qv.h" /* QV platform-independent public interface */ - -#endif /* QV_PORT_H */ diff --git a/ports/embos/qep_port.h b/ports/embos/qep_port.h deleted file mode 100644 index a6607ff9..00000000 --- a/ports/embos/qep_port.h +++ /dev/null @@ -1,40 +0,0 @@ -/*============================================================================ -* QP/C Real-Time Embedded Framework (RTEF) -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2022-07-30 -* @version Last updated for: @ref qpc_7_0_1 -* -* @file -* @brief QEP/C port, generic C99 compiler -*/ -#ifndef QEP_PORT_H -#define QEP_PORT_H - -#include /* Exact-width types. WG14/N843 C99 Standard */ -#include /* Boolean type. WG14/N843 C99 Standard */ - -#include "qep.h" /* QEP platform-independent public interface */ - -#endif /* QEP_PORT_H */ diff --git a/ports/embos/qf_port.c b/ports/embos/qf_port.c index 4a9ec785..ee3fc295 100644 --- a/ports/embos/qf_port.c +++ b/ports/embos/qf_port.c @@ -1,276 +1,286 @@ -/*============================================================================ -* QP/C Real-Time Embedded Framework (RTEF) -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2022-11-22 -* @version Last updated for: @ref qpc_7_1_3 -* -* @file -* @brief QF/C port to embOS -*/ -#define QP_IMPL /* this is QP implementation */ -#include "qf_port.h" /* QF port */ -#include "qf_pkg.h" -#include "qassert.h" -#ifdef Q_SPY /* QS software tracing enabled? */ - #include "qs_port.h" /* QS port */ - #include "qs_pkg.h" /* QS package-scope internal interface */ +//============================================================================ +// QP/C Real-Time Embedded Framework (RTEF) +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +//============================================================================ +//! @date Last updated on: 2023-08-30 +//! @version Last updated for: @ref qpc_7_3_0 +//! +//! @file +//! @brief QF/C port to embOS RTOS kernel, generic C11 compiler +//! +#define QP_IMPL // this is QP implementation +#include "qp_port.h" // QP port +#include "qp_pkg.h" // QP package-level interface +#include "qsafe.h" // QP Functional Safety (FuSa) subsystem +#ifdef Q_SPY // QS software tracing enabled? + #include "qs_port.h" // QS port + #include "qs_pkg.h" // QS package-scope internal interface #else - #include "qs_dummy.h" /* disable the QS software tracing */ -#endif /* Q_SPY */ + #include "qs_dummy.h" // disable the QS software tracing +#endif // Q_SPY Q_DEFINE_THIS_MODULE("qf_port") -/*..........................................................................*/ -/* define __TARGET_FPU_VFP symbol depending on the compiler... */ -#if defined (__CC_ARM) /* ARM Compiler */ - /* in ARM Compiler __TARGET_FPU_VFP is a pre-defined symbol*/ -#elif defined (__ICCARM__) /* IAR Compiler */ +//............................................................................ +// define __TARGET_FPU_VFP symbol depending on the compiler... +#if defined (__CC_ARM) // ARM Compiler + // in ARM Compiler __TARGET_FPU_VFP is a pre-defined symbol +#elif defined (__ICCARM__) // IAR Compiler #if defined __ARMVFP__ #define __TARGET_FPU_VFP 1 #endif -#elif defined (__GNUC__) /* GNU Compiler */ +#elif defined (__GNUC__) // GNU Compiler #if defined (__VFP_FP__) && !defined(__SOFTFP__) #define __TARGET_FPU_VFP 1 #endif #endif -/*..........................................................................*/ -void QF_init(void) { - OS_InitKern(); /* initialize embOS */ - OS_InitHW(); /* initialize the hardware used by embOS */ -} -/*..........................................................................*/ -int_t QF_run(void) { - QS_CRIT_STAT_ - - QF_onStartup(); /* QF callback to configure and start interrupts */ - - /* produce the QS_QF_RUN trace record */ - QS_BEGIN_PRE_(QS_QF_RUN, 0U) - QS_END_PRE_() - - OS_Start(); /* start embOS multitasking */ - Q_ERROR_ID(100); /* OS_Start() should never return */ - return 0; /* dummy return to make the compiler happy */ -} -/*..........................................................................*/ -void QF_stop(void) { - QF_onCleanup(); /* cleanup callback */ -} - -/*..........................................................................*/ -static void thread_function(void *pVoid) { /* embOS signature */ - QActive *act = (QActive *)pVoid; +//............................................................................ +static void thread_function(void *pVoid); // prototype +static void thread_function(void *pVoid) { // embOS signature + QActive * const act = (QActive *)pVoid; #ifdef __TARGET_FPU_VFP - /* does the task use the FPU? see NOTE1 */ + // does the task use the FPU? see NOTE1 if ((act->osObject & TASK_USES_FPU) != 0U) { OS_ExtendTaskContext_VFP(); } -#endif /* __TARGET_FPU_VFP */ +#endif // __TARGET_FPU_VFP - /* event-loop */ - for (;;) { /* for-ever */ + // event-loop + for (;;) { QEvt const *e = QActive_get_(act); - QHSM_DISPATCH(&act->super, e, act->prio); - QF_gc(e); /* check if the event is garbage, and collect it if so */ + // dispatch event (virtual call) + (*act->super.vptr->dispatch)(&act->super, e, act->prio); + QF_gc(e); // check if the event is garbage, and collect it if so } } -/*..........................................................................*/ +//............................................................................ +void QF_init(void) { + OS_InitKern(); // initialize embOS + OS_InitHW(); // initialize the hardware used by embOS +} +//............................................................................ +int QF_run(void) { + QF_onStartup(); // QF callback to configure and start interrupts + + // produce the QS_QF_RUN trace record + QS_CRIT_STAT + QS_CRIT_ENTRY(); + QS_BEGIN_PRE_(QS_QF_RUN, 0U) + QS_END_PRE_() + QS_CRIT_EXIT(); + + OS_Start(); // start embOS multitasking + + return 0; // dummy return to make the compiler happy +} +//............................................................................ +void QF_stop(void) { + QF_onCleanup(); // cleanup callback +} + +//............................................................................ void QActive_start_(QActive * const me, QPrioSpec const prioSpec, QEvt const * * const qSto, uint_fast16_t const qLen, void * const stkSto, uint_fast16_t const stkSize, void const * const par) { - /* create the embOS message box for the AO */ - OS_CreateMB(&me->eQueue, + // create the embOS message box for the AO + OS_MAILBOX_Create(&me->eQueue, (OS_U16)sizeof(QEvt *), (OS_UINT)qLen, (void *)&qSto[0]); - me->prio = (uint8_t)(prioSpec & 0xFFU); /* QF-priority of the AO */ - me->pthre = (uint8_t)(prioSpec >> 8U); /* preemption-threshold */ - QActive_register_(me); /* register this AO */ + me->prio = (uint8_t)(prioSpec & 0xFFU); // QF-priority of the AO + me->pthre = 0U; // preemption-threshold (not used) + QActive_register_(me); // make QF aware of this AO - QHSM_INIT(&me->super, par, me->prio); /* the top-most initial tran. */ - QS_FLUSH(); /* flush the trace buffer to the host */ + // top-most initial tran. (virtual call) + (*me->super.vptr->init)(&me->super, par, me->prio); + QS_FLUSH(); // flush the trace buffer to the host - /* create an embOS task for the AO */ - OS_CreateTaskEx(&me->thread, + // create an embOS task for the AO + OS_TASK_CreateEx(&me->thread, #if (OS_TRACKNAME != 0) - me->thread.Name, /* the configured task name */ + me->thread.Name, // the configured task name #elif - "AO", /* a generic AO task name */ + "AO", // a generic AO task name #endif - (OS_PRIO)me->prio,/* embOS uses the same numbering as QP*/ - &thread_function, - (void OS_STACKPTR *)stkSto, - (OS_UINT)stkSize, - (OS_UINT)0, /* no AOs at the same prio */ - (void *)me); + (OS_PRIO)me->prio, // embOS uses the same numbering as QP + &thread_function, + (void OS_STACKPTR *)stkSto, + (OS_UINT)stkSize, + 0U, // no AOs at the same prio + (void *)me); } -/*..........................................................................*/ +//............................................................................ void QActive_setAttr(QActive *const me, uint32_t attr1, void const *attr2) { + QF_CRIT_STAT + QF_CRIT_ENTRY(); switch (attr1) { - case TASK_NAME_ATTR: + case TASK_NAME_ATTR: { #if (OS_TRACKNAME != 0) - Q_ASSERT_ID(300, me->thread.Name == (char *)0); - me->thread.Name = (char const *)attr2; + Q_ASSERT_INCRIT(300, me->thread.Name == (char *)0); + me->thread.Name = (char const *)attr2; #endif break; + } case TASK_USES_FPU: me->osObject = attr1; break; - /* ... */ + // ... default: break; } + QF_CRIT_EXIT(); } -/*..........................................................................*/ +//............................................................................ bool QActive_post_(QActive * const me, QEvt const * const e, uint_fast16_t const margin, void const * const sender) { - uint_fast16_t nFree; + QF_CRIT_STAT + QF_CRIT_ENTRY(); + uint_fast16_t nFree = + (uint_fast16_t)(me->eQueue.maxMsg - me->eQueue.nofMsg); + bool status; - QF_CRIT_STAT_ - - QF_CRIT_E_(); - nFree = (uint_fast16_t)(me->eQueue.maxMsg - me->eQueue.nofMsg); - if (margin == QF_NO_MARGIN) { - if (nFree > (QEQueueCtr)0) { - status = true; /* can post */ + if (nFree > 0U) { + status = true; // can post } else { - status = false; /* cannot post */ - Q_ERROR_ID(510); /* must be able to post the event */ + status = false; // cannot post + Q_ERROR_INCRIT(510); // must be able to post the event } } else if (nFree > (QEQueueCtr)margin) { - status = true; /* can post */ + status = true; // can post } else { - status = false; /* cannot post */ + status = false; // cannot post } - if (status) { /* can post the event? */ + if (status) { // can post the event? - QS_BEGIN_NOCRIT_PRE_(QS_QF_ACTIVE_POST, me->prio) - QS_TIME_PRE_(); /* timestamp */ - QS_OBJ_PRE_(sender); /* the sender object */ - QS_SIG_PRE_(e->sig); /* the signal of the event */ - QS_OBJ_PRE_(me); /* this active object (recipient) */ - QS_2U8_PRE_(e->poolId_, e->refCtr_); /* pool Id & ref Count */ - QS_EQC_PRE_(nFree); /* # free entries available */ - QS_EQC_PRE_(0U); /* min # free entries (unknown) */ - QS_END_NOCRIT_PRE_() + QS_BEGIN_PRE_(QS_QF_ACTIVE_POST, me->prio) + QS_TIME_PRE_(); // timestamp + QS_OBJ_PRE_(sender); // the sender object + QS_SIG_PRE_(e->sig); // the signal of the event + QS_OBJ_PRE_(me); // this active object (recipient) + QS_2U8_PRE_(QEvt_getPoolId_(e), e->refCtr_); // pool-Id&ref-Count + QS_EQC_PRE_(nFree); // # free entries + QS_EQC_PRE_(0U); // min # free entries (unknown) + QS_END_PRE_() - if (e->poolId_ != 0U) { /* is it a pool event? */ - QEvt_refCtr_inc_(e); /* increment the reference counter */ + if (QEvt_getPoolId_(e) != 0U) { // is it a pool event? + QEvt_refCtr_inc_(e); // increment the reference counter } + QF_CRIT_EXIT(); - QF_CRIT_X_(); + char err = OS_MAILBOX_Put(&me->eQueue, (OS_CONST_PTR void *)&e); - /* posting to the embOS mailbox must succeed, see NOTE3 */ - Q_ALLEGE_ID(520, - OS_PutMailCond(&me->eQueue, (OS_CONST_PTR void *)&e) - == (char)0); + QF_CRIT_ENTRY(); + // posting to the embOS mailbox must succeed, see NOTE3 + Q_ASSERT_INCRIT(520, err == '\0'); } else { - QS_BEGIN_NOCRIT_PRE_(QS_QF_ACTIVE_POST_ATTEMPT, me->prio) - QS_TIME_PRE_(); /* timestamp */ - QS_OBJ_PRE_(sender); /* the sender object */ - QS_SIG_PRE_(e->sig); /* the signal of the event */ - QS_OBJ_PRE_(me); /* this active object (recipient) */ - QS_2U8_PRE_(e->poolId_, e->refCtr_); /* pool Id & ref Count */ - QS_EQC_PRE_(nFree); /* # free entries available */ - QS_EQC_PRE_(margin); /* margin requested */ - QS_END_NOCRIT_PRE_() + QS_BEGIN_PRE_(QS_QF_ACTIVE_POST_ATTEMPT, me->prio) + QS_TIME_PRE_(); // timestamp + QS_OBJ_PRE_(sender); // the sender object + QS_SIG_PRE_(e->sig); // the signal of the event + QS_OBJ_PRE_(me); // this active object (recipient) + QS_2U8_PRE_(QEvt_getPoolId_(e), e->refCtr_); // pool-Id&ref-Count + QS_EQC_PRE_(nFree); // # free entries + QS_EQC_PRE_(margin); // margin requested + QS_END_PRE_() - QF_CRIT_X_(); - } + } + QF_CRIT_EXIT(); return status; } -/*..........................................................................*/ +//............................................................................ void QActive_postLIFO_(QActive * const me, QEvt const * const e) { - QF_CRIT_STAT_ - QF_CRIT_E_(); + QF_CRIT_STAT + QF_CRIT_ENTRY(); - QS_BEGIN_NOCRIT_PRE_(QS_QF_ACTIVE_POST_LIFO, me->prio) - QS_TIME_PRE_(); /* timestamp */ - QS_SIG_PRE_(e->sig); /* the signal of this event */ - QS_OBJ_PRE_(me); /* this active object */ - QS_2U8_PRE_(e->poolId_, e->refCtr_); /* pool Id & ref Count */ - QS_EQC_PRE_(me->eQueue.maxMsg - me->eQueue.nofMsg); /* # free */ - QS_EQC_PRE_(0U); /* min # free entries (unknown) */ - QS_END_NOCRIT_PRE_() + QS_BEGIN_PRE_(QS_QF_ACTIVE_POST_LIFO, me->prio) + QS_TIME_PRE_(); // timestamp + QS_SIG_PRE_(e->sig); // the signal of this event + QS_OBJ_PRE_(me); // this active object + QS_2U8_PRE_(QEvt_getPoolId_(e), e->refCtr_); // pool-Id&ref-Count + QS_EQC_PRE_(me->eQueue.maxMsg - me->eQueue.nofMsg); // # free + QS_EQC_PRE_(0U); // min # free entries (unknown) + QS_END_PRE_() - if (e->poolId_ != 0U) { /* is it a pool event? */ - QEvt_refCtr_inc_(e); /* increment the reference counter */ + if (QEvt_getPoolId_(e) != 0U) { // is it a pool event? + QEvt_refCtr_inc_(e); // increment the reference counter } + QF_CRIT_EXIT(); - QF_CRIT_X_(); + char err = OS_MAILBOX_PutFront(&me->eQueue, (OS_CONST_PTR void *)&e); - /* posting to the embOS mailbox must succeed, see NOTE3 */ - Q_ALLEGE_ID(810, - OS_PutMailFrontCond(&me->eQueue, (OS_CONST_PTR void *)&e) - == (char)0); + QF_CRIT_ENTRY(); + // posting to the embOS mailbox must succeed, see NOTE3 + Q_ASSERT_INCRIT(610, err == '\0'); + QF_CRIT_EXIT(); } -/*..........................................................................*/ +//............................................................................ QEvt const *QActive_get_(QActive * const me) { QEvt const *e; - QS_CRIT_STAT_ - - OS_GetMail(&me->eQueue, (void *)&e); + OS_MAILBOX_GetBlocked(&me->eQueue, (void *)&e); + QS_CRIT_STAT + QS_CRIT_ENTRY(); QS_BEGIN_PRE_(QS_QF_ACTIVE_GET, me->prio) - QS_TIME_PRE_(); /* timestamp */ - QS_SIG_PRE_(e->sig); /* the signal of this event */ - QS_OBJ_PRE_(me); /* this active object */ - QS_2U8_PRE_(e->poolId_, e->refCtr_); /* pool Id & ref Count */ - QS_EQC_PRE_(me->eQueue.maxMsg - me->eQueue.nofMsg);/* # free */ + QS_TIME_PRE_(); // timestamp + QS_SIG_PRE_(e->sig); // the signal of this event + QS_OBJ_PRE_(me); // this active object + QS_2U8_PRE_(QEvt_getPoolId_(e), e->refCtr_); // pool-Id&ref-Count + QS_EQC_PRE_(me->eQueue.maxMsg - me->eQueue.nofMsg);// # free QS_END_PRE_() + QS_CRIT_EXIT(); return e; } -/***************************************************************************** -* NOTE1: -* In case of hardware-supported floating point unit (FPU), a task must -* preserve the FPU registers accross the context switch. However, this -* additional overhead is necessary only for tasks that actually use the -* FPU. In this QP-embOS port, an active object task that uses the FPU is -* designated by the QF_TASK_USES_FPU attribute, which can be set wiht the -* QF_setEmbOsTaskAttr() function. The task attributes must be set *before* -* calling QACTIVE_START(). The task attributes are saved in QActive.osObject -* member. -* -* NOTE3: -* The event posting to embOS mailbox occurs inside a critical section, -* but this is OK, because the QF/embOS critical sections are designed -* to nest. -*/ +//============================================================================ +// NOTE1: +// In case of hardware-supported floating point unit (FPU), a task must +// preserve the FPU registers across the context switch. However, this +// additional overhead is necessary only for tasks that actually use the +// FPU. In this QP-embOS port, an active object task that uses the FPU is +// designated by the QF_TASK_USES_FPU attribute, which can be set with the +// QF_setEmbOsTaskAttr() function. The task attributes must be set *before* +// calling QACTIVE_START(). The task attributes are saved in QActive.osObject +// member. +// +// NOTE3: +// The event posting to embOS mailbox occurs OUTSIDE critical section, +// which means that the remaining margin of available slots in the queue +// cannot be guaranteed. The problem is that interrupts and other tasks can +// preempt the event posting after checking the margin, but before actually +// posting the event to the queue. +// diff --git a/ports/embos/qf_port.h b/ports/embos/qf_port.h deleted file mode 100644 index c8319a36..00000000 --- a/ports/embos/qf_port.h +++ /dev/null @@ -1,114 +0,0 @@ -/*============================================================================ -* QP/C Real-Time Embedded Framework (RTEF) -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2022-07-30 -* @version Last updated for: @ref qpc_7_0_1 -* -* @file -* @brief QF/C port to embOS -* @endcond -*/ -#ifndef QF_PORT_H -#define QF_PORT_H - -/* embOS message mailbox and thread types */ -#define QF_EQUEUE_TYPE OS_MAILBOX -#define QF_THREAD_TYPE OS_TASK -#define QF_OS_OBJECT_TYPE uint32_t - -/* The maximum number of active objects in the application, see NOTE1 */ -#define QF_MAX_ACTIVE 32U - -/* QF interrupt disable/enable */ -#define QF_INT_DISABLE() OS_IncDI() -#define QF_INT_ENABLE() OS_DecRI() - -/* QF critical section for embOS, see NOTE2 */ -/*#define QF_CRIT_STAT_TYPE not defined */ -#define QF_CRIT_ENTRY(dummy) QF_INT_DISABLE() -#define QF_CRIT_EXIT(dummy) QF_INT_ENABLE() - -/* thread attributes... */ -enum EmbOS_TaskAttrs { - TASK_NAME_ATTR, - TASK_USES_FPU -}; - -#include "RTOS.h" /* embOS API */ -#include "qep_port.h" /* QEP port */ -#include "qequeue.h" /* used for event deferral */ -#include "qmpool.h" /* this QP port uses the native QF memory pool */ -#include "qf.h" /* QF platform-independent public interface */ - -/*==========================================================================*/ -/* interface used only inside QF, but not in applications -*/ -#ifdef QP_IMPL - - /* embOS-specific scheduler locking, see NOTE3 */ - #define QF_SCHED_STAT_ - #define QF_SCHED_LOCK_(dummy) do { \ - if (OS_InInterrupt() == (OS_BOOL)0) { \ - OS_EnterRegion(); \ - } \ - } while (false) - #define QF_SCHED_UNLOCK_() do { \ - if (OS_InInterrupt() == (OS_BOOL)0) { \ - OS_LeaveRegion(); \ - } \ - } while (false) - - /* native QF event pool operations */ - #define QF_EPOOL_TYPE_ QMPool - #define QF_EPOOL_INIT_(p_, poolSto_, poolSize_, evtSize_) \ - (QMPool_init(&(p_), (poolSto_), (poolSize_), (evtSize_))) - #define QF_EPOOL_EVENT_SIZE_(p_) ((uint_fast16_t)(p_).blockSize) - #define QF_EPOOL_GET_(p_, e_, m_, qs_id_) \ - ((e_) = (QEvt *)QMPool_get(&(p_), (m_), (qs_id_))) - #define QF_EPOOL_PUT_(p_, e_, qs_id_) \ - (QMPool_put(&(p_), (e_), (qs_id_))) - -#endif /* ifdef QP_IMPL */ - -/*==========================================================================*/ -/* NOTE1: -* The maximum number of active objects in QP can be increased to 63, -* inclusive, but it can be reduced to save some memory. Also, the number of -* active objects cannot exceed the number of embOS thread priorities, -* because each QP active object requires a unique priority level. -* -* NOTE2: -* The embOS critical section does not use the status variable, because the -* implementation uses a global up-down counter, which allows the embOS -* critical section to nest. Nesting of critical sections is needed in this -* QP-embOS port. -* -* NOTE3: -* embOS provides only global scheduler locking for all thread priorities -* by means of OS_EnterRegion() and OS_LeaveRegion(). Therefore, locking the -* scheduler only up to the specified lock priority is not supported. -*/ - -#endif /* QF_PORT_H */ diff --git a/ports/embos/qp_port.h b/ports/embos/qp_port.h new file mode 100644 index 00000000..3bcf6ce6 --- /dev/null +++ b/ports/embos/qp_port.h @@ -0,0 +1,122 @@ +//============================================================================ +// QP/C Real-Time Embedded Framework (RTEF) +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +//============================================================================ +//! @date Last updated on: 2023-09-07 +//! @version Last updated for: @ref qpc_7_3_0 +//! +//! @file +//! @brief QP/C port to embOS RTOS (v5), generic C11 compiler + +#ifndef QP_PORT_H_ +#define QP_PORT_H_ + +#include // Exact-width types. WG14/N843 C99 Standard +#include // Boolean type. WG14/N843 C99 Standard + +#ifdef QP_CONFIG +#include "qp_config.h" // external QP configuration +#endif + +// no-return function specifier (C11 Standard) +#define Q_NORETURN _Noreturn void + +// embOS message mailbox and thread types +#define QACTIVE_EQUEUE_TYPE OS_MAILBOX +#define QACTIVE_THREAD_TYPE OS_TASK +#define QACTIVE_OS_OBJ_TYPE uint32_t + +// QF interrupt disable/enable +#define QF_INT_DISABLE() OS_INT_IncDI() +#define QF_INT_ENABLE() OS_INT_DecRI() + +// QF critical section for embOS, see NOTE2 +#define QF_CRIT_STAT +#define QF_CRIT_ENTRY() QF_INT_DISABLE() +#define QF_CRIT_EXIT() QF_INT_ENABLE() + +// include files ------------------------------------------------------------- +#include "RTOS.h" // embOS API + +#include "qequeue.h" // QP event queue (for deferring events) +#include "qmpool.h" // QP memory pool (for event pools) +#include "qp.h" // QP platform-independent public interface + + +enum EmbOS_TaskAttrs { + TASK_NAME_ATTR, + TASK_USES_FPU +}; + + +//============================================================================ +// interface used only inside QF, but not in applications + +#ifdef QP_IMPL + + // embOS-specific scheduler locking, see NOTE3 + #define QF_SCHED_STAT_ + #define QF_SCHED_LOCK_(dummy) do { \ + if (OS_INT_InInterrupt() == (OS_BOOL)0) { \ + OS_TASK_EnterRegion(); \ + } \ + } while (false) + + #define QF_SCHED_UNLOCK_() do { \ + if (OS_INT_InInterrupt() == (OS_BOOL)0) { \ + OS_TASK_LeaveRegion(); \ + } \ + } while (false) + + // native QF event pool customization + #define QF_EPOOL_TYPE_ QMPool + #define QF_EPOOL_INIT_(p_, poolSto_, poolSize_, evtSize_) \ + (QMPool_init(&(p_), (poolSto_), (poolSize_), (evtSize_))) + #define QF_EPOOL_EVENT_SIZE_(p_) ((uint_fast16_t)(p_).blockSize) + #define QF_EPOOL_GET_(p_, e_, m_, qs_id_) \ + ((e_) = (QEvt *)QMPool_get(&(p_), (m_), (qs_id_))) + #define QF_EPOOL_PUT_(p_, e_, qs_id_) \ + (QMPool_put(&(p_), (e_), (qs_id_))) + +#endif // QP_IMPL + +//============================================================================ +// NOTE2: +// The embOS critical section does not use the status variable, because the +// implementation uses a global up-down counter, which allows the embOS +// critical section to nest. Nesting of critical sections is needed in this +// QP-embOS port. +// +// NOTE3: +// embOS provides only global scheduler locking for all thread priorities +// by means of OS_EnterRegion() and OS_LeaveRegion(). Therefore, locking the +// scheduler only up to the specified lock priority is not supported. +// + +#endif // QP_PORT_H_ + diff --git a/ports/embos/qs_port.h b/ports/embos/qs_port.h index e8b00882..f01b9af5 100644 --- a/ports/embos/qs_port.h +++ b/ports/embos/qs_port.h @@ -1,60 +1,56 @@ -/*============================================================================ -* QP/C Real-Time Embedded Framework (RTEF) -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2022-06-12 -* @version Last updated for: @ref qpc_7_0_1 -* -* @file -* @brief QS/C port to a 32-bit CPU and a generic C99 compiler. -* @description -* This is an example of a QP/C port with the documentation for the -* configuration macros and includes. -*/ -#ifndef QS_PORT_H -#define QS_PORT_H +//============================================================================ +// QP/C Real-Time Embedded Framework (RTEF) +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +//============================================================================ +//! @date Last updated on: 2023-08-16 +//! @version Last updated for: @ref qpc_7_3_0 +//! +//! @file +//! @brief QS/C port to a 32-bit CPU, generic C11 compiler -/* QS time-stamp size in bytes */ -#define QS_TIME_SIZE 4 +#ifndef QS_PORT_H_ +#define QS_PORT_H_ -/* object pointer size in bytes */ -#define QS_OBJ_PTR_SIZE 4 +// QS time-stamp size in bytes +#define QS_TIME_SIZE 4U -/* function pointer size in bytes */ -#define QS_FUN_PTR_SIZE 4 +// object pointer size in bytes +#define QS_OBJ_PTR_SIZE 4U -/*==========================================================================*/ -/* NOTE: QS might be used with or without other QP components, in which -* case the separate definitions of the macros QF_CRIT_STAT_TYPE, -* QF_CRIT_ENTRY, and QF_CRIT_EXIT are needed. In this port QS is configured -* to be used with the other QP component, by simply including "qf_port.h" -* *before* "qs.h". -*/ -#ifndef QF_PORT_H -#include "qf_port.h" /* use QS with QF */ +// function pointer size in bytes +#define QS_FUN_PTR_SIZE 4U + +//============================================================================ +// NOTE: QS might be used with or without other QP components, in which +// case the separate definitions of the macros QF_CRIT_STAT, QF_CRIT_ENTRY(), +// and QF_CRIT_EXIT() are needed. In this port QS is configured to be used +// with the other QP component, by simply including "qp_port.h" +//*before* "qs.h". +#ifndef QP_PORT_H_ +#include "qp_port.h" // use QS with QP #endif -#include "qs.h" /* QS platform-independent public interface */ +#include "qs.h" // QS platform-independent public interface + +#endif // QS_PORT_H_ -#endif /* QS_PORT_H */ diff --git a/ports/esp-idf/qep_port.h b/ports/esp-idf/qep_port.h deleted file mode 100644 index be4fa2d4..00000000 --- a/ports/esp-idf/qep_port.h +++ /dev/null @@ -1,40 +0,0 @@ -/*============================================================================ -* QP/C Real-Time Embedded Framework (RTEF) -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2022-06-03 -* @version Last updated for: @ref qpc_7_0_1 -* -* @file -* @brief QEP/C port, generic C99 compiler -*/ -#ifndef QEP_PORT_H -#define QEP_PORT_H - -#include /* Exact-width types. WG14/N843 C99 Standard */ -#include /* Boolean type. WG14/N843 C99 Standard */ - -#include "qep.h" /* QEP platform-independent public interface */ - -#endif /* QEP_PORT_H */ diff --git a/ports/esp-idf/qf_port.c b/ports/esp-idf/qf_port.c index 73140247..e9d806c7 100644 --- a/ports/esp-idf/qf_port.c +++ b/ports/esp-idf/qf_port.c @@ -1,279 +1,325 @@ -/*============================================================================ -* QP/C Real-Time Embedded Framework (RTEF) -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2022-12-20 -* @version Last updated for: @ref qpc_7_2_0 -* -* @file -* @brief "Experimental" QF/C port to Espressif ESP-IDF (version 4.x) -*/ -#define QP_IMPL /* this is QP implementation */ -#include "qf_port.h" /* QF port */ -#include "qf_pkg.h" -#include "qassert.h" -#ifdef Q_SPY /* QS software tracing enabled? */ - #include "qs_port.h" /* QS port */ - #include "qs_pkg.h" /* QS package-scope internal interface */ +//============================================================================ +// QP/C Real-Time Embedded Framework (RTEF) +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +//============================================================================ +//! @date Last updated on: 2023-09-10 +//! @version Last updated for: @ref qpc_7_3_0 +//! +//! @file +//! @brief "Experimental" QF/C port to Espressif ESP-IDF (version 4.x) + +#define QP_IMPL // this is QP implementation +#include "qp_port.h" // QP port +#include "qp_pkg.h" // QP package-level interface +#include "qsafe.h" // QP Functional Safety (FuSa) Subsystem +#ifdef Q_SPY // QS software tracing enabled? + #include "qs_port.h" // QS port + #include "qs_pkg.h" // QS package-scope internal interface #else - #include "qs_dummy.h" /* disable the QS software tracing */ -#endif /* Q_SPY */ + #include "qs_dummy.h" // disable the QS software tracing +#endif // Q_SPY Q_DEFINE_THIS_MODULE("qf_port") -//static const char *TAG = "qf_port"; #if ( configSUPPORT_STATIC_ALLOCATION == 0 ) - #error "This QP/C port to FreeRTOS requires configSUPPORT_STATIC_ALLOCATION " +#error "This QP/C port to FreeRTOS requires configSUPPORT_STATIC_ALLOCATION " #endif #if ( configMAX_PRIORITIES < QF_MAX_ACTIVE ) - #error "FreeRTOS configMAX_PRIORITIES must not be less than QF_MAX_ACTIVE" +#error "FreeRTOS configMAX_PRIORITIES must not be less than QF_MAX_ACTIVE" #endif -/* Global objects ----------------------------------------------------------*/ +// Global objects ---------------------------------------------------------- PRIVILEGED_DATA portMUX_TYPE QF_esp32mux = portMUX_INITIALIZER_UNLOCKED; -/* Local objects -----------------------------------------------------------*/ -static void task_function(void *pvParameters); /* FreeRTOS task signature */ +// Local objects ----------------------------------------------------------- +static void task_function(void *pvParameters); // FreeRTOS task signature -/* The following macro provides the number of free slots in the FreeRTOS -* queue. -* -* NOTE1: -* The official FreeRTOS API uxQueueSpacesAvailable() is not used -* here, because that API uses task-level critical section internally. -* Instead, the free slots calculation happens here in already -* established critical section. Unfortunately, the bizarre "information -* obfuscating" policy of FreeRTOS (incorrectly called "information -* hiding") forces the use of the StaticQueue_t with "dummy" members. -* This could potentially break in the future releases of FreeRTOS. -* -* Currently, the correspondence between xQUEUE and StaticQueue_t -* is as follows (see queue.c and FreeRTOS.h, respectively): -* -* xQUEUE.uxMessagesWaiting == StaticQueue_t.uxDummy4[0]; -* xQUEUE.uxLength == StaticQueue_t.uxDummy4[1]; -*/ +// The following macro provides the number of free slots in the FreeRTOS +// queue. +// +// NOTE1: +// The official FreeRTOS API uxQueueSpacesAvailable() is not used +// here, because that API uses task-level critical section internally. +// Instead, the free slots calculation happens here in already +// established critical section. Unfortunately, the bizarre "information +// obfuscating" policy of FreeRTOS (incorrectly called "information +// hiding") forces the use of the StaticQueue_t with "dummy" members. +// This could potentially break in the future releases of FreeRTOS. +// +// Currently, the correspondence between xQUEUE and StaticQueue_t +// is as follows (see queue.c and FreeRTOS.h, respectively): +// +// xQUEUE.uxMessagesWaiting == StaticQueue_t.uxDummy4[0]; +// xQUEUE.uxLength == StaticQueue_t.uxDummy4[1]; +// #define FREERTOS_QUEUE_GET_FREE(me_) \ ((me_)->osObject.uxDummy4[1] - (me_)->osObject.uxDummy4[0]) -/*==========================================================================*/ +//============================================================================ void QF_init(void) { - /* empty for esp-idf */ + // empty for ESP-IDF } -/*..........................................................................*/ +//............................................................................ int_t QF_run(void) { - QF_onStartup(); /* the startup callback (configure/enable interrupts) */ + QF_onStartup(); // the startup callback (configure/enable interrupts) - return 0; /* dummy return to make the compiler happy */ + // produce the QS_QF_RUN trace record + QF_CRIT_STAT + QF_CRIT_ENTRY(); + QS_BEGIN_PRE_(QS_QF_RUN, 0U) + QS_END_PRE_() + QF_CRIT_EXIT(); + + return 0; // dummy return to make the compiler happy } -/*..........................................................................*/ +//............................................................................ void QF_stop(void) { - QF_onCleanup(); /* cleanup callback */ + QF_onCleanup(); // cleanup callback } -/*..........................................................................*/ -static void task_function(void *pvParameters) { /* FreeRTOS task signature */ +//............................................................................ +static void task_function(void *pvParameters) { // FreeRTOS task signature QActive *act = (QActive *)pvParameters; - /* event-loop */ - for (;;) { /* for-ever */ - QEvt const *e = QActive_get_(act); - QHSM_DISPATCH(&act->super, e, act->prio); - QF_gc(e); /* check if the event is garbage, and collect it if so */ +#ifdef QACTIVE_CAN_STOP + while (act->eQueue != (QueueHandle_t)0) +#else + for (;;) // for-ever +#endif + { + QEvt const *e = QActive_get_(act); // wait for event + QASM_DISPATCH(&act->super, e, act->prio); // dispatch to the SM + QF_gc(e); // check if the event is garbage, and collect it if so } +#ifdef QACTIVE_CAN_STOP + QActive_unregister_(act); // remove this object from the framewrok + vTaskDelete((TaskHandle_t)0); // delete this FreeRTOS task +#endif } -/*..........................................................................*/ -void QActive_start_(QActive * const me, QPrioSpec const prioSpec, - QEvt const * * const qSto, uint_fast16_t const qLen, - void * const stkSto, uint_fast16_t const stkSize, - void const * const par) + +//............................................................................ +void QActive_start_(QActive * const me, + QPrioSpec const prioSpec, + QEvt const * * const qSto, + uint_fast16_t const qLen, + void * const stkSto, + uint_fast16_t const stkSize, + void const * const par) { - Q_REQUIRE_ID(200, - (qSto != (QEvt const **)0) /* queue storage must be provided */ - && (qLen > 0U) /* queue size must be provided */ - && (stkSto != (void *)0) /* stack storage must be provided */ - && (stkSize > 0U)); /* stack size must be provided */ + QF_CRIT_STAT + QF_CRIT_ENTRY(); + // precondition: + // - queue storage must be provided + // - queue size must be provided + // - stack storage must be provided + // - stack size must be provided + Q_REQUIRE_INCRIT(200, + (qSto != (QEvt const **)0) && (qLen > 0U) + && (stkSto != (void *)0) && (stkSize > 0U)); + QF_CRIT_EXIT(); - /* create FreeRTOS message queue */ + // create FreeRTOS message queue me->eQueue = xQueueCreateStatic( - (UBaseType_t)qLen, /* length of the queue */ - (UBaseType_t)sizeof(QEvt *), /* element size */ - (uint8_t *)qSto, /* storage buffer */ - &me->osObject); /* static queue buffer */ - Q_ASSERT_ID(210, me->eQueue != (QueueHandle_t)0); + (UBaseType_t)qLen, // length of the queue + (UBaseType_t)sizeof(QEvt *), // element size + (uint8_t *)qSto, // storage buffer + &me->osObject); // static queue buffer + QF_CRIT_ENTRY(); + Q_ASSERT_INCRIT(210, me->eQueue != (QueueHandle_t)0); + QF_CRIT_EXIT(); - me->prio = (uint8_t)(prioSpec & 0xFFU); /* QF-priority of the AO */ - me->pthre = (uint8_t)(prioSpec >> 8U); /* preemption-threshold */ - QActive_register_(me); /* register this AO */ + me->prio = (uint8_t)(prioSpec & 0xFFU); // QF-priority of the AO + me->pthre = 0U; // preemption-threshold (not used) + QActive_register_(me); // register this AO - QHSM_INIT(&me->super, par, me->prio); /* the top-most initial tran. */ - QS_FLUSH(); /* flush the QS trace buffer to the host */ + // top-most initial tran. (virtual call) + (*me->super.vptr->init)(&me->super, par, me->prio); + QS_FLUSH(); // flush the QS trace buffer to the host - /* task name provided by the user in QActive_setAttr() or default name */ + // task name provided by the user in QActive_setAttr() or default name char const *taskName = (me->thread.pxDummy1 != (void *)0) ? (char const *)me->thread.pxDummy1 : (char const *)"AO"; - /* statically create the FreeRTOS task for the AO */ - Q_ALLEGE_ID(220, - (TaskHandle_t)0 != xTaskCreateStaticPinnedToCore( - &task_function, /* the task function */ - taskName , /* the name of the task */ - stkSize/sizeof(portSTACK_TYPE), /* stack length */ - (void *)me, /* the 'pvParameters' parameter */ - FREERTOS_TASK_PRIO(me->prio), /* FreeRTOS priority */ - (StackType_t *)stkSto, /* stack storage */ - &me->thread, /* task buffer */ - QPC_CPU_NUM)); /* CPU number */ + // statically create the FreeRTOS task for the AO + TaskHandle_t task = xTaskCreateStaticPinnedToCore( + &task_function, // the task function + taskName , // the name of the task + stkSize/sizeof(portSTACK_TYPE), // stack length + (void *)me, // the 'pvParameters' parameter + FREERTOS_TASK_PRIO(me->prio), // FreeRTOS priority + (StackType_t *)stkSto, // stack storage + &me->thread, // task buffer + QPC_CPU_NUM); // CPU number + + QF_CRIT_ENTRY(); + Q_ASSERT_INCRIT(220, task != (TaskHandle_t)0); + QF_CRIT_EXIT(); } -/*..........................................................................*/ +//............................................................................ +#ifdef QACTIVE_CAN_STOP +void QActive_stop(QActive * const me) { + QActive_unsubscribeAll(me); // unsubscribe from all events + me->eQueue = (QueueHandle_t)0; // stop the thread (see task_function()) +} +#endif +//............................................................................ void QActive_setAttr(QActive *const me, uint32_t attr1, void const *attr2) { - /* this function must be called before QACTIVE_START(), - * which implies that me->thread.pxDummy1 must not be used yet; - */ - Q_REQUIRE_ID(300, me->thread.pxDummy1 == (void *)0); + QF_CRIT_STAT + QF_CRIT_ENTRY(); + // this function must be called before QACTIVE_START(), + // which implies that me->thread.pxDummy1 must not be used yet; + Q_REQUIRE_INCRIT(300, me->thread.pxDummy1 == (void *)0); switch (attr1) { case TASK_NAME_ATTR: - /* temporarily store the name */ - me->thread.pxDummy1 = (void *)attr2; /* cast 'const' away */ + // temporarily store the name, cast 'const' away + me->thread.pxDummy1 = (void *)attr2; break; - /* ... */ + // ... } + QF_CRIT_EXIT(); } -/*==========================================================================*/ +//============================================================================ bool IRAM_ATTR QActive_post_(QActive * const me, QEvt const * const e, uint_fast16_t const margin, void const * const sender) { - QF_CRIT_STAT_ - QF_CRIT_E_(); +#ifndef Q_SPY + Q_UNUSED_PAR(sender); +#endif - /* find out the number of free slots available in the queue */ + QF_CRIT_STAT + QF_CRIT_ENTRY(); + + // find the number of free slots available in the queue uint_fast16_t const nFree = (uint_fast16_t)FREERTOS_QUEUE_GET_FREE(me); bool status; if (margin == QF_NO_MARGIN) { if (nFree > 0U) { - status = true; /* can post */ + status = true; // can post } else { - status = false; /* cannot post */ - Q_ERROR_ID(510); /* must be able to post the event */ + status = false; // cannot post + Q_ERROR_INCRIT(510); // must be able to post the event } } else if (nFree > margin) { - status = true; /* can post */ + status = true; // can post } else { - status = false; /* cannot post */ + status = false; // cannot post } - if (status) { /* can post the event? */ + if (status) { // can post the event? - QS_BEGIN_NOCRIT_PRE_(QS_QF_ACTIVE_POST, me->prio) - QS_TIME_PRE_(); /* timestamp */ - QS_OBJ_PRE_(sender); /* the sender object */ - QS_SIG_PRE_(e->sig); /* the signal of the event */ - QS_OBJ_PRE_(me); /* this active object (recipient) */ - QS_2U8_PRE_(e->poolId_, e->refCtr_); /* pool Id & ref Count */ - QS_EQC_PRE_((QEQueueCtr)nFree); /* # free entries available */ - QS_EQC_PRE_(0U); /* min # free entries (unknown) */ - QS_END_NOCRIT_PRE_() + QS_BEGIN_PRE_(QS_QF_ACTIVE_POST, me->prio) + QS_TIME_PRE_(); // timestamp + QS_OBJ_PRE_(sender); // the sender object + QS_SIG_PRE_(e->sig); // the signal of the event + QS_OBJ_PRE_(me); // this active object (recipient) + QS_2U8_PRE_(QEvt_getPoolId_(e), e->refCtr_); // pool Id&ref Count + QS_EQC_PRE_((QEQueueCtr)nFree); // # free entries + QS_EQC_PRE_(0U); // min # free entries (unknown) + QS_END_PRE_() - if (e->poolId_ != 0U) { /* is it a pool event? */ - QEvt_refCtr_inc_(e); /* increment the reference counter */ + if (QEvt_getPoolId_(e) != 0U) { // is it a pool event? + QEvt_refCtr_inc_(e); // increment the reference counter } + QF_CRIT_EXIT(); - QF_CRIT_X_(); + BaseType_t err = xQueueSendToBack( + me->eQueue, (void const *)&e, (TickType_t)0); - /* posting to the FreeRTOS message queue must succeed, see NOTE3 */ - Q_ALLEGE_ID(520, - xQueueSend(me->eQueue, (void const *)&e, portMAX_DELAY) - == pdPASS); + // posting to the FreeRTOS message queue must succeed, see NOTE3 + QF_CRIT_ENTRY(); + Q_ASSERT_INCRIT(520, err == pdPASS); } else { - QS_BEGIN_NOCRIT_PRE_(QS_QF_ACTIVE_POST_ATTEMPT, me->prio) - QS_TIME_PRE_(); /* timestamp */ - QS_OBJ_PRE_(sender); /* the sender object */ - QS_SIG_PRE_(e->sig); /* the signal of the event */ - QS_OBJ_PRE_(me); /* this active object (recipient) */ - QS_2U8_PRE_(e->poolId_, e->refCtr_); /* pool Id & ref Count */ - QS_EQC_PRE_((QEQueueCtr)nFree); /* # free entries available */ - QS_EQC_PRE_(margin); /* margin requested */ - QS_END_NOCRIT_PRE_() - - QF_CRIT_X_(); - } + QS_BEGIN_PRE_(QS_QF_ACTIVE_POST_ATTEMPT, me->prio) + QS_TIME_PRE_(); // timestamp + QS_OBJ_PRE_(sender); // the sender object + QS_SIG_PRE_(e->sig); // the signal of the event + QS_OBJ_PRE_(me); // this active object (recipient) + QS_2U8_PRE_(QEvt_getPoolId_(e), e->refCtr_); // pool Id&ref Count + QS_EQC_PRE_((QEQueueCtr)nFree); // # free entries + QS_EQC_PRE_(margin); // margin requested + QS_END_PRE_() + } + QF_CRIT_EXIT(); return status; } -/*..........................................................................*/ +//............................................................................ void IRAM_ATTR QActive_postLIFO_(QActive * const me, QEvt const * const e) { - QF_CRIT_STAT_ - QF_CRIT_E_(); + QF_CRIT_STAT + QF_CRIT_ENTRY(); - QS_BEGIN_NOCRIT_PRE_(QS_QF_ACTIVE_POST_LIFO, me->prio) - QS_TIME_PRE_(); /* timestamp */ - QS_SIG_PRE_(e->sig); /* the signal of this event */ - QS_OBJ_PRE_(me); /* this active object */ - QS_2U8_PRE_(e->poolId_, e->refCtr_); /* pool Id & ref Count */ - QS_EQC_PRE_((QEQueueCtr)FREERTOS_QUEUE_GET_FREE(me)); /* # free */ - QS_EQC_PRE_(0U); /* min # free entries (unknown) */ - QS_END_NOCRIT_PRE_() + QS_BEGIN_PRE_(QS_QF_ACTIVE_POST_LIFO, me->prio) + QS_TIME_PRE_(); // timestamp + QS_SIG_PRE_(e->sig); // the signal of this event + QS_OBJ_PRE_(me); // this active object + QS_2U8_PRE_(QEvt_getPoolId_(e), e->refCtr_); // pool Id&ref Count + QS_EQC_PRE_((QEQueueCtr)FREERTOS_QUEUE_GET_FREE(me)); // # free + QS_EQC_PRE_(0U); // min # free entries (unknown) + QS_END_PRE_() - if (e->poolId_ != 0U) { /* is it a pool event? */ - QEvt_refCtr_inc_(e); /* increment the reference counter */ + if (QEvt_getPoolId_(e) != 0U) { // is it a pool event? + QEvt_refCtr_inc_(e); // increment the reference counter } + QF_CRIT_EXIT(); - QF_CRIT_X_(); + BaseType_t err = xQueueSendToFront( + me->eQueue, (void const *)&e, (TickType_t)0); - /* LIFO posting to the FreeRTOS queue must succeed */ - Q_ALLEGE_ID(610, - xQueueSendToBack(me->eQueue, (void const *)&e, portMAX_DELAY) - == pdPASS); + // LIFO posting to the FreeRTOS queue must succeed, see NOTE3 + QF_CRIT_ENTRY(); + Q_ASSERT_INCRIT(610, err == pdPASS); + QF_CRIT_EXIT(); } -/*..........................................................................*/ +//............................................................................ QEvt const *QActive_get_(QActive * const me) { QEvt const *e; xQueueReceive(me->eQueue, (void *)&e, portMAX_DELAY); - QS_CRIT_STAT_ + QS_CRIT_STAT + QS_CRIT_ENTRY(); QS_BEGIN_PRE_(QS_QF_ACTIVE_GET, me->prio) - QS_TIME_PRE_(); /* timestamp */ - QS_SIG_PRE_(e->sig); /* the signal of this event */ - QS_OBJ_PRE_(me); /* this active object */ - QS_2U8_PRE_(e->poolId_, e->refCtr_); /* pool Id & ref Count */ - QS_EQC_PRE_((QEQueueCtr)FREERTOS_QUEUE_GET_FREE(me)); /* # free */ + QS_TIME_PRE_(); // timestamp + QS_SIG_PRE_(e->sig); // the signal of this event + QS_OBJ_PRE_(me); // this active object + QS_2U8_PRE_(QEvt_getPoolId_(e), e->refCtr_); // pool Id&ref Count + QS_EQC_PRE_((QEQueueCtr)FREERTOS_QUEUE_GET_FREE(me)); // # free QS_END_PRE_() + QS_CRIT_EXIT(); return e; } -/*==========================================================================*/ -/* The "FromISR" QP APIs for the FreeRTOS port... */ +//============================================================================ +// The "FromISR" QP APIs for the FreeRTOS port... bool IRAM_ATTR QActive_postFromISR_(QActive * const me, QEvt const * const e, uint_fast16_t const margin, BaseType_t * const pxHigherPriorityTaskWoken, @@ -281,424 +327,454 @@ bool IRAM_ATTR QActive_postFromISR_(QActive * const me, QEvt const * const e, { portENTER_CRITICAL_ISR(&QF_esp32mux); - /* find out the number of free slots in the queue */ + // find the number of free slots available in the queue uint_fast16_t const nFree = (uint_fast16_t)FREERTOS_QUEUE_GET_FREE(me); bool status; if (margin == QF_NO_MARGIN) { if (nFree > 0U) { - status = true; /* can post */ + status = true; // can post } else { - status = false; /* cannot post */ - Q_ERROR_ID(810); /* must be able to post the event */ + status = false; // cannot post + Q_ERROR_INCRIT(810); // must be able to post the event } } else if (nFree > margin) { - status = true; /* can post */ + status = true; // can post } else { - status = false; /* cannot post */ + status = false; // cannot post } - if (status) { /* can post the event? */ + if (status) { // can post the event? - QS_BEGIN_NOCRIT_PRE_(QS_QF_ACTIVE_POST, me->prio) - QS_TIME_PRE_(); /* timestamp */ - QS_OBJ_PRE_(sender); /* the sender object */ - QS_SIG_PRE_(e->sig); /* the signal of the event */ - QS_OBJ_PRE_(me); /* this active object (recipient) */ - QS_2U8_PRE_(e->poolId_, e->refCtr_); /* pool Id & ref Count */ - QS_EQC_PRE_(nFree); /* # free entries available */ - QS_EQC_PRE_(0U); /* min # free entries (unknown) */ - QS_END_NOCRIT_PRE_() + QS_BEGIN_PRE_(QS_QF_ACTIVE_POST, me->prio) + QS_TIME_PRE_(); // timestamp + QS_OBJ_PRE_(sender); // the sender object + QS_SIG_PRE_(e->sig); // the signal of the event + QS_OBJ_PRE_(me); // this active object (recipient) + QS_2U8_PRE_(QEvt_getPoolId_(e), e->refCtr_); // pool Id&ref Count + QS_EQC_PRE_(nFree); // # free entries available + QS_EQC_PRE_(0U); // min # free entries (unknown) + QS_END_PRE_() - if (e->poolId_ != 0U) { /* is it a pool event? */ - QEvt_refCtr_inc_(e); /* increment the reference counter */ + if (QEvt_getPoolId_(e) != 0U) { // is it a pool event? + QEvt_refCtr_inc_(e); // increment the reference counter } - portEXIT_CRITICAL_ISR(&QF_esp32mux); - /* posting to the FreeRTOS message queue must succeed */ - Q_ALLEGE_ID(820, - xQueueSendFromISR(me->eQueue, (void const *)&e, - pxHigherPriorityTaskWoken) - == pdTRUE); + BaseType_t err = xQueueSendToBackFromISR(me->eQueue, + (void const *)&e, + pxHigherPriorityTaskWoken); + + // posting to the FreeRTOS message queue must succeed + portENTER_CRITICAL_ISR(&QF_esp32mux); + Q_ASSERT_INCRIT(820, err == pdPASS); + portEXIT_CRITICAL_ISR(&QF_esp32mux); } else { - QS_BEGIN_NOCRIT_PRE_(QS_QF_ACTIVE_POST_ATTEMPT, me->prio) - QS_TIME_PRE_(); /* timestamp */ - QS_OBJ_PRE_(sender); /* the sender object */ - QS_SIG_PRE_(e->sig); /* the signal of the event */ - QS_OBJ_PRE_(me); /* this active object (recipient) */ - QS_2U8_PRE_(e->poolId_, e->refCtr_); /* pool Id & ref Count */ - QS_EQC_PRE_(nFree); /* # free entries available */ - QS_EQC_PRE_(margin); /* margin requested */ - QS_END_NOCRIT_PRE_() - + QS_BEGIN_PRE_(QS_QF_ACTIVE_POST_ATTEMPT, me->prio) + QS_TIME_PRE_(); // timestamp + QS_OBJ_PRE_(sender); // the sender object + QS_SIG_PRE_(e->sig); // the signal of the event + QS_OBJ_PRE_(me); // this active object (recipient) + QS_2U8_PRE_(QEvt_getPoolId_(e), e->refCtr_); // pool Id&ref Count + QS_EQC_PRE_(nFree); // # free entries available + QS_EQC_PRE_(margin); // margin requested + QS_END_PRE_() portEXIT_CRITICAL_ISR(&QF_esp32mux); - QF_gcFromISR(e); /* recycle the event to avoid a leak */ + QF_gcFromISR(e); // recycle the event to avoid a leak } return status; } -/*..........................................................................*/ +//............................................................................ void IRAM_ATTR QActive_publishFromISR_(QEvt const * const e, BaseType_t * const pxHigherPriorityTaskWoken, void const * const sender) { - /** @pre the published signal must be within the configured range */ - Q_REQUIRE_ID(500, e->sig < (QSignal)QActive_maxPubSignal_); + QSignal const sig = e->sig; portENTER_CRITICAL_ISR(&QF_esp32mux); - QS_BEGIN_NOCRIT_PRE_(QS_QF_PUBLISH, 0U) - QS_TIME_PRE_(); /* the timestamp */ - QS_OBJ_PRE_(sender); /* the sender object */ - QS_SIG_PRE_(e->sig); /* the signal of the event */ - QS_2U8_PRE_(e->poolId_, e->refCtr_);/* pool-Id & ref-Count */ - QS_END_NOCRIT_PRE_() + //! @pre the published signal must be within the configured range + Q_REQUIRE_INCRIT(500, sig < (QSignal)QActive_maxPubSignal_); + Q_REQUIRE_INCRIT(502, + QPSet_verify_(&QActive_subscrList_[sig].set, + &QActive_subscrList_[sig].set_dis)); - /* is it a dynamic event? */ - if (e->poolId_ != 0U) { - /* NOTE: The reference counter of a dynamic event is incremented to - * prevent premature recycling of the event while the multicasting - * is still in progress. At the end of the function, the garbage - * collector step (QF_gcFromISR()) decrements the reference counter and - * recycles the event if the counter drops to zero. This covers the - * case when the event was published without any subscribers. - */ + QS_BEGIN_PRE_(QS_QF_PUBLISH, 0U) + QS_TIME_PRE_(); // the timestamp + QS_OBJ_PRE_(sender); // the sender object + QS_SIG_PRE_(sig); // the signal of the event + QS_2U8_PRE_(QEvt_getPoolId_(e), e->refCtr_);// pool-Id & ref-Count + QS_END_PRE_() + + // is it a dynamic event? + if (QEvt_getPoolId_(e) != 0U) { + // NOTE: The reference counter of a dynamic event is incremented to + // prevent premature recycling of the event while the multicasting + // is still in progress. At the end of the function, the garbage + // collector step (QF_gcFromISR()) decrements the reference counter + // and recycles the event if the counter drops to zero. This covers + // the case when the event was published without any subscribers. QEvt_refCtr_inc_(e); } - /* make a local, modifiable copy of the subscriber list */ - QPSet subscrList = QActive_subscrList_[e->sig]; + // make a local, modifiable copy of the subscriber list + QPSet subscrSet = QActive_subscrList_[sig].set; portEXIT_CRITICAL_ISR(&QF_esp32mux); - if (QPSet_notEmpty(&subscrList)) { /* any subscribers? */ - /* the highest-prio subscriber */ - uint_fast8_t p = QPSet_findMax(&subscrList); + if (QPSet_notEmpty(&subscrSet)) { // any subscribers? + // the highest-prio subscriber + uint_fast8_t p = QPSet_findMax(&subscrSet); - /* no need to lock the scheduler in the ISR context */ - do { /* loop over all subscribers */ - /* the prio of the AO must be registered with the framework */ - Q_ASSERT_ID(510, QActive_registry_[p] != (QActive *)0); + // no need to lock the scheduler in the ISR context + do { // loop over all subscribers + // the prio of the AO must be registered with the framework + portENTER_CRITICAL_ISR(&QF_esp32mux); + Q_ASSERT_INCRIT(510, QActive_registry_[p] != (QActive *)0); + portEXIT_CRITICAL_ISR(&QF_esp32mux); - /* QACTIVE_POST_FROM_ISR() asserts if the queue overflows */ + // QACTIVE_POST_FROM_ISR() asserts if the queue overflows QACTIVE_POST_FROM_ISR(QActive_registry_[p], e, pxHigherPriorityTaskWoken, sender); - QPSet_remove(&subscrList, p); /* remove the handled subscriber */ - if (QPSet_notEmpty(&subscrList)) { /* still more subscribers? */ - /* highest-prio subscriber */ - p = QPSet_findMax(&subscrList); + QPSet_remove(&subscrSet, p); // remove the handled subscriber + if (QPSet_notEmpty(&subscrSet)) { // still more subscribers? + p = QPSet_findMax(&subscrSet); // the highest-prio subscriber } else { - p = 0U; /* no more subscribers */ + p = 0U; // no more subscribers } } while (p != 0U); - /* no need to unlock the scheduler in the ISR context */ + // no need to unlock the scheduler in the ISR context } - /* The following garbage collection step decrements the reference counter - * and recycles the event if the counter drops to zero. This covers both - * cases when the event was published with or without any subscribers. - */ + // The following garbage collection step decrements the reference counter + // and recycles the event if the counter drops to zero. This covers both + // cases when the event was published with or without any subscribers. QF_gcFromISR(e); } -/*..........................................................................*/ +//............................................................................ void IRAM_ATTR QTimeEvt_tickFromISR_(uint_fast8_t const tickRate, BaseType_t * const pxHigherPriorityTaskWoken, void const * const sender) { - QTimeEvt *prev = &QTimeEvt_timeEvtHead_[tickRate]; - portENTER_CRITICAL_ISR(&QF_esp32mux); - QS_BEGIN_NOCRIT_PRE_(QS_QF_TICK, 0U) + QTimeEvt *prev = &QTimeEvt_timeEvtHead_[tickRate]; + + QS_BEGIN_PRE_(QS_QF_TICK, 0U) ++prev->ctr; - QS_TEC_PRE_(prev->ctr); /* tick ctr */ - QS_U8_PRE_(tickRate); /* tick rate */ - QS_END_NOCRIT_PRE_() + QS_TEC_PRE_(prev->ctr); // tick ctr + QS_U8_PRE_(tickRate); // tick rate + QS_END_PRE_() - /* scan the linked-list of time events at this rate... */ + // scan the linked-list of time events at this rate... for (;;) { - QTimeEvt *t = prev->next; /* advance down the time evt. list */ + QTimeEvt *t = prev->next; // advance down the time evt. list - /* end of the list? */ + // end of the list? if (t == (QTimeEvt *)0) { - /* any new time events armed since the last QTimeEvt_tick_()? */ + // any new time events armed since the last QTimeEvt_tick_()? if (QTimeEvt_timeEvtHead_[tickRate].act != (void *)0) { - /* sanity check */ - Q_ASSERT_ID(610, prev != (QTimeEvt *)0); + // sanity check + Q_ASSERT_INCRIT(610, prev != (QTimeEvt *)0); prev->next = (QTimeEvt *)QTimeEvt_timeEvtHead_[tickRate].act; QTimeEvt_timeEvtHead_[tickRate].act = (void *)0; - t = prev->next; /* switch to the new list */ + t = prev->next; // switch to the new list } else { - break; /* all currently armed time evts. processed */ + break; // all currently armed time evts. processed } } - /* time event scheduled for removal? */ + // time event scheduled for removal? if (t->ctr == 0U) { prev->next = t->next; - /* mark time event 't' as NOT linked */ + // mark time event 't' as NOT linked t->super.refCtr_ &= (uint8_t)(~QTE_IS_LINKED); - /* do NOT advance the prev pointer */ - /* exit crit. section to reduce latency */ + // do NOT advance the prev pointer + // exit crit. section to reduce latency portEXIT_CRITICAL_ISR(&QF_esp32mux); } else { --t->ctr; - /* is time event about to expire? */ - if (t->ctr == (QTimeEvtCtr)0) { - QActive *act = (QActive *)t->act; /* temp. for volatile */ + // is time evt about to expire? + if (t->ctr == 0U) { + QActive *act = (QActive *)t->act; // temp. for volatile - /* periodic time evt? */ + // periodic time evt? if (t->interval != 0U) { - t->ctr = t->interval; /* rearm the time event */ - prev = t; /* advance to this time event */ + t->ctr = t->interval; // rearm the time event + prev = t; // advance to this time event } - /* one-shot time event: automatically disarm */ + // one-shot time event: automatically disarm else { prev->next = t->next; - /* mark time event 't' as NOT linked */ + // mark time event 't' as NOT linked t->super.refCtr_ &= (uint8_t)(~QTE_IS_LINKED); - /* do NOT advance the prev pointer */ + // do NOT advance the prev pointer - QS_BEGIN_NOCRIT_PRE_(QS_QF_TIMEEVT_AUTO_DISARM, act->prio) - QS_OBJ_PRE_(t); /* this time event object */ - QS_OBJ_PRE_(act); /* the target AO */ - QS_U8_PRE_(tickRate); /* tick rate */ - QS_END_NOCRIT_PRE_() + QS_BEGIN_PRE_(QS_QF_TIMEEVT_AUTO_DISARM, act->prio) + QS_OBJ_PRE_(t); // this time event object + QS_OBJ_PRE_(act); // the target AO + QS_U8_PRE_(tickRate); // tick rate + QS_END_PRE_() } - QS_BEGIN_NOCRIT_PRE_(QS_QF_TIMEEVT_POST, act->prio) - QS_TIME_PRE_(); /* timestamp */ - QS_OBJ_PRE_(t); /* the time event object */ - QS_SIG_PRE_(t->super.sig); /* signal of this time event */ - QS_OBJ_PRE_(act); /* the target AO */ - QS_U8_PRE_(tickRate); /* tick rate */ - QS_END_NOCRIT_PRE_() + QS_BEGIN_PRE_(QS_QF_TIMEEVT_POST, act->prio) + QS_TIME_PRE_(); // timestamp + QS_OBJ_PRE_(t); // the time event object + QS_SIG_PRE_(t->super.sig); // signal of time event + QS_OBJ_PRE_(act); // the target AO + QS_U8_PRE_(tickRate); // tick rate + QS_END_PRE_() - /* exit critical section before posting */ + // exit critical section before posting portEXIT_CRITICAL_ISR(&QF_esp32mux); - /* QACTIVE_POST_FROM_ISR() asserts if the queue overflows */ + // QACTIVE_POST_FROM_ISR() asserts if the queue overflows QACTIVE_POST_FROM_ISR(act, &t->super, pxHigherPriorityTaskWoken, sender); } else { - prev = t; /* advance to this time event */ - /* exit crit. section to reduce latency */ + prev = t; // advance to this time event + // exit crit. section to reduce latency portEXIT_CRITICAL_ISR(&QF_esp32mux); } } - /* re-enter crit. section to continue */ + // re-enter crit. section to continue portENTER_CRITICAL_ISR(&QF_esp32mux); } portEXIT_CRITICAL_ISR(&QF_esp32mux); } -/*..........................................................................*/ +//............................................................................ QEvt IRAM_ATTR *QF_newXFromISR_(uint_fast16_t const evtSize, uint_fast16_t const margin, enum_t const sig) { - /* find the pool index that fits the requested event size ... */ + // find the poolId that fits the requested event size ... uint_fast8_t idx; - for (idx = 0U; idx < QF_maxPool_; ++idx) { - if (evtSize <= QF_EPOOL_EVENT_SIZE_(QF_ePool_[idx])) { + for (idx = 0U; idx < QF_priv_.maxPool_; ++idx) { + if (evtSize <= QF_EPOOL_EVENT_SIZE_(QF_priv_.ePool_[idx])) { break; } } - /* cannot run out of registered pools */ - Q_ASSERT_ID(710, idx < QF_maxPool_); + // cannot run out of registered pools + portENTER_CRITICAL_ISR(&QF_esp32mux); + Q_REQUIRE_INCRIT(700, idx < QF_priv_.maxPool_); + portEXIT_CRITICAL_ISR(&QF_esp32mux); - /* get e -- platform-dependent */ + // get e -- platform-dependent #ifdef Q_SPY - QEvt *e = QMPool_getFromISR(&QF_ePool_[idx], + QEvt *e = QMPool_getFromISR(&QF_priv_.ePool_[idx], ((margin != QF_NO_MARGIN) ? margin : 0U), (uint_fast8_t)QS_EP_ID + idx + 1U); #else - QEvt *e = QMPool_getFromISR(&QF_ePool_[idx], + QEvt *e = QMPool_getFromISR(&QF_priv_.ePool_[idx], ((margin != QF_NO_MARGIN) ? margin : 0U), 0U); #endif - /* was e allocated correctly? */ + // was e allocated correctly? if (e != (QEvt *)0) { - e->sig = (QSignal)sig; /* set signal for this event */ - e->poolId_ = (uint8_t)(idx + 1U); /* store the pool ID */ - e->refCtr_ = 0U; /* set the reference counter to 0 */ + QEvt_ctor(e, sig); + e->evtTag_ = (uint8_t)(QEVT_MARKER | (idx + 1U)); // pool ID #ifdef Q_SPY portENTER_CRITICAL_ISR(&QF_esp32mux); - QS_BEGIN_PRE_(QS_QF_NEW, (uint_fast8_t)QS_EP_ID + e->poolId_) - QS_TIME_PRE_(); /* timestamp */ - QS_EVS_PRE_(evtSize); /* the size of the event */ - QS_SIG_PRE_(sig); /* the signal of the event */ - QS_END_NOCRIT_PRE_() + QS_BEGIN_PRE_(QS_QF_NEW, + (uint_fast8_t)QS_EP_ID + idx + 1U) + QS_TIME_PRE_(); // timestamp + QS_EVS_PRE_(evtSize); // the size of the event + QS_SIG_PRE_(sig); // the signal of the event + QS_END_PRE_() portEXIT_CRITICAL_ISR(&QF_esp32mux); -#endif /* Q_SPY */ +#endif // Q_SPY } - /* event cannot be allocated */ - else { - /* must tolerate bad alloc. */ - Q_ASSERT_ID(720, margin != QF_NO_MARGIN); + else { // event cannot be allocated + // must tolerate bad alloc. + portENTER_CRITICAL_ISR(&QF_esp32mux); + Q_ASSERT_INCRIT(720, margin != QF_NO_MARGIN); + portEXIT_CRITICAL_ISR(&QF_esp32mux); #ifdef Q_SPY portENTER_CRITICAL_ISR(&QF_esp32mux); - QS_BEGIN_PRE_(QS_QF_NEW_ATTEMPT, (uint_fast8_t)QS_EP_ID + idx + 1U) - QS_TIME_PRE_(); /* timestamp */ - QS_EVS_PRE_(evtSize); /* the size of the event */ - QS_SIG_PRE_(sig); /* the signal of the event */ - QS_END_NOCRIT_PRE_() + QS_BEGIN_PRE_(QS_QF_NEW_ATTEMPT, + (uint_fast8_t)QS_EP_ID + idx + 1U) + QS_TIME_PRE_(); // timestamp + QS_EVS_PRE_(evtSize); // the size of the event + QS_SIG_PRE_(sig); // the signal of the event + QS_END_PRE_() portEXIT_CRITICAL_ISR(&QF_esp32mux); -#endif /* Q_SPY */ +#endif // Q_SPY } - return e; /* can't be NULL if we can't tolerate bad allocation */ + return e; // can't be NULL if we can't tolerate bad allocation } -/*..........................................................................*/ +//............................................................................ void IRAM_ATTR QF_gcFromISR(QEvt const * const e) { - - /* is it a dynamic event? */ - if (e->poolId_ != 0U) { + // is it a dynamic event? + if (QEvt_getPoolId_(e) != 0U) { portENTER_CRITICAL_ISR(&QF_esp32mux); - /* isn't this the last ref? */ + // isn't this the last ref? if (e->refCtr_ > 1U) { - QEvt_refCtr_dec_(e); /* decrement the reference counter */ + QEvt_refCtr_dec_(e); // decrement the ref counter - QS_BEGIN_NOCRIT_PRE_(QS_QF_GC_ATTEMPT, (uint_fast8_t)e->poolId_) - QS_TIME_PRE_(); /* timestamp */ - QS_SIG_PRE_(e->sig); /* the signal of the event */ - QS_2U8_PRE_(e->poolId_, e->refCtr_); /* pool Id & ref Count */ - QS_END_NOCRIT_PRE_() + QS_BEGIN_PRE_(QS_QF_GC_ATTEMPT, + (uint_fast8_t)QEvt_getPoolId_(e)) + QS_TIME_PRE_(); // timestamp + QS_SIG_PRE_(e->sig); // the signal of the event + QS_2U8_PRE_(QEvt_getPoolId_(e), e->refCtr_);//pool-Id&ref-Count + QS_END_PRE_() portEXIT_CRITICAL_ISR(&QF_esp32mux); } - /* this is the last reference to this event, recycle it */ + // this is the last reference to this event, recycle it else { - uint_fast8_t idx = (uint_fast8_t)e->poolId_ - 1U; + uint_fast8_t idx = (uint_fast8_t)QEvt_getPoolId_(e) - 1U; - QS_BEGIN_NOCRIT_PRE_(QS_QF_GC, (uint_fast8_t)e->poolId_) - QS_TIME_PRE_(); /* timestamp */ - QS_SIG_PRE_(e->sig); /* the signal of the event */ - QS_2U8_PRE_(e->poolId_, e->refCtr_); /* pool Id & ref Count */ - QS_END_NOCRIT_PRE_() + QS_BEGIN_PRE_(QS_QF_GC, (uint_fast8_t)QEvt_getPoolId_(e)) + QS_TIME_PRE_(); // timestamp + QS_SIG_PRE_(e->sig); // the signal of the event + QS_2U8_PRE_(QEvt_getPoolId_(e), e->refCtr_);//pool-Id&ref-Count + QS_END_PRE_() + + // pool ID must be in range + Q_ASSERT_INCRIT(810, idx < QF_priv_.maxPool_); portEXIT_CRITICAL_ISR(&QF_esp32mux); - /* pool ID must be in range */ - Q_ASSERT_ID(810, idx < QF_maxPool_); - #ifdef Q_SPY - /* cast 'const' away in (QEvt *)e is OK, - * because it's a pool event */ - QMPool_putFromISR(&QF_ePool_[idx], (QEvt *)e, - (uint_fast8_t)QS_EP_ID + e->poolId_); + // cast 'const' away in (QEvt *)e is OK because it's a pool event + QMPool_putFromISR(&QF_priv_.ePool_[idx], (QEvt *)e, + (uint_fast8_t)QS_EP_ID + QEvt_getPoolId_(e)); #else - QMPool_putFromISR(&QF_ePool_[idx], (QEvt *)e, 0U); + QMPool_putFromISR(&QF_priv_.ePool_[idx], (QEvt *)e, 0U); #endif } } } -/*..........................................................................*/ +//............................................................................ void IRAM_ATTR QMPool_putFromISR(QMPool * const me, void *b, uint_fast8_t const qs_id) { - /** @pre # free blocks cannot exceed the total # blocks and - * the block pointer must be from this pool. - */ - Q_REQUIRE_ID(900, (me->nFree < me->nTot) - && (me->start <= b) && (b <= me->end)); +#ifndef Q_SPY + Q_UNUSED_PAR(qs_id); +#endif - (void)qs_id; /* unused parameter (outside Q_SPY build configuration) */ + QFreeBlock * const fb = (QFreeBlock *)block; portENTER_CRITICAL_ISR(&QF_esp32mux); - ((QFreeBlock *)b)->next = (QFreeBlock *)me->free_head;/* link into list */ - me->free_head = b; /* set as new head of the free list */ - ++me->nFree; /* one more free block in this pool */ + // precondition: + // - # free blocks cannot exceed the total # blocks and + // - the block pointer must be from this pool. + Q_REQUIRE_INCRIT(900, (me->nFree < me->nTot) + && (me->start <= fb) && (fb <= me->end)); - QS_BEGIN_NOCRIT_PRE_(QS_QF_MPOOL_PUT, qs_id) - QS_TIME_PRE_(); /* timestamp */ - QS_OBJ_PRE_(me->start); /* the memory managed by this pool */ - QS_MPC_PRE_(me->nFree); /* # free blocks in the pool */ - QS_END_NOCRIT_PRE_() + fb->next = me->free_head; // link into list +#ifndef Q_UNSAFE + fb->next_dis = (uintptr_t)(~Q_UINTPTR_CAST_(fb->next)); +#endif + + me->free_head = block; // set as new head of the free list + ++me->nFree; // one more free block in this pool + + QS_BEGIN_PRE_(QS_QF_MPOOL_PUT, qs_id) + QS_TIME_PRE_(); // timestamp + QS_OBJ_PRE_(me); // this memory pool + QS_MPC_PRE_(me->nFree); // the number of free blocks in the pool + QS_END_PRE_() portEXIT_CRITICAL_ISR(&QF_esp32mux); } -/*..........................................................................*/ +//............................................................................ void *QMPool_getFromISR(QMPool * const me, uint_fast16_t const margin, uint_fast8_t const qs_id) { - (void)qs_id; /* unused parameter (outside Q_SPY build configuration) */ +#ifndef Q_SPY + Q_UNUSED_PAR(qs_id); +#endif portENTER_CRITICAL_ISR(&QF_esp32mux); - /* have more free blocks than the requested margin? */ + // have more free blocks than the requested margin? QFreeBlock *fb; if (me->nFree > (QMPoolCtr)margin) { - void *fb_next; - fb = (QFreeBlock *)me->free_head; /* get a free block */ + fb = me->free_head; // get a free block - /* the pool has some free blocks, so a free block must be available */ - Q_ASSERT_ID(910, fb != (QFreeBlock *)0); + // the pool has some free blocks, so a free block must be available + Q_ASSERT_INCRIT(900, fb != (QFreeBlock *)0); - fb_next = fb->next; /* put volatile to a temporary to avoid UB */ + QFreeBlock * const fb_next = fb->next; // fast temporary to avoid UB - /* is the pool becoming empty? */ - --me->nFree; /* one less free block */ - if (me->nFree == (QMPoolCtr)0) { - /* pool is becoming empty, so the next free block must be NULL */ - Q_ASSERT_ID(920, fb_next == (QFreeBlock *)0); + // the free block must have integrity (duplicate inverse storage) + Q_ASSERT_INCRIT(902, Q_UINTPTR_CAST_(fb_next) + == (uintptr_t)~fb->next_dis); - me->nMin = (QMPoolCtr)0; /* remember that the pool got empty */ + // is the pool becoming empty? + --me->nFree; // one less free block + if (me->nFree == 0U) { + // pool is becoming empty, so the next free block must be NULL + Q_ASSERT_INCRIT(920, fb_next == (QFreeBlock *)0); + + me->nMin = 0U; // remember that the pool got empty } else { - /* pool is not empty, so the next free block must be in range - * - * NOTE: the next free block pointer can fall out of range - * when the client code writes past the memory block, thus - * corrupting the next block. - */ - Q_ASSERT_ID(930, (me->start <= fb_next) && (fb_next <= me->end)); + // invariant + // The pool is not empty, so the next free-block pointer, + // so the next free block must be in range. + // + // NOTE: The next free block pointer can fall out of range + // when the client code writes past the memory block, thus + // corrupting the next block. + Q_ASSERT_INCRIT(930, + (me->start <= fb_next) && (fb_next <= me->end)); - /* is the number of free blocks the new minimum so far? */ + // is the number of free blocks the new minimum so far? if (me->nMin > me->nFree) { - me->nMin = me->nFree; /* remember the new minimum */ + me->nMin = me->nFree; // remember the new minimum } } - me->free_head = fb_next; /* set the head to the next free block */ - - QS_BEGIN_NOCRIT_PRE_(QS_QF_MPOOL_GET, qs_id) - QS_TIME_PRE_(); /* timestamp */ - QS_OBJ_PRE_(me->start); /* the memory managed by this pool */ - QS_MPC_PRE_(me->nFree); /* # free blocks in the pool */ - QS_MPC_PRE_(me->nMin); /* min # free blocks ever in the pool */ - QS_END_NOCRIT_PRE_() + me->free_head = fb_next; // set the head to the next free block + QS_BEGIN_PRE_(QS_QF_MPOOL_GET, qs_id) + QS_TIME_PRE_(); // timestamp + QS_OBJ_PRE_(me); // this memory pool + QS_MPC_PRE_(me->nFree); // # free blocks in the pool + QS_MPC_PRE_(me->nMin); // min # free blocks ever in the pool + QS_END_PRE_() } - /* don't have enough free blocks at this point */ - else { + else { // don't have enough free blocks at this point fb = (QFreeBlock *)0; - QS_BEGIN_NOCRIT_PRE_(QS_QF_MPOOL_GET_ATTEMPT, qs_id) - QS_TIME_PRE_(); /* timestamp */ - QS_OBJ_PRE_(me->start); /* the memory managed by this pool */ - QS_MPC_PRE_(me->nFree); /* # free blocks in the pool */ - QS_MPC_PRE_(margin); /* the requested margin */ - QS_END_NOCRIT_PRE_() + QS_BEGIN_PRE_(QS_QF_MPOOL_GET_ATTEMPT, qs_id) + QS_TIME_PRE_(); // timestamp + QS_OBJ_PRE_(me); // this memory pool + QS_MPC_PRE_(me->nFree); // # free blocks in the pool + QS_MPC_PRE_(margin); // the requested margin + QS_END_PRE_() } portEXIT_CRITICAL_ISR(&QF_esp32mux); - return fb; /* return the pointer to memory block or NULL to the caller */ + return fb; // return the block or NULL pointer to the caller } +//============================================================================ +// NOTE3: +// The event posting to FreeRTOS message queue occurs OUTSIDE critical section, +// which means that the remaining margin of available slots in the queue +// cannot be guaranteed. The problem is that interrupts and other tasks can +// preempt the event posting after checking the margin, but before actually +// posting the event to the queue. +// + diff --git a/ports/esp-idf/qf_port.h b/ports/esp-idf/qf_port.h deleted file mode 100644 index 301c3861..00000000 --- a/ports/esp-idf/qf_port.h +++ /dev/null @@ -1,276 +0,0 @@ -/*============================================================================ -* QP/C Real-Time Embedded Framework (RTEF) -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2022-12-27 -* @version Last updated for: @ref qpc_7_2_0 -* -* @file -* @brief "Experimental" QF/C port to Espressif ESP-IDF (version 4.x) -*/ -#ifndef QF_PORT_H -#define QF_PORT_H - -/* FreeRTOS-ESP32 event queue and thread types, see NOTE0 */ -#define QF_EQUEUE_TYPE QueueHandle_t -#define QF_OS_OBJECT_TYPE StaticQueue_t -#define QF_THREAD_TYPE StaticTask_t - -/* The maximum number of active objects in the application, see NOTE1 */ -#define QF_MAX_ACTIVE configMAX_PRIORITIES - -/* QF interrupt disabling for FreeRTOS-ESP32 (task level), see NOTE2 */ -#define QF_INT_DISABLE() portENTER_CRITICAL(&QF_esp32mux) -#define QF_INT_ENABLE() portEXIT_CRITICAL(&QF_esp32mux) - -/* QF critical section for FreeRTOS-ESP32 (task level), see NOTE2 */ -/* #define QF_CRIT_STAT_TYPE not defined */ -#define QF_CRIT_ENTRY(dummy) portENTER_CRITICAL(&QF_esp32mux) -#define QF_CRIT_EXIT(dummy) portEXIT_CRITICAL(&QF_esp32mux) - -#include "freertos/FreeRTOS.h" /* FreeRTOS master include file, see NOTE3 */ -#include "freertos/task.h" /* FreeRTOS task management */ -#include "freertos/queue.h" /* FreeRTOS queue management */ - -#include "qep_port.h" /* QEP port */ -#include "qequeue.h" /* this QP port uses the native QF event queue */ -#include "qmpool.h" /* this QP port uses the native QF memory pool */ -#include "qf.h" /* QF platform-independent public interface */ - -/* global spinlock "mutex" for all critical sections in QF (see NOTE4) */ -extern PRIVILEGED_DATA portMUX_TYPE QF_esp32mux; - -#if defined( CONFIG_QPC_PINNED_TO_CORE_0 ) - #define QPC_CPU_NUM PRO_CPU_NUM -#elif defined( CONFIG_QPC_PINNED_TO_CORE_1 ) - #define QPC_CPU_NUM APP_CPU_NUM -#else - /* Defaults to APP_CPU */ - #define QPC_CPU_NUM APP_CPU_NUM -#endif - -/* the "FromISR" versions of the QF APIs, see NOTE3 */ -#ifdef Q_SPY - -#define QACTIVE_POST_FROM_ISR(me_, e_, pxHigherPrioTaskWoken_, sender_) \ - ((void)QActive_postFromISR_((me_), (e_), QF_NO_MARGIN, \ - (pxHigherPrioTaskWoken_), (sender_))) - -#define QACTIVE_POST_X_FROM_ISR(me_, e_, margin_, \ - pxHigherPrioTaskWoken_, sender_) \ - (QActive_postFromISR_((me_), (e_), (margin_), \ - (pxHigherPrioTaskWoken_), (sender_))) - -#define QACTIVE_PUBLISH_FROM_ISR(e_, pxHigherPrioTaskWoken_, sender_) \ - (QActive_publishFromISR_((e_), (pxHigherPrioTaskWoken_), \ - (void const *)(sender_))) - -#define QTIMEEVT_TICK_FROM_ISR(tickRate_, pxHigherPrioTaskWoken_, sender_) \ - (QTimeEvt_tickFromISR_((tickRate_), (pxHigherPrioTaskWoken_), (sender_))) - -#else /* ndef Q_SPY */ - -#define QACTIVE_POST_FROM_ISR(me_, e_, pxHigherPrioTaskWoken_, dummy) \ - ((void)QActive_postFromISR_((me_), (e_), QF_NO_MARGIN, \ - (pxHigherPrioTaskWoken_), (void *)0)) - -#define QACTIVE_POST_X_FROM_ISR(me_, e_, margin_, \ - pxHigherPrioTaskWoken_, dummy) \ - (QActive_postFromISR_((me_), (e_), (margin_), \ - (pxHigherPrioTaskWoken_), (void *)0)) - -#define QACTIVE_PUBLISH_FROM_ISR(e_, pxHigherPrioTaskWoken_, dummy) \ - (QActive_publishFromISR_((e_), (pxHigherPrioTaskWoken_), \ - (void *)0)) - -#define QTIMEEVT_TICK_FROM_ISR(tickRate_, pxHigherPrioTaskWoken_, dummy) \ - (QTimeEvt_tickFromISR_((tickRate_), (pxHigherPrioTaskWoken_), (void *)0)) - -#endif /* Q_SPY */ - -/* this function only to be used through macros QACTIVE_POST_FROM_ISR() -* and QACTIVE_POST_X_FROM_ISR(). -*/ -bool IRAM_ATTR QActive_postFromISR_(QActive * const me, QEvt const * const e, - uint_fast16_t const margin, - BaseType_t * const pxHigherPriorityTaskWoken, - void const * const sender); - -void IRAM_ATTR QActive_publishFromISR_(QEvt const * const e, - BaseType_t * const pxHigherPriorityTaskWoken, - void const * const sender); - -void IRAM_ATTR QTimeEvt_tickFromISR_(uint_fast8_t const tickRate, - BaseType_t * const pxHigherPriorityTaskWoken, - void const * const sender); - -#define QF_TICK_FROM_ISR(pxHigherPrioTaskWoken_, sender_) \ - QTIMEEVT_TICK_FROM_ISR(0U, pxHigherPrioTaskWoken_, sender_) - -#ifdef Q_EVT_CTOR /* Shall the ctor for the ::QEvt class be provided? */ - - #define Q_NEW_FROM_ISR(evtT_, sig_, ...) \ - (evtT_##_ctor((evtT_ *)QF_newXFromISR_(sizeof(evtT_), \ - QF_NO_MARGIN, (sig_)), (sig_), ##__VA_ARGS__)) - - #define Q_NEW_X_FROM_ISR(e_, evtT_, margin_, sig_, ...) do { \ - (e_) = (evtT_ *)QF_newXFromISR_(sizeof(evtT_), \ - (margin_), (sig_)); \ - if ((e_) != (evtT_ *)0) { \ - evtT_##_ctor((e_), (sig_), ##__VA_ARGS__); \ - } \ - } while (false) - -#else - - #define Q_NEW_FROM_ISR(evtT_, sig_) \ - ((evtT_ *)QF_newXFromISR_((uint_fast16_t)sizeof(evtT_), \ - QF_NO_MARGIN, (sig_))) - - #define Q_NEW_X_FROM_ISR(e_, evtT_, margin_, sig_) ((e_) = \ - (evtT_ *)QF_newXFromISR_((uint_fast16_t)sizeof(evtT_), \ - (margin_), (sig_))) - -#endif /* Q_EVT_CTOR */ - -void QF_gcFromISR(QEvt const * const e); - -/* this function only to be used through macros Q_NEW_FROM_ISR() and -* Q_NEW_X_FROM_ISR(). -*/ -QEvt *QF_newXFromISR_(uint_fast16_t const evtSize, - uint_fast16_t const margin, enum_t const sig); - -void *QMPool_getFromISR(QMPool * const me, uint_fast16_t const margin, - uint_fast8_t const qs_id); -void QMPool_putFromISR(QMPool * const me, void *b, uint_fast8_t const qs_id); - -enum FreeRTOS_TaskAttrs { - TASK_NAME_ATTR -}; - -/* FreeRTOS hooks prototypes (not provided by FreeRTOS) */ -#if (configUSE_IDLE_HOOK > 0) - void vApplicationIdleHook(void); -#endif -#if (configUSE_TICK_HOOK > 0) - void vApplicationTickHook(void); -#endif -#if (configCHECK_FOR_STACK_OVERFLOW > 0) - void vApplicationStackOverflowHook(TaskHandle_t xTask, char *pcTaskName); -#endif -#if (configSUPPORT_STATIC_ALLOCATION > 0) - void vApplicationGetIdleTaskMemory( StaticTask_t **ppxIdleTaskTCBBuffer, - StackType_t **ppxIdleTaskStackBuffer, - uint32_t *pulIdleTaskStackSize ); -#endif - -/***************************************************************************** -* interface used only inside QF, but not in applications -*/ -#ifdef QP_IMPL - #define FREERTOS_TASK_PRIO(qp_prio_) \ - ((UBaseType_t)((qp_prio_) + tskIDLE_PRIORITY)) - - /* FreeRTOS scheduler locking for QF_publish_() (task context only) */ - #define QF_SCHED_STAT_ \ - UBaseType_t curr_prio; \ - TaskHandle_t curr_task; - #define QF_SCHED_LOCK_(prio_) do { \ - curr_task = xTaskGetCurrentTaskHandle(); \ - curr_prio = uxTaskPriorityGet(curr_task); \ - if (FREERTOS_TASK_PRIO(prio_) > curr_prio) { \ - vTaskPrioritySet(curr_task, FREERTOS_TASK_PRIO(prio_));\ - } \ - else { \ - curr_prio = tskIDLE_PRIORITY; \ - } \ - } while (0) - - #define QF_SCHED_UNLOCK_() \ - if (curr_prio != tskIDLE_PRIORITY) { \ - vTaskPrioritySet(curr_task, curr_prio); \ - } else ((void)0) - - /* native QF event pool operations */ - #define QF_EPOOL_TYPE_ QMPool - #define QF_EPOOL_INIT_(p_, poolSto_, poolSize_, evtSize_) \ - (QMPool_init(&(p_), (poolSto_), (poolSize_), (evtSize_))) - #define QF_EPOOL_EVENT_SIZE_(p_) ((uint_fast16_t)(p_).blockSize) - #define QF_EPOOL_GET_(p_, e_, m_, qs_id_) \ - ((e_) = (QEvt *)QMPool_get(&(p_), (m_), (qs_id_))) - #define QF_EPOOL_PUT_(p_, e_, qs_id_) \ - (QMPool_put(&(p_), (e_), (qs_id_))) - -#endif /* ifdef QP_IMPL */ - -/***************************************************************************** -* NOTE0: -* This is the "experimental" port to the [Espressif ESP-IDF][1] -* IoT Framework, which is loosely based on the [FreeRTOS kernel][2]. -* -* "Experimental" means that the port has not been thouroughly tested at -* Quantum Leaps and no working examples are provided. -* -* The [Espressif ESP-IDF][1] is based on a significantly changed version -* of the FreeRTOS kernel developed by Espressif to support the ESP32 -* multi-core CPUs (see [ESP-IDF][1]). -* -* The Espressif version of FreeRTOS is __NOT__ compatible with the baseline -* FreeRTOS and it needs to be treated as a separate RTOS kernel. -* According to the comments in the Espressif source code, FreeRTOS-ESP-IDF -* is based on FreeRTOS V8.2.0, but apparently FreeRTOS-ESP-IDF has been -* updated with the newer features introduced to the original FreeRTOS in the -* later versions. For example, FreeRTOS-ESP32 supports the "static allocation", -* first introduced in baseline FreeRTOS V9.x. This QP port to FreeRTOS-ESP-IDF -* takes advantage of the "static allocation". -* -* [1]: https://www.espressif.com/en/products/sdks/esp-idf -* [2]: https://freertos.org -* -* NOTE1: -* The maximum number of active objects QF_MAX_ACTIVE cannot exceed the number -* of FreeRTOS priorities (configMAX_PRIORITIES) because each QP active object -* requires a unique priority level. This port assumes that configMAX_PRIORITIES -* is below the QP limit of 64, inclusive (QP framework will assert if -* QF_MAX_ACTIVE exceeds the limit of 64). -* -* NOTE2: -* The critical section definition applies only to the FreeRTOS "task level" -* APIs. The "FromISR" APIs are defined separately. -* -* NOTE3: -* The design of FreeRTOS requires using different APIs inside the ISRs -* (the "FromISR" variant) than at the task level. Accordingly, this port -* provides the "FromISR" variants for QP functions and "FROM_ISR" variants -* for QP macros to be used inside ISRs. ONLY THESE "FROM_ISR" VARIANTS -* ARE ALLOWED INSIDE ISRs AND CALLING THE TASK-LEVEL APIs IS AN ERROR. - -* NOTE4: -* This QF port to FreeRTOS-ESP32 uses the FreeRTOS-ESP32 spin lock "mutex", -* similar to the internal implementation of FreeRTOS-ESP32 (see tasks.c). -* However, the QF port uses its own "mutex" object QF_esp32mux. -*/ - -#endif /* QF_PORT_H */ diff --git a/ports/esp-idf/qp_port.h b/ports/esp-idf/qp_port.h new file mode 100644 index 00000000..ed5f6667 --- /dev/null +++ b/ports/esp-idf/qp_port.h @@ -0,0 +1,269 @@ +//============================================================================ +// QP/C Real-Time Embedded Framework (RTEF) +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +//============================================================================ +//! @date Last updated on: 2023-09-07 +//! @version Last updated for: @ref qpc_7_3_0 +//! +//! @file +//! @brief QP/C port to Espressif ESP-IDF (version 4.x), Experimental, NOTE0 +//! +#ifndef QP_PORT_H_ +#define QP_PORT_H_ + +#include // Exact-width types. WG14/N843 C99 Standard +#include // Boolean type. WG14/N843 C99 Standard + +#ifdef QP_CONFIG +#include "qp_config.h" // external QP configuration +#endif + +// no-return function specifier (C11 Standard) +#define Q_NORETURN _Noreturn void + +// QActive event queue and thread types for Espressif ESP-IDF +#define QACTIVE_EQUEUE_TYPE QueueHandle_t +#define QACTIVE_OS_OBJ_TYPE StaticQueue_t +#define QACTIVE_THREAD_TYPE StaticTask_t + +// FreeRTOS requires the "FromISR" API in QP/C++ +#define QF_ISR_API 1 + +// QF interrupt disabling for FreeRTOS-ESP32 (task level), see NOTE2 +#define QF_INT_DISABLE() portENTER_CRITICAL(&QF_esp32mux) +#define QF_INT_ENABLE() portEXIT_CRITICAL(&QF_esp32mux) + +// QF critical section for FreeRTOS-ESP32 (task level), see NOTE2 +#define QF_CRIT_STAT +#define QF_CRIT_ENTRY() portENTER_CRITICAL(&QF_esp32mux) +#define QF_CRIT_EXIT() portEXIT_CRITICAL(&QF_esp32mux) + +// include files ------------------------------------------------------------- +#include "freertos/FreeRTOS.h" // FreeRTOS master include file, see NOTE3 +#include "freertos/task.h" // FreeRTOS task management +#include "freertos/queue.h" // FreeRTOS queue management + +#include "qequeue.h" // QP event queue (for deferring events) +#include "qmpool.h" // QP memory pool (for event pools) +#include "qp.h" // QP platform-independent public interface + +// global spinlock "mutex" for all critical sections in QF (see NOTE4) +extern PRIVILEGED_DATA portMUX_TYPE QF_esp32mux; + +#if defined( CONFIG_QPC_PINNED_TO_CORE_0 ) + #define QPC_CPU_NUM PRO_CPU_NUM +#elif defined( CONFIG_QPC_PINNED_TO_CORE_1 ) + #define QPC_CPU_NUM APP_CPU_NUM +#else + // Defaults to APP_CPU + #define QPC_CPU_NUM APP_CPU_NUM +#endif + +// the "FromISR" versions of the QF APIs, see NOTE3 +#ifdef Q_SPY + +#define QACTIVE_POST_FROM_ISR(me_, e_, pxHigherPrioTaskWoken_, sender_) \ + ((void)QActive_postFromISR_((me_), (e_), QF_NO_MARGIN, \ + (pxHigherPrioTaskWoken_), (sender_))) + +#define QACTIVE_POST_X_FROM_ISR(me_, e_, margin_, \ + pxHigherPrioTaskWoken_, sender_) \ + (QActive_postFromISR_((me_), (e_), (margin_), \ + (pxHigherPrioTaskWoken_), (sender_))) + +#define QACTIVE_PUBLISH_FROM_ISR(e_, pxHigherPrioTaskWoken_, sender_) \ + (QActive_publishFromISR_((e_), (pxHigherPrioTaskWoken_), \ + (void const *)(sender_))) + +#define QTIMEEVT_TICK_FROM_ISR(tickRate_, pxHigherPrioTaskWoken_, sender_) \ + (QTimeEvt_tickFromISR_((tickRate_), (pxHigherPrioTaskWoken_), (sender_))) + +#else // ndef Q_SPY + +#define QACTIVE_POST_FROM_ISR(me_, e_, pxHigherPrioTaskWoken_, dummy) \ + ((void)QActive_postFromISR_((me_), (e_), QF_NO_MARGIN, \ + (pxHigherPrioTaskWoken_), (void *)0)) + +#define QACTIVE_POST_X_FROM_ISR(me_, e_, margin_, \ + pxHigherPrioTaskWoken_, dummy) \ + (QActive_postFromISR_((me_), (e_), (margin_), \ + (pxHigherPrioTaskWoken_), (void *)0)) + +#define QACTIVE_PUBLISH_FROM_ISR(e_, pxHigherPrioTaskWoken_, dummy) \ + (QActive_publishFromISR_((e_), (pxHigherPrioTaskWoken_), \ + (void *)0)) + +#define QTIMEEVT_TICK_FROM_ISR(tickRate_, pxHigherPrioTaskWoken_, dummy) \ + (QTimeEvt_tickFromISR_((tickRate_), (pxHigherPrioTaskWoken_), (void *)0)) + +#endif // Q_SPY + +bool IRAM_ATTR QActive_postFromISR_(QActive * const me, QEvt const * const e, + uint_fast16_t const margin, + BaseType_t * const pxHigherPriorityTaskWoken, + void const * const sender); + +void IRAM_ATTR QActive_publishFromISR_(QEvt const * const e, + BaseType_t * const pxHigherPriorityTaskWoken, + void const * const sender); + +void IRAM_ATTR QTimeEvt_tickFromISR_(uint_fast8_t const tickRate, + BaseType_t * const pxHigherPriorityTaskWoken, + void const * const sender); + +#define QF_TICK_FROM_ISR(pxHigherPrioTaskWoken_, sender_) \ + QTIMEEVT_TICK_FROM_ISR(0U, pxHigherPrioTaskWoken_, sender_) + +#ifdef QEVT_DYN_CTOR // Shall the ctor for the ::QEvt class be provided? + + #define Q_NEW_FROM_ISR(evtT_, sig_, ...) \ + (evtT_##_ctor((evtT_ *)QF_newXFromISR_(sizeof(evtT_), \ + QF_NO_MARGIN, (sig_)), __VA_ARGS__)) + + #define Q_NEW_X_FROM_ISR(e_, evtT_, margin_, sig_, ...) do { \ + (e_) = (evtT_ *)QF_newXFromISR_(sizeof(evtT_), \ + (margin_), (sig_)); \ + if ((e_) != (evtT_ *)0) { \ + evtT_##_ctor((e_), __VA_ARGS__); \ + } \ + } while (false) + +#else // no ::QEvt ctor + + #define Q_NEW_FROM_ISR(evtT_, sig_) \ + ((evtT_ *)QF_newXFromISR_((uint_fast16_t)sizeof(evtT_), \ + QF_NO_MARGIN, (sig_))) + + #define Q_NEW_X_FROM_ISR(e_, evtT_, margin_, sig_) ((e_) = \ + (evtT_ *)QF_newXFromISR_((uint_fast16_t)sizeof(evtT_), \ + (margin_), (sig_))) + +#endif // QEVT_DYN_CTOR + +void QF_gcFromISR(QEvt const * const e); + +QEvt *QF_newXFromISR_(uint_fast16_t const evtSize, + uint_fast16_t const margin, enum_t const sig); + +void *QMPool_getFromISR(QMPool * const me, uint_fast16_t const margin, + uint_fast8_t const qs_id); +void QMPool_putFromISR(QMPool * const me, void *block, + uint_fast8_t const qs_id); + +enum FreeRTOS_TaskAttrs { + TASK_NAME_ATTR +}; + +// FreeRTOS hooks prototypes (not provided by FreeRTOS) +#if (configUSE_IDLE_HOOK > 0) + void vApplicationIdleHook(void); +#endif +#if (configUSE_TICK_HOOK > 0) + void vApplicationTickHook(void); +#endif +#if (configCHECK_FOR_STACK_OVERFLOW > 0) + void vApplicationStackOverflowHook(TaskHandle_t xTask, char *pcTaskName); +#endif +#if (configSUPPORT_STATIC_ALLOCATION > 0) + void vApplicationGetIdleTaskMemory(StaticTask_t **ppxIdleTaskTCBBuffer, + StackType_t **ppxIdleTaskStackBuffer, + uint32_t *pulIdleTaskStackSize); +#endif + +//============================================================================ +// interface used only inside QF, but not in applications + +#ifdef QP_IMPL + #define FREERTOS_TASK_PRIO(qp_prio_) \ + ((UBaseType_t)((qp_prio_) + tskIDLE_PRIORITY)) + + // FreeRTOS scheduler locking for QF_publish_() (task context only) + #define QF_SCHED_STAT_ + #define QF_SCHED_LOCK_(prio_) (vTaskSuspendAll()) + #define QF_SCHED_UNLOCK_() ((void)xTaskResumeAll()) + + // native QF event pool customization + #define QF_EPOOL_TYPE_ QMPool + #define QF_EPOOL_INIT_(p_, poolSto_, poolSize_, evtSize_) \ + (QMPool_init(&(p_), (poolSto_), (poolSize_), (evtSize_))) + #define QF_EPOOL_EVENT_SIZE_(p_) ((uint_fast16_t)(p_).blockSize) + #define QF_EPOOL_GET_(p_, e_, m_, qs_id_) \ + ((e_) = (QEvt *)QMPool_get(&(p_), (m_), (qs_id_))) + #define QF_EPOOL_PUT_(p_, e_, qs_id_) \ + (QMPool_put(&(p_), (e_), (qs_id_))) + +#endif // QP_IMPL + +//============================================================================ +// NOTE0: +// This is the "experimental" port to the [Espressif ESP-IDF][1] +// IoT Framework, which is loosely based on the [FreeRTOS kernel][2]. +// +// "Experimental" means that the port has not been thouroughly tested at +// Quantum Leaps and no working examples are provided. +// +// The [Espressif ESP-IDF][1] is based on a significantly changed version +// of the FreeRTOS kernel developed by Espressif to support the ESP32 +// multi-core CPUs (see [ESP-IDF][1]). +// +// The Espressif version of FreeRTOS is **NOT** compatible with the baseline +// FreeRTOS and it needs to be treated as a separate RTOS kernel. +// According to the comments in the Espressif source code, FreeRTOS-ESP-IDF +// is based on FreeRTOS V8.2.0, but apparently FreeRTOS-ESP-IDF has been +// updated with the newer features introduced to the original FreeRTOS in the +// later versions. For example, FreeRTOS-ESP32 supports the "static allocation", +// first introduced in baseline FreeRTOS V9.x. This QP port to FreeRTOS-ESP-IDF +// takes advantage of the "static allocation". +// +// [1]: https://www.espressif.com/en/products/sdks/esp-idf +// [2]: https://freertos.org +// +// NOTE1: +// The maximum number of active objects QF_MAX_ACTIVE can be increased to 64, +// inclusive, but it can be reduced to save some memory. Also, the number of +// active objects cannot exceed the number of FreeRTOS task priorities, +// because each QP active object requires a unique priority level. +// +// NOTE2: +// The critical section definition applies only to the FreeRTOS "task level" +// APIs. The "FromISR" APIs are defined separately. +// +// NOTE3: +// The design of FreeRTOS requires using different APIs inside the ISRs +// (the "FromISR" variant) than at the task level. Accordingly, this port +// provides the "FromISR" variants for QP functions and "FROM_ISR" variants +// for QP macros to be used inside ISRs. ONLY THESE "FROM_ISR" VARIANTS +// ARE ALLOWED INSIDE ISRs AND CALLING THE TASK-LEVEL APIs IS AN ERROR. +// +// NOTE4: +// This QF port to FreeRTOS-ESP32 uses the FreeRTOS-ESP32 spin lock "mutex", +// similar to the internal implementation of FreeRTOS-ESP32 (see tasks.c). +// However, the QF port uses its own "mutex" object QF_esp32mux. + +#endif // QP_PORT_H_ + diff --git a/ports/esp-idf/qs_port.h b/ports/esp-idf/qs_port.h index e8b00882..206b7e4c 100644 --- a/ports/esp-idf/qs_port.h +++ b/ports/esp-idf/qs_port.h @@ -1,60 +1,56 @@ -/*============================================================================ -* QP/C Real-Time Embedded Framework (RTEF) -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2022-06-12 -* @version Last updated for: @ref qpc_7_0_1 -* -* @file -* @brief QS/C port to a 32-bit CPU and a generic C99 compiler. -* @description -* This is an example of a QP/C port with the documentation for the -* configuration macros and includes. -*/ -#ifndef QS_PORT_H -#define QS_PORT_H +//============================================================================ +// QP/C Real-Time Embedded Framework (RTEF) +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +//============================================================================ +//! @date Last updated on: 2023-08-16 +//! @version Last updated for: @ref qpc_7_3_0 +//! +//! @file +//! @brief QS/C port to a 32-bit CPU and a generic C11 compiler. -/* QS time-stamp size in bytes */ -#define QS_TIME_SIZE 4 +#ifndef QS_PORT_H_ +#define QS_PORT_H_ -/* object pointer size in bytes */ -#define QS_OBJ_PTR_SIZE 4 +// QS time-stamp size in bytes +#define QS_TIME_SIZE 4U -/* function pointer size in bytes */ -#define QS_FUN_PTR_SIZE 4 +// object pointer size in bytes +#define QS_OBJ_PTR_SIZE 4U -/*==========================================================================*/ -/* NOTE: QS might be used with or without other QP components, in which -* case the separate definitions of the macros QF_CRIT_STAT_TYPE, -* QF_CRIT_ENTRY, and QF_CRIT_EXIT are needed. In this port QS is configured -* to be used with the other QP component, by simply including "qf_port.h" -* *before* "qs.h". -*/ -#ifndef QF_PORT_H -#include "qf_port.h" /* use QS with QF */ +// function pointer size in bytes +#define QS_FUN_PTR_SIZE 4U + +//============================================================================ +// NOTE: QS might be used with or without other QP components, in which +// case the separate definitions of the macros QF_CRIT_STAT, QF_CRIT_ENTRY(), +// and QF_CRIT_EXIT() are needed. In this port QS is configured to be used +// with the other QP component, by simply including "qp_port.h" +//*before* "qs.h". +#ifndef QP_PORT_H_ +#include "qp_port.h" // use QS with QF #endif -#include "qs.h" /* QS platform-independent public interface */ +#include "qs.h" // QS platform-independent public interface + +#endif // QS_PORT_H_ -#endif /* QS_PORT_H */ diff --git a/ports/freertos/qep_port.h b/ports/freertos/qep_port.h deleted file mode 100644 index be4fa2d4..00000000 --- a/ports/freertos/qep_port.h +++ /dev/null @@ -1,40 +0,0 @@ -/*============================================================================ -* QP/C Real-Time Embedded Framework (RTEF) -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2022-06-03 -* @version Last updated for: @ref qpc_7_0_1 -* -* @file -* @brief QEP/C port, generic C99 compiler -*/ -#ifndef QEP_PORT_H -#define QEP_PORT_H - -#include /* Exact-width types. WG14/N843 C99 Standard */ -#include /* Boolean type. WG14/N843 C99 Standard */ - -#include "qep.h" /* QEP platform-independent public interface */ - -#endif /* QEP_PORT_H */ diff --git a/ports/freertos/qf_port.c b/ports/freertos/qf_port.c index 5a0037ee..5d9bbe61 100644 --- a/ports/freertos/qf_port.c +++ b/ports/freertos/qf_port.c @@ -1,44 +1,43 @@ -/*============================================================================ -* QP/C Real-Time Embedded Framework (RTEF) -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2022-10-18 -* @version Last updated for: @ref qpc_7_1_3 -* -* @file -* @brief QF/C port to FreeRTOS 10.x -*/ -#define QP_IMPL /* this is QP implementation */ -#include "qf_port.h" /* QF port */ -#include "qf_pkg.h" -#include "qassert.h" -#ifdef Q_SPY /* QS software tracing enabled? */ - #include "qs_port.h" /* QS port */ - #include "qs_pkg.h" /* QS package-scope internal interface */ +//============================================================================ +// QP/C Real-Time Embedded Framework (RTEF) +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +//============================================================================ +//! @date Last updated on: 2023-09-10 +//! @version Last updated for: @ref qpc_7_3_0 +//! +//! @file +//! @brief QF/C port to FreeRTOS 10.x, generic C11 compiler + +#define QP_IMPL // this is QP implementation +#include "qp_port.h" // QP port +#include "qp_pkg.h" // QP package-level interface +#include "qsafe.h" // QP Functional Safety (FuSa) Subsystem +#ifdef Q_SPY // QS software tracing enabled? + #include "qs_port.h" // QS port + #include "qs_pkg.h" // QS package-scope internal interface #else - #include "qs_dummy.h" /* disable the QS software tracing */ -#endif /* Q_SPY */ + #include "qs_dummy.h" // disable the QS software tracing +#endif // Q_SPY Q_DEFINE_THIS_MODULE("qf_port") @@ -50,233 +49,279 @@ Q_DEFINE_THIS_MODULE("qf_port") #error "FreeRTOS configMAX_PRIORITIES must not be less than QF_MAX_ACTIVE" #endif -/* Local objects -----------------------------------------------------------*/ -static void task_function(void *pvParameters); /* FreeRTOS task signature */ +// Local objects ------------------------------------------------------------- +static void task_function(void *pvParameters); // FreeRTOS task signature -/* The following macro provides the number of free slots in the FreeRTOS -* queue. -* -* NOTE1: -* The official FreeRTOS API uxQueueSpacesAvailable() is not used -* here, because that API uses task-level critical section internally. -* Instead, the free slots calculation happens here in already -* established critical section. Unfortunately, the bizarre "information -* obfuscating" policy of FreeRTOS (incorrectly called "information -* hiding") forces the use of the StaticQueue_t with "dummy" members. -* This could potentially break in the future releases of FreeRTOS. -* -* Currently, the correspondence between xQUEUE and StaticQueue_t -* is as follows (see queue.c and FreeRTOS.h, respectively): -* -* xQUEUE.uxMessagesWaiting == StaticQueue_t.uxDummy4[0]; -* xQUEUE.uxLength == StaticQueue_t.uxDummy4[1]; -*/ +// The following macro provides the number of free slots in the FreeRTOS +// queue. +// +// NOTE1: +// The official FreeRTOS API uxQueueSpacesAvailable() is not used +// here, because that API uses task-level critical section internally. +// Instead, the free slots calculation happens here in already +// established critical section. Unfortunately, the bizarre "information +// obfuscating" policy of FreeRTOS (incorrectly called "information +// hiding") forces the use of the StaticQueue_t with "dummy" members. +// This could potentially break in the future releases of FreeRTOS. +// +// Currently, the correspondence between xQUEUE and StaticQueue_t +// is as follows (see queue.c and FreeRTOS.h, respectively): +// +// xQUEUE.uxMessagesWaiting == StaticQueue_t.uxDummy4[0]; +// xQUEUE.uxLength == StaticQueue_t.uxDummy4[1]; +// #define FREERTOS_QUEUE_GET_FREE(me_) \ ((me_)->osObject.uxDummy4[1] - (me_)->osObject.uxDummy4[0]) -/*==========================================================================*/ +//============================================================================ void QF_init(void) { - /* empty for FreeRTOS */ + // empty for FreeRTOS } -/*..........................................................................*/ +//............................................................................ int_t QF_run(void) { - QS_CRIT_STAT_ + QF_onStartup(); // the startup callback (configure/enable interrupts) - QF_onStartup(); /* the startup callback (configure/enable interrupts) */ - - /* produce the QS_QF_RUN trace record */ + // produce the QS_QF_RUN trace record + QF_CRIT_STAT + QF_CRIT_ENTRY(); QS_BEGIN_PRE_(QS_QF_RUN, 0U) QS_END_PRE_() + QF_CRIT_EXIT(); - vTaskStartScheduler(); /* start the FreeRTOS scheduler */ - Q_ERROR_ID(110); /* the FreeRTOS scheduler should never return */ - return 0; /* dummy return to make the compiler happy */ + vTaskStartScheduler(); // start the FreeRTOS scheduler + + QF_CRIT_ENTRY(); + Q_ERROR_INCRIT(110); // the FreeRTOS scheduler should never return + QF_CRIT_EXIT(); + + return 0; // dummy return to make the compiler happy } -/*..........................................................................*/ +//............................................................................ void QF_stop(void) { - QF_onCleanup(); /* cleanup callback */ + QF_onCleanup(); // cleanup callback } -/*..........................................................................*/ -static void task_function(void *pvParameters) { /* FreeRTOS task signature */ +//............................................................................ +static void task_function(void *pvParameters) { // FreeRTOS task signature QActive *act = (QActive *)pvParameters; - /* event-loop */ - for (;;) { /* for-ever */ - QEvt const *e = QActive_get_(act); - QHSM_DISPATCH(&act->super, e, act->prio); - QF_gc(e); /* check if the event is garbage, and collect it if so */ +#ifdef QACTIVE_CAN_STOP + while (act->eQueue != (QueueHandle_t)0) +#else + for (;;) // for-ever +#endif + { + QEvt const *e = QActive_get_(act); // wait for event + QASM_DISPATCH(&act->super, e, act->prio); // dispatch to the SM + QF_gc(e); // check if the event is garbage, and collect it if so } +#ifdef QACTIVE_CAN_STOP + QActive_unregister_(act); // remove this object from the framewrok + vTaskDelete((TaskHandle_t)0); // delete this FreeRTOS task +#endif } -/*..........................................................................*/ -void QActive_start_(QActive * const me, QPrioSpec const prioSpec, - QEvt const * * const qSto, uint_fast16_t const qLen, - void * const stkSto, uint_fast16_t const stkSize, - void const * const par) + +//............................................................................ +void QActive_start_(QActive * const me, + QPrioSpec const prioSpec, + QEvt const * * const qSto, + uint_fast16_t const qLen, + void * const stkSto, + uint_fast16_t const stkSize, + void const * const par) { - Q_REQUIRE_ID(200, - (qSto != (QEvt const **)0) /* queue storage must be provided */ - && (qLen > 0U) /* queue size must be provided */ - && (stkSto != (void *)0) /* stack storage must be provided */ - && (stkSize > 0U)); /* stack size must be provided */ + QF_CRIT_STAT + QF_CRIT_ENTRY(); + // precondition: + // - queue storage must be provided + // - queue size must be provided + // - stack storage must be provided + // - stack size must be provided + Q_REQUIRE_INCRIT(200, + (qSto != (QEvt const **)0) && (qLen > 0U) + && (stkSto != (void *)0) && (stkSize > 0U)); + QF_CRIT_EXIT(); - /* create FreeRTOS message queue */ + // create FreeRTOS message queue me->eQueue = xQueueCreateStatic( - (UBaseType_t)qLen, /* length of the queue */ - (UBaseType_t)sizeof(QEvt *), /* element size */ - (uint8_t *)qSto, /* storage buffer */ - &me->osObject); /* static queue buffer */ - Q_ASSERT_ID(210, me->eQueue != (QueueHandle_t)0); + (UBaseType_t)qLen, // length of the queue + (UBaseType_t)sizeof(QEvt *), // element size + (uint8_t *)qSto, // storage buffer + &me->osObject); // static queue buffer + QF_CRIT_ENTRY(); + Q_ASSERT_INCRIT(210, me->eQueue != (QueueHandle_t)0); + QF_CRIT_EXIT(); - me->prio = (uint8_t)(prioSpec & 0xFFU); /* QF-priority of the AO */ - me->pthre = (uint8_t)(prioSpec >> 8U); /* preemption-threshold */ - QActive_register_(me); /* register this AO */ + me->prio = (uint8_t)(prioSpec & 0xFFU); // QF-priority of the AO + me->pthre = 0U; // preemption-threshold (not used) + QActive_register_(me); // register this AO - QHSM_INIT(&me->super, par, me->prio); /* the top-most initial tran. */ - QS_FLUSH(); /* flush the QS trace buffer to the host */ + // top-most initial tran. (virtual call) + (*me->super.vptr->init)(&me->super, par, me->prio); + QS_FLUSH(); // flush the QS trace buffer to the host - /* task name provided by the user in QActive_setAttr() or default name */ + // task name provided by the user in QActive_setAttr() or default name char const *taskName = (me->thread.pxDummy1 != (void *)0) ? (char const *)me->thread.pxDummy1 : (char const *)"AO"; - /* statically create the FreeRTOS task for the AO */ - Q_ALLEGE_ID(220, - (TaskHandle_t)0 != xTaskCreateStatic( - &task_function, /* the task function */ - taskName , /* the name of the task */ - stkSize/sizeof(portSTACK_TYPE), /* stack length */ - (void *)me, /* the 'pvParameters' parameter */ - FREERTOS_TASK_PRIO(me->prio), /* FreeRTOS priority */ - (StackType_t *)stkSto, /* stack storage */ - &me->thread)); /* task buffer */ + // statically create the FreeRTOS task for the AO + TaskHandle_t task = xTaskCreateStatic( + &task_function, // the task function + taskName , // the name of the task + stkSize/sizeof(portSTACK_TYPE), // stack length + (void *)me, // the 'pvParameters' parameter + FREERTOS_TASK_PRIO(me->prio), // FreeRTOS priority + (StackType_t *)stkSto, // stack storage + &me->thread); // task buffer + + QF_CRIT_ENTRY(); + Q_ASSERT_INCRIT(220, task != (TaskHandle_t)0); + QF_CRIT_EXIT(); } -/*..........................................................................*/ +//............................................................................ +#ifdef QACTIVE_CAN_STOP +void QActive_stop(QActive * const me) { + QActive_unsubscribeAll(me); // unsubscribe from all events + me->eQueue = (QueueHandle_t)0; // stop the thread (see task_function()) +} +#endif +//............................................................................ void QActive_setAttr(QActive *const me, uint32_t attr1, void const *attr2) { - /* this function must be called before QACTIVE_START(), - * which implies that me->thread.pxDummy1 must not be used yet; - */ - Q_REQUIRE_ID(300, me->thread.pxDummy1 == (void *)0); + QF_CRIT_STAT + QF_CRIT_ENTRY(); + // this function must be called before QACTIVE_START(), + // which implies that me->thread.pxDummy1 must not be used yet; + Q_REQUIRE_INCRIT(300, me->thread.pxDummy1 == (void *)0); switch (attr1) { case TASK_NAME_ATTR: - /* temporarily store the name */ - me->thread.pxDummy1 = (void *)attr2; /* cast 'const' away */ + // temporarily store the name, cast 'const' away + me->thread.pxDummy1 = (void *)attr2; break; - /* ... */ + // ... } + QF_CRIT_EXIT(); } -/*==========================================================================*/ +//============================================================================ bool QActive_post_(QActive * const me, QEvt const * const e, uint_fast16_t const margin, void const * const sender) { - QF_CRIT_STAT_ - QF_CRIT_E_(); +#ifndef Q_SPY + Q_UNUSED_PAR(sender); +#endif - /* find out the number of free slots available in the queue */ + QF_CRIT_STAT + QF_CRIT_ENTRY(); + + // find the number of free slots available in the queue uint_fast16_t const nFree = (uint_fast16_t)FREERTOS_QUEUE_GET_FREE(me); bool status; if (margin == QF_NO_MARGIN) { if (nFree > 0U) { - status = true; /* can post */ + status = true; // can post } else { - status = false; /* cannot post */ - Q_ERROR_ID(510); /* must be able to post the event */ + status = false; // cannot post + Q_ERROR_INCRIT(510); // must be able to post the event } } else if (nFree > margin) { - status = true; /* can post */ + status = true; // can post } else { - status = false; /* cannot post */ + status = false; // cannot post } - if (status) { /* can post the event? */ + if (status) { // can post the event? - QS_BEGIN_NOCRIT_PRE_(QS_QF_ACTIVE_POST, me->prio) - QS_TIME_PRE_(); /* timestamp */ - QS_OBJ_PRE_(sender); /* the sender object */ - QS_SIG_PRE_(e->sig); /* the signal of the event */ - QS_OBJ_PRE_(me); /* this active object (recipient) */ - QS_2U8_PRE_(e->poolId_, e->refCtr_); /* pool Id & ref Count */ - QS_EQC_PRE_((QEQueueCtr)nFree); /* # free entries available */ - QS_EQC_PRE_(0U); /* min # free entries (unknown) */ - QS_END_NOCRIT_PRE_() + QS_BEGIN_PRE_(QS_QF_ACTIVE_POST, me->prio) + QS_TIME_PRE_(); // timestamp + QS_OBJ_PRE_(sender); // the sender object + QS_SIG_PRE_(e->sig); // the signal of the event + QS_OBJ_PRE_(me); // this active object (recipient) + QS_2U8_PRE_(QEvt_getPoolId_(e), e->refCtr_); // pool Id&ref Count + QS_EQC_PRE_((QEQueueCtr)nFree); // # free entries + QS_EQC_PRE_(0U); // min # free entries (unknown) + QS_END_PRE_() - if (e->poolId_ != 0U) { /* is it a pool event? */ - QEvt_refCtr_inc_(e); /* increment the reference counter */ + if (QEvt_getPoolId_(e) != 0U) { // is it a pool event? + QEvt_refCtr_inc_(e); // increment the reference counter } + QF_CRIT_EXIT(); - QF_CRIT_X_(); + BaseType_t err = xQueueSendToBack( + me->eQueue, (void const *)&e, (TickType_t)0); - /* posting to the FreeRTOS message queue must succeed, see NOTE3 */ - Q_ALLEGE_ID(520, - xQueueSend(me->eQueue, (void const *)&e, portMAX_DELAY) - == pdPASS); + // posting to the FreeRTOS message queue must succeed, see NOTE3 + QF_CRIT_ENTRY(); + Q_ASSERT_INCRIT(520, err == pdPASS); } else { - QS_BEGIN_NOCRIT_PRE_(QS_QF_ACTIVE_POST_ATTEMPT, me->prio) - QS_TIME_PRE_(); /* timestamp */ - QS_OBJ_PRE_(sender); /* the sender object */ - QS_SIG_PRE_(e->sig); /* the signal of the event */ - QS_OBJ_PRE_(me); /* this active object (recipient) */ - QS_2U8_PRE_(e->poolId_, e->refCtr_); /* pool Id & ref Count */ - QS_EQC_PRE_((QEQueueCtr)nFree); /* # free entries available */ - QS_EQC_PRE_(margin); /* margin requested */ - QS_END_NOCRIT_PRE_() - - QF_CRIT_X_(); - } + QS_BEGIN_PRE_(QS_QF_ACTIVE_POST_ATTEMPT, me->prio) + QS_TIME_PRE_(); // timestamp + QS_OBJ_PRE_(sender); // the sender object + QS_SIG_PRE_(e->sig); // the signal of the event + QS_OBJ_PRE_(me); // this active object (recipient) + QS_2U8_PRE_(QEvt_getPoolId_(e), e->refCtr_); // pool Id&ref Count + QS_EQC_PRE_((QEQueueCtr)nFree); // # free entries + QS_EQC_PRE_(margin); // margin requested + QS_END_PRE_() + } + QF_CRIT_EXIT(); return status; } -/*..........................................................................*/ +//............................................................................ void QActive_postLIFO_(QActive * const me, QEvt const * const e) { - QF_CRIT_STAT_ - QF_CRIT_E_(); + QF_CRIT_STAT + QF_CRIT_ENTRY(); - QS_BEGIN_NOCRIT_PRE_(QS_QF_ACTIVE_POST_LIFO, me->prio) - QS_TIME_PRE_(); /* timestamp */ - QS_SIG_PRE_(e->sig); /* the signal of this event */ - QS_OBJ_PRE_(me); /* this active object */ - QS_2U8_PRE_(e->poolId_, e->refCtr_); /* pool Id & ref Count */ - QS_EQC_PRE_((QEQueueCtr)FREERTOS_QUEUE_GET_FREE(me)); /* # free */ - QS_EQC_PRE_(0U); /* min # free entries (unknown) */ - QS_END_NOCRIT_PRE_() + QS_BEGIN_PRE_(QS_QF_ACTIVE_POST_LIFO, me->prio) + QS_TIME_PRE_(); // timestamp + QS_SIG_PRE_(e->sig); // the signal of this event + QS_OBJ_PRE_(me); // this active object + QS_2U8_PRE_(QEvt_getPoolId_(e), e->refCtr_); // pool Id&ref Count + QS_EQC_PRE_((QEQueueCtr)FREERTOS_QUEUE_GET_FREE(me)); // # free + QS_EQC_PRE_(0U); // min # free entries (unknown) + QS_END_PRE_() - if (e->poolId_ != 0U) { /* is it a pool event? */ - QEvt_refCtr_inc_(e); /* increment the reference counter */ + if (QEvt_getPoolId_(e) != 0U) { // is it a pool event? + QEvt_refCtr_inc_(e); // increment the reference counter } + QF_CRIT_EXIT(); - QF_CRIT_X_(); + BaseType_t err = xQueueSendToFront( + me->eQueue, (void const *)&e, (TickType_t)0); - /* LIFO posting to the FreeRTOS queue must succeed */ - Q_ALLEGE_ID(610, - xQueueSendToBack(me->eQueue, (void const *)&e, portMAX_DELAY) - == pdPASS); + // LIFO posting to the FreeRTOS queue must succeed, see NOTE3 + QF_CRIT_ENTRY(); + Q_ASSERT_INCRIT(610, err == pdPASS); + QF_CRIT_EXIT(); } -/*..........................................................................*/ +//............................................................................ QEvt const *QActive_get_(QActive * const me) { QEvt const *e; xQueueReceive(me->eQueue, (void *)&e, portMAX_DELAY); - QS_CRIT_STAT_ + QS_CRIT_STAT + QS_CRIT_ENTRY(); QS_BEGIN_PRE_(QS_QF_ACTIVE_GET, me->prio) - QS_TIME_PRE_(); /* timestamp */ - QS_SIG_PRE_(e->sig); /* the signal of this event */ - QS_OBJ_PRE_(me); /* this active object */ - QS_2U8_PRE_(e->poolId_, e->refCtr_); /* pool Id & ref Count */ - QS_EQC_PRE_((QEQueueCtr)FREERTOS_QUEUE_GET_FREE(me)); /* # free */ + QS_TIME_PRE_(); // timestamp + QS_SIG_PRE_(e->sig); // the signal of this event + QS_OBJ_PRE_(me); // this active object + QS_2U8_PRE_(QEvt_getPoolId_(e), e->refCtr_); // pool Id&ref Count + QS_EQC_PRE_((QEQueueCtr)FREERTOS_QUEUE_GET_FREE(me)); // # free QS_END_PRE_() + QS_CRIT_EXIT(); return e; } -/*==========================================================================*/ -/* The "FromISR" QP APIs for the FreeRTOS port... */ +//============================================================================ +// The "FromISR" QP APIs for the FreeRTOS port... bool QActive_postFromISR_(QActive * const me, QEvt const * const e, uint_fast16_t const margin, BaseType_t * const pxHigherPriorityTaskWoken, @@ -284,424 +329,454 @@ bool QActive_postFromISR_(QActive * const me, QEvt const * const e, { UBaseType_t uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); - /* find out the number of free slots in the queue */ + // find the number of free slots available in the queue uint_fast16_t const nFree = (uint_fast16_t)FREERTOS_QUEUE_GET_FREE(me); bool status; if (margin == QF_NO_MARGIN) { if (nFree > 0U) { - status = true; /* can post */ + status = true; // can post } else { - status = false; /* cannot post */ - Q_ERROR_ID(810); /* must be able to post the event */ + status = false; // cannot post + Q_ERROR_INCRIT(810); // must be able to post the event } } else if (nFree > margin) { - status = true; /* can post */ + status = true; // can post } else { - status = false; /* cannot post */ + status = false; // cannot post } - if (status) { /* can post the event? */ + if (status) { // can post the event? - QS_BEGIN_NOCRIT_PRE_(QS_QF_ACTIVE_POST, me->prio) - QS_TIME_PRE_(); /* timestamp */ - QS_OBJ_PRE_(sender); /* the sender object */ - QS_SIG_PRE_(e->sig); /* the signal of the event */ - QS_OBJ_PRE_(me); /* this active object (recipient) */ - QS_2U8_PRE_(e->poolId_, e->refCtr_); /* pool Id & ref Count */ - QS_EQC_PRE_(nFree); /* # free entries available */ - QS_EQC_PRE_(0U); /* min # free entries (unknown) */ - QS_END_NOCRIT_PRE_() + QS_BEGIN_PRE_(QS_QF_ACTIVE_POST, me->prio) + QS_TIME_PRE_(); // timestamp + QS_OBJ_PRE_(sender); // the sender object + QS_SIG_PRE_(e->sig); // the signal of the event + QS_OBJ_PRE_(me); // this active object (recipient) + QS_2U8_PRE_(QEvt_getPoolId_(e), e->refCtr_); // pool Id&ref Count + QS_EQC_PRE_(nFree); // # free entries available + QS_EQC_PRE_(0U); // min # free entries (unknown) + QS_END_PRE_() - if (e->poolId_ != 0U) { /* is it a pool event? */ - QEvt_refCtr_inc_(e); /* increment the reference counter */ + if (QEvt_getPoolId_(e) != 0U) { // is it a pool event? + QEvt_refCtr_inc_(e); // increment the reference counter } - portCLEAR_INTERRUPT_MASK_FROM_ISR(uxSavedInterruptStatus); - /* posting to the FreeRTOS message queue must succeed */ - Q_ALLEGE_ID(820, - xQueueSendFromISR(me->eQueue, (void const *)&e, - pxHigherPriorityTaskWoken) - == pdTRUE); + BaseType_t err = xQueueSendToBackFromISR(me->eQueue, + (void const *)&e, + pxHigherPriorityTaskWoken); + + // posting to the FreeRTOS message queue must succeed + uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); + Q_ASSERT_INCRIT(820, err == pdPASS); + portCLEAR_INTERRUPT_MASK_FROM_ISR(uxSavedInterruptStatus); } else { - QS_BEGIN_NOCRIT_PRE_(QS_QF_ACTIVE_POST_ATTEMPT, me->prio) - QS_TIME_PRE_(); /* timestamp */ - QS_OBJ_PRE_(sender); /* the sender object */ - QS_SIG_PRE_(e->sig); /* the signal of the event */ - QS_OBJ_PRE_(me); /* this active object (recipient) */ - QS_2U8_PRE_(e->poolId_, e->refCtr_); /* pool Id & ref Count */ - QS_EQC_PRE_(nFree); /* # free entries available */ - QS_EQC_PRE_(margin); /* margin requested */ - QS_END_NOCRIT_PRE_() - + QS_BEGIN_PRE_(QS_QF_ACTIVE_POST_ATTEMPT, me->prio) + QS_TIME_PRE_(); // timestamp + QS_OBJ_PRE_(sender); // the sender object + QS_SIG_PRE_(e->sig); // the signal of the event + QS_OBJ_PRE_(me); // this active object (recipient) + QS_2U8_PRE_(QEvt_getPoolId_(e), e->refCtr_); // pool Id&ref Count + QS_EQC_PRE_(nFree); // # free entries available + QS_EQC_PRE_(margin); // margin requested + QS_END_PRE_() portCLEAR_INTERRUPT_MASK_FROM_ISR(uxSavedInterruptStatus); - QF_gcFromISR(e); /* recycle the event to avoid a leak */ + QF_gcFromISR(e); // recycle the event to avoid a leak } return status; } -/*..........................................................................*/ +//............................................................................ void QActive_publishFromISR_(QEvt const * const e, - BaseType_t * const pxHigherPriorityTaskWoken, - void const * const sender) + BaseType_t * const pxHigherPriorityTaskWoken, + void const * const sender) { - /** @pre the published signal must be within the configured range */ - Q_REQUIRE_ID(500, e->sig < (QSignal)QActive_maxPubSignal_); + QSignal const sig = e->sig; UBaseType_t uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); - QS_BEGIN_NOCRIT_PRE_(QS_QF_PUBLISH, 0U) - QS_TIME_PRE_(); /* the timestamp */ - QS_OBJ_PRE_(sender); /* the sender object */ - QS_SIG_PRE_(e->sig); /* the signal of the event */ - QS_2U8_PRE_(e->poolId_, e->refCtr_);/* pool-Id & ref-Count */ - QS_END_NOCRIT_PRE_() + //! @pre the published signal must be within the configured range + Q_REQUIRE_INCRIT(500, sig < (QSignal)QActive_maxPubSignal_); + Q_REQUIRE_INCRIT(502, + QPSet_verify_(&QActive_subscrList_[sig].set, + &QActive_subscrList_[sig].set_dis)); - /* is it a dynamic event? */ - if (e->poolId_ != 0U) { - /* NOTE: The reference counter of a dynamic event is incremented to - * prevent premature recycling of the event while the multicasting - * is still in progress. At the end of the function, the garbage - * collector step (QF_gcFromISR()) decrements the reference counter and - * recycles the event if the counter drops to zero. This covers the - * case when the event was published without any subscribers. - */ + QS_BEGIN_PRE_(QS_QF_PUBLISH, 0U) + QS_TIME_PRE_(); // the timestamp + QS_OBJ_PRE_(sender); // the sender object + QS_SIG_PRE_(sig); // the signal of the event + QS_2U8_PRE_(QEvt_getPoolId_(e), e->refCtr_);// pool-Id & ref-Count + QS_END_PRE_() + + // is it a dynamic event? + if (QEvt_getPoolId_(e) != 0U) { + // NOTE: The reference counter of a dynamic event is incremented to + // prevent premature recycling of the event while the multicasting + // is still in progress. At the end of the function, the garbage + // collector step (QF_gcFromISR()) decrements the reference counter + // and recycles the event if the counter drops to zero. This covers + // the case when the event was published without any subscribers. QEvt_refCtr_inc_(e); } - /* make a local, modifiable copy of the subscriber list */ - QPSet subscrList = QActive_subscrList_[e->sig]; + // make a local, modifiable copy of the subscriber list + QPSet subscrSet = QActive_subscrList_[sig].set; portCLEAR_INTERRUPT_MASK_FROM_ISR(uxSavedInterruptStatus); - if (QPSet_notEmpty(&subscrList)) { /* any subscribers? */ - /* the highest-prio subscriber */ - uint_fast8_t p = QPSet_findMax(&subscrList); + if (QPSet_notEmpty(&subscrSet)) { // any subscribers? + // the highest-prio subscriber + uint_fast8_t p = QPSet_findMax(&subscrSet); - /* no need to lock the scheduler in the ISR context */ - do { /* loop over all subscribers */ - /* the prio of the AO must be registered with the framework */ - Q_ASSERT_ID(510, QActive_registry_[p] != (QActive *)0); + // no need to lock the scheduler in the ISR context + do { // loop over all subscribers + // the prio of the AO must be registered with the framework + uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); + Q_ASSERT_INCRIT(510, QActive_registry_[p] != (QActive *)0); + portCLEAR_INTERRUPT_MASK_FROM_ISR(uxSavedInterruptStatus); - /* QACTIVE_POST_FROM_ISR() asserts if the queue overflows */ + // QACTIVE_POST_FROM_ISR() asserts if the queue overflows QACTIVE_POST_FROM_ISR(QActive_registry_[p], e, pxHigherPriorityTaskWoken, sender); - QPSet_remove(&subscrList, p); /* remove the handled subscriber */ - if (QPSet_notEmpty(&subscrList)) { /* still more subscribers? */ - /* highest-prio subscriber */ - p = QPSet_findMax(&subscrList); + QPSet_remove(&subscrSet, p); // remove the handled subscriber + if (QPSet_notEmpty(&subscrSet)) { // still more subscribers? + p = QPSet_findMax(&subscrSet); // the highest-prio subscriber } else { - p = 0U; /* no more subscribers */ + p = 0U; // no more subscribers } } while (p != 0U); - /* no need to unlock the scheduler in the ISR context */ + // no need to unlock the scheduler in the ISR context } - /* The following garbage collection step decrements the reference counter - * and recycles the event if the counter drops to zero. This covers both - * cases when the event was published with or without any subscribers. - */ + // The following garbage collection step decrements the reference counter + // and recycles the event if the counter drops to zero. This covers both + // cases when the event was published with or without any subscribers. QF_gcFromISR(e); } -/*..........................................................................*/ +//............................................................................ void QTimeEvt_tickFromISR_(uint_fast8_t const tickRate, - BaseType_t * const pxHigherPriorityTaskWoken, - void const * const sender) + BaseType_t * const pxHigherPriorityTaskWoken, + void const * const sender) { - QTimeEvt *prev = &QTimeEvt_timeEvtHead_[tickRate]; - UBaseType_t uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); - QS_BEGIN_NOCRIT_PRE_(QS_QF_TICK, 0U) + QTimeEvt *prev = &QTimeEvt_timeEvtHead_[tickRate]; + + QS_BEGIN_PRE_(QS_QF_TICK, 0U) ++prev->ctr; - QS_TEC_PRE_(prev->ctr); /* tick ctr */ - QS_U8_PRE_(tickRate); /* tick rate */ - QS_END_NOCRIT_PRE_() + QS_TEC_PRE_(prev->ctr); // tick ctr + QS_U8_PRE_(tickRate); // tick rate + QS_END_PRE_() - /* scan the linked-list of time events at this rate... */ + // scan the linked-list of time events at this rate... for (;;) { - QTimeEvt *t = prev->next; /* advance down the time evt. list */ + QTimeEvt *t = prev->next; // advance down the time evt. list - /* end of the list? */ + // end of the list? if (t == (QTimeEvt *)0) { - /* any new time events armed since the last QTimeEvt_tick_()? */ + // any new time events armed since the last QTimeEvt_tick_()? if (QTimeEvt_timeEvtHead_[tickRate].act != (void *)0) { - /* sanity check */ - Q_ASSERT_ID(610, prev != (QTimeEvt *)0); + // sanity check + Q_ASSERT_INCRIT(610, prev != (QTimeEvt *)0); prev->next = (QTimeEvt *)QTimeEvt_timeEvtHead_[tickRate].act; QTimeEvt_timeEvtHead_[tickRate].act = (void *)0; - t = prev->next; /* switch to the new list */ + t = prev->next; // switch to the new list } else { - break; /* all currently armed time evts. processed */ + break; // all currently armed time evts. processed } } - /* time event scheduled for removal? */ + // time event scheduled for removal? if (t->ctr == 0U) { prev->next = t->next; - /* mark time event 't' as NOT linked */ + // mark time event 't' as NOT linked t->super.refCtr_ &= (uint8_t)(~QTE_IS_LINKED); - /* do NOT advance the prev pointer */ - /* exit crit. section to reduce latency */ + // do NOT advance the prev pointer + // exit crit. section to reduce latency portCLEAR_INTERRUPT_MASK_FROM_ISR(uxSavedInterruptStatus); } else { --t->ctr; - /* is time event about to expire? */ - if (t->ctr == (QTimeEvtCtr)0) { - QActive *act = (QActive *)t->act; /* temp. for volatile */ + // is time evt about to expire? + if (t->ctr == 0U) { + QActive *act = (QActive *)t->act; // temp. for volatile - /* periodic time evt? */ + // periodic time evt? if (t->interval != 0U) { - t->ctr = t->interval; /* rearm the time event */ - prev = t; /* advance to this time event */ + t->ctr = t->interval; // rearm the time event + prev = t; // advance to this time event } - /* one-shot time event: automatically disarm */ + // one-shot time event: automatically disarm else { prev->next = t->next; - /* mark time event 't' as NOT linked */ + // mark time event 't' as NOT linked t->super.refCtr_ &= (uint8_t)(~QTE_IS_LINKED); - /* do NOT advance the prev pointer */ + // do NOT advance the prev pointer - QS_BEGIN_NOCRIT_PRE_(QS_QF_TIMEEVT_AUTO_DISARM, act->prio) - QS_OBJ_PRE_(t); /* this time event object */ - QS_OBJ_PRE_(act); /* the target AO */ - QS_U8_PRE_(tickRate); /* tick rate */ - QS_END_NOCRIT_PRE_() + QS_BEGIN_PRE_(QS_QF_TIMEEVT_AUTO_DISARM, act->prio) + QS_OBJ_PRE_(t); // this time event object + QS_OBJ_PRE_(act); // the target AO + QS_U8_PRE_(tickRate); // tick rate + QS_END_PRE_() } - QS_BEGIN_NOCRIT_PRE_(QS_QF_TIMEEVT_POST, act->prio) - QS_TIME_PRE_(); /* timestamp */ - QS_OBJ_PRE_(t); /* the time event object */ - QS_SIG_PRE_(t->super.sig); /* signal of this time event */ - QS_OBJ_PRE_(act); /* the target AO */ - QS_U8_PRE_(tickRate); /* tick rate */ - QS_END_NOCRIT_PRE_() + QS_BEGIN_PRE_(QS_QF_TIMEEVT_POST, act->prio) + QS_TIME_PRE_(); // timestamp + QS_OBJ_PRE_(t); // the time event object + QS_SIG_PRE_(t->super.sig); // signal of time event + QS_OBJ_PRE_(act); // the target AO + QS_U8_PRE_(tickRate); // tick rate + QS_END_PRE_() - /* exit critical section before posting */ + // exit critical section before posting portCLEAR_INTERRUPT_MASK_FROM_ISR(uxSavedInterruptStatus); - /* QACTIVE_POST_FROM_ISR() asserts if the queue overflows */ + // QACTIVE_POST_FROM_ISR() asserts if the queue overflows QACTIVE_POST_FROM_ISR(act, &t->super, pxHigherPriorityTaskWoken, sender); } else { - prev = t; /* advance to this time event */ - /* exit crit. section to reduce latency */ + prev = t; // advance to this time event + // exit crit. section to reduce latency portCLEAR_INTERRUPT_MASK_FROM_ISR(uxSavedInterruptStatus); } } - /* re-enter crit. section to continue */ + // re-enter crit. section to continue uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); } portCLEAR_INTERRUPT_MASK_FROM_ISR(uxSavedInterruptStatus); } -/*..........................................................................*/ +//............................................................................ QEvt *QF_newXFromISR_(uint_fast16_t const evtSize, uint_fast16_t const margin, enum_t const sig) { - /* find the pool index that fits the requested event size ... */ + // find the poolId that fits the requested event size ... uint_fast8_t idx; - for (idx = 0U; idx < QF_maxPool_; ++idx) { - if (evtSize <= QF_EPOOL_EVENT_SIZE_(QF_ePool_[idx])) { + for (idx = 0U; idx < QF_priv_.maxPool_; ++idx) { + if (evtSize <= QF_EPOOL_EVENT_SIZE_(QF_priv_.ePool_[idx])) { break; } } - /* cannot run out of registered pools */ - Q_ASSERT_ID(710, idx < QF_maxPool_); + // cannot run out of registered pools + UBaseType_t uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); + Q_REQUIRE_INCRIT(700, idx < QF_priv_.maxPool_); + portCLEAR_INTERRUPT_MASK_FROM_ISR(uxSavedInterruptStatus); - /* get e -- platform-dependent */ + // get e -- platform-dependent #ifdef Q_SPY - QEvt *e = QMPool_getFromISR(&QF_ePool_[idx], + QEvt *e = QMPool_getFromISR(&QF_priv_.ePool_[idx], ((margin != QF_NO_MARGIN) ? margin : 0U), (uint_fast8_t)QS_EP_ID + idx + 1U); #else - QEvt *e = QMPool_getFromISR(&QF_ePool_[idx], + QEvt *e = QMPool_getFromISR(&QF_priv_.ePool_[idx], ((margin != QF_NO_MARGIN) ? margin : 0U), 0U); #endif - /* was e allocated correctly? */ + // was e allocated correctly? if (e != (QEvt *)0) { - e->sig = (QSignal)sig; /* set signal for this event */ - e->poolId_ = (uint8_t)(idx + 1U); /* store the pool ID */ - e->refCtr_ = 0U; /* set the reference counter to 0 */ + QEvt_ctor(e, sig); + e->evtTag_ = (uint8_t)(QEVT_MARKER | (idx + 1U)); // pool ID #ifdef Q_SPY - UBaseType_t uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); - QS_BEGIN_PRE_(QS_QF_NEW, (uint_fast8_t)QS_EP_ID + e->poolId_) - QS_TIME_PRE_(); /* timestamp */ - QS_EVS_PRE_(evtSize); /* the size of the event */ - QS_SIG_PRE_(sig); /* the signal of the event */ - QS_END_NOCRIT_PRE_() + uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); + QS_BEGIN_PRE_(QS_QF_NEW, + (uint_fast8_t)QS_EP_ID + idx + 1U) + QS_TIME_PRE_(); // timestamp + QS_EVS_PRE_(evtSize); // the size of the event + QS_SIG_PRE_(sig); // the signal of the event + QS_END_PRE_() portCLEAR_INTERRUPT_MASK_FROM_ISR(uxSavedInterruptStatus); -#endif /* Q_SPY */ +#endif // Q_SPY } - /* event cannot be allocated */ - else { - /* must tolerate bad alloc. */ - Q_ASSERT_ID(720, margin != QF_NO_MARGIN); + else { // event cannot be allocated + // must tolerate bad alloc. + uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); + Q_ASSERT_INCRIT(720, margin != QF_NO_MARGIN); + portCLEAR_INTERRUPT_MASK_FROM_ISR(uxSavedInterruptStatus); #ifdef Q_SPY - UBaseType_t uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); - QS_BEGIN_PRE_(QS_QF_NEW_ATTEMPT, (uint_fast8_t)QS_EP_ID + idx + 1U) - QS_TIME_PRE_(); /* timestamp */ - QS_EVS_PRE_(evtSize); /* the size of the event */ - QS_SIG_PRE_(sig); /* the signal of the event */ - QS_END_NOCRIT_PRE_() + uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); + QS_BEGIN_PRE_(QS_QF_NEW_ATTEMPT, + (uint_fast8_t)QS_EP_ID + idx + 1U) + QS_TIME_PRE_(); // timestamp + QS_EVS_PRE_(evtSize); // the size of the event + QS_SIG_PRE_(sig); // the signal of the event + QS_END_PRE_() portCLEAR_INTERRUPT_MASK_FROM_ISR(uxSavedInterruptStatus); -#endif /* Q_SPY */ +#endif // Q_SPY } - return e; /* can't be NULL if we can't tolerate bad allocation */ + return e; // can't be NULL if we can't tolerate bad allocation } -/*..........................................................................*/ +//............................................................................ void QF_gcFromISR(QEvt const * const e) { - - /* is it a dynamic event? */ - if (e->poolId_ != 0U) { + // is it a dynamic event? + if (QEvt_getPoolId_(e) != 0U) { UBaseType_t uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); - /* isn't this the last ref? */ + // isn't this the last ref? if (e->refCtr_ > 1U) { - QEvt_refCtr_dec_(e); /* decrements the ref counter */ + QEvt_refCtr_dec_(e); // decrement the ref counter - QS_BEGIN_NOCRIT_PRE_(QS_QF_GC_ATTEMPT, (uint_fast8_t)e->poolId_) - QS_TIME_PRE_(); /* timestamp */ - QS_SIG_PRE_(e->sig); /* the signal of the event */ - QS_2U8_PRE_(e->poolId_, e->refCtr_); /* pool Id & ref Count */ - QS_END_NOCRIT_PRE_() + QS_BEGIN_PRE_(QS_QF_GC_ATTEMPT, + (uint_fast8_t)QEvt_getPoolId_(e)) + QS_TIME_PRE_(); // timestamp + QS_SIG_PRE_(e->sig); // the signal of the event + QS_2U8_PRE_(QEvt_getPoolId_(e), e->refCtr_);//pool-Id&ref-Count + QS_END_PRE_() portCLEAR_INTERRUPT_MASK_FROM_ISR(uxSavedInterruptStatus); } - /* this is the last reference to this event, recycle it */ + // this is the last reference to this event, recycle it else { - uint_fast8_t idx = (uint_fast8_t)e->poolId_ - 1U; + uint_fast8_t idx = (uint_fast8_t)QEvt_getPoolId_(e) - 1U; - QS_BEGIN_NOCRIT_PRE_(QS_QF_GC, (uint_fast8_t)e->poolId_) - QS_TIME_PRE_(); /* timestamp */ - QS_SIG_PRE_(e->sig); /* the signal of the event */ - QS_2U8_PRE_(e->poolId_, e->refCtr_); /* pool Id & ref Count */ - QS_END_NOCRIT_PRE_() + QS_BEGIN_PRE_(QS_QF_GC, (uint_fast8_t)QEvt_getPoolId_(e)) + QS_TIME_PRE_(); // timestamp + QS_SIG_PRE_(e->sig); // the signal of the event + QS_2U8_PRE_(QEvt_getPoolId_(e), e->refCtr_);//pool-Id&ref-Count + QS_END_PRE_() + + // pool ID must be in range + Q_ASSERT_INCRIT(810, idx < QF_priv_.maxPool_); portCLEAR_INTERRUPT_MASK_FROM_ISR(uxSavedInterruptStatus); - /* pool ID must be in range */ - Q_ASSERT_ID(810, idx < QF_maxPool_); - #ifdef Q_SPY - /* cast 'const' away in (QEvt *)e is OK, - * because it's a pool event */ - QMPool_putFromISR(&QF_ePool_[idx], (QEvt *)e, - (uint_fast8_t)QS_EP_ID + e->poolId_); + // cast 'const' away in (QEvt *)e is OK because it's a pool event + QMPool_putFromISR(&QF_priv_.ePool_[idx], (QEvt *)e, + (uint_fast8_t)QS_EP_ID + QEvt_getPoolId_(e)); #else - QMPool_putFromISR(&QF_ePool_[idx], (QEvt *)e, 0U); + QMPool_putFromISR(&QF_priv_.ePool_[idx], (QEvt *)e, 0U); #endif } } } -/*..........................................................................*/ -void QMPool_putFromISR(QMPool * const me, void *b, - uint_fast8_t const qs_id) +//............................................................................ +void QMPool_putFromISR(QMPool * const me, void *block, + uint_fast8_t const qs_id) { - /** @pre # free blocks cannot exceed the total # blocks and - * the block pointer must be from this pool. - */ - Q_REQUIRE_ID(900, (me->nFree < me->nTot) - && (me->start <= b) && (b <= me->end)); +#ifndef Q_SPY + Q_UNUSED_PAR(qs_id); +#endif - (void)qs_id; /* unused parameter (outside Q_SPY build configuration) */ + QFreeBlock * const fb = (QFreeBlock *)block; UBaseType_t uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); - ((QFreeBlock *)b)->next = (QFreeBlock *)me->free_head;/* link into list */ - me->free_head = b; /* set as new head of the free list */ - ++me->nFree; /* one more free block in this pool */ + // precondition: + // - # free blocks cannot exceed the total # blocks and + // - the block pointer must be from this pool. + Q_REQUIRE_INCRIT(900, (me->nFree < me->nTot) + && (me->start <= fb) && (fb <= me->end)); - QS_BEGIN_NOCRIT_PRE_(QS_QF_MPOOL_PUT, qs_id) - QS_TIME_PRE_(); /* timestamp */ - QS_OBJ_PRE_(me->start); /* the memory managed by this pool */ - QS_MPC_PRE_(me->nFree); /* # free blocks in the pool */ - QS_END_NOCRIT_PRE_() + fb->next = me->free_head; // link into list +#ifndef Q_UNSAFE + fb->next_dis = (uintptr_t)(~Q_UINTPTR_CAST_(fb->next)); +#endif + + me->free_head = fb; // set as new head of the free list + ++me->nFree; // one more free block in this pool + + QS_BEGIN_PRE_(QS_QF_MPOOL_PUT, qs_id) + QS_TIME_PRE_(); // timestamp + QS_OBJ_PRE_(me); // this memory pool + QS_MPC_PRE_(me->nFree); // the number of free blocks in the pool + QS_END_PRE_() portCLEAR_INTERRUPT_MASK_FROM_ISR(uxSavedInterruptStatus); } -/*..........................................................................*/ +//............................................................................ void *QMPool_getFromISR(QMPool * const me, uint_fast16_t const margin, uint_fast8_t const qs_id) { - (void)qs_id; /* unused parameter (outside Q_SPY build configuration) */ +#ifndef Q_SPY + Q_UNUSED_PAR(qs_id); +#endif UBaseType_t uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); - /* have more free blocks than the requested margin? */ + // have more free blocks than the requested margin? QFreeBlock *fb; if (me->nFree > (QMPoolCtr)margin) { - fb = (QFreeBlock *)me->free_head; /* get a free block */ + fb = me->free_head; // get a free block - /* the pool has some free blocks, so a free block must be available */ - Q_ASSERT_ID(910, fb != (QFreeBlock *)0); + // the pool has some free blocks, so a free block must be available + Q_ASSERT_INCRIT(900, fb != (QFreeBlock *)0); - void *fb_next = fb->next; /* put volatile to a temporary to avoid UB */ + QFreeBlock * const fb_next = fb->next; // fast temporary to avoid UB - /* is the pool becoming empty? */ - --me->nFree; /* one less free block */ - if (me->nFree == (QMPoolCtr)0) { - /* pool is becoming empty, so the next free block must be NULL */ - Q_ASSERT_ID(920, fb_next == (QFreeBlock *)0); + // the free block must have integrity (duplicate inverse storage) + Q_ASSERT_INCRIT(902, Q_UINTPTR_CAST_(fb_next) + == (uintptr_t)~fb->next_dis); - me->nMin = (QMPoolCtr)0; /* remember that the pool got empty */ + // is the pool becoming empty? + --me->nFree; // one less free block + if (me->nFree == 0U) { + // pool is becoming empty, so the next free block must be NULL + Q_ASSERT_INCRIT(920, fb_next == (QFreeBlock *)0); + + me->nMin = 0U; // remember that the pool got empty } else { - /* pool is not empty, so the next free block must be in range - * - * NOTE: the next free block pointer can fall out of range - * when the client code writes past the memory block, thus - * corrupting the next block. - */ - Q_ASSERT_ID(930, (me->start <= fb_next) - && (fb_next <= me->end)); + // invariant + // The pool is not empty, so the next free-block pointer, + // so the next free block must be in range. + // + // NOTE: The next free block pointer can fall out of range + // when the client code writes past the memory block, thus + // corrupting the next block. + Q_ASSERT_INCRIT(930, + (me->start <= fb_next) && (fb_next <= me->end)); - /* is the number of free blocks the new minimum so far? */ + // is the number of free blocks the new minimum so far? if (me->nMin > me->nFree) { - me->nMin = me->nFree; /* remember the new minimum */ + me->nMin = me->nFree; // remember the new minimum } } - me->free_head = fb_next; /* set the head to the next free block */ - - QS_BEGIN_NOCRIT_PRE_(QS_QF_MPOOL_GET, qs_id) - QS_TIME_PRE_(); /* timestamp */ - QS_OBJ_PRE_(me->start); /* the memory managed by this pool */ - QS_MPC_PRE_(me->nFree); /* # free blocks in the pool */ - QS_MPC_PRE_(me->nMin); /* min # free blocks ever in the pool */ - QS_END_NOCRIT_PRE_() + me->free_head = fb_next; // set the head to the next free block + QS_BEGIN_PRE_(QS_QF_MPOOL_GET, qs_id) + QS_TIME_PRE_(); // timestamp + QS_OBJ_PRE_(me); // this memory pool + QS_MPC_PRE_(me->nFree); // # free blocks in the pool + QS_MPC_PRE_(me->nMin); // min # free blocks ever in the pool + QS_END_PRE_() } - /* don't have enough free blocks at this point */ - else { + else { // don't have enough free blocks at this point fb = (QFreeBlock *)0; - QS_BEGIN_NOCRIT_PRE_(QS_QF_MPOOL_GET_ATTEMPT, qs_id) - QS_TIME_PRE_(); /* timestamp */ - QS_OBJ_PRE_(me->start); /* the memory managed by this pool */ - QS_MPC_PRE_(me->nFree); /* # free blocks in the pool */ - QS_MPC_PRE_(margin); /* the requested margin */ - QS_END_NOCRIT_PRE_() + QS_BEGIN_PRE_(QS_QF_MPOOL_GET_ATTEMPT, qs_id) + QS_TIME_PRE_(); // timestamp + QS_OBJ_PRE_(me); // this memory pool + QS_MPC_PRE_(me->nFree); // # free blocks in the pool + QS_MPC_PRE_(margin); // the requested margin + QS_END_PRE_() } portCLEAR_INTERRUPT_MASK_FROM_ISR(uxSavedInterruptStatus); - return fb; /* return the pointer to memory block or NULL to the caller */ + return fb; // return the block or NULL pointer to the caller } +//============================================================================ +// NOTE3: +// The event posting to FreeRTOS message queue occurs OUTSIDE critical section, +// which means that the remaining margin of available slots in the queue +// cannot be guaranteed. The problem is that interrupts and other tasks can +// preempt the event posting after checking the margin, but before actually +// posting the event to the queue. +// + diff --git a/ports/freertos/qf_port.h b/ports/freertos/qf_port.h deleted file mode 100644 index bf0d1af6..00000000 --- a/ports/freertos/qf_port.h +++ /dev/null @@ -1,236 +0,0 @@ -/*============================================================================ -* QP/C Real-Time Embedded Framework (RTEF) -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2022-12-27 -* @version Last updated for: @ref qpc_7_2_0 -* -* @file -* @brief QF/C port to FreeRTOS 10.x -*/ -#ifndef QF_PORT_H -#define QF_PORT_H - -/* FreeRTOS event queue and thread types */ -#define QF_EQUEUE_TYPE QueueHandle_t -#define QF_OS_OBJECT_TYPE StaticQueue_t -#define QF_THREAD_TYPE StaticTask_t - -/* The maximum number of active objects in the application, see NOTE1 */ -#define QF_MAX_ACTIVE 32U - -/* QF interrupt disabling/enabling (task level) */ -#define QF_INT_DISABLE() taskDISABLE_INTERRUPTS() -#define QF_INT_ENABLE() taskENABLE_INTERRUPTS() - -/* QF critical section for FreeRTOS (task level), see NOTE2 */ -/* #define QF_CRIT_STAT_TYPE not defined */ -#define QF_CRIT_ENTRY(stat_) taskENTER_CRITICAL() -#define QF_CRIT_EXIT(stat_) taskEXIT_CRITICAL() - -#include "FreeRTOS.h" /* FreeRTOS master include file, see NOTE3 */ -#include "task.h" /* FreeRTOS task management */ -#include "queue.h" /* FreeRTOS queue management */ - -#include "qep_port.h" /* QEP port */ -#include "qequeue.h" /* QF event queue (for deferring events) */ -#include "qmpool.h" /* QF memory pool (for event pools) */ -#include "qf.h" /* QF platform-independent public interface */ - -/* the "FromISR" versions of the QF APIs, see NOTE3 */ -#ifdef Q_SPY - -#define QACTIVE_POST_FROM_ISR(me_, e_, pxHigherPrioTaskWoken_, sender_) \ - ((void)QActive_postFromISR_((me_), (e_), QF_NO_MARGIN, \ - (pxHigherPrioTaskWoken_), (sender_))) - -#define QACTIVE_POST_X_FROM_ISR(me_, e_, margin_, \ - pxHigherPrioTaskWoken_, sender_) \ - (QActive_postFromISR_((me_), (e_), (margin_), \ - (pxHigherPrioTaskWoken_), (sender_))) - -#define QACTIVE_PUBLISH_FROM_ISR(e_, pxHigherPrioTaskWoken_, sender_) \ - (QActive_publishFromISR_((e_), (pxHigherPrioTaskWoken_), \ - (void const *)(sender_))) - -#define QTIMEEVT_TICK_FROM_ISR(tickRate_, pxHigherPrioTaskWoken_, sender_) \ - (QTimeEvt_tickFromISR_((tickRate_), (pxHigherPrioTaskWoken_), (sender_))) - -#else /* ndef Q_SPY */ - -#define QACTIVE_POST_FROM_ISR(me_, e_, pxHigherPrioTaskWoken_, dummy) \ - ((void)QActive_postFromISR_((me_), (e_), QF_NO_MARGIN, \ - (pxHigherPrioTaskWoken_), (void *)0)) - -#define QACTIVE_POST_X_FROM_ISR(me_, e_, margin_, \ - pxHigherPrioTaskWoken_, dummy) \ - (QActive_postFromISR_((me_), (e_), (margin_), \ - (pxHigherPrioTaskWoken_), (void *)0)) - -#define QACTIVE_PUBLISH_FROM_ISR(e_, pxHigherPrioTaskWoken_, dummy) \ - (QActive_publishFromISR_((e_), (pxHigherPrioTaskWoken_), \ - (void *)0)) - -#define QTIMEEVT_TICK_FROM_ISR(tickRate_, pxHigherPrioTaskWoken_, dummy) \ - (QTimeEvt_tickFromISR_((tickRate_), (pxHigherPrioTaskWoken_), (void *)0)) - -#endif /* Q_SPY */ - -/* this function only to be used through macros QACTIVE_POST_FROM_ISR() -* and QACTIVE_POST_X_FROM_ISR(). -*/ -bool QActive_postFromISR_(QActive * const me, QEvt const * const e, - uint_fast16_t const margin, - BaseType_t * const pxHigherPriorityTaskWoken, - void const * const sender); - -void QActive_publishFromISR_(QEvt const * const e, - BaseType_t * const pxHigherPriorityTaskWoken, - void const * const sender); - -void QTimeEvt_tickFromISR_(uint_fast8_t const tickRate, - BaseType_t * const pxHigherPriorityTaskWoken, - void const * const sender); - -#define QF_TICK_FROM_ISR(pxHigherPrioTaskWoken_, sender_) \ - QTIMEEVT_TICK_FROM_ISR(0U, pxHigherPrioTaskWoken_, sender_) - -#ifdef Q_EVT_CTOR /* Shall the ctor for the ::QEvt class be provided? */ - - #define Q_NEW_FROM_ISR(evtT_, sig_, ...) \ - (evtT_##_ctor((evtT_ *)QF_newXFromISR_(sizeof(evtT_), \ - QF_NO_MARGIN, (sig_)), (sig_), ##__VA_ARGS__)) - - #define Q_NEW_X_FROM_ISR(e_, evtT_, margin_, sig_, ...) do { \ - (e_) = (evtT_ *)QF_newXFromISR_(sizeof(evtT_), \ - (margin_), (sig_)); \ - if ((e_) != (evtT_ *)0) { \ - evtT_##_ctor((e_), (sig_), ##__VA_ARGS__); \ - } \ - } while (false) - -#else /* no ::QEvt ctor */ - - #define Q_NEW_FROM_ISR(evtT_, sig_) \ - ((evtT_ *)QF_newXFromISR_((uint_fast16_t)sizeof(evtT_), \ - QF_NO_MARGIN, (sig_))) - - #define Q_NEW_X_FROM_ISR(e_, evtT_, margin_, sig_) ((e_) = \ - (evtT_ *)QF_newXFromISR_((uint_fast16_t)sizeof(evtT_), \ - (margin_), (sig_))) - -#endif /* Q_EVT_CTOR */ - -void QF_gcFromISR(QEvt const * const e); - -/* this function only to be used through macros Q_NEW_FROM_ISR() and -* Q_NEW_X_FROM_ISR(). -*/ -QEvt *QF_newXFromISR_(uint_fast16_t const evtSize, - uint_fast16_t const margin, enum_t const sig); - -void *QMPool_getFromISR(QMPool * const me, uint_fast16_t const margin, - uint_fast8_t const qs_id); -void QMPool_putFromISR(QMPool * const me, void *b, uint_fast8_t const qs_id); - -enum FreeRTOS_TaskAttrs { - TASK_NAME_ATTR -}; - -/* FreeRTOS hooks prototypes (not provided by FreeRTOS) */ -#if (configUSE_IDLE_HOOK > 0) - void vApplicationIdleHook(void); -#endif -#if (configUSE_TICK_HOOK > 0) - void vApplicationTickHook(void); -#endif -#if (configCHECK_FOR_STACK_OVERFLOW > 0) - void vApplicationStackOverflowHook(TaskHandle_t xTask, char *pcTaskName); -#endif -#if (configSUPPORT_STATIC_ALLOCATION > 0) - void vApplicationGetIdleTaskMemory(StaticTask_t **ppxIdleTaskTCBBuffer, - StackType_t **ppxIdleTaskStackBuffer, - uint32_t *pulIdleTaskStackSize); -#endif - -/*==========================================================================*/ -/* interface used only inside QF, but not in applications */ - -#ifdef QP_IMPL - #define FREERTOS_TASK_PRIO(qp_prio_) \ - ((UBaseType_t)((qp_prio_) + tskIDLE_PRIORITY)) - - /* FreeRTOS scheduler locking for QF_publish_() (task context only) */ - #define QF_SCHED_STAT_ \ - UBaseType_t curr_prio; \ - TaskHandle_t curr_task; - #define QF_SCHED_LOCK_(prio_) do { \ - curr_task = xTaskGetCurrentTaskHandle(); \ - curr_prio = uxTaskPriorityGet(curr_task); \ - if (FREERTOS_TASK_PRIO(prio_) > curr_prio) { \ - vTaskPrioritySet(curr_task, FREERTOS_TASK_PRIO(prio_));\ - } \ - else { \ - curr_prio = tskIDLE_PRIORITY; \ - } \ - } while (0) - - #define QF_SCHED_UNLOCK_() \ - if (curr_prio != tskIDLE_PRIORITY) { \ - vTaskPrioritySet(curr_task, curr_prio); \ - } else ((void)0) - - /* native QF event pool operations */ - #define QF_EPOOL_TYPE_ QMPool - #define QF_EPOOL_INIT_(p_, poolSto_, poolSize_, evtSize_) \ - (QMPool_init(&(p_), (poolSto_), (poolSize_), (evtSize_))) - #define QF_EPOOL_EVENT_SIZE_(p_) ((uint_fast16_t)(p_).blockSize) - #define QF_EPOOL_GET_(p_, e_, m_, qs_id_) \ - ((e_) = (QEvt *)QMPool_get(&(p_), (m_), (qs_id_))) - #define QF_EPOOL_PUT_(p_, e_, qs_id_) \ - (QMPool_put(&(p_), (e_), (qs_id_))) - -#endif /* ifdef QP_IMPL */ - -/*==========================================================================*/ -/* NOTE1: -* The maximum number of active objects QF_MAX_ACTIVE can be increased to 64, -* inclusive, but it can be reduced to save some memory. Also, the number of -* active objects cannot exceed the number of FreeRTOS task priorities, -* because each QP active object requires a unique priority level. -* -* NOTE2: -* The critical section definition applies only to the FreeRTOS "task level" -* APIs. The "FromISR" APIs are defined separately. -* -* NOTE3: -* The design of FreeRTOS requires using different APIs inside the ISRs -* (the "FromISR" variant) than at the task level. Accordingly, this port -* provides the "FromISR" variants for QP functions and "FROM_ISR" variants -* for QP macros to be used inside ISRs. ONLY THESE "FROM_ISR" VARIANTS -* ARE ALLOWED INSIDE ISRs AND CALLING THE TASK-LEVEL APIs IS AN ERROR. -*/ - -#endif /* QF_PORT_H */ - diff --git a/ports/freertos/qp_port.h b/ports/freertos/qp_port.h new file mode 100644 index 00000000..19af867c --- /dev/null +++ b/ports/freertos/qp_port.h @@ -0,0 +1,224 @@ +//============================================================================ +// QP/C Real-Time Embedded Framework (RTEF) +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +//============================================================================ +//! @date Last updated on: 2023-09-07 +//! @version Last updated for: @ref qpc_7_3_0 +//! +//! @file +//! @brief QP/C port to FreeRTOS 10.x, generic C11 compiler + +#ifndef QP_PORT_H_ +#define QP_PORT_H_ + +#include // Exact-width types. WG14/N843 C99 Standard +#include // Boolean type. WG14/N843 C99 Standard + +#ifdef QP_CONFIG +#include "qp_config.h" // external QP configuration +#endif + +// no-return function specifier (C11 Standard) +#define Q_NORETURN _Noreturn void + +// QActive event queue and thread types for FreeRTOS +#define QACTIVE_EQUEUE_TYPE QueueHandle_t +#define QACTIVE_OS_OBJ_TYPE StaticQueue_t +#define QACTIVE_THREAD_TYPE StaticTask_t + +// FreeRTOS requires the "FromISR" API in QP/C++ +#define QF_ISR_API 1 + +// QF interrupt disabling/enabling (task level) +#define QF_INT_DISABLE() taskDISABLE_INTERRUPTS() +#define QF_INT_ENABLE() taskENABLE_INTERRUPTS() + +// QF critical section for FreeRTOS (task level), see NOTE2 +#define QF_CRIT_STAT +#define QF_CRIT_ENTRY() taskENTER_CRITICAL() +#define QF_CRIT_EXIT() taskEXIT_CRITICAL() + +// include files ------------------------------------------------------------- +#include "FreeRTOS.h" // FreeRTOS master include file, see NOTE3 +#include "task.h" // FreeRTOS task management +#include "queue.h" // FreeRTOS queue management + +#include "qequeue.h" // QP event queue (for deferring events) +#include "qmpool.h" // QP memory pool (for event pools) +#include "qp.h" // QP platform-independent public interface + + +// the "FromISR" versions of the QF APIs, see NOTE3 +#ifdef Q_SPY + +#define QACTIVE_POST_FROM_ISR(me_, e_, pxHigherPrioTaskWoken_, sender_) \ + ((void)QActive_postFromISR_((me_), (e_), QF_NO_MARGIN, \ + (pxHigherPrioTaskWoken_), (sender_))) + +#define QACTIVE_POST_X_FROM_ISR(me_, e_, margin_, \ + pxHigherPrioTaskWoken_, sender_) \ + (QActive_postFromISR_((me_), (e_), (margin_), \ + (pxHigherPrioTaskWoken_), (sender_))) + +#define QACTIVE_PUBLISH_FROM_ISR(e_, pxHigherPrioTaskWoken_, sender_) \ + (QActive_publishFromISR_((e_), (pxHigherPrioTaskWoken_), \ + (void const *)(sender_))) + +#define QTIMEEVT_TICK_FROM_ISR(tickRate_, pxHigherPrioTaskWoken_, sender_) \ + (QTimeEvt_tickFromISR_((tickRate_), (pxHigherPrioTaskWoken_), (sender_))) + +#else // ndef Q_SPY + +#define QACTIVE_POST_FROM_ISR(me_, e_, pxHigherPrioTaskWoken_, dummy) \ + ((void)QActive_postFromISR_((me_), (e_), QF_NO_MARGIN, \ + (pxHigherPrioTaskWoken_), (void *)0)) + +#define QACTIVE_POST_X_FROM_ISR(me_, e_, margin_, \ + pxHigherPrioTaskWoken_, dummy) \ + (QActive_postFromISR_((me_), (e_), (margin_), \ + (pxHigherPrioTaskWoken_), (void *)0)) + +#define QACTIVE_PUBLISH_FROM_ISR(e_, pxHigherPrioTaskWoken_, dummy) \ + (QActive_publishFromISR_((e_), (pxHigherPrioTaskWoken_), \ + (void *)0)) + +#define QTIMEEVT_TICK_FROM_ISR(tickRate_, pxHigherPrioTaskWoken_, dummy) \ + (QTimeEvt_tickFromISR_((tickRate_), (pxHigherPrioTaskWoken_), (void *)0)) + +#endif // Q_SPY + +bool QActive_postFromISR_(QActive * const me, QEvt const * const e, + uint_fast16_t const margin, + BaseType_t * const pxHigherPriorityTaskWoken, + void const * const sender); + +void QActive_publishFromISR_(QEvt const * const e, + BaseType_t * const pxHigherPriorityTaskWoken, + void const * const sender); + +void QTimeEvt_tickFromISR_(uint_fast8_t const tickRate, + BaseType_t * const pxHigherPriorityTaskWoken, + void const * const sender); + +#define QF_TICK_FROM_ISR(pxHigherPrioTaskWoken_, sender_) \ + QTIMEEVT_TICK_FROM_ISR(0U, pxHigherPrioTaskWoken_, sender_) + +#ifdef QEVT_DYN_CTOR // Shall the ctor for the ::QEvt class be provided? + + #define Q_NEW_FROM_ISR(evtT_, sig_, ...) \ + (evtT_##_ctor((evtT_ *)QF_newXFromISR_(sizeof(evtT_), \ + QF_NO_MARGIN, (sig_)), __VA_ARGS__)) + + #define Q_NEW_X_FROM_ISR(e_, evtT_, margin_, sig_, ...) do { \ + (e_) = (evtT_ *)QF_newXFromISR_(sizeof(evtT_), \ + (margin_), (sig_)); \ + if ((e_) != (evtT_ *)0) { \ + evtT_##_ctor((e_), __VA_ARGS__); \ + } \ + } while (false) + +#else // no ::QEvt ctor + + #define Q_NEW_FROM_ISR(evtT_, sig_) \ + ((evtT_ *)QF_newXFromISR_((uint_fast16_t)sizeof(evtT_), \ + QF_NO_MARGIN, (sig_))) + + #define Q_NEW_X_FROM_ISR(e_, evtT_, margin_, sig_) ((e_) = \ + (evtT_ *)QF_newXFromISR_((uint_fast16_t)sizeof(evtT_), \ + (margin_), (sig_))) + +#endif // QEVT_DYN_CTOR + +void QF_gcFromISR(QEvt const * const e); + +QEvt *QF_newXFromISR_(uint_fast16_t const evtSize, + uint_fast16_t const margin, enum_t const sig); + +void *QMPool_getFromISR(QMPool * const me, uint_fast16_t const margin, + uint_fast8_t const qs_id); +void QMPool_putFromISR(QMPool * const me, void *block, + uint_fast8_t const qs_id); + +enum FreeRTOS_TaskAttrs { + TASK_NAME_ATTR +}; + +// FreeRTOS hooks prototypes (not provided by FreeRTOS) +#if (configUSE_IDLE_HOOK > 0) + void vApplicationIdleHook(void); +#endif +#if (configUSE_TICK_HOOK > 0) + void vApplicationTickHook(void); +#endif +#if (configCHECK_FOR_STACK_OVERFLOW > 0) + void vApplicationStackOverflowHook(TaskHandle_t xTask, char *pcTaskName); +#endif +#if (configSUPPORT_STATIC_ALLOCATION > 0) + void vApplicationGetIdleTaskMemory(StaticTask_t **ppxIdleTaskTCBBuffer, + StackType_t **ppxIdleTaskStackBuffer, + uint32_t *pulIdleTaskStackSize); +#endif + +//============================================================================ +// interface used only inside QF, but not in applications + +#ifdef QP_IMPL + #define FREERTOS_TASK_PRIO(qp_prio_) \ + ((UBaseType_t)((qp_prio_) + tskIDLE_PRIORITY)) + + // FreeRTOS scheduler locking for QF_publish_() (task context only) + #define QF_SCHED_STAT_ + #define QF_SCHED_LOCK_(prio_) (vTaskSuspendAll()) + #define QF_SCHED_UNLOCK_() ((void)xTaskResumeAll()) + + // native QF event pool customization + #define QF_EPOOL_TYPE_ QMPool + #define QF_EPOOL_INIT_(p_, poolSto_, poolSize_, evtSize_) \ + (QMPool_init(&(p_), (poolSto_), (poolSize_), (evtSize_))) + #define QF_EPOOL_EVENT_SIZE_(p_) ((uint_fast16_t)(p_).blockSize) + #define QF_EPOOL_GET_(p_, e_, m_, qs_id_) \ + ((e_) = (QEvt *)QMPool_get(&(p_), (m_), (qs_id_))) + #define QF_EPOOL_PUT_(p_, e_, qs_id_) \ + (QMPool_put(&(p_), (e_), (qs_id_))) + +#endif // QP_IMPL + +//============================================================================ +// NOTE2: +// The critical section definition applies only to the FreeRTOS "task level" +// APIs. The "FromISR" APIs are defined separately. +// +// NOTE3: +// The design of FreeRTOS requires using different APIs inside the ISRs +// (the "FromISR" variant) than at the task level. Accordingly, this port +// provides the "FromISR" variants for QP functions and "FROM_ISR" variants +// for QP macros to be used inside ISRs. ONLY THESE "FROM_ISR" VARIANTS +// ARE ALLOWED INSIDE ISRs AND CALLING THE TASK-LEVEL APIs IS AN ERROR. + +#endif // QP_PORT_H_ + diff --git a/ports/freertos/qs_port.h b/ports/freertos/qs_port.h index e8b00882..206b7e4c 100644 --- a/ports/freertos/qs_port.h +++ b/ports/freertos/qs_port.h @@ -1,60 +1,56 @@ -/*============================================================================ -* QP/C Real-Time Embedded Framework (RTEF) -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2022-06-12 -* @version Last updated for: @ref qpc_7_0_1 -* -* @file -* @brief QS/C port to a 32-bit CPU and a generic C99 compiler. -* @description -* This is an example of a QP/C port with the documentation for the -* configuration macros and includes. -*/ -#ifndef QS_PORT_H -#define QS_PORT_H +//============================================================================ +// QP/C Real-Time Embedded Framework (RTEF) +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +//============================================================================ +//! @date Last updated on: 2023-08-16 +//! @version Last updated for: @ref qpc_7_3_0 +//! +//! @file +//! @brief QS/C port to a 32-bit CPU and a generic C11 compiler. -/* QS time-stamp size in bytes */ -#define QS_TIME_SIZE 4 +#ifndef QS_PORT_H_ +#define QS_PORT_H_ -/* object pointer size in bytes */ -#define QS_OBJ_PTR_SIZE 4 +// QS time-stamp size in bytes +#define QS_TIME_SIZE 4U -/* function pointer size in bytes */ -#define QS_FUN_PTR_SIZE 4 +// object pointer size in bytes +#define QS_OBJ_PTR_SIZE 4U -/*==========================================================================*/ -/* NOTE: QS might be used with or without other QP components, in which -* case the separate definitions of the macros QF_CRIT_STAT_TYPE, -* QF_CRIT_ENTRY, and QF_CRIT_EXIT are needed. In this port QS is configured -* to be used with the other QP component, by simply including "qf_port.h" -* *before* "qs.h". -*/ -#ifndef QF_PORT_H -#include "qf_port.h" /* use QS with QF */ +// function pointer size in bytes +#define QS_FUN_PTR_SIZE 4U + +//============================================================================ +// NOTE: QS might be used with or without other QP components, in which +// case the separate definitions of the macros QF_CRIT_STAT, QF_CRIT_ENTRY(), +// and QF_CRIT_EXIT() are needed. In this port QS is configured to be used +// with the other QP component, by simply including "qp_port.h" +//*before* "qs.h". +#ifndef QP_PORT_H_ +#include "qp_port.h" // use QS with QF #endif -#include "qs.h" /* QS platform-independent public interface */ +#include "qs.h" // QS platform-independent public interface + +#endif // QS_PORT_H_ -#endif /* QS_PORT_H */ diff --git a/ports/lint-plus/16bit/qs_port.h b/ports/lint-plus/16bit/qs_port.h index 97568991..e2dc3231 100644 --- a/ports/lint-plus/16bit/qs_port.h +++ b/ports/lint-plus/16bit/qs_port.h @@ -1,60 +1,58 @@ -/*============================================================================ -* QP/C Real-Time Embedded Framework (RTEF) -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2022-06-12 -* @version Last updated for: @ref qpc_7_0_1 -* -* @file -* @brief QS/C port to a 32-bit CPU and a generic C99 compiler. -* @description -* This is an example of a QP/C port with the documentation for the -* configuration macros and includes. -*/ -#ifndef QS_PORT_H -#define QS_PORT_H +//============================================================================ +// QP/C Real-Time Embedded Framework (RTEF) +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +//============================================================================ +//! @date Last updated on: 2023-08-16 +//! @version Last updated for: @ref qpc_7_3_0 +//! +//! @file +//! @brief QS/C port to a 16-bit CPU and a generic C11 compiler. +//! @description +//! This is an example of a QP/C port with the documentation for the +//! configuration macros and includes. +//! +#ifndef QS_PORT_H_ +#define QS_PORT_H_ -/* QS time-stamp size in bytes */ +// QS time-stamp size in bytes #define QS_TIME_SIZE 4U -/* object pointer size in bytes */ +// object pointer size in bytes #define QS_OBJ_PTR_SIZE 2U -/* function pointer size in bytes */ +// function pointer size in bytes #define QS_FUN_PTR_SIZE 2U -/***************************************************************************** -* NOTE: QS might be used with or without other QP components, in which -* case the separate definitions of the macros QF_CRIT_STAT_TYPE, -* QF_CRIT_ENTRY, and QF_CRIT_EXIT are needed. In this port QS is configured -* to be used with the other QP component, by simply including "qf_port.h" -* *before* "qs.h". -*/ -#ifndef QF_PORT_H -#include "qf_port.h" /* use QS with QF */ +//============================================================================ +// NOTE: QS might be used with or without other QP components, in which +// case the separate definitions of the macros QF_CRIT_STAT, QF_CRIT_ENTRY(), +// and QF_CRIT_EXIT() are needed. In this port QS is configured to be used +// with the other QP component, by simply including "qp_port.h" +// *before* "qs.h". +#ifndef QP_PORT_H_ +#include "qp_port.h" // use QS with QP #endif -#include "qs.h" /* QS platform-independent public interface */ +#include "qs.h" // QS platform-independent public interface -#endif /* QS_PORT_H */ +#endif // QS_PORT_H_ diff --git a/ports/lint-plus/16bit/stdint.h b/ports/lint-plus/16bit/stdint.h index 43548b9d..c1b99efc 100644 --- a/ports/lint-plus/16bit/stdint.h +++ b/ports/lint-plus/16bit/stdint.h @@ -1,46 +1,47 @@ -/** -* @file -* @brief Selected exact-width and fast minimum-width integer types -* for 16-bit CPU architecture (e.g., MSP430). -* -* @description -* This header is part of the ANSI C99 standard library to define the -* standard exact-width integer types (see C99 Section 7.18.1.1). -* If the compiler does not provide the stdint.h header file, you can -* either create one in the QP port directory, or you can typedef the -* 8 exact-width integer types directly in the qep_port.h header file. -* -* @note The version included in the QP documentation contains only the 8 -* exact-width types and 6 fast minimum-width types actually used in QP. -* The actual definition of the integer types is platform dependent. -*/ -#ifndef STDINT_H -#define STDINT_H +//! @file +//! @brief Selected exact-width and fast minimum-width integer types +//! for 16-bit CPU architecture (e.g., MSP430). +//! +//! @description +//! This header is part of the ANSI C99 standard library to define the +//! standard exact-width integer types (see C99 Section 7.18.1.1). +//! If the compiler does not provide the stdint.h header file, you can +//! either create one in the QP port directory, or you can typedef the +//! 8 exact-width integer types directly in the qep_port.h header file. +//! +//! @note The version included in the QP documentation contains only the 8 +//! exact-width types and 6 fast minimum-width types actually used in QP. +//! The actual definition of the integer types is platform dependent. +#ifndef STDINT_H_ +#define STDINT_H_ -/*lint -save */ -/*lint -e9093 M3:R21.2(R) name matches a pattern reserved to the compiler */ -/*lint -e586 B18:R5.2(b) keyword 'short'/'long' is deprecated */ +//lint -save +//lint -e9093 M3:R21.2(R) name matches a pattern reserved to the compiler +//lint -e586 B18:R5.2(b) keyword 'short'/'long' is deprecated -/* Exact-width types. WG14/N843 C99 Standard, Section 7.18.1.1 */ -typedef signed char int8_t; /*!< exact-width 8-bit signed int */ -typedef signed int int16_t; /*!< exact-width 16-bit signed int */ -typedef signed long int int32_t; /*!< exact-width 32-bit signed int */ -typedef signed long long int64_t; /*!< exact-width 64-bit signed int */ +// Exact-width types. WG14/N843 C99 Standard, Section 7.18.1.1 +typedef signed char int8_t; //!< exact-width 8-bit signed int +typedef signed int int16_t; //!< exact-width 16-bit signed int +typedef signed long int int32_t; //!< exact-width 32-bit signed int +typedef signed long long int64_t; //!< exact-width 64-bit signed int -typedef unsigned char uint8_t; /*!< exact-width 8-bit unsigned int */ -typedef unsigned int uint16_t; /*!< exact-width 16-bit unsigned int */ -typedef unsigned long int uint32_t; /*!< exact-width 32-bit unsigned int */ -typedef unsigned long long uint64_t; /*!< exact-width 64-bit unsigned int */ +typedef unsigned char uint8_t; //!< exact-width 8-bit unsigned int +typedef unsigned int uint16_t; //!< exact-width 16-bit unsigned int +typedef unsigned long int uint32_t; //!< exact-width 32-bit unsigned int +typedef unsigned long long uint64_t; //!< exact-width 64-bit unsigned int -/* Fastest minimum-width types. WG14/N843 C99 Standard, Section 7.18.1.3 */ -typedef signed int int_fast8_t; /*!< fast at-least 8-bit signed int */ -typedef unsigned int uint_fast8_t; /*!< fast at-least 8-bit unsigned int */ -typedef signed int int_fast16_t; /*!< fast at-least 16-bit signed int */ -typedef unsigned int uint_fast16_t; /*!< fast at-least 16-bit unsigned int */ -typedef signed long int_fast32_t; /*!< fast at-least 32-bit signed int */ -typedef unsigned long uint_fast32_t; /*!< fast at-least 32-bit unsigned int */ +// Fastest minimum-width types. WG14/N843 C99 Standard, Section 7.18.1.3 +typedef signed int int_fast8_t; //!< fast at-least 8-bit signed int +typedef unsigned int uint_fast8_t; //!< fast at-least 8-bit unsigned int +typedef signed int int_fast16_t; //!< fast at-least 16-bit signed int +typedef unsigned int uint_fast16_t; //!< fast at-least 16-bit unsigned int +typedef signed long int_fast32_t; //!< fast at-least 32-bit signed int +typedef unsigned long uint_fast32_t; //!< fast at-least 32-bit unsigned int -/*lint -restore */ +// unsigned integer type capable of holding a pointer to void. +typedef unsigned uintptr_t; //!< unsigned int capable of holding void* -#endif /* STDINT_H */ +//lint -restore + +#endif // STDINT_H_ diff --git a/ports/lint-plus/32bit/qs_port.h b/ports/lint-plus/32bit/qs_port.h index b1c77d47..dc2d7fbd 100644 --- a/ports/lint-plus/32bit/qs_port.h +++ b/ports/lint-plus/32bit/qs_port.h @@ -1,60 +1,58 @@ -/*============================================================================ -* QP/C Real-Time Embedded Framework (RTEF) -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2022-06-12 -* @version Last updated for: @ref qpc_7_0_1 -* -* @file -* @brief QS/C port to a 32-bit CPU and a generic C99 compiler. -* @description -* This is an example of a QP/C port with the documentation for the -* configuration macros and includes. -*/ -#ifndef QS_PORT_H -#define QS_PORT_H +//============================================================================ +// QP/C Real-Time Embedded Framework (RTEF) +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +//============================================================================ +//! @date Last updated on: 2023-08-16 +//! @version Last updated for: @ref qpc_7_3_0 +//! +//! @file +//! @brief QS/C port to a 32-bit CPU and a generic C11 compiler. +//! @description +//! This is an example of a QP/C port with the documentation for the +//! configuration macros and includes. +//! +#ifndef QS_PORT_H_ +#define QS_PORT_H_ -/* QS time-stamp size in bytes */ +// QS time-stamp size in bytes #define QS_TIME_SIZE 4U -/* object pointer size in bytes */ +// object pointer size in bytes #define QS_OBJ_PTR_SIZE 4U -/* function pointer size in bytes */ +// function pointer size in bytes #define QS_FUN_PTR_SIZE 4U -/*==========================================================================*/ -/* NOTE: QS might be used with or without other QP components, in which -* case the separate definitions of the macros QF_CRIT_STAT_TYPE, -* QF_CRIT_ENTRY, and QF_CRIT_EXIT are needed. In this port QS is configured -* to be used with the other QP component, by simply including "qf_port.h" -* *before* "qs.h". -*/ -#ifndef QF_PORT_H -#include "qf_port.h" /* use QS with QF */ +//============================================================================ +// NOTE: QS might be used with or without other QP components, in which +// case the separate definitions of the macros QF_CRIT_STAT, QF_CRIT_ENTRY(), +// and QF_CRIT_EXIT() are needed. In this port QS is configured to be used +// with the other QP component, by simply including "qp_port.h" +// *before* "qs.h". +#ifndef QP_PORT_H_ +#include "qp_port.h" // use QS with QP #endif -#include "qs.h" /* QS platform-independent public interface */ +#include "qs.h" // QS platform-independent public interface -#endif /* QS_PORT_H */ +#endif // QS_PORT_H_ diff --git a/ports/lint-plus/32bit/stdint.h b/ports/lint-plus/32bit/stdint.h index d0db6a27..96e3af0c 100644 --- a/ports/lint-plus/32bit/stdint.h +++ b/ports/lint-plus/32bit/stdint.h @@ -1,46 +1,47 @@ -/*! -* @file -* @brief Selected exact-width and fast minimum-width integer types -* for 32-bit CPU architecture (e.g., ARM Cortex-M). -* -* @description -* This header is part of the ANSI C99 standard library to define the -* standard exact-width integer types (see C99 Section 7.18.1.1). -* If the compiler does not provide the stdint.h header file, you can -* either create one in the QP port directory, or you can typedef the -* 8 exact-width integer types directly in the qep_port.h header file. -* -* @note The version included in the QP documentation contains only the 8 -* exact-width types and 6 fast minimum-width types actually used in QP. -* The actual definition of the integer types is platform dependent. -*/ -#ifndef STDINT_H -#define STDINT_H +//! @file +//! @brief Selected exact-width and fast minimum-width integer types +//! for 32-bit CPU architecture (e.g., ARM Cortex-M). +//! +//! @description +//! This header is part of the ANSI C99 standard library to define the +//! standard exact-width integer types (see C99 Section 7.18.1.1). +//! If the compiler does not provide the stdint.h header file, you can +//! either create one in the QP port directory, or you can typedef the +//! 8 exact-width integer types directly in the qep_port.h header file. +//! +//! @note The version included in the QP documentation contains only the 8 +//! exact-width types and 6 fast minimum-width types actually used in QP. +//! The actual definition of the integer types is platform dependent. +#ifndef STDINT_H_ +#define STDINT_H_ -/*lint -save */ -/*lint -e9093 M3:R21.2(R) name matches a pattern reserved to the compiler */ -/*lint -e586 B18:R5.2(b) keyword 'short'/'long' is deprecated */ +//lint -save +//lint -e9093 M3:R21.2(R) name matches a pattern reserved to the compiler +//lint -e586 B18:R5.2(b) keyword 'short'/'long' is deprecated -/* Exact-width types. WG14/N843 C99 Standard, Section 7.18.1.1 */ -typedef signed char int8_t; /*!< exact-width 8-bit signed int */ -typedef signed short int16_t; /*!< exact-width 16-bit signed int */ -typedef signed long int32_t; /*!< exact-width 32-bit signed int */ -typedef signed long long int64_t; /*!< exact-width 64-bit signed int */ +// Exact-width types. WG14/N843 C99 Standard, Section 7.18.1.1 +typedef signed char int8_t; //!< exact-width 8-bit signed int +typedef signed short int16_t; //!< exact-width 16-bit signed int +typedef signed int int32_t; //!< exact-width 32-bit signed int +typedef signed long long int64_t; //!< exact-width 64-bit signed int -typedef unsigned char uint8_t; /*!< exact-width 8-bit unsigned int */ -typedef unsigned short uint16_t; /*!< exact-width 16-bit unsigned int */ -typedef unsigned long uint32_t; /*!< exact-width 32-bit unsigned int */ -typedef unsigned long long uint64_t; /*!< exact-width 64-bit unsigned int */ +typedef unsigned char uint8_t; //!< exact-width 8-bit unsigned int +typedef unsigned short uint16_t; //!< exact-width 16-bit unsigned int +typedef unsigned int uint32_t; //!< exact-width 32-bit unsigned int +typedef unsigned long long uint64_t; //!< exact-width 64-bit unsigned int -/* Fastest minimum-width types. WG14/N843 C99 Standard, Section 7.18.1.3 */ -typedef signed int int_fast8_t; /*!< fast at-least 8-bit signed int */ -typedef unsigned int uint_fast8_t; /*!< fast at-least 8-bit unsigned int */ -typedef signed int int_fast16_t; /*!< fast at-least 16-bit signed int */ -typedef unsigned int uint_fast16_t; /*!< fast at-least 16-bit unsigned int */ -typedef signed long int_fast32_t; /*!< fast at-least 32-bit signed int */ -typedef unsigned long uint_fast32_t; /*!< fast at-least 32-bit unsigned int */ +// Fastest minimum-width types. WG14/N843 C99 Standard, Section 7.18.1.3 +typedef signed int int_fast8_t; //!< fast at-least 8-bit signed int +typedef unsigned int uint_fast8_t; //!< fast at-least 8-bit unsigned int +typedef signed int int_fast16_t; //!< fast at-least 16-bit signed int +typedef unsigned int uint_fast16_t; //!< fast at-least 16-bit unsigned int +typedef signed long int_fast32_t; //!< fast at-least 32-bit signed int +typedef unsigned long uint_fast32_t; //!< fast at-least 32-bit unsigned int -/*lint -restore */ +// unsigned integer type capable of holding a pointer to void. +typedef unsigned uintptr_t; //!< unsigned int capable of holding void* -#endif /* STDINT_H */ +//lint -restore + +#endif // STDINT_H_ diff --git a/ports/lint-plus/au-barr.lnt b/ports/lint-plus/au-barr.lnt index 362fef23..c1d3f84c 100644 --- a/ports/lint-plus/au-barr.lnt +++ b/ports/lint-plus/au-barr.lnt @@ -1,7 +1,7 @@ // --------------------------------------------------------------------------- -// Copyright Gimpel Software LLC 2019. All rights reserved. +// Copyright Vector Informatik GmbH 2019. All rights reserved. // -// This file is provided by Gimpel Software LLC (https://www.gimpel.com) for +// This file is provided by Vector Informatik GmbH (https://www.vector.com) for // use with PC-lint Plus. Redistribution is permitted but any redistribution // must preserve this notice and, if the redistributed file has been modified, // provide notice that the file has been modified from the original. @@ -13,7 +13,7 @@ // checks advocated by the Embedded C Coding Standard BARR-C:2018. // https://barrgroup.com/Embedded-Systems/Books/Embedded-C-Coding-Standard -// ========== GENERAL RULES ========== +//========== GENERAL RULES ========== // 1.1 Which C? @@ -121,7 +121,7 @@ +e2765 -append(2765,[BARR-C:2018 Rule 1.8c]) -// ========== COMMENTS ========== +//========== COMMENTS ========== // 2.1 Acceptable Formats @@ -149,7 +149,7 @@ /* not statically checkable */ -// ========== WHITE SPACE RULES ========== +//========== WHITE SPACE RULES ========== // 3.1 Spaces @@ -187,7 +187,7 @@ /* not currently supported */ -// ========== MODULE RULES ========== +//========== MODULE RULES ========== // 4.1 Naming Conventions @@ -210,8 +210,12 @@ -append(8518,[BARR-C:2018 Rule 4.1b]) /* 8519 - 'main' function defined in file that does not contain the word 'main' */ - -hook(func_decl, -cond('%[qual_name]' == 'main' && %[is_definition] && !('%[file]' ~ 'main'), - +message(8519, "main function defined in file '%[file]' which does not have the word 'main' in its name"))) + -astquery(FunctionDecl : { + getQualifiedNameAsString() == "main" + isThisDeclarationADefinition() + not "main" in getLocation().getBufferName() + message(8519 "main function defined in file '" getLocation().getBufferName() "' which does not have the word 'main' in its name") + }) +e8519 -append(8519,[BARR-C:2018 Rule 4.1d]) @@ -278,27 +282,37 @@ /* not statically checkable */ -// ========== DATA TYPE RULES ========== +//========== DATA TYPE RULES ========== // 5.1 Naming Conventions /* 8526 - typedef name should consist of lowercase letters and underscores */ - -hook(typename_decl, -cond(!('%[name]' ~ '^[[:lower:]_]*$'), - +message(8526, "typedef name '%[name]' should consist of lowercase letters and underscores"))) + -astquery(TypedefDecl : { + $name = getNameAsString() + $name ~~ "[^[:lower:]_]" + message(8526 "typedef name '" $name "' should consist of lowercase letters and underscores") + }) +e8526 -append(8526,[BARR-C:2018 Rule 5.1a]) /* 8527 - typedef name should end with '_t' suffix */ - -hook(typename_decl, -cond(!('%[name]' ~ '_t$'), - +message(8527, "typedef name '%[name]' should end with '_t' suffix"))) + -astquery(TypedefDecl : { + $name = getNameAsString() + not $name ~~ "_t$" + message(8527 "typedef name '" $name " ' should end with '_t' suffix") + }) +e8527 -append(8527,[BARR-C:2018 Rule 5.1a]) /* 8528 - non-anonymous struct/union/enum declared outside of typedef */ - -hook(record_decl, -cond(%[is_freestanding] && !%[is_anonymous], - +message(8528, "non-anonymous struct/union declared outside of a typedef"))) - -hook(enum_decl, -cond(%[is_freestanding] && '%[name]' != '', - +message(8528, "non-anonymous enum declared outside of a typedef"))) + -astquery(RecordDecl : { + isFreeStanding() && not isAnonymousStructOrUnion() + message(8528 "non-anonymous struct/union declared outside of a typedef") + }) + -astquery(EnumDecl : { + isFreeStanding() && hasName() + message(8528 "non-anonymous enum declared outside of a typedef") + }) +e8528 -append(8528,[BARR-C:2018 Rule 5.1b]) @@ -344,15 +358,15 @@ -append(713,[BARR-C:2018 Rule 5.3c]) /* 8524 - combining signed and unsigned types with operator op1 */ - -hook(binary_expr, -cond(%[walk_lhs_expr{false}.walk_type.is_integer] && - %[walk_rhs_expr{false}.walk_type.is_integer] && - !%[walk_lhs_expr.walk_past_paren_imp.walk_type.is_enumeral] && - !%[walk_rhs_expr.walk_past_paren_imp.walk_type.is_enumeral] && - !%[walk_lhs_expr.walk_past_paren_imp.walk_type.is_boolean] && - !%[walk_rhs_expr.walk_past_paren_imp.walk_type.is_boolean] && - '%[walk_lhs_expr.walk_past_paren_imp.walk_type.is_unsigned_int_enum]' != - '%[walk_rhs_expr.walk_past_paren_imp.walk_type.is_unsigned_int_enum]', - +message(8524, "combining signed and unsigned types with operator '%[opcode]'"))) + -astquery(BinaryOperator : { + getLHS().getType().isIntegerType() && getRHS().getType().isIntegerType() + $lhs_type = getLHS().ignoreParenImpCasts().getType() + $rhs_type = getRHS().ignoreParenImpCasts().getType() + ! $lhs_type.isEnumeralType() && ! $lhs_type.isBooleanType() + ! $rhs_type.isEnumeralType() && ! $rhs_type.isBooleanType() + $lhs_type.isUnsignedIntegerOrEnumerationType() != $rhs_type.isUnsignedIntegerOrEnumerationType() + message(8524 "combining signed and unsigned types with operator '" getOpcodeStr "'") + }) +e8524 -append(8524,[BARR-C:2018 Rule 5.3c]) @@ -378,37 +392,54 @@ // 5.6 Booleans /* 8523 - cast to boolean */ - -hook(cast_expr, -cond(%[is_cstyle_cast] && %[walk_type.is_boolean], - +message(8523, "cast to boolean"))) + -astquery(CStyleCastExpr() : { + getType().isBooleanType() + message(8523 "cast to Boolean") + }) +e8523 -append(8523,[BARR-C:2018 Rule 5.6b]) -// ========== PROCEDURE RULES ========== +//========== PROCEDURE RULES ========== // 6.1 Naming Conventions /* 8501 - function has name that matches a keyword in C or C++ */ - -hook(func_decl, -cond('%[name]' ~ '^(?Palignas|alignof|and|and_eq|asm|auto|bitand|bitor|bool|break|case|catch|char|char8_t|char16_t|char32_t|class|compl|concept|const|consteval|constexpr|const_cast|continue|co_await|co_return|co_yield|decltype|default|delete|do|double|dynamic_cast|else|enum|explicit|export|extern|false|float|for|friend|goto|if|inline|int|long|mutable|namespace|new|noexcept|not|not_eq|nullptr|operator|or|or_eq|private|protected|public|register|reinterpret_cast|requires|restrict|return|short|signed|sizeof|static|static_assert|static_cast|struct|switch|template|this|thread_local|throw|true|try|typedef|typeid|typename|union|unsigned|using|virtual|void|volatile|wchar_t|while|xor|xor_eq|_Alignas|_Alignof|_Atomic|_Bool|_Complex|_Generic|_Imaginary|_Noreturn|_Static_assert|_Thread_local)$', +message(8501, "function '%[name]' matches the name of a C/C++ keyword"))) + -astquery(FunctionDecl() : { + ("|" + getNameAsString() + "|") in "|alignas|alignof|and|and_eq|asm|auto|bitand|bitor|bool|break|case|catch|char|char8_t|char16_t|char32_t|class|compl|concept|const|consteval|constexpr|const_cast|continue|co_await|co_return|co_yield|decltype|default|delete|do|double|dynamic_cast|else|enum|explicit|export|extern|false|float|for|friend|goto|if|inline|int|long|mutable|namespace|new|noexcept|not|not_eq|nullptr|operator|or|or_eq|private|protected|public|register|reinterpret_cast|requires|restrict|return|short|signed|sizeof|static|static_assert|static_cast|struct|switch|template|this|thread_local|throw|true|try|typedef|typeid|typename|union|unsigned|using|virtual|void|volatile|wchar_t|while|xor|xor_eq|_Alignas|_Alignof|_Atomic|_Bool|_Complex|_Generic|_Imaginary|_Noreturn|_Static_assert|_Thread_local|" + message(8501 "function '" currentnode "'matches the name of a C/C++ keyword") + }) +e8501 -append(8501,[BARR-C:2018 Rule 6.1a]) /* 8502 - function has same name as standard library function */ - -hook(func_decl, -cond('%[name]' ~ '^(?:abort|abs|acos|acosf|acosh|acoshf|acoshl|acosl|asctime|asin|asinf|asinh|asinhf|asinhl|asinl|assert|atan|atan2|atan2f|atan2l|atanf|atanh|atanhf|atanhl|atanl|atexit|atof|atoi|atol|atoll|bsearch|btowc|cabs|cabsf|cabsl|cacos|cacosf|cacosh|cacoshf|cacoshl|cacosl|calloc|carg|cargf|cargl|casin|casinf|casinh|casinhf|casinhl|casinl|catan|catanf|catanh|catanhf|catanhl|catanl|cbrt|cbrtf|cbrtl|ccos|ccosf|ccosh|ccoshf|ccoshl|ccosl|ceil|ceilf|ceill|cexp|cexpf|cexpl|cimag|cimagf|cimagl|clearerr|clock|clog|clogf|clogl|conj|conjf|conjl|copysign|copysignf|copysignl|cos|cosf|cosh|coshf|coshl|cosl|cpow|cpowf|cpowl|cproj|cprojf|cprojl|creal|crealf|creall|csin|csinf|csinh|csinhf|csinhl|csinl|csqrt|csqrtf|csqrtl|ctan|ctanf|ctanh|ctanhf|ctanhl|ctanl|ctime|difftime|div|erf|erfc|erfcf|erfcl|erff|erfl|exit|_Exit|exp|exp2|exp2f|exp2l|expf|expl|expm1|expm1f|expm1l|fabs|fabsf|fabsl|fclose|fdim|fdimf|fdiml|feclearexcept|fegetenv|fegetexceptflag|fegetround|feholdexcept|feof|feraiseexcept|ferror|fesetenv|fesetexceptflag|fesetround|fetestexcept|feupdateenv|fflush|fgetc|fgetpos|fgets|fgetwc|fgetws|floor|floorf|floorl|fma|fmaf|fmal|fmax|fmaxf|fmaxl|fmin|fminf|fminl|fmod|fmodf|fmodl|fopen|fpclassify|fprintf|fputc|fputs|fputwc|fputws|fread|free|freopen|frexp|frexpf|frexpl|fscanf|fseek|fsetpos|ftell|fwide|fwprintf|fwrite|fwscanf|getc|getchar|getenv|gets|getwc|getwchar|gmtime|hypot|hypotf|hypotl|ilogb|ilogbf|ilogbl|imaxabs|imaxdiv|isalnum|isalpha|isblank|iscntrl|isdigit|isfinite|isgraph|isgreater|isgreaterequal|isinf|isless|islessequal|islessgreater|islower|isnan|isnormal|isprint|ispunct|isspace|isunordered|isupper|iswalnum|iswalpha|iswblank|iswcntrl|iswctype|iswdigit|iswgraph|iswlower|iswprint|iswpunct|iswspace|iswupper|iswxdigit|isxdigit|labs|ldexp|ldexpf|ldexpl|ldiv|lgamma|lgammaf|lgammal|llabs|lldiv|llrint|llrintf|llrintl|llround|llroundf|llroundl|localeconv|localtime|log|log10|log10f|log10l|log1p|log1pf|log1pl|log2|log2f|log2l|logb|logbf|logbl|logf|logl|longjmp|lrint|lrintf|lrintl|lround|lroundf|lroundl|malloc|mblen|mbrlen|mbrtowc|mbsinit|mbsrtowcs|mbstowcs|mbtowc|memchr|memcmp|memcpy|memmove|memset|mktime|modf|modff|modfl|nan|nanf|nanl|nearbyint|nearbyintf|nearbyintl|nextafter|nextafterf|nextafterl|nexttoward|nexttowardf|nexttowardl|perror|pow|powf|powl|printf|putc|putchar|puts|putwc|putwchar|qsort|raise|rand|realloc|remainder|remainderf|remainderl|remove|remquo|remquof|remquol|rename|rewind|rint|rintf|rintl|round|roundf|roundl|scalbln|scalblnf|scalblnl|scalbn|scalbnf|scalbnl|scanf|setbuf|setjmp|setlocale|setvbuf|signal|signbit|sin|sinf|sinh|sinhf|sinhl|sinl|snprintf|sprintf|sqrt|sqrtf|sqrtl|srand|sscanf|strcat|strchr|strcmp|strcoll|strcpy|strcspn|strerror|strftime|strlen|strncat|strncmp|strncpy|strpbrk|strrchr|strspn|strstr|strtod|strtof|strtoimax|strtok|strtol|strtold|strtoll|strtoul|strtoull|strtoumax|strxfrm|swprintf|swscanf|system|tan|tanf|tanh|tanhf|tanhl|tanl|tgamma|tgammaf|tgammal|time|tmpfile|tmpnam|tolower|toupper|towctrans|towlower|towupper|trunc|truncf|truncl|ungetc|ungetwc|va_arg|va_copy|va_end|va_start|vfprintf|vfscanf|vfwprintf|vfwscanf|vprintf|vscanf|vsnprintf|vsprintf|vsscanf|vswprintf|vswscanf|vwprintf|vwscanf|wcrtomb|wcscat|wcschr|wcscmp|wcscoll|wcscpy|wcscspn|wcsftime|wcslen|wcsncat|wcsncmp|wcsncpy|wcspbrk|wcsrchr|wcsrtombs|wcsspn|wcsstr|wcstod|wcstof|wcstoimax|wcstok|wcstol|wcstold|wcstoll|wcstombs|wcstoul|wcstoull|wcstoumax|wcsxfrm|wctob|wctomb|wctrans|wctype|wmemchr|wmemcmp|wmemcpy|wmemmove|wmemset|wprintf|wscanf)$', +message(8502, "function '%[name]' matches the name of a standard library function"))) + -astquery(FunctionDecl() : { + ("|" + getNameAsString() + "|") in "|abort|abs|acos|acosf|acosh|acoshf|acoshl|acosl|asctime|asin|asinf|asinh|asinhf|asinhl|asinl|assert|atan|atan2|atan2f|atan2l|atanf|atanh|atanhf|atanhl|atanl|atexit|atof|atoi|atol|atoll|bsearch|btowc|cabs|cabsf|cabsl|cacos|cacosf|cacosh|cacoshf|cacoshl|cacosl|calloc|carg|cargf|cargl|casin|casinf|casinh|casinhf|casinhl|casinl|catan|catanf|catanh|catanhf|catanhl|catanl|cbrt|cbrtf|cbrtl|ccos|ccosf|ccosh|ccoshf|ccoshl|ccosl|ceil|ceilf|ceill|cexp|cexpf|cexpl|cimag|cimagf|cimagl|clearerr|clock|clog|clogf|clogl|conj|conjf|conjl|copysign|copysignf|copysignl|cos|cosf|cosh|coshf|coshl|cosl|cpow|cpowf|cpowl|cproj|cprojf|cprojl|creal|crealf|creall|csin|csinf|csinh|csinhf|csinhl|csinl|csqrt|csqrtf|csqrtl|ctan|ctanf|ctanh|ctanhf|ctanhl|ctanl|ctime|difftime|div|erf|erfc|erfcf|erfcl|erff|erfl|exit|_Exit|exp|exp2|exp2f|exp2l|expf|expl|expm1|expm1f|expm1l|fabs|fabsf|fabsl|fclose|fdim|fdimf|fdiml|feclearexcept|fegetenv|fegetexceptflag|fegetround|feholdexcept|feof|feraiseexcept|ferror|fesetenv|fesetexceptflag|fesetround|fetestexcept|feupdateenv|fflush|fgetc|fgetpos|fgets|fgetwc|fgetws|floor|floorf|floorl|fma|fmaf|fmal|fmax|fmaxf|fmaxl|fmin|fminf|fminl|fmod|fmodf|fmodl|fopen|fpclassify|fprintf|fputc|fputs|fputwc|fputws|fread|free|freopen|frexp|frexpf|frexpl|fscanf|fseek|fsetpos|ftell|fwide|fwprintf|fwrite|fwscanf|getc|getchar|getenv|gets|getwc|getwchar|gmtime|hypot|hypotf|hypotl|ilogb|ilogbf|ilogbl|imaxabs|imaxdiv|isalnum|isalpha|isblank|iscntrl|isdigit|isfinite|isgraph|isgreater|isgreaterequal|isinf|isless|islessequal|islessgreater|islower|isnan|isnormal|isprint|ispunct|isspace|isunordered|isupper|iswalnum|iswalpha|iswblank|iswcntrl|iswctype|iswdigit|iswgraph|iswlower|iswprint|iswpunct|iswspace|iswupper|iswxdigit|isxdigit|labs|ldexp|ldexpf|ldexpl|ldiv|lgamma|lgammaf|lgammal|llabs|lldiv|llrint|llrintf|llrintl|llround|llroundf|llroundl|localeconv|localtime|log|log10|log10f|log10l|log1p|log1pf|log1pl|log2|log2f|log2l|logb|logbf|logbl|logf|logl|longjmp|lrint|lrintf|lrintl|lround|lroundf|lroundl|malloc|mblen|mbrlen|mbrtowc|mbsinit|mbsrtowcs|mbstowcs|mbtowc|memchr|memcmp|memcpy|memmove|memset|mktime|modf|modff|modfl|nan|nanf|nanl|nearbyint|nearbyintf|nearbyintl|nextafter|nextafterf|nextafterl|nexttoward|nexttowardf|nexttowardl|perror|pow|powf|powl|printf|putc|putchar|puts|putwc|putwchar|qsort|raise|rand|realloc|remainder|remainderf|remainderl|remove|remquo|remquof|remquol|rename|rewind|rint|rintf|rintl|round|roundf|roundl|scalbln|scalblnf|scalblnl|scalbn|scalbnf|scalbnl|scanf|setbuf|setjmp|setlocale|setvbuf|signal|signbit|sin|sinf|sinh|sinhf|sinhl|sinl|snprintf|sprintf|sqrt|sqrtf|sqrtl|srand|sscanf|strcat|strchr|strcmp|strcoll|strcpy|strcspn|strerror|strftime|strlen|strncat|strncmp|strncpy|strpbrk|strrchr|strspn|strstr|strtod|strtof|strtoimax|strtok|strtol|strtold|strtoll|strtoul|strtoull|strtoumax|strxfrm|swprintf|swscanf|system|tan|tanf|tanh|tanhf|tanhl|tanl|tgamma|tgammaf|tgammal|time|tmpfile|tmpnam|tolower|toupper|towctrans|towlower|towupper|trunc|truncf|truncl|ungetc|ungetwc|va_arg|va_copy|va_end|va_start|vfprintf|vfscanf|vfwprintf|vfwscanf|vprintf|vscanf|vsnprintf|vsprintf|vsscanf|vswprintf|vswscanf|vwprintf|vwscanf|wcrtomb|wcscat|wcschr|wcscmp|wcscoll|wcscpy|wcscspn|wcsftime|wcslen|wcsncat|wcsncmp|wcsncpy|wcspbrk|wcsrchr|wcsrtombs|wcsspn|wcsstr|wcstod|wcstof|wcstoimax|wcstok|wcstol|wcstold|wcstoll|wcstombs|wcstoul|wcstoull|wcstoumax|wcsxfrm|wctob|wctomb|wctrans|wctype|wmemchr|wmemcmp|wmemcpy|wmemmove|wmemset|wprintf|wscanf|" + message(8502 "function '" currentnode "' matches the name of a standard library function") + }) +e8502 -append(8502,[BARR-C:2018 Rule 6.1b]) /* 8503 - function has name that begins with an underscore */ - -hook(func_decl, -cond('%[name]' ~ '^_', +message(8503, "function '%[name]' begins with an underscore"))) + -astquery(FunctionDecl : { + getNameAsString().startsWith("_") + message(8503 "function '" currentnode "' begins with an underscore") + }) +e8503 -append(8503,[BARR-C:2018 Rule 6.1c]) /* 8504 - function name is longer than 31 characters */ - -hook(func_decl, -cond('%[name]' ~ '.{32,}', +message(8504, "function '%[name]' is longer than 31 characters"))) + -astquery(FunctionDecl : { + getNameAsString().length() > 31 + message(8504 "function '" currentnode "' is longer than 31 characters") + }) +e8504 -append(8504,[BARR-C:2018 Rule 6.1d]) /* 8505 - function name contains upper case letter(s) */ - -hook(func_decl, -cond('%[name]' ~ '[[:upper:]]', +message(8505, "function '%[name]' contains uppercase letters"))) + -astquery(FunctionDecl : { + getNameAsString() ~~ "[[:upper:]]" + message(8505 "function '" currentnode "' contains uppercase letters") + }) +e8505 -append(8505,[BARR-C:2018 Rule 6.1e]) @@ -465,60 +496,90 @@ /* not currently supported */ -// ========== VARIABLES ========== +//========== VARIABLES ========== // 7.1 Naming Conventions /* 8507 - variable has name that matches a keyword in C or C++ */ - -hook(var_decl, -cond('%[name]' ~ '^(?Palignas|alignof|and|and_eq|asm|auto|bitand|bitor|bool|break|case|catch|char|char8_t|char16_t|char32_t|class|compl|concept|const|consteval|constexpr|const_cast|continue|co_await|co_return|co_yield|decltype|default|delete|do|double|dynamic_cast|else|enum|explicit|export|extern|false|float|for|fortran|friend|goto|if|inline|int|interrupt|long|mutable|namespace|new|noexcept|not|not_eq|nullptr|operator|or|or_eq|private|protected|public|register|reinterpret_cast|requires|restrict|return|short|signed|sizeof|static|static_assert|static_cast|struct|switch|template|this|thread_local|throw|true|try|typedef|typeid|typename|union|unsigned|using|virtual|void|volatile|wchar_t|while|xor|xor_eq|_Alignas|_Alignof|_Atomic|_Bool|_Complex|_Generic|_Imaginary|_Noreturn|_Static_assert|_Thread_local)$', +message(8507, "variable '%[name]' matches the name of a C/C++ keyword"))) + -astquery(VarDecl : { + ("|" + getNameAsString() + "|") in "|alignas|alignof|and|and_eq|asm|auto|bitand|bitor|bool|break|case|catch|char|char8_t|char16_t|char32_t|class|compl|concept|const|consteval|constexpr|const_cast|continue|co_await|co_return|co_yield|decltype|default|delete|do|double|dynamic_cast|else|enum|explicit|export|extern|false|float|for|fortran|friend|goto|if|inline|int|interrupt|long|mutable|namespace|new|noexcept|not|not_eq|nullptr|operator|or|or_eq|private|protected|public|register|reinterpret_cast|requires|restrict|return|short|signed|sizeof|static|static_assert|static_cast|struct|switch|template|this|thread_local|throw|true|try|typedef|typeid|typename|union|unsigned|using|virtual|void|volatile|wchar_t|while|xor|xor_eq|_Alignas|_Alignof|_Atomic|_Bool|_Complex|_Generic|_Imaginary|_Noreturn|_Static_assert|_Thread_local|" + message(8507 "variable '" currentnode "' matches the name of a C/C++ keyword") + }) +e8507 -append(8507,[BARR-C:2018 Rule 7.1a]) /* 8525 - variable has same name as standard library variable */ - -hook(var_decl, -cond('%[name]' ~ '^(?:errno|stderr|stdin|stdout)$', - +message(8525, "variale '%[name]' matches the same name of a standard library variable"))) + -astquery(VarDecl : { + ("|" + getNameAsString() + "|") in "|errno|stderr|stdin|stdout|" + message(8525 "variable '" currentnode "' matches the same name of a standard library variable") + }) +e8525 -append(8525,[BARR-C:2018 Rule 7.1b]) /* 8508 - variable has name that begins with an underscore */ - -hook(var_decl, -cond('%[name]' ~ '^_', +message(8508, "variable '%[name]' begins with an underscore"))) + -astquery(VarDecl : { + getNameAsString().startsWith("_") + message(8508 "variable '" currentnode "' begins with an underscore") + }) +e8508 -append(8508,[BARR-C:2018 Rule 7.1c]) /* 8509 - variable name is longer than 31 characters */ - -hook(var_decl, -cond('%[name]' ~ '.{32,}', +message(8509, "variable '%[name]' is longer than 31 characters"))) + -astquery(VarDecl : { + getNameAsString().length() > 31 + message(8509 "variable '" currentnode "' is longer than 31 characters") + }) +e8509 - -append(8509,[BARR-C:2018 Rule 6.1d]) + -append(8509,[BARR-C:2018 Rule 7.1d]) /* 8510 - variable name contains less than 3 characters */ - -hook(var_decl, -cond('%[name]' ~ '^.{1,2}$', +message(8510, "variable '%[name]' contains less than 3 characters"))) + -astquery(VarDecl : { + getNameAsString().length() < 3 + message(8510 "variable '" currentnode "' contains less than 3 characters") + }) +e8510 -append(8510,[BARR-C:2018 Rule 7.1e]) /* 8511 - variable name contains upper case letter(s) */ - -hook(var_decl, -cond('%[name]' ~ '[[:upper:]]', +message(8511, "variable '%[name]' contains uppercase letters"))) + -astquery(VarDecl : { + getNameAsString() ~~ "[[:upper:]]" + message(8511 "variable '" currentnode "' contains uppercase letters") + }) +e8511 -append(8511,[BARR-C:2018 Rule 7.1f]) /* 8512 - global variable must start with 'g' */ - -hook(var_decl, -cond('%[linkage]' == 'external' && !('%[name]' ~ '^g'), +message(8512, "global variable '%[name]' should have 'g' prefix"))) + -astquery(VarDecl() : { + hasExternalFormalLinkage() + not getNameAsString().startsWith("g") + message(8512 "global variable '" currentnode "' should have 'g' prefix") + }) +e8512 -append(8512,[BARR-C:2018 Rule 7.1j]) /* 8513 - variable of pointer type should have 'p' prefix */ /* 8514 - variable of pointer type should have 'pp' prefix */ - -hook(var_decl, -cond('%[walk_type.is_pointer]' == 'true', - -cond('%[walk_type.walk_pointee.is_pointer]' == 'true', - -cond(!('%[name]' ~ '^g?pp'), +message(8513, "variable '%[name]' of type '%[walk_type.as_string]' should have 'pp' prefix")), - -cond(!('%[name]' ~ '^g?p'), +message(8514, "variable '%[name]' of type '%[walk_type.as_string]' should have 'p' prefix")) - ))) + -astquery(VarDecl() : { + getType().isPointerType() + if (getType().getPointeeType().isPointerType) { + not getNameAsString().startsWith("pp") + message(8514 "variable '" currentnode "' of type '" getType() "' should have 'pp' prefix") + } else { + not getNameAsString().startsWith("p") + message(8513 "variable '" currentnode "' of type '" getType() "' should have 'p' prefix") + } + }) +e8513 +e8514 -append(8513,[BARR-C:2018 Rule 7.1k]) -append(8514,[BARR-C:2018 Rule 7.1l]) /* 8515 - boolean variable should have 'b' prefix */ - -hook(var_decl, -cond('%[walk_type.is_boolean]' == 'true' && !('%[name]' ~ '^g?b'), +message(8515, "boolean variable '%[name]' should have 'b' prefix"))) + -astquery(VarDecl: { + getType.isBooleanType() + not getNameAsString().startsWith("b") + message(8515 "boolean variable '" currentnode "' should have 'b' prefix") + }) +e8515 -append(8515,[BARR-C:2018 Rule 7.1m]) @@ -564,7 +625,7 @@ +e785 -append(785,[BARR-C:2018 Rule 7.2a]) -// ========== STATEMENT RULES ========== +//========== STATEMENT RULES ========== // 8.1 Variable Declarations @@ -625,9 +686,11 @@ // 8.6 Equivalence Test /* 8522 - variable should appear on RHS of '==' operator */ - -hook(binary_expr, -cond('%[opcode]' == '==' && - '%[walk_lhs_expr.walk_past_paren_cast.set_msg_loc.is_decl_ref_expr]' == 'true' && - '%[walk_rhs_expr.is_constant_expr]' == 'true', - +message(8522, "variable '%[walk_lhs_expr.walk_past_paren_cast.walk_decl.qual_name]' should appear on RHS of '==' operator"))) + -astquery(BinaryOperator() : { + getOpcodeStr() == "==" + $decl_ref = getLHS().ignoreParenCasts().DeclRefExpr() + $decl_ref && getRHS().isConstantExpr() + message(8522 "variable '" $decl_ref.getDecl() "' should appear on RHS of '==' operator") + }) +e8522 -append(8522,[BARR-C:2018 Rule 8.6a]) diff --git a/ports/lint-plus/au-misra3-amd1.lnt b/ports/lint-plus/au-misra3-amd1.lnt deleted file mode 100644 index a703363d..00000000 --- a/ports/lint-plus/au-misra3-amd1.lnt +++ /dev/null @@ -1,266 +0,0 @@ -// --------------------------------------------------------------------------- -// Copyright Gimpel Software LLC 2020. All rights reserved. -// -// This file is provided by Gimpel Software LLC (https://www.gimpel.com) for -// use with PC-lint Plus. Redistribution is permitted but any redistribution -// must preserve this notice and, if the redistributed file has been modified, -// provide notice that the file has been modified from the original. -// --------------------------------------------------------------------------- - -// au-misra3-amd1.lnt -- Author options - MISRA C 2012 - -/* - This options file can be used to explicitly activate those - checks advocated by the Motor Industry Software Reliability - Association. - - You can use this file directly when linting your programs as in: - - lint au-misra3-amd1.lnt hello.c - - Note that this file does not enable checking for the base MISRA C 2012 - guidelines. Typical use will include au-misra3.lnt, e.g.: - - lint au-misra3.lnt au-misra3-amd1.lnt hello.c - - Gimpel Software relies on the document, "MISRA C:2012 Amendment 1 - Additional security guidelines for MISRA C:2012" - copyright 2016 by HORIBA MIRA Ltd, as the primary source for this - file. Gimpel Software makes no warranty as to the completeness - or applicability of this options file and reserves the right to - amend or alter the official contents of such at any time. - - "MISRA" is a registered trademark of HORIBA MIRA Ltd, held on - behalf of the MISRA Consortium. - - */ - -/* version check */ -cond('%PCLP_NO_LNT_VERSION_CHECK%' != '1' && (%LINT_MAJOR_VERSION% != 1 || %LINT_MINOR_VERSION% != 4), - +fatal_error(This configuration file is intended for PC-lint Plus 1.4. - You are attempting to use it with PC-lint Plus %LINT_MAJOR_VERSION%.%LINT_MINOR_VERSION%. - It is recommended that you use configuration files intended - for PC-lint Plus %LINT_MAJOR_VERSION%.%LINT_MINOR_VERSION%.) -) - - -/**** Dir 4.14 (Req) ************/ - - /* Not currently supported */ - -/**** Rule 12.5 (Mand) ************/ - - +e682 /* sizeof applied to parameter whose type is sized array */ - +elib(682) - -append(682,[MISRA 2012 Rule 12.5, mandatory]) - - +e882 /* sizeof applied to parameter declared as incomplete array */ - +elib(882) - -append(882,[MISRA 2012 Rule 12.5, mandatory]) - -/**** Rule 21.13 (Mand) ************/ - - /* While MISRA has declared this rule to be "undecidable", Gimpel - * Software provides the following options to assist: - */ - - /* Define EOF until a proper definition is seen */ - -dEOF=-1 - - /* Define UCHAR_MIN and UCHAR_MAX if no definition available */ - -dUCHAR_MIN=0 - -dUCHAR_MAX=255 - - /* Ensure macro versions of ctype.h functions expand to function versions - to make use of the function semantics defined below */ - --uisalnum - --uisalpha - --uisblank - --uiscntrl - --uisdigit - --uisgraph - --uislower - --uisprint - --uispunct - --uisspace - --uisupper - --uisxdigit - --utolower - --utoupper - - /* Define semantics for ctype.h functions */ - -sem(isalnum, (1n >= UCHAR_MIN && 1n <= UCHAR_MAX) || 1n == EOF) - -sem(isalpha, (1n >= UCHAR_MIN && 1n <= UCHAR_MAX) || 1n == EOF) - -sem(isblank, (1n >= UCHAR_MIN && 1n <= UCHAR_MAX) || 1n == EOF) - -sem(iscntrl, (1n >= UCHAR_MIN && 1n <= UCHAR_MAX) || 1n == EOF) - -sem(isdigit, (1n >= UCHAR_MIN && 1n <= UCHAR_MAX) || 1n == EOF) - -sem(isgraph, (1n >= UCHAR_MIN && 1n <= UCHAR_MAX) || 1n == EOF) - -sem(islower, (1n >= UCHAR_MIN && 1n <= UCHAR_MAX) || 1n == EOF) - -sem(isprint, (1n >= UCHAR_MIN && 1n <= UCHAR_MAX) || 1n == EOF) - -sem(ispunct, (1n >= UCHAR_MIN && 1n <= UCHAR_MAX) || 1n == EOF) - -sem(isspace, (1n >= UCHAR_MIN && 1n <= UCHAR_MAX) || 1n == EOF) - -sem(isupper, (1n >= UCHAR_MIN && 1n <= UCHAR_MAX) || 1n == EOF) - -sem(isxdigit, (1n >= UCHAR_MIN && 1n <= UCHAR_MAX) || 1n == EOF) - -sem(tolower, (1n >= UCHAR_MIN && 1n <= UCHAR_MAX) || 1n == EOF) - -sem(toupper, (1n >= UCHAR_MIN && 1n <= UCHAR_MAX) || 1n == EOF) - - +esym(426, isalnum) - +esym(426, isalpha) - +esym(426, isblank) - +esym(426, iscntrl) - +esym(426, isdigit) - +esym(426, isgraph) - +esym(426, islower) - +esym(426, isprint) - +esym(426, ispunct) - +esym(426, isspace) - +esym(426, isupper) - +esym(426, isxdigit) - +esym(426, tolower) - +esym(426, toupper) - - -append(426(isalnum), value passed to isalnum is not representable as unsigned char and is not EOF) - -append(426(isalnum),[MISRA 2012 Rule 21.13, mandatory]) - - -append(426(isalpha), value passed to isalpha is not representable as unsigned char and is not EOF) - -append(426(isalpha),[MISRA 2012 Rule 21.13, mandatory]) - - -append(426(isblank), value passed to isblank is not representable as unsigned char and is not EOF) - -append(426(isblank),[MISRA 2012 Rule 21.13, mandatory]) - - -append(426(iscntrl), value passed to iscntrl is not representable as unsigned char and is not EOF) - -append(426(iscntrl),[MISRA 2012 Rule 21.13, mandatory]) - - -append(426(isdigit), value passed to isdigit is not representable as unsigned char and is not EOF) - -append(426(isdigit),[MISRA 2012 Rule 21.13, mandatory]) - - -append(426(isgraph), value passed to isgraph is not representable as unsigned char and is not EOF) - -append(426(isgraph),[MISRA 2012 Rule 21.13, mandatory]) - - -append(426(islower), value passed to islower is not representable as unsigned char and is not EOF) - -append(426(islower),[MISRA 2012 Rule 21.13, mandatory]) - - -append(426(isprint), value passed to isprint is not representable as unsigned char and is not EOF) - -append(426(isprint),[MISRA 2012 Rule 21.13, mandatory]) - - -append(426(ispunct), value passed to ispunct is not representable as unsigned char and is not EOF) - -append(426(ispunct),[MISRA 2012 Rule 21.13, mandatory]) - - -append(426(isspace), value passed to isspace is not representable as unsigned char and is not EOF) - -append(426(isspace),[MISRA 2012 Rule 21.13, mandatory]) - - -append(426(isupper), value passed to isupper is not representable as unsigned char and is not EOF) - -append(426(isupper),[MISRA 2012 Rule 21.13, mandatory]) - - -append(426(isxdigit), value passed to isxdigit is not representable as unsigned char and is not EOF) - -append(426(isxdigit),[MISRA 2012 Rule 21.13, mandatory]) - - -append(426(tolower), value passed to tolower is not representable as unsigned char and is not EOF) - -append(426(tolower),[MISRA 2012 Rule 21.13, mandatory]) - - -append(426(toupper), value passed to toupper is not representable as unsigned char and is not EOF) - -append(426(toupper),[MISRA 2012 Rule 21.13, mandatory]) - -/**** Rule 21.14 (Req) ************/ - - /* Not currently supported */ - -/**** Rule 21.15 (Req) ************/ - - +e857 /* incompatible pointer arguments to memcpy/memmove/memcmp */ - +elib(857) - -append(857,[MISRA 2012 Rule 21.15, required]) - -/**** Rule 21.16 (Req) ************/ - - +e9098 /* pointer argument to memcmp does not point to a pointer type - or an essentially signed, unsigned, boolean, or enum type */ - +elib(9098) - -append(9098,[MISRA 2012 Rule 21.16, required]) - -/**** Rule 21.17 (Mand) ************/ - - /* While MISRA has declared this rule to be "undecidable", Gimpel - * Software provides the following options to assist: - */ - - /* 419 - apparent data overrun for function */ - /* 420 - apparent access beyond array for function */ - - +esym(419 420, strcat, strcpy) - -append(419(strcat),[MISRA 2012 Rule 21.17, mandatory]) - -append(420(strcat),[MISRA 2012 Rule 21.17, mandatory]) - -append(419(strcpy),[MISRA 2012 Rule 21.17, mandatory]) - -append(420(strcpy),[MISRA 2012 Rule 21.17, mandatory]) - -/**** Rule 21.18 (Mand) ************/ - - /* While MISRA has declared this rule to be "undecidable", Gimpel - * Software provides the following options to assist: - */ - - /* 419 - apparent data overrun for function */ - /* 420 - apparent access beyond array for function */ - /* 422 - function passed a negative value */ - - +esym(419 420 422, memchr, memcmp, memcpy, memmove, memset) - +esym(419 420 422, strncat, strncmp, strncpy, strxfrm) - - /* PC-lint Plus will issue 419 when it can determine that - * the size parameter of the below functions exceeds the - * size of the buffer that is being written to. - */ - - -append(419(memcpy),[MISRA 2012 Rule 21.18, mandatory]) - -append(419(memmove),[MISRA 2012 Rule 21.18, mandatory]) - -append(419(strncat),[MISRA 2012 Rule 21.18, mandatory]) - -append(419(strncpy),[MISRA 2012 Rule 21.18, mandatory]) - - /* PC-lint Plus will issue 420 when it can determine that - * the size parameter of the below functions exceeds the - * size of the buffer that is being read from. - */ - - -append(420(memchr),[MISRA 2012 Rule 21.18, mandatory]) - -append(420(memcmp),[MISRA 2012 Rule 21.18, mandatory]) - -append(420(memcpy),[MISRA 2012 Rule 21.18, mandatory]) - -append(420(memmove),[MISRA 2012 Rule 21.18, mandatory]) - - /* PC-lint Plus will issue 422 when it can determine that - * a negative value is being passed to the size parameter - * of the below functions. - */ - - -append(422(memchr),[MISRA 2012 Rule 21.18, mandatory]) - -append(422(memcmp),[MISRA 2012 Rule 21.18, mandatory]) - -append(422(memcpy),[MISRA 2012 Rule 21.18, mandatory]) - -append(422(memmove),[MISRA 2012 Rule 21.18, mandatory]) - -append(422(memset),[MISRA 2012 Rule 21.18, mandatory]) - -append(422(strncat),[MISRA 2012 Rule 21.18, mandatory]) - -append(422(strncmp),[MISRA 2012 Rule 21.18, mandatory]) - -append(422(strncpy),[MISRA 2012 Rule 21.18, mandatory]) - -append(422(strxfrm),[MISRA 2012 Rule 21.18, mandatory]) - -/**** Rule 21.19 (Mand) ************/ - - /* Not currently supported */ - -/**** Rule 21.20 (Mand) ************/ - - /* Not currently supported */ - -/**** Rule 22.7 (Req) ************/ - - /* Not currently supported */ - -/**** Rule 22.8 (Req) ************/ - - /* Not currently supported */ - -/**** Rule 22.9 (Req) ************/ - - /* Not currently supported */ - -/**** Rule 22.10 (Req) ************/ - - /* Not currently supported */ - diff --git a/ports/lint-plus/au-misra3-amd2.lnt b/ports/lint-plus/au-misra3-amd2.lnt deleted file mode 100644 index cf54b2dd..00000000 --- a/ports/lint-plus/au-misra3-amd2.lnt +++ /dev/null @@ -1,431 +0,0 @@ -// --------------------------------------------------------------------------- -// Copyright Gimpel Software LLC 2020. All rights reserved. -// -// This file is provided by Gimpel Software LLC (https://www.gimpel.com) for -// use with PC-lint Plus. Redistribution is permitted but any redistribution -// must preserve this notice and, if the redistributed file has been modified, -// provide notice that the file has been modified from the original. -// --------------------------------------------------------------------------- - -// au-misra3-amd2.lnt -- Author options - MISRA C 2012 - -/* - This options file can be used to explicitly activate those - checks advocated by the Motor Industry Software Reliability - Association. - - You can use this file directly when linting your programs as in: - - lint au-misra3-amd2.lnt hello.c - - Note that this file does not enable checking for the base MISRA C 2012 - guidelines. Typical use will include au-misra3.lnt, e.g.: - - lint au-misra3.lnt au-misra3-amd2.lnt hello.c - - To include checking of rules introduced in both AMD-1 and AMD-2, use: - - lint au-misra3.lnt au-misra3-amd1.lnt au-misra3-amd2.lnt hello.c - - Gimpel Software relies on the document, "MISRA C:2012 Amendment 2 - Updates for ISO/IEC 9899:2011 Core functionality" - copyright 2020 by HORIBA MIRA Ltd, as the primary source for this - file. Gimpel Software makes no warranty as to the completeness - or applicability of this options file and reserves the right to - amend or alter the official contents of such at any time. - - "MISRA" is a registered trademark of HORIBA MIRA Ltd, held on - behalf of the MISRA Consortium. - - */ - -/* version check */ -cond('%PCLP_NO_LNT_VERSION_CHECK%' != '1' && (%LINT_MAJOR_VERSION% != 1 || %LINT_MINOR_VERSION% != 4), - +fatal_error(This configuration file is intended for PC-lint Plus 1.4. - You are attempting to use it with PC-lint Plus %LINT_MAJOR_VERSION%.%LINT_MINOR_VERSION%. - It is recommended that you use configuration files intended - for PC-lint Plus %LINT_MAJOR_VERSION%.%LINT_MINOR_VERSION%.) -) - - - -/**** Rule 1.4 (Req) ************/ - - +e586 /* to activate the deprecation message */ - +elib(586) - - /* C11 Keywords */ - -deprecate(keyword,_Alignas,[MISRA 2012 Rule 1.4, required]) - -deprecate(keyword,_Alignof,[MISRA 2012 Rule 1.4, required]) - -deprecate(keyword,_Atomic,[MISRA 2012 Rule 1.4, required]) - -deprecate(keyword,_Generic,[MISRA 2012 Rule 1.4, required]) - -deprecate(keyword,_Noreturn,[MISRA 2012 Rule 1.4, required]) - -deprecate(keyword,_Thread_local,[MISRA 2012 Rule 1.4, required]) - - /* Facilities provided by the header file */ - -deprecate(macro,ATOMIC_BOOL_LOCK_FREE,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,ATOMIC_CHAR16_T_LOCK_FREE,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,ATOMIC_CHAR32_T_LOCK_FREE,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,ATOMIC_CHAR_LOCK_FREE,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,ATOMIC_FLAG_INIT,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,ATOMIC_INT_LOCK_FREE,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,ATOMIC_LLONG_LOCK_FREE,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,ATOMIC_LONG_LOCK_FREE,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,ATOMIC_POINTER_LOCK_FREE,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,ATOMIC_SHORT_LOCK_FREE,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,ATOMIC_VAR_INIT,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,ATOMIC_WCHAR_T_LOCK_FREE,[MISRA 2012 Rule 1.4, required]) - - -deprecate(function,atomic_init,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,atomic_init,[MISRA 2012 Rule 1.4, required]) - - -deprecate(type,enum memory_order,[MISRA 2012 Rule 1.4, required]) - -deprecate(type,memory_order,[MISRA 2012 Rule 1.4, required]) - - -deprecate(type,atomic_flag,[MISRA 2012 Rule 1.4, required]) - -deprecate(type,struct atomic_flag,[MISRA 2012 Rule 1.4, required]) - - -deprecate(macro,kill_dependency,[MISRA 2012 Rule 1.4, required]) - - -deprecate(function,atomic_compare_exchange_strong,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,atomic_compare_exchange_strong_explicit,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,atomic_compare_exchange_weak,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,atomic_compare_exchange_weak_explicit,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,atomic_exchange,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,atomic_exchange_explicit,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,atomic_fetch_add,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,atomic_fetch_add_explicit,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,atomic_fetch_and,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,atomic_fetch_and_explicit,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,atomic_fetch_or,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,atomic_fetch_or_explicit,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,atomic_fetch_sub,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,atomic_fetch_sub_explicit,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,atomic_fetch_xor,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,atomic_fetch_xor_explicit,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,atomic_flag_clear,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,atomic_flag_clear_explicit,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,atomic_flag_test_and_set,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,atomic_flag_test_and_set_explicit,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,atomic_is_lock_free,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,atomic_load,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,atomic_load_explicit,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,atomic_signal_fence,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,atomic_store,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,atomic_store_explicit,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,atomic_thread_fence,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,atomic_compare_exchange_strong,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,atomic_compare_exchange_strong_explicit,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,atomic_compare_exchange_weak,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,atomic_compare_exchange_weak_explicit,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,atomic_exchange,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,atomic_exchange_explicit,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,atomic_fetch_add,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,atomic_fetch_add_explicit,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,atomic_fetch_and,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,atomic_fetch_and_explicit,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,atomic_fetch_or,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,atomic_fetch_or_explicit,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,atomic_fetch_sub,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,atomic_fetch_sub_explicit,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,atomic_fetch_xor,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,atomic_fetch_xor_explicit,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,atomic_flag_clear,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,atomic_flag_clear_explicit,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,atomic_flag_test_and_set,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,atomic_flag_test_and_set_explicit,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,atomic_is_lock_free,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,atomic_load,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,atomic_load_explicit,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,atomic_signal_fence,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,atomic_store,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,atomic_store_explicit,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,atomic_thread_fence,[MISRA 2012 Rule 1.4, required]) - - -deprecate(type,atomic_bool,[MISRA 2012 Rule 1.4, required]) - -deprecate(type,atomic_char,[MISRA 2012 Rule 1.4, required]) - -deprecate(type,atomic_char16_t,[MISRA 2012 Rule 1.4, required]) - -deprecate(type,atomic_char32_t,[MISRA 2012 Rule 1.4, required]) - -deprecate(type,atomic_int,[MISRA 2012 Rule 1.4, required]) - -deprecate(type,atomic_int_fast16_t,[MISRA 2012 Rule 1.4, required]) - -deprecate(type,atomic_int_fast32_t,[MISRA 2012 Rule 1.4, required]) - -deprecate(type,atomic_int_fast64_t,[MISRA 2012 Rule 1.4, required]) - -deprecate(type,atomic_int_fast8_t,[MISRA 2012 Rule 1.4, required]) - -deprecate(type,atomic_int_least16_t,[MISRA 2012 Rule 1.4, required]) - -deprecate(type,atomic_int_least32_t,[MISRA 2012 Rule 1.4, required]) - -deprecate(type,atomic_int_least64_t,[MISRA 2012 Rule 1.4, required]) - -deprecate(type,atomic_int_least8_t,[MISRA 2012 Rule 1.4, required]) - -deprecate(type,atomic_intmax_t,[MISRA 2012 Rule 1.4, required]) - -deprecate(type,atomic_intptr_t,[MISRA 2012 Rule 1.4, required]) - -deprecate(type,atomic_llong,[MISRA 2012 Rule 1.4, required]) - -deprecate(type,atomic_long,[MISRA 2012 Rule 1.4, required]) - -deprecate(type,atomic_ptrdiff_t,[MISRA 2012 Rule 1.4, required]) - -deprecate(type,atomic_schar,[MISRA 2012 Rule 1.4, required]) - -deprecate(type,atomic_short,[MISRA 2012 Rule 1.4, required]) - -deprecate(type,atomic_size_t,[MISRA 2012 Rule 1.4, required]) - -deprecate(type,atomic_uchar,[MISRA 2012 Rule 1.4, required]) - -deprecate(type,atomic_uint,[MISRA 2012 Rule 1.4, required]) - -deprecate(type,atomic_uint_fast16_t,[MISRA 2012 Rule 1.4, required]) - -deprecate(type,atomic_uint_fast32_t,[MISRA 2012 Rule 1.4, required]) - -deprecate(type,atomic_uint_fast64_t,[MISRA 2012 Rule 1.4, required]) - -deprecate(type,atomic_uint_fast8_t,[MISRA 2012 Rule 1.4, required]) - -deprecate(type,atomic_uint_least16_t,[MISRA 2012 Rule 1.4, required]) - -deprecate(type,atomic_uint_least32_t,[MISRA 2012 Rule 1.4, required]) - -deprecate(type,atomic_uint_least64_t,[MISRA 2012 Rule 1.4, required]) - -deprecate(type,atomic_uint_least8_t,[MISRA 2012 Rule 1.4, required]) - -deprecate(type,atomic_uintmax_t,[MISRA 2012 Rule 1.4, required]) - -deprecate(type,atomic_uintptr_t,[MISRA 2012 Rule 1.4, required]) - -deprecate(type,atomic_ullong,[MISRA 2012 Rule 1.4, required]) - -deprecate(type,atomic_ulong,[MISRA 2012 Rule 1.4, required]) - -deprecate(type,atomic_ushort,[MISRA 2012 Rule 1.4, required]) - -deprecate(type,atomic_wchar_t,[MISRA 2012 Rule 1.4, required]) - - /* Facilities provided by the header file */ - -deprecate(macro,ONCE_FLAG_INIT,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,TSS_DTOR_ITERATIONS,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,thread_local,[MISRA 2012 Rule 1.4, required]) - - -deprecate(type,cnd_t,[MISRA 2012 Rule 1.4, required]) - -deprecate(type,mtx_t,[MISRA 2012 Rule 1.4, required]) - -deprecate(type,once_flag,[MISRA 2012 Rule 1.4, required]) - -deprecate(type,thrd_start_t,[MISRA 2012 Rule 1.4, required]) - -deprecate(type,thrd_t,[MISRA 2012 Rule 1.4, required]) - -deprecate(type,tss_dtor_t,[MISRA 2012 Rule 1.4, required]) - -deprecate(type,tss_t,[MISRA 2012 Rule 1.4, required]) - - -deprecate(function,call_once,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,cnd_broadcast,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,cnd_destroy,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,cnd_init,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,cnd_signal,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,cnd_timedwait,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,cnd_wait,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,mtx_destroy,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,mtx_init,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,mtx_lock,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,mtx_timedlock,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,mtx_trylock,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,mtx_unlock,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,thrd_create,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,thrd_current,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,thrd_detach,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,thrd_equal,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,thrd_exit,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,thrd_join,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,thrd_sleep,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,thrd_yield,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,tss_create,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,tss_delete,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,tss_get,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,tss_set,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,call_once,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,cnd_broadcast,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,cnd_destroy,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,cnd_init,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,cnd_signal,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,cnd_timedwait,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,cnd_wait,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,mtx_destroy,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,mtx_init,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,mtx_lock,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,mtx_timedlock,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,mtx_trylock,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,mtx_unlock,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,thrd_create,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,thrd_current,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,thrd_detach,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,thrd_equal,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,thrd_exit,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,thrd_join,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,thrd_sleep,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,thrd_yield,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,tss_create,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,tss_delete,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,tss_get,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,tss_set,[MISRA 2012 Rule 1.4, required]) - - /* The and header files */ - +e829 /* warn on header usage */ - +elib(829) - - +headerwarn(stdalign.h) - +headerwarn(stdnoreturn.h) - - /* Facilities of Annex K (Bounds-checking interfaces) */ - -deprecate(type,errno_t,[MISRA 2012 Rule 1.4, required]) - -deprecate(type,rsize_t,[MISRA 2012 Rule 1.4, required]) - -deprecate(type,constraint_handler_t,[MISRA 2012 Rule 1.4, required]) - - -deprecate(macro,RSIZE_MAX,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,L_tmpnam_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,TMP_MAX_S,[MISRA 2012 Rule 1.4, required]) - - -deprecate(function,abort_handler_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,asctime_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,bsearch_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,ctime_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,fopen_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,fprintf_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,freopen_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,fscanf_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,fwprintf_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,fwscanf_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,getenv_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,gets_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,gmtime_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,ignore_handler_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,localtime_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,mbsrtowcs_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,mbstowcs_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,memcpy_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,memmove_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,memset_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,printf_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,qsort_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,scanf_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,set_constraint_handler_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,snprintf_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,snwprintf_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,sprintf_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,sscanf_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,strcat_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,strcpy_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,strerror_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,strerrorlen_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,strncat_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,strncpy_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,strnlen_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,strtok_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,swprintf_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,swscanf_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,tmpfile_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,tmpnam_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,vfprintf_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,vfscanf_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,vfwprintf_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,vfwscanf_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,vprintf_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,vscanf_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,vsnprintf_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,vsnwprintf_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,vsprintf_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,vsscanf_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,vswprintf_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,vswscanf_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,vwprintf_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,vwscanf_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,wcrtomb_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,wcscat_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,wcscpy_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,wcsncat_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,wcsncpy_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,wcsnlen_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,wcsrtombs_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,wcstok_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,wcstombs_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,wctomb_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,wmemcpy_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,wmemmove_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,wprintf_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(function,wscanf_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,abort_handler_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,asctime_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,bsearch_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,ctime_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,fopen_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,fprintf_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,freopen_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,fscanf_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,fwprintf_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,fwscanf_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,getenv_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,gets_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,gmtime_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,ignore_handler_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,localtime_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,mbsrtowcs_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,mbstowcs_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,memcpy_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,memmove_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,memset_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,printf_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,qsort_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,scanf_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,set_constraint_handler_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,snprintf_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,snwprintf_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,sprintf_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,sscanf_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,strcat_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,strcpy_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,strerror_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,strerrorlen_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,strncat_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,strncpy_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,strnlen_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,strtok_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,swprintf_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,swscanf_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,tmpfile_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,tmpnam_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,vfprintf_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,vfscanf_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,vfwprintf_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,vfwscanf_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,vprintf_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,vscanf_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,vsnprintf_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,vsnwprintf_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,vsprintf_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,vsscanf_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,vswprintf_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,vswscanf_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,vwprintf_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,vwscanf_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,wcrtomb_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,wcscat_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,wcscpy_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,wcsncat_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,wcsncpy_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,wcsnlen_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,wcsrtombs_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,wcstok_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,wcstombs_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,wctomb_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,wmemcpy_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,wmemmove_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,wprintf_s,[MISRA 2012 Rule 1.4, required]) - -deprecate(macro,wscanf_s,[MISRA 2012 Rule 1.4, required]) - -/**** Rule 21.3 (Req) ************/ - - +e586 /* to activate the deprecation message */ - +elib(586) - - /* The other functions covered by this rule are included in au-misra3.lnt */ - -deprecate(function,aligned_alloc,[MISRA 2012 Rule 21.3, required]) - -deprecate(macro,aligned_alloc,[MISRA 2012 Rule 21.3, required]) - -/**** Rule 21.8 (Req) ************/ - - +e586 /* to activate the deprecation message */ - +elib(586) - - /* Deprecations for the abort and exit functions are included in au-misra3.lnt */ - -deprecate(function,_Exit,[MISRA 2012 Rule 21.8, required]) - -deprecate(function,quick_exit,[MISRA 2012 Rule 21.8, required]) - -deprecate(macro,_Exit,[MISRA 2012 Rule 21.8, required]) - -deprecate(macro,quick_exit,[MISRA 2012 Rule 21.8, required]) - - /* Suppress deprecation messages targeting getenv for Rule 21.8 which is - marked as deprecated in au-misra3.lnt but no longer a violation. */ - -egrep(586,"function 'getenv' is deprecated. [[]MISRA 2012 Rule 21.8, required[]]$") - -egrep(586,"macro 'getenv' is deprecated. [[]MISRA 2012 Rule 21.8, required[]]$") - -/**** Rule 21.21 (Req) ************/ - - +e586 /* to activate the deprecation message */ - +elib(586) - - -deprecate(function,system,[MISRA 2012 Rule 21.21, required]) - -deprecate(macro,system,[MISRA 2012 Rule 21.21, required]) - diff --git a/ports/lint-plus/au-misra3.lnt b/ports/lint-plus/au-misra4.lnt similarity index 64% rename from ports/lint-plus/au-misra3.lnt rename to ports/lint-plus/au-misra4.lnt index f7e546f4..a4567728 100644 --- a/ports/lint-plus/au-misra3.lnt +++ b/ports/lint-plus/au-misra4.lnt @@ -1,13 +1,15 @@ // --------------------------------------------------------------------------- -// Copyright Gimpel Software LLC 2020. All rights reserved. +// Copyright Vector Informatik GmbH 2020. All rights reserved. // -// This file is provided by Gimpel Software LLC (https://www.gimpel.com) for +// This file is provided by Vector Informatik GmbH (https://www.vector.com) for // use with PC-lint Plus. Redistribution is permitted but any redistribution // must preserve this notice and, if the redistributed file has been modified, // provide notice that the file has been modified from the original. // --------------------------------------------------------------------------- -// au-misra3.lnt -- Author options - MISRA C 2012 +// Modified by Quantum Leaps for MISRA C 2023 + +// au-misra4.lnt -- Author options - MISRA C 2023 /* This options file can be used to explicitly activate those @@ -16,22 +18,15 @@ You can use this file directly when linting your programs as in: - lint au-misra3.lnt hello.c - - Gimpel Software relies on the document, "MISRA-C:2012 - Guidelines for the use of the C language in critical systems", - copyright 2012 by MISRA Limited, as the primary source for this - file. Gimpel Software makes no warranty as to the completeness - or applicability of this options file and reserves the right to - amend or alter the official contents of such at any time. + lint au-misra4.lnt hello.c "MISRA" is a registered trademark of MIRA Limited, held on behalf of the MISRA Consortium. - */ +*/ -/* version check */ -cond('%PCLP_NO_LNT_VERSION_CHECK%' != '1' && (%LINT_MAJOR_VERSION% != 1 || %LINT_MINOR_VERSION% != 4), - +fatal_error(This configuration file is intended for PC-lint Plus 1.4. +/* version check */ -cond('%PCLP_NO_LNT_VERSION_CHECK%' != '1' && (%LINT_MAJOR_VERSION% != 2 || %LINT_MINOR_VERSION% != 0), + +fatal_error(This configuration file is intended for PC-lint Plus 2.0. You are attempting to use it with PC-lint Plus %LINT_MAJOR_VERSION%.%LINT_MINOR_VERSION%. It is recommended that you use configuration files intended for PC-lint Plus %LINT_MAJOR_VERSION%.%LINT_MINOR_VERSION%.) @@ -146,20 +141,24 @@ /**** Rule 1.1 (Req) ************/ - /* While MISRA has declared this rule to be "undecidable", Gimpel - * Software provides the following options to assist: - */ -std(c99) /* strict ISO C99 */ /* Note: if you code to the C90 standard instead, you may want to comment out the above option and uncomment the following option. You will also want to do likewise for other uses of the '-std(c99)' option throughout this file. */ // -std(c90) + /* Note: appended citation text is not applied to errors + reporting violations of the C language. */ + + /* See the -lang_limit option. */ + +e793 /* language limit exceeded */ + +elib(793) + -append(793,[MISRA 2012 Rule 1.1, required]) /**** Rule 1.2 (Adv) ************/ - /* While MISRA has declared this rule to be "undecidable", Gimpel - * Software provides the following options to assist: + /* While MISRA has declared this rule to be "undecidable", the + * following options are provided to assist: */ -std(c99) /* strict ISO C99 */ /* Note: if you code to the C90 standard instead, you may @@ -170,8 +169,8 @@ /**** Rule 1.3 (Req) ************/ - /* While MISRA has declared this rule to be "undecidable", Gimpel - * Software provides the following options to assist: + /* While MISRA has declared this rule to be "undecidable", the + * following options are provided to assist: */ /* Avoid the use of undefined or unspecified behavior as described @@ -338,9 +337,6 @@ (ISO C, Appendix A.6.2, point 39). Also, see Rule 9.2 */ - +e64 /* type mismatch */ - +elib(64) - -append(64,[MISRA 2012 Rule 1.3, required]) /* The value of a function is used, but no value was returned (ISO C, Appendix A.6.2, point 40). @@ -452,8 +448,8 @@ /**** Rule 2.1 (Req) ************/ - /* While MISRA has declared this rule to be "undecidable", Gimpel - * Software provides the following options to assist: + /* While MISRA has declared this rule to be "undecidable", the + * following options are provided to assist: */ +e527 /* unreachable */ +elib(527) @@ -467,8 +463,8 @@ /**** Rule 2.2 (Req) ************/ - /* While MISRA has declared this rule to be "undecidable", Gimpel - * Software provides the following options to assist: + /* While MISRA has declared this rule to be "undecidable", the + * following options are provided to assist: */ +e438 /* value not used */ +elib(438) @@ -834,8 +830,8 @@ /**** Rule 8.13 (Adv) ************/ - /* While MISRA has declared this rule to be "undecidable", Gimpel - * Software provides the following options to assist: + /* While MISRA has declared this rule to be "undecidable", the + * following options are provided to assist: */ +e818 /* pointer could be declared pointing to const */ +elib(818) @@ -857,8 +853,8 @@ /**** Rule 9.1 (Mand) ************/ - /* While MISRA has declared this rule to be "undecidable", Gimpel - * Software provides the following options to assist: + /* While MISRA has declared this rule to be "undecidable", the + * following options are provided to assist: */ +e644 /* Symbol may not have been initialized */ +elib(644) @@ -916,7 +912,6 @@ +e9034 /* expression assigned to narrower or different essential type */ +elib(9034) - -estring(9052, true, false) -append(9034,[MISRA 2012 Rule 10.3, required]) /**** Rule 10.4 (Req) ************/ @@ -1033,8 +1028,8 @@ /**** Rule 12.2 (Req) ************/ - /* While MISRA has declared this rule to be "undecidable", Gimpel - * Software provides the following options to assist: + /* While MISRA has declared this rule to be "undecidable", the + * following options are provided to assist: */ +e598 /* excessive left shift */ +elib(598) @@ -1055,8 +1050,8 @@ /**** Rule 13.1 (Req) ************/ - /* While MISRA has declared this rule to be "undecidable", Gimpel - * Software provides the following options to assist: + /* While MISRA has declared this rule to be "undecidable", the + * following options are provided to assist: */ +e446 /* side effect in initializer */ +elib(446) @@ -1064,8 +1059,8 @@ /**** Rule 13.2 (Req) ************/ - /* While MISRA has declared this rule to be "undecidable", Gimpel - * Software provides the following options to assist: + /* While MISRA has declared this rule to be "undecidable", the + * following options are provided to assist: */ +e564 /* variable depends on order of evaluation */ +elib(564) @@ -1092,8 +1087,8 @@ /**** Rule 13.5 (Req) ************/ - /* While MISRA has declared this rule to be "undecidable", Gimpel - * Software provides the following options to assist: + /* While MISRA has declared this rule to be "undecidable", the + * following options are provided to assist: */ +e9007 /* side effects on right hand side of logical operator */ +elib(9007) @@ -1107,8 +1102,8 @@ /**** Rule 14.1 (Req) ************/ - /* While MISRA has declared this rule to be "undecidable", Gimpel - * Software provides the following options to assist: + /* While MISRA has declared this rule to be "undecidable", the + * following options are provided to assist: */ +e9009 /* floating point variable used as loop counter */ +elib(9009) @@ -1120,8 +1115,8 @@ /**** Rule 14.3 (Req) ************/ - /* While MISRA has declared this rule to be "undecidable", Gimpel - * Software provides the following options to assist: + /* While MISRA has declared this rule to be "undecidable", the + * following options are provided to assist: */ +e685 /* relational always evaluates to true/false */ +elib(685) @@ -1288,8 +1283,8 @@ /**** Rule 17.2 (Req) ************/ - /* While MISRA has declared this rule to be "undecidable", Gimpel - * Software provides the following options to assist: + /* While MISRA has declared this rule to be "undecidable", the + * following options are provided to assist: */ +e9070 -append(9070,[MISRA 2012 Rule 17.2, required]) @@ -1328,8 +1323,8 @@ /**** Rule 17.8 (Adv) ************/ - /* While MISRA has declared this rule to be "undecidable", Gimpel - * Software provides the following options to assist: + /* While MISRA has declared this rule to be "undecidable", the + * following options are provided to assist: */ +e9044 /* function parameter modified */ +elib(9044) @@ -1337,8 +1332,8 @@ /**** Rule 18.1 (Req) ************/ - /* While MISRA has declared this rule to be "undecidable", Gimpel - * Software provides the following options to assist: + /* While MISRA has declared this rule to be "undecidable", the + * following options are provided to assist: */ +e415 /* out-of-bounds pointer */ +elib(415) @@ -1361,8 +1356,8 @@ /**** Rule 18.2 (Req) ************/ - /* While MISRA has declared this rule to be "undecidable", Gimpel - * Software provides the following options to assist: + /* While MISRA has declared this rule to be "undecidable", the + * following options are provided to assist: */ +e947 /* pointer subtraction */ +elib(947) @@ -1370,8 +1365,8 @@ /**** Rule 18.3 (Req) ************/ - /* While MISRA has declared this rule to be "undecidable", Gimpel - * Software provides the following options to assist: + /* While MISRA has declared this rule to be "undecidable", the + * following options are provided to assist: */ +e946 /* relational operator applied to pointers */ +elib(946) @@ -1391,8 +1386,8 @@ /**** Rule 18.6 (Req) ************/ - /* While MISRA has declared this rule to be "undecidable", Gimpel - * Software provides the following options to assist: + /* While MISRA has declared this rule to be "undecidable", the + * following options are provided to assist: */ +e733 /* assigning address of auto to outer scope symbol */ +elib(733) @@ -2026,8 +2021,8 @@ /**** Rule 22.1 (Req) ************/ - /* While MISRA has declared this rule to be "undecidable", Gimpel - * Software provides the following options to assist: + /* While MISRA has declared this rule to be "undecidable", the + * following options are provided to assist: */ +e429 /* custodial pointer neither free'd nor returned */ +elib(429) @@ -2040,8 +2035,8 @@ /**** Rule 22.2 (Mand) ************/ - /* While MISRA has declared this rule to be "undecidable", Gimpel - * Software provides the following options to assist: + /* While MISRA has declared this rule to be "undecidable", the + * following options are provided to assist: */ +e424 /* inappropriate deallocation */ +elib(424) @@ -2057,8 +2052,8 @@ /**** Rule 22.4 (Mand) ************/ - /* While MISRA has declared this rule to be "undecidable", Gimpel - * Software provides the following options to assist: + /* While MISRA has declared this rule to be "undecidable", the + * following options are provided to assist: */ +e2477 /* attempt to perform write operation on stream not opened for writing */ @@ -2067,8 +2062,8 @@ /**** Rule 22.5 (Mand) ************/ - /* While MISRA has declared this rule to be "undecidable", Gimpel - Software provides the following message to assist: + /* While MISRA has declared this rule to be "undecidable", the + * following options are provided to assist: */ +e9047 /* FILE pointer dereferenced */ +elib(9047) @@ -2077,10 +2072,693 @@ /**** Rule 22.6 (Mand) ************/ - /* While MISRA has declared this rule to be "undecidable", Gimpel - * Software provides the following options to assist: + /* While MISRA has declared this rule to be "undecidable", the + * following options are provided to assist: */ +e2471 /* operation on stream that has been closed */ +elib(2471) -append(2471,[MISRA 2012 Rule 22.6, mandatory]) + +// au-misra3-amd1.lnt -- Author options - MISRA C 2012 + +/* + This options file can be used to explicitly activate those + checks advocated by the Motor Industry Software Reliability + Association. + + You can use this file directly when linting your programs as in: + + lint au-misra3-amd1.lnt hello.c + + Note that this file does not enable checking for the base MISRA C 2012 + guidelines. Typical use will include au-misra3.lnt, e.g.: + + lint au-misra3.lnt au-misra3-amd1.lnt hello.c + + Vector Informatik GmbH relies on the document, "MISRA C:2012 Amendment 1 + Additional security guidelines for MISRA C:2012" + copyright 2016 by HORIBA MIRA Ltd, as the primary source for this + file. Vector Informatik GmbH makes no warranty as to the completeness + or applicability of this options file and reserves the right to + amend or alter the official contents of such at any time. + + "MISRA" is a registered trademark of HORIBA MIRA Ltd, held on + behalf of the MISRA Consortium. + + */ + +/* version check */ -cond('%PCLP_NO_LNT_VERSION_CHECK%' != '1' && (%LINT_MAJOR_VERSION% != 2 || %LINT_MINOR_VERSION% != 0), + +fatal_error(This configuration file is intended for PC-lint Plus 2.0. + You are attempting to use it with PC-lint Plus %LINT_MAJOR_VERSION%.%LINT_MINOR_VERSION%. + It is recommended that you use configuration files intended + for PC-lint Plus %LINT_MAJOR_VERSION%.%LINT_MINOR_VERSION%.) +) + + +/**** Dir 4.14 (Req) ************/ + + /* Not currently supported */ + +/**** Rule 12.5 (Mand) ************/ + + +e682 /* sizeof applied to parameter whose type is sized array */ + +elib(682) + -append(682,[MISRA 2012 Rule 12.5, mandatory]) + + +e882 /* sizeof applied to parameter declared as incomplete array */ + +elib(882) + -append(882,[MISRA 2012 Rule 12.5, mandatory]) + +/**** Rule 21.13 (Mand) ************/ + + /* While MISRA has declared this rule to be "undecidable", the + * following options are provided to assist: + */ + + /* Define EOF until a proper definition is seen */ + -dEOF=-1 + + /* Define UCHAR_MIN and UCHAR_MAX if no definition available */ + -dUCHAR_MIN=0 + -dUCHAR_MAX=255 + + /* Ensure macro versions of ctype.h functions expand to function versions + to make use of the function semantics defined below */ + --uisalnum + --uisalpha + --uisblank + --uiscntrl + --uisdigit + --uisgraph + --uislower + --uisprint + --uispunct + --uisspace + --uisupper + --uisxdigit + --utolower + --utoupper + + /* Define semantics for ctype.h functions */ + -sem(isalnum, (1n >= UCHAR_MIN && 1n <= UCHAR_MAX) || 1n == EOF) + -sem(isalpha, (1n >= UCHAR_MIN && 1n <= UCHAR_MAX) || 1n == EOF) + -sem(isblank, (1n >= UCHAR_MIN && 1n <= UCHAR_MAX) || 1n == EOF) + -sem(iscntrl, (1n >= UCHAR_MIN && 1n <= UCHAR_MAX) || 1n == EOF) + -sem(isdigit, (1n >= UCHAR_MIN && 1n <= UCHAR_MAX) || 1n == EOF) + -sem(isgraph, (1n >= UCHAR_MIN && 1n <= UCHAR_MAX) || 1n == EOF) + -sem(islower, (1n >= UCHAR_MIN && 1n <= UCHAR_MAX) || 1n == EOF) + -sem(isprint, (1n >= UCHAR_MIN && 1n <= UCHAR_MAX) || 1n == EOF) + -sem(ispunct, (1n >= UCHAR_MIN && 1n <= UCHAR_MAX) || 1n == EOF) + -sem(isspace, (1n >= UCHAR_MIN && 1n <= UCHAR_MAX) || 1n == EOF) + -sem(isupper, (1n >= UCHAR_MIN && 1n <= UCHAR_MAX) || 1n == EOF) + -sem(isxdigit, (1n >= UCHAR_MIN && 1n <= UCHAR_MAX) || 1n == EOF) + -sem(tolower, (1n >= UCHAR_MIN && 1n <= UCHAR_MAX) || 1n == EOF) + -sem(toupper, (1n >= UCHAR_MIN && 1n <= UCHAR_MAX) || 1n == EOF) + + +esym(426, isalnum) + +esym(426, isalpha) + +esym(426, isblank) + +esym(426, iscntrl) + +esym(426, isdigit) + +esym(426, isgraph) + +esym(426, islower) + +esym(426, isprint) + +esym(426, ispunct) + +esym(426, isspace) + +esym(426, isupper) + +esym(426, isxdigit) + +esym(426, tolower) + +esym(426, toupper) + + -append(426(isalnum), value passed to isalnum is not representable as unsigned char and is not EOF) + -append(426(isalnum),[MISRA 2012 Rule 21.13, mandatory]) + + -append(426(isalpha), value passed to isalpha is not representable as unsigned char and is not EOF) + -append(426(isalpha),[MISRA 2012 Rule 21.13, mandatory]) + + -append(426(isblank), value passed to isblank is not representable as unsigned char and is not EOF) + -append(426(isblank),[MISRA 2012 Rule 21.13, mandatory]) + + -append(426(iscntrl), value passed to iscntrl is not representable as unsigned char and is not EOF) + -append(426(iscntrl),[MISRA 2012 Rule 21.13, mandatory]) + + -append(426(isdigit), value passed to isdigit is not representable as unsigned char and is not EOF) + -append(426(isdigit),[MISRA 2012 Rule 21.13, mandatory]) + + -append(426(isgraph), value passed to isgraph is not representable as unsigned char and is not EOF) + -append(426(isgraph),[MISRA 2012 Rule 21.13, mandatory]) + + -append(426(islower), value passed to islower is not representable as unsigned char and is not EOF) + -append(426(islower),[MISRA 2012 Rule 21.13, mandatory]) + + -append(426(isprint), value passed to isprint is not representable as unsigned char and is not EOF) + -append(426(isprint),[MISRA 2012 Rule 21.13, mandatory]) + + -append(426(ispunct), value passed to ispunct is not representable as unsigned char and is not EOF) + -append(426(ispunct),[MISRA 2012 Rule 21.13, mandatory]) + + -append(426(isspace), value passed to isspace is not representable as unsigned char and is not EOF) + -append(426(isspace),[MISRA 2012 Rule 21.13, mandatory]) + + -append(426(isupper), value passed to isupper is not representable as unsigned char and is not EOF) + -append(426(isupper),[MISRA 2012 Rule 21.13, mandatory]) + + -append(426(isxdigit), value passed to isxdigit is not representable as unsigned char and is not EOF) + -append(426(isxdigit),[MISRA 2012 Rule 21.13, mandatory]) + + -append(426(tolower), value passed to tolower is not representable as unsigned char and is not EOF) + -append(426(tolower),[MISRA 2012 Rule 21.13, mandatory]) + + -append(426(toupper), value passed to toupper is not representable as unsigned char and is not EOF) + -append(426(toupper),[MISRA 2012 Rule 21.13, mandatory]) + +/**** Rule 21.14 (Req) ************/ + + /* Not currently supported */ + +/**** Rule 21.15 (Req) ************/ + + +e857 /* incompatible pointer arguments to memcpy/memmove/memcmp */ + +elib(857) + -append(857,[MISRA 2012 Rule 21.15, required]) + +/**** Rule 21.16 (Req) ************/ + + +e9098 /* pointer argument to memcmp does not point to a pointer type + or an essentially signed, unsigned, boolean, or enum type */ + +elib(9098) + -append(9098,[MISRA 2012 Rule 21.16, required]) + +/**** Rule 21.17 (Mand) ************/ + + /* While MISRA has declared this rule to be "undecidable", the + * following options are provided to assist: + */ + + /* 419 - apparent data overrun for function */ + /* 420 - apparent access beyond array for function */ + + +esym(419 420, strcat, strcpy) + -append(419(strcat),[MISRA 2012 Rule 21.17, mandatory]) + -append(420(strcat),[MISRA 2012 Rule 21.17, mandatory]) + -append(419(strcpy),[MISRA 2012 Rule 21.17, mandatory]) + -append(420(strcpy),[MISRA 2012 Rule 21.17, mandatory]) + +/**** Rule 21.18 (Mand) ************/ + + /* While MISRA has declared this rule to be "undecidable", the + * following options are provided to assist: + */ + + /* 419 - apparent data overrun for function */ + /* 420 - apparent access beyond array for function */ + /* 422 - function passed a negative value */ + + +esym(419 420 422, memchr, memcmp, memcpy, memmove, memset) + +esym(419 420 422, strncat, strncmp, strncpy, strxfrm) + + /* PC-lint Plus will issue 419 when it can determine that + * the size parameter of the below functions exceeds the + * size of the buffer that is being written to. + */ + + -append(419(memcpy),[MISRA 2012 Rule 21.18, mandatory]) + -append(419(memmove),[MISRA 2012 Rule 21.18, mandatory]) + -append(419(strncat),[MISRA 2012 Rule 21.18, mandatory]) + -append(419(strncpy),[MISRA 2012 Rule 21.18, mandatory]) + + /* PC-lint Plus will issue 420 when it can determine that + * the size parameter of the below functions exceeds the + * size of the buffer that is being read from. + */ + + -append(420(memchr),[MISRA 2012 Rule 21.18, mandatory]) + -append(420(memcmp),[MISRA 2012 Rule 21.18, mandatory]) + -append(420(memcpy),[MISRA 2012 Rule 21.18, mandatory]) + -append(420(memmove),[MISRA 2012 Rule 21.18, mandatory]) + + /* PC-lint Plus will issue 422 when it can determine that + * a negative value is being passed to the size parameter + * of the below functions. + */ + + -append(422(memchr),[MISRA 2012 Rule 21.18, mandatory]) + -append(422(memcmp),[MISRA 2012 Rule 21.18, mandatory]) + -append(422(memcpy),[MISRA 2012 Rule 21.18, mandatory]) + -append(422(memmove),[MISRA 2012 Rule 21.18, mandatory]) + -append(422(memset),[MISRA 2012 Rule 21.18, mandatory]) + -append(422(strncat),[MISRA 2012 Rule 21.18, mandatory]) + -append(422(strncmp),[MISRA 2012 Rule 21.18, mandatory]) + -append(422(strncpy),[MISRA 2012 Rule 21.18, mandatory]) + -append(422(strxfrm),[MISRA 2012 Rule 21.18, mandatory]) + +/**** Rule 21.19 (Mand) ************/ + + /* Not currently supported */ + +/**** Rule 21.20 (Mand) ************/ + + /* Not currently supported */ + +/**** Rule 22.7 (Req) ************/ + + /* Not currently supported */ + +/**** Rule 22.8 (Req) ************/ + + /* Not currently supported */ + +/**** Rule 22.9 (Req) ************/ + + /* Not currently supported */ + +/**** Rule 22.10 (Req) ************/ + + /* Not currently supported */ + +// au-misra3-amd2.lnt -- Author options - MISRA C 2012 + +/* + This options file can be used to explicitly activate those + checks advocated by the Motor Industry Software Reliability + Association. + + You can use this file directly when linting your programs as in: + + lint au-misra3-amd2.lnt hello.c + + Note that this file does not enable checking for the base MISRA C 2012 + guidelines. Typical use will include au-misra3.lnt, e.g.: + + lint au-misra3.lnt au-misra3-amd2.lnt hello.c + + To include checking of rules introduced in both AMD-1 and AMD-2, use: + + lint au-misra3.lnt au-misra3-amd1.lnt au-misra3-amd2.lnt hello.c + + Vector Informatik GmbH relies on the document, "MISRA C:2012 Amendment 2 + Updates for ISO/IEC 9899:2011 Core functionality" + copyright 2020 by HORIBA MIRA Ltd, as the primary source for this + file. Vector Informatik GmbH makes no warranty as to the completeness + or applicability of this options file and reserves the right to + amend or alter the official contents of such at any time. + + "MISRA" is a registered trademark of HORIBA MIRA Ltd, held on + behalf of the MISRA Consortium. + + */ + +/* version check */ -cond('%PCLP_NO_LNT_VERSION_CHECK%' != '1' && (%LINT_MAJOR_VERSION% != 2 || %LINT_MINOR_VERSION% != 0), + +fatal_error(This configuration file is intended for PC-lint Plus 2.0. + You are attempting to use it with PC-lint Plus %LINT_MAJOR_VERSION%.%LINT_MINOR_VERSION%. + It is recommended that you use configuration files intended + for PC-lint Plus %LINT_MAJOR_VERSION%.%LINT_MINOR_VERSION%.) +) + + + +/**** Rule 1.4 (Req) ************/ + + +e586 /* to activate the deprecation message */ + +elib(586) + + /* C11 Keywords */ + -deprecate(keyword,_Alignas,[MISRA 2012 Rule 1.4, required]) + -deprecate(keyword,_Alignof,[MISRA 2012 Rule 1.4, required]) + -deprecate(keyword,_Atomic,[MISRA 2012 Rule 1.4, required]) + -deprecate(keyword,_Generic,[MISRA 2012 Rule 1.4, required]) + //-deprecate(keyword,_Noreturn,[MISRA 2012 Rule 1.4, required]) + -deprecate(keyword,_Thread_local,[MISRA 2012 Rule 1.4, required]) + + /* Facilities provided by the header file */ + -deprecate(macro,ATOMIC_BOOL_LOCK_FREE,[MISRA 2012 Rule 1.4, required]) + -deprecate(macro,ATOMIC_CHAR16_T_LOCK_FREE,[MISRA 2012 Rule 1.4, required]) + -deprecate(macro,ATOMIC_CHAR32_T_LOCK_FREE,[MISRA 2012 Rule 1.4, required]) + -deprecate(macro,ATOMIC_CHAR_LOCK_FREE,[MISRA 2012 Rule 1.4, required]) + -deprecate(macro,ATOMIC_FLAG_INIT,[MISRA 2012 Rule 1.4, required]) + -deprecate(macro,ATOMIC_INT_LOCK_FREE,[MISRA 2012 Rule 1.4, required]) + -deprecate(macro,ATOMIC_LLONG_LOCK_FREE,[MISRA 2012 Rule 1.4, required]) + -deprecate(macro,ATOMIC_LONG_LOCK_FREE,[MISRA 2012 Rule 1.4, required]) + -deprecate(macro,ATOMIC_POINTER_LOCK_FREE,[MISRA 2012 Rule 1.4, required]) + -deprecate(macro,ATOMIC_SHORT_LOCK_FREE,[MISRA 2012 Rule 1.4, required]) + -deprecate(macro,ATOMIC_VAR_INIT,[MISRA 2012 Rule 1.4, required]) + -deprecate(macro,ATOMIC_WCHAR_T_LOCK_FREE,[MISRA 2012 Rule 1.4, required]) + + -deprecate(function,atomic_init,[MISRA 2012 Rule 1.4, required]) + -deprecate(macro,atomic_init,[MISRA 2012 Rule 1.4, required]) + + -deprecate(type,enum memory_order,[MISRA 2012 Rule 1.4, required]) + -deprecate(type,memory_order,[MISRA 2012 Rule 1.4, required]) + + -deprecate(type,atomic_flag,[MISRA 2012 Rule 1.4, required]) + -deprecate(type,struct atomic_flag,[MISRA 2012 Rule 1.4, required]) + + -deprecate(macro,kill_dependency,[MISRA 2012 Rule 1.4, required]) + + -deprecate(function,atomic_compare_exchange_strong,[MISRA 2012 Rule 1.4, required]) + -deprecate(function,atomic_compare_exchange_strong_explicit,[MISRA 2012 Rule 1.4, required]) + -deprecate(function,atomic_compare_exchange_weak,[MISRA 2012 Rule 1.4, required]) + -deprecate(function,atomic_compare_exchange_weak_explicit,[MISRA 2012 Rule 1.4, required]) + -deprecate(function,atomic_exchange,[MISRA 2012 Rule 1.4, required]) + -deprecate(function,atomic_exchange_explicit,[MISRA 2012 Rule 1.4, required]) + -deprecate(function,atomic_fetch_add,[MISRA 2012 Rule 1.4, required]) + -deprecate(function,atomic_fetch_add_explicit,[MISRA 2012 Rule 1.4, required]) + -deprecate(function,atomic_fetch_and,[MISRA 2012 Rule 1.4, required]) + -deprecate(function,atomic_fetch_and_explicit,[MISRA 2012 Rule 1.4, required]) + -deprecate(function,atomic_fetch_or,[MISRA 2012 Rule 1.4, required]) + -deprecate(function,atomic_fetch_or_explicit,[MISRA 2012 Rule 1.4, required]) + -deprecate(function,atomic_fetch_sub,[MISRA 2012 Rule 1.4, required]) + -deprecate(function,atomic_fetch_sub_explicit,[MISRA 2012 Rule 1.4, required]) + -deprecate(function,atomic_fetch_xor,[MISRA 2012 Rule 1.4, required]) + -deprecate(function,atomic_fetch_xor_explicit,[MISRA 2012 Rule 1.4, required]) + -deprecate(function,atomic_flag_clear,[MISRA 2012 Rule 1.4, required]) + -deprecate(function,atomic_flag_clear_explicit,[MISRA 2012 Rule 1.4, required]) + -deprecate(function,atomic_flag_test_and_set,[MISRA 2012 Rule 1.4, required]) + -deprecate(function,atomic_flag_test_and_set_explicit,[MISRA 2012 Rule 1.4, required]) + -deprecate(function,atomic_is_lock_free,[MISRA 2012 Rule 1.4, required]) + -deprecate(function,atomic_load,[MISRA 2012 Rule 1.4, required]) + -deprecate(function,atomic_load_explicit,[MISRA 2012 Rule 1.4, required]) + -deprecate(function,atomic_signal_fence,[MISRA 2012 Rule 1.4, required]) + -deprecate(function,atomic_store,[MISRA 2012 Rule 1.4, required]) + -deprecate(function,atomic_store_explicit,[MISRA 2012 Rule 1.4, required]) + -deprecate(function,atomic_thread_fence,[MISRA 2012 Rule 1.4, required]) + -deprecate(macro,atomic_compare_exchange_strong,[MISRA 2012 Rule 1.4, required]) + -deprecate(macro,atomic_compare_exchange_strong_explicit,[MISRA 2012 Rule 1.4, required]) + -deprecate(macro,atomic_compare_exchange_weak,[MISRA 2012 Rule 1.4, required]) + -deprecate(macro,atomic_compare_exchange_weak_explicit,[MISRA 2012 Rule 1.4, required]) + -deprecate(macro,atomic_exchange,[MISRA 2012 Rule 1.4, required]) + -deprecate(macro,atomic_exchange_explicit,[MISRA 2012 Rule 1.4, required]) + -deprecate(macro,atomic_fetch_add,[MISRA 2012 Rule 1.4, required]) + -deprecate(macro,atomic_fetch_add_explicit,[MISRA 2012 Rule 1.4, required]) + -deprecate(macro,atomic_fetch_and,[MISRA 2012 Rule 1.4, required]) + -deprecate(macro,atomic_fetch_and_explicit,[MISRA 2012 Rule 1.4, required]) + -deprecate(macro,atomic_fetch_or,[MISRA 2012 Rule 1.4, required]) + -deprecate(macro,atomic_fetch_or_explicit,[MISRA 2012 Rule 1.4, required]) + -deprecate(macro,atomic_fetch_sub,[MISRA 2012 Rule 1.4, required]) + -deprecate(macro,atomic_fetch_sub_explicit,[MISRA 2012 Rule 1.4, required]) + -deprecate(macro,atomic_fetch_xor,[MISRA 2012 Rule 1.4, required]) + -deprecate(macro,atomic_fetch_xor_explicit,[MISRA 2012 Rule 1.4, required]) + -deprecate(macro,atomic_flag_clear,[MISRA 2012 Rule 1.4, required]) + -deprecate(macro,atomic_flag_clear_explicit,[MISRA 2012 Rule 1.4, required]) + -deprecate(macro,atomic_flag_test_and_set,[MISRA 2012 Rule 1.4, required]) + -deprecate(macro,atomic_flag_test_and_set_explicit,[MISRA 2012 Rule 1.4, required]) + -deprecate(macro,atomic_is_lock_free,[MISRA 2012 Rule 1.4, required]) + -deprecate(macro,atomic_load,[MISRA 2012 Rule 1.4, required]) + -deprecate(macro,atomic_load_explicit,[MISRA 2012 Rule 1.4, required]) + -deprecate(macro,atomic_signal_fence,[MISRA 2012 Rule 1.4, required]) + -deprecate(macro,atomic_store,[MISRA 2012 Rule 1.4, required]) + -deprecate(macro,atomic_store_explicit,[MISRA 2012 Rule 1.4, required]) + -deprecate(macro,atomic_thread_fence,[MISRA 2012 Rule 1.4, required]) + + -deprecate(type,atomic_bool,[MISRA 2012 Rule 1.4, required]) + -deprecate(type,atomic_char,[MISRA 2012 Rule 1.4, required]) + -deprecate(type,atomic_char16_t,[MISRA 2012 Rule 1.4, required]) + -deprecate(type,atomic_char32_t,[MISRA 2012 Rule 1.4, required]) + -deprecate(type,atomic_int,[MISRA 2012 Rule 1.4, required]) + -deprecate(type,atomic_int_fast16_t,[MISRA 2012 Rule 1.4, required]) + -deprecate(type,atomic_int_fast32_t,[MISRA 2012 Rule 1.4, required]) + -deprecate(type,atomic_int_fast64_t,[MISRA 2012 Rule 1.4, required]) + -deprecate(type,atomic_int_fast8_t,[MISRA 2012 Rule 1.4, required]) + -deprecate(type,atomic_int_least16_t,[MISRA 2012 Rule 1.4, required]) + -deprecate(type,atomic_int_least32_t,[MISRA 2012 Rule 1.4, required]) + -deprecate(type,atomic_int_least64_t,[MISRA 2012 Rule 1.4, required]) + -deprecate(type,atomic_int_least8_t,[MISRA 2012 Rule 1.4, required]) + -deprecate(type,atomic_intmax_t,[MISRA 2012 Rule 1.4, required]) + -deprecate(type,atomic_intptr_t,[MISRA 2012 Rule 1.4, required]) + -deprecate(type,atomic_llong,[MISRA 2012 Rule 1.4, required]) + -deprecate(type,atomic_long,[MISRA 2012 Rule 1.4, required]) + -deprecate(type,atomic_ptrdiff_t,[MISRA 2012 Rule 1.4, required]) + -deprecate(type,atomic_schar,[MISRA 2012 Rule 1.4, required]) + -deprecate(type,atomic_short,[MISRA 2012 Rule 1.4, required]) + -deprecate(type,atomic_size_t,[MISRA 2012 Rule 1.4, required]) + -deprecate(type,atomic_uchar,[MISRA 2012 Rule 1.4, required]) + -deprecate(type,atomic_uint,[MISRA 2012 Rule 1.4, required]) + -deprecate(type,atomic_uint_fast16_t,[MISRA 2012 Rule 1.4, required]) + -deprecate(type,atomic_uint_fast32_t,[MISRA 2012 Rule 1.4, required]) + -deprecate(type,atomic_uint_fast64_t,[MISRA 2012 Rule 1.4, required]) + -deprecate(type,atomic_uint_fast8_t,[MISRA 2012 Rule 1.4, required]) + -deprecate(type,atomic_uint_least16_t,[MISRA 2012 Rule 1.4, required]) + -deprecate(type,atomic_uint_least32_t,[MISRA 2012 Rule 1.4, required]) + -deprecate(type,atomic_uint_least64_t,[MISRA 2012 Rule 1.4, required]) + -deprecate(type,atomic_uint_least8_t,[MISRA 2012 Rule 1.4, required]) + -deprecate(type,atomic_uintmax_t,[MISRA 2012 Rule 1.4, required]) + -deprecate(type,atomic_uintptr_t,[MISRA 2012 Rule 1.4, required]) + -deprecate(type,atomic_ullong,[MISRA 2012 Rule 1.4, required]) + -deprecate(type,atomic_ulong,[MISRA 2012 Rule 1.4, required]) + -deprecate(type,atomic_ushort,[MISRA 2012 Rule 1.4, required]) + -deprecate(type,atomic_wchar_t,[MISRA 2012 Rule 1.4, required]) + + /* Facilities provided by the header file */ + -deprecate(macro,ONCE_FLAG_INIT,[MISRA 2012 Rule 1.4, required]) + -deprecate(macro,TSS_DTOR_ITERATIONS,[MISRA 2012 Rule 1.4, required]) + -deprecate(macro,thread_local,[MISRA 2012 Rule 1.4, required]) + + -deprecate(type,cnd_t,[MISRA 2012 Rule 1.4, required]) + -deprecate(type,mtx_t,[MISRA 2012 Rule 1.4, required]) + -deprecate(type,once_flag,[MISRA 2012 Rule 1.4, required]) + -deprecate(type,thrd_start_t,[MISRA 2012 Rule 1.4, required]) + -deprecate(type,thrd_t,[MISRA 2012 Rule 1.4, required]) + -deprecate(type,tss_dtor_t,[MISRA 2012 Rule 1.4, required]) + -deprecate(type,tss_t,[MISRA 2012 Rule 1.4, required]) + + -deprecate(function,call_once,[MISRA 2012 Rule 1.4, required]) + -deprecate(function,cnd_broadcast,[MISRA 2012 Rule 1.4, required]) + -deprecate(function,cnd_destroy,[MISRA 2012 Rule 1.4, required]) + -deprecate(function,cnd_init,[MISRA 2012 Rule 1.4, required]) + -deprecate(function,cnd_signal,[MISRA 2012 Rule 1.4, required]) + -deprecate(function,cnd_timedwait,[MISRA 2012 Rule 1.4, required]) + -deprecate(function,cnd_wait,[MISRA 2012 Rule 1.4, required]) + -deprecate(function,mtx_destroy,[MISRA 2012 Rule 1.4, required]) + -deprecate(function,mtx_init,[MISRA 2012 Rule 1.4, required]) + -deprecate(function,mtx_lock,[MISRA 2012 Rule 1.4, required]) + -deprecate(function,mtx_timedlock,[MISRA 2012 Rule 1.4, required]) + -deprecate(function,mtx_trylock,[MISRA 2012 Rule 1.4, required]) + -deprecate(function,mtx_unlock,[MISRA 2012 Rule 1.4, required]) + -deprecate(function,thrd_create,[MISRA 2012 Rule 1.4, required]) + -deprecate(function,thrd_current,[MISRA 2012 Rule 1.4, required]) + -deprecate(function,thrd_detach,[MISRA 2012 Rule 1.4, required]) + -deprecate(function,thrd_equal,[MISRA 2012 Rule 1.4, required]) + -deprecate(function,thrd_exit,[MISRA 2012 Rule 1.4, required]) + -deprecate(function,thrd_join,[MISRA 2012 Rule 1.4, required]) + -deprecate(function,thrd_sleep,[MISRA 2012 Rule 1.4, required]) + -deprecate(function,thrd_yield,[MISRA 2012 Rule 1.4, required]) + -deprecate(function,tss_create,[MISRA 2012 Rule 1.4, required]) + -deprecate(function,tss_delete,[MISRA 2012 Rule 1.4, required]) + -deprecate(function,tss_get,[MISRA 2012 Rule 1.4, required]) + -deprecate(function,tss_set,[MISRA 2012 Rule 1.4, required]) + -deprecate(macro,call_once,[MISRA 2012 Rule 1.4, required]) + -deprecate(macro,cnd_broadcast,[MISRA 2012 Rule 1.4, required]) + -deprecate(macro,cnd_destroy,[MISRA 2012 Rule 1.4, required]) + -deprecate(macro,cnd_init,[MISRA 2012 Rule 1.4, required]) + -deprecate(macro,cnd_signal,[MISRA 2012 Rule 1.4, required]) + -deprecate(macro,cnd_timedwait,[MISRA 2012 Rule 1.4, required]) + -deprecate(macro,cnd_wait,[MISRA 2012 Rule 1.4, required]) + -deprecate(macro,mtx_destroy,[MISRA 2012 Rule 1.4, required]) + -deprecate(macro,mtx_init,[MISRA 2012 Rule 1.4, required]) + -deprecate(macro,mtx_lock,[MISRA 2012 Rule 1.4, required]) + -deprecate(macro,mtx_timedlock,[MISRA 2012 Rule 1.4, required]) + -deprecate(macro,mtx_trylock,[MISRA 2012 Rule 1.4, required]) + -deprecate(macro,mtx_unlock,[MISRA 2012 Rule 1.4, required]) + -deprecate(macro,thrd_create,[MISRA 2012 Rule 1.4, required]) + -deprecate(macro,thrd_current,[MISRA 2012 Rule 1.4, required]) + -deprecate(macro,thrd_detach,[MISRA 2012 Rule 1.4, required]) + -deprecate(macro,thrd_equal,[MISRA 2012 Rule 1.4, required]) + -deprecate(macro,thrd_exit,[MISRA 2012 Rule 1.4, required]) + -deprecate(macro,thrd_join,[MISRA 2012 Rule 1.4, required]) + -deprecate(macro,thrd_sleep,[MISRA 2012 Rule 1.4, required]) + -deprecate(macro,thrd_yield,[MISRA 2012 Rule 1.4, required]) + -deprecate(macro,tss_create,[MISRA 2012 Rule 1.4, required]) + -deprecate(macro,tss_delete,[MISRA 2012 Rule 1.4, required]) + -deprecate(macro,tss_get,[MISRA 2012 Rule 1.4, required]) + -deprecate(macro,tss_set,[MISRA 2012 Rule 1.4, required]) + + /* The and header files */ + +e829 /* warn on header usage */ + +elib(829) + + +headerwarn(stdalign.h) + +headerwarn(stdnoreturn.h) + + -append(829(stdalign.h),[MISRA 2012 Rule 1.4, required]) + -append(829(stdnoreturn.h),[MISRA 2012 Rule 1.4, required]) + + /* Facilities of Annex K (Bounds-checking interfaces) */ + -deprecate(type,errno_t,[MISRA 2012 Rule 1.4, required]) + -deprecate(type,rsize_t,[MISRA 2012 Rule 1.4, required]) + -deprecate(type,constraint_handler_t,[MISRA 2012 Rule 1.4, required]) + + -deprecate(macro,RSIZE_MAX,[MISRA 2012 Rule 1.4, required]) + -deprecate(macro,L_tmpnam_s,[MISRA 2012 Rule 1.4, required]) + -deprecate(macro,TMP_MAX_S,[MISRA 2012 Rule 1.4, required]) + + -deprecate(function,abort_handler_s,[MISRA 2012 Rule 1.4, required]) + -deprecate(function,asctime_s,[MISRA 2012 Rule 1.4, required]) + -deprecate(function,bsearch_s,[MISRA 2012 Rule 1.4, required]) + -deprecate(function,ctime_s,[MISRA 2012 Rule 1.4, required]) + -deprecate(function,fopen_s,[MISRA 2012 Rule 1.4, required]) + -deprecate(function,fprintf_s,[MISRA 2012 Rule 1.4, required]) + -deprecate(function,freopen_s,[MISRA 2012 Rule 1.4, required]) + -deprecate(function,fscanf_s,[MISRA 2012 Rule 1.4, required]) + -deprecate(function,fwprintf_s,[MISRA 2012 Rule 1.4, required]) + -deprecate(function,fwscanf_s,[MISRA 2012 Rule 1.4, required]) + -deprecate(function,getenv_s,[MISRA 2012 Rule 1.4, required]) + -deprecate(function,gets_s,[MISRA 2012 Rule 1.4, required]) + -deprecate(function,gmtime_s,[MISRA 2012 Rule 1.4, required]) + -deprecate(function,ignore_handler_s,[MISRA 2012 Rule 1.4, required]) + -deprecate(function,localtime_s,[MISRA 2012 Rule 1.4, required]) + -deprecate(function,mbsrtowcs_s,[MISRA 2012 Rule 1.4, required]) + -deprecate(function,mbstowcs_s,[MISRA 2012 Rule 1.4, required]) + -deprecate(function,memcpy_s,[MISRA 2012 Rule 1.4, required]) + -deprecate(function,memmove_s,[MISRA 2012 Rule 1.4, required]) + -deprecate(function,memset_s,[MISRA 2012 Rule 1.4, required]) + -deprecate(function,printf_s,[MISRA 2012 Rule 1.4, required]) + -deprecate(function,qsort_s,[MISRA 2012 Rule 1.4, required]) + -deprecate(function,scanf_s,[MISRA 2012 Rule 1.4, required]) + -deprecate(function,set_constraint_handler_s,[MISRA 2012 Rule 1.4, required]) + -deprecate(function,snprintf_s,[MISRA 2012 Rule 1.4, required]) + -deprecate(function,snwprintf_s,[MISRA 2012 Rule 1.4, required]) + -deprecate(function,sprintf_s,[MISRA 2012 Rule 1.4, required]) + -deprecate(function,sscanf_s,[MISRA 2012 Rule 1.4, required]) + -deprecate(function,strcat_s,[MISRA 2012 Rule 1.4, required]) + -deprecate(function,strcpy_s,[MISRA 2012 Rule 1.4, required]) + -deprecate(function,strerror_s,[MISRA 2012 Rule 1.4, required]) + -deprecate(function,strerrorlen_s,[MISRA 2012 Rule 1.4, required]) + -deprecate(function,strncat_s,[MISRA 2012 Rule 1.4, required]) + -deprecate(function,strncpy_s,[MISRA 2012 Rule 1.4, required]) + -deprecate(function,strnlen_s,[MISRA 2012 Rule 1.4, required]) + -deprecate(function,strtok_s,[MISRA 2012 Rule 1.4, required]) + -deprecate(function,swprintf_s,[MISRA 2012 Rule 1.4, required]) + -deprecate(function,swscanf_s,[MISRA 2012 Rule 1.4, required]) + -deprecate(function,tmpfile_s,[MISRA 2012 Rule 1.4, required]) + -deprecate(function,tmpnam_s,[MISRA 2012 Rule 1.4, required]) + -deprecate(function,vfprintf_s,[MISRA 2012 Rule 1.4, required]) + -deprecate(function,vfscanf_s,[MISRA 2012 Rule 1.4, required]) + -deprecate(function,vfwprintf_s,[MISRA 2012 Rule 1.4, required]) + -deprecate(function,vfwscanf_s,[MISRA 2012 Rule 1.4, required]) + -deprecate(function,vprintf_s,[MISRA 2012 Rule 1.4, required]) + -deprecate(function,vscanf_s,[MISRA 2012 Rule 1.4, required]) + -deprecate(function,vsnprintf_s,[MISRA 2012 Rule 1.4, required]) + -deprecate(function,vsnwprintf_s,[MISRA 2012 Rule 1.4, required]) + -deprecate(function,vsprintf_s,[MISRA 2012 Rule 1.4, required]) + -deprecate(function,vsscanf_s,[MISRA 2012 Rule 1.4, required]) + -deprecate(function,vswprintf_s,[MISRA 2012 Rule 1.4, required]) + -deprecate(function,vswscanf_s,[MISRA 2012 Rule 1.4, required]) + -deprecate(function,vwprintf_s,[MISRA 2012 Rule 1.4, required]) + -deprecate(function,vwscanf_s,[MISRA 2012 Rule 1.4, required]) + -deprecate(function,wcrtomb_s,[MISRA 2012 Rule 1.4, required]) + -deprecate(function,wcscat_s,[MISRA 2012 Rule 1.4, required]) + -deprecate(function,wcscpy_s,[MISRA 2012 Rule 1.4, required]) + -deprecate(function,wcsncat_s,[MISRA 2012 Rule 1.4, required]) + -deprecate(function,wcsncpy_s,[MISRA 2012 Rule 1.4, required]) + -deprecate(function,wcsnlen_s,[MISRA 2012 Rule 1.4, required]) + -deprecate(function,wcsrtombs_s,[MISRA 2012 Rule 1.4, required]) + -deprecate(function,wcstok_s,[MISRA 2012 Rule 1.4, required]) + -deprecate(function,wcstombs_s,[MISRA 2012 Rule 1.4, required]) + -deprecate(function,wctomb_s,[MISRA 2012 Rule 1.4, required]) + -deprecate(function,wmemcpy_s,[MISRA 2012 Rule 1.4, required]) + -deprecate(function,wmemmove_s,[MISRA 2012 Rule 1.4, required]) + -deprecate(function,wprintf_s,[MISRA 2012 Rule 1.4, required]) + -deprecate(function,wscanf_s,[MISRA 2012 Rule 1.4, required]) + -deprecate(macro,abort_handler_s,[MISRA 2012 Rule 1.4, required]) + -deprecate(macro,asctime_s,[MISRA 2012 Rule 1.4, required]) + -deprecate(macro,bsearch_s,[MISRA 2012 Rule 1.4, required]) + -deprecate(macro,ctime_s,[MISRA 2012 Rule 1.4, required]) + -deprecate(macro,fopen_s,[MISRA 2012 Rule 1.4, required]) + -deprecate(macro,fprintf_s,[MISRA 2012 Rule 1.4, required]) + -deprecate(macro,freopen_s,[MISRA 2012 Rule 1.4, required]) + -deprecate(macro,fscanf_s,[MISRA 2012 Rule 1.4, required]) + -deprecate(macro,fwprintf_s,[MISRA 2012 Rule 1.4, required]) + -deprecate(macro,fwscanf_s,[MISRA 2012 Rule 1.4, required]) + -deprecate(macro,getenv_s,[MISRA 2012 Rule 1.4, required]) + -deprecate(macro,gets_s,[MISRA 2012 Rule 1.4, required]) + -deprecate(macro,gmtime_s,[MISRA 2012 Rule 1.4, required]) + -deprecate(macro,ignore_handler_s,[MISRA 2012 Rule 1.4, required]) + -deprecate(macro,localtime_s,[MISRA 2012 Rule 1.4, required]) + -deprecate(macro,mbsrtowcs_s,[MISRA 2012 Rule 1.4, required]) + -deprecate(macro,mbstowcs_s,[MISRA 2012 Rule 1.4, required]) + -deprecate(macro,memcpy_s,[MISRA 2012 Rule 1.4, required]) + -deprecate(macro,memmove_s,[MISRA 2012 Rule 1.4, required]) + -deprecate(macro,memset_s,[MISRA 2012 Rule 1.4, required]) + -deprecate(macro,printf_s,[MISRA 2012 Rule 1.4, required]) + -deprecate(macro,qsort_s,[MISRA 2012 Rule 1.4, required]) + -deprecate(macro,scanf_s,[MISRA 2012 Rule 1.4, required]) + -deprecate(macro,set_constraint_handler_s,[MISRA 2012 Rule 1.4, required]) + -deprecate(macro,snprintf_s,[MISRA 2012 Rule 1.4, required]) + -deprecate(macro,snwprintf_s,[MISRA 2012 Rule 1.4, required]) + -deprecate(macro,sprintf_s,[MISRA 2012 Rule 1.4, required]) + -deprecate(macro,sscanf_s,[MISRA 2012 Rule 1.4, required]) + -deprecate(macro,strcat_s,[MISRA 2012 Rule 1.4, required]) + -deprecate(macro,strcpy_s,[MISRA 2012 Rule 1.4, required]) + -deprecate(macro,strerror_s,[MISRA 2012 Rule 1.4, required]) + -deprecate(macro,strerrorlen_s,[MISRA 2012 Rule 1.4, required]) + -deprecate(macro,strncat_s,[MISRA 2012 Rule 1.4, required]) + -deprecate(macro,strncpy_s,[MISRA 2012 Rule 1.4, required]) + -deprecate(macro,strnlen_s,[MISRA 2012 Rule 1.4, required]) + -deprecate(macro,strtok_s,[MISRA 2012 Rule 1.4, required]) + -deprecate(macro,swprintf_s,[MISRA 2012 Rule 1.4, required]) + -deprecate(macro,swscanf_s,[MISRA 2012 Rule 1.4, required]) + -deprecate(macro,tmpfile_s,[MISRA 2012 Rule 1.4, required]) + -deprecate(macro,tmpnam_s,[MISRA 2012 Rule 1.4, required]) + -deprecate(macro,vfprintf_s,[MISRA 2012 Rule 1.4, required]) + -deprecate(macro,vfscanf_s,[MISRA 2012 Rule 1.4, required]) + -deprecate(macro,vfwprintf_s,[MISRA 2012 Rule 1.4, required]) + -deprecate(macro,vfwscanf_s,[MISRA 2012 Rule 1.4, required]) + -deprecate(macro,vprintf_s,[MISRA 2012 Rule 1.4, required]) + -deprecate(macro,vscanf_s,[MISRA 2012 Rule 1.4, required]) + -deprecate(macro,vsnprintf_s,[MISRA 2012 Rule 1.4, required]) + -deprecate(macro,vsnwprintf_s,[MISRA 2012 Rule 1.4, required]) + -deprecate(macro,vsprintf_s,[MISRA 2012 Rule 1.4, required]) + -deprecate(macro,vsscanf_s,[MISRA 2012 Rule 1.4, required]) + -deprecate(macro,vswprintf_s,[MISRA 2012 Rule 1.4, required]) + -deprecate(macro,vswscanf_s,[MISRA 2012 Rule 1.4, required]) + -deprecate(macro,vwprintf_s,[MISRA 2012 Rule 1.4, required]) + -deprecate(macro,vwscanf_s,[MISRA 2012 Rule 1.4, required]) + -deprecate(macro,wcrtomb_s,[MISRA 2012 Rule 1.4, required]) + -deprecate(macro,wcscat_s,[MISRA 2012 Rule 1.4, required]) + -deprecate(macro,wcscpy_s,[MISRA 2012 Rule 1.4, required]) + -deprecate(macro,wcsncat_s,[MISRA 2012 Rule 1.4, required]) + -deprecate(macro,wcsncpy_s,[MISRA 2012 Rule 1.4, required]) + -deprecate(macro,wcsnlen_s,[MISRA 2012 Rule 1.4, required]) + -deprecate(macro,wcsrtombs_s,[MISRA 2012 Rule 1.4, required]) + -deprecate(macro,wcstok_s,[MISRA 2012 Rule 1.4, required]) + -deprecate(macro,wcstombs_s,[MISRA 2012 Rule 1.4, required]) + -deprecate(macro,wctomb_s,[MISRA 2012 Rule 1.4, required]) + -deprecate(macro,wmemcpy_s,[MISRA 2012 Rule 1.4, required]) + -deprecate(macro,wmemmove_s,[MISRA 2012 Rule 1.4, required]) + -deprecate(macro,wprintf_s,[MISRA 2012 Rule 1.4, required]) + -deprecate(macro,wscanf_s,[MISRA 2012 Rule 1.4, required]) + +/**** Rule 21.3 (Req) ************/ + + +e586 /* to activate the deprecation message */ + +elib(586) + + /* The other functions covered by this rule are included in au-misra3.lnt */ + -deprecate(function,aligned_alloc,[MISRA 2012 Rule 21.3, required]) + -deprecate(macro,aligned_alloc,[MISRA 2012 Rule 21.3, required]) + +/**** Rule 21.8 (Req) ************/ + + +e586 /* to activate the deprecation message */ + +elib(586) + + /* Deprecations for the abort and exit functions are included in au-misra3.lnt */ + -deprecate(function,_Exit,[MISRA 2012 Rule 21.8, required]) + -deprecate(function,quick_exit,[MISRA 2012 Rule 21.8, required]) + -deprecate(macro,_Exit,[MISRA 2012 Rule 21.8, required]) + -deprecate(macro,quick_exit,[MISRA 2012 Rule 21.8, required]) + + /* Suppress deprecation messages targeting getenv for Rule 21.8 which is + marked as deprecated in au-misra3.lnt but no longer a violation. */ + -egrep(586,"function 'getenv' is deprecated. [[]MISRA 2012 Rule 21.8, required[]]$") + -egrep(586,"macro 'getenv' is deprecated. [[]MISRA 2012 Rule 21.8, required[]]$") + +/**** Rule 21.21 (Req) ************/ + + +e586 /* to activate the deprecation message */ + +elib(586) + + -deprecate(function,system,[MISRA 2012 Rule 21.21, required]) + -deprecate(macro,system,[MISRA 2012 Rule 21.21, required]) + diff --git a/ports/lint-plus/au-ql-c99.lnt b/ports/lint-plus/au-ql-c99.lnt index c8fc6b82..520fe560 100644 --- a/ports/lint-plus/au-ql-c99.lnt +++ b/ports/lint-plus/au-ql-c99.lnt @@ -13,7 +13,7 @@ // by the Quantum Leaps Embedded C/C++ Coding Style (QL-C/C++:2022): // https://github.com/QuantumLeaps/embedded-coding-style -// ========== GENERAL RULES ========== +//========== GENERAL RULES ========== // 1.1 Which C? @@ -121,7 +121,7 @@ +e2765 -append(2765,[BARR-C:2018 Rule 1.8c]) -// ========== COMMENTS ========== +//========== COMMENTS ========== // 2.1 Acceptable Formats @@ -149,7 +149,7 @@ /* not statically checkable */ -// ========== WHITE SPACE RULES ========== +//========== WHITE SPACE RULES ========== // 3.1 Spaces @@ -187,7 +187,7 @@ /* not currently supported */ -// ========== MODULE RULES ========== +//========== MODULE RULES ========== // 4.1 Naming Conventions @@ -278,7 +278,7 @@ /* not statically checkable */ -// ========== DATA TYPE RULES ========== +//========== DATA TYPE RULES ========== // 5.1 Naming Conventions @@ -383,7 +383,7 @@ +e8523 -append(8523,[BARR-C:2018 Rule 5.6b]) -// ========== PROCEDURE RULES ========== +//========== PROCEDURE RULES ========== // 6.1 Naming Conventions @@ -465,7 +465,7 @@ /* not currently supported */ -// ========== VARIABLES ========== +//========== VARIABLES ========== // 7.1 Naming Conventions @@ -564,7 +564,7 @@ +e785 -append(785,[BARR-C:2018 Rule 7.2a]) -// ========== STATEMENT RULES ========== +//========== STATEMENT RULES ========== // 8.1 Variable Declarations diff --git a/ports/lint-plus/lin.bat b/ports/lint-plus/make.bat similarity index 82% rename from ports/lint-plus/lin.bat rename to ports/lint-plus/make.bat index 1f54ffb6..eff2d164 100644 --- a/ports/lint-plus/lin.bat +++ b/ports/lint-plus/make.bat @@ -1,6 +1,6 @@ @echo off :: =========================================================================== -:: Batch script for linting QP/C with PC-Lint-Plus +:: Batch script for linting QP/C with PC-Lint-Plus2 :: Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. :: :: SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial @@ -25,18 +25,18 @@ :: =========================================================================== @setlocal -:: usage of lin.bat -@echo Usage: lin [16bit] [-d...] +:: usage of make.bat +@echo Usage: make [16bit] [-u...] files @echo examples: -@echo lin -uQ_SPY -uQ_UTEST : use 32bit CPU (default) and undefine Q_SPY/Q_UTEST -@echo lin 16bit -uQ_SPY : use 16bit CPU includes and undefine Q_SPY +@echo make -uQ_SPY -uQ_UTEST : use 32bit CPU (default) and undefine Q_SPY/Q_UTEST +@echo make 16bit -uQ_SPY : use 16bit CPU includes and undefine Q_SPY @echo. :: NOTE: adjust to for your installation directory of PC-Lint-Plus -@set PCLP=C:\tools\lint-plus\windows\pclp64.exe +@set PCLP=C:\tools\lint-plus2\windows\pclp64.exe if NOT exist "%PCLP%" ( - @echo The PC-Lint-Plus toolset not found. Please adjust lin.bat + @echo The PC-Lint-Plus toolset not found. Please adjust make.bat @goto end ) diff --git a/ports/lint-plus/options.lnt b/ports/lint-plus/options.lnt index 57db6502..3413ba2e 100644 --- a/ports/lint-plus/options.lnt +++ b/ports/lint-plus/options.lnt @@ -22,8 +22,8 @@ // // //============================================================================ -//! @date Last updated on: 2022-10-14 -//! @version Last updated for version: 7.1.3 +//! @date Last updated on: 2023-09-08 +//! @version Last updated for version: 7.3.0 //! //! @file //! @brief PC-Lint-Plus option file for linting QP/C source code @@ -32,6 +32,7 @@ // general options -unit_check // perform only subset check (suppresses Global Wrapup) -max_threads=1 // suppress message "no '-max_threads=N' option" +++efreeze(686) // never suppress (see PC-Lint-Plus in Safety-Critical) //-vf // print names of all source files (for debugging linting) // include directories @@ -40,11 +41,7 @@ // standards // language standard... -au-misra3.lnt // MISRA-C:2012 compliance -au-misra3-amd1.lnt // MISRA-C:2012 amendment 1 compliance -au-misra3-amd2.lnt // MISRA-C:2012 amendment 2 compliance - -au-ds.lnt // Dan Saks recommendations +au-misra4.lnt // MISRA-C:2023 (MC4) compliance // customized BARR-C:2018 style guidelines au-barr.lnt // BARR-C:2018 style guidelines @@ -60,6 +57,9 @@ au-barr.lnt // BARR-C:2018 style guidelines -e9209 // suppress [Rule 5.2c] plain char data used with prohibited operator & -e8522 // suppress [Rule 8.6a] variable should appear on RHS of '==' operator +au-ds.lnt // Dan Saks recommendations + + // size/alignment options cpu.lnt // for the chosen CPU @@ -76,200 +76,182 @@ qpc.lnt // QP/C options // QEP ----------------------------------------------------------------------- -// M3-D4.9(A) function-like macro +//! M4-D4.9(A) function-like macro +//! @tr{DVP-QP-MC4-D04_09A} -esym(9026, - QMSM_CAST_, QACTIVE_CAST_) -// QF ------------------------------------------------------------------------ -// M3-D4.8(A) complete definition is unnecessary in this translation unit --efile(9045, - -qf_pkg.h) - -// M3-D4.9(A) function-like macro +//! M4-D4.9(A) function-like macro +//! @tr{DVP-QP-MC4-D04_09B} -esym(9026, - QF_CONST_CAST_, - QF_PTR_AT_, - QF_CRIT_E_, - QF_CRIT_X_, - Q_ASSERT_CRIT_, - Q_REQUIRE_CRIT_, - Q_ERROR_CRIT_, + QHSM_RESERVED_EVT_, + QS_STATE_ENTRY_, + QS_STATE_EXIT_) + +//! M4-R11.5(A) conversion from pointer to void to other pointer +//! @tr{DVR-QP-MC4-R11_05} +-emacro(9079, + Q_EVT_CAST) + +// QF ------------------------------------------------------------------------ + +//! M4-D4.8(A) complete definition is unnecessary in this translation unit +//! @tr{DVP-QP-MC4-D04_08} +-efile(9045, + -qp_pkg.h) + +//! M4-D4.9(A) function-like macro +//! @tr{DVP-QP-MC4-D04_09A} +-esym(9026, + QF_CRIT_ENTRY, + QF_CRIT_EXIT, + Q_ASSERT_INCRIT, + Q_REQUIRE_INCRIT, + Q_ERROR_INCRIT, + Q_ENSURE_INCRIT, QF_SCHED_LOCK_, QF_SCHED_UNLOCK_, QF_ISR_CONTEXT_, QF_MPOOL_EL, - QTICKER_CAST_) + Q_UINTPTR_CAST_) -// M3-R11.3(R) cast from pointer to object type +//! M4-R8.13(A) parameter of function could be pointer to const +//! @tr{DVR-QP-MC4-R08_13} +-efunc(818, + QActive_start_) + +//! M4-R11.3(R) cast from pointer to object type +//! @tr{DVP-QP-MC4-R11_03B} -emacro(9087, - QMSM_CAST_, - QTICKER_CAST_) + QACTIVE_CAST_) -// suspicious pointer-to-pointer conversion (area too small) --emacro(826, - QTICKER_CAST_) +//! M4-R11.3(R) cast from pointer to object type +//! @tr{DVP-QP-MC4-R11_03B} +-efunc(9087, + QActive_ctor, + QMActive_ctor) -// definition of macro ends in semicolon --esym(823, - QF_CRIT_STAT_) +//! M4-R11.4(A) conversion between object pointer type and integer type +//! @tr{DVR-QP-MC4-R11_04} +-emacro(9078, + Q_UINTPTR_CAST_) -// M3-R11.8(R) cast drops const qualifier --efunc(9005, - QF_gc, - QF_init) - -// M3-D11.5(A) conversion from pointer to void to other pointer type --efunc(9079, - QF_bzero) - -// M3-R17.8(A) function parameter modified --efunc(9044, - QF_LOG2, - QMPool_init) - -// M3-R18.1(R) potential out of bounds pointer access --emacro(661, - QF_EPOOL_EVENT_SIZE_) - -// M3-R11.5(A) conversion from pointer to void to other pointer type +//! M4-R11.5(A) conversion from pointer to void to other pointer type +//! @tr{DVR-QP-MC4-R11_05} -emacro(9079, QACTIVE_CAST_, QF_EPOOL_GET_) -efunc(9079, + QF_bzero_, QF_deleteRef_, QMPool_get, - QMPool_put) - -// M3-R11.5(A) conversion from pointer to void to other pointer type --efunc(9079, + QMPool_put, QMPool_init, QTimeEvt_tick_, QTimeEvt_armX, QTimeEvt_rearm) -// M3-R18.3(R) relational operator <= applied to pointers +//! M4-R11.8(R) cast drops const qualifier +//! @tr{DVR-QP-MC4-R11_08} +-emacro(9005, + QACTIVE_CAST_) +-efunc(9005, + QEvt_refCtr_inc_, + QEvt_refCtr_dec_, + QF_gc) + +//! M4-R15.5(A) return statement before end of function +//! @tr{DVP-QS-MC4-R15_05} +-efunc(904, + QActive_post_, + QActive_postLIFO_) + +//! M4-R18.3(R) relational operator <= applied to pointers +//! @tr{DVR-QP-MC4-R18_03} -efunc(946, QMPool_get, QMPool_put) -// M3-R8.13(A) parameter of function could be pointer to const --efunc(818, - QActive_start_, - QTicker_postLIFO_) - -// function could be declared as 'noreturn' --esym(2707, - QTicker_postLIFO_) - -// definition of macro ends in semicolon +//! definition of macro ends in semicolon +//! @tr{DVR-QP-PCLP-823} -esym(823, + QF_CRIT_STAT, QF_SCHED_STAT_) +//! suspicious pointer-to-pointer conversion (area too small) +//! @tr{DVP-QP-PCLP-826} +-emacro(826, + QACTIVE_CAST_) + + // QV ------------------------------------------------------------------------ // QK ------------------------------------------------------------------------ -// M3-D4.9(A) function-like macro +//! M4-D4.9(A) function-like macro +//! @tr{DVP-QP-MC4-D04_09A} -esym(9026, QK_ISR_CONTEXT_, QK_ISR_ENTRY, QK_ISR_EXIT) // QXK ----------------------------------------------------------------------- -// M3-D4.9(A) function-like macro + +//! M4-D4.9(A) function-like macro +//! @tr{DVP-QP-MC4-D04_09A} -esym(9026, QXK_ISR_CONTEXT_, QXK_CONTEXT_SWITCH_, QXK_PTR_CAST_, - QXTHREAD_CAST_) + QXTHREAD_CAST_, + QXTHREAD_EQUEUE_SIGNAL_) -// M3-R11.3(R) cast from pointer to object type +//! M4-R11.3(R) cast from pointer to object type +//! @tr{DVP-QP-MC4-R11_03B} -emacro(9087, - QXK_PTR_CAST_, QXTHREAD_CAST_) -// M3-R11.5(A) conversion from pointer to void to other pointer type +//! M4-R11.3(R) cast from pointer to object type +//! @tr{DVR-QP-MC4-R11_03C} +-emacro(9087, + QXK_PTR_CAST_) + +//! M4-R11.5(A) conversion from pointer to void to other pointer type +//! @tr{DVR-QP-MC4-R11_05} -emacro(9079, QXK_PTR_CAST_) -// suspicious pointer-to-pointer conversion (area too small) --emacro(826, - QXK_PTR_CAST_, - QXTHREAD_CAST_) - -// cast increases required alignment from 2 to 4 --emacro(2445, - QXK_PTR_CAST_) - -// M3-R8.13(A) parameter 'me' of function could be pointer to const +//! MC3-R8.13(A) could be pointer to const +//! @tr{DVR-QP-MC4-R08_13} -efunc(818, QXThread_init_, QXThread_dispatch_, QXThread_postLIFO_) -// function could be declared as 'noreturn' --esym(2707, - QXThread_init_, - QXThread_dispatch_, - QXThread_postLIFO_) +//! @tr{DVP-QP-PCLP-826} +-emacro(826, + QXK_PTR_CAST_, + QXTHREAD_CAST_) + +//! cast increases required alignment from 2 to 4 +//! @tr{DVR-QP-PCLP-2445} +-emacro(2445, + QXK_PTR_CAST_) // QS ------------------------------------------------------------------------ // the following options are needed only when Q_SPY is defined... -// M3-D4.9(A) function-like macro +//! M4-D4.9(A) function-like macro +//! @tr{DVP-QS-MC4-D04_09A} -esym(9026, QS_INSERT_BYTE_, QS_INSERT_ESC_BYTE_, QS_RX_TRAN_, - QS_CRIT_E_, - QS_CRIT_X_, - QS_PTR_INC_) + QS_CRIT_ENTRY, + QS_CRIT_EXIT) -// M3-R11.1(4) conversion between pointer to function and differing type --emacro(9074, - QS_FUN_PRE_) - -// M3-R14.3(R) boolean condition for 'if' always evaluates to 'false' --emacro(774, - QS_BEGIN_PRE_, - QS_BEGIN_NOCRIT_PRE_) - -// M3-R11.3(R) cast from pointer to object type --efile(9087, - -qs_rx.c, - -qutest.c) - -// M3-R11.4(A) conversion between object pointer type and integer type --efile(572, - -qs.c, - -qs_rx.c) - -// M3-R11.5(A) conversion from pointer to void to other pointer type --efile(9079, - -qs_rx.c, - -qutest.c) - -// M3-R15.5(A) return statement before end of function --efile(904, - -qs_rx.c) - -// suspicious pointer-to-pointer conversion (area too small) --efile(826, - -qs_rx.c, - -qutest.c) - -// M3-R11.4(A) conversion between object pointer type and integer type --emacro(9078, - QS_OBJ_PRE_, - QS_FUN_PRE_) - -// Constant expression evaluates to 0 in 'binary' operation '>>' --emacro(778, - QS_BEGIN_PRE_, - QS_BEGIN_NOCRIT_PRE_) - -// M3-R8.13(A) parameter ... of function could be pointer to const +//! M4-R8.13(A) parameter ... of function could be pointer to const +//! @tr{DVR-QS-MC4-R08_13} -efunc(818, QHsmDummy_init_, QHsmDummy_dispatch_, @@ -277,69 +259,102 @@ qpc.lnt // QP/C options QActiveDummy_init_, QActiveDummy_dispatch_) -// M3-R11.1(4) conversion between pointer to function and differing type +//! M4-R11.1(R) conversion between pointer to function and differing type +//! @tr{DVP-QS-MC4-R11_01} +-emacro(9074, + QS_FUN_PRE_) -efunc(9074, QS_getTestProbe_) -// M3-R11.4(R) conversion between object pointer type +//! M4-R11.3(R) cast from pointer to object type +//! @tr{DVR-QS-MC4-R11_03C} +-efile(9087, + -qs_rx.c, + -qutest.c) + +//! M4-R11.4(A) conversion between object pointer type and integer type +//! @tr{DVR-QS-MC4-R11_04} +-emacro(9078, + QS_OBJ_PRE_, + QS_FUN_PRE_) -efunc(9078, QS_rxHandleGoodFrame_, QS_getTestProbe_) -// M3-R11.6(R) explicit cast from integer to 'void *' +//! M4-R11.5(A) conversion from pointer to void to other pointer type +//! @tr{DVR-QS-MC4-R11_05} +-efile(9079, + -qs_rx.c, + -qutest.c) + +//! M4-R11.6(R) explicit cast from integer to 'void *' +//! @tr{DVR-QS-MC4-R11_06} +-emacro(923, + QS_OBJ_PRE_, + QS_FUN_PRE_) -efunc(923, QS_rxHandleGoodFrame_, QS_getTestProbe_) -// cast increases required alignment --efunc(2445, - QS_rxHandleGoodFrame_, - QS_rxPoke_) +//! M4-R14.3(R) boolean condition for 'if' always evaluates to 'false' +//! @tr{DVR-QS-MC4-R14_03} +-emacro(774, + QS_BEGIN_PRE_) -// excessive shift value (precision 0 shifted right by ...) --emacro(572, - QS_BEGIN_PRE_, - QS_BEGIN_NOCRIT_PRE_) - -// M3-R11.6(R) explicit cast from integer to 'void *' --emacro(923, - QS_OBJ_PRE_, - QS_FUN_PRE_) - -// M3-R17.8(A) function parameter modified --efunc(9044, - QS_u64_raw_, - QS_u64_fmt_) - -// definition of macro ends in semi-colon --esym(823, - QS_CRIT_STAT_, - QS_BEGIN_PRE_, - QS_BEGIN_NOCRIT_PRE_) - -// the right operand to << always evaluates to 0 --emacro(845, - QS_BEGIN_PRE_, - QS_BEGIN_NOCRIT_PRE_) - -// constant value used in Boolean context (left operand to || operator) --emacro(506, - QS_BEGIN_PRE_, - QS_BEGIN_NOCRIT_PRE_) - -// M3-R19.2(A) union declared +//! M4-R19.2(A) union declared +//! @tr{DVR-QS-MC4-R19_02} -efunc(9018, QS_target_info_pre_, QS_f32_fmt_, QS_f64_fmt_) -// union initialization +//! constant value used in Boolean context (left operand to || operator) +//! @tr{DVR-QS-PCLP-506} +-emacro(506, + QS_BEGIN_PRE_) + +//! excessive shift value (precision 0 shifted right by ...) +//! @tr{DVR-QS-PCLP-572} +-emacro(572, + QS_BEGIN_PRE_) + +//! union initialization +//! @tr{DVR-QS-PCLP-708} -efunc(708, QS_f64_fmt_) -// union member not referenced +//! union member not referenced +//! @tr{DVR-QS-PCLP-754} -esym(754, Variant::aFlt, AFltVar::prio, *U32Rep::u32) +//! Constant expression evaluates to 0 in 'binary' operation '>>' +//! @tr{DVR-QS-PCLP-778} +-emacro(778, + QS_BEGIN_PRE_) + +//! suspicious pointer-to-pointer conversion (area too small) +//! @tr{DVR-QS-PCLP-818} +-efile(826, + -qs_rx.c, + -qutest.c) + +//! definition of macro ends in semicolon +//! @tr{DVR-QS-PCLP-823} +-esym(823, + QS_CRIT_STAT, + QS_BEGIN_PRE_) + +//! the right operand to << always evaluates to 0 +//! @tr{DVR-QS-PCLP-845} +-emacro(845, + QS_BEGIN_PRE_) + +//! cast increases required alignment +//! @tr{DVP-QS-PCLP-2445} +-efunc(2445, + QS_rxHandleGoodFrame_, + QS_rxPoke_) + diff --git a/ports/lint-plus/qep_port.h b/ports/lint-plus/qep_port.h deleted file mode 100644 index 99aed52d..00000000 --- a/ports/lint-plus/qep_port.h +++ /dev/null @@ -1,43 +0,0 @@ -/*============================================================================ -* QP/C Real-Time Embedded Framework (RTEF) -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2022-10-12 -* @version Last updated for: @ref qpc_7_1_3 -* -* @file -* @brief QEP/C port, generic C11 compiler -*/ -#ifndef QEP_PORT_H -#define QEP_PORT_H - -/*! no-return void function specifier (C11 Standard) */ -#define Q_NORETURN _Noreturn void - -#include /* Exact-width types. WG14/N843 C99 Standard */ -#include /* Boolean type. WG14/N843 C99 Standard */ - -#include "qep.h" /* QEP platform-independent public interface */ - -#endif /* QEP_PORT_H */ diff --git a/ports/lint-plus/qk/qf_port.h b/ports/lint-plus/qk/qf_port.h deleted file mode 100644 index 945d8718..00000000 --- a/ports/lint-plus/qk/qf_port.h +++ /dev/null @@ -1,54 +0,0 @@ -/*============================================================================ -* QEP/C port to ARM Cortex-M, GNU-ARM -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2022-07-29 -* @version Last updated for: @ref qpc_7_0_1 -* -* @file -* @brief QF/C port example for QK, generic C compiler. -*/ -#ifndef QF_PORT_H -#define QF_PORT_H - -/* interrupt disabling mechanism */ -#define QF_INT_DISABLE() intDisable() -#define QF_INT_ENABLE() intEnable() - -void intDisable(void); -void intEnable(void); - -/* QF critical section mechanism */ -#define QF_CRIT_STAT_TYPE crit_stat_t -#define QF_CRIT_ENTRY(stat_) ((stat_) = critEntry()) -#define QF_CRIT_EXIT(stat_) critExit(stat_) - -typedef unsigned int crit_stat_t; -crit_stat_t critEntry(void); -void critExit(crit_stat_t stat); - -#include "qep_port.h" /* QEP port */ -#include "qk_port.h" /* QK port */ - -#endif /* QF_PORT_H */ diff --git a/ports/lint-plus/qk/qk_port.h b/ports/lint-plus/qk/qk_port.h deleted file mode 100644 index d6c8309b..00000000 --- a/ports/lint-plus/qk/qk_port.h +++ /dev/null @@ -1,85 +0,0 @@ -/*============================================================================ -* QP/C Real-Time Embedded Framework (RTEF) -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2022-12-13 -* @version Last updated for: @ref qpc_7_2_0 -* -* @file -* @brief QK/C port example for a generic C compiler. -*/ -#ifndef QK_PORT_H -#define QK_PORT_H - -/****************************************************************************/ - -/*! enable the context-switch callback */ -#define QF_ON_CONTEXT_SW 1 - -/*! determination if the code executes in the ISR context (ARM Cortex-M) */ -#define QK_ISR_CONTEXT_() (get_IPSR() != 0U) - -/* QK interrupt entry and exit... */ -/*! Define the ISR entry sequence, if the compiler supports writing -* interrupts in C. -*/ -/** -* @note This is just an example of #QK_ISR_ENTRY. You need to define -* the macro appropriately for the CPU/compiler you're using. Also, some -* QK ports will not define this macro, but instead will provide ISR -* skeleton code in assembly. -*/ -#define QK_ISR_ENTRY() do { \ - QF_INT_DISABLE(); \ - ++QF_intNest_; \ - QF_QS_ISR_ENTRY(QF_intNest_, QK_currPrio_); \ - QF_INT_ENABLE(); \ -} while (false) - -/*! Define the ISR exit sequence, if the compiler supports writing -* interrupts in C. -*/ -/** -* @note -* This is just an example of #QK_ISR_EXIT. You need to define the macro -* appropriately for the CPU/compiler you're using. Also, some QK ports will -* not define this macro, but instead will provide ISR skeleton in assembly. -*/ -#define QK_ISR_EXIT() do { \ - QF_INT_DISABLE(); \ - --QF_intNest_; \ - if (QF_intNest_ == 0U) { \ - if (QK_sched_() != 0U) { \ - QK_activate_(); \ - } \ - } \ - QF_INT_ENABLE(); \ -} while (false) - -#include "qk.h" /* QK platform-independent public interface */ - -uint32_t get_IPSR(void); - -#endif /* QK_PORT_H */ - diff --git a/ports/lint-plus/qk/qp_port.h b/ports/lint-plus/qk/qp_port.h new file mode 100644 index 00000000..1ec29dc2 --- /dev/null +++ b/ports/lint-plus/qk/qp_port.h @@ -0,0 +1,94 @@ +//============================================================================ +// QP/C Real-Time Embedded Framework (RTEF) +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +//============================================================================ +//! @date Last updated on: 2023-09-07 +//! @version Last updated for: @ref qpc_7_3_0 +//! +//! @file +//! @brief QP/C "port" to PC-Lint-Plus, QK kernel, generic C99 + +#ifndef QP_PORT_H_ +#define QP_PORT_H_ + +#include // Exact-width types. WG14/N843 C99 Standard +#include // Boolean type. WG14/N843 C99 Standard + +#ifdef QP_CONFIG +#include "qp_config.h" // external QP configuration +#endif + +// no-return function specifier (C11 Standard) +#define Q_NORETURN _Noreturn void + +// QF configuration for QK -- data members of the QActive class... + +// QK event-queue used for AOs +#define QACTIVE_EQUEUE_TYPE QEQueue + +// QF "thread" type used to store the MPU settings in the AO +#define QACTIVE_THREAD_TYPE void const * + +// interrupt disabling mechanism +#define QF_INT_DISABLE() intDisable() +#define QF_INT_ENABLE() intEnable() + +// QF critical section mechanism +#define QF_CRIT_STAT uint32_t crit_stat_; +#define QF_CRIT_ENTRY() (crit_stat_ = critEntry()) +#define QF_CRIT_EXIT() critExit(crit_stat_) + +// Check if the code executes in the ISR context +#define QK_ISR_CONTEXT_() (QK_get_IPSR() != 0U) + +// Define the ISR entry sequence +#define QK_ISR_ENTRY() ((void)0) + +// Define the ISR exit sequence +#define QK_ISR_EXIT() do { \ + QF_INT_DISABLE(); \ + if (QK_sched_() != 0U) { \ + *Q_UINT2PTR_CAST(uint32_t, 0xE000ED04U) = (1U << 28U);\ + } \ + QF_INT_ENABLE(); \ +} while (false) + +void intDisable(void); +void intEnable(void); +uint32_t critEntry(void); +void critExit(uint32_t stat); +uint32_t QK_get_IPSR(void); + +// include files ------------------------------------------------------------- +#include "qequeue.h" // QK kernel uses the native QP event queue +#include "qmpool.h" // QK kernel uses the native QP memory pool +#include "qp.h" // QP framework +#include "qk.h" // QK kernel + +#endif // QP_PORT_H_ + diff --git a/ports/lint-plus/ql-style.lnt b/ports/lint-plus/ql-style.lnt index c02a5713..c4e6efaa 100644 --- a/ports/lint-plus/ql-style.lnt +++ b/ports/lint-plus/ql-style.lnt @@ -15,7 +15,7 @@ // checks advocated by the Quantum Leaps Coding Standard // https://barrgroup.com/Embedded-Systems/Books/Embedded-C-Coding-Standard -// ========== GENERAL RULES ========== +//========== GENERAL RULES ========== // 1.2 Line Widths @@ -110,7 +110,7 @@ +e2765 -append(2765,[BARR-C:2018 Rule 1.8c]) -// ========== COMMENTS ========== +//========== COMMENTS ========== // 2.1 Acceptable Formats @@ -138,7 +138,7 @@ /* not statically checkable */ -// ========== WHITE SPACE RULES ========== +//========== WHITE SPACE RULES ========== // 3.1 Spaces @@ -176,7 +176,7 @@ /* not currently supported */ -// ========== MODULE RULES ========== +//========== MODULE RULES ========== // 4.1 Naming Conventions @@ -261,7 +261,7 @@ /* not statically checkable */ -// ========== DATA TYPE RULES ========== +//========== DATA TYPE RULES ========== /* 8528 - non-anonymous struct/union/enum declared outside of typedef */ -hook(record_decl, -cond(%[is_freestanding] && !%[is_anonymous], @@ -348,7 +348,7 @@ +e8523 -append(8523,[BARR-C:2018 Rule 5.6b]) -// ========== PROCEDURE RULES ========== +//========== PROCEDURE RULES ========== // 6.1 Naming Conventions @@ -425,7 +425,7 @@ /* not currently supported */ -// ========== VARIABLES ========== +//========== VARIABLES ========== // 7.1 Naming Conventions @@ -493,7 +493,7 @@ +e785 -append(785,[BARR-C:2018 Rule 7.2a]) -// ========== STATEMENT RULES ========== +//========== STATEMENT RULES ========== // 8.1 Variable Declarations diff --git a/ports/lint-plus/qpc.lnt b/ports/lint-plus/qpc.lnt index c87de4c7..46f01bd5 100644 --- a/ports/lint-plus/qpc.lnt +++ b/ports/lint-plus/qpc.lnt @@ -22,41 +22,40 @@ // // //============================================================================ -//! @date Last updated on: 2022-11-29 -//! @version Last updated for version: 7.2.0 +//! @date Last updated on: 2023-09-01 +//! @version Last updated for version: 7.3.0 //! //! @file -//! @brief PC-Lint-Plus option file for linting **QP/C Applications** +//! @brief PC-Lint-Plus option file for analysing both **QP/C** +//! and **QP/C Applications** -// M3-D4.8(A) complete definition is unnecessary in this translation unit +// C Language Standard +-std=c99 // apply the C99 Language Standard + +//! M4-D4.8(A) complete definition is unnecessary in this translation unit +//! @tr{DVP-QP-MC4-D04_08} -efile(9045, - -qep.h, + -qp.h, -qequeue.h, -qmpool.h, - -qpset.h, - -qf.h, -qv.h, -qk.h, -qxk.h, - -qxthread.h, -qs.h) -// Assertions ---------------------------------------------------------------- +// Functinal Safety (FuSa) System -------------------------------------------- -// give Q_onAssert() the semantics of "no return" --sem(Q_onAssert, r_no) +// "no return" semantics for error/failure callbacks +-sem(Q_onError, r_no) +-sem(assert_failed, r_no) -// M3-R1.4(R1.4) keyword '_Noreturn' is deprecated -// @tr{PQA01_4} --emacro(586, - Q_NORETURN) - -// M3-D4.9(A) function-like macro +//! M4-D4.9(A) function-like macro +//! @tr{DVP-QP-MC4-D04_09A} (false-positive) -esym(9026, + Q_DEFINE_THIS_MODULE, + Q_ASSERT_STATIC, Q_ASSERT, Q_ASSERT_ID, - Q_ALLEGE, - Q_ALLEGE_ID, Q_ERROR, Q_ERROR_ID, Q_REQUIRE, @@ -65,34 +64,44 @@ Q_ENSURE_ID, Q_INVARIANT, Q_INVARIANT_ID, - Q_ASSERT_STATIC, - Q_ASSERT_COMPILE, - Q_DEFINE_THIS_MODULE, - Q_UNUSED_PAR, Q_DIM) -// definition of macro ends in semicolon +//! PCLP definition of macro ends in semicolon +//! @tr{DVP-QP-PCLP-823} -esym(823, - Q_DEFINE_THIS_FILE, - Q_DEFINE_THIS_MODULE) + Q_DEFINE_THIS_MODULE, + Q_DEFINE_THIS_FILE) + +//! BARR-C(R1.8b) parameter of function could be const +-efunc(952, + Q_onError +) // QEP ----------------------------------------------------------------------- -// M3-D4.9(A) function-like macro +//! M4-D4.9(A) function-like macro +//! @tr{DVP-QP-MC4-D04_09A} (false-positive) -esym(9026, - QHSM_INIT, - QHSM_DISPATCH, + Q_UNUSED_PAR, Q_TRAN, Q_TRAN_HIST, Q_SUPER, Q_HANDLED, Q_UNHANDLED, Q_IGNORED, + Q_ASM_UPCAST, Q_HSM_UPCAST, + Q_MSM_UPCAST, Q_EVT_CAST, QEVT_INITIALIZER, Q_UINT2PTR_CAST, Q_STATE_CAST, Q_ACTION_CAST, + QASM_INIT, + QASM_DISPATCH) + +//! M4-D4.9(A) function-like macro +//! @tr{DVP-QP-MC4-D04_09B} (correct identification) +-esym(9026, QM_ENTRY, QM_EXIT, QM_SM_EXIT, @@ -108,7 +117,8 @@ QMSM_INIT, QMSM_DISPATCH) -// M3-R11.1(R) conversion between pointer to function type +//! M4-R11.1(R) conversion between pointer to function type +//! @tr{DVP-QP-MC4-R11_01} -emacro(9074, Q_STATE_CAST, Q_ACTION_CAST, @@ -124,22 +134,27 @@ QM_TRAN_EP, QM_TRAN_XP) -// M3-R11.3(R) cast from pointer to pointer (upcast) +//! M4-R11.3(R) cast from pointer to pointer (upcast) +//! @tr{DVP-QP-MC4-R11_03A} -emacro(9087, + Q_ASM_UPCAST, Q_HSM_UPCAST, - Q_EVT_CAST, + Q_MSM_UPCAST, QM_TRAN, QM_TRAN_EP, QM_TRAN_INIT) -// M3-R11.5(A) conversion from pointer to void to other pointer --emacro(9079, +//! M4-R11.3(R) cast from pointer to pointer (downcast) +//! @tr{DVP-QP-MC4-R11_03B} +-emacro(9087, Q_EVT_CAST) -// M3-R12.3(A) comma operator used +//! M4-R12.3(A) comma operator used +//! @tr{DVP-QP-MC4-R12_03} -emacro(9008, Q_SUPER, Q_TRAN, + Q_TRAN_HIST, QM_ENTRY, QM_EXIT, QM_SUPER_SUB, @@ -150,7 +165,8 @@ QM_SM_EXIT, QM_SUPER_SUB) -// M3-R13.4(A) result of assignment used in left operand to ',' operator +//! M4-R13.4(A) result of assignment used in left operand to ',' operator +//! @tr{DVP-QP-MC4-R13_04} -emacro(9084, Q_SUPER, Q_TRAN, @@ -158,24 +174,28 @@ QM_EXIT, QM_TRAN, QM_TRAN_INIT, + QM_TRAN_HIST, QM_TRAN_EP, QM_TRAN_XP, QM_SM_EXIT, QM_SUPER_SUB) -// M3-R19.2(A) union declared +//! M4-R19.2(A) union declared +//! @tr{DVP-QP-MC4-R19_02} -esym(9018, - QHsmAttr) + QAsmAttr) -// suspicious pointer-to-pointer conversion (area too small) --emacro(826, - Q_EVT_CAST) - -// '' not referenced in QM-style state machines +//! '' not referenced in QM-style state machines +//! @tr{DVP-QP-PCLP-754} -esym(754, *(anonymous struct)::act, *(anonymous struct)::target) +//! suspicious pointer-to-pointer conversion (area too small) +//! @tr{DVP-QP-PCLP-826} +-emacro(826, + Q_EVT_CAST) + // deprecated QEP facilities... -deprecate( type, QFsm, QP/C API pre 5.4.x) -deprecate( function, QFsm_ctor, QP/C API pre 5.4.x) @@ -186,12 +206,11 @@ // QF ------------------------------------------------------------------------ -// M3-D4.9(A) function-like macro +//! M4-D4.9(A) function-like macro +//! @tr{DVP-QP-MC4-D04_09B} -esym(9026, QF_INT_DISABLE, QF_INT_ENABLE, - QF_CRIT_ENTRY, - QF_CRIT_EXIT, Q_PRIO, QF_LOG2, Q_NEW, @@ -199,20 +218,13 @@ Q_NEW_REF, Q_DELETE_REF, QF_PUBLISH, - QF_TICK_X, - QF_TICK, - QF_INT_DISABLE, - QF_INT_ENABLE, QF_CRIT_ENTRY, QF_CRIT_EXIT, QF_CRIT_EXIT_NOP, + QF_MEM_SYS, + QF_MEM_APP, QF_MPOOL_EL, QF_LOG2, - QF_QS_CRIT_ENTRY, - QF_QS_CRIT_EXIT, - QF_QS_ISR_ENTRY, - QF_QS_ISR_EXIT, - QF_QS_ACTION, QF_EPOOL_INIT_, QF_EPOOL_EVENT_SIZE_, QF_EPOOL_GET_, @@ -227,22 +239,28 @@ QACTIVE_EQUEUE_SIGNAL_, QACTIVE_EQUEUE_ONEMPTY_, QTIMEEVT_TICK, - QTIMEEVT_TICK_X) + QTIMEEVT_TICK_X, + QTICKER_TRIG, + QF_TICK, + QF_TICK_X) -// M3-R10.3(R) cannot assign enum to different essential type 'int_t' --emacro(9034, - Q_NEW) - -// M3-R11.3(R) cast to pointer to different object type +//! M4-R11.3(R) cast to pointer to different object type (upcast) +//! @tr{DVP-QP-MC4-R11_03A} -emacro(9087, - Q_NEW, - Q_NEW_X, QACTIVE_POST, QACTIVE_POST_LIFO) -// suspicious pointer-to-pointer conversion (area too small) +//! M4-R11.3(R) cast to pointer to different object type (downcast) +//! @tr{DVP-QP-MC4-R11_03B} +-emacro(9087, + Q_NEW, + Q_NEW_X) + +//! suspicious pointer-to-pointer conversion (area too small) +//! @tr{DVP-QP-PCLP-826} -emacro(826, QACTIVE_POST, + QACTIVE_POST_X, QACTIVE_POST_LIFO, Q_NEW, Q_NEW_X) @@ -253,33 +271,36 @@ -deprecate( macro,QTimeEvt_postEvery, QP/C API pre 5.8.x) // QV ------------------------------------------------------------------------ -// M3-D4.9(A) function-like macro +//! M4-D4.9(A) function-like macro +//! @tr{DVP-QP-MC4-D04_09A} -esym(9026, QV_CPU_SLEEP) // QK ------------------------------------------------------------------------ -// M3-D4.9(A) function-like macro +// M4-D4.9(A) function-like macro +//! @tr{DVP-QP-MC4-D04_09A} -esym(9026, QK_ISR_ENTRY, QK_ISR_EXIT, QK_ISR_CONTEXT_) // QXK ----------------------------------------------------------------------- -// M3-D4.9(A) function-like macro +//! M4-D4.9(A) function-like macro +//! @tr{DVP-QP-MC4-D04_09A} -esym(9026, QXK_ISR_ENTRY, QXK_ISR_EXIT, QXK_TLS, QXTHREAD_START, - QXTHREAD_POST_X, - Q_XTHREAD_CAST) + QXTHREAD_POST_X) // deprecated QXK facilities... -deprecate( macro, Q_XTHREAD_CAST, QP/C API pre 6.7.x) // QS ------------------------------------------------------------------------ -// M3-D4.9(A) function-like macro +//! M4-D4.9(A) function-like macro +//! @tr{DVP-QS-MC4-D04_09A} -esym(9026, QS_INIT, QS_EXIT, @@ -300,8 +321,13 @@ QS_BEGIN, QS_BEGIN_ID, QS_END, - QS_BEGIN_NOCRIT, - QS_END_NOCRIT, + QS_BEGIN_INCRIT, + QS_END_INCRIT, + QS_TR_CRIT_ENTRY, + QS_TR_CRIT_EXIT, + QS_TR_ISR_ENTRY, + QS_TR_ISR_EXIT, + QS_ONLY, QS_REC_DONE, QS_I8, QS_U8, @@ -337,16 +363,17 @@ QS_TEST_PROBE, QS_TEST_PROBE_ID) -// M3-D4.9(A) function-like macro +//! M4-D4.9(A) function-like macro +//! @tr{DVP-QS-MC4-D04_09A} -esym(9026, - QS_CRIT_E_, - QS_CRIT_X_, + QS_CRIT_ENTRY, + QS_CRIT_EXIT, + QS_MEM_SYS, + QS_MEM_APP, QS_GLB_CHECK_, QS_LOC_CHECK_, QS_BEGIN_PRE_, QS_END_PRE_, - QS_BEGIN_NOCRIT_PRE_, - QS_END_NOCRIT_PRE_, QS_U8_PRE_, QS_2U8_PRE_, QS_U16_PRE_, @@ -362,16 +389,24 @@ QS_MPS_PRE_, QS_TEC_PRE_) -// definition of macro ends in semicolon --esym(823, - QS_TEST_PROBE_DEF) - -// M3-R11.1(R) conversion between pointer to function type +//! M4-R11.1(R) conversion between pointer to function type +//! @tr{DVP-QS-MC4-R11_01} -emacro(9074, QS_FUN_DICTIONARY, QS_TEST_PROBE_DEF) -// M3-R20.10(A) stringize operator +// M4-R15.5(A) return statement before end of function +//! @tr{DVP-QS-MC4-R15_05} +-emacro(904, + QS_TEST_PROBE) + +//! M4-R19.2(A) union declared +//! @tr{DVR-QS-MC4-R19_02} +-esym(9018, + Variant) + +//! M4-R20.10(A) stringize operator +//! @tr{DVP-QS-MC4-R20_10} -esym(9024, QS_OBJ_DICTIONARY, QS_OBJ_ARR_DICTIONARY, @@ -380,18 +415,12 @@ QS_USR_DICTIONARY, QS_ENUM_DICTIONARY) -// M3-R10.3(R) cannot assign enum to different essential type --emacro(9034, - QS_SIG_DICTIONARY) - -// M3-R15.5(A) return statement before end of function --emacro(904, - QS_TEST_PROBE) - -// M3-R19.2(A) union declared --esym(9018, - Variant) - -// implicit conversion of enum to integral type 'int' +//! implicit conversion of enum to integral type 'int' +//! @tr{DVP-QS-PCLP-641} -emacro(641, QS_SIG_DICTIONARY) + +//! definition of macro ends in semicolon +//! @tr{DVP-QS-PCLP-823} +-esym(823, + QS_TEST_PROBE_DEF) diff --git a/ports/lint-plus/qv/qf_port.h b/ports/lint-plus/qv/qf_port.h deleted file mode 100644 index 748fe467..00000000 --- a/ports/lint-plus/qv/qf_port.h +++ /dev/null @@ -1,55 +0,0 @@ -/*============================================================================ -* QP/C Real-Time Embedded Framework (RTEF) -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2022-07-29 -* @version Last updated for: @ref qpc_7_0_1 -* -* @file -* @brief QF/C port example for QV, generic C compiler. -*/ -#ifndef QF_PORT_H -#define QF_PORT_H - -/* interrupt disabling mechanism */ -#define QF_INT_DISABLE() intDisable() -#define QF_INT_ENABLE() intEnable() - -void intDisable(void); -void intEnable(void); - -/* QF critical section mechanism */ -#define QF_CRIT_STAT_TYPE crit_stat_t -#define QF_CRIT_ENTRY(stat_) ((stat_) = critEntry()) -#define QF_CRIT_EXIT(stat_) critExit(stat_) - -typedef unsigned int crit_stat_t; -crit_stat_t critEntry(void); -void critExit(crit_stat_t stat); - -#include "qep_port.h" /* QEP port */ -#include "qv_port.h" /* QV port */ - -#endif /* QF_PORT_H */ - diff --git a/ports/lint-plus/qv/qp_port.h b/ports/lint-plus/qv/qp_port.h new file mode 100644 index 00000000..625fa957 --- /dev/null +++ b/ports/lint-plus/qv/qp_port.h @@ -0,0 +1,86 @@ +//============================================================================ +// QP/C Real-Time Embedded Framework (RTEF) +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +//============================================================================ +//! @date Last updated on: 2023-09-07 +//! @version Last updated for: @ref qpc_7_3_0 +//! +//! @file +//! @brief QP/C "port" to PC-Lint-Plus, QV kernel, generic C99 + +#ifndef QP_PORT_H_ +#define QP_PORT_H_ + +#include // Exact-width types. WG14/N843 C99 Standard +#include // Boolean type. WG14/N843 C99 Standard + +#ifdef QP_CONFIG +#include "qp_config.h" // external QP configuration +#endif + +// no-return function specifier (C11 Standard) +#define Q_NORETURN _Noreturn void + +// QF configuration for QV -- data members of the QActive class... + +// QV event-queue used for AOs +#define QACTIVE_EQUEUE_TYPE QEQueue + +// QF "thread" type used to store the MPU settings in the AO +#define QACTIVE_THREAD_TYPE void const * + +// interrupt disabling mechanism +#define QF_INT_DISABLE() intDisable() +#define QF_INT_ENABLE() intEnable() + +// QF critical section mechanism +#define QF_CRIT_STAT uint32_t crit_stat_; +#define QF_CRIT_ENTRY() (crit_stat_ = critEntry()) +#define QF_CRIT_EXIT() critExit(crit_stat_) + +#define QV_CPU_SLEEP() \ +do { \ + __disable_interrupt(); \ + QF_INT_ENABLE(); \ + __WFI(); \ + __enable_interrupt(); \ +} while (false) + +void intDisable(void); +void intEnable(void); +uint32_t critEntry(void); +void critExit(uint32_t stat); + +// include files ------------------------------------------------------------- +#include "qequeue.h" // QV kernel uses the native QP event queue +#include "qmpool.h" // QV kernel uses the native QP memory pool +#include "qp.h" // QP framework +#include "qv.h" // QV kernel + +#endif // QP_PORT_H_ + diff --git a/ports/lint-plus/qv/qv_port.h b/ports/lint-plus/qv/qv_port.h deleted file mode 100644 index 0a5243bd..00000000 --- a/ports/lint-plus/qv/qv_port.h +++ /dev/null @@ -1,55 +0,0 @@ -/*============================================================================ -* QP/C Real-Time Embedded Framework (RTEF) -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2022-07-29 -* @version Last updated for: @ref qpc_7_0_1 -* -* @file -* @brief QV/C port example for a generic C compiler. -*/ -#ifndef QV_PORT_H -#define QV_PORT_H - -/*! Macro to put the CPU to sleep safely in the cooperative -* QV kernel (inside QV_onIdle()). -*/ -/** -* @description -* This macro is provided in some QP ports for the QV kernel and -* in general it depends on the interrupt disabling policy. -* -* @note The provided code is just an example (for ARM Cortex-M). -*/ -#define QV_CPU_SLEEP() do { \ - __disable_interrupt(); \ - QF_INT_ENABLE(); \ - __WFI(); \ - __enable_interrupt(); \ -} while (false) - -#include "qv.h" /* QV platform-independent public interface */ - -#endif /* QV_PORT_H */ - diff --git a/ports/lint-plus/qxk/qf_port.h b/ports/lint-plus/qxk/qf_port.h deleted file mode 100644 index 01207481..00000000 --- a/ports/lint-plus/qxk/qf_port.h +++ /dev/null @@ -1,54 +0,0 @@ -/*============================================================================ -* QP/C Real-Time Embedded Framework (RTEF) -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2022-07-29 -* @version Last updated for: @ref qpc_7_0_1 -* -* @file -* @brief QF/C port example for QXK, generic C99 compiler. -*/ -#ifndef QF_PORT_H -#define QF_PORT_H - -/* interrupt disabling mechanism */ -#define QF_INT_DISABLE() intDisable() -#define QF_INT_ENABLE() intEnable() - -void intDisable(void); -void intEnable(void); - -/* QF critical section mechanism */ -#define QF_CRIT_STAT_TYPE crit_stat_t -#define QF_CRIT_ENTRY(stat_) ((stat_) = critEntry()) -#define QF_CRIT_EXIT(stat_) critExit(stat_) - -typedef unsigned int crit_stat_t; -crit_stat_t critEntry(void); -void critExit(crit_stat_t stat); - -#include "qep_port.h" /* QEP port */ -#include "qxk_port.h" /* QXK port */ - -#endif /* QF_PORT_H */ diff --git a/ports/lint-plus/qxk/qp_port.h b/ports/lint-plus/qxk/qp_port.h new file mode 100644 index 00000000..84a2f19c --- /dev/null +++ b/ports/lint-plus/qxk/qp_port.h @@ -0,0 +1,101 @@ +//============================================================================ +// QP/C Real-Time Embedded Framework (RTEF) +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +//============================================================================ +//! @date Last updated on: 2023-09-07 +//! @version Last updated for: @ref qpc_7_3_0 +//! +//! @file +//! @brief QP/C "port" to PC-Lint-Plus, QXK kernel, generic C99 + +#ifndef QP_PORT_H_ +#define QP_PORT_H_ + +#include // Exact-width types. WG14/N843 C99 Standard +#include // Boolean type. WG14/N843 C99 Standard + +#ifdef QP_CONFIG +#include "qp_config.h" // external QP configuration +#endif + +// no-return function specifier (C11 Standard) +#define Q_NORETURN _Noreturn void + +// QF configuration for QXK -- data members of the QActive class... + +// QXK event-queue type used for AOs and eXtended threads. +#define QACTIVE_EQUEUE_TYPE QEQueue + +// QXK OS-Object type used for the private stack pointer for eXtended threads. +// (The private stack pointer is NULL for basic-threads). +#define QACTIVE_OS_OBJ_TYPE void* + +// QF "thread" type used to store the MPU settings in the AO +#define QACTIVE_THREAD_TYPE void const * + +// interrupt disabling mechanism +#define QF_INT_DISABLE() intDisable() +#define QF_INT_ENABLE() intEnable() + +// QF critical section mechanism +#define QF_CRIT_STAT uint32_t crit_stat_; +#define QF_CRIT_ENTRY() (crit_stat_ = critEntry()) +#define QF_CRIT_EXIT() critExit(crit_stat_) + +// Check if the code executes in the ISR context +#define QXK_ISR_CONTEXT_() (QXK_get_IPSR() != 0U) + +// Define the ISR entry sequence +#define QXK_ISR_ENTRY() ((void)0) + +// Define the ISR exit sequence +#define QXK_ISR_EXIT() do { \ + QF_INT_DISABLE(); \ + if (QXK_sched_() != 0U) { \ + *Q_UINT2PTR_CAST(uint32_t, 0xE000ED04U) = (1U << 28U);\ + } \ + QF_INT_ENABLE(); \ +} while (false) + +#define QXK_CONTEXT_SWITCH_() (QXK_trigPendSV()) + +void intDisable(void); +void intEnable(void); +uint32_t critEntry(void); +void critExit(uint32_t stat); +uint32_t QXK_get_IPSR(void); +void QXK_trigPendSV(void); + +// include files ------------------------------------------------------------- +#include "qequeue.h" // QXK kernel uses the native QP event queue +#include "qmpool.h" // QXK kernel uses the native QP memory pool +#include "qp.h" // QP framework +#include "qxk.h" // QXK kernel + +#endif // QP_PORT_H_ + diff --git a/ports/lint-plus/qxk/qxk_port.h b/ports/lint-plus/qxk/qxk_port.h deleted file mode 100644 index c16de180..00000000 --- a/ports/lint-plus/qxk/qxk_port.h +++ /dev/null @@ -1,84 +0,0 @@ -/*============================================================================ -* QP/C Real-Time Embedded Framework (RTEF) -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2022-12-13 -* @version Last updated for: @ref qpc_7_2_0 -* -* @file -* @brief QXK/C port example for a generic C99 compiler. -* @description -* This is an example of a QP/C port with the documentation for the -* configuration macros and includes. -*/ -#ifndef QXK_PORT_H -#define QXK_PORT_H - -/*==========================================================================*/ - -/*! determination if the code executes in the ISR context (ARM Cortex-M) */ -#define QXK_ISR_CONTEXT_() (getSR() != 0U) - -/*! activate the context-switch callback */ -#define QF_ON_CONTEXT_SW 1 - -/*! trigger context switch (used internally in QXK only) */ -#define QXK_CONTEXT_SWITCH_() (trigPendSV()) - -/* QXK interrupt entry and exit... */ -/*! Define the ISR entry sequence, if the compiler supports writing -* interrupts in C. -*/ -#define QXK_ISR_ENTRY() do { \ - QF_INT_DISABLE(); \ - ++QF_intNest_; \ - QF_QS_ISR_ENTRY(QF_intNest_, QXK_currPrio_); \ - QF_INT_ENABLE(); \ -} while (false) - - -/*! Define the ISR exit sequence, if the compiler supports writing -* interrupts in C. */ -/** -* @note -* This is just an example of #QXK_ISR_EXIT. You need to define the macro -* appropriately for the CPU/compiler you're using. Also, some QXK ports will -* not define this macro, but instead will provide ISR skeleton in assembly. -*/ -#define QXK_ISR_EXIT() do { \ - QF_INT_DISABLE(); \ - --QF_intNest_; \ - if (QF_intNest_ == 0U) { \ - QXK_sched_(); \ - } \ - QF_INT_ENABLE(); \ -} while (false) - -uint32_t getSR(void); -void trigPendSV(void); - -#include "qxk.h" /* QXK platform-independent public interface */ - -#endif /* QXK_PORT_H */ - diff --git a/ports/lint-plus/std.lnt b/ports/lint-plus/std.lnt index 28afa778..5e6957c7 100644 --- a/ports/lint-plus/std.lnt +++ b/ports/lint-plus/std.lnt @@ -22,8 +22,8 @@ // // //============================================================================ -//! @date Last updated on: 2022-10-12 -//! @version Last updated for version: 7.1.3 +//! @date Last updated on: 2023-06-06 +//! @version Last updated for version: 7.3.0 //! //! @file //! @brief PC-Lint-Plus standard option file @@ -35,8 +35,6 @@ -width(120,4) // break lines after 99 characters with 4 characters indent +flm // make sure no foreign includes change the format --std=c99 // apply the C99 language standard - -zero(99) // don't stop because of warnings -passes(2) // make two passes (for better error messages) -restore_at_end // don't let -e options bleed to other files diff --git a/ports/lint-plus/stdbool.h b/ports/lint-plus/stdbool.h index 04416a0b..acefc5f2 100644 --- a/ports/lint-plus/stdbool.h +++ b/ports/lint-plus/stdbool.h @@ -1,32 +1,30 @@ -/** -* @file -* @brief Boolean type and constansts. WG14/N843 C99 Standard, Section 7.16 -* -* @description -* This header is part of the ANSI C99 standard library to define the -* standard Boolean type as well as the 'true' and 'false' constansts. -*/ -#ifndef STDBOOL_H -#define STDBOOL_H +//! @file +//! @brief Boolean type and constansts. WG14/N843 C99 Standard, Section 7.16 +//! +//! @description +//! This header is part of the ANSI C99 standard library to define the +//! standard Boolean type as well as the 'true' and 'false' constansts. +#ifndef STDBOOL_H_ +#define STDBOOL_H_ -/*lint -save */ -/*lint -e9071 M3-R21.1(r), defined macro is reserved to the compiler */ -/*lint -e9093 the name is reserved to the compiler */ -/*lint -emacro(8523, false, true) cast to boolean */ +//lint -save +//lint -e9071 M3-R21.1(r), defined macro is reserved to the compiler +//lint -e9093 the name is reserved to the compiler +//lint -emacro(8523, false, true) cast to boolean #ifndef __cplusplus -typedef _Bool bool; /*!< standard Boolean data type */ +typedef _Bool bool; //!< standard Boolean data type -/*! standard 'false' constant */ +//! standard 'false' constant #define false ((bool)0) -/*! standard 'true' constant */ +//! standard 'true' constant #define true ((bool)1) -#endif /* !__cplusplus */ +#endif // !__cplusplus -/*lint -restore */ +//lint -restore -#endif /* STDBOOL_H */ +#endif // STDBOOL_H_ diff --git a/ports/msp430/qk/qep_port.h b/ports/msp430/qk/qep_port.h deleted file mode 100644 index f7a5a9a8..00000000 --- a/ports/msp430/qk/qep_port.h +++ /dev/null @@ -1,40 +0,0 @@ -/*============================================================================ -* QP/C Real-Time Embedded Framework (RTEF) -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2023-01-07 -* @version Last updated for: @ref qpc_7_2_0 -* -* @file -* @brief QEP/C port, generic C99 compiler -*/ -#ifndef QEP_PORT_H -#define QEP_PORT_H - -#include /* Exact-width types. WG14/N843 C99 Standard */ -#include /* Boolean type. WG14/N843 C99 Standard */ - -#include "qep.h" /* QEP platform-independent public interface */ - -#endif /* QEP_PORT_H */ diff --git a/ports/msp430/qk/qf_port.h b/ports/msp430/qk/qf_port.h deleted file mode 100644 index 9824d6b0..00000000 --- a/ports/msp430/qk/qf_port.h +++ /dev/null @@ -1,74 +0,0 @@ -/*============================================================================ -* QP/C Real-Time Embedded Framework (RTEF) -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2023-01-07 -* @version Last updated for: @ref qpc_7_2_0 -* -* @file -* @brief QF/C port to MSP430, preemptive QK kernel -*/ -#ifndef QF_PORT_H -#define QF_PORT_H - -/* The maximum number of active objects in the application, see NOTE01 */ -#define QF_MAX_ACTIVE 8U - -#define QF_EVENT_SIZ_SIZE 1U -#define QF_EQUEUE_CTR_SIZE 1U -#define QF_MPOOL_SIZ_SIZE 1U -#define QF_MPOOL_CTR_SIZE 1U -#define QF_TIMEEVT_CTR_SIZE 2U - -/* QF interrupt disable/enable... */ -#define QF_INT_DISABLE() __disable_interrupt() -#define QF_INT_ENABLE() __enable_interrupt() - -/* QF critical section entry/exit... */ -#define QF_CRIT_STAT_TYPE unsigned short -#define QF_CRIT_ENTRY(stat_) do { \ - (stat_) = __get_interrupt_state(); \ - __disable_interrupt(); \ -} while (false) -#define QF_CRIT_EXIT(stat_) __set_interrupt_state(stat_) - - -#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__) - #include /* intrinsic functions */ -#elif defined(__GNUC__) - #include - #include "in430.h" -#endif - -#include "qep_port.h" /* QEP port */ -#include "qk_port.h" /* QK preemptive kernel port */ -#include "qf.h" /* QF platform-independent public interface */ - -/*==========================================================================*/ -/* NOTE01: -* The maximum number of active objects QF_MAX_ACTIVE can be increased -* up to 64, if necessary. Here it is set to a lower level to save some RAM. -*/ - -#endif /* QF_PORT_H */ diff --git a/ports/msp430/qk/qk_port.h b/ports/msp430/qk/qk_port.h deleted file mode 100644 index cac3dcd0..00000000 --- a/ports/msp430/qk/qk_port.h +++ /dev/null @@ -1,52 +0,0 @@ -/*============================================================================ -* QP/C Real-Time Embedded Framework (RTEF) -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2022-10-02 -* @version Last updated for: @ref qpc_7_1_2 -* -* @file -* @brief QK/C port port to MSP430 -*/ -#ifndef QK_PORT_H -#define QK_PORT_H - -/* QK interrupt entry and exit... */ -#define QK_ISR_ENTRY() (++QF_intNest_) - -#define QK_ISR_EXIT() do { \ - --QF_intNest_; \ - if (QF_intNest_ == 0U) { \ - if (QK_sched_() != 0U) { \ - QK_activate_(); \ - } \ - } \ - else { \ - Q_ERROR(); \ - } \ -} while (false) - -#include "qk.h" /* QK platform-independent public interface */ - -#endif /* QK_PORT_H */ diff --git a/ports/msp430/qk/qp_port.h b/ports/msp430/qk/qp_port.h new file mode 100644 index 00000000..be004a4b --- /dev/null +++ b/ports/msp430/qk/qp_port.h @@ -0,0 +1,100 @@ +//============================================================================ +// QP/C Real-Time Embedded Framework (RTEF) +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC . +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +//============================================================================ +//! @date Last updated on: 2023-09-07 +//! @version Last updated for: @ref qpc_7_3_0 +//! +//! @file +//! @brief QP/C port to MSP430, QK kernel, TI, GNU, IAR compilers + +#ifndef QP_PORT_H_ +#define QP_PORT_H_ + +#include // Exact-width types. WG14/N843 C99 Standard +#include // Boolean type. WG14/N843 C99 Standard + +#include "qp_config.h" // external QP configuration required in this port + +#if defined(__TI_COMPILER_VERSION__) || defined(__GNUC__) + // no-return function specifier (C11 Standard) + #define Q_NORETURN _Noreturn void +#elif defined(__IAR_SYSTEMS_ICC__) + #define Q_NORETURN __noreturn void +#endif + +// QF configuration for QK -- data members of the QActive class... + +// QActive event queue type +#define QACTIVE_EQUEUE_TYPE QEQueue +// QACTIVE_OS_OBJ_TYPE not used in this port +// QACTIVE_THREAD_TYPE not used in this port + +// QF interrupt disable/enable... +#define QF_INT_DISABLE() __disable_interrupt() +#define QF_INT_ENABLE() __enable_interrupt() + +// QF critical section entry/exit... +#define QF_CRIT_STAT unsigned short int_state_; +#define QF_CRIT_ENTRY() do { \ + int_state_ = __get_interrupt_state(); \ + __disable_interrupt(); \ +} while (false) + +#define QF_CRIT_EXIT() __set_interrupt_state(int_state_) + +// Check if the code executes in the ISR context +#define QK_ISR_CONTEXT_() (QK_priv_.intNest != 0U) + +// QK interrupt entry and exit... +#define QK_ISR_ENTRY() (++QK_priv_.intNest) + +#define QK_ISR_EXIT() do { \ + --QK_priv_.intNest; \ + if (QK_priv_.intNest == 0U) { \ + if (QK_sched_() != 0U) { \ + QK_activate_(); \ + } \ + } \ +} while (false) + +// include files ------------------------------------------------------------- +#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__) + #include +#elif defined(__GNUC__) + #include + #include "in430.h" +#endif + +#include "qequeue.h" // QK kernel uses the native QP event queue +#include "qmpool.h" // QK kernel uses the native QP memory pool +#include "qp.h" // QP framework +#include "qk.h" // QK kernel + +#endif // QP_PORT_H_ + diff --git a/ports/msp430/qk/qs_port.h b/ports/msp430/qk/qs_port.h index b1c77d47..5330e720 100644 --- a/ports/msp430/qk/qs_port.h +++ b/ports/msp430/qk/qs_port.h @@ -1,60 +1,56 @@ -/*============================================================================ -* QP/C Real-Time Embedded Framework (RTEF) -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2022-06-12 -* @version Last updated for: @ref qpc_7_0_1 -* -* @file -* @brief QS/C port to a 32-bit CPU and a generic C99 compiler. -* @description -* This is an example of a QP/C port with the documentation for the -* configuration macros and includes. -*/ -#ifndef QS_PORT_H -#define QS_PORT_H +//============================================================================ +// QP/C Real-Time Embedded Framework (RTEF) +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +//============================================================================ +//! @date Last updated on: 2023-08-16 +//! @version Last updated for: @ref qpc_7_3_0 +//! +//! @file +//! @brief QS/C port to a 16-bit CPU and a generic C11 compiler. -/* QS time-stamp size in bytes */ +#ifndef QS_PORT_H_ +#define QS_PORT_H_ + +// QS time-stamp size in bytes #define QS_TIME_SIZE 4U -/* object pointer size in bytes */ -#define QS_OBJ_PTR_SIZE 4U +// object pointer size in bytes +#define QS_OBJ_PTR_SIZE 2U -/* function pointer size in bytes */ -#define QS_FUN_PTR_SIZE 4U +// function pointer size in bytes +#define QS_FUN_PTR_SIZE 2U -/*==========================================================================*/ -/* NOTE: QS might be used with or without other QP components, in which -* case the separate definitions of the macros QF_CRIT_STAT_TYPE, -* QF_CRIT_ENTRY, and QF_CRIT_EXIT are needed. In this port QS is configured -* to be used with the other QP component, by simply including "qf_port.h" -* *before* "qs.h". -*/ -#ifndef QF_PORT_H -#include "qf_port.h" /* use QS with QF */ +//============================================================================ +// NOTE: QS might be used with or without other QP components, in which +// case the separate definitions of the macros QF_CRIT_STAT, QF_CRIT_ENTRY(), +// and QF_CRIT_EXIT() are needed. In this port QS is configured to be used +// with the other QP component, by simply including "qp_port.h" +//*before* "qs.h". +#ifndef QP_PORT_H_ +#include "qp_port.h" // use QS with QF #endif -#include "qs.h" /* QS platform-independent public interface */ +#include "qs.h" // QS platform-independent public interface + +#endif // QS_PORT_H_ -#endif /* QS_PORT_H */ diff --git a/ports/msp430/qutest/qep_port.h b/ports/msp430/qutest/qep_port.h deleted file mode 100644 index f7a5a9a8..00000000 --- a/ports/msp430/qutest/qep_port.h +++ /dev/null @@ -1,40 +0,0 @@ -/*============================================================================ -* QP/C Real-Time Embedded Framework (RTEF) -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2023-01-07 -* @version Last updated for: @ref qpc_7_2_0 -* -* @file -* @brief QEP/C port, generic C99 compiler -*/ -#ifndef QEP_PORT_H -#define QEP_PORT_H - -#include /* Exact-width types. WG14/N843 C99 Standard */ -#include /* Boolean type. WG14/N843 C99 Standard */ - -#include "qep.h" /* QEP platform-independent public interface */ - -#endif /* QEP_PORT_H */ diff --git a/ports/msp430/qutest/qf_port.h b/ports/msp430/qutest/qf_port.h deleted file mode 100644 index 7d38297d..00000000 --- a/ports/msp430/qutest/qf_port.h +++ /dev/null @@ -1,100 +0,0 @@ -/*============================================================================ -* QP/C Real-Time Embedded Framework (RTEF) -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2022-11-11 -* @version Last updated for: @ref qpc_7_1_3 -* -* @file -* @brief QF/C port to MSP430, QUTEST, generic C99 compiler -*/ -#ifndef QF_PORT_H -#define QF_PORT_H - -/* QUTEST event queue and thread types */ -#define QF_EQUEUE_TYPE QEQueue -/*#define QF_OS_OBJECT_TYPE */ -/*#define QF_THREAD_TYPE */ - -/* The maximum number of active objects in the application, see NOTE01 */ -#define QF_MAX_ACTIVE 8U - -#define QF_EVENT_SIZ_SIZE 1U -#define QF_EQUEUE_CTR_SIZE 1U -#define QF_MPOOL_SIZ_SIZE 1U -#define QF_MPOOL_CTR_SIZE 1U -#define QF_TIMEEVT_CTR_SIZE 2U - -/* QF interrupt disable/enable */ -#define QF_INT_DISABLE() (++QF_intLock_) -#define QF_INT_ENABLE() (--QF_intLock_) - -/* QF critical section */ -/* QF_CRIT_STAT_TYPE not defined */ -#define QF_CRIT_ENTRY(dummy) QF_INT_DISABLE() -#define QF_CRIT_EXIT(dummy) QF_INT_ENABLE() - -/* QF_LOG2 not defined -- use the internal LOG2() implementation */ - -#include "qep_port.h" /* QEP port */ -#include "qequeue.h" /* QUTEST port uses QEQueue event-queue */ -#include "qmpool.h" /* QUTEST port uses QMPool memory-pool */ -#include "qf.h" /* QF platform-independent public interface */ - -/****************************************************************************/ -/* interface used only inside QF implementation, but not in applications */ -#ifdef QP_IMPL - - /* QUTEST scheduler locking (not used) */ - #define QF_SCHED_STAT_ - #define QF_SCHED_LOCK_(dummy) ((void)0) - #define QF_SCHED_UNLOCK_() ((void)0) - - /* native event queue operations */ - #define QACTIVE_EQUEUE_WAIT_(me_) \ - Q_ASSERT_ID(0, (me_)->eQueue.frontEvt != (QEvt *)0) - #define QACTIVE_EQUEUE_SIGNAL_(me_) \ - QPSet_insert(&QF_readySet_, (uint_fast8_t)(me_)->prio) - - /* native QF event pool operations */ - #define QF_EPOOL_TYPE_ QMPool - #define QF_EPOOL_INIT_(p_, poolSto_, poolSize_, evtSize_) \ - (QMPool_init(&(p_), (poolSto_), (poolSize_), (evtSize_))) - #define QF_EPOOL_EVENT_SIZE_(p_) ((uint_fast16_t)(p_).blockSize) - #define QF_EPOOL_GET_(p_, e_, m_, qs_id_) \ - ((e_) = (QEvt *)QMPool_get(&(p_), (m_), (qs_id_))) - #define QF_EPOOL_PUT_(p_, e_, qs_id_) \ - (QMPool_put(&(p_), (e_), (qs_id_))) - - #include "qf_pkg.h" /* internal QF interface */ - -#endif /* QP_IMPL */ - -/***************************************************************************** -* NOTE01: -* The maximum number of active objects QF_MAX_ACTIVE can be increased -* up to 64, if necessary. Here it is set to a lower level to save some RAM. -*/ - -#endif /* QF_PORT_H */ diff --git a/ports/msp430/qutest/qp_port.h b/ports/msp430/qutest/qp_port.h new file mode 100644 index 00000000..9ffe295b --- /dev/null +++ b/ports/msp430/qutest/qp_port.h @@ -0,0 +1,115 @@ +//============================================================================ +// QP/C Real-Time Embedded Framework (RTEF) +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC . +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +//============================================================================ +//! @date Last updated on: 2023-09-07 +//! @version Last updated for: @ref qpc_7_3_0 +//! +//! @file +//! @brief QP/C "port" for QUTEST on MSP430, generic C11 compiler + +#ifndef QP_PORT_H_ +#define QP_PORT_H_ + +#include // Exact-width types. WG14/N843 C99 Standard +#include // Boolean type. WG14/N843 C99 Standard + +#include "qp_config.h" // external QP configuration required in this port + +#if defined(__TI_COMPILER_VERSION__) || defined(__GNUC__) + // no-return function specifier (C11 Standard) + #define Q_NORETURN _Noreturn void +#elif defined(__IAR_SYSTEMS_ICC__) + #define Q_NORETURN __noreturn void +#endif + +// QF configuration for QK -- data members of the QActive class... + +// QActive event queue type +#define QACTIVE_EQUEUE_TYPE QEQueue +// QACTIVE_OS_OBJ_TYPE not used in this port +// QACTIVE_THREAD_TYPE not used in this port + +// QF interrupt disable/enable +#define QF_INT_DISABLE() (++QS_tstPriv_.intLock) +#define QF_INT_ENABLE() (--QS_tstPriv_.intLock) + +// QF critical section +#define QF_CRIT_STAT +#define QF_CRIT_ENTRY() QF_INT_DISABLE() +#define QF_CRIT_EXIT() QF_INT_ENABLE() + +// QF_LOG2 not defined -- use the internal LOG2() implementation + +// include files ------------------------------------------------------------- +#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__) + #include +#elif defined(__GNUC__) + #include + #include "in430.h" +#endif + +#include "qequeue.h" // QUTest port uses QEQueue event-queue +#include "qmpool.h" // QUTest port uses QMPool memory-pool +#include "qp.h" // QP framework + +//============================================================================ +// interface used only inside QF implementation, but not in applications +#ifdef QP_IMPL + + // QUTest scheduler locking (not used) + #define QF_SCHED_STAT_ + #define QF_SCHED_LOCK_(dummy) ((void)0) + #define QF_SCHED_UNLOCK_() ((void)0) + + // native event queue operations + #define QACTIVE_EQUEUE_WAIT_(me_) \ + Q_ASSERT_INCRIT(110, (me_)->eQueue.frontEvt != (QEvt *)0) +#ifndef Q_UNSAFE + #define QACTIVE_EQUEUE_SIGNAL_(me_) \ + QPSet_insert(&QS_tstPriv_.readySet, (uint_fast8_t)(me_)->prio); \ + QPSet_update_(&QS_tstPriv_.readySet, &QS_tstPriv_.readySet_dis) +#else + #define QACTIVE_EQUEUE_SIGNAL_(me_) \ + QPSet_insert(&QF_readySet_, (uint_fast8_t)(me_)->prio) +#endif + + // native QF event pool operations + #define QF_EPOOL_TYPE_ QMPool + #define QF_EPOOL_INIT_(p_, poolSto_, poolSize_, evtSize_) \ + (QMPool_init(&(p_), (poolSto_), (poolSize_), (evtSize_))) + #define QF_EPOOL_EVENT_SIZE_(p_) ((uint_fast16_t)(p_).blockSize) + #define QF_EPOOL_GET_(p_, e_, m_, qs_id_) \ + ((e_) = (QEvt *)QMPool_get(&(p_), (m_), (qs_id_))) + #define QF_EPOOL_PUT_(p_, e_, qs_id_) \ + (QMPool_put(&(p_), (e_), (qs_id_))) + +#endif // QP_IMPL + +#endif // QP_PORT_H_ + diff --git a/ports/msp430/qutest/qs_port.h b/ports/msp430/qutest/qs_port.h index b1c77d47..5330e720 100644 --- a/ports/msp430/qutest/qs_port.h +++ b/ports/msp430/qutest/qs_port.h @@ -1,60 +1,56 @@ -/*============================================================================ -* QP/C Real-Time Embedded Framework (RTEF) -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2022-06-12 -* @version Last updated for: @ref qpc_7_0_1 -* -* @file -* @brief QS/C port to a 32-bit CPU and a generic C99 compiler. -* @description -* This is an example of a QP/C port with the documentation for the -* configuration macros and includes. -*/ -#ifndef QS_PORT_H -#define QS_PORT_H +//============================================================================ +// QP/C Real-Time Embedded Framework (RTEF) +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +//============================================================================ +//! @date Last updated on: 2023-08-16 +//! @version Last updated for: @ref qpc_7_3_0 +//! +//! @file +//! @brief QS/C port to a 16-bit CPU and a generic C11 compiler. -/* QS time-stamp size in bytes */ +#ifndef QS_PORT_H_ +#define QS_PORT_H_ + +// QS time-stamp size in bytes #define QS_TIME_SIZE 4U -/* object pointer size in bytes */ -#define QS_OBJ_PTR_SIZE 4U +// object pointer size in bytes +#define QS_OBJ_PTR_SIZE 2U -/* function pointer size in bytes */ -#define QS_FUN_PTR_SIZE 4U +// function pointer size in bytes +#define QS_FUN_PTR_SIZE 2U -/*==========================================================================*/ -/* NOTE: QS might be used with or without other QP components, in which -* case the separate definitions of the macros QF_CRIT_STAT_TYPE, -* QF_CRIT_ENTRY, and QF_CRIT_EXIT are needed. In this port QS is configured -* to be used with the other QP component, by simply including "qf_port.h" -* *before* "qs.h". -*/ -#ifndef QF_PORT_H -#include "qf_port.h" /* use QS with QF */ +//============================================================================ +// NOTE: QS might be used with or without other QP components, in which +// case the separate definitions of the macros QF_CRIT_STAT, QF_CRIT_ENTRY(), +// and QF_CRIT_EXIT() are needed. In this port QS is configured to be used +// with the other QP component, by simply including "qp_port.h" +//*before* "qs.h". +#ifndef QP_PORT_H_ +#include "qp_port.h" // use QS with QF #endif -#include "qs.h" /* QS platform-independent public interface */ +#include "qs.h" // QS platform-independent public interface + +#endif // QS_PORT_H_ -#endif /* QS_PORT_H */ diff --git a/ports/msp430/qv/qep_port.h b/ports/msp430/qv/qep_port.h deleted file mode 100644 index f7a5a9a8..00000000 --- a/ports/msp430/qv/qep_port.h +++ /dev/null @@ -1,40 +0,0 @@ -/*============================================================================ -* QP/C Real-Time Embedded Framework (RTEF) -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2023-01-07 -* @version Last updated for: @ref qpc_7_2_0 -* -* @file -* @brief QEP/C port, generic C99 compiler -*/ -#ifndef QEP_PORT_H -#define QEP_PORT_H - -#include /* Exact-width types. WG14/N843 C99 Standard */ -#include /* Boolean type. WG14/N843 C99 Standard */ - -#include "qep.h" /* QEP platform-independent public interface */ - -#endif /* QEP_PORT_H */ diff --git a/ports/msp430/qv/qf_port.h b/ports/msp430/qv/qf_port.h deleted file mode 100644 index be2181c1..00000000 --- a/ports/msp430/qv/qf_port.h +++ /dev/null @@ -1,74 +0,0 @@ -/*============================================================================ -* QP/C Real-Time Embedded Framework (RTEF) -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2022-07-30 -* @version Last updated for: @ref qpc_7_0_1 -* -* @file -* @brief QF/C port to MSP430, cooperative QV kernel -*/ -#ifndef QF_PORT_H -#define QF_PORT_H - -/* The maximum number of active objects in the application, see NOTE01 */ -#define QF_MAX_ACTIVE 8U - -#define QF_EVENT_SIZ_SIZE 1U -#define QF_EQUEUE_CTR_SIZE 1U -#define QF_MPOOL_SIZ_SIZE 1U -#define QF_MPOOL_CTR_SIZE 1U -#define QF_TIMEEVT_CTR_SIZE 2U - -/* QF interrupt disable/enable... */ -#define QF_INT_DISABLE() __disable_interrupt() -#define QF_INT_ENABLE() __enable_interrupt() - -/* QF critical section entry/exit... */ -#define QF_CRIT_STAT_TYPE unsigned short -#define QF_CRIT_ENTRY(stat_) do { \ - (stat_) = __get_interrupt_state(); \ - __disable_interrupt(); \ -} while (false) -#define QF_CRIT_EXIT(stat_) __set_interrupt_state(stat_) - - -#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__) - #include /* intrinsic functions */ -#elif defined(__GNUC__) - #include - #include "in430.h" -#endif - -#include "qep_port.h" /* QEP port */ -#include "qv_port.h" /* QV cooperative kernel port */ -#include "qf.h" /* QF platform-independent public interface */ - -/***************************************************************************** -* NOTE01: -* The maximum number of active objects QF_MAX_ACTIVE can be increased -* up to 64, if necessary. Here it is set to a lower level to save some RAM. -*/ - -#endif /* QF_PORT_H */ diff --git a/ports/msp430/qv/qp_port.h b/ports/msp430/qv/qp_port.h new file mode 100644 index 00000000..101b994c --- /dev/null +++ b/ports/msp430/qv/qp_port.h @@ -0,0 +1,85 @@ +//============================================================================ +// QP/C Real-Time Embedded Framework (RTEF) +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC . +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +//============================================================================ +//! @date Last updated on: 2023-09-07 +//! @version Last updated for: @ref qpc_7_3_0 +//! +//! @file +//! @brief QP/C port to MSP430, QV kernel, TI, GNU, IAR compilers + +#ifndef QP_PORT_H_ +#define QP_PORT_H_ + +#include // Exact-width types. WG14/N843 C99 Standard +#include // Boolean type. WG14/N843 C99 Standard + +#include "qp_config.h" // external QP configuration required in this port + +#if defined(__TI_COMPILER_VERSION__) || defined(__GNUC__) + // no-return function specifier (C11 Standard) + #define Q_NORETURN _Noreturn void +#elif defined(__IAR_SYSTEMS_ICC__) + #define Q_NORETURN __noreturn void +#endif + +// QF configuration for QV -- data members of the QActive class... + +// QActive event queue type +#define QACTIVE_EQUEUE_TYPE QEQueue +// QACTIVE_OS_OBJ_TYPE not used in this port +// QACTIVE_THREAD_TYPE not used in this port + +// QF interrupt disable/enable... +#define QF_INT_DISABLE() __disable_interrupt() +#define QF_INT_ENABLE() __enable_interrupt() + +// QF critical section entry/exit... +#define QF_CRIT_STAT unsigned short int_state_; +#define QF_CRIT_ENTRY() do { \ + int_state_ = __get_interrupt_state(); \ + __disable_interrupt(); \ +} while (false) + +#define QF_CRIT_EXIT() __set_interrupt_state(int_state_) + +// include files ------------------------------------------------------------- +#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__) + #include +#elif defined(__GNUC__) + #include + #include "in430.h" +#endif + +#include "qequeue.h" // QV kernel uses the native QP event queue +#include "qmpool.h" // QV kernel uses the native QP memory pool +#include "qp.h" // QP framework +#include "qv.h" // QV kernel + +#endif // QP_PORT_H_ + diff --git a/ports/msp430/qv/qs_port.h b/ports/msp430/qv/qs_port.h index b1c77d47..5330e720 100644 --- a/ports/msp430/qv/qs_port.h +++ b/ports/msp430/qv/qs_port.h @@ -1,60 +1,56 @@ -/*============================================================================ -* QP/C Real-Time Embedded Framework (RTEF) -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2022-06-12 -* @version Last updated for: @ref qpc_7_0_1 -* -* @file -* @brief QS/C port to a 32-bit CPU and a generic C99 compiler. -* @description -* This is an example of a QP/C port with the documentation for the -* configuration macros and includes. -*/ -#ifndef QS_PORT_H -#define QS_PORT_H +//============================================================================ +// QP/C Real-Time Embedded Framework (RTEF) +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +//============================================================================ +//! @date Last updated on: 2023-08-16 +//! @version Last updated for: @ref qpc_7_3_0 +//! +//! @file +//! @brief QS/C port to a 16-bit CPU and a generic C11 compiler. -/* QS time-stamp size in bytes */ +#ifndef QS_PORT_H_ +#define QS_PORT_H_ + +// QS time-stamp size in bytes #define QS_TIME_SIZE 4U -/* object pointer size in bytes */ -#define QS_OBJ_PTR_SIZE 4U +// object pointer size in bytes +#define QS_OBJ_PTR_SIZE 2U -/* function pointer size in bytes */ -#define QS_FUN_PTR_SIZE 4U +// function pointer size in bytes +#define QS_FUN_PTR_SIZE 2U -/*==========================================================================*/ -/* NOTE: QS might be used with or without other QP components, in which -* case the separate definitions of the macros QF_CRIT_STAT_TYPE, -* QF_CRIT_ENTRY, and QF_CRIT_EXIT are needed. In this port QS is configured -* to be used with the other QP component, by simply including "qf_port.h" -* *before* "qs.h". -*/ -#ifndef QF_PORT_H -#include "qf_port.h" /* use QS with QF */ +//============================================================================ +// NOTE: QS might be used with or without other QP components, in which +// case the separate definitions of the macros QF_CRIT_STAT, QF_CRIT_ENTRY(), +// and QF_CRIT_EXIT() are needed. In this port QS is configured to be used +// with the other QP component, by simply including "qp_port.h" +//*before* "qs.h". +#ifndef QP_PORT_H_ +#include "qp_port.h" // use QS with QF #endif -#include "qs.h" /* QS platform-independent public interface */ +#include "qs.h" // QS platform-independent public interface + +#endif // QS_PORT_H_ -#endif /* QS_PORT_H */ diff --git a/ports/msp430/qv/qv_port.h b/ports/msp430/qv/qv_port.h deleted file mode 100644 index 8e824cf3..00000000 --- a/ports/msp430/qv/qv_port.h +++ /dev/null @@ -1,37 +0,0 @@ -/*============================================================================ -* QP/C Real-Time Embedded Framework (RTEF) -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2022-07-30 -* @version Last updated for: @ref qpc_7_0_1 -* -* @file -* @brief QV/C port port to MSP430 -*/ -#ifndef QV_PORT_H -#define QV_PORT_H - -#include "qv.h" /* QV platform-independent public interface */ - -#endif /* QV_PORT_H */ diff --git a/ports/pic32/qk/xc32/qep_port.h b/ports/pic32/qk/xc32/qep_port.h deleted file mode 100644 index e3640a77..00000000 --- a/ports/pic32/qk/xc32/qep_port.h +++ /dev/null @@ -1,43 +0,0 @@ -/*============================================================================ -* QP/C Real-Time Embedded Framework (RTEF) -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2023-01-07 -* @version Last updated for: @ref qpc_7_2_0 -* -* @file -* @brief QEP/C port, GCC-ARM compiler -*/ -#ifndef QEP_PORT_H -#define QEP_PORT_H - -/*! no-return function specifier (GCC-ARM compiler) */ -#define Q_NORETURN __attribute__ ((noreturn)) void - -#include /* Exact-width types. WG14/N843 C99 Standard */ -#include /* Boolean type. WG14/N843 C99 Standard */ - -#include "qep.h" /* QEP platform-independent public interface */ - -#endif /* QEP_PORT_H */ diff --git a/ports/pic32/qk/xc32/qf_port.h b/ports/pic32/qk/xc32/qf_port.h deleted file mode 100644 index 577ab756..00000000 --- a/ports/pic32/qk/xc32/qf_port.h +++ /dev/null @@ -1,84 +0,0 @@ -/*============================================================================ -* QP/C Real-Time Embedded Framework (RTEF) -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2023-01-07 -* @version Last updated for: @ref qpc_7_2_0 -* -* @file -* @brief QF/C port, preemptive QK kernel, MPLAB-X XC32 compiler -*/ -#ifndef QF_PORT_H -#define QF_PORT_H - -/* The maximum number of system clock tick rates */ -#define QF_MAX_TICK_RATE 2U - -/* The maximum number of active objects in the application, see NOTE1 */ -#define QF_MAX_ACTIVE 32U - -/* QF interrupt disable/enable, see NOTE02 */ -#define QF_INT_DISABLE() __builtin_disable_interrupts() -#define QF_INT_ENABLE() __builtin_enable_interrupts() - -/* QF critical section entry/exit, see NOTE02 */ -/* QF_CRIT_STAT_TYPE not defined: unconditional interrupt disabling policy */ -#define QF_CRIT_ENTRY(dummy) QF_INT_DISABLE() -#define QF_CRIT_EXIT(dummy) QF_INT_ENABLE() - -/* fast log-base-2 with CLZ instruction */ -#define QF_LOG2(n_) ((uint8_t)(32 - _clz(n_))) - -#include /* for _clz() */ - -#include "qep_port.h" /* QEP port */ -#include "qk_port.h" /* QK preemptive kernel port */ -#include "qf.h" /* QF platform-independent public interface */ - -/***************************************************************************** -* NOTE1: -* The maximum number of active objects QF_MAX_ACTIVE can be increased -* up to 64, if necessary. Here it is set to a lower level to save some RAM. -* -* NOTE2: -* The DI (disable interrupts) instruction is used for fast, unconditional -* disabling and enabling of interrupts. The DI instruction only disables -* interrupts with priority levels 1-6. Priority level 7 interrupts and all -* trap events still have the ability to interrupt the CPU when the DI -* instruction is active. This means that from the perspective of QP, the -* level 7 interrupts are treated as non-maskable interrupts (NMIs). Such -* non-maskable interrupts _cannot_ call any QP services. In particular, -* they cannot post events. -* -* CAUTION: This QP port assumes that interrupt nesting is _enabled_, -* which is the default in the PIC32 processors. Interrupt nesting should -* never be disabled by setting the NSTDIS control bit (INTCON1<15>). If you -* don't want interrupts to nest, you can always prioritize them at the same -* level. For example, the default priority level for all interrupts is 4 out -* of reset. If you don't change this level for any interrupt the nesting of -* interrupt will not occur. -*/ - -#endif /* QF_PORT_H */ - diff --git a/ports/pic32/qk/xc32/qk_port.c b/ports/pic32/qk/xc32/qk_port.c index 5a5297f4..2f26718f 100644 --- a/ports/pic32/qk/xc32/qk_port.c +++ b/ports/pic32/qk/xc32/qk_port.c @@ -1,75 +1,74 @@ -/*============================================================================ -* QP/C Real-Time Embedded Framework (RTEF) -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2023-01-07 -* @version Last updated for: @ref qpc_7_2_0 -* -* @file -* @brief QK/C port, preemptive QK kernel, MPLAB-X XC32 compiler -*/ -#include "qf_port.h" +//============================================================================ +// QP/C Real-Time Embedded Framework (RTEF) +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +//============================================================================ +//! @date Last updated on: 2023-08-16 +//! @version Last updated for: @ref qpc_7_3_0 +//! +//! @file +//! @brief QK/C port, MPLAB-X XC32 compiler +#define QP_IMPL 1U +#include "qp_port.h" -/*..........................................................................*/ +//............................................................................ void QK_init(void) { - INTCONSET = _INTCON_MVEC_MASK; /* configure multi-vectored interrupts */ + INTCONSET = _INTCON_MVEC_MASK; // configure multi-vectored interrupts - IPC0bits.CS0IP = 1; /* priority 1 for Core Software Interrupt 0, NOTE1 */ - IPC0bits.CS0IS = 0; /* sub-priority 0 for Core Software Interrupt 0 */ + IPC0bits.CS0IP = 1; // priority 1 for Core Software Interrupt 0, NOTE1 + IPC0bits.CS0IS = 0; // sub-priority 0 for Core Software Interrupt 0 - IFS0CLR = _IFS0_CS0IF_MASK; /* clear the Core Software Interrupt 0 flag */ - IEC0SET = _IEC0_CS0IE_MASK; /* enable the Core Software Interrupt 0 */ + IFS0CLR = _IFS0_CS0IF_MASK; // clear the Core Software Interrupt 0 flag + IEC0SET = _IEC0_CS0IE_MASK; // enable the Core Software Interrupt 0 } -/*..........................................................................*/ +//............................................................................ __attribute__((vector(_CORE_SOFTWARE_0_VECTOR),interrupt(IPL1AUTO), nomips16)) -void QK_isr_(void) { /* NOTE2 */ - IFS0CLR = _IFS0_CS0IF_MASK; /* clear the Core Software Interrupt 0 flag */ +void QK_isr_(void) { // NOTE2 + IFS0CLR = _IFS0_CS0IF_MASK; // clear the Core Software Interrupt 0 flag QF_INT_DISABLE(); - _mtc0(_CP0_STATUS, _CP0_STATUS_SELECT, 0U); /* drop IPL to 0 */ - QK_activate_(); /* activate higher priority AO */ - _mtc0(_CP0_STATUS, _CP0_STATUS_SELECT, 1U << 10); /*restore IPL to 1 */ + _mtc0(_CP0_STATUS, _CP0_STATUS_SELECT, 0U); // drop IPL to 0 + QK_activate_(); // activate higher priority AO + _mtc0(_CP0_STATUS, _CP0_STATUS_SELECT, 1U << 10); //restore IPL to 1 QF_INT_ENABLE(); } -/***************************************************************************** -* NOTE1: -* The Core Software Interrupt 0 at priority 1, sub-priority 0 is reserved for -* QK. All other interrupts must have higher priority, e.g. 2-7. The user may -* _not_ set the shadow register set to priority 1. -* -* NOTE2: -* The QK_isr_() Core Software Interrupt 0 is used to perform the scheduling -* (asynchronous preemption in QK). This ISR is configured to use software -* register stacking (IPL1SOFT), because it can nest on itself. The QK_isr_() -* runs at IPL1, which should be the lowest of all other ISRs. This will -* guarantee that the Core Software Interrupt 0 will not execute until all -* other interrupts have completed, including any nesting. -* -* Any ISR that interacts with QP must trigger Core Software Interrupt 0. -* This triggering is accomplished in the macros QK_ISR_ENTRY()/ -* QK_ISR_EXIT(), which _must_ be placed at the entry and exit of every ISR, -* respectively. -*/ +//============================================================================ +// NOTE1: +// The Core Software Interrupt 0 at priority 1, sub-priority 0 is reserved for +// QK. All other interrupts must have higher priority, e.g. 2-7. The user may +// _not_ set the shadow register set to priority 1. +// +// NOTE2: +// The QK_isr_() Core Software Interrupt 0 is used to perform the scheduling +// (asynchronous preemption in QK). This ISR is configured to use software +// register stacking (IPL1SOFT), because it can nest on itself. The QK_isr_() +// runs at IPL1, which should be the lowest of all other ISRs. This will +// guarantee that the Core Software Interrupt 0 will not execute until all +// other interrupts have completed, including any nesting. +// +// Any ISR that interacts with QP must trigger Core Software Interrupt 0. +// This triggering is accomplished in the macros QK_ISR_ENTRY()/ +// QK_ISR_EXIT(), which _must_ be placed at the entry and exit of every ISR, +// respectively. +// diff --git a/ports/pic32/qk/xc32/qk_port.h b/ports/pic32/qk/xc32/qk_port.h deleted file mode 100644 index ef532e56..00000000 --- a/ports/pic32/qk/xc32/qk_port.h +++ /dev/null @@ -1,66 +0,0 @@ -/*============================================================================ -* QP/C Real-Time Embedded Framework (RTEF) -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2023-01-07 -* @version Last updated for: @ref qpc_7_2_0 -* -* @file -* @brief QK/C port, preemptive QK kernel, MPLAB-X XC32 compiler -*/ -#ifndef QK_PORT_H -#define QK_PORT_H - -/* QK interrupt entry and exit */ -#define QK_ISR_ENTRY() do { \ - QF_INT_DISABLE(); \ - ++QF_intNest_; \ - QF_INT_ENABLE(); \ -} while (false) - -#define QK_ISR_EXIT() do { \ - QF_INT_DISABLE(); \ - --QF_intNest_; \ - if (QK_sched_() != 0U) { \ - IFS0SET = _IFS0_CS0IF_MASK; \ - } \ - QF_INT_ENABLE(); \ -} while (false) - -/* initialization of the QK kernel */ -#define QK_INIT() QK_init() -void QK_init(void); - -#include "qk.h" /* QK platform-independent public interface */ - -/*==========================================================================*/ -/* NOTE01: -* Any interrupt service routine that interacts with QP must begin with the -* QK_ISR_ENTRY() macro and must end with the QK_ISR_EXIT() macro. The source -* file containing the interrupt service routine must #include . -* Core software interrupt 0 and Interrupt Priority Level 1 are reserved for -* use by QK. -*/ - -#endif /* QK_PORT_H */ diff --git a/ports/pic32/qk/xc32/qp_port.h b/ports/pic32/qk/xc32/qp_port.h new file mode 100644 index 00000000..c85131d9 --- /dev/null +++ b/ports/pic32/qk/xc32/qp_port.h @@ -0,0 +1,121 @@ +//============================================================================ +// QP/C Real-Time Embedded Framework (RTEF) +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC . +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +//============================================================================ +//! @date Last updated on: 2023-09-07 +//! @version Last updated for: @ref qpc_7_3_0 +//! +//! @file +//! @brief QP/C port to PIC32, QK kernel, MPLAB-X XC32 + +#ifndef QP_PORT_H_ +#define QP_PORT_H_ + +#include // Exact-width types. WG14/N843 C99 Standard +#include // Boolean type. WG14/N843 C99 Standard +#include // for _clz() + +#ifdef QP_CONFIG +#include "qp_config.h" // external QP configuration +#endif + +// no-return function specifier (C11 Standard) +#define Q_NORETURN _Noreturn void + +// QF configuration for QK -- data members of the QActive class... + +// QActive event queue type +#define QACTIVE_EQUEUE_TYPE QEQueue +// QACTIVE_OS_OBJ_TYPE not used in this port +// QACTIVE_THREAD_TYPE not used in this port + +// QF interrupt disable/enable, see NOTE1 +#define QF_INT_DISABLE() __builtin_disable_interrupts() +#define QF_INT_ENABLE() __builtin_enable_interrupts() + +// QF critical section entry/exit, see NOTE1 +#define QF_CRIT_STAT +#define QF_CRIT_ENTRY() QF_INT_DISABLE() +#define QF_CRIT_EXIT() QF_INT_ENABLE() + +// fast log-base-2 with CLZ instruction +#define QF_LOG2(n_) ((uint8_t)(32U - _clz(n_))) + +// Check if the code executes in the ISR context +#define QK_ISR_CONTEXT_() (QK_priv_.intNest != 0U) + +// QK interrupt entry and exit +#define QK_ISR_ENTRY() do { \ + QF_INT_DISABLE(); \ + ++QK_priv_.intNest; \ + QF_INT_ENABLE(); \ +} while (false) + +#define QK_ISR_EXIT() do { \ + QF_INT_DISABLE(); \ + --QK_priv_.intNest; \ + if (QK_sched_() != 0U) { \ + IFS0SET = _IFS0_CS0IF_MASK; \ + } \ + QF_INT_ENABLE(); \ +} while (false) + +// include files ------------------------------------------------------------- +#include "qequeue.h" // QK kernel uses the native QP event queue +#include "qmpool.h" // QK kernel uses the native QP memory pool +#include "qp.h" // QP framework +#include "qk.h" // QK kernel + +// initialization of the QK kernel +#define QK_INIT() QK_init() +void QK_init(void); + +//============================================================================ +// NOTE1: +// The intrinsic functions __builtin_disable_interrupts() and +// __builtin_enable_interrupts() use the DI (disable interrupts) and +// EI (enable interrupts) instruction, unconditional disabling and enabling +// of interrupts. The DI instruction only disables interrupts with priority +// levels 1-6. Priority level 7 interrupts and all trap events still have +// the ability to interrupt the CPU when the DI instruction is active. +// This means that from the perspective of QP framework, the level 7 interrupts +// are treated "kernel unaware" interrupts or non-maskable interrupts. +// Such "kernel unaware" interrupts **cannot** call any QP services. +// In particular, they cannot post events. +// +// CAUTION: This QP port assumes that interrupt nesting is **enabled**, +// which is the default in the PIC32 processors. Interrupt nesting should +// never be disabled by setting the NSTDIS control bit (INTCON1<15>). If you +// don't want interrupts to nest, you can always prioritize them at the same +// level. For example, the default priority level for all interrupts is 4 out +// of reset. If you don't change this level for any interrupt the nesting of +// interrupt will not occur. +// + +#endif // QP_PORT_H_ + diff --git a/ports/pic32/qk/xc32/qs_port.h b/ports/pic32/qk/xc32/qs_port.h index b1c77d47..206b7e4c 100644 --- a/ports/pic32/qk/xc32/qs_port.h +++ b/ports/pic32/qk/xc32/qs_port.h @@ -1,60 +1,56 @@ -/*============================================================================ -* QP/C Real-Time Embedded Framework (RTEF) -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2022-06-12 -* @version Last updated for: @ref qpc_7_0_1 -* -* @file -* @brief QS/C port to a 32-bit CPU and a generic C99 compiler. -* @description -* This is an example of a QP/C port with the documentation for the -* configuration macros and includes. -*/ -#ifndef QS_PORT_H -#define QS_PORT_H +//============================================================================ +// QP/C Real-Time Embedded Framework (RTEF) +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +//============================================================================ +//! @date Last updated on: 2023-08-16 +//! @version Last updated for: @ref qpc_7_3_0 +//! +//! @file +//! @brief QS/C port to a 32-bit CPU and a generic C11 compiler. -/* QS time-stamp size in bytes */ +#ifndef QS_PORT_H_ +#define QS_PORT_H_ + +// QS time-stamp size in bytes #define QS_TIME_SIZE 4U -/* object pointer size in bytes */ +// object pointer size in bytes #define QS_OBJ_PTR_SIZE 4U -/* function pointer size in bytes */ +// function pointer size in bytes #define QS_FUN_PTR_SIZE 4U -/*==========================================================================*/ -/* NOTE: QS might be used with or without other QP components, in which -* case the separate definitions of the macros QF_CRIT_STAT_TYPE, -* QF_CRIT_ENTRY, and QF_CRIT_EXIT are needed. In this port QS is configured -* to be used with the other QP component, by simply including "qf_port.h" -* *before* "qs.h". -*/ -#ifndef QF_PORT_H -#include "qf_port.h" /* use QS with QF */ +//============================================================================ +// NOTE: QS might be used with or without other QP components, in which +// case the separate definitions of the macros QF_CRIT_STAT, QF_CRIT_ENTRY(), +// and QF_CRIT_EXIT() are needed. In this port QS is configured to be used +// with the other QP component, by simply including "qp_port.h" +//*before* "qs.h". +#ifndef QP_PORT_H_ +#include "qp_port.h" // use QS with QF #endif -#include "qs.h" /* QS platform-independent public interface */ +#include "qs.h" // QS platform-independent public interface + +#endif // QS_PORT_H_ -#endif /* QS_PORT_H */ diff --git a/ports/pic32/qutest/xc32/qep_port.h b/ports/pic32/qutest/xc32/qep_port.h deleted file mode 100644 index e3640a77..00000000 --- a/ports/pic32/qutest/xc32/qep_port.h +++ /dev/null @@ -1,43 +0,0 @@ -/*============================================================================ -* QP/C Real-Time Embedded Framework (RTEF) -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2023-01-07 -* @version Last updated for: @ref qpc_7_2_0 -* -* @file -* @brief QEP/C port, GCC-ARM compiler -*/ -#ifndef QEP_PORT_H -#define QEP_PORT_H - -/*! no-return function specifier (GCC-ARM compiler) */ -#define Q_NORETURN __attribute__ ((noreturn)) void - -#include /* Exact-width types. WG14/N843 C99 Standard */ -#include /* Boolean type. WG14/N843 C99 Standard */ - -#include "qep.h" /* QEP platform-independent public interface */ - -#endif /* QEP_PORT_H */ diff --git a/ports/pic32/qutest/xc32/qf_port.h b/ports/pic32/qutest/xc32/qf_port.h deleted file mode 100644 index 4a8eb4e3..00000000 --- a/ports/pic32/qutest/xc32/qf_port.h +++ /dev/null @@ -1,91 +0,0 @@ -/*============================================================================ -* QP/C Real-Time Embedded Framework (RTEF) -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2022-11-11 -* @version Last updated for: @ref qpc_7_1_3 -* -* @file -* @brief QF/C port to PIC32, QUTEST unit test harness, generic C99 compiler -*/ -#ifndef QF_PORT_H -#define QF_PORT_H - -/* QUTEST event queue and thread types */ -#define QF_EQUEUE_TYPE QEQueue -/*#define QF_OS_OBJECT_TYPE */ -/*#define QF_THREAD_TYPE */ - -/* The maximum number of active objects in the application */ -#define QF_MAX_ACTIVE 32U - -/* The number of system clock tick rates */ -#define QF_MAX_TICK_RATE 2U - -/* QF interrupt disable/enable */ -#define QF_INT_DISABLE() (++QF_intLock_) -#define QF_INT_ENABLE() (--QF_intLock_) - -/* QF critical section */ -/* QF_CRIT_STAT_TYPE not defined */ -#define QF_CRIT_ENTRY(dummy) QF_INT_DISABLE() -#define QF_CRIT_EXIT(dummy) QF_INT_ENABLE() - -/* QF_LOG2 not defined -- use the internal LOG2() implementation */ - -#include "qep_port.h" /* QEP port */ -#include "qequeue.h" /* QUTEST port uses QEQueue event-queue */ -#include "qmpool.h" /* QUTEST port uses QMPool memory-pool */ -#include "qf.h" /* QF platform-independent public interface */ - -/****************************************************************************/ -/* interface used only inside QF implementation, but not in applications */ -#ifdef QP_IMPL - - /* QUTEST scheduler locking (not used) */ - #define QF_SCHED_STAT_ - #define QF_SCHED_LOCK_(dummy) ((void)0) - #define QF_SCHED_UNLOCK_() ((void)0) - - /* native event queue operations */ - #define QACTIVE_EQUEUE_WAIT_(me_) \ - Q_ASSERT_ID(0, (me_)->eQueue.frontEvt != (QEvt *)0) - #define QACTIVE_EQUEUE_SIGNAL_(me_) \ - QPSet_insert(&QF_readySet_, (uint_fast8_t)(me_)->prio) - - /* native QF event pool operations */ - #define QF_EPOOL_TYPE_ QMPool - #define QF_EPOOL_INIT_(p_, poolSto_, poolSize_, evtSize_) \ - (QMPool_init(&(p_), (poolSto_), (poolSize_), (evtSize_))) - #define QF_EPOOL_EVENT_SIZE_(p_) ((uint_fast16_t)(p_).blockSize) - #define QF_EPOOL_GET_(p_, e_, m_, qs_id_) \ - ((e_) = (QEvt *)QMPool_get(&(p_), (m_), (qs_id_))) - #define QF_EPOOL_PUT_(p_, e_, qs_id_) \ - (QMPool_put(&(p_), (e_), (qs_id_))) - - #include "qf_pkg.h" /* internal QF interface */ - -#endif /* QP_IMPL */ - -#endif /* QF_PORT_H */ diff --git a/ports/pic32/qutest/xc32/qp_port.h b/ports/pic32/qutest/xc32/qp_port.h new file mode 100644 index 00000000..f505488d --- /dev/null +++ b/ports/pic32/qutest/xc32/qp_port.h @@ -0,0 +1,106 @@ +//============================================================================ +// QP/C Real-Time Embedded Framework (RTEF) +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC . +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +//============================================================================ +//! @date Last updated on: 2023-09-07 +//! @version Last updated for: @ref qpc_7_3_0 +//! +//! @file +//! @brief QP/C port to PIC32, QUTest, MPLAB-X XC32 + +#ifndef QP_PORT_H_ +#define QP_PORT_H_ + +#include // Exact-width types. WG14/N843 C99 Standard +#include // Boolean type. WG14/N843 C99 Standard + +#ifdef QP_CONFIG +#include "qp_config.h" // external QP configuration +#endif + +// no-return function specifier (C11 Standard) +#define Q_NORETURN _Noreturn void + +// QF configuration for "QUTest" -- data members of the QActive class... + +// QUTest event-queue used for AOs +#define QACTIVE_EQUEUE_TYPE QEQueue +// QACTIVE_OS_OBJ_TYPE not used in this port +// QACTIVE_THREAD_TYPE not used in this port + +// QF interrupt disable/enable +#define QF_INT_DISABLE() (++QS_tstPriv_.intLock) +#define QF_INT_ENABLE() (--QS_tstPriv_.intLock) + +// QF critical section entry/exit, see NOTE02 +#define QF_CRIT_STAT +#define QF_CRIT_ENTRY() QF_INT_DISABLE() +#define QF_CRIT_EXIT() QF_INT_ENABLE() + +// QF_LOG2 not defined -- use the internal LOG2() implementation + +// include files ------------------------------------------------------------- +#include "qequeue.h" // QUTest port uses the native QP event queue +#include "qmpool.h" // QUTest port uses the native QP memory pool +#include "qp.h" // QP framework + +//============================================================================ +// interface used only inside QF implementation, but not in applications + +#ifdef QP_IMPL + + // scheduler locking (not used in QUTest) + #define QF_SCHED_STAT_ + #define QF_SCHED_LOCK_(dummy) ((void)0) + #define QF_SCHED_UNLOCK_() ((void)0) + + // native event queue operations + #define QACTIVE_EQUEUE_WAIT_(me_) \ + Q_ASSERT_INCRIT(302, (me_)->eQueue.frontEvt != (QEvt *)0) +#ifndef Q_UNSAFE + #define QACTIVE_EQUEUE_SIGNAL_(me_) \ + QPSet_insert(&QS_tstPriv_.readySet, (uint_fast8_t)(me_)->prio); \ + QPSet_update_(&QS_tstPriv_.readySet, &QS_tstPriv_.readySet_dis) +#else + #define QACTIVE_EQUEUE_SIGNAL_(me_) \ + QPSet_insert(&QF_readySet_, (uint_fast8_t)(me_)->prio) +#endif + + // native QF event pool operations + #define QF_EPOOL_TYPE_ QMPool + #define QF_EPOOL_INIT_(p_, poolSto_, poolSize_, evtSize_) \ + (QMPool_init(&(p_), (poolSto_), (poolSize_), (evtSize_))) + #define QF_EPOOL_EVENT_SIZE_(p_) ((uint_fast16_t)(p_).blockSize) + #define QF_EPOOL_GET_(p_, e_, m_, qs_id_) \ + ((e_) = (QEvt *)QMPool_get(&(p_), (m_), (qs_id_))) + #define QF_EPOOL_PUT_(p_, e_, qs_id_) (QMPool_put(&(p_), (e_), (qs_id_))) + +#endif // QP_IMPL + +#endif // QP_PORT_H_ + diff --git a/ports/pic32/qutest/xc32/qs_port.h b/ports/pic32/qutest/xc32/qs_port.h index b1c77d47..206b7e4c 100644 --- a/ports/pic32/qutest/xc32/qs_port.h +++ b/ports/pic32/qutest/xc32/qs_port.h @@ -1,60 +1,56 @@ -/*============================================================================ -* QP/C Real-Time Embedded Framework (RTEF) -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2022-06-12 -* @version Last updated for: @ref qpc_7_0_1 -* -* @file -* @brief QS/C port to a 32-bit CPU and a generic C99 compiler. -* @description -* This is an example of a QP/C port with the documentation for the -* configuration macros and includes. -*/ -#ifndef QS_PORT_H -#define QS_PORT_H +//============================================================================ +// QP/C Real-Time Embedded Framework (RTEF) +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +//============================================================================ +//! @date Last updated on: 2023-08-16 +//! @version Last updated for: @ref qpc_7_3_0 +//! +//! @file +//! @brief QS/C port to a 32-bit CPU and a generic C11 compiler. -/* QS time-stamp size in bytes */ +#ifndef QS_PORT_H_ +#define QS_PORT_H_ + +// QS time-stamp size in bytes #define QS_TIME_SIZE 4U -/* object pointer size in bytes */ +// object pointer size in bytes #define QS_OBJ_PTR_SIZE 4U -/* function pointer size in bytes */ +// function pointer size in bytes #define QS_FUN_PTR_SIZE 4U -/*==========================================================================*/ -/* NOTE: QS might be used with or without other QP components, in which -* case the separate definitions of the macros QF_CRIT_STAT_TYPE, -* QF_CRIT_ENTRY, and QF_CRIT_EXIT are needed. In this port QS is configured -* to be used with the other QP component, by simply including "qf_port.h" -* *before* "qs.h". -*/ -#ifndef QF_PORT_H -#include "qf_port.h" /* use QS with QF */ +//============================================================================ +// NOTE: QS might be used with or without other QP components, in which +// case the separate definitions of the macros QF_CRIT_STAT, QF_CRIT_ENTRY(), +// and QF_CRIT_EXIT() are needed. In this port QS is configured to be used +// with the other QP component, by simply including "qp_port.h" +//*before* "qs.h". +#ifndef QP_PORT_H_ +#include "qp_port.h" // use QS with QF #endif -#include "qs.h" /* QS platform-independent public interface */ +#include "qs.h" // QS platform-independent public interface + +#endif // QS_PORT_H_ -#endif /* QS_PORT_H */ diff --git a/ports/pic32/qv/xc32/qep_port.h b/ports/pic32/qv/xc32/qep_port.h deleted file mode 100644 index e3640a77..00000000 --- a/ports/pic32/qv/xc32/qep_port.h +++ /dev/null @@ -1,43 +0,0 @@ -/*============================================================================ -* QP/C Real-Time Embedded Framework (RTEF) -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2023-01-07 -* @version Last updated for: @ref qpc_7_2_0 -* -* @file -* @brief QEP/C port, GCC-ARM compiler -*/ -#ifndef QEP_PORT_H -#define QEP_PORT_H - -/*! no-return function specifier (GCC-ARM compiler) */ -#define Q_NORETURN __attribute__ ((noreturn)) void - -#include /* Exact-width types. WG14/N843 C99 Standard */ -#include /* Boolean type. WG14/N843 C99 Standard */ - -#include "qep.h" /* QEP platform-independent public interface */ - -#endif /* QEP_PORT_H */ diff --git a/ports/pic32/qv/xc32/qf_port.h b/ports/pic32/qv/xc32/qf_port.h deleted file mode 100644 index 83f943e8..00000000 --- a/ports/pic32/qv/xc32/qf_port.h +++ /dev/null @@ -1,78 +0,0 @@ -/*============================================================================ -* QP/C Real-Time Embedded Framework (RTEF) -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2023-01-07 -* @version Last updated for: @ref qpc_7_2_0 -* -* @file -* @brief QF/C port, cooperative QV kernel, MPLAB-X XC32 compiler -*/ -#ifndef QF_PORT_H -#define QF_PORT_H - -/* The maximum number of system clock tick rates */ -#define QF_MAX_TICK_RATE 2U - -/* The maximum number of active objects in the application, see NOTE1 */ -#define QF_MAX_ACTIVE 32U - -/* QF interrupt disable/enable, see NOTE02 */ -#define QF_INT_DISABLE() __builtin_disable_interrupts() -#define QF_INT_ENABLE() __builtin_enable_interrupts() - -/* QF critical section entry/exit, see NOTE02 */ -/* QF_CRIT_STAT_TYPE not defined: unconditional interrupt disabling policy */ -#define QF_CRIT_ENTRY(dummy) QF_INT_DISABLE() -#define QF_CRIT_EXIT(dummy) QF_INT_ENABLE() - -/* fast log-base-2 with CLZ instruction */ -#define QF_LOG2(n_) ((uint8_t)(32U - _clz(n_))) - -#include /* for _clz() */ - -#include "qep_port.h" /* QEP port */ -#include "qv_port.h" /* QV cooperative kernel port */ -#include "qf.h" /* QF platform-independent public interface */ - -/***************************************************************************** -* NOTE1: -* The maximum number of active objects QF_MAX_ACTIVE can be increased -* up to 64, if necessary. Here it is set to a lower level to save some RAM. -* -* NOTE2: -* The DI/EI instructions are used for fast, unconditional disabling and -* enabling of interrupts. -* -* CAUTION: This QP port assumes that interrupt nesting is _enabled_, -* which is the default in the PIC32 processors. Interrupt nesting should -* never be disabled by setting the NSTDIS control bit (INTCON1<15>). If you -* don't want interrupts to nest, you can always prioritize them at the same -* level. For example, the default priority level for all interrupts is 4 out -* of reset. If you don't change this level for any interrupt the nesting of -* interrupt will not occur. -*/ - -#endif /* QF_PORT_H */ - diff --git a/ports/pic32/qv/xc32/qp_port.h b/ports/pic32/qv/xc32/qp_port.h new file mode 100644 index 00000000..e19262fe --- /dev/null +++ b/ports/pic32/qv/xc32/qp_port.h @@ -0,0 +1,98 @@ +//============================================================================ +// QP/C Real-Time Embedded Framework (RTEF) +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC . +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +//============================================================================ +//! @date Last updated on: 2023-09-07 +//! @version Last updated for: @ref qpc_7_3_0 +//! +//! @file +//! @brief QP/C port to PIC32, QV kernel, MPLAB-X XC32 + +#ifndef QP_PORT_H_ +#define QP_PORT_H_ + +#include // Exact-width types. WG14/N843 C99 Standard +#include // Boolean type. WG14/N843 C99 Standard +#include // for _clz() + +#ifdef QP_CONFIG +#include "qp_config.h" // external QP configuration +#endif + +// no-return function specifier (C11 Standard) +#define Q_NORETURN _Noreturn void + +// QF configuration for QV -- data members of the QActive class... + +// QActive event queue type +#define QACTIVE_EQUEUE_TYPE QEQueue +// QACTIVE_OS_OBJ_TYPE not used in this port +// QACTIVE_THREAD_TYPE not used in this port + +// QF interrupt disable/enable, see NOTE1 +#define QF_INT_DISABLE() __builtin_disable_interrupts() +#define QF_INT_ENABLE() __builtin_enable_interrupts() + +// QF critical section entry/exit, see NOTE1 +#define QF_CRIT_STAT +#define QF_CRIT_ENTRY() QF_INT_DISABLE() +#define QF_CRIT_EXIT() QF_INT_ENABLE() + +// fast log-base-2 with CLZ instruction +#define QF_LOG2(n_) ((uint8_t)(32U - _clz(n_))) + +// include files ------------------------------------------------------------- +#include "qequeue.h" // QV kernel uses the native QP event queue +#include "qmpool.h" // QV kernel uses the native QP memory pool +#include "qp.h" // QP framework +#include "qv.h" // QV kernel + +//============================================================================ +// NOTE1: +// The intrinsic functions __builtin_disable_interrupts() and +// __builtin_enable_interrupts() use the DI (disable interrupts) and +// EI (enable interrupts) instruction, unconditional disabling and enabling +// of interrupts. The DI instruction only disables interrupts with priority +// levels 1-6. Priority level 7 interrupts and all trap events still have +// the ability to interrupt the CPU when the DI instruction is active. +// This means that from the perspective of QP framework, the level 7 interrupts +// are treated "kernel unaware" interrupts or non-maskable interrupts. +// Such "kernel unaware" interrupts **cannot** call any QP services. +// In particular, they cannot post events. +// +// CAUTION: This QP port assumes that interrupt nesting is **enabled**, +// which is the default in the PIC32 processors. Interrupt nesting should +// never be disabled by setting the NSTDIS control bit (INTCON1<15>). If you +// don't want interrupts to nest, you can always prioritize them at the same +// level. For example, the default priority level for all interrupts is 4 out +// of reset. If you don't change this level for any interrupt the nesting of +// interrupt will not occur. +// + +#endif // QP_PORT_H_ + diff --git a/ports/pic32/qv/xc32/qs_port.h b/ports/pic32/qv/xc32/qs_port.h index b1c77d47..206b7e4c 100644 --- a/ports/pic32/qv/xc32/qs_port.h +++ b/ports/pic32/qv/xc32/qs_port.h @@ -1,60 +1,56 @@ -/*============================================================================ -* QP/C Real-Time Embedded Framework (RTEF) -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2022-06-12 -* @version Last updated for: @ref qpc_7_0_1 -* -* @file -* @brief QS/C port to a 32-bit CPU and a generic C99 compiler. -* @description -* This is an example of a QP/C port with the documentation for the -* configuration macros and includes. -*/ -#ifndef QS_PORT_H -#define QS_PORT_H +//============================================================================ +// QP/C Real-Time Embedded Framework (RTEF) +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +//============================================================================ +//! @date Last updated on: 2023-08-16 +//! @version Last updated for: @ref qpc_7_3_0 +//! +//! @file +//! @brief QS/C port to a 32-bit CPU and a generic C11 compiler. -/* QS time-stamp size in bytes */ +#ifndef QS_PORT_H_ +#define QS_PORT_H_ + +// QS time-stamp size in bytes #define QS_TIME_SIZE 4U -/* object pointer size in bytes */ +// object pointer size in bytes #define QS_OBJ_PTR_SIZE 4U -/* function pointer size in bytes */ +// function pointer size in bytes #define QS_FUN_PTR_SIZE 4U -/*==========================================================================*/ -/* NOTE: QS might be used with or without other QP components, in which -* case the separate definitions of the macros QF_CRIT_STAT_TYPE, -* QF_CRIT_ENTRY, and QF_CRIT_EXIT are needed. In this port QS is configured -* to be used with the other QP component, by simply including "qf_port.h" -* *before* "qs.h". -*/ -#ifndef QF_PORT_H -#include "qf_port.h" /* use QS with QF */ +//============================================================================ +// NOTE: QS might be used with or without other QP components, in which +// case the separate definitions of the macros QF_CRIT_STAT, QF_CRIT_ENTRY(), +// and QF_CRIT_EXIT() are needed. In this port QS is configured to be used +// with the other QP component, by simply including "qp_port.h" +//*before* "qs.h". +#ifndef QP_PORT_H_ +#include "qp_port.h" // use QS with QF #endif -#include "qs.h" /* QS platform-independent public interface */ +#include "qs.h" // QS platform-independent public interface + +#endif // QS_PORT_H_ -#endif /* QS_PORT_H */ diff --git a/ports/pic32/qv/xc32/qv_port.h b/ports/pic32/qv/xc32/qv_port.h deleted file mode 100644 index f400355c..00000000 --- a/ports/pic32/qv/xc32/qv_port.h +++ /dev/null @@ -1,37 +0,0 @@ -/*============================================================================ -* QP/C Real-Time Embedded Framework (RTEF) -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2023-01-07 -* @version Last updated for: @ref qpc_7_2_0 -* -* @file -* @brief QV/C port, cooperative QV kernel, MPLAB-X XC32 compiler -*/ -#ifndef QV_PORT_H -#define QV_PORT_H - -#include "qv.h" /* QV platform-independent public interface */ - -#endif /* QV_PORT_H */ diff --git a/ports/posix-qutest/qep_port.h b/ports/posix-qutest/qep_port.h deleted file mode 100644 index 7cc207f5..00000000 --- a/ports/posix-qutest/qep_port.h +++ /dev/null @@ -1,43 +0,0 @@ -/*============================================================================ -* QP/C Real-Time Embedded Framework (RTEF) -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2023-01-07 -* @version Last updated for: @ref qpc_7_2_0 -* -* @file -* @brief QEP/C port, generic C11 compiler -*/ -#ifndef QEP_PORT_H -#define QEP_PORT_H - -/*! no-return function specifier (C11 Standard) */ -#define Q_NORETURN _Noreturn void - -#include /* Exact-width types. WG14/N843 C99 Standard */ -#include /* Boolean type. WG14/N843 C99 Standard */ - -#include "qep.h" /* QEP platform-independent public interface */ - -#endif /* QEP_PORT_H */ diff --git a/ports/posix-qutest/qf_port.h b/ports/posix-qutest/qf_port.h deleted file mode 100644 index 3f6b4476..00000000 --- a/ports/posix-qutest/qf_port.h +++ /dev/null @@ -1,94 +0,0 @@ -/*============================================================================ -* QP/C Real-Time Embedded Framework (RTEF) -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2022-11-11 -* @version Last updated for: @ref qpc_7_1_3 -* -* @file -* @brief QF/C "port" for QUTEST unit test harness, generic C99 compiler -*/ -#ifndef QF_PORT_H -#define QF_PORT_H - -/* QUTEST event queue and thread types */ -#define QF_EQUEUE_TYPE QEQueue -/* QF_OS_OBJECT_TYPE not used in this port */ -/* QF_THREAD_TYPE not used in this port */ - -/* The maximum number of active objects in the application */ -#define QF_MAX_ACTIVE 64U - -/* The number of system clock tick rates */ -#define QF_MAX_TICK_RATE 2U - -/* Activate the QF QActive_stop() API */ -#define QF_ACTIVE_STOP 1 - -/* QF interrupt disable/enable */ -#define QF_INT_DISABLE() (++QF_intLock_) -#define QF_INT_ENABLE() (--QF_intLock_) - -/* QF critical section */ -/* QF_CRIT_STAT_TYPE not defined */ -#define QF_CRIT_ENTRY(dummy) QF_INT_DISABLE() -#define QF_CRIT_EXIT(dummy) QF_INT_ENABLE() - -/* QF_LOG2 not defined -- use the internal LOG2() implementation */ - -#include "qep_port.h" /* QEP port */ -#include "qequeue.h" /* QUTEST port uses QEQueue event-queue */ -#include "qmpool.h" /* QUTEST port uses QMPool memory-pool */ -#include "qf.h" /* QF platform-independent public interface */ - -/****************************************************************************/ -/* interface used only inside QF implementation, but not in applications */ -#ifdef QP_IMPL - - /* QUTEST scheduler locking (not used) */ - #define QF_SCHED_STAT_ - #define QF_SCHED_LOCK_(dummy) ((void)0) - #define QF_SCHED_UNLOCK_() ((void)0) - - /* native event queue operations */ - #define QACTIVE_EQUEUE_WAIT_(me_) \ - Q_ASSERT_ID(0, (me_)->eQueue.frontEvt != (QEvt *)0) - #define QACTIVE_EQUEUE_SIGNAL_(me_) \ - QPSet_insert(&QF_readySet_, (uint_fast8_t)(me_)->prio) - - /* native QF event pool operations */ - #define QF_EPOOL_TYPE_ QMPool - #define QF_EPOOL_INIT_(p_, poolSto_, poolSize_, evtSize_) \ - (QMPool_init(&(p_), (poolSto_), (poolSize_), (evtSize_))) - #define QF_EPOOL_EVENT_SIZE_(p_) ((uint_fast16_t)(p_).blockSize) - #define QF_EPOOL_GET_(p_, e_, m_, qs_id_) \ - ((e_) = (QEvt *)QMPool_get(&(p_), (m_), (qs_id_))) - #define QF_EPOOL_PUT_(p_, e_, qs_id_) \ - (QMPool_put(&(p_), (e_), (qs_id_))) - - #include "qf_pkg.h" /* internal QF interface */ - -#endif /* QP_IMPL */ - -#endif /* QF_PORT_H */ diff --git a/ports/posix-qutest/qp_port.h b/ports/posix-qutest/qp_port.h new file mode 100644 index 00000000..a8863560 --- /dev/null +++ b/ports/posix-qutest/qp_port.h @@ -0,0 +1,105 @@ +//============================================================================ +// QP/C Real-Time Embedded Framework (RTEF) +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC . +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +//============================================================================ +//! @date Last updated on: 2023-09-07 +//! @version Last updated for: @ref qpc_7_3_0 +//! +//! @file +//! @brief QP/C "port" for QUTEST unit test harness, generic C11 compiler + +#ifndef QP_PORT_H_ +#define QP_PORT_H_ + +#include // Exact-width types. WG14/N843 C99 Standard +#include // Boolean type. WG14/N843 C99 Standard + +#ifdef QP_CONFIG +#include "qp_config.h" // external QP configuration +#endif + +// no-return function specifier (C11 Standard) +#define Q_NORETURN _Noreturn void + +// QUTest event queue and thread types +#define QACTIVE_EQUEUE_TYPE QEQueue +// QACTIVE_OS_OBJ_TYPE not used in this port +// QACTIVE_THREAD_TYPE not used in this port + +// QF interrupt disable/enable +#define QF_INT_DISABLE() (++QS_tstPriv_.intLock) +#define QF_INT_ENABLE() (--QS_tstPriv_.intLock) + +// QF critical section +#define QF_CRIT_STAT +#define QF_CRIT_ENTRY() QF_INT_DISABLE() +#define QF_CRIT_EXIT() QF_INT_ENABLE() + +// QF_LOG2 not defined -- use the internal LOG2() implementation + +// include files ------------------------------------------------------------- +#include "qequeue.h" // QUTest port uses QEQueue event-queue +#include "qmpool.h" // QUTest port uses QMPool memory-pool +#include "qp.h" // QP platform-independent public interface + +//============================================================================ +// interface used only inside QF implementation, but not in applications + +#ifdef QP_IMPL + + // QUTest scheduler locking (not used) + #define QF_SCHED_STAT_ + #define QF_SCHED_LOCK_(dummy) ((void)0) + #define QF_SCHED_UNLOCK_() ((void)0) + + // native event queue operations + #define QACTIVE_EQUEUE_WAIT_(me_) \ + Q_ASSERT_INCRIT(305, (me_)->eQueue.frontEvt != (QEvt *)0) +#ifndef Q_UNSAFE + #define QACTIVE_EQUEUE_SIGNAL_(me_) \ + QPSet_insert(&QS_tstPriv_.readySet, (uint_fast8_t)(me_)->prio); \ + QPSet_update_(&QS_tstPriv_.readySet, &QS_tstPriv_.readySet_dis) +#else + #define QACTIVE_EQUEUE_SIGNAL_(me_) \ + QPSet_insert(&QF_readySet_, (uint_fast8_t)(me_)->prio) +#endif + + // native QF event pool operations + #define QF_EPOOL_TYPE_ QMPool + #define QF_EPOOL_INIT_(p_, poolSto_, poolSize_, evtSize_) \ + (QMPool_init(&(p_), (poolSto_), (poolSize_), (evtSize_))) + #define QF_EPOOL_EVENT_SIZE_(p_) ((uint_fast16_t)(p_).blockSize) + #define QF_EPOOL_GET_(p_, e_, m_, qs_id_) \ + ((e_) = (QEvt *)QMPool_get(&(p_), (m_), (qs_id_))) + #define QF_EPOOL_PUT_(p_, e_, qs_id_) \ + (QMPool_put(&(p_), (e_), (qs_id_))) + +#endif // QP_IMPL + +#endif // QP_PORT_H_ + diff --git a/ports/posix-qutest/qs_port.h b/ports/posix-qutest/qs_port.h index e82b6cad..79c8e010 100644 --- a/ports/posix-qutest/qs_port.h +++ b/ports/posix-qutest/qs_port.h @@ -1,63 +1,61 @@ -/*============================================================================ -* QP/C Real-Time Embedded Framework (RTEF) -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2023-01-07 -* @version Last updated for: @ref qpc_7_2_0 -* -* @file -* @brief QS/C port to POSIX with GNU compiler -*/ -#ifndef QS_PORT_H -#define QS_PORT_H +//============================================================================ +// QP/C Real-Time Embedded Framework (RTEF) +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +//============================================================================ +//! @date Last updated on: 2023-08-19 +//! @version Last updated for: @ref qpc_7_3_0 +//! +//! @file +//! @brief QS/C port to POSIX with GNU + +#ifndef QS_PORT_H_ +#define QS_PORT_H_ #define QS_CTR_SIZE 4U #define QS_TIME_SIZE 4U -#if defined(__LP64__) || defined(_LP64) /* 64-bit architecture? */ +#if defined(__LP64__) || defined(_LP64) // 64-bit architecture? #define QS_OBJ_PTR_SIZE 8U #define QS_FUN_PTR_SIZE 8U -#else /* 32-bit architecture */ +#else // 32-bit architecture #define QS_OBJ_PTR_SIZE 4U #define QS_FUN_PTR_SIZE 4U #endif -/* flush the QS output buffer after each QS record */ -#define QS_REC_DONE() QS_onFlush() +void QS_output(void); // handle the QS output +void QS_rx_input(void); // handle the QS-RX input -/*==========================================================================*/ -/* NOTE: QS might be used with or without other QP components, in which -* case the separate definitions of the macros QF_CRIT_STAT_TYPE, -* QF_CRIT_ENTRY, and QF_CRIT_EXIT are needed. In this port QS is configured -* to be used with the other QP component, by simply including "qf_port.h" -* *before* "qs.h". -*/ -#ifndef QF_PORT_H -#include "qf_port.h" /* use QS with QF */ +//============================================================================ +// NOTE: QS might be used with or without other QP components, in which +// case the separate definitions of the macros QF_CRIT_STAT, QF_CRIT_ENTRY(), +// and QF_CRIT_EXIT() are needed. In this port QS is configured to be used +// with the other QP component, by simply including "qp_port.h" +//*before* "qs.h". +#ifndef QP_PORT_H_ +#include "qp_port.h" // use QS with QP #endif -#include "qs.h" /* QS platform-independent public interface */ +#include "qs.h" // QS platform-independent public interface -#endif /* QS_PORT_H */ +#endif // QS_PORT_H_ diff --git a/ports/posix-qutest/qutest_port.c b/ports/posix-qutest/qutest_port.c index d9dc45a4..ec9bc0bb 100644 --- a/ports/posix-qutest/qutest_port.c +++ b/ports/posix-qutest/qutest_port.c @@ -1,48 +1,47 @@ -/*============================================================================ -* QP/C Real-Time Embedded Framework (RTEF) -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2023-01-07 -* @version Last updated for: @ref qpc_7_2_0 -* -* @file -* @brief QS/C QUTest port to POSIX -*/ -/* expose features from the 2008 POSIX standard (IEEE Standard 1003.1-2008) */ +//============================================================================ +// QP/C Real-Time Embedded Framework (RTEF) +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +//============================================================================ +//! @date Last updated on: 2023-08-20 +//! @version Last updated for: @ref qpc_7_3_0 +//! +//! @file +//! @brief QS/C "port" to QUTest with POSIX + +// expose features from the 2008 POSIX standard (IEEE Standard 1003.1-2008) #define _POSIX_C_SOURCE 200809L #ifndef Q_SPY #error "Q_SPY must be defined to compile qutest_port.c" -#endif /* Q_SPY */ +#endif // Q_SPY -#define QP_IMPL /* this is QP implementation */ -#include "qf_port.h" /* QF port */ -#include "qassert.h" /* QP embedded systems-friendly assertions */ -#include "qs_port.h" /* QS port */ -#include "qs_pkg.h" /* QS package-scope interface */ +#define QP_IMPL // this is QP implementation +#include "qp_port.h" // QP port +#include "qsafe.h" // QP Functional Safety (FuSa) System +#include "qs_port.h" // QS port +#include "qs_pkg.h" // QS package-scope interface -#include "safe_std.h" /* portable "safe" / facilities */ +#include "safe_std.h" // portable "safe" / facilities #include #include #include @@ -63,24 +62,29 @@ #define INVALID_SOCKET -1 #define SOCKET_ERROR -1 -/*Q_DEFINE_THIS_MODULE("qutest_port")*/ +//Q_DEFINE_THIS_MODULE("qutest_port") -/* local variables .........................................................*/ +// local variables ......................................................... static int l_sock = INVALID_SOCKET; -static void sigIntHandler(int dummy); /* prototype */ +static void sigIntHandler(int dummy); // prototype static void sigIntHandler(int dummy) { - (void)dummy; /* unused parameter */ + (void)dummy; // unused parameter QS_onCleanup(); - /*PRINTF_S("\n disconnecting from QSPY\n");*/ + //PRINTF_S("\n disconnecting from QSPY\n"); exit(-1); } -/*..........................................................................*/ +//............................................................................ uint8_t QS_onStartup(void const *arg) { - static uint8_t qsBuf[QS_TX_SIZE]; /* buffer for QS-TX channel */ - static uint8_t qsRxBuf[QS_RX_SIZE]; /* buffer for QS-RX channel */ + + static uint8_t qsBuf[QS_TX_SIZE]; // buffer for QS-TX channel + QS_initBuf(qsBuf, sizeof(qsBuf)); + + static uint8_t qsRxBuf[QS_RX_SIZE]; // buffer for QS-RX channel + QS_rxInitBuf(qsRxBuf, sizeof(qsRxBuf)); + char hostName[128]; - char const *serviceName = "6601"; /* default QSPY server port */ + char const *serviceName = "6601"; // default QSPY server port char const *src; char *dst; int status; @@ -90,16 +94,10 @@ uint8_t QS_onStartup(void const *arg) { struct addrinfo hints; int sockopt_bool; - struct sigaction sig_act; - - /* initialize the QS transmit and receive buffers */ - QS_initBuf(qsBuf, sizeof(qsBuf)); - QS_rxInitBuf(qsRxBuf, sizeof(qsRxBuf)); - - /* extract hostName from 'arg' (hostName:port_remote)... */ + // extract hostName from 'arg' (hostName:port_remote)... src = (arg != (void *)0) ? (char const *)arg - : "localhost"; /* default QSPY host */ + : "localhost"; // default QSPY host dst = hostName; while ((*src != '\0') && (*src != ':') @@ -107,14 +105,12 @@ uint8_t QS_onStartup(void const *arg) { { *dst++ = *src++; } - *dst = '\0'; /* zero-terminate hostName */ + *dst = '\0'; // zero-terminate hostName - /* extract serviceName from 'arg' (hostName:serviceName)... */ + // extract serviceName from 'arg' (hostName:serviceName)... if (*src == ':') { serviceName = src + 1; } - //PRINTF_S(" Connecting to QSPY on Host=%s:%s...\n", - // hostName, serviceName); memset(&hints, 0, sizeof(hints)); hints.ai_family = AF_INET; @@ -124,7 +120,7 @@ uint8_t QS_onStartup(void const *arg) { if (status != 0) { FPRINTF_S(stderr, " ERROR cannot resolve host Name=%s:%s,Err=%d\n", - hostName, serviceName, status); + hostName, serviceName, status); goto error; } @@ -143,7 +139,7 @@ uint8_t QS_onStartup(void const *arg) { freeaddrinfo(result); - /* socket could not be opened & connected? */ + // socket could not be opened & connected? if (l_sock == INVALID_SOCKET) { FPRINTF_S(stderr, " ERROR cannot connect to QSPY at " "host=%s:%s\n", @@ -151,7 +147,7 @@ uint8_t QS_onStartup(void const *arg) { goto error; } - /* set the socket to non-blocking mode */ + // set the socket to non-blocking mode status = fcntl(l_sock, F_GETFL, 0); if (status == -1) { FPRINTF_S(stderr, @@ -167,84 +163,91 @@ uint8_t QS_onStartup(void const *arg) { goto error; } - /* configure the socket to reuse the address and not to linger */ + // configure the socket to reuse the address and not to linger sockopt_bool = 1; setsockopt(l_sock, SOL_SOCKET, SO_REUSEADDR, &sockopt_bool, sizeof(sockopt_bool)); - sockopt_bool = 0; /* negative option */ + sockopt_bool = 0; // negative option setsockopt(l_sock, SOL_SOCKET, SO_LINGER, &sockopt_bool, sizeof(sockopt_bool)); - - //PRINTF_S(" Connected to QSPY at Host=%s:%d\n", - // hostName, port_remote); QS_onFlush(); - /* install the SIGINT (Ctrl-C) signal handler */ + // install the SIGINT (Ctrl-C) signal handler + struct sigaction sig_act; memset(&sig_act, 0, sizeof(sig_act)); sig_act.sa_handler = &sigIntHandler; sigaction(SIGINT, &sig_act, NULL); - return 1U; /* success */ + return 1U; // success error: - return 0U; /* failure */ + return 0U; // failure } -/*..........................................................................*/ +//............................................................................ void QS_onCleanup(void) { static struct timespec const c_timeout = {0, 10L*QS_TIMEOUT_MS*1000000L }; - nanosleep(&c_timeout, NULL); /* allow the last QS output to come out */ + nanosleep(&c_timeout, NULL); // allow the last QS output to come out if (l_sock != INVALID_SOCKET) { close(l_sock); l_sock = INVALID_SOCKET; } - /*PRINTF_S(" Disconnected from QSPY\n");*/ + //PRINTF_S(" Disconnected from QSPY\n"); } -/*..........................................................................*/ +//............................................................................ void QS_onReset(void) { QS_onCleanup(); + //PRINTF_S("\n%s\n", "QS_onReset"); exit(0); } -/*..........................................................................*/ +//............................................................................ void QS_onFlush(void) { - if (l_sock == INVALID_SOCKET) { /* socket NOT initialized? */ - FPRINTF_S(stderr, "%s\n", " ERROR invalid TCP socket"); + if (l_sock == INVALID_SOCKET) { // socket NOT initialized? + FPRINTF_S(stderr, " ERROR %s\n", + "invalid TCP socket"); + QF_stop(); // <== stop and exit the application return; } - uint8_t const *data; static struct timespec const c_timeout = { 0, QS_TIMEOUT_MS*1000000L }; + + QS_CRIT_STAT + QS_CRIT_ENTRY(); uint16_t nBytes = QS_TX_CHUNK; + uint8_t const *data; while ((data = QS_getBlock(&nBytes)) != (uint8_t *)0) { - for (;;) { /* for-ever until break or return */ + QS_CRIT_EXIT(); + for (;;) { // for-ever until break or return int nSent = send(l_sock, (char const *)data, (int)nBytes, 0); - if (nSent == SOCKET_ERROR) { /* sending failed? */ + if (nSent == SOCKET_ERROR) { // sending failed? if ((errno == EWOULDBLOCK) || (errno == EAGAIN)) { - /* sleep for the timeout and then loop back - * to send() the SAME data again - */ + // sleep for the timeout and then loop back + // to send() the SAME data again nanosleep(&c_timeout, NULL); } - else { /* some other socket error... */ + else { // some other socket error... FPRINTF_S(stderr, " ERROR sending data over TCP," "errno=%d\n", errno); + QF_stop(); // <== stop and exit the application return; } } - else if (nSent < (int)nBytes) { /* sent fewer than requested? */ - nanosleep(&c_timeout, NULL); /* sleep for the timeout */ - /* adjust the data and loop back to send() the rest */ + else if (nSent < (int)nBytes) { // sent fewer than requested? + nanosleep(&c_timeout, NULL); // sleep for the timeout + // adjust the data and loop back to send() the rest data += nSent; nBytes -= (uint16_t)nSent; } else { - break; + break; // break out of the for-ever loop } } - /* set nBytes for the next call to QS_getBlock() */ + // set nBytes for the next call to QS_getBlock() nBytes = QS_TX_CHUNK; + QS_CRIT_ENTRY(); } + QS_CRIT_EXIT(); } -/*..........................................................................*/ +//............................................................................ void QS_onTestLoop() { fd_set readSet; FD_ZERO(&readSet); @@ -257,7 +260,7 @@ void QS_onTestLoop() { while (QS_rxPriv_.inTestLoop) { FD_SET(l_sock, &readSet); - /* selective, timed blocking on the TCP/IP socket... */ + // selective, timed blocking on the TCP/IP socket... timeout.tv_usec = (long)(QS_TIMEOUT_MS * 1000); int status = select(l_sock + 1, &readSet, (fd_set *)0, (fd_set *)0, &timeout); @@ -267,21 +270,21 @@ void QS_onTestLoop() { QS_onCleanup(); exit(-2); } - else if ((status > 0) && FD_ISSET(l_sock, &readSet)) { /* socket ready */ + else if ((status > 0) && FD_ISSET(l_sock, &readSet)) { // socket ready status = recv(l_sock, (char *)QS_rxPriv_.buf, (int)QS_rxPriv_.end, 0); - if (status > 0) { /* any data received? */ + if (status > 0) { // any data received? QS_rxPriv_.tail = 0U; - QS_rxPriv_.head = status; /* # bytes received */ - QS_rxParse(); /* parse all received bytes */ + QS_rxPriv_.head = status; // # bytes received + QS_rxParse(); // parse all received bytes } } QS_onFlush(); } - /* set inTestLoop to true in case calls to QS_onTestLoop() nest, - * which can happen through the calls to QS_TEST_PAUSE(). - */ + // set inTestLoop to true in case calls to QS_onTestLoop() nest, + // which can happen through the calls to QS_TEST_PAUSE(). + // QS_rxPriv_.inTestLoop = true; } diff --git a/ports/posix-qutest/safe_std.h b/ports/posix-qutest/safe_std.h index 7e0a2439..c752662c 100644 --- a/ports/posix-qutest/safe_std.h +++ b/ports/posix-qutest/safe_std.h @@ -1,42 +1,40 @@ -/*============================================================================ -* QP/C Real-Time Embedded Framework (RTEF) -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2022-07-30 -* @version Last updated for: @ref qpc_7_0_1 -* -* @file -* @brief "safe" and facilities -*/ +//============================================================================ +// QP/C Real-Time Embedded Framework (RTEF) +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +//============================================================================ +//! @date Last updated on: 2022-07-30 +//! @version Last updated for: @ref qpc_7_1_3 +//! +//! @file +//! @brief "safe" and facilities #ifndef SAFE_STD_H #define SAFE_STD_H #include #include -/* portable "safe" facilities from and ................*/ -#ifdef _WIN32 /* Windows OS? */ +// portable "safe" facilities from and ................ +#ifdef _WIN32 // Windows OS? #define MEMMOVE_S(dest_, num_, src_, count_) \ memmove_s(dest_, num_, src_, count_) @@ -48,13 +46,13 @@ strcat_s(dest_, destsiz_, src_) #define SNPRINTF_S(buf_, bufsiz_, format_, ...) \ - _snprintf_s(buf_, bufsiz_, _TRUNCATE, format_, ##__VA_ARGS__) + _snprintf_s(buf_, bufsiz_, _TRUNCATE, format_, __VA_ARGS__) #define PRINTF_S(format_, ...) \ - printf_s(format_, ##__VA_ARGS__) + printf_s(format_, __VA_ARGS__) #define FPRINTF_S(fp_, format_, ...) \ - fprintf_s(fp_, format_, ##__VA_ARGS__) + fprintf_s(fp_, format_, __VA_ARGS__) #ifdef _MSC_VER #define FREAD_S(buf_, bufsiz_, elsiz_, count_, fp_) \ @@ -62,7 +60,7 @@ #else #define FREAD_S(buf_, bufsiz_, elsiz_, count_, fp_) \ fread(buf_, elsiz_, count_, fp_) -#endif /* _MSC_VER */ +#endif // _MSC_VER #define FOPEN_S(fp_, fName_, mode_) \ if (fopen_s(&fp_, fName_, mode_) != 0) { \ @@ -72,7 +70,7 @@ if (fopen_s(&fp_, fName_, mode_) != 0) { \ #define LOCALTIME_S(tm_, time_) \ localtime_s(tm_, time_) -#else /* other OS (Linux, MacOS, etc.) .....................................*/ +#else // other OS (Linux, MacOS, etc.) ..................................... #define MEMMOVE_S(dest_, num_, src_, count_) \ memmove(dest_, src_, count_) @@ -86,13 +84,13 @@ if (fopen_s(&fp_, fName_, mode_) != 0) { \ strcat(dest_, src_) #define SNPRINTF_S(buf_, bufsiz_, format_, ...) \ - snprintf(buf_, bufsiz_, format_, ##__VA_ARGS__) + snprintf(buf_, bufsiz_, format_, __VA_ARGS__) #define PRINTF_S(format_, ...) \ - printf(format_, ##__VA_ARGS__) + printf(format_, __VA_ARGS__) #define FPRINTF_S(fp_, format_, ...) \ - fprintf(fp_, format_, ##__VA_ARGS__) + fprintf(fp_, format_, __VA_ARGS__) #define FREAD_S(buf_, bufsiz_, elsiz_, count_, fp_) \ fread(buf_, elsiz_, count_, fp_) @@ -103,6 +101,6 @@ if (fopen_s(&fp_, fName_, mode_) != 0) { \ #define LOCALTIME_S(tm_, time_) \ memcpy(tm_, localtime(time_), sizeof(struct tm)) -#endif /* _WIN32 */ +#endif // _WIN32 -#endif /* SAFE_STD_H */ +#endif // SAFE_STD_H diff --git a/ports/posix-qv/qep_port.h b/ports/posix-qv/qep_port.h deleted file mode 100644 index 7cc207f5..00000000 --- a/ports/posix-qv/qep_port.h +++ /dev/null @@ -1,43 +0,0 @@ -/*============================================================================ -* QP/C Real-Time Embedded Framework (RTEF) -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2023-01-07 -* @version Last updated for: @ref qpc_7_2_0 -* -* @file -* @brief QEP/C port, generic C11 compiler -*/ -#ifndef QEP_PORT_H -#define QEP_PORT_H - -/*! no-return function specifier (C11 Standard) */ -#define Q_NORETURN _Noreturn void - -#include /* Exact-width types. WG14/N843 C99 Standard */ -#include /* Boolean type. WG14/N843 C99 Standard */ - -#include "qep.h" /* QEP platform-independent public interface */ - -#endif /* QEP_PORT_H */ diff --git a/ports/posix-qv/qf_port.c b/ports/posix-qv/qf_port.c index 8f60e31b..de4789b1 100644 --- a/ports/posix-qv/qf_port.c +++ b/ports/posix-qv/qf_port.c @@ -1,54 +1,52 @@ -/*============================================================================ -* QP/C Real-Time Embedded Framework (RTEF) -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2023-01-07 -* @version Last updated for: @ref qpc_7_2_0 -* -* @file -* @brief QF/C port to POSIX API (single-threaded, like QV kernel) -*/ +//============================================================================ +// QP/C Real-Time Embedded Framework (RTEF) +// Copyright (C) 2005 Quantum Leaps, LLC . +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +//============================================================================ +//! @date Last updated on: 2023-08-26 +//! @version Last updated for: @ref qpc_7_3_0 +//! +//! @file +//! @brief QF/C port to POSIX-QV (single-threaded) -/* expose features from the 2008 POSIX standard (IEEE Standard 1003.1-2008) */ +// expose features from the 2008 POSIX standard (IEEE Standard 1003.1-2008) #define _POSIX_C_SOURCE 200809L -#define QP_IMPL /* this is QP implementation */ -#include "qf_port.h" /* QF port */ -#include "qf_pkg.h" -#include "qassert.h" -#ifdef Q_SPY /* QS software tracing enabled? */ - #include "qs_port.h" /* QS port */ - #include "qs_pkg.h" /* QS package-scope internal interface */ +#define QP_IMPL // this is QP implementation +#include "qp_port.h" // QP port +#include "qp_pkg.h" // QP package-scope interface +#include "qsafe.h" // QP Functional Safety (FuSa) System +#ifdef Q_SPY // QS software tracing enabled? + #include "qs_port.h" // QS port + #include "qs_pkg.h" // QS package-scope internal interface #else - #include "qs_dummy.h" /* disable the QS software tracing */ -#endif /* Q_SPY */ + #include "qs_dummy.h" // disable the QS software tracing +#endif // Q_SPY -#include /* for PTHREAD_STACK_MIN */ -#include /* for mlockall() */ -#include +#include // for PTHREAD_STACK_MIN +#include // for mlockall() #include -#include /* for memcpy() and memset() */ +#include // for clock_nanosleep() +#include // for memcpy() and memset() #include #include #include @@ -57,93 +55,155 @@ Q_DEFINE_THIS_MODULE("qf_port") -/* Global objects ==========================================================*/ -pthread_cond_t QV_condVar_; /* Cond.var. to signal events */ +// Local objects ============================================================= -/* Local objects ===========================================================*/ -static pthread_mutex_t l_pThreadMutex; /* POSIX mutex for critical sections */ -static bool l_isRunning; -static struct termios l_tsav; /* structure with saved terminal attributes */ -static struct timespec l_tick; -static int_t l_tickPrio; -enum { NANOSLEEP_NSEC_PER_SEC = 1000000000 }; /* see NOTE05 */ +// NOTE: initialize the critical section mutex first with default +// non-recursive initializer, but later in QF_init() it will be +// re-initialized it as *recursive mutex* in a portable way +static pthread_mutex_t l_critSectMutex_ = PTHREAD_MUTEX_INITIALIZER; -static void *ticker_thread(void *arg); -static void sigIntHandler(int dummy); +static bool l_isRunning; // flag indicating when QF is running +static struct termios l_tsav; // structure with saved terminal attributes +static struct timespec l_tick; // structure for the clock tick +static int_t l_tickPrio; // priority of the ticker thread -/* QF functions ============================================================*/ +#define NSEC_PER_SEC 1000000000L +#define DEFAULT_TICKS_PER_SEC 100 + +//============================================================================ +static void *ticker_thread(void *arg); // prototype +static void *ticker_thread(void *arg) { // for pthread_create() + Q_UNUSED_PAR(arg); + + // system clock tick must be configured + Q_REQUIRE_ID(100, l_tick.tv_nsec != 0); + + // get the absolute monotonic time for no-drift sleeping + static struct timespec next_tick; + clock_gettime(CLOCK_MONOTONIC, &next_tick); + + // round down nanoseconds to the nearest configured period + next_tick.tv_nsec = (next_tick.tv_nsec / l_tick.tv_nsec) * l_tick.tv_nsec; + + while (l_isRunning) { // the clock tick loop... + + // advance to the next tick (absolute time) + next_tick.tv_nsec += l_tick.tv_nsec; + if (next_tick.tv_nsec >= NSEC_PER_SEC) { + next_tick.tv_nsec -= NSEC_PER_SEC; + next_tick.tv_sec += 1; + } + + // sleep without drifting till next_tick (absolute), see NOTE03 + if (clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, + &next_tick, NULL) == 0) // success? + { + QF_onClockTick(); // must call QTIMEEVT_TICK_X() + } + } + return (void *)0; // return success +} +//............................................................................ +static void sigIntHandler(int dummy); // prototype +static void sigIntHandler(int dummy) { + Q_UNUSED_PAR(dummy); + QF_onCleanup(); + exit(-1); +} + +// Global objects ============================================================ +QPSet QF_readySet_; +QPSet QF_readySet_dis_; +pthread_cond_t QF_condVar_; // Cond.var. to signal events + +//============================================================================ +// QF functions + +//............................................................................ void QF_init(void) { - struct sigaction sig_act; + QPSet_setEmpty(&QF_readySet_); +#ifndef Q_UNSAFE + QPSet_update_(&QF_readySet_, &QF_readySet_dis_); +#endif - /* lock memory so we're never swapped out to disk */ - /*mlockall(MCL_CURRENT | MCL_FUTURE); uncomment when supported */ + // lock memory so we're never swapped out to disk + //mlockall(MCL_CURRENT | MCL_FUTURE); // un-comment when supported - /* init the global mutex with the default non-recursive initializer */ - pthread_mutex_init(&l_pThreadMutex, NULL); + // initialize the critical section mutex l_critSectMutex_ as a + // *recursive mutex* in a portable way according to the POSIX Standard + pthread_mutexattr_t attr; + pthread_mutexattr_init(&attr); + pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); + pthread_mutex_init(&l_critSectMutex_, &attr); + pthread_mutexattr_destroy(&attr); - /* init the global condition variable with the default initializer */ - pthread_cond_init(&QV_condVar_, NULL); + // init the global condition variable with the default initializer + pthread_cond_init(&QF_condVar_, NULL); l_tick.tv_sec = 0; - l_tick.tv_nsec = NANOSLEEP_NSEC_PER_SEC/100L; /* default clock tick */ - l_tickPrio = sched_get_priority_min(SCHED_FIFO); /* default tick prio */ + l_tick.tv_nsec = NSEC_PER_SEC / DEFAULT_TICKS_PER_SEC; // default clock tick + l_tickPrio = sched_get_priority_min(SCHED_FIFO); // default ticker prio - /* install the SIGINT (Ctrl-C) signal handler */ + // install the SIGINT (Ctrl-C) signal handler + struct sigaction sig_act; memset(&sig_act, 0, sizeof(sig_act)); sig_act.sa_handler = &sigIntHandler; sigaction(SIGINT, &sig_act, NULL); } -/****************************************************************************/ +//............................................................................ void QF_enterCriticalSection_(void) { - pthread_mutex_lock(&l_pThreadMutex); + if (l_isRunning) { + pthread_mutex_lock(&l_critSectMutex_); + } } -/****************************************************************************/ +//............................................................................ void QF_leaveCriticalSection_(void) { - pthread_mutex_unlock(&l_pThreadMutex); + if (l_isRunning) { + pthread_mutex_unlock(&l_critSectMutex_); + } } -/****************************************************************************/ -int_t QF_run(void) { - QF_CRIT_STAT_ +//............................................................................ +int QF_run(void) { - QF_onStartup(); /* invoke startup callback */ + QF_onStartup(); // application-specific startup callback - l_isRunning = true; /* QF is running */ - - /* system clock tick configured? */ + QF_CRIT_STAT + // system clock tick configured? if ((l_tick.tv_sec != 0) || (l_tick.tv_nsec != 0)) { - pthread_attr_t attr; - struct sched_param param; - pthread_t ticker; - int err; + pthread_attr_t attr; pthread_attr_init(&attr); - /* SCHED_FIFO corresponds to real-time preemptive priority-based - * scheduler. - * NOTE: This scheduling policy requires the superuser priviledges - */ + // SCHED_FIFO corresponds to real-time preemptive priority-based + // scheduler. + // NOTE: This scheduling policy requires the superuser priviledges pthread_attr_setschedpolicy (&attr, SCHED_FIFO); pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED); pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED); + struct sched_param param; param.sched_priority = l_tickPrio; - pthread_attr_setschedparam(&attr, ¶m); - err = pthread_create(&ticker, &attr, &ticker_thread, 0); + pthread_attr_setschedparam(&attr, ¶m); + pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); + + pthread_t ticker; + int err = pthread_create(&ticker, &attr, &ticker_thread, 0); if (err != 0) { - /* Creating the p-thread with the SCHED_FIFO policy failed. - * Most probably this application has no superuser privileges, - * so we just fall back to the default SCHED_OTHER policy - * and priority 0. - */ + // Creating the p-thread with the SCHED_FIFO policy failed. + // Most probably this application has no superuser privileges, + // so we just fall back to the default SCHED_OTHER policy + // and priority 0. pthread_attr_setschedpolicy(&attr, SCHED_OTHER); param.sched_priority = 0; pthread_attr_setschedparam(&attr, ¶m); err = pthread_create(&ticker, &attr, &ticker_thread, 0); } - Q_ASSERT_ID(310, err == 0); /* ticker thread must be created */ + QF_CRIT_ENTRY(); + Q_ASSERT_INCRIT(310, err == 0); // ticker thread must be created + QF_CRIT_EXIT(); //pthread_attr_getschedparam(&attr, ¶m); //printf("param.sched_priority==%d\n", param.sched_priority); @@ -151,96 +211,95 @@ int_t QF_run(void) { pthread_attr_destroy(&attr); } - /* the combined event-loop and background-loop of the QV kernel */ - QF_CRIT_E_(); + // the combined event-loop and background-loop of the QV kernel + QF_CRIT_ENTRY(); - /* produce the QS_QF_RUN trace record */ - QS_BEGIN_NOCRIT_PRE_(QS_QF_RUN, 0U) - QS_END_NOCRIT_PRE_() + // produce the QS_QF_RUN trace record + QS_BEGIN_PRE_(QS_QF_RUN, 0U) + QS_END_PRE_() + l_isRunning = true; // QF is running while (l_isRunning) { - /* find the maximum priority AO ready to run */ + Q_ASSERT_INCRIT(200, QPSet_verify_(&QF_readySet_, &QF_readySet_dis_)); + + // find the maximum priority AO ready to run if (QPSet_notEmpty(&QF_readySet_)) { uint_fast8_t p = QPSet_findMax(&QF_readySet_); QActive *a = QActive_registry_[p]; - QF_CRIT_X_(); - /* the active object 'a' must still be registered in QF - * (e.g., it must not be stopped) - */ - Q_ASSERT_ID(320, a != (QActive *)0); + // the active object 'a' must still be registered in QF + // (e.g., it must not be stopped) + Q_ASSERT_INCRIT(320, a != (QActive *)0); + QF_CRIT_EXIT(); - /* perform the run-to-completion (RTS) step... - * 1. retrieve the event from the AO's event queue, which by this - * time must be non-empty and The "Vanialla" kernel asserts it. - * 2. dispatch the event to the AO's state machine. - * 3. determine if event is garbage and collect it if so - */ QEvt const *e = QActive_get_(a); - QHSM_DISPATCH(&a->super, e, a->prio); + // dispatch event (virtual call) + (*a->super.vptr->dispatch)(&a->super, e, a->prio); QF_gc(e); - QF_CRIT_E_(); - - if (a->eQueue.frontEvt == (QEvt *)0) { /* empty queue? */ + QF_CRIT_ENTRY(); + if (a->eQueue.frontEvt == (QEvt *)0) { // empty queue? QPSet_remove(&QF_readySet_, p); +#ifndef Q_UNSAFE + QPSet_update_(&QF_readySet_, &QF_readySet_dis_); +#endif } } else { - /* the QV kernel in embedded systems calls here the QV_onIdle() - * callback. However, the POSIX-QV port does not do busy-waiting - * for events. Instead, the POSIX-QV port efficiently waits until - * QP events become available. - */ + // the QV kernel in embedded systems calls here the QV_onIdle() + // callback. However, the POSIX-QV port does not do busy-waiting + // for events. Instead, the POSIX-QV port efficiently waits until + // QP events become available. while (QPSet_isEmpty(&QF_readySet_)) { - pthread_cond_wait(&QV_condVar_, &l_pThreadMutex); + pthread_cond_wait(&QF_condVar_, &l_critSectMutex_); } } } - QF_CRIT_X_(); - QF_onCleanup(); /* cleanup callback */ - QS_EXIT(); /* cleanup the QSPY connection */ + QF_CRIT_EXIT(); + QF_onCleanup(); // cleanup callback + QS_EXIT(); // cleanup the QSPY connection - pthread_cond_destroy(&QV_condVar_); /* cleanup the condition variable */ - pthread_mutex_destroy(&l_pThreadMutex); /* cleanup the global mutex */ + pthread_cond_destroy(&QF_condVar_); // cleanup the condition variable + pthread_mutex_destroy(&l_critSectMutex_); // cleanup the global mutex - return 0; /* return success */ + return 0; // return success } -/*..........................................................................*/ -void QF_setTickRate(uint32_t ticksPerSec, int_t tickPrio) { +//............................................................................ +void QF_stop(void) { + l_isRunning = false; // terminate the main event-loop + + // unblock the event-loop so it can terminate + QPSet_insert(&QF_readySet_, 1U); +#ifndef Q_UNSAFE + QPSet_update_(&QF_readySet_, &QF_readySet_dis_); +#endif + pthread_cond_signal(&QF_condVar_); +} +//............................................................................ +void QF_setTickRate(uint32_t ticksPerSec, int tickPrio) { if (ticksPerSec != 0U) { - l_tick.tv_nsec = NANOSLEEP_NSEC_PER_SEC / ticksPerSec; + l_tick.tv_nsec = NSEC_PER_SEC / ticksPerSec; } else { - l_tick.tv_nsec = 0; /* means NO system clock tick */ + l_tick.tv_nsec = 0U; // means NO system clock tick } l_tickPrio = tickPrio; } -/*..........................................................................*/ -void QF_stop(void) { - uint_fast8_t p; - l_isRunning = false; /* terminate the main event-loop thread */ - /* unblock the event-loop so it can terminate */ - p = 1U; - QPSet_insert(&QF_readySet_, p); - pthread_cond_signal(&QV_condVar_); -} - -/*..........................................................................*/ +//............................................................................ void QF_consoleSetup(void) { - struct termios tio; /* modified terminal attributes */ + struct termios tio; // modified terminal attributes - tcgetattr(0, &l_tsav); /* save the current terminal attributes */ - tcgetattr(0, &tio); /* obtain the current terminal attributes */ - tio.c_lflag &= ~(ICANON | ECHO); /* disable the canonical mode & echo */ - tcsetattr(0, TCSANOW, &tio); /* set the new attributes */ + tcgetattr(0, &l_tsav); // save the current terminal attributes + tcgetattr(0, &tio); // obtain the current terminal attributes + tio.c_lflag &= ~(ICANON | ECHO); // disable the canonical mode & echo + tcsetattr(0, TCSANOW, &tio); // set the new attributes } -/*..........................................................................*/ +//............................................................................ void QF_consoleCleanup(void) { - tcsetattr(0, TCSANOW, &l_tsav); /* restore the saved attributes */ + tcsetattr(0, TCSANOW, &l_tsav); // restore the saved attributes } -/*..........................................................................*/ +//............................................................................ int QF_consoleGetKey(void) { int byteswaiting; ioctl(0, FIONREAD, &byteswaiting); @@ -249,112 +308,93 @@ int QF_consoleGetKey(void) { read(0, &ch, 1); return (int)ch; } - return 0; /* no input at this time */ + return 0; // no input at this time } -/*..........................................................................*/ +//............................................................................ int QF_consoleWaitForKey(void) { - return getchar(); + return (int)getchar(); } -/****************************************************************************/ -void QActive_start_(QActive * const me, QPrioSpec const prioSpec, - QEvt const * * const qSto, uint_fast16_t const qLen, - void * const stkSto, uint_fast16_t const stkSize, - void const * const par) -{ - (void)stkSize; /* unused parameter in the POSIX port */ +// QActive functions ========================================================= + +void QActive_start_(QActive * const me, QPrioSpec const prioSpec, + QEvt const * * const qSto, uint_fast16_t const qLen, + void * const stkSto, uint_fast16_t const stkSize, + void const * const par) +{ + Q_UNUSED_PAR(stkSto); + Q_UNUSED_PAR(stkSize); + + // no per-AO stack needed for this port + QF_CRIT_STAT + QF_CRIT_ENTRY(); + Q_REQUIRE_INCRIT(600, stkSto == (void *)0); + QF_CRIT_EXIT(); + + me->prio = (uint8_t)(prioSpec & 0xFFU); // QF-priority of the AO + me->pthre = 0U; // preemption-threshold (not used in this port) + QActive_register_(me); // register this AO - /* no external stack storage needed for this port */ - Q_REQUIRE_ID(600, (stkSto == (void *)0)); QEQueue_init(&me->eQueue, qSto, qLen); - me->prio = (uint8_t)(prioSpec & 0xFFU); /* QF-priority of the AO */ - me->pthre = (uint8_t)(prioSpec >> 8U); /* preemption-threshold */ - QActive_register_(me); /* register this AO */ - - /* the top-most initial tran. (virtual) */ - QHSM_INIT(&me->super, par, me->prio); - QS_FLUSH(); /* flush the trace buffer to the host */ + // top-most initial tran. (virtual call) + (*me->super.vptr->init)(&me->super, par, me->prio); + QS_FLUSH(); // flush the QS trace buffer to the host } -/*..........................................................................*/ -#ifdef QF_ACTIVE_STOP + +//............................................................................ +#ifdef QACTIVE_CAN_STOP void QActive_stop(QActive * const me) { - QF_CRIT_STAT_ + QActive_unsubscribeAll(me); - QActive_unsubscribeAll(me); /* unsubscribe from all events */ - - /* make sure the AO is no longer in "ready set" */ - QF_CRIT_E_(); + // make sure the AO is no longer in "ready set" + QF_CRIT_STAT + QF_CRIT_ENTRY(); QPSet_remove(&QF_readySet_, me->prio); - QF_CRIT_X_(); +#ifndef Q_UNSAFE + QPSet_update_(&QF_readySet_, &QF_readySet_dis_); +#endif + QF_CRIT_EXIT(); - QActive_unregister_(me); /* un-register this active object */ + QActive_unregister_(me); } #endif -/*..........................................................................*/ +//............................................................................ void QActive_setAttr(QActive *const me, uint32_t attr1, void const *attr2) { - (void)me; /* unused parameter */ - (void)attr1; /* unused parameter */ - (void)attr2; /* unused parameter */ - Q_ERROR_ID(900); /* this function should not be called in this QP port */ + Q_UNUSED_PAR(me); + Q_UNUSED_PAR(attr1); + Q_UNUSED_PAR(attr2); + Q_ERROR_INCRIT(900); // should not be called in this QP port } -/****************************************************************************/ -static void *ticker_thread(void *arg) { /* for pthread_create() */ - (void)arg; /* unused parameter */ - while (l_isRunning) { /* the clock tick loop... */ - nanosleep(&l_tick, NULL); /* sleep for the number of ticks, NOTE05 */ - QF_onClockTick(); /* clock tick callback (must call QTIMEEVT_TICK_X()) */ - } - return (void *)0; /* return success */ -} -/*..........................................................................*/ -static void sigIntHandler(int dummy) { - (void)dummy; /* unused parameter */ - QF_onCleanup(); - exit(-1); -} - -/*==========================================================================*/ -/* NOTE01: -* In Linux, the scheduler policy closest to real-time is the SCHED_FIFO -* policy, available only with superuser privileges. QF_run() attempts to set -* this policy as well as to maximize its priority, so that the ticking -* occurrs in the most timely manner (as close to an interrupt as possible). -* However, setting the SCHED_FIFO policy might fail, most probably due to -* insufficient privileges. -* -* NOTE02: -* On some Linux systems nanosleep() might actually not deliver the finest -* time granularity. For example, on some Linux implementations, nanosleep() -* could not block for shorter intervals than 20ms, while the underlying -* clock tick period was only 10ms. Sometimes, the select() system call can -* provide a finer granularity. -* -* NOTE03: -* Any blocking system call, such as nanosleep() or select() system call can -* be interrupted by a signal, such as ^C from the keyboard. In this case this -* QF port breaks out of the event-loop and returns to main() that exits and -* terminates all spawned p-threads. -* -* NOTE04: -* According to the man pages (for pthread_attr_setschedpolicy) the only value -* supported in the Linux p-threads implementation is PTHREAD_SCOPE_SYSTEM, -* meaning that the threads contend for CPU time with all processes running on -* the machine. In particular, thread priorities are interpreted relative to -* the priorities of all other processes on the machine. -* -* This is good, because it seems that if we set the priorities high enough, -* no other process (or thread running within) can gain control over the CPU. -* -* However, QF limits the number of priority levels to QF_MAX_ACTIVE. -* Assuming that a QF application will be real-time, this port reserves the -* three highest p-thread priorities for the ISR-like threads (e.g., I/O), -* and the rest highest-priorities for the active objects. -* -* NOTE05: -* In some (older) Linux kernels, the POSIX nanosleep() system call might -* deliver only 2*actual-system-tick granularity. To compensate for this, -* you would need to reduce the constant NANOSLEEP_NSEC_PER_SEC by factor 2. -*/ +//============================================================================ +// NOTE01: +// In Linux, the scheduler policy closest to real-time is the SCHED_FIFO +// policy, available only with superuser privileges. QF_run() attempts to set +// this policy as well as to maximize its priority, so that the ticking +// occurs in the most timely manner (as close to an interrupt as possible). +// However, setting the SCHED_FIFO policy might fail, most probably due to +// insufficient privileges. +// +// NOTE03: +// Any blocking system call, such as clock_nanosleep() system call can +// be interrupted by a signal, such as ^C from the keyboard. In this case this +// QF port breaks out of the event-loop and returns to main() that exits and +// terminates all spawned p-threads. +// +// NOTE04: +// According to the man pages (for pthread_attr_setschedpolicy) the only value +// supported in the Linux p-threads implementation is PTHREAD_SCOPE_SYSTEM, +// meaning that the threads contend for CPU time with all processes running on +// the machine. In particular, thread priorities are interpreted relative to +// the priorities of all other processes on the machine. +// +// This is good, because it seems that if we set the priorities high enough, +// no other process (or thread running within) can gain control over the CPU. +// +// However, QF limits the number of priority levels to QF_MAX_ACTIVE. +// Assuming that a QF application will be real-time, this port reserves the +// three highest p-thread priorities for the ISR-like threads (e.g., I/O), +// and the remaining highest-priorities for the active objects. +// diff --git a/ports/posix-qv/qf_port.h b/ports/posix-qv/qf_port.h deleted file mode 100644 index 3c2f2bae..00000000 --- a/ports/posix-qv/qf_port.h +++ /dev/null @@ -1,150 +0,0 @@ -/*============================================================================ -* QP/C Real-Time Embedded Framework (RTEF) -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2022-07-30 -* @version Last updated for: @ref qpc_7_0_1 -* -* @file -* @brief QF/C port to POSIX API (single-threaded, like the QV kernel) -*/ -#ifndef QF_PORT_H -#define QF_PORT_H - -/* POSIX-QV event queue and thread types */ -#define QF_EQUEUE_TYPE QEQueue -/* QF_OS_OBJECT_TYPE not used in this port */ -/* QF_THREAD_TYPE not used in this port */ - -/* The maximum number of active objects in the application */ -#define QF_MAX_ACTIVE 64U - -/* The number of system clock tick rates */ -#define QF_MAX_TICK_RATE 2U - -/* Activate the QF QActive_stop() API */ -#define QF_ACTIVE_STOP 1 - -/* various QF object sizes configuration for this port */ -#define QF_EVENT_SIZ_SIZE 4U -#define QF_EQUEUE_CTR_SIZE 4U -#define QF_MPOOL_SIZ_SIZE 4U -#define QF_MPOOL_CTR_SIZE 4U -#define QF_TIMEEVT_CTR_SIZE 4U - -/* QF critical section entry/exit for POSIX-QV, see NOTE1 */ -/* QF_CRIT_STAT_TYPE not defined */ -#define QF_CRIT_ENTRY(dummy) QF_enterCriticalSection_() -#define QF_CRIT_EXIT(dummy) QF_leaveCriticalSection_() - -/* QF_LOG2 not defined -- use the internal LOG2() implementation */ - -#include "qep_port.h" /* QEP port */ -#include "qequeue.h" /* POSIX-QV needs event-queue */ -#include "qmpool.h" /* POSIX-QV needs memory-pool */ -#include "qf.h" /* QF platform-independent public interface */ - -void QF_enterCriticalSection_(void); -void QF_leaveCriticalSection_(void); - -/* set clock tick rate and p-thread priority -* (NOTE ticksPerSec==0 disables the "ticker thread" -*/ -void QF_setTickRate(uint32_t ticksPerSec, int_t tickPrio); - -/* clock tick callback (NOTE not called when "ticker thread" is not running) */ -void QF_onClockTick(void); /* clock tick callback (provided in the app) */ - -/* abstractions for console access... */ -void QF_consoleSetup(void); -void QF_consoleCleanup(void); -int QF_consoleGetKey(void); -int QF_consoleWaitForKey(void); - -/****************************************************************************/ -/* interface used only inside QF implementation, but not in applications */ -#ifdef QP_IMPL - - /* scheduler locking (not needed in single-thread port) */ - #define QF_SCHED_STAT_ - #define QF_SCHED_LOCK_(dummy) ((void)0) - #define QF_SCHED_UNLOCK_() ((void)0) - - /* POSIX-QV active object event queue customization... */ - #define QACTIVE_EQUEUE_WAIT_(me_) \ - Q_ASSERT((me_)->eQueue.frontEvt != (QEvt *)0) - - #define QACTIVE_EQUEUE_SIGNAL_(me_) do { \ - QPSet_insert(&QF_readySet_, (me_)->prio); \ - pthread_cond_signal(&QV_condVar_); \ - } while (false) - - /* native QF event pool operations */ - #define QF_EPOOL_TYPE_ QMPool - #define QF_EPOOL_INIT_(p_, poolSto_, poolSize_, evtSize_) \ - (QMPool_init(&(p_), (poolSto_), (poolSize_), (evtSize_))) - #define QF_EPOOL_EVENT_SIZE_(p_) ((uint_fast16_t)(p_).blockSize) - #define QF_EPOOL_GET_(p_, e_, m_, qs_id_) \ - ((e_) = (QEvt *)QMPool_get(&(p_), (m_), (qs_id_))) - #define QF_EPOOL_PUT_(p_, e_, qs_id_) \ - (QMPool_put(&(p_), (e_), (qs_id_))) - - #include /* POSIX-thread API */ - - extern pthread_cond_t QV_condVar_; /* Cond.var. to signal events */ - -#endif /* QP_IMPL */ - -/*==========================================================================*/ -/* -* NOTE1: -* QF, like all real-time frameworks, needs to execute certain sections of -* code exclusively, meaning that only one thread can execute the code at -* the time. Such sections of code are called "critical sections" -* -* This port uses a pair of functions QF_enterCriticalSection_() / -* QF_leaveCriticalSection_() to enter/leave the cirtical section, -* respectively. -* -* These functions are implemented in the qf_port.c module, where they -* manipulate the file-scope POSIX mutex object l_pThreadMutex_ -* to protect all critical sections. Using the single mutex for all crtical -* section guarantees that only one thread at a time can execute inside a -* critical section. This prevents race conditions and data corruption. -* -* Please note, however, that the POSIX mutex implementation behaves -* differently than interrupt disabling. A common POSIX mutex ensures -* that only one thread at a time can execute a critical section, but it -* does not guarantee that a context switch cannot occur within the -* critical section. In fact, such context switches probably will happen, -* but they should not cause concurrency hazards because the critical -* section eliminates all race conditionis. -* -* Unlinke simply disabling and enabling interrupts, the mutex approach is -* also subject to priority inversions. However, the p-thread mutex -* implementation, such as POSIX threads, should support the priority- -* inheritance protocol. -*/ - -#endif /* QF_PORT_H */ diff --git a/ports/posix-qv/qp_port.h b/ports/posix-qv/qp_port.h new file mode 100644 index 00000000..de009827 --- /dev/null +++ b/ports/posix-qv/qp_port.h @@ -0,0 +1,160 @@ +//============================================================================ +// QP/C Real-Time Embedded Framework (RTEF) +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC . +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +//============================================================================ +//! @date Last updated on: 2023-09-07 +//! @version Last updated for: @ref qpc_7_3_0 +//! +//! @file +//! @brief QP/C port to POSIX-QV (single-threaded) with GNU compiler + +#ifndef QP_PORT_H_ +#define QP_PORT_H_ + +#include // Exact-width types. WG14/N843 C99 Standard +#include // Boolean type. WG14/N843 C99 Standard + +#ifdef QP_CONFIG +#include "qp_config.h" // external QP configuration +#endif + +// no-return function specifier (C11 Standard) +#define Q_NORETURN _Noreturn void + +// QF event queue and thread types for POSIX-QV +#define QACTIVE_EQUEUE_TYPE QEQueue +//QACTIVE_OS_OBJ_TYPE not used in this port +//QACTIVE_THREAD_TYPE not used in this port + +// QF critical section for POSIX-QV, see NOTE1 +#define QF_CRIT_STAT +#define QF_CRIT_ENTRY() QF_enterCriticalSection_() +#define QF_CRIT_EXIT() QF_leaveCriticalSection_() + +// QF_LOG2 not defined -- use the internal LOG2() implementation + +// internal functions for critical section management +void QF_enterCriticalSection_(void); +void QF_leaveCriticalSection_(void); + +// set clock tick rate and p-thread priority +// (NOTE ticksPerSec==0 disables the "ticker thread" +void QF_setTickRate(uint32_t ticksPerSec, int tickPrio); + +// clock tick callback (NOTE not called when "ticker thread" is not running) +void QF_onClockTick(void); + +// abstractions for console access... +void QF_consoleSetup(void); +void QF_consoleCleanup(void); +int QF_consoleGetKey(void); +int QF_consoleWaitForKey(void); + +// include files ------------------------------------------------------------- +#include "qequeue.h" // POSIX-QV needs the native event-queue +#include "qmpool.h" // POSIX-QV needs the native memory-pool +#include "qp.h" // QP platform-independent public interface + +//============================================================================ +// interface used only inside QF implementation, but not in applications + +#ifdef QP_IMPL + + // QF scheduler locking for POSIX-QV (not needed in single-thread port) + #define QF_SCHED_STAT_ + #define QF_SCHED_LOCK_(dummy) ((void)0) + #define QF_SCHED_UNLOCK_() ((void)0) + + // QF event queue customization for POSIX-QV... + #define QACTIVE_EQUEUE_WAIT_(me_) \ + Q_ASSERT_INCRIT(302, (me_)->eQueue.frontEvt != (QEvt *)0) +#ifndef Q_UNSAFE + #define QACTIVE_EQUEUE_SIGNAL_(me_) \ + QPSet_insert(&QF_readySet_, (me_)->prio); \ + QPSet_update_(&QF_readySet_, &QF_readySet_dis_); \ + pthread_cond_signal(&QF_condVar_) +#else + #define QACTIVE_EQUEUE_SIGNAL_(me_) \ + QPSet_insert(&QF_readySet_, (me_)->prio); \ + pthread_cond_signal(&QF_condVar_) +#endif + + // native QF event pool operations + #define QF_EPOOL_TYPE_ QMPool + #define QF_EPOOL_INIT_(p_, poolSto_, poolSize_, evtSize_) \ + (QMPool_init(&(p_), (poolSto_), (poolSize_), (evtSize_))) + #define QF_EPOOL_EVENT_SIZE_(p_) ((uint_fast16_t)(p_).blockSize) + #define QF_EPOOL_GET_(p_, e_, m_, qs_id_) \ + ((e_) = (QEvt *)QMPool_get(&(p_), (m_), (qs_id_))) + #define QF_EPOOL_PUT_(p_, e_, qs_id_) \ + (QMPool_put(&(p_), (e_), (qs_id_))) + + #include // POSIX-thread API + + extern QPSet QF_readySet_; + extern QPSet QF_readySet_dis_; + extern pthread_cond_t QF_condVar_; // Cond.var. to signal events + +#endif // QP_IMPL + +//============================================================================ +// NOTE1: +// QP, like all real-time frameworks, needs to execute certain sections of +// code exclusively, meaning that only one thread can execute the code at +// the time. Such sections of code are called "critical sections". +// +// This port uses a pair of functions QF_enterCriticalSection_() / +// QF_leaveCriticalSection_() to enter/leave the cirtical section, +// respectively. +// +// These functions are implemented in the qf_port.c module, where they +// manipulate the file-scope POSIX mutex object l_critSectMutex_ +// to protect all critical sections. Using the single mutex for all crtical +// section guarantees that only one thread at a time can execute inside a +// critical section. This prevents race conditions and data corruption. +// +// Please note, however, that the POSIX mutex implementation behaves +// differently than interrupt disabling. A common POSIX mutex ensures +// that only one thread at a time can execute a critical section, but it +// does not guarantee that a context switch cannot occur within the +// critical section. In fact, such context switches probably will happen, +// but they should not cause concurrency hazards because the critical +// section eliminates all race conditionis. +// +// Unlinke simply disabling and enabling interrupts, the mutex approach is +// also subject to priority inversions. However, the p-thread mutex +// implementation, such as POSIX threads, should support the priority- +// inheritance protocol. +// +// NOTE2: +// Scheduler locking (used inside QActive_publish_()) is not needed in the +// single-threaded port, because event multicasting is already atomic. +// + +#endif // QP_PORT_H_ + diff --git a/ports/posix-qv/qs_port.c b/ports/posix-qv/qs_port.c index 259b516b..40754b42 100644 --- a/ports/posix-qv/qs_port.c +++ b/ports/posix-qv/qs_port.c @@ -1,48 +1,47 @@ -/*============================================================================ -* QP/C Real-Time Embedded Framework (RTEF) -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2023-01-07 -* @version Last updated for: @ref qpc_7_2_0 -* -* @file -* @brief QS/C port to POSIX -*/ -/* expose features from the 2008 POSIX standard (IEEE Standard 1003.1-2008) */ +//============================================================================ +// QP/C Real-Time Embedded Framework (RTEF) +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +//============================================================================ +//! @date Last updated on: 2023-08-20 +//! @version Last updated for: @ref qpc_7_3_0 +//! +//! @file +//! @brief QS/C port to POSIX + +// expose features from the 2008 POSIX standard (IEEE Standard 1003.1-2008) #define _POSIX_C_SOURCE 200809L #ifndef Q_SPY #error "Q_SPY must be defined to compile qs_port.c" -#endif /* Q_SPY */ +#endif // Q_SPY -#define QP_IMPL /* this is QP implementation */ -#include "qf_port.h" /* QF port */ -#include "qassert.h" /* QP embedded systems-friendly assertions */ -#include "qs_port.h" /* QS port */ -#include "qs_pkg.h" /* QS package-scope interface */ +#define QP_IMPL // this is QP implementation +#include "qp_port.h" // QP port +#include "qsafe.h" // QP Functional Safety (FuSa) System +#include "qs_port.h" // QS port +#include "qs_pkg.h" // QS package-scope interface -#include "safe_std.h" /* portable "safe" / facilities */ +#include "safe_std.h" // portable "safe" / facilities #include #include #include @@ -53,26 +52,31 @@ #include #include -/*Q_DEFINE_THIS_MODULE("qs_port")*/ +//Q_DEFINE_THIS_MODULE("qs_port") #define QS_TX_SIZE (8*1024) #define QS_RX_SIZE (2*1024) #define QS_TX_CHUNK QS_TX_SIZE -#define QS_TIMEOUT_MS 10 +#define QS_TIMEOUT_MS 10L #define INVALID_SOCKET -1 #define SOCKET_ERROR -1 -/* local variables .........................................................*/ +// local variables ......................................................... static int l_sock = INVALID_SOCKET; static struct timespec const c_timeout = { 0, QS_TIMEOUT_MS*1000000L }; -/*..........................................................................*/ +//............................................................................ uint8_t QS_onStartup(void const *arg) { - static uint8_t qsBuf[QS_TX_SIZE]; /* buffer for QS-TX channel */ - static uint8_t qsRxBuf[QS_RX_SIZE]; /* buffer for QS-RX channel */ + + static uint8_t qsBuf[QS_TX_SIZE]; // buffer for QS-TX channel + QS_initBuf(qsBuf, sizeof(qsBuf)); + + static uint8_t qsRxBuf[QS_RX_SIZE]; // buffer for QS-RX channel + QS_rxInitBuf(qsRxBuf, sizeof(qsRxBuf)); + char hostName[128]; - char const *serviceName = "6601"; /* default QSPY server port */ + char const *serviceName = "6601"; // default QSPY server port char const *src; char *dst; int status; @@ -82,14 +86,10 @@ uint8_t QS_onStartup(void const *arg) { struct addrinfo hints; int sockopt_bool; - /* initialize the QS transmit and receive buffers */ - QS_initBuf(qsBuf, sizeof(qsBuf)); - QS_rxInitBuf(qsRxBuf, sizeof(qsRxBuf)); - - /* extract hostName from 'arg' (hostName:port_remote)... */ + // extract hostName from 'arg' (hostName:port_remote)... src = (arg != (void *)0) ? (char const *)arg - : "localhost"; /* default QSPY host */ + : "localhost"; // default QSPY host dst = hostName; while ((*src != '\0') && (*src != ':') @@ -97,9 +97,9 @@ uint8_t QS_onStartup(void const *arg) { { *dst++ = *src++; } - *dst = '\0'; /* zero-terminate hostName */ + *dst = '\0'; // zero-terminate hostName - /* extract serviceName from 'arg' (hostName:serviceName)... */ + // extract serviceName from 'arg' (hostName:serviceName)... if (*src == ':') { serviceName = src + 1; } @@ -131,7 +131,7 @@ uint8_t QS_onStartup(void const *arg) { freeaddrinfo(result); - /* socket could not be opened & connected? */ + // socket could not be opened & connected? if (l_sock == INVALID_SOCKET) { FPRINTF_S(stderr, " ERROR cannot connect to QSPY at " "host=%s:%s\n", @@ -139,7 +139,7 @@ uint8_t QS_onStartup(void const *arg) { goto error; } - /* set the socket to non-blocking mode */ + // set the socket to non-blocking mode status = fcntl(l_sock, F_GETFL, 0); if (status == -1) { FPRINTF_S(stderr, @@ -155,143 +155,143 @@ uint8_t QS_onStartup(void const *arg) { goto error; } - /* configure the socket to reuse the address and not to linger */ + // configure the socket to reuse the address and not to linger sockopt_bool = 1; setsockopt(l_sock, SOL_SOCKET, SO_REUSEADDR, &sockopt_bool, sizeof(sockopt_bool)); - sockopt_bool = 0; /* negative option */ + sockopt_bool = 0; // negative option setsockopt(l_sock, SOL_SOCKET, SO_LINGER, &sockopt_bool, sizeof(sockopt_bool)); QS_onFlush(); - return 1U; /* success */ + return 1U; // success error: - return 0U; /* failure */ + return 0U; // failure } -/*..........................................................................*/ +//............................................................................ void QS_onCleanup(void) { + static struct timespec const c_timeout = {0, 10L*QS_TIMEOUT_MS*1000000L }; + nanosleep(&c_timeout, NULL); // allow the last QS output to come out if (l_sock != INVALID_SOCKET) { close(l_sock); l_sock = INVALID_SOCKET; } - /*PRINTF_S(" Disconnected from QSPY\n");*/ + //PRINTF_S(" Disconnected from QSPY\n"); } -/*..........................................................................*/ +//............................................................................ void QS_onReset(void) { QS_onCleanup(); + //PRINTF_S("\n%s\n", "QS_onReset"); exit(0); } -/*..........................................................................*/ +//............................................................................ void QS_onFlush(void) { - uint16_t nBytes; - uint8_t const *data; - QS_CRIT_STAT_ - - if (l_sock == INVALID_SOCKET) { /* socket NOT initialized? */ - FPRINTF_S(stderr, " ERROR %s\n", "invalid TCP socket"); + if (l_sock == INVALID_SOCKET) { // socket NOT initialized? + FPRINTF_S(stderr, " ERROR %s\n", + "invalid TCP socket"); + QF_stop(); // <== stop and exit the application return; } - nBytes = QS_TX_CHUNK; - QS_CRIT_E_(); + QS_CRIT_STAT + QS_CRIT_ENTRY(); + uint16_t nBytes = QS_TX_CHUNK; + uint8_t const *data; while ((data = QS_getBlock(&nBytes)) != (uint8_t *)0) { - QS_CRIT_X_(); - for (;;) { /* for-ever until break or return */ + QS_CRIT_EXIT(); + for (;;) { // for-ever until break or return int nSent = send(l_sock, (char const *)data, (int)nBytes, 0); - if (nSent == SOCKET_ERROR) { /* sending failed? */ + if (nSent == SOCKET_ERROR) { // sending failed? if ((errno == EWOULDBLOCK) || (errno == EAGAIN)) { - /* sleep for the timeout and then loop back - * to send() the SAME data again - */ + // sleep for the timeout and then loop back + // to send() the SAME data again nanosleep(&c_timeout, NULL); } - else { /* some other socket error... */ + else { // some other socket error... FPRINTF_S(stderr, " ERROR sending data over TCP," "errno=%d\n", errno); + QF_stop(); // <== stop and exit the application return; } } - else if (nSent < (int)nBytes) { /* sent fewer than requested? */ - nanosleep(&c_timeout, NULL); /* sleep for the timeout */ - /* adjust the data and loop back to send() the rest */ + else if (nSent < (int)nBytes) { // sent fewer than requested? + nanosleep(&c_timeout, NULL); // sleep for the timeout + // adjust the data and loop back to send() the rest data += nSent; nBytes -= (uint16_t)nSent; } else { - break; + break; // break out of the for-ever loop } } - /* set nBytes for the next call to QS_getBlock() */ + // set nBytes for the next call to QS_getBlock() nBytes = QS_TX_CHUNK; - QS_CRIT_E_(); + QS_CRIT_ENTRY(); } - QS_CRIT_X_(); + QS_CRIT_EXIT(); } -/*..........................................................................*/ +//............................................................................ QSTimeCtr QS_onGetTime(void) { struct timespec tspec; - QSTimeCtr time; clock_gettime(CLOCK_MONOTONIC_RAW, &tspec); - /* convert to units of 0.1 microsecond */ - time = (QSTimeCtr)(tspec.tv_sec * 10000000 + tspec.tv_nsec / 100); + // convert to units of 0.1 microsecond + QSTimeCtr time = (QSTimeCtr)(tspec.tv_sec * 10000000 + tspec.tv_nsec / 100); return time; } -/*..........................................................................*/ +//............................................................................ void QS_output(void) { - uint16_t nBytes; - uint8_t const *data; - QS_CRIT_STAT_ - - if (l_sock == INVALID_SOCKET) { /* socket NOT initialized? */ - FPRINTF_S(stderr, " ERROR %s\n", "invalid TCP socket"); + if (l_sock == INVALID_SOCKET) { // socket NOT initialized? + FPRINTF_S(stderr, " ERROR %s\n", + "invalid TCP socket"); + QF_stop(); // <== stop and exit the application return; } - nBytes = QS_TX_CHUNK; - QS_CRIT_E_(); - if ((data = QS_getBlock(&nBytes)) != (uint8_t *)0) { - QS_CRIT_X_(); - for (;;) { /* for-ever until break or return */ + QS_CRIT_STAT + QS_CRIT_ENTRY(); + uint16_t nBytes = QS_TX_CHUNK; + uint8_t const *data = QS_getBlock(&nBytes); + QS_CRIT_EXIT(); + + if (nBytes > 0U) { // any bytes to send? + for (;;) { // for-ever until break or return int nSent = send(l_sock, (char const *)data, (int)nBytes, 0); - if (nSent == SOCKET_ERROR) { /* sending failed? */ + if (nSent == SOCKET_ERROR) { // sending failed? if ((errno == EWOULDBLOCK) || (errno == EAGAIN)) { - /* sleep for the timeout and then loop back - * to send() the SAME data again - */ + // sleep for the timeout and then loop back + // to send() the SAME data again nanosleep(&c_timeout, NULL); } - else { /* some other socket error... */ + else { // some other socket error... FPRINTF_S(stderr, " ERROR sending data over TCP," "errno=%d\n", errno); + QF_stop(); // <== stop and exit the application return; } } - else if (nSent < (int)nBytes) { /* sent fewer than requested? */ - nanosleep(&c_timeout, NULL); /* sleep for the timeout */ - /* adjust the data and loop back to send() the rest */ + else if (nSent < (int)nBytes) { // sent fewer than requested? + nanosleep(&c_timeout, NULL); // sleep for the timeout + // adjust the data and loop back to send() the rest data += nSent; nBytes -= (uint16_t)nSent; } else { - break; + break; // break out of the for-ever loop } } } - else { - QS_CRIT_X_(); - } } -/*..........................................................................*/ +//............................................................................ void QS_rx_input(void) { int status = recv(l_sock, (char *)QS_rxPriv_.buf, (int)QS_rxPriv_.end, 0); - if (status > 0) { /* any data received? */ + if (status > 0) { // any data received? QS_rxPriv_.tail = 0U; - QS_rxPriv_.head = status; /* # bytes received */ - QS_rxParse(); /* parse all received bytes */ + QS_rxPriv_.head = status; // # bytes received + QS_rxParse(); // parse all received bytes } } diff --git a/ports/posix-qv/qs_port.h b/ports/posix-qv/qs_port.h index 70e917bd..79c8e010 100644 --- a/ports/posix-qv/qs_port.h +++ b/ports/posix-qv/qs_port.h @@ -1,63 +1,61 @@ -/*============================================================================ -* QP/C Real-Time Embedded Framework (RTEF) -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2023-01-07 -* @version Last updated for: @ref qpc_7_2_0 -* -* @file -* @brief QS/C port to POSIX with GNU compiler -*/ -#ifndef QS_PORT_H -#define QS_PORT_H +//============================================================================ +// QP/C Real-Time Embedded Framework (RTEF) +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +//============================================================================ +//! @date Last updated on: 2023-08-19 +//! @version Last updated for: @ref qpc_7_3_0 +//! +//! @file +//! @brief QS/C port to POSIX with GNU + +#ifndef QS_PORT_H_ +#define QS_PORT_H_ #define QS_CTR_SIZE 4U #define QS_TIME_SIZE 4U -#if defined(__LP64__) || defined(_LP64) /* 64-bit architecture? */ +#if defined(__LP64__) || defined(_LP64) // 64-bit architecture? #define QS_OBJ_PTR_SIZE 8U #define QS_FUN_PTR_SIZE 8U -#else /* 32-bit architecture */ +#else // 32-bit architecture #define QS_OBJ_PTR_SIZE 4U #define QS_FUN_PTR_SIZE 4U #endif -void QS_output(void); /* handle the QS output */ -void QS_rx_input(void); /* handle the QS-RX input */ +void QS_output(void); // handle the QS output +void QS_rx_input(void); // handle the QS-RX input -/*==========================================================================*/ -/* NOTE: QS might be used with or without other QP components, in which -* case the separate definitions of the macros QF_CRIT_STAT_TYPE, -* QF_CRIT_ENTRY, and QF_CRIT_EXIT are needed. In this port QS is configured -* to be used with the other QP component, by simply including "qf_port.h" -* *before* "qs.h". -*/ -#ifndef QF_PORT_H -#include "qf_port.h" /* use QS with QF */ +//============================================================================ +// NOTE: QS might be used with or without other QP components, in which +// case the separate definitions of the macros QF_CRIT_STAT, QF_CRIT_ENTRY(), +// and QF_CRIT_EXIT() are needed. In this port QS is configured to be used +// with the other QP component, by simply including "qp_port.h" +//*before* "qs.h". +#ifndef QP_PORT_H_ +#include "qp_port.h" // use QS with QP #endif -#include "qs.h" /* QS platform-independent public interface */ +#include "qs.h" // QS platform-independent public interface -#endif /* QS_PORT_H */ +#endif // QS_PORT_H_ diff --git a/ports/posix-qv/safe_std.h b/ports/posix-qv/safe_std.h index 7e0a2439..c752662c 100644 --- a/ports/posix-qv/safe_std.h +++ b/ports/posix-qv/safe_std.h @@ -1,42 +1,40 @@ -/*============================================================================ -* QP/C Real-Time Embedded Framework (RTEF) -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2022-07-30 -* @version Last updated for: @ref qpc_7_0_1 -* -* @file -* @brief "safe" and facilities -*/ +//============================================================================ +// QP/C Real-Time Embedded Framework (RTEF) +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +//============================================================================ +//! @date Last updated on: 2022-07-30 +//! @version Last updated for: @ref qpc_7_1_3 +//! +//! @file +//! @brief "safe" and facilities #ifndef SAFE_STD_H #define SAFE_STD_H #include #include -/* portable "safe" facilities from and ................*/ -#ifdef _WIN32 /* Windows OS? */ +// portable "safe" facilities from and ................ +#ifdef _WIN32 // Windows OS? #define MEMMOVE_S(dest_, num_, src_, count_) \ memmove_s(dest_, num_, src_, count_) @@ -48,13 +46,13 @@ strcat_s(dest_, destsiz_, src_) #define SNPRINTF_S(buf_, bufsiz_, format_, ...) \ - _snprintf_s(buf_, bufsiz_, _TRUNCATE, format_, ##__VA_ARGS__) + _snprintf_s(buf_, bufsiz_, _TRUNCATE, format_, __VA_ARGS__) #define PRINTF_S(format_, ...) \ - printf_s(format_, ##__VA_ARGS__) + printf_s(format_, __VA_ARGS__) #define FPRINTF_S(fp_, format_, ...) \ - fprintf_s(fp_, format_, ##__VA_ARGS__) + fprintf_s(fp_, format_, __VA_ARGS__) #ifdef _MSC_VER #define FREAD_S(buf_, bufsiz_, elsiz_, count_, fp_) \ @@ -62,7 +60,7 @@ #else #define FREAD_S(buf_, bufsiz_, elsiz_, count_, fp_) \ fread(buf_, elsiz_, count_, fp_) -#endif /* _MSC_VER */ +#endif // _MSC_VER #define FOPEN_S(fp_, fName_, mode_) \ if (fopen_s(&fp_, fName_, mode_) != 0) { \ @@ -72,7 +70,7 @@ if (fopen_s(&fp_, fName_, mode_) != 0) { \ #define LOCALTIME_S(tm_, time_) \ localtime_s(tm_, time_) -#else /* other OS (Linux, MacOS, etc.) .....................................*/ +#else // other OS (Linux, MacOS, etc.) ..................................... #define MEMMOVE_S(dest_, num_, src_, count_) \ memmove(dest_, src_, count_) @@ -86,13 +84,13 @@ if (fopen_s(&fp_, fName_, mode_) != 0) { \ strcat(dest_, src_) #define SNPRINTF_S(buf_, bufsiz_, format_, ...) \ - snprintf(buf_, bufsiz_, format_, ##__VA_ARGS__) + snprintf(buf_, bufsiz_, format_, __VA_ARGS__) #define PRINTF_S(format_, ...) \ - printf(format_, ##__VA_ARGS__) + printf(format_, __VA_ARGS__) #define FPRINTF_S(fp_, format_, ...) \ - fprintf(fp_, format_, ##__VA_ARGS__) + fprintf(fp_, format_, __VA_ARGS__) #define FREAD_S(buf_, bufsiz_, elsiz_, count_, fp_) \ fread(buf_, elsiz_, count_, fp_) @@ -103,6 +101,6 @@ if (fopen_s(&fp_, fName_, mode_) != 0) { \ #define LOCALTIME_S(tm_, time_) \ memcpy(tm_, localtime(time_), sizeof(struct tm)) -#endif /* _WIN32 */ +#endif // _WIN32 -#endif /* SAFE_STD_H */ +#endif // SAFE_STD_H diff --git a/ports/posix/qep_port.h b/ports/posix/qep_port.h deleted file mode 100644 index 7cc207f5..00000000 --- a/ports/posix/qep_port.h +++ /dev/null @@ -1,43 +0,0 @@ -/*============================================================================ -* QP/C Real-Time Embedded Framework (RTEF) -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2023-01-07 -* @version Last updated for: @ref qpc_7_2_0 -* -* @file -* @brief QEP/C port, generic C11 compiler -*/ -#ifndef QEP_PORT_H -#define QEP_PORT_H - -/*! no-return function specifier (C11 Standard) */ -#define Q_NORETURN _Noreturn void - -#include /* Exact-width types. WG14/N843 C99 Standard */ -#include /* Boolean type. WG14/N843 C99 Standard */ - -#include "qep.h" /* QEP platform-independent public interface */ - -#endif /* QEP_PORT_H */ diff --git a/ports/posix/qf_port.c b/ports/posix/qf_port.c index 76f1a4a3..f563da74 100644 --- a/ports/posix/qf_port.c +++ b/ports/posix/qf_port.c @@ -1,54 +1,52 @@ -/*============================================================================ -* QP/C Real-Time Embedded Framework (RTEF) -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2023-01-07 -* @version Last updated for: @ref qpc_7_2_0 -* -* @file -* @brief QF/C port to POSIX API (multi-threaded) -*/ +//============================================================================ +// QP/C Real-Time Embedded Framework (RTEF) +// Copyright (C) 2005 Quantum Leaps, LLC . +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +//============================================================================ +//! @date Last updated on: 2023-08-26 +//! @version Last updated for: @ref qpc_7_3_0 +//! +//! @file +//! @brief QF/C port to POSIX (multithreaded with P-threads) -/* expose features from the 2008 POSIX standard (IEEE Standard 1003.1-2008) */ +// expose features from the 2008 POSIX standard (IEEE Standard 1003.1-2008) #define _POSIX_C_SOURCE 200809L -#define QP_IMPL /* this is QP implementation */ -#include "qf_port.h" /* QF port */ -#include "qf_pkg.h" -#include "qassert.h" -#ifdef Q_SPY /* QS software tracing enabled? */ - #include "qs_port.h" /* QS port */ - #include "qs_pkg.h" /* QS package-scope internal interface */ +#define QP_IMPL // this is QP implementation +#include "qp_port.h" // QP port +#include "qp_pkg.h" // QP package-scope interface +#include "qsafe.h" // QP Functional Safety (FuSa) Subsystem +#ifdef Q_SPY // QS software tracing enabled? + #include "qs_port.h" // QS port + #include "qs_pkg.h" // QS package-scope internal interface #else - #include "qs_dummy.h" /* disable the QS software tracing */ -#endif /* Q_SPY */ + #include "qs_dummy.h" // disable the QS software tracing +#endif // Q_SPY -#include /* for PTHREAD_STACK_MIN */ -#include /* for mlockall() */ -#include +#include // for PTHREAD_STACK_MIN +#include // for mlockall() #include -#include /* for memcpy() and memset() */ +#include // for clock_nanosleep() +#include // for memcpy() and memset() #include #include #include @@ -57,117 +55,153 @@ Q_DEFINE_THIS_MODULE("qf_port") -/* Global objects ==========================================================*/ -pthread_mutex_t QF_pThreadMutex_; /* mutex for QF critical section */ +// Local objects ============================================================= +// initialize the startup mutex with default non-recursive initializer +static pthread_mutex_t l_startupMutex = PTHREAD_MUTEX_INITIALIZER; -/* Local objects ===========================================================*/ -static pthread_mutex_t l_startupMutex; -static bool l_isRunning; /* flag indicating when QF is running */ -static struct termios l_tsav; /* structure with saved terminal attributes */ -static struct timespec l_tick; -static int_t l_tickPrio; -enum { NANOSLEEP_NSEC_PER_SEC = 1000000000 }; /* see NOTE05 */ +static bool l_isRunning; // flag indicating when QF is running +static struct termios l_tsav; // structure with saved terminal attributes +static struct timespec l_tick; // structure for the clock tick +static int_t l_tickPrio; // priority of the ticker thread -static void sigIntHandler(int dummy); +#define NSEC_PER_SEC 1000000000L +#define DEFAULT_TICKS_PER_SEC 100L -/* QF functions ============================================================*/ +static void sigIntHandler(int dummy); // prototype +static void sigIntHandler(int dummy) { + Q_UNUSED_PAR(dummy); + QF_onCleanup(); + exit(-1); +} + +//============================================================================ + +// NOTE: initialize the critical section mutex first with default +// non-recursive initializer, but later in QF_init() it will be +// re-initialized it as *recursive mutex* in a portable way +pthread_mutex_t QF_critSectMutex_ = PTHREAD_MUTEX_INITIALIZER; + +//............................................................................ void QF_init(void) { - struct sigaction sig_act; + // lock memory so we're never swapped out to disk + //mlockall(MCL_CURRENT | MCL_FUTURE); // un-comment when supported - /* lock memory so we're never swapped out to disk */ - /*mlockall(MCL_CURRENT | MCL_FUTURE); uncomment when supported */ - - /* init the global mutex with the default non-recursive initializer */ - pthread_mutex_init(&QF_pThreadMutex_, NULL); - - /* init the startup mutex with the default non-recursive initializer */ - pthread_mutex_init(&l_startupMutex, NULL); - - /* lock the startup mutex to block any active objects started before - * calling QF_run() - */ + // lock the startup mutex to block any active objects started before + // calling QF_run() pthread_mutex_lock(&l_startupMutex); - l_tick.tv_sec = 0; - l_tick.tv_nsec = NANOSLEEP_NSEC_PER_SEC/100L; /* default clock tick */ - l_tickPrio = sched_get_priority_min(SCHED_FIFO); /* default tick prio */ + // initialize the critical section mutex QF_critSectMutex_ as a + // *recursive mutex* in a portable way according to the POSIX Standard + pthread_mutexattr_t attr; + pthread_mutexattr_init(&attr); + pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); + pthread_mutex_init(&QF_critSectMutex_, &attr); + pthread_mutexattr_destroy(&attr); - /* install the SIGINT (Ctrl-C) signal handler */ + l_tick.tv_sec = 0; + l_tick.tv_nsec = NSEC_PER_SEC / DEFAULT_TICKS_PER_SEC; // default tick + l_tickPrio = sched_get_priority_min(SCHED_FIFO); // default ticker prio + + // install the SIGINT (Ctrl-C) signal handler + struct sigaction sig_act; memset(&sig_act, 0, sizeof(sig_act)); sig_act.sa_handler = &sigIntHandler; sigaction(SIGINT, &sig_act, NULL); } -/****************************************************************************/ +//............................................................................ void QF_enterCriticalSection_(void) { - pthread_mutex_lock(&QF_pThreadMutex_); + if (l_isRunning) { + pthread_mutex_lock(&QF_critSectMutex_); + } } -/****************************************************************************/ +//............................................................................ void QF_leaveCriticalSection_(void) { - pthread_mutex_unlock(&QF_pThreadMutex_); + if (l_isRunning) { + pthread_mutex_unlock(&QF_critSectMutex_); + } } +//............................................................................ +int QF_run(void) { -/****************************************************************************/ -int_t QF_run(void) { + QF_onStartup(); // application-specific startup callback + + // produce the QS_QF_RUN trace record + QS_BEGIN_PRE_(QS_QF_RUN, 0U) + QS_END_PRE_() + + // try to set the priority of the ticker thread, see NOTE01 struct sched_param sparam; - - QF_onStartup(); /* invoke startup callback */ - - /* produce the QS_QF_RUN trace record */ - QS_BEGIN_NOCRIT_PRE_(QS_QF_RUN, 0U) - QS_END_NOCRIT_PRE_() - - /* try to set the priority of the ticker thread, see NOTE01 */ sparam.sched_priority = l_tickPrio; if (pthread_setschedparam(pthread_self(), SCHED_FIFO, &sparam) == 0) { - /* success, this application has sufficient privileges */ + // success, this application has sufficient privileges } else { - /* setting priority failed, probably due to insufficient privieges */ + // setting priority failed, probably due to insufficient privileges } - /* unlock the startup mutex to unblock any active objects started before - * calling QF_run() - */ + // exit the startup critical section to unblock any active objects + // started before calling QF_run() pthread_mutex_unlock(&l_startupMutex); + // get the absolute monotonic time for no-drift sleeping + static struct timespec next_tick; + clock_gettime(CLOCK_MONOTONIC, &next_tick); + + // round down nanoseconds to the nearest configured period + next_tick.tv_nsec = (next_tick.tv_nsec / l_tick.tv_nsec) * l_tick.tv_nsec; + l_isRunning = true; - while (l_isRunning) { /* the clock tick loop... */ - QF_onClockTick(); /* callback (must call QTIMEEVT_TICK_X()) */ + while (l_isRunning) { // the clock tick loop... - nanosleep(&l_tick, NULL); /* sleep for the number of ticks, NOTE05 */ + // advance to the next tick (absolute time) + next_tick.tv_nsec += l_tick.tv_nsec; + if (next_tick.tv_nsec >= NSEC_PER_SEC) { + next_tick.tv_nsec -= NSEC_PER_SEC; + next_tick.tv_sec += 1; + } + + // sleep without drifting till next_time (absolute), see NOTE03 + if (clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, + &next_tick, NULL) == 0) // success? + { + // clock tick callback (must call QTIMEEVT_TICK_X()) + QF_onClockTick(); + } } - QF_onCleanup(); /* invoke cleanup callback */ - pthread_mutex_destroy(&l_startupMutex); - pthread_mutex_destroy(&QF_pThreadMutex_); + QF_onCleanup(); // cleanup callback + QS_EXIT(); // cleanup the QSPY connection - return 0; /* return success */ + pthread_mutex_destroy(&l_startupMutex); + pthread_mutex_destroy(&QF_critSectMutex_); + + return 0; // return success } -/*..........................................................................*/ -void QF_setTickRate(uint32_t ticksPerSec, int_t tickPrio) { - Q_REQUIRE_ID(300, ticksPerSec != 0U); - l_tick.tv_nsec = NANOSLEEP_NSEC_PER_SEC / ticksPerSec; +//............................................................................ +void QF_stop(void) { + l_isRunning = false; // terminate the main (ticker) thread +} +//............................................................................ +void QF_setTickRate(uint32_t ticksPerSec, int tickPrio) { + Q_REQUIRE_ID(600, ticksPerSec != 0U); + l_tick.tv_nsec = NSEC_PER_SEC / ticksPerSec; l_tickPrio = tickPrio; } -/*..........................................................................*/ -void QF_stop(void) { - l_isRunning = false; /* stop the loop in QF_run() */ -} -/*..........................................................................*/ +//............................................................................ void QF_consoleSetup(void) { - struct termios tio; /* modified terminal attributes */ + struct termios tio; // modified terminal attributes - tcgetattr(0, &l_tsav); /* save the current terminal attributes */ - tcgetattr(0, &tio); /* obtain the current terminal attributes */ - tio.c_lflag &= ~(ICANON | ECHO); /* disable the canonical mode & echo */ - tcsetattr(0, TCSANOW, &tio); /* set the new attributes */ + tcgetattr(0, &l_tsav); // save the current terminal attributes + tcgetattr(0, &tio); // obtain the current terminal attributes + tio.c_lflag &= ~(ICANON | ECHO); // disable the canonical mode & echo + tcsetattr(0, TCSANOW, &tio); // set the new attributes } -/*..........................................................................*/ +//............................................................................ void QF_consoleCleanup(void) { - tcsetattr(0, TCSANOW, &l_tsav); /* restore the saved attributes */ + tcsetattr(0, TCSANOW, &l_tsav); // restore the saved attributes } -/*..........................................................................*/ +//............................................................................ int QF_consoleGetKey(void) { int byteswaiting; ioctl(0, FIONREAD, &byteswaiting); @@ -176,73 +210,72 @@ int QF_consoleGetKey(void) { read(0, &ch, 1); return (int)ch; } - return 0; /* no input at this time */ + return 0; // no input at this time } -/*..........................................................................*/ +//............................................................................ int QF_consoleWaitForKey(void) { - return getchar(); + return (int)getchar(); } -/****************************************************************************/ -static void *thread_routine(void *arg) { /* the expected POSIX signature */ +//============================================================================ +static void *thread_routine(void *arg) { // the expected POSIX signature QActive *act = (QActive *)arg; - /* block this thread until the startup mutex is unlocked from QF_run() */ + // block this thread until the startup mutex is unlocked from QF_run() pthread_mutex_lock(&l_startupMutex); pthread_mutex_unlock(&l_startupMutex); -#ifdef QF_ACTIVE_STOP +#ifdef QACTIVE_CAN_STOP act->thread = true; while (act->thread) #else - for (;;) /* for-ever */ + for (;;) // for-ever #endif { - QEvt const *e = QActive_get_(act); /* wait for the event */ - QHSM_DISPATCH(&act->super, e, act->prio); /* dispatch to the HSM */ - QF_gc(e); /* check if the event is garbage, and collect it if so */ + QEvt const *e = QActive_get_(act); // wait for event + QASM_DISPATCH(&act->super, e, act->prio); // dispatch to the HSM + QF_gc(e); // check if the event is garbage, and collect it if so } -#ifdef QF_ACTIVE_STOP - QActive_unregister_(act); /* un-register this active object */ +#ifdef QACTIVE_CAN_STOP + QActive_unregister_(act); // un-register this active object #endif - return (void *)0; /* return success */ + return (void *)0; // return success } -/****************************************************************************/ +// QActive functions ======================================================= void QActive_start_(QActive * const me, QPrioSpec const prioSpec, QEvt const * * const qSto, uint_fast16_t const qLen, void * const stkSto, uint_fast16_t const stkSize, void const * const par) { - pthread_t thread; - pthread_attr_t attr; - struct sched_param param; - int err; + Q_UNUSED_PAR(stkSto); + Q_UNUSED_PAR(stkSize); - /* p-threads allocate stack internally */ - Q_REQUIRE_ID(600, stkSto == (void *)0); + // p-threads allocate stack internally + Q_REQUIRE_ID(800, stkSto == (void *)0); QEQueue_init(&me->eQueue, qSto, qLen); pthread_cond_init(&me->osObject, NULL); - me->prio = (uint8_t)(prioSpec & 0xFFU); /* QF-priority of the AO */ - me->pthre = (uint8_t)(prioSpec >> 8U); /* preemption-threshold */ - QActive_register_(me); /* register this AO */ + me->prio = (uint8_t)(prioSpec & 0xFFU); // QF-priority of the AO + me->pthre = 0U; // preemption-threshold (not used in this port) + QActive_register_(me); // register this AO - /* the top-most initial tran. (virtual) */ - QHSM_INIT(&me->super, par, me->prio); - QS_FLUSH(); /* flush the trace buffer to the host */ + // top-most initial tran. (virtual call) + (*me->super.vptr->init)(&me->super, par, me->prio); + QS_FLUSH(); // flush the trace buffer to the host + pthread_attr_t attr; pthread_attr_init(&attr); - /* SCHED_FIFO corresponds to real-time preemptive priority-based scheduler - * NOTE: This scheduling policy requires the superuser privileges - */ + // SCHED_FIFO corresponds to real-time preemptive priority-based scheduler + // NOTE: This scheduling policy requires the superuser privileges pthread_attr_setschedpolicy (&attr, SCHED_FIFO); pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED); pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED); - /* priority of the p-thread, see NOTE04 */ + // priority of the p-thread, see NOTE04 + struct sched_param param; param.sched_priority = me->prio + (sched_get_priority_max(SCHED_FIFO) - QF_MAX_ACTIVE - 3U); @@ -251,87 +284,67 @@ void QActive_start_(QActive * const me, QPrioSpec const prioSpec, pthread_attr_setstacksize(&attr, (stkSize < PTHREAD_STACK_MIN ? PTHREAD_STACK_MIN : stkSize)); - - err = pthread_create(&thread, &attr, &thread_routine, me); + pthread_t thread; + int err = pthread_create(&thread, &attr, &thread_routine, me); if (err != 0) { - /* Creating p-thread with the SCHED_FIFO policy failed. Most likely - * this application has no superuser privileges, so we just fall - * back to the default SCHED_OTHER policy and priority 0. - */ + // Creating p-thread with the SCHED_FIFO policy failed. Most likely + // this application has no superuser privileges, so we just fall + // back to the default SCHED_OTHER policy and priority 0. pthread_attr_setschedpolicy(&attr, SCHED_OTHER); param.sched_priority = 0; pthread_attr_setschedparam(&attr, ¶m); err = pthread_create(&thread, &attr, &thread_routine, me); } - Q_ASSERT_ID(610, err == 0); /* AO thread must be created */ + Q_ASSERT_ID(810, err == 0); // AO thread must be created //pthread_attr_getschedparam(&attr, ¶m); //printf("param.sched_priority==%d\n", param.sched_priority); pthread_attr_destroy(&attr); } -/*..........................................................................*/ -#ifdef QF_ACTIVE_STOP +//............................................................................ +#ifdef QACTIVE_CAN_STOP void QActive_stop(QActive * const me) { - QActive_unsubscribeAll(me); /* unsubscribe this AO from all events */ - me->thread = false; /* stop the thread loop (see thread_routine()) */ + QActive_unsubscribeAll(me); // unsubscribe this AO from all events + me->thread = false; // stop the thread loop (see thread_routine()) } #endif -/*..........................................................................*/ +//............................................................................ void QActive_setAttr(QActive *const me, uint32_t attr1, void const *attr2) { - (void)me; /* unused parameter */ - (void)attr1; /* unused parameter */ - (void)attr2; /* unused parameter */ - Q_ERROR_ID(900); /* this function should not be called in this QP port */ + Q_UNUSED_PAR(me); + Q_UNUSED_PAR(attr1); + Q_UNUSED_PAR(attr2); + Q_ERROR_INCRIT(900); // should not be called in this QP port } -/****************************************************************************/ -static void sigIntHandler(int dummy) { - (void)dummy; /* unused parameter */ - QF_onCleanup(); - exit(-1); -} - -/***************************************************************************** -* NOTE01: -* In Linux, the scheduler policy closest to real-time is the SCHED_FIFO -* policy, available only with superuser privileges. QF_run() attempts to set -* this policy as well as to maximize its priority, so that the ticking -* occurrs in the most timely manner (as close to an interrupt as possible). -* However, setting the SCHED_FIFO policy might fail, most probably due to -* insufficient privileges. -* -* NOTE02: -* On some Linux systems nanosleep() might actually not deliver the finest -* time granularity. For example, on some Linux implementations, nanosleep() -* could not block for shorter intervals than 20ms, while the underlying -* clock tick period was only 10ms. Sometimes, the select() system call can -* provide a finer granularity. -* -* NOTE03: -* Any blocking system call, such as nanosleep() or select() system call can -* be interrupted by a signal, such as ^C from the keyboard. In this case this -* QF port breaks out of the event-loop and returns to main() that exits and -* terminates all spawned p-threads. -* -* NOTE04: -* According to the man pages (for pthread_attr_setschedpolicy) the only value -* supported in the Linux p-threads implementation is PTHREAD_SCOPE_SYSTEM, -* meaning that the threads contend for CPU time with all processes running on -* the machine. In particular, thread priorities are interpreted relative to -* the priorities of all other processes on the machine. -* -* This is good, because it seems that if we set the priorities high enough, -* no other process (or thread running within) can gain control over the CPU. -* -* However, QF limits the number of priority levels to QF_MAX_ACTIVE. -* Assuming that a QF application will be real-time, this port reserves the -* three highest p-thread priorities for the ISR-like threads (e.g., I/O), -* and the rest highest-priorities for the active objects. -* -* NOTE05: -* In some (older) Linux kernels, the POSIX nanosleep() system call might -* deliver only 2*actual-system-tick granularity. To compensate for this, -* you would need to reduce the constant NANOSLEEP_NSEC_PER_SEC by factor 2. -*/ +//============================================================================ +// NOTE01: +// In Linux, the scheduler policy closest to real-time is the SCHED_FIFO +// policy, available only with superuser privileges. QF_run() attempts to set +// this policy as well as to maximize its priority, so that the ticking +// occurs in the most timely manner (as close to an interrupt as possible). +// However, setting the SCHED_FIFO policy might fail, most probably due to +// insufficient privileges. +// +// NOTE03: +// Any blocking system call, such as clock_nanosleep() system call can +// be interrupted by a signal, such as ^C from the keyboard. In this case this +// QF port breaks out of the event-loop and returns to main() that exits and +// terminates all spawned p-threads. +// +// NOTE04: +// According to the man pages (for pthread_attr_setschedpolicy) the only value +// supported in the Linux p-threads implementation is PTHREAD_SCOPE_SYSTEM, +// meaning that the threads contend for CPU time with all processes running on +// the machine. In particular, thread priorities are interpreted relative to +// the priorities of all other processes on the machine. +// +// This is good, because it seems that if we set the priorities high enough, +// no other process (or thread running within) can gain control over the CPU. +// +// However, QF limits the number of priority levels to QF_MAX_ACTIVE. +// Assuming that a QF application will be real-time, this port reserves the +// three highest p-thread priorities for the ISR-like threads (e.g., I/O), +// and the rest highest-priorities for the active objects. +// diff --git a/ports/posix/qf_port.h b/ports/posix/qf_port.h deleted file mode 100644 index ce99c5db..00000000 --- a/ports/posix/qf_port.h +++ /dev/null @@ -1,146 +0,0 @@ -/*============================================================================ -* QP/C Real-Time Embedded Framework (RTEF) -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2022-07-30 -* @version Last updated for: @ref qpc_7_0_1 -* -* @file -* @brief QF/C port to POSIX API (multi-threaded) -*/ -#ifndef QF_PORT_H -#define QF_PORT_H - -/* POSIX event queue and thread types */ -#define QF_EQUEUE_TYPE QEQueue -#define QF_OS_OBJECT_TYPE pthread_cond_t -#define QF_THREAD_TYPE bool - -/* The maximum number of active objects in the application */ -#define QF_MAX_ACTIVE 64U - -/* The number of system clock tick rates */ -#define QF_MAX_TICK_RATE 2U - -/* Activate the QF QActive_stop() API */ -#define QF_ACTIVE_STOP 1 - -/* various QF object sizes configuration for this port */ -#define QF_EVENT_SIZ_SIZE 4U -#define QF_EQUEUE_CTR_SIZE 4U -#define QF_MPOOL_SIZ_SIZE 4U -#define QF_MPOOL_CTR_SIZE 4U -#define QF_TIMEEVT_CTR_SIZE 4U - -/* QF critical section entry/exit for POSIX, see NOTE1 */ -/* QF_CRIT_STAT_TYPE not defined */ -#define QF_CRIT_ENTRY(dummy) QF_enterCriticalSection_() -#define QF_CRIT_EXIT(dummy) QF_leaveCriticalSection_() - -#include /* POSIX-thread API */ -#include "qep_port.h" /* QEP port */ -#include "qequeue.h" /* POSIX needs event-queue */ -#include "qmpool.h" /* POSIX needs memory-pool */ -#include "qf.h" /* QF platform-independent public interface */ - -void QF_enterCriticalSection_(void); -void QF_leaveCriticalSection_(void); - -/* set clock tick rate and p-thread priority */ -void QF_setTickRate(uint32_t ticksPerSec, int_t tickPrio); - -/* clock tick callback (NOTE not called when "ticker thread" is not running) */ -void QF_onClockTick(void); /* clock tick callback (provided in the app) */ - -/* abstractions for console access... */ -void QF_consoleSetup(void); -void QF_consoleCleanup(void); -int QF_consoleGetKey(void); -int QF_consoleWaitForKey(void); - -/****************************************************************************/ -/* interface used only inside QF implementation, but not in applications */ -#ifdef QP_IMPL - - /* QF-specific scheduler locking (not used at this point) */ - #define QF_SCHED_STAT_ - #define QF_SCHED_LOCK_(dummy) ((void)0) - #define QF_SCHED_UNLOCK_() ((void)0) - - /* POSIX active object event queue customization... */ - #define QACTIVE_EQUEUE_WAIT_(me_) \ - while ((me_)->eQueue.frontEvt == (QEvt *)0) \ - pthread_cond_wait(&(me_)->osObject, &QF_pThreadMutex_) - #define QACTIVE_EQUEUE_SIGNAL_(me_) \ - Q_ASSERT_ID(410, QActive_registry_[(me_)->prio] != (QActive *)0); \ - pthread_cond_signal(&(me_)->osObject) - - /* native QF event pool operations */ - #define QF_EPOOL_TYPE_ QMPool - #define QF_EPOOL_INIT_(p_, poolSto_, poolSize_, evtSize_) \ - (QMPool_init(&(p_), (poolSto_), (poolSize_), (evtSize_))) - #define QF_EPOOL_EVENT_SIZE_(p_) ((uint_fast16_t)(p_).blockSize) - #define QF_EPOOL_GET_(p_, e_, m_, qs_id_) \ - ((e_) = (QEvt *)QMPool_get(&(p_), (m_), (qs_id_))) - #define QF_EPOOL_PUT_(p_, e_, qs_id_) \ - (QMPool_put(&(p_), (e_), (qs_id_))) - - /* mutex for QF critical section */ - extern pthread_mutex_t QF_pThreadMutex_; - -#endif /* QP_IMPL */ - -/****************************************************************************/ -/* -* NOTE1: -* QF, like all real-time frameworks, needs to execute certain sections of -* code exclusively, meaning that only one thread can execute the code at -* the time. Such sections of code are called "critical sections" -* -* This port uses a pair of functions QF_enterCriticalSection_() / -* QF_leaveCriticalSection_() to enter/leave the cirtical section, -* respectively. -* -* These functions are implemented in the qf_port.c module, where they -* manipulate the file-scope POSIX mutex object QF_pThreadMutex_ -* to protect all critical sections. Using the single mutex for all crtical -* section guarantees that only one thread at a time can execute inside a -* critical section. This prevents race conditions and data corruption. -* -* Please note, however, that the POSIX mutex implementation behaves -* differently than interrupt disabling. A common POSIX mutex ensures -* that only one thread at a time can execute a critical section, but it -* does not guarantee that a context switch cannot occur within the -* critical section. In fact, such context switches probably will happen, -* but they should not cause concurrency hazards because the critical -* section eliminates all race conditionis. -* -* Unlinke simply disabling and enabling interrupts, the mutex approach is -* also subject to priority inversions. However, the p-thread mutex -* implementation, such as POSIX threads, should support the priority- -* inheritance protocol. -*/ - -#endif /* QF_PORT_H */ - diff --git a/ports/posix/qp_port.h b/ports/posix/qp_port.h new file mode 100644 index 00000000..ffe23623 --- /dev/null +++ b/ports/posix/qp_port.h @@ -0,0 +1,153 @@ +//============================================================================ +// QP/C Real-Time Embedded Framework (RTEF) +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC . +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +//============================================================================ +//! @date Last updated on: 2023-09-07 +//! @version Last updated for: @ref qpc_7_3_0 +//! +//! @file +//! @brief QP/C port to to POSIX (multithreaded with P-threads) + +#ifndef QP_PORT_H_ +#define QP_PORT_H_ + +#include // Exact-width types. WG14/N843 C99 Standard +#include // Boolean type. WG14/N843 C99 Standard +#include // POSIX-thread API + +#ifdef QP_CONFIG +#include "qp_config.h" // external QP configuration +#endif + +// no-return function specifier (C11 Standard) +#define Q_NORETURN _Noreturn void + +// QActive event queue and thread types for POSIX +#define QACTIVE_EQUEUE_TYPE QEQueue +#define QACTIVE_OS_OBJ_TYPE pthread_cond_t +#define QACTIVE_THREAD_TYPE bool + +// QF critical section for POSIX, see NOTE1 +#define QF_CRIT_STAT +#define QF_CRIT_ENTRY() QF_enterCriticalSection_() +#define QF_CRIT_EXIT() QF_leaveCriticalSection_() + +// QF_LOG2 not defined -- use the internal LOG2() implementation + +// internal functions for critical section management +void QF_enterCriticalSection_(void); +void QF_leaveCriticalSection_(void); + +// set clock tick rate and priority +void QF_setTickRate(uint32_t ticksPerSec, int tickPrio); + +// clock tick callback +void QF_onClockTick(void); + +// abstractions for console access... +void QF_consoleSetup(void); +void QF_consoleCleanup(void); +int QF_consoleGetKey(void); +int QF_consoleWaitForKey(void); + +// include files ------------------------------------------------------------- +#include "qequeue.h" // POSIX port needs the native event-queue +#include "qmpool.h" // POSIX port needs the native memory-pool +#include "qp.h" // QP platform-independent public interface + +//============================================================================ +// interface used only inside QF implementation, but not in applications + +#ifdef QP_IMPL + + // QF scheduler locking for POSIX (not used at this point, see NOTE2) + #define QF_SCHED_STAT_ + #define QF_SCHED_LOCK_(dummy) ((void)0) + #define QF_SCHED_UNLOCK_() ((void)0) + + // QF event queue customization for POSIX... + #define QACTIVE_EQUEUE_WAIT_(me_) \ + while ((me_)->eQueue.frontEvt == (QEvt *)0) \ + pthread_cond_wait(&(me_)->osObject, &QF_critSectMutex_) + + #define QACTIVE_EQUEUE_SIGNAL_(me_) \ + pthread_cond_signal(&(me_)->osObject) + + // native QF event pool operations + #define QF_EPOOL_TYPE_ QMPool + #define QF_EPOOL_INIT_(p_, poolSto_, poolSize_, evtSize_) \ + (QMPool_init(&(p_), (poolSto_), (poolSize_), (evtSize_))) + #define QF_EPOOL_EVENT_SIZE_(p_) ((uint_fast16_t)(p_).blockSize) + #define QF_EPOOL_GET_(p_, e_, m_, qs_id_) \ + ((e_) = (QEvt *)QMPool_get(&(p_), (m_), (qs_id_))) + #define QF_EPOOL_PUT_(p_, e_, qs_id_) \ + (QMPool_put(&(p_), (e_), (qs_id_))) + + // mutex for QF critical section + extern pthread_mutex_t QF_critSectMutex_; + +#endif // QP_IMPL + +//============================================================================ +// NOTE1: +// QP, like all real-time frameworks, needs to execute certain sections of +// code exclusively, meaning that only one thread can execute the code at +// the time. Such sections of code are called "critical sections". +// +// This port uses a pair of functions QF_enterCriticalSection_() / +// QF_leaveCriticalSection_() to enter/leave the critical section, +// respectively. +// +// These functions are implemented in the qf_port.c module, where they +// manipulate the file-scope POSIX mutex object QF_critSectMutex_ +// to protect all critical sections. Using the single mutex for all crtical +// section guarantees that only one thread at a time can execute inside a +// critical section. This prevents race conditions and data corruption. +// +// Please note, however, that the POSIX mutex implementation behaves +// differently than interrupt disabling. A common POSIX mutex ensures +// that only one thread at a time can execute a critical section, but it +// does not guarantee that a context switch cannot occur within the +// critical section. In fact, such context switches probably will happen, +// but they should not cause concurrency hazards because the critical +// section eliminates all race conditionis. +// +// Unlinke simply disabling and enabling interrupts, the mutex approach is +// also subject to priority inversions. However, the p-thread mutex +// implementation, such as POSIX threads, should support the priority- +// inheritance protocol. +// +// NOTE2: +// Scheduler locking (used inside QActive_publish_()) is NOT implemented +// in this port. This means that event multicasting is NOT atomic, so thread +// preemption CAN happen during that time. This can lead to (occasionally) +// unexpected event sequences. +// + +#endif // QP_PORT_H_ + diff --git a/ports/posix/qs_port.c b/ports/posix/qs_port.c index 259b516b..b58fd5c3 100644 --- a/ports/posix/qs_port.c +++ b/ports/posix/qs_port.c @@ -1,48 +1,47 @@ -/*============================================================================ -* QP/C Real-Time Embedded Framework (RTEF) -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2023-01-07 -* @version Last updated for: @ref qpc_7_2_0 -* -* @file -* @brief QS/C port to POSIX -*/ -/* expose features from the 2008 POSIX standard (IEEE Standard 1003.1-2008) */ +//============================================================================ +// QP/C Real-Time Embedded Framework (RTEF) +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +//============================================================================ +//! @date Last updated on: 2023-08-20 +//! @version Last updated for: @ref qpc_7_3_0 +//! +//! @file +//! @brief QS/C port to POSIX + +// expose features from the 2008 POSIX standard (IEEE Standard 1003.1-2008) #define _POSIX_C_SOURCE 200809L #ifndef Q_SPY #error "Q_SPY must be defined to compile qs_port.c" -#endif /* Q_SPY */ +#endif // Q_SPY -#define QP_IMPL /* this is QP implementation */ -#include "qf_port.h" /* QF port */ -#include "qassert.h" /* QP embedded systems-friendly assertions */ -#include "qs_port.h" /* QS port */ -#include "qs_pkg.h" /* QS package-scope interface */ +#define QP_IMPL // this is QP implementation +#include "qp_port.h" // QP port +#include "qsafe.h" // QP Functional Safety (FuSa) System +#include "qs_port.h" // QS port +#include "qs_pkg.h" // QS package-scope interface -#include "safe_std.h" /* portable "safe" / facilities */ +#include "safe_std.h" // portable "safe" / facilities #include #include #include @@ -53,26 +52,31 @@ #include #include -/*Q_DEFINE_THIS_MODULE("qs_port")*/ +//Q_DEFINE_THIS_MODULE("qs_port") #define QS_TX_SIZE (8*1024) #define QS_RX_SIZE (2*1024) #define QS_TX_CHUNK QS_TX_SIZE -#define QS_TIMEOUT_MS 10 +#define QS_TIMEOUT_MS 10L #define INVALID_SOCKET -1 #define SOCKET_ERROR -1 -/* local variables .........................................................*/ +// local variables ......................................................... static int l_sock = INVALID_SOCKET; static struct timespec const c_timeout = { 0, QS_TIMEOUT_MS*1000000L }; -/*..........................................................................*/ +//............................................................................ uint8_t QS_onStartup(void const *arg) { - static uint8_t qsBuf[QS_TX_SIZE]; /* buffer for QS-TX channel */ - static uint8_t qsRxBuf[QS_RX_SIZE]; /* buffer for QS-RX channel */ + + static uint8_t qsBuf[QS_TX_SIZE]; // buffer for QS-TX channel + QS_initBuf(qsBuf, sizeof(qsBuf)); + + static uint8_t qsRxBuf[QS_RX_SIZE]; // buffer for QS-RX channel + QS_rxInitBuf(qsRxBuf, sizeof(qsRxBuf)); + char hostName[128]; - char const *serviceName = "6601"; /* default QSPY server port */ + char const *serviceName = "6601"; // default QSPY server port char const *src; char *dst; int status; @@ -82,14 +86,10 @@ uint8_t QS_onStartup(void const *arg) { struct addrinfo hints; int sockopt_bool; - /* initialize the QS transmit and receive buffers */ - QS_initBuf(qsBuf, sizeof(qsBuf)); - QS_rxInitBuf(qsRxBuf, sizeof(qsRxBuf)); - - /* extract hostName from 'arg' (hostName:port_remote)... */ + // extract hostName from 'arg' (hostName:port_remote)... src = (arg != (void *)0) ? (char const *)arg - : "localhost"; /* default QSPY host */ + : "localhost"; // default QSPY host dst = hostName; while ((*src != '\0') && (*src != ':') @@ -97,9 +97,9 @@ uint8_t QS_onStartup(void const *arg) { { *dst++ = *src++; } - *dst = '\0'; /* zero-terminate hostName */ + *dst = '\0'; // zero-terminate hostName - /* extract serviceName from 'arg' (hostName:serviceName)... */ + // extract serviceName from 'arg' (hostName:serviceName)... if (*src == ':') { serviceName = src + 1; } @@ -131,7 +131,7 @@ uint8_t QS_onStartup(void const *arg) { freeaddrinfo(result); - /* socket could not be opened & connected? */ + // socket could not be opened & connected? if (l_sock == INVALID_SOCKET) { FPRINTF_S(stderr, " ERROR cannot connect to QSPY at " "host=%s:%s\n", @@ -139,7 +139,7 @@ uint8_t QS_onStartup(void const *arg) { goto error; } - /* set the socket to non-blocking mode */ + // set the socket to non-blocking mode status = fcntl(l_sock, F_GETFL, 0); if (status == -1) { FPRINTF_S(stderr, @@ -155,143 +155,143 @@ uint8_t QS_onStartup(void const *arg) { goto error; } - /* configure the socket to reuse the address and not to linger */ + // configure the socket to reuse the address and not to linger sockopt_bool = 1; setsockopt(l_sock, SOL_SOCKET, SO_REUSEADDR, &sockopt_bool, sizeof(sockopt_bool)); - sockopt_bool = 0; /* negative option */ + sockopt_bool = 0; // negative option setsockopt(l_sock, SOL_SOCKET, SO_LINGER, &sockopt_bool, sizeof(sockopt_bool)); QS_onFlush(); - return 1U; /* success */ + return 1U; // success error: - return 0U; /* failure */ + return 0U; // failure } -/*..........................................................................*/ +//............................................................................ void QS_onCleanup(void) { + static struct timespec const c_timeout = {0, 10L*QS_TIMEOUT_MS*1000000L }; + nanosleep(&c_timeout, NULL); // allow the last QS output to come out if (l_sock != INVALID_SOCKET) { close(l_sock); l_sock = INVALID_SOCKET; } - /*PRINTF_S(" Disconnected from QSPY\n");*/ + //PRINTF_S("%s\n", " Disconnected from QSPY"); } -/*..........................................................................*/ +//............................................................................ void QS_onReset(void) { QS_onCleanup(); + //PRINTF_S("\n%s\n", "QS_onReset"); exit(0); } -/*..........................................................................*/ +//............................................................................ void QS_onFlush(void) { - uint16_t nBytes; - uint8_t const *data; - QS_CRIT_STAT_ - - if (l_sock == INVALID_SOCKET) { /* socket NOT initialized? */ - FPRINTF_S(stderr, " ERROR %s\n", "invalid TCP socket"); + if (l_sock == INVALID_SOCKET) { // socket NOT initialized? + FPRINTF_S(stderr, " ERROR %s\n", + "invalid TCP socket"); + QF_stop(); // <== stop and exit the application return; } - nBytes = QS_TX_CHUNK; - QS_CRIT_E_(); + QS_CRIT_STAT + QS_CRIT_ENTRY(); + uint16_t nBytes = QS_TX_CHUNK; + uint8_t const *data; while ((data = QS_getBlock(&nBytes)) != (uint8_t *)0) { - QS_CRIT_X_(); - for (;;) { /* for-ever until break or return */ + QS_CRIT_EXIT(); + for (;;) { // for-ever until break or return int nSent = send(l_sock, (char const *)data, (int)nBytes, 0); - if (nSent == SOCKET_ERROR) { /* sending failed? */ + if (nSent == SOCKET_ERROR) { // sending failed? if ((errno == EWOULDBLOCK) || (errno == EAGAIN)) { - /* sleep for the timeout and then loop back - * to send() the SAME data again - */ + // sleep for the timeout and then loop back + // to send() the SAME data again nanosleep(&c_timeout, NULL); } - else { /* some other socket error... */ + else { // some other socket error... FPRINTF_S(stderr, " ERROR sending data over TCP," "errno=%d\n", errno); + QF_stop(); // <== stop and exit the application return; } } - else if (nSent < (int)nBytes) { /* sent fewer than requested? */ - nanosleep(&c_timeout, NULL); /* sleep for the timeout */ - /* adjust the data and loop back to send() the rest */ + else if (nSent < (int)nBytes) { // sent fewer than requested? + nanosleep(&c_timeout, NULL); // sleep for the timeout + // adjust the data and loop back to send() the rest data += nSent; nBytes -= (uint16_t)nSent; } else { - break; + break; // break out of the for-ever loop } } - /* set nBytes for the next call to QS_getBlock() */ + // set nBytes for the next call to QS_getBlock() nBytes = QS_TX_CHUNK; - QS_CRIT_E_(); + QS_CRIT_ENTRY(); } - QS_CRIT_X_(); + QS_CRIT_EXIT(); } -/*..........................................................................*/ +//............................................................................ QSTimeCtr QS_onGetTime(void) { struct timespec tspec; - QSTimeCtr time; clock_gettime(CLOCK_MONOTONIC_RAW, &tspec); - /* convert to units of 0.1 microsecond */ - time = (QSTimeCtr)(tspec.tv_sec * 10000000 + tspec.tv_nsec / 100); + // convert to units of 0.1 microsecond + QSTimeCtr time = (QSTimeCtr)(tspec.tv_sec * 10000000 + tspec.tv_nsec / 100); return time; } -/*..........................................................................*/ +//............................................................................ void QS_output(void) { - uint16_t nBytes; - uint8_t const *data; - QS_CRIT_STAT_ - - if (l_sock == INVALID_SOCKET) { /* socket NOT initialized? */ - FPRINTF_S(stderr, " ERROR %s\n", "invalid TCP socket"); + if (l_sock == INVALID_SOCKET) { // socket NOT initialized? + FPRINTF_S(stderr, " ERROR %s\n", + "invalid TCP socket"); + QF_stop(); // <== stop and exit the application return; } - nBytes = QS_TX_CHUNK; - QS_CRIT_E_(); - if ((data = QS_getBlock(&nBytes)) != (uint8_t *)0) { - QS_CRIT_X_(); - for (;;) { /* for-ever until break or return */ + QS_CRIT_STAT + QS_CRIT_ENTRY(); + uint16_t nBytes = QS_TX_CHUNK; + uint8_t const *data = QS_getBlock(&nBytes); + QS_CRIT_EXIT(); + + if (nBytes > 0U) { // any bytes to send? + for (;;) { // for-ever until break or return int nSent = send(l_sock, (char const *)data, (int)nBytes, 0); - if (nSent == SOCKET_ERROR) { /* sending failed? */ + if (nSent == SOCKET_ERROR) { // sending failed? if ((errno == EWOULDBLOCK) || (errno == EAGAIN)) { - /* sleep for the timeout and then loop back - * to send() the SAME data again - */ + // sleep for the timeout and then loop back + // to send() the SAME data again nanosleep(&c_timeout, NULL); } - else { /* some other socket error... */ + else { // some other socket error... FPRINTF_S(stderr, " ERROR sending data over TCP," "errno=%d\n", errno); + QF_stop(); // <== stop and exit the application return; } } - else if (nSent < (int)nBytes) { /* sent fewer than requested? */ - nanosleep(&c_timeout, NULL); /* sleep for the timeout */ - /* adjust the data and loop back to send() the rest */ + else if (nSent < (int)nBytes) { // sent fewer than requested? + nanosleep(&c_timeout, NULL); // sleep for the timeout + // adjust the data and loop back to send() the rest data += nSent; nBytes -= (uint16_t)nSent; } else { - break; + break; // break out of the for-ever loop } } } - else { - QS_CRIT_X_(); - } } -/*..........................................................................*/ +//............................................................................ void QS_rx_input(void) { int status = recv(l_sock, (char *)QS_rxPriv_.buf, (int)QS_rxPriv_.end, 0); - if (status > 0) { /* any data received? */ + if (status > 0) { // any data received? QS_rxPriv_.tail = 0U; - QS_rxPriv_.head = status; /* # bytes received */ - QS_rxParse(); /* parse all received bytes */ + QS_rxPriv_.head = status; // # bytes received + QS_rxParse(); // parse all received bytes } } diff --git a/ports/posix/qs_port.h b/ports/posix/qs_port.h index 70e917bd..79c8e010 100644 --- a/ports/posix/qs_port.h +++ b/ports/posix/qs_port.h @@ -1,63 +1,61 @@ -/*============================================================================ -* QP/C Real-Time Embedded Framework (RTEF) -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2023-01-07 -* @version Last updated for: @ref qpc_7_2_0 -* -* @file -* @brief QS/C port to POSIX with GNU compiler -*/ -#ifndef QS_PORT_H -#define QS_PORT_H +//============================================================================ +// QP/C Real-Time Embedded Framework (RTEF) +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +//============================================================================ +//! @date Last updated on: 2023-08-19 +//! @version Last updated for: @ref qpc_7_3_0 +//! +//! @file +//! @brief QS/C port to POSIX with GNU + +#ifndef QS_PORT_H_ +#define QS_PORT_H_ #define QS_CTR_SIZE 4U #define QS_TIME_SIZE 4U -#if defined(__LP64__) || defined(_LP64) /* 64-bit architecture? */ +#if defined(__LP64__) || defined(_LP64) // 64-bit architecture? #define QS_OBJ_PTR_SIZE 8U #define QS_FUN_PTR_SIZE 8U -#else /* 32-bit architecture */ +#else // 32-bit architecture #define QS_OBJ_PTR_SIZE 4U #define QS_FUN_PTR_SIZE 4U #endif -void QS_output(void); /* handle the QS output */ -void QS_rx_input(void); /* handle the QS-RX input */ +void QS_output(void); // handle the QS output +void QS_rx_input(void); // handle the QS-RX input -/*==========================================================================*/ -/* NOTE: QS might be used with or without other QP components, in which -* case the separate definitions of the macros QF_CRIT_STAT_TYPE, -* QF_CRIT_ENTRY, and QF_CRIT_EXIT are needed. In this port QS is configured -* to be used with the other QP component, by simply including "qf_port.h" -* *before* "qs.h". -*/ -#ifndef QF_PORT_H -#include "qf_port.h" /* use QS with QF */ +//============================================================================ +// NOTE: QS might be used with or without other QP components, in which +// case the separate definitions of the macros QF_CRIT_STAT, QF_CRIT_ENTRY(), +// and QF_CRIT_EXIT() are needed. In this port QS is configured to be used +// with the other QP component, by simply including "qp_port.h" +//*before* "qs.h". +#ifndef QP_PORT_H_ +#include "qp_port.h" // use QS with QP #endif -#include "qs.h" /* QS platform-independent public interface */ +#include "qs.h" // QS platform-independent public interface -#endif /* QS_PORT_H */ +#endif // QS_PORT_H_ diff --git a/ports/posix/safe_std.h b/ports/posix/safe_std.h index 7e0a2439..c752662c 100644 --- a/ports/posix/safe_std.h +++ b/ports/posix/safe_std.h @@ -1,42 +1,40 @@ -/*============================================================================ -* QP/C Real-Time Embedded Framework (RTEF) -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2022-07-30 -* @version Last updated for: @ref qpc_7_0_1 -* -* @file -* @brief "safe" and facilities -*/ +//============================================================================ +// QP/C Real-Time Embedded Framework (RTEF) +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +//============================================================================ +//! @date Last updated on: 2022-07-30 +//! @version Last updated for: @ref qpc_7_1_3 +//! +//! @file +//! @brief "safe" and facilities #ifndef SAFE_STD_H #define SAFE_STD_H #include #include -/* portable "safe" facilities from and ................*/ -#ifdef _WIN32 /* Windows OS? */ +// portable "safe" facilities from and ................ +#ifdef _WIN32 // Windows OS? #define MEMMOVE_S(dest_, num_, src_, count_) \ memmove_s(dest_, num_, src_, count_) @@ -48,13 +46,13 @@ strcat_s(dest_, destsiz_, src_) #define SNPRINTF_S(buf_, bufsiz_, format_, ...) \ - _snprintf_s(buf_, bufsiz_, _TRUNCATE, format_, ##__VA_ARGS__) + _snprintf_s(buf_, bufsiz_, _TRUNCATE, format_, __VA_ARGS__) #define PRINTF_S(format_, ...) \ - printf_s(format_, ##__VA_ARGS__) + printf_s(format_, __VA_ARGS__) #define FPRINTF_S(fp_, format_, ...) \ - fprintf_s(fp_, format_, ##__VA_ARGS__) + fprintf_s(fp_, format_, __VA_ARGS__) #ifdef _MSC_VER #define FREAD_S(buf_, bufsiz_, elsiz_, count_, fp_) \ @@ -62,7 +60,7 @@ #else #define FREAD_S(buf_, bufsiz_, elsiz_, count_, fp_) \ fread(buf_, elsiz_, count_, fp_) -#endif /* _MSC_VER */ +#endif // _MSC_VER #define FOPEN_S(fp_, fName_, mode_) \ if (fopen_s(&fp_, fName_, mode_) != 0) { \ @@ -72,7 +70,7 @@ if (fopen_s(&fp_, fName_, mode_) != 0) { \ #define LOCALTIME_S(tm_, time_) \ localtime_s(tm_, time_) -#else /* other OS (Linux, MacOS, etc.) .....................................*/ +#else // other OS (Linux, MacOS, etc.) ..................................... #define MEMMOVE_S(dest_, num_, src_, count_) \ memmove(dest_, src_, count_) @@ -86,13 +84,13 @@ if (fopen_s(&fp_, fName_, mode_) != 0) { \ strcat(dest_, src_) #define SNPRINTF_S(buf_, bufsiz_, format_, ...) \ - snprintf(buf_, bufsiz_, format_, ##__VA_ARGS__) + snprintf(buf_, bufsiz_, format_, __VA_ARGS__) #define PRINTF_S(format_, ...) \ - printf(format_, ##__VA_ARGS__) + printf(format_, __VA_ARGS__) #define FPRINTF_S(fp_, format_, ...) \ - fprintf(fp_, format_, ##__VA_ARGS__) + fprintf(fp_, format_, __VA_ARGS__) #define FREAD_S(buf_, bufsiz_, elsiz_, count_, fp_) \ fread(buf_, elsiz_, count_, fp_) @@ -103,6 +101,6 @@ if (fopen_s(&fp_, fName_, mode_) != 0) { \ #define LOCALTIME_S(tm_, time_) \ memcpy(tm_, localtime(time_), sizeof(struct tm)) -#endif /* _WIN32 */ +#endif // _WIN32 -#endif /* SAFE_STD_H */ +#endif // SAFE_STD_H diff --git a/ports/qep-only/qp_port.h b/ports/qep-only/qp_port.h new file mode 100644 index 00000000..450e5aa0 --- /dev/null +++ b/ports/qep-only/qp_port.h @@ -0,0 +1,62 @@ +//============================================================================ +// QP/C Real-Time Embedded Framework (RTEF) +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC . +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +//============================================================================ +//! @date Last updated on: 2023-09-07 +//! @version Last updated for: @ref qpc_7_3_0 +//! +//! @file +//! @brief QP/C dummy port + +#ifndef QP_PORT_H_ +#define QP_PORT_H_ + +#include // Exact-width types. WG14/N843 C99 Standard +#include // Boolean type. WG14/N843 C99 Standard + +#ifdef QP_CONFIG +#include "qp_config.h" // external QP configuration +#endif + +// no-return function specifier (C11 Standard) +#define Q_NORETURN _Noreturn void + +#define QF_MAX_EPOOL 0U + +#define QF_CRIT_STAT +#define QF_CRIT_ENTRY() ((void)0) +#define QF_CRIT_EXIT() ((void)0) + +#define QF_MEM_SYS() ((void)0) +#define QF_MEM_APP() ((void)0) + +// include files ------------------------------------------------------------- +#include "qp.h" // QP platform-independent public interface + +#endif // QP_PORT_H_ + diff --git a/ports/qep-only/safe_std.h b/ports/qep-only/safe_std.h new file mode 100644 index 00000000..c752662c --- /dev/null +++ b/ports/qep-only/safe_std.h @@ -0,0 +1,106 @@ +//============================================================================ +// QP/C Real-Time Embedded Framework (RTEF) +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +//============================================================================ +//! @date Last updated on: 2022-07-30 +//! @version Last updated for: @ref qpc_7_1_3 +//! +//! @file +//! @brief "safe" and facilities +#ifndef SAFE_STD_H +#define SAFE_STD_H + +#include +#include + +// portable "safe" facilities from and ................ +#ifdef _WIN32 // Windows OS? + +#define MEMMOVE_S(dest_, num_, src_, count_) \ + memmove_s(dest_, num_, src_, count_) + +#define STRNCPY_S(dest_, destsiz_, src_) \ + strncpy_s(dest_, destsiz_, src_, _TRUNCATE) + +#define STRCAT_S(dest_, destsiz_, src_) \ + strcat_s(dest_, destsiz_, src_) + +#define SNPRINTF_S(buf_, bufsiz_, format_, ...) \ + _snprintf_s(buf_, bufsiz_, _TRUNCATE, format_, __VA_ARGS__) + +#define PRINTF_S(format_, ...) \ + printf_s(format_, __VA_ARGS__) + +#define FPRINTF_S(fp_, format_, ...) \ + fprintf_s(fp_, format_, __VA_ARGS__) + +#ifdef _MSC_VER +#define FREAD_S(buf_, bufsiz_, elsiz_, count_, fp_) \ + fread_s(buf_, bufsiz_, elsiz_, count_, fp_) +#else +#define FREAD_S(buf_, bufsiz_, elsiz_, count_, fp_) \ + fread(buf_, elsiz_, count_, fp_) +#endif // _MSC_VER + +#define FOPEN_S(fp_, fName_, mode_) \ +if (fopen_s(&fp_, fName_, mode_) != 0) { \ + fp_ = (FILE *)0; \ +} else (void)0 + +#define LOCALTIME_S(tm_, time_) \ + localtime_s(tm_, time_) + +#else // other OS (Linux, MacOS, etc.) ..................................... + +#define MEMMOVE_S(dest_, num_, src_, count_) \ + memmove(dest_, src_, count_) + +#define STRNCPY_S(dest_, destsiz_, src_) do { \ + strncpy(dest_, src_, destsiz_); \ + dest_[(destsiz_) - 1] = '\0'; \ +} while (false) + +#define STRCAT_S(dest_, destsiz_, src_) \ + strcat(dest_, src_) + +#define SNPRINTF_S(buf_, bufsiz_, format_, ...) \ + snprintf(buf_, bufsiz_, format_, __VA_ARGS__) + +#define PRINTF_S(format_, ...) \ + printf(format_, __VA_ARGS__) + +#define FPRINTF_S(fp_, format_, ...) \ + fprintf(fp_, format_, __VA_ARGS__) + +#define FREAD_S(buf_, bufsiz_, elsiz_, count_, fp_) \ + fread(buf_, elsiz_, count_, fp_) + +#define FOPEN_S(fp_, fName_, mode_) \ + (fp_ = fopen(fName_, mode_)) + +#define LOCALTIME_S(tm_, time_) \ + memcpy(tm_, localtime(time_), sizeof(struct tm)) + +#endif // _WIN32 + +#endif // SAFE_STD_H diff --git a/ports/qube/qep_port.h b/ports/qube/qep_port.h deleted file mode 100644 index 071d8d7a..00000000 --- a/ports/qube/qep_port.h +++ /dev/null @@ -1,70 +0,0 @@ -/*============================================================================ -* QP/C Real-Time Embedded Framework (RTEF) -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2023-01-07 -* @version Last updated for: @ref qpc_7_2_0 -* -* @file -* @brief QEP/C port for the "Qube" execution harness (Windows, Linux, macOS) -*/ -#ifndef QEP_PORT_H_ -#define QEP_PORT_H_ - -#include /* Exact-width types. WG14/N843 C99 Standard */ -#include /* Boolean type. WG14/N843 C99 Standard */ - -#ifdef __GNUC__ -/*! no-return function specifier (C11 Standard) */ -#define Q_NORETURN _Noreturn void -#elif (defined _MSC_VER) && (defined __cplusplus) - - /* no-return function specifier (Microsoft Visual Studio C++ compiler) */ - #define Q_NORETURN [[ noreturn ]] void - - /* - * This is the case where QP/C is compiled by the Microsoft Visual C++ - * compiler in the C++ mode, which can happen when qep_port.h is included - * in a C++ module, or the compilation is forced to C++ by the option /TP. - * - * The following pragma suppresses the level-4 C++ warnings C4510, C4512, - * and C4610, which warn that default constructors and assignment operators - * could not be generated for structures QMState and QMTranActTable. - * - * The QP/C source code cannot be changed to avoid these C++ warnings - * because the structures QMState and QMTranActTable must remain PODs - * (Plain Old Datatypes) to be initializable statically with constant - * initializers. - */ - #pragma warning (disable: 4510 4512 4610) - -#endif - -#include "qep.h" /* QEP platform-independent public interface */ - -#if (defined __cplusplus) && (defined _MSC_VER) - #pragma warning (default: 4510 4512 4610) -#endif - -#endif /* QEP_PORT_H_ */ diff --git a/ports/qube/qf_port.h b/ports/qube/qf_port.h deleted file mode 100644 index ea21c545..00000000 --- a/ports/qube/qf_port.h +++ /dev/null @@ -1,91 +0,0 @@ -/*============================================================================ -* QP/C Real-Time Embedded Framework (RTEF) -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2023-01-07 -* @version Last updated for: @ref qpc_7_2_0 -* -* @file -* @brief QF/C port for the "Qube" execution harness (Windows, Linux, macOS) -*/ -#ifndef QF_PORT_H -#define QF_PORT_H - -/* Qube event queue and thread types */ -#define QF_EQUEUE_TYPE QEQueue -/* QF_OS_OBJECT_TYPE not used */ -/* QF_THREAD_TYPE not used */ - -/* The maximum number of active objects in the application */ -#define QF_MAX_ACTIVE 64U - -/* QF interrupt disable/enable */ -#define QF_INT_DISABLE() (++QF_intLock_) -#define QF_INT_ENABLE() (--QF_intLock_) - -/* Qube critical section */ -/* QF_CRIT_STAT_TYPE not defined */ -#define QF_CRIT_ENTRY(dummy) QF_INT_DISABLE() -#define QF_CRIT_EXIT(dummy) QF_INT_ENABLE() - -/* QF_LOG2 not defined -- use the internal LOG2() implementation */ - -#include "qep_port.h" /* QEP port */ -#include "qequeue.h" /* Qube port uses QEQueue event-queue */ -#include "qmpool.h" /* Qube port uses QMPool memory-pool */ -#include "qf.h" /* QF platform-independent public interface */ - -void Qube_setAO(QActive *ao); -QEvt const *Qube_onGenEvt(QSignal sig, char const *params); - -/*==========================================================================*/ -/* interface used only inside QF implementation, but not in applications */ -#ifdef QP_IMPL - - /* Qube scheduler locking (not used) */ - #define QF_SCHED_STAT_ - #define QF_SCHED_LOCK_(dummy) ((void)0) - #define QF_SCHED_UNLOCK_() ((void)0) - - /* native event queue operations */ - #define QACTIVE_EQUEUE_WAIT_(me_) \ - Q_ASSERT_ID(110, (me_)->eQueue.frontEvt != (QEvt *)0) - #define QACTIVE_EQUEUE_SIGNAL_(me_) \ - QPSet_insert(&QF_readySet_, (uint_fast8_t)(me_)->prio) - - /* native QF event pool operations */ - #define QF_EPOOL_TYPE_ QMPool - #define QF_EPOOL_INIT_(p_, poolSto_, poolSize_, evtSize_) \ - (QMPool_init(&(p_), (poolSto_), (poolSize_), (evtSize_))) - #define QF_EPOOL_EVENT_SIZE_(p_) ((uint_fast16_t)(p_).blockSize) - #define QF_EPOOL_GET_(p_, e_, m_, qs_id_) \ - ((e_) = (QEvt *)QMPool_get(&(p_), (m_), (qs_id_))) - #define QF_EPOOL_PUT_(p_, e_, qs_id_) \ - (QMPool_put(&(p_), (e_), (qs_id_))) - - #include "qf_pkg.h" /* internal QF interface */ - -#endif /* QP_IMPL */ - -#endif /* QF_PORT_H */ diff --git a/ports/qube/qp_port.h b/ports/qube/qp_port.h new file mode 100644 index 00000000..06b88cfe --- /dev/null +++ b/ports/qube/qp_port.h @@ -0,0 +1,112 @@ +//============================================================================ +// QP/C Real-Time Embedded Framework (RTEF) +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC . +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +//============================================================================ +//! @date Last updated on: 2023-09-07 +//! @version Last updated for: @ref qpc_7_3_0 +//! +//! @file +//! @brief QP/C port for the "Qube" execution harness (Windows, Linux, macOS) + +#ifndef QP_PORT_H_ +#define QP_PORT_H_ + +#include // Exact-width types. WG14/N843 C99 Standard +#include // Boolean type. WG14/N843 C99 Standard + +#ifdef QP_CONFIG +#include "qp_config.h" // external QP configuration +#endif + +// no-return function specifier (C11 Standard) +#define Q_NORETURN _Noreturn void + +// Qube event queue and thread types +#define QACTIVE_EQUEUE_TYPE QEQueue +#define QACTIVE_OS_OBJ_TYPE void * +#define QACTIVE_THREAD_TYPE void const * + +// QF interrupt disable/enable +#define QF_INT_DISABLE() (++QF_intLock_) +#define QF_INT_ENABLE() (--QF_intLock_) + +// Qube critical section +#define QF_CRIT_STAT +#define QF_CRIT_ENTRY() QF_INT_DISABLE() +#define QF_CRIT_EXIT() QF_INT_ENABLE() + +// QF_LOG2 not defined -- use the internal LOG2() implementation + +// include files ------------------------------------------------------------- +#include "qequeue.h" // Qube port uses QEQueue event-queue +#include "qmpool.h" // Qube port uses QMPool memory-pool +#include "qp.h" // QP platform-independent public interface + +void Qube_setAO(QActive *ao); +QEvt const *Qube_onGenEvt(QSignal sig, char const *params); +extern uint_fast8_t QF_intLock_; + +//========================================================================== +// interface used only inside QF implementation, but not in applications +#ifdef QP_IMPL + + extern QPSet QF_readySet_; + extern QPSet QF_readySet_dis_; + + // Qube scheduler locking (not used) + #define QF_SCHED_STAT_ + #define QF_SCHED_LOCK_(dummy) ((void)0) + #define QF_SCHED_UNLOCK_() ((void)0) + + // native event queue operations + #define QACTIVE_EQUEUE_WAIT_(me_) \ + Q_ASSERT_INCRIT(302, (me_)->eQueue.frontEvt != (QEvt *)0) +#ifndef Q_UNSAFE + #define QACTIVE_EQUEUE_SIGNAL_(me_) \ + QPSet_insert(&QF_readySet_, (uint_fast8_t)(me_)->prio); \ + QPSet_update_(&QF_readySet_, &QF_readySet_dis_) +#else + #define QACTIVE_EQUEUE_SIGNAL_(me_) \ + QPSet_insert(&QF_readySet_, (uint_fast8_t)(me_)->prio) +#endif + + // native QF event pool operations + #define QF_EPOOL_TYPE_ QMPool + #define QF_EPOOL_INIT_(p_, poolSto_, poolSize_, evtSize_) \ + (QMPool_init(&(p_), (poolSto_), (poolSize_), (evtSize_))) + #define QF_EPOOL_EVENT_SIZE_(p_) ((uint_fast16_t)(p_).blockSize) + #define QF_EPOOL_GET_(p_, e_, m_, qs_id_) \ + ((e_) = (QEvt *)QMPool_get(&(p_), (m_), (qs_id_))) + #define QF_EPOOL_PUT_(p_, e_, qs_id_) \ + (QMPool_put(&(p_), (e_), (qs_id_))) + + #include "qp_pkg.h" // internal QP interface + +#endif // QP_IMPL + +#endif // QP_PORT_H_ diff --git a/ports/qube/qs_port.h b/ports/qube/qs_port.h index 3d8b2112..1f081fef 100644 --- a/ports/qube/qs_port.h +++ b/ports/qube/qs_port.h @@ -1,64 +1,62 @@ -/*============================================================================ -* QP/C Real-Time Embedded Framework (RTEF) -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2023-01-04 -* @version Last updated for: @ref qpc_7_2.0 -* -* @file -* @brief QS/C port for the "Qube" execution harness (Windows, Linux, macOS) -*/ +//============================================================================ +// QP/C Real-Time Embedded Framework (RTEF) +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +//============================================================================ +//! @date Last updated on: 2023-08-16 +//! @version Last updated for: @ref qpc_7_3_0 +//! +//! @file +//! @brief QS/C port for the "Qube" execution harness (Windows, Linux, macOS) + #ifndef QS_PORT_H_ #define QS_PORT_H_ #define QS_CTR_SIZE 4U #define QS_TIME_SIZE 4U -/* 64-bit architecture? */ +// 64-bit architecture? #if defined(__LP64__) || defined(_LP64) || defined(_WIN64) #define QS_OBJ_PTR_SIZE 8U #define QS_FUN_PTR_SIZE 8U -#else /* 32-bit architecture */ +#else // 32-bit architecture #define QS_OBJ_PTR_SIZE 4U #define QS_FUN_PTR_SIZE 4U #endif -/* flush the QS output buffer after each QS record */ +// flush the QS output buffer after each QS record #define QS_REC_DONE() QS_onFlush() -/*============================================================================ -* NOTE: QS might be used with or without other QP components, in which -* case the separate definitions of the macros QF_CRIT_STAT_TYPE, -* QF_CRIT_ENTRY, and QF_CRIT_EXIT are needed. In this port QS is configured -* to be used with the other QP component, by simply including "qf_port.h" -* *before* "qs.h". -*/ -#ifndef QF_PORT_H -#include "qf_port.h" /* use QS with QF */ +//============================================================================ +// NOTE: QS might be used with or without other QP components, in which +// case the separate definitions of the macros QF_CRIT_STAT, QF_CRIT_ENTRY(), +// and QF_CRIT_EXIT() are needed. In this port QS is configured to be used +// with the other QP component, by simply including "qp_port.h" +//*before* "qs.h". +// +#ifndef QP_PORT_H_ +#include "qp_port.h" // use QS with QP #endif -#include "qs.h" /* QS platform-independent public interface */ - -#endif /* QS_PORT_H_ */ +#include "qs.h" // QS platform-independent public interface +#endif // QS_PORT_H_ diff --git a/ports/qube/qube.c b/ports/qube/qube.c index 13a56225..0d3d4c91 100644 --- a/ports/qube/qube.c +++ b/ports/qube/qube.c @@ -1,59 +1,63 @@ -/*============================================================================ -* QP/C Real-Time Embedded Framework (RTEF) -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2023-01-07 -* @version Last updated for: @ref qpc_7_2_0 -* -* @file -* @brief Qube command-line QP execution environment -*/ +//============================================================================ +// QP/C Real-Time Embedded Framework (RTEF) +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +//============================================================================ +//! @date Last updated on: 2023-07-27 +//! @version Last updated for: @ref qpc_7_3_0 +//! +//! @file +//! @brief Qube command-line QP execution environment + #ifndef Q_SPY #error "Q_SPY must be defined to compile qube.c" -#endif /* Q_SPY */ +#endif // Q_SPY -#define QP_IMPL /* this is QP implementation */ -#include "qf_port.h" /* QF port */ -#include "qassert.h" /* QP embedded systems-friendly assertions */ -#include "qs_port.h" /* QS port */ -#include "qs_pkg.h" /* QS package-scope interface */ +#define QP_IMPL // this is QP implementation +#include "qp_port.h" // QP port +#include "qsafe.h" // QP Functional Safety (FuSa) System +#include "qs_port.h" // QS port +#include "qs_pkg.h" // QS package-scope interface -#include "qspy.h" /* QSPY parser interface */ +#include "qspy.h" // QSPY parser interface -#include "safe_std.h" /* portable "safe" / facilities */ -#include /* for exit() */ +#include "safe_std.h" // portable "safe" / facilities +#include // for exit() Q_DEFINE_THIS_MODULE("qube") -/*..........................................................................*/ +// Global objects ========================================================== +QPSet QF_readySet_; +QPSet QF_readySet_dis_; +uint_fast8_t QF_intLock_; + +//............................................................................ static QActive *l_currAO; static char l_currAO_name[QS_DNAME_LEN_MAX]; static uint8_t const Qube = 0U; -static char l_line[QS_LINE_LEN_MAX]; /* last line entered by the user */ -static char l_cmd[QS_DNAME_LEN_MAX]; /* last command part of the line */ +static char l_line[QS_LINE_LEN_MAX]; // last line entered by the user +static char l_cmd[QS_DNAME_LEN_MAX]; // last command part of the line static void parse_input(void); static void handle_evts(void); @@ -66,7 +70,7 @@ static char const *HELP_STR = "curr set the current AO\n" "SIG [params] dispatch a given event to the current AO"; -/* terminal colors */ +// terminal colors #define B_BLUE "\x1b[44m" #define F_GRAY "\x1b[30;1m" #define F_YELLOW "\x1b[33m" @@ -75,11 +79,11 @@ static char const *HELP_STR = #define COLOR_DFLT "\x1b[K\x1b[0m" #define COLOR_APP B_BLUE F_YELLOW -/*..........................................................................*/ +//............................................................................ void Qube_setAO(QActive* ao) { l_currAO = ao; } -/*..........................................................................*/ +//............................................................................ static bool cmd_evt(char const* cmd, char const* params) { QSignal sig = (QSignal)QSPY_findSig(cmd, (ObjType)((uintptr_t)l_currAO)); if (sig != 0U) { @@ -106,7 +110,7 @@ static bool cmd_evt(char const* cmd, char const* params) { } return true; } -/*..........................................................................*/ +//............................................................................ static bool cmd_help(char const* cmd, char const* params) { Q_UNUSED_PAR(cmd); Q_UNUSED_PAR(params); @@ -114,7 +118,7 @@ static bool cmd_help(char const* cmd, char const* params) { PRINTF_S("\n%s", HELP_STR); return true; } -/*..........................................................................*/ +//............................................................................ static bool cmd_curr(char const* cmd, char const* params) { Q_UNUSED_PAR(cmd); @@ -130,53 +134,53 @@ static bool cmd_curr(char const* cmd, char const* params) { } return true; } -/*..........................................................................*/ +//............................................................................ static void parse_input(void) { static struct { char const *name; bool (*handler)(char const *cmd, char const *params); } const commands[] = { - { "A..Z", &cmd_evt }, /* not used directly */ + { "A..Z", &cmd_evt }, // not used directly { "?", &cmd_help }, { "help", &cmd_help }, { "curr", &cmd_curr }, }; - char* lin = l_line; /* pointer within the current line */ - char* cmd = l_cmd; /* pointer within the current command */ - char* params; /* pointer to the parameters part in the line */ + char* lin = l_line; // pointer within the current line + char* cmd = l_cmd; // pointer within the current command + char* params; // pointer to the parameters part in the line - /* - * find the beginning of parameters in the current line - * copy over the command part into l_cmd[]. - */ + // + // find the beginning of parameters in the current line + // copy over the command part into l_cmd[]. + // for (; (*lin != '\n') && (lin < &l_line[Q_DIM(l_line) - 1U]) && (cmd < &l_cmd[Q_DIM(l_cmd)]); ++lin, ++cmd) { - if ((*lin == ' ') || (*lin == ',')) { /* separator? */ - ++lin; /* skip the separator */ + if ((*lin == ' ') || (*lin == ',')) { // separator? + ++lin; // skip the separator break; } else { *cmd = *lin; } } - *cmd = '\0'; /* zero-terminate the command */ - params = lin; /* remember the start of parameters */ + *cmd = '\0'; // zero-terminate the command + params = lin; // remember the start of parameters - /* scan to the end of line and replace the terminating '\n' with '\0' */ + // scan to the end of line and replace the terminating '\n' with '\0' for (; (*lin != '\n') && (lin < &l_line[Q_DIM(l_line) - 1U]); ++lin) { } - *lin = '\0'; /* zero-terminate */ + *lin = '\0'; // zero-terminate bool ok = false; - if (('A' <= l_cmd[0]) && (l_cmd[0] <= 'Z')) { /* A..Z ? */ + if (('A' <= l_cmd[0]) && (l_cmd[0] <= 'Z')) { // A..Z ? STRNCPY_S(cmd, (&l_cmd[Q_DIM(l_cmd)] - cmd), "_SIG"); ok = cmd_evt(l_cmd, params); } - else { /* other command */ - /* search existing command (past cmd_evt)... */ + else { // other command + // search existing command (past cmd_evt)... for (unsigned i = 1U; i < Q_DIM(commands); ++i) { if (strcmp(commands[i].name, l_cmd) == 0) { ok = (*commands[i].handler)(l_cmd, params); @@ -189,30 +193,36 @@ static void parse_input(void) { PRINTF_S("\n%s\n", HELP_STR); } } -/*..........................................................................*/ +//............................................................................ static void handle_evts(void) { while (QPSet_notEmpty(&QF_readySet_)) { uint_fast8_t const p = QPSet_findMax(&QF_readySet_); QActive* const a = QActive_registry_[p]; - /* perform the run-to-completion (RTC) step... - * 1. retrieve the event from the AO's event queue, which by this - * time must be non-empty and The "Vanialla" kernel asserts it. - * 2. dispatch the event to the AO's state machine. - * 3. determine if event is garbage and collect it if so - */ + // perform the run-to-completion (RTC) step... + // 1. retrieve the event from the AO's event queue, which by this + // time must be non-empty and The "Vanialla" kernel asserts it. + // 2. dispatch the event to the AO's state machine. + // 3. determine if event is garbage and collect it if so + // QEvt const* const e = QActive_get_(a); - QHSM_DISPATCH(&a->super, e, a->prio); + QS_FLUSH(); + QASM_DISPATCH(&a->super, e, a->prio); + QS_FLUSH(); #if (QF_MAX_EPOOL > 0U) QF_gc(e); + QS_FLUSH(); #endif - if (a->eQueue.frontEvt == (QEvt*)0) { /* empty queue? */ + if (a->eQueue.frontEvt == (QEvt*)0) { // empty queue? QPSet_remove(&QF_readySet_, p); +#ifndef Q_UNSAFE + QPSet_update_(&QF_readySet_, &QF_readySet_dis_); +#endif } } } -/*..........................................................................*/ +//............................................................................ #if 0 static char const* my_strtok(char* str, char delim) { static char* next; @@ -242,61 +252,68 @@ static char const* my_strtok(char* str, char delim) { } #endif -/* QF functions ============================================================*/ +// QF functions ============================================================ void QF_init(void) { #ifdef _WIN32 - system("color"); /* to support color output */ + system("color"); // to support color output #endif PRINTF_S("Qube %s (c) state-machine.com\n\n%s\n\n", QP_VERSION_STR, HELP_STR); - /* Clear the internal QF variables, so that the framework can start - * correctly even if the startup code fails to clear the uninitialized - * data (as is required by the C Standard). - */ - QF_maxPool_ = 0U; - QF_intLock_ = 0U; - QF_intNest_ = 0U; + // Clear the internal QF variables, so that the framework can start + // correctly even if the startup code fails to clear the uninitialized + // data (as is required by the C Standard). + // + QF_bzero_(&QF_priv_, sizeof(QF_priv_)); + QF_bzero_(&QF_readySet_, sizeof(QF_readySet_)); + QF_bzero_(&QF_intLock_, sizeof(QF_intLock_)); + QF_bzero_(&QActive_registry_[0], sizeof(QActive_registry_)); - QF_bzero(&QActive_registry_[0], sizeof(QActive_registry_)); - QF_bzero(&QF_readySet_, sizeof(QF_readySet_)); +#ifndef Q_UNSAFE + QPSet_update_(&QF_readySet_, &QF_readySet_dis_); +#endif l_currAO_name[0] = '\0'; fputs(COLOR_APP, stdout); - /* initialize the QS software tracing... */ + // initialize the QS software tracing... if (QS_INIT((void*)0) == 0U) { Q_ERROR(); } } -/*..........................................................................*/ +//............................................................................ void QF_stop(void) { QS_onReset(); } -/*..........................................................................*/ +//............................................................................ void QF_onCleanup(void) { fputs(COLOR_DFLT "\n", stdout); PRINTF_S("%s\n", "Qube exit"); } -/*..........................................................................*/ +//............................................................................ int_t QF_run(void) { - /* function dictionaries for the standard API */ + QS_CRIT_STAT + QS_CRIT_ENTRY(); + QS_MEM_SYS(); + + // function dictionaries for the standard API QS_FUN_DICTIONARY(&QActive_post_); QS_FUN_DICTIONARY(&QActive_postLIFO_); - QS_OBJ_DICTIONARY(&Qube); - /* produce the QS_QF_RUN trace record */ - QS_CRIT_STAT_ + // produce the QS_QF_RUN trace record QS_BEGIN_PRE_(QS_QF_RUN, 0U) QS_END_PRE_() - handle_evts(); /* handle all events posted so far */ + QS_MEM_APP(); + QS_CRIT_EXIT(); - if (l_currAO == (QActive*)0) { /* current AO not set? */ - /* take the highest-priority registered AO */ + handle_evts(); // handle all events posted so far + + if (l_currAO == (QActive*)0) { // current AO not set? + // take the highest-priority registered AO for (uint8_t p = QF_MAX_ACTIVE; p != 0U; --p) { if (QActive_registry_[p] != (QActive *)0) { l_currAO = QActive_registry_[p]; @@ -304,7 +321,7 @@ int_t QF_run(void) { } } } - /* still not found? */ + // still not found? if (l_currAO != (QActive*)0) { extern Dictionary QSPY_objDict; @@ -321,11 +338,11 @@ int_t QF_run(void) { fputs(COLOR_DFLT "\n", stdout); - /* event loop... */ + // event loop... for (;;) { PRINTF_S("%s>", l_currAO_name); if (fgets(l_line, sizeof(l_line), stdin) != (char*)0) { - if (l_line[0] == '\n') { /* ? */ + if (l_line[0] == '\n') { // ? break; } parse_input(); @@ -336,10 +353,10 @@ int_t QF_run(void) { } } QF_onCleanup(); - return 0; /* return no error */ + return 0; // return no error } -/*--------------------------------------------------------------------------*/ +//-------------------------------------------------------------------------- void QActive_start_(QActive* const me, QPrioSpec const prioSpec, QEvt const** const qSto, @@ -351,63 +368,63 @@ void QActive_start_(QActive* const me, Q_UNUSED_PAR(stkSto); Q_UNUSED_PAR(stkSize); - me->prio = (uint8_t)(prioSpec & 0xFFU); /* QF-priority of the AO */ - me->pthre = (uint8_t)(prioSpec >> 8U); /* preemption-threshold */ - QActive_register_(me); /* make QF aware of this active object */ + me->prio = (uint8_t)(prioSpec & 0xFFU); // QF-priority of the AO + me->pthre = (uint8_t)(prioSpec >> 8U); // preemption-threshold + QActive_register_(me); // make QF aware of this active object - QEQueue_init(&me->eQueue, qSto, qLen); /* initialize the built-in queue */ + QEQueue_init(&me->eQueue, qSto, qLen); // initialize the built-in queue - QHSM_INIT(&me->super, par, me->prio); /* the top-most initial tran. */ + QASM_INIT(&me->super, par, me->prio); // the top-most initial tran. } -/*..........................................................................*/ -#ifdef QF_ACTIVE_STOP +//............................................................................ +#ifdef QACTIVE_CAN_STOP void QActive_stop(QActive* const me) { - QActive_unsubscribeAll(me); /* unsubscribe from all events */ - QActive_unregister_(me); /* un-register this active object */ + QActive_unsubscribeAll(me); // unsubscribe from all events + QActive_unregister_(me); // un-register this active object } -#endif /* def QF_ACTIVE_STOP */ +#endif // def QACTIVE_CAN_STOP -/*--------------------------------------------------------------------------*/ +//-------------------------------------------------------------------------- uint8_t QS_onStartup(void const *arg) { Q_UNUSED_PAR(arg); - /* initialize the QS transmit and receive buffers */ - static uint8_t qsBuf[4 * 1024]; /* buffer for QS-TX channel */ + // initialize the QS transmit and receive buffers + static uint8_t qsBuf[4 * 1024]; // buffer for QS-TX channel QS_initBuf(qsBuf, sizeof(qsBuf)); - /* QS configuration options for this application... */ + // QS configuration options for this application... QSpyConfig const config = { - QP_VERSION, /* version */ - 0U, /* endianness (little) */ - QS_OBJ_PTR_SIZE, /* objPtrSize */ - QS_FUN_PTR_SIZE, /* funPtrSize */ - QS_TIME_SIZE, /* tstampSize */ - Q_SIGNAL_SIZE, /* sigSize */ - QF_EVENT_SIZ_SIZE, /* evtSize */ - QF_EQUEUE_CTR_SIZE, /* queueCtrSize */ - QF_MPOOL_CTR_SIZE, /* poolCtrSize */ - QF_MPOOL_SIZ_SIZE, /* poolBlkSize */ - QF_TIMEEVT_CTR_SIZE, /* tevtCtrSize */ - { 0U, 0U, 0U, 0U, 0U, 0U} /* tstamp */ + QP_VERSION, // version + 0U, // endianness (little) + QS_OBJ_PTR_SIZE, // objPtrSize + QS_FUN_PTR_SIZE, // funPtrSize + QS_TIME_SIZE, // tstampSize + Q_SIGNAL_SIZE, // sigSize + QF_EVENT_SIZ_SIZE, // evtSize + QF_EQUEUE_CTR_SIZE, // queueCtrSize + QF_MPOOL_CTR_SIZE, // poolCtrSize + QF_MPOOL_SIZ_SIZE, // poolBlkSize + QF_TIMEEVT_CTR_SIZE, // tevtCtrSize + { 0U, 0U, 0U, 0U, 0U, 0U} // tstamp }; QSPY_config(&config, (QSPY_CustParseFun)0); // no custom parser function - return 1U; /* success */ + return 1U; // success } -/*..........................................................................*/ +//............................................................................ void QS_onCleanup(void) { } -/*..........................................................................*/ +//............................................................................ void QSPY_onPrintLn(void) { PRINTF_S("%s\n", QSPY_line); } -/*..........................................................................*/ +//............................................................................ void QS_onReset(void) { QF_onCleanup(); exit(0); } -/*..........................................................................*/ +//............................................................................ void QS_onFlush(void) { for (;;) { uint16_t nBytes = 1024U; @@ -420,17 +437,17 @@ void QS_onFlush(void) { } } } -/*..........................................................................*/ +//............................................................................ QSTimeCtr QS_onGetTime(void) { static QSTimeCtr time_ctr = 0U; ++time_ctr; return time_ctr; } -/*..........................................................................*/ -Q_NORETURN Q_onAssert(char const * const module, int_t const loc) { - QS_ASSERTION(module, loc, 0U); /* report assertion to QS */ - FPRINTF_S(stderr, "Assertion failed in %s:%d", module, loc); +//............................................................................ +Q_NORETURN Q_onError(char const * const module, int_t const id) { + FPRINTF_S(stderr, "ERROR in %s:%d", module, id); + QS_ASSERTION(module, id, 0U); // report assertion to QS QF_onCleanup(); QS_EXIT(); exit(-1); diff --git a/ports/qube/safe_std.h b/ports/qube/safe_std.h index b4a1f511..c752662c 100644 --- a/ports/qube/safe_std.h +++ b/ports/qube/safe_std.h @@ -1,42 +1,40 @@ -/*============================================================================ -* QP/C Real-Time Embedded Framework (RTEF) -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2022-07-30 -* @version Last updated for: @ref qpc_7_1_3 -* -* @file -* @brief "safe" and facilities -*/ +//============================================================================ +// QP/C Real-Time Embedded Framework (RTEF) +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +//============================================================================ +//! @date Last updated on: 2022-07-30 +//! @version Last updated for: @ref qpc_7_1_3 +//! +//! @file +//! @brief "safe" and facilities #ifndef SAFE_STD_H #define SAFE_STD_H #include #include -/* portable "safe" facilities from and ................*/ -#ifdef _WIN32 /* Windows OS? */ +// portable "safe" facilities from and ................ +#ifdef _WIN32 // Windows OS? #define MEMMOVE_S(dest_, num_, src_, count_) \ memmove_s(dest_, num_, src_, count_) @@ -62,7 +60,7 @@ #else #define FREAD_S(buf_, bufsiz_, elsiz_, count_, fp_) \ fread(buf_, elsiz_, count_, fp_) -#endif /* _MSC_VER */ +#endif // _MSC_VER #define FOPEN_S(fp_, fName_, mode_) \ if (fopen_s(&fp_, fName_, mode_) != 0) { \ @@ -72,7 +70,7 @@ if (fopen_s(&fp_, fName_, mode_) != 0) { \ #define LOCALTIME_S(tm_, time_) \ localtime_s(tm_, time_) -#else /* other OS (Linux, MacOS, etc.) .....................................*/ +#else // other OS (Linux, MacOS, etc.) ..................................... #define MEMMOVE_S(dest_, num_, src_, count_) \ memmove(dest_, src_, count_) @@ -103,6 +101,6 @@ if (fopen_s(&fp_, fName_, mode_) != 0) { \ #define LOCALTIME_S(tm_, time_) \ memcpy(tm_, localtime(time_), sizeof(struct tm)) -#endif /* _WIN32 */ +#endif // _WIN32 -#endif /* SAFE_STD_H */ +#endif // SAFE_STD_H diff --git a/ports/risc-v/qv/gnu/qep_port.h b/ports/risc-v/qv/gnu/qep_port.h deleted file mode 100644 index b31e5622..00000000 --- a/ports/risc-v/qv/gnu/qep_port.h +++ /dev/null @@ -1,44 +0,0 @@ -/*============================================================================ -* QP/C Real-Time Embedded Framework (RTEF) -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2022-09-27 -* @version Last updated for: @ref qpc_7_1_1 -* -* @file -* @brief QEP/C port, GNU compiler -*/ -#ifndef RISCV_QEP_PORT_H_ -#define RISCV_QEP_PORT_H_ - -/*! no-return function specifier (GCC compiler) */ -#define Q_NORETURN __attribute__ ((noreturn)) void - -#include /* Exact-width types. WG14/N843 C99 Standard */ -#include /* Boolean type. WG14/N843 C99 Standard */ - -#include "qep.h" /* QEP platform-independent public interface */ - -#endif /* RISCV_QEP_PORT_H_ */ - diff --git a/ports/risc-v/qv/gnu/qf_port.h b/ports/risc-v/qv/gnu/qf_port.h deleted file mode 100644 index 0e78fa73..00000000 --- a/ports/risc-v/qv/gnu/qf_port.h +++ /dev/null @@ -1,86 +0,0 @@ -/*============================================================================ -* QP/C Real-Time Embedded Framework (RTEF) -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2022-09-30 -* @version Last updated for: @ref qpc_7_1_2 -* -* @file -* @brief QF/C port to RISC-V, cooperative QV kernel, GNU compiler -*/ -#ifndef RISCV_QF_PORT_H_ -#define RISCV_QF_PORT_H_ - -/* The maximum number of active objects in the application, see NOTE1 */ -#define QF_MAX_ACTIVE 32U - -/* interrupt disabling policy, see NOTE2 */ -#define QF_INT_DISABLE() __asm__ volatile("csrc mstatus,8") -#define QF_INT_ENABLE() __asm__ volatile("csrs mstatus,8") - -/* QF critical section entry/exit, see NOTE3 */ -#define QF_CRIT_STAT_TYPE unsigned int -#define QF_CRIT_ENTRY(status_) do { \ - __asm__ volatile("csrr %0, mstatus" : "=r"(status_)); \ - QF_INT_DISABLE(); \ -} while (false) -#define QF_CRIT_EXIT(status_) \ - __asm__ volatile ("csrw mstatus, %0" :: "rK"(status_)) - -/* support for fast LOG2, see NOTE4 */ -#define QF_LOG2(n_) ((uint_fast8_t)(32U - __builtin_clz((n_)))) - -/* NOP instruction for RISC-V, NOTE5 */ -#define QF_CRIT_EXIT_NOP() __asm__ volatile ("nop") - -#include "qep_port.h" /* QEP port */ -#include "qv_port.h" /* QV cooperative kernel port */ -#include "qf.h" /* QF platform-independent public interface */ - -/*==========================================================================*/ -/* NOTE1: -* The maximum number of active objects QF_MAX_ACTIVE can be increased -* up to 64U, if necessary. Here it is set to a lower level of 32 to -* slightly improve performance and save some RAM. -* -* NOTE2: -* Interrupts are disabled by clearing the MIE (bit-3) in the mstatus register. -* Interrupts are enabled by setting the MIE (bit-3) in the mstatus register. -* -* NOTE3: -* QP critical section uses the "save and restore interrupt status" policy. -* This policy is appropriate for CPUs that disable interrupts inside ISRs, -* which is the case with RISC-V. Also, this policy allows *nesting* of -* critical sections. -* -* NOTE4: -* The __builtin_clz() function is used for the integer log-base-2 -* implementation, which is used in the QV scheduler. - -* NOTE5: -* The NOP instruction is used to prevent merging of back-to-back critical -* sections. -*/ - -#endif /* RISCV_QF_PORT_H_ */ diff --git a/ports/risc-v/qv/gnu/qp_port.h b/ports/risc-v/qv/gnu/qp_port.h new file mode 100644 index 00000000..124f5c41 --- /dev/null +++ b/ports/risc-v/qv/gnu/qp_port.h @@ -0,0 +1,95 @@ +//============================================================================ +// QP/C Real-Time Embedded Framework (RTEF) +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC . +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +//============================================================================ +//! @date Last updated on: 2023-09-07 +//! @version Last updated for: @ref qpc_7_3_0 +//! +//! @file +//! @brief QP/C port to RISC-V, QV kernel, GNU-RISCV compiler + +#ifndef QP_PORT_H_ +#define QP_PORT_H_ + +#include // Exact-width types. WG14/N843 C99 Standard +#include // Boolean type. WG14/N843 C99 Standard + +#ifdef QP_CONFIG +#include "qp_config.h" // external QP configuration +#endif + +// no-return function specifier (C11 Standard) +#define Q_NORETURN _Noreturn void + +// interrupt disabling policy, see NOTE2 +#define QF_INT_DISABLE() __asm__ volatile("csrc mstatus,8") +#define QF_INT_ENABLE() __asm__ volatile("csrs mstatus,8") + +// QF critical section entry/exit, see NOTE3 +#define QF_CRIT_STAT unsigned int mstatus_; +#define QF_CRIT_ENTRY() do { \ + __asm__ volatile("csrr %0, mstatus" : "=r"(mstatus_)); \ + QF_INT_DISABLE(); \ +} while (false) +#define QF_CRIT_EXIT() \ + __asm__ volatile ("csrw mstatus, %0" :: "rK"(mstatus_)) + +// support for fast LOG2, see NOTE4 +#define QF_LOG2(n_) ((uint_fast8_t)(32U - __builtin_clz((n_)))) + +// NOP instruction for RISC-V, NOTE5 +#define QF_CRIT_EXIT_NOP() __asm__ volatile ("nop") + +// include files ------------------------------------------------------------- +#include "qequeue.h" // QK kernel uses the native QP event queue +#include "qmpool.h" // QK kernel uses the native QP memory pool +#include "qp.h" // QP platform-independent public interface +#include "qv.h" // QV kernel integrates directly with QP + +//============================================================================ +// NOTE2: +// Interrupts are disabled by clearing the MIE (bit-3) in the mstatus register. +// Interrupts are enabled by setting the MIE (bit-3) in the mstatus register. +// +// NOTE3: +// QP critical section uses the "save and restore interrupt status" policy. +// This policy is appropriate for CPUs that disable interrupts inside ISRs, +// which is the case with RISC-V. Also, this policy allows *nesting* of +// critical sections. +// +// NOTE4: +// The __builtin_clz() function is used for the integer log-base-2 +// implementation, which is used in the QV scheduler. +// +// NOTE5: +// The NOP instruction is used to prevent merging of back-to-back critical +// sections. +// + +#endif // QP_PORT_H_ + diff --git a/ports/risc-v/qv/gnu/qs_port.h b/ports/risc-v/qv/gnu/qs_port.h index b358159d..e2eb1a77 100644 --- a/ports/risc-v/qv/gnu/qs_port.h +++ b/ports/risc-v/qv/gnu/qs_port.h @@ -1,57 +1,60 @@ -/*============================================================================ -* QP/C Real-Time Embedded Framework (RTEF) -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2022-09-27 -* @version Last updated for: @ref qpc_7_1_1 -* -* @file -* @brief QS/C port to a 32-bit CPU and a generic C99 compiler. -*/ -#ifndef RISCV_QS_PORT_H_ -#define QS_RISCV_QS_PORT_H__H +//============================================================================ +// QP/C Real-Time Embedded Framework (RTEF) +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +//============================================================================ +//! @date Last updated on: 2023-05-23 +//! @version Last updated for: @ref qpc_7_3_0 +//! +//! @file +//! @brief QS/C port to a 32-bit CPU and a generic C11 compiler. +//! @description +//! This is an example of a QP/C port with the documentation for the +//! configuration macros and includes. -/* QS time-stamp size in bytes */ -#define QS_TIME_SIZE 4 +#ifndef QS_PORT_H_ +#define QS_PORT_H_ -/* object pointer size in bytes */ -#define QS_OBJ_PTR_SIZE 4 +// QS time-stamp size in bytes +#define QS_TIME_SIZE 4U -/* function pointer size in bytes */ -#define QS_FUN_PTR_SIZE 4 +// object pointer size in bytes +#define QS_OBJ_PTR_SIZE 4U -/*==========================================================================*/ -/* NOTE: QS might be used with or without other QP components, in which -* case the separate definitions of the macros QF_CRIT_STAT_TYPE, -* QF_CRIT_ENTRY, and QF_CRIT_EXIT are needed. In this port QS is configured -* to be used with the other QP component, by simply including "qf_port.h" -* *before* "qs.h". -*/ -#ifndef QF_PORT_H -#include "qf_port.h" /* use QS with QF */ +// function pointer size in bytes +#define QS_FUN_PTR_SIZE 4U + +//============================================================================ +// NOTE: QS might be used with or without other QP components, in which +// case the separate definitions of the macros QF_CRIT_STAT, QF_CRIT_ENTRY(), +// and QF_CRIT_EXIT() are needed. In this port QS is configured to be used +// with the other QP component, by simply including "qp_port.h" +//*before* "qs.h". +// +#ifndef QP_PORT_H_ +#include "qp_port.h" // use QS with QP #endif -#include "qs.h" /* QS platform-independent public interface */ +#include "qs.h" // QS platform-independent public interface + +#endif // QS_PORT_H_ -#endif /* RISCV_QS_PORT_H_ */ diff --git a/ports/risc-v/qv/gnu/qv_port.h b/ports/risc-v/qv/gnu/qv_port.h deleted file mode 100644 index 5d3e3b52..00000000 --- a/ports/risc-v/qv/gnu/qv_port.h +++ /dev/null @@ -1,53 +0,0 @@ -/*============================================================================ -* QP/C Real-Time Embedded Framework (RTEF) -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2022-09-29 -* @version Last updated for: @ref qpc_7_1_2 -* -* @file -* @brief QV/C port to RISC-V, GNU compiler -*/ -#ifndef RISCV_QV_PORT_H_ -#define RISCV_QV_PORT_H_ - -/*! macro to put the CPU to sleep inside QV_onIdle() */ -/* The following QV_CPU_SLEEP() executes the WFI instruction with -* interrupts still DISABLED. Interrupts are enabled only after -* the RISC-V CPU wakes up. See NOTE6. -*/ -#define QV_CPU_SLEEP() do { \ - __asm volatile("wfi"); \ - QF_INT_ENABLE(); \ -} while (false) - -#include "qv.h" /* QV platform-independent public interface */ - -/*==========================================================================*/ -/* NOTE6: -* The QV_CPU_SLEEP() macro is entered with interrupts still **disabled**. -* But, according to the "The RISC-V Instruction Set Manual", -* the `WFI` instruction *can* be executed when interrupts are disabled. -*/ -#endif /* RISCV_QV_PORT_H_ */ diff --git a/ports/sample/README.md b/ports/sample/README.md deleted file mode 100644 index dd61b5ce..00000000 --- a/ports/sample/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# Sample QP/C Port -This direcctory contains a typical QP/C port with documented configuration -options. diff --git a/ports/sample/qep_port.h b/ports/sample/qep_port.h deleted file mode 100644 index da5536c8..00000000 --- a/ports/sample/qep_port.h +++ /dev/null @@ -1,62 +0,0 @@ -/*============================================================================ -* QP/C Real-Time Embedded Framework -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2022-12-23 -* @version Last updated for: @ref qpc_7_2_0 -* -* @file -* @brief QEP/C sample port with all configurable options -*/ -#ifndef QEP_PORT_H_ -#define QEP_PORT_H_ - -/*! The size (in bytes) of the signal of an event. Valid values: -* 1U, 2U, or 4U; default 2U -* -* @details -* This macro can be defined in the QEP port file (qep_port.h) to -* configure the ::QSignal type. When the macro is not defined, the -* default of 2 bytes is applied in the `qep.h` header file. -*/ -#define Q_SIGNAL_SIZE 2U - -/*! No-return function specifier for the Q_onAssert() callback function. -* -* The `Q_NORETURN` macro is supposed to be defined in the QP/C port -* (file `qep_port.h`). If such definition is NOT provided, the default -* definition is provided in the `qassert.h` header file, where -* it assumes only `void` type returned from Q_onAssert(). -* -* @trace -* @tr{PQA01_4} -*/ -#define Q_NORETURN __attribute__ ((noreturn)) void - -#include /* Exact-width types. WG14/N843 C99 Standard */ -#include /* Boolean type. WG14/N843 C99 Standard */ - -#include "qep.h" /* QEP platform-independent public interface */ - -#endif /* QEP_PORT_H_ */ diff --git a/ports/sample/qf_port.h b/ports/sample/qf_port.h deleted file mode 100644 index 281eebc1..00000000 --- a/ports/sample/qf_port.h +++ /dev/null @@ -1,255 +0,0 @@ -/*============================================================================ -* QP/C Real-Time Embedded Framework -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2022-11-23 -* @version Last updated for: @ref qpc_7_2_0 -* -* @file -* @brief QF/C sample port with all configurable options -*/ -#ifndef QF_PORT_H_ -#define QF_PORT_H_ - -/*! This macro defines the type of the thread handle used for AOs */ -#define QF_THREAD_TYPE void* - -/*! This macro defines the type of the event-queue used for AOs */ -#define QF_EQUEUE_TYPE QEQueue - -/*! This macro defines the type of the OS-Object used for blocking -* the native ::QEQueue when the queue is empty -* -* @description -* This macro is used when ::QEQueue is used as the event-queue for AOs -* but also the AO queue must *block* when the queue is empty. -* In that case, #QF_OS_OBJECT_TYPE specifies the blocking mechanism. -* For example, in the POSIX port, the blocking mechanism is a condition -* variable. -*/ -#define QF_OS_OBJECT_TYPE pthread_cond_t - -/*! This macro defines the type of the event pool used in the port. -* -* @description -* This is a specific implementation for the QK-port of QF. -* In other QF ports you need to define the macro appropriately for -* the underlying kernel/OS you're using. -*/ -#define QF_EPOOL_TYPE_ QMPool - -/*! The maximum number of active objects in the application. -* -* @description -* This macro *must* be defined in the `qf_port.h` header file and should be -* in range of 1U..64U, inclusive. The value of this macro determines the -* maximum priority level of an active object in the system. Not all priority -* levels must be used, but the maximum priority cannot exceed `QF_MAX_ACTIVE`. -* Defining the value below the maximum limit of 64 saves some memory (RAM). -*/ -#define QF_MAX_ACTIVE 64U - -/*! The maximum number of clock tick rates in the application. -* -* @description -* This macro can be defined in the `qf_port.h` header file and should be -* in range of 1U..15U, inclusive. The value of this macro determines the -* maximum number of clock tick rates for time events (::QTimeEvt). -* -* If the macro is not defined, the `qf.h` header file sets the default -* value to 1U. -*/ -#define QF_MAX_TICK_RATE 1U - -/*! The size (in bytes) of the time event-counter representation -* in the ::QTimeEvt struct. Valid values: 1U, 2U, or 4U; default 2U. -* -* @description -* This macro can be defined in the `qf_port.h` header file to configure the -* internal tick counters of Time Events. If the macro is not defined, the -* default of 4 bytes will be chosen in `qf.h`. The valid #QF_TIMEEVT_CTR_SIZE -* values of 1, 2, or 4, correspond to tick counters of uint8_t, uint16_t, -* and uint32_t, respectively. The tick counter representation determines the -* dynamic range of time delays that a Time Event can handle. -* @sa ::QTimeEvt -*/ -#define QF_TIMEEVT_CTR_SIZE 4U - -/*! The maximum number of event pools in the application. -* -* @description -* This macro can be defined in the `qf_port.h` header file and should be -* in range of 1U..255U, inclusive. The value of this macro determines the -* maximum number of event pools in the system. Not all event pools must be -* actually used, but the maximum number of pools cannot exceed `QF_MAX_EPOOL`. -* -* If the macro is not defined, the `qf.h` header file sets the default -* value to 3U. Defining `QF_MAX_EPOOL` below the maximum limit of 255 -* saves some memory (RAM). -*/ -#define QF_MAX_EPOOL 3U - -/*! The size (in bytes) of the event-size representation in the QF. -* Valid values: 1U, 2U, or 4U; default 2U -* -* @description -* This macro can be defined in the QF ports to configure the size -* of the event-size. -*/ -#define QF_EVENT_SIZ_SIZE 2U - -/*! The size (in bytes) of the ring-buffer counters used in the native QF -* event queue implementation. Valid values: 1U, 2U, or 4U; default 1U -* -* @description -* This macro can be defined in the `qf_port.h` header file to configure -* the ::QEQueueCtr type. If the macro is not defined, the default of 1 byte -* will be chosen in `qequeue.h`. The valid #QF_EQUEUE_CTR_SIZE values of -* 1U, 2U, or 4U, correspond to ::QEQueueCtr of uint8_t, uint16_t, and -* uint32_t, respectively. The::QEQueueCtr data type determines the dynamic -* range of numerical values of ring-buffer counters inside event queues, or, -* in other words, the maximum number of events that the native QF event -* queue can manage. -* @sa ::QEQueue -*/ -#define QF_EQUEUE_CTR_SIZE 1U - -/*! The size (in bytes) of the block-size representation in the native QF -* event pool. Valid values: 1U, 2U, or 4U; default #QF_EVENT_SIZ_SIZE. -* -* @description -* This macro can be defined in the `qf_port.h` header file to configure the -* ::QMPoolSize type. If the macro is not defined, the default of -* #QF_EVENT_SIZ_SIZE will be chosen in `qmpool.h`, because the memory pool -* is primarily used for implementing event pools. -* -* The valid #QF_MPOOL_SIZ_SIZE values of 1U, 2U, or 4U, correspond to -* ::QMPoolSize of uint8_t, uint16_t, and uint32_t, respectively. The -* ::QMPoolSize data type determines the dynamic range of block-sizes that -* the native ::QMPool can handle. -* @sa #QF_EVENT_SIZ_SIZE, ::QMPool -*/ -#define QF_MPOOL_SIZ_SIZE 2U - -/*! The size (in bytes) of the block-counter representation in the -* native QF event pool. Valid values: 1U, 2U, or 4U; default 2U. -* -* @description -* This macro can be defined in the `qf_port.h` header file to configure the -* ::QMPoolCtr type. If the macro is not defined, the default of 2 bytes will -* be chosen in `qmpool.h`. The valid #QF_MPOOL_CTR_SIZE values of 1U, 2U, -* or 4U, correspond to ::QMPoolSize of uint8_t, uint16_t, and uint32_t, -* respectively. The ::QMPoolCtr data type determines the dynamic range of -* block-counters that the native ::QMPool can handle, or, in other words, -* the maximum number of blocks that the native QF event pool can manage. -* @sa ::QMPool -*/ -#define QF_MPOOL_CTR_SIZE 2U - -/*! Define the interrupt disabling policy. -* -* @description -* This macro encapsulates platform-specific way of disabling interrupts -* from "C" for a given CPU and compiler. -* -* @note -* the #QF_INT_DISABLE macro should always be used in pair with the -* macro #QF_INT_ENABLE. -*/ -#define QF_INT_DISABLE() intDisable() - -/*! Define the interrupt enabling policy. -* -* @description -* This macro encapsulates platform-specific way of enabling interrupts -* from "C" for a given CPU and compiler. -* -* @note the #QF_INT_DISABLE macro should always be used in pair with the -* macro #QF_INT_ENABLE. -*/ -#define QF_INT_ENABLE() intEnable() - -/*! Define the type of the critical section status. -* -* @description -* Defining this macro configures the "saving and restoring critical section -* status" policy. Conversely, if this macro is not defined, the simple -* "unconditional critical section exit" is used. -*/ -#define QF_CRIT_STAT_TYPE crit_stat_t - -/*! Define the critical section entry policy. -* -* @description -* This macro enters a critical section (often by means of disabling -* interrupts). When the "saving and restoring critical section status" -* policy is used, the macro sets the @a status_ argument to the critical -* section status just before the entry. When the policy of "unconditional -* critical section exit" is used, the macro does not use the @a status_ -* argument. -* -* @note the #QF_CRIT_ENTRY macro should always be used in pair with the -* macro #QF_CRIT_EXIT. -*/ -#define QF_CRIT_ENTRY(stat_) ((stat_) = critEntry()) - -/*! Define the critical section exit policy. -* -* @description -* This macro enters a critical section (often by means of disabling -* interrupts). When the "saving and restoring critical section status" -* policy is used, the macro restores the critical section status from the -* @a status_ argument. When the policy of "unconditional critical section -* exit" is used, the macro does not use the @a status argument and -* exits the critical section unconditionally (often by means of enabling -* interrupts). -* -* @note the #QF_CRIT_ENTRY macro should always be used in pair with the -* macro #QF_CRIT_EXIT. -*/ -#define QF_CRIT_EXIT(stat_) critExit(stat_) - -/*! Define No-Operation (NOP) implementation to prevent joining -* adjacent critical sections. -*/ -#define QF_CRIT_EXIT_NOP() __asm volatile ("isb") - -/*! Define integer log-base-2 implementation strategy -* -* @description -* This macro can be defined in the `qf_port.h` header file to speed up -* the integer log-base-2 computation, which is used internally in QP to -* quickly find the highest-priority AO to execute or to find the -* highest-priority subscriber AO to a given event signal. The QF_LOG2() -* macro allows the port to specify a fast, hardware-supported computation -* (e.g., based on the count-leading-zeros instruction available in some CPUs). -* -* If this macros is NOT defined a default, reasonably fast algorithm is used. -*/ -#define QF_LOG2(n_) ((uint_fast8_t)(32U - __builtin_clz((unsigned)(n_)))) - -#include "qk_port.h" /* underlying real-time kernel port */ -#include "qf.h" /* QF platform-independent public interface */ - -#endif /* QF_PORT_H */ diff --git a/ports/sample/qk_port.h b/ports/sample/qk_port.h deleted file mode 100644 index d0398d40..00000000 --- a/ports/sample/qk_port.h +++ /dev/null @@ -1,52 +0,0 @@ -/*============================================================================ -* QP/C Real-Time Embedded Framework (RTEF) -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2022-10-02 -* @version Last updated for: @ref qpc_7_1_2 -* -* @file -* @brief QK/C sample port with all configurable options -*/ -#ifndef QK_PORT_H_ -#define QK_PORT_H_ - -/* QK interrupt entry and exit... */ -#define QK_ISR_ENTRY() (++QF_intNest_) - -#define QK_ISR_EXIT() do { \ - --QF_intNest_; \ - if (QF_intNest_ == 0U) { \ - if (QK_sched_() != 0U) { \ - QK_activate_(); \ - } \ - } \ - else { \ - Q_ERROR(); \ - } \ -} while (false) - -#include "qk.h" /* QK platform-independent public interface */ - -#endif /* QK_PORT_H_ */ diff --git a/ports/sample/qs_port.h b/ports/sample/qs_port.h deleted file mode 100644 index d40ad4a7..00000000 --- a/ports/sample/qs_port.h +++ /dev/null @@ -1,60 +0,0 @@ -/*============================================================================ -* QP/C Real-Time Embedded Framework (RTEF) -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2023-01-05 -* @version Last updated for: @ref qpc_7_2_0 -* -* @file -* @brief QS/C sample port with all configurable options -*/ -#ifndef QS_PORT_H_ -#define QS_PORT_H_ - -/*! QS buffer counter size in bytes */ -#define QS_CTR_SIZE 2U - -/*! QS time-stamp size in bytes */ -#define QS_TIME_SIZE 4U - -/*! object pointer size in bytes */ -#define QS_OBJ_PTR_SIZE 4U - -/*! function pointer size in bytes */ -#define QS_FUN_PTR_SIZE 4U - -/*==========================================================================*/ -/* NOTE: QS might be used with or without other QP components, in which -* case the separate definitions of the macros QF_CRIT_STAT_TYPE, -* QF_CRIT_ENTRY, and QF_CRIT_EXIT are needed. In this port QS is configured -* to be used with the other QP component, by simply including "qf_port.h" -* *before* "qs.h". -*/ -#ifndef QF_PORT_H -#include "qf_port.h" /* use QS with QF */ -#endif - -#include "qs.h" /* QS platform-independent public interface */ - -#endif /* QS_PORT_H_ */ diff --git a/ports/threadx/qep_port.h b/ports/threadx/qep_port.h deleted file mode 100644 index f7a5a9a8..00000000 --- a/ports/threadx/qep_port.h +++ /dev/null @@ -1,40 +0,0 @@ -/*============================================================================ -* QP/C Real-Time Embedded Framework (RTEF) -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2023-01-07 -* @version Last updated for: @ref qpc_7_2_0 -* -* @file -* @brief QEP/C port, generic C99 compiler -*/ -#ifndef QEP_PORT_H -#define QEP_PORT_H - -#include /* Exact-width types. WG14/N843 C99 Standard */ -#include /* Boolean type. WG14/N843 C99 Standard */ - -#include "qep.h" /* QEP platform-independent public interface */ - -#endif /* QEP_PORT_H */ diff --git a/ports/threadx/qf_port.c b/ports/threadx/qf_port.c index 9e47504c..fcc758c6 100644 --- a/ports/threadx/qf_port.c +++ b/ports/threadx/qf_port.c @@ -1,293 +1,329 @@ -/*============================================================================ -* QP/C Real-Time Embedded Framework (RTEF) -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2023-01-07 -* @version Last updated for: @ref qpc_7_2_0 -* -* @file -* @brief QF/C, port to ThreadX -*/ -#define QP_IMPL /* this is QP implementation */ -#include "qf_port.h" /* QF port */ -#include "qf_pkg.h" -#include "qassert.h" -#ifdef Q_SPY /* QS software tracing enabled? */ - #include "qs_port.h" /* QS port */ - #include "qs_pkg.h" /* QS package-scope internal interface */ +//============================================================================ +// QP/C Real-Time Embedded Framework (RTEF) +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +//============================================================================ +//! @date Last updated on: 2023-08-22 +//! @version Last updated for: @ref qpc_7_3_0 +//! +//! @file +//! @brief QF/C, port to ThreadX + +#define QP_IMPL // this is QP implementation +#include "qp_port.h" // QP port +#include "qp_pkg.h" // QP package-scope interface +#include "qsafe.h" // QP Functional Safety (FuSa) Subsystem +#ifdef Q_SPY // QS software tracing enabled? + #include "qs_port.h" // QS port + #include "qs_pkg.h" // QS package-scope internal interface #else - #include "qs_dummy.h" /* disable the QS software tracing */ -#endif /* Q_SPY */ + #include "qs_dummy.h" // disable the QS software tracing +#endif // Q_SPY Q_DEFINE_THIS_MODULE("qf_port") -/*..........................................................................*/ +//............................................................................ void QF_init(void) { } -/*..........................................................................*/ +//............................................................................ int_t QF_run(void) { - QS_CRIT_STAT_ + QF_onStartup(); // QF callback to configure and start interrupts - QF_onStartup(); /* QF callback to configure and start interrupts */ - - /* produce the QS_QF_RUN trace record */ + // produce the QS_QF_RUN trace record + QS_CRIT_STAT + QS_CRIT_ENTRY(); QS_BEGIN_PRE_(QS_QF_RUN, 0U) QS_END_PRE_() + QS_CRIT_EXIT(); - return 0; /* return success */ + return 0; // return success } -/*..........................................................................*/ +//............................................................................ void QF_stop(void) { - QF_onCleanup(); /* cleanup callback */ + QF_onCleanup(); // cleanup callback } -/*..........................................................................*/ -static void thread_function(ULONG thread_input) { /* ThreadX signature */ +//............................................................................ +static void thread_function(ULONG thread_input) { // ThreadX signature QActive *act = (QActive *)thread_input; - /* event-loop */ - for (;;) { /* for-ever */ + // event-loop + for (;;) { // for-ever QEvt const *e = QActive_get_(act); - QHSM_DISPATCH(&act->super, e, act->prio); - QF_gc(e); /* check if the event is garbage, and collect it if so */ + QASM_DISPATCH(&act->super, e, act->prio); + QF_gc(e); // check if the event is garbage, and collect it if so } } -/*..........................................................................*/ +//............................................................................ void QActive_start_(QActive * const me, QPrioSpec const prioSpec, QEvt const * * const qSto, uint_fast16_t const qLen, void * const stkSto, uint_fast16_t const stkSize, void const * const par) { - /* allege that the ThreadX queue is created successfully */ - Q_ALLEGE_ID(210, - tx_queue_create(&me->eQueue, - me->thread.tx_thread_name, - TX_1_ULONG, - (VOID *)qSto, - (ULONG)(qLen * sizeof(ULONG))) - == TX_SUCCESS); + me->prio = (uint8_t)(prioSpec & 0xFFU); // QF-priority + me->pthre = (uint8_t)(prioSpec >> 8U); // QF preemption-threshold + QActive_register_(me); // register this AO - me->prio = (uint8_t)(prioSpec & 0xFFU); /* QF-priority */ - me->pthre = (uint8_t)(prioSpec >> 8U); /* preemption-threshold */ - QActive_register_(me); /* register this AO */ + UINT tx_err = tx_queue_create(&me->eQueue, + me->thread.tx_thread_name, + TX_1_ULONG, + (VOID *)qSto, + (ULONG)(qLen * sizeof(ULONG))); - QHSM_INIT(&me->super, par, me->prio); /* initial tran. (virtual) */ - QS_FLUSH(); /* flush the trace buffer to the host */ + QF_CRIT_STAT + QF_CRIT_ENTRY(); + Q_ASSERT_INCRIT(210, tx_err == TX_SUCCESS); + QF_CRIT_EXIT(); - Q_ALLEGE_ID(220, - tx_thread_create( - &me->thread, /* ThreadX thread control block */ - me->thread.tx_thread_name, /* unique thread name */ - &thread_function, /* thread function */ - (ULONG)me, /* thread parameter */ - stkSto, /* stack start */ - stkSize, /* stack size in bytes */ - QF_TX_PRIO_OFFSET + QF_MAX_ACTIVE - me->prio, /* ThreadX prio */ - QF_TX_PRIO_OFFSET + QF_MAX_ACTIVE - me->pthre, /* preempt-thre */ - TX_NO_TIME_SLICE, - TX_AUTO_START) - == TX_SUCCESS); + QASM_INIT(&me->super, par, me->prio); // initial tran. (virtual) + QS_FLUSH(); // flush the trace buffer to the host + + UINT tx_prio = QF_TX_PRIO_OFFSET + QF_MAX_ACTIVE - me->prio; + UINT tx_pt = QF_TX_PRIO_OFFSET + QF_MAX_ACTIVE - me->pthre; + tx_err = tx_thread_create( + &me->thread, // ThreadX thread control block + me->thread.tx_thread_name, // unique thread name + &thread_function, // thread function + (ULONG)me, // thread parameter + stkSto, // stack start + stkSize, // stack size in bytes + tx_prio, // ThreadX priority + tx_pt, // ThreadX preempt-threshold, see NOTE1 + TX_NO_TIME_SLICE, + TX_AUTO_START); + + QF_CRIT_ENTRY(); + Q_ASSERT_INCRIT(220, tx_err == TX_SUCCESS); + QF_CRIT_EXIT(); } -/*..........................................................................*/ +//............................................................................ void QActive_setAttr(QActive *const me, uint32_t attr1, void const *attr2) { - /* this function must be called before QACTIVE_START(), - * which implies that me->thread.tx_thread_name must not be used yet; - */ - Q_REQUIRE_ID(300, me->thread.tx_thread_name == (char *)0); + // this function must be called before QACTIVE_START(), + // which implies that me->thread.tx_thread_name must not be used yet; + // + QF_CRIT_STAT + QF_CRIT_ENTRY(); + Q_REQUIRE_INCRIT(300, me->thread.tx_thread_name == (char *)0); + switch (attr1) { case THREAD_NAME_ATTR: - /* temporarily store the name, cast 'const' away */ + // temporarily store the name, cast 'const' away me->thread.tx_thread_name = (char *)attr2; break; - /* ... */ + // ... } + QF_CRIT_EXIT(); } -/*..........................................................................*/ +//............................................................................ bool QActive_post_(QActive * const me, QEvt const * const e, uint_fast16_t const margin, void const * const sender) { - uint_fast16_t nFree; + QF_CRIT_STAT + QF_CRIT_ENTRY(); + + uint_fast16_t nFree = (uint_fast16_t)me->eQueue.tx_queue_available_storage; + bool status; - QF_CRIT_STAT_ - - QF_CRIT_E_(); - nFree = (uint_fast16_t)me->eQueue.tx_queue_available_storage; - if (margin == QF_NO_MARGIN) { if (nFree > 0U) { - status = true; /* can post */ + status = true; // can post } else { - status = false; /* cannot post */ - Q_ERROR_ID(510); /* must be able to post the event */ + status = false; // cannot post + Q_ERROR_INCRIT(510); // must be able to post the event } } else if (nFree > (QEQueueCtr)margin) { - status = true; /* can post */ + status = true; // can post } else { - status = false; /* cannot post */ + status = false; // cannot post } - if (status) { /* can post the event? */ + if (status) { // can post the event? - QS_BEGIN_NOCRIT_PRE_(QS_QF_ACTIVE_POST, me->prio) - QS_TIME_PRE_(); /* timestamp */ - QS_OBJ_PRE_(sender); /* the sender object */ - QS_SIG_PRE_(e->sig); /* the signal of the event */ - QS_OBJ_PRE_(me); /* this active object (recipient) */ - QS_2U8_PRE_(e->poolId_, e->refCtr_); /* pool Id & ref Count */ - QS_EQC_PRE_(nFree); /* # free entries available */ - QS_EQC_PRE_(0U); /* min # free entries (unknown) */ - QS_END_NOCRIT_PRE_() + QS_BEGIN_PRE_(QS_QF_ACTIVE_POST, me->prio) + QS_TIME_PRE_(); // timestamp + QS_OBJ_PRE_(sender); // the sender object + QS_SIG_PRE_(e->sig); // the signal of the event + QS_OBJ_PRE_(me); // this active object (recipient) + QS_2U8_PRE_(QEvt_getPoolId_(e), e->refCtr_); // pool-Id&ref-Count + QS_EQC_PRE_(nFree); // # free entries available + QS_EQC_PRE_(0U); // min # free entries (unknown) + QS_END_PRE_() - if (e->poolId_ != 0U) { /* is it a pool event? */ - QEvt_refCtr_inc_(e); /* increment the reference counter */ + if (QEvt_getPoolId_(e) != 0U) { // is it a pool event? + QEvt_refCtr_inc_(e); // increment the reference counter } + QF_CRIT_EXIT(); - QF_CRIT_X_(); + UINT tx_err = tx_queue_send(&me->eQueue, (VOID *)&e, TX_NO_WAIT); - /* posting to the ThreadX message queue must succeed, see NOTE1 */ - Q_ALLEGE_ID(520, - tx_queue_send(&me->eQueue, (VOID *)&e, TX_NO_WAIT) - == TX_SUCCESS); + // posting to the ThreadX message queue must succeed, see NOTE3 + QF_CRIT_ENTRY(); + Q_ASSERT_INCRIT(520, tx_err == TX_SUCCESS); + QF_CRIT_EXIT(); } else { - QS_BEGIN_NOCRIT_PRE_(QS_QF_ACTIVE_POST_ATTEMPT, me->prio) - QS_TIME_PRE_(); /* timestamp */ - QS_OBJ_PRE_(sender); /* the sender object */ - QS_SIG_PRE_(e->sig); /* the signal of the event */ - QS_OBJ_PRE_(me); /* this active object (recipient) */ - QS_2U8_PRE_(e->poolId_, e->refCtr_); /* pool Id & ref Count */ - QS_EQC_PRE_(nFree); /* # free entries available */ - QS_EQC_PRE_(0U); /* min # free entries (unknown) */ - QS_END_NOCRIT_PRE_() + QS_BEGIN_PRE_(QS_QF_ACTIVE_POST_ATTEMPT, me->prio) + QS_TIME_PRE_(); // timestamp + QS_OBJ_PRE_(sender); // the sender object + QS_SIG_PRE_(e->sig); // the signal of the event + QS_OBJ_PRE_(me); // this active object (recipient) + QS_2U8_PRE_(QEvt_getPoolId_(e), e->refCtr_); // pool-Id&ref-Count + QS_EQC_PRE_(nFree); // # free entries available + QS_EQC_PRE_(0U); // min # free entries (unknown) + QS_END_PRE_() - QF_CRIT_X_(); + QF_CRIT_EXIT(); } return status; } -/*..........................................................................*/ +//............................................................................ void QActive_postLIFO_(QActive * const me, QEvt const * const e) { - QF_CRIT_STAT_ - QF_CRIT_E_(); + QF_CRIT_STAT + QF_CRIT_ENTRY(); - QS_BEGIN_NOCRIT_PRE_(QS_QF_ACTIVE_POST_LIFO, me->prio) - QS_TIME_PRE_(); /* timestamp */ - QS_SIG_PRE_(e->sig); /* the signal of this event */ - QS_OBJ_PRE_(me); /* this active object */ - QS_2U8_PRE_(e->poolId_, e->refCtr_); /* pool Id & ref Count */ - QS_EQC_PRE_(me->eQueue.tx_queue_available_storage); /* # free */ - QS_EQC_PRE_(0U); /* min # free entries (unknown) */ - QS_END_NOCRIT_PRE_() + QS_BEGIN_PRE_(QS_QF_ACTIVE_POST_LIFO, me->prio) + QS_TIME_PRE_(); // timestamp + QS_SIG_PRE_(e->sig); // the signal of this event + QS_OBJ_PRE_(me); // this active object + QS_2U8_PRE_(QEvt_getPoolId_(e), e->refCtr_); // pool-Id&ref-Count + QS_EQC_PRE_(me->eQueue.tx_queue_available_storage); // # free + QS_EQC_PRE_(0U); // min # free entries (unknown) + QS_END_PRE_() - if (e->poolId_ != 0U) { /* is it a pool event? */ - QEvt_refCtr_inc_(e); /* increment the reference counter */ + if (QEvt_getPoolId_(e) != 0U) { // is it a pool event? + QEvt_refCtr_inc_(e); // increment the reference counter } + QF_CRIT_EXIT(); - QF_CRIT_X_(); + UINT tx_err = tx_queue_front_send(&me->eQueue, (VOID *)&e, TX_NO_WAIT); - /* LIFO posting must succeed, see NOTE1 */ - Q_ALLEGE_ID(610, - tx_queue_front_send(&me->eQueue, (VOID *)&e, TX_NO_WAIT) - == TX_SUCCESS); + // LIFO posting must succeed, see NOTE3 + QF_CRIT_ENTRY(); + Q_ASSERT_INCRIT(610, tx_err == TX_SUCCESS); + QF_CRIT_EXIT(); } -/*..........................................................................*/ +//............................................................................ QEvt const *QActive_get_(QActive * const me) { QEvt const *e; - QS_CRIT_STAT_ + UINT tx_err = tx_queue_receive(&me->eQueue, (VOID *)&e, TX_WAIT_FOREVER); - Q_ALLEGE_ID(710, - tx_queue_receive(&me->eQueue, (VOID *)&e, TX_WAIT_FOREVER) - == TX_SUCCESS); + QF_CRIT_STAT + QF_CRIT_ENTRY(); + Q_ASSERT_INCRIT(710, tx_err == TX_SUCCESS); QS_BEGIN_PRE_(QS_QF_ACTIVE_GET, me->prio) - QS_TIME_PRE_(); /* timestamp */ - QS_SIG_PRE_(e->sig); /* the signal of this event */ - QS_OBJ_PRE_(me); /* this active object */ - QS_2U8_PRE_(e->poolId_, e->refCtr_); /* pool Id & ref Count */ - QS_EQC_PRE_(me->eQueue.tx_queue_available_storage);/* # free */ + QS_TIME_PRE_(); // timestamp + QS_SIG_PRE_(e->sig); // the signal of this event + QS_OBJ_PRE_(me); // this active object + QS_2U8_PRE_(QEvt_getPoolId_(e), e->refCtr_); // pool-Id&ref-Count + QS_EQC_PRE_(me->eQueue.tx_queue_available_storage);// # free QS_END_PRE_() + QF_CRIT_EXIT(); return e; } -/*..........................................................................*/ +//............................................................................ void QFSchedLock_(QFSchedLock * const lockStat, uint_fast8_t prio) { - UINT tx_err; lockStat->lockHolder = tx_thread_identify(); - /*! @pre must be thread level, so current TX thread must be valid */ - Q_REQUIRE_ID(800, lockStat->lockHolder != (TX_THREAD *)0); + QF_CRIT_STAT + QF_CRIT_ENTRY(); + // must be in thread context, so current TX thread must be valid + Q_REQUIRE_INCRIT(800, lockStat->lockHolder != (TX_THREAD *)0); + QF_CRIT_EXIT(); - /* change the preemption threshold of the current thread */ - tx_err = tx_thread_preemption_change(lockStat->lockHolder, + // change the preemption threshold of the current thread + UINT tx_err = tx_thread_preemption_change(lockStat->lockHolder, (QF_TX_PRIO_OFFSET + QF_MAX_ACTIVE - prio), &lockStat->prevThre); if (tx_err == TX_SUCCESS) { - QS_CRIT_STAT_ lockStat->lockPrio = prio; + QF_CRIT_ENTRY(); QS_BEGIN_PRE_(QS_SCHED_LOCK, 0U) - QS_TIME_PRE_(); /* timestamp */ + QS_TIME_PRE_(); // timestamp QS_2U8_PRE_((QF_TX_PRIO_OFFSET + QF_MAX_ACTIVE - lockStat->prevThre), - prio); /* new lock prio */ + prio); // new lock prio QS_END_PRE_() + QF_CRIT_EXIT(); } else if (tx_err == TX_THRESH_ERROR) { - /* threshold was greater than (lower prio) than the current prio */ - lockStat->lockPrio = 0U; /* threshold not changed */ + // threshold was greater than (lower prio) than the current prio + lockStat->lockPrio = 0U; // threshold not changed } else { - /* no other errors are tolerated */ - Q_ERROR_ID(810); + // no other errors are tolerated + QF_CRIT_ENTRY(); + Q_ERROR_INCRIT(810); + //QF_CRIT_EXIT(); } } -/*..........................................................................*/ +//............................................................................ void QFSchedUnlock_(QFSchedLock const * const lockStat) { - UINT old_thre; - QS_CRIT_STAT_ - /*! @pre the lock holder must be valid and the scheduler must be locked */ - Q_REQUIRE_ID(900, (lockStat->lockHolder != (TX_THREAD *)0) + QF_CRIT_STAT + QF_CRIT_ENTRY(); + // the lock holder must be valid and the scheduler must be locked + Q_REQUIRE_INCRIT(900, (lockStat->lockHolder != (TX_THREAD *)0) && (lockStat->lockPrio != 0U)); - QS_BEGIN_PRE_(QS_SCHED_LOCK, 0U) - QS_TIME_PRE_(); /* timestamp */ - QS_2U8_PRE_(lockStat->lockPrio, /* prev lock prio */ + QS_BEGIN_PRE_(QS_SCHED_UNLOCK, 0U) + QS_TIME_PRE_(); // timestamp + QS_2U8_PRE_(lockStat->lockPrio, // prev lock prio (QF_TX_PRIO_OFFSET + QF_MAX_ACTIVE - - lockStat->prevThre)); /* new lock prio */ + - lockStat->prevThre)); // new lock prio QS_END_PRE_() + QF_CRIT_EXIT(); - /* restore the preemption threshold of the lock holder */ - Q_ALLEGE_ID(910, tx_thread_preemption_change(lockStat->lockHolder, + // restore the preemption threshold of the lock holder + UINT old_thre; + UINT tx_err = tx_thread_preemption_change(lockStat->lockHolder, lockStat->prevThre, - &old_thre) == TX_SUCCESS); + &old_thre); + QF_CRIT_ENTRY(); + Q_ASSERT_INCRIT(910, tx_err == TX_SUCCESS); + QF_CRIT_EXIT(); } +//============================================================================ +// NOTE1: +// When QF preemption threshold is NOT specified (upper byte of prio is 0), +// QActive_register_() will set me->pthre equal to me->prio, which means +// that tx_pt == tx_prio. In that case the call to ThreadX tx_thread_create() +// will disable the ThreadX preemption-threshold for this thread. +// +// NOTE3: +// The event posting to ThreadX message queue occurs OUTSIDE critical section, +// which means that the remaining margin of available slots in the queue +// cannot be guaranteed. The problem is that interrupts and other tasks can +// preempt the event posting after checking the margin, but before actually +// posting the event to the queue. +// diff --git a/ports/threadx/qf_port.h b/ports/threadx/qf_port.h deleted file mode 100644 index 046a2099..00000000 --- a/ports/threadx/qf_port.h +++ /dev/null @@ -1,134 +0,0 @@ -/*============================================================================ -* QP/C Real-Time Embedded Framework (RTEF) -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2022-06-12 -* @version Last updated for: @ref qpc_7_0_1 -* -* @file -* @brief QF/C, port to ThreadX -*/ -#ifndef QF_PORT_H -#define QF_PORT_H - -/* ThreadX event queue and thread types */ -#define QF_EQUEUE_TYPE TX_QUEUE -#define QF_THREAD_TYPE TX_THREAD -#define QF_OS_OBJECT_TYPE uint8_t - -/* QF priority offset within ThreadX priority numbering scheme, see NOTE1 */ -#define QF_TX_PRIO_OFFSET 8U - -/* The maximum number of active objects in the application, see NOTE2 */ -#define QF_MAX_ACTIVE (31U - QF_TX_PRIO_OFFSET) - -/* QF critical section for ThreadX, see NOTE3 */ -#define QF_CRIT_STAT_TYPE UINT -#define QF_CRIT_ENTRY(stat_) ((stat_) = tx_interrupt_control(TX_INT_DISABLE)) -#define QF_CRIT_EXIT(stat_) ((void)tx_interrupt_control(stat_)) - -enum ThreadX_ThreadAttrs { - THREAD_NAME_ATTR -}; - -#include "tx_api.h" /* ThreadX API */ - -#include "qep_port.h" /* QEP port */ -#include "qequeue.h" /* native QF event queue for deferring events */ -#include "qmpool.h" /* native QF event pool */ -#include "qf.h" /* QF platform-independent public interface */ - -/***************************************************************************** -* interface used only inside QF, but not in applications -*/ -#ifdef QP_IMPL - - /*! ThreadX-specific scheduler locking (implemented in qf_port.c) */ - typedef struct { - uint_fast8_t lockPrio; /*!< lock prio [QF numbering scheme] */ - UINT prevThre; /*!< previoius preemption threshold */ - TX_THREAD *lockHolder; /*!< the thread holding the lock */ - } QFSchedLock; - - #define QF_SCHED_STAT_ QFSchedLock lockStat_; - #define QF_SCHED_LOCK_(prio_) do { \ - if (TX_THREAD_GET_SYSTEM_STATE() != 0U) { \ - lockStat_.lockPrio = 0U; \ - } else { \ - QFSchedLock_(&lockStat_, (prio_)); \ - } \ - } while (false) - - #define QF_SCHED_UNLOCK_() do { \ - if (lockStat_.lockPrio != 0U) { \ - QFSchedUnlock_(&lockStat_); \ - } \ - } while (false) - - /* internal implementation of scheduler locking/unlocking */ - void QFSchedLock_(QFSchedLock * const lockStat, uint_fast8_t prio); - void QFSchedUnlock_(QFSchedLock const * const lockStat); - /* internal TX interrupt counter for TX_THREAD_GET_SYSTEM_STATE() */ - extern ULONG volatile _tx_thread_system_state; - - /* native QF event pool operations */ - #define QF_EPOOL_TYPE_ QMPool - #define QF_EPOOL_INIT_(p_, poolSto_, poolSize_, evtSize_) \ - (QMPool_init(&(p_), (poolSto_), (poolSize_), (evtSize_))) - #define QF_EPOOL_EVENT_SIZE_(p_) ((uint_fast16_t)(p_).blockSize) - #define QF_EPOOL_GET_(p_, e_, m_, qs_id_) \ - ((e_) = (QEvt *)QMPool_get(&(p_), (m_), (qs_id_))) - #define QF_EPOOL_PUT_(p_, e_, qs_id_) \ - (QMPool_put(&(p_), (e_), (qs_id_))) - -#endif /* ifdef QP_IMPL */ - -/***************************************************************************** -* NOTE1: -* QF_TX_PRIO_OFFSET specifies the number of highest-urgency ThreadX -* priorities not available to QP active objects. These highest-urgency -* priorities might be used by ThreadX threads that run "above" QP active -* objects. -* -* Because the ThreadX priority numbering is "upside down" compared -* to the QP priority numbering, the ThreadX priority for an active object -* thread is calculated as follows: -* tx_prio = QF_TX_PRIO_OFFSET + QF_MAX_ACTIVE - qp_prio -* -* NOTE2: -* The maximum number of active objects in QP can be increased to 63, -* inclusive, but it can be reduced to save some memory. Also, the number of -* active objects cannot exceed the number of TreadX thread priorities -* TX_MAX_PRIORITIES, because each QP active object requires a unique -* priority level. Due to the artificial limitations of the ThreadX demo -* for Windows, QF_MAX_ACTIVE is set here lower to not exceed the total -* available priority levels. -* -* NOTE3: -* The ThreadX critical section must be able to nest, which is the case with -* the tx_interrupt_control() API. -*/ - -#endif /* QF_PORT_H */ - diff --git a/ports/threadx/qp_port.h b/ports/threadx/qp_port.h new file mode 100644 index 00000000..57c313b2 --- /dev/null +++ b/ports/threadx/qp_port.h @@ -0,0 +1,136 @@ +//============================================================================ +// QP/C Real-Time Embedded Framework (RTEF) +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +//============================================================================ +//! @date Last updated on: 2023-09-07 +//! @version Last updated for: @ref qpc_7_3_0 +//! +//! @file +//! @brief QP/C, port to ThreadX, generic C11 compiler + +#ifndef QP_PORT_H_ +#define QP_PORT_H_ + +#include // Exact-width types. WG14/N843 C99 Standard +#include // Boolean type. WG14/N843 C99 Standard + +#ifdef QP_CONFIG +#include "qp_config.h" // external QP configuration +#endif + +// no-return function specifier (C11 Standard) +#define Q_NORETURN _Noreturn void + +// ThreadX event queue and thread types +#define QACTIVE_EQUEUE_TYPE TX_QUEUE +#define QACTIVE_THREAD_TYPE TX_THREAD +#define QACTIVE_OS_OBJ_TYPE uint8_t + +// QF priority offset within ThreadX priority numbering scheme, see NOTE1 +#define QF_TX_PRIO_OFFSET 8U + +// QF critical section for ThreadX, see NOTE3 +#define QF_CRIT_STAT UINT int_ctrl_; +#define QF_CRIT_ENTRY() (int_ctrl_ = tx_interrupt_control(TX_INT_DISABLE)) +#define QF_CRIT_EXIT() ((void)tx_interrupt_control(int_ctrl_)) + +enum ThreadX_ThreadAttrs { + THREAD_NAME_ATTR +}; + +// include files ------------------------------------------------------------- +#include "tx_api.h" // ThreadX API + +#include "qequeue.h" // QP native QF event queue for deferring events +#include "qmpool.h" // QP native QF event pool +#include "qp.h" // QP platform-independent public interface + +//============================================================================ +// interface used only inside QF implementation, but not in applications +#ifdef QP_IMPL + + //! ThreadX-specific scheduler locking (implemented in qf_port.c) + typedef struct { + uint_fast8_t lockPrio; //!< lock prio [QF numbering scheme] + UINT prevThre; //!< previoius preemption threshold + TX_THREAD *lockHolder; //!< the thread holding the lock + } QFSchedLock; + + // ThreadX-specific scheduler locking (implemented in qf_port.cpp) + #define QF_SCHED_STAT_ QFSchedLock lockStat_; + #define QF_SCHED_LOCK_(prio_) do { \ + if (TX_THREAD_GET_SYSTEM_STATE() != 0U) { \ + lockStat_.lockPrio = 0U; \ + } else { \ + QFSchedLock_(&lockStat_, (prio_)); \ + } \ + } while (false) + + #define QF_SCHED_UNLOCK_() do { \ + if (lockStat_.lockPrio != 0U) { \ + QFSchedUnlock_(&lockStat_); \ + } \ + } while (false) + + // internal implementation of scheduler locking/unlocking + void QFSchedLock_(QFSchedLock * const lockStat, uint_fast8_t prio); + void QFSchedUnlock_(QFSchedLock const * const lockStat); + // internal TX interrupt counter for TX_THREAD_GET_SYSTEM_STATE() + extern ULONG volatile _tx_thread_system_state; + + // native QF event pool customization + #define QF_EPOOL_TYPE_ QMPool + #define QF_EPOOL_INIT_(p_, poolSto_, poolSize_, evtSize_) \ + (QMPool_init(&(p_), (poolSto_), (poolSize_), (evtSize_))) + #define QF_EPOOL_EVENT_SIZE_(p_) ((uint_fast16_t)(p_).blockSize) + #define QF_EPOOL_GET_(p_, e_, m_, qs_id_) \ + ((e_) = (QEvt *)QMPool_get(&(p_), (m_), (qs_id_))) + #define QF_EPOOL_PUT_(p_, e_, qs_id_) \ + (QMPool_put(&(p_), (e_), (qs_id_))) + +#endif // QP_IMPL + +//============================================================================ +// NOTE1: +// QF_TX_PRIO_OFFSET specifies the number of highest-urgency ThreadX +// priorities not available to QP active objects. These highest-urgency +// priorities might be used by ThreadX threads that run "above" QP active +// objects. +// +// Because the ThreadX priority numbering is "upside down" compared +// to the QP priority numbering, the ThreadX priority for an active object +// thread is calculated as follows: +// tx_prio = QF_TX_PRIO_OFFSET + QF_MAX_ACTIVE - qp_prio +// +// NOTE3: +// The ThreadX critical section must be able to nest, which is the case with +// the tx_interrupt_control() API. +// + +#endif // QP_PORT_H_ + diff --git a/ports/threadx/qs_port.h b/ports/threadx/qs_port.h index b1c77d47..2350d92f 100644 --- a/ports/threadx/qs_port.h +++ b/ports/threadx/qs_port.h @@ -1,60 +1,60 @@ -/*============================================================================ -* QP/C Real-Time Embedded Framework (RTEF) -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2022-06-12 -* @version Last updated for: @ref qpc_7_0_1 -* -* @file -* @brief QS/C port to a 32-bit CPU and a generic C99 compiler. -* @description -* This is an example of a QP/C port with the documentation for the -* configuration macros and includes. -*/ -#ifndef QS_PORT_H -#define QS_PORT_H +//============================================================================ +// QP/C Real-Time Embedded Framework (RTEF) +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +//============================================================================ +//! @date Last updated on: 2023-08-16 +//! @version Last updated for: @ref qpc_7_3_0 +//! +//! @file +//! @brief QS/C port to a 32-bit CPU and a generic C11 compiler. +//! @description +//! This is an example of a QP/C port with the documentation for the +//! configuration macros and includes. -/* QS time-stamp size in bytes */ +#ifndef QS_PORT_H_ +#define QS_PORT_H_ + +// QS time-stamp size in bytes #define QS_TIME_SIZE 4U -/* object pointer size in bytes */ +// object pointer size in bytes #define QS_OBJ_PTR_SIZE 4U -/* function pointer size in bytes */ +// function pointer size in bytes #define QS_FUN_PTR_SIZE 4U -/*==========================================================================*/ -/* NOTE: QS might be used with or without other QP components, in which -* case the separate definitions of the macros QF_CRIT_STAT_TYPE, -* QF_CRIT_ENTRY, and QF_CRIT_EXIT are needed. In this port QS is configured -* to be used with the other QP component, by simply including "qf_port.h" -* *before* "qs.h". -*/ -#ifndef QF_PORT_H -#include "qf_port.h" /* use QS with QF */ +//============================================================================ +// NOTE: QS might be used with or without other QP components, in which +// case the separate definitions of the macros QF_CRIT_STAT, QF_CRIT_ENTRY(), +// and QF_CRIT_EXIT() are needed. In this port QS is configured to be used +// with the other QP component, by simply including "qp_port.h" +//*before* "qs.h". +// +#ifndef QP_PORT_H_ +#include "qp_port.h" // use QS with QP #endif -#include "qs.h" /* QS platform-independent public interface */ +#include "qs.h" // QS platform-independent public interface + +#endif // QS_PORT_H_ -#endif /* QS_PORT_H */ diff --git a/ports/uc-os2/qep_port.h b/ports/uc-os2/qep_port.h deleted file mode 100644 index f7a5a9a8..00000000 --- a/ports/uc-os2/qep_port.h +++ /dev/null @@ -1,40 +0,0 @@ -/*============================================================================ -* QP/C Real-Time Embedded Framework (RTEF) -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2023-01-07 -* @version Last updated for: @ref qpc_7_2_0 -* -* @file -* @brief QEP/C port, generic C99 compiler -*/ -#ifndef QEP_PORT_H -#define QEP_PORT_H - -#include /* Exact-width types. WG14/N843 C99 Standard */ -#include /* Boolean type. WG14/N843 C99 Standard */ - -#include "qep.h" /* QEP platform-independent public interface */ - -#endif /* QEP_PORT_H */ diff --git a/ports/uc-os2/qf_port.c b/ports/uc-os2/qf_port.c index f6e2f11c..e2b1d820 100644 --- a/ports/uc-os2/qf_port.c +++ b/ports/uc-os2/qf_port.c @@ -1,272 +1,301 @@ -/*============================================================================ -* QP/C Real-Time Embedded Framework (RTEF) -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2023-01-07 -* @version Last updated for: @ref qpc_7_2_0 -* -* @file -* @brief QF/C port to uC-OS2, generic C99 compiler -*/ -#define QP_IMPL /* this is QP implementation */ -#include "qf_port.h" /* QF port */ -#include "qf_pkg.h" -#include "qassert.h" -#ifdef Q_SPY /* QS software tracing enabled? */ - #include "qs_port.h" /* QS port */ - #include "qs_pkg.h" /* QS package-scope internal interface */ +//============================================================================ +// QP/C Real-Time Embedded Framework (RTEF) +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +//============================================================================ +//! @date Last updated on: 2023-08-30 +//! @version Last updated for: @ref qpc_7_3_0 +//! +//! @file +//! @brief QP/C port to uC-OS2, generic C11 compiler +//! +#define QP_IMPL // this is QP implementation +#include "qp_port.h" // QP port +#include "qp_pkg.h" // QP package-scope interface +#include "qsafe.h" // QP Functional Safety (FuSa) System +#ifdef Q_SPY // QS software tracing enabled? + #include "qs_port.h" // QS port + #include "qs_pkg.h" // QS package-scope internal interface #else - #include "qs_dummy.h" /* disable the QS software tracing */ -#endif /* Q_SPY */ + #include "qs_dummy.h" // disable the QS software tracing +#endif // Q_SPY Q_DEFINE_THIS_MODULE("qf_port") -/* Local objects -----------------------------------------------------------*/ -static void task_function(void *pdata); /* uC-OS2 task signature */ +// Local objects ----------------------------------------------------------- +static void task_function(void *pdata); // uC-OS2 task signature -/*..........................................................................*/ +//............................................................................ void QF_init(void) { - OSInit(); /* initialize uC-OS2 */ + OSInit(); // initialize uC-OS2 } -/*..........................................................................*/ +//............................................................................ int_t QF_run(void) { - QF_onStartup(); /* QF callback to configure and start interrupts */ + QF_onStartup(); // QF callback to configure and start interrupts - /* produce the QS_QF_RUN trace record */ - QS_CRIT_STAT_ + // produce the QS_QF_RUN trace record + QS_CRIT_STAT + QS_CRIT_ENTRY(); QS_BEGIN_PRE_(QS_QF_RUN, 0U) QS_END_PRE_() + QS_CRIT_EXIT(); - OSStart(); /* start uC-OS2 multitasking */ - Q_ERROR_ID(100); /* OSStart() should never return */ - return 0; /* this unreachable return keeps the compiler happy */ + OSStart(); // start uC-OS2 multitasking, should never return + + return 0; // this unreachable return keeps the compiler happy } -/*..........................................................................*/ +//............................................................................ void QF_stop(void) { - QF_onCleanup(); /* cleanup callback */ + QF_onCleanup(); // cleanup callback } -/*..........................................................................*/ +//............................................................................ +static void task_function(void *pdata) { // uC-OS2 task signature + QActive *act = (QActive *)pdata; + + // event-loop + for (;;) { // for-ever + QEvt const *e = QActive_get_((QActive *)pdata); + // dispatch event (virtual call) + (*act->super.vptr->dispatch)(&act->super, e, act->prio); + QF_gc(e); // check if the event is garbage, and collect it if so + } + //act->unregister_(); // remove this object from QF +} + +//............................................................................ void QActive_start_(QActive * const me, QPrioSpec const prioSpec, QEvt const * * const qSto, uint_fast16_t const qLen, void * const stkSto, uint_fast16_t const stkSize, void const * const par) { - /* task name to be passed to OSTaskCreateExt() */ + // task name to be passed to OSTaskCreateExt() void * const task_name = (void *)me->eQueue; - me->eQueue = OSQCreate((void **)qSto, qLen); /* create uC-OS2 queue */ - /* the uC-OS2 queue must be created correctly */ - Q_ASSERT_ID(210, me->eQueue != (OS_EVENT *)0); + // create uC-OS2 queue and make sure it was created correctly + me->eQueue = OSQCreate((void **)qSto, qLen); // create uC-OS2 queue - me->prio = (uint8_t)(prioSpec & 0xFFU); /* QF-priority of the AO */ - me->pthre = (uint8_t)(prioSpec >> 8U); /* preemption-threshold */ - QActive_register_(me); /* register this AO */ + QF_CRIT_STAT + QF_CRIT_ENTRY(); + // the uC-OS2 queue must be created correctly + Q_ASSERT_INCRIT(210, me->eQueue != (OS_EVENT *)0); + QF_CRIT_EXIT(); - QHSM_INIT(&me->super, par, me->prio); /* initial tran. (virtual) */ - QS_FLUSH(); /* flush the trace buffer to the host */ + me->prio = (uint8_t)(prioSpec & 0xFFU); // QF-priority of the AO + me->pthre = 0U; // preemption-threshold (not used) + QActive_register_(me); // make QF aware of this AO - /* map from QP to uC/OS priority */ + // top-most initial tran. (virtual call) + (*me->super.vptr->init)(&me->super, par, me->prio); + QS_FLUSH(); // flush the trace buffer to the host + + // map from QP to uC-OS2 priority INT8U const p_ucos = (INT8U)(QF_MAX_ACTIVE - me->prio); - /* create AO's task... */ - /* - * NOTE: The call to uC-OS2 API OSTaskCreateExt() assumes that the - * pointer to the top-of-stack (ptos) is at the end of the provided - * stack memory. This is correct only for CPUs with downward-growing - * stack, but must be changed for CPUs with upward-growing stack - */ - INT8U const err = OSTaskCreateExt(&task_function, /* the task function */ - (void *)me, /* the 'pdata' parameter */ + // create AO's task... + // + // NOTE: The call to uC-OS2 API OSTaskCreateExt() assumes that the + // pointer to the top-of-stack (ptos) is at the end of the provided + // stack memory. This is correct only for CPUs with downward-growing + // stack, but must be changed for CPUs with upward-growing stack + INT8U const err = OSTaskCreateExt(&task_function, // the task function + (void *)me, // the 'pdata' parameter #if OS_STK_GROWTH - &((OS_STK *)stkSto)[(stkSize/sizeof(OS_STK)) - 1], /* ptos */ + &((OS_STK *)stkSto)[(stkSize/sizeof(OS_STK)) - 1], // ptos #else - (OS_STK *)stkSto, /* ptos */ + (OS_STK *)stkSto, // ptos #endif - p_ucos, /* uC-OS2 task priority */ - (INT16U)me->prio, /* the unique AO priority as task ID */ + p_ucos, // uC-OS2 task priority + (INT16U)me->prio, // the unique AO priority as task ID #if OS_STK_GROWTH - (OS_STK *)stkSto, /* pbos */ + (OS_STK *)stkSto, // pbos #else - &((OS_STK *)stkSto)[(stkSize/sizeof(OS_STK)) - 1], /* pbos */ + &((OS_STK *)stkSto)[(stkSize/sizeof(OS_STK)) - 1], // pbos #endif - (INT32U)(stkSize/sizeof(OS_STK)),/* stack size in OS_STK units */ - task_name, /* pext */ - (INT16U)me->thread); /* task options, see NOTE1 */ + (INT32U)(stkSize/sizeof(OS_STK)), // stack size in OS_STK units + task_name, // pext + (INT16U)me->thread); // task options, see NOTE1 - /* uC-OS2 task must be created correctly */ - Q_ENSURE_ID(220, err == OS_ERR_NONE); + QF_CRIT_ENTRY(); + // uC-OS2 task must be created correctly + Q_ASSERT_INCRIT(220, err == OS_ERR_NONE); + QF_CRIT_EXIT(); } -/*..........................................................................*/ +//............................................................................ +// NOTE: This function must be called BEFORE starting an active object void QActive_setAttr(QActive *const me, uint32_t attr1, void const *attr2) { + QF_CRIT_STAT + QF_CRIT_ENTRY(); switch (attr1) { case TASK_NAME_ATTR: - /* this function must be called before QACTIVE_START(), - * which implies that me->eQueue must not be used yet; - */ - Q_ASSERT_ID(300, me->eQueue == (OS_EVENT *)0); - /* temporarily store the name, cast 'const' away */ + // this function must be called before QACTIVE_START(), + // which implies that me->eQueue must not be used yet; + Q_ASSERT_INCRIT(300, me->eQueue == (OS_EVENT *)0); + // temporarily store the name, cast 'const' away me->eQueue = (OS_EVENT *)attr2; break; - /* ... */ + // ... default: me->thread = attr1; break; } + QF_CRIT_EXIT(); } -/*..........................................................................*/ -static void task_function(void *pdata) { /* uC-OS2 task signature */ - /* event-loop */ - for (;;) { /* for-ever */ - QEvt const *e = QActive_get_((QActive *)pdata); - /* dispatch to the AO's SM */ - QHSM_DISPATCH((QHsm *)pdata, e, ((QActive *)pdata)->prio); - QF_gc(e); /* check if the event is garbage, and collect it if so */ - } -} -/*..........................................................................*/ +//............................................................................ bool QActive_post_(QActive * const me, QEvt const * const e, uint_fast16_t const margin, void const * const sender) { - QF_CRIT_STAT_ - QF_CRIT_E_(); + QF_CRIT_STAT + QF_CRIT_ENTRY(); uint_fast16_t const nFree = (uint_fast16_t)(((OS_Q_DATA *)me->eQueue)->OSQSize - ((OS_Q_DATA *)me->eQueue)->OSNMsgs); bool status; if (margin == QF_NO_MARGIN) { if (nFree > 0U) { - status = true; /* can post */ + status = true; // can post } else { - status = false; /* cannot post */ - Q_ERROR_ID(710); /* must be able to post the event */ + status = false; // cannot post + Q_ERROR_INCRIT(710); // must be able to post the event } } else if (nFree > (QEQueueCtr)margin) { - status = true; /* can post */ + status = true; // can post } else { - status = false; /* cannot post */ + status = false; // cannot post } - if (status) { /* can post the event? */ + if (status) { // can post the event? - QS_BEGIN_NOCRIT_PRE_(QS_QF_ACTIVE_POST, me->prio) - QS_TIME_PRE_(); /* timestamp */ - QS_OBJ_PRE_(sender); /* the sender object */ - QS_SIG_PRE_(e->sig); /* the signal of the event */ - QS_OBJ_PRE_(me); /* this active object (recipient) */ - QS_2U8_PRE_(e->poolId_, e->refCtr_); /* pool Id & ref Count */ - QS_EQC_PRE_(nFree); /* # free entries */ - QS_EQC_PRE_(0U); /* min # free entries (unknown) */ - QS_END_NOCRIT_PRE_() + QS_BEGIN_PRE_(QS_QF_ACTIVE_POST, me->prio) + QS_TIME_PRE_(); // timestamp + QS_OBJ_PRE_(sender); // the sender object + QS_SIG_PRE_(e->sig); // the signal of the event + QS_OBJ_PRE_(me); // this active object (recipient) + QS_2U8_PRE_(QEvt_getPoolId_(e), e->refCtr_);// pool-Id & ref-Count + QS_EQC_PRE_(nFree); // # free entries + QS_EQC_PRE_(0U); // min # free entries (unknown) + QS_END_PRE_() - if (e->poolId_ != 0U) { /* is it a pool event? */ - QEvt_refCtr_inc_(e); /* increment the reference counter */ + if (QEvt_getPoolId_(e) != 0U) { // is it a pool event? + QEvt_refCtr_inc_(e); // increment the reference counter } - QF_CRIT_X_(); + QF_CRIT_EXIT(); - /* posting the event to uC-OS2 message queue must succeed */ - Q_ALLEGE_ID(720, - OSQPost(me->eQueue, (void *)e) == OS_ERR_NONE); + INT8U err = OSQPost(me->eQueue, (void *)e); + + QF_CRIT_ENTRY(); + // posting to uC-OS2 message queue must succeed, see NOTE3 + Q_ASSERT_INCRIT(720, err == OS_ERR_NONE); + QF_CRIT_EXIT(); } else { - QS_BEGIN_NOCRIT_PRE_(QS_QF_ACTIVE_POST_ATTEMPT, me->prio) - QS_TIME_PRE_(); /* timestamp */ - QS_OBJ_PRE_(sender); /* the sender object */ - QS_SIG_PRE_(e->sig); /* the signal of the event */ - QS_OBJ_PRE_(me); /* this active object (recipient) */ - QS_2U8_PRE_(e->poolId_, e->refCtr_); /* pool Id & ref Count */ - QS_EQC_PRE_(nFree); /* # free entries available */ - QS_EQC_PRE_(margin); /* margin requested */ - QS_END_NOCRIT_PRE_() + QS_BEGIN_PRE_(QS_QF_ACTIVE_POST_ATTEMPT, me->prio) + QS_TIME_PRE_(); // timestamp + QS_OBJ_PRE_(sender); // the sender object + QS_SIG_PRE_(e->sig); // the signal of the event + QS_OBJ_PRE_(me); // this active object (recipient) + QS_2U8_PRE_(QEvt_getPoolId_(e), e->refCtr_);// pool-Id & ref-Count + QS_EQC_PRE_(nFree); // # free entries available + QS_EQC_PRE_(margin); // margin requested + QS_END_PRE_() - QF_CRIT_X_(); + QF_CRIT_EXIT(); } return status; } -/*..........................................................................*/ +//............................................................................ void QActive_postLIFO_(QActive * const me, QEvt const * const e) { - QF_CRIT_STAT_ - QF_CRIT_E_(); + QF_CRIT_STAT + QF_CRIT_ENTRY(); - QS_BEGIN_NOCRIT_PRE_(QS_QF_ACTIVE_POST_LIFO, me->prio) - QS_TIME_PRE_(); /* timestamp */ - QS_SIG_PRE_(e->sig); /* the signal of this event */ - QS_OBJ_PRE_(me); /* this active object */ - QS_2U8_PRE_(e->poolId_, e->refCtr_); /* pool Id & ref Count */ + QS_BEGIN_PRE_(QS_QF_ACTIVE_POST_LIFO, me->prio) + QS_TIME_PRE_(); // timestamp + QS_SIG_PRE_(e->sig); // the signal of this event + QS_OBJ_PRE_(me); // this active object + QS_2U8_PRE_(QEvt_getPoolId_(e), e->refCtr_); // pool-Id & ref-Count QS_EQC_PRE_(((OS_Q *)me->eQueue)->OSQSize - - ((OS_Q *)me->eQueue)->OSQEntries); /* # free entries */ - QS_EQC_PRE_(0U); /* min # free entries (unknown) */ - QS_END_NOCRIT_PRE_() + - ((OS_Q *)me->eQueue)->OSQEntries); // # free entries + QS_EQC_PRE_(0U); // min # free entries (unknown) + QS_END_PRE_() - if (e->poolId_ != 0U) { /* is it a pool event? */ - QEvt_refCtr_inc_(e); /* increment the reference counter */ + if (QEvt_getPoolId_(e) != 0U) { // is it a pool event? + QEvt_refCtr_inc_(e); // increment the reference counter } + QF_CRIT_EXIT(); - QF_CRIT_X_(); + INT8U err = OSQPostFront((OS_EVENT *)me->eQueue, (void *)e); - /* posting the event to uC/OS message queue must succeed */ - Q_ALLEGE_ID(810, - OSQPostFront((OS_EVENT *)me->eQueue, (void *)e) == OS_ERR_NONE); + QF_CRIT_ENTRY(); + // posting to uC-OS2 message queue must succeed, see NOTE3 + Q_ASSERT_INCRIT(810, err == OS_ERR_NONE); + QF_CRIT_EXIT(); } -/*..........................................................................*/ +//............................................................................ QEvt const *QActive_get_(QActive * const me) { INT8U err; - QEvt const *e = (QEvt *)OSQPend((OS_EVENT *)me->eQueue, 0U, &err); + QEvt const *e = (QEvt const *)OSQPend((OS_EVENT *)me->eQueue, 0U, &err); - Q_ASSERT_ID(910, err == OS_ERR_NONE); + QF_CRIT_STAT + QF_CRIT_ENTRY(); + Q_ASSERT_INCRIT(910, err == OS_ERR_NONE); - QS_CRIT_STAT_ QS_BEGIN_PRE_(QS_QF_ACTIVE_GET, me->prio) - QS_TIME_PRE_(); /* timestamp */ - QS_SIG_PRE_(e->sig); /* the signal of this event */ - QS_OBJ_PRE_(me); /* this active object */ - QS_2U8_PRE_(e->poolId_, e->refCtr_); /* pool Id & ref Count */ + QS_TIME_PRE_(); // timestamp + QS_SIG_PRE_(e->sig); // the signal of this event + QS_OBJ_PRE_(me); // this active object + QS_2U8_PRE_(QEvt_getPoolId_(e), e->refCtr_); // pool-Id & ref-Count QS_EQC_PRE_(((OS_Q *)me->eQueue)->OSQSize - - ((OS_Q *)me->eQueue)->OSQEntries); /* # free entries */ + - ((OS_Q *)me->eQueue)->OSQEntries); // # free entries QS_END_PRE_() + QF_CRIT_EXIT(); return e; } -/***************************************************************************** -* NOTE0: -* The QF_onStartup() should enter the critical section before configuring -* and starting interrupts and it should NOT exit the critical section. -* Thus the interrupts cannot fire until uC-OS2 starts multitasking -* in OSStart(). This is to prevent a (narrow) time window in which interrupts -* could make some tasks ready to run, but the OS would not be ready yet -* to perform context switch. -* -* NOTE1: -* The member QActive.thread is set to the uC-OS2 task options in the -* function QF_setUCosTaskAttr(), which must be called **before** -* QACTIVE_START(). -*/ +//============================================================================ +// NOTE0: +// The QF_onStartup() should enter the critical section before configuring +// and starting interrupts and it should NOT exit the critical section. +// Thus the interrupts cannot fire until uC-OS2 starts multitasking +// in OSStart(). This is to prevent a (narrow) time window in which interrupts +// could make some tasks ready to run, but the OS would not be ready yet +// to perform context switch. +// +// NOTE1: +// The member QActive.thread is set to the uC-OS2 task options in the +// function QF_setUCosTaskAttr(), which must be called **before** +// QACTIVE_START(). +// +// NOTE3: +// The event posting to uC-OS2 message queue occurs OUTSIDE critical section, +// which means that the remaining margin of available slots in the queue +// cannot be guaranteed. The problem is that interrupts and other tasks can +// preempt the event posting after checking the margin, but before actually +// posting the event to the queue. + diff --git a/ports/uc-os2/qf_port.h b/ports/uc-os2/qf_port.h deleted file mode 100644 index 7929f083..00000000 --- a/ports/uc-os2/qf_port.h +++ /dev/null @@ -1,119 +0,0 @@ -/*============================================================================ -* QP/C Real-Time Embedded Framework (RTEF) -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2023-01-07 -* @version Last updated for: @ref qpc_7_2_0 -* -* @file -* @brief QF/C port to uC-OS2, generic C99 compiler -*/ -#ifndef QF_PORT_H -#define QF_PORT_H - -/* uC-OS2 event queue and thread types */ -#define QF_EQUEUE_TYPE OS_EVENT * -#define QF_THREAD_TYPE uint32_t - -/* The maximum number of active objects in the application */ -#define QF_MAX_ACTIVE ((OS_LOWEST_PRIO - 2 < 64) ? (OS_LOWEST_PRIO - 2) : 64U) - -#include "ucos_ii.h" /* uC-OS2 API, port and compile-time configuration */ - -/* uC-OS2 crtitical section, NOTE1 */ -#if (OS_CRITICAL_METHOD == 1u) - /* QF_CRIT_STAT_TYPE not defined */ - #define QF_CRIT_ENTRY(dummy) OS_ENTER_CRITICAL() - #define QF_CRIT_EXIT(dummy) OS_EXIT_CRITICAL() -#elif (OS_CRITICAL_METHOD == 3u) - #define QF_CRIT_STAT_TYPE OS_CPU_SR - #define QF_CRIT_ENTRY(dummy) OS_ENTER_CRITICAL() - #define QF_CRIT_EXIT(dummy) OS_EXIT_CRITICAL() -#else - #error Unsupported uC-OS2 critical section type -#endif /* OS_CRITICAL_METHOD */ - -enum UCOS2_TaskAttrs { - TASK_NAME_ATTR -}; - -#include "qep_port.h" /* QEP port */ -#include "qequeue.h" /* native QF event queue for deferring events */ -#include "qmpool.h" /* native QF event pool */ -#include "qf.h" /* QF platform-independent public interface */ - -/***************************************************************************** -* interface used only inside QF, but not in applications -*/ -#ifdef QP_IMPL - - /* uC-OS2 crtitical section, NOTE1 */ -#if (OS_CRITICAL_METHOD == 3u) - /* internal uC-OS2 critical section operations, NOTE1 */ - #define QF_CRIT_STAT_ OS_CPU_SR cpu_sr; - #define QF_CRIT_E_() OS_ENTER_CRITICAL() - #define QF_CRIT_X_() OS_EXIT_CRITICAL() -#endif /* OS_CRITICAL_METHOD */ - - /* uC-OS2-specific scheduler locking, see NOTE2 */ - #define QF_SCHED_STAT_ - #define QF_SCHED_LOCK_(dummy) do { \ - if (OSIntNesting == 0) { \ - OSSchedLock(); \ - } \ - } while (false) - - #define QF_SCHED_UNLOCK_() do { \ - if (OSIntNesting == 0) { \ - OSSchedUnlock(); \ - } \ - } while (false) - - /* native QF event pool operations */ - #define QF_EPOOL_TYPE_ QMPool - #define QF_EPOOL_INIT_(p_, poolSto_, poolSize_, evtSize_) \ - (QMPool_init(&(p_), (poolSto_), (poolSize_), (evtSize_))) - #define QF_EPOOL_EVENT_SIZE_(p_) ((uint_fast16_t)(p_).blockSize) - #define QF_EPOOL_GET_(p_, e_, m_, qs_id_) \ - ((e_) = (QEvt *)QMPool_get(&(p_), (m_), (qs_id_))) - #define QF_EPOOL_PUT_(p_, e_, qs_id_) \ - (QMPool_put(&(p_), (e_), (qs_id_))) - -#endif /* ifdef QP_IMPL */ - -/***************************************************************************** -* NOTE1: -* This QP port to uC-OS2 re-uses the exact same crtical section mechanism -* as uC-OS2. The goal is to make this port independent on the CPU or the -* toolchain by employing only the official uC-OS2 API. That way, all CPU -* and toolchain dependencies are handled internally by uC-OS2. -* -* NOTE2: -* uC-OS2 provides only global scheduler locking for all thread priorities -* by means of OSSchedLock() and OSSchedUnlock(). Therefore, locking the -* scheduler only up to the specified lock priority is not supported. -*/ - -#endif /* QF_PORT_H */ - diff --git a/ports/uc-os2/qp_port.h b/ports/uc-os2/qp_port.h new file mode 100644 index 00000000..2c746ac5 --- /dev/null +++ b/ports/uc-os2/qp_port.h @@ -0,0 +1,122 @@ +//============================================================================ +// QP/C Real-Time Embedded Framework (RTEF) +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +//============================================================================ +//! @date Last updated on: 2023-09-07 +//! @version Last updated for: @ref qpc_7_3_0 +//! +//! @file +//! @brief QP/C port to uC-OS2, generic C11 compiler + +#ifndef QP_PORT_H_ +#define QP_PORT_H_ + +#include // Exact-width types. WG14/N843 C99 Standard +#include // Boolean type. WG14/N843 C99 Standard + +#ifdef QP_CONFIG +#include "qp_config.h" // external QP configuration +#endif + +// no-return function specifier (C11 Standard) +#define Q_NORETURN _Noreturn void + +// uC-OS2 event queue and thread types +#define QACTIVE_EQUEUE_TYPE OS_EVENT * +#define QACTIVE_THREAD_TYPE uint32_t + +// include files ------------------------------------------------------------- +#include "ucos_ii.h" // uC-OS2 API, port and compile-time configuration + +#include "qequeue.h" // QP event queue (for deferring events) +#include "qmpool.h" // QP memory pool (for event pools) +#include "qp.h" // QP platform-independent public interface + +// uC-OS2 critical section, NOTE1 +#if (OS_CRITICAL_METHOD == 1U) + #define QF_CRIT_STAT + #define QF_CRIT_ENTRY() OS_ENTER_CRITICAL() + #define QF_CRIT_EXIT() OS_EXIT_CRITICAL() +#elif (OS_CRITICAL_METHOD == 3U) + #define QF_CRIT_STAT OS_CPU_SR cpu_sr; + #define QF_CRIT_ENTRY() OS_ENTER_CRITICAL() + #define QF_CRIT_EXIT() OS_EXIT_CRITICAL() +#else + #error Unsupported uC-OS2 critical section type +#endif // OS_CRITICAL_METHOD + + +enum UCOS2_TaskAttrs { + TASK_NAME_ATTR +}; + +//============================================================================ +// interface used only inside QF implementation, but not in applications +#ifdef QP_IMPL + + // uC-OS2-specific scheduler locking, see NOTE2 + #define QF_SCHED_STAT_ + #define QF_SCHED_LOCK_(dummy) do { \ + if (OSIntNesting == 0U) { \ + OSSchedLock(); \ + } \ + } while (false) + + #define QF_SCHED_UNLOCK_() do { \ + if (OSIntNesting == 0U) { \ + OSSchedUnlock(); \ + } \ + } while (false) + + // native QF event pool customization + #define QF_EPOOL_TYPE_ QMPool + #define QF_EPOOL_INIT_(p_, poolSto_, poolSize_, evtSize_) \ + (QMPool_init(&(p_), (poolSto_), (poolSize_), (evtSize_))) + #define QF_EPOOL_EVENT_SIZE_(p_) ((uint_fast16_t)(p_).blockSize) + #define QF_EPOOL_GET_(p_, e_, m_, qs_id_) \ + ((e_) = (QEvt *)QMPool_get(&(p_), (m_), (qs_id_))) + #define QF_EPOOL_PUT_(p_, e_, qs_id_) \ + (QMPool_put(&(p_), (e_), (qs_id_))) + +#endif // QP_IMPL + +//============================================================================ +// NOTE1: +// This QP port to uC-OS2 re-uses the exact same critical section mechanism +// as uC-OS2. The goal is to make this port independent on the CPU or the +// toolchain by employing only the official uC-OS2 API. That way, all CPU +// and toolchain dependencies are handled internally by uC-OS2. +// +// NOTE2: +// uC-OS2 provides only global scheduler locking for all thread priorities +// by means of OSSchedLock() and OSSchedUnlock(). Therefore, locking the +// scheduler only up to the specified lock priority is not supported. +// + +#endif // QP_PORT_H_ + diff --git a/ports/uc-os2/qs_port.h b/ports/uc-os2/qs_port.h index 34803ddf..2350d92f 100644 --- a/ports/uc-os2/qs_port.h +++ b/ports/uc-os2/qs_port.h @@ -1,58 +1,60 @@ -/*============================================================================ -* QP/C Real-Time Embedded Framework (RTEF) -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2022-06-12 -* @version Last updated for: @ref qpc_7_0_1 -* -* @file -* @brief QS/C port to uC-OS2, generic C99 compiler -*/ -#ifndef QS_PORT_H -#define QS_PORT_H +//============================================================================ +// QP/C Real-Time Embedded Framework (RTEF) +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +//============================================================================ +//! @date Last updated on: 2023-08-16 +//! @version Last updated for: @ref qpc_7_3_0 +//! +//! @file +//! @brief QS/C port to a 32-bit CPU and a generic C11 compiler. +//! @description +//! This is an example of a QP/C port with the documentation for the +//! configuration macros and includes. +#ifndef QS_PORT_H_ +#define QS_PORT_H_ + +// QS time-stamp size in bytes #define QS_TIME_SIZE 4U + +// object pointer size in bytes #define QS_OBJ_PTR_SIZE 4U + +// function pointer size in bytes #define QS_FUN_PTR_SIZE 4U -/*==========================================================================*/ -/* NOTE: QS might be used with or without other QP components, in which -* case the separate definitions of the macros QF_CRIT_STAT_TYPE, -* QF_CRIT_ENTRY, and QF_CRIT_EXIT are needed. In this port QS is configured -* to be used with the other QP component, by simply including "qf_port.h" -* *before* "qs.h". -*/ -#ifndef QF_PORT_H -#include "qf_port.h" /* use QS with QF */ +//============================================================================ +// NOTE: QS might be used with or without other QP components, in which +// case the separate definitions of the macros QF_CRIT_STAT, QF_CRIT_ENTRY(), +// and QF_CRIT_EXIT() are needed. In this port QS is configured to be used +// with the other QP component, by simply including "qp_port.h" +//*before* "qs.h". +// +#ifndef QP_PORT_H_ +#include "qp_port.h" // use QS with QP #endif -#if (OS_CRITICAL_METHOD == 3U) - #define QS_CRIT_STAT_ OS_CPU_SR cpu_sr; - #define QS_CRIT_E_() OS_ENTER_CRITICAL() - #define QS_CRIT_X_() OS_EXIT_CRITICAL(); QS_REC_DONE() -#endif /* OS_CRITICAL_METHOD */ +#include "qs.h" // QS platform-independent public interface -#include "qs.h" /* QS platform-independent public interface */ +#endif // QS_PORT_H_ -#endif /* QS_PORT_H */ diff --git a/ports/win32-qutest/qep_port.h b/ports/win32-qutest/qep_port.h deleted file mode 100644 index a68b88b2..00000000 --- a/ports/win32-qutest/qep_port.h +++ /dev/null @@ -1,71 +0,0 @@ -/*============================================================================ -* QP/C Real-Time Embedded Framework (RTEF) -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2022-06-12 -* @version Last updated for: @ref qpc_7_0_1 -* -* @file -* @brief QEP/C port to Win32 with GNU or Visual Studio C/C++ compilers -*/ -#ifndef QEP_PORT_H -#define QEP_PORT_H - -#include /* Exact-width types. WG14/N843 C99 Standard */ -#include /* Boolean type. WG14/N843 C99 Standard */ - -#ifdef __GNUC__ - - /*! no-return function specifier (GCC-ARM compiler) */ - #define Q_NORETURN __attribute__ ((noreturn)) void - -#elif (defined _MSC_VER) && (defined __cplusplus) - - /* no-return function specifier (Microsoft Visual Studio C++ compiler) */ - #define Q_NORETURN [[ noreturn ]] void - - /* - * This is the case where QP/C is compiled by the Microsoft Visual C++ - * compiler in the C++ mode, which can happen when qep_port.h is included - * in a C++ module, or the compilation is forced to C++ by the option /TP. - * - * The following pragma suppresses the level-4 C++ warnings C4510, C4512, and - * C4610, which warn that default constructors and assignment operators could - * not be generated for structures QMState and QMTranActTable. - * - * The QP/C source code cannot be changed to avoid these C++ warnings, because - * the structures QMState and QMTranActTable must remain PODs (Plain Old - * Datatypes) to be initializable statically with constant initializers. - */ - #pragma warning (disable: 4510 4512 4610) - -#endif - -#include "qep.h" /* QEP platform-independent public interface */ - -#if (defined __cplusplus) && (defined _MSC_VER) - #pragma warning (default: 4510 4512 4610) -#endif - -#endif /* QEP_PORT_H */ diff --git a/ports/win32-qutest/qf_port.h b/ports/win32-qutest/qf_port.h deleted file mode 100644 index 413c2cf8..00000000 --- a/ports/win32-qutest/qf_port.h +++ /dev/null @@ -1,94 +0,0 @@ -/*============================================================================ -* QP/C Real-Time Embedded Framework (RTEF) -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2023-01-07 -* @version Last updated for: @ref qpc_7_2_0 -* -* @file -* @brief QF/C "port" for QUTest unit test harness, Win32 with GNU or VisualC++ -*/ -#ifndef QF_PORT_H -#define QF_PORT_H - -/* QUTest event queue and thread types */ -#define QF_EQUEUE_TYPE QEQueue -/* QF_OS_OBJECT_TYPE not used */ -/* QF_THREAD_TYPE not used */ - -/* The maximum number of active objects in the application */ -#define QF_MAX_ACTIVE 64U - -/* The number of system clock tick rates */ -#define QF_MAX_TICK_RATE 2U - -/* Activate the QF QActive_stop() API */ -#define QF_ACTIVE_STOP 1 - -/* QF interrupt disable/enable */ -#define QF_INT_DISABLE() (++QF_intLock_) -#define QF_INT_ENABLE() (--QF_intLock_) - -/* QUTest critical section */ -/* QF_CRIT_STAT_TYPE not defined */ -#define QF_CRIT_ENTRY(dummy) QF_INT_DISABLE() -#define QF_CRIT_EXIT(dummy) QF_INT_ENABLE() - -/* QF_LOG2 not defined -- use the internal LOG2() implementation */ - -#include "qep_port.h" /* QEP port */ -#include "qequeue.h" /* QUTest port uses QEQueue event-queue */ -#include "qmpool.h" /* QUTest port uses QMPool memory-pool */ -#include "qf.h" /* QF platform-independent public interface */ - -/****************************************************************************/ -/* interface used only inside QF implementation, but not in applications */ -#ifdef QP_IMPL - - /* QUTest scheduler locking (not used) */ - #define QF_SCHED_STAT_ - #define QF_SCHED_LOCK_(dummy) ((void)0) - #define QF_SCHED_UNLOCK_() ((void)0) - - /* native event queue operations */ - #define QACTIVE_EQUEUE_WAIT_(me_) \ - Q_ASSERT_ID(110, (me_)->eQueue.frontEvt != (QEvt *)0) - #define QACTIVE_EQUEUE_SIGNAL_(me_) \ - QPSet_insert(&QF_readySet_, (uint_fast8_t)(me_)->prio) - - /* native QF event pool operations */ - #define QF_EPOOL_TYPE_ QMPool - #define QF_EPOOL_INIT_(p_, poolSto_, poolSize_, evtSize_) \ - (QMPool_init(&(p_), (poolSto_), (poolSize_), (evtSize_))) - #define QF_EPOOL_EVENT_SIZE_(p_) ((uint_fast16_t)(p_).blockSize) - #define QF_EPOOL_GET_(p_, e_, m_, qs_id_) \ - ((e_) = (QEvt *)QMPool_get(&(p_), (m_), (qs_id_))) - #define QF_EPOOL_PUT_(p_, e_, qs_id_) \ - (QMPool_put(&(p_), (e_), (qs_id_))) - - #include "qf_pkg.h" /* internal QF interface */ - -#endif /* QP_IMPL */ - -#endif /* QF_PORT_H */ diff --git a/ports/win32-qutest/qp_port.h b/ports/win32-qutest/qp_port.h new file mode 100644 index 00000000..f1e93598 --- /dev/null +++ b/ports/win32-qutest/qp_port.h @@ -0,0 +1,137 @@ +//============================================================================ +// QP/C Real-Time Embedded Framework (RTEF) +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC . +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +//============================================================================ +//! @date Last updated on: 2023-09-07 +//! @version Last updated for: @ref qpc_7_3_0 +//! +//! @file +//! @brief QP/C port to Win32-QUtest with GNU or Visual Studio C/C++ + +#ifndef QP_PORT_H_ +#define QP_PORT_H_ + +#include // Exact-width types. WG14/N843 C99 Standard +#include // Boolean type. WG14/N843 C99 Standard + +#ifdef QP_CONFIG +#include "qp_config.h" // external QP configuration +#endif + +#ifdef __GNUC__ + + // no-return function specifier (GCC-ARM compiler) + #define Q_NORETURN __attribute__ ((noreturn)) void + +#elif (defined _MSC_VER) + #ifdef __cplusplus + // no-return function specifier (Microsoft Visual Studio C++ compiler) + #define Q_NORETURN [[ noreturn ]] void + #else + // no-return function specifier C11 + #define Q_NORETURN _Noreturn void + #endif + + // This is the case where QP/C is compiled by the Microsoft Visual C++ + // compiler in the C++ mode, which can happen when qep_port.h is included + // in a C++ module, or the compilation is forced to C++ by the option /TP. + // + // The following pragma suppresses the level-4 C++ warnings C4510, C4512, + // and C4610, which warn that default constructors and assignment operators + // could not be generated for structures QMState and QMTranActTable. + // + // The QP/C source code cannot be changed to avoid these C++ warnings + // because the structures QMState and QMTranActTable must remain PODs + // (Plain Old Datatypes) to be initializable statically with constant + // initializers. + // + #pragma warning (disable: 4510 4512 4610) + +#endif + +// QUTest event queue and thread types +#define QACTIVE_EQUEUE_TYPE QEQueue +// QACTIVE_OS_OBJ_TYPE not used in this port +// QACTIVE_THREAD_TYPE not used in this port + +// QF interrupt disable/enable +#define QF_INT_DISABLE() (++QS_tstPriv_.intLock) +#define QF_INT_ENABLE() (--QS_tstPriv_.intLock) + +// QF critical section +#define QF_CRIT_STAT +#define QF_CRIT_ENTRY() QF_INT_DISABLE() +#define QF_CRIT_EXIT() QF_INT_ENABLE() + +// QF_LOG2 not defined -- use the internal LOG2() implementation + +// include files ------------------------------------------------------------- +#include "qequeue.h" // QUTest port uses QEQueue event-queue +#include "qmpool.h" // QUTest port uses QMPool memory-pool +#include "qp.h" // QP platform-independent public interface + +#ifdef _MSC_VER + #pragma warning (default: 4510 4512 4610) +#endif + +//============================================================================ +// interface used only inside QF implementation, but not in applications + +#ifdef QP_IMPL + + // QUTest scheduler locking (not used) + #define QF_SCHED_STAT_ + #define QF_SCHED_LOCK_(dummy) ((void)0) + #define QF_SCHED_UNLOCK_() ((void)0) + + // native event queue operations + #define QACTIVE_EQUEUE_WAIT_(me_) \ + Q_ASSERT_INCRIT(305, (me_)->eQueue.frontEvt != (QEvt *)0) +#ifndef Q_UNSAFE + #define QACTIVE_EQUEUE_SIGNAL_(me_) \ + QPSet_insert(&QS_tstPriv_.readySet, (uint_fast8_t)(me_)->prio); \ + QPSet_update_(&QS_tstPriv_.readySet, &QS_tstPriv_.readySet_dis) +#else + #define QACTIVE_EQUEUE_SIGNAL_(me_) \ + QPSet_insert(&QF_readySet_, (uint_fast8_t)(me_)->prio) +#endif + + // native QF event pool operations + #define QF_EPOOL_TYPE_ QMPool + #define QF_EPOOL_INIT_(p_, poolSto_, poolSize_, evtSize_) \ + (QMPool_init(&(p_), (poolSto_), (poolSize_), (evtSize_))) + #define QF_EPOOL_EVENT_SIZE_(p_) ((uint_fast16_t)(p_).blockSize) + #define QF_EPOOL_GET_(p_, e_, m_, qs_id_) \ + ((e_) = (QEvt *)QMPool_get(&(p_), (m_), (qs_id_))) + #define QF_EPOOL_PUT_(p_, e_, qs_id_) \ + (QMPool_put(&(p_), (e_), (qs_id_))) + +#endif // QP_IMPL + +#endif // QP_PORT_H_ + diff --git a/ports/win32-qutest/qs_port.h b/ports/win32-qutest/qs_port.h index 0ea303e3..fed3284f 100644 --- a/ports/win32-qutest/qs_port.h +++ b/ports/win32-qutest/qs_port.h @@ -1,63 +1,61 @@ -/*============================================================================ -* QP/C Real-Time Embedded Framework (RTEF) -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2023-01-07 -* @version Last updated for: @ref qpc_7_2_0 -* -* @file -* @brief QS/C port to Win32 with GNU or Visual C++ compilers -*/ -#ifndef QS_PORT_H -#define QS_PORT_H +//============================================================================ +// QP/C Real-Time Embedded Framework (RTEF) +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +//============================================================================ +//! @date Last updated on: 2023-08-16 +//! @version Last updated for: @ref qpc_7_3_0 +//! +//! @file +//! @brief QS/C port to Win32 with GNU or Visual C++ compilers + +#ifndef QS_PORT_H_ +#define QS_PORT_H_ #define QS_CTR_SIZE 4U #define QS_TIME_SIZE 4U -#ifdef _WIN64 /* 64-bit architecture? */ +#ifdef _WIN64 // 64-bit architecture? #define QS_OBJ_PTR_SIZE 8U #define QS_FUN_PTR_SIZE 8U -#else /* 32-bit architecture */ +#else // 32-bit architecture #define QS_OBJ_PTR_SIZE 4U #define QS_FUN_PTR_SIZE 4U #endif -/* flush the QS output buffer after each QS record */ -#define QS_REC_DONE() QS_onFlush() +void QS_output(void); // handle the QS output +void QS_rx_input(void); // handle the QS-RX input -/*==========================================================================*/ -/* NOTE: QS might be used with or without other QP components, in which -* case the separate definitions of the macros QF_CRIT_STAT_TYPE, -* QF_CRIT_ENTRY, and QF_CRIT_EXIT are needed. In this port QS is configured -* to be used with the other QP component, by simply including "qf_port.h" -* *before* "qs.h". -*/ -#ifndef QF_PORT_H -#include "qf_port.h" /* use QS with QF */ +//============================================================================ +// NOTE: QS might be used with or without other QP components, in which +// case the separate definitions of the macros QF_CRIT_STAT, QF_CRIT_ENTRY(), +// and QF_CRIT_EXIT() are needed. In this port QS is configured to be used +// with the other QP component, by simply including "qp_port.h" +//*before* "qs.h". +#ifndef QP_PORT_H_ +#include "qp_port.h" // use QS with QP #endif -#include "qs.h" /* QS platform-independent public interface */ +#include "qs.h" // QS platform-independent public interface -#endif /* QS_PORT_H */ +#endif // QS_PORT_H_ diff --git a/ports/win32-qutest/qutest_port.c b/ports/win32-qutest/qutest_port.c index d41faf7d..e3047521 100644 --- a/ports/win32-qutest/qutest_port.c +++ b/ports/win32-qutest/qutest_port.c @@ -1,50 +1,49 @@ -/*============================================================================ -* QP/C Real-Time Embedded Framework (RTEF) -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2023-01-07 -* @version Last updated for: @ref qpc_7_2_0 -* -* @file -* @brief QS/C QUTest port for Win32 -*/ +//============================================================================ +// QP/C Real-Time Embedded Framework (RTEF) +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +//============================================================================ +//! @date Last updated on: 2023-08-20 +//! @version Last updated for: @ref qpc_7_3_0 +//! +//! @file +//! @brief QS/C QUTest port for Win32 + #ifndef Q_SPY #error "Q_SPY must be defined to compile qutest_port.c" -#endif /* Q_SPY */ +#endif // Q_SPY -#define QP_IMPL /* this is QP implementation */ -#include "qf_port.h" /* QF port */ -#include "qassert.h" /* QP embedded systems-friendly assertions */ -#include "qs_port.h" /* QS port */ -#include "qs_pkg.h" /* QS package-scope interface */ +#define QP_IMPL // this is QP implementation +#include "qp_port.h" // QP port +#include "qsafe.h" // QP Functional Safety (FuSa) System +#include "qs_port.h" // QS port +#include "qs_pkg.h" // QS package-scope interface -#include "safe_std.h" /* portable "safe" / facilities */ +#include "safe_std.h" // portable "safe" / facilities #include #include #include -/* Minimum required Windows version is Windows-XP or newer (0x0501) */ +// Minimum required Windows version is Windows-XP or newer (0x0501) #ifdef WINVER #undef WINVER #endif @@ -57,22 +56,27 @@ #include -/*Q_DEFINE_THIS_MODULE("qutest_port")*/ +//Q_DEFINE_THIS_MODULE("qutest_port") #define QS_TX_SIZE (8*1024) #define QS_RX_SIZE (2*1024) #define QS_TX_CHUNK QS_TX_SIZE #define QS_TIMEOUT_MS 10U -/* local variables .........................................................*/ +// local variables ......................................................... static SOCKET l_sock = INVALID_SOCKET; -/*..........................................................................*/ +//............................................................................ uint8_t QS_onStartup(void const *arg) { - static uint8_t qsBuf[QS_TX_SIZE]; /* buffer for QS-TX channel */ - static uint8_t qsRxBuf[QS_RX_SIZE]; /* buffer for QS-RX channel */ + // initialize the QS transmit and receive buffers + static uint8_t qsBuf[QS_TX_SIZE]; // buffer for QS-TX channel + QS_initBuf(qsBuf, sizeof(qsBuf)); + + static uint8_t qsRxBuf[QS_RX_SIZE]; // buffer for QS-RX channel + QS_rxInitBuf(qsRxBuf, sizeof(qsRxBuf)); + char hostName[128]; - char const *serviceName = "6601"; /* default QSPY server port */ + char const *serviceName = "6601"; // default QSPY server port char const *src; char *dst; int status; @@ -84,21 +88,17 @@ uint8_t QS_onStartup(void const *arg) { ULONG ioctl_opt; WSADATA wsaData; - /* initialize the QS transmit and receive buffers */ - QS_initBuf(qsBuf, sizeof(qsBuf)); - QS_rxInitBuf(qsRxBuf, sizeof(qsRxBuf)); - - /* initialize Windows sockets version 2.2 */ + // initialize Windows sockets version 2.2 if (WSAStartup(MAKEWORD(2, 2), &wsaData) != NO_ERROR) { FPRINTF_S(stderr, " ERROR %s\n", "Windows Sockets cannot be initialized"); goto error; } - /* extract hostName from 'arg' (hostName:port_remote)... */ + // extract hostName from 'arg' (hostName:port_remote)... src = (arg != (void *)0) ? (char const *)arg - : "localhost"; /* default QSPY host */ + : "localhost"; // default QSPY host dst = hostName; while ((*src != '\0') && (*src != ':') @@ -106,14 +106,12 @@ uint8_t QS_onStartup(void const *arg) { { *dst++ = *src++; } - *dst = '\0'; /* zero-terminate hostName */ + *dst = '\0'; // zero-terminate hostName - /* extract serviceName from 'arg' (hostName:serviceName)... */ + // extract serviceName from 'arg' (hostName:serviceName)... if (*src == ':') { serviceName = src + 1; } - //printf(" Connecting to QSPY on Host=%s:%s...\n", - // hostName, serviceName); memset(&hints, 0, sizeof(hints)); hints.ai_family = AF_INET; @@ -142,7 +140,7 @@ uint8_t QS_onStartup(void const *arg) { freeaddrinfo(result); - /* socket could not be opened & connected? */ + // socket could not be opened & connected? if (l_sock == INVALID_SOCKET) { FPRINTF_S(stderr, " ERROR cannot connect to QSPY at " "host=%s:%s\n", @@ -150,7 +148,7 @@ uint8_t QS_onStartup(void const *arg) { goto error; } - /* set the socket to non-blocking mode */ + // set the socket to non-blocking mode ioctl_opt = 1; if (ioctlsocket(l_sock, FIONBIO, &ioctl_opt) != NO_ERROR) { FPRINTF_S(stderr, " ERROR %s WASErr=%d\n,", @@ -158,81 +156,86 @@ uint8_t QS_onStartup(void const *arg) { goto error; } - /* configure the socket to reuse the address and not to linger */ + // configure the socket to reuse the address and not to linger sockopt_bool = TRUE; setsockopt(l_sock, SOL_SOCKET, SO_REUSEADDR, (const char *)&sockopt_bool, sizeof(sockopt_bool)); sockopt_bool = TRUE; setsockopt(l_sock, SOL_SOCKET, SO_DONTLINGER, (const char *)&sockopt_bool, sizeof(sockopt_bool)); - //PRINTF_S(" Connected to QSPY at Host=%s:%d\n", // hostName, port_remote); QS_onFlush(); - return 1U; /* success */ + return 1U; // success error: - return 0U; /* failure */ + return 0U; // failure } -/*..........................................................................*/ +//............................................................................ void QS_onCleanup(void) { - Sleep(QS_TIMEOUT_MS * 10U); /* allow the last QS output to come out */ + Sleep(QS_TIMEOUT_MS * 10U); // allow the last QS output to come out if (l_sock != INVALID_SOCKET) { closesocket(l_sock); l_sock = INVALID_SOCKET; } WSACleanup(); - //PRINTF_S("\n%s\n", "QS_onCleanup"); + //PRINTF_S(" Disconnected from QSPY\n"); } -/*..........................................................................*/ +//............................................................................ void QS_onReset(void) { QS_onCleanup(); //PRINTF_S("\n%s\n", "QS_onReset"); exit(0); } -/*..........................................................................*/ +//............................................................................ void QS_onFlush(void) { - if (l_sock == INVALID_SOCKET) { /* socket NOT initialized? */ - FPRINTF_S(stderr, " ERROR %s\n", "invalid TCP socket"); + if (l_sock == INVALID_SOCKET) { // socket NOT initialized? + FPRINTF_S(stderr, " ERROR %s\n", + "invalid TCP socket"); + QF_stop(); // <== stop and exit the application return; } + QS_CRIT_STAT + QS_CRIT_ENTRY(); uint16_t nBytes = QS_TX_CHUNK; uint8_t const *data; while ((data = QS_getBlock(&nBytes)) != (uint8_t *)0) { - for (;;) { /* for-ever until break or return */ + QS_CRIT_EXIT(); + for (;;) { // for-ever until break or return int nSent = send(l_sock, (char const *)data, (int)nBytes, 0); - if (nSent == SOCKET_ERROR) { /* sending failed? */ + if (nSent == SOCKET_ERROR) { // sending failed? int err = WSAGetLastError(); if (err == WSAEWOULDBLOCK) { - /* sleep for the timeout and then loop back - * to send() the SAME data again - */ + // sleep for the timeout and then loop back + // to send() the SAME data again Sleep(QS_TIMEOUT_MS); } - else { /* some other socket error... */ + else { // some other socket error... FPRINTF_S(stderr, " ERROR %s WASErr=%d\n", "sending data over TCP", err); + QF_stop(); // <== stop and exit the application return; } } - else if (nSent < (int)nBytes) { /* sent fewer than requested? */ - Sleep(QS_TIMEOUT_MS); /* sleep for the timeout */ - - /* adjust the data and loop back to send() the rest */ + else if (nSent < (int)nBytes) { // sent fewer than requested? + Sleep(QS_TIMEOUT_MS); // sleep for the timeout + // adjust the data and loop back to send() the rest data += nSent; nBytes -= (uint16_t)nSent; } else { - break; /* break out of the for-ever loop */ + break; // break out of the for-ever loop } } - /* set nBytes for the next call to QS_getBlock() */ + // set nBytes for the next call to QS_getBlock() nBytes = QS_TX_CHUNK; + QS_CRIT_ENTRY(); } + QS_CRIT_EXIT(); } -/*..........................................................................*/ +//............................................................................ void QS_onTestLoop() { fd_set readSet; FD_ZERO(&readSet); @@ -245,7 +248,7 @@ void QS_onTestLoop() { FD_SET(l_sock, &readSet); - /* selective, timed blocking on the TCP/IP socket... */ + // selective, timed blocking on the TCP/IP socket... int status = select(0, &readSet, (fd_set *)0, (fd_set *)0, &timeout); if (status == SOCKET_ERROR) { FPRINTF_S(stderr, @@ -254,35 +257,35 @@ void QS_onTestLoop() { QS_onCleanup(); exit(-2); } - else if (FD_ISSET(l_sock, &readSet)) { /* socket ready to read? */ + else if (FD_ISSET(l_sock, &readSet)) { // socket ready to read? status = recv(l_sock, (char *)QS_rxPriv_.buf, (int)QS_rxPriv_.end, 0); - if (status > 0) { /* any data received? */ + if (status > 0) { // any data received? QS_rxPriv_.tail = 0U; - QS_rxPriv_.head = status; /* # bytes received */ - QS_rxParse(); /* parse all received bytes */ + QS_rxPriv_.head = status; // # bytes received + QS_rxParse(); // parse all received bytes } } QS_onFlush(); wint_t ch = 0; - while (_kbhit()) { /* any key pressed? */ + while (_kbhit()) { // any key pressed? ch = _getwch(); } switch (ch) { - case 'x': /* 'x' pressed? */ - case 'X': /* 'X' pressed? */ - case '\033': { /* ESC pressed? */ + case 'x': // 'x' pressed? + case 'X': // 'X' pressed? + case '\033': { // ESC pressed? QS_onCleanup(); exit(1); break; } } } - /* set inTestLoop to true in case calls to QS_onTestLoop() nest, - * which can happen through the calls to QS_TEST_PAUSE(). - */ + // set inTestLoop to true in case calls to QS_onTestLoop() nest, + // which can happen through the calls to QS_TEST_PAUSE(). + // QS_rxPriv_.inTestLoop = true; } diff --git a/ports/win32-qutest/safe_std.h b/ports/win32-qutest/safe_std.h index 7e0a2439..c752662c 100644 --- a/ports/win32-qutest/safe_std.h +++ b/ports/win32-qutest/safe_std.h @@ -1,42 +1,40 @@ -/*============================================================================ -* QP/C Real-Time Embedded Framework (RTEF) -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2022-07-30 -* @version Last updated for: @ref qpc_7_0_1 -* -* @file -* @brief "safe" and facilities -*/ +//============================================================================ +// QP/C Real-Time Embedded Framework (RTEF) +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +//============================================================================ +//! @date Last updated on: 2022-07-30 +//! @version Last updated for: @ref qpc_7_1_3 +//! +//! @file +//! @brief "safe" and facilities #ifndef SAFE_STD_H #define SAFE_STD_H #include #include -/* portable "safe" facilities from and ................*/ -#ifdef _WIN32 /* Windows OS? */ +// portable "safe" facilities from and ................ +#ifdef _WIN32 // Windows OS? #define MEMMOVE_S(dest_, num_, src_, count_) \ memmove_s(dest_, num_, src_, count_) @@ -48,13 +46,13 @@ strcat_s(dest_, destsiz_, src_) #define SNPRINTF_S(buf_, bufsiz_, format_, ...) \ - _snprintf_s(buf_, bufsiz_, _TRUNCATE, format_, ##__VA_ARGS__) + _snprintf_s(buf_, bufsiz_, _TRUNCATE, format_, __VA_ARGS__) #define PRINTF_S(format_, ...) \ - printf_s(format_, ##__VA_ARGS__) + printf_s(format_, __VA_ARGS__) #define FPRINTF_S(fp_, format_, ...) \ - fprintf_s(fp_, format_, ##__VA_ARGS__) + fprintf_s(fp_, format_, __VA_ARGS__) #ifdef _MSC_VER #define FREAD_S(buf_, bufsiz_, elsiz_, count_, fp_) \ @@ -62,7 +60,7 @@ #else #define FREAD_S(buf_, bufsiz_, elsiz_, count_, fp_) \ fread(buf_, elsiz_, count_, fp_) -#endif /* _MSC_VER */ +#endif // _MSC_VER #define FOPEN_S(fp_, fName_, mode_) \ if (fopen_s(&fp_, fName_, mode_) != 0) { \ @@ -72,7 +70,7 @@ if (fopen_s(&fp_, fName_, mode_) != 0) { \ #define LOCALTIME_S(tm_, time_) \ localtime_s(tm_, time_) -#else /* other OS (Linux, MacOS, etc.) .....................................*/ +#else // other OS (Linux, MacOS, etc.) ..................................... #define MEMMOVE_S(dest_, num_, src_, count_) \ memmove(dest_, src_, count_) @@ -86,13 +84,13 @@ if (fopen_s(&fp_, fName_, mode_) != 0) { \ strcat(dest_, src_) #define SNPRINTF_S(buf_, bufsiz_, format_, ...) \ - snprintf(buf_, bufsiz_, format_, ##__VA_ARGS__) + snprintf(buf_, bufsiz_, format_, __VA_ARGS__) #define PRINTF_S(format_, ...) \ - printf(format_, ##__VA_ARGS__) + printf(format_, __VA_ARGS__) #define FPRINTF_S(fp_, format_, ...) \ - fprintf(fp_, format_, ##__VA_ARGS__) + fprintf(fp_, format_, __VA_ARGS__) #define FREAD_S(buf_, bufsiz_, elsiz_, count_, fp_) \ fread(buf_, elsiz_, count_, fp_) @@ -103,6 +101,6 @@ if (fopen_s(&fp_, fName_, mode_) != 0) { \ #define LOCALTIME_S(tm_, time_) \ memcpy(tm_, localtime(time_), sizeof(struct tm)) -#endif /* _WIN32 */ +#endif // _WIN32 -#endif /* SAFE_STD_H */ +#endif // SAFE_STD_H diff --git a/ports/win32-qv/qep_port.h b/ports/win32-qv/qep_port.h deleted file mode 100644 index a68b88b2..00000000 --- a/ports/win32-qv/qep_port.h +++ /dev/null @@ -1,71 +0,0 @@ -/*============================================================================ -* QP/C Real-Time Embedded Framework (RTEF) -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2022-06-12 -* @version Last updated for: @ref qpc_7_0_1 -* -* @file -* @brief QEP/C port to Win32 with GNU or Visual Studio C/C++ compilers -*/ -#ifndef QEP_PORT_H -#define QEP_PORT_H - -#include /* Exact-width types. WG14/N843 C99 Standard */ -#include /* Boolean type. WG14/N843 C99 Standard */ - -#ifdef __GNUC__ - - /*! no-return function specifier (GCC-ARM compiler) */ - #define Q_NORETURN __attribute__ ((noreturn)) void - -#elif (defined _MSC_VER) && (defined __cplusplus) - - /* no-return function specifier (Microsoft Visual Studio C++ compiler) */ - #define Q_NORETURN [[ noreturn ]] void - - /* - * This is the case where QP/C is compiled by the Microsoft Visual C++ - * compiler in the C++ mode, which can happen when qep_port.h is included - * in a C++ module, or the compilation is forced to C++ by the option /TP. - * - * The following pragma suppresses the level-4 C++ warnings C4510, C4512, and - * C4610, which warn that default constructors and assignment operators could - * not be generated for structures QMState and QMTranActTable. - * - * The QP/C source code cannot be changed to avoid these C++ warnings, because - * the structures QMState and QMTranActTable must remain PODs (Plain Old - * Datatypes) to be initializable statically with constant initializers. - */ - #pragma warning (disable: 4510 4512 4610) - -#endif - -#include "qep.h" /* QEP platform-independent public interface */ - -#if (defined __cplusplus) && (defined _MSC_VER) - #pragma warning (default: 4510 4512 4610) -#endif - -#endif /* QEP_PORT_H */ diff --git a/ports/win32-qv/qf_port.c b/ports/win32-qv/qf_port.c index 86443d5a..d99e4d79 100644 --- a/ports/win32-qv/qf_port.c +++ b/ports/win32-qv/qf_port.c @@ -1,228 +1,64 @@ -/*============================================================================ -* QP/C Real-Time Embedded Framework (RTEF) -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2023-01-07 -* @version Last updated for: @ref qpc_7_2_0 -* -* @file -* @brief QF/C port to Win32 API (single-threaded, like the QV kernel) -*/ -#define QP_IMPL /* this is QP implementation */ -#include "qf_port.h" /* QF port */ -#include "qf_pkg.h" /* QF package-scope interface */ -#include "qassert.h" /* QP embedded systems-friendly assertions */ -#ifdef Q_SPY /* QS software tracing enabled? */ - #include "qs_port.h" /* QS port */ - #include "qs_pkg.h" /* QS package-scope internal interface */ -#else - #include "qs_dummy.h" /* disable the QS software tracing */ -#endif /* Q_SPY */ +//============================================================================ +// QP/C Real-Time Embedded Framework (RTEF) +// Copyright (C) 2005 Quantum Leaps, LLC . +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +//============================================================================ +//! @date Last updated on: 2023-08-21 +//! @version Last updated for: @ref qpc_7_3_0 +//! +//! @file +//! @brief QF/C port to Win32-QV (single-threaded) -#include /* limits of dynamic range for integers */ -#include /* console input/output */ +#define QP_IMPL // this is QP implementation +#include "qp_port.h" // QP port +#include "qp_pkg.h" // QP package-scope interface +#include "qsafe.h" // QP Functional Safety (FuSa) System +#ifdef Q_SPY // QS software tracing enabled? + #include "qs_port.h" // QS port + #include "qs_pkg.h" // QS package-scope internal interface +#else + #include "qs_dummy.h" // disable the QS software tracing +#endif // Q_SPY + +#include // limits of dynamic range for integers +#include // console input/output Q_DEFINE_THIS_MODULE("qf_port") -/* Global objects ==========================================================*/ -HANDLE QV_win32Event_; /* Win32 event to signal events */ - -/* Local objects ===========================================================*/ +// Local objects ============================================================= static CRITICAL_SECTION l_win32CritSect; -static DWORD l_tickMsec = 10U; /* clock tick in msec (argument for Sleep()) */ -static int_t l_tickPrio = 50; /* default priority of the "ticker" thread */ -static bool l_isRunning; /* flag indicating when QF is running */ +static DWORD l_tickMsec = 10U; // clock tick in msec (argument for Sleep()) +static int l_tickPrio = 50; // default priority of the "ticker" thread +static bool l_isRunning; // flag indicating when QF is running -static DWORD WINAPI ticker_thread(LPVOID arg); +//============================================================================ +static DWORD WINAPI ticker_thread(LPVOID arg); // prototype +static DWORD WINAPI ticker_thread(LPVOID arg) { // for CreateThread() + Q_UNUSED_PAR(arg); -/* QF functions ============================================================*/ -void QF_init(void) { - InitializeCriticalSection(&l_win32CritSect); - QV_win32Event_ = CreateEvent(NULL, FALSE, FALSE, NULL); -} -/****************************************************************************/ -void QF_enterCriticalSection_(void) { - EnterCriticalSection(&l_win32CritSect); -} -/****************************************************************************/ -void QF_leaveCriticalSection_(void) { - LeaveCriticalSection(&l_win32CritSect); -} -/****************************************************************************/ -void QF_stop(void) { - l_isRunning = false; /* terminate the QV event loop and ticker thread */ - SetEvent(QV_win32Event_); /* unblock the event-loop so it can terminate */ -} -/****************************************************************************/ -int_t QF_run(void) { - QF_CRIT_STAT_ - - QF_onStartup(); /* application-specific startup callback */ - - l_isRunning = true; /* QF is running */ - - if (l_tickMsec != 0U) { /* system clock tick configured? */ - /* create the ticker thread... */ - HANDLE ticker = CreateThread(NULL, 1024, &ticker_thread, - (void *)0, 0, NULL); - Q_ASSERT_ID(310, ticker != (HANDLE)0); /* thread must be created */ - } - - /* the combined event-loop and background-loop of the QV kernel */ - QF_CRIT_E_(); - - /* produce the QS_QF_RUN trace record */ - QS_BEGIN_NOCRIT_PRE_(QS_QF_RUN, 0U) - QS_END_NOCRIT_PRE_() - - while (l_isRunning) { - /* find the maximum priority AO ready to run */ - if (QPSet_notEmpty(&QF_readySet_)) { - uint_fast8_t p = QPSet_findMax(&QF_readySet_); - QActive *a = QActive_registry_[p]; - QF_CRIT_X_(); - - /* the active object 'a' must still be registered in QF - * (e.g., it must not be stopped) - */ - Q_ASSERT_ID(320, a != (QActive *)0); - - /* perform the run-to-completion (RTS) step... - * 1. retrieve the event from the AO's event queue, which by this - * time must be non-empty and The "Vanilla" kernel asserts it. - * 2. dispatch the event to the AO's state machine. - * 3. determine if event is garbage and collect it if so - */ - QEvt const *e = QActive_get_(a); - QHSM_DISPATCH(&a->super, e, a->prio); - QF_gc(e); - - QF_CRIT_E_(); - - if (a->eQueue.frontEvt == (QEvt *)0) { /* empty queue? */ - QPSet_remove(&QF_readySet_, p); - } - } - else { - /* the QV kernel in embedded systems calls here the QV_onIdle() - * callback. However, the Win32-QV port does not do busy-waiting - * for events. Instead, the Win32-QV port efficiently waits until - * QP events become available. - */ - QF_CRIT_X_(); - - (void)WaitForSingleObject(QV_win32Event_, (DWORD)INFINITE); - - QF_CRIT_E_(); - } - } - QF_CRIT_X_(); - QF_onCleanup(); /* cleanup callback */ - QS_EXIT(); /* cleanup the QSPY connection */ - - return 0; /* return success */ -} -/****************************************************************************/ -void QF_setTickRate(uint32_t ticksPerSec, int_t tickPrio) { - if (ticksPerSec != 0U) { - l_tickMsec = 1000UL / ticksPerSec; - } - else { - l_tickMsec = 0U; /* means NO system clock tick */ - } - l_tickPrio = tickPrio; -} - -/*..........................................................................*/ -void QF_consoleSetup(void) { -} -/*..........................................................................*/ -void QF_consoleCleanup(void) { -} -/*..........................................................................*/ -int QF_consoleGetKey(void) { - if (_kbhit()) { /* any key pressed? */ - return (int)_getwch(); - } - return 0; -} -/*..........................................................................*/ -int QF_consoleWaitForKey(void) { - return (int)_getwch(); -} - -/* QActive functions =======================================================*/ -void QActive_start_(QActive * const me, QPrioSpec const prioSpec, - QEvt const * * const qSto, uint_fast16_t const qLen, - void * const stkSto, uint_fast16_t const stkSize, - void const * const par) -{ - Q_UNUSED_PAR(stkSize); - - /* no per-AO stack needed for this port */ - Q_REQUIRE_ID(600, stkSto == (void *)0); - - me->prio = (uint8_t)(prioSpec & 0xFFU); /* QF-priority of the AO */ - me->pthre = (uint8_t)(prioSpec >> 8U); /* preemption-threshold */ - QActive_register_(me); /* register this AO */ - - QEQueue_init(&me->eQueue, qSto, qLen); - - /* the top-most initial tran. (virtual) */ - QHSM_INIT(&me->super, par, me->prio); - QS_FLUSH(); /* flush the trace buffer to the host */ -} -/*..........................................................................*/ -#ifdef QF_ACTIVE_STOP -void QActive_stop(QActive * const me) { - QF_CRIT_STAT_ - - QActive_unsubscribeAll(me); /* unsubscribe from all events */ - - /* make sure the AO is no longer in "ready set" */ - QF_CRIT_E_(); - QPSet_remove(&QF_readySet_, me->prio); - QF_CRIT_X_(); - - QActive_unregister_(me); /* un-register this active object */ -} -#endif -/*..........................................................................*/ -void QActive_setAttr(QActive *const me, uint32_t attr1, void const *attr2) { - (void)me; /* unused parameter */ - (void)attr1; /* unused parameter */ - (void)attr2; /* unused parameter */ - Q_ERROR_ID(900); /* this function should not be called in this QP port */ -} - -/****************************************************************************/ -static DWORD WINAPI ticker_thread(LPVOID arg) { /* for CreateThread() */ int threadPrio = THREAD_PRIORITY_NORMAL; - /* set the ticker thread priority according to selection made in - * QF_setTickRate() - */ + // set the ticker thread priority according to selection made in + // QF_setTickRate() if (l_tickPrio < 33) { threadPrio = THREAD_PRIORITY_BELOW_NORMAL; } @@ -232,13 +68,204 @@ static DWORD WINAPI ticker_thread(LPVOID arg) { /* for CreateThread() */ SetThreadPriority(GetCurrentThread(), threadPrio); - while (l_isRunning) { - Sleep(l_tickMsec); /* wait for the tick interval */ - QF_onClockTick(); /* callback (must call QTIMEEVT_TICK_X()) */ + while (l_isRunning) { // the clock tick loop... + Sleep(l_tickMsec); // wait for the tick interval + QF_onClockTick(); // must call QTIMEEVT_TICK_X() } - (void)arg; /* unused parameter */ - - return 0U; /* return success */ + return 0U; // return success } +// Global objects ============================================================ +QPSet QF_readySet_; +QPSet QF_readySet_dis_; +HANDLE QF_win32Event_; // Win32 event to signal events +//============================================================================ +// QF functions + +//............................................................................ +void QF_init(void) { + QPSet_setEmpty(&QF_readySet_); +#ifndef Q_UNSAFE + QPSet_update_(&QF_readySet_, &QF_readySet_dis_); +#endif + + InitializeCriticalSection(&l_win32CritSect); + QF_win32Event_ = CreateEvent(NULL, FALSE, FALSE, NULL); +} + +//............................................................................ +void QF_enterCriticalSection_(void) { + if (l_isRunning) { + EnterCriticalSection(&l_win32CritSect); + } +} +//............................................................................ +void QF_leaveCriticalSection_(void) { + if (l_isRunning) { + LeaveCriticalSection(&l_win32CritSect); + } +} + +//............................................................................ +int QF_run(void) { + + QF_onStartup(); // application-specific startup callback + + QF_CRIT_STAT + + if (l_tickMsec != 0U) { // system clock tick configured? + // create the ticker thread... + HANDLE ticker = CreateThread(NULL, 1024, &ticker_thread, + (void *)0, 0U, NULL); + QF_CRIT_ENTRY(); + Q_ASSERT_INCRIT(310, ticker != 0); // thread must be created + QF_CRIT_EXIT(); + } + + // the combined event-loop and background-loop of the QV kernel + QF_CRIT_ENTRY(); + + // produce the QS_QF_RUN trace record + QS_BEGIN_PRE_(QS_QF_RUN, 0U) + QS_END_PRE_() + + l_isRunning = true; // QF is running + while (l_isRunning) { + Q_ASSERT_INCRIT(200, QPSet_verify_(&QF_readySet_, &QF_readySet_dis_)); + + // find the maximum priority AO ready to run + if (QPSet_notEmpty(&QF_readySet_)) { + uint_fast8_t p = QPSet_findMax(&QF_readySet_); + QActive *a = QActive_registry_[p]; + + // the active object 'a' must still be registered in QF + // (e.g., it must not be stopped) + Q_ASSERT_INCRIT(320, a != (QActive *)0); + QF_CRIT_EXIT(); + + QEvt const *e = QActive_get_(a); + // dispatch event (virtual call) + (*a->super.vptr->dispatch)(&a->super, e, a->prio); + QF_gc(e); + + QF_CRIT_ENTRY(); + if (a->eQueue.frontEvt == (QEvt *)0) { // empty queue? + QPSet_remove(&QF_readySet_, p); +#ifndef Q_UNSAFE + QPSet_update_(&QF_readySet_, &QF_readySet_dis_); +#endif + } + } + else { + // the QV kernel in embedded systems calls here the QV_onIdle() + // callback. However, the Win32-QV port does not do busy-waiting + // for events. Instead, the Win32-QV port efficiently waits until + // QP events become available. + QF_CRIT_EXIT(); + + WaitForSingleObject(QF_win32Event_, INFINITE); + + QF_CRIT_ENTRY(); + } + } + QF_CRIT_EXIT(); + QF_onCleanup(); // cleanup callback + QS_EXIT(); // cleanup the QSPY connection + + //CloseHandle(win32Event_); + //DeleteCriticalSection(&l_win32CritSect); + + return 0; // return success +} +//............................................................................ +void QF_stop(void) { + l_isRunning = false; // terminate the main event-loop + + // unblock the event-loop so it can terminate + QPSet_insert(&QF_readySet_, 1U); +#ifndef Q_UNSAFE + QPSet_update_(&QF_readySet_, &QF_readySet_dis_); +#endif + SetEvent(QF_win32Event_); +} +//............................................................................ +void QF_setTickRate(uint32_t ticksPerSec, int tickPrio) { + if (ticksPerSec != 0U) { + l_tickMsec = 1000UL / ticksPerSec; + } + else { + l_tickMsec = 0U; // means NO system clock tick + } + l_tickPrio = tickPrio; +} + +//............................................................................ +void QF_consoleSetup(void) { +} +//............................................................................ +void QF_consoleCleanup(void) { +} +//............................................................................ +int QF_consoleGetKey(void) { + if (_kbhit()) { // any key pressed? + return (int)_getwch(); + } + return 0; // no input at this time +} +//............................................................................ +int QF_consoleWaitForKey(void) { + return (int)_getwch(); +} + +// QActive functions ========================================================= + +void QActive_start_(QActive * const me, QPrioSpec const prioSpec, + QEvt const * * const qSto, uint_fast16_t const qLen, + void * const stkSto, uint_fast16_t const stkSize, + void const * const par) +{ + Q_UNUSED_PAR(stkSto); + Q_UNUSED_PAR(stkSize); + + // no per-AO stack needed for this port + QF_CRIT_STAT + QF_CRIT_ENTRY(); + Q_REQUIRE_INCRIT(600, stkSto == (void *)0); + QF_CRIT_EXIT(); + + me->prio = (uint8_t)(prioSpec & 0xFFU); // QF-priority of the AO + me->pthre = 0U; // preemption-threshold (not used in this port) + QActive_register_(me); // register this AO + + QEQueue_init(&me->eQueue, qSto, qLen); + + // top-most initial tran. (virtual call) + (*me->super.vptr->init)(&me->super, par, me->prio); + QS_FLUSH(); // flush the QS trace buffer to the host +} + +//............................................................................ +#ifdef QACTIVE_CAN_STOP +void QActive_stop(QActive * const me) { + QActive_unsubscribeAll(me); + + // make sure the AO is no longer in "ready set" + QF_CRIT_STAT + QF_CRIT_ENTRY(); + QPSet_remove(&QF_readySet_, me->prio); +#ifndef Q_UNSAFE + QPSet_update_(&QF_readySet_, &QF_readySet_dis_); +#endif + QF_CRIT_EXIT(); + + QActive_unregister_(me); +} +#endif +//............................................................................ +void QActive_setAttr(QActive *const me, uint32_t attr1, void const *attr2) { + Q_UNUSED_PAR(me); + Q_UNUSED_PAR(attr1); + Q_UNUSED_PAR(attr2); + Q_ERROR_INCRIT(900); // should not be called in this QP port +} diff --git a/ports/win32-qv/qf_port.h b/ports/win32-qv/qf_port.h deleted file mode 100644 index cff8a94d..00000000 --- a/ports/win32-qv/qf_port.h +++ /dev/null @@ -1,173 +0,0 @@ -/*============================================================================ -* QP/C Real-Time Embedded Framework (RTEF) -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2023-01-07 -* @version Last updated for: @ref qpc_7_2_0 -* -* @file -* @brief QF/C port to Win32 API (single-threaded, like the QV kernel) -*/ -#ifndef QF_PORT_H -#define QF_PORT_H - -/* Win32 event queue and thread types */ -#define QF_EQUEUE_TYPE QEQueue -/* QF_OS_OBJECT_TYPE not used */ -/* QF_THREAD_TYPE not used */ - -/* The maximum number of active objects in the application */ -#define QF_MAX_ACTIVE 64U - -/* The number of system clock tick rates */ -#define QF_MAX_TICK_RATE 2U - -/* Activate the QF QActive_stop() API */ -#define QF_ACTIVE_STOP 1 - -/* various QF object sizes configuration for this port */ -#define QF_EVENT_SIZ_SIZE 4U -#define QF_EQUEUE_CTR_SIZE 4U -#define QF_MPOOL_SIZ_SIZE 4U -#define QF_MPOOL_CTR_SIZE 4U -#define QF_TIMEEVT_CTR_SIZE 4U - -/* Win32 critical section, see NOTE1 */ -/* QF_CRIT_STAT_TYPE not defined */ -#define QF_CRIT_ENTRY(dummy) QF_enterCriticalSection_() -#define QF_CRIT_EXIT(dummy) QF_leaveCriticalSection_() - -/* QF_LOG2 not defined -- use the internal LOG2() implementation */ - -#include "qep_port.h" /* QEP port */ -#include "qequeue.h" /* Win32-QV needs the native event-queue */ -#include "qmpool.h" /* Win32-QV needs the native memory-pool */ -#include "qf.h" /* QF platform-independent public interface */ - -/* internal functions for critical section management */ -void QF_enterCriticalSection_(void); -void QF_leaveCriticalSection_(void); - -/* set clock tick rate (NOTE ticksPerSec==0 disables the "ticker thread") */ -void QF_setTickRate(uint32_t ticksPerSec, int_t tickPrio); - -/* clock tick callback (NOTE not called when "ticker thread" is not running) */ -void QF_onClockTick(void); - -/* special adaptations for QWIN GUI applications... */ -#ifdef QWIN_GUI - /* replace main() with main_gui() as the entry point to a GUI app. */ - #define main() main_gui() - int_t main_gui(void); /* prototype of the GUI application entry point */ -#endif - -/* abstractions for console access... */ -void QF_consoleSetup(void); -void QF_consoleCleanup(void); -int QF_consoleGetKey(void); -int QF_consoleWaitForKey(void); - -/****************************************************************************/ -/* interface used only inside QF implementation, but not in applications */ -#ifdef QP_IMPL - - /* Win32-QV specific scheduler locking, see NOTE2 */ - #define QF_SCHED_STAT_ - #define QF_SCHED_LOCK_(dummy) ((void)0) - #define QF_SCHED_UNLOCK_() ((void)0) - - /* Win32-QV active object event queue customization... */ - #define QACTIVE_EQUEUE_WAIT_(me_) \ - Q_ASSERT_ID(0, (me_)->eQueue.frontEvt != (QEvt *)0) - #define QACTIVE_EQUEUE_SIGNAL_(me_) \ - QPSet_insert(&QF_readySet_, (me_)->prio); \ - (void)SetEvent(QV_win32Event_) - - /* native QF event pool operations */ - #define QF_EPOOL_TYPE_ QMPool - #define QF_EPOOL_INIT_(p_, poolSto_, poolSize_, evtSize_) \ - (QMPool_init(&(p_), (poolSto_), (poolSize_), (evtSize_))) - #define QF_EPOOL_EVENT_SIZE_(p_) ((uint_fast16_t)(p_).blockSize) - #define QF_EPOOL_GET_(p_, e_, m_, qs_id_) \ - ((e_) = (QEvt *)QMPool_get(&(p_), (m_), (qs_id_))) - #define QF_EPOOL_PUT_(p_, e_, qs_id_) \ - (QMPool_put(&(p_), (e_), (qs_id_))) - - /* Minimum required Windows version is Windows-XP or newer (0x0501) */ - #ifdef WINVER - #undef WINVER - #endif - #ifdef _WIN32_WINNT - #undef _WIN32_WINNT - #endif - - #define WINVER _WIN32_WINNT_WINXP - #define _WIN32_WINNT _WIN32_WINNT_WINXP - - #define WIN32_LEAN_AND_MEAN - #include /* Win32 API */ - - extern HANDLE QV_win32Event_; /* Win32 event to signal events */ - -#endif /* QP_IMPL */ - -/* NOTES: ==================================================================*/ -/* -* NOTE1: -* QF, like all real-time frameworks, needs to execute certain sections of -* code exclusively, meaning that only one thread can execute the code at -* the time. Such sections of code are called "critical sections" -* -* This port uses a pair of functions QF_enterCriticalSection_() / -* QF_leaveCriticalSection_() to enter/leave the cirtical section, -* respectively. -* -* These functions are implemented in the qf_port.c module, where they -* manipulate the file-scope Win32 critical section object l_win32CritSect -* to protect all critical sections. Using the single critical section -* object for all crtical section guarantees that only one thread at a time -* can execute inside a critical section. This prevents race conditions and -* data corruption. -* -* Please note, however, that the Win32 critical section implementation -* behaves differently than interrupt disabling. A common Win32 critical -* section ensures that only one thread at a time can execute a critical -* section, but it does not guarantee that a context switch cannot occur -* within the critical section. In fact, such context switches probably -* will happen, but they should not cause concurrency hazards because the -* critical section eliminates all race conditionis. -* -* Unlinke simply disabling and enabling interrupts, the critical section -* approach is also subject to priority inversions. Various versions of -* Windows handle priority inversions differently, but it seems that most of -* them recognize priority inversions and dynamically adjust the priorities of -* threads to prevent it. Please refer to the MSN articles for more -* information. -* -* NOTE2: -* Scheduler locking (used inside QF_publish_()) is not needed in the single- -* threaded Win32-QV port, because event multicasting is already atomic. -*/ - -#endif /* QF_PORT_H */ diff --git a/ports/win32-qv/qp_port.h b/ports/win32-qv/qp_port.h new file mode 100644 index 00000000..898ebe49 --- /dev/null +++ b/ports/win32-qv/qp_port.h @@ -0,0 +1,214 @@ +//============================================================================ +// QP/C Real-Time Embedded Framework (RTEF) +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC . +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +//============================================================================ +//! @date Last updated on: 2023-09-07 +//! @version Last updated for: @ref qpc_7_3_0 +//! +//! @file +//! @brief QP/C port to Win32-QV (single-threaded) with GNU or Visual C/C++ + +#ifndef QP_PORT_H_ +#define QP_PORT_H_ + +#include // Exact-width types. WG14/N843 C99 Standard +#include // Boolean type. WG14/N843 C99 Standard + +#ifdef QP_CONFIG +#include "qp_config.h" // external QP configuration +#endif + +#ifdef __GNUC__ + + // no-return function specifier (GCC-ARM compiler) + #define Q_NORETURN __attribute__ ((noreturn)) void + +#elif (defined _MSC_VER) + #ifdef __cplusplus + // no-return function specifier (Microsoft Visual Studio C++ compiler) + #define Q_NORETURN [[ noreturn ]] void + #else + // no-return function specifier C11 + #define Q_NORETURN _Noreturn void + #endif + + // This is the case where QP/C is compiled by the Microsoft Visual C++ + // compiler in the C++ mode, which can happen when qep_port.h is included + // in a C++ module, or the compilation is forced to C++ by the option /TP. + // + // The following pragma suppresses the level-4 C++ warnings C4510, C4512, + // and C4610, which warn that default constructors and assignment operators + // could not be generated for structures QMState and QMTranActTable. + // + // The QP/C source code cannot be changed to avoid these C++ warnings + // because the structures QMState and QMTranActTable must remain PODs + // (Plain Old Datatypes) to be initializable statically with constant + // initializers. + // + #pragma warning (disable: 4510 4512 4610) + +#endif + +// QF event queue and thread types for Win32-QV +#define QACTIVE_EQUEUE_TYPE QEQueue +//QACTIVE_OS_OBJ_TYPE not used in this port +//QACTIVE_THREAD_TYPE not used in this port + +// QF critical section for Win32-QV, see NOTE1 +#define QF_CRIT_STAT +#define QF_CRIT_ENTRY() QF_enterCriticalSection_() +#define QF_CRIT_EXIT() QF_leaveCriticalSection_() + +// QF_LOG2 not defined -- use the internal LOG2() implementation + +// internal functions for critical section management +void QF_enterCriticalSection_(void); +void QF_leaveCriticalSection_(void); + +// set clock tick rate and p-thread priority +// (NOTE ticksPerSec==0 disables the "ticker thread" +void QF_setTickRate(uint32_t ticksPerSec, int tickPrio); + +// clock tick callback (NOTE not called when "ticker thread" is not running) +void QF_onClockTick(void); + +// abstractions for console access... +void QF_consoleSetup(void); +void QF_consoleCleanup(void); +int QF_consoleGetKey(void); +int QF_consoleWaitForKey(void); + +// special adaptations for QWIN GUI applications +#ifdef QWIN_GUI + // replace main() with main_gui() as the entry point to a GUI app. + #define main() main_gui() + int main_gui(void); // prototype of the GUI application entry point +#endif + +// include files ------------------------------------------------------------- +#include "qequeue.h" // Win32-QV needs the native event-queue +#include "qmpool.h" // Win32-QV needs the native memory-pool +#include "qp.h" // QP platform-independent public interface + +#ifdef _MSC_VER + #pragma warning (default: 4510 4512 4610) +#endif + +//============================================================================ +// interface used only inside QF implementation, but not in applications + +#ifdef QP_IMPL + + // QF scheduler locking for Win32-QV (not needed in single-thread port) + #define QF_SCHED_STAT_ + #define QF_SCHED_LOCK_(dummy) ((void)0) + #define QF_SCHED_UNLOCK_() ((void)0) + + // QF event queue customization for Win32-QV... + #define QACTIVE_EQUEUE_WAIT_(me_) \ + Q_ASSERT_INCRIT(302, (me_)->eQueue.frontEvt != (QEvt *)0) +#ifndef Q_UNSAFE + #define QACTIVE_EQUEUE_SIGNAL_(me_) \ + QPSet_insert(&QF_readySet_, (me_)->prio); \ + QPSet_update_(&QF_readySet_, &QF_readySet_dis_); \ + (void)SetEvent(QF_win32Event_) +#else + #define QACTIVE_EQUEUE_SIGNAL_(me_) \ + QPSet_insert(&QF_readySet_, (me_)->prio); \ + (void)SetEvent(QF_win32Event_) +#endif + + // native QF event pool operations + #define QF_EPOOL_TYPE_ QMPool + #define QF_EPOOL_INIT_(p_, poolSto_, poolSize_, evtSize_) \ + (QMPool_init(&(p_), (poolSto_), (poolSize_), (evtSize_))) + #define QF_EPOOL_EVENT_SIZE_(p_) ((uint_fast16_t)(p_).blockSize) + #define QF_EPOOL_GET_(p_, e_, m_, qs_id_) \ + ((e_) = (QEvt *)QMPool_get(&(p_), (m_), (qs_id_))) + #define QF_EPOOL_PUT_(p_, e_, qs_id_) \ + (QMPool_put(&(p_), (e_), (qs_id_))) + + // Minimum required Windows version is Windows-XP or newer (0x0501) + #ifdef WINVER + #undef WINVER + #endif + #ifdef _WIN32_WINNT + #undef _WIN32_WINNT + #endif + + #define WINVER _WIN32_WINNT_WINXP + #define _WIN32_WINNT _WIN32_WINNT_WINXP + + #define WIN32_LEAN_AND_MEAN + #include // Win32 API + + extern QPSet QF_readySet_; + extern QPSet QF_readySet_dis_; + extern HANDLE QF_win32Event_; // Win32 event to signal events + +#endif // QP_IMPL + +//============================================================================ +// NOTE1: +// QP, like all real-time frameworks, needs to execute certain sections of +// code exclusively, meaning that only one thread can execute the code at +// the time. Such sections of code are called "critical sections". +// +// This port uses a pair of functions QF_enterCriticalSection_() / +// QF_leaveCriticalSection_() to enter/leave the critical section, +// respectively. +// +// These functions are implemented in the qf_port.c module, where they +// manipulate the file-scope Win32 critical section object l_win32CritSect +// to protect all critical sections. Using the single critical section +// object for all critical section guarantees that only one thread at a time +// can execute inside a critical section. This prevents race conditions and +// data corruption. +// +// Please note, however, that the Win32 critical section implementation +// behaves differently than interrupt disabling. A common Win32 critical +// section ensures that only one thread at a time can execute a critical +// section, but it does not guarantee that a context switch cannot occur +// within the critical section. In fact, such context switches probably +// will happen, but they should not cause concurrency hazards because the +// critical section eliminates all race conditions. +// +// Unlike simply disabling and enabling interrupts, the critical section +// approach is also subject to priority inversions. Various versions of +// Windows handle priority inversions differently, but it seems that most of +// them recognize priority inversions and dynamically adjust the priorities of +// threads to prevent it. Please refer to the MSN articles for more +// information. +// +// NOTE2: +// Scheduler locking (used inside QF_publish_()) is not needed in the single- +// threaded Win32-QV port, because event multicasting is already atomic. +// + +#endif // QP_PORT_H_ + diff --git a/ports/win32-qv/qs_port.c b/ports/win32-qv/qs_port.c index fd9d651a..eedc7465 100644 --- a/ports/win32-qv/qs_port.c +++ b/ports/win32-qv/qs_port.c @@ -1,50 +1,49 @@ -/*============================================================================ -* QP/C Real-Time Embedded Framework (RTEF) -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2023-01-07 -* @version Last updated for: @ref qpc_7_2_0 -* -* @file -* @brief QS/C port for Win32 API -*/ +//============================================================================ +// QP/C Real-Time Embedded Framework (RTEF) +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +//============================================================================ +//! @date Last updated on: 2023-08-20 +//! @version Last updated for: @ref qpc_7_3_0 +//! +//! @file +//! @brief QS/C port for Win32 API + #ifndef Q_SPY #error "Q_SPY must be defined to compile qs_port.c" -#endif /* Q_SPY */ +#endif // Q_SPY -#define QP_IMPL /* this is QP implementation */ -#include "qf_port.h" /* QF port */ -#include "qassert.h" /* QP embedded systems-friendly assertions */ -#include "qs_port.h" /* QS port */ -#include "qs_pkg.h" /* QS package-scope interface */ +#define QP_IMPL // this is QP implementation +#include "qp_port.h" // QP port +#include "qsafe.h" // QP Functional Safety (FuSa) System +#include "qs_port.h" // QS port +#include "qs_pkg.h" // QS package-scope interface -#include "safe_std.h" /* portable "safe" / facilities */ +#include "safe_std.h" // portable "safe" / facilities #include #include #include -/* Minimum required Windows version is Windows-XP or newer (0x0501) */ +// Minimum required Windows version is Windows-XP or newer (0x0501) #ifdef WINVER #undef WINVER #endif @@ -57,22 +56,27 @@ #include -/*Q_DEFINE_THIS_MODULE("qs_port")*/ +//Q_DEFINE_THIS_MODULE("qs_port") #define QS_TX_SIZE (8*1024) #define QS_RX_SIZE (2*1024) #define QS_TX_CHUNK QS_TX_SIZE -#define QS_TIMEOUT_MS 10 +#define QS_TIMEOUT_MS 10U -/* local variables .........................................................*/ +// local variables ......................................................... static SOCKET l_sock = INVALID_SOCKET; -/*..........................................................................*/ +//............................................................................ uint8_t QS_onStartup(void const *arg) { - static uint8_t qsBuf[QS_TX_SIZE]; /* buffer for QS-TX channel */ - static uint8_t qsRxBuf[QS_RX_SIZE]; /* buffer for QS-RX channel */ + // initialize the QS transmit and receive buffers + static uint8_t qsBuf[QS_TX_SIZE]; // buffer for QS-TX channel + QS_initBuf(qsBuf, sizeof(qsBuf)); + + static uint8_t qsRxBuf[QS_RX_SIZE]; // buffer for QS-RX channel + QS_rxInitBuf(qsRxBuf, sizeof(qsRxBuf)); + char hostName[128]; - char const *serviceName = "6601"; /* default QSPY server port */ + char const *serviceName = "6601"; // default QSPY server port char const *src; char *dst; int status; @@ -84,21 +88,17 @@ uint8_t QS_onStartup(void const *arg) { ULONG ioctl_opt; WSADATA wsaData; - /* initialize the QS transmit and receive buffers */ - QS_initBuf(qsBuf, sizeof(qsBuf)); - QS_rxInitBuf(qsRxBuf, sizeof(qsRxBuf)); - - /* initialize Windows sockets version 2.2 */ + // initialize Windows sockets version 2.2 if (WSAStartup(MAKEWORD(2, 2), &wsaData) != NO_ERROR) { FPRINTF_S(stderr, " ERROR %s\n", "Windows Sockets cannot be initialized"); goto error; } - /* extract hostName from 'arg' (hostName:port_remote)... */ + // extract hostName from 'arg' (hostName:port_remote)... src = (arg != (void *)0) ? (char const *)arg - : "localhost"; /* default QSPY host */ + : "localhost"; // default QSPY host dst = hostName; while ((*src != '\0') && (*src != ':') @@ -106,9 +106,9 @@ uint8_t QS_onStartup(void const *arg) { { *dst++ = *src++; } - *dst = '\0'; /* zero-terminate hostName */ + *dst = '\0'; // zero-terminate hostName - /* extract serviceName from 'arg' (hostName:serviceName)... */ + // extract serviceName from 'arg' (hostName:serviceName)... if (*src == ':') { serviceName = src + 1; } @@ -140,7 +140,7 @@ uint8_t QS_onStartup(void const *arg) { freeaddrinfo(result); - /* socket could not be opened & connected? */ + // socket could not be opened & connected? if (l_sock == INVALID_SOCKET) { FPRINTF_S(stderr, " ERROR cannot connect to QSPY at " "host=%s:%s\n", @@ -148,7 +148,7 @@ uint8_t QS_onStartup(void const *arg) { goto error; } - /* set the socket to non-blocking mode */ + // set the socket to non-blocking mode ioctl_opt = 1; if (ioctlsocket(l_sock, FIONBIO, &ioctl_opt) != NO_ERROR) { FPRINTF_S(stderr, " ERROR %s WASErr=%d\n,", @@ -156,144 +156,144 @@ uint8_t QS_onStartup(void const *arg) { goto error; } - /* configure the socket to reuse the address and not to linger */ + // configure the socket to reuse the address and not to linger sockopt_bool = TRUE; setsockopt(l_sock, SOL_SOCKET, SO_REUSEADDR, (const char *)&sockopt_bool, sizeof(sockopt_bool)); sockopt_bool = TRUE; setsockopt(l_sock, SOL_SOCKET, SO_DONTLINGER, (const char *)&sockopt_bool, sizeof(sockopt_bool)); + //PRINTF_S(" Connected to QSPY at Host=%s:%d\n", + // hostName, port_remote); QS_onFlush(); - return 1U; /* success */ + return 1U; // success error: - return 0U; /* failure */ + return 0U; // failure } -/*..........................................................................*/ +//............................................................................ void QS_onCleanup(void) { + Sleep(QS_TIMEOUT_MS * 10U); // allow the last QS output to come out if (l_sock != INVALID_SOCKET) { closesocket(l_sock); l_sock = INVALID_SOCKET; } WSACleanup(); - /*PRINTF_S(" Disconnected from QSPY\n");*/ + //PRINTF_S(" Disconnected from QSPY\n"); } -/*..........................................................................*/ +//............................................................................ void QS_onReset(void) { QS_onCleanup(); + //PRINTF_S("\n%s\n", "QS_onReset"); exit(0); } -/*..........................................................................*/ +//............................................................................ void QS_onFlush(void) { - uint16_t nBytes; - uint8_t const *data; - QS_CRIT_STAT_ - - if (l_sock == INVALID_SOCKET) { /* socket NOT initialized? */ + if (l_sock == INVALID_SOCKET) { // socket NOT initialized? FPRINTF_S(stderr, " ERROR %s\n", "invalid TCP socket"); + QF_stop(); // <== stop and exit the application return; } - nBytes = QS_TX_CHUNK; - QS_CRIT_E_(); + QS_CRIT_STAT + QS_CRIT_ENTRY(); + uint16_t nBytes = QS_TX_CHUNK; + uint8_t const *data; while ((data = QS_getBlock(&nBytes)) != (uint8_t *)0) { - QS_CRIT_X_(); - for (;;) { /* for-ever until break or return */ + QS_CRIT_EXIT(); + for (;;) { // for-ever until break or return int nSent = send(l_sock, (char const *)data, (int)nBytes, 0); - if (nSent == SOCKET_ERROR) { /* sending failed? */ + if (nSent == SOCKET_ERROR) { // sending failed? int err = WSAGetLastError(); if (err == WSAEWOULDBLOCK) { - /* sleep for the timeout and then loop back - * to send() the SAME data again - */ + // sleep for the timeout and then loop back + // to send() the SAME data again Sleep(QS_TIMEOUT_MS); } - else { /* some other socket error... */ + else { // some other socket error... FPRINTF_S(stderr, " ERROR %s WASErr=%d\n", "sending data over TCP", err); + QF_stop(); // <== stop and exit the application return; } } - else if (nSent < (int)nBytes) { /* sent fewer than requested? */ - Sleep(QS_TIMEOUT_MS); /* sleep for the timeout */ - /* adjust the data and loop back to send() the rest */ + else if (nSent < (int)nBytes) { // sent fewer than requested? + Sleep(QS_TIMEOUT_MS); // sleep for the timeout + // adjust the data and loop back to send() the rest data += nSent; nBytes -= (uint16_t)nSent; } else { - break; /* break out of the for-ever loop */ + break; // break out of the for-ever loop } } - /* set nBytes for the next call to QS_getBlock() */ + // set nBytes for the next call to QS_getBlock() nBytes = QS_TX_CHUNK; - QS_CRIT_E_(); + QS_CRIT_ENTRY(); } - QS_CRIT_X_(); + QS_CRIT_EXIT(); } -/*..........................................................................*/ +//............................................................................ QSTimeCtr QS_onGetTime(void) { LARGE_INTEGER time; QueryPerformanceCounter(&time); return (QSTimeCtr)time.QuadPart; } -/*..........................................................................*/ +//............................................................................ void QS_output(void) { - uint16_t nBytes; - uint8_t const *data; - QS_CRIT_STAT_ - - if (l_sock == INVALID_SOCKET) { /* socket NOT initialized? */ + if (l_sock == INVALID_SOCKET) { // socket NOT initialized? FPRINTF_S(stderr, " ERROR %s\n", "invalid TCP socket"); + QF_stop(); // <== stop and exit the application return; } - nBytes = QS_TX_CHUNK; - QS_CRIT_E_(); - if ((data = QS_getBlock(&nBytes)) != (uint8_t *)0) { - QS_CRIT_X_(); - for (;;) { /* for-ever until break or return */ + QS_CRIT_STAT + QS_CRIT_ENTRY(); + uint16_t nBytes = QS_TX_CHUNK; + uint8_t const *data = QS_getBlock(&nBytes); + QS_CRIT_EXIT(); + + if (nBytes > 0U) { // any bytes to send? + for (;;) { // for-ever until break or return int nSent = send(l_sock, (char const *)data, (int)nBytes, 0); - if (nSent == SOCKET_ERROR) { /* sending failed? */ + if (nSent == SOCKET_ERROR) { // sending failed? int err = WSAGetLastError(); if (err == WSAEWOULDBLOCK) { - /* sleep for the timeout and then loop back - * to send() the SAME data again - */ + // sleep for the timeout and then loop back + // to send() the SAME data again Sleep(QS_TIMEOUT_MS); } - else { /* some other socket error... */ + else { // some other socket error... FPRINTF_S(stderr, " ERROR sending data over TCP," "WASErr=%d\n", err); + QF_stop(); // <== stop and exit the application return; } } - else if (nSent < (int)nBytes) { /* sent fewer than requested? */ - Sleep(QS_TIMEOUT_MS); /* sleep for the timeout */ - /* adjust the data and loop back to send() the rest */ + else if (nSent < (int)nBytes) { // sent fewer than requested? + Sleep(QS_TIMEOUT_MS); // sleep for the timeout + // adjust the data and loop back to send() the rest data += nSent; nBytes -= (uint16_t)nSent; } else { - break; + break; // break out of the for-ever loop } } } - else { - QS_CRIT_X_(); - } } -/*..........................................................................*/ +//............................................................................ void QS_rx_input(void) { int status = recv(l_sock, (char *)QS_rxPriv_.buf, (int)QS_rxPriv_.end, 0); - if (status > 0) { /* any data received? */ + if (status > 0) { // any data received? QS_rxPriv_.tail = 0U; - QS_rxPriv_.head = status; /* # bytes received */ - QS_rxParse(); /* parse all received bytes */ + QS_rxPriv_.head = status; // # bytes received + QS_rxParse(); // parse all received bytes } } diff --git a/ports/win32-qv/qs_port.h b/ports/win32-qv/qs_port.h index 103ecd1b..fed3284f 100644 --- a/ports/win32-qv/qs_port.h +++ b/ports/win32-qv/qs_port.h @@ -1,63 +1,61 @@ -/*============================================================================ -* QP/C Real-Time Embedded Framework (RTEF) -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2023-01-07 -* @version Last updated for: @ref qpc_7_2_0 -* -* @file -* @brief QS/C port to Win32 with GNU or Visual C++ compilers -*/ -#ifndef QS_PORT_H -#define QS_PORT_H +//============================================================================ +// QP/C Real-Time Embedded Framework (RTEF) +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +//============================================================================ +//! @date Last updated on: 2023-08-16 +//! @version Last updated for: @ref qpc_7_3_0 +//! +//! @file +//! @brief QS/C port to Win32 with GNU or Visual C++ compilers + +#ifndef QS_PORT_H_ +#define QS_PORT_H_ #define QS_CTR_SIZE 4U #define QS_TIME_SIZE 4U -#ifdef _WIN64 /* 64-bit architecture? */ +#ifdef _WIN64 // 64-bit architecture? #define QS_OBJ_PTR_SIZE 8U #define QS_FUN_PTR_SIZE 8U -#else /* 32-bit architecture */ +#else // 32-bit architecture #define QS_OBJ_PTR_SIZE 4U #define QS_FUN_PTR_SIZE 4U #endif -void QS_output(void); /* handle the QS output */ -void QS_rx_input(void); /* handle the QS-RX input */ +void QS_output(void); // handle the QS output +void QS_rx_input(void); // handle the QS-RX input -/*==========================================================================*/ -/* NOTE: QS might be used with or without other QP components, in which -* case the separate definitions of the macros QF_CRIT_STAT_TYPE, -* QF_CRIT_ENTRY, and QF_CRIT_EXIT are needed. In this port QS is configured -* to be used with the other QP component, by simply including "qf_port.h" -* *before* "qs.h". -*/ -#ifndef QF_PORT_H -#include "qf_port.h" /* use QS with QF */ +//============================================================================ +// NOTE: QS might be used with or without other QP components, in which +// case the separate definitions of the macros QF_CRIT_STAT, QF_CRIT_ENTRY(), +// and QF_CRIT_EXIT() are needed. In this port QS is configured to be used +// with the other QP component, by simply including "qp_port.h" +//*before* "qs.h". +#ifndef QP_PORT_H_ +#include "qp_port.h" // use QS with QP #endif -#include "qs.h" /* QS platform-independent public interface */ +#include "qs.h" // QS platform-independent public interface -#endif /* QS_PORT_H */ +#endif // QS_PORT_H_ diff --git a/ports/win32-qv/qwin_gui.c b/ports/win32-qv/qwin_gui.c index 48e4ef96..eb61ece0 100644 --- a/ports/win32-qv/qwin_gui.c +++ b/ports/win32-qv/qwin_gui.c @@ -1,41 +1,41 @@ -/*============================================================================ -* QP/C Real-Time Embedded Framework (RTEF) -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2022-06-12 -* @version Last updated for: @ref qpc_7_0_1 -* -* @file -* @brief QWIN GUI facilities for building realistic embedded front panels -*/ +//============================================================================ +// QP/C Real-Time Embedded Framework (RTEF) +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +//============================================================================ +//! +//! @date Last updated on: 2022-06-12 +//! @version Last updated for: @ref qpc_7_0_1 +//! +//! @file +//! @brief QWIN GUI facilities for building realistic embedded front panels +//! #include "qwin_gui.h" #include static HWND l_hWnd; static HDC l_hDC; -/*--------------------------------------------------------------------------*/ +//-------------------------------------------------------------------------- HWND CreateCustDialog(HINSTANCE hInst, int iDlg, HWND hParent, WNDPROC lpfnWndProc, LPCTSTR lpWndClass) { @@ -57,19 +57,19 @@ HWND CreateCustDialog(HINSTANCE hInst, int iDlg, HWND hParent, RegisterClassEx(&wndclass); l_hWnd = CreateDialog(hInst, MAKEINTRESOURCE(iDlg), hParent, NULL); - l_hDC = GetDC(l_hWnd); /* obtain the DC for the client area of the window */ + l_hDC = GetDC(l_hWnd); // obtain the DC for the client area of the window - /* NOTE: WM_INITDIALOG provides stimulus for initializing dialog controls. - * Dialog box procedures typically use this message to initialize controls - * and carry out any other initialization tasks that affect the appearance - * of the dialog box. - */ + // NOTE: WM_INITDIALOG provides stimulus for initializing dialog controls. + // Dialog box procedures typically use this message to initialize controls + // and carry out any other initialization tasks that affect the appearance + // of the dialog box. + // SendMessage(l_hWnd, WM_INITDIALOG, (WPARAM)0, (LPARAM)0); return l_hWnd; } -/*--------------------------------------------------------------------------*/ +//-------------------------------------------------------------------------- void OwnerDrawnButton_init(OwnerDrawnButton * const me, UINT itemID, HBITMAP hBitmapUp, HBITMAP hBitmapDwn, @@ -81,13 +81,13 @@ void OwnerDrawnButton_init(OwnerDrawnButton * const me, me->hCursor = hCursor; me->isDepressed = 0; } -/*..........................................................................*/ +//............................................................................ void OwnerDrawnButton_xtor(OwnerDrawnButton * const me) { DeleteObject(me->hBitmapUp); DeleteObject(me->hBitmapDown); DeleteObject(me->hCursor); } -/*..........................................................................*/ +//............................................................................ enum OwnerDrawnButtonAction OwnerDrawnButton_draw( OwnerDrawnButton * const me, LPDRAWITEMSTRUCT lpdis) @@ -98,7 +98,7 @@ enum OwnerDrawnButtonAction OwnerDrawnButton_draw( if (me->hCursor != NULL) { SetClassLongPtr(lpdis->hwndItem, GCLP_HCURSOR, (LONG_PTR)me->hCursor); - me->hCursor = NULL; /* mark the cursor set */ + me->hCursor = NULL; // mark the cursor set } DrawBitmap(lpdis->hDC, me->hBitmapUp, lpdis->rcItem.left, lpdis->rcItem.top); @@ -113,16 +113,16 @@ enum OwnerDrawnButtonAction OwnerDrawnButton_draw( ret = BTN_DEPRESSED; } else { - /* NOTE: the bitmap for button "UP" look will be - * drawn in the ODA_DRAWENTIRE action - */ + // NOTE: the bitmap for button "UP" look will be + // drawn in the ODA_DRAWENTIRE action + // me->isDepressed = 0; ret = BTN_RELEASED; } } return ret; } -/*..........................................................................*/ +//............................................................................ void OwnerDrawnButton_set(OwnerDrawnButton * const me, int isDepressed) { if (me->isDepressed != isDepressed) { HWND hItem = GetDlgItem(l_hWnd, me->itemID); @@ -135,12 +135,12 @@ void OwnerDrawnButton_set(OwnerDrawnButton * const me, int isDepressed) { } } } -/*..........................................................................*/ +//............................................................................ BOOL OwnerDrawnButton_isDepressed(OwnerDrawnButton const * const me) { return me->isDepressed; } -/*--------------------------------------------------------------------------*/ +//-------------------------------------------------------------------------- void GraphicDisplay_init(GraphicDisplay * const me, UINT width, UINT height, UINT itemID, BYTE const bgColor[3]) @@ -161,8 +161,8 @@ void GraphicDisplay_init(GraphicDisplay * const me, me->bgColor[1] = bgColor[1]; me->bgColor[2] = bgColor[2]; - bi24BitInfo.bmiHeader.biBitCount = 3U*8U; /* 3 RGB bytes */ - bi24BitInfo.bmiHeader.biCompression = BI_RGB; /* RGB color */ + bi24BitInfo.bmiHeader.biBitCount = 3U*8U; // 3 RGB bytes + bi24BitInfo.bmiHeader.biCompression = BI_RGB; // RGB color bi24BitInfo.bmiHeader.biPlanes = 1U; bi24BitInfo.bmiHeader.biSize = sizeof(bi24BitInfo.bmiHeader); bi24BitInfo.bmiHeader.biWidth = me->src_width; @@ -176,13 +176,13 @@ void GraphicDisplay_init(GraphicDisplay * const me, GraphicDisplay_clear(me); GraphicDisplay_redraw(me); } -/*..........................................................................*/ +//............................................................................ void GraphicDisplay_xtor(GraphicDisplay * const me) { DeleteDC(me->src_hDC); DeleteObject(me->hBitmap); OutputDebugString("GraphicDisplay_xtor\n"); } -/*..........................................................................*/ +//............................................................................ void GraphicDisplay_clear(GraphicDisplay * const me) { UINT n; BYTE r = me->bgColor[0]; @@ -196,13 +196,13 @@ void GraphicDisplay_clear(GraphicDisplay * const me) { bits[2] = r; } } -/*..........................................................................*/ +//............................................................................ void GraphicDisplay_redraw(GraphicDisplay * const me) { StretchBlt(me->dst_hDC, 0, 0, me->dst_width, me->dst_height, me->src_hDC, 0, 0, me->src_width, me->src_height, SRCCOPY); } -/* SegmentDisplay ----------------------------------------------------------*/ +// SegmentDisplay ---------------------------------------------------------- void SegmentDisplay_init(SegmentDisplay * const me, UINT segmentNum, UINT bitmapNum) { @@ -219,7 +219,7 @@ void SegmentDisplay_init(SegmentDisplay * const me, me->hBitmap[n] = NULL; } } -/*..........................................................................*/ +//............................................................................ void SegmentDisplay_xtor(SegmentDisplay * const me) { UINT n; @@ -233,7 +233,7 @@ void SegmentDisplay_xtor(SegmentDisplay * const me) { } free(me->hBitmap); } -/*..........................................................................*/ +//............................................................................ BOOL SegmentDisplay_initSegment(SegmentDisplay * const me, UINT segmentNum, UINT segmentID) { @@ -245,7 +245,7 @@ BOOL SegmentDisplay_initSegment(SegmentDisplay * const me, return FALSE; } } -/*..........................................................................*/ +//............................................................................ BOOL SegmentDisplay_initBitmap(SegmentDisplay * const me, UINT bitmapNum, HBITMAP hBitmap) { @@ -257,7 +257,7 @@ BOOL SegmentDisplay_initBitmap(SegmentDisplay * const me, return FALSE; } } -/*..........................................................................*/ +//............................................................................ BOOL SegmentDisplay_setSegment(SegmentDisplay * const me, UINT segmentNum, UINT bitmapNum) { @@ -272,10 +272,10 @@ BOOL SegmentDisplay_setSegment(SegmentDisplay * const me, } } -/*--------------------------------------------------------------------------*/ -/* DrawBitmap() function adapted from the book "Programming Windows" by -* Charles Petzold. -*/ +//-------------------------------------------------------------------------- +// DrawBitmap() function adapted from the book "Programming Windows" by +// Charles Petzold. +// void DrawBitmap(HDC hdc, HBITMAP hBitmap, int xStart, int yStart) { diff --git a/ports/win32-qv/qwin_gui.h b/ports/win32-qv/qwin_gui.h index f0531374..36a517e5 100644 --- a/ports/win32-qv/qwin_gui.h +++ b/ports/win32-qv/qwin_gui.h @@ -1,34 +1,34 @@ -/*============================================================================ -* QP/C Real-Time Embedded Framework (RTEF) -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2022-06-12 -* @version Last updated for: @ref qpc_7_0_1 -* -* @file -* @brief QWIN GUI facilities for building realistic embedded front panels -*/ +//============================================================================ +// QP/C Real-Time Embedded Framework (RTEF) +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +//============================================================================ +//! +//! @date Last updated on: 2022-06-12 +//! @version Last updated for: @ref qpc_7_0_1 +//! +//! @file +//! @brief QWIN GUI facilities for building realistic embedded front panels +//! #ifndef QWIN_GUI_H #define QWIN_GUI_H @@ -37,17 +37,17 @@ #endif #define WIN32_LEAN_AND_MEAN -#include /* Win32 API */ +#include // Win32 API #ifdef __cplusplus extern "C" { #endif -/* create the custom dialog hosting the embedded front panel ...............*/ +// create the custom dialog hosting the embedded front panel ............... HWND CreateCustDialog(HINSTANCE hInst, int iDlg, HWND hParent, WNDPROC lpfnWndProc, LPCTSTR lpWndClass); -/* OwnerDrawnButton "class" ................................................*/ +// OwnerDrawnButton "class" ................................................ typedef struct { UINT itemID; HBITMAP hBitmapUp; @@ -75,9 +75,9 @@ void OwnerDrawnButton_set(OwnerDrawnButton * const me, int isDepressed); BOOL OwnerDrawnButton_isDepressed(OwnerDrawnButton const * const me); -/* GraphicDisplay "class" for drawing graphic displays -* with up to 24-bit color... -*/ +// GraphicDisplay "class" for drawing graphic displays +// with up to 24-bit color... +// typedef struct { HDC src_hDC; int src_width; @@ -113,12 +113,12 @@ void GraphicDisplay_redraw(GraphicDisplay * const me); pixelRGB[2] = (me_)->bgColor[2]; \ } while (false) -/* SegmentDisplay "class" for drawing segment displays, LEDs, etc...........*/ +// SegmentDisplay "class" for drawing segment displays, LEDs, etc........... typedef struct { - HWND *hSegment; /* array of segment controls */ - UINT segmentNum; /* number of segments */ - HBITMAP *hBitmap; /* array of bitmap handles */ - UINT bitmapNum; /* number of bitmaps */ + HWND *hSegment; // array of segment controls + UINT segmentNum; // number of segments + HBITMAP *hBitmap; // array of bitmap handles + UINT bitmapNum; // number of bitmaps } SegmentDisplay; void SegmentDisplay_init(SegmentDisplay * const me, @@ -131,11 +131,11 @@ BOOL SegmentDisplay_initBitmap(SegmentDisplay * const me, BOOL SegmentDisplay_setSegment(SegmentDisplay * const me, UINT segmentNum, UINT bitmapNum); -/* useful helper functions .................................................*/ +// useful helper functions ................................................. void DrawBitmap(HDC hdc, HBITMAP hBitmap, int xStart, int yStart); #ifdef __cplusplus } #endif -#endif /* QWIN_GUI_H */ +#endif // QWIN_GUI_H diff --git a/ports/win32-qv/safe_std.h b/ports/win32-qv/safe_std.h index b4a1f511..c752662c 100644 --- a/ports/win32-qv/safe_std.h +++ b/ports/win32-qv/safe_std.h @@ -1,42 +1,40 @@ -/*============================================================================ -* QP/C Real-Time Embedded Framework (RTEF) -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2022-07-30 -* @version Last updated for: @ref qpc_7_1_3 -* -* @file -* @brief "safe" and facilities -*/ +//============================================================================ +// QP/C Real-Time Embedded Framework (RTEF) +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +//============================================================================ +//! @date Last updated on: 2022-07-30 +//! @version Last updated for: @ref qpc_7_1_3 +//! +//! @file +//! @brief "safe" and facilities #ifndef SAFE_STD_H #define SAFE_STD_H #include #include -/* portable "safe" facilities from and ................*/ -#ifdef _WIN32 /* Windows OS? */ +// portable "safe" facilities from and ................ +#ifdef _WIN32 // Windows OS? #define MEMMOVE_S(dest_, num_, src_, count_) \ memmove_s(dest_, num_, src_, count_) @@ -62,7 +60,7 @@ #else #define FREAD_S(buf_, bufsiz_, elsiz_, count_, fp_) \ fread(buf_, elsiz_, count_, fp_) -#endif /* _MSC_VER */ +#endif // _MSC_VER #define FOPEN_S(fp_, fName_, mode_) \ if (fopen_s(&fp_, fName_, mode_) != 0) { \ @@ -72,7 +70,7 @@ if (fopen_s(&fp_, fName_, mode_) != 0) { \ #define LOCALTIME_S(tm_, time_) \ localtime_s(tm_, time_) -#else /* other OS (Linux, MacOS, etc.) .....................................*/ +#else // other OS (Linux, MacOS, etc.) ..................................... #define MEMMOVE_S(dest_, num_, src_, count_) \ memmove(dest_, src_, count_) @@ -103,6 +101,6 @@ if (fopen_s(&fp_, fName_, mode_) != 0) { \ #define LOCALTIME_S(tm_, time_) \ memcpy(tm_, localtime(time_), sizeof(struct tm)) -#endif /* _WIN32 */ +#endif // _WIN32 -#endif /* SAFE_STD_H */ +#endif // SAFE_STD_H diff --git a/ports/win32/Makefile b/ports/win32/Makefile new file mode 100644 index 00000000..ecf06057 --- /dev/null +++ b/ports/win32/Makefile @@ -0,0 +1,226 @@ +############################################################################## +# QP/C Real-Time Embedded Framework (RTEF) +# +# Q u a n t u m L e a P s +# ------------------------ +# Modern Embedded Software +# +# Copyright (C) 2005 Quantum Leaps, LLC, . +# +# SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +# +# This software is dual-licensed under the terms of the open source GNU +# General Public License version 3 (or any later version), or alternatively, +# under the terms of one of the closed source Quantum Leaps commercial +# licenses. +# +# The terms of the open source GNU General Public License version 3 +# can be found at: +# +# The terms of the closed source Quantum Leaps commercial licenses +# can be found at: +# +# Redistributions in source code must retain this top-level comment block. +# Plagiarizing this software to sidestep the license obligations is illegal. +# +# Contact information: +# +# +############################################################################## +# examples of invoking this Makefile: +# building configurations: Debug (default), Release and Spy +# make +# make CONF=rel +# make CONF=spy +# +# cleaning configurations: Debug (default), Release, and Spy +# make clean +# make CONF=rel clean +# make CONF=spy clean +# +# NOTE: +# To use this Makefile on Windows, you will need the GNU make utility, which +# is included in the QTools collection for Windows, see: +# https://github.com/QuantumLeaps/qtools +# + +#----------------------------------------------------------------------------- +# project name: +# +PROJECT := qp + +#----------------------------------------------------------------------------- +# project directories: +# + +# location of the QP/C framework +QPC := ../.. + +# QP port used in this project +QP_PORT_DIR := . + +# list of all source directories used by this project +VPATH = \ + $(QPC)/src/qf \ + $(QPC)/src/qs \ + $(QP_PORT_DIR) + +# list of all include directories needed by this project +INCLUDES = \ + -I$(QPC)/include \ + -I$(QPC)/src \ + -I$(QP_PORT_DIR) + +#----------------------------------------------------------------------------- +# files +# + +# C source files +C_SRCS := \ + qep_hsm.c \ + qep_msm.c \ + qf_act.c \ + qf_actq.c \ + qf_defer.c \ + qf_dyn.c \ + qf_mem.c \ + qf_ps.c \ + qf_qact.c \ + qf_qeq.c \ + qf_qmact.c \ + qf_time.c \ + qwin_gui.c \ + qf_port.c + +C_QS_SRCS := \ + qs.c \ + qs_rx.c \ + qs_fp.c \ + qs_64bit.c \ + qs_port.c + +# C++ source files +CPP_SRCS := + +# defines: +DEFINES := -DQWIN_GUI -DQP_API_VERSION=9999 + +#----------------------------------------------------------------------------- +# MinGW toolset (NOTE: assumed to be on your PATH) +# +# NOTE: +# MinGW toolset is included in the Qtools collection for Windows, see: +# https://github.com/QuantumLeaps/qtools + +CC := gcc +CPP := g++ +LIB := ar + + +############################################################################## +# Typically, you should not need to change anything below this line + +# basic utilities (included in Qtools for Windows), see: +# https://github.com/QuantumLeaps/qtools + +MKDIR := mkdir +RM := rm + +#----------------------------------------------------------------------------- +# build options for various configurations +# + +LIBFLAGS := rs + +ifeq (rel, $(CONF)) # Release configuration ................................. + +BIN_DIR := rel + +# gcc options: +CFLAGS := -c -O3 -fno-pie -std=c11 -pedantic -Wall -Wextra -W \ + $(INCLUDES) $(DEFINES) -DNDEBUG + +CPPFLAGS := -c -O3 -fno-pie -std=c++11 -pedantic -Wall -Wextra \ + -fno-rtti -fno-exceptions \ + $(INCLUDES) $(DEFINES) -DNDEBUG + +else ifeq (spy, $(CONF)) # Spy configuration ................................ + +BIN_DIR := spy + +# add the QS sources... +C_SRCS += $(C_QS_SRCS) + +# gcc options: +CFLAGS := -c -g -O -fno-pie -std=c11 -pedantic -Wall -Wextra -W \ + $(INCLUDES) $(DEFINES) -DQ_SPY + +CPPFLAGS := -c -g -O -fno-pie -std=c++11 -pedantic -Wall -Wextra \ + -fno-rtti -fno-exceptions \ + $(INCLUDES) $(DEFINES) -DQ_SPY + +else # default Debug configuration ......................................... + +BIN_DIR := dbg + +# gcc options: +CFLAGS := -c -g -O -fno-pie -std=c11 -pedantic -Wall -Wextra -W \ + $(INCLUDES) $(DEFINES) + +CPPFLAGS := -c -g -O -fno-pie -std=c++11 -pedantic -Wall -Wextra \ + -fno-rtti -fno-exceptions \ + $(INCLUDES) $(DEFINES) + +endif + +#----------------------------------------------------------------------------- +C_OBJS := $(patsubst %.c,%.o, $(notdir $(C_SRCS))) +CPP_OBJS := $(patsubst %.cpp,%.o,$(notdir $(CPP_SRCS))) + +TARGET_LIB := $(BIN_DIR)/lib$(PROJECT).a +C_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(C_OBJS)) +C_DEPS_EXT := $(patsubst %.o,%.d, $(C_OBJS_EXT)) +CPP_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(CPP_OBJS)) +CPP_DEPS_EXT := $(patsubst %.o,%.d, $(CPP_OBJS_EXT)) + +# create $(BIN_DIR) if it does not exist +ifeq ("$(wildcard $(BIN_DIR))","") +$(shell $(MKDIR) $(BIN_DIR)) +endif + +#----------------------------------------------------------------------------- +# rules +# + +all: $(TARGET_LIB) + -$(RM) $(BIN_DIR)/*.o + +$(TARGET_LIB) : $(ASM_OBJS_EXT) $(C_OBJS_EXT) $(CPP_OBJS_EXT) + $(LIB) $(LIBFLAGS) $@ $^ + +$(BIN_DIR)/%.o : %.c + $(CC) $(CFLAGS) $< -o $@ + +$(BIN_DIR)/%.o : %.cpp + $(CPP) $(CPPFLAGS) $< -o $@ + +#----------------------------------------------------------------------------- +# the clean target +# +.PHONY : clean +clean: + -$(RM) $(BIN_DIR)/*.o $(TARGET_LIB) + +#----------------------------------------------------------------------------- +# the show target for debugging +# +show: + @echo PROJECT = $(PROJECT) + @echo CONF = $(CONF) + @echo TARGET_LIB = $(TARGET_LIB) + @echo C_SRCS = $(C_SRCS) + @echo CPP_SRCS = $(CPP_SRCS) + @echo C_OBJS_EXT = $(C_OBJS_EXT) + @echo C_DEPS_EXT = $(C_DEPS_EXT) + @echo CPP_OBJS_EXT = $(CPP_OBJS_EXT) + @echo CPP_DEPS_EXT = $(CPP_DEPS_EXT) diff --git a/ports/win32/qep_port.h b/ports/win32/qep_port.h deleted file mode 100644 index 6a2e7e67..00000000 --- a/ports/win32/qep_port.h +++ /dev/null @@ -1,72 +0,0 @@ -/*============================================================================ -* QP/C Real-Time Embedded Framework (RTEF) -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2022-07-30 -* @version Last updated for: @ref qpc_7_0_1 -* -* @file -* @brief QEP/C port to Win32 with GNU or Visual Studio C/C++ compilers -*/ -#ifndef QEP_PORT_H -#define QEP_PORT_H - -#include /* Exact-width types. WG14/N843 C99 Standard */ -#include /* Boolean type. WG14/N843 C99 Standard */ - -#ifdef __GNUC__ - - /*! no-return function specifier (GCC-ARM compiler) */ - #define Q_NORETURN __attribute__ ((noreturn)) void - -#elif (defined _MSC_VER) && (defined __cplusplus) - - /* no-return function specifier (Microsoft Visual Studio C++ compiler) */ - #define Q_NORETURN [[ noreturn ]] void - - /* - * This is the case where QP/C is compiled by the Microsoft Visual C++ - * compiler in the C++ mode, which can happen when qep_port.h is included - * in a C++ module, or the compilation is forced to C++ by the option /TP. - * - * The following pragma suppresses the level-4 C++ warnings C4510, C4512, - * and C4610, which warn that default constructors and assignment operators - * could not be generated for structures QMState and QMTranActTable. - * - * The QP/C source code cannot be changed to avoid these C++ warnings - * because the structures QMState and QMTranActTable must remain PODs - * (Plain Old Datatypes) to be initializable statically with constant - * initializers. - */ - #pragma warning (disable: 4510 4512 4610) - -#endif - -#include "qep.h" /* QEP platform-independent public interface */ - -#if (defined __cplusplus) && (defined _MSC_VER) - #pragma warning (default: 4510 4512 4610) -#endif - -#endif /* QEP_PORT_H */ diff --git a/ports/win32/qf_port.c b/ports/win32/qf_port.c index d80a41af..37823c6c 100644 --- a/ports/win32/qf_port.c +++ b/ports/win32/qf_port.c @@ -1,102 +1,101 @@ -/*============================================================================ -* QP/C Real-Time Embedded Framework (RTEF) -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2023-01-07 -* @version Last updated for: @ref qpc_7_2_0 -* -* @file -* @brief QF/C port to Win32 API -*/ -#define QP_IMPL /* this is QP implementation */ -#include "qf_port.h" /* QF port */ -#include "qf_pkg.h" /* QF package-scope interface */ -#include "qassert.h" /* QP embedded systems-friendly assertions */ -#ifdef Q_SPY /* QS software tracing enabled? */ - #include "qs_port.h" /* QS port */ - #include "qs_pkg.h" /* QS package-scope internal interface */ -#else - #include "qs_dummy.h" /* disable the QS software tracing */ -#endif /* Q_SPY */ +//============================================================================ +// QP/C Real-Time Embedded Framework (RTEF) +// Copyright (C) 2005 Quantum Leaps, LLC . +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +//============================================================================ +//! @date Last updated on: 2023-08-21 +//! @version Last updated for: @ref qpc_7_3_0 +//! +//! @file +//! @brief QF/C port to Win32 (multithreaded) -#include /* limits of dynamic range for integers */ -#include /* console input/output */ +#define QP_IMPL // this is QP implementation +#include "qp_port.h" // QP port +#include "qp_pkg.h" // QP package-scope interface +#include "qsafe.h" // QP Functional Safety (FuSa) Subsystem +#ifdef Q_SPY // QS software tracing enabled? + #include "qs_port.h" // QS port + #include "qs_pkg.h" // QS package-scope internal interface +#else + #include "qs_dummy.h" // disable the QS software tracing +#endif // Q_SPY + +#include // limits of dynamic range for integers +#include // console input/output Q_DEFINE_THIS_MODULE("qf_port") -/* Local objects ===========================================================*/ +// Local objects ============================================================= static CRITICAL_SECTION l_win32CritSect; static CRITICAL_SECTION l_startupCritSect; -static DWORD l_tickMsec = 10U; /* clock tick in msec (argument for Sleep()) */ -static int_t l_tickPrio = 50; /* default priority of the "ticker" thread */ -static bool l_isRunning; /* flag indicating when QF is running */ +static DWORD l_tickMsec = 10U; // clock tick in msec (argument for Sleep()) +static int l_tickPrio = 50; // default priority of the "ticker" thread +static bool l_isRunning; // flag indicating when QF is running static DWORD WINAPI ao_thread(LPVOID arg); -/* QF functions ============================================================*/ +//============================================================================ +// QF functions + +//............................................................................ void QF_init(void) { InitializeCriticalSection(&l_win32CritSect); - /* initialize and enter the startup critical section object to block - * any active objects started before calling QF_run() - */ + // initialize and enter the startup critical section object to block + // any active objects started before calling QF_run() InitializeCriticalSection(&l_startupCritSect); EnterCriticalSection(&l_startupCritSect); } -/****************************************************************************/ + +//............................................................................ void QF_enterCriticalSection_(void) { - EnterCriticalSection(&l_win32CritSect); + if (l_isRunning) { + EnterCriticalSection(&l_win32CritSect); + } } -/****************************************************************************/ +//............................................................................ void QF_leaveCriticalSection_(void) { - LeaveCriticalSection(&l_win32CritSect); + if (l_isRunning) { + LeaveCriticalSection(&l_win32CritSect); + } } -/****************************************************************************/ -void QF_stop(void) { - l_isRunning = false; /* terminate the main (ticker) thread */ -} -/****************************************************************************/ -int_t QF_run(void) { - int threadPrio = THREAD_PRIORITY_NORMAL; +//............................................................................ +int QF_run(void) { + QF_onStartup(); // application-specific startup callback - QF_onStartup(); /* application-specific startup callback */ + // produce the QS_QF_RUN trace record + QS_BEGIN_PRE_(QS_QF_RUN, 0U) + QS_END_PRE_() - /* produce the QS_QF_RUN trace record */ - QS_BEGIN_NOCRIT_PRE_(QS_QF_RUN, 0U) - QS_END_NOCRIT_PRE_() - - /* leave the startup critical section to unblock any active objects - * started before calling QF_run() - */ + // leave the startup critical section to unblock any active objects + // started before calling QF_run() LeaveCriticalSection(&l_startupCritSect); - l_isRunning = true; /* QF is running */ + l_isRunning = true; // QF is running - /* set the ticker (this thread) priority according to selection made in - * QF_setTickRate() - */ + // set the ticker (this thread) priority according to selection made in + // QF_setTickRate() + int threadPrio = THREAD_PRIORITY_NORMAL; if (l_tickPrio < 33) { threadPrio = THREAD_PRIORITY_BELOW_NORMAL; } @@ -106,56 +105,74 @@ int_t QF_run(void) { SetThreadPriority(GetCurrentThread(), threadPrio); while (l_isRunning) { - Sleep(l_tickMsec); /* wait for the tick interval */ - QF_onClockTick(); /* must call QTIMEEVT_TICK_X() */ + Sleep(l_tickMsec); // wait for the tick interval + QF_onClockTick(); // must call QTIMEEVT_TICK_X() } - QF_onCleanup(); /* cleanup callback */ - QS_EXIT(); /* cleanup the QSPY connection */ - /*DeleteCriticalSection(&l_startupCritSect);*/ - /*DeleteCriticalSection(&l_win32CritSect);*/ - return 0; /* return success */ + QF_onCleanup(); // cleanup callback + QS_EXIT(); // cleanup the QSPY connection + + //DeleteCriticalSection(&l_startupCritSect); + //DeleteCriticalSection(&l_win32CritSect); + return 0; // return success } -/****************************************************************************/ -void QF_setTickRate(uint32_t ticksPerSec, int_t tickPrio) { +//............................................................................ +void QF_stop(void) { + l_isRunning = false; // terminate the main (ticker) thread +} +//............................................................................ +void QF_setTickRate(uint32_t ticksPerSec, int tickPrio) { Q_REQUIRE_ID(600, ticksPerSec != 0U); l_tickMsec = 1000UL / ticksPerSec; l_tickPrio = tickPrio; } -/****************************************************************************/ -void QF_setWin32Prio(QActive *act, int_t win32Prio) { - HANDLE win32thread = (HANDLE)act->thread; - /* thread must be already created, see QActive_start_() */ - Q_REQUIRE_ID(700, win32thread != (HANDLE)0); - SetThreadPriority(win32thread, win32Prio); +//............................................................................ +void QF_consoleSetup(void) { +} +//............................................................................ +void QF_consoleCleanup(void) { +} +//............................................................................ +int QF_consoleGetKey(void) { + if (_kbhit()) { // any key pressed? + return (int)_getwch(); + } + return 0; // no input at this time +} +//............................................................................ +int QF_consoleWaitForKey(void) { + return (int)_getwch(); } -/* QActive functions =======================================================*/ +// QActive functions ========================================================= + void QActive_start_(QActive * const me, QPrioSpec const prioSpec, QEvt const * * const qSto, uint_fast16_t const qLen, void * const stkSto, uint_fast16_t const stkSize, void const * const par) { - /* no external AO-stack storage needed for this port */ + Q_UNUSED_PAR(stkSto); + Q_UNUSED_PAR(stkSize); + + // no external AO-stack storage needed for this port Q_REQUIRE_ID(800, stkSto == (void *)0); - me->prio = (uint8_t)(prioSpec & 0xFFU); /* QF-priority of the AO */ - me->pthre = (uint8_t)(prioSpec >> 8U); /* preemption-threshold */ - QActive_register_(me); /* register this AO */ + me->prio = (uint8_t)(prioSpec & 0xFFU); // QF-priority + me->pthre = 0U; // preemption-threshold (not used in QF, but in Win32) + QActive_register_(me); // register this AO + + // create the Win32 "event" to throttle the AO's event queue + me->osObject = CreateEvent(NULL, FALSE, FALSE, NULL); QEQueue_init(&me->eQueue, qSto, qLen); - /* create the Win32 "event" to throttle the AO's event queue */ - me->osObject = CreateEvent(NULL, FALSE, FALSE, NULL); + // the top-most initial tran. (virtual) + QASM_INIT(&me->super, par, me->prio); + QS_FLUSH(); // flush the QS trace buffer to the host - /* the top-most initial tran. (virtual) */ - QHSM_INIT(&me->super, par, me->prio); - QS_FLUSH(); /* flush the trace buffer to the host */ - - /* create a Win32 thread for the AO; - * The thread is created with THREAD_PRIORITY_NORMAL - */ + // create a Win32 thread for the AO; + // The thread is created with THREAD_PRIORITY_NORMAL me->thread = CreateThread( NULL, (stkSize < 1024U ? 1024U : stkSize), @@ -163,63 +180,64 @@ void QActive_start_(QActive * const me, QPrioSpec const prioSpec, me, 0, NULL); - Q_ENSURE_ID(830, me->thread != (HANDLE)0); /* must succeed */ + Q_ENSURE_ID(830, me->thread != (HANDLE)0); // must succeed + + // set the priority of the Win32 thread based on the + // "prio-threshold" field provided in the `prioSpec` parameter + int win32Prio; + switch ((prioSpec >> 8U) & 0xFFU) { + case 1U: + win32Prio = THREAD_PRIORITY_LOWEST; + break; + case 2U: + win32Prio = THREAD_PRIORITY_NORMAL; + break; + case 3U: + win32Prio = THREAD_PRIORITY_TIME_CRITICAL; + break; + default: + win32Prio = THREAD_PRIORITY_NORMAL; + break; + } + SetThreadPriority(me->thread, win32Prio); } -/*..........................................................................*/ -#ifdef QF_ACTIVE_STOP +//............................................................................ +#ifdef QACTIVE_CAN_STOP void QActive_stop(QActive * const me) { - QActive_unsubscribeAll(me); /* unsubscribe this AO from all events */ - me->thread = (void *)0; /* stop the thread loop (see ao_thread()) */ + QActive_unsubscribeAll(me); // unsubscribe this AO from all events + me->thread = (void *)0; // stop the thread loop (see ao_thread()) } #endif -/*..........................................................................*/ +//............................................................................ void QActive_setAttr(QActive *const me, uint32_t attr1, void const *attr2) { - (void)me; /* unused parameter */ - (void)attr1; /* unused parameter */ - (void)attr2; /* unused parameter */ - Q_ERROR_ID(900); /* this function should not be called in this QP port */ + Q_UNUSED_PAR(me); + Q_UNUSED_PAR(attr1); + Q_UNUSED_PAR(attr2); + Q_ERROR_INCRIT(900); // should not be called in this QP port } -/****************************************************************************/ -void QF_consoleSetup(void) { -} -/*..........................................................................*/ -void QF_consoleCleanup(void) { -} -/*..........................................................................*/ -int QF_consoleGetKey(void) { - if (_kbhit()) { /* any key pressed? */ - return (int)_getwch(); - } - return 0; -} -/*..........................................................................*/ -int QF_consoleWaitForKey(void) { - return (int)_getwch(); -} - -/****************************************************************************/ -static DWORD WINAPI ao_thread(LPVOID arg) { /* for CreateThread() */ +//============================================================================ +static DWORD WINAPI ao_thread(LPVOID arg) { // for CreateThread() QActive *act = (QActive *)arg; - /* block this thread until the startup critical section is exited - * from QF_run() */ + // block this thread until the startup critical section is exited + // from QF_run() EnterCriticalSection(&l_startupCritSect); LeaveCriticalSection(&l_startupCritSect); -#ifdef QF_ACTIVE_STOP +#ifdef QACTIVE_CAN_STOP while (act->thread) #else - for (;;) /* for-ever */ + for (;;) // for-ever #endif { - QEvt const *e = QActive_get_(act); /* wait for event */ - QHSM_DISPATCH(&act->super, e, act->prio); /* dispatch to the SM */ - QF_gc(e); /* check if the event is garbage, and collect it if so */ + QEvt const *e = QActive_get_(act); // wait for event + QASM_DISPATCH(&act->super, e, act->prio); // dispatch to the SM + QF_gc(e); // check if the event is garbage, and collect it if so } -#ifdef QF_ACTIVE_STOP - QActive_unregister_(act); /* un-register this active object */ +#ifdef QACTIVE_CAN_STOP + QActive_unregister_(act); // un-register this active object #endif - return (DWORD)0; /* return success */ + return (DWORD)0; // return success } diff --git a/ports/win32/qf_port.h b/ports/win32/qf_port.h deleted file mode 100644 index 86978bd8..00000000 --- a/ports/win32/qf_port.h +++ /dev/null @@ -1,183 +0,0 @@ -/*============================================================================ -* QP/C Real-Time Embedded Framework (RTEF) -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2023-01-07 -* @version Last updated for: @ref qpc_7_2_0 -* -* @file -* @brief QF/C port to Win32 API (multi-threaded) -*/ -#ifndef QF_PORT_H -#define QF_PORT_H - -/* Win32 event queue and thread types */ -#define QF_EQUEUE_TYPE QEQueue -#define QF_OS_OBJECT_TYPE void* -#define QF_THREAD_TYPE void* - -/* The maximum number of active objects in the application */ -#define QF_MAX_ACTIVE 64U - -/* The number of system clock tick rates */ -#define QF_MAX_TICK_RATE 2U - -/* Activate the QF QActive_stop() API */ -#define QF_ACTIVE_STOP 1 - -/* various QF object sizes configuration for this port */ -#define QF_EVENT_SIZ_SIZE 4U -#define QF_EQUEUE_CTR_SIZE 4U -#define QF_MPOOL_SIZ_SIZE 4U -#define QF_MPOOL_CTR_SIZE 4U -#define QF_TIMEEVT_CTR_SIZE 4U - -/* Win32 critical section, see NOTE1 */ -/* QF_CRIT_STAT_TYPE not defined */ -#define QF_CRIT_ENTRY(dummy) QF_enterCriticalSection_() -#define QF_CRIT_EXIT(dummy) QF_leaveCriticalSection_() - -/* QF_LOG2 not defined -- use the internal LOG2() implementation */ - -#include "qep_port.h" /* QEP port */ -#include "qequeue.h" /* Win32 needs the native event-queue */ -#include "qmpool.h" /* Win32 needs the native memory-pool */ -#include "qf.h" /* QF platform-independent public interface */ - -/* internal functions for critical section management */ -void QF_enterCriticalSection_(void); -void QF_leaveCriticalSection_(void); - -/* set Win32 thread priority for an active object; -* see: Microsoft documentation for SetThreadPriority() -* NOTE: must be called *after* QACTIVE_START() -*/ -void QF_setWin32Prio(QActive *act, int_t win32Prio); - -/* set clock tick rate */ -void QF_setTickRate(uint32_t ticksPerSec, int_t tickPrio); - -/* application-level clock tick callback */ -void QF_onClockTick(void); - -/* special adaptations for QWIN GUI applications... */ -#ifdef QWIN_GUI - /* replace main() with main_gui() as the entry point to a GUI app. */ - #define main() main_gui() - int_t main_gui(void); /* prototype of the GUI application entry point */ -#endif - -/* abstractions for console access... */ -void QF_consoleSetup(void); -void QF_consoleCleanup(void); -int QF_consoleGetKey(void); -int QF_consoleWaitForKey(void); - -/****************************************************************************/ -/* interface used only inside QF implementation, but not in applications */ -#ifdef QP_IMPL - - /* Win32-specific scheduler locking, see NOTE2 */ - #define QF_SCHED_STAT_ - #define QF_SCHED_LOCK_(dummy) QF_enterCriticalSection_() - #define QF_SCHED_UNLOCK_() QF_leaveCriticalSection_() - - /* Win32 active object event queue customization... */ - #define QACTIVE_EQUEUE_WAIT_(me_) \ - while ((me_)->eQueue.frontEvt == (QEvt *)0) { \ - QF_CRIT_X_(); \ - (void)WaitForSingleObject((me_)->osObject, (DWORD)INFINITE); \ - QF_CRIT_E_(); \ - } - #define QACTIVE_EQUEUE_SIGNAL_(me_) \ - Q_ASSERT_ID(410, QActive_registry_[(me_)->prio] != (QActive *)0); \ - (void)SetEvent((me_)->osObject) - - /* native QF event pool operations */ - #define QF_EPOOL_TYPE_ QMPool - #define QF_EPOOL_INIT_(p_, poolSto_, poolSize_, evtSize_) \ - (QMPool_init(&(p_), (poolSto_), (poolSize_), (evtSize_))) - #define QF_EPOOL_EVENT_SIZE_(p_) ((uint_fast16_t)(p_).blockSize) - #define QF_EPOOL_GET_(p_, e_, m_, qs_id_) \ - ((e_) = (QEvt *)QMPool_get(&(p_), (m_), (qs_id_))) - #define QF_EPOOL_PUT_(p_, e_, qs_id_) \ - (QMPool_put(&(p_), (e_), (qs_id_))) - - /* Minimum required Windows version is Windows-XP or newer (0x0501) */ - #ifdef WINVER - #undef WINVER - #endif - #ifdef _WIN32_WINNT - #undef _WIN32_WINNT - #endif - - #define WINVER _WIN32_WINNT_WINXP - #define _WIN32_WINNT _WIN32_WINNT_WINXP - - #define WIN32_LEAN_AND_MEAN - #include /* Win32 API */ - -#endif /* QP_IMPL */ - -/* NOTES: ==================================================================*/ -/* -* NOTE1: -* QF, like all real-time frameworks, needs to execute certain sections of -* code exclusively, meaning that only one thread can execute the code at -* the time. Such sections of code are called "critical sections" -* -* This port uses a pair of functions QF_enterCriticalSection_() / -* QF_leaveCriticalSection_() to enter/leave the cirtical section, -* respectively. -* -* These functions are implemented in the qf_port.c module, where they -* manipulate the file-scope Win32 critical section object l_win32CritSect -* to protect all critical sections. Using the single critical section -* object for all crtical section guarantees that only one thread at a time -* can execute inside a critical section. This prevents race conditions and -* data corruption. -* -* Please note, however, that the Win32 critical section implementation -* behaves differently than interrupt disabling. A common Win32 critical -* section ensures that only one thread at a time can execute a critical -* section, but it does not guarantee that a context switch cannot occur -* within the critical section. In fact, such context switches probably -* will happen, but they should not cause concurrency hazards because the -* critical section eliminates all race conditionis. -* -* Unlinke simply disabling and enabling interrupts, the critical section -* approach is also subject to priority inversions. Various versions of -* Windows handle priority inversions differently, but it seems that most of -* them recognize priority inversions and dynamically adjust the priorities of -* threads to prevent it. Please refer to the MSN articles for more -* information. -* -* NOTE2: -* Scheduler locking (used inside QF_publish_()) is implemented in this -* port with the main critical section. This means that event multicasting -* will appear atomic, in the sense that no thread will be able to post -* events during multicasting. -*/ - -#endif /* QF_PORT_H */ diff --git a/ports/win32/qp_port.h b/ports/win32/qp_port.h new file mode 100644 index 00000000..1c41b247 --- /dev/null +++ b/ports/win32/qp_port.h @@ -0,0 +1,208 @@ +//============================================================================ +// QP/C Real-Time Embedded Framework (RTEF) +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC . +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +//============================================================================ +//! @date Last updated on: 2023-09-07 +//! @version Last updated for: @ref qpc_7_3_0 +//! +//! @file +//! @brief QP/C port to Win32 (multithreaded) with GNU or Visual C/C++ + +#ifndef QP_PORT_H_ +#define QP_PORT_H_ + +#include // Exact-width types. WG14/N843 C99 Standard +#include // Boolean type. WG14/N843 C99 Standard + +#ifdef QP_CONFIG +#include "qp_config.h" // external QP configuration +#endif + +#ifdef __GNUC__ + + // no-return function specifier (GCC-ARM compiler) + #define Q_NORETURN __attribute__ ((noreturn)) void + +#elif (defined _MSC_VER) + #ifdef __cplusplus + // no-return function specifier (Microsoft Visual Studio C++ compiler) + #define Q_NORETURN [[ noreturn ]] void + #else + // no-return function specifier C11 + #define Q_NORETURN _Noreturn void + #endif + + // This is the case where QP/C is compiled by the Microsoft Visual C++ + // compiler in the C++ mode, which can happen when qep_port.h is included + // in a C++ module, or the compilation is forced to C++ by the option /TP. + // + // The following pragma suppresses the level-4 C++ warnings C4510, C4512, + // and C4610, which warn that default constructors and assignment operators + // could not be generated for structures QMState and QMTranActTable. + // + // The QP/C source code cannot be changed to avoid these C++ warnings + // because the structures QMState and QMTranActTable must remain PODs + // (Plain Old Datatypes) to be initializable statically with constant + // initializers. + // + #pragma warning (disable: 4510 4512 4610) + +#endif + +// QF event queue and thread types for Win32 +#define QACTIVE_EQUEUE_TYPE QEQueue +#define QACTIVE_OS_OBJ_TYPE void* +#define QACTIVE_THREAD_TYPE void* + +// QF critical section for Win32, see NOTE1 +#define QF_CRIT_STAT +#define QF_CRIT_ENTRY() QF_enterCriticalSection_() +#define QF_CRIT_EXIT() QF_leaveCriticalSection_() + +// QF_LOG2 not defined -- use the internal LOG2() implementation + +// internal functions for critical section management +void QF_enterCriticalSection_(void); +void QF_leaveCriticalSection_(void); + +// set clock tick rate and priority +void QF_setTickRate(uint32_t ticksPerSec, int tickPrio); + +// clock tick callback +void QF_onClockTick(void); + +// abstractions for console access... +void QF_consoleSetup(void); +void QF_consoleCleanup(void); +int QF_consoleGetKey(void); +int QF_consoleWaitForKey(void); + +// special adaptations for QWIN GUI applications +#ifdef QWIN_GUI + // replace main() with main_gui() as the entry point to a GUI app. + #define main() main_gui() + int main_gui(void); // prototype of the GUI application entry point +#endif + +// include files ------------------------------------------------------------- +#include "qequeue.h" // Win32 port needs the native event-queue +#include "qmpool.h" // Win32 port needs the native memory-pool +#include "qp.h" // QP platform-independent public interface + +#ifdef _MSC_VER + #pragma warning (default: 4510 4512 4610) +#endif + +//============================================================================ +// interface used only inside QF implementation, but not in applications + +#ifdef QP_IMPL + + // QF scheduler locking for Win32, see NOTE2 + #define QF_SCHED_STAT_ + #define QF_SCHED_LOCK_(dummy) QF_enterCriticalSection_() + #define QF_SCHED_UNLOCK_() QF_leaveCriticalSection_() + + // QF event queue customization for Win32... + #define QACTIVE_EQUEUE_WAIT_(me_) \ + while ((me_)->eQueue.frontEvt == (QEvt *)0) { \ + QF_CRIT_EXIT(); \ + (void)WaitForSingleObject((me_)->osObject, (DWORD)INFINITE); \ + QF_CRIT_ENTRY(); \ + } + + #define QACTIVE_EQUEUE_SIGNAL_(me_) \ + (void)SetEvent((me_)->osObject) + + // native QF event pool operations + #define QF_EPOOL_TYPE_ QMPool + #define QF_EPOOL_INIT_(p_, poolSto_, poolSize_, evtSize_) \ + (QMPool_init(&(p_), (poolSto_), (poolSize_), (evtSize_))) + #define QF_EPOOL_EVENT_SIZE_(p_) ((uint_fast16_t)(p_).blockSize) + #define QF_EPOOL_GET_(p_, e_, m_, qs_id_) \ + ((e_) = (QEvt *)QMPool_get(&(p_), (m_), (qs_id_))) + #define QF_EPOOL_PUT_(p_, e_, qs_id_) \ + (QMPool_put(&(p_), (e_), (qs_id_))) + + // Minimum required Windows version is Windows-XP or newer (0x0501) + #ifdef WINVER + #undef WINVER + #endif + #ifdef _WIN32_WINNT + #undef _WIN32_WINNT + #endif + + #define WINVER _WIN32_WINNT_WINXP + #define _WIN32_WINNT _WIN32_WINNT_WINXP + + #define WIN32_LEAN_AND_MEAN + #include // Win32 API + +#endif // QP_IMPL + +//============================================================================ +// NOTE1: +// QP, like all real-time frameworks, needs to execute certain sections of +// code exclusively, meaning that only one thread can execute the code at +// the time. Such sections of code are called "critical sections". +// +// This port uses a pair of functions QF_enterCriticalSection_() / +// QF_leaveCriticalSection_() to enter/leave the critical section, +// respectively. +// +// These functions are implemented in the qf_port.c module, where they +// manipulate the file-scope Win32 critical section object l_win32CritSect +// to protect all critical sections. Using the single critical section +// object for all critical section guarantees that only one thread at a time +// can execute inside a critical section. This prevents race conditions and +// data corruption. +// +// Please note, however, that the Win32 critical section implementation +// behaves differently than interrupt disabling. A common Win32 critical +// section ensures that only one thread at a time can execute a critical +// section, but it does not guarantee that a context switch cannot occur +// within the critical section. In fact, such context switches probably +// will happen, but they should not cause concurrency hazards because the +// critical section eliminates all race conditions. +// +// Unlike simply disabling and enabling interrupts, the critical section +// approach is also subject to priority inversions. Various versions of +// Windows handle priority inversions differently, but it seems that most of +// them recognize priority inversions and dynamically adjust the priorities of +// threads to prevent it. Please refer to the MSN articles for more +// information. +// +// NOTE2: +// Scheduler locking (used inside QActive_publish_()) is implemented in this +// port with the main critical section. This means that event multicasting +// will appear atomic, in the sense that no thread will be able to post +// events during multicasting. +// + +#endif // QP_PORT_H_ + diff --git a/ports/win32/qs_port.c b/ports/win32/qs_port.c index fd9d651a..eedc7465 100644 --- a/ports/win32/qs_port.c +++ b/ports/win32/qs_port.c @@ -1,50 +1,49 @@ -/*============================================================================ -* QP/C Real-Time Embedded Framework (RTEF) -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2023-01-07 -* @version Last updated for: @ref qpc_7_2_0 -* -* @file -* @brief QS/C port for Win32 API -*/ +//============================================================================ +// QP/C Real-Time Embedded Framework (RTEF) +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +//============================================================================ +//! @date Last updated on: 2023-08-20 +//! @version Last updated for: @ref qpc_7_3_0 +//! +//! @file +//! @brief QS/C port for Win32 API + #ifndef Q_SPY #error "Q_SPY must be defined to compile qs_port.c" -#endif /* Q_SPY */ +#endif // Q_SPY -#define QP_IMPL /* this is QP implementation */ -#include "qf_port.h" /* QF port */ -#include "qassert.h" /* QP embedded systems-friendly assertions */ -#include "qs_port.h" /* QS port */ -#include "qs_pkg.h" /* QS package-scope interface */ +#define QP_IMPL // this is QP implementation +#include "qp_port.h" // QP port +#include "qsafe.h" // QP Functional Safety (FuSa) System +#include "qs_port.h" // QS port +#include "qs_pkg.h" // QS package-scope interface -#include "safe_std.h" /* portable "safe" / facilities */ +#include "safe_std.h" // portable "safe" / facilities #include #include #include -/* Minimum required Windows version is Windows-XP or newer (0x0501) */ +// Minimum required Windows version is Windows-XP or newer (0x0501) #ifdef WINVER #undef WINVER #endif @@ -57,22 +56,27 @@ #include -/*Q_DEFINE_THIS_MODULE("qs_port")*/ +//Q_DEFINE_THIS_MODULE("qs_port") #define QS_TX_SIZE (8*1024) #define QS_RX_SIZE (2*1024) #define QS_TX_CHUNK QS_TX_SIZE -#define QS_TIMEOUT_MS 10 +#define QS_TIMEOUT_MS 10U -/* local variables .........................................................*/ +// local variables ......................................................... static SOCKET l_sock = INVALID_SOCKET; -/*..........................................................................*/ +//............................................................................ uint8_t QS_onStartup(void const *arg) { - static uint8_t qsBuf[QS_TX_SIZE]; /* buffer for QS-TX channel */ - static uint8_t qsRxBuf[QS_RX_SIZE]; /* buffer for QS-RX channel */ + // initialize the QS transmit and receive buffers + static uint8_t qsBuf[QS_TX_SIZE]; // buffer for QS-TX channel + QS_initBuf(qsBuf, sizeof(qsBuf)); + + static uint8_t qsRxBuf[QS_RX_SIZE]; // buffer for QS-RX channel + QS_rxInitBuf(qsRxBuf, sizeof(qsRxBuf)); + char hostName[128]; - char const *serviceName = "6601"; /* default QSPY server port */ + char const *serviceName = "6601"; // default QSPY server port char const *src; char *dst; int status; @@ -84,21 +88,17 @@ uint8_t QS_onStartup(void const *arg) { ULONG ioctl_opt; WSADATA wsaData; - /* initialize the QS transmit and receive buffers */ - QS_initBuf(qsBuf, sizeof(qsBuf)); - QS_rxInitBuf(qsRxBuf, sizeof(qsRxBuf)); - - /* initialize Windows sockets version 2.2 */ + // initialize Windows sockets version 2.2 if (WSAStartup(MAKEWORD(2, 2), &wsaData) != NO_ERROR) { FPRINTF_S(stderr, " ERROR %s\n", "Windows Sockets cannot be initialized"); goto error; } - /* extract hostName from 'arg' (hostName:port_remote)... */ + // extract hostName from 'arg' (hostName:port_remote)... src = (arg != (void *)0) ? (char const *)arg - : "localhost"; /* default QSPY host */ + : "localhost"; // default QSPY host dst = hostName; while ((*src != '\0') && (*src != ':') @@ -106,9 +106,9 @@ uint8_t QS_onStartup(void const *arg) { { *dst++ = *src++; } - *dst = '\0'; /* zero-terminate hostName */ + *dst = '\0'; // zero-terminate hostName - /* extract serviceName from 'arg' (hostName:serviceName)... */ + // extract serviceName from 'arg' (hostName:serviceName)... if (*src == ':') { serviceName = src + 1; } @@ -140,7 +140,7 @@ uint8_t QS_onStartup(void const *arg) { freeaddrinfo(result); - /* socket could not be opened & connected? */ + // socket could not be opened & connected? if (l_sock == INVALID_SOCKET) { FPRINTF_S(stderr, " ERROR cannot connect to QSPY at " "host=%s:%s\n", @@ -148,7 +148,7 @@ uint8_t QS_onStartup(void const *arg) { goto error; } - /* set the socket to non-blocking mode */ + // set the socket to non-blocking mode ioctl_opt = 1; if (ioctlsocket(l_sock, FIONBIO, &ioctl_opt) != NO_ERROR) { FPRINTF_S(stderr, " ERROR %s WASErr=%d\n,", @@ -156,144 +156,144 @@ uint8_t QS_onStartup(void const *arg) { goto error; } - /* configure the socket to reuse the address and not to linger */ + // configure the socket to reuse the address and not to linger sockopt_bool = TRUE; setsockopt(l_sock, SOL_SOCKET, SO_REUSEADDR, (const char *)&sockopt_bool, sizeof(sockopt_bool)); sockopt_bool = TRUE; setsockopt(l_sock, SOL_SOCKET, SO_DONTLINGER, (const char *)&sockopt_bool, sizeof(sockopt_bool)); + //PRINTF_S(" Connected to QSPY at Host=%s:%d\n", + // hostName, port_remote); QS_onFlush(); - return 1U; /* success */ + return 1U; // success error: - return 0U; /* failure */ + return 0U; // failure } -/*..........................................................................*/ +//............................................................................ void QS_onCleanup(void) { + Sleep(QS_TIMEOUT_MS * 10U); // allow the last QS output to come out if (l_sock != INVALID_SOCKET) { closesocket(l_sock); l_sock = INVALID_SOCKET; } WSACleanup(); - /*PRINTF_S(" Disconnected from QSPY\n");*/ + //PRINTF_S(" Disconnected from QSPY\n"); } -/*..........................................................................*/ +//............................................................................ void QS_onReset(void) { QS_onCleanup(); + //PRINTF_S("\n%s\n", "QS_onReset"); exit(0); } -/*..........................................................................*/ +//............................................................................ void QS_onFlush(void) { - uint16_t nBytes; - uint8_t const *data; - QS_CRIT_STAT_ - - if (l_sock == INVALID_SOCKET) { /* socket NOT initialized? */ + if (l_sock == INVALID_SOCKET) { // socket NOT initialized? FPRINTF_S(stderr, " ERROR %s\n", "invalid TCP socket"); + QF_stop(); // <== stop and exit the application return; } - nBytes = QS_TX_CHUNK; - QS_CRIT_E_(); + QS_CRIT_STAT + QS_CRIT_ENTRY(); + uint16_t nBytes = QS_TX_CHUNK; + uint8_t const *data; while ((data = QS_getBlock(&nBytes)) != (uint8_t *)0) { - QS_CRIT_X_(); - for (;;) { /* for-ever until break or return */ + QS_CRIT_EXIT(); + for (;;) { // for-ever until break or return int nSent = send(l_sock, (char const *)data, (int)nBytes, 0); - if (nSent == SOCKET_ERROR) { /* sending failed? */ + if (nSent == SOCKET_ERROR) { // sending failed? int err = WSAGetLastError(); if (err == WSAEWOULDBLOCK) { - /* sleep for the timeout and then loop back - * to send() the SAME data again - */ + // sleep for the timeout and then loop back + // to send() the SAME data again Sleep(QS_TIMEOUT_MS); } - else { /* some other socket error... */ + else { // some other socket error... FPRINTF_S(stderr, " ERROR %s WASErr=%d\n", "sending data over TCP", err); + QF_stop(); // <== stop and exit the application return; } } - else if (nSent < (int)nBytes) { /* sent fewer than requested? */ - Sleep(QS_TIMEOUT_MS); /* sleep for the timeout */ - /* adjust the data and loop back to send() the rest */ + else if (nSent < (int)nBytes) { // sent fewer than requested? + Sleep(QS_TIMEOUT_MS); // sleep for the timeout + // adjust the data and loop back to send() the rest data += nSent; nBytes -= (uint16_t)nSent; } else { - break; /* break out of the for-ever loop */ + break; // break out of the for-ever loop } } - /* set nBytes for the next call to QS_getBlock() */ + // set nBytes for the next call to QS_getBlock() nBytes = QS_TX_CHUNK; - QS_CRIT_E_(); + QS_CRIT_ENTRY(); } - QS_CRIT_X_(); + QS_CRIT_EXIT(); } -/*..........................................................................*/ +//............................................................................ QSTimeCtr QS_onGetTime(void) { LARGE_INTEGER time; QueryPerformanceCounter(&time); return (QSTimeCtr)time.QuadPart; } -/*..........................................................................*/ +//............................................................................ void QS_output(void) { - uint16_t nBytes; - uint8_t const *data; - QS_CRIT_STAT_ - - if (l_sock == INVALID_SOCKET) { /* socket NOT initialized? */ + if (l_sock == INVALID_SOCKET) { // socket NOT initialized? FPRINTF_S(stderr, " ERROR %s\n", "invalid TCP socket"); + QF_stop(); // <== stop and exit the application return; } - nBytes = QS_TX_CHUNK; - QS_CRIT_E_(); - if ((data = QS_getBlock(&nBytes)) != (uint8_t *)0) { - QS_CRIT_X_(); - for (;;) { /* for-ever until break or return */ + QS_CRIT_STAT + QS_CRIT_ENTRY(); + uint16_t nBytes = QS_TX_CHUNK; + uint8_t const *data = QS_getBlock(&nBytes); + QS_CRIT_EXIT(); + + if (nBytes > 0U) { // any bytes to send? + for (;;) { // for-ever until break or return int nSent = send(l_sock, (char const *)data, (int)nBytes, 0); - if (nSent == SOCKET_ERROR) { /* sending failed? */ + if (nSent == SOCKET_ERROR) { // sending failed? int err = WSAGetLastError(); if (err == WSAEWOULDBLOCK) { - /* sleep for the timeout and then loop back - * to send() the SAME data again - */ + // sleep for the timeout and then loop back + // to send() the SAME data again Sleep(QS_TIMEOUT_MS); } - else { /* some other socket error... */ + else { // some other socket error... FPRINTF_S(stderr, " ERROR sending data over TCP," "WASErr=%d\n", err); + QF_stop(); // <== stop and exit the application return; } } - else if (nSent < (int)nBytes) { /* sent fewer than requested? */ - Sleep(QS_TIMEOUT_MS); /* sleep for the timeout */ - /* adjust the data and loop back to send() the rest */ + else if (nSent < (int)nBytes) { // sent fewer than requested? + Sleep(QS_TIMEOUT_MS); // sleep for the timeout + // adjust the data and loop back to send() the rest data += nSent; nBytes -= (uint16_t)nSent; } else { - break; + break; // break out of the for-ever loop } } } - else { - QS_CRIT_X_(); - } } -/*..........................................................................*/ +//............................................................................ void QS_rx_input(void) { int status = recv(l_sock, (char *)QS_rxPriv_.buf, (int)QS_rxPriv_.end, 0); - if (status > 0) { /* any data received? */ + if (status > 0) { // any data received? QS_rxPriv_.tail = 0U; - QS_rxPriv_.head = status; /* # bytes received */ - QS_rxParse(); /* parse all received bytes */ + QS_rxPriv_.head = status; // # bytes received + QS_rxParse(); // parse all received bytes } } diff --git a/ports/win32/qs_port.h b/ports/win32/qs_port.h index 103ecd1b..fed3284f 100644 --- a/ports/win32/qs_port.h +++ b/ports/win32/qs_port.h @@ -1,63 +1,61 @@ -/*============================================================================ -* QP/C Real-Time Embedded Framework (RTEF) -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2023-01-07 -* @version Last updated for: @ref qpc_7_2_0 -* -* @file -* @brief QS/C port to Win32 with GNU or Visual C++ compilers -*/ -#ifndef QS_PORT_H -#define QS_PORT_H +//============================================================================ +// QP/C Real-Time Embedded Framework (RTEF) +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +//============================================================================ +//! @date Last updated on: 2023-08-16 +//! @version Last updated for: @ref qpc_7_3_0 +//! +//! @file +//! @brief QS/C port to Win32 with GNU or Visual C++ compilers + +#ifndef QS_PORT_H_ +#define QS_PORT_H_ #define QS_CTR_SIZE 4U #define QS_TIME_SIZE 4U -#ifdef _WIN64 /* 64-bit architecture? */ +#ifdef _WIN64 // 64-bit architecture? #define QS_OBJ_PTR_SIZE 8U #define QS_FUN_PTR_SIZE 8U -#else /* 32-bit architecture */ +#else // 32-bit architecture #define QS_OBJ_PTR_SIZE 4U #define QS_FUN_PTR_SIZE 4U #endif -void QS_output(void); /* handle the QS output */ -void QS_rx_input(void); /* handle the QS-RX input */ +void QS_output(void); // handle the QS output +void QS_rx_input(void); // handle the QS-RX input -/*==========================================================================*/ -/* NOTE: QS might be used with or without other QP components, in which -* case the separate definitions of the macros QF_CRIT_STAT_TYPE, -* QF_CRIT_ENTRY, and QF_CRIT_EXIT are needed. In this port QS is configured -* to be used with the other QP component, by simply including "qf_port.h" -* *before* "qs.h". -*/ -#ifndef QF_PORT_H -#include "qf_port.h" /* use QS with QF */ +//============================================================================ +// NOTE: QS might be used with or without other QP components, in which +// case the separate definitions of the macros QF_CRIT_STAT, QF_CRIT_ENTRY(), +// and QF_CRIT_EXIT() are needed. In this port QS is configured to be used +// with the other QP component, by simply including "qp_port.h" +//*before* "qs.h". +#ifndef QP_PORT_H_ +#include "qp_port.h" // use QS with QP #endif -#include "qs.h" /* QS platform-independent public interface */ +#include "qs.h" // QS platform-independent public interface -#endif /* QS_PORT_H */ +#endif // QS_PORT_H_ diff --git a/ports/win32/qwin_gui.c b/ports/win32/qwin_gui.c index 92c06dac..5d09ed2d 100644 --- a/ports/win32/qwin_gui.c +++ b/ports/win32/qwin_gui.c @@ -1,41 +1,41 @@ -/*============================================================================ -* QP/C Real-Time Embedded Framework (RTEF) -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2022-07-30 -* @version Last updated for: @ref qpc_7_0_1 -* -* @file -* @brief QWIN GUI facilities for building realistic embedded front panels -*/ +//============================================================================ +// QP/C Real-Time Embedded Framework (RTEF) +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +//============================================================================ +//! +//! @date Last updated on: 2022-07-30 +//! @version Last updated for: @ref qpc_7_0_1 +//! +//! @file +//! @brief QWIN GUI facilities for building realistic embedded front panels +//! #include "qwin_gui.h" #include static HWND l_hWnd; static HDC l_hDC; -/*--------------------------------------------------------------------------*/ +//-------------------------------------------------------------------------- HWND CreateCustDialog(HINSTANCE hInst, int iDlg, HWND hParent, WNDPROC lpfnWndProc, LPCTSTR lpWndClass) { @@ -57,19 +57,19 @@ HWND CreateCustDialog(HINSTANCE hInst, int iDlg, HWND hParent, RegisterClassEx(&wndclass); l_hWnd = CreateDialog(hInst, MAKEINTRESOURCE(iDlg), hParent, NULL); - l_hDC = GetDC(l_hWnd); /* obtain the DC for the client area of the window */ + l_hDC = GetDC(l_hWnd); // obtain the DC for the client area of the window - /* NOTE: WM_INITDIALOG provides stimulus for initializing dialog controls. - * Dialog box procedures typically use this message to initialize controls - * and carry out any other initialization tasks that affect the appearance - * of the dialog box. - */ + // NOTE: WM_INITDIALOG provides stimulus for initializing dialog controls. + // Dialog box procedures typically use this message to initialize controls + // and carry out any other initialization tasks that affect the appearance + // of the dialog box. + // SendMessage(l_hWnd, WM_INITDIALOG, (WPARAM)0, (LPARAM)0); return l_hWnd; } -/*--------------------------------------------------------------------------*/ +//-------------------------------------------------------------------------- void OwnerDrawnButton_init(OwnerDrawnButton * const me, UINT itemID, HBITMAP hBitmapUp, HBITMAP hBitmapDwn, @@ -81,13 +81,13 @@ void OwnerDrawnButton_init(OwnerDrawnButton * const me, me->hCursor = hCursor; me->isDepressed = 0; } -/*..........................................................................*/ +//............................................................................ void OwnerDrawnButton_xtor(OwnerDrawnButton * const me) { DeleteObject(me->hBitmapUp); DeleteObject(me->hBitmapDown); DeleteObject(me->hCursor); } -/*..........................................................................*/ +//............................................................................ enum OwnerDrawnButtonAction OwnerDrawnButton_draw( OwnerDrawnButton * const me, LPDRAWITEMSTRUCT lpdis) @@ -98,7 +98,7 @@ enum OwnerDrawnButtonAction OwnerDrawnButton_draw( if (me->hCursor != NULL) { SetClassLongPtr(lpdis->hwndItem, GCLP_HCURSOR, (LONG_PTR)me->hCursor); - me->hCursor = NULL; /* mark the cursor set */ + me->hCursor = NULL; // mark the cursor set } DrawBitmap(lpdis->hDC, me->hBitmapUp, lpdis->rcItem.left, lpdis->rcItem.top); @@ -113,16 +113,16 @@ enum OwnerDrawnButtonAction OwnerDrawnButton_draw( ret = BTN_DEPRESSED; } else { - /* NOTE: the bitmap for button "UP" look will be - * drawn in the ODA_DRAWENTIRE action - */ + // NOTE: the bitmap for button "UP" look will be + // drawn in the ODA_DRAWENTIRE action + // me->isDepressed = 0; ret = BTN_RELEASED; } } return ret; } -/*..........................................................................*/ +//............................................................................ void OwnerDrawnButton_set(OwnerDrawnButton * const me, int isDepressed) { if (me->isDepressed != isDepressed) { HWND hItem = GetDlgItem(l_hWnd, me->itemID); @@ -135,12 +135,12 @@ void OwnerDrawnButton_set(OwnerDrawnButton * const me, int isDepressed) { } } } -/*..........................................................................*/ +//............................................................................ BOOL OwnerDrawnButton_isDepressed(OwnerDrawnButton const * const me) { return me->isDepressed; } -/*--------------------------------------------------------------------------*/ +//-------------------------------------------------------------------------- void GraphicDisplay_init(GraphicDisplay * const me, UINT width, UINT height, UINT itemID, BYTE const bgColor[3]) @@ -161,8 +161,8 @@ void GraphicDisplay_init(GraphicDisplay * const me, me->bgColor[1] = bgColor[1]; me->bgColor[2] = bgColor[2]; - bi24BitInfo.bmiHeader.biBitCount = 3U*8U; /* 3 RGB bytes */ - bi24BitInfo.bmiHeader.biCompression = BI_RGB; /* RGB color */ + bi24BitInfo.bmiHeader.biBitCount = 3U*8U; // 3 RGB bytes + bi24BitInfo.bmiHeader.biCompression = BI_RGB; // RGB color bi24BitInfo.bmiHeader.biPlanes = 1U; bi24BitInfo.bmiHeader.biSize = sizeof(bi24BitInfo.bmiHeader); bi24BitInfo.bmiHeader.biWidth = me->src_width; @@ -176,13 +176,13 @@ void GraphicDisplay_init(GraphicDisplay * const me, GraphicDisplay_clear(me); GraphicDisplay_redraw(me); } -/*..........................................................................*/ +//............................................................................ void GraphicDisplay_xtor(GraphicDisplay * const me) { DeleteDC(me->src_hDC); DeleteObject(me->hBitmap); OutputDebugString("GraphicDisplay_xtor\n"); } -/*..........................................................................*/ +//............................................................................ void GraphicDisplay_clear(GraphicDisplay * const me) { UINT n; BYTE r = me->bgColor[0]; @@ -196,13 +196,13 @@ void GraphicDisplay_clear(GraphicDisplay * const me) { bits[2] = r; } } -/*..........................................................................*/ +//............................................................................ void GraphicDisplay_redraw(GraphicDisplay * const me) { StretchBlt(me->dst_hDC, 0, 0, me->dst_width, me->dst_height, me->src_hDC, 0, 0, me->src_width, me->src_height, SRCCOPY); } -/* SegmentDisplay ----------------------------------------------------------*/ +// SegmentDisplay ---------------------------------------------------------- void SegmentDisplay_init(SegmentDisplay * const me, UINT segmentNum, UINT bitmapNum) { @@ -219,7 +219,7 @@ void SegmentDisplay_init(SegmentDisplay * const me, me->hBitmap[n] = NULL; } } -/*..........................................................................*/ +//............................................................................ void SegmentDisplay_xtor(SegmentDisplay * const me) { UINT n; @@ -233,7 +233,7 @@ void SegmentDisplay_xtor(SegmentDisplay * const me) { } free(me->hBitmap); } -/*..........................................................................*/ +//............................................................................ BOOL SegmentDisplay_initSegment(SegmentDisplay * const me, UINT segmentNum, UINT segmentID) { @@ -245,7 +245,7 @@ BOOL SegmentDisplay_initSegment(SegmentDisplay * const me, return FALSE; } } -/*..........................................................................*/ +//............................................................................ BOOL SegmentDisplay_initBitmap(SegmentDisplay * const me, UINT bitmapNum, HBITMAP hBitmap) { @@ -257,7 +257,7 @@ BOOL SegmentDisplay_initBitmap(SegmentDisplay * const me, return FALSE; } } -/*..........................................................................*/ +//............................................................................ BOOL SegmentDisplay_setSegment(SegmentDisplay * const me, UINT segmentNum, UINT bitmapNum) { @@ -272,10 +272,10 @@ BOOL SegmentDisplay_setSegment(SegmentDisplay * const me, } } -/*--------------------------------------------------------------------------*/ -/* DrawBitmap() function adapted from the book "Programming Windows" by -* Charles Petzold. -*/ +//-------------------------------------------------------------------------- +// DrawBitmap() function adapted from the book "Programming Windows" by +// Charles Petzold. +// void DrawBitmap(HDC hdc, HBITMAP hBitmap, int xStart, int yStart) { diff --git a/ports/win32/qwin_gui.h b/ports/win32/qwin_gui.h index 357a88f9..29b7f76d 100644 --- a/ports/win32/qwin_gui.h +++ b/ports/win32/qwin_gui.h @@ -1,34 +1,34 @@ -/*============================================================================ -* QP/C Real-Time Embedded Framework (RTEF) -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2022-07-30 -* @version Last updated for: @ref qpc_7_0_1 -* -* @file -* @brief QWIN GUI facilities for building realistic embedded front panels -*/ +//============================================================================ +// QP/C Real-Time Embedded Framework (RTEF) +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +//============================================================================ +//! +//! @date Last updated on: 2022-07-30 +//! @version Last updated for: @ref qpc_7_0_1 +//! +//! @file +//! @brief QWIN GUI facilities for building realistic embedded front panels +//! #ifndef QWIN_GUI_H #define QWIN_GUI_H @@ -37,17 +37,17 @@ #endif #define WIN32_LEAN_AND_MEAN -#include /* Win32 API */ +#include // Win32 API #ifdef __cplusplus extern "C" { #endif -/* create the custom dialog hosting the embedded front panel ...............*/ +// create the custom dialog hosting the embedded front panel ............... HWND CreateCustDialog(HINSTANCE hInst, int iDlg, HWND hParent, WNDPROC lpfnWndProc, LPCTSTR lpWndClass); -/* OwnerDrawnButton "class" ................................................*/ +// OwnerDrawnButton "class" ................................................ typedef struct { UINT itemID; HBITMAP hBitmapUp; @@ -75,9 +75,9 @@ void OwnerDrawnButton_set(OwnerDrawnButton * const me, int isDepressed); BOOL OwnerDrawnButton_isDepressed(OwnerDrawnButton const * const me); -/* GraphicDisplay "class" for drawing graphic displays -* with up to 24-bit color... -*/ +// GraphicDisplay "class" for drawing graphic displays +// with up to 24-bit color... +// typedef struct { HDC src_hDC; int src_width; @@ -113,12 +113,12 @@ void GraphicDisplay_redraw(GraphicDisplay * const me); pixelRGB[2] = (me_)->bgColor[2]; \ } while (false) -/* SegmentDisplay "class" for drawing segment displays, LEDs, etc...........*/ +// SegmentDisplay "class" for drawing segment displays, LEDs, etc........... typedef struct { - HWND *hSegment; /* array of segment controls */ - UINT segmentNum; /* number of segments */ - HBITMAP *hBitmap; /* array of bitmap handles */ - UINT bitmapNum; /* number of bitmaps */ + HWND *hSegment; // array of segment controls + UINT segmentNum; // number of segments + HBITMAP *hBitmap; // array of bitmap handles + UINT bitmapNum; // number of bitmaps } SegmentDisplay; void SegmentDisplay_init(SegmentDisplay * const me, @@ -131,11 +131,11 @@ BOOL SegmentDisplay_initBitmap(SegmentDisplay * const me, BOOL SegmentDisplay_setSegment(SegmentDisplay * const me, UINT segmentNum, UINT bitmapNum); -/* useful helper functions .................................................*/ +// useful helper functions ................................................. void DrawBitmap(HDC hdc, HBITMAP hBitmap, int xStart, int yStart); #ifdef __cplusplus } #endif -#endif /* QWIN_GUI_H */ +#endif // QWIN_GUI_H diff --git a/ports/win32/safe_std.h b/ports/win32/safe_std.h index b4a1f511..c752662c 100644 --- a/ports/win32/safe_std.h +++ b/ports/win32/safe_std.h @@ -1,42 +1,40 @@ -/*============================================================================ -* QP/C Real-Time Embedded Framework (RTEF) -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2022-07-30 -* @version Last updated for: @ref qpc_7_1_3 -* -* @file -* @brief "safe" and facilities -*/ +//============================================================================ +// QP/C Real-Time Embedded Framework (RTEF) +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +//============================================================================ +//! @date Last updated on: 2022-07-30 +//! @version Last updated for: @ref qpc_7_1_3 +//! +//! @file +//! @brief "safe" and facilities #ifndef SAFE_STD_H #define SAFE_STD_H #include #include -/* portable "safe" facilities from and ................*/ -#ifdef _WIN32 /* Windows OS? */ +// portable "safe" facilities from and ................ +#ifdef _WIN32 // Windows OS? #define MEMMOVE_S(dest_, num_, src_, count_) \ memmove_s(dest_, num_, src_, count_) @@ -62,7 +60,7 @@ #else #define FREAD_S(buf_, bufsiz_, elsiz_, count_, fp_) \ fread(buf_, elsiz_, count_, fp_) -#endif /* _MSC_VER */ +#endif // _MSC_VER #define FOPEN_S(fp_, fName_, mode_) \ if (fopen_s(&fp_, fName_, mode_) != 0) { \ @@ -72,7 +70,7 @@ if (fopen_s(&fp_, fName_, mode_) != 0) { \ #define LOCALTIME_S(tm_, time_) \ localtime_s(tm_, time_) -#else /* other OS (Linux, MacOS, etc.) .....................................*/ +#else // other OS (Linux, MacOS, etc.) ..................................... #define MEMMOVE_S(dest_, num_, src_, count_) \ memmove(dest_, src_, count_) @@ -103,6 +101,6 @@ if (fopen_s(&fp_, fName_, mode_) != 0) { \ #define LOCALTIME_S(tm_, time_) \ memcpy(tm_, localtime(time_), sizeof(struct tm)) -#endif /* _WIN32 */ +#endif // _WIN32 -#endif /* SAFE_STD_H */ +#endif // SAFE_STD_H diff --git a/qpc.qm b/qpc.qm index 82fbc831..41ebf080 100644 --- a/qpc.qm +++ b/qpc.qm @@ -1,7 +1,7 @@ - + QP/C Real-Time Embedded Framework (RTEF) -The model is used to generate the whole QP/C source code. +This model is used to generate the whole QP/C source code. Copyright (C) 2005 Quantum Leaps, LLC <state-machine.com>. @@ -26,399 +26,188 @@ Contact information: <info@state-machine.com> - - - - - /*! No-return function specifier for the Q_onAssert() callback function. -* -* The `Q_NORETURN` macro is supposed to be defined in the QP/C port -* (file `qep_port.h`). If such definition is NOT porvided, the default -* definition assumes only `void` type returned from Q_onAssert(). -* -* @tr{PQA01_4} -*/ - void - - + + + + + + + + + \ + static char const Q_this_module_[] = name_; + + + + + + + + \ + ((expr_) ? ((void)0) : Q_onError(&Q_this_module_[0], (id_))) + + + + + + \ + (Q_onError(&Q_this_module_[0], (id_))) + + + + + + + + do { \ + QF_CRIT_STAT \ + QF_CRIT_ENTRY(); \ + (expr_) ? ((void)0) : Q_onError(&Q_this_module_[0], (id_)); \ + QF_CRIT_EXIT(); \ +} while (false) + + + + + + do { \ + QF_CRIT_STAT \ + QF_CRIT_ENTRY(); \ + Q_onError(&Q_this_module_[0], (id_)); \ + QF_CRIT_EXIT(); \ +} while (false) + + + + + + + + + + + + + + + + ((void)0) + + + + + + ((void)0) + + + + + + + + ((void)0) + + + + + + ((void)0) + + + - /*! Define the file name (with `__FILE__`) for assertions in this file -* -* @details -* Macro to be placed at the top of each C/C++ module to define the -* single instance of the file name string to be used in reporting -* assertions in this module. -* -* @note -* The file name string literal is defined by means of the standard -* preprocessor macro `__FILE__`. However, please note that, depending -* on the compiler, the `__FILE__` macro might contain the whole path name -* to the file, which might be inconvenient to log assertions. -* -* @attention -* This macro should **not** be terminated by a semicolon. -* -* @sa Q_DEFINE_THIS_MODULE() -*/ Q_DEFINE_THIS_MODULE(__FILE__) - - - /*! Define the user-specified module name for assertions in this file. -* -* @details -* Macro to be placed at the top of each C/C++ module to define the -* single instance of the module name string to be used in reporting -* assertions in this module. This macro takes the user-supplied parameter -* `name_` instead of `__FILE__` to precisely control the name of the -* module. -* -* @param[in] name_ string constant representing the module name -* -* @note -* This macro should **not** be terminated by a semicolon. -*/ - - - \ - static char const Q_this_module_[] = name_; - - - - /*! inactive version of Q_DEFINE_THIS_MODULE() */ - - - - - - /*! General purpose assertion with user-specified ID number. -* -* @details -* Makes sure the `test_` parameter is TRUE. Calls the Q_onAssert() -* callback if the `test_` evaluates to FALSE. This assertion takes the -* user-supplied parameter `id_` to identify the location of this -* assertion within the file. This avoids the volatility of using line -* numbers, which change whenever a line of code is added or removed -* upstream from the assertion. -* -* @param[in] id_ ID number (unique within the module) of the assertion -* @param[in] expr_ Boolean expression to check -* -* @note -* The `test_` expression is **not** evaluated if assertions are -* disabled with the ::Q_NASSERT switch. -*/ - - - - - ((expr_) \ - ? ((void)0) : Q_onAssert(&Q_this_module_[0], (id_))) - - - - /*! inactive version of Q_ASSERT_ID() */ - - - - - ((void)0) - - - - /*! Assertion with user-specified ID for a wrong path through the code -* -* @details -* Calls the Q_onAssert() callback if ever executed. This assertion -* takes the user-supplied parameter `id_` to identify the location of -* this assertion within the file. This avoids the volatility of using -* line numbers, which change whenever a line of code is added or removed -* upstream from the assertion. -* -* @param[in] id_ ID number (unique within the module) of the assertion -* -* @note -* Does noting if assertions are disabled with the ::Q_NASSERT switch. -*/ - - - Q_onAssert(&Q_this_module_[0], (id_)) - - - - /*! inactive version of Q_ERROR_ID() */ - - - ((void)0) - - - - /*! General purpose assertion with user-specified ID number that -* **always** evaluates the `expr_` expression. -* -* @details -* Like the Q_ASSERT_ID() macro, except it **always** evaluates the -* `expr_` expression even when assertions are disabled with the -* ::Q_NASSERT macro. However, when the ::Q_NASSERT macro is defined, the -* Q_onAssert() callback is **not** called, even if `expr_` evaluates -* to FALSE. -* -* @param[in] id_ ID number (unique within the module) of the assertion -* @param[in] expr_ Boolean expression to check -*/ - - - - - Q_ASSERT_ID((id_), (expr_)) - - - - /*! inactive version of Q_ALLEGE_ID() -* -* @attention -* The expression `expr_` **is** executed. -*/ - - - - - ((void)(expr_)) - - - - /*! Assertion for checking preconditions. -* -* @details -* This macro is equivalent to Q_ASSERT_ID(), except the name provides a better -* documentation of the intention of this assertion. -* -* @param[in] id_ ID number (unique within the module) of the assertion -* @param[in] expr_ Boolean expression -*/ - - - - - Q_ASSERT_ID((id_), (expr_)) - - - - /*! Assertion for checking preconditions (based on __LINE__). -* -* @details -* Equivalent to Q_ASSERT(), except the name provides a better documentation -* of the intention of this assertion. -* -* @param[in] expr_ Boolean expression -*/ - - - Q_REQUIRE_ID(__LINE__, (expr_)) - - - - /*! Assertion for checking postconditions. -* -* @details -* This macro is equivalent to Q_ASSERT_ID(), except the name provides a better -* documentation of the intention of this assertion. -* -* @param[in] id_ ID number (unique within the module) of the assertion -* @param[in] expr_ Boolean expression -*/ - - - - - Q_ASSERT_ID((id_), (expr_)) - - - - /*! Assertion for checking postconditions. -* -* @details -* Equivalent to Q_ASSERT(), except the name provides a better documentation -* of the intention of this assertion. -* -* @param[in] expr_ Boolean expression -*/ - - - Q_ENSURE_ID(__LINE__, (expr_)) - - - - /*! Assertion for checking invariants. -* -* @details -* Equivalent to Q_ASSERT(), except the name provides a better documentation -* of the intention of this assertion. -* -* @param[in] id_ ID number (unique within the module) of the assertion -* @param[in] expr_ Boolean expression -*/ - - - - - Q_ASSERT_ID((id_), (expr_)) - - - - /*! Assertion for checking invariants. -* -* @details -* Equivalent to Q_ASSERT(), except the name provides a better documentation -* of the intention of this assertion. -* -* @param[in] expr_ Boolean expression -*/ - - - Q_INVARIANT_ID(__LINE__, (expr_)) - - + - /*! Assertion for a wrong path through the code (based on __LINE__) -* -* @details -* Calls the Q_onAssert() callback if ever executed. -* -* @note -* This macro identifies the problem location with the line number, -* which might change as the code is modified. -* -* @sa Q_ASSERT_ID() -*/ - + Q_ASSERT_ID(__LINE__, (expr_)) - + - /*! Assertion for a wrong path through the code -* -* @details -* Calls the Q_onAssert() callback if ever executed. -* -* @note -* This macro identifies the problem location with the line number, -* which might change as the code is modified. -* -* @sa Q_ERROR_ID() -*/ Q_ERROR_ID(__LINE__) - - - /*! General purpose assertion with user-specified ID number that -* **always** evaluates the `expr_` expression. -* -* @details -* Like the Q_ASSERT_ID() macro, except it **always** evaluates the -* `expr_` expression even when assertions are disabled with the -* ::Q_NASSERT macro. However, when the ::Q_NASSERT macro is defined, the -* Q_onAssert() callback is **not** called, even if `expr_` evaluates -* to FALSE. -* -* @param[in] expr_ Boolean expression to check -* -* @sa Q_ALLEGE_ID() -*/ - + + + + + - Q_ALLEGE_ID(__LINE__, (expr_)) + Q_ASSERT_ID((id_), (expr_)) - + + + + + Q_ASSERT(expr_) + + + + + + + + Q_ASSERT_INCRIT((id_), (expr_)) + + + + + + + + Q_ASSERT_ID((id_), (expr_)) + + + + + + Q_ASSERT(expr_) + + + + + + + + Q_ASSERT_INCRIT((id_), (expr_)) + + + + + + + + Q_ASSERT_ID((id_), (expr_)) + + + + + + Q_ASSERT(expr_) + + - /*! Static (compile-time) assertion. -* -* @details -* This type of assertion deliberately causes a compile-time error when -* the `expr_` Boolean expression evaluates to FALSE. The macro exploits -* the fact that in C/C++ a dimension of an array cannot be negative. -* The compile-time assertion has no runtime side effects. -* -* @param[in] expr_ Compile-time Boolean expression -* -* @note -* The static assertion macro is provided for backwards compatibility with -* older C standards. Newer C11 supports `_Static_assert()`, which should -* be used instead of Q_ASSERT_STATIC(). -*/ - + extern char Q_static_assert_[(expr_) ? 1 : -1] - - - /*! Static (compile-time) assertion. -* -* @deprecated -* Use Q_ASSERT_STATIC() or better yet `_Static_assert()` instead. -*/ - - - Q_ASSERT_STATIC(expr_) - - - - /*! typedef for assertions-ids and line numbers in assertions. -* -* @details -* This typedef specifies integer type for exclusive use in assertions. -* Use of this type, rather than plain 'int', is in compliance -* with the MISRA-C 2012 Dir 4.6 (adv). -*/ + + + _Noreturn void - - - /*! Callback function invoked in case of an assertion failure. -* -* @details -* This is an application-specific callback function needs to be defined in -* the application to perform the clean system shutdown and perhaps a reset. -* The Q_onAssert() function is the last line of defense after the -* system failure and its implementation shouild be very **carefully** -* designed and **tested** under various fault conditions, including but -* not limited to: stack overflow, stack corruption, or calling Q_onAssert() -* from an interrupt. - -* @param[in] module name of the file/module in which the assertion failed -* (constant, zero-terminated C string) -* @param[in] location location of the assertion within the module. This could -* be a line number or a user-specified ID-number. -* -* @returns -* This callback function should **not return** (see ::Q_NORETURN), -* as continuation after an assertion failure does not make sense. -* -* @note -* It is typically a **bad idea** to implement Q_onAssert() as an endless -* loop that ties up the CPU. During debuggin, Q_onAssert() is an ideal -* place to put a breakpoint. -* -* @tr{PQA01_4} -* -* Called by the following: Q_ASSERT_ID(), Q_ERROR_ID(), Q_REQUIRE_ID(), -* Q_ENSURE_ID(), Q_INVARIANT_ID() and Q_ALLEGE_ID() as well as: -* Q_ASSERT(), Q_ERROR(), Q_REQUIRE(), Q_ENSURE(), Q_INVARIANT(), -* and Q_ALLEGE(). -*/ - - - - + + + + + + + + - + - /*! Helper macro to calculate static dimension of a 1-dim `array_` -* -* @param array_ 1-dimensional array -* @returns the length of the array (number of elements it can hold) -*/ - + (sizeof(array_) / sizeof((array_)[0U])) @@ -426,1017 +215,365 @@ Contact information: - - /*! alias for line numbers in assertions and return from QF_run() */ - + - - /*! alias for enumerations used for event signals */ - + - - /*! alias for IEEE 754 32-bit floating point number, -* MISRA-C 2012 Dir 4.6(A) -* -* @note -* QP does not use floating-point types anywhere in the internal -* implementation, except in QS software tracing, where utilities for -* output of floating-point numbers are provided for application-specific -* trace records. -*/ - + - - /*! alias for IEEE 754 64-bit floating point number, -* MISRA-C 2012 Dir 4.6(A) -* -* @note -* QP does not use floating-point types anywhere in the internal -* implementation, except in QS software tracing, where utilities for -* output of floating-point numbers are provided for application-specific -* trace records. -*/ - - - - - - - /*! The size (in bytes) of the signal of an event. Valid values: -* 1U, 2U, or 4U; default 2U -* -* @details -* This macro can be defined in the QEP port file (qep_port.h) to -* configure the ::QSignal type. When the macro is not defined, the -* default of 2 bytes is applied. -*/ - 2U - - - - - - - /*! Virtual call to the top-most initial transition in a HSM. -* -* @param[in,out] me_ current instance pointer (see @ref oop) -* @param[in] par_ pointer the optional initialization parameter -* @param[in] qs_id_ QS local filter ID (used only when Q_SPY is defined) -* -* @note Must be called only ONCE after the SM "constructor". -* -* @tr{RQP102} -* -* @usage -* The following example illustrates how to initialize a SM, and dispatch -* events to it: -* @include qep_qhsm_use.c -*/ - - - - - - - do { \ - Q_ASSERT((me_)->vptr); \ - (*(me_)->vptr->init)((me_), (par_), (qs_id_)); \ -} while (false) - - - - - - - - - - do { \ - Q_ASSERT((me_)->vptr); \ - (*(me_)->vptr->init)((me_), (par_), 0U); \ -} while (false) - - - - /*! Virtual call to dispatch an event to a HSM -* -* @details -* Processes one event at a time in Run-to-Completion fashion. -* -* @param[in,out] me_ current instance pointer (see @ref oop) -* @param[in] e_ constant pointer the ::QEvt or a class -* derived from ::QEvt (see @ref oop) -* @param[in] qs_id_ QS local filter ID (used only when Q_SPY is defined) -* -* @note Must be called after the "constructor" and after QHSM_INIT(). -* -* @tr{RQP102} -*/ - - - - - - - \ - ((*(me_)->vptr->dispatch)((me_), (e_), (qs_id_))) - - - - - - - - - - \ - ((*(me_)->vptr->dispatch)((me_), (e_), 0U)) - - - - /*! Perform upcast from a subclass of ::QHsm to the base class ::QHsm -* -* @details -* Upcasting from a subclass to superclass is a very frequent and **safe** -* operation in object-oriented programming and object-oriented languages -* (such as C++) perform such upcasting automatically. However, OOP is -* implemented in C just as a set of coding conventions (see @ref oop), -* and the C compiler does not "know" that certain types are related by -* inheritance. Therefore for C, the upcast must be performed explicitly. -* Unfortunately, pointer casting violates the advisory MISRA-C 2012 -* Rule 11.3(req) "A cast shall not be performed between a pointer to object -* type and a pointer to a different object type". This macro encapsulates -* this deviation and provides a descriptive name for the reason of this cast. -*/ - - - ((QHsm *)(ptr_)) - - - - /*! Perform upcast from a subclass of ::QHsm to the base class ::QHsm -* -* @details -* Upcasting from a subclass to superclass is a very frequent and **safe** -* operation in object-oriented programming and object-oriented languages -* (such as C++) perform such upcasting automatically. However, OOP is -* implemented in C just as a set of coding conventions (see @ref oop), -* and the C compiler does not "know" that certain types are related by -* inheritance. Therefore for C, the upcast must be performed explicitly. -* Unfortunately, pointer casting violates the advisory MISRA-C 2012 -* Rule 11.3(req) "A cast shall not be performed between a pointer to object -* type and a pointer to a different object type". This macro encapsulates -* this deviation and provides a descriptive name for the reason of this cast. -*/ - - - \ - ((Q_HSM_UPCAST(me))->temp.fun = Q_STATE_CAST(target_), Q_RET_TRAN) - - - - /*! Macro to call in a state-handler when it executes a transition -* to history. Applicable only to HSMs. -* -* @tr{RQP103} @tr{RQP120H} -* -* @usage -* @include qep_qhist.c -*/ - - - \ - ((Q_HSM_UPCAST(me))->temp.fun = (hist_), Q_RET_TRAN_HIST) - - - - /*! Macro to call in a state-handler when it designates the superstate -* of a given state. Applicable only to ::QHsm subclasses. -* -* @tr{RQP103} -* -* @usage -* @include qep_qsuper.c -*/ - - - \ - ((Q_HSM_UPCAST(me))->temp.fun = Q_STATE_CAST(super_), Q_RET_SUPER) - - - - /*! Macro to call in a state-handler when it handles an event. -* @tr{RQP103} @tr{RQP120B} @tr{RQP120C} -*/ - (Q_RET_HANDLED) - - - - /*! Macro to call in a state-handler when it attempts to handle -* an event but a guard condition evaluates to 'false' and there is no other -* explicit way of handling the event. Applicable only to ::QHsm subclasses. -*/ - (Q_RET_UNHANDLED) - - - - /*! Macro to provide strictly-typed zero-action to terminate action lists -*! in the transition-action-tables -*/ - ((QActionHandler)0) - - - - /*! Perform downcast of an event onto a subclass of ::QEvt `class_` -* -* @details -* This macro encapsulates the downcast of ::QEvt pointers, which violates -* MISRA-C 2012 Rule 11.3(R) "A cast shall not be performed between a -* pointer to object type and a pointer to a different object type". This -* macro helps to localize this deviation. -* -* @param class_ a subclass of ::QEvt -* -* @tr{RQP003} -* @tr{PQA11_3} -*/ - - - ((class_ const *)(e)) - - - - /*! Perform cast to ::QStateHandler. -* @details -* This macro encapsulates the cast of a specific state handler function -* pointer to ::QStateHandler, which violates MISRA:C-2012 Rule 11.1(req) -* "Conversions shall not be performed between a pointer to function and -* any other type". This macro helps to localize this deviation. -* -* @tr{PQP11_1} @tr{PQA11_1} -* -* @usage -* @include qep_qhsm_ctor.c -*/ - - - ((QStateHandler)(handler_)) - - - - /*! Perform cast to ::QActionHandler. -* @details -* This macro encapsulates the cast of a specific action handler function -* pointer to ::QActionHandler, which violates MISRA:C-2012 Rule 11.1(R) -* "Conversions shall not be performed between a pointer to function and -* any other type". This macro helps to localize this deviation. -* -* @tr{PQP11_1} @tr{PQA11_1} -*/ - - - ((QActionHandler)(action_)) - - - - /*! Helper macro to clearly mark unused parameters of functions. */ - - - ((void)(par_)) - - - - /*! Helper macro to calculate static dimension of a 1-dim `array_` -* -* @param array_ 1-dimensional array -* @returns the length of the array (number of elements it can hold) -*/ - - - (sizeof(array_) / sizeof((array_)[0U])) - - - - /*! Perform cast from unsigned integer `uint_` to pointer of type `type_` -* -* @details -* This macro encapsulates the cast to (type_ *), which QP ports or -* application might use to access embedded hardware registers. -* Such uses can trigger PC-Lint "Note 923: cast from int to pointer" -* and this macro helps to encapsulate this deviation. -*/ - - - - - ((type_ *)(uint_)) - - - - /*! Initializer of static constant QEvt instances -* -* @details -* This macro encapsulates the ugly casting of enumerated signals -* to QSignal and constants for QEvt.poolID and QEvt.refCtr_. -*/ - - - { (QSignal)(sig_), 0U, 0U } - - - - /*! Macro to call in a QM action-handler when it executes -* an entry action. Applicable only to ::QMsm subclasses. -*/ - - - \ - ((Q_HSM_UPCAST(me))->temp.obj = (state_), Q_RET_ENTRY) - - - - - - (Q_RET_ENTRY) - - - - /*! Macro to call in a QM action-handler when it executes -* an exit action. Applicable only to ::QMsm subclasses. -*/ - - - \ - ((Q_HSM_UPCAST(me))->temp.obj = (state_), Q_RET_EXIT) - - - - - - (Q_RET_EXIT) - - - - /*! Macro to call in a QM submachine exit-handler. -* Applicable only to subclasses of ::QMsm. -*/ - - - \ - ((Q_HSM_UPCAST(me))->temp.obj = (state_), Q_RET_EXIT) - - - - /*! Macro to call in a QM state-handler when it executes a regular -* transition. Applicable only to ::QMsm subclasses. -*/ - - - ((Q_HSM_UPCAST(me))->temp.tatbl \ - = (struct QMTranActTable const *)(tatbl_), Q_RET_TRAN) - - - - /*! Macro to call in a QM state-handler when it executes an initial -* transition. Applicable only to ::QMsm subclasses. -*/ - - - ((Q_HSM_UPCAST(me))->temp.tatbl \ - = (struct QMTranActTable const *)(tatbl_), Q_RET_TRAN_INIT) - - - - /*! Macro to call in a QM state-handler when it executes a transition -* to history. Applicable only to ::QMsm subclasses. -*/ - - - - - \ - ((((Q_HSM_UPCAST(me))->state.obj = (history_)), \ - ((Q_HSM_UPCAST(me))->temp.tatbl = \ - (struct QMTranActTable const *)(tatbl_))), \ - Q_RET_TRAN_HIST) - - - - /*! Macro to call in a QM state-handler when it executes a transition -* to the submachine via an entry point. -*/ - - - ((Q_HSM_UPCAST(me))->temp.tatbl \ - = (struct QMTranActTable const *)(tatbl_), Q_RET_TRAN_EP) - - - - /*! Macro to call in a QM state-handler when it executes a transition -* to exit point. Applicable only to ::QMsm subclasses. -*/ - - - - - \ - ((((Q_HSM_UPCAST(me))->state.act = (xp_)), \ - ((Q_HSM_UPCAST(me))->temp.tatbl = \ - (struct QMTranActTable const *)(tatbl_))), \ - Q_RET_TRAN_XP) - - - - /*! Macro to call in a QM state-handler when it handled an event. -* Applicable only to ::QMsm subclasses. -*/ - (Q_RET_HANDLED) - - - - /*! Macro to call in a QM state-handler when when it attempts to -* handle an event but a guard condition evaluates to 'false' and there is -* no other explicit way of handling the event. Applicable only to -* ::QMsm subclasses. -*/ - (Q_RET_UNHANDLED) - - - - /*! Macro to call in a QM state-handler when it designates the -* superstate to handle an event. Applicable only to QMSMs. -*/ - (Q_RET_SUPER) - - - - /*! Macro to call in a QM submachine-handler when it designates the -* host state to handle an event. Applicable only to subclasses of ::QMsm. -*/ - - - \ - ((Q_HSM_UPCAST(me))->temp.obj = (host_), Q_RET_SUPER_SUB) - - - - /*! Macro to provide strictly-typed zero-state to use for submachines. -*! Applicable to subclasses of ::QMsm. -*/ - ((QMState *)0) - + - /*! the current QP version number string in ROM, based on #QP_VERSION_STR */ + //! the current QP version number string in ROM, based on #QP_VERSION_STR = QP_VERSION_STR; - - /*! ::QSignal represents the signal of an event -* -* @details -* The relationship between an event and a signal is as follows. A signal -* in UML is the specification of an asynchronous stimulus that triggers -* reactions, and as such is an essential part of an event. (The signal -* conveys the type of the occurrence--what happened?) However, an event -* can also contain additional quantitative information about the -* occurrence in form of event parameters. -*/ - - + + + + + 0xE0U + + + + 0U + - /*! @brief Event class -* @class QEvt -* -* @details -* ::QEvt represents events without parameters and serves as the base class -* for derivation of events with parameters. -* -* @tr{RQP001} @tr{RQP004} -* @tr{AQP210} -* -* @usage -* The following example illustrates how to add an event parameter by -* derivation of the ::QEvt class. Please note that the ::QEvt member -* super is defined as the FIRST member of the derived struct. -* @include qep_qevt.c -*/ + // ! @class QEvt - /*! Signal of the event. -* @public @memberof QEvt -* -* @tr{RQP002} -*/ - - - - /*! Pool ID (==0 for immutable event) -* @private @memberof QEvt -* -* @tr{RQP003} -*/ + //! @public @memberof QEvt - /*! Reference counter (for mutable events) -* @private @memberof QEvt -* -* @tr{RQP003} -*/ + //! @private @memberof QEvt + + + + //! @private @memberof QEvt + + + + = { + QEVT_INITIALIZER(Q_EMPTY_SIG), + QEVT_INITIALIZER(Q_ENTRY_SIG), + QEVT_INITIALIZER(Q_EXIT_SIG), + QEVT_INITIALIZER(Q_INIT_SIG) +}; - - /*! Custom event constructor -* @public @memberof QEvt -* @note -* Available only when the macro #Q_EVT_CTOR is defined -* @tr{RQP005} -*/ + + //! @public @memberof QEvt + +//! @public @memberof QEvt + if (sig != QEVT_DYNAMIC) { + me->sig = (QSignal)sig; + me->refCtr_ = 0U; + me->evtTag_ = QEVT_MARKER; +} +return me; + + + + const + //! @private @memberof QEvt + +//! @private @memberof QEvt + return (me != (QEvt const *)0) + && ((me->evtTag_ & 0xF0U) == QEVT_MARKER); + + + + const + //! @private @memberof QEvt + +//! @private @memberof QEvt + return (uint_fast8_t)me->evtTag_ & 0x0FU; - /*! All possible values returned from state/action handlers -* -* @note -* The order matters for algorithmic correctness. -*/ + //! All possible values returned from state/action handlers +//! @note +//! The order of enumeration matters for algorithmic correctness. { - /* unhandled and need to "bubble up" */ - Q_RET_SUPER, /*!< event passed to superstate to handle */ - Q_RET_SUPER_SUB, /*!< event passed to submachine superstate */ - Q_RET_UNHANDLED, /*!< event unhandled due to a guard */ + // unhandled and need to "bubble up" + Q_RET_SUPER, //!< event passed to superstate to handle + Q_RET_SUPER_SUB, //!< event passed to submachine superstate + Q_RET_UNHANDLED, //!< event unhandled due to a guard - /* handled and do not need to "bubble up" */ - Q_RET_HANDLED, /*!< event handled (internal transition) */ - Q_RET_IGNORED, /*!< event silently ignored (bubbled up to top) */ + // handled and do not need to "bubble up" + Q_RET_HANDLED, //!< event handled (internal transition) + Q_RET_IGNORED, //!< event silently ignored (bubbled up to top) - /* entry/exit */ - Q_RET_ENTRY, /*!< state entry action executed */ - Q_RET_EXIT, /*!< state exit action executed */ + // entry/exit + Q_RET_ENTRY, //!< state entry action executed + Q_RET_EXIT, //!< state exit action executed - /* no side effects */ - Q_RET_NULL, /*!< return value without any effect */ + // no side effects + Q_RET_NULL, //!< return value without any effect - /* transitions need to execute transition-action table in ::QMsm */ - Q_RET_TRAN, /*!< regular transition */ - Q_RET_TRAN_INIT, /*!< initial transition in a state or submachine */ - Q_RET_TRAN_EP, /*!< entry-point transition into a submachine */ + // transitions need to execute transition-action table in ::QMsm + Q_RET_TRAN, //!< regular transition + Q_RET_TRAN_INIT, //!< initial transition in a state or submachine + Q_RET_TRAN_EP, //!< entry-point transition into a submachine - /* transitions that additionally clobber me->state */ - Q_RET_TRAN_HIST, /*!< transition to history of a given state */ - Q_RET_TRAN_XP /*!< exit-point transition out of a submachine */ + // transitions that additionally clobber me->state + Q_RET_TRAN_HIST, //!< transition to history of a given state + Q_RET_TRAN_XP //!< exit-point transition out of a submachine }; - - /*! Type returned from state-handler functions */ - + - /*! Pointer to a state-handler function. */ )(void * const me, QEvt const * const e); - /*! Pointer to an action-handler function. */ )(void * const me); - /* forward declaration */ + // forward declaration - /*! Pointer to an eXthended thread handler function */ )(struct QXThread * const me); - /*! @brief State object for the ::QMsm class (QM State Machine). -* -* @details -* This class groups together the attributes of a ::QMsm state, such as the -* parent state (state nesting), the associated state handler function and -* the exit action handler function. These attributes are used inside the -* QMsm_dispatch() and QMsm_init() functions. -* -* @tr{RQP104} -* -* @attention -* The ::QMState class is only intended for the QM code generator and should -* not be used in hand-crafted code. -*/ { - struct QMState const *superstate; /*!< superstate of this state */ - QStateHandler const stateHandler; /*!< state handler function */ - QActionHandler const entryAction; /*!< entry action handler function */ - QActionHandler const exitAction; /*!< exit action handler function */ - QActionHandler const initAction; /*!< init action handler function */ + struct QMState const *superstate; //!< @private @memberof QMState + QStateHandler const stateHandler; //!< @private @memberof QMState + QActionHandler const entryAction; //!< @private @memberof QMState + QActionHandler const exitAction; //!< @private @memberof QMState + QActionHandler const initAction; //!< @private @memberof QMState } QMState; - /*! @brief Transition-Action Table for the ::QMsm State Machine. */ { - QMState const *target; /*!< target of the transition */ - QActionHandler const act[1]; /*!< array of actions */ + QMState const *target; //!< @private @memberof QMTranActTable + QActionHandler const act[1]; //!< @private @memberof QMTranActTable } QMTranActTable; - - - /*! @brief Attribute of for the ::QHsm class (Hierarchical State Machine). -* -* @details -* This union represents possible values stored in the 'state' and 'temp' -* attributes of the ::QHsm class. -*/ - { - QStateHandler fun; /*!< @private pointer to a state-handler */ - QActionHandler act; /*!< @private pointer to an action-handler */ - QXThreadHandler thr; /*!< @private pointer to an thread-handler */ - QMTranActTable const *tatbl; /*!< @private transition-action table */ - struct QMState const *obj; /*!< @private pointer to QMState object */ -}; - - - - /*! maximum depth of state nesting in a HSM (including the top level), -* must be >= 3 -*/ - = 6}; - - /*! Reserved signals by the HSM-style state machine -* implementation strategy. -*/ + //! Reserved signals by the QHsm-style state machine implementation { - Q_EMPTY_SIG, /*!< signal to execute the default case */ - Q_ENTRY_SIG, /*!< signal for coding entry actions */ - Q_EXIT_SIG, /*!< signal for coding exit actions */ - Q_INIT_SIG, /*!< signal for coding initial transitions */ - Q_USER_SIG /*!< offset for the user signals (QP Application) */ + Q_EMPTY_SIG, //!< signal to execute the default case + Q_ENTRY_SIG, //!< signal for coding entry actions + Q_EXIT_SIG, //!< signal for coding exit actions + Q_INIT_SIG, //!< signal for coding initial transitions + Q_USER_SIG //!< offset for the user signals (QP Application) +}; + + + + { + QStateHandler fun; //!< @private @memberof QAsmAttr + QActionHandler act; //!< @private @memberof QAsmAttr + QXThreadHandler thr; //!< @private @memberof QAsmAttr + QMTranActTable const *tatbl; //!< @private @memberof QAsmAttr + struct QMState const *obj; //!< @private @memberof QAsmAttr +#ifndef Q_UNSAFE + uintptr_t uint; //!< @private @memberof QAsmAttr +#endif +}; + + + + //! @class QAsm + + + //! @protected @memberof QAsm + + + + //! @protected @memberof QAsm + + + + //! @protected @memberof QAsm + + + + //! @protected @memberof QAsm + +//! @protected @memberof QAsm + me->vptr = (QAsmVtable *)0; +me->state.fun = Q_STATE_CAST(0); +me->temp.fun = Q_STATE_CAST(0); + + + + + { + void (*init)(QAsm * const me, void const * const e, + uint_fast8_t const qs_id); + void (*dispatch)(QAsm * const me, QEvt const * const e, + uint_fast8_t const qs_id); +#ifdef Q_SPY + QStateHandler (*getStateHandler)(QAsm * const me); +#endif // Q_SPY }; - - /*! @brief Hierarchical State Machine class -* @class QHsm -* -* @details -* QHsm represents a Hierarchical State Machine (HSM) with full support for -* hierarchical nesting of states, entry/exit actions, initial transitions, -* and transitions to history in any composite state. This class is designed -* for ease of manual coding of HSMs in C, but it is also supported by the -* QM modeling tool.<br> -* -* QHsm is also the base class for the QMsm state machine, which provides -* a superior efficiency, but requires the use of the QM modeling tool to -* generate code. -* -* @note -* QHsm is not intended to be instantiated directly, but rather serves as the -* abstract base class for derivation of state machines in the QP application. -* -* @tr{RQP103} -* @tr{AQP211} -* -* @usage -* The following example illustrates how to derive a state machine class -* from QHsm. Please note that the QHsm member `super` is defined as the -* FIRST member of the derived class. -* @include qep_qhsm.c -*/ - - - /*! Virtual pointer -* @private @memberof QHsm -* -* @tr{RQP102} -*/ - - - - /*! Current active state (state-variable). -* @private @memberof QHsm -*/ - - - - /*! Temporary: target/act-table, etc. -* @private @memberof QHsm -*/ - - - - /*! Tests if a given state is part of the current active state -* configuration in ::QHsm subclasses. -* @public @memberof QHsm -* -* @details -* Tests if a state machine derived from QHsm is-in a given state. -* -* @note For a HSM, to "be in a state" means also to be in a superstate of -* of the state. -* -* @param[in] me current instance pointer (see @ref oop) -* @param[in] state pointer to the state-handler function to be tested -* -* @returns -*'true' if the HSM "is in" the `state` and 'false' otherwise -* -* @tr{RQP103} -* @tr{RQP120S} -*/ - - - /*! @pre the state configuration must be stable */ -Q_REQUIRE_ID(600, me->temp.fun == me->state.fun); + + //! @class QHsm +//! @extends QAsm -bool inState = false; /* assume that this HSM is not in 'state' */ - -/* scan the state hierarchy bottom-up */ -QState r; -do { - /* do the states match? */ - if (me->temp.fun == state) { - inState = true; /* 'true' means that match found */ - r = Q_RET_IGNORED; /* break out of the loop */ - } - else { - r = QHsm_reservedEvt_(me, me->temp.fun, Q_EMPTY_SIG); - } -} while (r != Q_RET_IGNORED); /* QHsm_top() state not reached */ -me->temp.fun = me->state.fun; /* restore the stable state configuration */ - -return inState; /* return the status */ - - - - /*! Obtain the current active state from a HSM (read only). -* @public @memberof QHsm -* -* @param[in] me current instance pointer (see @ref oop) -* -* @returns the current active state of the QHsm class -* -* @note -* This function is used in QM for auto-generating code for state history. -*/ - return me->state.fun; - - - - /*! Obtain the current active child state of a given parent in ::QHsm -* @public @memberof QHsm -* -* @details -* Finds the child state of the given `parent`, such that this child state -* is an ancestor of the currently active state. The main purpose of this -* function is to support **shallow history** transitions in state machines -* derived from QHsm. -* -* @param[in] me current instance pointer (see @ref oop) -* @param[in] parent pointer to the state-handler function -* -* @returns -* the child of a given `parent` state, which is an ancestor of the current -* active state. For the corner case when the currently active state is the -* given `parent` state, function returns the `parent` state. -* -* @note -* this function is designed to be called during state transitions, so it -* does not necessarily start in a stable state configuration. -* However, the function establishes stable state configuration upon exit. -* -* @tr{RQP103} -* @tr{RQP120H} -*/ - - - QStateHandler child = me->state.fun; /* start with the current state */ -bool isFound = false; /* start with the child not found */ - -/* establish stable state configuration */ -me->temp.fun = me->state.fun; -QState r; -do { - /* is this the parent of the current child? */ - if (me->temp.fun == parent) { - isFound = true; /* child is found */ - r = Q_RET_IGNORED; /* break out of the loop */ - } - else { - child = me->temp.fun; - r = QHsm_reservedEvt_(me, me->temp.fun, Q_EMPTY_SIG); - } -} while (r != Q_RET_IGNORED); /* QHsm_top() state not reached */ -me->temp.fun = me->state.fun; /* establish stable state configuration */ - -/*! @post the child must be found */ -Q_ENSURE_ID(810, isFound); - -#ifdef Q_NASSERT -Q_UNUSED_PAR(isFound); -#endif - -return child; /* return the child */ - +Human-generated State Machine - /*! Protected "constructor" of ::QHsm -* @protected @memberof QHsm -* -* @details -* Performs the first step of HSM initialization by assigning the initial -* pseudostate to the currently active state of the state machine. -* -* @param[in,out] me current instance pointer (see @ref oop) -* @param[in] initial pointer to the top-most initial state-handler -* function in the derived state machine -* -* @note Must be called only by the constructors of the derived state -* machines. -* -* @note Must be called only ONCE before QHSM_INIT(). -* -* @usage -* The following example illustrates how to invoke QHsm_ctor() in the -* "constructor" of a derived state machine: -* @include qep_qhsm_ctor.c -* -* @tr{RQP103} -*/ + //! @protected @memberof QHsm + +//! @protected @memberof QHsm - static struct QHsmVtable const vtable = { /* QHsm virtual table */ + static struct QAsmVtable const vtable = { // QAsm virtual table &QHsm_init_, &QHsm_dispatch_ #ifdef Q_SPY ,&QHsm_getStateHandler_ #endif }; -me->vptr = &vtable; -me->state.fun = Q_STATE_CAST(&QHsm_top); -me->temp.fun = initial; - - - - const - /*! The top-state of QHsm. -* @protected @memberof QHsm -* -* @details -* QHsm_top() is the ultimate root of state hierarchy in all HSMs derived -* from ::QHsm. -* -* @param[in] me current instance pointer (see @ref oop) -* @param[in] e pointer to the event to be dispatched to the FSM -* -* @returns -* Always returns ::Q_RET_IGNORED, which means that the top state ignores -* all events. -* -* @note The parameters to this state handler are not used. They are provided -* for conformance with the state-handler function signature ::QStateHandler. -* -* @tr{RQP103} @tr{RQP120T} -*/ - - - Q_UNUSED_PAR(me); -Q_UNUSED_PAR(e); -return Q_RET_IGNORED; /* the top state ignores all events */ +// do not call the QAsm_ctor() here +me->super.vptr = &vtable; +me->super.state.fun = Q_STATE_CAST(&QHsm_top); +me->super.temp.fun = initial; - - /*! Implementation of the top-most initial tran. in ::QHsm. -* @protected @memberof QHsm -* -* @details -* Executes the top-most initial transition in a HSM. -* -* @param[in,out] me current instance pointer (see @ref oop) -* @param[in] e pointer to an extra parameter (might be NULL) -* @param[in] qs_id QS-id of this state machine (for QS local filter) -* -* @note Must be called only ONCE after the QHsm_ctor(). -* -* @tr{RQP103} @tr{RQP120I} @tr{RQP120D} -*/ + + //! @private @memberof QHsm + +//! @private @memberof QHsm + + - #ifdef Q_SPY + QF_CRIT_STAT + +#ifdef Q_SPY +QS_CRIT_ENTRY(); +QS_MEM_SYS(); if ((QS_priv_.flags & 0x01U) == 0U) { QS_priv_.flags |= 0x01U; QS_FUN_DICTIONARY(&QHsm_top); } +QS_MEM_APP(); +QS_CRIT_EXIT(); #else Q_UNUSED_PAR(qs_id); #endif QStateHandler t = me->state.fun; -/*! @pre the virtual pointer must be initialized, the top-most initial -* transition must be initialized, and the initial transition must not -* be taken yet. -*/ -Q_REQUIRE_ID(200, (me->vptr != (struct QHsmVtable *)0) +QF_CRIT_ENTRY(); +Q_REQUIRE_INCRIT(200, (me->vptr != (struct QAsmVtable *)0) && (me->temp.fun != Q_STATE_CAST(0)) && (t == Q_STATE_CAST(&QHsm_top))); +QF_CRIT_EXIT(); -/* execute the top-most initial tran. */ +// execute the top-most initial tran. QState r = (*me->temp.fun)(me, Q_EVT_CAST(QEvt)); -/* the top-most initial transition must be taken */ -Q_ASSERT_ID(210, r == Q_RET_TRAN); +QF_CRIT_ENTRY(); +// the top-most initial tran. must be taken +Q_ASSERT_INCRIT(210, r == Q_RET_TRAN); -QS_CRIT_STAT_ +QS_MEM_SYS(); QS_BEGIN_PRE_(QS_QEP_STATE_INIT, qs_id) - QS_OBJ_PRE_(me); /* this state machine object */ - QS_FUN_PRE_(t); /* the source state */ - QS_FUN_PRE_(me->temp.fun); /* the target of the initial transition */ + QS_OBJ_PRE_(me); // this state machine object + QS_FUN_PRE_(t); // the source state + QS_FUN_PRE_(me->temp.fun); // the target of the initial tran. QS_END_PRE_() +QS_MEM_APP(); -/* drill down into the state hierarchy with initial transitions... */ +QF_CRIT_EXIT(); + +// drill down into the state hierarchy with initial transitions... do { - QStateHandler path[QHSM_MAX_NEST_DEPTH_]; /* tran entry path array */ - int_fast8_t ip = 0; /* tran entry path index */ + QStateHandler path[QHSM_MAX_NEST_DEPTH_]; // tran entry path array + int_fast8_t ip = 0; // tran entry path index path[0] = me->temp.fun; - (void)QHsm_reservedEvt_(me, me->temp.fun, Q_EMPTY_SIG); + (void)QHSM_RESERVED_EVT_(me->temp.fun, Q_EMPTY_SIG); while (me->temp.fun != t) { ++ip; - Q_ASSERT_ID(220, ip < QHSM_MAX_NEST_DEPTH_); + QF_CRIT_ENTRY(); + Q_ASSERT_INCRIT(220, ip < QHSM_MAX_NEST_DEPTH_); + QF_CRIT_EXIT(); path[ip] = me->temp.fun; - (void)QHsm_reservedEvt_(me, me->temp.fun, Q_EMPTY_SIG); + (void)QHSM_RESERVED_EVT_(me->temp.fun, Q_EMPTY_SIG); } me->temp.fun = path[0]; - /* nested initial transition, drill into the target hierarchy... */ + // nested initial tran.; drill into the target hierarchy... do { - QHsm_state_entry_(me, path[ip], qs_id); /* enter path[ip] */ + // enter path[ip] + if (QHSM_RESERVED_EVT_(path[ip], Q_ENTRY_SIG) + == Q_RET_HANDLED) + { + QS_STATE_ENTRY_(path[ip], qs_id); + } --ip; } while (ip >= 0); - t = path[0]; /* current state becomes the new source */ + t = path[0]; // current state becomes the new source - r = QHsm_reservedEvt_(me, t, Q_INIT_SIG); /* execute initial transition */ + r = QHSM_RESERVED_EVT_(t, Q_INIT_SIG); // execute initial tran. #ifdef Q_SPY if (r == Q_RET_TRAN) { + QS_CRIT_ENTRY(); + QS_MEM_SYS(); QS_BEGIN_PRE_(QS_QEP_STATE_INIT, qs_id) - QS_OBJ_PRE_(me); /* this state machine object */ - QS_FUN_PRE_(t); /* the source state */ - QS_FUN_PRE_(me->temp.fun); /* target of the initial tran. */ + QS_OBJ_PRE_(me); // this state machine object + QS_FUN_PRE_(t); // the source state + QS_FUN_PRE_(me->temp.fun); // the target of the initial tran. QS_END_PRE_() + QS_MEM_APP(); + QS_CRIT_EXIT(); } -#endif /* Q_SPY */ +#endif // Q_SPY } while (r == Q_RET_TRAN); +QS_CRIT_ENTRY(); +QS_MEM_SYS(); QS_BEGIN_PRE_(QS_QEP_INIT_TRAN, qs_id) - QS_TIME_PRE_(); /* time stamp */ - QS_OBJ_PRE_(me); /* this state machine object */ - QS_FUN_PRE_(t); /* the new active state */ + QS_TIME_PRE_(); // time stamp + QS_OBJ_PRE_(me); // this state machine object + QS_FUN_PRE_(t); // the new active state QS_END_PRE_() +QS_MEM_APP(); +QS_CRIT_EXIT(); -me->state.fun = t; /* change the current active state */ -me->temp.fun = t; /* mark the configuration as stable */ +me->state.fun = t; // change the current active state +#ifndef Q_UNSAFE +me->temp.uint = ~me->state.uint; +#endif - - /*! Implementation of dispatching events to a ::QHsm -* @protected @memberof QHsm -* -* @details -* Dispatches an event for processing to a hierarchical state machine (HSM). -* The processing of an event represents one run-to-completion (RTC) step. -* -* @param[in,out] me current instance pointer (see @ref oop) -* @param[in] e pointer to the event to be dispatched to the HSM -* @param[in] qs_id QS-id of this state machine (for QS local filter) -* -* @note -* This function should be called only via the virtual table (see -* QHSM_DISPATCH()) and should NOT be called directly in the applications. -* -* @tr{RQP103} -* @tr{RQP120A} @tr{RQP120B} @tr{RQP120C} @tr{RQP120D} @tr{RQP120E} -*/ + + //! @private @memberof QHsm + +//! @private @memberof QHsm + + @@ -1445,175 +582,278 @@ me->temp.fun = t; /* mark the configuration as stable */ Q_UNUSED_PAR(qs_id); #endif -QStateHandler t = me->state.fun; -QS_CRIT_STAT_ +QStateHandler s = me->state.fun; +QStateHandler t = s; +QF_CRIT_STAT -/*! @pre the current state must be initialized and -* the state configuration must be stable -*/ -Q_REQUIRE_ID(400, (t != Q_STATE_CAST(0)) - && (t == me->temp.fun)); +QF_CRIT_ENTRY(); +Q_REQUIRE_INCRIT(300, (s != Q_STATE_CAST(0)) + && (me->state.uint == (uintptr_t)(~me->temp.uint))); +Q_REQUIRE_INCRIT(302, QEvt_verify_(e)); +QS_MEM_SYS(); QS_BEGIN_PRE_(QS_QEP_DISPATCH, qs_id) - QS_TIME_PRE_(); /* time stamp */ - QS_SIG_PRE_(e->sig); /* the signal of the event */ - QS_OBJ_PRE_(me); /* this state machine object */ - QS_FUN_PRE_(t); /* the current state */ + QS_TIME_PRE_(); // time stamp + QS_SIG_PRE_(e->sig); // the signal of the event + QS_OBJ_PRE_(me); // this state machine object + QS_FUN_PRE_(s); // the current state QS_END_PRE_() +QS_MEM_APP(); -QStateHandler s; +QF_CRIT_EXIT(); + +// process the event hierarchically... QState r; -/* process the event hierarchically... */ +me->temp.fun = s; do { s = me->temp.fun; - r = (*s)(me, e); /* invoke state handler s */ + r = (*s)(me, e); // invoke state handler s - if (r == Q_RET_UNHANDLED) { /* unhandled due to a guard? */ + if (r == Q_RET_UNHANDLED) { // unhandled due to a guard? + QS_CRIT_ENTRY(); + QS_MEM_SYS(); QS_BEGIN_PRE_(QS_QEP_UNHANDLED, qs_id) - QS_SIG_PRE_(e->sig); /* the signal of the event */ - QS_OBJ_PRE_(me); /* this state machine object */ - QS_FUN_PRE_(s); /* the current state */ + QS_SIG_PRE_(e->sig); // the signal of the event + QS_OBJ_PRE_(me); // this state machine object + QS_FUN_PRE_(s); // the current state QS_END_PRE_() + QS_MEM_APP(); + QS_CRIT_EXIT(); - r = QHsm_reservedEvt_(me, s, Q_EMPTY_SIG); /* find superstate of s */ + r = QHSM_RESERVED_EVT_(s, Q_EMPTY_SIG); // superstate of s } } while (r == Q_RET_SUPER); -/* regular transition taken? */ -/*! @tr{RQP120E} */ -if (r >= Q_RET_TRAN) { +if (r >= Q_RET_TRAN) { // regular tran. taken? QStateHandler path[QHSM_MAX_NEST_DEPTH_]; - path[0] = me->temp.fun; /* save the target of the transition */ - path[1] = t; - path[2] = s; + path[0] = me->temp.fun; // tran. target + path[1] = t; // current state + path[2] = s; // tran. source - /* exit current state to transition source s... */ - /*! @tr{RQP120C} */ + // exit current state to tran. source s... for (; t != s; t = me->temp.fun) { - /* exit from t handled? */ - if (QHsm_state_exit_(me, t, qs_id)) { - /* find superstate of t */ - (void)QHsm_reservedEvt_(me, t, Q_EMPTY_SIG); + // exit from t + if (QHSM_RESERVED_EVT_(t, Q_EXIT_SIG) == Q_RET_HANDLED) { + QS_STATE_EXIT_(t, qs_id); + // find superstate of t + (void)QHSM_RESERVED_EVT_(t, Q_EMPTY_SIG); } } - - int_fast8_t ip = QHsm_tran_(me, path, qs_id); /* the HSM transition */ + int_fast8_t ip = QHsm_tran_(me, path, qs_id); // take the tran. #ifdef Q_SPY if (r == Q_RET_TRAN_HIST) { + QS_CRIT_ENTRY(); + QS_MEM_SYS(); QS_BEGIN_PRE_(QS_QEP_TRAN_HIST, qs_id) - QS_OBJ_PRE_(me); /* this state machine object */ - QS_FUN_PRE_(t); /* the source of the transition */ - QS_FUN_PRE_(path[0]); /* the target of tran. to history */ + QS_OBJ_PRE_(me); // this state machine object + QS_FUN_PRE_(t); // the source of the tran. + QS_FUN_PRE_(path[0]); // the target of the tran. to history QS_END_PRE_() + QS_MEM_APP(); + QS_CRIT_EXIT(); } -#endif /* Q_SPY */ +#endif // Q_SPY - /* execute state entry actions in the desired order... */ - /*! @tr{RQP120B} */ + // execute state entry actions in the desired order... for (; ip >= 0; --ip) { - QHsm_state_entry_(me, path[ip], qs_id); /* enter path[ip] */ + // enter path[ip] + if (QHSM_RESERVED_EVT_(path[ip], Q_ENTRY_SIG) + == Q_RET_HANDLED) + { + QS_STATE_ENTRY_(path[ip], qs_id); + } } + t = path[0]; // stick the target into register + me->temp.fun = t; // update the next state - t = path[0]; /* stick the target into register */ - me->temp.fun = t; /* update the next state */ - - /* while nested initial transition... */ - /*! @tr{RQP120I} */ - while (QHsm_reservedEvt_(me, t, Q_INIT_SIG) == Q_RET_TRAN) { + // drill into the target hierarchy... + while (QHSM_RESERVED_EVT_(t, Q_INIT_SIG) == Q_RET_TRAN) { + QS_CRIT_ENTRY(); + QS_MEM_SYS(); QS_BEGIN_PRE_(QS_QEP_STATE_INIT, qs_id) - QS_OBJ_PRE_(me); /* this state machine object */ - QS_FUN_PRE_(t); /* the source (pseudo)state */ - QS_FUN_PRE_(me->temp.fun); /* the target of the tran. */ + QS_OBJ_PRE_(me); // this state machine object + QS_FUN_PRE_(t); // the source (pseudo)state + QS_FUN_PRE_(me->temp.fun); // the target of the tran. QS_END_PRE_() + QS_MEM_APP(); + QS_CRIT_EXIT(); ip = 0; path[0] = me->temp.fun; - /* find superstate */ - (void)QHsm_reservedEvt_(me, me->temp.fun, Q_EMPTY_SIG); + // find superstate + (void)QHSM_RESERVED_EVT_(me->temp.fun, Q_EMPTY_SIG); while (me->temp.fun != t) { ++ip; path[ip] = me->temp.fun; - /* find superstate */ - (void)QHsm_reservedEvt_(me, me->temp.fun, Q_EMPTY_SIG); + // find superstate + (void)QHSM_RESERVED_EVT_(me->temp.fun, Q_EMPTY_SIG); } me->temp.fun = path[0]; - /* entry path must not overflow */ - Q_ASSERT_ID(410, ip < QHSM_MAX_NEST_DEPTH_); + // entry path must not overflow + QF_CRIT_ENTRY(); + Q_ASSERT_INCRIT(410, ip < QHSM_MAX_NEST_DEPTH_); + QF_CRIT_EXIT(); - /* retrace the entry path in reverse (correct) order... */ + // retrace the entry path in reverse (correct) order... do { - QHsm_state_entry_(me, path[ip], qs_id); /* enter path[ip] */ + // enter path[ip] + if (QHSM_RESERVED_EVT_(path[ip], Q_ENTRY_SIG) + == Q_RET_HANDLED) + { + QS_STATE_ENTRY_(path[ip], qs_id); + } --ip; } while (ip >= 0); - t = path[0]; /* current state becomes the new source */ + t = path[0]; // current state becomes the new source } + QS_CRIT_ENTRY(); + QS_MEM_SYS(); QS_BEGIN_PRE_(QS_QEP_TRAN, qs_id) - QS_TIME_PRE_(); /* time stamp */ - QS_SIG_PRE_(e->sig); /* the signal of the event */ - QS_OBJ_PRE_(me); /* this state machine object */ - QS_FUN_PRE_(s); /* the source of the transition */ - QS_FUN_PRE_(t); /* the new active state */ + QS_TIME_PRE_(); // time stamp + QS_SIG_PRE_(e->sig); // the signal of the event + QS_OBJ_PRE_(me); // this state machine object + QS_FUN_PRE_(s); // the source of the tran. + QS_FUN_PRE_(t); // the new active state QS_END_PRE_() + QS_MEM_APP(); + QS_CRIT_EXIT(); } #ifdef Q_SPY else if (r == Q_RET_HANDLED) { - + QS_CRIT_ENTRY(); + QS_MEM_SYS(); QS_BEGIN_PRE_(QS_QEP_INTERN_TRAN, qs_id) - QS_TIME_PRE_(); /* time stamp */ - QS_SIG_PRE_(e->sig); /* the signal of the event */ - QS_OBJ_PRE_(me); /* this state machine object */ - QS_FUN_PRE_(s); /* the source state */ + QS_TIME_PRE_(); // time stamp + QS_SIG_PRE_(e->sig); // the signal of the event + QS_OBJ_PRE_(me); // this state machine object + QS_FUN_PRE_(s); // the source state QS_END_PRE_() - + QS_MEM_APP(); + QS_CRIT_EXIT(); } else { - + QS_CRIT_ENTRY(); + QS_MEM_SYS(); QS_BEGIN_PRE_(QS_QEP_IGNORED, qs_id) - QS_TIME_PRE_(); /* time stamp */ - QS_SIG_PRE_(e->sig); /* the signal of the event */ - QS_OBJ_PRE_(me); /* this state machine object */ - QS_FUN_PRE_(me->state.fun); /* the current state */ + QS_TIME_PRE_(); // time stamp + QS_SIG_PRE_(e->sig); // the signal of the event + QS_OBJ_PRE_(me); // this state machine object + QS_FUN_PRE_(me->state.fun); // the current state QS_END_PRE_() - + QS_MEM_APP(); + QS_CRIT_EXIT(); } -#endif /* Q_SPY */ +#endif // Q_SPY -me->state.fun = t; /* change the current active state */ -me->temp.fun = t; /* mark the configuration as stable */ +me->state.fun = t; // change the current active state +#ifndef Q_UNSAFE +me->temp.uint = ~me->state.uint; +#endif - - /*! Implementation of getting the state handler in a ::QHsm subclass -* @private @memberof QHsm -*/ + + //! @private @memberof QHsm + +//! @private @memberof QHsm + + return me->state.fun; + + + //! @public @memberof QHsm + +//! @public @memberof QHsm + + + QF_CRIT_STAT +QF_CRIT_ENTRY(); +Q_REQUIRE_INCRIT(602, me->super.state.uint + == (uintptr_t)(~me->super.temp.uint)); +QF_CRIT_EXIT(); + +bool inState = false; // assume that this HSM is not in 'state' + +// scan the state hierarchy bottom-up +QState r; +do { + // do the states match? + if (me->super.temp.fun == state) { + inState = true; // 'true' means that match found + r = Q_RET_IGNORED; // cause breaking out of the loop + } + else { + r = QHSM_RESERVED_EVT_(me->super.temp.fun, Q_EMPTY_SIG); + } +} while (r != Q_RET_IGNORED); // QHsm_top() state not reached + +#ifndef Q_UNSAFE +me->super.temp.uint = ~me->super.state.uint; +#endif + +return inState; // return the status + + + + const + //! @public @memberof QHsm + +//! @public @memberof QHsm + return me->super.state.fun; + + + + //! @public @memberof QHsm + +//! @public @memberof QHsm + + + QStateHandler child = me->super.state.fun; // start with current state +bool isFound = false; // start with the child not found + +// establish stable state configuration +me->super.temp.fun = child; +QState r; +do { + // is this the parent of the current child? + if (me->super.temp.fun == parent) { + isFound = true; // child is found + r = Q_RET_IGNORED; // break out of the loop + } + else { + child = me->super.temp.fun; + r = QHSM_RESERVED_EVT_(me->super.temp.fun, Q_EMPTY_SIG); + } +} while (r != Q_RET_IGNORED); // the top state not reached + +#ifndef Q_UNSAFE +me->super.temp.uint = ~me->super.state.uint; +#endif + +QF_CRIT_STAT +QF_CRIT_ENTRY(); +Q_ASSERT_INCRIT(890, isFound); +QF_CRIT_EXIT(); + +return child; // return the child + - - /*! Helper function to execute transition sequence in a hierarchical state -* machine (HSM). -* @private @memberof QHsm -* -* @param[in,out] path array of pointers to state-handler functions -* to execute the entry actions -* @param[in] qs_id QS-id of this state machine (for QS local filter) -* -* @returns -* the depth of the entry path stored in the `path` parameter. -* -* @tr{RQP103} -* @tr{RQP120E} @tr{RQP120F} -*/ + + //! @private @memberof QHsm + +//! @private @memberof QHsm + + @@ -1622,116 +862,128 @@ me->temp.fun = t; /* mark the configuration as stable */ Q_UNUSED_PAR(qs_id); #endif -int_fast8_t ip = -1; /* transition entry path index */ +int_fast8_t ip = -1; // tran. entry path index QStateHandler t = path[0]; QStateHandler const s = path[2]; +QF_CRIT_STAT -/* (a) check source==target (transition to self)... */ +// (a) check source==target (tran. to self)... if (s == t) { - (void)QHsm_state_exit_(me, s, qs_id); /* exit source */ - ip = 0; /* enter the target */ + // exit source s + if (QHSM_RESERVED_EVT_(s, Q_EXIT_SIG) == Q_RET_HANDLED) { + QS_STATE_EXIT_(s, qs_id); + } + ip = 0; // enter the target } else { - /* find superstate of target */ - (void)QHsm_reservedEvt_(me, t, Q_EMPTY_SIG); + // find superstate of target + (void)QHSM_RESERVED_EVT_(t, Q_EMPTY_SIG); t = me->temp.fun; - /* (b) check source==target->super... */ + // (b) check source==target->super... if (s == t) { - ip = 0; /* enter the target */ + ip = 0; // enter the target } else { - /* find superstate of src */ - (void)QHsm_reservedEvt_(me, s, Q_EMPTY_SIG); + // find superstate of src + (void)QHSM_RESERVED_EVT_(s, Q_EMPTY_SIG); - /* (c) check source->super==target->super... */ + // (c) check source->super==target->super... if (me->temp.fun == t) { - (void)QHsm_state_exit_(me, s, qs_id); /* exit source */ - ip = 0; /* enter the target */ + // exit source s + if (QHSM_RESERVED_EVT_(s, Q_EXIT_SIG) == Q_RET_HANDLED) { + QS_STATE_EXIT_(s, qs_id); + } + ip = 0; // enter the target } else { - /* (d) check source->super==target... */ + // (d) check source->super==target... if (me->temp.fun == path[0]) { - (void)QHsm_state_exit_(me, s, qs_id); /* exit source */ + // exit source s + if (QHSM_RESERVED_EVT_(s, Q_EXIT_SIG) == Q_RET_HANDLED) { + QS_STATE_EXIT_(s, qs_id); + } } else { - /* (e) check rest of source==target->super->super.. - * and store the entry path along the way - */ - int_fast8_t iq = 0; /* indicate that LCA not found */ - ip = 1; /* enter target and its superstate */ - path[1] = t; /* save the superstate of target */ - t = me->temp.fun; /* save source->super */ + // (e) check rest of source==target->super->super.. + // and store the entry path along the way + int_fast8_t iq = 0; // indicate that LCA was found + ip = 1; // enter target and its superstate + path[1] = t; // save the superstate of target + t = me->temp.fun; // save source->super - /* find target->super->super... */ - QState r = QHsm_reservedEvt_(me, path[1], Q_EMPTY_SIG); + // find target->super->super... + QState r = QHSM_RESERVED_EVT_(path[1], Q_EMPTY_SIG); while (r == Q_RET_SUPER) { ++ip; - path[ip] = me->temp.fun; /* store the entry path */ - if (me->temp.fun == s) { /* is it the source? */ - iq = 1; /* indicate that LCA found */ + path[ip] = me->temp.fun; // store the entry path + if (me->temp.fun == s) { // is it the source? + iq = 1; // indicate that the LCA found - /* entry path must not overflow */ - Q_ASSERT_ID(510, - ip < QHSM_MAX_NEST_DEPTH_); - --ip; /* do not enter the source */ - r = Q_RET_HANDLED; /* terminate loop */ + // entry path must not overflow + QF_CRIT_ENTRY(); + Q_ASSERT_INCRIT(510, ip < QHSM_MAX_NEST_DEPTH_); + QF_CRIT_EXIT(); + --ip; // do not enter the source + r = Q_RET_HANDLED; // terminate the loop } - /* it is not the source, keep going up */ - else { - r = QHsm_reservedEvt_(me, me->temp.fun, - Q_EMPTY_SIG); + else { // it is not the source, keep going up + r = QHSM_RESERVED_EVT_(me->temp.fun, Q_EMPTY_SIG); } } - /* the LCA not found yet? */ + // the LCA not found yet? if (iq == 0) { + // entry path must not overflow + QF_CRIT_ENTRY(); + Q_ASSERT_INCRIT(520, ip < QHSM_MAX_NEST_DEPTH_); + QF_CRIT_EXIT(); - /* entry path must not overflow */ - Q_ASSERT_ID(520, ip < QHSM_MAX_NEST_DEPTH_); + // exit source s + if (QHSM_RESERVED_EVT_(s, Q_EXIT_SIG) + == Q_RET_HANDLED) + { + QS_STATE_EXIT_(s, qs_id); + } - /* exit source */ - (void)QHsm_state_exit_(me, s, qs_id); - - /* (f) check the rest of source->super - * == target->super->super... - */ + // (f) check the rest of source->super + // == target->super->super... iq = ip; - r = Q_RET_IGNORED; /* LCA NOT found */ + r = Q_RET_IGNORED; // indicate that the LCA NOT found do { - if (t == path[iq]) { /* is this the LCA? */ - r = Q_RET_HANDLED; /* LCA found */ - ip = iq - 1; /* do not enter LCA */ - iq = -1; /* cause termintion of the loop */ + if (t == path[iq]) { // is this the LCA? + r = Q_RET_HANDLED; // indicate the LCA found + ip = iq - 1; // do not enter the LCA + iq = -1; // cause termination of the loop } else { - --iq; /* try lower superstate of target */ + --iq; // try lower superstate of target } } while (iq >= 0); - /* LCA not found? */ + // the LCA not found yet? if (r != Q_RET_HANDLED) { - /* (g) check each source->super->... - * for each target->super... - */ - r = Q_RET_IGNORED; /* keep looping */ + // (g) check each source->super->... + // for each target->super... + r = Q_RET_IGNORED; // keep looping do { - /* exit from t handled? */ - if (QHsm_state_exit_(me, t, qs_id)) { - /* find superstate of t */ - (void)QHsm_reservedEvt_(me, t, Q_EMPTY_SIG); + // exit from t + if (QHSM_RESERVED_EVT_(t, Q_EXIT_SIG) + == Q_RET_HANDLED) + { + QS_STATE_EXIT_(t, qs_id); + // find superstate of t + (void)QHSM_RESERVED_EVT_(t, Q_EMPTY_SIG); } - t = me->temp.fun; /* set to super of t */ + t = me->temp.fun; // set to super of t iq = ip; do { - /* is this LCA? */ + // is this the LCA? if (t == path[iq]) { - /* do not enter LCA */ - ip = (int_fast8_t)(iq - 1); - iq = -1; /* break out of inner loop */ - /* break out of outer loop */ - r = Q_RET_HANDLED; + ip = iq - 1; // do not enter the LCA + iq = -1; // break out of inner loop + r = Q_RET_HANDLED; // break outer loop } else { --iq; @@ -1746,285 +998,51 @@ else { } return ip; - - - /*! Helper function to execute entry into a given state in a -* hierarchical state machine (HSM). -* @private @memberof QHsm -* -* @param[in] state state handler function -* @param[in] qs_id QS-id of this state machine (for QS local filter) -*/ - - - - - #ifdef Q_SPY -if ((*state)(me, &l_reservedEvt_[Q_ENTRY_SIG]) == Q_RET_HANDLED) { - QS_CRIT_STAT_ - QS_BEGIN_PRE_(QS_QEP_STATE_ENTRY, qs_id) - QS_OBJ_PRE_(me); - QS_FUN_PRE_(state); - QS_END_PRE_() -} -#else -Q_UNUSED_PAR(qs_id); -(void)(*state)(me, &l_reservedEvt_[Q_ENTRY_SIG]); -#endif /* Q_SPY */ - - - - /*! Helper function to execute exit from a given state in a -* hierarchical state machine (HSM). -* @private @memberof QHsm -* -* @param[in] state state handler function -* @param[in] qs_id QS-id of this state machine (for QS local filter) -* -* @returns -* 'true' if the exit action has been found in the state and -* 'flase' otherwise. -*/ - - - - - #ifdef Q_SPY -bool isHandled; -if ((*state)(me, &l_reservedEvt_[Q_EXIT_SIG]) == Q_RET_HANDLED) { - QS_CRIT_STAT_ - QS_BEGIN_PRE_(QS_QEP_STATE_EXIT, qs_id) - QS_OBJ_PRE_(me); - QS_FUN_PRE_(state); - QS_END_PRE_() - isHandled = true; -} -else { - isHandled = false; -} -return isHandled; -#else -Q_UNUSED_PAR(qs_id); -return (*state)(me, &l_reservedEvt_[Q_EXIT_SIG]) == Q_RET_HANDLED; -#endif /* Q_SPY */ + + + const + //! @protected @memberof QAsm + +//! @protected @memberof QAsm + + + Q_UNUSED_PAR(me); +Q_UNUSED_PAR(e); +return Q_RET_IGNORED; // the top state ignores all events - - - /*! @brief Virtual table for the ::QHsm class. -* -* @tr{RQP102} -*/ - { - /*! Triggers the top-most initial transition in the HSM. */ - void (*init)(QHsm * const me, void const * const e, - uint_fast8_t const qs_id); - - /*! Dispatches an event to the HSM. */ - void (*dispatch)(QHsm * const me, QEvt const * const e, - uint_fast8_t const qs_id); - -#ifdef Q_SPY - /*! Get the current state handler of the HSM. */ - QStateHandler (*getStateHandler)(QHsm * const me); -#endif /* Q_SPY */ -}; - - - /*! @brief QM state machine implementation strategy -* @class QMsm -* @extends QHsm -* -* @details -* QMsm (QM State Machine) provides a more efficient state machine -* implementation strategy than ::QHsm, but requires the use of the QM -* modeling tool, but are the fastest and need the least run-time -* support (the smallest event-processor taking up the least code space). -* -* @note -* QMsm is not intended to be instantiated directly, but rather serves -* as the abstrace base class for derivation of state machines in the -* application code. -* -* @tr{RQP104} -* -* @usage -* The following example illustrates how to derive a state machine class -* from QMsm. Please note that the QMsm member `super` is defined -* as the *first* member of the derived struct. -* @include qep_qmsm.c -*/ - - - const - /*! Tests if a given state is part of the current active state -* configuration in a MSM. -* @public @memberof QMsm -* -* @details -* Tests if a state machine derived from QMsm is-in a given state. -* -* @note -* For a MSM, to "be-in" a state means also to "be-in" a superstate of -* of the state. -* -* @param[in] me current instance pointer (see @ref oop) -* @param[in] state pointer to the QMState object that corresponds to the -* tested state. -* @returns -* 'true' if the MSM "is in" the `state` and 'false' otherwise -*/ - - - bool inState = false; /* assume that this MSM is not in 'state' */ + + //! @class QMsm +//! @extends QAsm -for (QMState const *s = me->super.state.obj; - s != (QMState *)0; - s = s->superstate) -{ - if (s == state) { - inState = true; /* match found, return 'true' */ - break; - } -} -return inState; - - - - /*! Obtain the current active state from a MSM (read only) -* @public @memberof QMsm -* -* @param[in] me current instance pointer (see @ref oop) -* -* @returns the current active state-object -* -* @note -* This function is used in QM for auto-generating code for state history -*/ - - - return me->state.obj; - - - - /*! Obtain the current active child state of a given parent in ::QMsm -* @public @memberof QMsm -* -* @details -* Finds the child state of the given @c parent, such that this child state -* is an ancestor of the currently active state. The main purpose of this -* function is to support **shallow history** transitions in state machines -* derived from QMsm. -* -* @param[in] me current instance pointer (see @ref oop) -* @param[in] parent pointer to the state-handler object -* -* @returns -* the child of a given @c parent state, which is an ancestor of -* the currently active state. For the corner case when the currently active -* state is the given @c parent state, function returns the @c parent state. -* -* @sa QMsm_childStateObj() -*/ - - - - - QMState const *child = me->state.obj; -bool isFound = false; /* start with the child not found */ -QMState const *s; - -for (s = me->state.obj; s != (QMState *)0; s = s->superstate) { - if (s == parent) { - isFound = true; /* child is found */ - break; - } - else { - child = s; - } -} -if (!isFound) { /* still not found? */ - for (s = me->temp.obj; s != (QMState *)0; s = s->superstate) { - if (s == parent) { - isFound = true; /* child is found */ - break; - } - else { - child = s; - } - } -} - -/*! @post the child must be found */ -Q_ENSURE_ID(810, isFound); - -#ifdef Q_NASSERT -Q_UNUSED_PAR(isFound); -#endif - -return child; /* return the child */ - +Machine-generated State Machine - /*! Constructor of ::QMsm -* @protected @memberof QMsm -* -* @details -* Performs the first step of QMsm initialization by assigning the initial -* pseudostate to the currently active state of the state machine. -* -* @param[in,out] me current instance pointer (see @ref oop) -* @param[in] initial the top-most initial transition for the MSM. -* -* @note -* Must be called only ONCE before QHSM_INIT(). -* -* @note -* QMsm inherits QHsm, so by the @ref oop convention it should call the -* constructor of the superclass, i.e., QHsm_ctor(). However, this would pull -* in the QHsmVtable, which in turn will pull in the code for QHsm_init_() and -* QHsm_dispatch_() implemetations. To avoid this code size penalty, in case -* ::QHsm is not used in a given project, the QMsm_ctor() performs direct -* intitialization of the Vtable, which avoids pulling in the code for QMsm. -* -* @usage -* The following example illustrates how to invoke QMsm_ctor() in the -* "constructor" of a derived state machine: -* @include qep_qmsm_ctor.c -*/ + //! @protected @memberof QMsm + +//! @protected @memberof QMsm - static struct QHsmVtable const vtable = { /* QHsm virtual table */ + static struct QAsmVtable const vtable = { // QAsm virtual table &QMsm_init_, &QMsm_dispatch_ #ifdef Q_SPY ,&QMsm_getStateHandler_ #endif }; -/* do not call the QHsm_ctor() here */ +// do not call the QAsm_ctor() here me->super.vptr = &vtable; -me->super.state.obj = &l_msm_top_s; /* the current state (top) */ -me->super.temp.fun = initial; /* the initial transition handler */ +me->super.state.obj = &l_msm_top_s; // the current state (top) +me->super.temp.fun = initial; // the initial tran. handler - /*! Implementation of the top-most initial tran. in ::QMsm. -* @private @memberof QMsm -* -* @details -* Executes the top-most initial transition in a MSM. -* -* @param[in,out] me current instance pointer (see @ref oop) -* @param[in] e pointer to an extra parameter (might be NULL) -* @param[in] qs_id QS-id of this state machine (for QS local filter) -* -* @note -* This function should be called only via the virtual table (see -* QHSM_INIT()) and should NOT be called directly in the applications. -*/ + //! @private @memberof QMsm + +//! @private @memberof QMsm - + @@ -2033,61 +1051,60 @@ me->super.temp.fun = initial; /* the initial transition handler */ + QS_TIME_PRE_(); // time stamp + QS_OBJ_PRE_(me); // this state machine object + QS_FUN_PRE_(me->state.obj->stateHandler); // the new current state +QS_END_PRE_() +QS_MEM_APP(); +QS_CRIT_EXIT(); + +#ifndef Q_UNSAFE +me->temp.uint = ~me->state.uint; +#endif - /*! Implementation of dispatching events to a ::QMsm -* @private @memberof QMsm -* -* @details -* Dispatches an event for processing to a meta state machine (MSM). -* The processing of an event represents one run-to-completion (RTC) step. -* -* @param[in,out] me current instance pointer (see @ref oop) -* @param[in] e pointer to the event to be dispatched to the MSM -* @param[in] qs_id QS-id of this state machine (for QS local filter) -* -* @note -* This function should be called only via the virtual table (see -* QHSM_DISPATCH()) and should NOT be called directly in the applications. -*/ + //! @private @memberof QMsm + +//! @private @memberof QMsm - + @@ -2096,196 +1113,276 @@ QS_END_PRE_() Q_UNUSED_PAR(qs_id); #endif -QMState const *s = me->state.obj; /* store the current state */ +QMState const *s = me->state.obj; // store the current state QMState const *t = s; -/*! @pre current state must be initialized */ -Q_REQUIRE_ID(300, s != (QMState *)0); +QF_CRIT_STAT +QF_CRIT_ENTRY(); +Q_REQUIRE_INCRIT(300, (s != (QMState *)0) + && (me->state.uint == (uintptr_t)(~me->temp.uint))); +Q_REQUIRE_INCRIT(302, QEvt_verify_(e)); -QS_CRIT_STAT_ +QS_MEM_SYS(); QS_BEGIN_PRE_(QS_QEP_DISPATCH, qs_id) - QS_TIME_PRE_(); /* time stamp */ - QS_SIG_PRE_(e->sig); /* the signal of the event */ - QS_OBJ_PRE_(me); /* this state machine object */ - QS_FUN_PRE_(s->stateHandler); /* the current state handler */ + QS_TIME_PRE_(); // time stamp + QS_SIG_PRE_(e->sig); // the signal of the event + QS_OBJ_PRE_(me); // this state machine object + QS_FUN_PRE_(s->stateHandler); // the current state handler QS_END_PRE_() +QS_MEM_APP(); -/* scan the state hierarchy up to the top state... */ +QF_CRIT_EXIT(); + +// scan the state hierarchy up to the top state... QState r; do { - r = (*t->stateHandler)(me, e); /* call state handler function */ + r = (*t->stateHandler)(me, e); // call state handler function - /* event handled? (the most frequent case) */ + // event handled? (the most frequent case) if (r >= Q_RET_HANDLED) { - break; /* done scanning the state hierarchy */ + break; // done scanning the state hierarchy } - /* event unhandled and passed to the superstate? */ + // event unhandled and passed to the superstate? else if (r == Q_RET_SUPER) { - t = t->superstate; /* advance to the superstate */ + t = t->superstate; // advance to the superstate } - /* event unhandled and passed to a submachine superstate? */ + // event unhandled and passed to a submachine superstate? else if (r == Q_RET_SUPER_SUB) { - t = me->temp.obj; /* current host state of the submachie */ + t = me->temp.obj; // current host state of the submachie } - /* event unhandled due to a guard? */ - else if (r == Q_RET_UNHANDLED) { + else { // event unhandled due to a guard? + QF_CRIT_ENTRY(); + // event must be unhandled due to a guard evaluating to 'false' + Q_ASSERT_INCRIT(310, r == Q_RET_UNHANDLED); + QS_MEM_SYS(); QS_BEGIN_PRE_(QS_QEP_UNHANDLED, qs_id) - QS_SIG_PRE_(e->sig); /* the signal of the event */ - QS_OBJ_PRE_(me); /* this state machine object */ - QS_FUN_PRE_(t->stateHandler); /* the current state */ + QS_SIG_PRE_(e->sig); // the signal of the event + QS_OBJ_PRE_(me); // this state machine object + QS_FUN_PRE_(t->stateHandler); // the current state QS_END_PRE_() + QS_MEM_APP(); - t = t->superstate; /* advance to the superstate */ - } - else { - /* no other return value should be produced */ - Q_ERROR_ID(310); + QF_CRIT_EXIT(); + + t = t->superstate; // advance to the superstate } } while (t != (QMState *)0); - -/* any kind of transition taken? */ -if (r >= Q_RET_TRAN) { +if (r >= Q_RET_TRAN) { // any kind of tran. taken? #ifdef Q_SPY - QMState const * const ts = t; /* transition source for QS tracing */ + QMState const * const ts = t; // tran. source for QS tracing - /* the transition source state must not be NULL */ - Q_ASSERT_ID(320, ts != (QMState *)0); -#endif /* Q_SPY */ + QF_CRIT_ENTRY(); + // the tran. source state must not be NULL + Q_ASSERT_INCRIT(320, ts != (QMState *)0); + QF_CRIT_EXIT(); +#endif // Q_SPY do { - /* save the transition-action table before it gets clobbered */ + // save the tran-action table before it gets clobbered struct QMTranActTable const * const tatbl = me->temp.tatbl; - union QHsmAttr tmp; /* temporary to save intermediate values */ + union QAsmAttr tmp; // temporary to save intermediate values - /* was TRAN, TRAN_INIT, or TRAN_EP taken? */ + // was TRAN, TRAN_INIT, or TRAN_EP taken? if (r <= Q_RET_TRAN_EP) { - me->temp.obj = (QMState *)0; /* clear */ + me->temp.obj = (QMState *)0; // clear QMsm_exitToTranSource_(me, s, t, qs_id); r = QMsm_execTatbl_(me, tatbl, qs_id); s = me->state.obj; } - /* was a transition segment to history taken? */ + // was a tran. segment to history taken? else if (r == Q_RET_TRAN_HIST) { - tmp.obj = me->state.obj; /* save history */ - me->state.obj = s; /* restore the original state */ + tmp.obj = me->state.obj; // save history + me->state.obj = s; // restore the original state QMsm_exitToTranSource_(me, s, t, qs_id); (void)QMsm_execTatbl_(me, tatbl, qs_id); r = QMsm_enterHistory_(me, tmp.obj, qs_id); s = me->state.obj; } - /* was a transition segment to an exit point taken? */ - else if (r == Q_RET_TRAN_XP) { - tmp.act = me->state.act; /* save XP action */ - me->state.obj = s; /* restore the original state */ - r = (*tmp.act)(me); /* execute the XP action */ - if (r == Q_RET_TRAN) { /* XP -> TRAN ? */ - tmp.tatbl = me->temp.tatbl; /* save me->temp */ + else { + QF_CRIT_ENTRY(); + // must be tran. to exit point + Q_ASSERT_INCRIT(340, r == Q_RET_TRAN_XP); + QF_CRIT_EXIT(); + + tmp.act = me->state.act; // save XP action + me->state.obj = s; // restore the original state + r = (*tmp.act)(me); // execute the XP action + if (r == Q_RET_TRAN) { // XP -> TRAN ? +#ifdef Q_SPY + tmp.tatbl = me->temp.tatbl; // save me->temp +#endif // Q_SPY QMsm_exitToTranSource_(me, s, t, qs_id); - /* take the tran-to-XP segment inside submachine */ + // take the tran-to-XP segment inside submachine (void)QMsm_execTatbl_(me, tatbl, qs_id); s = me->state.obj; #ifdef Q_SPY - me->temp.tatbl = tmp.tatbl; /* restore me->temp */ -#endif /* Q_SPY */ + me->temp.tatbl = tmp.tatbl; // restore me->temp +#endif // Q_SPY } - else if (r == Q_RET_TRAN_HIST) { /* XP -> HIST ? */ - tmp.obj = me->state.obj; /* save the history */ - me->state.obj = s; /* restore the original state */ - s = me->temp.obj; /* save me->temp */ + else if (r == Q_RET_TRAN_HIST) { // XP -> HIST ? + tmp.obj = me->state.obj; // save the history + me->state.obj = s; // restore the original state + s = me->temp.obj; // save me->temp QMsm_exitToTranSource_(me, me->state.obj, t, qs_id); - /* take the tran-to-XP segment inside submachine */ + // take the tran-to-XP segment inside submachine (void)QMsm_execTatbl_(me, tatbl, qs_id); #ifdef Q_SPY - me->temp.obj = s; /* restore me->temp */ -#endif /* Q_SPY */ + me->temp.obj = s; // restore me->temp +#endif // Q_SPY s = me->state.obj; - me->state.obj = tmp.obj; /* restore the history */ + me->state.obj = tmp.obj; // restore the history } else { - /* TRAN_XP must NOT be followed by any other tran type */ - Q_ASSERT_ID(330, r < Q_RET_TRAN); + QF_CRIT_ENTRY(); + // TRAN_XP must NOT be followed by any other tran type + Q_ASSERT_INCRIT(330, r < Q_RET_TRAN); + QF_CRIT_EXIT(); } } - else { - /* no other return value should be produced */ - Q_ERROR_ID(340); - } - t = s; /* set target to the current state */ + t = s; // set target to the current state } while (r >= Q_RET_TRAN); + QS_CRIT_ENTRY(); + QS_MEM_SYS(); QS_BEGIN_PRE_(QS_QEP_TRAN, qs_id) - QS_TIME_PRE_(); /* time stamp */ - QS_SIG_PRE_(e->sig); /* the signal of the event */ - QS_OBJ_PRE_(me); /* this state machine object */ - QS_FUN_PRE_(ts->stateHandler); /* the transition source */ - QS_FUN_PRE_(s->stateHandler); /* the new active state */ + QS_TIME_PRE_(); // time stamp + QS_SIG_PRE_(e->sig); // the signal of the event + QS_OBJ_PRE_(me); // this state machine object + QS_FUN_PRE_(ts->stateHandler); // the tran. source + QS_FUN_PRE_(s->stateHandler); // the new active state QS_END_PRE_() + QS_MEM_APP(); + QS_CRIT_EXIT(); } #ifdef Q_SPY -/* was the event handled? */ +// was the event handled? else if (r == Q_RET_HANDLED) { - /* internal tran. source can't be NULL */ - Q_ASSERT_ID(340, t != (QMState *)0); + QF_CRIT_ENTRY(); + // internal tran. source can't be NULL + Q_ASSERT_INCRIT(340, t != (QMState *)0); + QS_MEM_SYS(); QS_BEGIN_PRE_(QS_QEP_INTERN_TRAN, qs_id) - QS_TIME_PRE_(); /* time stamp */ - QS_SIG_PRE_(e->sig); /* the signal of the event */ - QS_OBJ_PRE_(me); /* this state machine object */ - QS_FUN_PRE_(t->stateHandler); /* the source state */ + QS_TIME_PRE_(); // time stamp + QS_SIG_PRE_(e->sig); // the signal of the event + QS_OBJ_PRE_(me); // this state machine object + QS_FUN_PRE_(t->stateHandler); // the source state QS_END_PRE_() + QS_MEM_APP(); + QF_CRIT_EXIT(); } -/* event bubbled to the 'top' state? */ +// event bubbled to the 'top' state? else if (t == (QMState *)0) { - + QS_CRIT_ENTRY(); + QS_MEM_SYS(); QS_BEGIN_PRE_(QS_QEP_IGNORED, qs_id) - QS_TIME_PRE_(); /* time stamp */ - QS_SIG_PRE_(e->sig); /* the signal of the event */ - QS_OBJ_PRE_(me); /* this state machine object */ - QS_FUN_PRE_(s->stateHandler); /* the current state */ + QS_TIME_PRE_(); // time stamp + QS_SIG_PRE_(e->sig); // the signal of the event + QS_OBJ_PRE_(me); // this state machine object + QS_FUN_PRE_(s->stateHandler); // the current state QS_END_PRE_() - + QS_MEM_APP(); + QS_CRIT_EXIT(); } -#endif /* Q_SPY */ +#endif // Q_SPY else { - /* empty */ -} + // empty +} + +#ifndef Q_UNSAFE +me->temp.uint = ~me->state.uint; +#endif - - /*! Implementation of getting the state handler in a ::QMsm subclass -* @public @memberof QMsm -*/ + + //! @public @memberof QMsm + +//! @public @memberof QMsm - + return me->state.obj->stateHandler; + + + const + //! @public @memberof QMsm + +//! @public @memberof QMsm + + + bool inState = false; // assume that this SM is not in 'state' + +for (QMState const *s = me->super.state.obj; + s != (QMState *)0; + s = s->superstate) +{ + if (s == stateObj) { + inState = true; // match found, return 'true' + break; + } +} +return inState; + + + + //! @public @memberof QMsm + +//! @public @memberof QMsm + return me->super.state.obj; + + + + const + //! @public @memberof QMsm + +//! @public @memberof QMsm + + + QMState const *child = me->super.state.obj; +bool isFound = false; // start with the child not found +QMState const *s; + +for (s = me->super.state.obj; s != (QMState *)0; s = s->superstate) { + if (s == parent) { + isFound = true; // child is found + break; + } + else { + child = s; + } +} +if (!isFound) { // still not found? + for (s = me->super.temp.obj; s != (QMState *)0; s = s->superstate) { + if (s == parent) { + isFound = true; // child is found + break; + } + else { + child = s; + } + } +} + +QF_CRIT_STAT +QF_CRIT_ENTRY(); +Q_ASSERT_INCRIT(890, isFound); +QF_CRIT_EXIT(); + +return child; // return the child + - /*! Execute transition-action table -* @private @memberof QMsm -* -* @details -* Helper function to execute transition sequence in a transition-action table. -* -* @param[in,out] me current instance pointer (see @ref oop) -* @param[in] tatbl pointer to the transition-action table -* @param[in] qs_id QS-id of this state machine (for QS local filter) -* -* @returns -* status of the last action from the transition-action table. -* -* @note -* This function is for internal use inside the QEP event processor and -* should **not** be called directly from the applications. -*/ + //! @private @memberof QMsm + +//! @private @memberof QMsm - + @@ -2294,60 +1391,61 @@ else { Q_UNUSED_PAR(qs_id); #endif +QF_CRIT_STAT +QF_CRIT_ENTRY(); +// precondition: +// - the tran-action table pointer must not be NULL +Q_REQUIRE_INCRIT(400, tatbl != (struct QMTranActTable *)0); +QF_CRIT_EXIT(); + QState r = Q_RET_NULL; -QS_CRIT_STAT_ - -/*! @pre the transition-action table pointer must not be NULL */ -Q_REQUIRE_ID(400, tatbl != (struct QMTranActTable *)0); - for (QActionHandler const *a = &tatbl->act[0]; *a != Q_ACTION_CAST(0); ++a) { - r = (*(*a))(me); /* call the action through the 'a' pointer */ + r = (*(*a))(me); // call the action through the 'a' pointer #ifdef Q_SPY + QS_CRIT_ENTRY(); + QS_MEM_SYS(); if (r == Q_RET_ENTRY) { - QS_BEGIN_PRE_(QS_QEP_STATE_ENTRY, qs_id) - QS_OBJ_PRE_(me); /* this state machine object */ - QS_FUN_PRE_(me->temp.obj->stateHandler);/*entered state */ + QS_OBJ_PRE_(me); // this state machine object + QS_FUN_PRE_(me->temp.obj->stateHandler); // entered state QS_END_PRE_() } else if (r == Q_RET_EXIT) { - QS_BEGIN_PRE_(QS_QEP_STATE_EXIT, qs_id) - QS_OBJ_PRE_(me); /* this state machine object */ - QS_FUN_PRE_(me->temp.obj->stateHandler); /* exited state */ + QS_OBJ_PRE_(me); // this state machine object + QS_FUN_PRE_(me->temp.obj->stateHandler); // exited state QS_END_PRE_() } else if (r == Q_RET_TRAN_INIT) { - QS_BEGIN_PRE_(QS_QEP_STATE_INIT, qs_id) - QS_OBJ_PRE_(me); /* this state machine object */ - QS_FUN_PRE_(tatbl->target->stateHandler); /* source */ - QS_FUN_PRE_(me->temp.tatbl->target->stateHandler);/* target */ + QS_OBJ_PRE_(me); // this state machine object + QS_FUN_PRE_(tatbl->target->stateHandler); // source + QS_FUN_PRE_(me->temp.tatbl->target->stateHandler); // target QS_END_PRE_() } else if (r == Q_RET_TRAN_EP) { - QS_BEGIN_PRE_(QS_QEP_TRAN_EP, qs_id) - QS_OBJ_PRE_(me); /* this state machine object */ - QS_FUN_PRE_(tatbl->target->stateHandler); /* source */ - QS_FUN_PRE_(me->temp.tatbl->target->stateHandler);/* target */ + QS_OBJ_PRE_(me); // this state machine object + QS_FUN_PRE_(tatbl->target->stateHandler); // source + QS_FUN_PRE_(me->temp.tatbl->target->stateHandler); // target QS_END_PRE_() } else if (r == Q_RET_TRAN_XP) { - QS_BEGIN_PRE_(QS_QEP_TRAN_XP, qs_id) - QS_OBJ_PRE_(me); /* this state machine object */ - QS_FUN_PRE_(tatbl->target->stateHandler); /* source */ - QS_FUN_PRE_(me->temp.tatbl->target->stateHandler);/* target */ + QS_OBJ_PRE_(me); // this state machine object + QS_FUN_PRE_(tatbl->target->stateHandler); // source + QS_FUN_PRE_(me->temp.tatbl->target->stateHandler); // target QS_END_PRE_() } else { - /* empty */ + // empty } -#endif /* Q_SPY */ + QS_MEM_APP(); + QS_CRIT_EXIT(); +#endif // Q_SPY } me->state.obj = (r >= Q_RET_TRAN) @@ -2357,21 +1455,11 @@ return r; - /*! Exit the current state up to the explicit transition source -* @private @memberof QMsm -* -* @details -* Static helper function to exit the current state configuration to the -* transition source, which in a hierarchical state machine might be a -* superstate of the current state. -* -* @param[in,out] me current instance pointer (see @ref oop) -* @param[in] cs pointer to the current state -* @param[in] ts pointer to the transition source state -* @param[in] qs_id QS-id of this state machine (for QS local filter) -*/ + //! @private @memberof QMsm + +//! @private @memberof QMsm - + @@ -2382,48 +1470,43 @@ return r; Q_UNUSED_PAR(qs_id); #endif -/* exit states from the current state to the tran. source state */ +QF_CRIT_STAT + +// exit states from the current state to the tran. source state QMState const *s = cs; while (s != ts) { - /* exit action provided in state 's'? */ + // exit action provided in state 's'? if (s->exitAction != Q_ACTION_CAST(0)) { - QS_CRIT_STAT_ - - (void)(*s->exitAction)(me); /* execute the exit action */ + // execute the exit action + (void)(*s->exitAction)(me); + QS_CRIT_ENTRY(); + QS_MEM_SYS(); QS_BEGIN_PRE_(QS_QEP_STATE_EXIT, qs_id) - QS_OBJ_PRE_(me); /* this state machine object */ - QS_FUN_PRE_(s->stateHandler); /* the exited state handler */ + QS_OBJ_PRE_(me); // this state machine object + QS_FUN_PRE_(s->stateHandler); // the exited state handler QS_END_PRE_() + QS_MEM_APP(); + QS_CRIT_EXIT(); } - s = s->superstate; /* advance to the superstate */ + s = s->superstate; // advance to the superstate - if (s == (QMState *)0) { /* reached the top of a submachine? */ - s = me->temp.obj; /* the superstate from QM_SM_EXIT() */ - Q_ASSERT_ID(510, s != (QMState *)0); /* must be valid */ + if (s == (QMState *)0) { // reached the top of a submachine? + s = me->temp.obj; // the superstate from QM_SM_EXIT() + QF_CRIT_ENTRY(); + Q_ASSERT_INCRIT(510, s != (QMState *)0); // must be valid + QF_CRIT_EXIT(); } } - /*! Enter history of a composite state -* @private @memberof QMsm -* -* @details -* Static helper function to execute the segment of transition to history -* after entering the composite state and -* -* @param[in,out] me current instance pointer (see @ref oop) -* @param[in] hist pointer to the history substate -* @param[in] qs_id QS-id of this state machine (for QS local filter) -* -* @returns -* #Q_RET_TRAN_INIT, if an initial transition has been executed in the last -* entered state or #Q_RET_NULL if no such transition was taken. -*/ + //! @private @memberof QMsm + +//! @private @memberof QMsm - + @@ -2433,349 +1516,2814 @@ Q_UNUSED_PAR(qs_id); #endif QMState const *s = hist; -QMState const *ts = me->state.obj; /* transition source */ +QMState const *ts = me->state.obj; // tran. source QMState const *epath[QMSM_MAX_ENTRY_DEPTH_]; -QS_CRIT_STAT_ +QF_CRIT_STAT + +QS_CRIT_ENTRY(); +QS_MEM_SYS(); QS_BEGIN_PRE_(QS_QEP_TRAN_HIST, qs_id) - QS_OBJ_PRE_(me); /* this state machine object */ - QS_FUN_PRE_(ts->stateHandler); /* source state handler */ - QS_FUN_PRE_(hist->stateHandler); /* target state handler */ + QS_OBJ_PRE_(me); // this state machine object + QS_FUN_PRE_(ts->stateHandler); // source state handler + QS_FUN_PRE_(hist->stateHandler); // target state handler QS_END_PRE_() +QS_MEM_APP(); +QS_CRIT_EXIT(); -int_fast8_t i = 0; /* transition entry path index */ +int_fast8_t i = 0; // tran. entry path index while (s != ts) { if (s->entryAction != Q_ACTION_CAST(0)) { - Q_ASSERT_ID(620, i < QMSM_MAX_ENTRY_DEPTH_); + QF_CRIT_ENTRY(); + Q_ASSERT_INCRIT(620, i < QMSM_MAX_ENTRY_DEPTH_); + QF_CRIT_EXIT(); epath[i] = s; ++i; } s = s->superstate; if (s == (QMState *)0) { - ts = s; /* force exit from the for-loop */ + ts = s; // force exit from the for-loop } } -/* retrace the entry path in reverse (desired) order... */ +// retrace the entry path in reverse (desired) order... while (i > 0) { --i; - (void)(*epath[i]->entryAction)(me); /* run entry action in epath[i] */ + (void)(*epath[i]->entryAction)(me); // run entry action in epath[i] + QS_CRIT_ENTRY(); + QS_MEM_SYS(); QS_BEGIN_PRE_(QS_QEP_STATE_ENTRY, qs_id) QS_OBJ_PRE_(me); - QS_FUN_PRE_(epath[i]->stateHandler); /* entered state handler */ + QS_FUN_PRE_(epath[i]->stateHandler); // entered state handler QS_END_PRE_() + QS_MEM_APP(); + QS_CRIT_EXIT(); } -me->state.obj = hist; /* set current state to the transition target */ +me->state.obj = hist; // set current state to the tran. target -/* initial tran. present? */ +// initial tran. present? QState r; if (hist->initAction != Q_ACTION_CAST(0)) { - r = (*hist->initAction)(me); /* execute the transition action */ + r = (*hist->initAction)(me); // execute the tran. action } else { r = Q_RET_NULL; } + return r; - - - - - /*! Maximum number of active objects (configurable value in qf_port.h) -* Valid values: [1U..64U]; default 32U -*/ - 32U + + + + + + + { (QSignal)(sig_), 0U, QEVT_MARKER } + + + + + + + + + + do { \ + Q_ASSERT(((QAsm *)(me_))->vptr); \ + (*((QAsm *)(me_))->vptr->init)((QAsm *)(me_), (par_), (qs_id_)); \ +} while (false) + + + + + + + + + + do { \ + Q_ASSERT(((QAsm *)(me_))->vptr); \ + (*((QAsm *)(me_))->vptr->init)((QAsm *)(me_), (par_), 0); \ +} while (false) + + + + + + + + + + \ + (*((QAsm *)(me_))->vptr->dispatch)((QAsm *)(me_), (e_), (qs_id_)) + + + + + + + + + + \ + (*((QAsm *)(me_))->vptr->dispatch)((QAsm *)(me_), (e_), 0U) + + + + + + ((QAsm *)(ptr_)) + + + + + + ((QHsm *)(ptr_)) + + + + + + ((QMsm *)(ptr_)) + + + + + + \ + ((Q_ASM_UPCAST(me))->temp.fun = Q_STATE_CAST(target_), \ + (QState)Q_RET_TRAN) + + + + + + \ + ((Q_ASM_UPCAST(me))->temp.fun = (hist_), \ + (QState)Q_RET_TRAN_HIST) + + + + + + \ + ((Q_ASM_UPCAST(me))->temp.fun = Q_STATE_CAST(super_), \ + (QState)Q_RET_SUPER) + + + + ((QState)Q_RET_HANDLED) + + + + ((QState)Q_RET_UNHANDLED) + + + + / + ((QActionHandler)0) - - - - - /*! Maximum number of clock rates (configurable value in qf_port.h) -* Valid values: [0U..15U]; default 1U -*/ - 1U + + + + + ((class_ const *)(e)) + + + + + + ((QStateHandler)(handler_)) + + + + + + ((QActionHandler)(action_)) + + + + + + ((void)(par_)) + + + + + + (sizeof(array_) / sizeof((array_)[0U])) + + + + + + + + ((type_ *)(uint_)) + + + + + + \ + ((Q_ASM_UPCAST(me))->temp.obj = (state_), \ + (QState)Q_RET_ENTRY) + + + + + + ((QState)Q_RET_ENTRY) + + + + + + \ + ((Q_ASM_UPCAST(me))->temp.obj = (state_), \ + (QState)Q_RET_EXIT) + + + + + + ((QState)Q_RET_EXIT) + + + + + + \ + ((Q_ASM_UPCAST(me))->temp.obj = (state_), \ + (QState)Q_RET_EXIT) + + + + + + ((Q_ASM_UPCAST(me))->temp.tatbl \ + = (struct QMTranActTable const *)(tatbl_), \ + (QState)Q_RET_TRAN) + + + + + + ((Q_ASM_UPCAST(me))->temp.tatbl \ + = (struct QMTranActTable const *)(tatbl_), \ + (QState)Q_RET_TRAN_INIT) + + + + + + + + \ + ((((Q_ASM_UPCAST(me))->state.obj = (history_)), \ + ((Q_ASM_UPCAST(me))->temp.tatbl = \ + (struct QMTranActTable const *)(tatbl_))), \ + (QState)Q_RET_TRAN_HIST) + + + + + + ((Q_ASM_UPCAST(me))->temp.tatbl \ + = (struct QMTranActTable const *)(tatbl_), \ + (QState)Q_RET_TRAN_EP) + + + + + + + + \ + ((((Q_ASM_UPCAST(me))->state.act = (xp_)), \ + ((Q_ASM_UPCAST(me))->temp.tatbl = \ + (struct QMTranActTable const *)(tatbl_))), \ + (QState)Q_RET_TRAN_XP) + + + + ((QState)Q_RET_HANDLED) + + + + ((QState)Q_RET_UNHANDLED) + + + + ((QState)Q_RET_SUPER) + + + + + + \ + ((Q_ASM_UPCAST(me))->temp.obj = (host_), \ + (QState)Q_RET_SUPER_SUB) + + + + ((QMState *)0) - - - - - /*! Maximum number of event pools (configurable value in qf_port.h) -* Valid values: [0U..15U]; default 3U -* -* @note -* #QF_MAX_EPOOL set to zero means that dynamic events are NOT configured -* and should not be used in the application. -*/ - 3U - - - - - - /*! Size of the QTimeEvt counter (configurable value in qf_port.h) -* Valid values: 1U, 2U, or 4U; default 4U -*/ - 4U - - - - - - /*! Size of the event-size (configurable value in qf_port.h) -* Valid values: 1U, 2U, or 4U; default 2U -*/ - 2U - - - - - - - - /*! bitmask for the internal representation of QPSet elements */ + + + + + // @class QF + { + //! @cond INTERNAL + uint8_t dummy; + //! @endcond +} QV; - - - - - - - /*! Data type to store the block-size defined based on the macro -* #QF_TIMEEVT_CTR_SIZE. -* -* @details -* The dynamic range of this data type determines the maximum block -* size that can be managed by the pool. -*/ - - - - - - - - const - /*! Log-base-2 calculation when hardware acceleration -* is NOT provided (#QF_LOG2 not defined). -*/ - - - static uint8_t const log2LUT[16] = { + + + + + + + + + + + + + + + + + + + const + + + static uint8_t const log2LUT[16] = { 0U, 1U, 2U, 2U, 3U, 3U, 3U, 3U, 4U, 4U, 4U, 4U, 4U, 4U, 4U, 4U }; uint_fast8_t n = 0U; -QPSetBits t; +QPSetBits tmp; +QPSetBits x = bitmask; #if (QF_MAX_ACTIVE > 16U) -t = (QPSetBits)(x >> 16U); -if (t != 0U) { +tmp = (x >> 16U); +if (tmp != 0U) { n += 16U; - x = t; + x = tmp; } #endif #if (QF_MAX_ACTIVE > 8U) -t = (x >> 8U); -if (t != 0U) { +tmp = (x >> 8U); +if (tmp != 0U) { n += 8U; - x = t; + x = tmp; } #endif -t = (x >> 4U); -if (t != 0U) { +tmp = (x >> 4U); +if (tmp != 0U) { n += 4U; - x = t; + x = tmp; } return n + log2LUT[x]; - - - - /*! Priority specification for Active Objects in QP -* -* @details -* Active Object priorities in QP are integer numbers in the range -* [1..#QF_MAX_ACTIVE], whereas the special priority number 0 is reserved -* for the lowest-priority idle thread. The QP framework uses the *direct* -* priority numbering, in which higher numerical values denote higher urgency. -* For example, an AO with priority 32 has higher urgency than an AO with -* priority 23. -* -* ::QPrioSpec allows an application developer to assign **two** -* priorities to a given AO (see also Q_PRIO()): -* -* 1. The "QF-priority", which resides in the least-significant byte -* of the ::QPrioSpec data type. The "QF-priority" must be **unique** -* for each thread in the system and higher numerical values represent -* higher urgency (direct pirority numbering). -* -* 2. The "preemption-threshold" priority, which resides in the most- -* significant byte of the ::QPrioSpec data type. The second priority -* cannot be lower than the "QF-priority", but does NOT need to be -* unuque. -* -* In the QP native preemptive kernels, like QK and QXK, the "preemption- -* threshold" priority is used as to implement the "preemption-threshold -* scheduling" (PTS). It determines the conditions under which a given -* thread can be *preempted* by other threads. Specifically, a given -* thread can be preempted only by another thread with a *higher* -* priority than the "preemption-threshold" of the original thread. -* -* ![QF-priority and preemption-threshold relations](qp-prio.png) -* -* @note -* For backwards-compatibility, ::QPrioSpec data type might contain only -* the "QF-priority" component (and the "preemption-threshold" component -* left at zero). In that case, the "preemption-threshold" will be assumed -* to be the same as the "QF-priority". This corresponds exactly to the -* previous semantics of AO priority. -* -* @remark -* When QP runs on top of 3rd-party kernels/RTOSes or general-purpose -* operating systems, sthe second priority can have different meaning, -* depending on the specific RTOS/GPOS used. -*/ - - - - /*! The scheduler lock status used in some real-time kernels */ - - - - /*! @brief Priority Set of up to #QF_MAX_ACTIVE elements -* @class QPSet -* -* @details -* The priority set represents the set of active objects that are ready to -* run and need to be considered by the scheduling algorithm. The set is -* capable of storing up to #QF_MAX_ACTIVE priority levels, which can be -* configured in the rage 1..64, inclusive. -*/ - - - /*! bitmask with a bit for each element */ + + + + //! @class QPSet + + + //! @private @memberof QPSet + + + + //! @public @memberof QPSet + +//! @public @memberof QPSet + me->bits[0] = 0U; +#if (QF_MAX_ACTIVE > 32) +me->bits[1] = 0U; +#endif + + + + const + //! @public @memberof QPSet + +//! @public @memberof QPSet + #if (QF_MAX_ACTIVE <= 32U) +return (me->bits[0] == 0U); +#else +return (me->bits[0] == 0U) ? (me->bits[1] == 0U) : false; +#endif + + + + const + //! @public @memberof QPSet + +//! @public @memberof QPSet + #if (QF_MAX_ACTIVE <= 32U) +return (me->bits[0] != 0U); +#else +return (me->bits[0] != 0U) ? true : (me->bits[1] != 0U); +#endif + + + + const + //! @public @memberof QPSet + +//! @public @memberof QPSet + + + #if (QF_MAX_ACTIVE <= 32U) +return (me->bits[0] & ((QPSetBits)1U << (n - 1U))) != 0U; +#else +return (n <= 32U) + ? ((me->bits[0] & ((QPSetBits)1U << (n - 1U))) != 0U) + : ((me->bits[1] & ((QPSetBits)1U << (n - 33U))) != 0U); +#endif + + + + //! @public @memberof QPSet + +//! @public @memberof QPSet + + + #if (QF_MAX_ACTIVE <= 32U) +me->bits[0] = (me->bits[0] | ((QPSetBits)1U << (n - 1U))); +#else +if (n <= 32U) { + me->bits[0] = (me->bits[0] | ((QPSetBits)1U << (n - 1U))); +} +else { + me->bits[1] = (me->bits[1] | ((QPSetBits)1U << (n - 33U))); +} +#endif + + + + //! @public @memberof QPSet + +//! @public @memberof QPSet + + + #if (QF_MAX_ACTIVE <= 32U) +me->bits[0] = (me->bits[0] & (QPSetBits)(~((QPSetBits)1U << (n - 1U)))); +#else +if (n <= 32U) { + (me->bits[0] = (me->bits[0] & ~((QPSetBits)1U << (n - 1U)))); +} +else { + (me->bits[1] = (me->bits[1] & ~((QPSetBits)1U << (n - 33U)))); +} +#endif + + + + const + //! @public @memberof QPSet + +//! @public @memberof QPSet + #if (QF_MAX_ACTIVE <= 32U) +return QF_LOG2(me->bits[0]); +#else +return (me->bits[1] != 0U) + ? (QF_LOG2(me->bits[1]) + 32U) + : (QF_LOG2(me->bits[0])); +#endif + + + + const + //! @private @memberof QPSet + +//! @private @memberof QPSet + + + dis->bits[0] = ~me->bits[0]; +#if (QF_MAX_ACTIVE > 32U) +dis->bits[1] = ~me->bits[1]; +#endif + + + + const + //! @private @memberof QPSet + +//! @private @memberof QPSet + + + #if (QF_MAX_ACTIVE <= 32U) +return me->bits[0] == (QPSetBits)(~dis->bits[0]); +#else +return (me->bits[0] == (QPSetBits)(~dis->bits[0])) + && (me->bits[1] == (QPSetBits)(~dis->bits[1])); +#endif + + + + + // @struct QSubscrList + + + //! @private @memberof QSubscrList + + + + //! @private @memberof QSubscrList + + + + + + + + //! @class QActive +//! @extends QAsm + + + //! @private @memberof QActive - - - /*! bitmasks with a bit for each element */ + + + //! @private @memberof QActive - - - /*! Make the priority set empty */ - #if (QF_MAX_ACTIVE <= 32) - me->bits = 0U; -#else - me->bits[0] = 0U; - me->bits[1] = 0U; -#endif + + + //! @private @memberof QActive + + + + //! @private @memberof QActive + + + + //! @private @memberof QActive + + + + //! @static @private @memberof QActive + + + + //! @static @private @memberof QActive + + + + //! @static @private @memberof QActive + + + + //! @protected @memberof QActive + +//! @protected @memberof QActive + + + // clear the whole QActive object, so that the framework can start +// correctly even if the startup code fails to clear the uninitialized +// data (as is required by the C Standard). +QF_bzero_(me, sizeof(*me)); + +// NOTE: QActive inherits the abstract QAsm class, but it calls the +// constructor of the QHsm subclass. This is because QActive inherits +// the behavior from the QHsm subclass. +QHsm_ctor((QHsm *)(me), initial); + +// NOTE: this vtable is identical as QHsm, but is provided +// for the QActive subclass to provide a UNIQUE vptr to distinguish +// subclasses of QActive (e.g., in the debugger). +static struct QAsmVtable const vtable = { // QActive virtual table + &QHsm_init_, + &QHsm_dispatch_ +#ifdef Q_SPY + ,&QHsm_getStateHandler_ +#endif +}; +me->super.vptr = &vtable; // hook vptr to QActive vtable - - - const - /*! Return 'true' if the priority set is empty */ - #if (QF_MAX_ACTIVE <= 32) - return (me->bits == 0U); -#else - return (me->bits[0] == 0U) ? (me->bits[1] == 0U) : false; -#endif + + + //! @public @memberof QActive + +//! @public @memberof QActive + + + + - - - const - /*! Return 'true' if the priority set is NOT empty */ - #if (QF_MAX_ACTIVE <= 32) - return (me->bits != 0U); -#else - return (me->bits[0] != 0U) ? true : (me->bits[1] != 0U); -#endif + + + //! @private @memberof QActive + +//! @private @memberof QActive + + + + + + + + + + + + - - - const - /*! Return 'true' if the priority set has the element n. */ - - - #if (QF_MAX_ACTIVE <= 32U) - return (me->bits & (1U << (n - 1U))) != 0U; -#else - return (n <= 32U) - ? ((me->bits[0] & ((uint32_t)1U << (n - 1U))) != 0U) - : ((me->bits[1] & ((uint32_t)1U << (n - 33U))) != 0U); -#endif + + + //! @protected @memberof QActive + +//! @protected @memberof QActive - - - /*! insert element `n` into the set (n = 1..::QF_MAX_ACTIVE) */ - - - #if (QF_MAX_ACTIVE <= 32U) - me->bits = (me->bits | (1U << (n - 1U))); -#else - if (n <= 32U) { - me->bits[0] = (me->bits[0] | ((uint32_t)1U << (n - 1U))); + + + //! @private @memberof QActive + +//! @private @memberof QActive + QF_CRIT_STAT +QF_CRIT_ENTRY(); +QF_MEM_SYS(); + +if (me->pthre == 0U) { // preemption-threshold not defined? + me->pthre = me->prio; // apply the default +} + +#ifndef Q_UNSAFE + +Q_REQUIRE_INCRIT(100, (0U < me->prio) && (me->prio <= QF_MAX_ACTIVE) + && (QActive_registry_[me->prio] == (QActive *)0) + && (me->prio <= me->pthre)); + +uint8_t prev_thre = me->pthre; +uint8_t next_thre = me->pthre; + +uint_fast8_t p; +for (p = (uint_fast8_t)me->prio - 1U; p > 0U; --p) { + if (QActive_registry_[p] != (QActive *)0) { + prev_thre = QActive_registry_[p]->pthre; + break; + } +} +for (p = (uint_fast8_t)me->prio + 1U; p <= QF_MAX_ACTIVE; ++p) { + if (QActive_registry_[p] != (QActive *)0) { + next_thre = QActive_registry_[p]->pthre; + break; + } +} + +Q_ASSERT_INCRIT(190, (prev_thre <= me->pthre) + && (me->pthre <= next_thre)); +#endif // Q_UNSAFE + +// register the AO at the QF-prio. +QActive_registry_[me->prio] = me; + +QF_MEM_APP(); +QF_CRIT_EXIT(); + + + + //! @private @memberof QActive + +//! @private @memberof QActive + uint_fast8_t const p = (uint_fast8_t)me->prio; + +QF_CRIT_STAT +QF_CRIT_ENTRY(); +QF_MEM_SYS(); + +Q_REQUIRE_INCRIT(200, (0U < p) && (p <= QF_MAX_ACTIVE) + && (QActive_registry_[p] == me)); +QActive_registry_[p] = (QActive *)0; // free-up the prio. level +me->super.state.fun = Q_STATE_CAST(0); // invalidate the state + +QF_MEM_APP(); +QF_CRIT_EXIT(); + + + + //! @private @memberof QActive + +//! @private @memberof QActive + + + + + + + #ifndef Q_SPY +Q_UNUSED_PAR(sender); +#endif + +#ifdef Q_UTEST // test? +#if Q_UTEST != 0 // testing QP-stub? +if (me->super.temp.fun == Q_STATE_CAST(0)) { // QActiveDummy? + return QActiveDummy_fakePost_(me, e, margin, sender); +} +#endif +#endif + +QF_CRIT_STAT +QF_CRIT_ENTRY(); +QF_MEM_SYS(); + +Q_REQUIRE_INCRIT(102, QEvt_verify_(e)); + +QEQueueCtr nFree = me->eQueue.nFree; // get volatile into temporary + +// test-probe#1 for faking queue overflow +QS_TEST_PROBE_DEF(&QActive_post_) +QS_TEST_PROBE_ID(1, + nFree = 0U; +) + +bool status; +if (margin == QF_NO_MARGIN) { + if (nFree > 0U) { + status = true; // can post } else { - me->bits[1] = (me->bits[1] | ((uint32_t)1U << (n - 33U))); + status = false; // cannot post + Q_ERROR_INCRIT(190); // must be able to post the event } -#endif - - - - /*! Remove element `n` from the set (n = 1U..::QF_MAX_ACTIVE) */ - - - #if (QF_MAX_ACTIVE <= 32U) - me->bits = (me->bits & - (QPSetBits)(~((QPSetBits)1U << (n - 1U)))); +} +else if (nFree > (QEQueueCtr)margin) { + status = true; // can post +} +else { + status = false; // cannot post, but don't assert +} + +// is it a mutable event? +if (QEvt_getPoolId_(e) != 0U) { + QEvt_refCtr_inc_(e); // increment the reference counter +} + +if (status) { // can post the event? + + --nFree; // one free entry just used up + me->eQueue.nFree = nFree; // update the original + if (me->eQueue.nMin > nFree) { + me->eQueue.nMin = nFree; // increase minimum so far + } + + QS_BEGIN_PRE_(QS_QF_ACTIVE_POST, me->prio) + QS_TIME_PRE_(); // timestamp + QS_OBJ_PRE_(sender); // the sender object + QS_SIG_PRE_(e->sig); // the signal of the event + QS_OBJ_PRE_(me); // this active object (recipient) + QS_2U8_PRE_(QEvt_getPoolId_(e), e->refCtr_); // poolId & refCtr + QS_EQC_PRE_(nFree); // # free entries + QS_EQC_PRE_(me->eQueue.nMin); // min # free entries + QS_END_PRE_() + +#ifdef Q_UTEST + // callback to examine the posted event under the same conditions + // as producing the #QS_QF_ACTIVE_POST trace record, which are: + // the local filter for this AO ('me->prio') is set + if (QS_LOC_CHECK_(me->prio)) { + QS_onTestPost(sender, me, e, status); + } +#endif + + if (me->eQueue.frontEvt == (QEvt *)0) { // empty queue? + me->eQueue.frontEvt = e; // deliver event directly + +#ifdef QXK_H_ + if (me->super.state.act == Q_ACTION_CAST(0)) { // eXtended? + QXTHREAD_EQUEUE_SIGNAL_(me); // signal the event queue + } + else { + QACTIVE_EQUEUE_SIGNAL_(me); // signal the event queue + } #else - if (n <= 32U) { - (me->bits[0] = (me->bits[0] & ~((uint32_t)1U << (n - 1U)))); + QACTIVE_EQUEUE_SIGNAL_(me); // signal the event queue +#endif } + // queue is not empty, insert event into the ring-buffer else { - (me->bits[1] = (me->bits[1] & ~((uint32_t)1U << (n - 33U)))); + // insert event into the ring buffer (FIFO) + me->eQueue.ring[me->eQueue.head] = e; + + if (me->eQueue.head == 0U) { // need to wrap head? + me->eQueue.head = me->eQueue.end; // wrap around + } + --me->eQueue.head; // advance the head (counter clockwise) } + + QF_MEM_APP(); + QF_CRIT_EXIT(); +} +else { // cannot post the event + + QS_BEGIN_PRE_(QS_QF_ACTIVE_POST_ATTEMPT, me->prio) + QS_TIME_PRE_(); // timestamp + QS_OBJ_PRE_(sender); // the sender object + QS_SIG_PRE_(e->sig); // the signal of the event + QS_OBJ_PRE_(me); // this active object (recipient) + QS_2U8_PRE_(QEvt_getPoolId_(e), e->refCtr_); // poolId & refCtr + QS_EQC_PRE_(nFree); // # free entries + QS_EQC_PRE_(margin); // margin requested + QS_END_PRE_() + +#ifdef Q_UTEST + // callback to examine the posted event under the same conditions + // as producing the #QS_QF_ACTIVE_POST trace record, which are: + // the local filter for this AO ('me->prio') is set + if (QS_LOC_CHECK_(me->prio)) { + QS_onTestPost(sender, me, e, status); + } +#endif + + QF_MEM_APP(); + QF_CRIT_EXIT(); + +#if (QF_MAX_EPOOL > 0U) + QF_gc(e); // recycle the event to avoid a leak +#endif +} + +return status; + + + + //! @private @memberof QActive + +//! @private @memberof QActive + + + #ifdef Q_UTEST // test? +#if Q_UTEST != 0 // testing QP-stub? +if (me->super.temp.fun == Q_STATE_CAST(0)) { // QActiveDummy? + QActiveDummy_fakePostLIFO_(me, e); + return; +} +#endif +#endif + +QF_CRIT_STAT +QF_CRIT_ENTRY(); +QF_MEM_SYS(); + +Q_REQUIRE_INCRIT(202, QEvt_verify_(e)); + +#ifdef QXK_H_ +Q_REQUIRE_INCRIT(200, me->super.state.act != Q_ACTION_CAST(0)); +#endif + +QEQueueCtr nFree = me->eQueue.nFree; // get volatile into temporary + +// test-probe#1 for faking queue overflow +QS_TEST_PROBE_DEF(&QActive_postLIFO_) +QS_TEST_PROBE_ID(1, + nFree = 0U; +) + +Q_REQUIRE_INCRIT(201, nFree != 0U); + +if (QEvt_getPoolId_(e) != 0U) { // is it a mutable event? + QEvt_refCtr_inc_(e); // increment the reference counter +} + +--nFree; // one free entry just used up +me->eQueue.nFree = nFree; // update the original +if (me->eQueue.nMin > nFree) { + me->eQueue.nMin = nFree; // update minimum so far +} + +QS_BEGIN_PRE_(QS_QF_ACTIVE_POST_LIFO, me->prio) + QS_TIME_PRE_(); // timestamp + QS_SIG_PRE_(e->sig); // the signal of this event + QS_OBJ_PRE_(me); // this active object + QS_2U8_PRE_(QEvt_getPoolId_(e), e->refCtr_);// poolId & refCtr + QS_EQC_PRE_(nFree); // # free entries + QS_EQC_PRE_(me->eQueue.nMin); // min # free entries +QS_END_PRE_() + +#ifdef Q_UTEST +// callback to examine the posted event under the same conditions +// as producing the #QS_QF_ACTIVE_POST trace record, which are: +// the local filter for this AO ('me->prio') is set +if (QS_LOC_CHECK_(me->prio)) { + QS_onTestPost((QActive *)0, me, e, true); +} +#endif + +QEvt const * const frontEvt = me->eQueue.frontEvt; +me->eQueue.frontEvt = e; // deliver the event directly to the front + +if (frontEvt == (QEvt *)0) { // was the queue empty? + QACTIVE_EQUEUE_SIGNAL_(me); // signal the event queue +} +else { // queue was not empty, leave the event in the ring-buffer + ++me->eQueue.tail; + if (me->eQueue.tail == me->eQueue.end) { // need to wrap the tail? + me->eQueue.tail = 0U; // wrap around + } + + me->eQueue.ring[me->eQueue.tail] = frontEvt; +} + +QF_MEM_APP(); +QF_CRIT_EXIT(); + + + + //! @private @memberof QActive + +//! @private @memberof QActive + QF_CRIT_STAT +QF_CRIT_ENTRY(); +QF_MEM_SYS(); + +QACTIVE_EQUEUE_WAIT_(me); // wait for event to arrive directly + +// always remove event from the front +QEvt const * const e = me->eQueue.frontEvt; +QEQueueCtr const nFree = me->eQueue.nFree + 1U; // get volatile into tmp +me->eQueue.nFree = nFree; // update the # free + +if (nFree <= me->eQueue.end) { // any events in the ring buffer? + // remove event from the tail + me->eQueue.frontEvt = me->eQueue.ring[me->eQueue.tail]; + if (me->eQueue.tail == 0U) { // need to wrap the tail? + me->eQueue.tail = me->eQueue.end; // wrap around + } + --me->eQueue.tail; + + QS_BEGIN_PRE_(QS_QF_ACTIVE_GET, me->prio) + QS_TIME_PRE_(); // timestamp + QS_SIG_PRE_(e->sig); // the signal of this event + QS_OBJ_PRE_(me); // this active object + QS_2U8_PRE_(QEvt_getPoolId_(e), e->refCtr_); // poolId & refCtr + QS_EQC_PRE_(nFree); // # free entries + QS_END_PRE_() +} +else { + me->eQueue.frontEvt = (QEvt *)0; // queue becomes empty + + // all entries in the queue must be free (+1 for fronEvt) + Q_ASSERT_INCRIT(310, nFree == (me->eQueue.end + 1U)); + + QS_BEGIN_PRE_(QS_QF_ACTIVE_GET_LAST, me->prio) + QS_TIME_PRE_(); // timestamp + QS_SIG_PRE_(e->sig); // the signal of this event + QS_OBJ_PRE_(me); // this active object + QS_2U8_PRE_(QEvt_getPoolId_(e), e->refCtr_); // poolId & refCtr + QS_END_PRE_() +} + +QF_MEM_APP(); +QF_CRIT_EXIT(); + +return e; + + + + //! @static @public @memberof QActive + +//! @static @public @memberof QActive + + + + + QActive_subscrList_ = subscrSto; +QActive_maxPubSignal_ = maxSignal; + +// initialize the subscriber list +for (enum_t sig = 0; sig < maxSignal; ++sig) { + QPSet_setEmpty(&subscrSto[sig].set); +#ifndef Q_UNSAFE + QPSet_update_(&subscrSto[sig].set, &subscrSto[sig].set_dis); +#endif +} + + + + //! @static @private @memberof QActive + +//! @static @private @memberof QActive + + + + + + + #ifndef Q_SPY +Q_UNUSED_PAR(sender); +Q_UNUSED_PAR(qs_id); +#endif + +QSignal const sig = e->sig; + +QF_CRIT_STAT +QF_CRIT_ENTRY(); +QF_MEM_SYS(); + +Q_REQUIRE_INCRIT(200, sig < (QSignal)QActive_maxPubSignal_); +Q_REQUIRE_INCRIT(202, + QPSet_verify_(&QActive_subscrList_[sig].set, + &QActive_subscrList_[sig].set_dis)); + +QS_BEGIN_PRE_(QS_QF_PUBLISH, qs_id) + QS_TIME_PRE_(); // the timestamp + QS_OBJ_PRE_(sender); // the sender object + QS_SIG_PRE_(sig); // the signal of the event + QS_2U8_PRE_(QEvt_getPoolId_(e), e->refCtr_); // poolId & refCtr +QS_END_PRE_() + +// is it a mutable event? +if (QEvt_getPoolId_(e) != 0U) { + // NOTE: The reference counter of a mutable event is incremented to + // prevent premature recycling of the event while the multicasting + // is still in progress. At the end of the function, the garbage + // collector step (QF_gc()) decrements the reference counter and + // recycles the event if the counter drops to zero. This covers the + // case when the event was published without any subscribers. + QEvt_refCtr_inc_(e); +} + +// make a local, modifiable copy of the subscriber set +QPSet subscrSet = QActive_subscrList_[sig].set; + +QF_MEM_APP(); +QF_CRIT_EXIT(); + +if (QPSet_notEmpty(&subscrSet)) { // any subscribers? + // highest-prio subscriber + uint_fast8_t p = QPSet_findMax(&subscrSet); + + QF_CRIT_ENTRY(); + QF_MEM_SYS(); + + QActive *a = QActive_registry_[p]; + // the AO must be registered with the framework + Q_ASSERT_INCRIT(210, a != (QActive *)0); + + QF_MEM_APP(); + QF_CRIT_EXIT(); + + QF_SCHED_STAT_ + QF_SCHED_LOCK_(p); // lock the scheduler up to AO's prio + do { // loop over all subscribers + + // QACTIVE_POST() asserts internally if the queue overflows + QACTIVE_POST(a, e, sender); + + QPSet_remove(&subscrSet, p); // remove the handled subscriber + if (QPSet_notEmpty(&subscrSet)) { // still more subscribers? + p = QPSet_findMax(&subscrSet); // highest-prio subscriber + + QF_CRIT_ENTRY(); + QF_MEM_SYS(); + + a = QActive_registry_[p]; + // the AO must be registered with the framework + Q_ASSERT_INCRIT(220, a != (QActive *)0); + + QF_MEM_APP(); + QF_CRIT_EXIT(); + } + else { + p = 0U; // no more subscribers + } + } while (p != 0U); + QF_SCHED_UNLOCK_(); // unlock the scheduler +} + +// The following garbage collection step decrements the reference counter +// and recycles the event if the counter drops to zero. This covers both +// cases when the event was published with or without any subscribers. +#if (QF_MAX_EPOOL > 0U) +QF_gc(e); // recycle the event to avoid a leak #endif - - + + const - /*! Find the maximum element in the set, returns zero if the set is empty */ - #if (QF_MAX_ACTIVE <= 32) - return QF_LOG2(me->bits); -#else - return (me->bits[1] != 0U) - ? (QF_LOG2(me->bits[1]) + 32U) - : (QF_LOG2(me->bits[0])); -#endif + //! @protected @memberof QActive + +//! @protected @memberof QActive + + + uint_fast8_t const p = (uint_fast8_t)me->prio; + +QF_CRIT_STAT +QF_CRIT_ENTRY(); +QF_MEM_SYS(); + +Q_REQUIRE_INCRIT(300, ((enum_t)Q_USER_SIG <= sig) + && (sig < QActive_maxPubSignal_) + && (0U < p) && (p <= QF_MAX_ACTIVE) + && (QActive_registry_[p] == me)); +Q_REQUIRE_INCRIT(302, + QPSet_verify_(&QActive_subscrList_[sig].set, + &QActive_subscrList_[sig].set_dis)); + +QS_BEGIN_PRE_(QS_QF_ACTIVE_SUBSCRIBE, p) + QS_TIME_PRE_(); // timestamp + QS_SIG_PRE_(sig); // the signal of this event + QS_OBJ_PRE_(me); // this active object +QS_END_PRE_() + +// insert the prio. into the subscriber set +QPSet_insert(&QActive_subscrList_[sig].set, p); +#ifndef Q_UNSAFE +QPSet_update_(&QActive_subscrList_[sig].set, + &QActive_subscrList_[sig].set_dis); +#endif + +QF_MEM_APP(); +QF_CRIT_EXIT(); + + + + const + //! @protected @memberof QActive + +//! @protected @memberof QActive + + + uint_fast8_t const p = (uint_fast8_t)me->prio; + +QF_CRIT_STAT +QF_CRIT_ENTRY(); +QF_MEM_SYS(); + +Q_REQUIRE_INCRIT(400, ((enum_t)Q_USER_SIG <= sig) + && (sig < QActive_maxPubSignal_) + && (0U < p) && (p <= QF_MAX_ACTIVE) + && (QActive_registry_[p] == me)); +Q_REQUIRE_INCRIT(402, + QPSet_verify_(&QActive_subscrList_[sig].set, + &QActive_subscrList_[sig].set_dis)); + +QS_BEGIN_PRE_(QS_QF_ACTIVE_UNSUBSCRIBE, p) + QS_TIME_PRE_(); // timestamp + QS_SIG_PRE_(sig); // the signal of this event + QS_OBJ_PRE_(me); // this active object +QS_END_PRE_() + +// remove the prio. from the subscriber set +QPSet_remove(&QActive_subscrList_[sig].set, p); +#ifndef Q_UNSAFE +QPSet_update_(&QActive_subscrList_[sig].set, + &QActive_subscrList_[sig].set_dis); +#endif + +QF_MEM_APP(); +QF_CRIT_EXIT(); + + + + const + //! @protected @memberof QActive + +//! @protected @memberof QActive + QF_CRIT_STAT +QF_CRIT_ENTRY(); +QF_MEM_SYS(); + +uint_fast8_t const p = (uint_fast8_t)me->prio; + +Q_REQUIRE_INCRIT(500, (0U < p) && (p <= QF_MAX_ACTIVE) + && (QActive_registry_[p] == me)); +enum_t const maxPubSig = QActive_maxPubSignal_; + +QF_MEM_APP(); +QF_CRIT_EXIT(); + +for (enum_t sig = (enum_t)Q_USER_SIG; sig < maxPubSig; ++sig) { + QF_CRIT_ENTRY(); + QF_MEM_SYS(); + + if (QPSet_hasElement(&QActive_subscrList_[sig].set, p)) { + QPSet_remove(&QActive_subscrList_[sig].set, p); +#ifndef Q_UNSAFE + QPSet_update_(&QActive_subscrList_[sig].set, + &QActive_subscrList_[sig].set_dis); +#endif + QS_BEGIN_PRE_(QS_QF_ACTIVE_UNSUBSCRIBE, p) + QS_TIME_PRE_(); // timestamp + QS_SIG_PRE_(sig); // the signal of this event + QS_OBJ_PRE_(me); // this active object + QS_END_PRE_() + } + QF_MEM_APP(); + QF_CRIT_EXIT(); + + QF_CRIT_EXIT_NOP(); // prevent merging critical sections +} + + + + const + //! @protected @memberof QActive + +//! @protected @memberof QActive + + + + + bool const status = QEQueue_post(eq, e, 0U, me->prio); + +QS_CRIT_STAT +QS_CRIT_ENTRY(); +QS_MEM_SYS(); +QS_BEGIN_PRE_(QS_QF_ACTIVE_DEFER, me->prio) + QS_TIME_PRE_(); // time stamp + QS_OBJ_PRE_(me); // this active object + QS_OBJ_PRE_(eq); // the deferred queue + QS_SIG_PRE_(e->sig); // the signal of the event + QS_2U8_PRE_(QEvt_getPoolId_(e), e->refCtr_); // poolId & refCtr +QS_END_PRE_() +QS_MEM_APP(); +QS_CRIT_EXIT(); + +return status; + + + + //! @protected @memberof QActive + +//! @protected @memberof QActive + + + QEvt const * const e = QEQueue_get(eq, me->prio); +QF_CRIT_STAT + +bool recalled; +if (e != (QEvt *)0) { // event available? + QACTIVE_POST_LIFO(me, e); // post it to the front of the AO's queue + + QF_CRIT_ENTRY(); + QF_MEM_SYS(); + + if (QEvt_getPoolId_(e) != 0U) { // is it a mutable event? + + // after posting to the AO's queue the event must be referenced + // at least twice: once in the deferred event queue (eq->get() + // did NOT decrement the reference counter) and once in the + // AO's event queue. + Q_ASSERT_INCRIT(210, e->refCtr_ >= 2U); + + // we need to decrement the reference counter once, to account + // for removing the event from the deferred event queue. + QEvt_refCtr_dec_(e); // decrement the reference counter + } + + QS_BEGIN_PRE_(QS_QF_ACTIVE_RECALL, me->prio) + QS_TIME_PRE_(); // time stamp + QS_OBJ_PRE_(me); // this active object + QS_OBJ_PRE_(eq); // the deferred queue + QS_SIG_PRE_(e->sig); // the signal of the event + QS_2U8_PRE_(QEvt_getPoolId_(e), e->refCtr_); // poolId & refCtr + QS_END_PRE_() + + QF_MEM_APP(); + QF_CRIT_EXIT(); + + recalled = true; +} +else { + QS_CRIT_ENTRY(); + QS_MEM_SYS(); + + QS_BEGIN_PRE_(QS_QF_ACTIVE_RECALL_ATTEMPT, me->prio) + QS_TIME_PRE_(); // time stamp + QS_OBJ_PRE_(me); // this active object + QS_OBJ_PRE_(eq); // the deferred queue + QS_END_PRE_() + + QS_MEM_APP(); + QS_CRIT_EXIT(); + + recalled = false; +} +return recalled; + + + + const + //! @protected @memberof QActive + +//! @protected @memberof QActive + + + uint_fast16_t n = 0U; +for (QEvt const *e = QEQueue_get(eq, me->prio); + e != (QEvt *)0; + e = QEQueue_get(eq, me->prio)) +{ + ++n; // count the flushed event +#if (QF_MAX_EPOOL > 0U) + QF_gc(e); // garbage collect +#endif +} +return n; + + + + //! @private @memberof QActive + +//! @private @memberof QActive - - - /*! Subscriber List (for publish-subscribe) -* -* @details -* This data type represents a set of Active Objects that subscribe to -* a given signal. The set is represented as priority-set, where each -* bit corresponds to the unique QF-priority of an AO (see ::QPrioSpec). -*/ - + + + //! @class QMActive +//! @extends QActive + + + //! @protected @memberof QMActive + +//! @protected @memberof QMActive + + + // clear the whole QMActive object, so that the framework can start +// correctly even if the startup code fails to clear the uninitialized +// data (as is required by the C Standard). +QF_bzero_(me, sizeof(*me)); + +// NOTE: QActive inherits the QActvie class, but it calls the +// constructor of the QMsm subclass. This is because QMActive inherits +// the behavior from the QMsm subclass. +QMsm_ctor((QMsm *)(me), initial); + +// NOTE: this vtable is identical as QMsm, but is provided +// for the QMActive subclass to provide a UNIQUE vptr to distinguish +// subclasses of QActive (e.g., in the debugger). +static struct QAsmVtable const vtable = { // QMActive virtual table + &QMsm_init_, + &QMsm_dispatch_ +#ifdef Q_SPY + ,&QMsm_getStateHandler_ +#endif +}; +me->super.super.vptr = &vtable; // hook vptr to QMActive vtable + + + + + //! @class QTimeEvt +// @extends QEvt + + + //! @private @memberof QTimeEvt + + + + //! @private @memberof QTimeEvt + + + + //! @private @memberof QTimeEvt + + + + //! @private @memberof QTimeEvt + + + + //! @static @private @memberof QTimeEvt + + + + //! @public @memberof QTimeEvt + +//! @public @memberof QTimeEvt + + + + + + + me->next = (QTimeEvt *)0; +me->act = act; +me->ctr = 0U; +me->interval = 0U; + +QF_CRIT_STAT +QF_CRIT_ENTRY(); +Q_REQUIRE_INCRIT(300, (sig != 0) + && (tickRate < QF_MAX_TICK_RATE)); +QF_CRIT_EXIT(); + +// This default event constructor initializes the event +// as NOT allocated from any event-pool, which must be +// the case for Time Events. +QEvt_ctor(&me->super, sig); + +// The refCtr_ attribute is not used in time events, so it is +// reused to hold the tickRate as well as other information +me->super.refCtr_ = (uint8_t)tickRate; + + + + //! @public @memberof QTimeEvt + +//! @public @memberof QTimeEvt + + + + + uint_fast8_t const tickRate + = ((uint_fast8_t)me->super.refCtr_ & QTE_TICK_RATE); +QTimeEvtCtr const ctr = me->ctr; +#ifdef Q_SPY +uint_fast8_t const qs_id = ((QActive *)(me->act))->prio; +#endif + +QF_CRIT_STAT +QF_CRIT_ENTRY(); +QF_MEM_SYS(); + +Q_REQUIRE_INCRIT(400, (me->act != (void *)0) + && (ctr == 0U) + && (nTicks != 0U) + && (tickRate < (uint_fast8_t)QF_MAX_TICK_RATE) + && (me->super.sig >= (QSignal)Q_USER_SIG)); +#ifdef Q_UNSAFE +Q_UNUSED_PAR(ctr); +#endif + +me->ctr = nTicks; +me->interval = interval; + +// is the time event unlinked? +// NOTE: For the duration of a single clock tick of the specified tick +// rate a time event can be disarmed and yet still linked into the list +// because un-linking is performed exclusively in QTimeEvt_tick_(). +if ((me->super.refCtr_ & QTE_IS_LINKED) == 0U) { + // mark as linked + me->super.refCtr_ |= QTE_IS_LINKED; + + // The time event is initially inserted into the separate + // "freshly armed" link list based on QTimeEvt_timeEvtHead_[tickRate].act. + // Only later, inside the QTimeEvt_tick_() function, the "freshly armed" + // list is appended to the main list of armed time events based on + // QTimeEvt_timeEvtHead_[tickRate].next. Again, this is to keep any + // changes to the main list exclusively inside the QTimeEvt_tick_(). + me->next = (QTimeEvt *)QTimeEvt_timeEvtHead_[tickRate].act; + QTimeEvt_timeEvtHead_[tickRate].act = me; +} + +QS_BEGIN_PRE_(QS_QF_TIMEEVT_ARM, qs_id) + QS_TIME_PRE_(); // timestamp + QS_OBJ_PRE_(me); // this time event object + QS_OBJ_PRE_(me->act); // the active object + QS_TEC_PRE_(nTicks); // the # ticks + QS_TEC_PRE_(interval); // the interval + QS_U8_PRE_(tickRate); // tick rate +QS_END_PRE_() + +QF_MEM_APP(); +QF_CRIT_EXIT(); + + + + //! @public @memberof QTimeEvt + +//! @public @memberof QTimeEvt + #ifdef Q_SPY +uint_fast8_t const qs_id = QACTIVE_CAST_(me->act)->prio; +#endif + +QF_CRIT_STAT +QF_CRIT_ENTRY(); +QF_MEM_SYS(); + +// is the time event actually armed? +bool wasArmed; +if (me->ctr != 0U) { + wasArmed = true; + me->super.refCtr_ |= QTE_WAS_DISARMED; + + QS_BEGIN_PRE_(QS_QF_TIMEEVT_DISARM, qs_id) + QS_TIME_PRE_(); // timestamp + QS_OBJ_PRE_(me); // this time event object + QS_OBJ_PRE_(me->act); // the target AO + QS_TEC_PRE_(me->ctr); // the # ticks + QS_TEC_PRE_(me->interval); // the interval + QS_U8_PRE_(me->super.refCtr_ & QTE_TICK_RATE); // tick rate + QS_END_PRE_() + + me->ctr = 0U; // schedule removal from the list +} +else { // the time event was already disarmed automatically + wasArmed = false; + me->super.refCtr_ &= (uint8_t)(~QTE_WAS_DISARMED & 0xFFU); + + QS_BEGIN_PRE_(QS_QF_TIMEEVT_DISARM_ATTEMPT, qs_id) + QS_TIME_PRE_(); // timestamp + QS_OBJ_PRE_(me); // this time event object + QS_OBJ_PRE_(me->act); // the target AO + QS_U8_PRE_(me->super.refCtr_ & QTE_TICK_RATE); // tick rate + QS_END_PRE_() +} + +QF_MEM_APP(); +QF_CRIT_EXIT(); + +return wasArmed; + + + + //! @public @memberof QTimeEvt + +//! @public @memberof QTimeEvt + + + uint_fast8_t const tickRate + = (uint_fast8_t)me->super.refCtr_ & QTE_TICK_RATE; +#ifdef Q_SPY +uint_fast8_t const qs_id = ((QActive *)(me->act))->prio; +#endif + +QF_CRIT_STAT +QF_CRIT_ENTRY(); +QF_MEM_SYS(); + +Q_REQUIRE_INCRIT(600, (me->act != (void *)0) + && (tickRate < QF_MAX_TICK_RATE) + && (nTicks != 0U) + && (me->super.sig >= (QSignal)Q_USER_SIG)); + +// is the time evt not running? +bool wasArmed; +if (me->ctr == 0U) { + wasArmed = false; + + // NOTE: For the duration of a single clock tick of the specified + // tick rate a time event can be disarmed and yet still linked into + // the list, because unlinking is performed exclusively in the + // QTimeEvt_tick_() function. + + // is the time event unlinked? + if ((me->super.refCtr_ & QTE_IS_LINKED) == 0U) { + // mark as linked + me->super.refCtr_ |= QTE_IS_LINKED; + + // The time event is initially inserted into the separate + // "freshly armed" list based on QTimeEvt_timeEvtHead_[tickRate].act. + // Only later, inside the QTimeEvt_tick_() function, the "freshly + // armed" list is appended to the main list of armed time events + // based on QTimeEvt_timeEvtHead_[tickRate].next. Again, this is + // to keep any changes to the main list exclusively inside the + // QTimeEvt_tick_(). + me->next = (QTimeEvt *)QTimeEvt_timeEvtHead_[tickRate].act; + QTimeEvt_timeEvtHead_[tickRate].act = me; + } +} +else { // the time event was armed + wasArmed = true; +} +me->ctr = nTicks; // re-load the tick counter (shift the phasing) + +QS_BEGIN_PRE_(QS_QF_TIMEEVT_REARM, qs_id) + QS_TIME_PRE_(); // timestamp + QS_OBJ_PRE_(me); // this time event object + QS_OBJ_PRE_(me->act); // the target AO + QS_TEC_PRE_(me->ctr); // the # ticks + QS_TEC_PRE_(me->interval); // the interval + QS_2U8_PRE_(tickRate, (wasArmed ? 1U : 0U)); +QS_END_PRE_() + +QF_MEM_APP(); +QF_CRIT_EXIT(); + +return wasArmed; + + + + //! @public @memberof QTimeEvt + +//! @public @memberof QTimeEvt + QF_CRIT_STAT +QF_CRIT_ENTRY(); +QF_MEM_SYS(); + +uint8_t const wasDisarmed = (me->super.refCtr_ & QTE_WAS_DISARMED); +me->super.refCtr_ |= QTE_WAS_DISARMED; // mark as disarmed + +QF_MEM_APP(); +QF_CRIT_EXIT(); + +return wasDisarmed != 0U; + + + + const + //! @public @memberof QTimeEvt + +//! @public @memberof QTimeEvt + QF_CRIT_STAT +QF_CRIT_ENTRY(); +QTimeEvtCtr const ctr = me->ctr; +QF_CRIT_EXIT(); + +return ctr; + + + + //! @static @private @memberof QTimeEvt + +//! @static @private @memberof QTimeEvt + + + + + #ifndef Q_SPY +Q_UNUSED_PAR(sender); +#endif + +QTimeEvt *prev = &QTimeEvt_timeEvtHead_[tickRate]; + +QF_CRIT_STAT +QF_CRIT_ENTRY(); +QF_MEM_SYS(); + +QS_BEGIN_PRE_(QS_QF_TICK, 0U) + ++prev->ctr; + QS_TEC_PRE_(prev->ctr); // tick ctr + QS_U8_PRE_(tickRate); // tick rate +QS_END_PRE_() + +// scan the linked-list of time events at this rate... +for (;;) { + QTimeEvt *t = prev->next; // advance down the time evt. list + + if (t == (QTimeEvt *)0) { // end of the list? + + // any new time events armed since the last QTimeEvt_tick_()? + if (QTimeEvt_timeEvtHead_[tickRate].act != (void *)0) { + + // sanity check + Q_ASSERT_INCRIT(110, prev != (QTimeEvt *)0); + prev->next = (QTimeEvt *)QTimeEvt_timeEvtHead_[tickRate].act; + QTimeEvt_timeEvtHead_[tickRate].act = (void *)0; + t = prev->next; // switch to the new list + } + else { + break; // all currently armed time evts. processed + } + } + + if (t->ctr == 0U) { // time event scheduled for removal? + prev->next = t->next; + // mark time event 't' as NOT linked + t->super.refCtr_ &= (uint8_t)(~QTE_IS_LINKED & 0xFFU); + // do NOT advance the prev pointer + QF_MEM_APP(); + QF_CRIT_EXIT(); // exit crit. section to reduce latency + + // NOTE: prevent merging critical sections + // In some QF ports the critical section exit takes effect only + // on the next machine instruction. If the next instruction is + // another entry to a critical section, the critical section + // might not be really exited, but rather the two adjacent + // critical sections would be MERGED. The QF_CRIT_EXIT_NOP() + // macro contains minimal code required to prevent such merging + // of critical sections in QF ports, in which it can occur. + QF_CRIT_EXIT_NOP(); + } + else { + --t->ctr; + + if (t->ctr == 0U) { // is time event about to expire? + QActive * const act = (QActive *)t->act; + + if (t->interval != 0U) { // periodic time evt? + t->ctr = t->interval; // rearm the time event + prev = t; // advance to this time event + } + else { // one-shot time event: automatically disarm + prev->next = t->next; + + // mark time event 't' as NOT linked + t->super.refCtr_ &= (uint8_t)(~QTE_IS_LINKED & 0xFFU); + // do NOT advance the prev pointer + + QS_BEGIN_PRE_(QS_QF_TIMEEVT_AUTO_DISARM, act->prio) + QS_OBJ_PRE_(t); // this time event object + QS_OBJ_PRE_(act); // the target AO + QS_U8_PRE_(tickRate); // tick rate + QS_END_PRE_() + } + + QS_BEGIN_PRE_(QS_QF_TIMEEVT_POST, act->prio) + QS_TIME_PRE_(); // timestamp + QS_OBJ_PRE_(t); // the time event object + QS_SIG_PRE_(t->super.sig); // signal of this time event + QS_OBJ_PRE_(act); // the target AO + QS_U8_PRE_(tickRate); // tick rate + QS_END_PRE_() + +#ifdef QXK_H_ + if (t->super.sig < Q_USER_SIG) { + QXThread_timeout_(act); + } + else { + QF_MEM_APP(); + QF_CRIT_EXIT(); // exit crit. section before posting + + // QACTIVE_POST() asserts if the queue overflows + QACTIVE_POST(act, &t->super, sender); + } +#else + QF_MEM_APP(); + QF_CRIT_EXIT(); // exit crit. section before posting + + // QACTIVE_POST() asserts if the queue overflows + QACTIVE_POST(act, &t->super, sender); +#endif + } + else { + prev = t; // advance to this time event + + QF_MEM_APP(); + QF_CRIT_EXIT(); // exit crit. section to reduce latency + + // prevent merging critical sections, see NOTE above + QF_CRIT_EXIT_NOP(); + } + } + QF_CRIT_ENTRY(); // re-enter crit. section to continue the loop + QF_MEM_SYS(); +} + +QF_MEM_APP(); +QF_CRIT_EXIT(); + + + + //! @static @private @memberof QTimeEvt + +//! @static @private @memberof QTimeEvt + + + + + + + + //! @static @public @memberof QTimeEvt + +//! @static @public @memberof QTimeEvt + + + QF_CRIT_STAT +QF_CRIT_ENTRY(); +Q_REQUIRE_INCRIT(800, tickRate < QF_MAX_TICK_RATE); +QF_CRIT_EXIT(); + +bool inactive; +if (QTimeEvt_timeEvtHead_[tickRate].next != (QTimeEvt *)0) { + inactive = false; +} +else if ((QTimeEvt_timeEvtHead_[tickRate].act != (void *)0)) { + inactive = false; +} +else { + inactive = true; +} +return inactive; + + + + + //! @class QTicker +// @extends QActive + + + //! @public @memberof QTicker + +//! @public @memberof QTicker + + + QActive_ctor(&me->super, Q_STATE_CAST(0)); // superclass' ctor + +static struct QAsmVtable const vtable = { // QTicker virtual table + &QTicker_init_, + &QTicker_dispatch_ +#ifdef Q_SPY + ,&QHsm_getStateHandler_ +#endif +}; +me->super.super.vptr = &vtable; // hook the vptr + +// reuse eQueue.head for tick-rate +me->super.eQueue.head = (QEQueueCtr)tickRate; + + + + //! @private @memberof QTicker + +//! @private @memberof QTicker + + + + + + + Q_UNUSED_PAR(me); +Q_UNUSED_PAR(par); +Q_UNUSED_PAR(qs_id); + +QF_CRIT_STAT +QF_CRIT_ENTRY(); +QF_MEM_SYS(); + +QACTIVE_CAST_(me)->eQueue.tail = 0U; + +QF_MEM_APP(); +QF_CRIT_EXIT(); + + + + //! @private @memberof QTicker + +//! @private @memberof QTicker + + + + + + + Q_UNUSED_PAR(e); +Q_UNUSED_PAR(qs_id); + +QF_CRIT_STAT +QF_CRIT_ENTRY(); +QF_MEM_SYS(); + +QEQueueCtr nTicks = QACTIVE_CAST_(me)->eQueue.tail; // save # of ticks +QACTIVE_CAST_(me)->eQueue.tail = 0U; // clear # ticks + +QF_MEM_APP(); +QF_CRIT_EXIT(); + +for (; nTicks > 0U; --nTicks) { + QTimeEvt_tick_((uint_fast8_t)QACTIVE_CAST_(me)->eQueue.head, me); +} + + + + //! @private @memberof QTicker + +//! @private @memberof QTicker + + + + + #ifndef Q_SPY +Q_UNUSED_PAR(sender); +#endif + +QF_CRIT_STAT +QF_CRIT_ENTRY(); +QF_MEM_SYS(); + +if (me->eQueue.frontEvt == (QEvt *)0) { + + static QEvt const tickEvt = QEVT_INITIALIZER(0); + me->eQueue.frontEvt = &tickEvt; // deliver event directly + --me->eQueue.nFree; // one less free event + + QACTIVE_EQUEUE_SIGNAL_(me); // signal the event queue +} + +++me->eQueue.tail; // account for one more tick event + +QS_BEGIN_PRE_(QS_QF_ACTIVE_POST, me->prio) + QS_TIME_PRE_(); // timestamp + QS_OBJ_PRE_(sender); // the sender object + QS_SIG_PRE_(0U); // the signal of the event + QS_OBJ_PRE_(me); // this active object + QS_2U8_PRE_(0U, 0U); // poolId & refCtr + QS_EQC_PRE_(0U); // # free entries + QS_EQC_PRE_(0U); // min # free entries +QS_END_PRE_() + +QF_MEM_APP(); +QF_CRIT_EXIT(); + + + + + //! @class QEQueue + + + //! @private @memberof QEQueue + + + + //! @private @memberof QEQueue + + + + //! @private @memberof QEQueue + + + + //! @private @memberof QEQueue + + + + //! @private @memberof QEQueue + + + + //! @private @memberof QEQueue + + + + //! @private @memberof QEQueue + + + + dummy static member to force generation of +'struct QEQueue' + + + + //! @public @memberof QEQueue + +//! @public @memberof QEQueue + + + + + me->frontEvt = (QEvt *)0; // no events in the queue +me->ring = qSto; // the beginning of the ring buffer +me->end = (QEQueueCtr)qLen; +if (qLen != 0U) { + me->head = 0U; + me->tail = 0U; +} +me->nFree = (QEQueueCtr)(qLen + 1U); // +1 for frontEvt +me->nMin = me->nFree; + + + + //! @public @memberof QEQueue + +//! @public @memberof QEQueue + + + + + + + #ifndef Q_SPY +Q_UNUSED_PAR(qs_id); +#endif + +QF_CRIT_STAT +QF_CRIT_ENTRY(); +QF_MEM_SYS(); + +Q_REQUIRE_INCRIT(200, e != (QEvt *)0); + +QEQueueCtr nFree = me->nFree; // get volatile into temporary + +// required margin available? +bool status; +if (((margin == QF_NO_MARGIN) && (nFree > 0U)) + || (nFree > (QEQueueCtr)margin)) +{ + // is it a mutable event? + if (QEvt_getPoolId_(e) != 0U) { + QEvt_refCtr_inc_(e); // increment the reference counter + } + + --nFree; // one free entry just used up + me->nFree = nFree; // update the original + if (me->nMin > nFree) { + me->nMin = nFree; // update minimum so far + } + + QS_BEGIN_PRE_(QS_QF_EQUEUE_POST, qs_id) + QS_TIME_PRE_(); // timestamp + QS_SIG_PRE_(e->sig); // the signal of this event + QS_OBJ_PRE_(me); // this queue object + QS_2U8_PRE_(QEvt_getPoolId_(e), e->refCtr_); // poolId & refCtr + QS_EQC_PRE_(nFree); // # free entries + QS_EQC_PRE_(me->nMin); // min # free entries + QS_END_PRE_() + + if (me->frontEvt == (QEvt *)0) { // was the queue empty? + me->frontEvt = e; // deliver event directly + } + else { // queue was not empty, insert event into the ring-buffer + // insert event into the ring buffer (FIFO)... + me->ring[me->head] = e; // insert e into buffer + // need to wrap the head? + if (me->head == 0U) { + me->head = me->end; // wrap around + } + --me->head; + } + status = true; // event posted successfully +} +else { // event cannot be posted + // dropping events must be acceptable + Q_ASSERT_INCRIT(210, margin != QF_NO_MARGIN); + + QS_BEGIN_PRE_(QS_QF_EQUEUE_POST_ATTEMPT, qs_id) + QS_TIME_PRE_(); // timestamp + QS_SIG_PRE_(e->sig); // the signal of this event + QS_OBJ_PRE_(me); // this queue object + QS_2U8_PRE_(QEvt_getPoolId_(e), e->refCtr_); // poolId & refCtr + QS_EQC_PRE_(nFree); // # free entries + QS_EQC_PRE_(margin); // margin requested + QS_END_PRE_() + + status = false; // event not posted +} + +QF_MEM_APP(); +QF_CRIT_EXIT(); + +return status; + + + + //! @public @memberof QEQueue + +//! @public @memberof QEQueue + + + + + #ifndef Q_SPY +Q_UNUSED_PAR(qs_id); +#endif + +QF_CRIT_STAT +QF_CRIT_ENTRY(); +QF_MEM_SYS(); + +QEQueueCtr nFree = me->nFree; // get volatile into temporary + +Q_REQUIRE_INCRIT(300, nFree != 0U); + +if (QEvt_getPoolId_(e) != 0U) { // is it a mutable event? + QEvt_refCtr_inc_(e); // increment the reference counter +} + +--nFree; // one free entry just used up +me->nFree = nFree; // update the original +if (me->nMin > nFree) { + me->nMin = nFree; // update minimum so far +} + +QS_BEGIN_PRE_(QS_QF_EQUEUE_POST_LIFO, qs_id) + QS_TIME_PRE_(); // timestamp + QS_SIG_PRE_(e->sig); // the signal of this event + QS_OBJ_PRE_(me); // this queue object + QS_2U8_PRE_(QEvt_getPoolId_(e), e->refCtr_); // poolId & refCtr + QS_EQC_PRE_(nFree); // # free entries + QS_EQC_PRE_(me->nMin); // min # free entries +QS_END_PRE_() + +QEvt const * const frontEvt = me->frontEvt; // read into temporary +me->frontEvt = e; // deliver event directly to the front of the queue + +if (frontEvt != (QEvt *)0) { // was the queue not empty? + ++me->tail; + if (me->tail == me->end) { // need to wrap the tail? + me->tail = 0U; // wrap around + } + me->ring[me->tail] = frontEvt; // save old front evt +} + +QF_MEM_APP(); +QF_CRIT_EXIT(); + + + + //! @public @memberof QEQueue + +//! @public @memberof QEQueue + + + #ifndef Q_SPY +Q_UNUSED_PAR(qs_id); +#endif + +QF_CRIT_STAT +QF_CRIT_ENTRY(); +QF_MEM_SYS(); + +QEvt const * const e = me->frontEvt; // always remove evt from the front + +if (e != (QEvt *)0) { // was the queue not empty? + // use a temporary variable to increment me->nFree + QEQueueCtr const nFree = me->nFree + 1U; + me->nFree = nFree; // update the # free + + // any events in the ring buffer? + if (nFree <= me->end) { + me->frontEvt = me->ring[me->tail]; // get from tail + if (me->tail == 0U) { // need to wrap the tail? + me->tail = me->end; // wrap around + } + --me->tail; + + QS_BEGIN_PRE_(QS_QF_EQUEUE_GET, qs_id) + QS_TIME_PRE_(); // timestamp + QS_SIG_PRE_(e->sig); // the signal of this event + QS_OBJ_PRE_(me); // this queue object + QS_2U8_PRE_(QEvt_getPoolId_(e), e->refCtr_); // poolId & refCtr + QS_EQC_PRE_(nFree); // # free entries + QS_END_PRE_() + } + else { + me->frontEvt = (QEvt *)0; // queue becomes empty + + // all entries in the queue must be free (+1 for fronEvt) + Q_ASSERT_INCRIT(410, nFree == (me->end + 1U)); + + QS_BEGIN_PRE_(QS_QF_EQUEUE_GET_LAST, qs_id) + QS_TIME_PRE_(); // timestamp + QS_SIG_PRE_(e->sig); // the signal of this event + QS_OBJ_PRE_(me); // this queue object + QS_2U8_PRE_(QEvt_getPoolId_(e), e->refCtr_); // poolId & refCtr + QS_END_PRE_() + } +} + +QF_MEM_APP(); +QF_CRIT_EXIT(); + +return e; + + + + const + //! @public @memberof QEQueue + +//! @public @memberof QEQueue + return me->nFree; + + + + const + //! @public @memberof QEQueue + +//! @public @memberof QEQueue + return me->nMin; + + + + const + //! @public @memberof QEQueue + +//! @public @memberof QEQueue + return me->frontEvt == (struct QEvt *)0; + + + + + //! @struct QFreeBlock + + + //! @private @memberof QFreeBlock + + + + //! @private @memberof QFreeBlock + + + + + //! @class QMPool + + + //! @private @memberof QMPool + + + + //! @private @memberof QMPool + + + + //! @private @memberof QMPool + + + + //! @private @memberof QMPool + + + + //! @private @memberof QMPool + + + + //! @private @memberof QMPool + + + + //! @private @memberof QMPool + + + + //! @public @memberof QMPool + +//! @public @memberof QMPool + + + + + + + QF_CRIT_STAT +QF_CRIT_ENTRY(); +QF_MEM_SYS(); + +Q_REQUIRE_INCRIT(100, (poolSto != (void *)0) + && (poolSize >= (uint_fast32_t)sizeof(QFreeBlock)) + && ((uint_fast16_t)(blockSize + sizeof(QFreeBlock)) > blockSize)); + +me->free_head = (QFreeBlock *)poolSto; + +// find # free blocks in a memory block, NO DIVISION +me->blockSize = (QMPoolSize)sizeof(QFreeBlock); +uint_fast16_t nblocks = 1U; +while (me->blockSize < (QMPoolSize)blockSize) { + me->blockSize += (QMPoolSize)sizeof(QFreeBlock); + ++nblocks; +} + +// the pool buffer must fit at least one rounded-up block +Q_ASSERT_INCRIT(110, poolSize >= me->blockSize); + +// start at the head of the free list +QFreeBlock *fb = me->free_head; +me->nTot = 1U; // the last block already in the list + +// chain all blocks together in a free-list... +for (uint_fast32_t size = poolSize - me->blockSize; + size >= (uint_fast32_t)me->blockSize; + size -= (uint_fast32_t)me->blockSize) +{ + fb->next = &fb[nblocks]; // point next link to next block +#ifndef Q_UNSAFE + fb->next_dis = (uintptr_t)(~Q_UINTPTR_CAST_(fb->next)); +#endif + fb = fb->next; // advance to the next block + ++me->nTot; // one more free block in the pool +} + +fb->next = (QFreeBlock *)0; // the last link points to NULL +#ifndef Q_UNSAFE +fb->next_dis = (uintptr_t)(~Q_UINTPTR_CAST_(fb->next)); +#endif + +me->nFree = me->nTot; // all blocks are free +me->nMin = me->nTot; // the minimum # free blocks +me->start = poolSto; // the original start this pool buffer +me->end = fb; // the last block in this pool + +QF_MEM_APP(); +QF_CRIT_EXIT(); + + + + //! @public @memberof QMPool + +//! @public @memberof QMPool + + + + + #ifndef Q_SPY +Q_UNUSED_PAR(qs_id); +#endif + +QF_CRIT_STAT +QF_CRIT_ENTRY(); +QF_MEM_SYS(); + +// have more free blocks than the requested margin? +QFreeBlock *fb; +if (me->nFree > (QMPoolCtr)margin) { + fb = me->free_head; // get a free block + + // a free block must be valid + Q_ASSERT_INCRIT(300, fb != (QFreeBlock *)0); + + QFreeBlock * const fb_next = fb->next; // fast temporary + + // the free block must have integrity (duplicate inverse storage) + Q_ASSERT_INCRIT(302, Q_UINTPTR_CAST_(fb_next) + == (uintptr_t)~fb->next_dis); + + --me->nFree; // one less free block + if (me->nFree == 0U) { // is the pool becoming empty? + // pool is becoming empty, so the next free block must be NULL + Q_ASSERT_INCRIT(320, fb_next == (QFreeBlock *)0); + + me->nMin = 0U; // remember that the pool got empty + } + else { + // invariant: + // The pool is not empty, so the next free-block pointer, + // so the next free block must be in range. + + // NOTE: The next free block pointer can fall out of range + // when the client code writes past the memory block, thus + // corrupting the next block. + Q_ASSERT_INCRIT(330, + (me->start <= fb_next) && (fb_next <= me->end)); + + // is the # free blocks the new minimum so far? + if (me->nMin > me->nFree) { + me->nMin = me->nFree; // remember the new minimum + } + } + + me->free_head = fb_next; // set the head to the next free block + + QS_BEGIN_PRE_(QS_QF_MPOOL_GET, qs_id) + QS_TIME_PRE_(); // timestamp + QS_OBJ_PRE_(me); // this memory pool + QS_MPC_PRE_(me->nFree); // # of free blocks in the pool + QS_MPC_PRE_(me->nMin); // min # free blocks ever in the pool + QS_END_PRE_() +} +else { // don't have enough free blocks at this point + fb = (QFreeBlock *)0; + + QS_BEGIN_PRE_(QS_QF_MPOOL_GET_ATTEMPT, qs_id) + QS_TIME_PRE_(); // timestamp + QS_OBJ_PRE_(me); // this memory pool + QS_MPC_PRE_(me->nFree); // # of free blocks in the pool + QS_MPC_PRE_(margin); // the requested margin + QS_END_PRE_() +} + +QF_MEM_APP(); +QF_CRIT_EXIT(); + +return fb; // return the block or NULL pointer to the caller + + + + //! @public @memberof QMPool + +//! @public @memberof QMPool + + + + + #ifndef Q_SPY +Q_UNUSED_PAR(qs_id); +#endif + +QFreeBlock * const fb = (QFreeBlock *)block; + +QF_CRIT_STAT +QF_CRIT_ENTRY(); +QF_MEM_SYS(); + +Q_REQUIRE_INCRIT(200, (me->nFree < me->nTot) + && (me->start <= fb) && (fb <= me->end)); + +fb->next = me->free_head; // link into list +#ifndef Q_UNSAFE +fb->next_dis = (uintptr_t)(~Q_UINTPTR_CAST_(fb->next)); +#endif + +// set as new head of the free list +me->free_head = block; + +++me->nFree; // one more free block in this pool + +QS_BEGIN_PRE_(QS_QF_MPOOL_PUT, qs_id) + QS_TIME_PRE_(); // timestamp + QS_OBJ_PRE_(me); // this memory pool + QS_MPC_PRE_(me->nFree); // the # free blocks in the pool +QS_END_PRE_() + +QF_MEM_APP(); +QF_CRIT_EXIT(); + + + + + + + //! @class QF_Attr + + + //! @private @memberof QF_Attr + + + + //! @private @memberof QF_Attr + + + + //! @private @memberof QF_Attr + + + + + //! @static @private @memberof QF + + + + //! @static @private @memberof QF + +//! @static @private @memberof QF + + + + + uint8_t *ptr = (uint8_t *)start; +for (uint_fast16_t n = len; n > 0U; --n) { + *ptr = 0U; + ++ptr; +} + + + + + + + //! @static @public @memberof QF + +//! @static @public @memberof QF + + + + //! @static @public @memberof QF + +//! @static @public @memberof QF + + + + //! @static @public @memberof QF + +//! @static @public @memberof QF + + + + //! @static @public @memberof QF + +//! @static @public @memberof QF + + + QF_CRIT_STAT +QF_CRIT_ENTRY(); +Q_REQUIRE_INCRIT(400, (prio <= QF_MAX_ACTIVE) + && (QActive_registry_[prio] != (QActive *)0)); +uint_fast16_t const min = + (uint_fast16_t)QActive_registry_[prio]->eQueue.nMin; +QF_CRIT_EXIT(); + +return min; + + + + //! @static @public @memberof QF + +//! @static @public @memberof QF + + + + //! @static @public @memberof QF + +//! @static @public @memberof QF + + + + //! @static @public @memberof QF + +//! @static @public @memberof QF + + + + + + + + + + + //! @static @public @memberof QF + +//! @static @public @memberof QF + + + + + + + uint_fast8_t const poolId = QF_priv_.maxPool_; + +// see precondition{qf_dyn,200} and precondition{qf_dyn,201} +QF_CRIT_STAT +QF_CRIT_ENTRY(); +QF_MEM_SYS(); + +Q_REQUIRE_INCRIT(200, poolId < QF_MAX_EPOOL); +if (poolId > 0U) { + Q_REQUIRE_INCRIT(201, + QF_EPOOL_EVENT_SIZE_(QF_priv_.ePool_[poolId - 1U]) < evtSize); +} +QF_priv_.maxPool_ = poolId + 1U; // one more pool + +QF_MEM_APP(); +QF_CRIT_EXIT(); + +// perform the port-dependent initialization of the event-pool +QF_EPOOL_INIT_(QF_priv_.ePool_[poolId], poolSto, poolSize, evtSize); + +#ifdef Q_SPY +// generate the object-dictionary entry for the initialized pool +{ + uint8_t obj_name[9] = "EvtPool?"; + obj_name[7] = (uint8_t)((uint8_t)'0' + poolId + 1U); + QF_CRIT_ENTRY(); + QF_MEM_SYS(); + QS_obj_dict_pre_(&QF_priv_.ePool_[poolId], (char const *)obj_name); + QF_MEM_APP(); + QF_CRIT_EXIT(); +} +#endif // Q_SPY + + + + //! @static @public @memberof QF + +//! @static @public @memberof QF + return QF_EPOOL_EVENT_SIZE_(QF_priv_.ePool_[QF_priv_.maxPool_ - 1U]); + + + + //! @static @public @memberof QF + +//! @static @public @memberof QF + + + QF_CRIT_STAT +QF_CRIT_ENTRY(); +QF_MEM_SYS(); + +Q_REQUIRE_INCRIT(400, (poolId <= QF_MAX_EPOOL) + && (0U < poolId) && (poolId <= QF_priv_.maxPool_)); + +uint_fast16_t const min = (uint_fast16_t)QF_priv_.ePool_[poolId - 1U].nMin; + +QF_MEM_APP(); +QF_CRIT_EXIT(); + +return min; + + + + //! @static @private @memberof QF + +//! @static @private @memberof QF + + + + + + + QF_CRIT_STAT +QF_CRIT_ENTRY(); +QF_MEM_SYS(); + +// find the pool id that fits the requested event size... +uint_fast8_t poolId = 0U; // zero-based poolId initially +for (; poolId < QF_priv_.maxPool_; ++poolId) { + if (evtSize <= QF_EPOOL_EVENT_SIZE_(QF_priv_.ePool_[poolId])) { + break; + } +} + +// precondition: +// - cannot run out of registered pools +Q_REQUIRE_INCRIT(300, poolId < QF_priv_.maxPool_); + +++poolId; // convert to 1-based poolId + +QF_MEM_APP(); +QF_CRIT_EXIT(); + +// get event e (port-dependent)... +QEvt *e; +#ifdef Q_SPY +QF_EPOOL_GET_(QF_priv_.ePool_[poolId - 1U], e, + ((margin != QF_NO_MARGIN) ? margin : 0U), + (uint_fast8_t)QS_EP_ID + poolId); +#else +QF_EPOOL_GET_(QF_priv_.ePool_[poolId - 1U], e, + ((margin != QF_NO_MARGIN) ? margin : 0U), 0U); +#endif + +if (e != (QEvt *)0) { // was e allocated correctly? + e->sig = (QSignal)sig; // set the signal + e->refCtr_ = 0U; // initialize the reference counter to 0 + e->evtTag_ = (uint8_t)(QEVT_MARKER | poolId); + + QS_CRIT_ENTRY(); + QS_MEM_SYS(); + QS_BEGIN_PRE_(QS_QF_NEW, + (uint_fast8_t)QS_EP_ID + poolId) + QS_TIME_PRE_(); // timestamp + QS_EVS_PRE_(evtSize); // the size of the event + QS_SIG_PRE_(sig); // the signal of the event + QS_END_PRE_() + QS_MEM_APP(); + QS_CRIT_EXIT(); +} +else { // event was not allocated + + QF_CRIT_ENTRY(); + // This assertion means that the event allocation failed, + // and this failure cannot be tolerated. The most frequent + // reason is an event leak in the application. + Q_ASSERT_INCRIT(320, margin != QF_NO_MARGIN); + + QS_MEM_SYS(); + QS_BEGIN_PRE_(QS_QF_NEW_ATTEMPT, + (uint_fast8_t)QS_EP_ID + poolId) + QS_TIME_PRE_(); // timestamp + QS_EVS_PRE_(evtSize); // the size of the event + QS_SIG_PRE_(sig); // the signal of the event + QS_END_PRE_() + QS_MEM_APP(); + + QF_CRIT_EXIT(); +} + +// the returned event e is guaranteed to be valid (not NULL) +// if we can't tolerate failed allocation +return e; + + + + //! @static @public @memberof QF + +//! @static @public @memberof QF + + + QF_CRIT_STAT +QF_CRIT_ENTRY(); +Q_REQUIRE_INCRIT(402, QEvt_verify_(e)); + +uint_fast8_t const poolId = QEvt_getPoolId_(e); + +if (poolId != 0U) { // is it a pool event (mutable)? + QF_MEM_SYS(); + + if (e->refCtr_ > 1U) { // isn't this the last reference? + + QS_BEGIN_PRE_(QS_QF_GC_ATTEMPT, + (uint_fast8_t)QS_EP_ID + poolId) + QS_TIME_PRE_(); // timestamp + QS_SIG_PRE_(e->sig); // the signal of the event + QS_2U8_PRE_(poolId, e->refCtr_); // poolId & refCtr + QS_END_PRE_() + + QEvt_refCtr_dec_(e); // decrement the ref counter + + QF_MEM_APP(); + QF_CRIT_EXIT(); + } + else { // this is the last reference to this event, recycle it + + QS_BEGIN_PRE_(QS_QF_GC, + (uint_fast8_t)QS_EP_ID + poolId) + QS_TIME_PRE_(); // timestamp + QS_SIG_PRE_(e->sig); // the signal of the event + QS_2U8_PRE_(poolId, e->refCtr_); // poolId & refCtr + QS_END_PRE_() + + // pool number must be in range + Q_ASSERT_INCRIT(410, (poolId <= QF_priv_.maxPool_) + && (poolId <= QF_MAX_EPOOL)); + QF_MEM_APP(); + QF_CRIT_EXIT(); + + // NOTE: casting 'const' away is legit because it's a pool event +#ifdef Q_SPY + QF_EPOOL_PUT_(QF_priv_.ePool_[poolId - 1U], + (QEvt *)e, + (uint_fast8_t)QS_EP_ID + poolId); +#else + QF_EPOOL_PUT_(QF_priv_.ePool_[poolId - 1U], + (QEvt *)e, 0U); +#endif + } +} +else { + QF_CRIT_EXIT(); +} + + + + //! @static @private @memberof QF + +//! @static @private @memberof QF + + + + + #ifdef Q_UNSAFE +Q_UNUSED_PAR(evtRef); +#endif + +QF_CRIT_STAT +QF_CRIT_ENTRY(); + +Q_REQUIRE_INCRIT(502, QEvt_verify_(e)); + +uint_fast8_t const poolId = QEvt_getPoolId_(e); + +Q_REQUIRE_INCRIT(500, (poolId != 0U) + && (evtRef == (void *)0)); + +QEvt_refCtr_inc_(e); // increments the ref counter + +QS_MEM_SYS(); +QS_BEGIN_PRE_(QS_QF_NEW_REF, + (uint_fast8_t)QS_EP_ID + poolId) + QS_TIME_PRE_(); // timestamp + QS_SIG_PRE_(e->sig); // the signal of the event + QS_2U8_PRE_(poolId, e->refCtr_); // poolId & refCtr +QS_END_PRE_() +QS_MEM_APP(); + +QF_CRIT_EXIT(); + +return e; + + + + //! @static @private @memberof QF + +//! @static @private @memberof QF + + + QEvt const * const e = evtRef; + +QF_CRIT_STAT +QF_CRIT_ENTRY(); +Q_REQUIRE_INCRIT(602, QEvt_verify_(e)); + +#ifdef Q_SPY +uint_fast8_t const poolId = QEvt_getPoolId_(e); +#endif + +QS_MEM_SYS(); +QS_BEGIN_PRE_(QS_QF_DELETE_REF, + (uint_fast8_t)QS_EP_ID + poolId) + QS_TIME_PRE_(); // timestamp + QS_SIG_PRE_(e->sig); // the signal of the event + QS_2U8_PRE_(poolId, e->refCtr_); // poolId & refCtr +QS_END_PRE_() +QS_MEM_APP(); + +QF_CRIT_EXIT(); + +#if (QF_MAX_EPOOL > 0U) +QF_gc(e); // recycle the referenced event +#endif + + + + //! @static @public @memberof QF + +//! @static @public @memberof QF + + + + - /*! Special value of margin that causes asserting failure in case -* event allocation or event posting fails -*/ ((uint_fast16_t)0xFFFFU) - /*! Create a ::QPrioSpec object to specify priorty of an AO or a thread */ @@ -2783,29 +4331,7 @@ return n + log2LUT[x]; ((QPrioSpec)((prio_) | ((pthre_) << 8U))) - - /*! Allocate a dynamic event (case when ::QEvt is a POD) -* -* @details -* The macro calls the internal QF function QF::newX_() with -* margin == ::QF_NO_MARGIN, which causes an assertion when the event -* cannot be successfully allocated. -* -* @param[in] evtT_ event type (class name) of the event to allocate -* @param[in] sig_ signal to assign to the newly allocated event -* -* @returns a valid event pointer cast to the type `evtT_`. -* -* @note -* If #Q_EVT_CTOR is defined, the Q_NEW() macro becomes variadic and -* takes all the arguments needed by the constructor of the event -* class being allocated. The constructor is then called by means -* of the placement-new operator. -* -* @usage -* The following example illustrates dynamic allocation of an event: -* @include qf_post.c -*/ + @@ -2814,10 +4340,7 @@ return n + log2LUT[x]; QF_NO_MARGIN, (enum_t)(sig_))) - - /*! Asserting allocate a dynamic event -* (case when ::QEvt is not a POD) -*/ + @@ -2826,56 +4349,22 @@ return n + log2LUT[x]; \ (evtT_##_ctor((evtT_ *)QF_newX_((uint_fast16_t)sizeof(evtT_), \ - QF_NO_MARGIN, (sig_)), (enum_t)(sig_), ##__VA_ARGS__)) + QF_NO_MARGIN, (sig_)), __VA_ARGS__)) - - /*! Non-asserting allocate a dynamic event (case when ::QEvt is a POD). -* -* @details -* This macro allocates a new event and sets the pointer `e_`, while -* leaving at least `margin_` of events still available in the pool -* -* @param[out] e_ pointer to the newly allocated event -* @param[in] evtT_ event type (class name) of the event to allocate -* @param[in] margin_ number of events that must remain available -* in the given pool after this allocation. The -* special value ::QF_NO_MARGIN causes asserting -* failure in case event allocation fails. -* @param[in] sig_ signal to assign to the newly allocated event -* -* @returns an event pointer cast to the type `evtT_` or NULL if the -* event cannot be allocated with the specified `margin`. -* -* @note -* If #Q_EVT_CTOR is defined, the Q_NEW_X() macro becomes variadic and -* takes all the arguments needed by the constructor of the event -* class being allocated. The constructor is then called by means -* of the placement-new operator. -* -* @usage -* The following example illustrates dynamic allocation of an event: -* @include qf_postx.c -*/ - - + - ((e_) = \ + \ (evtT_ *)QF_newX_((uint_fast16_t)sizeof(evtT_), \ (margin_), (enum_t)(sig_))) - - /*! Non-asserting allocate a dynamic event -* (case when ::QEvt is not a POD) -*/ - - + @@ -2884,36 +4373,12 @@ return n + log2LUT[x]; - do { \ - (e_) = (evtT_ *)QF_newX_((uint_fast16_t)sizeof(evtT_), \ - (margin_), (enum_t)(sig_));\ - if ((e_) != (evtT_ *)0) { \ - evtT_##_ctor((e_), (enum_t)(sig_), ##__VA_ARGS__); \ - } \ - } while (false) + \ + (evtT_##_ctor((evtT_ *)QF_newX_((uint_fast16_t)sizeof(evtT_), \ + (margin_), (sig_)), __VA_ARGS__)) - /*! Create a new reference of the current event `e` -* -* @details -* The current event processed by an active object is available only for -* the duration of the run-to-completion (RTC) step. After that step, the -* current event is no longer available and the framework might recycle -* (garbage-collect) the event. The macro Q_NEW_REF() explicitly creates -* a new reference to the current event that can be stored and used beyond -* the current RTC step, until the reference is explicitly recycled by -* means of the macro Q_DELETE_REF(). -* -* @param[in,out] evtRef_ event reference to create -* @param[in] evtT_ event type (class name) of the event reference -* -* @usage -* The example **defer** in the directory `examples/win32/defer` illustrates -* the use of Q_NEW_REF() -* -* @sa Q_DELETE_REF() -*/ @@ -2923,21 +4388,6 @@ return n + log2LUT[x]; - /*! Delete the event reference -* -* @details -* Every event reference created with the macro Q_NEW_REF() needs to be -* eventually deleted by means of the macro Q_DELETE_REF() to avoid leaking -* the event. -* -* @param[in,out] evtRef_ event reference to delete -* -* @usage -* The example **defer** in the directory `examples/win32/defer` illustrates -* the use of Q_DELETE_REF() -* -* @sa Q_NEW_REF() -*/ do { \ @@ -2947,24 +4397,6 @@ return n + log2LUT[x]; - /*! Virtual call to start an active object. -* -* @details -* Starts execution of the AO and registers the AO with the framework. -* -* @param[in,out] me_ current instance pointer (see @ref oop) -* @param[in] prioSpec_ priority specification for the Active Object -* @param[in] qSto_ pointer to the storage for the ring buffer of the -* event queue (used only with the built-in ::QEQueue) -* @param[in] qLen_ length of the event queue (in events) -* @param[in] stkSto_ pointer to the stack storage (used only when -* per-AO stack is needed) -* @param[in] stkSize_ stack size (in bytes) -* @param[in] par_ pointer to the additional port-specific parameter(s) -* (might be NULL). -* @usage -* @include qf_start.c -*/ @@ -2979,38 +4411,12 @@ return n + log2LUT[x]; - do { \ - Q_ASSERT((Q_HSM_UPCAST(me_))->vptr); \ - (*((QActiveVtable const *)((Q_HSM_UPCAST(me_))->vptr))->start)( \ - (QActive *)(me_), (prioSpec_), \ - (qSto_), (qLen_), (stkSto_), (stkSize_), (par_)); \ -} while (false) + \ + (QActive_start_((QActive *)(me_), (prioSpec_), \ + (qSto_), (qLen_), (stkSto_), (stkSize_), (par_))) - /*! Invoke the direct event posting facility QActive_post_() -* -* @details -* This macro asserts if the queue overflows and cannot accept the event. -* -* @param[in,out] me_ current instance pointer (see @ref oop) -* @param[in] e_ pointer to the event to post -* @param[in] sender_ pointer to the sender object. -* -* @note -* The `sendedr_` parameter is actually only used when QS tracing -* is enabled (macro #Q_SPY is defined). When QS software tracing is -* disenabled, the QACTIVE_POST() macro does not pass the `sender_` -* parameter, so the overhead of passing this extra parameter is entirely -* avoided. -* -* @note the pointer to the sender object is not necessarily a pointer -* to an active object. In fact, if QACTIVE_POST() is called from an -* interrupt or other context, you can create a unique object just to -* unambiguously identify the sender of the event. -* -* @sa QActive_post_() -*/ @@ -3018,8 +4424,7 @@ return n + log2LUT[x]; \ - ((void)(*((QActiveVtable const *)((Q_HSM_UPCAST(me_))->vptr))->post)(\ - (me_), (e_), QF_NO_MARGIN, (sender_))) + ((void)QActive_post_((me_), (e_), QF_NO_MARGIN, (sender_))) @@ -3030,46 +4435,10 @@ return n + log2LUT[x]; \ - ((void)(*((QActiveVtable const *)((Q_HSM_UPCAST(me_))->vptr))->post)(\ - (me_), (e_), QF_NO_MARGIN, (void *)0)) + ((void)QActive_post_((me_), (e_), QF_NO_MARGIN, (void *)0)) - /*! Invoke the direct event posting facility QActive_post_() -* without delivery guarantee -* -* @details -* This macro does not assert if the queue overflows and cannot accept -* the event with the specified margin of free slots remaining. -* -* @param[in,out] me_ current instance pointer (see @ref oop) -* @param[in] e_ pointer to the event to post -* @param[in] margin_ the minimum free slots in the queue, which -* must still be available after posting the event. -* The special value ::QF_NO_MARGIN causes -* asserting failure in case event posting fails. -* @param[in] sender_ pointer to the sender object. -* -* @returns -* 'true' if the posting succeeded, and 'false' if the posting -* failed due to insufficient margin of free entries available in -* the queue. -* -* @note -* The `sender_` parameter is actually only used when QS tracing -* is enabled (macro #Q_SPY is defined). When QS software tracing is -* disabled, the POST_X() macro does not pass the `sender_` parameter, -* so the overhead of passing this extra parameter is entirely avoided. -* -* @note -* The pointer to the sender object is not necessarily a pointer -* to an active object. In fact, if POST_X() is called from an -* interrupt or other context, you can create a unique object just to -* unambiguously identify the sender of the event. -* -* @usage -* @include qf_postx.c -*/ @@ -3079,8 +4448,7 @@ return n + log2LUT[x]; \ - ((*((QActiveVtable const *)((Q_HSM_UPCAST(me_))->vptr))->post)((me_),\ - (e_), (margin_), (sender_))) + (QActive_post_((me_), (e_), (margin_), (sender_))) @@ -3093,47 +4461,19 @@ return n + log2LUT[x]; \ - ((*((QActiveVtable const *)((Q_HSM_UPCAST(me_))->vptr))->post)((me_),\ - (e_), (margin_), (void *)0)) + (QActive_post_((me_), (e_), (margin_), (void *)0)) - /*! Virtual call to post an event to an active object using the -* Last-In-First-Out (LIFO) policy. -* -* @param[in,out] me_ current instance pointer (see @ref oop) -* @param[in] e_ pointer to the event to post -*/ - \ - ((*((QActiveVtable const *)((Q_HSM_UPCAST(me_))->vptr))->postLIFO)( \ - (me_), (e_))) + (QActive_postLIFO_((me_), (e_))) - /*! Publish an event to all subscriber Active Objects. -* -* @details -* If #Q_SPY is defined, this macro calls QActive_publish_() with -* the `sender_` parameter to identify the publisher of the event. -* Otherwise, `sender_` is not used. -* -* @param[in] e_ pointer to the posted event -* @param[in] sender_ pointer to the sender object (actually used -* only when #Q_SPY is defined) -* -* @note -* The pointer to the `sender_` object is not necessarily a pointer -* to an active object. In fact, if QACTIVE_PUBLISH() is called from an -* interrupt or other context, you can create a unique object just to -* unambiguously identify the sender of the event. -* -* @sa QActive_publish_() -*/ @@ -3151,36 +4491,11 @@ return n + log2LUT[x]; - /*! Invoke the system clock tick processing QTimeEvt_tick_() -* -* @details -* This macro is the recommended way of invoking clock tick processing, -* because it provides the vital information for software tracing and -* avoids any overhead when the tracing is disabled. -* -* @param[in] tickRate_ clock tick rate to be serviced through this call -* @param[in] sender_ pointer to the sender object. This parameter -* is actually only used when QS software tracing is enabled -* (macro #Q_SPY is defined) -* @note -* When QS software tracing is disabled, the macro calls QTimeEvt_tick_() -* without the `sender` parameter, so the overhead of passing this -* extra parameter is entirely avoided. -* -* @note -* The pointer to the sender object is not necessarily a pointer -* to an active object. In fact, when QTIMEEVT_TICK_X() is called from -* an interrupt, you would create a unique object just to unambiguously -* identify the ISR as the sender of the time events. -* -* @sa QTimeEvt_tick_() -*/ - \ - (QTimeEvt_tick_((tickRate_), (sender_))) + (QTimeEvt_tick_((tickRate_), (sender_))) @@ -3188,40 +4503,36 @@ return n + log2LUT[x]; - \ - (QTimeEvt_tick_((tickRate_), (void *)0)) + (QTimeEvt_tick_((tickRate_), (void *)0)) - /*! Invoke the system clock tick processing -* for tick rate 0 -*/ QTIMEEVT_TICK_X(0U, (sender_)) + + + + + + + (QTicker_trig_((ticker_), (sender_))) + + + + + + + + (QTicker_trig_((ticker_), (void *)0)) + - /*! No-operation for exiting a critical section -* -* @details -* In some QF ports the critical section exit takes effect only on the -* next machine instruction. If this next instruction is another entry -* to a critical section, the critical section won't be really exited, -* but rather the two adjecent critical sections would be merged. -* The QF_CRIT_EXIT_NOP() macro contains minimal code required to -* prevent such merging of critical sections in such merging of -* critical sections in QF ports, in which it can occur. -*/ ((void)0) - /*! Invoke the system clock tick processing -* -* @deprecated -* superseded by QTIMEEVT_TICK_X() -*/ @@ -3230,3591 +4541,3664 @@ return n + log2LUT[x]; - /*! Invoke the system clock tick processing for tick rate 0 -* -* @deprecated -* superseded by QTIMEEVT_TICK() -*/ QTIMEEVT_TICK(sender_) - /*! Publish an event to all subscriber Active Objects. -* -* @deprecated -* superseded by QACTIVE_PUBLISH() -*/ QACTIVE_PUBLISH((e_), (sender_)) + + + ((void)0) + + + + ((void)0) + - - - - - /*! @brief Active object class (based on the QHsm implementation strategy) -* @class QActive -* @extends QHsm -* -* @details -* Active objects are encapsulated tasks (each containing an event queue and -* a state machine) that communicate with one another asynchronously by -* sending and receiving events. Within an active object, events are -* processed in a run-to-completion (RTC) fashion, while QF encapsulates -* all the details of thread-safe event exchange and queuing.<br> -* -* QActive represents an active object that uses the QHsm-style -* implementation strategy for state machines. This strategy is tailored -* to manual coding, but it is also supported by the QM modeling tool. -* The resulting code is slower than in the ::QMsm-style implementation -* strategy. -* -* @note -* QActive is not intended to be instantiated directly, but rather serves -* as the abstract base class for derivation of active objects in the -* applications. -* -* @sa QMActive -* -* @usage -* The following example illustrates how to derive an active object from -* QActive. -* @include qf_qactive.c -*/ - - - /*! OS-dependent event-queue type -* @private @memberof QActive -* -* @details -* The type of the queue depends on the underlying operating system or -* a kernel. Many kernels support "message queues" that can be adapted -* to deliver QF events to the active object. Alternatively, QF provides -* a native event queue implementation that can be used as well. -* -* @note -* The native QF event queue is configured by defining the macro -* #QF_EQUEUE_TYPE as ::QEQueue. -*/ - - - - /*! OS-dependent per-thread object -* @private @memberof QActive -* -* @details -* This data might be used in various ways, depending on the QF port. -* In some ports me->osObject is used to block the calling thread when -* the native QF queue is empty. In other QF ports the OS-dependent -* object might be used differently. -*/ - - - - /*! OS-dependent representation of the thread of the active object -* @private @memberof QActive -* -* @details -* This data might be used in various ways, depending on the QF port. -* In some ports me->thread is used store the thread handle. In other ports -* me->thread can be a pointer to the Thread-Local-Storage (TLS). -*/ - - - - /*! QF-priority [1..#QF_MAX_ACTIVE] of this AO. -* @private @memberof QActive -* @sa ::QPrioSpec -*/ - - - - /*! preemption-threshold [1..#QF_MAX_ACTIVE] of this AO. -* @private @memberof QActive -* @sa ::QPrioSpec -*/ - - - - /*! Internal array of registered active objects -* @static @private @memberof QActive -*/ - - - - /*! pointer to the array of all subscriber AOs for a given event signal. -* @static @private @memberof QActive -*/ - - - - /*! The maximum published signal (the size of the subscrList_ array) -* @static @private @memberof QActive -*/ - - - - /*! Internal array of registered active objects -* @static @private @memberof QActive -*/ - - - - /*! ::QActive constructor (abstract base class) -* @protected @memberof QActive -*/ - - - static QActiveVtable const vtable = { /* QActive virtual table */ - { &QHsm_init_, - &QHsm_dispatch_ -#ifdef Q_SPY - ,&QHsm_getStateHandler_ -#endif - }, - &QActive_start_, - &QActive_post_, - &QActive_postLIFO_ -}; -/* clear the whole QActive object, so that the framework can start -* correctly even if the startup code fails to clear the uninitialized -* data (as is required by the C Standard). -*/ -QF_bzero(me, sizeof(*me)); - -QHsm_ctor(&me->super, initial); /* explicitly call superclass' ctor */ -me->super.vptr = &vtable.super; /* hook the vptr to QActive vtable */ - - - - /*! Starts execution of an active object and registers the object -* with the framework -* @private @memberof QActive -* -* @details -* Starts execution of the AO and registers the AO with the framework. -* -* @param[in] prioSpec priority specification for the AO (See ::QPrioSpec) -* @param[in] qSto pointer to the storage for the ring buffer of the -* event queue -* @param[in] qLen length of the event queue [# ::QEvt* pointers] -* @param[in] stkSto pointer to the stack storage (might be NULL) -* @param[in] stkSize stack size [bytes] -* @param[in] par pointer to an extra parameter (might be NULL) -* -* @usage -* The following example shows starting an AO when a per-task stack -* is needed: -* @include qf_start.c -*/ - - - - - - - - - - - - - - - - /*! Stops execution of an active object and removes it from the -* framework's supervision -* @protected @memberof QActive -* -* @attention -* QActive_stop() must be called only from the AO that is about -* to stop its execution. By that time, any pointers or references -* to the AO are considered invalid (dangling) and it becomes -* illegal for the rest of the application to post events to the AO. -*/ - - - - /*! Posts an event `e` directly to the event queue of the active object -* using the First-In-First-Out (FIFO) policy. -* @private @memberof QActive -* -* @details -* Direct event posting is the simplest asynchronous communication -* method available in QF. -* -* @param[in] e pointer to the event to be posted -* @param[in] margin number of required free slots in the queue -* after posting the event or ::QF_NO_MARGIN. -* @param[in] sender pointer to a sender object (used in QS only) -* -* @returns -* 'true' (success) if the posting succeeded (with the provided margin) -* and 'false' (failure) when the posting fails. -* -* @attention -* For `margin` == ::QF_NO_MARGIN, this function will assert internally -* if the event posting fails. In that case, it is unnecessary to check -* the retrun value from this function. -* -* @note -* This function might be implemented differently in various QP/C++ -* ports. The provided implementation assumes that the ::QEQueue -* class is used for the ::QActive event queue. -* -* @usage -* @include qf_post.cpp -* -* @sa -* QActive_postLIFO() -*/ - - - - - - - #ifndef Q_SPY -Q_UNUSED_PAR(sender); -#endif - -/*! @pre event pointer must be valid */ -Q_REQUIRE_ID(100, e != (QEvt *)0); - -QF_CRIT_STAT_ -QF_CRIT_E_(); -QEQueueCtr nFree = me->eQueue.nFree; /* get volatile into the temporary */ - -/* test-probe#1 for faking queue overflow */ -QS_TEST_PROBE_DEF(&QActive_post_) -QS_TEST_PROBE_ID(1, - nFree = 0U; -) - -bool status; -if (margin == QF_NO_MARGIN) { - if (nFree > 0U) { - status = true; /* can post */ - } - else { - status = false; /* cannot post */ - Q_ERROR_CRIT_(110); /* must be able to post the event */ - } -} -else if (nFree > (QEQueueCtr)margin) { - status = true; /* can post */ -} -else { - status = false; /* cannot post, but don't assert */ -} - -/* is it a dynamic event? */ -if (e->poolId_ != 0U) { - QEvt_refCtr_inc_(e); /* increment the reference counter */ -} - -if (status) { /* can post the event? */ - - --nFree; /* one free entry just used up */ - me->eQueue.nFree = nFree; /* update the volatile */ - if (me->eQueue.nMin > nFree) { - me->eQueue.nMin = nFree; /* increase minimum so far */ - } - - QS_BEGIN_NOCRIT_PRE_(QS_QF_ACTIVE_POST, me->prio) - QS_TIME_PRE_(); /* timestamp */ - QS_OBJ_PRE_(sender); /* the sender object */ - QS_SIG_PRE_(e->sig); /* the signal of the event */ - QS_OBJ_PRE_(me); /* this active object (recipient) */ - QS_2U8_PRE_(e->poolId_, e->refCtr_); /* pool Id & ref Count */ - QS_EQC_PRE_(nFree); /* number of free entries */ - QS_EQC_PRE_(me->eQueue.nMin); /* min number of free entries */ - QS_END_NOCRIT_PRE_() - -#ifdef Q_UTEST - /* callback to examine the posted event under the same conditions - * as producing the #QS_QF_ACTIVE_POST trace record, which are: - * the local filter for this AO ('me->prio') is set - */ - if (QS_LOC_CHECK_(me->prio)) { - /* callback to examine the posted event */ - QS_onTestPost(sender, me, e, status); - } -#endif - - /* empty queue? */ - if (me->eQueue.frontEvt == (QEvt *)0) { - me->eQueue.frontEvt = e; /* deliver event directly */ - QACTIVE_EQUEUE_SIGNAL_(me); /* signal the event queue */ - } - /* queue is not empty, insert event into the ring-buffer */ - else { - /* insert event into the ring buffer (FIFO) */ - me->eQueue.ring[me->eQueue.head] = e; - - if (me->eQueue.head == 0U) { /* need to wrap head? */ - me->eQueue.head = me->eQueue.end; /* wrap around */ - } - --me->eQueue.head; /* advance the head (counter clockwise) */ - } - - QF_CRIT_X_(); -} -else { /* cannot post the event */ - - QS_BEGIN_NOCRIT_PRE_(QS_QF_ACTIVE_POST_ATTEMPT, me->prio) - QS_TIME_PRE_(); /* timestamp */ - QS_OBJ_PRE_(sender); /* the sender object */ - QS_SIG_PRE_(e->sig); /* the signal of the event */ - QS_OBJ_PRE_(me); /* this active object (recipient) */ - QS_2U8_PRE_(e->poolId_, e->refCtr_); /* pool Id & ref Count */ - QS_EQC_PRE_(nFree); /* number of free entries */ - QS_EQC_PRE_(margin); /* margin requested */ - QS_END_NOCRIT_PRE_() - -#ifdef Q_UTEST - /* callback to examine the posted event under the same conditions - * as producing the #QS_QF_ACTIVE_POST trace record, which are: - * the local filter for this AO ('me->prio') is set - */ - if (QS_LOC_CHECK_(me->prio)) { - QS_onTestPost(sender, me, e, status); - } -#endif - - QF_CRIT_X_(); - -#if (QF_MAX_EPOOL > 0U) - QF_gc(e); /* recycle the event to avoid a leak */ -#endif -} - -return status; - - - - /*! Posts an event `e` directly to the event queue of the active object -* using the Last-In-First-Out (LIFO) policy. -* @private @memberof QActive -* -* @details -* The LIFO policy should be used only for self-posting and with caution, -* because it alters order of events in the queue. -* -* @param[in] e pointer to the event to be posted -* -* @attention -* This function asserts internally if the posting fails. -* -* @note -* This function might be implemented differently in various QP/C++ -* ports. The provided implementation assumes that the ::QEQueue -* class is used for the QActive event queue. -* -* @sa -* QActive_post() -*/ - - - QF_CRIT_STAT_ -QF_CRIT_E_(); -QEQueueCtr nFree = me->eQueue.nFree; /* get volatile into the temporary */ - -/* test-probe#1 for faking queue overflow */ -QS_TEST_PROBE_DEF(&QActive_postLIFO_) -QS_TEST_PROBE_ID(1, - nFree = 0U; -) - -/* the queue must be able to accept the event (cannot overflow) */ -Q_ASSERT_CRIT_(210, nFree != 0U); - -/* is it a dynamic event? */ -if (e->poolId_ != 0U) { - QEvt_refCtr_inc_(e); /* increment the reference counter */ -} - ---nFree; /* one free entry just used up */ -me->eQueue.nFree = nFree; /* update the volatile */ -if (me->eQueue.nMin > nFree) { - me->eQueue.nMin = nFree; /* update minimum so far */ -} - -QS_BEGIN_NOCRIT_PRE_(QS_QF_ACTIVE_POST_LIFO, me->prio) - QS_TIME_PRE_(); /* timestamp */ - QS_SIG_PRE_(e->sig); /* the signal of this event */ - QS_OBJ_PRE_(me); /* this active object */ - QS_2U8_PRE_(e->poolId_, e->refCtr_);/* pool Id & ref Count */ - QS_EQC_PRE_(nFree); /* # free entries */ - QS_EQC_PRE_(me->eQueue.nMin); /* min number of free entries */ -QS_END_NOCRIT_PRE_() - -#ifdef Q_UTEST - /* callback to examine the posted event under the same conditions - * as producing the #QS_QF_ACTIVE_POST trace record, which are: - * the local filter for this AO ('me->prio') is set - */ - if (QS_LOC_CHECK_(me->prio)) { - QS_onTestPost((QActive *)0, me, e, true); - } -#endif - -/* temporary to avoid UB for volatile access */ -QEvt const * const frontEvt = me->eQueue.frontEvt; -me->eQueue.frontEvt = e; /* deliver the event directly to the front */ - -/* was the queue empty? */ -if (frontEvt == (QEvt *)0) { - QACTIVE_EQUEUE_SIGNAL_(me); /* signal the event queue */ -} -/* queue was not empty, leave the event in the ring-buffer */ -else { - ++me->eQueue.tail; - /* need to wrap the tail? */ - if (me->eQueue.tail == me->eQueue.end) { - me->eQueue.tail = 0U; /* wrap around */ - } - - me->eQueue.ring[me->eQueue.tail] = frontEvt; -} -QF_CRIT_X_(); - - - - /*! Get an event from the event queue of an active object -* @private @memberof QActive -* -* @details -* The behavior of this function depends on the kernel used in the -* QF port. For built-in kernels (Vanilla or QK) the function can be -* called only when the queue is not empty, so it doesn't block. For -* a blocking kernel/OS the function can block and wait for delivery -* of an event. -* -* @returns -* A pointer to the received event. The returned pointer is guaranteed -* to be valid (can't be NULL). -* -* @note -* This function might be implemented differently in various QP/C++ -* ports. The provided implementation assumes that the ::QEQueue -* class is used for the QActive event queue. -*/ - QF_CRIT_STAT_ -QF_CRIT_E_(); -QACTIVE_EQUEUE_WAIT_(me); /* wait for event to arrive directly */ - -/* always remove event from the front */ -QEvt const * const e = me->eQueue.frontEvt; -QEQueueCtr const nFree = me->eQueue.nFree + 1U; /* volatile into tmp */ -me->eQueue.nFree = nFree; /* update the number of free */ - -/* any events in the ring buffer? */ -if (nFree <= me->eQueue.end) { - - /* remove event from the tail */ - me->eQueue.frontEvt = me->eQueue.ring[me->eQueue.tail]; - if (me->eQueue.tail == 0U) { /* need to wrap the tail? */ - me->eQueue.tail = me->eQueue.end; /* wrap around */ - } - --me->eQueue.tail; - - QS_BEGIN_NOCRIT_PRE_(QS_QF_ACTIVE_GET, me->prio) - QS_TIME_PRE_(); /* timestamp */ - QS_SIG_PRE_(e->sig); /* the signal of this event */ - QS_OBJ_PRE_(me); /* this active object */ - QS_2U8_PRE_(e->poolId_, e->refCtr_); /* pool Id & ref Count */ - QS_EQC_PRE_(nFree); /* # free entries */ - QS_END_NOCRIT_PRE_() -} -else { - me->eQueue.frontEvt = (QEvt *)0; /* queue becomes empty */ - - /* all entries in the queue must be free (+1 for fronEvt) */ - Q_ASSERT_CRIT_(310, nFree == (me->eQueue.end + 1U)); - - QS_BEGIN_NOCRIT_PRE_(QS_QF_ACTIVE_GET_LAST, me->prio) - QS_TIME_PRE_(); /* timestamp */ - QS_SIG_PRE_(e->sig); /* the signal of this event */ - QS_OBJ_PRE_(me); /* this active object */ - QS_2U8_PRE_(e->poolId_, e->refCtr_); /* pool Id & ref Count */ - QS_END_NOCRIT_PRE_() -} -QF_CRIT_X_(); -return e; - - - - const - /*! Subscribes for delivery of signal `sig` to the active object -* @public @memberof QActive -* -* @details -* This function is part of the Publish-Subscribe event delivery -* mechanism available in QF. Subscribing to an event means that the -* framework will start posting all published events with a given signal -* `sig` to the event queue of the active object. -* -* @param[in] sig event signal to subscribe -* -* The following example shows how the Table active object subscribes -* to three signals in the initial transition: -* @include qf_subscribe.cpp -* -* @sa -* QActive_publish_(), QActive_unsubscribe(), and -* QActive_unsubscribeAll() -*/ - - - uint_fast8_t const p = (uint_fast8_t)me->prio; - -Q_REQUIRE_ID(300, ((enum_t)Q_USER_SIG <= sig) - && (sig < QActive_maxPubSignal_) - && (0U < p) && (p <= QF_MAX_ACTIVE) - && (QActive_registry_[p] == me)); - -QF_CRIT_STAT_ -QF_CRIT_E_(); - -QS_BEGIN_NOCRIT_PRE_(QS_QF_ACTIVE_SUBSCRIBE, me->prio) - QS_TIME_PRE_(); /* timestamp */ - QS_SIG_PRE_(sig); /* the signal of this event */ - QS_OBJ_PRE_(me); /* this active object */ -QS_END_NOCRIT_PRE_() - -/* set the priority bit */ -QPSet_insert(&QActive_subscrList_[sig], p); - -QF_CRIT_X_(); - - - - const - /*! Unsubscribes from the delivery of signal `sig` to the active object -* @public @memberof QActive -* -* @details -* This function is part of the Publish-Subscribe event delivery -* mechanism available in QF. Un-subscribing from an event means that -* the framework will stop posting published events with a given signal -* `sig` to the event queue of the active object. -* -* @param[in] sig event signal to unsubscribe -* -* @note -* Due to the latency of event queues, an active object should NOT -* assume that a given signal `sig` will never be dispatched to the -* state machine of the active object after un-subscribing from that -* signal. The event might be already in the queue, or just about to -* be posted and the un-subscribe operation will not flush such events. -* -* @note -* Un-subscribing from a signal that has never been subscribed in the -* first place is considered an error and QF will raise an assertion. -* -* @sa -* QActive_publish_(), QActive_subscribe(), and -* QActive_unsubscribeAll() -*/ - - - uint_fast8_t const p = (uint_fast8_t)me->prio; - -/*! @pre the singal and the prioriy must be in ragne, the AO must also -* be registered with the framework -*/ -Q_REQUIRE_ID(400, ((enum_t)Q_USER_SIG <= sig) - && (sig < QActive_maxPubSignal_) - && (0U < p) && (p <= QF_MAX_ACTIVE) - && (QActive_registry_[p] == me)); - -QF_CRIT_STAT_ -QF_CRIT_E_(); - -QS_BEGIN_NOCRIT_PRE_(QS_QF_ACTIVE_UNSUBSCRIBE, me->prio) - QS_TIME_PRE_(); /* timestamp */ - QS_SIG_PRE_(sig); /* the signal of this event */ - QS_OBJ_PRE_(me); /* this active object */ -QS_END_NOCRIT_PRE_() - -/* clear priority bit */ -QPSet_remove(&QActive_subscrList_[sig], p); - -QF_CRIT_X_(); - - - - const - /*! Unsubscribes from the delivery of all signals to the active object -* @public @memberof QActive -* -* @details -* This function is part of the Publish-Subscribe event delivery -* mechanism available in QF. Un-subscribing from all events means that -* the framework will stop posting any published events to the event -* queue of the active object. -* -* @note -* Due to the latency of event queues, an active object should NOT -* assume that no events will ever be dispatched to the state machine of -* the active object after un-subscribing from all events. -* The events might be already in the queue, or just about to be posted -* and the un-subscribe operation will not flush such events. Also, the -* alternative event-delivery mechanisms, such as direct event posting or -* time events, can be still delivered to the event queue of the active -* object. -* -* @sa -* QActive_publish_(), QActive_subscribe(), and QActive_unsubscribe() -*/ - uint_fast8_t const p = (uint_fast8_t)me->prio; - -Q_REQUIRE_ID(500, (0U < p) && (p <= QF_MAX_ACTIVE) - && (QActive_registry_[p] == me)); - -for (enum_t sig = (enum_t)Q_USER_SIG; sig < QActive_maxPubSignal_; ++sig) { - QF_CRIT_STAT_ - QF_CRIT_E_(); - if (QPSet_hasElement(&QActive_subscrList_[sig], p)) { - QPSet_remove(&QActive_subscrList_[sig], p); - - QS_BEGIN_NOCRIT_PRE_(QS_QF_ACTIVE_UNSUBSCRIBE, me->prio) - QS_TIME_PRE_(); /* timestamp */ - QS_SIG_PRE_(sig); /* the signal of this event */ - QS_OBJ_PRE_(me); /* this active object */ - QS_END_NOCRIT_PRE_() - } - QF_CRIT_X_(); - - /* prevent merging critical sections */ - QF_CRIT_EXIT_NOP(); -} - - - - /*! Publish event to all subscribers of a given signal `e->sig` -* @static @public @memberof QActive -* -* @details -* This function posts (using the FIFO policy) the event @a e to **all** -* active objects that have subscribed to the signal @a e->sig, which is -* called _multicasting_. The multicasting performed in this function is -* very efficient based on reference-counting inside the published event -* ("zero-copy" event multicasting). This function is designed to be -* callable from any part of the system, including ISRs, device drivers, -* and active objects. -* -* @note -* To avoid any unexpected re-ordering of events posted into AO queues, -* the event multicasting is performed with scheduler **locked**. -* However, the scheduler is locked only up to the priority level of -* the highest-priority subscriber, so any AOs of even higher priority, -* which did not subscribe to this event are *not* affected. -*/ - - - - - QActive_subscrList_ = subscrSto; -QActive_maxPubSignal_ = maxSignal; - -/* zero the subscriber list, so that the framework can start correctly -* even if the startup code fails to clear the uninitialized data -* (as is required by the C Standard). -*/ -QF_bzero(subscrSto, (uint_fast16_t)maxSignal * sizeof(QSubscrList)); - - - - /*! Publish event to all subscribers of a given signal `e->sig` -* @static @private @memberof QActive -* -* @details -* This function posts (using the FIFO policy) the event @a e to **all** -* active objects that have subscribed to the signal @a e->sig, which is -* called _multicasting_. The multicasting performed in this function is -* very efficient based on reference-counting inside the published event -* ("zero-copy" event multicasting). This function is designed to be -* callable from any part of the system, including ISRs, device drivers, -* and active objects. -* -* @note -* To avoid any unexpected re-ordering of events posted into AO queues, -* the event multicasting is performed with scheduler **locked**. -* However, the scheduler is locked only up to the priority level of -* the highest-priority subscriber, so any AOs of even higher priority, -* which did not subscribe to this event are *not* affected. -*/ - - - - - - - #ifndef Q_SPY -Q_UNUSED_PAR(sender); -Q_UNUSED_PAR(qs_id); -#endif - -/*! @pre the published signal must be within the configured range */ -Q_REQUIRE_ID(200, e->sig < (QSignal)QActive_maxPubSignal_); - -QF_CRIT_STAT_ -QF_CRIT_E_(); - -QS_BEGIN_NOCRIT_PRE_(QS_QF_PUBLISH, qs_id) - QS_TIME_PRE_(); /* the timestamp */ - QS_OBJ_PRE_(sender); /* the sender object */ - QS_SIG_PRE_(e->sig); /* the signal of the event */ - QS_2U8_PRE_(e->poolId_, e->refCtr_);/* pool Id & ref Count */ -QS_END_NOCRIT_PRE_() - -/* is it a dynamic event? */ -if (e->poolId_ != 0U) { - /* NOTE: The reference counter of a dynamic event is incremented to - * prevent premature recycling of the event while the multicasting - * is still in progress. At the end of the function, the garbage - * collector step (QF_gc()) decrements the reference counter and - * recycles the event if the counter drops to zero. This covers the - * case when the event was published without any subscribers. - */ - QEvt_refCtr_inc_(e); -} - -/* make a local, modifiable copy of the subscriber list */ -QPSet subscrList = QActive_subscrList_[e->sig]; -QF_CRIT_X_(); - -if (QPSet_notEmpty(&subscrList)) { /* any subscribers? */ - /* the highest-prio subscriber */ - uint_fast8_t p = QPSet_findMax(&subscrList); - QActive *a = QActive_registry_[p]; - QF_SCHED_STAT_ - - QF_SCHED_LOCK_(a->prio); /* lock the scheduler up to AO's prio */ - do { /* loop over all subscribers */ - /* the prio of the AO must be registered with the framework */ - Q_ASSERT_ID(210, a != (QActive *)0); - - /* QACTIVE_POST() asserts internally if the queue overflows */ - QACTIVE_POST(a, e, sender); - - QPSet_remove(&subscrList, p); /* remove the handled subscriber */ - if (QPSet_notEmpty(&subscrList)) { /* still more subscribers? */ - /* highest-prio subscriber */ - p = QPSet_findMax(&subscrList); - a = QActive_registry_[p]; - } - else { - p = 0U; /* no more subscribers */ - } - } while (p != 0U); - QF_SCHED_UNLOCK_(); /* unlock the scheduler */ -} - -/* The following garbage collection step decrements the reference counter -* and recycles the event if the counter drops to zero. This covers both -* cases when the event was published with or without any subscribers. -*/ -#if (QF_MAX_EPOOL > 0U) -QF_gc(e); /* recycle the event to avoid a leak */ -#endif - - - - - const - /*! Defer an event to a given separate event queue -* @protected @memberof QActive -* -* @details -* This function is part of the event deferral support. An active object -* uses this function to defer an event `e` to the QF-supported native -* event queue `eq`. QF correctly accounts for another outstanding -* reference to the event and will not recycle the event at the end of -* the RTC step. Later, the active object might recall one event at a -* time from the event queue. -* -* @param[in] eq pointer to a "raw" thread-safe queue to recall -* an event from. -* @param[in] e pointer to the event to be deferred -* -* @returns -* 'true' (success) when the event could be deferred and 'false' -* (failure) if event deferral failed due to overflowing the queue. -* -* An active object can use multiple event queues to defer events of -* different kinds. -* -* @sa -* QActive_recall(), ::QEQueue, QActive_flushDeferred() -*/ - - - - - bool const status = QEQueue_post(eq, e, 0U, me->prio); -QS_CRIT_STAT_ - -QS_BEGIN_PRE_(QS_QF_ACTIVE_DEFER, me->prio) - QS_TIME_PRE_(); /* time stamp */ - QS_OBJ_PRE_(me); /* this active object */ - QS_OBJ_PRE_(eq); /* the deferred queue */ - QS_SIG_PRE_(e->sig); /* the signal of the event */ - QS_2U8_PRE_(e->poolId_, e->refCtr_); /* pool Id & ref Count */ -QS_END_PRE_() - -return status; - - - - /*! Recall a deferred event from a given event queue -* @protected @memberof QActive -* -* @details -* This function is part of the event deferral support. An active object -* uses this function to recall a deferred event from a given QF -* event queue. Recalling an event means that it is removed from the -* deferred event queue `eq` and posted (LIFO) to the event queue of -* the active object. -* -* @param[in] eq pointer to a "raw" thread-safe queue to recall -* an event from. -* -* @returns -* 'true' if an event has been recalled and 'false' if not. -* -* @note -* An active object can use multiple event queues to defer events of -* different kinds. -* -* @sa -* QActive_recall(), QActive_postLIFO_(), ::QEQueue -*/ - - - QEvt const * const e = QEQueue_get(eq, me->prio); -bool recalled; - -/* event available? */ -if (e != (QEvt *)0) { - QF_CRIT_STAT_ - - QACTIVE_POST_LIFO(me, e); /* post it to the front of the AO's queue */ - - QF_CRIT_E_(); - - /* is it a dynamic event? */ - if (e->poolId_ != 0U) { - - /* after posting to the AO's queue the event must be referenced - * at least twice: once in the deferred event queue (eq->get() - * did NOT decrement the reference counter) and once in the - * AO's event queue. - */ - Q_ASSERT_CRIT_(210, e->refCtr_ >= 2U); - - /* we need to decrement the reference counter once, to account - * for removing the event from the deferred event queue. - */ - QEvt_refCtr_dec_(e); /* decrement the reference counter */ - } - - QS_BEGIN_NOCRIT_PRE_(QS_QF_ACTIVE_RECALL, me->prio) - QS_TIME_PRE_(); /* time stamp */ - QS_OBJ_PRE_(me); /* this active object */ - QS_OBJ_PRE_(eq); /* the deferred queue */ - QS_SIG_PRE_(e->sig); /* the signal of the event */ - QS_2U8_PRE_(e->poolId_, e->refCtr_); /* pool Id & ref Count */ - QS_END_NOCRIT_PRE_() - - QF_CRIT_X_(); - recalled = true; -} -else { - QS_CRIT_STAT_ - - QS_BEGIN_PRE_(QS_QF_ACTIVE_RECALL_ATTEMPT, me->prio) - QS_TIME_PRE_(); /* time stamp */ - QS_OBJ_PRE_(me); /* this active object */ - QS_OBJ_PRE_(eq); /* the deferred queue */ - QS_END_PRE_() - - recalled = false; -} -return recalled; - - - - const - /*! Flush the specified deferred queue 'eq' -* @protected @memberof QActive -* -* @details -* This function is part of the event deferral support. An active object -* can use this function to flush a given QF event queue. The function -* makes sure that the events are not leaked. -* -* @param[in] eq pointer to a "raw" thread-safe queue to flush. -* -* @returns -* the number of events actually flushed from the queue. -* -* @sa -* QActive_defer(), QActive_recall(), ::QEQueue -*/ - - - uint_fast16_t n = 0U; -for (QEvt const *e = QEQueue_get(eq, me->prio); - e != (QEvt *)0; - e = QEQueue_get(eq, me->prio)) -{ - ++n; /* count the flushed event */ -#if (QF_MAX_EPOOL > 0U) - QF_gc(e); /* garbage collect */ -#endif -} -return n; - - - - /*! Generic setting of additional attributes (useful in QP ports) -* @public @memberof QActive -*/ - - - - - - - - /*! Thread routine for executing an active object `act` -* @private @memberof QActive -*/ - - - - - - /*! Register this active object to be managed by the framework -* @protected @memberof QActive -* -* @details -* This function adds a given active object to the active objects -* managed by the QF framework. It should not be called by the -* application directly, only through the function QActive::start(). -* -* @note -* The priority of the active object a should be set before calling -* this function. -* -* @sa QActive_unregister_() -*/ - if (me->pthre == 0U) { /* preemption-threshold not defined? */ - me->pthre = me->prio; /* apply the default */ -} - -#ifndef Q_NASSERT - -/*! @pre -* 1. the "QF-priority" of the AO must be in range -* 2. the "QF-priority" must not be already in use (unique priority) -* 3. the "QF-priority" must not exceed the "preemption-threshold" -*/ -Q_REQUIRE_ID(100, (0U < me->prio) && (me->prio <= QF_MAX_ACTIVE) - && (QActive_registry_[me->prio] == (QActive *)0) - && (me->prio <= me->pthre)); - -uint8_t prev_thre = me->pthre; -uint8_t next_thre = me->pthre; -uint_fast8_t p; - -for (p = (uint_fast8_t)me->prio - 1U; p > 0U; --p) { - if (QActive_registry_[p] != (QActive *)0) { - prev_thre = QActive_registry_[p]->pthre; - break; - } -} -for (p = (uint_fast8_t)me->prio + 1U; p <= QF_MAX_ACTIVE; ++p) { - if (QActive_registry_[p] != (QActive *)0) { - next_thre = QActive_registry_[p]->pthre; - break; - } -} - -/*! @post -* 1. the preceding pre-thre must not exceed the preemption-threshold -* 2. the preemption-threshold must not exceed the next pre-thre -*/ -Q_ENSURE_ID(101, (prev_thre <= me->pthre) && (me->pthre <= next_thre)); - -#endif // Q_NASSERT - -QF_CRIT_STAT_ -QF_CRIT_E_(); -/* register the AO at the "QF-priority" */ -QActive_registry_[me->prio] = me; -QF_CRIT_X_(); - - - - /*! Un-register the active object from the framework -* @protected @memberof QActive -* -* @details -* This function un-registers a given active object from the active objects -* managed by the QF framework. It should not be called by the QP ports. -* -* @param[in] me pointer to the active object to remove from the -* framework. -* -* @note -* The active object that is removed from the framework can no longer -* participate in any event exchange. -* -* @sa QActive_register_() -*/ - uint_fast8_t const p = (uint_fast8_t)me->prio; - -/*! @pre the priority of the active object must not be zero and cannot -* exceed the maximum #QF_MAX_ACTIVE. Also, the priority of the active -* object must be already registered with the framework. -*/ -Q_REQUIRE_ID(200, (0U < p) && (p <= QF_MAX_ACTIVE) - && (QActive_registry_[p] == me)); -QF_CRIT_STAT_ -QF_CRIT_E_(); -QActive_registry_[p] = (QActive *)0; /* free-up the priority level */ -me->super.state.fun = Q_STATE_CAST(0); /* invalidate the state */ -QF_CRIT_X_(); - - - - /*! the "FromISR" variant used in the QP port to "FreeRTOS" -* @private @memberof QActive -*/ - - - - - - - - - - - - /*! the "FromISR" variant used in the QP port to "FreeRTOS" -* @private @memberof QActive -*/ - - - - - - - - - - - /*! @brief Virtual table for the QActive class */ - { - struct QHsmVtable super; /*!< @protected inherits ::QHsmVtable */ - - /*! @private virtual function to start the AO/thread - * @sa QACTIVE_START() - */ - void (*start)(QActive * const me, QPrioSpec prio, - QEvt const * * const qSto, uint_fast16_t const qLen, - void * const stkSto, uint_fast16_t const stkSize, - void const * const par); - - /*! @private virtual function to asynchronously post (FIFO) - * an event to the AO - * @sa QACTIVE_POST() and QACTIVE_POST_X() - */ - bool (*post)(QActive * const me, QEvt const * const e, - uint_fast16_t const margin, void const * const sender); - - /*! @private virtual function to asynchronously post (LIFO) - * an event to the AO - * @sa QACTIVE_POST_LIFO() - */ - void (*postLIFO)(QActive * const me, QEvt const * const e); - -} QActiveVtable; - - - - /*! @brief Active object class (based on QMsm implementation strategy) -* @class QMActive -* @extends QActive -* -* @details -* ::QMActive represents an active object that uses the ::QMsm style state -* machine implementation strategy. This strategy requires the use of the -* QM modeling tool to generate state machine code automatically, but the -* code is faster than in the ::QHsm style implementation strategy and needs -* less run-time support (smaller event-processor). -* -* @note -* ::QMActive is not intended to be instantiated directly, but rather serves -* as the base class for derivation of active objects in the application. -* -* @tr{AQP214} -* -* @usage -* The following example illustrates how to derive an active object from -* ::QMActive. Please note that the ::QActive member @c super is defined as -* the **first** member of the derived struct (see @ref oop). -* @include qf_qmactive.c -*/ - - - /*! Constructor of ::QMActive class. -* @protected @memberof QMActive -* -* @details -* Performs the first step of active object initialization by assigning -* the virtual pointer and calling the superclass constructor. -* -* @param[in,out] me current instance pointer (see @ref oop) -* @param[in] initial pointer to the event to be dispatched to the MSM -* -* @note Must be called only ONCE before QHSM_INIT(). -* -* @sa QHsm_ctor() -*/ - - - static QMActiveVtable const vtable = { /* QMActive virtual table */ - { &QMsm_init_, - &QMsm_dispatch_ -#ifdef Q_SPY - ,&QMsm_getStateHandler_ -#endif - }, - &QActive_start_, - &QActive_post_, - &QActive_postLIFO_ -}; - -/* clear the whole QMActive object, so that the framework can start -* correctly even if the startup code fails to clear the uninitialized -* data (as is required by the C Standard). -*/ -QF_bzero(me, sizeof(*me)); - -/*! -* @note -* ::QMActive inherits ::QActive, so by the @ref oop convention -* it should call the constructor of the superclass, i.e., QActive_ctor(). -* However, this would pull in the QActiveVtable, which in turn will pull -* in the code for QHsm_init_() and QHsm_dispatch_() implemetations, -* which is expensive. To avoid this code size penalty, in case QHsm is -* not used in a given project, the call to QMsm_ctor() avoids pulling -* in the code for QHsm. -*/ -QMsm_ctor(QMSM_CAST_(&me->super.super), initial); - -me->super.super.vptr = &vtable.super; /* hook vptr to QMActive vtable */ - - - - - /*! @brief Virtual Table for the ::QMActive class (inherited -* from ::QActiveVtable) -* -* @note -* ::QMActive inherits ::QActive exactly, without adding any new virtual -* functions and therefore, ::QMActiveVtable is typedef'ed as ::QActiveVtable. -*/ - - - - /*! @brief Time Event class -* @class QTimeEvt -* @extends QEvt -* -* @details -* Time events are special QF events equipped with the notion of time passage. -* The basic usage model of the time events is as follows. An active object -* allocates one or more ::QTimeEvt objects (provides the storage for them). -* When the active object needs to arrange for a timeout, it arms one of its -* time events to fire either just once (one-shot) or periodically. Each time -* event times out independently from the others, so a QF application can make -* multiple parallel timeout requests (from the same or different active -* objects). When QF detects that the appropriate moment has arrived, it -* inserts the time event directly into the recipient's event queue. The -* recipient then processes the time event just like any other event. -* -* Time events, as any other QF events derive from the ::QEvt base class. -* Typically, you will use a time event as-is, but you can also further -* derive more specialized time events from it by adding some more data -* members and/or specialized functions that operate on the specialized -* time events. -* -* Internally, the armed time events are organized into linked lists--one -* list for every supported ticking rate. These linked lists are scanned in -* every invocation of the QTIMEEVT_TICK_X() macro. Only armed (timing out) -* time events are in the list, so only armed time events consume CPU cycles. -* -* @sa ::QTimeEvt for the description of the data members -* -* @tr{AQP215} -* -* @note -* QF manages the time events in the QTIMEEVT_TICK_X() macro, which must -* be called periodically, from the clock tick ISR or from other periodic -* source. QTIMEEVT_TICK_X() caYou might also use the special ::QTicker -* active object. -* -* @note -* Even though ::QTimeEvt is a subclass of ::QEvt, ::QTimeEvt instances can NOT -* be allocated dynamically from event pools. In other words, it is illegal to -* allocate ::QTimeEvt instances with the Q_NEW() or Q_NEW_X() macros. -*/ - - - /*! link to the next time event in the list -* @private @memberof QTimeEvt -*/ - - - - /*! The active object that receives the time events -* @private @memberof QTimeEvt -*/ - - - - /*! Internal down-counter of the time event. -* @private @memberof QTimeEvt -* -* @details -* The down-counter is decremented by 1 in every QTimeEvt_tick_() call. -* The time event fires (gets posted or published) when the down-counter -* reaches zero. -*/ - - - - /*! Interval for periodic time event (zero for one-shot time event) -* @private @memberof QTimeEvt -* -* @details -* The value of the interval is re-loaded to the internal down-counter -* when the time event expires, so that the time event keeps timing out -* periodically. -*/ - - - - /*! heads of linked lists of time events, one for every clock tick rate */ - - - - /*! The extended "constructor" to initialize a Time Event. -* @public @memberof QTimeEvt -* -* @details -* When creating a time event, you must commit it to a specific active object -* `act`, tick rate `tickRate` and event signal `sig`. You cannot change -* these attributes later. -* -* @param[in,out] me current instance pointer (see @ref oop) -* @param[in] act pointer to the active object associated with this -* time event. The time event will post itself to this AO. -* @param[in] sig signal to associate with this time event. -* @param[in] tickRate system clock tick rate to associate with this -* time event in the range [0..15]. -* -* @note You should call the constructor exactly once for every Time Event -* object **before** arming the Time Event. The ideal place for initializing -* the time event(s) associated with a given AO is the AO's constructor. -*/ - - - - - - - /*! @pre The signal must be valid and the tick rate in range */ -Q_REQUIRE_ID(300, (sig != 0) - && (tickRate < QF_MAX_TICK_RATE)); - -me->next = (QTimeEvt *)0; -me->ctr = 0U; -me->interval = 0U; -me->super.sig = (QSignal)sig; - -/* For backwards compatibility with QTimeEvt_ctor(), the active object -* pointer can be uninitialized (NULL) and is NOT validated in the -* precondition. The active object pointer is validated in preconditions -* to QTimeEvt_arm_() and QTimeEvt_rearm(). -*/ -me->act = act; - -/* Setting the POOL_ID event attribute to zero is correct only for -* events not allocated from event pools, which must be the case -* for Time Events. -*/ -me->super.poolId_ = 0U; - -/* The refCtr_ attribute is not used in time events, so it is -* reused to hold the tickRate as well as other information -*/ -me->super.refCtr_ = (uint8_t)tickRate; - - - - /*! Arm a time event (one shot or periodic) for direct event posting. -* @public @memberof QTimeEvt -* -* @details -* Arms a time event to fire in a specified number of clock ticks and with -* a specified interval. If the interval is zero, the time event is armed for -* one shot ('one-shot' time event). When the timeout expires, the time event -* gets directly posted (using the FIFO policy) into the event queue of the -* host active object. After posting, a one-shot time event gets automatically -* disarmed while a periodic time event (interval != 0) is automatically -* re-armed. -* -* A time event can be disarmed at any time by calling QTimeEvt_disarm(). -* Also, a time event can be re-armed to fire in a different number of clock -* ticks by calling the QTimeEvt_rearm(). -* -* @param[in,out] me current instance pointer (see @ref oop) -* @param[in] nTicks number of clock ticks (at the associated rate) -* to rearm the time event with. -* @param[in] interval interval (in clock ticks) for periodic time event. -* -* @attention -* Arming an already armed time event is __not__ allowed and is considered -* a programming error. The QP/C framework will assert if it detects an -* attempt to arm an already armed time event. -* -* @usage -* The following example shows how to arm a periodic time event as well as -* one-shot time event from a state machine of an active object: -* @include qf_tevt.c -*/ - - - - - uint_fast8_t const tickRate - = ((uint_fast8_t)me->super.refCtr_ & QTE_TICK_RATE); -QTimeEvtCtr const ctr = me->ctr; -#ifdef Q_SPY -uint_fast8_t const qs_id = ((QActive *)(me->act))->prio; -#endif - -/*! @pre the host AO must be valid, time evnet must be disarmed, -* number of clock ticks cannot be zero, and the signal must be valid. -*/ -Q_REQUIRE_ID(400, (me->act != (void *)0) - && (ctr == 0U) - && (nTicks != 0U) - && (tickRate < (uint_fast8_t)QF_MAX_TICK_RATE) - && (me->super.sig >= (QSignal)Q_USER_SIG)); -#ifdef Q_NASSERT -Q_UNUSED_PAR(ctr); -#endif - -QF_CRIT_STAT_ -QF_CRIT_E_(); -me->ctr = nTicks; -me->interval = interval; - -/* is the time event unlinked? -* NOTE: For the duration of a single clock tick of the specified tick -* rate a time event can be disarmed and yet still linked into the list, -* because un-linking is performed exclusively in QTimeEvt_tick_(). -*/ -if ((me->super.refCtr_ & QTE_IS_LINKED) == 0U) { - me->super.refCtr_ |= QTE_IS_LINKED; /* mark as linked */ - - /* The time event is initially inserted into the separate - * "freshly armed" link list based on QTimeEvt_timeEvtHead_[tickRate].act. - * Only later, inside the QTimeEvt_tick_() function, the "freshly armed" - * list is appended to the main list of armed time events based on - * QTimeEvt_timeEvtHead_[tickRate].next. Again, this is to keep any - * changes to the main list exclusively inside the QTimeEvt_tick_() - * function. - */ - me->next = (QTimeEvt *)QTimeEvt_timeEvtHead_[tickRate].act; - QTimeEvt_timeEvtHead_[tickRate].act = me; -} - -QS_BEGIN_NOCRIT_PRE_(QS_QF_TIMEEVT_ARM, qs_id) - QS_TIME_PRE_(); /* timestamp */ - QS_OBJ_PRE_(me); /* this time event object */ - QS_OBJ_PRE_(me->act); /* the active object */ - QS_TEC_PRE_(nTicks); /* the number of ticks */ - QS_TEC_PRE_(interval); /* the interval */ - QS_U8_PRE_(tickRate); /* tick rate */ -QS_END_NOCRIT_PRE_() - -QF_CRIT_X_(); - - - - /*! Disarm a time event. -* @public @memberof QTimeEvt -* -* @details -* Disarm the time event so it can be safely reused. -* -* @param[in,out] me current instance pointer (see @ref oop) -* -* @returns -* 'true' if the time event was truly disarmed, that is, it was running. -* The return of 'false' means that the time event was not truly disarmed, -* because it was not running. The 'false' return is only possible for one- -* shot time events that have been automatically disarmed upon expiration. -* In this case the 'false' return means that the time event has already -* been posted or published and should be expected in the active object's -* state machine. -* -* @note -* there is no harm in disarming an already disarmed time event -*/ - #ifdef Q_SPY -uint_fast8_t const qs_id = QACTIVE_CAST_(me->act)->prio; -#endif - -QF_CRIT_STAT_ -QF_CRIT_E_(); - -/* is the time event actually armed? */ -bool wasArmed; -if (me->ctr != 0U) { - wasArmed = true; - me->super.refCtr_ |= QTE_WAS_DISARMED; - - QS_BEGIN_NOCRIT_PRE_(QS_QF_TIMEEVT_DISARM, qs_id) - QS_TIME_PRE_(); /* timestamp */ - QS_OBJ_PRE_(me); /* this time event object */ - QS_OBJ_PRE_(me->act); /* the target AO */ - QS_TEC_PRE_(me->ctr); /* the number of ticks */ - QS_TEC_PRE_(me->interval); /* the interval */ - QS_U8_PRE_(me->super.refCtr_ & QTE_TICK_RATE); - QS_END_NOCRIT_PRE_() - - me->ctr = 0U; /* schedule removal from the list */ -} -else { /* the time event was already disarmed automatically */ - wasArmed = false; - me->super.refCtr_ &= (uint8_t)(~QTE_WAS_DISARMED & 0xFFU); - - QS_BEGIN_NOCRIT_PRE_(QS_QF_TIMEEVT_DISARM_ATTEMPT, qs_id) - QS_TIME_PRE_(); /* timestamp */ - QS_OBJ_PRE_(me); /* this time event object */ - QS_OBJ_PRE_(me->act); /* the target AO */ - QS_U8_PRE_(me->super.refCtr_ & QTE_TICK_RATE); - QS_END_NOCRIT_PRE_() - -} -QF_CRIT_X_(); - -return wasArmed; - - - - /*! Rearm a time event. -* @public @memberof QTimeEvt -* -* @details -* Rearms a time event with a new number of clock ticks. This function can -* be used to adjust the current period of a periodic time event or to -* prevent a one-shot time event from expiring (e.g., a watchdog time event). -* Rearming a periodic timer leaves the interval unchanged and is a convenient -* method to adjust the phasing of a periodic time event. -* -* @param[in,out] me current instance pointer (see @ref oop) -* @param[in] nTicks number of clock ticks (at the associated rate) -* to rearm the time event with. -* -* @returns -* 'true' if the time event was running as it was re-armed. The 'false' -* return means that the time event was not truly rearmed because it was -* not running. The 'false' return is only possible for one-shot time events -* that have been automatically disarmed upon expiration. In this case the -* 'false' return means that the time event has already been posted or -* published and should be expected in the active object's state machine. -*/ - - - uint_fast8_t const tickRate - = (uint_fast8_t)me->super.refCtr_ & QTE_TICK_RATE; -#ifdef Q_SPY -uint_fast8_t const qs_id = ((QActive *)(me->act))->prio; -#endif - -/*! @pre AO must be valid, tick rate must be in range, nTicks must not -* be zero, and the signal of this time event must be valid -*/ -Q_REQUIRE_ID(600, (me->act != (void *)0) - && (tickRate < QF_MAX_TICK_RATE) - && (nTicks != 0U) - && (me->super.sig >= (QSignal)Q_USER_SIG)); - -QF_CRIT_STAT_ -QF_CRIT_E_(); - -/* is the time evt not running? */ -bool wasArmed; -if (me->ctr == 0U) { - wasArmed = false; - - /* NOTE: For the duration of a single clock tick of the specified - * tick rate a time event can be disarmed and yet still linked into - * the list, because unlinking is performed exclusively in the - * QTimeEvt_tick_() function. - */ - /* is the time event linked yet? */ - if ((me->super.refCtr_ & QTE_IS_LINKED) == 0U) { - me->super.refCtr_ |= QTE_IS_LINKED; /* mark as linked */ - - /* The time event is initially inserted into the separate - * "freshly armed" list based on QTimeEvt_timeEvtHead_[tickRate].act. - * Only later, inside the QTimeEvt_tick_() function, the "freshly - * armed" list is appended to the main list of armed time events - * based on QTimeEvt_timeEvtHead_[tickRate].next. Again, this is - * to keep any changes to the main list exclusively inside the - * QTimeEvt_tick_() function. - */ - me->next = (QTimeEvt *)QTimeEvt_timeEvtHead_[tickRate].act; - QTimeEvt_timeEvtHead_[tickRate].act = me; - } -} -else { /* the time event was armed */ - wasArmed = true; -} -me->ctr = nTicks; /* re-load the tick counter (shift the phasing) */ - -QS_BEGIN_NOCRIT_PRE_(QS_QF_TIMEEVT_REARM, qs_id) - QS_TIME_PRE_(); /* timestamp */ - QS_OBJ_PRE_(me); /* this time event object */ - QS_OBJ_PRE_(me->act); /* the target AO */ - QS_TEC_PRE_(me->ctr); /* the number of ticks */ - QS_TEC_PRE_(me->interval); /* the interval */ - QS_2U8_PRE_(tickRate, (wasArmed ? 1U : 0U)); -QS_END_NOCRIT_PRE_() - -QF_CRIT_X_(); - -return wasArmed; - - - - /*! Check the "was disarmed" status of a time event. -* @public @memberof QTimeEvt -* -* @details -* Useful for checking whether a one-shot time event was disarmed in the -* QTimeEvt_disarm() operation. -* -* @param[in,out] me current instance pointer (see @ref oop) -* -* @returns -* 'true' if the time event was truly disarmed in the last QTimeEvt_disarm() -* operation. The 'false' return means that the time event was not truly -* disarmed, because it was not running at that time. The 'false' return is -* only possible for one-shot time events that have been automatically disarmed -* upon expiration. In this case the 'false' return means that the time event -* has already been posted or published and should be expected in the active -* object's event queue. -* -* @note -* This function has a **side effect** of setting the "was disarmed" status, -* which means that the second and subsequent times this function is called -* the function will return 'true'. -*/ - uint8_t const wasDisarmed = (me->super.refCtr_ & QTE_WAS_DISARMED); -me->super.refCtr_ |= QTE_WAS_DISARMED; /* mark as disarmed */ -return wasDisarmed != 0U; - - - - const - /*! Get the current value of the down-counter of a time event. -* @public @memberof QTimeEvt -* -* @details -* Useful for checking how many clock ticks (at the tick rate associated -* with the time event) remain until the time event expires. -* -* @param[in,out] me current instance pointer (see @ref oop) -* -* @returns -* For an armed time event, the function returns the current value of the -* down-counter of the given time event. If the time event is not armed, -* the function returns 0. -* -* @note -* The function is thread-safe. -*/ - QF_CRIT_STAT_ -QF_CRIT_E_(); -QTimeEvtCtr const ret = me->ctr; -QF_CRIT_X_(); - -return ret; - - - - /*! Processes all armed time events at every clock tick. -* @static @private @memberof QTimeEvt -* -* @details -* This internal helper function processes all armed ::QTimeEvt objects -* associated wit the tick rate `tickRate`. -* -* This function must be called periodically from a time-tick ISR or from -* a task so that QF can manage the timeout events assigned to the given -* system clock tick rate. -* -* @param[in] tickRate clock tick rate serviced in this call [1..15]. -* @param[in] sender pointer to a sender object (only for QS tracing) -* -* @note -* this function should be called only via the macro QTIMEEVT_TICK_X() -* -* @note -* the calls to QTimeEvt_tick_() with different `tickRate` parameter can -* preempt each other. For example, higher clock tick rates might be -* serviced from interrupts while others from tasks (active objects). -* -* @sa ::QTimeEvt. -*/ - - - - - #ifndef Q_SPY -Q_UNUSED_PAR(sender); -#endif - -QTimeEvt *prev = &QTimeEvt_timeEvtHead_[tickRate]; - -QF_CRIT_STAT_ -QF_CRIT_E_(); - -QS_BEGIN_NOCRIT_PRE_(QS_QF_TICK, 0U) - ++prev->ctr; - QS_TEC_PRE_(prev->ctr); /* tick ctr */ - QS_U8_PRE_(tickRate); /* tick rate */ -QS_END_NOCRIT_PRE_() - -/* scan the linked-list of time events at this rate... */ -for (;;) { - QTimeEvt *t = prev->next; /* advance down the time evt. list */ - - /* end of the list? */ - if (t == (QTimeEvt *)0) { - - /* any new time events armed since the last QTimeEvt_tick_()? */ - if (QTimeEvt_timeEvtHead_[tickRate].act != (void *)0) { - - /* sanity check */ - Q_ASSERT_CRIT_(110, prev != (QTimeEvt *)0); - prev->next = (QTimeEvt *)QTimeEvt_timeEvtHead_[tickRate].act; - QTimeEvt_timeEvtHead_[tickRate].act = (void *)0; - t = prev->next; /* switch to the new list */ - } - else { - break; /* all currently armed time evts. processed */ - } - } - - /* time event scheduled for removal? */ - if (t->ctr == 0U) { - prev->next = t->next; - /* mark time event 't' as NOT linked */ - t->super.refCtr_ &= (uint8_t)(~QTE_IS_LINKED & 0xFFU); - /* do NOT advance the prev pointer */ - QF_CRIT_X_(); /* exit crit. section to reduce latency */ - - /* prevent merging critical sections, see NOTE1 below */ - QF_CRIT_EXIT_NOP(); - } - else { - --t->ctr; - - /* is time event about to expire? */ - if (t->ctr == 0U) { - /* temporary for volatile */ - QActive * const act = (QActive *)t->act; - - /* periodic time evt? */ - if (t->interval != 0U) { - t->ctr = t->interval; /* rearm the time event */ - prev = t; /* advance to this time event */ - } - /* one-shot time event: automatically disarm */ - else { - prev->next = t->next; - /* mark time event 't' as NOT linked */ - t->super.refCtr_ &= (uint8_t)(~QTE_IS_LINKED & 0xFFU); - /* do NOT advance the prev pointer */ - - QS_BEGIN_NOCRIT_PRE_(QS_QF_TIMEEVT_AUTO_DISARM, act->prio) - QS_OBJ_PRE_(t); /* this time event object */ - QS_OBJ_PRE_(act); /* the target AO */ - QS_U8_PRE_(tickRate); /* tick rate */ - QS_END_NOCRIT_PRE_() - } - - QS_BEGIN_NOCRIT_PRE_(QS_QF_TIMEEVT_POST, act->prio) - QS_TIME_PRE_(); /* timestamp */ - QS_OBJ_PRE_(t); /* the time event object */ - QS_SIG_PRE_(t->super.sig); /* signal of this time event */ - QS_OBJ_PRE_(act); /* the target AO */ - QS_U8_PRE_(tickRate); /* tick rate */ - QS_END_NOCRIT_PRE_() - - QF_CRIT_X_(); /* exit critical section before posting */ - - /* QACTIVE_POST() asserts internally if the queue overflows */ - QACTIVE_POST(act, &t->super, sender); - } - else { - prev = t; /* advance to this time event */ - QF_CRIT_X_(); /* exit crit. section to reduce latency */ - - /* prevent merging critical sections - * In some QF ports the critical section exit takes effect only - * on the next machine instruction. If this case, the next - * instruction is another entry to a critical section, the - * critical section won't be really exited, but rather the - * two adjacent critical sections would be merged. The - * QF_CRIT_EXIT_NOP() macro contains minimal code required - * to prevent such merging of critical sections in QF ports, - * in which it can occur. - */ - QF_CRIT_EXIT_NOP(); - } - } - QF_CRIT_E_(); /* re-enter crit. section to continue */ -} -QF_CRIT_X_(); - - - - /*! Processes one clock tick for QUTest */ - - - - - - - - /*! Returns 'true' if there are no armed time events at a given tick rate. -* @static @public @memberof QTimeEvt -* -* @details -* Find out if any time events are armed at the given clock tick rate. -* -* @param[in] tickRate system clock tick rate to find out about. -* -* @returns -* 'true' if no time events are armed at the given tick rate and -* 'false' otherwise. -* -* @note -* This function should be called in critical section. -*/ - - - /*! @pre the tick rate must be in range */ -Q_REQUIRE_ID(200, tickRate < QF_MAX_TICK_RATE); - -bool inactive; -if (QTimeEvt_timeEvtHead_[tickRate].next != (QTimeEvt *)0) { - inactive = false; -} -else if ((QTimeEvt_timeEvtHead_[tickRate].act != (void *)0)) { - inactive = false; -} -else { - inactive = true; -} -return inactive; - - - - - /*! @brief "Ticker" Active Object class -* @class QTicker -* @extends QActive -* -* @details -* QTicker is an efficient active object specialized to process QF system -* clock tick at a specified tick rate [0..#QF_MAX_TICK_RATE]. -* Placing system clock tick processing in an active object allows you -* to remove the non-deterministic QTIMEEVT_TICK_X() processing from the -* interrupt level and move it into the thread-level, where you can prioritize -* it as low as you wish. -* -* @usage -* The following example illustrates use of QTicker active objects: -* @include qf_ticker.c -*/ - - - /*! Constructor of the QTicker Active Object class -* @public @memberof QTicker -*/ - - - static QActiveVtable const vtable = { /* QActive virtual table */ - { &QTicker_init_, - &QTicker_dispatch_ -#ifdef Q_SPY - ,&QHsm_getStateHandler_ -#endif - }, - &QActive_start_, - &QTicker_post_, - &QTicker_postLIFO_ -}; -QActive_ctor(&me->super, Q_STATE_CAST(0)); /* superclass' ctor */ -me->super.super.vptr = &vtable.super; /* hook the vptr */ - -/* reuse eQueue.head for tick-rate */ -me->super.eQueue.head = (QEQueueCtr)tickRate; - - - - /*! initialization (override) -* @private @memberof QTicker -*/ - - - - - - - Q_UNUSED_PAR(me); -Q_UNUSED_PAR(par); -Q_UNUSED_PAR(qs_id); - -QTICKER_CAST_(me)->eQueue.tail = 0U; - - - - /*! dispatching (override) -* @private @memberof QTicker -*/ - - - - - - - Q_UNUSED_PAR(e); -Q_UNUSED_PAR(qs_id); - -QF_CRIT_STAT_ -QF_CRIT_E_(); -QEQueueCtr nTicks = QTICKER_CAST_(me)->eQueue.tail; /* save # of ticks */ -QTICKER_CAST_(me)->eQueue.tail = 0U; /* clear # ticks */ -QF_CRIT_X_(); - -for (; nTicks > 0U; --nTicks) { - QTimeEvt_tick_((uint_fast8_t)QTICKER_CAST_(me)->eQueue.head, me); -} - - - - /*! post (override) -* @private @memberof QTicker -*/ - - - - - - - - - Q_UNUSED_PAR(e); -Q_UNUSED_PAR(margin); -#ifndef Q_SPY -Q_UNUSED_PAR(sender); -#endif - -QF_CRIT_STAT_ -QF_CRIT_E_(); -if (me->eQueue.frontEvt == (QEvt *)0) { - - static QEvt const tickEvt = { 0U, 0U, 0U }; - me->eQueue.frontEvt = &tickEvt; /* deliver event directly */ - --me->eQueue.nFree; /* one less free event */ - - QACTIVE_EQUEUE_SIGNAL_(me); /* signal the event queue */ -} - -++me->eQueue.tail; /* account for one more tick event */ - -QS_BEGIN_NOCRIT_PRE_(QS_QF_ACTIVE_POST, me->prio) - QS_TIME_PRE_(); /* timestamp */ - QS_OBJ_PRE_(sender); /* the sender object */ - QS_SIG_PRE_(0U); /* the signal of the event */ - QS_OBJ_PRE_(me); /* this active object */ - QS_2U8_PRE_(0U, 0U); /* pool Id & refCtr of the evt */ - QS_EQC_PRE_(0U); /* number of free entries */ - QS_EQC_PRE_(0U); /* min number of free entries */ -QS_END_NOCRIT_PRE_() - -QF_CRIT_X_(); - -return true; /* the event is always posted correctly */ - - - - /*! post-LIFO (override) -* @private @memberof QTicker -*/ - - - - - Q_UNUSED_PAR(me); -Q_UNUSED_PAR(e); - -Q_ERROR_ID(900); - - - - - /*! @brief Native QF Event Queue -* @class QEQueue -* -* @details -* This class describes the native QF event queue, which can be used as -* the event queue for active objects, or as a simple "raw" event queue for -* thread-safe event passing among non-framework entities, such as ISRs, -* device drivers, or other third-party components.<br> -* -* The native QF event queue is configured by defining the macro -* #QF_EQUEUE_TYPE as ::QEQueue in the specific QF port header file.<br> -* <br> -* The ::QEQueue structure contains only data members for managing an event -* queue, but does not contain the storage for the queue buffer, which must -* be provided externally during the queue initialization.<br> -* <br> -* The event queue can store only event pointers, not the whole events. The -* internal implementation uses the standard ring-buffer plus one external -* location that optimizes the queue operation for the most frequent case -* of empty queue.<br> -* <br> -* The ::QEQueue structure is used with two sets of functions. One set is for -* the active object event queue, which might need to block the active object -* task when the event queue is empty and might need to unblock it when -* events are posted to the queue. The interface for the native active object -* event queue consists of the following functions: QActive_post(), -* QActive_postLIFO(), and QActive_get_(). Additionally the function -* QEQueue_init() is used to initialize the queue.<br> -* <br> -* The other set of functions, uses ::QEQueue as a simple "raw" event -* queue to pass events between entities other than active objects, such as -* ISRs. The "raw" event queue is not capable of blocking on the get() -* operation, but is still thread-safe because it uses QF critical section -* to protect its integrity. The interface for the "raw" thread-safe queue -* consists of the following functions: QEQueue_post(), -* QEQueue_postLIFO(), and QEQueue_get(). Additionally the function -* QEQueue_init() is used to initialize the queue. -* -* <br>ote Most event queue operations (both the active object queues and -* the "raw" queues) internally use the QF critical section. You should be -* careful not to invoke those operations from other critical sections when -* nesting of critical sections is not supported. -* -* @sa ::QEQueue for the description of the data members -*/ - - - /*! pointer to event at the front of the queue. -* @private @memberof QEQueue -* -* @details -* All incoming and outgoing events pass through the frontEvt location. -* When the queue is empty (which is most of the time), the extra -* frontEvt location allows to bypass the ring buffer altogether, -* greatly optimizing the performance of the queue. Only bursts of events -* engage the ring buffer. -* -* <br>ote The additional role of this attribute is to indicate the empty -* status of the queue. The queue is empty when frontEvt is NULL. -*/ - - - - /*! pointer to the start of the ring buffer -* @private @memberof QEQueue -*/ - - - - /*! offset of the end of the ring buffer from the start of the buffer -* @private @memberof QEQueue -*/ - - - - /*! offset to where next event will be inserted into the buffer -* @private @memberof QEQueue -*/ - - - - /*! offset of where next event will be extracted from the buffer -* @private @memberof QEQueue -*/ - - - - /*! number of free events in the ring buffer -* @private @memberof QEQueue -*/ - - - - /*! Minimum number of free events ever in the ring buffer. -* @private @memberof QEQueue -* -* @details -* This attribute remembers the low-watermark of the ring buffer, -* which provides a valuable information for sizing event queues. -* @sa QF_getQueueMargin(). -*/ - - - - /*! Initialize the native QF event queue. -* @public @memberof QEQueue -* -* @details -* Initialize the event queue by giving it the storage for the ring buffer. -* -* @param[in,out] me current instance pointer (see @ref oop) -* @param[in] qSto an array of pointers to ::QEvt to sereve as the -* ring buffer for the event queue -* @param[in] qLen the length of the `qSto` buffer (in ::QEvt pointers) -* -* @note The actual capacity of the queue is qLen + 1, because of the extra -* location forntEvt. -* -* @note -* This function is also used to initialize the event queues of active -* objects in the built-int QV and QK kernels, as well as other -* QP ports to OSes/RTOSes that do provide a suitable message queue. -*/ - - - - - me->frontEvt = (QEvt *)0; /* no events in the queue */ -me->ring = qSto; /* the beginning of the ring buffer */ -me->end = (QEQueueCtr)qLen; -if (qLen != 0U) { - me->head = 0U; - me->tail = 0U; -} -me->nFree = (QEQueueCtr)(qLen + 1U); /* +1 for frontEvt */ -me->nMin = me->nFree; - - - - /*! Post an event to the "raw" thread-safe event queue (FIFO). -* @public @memberof QEQueue -* -* @details -* Post an event to the "raw" thread-safe event queue using the -* First-In-First-Out (FIFO) order. -* -* @param[in,out] me current instance pointer (see @ref oop) -* @param[in] e pointer to the event to be posted to the queue -* @param[in] margin number of required free slots in the queue after -* posting the event. The special value #QF_NO_MARGIN -* means that this function will assert if posting -* @note -* The #QF_NO_MARGIN value of the `margin` parameter is special and -* denotes situation when the post() operation is assumed to succeed (event -* delivery guarantee). An assertion fires, when the event cannot be -* delivered in this case. -* -* @returns 'true' (success) when the posting succeeded with the provided -* margin and 'false' (failure) when the posting fails. -* -* @note This function can be called from any task context or ISR context. -* -* @sa QEQueue_postLIFO(), QEQueue_get() -*/ - - - - - - - #ifndef Q_SPY -Q_UNUSED_PAR(qs_id); -#endif - -/* @pre event must be valid */ -Q_REQUIRE_ID(200, e != (QEvt *)0); - -QF_CRIT_STAT_ -QF_CRIT_E_(); -QEQueueCtr nFree = me->nFree; /* get volatile into the temporary */ - -/* required margin available? */ -bool status; -if (((margin == QF_NO_MARGIN) && (nFree > 0U)) - || (nFree > (QEQueueCtr)margin)) -{ - /* is it a dynamic event? */ - if (e->poolId_ != 0U) { - QEvt_refCtr_inc_(e); /* increment the reference counter */ - } - - --nFree; /* one free entry just used up */ - me->nFree = nFree; /* update the volatile */ - if (me->nMin > nFree) { - me->nMin = nFree; /* update minimum so far */ - } - - QS_BEGIN_NOCRIT_PRE_(QS_QF_EQUEUE_POST, qs_id) - QS_TIME_PRE_(); /* timestamp */ - QS_SIG_PRE_(e->sig); /* the signal of this event */ - QS_OBJ_PRE_(me); /* this queue object */ - QS_2U8_PRE_(e->poolId_, e->refCtr_); /* pool Id & ref Count */ - QS_EQC_PRE_(nFree); /* number of free entries */ - QS_EQC_PRE_(me->nMin); /* min number of free entries */ - QS_END_NOCRIT_PRE_() - - /* was the queue empty? */ - if (me->frontEvt == (QEvt *)0) { - me->frontEvt = e; /* deliver event directly */ - } - /* queue was not empty, insert event into the ring-buffer */ - else { - /* insert event into the ring buffer (FIFO)... */ - me->ring[me->head] = e; /* insert e into buffer */ - /* need to wrap the head? */ - if (me->head == 0U) { - me->head = me->end; /* wrap around */ - } - --me->head; - } - status = true; /* event posted successfully */ -} -else { - /*! @note assert if event cannot be posted and dropping events is - * not acceptable - */ - Q_ASSERT_CRIT_(210, margin != QF_NO_MARGIN); - - QS_BEGIN_NOCRIT_PRE_(QS_QF_EQUEUE_POST_ATTEMPT, qs_id) - QS_TIME_PRE_(); /* timestamp */ - QS_SIG_PRE_(e->sig); /* the signal of this event */ - QS_OBJ_PRE_(me); /* this queue object */ - QS_2U8_PRE_(e->poolId_, e->refCtr_); /* pool Id & ref Count */ - QS_EQC_PRE_(nFree); /* number of free entries */ - QS_EQC_PRE_(margin); /* margin requested */ - QS_END_NOCRIT_PRE_() - - status = false; -} -QF_CRIT_X_(); - -return status; - - - - /*! Post an event to the "raw" thread-safe event queue (LIFO). -* @public @memberof QEQueue -* -* @details -* Post an event to the "raw" thread-safe event queue using the -* Last-In-First-Out (LIFO) order. -* -* @param[in,out] me current instance pointer (see @ref oop) -* @param[in] e pointer to the event to be posted to the queue -* -* @attention -* The LIFO policy should be used only with great __caution__, because -* it alters the order of events in the queue. -* -* @note -* This function can be called from any task context or ISR context. -* -* @note -* this function is used for the "raw" thread-safe queues and __not__ -* for the queues of active objects. -* -* @sa -* QEQueue_post(), QEQueue_get(), QActive_defer() -*/ - - - - - #ifndef Q_SPY -Q_UNUSED_PAR(qs_id); -#endif - -QF_CRIT_STAT_ -QF_CRIT_E_(); -QEQueueCtr nFree = me->nFree; /* get volatile into the temporary */ - -/*! @pre the queue must be able to accept the event (cannot overflow) */ -Q_REQUIRE_CRIT_(300, nFree != 0U); - -/* is it a dynamic event? */ -if (e->poolId_ != 0U) { - QEvt_refCtr_inc_(e); /* increment the reference counter */ -} - ---nFree; /* one free entry just used up */ -me->nFree = nFree; /* update the volatile */ -if (me->nMin > nFree) { - me->nMin = nFree; /* update minimum so far */ -} - -QS_BEGIN_NOCRIT_PRE_(QS_QF_EQUEUE_POST_LIFO, qs_id) - QS_TIME_PRE_(); /* timestamp */ - QS_SIG_PRE_(e->sig); /* the signal of this event */ - QS_OBJ_PRE_(me); /* this queue object */ - QS_2U8_PRE_(e->poolId_, e->refCtr_);/* pool Id & ref Count of event */ - QS_EQC_PRE_(nFree); /* number of free entries */ - QS_EQC_PRE_(me->nMin); /* min number of free entries */ -QS_END_NOCRIT_PRE_() - -QEvt const * const frontEvt = me->frontEvt; /* read volatile into temp */ -me->frontEvt = e; /* deliver event directly to the front of the queue */ - -/* was the queue not empty? */ -if (frontEvt != (QEvt *)0) { - ++me->tail; - if (me->tail == me->end) { /* need to wrap the tail? */ - me->tail = 0U; /* wrap around */ - } - me->ring[me->tail] = frontEvt; /* save old front evt */ -} -QF_CRIT_X_(); - - - - /*! Obtain an event from the "raw" thread-safe queue. -* @public @memberof QEQueue -* -* @details -* Retrieves an event from the front of the "raw" thread-safe queue and -* returns a pointer to this event to the caller. -* -* @param[in,out] me current instance pointer (see @ref oop) -* -* @returns -* pointer to event at the front of the queue, if the queue is -* not empty and NULL if the queue is empty. -* -* @note -* this function is used for the "raw" thread-safe queues and __not__ -* for the queues of active objects. -* -* @sa -* QEQueue_post(), QEQueue_postLIFO(), QActive_recall() -*/ - - - #ifndef Q_SPY -Q_UNUSED_PAR(qs_id); -#endif - -QF_CRIT_STAT_ -QF_CRIT_E_(); -QEvt const * const e = me->frontEvt; /* remove event from the front */ - -/* was the queue not empty? */ -if (e != (QEvt *)0) { - /* use a temporary variable to increment volatile me->nFree */ - QEQueueCtr const nFree = me->nFree + 1U; - me->nFree = nFree; /* update the number of free */ - - /* any events in the ring buffer? */ - if (nFree <= me->end) { - me->frontEvt = me->ring[me->tail]; /* get from tail */ - if (me->tail == 0U) { /* need to wrap the tail? */ - me->tail = me->end; /* wrap around */ - } - --me->tail; - - QS_BEGIN_NOCRIT_PRE_(QS_QF_EQUEUE_GET, qs_id) - QS_TIME_PRE_(); /* timestamp */ - QS_SIG_PRE_(e->sig); /* the signal of this event */ - QS_OBJ_PRE_(me); /* this queue object */ - QS_2U8_PRE_(e->poolId_, e->refCtr_);/* pool Id & ref Count */ - QS_EQC_PRE_(nFree); /* number of free entries */ - QS_END_NOCRIT_PRE_() - } - else { - me->frontEvt = (QEvt *)0; /* queue becomes empty */ - - /* all entries in the queue must be free (+1 for fronEvt) */ - Q_ASSERT_CRIT_(410, nFree == (me->end + 1U)); - - QS_BEGIN_NOCRIT_PRE_(QS_QF_EQUEUE_GET_LAST, qs_id) - QS_TIME_PRE_(); /* timestamp */ - QS_SIG_PRE_(e->sig); /* the signal of this event */ - QS_OBJ_PRE_(me); /* this queue object */ - QS_2U8_PRE_(e->poolId_, e->refCtr_); /* pool Id & ref Count */ - QS_END_NOCRIT_PRE_() - } -} -QF_CRIT_X_(); -return e; - - - - const - /*! "raw" thread-safe QF event queue operation for obtaining the number -* of free entries still available in the queue. -* @public @memberof QEQueue -* -* @details -* This operation needs to be used with caution because the number of free -* entries can change unexpectedly. The main intent for using this operation -* is in conjunction with event deferral. In this case the queue is accessed -* only from a single thread (by a single AO), so the number of free -* entries cannot change unexpectedly. -* -* @param[in] me current instance pointer (see @ref oop) -* -* @returns the current number of free slots in the queue. -*/ - return me->nFree; - - - - const - /*! "raw" thread-safe QF event queue operation for obtaining the minimum -* number of free entries ever in the queue (a.k.a. "low-watermark"). -* @public @memberof QEQueue -* -* @details -* This operation needs to be used with caution because the "low-watermark" -* can change unexpectedly. The main intent for using this operation is to -* get an idea of queue usage to size the queue adequately. -* -* @param[in] me current instance pointer (see @ref oop) -* -* @returns the minimum number of free entries ever in the queue since init. -*/ - return me->nMin; - - - - const - /*! "raw" thread-safe QF event queue operation to find out if the queue -* is empty. -* @public @memberof QEQueue -* -* @details -* This operation needs to be used with caution because the queue status -* can change unexpectedly. The main intent for using this operation is in -* conjunction with event deferral. In this case the queue is accessed only -* from a single thread (by a single AO), so no other entity can post -* events to the queue. -* -* @param[in] me_ current instance pointer (see @ref oop) -* -* @returns 'true' if the queue is current empty and 'false' otherwise. -*/ - return me->frontEvt == (QEvt *)0; - - - - - /*! @brief Native QF Memory Pool -* @class QMPool -* -* @details -* A fixed block-size memory pool is a very fast and efficient data -* structure for dynamic allocation of fixed block-size chunks of memory. -* A memory pool offers fast and deterministic allocation and recycling of -* memory blocks and is not subject to fragmenation.<br> -* -* The ::QMPool class describes the native QF memory pool, which can be used as -* the event pool for dynamic event allocation, or as a fast, deterministic -* fixed block-size heap for any other objects in your application. -* -* @note -* ::QMPool contains only data members for managing a memory pool, but -* does not contain the pool storage, which must be provided externally -* during the pool initialization. -* -* @note -* The native QF event pool is configured by defining the macro -* #QF_EPOOL_TYPE_ as ::QMPool in the specific QF port header file. -*/ - - - /*! start of the memory managed by this memory pool -* @private @memberof QMPool -*/ - - - - /*! end of the memory managed by this memory pool -* @private @memberof QMPool -*/ - - - - /*! head of linked list of free blocks -* @private @memberof QMPool -*/ - - - - /*! maximum block size (in bytes) -* @private @memberof QMPool -*/ - - - - /*! total number of blocks -* @private @memberof QMPool -*/ - - - - /*! number of free blocks remaining -* @private @memberof QMPool -*/ - - - - /*! minimum number of free blocks ever present in this pool -* @private @memberof QMPool -* -* @details -* this attribute remembers the low watermark of the pool, which -* provides a valuable information for sizing event pools. -* @sa QF_getPoolMin(). -*/ - - - - /*! Initializes the native QF memory pool -* @public @memberof QMPool -* -* @details -* Initialize a fixed block-size memory pool by providing it with the pool -* memory to manage, size of this memory, and the block size. -* -* @param[in,out] me current instance pointer (see @ref oop) -* @param[in] poolSto pointer to the memory buffer for pool storage -* @param[in] poolSize size of the storage buffer in bytes -* @param[in] blockSize fixed-size of the memory blocks in bytes -* -* @attention -* The caller of QMPool::init() must make sure that the `poolSto` -* pointer is properly **aligned**. In particular, it must be possible to -* efficiently store a pointer at the location pointed to by `poolSto`. -* Internally, the QMPool_init() function rounds up the block size -* `blockSize` so that it can fit an integer number of pointers. -* This is done to achieve proper alignment of the blocks within the pool. -* -* @note -* Due to the rounding of block size the actual capacity of the pool might -* be less than (`poolSize` / `blockSize`). You can check the capacity -* of the pool by calling the QF_getPoolMin() function. -* -* @note -* This function is **not** protected by a critical section, because -* it is intended to be called only during the initialization of the system, -* when interrupts are not allowed yet. -* -* @note -* Many QF ports use memory pools to implement the event pools. -* -* @usage -* The following example illustrates how to invoke QMPool_init(): -* @include qmp_init.c -*/ - - - - - - - /*! @pre The memory block must be valid -* and the poolSize must fit at least one free block -* and the blockSize must not be too close to the top of the dynamic range -*/ -Q_REQUIRE_ID(100, (poolSto != (void *)0) - && (poolSize >= (uint_fast32_t)sizeof(QFreeBlock)) - && ((uint_fast16_t)(blockSize + sizeof(QFreeBlock)) > blockSize)); - -me->free_head = poolSto; - -/* round up the blockSize to fit an integer # free blocks, no division */ -me->blockSize = (QMPoolSize)sizeof(QFreeBlock); /* start with just one */ - -/* #free blocks that fit in one memory block */ -uint_fast16_t nblocks = 1U; -while (me->blockSize < (QMPoolSize)blockSize) { - me->blockSize += (QMPoolSize)sizeof(QFreeBlock); - ++nblocks; -} -blockSize = (uint_fast16_t)me->blockSize; /* round-up to nearest block */ - -/* the pool buffer must fit at least one rounded-up block */ -Q_ASSERT_ID(110, poolSize >= blockSize); - -/* chain all blocks together in a free-list... */ -poolSize -= (uint_fast32_t)blockSize; /* don't count the last block */ -me->nTot = 1U; /* the last block already in the pool */ - -/* start at the head of the free list */ -QFreeBlock *fb = (QFreeBlock *)me->free_head; - -/* chain all blocks together in a free-list... */ -while (poolSize >= (uint_fast32_t)blockSize) { - fb->next = &fb[nblocks]; /* point next link to next block */ - fb = fb->next; /* advance to the next block */ - poolSize -= (uint_fast32_t)blockSize; /* reduce available pool size */ - ++me->nTot; /* increment the number of blocks so far */ -} - -fb->next = (QFreeBlock *)0; /* the last link points to NULL */ -me->nFree = me->nTot; /* all blocks are free */ -me->nMin = me->nTot; /* the minimum number of free blocks */ -me->start = poolSto; /* the original start this pool buffer */ -me->end = fb; /* the last block in this pool */ - - - - /*! Obtains a memory block from a memory pool. -* @public @memberof QMPool -* -* @details -* The function allocates a memory block from the pool and returns a pointer -* to the block back to the caller. -* -* @param[in,out] me current instance pointer (see @ref oop) -* @param[in] margin the minimum number of unused blocks still available -* in the pool after the allocation. -* -* @returns -* A pointer to a memory block or NULL if no more blocks are available in -* the memory pool. -* -* @note -* This function can be called from any task level or ISR level. -* -* @note -* The memory pool `me` must be initialized before any events can -* be requested from it. Also, the QMPool_get() function uses internally a -* QF critical section, so you should be careful not to call it from within -* a critical section when nesting of critical section is not supported. -* -* @attention -* An allocated block must be later returned back to the **same** pool -* from which it has been allocated. -* -* @sa QMPool_put() -* -* @usage -* The following example illustrates how to use QMPool_get(): -* @include qmp_use.c -*/ - - - - - #ifndef Q_SPY -Q_UNUSED_PAR(qs_id); -#endif - -QF_CRIT_STAT_ -QF_CRIT_E_(); - -/* have more free blocks than the requested margin? */ -QFreeBlock *fb; -if (me->nFree > (QMPoolCtr)margin) { - void *fb_next; - fb = (QFreeBlock *)me->free_head; /* get a free block */ - - /* the pool has some free blocks, so a free block must be available */ - Q_ASSERT_CRIT_(310, fb != (QFreeBlock *)0); - - fb_next = fb->next; /* put volatile to a temporary to avoid UB */ - - /* is the pool becoming empty? */ - --me->nFree; /* one less free block */ - if (me->nFree == 0U) { - /* pool is becoming empty, so the next free block must be NULL */ - Q_ASSERT_CRIT_(320, fb_next == (QFreeBlock *)0); - - me->nMin = 0U; /* remember that the pool got empty */ - } - else { - /*! @invariant - * The pool is not empty, so the next free-block pointer, - * so the next free block must be in range. - * - * @tr{PQP18_3} - */ - /* NOTE: The next free block pointer can fall out of range - * when the client code writes past the memory block, thus - * corrupting the next block. - */ - Q_ASSERT_CRIT_(330, - (me->start <= fb_next) && (fb_next <= me->end)); - - /* is the number of free blocks the new minimum so far? */ - if (me->nMin > me->nFree) { - me->nMin = me->nFree; /* remember the new minimum */ - } - } - - me->free_head = fb_next; /* set the head to the next free block */ - - QS_BEGIN_NOCRIT_PRE_(QS_QF_MPOOL_GET, qs_id) - QS_TIME_PRE_(); /* timestamp */ - QS_OBJ_PRE_(me); /* this memory pool */ - QS_MPC_PRE_(me->nFree); /* # of free blocks in the pool */ - QS_MPC_PRE_(me->nMin); /* min # free blocks ever in the pool */ - QS_END_NOCRIT_PRE_() -} -/* don't have enough free blocks at this point */ -else { - fb = (QFreeBlock *)0; - - QS_BEGIN_NOCRIT_PRE_(QS_QF_MPOOL_GET_ATTEMPT, qs_id) - QS_TIME_PRE_(); /* timestamp */ - QS_OBJ_PRE_(me); /* this memory pool */ - QS_MPC_PRE_(me->nFree); /* # of free blocks in the pool */ - QS_MPC_PRE_(margin); /* the requested margin */ - QS_END_NOCRIT_PRE_() -} -QF_CRIT_X_(); - -return fb; /* return the block or NULL pointer to the caller */ - - - - /*! Recycles a memory block back to a memory pool. -* @public @memberof QMPool -* -* @details -* Recycle a memory block to the fixed block-size memory pool. -* -* @param[in,out] me current instance pointer (see @ref oop) -* @param[in] b pointer to the memory block that is being recycled -* -* @attention -* The recycled block must be allocated from the **same** memory pool -* to which it is returned. -* -* @note -* This function can be called from any task level or ISR level. -* -* @sa -* QMPool_get() -* -* @usage -* The following example illustrates how to use QMPool_put(): -* @include qmp_use.c -*/ - - - - - #ifndef Q_SPY -Q_UNUSED_PAR(qs_id); -#endif - -/*! @pre number of free blocks cannot exceed the total # blocks and -* the block pointer must be in range for this pool. -*/ -Q_REQUIRE_ID(200, (me->nFree < me->nTot) - && (me->start <= b) && (b <= me->end)); - -QF_CRIT_STAT_ -QF_CRIT_E_(); -((QFreeBlock *)b)->next = (QFreeBlock *)me->free_head;/* link into list */ -me->free_head = b; /* set as new head of the free list */ -++me->nFree; /* one more free block in this pool */ - -QS_BEGIN_NOCRIT_PRE_(QS_QF_MPOOL_PUT, qs_id) - QS_TIME_PRE_(); /* timestamp */ - QS_OBJ_PRE_(me); /* this memory pool */ - QS_MPC_PRE_(me->nFree); /* the number of free blocks in the pool */ -QS_END_NOCRIT_PRE_() - -QF_CRIT_X_(); - - - - - - - /*! @brief QF active object framework -* @class QF -*/ - { - uint8_t dummy; /*< dummy attribute */ -} QF; - - - - /*! Interrupt lock up-down counter (used in some QF ports ) -* @static @private @memberof QF -*/ - - - - /*! Interrupt nesting up-down counter (used in some QF ports ) -* @static @private @memberof QF -*/ - - - - /*! QF initialization -* @static @public @memberof QF -* -* @details -* Initializes QF and must be called exactly once before any other QF -* function. Typcially, QF_init() is called from main() even before -* initializing the Board Support Package (BSP). -* -* @note -* QF_init() clears the internal QF variables, so that the framework -* can start correctly even if the startup code fails to clear the -* uninitialized data (as is required by the C Standard). -*/ - - - - /*! Function invoked by the application layer to stop the QF -* application and return control to the OS/Kernel. -* @static @public @memberof QF -* -* @details -* This function stops the QF application. After calling this function, -* QF attempts to gracefully stop the application. This graceful shutdown -* might take some time to complete. The typical use of this function is -* for terminating the QF application to return back to the operating -* system or for handling fatal errors that require shutting down -* (and possibly re-setting) the system. -* -* @attention -* After calling QF_stop() the application must terminate and cannot -* continue. In particular, QF_stop() is **not** intended to be followed -* by a call to QF_init() to "resurrect" the application. -* -* @sa QF_onCleanup() -*/ - - - - /*! Transfers control to QF to run the application. -* @static @public @memberof QF -* -* @details -* QF_run() is typically called from your startup code after you initialize -* the QF and start at least one active object with QACTIVE_START(). -* -* @returns -* In QK, the QF_run() does not return. -*/ - - - - /*! initialization of publish-subscribe -* -* @deprecated -* @sa QActive_psInit() -*/ - - - - - QActive_psInit(subscrSto, maxSignal); - - - - /*! This function returns the minimum of free entries of -* the given event queue. -* @static @public @memberof QF -* -* @details -* Queries the minimum of free ever present in the given event queue of -* an active object with priority `prio`, since the active object -* was started. -* -* @note -* This function is available only when the native QF event queue -* implementation is used. Requesting the queue minimum of an unused -* priority level raises an assertion in the QF. (A priority level becomes -* used in QF after the call to the QActive_register_() function.) -* -* @param[in] prio Priority of the active object, whose queue is queried -* -* @returns -* the minimum of free ever present in the given event queue of an active -* object with priority `prio`, since the active object was started. -*/ - - - Q_REQUIRE_ID(400, (prio <= QF_MAX_ACTIVE) - && (QActive_registry_[prio] != (QActive *)0)); -QF_CRIT_STAT_ -QF_CRIT_E_(); -uint_fast16_t const min = - (uint_fast16_t)QActive_registry_[prio]->eQueue.nMin; -QF_CRIT_X_(); - -return min; - - - - /*! Startup QF callback. -* @static @public @memberof QF -* -* @details -* The purpose of the QF_onStartup() callback is to configure and enable -* hardware interrupts. The callback is invoked from QF_run(), right before -* starting the underlying real-time kernel. By that time, the application -* is considered ready to receive and service interrupts. -* -* This function is application-specific and is not implemented in QF, but -* rather in the Board Support Package (BSP) for the given application. -*/ - - - - /*! Cleanup QF callback. -* @static @public @memberof QF -* -* @details -* QF_onCleanup() is called in some QF ports before QF returns to the -* underlying real-time kernel or operating system. -* -* This function is strongly platform-specific and is not implemented in -* the QF, but either in the QF port or in the Board Support Package (BSP) -* for the given application. Some QF ports might not require implementing -* QF_onCleanup() at all, because many embedded applications don't have -* anything to exit to. -* -* @sa QF_stop() -*/ - - - - - - - /*! Event pool initialization for dynamic allocation of events. -* @static @public @memberof QF -* -* @details -* This function initializes one event pool at a time and must be called -* exactly once for each event pool before the pool can be used. -* -* @param[in] poolSto pointer to the storage for the event pool -* @param[in] poolSize size of the storage for the pool in bytes -* @param[in] evtSize the block-size of the pool in bytes, which determines -* the maximum size of events that can be allocated from the pool. -* -* @attention -* You might initialize many event pools by making many consecutive calls -* to the QF_poolInit() function. However, for the simplicity of the internal -* implementation, you must initialize event pools in the **ascending order** -* of the event size. -* -* Many RTOSes provide fixed block-size heaps, a.k.a. memory pools that can -* be adapted for QF event pools. In case such support is missing, QF provides -* a native QF event pool implementation. The macro #QF_EPOOL_TYPE_ determines -* the type of event pool used by a particular QF port. See structure ::QMPool -* for more information. -* -* @note The actual number of events available in the pool might be actually -* less than (`poolSize` / `evtSize`) due to the internal alignment -* of the blocks that the pool might perform. You can always check the -* capacity of the pool by calling QF_getPoolMin(). -* -* @note The dynamic allocation of events is optional, meaning that you -* might choose not to use dynamic events. In that case calling QF_poolInit() -* and using up memory for the memory blocks is unnecessary. -* -* @sa QF initialization example for QF_init() -*/ - - - - - - - /*! @pre cannot exceed the number of available memory pools */ -Q_REQUIRE_ID(200, QF_maxPool_ < QF_MAX_EPOOL); - -/*! @pre please initialize event pools in ascending order of evtSize: */ -Q_REQUIRE_ID(201, (QF_maxPool_ == 0U) - || (QF_EPOOL_EVENT_SIZE_(QF_ePool_[QF_maxPool_ - 1U]) - < evtSize)); - -/* perform the platform-dependent initialization of the pool */ -QF_EPOOL_INIT_(QF_ePool_[QF_maxPool_], poolSto, poolSize, evtSize); -++QF_maxPool_; /* one more pool */ - -#ifdef Q_SPY -/* generate the object-dictionary entry for the initialized pool */ -{ - uint8_t obj_name[9] = "EvtPool?"; - obj_name[7] = (uint8_t)(((uint8_t)'0' + QF_maxPool_) & 0x7FU); - QS_obj_dict_pre_(&QF_ePool_[QF_maxPool_ - 1U], (char const *)obj_name); -} -#endif /* Q_SPY*/ - - - - /*! Obtain the block size of any registered event pools. -* @static @public @memberof QF -* -* @details -* Obtain the block size of any registered event pools -*/ - return QF_EPOOL_EVENT_SIZE_(QF_ePool_[QF_maxPool_ - 1U]); - - - - /*! Obtain the minimum of free entries of the given event pool. -* @static @public @memberof QF -* -* @details -* This function obtains the minimum number of free blocks in the given -* event pool since this pool has been initialized by a call to QF_poolInit(). -* -* @param[in] poolId event pool ID in the range 1..QF_maxPool_, where -* QF_maxPool_ is the number of event pools initialized -* with the function QF_poolInit(). -* -* @returns -* the minimum number of unused blocks in the given event pool. -*/ - - - /*! @pre the poolId must be in range */ -Q_REQUIRE_ID(400, (poolId <= QF_MAX_EPOOL) - && (0U < poolId) && (poolId <= QF_maxPool_)); - -QF_CRIT_STAT_ -QF_CRIT_E_(); -uint_fast16_t const min = (uint_fast16_t)QF_ePool_[poolId - 1U].nMin; -QF_CRIT_X_(); - -return min; - - - - /*! Internal QF implementation of creating new dynamic event. -* @static @private @memberof QF -* -* @details -* Allocates an event dynamically from one of the QF event pools. -* -* @param[in] evtSize the size (in bytes) of the event to allocate -* @param[in] margin the number of un-allocated events still available -* in a given event pool after the allocation completes. -* The special value ::QF_NO_MARGIN means that this function -* will assert if allocation fails. -* @param[in] sig the signal to be assigned to the allocated event -* -* @returns -* pointer to the newly allocated event. This pointer can be NULL only if -* margin != #QF_NO_MARGIN and the event cannot be allocated with the -* specified margin still available in the given pool. -* -* @note -* The internal QF function QF_newX_() raises an assertion when the -* `margin` parameter is #QF_NO_MARGIN and allocation of the event turns -* out to be impossible due to event pool depletion, or incorrect (too big) -* size of the requested event. -* -* @note -* The application code should not call this function directly. -* The only allowed use is thorough the macros Q_NEW() or Q_NEW_X(). -*/ - - - - - - - uint_fast8_t idx; - -/* find the pool index that fits the requested event size ... */ -for (idx = 0U; idx < QF_maxPool_; ++idx) { - if (evtSize <= QF_EPOOL_EVENT_SIZE_(QF_ePool_[idx])) { - break; - } -} -/* cannot run out of registered pools */ -Q_ASSERT_ID(310, idx < QF_maxPool_); - -/* get e -- platform-dependent */ -QEvt *e; - -#ifdef Q_SPY -QF_EPOOL_GET_(QF_ePool_[idx], e, - ((margin != QF_NO_MARGIN) ? margin : 0U), - (uint_fast8_t)QS_EP_ID + idx + 1U); -#else -QF_EPOOL_GET_(QF_ePool_[idx], e, - ((margin != QF_NO_MARGIN) ? margin : 0U), 0U); -#endif - -/* was e allocated correctly? */ -QS_CRIT_STAT_ -if (e != (QEvt *)0) { - e->sig = (QSignal)sig; /* set signal for this event */ - e->poolId_ = (uint8_t)(idx + 1U); /* store the pool ID */ - e->refCtr_ = 0U; /* set the reference counter to 0 */ - - QS_BEGIN_PRE_(QS_QF_NEW, (uint_fast8_t)QS_EP_ID + e->poolId_) - QS_TIME_PRE_(); /* timestamp */ - QS_EVS_PRE_(evtSize); /* the size of the event */ - QS_SIG_PRE_(sig); /* the signal of the event */ - QS_END_PRE_() -} -/* event cannot be allocated */ -else { - /* This assertion means that the event allocation failed, - * and this failure cannot be tolerated. The most frequent - * reason is an event leak in the application. - */ - Q_ASSERT_ID(320, margin != QF_NO_MARGIN); - - QS_BEGIN_PRE_(QS_QF_NEW_ATTEMPT, (uint_fast8_t)QS_EP_ID + idx + 1U) - QS_TIME_PRE_(); /* timestamp */ - QS_EVS_PRE_(evtSize); /* the size of the event */ - QS_SIG_PRE_(sig); /* the signal of the event */ - QS_END_PRE_() -} -return e; /* can't be NULL if we can't tolerate failed allocation */ - - - - /*! Recycle a dynamic event -* @static @private @memberof QF -* -* @details -* This function implements a simple garbage collector for the dynamic events. -* Only dynamic events are candidates for recycling. (A dynamic event is one -* that is allocated from an event pool, which is determined as non-zero -* e->poolId_ attribute.) Next, the function decrements the reference counter -* of the event (e->refCtr_), and recycles the event only if the counter drops -* to zero (meaning that no more references are outstanding for this event). -* The dynamic event is recycled by returning it to the pool from which -* it was originally allocated. -* -* @param[in] e pointer to the event to recycle -* -* @note -* QF invokes the garbage collector at all appropriate contexts, when -* an event can become garbage (automatic garbage collection), so the -* application code should have no need to call QF_gc() directly. The QF_gc() -* function is exposed only for special cases when your application sends -* dynamic events to the "raw" thread-safe queues (see ::QEQueue). Such -* queues are processed outside of QF and the automatic garbage collection -* is **NOT** performed for these events. In this case you need to call -* QF_gc() explicitly. -*/ - - - /* is it a dynamic event? */ -if (e->poolId_ != 0U) { - QF_CRIT_STAT_ - QF_CRIT_E_(); - - /* isn't this the last reference? */ - if (e->refCtr_ > 1U) { - - QS_BEGIN_NOCRIT_PRE_(QS_QF_GC_ATTEMPT, - (uint_fast8_t)QS_EP_ID + e->poolId_) - QS_TIME_PRE_(); /* timestamp */ - QS_SIG_PRE_(e->sig); /* the signal of the event */ - QS_2U8_PRE_(e->poolId_, e->refCtr_); /* pool Id & ref Count */ - QS_END_NOCRIT_PRE_() - - QEvt_refCtr_dec_(e); /* decrement the ref counter */ - - QF_CRIT_X_(); - } - /* this is the last reference to this event, recycle it */ - else { - uint_fast8_t const idx = (uint_fast8_t)e->poolId_ - 1U; - - QS_BEGIN_NOCRIT_PRE_(QS_QF_GC, - (uint_fast8_t)QS_EP_ID + e->poolId_) - QS_TIME_PRE_(); /* timestamp */ - QS_SIG_PRE_(e->sig); /* the signal of the event */ - QS_2U8_PRE_(e->poolId_, e->refCtr_); /* pool Id & ref Count */ - QS_END_NOCRIT_PRE_() - - QF_CRIT_X_(); - - /* pool ID must be in range */ - Q_ASSERT_ID(410, idx < QF_maxPool_); - - /* cast 'const' away, which is OK, because it's a pool event */ -#ifdef Q_SPY - QF_EPOOL_PUT_(QF_ePool_[idx], (QEvt *)e, - (uint_fast8_t)QS_EP_ID + e->poolId_); -#else - QF_EPOOL_PUT_(QF_ePool_[idx], (QEvt *)e, 0U); -#endif - } -} - - - - /*! Internal QF implementation of creating new event reference. -* @static @private @memberof QF -* -* @details -* Creates and returns a new reference to the current event e -* -* @param[in] e pointer to the current event -* @param[in] evtRef the event reference -* -* @returns -* the newly created reference to the event `e` -* -* @note -* The application code should not call this function directly. -* The only allowed use is thorough the macro Q_NEW_REF(). -*/ - - - - - #ifdef Q_NASSERT -Q_UNUSED_PAR(evtRef); -#endif - -/*! @pre the event must be dynamic and the provided event reference -* must not be already in use */ -Q_REQUIRE_ID(500, - (e->poolId_ != 0U) - && (evtRef == (void *)0)); - -QF_CRIT_STAT_ -QF_CRIT_E_(); - -QEvt_refCtr_inc_(e); /* increments the ref counter */ - -QS_BEGIN_NOCRIT_PRE_(QS_QF_NEW_REF, - (uint_fast8_t)QS_EP_ID + e->poolId_) - QS_TIME_PRE_(); /* timestamp */ - QS_SIG_PRE_(e->sig); /* the signal of the event */ - QS_2U8_PRE_(e->poolId_, e->refCtr_); /* pool Id & ref Count */ -QS_END_NOCRIT_PRE_() - -QF_CRIT_X_(); - -return e; - - - - /*! Internal QF implementation of deleting event reference. -* @static @private @memberof QF -* -* @details -* Deletes an existing reference to the event e -* -* @param[in] evtRef the event reference -* -* @note -* The application code should not call this function directly. -* The only allowed use is thorough the macro Q_DELETE_REF(). -*/ - - - QS_CRIT_STAT_ -QEvt const * const e = (QEvt const *)evtRef; - -QS_BEGIN_PRE_(QS_QF_DELETE_REF, - (uint_fast8_t)QS_EP_ID + e->poolId_) - QS_TIME_PRE_(); /* timestamp */ - QS_SIG_PRE_(e->sig); /* the signal of the event */ - QS_2U8_PRE_(e->poolId_, e->refCtr_); /* pool Id & ref Count */ -QS_END_PRE_() - -#if (QF_MAX_EPOOL > 0U) -QF_gc(e); -#endif - - - - - - - /*! array of event pools managed by QF */ - - - - /*! number of initialized event pools */ - - - - /*! "Ready-set" of all threads used in the built-in kernels -* @static @private @memberof QF -*/ - - - - /*! Clear a specified region of memory to zero. -* @static @public @memberof QF -* -* @details -* Clears a memory buffer by writing zeros byte-by-byte. -* -* @param[in] start pointer to the beginning of a memory buffer. -* @param[in] len length of the memory buffer to clear (in bytes) -* -* @note The main application of this function is clearing the internal QF -* variables upon startup. This is done to avoid problems with non-standard -* startup code provided with some compilers and toolsets (e.g., TI DSPs or -* Microchip MPLAB), which does not zero the uninitialized variables, as -* required by the ANSI C standard. -*/ - - - - - uint8_t *ptr = (uint8_t *)start; -for (uint_fast16_t n = len; n > 0U; --n) { - *ptr = 0U; - ++ptr; -} - - - - - - - /*! QF context switch callback used in built-in kernels (QV, QK, QXK) -* @static @public @memberof QF -* -* @details -* This callback function provides a mechanism to perform additional -* custom operations when one of the built-in kernels switches context -* from one thread to another. -* -* @param[in] prev pointer to the previous thread (active object) -* (prev==0 means that `prev` was the idle loop) -* @param[in] next pointer to the next thread (active object) -* (next==0) means that `next` is the idle loop) -* @attention -* QF_onContextSw() is invoked with interrupts **disabled** and must also -* return with interrupts **disabled**. -* -* @note -* This callback is enabled by defining the macro #QF_ON_CONTEXT_SW. -* -* @include qf_oncontextsw.c -*/ - - - - - - - - - - + + + - Native QF event pool QMPool - + - Native QF event pool initialization - + - + - + - + \ (QMPool_init(&(p_), (poolSto_), (poolSize_), (evtSize_))) - + - Native QF event pool event-size getter - + ((uint_fast16_t)(p_).blockSize) - + - Native QF event pool get-event - + - + - + - + \ ((e_) = (QEvt *)QMPool_get(&(p_), (m_), (qs_id_))) - + - Native QF event pool put-event - + - + - - + + \ (QMPool_put(&(p_), (e_), (qs_id_))) - - - - - /*! The size [bytes] of the internal QS buffer-counters. Valid values: 2U or 4U; -* default 2U. -* -* @details -* This macro can be defined in the QS port file (qs_port.h) to -* configure the ::QSCtr type. Here the macro is not defined so the -* default of 2 byte is chosen. -*/ - 2U + + + + + // @class QV + { + //! @cond INTERNAL + uint8_t dummy; + //! @endcond +} QV; - - - - - /*! The size [bytes] of the QS time stamp. Valid values: 1U, 2U, or 4U; -* default 4U. -* -* @details -* This macro can be defined in the QS port file (qs_port.h) to -* configure the ::QSTimeCtr type. Here the macro is not defined so the -* default of 4 byte is chosen. -*/ - 4U + + + + + //! @class QV_Attr + + + //! @memberof QV_Attr + + + + //! @memberof QV_Attr + + + + + //! @static @private @memberof QV + + + + //! @static @public @memberof QV + +//! @static @public @memberof QV + + + + + + + //! @static @public @memberof QF + +//! @static @public @memberof QF + QF_bzero_(&QF_priv_, sizeof(QF_priv_)); +QF_bzero_(&QV_priv_, sizeof(QV_priv_)); +QF_bzero_(&QTimeEvt_timeEvtHead_[0], sizeof(QTimeEvt_timeEvtHead_)); +QF_bzero_(&QActive_registry_[0], sizeof(QActive_registry_)); + +#ifndef Q_UNSAFE +QPSet_update_(&QV_priv_.readySet, &QV_priv_.readySet_dis); +#endif + +#ifdef QV_INIT +QV_INIT(); // port-specific initialization of the QV kernel +#endif + + + + //! @static @public @memberof QF + +//! @static @public @memberof QF + QF_onCleanup(); // application-specific cleanup callback +// nothing else to do for the cooperative QV kernel + + + + //! @static @public @memberof QF + +//! @static @public @memberof QF + #ifdef Q_SPY +// produce the QS_QF_RUN trace record +QF_INT_DISABLE(); +QF_MEM_SYS(); +QS_beginRec_((uint_fast8_t)QS_QF_RUN); +QS_endRec_(); +QF_MEM_APP(); +QF_INT_ENABLE(); +#endif // Q_SPY + +QF_onStartup(); // application-specific startup callback + +QF_INT_DISABLE(); +QF_MEM_SYS(); + +#ifdef QV_START +QV_START(); // port-specific startup of the QV kernel +#endif + +#if (defined QF_ON_CONTEXT_SW) || (defined Q_SPY) +uint8_t pprev = 0U; // previously used prio. +#endif + +for (;;) { // QV event loop... + + // check internal integrity (duplicate inverse storage) + Q_ASSERT_INCRIT(202, QPSet_verify_(&QV_priv_.readySet, + &QV_priv_.readySet_dis)); + + // find the maximum prio. AO ready to run + if (QPSet_notEmpty(&QV_priv_.readySet)) { + + uint8_t const p = (uint8_t)QPSet_findMax(&QV_priv_.readySet); + QActive * const a = QActive_registry_[p]; + +#if (defined QF_ON_CONTEXT_SW) || (defined Q_SPY) + QS_BEGIN_PRE_(QS_SCHED_NEXT, p) + QS_TIME_PRE_(); // timestamp + QS_2U8_PRE_(p, pprev); // scheduled prio & previous prio + QS_END_PRE_() + +#ifdef QF_ON_CONTEXT_SW + QF_onContextSw(((pprev != 0U) + ? QActive_registry_[pprev] + : (QActive *)0), a); +#endif // QF_ON_CONTEXT_SW + + pprev = p; // update previous prio. +#endif // (defined QF_ON_CONTEXT_SW) || (defined Q_SPY) + + QF_MEM_APP(); + QF_INT_ENABLE(); + + QEvt const * const e = QActive_get_(a); + // NOTE QActive_get_() performs QS_MEM_APP() before return + + // dispatch event (virtual call) + (*a->super.vptr->dispatch)(&a->super, e, p); +#if (QF_MAX_EPOOL > 0U) + QF_gc(e); +#endif + QF_INT_DISABLE(); + QF_MEM_SYS(); + + if (a->eQueue.frontEvt == (QEvt *)0) { // empty queue? + QPSet_remove(&QV_priv_.readySet, p); +#ifndef Q_UNSAFE + QPSet_update_(&QV_priv_.readySet, &QV_priv_.readySet_dis); +#endif + } + } + else { // no AO ready to run --> idle +#if (defined QF_ON_CONTEXT_SW) || (defined Q_SPY) + if (pprev != 0U) { + QS_BEGIN_PRE_(QS_SCHED_IDLE, pprev) + QS_TIME_PRE_(); // timestamp + QS_U8_PRE_(pprev); // previous prio + QS_END_PRE_() + +#ifdef QF_ON_CONTEXT_SW + QF_onContextSw(QActive_registry_[pprev], (QActive *)0); +#endif // QF_ON_CONTEXT_SW + + pprev = 0U; // update previous prio. + } +#endif // (defined QF_ON_CONTEXT_SW) || (defined Q_SPY) + + QF_MEM_APP(); + + // QV_onIdle() must be called with interrupts DISABLED + // because the determination of the idle condition (all event + // queues empty) can change at any time by an interrupt posting + // events to a queue. + // + // NOTE: QV_onIdle() MUST enable interrupts internally, + // ideally at the same time as putting the CPU into a power- + // saving mode. + QV_onIdle(); + + QF_INT_DISABLE(); // disable interrupts before looping back + QF_MEM_SYS(); + } +} +#ifdef __GNUC__ // GNU compiler? +return 0; +#endif + + + + + //! QActive active object class customization for QV + + + //! @public @memberof QActive + +//! @public @memberof QActive + + + + + + + + + + + + + Q_UNUSED_PAR(stkSto); // not needed in QV +Q_UNUSED_PAR(stkSize); // not needed in QV + +QF_CRIT_STAT +QF_CRIT_ENTRY(); +Q_REQUIRE_INCRIT(300, stkSto == (void *)0); +QF_CRIT_EXIT(); + +me->prio = (uint8_t)(prioSpec & 0xFFU); // QF-prio. of the AO +me->pthre = (uint8_t)(prioSpec >> 8U); // preemption-threshold +QActive_register_(me); // make QF aware of this active object + +QEQueue_init(&me->eQueue, qSto, qLen); // init the built-in queue + +// top-most initial tran. (virtual call) +(*me->super.vptr->init)(&me->super, par, me->prio); +QS_FLUSH(); // flush the trace buffer to the host + + + + + + + + + + + + ((void)0) + + + + ((void)0) + + + + + + \ + Q_ASSERT_INCRIT(310, (me_)->eQueue.frontEvt != (QEvt *)0) + + + + + + \ + QPSet_insert(&QV_priv_.readySet, (uint_fast8_t)(me_)->prio); \ + QPSet_update_(&QV_priv_.readySet, &QV_priv_.readySet_dis) + + + + + + \ + QPSet_insert(&QV_priv_.readySet, (uint_fast8_t)(me_)->prio) + + + + + + + // @class QK + { + //! @cond INTERNAL + uint8_t dummy; + //! @endcond +} QK; - - + + + + + + + //! @class QK_Attr + + + //! @memberof QK_Attr + + + + //! @memberof QK_Attr + + + + //! @memberof QK_Attr + + + + //! @memberof QK_Attr + + + + //! @memberof QK_Attr + + + + //! @memberof QK_Attr + + + + //! @memberof QK_Attr + + + + //! @memberof QK_Attr + + + + + //! @static @private @memberof QK + + + + //! @static @public @memberof QK + +//! @static @public @memberof QK + + + QF_CRIT_STAT +QF_CRIT_ENTRY(); +QF_MEM_SYS(); + +Q_REQUIRE_INCRIT(100, !QK_ISR_CONTEXT_()); + +// first store the previous lock prio +QSchedStatus stat; +if (ceiling > QK_priv_.lockCeil) { // raising the lock ceiling? + QS_BEGIN_PRE_(QS_SCHED_LOCK, 0U) + QS_TIME_PRE_(); // timestamp + // the previous lock ceiling & new lock ceiling + QS_2U8_PRE_((uint8_t)QK_priv_.lockCeil, + (uint8_t)ceiling); + QS_END_PRE_() + + // previous status of the lock + stat = (QSchedStatus)QK_priv_.lockHolder; + stat |= (QSchedStatus)QK_priv_.lockCeil << 8U; + + // new status of the lock + QK_priv_.lockHolder = QK_priv_.actPrio; + QK_priv_.lockCeil = ceiling; +} +else { + stat = 0xFFU; // scheduler not locked +} + +QF_MEM_APP(); +QF_CRIT_EXIT(); + +return stat; // return the status to be saved in a stack variable + + + + //! @static @public @memberof QK + +//! @static @public @memberof QK + + + // has the scheduler been actually locked by the last QK_schedLock()? +if (stat != 0xFFU) { + QF_CRIT_STAT + QF_CRIT_ENTRY(); + QF_MEM_SYS(); + + uint_fast8_t const lockCeil = QK_priv_.lockCeil; + uint_fast8_t const prevCeil = (stat >> 8U); + Q_REQUIRE_INCRIT(200, (!QK_ISR_CONTEXT_()) + && (lockCeil > prevCeil)); + + QS_BEGIN_PRE_(QS_SCHED_UNLOCK, 0U) + QS_TIME_PRE_(); // timestamp + // current lock ceiling (old), previous lock ceiling (new) + QS_2U8_PRE_((uint8_t)lockCeil, (uint8_t)prevCeil); + QS_END_PRE_() + + // restore the previous lock ceiling and lock holder + QK_priv_.lockCeil = prevCeil; + QK_priv_.lockHolder = (stat & 0xFFU); + + // find if any AOs should be run after unlocking the scheduler + if (QK_sched_() != 0U) { // preemption needed? + QK_activate_(); // activate any unlocked AOs + } + + QF_MEM_APP(); + QF_CRIT_EXIT(); +} + + + + //! @static @public @memberof QK + +//! @static @public @memberof QK + + + + //! @static @private @memberof QK + +//! @static @private @memberof QK + Q_REQUIRE_INCRIT(400, QPSet_verify_(&QK_priv_.readySet, + &QK_priv_.readySet_dis)); + +uint_fast8_t p; +if (QPSet_isEmpty(&QK_priv_.readySet)) { + p = 0U; // no activation needed +} +else { + // find the highest-prio AO with non-empty event queue + p = QPSet_findMax(&QK_priv_.readySet); + + // is the AO's prio. below the active preemption-threshold? + if (p <= QK_priv_.actThre) { + p = 0U; // no activation needed + } + // is the AO's prio. below the lock-ceiling? + else if (p <= QK_priv_.lockCeil) { + p = 0U; // no activation needed + } + else { + QK_priv_.nextPrio = p; // next AO to run + } +} + +return p; + + + + //! @static @private @memberof QK + +//! @static @private @memberof QK + uint_fast8_t const prio_in = QK_priv_.actPrio; // save initial prio. +uint_fast8_t p = QK_priv_.nextPrio; // next prio to run +QK_priv_.nextPrio = 0U; // clear for the next time + +Q_REQUIRE_INCRIT(500, (prio_in <= QF_MAX_ACTIVE) + && (0U < p) && (p <= QF_MAX_ACTIVE)); + +#if (defined QF_ON_CONTEXT_SW) || (defined Q_SPY) +uint_fast8_t pprev = prio_in; +#endif // QF_ON_CONTEXT_SW || Q_SPY + +// loop until no more ready-to-run AOs of higher pthre than the initial +QActive *a; +do { + a = QActive_registry_[p]; // obtain the pointer to the AO + Q_ASSERT_INCRIT(505, a != (QActive *)0); // the AO must be registered + + // set new active prio. and preemption-threshold + QK_priv_.actPrio = p; + QK_priv_.actThre = a->pthre; + +#if (defined QF_ON_CONTEXT_SW) || (defined Q_SPY) + if (p != pprev) { // changing threads? + + QS_BEGIN_PRE_(QS_SCHED_NEXT, p) + QS_TIME_PRE_(); // timestamp + QS_2U8_PRE_(p, // prio. of the scheduled AO + pprev); // previous prio. + QS_END_PRE_() + +#ifdef QF_ON_CONTEXT_SW + QF_onContextSw(((pprev != 0U) + ? QActive_registry_[pprev] + : (QActive *)0), a); +#endif // QF_ON_CONTEXT_SW + + pprev = p; // update previous prio. + } +#endif // QF_ON_CONTEXT_SW || Q_SPY + + QF_INT_ENABLE(); // unconditionally enable interrupts + + QEvt const * const e = QActive_get_(a); + // NOTE QActive_get_() performs QF_MEM_APP() before return + + // dispatch event (virtual call) + (*a->super.vptr->dispatch)(&a->super, e, p); +#if (QF_MAX_EPOOL > 0U) + QF_gc(e); +#endif + + // determine the next highest-prio. AO ready to run... + QF_INT_DISABLE(); // unconditionally disable interrupts + QF_MEM_SYS(); + + // internal integrity check (duplicate inverse storage) + Q_ASSERT_INCRIT(502, QPSet_verify_(&QK_priv_.readySet, + &QK_priv_.readySet_dis)); + + if (a->eQueue.frontEvt == (QEvt *)0) { // empty queue? + QPSet_remove(&QK_priv_.readySet, p); +#ifndef Q_UNSAFE + QPSet_update_(&QK_priv_.readySet, &QK_priv_.readySet_dis); +#endif + } + + if (QPSet_isEmpty(&QK_priv_.readySet)) { + p = 0U; // no activation needed + } + else { + // find new highest-prio AO ready to run... + p = (uint8_t)QPSet_findMax(&QK_priv_.readySet); + + // is the new prio. below the initial preemption-threshold? + if (p <= QActive_registry_[prio_in]->pthre) { + p = 0U; // no activation needed + } + // is the AO's prio. below the lock preemption-threshold? + else if (p <= QK_priv_.lockCeil) { + p = 0U; // no activation needed + } + else { + Q_ASSERT_INCRIT(510, p <= QF_MAX_ACTIVE); + } + } +} while (p != 0U); + +// restore the active prio. and preemption-threshold +QK_priv_.actPrio = prio_in; +QK_priv_.actThre = (uint_fast8_t)QActive_registry_[prio_in]->pthre; + +#if (defined QF_ON_CONTEXT_SW) || (defined Q_SPY) +if (prio_in != 0U) { // resuming an active object? + a = QActive_registry_[prio_in]; // pointer to preempted AO + + QS_BEGIN_PRE_(QS_SCHED_NEXT, prio_in) + QS_TIME_PRE_(); // timestamp + // prio. of the resumed AO, previous prio. + QS_2U8_PRE_(prio_in, pprev); + QS_END_PRE_() +} +else { // resuming prio.==0 --> idle + a = (QActive *)0; // QK idle loop + + QS_BEGIN_PRE_(QS_SCHED_IDLE, pprev) + QS_TIME_PRE_(); // timestamp + QS_U8_PRE_(pprev); // previous prio. + QS_END_PRE_() +} + +#ifdef QF_ON_CONTEXT_SW +QF_onContextSw(QActive_registry_[pprev], a); +#endif // QF_ON_CONTEXT_SW + +#endif // QF_ON_CONTEXT_SW || Q_SPY + + + + + + + //! @static @public @memberof QF + +//! @static @public @memberof QF + QF_bzero_(&QF_priv_, sizeof(QF_priv_)); +QF_bzero_(&QK_priv_, sizeof(QK_priv_)); +QF_bzero_(&QTimeEvt_timeEvtHead_[0], sizeof(QTimeEvt_timeEvtHead_)); +QF_bzero_(&QActive_registry_[0], sizeof(QActive_registry_)); + +#ifndef Q_UNSAFE +QPSet_update_(&QK_priv_.readySet, &QK_priv_.readySet_dis); +#endif + +// setup the QK scheduler as initially locked and not running +QK_priv_.lockCeil = (QF_MAX_ACTIVE + 1U); // scheduler locked + +// QK idle AO object (const in ROM) +static QActive const idle_ao = { (struct QAsmVtable const *)0 }; + +// register the idle AO object (cast 'const' away) +QActive_registry_[0] = QACTIVE_CAST_(&idle_ao); + +#ifdef QK_INIT +QK_INIT(); // port-specific initialization of the QK kernel +#endif + + + + //! @static @public @memberof QF + +//! @static @public @memberof QF + QF_onCleanup(); // application-specific cleanup callback +// nothing else to do for the preemptive QK kernel + + + + //! @static @public @memberof QF + +//! @static @public @memberof QF + #ifdef Q_SPY +// produce the QS_QF_RUN trace record +QF_INT_DISABLE(); +QF_MEM_SYS(); +QS_beginRec_((uint_fast8_t)QS_QF_RUN); +QS_endRec_(); +QF_MEM_APP(); +QF_INT_ENABLE(); +#endif // Q_SPY + +QF_onStartup(); // application-specific startup callback + +QF_INT_DISABLE(); +QF_MEM_SYS(); + +QK_priv_.lockCeil = 0U; // unlock the QK scheduler + +// activate AOs to process events posted so far +if (QK_sched_() != 0U) { + QK_activate_(); +} + +#ifdef QK_START +QK_START(); // port-specific startup of the QK kernel +#endif + +QF_MEM_APP(); +QF_INT_ENABLE(); + +for (;;) { // QK idle loop... + QK_onIdle(); // application-specific QK on-idle callback +} + +#ifdef __GNUC__ +return 0; +#endif + + + + + // QActive class customization for QK + + + //! @public @memberof QActive + +//! @public @memberof QActive + + + + + + + + + + + + + Q_UNUSED_PAR(stkSto); // not needed in QK +Q_UNUSED_PAR(stkSize); // not needed in QK + +QF_CRIT_STAT +QF_CRIT_ENTRY(); +QF_MEM_SYS(); + +Q_REQUIRE_INCRIT(300, (!QK_ISR_CONTEXT_()) + && (stkSto == (void *)0)); +QF_MEM_APP(); +QF_CRIT_EXIT(); + +me->prio = (uint8_t)(prioSpec & 0xFFU); // QF-prio. of the AO +me->pthre = (uint8_t)(prioSpec >> 8U); // preemption-threshold +QActive_register_(me); // make QF aware of this active object + +QEQueue_init(&me->eQueue, qSto, qLen); // init the built-in queue + +// top-most initial tran. (virtual call) +(*me->super.vptr->init)(&me->super, par, me->prio); +QS_FLUSH(); // flush the trace buffer to the host + +// See if this AO needs to be scheduled if QK is already running +QF_CRIT_ENTRY(); +QF_MEM_SYS(); +if (QK_sched_() != 0U) { // activation needed? + QK_activate_(); +} +QF_MEM_APP(); +QF_CRIT_EXIT(); + + + + + + + + QSchedStatus lockStat_; + + + + + + do { \ + if (QK_ISR_CONTEXT_()) { \ + lockStat_ = 0xFFU; \ + } else { \ + lockStat_ = QK_schedLock((ceil_)); \ + } \ +} while (false) + + + + do { \ + if (lockStat_ != 0xFFU) { \ + QK_schedUnlock(lockStat_); \ + } \ +} while (false) + + + + + + \ + Q_ASSERT_INCRIT(320, (me_)->eQueue.frontEvt != (QEvt *)0) + + + + + + do { \ + QPSet_insert(&QK_priv_.readySet, (uint_fast8_t)(me_)->prio); \ + QPSet_update_(&QK_priv_.readySet, &QK_priv_.readySet_dis); \ + if (!QK_ISR_CONTEXT_()) { \ + if (QK_sched_() != 0U) { \ + QK_activate_(); \ + } \ + } \ +} while (false) + + + + + + do { \ + QPSet_insert(&QK_priv_.readySet, (uint_fast8_t)(me_)->prio); \ + if (!QK_ISR_CONTEXT_()) { \ + if (QK_sched_() != 0U) { \ + QK_activate_(); \ + } \ + } \ +} while (false) + + + + + + + // @class QXK + { + //! @cond INTERNAL + uint8_t dummy; + //! @endcond +} QXK; + + + + + + ((QTimeEvtCtr)0) + + + + + + //! @class QXK_Attr + + + //! @memberof QXK_Attr + + + + //! @memberof QXK_Attr + + + + //! @memberof QXK_Attr + + + + //! @memberof QXK_Attr + + + + //! @memberof QXK_Attr + + + + //! @memberof QXK_Attr + + + + //! @memberof QXK_Attr + + + + //! @memberof QXK_Attr + + + + + //! @static @private @memberof QXK + + + + //! @static @public @memberof QXK + +//! @static @public @memberof QXK + + + + //! @static @public @memberof QXK + +//! @static @public @memberof QXK + + + QF_CRIT_STAT +QF_CRIT_ENTRY(); +QF_MEM_SYS(); + +Q_REQUIRE_INCRIT(100, !QXK_ISR_CONTEXT_()); + +QSchedStatus stat; // saved lock status to be returned + +// is the lock ceiling being raised? +if (ceiling > QXK_priv_.lockCeil) { + QS_BEGIN_PRE_(QS_SCHED_LOCK, 0U) + QS_TIME_PRE_(); // timestamp + // the previous lock ceiling & new lock ceiling + QS_2U8_PRE_((uint8_t)QXK_priv_.lockCeil, (uint8_t)ceiling); + QS_END_PRE_() + + // previous status of the lock + stat = (QSchedStatus)QXK_priv_.lockHolder; + stat |= (QSchedStatus)QXK_priv_.lockCeil << 8U; + + // new status of the lock + QXK_priv_.lockHolder = (QXK_priv_.curr != (QActive *)0) + ? (uint_fast8_t)QXK_priv_.curr->prio + : 0U; + QXK_priv_.lockCeil = ceiling; +} +else { + stat = 0xFFU; // scheduler not locked +} +QF_MEM_APP(); +QF_CRIT_EXIT(); + +return stat; // return the status to be saved in a stack variable + + + + //! @static @public @memberof QXK + +//! @static @public @memberof QXK + + + // has the scheduler been actually locked by the last QXK_schedLock()? +if (stat != 0xFFU) { + uint8_t const prevCeil = (uint8_t)(stat >> 8U); + QF_CRIT_STAT + QF_CRIT_ENTRY(); + QF_MEM_SYS(); + + Q_REQUIRE_INCRIT(200, !QXK_ISR_CONTEXT_()); + Q_REQUIRE_INCRIT(201, QXK_priv_.lockCeil > prevCeil); + + QS_BEGIN_PRE_(QS_SCHED_UNLOCK, 0U) + QS_TIME_PRE_(); // timestamp + // ceiling before unlocking & prio after unlocking + QS_2U8_PRE_((uint8_t)QXK_priv_.lockCeil, (uint8_t)prevCeil); + QS_END_PRE_() + + // restore the previous lock ceiling and lock holder + QXK_priv_.lockCeil = prevCeil; + QXK_priv_.lockHolder = (stat & 0xFFU); + + // find if any threads should be run after unlocking the scheduler + if (QXK_sched_() != 0U) { // activation needed? + QXK_activate_(); // synchronously activate basic-thred(s) + } + + QF_MEM_APP(); + QF_CRIT_EXIT(); +} + + + + //! @static @public @memberof QXK + +//! @static @public @memberof QXK + QF_CRIT_STAT +QF_CRIT_ENTRY(); +QF_MEM_SYS(); + +Q_REQUIRE_INCRIT(600, QXK_priv_.lockCeil <= QF_MAX_ACTIVE); + +struct QActive *curr = QXK_priv_.curr; +if (curr == (QActive *)0) { // basic thread? + curr = QActive_registry_[QXK_priv_.actPrio]; +} + +Q_ASSERT_INCRIT(690, curr != (QActive *)0); + +QF_MEM_APP(); +QF_CRIT_EXIT(); + +return curr; + + + + //! @static @private @memberof QXK + +//! @static @private @memberof QXK + Q_REQUIRE_INCRIT(402, QPSet_verify_(&QXK_priv_.readySet, + &QXK_priv_.readySet_dis)); +uint_fast8_t p; +if (QPSet_isEmpty(&QXK_priv_.readySet)) { + p = 0U; // no activation needed +} +else { + // find the highest-prio thread ready to run + p = QPSet_findMax(&QXK_priv_.readySet); + if (p <= QXK_priv_.lockCeil) { + // prio. of the thread holding the lock + p = (uint_fast8_t)QActive_registry_[QXK_priv_.lockHolder]->prio; + if (p != 0U) { + Q_ASSERT_INCRIT(410, + QPSet_hasElement(&QXK_priv_.readySet, p)); + } + } +} +QActive const * const curr = QXK_priv_.curr; +QActive * const next = QActive_registry_[p]; + +// the next thread found must be registered in QF +Q_ASSERT_INCRIT(420, next != (QActive *)0); + +// is the current thread a basic-thread? +if (curr == (QActive *)0) { + + // is the new prio. above the active prio.? + if (p > QXK_priv_.actPrio) { + QXK_priv_.next = next; // set the next AO to activate + + if (next->osObject != (void *)0) { // is next extended? + QXK_CONTEXT_SWITCH_(); + p = 0U; // no activation needed + } + } + else { // below the pre-thre + QXK_priv_.next = (QActive *)0; + p = 0U; // no activation needed + } +} +else { // currently executing an extended-thread + // is the current thread different from the next? + if (curr != next) { + QXK_priv_.next = next; + QXK_CONTEXT_SWITCH_(); + } + else { // current is the same as next + QXK_priv_.next = (QActive *)0; // no need to context-switch + } + p = 0U; // no activation needed +} + +return p; + + + + //! @static @private @memberof QXK + +//! @static @private @memberof QXK + uint_fast8_t const prio_in = QXK_priv_.actPrio; +QActive *next = QXK_priv_.next; // the next AO (basic-thread) to run + +Q_REQUIRE_INCRIT(500, (next != (QActive *)0) + && (prio_in <= QF_MAX_ACTIVE)); + +// QXK Context switch callback defined or QS tracing enabled? +#if (defined QF_ON_CONTEXT_SW) || (defined Q_SPY) +QXK_contextSw_(next); +#endif // QF_ON_CONTEXT_SW || Q_SPY + +QXK_priv_.next = (QActive *)0; // clear the next AO +QXK_priv_.curr = (QActive *)0; // current is basic-thread + +// prio. of the next thread +uint_fast8_t p = (uint_fast8_t)next->prio; + +// loop until no more ready-to-run AOs of higher prio than the initial +do { + QXK_priv_.actPrio = p; // next active prio + + QF_INT_ENABLE(); // unconditionally enable interrupts + + QEvt const * const e = QActive_get_(next); + // NOTE QActive_get_() performs QS_MEM_APP() before return + + // dispatch event (virtual call) + (*next->super.vptr->dispatch)(&next->super, e, p); +#if (QF_MAX_EPOOL > 0U) + QF_gc(e); +#endif + + QF_INT_DISABLE(); // unconditionally disable interrupts + QF_MEM_SYS(); + + // check internal integrity (duplicate inverse storage) + Q_ASSERT_INCRIT(502, QPSet_verify_(&QXK_priv_.readySet, + &QXK_priv_.readySet_dis)); + + if (next->eQueue.frontEvt == (QEvt *)0) { // empty queue? + QPSet_remove(&QXK_priv_.readySet, p); +#ifndef Q_UNSAFE + QPSet_update_(&QXK_priv_.readySet, &QXK_priv_.readySet_dis); +#endif + } + + if (QPSet_isEmpty(&QXK_priv_.readySet)) { + QXK_priv_.next = (QActive *)0; + next = QActive_registry_[0]; + p = 0U; // no activation needed + } + else { + // find next highest-prio below the lock ceiling + p = (uint8_t)QPSet_findMax(&QXK_priv_.readySet); + if (p <= QXK_priv_.lockCeil) { + p = QXK_priv_.lockHolder; // thread holding lock + if (p != 0U) { + Q_ASSERT_INCRIT(510, + QPSet_hasElement(&QXK_priv_.readySet, p)); + } + } + + // set the next thread and ensure that it is registered + next = QActive_registry_[p]; + Q_ASSERT_INCRIT(520, next != (QActive *)0); + + // is next a basic thread? + if (next->osObject == (void *)0) { + // is the next prio. above the initial prio.? + if (p > QActive_registry_[prio_in]->prio) { +#if (defined QF_ON_CONTEXT_SW) || (defined Q_SPY) + if (p != QXK_priv_.actPrio) { // changing threads? + QXK_contextSw_(next); + } +#endif // QF_ON_CONTEXT_SW || Q_SPY + QXK_priv_.next = next; + } + else { + QXK_priv_.next = (QActive *)0; + p = 0U; // no activation needed + } + } + else { // next is the extended-thread + QXK_priv_.next = next; + QXK_CONTEXT_SWITCH_(); + p = 0U; // no activation needed + } + } +} while (p != 0U); // while activation needed + +// restore the active prio. +QXK_priv_.actPrio = prio_in; + +#if (defined QF_ON_CONTEXT_SW) || (defined Q_SPY) +if (next->osObject == (void *)0) { + QXK_contextSw_((prio_in == 0U) + ? (QActive *)0 + : QActive_registry_[prio_in]); +} +#endif // QF_ON_CONTEXT_SW || Q_SPY + + + + __attribute__(( used )) + //! @static @public @memberof QXK + +//! @static @public @memberof QXK + + + #ifdef Q_SPY +uint8_t const prev_prio = (QXK_priv_.prev != (QActive *)0) + ? QXK_priv_.prev->prio + : 0U; +if (next != (QActive *)0) { // next is NOT idle? + QS_BEGIN_PRE_(QS_SCHED_NEXT, next->prio) + QS_TIME_PRE_(); // timestamp + QS_2U8_PRE_(next->prio, prev_prio); + QS_END_PRE_() +} +else { // going to idle + QS_BEGIN_PRE_(QS_SCHED_IDLE, prev_prio) + QS_TIME_PRE_(); // timestamp + QS_U8_PRE_(prev_prio); + QS_END_PRE_() +} +#endif // Q_SPY + +#ifdef QF_ON_CONTEXT_SW +QF_onContextSw(QXK_priv_.prev, next); +#endif // QF_ON_CONTEXT_SW + +QXK_priv_.prev = next; // update the previous thread + + + + //! @static @private @memberof QXK + +//! @static @private @memberof QXK + QF_CRIT_STAT +QF_CRIT_ENTRY(); + +QXThread const * const thr = QXTHREAD_CAST_(QXK_priv_.curr); + +Q_REQUIRE_INCRIT(900, (!QXK_ISR_CONTEXT_()) + && (thr != (QXThread *)0)); // current thread must be extended +Q_REQUIRE_INCRIT(901, + QXK_priv_.lockHolder != (uint_fast8_t)thr->super.prio); + +uint_fast8_t const p = (uint_fast8_t)thr->super.prio; + +QF_MEM_SYS(); +QActive_registry_[p] = (QActive *)0; +QPSet_remove(&QXK_priv_.readySet, p); +#ifndef Q_UNSAFE +QPSet_update_(&QXK_priv_.readySet, &QXK_priv_.readySet_dis); +#endif + +(void)QXK_sched_(); // schedule other threads + +QF_MEM_APP(); +QF_CRIT_EXIT(); + + + + + + + //! @static @public @memberof QF + +//! @static @public @memberof QF + QF_bzero_(&QF_priv_, sizeof(QF_priv_)); +QF_bzero_(&QXK_priv_, sizeof(QXK_priv_)); +QF_bzero_(&QTimeEvt_timeEvtHead_[0], sizeof(QTimeEvt_timeEvtHead_)); +QF_bzero_(&QActive_registry_[0], sizeof(QActive_registry_)); + +#ifndef Q_UNSAFE +QPSet_update_(&QXK_priv_.readySet, &QXK_priv_.readySet_dis); +#endif + +// setup the QXK scheduler as initially locked and not running +QXK_priv_.lockCeil = (QF_MAX_ACTIVE + 1U); // scheduler locked + +// QXK idle AO object (const in ROM) +static QActive const idle_ao = { (struct QAsmVtable const *)0 }; + +// register the idle AO object (cast 'const' away) +QActive_registry_[0] = QACTIVE_CAST_(&idle_ao); +QXK_priv_.prev = QActive_registry_[0]; + +#ifdef QXK_INIT +QXK_INIT(); // port-specific initialization of the QXK kernel +#endif + + + + //! @static @public @memberof QF + +//! @static @public @memberof QF + QF_onCleanup(); // application-specific cleanup callback +// nothing else to do for the dual-mode QXK kernel + + + + //! @static @public @memberof QF + +//! @static @public @memberof QF + #ifdef Q_SPY +QS_SIG_DICTIONARY(QXK_DELAY_SIG, (void *)0); +QS_SIG_DICTIONARY(QXK_TIMEOUT_SIG, (void *)0); + +// produce the QS_QF_RUN trace record +QF_INT_DISABLE(); +QF_MEM_SYS(); +QS_beginRec_((uint_fast8_t)QS_QF_RUN); +QS_endRec_(); +QF_MEM_APP(); +QF_INT_ENABLE(); +#endif // Q_SPY + +QF_onStartup(); // application-specific startup callback + +QF_INT_DISABLE(); +QF_MEM_SYS(); + +QXK_priv_.lockCeil = 0U; // unlock the QXK scheduler + +// activate AOs to process events posted so far +if (QXK_sched_() != 0U) { + QXK_activate_(); +} + +#ifdef QXK_START +QXK_START(); // port-specific startup of the QXK kernel +#endif + +QF_MEM_APP(); +QF_INT_ENABLE(); + +for (;;) { // QXK idle loop... + QXK_onIdle(); // application-specific QXK idle callback +} + +#ifdef __GNUC__ // GNU compiler? +return 0; +#endif + + + + + // QActive active object class customization for QK + + + //! @public @memberof QActive + +//! @public @memberof QActive + + + + + + + + + + + + + QF_CRIT_STAT +QF_CRIT_ENTRY(); +Q_REQUIRE_INCRIT(300, (!QXK_ISR_CONTEXT_()) + && ((prioSpec & 0xFF00U) == 0U)); +QF_CRIT_EXIT(); + +me->prio = (uint8_t)(prioSpec & 0xFFU); // QF-prio. of the AO +me->pthre = 0U; // preemption-threshold NOT used +QActive_register_(me); // make QF aware of this active object + +if (stkSto == (void *)0) { // starting basic thread (AO)? + + QEQueue_init(&me->eQueue, qSto, qLen); // init the built-in queue + me->osObject = (void *)0; // no private stack for AO + + // top-most initial tran. (virtual call) + (*me->super.vptr->init)(&me->super, par, me->prio); + QS_FLUSH(); // flush the trace buffer to the host + + // see if this AO needs to be scheduled if QXK is already running + QF_CRIT_ENTRY(); + QF_MEM_SYS(); + if (QXK_priv_.lockCeil <= QF_MAX_ACTIVE) { // scheduler running? + if (QXK_sched_() != 0U) { // activation needed? + QXK_activate_(); // synchronously activate basic-thred(s) + } + } + QF_MEM_APP(); + QF_CRIT_EXIT(); +} +else { // starting QXThread + + // is storage for the queue buffer provided? + if (qSto != (QEvt const **)0) { + QEQueue_init(&me->eQueue, qSto, qLen); + } + + // extended thread constructor puts the thread handler in place of + // the top-most initial tran. 'me->super.temp.act' + QXThread_stackInit_(me, me->super.temp.thr, stkSto, stkSize); + + // the new thread is not blocked on any object + me->super.temp.obj = (QMState *)0; + + QF_CRIT_ENTRY(); + QF_MEM_SYS(); + + // extended-thread becomes ready immediately + QPSet_insert(&QXK_priv_.readySet, (uint_fast8_t)me->prio); + #ifndef Q_UNSAFE + QPSet_update_(&QXK_priv_.readySet, &QXK_priv_.readySet_dis); + #endif + + // see if this thread needs to be scheduled in case QXK is running + if (QXK_priv_.lockCeil <= QF_MAX_ACTIVE) { + (void)QXK_sched_(); // schedule other threads + } + QF_MEM_APP(); + QF_CRIT_EXIT(); +} + + + + + //! @class QXThread +//! @extends QActive + + + //! @private @memberof QXThread + + + + //! @static @private @memberof QXThread +//! dummy static member to force QM to generate 'struct QXThread' + + + + //! @public @memberof QXThread + +//! @public @memberof QXThread + + + + + union QAsmAttr tmp; +tmp.thr = handler; +QActive_ctor(&me->super, tmp.fun); // superclass' ctor + +me->super.super.state.act = Q_ACTION_CAST(0); // mark as extended thread + +// instantiate the time-event member in the QXThread class +QTimeEvt_ctorX(&me->timeEvt, &me->super, + (enum_t)QXK_DELAY_SIG, tickRate); + + + + //! @public @memberof QXThread + +//! @public @memberof QXThread + + + QF_CRIT_STAT +QF_CRIT_ENTRY(); +QF_MEM_SYS(); + +QXThread * const thr = QXTHREAD_CAST_(QXK_priv_.curr); + +// precondition, this function: +// - must NOT be called from an ISR; +// - number of ticks cannot be zero +// - be called from an extended thread; +// - the thread must NOT be already blocked on any object. +Q_REQUIRE_INCRIT(800, (!QXK_ISR_CONTEXT_()) + && (nTicks != 0U) + && (thr != (QXThread *)0) + && (thr->super.super.temp.obj == (QMState *)0)); +// - the thread must NOT be holding a scheduler lock. +Q_REQUIRE_INCRIT(801, + QXK_priv_.lockHolder != (uint_fast8_t)thr->super.prio); + +// remember the blocking object +thr->super.super.temp.obj = QXK_PTR_CAST_(QMState const*, &thr->timeEvt); +QXThread_teArm_(thr, (enum_t)QXK_DELAY_SIG, nTicks); +QXThread_block_(thr); + +QF_MEM_APP(); +QF_CRIT_EXIT(); +QF_CRIT_EXIT_NOP(); // BLOCK here + +// after unblocking... +QF_CRIT_ENTRY(); +QF_MEM_SYS(); + +// the blocking object must be the time event +Q_ASSERT_INCRIT(890, thr->super.super.temp.obj + == QXK_PTR_CAST_(QMState const*, &thr->timeEvt)); +thr->super.super.temp.obj = (QMState *)0; // clear + +QF_MEM_APP(); +QF_CRIT_EXIT(); + +// signal of zero means that the time event was posted without +// being canceled. +return thr->timeEvt.super.sig == 0U; + + + + //! @public @memberof QXThread + +//! @public @memberof QXThread + QF_CRIT_STAT +QF_CRIT_ENTRY(); +QF_MEM_SYS(); + +bool wasArmed; +if (me->super.super.temp.obj == QXK_PTR_CAST_(QMState*, &me->timeEvt)) { + wasArmed = QXThread_teDisarm_(me); + QXThread_unblock_(me); +} +else { + wasArmed = false; +} +QF_MEM_APP(); +QF_CRIT_EXIT(); + +return wasArmed; + + + + //! @static @public @memberof QXThread + +//! @static @public @memberof QXThread + + + QF_CRIT_STAT +QF_CRIT_ENTRY(); +QF_MEM_SYS(); + +QXThread * const thr = QXTHREAD_CAST_(QXK_priv_.curr); + +// precondition, this function: +// - must NOT be called from an ISR; +// - be called from an extended thread; +// - the thread must NOT be already blocked on any object. +Q_REQUIRE_INCRIT(500, (!QXK_ISR_CONTEXT_()) + && (thr != (QXThread *)0) + && (thr->super.super.temp.obj == (QMState *)0)); +// - the thread must NOT be holding a scheduler lock. +Q_REQUIRE_INCRIT(501, + QXK_priv_.lockHolder != (uint_fast8_t)thr->super.prio); + +// is the queue empty? +if (thr->super.eQueue.frontEvt == (QEvt *)0) { + + // remember the blocking object (the thread's queue) + thr->super.super.temp.obj + = QXK_PTR_CAST_(QMState const*, &thr->super.eQueue); + + QXThread_teArm_(thr, (enum_t)QXK_TIMEOUT_SIG, nTicks); + QPSet_remove(&QXK_priv_.readySet, (uint_fast8_t)thr->super.prio); +#ifndef Q_UNSAFE + QPSet_update_(&QXK_priv_.readySet, &QXK_priv_.readySet_dis); +#endif + + (void)QXK_sched_(); // schedule other threads + + QF_MEM_APP(); + QF_CRIT_EXIT(); + QF_CRIT_EXIT_NOP(); // BLOCK here + + // after unblocking... + QF_CRIT_ENTRY(); + QF_MEM_SYS(); + + // the blocking object must be this queue + Q_ASSERT_INCRIT(510, thr->super.super.temp.obj + == QXK_PTR_CAST_(QMState const*, &thr->super.eQueue)); + thr->super.super.temp.obj = (QMState *)0; // clear +} + +// is the queue not empty? +QEvt const *e; +if (thr->super.eQueue.frontEvt != (QEvt *)0) { + e = thr->super.eQueue.frontEvt; // remove from the front + QEQueueCtr const nFree= thr->super.eQueue.nFree + 1U; + thr->super.eQueue.nFree = nFree; // update the # free + + // any events in the ring buffer? + if (nFree <= thr->super.eQueue.end) { + + // remove event from the tail + thr->super.eQueue.frontEvt = + thr->super.eQueue.ring[thr->super.eQueue.tail]; + if (thr->super.eQueue.tail == 0U) { // need to wrap? + thr->super.eQueue.tail = thr->super.eQueue.end; // wrap + } + --thr->super.eQueue.tail; + + QS_BEGIN_PRE_(QS_QF_ACTIVE_GET, thr->super.prio) + QS_TIME_PRE_(); // timestamp + QS_SIG_PRE_(e->sig); // the signal of this event + QS_OBJ_PRE_(&thr->super); // this active object + QS_2U8_PRE_(QEvt_getPoolId_(e), e->refCtr_); // poolId & refCtr + QS_EQC_PRE_(nFree); // # free entries + QS_END_PRE_() + } + else { + thr->super.eQueue.frontEvt = (QEvt *)0; // empty queue + + // all entries in the queue must be free (+1 for fronEvt) + Q_ASSERT_INCRIT(520, nFree == (thr->super.eQueue.end + 1U)); + + QS_BEGIN_PRE_(QS_QF_ACTIVE_GET_LAST, thr->super.prio) + QS_TIME_PRE_(); // timestamp + QS_SIG_PRE_(e->sig); // the signal of this event + QS_OBJ_PRE_(&thr->super); // this active object + QS_2U8_PRE_(QEvt_getPoolId_(e), e->refCtr_); // poolId & refCtr + QS_END_PRE_() + } +} +else { // the queue is still empty -- the timeout must have fired + e = (QEvt *)0; +} +QF_MEM_APP(); +QF_CRIT_EXIT(); + +return e; + + + + const + //! @private @memberof QXThread + +//! @private @memberof QXThread + // NOTE: must be called IN a critical section + +Q_REQUIRE_INCRIT(600, + QXK_priv_.lockHolder != (uint_fast8_t)me->super.prio); + +QPSet_remove(&QXK_priv_.readySet, (uint_fast8_t)me->super.prio); +#ifndef Q_UNSAFE +QPSet_update_(&QXK_priv_.readySet, &QXK_priv_.readySet_dis); +#endif + +(void)QXK_sched_(); // schedule other threads + + + + const + //! @private @memberof QXThread + +//! @private @memberof QXThread + // NOTE: must be called IN a critical section + +QPSet_insert(&QXK_priv_.readySet, (uint_fast8_t)me->super.prio); +#ifndef Q_UNSAFE +QPSet_update_(&QXK_priv_.readySet, &QXK_priv_.readySet_dis); +#endif + +if ((!QXK_ISR_CONTEXT_()) // not inside ISR? + && (QActive_registry_[0] != (QActive *)0)) // kernel started? +{ + (void)QXK_sched_(); // schedule other threads +} + + + + //! @private @memberof QXThread + +//! @private @memberof QXThread + + + // NOTE: must be called IN a critical section + +// the private time event is now disarmed and not in any queue, +// so it is safe to change its signal. The signal of 0 means +// that the time event has expired. +QXTHREAD_CAST_(act)->timeEvt.super.sig = 0U; + +QXThread_unblock_(QXTHREAD_CAST_(act)); + + + + //! @private @memberof QXThread + +//! @private @memberof QXThread + + + + + // NOTE: must be called IN a critical section + +// precondition: +// - the time event must be unused +Q_REQUIRE_INCRIT(700, me->timeEvt.ctr == 0U); + +me->timeEvt.super.sig = (QSignal)sig; + +if (nTicks != QXTHREAD_NO_TIMEOUT) { + me->timeEvt.ctr = (QTimeEvtCtr)nTicks; + me->timeEvt.interval = 0U; + + // is the time event unlinked? + // NOTE: For the duration of a single clock tick of the specified tick + // rate a time event can be disarmed and yet still linked in the list, + // because un-linking is performed exclusively in QTimeEvt_tick_(). + if ((me->timeEvt.super.refCtr_ & QTE_IS_LINKED) == 0U) { + uint_fast8_t const tickRate + = ((uint_fast8_t)me->timeEvt.super.refCtr_ & QTE_TICK_RATE); + Q_ASSERT_INCRIT(710, tickRate < QF_MAX_TICK_RATE); + + // mark as linked + me->timeEvt.super.refCtr_ |= QTE_IS_LINKED; + + // The time event is initially inserted into the separate + // "freshly armed" list based on QTimeEvt_timeEvtHead_[tickRate].act. + // Only later, inside the QTimeEvt_tick_() function, the "freshly + // armed" list is appended to the main list of armed time events + // based on QTimeEvt_timeEvtHead_[tickRate].next. Again, this is + // to keep any changes to the main list exclusively inside + // QTimeEvt_tick_(). + me->timeEvt.next + = QXK_PTR_CAST_(QTimeEvt*, QTimeEvt_timeEvtHead_[tickRate].act); + QTimeEvt_timeEvtHead_[tickRate].act = &me->timeEvt; + } +} + + + + //! @private @memberof QXThread + +//! @private @memberof QXThread + // NOTE: must be called IN a critical section + +bool wasArmed; +// is the time evt running? +if (me->timeEvt.ctr != 0U) { + wasArmed = true; + me->timeEvt.ctr = 0U; // schedule removal from list +} +// the time event was already automatically disarmed +else { + wasArmed = false; +} +return wasArmed; + + + + //! @private @memberof QXThread + +//! @private @memberof QXThread + + + + + + + + + + + + + //! @class QXSemaphore + + + //! @private @memberof QXSemaphore + + + + //! @private @memberof QXSemaphore + + + + //! @private @memberof QXSemaphore + + + + //! @public @memberof QXSemaphore + +//! @public @memberof QXSemaphore + + + + + QF_CRIT_STAT +QF_CRIT_ENTRY(); +QF_MEM_SYS(); + +Q_REQUIRE_INCRIT(100, (count <= max_count) + && (0U < max_count) && (max_count <= 0xFFU)); + +me->count = (uint8_t)count; +me->max_count = (uint8_t)max_count; +QPSet_setEmpty(&me->waitSet); + +QF_MEM_APP(); +QF_CRIT_EXIT(); + + + + //! @public @memberof QXSemaphore + +//! @public @memberof QXSemaphore + + + QF_CRIT_STAT +QF_CRIT_ENTRY(); +QF_MEM_SYS(); + +QXThread * const curr = QXK_PTR_CAST_(QXThread*, QXK_priv_.curr); + +// precondition, this function: +// - must NOT be called from an ISR; +// - the semaphore must be initialized +// - be called from an extended thread; +// - the thread must NOT be already blocked on any object. +Q_REQUIRE_INCRIT(200, (!QXK_ISR_CONTEXT_()) + && (me->max_count > 0U) + && (curr != (QXThread *)0) + && (curr->super.super.temp.obj == (QMState *)0)); +// - the thread must NOT be holding a scheduler lock. +Q_REQUIRE_INCRIT(201, + QXK_priv_.lockHolder != (uint_fast8_t)curr->super.prio); + +bool taken = true; // assume that the semaphore will be signaled +if (me->count > 0U) { + --me->count; // semaphore taken: decrement the count + + QS_BEGIN_PRE_(QS_SEM_TAKE, curr->super.prio) + QS_TIME_PRE_(); // timestamp + QS_OBJ_PRE_(me); // this semaphore + QS_2U8_PRE_(curr->super.prio, me->count); + QS_END_PRE_() +} +else { // semaphore not available -- BLOCK the thread + uint_fast8_t const p = (uint_fast8_t)curr->super.prio; + // remove the curr prio from the ready set (will block) + // and insert to the waiting set on this semaphore + QPSet_remove(&QXK_priv_.readySet, p); +#ifndef Q_UNSAFE + QPSet_update_(&QXK_priv_.readySet, &QXK_priv_.readySet_dis); +#endif + QPSet_insert(&me->waitSet, p); + + // remember the blocking object (this semaphore) + curr->super.super.temp.obj = QXK_PTR_CAST_(QMState*, me); + QXThread_teArm_(curr, (enum_t)QXK_TIMEOUT_SIG, nTicks); + + QS_BEGIN_PRE_(QS_SEM_BLOCK, curr->super.prio) + QS_TIME_PRE_(); // timestamp + QS_OBJ_PRE_(me); // this semaphore + QS_2U8_PRE_(curr->super.prio, me->count); + QS_END_PRE_() + + // schedule the next thread if multitasking started + (void)QXK_sched_(); // schedule other threads + + QF_MEM_APP(); + QF_CRIT_EXIT(); + QF_CRIT_EXIT_NOP(); // BLOCK here !!! + + QF_CRIT_ENTRY(); // AFTER unblocking... + QF_MEM_SYS(); + + // the blocking object must be this semaphore + Q_ASSERT_INCRIT(240, curr->super.super.temp.obj + == QXK_PTR_CAST_(QMState*, me)); + + // did the blocking time-out? (signal of zero means that it did) + if (curr->timeEvt.super.sig == 0U) { + if (QPSet_hasElement(&me->waitSet, p)) { // still waiting? + QPSet_remove(&me->waitSet, p); // remove unblocked thread + taken = false; // the semaphore was NOT taken + } + } + else { // blocking did NOT time out + // the thread must NOT be waiting on this semaphore + Q_ASSERT_INCRIT(250, !QPSet_hasElement(&me->waitSet, p)); + } + curr->super.super.temp.obj = (QMState *)0; // clear blocking obj. +} +QF_MEM_APP(); +QF_CRIT_EXIT(); + +return taken; + + + + //! @public @memberof QXSemaphore + +//! @public @memberof QXSemaphore + QF_CRIT_STAT +QF_CRIT_ENTRY(); +QF_MEM_SYS(); + +// precondition: +// - the semaphore must be initialized +Q_REQUIRE_INCRIT(300, me->max_count > 0U); + +#ifdef Q_SPY +QActive const * const curr = QXK_PTR_CAST_(QActive*, QXK_priv_.curr); +#endif // Q_SPY + +bool taken; +// is the semaphore available? +if (me->count > 0U) { + --me->count; + taken = true; + + QS_BEGIN_PRE_(QS_SEM_TAKE, curr->prio) + QS_TIME_PRE_(); // timestamp + QS_OBJ_PRE_(me); // this semaphore + QS_2U8_PRE_(curr->prio, me->count); + QS_END_PRE_() +} +else { // the semaphore is NOT available (would block) + taken = false; + + QS_BEGIN_PRE_(QS_SEM_BLOCK_ATTEMPT, curr->prio) + QS_TIME_PRE_(); // timestamp + QS_OBJ_PRE_(me); // this semaphore + QS_2U8_PRE_(curr->prio, me->count); + QS_END_PRE_() +} +QF_MEM_APP(); +QF_CRIT_EXIT(); + +return taken; + + + + //! @public @memberof QXSemaphore + +//! @public @memberof QXSemaphore + bool signaled = true; // assume that the semaphore will be signaled + +QF_CRIT_STAT +QF_CRIT_ENTRY(); +QF_MEM_SYS(); + +// precondition: +// - the semaphore must be initialized +Q_REQUIRE_INCRIT(400, me->max_count > 0U); + +// any threads blocked on this semaphore? +if (QPSet_notEmpty(&me->waitSet)) { + // find the highest-prio. thread waiting on this semaphore + uint_fast8_t const p = QPSet_findMax(&me->waitSet); + QXThread * const thr = + QXK_PTR_CAST_(QXThread*, QActive_registry_[p]); + + // assert that the tread: + // - must be registered in QF; + // - must be extended; and + // - must be blocked on this semaphore; + Q_ASSERT_INCRIT(410, (thr != (QXThread *)0) + && (thr->super.osObject != (void *)0) + && (thr->super.super.temp.obj + == QXK_PTR_CAST_(QMState*, me))); + + // disarm the internal time event + (void)QXThread_teDisarm_(thr); + + // make the thread ready to run and remove from the wait-list + QPSet_insert(&QXK_priv_.readySet, p); +#ifndef Q_UNSAFE + QPSet_update_(&QXK_priv_.readySet, &QXK_priv_.readySet_dis); +#endif + QPSet_remove(&me->waitSet, p); + + QS_BEGIN_PRE_(QS_SEM_TAKE, thr->super.prio) + QS_TIME_PRE_(); // timestamp + QS_OBJ_PRE_(me); // this semaphore + QS_2U8_PRE_(thr->super.prio, me->count); + QS_END_PRE_() + + if (!QXK_ISR_CONTEXT_()) { // not inside ISR? + (void)QXK_sched_(); // schedule other threads + } +} +else if (me->count < me->max_count) { + ++me->count; // increment the semaphore count + + QS_BEGIN_PRE_(QS_SEM_SIGNAL, 0U) + QS_TIME_PRE_(); // timestamp + QS_OBJ_PRE_(me); // this semaphore + QS_2U8_PRE_(0U, me->count); + QS_END_PRE_() +} +else { + signaled = false; // semaphore NOT signaled +} +QF_MEM_APP(); +QF_CRIT_EXIT(); + +return signaled; + + + + + //! @class QXMutex + + + //! @private @memberof QXMutex + + + + //! @private @memberof QXMutex + + + + //! @public @memberof QXMutex + +//! @public @memberof QXMutex + + + QF_CRIT_STAT +QF_CRIT_ENTRY(); +QF_MEM_SYS(); + +Q_REQUIRE_INCRIT(100, (prioSpec & 0xFF00U) == 0U); + +me->ao.prio = (uint8_t)(prioSpec & 0xFFU); // QF-prio. +me->ao.pthre = 0U; // preemption-threshold (not used) +QActive * const ao = &me->ao; + +QF_MEM_APP(); +QF_CRIT_EXIT(); + +QActive_register_(ao); // register this mutex as AO + + + + //! @public @memberof QXMutex + +//! @public @memberof QXMutex + + + QF_CRIT_STAT +QF_CRIT_ENTRY(); +QF_MEM_SYS(); + +QXThread * const curr = QXK_PTR_CAST_(QXThread*, QXK_priv_.curr); + +// precondition, this mutex operation must: +// - NOT be called from an ISR; +// - be called from an eXtended thread; +// - the mutex-prio. must be in range; +// - the thread must NOT be already blocked on any object. +Q_REQUIRE_INCRIT(200, (!QXK_ISR_CONTEXT_()) + && (curr != (QXThread *)0) + && (me->ao.prio <= QF_MAX_ACTIVE) + && (curr->super.super.temp.obj == (QMState *)0)); +// also: the thread must NOT be holding a scheduler lock. +Q_REQUIRE_INCRIT(201, + QXK_priv_.lockHolder != (uint_fast8_t)curr->super.prio); + +// is the mutex available? +bool locked = true; // assume that the mutex will be locked +if (me->ao.eQueue.nFree == 0U) { + me->ao.eQueue.nFree = 1U; // mutex lock nesting + + // also: the newly locked mutex must have no holder yet + Q_REQUIRE_INCRIT(203, me->ao.osObject == (void *)0); + + // set the new mutex holder to the curr thread and + // save the thread's prio in the mutex + // NOTE: reuse the otherwise unused eQueue data member. + me->ao.osObject = curr; + me->ao.eQueue.head = (QEQueueCtr)curr->super.prio; + + QS_BEGIN_PRE_(QS_MTX_LOCK, curr->super.prio) + QS_TIME_PRE_(); // timestamp + QS_OBJ_PRE_(me); // this mutex + QS_U8_PRE_((uint8_t)me->ao.eQueue.head); // holder prio + QS_U8_PRE_((uint8_t)me->ao.eQueue.nFree); // nesting + QS_END_PRE_() + + if (me->ao.prio != 0U) { // prio.-ceiling protocol used? + // the holder prio. must be lower than that of the mutex + // and the prio. slot must be occupied by this mutex + Q_ASSERT_INCRIT(210, (curr->super.prio < me->ao.prio) + && (QActive_registry_[me->ao.prio] == &me->ao)); + + // remove the thread's original prio from the ready set + // and insert the mutex's prio into the ready set + QPSet_remove(&QXK_priv_.readySet, + (uint_fast8_t)me->ao.eQueue.head); + QPSet_insert(&QXK_priv_.readySet, + (uint_fast8_t)me->ao.prio); +#ifndef Q_UNSAFE + QPSet_update_(&QXK_priv_.readySet, &QXK_priv_.readySet_dis); +#endif + // put the thread into the AO registry in place of the mutex + QActive_registry_[me->ao.prio] = &curr->super; + + // set thread's prio to that of the mutex + curr->super.prio = me->ao.prio; + } +} +// is the mutex locked by this thread already (nested locking)? +else if (me->ao.osObject == &curr->super) { + + // the nesting level beyond the arbitrary but high limit + // most likely means cyclic or recursive locking of a mutex. + Q_ASSERT_INCRIT(220, me->ao.eQueue.nFree < 0xFFU); + + ++me->ao.eQueue.nFree; // lock one more level + + QS_BEGIN_PRE_(QS_MTX_LOCK, curr->super.prio) + QS_TIME_PRE_(); // timestamp + QS_OBJ_PRE_(me); // this mutex + QS_U8_PRE_((uint8_t)me->ao.eQueue.head); // holder prio + QS_U8_PRE_((uint8_t)me->ao.eQueue.nFree); // nesting + QS_END_PRE_() +} +else { // the mutex is already locked by a different thread + // the mutex holder must be valid + Q_ASSERT_INCRIT(230, me->ao.osObject != (void *)0); + + if (me->ao.prio != 0U) { // prio.-ceiling protocol used? + // the prio slot must be occupied by the thr. holding the mutex + Q_ASSERT_INCRIT(240, QActive_registry_[me->ao.prio] + == QACTIVE_CAST_(me->ao.osObject)); + } + + // remove the curr thread's prio from the ready set (will block) + // and insert it to the waiting set on this mutex + uint_fast8_t const p = (uint_fast8_t)curr->super.prio; + QPSet_remove(&QXK_priv_.readySet, p); +#ifndef Q_UNSAFE + QPSet_update_(&QXK_priv_.readySet, &QXK_priv_.readySet_dis); +#endif + QPSet_insert(&me->waitSet, p); + + // set the blocking object (this mutex) + curr->super.super.temp.obj = QXK_PTR_CAST_(QMState*, me); + QXThread_teArm_(curr, (enum_t)QXK_TIMEOUT_SIG, nTicks); + + QS_BEGIN_PRE_(QS_MTX_BLOCK, curr->super.prio) + QS_TIME_PRE_(); // timestamp + QS_OBJ_PRE_(me); // this mutex + QS_2U8_PRE_((uint8_t)me->ao.eQueue.head, // holder prio + curr->super.prio); // blocked thread prio + QS_END_PRE_() + + // schedule the next thread if multitasking started + (void)QXK_sched_(); // schedule other threads + + QF_MEM_APP(); + QF_CRIT_EXIT(); + QF_CRIT_EXIT_NOP(); // BLOCK here !!! + + // AFTER unblocking... + QF_CRIT_ENTRY(); + QF_MEM_SYS(); + // the blocking object must be this mutex + Q_ASSERT_INCRIT(250, curr->super.super.temp.obj + == QXK_PTR_CAST_(QMState*, me)); + + // did the blocking time-out? (signal of zero means that it did) + if (curr->timeEvt.super.sig == 0U) { + if (QPSet_hasElement(&me->waitSet, p)) { // still waiting? + QPSet_remove(&me->waitSet, p); // remove unblocked thread + locked = false; // the mutex was NOT locked + } + } + else { // blocking did NOT time out + // the thread must NOT be waiting on this mutex + Q_ASSERT_INCRIT(260, !QPSet_hasElement(&me->waitSet, p)); + } + curr->super.super.temp.obj = (QMState *)0; // clear blocking obj. +} +QF_MEM_APP(); +QF_CRIT_EXIT(); + +return locked; + + + + //! @public @memberof QXMutex + +//! @public @memberof QXMutex + QF_CRIT_STAT +QF_CRIT_ENTRY(); +QF_MEM_SYS(); + +QActive *curr = QXK_priv_.curr; +if (curr == (QActive *)0) { // called from a basic thread? + curr = QActive_registry_[QXK_priv_.actPrio]; +} + +// precondition, this mutex must: +// - NOT be called from an ISR; +// - the calling thread must be valid; +// - the mutex-prio. must be in range +Q_REQUIRE_INCRIT(300, (!QXK_ISR_CONTEXT_()) + && (curr != (QActive *)0) + && (me->ao.prio <= QF_MAX_ACTIVE)); +// also: the thread must NOT be holding a scheduler lock. +Q_REQUIRE_INCRIT(301, + QXK_priv_.lockHolder != (uint_fast8_t)curr->prio); + +// is the mutex available? +if (me->ao.eQueue.nFree == 0U) { + me->ao.eQueue.nFree = 1U; // mutex lock nesting + + // also the newly locked mutex must have no holder yet + Q_REQUIRE_INCRIT(303, me->ao.osObject == (void *)0); + + // set the new mutex holder to the curr thread and + // save the thread's prio in the mutex + // NOTE: reuse the otherwise unused eQueue data member. + me->ao.osObject = curr; + me->ao.eQueue.head = (QEQueueCtr)curr->prio; + + QS_BEGIN_PRE_(QS_MTX_LOCK, curr->prio) + QS_TIME_PRE_(); // timestamp + QS_OBJ_PRE_(me); // this mutex + QS_U8_PRE_((uint8_t)me->ao.eQueue.head); // holder prio + QS_U8_PRE_((uint8_t)me->ao.eQueue.nFree); // nesting + QS_END_PRE_() + + if (me->ao.prio != 0U) { // prio.-ceiling protocol used? + // the holder prio. must be lower than that of the mutex + // and the prio. slot must be occupied by this mutex + Q_ASSERT_INCRIT(310, (curr->prio < me->ao.prio) + && (QActive_registry_[me->ao.prio] == &me->ao)); + + // remove the thread's original prio from the ready set + // and insert the mutex's prio into the ready set + QPSet_remove(&QXK_priv_.readySet, + (uint_fast8_t)me->ao.eQueue.head); + QPSet_insert(&QXK_priv_.readySet, + (uint_fast8_t)me->ao.prio); +#ifndef Q_UNSAFE + QPSet_update_(&QXK_priv_.readySet, &QXK_priv_.readySet_dis); +#endif + // put the thread into the AO registry in place of the mutex + QActive_registry_[me->ao.prio] = curr; + + // set thread's prio to that of the mutex + curr->prio = me->ao.prio; + } +} +// is the mutex locked by this thread already (nested locking)? +else if (me->ao.osObject == curr) { + // the nesting level must not exceed the specified limit + Q_ASSERT_INCRIT(320, me->ao.eQueue.nFree < 0xFFU); + + ++me->ao.eQueue.nFree; // lock one more level + + QS_BEGIN_PRE_(QS_MTX_LOCK, curr->prio) + QS_TIME_PRE_(); // timestamp + QS_OBJ_PRE_(me); // this mutex + QS_U8_PRE_((uint8_t)me->ao.eQueue.head); // holder prio + QS_U8_PRE_((uint8_t)me->ao.eQueue.nFree); // nesting + QS_END_PRE_() +} +else { // the mutex is already locked by a different thread + if (me->ao.prio != 0U) { // prio.-ceiling protocol used? + // the prio slot must be occupied by the thr. holding the mutex + Q_ASSERT_INCRIT(330, QActive_registry_[me->ao.prio] + == QACTIVE_CAST_(me->ao.osObject)); + } + + QS_BEGIN_PRE_(QS_MTX_BLOCK_ATTEMPT, curr->prio) + QS_TIME_PRE_(); // timestamp + QS_OBJ_PRE_(me); // this mutex + QS_2U8_PRE_((uint8_t)me->ao.eQueue.head, // holder prio + curr->prio); // trying thread prio + QS_END_PRE_() + + curr = (QActive *)0; // means that mutex is NOT available +} +QF_MEM_APP(); +QF_CRIT_EXIT(); + +return curr != (QActive *)0; + + + + //! @public @memberof QXMutex + +//! @public @memberof QXMutex + QF_CRIT_STAT +QF_CRIT_ENTRY(); +QF_MEM_SYS(); + +QActive *curr = QXK_priv_.curr; +if (curr == (QActive *)0) { // called from a basic thread? + curr = QActive_registry_[QXK_priv_.actPrio]; +} + +Q_REQUIRE_INCRIT(400, (!QXK_ISR_CONTEXT_()) + && (curr != (QActive *)0)); +Q_REQUIRE_INCRIT(401, me->ao.eQueue.nFree > 0U); +Q_REQUIRE_INCRIT(403, me->ao.osObject == curr); + +// is this the last nesting level? +if (me->ao.eQueue.nFree == 1U) { + + if (me->ao.prio != 0U) { // prio.-ceiling protocol used? + // prio. must be in range + Q_ASSERT_INCRIT(410, me->ao.prio < QF_MAX_ACTIVE); + + // restore the holding thread's prio from the mutex + curr->prio = (uint8_t)me->ao.eQueue.head; + + // put the mutex back into the AO registry + QActive_registry_[me->ao.prio] = &me->ao; + + // remove the mutex' prio from the ready set + // and insert the original thread's prio. + QPSet_remove(&QXK_priv_.readySet, + (uint_fast8_t)me->ao.prio); + QPSet_insert(&QXK_priv_.readySet, + (uint_fast8_t)me->ao.eQueue.head); +#ifndef Q_UNSAFE + QPSet_update_(&QXK_priv_.readySet, &QXK_priv_.readySet_dis); +#endif + } + + QS_BEGIN_PRE_(QS_MTX_UNLOCK, curr->prio) + QS_TIME_PRE_(); // timestamp + QS_OBJ_PRE_(me); // this mutex + QS_2U8_PRE_((uint8_t)me->ao.eQueue.head, // holder prio + 0U); // nesting + QS_END_PRE_() + + // are any other threads waiting on this mutex? + if (QPSet_notEmpty(&me->waitSet)) { + // find the highest-prio. thread waiting on this mutex + uint_fast8_t const p = QPSet_findMax(&me->waitSet); + + // remove this thread from waiting on the mutex + // and insert it into the ready set. + QPSet_remove(&me->waitSet, p); + QPSet_insert(&QXK_priv_.readySet, p); +#ifndef Q_UNSAFE + QPSet_update_(&QXK_priv_.readySet, &QXK_priv_.readySet_dis); +#endif + + QXThread * const thr = + QXK_PTR_CAST_(QXThread*, QActive_registry_[p]); + + // the waiting thread must: + // - be registered in QF + // - have the prio. corresponding to the registration + // - be an extended thread + // - be blocked on this mutex + Q_ASSERT_INCRIT(420, (thr != (QXThread *)0) + && (thr->super.prio == (uint8_t)p) + && (thr->super.super.state.act == Q_ACTION_CAST(0)) + && (thr->super.super.temp.obj + == QXK_PTR_CAST_(QMState*, me))); + + // disarm the internal time event + (void)QXThread_teDisarm_(thr); + + // set the new mutex holder to the curr thread and + // save the thread's prio in the mutex + // NOTE: reuse the otherwise unused eQueue data member. + me->ao.osObject = thr; + me->ao.eQueue.head = (QEQueueCtr)thr->super.prio; + + QS_BEGIN_PRE_(QS_MTX_LOCK, thr->super.prio) + QS_TIME_PRE_(); // timestamp + QS_OBJ_PRE_(me); // this mutex + QS_U8_PRE_((uint8_t)me->ao.eQueue.head); // holder prio + QS_U8_PRE_((uint8_t)me->ao.eQueue.nFree); // nesting + QS_END_PRE_() + + if (me->ao.prio != 0U) { // prio.-ceiling protocol used? + // the holder prio. must be lower than that of the mutex + Q_ASSERT_INCRIT(430, (me->ao.prio < QF_MAX_ACTIVE) + && (thr->super.prio < me->ao.prio)); + + // put the thread into AO registry in place of the mutex + QActive_registry_[me->ao.prio] = &thr->super; + } + } + else { // no threads are waiting for this mutex + me->ao.eQueue.nFree = 0U; // free up the nesting count + + // the mutex no longer held by any thread + me->ao.osObject = (void *)0; + me->ao.eQueue.head = 0U; + me->ao.eQueue.tail = 0U; + + if (me->ao.prio != 0U) { // prio.-ceiling protocol used? + // put the mutex back at the original mutex slot + QActive_registry_[me->ao.prio] = + QXK_PTR_CAST_(QActive*, me); + } + } + + // schedule the next thread if multitasking started + if (QXK_sched_() != 0U) { // activation needed? + QXK_activate_(); // synchronously activate basic-thred(s) + } +} +else { // releasing one level of nested mutex lock + --me->ao.eQueue.nFree; // unlock one level + + QS_BEGIN_PRE_(QS_MTX_UNLOCK_ATTEMPT, curr->prio) + QS_TIME_PRE_(); // timestamp + QS_OBJ_PRE_(me); // this mutex + QS_U8_PRE_((uint8_t)me->ao.eQueue.head); // holder prio + QS_U8_PRE_((uint8_t)me->ao.eQueue.nFree); // nesting + QS_END_PRE_() +} +QF_MEM_APP(); +QF_CRIT_EXIT(); + + + + + + + + + + + + + + + + + + + + + + QACTIVE_START((me_), (prioSpec_), (qSto_), (qLen_), \ + (stkSto_), (stkSize_), (par_)) + + + + + + + + + + + + \ + QACTIVE_POST_X(&(me_)->super, (e_), (margin_), (sender_)) + + + + + + + QSchedStatus lockStat_; + + + + + + do { \ + if (QXK_ISR_CONTEXT_()) { \ + lockStat_ = 0xFFU; \ + } else { \ + lockStat_ = QXK_schedLock((ceil_)); \ + } \ +} while (false) + + + + do { \ + if (lockStat_ != 0xFFU) { \ + QXK_schedUnlock(lockStat_); \ + } \ +} while (false) + + + + + + \ + Q_ASSERT_INCRIT(310, (me_)->eQueue.frontEvt != (QEvt *)0) + + + + + + do { \ + QPSet_insert(&QXK_priv_.readySet, (uint_fast8_t)(me_)->prio); \ + QPSet_update_(&QXK_priv_.readySet, &QXK_priv_.readySet_dis); \ + if (!QXK_ISR_CONTEXT_()) { \ + if (QXK_sched_() != 0U) { \ + QXK_activate_(); \ + } \ + } \ +} while (false) + + + + + + do { \ + QPSet_insert(&QXK_priv_.readySet, (uint_fast8_t)(me_)->prio); \ + if (!QXK_ISR_CONTEXT_()) { \ + if (QXK_sched_() != 0U) { \ + QXK_activate_(); \ + } \ + } \ +} while (false) + + + + + + do { \ + if (me->super.temp.obj == QXK_PTR_CAST_(QMState*, &me->eQueue)) { \ + (void)QXThread_teDisarm_(QXTHREAD_CAST_(me)); \ + QPSet_insert(&QXK_priv_.readySet, (uint_fast8_t)me->prio); \ + QPSet_update_(&QXK_priv_.readySet, &QXK_priv_.readySet_dis); \ + if (!QXK_ISR_CONTEXT_()) { \ + (void)QXK_sched_(); \ + } \ + } \ +} while (false) + + + + + + do { \ + if (me->super.temp.obj == QXK_PTR_CAST_(QMState*, &me->eQueue)) { \ + (void)QXThread_teDisarm_(QXTHREAD_CAST_(me)); \ + QPSet_insert(&QXK_priv_.readySet, (uint_fast8_t)me->prio); \ + if (!QXK_ISR_CONTEXT_()) { \ + (void)QXK_sched_(); \ + } \ + } \ +} while (false) + + + + <type_> + + + + + ((type_)(ptr_)) + + + + + + ((QXThread *)(ptr_)) + + + + + + + + + //! @class QS + { + //! @cond INTERNAL + uint8_t dummy; + //! @endcond +} QS; + + + + //! @static @public @memberof QS +//! pre-defined QS record IDs + { + // [0] QS session (not maskable) + QS_EMPTY, //!< QS record for cleanly starting a session + + // [1] SM records + QS_QEP_STATE_ENTRY, //!< a state was entered + QS_QEP_STATE_EXIT, //!< a state was exited + QS_QEP_STATE_INIT, //!< an initial transition was taken in a state + QS_QEP_INIT_TRAN, //!< the top-most initial transition was taken + QS_QEP_INTERN_TRAN, //!< an internal transition was taken + QS_QEP_TRAN, //!< a regular transition was taken + QS_QEP_IGNORED, //!< an event was ignored (silently discarded) + QS_QEP_DISPATCH, //!< an event was dispatched (begin of RTC step) + QS_QEP_UNHANDLED, //!< an event was un-handled due to a guard + + // [10] Active Object (AO) records + QS_QF_ACTIVE_DEFER, //!< AO deferred an event + QS_QF_ACTIVE_RECALL, //!< AO recalled an event + QS_QF_ACTIVE_SUBSCRIBE, //!< an AO subscribed to an event + QS_QF_ACTIVE_UNSUBSCRIBE, //!< an AO unsubscribed to an event + QS_QF_ACTIVE_POST, //!< an event was posted (FIFO) directly to AO + QS_QF_ACTIVE_POST_LIFO, //!< an event was posted (LIFO) directly to AO + QS_QF_ACTIVE_GET, //!< AO got an event and its queue is not empty + QS_QF_ACTIVE_GET_LAST,//!< AO got an event and its queue is empty + QS_QF_ACTIVE_RECALL_ATTEMPT, //!< AO attempted to recall an event + + // [19] Event Queue (EQ) records + QS_QF_EQUEUE_POST, //!< an event was posted (FIFO) to a raw queue + QS_QF_EQUEUE_POST_LIFO, //!< an event was posted (LIFO) to a raw queue + QS_QF_EQUEUE_GET, //!< get an event and queue still not empty + QS_QF_EQUEUE_GET_LAST,//!< get the last event from the queue + + // [23] Framework (QF) records + QS_QF_NEW_ATTEMPT, //!< an attempt to allocate an event failed + + // [24] Memory Pool (MP) records + QS_QF_MPOOL_GET, //!< a memory block was removed from memory pool + QS_QF_MPOOL_PUT, //!< a memory block was returned to memory pool + + // [26] Additional Framework (QF) records + QS_QF_PUBLISH, //!< an event was published to active objects + QS_QF_NEW_REF, //!< new event reference was created + QS_QF_NEW, //!< new event was created + QS_QF_GC_ATTEMPT, //!< garbage collection attempt + QS_QF_GC, //!< garbage collection + QS_QF_TICK, //!< QTimeEvt tick was called + + // [32] Time Event (TE) records + QS_QF_TIMEEVT_ARM, //!< a time event was armed + QS_QF_TIMEEVT_AUTO_DISARM, //!< a time event expired and was disarmed + QS_QF_TIMEEVT_DISARM_ATTEMPT,//!< attempt to disarm a disarmed QTimeEvt + QS_QF_TIMEEVT_DISARM, //!< true disarming of an armed time event + QS_QF_TIMEEVT_REARM, //!< rearming of a time event + QS_QF_TIMEEVT_POST, //!< a time event posted itself directly to an AO + + // [38] Additional Framework (QF) records + QS_QF_DELETE_REF, //!< an event reference is about to be deleted + QS_QF_CRIT_ENTRY, //!< critical section was entered + QS_QF_CRIT_EXIT, //!< critical section was exited + QS_QF_ISR_ENTRY, //!< an ISR was entered + QS_QF_ISR_EXIT, //!< an ISR was exited + QS_QF_INT_DISABLE, //!< interrupts were disabled + QS_QF_INT_ENABLE, //!< interrupts were enabled + + // [45] Additional Active Object (AO) records + QS_QF_ACTIVE_POST_ATTEMPT,//!< attempt to post an evt to AO failed + + // [46] Additional Event Queue (EQ) records + QS_QF_EQUEUE_POST_ATTEMPT,//!< attempt to post evt to QEQueue failed + + // [47] Additional Memory Pool (MP) records + QS_QF_MPOOL_GET_ATTEMPT, //!< attempt to get a memory block failed + + // [48] Scheduler (SC) records + QS_SCHED_PREEMPT, //!< scheduler asynchronously preempted a task + QS_SCHED_RESTORE, //!< scheduler restored preempted task + QS_SCHED_LOCK, //!< scheduler was locked + QS_SCHED_UNLOCK, //!< scheduler was unlocked + QS_SCHED_NEXT, //!< scheduler started next task + QS_SCHED_IDLE, //!< scheduler restored the idle task + + // [54] Miscellaneous QS records (not maskable) + QS_ENUM_DICT, //!< enumeration dictionary entry + + // [55] Additional QEP records + QS_QEP_TRAN_HIST, //!< a tran to history was taken + QS_QEP_TRAN_EP, //!< a tran to entry point into a submachine + QS_QEP_TRAN_XP, //!< a tran to exit point out of a submachine + + // [58] Miscellaneous QS records (not maskable) + QS_TEST_PAUSED, //!< test has been paused + QS_TEST_PROBE_GET, //!< reports that Test-Probe has been used + QS_SIG_DICT, //!< signal dictionary entry + QS_OBJ_DICT, //!< object dictionary entry + QS_FUN_DICT, //!< function dictionary entry + QS_USR_DICT, //!< user QS record dictionary entry + QS_TARGET_INFO, //!< reports the Target information + QS_TARGET_DONE, //!< reports completion of a user callback + QS_RX_STATUS, //!< reports QS data receive status + QS_QUERY_DATA, //!< reports the data from "current object" query + QS_PEEK_DATA, //!< reports the data from the PEEK query + QS_ASSERT_FAIL, //!< assertion failed in the code + QS_QF_RUN, //!< QF_run() was entered + + // [71] Semaphore (SEM) records + QS_SEM_TAKE, //!< a semaphore was taken by a thread + QS_SEM_BLOCK, //!< a semaphore blocked a thread + QS_SEM_SIGNAL, //!< a semaphore was signaled + QS_SEM_BLOCK_ATTEMPT, //!< a semaphore blocked was attempted + + // [75] Mutex (MTX) records + QS_MTX_LOCK, //!< a mutex was locked + QS_MTX_BLOCK, //!< a mutex blocked a thread + QS_MTX_UNLOCK, //!< a mutex was unlocked + QS_MTX_LOCK_ATTEMPT, //!< a mutex lock was attempted + QS_MTX_BLOCK_ATTEMPT, //!< a mutex blocking was attempted + QS_MTX_UNLOCK_ATTEMPT,//!< a mutex unlock was attempted + + // [81] + QS_PRE_MAX //!< the # predefined signals +}; + + + + //! @static @public @memberof QS +//! QS-TX record groups for QS_GLB_FILTER() + { + QS_ALL_RECORDS = 0xF0,//!< all maskable QS records + QS_SM_RECORDS, //!< State Machine QS records + QS_AO_RECORDS, //!< Active Object QS records + QS_EQ_RECORDS, //!< Event Queues QS records + QS_MP_RECORDS, //!< Memory Pools QS records + QS_TE_RECORDS, //!< Time Events QS records + QS_QF_RECORDS, //!< QF QS records + QS_SC_RECORDS, //!< Scheduler QS records + QS_SEM_RECORDS, //!< Semaphore QS records + QS_MTX_RECORDS, //!< Mutex QS records + QS_U0_RECORDS, //!< User Group 100-104 records + QS_U1_RECORDS, //!< User Group 105-109 records + QS_U2_RECORDS, //!< User Group 110-114 records + QS_U3_RECORDS, //!< User Group 115-119 records + QS_U4_RECORDS, //!< User Group 120-124 records + QS_UA_RECORDS //!< All User records +}; + + + + //! @static @public @memberof QS +//! QS user record group offsets for QS_GLB_FILTER() + { + QS_USER = 100, //!< the first record available to QS users + QS_USER0 = QS_USER, //!< offset for User Group 0 + QS_USER1 = (enum_t)QS_USER0 + 5, //!< offset for User Group 1 + QS_USER2 = (enum_t)QS_USER1 + 5, //!< offset for User Group 2 + QS_USER3 = (enum_t)QS_USER2 + 5, //!< offset for User Group 3 + QS_USER4 = (enum_t)QS_USER3 + 5 //!< offset for User Group 4 +}; + + + + //! @static @public @memberof QS +//! QS ID offsets for QS_LOC_FILTER() + { + QS_AO_ID = 0, //!< offset for AO priorities + QS_EP_ID = 64, //!< offset for event-pool IDs + QS_EQ_ID = 80, //!< offset for event-queue IDs + QS_AP_ID = 96 //!< offset for Application-specific IDs +}; + + + + //! @static @public @memberof QS +//! QS ID groups for QS_LOC_FILTER() + { + QS_ALL_IDS = 0xF0, //!< all QS IDs + QS_AO_IDS = 0x80 + (enum_t)QS_AO_ID, //!< AO IDs (priorities) + QS_EP_IDS = 0x80 + (enum_t)QS_EP_ID, //!< event-pool IDs + QS_EQ_IDS = 0x80 + (enum_t)QS_EQ_ID, //!< event-queue IDs + QS_AP_IDS = 0x80 + (enum_t)QS_AP_ID //!< Application-specific IDs +}; + + + + //! @struct QSpyId + + + + //! @static @private @memberof QS + )(void); + + + + + + + + + + + + + + + + + + + + + //! @struct QS_Filter + + + + + + + + //! @static @private @memberof QS + + + + + + + //! Enumerates data elements for app-specific trace records + { + QS_I8_ENUM_T, //!< signed 8-bit integer or enum format + QS_U8_T, //!< unsigned 8-bit integer format + QS_I16_T, //!< signed 16-bit integer format + QS_U16_T, //!< unsigned 16-bit integer format + QS_I32_T, //!< signed 32-bit integer format + QS_U32_T, //!< unsigned 32-bit integer format + QS_F32_T, //!< 32-bit floating point format + QS_F64_T, //!< 64-bit floating point format + QS_STR_T, //!< zero-terminated ASCII string format + QS_MEM_T, //!< up to 255-bytes memory block format + QS_SIG_T, //!< event signal format + QS_OBJ_T, //!< object pointer format + QS_FUN_T, //!< function pointer format + QS_I64_T, //!< signed 64-bit integer format + QS_U64_T //!< unsigned 64-bit integer format +}; + + + + //! @static @public @memberof QS + +//! @static @public @memberof QS + + + + + QS_priv_.buf = &sto[0]; +QS_priv_.end = (QSCtr)stoSize; +QS_priv_.head = 0U; +QS_priv_.tail = 0U; +QS_priv_.used = 0U; +QS_priv_.seq = 0U; +QS_priv_.chksum = 0U; +QS_priv_.critNest = 0U; + +QS_glbFilter_(-(int_fast16_t)QS_ALL_RECORDS); // all global filters OFF +QS_locFilter_((int_fast16_t)QS_ALL_IDS); // all local filters ON +QS_priv_.locFilter_AP = (void *)0; // deprecated "AP-filter" + +// produce an empty record to "flush" the QS trace buffer +QS_beginRec_((uint_fast8_t)QS_EMPTY); +QS_endRec_(); + +// produce the reset record to inform QSPY of a new session +QS_target_info_pre_(0xFFU); + +// hold off flushing after successfull initialization (see QS_INIT()) + + + + //! @static @public @memberof QS + +//! @static @public @memberof QS + uint16_t ret; +if (QS_priv_.used == 0U) { + ret = QS_EOD; // set End-Of-Data +} +else { + uint8_t const * const buf = QS_priv_.buf; // put in a temporary + QSCtr tail = QS_priv_.tail; // put in a temporary (register) + ret = (uint16_t)buf[tail]; // set the byte to return + ++tail; // advance the tail + if (tail == QS_priv_.end) { // tail wrap around? + tail = 0U; + } + QS_priv_.tail = tail; // update the tail + --QS_priv_.used; // one less byte used +} +return ret; // return the byte or EOD + + + + //! @static @public @memberof QS + +//! @static @public @memberof QS + + + QSCtr const used = QS_priv_.used; // put in a temporary (register) +uint8_t const *buf; + +// any bytes used in the ring buffer? +if (used != 0U) { + QSCtr tail = QS_priv_.tail; // put in a temporary (register) + QSCtr const end = QS_priv_.end; // put in a temporary (register) + QSCtr n = (QSCtr)(end - tail); + if (n > used) { + n = used; + } + if (n > (QSCtr)(*pNbytes)) { + n = (QSCtr)(*pNbytes); + } + *pNbytes = (uint16_t)n; // n-bytes available + buf = &QS_priv_.buf[tail]; // the bytes are at the tail + + QS_priv_.used = (QSCtr)(used - n); + tail += n; + if (tail == end) { + tail = 0U; + } + QS_priv_.tail = tail; +} +else { // no bytes available + *pNbytes = 0U; // no bytes available right now + buf = (uint8_t *)0; // no bytes available right now +} +return buf; + + + + //! @static @public @memberof QS + +//! @static @public @memberof QS + + + + //! @static @public @memberof QS + +//! @static @public @memberof QS + + + + + + //! @static @public @memberof QS + +//! @static @public @memberof QS + + + + //! @static @public @memberof QS + +//! @static @public @memberof QS + + + + //! @static @public @memberof QS + +//! @static @public @memberof QS + + + + + + + //! @static @public @memberof QS +//! Kinds of objects used in QS-RX + { + SM_OBJ, //!< state machine object + AO_OBJ, //!< active object + MP_OBJ, //!< event pool object + EQ_OBJ, //!< raw queue object + TE_OBJ, //!< time event object + AP_OBJ, //!< generic Application-specific object + MAX_OBJ +}; + + + + //! @static @public @memberof QS +//! Object combinations for QS-RX + { + SM_AO_OBJ = (enum_t)MAX_OBJ //!< combination of SM and AO +}; + + + + //! @static @public @memberof QS + +//! @static @public @memberof QS + + + + + QS_rxPriv_.buf = &sto[0]; +QS_rxPriv_.end = (QSCtr)stoSize; +QS_rxPriv_.head = 0U; +QS_rxPriv_.tail = 0U; + +QS_rxPriv_.currObj[SM_OBJ] = (void *)0; +QS_rxPriv_.currObj[AO_OBJ] = (void *)0; +QS_rxPriv_.currObj[MP_OBJ] = (void *)0; +QS_rxPriv_.currObj[EQ_OBJ] = (void *)0; +QS_rxPriv_.currObj[TE_OBJ] = (void *)0; +QS_rxPriv_.currObj[AP_OBJ] = (void *)0; + +QS_RX_TRAN_(WAIT4_SEQ); +l_rx.esc = 0U; +l_rx.seq = 0U; +l_rx.chksum = 0U; + +QS_beginRec_((uint_fast8_t)QS_OBJ_DICT); + QS_OBJ_PRE_(&QS_rxPriv_); + QS_STR_PRE_("QS_RX"); +QS_endRec_(); +// no QS_REC_DONE(), because QS is not running yet + +#ifdef Q_UTEST +QS_tstPriv_.tpNum = 0U; +QS_tstPriv_.testTime = 0U; +#endif // Q_UTEST + + + + //! @static @public @memberof QS + +//! @static @public @memberof QS + + + // NOTE: does not need critical section +// But requires system-level memory access (QF_MEM_SYS()). + +QSCtr head = QS_rxPriv_.head + 1U; +if (head == QS_rxPriv_.end) { + head = 0U; +} +if (head != QS_rxPriv_.tail) { // buffer NOT full? + QS_rxPriv_.buf[QS_rxPriv_.head] = b; + QS_rxPriv_.head = head; // update the head to a *valid* index + return true; // byte placed in the buffer +} +else { + return false; // byte NOT placed in the buffer +} + + + + //! @static @public @memberof QS + +//! @static @public @memberof QS + // NOTE: Must be called IN critical section. +// Also requires system-level memory access (QF_MEM_SYS()). + +QSCtr tail = QS_rxPriv_.tail; +while (QS_rxPriv_.head != tail) { // QS-RX buffer NOT empty? + uint8_t b = QS_rxPriv_.buf[tail]; + + ++tail; + if (tail == QS_rxPriv_.end) { + tail = 0U; + } + QS_rxPriv_.tail = tail; // update the tail to a *valid* index + + if (l_rx.esc != 0U) { // escaped byte arrived? + l_rx.esc = 0U; + b ^= QS_ESC_XOR; + + l_rx.chksum += b; + QS_rxParseData_(b); + } + else if (b == QS_ESC) { + l_rx.esc = 1U; + } + else if (b == QS_FRAME) { + // get ready for the next frame + b = l_rx.state; // save the current state in b + l_rx.esc = 0U; + QS_RX_TRAN_(WAIT4_SEQ); + + if (l_rx.chksum == QS_GOOD_CHKSUM) { + l_rx.chksum = 0U; + QS_rxHandleGoodFrame_(b); + } + else { // bad checksum + l_rx.chksum = 0U; + QS_rxReportError_(0x41); + QS_rxHandleBadFrame_(b); + } + } + else { + l_rx.chksum += b; + QS_rxParseData_(b); + } +} + + + + //! @static @public @memberof QS + +//! @static @public @memberof QS + // NOTE: Must be called IN critical section. +// Also requires system-level memory access (QF_MEM_SYS()). + +QSCtr const head = QS_rxPriv_.head; +uint16_t nFree; +if (head == QS_rxPriv_.tail) { // buffer empty? + nFree = (uint16_t)(QS_rxPriv_.end - 1U); +} +else if (head < QS_rxPriv_.tail) { + nFree = (uint16_t)(QS_rxPriv_.tail - (head + 1U)); +} +else { + nFree = (uint16_t)((head + 1U) - QS_rxPriv_.tail); + nFree = (uint16_t)(QS_rxPriv_.end - nFree); +} +return nFree; + + + + //! @static @public @memberof QS + +//! @static @public @memberof QS + + + + //! @static @public @memberof QS + +//! @static @public @memberof QS + + + + //! @static @public @memberof QS + +//! @static @public @memberof QS + + + + + + + + + + + + + + + // @struct TProbe + { + QSFun addr; + uint32_t data; + uint8_t idx; +}; + + + + //! @static @public @memberof QS + +//! @static @public @memberof QS + + + + //! @static @public @memberof QS + +//! @static @public @memberof QS + + + + //! @static @public @memberof QS + +//! @static @public @memberof QS + + + + + + //! @static @public @memberof QS + +//! @static @public @memberof QS + + + + + + + + + + + + //! @static @public @memberof QS + +//! @static @public @memberof QS + + + + + + + + + //! QF_init() stub for QUTest + // Clear the internal QF variables, so that the framework can start +// correctly even if the startup code fails to clear the uninitialized +// data (as is required by the C Standard). +QF_bzero_(&QF_priv_, sizeof(QF_priv_)); +QF_bzero_(&QS_tstPriv_, sizeof(QS_tstPriv_)); +QF_bzero_(&QActive_registry_[0], sizeof(QActive_registry_)); + +#ifndef Q_UNSAFE +QPSet_update_(&QS_tstPriv_.readySet, &QS_tstPriv_.readySet_dis); +#endif + + + + //! QF_stop() stub for QUTest + QS_onReset(); + + + + //! QF_run() stub for QUTest + QS_CRIT_STAT +QS_CRIT_ENTRY(); +QS_MEM_SYS(); + +// function dictionaries for the standard API +QS_FUN_DICTIONARY(&QActive_post_); +QS_FUN_DICTIONARY(&QActive_postLIFO_); +QS_FUN_DICTIONARY(&QS_processTestEvts_); + +// produce the QS_QF_RUN trace record +QS_BEGIN_PRE_(QS_QF_RUN, 0U) +QS_END_PRE_() + +QS_MEM_APP(); +QS_CRIT_EXIT(); + +QS_processTestEvts_(); // process all events posted so far +QS_onTestLoop(); // run the test loop +QS_onCleanup(); // application cleanup +return 0; // return no error + + + + + // QActive stub for QUTest + + + //! @private @memberof QActive + +//! @private @memberof QActive + + + + + + + + + + + + + Q_UNUSED_PAR(stkSto); +Q_UNUSED_PAR(stkSize); + +me->prio = (uint8_t)(prioSpec & 0xFFU); // QF-prio. of the AO +me->pthre = (uint8_t)(prioSpec >> 8U); // preemption-threshold +QActive_register_(me); // make QF aware of this active object + +QEQueue_init(&me->eQueue, qSto, qLen); + +// top-most initial tran. (virtual call) +(*me->super.vptr->init)(&me->super, par, me->prio); + + + + //! @protected @memberof QActive + +//! @protected @memberof QActive + QActive_unsubscribeAll(me); // unsubscribe from all events +QActive_unregister_(me); // un-register this active object + + + + + // QTimeEvt stub for QUTest + + + //! @private @memberof QTimeEvt + +//! @private @memberof QTimeEvt + + + + + QS_CRIT_STAT +QS_CRIT_ENTRY(); +QS_MEM_SYS(); + +QTimeEvt *prev = &QTimeEvt_timeEvtHead_[tickRate]; + +QS_BEGIN_PRE_(QS_QF_TICK, 0U) + ++prev->ctr; + QS_TEC_PRE_(prev->ctr); // tick ctr + QS_U8_PRE_(tickRate); // tick rate +QS_END_PRE_() + +// is current Time Event object provided? +QTimeEvt *t = (QTimeEvt *)QS_rxPriv_.currObj[TE_OBJ]; +if (t != (QTimeEvt *)0) { + + // the time event must be armed + Q_ASSERT_INCRIT(810, t->ctr != 0U); + + QActive * const act = (QActive *)(t->act); + + // the recipient AO must be provided + Q_ASSERT_INCRIT(820, act != (QActive *)0); + + // periodic time evt? + if (t->interval != 0U) { + t->ctr = t->interval; // rearm the time event + } + else { // one-shot time event: automatically disarm + t->ctr = 0U; // auto-disarm + // mark time event 't' as NOT linked + t->super.refCtr_ &= (uint8_t)(~(uint8_t)QTE_IS_LINKED); + + QS_BEGIN_PRE_(QS_QF_TIMEEVT_AUTO_DISARM, act->prio) + QS_OBJ_PRE_(t); // this time event object + QS_OBJ_PRE_(act); // the target AO + QS_U8_PRE_(tickRate); // tick rate + QS_END_PRE_() + } + + QS_BEGIN_PRE_(QS_QF_TIMEEVT_POST, act->prio) + QS_TIME_PRE_(); // timestamp + QS_OBJ_PRE_(t); // the time event object + QS_SIG_PRE_(t->super.sig); // signal of this time event + QS_OBJ_PRE_(act); // the target AO + QS_U8_PRE_(tickRate); // tick rate + QS_END_PRE_() + QS_MEM_APP(); + QS_CRIT_EXIT(); // exit critical section before posting + + QACTIVE_POST(act, &t->super, sender); // asserts if queue overflows + + QS_CRIT_ENTRY(); + QS_MEM_SYS(); +} + +// update the linked list of time events +for (;;) { + t = prev->next; // advance down the time evt. list + + // end of the list? + if (t == (QTimeEvt *)0) { + + // any new time events armed since the last QTimeEvt_tick_()? + if (QTimeEvt_timeEvtHead_[tickRate].act != (void *)0) { + + // sanity check + Q_ASSERT_INCRIT(830, prev != (QTimeEvt *)0); + prev->next = (QTimeEvt *)QTimeEvt_timeEvtHead_[tickRate].act; + QTimeEvt_timeEvtHead_[tickRate].act = (void *)0; + t = prev->next; // switch to the new list + } + else { + break; // all currently armed time evts. processed + } + } + + // time event scheduled for removal? + if (t->ctr == 0U) { + prev->next = t->next; + // mark time event 't' as NOT linked + t->super.refCtr_ &= (uint8_t)(~(uint8_t)QTE_IS_LINKED); + // do NOT advance the prev pointer + QS_MEM_APP(); + QS_CRIT_EXIT(); // exit crit. section to reduce latency + } + else { + prev = t; // advance to this time event + QS_MEM_APP(); + QS_CRIT_EXIT(); // exit crit. section to reduce latency + } + QS_CRIT_ENTRY(); // re-enter crit. section to continue + QS_MEM_SYS(); +} + +QS_MEM_APP(); +QS_CRIT_EXIT(); + + + + + //! @class QHsmDummy +//! @extends QHsm + + + //! @public @memberof QHsmDummy + +//! @public @memberof QHsmDummy + static struct QAsmVtable const vtable = { + &QHsmDummy_init_, + &QHsmDummy_dispatch_ +#ifdef Q_SPY + ,&QHsm_getStateHandler_ +#endif +}; +me->super.vptr = &vtable; // hook the vptr + + + + //! @private @memberof QHsmDummy + +//! @private @memberof QHsmDummy + + + + + + + Q_UNUSED_PAR(par); + +#ifdef Q_SPY +if ((QS_priv_.flags & 0x01U) == 0U) { + QS_priv_.flags |= 0x01U; + QS_FUN_DICTIONARY(&QHsm_top); +} +#endif + +QS_CRIT_STAT +QS_CRIT_ENTRY(); +QS_MEM_SYS(); +QS_BEGIN_PRE_(QS_QEP_STATE_INIT, qs_id) + QS_OBJ_PRE_(me); // this state machine object + QS_FUN_PRE_(me->state.fun); // the source state + QS_FUN_PRE_(me->temp.fun); // the target of the initial tran. +QS_END_PRE_() +QS_MEM_APP(); +QS_CRIT_EXIT(); + + + + //! @private @memberof QHsmDummy + +//! @private @memberof QHsmDummy + + + + + + + QS_CRIT_STAT +QS_CRIT_ENTRY(); +QS_MEM_SYS(); +QS_BEGIN_PRE_(QS_QEP_DISPATCH, qs_id) + QS_TIME_PRE_(); // time stamp + QS_SIG_PRE_(e->sig); // the signal of the event + QS_OBJ_PRE_(me); // this state machine object + QS_FUN_PRE_(me->state.fun); // the current state +QS_END_PRE_() +QS_MEM_APP(); +QS_CRIT_EXIT(); + + + + + //! @class QActiveDummy +//! @extends QActive + + + //! @public @memberof QActiveDummy + +//! @public @memberof QActiveDummy + // superclass' ctor +QActive_ctor(&me->super, Q_STATE_CAST(0)); + +static struct QAsmVtable const vtable = { + &QActiveDummy_init_, + &QActiveDummy_dispatch_ +#ifdef Q_SPY + ,&QHsm_getStateHandler_ +#endif +}; +me->super.super.vptr = &vtable; // hook the vptr + + + + //! @private @memberof QActiveDummy + +//! @private @memberof QActiveDummy + + + + + + + Q_UNUSED_PAR(qs_id); + +QHsmDummy_init_(me, par, ((QActive const *)me)->prio); + + + + //! @private @memberof QActiveDummy + +//! @private @memberof QActiveDummy + + + + + + + Q_UNUSED_PAR(qs_id); + +QHsmDummy_dispatch_(me, e, ((QActive const *)me)->prio); + + + + //! @private @memberof QActiveDummy + +//! @private @memberof QActiveDummy + + + + + + + + + QS_TEST_PROBE_DEF(&QActive_post_) + +QF_CRIT_STAT +QF_CRIT_ENTRY(); +QF_MEM_SYS(); + +// test-probe#1 for faking queue overflow +bool status = true; +QS_TEST_PROBE_ID(1, + status = false; + if (margin == QF_NO_MARGIN) { + // fake assertion Mod=qf_actq,Loc=110 + Q_onError("qf_actq", 110); + } +) + +// is it a mutable event? +if (QEvt_getPoolId_(e) != 0U) { + QEvt_refCtr_inc_(e); +} + +uint_fast8_t const rec = (status ? (uint_fast8_t)QS_QF_ACTIVE_POST + : (uint_fast8_t)QS_QF_ACTIVE_POST_ATTEMPT); +QS_BEGIN_PRE_(rec, me->prio) + QS_TIME_PRE_(); // timestamp + QS_OBJ_PRE_(sender); // the sender object + QS_SIG_PRE_(e->sig); // the signal of the event + QS_OBJ_PRE_(me); // this active object + QS_2U8_PRE_(QEvt_getPoolId_(e), e->refCtr_); // poolId & refCtr + QS_EQC_PRE_(0U); // # free entries + QS_EQC_PRE_(margin); // margin requested +QS_END_PRE_() + +// callback to examine the posted event under the same conditions +// as producing the #QS_QF_ACTIVE_POST trace record, which are: +// the local filter for this AO ('me->prio') is set +if (QS_LOC_CHECK_(me->prio)) { + QS_onTestPost(sender, me, e, status); +} +QF_MEM_APP(); +QF_CRIT_EXIT(); + +// recycle the event immediately, because it was not really posted +#if (QF_MAX_EPOOL > 0U) +QF_gc(e); +#endif + +return status; // the event is "posted" correctly + + + + //! @private @memberof QActiveDummy + +//! @private @memberof QActiveDummy + + + + + QS_TEST_PROBE_DEF(&QActive_postLIFO_) + +QF_CRIT_STAT +QF_CRIT_ENTRY(); +QF_MEM_SYS(); + +// test-probe#1 for faking queue overflow +QS_TEST_PROBE_ID(1, + // fake assertion Mod=qf_actq,Loc=210 + Q_onError("qf_actq", 210); +) + +// is it a mutable event? +if (QEvt_getPoolId_(e) != 0U) { + QEvt_refCtr_inc_(e); +} + +QS_BEGIN_PRE_(QS_QF_ACTIVE_POST_LIFO, me->prio) + QS_TIME_PRE_(); // timestamp + QS_SIG_PRE_(e->sig); // the signal of this event + QS_OBJ_PRE_(me); // this active object + QS_2U8_PRE_(QEvt_getPoolId_(e), e->refCtr_); // poolId & refCtr + QS_EQC_PRE_(0U); // # free entries + QS_EQC_PRE_(0U); // min # free entries +QS_END_PRE_() + +// callback to examine the posted event under the same conditions +// as producing the #QS_QF_ACTIVE_POST trace record, which are: +// the local filter for this AO ('me->prio') is set +if (QS_LOC_CHECK_(me->prio)) { + QS_onTestPost((QActive *)0, me, e, true); +} +QF_MEM_APP(); +QF_CRIT_EXIT(); + +// recycle the event immediately, because it was not really posted +#if (QF_MAX_EPOOL > 0U) +QF_gc(e); +#endif + + + - /*! Initialize the QS facility -* -* @details -* This macro provides an indirection layer to invoke the QS initialization -* routine if #Q_SPY is defined, or do nothing if #Q_SPY is not defined. -* @sa QS_onStartup(), example of setting up a QS filter in -* QS_GLB_FILTER() -*/ (QS_onStartup(arg_)) - /*! Cleanup the QS facility -* -* @details -* This macro provides an indirection layer to invoke the QS cleanup -* routine if #Q_SPY is defined, or do nothing if #Q_SPY is not defined. -* @sa QS_onCleanup() -*/ (QS_onCleanup()) - /*! macro to handle the QS output from the application -* -* @note -* If this macro is used, the application must define QS_output(). -*/ (QS_output()) - /*! macro to handle the QS-RX input to the application -* -* @note -* If this macro is used, the application must define QS_doInput(). -*/ (QS_rx_input()) - /*! Global Filter ON for a given record type `rec_` -* -* @details -* This macro provides an indirection layer to call QS_filterOn() -* if #Q_SPY is defined, or do nothing if #Q_SPY is not defined. -* -* @sa -* - enum QSpyGroups - QS record groups that can be used as `rec_` -* - enum QSpyPre - predefined QS records that can be used as `rec_` -* -* @usage -* The following example shows how to use QS filters: -* @include qs_filter.c -*/ (QS_glbFilter_((int_fast16_t)(rec_))) - /*! Local Filter for a given state machine object `qs_id` -* -* @details -* This macro provides an indirection layer to call QS_locFilter_() -* if #Q_SPY is defined, or do nothing if #Q_SPY is not defined. -* -* @sa -* - enum QSpyIdGroups - QS ID groups that can be used as `qs_id_` -* - enum QSpyIdOffsets - QS ID offsets for `qs_id_` (e.g., QS_AP_IDS + 5) -* -* The following example shows how to use QS filters: -* @include qs_filter.c -*/ (QS_locFilter_((int_fast16_t)(qs_id_))) - /*! Begin an application-specific QS record with entering critical section -* -* @details -* The following example shows how to build a user QS record using the -* macros QS_BEGIN_ID(), QS_END(), and the formatted output macros: -* QS_U8(), QS_STR(), etc. -* -* @note -* Must always be used in pair with QS_END() -* -* @include qs_ap.c -*/ \ if (QS_GLB_CHECK_(rec_) && QS_LOC_CHECK_(qs_id_)) { \ - QS_CRIT_STAT_ \ - QS_CRIT_E_(); \ + QS_CRIT_STAT \ + QS_CRIT_ENTRY(); \ + QS_MEM_SYS(); \ QS_beginRec_((uint_fast8_t)(rec_)); \ QS_TIME_PRE_(); { - /*! End an application-specific QS record with exiting critical section. -* -* @sa example for QS_BEGIN_ID() -* @note Must always be used in pair with QS_BEGIN_ID() -*/ } \ QS_endRec_(); \ - QS_CRIT_X_(); \ + QS_MEM_APP(); \ + QS_CRIT_EXIT(); \ } - /*! Flush the QS trace data to the host -* -* @details -* This macro invokes the QS_flush() platform-dependent callback -* function to flush the QS trace buffer to the host. The function -* typically busy-waits until all the data in the buffer is sent to -* the host. This is acceptable only in the initial transient. -*/ (QS_onFlush()) - - - /*! Begin an application-specific QS record WITHOUT entering critical section */ - + + + - + \ if (QS_GLB_CHECK_(rec_) && QS_LOC_CHECK_(qs_id_)) { \ QS_beginRec_((uint_fast8_t)(rec_)); \ QS_TIME_PRE_(); { - - - /*! End an application-specific QS record WITHOUT exiting critical section */ + + } \ - QS_endRec_();\ + QS_endRec_(); \ } - /*! Helper macro for checking the global QS filter */ \ - (((uint_fast8_t)QS_priv_.glbFilter[(uint_fast8_t)(rec_) >> 3U] \ + (((uint_fast8_t)QS_filt_.glb[(uint_fast8_t)(rec_) >> 3U] \ & ((uint_fast8_t)1U << ((uint_fast8_t)(rec_) & 7U))) != 0U) - /*! Helper macro for checking the local QS filter */ \ - (((uint_fast8_t)QS_priv_.locFilter[(uint_fast8_t)(qs_id_) >> 3U] \ + (((uint_fast8_t)QS_filt_.loc[(uint_fast8_t)(qs_id_) >> 3U] \ & ((uint_fast8_t)1U << ((uint_fast8_t)(qs_id_) & 7U))) != 0U) - /*! Macro to execute user code when a QS record is produced -* -* @note -* This is a dummy definition in case this macro is undefined. -*/ ((void)0) - /*! Output formatted int8_t to the QS record */ @@ -6825,7 +8209,6 @@ if (QS_GLB_CHECK_(rec_) && QS_LOC_CHECK_(qs_id_)) { \ - /*! Output formatted uint8_t to the QS record */ @@ -6835,7 +8218,6 @@ if (QS_GLB_CHECK_(rec_) && QS_LOC_CHECK_(qs_id_)) { \ - /*! Output formatted int16_t to the QS record */ @@ -6845,7 +8227,6 @@ if (QS_GLB_CHECK_(rec_) && QS_LOC_CHECK_(qs_id_)) { \ - /*! Output formatted uint16_t to the QS record */ @@ -6855,7 +8236,6 @@ if (QS_GLB_CHECK_(rec_) && QS_LOC_CHECK_(qs_id_)) { \ - /*! Output formatted int32_t to the QS record */ @@ -6865,7 +8245,6 @@ if (QS_GLB_CHECK_(rec_) && QS_LOC_CHECK_(qs_id_)) { \ - /*! Output formatted uint32_t to the QS record */ @@ -6875,7 +8254,6 @@ if (QS_GLB_CHECK_(rec_) && QS_LOC_CHECK_(qs_id_)) { \ - /*! Output formatted int64_t to the QS record */ @@ -6885,7 +8263,6 @@ if (QS_GLB_CHECK_(rec_) && QS_LOC_CHECK_(qs_id_)) { \ - /*! Output formatted uint64_t to the QS record */ @@ -6895,7 +8272,6 @@ if (QS_GLB_CHECK_(rec_) && QS_LOC_CHECK_(qs_id_)) { \ - /*! Output formatted 32-bit floating point number to the QS record */ @@ -6905,7 +8281,6 @@ if (QS_GLB_CHECK_(rec_) && QS_LOC_CHECK_(qs_id_)) { \ - /*! Output formatted 64-bit floating point number to the QS record */ @@ -6915,14 +8290,12 @@ if (QS_GLB_CHECK_(rec_) && QS_LOC_CHECK_(qs_id_)) { \ - /*! Output formatted zero-terminated ASCII string to the QS record */ (QS_str_fmt_((str_))) - /*! Output formatted memory block of up to 255 bytes to the QS record */ @@ -6931,7 +8304,6 @@ if (QS_GLB_CHECK_(rec_) && QS_LOC_CHECK_(qs_id_)) { \ - /*! Output formatted enumeration to the QS record */ @@ -6941,26 +8313,12 @@ if (QS_GLB_CHECK_(rec_) && QS_LOC_CHECK_(qs_id_)) { \ (uint8_t)(value_))) - - /*! Output time stamp to a QS record (used in predefined -* and application-specific trace records) -*/ - (QS_u32_raw_(QS_onGetTime())) - - (QS_u16_raw_(QS_onGetTime())) - - (QS_u8_raw_(QS_onGetTime())) - - - - /*! Output formatted object pointer to the QS record */ - - - (QS_u32_fmt_(QS_OBJ_T, (uint32_t)(obj_))) + + (QS_u32_raw_(QS_onGetTime())) @@ -6969,10 +8327,10 @@ if (QS_GLB_CHECK_(rec_) && QS_LOC_CHECK_(qs_id_)) { \ (QS_u16_fmt_(QS_OBJ_T, (uint16_t)(obj_))) - + - (QS_u8_fmt_(QS_OBJ_T, (uint8_t)(obj_))) + (QS_u32_fmt_(QS_OBJ_T, (uint32_t)(obj_))) @@ -6981,23 +8339,16 @@ if (QS_GLB_CHECK_(rec_) && QS_LOC_CHECK_(qs_id_)) { \ (QS_u64_fmt_(QS_OBJ_T, (uint64_t)(obj_))) - - /* Output formatted function pointer to the QS record */ - - - (QS_u32_fmt_(QS_FUN_T, (uint32_t)(fun_))) - - (QS_u16_fmt_(QS_FUN_T, (uint16_t)(fun_))) - + - (QS_u8_fmt_(QS_FUN_T, (uint8_t)(fun_))) + (QS_u32_fmt_(QS_FUN_T, (uint32_t)(fun_))) @@ -7006,16 +8357,13 @@ if (QS_GLB_CHECK_(rec_) && QS_LOC_CHECK_(qs_id_)) { \ (QS_u64_fmt_(QS_FUN_T, (uint64_t)(fun_))) - - /*! Output formatted event signal (of type ::QSignal) and -* the state machine object to the user QS record -*/ + \ - QS_u32_fmt_(QS_SIG_T, (sig_)); \ + QS_u8_fmt_(QS_SIG_T, (sig_)); \ QS_obj_raw_(obj_) @@ -7029,70 +8377,26 @@ if (QS_GLB_CHECK_(rec_) && QS_LOC_CHECK_(qs_id_)) { \ QS_obj_raw_(obj_) - + \ - QS_u8_fmt_(QS_SIG_T, (sig_)); \ + QS_u32_fmt_(QS_SIG_T, (sig_)); \ QS_obj_raw_(obj_) - /*! Output QS signal dictionary record -* -* @details -* A signal dictionary record associates the numerical value of the signal -* and the binary address of the state machine that consumes that signal -* with the human-readable name of the signal. -* -* @param[in] sig_ event signal (typically enumerated, e.g. `TIMEOUT_SIG`) -* @param[in] obj_ pointer to the associated state machine object -* (might be `(void*)0` for globally recognized signals) -* -* A signal dictionary entry is associated with both the signal value `sig_` -* and the state machine `obj_`, because signals are required to be unique -* only within a given state machine and therefore the same numerical values -* can represent different signals in different state machines. -* -* For the "global" signals that have the same meaning in many state machines -* (such as globally published signals), you can specify a signal dictionary -* entry with the `obj_` parameter set to `(void*)0`. -* -* The following example shows the definition of signal dictionary entries -* in the initial transition of the Table active object. Please note that -* signals HUNGRY_SIG and DONE_SIG are associated with the Table state -* machine only ("me" `obj_` pointer). The EAT_SIG signal, on the other -* hand, is global (0 `obj_` pointer): -* @include qs_sigDic.c -* -* The following QSpy log example shows the signal dictionary records -* generated from the Table initial transition and subsequent records that -* show human-readable names of the signals: -* @include qs_sigLog.txt -*/ \ - (QS_sig_dict_pre_((sig_), (obj_), #sig_)) + (QS_sig_dict_pre_((QSignal)(sig_), (obj_), #sig_)) - /*! Output object dictionary record -* -* @details -* An object dictionary record associates the binary address of an object -* in the target's memory with the human-readable name of the object. -* -* @param[in] obj_ pointer to the object (any object) -* -* The following example shows the definition of object dictionary entry -* for the Table active object: -* @include qs_objDic.c -*/ \ @@ -7100,20 +8404,6 @@ if (QS_GLB_CHECK_(rec_) && QS_LOC_CHECK_(qs_id_)) { \ - /*! Output object-array dictionary record -* -* @details -* An object array dictionary record associates the binary address of the -* object element in the target's memory with the human-readable name -* of the object. -* -* @param[in] obj_ pointer to the object (any object) -* @param[in] idx_ array index -* -* The following example shows the definition of object array dictionary -* for `Philo::inst[n]` and `Philo::inst[n].m_timeEvt`: -* @include qs_objArrDic.c -*/ @@ -7123,19 +8413,6 @@ if (QS_GLB_CHECK_(rec_) && QS_LOC_CHECK_(qs_id_)) { \ - /*! Output function dictionary record -* -* @details -* A function dictionary record associates the binary address of a function -* in the target's memory with the human-readable name of the function. -* -* Providing a function dictionary QS record can vastly improve readability -* of the QS log, because instead of dealing with cryptic machine addresses -* the QSpy host utility can display human-readable function names. -* -* The example from #QS_SIG_DICTIONARY shows the definition of a function -* dictionary. -*/ \ @@ -7143,12 +8420,6 @@ if (QS_GLB_CHECK_(rec_) && QS_LOC_CHECK_(qs_id_)) { \ - /*! Output user QS record dictionary record -* -* @details -* A user QS record dictionary record associates the numerical value of a -* user record with the human-readable identifier. -*/ \ @@ -7156,12 +8427,6 @@ if (QS_GLB_CHECK_(rec_) && QS_LOC_CHECK_(qs_id_)) { \ - /*! Output enumeration dictionary record -* -* @details -* An enum QS record dictionary record associates the numerical value of -* an enumeration with the human-readable identifier. -*/ @@ -7169,1452 +8434,2257 @@ if (QS_GLB_CHECK_(rec_) && QS_LOC_CHECK_(qs_id_)) { \ \ (QS_enum_dict_pre_((value_), (group_), #value_)) - - - /*! Output the critical section entry record */ + + + + + (QS_rxPut((b_))) - - - /*! Output the critical section exit record */ - - - - /*! Output the interrupt entry record *//*! Output the ISR entry */ - + + + + + + + - - - QS_BEGIN_NOCRIT_PRE_(QS_QF_ISR_ENTRY, 0U) - QS_TIME_PRE_(); - QS_2u8_raw_(isrnest, prio); -QS_END_NOCRIT_PRE_() + + + do { \ + QS_BEGIN_PRE_(QS_QF_ISR_ENTRY, 0U) \ + QS_TIME_PRE_(); \ + QS_2u8_raw_(isrnest, prio); \ + QS_END_PRE_() \ +} - - - /*! Output the ISR exit trace record */ - + + + - + - QS_BEGIN_NOCRIT_PRE_(QS_QF_ISR_EXIT, 0U) - QS_TIME_PRE_(); - QS_2u8_raw_(isrnest, prio); -QS_END_NOCRIT_PRE_() + do { \ + QS_BEGIN_PRE_(QS_QF_ISR_EXIT, 0U) \ + QS_TIME_PRE_(); \ + QS_2u8_raw_(isrnest, prio); \ + QS_END_PRE_() \ +} while (false) - - - /*! Execute an action that is only necessary for QS output */ - - - (act_) + + + + + (code_) + + + + + + + + + + \ + (QS_assertion_pre_((module_), (id_), (delay_))) - /*! Constant representing End-Of-Data condition returned from the -* QS_getByte() function. -*/ ((uint16_t)0xFFFFU) - /*! Constant representing command enumeration group -* in QS_ENUM_DICTIONARY() and QS_ENUM() -* @sa QS_onCommand() -*/ ((uint8_t)7U) - /*! Constant representing HEX format for the "width" filed -* in QS_U8(), QS_U16(), QS_U32(), and QS_U64(). -*/ ((uint8_t)0x0FU) + + + QF_CRIT_STAT + + + + QF_CRIT_ENTRY() + + + + QF_CRIT_EXIT() + + + + QF_MEM_SYS() + + + + QF_MEM_APP() + - - - - - /*! QS ring buffer counter and offset type */ - - - - - - /*! QS time stamp type, which determines the dynamic range of QS time stamps */ - - - - - - - - /*! QS function pointer type (for serializing function pointers) */ - - - - - - - - - - /*! QS pre-defined record types (TX channel) -* @static @public @memberof QS_tx -* -* @details -* This enumeration specifies the record types used in the QP components. -* You can specify your own record types starting from ::QS_USER offset. -* Currently, the maximum of all records cannot exceed 125. -* -* @note -* The QS records labeled as "not maskable" are always enabled and cannot -* be turend off with the QS_GLB_FILTER() macro. Other QS trace records -* can be disabled by means of the "global filters" -* -* @sa QS_GLB_FILTER() macro -*/ - { - /* [0] QS session (not maskable) */ - QS_EMPTY, /*!< QS record for cleanly starting a session */ + + + + + #ifndef QSAFE_H_ +#define QSAFE_H_ - /* [1] SM records */ - QS_QEP_STATE_ENTRY, /*!< a state was entered */ - QS_QEP_STATE_EXIT, /*!< a state was exited */ - QS_QEP_STATE_INIT, /*!< an initial transition was taken in a state */ - QS_QEP_INIT_TRAN, /*!< the top-most initial transition was taken */ - QS_QEP_INTERN_TRAN, /*!< an internal transition was taken */ - QS_QEP_TRAN, /*!< a regular transition was taken */ - QS_QEP_IGNORED, /*!< an event was ignored (silently discarded) */ - QS_QEP_DISPATCH, /*!< an event was dispatched (begin of RTC step) */ - QS_QEP_UNHANDLED, /*!< an event was un-handled due to a guard */ +#ifdef __cplusplus +extern "C" { +#endif - /* [10] Active Object (AO) records */ - QS_QF_ACTIVE_DEFER, /*!< AO deferred an event */ - QS_QF_ACTIVE_RECALL, /*!< AO recalled an event */ - QS_QF_ACTIVE_SUBSCRIBE, /*!< an AO subscribed to an event */ - QS_QF_ACTIVE_UNSUBSCRIBE, /*!< an AO unsubscribed to an event */ - QS_QF_ACTIVE_POST, /*!< an event was posted (FIFO) directly to AO */ - QS_QF_ACTIVE_POST_LIFO, /*!< an event was posted (LIFO) directly to AO */ - QS_QF_ACTIVE_GET, /*!< AO got an event and its queue is not empty */ - QS_QF_ACTIVE_GET_LAST,/*!< AO got an event and its queue is empty */ - QS_QF_ACTIVE_RECALL_ATTEMPT, /*!< AO attempted to recall an event */ +// QF-FuSa enabled =========================================================== +#ifndef Q_UNSAFE - /* [19] Event Queue (EQ) records */ - QS_QF_EQUEUE_POST, /*!< an event was posted (FIFO) to a raw queue */ - QS_QF_EQUEUE_POST_LIFO, /*!< an event was posted (LIFO) to a raw queue */ - QS_QF_EQUEUE_GET, /*!< get an event and queue still not empty */ - QS_QF_EQUEUE_GET_LAST,/*!< get the last event from the queue */ +#ifndef QF_CRIT_STAT +#define QF_CRIT_STAT +#endif - /* [23] Framework (QF) records */ - QS_QF_NEW_ATTEMPT, /*!< an attempt to allocate an event failed */ +#ifndef QF_CRIT_ENTRY +#define QF_CRIT_ENTRY() ((void)0) +#endif - /* [24] Memory Pool (MP) records */ - QS_QF_MPOOL_GET, /*!< a memory block was removed from memory pool */ - QS_QF_MPOOL_PUT, /*!< a memory block was returned to memory pool */ +#ifndef QF_CRIT_EXIT +#define QF_CRIT_EXIT() ((void)0) +#endif - /* [26] Additional Framework (QF) records */ - QS_QF_PUBLISH, /*!< an event was published to active objects */ - QS_QF_NEW_REF, /*!< new event reference was created */ - QS_QF_NEW, /*!< new event was created */ - QS_QF_GC_ATTEMPT, /*!< garbage collection attempt */ - QS_QF_GC, /*!< garbage collection */ - QS_QF_TICK, /*!< QTimeEvt_tick_() was called */ +$declare ${QP-FuSa::enabled} - /* [32] Time Event (TE) records */ - QS_QF_TIMEEVT_ARM, /*!< a time event was armed */ - QS_QF_TIMEEVT_AUTO_DISARM, /*!< a time event expired and was disarmed */ - QS_QF_TIMEEVT_DISARM_ATTEMPT,/*!< attempt to disarm a disarmed QTimeEvt */ - QS_QF_TIMEEVT_DISARM, /*!< true disarming of an armed time event */ - QS_QF_TIMEEVT_REARM, /*!< rearming of a time event */ - QS_QF_TIMEEVT_POST, /*!< a time event posted itself directly to an AO */ +// QF-FuSa disabled ========================================================== +#else +$declare ${QP-FuSa::disabled} +#endif - /* [38] Additional Framework (QF) records */ - QS_QF_DELETE_REF, /*!< an event reference is about to be deleted */ - QS_QF_CRIT_ENTRY, /*!< critical section was entered */ - QS_QF_CRIT_EXIT, /*!< critical section was exited */ - QS_QF_ISR_ENTRY, /*!< an ISR was entered */ - QS_QF_ISR_EXIT, /*!< an ISR was exited */ - QS_QF_INT_DISABLE, /*!< interrupts were disabled */ - QS_QF_INT_ENABLE, /*!< interrupts were enabled */ +//============================================================================ +$declare1 ${QP-FuSa} - /* [45] Additional Active Object (AO) records */ - QS_QF_ACTIVE_POST_ATTEMPT,/*!< attempt to post an evt to AO failed */ - - /* [46] Additional Event Queue (EQ) records */ - QS_QF_EQUEUE_POST_ATTEMPT,/*!< attempt to post evt to QEQueue failed */ - - /* [47] Additional Memory Pool (MP) records */ - QS_QF_MPOOL_GET_ATTEMPT, /*!< attempt to get a memory block failed */ - - /* [48] Scheduler (SC) records */ - QS_SCHED_PREEMPT, /*!< scheduler asynchronously preempted a task */ - QS_SCHED_RESTORE, /*!< scheduler restored preempted task */ - QS_SCHED_LOCK, /*!< scheduler was locked */ - QS_SCHED_UNLOCK, /*!< scheduler was unlocked */ - QS_SCHED_NEXT, /*!< scheduler started new task */ - QS_SCHED_IDLE, /*!< scheduler restored the idle task */ - - /* [54] Miscellaneous QS records (not maskable) */ - QS_ENUM_DICT, /*!< enumeration dictionary entry */ - - /* [55] Additional QEP records */ - QS_QEP_TRAN_HIST, /*!< a tran to history was taken */ - QS_QEP_TRAN_EP, /*!< a tran to entry point into a submachine */ - QS_QEP_TRAN_XP, /*!< a tran to exit point out of a submachine */ - - /* [58] Miscellaneous QS records (not maskable) */ - QS_TEST_PAUSED, /*!< test has been paused */ - QS_TEST_PROBE_GET, /*!< reports that Test-Probe has been used */ - QS_SIG_DICT, /*!< signal dictionary entry */ - QS_OBJ_DICT, /*!< object dictionary entry */ - QS_FUN_DICT, /*!< function dictionary entry */ - QS_USR_DICT, /*!< user QS record dictionary entry */ - QS_TARGET_INFO, /*!< reports the Target information */ - QS_TARGET_DONE, /*!< reports completion of a user callback */ - QS_RX_STATUS, /*!< reports QS data receive status */ - QS_QUERY_DATA, /*!< reports the data from "current object" query */ - QS_PEEK_DATA, /*!< reports the data from the PEEK query */ - QS_ASSERT_FAIL, /*!< assertion failed in the code */ - QS_QF_RUN, /*!< QF_run() was entered */ - - /* [71] Semaphore (SEM) records */ - QS_SEM_TAKE, /*!< a semaphore was taken by a thread */ - QS_SEM_BLOCK, /*!< a semaphore blocked a thread */ - QS_SEM_SIGNAL, /*!< a semaphore was signaled */ - QS_SEM_BLOCK_ATTEMPT, /*!< a semaphore blocked was attempted */ - - /* [75] Mutex (MTX) records */ - QS_MTX_LOCK, /*!< a mutex was locked */ - QS_MTX_BLOCK, /*!< a mutex blocked a thread */ - QS_MTX_UNLOCK, /*!< a mutex was unlocked */ - QS_MTX_LOCK_ATTEMPT, /*!< a mutex lock was attempted */ - QS_MTX_BLOCK_ATTEMPT, /*!< a mutex blocking was attempted */ - QS_MTX_UNLOCK_ATTEMPT,/*!< a mutex unlock was attempted */ - - /* [81] */ - QS_PRE_MAX /*!< the number of predefined signals */ -}; - - - - /*! QS record groups for QS_GLB_FILTER() -* @static @public @memberof QS_tx -*/ - { - QS_ALL_RECORDS = 0xF0,/*!< all maskable QS records */ - QS_SM_RECORDS, /*!< State Machine QS records */ - QS_AO_RECORDS, /*!< Active Object QS records */ - QS_EQ_RECORDS, /*!< Event Queues QS records */ - QS_MP_RECORDS, /*!< Memory Pools QS records */ - QS_TE_RECORDS, /*!< Time Events QS records */ - QS_QF_RECORDS, /*!< QF QS records */ - QS_SC_RECORDS, /*!< Scheduler QS records */ - QS_SEM_RECORDS, /*!< Semaphore QS records */ - QS_MTX_RECORDS, /*!< Mutex QS records */ - QS_U0_RECORDS, /*!< User Group 100-104 records */ - QS_U1_RECORDS, /*!< User Group 105-109 records */ - QS_U2_RECORDS, /*!< User Group 110-114 records */ - QS_U3_RECORDS, /*!< User Group 115-119 records */ - QS_U4_RECORDS, /*!< User Group 120-124 records */ - QS_UA_RECORDS /*!< All User records */ -}; - - - - /*! QS user record group offsets for QS_GLB_FILTER() -* @static @public @memberof QS_tx -*/ - { - QS_USER = 100, /*!< the first record available to QS users */ - QS_USER0 = (enum_t)QS_USER, /*!< offset for User Group 0 */ - QS_USER1 = (enum_t)QS_USER0 + 5, /*!< offset for User Group 1 */ - QS_USER2 = (enum_t)QS_USER1 + 5, /*!< offset for User Group 2 */ - QS_USER3 = (enum_t)QS_USER2 + 5, /*!< offset for User Group 3 */ - QS_USER4 = (enum_t)QS_USER3 + 5 /*!< offset for User Group 4 */ -}; - - - - /*! QS ID offsets for QS_LOC_FILTER() -* @static @public @memberof QS_tx -*/ - { - QS_AO_ID = 0, /*!< offset for AO priorities */ - QS_EP_ID = 64, /*!< offset for event-pool IDs */ - QS_EQ_ID = 80, /*!< offset for event-queue IDs */ - QS_AP_ID = 96 /*!< offset for Application-specific IDs */ -}; - - - - /*! QS ID groups for QS_LOC_FILTER() -* @static @public @memberof QS_tx -*/ - { - QS_ALL_IDS = 0xF0, /*!< all QS IDs */ - QS_AO_IDS = (0x80 + (enum_t)QS_AO_ID), /*!< AO IDs (priorities) */ - QS_EP_IDS = (0x80 + (enum_t)QS_EP_ID), /*!< event-pool IDs */ - QS_EQ_IDS = (0x80 + (enum_t)QS_EQ_ID), /*!< event-queue IDs */ - QS_AP_IDS = (0x80 + (enum_t)QS_AP_ID) /*!< Application-specific IDs */ -}; - - - - /*! function pointer type for QS_fun_dict_pre_() -* @static @private @memberof QS_tx -*/ - )(void); - - - - /*! @brief QS ID type for applying local filtering -* @static @public @memberof QS_tx -*/ - - - - - - /*! @brief Software tracing, output QS-TX -* -* @details -* This class groups together QS services. -*/ - - - /*! global on/off QS filter */ - - - - /*! local on/off QS filter */ - - - - /*! @deprecated old local QS filter */ - - - - /*! pointer to the start of the QS-TX ring buffer */ - - - - /*! offset of the end of the ring buffer */ - - - - /*! offset to where next byte will be inserted */ - - - - /*! offset of where next record will be extracted */ - - - - /*! number of bytes currently in the ring buffer */ - - - - /*! sequence number of the last inserted QS record */ - - - - /*! checksum of the currently inserted record */ - - - - /*! critical section nesting level */ - - - - /* flags for internal use */ - - - - - /*! Enumerates data elements for app-specific trace records */ - { - QS_I8_ENUM_T, /*!< signed 8-bit integer or enum format */ - QS_U8_T, /*!< unsigned 8-bit integer format */ - QS_I16_T, /*!< signed 16-bit integer format */ - QS_U16_T, /*!< unsigned 16-bit integer format */ - QS_I32_T, /*!< signed 32-bit integer format */ - QS_U32_T, /*!< unsigned 32-bit integer format */ - QS_F32_T, /*!< 32-bit floating point format */ - QS_F64_T, /*!< 64-bit floating point format */ - QS_STR_T, /*!< zero-terminated ASCII string format */ - QS_MEM_T, /*!< up to 255-bytes memory block format */ - QS_SIG_T, /*!< event signal format */ - QS_OBJ_T, /*!< object pointer format */ - QS_FUN_T, /*!< function pointer format */ - QS_I64_T, /*!< signed 64-bit integer format */ - QS_U64_T /*!< unsigned 64-bit integer format */ -}; - - - - /*! the only instance of the QS-TX object (Singleton) */ - - - - /*! Initialize the QS-TX data buffer -* @static @public @memberof QS_tx -* -* @details -* This function should be called from QS_onStartup() to provide -* QS with the data buffer. The first argument `sto` is the address -* of the memory block, and the second argument `stoSize` is the size -* of this block [in bytes]. Currently the size of the QS buffer cannot -* exceed 64KB. -* -* @param[in] sto pointer to the storage for the transmit buffer -* @param[in] stoSize size in [bytes] of the storage buffer -* -* @remark -* QS can work with quite small data buffers, but you will start losing -* data if the buffer is too small for the bursts of tracing activity. -* The right size of the buffer depends on the data production rate and -* the data output rate. QS offers flexible filtering to reduce the data -* production rate. -* -* @note -* If the data output rate cannot keep up with the production rate, -* QS will start overwriting the older data with newer data. This is -* consistent with the "last-is-best" QS policy. The record sequence -* counters and check sums on each record allow the QSPY host utility -* to easily detect any data loss. -*/ - - - - - /* the provided buffer must be at least 8 bytes long */ -Q_REQUIRE_ID(100, stoSize > 8U); - -QS_priv_.buf = &sto[0]; -QS_priv_.end = (QSCtr)stoSize; -QS_priv_.head = 0U; -QS_priv_.tail = 0U; -QS_priv_.used = 0U; -QS_priv_.seq = 0U; -QS_priv_.chksum = 0U; -QS_priv_.critNest = 0U; - -QS_glbFilter_(-(int_fast16_t)QS_ALL_RECORDS); /* all global filters OFF */ -QS_locFilter_((int_fast16_t)QS_ALL_IDS); /* all local filters ON */ -QS_priv_.locFilter_AP = (void *)0; /* deprecated "AP-filter" */ - -/* produce an empty record to "flush" the QS trace buffer */ -QS_beginRec_((uint_fast8_t)QS_EMPTY); -QS_endRec_(); - -/* produce the reset record to inform QSPY of a new session */ -QS_target_info_pre_(0xFFU); /* send Reset and Target info */ - -/* hold off flushing after successfull initialization (see QS_INIT()) */ - - - - /*! Byte-oriented interface to the QS-TX data buffer -* @static @public @memberof QS_tx -* -* @details -* This function delivers one byte at a time from the QS data buffer. -* -* @returns -* the byte in the least-significant 8-bits of the 16-bit return -* value if the byte is available. If no more data is available at the -* time, the function returns ::QS_EOD (End-Of-Data). -* -* @note -* QS_getByte() is NOT protected with a critical section. -*/ - uint16_t ret; -if (QS_priv_.used == 0U) { - ret = QS_EOD; /* set End-Of-Data */ +#ifdef __cplusplus } -else { - uint8_t const * const buf = QS_priv_.buf; /* put in a temporary */ - QSCtr tail = QS_priv_.tail; /* put in a temporary (register) */ - ret = (uint16_t)buf[tail]; /* set the byte to return */ - ++tail; /* advance the tail */ - if (tail == QS_priv_.end) { /* tail wrap around? */ - tail = 0U; - } - QS_priv_.tail = tail; /* update the tail */ - --QS_priv_.used; /* one less byte used */ -} -return ret; /* return the byte or EOD */ - - - - /*! Block-oriented interface to the QS-TX data buffer -* @static @public @memberof QS_tx -* -* @details -* This function delivers a contiguous block of data from the QS data -* buffer. The function returns the pointer to the beginning of the -* block, and writes the number of bytes in the block to the location -* pointed to by `pNbytes`. The argument `pNbytes` is also used as -* input to provide the maximum size of the data block that the caller -* can accept. -* -* @param[in,out] pNbytes pointer to the number of bytes to send. -* On input, `pNbytes` specifies the maximum number -* of bytes that the function can provide. -* On output, `pNbytes` contains the actual number -* of bytes available. -* @returns -* if data is available, the function returns pointer to the -* contiguous block of data and sets the value pointed to by `pNbytes` -* to the # available bytes. If data is available at the time the -* function is called, the function returns NULL pointer and sets the -* value pointed to by `pNbytes` to zero. -* -* @note -* Only the NULL return from QS_getBlock() indicates that the QS -* buffer is empty at the time of the call. The non-NULL return often -* means that the block is at the end of the buffer and you need to call -* QS_getBlock() again to obtain the rest of the data that -* "wrapped around" to the beginning of the QS data buffer. -* -* @note QS_getBlock() is **not** protected with a critical section. -*/ - - - QSCtr const used = QS_priv_.used; /* put in a temporary (register) */ -uint8_t const *buf; +#endif -/* any bytes used in the ring buffer? */ -if (used != 0U) { - QSCtr tail = QS_priv_.tail; /* put in a temporary (register) */ - QSCtr const end = QS_priv_.end; /* put in a temporary (register) */ - QSCtr n = (QSCtr)(end - tail); - if (n > used) { - n = used; - } - if (n > (QSCtr)(*pNbytes)) { - n = (QSCtr)(*pNbytes); - } - *pNbytes = (uint16_t)n; /* n-bytes available */ - buf = &QS_priv_.buf[tail]; /* the bytes are at the tail */ +#endif // QSAFE_H_ + + + + #ifndef QP_H_ +#define QP_H_ - QS_priv_.used = (QSCtr)(used - n); - tail += n; - if (tail == end) { - tail = 0U; - } - QS_priv_.tail = tail; +//============================================================================ +#define QP_VERSION 730U +#define QP_VERSION_STR "7.3.0" + +//! Encrypted current QP release (7.3.0) and date (2023-09-12) +#define QP_RELEASE 0x765D9D25U + +//============================================================================ +//! @cond INTERNAL + +#ifndef Q_SIGNAL_SIZE +#define Q_SIGNAL_SIZE 2U +#endif + +#ifndef QF_MAX_ACTIVE +#define QF_MAX_ACTIVE 32U +#endif + +#if (QF_MAX_ACTIVE > 64U) +#error QF_MAX_ACTIVE exceeds the maximum of 64U; +#endif + +#ifndef QF_MAX_TICK_RATE +#define QF_MAX_TICK_RATE 1U +#endif + +#if (QF_MAX_TICK_RATE > 15U) +#error QF_MAX_TICK_RATE exceeds the maximum of 15U; +#endif + +#ifndef QF_MAX_EPOOL +#define QF_MAX_EPOOL 3U +#endif + +#if (QF_MAX_EPOOL > 15U) +#error QF_MAX_EPOOL exceeds the maximum of 15U; +#endif + +#ifndef QF_TIMEEVT_CTR_SIZE +#define QF_TIMEEVT_CTR_SIZE 4U +#endif + +#if (QF_TIMEEVT_CTR_SIZE > 4U) +#error QF_TIMEEVT_CTR_SIZE defined incorrectly, expected 1U, 2U, or 4U; +#endif + +#ifndef QF_EVENT_SIZ_SIZE +#define QF_EVENT_SIZ_SIZE 2U +#endif + +#if (QF_EVENT_SIZ_SIZE > 4U) +#error QF_EVENT_SIZ_SIZE defined incorrectly, expected 1U, 2U, or 4U; +#endif + +//! @endcond +//============================================================================ + +$declare ${glob-types} + +$declare ${QEP} + +$declare ${QEP-macros} + +$declare ${QF::types} + +$declare ${QF::QActive} + +$declare ${QF::QMActive} + +$declare ${QF::QTimeEvt} + +$declare ${QF::QTicker} + +$declare ${QF::QF-base} + +$declare ${QF::QF-dyn} + +$declare ${QF-macros} + +#endif // QP_H_ + + + + #ifndef QP_PKG_H_ +#define QP_PKG_H_ + +$declare ${QF::QF-pkg} + +// Bitmasks are for the QTimeEvt::refCtr_ attribute (inherited from ::QEvt). +// In ::QTimeEvt this attribute is NOT used for reference counting. +#define QTE_IS_LINKED (1U << 7U) +#define QTE_WAS_DISARMED (1U << 6U) +#define QTE_TICK_RATE 0x0FU + +//! @private @memberof QEvt +static inline void QEvt_refCtr_inc_(QEvt const *me) { + ++((QEvt *)me)->refCtr_; } -else { /* no bytes available */ - *pNbytes = 0U; /* no bytes available right now */ - buf = (uint8_t *)0; /* no bytes available right now */ +//! @private @memberof QEvt +static inline void QEvt_refCtr_dec_(QEvt const *me) { + --((QEvt *)me)->refCtr_; } -return buf; - - - - /*! Set/clear the global Filter for a given QS record or a group -* of records -* @static @public @memberof QS_tx -* -* @details -* This function sets up the QS filter to enable record types specified -* in the `filter` parameter. The value #QS_ALL_RECORDS specifies to -* filter-in all records. This function should be called indirectly -* through the macro QS_GLB_FILTER() -* -* @param[in] filter the QS record-d or group to enable in the filter, -* if positive or disable, if negative. The record-id -* numbers must be in the range -127..127. -* @note -* Filtering based on the record-type is only the first layer of -* filtering. The second layer is based on the object-type. Both filter -* layers must be enabled for the QS record to be inserted in the -* QS buffer. -* -* @sa QS_locFilter_() -*/ - - - bool const isRemove = (filter < 0); -uint8_t const rec = isRemove ? (uint8_t)(-filter) : (uint8_t)filter; -switch (rec) { - case QS_ALL_RECORDS: { - uint8_t const tmp = (isRemove ? 0x00U : 0xFFU); - /* set all global filters (partially unrolled loop) */ - for (uint_fast8_t i = 0U; - i < Q_DIM(QS_priv_.glbFilter); - i += 4U) - { - QS_priv_.glbFilter[i ] = tmp; - QS_priv_.glbFilter[i + 1U] = tmp; - QS_priv_.glbFilter[i + 2U] = tmp; - QS_priv_.glbFilter[i + 3U] = tmp; - } - if (isRemove) { - /* leave the "not maskable" filters enabled, - * see qs.h, Miscellaneous QS records (not maskable) - */ - QS_priv_.glbFilter[0] = 0x01U; - QS_priv_.glbFilter[6] = 0x40U; - QS_priv_.glbFilter[7] = 0xFCU; - QS_priv_.glbFilter[8] = 0x7FU; - } - else { - /* never turn the last 3 records on (0x7D, 0x7E, 0x7F) */ - QS_priv_.glbFilter[15] = 0x1FU; - } - break; - } - case QS_SM_RECORDS: - if (isRemove) { - QS_priv_.glbFilter[0] &= (uint8_t)(~0xFEU & 0xFFU); - QS_priv_.glbFilter[1] &= (uint8_t)(~0x03U & 0xFFU); - QS_priv_.glbFilter[6] &= (uint8_t)(~0x80U & 0xFFU); - QS_priv_.glbFilter[7] &= (uint8_t)(~0x03U & 0xFFU); - } - else { - QS_priv_.glbFilter[0] |= 0xFEU; - QS_priv_.glbFilter[1] |= 0x03U; - QS_priv_.glbFilter[6] |= 0x80U; - QS_priv_.glbFilter[7] |= 0x03U; - } - break; - case QS_AO_RECORDS: - if (isRemove) { - QS_priv_.glbFilter[1] &= (uint8_t)(~0xFCU & 0xFFU); - QS_priv_.glbFilter[2] &= (uint8_t)(~0x07U & 0xFFU); - QS_priv_.glbFilter[5] &= (uint8_t)(~0x20U & 0xFFU); - } - else { - QS_priv_.glbFilter[1] |= 0xFCU; - QS_priv_.glbFilter[2] |= 0x07U; - QS_priv_.glbFilter[5] |= 0x20U; - } - break; - case QS_EQ_RECORDS: - if (isRemove) { - QS_priv_.glbFilter[2] &= (uint8_t)(~0x78U & 0xFFU); - QS_priv_.glbFilter[5] &= (uint8_t)(~0x40U & 0xFFU); - } - else { - QS_priv_.glbFilter[2] |= 0x78U; - QS_priv_.glbFilter[5] |= 0x40U; - } - break; - case QS_MP_RECORDS: - if (isRemove) { - QS_priv_.glbFilter[3] &= (uint8_t)(~0x03U & 0xFFU); - QS_priv_.glbFilter[5] &= (uint8_t)(~0x80U & 0xFFU); - } - else { - QS_priv_.glbFilter[3] |= 0x03U; - QS_priv_.glbFilter[5] |= 0x80U; - } - break; - case QS_QF_RECORDS: - if (isRemove) { - QS_priv_.glbFilter[2] &= (uint8_t)(~0x80U & 0xFFU); - QS_priv_.glbFilter[3] &= (uint8_t)(~0xFCU & 0xFFU); - QS_priv_.glbFilter[4] &= (uint8_t)(~0xC0U & 0xFFU); - QS_priv_.glbFilter[5] &= (uint8_t)(~0x1FU & 0xFFU); - } - else { - QS_priv_.glbFilter[2] |= 0x80U; - QS_priv_.glbFilter[3] |= 0xFCU; - QS_priv_.glbFilter[4] |= 0xC0U; - QS_priv_.glbFilter[5] |= 0x1FU; - } - break; - case QS_TE_RECORDS: - if (isRemove) { - QS_priv_.glbFilter[4] &= (uint8_t)(~0x3FU & 0xFFU); - } - else { - QS_priv_.glbFilter[4] |= 0x3FU; - } - break; - case QS_SC_RECORDS: - if (isRemove) { - QS_priv_.glbFilter[6] &= (uint8_t)(~0x3FU & 0xFFU); - } - else { - QS_priv_.glbFilter[6] |= 0x3FU; - } - break; - case QS_SEM_RECORDS: - if (isRemove) { - QS_priv_.glbFilter[8] &= (uint8_t)(~0x80U & 0xFFU); - QS_priv_.glbFilter[9] &= (uint8_t)(~0x07U & 0xFFU); - } - else { - QS_priv_.glbFilter[8] |= 0x80U; - QS_priv_.glbFilter[9] |= 0x07U; - } - break; - case QS_MTX_RECORDS: - if (isRemove) { - QS_priv_.glbFilter[9] &= (uint8_t)(~0xF8U & 0xFFU); - QS_priv_.glbFilter[10] &= (uint8_t)(~0x01U & 0xFFU); - } - else { - QS_priv_.glbFilter[9] |= 0xF8U; - QS_priv_.glbFilter[10] |= 0x01U; - } - break; - case QS_U0_RECORDS: - if (isRemove) { - QS_priv_.glbFilter[12] &= (uint8_t)(~0xF0U & 0xFFU); - QS_priv_.glbFilter[13] &= (uint8_t)(~0x01U & 0xFFU); - } - else { - QS_priv_.glbFilter[12] |= 0xF0U; - QS_priv_.glbFilter[13] |= 0x01U; - } - break; - case QS_U1_RECORDS: - if (isRemove) { - QS_priv_.glbFilter[13] &= (uint8_t)(~0x3EU & 0xFFU); - } - else { - QS_priv_.glbFilter[13] |= 0x3EU; - } - break; - case QS_U2_RECORDS: - if (isRemove) { - QS_priv_.glbFilter[13] &= (uint8_t)(~0xC0U & 0xFFU); - QS_priv_.glbFilter[14] &= (uint8_t)(~0x07U & 0xFFU); - } - else { - QS_priv_.glbFilter[13] |= 0xC0U; - QS_priv_.glbFilter[14] |= 0x07U; - } - break; - case QS_U3_RECORDS: - if (isRemove) { - QS_priv_.glbFilter[14] &= (uint8_t)(~0xF8U & 0xFFU); - } - else { - QS_priv_.glbFilter[14] |= 0xF8U; - } - break; - case QS_U4_RECORDS: - if (isRemove) { - QS_priv_.glbFilter[15] &= 0x1FU; - } - else { - QS_priv_.glbFilter[15] |= 0x1FU; - } - break; - case QS_UA_RECORDS: - if (isRemove) { - QS_priv_.glbFilter[12] &= (uint8_t)(~0xF0U & 0xFFU); - QS_priv_.glbFilter[13] = 0U; - QS_priv_.glbFilter[14] = 0U; - QS_priv_.glbFilter[15] &= (uint8_t)(~0x1FU & 0xFFU); - } - else { - QS_priv_.glbFilter[12] |= 0xF0U; - QS_priv_.glbFilter[13] |= 0xFFU; - QS_priv_.glbFilter[14] |= 0xFFU; - QS_priv_.glbFilter[15] |= 0x1FU; - } - break; - default: - /* QS rec number can't exceed 0x7D, so no need for escaping */ - Q_ASSERT_ID(210, rec < 0x7DU); - if (isRemove) { - QS_priv_.glbFilter[rec >> 3U] - &= (uint8_t)(~(1U << (rec & 7U)) & 0xFFU); - } - else { - QS_priv_.glbFilter[rec >> 3U] - |= (1U << (rec & 7U)); - /* never turn the last 3 records on (0x7D, 0x7E, 0x7F) */ - QS_priv_.glbFilter[15] &= 0x1FU; - } - break; -} - - - - /*! Set/clear the local Filter for a given object-id -* or a group of object-ids -* @static @public @memberof QS_tx -* -* @details -* This function sets up the local QS filter to enable or disable the -* given QS object-id or a group of object-ids @a filter. -* This function should be called indirectly through the macro -* QS_LOC_FILTER() -* -* @param[in] filter the QS object-id or group to enable in the filter, -* if positive or disable, if negative. The qs_id numbers -* must be in the range 1..127. -* @note -* Filtering based on the object-id (local filter) is the second layer -* of filtering. The first layer is based on the QS record-type (global -* filter). Both filter layers must be enabled for the QS record to be -* inserted into the QS buffer. -* -* @sa QS_glbFilter_() -*/ - - - bool const isRemove = (filter < 0); -uint8_t const qs_id = isRemove ? (uint8_t)(-filter) : (uint8_t)filter; -uint8_t const tmp = (isRemove ? 0x00U : 0xFFU); -uint_fast8_t i; -switch (qs_id) { - case QS_ALL_IDS: - /* set all local filters (partially unrolled loop) */ - for (i = 0U; i < Q_DIM(QS_priv_.locFilter); i += 4U) { - QS_priv_.locFilter[i ] = tmp; - QS_priv_.locFilter[i + 1U] = tmp; - QS_priv_.locFilter[i + 2U] = tmp; - QS_priv_.locFilter[i + 3U] = tmp; - } - break; - case QS_AO_IDS: - for (i = 0U; i < 8U; i += 4U) { - QS_priv_.locFilter[i ] = tmp; - QS_priv_.locFilter[i + 1U] = tmp; - QS_priv_.locFilter[i + 2U] = tmp; - QS_priv_.locFilter[i + 3U] = tmp; - } - break; - case QS_EP_IDS: - i = 8U; - QS_priv_.locFilter[i ] = tmp; - QS_priv_.locFilter[i + 1U] = tmp; - break; - case QS_AP_IDS: - i = 12U; - QS_priv_.locFilter[i ] = tmp; - QS_priv_.locFilter[i + 1U] = tmp; - QS_priv_.locFilter[i + 2U] = tmp; - QS_priv_.locFilter[i + 3U] = tmp; - break; - default: - if (qs_id < 0x7FU) { +#define QACTIVE_CAST_(ptr_) ((QActive *)(ptr_)) +#define Q_UINTPTR_CAST_(ptr_) ((uintptr_t)(ptr_)) + +#endif // QP_PKG_H_ + + + + #ifndef QEQUEUE_H_ +#define QEQUEUE_H_ + +#ifndef QF_EQUEUE_CTR_SIZE + #define QF_EQUEUE_CTR_SIZE 1U +#endif + +#if (QF_EQUEUE_CTR_SIZE == 1U) + typedef uint8_t QEQueueCtr; +#elif (QF_EQUEUE_CTR_SIZE == 2U) + typedef uint16_t QEQueueCtr; +#elif (QF_EQUEUE_CTR_SIZE == 4U) + typedef uint32_t QEQueueCtr; +#else + #error "QF_EQUEUE_CTR_SIZE defined incorrectly, expected 1U, 2U, or 4U" +#endif + +struct QEvt; // forward declaration + +$declare ${QF::QEQueue} + +#endif // QEQUEUE_H_ + + + + #ifndef QMPOOL_H_ +#define QMPOOL_H_ + +#ifndef QF_MPOOL_SIZ_SIZE + #define QF_MPOOL_SIZ_SIZE 2U +#endif +#ifndef QF_MPOOL_CTR_SIZE + #define QF_MPOOL_CTR_SIZE 2U +#endif + +#if (QF_MPOOL_SIZ_SIZE == 1U) + typedef uint8_t QMPoolSize; +#elif (QF_MPOOL_SIZ_SIZE == 2U) + typedef uint16_t QMPoolSize; +#elif (QF_MPOOL_SIZ_SIZE == 4U) + typedef uint32_t QMPoolSize; +#else + #error "QF_MPOOL_SIZ_SIZE defined incorrectly, expected 1U, 2U, or 4U" +#endif + +#if (QF_MPOOL_CTR_SIZE == 1U) + typedef uint8_t QMPoolCtr; +#elif (QF_MPOOL_CTR_SIZE == 2U) + typedef uint16_t QMPoolCtr; +#elif (QF_MPOOL_CTR_SIZE == 4U) + typedef uint32_t QMPoolCtr; +#else + #error "QF_MPOOL_CTR_SIZE defined incorrectly, expected 1U, 2U, or 4U" +#endif + +#define QF_MPOOL_EL(evType_) struct { \ + QFreeBlock sto_[((sizeof(evType_) - 1U) \ + / sizeof(QFreeBlock)) + 1U]; } + +$declare ${QF::QFreeBlock} + +$declare ${QF::QMPool} + +#endif // QMPOOL_H_ + + + + #ifndef QV_H_ +#define QV_H_ + +$declare ${QV::QV} + +$declare ${QV::QV-base} + +//============================================================================ +// interface used only for internal implementation, but not in applications +#ifdef QP_IMPL + +$declare ${QV-impl} + +$declare ${QF_EPOOL-impl} + +#endif // QP_IMPL + +#endif // QV_H_ + + + + #ifndef QK_H_ +#define QK_H_ + +$declare ${QK::QK} + +$declare ${QK::QSchedStatus} + +$declare ${QK::QK-base} + +//============================================================================ +// interface used only for internal implementation, but not in applications +#ifdef QP_IMPL + +$declare ${QK-impl} + +$declare ${QF_EPOOL-impl} + +#endif // QP_IMPL + +#endif // QK_H_ + + + + #ifndef QXK_H_ +#define QXK_H_ + +$declare ${QXK::QXK} + +$declare ${QXK::QSchedStatus} + +$declare ${QXK::QXTHREAD_NO_TIMEOUT} + +$declare ${QXK::QXK-base} + +$declare ${QXK::QXThread} + +$declare ${QXK::QXSemaphore} + +$declare ${QXK::QXMutex} + +$declare ${QXK-macros} + +//============================================================================ +// interface used only for internal implementation, but not in applications +#ifdef QP_IMPL + +$declare ${QXK-impl} + +$declare ${QF_EPOOL-impl} + +enum QXK_TimeoutSigs { + QXK_DELAY_SIG = 1, + QXK_TIMEOUT_SIG +}; + +#endif // QP_IMPL + +#endif // QXK_H_ + + + + #ifndef QS_H_ +#define QS_H_ + +#ifndef Q_SPY +#error "Q_SPY must be defined to include qs.h" +#endif + +//============================================================================ +//! @cond INTERNAL + +#ifndef QS_CTR_SIZE +#define QS_CTR_SIZE 2U +#endif + +#ifndef QS_TIME_SIZE +#define QS_TIME_SIZE 4U +#endif + +//! @endcond +//============================================================================ + +$declare ${QS::types} +$declare ${QS::filters} +$declare ${QS-macros} + +//============================================================================ +//! @cond INTERNAL + +typedef struct { + void const * locFilter_AP; //!< @deprecated + uint8_t * buf; + QSCtr end; + QSCtr volatile head; + QSCtr volatile tail; + QSCtr volatile used; + uint8_t volatile seq; + uint8_t volatile chksum; + uint8_t volatile critNest; + uint8_t flags; +} QS_Attr; + +extern QS_Attr QS_priv_; + +void QS_glbFilter_(int_fast16_t const filter); +void QS_locFilter_(int_fast16_t const filter); + +void QS_beginRec_(uint_fast8_t const rec); +void QS_endRec_(void); + +void QS_u8_raw_(uint8_t const d); +void QS_2u8_raw_( + uint8_t const d1, + uint8_t const d2); +void QS_u16_raw_(uint16_t const d); +void QS_u32_raw_(uint32_t const d); +void QS_u64_raw_(uint64_t const d); +void QS_obj_raw_(void const * const obj); +void QS_str_raw_(char const * const str); + +void QS_u8_fmt_( + uint8_t const format, + uint8_t const d); +void QS_u16_fmt_( + uint8_t const format, + uint16_t const d); +void QS_u32_fmt_( + uint8_t const format, + uint32_t const d); +void QS_u64_fmt_( + uint8_t const format, + uint64_t const d); +void QS_f32_fmt_( + uint8_t const format, + float32_t const f); +void QS_f64_fmt_( + uint8_t const format, + float64_t const d); +void QS_str_fmt_(char const * const str); +void QS_mem_fmt_( + uint8_t const * const blk, + uint8_t const size); + +void QS_sig_dict_pre_( + QSignal const sig, + void const * const obj, + char const * const name); +void QS_obj_dict_pre_( + void const * const obj, + char const * const name); +void QS_obj_arr_dict_pre_( + void const * const obj, + uint_fast16_t const idx, + char const * const name); +void QS_fun_dict_pre_( + QSpyFunPtr const fun, + char const * const name); +void QS_usr_dict_pre_( + enum_t const rec, + char const * const name); +void QS_enum_dict_pre_( + enum_t const value, + uint8_t const group, + char const * const name); + +void QS_assertion_pre_( + char const * const module, + int_t const id, + uint32_t const delay); + +void QS_target_info_pre_(uint8_t const isReset); + +//! @endcond +//============================================================================ + +$declare ${QS::QS-TX} + +//============================================================================ +//! @cond INTERNAL + +typedef struct { + void * currObj[8]; + uint8_t * buf; + QSCtr end; + QSCtr volatile head; + QSCtr volatile tail; +#ifdef Q_UTEST + bool inTestLoop; +#endif +} QS_RxAttr; + +//! @static @private @memberof QS +extern QS_RxAttr QS_rxPriv_; + +//! @endcond +//============================================================================ + +$declare ${QS::QS-RX} + +//============================================================================ +#ifdef Q_UTEST + +$declare ${QS::QUTest} + +#define QUTEST_ON_POST 124 + +//============================================================================ +//! @cond INTERNAL + +typedef struct { + struct QS_TProbe tpBuf[16]; + uint8_t tpNum; + QSTimeCtr testTime; + QPSet readySet; + QPSet readySet_dis; + uint_fast8_t intLock; +} QSTestAttr; + +extern QSTestAttr QS_tstPriv_; + +void QS_test_pause_(void); +uint32_t QS_getTestProbe_(QSpyFunPtr const api); + +//! @endcond +//============================================================================ + +// QP-stub for QUTest +// NOTE: The QP-stub is needed for unit testing QP applications, +// but might NOT be needed for testing QP itself. +#if (Q_UTEST != 0) + +$declare ${QS::QUTest-stub::QHsmDummy} +$declare ${QS::QUTest-stub::QActiveDummy} + +#endif // Q_UTEST != 0 + +#define QS_TEST_PROBE_DEF(fun_) \ + uint32_t const qs_tp_ = QS_getTestProbe_((void (*)(void))(fun_)); + +#define QS_TEST_PROBE(code_) \ + if (qs_tp_ != 0U) { code_ } + +#define QS_TEST_PROBE_ID(id_, code_) \ + if (qs_tp_ == (uint32_t)(id_)) { code_ } + +#define QS_TEST_PAUSE() (QS_test_pause_()) + +#else // Q_UTEST not defined + +// dummy definitions when not building for QUTEST +#define QS_TEST_PROBE_DEF(fun_) +#define QS_TEST_PROBE(code_) +#define QS_TEST_PROBE_ID(id_, code_) +#define QS_TEST_PAUSE() ((void)0) + +#endif // Q_UTEST + +#endif // QS_H_ + + + + #ifndef QS_DUMMY_H_ +#define QS_DUMMY_H_ + +#ifdef Q_SPY + #error "Q_SPY must NOT be defined to include qs_dummy.h" +#endif + +#ifdef Q_UTEST + #error "Q_UTEST must NOT be defined to include qs_dummy.h" +#endif + +#define QS_INIT(arg_) ((uint8_t)1U) +#define QS_EXIT() ((void)0) +#define QS_DUMP() ((void)0) +#define QS_GLB_FILTER(rec_) ((void)0) +#define QS_LOC_FILTER(qs_id_) ((void)0) + +#define QS_GET_BYTE(pByte_) ((uint16_t)0xFFFFU) +#define QS_GET_BLOCK(pSize_) ((uint8_t *)0) + +#define QS_BEGIN_ID(rec_, qs_id_) if (false) { +#define QS_END() } +#define QS_BEGIN_INCRIT(rec_, qs_id_) if (false) { +#define QS_END_INCRIT() } + +#define QS_I8(width_, data_) ((void)0) +#define QS_U8(width_, data_) ((void)0) +#define QS_I16(width_, data_) ((void)0) +#define QS_U16(width_, data_) ((void)0) +#define QS_I32(width_, data_) ((void)0) +#define QS_U32(width_, data_) ((void)0) +#define QS_F32(width_, data_) ((void)0) +#define QS_F64(width_, data_) ((void)0) +#define QS_I64(width_, data_) ((void)0) +#define QS_U64(width_, data_) ((void)0) +#define QS_ENUM(group_, value_) ((void)0) +#define QS_STR(str_) ((void)0) +#define QS_MEM(mem_, size_) ((void)0) +#define QS_SIG(sig_, obj_) ((void)0) +#define QS_OBJ(obj_) ((void)0) +#define QS_FUN(fun_) ((void)0) + +#define QS_SIG_DICTIONARY(sig_, obj_) ((void)0) +#define QS_OBJ_DICTIONARY(obj_) ((void)0) +#define QS_OBJ_ARR_DICTIONARY(obj_, idx_) ((void)0) +#define QS_FUN_DICTIONARY(fun_) ((void)0) +#define QS_USR_DICTIONARY(rec_) ((void)0) +#define QS_ENUM_DICTIONARY(value_, group_) ((void)0) +#define QS_ASSERTION(module_, loc_, delay_) ((void)0) +#define QS_FLUSH() ((void)0) + +#define QS_TEST_PROBE_DEF(fun_) +#define QS_TEST_PROBE(code_) +#define QS_TEST_PROBE_ID(id_, code_) +#define QS_TEST_PAUSE() ((void)0) + +#define QS_OUTPUT() ((void)0) +#define QS_RX_INPUT() ((void)0) +#define QS_ONLY(code_) ((void)0) + +//============================================================================ +// interface used only for internal implementation, but not in applications +#ifdef QP_IMPL + // predefined QS trace records + #define QS_BEGIN_PRE_(rec_, qs_id_) if (false) { + #define QS_END_PRE_() } + #define QS_U8_PRE_(data_) ((void)0) + #define QS_2U8_PRE_(data1_, data2_) ((void)0) + #define QS_U16_PRE_(data_) ((void)0) + #define QS_U32_PRE_(data_) ((void)0) + #define QS_TIME_PRE_() ((void)0) + #define QS_SIG_PRE_(sig_) ((void)0) + #define QS_EVS_PRE_(size_) ((void)0) + #define QS_OBJ_PRE_(obj_) ((void)0) + #define QS_FUN_PRE_(fun_) ((void)0) + #define QS_EQC_PRE_(ctr_) ((void)0) + #define QS_MPC_PRE_(ctr_) ((void)0) + #define QS_MPS_PRE_(size_) ((void)0) + #define QS_TEC_PRE_(ctr_) ((void)0) + + #define QS_CRIT_STAT + #define QS_CRIT_ENTRY() ((void)0) + #define QS_CRIT_EXIT() ((void)0) + + #define QS_MEM_SYS() ((void)0) + #define QS_MEM_APP() ((void)0) + + #define QS_TR_CRIT_ENTRY() ((void)0) + #define QS_TR_CRIT_EXIT() ((void)0) + #define QS_TR_ISR_ENTRY(isrnest_, prio_) ((void)0) + #define QS_TR_ISR_EXIT(isrnest_, prio_) ((void)0) +#endif // QP_IMPL + +#endif // QS_DUMMY_H_ + + + + #ifndef QS_PKG_H_ +#define QS_PKG_H_ + +//============================================================================ +//! @cond INTERNAL + +//! QS received record types (RX channel) +enum QSpyRxRecords { + QS_RX_INFO, //!< query Target info (ver, config, tstamp) + QS_RX_COMMAND, //!< execute a user-defined command in the Target + QS_RX_RESET, //!< reset the Target + QS_RX_TICK, //!< call system clock tick in the Target + QS_RX_PEEK, //!< peek Target memory + QS_RX_POKE, //!< poke Target memory + QS_RX_FILL, //!< fill Target memory + QS_RX_TEST_SETUP, //!< test setup + QS_RX_TEST_TEARDOWN, //!< test teardown + QS_RX_TEST_PROBE, //!< set a Test-Probe in the Target + QS_RX_GLB_FILTER, //!< set global filters in the Target + QS_RX_LOC_FILTER, //!< set local filters in the Target + QS_RX_AO_FILTER, //!< set local AO filter in the Target + QS_RX_CURR_OBJ, //!< set the "current-object" in the Target + QS_RX_TEST_CONTINUE, //!< continue a test after QS_TEST_PAUSE() + QS_RX_QUERY_CURR, //!< query the "current object" in the Target + QS_RX_EVENT //!< inject an event to the Target +}; + +//---------------------------------------------------------------------------- +#define QS_FRAME 0x7EU +#define QS_ESC 0x7DU +#define QS_ESC_XOR 0x20U +#define QS_GOOD_CHKSUM 0xFFU + +//---------------------------------------------------------------------------- +#define QS_BEGIN_PRE_(rec_, qs_id_) \ + if (QS_GLB_CHECK_(rec_) && QS_LOC_CHECK_(qs_id_)) { \ + QS_beginRec_((uint_fast8_t)(rec_)); +#define QS_END_PRE_() QS_endRec_(); } + +#define QS_U8_PRE_(data_) (QS_u8_raw_((uint8_t)(data_))) +#define QS_2U8_PRE_(data1_, data2_) \ + (QS_2u8_raw_((uint8_t)(data1_), (uint8_t)(data2_))) +#define QS_U16_PRE_(data_) (QS_u16_raw_((uint16_t)(data_))) +#define QS_U32_PRE_(data_) (QS_u32_raw_((uint32_t)(data_))) +#define QS_STR_PRE_(msg_) (QS_str_raw_((msg_))) +#define QS_OBJ_PRE_(obj_) (QS_obj_raw_(obj_)) + +#if (!defined Q_SIGNAL_SIZE || (Q_SIGNAL_SIZE == 1U)) + #define QS_SIG_PRE_(sig_) (QS_u8_raw_((uint8_t)sig_)) +#elif (Q_SIGNAL_SIZE == 2U) + #define QS_SIG_PRE_(sig_) (QS_u16_raw_((uint16_t)sig_)) +#elif (Q_SIGNAL_SIZE == 4U) + #define QS_SIG_PRE_(sig_) (QS_u32_raw_((uint32_t)sig_)) +#endif + +#if (!defined QS_FUN_PTR_SIZE || (QS_FUN_PTR_SIZE == 2U)) + #define QS_FUN_PRE_(fun_) (QS_u16_raw_((uint16_t)(fun_))) +#elif (QS_FUN_PTR_SIZE == 4U) + #define QS_FUN_PRE_(fun_) (QS_u32_raw_((uint32_t)(fun_))) +#elif (QS_FUN_PTR_SIZE == 8U) + #define QS_FUN_PRE_(fun_) (QS_u64_raw_((uint64_t)(fun_))) +#else + #define QS_FUN_PRE_(fun_) (QS_u32_raw_((uint32_t)(fun_))) +#endif + +//---------------------------------------------------------------------------- +#if (!defined QF_EQUEUE_CTR_SIZE || (QF_EQUEUE_CTR_SIZE == 1U)) + #define QS_EQC_PRE_(ctr_) QS_u8_raw_((uint8_t)(ctr_)) +#elif (QF_EQUEUE_CTR_SIZE == 2U) + #define QS_EQC_PRE_(ctr_) QS_u16_raw_((uint16_t)(ctr_)) +#elif (QF_EQUEUE_CTR_SIZE == 4U) + #define QS_EQC_PRE_(ctr_) QS_u32_raw_((uint32_t)(ctr_)) +#endif + +#if (!defined QF_EVENT_SIZ_SIZE || (QF_EVENT_SIZ_SIZE == 1U)) + #define QS_EVS_PRE_(size_) QS_u8_raw_((uint8_t)(size_)) +#elif (QF_EVENT_SIZ_SIZE == 2U) + #define QS_EVS_PRE_(size_) QS_u16_raw_((uint16_t)(size_)) +#elif (QF_EVENT_SIZ_SIZE == 4U) + #define QS_EVS_PRE_(size_) QS_u32_raw_((uint32_t)(size_)) +#endif + +#if (!defined QF_MPOOL_SIZ_SIZE || (QF_MPOOL_SIZ_SIZE == 1U)) + #define QS_MPS_PRE_(size_) QS_u8_raw_((uint8_t)(size_)) +#elif (QF_MPOOL_SIZ_SIZE == 2U) + #define QS_MPS_PRE_(size_) QS_u16_raw_((uint16_t)(size_)) +#elif (QF_MPOOL_SIZ_SIZE == 4U) + #define QS_MPS_PRE_(size_) QS_u32_raw_((uint32_t)(size_)) +#endif + +#if (!defined QF_MPOOL_CTR_SIZE || (QF_MPOOL_CTR_SIZE == 1U)) + #define QS_MPC_PRE_(ctr_) QS_u8_raw_((uint8_t)(ctr_)) +#elif (QF_MPOOL_CTR_SIZE == 2U) + #define QS_MPC_PRE_(ctr_) QS_u16_raw_((uint16_t)(ctr_)) +#elif (QF_MPOOL_CTR_SIZE == 4U) + #define QS_MPC_PRE_(ctr_) QS_u32_raw_((uint16_t)(ctr_)) +#endif + +#if (!defined QF_TIMEEVT_CTR_SIZE || (QF_TIMEEVT_CTR_SIZE == 1U)) + #define QS_TEC_PRE_(ctr_) QS_u8_raw_((uint8_t)(ctr_)) +#elif (QF_TIMEEVT_CTR_SIZE == 2U) + #define QS_TEC_PRE_(ctr_) QS_u16_raw_((uint16_t)(ctr_)) +#elif (QF_TIMEEVT_CTR_SIZE == 4U) + #define QS_TEC_PRE_(ctr_) QS_u32_raw_((uint32_t)(ctr_)) +#endif + +//---------------------------------------------------------------------------- +#define QS_INSERT_BYTE_(b_) \ + buf[head] = (b_); \ + ++head; \ + if (head == end) { \ + head = 0U; \ + } + +#define QS_INSERT_ESC_BYTE_(b_) \ + chksum = (uint8_t)(chksum + (b_)); \ + if (((b_) != QS_FRAME) && ((b_) != QS_ESC)) { \ + QS_INSERT_BYTE_(b_) \ + } \ + else { \ + QS_INSERT_BYTE_(QS_ESC) \ + QS_INSERT_BYTE_((uint8_t)((b_) ^ QS_ESC_XOR))\ + ++QS_priv_.used; \ + } + +//---------------------------------------------------------------------------- +#if (defined Q_UTEST) && (Q_UTEST != 0) +void QS_processTestEvts_(void); +#endif // Q_UTEST != 0 + +//! @endcond +//============================================================================ + +#endif // QS_PKG_H_ + + + + #ifndef QSTAMP_H_ +#define QSTAMP_H_ + +extern char const Q_BUILD_DATE[12]; +extern char const Q_BUILD_TIME[9]; + +#endif // QSTAMP_H_ + + + + #ifndef QPC_H_ +#define QPC_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +//============================================================================ +#include "qp_port.h" // QP port from the port directory +#include "qsafe.h" // QP Functional Safety (FuSa) Subsystem +#ifdef Q_SPY // software tracing enabled? + #include "qs_port.h" // QS/C port from the port directory +#else + #include "qs_dummy.h" // QS/C dummy (inactive) interface +#endif + +//============================================================================ +#ifndef QP_API_VERSION + +#define QP_API_VERSION 0 + +#endif // #ifndef QP_API_VERSION + +//============================================================================ +// QP API compatibility layer... + +#if (QP_API_VERSION < 730) + +//! @deprecated plain 'char' is no longer forbidden in MISRA-C:2023 +typedef char char_t; + +//! @deprecated assertion failure handler +//! Use Q_onError() instead. +#define Q_onAssert(module_, id_) Q_onError(module_, id_) + +//! @deprecated #Q_NASSERT preprocessor switch to disable QP assertions +#ifdef Q_NASSERT + + // #Q_UNSAFE now replaces the functionality of Q_NASSERT + #define Q_UNSAFE + + //! @deprecated general purpose assertion with user-specified ID + //! number that **always** evaluates the `expr_` expression. + #define Q_ALLEGE_ID(id_, expr_) ((void)(expr_)) + +#else // QP FuSa Subsystem enabled + + //! @deprecated general purpose assertion with user-specified ID + //! number that **always** evaluates the `expr_` expression. + //! @note + //! The use of this macro is no longer recommended. + #define Q_ALLEGE_ID(id_, expr_) if (!(expr_)) { \ + QF_CRIT_STAT \ + QF_CRIT_ENTRY(); \ + Q_onError(&Q_this_module_[0], (id_)); \ + QF_CRIT_EXIT(); \ + } else ((void)0) + +#endif + +//! @deprecated general purpose assertion without ID number +//! that **always** evaluates the `expr_` expression. +//! Instead of ID number, this macro is based on the standard +//! `__LINE__` macro. +//! +//! @note The use of this macro is no longer recommended. +#define Q_ALLEGE(expr_) Q_ALLEGE_ID(__LINE__, (expr_)) + +//! Static (compile-time) assertion. +//! @deprecated +//! Use Q_ASSERT_STATIC() or better yet `_Static_assert()` instead. +#define Q_ASSERT_COMPILE(expr_) Q_ASSERT_STATIC(expr_) + +//! @static @public @memberof QF +//! @deprecated +static inline void QF_psInit( + QSubscrList * const subscrSto, + enum_t const maxSignal) +{ + QActive_psInit(subscrSto, maxSignal); +} + +//! @deprecated instead use: QASM_INIT() +#define QHSM_INIT(me_, par_, qs_id_) QASM_INIT((me_), (par_), (qs_id_)) + +//! @deprecated instead use: QASM_DISPATCH() +#define QHSM_DISPATCH(me_, e_, qs_id_) QASM_DISPATCH((me_), (e_), (qs_id_)) + +//============================================================================ +#if (QP_API_VERSION < 691) + +//! @deprecated enable the QS global filter +#define QS_FILTER_ON(rec_) QS_GLB_FILTER((rec_)) + +//! @deprecated disable the QS global filter +#define QS_FILTER_OFF(rec_) QS_GLB_FILTER(-(rec_)) + +//! @deprecated enable the QS local filter for SM (state machine) object +#define QS_FILTER_SM_OBJ(obj_) ((void)0) + +//! @deprecated enable the QS local filter for AO (active objects) +#define QS_FILTER_AO_OBJ(obj_) ((void)0) + +//! @deprecated enable the QS local filter for MP (memory pool) object +#define QS_FILTER_MP_OBJ(obj_) ((void)0) + +//! @deprecated enable the QS local filter for EQ (event queue) object +#define QS_FILTER_EQ_OBJ(obj_) ((void)0) + +//! @deprecated enable the QS local filter for TE (time event) object +#define QS_FILTER_TE_OBJ(obj_) ((void)0) + +#ifdef Q_SPY + +//! @deprecated local Filter for a generic application object `obj_`. +#define QS_FILTER_AP_OBJ(obj_) (QS_filt_.loc_AP = (obj_)) + +//! @deprecated begin of a user QS record, instead use QS_BEGIN_ID() +#define QS_BEGIN(rec_, obj_) \ + if (((QS_filt_.glb[(uint_fast8_t)(rec_) >> 3U] \ + & (1U << ((uint_fast8_t)(rec_) & 7U))) != 0U) \ + && ((QS_priv_.locFilter_AP == (void *)0) \ + || (QS_priv_.locFilter_AP == (obj_)))) \ + { \ + QS_CRIT_STAT \ + QS_CRIT_ENTRY(); \ + QS_beginRec_((uint_fast8_t)(rec_)); \ + QS_TIME_PRE_(); { + +//! @deprecated Output formatted uint32_t to the QS record +#define QS_U32_HEX(width_, data_) \ + (QS_u32_fmt_((uint8_t)(((width_) << 4)) | QS_HEX_FMT, (data_))) + +#else + +#define QS_FILTER_AP_OBJ(obj_) ((void)0) +#define QS_BEGIN(rec_, obj_) if (false) { +#define QS_U32_HEX(width_, data_) ((void)0) + +#endif + +//============================================================================ +#if (QP_API_VERSION < 660) + +//! @deprecated casting to QXThreadHandler +//! instead use: the new signature of QXThreadHandler and don't cast +#define Q_XTHREAD_CAST(handler_) ((QXThreadHandler)(handler_)) + +//============================================================================ +#if (QP_API_VERSION < 580) + +//! @deprecated instead use: QASM_INIT() +#define QMSM_INIT(me_, par_, qs_id_) QASM_INIT((me_), (par_), (qs_id_)) + +//! @deprecated instead use: QASM_DISPATCH() +#define QMSM_DISPATCH(me_, e_, qs_id_) QASM_DISPATCH((me_), (e_), (qs_id_)) + +#endif // QP_API_VERSION < 580 +#endif // QP_API_VERSION < 660 +#endif // QP_API_VERSION < 691 +#endif // QP_API_VERSION < 700 + +#ifdef __cplusplus +} +#endif + +#endif // QPC_H_ + + + + + + + + + #define QP_IMPL // this is QP implementation +#include "qp_port.h" // QP port +#include "qp_pkg.h" // QP package-scope interface +#include "qsafe.h" // QP Functional Safety (FuSa) Subsystem +#ifdef Q_SPY // QS software tracing enabled? + #include "qs_port.h" // QS port + #include "qs_pkg.h" // QS facilities for pre-defined trace records +#else + #include "qs_dummy.h" // disable the QS software tracing +#endif // Q_SPY + +Q_DEFINE_THIS_MODULE("qep_hsm") + +$define ${QEP::QP_versionStr[8]} + +//============================================================================ +//! @cond INTERNAL + +$define ${QEP::QEvt::reserved_[4]} + +enum { + // maximum depth of state nesting in a HSM (including the top level), + // must be >= 3 + QHSM_MAX_NEST_DEPTH_ = 6 +}; + +// helper macro to handle reserved event in an QHsm +#define QHSM_RESERVED_EVT_(state_, sig_) \ + ((*(state_))(me, &QEvt_reserved_[(sig_)])) + +// helper macro to trace state entry +#define QS_STATE_ENTRY_(state_, qs_id_) \ + QS_CRIT_ENTRY(); \ + QS_MEM_SYS(); \ + QS_BEGIN_PRE_(QS_QEP_STATE_ENTRY, (qs_id_)) \ + QS_OBJ_PRE_(me); \ + QS_FUN_PRE_(state_); \ + QS_END_PRE_() \ + QS_MEM_APP(); \ + QS_CRIT_EXIT() + +// helper macro to trace state exit +#define QS_STATE_EXIT_(state_, qs_id_) \ + QS_CRIT_ENTRY(); \ + QS_MEM_SYS(); \ + QS_BEGIN_PRE_(QS_QEP_STATE_EXIT, (qs_id_)) \ + QS_OBJ_PRE_(me); \ + QS_FUN_PRE_(state_); \ + QS_END_PRE_() \ + QS_MEM_APP(); \ + QS_CRIT_EXIT() + +//! @endcond + +$define ${QEP::QHsm} + + + + #define QP_IMPL // this is QP implementation +#include "qp_port.h" // QP port +#include "qp_pkg.h" // QP package-scope interface +#include "qsafe.h" // QP Functional Safety (FuSa) Subsystem +#ifdef Q_SPY // QS software tracing enabled? + #include "qs_port.h" // QS port + #include "qs_pkg.h" // QS facilities for pre-defined trace records +#else + #include "qs_dummy.h" // disable the QS software tracing +#endif // Q_SPY + +//============================================================================ +//! @cond INTERNAL + +Q_DEFINE_THIS_MODULE("qep_msm") + +// top-state object for QMsm-style state machines +static struct QMState const l_msm_top_s = { + (struct QMState *)0, + Q_STATE_CAST(0), + Q_ACTION_CAST(0), + Q_ACTION_CAST(0), + Q_ACTION_CAST(0) +}; + +enum { + // maximum depth of entry levels in a MSM for tran. to history. + QMSM_MAX_ENTRY_DEPTH_ = 4 +}; + +//! @endcond +//============================================================================ + +$define ${QEP::QMsm} + + + + #define QP_IMPL // this is QP implementation +#include "qp_port.h" // QP port +#include "qp_pkg.h" // QP package-scope interface +#include "qsafe.h" // QP Functional Safety (FuSa) Subsystem +#ifdef Q_SPY // QS software tracing enabled? + #include "qs_port.h" // QS port + #include "qs_pkg.h" // QS facilities for pre-defined trace records +#else + #include "qs_dummy.h" // disable the QS software tracing +#endif // Q_SPY + +//Q_DEFINE_THIS_MODULE("qf_act") + +$define ${QF::QActive::registry_[QF_MAX_ACTIVE + 1U]} + +$define ${QF::QF-pkg} + +$define ${QF::types::QF_LOG2} + + + + #define QP_IMPL // this is QP implementation +#include "qp_port.h" // QP port +#include "qp_pkg.h" // QP package-scope interface +#include "qsafe.h" // QP Functional Safety (FuSa) Subsystem +#ifdef Q_SPY // QS software tracing enabled? + #include "qs_port.h" // QS port + #include "qs_pkg.h" // QS facilities for pre-defined trace records +#else + #include "qs_dummy.h" // disable the QS software tracing +#endif // Q_SPY + +Q_DEFINE_THIS_MODULE("qf_actq") + +//============================================================================ +$define ${QF::QActive::post_} +$define ${QF::QActive::postLIFO_} +$define ${QF::QActive::get_} + +$define ${QF::QF-base::getQueueMin} +$define ${QF::QTicker} + + + + #define QP_IMPL // this is QP implementation +#include "qp_port.h" // QP port +#include "qp_pkg.h" // QP package-scope interface +#include "qsafe.h" // QP Functional Safety (FuSa) Subsystem +#ifdef Q_SPY // QS software tracing enabled? + #include "qs_port.h" // QS port + #include "qs_pkg.h" // QS facilities for pre-defined trace records +#else + #include "qs_dummy.h" // disable the QS software tracing +#endif // Q_SPY + +Q_DEFINE_THIS_MODULE("qf_defer") + +$define ${QF::QActive::defer} +$define ${QF::QActive::recall} +$define ${QF::QActive::flushDeferred} + + + + #define QP_IMPL // this is QP implementation +#include "qp_port.h" // QP port +#include "qp_pkg.h" // QP package-scope interface +#include "qsafe.h" // QP Functional Safety (FuSa) Subsystem +#ifdef Q_SPY // QS software tracing enabled? + #include "qs_port.h" // QS port + #include "qs_pkg.h" // QS facilities for pre-defined trace records +#else + #include "qs_dummy.h" // disable the QS software tracing +#endif // Q_SPY + +#if (QF_MAX_EPOOL > 0U) // mutable events configured? + +Q_DEFINE_THIS_MODULE("qf_dyn") + +$define ${QF::QF-dyn} + +#endif // (QF_MAX_EPOOL > 0U) mutable events configured + + + + #define QP_IMPL // this is QP implementation +#include "qp_port.h" // QP port +#include "qp_pkg.h" // QP package-scope interface +#include "qsafe.h" // QP Functional Safety (FuSa) Subsystem +#ifdef Q_SPY // QS software tracing enabled? + #include "qs_port.h" // QS port + #include "qs_pkg.h" // QS facilities for pre-defined trace records +#else + #include "qs_dummy.h" // disable the QS software tracing +#endif // Q_SPY + +Q_DEFINE_THIS_MODULE("qf_mem") + +$define ${QF::QMPool} + + + + #define QP_IMPL // this is QP implementation +#include "qp_port.h" // QP port +#include "qp_pkg.h" // QP package-scope interface +#include "qsafe.h" // QP Functional Safety (FuSa) Subsystem +#ifdef Q_SPY // QS software tracing enabled? + #include "qs_port.h" // QS port + #include "qs_pkg.h" // QS facilities for pre-defined trace records +#else + #include "qs_dummy.h" // disable the QS software tracing +#endif // Q_SPY + +Q_DEFINE_THIS_MODULE("qf_qact") + +$define ${QF::QActive::ctor} + +$define ${QF::QActive::register_} + +$define ${QF::QActive::unregister_} + + + + #define QP_IMPL // this is QP implementation +#include "qp_port.h" // QP port +#include "qp_pkg.h" // QP package-scope interface +#include "qsafe.h" // QP Functional Safety (FuSa) Subsystem +#ifdef Q_SPY // QS software tracing enabled? + #include "qs_port.h" // QS port + #include "qs_pkg.h" // QS facilities for pre-defined trace records +#else + #include "qs_dummy.h" // disable the QS software tracing +#endif // Q_SPY + +//Q_DEFINE_THIS_MODULE("qf_qmact") + +$define ${QF::QMActive} + + + + #define QP_IMPL // this is QP implementation +#include "qp_port.h" // QP port +#include "qp_pkg.h" // QP package-scope interface +#include "qsafe.h" // QP Functional Safety (FuSa) Subsystem +#ifdef Q_SPY // QS software tracing enabled? + #include "qs_port.h" // QS port + #include "qs_pkg.h" // QS facilities for pre-defined trace records +#else + #include "qs_dummy.h" // disable the QS software tracing +#endif // Q_SPY + +Q_DEFINE_THIS_MODULE("qf_qeq") + +$define ${QF::QEQueue} + + + + #define QP_IMPL // this is QP implementation +#include "qp_port.h" // QP port +#include "qp_pkg.h" // QP package-scope interface +#include "qsafe.h" // QP Functional Safety (FuSa) Subsystem +#ifdef Q_SPY // QS software tracing enabled? + #include "qs_port.h" // QS port + #include "qs_pkg.h" // QS facilities for pre-defined trace records +#else + #include "qs_dummy.h" // disable the QS software tracing +#endif // Q_SPY + +Q_DEFINE_THIS_MODULE("qf_ps") + +$define ${QF::QActive::subscrList_} + +$define ${QF::QActive::maxPubSignal_} + +$define ${QF::QActive::psInit} + +$define ${QF::QActive::publish_} + +$define ${QF::QActive::subscribe} + +$define ${QF::QActive::unsubscribe} + +$define ${QF::QActive::unsubscribeAll} + + + + #define QP_IMPL // this is QP implementation +#include "qp_port.h" // QP port +#include "qp_pkg.h" // QP package-scope interface +#include "qsafe.h" // QP Functional Safety (FuSa) Subsystem +#ifdef Q_SPY // QS software tracing enabled? + #include "qs_port.h" // QS port + #include "qs_pkg.h" // QS facilities for pre-defined trace records +#else + #include "qs_dummy.h" // disable the QS software tracing +#endif // Q_SPY + +Q_DEFINE_THIS_MODULE("qf_time") + +$define ${QF::QTimeEvt} + + + + + + + #define QP_IMPL // this is QP implementation +#include "qp_port.h" // QP port +#include "qp_pkg.h" // QP package-scope internal interface +#include "qsafe.h" // QP Functional Safety (FuSa) Subsystem +#ifdef Q_SPY // QS software tracing enabled? + #include "qs_port.h" // QS port + #include "qs_pkg.h" // QS facilities for pre-defined trace records +#else + #include "qs_dummy.h" // disable the QS software tracing +#endif // Q_SPY + +// protection against including this source file in a wrong project +#ifndef QV_H_ + #error "Source file included in a project NOT based on the QV kernel" +#endif // QV_H_ + +Q_DEFINE_THIS_MODULE("qv") + +$define ${QV::QV-base} + +$define ${QV::QF-cust} + +$define ${QV::QActive} + + + + + + + #define QP_IMPL // this is QP implementation +#include "qp_port.h" // QP port +#include "qp_pkg.h" // QP package-scope internal interface +#include "qsafe.h" // QP Functional Safety (FuSa) Subsystem +#ifdef Q_SPY // QS software tracing enabled? + #include "qs_port.h" // QS port + #include "qs_pkg.h" // QS facilities for pre-defined trace records +#else + #include "qs_dummy.h" // disable the QS software tracing +#endif // Q_SPY + +// protection against including this source file in a wrong project +#ifndef QK_H_ + #error "Source file included in a project NOT based on the QK kernel" +#endif // QK_H_ + +Q_DEFINE_THIS_MODULE("qk") + +$define ${QK::QK-base} + +$define ${QK::QF-cust} + +$define ${QK::QActive} + + + + + + + #define QP_IMPL // this is QP implementation +#include "qp_port.h" // QP port +#include "qp_pkg.h" // QP package-scope interface +#include "qsafe.h" // QP Functional Safety (FuSa) Subsystem +#ifdef Q_SPY // QS software tracing enabled? + #include "qs_port.h" // QS port + #include "qs_pkg.h" // QS facilities for pre-defined trace records +#else + #include "qs_dummy.h" // disable the QS software tracing +#endif // Q_SPY + +// protection against including this source file in a wrong project +#ifndef QXK_H_ + #error "Source file included in a project NOT based on the QXK kernel" +#endif // QXK_H_ + +Q_DEFINE_THIS_MODULE("qxk") + +$define ${QXK::QXK-base} + +$define ${QXK::QF-cust} + +$define ${QXK::QActive} + + + + #define QP_IMPL // this is QP implementation +#include "qp_port.h" // QP port +#include "qp_pkg.h" // QP package-scope interface +#include "qsafe.h" // QP Functional Safety (FuSa) Subsystem +#ifdef Q_SPY // QS software tracing enabled? + #include "qs_port.h" // QS port + #include "qs_pkg.h" // QS facilities for pre-defined trace records +#else + #include "qs_dummy.h" // disable the QS software tracing +#endif // Q_SPY + +// protection against including this source file in a wrong project +#ifndef QXK_H_ + #error "Source file included in a project NOT based on the QXK kernel" +#endif // QXK_H_ + +Q_DEFINE_THIS_MODULE("qxk_mutex") + +$define ${QXK::QXMutex} + + + + #define QP_IMPL // this is QP implementation +#include "qp_port.h" // QP port +#include "qp_pkg.h" // QP package-scope interface +#include "qsafe.h" // QP Functional Safety (FuSa) Subsystem +#ifdef Q_SPY // QS software tracing enabled? + #include "qs_port.h" // QS port + #include "qs_pkg.h" // QS facilities for pre-defined trace records +#else + #include "qs_dummy.h" // disable the QS software tracing +#endif // Q_SPY + +// protection against including this source file in a wrong project +#ifndef QXK_H_ + #error "Source file included in a project NOT based on the QXK kernel" +#endif // QXK_H_ + +Q_DEFINE_THIS_MODULE("qxk_sema") + +$define ${QXK::QXSemaphore} + + + + #define QP_IMPL // this is QP implementation +#include "qp_port.h" // QP port +#include "qp_pkg.h" // QP package-scope interface +#include "qsafe.h" // QP Functional Safety (FuSa) Subsystem +#ifdef Q_SPY // QS software tracing enabled? + #include "qs_port.h" // QS port + #include "qs_pkg.h" // QS facilities for pre-defined trace records +#else + #include "qs_dummy.h" // disable the QS software tracing +#endif // Q_SPY + +// protection against including this source file in a wrong project +#ifndef QXK_H_ + #error "Source file included in a project NOT based on the QXK kernel" +#endif // QXK_H_ + +Q_DEFINE_THIS_MODULE("qxk_xthr") + +$define ${QXK::QXThread} + + + + + + + #define QP_IMPL // this is QP implementation +#include "qs_port.h" // QS port +#include "qs_pkg.h" // QS package-scope interface +#include "qstamp.h" // QP time-stamp +#include "qsafe.h" // QP Functional Safety (FuSa) Subsystem + +Q_DEFINE_THIS_MODULE("qs") + +// ensure that the predefined records don't overlap the +// user records (application-specific). +Q_ASSERT_STATIC((enum_t)QS_PRE_MAX <= (enum_t)QS_USER); + +$define ${QS::QS-TX} + +#ifndef QF_MEM_ISOLATE +$define ${QS::filters} +#endif + +//============================================================================ +//! @cond INTERNAL + +//! @static @private @memberof QS +QS_Attr QS_priv_; + +//............................................................................ +void QS_glbFilter_(int_fast16_t const filter) { + bool const isRemove = (filter < 0); + uint8_t const rec = isRemove ? (uint8_t)(-filter) : (uint8_t)filter; + switch (rec) { + case (uint8_t)QS_ALL_RECORDS: { + uint8_t const tmp = (isRemove ? 0x00U : 0xFFU); + + // set all global filters (partially unrolled loop) + for (uint_fast8_t i = 0U; + i < Q_DIM(QS_filt_.glb); + i += 4U) + { + QS_filt_.glb[i ] = tmp; + QS_filt_.glb[i + 1U] = tmp; + QS_filt_.glb[i + 2U] = tmp; + QS_filt_.glb[i + 3U] = tmp; + } if (isRemove) { - QS_priv_.locFilter[qs_id >> 3U] + // leave the "not maskable" filters enabled, + // see qs.h, Miscellaneous QS records (not maskable) + QS_filt_.glb[0] = 0x01U; + QS_filt_.glb[6] = 0x40U; + QS_filt_.glb[7] = 0xFCU; + QS_filt_.glb[8] = 0x7FU; + } + else { + // never turn the last 3 records on (0x7D, 0x7E, 0x7F) + QS_filt_.glb[15] = 0x1FU; + } + break; + } + case (uint8_t)QS_SM_RECORDS: + if (isRemove) { + QS_filt_.glb[0] &= (uint8_t)(~0xFEU & 0xFFU); + QS_filt_.glb[1] &= (uint8_t)(~0x03U & 0xFFU); + QS_filt_.glb[6] &= (uint8_t)(~0x80U & 0xFFU); + QS_filt_.glb[7] &= (uint8_t)(~0x03U & 0xFFU); + } + else { + QS_filt_.glb[0] |= 0xFEU; + QS_filt_.glb[1] |= 0x03U; + QS_filt_.glb[6] |= 0x80U; + QS_filt_.glb[7] |= 0x03U; + } + break; + case (uint8_t)QS_AO_RECORDS: + if (isRemove) { + QS_filt_.glb[1] &= (uint8_t)(~0xFCU & 0xFFU); + QS_filt_.glb[2] &= (uint8_t)(~0x07U & 0xFFU); + QS_filt_.glb[5] &= (uint8_t)(~0x20U & 0xFFU); + } + else { + QS_filt_.glb[1] |= 0xFCU; + QS_filt_.glb[2] |= 0x07U; + QS_filt_.glb[5] |= 0x20U; + } + break; + case (uint8_t)QS_EQ_RECORDS: + if (isRemove) { + QS_filt_.glb[2] &= (uint8_t)(~0x78U & 0xFFU); + QS_filt_.glb[5] &= (uint8_t)(~0x40U & 0xFFU); + } + else { + QS_filt_.glb[2] |= 0x78U; + QS_filt_.glb[5] |= 0x40U; + } + break; + case (uint8_t)QS_MP_RECORDS: + if (isRemove) { + QS_filt_.glb[3] &= (uint8_t)(~0x03U & 0xFFU); + QS_filt_.glb[5] &= (uint8_t)(~0x80U & 0xFFU); + } + else { + QS_filt_.glb[3] |= 0x03U; + QS_filt_.glb[5] |= 0x80U; + } + break; + case (uint8_t)QS_QF_RECORDS: + if (isRemove) { + QS_filt_.glb[2] &= (uint8_t)(~0x80U & 0xFFU); + QS_filt_.glb[3] &= (uint8_t)(~0xFCU & 0xFFU); + QS_filt_.glb[4] &= (uint8_t)(~0xC0U & 0xFFU); + QS_filt_.glb[5] &= (uint8_t)(~0x1FU & 0xFFU); + } + else { + QS_filt_.glb[2] |= 0x80U; + QS_filt_.glb[3] |= 0xFCU; + QS_filt_.glb[4] |= 0xC0U; + QS_filt_.glb[5] |= 0x1FU; + } + break; + case (uint8_t)QS_TE_RECORDS: + if (isRemove) { + QS_filt_.glb[4] &= (uint8_t)(~0x3FU & 0xFFU); + } + else { + QS_filt_.glb[4] |= 0x3FU; + } + break; + case (uint8_t)QS_SC_RECORDS: + if (isRemove) { + QS_filt_.glb[6] &= (uint8_t)(~0x3FU & 0xFFU); + } + else { + QS_filt_.glb[6] |= 0x3FU; + } + break; + case (uint8_t)QS_SEM_RECORDS: + if (isRemove) { + QS_filt_.glb[8] &= (uint8_t)(~0x80U & 0xFFU); + QS_filt_.glb[9] &= (uint8_t)(~0x07U & 0xFFU); + } + else { + QS_filt_.glb[8] |= 0x80U; + QS_filt_.glb[9] |= 0x07U; + } + break; + case (uint8_t)QS_MTX_RECORDS: + if (isRemove) { + QS_filt_.glb[9] &= (uint8_t)(~0xF8U & 0xFFU); + QS_filt_.glb[10] &= (uint8_t)(~0x01U & 0xFFU); + } + else { + QS_filt_.glb[9] |= 0xF8U; + QS_filt_.glb[10] |= 0x01U; + } + break; + case (uint8_t)QS_U0_RECORDS: + if (isRemove) { + QS_filt_.glb[12] &= (uint8_t)(~0xF0U & 0xFFU); + QS_filt_.glb[13] &= (uint8_t)(~0x01U & 0xFFU); + } + else { + QS_filt_.glb[12] |= 0xF0U; + QS_filt_.glb[13] |= 0x01U; + } + break; + case (uint8_t)QS_U1_RECORDS: + if (isRemove) { + QS_filt_.glb[13] &= (uint8_t)(~0x3EU & 0xFFU); + } + else { + QS_filt_.glb[13] |= 0x3EU; + } + break; + case (uint8_t)QS_U2_RECORDS: + if (isRemove) { + QS_filt_.glb[13] &= (uint8_t)(~0xC0U & 0xFFU); + QS_filt_.glb[14] &= (uint8_t)(~0x07U & 0xFFU); + } + else { + QS_filt_.glb[13] |= 0xC0U; + QS_filt_.glb[14] |= 0x07U; + } + break; + case (uint8_t)QS_U3_RECORDS: + if (isRemove) { + QS_filt_.glb[14] &= (uint8_t)(~0xF8U & 0xFFU); + } + else { + QS_filt_.glb[14] |= 0xF8U; + } + break; + case (uint8_t)QS_U4_RECORDS: + if (isRemove) { + QS_filt_.glb[15] &= 0x1FU; + } + else { + QS_filt_.glb[15] |= 0x1FU; + } + break; + case (uint8_t)QS_UA_RECORDS: + if (isRemove) { + QS_filt_.glb[12] &= (uint8_t)(~0xF0U & 0xFFU); + QS_filt_.glb[13] = 0U; + QS_filt_.glb[14] = 0U; + QS_filt_.glb[15] &= (uint8_t)(~0x1FU & 0xFFU); + } + else { + QS_filt_.glb[12] |= 0xF0U; + QS_filt_.glb[13] |= 0xFFU; + QS_filt_.glb[14] |= 0xFFU; + QS_filt_.glb[15] |= 0x1FU; + } + break; + default: { + QS_CRIT_STAT + QS_CRIT_ENTRY(); + // QS rec number must be below 0x7D, so no need for escaping + Q_ASSERT_INCRIT(210, rec < 0x7DU); + QS_CRIT_EXIT(); + + if (isRemove) { + QS_filt_.glb[rec >> 3U] + &= (uint8_t)(~(1U << (rec & 7U)) & 0xFFU); + } + else { + QS_filt_.glb[rec >> 3U] + |= (1U << (rec & 7U)); + // never turn the last 3 records on (0x7D, 0x7E, 0x7F) + QS_filt_.glb[15] &= 0x1FU; + } + break; + } + } +} + +//............................................................................ +void QS_locFilter_(int_fast16_t const filter) { + bool const isRemove = (filter < 0); + uint8_t const qs_id = isRemove ? (uint8_t)(-filter) : (uint8_t)filter; + uint8_t const tmp = (isRemove ? 0x00U : 0xFFU); + uint_fast8_t i; + switch (qs_id) { + case (uint8_t)QS_ALL_IDS: + // set all local filters (partially unrolled loop) + for (i = 0U; i < Q_DIM(QS_filt_.loc); i += 4U) { + QS_filt_.loc[i ] = tmp; + QS_filt_.loc[i + 1U] = tmp; + QS_filt_.loc[i + 2U] = tmp; + QS_filt_.loc[i + 3U] = tmp; + } + break; + case (uint8_t)QS_AO_IDS: + for (i = 0U; i < 8U; i += 4U) { + QS_filt_.loc[i ] = tmp; + QS_filt_.loc[i + 1U] = tmp; + QS_filt_.loc[i + 2U] = tmp; + QS_filt_.loc[i + 3U] = tmp; + } + break; + case (uint8_t)QS_EP_IDS: + i = 8U; + QS_filt_.loc[i ] = tmp; + QS_filt_.loc[i + 1U] = tmp; + break; + case (uint8_t)QS_AP_IDS: + i = 12U; + QS_filt_.loc[i ] = tmp; + QS_filt_.loc[i + 1U] = tmp; + QS_filt_.loc[i + 2U] = tmp; + QS_filt_.loc[i + 3U] = tmp; + break; + default: { + QS_CRIT_STAT + QS_CRIT_ENTRY(); + // qs_id must be in range + Q_ASSERT_INCRIT(310, qs_id < 0x7FU); + QS_CRIT_EXIT(); + if (isRemove) { + QS_filt_.loc[qs_id >> 3U] &= (uint8_t)(~(1U << (qs_id & 7U)) & 0xFFU); } else { - QS_priv_.locFilter[qs_id >> 3U] + QS_filt_.loc[qs_id >> 3U] |= (1U << (qs_id & 7U)); } + break; } - else { - Q_ERROR_ID(310); /* incorrect qs_id */ - } - break; -} -QS_priv_.locFilter[0] |= 0x01U; /* leave QS_ID == 0 always on */ - - - - /*! Perform the QS-TX output (implemented in some QS ports) -* @static @public @memberof QS_tx -*/ - - - - /*! Mark the begin of a QS record `rec` -* @static @private @memberof QS_tx -* -* @details -* This function must be called at the beginning of each QS record. -* This function should be called indirectly through the macro QS_BEGIN_ID(), -* or QS_BEGIN_NOCRIT(), depending if it's called in a normal code or from -* a critical section. -*/ - - - - uint8_t const b = (uint8_t)(QS_priv_.seq + 1U); -uint8_t chksum = 0U; /* reset the checksum */ -uint8_t * const buf = QS_priv_.buf; /* put in a temporary (register) */ -QSCtr head = QS_priv_.head; /* put in a temporary (register) */ -QSCtr const end = QS_priv_.end; /* put in a temporary (register) */ - -QS_priv_.seq = b; /* store the incremented sequence num */ -QS_priv_.used += 2U; /* 2 bytes about to be added */ - -QS_INSERT_ESC_BYTE_(b) - -chksum = (uint8_t)(chksum + rec); /* update checksum */ -QS_INSERT_BYTE_((uint8_t)rec) /* rec byte does not need escaping */ - -QS_priv_.head = head; /* save the head */ -QS_priv_.chksum = chksum; /* save the checksum */ - - - - /*! Mark the end of a QS record `rec` -* @static @private @memberof QS_tx -* -* @details -* This function must be called at the end of each QS record. -* This function should be called indirectly through the macro QS_END(), -* or QS_END_NOCRIT(), depending if it's called in a normal code or from -* a critical section. -*/ - uint8_t * const buf = QS_priv_.buf; /* put in a temporary (register) */ -QSCtr head = QS_priv_.head; -QSCtr const end = QS_priv_.end; -uint8_t b = QS_priv_.chksum; -b ^= 0xFFU; /* invert the bits in the checksum */ - -QS_priv_.used += 2U; /* 2 bytes about to be added */ - -if ((b != QS_FRAME) && (b != QS_ESC)) { - QS_INSERT_BYTE_(b) -} -else { - QS_INSERT_BYTE_(QS_ESC) - QS_INSERT_BYTE_(b ^ QS_ESC_XOR) - ++QS_priv_.used; /* account for the ESC byte */ + } + QS_filt_.loc[0] |= 0x01U; // leave QS_ID == 0 always on } -QS_INSERT_BYTE_(QS_FRAME) /* do not escape this QS_FRAME */ +//............................................................................ +void QS_beginRec_(uint_fast8_t const rec) { + uint8_t const b = (uint8_t)(QS_priv_.seq + 1U); + uint8_t chksum = 0U; // reset the checksum + uint8_t * const buf = QS_priv_.buf; // put in a temporary (register) + QSCtr head = QS_priv_.head; // put in a temporary (register) + QSCtr const end = QS_priv_.end; // put in a temporary (register) -QS_priv_.head = head; /* save the head */ + QS_priv_.seq = b; // store the incremented sequence num + QS_priv_.used += 2U; // 2 bytes about to be added -/* overrun over the old data? */ -if (QS_priv_.used > end) { - QS_priv_.used = end; /* the whole buffer is used */ - QS_priv_.tail = head; /* shift the tail to the old data */ -} - - - - /*! output uint8_t data element without format information -* @static @private @memberof QS_tx -*/ - - - uint8_t chksum = QS_priv_.chksum; /* put in a temporary (register) */ -uint8_t * const buf = QS_priv_.buf; /* put in a temporary (register) */ -QSCtr head = QS_priv_.head; /* put in a temporary (register) */ -QSCtr const end = QS_priv_.end; /* put in a temporary (register) */ + QS_INSERT_ESC_BYTE_(b) -QS_priv_.used += 1U; /* 1 byte about to be added */ -QS_INSERT_ESC_BYTE_(d) + chksum = (uint8_t)(chksum + rec); // update checksum + QS_INSERT_BYTE_((uint8_t)rec) // rec byte does not need escaping -QS_priv_.head = head; /* save the head */ -QS_priv_.chksum = chksum; /* save the checksum */ - - - - /*! output two uint8_t data elements without format information -* @static @private @memberof QS_tx -*/ - - - - - uint8_t chksum = QS_priv_.chksum; /* put in a temporary (register) */ -uint8_t * const buf = QS_priv_.buf; /* put in a temporary (register) */ -QSCtr head = QS_priv_.head; /* put in a temporary (register) */ -QSCtr const end = QS_priv_.end; /* put in a temporary (register) */ - -QS_priv_.used += 2U; /* 2 bytes are about to be added */ -QS_INSERT_ESC_BYTE_(d1) -QS_INSERT_ESC_BYTE_(d2) - -QS_priv_.head = head; /* save the head */ -QS_priv_.chksum = chksum; /* save the checksum */ - - - - /*! output uint16_t data element without format information -* @static @private @memberof QS_tx -*/ - - - uint8_t chksum = QS_priv_.chksum; /* put in a temporary (register) */ -uint8_t * const buf = QS_priv_.buf; /* put in a temporary (register) */ -QSCtr head = QS_priv_.head; /* put in a temporary (register) */ -QSCtr const end = QS_priv_.end; /* put in a temporary (register) */ -uint16_t x = d; - -QS_priv_.used += 2U; /* 2 bytes are about to be added */ - -QS_INSERT_ESC_BYTE_((uint8_t)x) -x >>= 8U; -QS_INSERT_ESC_BYTE_((uint8_t)x) - -QS_priv_.head = head; /* save the head */ -QS_priv_.chksum = chksum; /* save the checksum */ - - - - /*! output uint32_t data element without format information -* @static @private @memberof QS_tx -*/ - - - uint8_t chksum = QS_priv_.chksum; /* put in a temporary (register) */ -uint8_t * const buf = QS_priv_.buf; /* put in a temporary (register) */ -QSCtr head = QS_priv_.head; /* put in a temporary (register) */ -QSCtr const end = QS_priv_.end; /* put in a temporary (register) */ -uint32_t x = d; - -QS_priv_.used += 4U; /* 4 bytes are about to be added */ -for (uint_fast8_t i = 4U; i != 0U; --i) { - QS_INSERT_ESC_BYTE_((uint8_t)x) - x >>= 8U; + QS_priv_.head = head; // save the head + QS_priv_.chksum = chksum; // save the checksum } -QS_priv_.head = head; /* save the head */ -QS_priv_.chksum = chksum; /* save the checksum */ - - - - /*! Output obj pointer data element without format information -* @static @private @memberof QS_tx -* -* @note This function is only to be used through macros, never in the -* client code directly. -*/ - - - - #if (QS_OBJ_PTR_SIZE == 1U) - QS_u8_raw_((uint8_t)obj); -#elif (QS_OBJ_PTR_SIZE == 2U) - QS_u16_raw_((uint16_t)obj); -#elif (QS_OBJ_PTR_SIZE == 4U) - QS_u32_raw_((uint32_t)obj); -#elif (QS_OBJ_PTR_SIZE == 8U) - QS_u64_raw_((uint64_t)obj); -#else - QS_u32_raw_((uint32_t)obj); -#endif - - - - /*! Output raw zero-terminated string element (without format information) -* @static @private @memberof QS_tx -* -* @note This function is only to be used through macros, never in the -* client code directly. -*/ - - - uint8_t chksum = QS_priv_.chksum; /* put in a temporary (register) */ -uint8_t * const buf = QS_priv_.buf; /* put in a temporary (register) */ -QSCtr head = QS_priv_.head; /* put in a temporary (register) */ -QSCtr const end = QS_priv_.end; /* put in a temporary (register) */ -QSCtr used = QS_priv_.used; /* put in a temporary (register) */ +//............................................................................ +void QS_endRec_(void) { + uint8_t * const buf = QS_priv_.buf; // put in a temporary (register) + QSCtr head = QS_priv_.head; + QSCtr const end = QS_priv_.end; + uint8_t b = QS_priv_.chksum; + b ^= 0xFFU; // invert the bits in the checksum -for (char const *s = str; *s != '\0'; ++s) { - chksum += (uint8_t)*s; /* update checksum */ - QS_INSERT_BYTE_((uint8_t)*s) /* ASCII char doesn't need escaping */ - ++used; -} -QS_INSERT_BYTE_((uint8_t)'\0') /* zero-terminate the string */ -++used; + QS_priv_.used += 2U; // 2 bytes about to be added -QS_priv_.head = head; /* save the head */ -QS_priv_.chksum = chksum; /* save the checksum */ -QS_priv_.used = used; /* save # of used buffer space */ - - - - /*! Output uint8_t data element with format information -* @static @private @memberof QS_tx -* -* @details -* @note This function is only to be used through macros, never in the -* client code directly. -*/ - - - - - uint8_t chksum = QS_priv_.chksum; /* put in a temporary (register) */ -uint8_t * const buf = QS_priv_.buf; /* put in a temporary (register) */ -QSCtr head = QS_priv_.head; /* put in a temporary (register) */ -QSCtr const end = QS_priv_.end; /* put in a temporary (register) */ - -QS_priv_.used += 2U; /* 2 bytes about to be added */ - -QS_INSERT_ESC_BYTE_(format) -QS_INSERT_ESC_BYTE_(d) - -QS_priv_.head = head; /* save the head */ -QS_priv_.chksum = chksum; /* save the checksum */ - - - - /*! output uint16_t data element with format information -* @static @private @memberof QS_tx -* -* @details -* This function is only to be used through macros, never in the -* client code directly. -*/ - - - - - uint8_t chksum = QS_priv_.chksum; /* put in a temporary (register) */ -uint8_t * const buf = QS_priv_.buf; /* put in a temporary (register) */ -QSCtr head = QS_priv_.head; /* put in a temporary (register) */ -QSCtr const end = QS_priv_.end; /* put in a temporary (register) */ -uint8_t b = (uint8_t)d; - -QS_priv_.used += 3U; /* 3 bytes about to be added */ - -QS_INSERT_ESC_BYTE_(format) -QS_INSERT_ESC_BYTE_(b) -b = (uint8_t)(d >> 8U); -QS_INSERT_ESC_BYTE_(b) - -QS_priv_.head = head; /* save the head */ -QS_priv_.chksum = chksum; /* save the checksum */ - - - - /*! Output uint32_t data element with format information -* @static @private @memberof QS_tx -* -* @note This function is only to be used through macros, never in the -* client code directly. -*/ - - - - - uint8_t chksum = QS_priv_.chksum; /* put in a temporary (register) */ -uint8_t * const buf = QS_priv_.buf; /* put in a temporary (register) */ -QSCtr head = QS_priv_.head; /* put in a temporary (register) */ -QSCtr const end = QS_priv_.end; /* put in a temporary (register) */ -uint32_t x = d; - -QS_priv_.used += 5U; /* 5 bytes about to be added */ -QS_INSERT_ESC_BYTE_(format) /* insert the format byte */ - -/* insert 4 bytes... */ -for (uint_fast8_t i = 4U; i != 0U; --i) { - QS_INSERT_ESC_BYTE_((uint8_t)x) - x >>= 8U; -} - -QS_priv_.head = head; /* save the head */ -QS_priv_.chksum = chksum; /* save the checksum */ - - - - /*! Output formatted zero-terminated ASCII string to the QS record -* @static @private @memberof QS_tx -*/ - - - uint8_t chksum = QS_priv_.chksum; -uint8_t * const buf = QS_priv_.buf; /* put in a temporary (register) */ -QSCtr head = QS_priv_.head; /* put in a temporary (register) */ -QSCtr const end = QS_priv_.end; /* put in a temporary (register) */ -QSCtr used = QS_priv_.used; /* put in a temporary (register) */ - -used += 2U; /* account for the format byte and the terminating-0 */ -QS_INSERT_BYTE_((uint8_t)QS_STR_T) -chksum += (uint8_t)QS_STR_T; - -for (char const *s = str; *s != '\0'; ++s) { - QS_INSERT_BYTE_((uint8_t)*s) /* ASCII char doesn't need escaping */ - chksum += (uint8_t)*s; /* update checksum */ - ++used; -} -QS_INSERT_BYTE_(0U) /* zero-terminate the string */ - -QS_priv_.head = head; /* save the head */ -QS_priv_.chksum = chksum; /* save the checksum */ -QS_priv_.used = used; /* save # of used buffer space */ - - - - /*! Output formatted memory block of up to 255 bytes to the QS record -* @static @private @memberof QS_tx -*/ - - - - - uint8_t chksum = QS_priv_.chksum; -uint8_t * const buf = QS_priv_.buf; /* put in a temporary (register) */ -QSCtr head = QS_priv_.head; /* put in a temporary (register) */ -QSCtr const end = QS_priv_.end; /* put in a temporary (register) */ -uint8_t const *pb = blk; - -QS_priv_.used += ((QSCtr)size + 2U); /* size+2 bytes to be added */ - -QS_INSERT_BYTE_((uint8_t)QS_MEM_T) -chksum += (uint8_t)QS_MEM_T; - -QS_INSERT_ESC_BYTE_(size) -/* output the 'size' number of bytes */ -for (uint8_t len = size; len > 0U; --len) { - QS_INSERT_ESC_BYTE_(*pb) - ++pb; -} - -QS_priv_.head = head; /* save the head */ -QS_priv_.chksum = chksum; /* save the checksum */ - - - - /*! Output predefined signal-dictionary record -* @static @private @memberof QS_tx -* -* @note This function is only to be used through macro QS_SIG_DICTIONARY() -*/ - - - - - - - QS_CRIT_STAT_ - -QS_CRIT_E_(); -QS_beginRec_((uint_fast8_t)QS_SIG_DICT); -QS_SIG_PRE_(sig); -QS_OBJ_PRE_(obj); -QS_str_raw_((*name == '&') ? &name[1] : name); -QS_endRec_(); -QS_CRIT_X_(); -QS_onFlush(); - - - - /*! Output predefined object-dictionary record -* @static @private @memberof QS_tx -* -* @note This function is only to be used through macro QS_OBJ_DICTIONARY() -*/ - - - - - QS_CRIT_STAT_ - -QS_CRIT_E_(); -QS_beginRec_((uint_fast8_t)QS_OBJ_DICT); -QS_OBJ_PRE_(obj); -QS_str_raw_((*name == '&') ? &name[1] : name); -QS_endRec_(); -QS_CRIT_X_(); -QS_onFlush(); - - - - /*! Output predefined object-array dictionary record -* @static @private @memberof QS_tx -* -* @note This function is only to be used through macro QS_OBJ_ARR_DICTIONARY() -*/ - - - - - - - Q_REQUIRE_ID(400, idx < 1000U); - -/* format idx into a char buffer as "xxx\0" */ -uint8_t idx_str[4]; -uint_fast16_t tmp = idx; -uint8_t i; -idx_str[3] = 0U; /* zero-terminate */ -idx_str[2] = (uint8_t)((uint8_t)'0' + (tmp % 10U)); -tmp /= 10U; -idx_str[1] = (uint8_t)((uint8_t)'0' + (tmp % 10U)); -if (idx_str[1] == (uint8_t)'0') { - i = 2U; -} -else { - tmp /= 10U; - idx_str[0] = (uint8_t)((uint8_t)'0' + (tmp % 10U)); - if (idx_str[0] == (uint8_t)'0') { - i = 1U; + if ((b != QS_FRAME) && (b != QS_ESC)) { + QS_INSERT_BYTE_(b) } else { - i = 0U; + QS_INSERT_BYTE_(QS_ESC) + QS_INSERT_BYTE_(b ^ QS_ESC_XOR) + ++QS_priv_.used; // account for the ESC byte + } + + QS_INSERT_BYTE_(QS_FRAME) // do not escape this QS_FRAME + + QS_priv_.head = head; // save the head + + // overrun over the old data? + if (QS_priv_.used > end) { + QS_priv_.used = end; // the whole buffer is used + QS_priv_.tail = head; // shift the tail to the old data } } -QS_CRIT_STAT_ -uint8_t j = ((*name == '&') ? 1U : 0U); +//............................................................................ +void QS_u8_raw_(uint8_t const d) { + uint8_t chksum = QS_priv_.chksum; // put in a temporary (register) + uint8_t * const buf = QS_priv_.buf; // put in a temporary (register) + QSCtr head = QS_priv_.head; // put in a temporary (register) + QSCtr const end = QS_priv_.end; // put in a temporary (register) -QS_CRIT_E_(); -QS_beginRec_((uint_fast8_t)QS_OBJ_DICT); -QS_OBJ_PRE_(obj); -for (; name[j] != '\0'; ++j) { - QS_U8_PRE_(name[j]); - if (name[j] == '[') { - ++j; - break; + QS_priv_.used += 1U; // 1 byte about to be added + QS_INSERT_ESC_BYTE_(d) + + QS_priv_.head = head; // save the head + QS_priv_.chksum = chksum; // save the checksum +} + +//............................................................................ +void QS_2u8_raw_( + uint8_t const d1, + uint8_t const d2) +{ + uint8_t chksum = QS_priv_.chksum; // put in a temporary (register) + uint8_t * const buf = QS_priv_.buf; // put in a temporary (register) + QSCtr head = QS_priv_.head; // put in a temporary (register) + QSCtr const end = QS_priv_.end; // put in a temporary (register) + + QS_priv_.used += 2U; // 2 bytes are about to be added + QS_INSERT_ESC_BYTE_(d1) + QS_INSERT_ESC_BYTE_(d2) + + QS_priv_.head = head; // save the head + QS_priv_.chksum = chksum; // save the checksum +} + +//............................................................................ +void QS_u16_raw_(uint16_t const d) { + uint8_t chksum = QS_priv_.chksum; // put in a temporary (register) + uint8_t * const buf = QS_priv_.buf; // put in a temporary (register) + QSCtr head = QS_priv_.head; // put in a temporary (register) + QSCtr const end = QS_priv_.end; // put in a temporary (register) + uint16_t x = d; + + QS_priv_.used += 2U; // 2 bytes are about to be added + + QS_INSERT_ESC_BYTE_((uint8_t)x) + x >>= 8U; + QS_INSERT_ESC_BYTE_((uint8_t)x) + + QS_priv_.head = head; // save the head + QS_priv_.chksum = chksum; // save the checksum +} + +//............................................................................ +void QS_u32_raw_(uint32_t const d) { + uint8_t chksum = QS_priv_.chksum; // put in a temporary (register) + uint8_t * const buf = QS_priv_.buf; // put in a temporary (register) + QSCtr head = QS_priv_.head; // put in a temporary (register) + QSCtr const end = QS_priv_.end; // put in a temporary (register) + uint32_t x = d; + + QS_priv_.used += 4U; // 4 bytes are about to be added + for (uint_fast8_t i = 4U; i != 0U; --i) { + QS_INSERT_ESC_BYTE_((uint8_t)x) + x >>= 8U; } + + QS_priv_.head = head; // save the head + QS_priv_.chksum = chksum; // save the checksum } -for (; idx_str[i] != 0U; ++i) { - QS_U8_PRE_(idx_str[i]); + +//............................................................................ +void QS_obj_raw_(void const * const obj) { + #if (QS_OBJ_PTR_SIZE == 1U) + QS_u8_raw_((uint8_t)obj); + #elif (QS_OBJ_PTR_SIZE == 2U) + QS_u16_raw_((uint16_t)obj); + #elif (QS_OBJ_PTR_SIZE == 4U) + QS_u32_raw_((uint32_t)obj); + #elif (QS_OBJ_PTR_SIZE == 8U) + QS_u64_raw_((uint64_t)obj); + #else + QS_u32_raw_((uint32_t)obj); + #endif } -/* skip chars until ']' */ -for (; name[j] != '\0'; ++j) { - if (name[j] == ']') { - break; + +//............................................................................ +void QS_str_raw_(char const * const str) { + uint8_t chksum = QS_priv_.chksum; // put in a temporary (register) + uint8_t * const buf = QS_priv_.buf; // put in a temporary (register) + QSCtr head = QS_priv_.head; // put in a temporary (register) + QSCtr const end = QS_priv_.end; // put in a temporary (register) + QSCtr used = QS_priv_.used; // put in a temporary (register) + + for (char const *s = str; *s != '\0'; ++s) { + chksum += (uint8_t)*s; // update checksum + QS_INSERT_BYTE_((uint8_t)*s) // ASCII char doesn't need escaping + ++used; } + QS_INSERT_BYTE_((uint8_t)'\0') // zero-terminate the string + ++used; + + QS_priv_.head = head; // save the head + QS_priv_.chksum = chksum; // save the checksum + QS_priv_.used = used; // save # of used buffer space } -for (; name[j] != '\0'; ++j) { - QS_U8_PRE_(name[j]); + +//............................................................................ +void QS_u8_fmt_( + uint8_t const format, + uint8_t const d) +{ + uint8_t chksum = QS_priv_.chksum; // put in a temporary (register) + uint8_t * const buf = QS_priv_.buf; // put in a temporary (register) + QSCtr head = QS_priv_.head; // put in a temporary (register) + QSCtr const end = QS_priv_.end; // put in a temporary (register) + + QS_priv_.used += 2U; // 2 bytes about to be added + + QS_INSERT_ESC_BYTE_(format) + QS_INSERT_ESC_BYTE_(d) + + QS_priv_.head = head; // save the head + QS_priv_.chksum = chksum; // save the checksum } -QS_U8_PRE_(0U); /* zero-terminate */ -QS_endRec_(); -QS_CRIT_X_(); -QS_onFlush(); - - - - /*! Output predefined function-dictionary record -* @static @private @memberof QS_tx -* -* @note This function is only to be used through macro QS_FUN_DICTIONARY() -*/ - - - - - QS_CRIT_STAT_ -QS_CRIT_E_(); -QS_beginRec_((uint_fast8_t)QS_FUN_DICT); -QS_FUN_PRE_(fun); -QS_str_raw_((*name == '&') ? &name[1] : name); -QS_endRec_(); -QS_CRIT_X_(); -QS_onFlush(); - - - - /*! Output predefined user-dictionary record -* @static @private @memberof QS_tx -* -* @note This function is only to be used through macro QS_USR_DICTIONARY() -*/ - - - - - QS_CRIT_STAT_ +//............................................................................ +void QS_u16_fmt_( + uint8_t const format, + uint16_t const d) +{ + uint8_t chksum = QS_priv_.chksum; // put in a temporary (register) + uint8_t * const buf = QS_priv_.buf; // put in a temporary (register) + QSCtr head = QS_priv_.head; // put in a temporary (register) + QSCtr const end = QS_priv_.end; // put in a temporary (register) + uint8_t b = (uint8_t)d; -QS_CRIT_E_(); -QS_beginRec_((uint_fast8_t)QS_USR_DICT); -QS_u8_raw_((uint8_t)rec); -QS_str_raw_(name); -QS_endRec_(); -QS_CRIT_X_(); -QS_onFlush(); - - - - /*! Output predefined enum-dictionary record -* @static @private @memberof QS_tx -* -* @note This function is only to be used through macro QS_ENUM_DICTIONARY() -*/ - - - - - - - QS_CRIT_STAT_ + QS_priv_.used += 3U; // 3 bytes about to be added -QS_CRIT_E_(); -QS_beginRec_((uint_fast8_t)QS_ENUM_DICT); -QS_2U8_PRE_((uint8_t)value, group); -QS_str_raw_(name); -QS_endRec_(); -QS_CRIT_X_(); -QS_onFlush(); - - - - /*! Output the predefined assertion failure trace record -* @static @public @memberof QS_tx -* -* @details -* This trace record is intended to use from the Q_onAssert() callback. -*/ - - - - - - - QS_BEGIN_NOCRIT_PRE_(QS_ASSERT_FAIL, 0U) - QS_TIME_PRE_(); - QS_U16_PRE_(loc); - QS_STR_PRE_((module != (char *)0) ? module : "?"); -QS_END_NOCRIT_PRE_() -QS_onFlush(); + QS_INSERT_ESC_BYTE_(format) + QS_INSERT_ESC_BYTE_(b) + b = (uint8_t)(d >> 8U); + QS_INSERT_ESC_BYTE_(b) -for (uint32_t volatile delay_ctr = delay; delay_ctr > 0U; --delay_ctr) { + QS_priv_.head = head; // save the head + QS_priv_.chksum = chksum; // save the checksum } -QS_onCleanup(); - - - - /*! Helper function to output the predefined Target-info trace record -* @static @private @memberof QS_tx -*/ - - - static uint8_t const ZERO = (uint8_t)'0'; -static uint8_t const * const TIME = (uint8_t const *)&Q_BUILD_TIME[0]; -static uint8_t const * const DATE = (uint8_t const *)&Q_BUILD_DATE[0]; -static union { - uint16_t u16; - uint8_t u8[2]; -} endian_test; -endian_test.u16 = 0x0102U; -QS_beginRec_((uint_fast8_t)QS_TARGET_INFO); +//............................................................................ +void QS_u32_fmt_( + uint8_t const format, + uint32_t const d) +{ + uint8_t chksum = QS_priv_.chksum; // put in a temporary (register) + uint8_t * const buf = QS_priv_.buf; // put in a temporary (register) + QSCtr head = QS_priv_.head; // put in a temporary (register) + QSCtr const end = QS_priv_.end; // put in a temporary (register) + uint32_t x = d; + + QS_priv_.used += 5U; // 5 bytes about to be added + QS_INSERT_ESC_BYTE_(format) // insert the format byte + + // insert 4 bytes... + for (uint_fast8_t i = 4U; i != 0U; --i) { + QS_INSERT_ESC_BYTE_((uint8_t)x) + x >>= 8U; + } + + QS_priv_.head = head; // save the head + QS_priv_.chksum = chksum; // save the checksum +} + +//............................................................................ +void QS_str_fmt_(char const * const str) { + uint8_t chksum = QS_priv_.chksum; + uint8_t * const buf = QS_priv_.buf; // put in a temporary (register) + QSCtr head = QS_priv_.head; // put in a temporary (register) + QSCtr const end = QS_priv_.end; // put in a temporary (register) + QSCtr used = QS_priv_.used; // put in a temporary (register) + + used += 2U; // account for the format byte and the terminating-0 + QS_INSERT_BYTE_((uint8_t)QS_STR_T) + chksum += (uint8_t)QS_STR_T; + + for (char const *s = str; *s != '\0'; ++s) { + QS_INSERT_BYTE_((uint8_t)*s) // ASCII char doesn't need escaping + chksum += (uint8_t)*s; // update checksum + ++used; + } + QS_INSERT_BYTE_(0U) // zero-terminate the string + + QS_priv_.head = head; // save the head + QS_priv_.chksum = chksum; // save the checksum + QS_priv_.used = used; // save # of used buffer space +} + +//............................................................................ +void QS_mem_fmt_( + uint8_t const * const blk, + uint8_t const size) +{ + uint8_t chksum = QS_priv_.chksum; + uint8_t * const buf = QS_priv_.buf; // put in a temporary (register) + QSCtr head = QS_priv_.head; // put in a temporary (register) + QSCtr const end = QS_priv_.end; // put in a temporary (register) + uint8_t const *pb = blk; + + QS_priv_.used += ((QSCtr)size + 2U); // size+2 bytes to be added + + QS_INSERT_BYTE_((uint8_t)QS_MEM_T) + chksum += (uint8_t)QS_MEM_T; + + QS_INSERT_ESC_BYTE_(size) + // output the 'size' # bytes + for (uint8_t len = size; len > 0U; --len) { + QS_INSERT_ESC_BYTE_(*pb) + ++pb; + } + + QS_priv_.head = head; // save the head + QS_priv_.chksum = chksum; // save the checksum +} + +//............................................................................ +void QS_sig_dict_pre_( + QSignal const sig, + void const * const obj, + char const * const name) +{ + QS_CRIT_STAT + QS_CRIT_ENTRY(); + QS_MEM_SYS(); + + QS_beginRec_((uint_fast8_t)QS_SIG_DICT); + QS_SIG_PRE_(sig); + QS_OBJ_PRE_(obj); + QS_STR_PRE_((*name == '&') ? &name[1] : name); + QS_endRec_(); + + QS_MEM_APP(); + QS_CRIT_EXIT(); + QS_onFlush(); +} + +//............................................................................ +void QS_obj_dict_pre_( + void const * const obj, + char const * const name) +{ + QS_CRIT_STAT + QS_CRIT_ENTRY(); + QS_MEM_SYS(); + + QS_beginRec_((uint_fast8_t)QS_OBJ_DICT); + QS_OBJ_PRE_(obj); + QS_STR_PRE_((*name == '&') ? &name[1] : name); + QS_endRec_(); + + QS_MEM_APP(); + QS_CRIT_EXIT(); + QS_onFlush(); +} + +//............................................................................ +void QS_obj_arr_dict_pre_( + void const * const obj, + uint_fast16_t const idx, + char const * const name) +{ + QS_CRIT_STAT + QS_CRIT_ENTRY(); + Q_REQUIRE_INCRIT(400, idx < 1000U); + QS_CRIT_EXIT(); + + // format idx into a char buffer as "xxx\0" + uint8_t idx_str[4]; + uint_fast16_t tmp = idx; + uint8_t i; + idx_str[3] = 0U; // zero-terminate + idx_str[2] = (uint8_t)((uint8_t)'0' + (tmp % 10U)); + tmp /= 10U; + idx_str[1] = (uint8_t)((uint8_t)'0' + (tmp % 10U)); + if (idx_str[1] == (uint8_t)'0') { + i = 2U; + } + else { + tmp /= 10U; + idx_str[0] = (uint8_t)((uint8_t)'0' + (tmp % 10U)); + if (idx_str[0] == (uint8_t)'0') { + i = 1U; + } + else { + i = 0U; + } + } + + uint8_t j = ((*name == '&') ? 1U : 0U); + + QS_CRIT_ENTRY(); + QS_MEM_SYS(); + + QS_beginRec_((uint_fast8_t)QS_OBJ_DICT); + QS_OBJ_PRE_(obj); + for (; name[j] != '\0'; ++j) { + QS_U8_PRE_(name[j]); + if (name[j] == '[') { + ++j; + break; + } + } + for (; idx_str[i] != 0U; ++i) { + QS_U8_PRE_(idx_str[i]); + } + // skip chars until ']' + for (; name[j] != '\0'; ++j) { + if (name[j] == ']') { + break; + } + } + for (; name[j] != '\0'; ++j) { + QS_U8_PRE_(name[j]); + } + QS_U8_PRE_(0U); // zero-terminate + QS_endRec_(); + + QS_MEM_APP(); + QS_CRIT_EXIT(); + QS_onFlush(); +} + +//............................................................................ +void QS_fun_dict_pre_( + QSpyFunPtr const fun, + char const * const name) +{ + QS_CRIT_STAT + QS_CRIT_ENTRY(); + QS_MEM_SYS(); + + QS_beginRec_((uint_fast8_t)QS_FUN_DICT); + QS_FUN_PRE_(fun); + QS_STR_PRE_((*name == '&') ? &name[1] : name); + QS_endRec_(); + + QS_MEM_APP(); + QS_CRIT_EXIT(); + QS_onFlush(); +} + +//............................................................................ +void QS_usr_dict_pre_( + enum_t const rec, + char const * const name) +{ + QS_CRIT_STAT + QS_CRIT_ENTRY(); + QS_MEM_SYS(); + + QS_beginRec_((uint_fast8_t)QS_USR_DICT); + QS_U8_PRE_(rec); + QS_STR_PRE_(name); + QS_endRec_(); + + QS_MEM_APP(); + QS_CRIT_EXIT(); + QS_onFlush(); +} + +//............................................................................ +void QS_enum_dict_pre_( + enum_t const value, + uint8_t const group, + char const * const name) +{ + QS_CRIT_STAT + QS_CRIT_ENTRY(); + QS_MEM_SYS(); + + QS_beginRec_((uint_fast8_t)QS_ENUM_DICT); + QS_2U8_PRE_(value, group); + QS_STR_PRE_(name); + QS_endRec_(); + + QS_MEM_APP(); + QS_CRIT_EXIT(); + QS_onFlush(); +} + +//............................................................................ +void QS_assertion_pre_( + char const * const module, + int_t const id, + uint32_t const delay) +{ + // NOTE: called in a critical section + + QS_beginRec_((uint_fast8_t)QS_ASSERT_FAIL); + QS_TIME_PRE_(); + QS_U16_PRE_(id); + QS_STR_PRE_((module != (char *)0) ? module : "?"); + QS_endRec_(); + QS_onFlush(); + + for (uint32_t volatile delay_ctr = delay; + delay_ctr > 0U; --delay_ctr) + {} + QS_onCleanup(); +} + +//............................................................................ +void QS_target_info_pre_(uint8_t const isReset) { + // NOTE: called in a critical section + + static uint8_t const ZERO = (uint8_t)'0'; + static uint8_t const * const TIME = (uint8_t const *)&Q_BUILD_TIME[0]; + static uint8_t const * const DATE = (uint8_t const *)&Q_BUILD_DATE[0]; + static union { + uint16_t u16; + uint8_t u8[2]; + } endian_test; + + endian_test.u16 = 0x0102U; + QS_beginRec_((uint_fast8_t)QS_TARGET_INFO); QS_U8_PRE_(isReset); - QS_U16_PRE_(((endian_test.u8[0] == 0x01U) /* big endian? */ + QS_U16_PRE_(((endian_test.u8[0] == 0x01U) // big endian? ? (0x8000U | QP_VERSION) - : QP_VERSION)); /* target endianness + version number */ + : QP_VERSION)); // target endianness + version number - /* send the object sizes... */ + // send the object sizes... QS_U8_PRE_(Q_SIGNAL_SIZE | (QF_EVENT_SIZ_SIZE << 4U)); #ifdef QF_EQUEUE_CTR_SIZE QS_U8_PRE_(QF_EQUEUE_CTR_SIZE | (QF_TIMEEVT_CTR_SIZE << 4U)); #else QS_U8_PRE_(QF_TIMEEVT_CTR_SIZE << 4U); -#endif /* QF_EQUEUE_CTR_SIZE */ +#endif // QF_EQUEUE_CTR_SIZE #ifdef QF_MPOOL_CTR_SIZE QS_U8_PRE_(QF_MPOOL_SIZ_SIZE | (QF_MPOOL_CTR_SIZE << 4U)); #else QS_U8_PRE_(0U); -#endif /* QF_MPOOL_CTR_SIZE */ +#endif // QF_MPOOL_CTR_SIZE QS_U8_PRE_(QS_OBJ_PTR_SIZE | (QS_FUN_PTR_SIZE << 4U)); QS_U8_PRE_(QS_TIME_SIZE); - /* send the limits... */ + // send the limits... QS_U8_PRE_(QF_MAX_ACTIVE); QS_U8_PRE_(QF_MAX_EPOOL | (QF_MAX_TICK_RATE << 4U)); - /* send the build time in three bytes (sec, min, hour)... */ + // send the build time in three bytes (sec, min, hour)... QS_U8_PRE_((10U * (uint8_t)(TIME[6] - ZERO)) + (uint8_t)(TIME[7] - ZERO)); QS_U8_PRE_((10U * (uint8_t)(TIME[3] - ZERO)) @@ -8627,7 +10697,7 @@ QS_beginRec_((uint_fast8_t)QS_TARGET_INFO); + (uint8_t)(TIME[1] - ZERO)); } - /* send the build date in three bytes (day, month, year) ... */ + // send the build date in three bytes (day, month, year) ... if (Q_BUILD_DATE[4] == ' ') { QS_U8_PRE_(DATE[5] - ZERO); } @@ -8635,7 +10705,7 @@ QS_beginRec_((uint_fast8_t)QS_TARGET_INFO); QS_U8_PRE_((10U * (uint8_t)(DATE[4] - ZERO)) + (uint8_t)(DATE[5] - ZERO)); } - /* convert the 3-letter month to a number 1-12 ... */ + // convert the 3-letter month to a number 1-12 ... uint8_t b; switch ((int_t)DATE[0] + (int_t)DATE[1] + (int_t)DATE[2]) { case (int_t)'J' + (int_t)'a' + (int_t)'n': @@ -8678,6207 +10748,172 @@ QS_beginRec_((uint_fast8_t)QS_TARGET_INFO); b = 0U; break; } - QS_U8_PRE_(b); /* store the month */ + QS_U8_PRE_(b); // store the month QS_U8_PRE_((10U * (uint8_t)(DATE[9] - ZERO)) + (uint8_t)(DATE[10] - ZERO)); -QS_endRec_(); - - - - /*! Callback to startup the QS facility -* @static @public @memberof QS_tx -*/ - - - - - - /*! Callback to cleanup the QS facility -* @static @public @memberof QS_tx -*/ - - - - /*! Callback to flush the QS trace data to the host -* @static @public @memberof QS_tx -*/ - - - - /*! Callback to obtain a timestamp for a QS record -* @static @public @memberof QS_tx -*/ - - - - - - - /*! Output uint64_t data element without format information -* @static @private @memberof QS_tx -*/ - - - uint8_t chksum = QS_priv_.chksum; -uint8_t * const buf = QS_priv_.buf; -QSCtr head = QS_priv_.head; -QSCtr const end = QS_priv_.end; - -QS_priv_.used += 8U; /* 8 bytes are about to be added */ -uint_fast8_t i; -for (i = 8U; i != 0U; --i) { - uint8_t const b = (uint8_t)d; - QS_INSERT_ESC_BYTE_(b) - d >>= 8U; -} - -QS_priv_.head = head; /* save the head */ -QS_priv_.chksum = chksum; /* save the checksum */ - - - - /*! Output uint64_t data element with format information -* @static @private @memberof QS_tx -* -* @sa QS_U64(), QS_I64() -*/ - - - - - uint8_t chksum = QS_priv_.chksum; -uint8_t * const buf = QS_priv_.buf; -QSCtr head = QS_priv_.head; -QSCtr const end = QS_priv_.end; - -QS_priv_.used += 9U; /* 9 bytes are about to be added */ -QS_INSERT_ESC_BYTE_(format) /* insert the format byte */ - -/* output 8 bytes of data... */ -uint_fast8_t i; -for (i = 8U; i != 0U; --i) { - format = (uint8_t)d; - QS_INSERT_ESC_BYTE_(format) - d >>= 8U; -} - -QS_priv_.head = head; /* save the head */ -QS_priv_.chksum = chksum; /* save the checksum */ - - - - - - - /*! Output 32-bit floating point data element with format information -* @static @private @memberof QS_tx -* -* @sa QS_F32() -*/ - - - - - union F32Rep { - float32_t f; - uint32_t u; -} fu32; /* the internal binary representation */ -uint8_t chksum = QS_priv_.chksum; /* put in a temporary (register) */ -uint8_t * const buf = QS_priv_.buf; -QSCtr head = QS_priv_.head; -QSCtr const end = QS_priv_.end; -uint_fast8_t i; - -fu32.f = d; /* assign the binary representation */ - -QS_priv_.used += 5U; /* 5 bytes about to be added */ -QS_INSERT_ESC_BYTE_(format) /* insert the format byte */ - -/* insert 4 bytes... */ -for (i = 4U; i != 0U; --i) { - QS_INSERT_ESC_BYTE_((uint8_t)fu32.u) - fu32.u >>= 8U; -} - -QS_priv_.head = head; /* save the head */ -QS_priv_.chksum = chksum; /* save the checksum */ - - - - /*! Output 64-bit floating point data element with format information -* @static @private @memberof QS_tx -* -* @sa QS_F64() -*/ - - - - - union F64Rep { - float64_t d; - uint32_t u[2]; -} fu64; /* the internal binary representation */ -uint8_t chksum = QS_priv_.chksum; -uint8_t * const buf = QS_priv_.buf; -QSCtr head = QS_priv_.head; -QSCtr const end = QS_priv_.end; -uint32_t i; - -/* static constant untion to detect endianness of the machine */ -static union U32Rep { - uint32_t u32; - uint8_t u8; -} const endian = { 1U }; - -fu64.d = d; /* assign the binary representation */ - -/* is this a big-endian machine? */ -if (endian.u8 == 0U) { - /* swap fu64.u[0] <-> fu64.u[1]... */ - i = fu64.u[0]; - fu64.u[0] = fu64.u[1]; - fu64.u[1] = i; -} - -QS_priv_.used += 9U; /* 9 bytes about to be added */ -QS_INSERT_ESC_BYTE_(format) /* insert the format byte */ - -/* output 4 bytes from fu64.u[0]... */ -for (i = 4U; i != 0U; --i) { - QS_INSERT_ESC_BYTE_((uint8_t)fu64.u[0]) - fu64.u[0] >>= 8U; -} - -/* output 4 bytes from fu64.u[1]... */ -for (i = 4U; i != 0U; --i) { - QS_INSERT_ESC_BYTE_((uint8_t)fu64.u[1]) - fu64.u[1] >>= 8U; -} - -QS_priv_.head = head; /* save the head */ -QS_priv_.chksum = chksum; /* save the checksum */ - - - - - - - /*! @brief QS software tracing parameters for QS input (QS-RX) */ - - - * current objects - - - - * pointer to the start of the ring buffer - - - - * offset of the end of the ring buffer - - - - * offset to where next byte will be inserted - - - - * offset of where next byte will be extracted - - - - * QUTest event loop is running - - - - - /*! the only instance of the QS-RX object (Singleton) -* @static @private @memberof QS_rx -*/ - - - - /*! Kinds of objects used in QS_setCurrObj() and QS_queryCurrObj() -* @static @public @memberof QS_rx -*/ - { - SM_OBJ, /*!< state machine object */ - AO_OBJ, /*!< active object */ - MP_OBJ, /*!< event pool object */ - EQ_OBJ, /*!< raw queue object */ - TE_OBJ, /*!< time event object */ - AP_OBJ, /*!< generic Application-specific object */ - MAX_OBJ -}; - - - - /*! Object combinations for QS_setCurrObj() and QS_queryCurrObj() -* @static @public @memberof QS_rx -*/ - { - SM_AO_OBJ = (enum_t)MAX_OBJ /*!< combination of SM and AO */ -}; - - - - /*! Initialize the QS-RX data buffer -* @static @public @memberof QS_rx -* -* @details -* This function should be called from QS::onStartup() to provide QS-RX -* with the receive data buffer. -* -* @param[in] sto pointer to the memory block for input buffer -* @param[in] stoSize the size of this block [bytes]. The size of the -* QS-RX buffer cannot exceed 64KB. -* -* @note -* QS-RX can work with quite small data buffers, but you will start -* losing data if the buffer is not drained fast enough (e.g., in the -* idle task). -* -* @note -* If the data input rate exceeds the QS-RX processing rate, the data -* will be lost, but the QS protocol will notice that: -* (1) that the checksum in the incomplete QS records will fail; and -* (2) the sequence counter in QS records will show discontinuities. -* -* The QS-RX channel will report any data errors by sending the -* QS_RX_DATA_ERROR trace record. -*/ - - - - - QS_rxPriv_.buf = &sto[0]; -QS_rxPriv_.end = (QSCtr)stoSize; -QS_rxPriv_.head = 0U; -QS_rxPriv_.tail = 0U; - -QS_rxPriv_.currObj[SM_OBJ] = (void *)0; -QS_rxPriv_.currObj[AO_OBJ] = (void *)0; -QS_rxPriv_.currObj[MP_OBJ] = (void *)0; -QS_rxPriv_.currObj[EQ_OBJ] = (void *)0; -QS_rxPriv_.currObj[TE_OBJ] = (void *)0; -QS_rxPriv_.currObj[AP_OBJ] = (void *)0; - -QS_RX_TRAN_(WAIT4_SEQ); -l_rx.esc = 0U; -l_rx.seq = 0U; -l_rx.chksum = 0U; - -QS_beginRec_((uint_fast8_t)QS_OBJ_DICT); - QS_OBJ_PRE_(&QS_rxPriv_); - QS_STR_PRE_("QS_RX"); -QS_endRec_(); -/* no QS_REC_DONE(), because QS is not running yet */ - -#ifdef Q_UTEST -QS_testData.tpNum = 0U; -QS_testData.testTime = 0U; -#endif /* Q_UTEST */ - - - - /*! Put one byte into the QS-RX lock-free buffer -* @static @public @memberof QS_rx -*/ - - - QSCtr head = QS_rxPriv_.head + 1U; -if (head == QS_rxPriv_.end) { - head = 0U; -} -if (head != QS_rxPriv_.tail) { /* buffer NOT full? */ - QS_rxPriv_.buf[QS_rxPriv_.head] = b; - QS_rxPriv_.head = head; /* update the head to a *valid* index */ - return true; /* byte placed in the buffer */ -} -else { - return false; /* byte NOT placed in the buffer */ -} - - - - /*! Obtain the number of free bytes in the QS-RX data buffer -* @static @public @memberof QS_rx -* -* @details -* This function is intended to be called from the ISR that reads the -* QS-RX bytes from the QSPY application. The function returns the -* conservative number of free bytes currently available in the buffer, -* assuming that the head pointer is not being moved concurrently. -* The tail pointer might be moving, meaning that bytes can be -* concurrently removed from the buffer. -*/ - QSCtr const head = QS_rxPriv_.head; -if (head == QS_rxPriv_.tail) { /* buffer empty? */ - return (uint16_t)(QS_rxPriv_.end - 1U); -} -else if (head < QS_rxPriv_.tail) { - return (uint16_t)(QS_rxPriv_.tail - (head + 1U)); -} -else { - return (uint16_t)(QS_rxPriv_.end + QS_rxPriv_.tail - (head + 1U)); -} - - - - /*! Perform the QS-RX input (implemented in some QS ports) -* @static @public @memberof QS_rx -*/ - - - - /*! Set the "current object" in the Target -* @static @public @memberof QS_rx -* -* @details -* This function sets the "current object" in the Target. -*/ - - - - - Q_REQUIRE_ID(100, obj_kind < Q_DIM(QS_rxPriv_.currObj)); -QS_rxPriv_.currObj[obj_kind] = obj_ptr; - - - - /*! Query the "current object" in the Target -* @static @public @memberof QS_rx -* -* @details -* This function programmatically generates the response to the query for -* a "current object". -*/ - - - if (QS_rxPriv_.currObj[obj_kind] != (void *)0) { - QS_CRIT_STAT_ - QS_CRIT_E_(); - QS_beginRec_((uint_fast8_t)QS_QUERY_DATA); - QS_TIME_PRE_(); /* timestamp */ - QS_U8_PRE_(obj_kind); /* object kind */ - QS_OBJ_PRE_(QS_rxPriv_.currObj[obj_kind]); - switch (obj_kind) { - case SM_OBJ: /* intentionally fall through */ - case AO_OBJ: - QS_FUN_PRE_((*((QHsm *)QS_rxPriv_.currObj[obj_kind])->vptr - ->getStateHandler)( - ((QHsm *)QS_rxPriv_.currObj[obj_kind]))); - break; - case MP_OBJ: - QS_MPC_PRE_(((QMPool *)QS_rxPriv_.currObj[obj_kind]) - ->nFree); - QS_MPC_PRE_(((QMPool *)QS_rxPriv_.currObj[obj_kind]) - ->nMin); - break; - case EQ_OBJ: - QS_EQC_PRE_(((QEQueue *)QS_rxPriv_.currObj[obj_kind]) - ->nFree); - QS_EQC_PRE_(((QEQueue *)QS_rxPriv_.currObj[obj_kind]) - ->nMin); - break; - case TE_OBJ: - QS_OBJ_PRE_(((QTimeEvt *)QS_rxPriv_.currObj[obj_kind]) - ->act); - QS_TEC_PRE_(((QTimeEvt *)QS_rxPriv_.currObj[obj_kind]) - ->ctr); - QS_TEC_PRE_(((QTimeEvt *)QS_rxPriv_.currObj[obj_kind]) - ->interval); - QS_SIG_PRE_(((QTimeEvt *)QS_rxPriv_.currObj[obj_kind]) - ->super.sig); - QS_U8_PRE_ (((QTimeEvt *)QS_rxPriv_.currObj[obj_kind]) - ->super.refCtr_); - break; - default: - /* intentionally empty */ - break; - } QS_endRec_(); - QS_CRIT_X_(); - - QS_REC_DONE(); /* user callback (if defined) */ -} -else { - QS_rxReportError_((int8_t)QS_RX_QUERY_CURR); -} - - - - /*! Parse all bytes present in the QS-RX data buffer -* @static @public @memberof QS_rx -*/ - QSCtr tail = QS_rxPriv_.tail; -while (QS_rxPriv_.head != tail) { /* QS-RX buffer NOT empty? */ - uint8_t b = QS_rxPriv_.buf[tail]; - - ++tail; - if (tail == QS_rxPriv_.end) { - tail = 0U; - } - QS_rxPriv_.tail = tail; /* update the tail to a *valid* index */ - - if (l_rx.esc != 0U) { /* escaped byte arrived? */ - l_rx.esc = 0U; - b ^= QS_ESC_XOR; - - l_rx.chksum += b; - QS_rxParseData_(b); - } - else if (b == QS_ESC) { - l_rx.esc = 1U; - } - else if (b == QS_FRAME) { - /* get ready for the next frame */ - b = l_rx.state; /* save the current state in b */ - l_rx.esc = 0U; - QS_RX_TRAN_(WAIT4_SEQ); - - if (l_rx.chksum == QS_GOOD_CHKSUM) { - l_rx.chksum = 0U; - QS_rxHandleGoodFrame_(b); - } - else { /* bad checksum */ - l_rx.chksum = 0U; - QS_rxReportError_(0x41); - QS_rxHandleBadFrame_(b); - } - } - else { - l_rx.chksum += b; - QS_rxParseData_(b); - } -} - - - - /*! internal function to handle incoming (QS-RX) packet -* @static @private @memberof QS_rx -*/ - - - uint8_t i; -uint8_t *ptr; -QS_CRIT_STAT_ - -switch (state) { - case WAIT4_INFO_FRAME: { - /* no need to report Ack or Done */ - QS_CRIT_E_(); - QS_target_info_pre_(0U); /* send only Target info */ - QS_CRIT_X_(); - break; - } - case WAIT4_RESET_FRAME: { - /* no need to report Ack or Done, because Target resets */ - QS_onReset(); /* reset the Target */ - break; - } - case WAIT4_CMD_PARAM1: /* intentionally fall-through */ - case WAIT4_CMD_PARAM2: /* intentionally fall-through */ - case WAIT4_CMD_PARAM3: /* intentionally fall-through */ - case WAIT4_CMD_FRAME: { - QS_rxReportAck_((int8_t)QS_RX_COMMAND); - QS_onCommand(l_rx.var.cmd.cmdId, l_rx.var.cmd.param1, - l_rx.var.cmd.param2, l_rx.var.cmd.param3); -#ifdef Q_UTEST -#if Q_UTEST != 0 - QS_processTestEvts_(); /* process all events produced */ -#endif /* Q_UTEST != 0 */ -#endif /* Q_UTEST */ - QS_rxReportDone_((int8_t)QS_RX_COMMAND); - break; - } - case WAIT4_TICK_FRAME: { - QS_rxReportAck_((int8_t)QS_RX_TICK); -#ifdef Q_UTEST - QTimeEvt_tick1_((uint_fast8_t)l_rx.var.tick.rate, &QS_rxPriv_); -#if Q_UTEST != 0 - QS_processTestEvts_(); /* process all events produced */ -#endif /* Q_UTEST != 0 */ -#else - QTimeEvt_tick_((uint_fast8_t)l_rx.var.tick.rate, &QS_rxPriv_); -#endif /* Q_UTEST */ - QS_rxReportDone_((int8_t)QS_RX_TICK); - break; - } - case WAIT4_PEEK_FRAME: { - - /* no need to report Ack or Done */ - QS_CRIT_E_(); - QS_beginRec_((uint_fast8_t)QS_PEEK_DATA); - ptr = (uint8_t *)QS_rxPriv_.currObj[AP_OBJ]; - ptr = &ptr[l_rx.var.peek.offs]; - QS_TIME_PRE_(); /* timestamp */ - QS_U16_PRE_(l_rx.var.peek.offs); /* data offset */ - QS_U8_PRE_(l_rx.var.peek.size); /* data size */ - QS_U8_PRE_(l_rx.var.peek.num); /* number of data items */ - for (i = 0U; i < l_rx.var.peek.num; ++i) { - switch (l_rx.var.peek.size) { - case 1: - QS_U8_PRE_(ptr[i]); - break; - case 2: - QS_U16_PRE_(((uint16_t *)ptr)[i]); - break; - case 4: - QS_U32_PRE_(((uint32_t *)ptr)[i]); - break; - default: - /* intentionally empty */ - break; - } - } - QS_endRec_(); - QS_CRIT_X_(); - - QS_REC_DONE(); /* user callback (if defined) */ - break; - } - case WAIT4_POKE_DATA: { - /* received less than expected poke data items */ - QS_rxReportError_((int8_t)QS_RX_POKE); - break; - } - case WAIT4_POKE_FRAME: { - QS_rxReportAck_((int8_t)QS_RX_POKE); - /* no need to report done */ - break; - } - case WAIT4_FILL_FRAME: { - QS_rxReportAck_((int8_t)QS_RX_FILL); - ptr = (uint8_t *)QS_rxPriv_.currObj[AP_OBJ]; - ptr = &ptr[l_rx.var.poke.offs]; - for (i = 0U; i < l_rx.var.poke.num; ++i) { - switch (l_rx.var.poke.size) { - case 1: - ptr[i] = (uint8_t)l_rx.var.poke.data; - break; - case 2: - ((uint16_t *)ptr)[i] - = (uint16_t)l_rx.var.poke.data; - break; - case 4: - ((uint32_t *)ptr)[i] = l_rx.var.poke.data; - break; - default: - /* intentionally empty */ - break; - } - } - break; - } - case WAIT4_FILTER_FRAME: { - QS_rxReportAck_(l_rx.var.flt.recId); - - /* apply the received filters */ - if (l_rx.var.flt.recId == (int8_t)QS_RX_GLB_FILTER) { - for (i = 0U; i < Q_DIM(QS_priv_.glbFilter); ++i) { - QS_priv_.glbFilter[i] = l_rx.var.flt.data[i]; - } - /* leave the "not maskable" filters enabled, - * see qs.h, Miscellaneous QS records (not maskable) - */ - QS_priv_.glbFilter[0] |= 0x01U; - QS_priv_.glbFilter[7] |= 0xFCU; - QS_priv_.glbFilter[8] |= 0x7FU; - - /* never enable the last 3 records (0x7D, 0x7E, 0x7F) */ - QS_priv_.glbFilter[15] &= 0x1FU; - } - else if (l_rx.var.flt.recId == (int8_t)QS_RX_LOC_FILTER) { - for (i = 0U; i < Q_DIM(QS_priv_.locFilter); ++i) { - QS_priv_.locFilter[i] = l_rx.var.flt.data[i]; - } - /* leave QS_ID == 0 always on */ - QS_priv_.locFilter[0] |= 0x01U; - } - else { - QS_rxReportError_(l_rx.var.flt.recId); - } - /* no need to report Done */ - break; - } - case WAIT4_OBJ_FRAME: { - i = l_rx.var.obj.kind; - if (i < (uint8_t)MAX_OBJ) { - if (l_rx.var.obj.recId == (int8_t)QS_RX_CURR_OBJ) { - QS_rxPriv_.currObj[i] = (void *)l_rx.var.obj.addr; - QS_rxReportAck_((int8_t)QS_RX_CURR_OBJ); - } - else if (l_rx.var.obj.recId == (int8_t)QS_RX_AO_FILTER) { - if (l_rx.var.obj.addr != 0U) { - int_fast16_t const filter = - (int_fast16_t)((QActive *)l_rx.var.obj.addr)->prio; - QS_locFilter_((i == 0U) - ? filter - :-filter); - QS_rxReportAck_((int8_t)QS_RX_AO_FILTER); - } - else { - QS_rxReportError_((int8_t)QS_RX_AO_FILTER); - } - } - else { - QS_rxReportError_(l_rx.var.obj.recId); - } - } - /* both SM and AO */ - else if (i == (uint8_t)SM_AO_OBJ) { - if (l_rx.var.obj.recId == (int8_t)QS_RX_CURR_OBJ) { - QS_rxPriv_.currObj[SM_OBJ] = (void *)l_rx.var.obj.addr; - QS_rxPriv_.currObj[AO_OBJ] = (void *)l_rx.var.obj.addr; - } - QS_rxReportAck_(l_rx.var.obj.recId); - } - else { - QS_rxReportError_(l_rx.var.obj.recId); - } - break; - } - case WAIT4_QUERY_FRAME: { - QS_queryCurrObj(l_rx.var.obj.kind); - break; - } - case WAIT4_EVT_FRAME: { - /* NOTE: Ack was already reported in the WAIT4_EVT_LEN state */ -#ifdef Q_UTEST - QS_onTestEvt(l_rx.var.evt.e); /* adjust the event, if needed */ -#endif /* Q_UTEST */ - i = 0U; /* use 'i' as status, 0 == success,no-recycle */ - - if (l_rx.var.evt.prio == 0U) { /* publish */ - QActive_publish_(l_rx.var.evt.e, &QS_rxPriv_, 0U); - } - else if (l_rx.var.evt.prio < QF_MAX_ACTIVE) { - if (!QACTIVE_POST_X(QActive_registry_[l_rx.var.evt.prio], - l_rx.var.evt.e, - 0U, /* margin */ - &QS_rxPriv_)) - { - /* failed QACTIVE_POST() recycles the event */ - i = 0x80U; /* failure status, no recycle */ - } - } - else if (l_rx.var.evt.prio == 255U) { /* special prio */ - /* dispatch to the current SM object */ - if (QS_rxPriv_.currObj[SM_OBJ] != (void *)0) { - /* increment the ref-ctr to simulate the situation - * when the event is just retreived from a queue. - * This is expected for the following QF_gc() call. - */ - ++l_rx.var.evt.e->refCtr_; - - QHSM_DISPATCH((QHsm *)QS_rxPriv_.currObj[SM_OBJ], - l_rx.var.evt.e, 0U); - i = 0x01U; /* success status, recycle needed */ - } - else { - i = 0x81U; /* failure status, recycle needed */ - } - } - else if (l_rx.var.evt.prio == 254U) { /* special prio */ - /* init the current SM object" */ - if (QS_rxPriv_.currObj[SM_OBJ] != (void *)0) { - /* increment the ref-ctr to simulate the situation - * when the event is just retreived from a queue. - * This is expected for the following QF_gc() call. - */ - ++l_rx.var.evt.e->refCtr_; - - QHSM_INIT((QHsm *)QS_rxPriv_.currObj[SM_OBJ], - l_rx.var.evt.e, 0U); - i = 0x01U; /* success status, recycle needed */ - } - else { - i = 0x81U; /* failure status, recycle needed */ - } - } - else if (l_rx.var.evt.prio == 253U) { /* special prio */ - /* post to the current AO */ - if (QS_rxPriv_.currObj[AO_OBJ] != (void *)0) { - if (!QACTIVE_POST_X( - (QActive *)QS_rxPriv_.currObj[AO_OBJ], - l_rx.var.evt.e, - 0U, /* margin */ - &QS_rxPriv_)) - { - /* failed QACTIVE_POST() recycles the event */ - i = 0x80U; /* failure status, no recycle */ - } - } - else { - i = 0x81U; /* failure status, recycle needed */ - } - } - else { - i = 0x81U; /* failure status, recycle needed */ - } - -#if (QF_MAX_EPOOL > 0U) - if ((i & 0x01U) != 0U) { /* recycle needed? */ - QF_gc(l_rx.var.evt.e); - } -#endif - if ((i & 0x80U) != 0U) { /* failure? */ - QS_rxReportError_((int8_t)QS_RX_EVENT); - } - else { -#ifdef Q_UTEST -#if Q_UTEST != 0 - QS_processTestEvts_(); /* process all events produced */ -#endif /* Q_UTEST != 0 */ -#endif /* Q_UTEST */ - QS_rxReportDone_((int8_t)QS_RX_EVENT); - } - break; - } - -#ifdef Q_UTEST - case WAIT4_TEST_SETUP_FRAME: { - QS_rxReportAck_((int8_t)QS_RX_TEST_SETUP); - QS_testData.tpNum = 0U; /* clear the Test-Probes */ - QS_testData.testTime = 0U; /* clear the time tick */ - /* don't clear current objects */ - QS_onTestSetup(); /* application-specific test setup */ - /* no need to report Done */ - break; - } - case WAIT4_TEST_TEARDOWN_FRAME: { - QS_rxReportAck_((int8_t)QS_RX_TEST_TEARDOWN); - QS_onTestTeardown(); /* application-specific test teardown */ - /* no need to report Done */ - break; - } - case WAIT4_TEST_CONTINUE_FRAME: { - QS_rxReportAck_((int8_t)QS_RX_TEST_CONTINUE); - QS_rxPriv_.inTestLoop = false; /* exit the QUTest loop */ - /* no need to report Done */ - break; - } - case WAIT4_TEST_PROBE_FRAME: { - QS_rxReportAck_((int8_t)QS_RX_TEST_PROBE); - Q_ASSERT_ID(815, QS_testData.tpNum - < (sizeof(QS_testData.tpBuf) / sizeof(QS_testData.tpBuf[0]))); - QS_testData.tpBuf[QS_testData.tpNum] = l_rx.var.tp; - ++QS_testData.tpNum; - /* no need to report Done */ - break; - } -#endif /* Q_UTEST */ - - case ERROR_STATE: { - /* keep ignoring all bytes until new frame */ - break; - } - default: { - QS_rxReportError_(0x47); - break; - } -} - - - - /*! callback function to reset the Target (to be implemented in the BSP) -* @static @public @memberof QS_rx -*/ - - - - /*! Callback function to execute user commands (to be implemented in BSP) -* @static @public @memberof QS_rx -*/ - - - - - - - - - - - - /*! Put one byte into the QS RX lock-free buffer -* @static @public @memberof QS_rx -*/ - - - QSCtr head = QS_rxPriv_.head + 1U; -if (head == QS_rxPriv_.end) { - head = 0U; -} -if (head != QS_rxPriv_.tail) { /* buffer NOT full? */ - QS_rxPriv_.buf[QS_rxPriv_.head] = b; - QS_rxPriv_.head = head; /* update the head to a *valid* index */ - return true; /* byte placed in the buffer */ -} -else { - return false; /* byte NOT placed in the buffer */ -} - - - - - - - - - - /*! @brief Test Probe attributes */ - { - QSFun addr; - uint32_t data; - uint8_t idx; -}; - - - - /*! @brief QUTest data */ - { - struct QS_TProbe tpBuf[16]; /*!< buffer of Test-Probes received so far */ - uint8_t tpNum; /*!< current number of Test-Probes */ - QSTimeCtr testTime; /*!< test time (tick counter) */ -}; - - - - /*! QUTest data */ - - - - /*! internal function to pause test and enter the test event loop */ - QS_beginRec_((uint_fast8_t)QS_TEST_PAUSED); -QS_endRec_(); -QS_onTestLoop(); - - - - /*! get the test probe data for the given API */ - - - uint32_t data = 0U; -uint_fast8_t i; -for (i = 0U; i < QS_testData.tpNum; ++i) { - uint_fast8_t j; - - if (QS_testData.tpBuf[i].addr == (QSFun)api) { - QS_CRIT_STAT_ - - data = QS_testData.tpBuf[i].data; - - QS_CRIT_E_(); - QS_beginRec_((uint_fast8_t)QS_TEST_PROBE_GET); - QS_TIME_PRE_(); /* timestamp */ - QS_FUN_PRE_(api); /* the calling API */ - QS_U32_PRE_(data); /* the Test-Probe data */ - QS_endRec_(); - QS_CRIT_X_(); - - QS_REC_DONE(); /* user callback (if defined) */ - - --QS_testData.tpNum; /* one less Test-Probe */ - /* move all remaining entries in the buffer up by one */ - for (j = i; j < QS_testData.tpNum; ++j) { - QS_testData.tpBuf[j] = QS_testData.tpBuf[j + 1U]; - } - break; /* we are done (Test-Probe retreived) */ - } -} -return data; - - - - /*! callback to setup a unit test inside the Target */ - - - - /*! callback to teardown after a unit test inside the Target */ - - - - /*! callback to "massage" the test event before dispatching/posting it */ - - - - - - /*! callback to examine an event that is about to be posted */ - - - - - - - - - - - - /*! callback to run the test loop */ - - - - - /*! record-ID for posting events */ - 124 - - - - - - - - - /*! internal function to process posted events during test */ - QS_TEST_PROBE_DEF(&QS_processTestEvts_) - -/* return immediately (do nothing) for Test Probe != 0 */ -QS_TEST_PROBE(return;) - -while (QPSet_notEmpty(&QF_readySet_)) { - uint_fast8_t const p = QPSet_findMax(&QF_readySet_); - QActive * const a = QActive_registry_[p]; - - /* perform the run-to-completion (RTC) step... - * 1. retrieve the event from the AO's event queue, which by this - * time must be non-empty and The "Vanialla" kernel asserts it. - * 2. dispatch the event to the AO's state machine. - * 3. determine if event is garbage and collect it if so - */ - QEvt const * const e = QActive_get_(a); - QHSM_DISPATCH(&a->super, e, a->prio); -#if (QF_MAX_EPOOL > 0U) - QF_gc(e); -#endif - if (a->eQueue.frontEvt == (QEvt *)0) { /* empty queue? */ - QPSet_remove(&QF_readySet_, p); - } -} - - - - - - - /*! QF initialization for QUTest */ - /* Clear the internal QF variables, so that the framework can start -* correctly even if the startup code fails to clear the uninitialized -* data (as is required by the C Standard). -*/ -QF_maxPool_ = 0U; -QF_intLock_ = 0U; -QF_intNest_ = 0U; - -QF_bzero(&QActive_registry_[0], sizeof(QActive_registry_)); -QF_bzero(&QF_readySet_, sizeof(QF_readySet_)); - - - - /*! stop the QF customization for QUTest */ - QS_onReset(); - - - - /*! QF_run() customization for QUTest */ - /* function dictionaries for the standard API */ -QS_FUN_DICTIONARY(&QActive_post_); -QS_FUN_DICTIONARY(&QActive_postLIFO_); -QS_FUN_DICTIONARY(&QS_processTestEvts_); - -/* produce the QS_QF_RUN trace record */ -QS_CRIT_STAT_ -QS_BEGIN_PRE_(QS_QF_RUN, 0U) -QS_END_PRE_() - -QS_processTestEvts_(); /* process all events posted so far */ -QS_onTestLoop(); /* run the test loop */ -QS_onCleanup(); /* application cleanup */ -return 0; /* return no error */ - - - - - /*! QActive active object class customization for QUTest */ - - - /*! QActive_start_() customization for QUTest -* @public @memberof QActive -*/ - - - - - - - - - - - - - Q_UNUSED_PAR(stkSto); -Q_UNUSED_PAR(stkSize); - -me->prio = (uint8_t)(prioSpec & 0xFFU); /* QF-priority of the AO */ -me->pthre = (uint8_t)(prioSpec >> 8U); /* preemption-threshold */ -QActive_register_(me); /* make QF aware of this active object */ - -QEQueue_init(&me->eQueue, qSto, qLen); /* initialize the built-in queue */ - -QHSM_INIT(&me->super, par, me->prio); /* the top-most initial tran. */ - - - - /*! Stops execution of an active object and unregisters the object -* with the framework customized for QUTest -* @public @memberof QActive -*/ - QActive_unsubscribeAll(me); /* unsubscribe from all events */ -QActive_unregister_(me); /* un-register this active object */ - - - - - /*! QTimeEvt class customization for QUTest */ - - - /*! Processes one clock tick for QUTest */ - - - - - QF_CRIT_STAT_ -QF_CRIT_E_(); - -QTimeEvt *prev = &QTimeEvt_timeEvtHead_[tickRate]; - -QS_BEGIN_NOCRIT_PRE_(QS_QF_TICK, 0U) - ++prev->ctr; - QS_TEC_PRE_(prev->ctr); /* tick ctr */ - QS_U8_PRE_(tickRate); /* tick rate */ -QS_END_NOCRIT_PRE_() - -/* is current Time Event object provided? */ -QTimeEvt *t = (QTimeEvt *)QS_rxPriv_.currObj[TE_OBJ]; -if (t != (QTimeEvt *)0) { - - /* the time event must be armed */ - Q_ASSERT_ID(810, t->ctr != 0U); - - /* temp. for volatile */ - QActive * const act = (QActive * const)(t->act); - - /* the recipient AO must be provided */ - Q_ASSERT_ID(820, act != (QActive *)0); - - /* periodic time evt? */ - if (t->interval != 0U) { - t->ctr = t->interval; /* rearm the time event */ - } - else { /* one-shot time event: automatically disarm */ - t->ctr = 0U; /* auto-disarm */ - /* mark time event 't' as NOT linked */ - t->super.refCtr_ &= (uint8_t)(~(uint8_t)QTE_IS_LINKED); - - QS_BEGIN_NOCRIT_PRE_(QS_QF_TIMEEVT_AUTO_DISARM, act->prio) - QS_OBJ_PRE_(t); /* this time event object */ - QS_OBJ_PRE_(act); /* the target AO */ - QS_U8_PRE_(tickRate); /* tick rate */ - QS_END_NOCRIT_PRE_() - } - - QS_BEGIN_NOCRIT_PRE_(QS_QF_TIMEEVT_POST, act->prio) - QS_TIME_PRE_(); /* timestamp */ - QS_OBJ_PRE_(t); /* the time event object */ - QS_SIG_PRE_(t->super.sig); /* signal of this time event */ - QS_OBJ_PRE_(act); /* the target AO */ - QS_U8_PRE_(tickRate); /* tick rate */ - QS_END_NOCRIT_PRE_() - - QF_CRIT_X_(); /* exit critical section before posting */ - - QACTIVE_POST(act, &t->super, sender); /* asserts if queue overflows */ - - QF_CRIT_E_(); -} - -/* update the linked list of time events */ -for (;;) { - t = prev->next; /* advance down the time evt. list */ - - /* end of the list? */ - if (t == (QTimeEvt *)0) { - - /* any new time events armed since the last QTimeEvt_tick_()? */ - if (QTimeEvt_timeEvtHead_[tickRate].act != (void *)0) { - - /* sanity check */ - Q_ASSERT_CRIT_(830, prev != (QTimeEvt *)0); - prev->next = (QTimeEvt *)QTimeEvt_timeEvtHead_[tickRate].act; - QTimeEvt_timeEvtHead_[tickRate].act = (void *)0; - t = prev->next; /* switch to the new list */ - } - else { - break; /* all currently armed time evts. processed */ - } - } - - /* time event scheduled for removal? */ - if (t->ctr == 0U) { - prev->next = t->next; - /* mark time event 't' as NOT linked */ - t->super.refCtr_ &= (uint8_t)(~(uint8_t)QTE_IS_LINKED); - /* do NOT advance the prev pointer */ - QF_CRIT_X_(); /* exit crit. section to reduce latency */ - - /* prevent merging critical sections, see NOTE1 below */ - QF_CRIT_EXIT_NOP(); - } - else { - prev = t; /* advance to this time event */ - QF_CRIT_X_(); /* exit crit. section to reduce latency */ - - /* prevent merging critical sections, see NOTE1 below */ - QF_CRIT_EXIT_NOP(); - } - QF_CRIT_E_(); /* re-enter crit. section to continue */ -} - -QF_CRIT_X_(); - - - - - - /*! @brief QHsmDummy class -* @class QHsmDummy -* @extends QHsm -* -* @details -* ::QHsmDummy is a test double for the role of "Orthogonal Components" -* HSM objects in QUTest unit testing. -*/ - - - /*! Constructor of the QHsmDummy HSM class -* @public @memberof QHsmDummy -*/ - static struct QHsmVtable const vtable = { /* QHsm virtual table */ - &QHsmDummy_init_, - &QHsmDummy_dispatch_ -#ifdef Q_SPY - ,&QHsm_getStateHandler_ -#endif -}; -/* superclass' ctor */ -QHsm_ctor(&me->super, Q_STATE_CAST(0)); -me->super.vptr = &vtable; /* hook the vptr */ - - - - /*! override for QHsm_init_() -* @private @memberof QHsmDummy -*/ - - - - - - - Q_UNUSED_PAR(par); - -#ifdef Q_SPY -if ((QS_priv_.flags & 0x01U) == 0U) { - QS_priv_.flags |= 0x01U; - QS_FUN_DICTIONARY(&QHsm_top); -} -#endif - -QS_CRIT_STAT_ -QS_BEGIN_PRE_(QS_QEP_STATE_INIT, qs_id) - QS_OBJ_PRE_(me); /* this state machine object */ - QS_FUN_PRE_(me->state.fun); /* the source state */ - QS_FUN_PRE_(me->temp.fun); /* the target of the initial transition */ -QS_END_PRE_() - - - - /*! override for QHsm_dispatch_() -* @private @memberof QHsmDummy -*/ - - - - - - - QS_CRIT_STAT_ -QS_BEGIN_PRE_(QS_QEP_DISPATCH, qs_id) - QS_TIME_PRE_(); /* time stamp */ - QS_SIG_PRE_(e->sig); /* the signal of the event */ - QS_OBJ_PRE_(me); /* this state machine object */ - QS_FUN_PRE_(me->state.fun); /* the current state */ -QS_END_PRE_() - - - - - /*! @brief QActiveDummy Object class -* @class QActiveDummy -* @extends QActive -* -* @details -* QActiveDummy is a test double for the role of collaborating active -* objects in QUTest unit testing. -*/ - - - /*! Constructor of the QActiveDummy Active Object class -* @public @memberof QActiveDummy -*/ - static QActiveVtable const vtable = { /* QActive virtual table */ - { &QActiveDummy_init_, - &QActiveDummy_dispatch_ -#ifdef Q_SPY - ,&QHsm_getStateHandler_ -#endif - }, - &QActiveDummy_start_, - &QActiveDummy_post_, - &QActiveDummy_postLIFO_ -}; -/* superclass' ctor */ -QActive_ctor(&me->super, Q_STATE_CAST(0)); -me->super.super.vptr = &vtable.super; /* hook the vptr */ - - - - /*! override for QHsm_init_() -* @private @memberof QActiveDummy -*/ - - - - - - - Q_UNUSED_PAR(qs_id); - -QHsmDummy_init_(me, par, ((QActive const *)me)->prio); - - - - /*! override for QHsm_dispatch_() -* @private @memberof QActiveDummy -*/ - - - - - - - Q_UNUSED_PAR(qs_id); - -QHsmDummy_dispatch_(me, e, ((QActive const *)me)->prio); - - - - /*! override for QActive_start_() -* @private @memberof QActiveDummy -*/ - - - - - - - - - - - - - - - /* No special preconditions for checking parameters to allow starting -* dummy AOs the exact same way as the real counterparts. -*/ -Q_UNUSED_PAR(qSto); -Q_UNUSED_PAR(qLen); -Q_UNUSED_PAR(stkSto); -Q_UNUSED_PAR(stkSize); - -me->prio = (uint8_t)(prioSpec & 0xFFU); /* QF-priority of the AO */ -me->pthre = (uint8_t)(prioSpec >> 8U); /* preemption-threshold */ -QActive_register_(me); /* make QF aware of this active object */ - -/* the top-most initial tran. (virtual) */ -QHSM_INIT(&me->super, par, me->prio); -//QS_FLUSH(); - - - - /*! override for QActive_post_() -* @private @memberof QActiveDummy -*/ - - - - - - - - - QS_TEST_PROBE_DEF(&QActive_post_) - -/* test-probe#1 for faking queue overflow */ -bool status = true; -QS_TEST_PROBE_ID(1, - status = false; - if (margin == QF_NO_MARGIN) { - /* fake assertion Mod=qf_actq,Loc=110 */ - Q_onAssert("qf_actq", 110); - } -) - -QF_CRIT_STAT_ -QF_CRIT_E_(); - -/* is it a dynamic event? */ -if (e->poolId_ != 0U) { - QEvt_refCtr_inc_(e); /* increment the reference counter */ -} - -uint_fast8_t const rec = (status ? (uint_fast8_t)QS_QF_ACTIVE_POST - : (uint_fast8_t)QS_QF_ACTIVE_POST_ATTEMPT); -QS_BEGIN_NOCRIT_PRE_(rec, me->prio) - QS_TIME_PRE_(); /* timestamp */ - QS_OBJ_PRE_(sender); /* the sender object */ - QS_SIG_PRE_(e->sig); /* the signal of the event */ - QS_OBJ_PRE_(me); /* this active object */ - QS_2U8_PRE_(e->poolId_, e->refCtr_); /* pool Id & refCtr of the evt */ - QS_EQC_PRE_(0U); /* number of free entries */ - QS_EQC_PRE_(margin); /* margin requested */ -QS_END_NOCRIT_PRE_() - -/* callback to examine the posted event under the same conditions -* as producing the #QS_QF_ACTIVE_POST trace record, which are: -* the local filter for this AO ('me->prio') is set -*/ -if ((QS_priv_.locFilter[me->prio >> 3U] - & (1U << (me->prio & 7U))) != 0U) -{ - QS_onTestPost(sender, me, e, status); -} -QF_CRIT_X_(); - -/* recycle the event immediately, because it was not really posted */ -#if (QF_MAX_EPOOL > 0U) -QF_gc(e); -#endif - -return status; /* the event is "posted" correctly */ - - - - /*! override for QActive_postLIFO_() -* @private @memberof QActiveDummy -*/ - - - - - QS_TEST_PROBE_DEF(&QActive_postLIFO_) - -/* test-probe#1 for faking queue overflow */ -QS_TEST_PROBE_ID(1, - /* fake assertion Mod=qf_actq,Loc=210 */ - Q_onAssert("qf_actq", 210); -) - -QF_CRIT_STAT_ -QF_CRIT_E_(); - -/* is it a dynamic event? */ -if (e->poolId_ != 0U) { - QEvt_refCtr_inc_(e); /* increment the reference counter */ -} - -QS_BEGIN_NOCRIT_PRE_(QS_QF_ACTIVE_POST_LIFO, me->prio) - QS_TIME_PRE_(); /* timestamp */ - QS_SIG_PRE_(e->sig); /* the signal of this event */ - QS_OBJ_PRE_(me); /* this active object */ - QS_2U8_PRE_(e->poolId_, e->refCtr_); /* pool Id & refCtr of the evt */ - QS_EQC_PRE_(0U); /* number of free entries */ - QS_EQC_PRE_(0U); /* min number of free entries */ -QS_END_NOCRIT_PRE_() - -/* callback to examine the posted event under the same conditions -* as producing the #QS_QF_ACTIVE_POST trace record, which are: -* the local filter for this AO ('me->prio') is set -*/ -if ((QS_priv_.locFilter[me->prio >> 3U] - & (1U << (me->prio & 7U))) != 0U) -{ - QS_onTestPost((QActive *)0, me, e, true); -} - -QF_CRIT_X_(); - -/* recycle the event immediately, because it was not really posted */ -#if (QF_MAX_EPOOL > 0U) -QF_gc(e); -#endif - - - - - - - - - - /*! @brief QV cooperative kernel -* @class QV -*/ - { - uint8_t dummy; /*< dummy attribute */ -} QV; - - - - /*! QV idle callback (customized in BSPs) -* @static @public @memberof QV -* -* @details -* QV_onIdle() is called by the cooperative QV kernel (from QF_run()) when -* the scheduler detects that no events are available for active objects -* (the idle condition). This callback gives the application an opportunity -* to enter a power-saving CPU mode, or perform some other idle processing -* (such as QS software tracing output). -* -* @note -* QV_onIdle() is invoked with interrupts **DISABLED** because the idle -* condition can be asynchronously changed at any time by an interrupt. -* QV_onIdle() MUST enable the interrupts internally, but not before -* putting the CPU into the low-power mode. (Ideally, enabling interrupts and -* low-power mode should happen atomically). At the very least, the function -* MUST enable interrupts, otherwise interrupts will remain disabled -* permanently. -*/ - - - - - - - /*! QF initialization for QV */ - #if (QF_MAX_EPOOL > 0U) -QF_maxPool_ = 0U; -#endif - -QF_bzero(&QTimeEvt_timeEvtHead_[0], sizeof(QTimeEvt_timeEvtHead_)); -QF_bzero(&QActive_registry_[0], sizeof(QActive_registry_)); -QF_bzero(&QF_readySet_, sizeof(QF_readySet_)); - -#ifdef QV_INIT -QV_INIT(); /* port-specific initialization of the QV kernel */ -#endif - - - - /*! stop the QF customization for QV -* -* @sa QF_onCleanup() -*/ - QF_onCleanup(); /* application-specific cleanup callback */ -/* nothing else to do for the cooperative QV kernel */ - - - - /*! QF_run() customization for QV kernel */ - #ifdef Q_SPY -/* produce the QS_QF_RUN trace record */ -QF_INT_DISABLE(); -QS_beginRec_((uint_fast8_t)QS_QF_RUN); -QS_endRec_(); -QF_INT_ENABLE(); -#endif /* Q_SPY */ - -QF_onStartup(); /* application-specific startup callback */ - -QF_INT_DISABLE(); - -#ifdef QV_START -QV_START(); /* port-specific startup of the QV kernel */ -#endif - -#if (defined QF_ON_CONTEXT_SW) || (defined Q_SPY) -uint8_t pprev = 0U; /* previously used priority */ -#endif /* (defined QF_ON_CONTEXT_SW) || (defined Q_SPY) */ - -for (;;) { /* QV event loop... */ - - /* find the maximum priority AO ready to run */ - if (QPSet_notEmpty(&QF_readySet_)) { - uint8_t const p = (uint8_t)QPSet_findMax(&QF_readySet_); - QActive * const a = QActive_registry_[p]; - -#if (defined QF_ON_CONTEXT_SW) || (defined Q_SPY) - QS_BEGIN_NOCRIT_PRE_(QS_SCHED_NEXT, p) - QS_TIME_PRE_(); /* timestamp */ - QS_2U8_PRE_(p, /* priority of the scheduled AO */ - pprev); /* previous priority */ - QS_END_NOCRIT_PRE_() - -#ifdef QF_ON_CONTEXT_SW - QF_onContextSw(((pprev != 0U) - ? QActive_registry_[pprev] - : (QActive *)0), a); -#endif /* QF_ON_CONTEXT_SW */ - - pprev = p; /* update previous priority */ -#endif /* (defined QF_ON_CONTEXT_SW) || (defined Q_SPY) */ - - QF_INT_ENABLE(); - - /* perform the run-to-completion (RTC) step... - * 1. retrieve the event from the AO's event queue, which - * by this time must be non-empty (and QV asserts it). - * 2. dispatch the event to the AO's state machine. - * 3. determine if event is garbage and collect it if so - */ - QEvt const * const e = QActive_get_(a); - QHSM_DISPATCH(&a->super, e, a->prio); -#if (QF_MAX_EPOOL > 0U) - QF_gc(e); -#endif - QF_INT_DISABLE(); - - if (a->eQueue.frontEvt == (QEvt *)0) { /* empty queue? */ - QPSet_remove(&QF_readySet_, p); - } - } - else { /* no AO ready to run --> idle */ -#if (defined QF_ON_CONTEXT_SW) || (defined Q_SPY) - if (pprev != 0U) { - QS_BEGIN_NOCRIT_PRE_(QS_SCHED_IDLE, pprev) - QS_TIME_PRE_(); /* timestamp */ - QS_U8_PRE_(pprev); /* previous priority */ - QS_END_NOCRIT_PRE_() - -#ifdef QF_ON_CONTEXT_SW - QF_onContextSw(QActive_registry_[pprev], (QActive *)0); -#endif /* QF_ON_CONTEXT_SW */ - - pprev = 0U; /* update previous priority */ - } -#endif /* (defined QF_ON_CONTEXT_SW) || (defined Q_SPY) */ - - /* QV_onIdle() must be called with interrupts DISABLED - * because the determination of the idle condition (all event - * queues empty) can change at any time by an interrupt posting - * events to a queue. - * - * NOTE: QV_onIdle() MUST enable interrupts internally, - * ideally at the same time as putting the CPU into a power- - * saving mode. - */ - QV_onIdle(); - - QF_INT_DISABLE(); /* disable interrupts before looping back */ - } -} -#ifdef __GNUC__ /* GNU compiler? */ -return 0; -#endif - - - - - /*! QActive active object class customization for QV */ - - - /*! Starts execution of an active object and registers the object -* with the framework customized for QV -*/ - - - - - - - - - - - - - Q_UNUSED_PAR(stkSto); /* not needed in QV */ -Q_UNUSED_PAR(stkSize); /* not needed in QV */ - -/*! @pre Stack storage must not be provided because the QV kernel -* does not need per-AO stacks. -*/ -Q_REQUIRE_ID(500, stkSto == (void *)0); - -me->prio = (uint8_t)(prioSpec & 0xFFU); /* QF-priority of the AO */ -me->pthre = (uint8_t)(prioSpec >> 8U); /* preemption-threshold */ -QActive_register_(me); /* make QF aware of this active object */ - -QEQueue_init(&me->eQueue, qSto, qLen); /* init the built-in queue */ - -QHSM_INIT(&me->super, par, me->prio); /* top-most initial tran. */ -QS_FLUSH(); /* flush the trace buffer to the host */ - - - - - - - - /*! QV scheduler lock status (not needed in QV) */ - - - - /*! QV scheduler locking (not needed in QV) */ - - - ((void)0) - - - - /*! QV scheduler unlocking (not needed in QV) */ - ((void)0) - - - - * QV native event queue waiting - - - \ - Q_ASSERT_ID(0, (me_)->eQueue.frontEvt != (QEvt *)0) - - - - /*! QV native event queue signaling */ - - - \ - QPSet_insert(&QF_readySet_, (uint_fast8_t)(me_)->prio) - - - - - - - - - /*! @brief QK preemptive non-blocking kernel -* @class QK -*/ - { - uint8_t volatile actPrio; /*!< QF prio of the active AO */ - uint8_t volatile nextPrio; /*!< QF prio of the next AO to execute */ - uint8_t volatile actThre; /*!< active preemption-threshold */ - uint8_t volatile lockCeil; /*!< lock preemption-ceiling (0==no-lock) */ - uint8_t volatile lockHolder; /*!< QF prio of the AO holding the lock */ -} QK; - - - - /*! attributes of the QK kernel */ - - - - /*! QK selective scheduler lock -* -* @details -* This function locks the QK scheduler to the specified ceiling. -* -* @param[in] ceiling preemption ceiling to which the QK scheduler -* needs to be locked -* -* @returns -* The previous QK Scheduler lock status, which is to be used to unlock -* the scheduler by restoring its previous lock status in -* QK_schedUnlock(). -* -* @note -* QK_schedLock() must be always followed by the corresponding -* QK_schedUnlock(). -* -* @sa QK_schedUnlock() -* -* @usage -* The following example shows how to lock and unlock the QK scheduler: -* @include qk_lock.c -*/ - - - QF_CRIT_STAT_ -QF_CRIT_E_(); - -/*! @pre The QK scheduler lock cannot be called from an ISR */ -Q_REQUIRE_ID(600, !QK_ISR_CONTEXT_()); - -/* first store the previous lock prio */ -QSchedStatus stat; -if (ceiling > QK_attr_.lockCeil) { /* raising the lock ceiling? */ - QS_BEGIN_NOCRIT_PRE_(QS_SCHED_LOCK, 0U) - QS_TIME_PRE_(); /* timestamp */ - /* the previous lock ceiling & new lock ceiling */ - QS_2U8_PRE_(QK_attr_.lockCeil, (uint8_t)ceiling); - QS_END_NOCRIT_PRE_() - - /* previous status of the lock */ - stat = (QSchedStatus)QK_attr_.lockHolder; - stat |= (QSchedStatus)QK_attr_.lockCeil << 8U; - - /* new status of the lock */ - QK_attr_.lockHolder = QK_attr_.actPrio; - QK_attr_.lockCeil = (uint8_t)ceiling; -} -else { - stat = 0xFFU; /* scheduler not locked */ -} -QF_CRIT_X_(); - -return stat; /* return the status to be saved in a stack variable */ - - - - /*! QK selective scheduler unlock -* -* @details -* This function unlocks the QK scheduler to the previous status. -* -* @param[in] stat previous QK Scheduler lock status returned from -* QK_schedLock() -* @note -* QK_schedUnlock() must always follow the corresponding -* QK_schedLock(). -* -* @sa QK_schedLock() -* -* @usage -* The following example shows how to lock and unlock the QK scheduler: -* @include qk_lock.c -*/ - - - /* has the scheduler been actually locked by the last QK_schedLock()? */ -if (stat != 0xFFU) { - uint8_t const lockCeil = QK_attr_.lockCeil; - uint8_t const prevCeil = (uint8_t)(stat >> 8U); - QF_CRIT_STAT_ - QF_CRIT_E_(); - - /*! @pre The scheduler cannot be unlocked: - * - from the ISR context; and - * - the current lock ceiling must be greater than the previous - */ - Q_REQUIRE_ID(700, (!QK_ISR_CONTEXT_()) - && (lockCeil > prevCeil)); - - QS_BEGIN_NOCRIT_PRE_(QS_SCHED_UNLOCK, 0U) - QS_TIME_PRE_(); /* timestamp */ - // current lock ceiling (old), previous lock ceiling (new) */ - QS_2U8_PRE_(lockCeil, prevCeil); - QS_END_NOCRIT_PRE_() - - /* restore the previous lock ceiling and lock holder */ - QK_attr_.lockCeil = prevCeil; - QK_attr_.lockHolder = (uint8_t)(stat & 0xFFU); - - /* find if any AOs should be run after unlocking the scheduler */ - if (QK_sched_() != 0U) { /* preemption needed? */ - QK_activate_(); /* activate any unlocked AOs */ - } - - QF_CRIT_X_(); -} - - - - /*! QK idle callback (customized in BSPs for QK) -* @static @public @memberof QK -* -* @details -* QK_onIdle() is called continuously by the QK idle loop. This callback -* gives the application an opportunity to enter a power-saving CPU mode, -* or perform some other idle processing. -* -* @note -* QK_onIdle() is invoked with interrupts enabled and must also return with -* interrupts enabled. -*/ - - - - - - - /*! QF initialization for QK */ - #if (QF_MAX_EPOOL > 0U) -QF_maxPool_ = 0U; -#endif - -QF_bzero(&QTimeEvt_timeEvtHead_[0], sizeof(QTimeEvt_timeEvtHead_)); -QF_bzero(&QActive_registry_[0], sizeof(QActive_registry_)); -QF_bzero(&QF_readySet_, sizeof(QF_readySet_)); -QF_bzero(&QK_attr_, sizeof(QK_attr_)); - -/* setup the QK scheduler as initially locked and not running */ -QK_attr_.lockCeil = (QF_MAX_ACTIVE + 1U); /* scheduler locked */ - -/* QK idle AO object (const in ROM) */ -static QActive const idle_ao = { (struct QHsmVtable const *)0 }; - -/* register the idle AO object (cast 'const' away) */ -QActive_registry_[0] = (QActive *)&idle_ao; - -#ifdef QK_INIT -QK_INIT(); /* port-specific initialization of the QK kernel */ -#endif - - - - /*! stop the QF customization for QK -* -* @sa QF_onCleanup() -*/ - QF_onCleanup(); /* application-specific cleanup callback */ -/* nothing else to do for the preemptive QK kernel */ - - - - /*! QF_run() customization for QK kernel */ - #ifdef Q_SPY -/* produce the QS_QF_RUN trace record */ -QF_INT_DISABLE(); -QS_beginRec_((uint_fast8_t)QS_QF_RUN); -QS_endRec_(); -QF_INT_ENABLE(); -#endif /* Q_SPY */ - -QF_onStartup(); /* application-specific startup callback */ - -QF_INT_DISABLE(); - -QK_attr_.lockCeil = 0U; /* unlock the QK scheduler */ - -/* activate AOs to process events posted so far */ -if (QK_sched_() != 0U) { - QK_activate_(); -} - -#ifdef QK_START -QK_START(); /* port-specific startup of the QK kernel */ -#endif - -QF_INT_ENABLE(); -for (;;) { /* QK idle loop... */ - QK_onIdle(); /* application-specific QK on-idle callback */ -} - -#ifdef __GNUC__ -return 0; -#endif - - - - - /*! QActive active object class customization for QK */ - - - /*! Starts execution of an active object and registers the object -* with the framework customized for QK -*/ - - - - - - - - - - - - - Q_UNUSED_PAR(stkSto); /* not needed in QK */ -Q_UNUSED_PAR(stkSize); /* not needed in QK */ - -/*! @pre AO cannot be started from an ISR and the stack storage must -* NOT be provided because the QK kernel does not need per-AO stacks. -*/ -Q_REQUIRE_ID(300, (!QK_ISR_CONTEXT_()) - && (stkSto == (void *)0)); - -me->prio = (uint8_t)(prioSpec & 0xFFU); /* QF-priority of the AO */ -me->pthre = (uint8_t)(prioSpec >> 8U); /* preemption-threshold */ -QActive_register_(me); /* make QF aware of this active object */ - -QEQueue_init(&me->eQueue, qSto, qLen); /* init the built-in queue */ - -QHSM_INIT(&me->super, par, me->prio); /* top-most initial tran. */ -QS_FLUSH(); /* flush the trace buffer to the host */ - -/* See if this AO needs to be scheduled if QK is already running */ -QF_CRIT_STAT_ -QF_CRIT_E_(); -if (QK_sched_() != 0U) { /* activation needed? */ - QK_activate_(); -} -QF_CRIT_X_(); - - - - - - - /*! QK scheduler finds the highest-priority AO ready to run -* @static @private @memberof QK -* -* @details -* The QK scheduler finds out the priority of the highest-priority AO -* that (1) has events to process and (2) has priority that is above the -* current priority. -* -* @returns -* The QF-priority of the next active object to activate, or zero -* if no activation of AO is needed. -* -* @attention -* QK_sched_() must be always called with interrupts **disabled** and -* returns with interrupts **disabled**. -*/ - uint_fast8_t p; - -if (QPSet_isEmpty(&QF_readySet_)) { - p = 0U; /* no activation needed */ -} -else { - /* find the highest-prio AO with non-empty event queue */ - p = QPSet_findMax(&QF_readySet_); - - /* is the AO's priority below the active preemption-threshold? */ - if (p <= QK_attr_.actThre) { - p = 0U; /* no activation needed */ - } - /* is the AO's priority below the lock-ceiling? */ - else if (p <= QK_attr_.lockCeil) { - p = 0U; /* no activation needed */ - } - else { - QK_attr_.nextPrio = (uint8_t)p; /* next AO to run */ - } -} -return p; - - - - /*! QK activator activates the next active object. The activated AO preempts -* the currently executing AOs. -* @static @private @memberof QK -* -* @details -* QK_activate_() activates ready-to run AOs that are above the initial -* preemption-threshold. -* -* @attention -* QK_activate_() must be always called with interrupts **disabled** and -* returns with interrupts **disabled**. -*/ - uint8_t const prio_in = QK_attr_.actPrio; /* saved initial priority */ -uint8_t p = QK_attr_.nextPrio; /* next prio to run */ -QK_attr_.nextPrio = 0U; /* clear for the next time */ - -/* QK_attr_.actPrio and QK_attr_.nextPrio must be in range */ -Q_REQUIRE_ID(500, (prio_in <= QF_MAX_ACTIVE) - && (0U < p) && (p <= QF_MAX_ACTIVE)); - -#if (defined QF_ON_CONTEXT_SW) || (defined Q_SPY) -uint8_t pprev = prio_in; -#endif /* QF_ON_CONTEXT_SW || Q_SPY */ - -/* loop until no more ready-to-run AOs of higher pthre than the initial */ -QActive *a; -do { - a = QActive_registry_[p]; /* obtain the pointer to the AO */ - Q_ASSERT_ID(505, a != (QActive *)0); /* the AO must be registered */ - - /* set new active priority and preemption-threshold */ - QK_attr_.actPrio = p; - QK_attr_.actThre = a->pthre; - -#if (defined QF_ON_CONTEXT_SW) || (defined Q_SPY) - if (p != pprev) { /* changing threads? */ - - QS_BEGIN_NOCRIT_PRE_(QS_SCHED_NEXT, p) - QS_TIME_PRE_(); /* timestamp */ - QS_2U8_PRE_(p, /* priority of the scheduled AO */ - pprev); /* previous priority */ - QS_END_NOCRIT_PRE_() - -#ifdef QF_ON_CONTEXT_SW - QF_onContextSw(((pprev != 0U) - ? QActive_registry_[pprev] - : (QActive *)0), a); -#endif /* QF_ON_CONTEXT_SW */ - - pprev = p; /* update previous priority */ - } -#endif /* QF_ON_CONTEXT_SW || Q_SPY */ - - QF_INT_ENABLE(); /* unconditionally enable interrupts */ - - /* perform the run-to-completion (RTC) step... - * 1. retrieve the event from the AO's event queue, which by this - * time must be non-empty and QActive_get_() asserts it. - * 2. dispatch the event to the AO's state machine. - * 3. determine if event is garbage and collect it if so - */ - QEvt const * const e = QActive_get_(a); - QHSM_DISPATCH(&a->super, e, p); -#if (QF_MAX_EPOOL > 0U) - QF_gc(e); -#endif - - /* determine the next highest-priority AO ready to run... */ - QF_INT_DISABLE(); /* unconditionally disable interrupts */ - - if (a->eQueue.frontEvt == (QEvt *)0) { /* empty queue? */ - QPSet_remove(&QF_readySet_, p); - } - - if (QPSet_isEmpty(&QF_readySet_)) { - p = 0U; /* no activation needed */ - } - else { - /* find new highest-prio AO ready to run... */ - p = (uint8_t)QPSet_findMax(&QF_readySet_); - - /* is the new priority below the initial preemption-threshold? */ - if (p <= QActive_registry_[prio_in]->pthre) { - p = 0U; /* no activation needed */ - } - /* is the AO's priority below the lock preemption-ceiling? */ - else if (p <= QK_attr_.lockCeil) { - p = 0U; /* no activation needed */ - } - else { - Q_ASSERT_ID(510, p <= QF_MAX_ACTIVE); - } - } -} while (p != 0U); - -/* restore the active priority and preemption-threshold */ -QK_attr_.actPrio = prio_in; -QK_attr_.actThre = QActive_registry_[prio_in]->pthre; - -#if (defined QF_ON_CONTEXT_SW) || (defined Q_SPY) -if (prio_in != 0U) { /* resuming an active object? */ - a = QActive_registry_[prio_in]; /* pointer to the preempted AO */ - - QS_BEGIN_NOCRIT_PRE_(QS_SCHED_NEXT, prio_in) - QS_TIME_PRE_(); /* timestamp */ - /* priority of the resumed AO, previous priority */ - QS_2U8_PRE_(prio_in, pprev); - QS_END_NOCRIT_PRE_() -} -else { /* resuming priority==0 --> idle */ - a = (QActive *)0; /* QK idle loop */ - - QS_BEGIN_NOCRIT_PRE_(QS_SCHED_IDLE, pprev) - QS_TIME_PRE_(); /* timestamp */ - QS_U8_PRE_(pprev); /* previous priority */ - QS_END_NOCRIT_PRE_() -} - -#ifdef QF_ON_CONTEXT_SW -QF_onContextSw(QActive_registry_[pprev], a); -#endif /* QF_ON_CONTEXT_SW */ - -#endif /* QF_ON_CONTEXT_SW || Q_SPY */ - - - - - - - - /*! Internal macro that reports the execution context (ISR vs. thread) -* -* @returns true if the code executes in the ISR context and false -* otherwise -*/ - (QF_intNest_ != 0U) - - - - /*! QK scheduler lock status */ - QSchedStatus lockStat_; - - - - /*! QK selective scheduler locking */ - - - do { \ - if (QK_ISR_CONTEXT_()) { \ - lockStat_ = 0xFFU; \ - } else { \ - lockStat_ = QK_schedLock((ceil_)); \ - } \ -} while (false) - - - - /*! QK selective scheduler unlocking */ - do { \ - if (lockStat_ != 0xFFU) { \ - QK_schedUnlock(lockStat_); \ - } \ -} while (false) - - - - /*! QK native event queue waiting */ - - - \ - (Q_ASSERT_ID(110, (me_)->eQueue.frontEvt != (QEvt *)0)) - - - - /*! QK native event queue signaling */ - - - do { \ - QPSet_insert(&QF_readySet_, (uint_fast8_t)(me_)->prio); \ - if (!QK_ISR_CONTEXT_()) { \ - if (QK_sched_() != 0U) { \ - QK_activate_(); \ - } \ - } \ -} while (false) - - - - - - - - - /*! QXK idle callback (customized in BSPs for QXK) -* @static @public @memberof QXK -* -* @details -* QXK_onIdle() is called continuously by the QXK idle thread. This callback -* gives the application an opportunity to enter a power-saving CPU mode, -* or perform some other idle processing. -* -* @note -* QXK_onIdle() is invoked with interrupts enabled and must also return with -* interrupts enabled. -*/ - - - - /*! QXK Scheduler lock -* @static @public @memberof QXK -* -* @details -* This function locks the QXK scheduler to the specified ceiling. -* -* @param[in] ceiling preemption ceiling to which the QXK scheduler -* needs to be locked -* -* @returns -* The previous QXK Scheduler lock status, which is to be used to unlock -* the scheduler by restoring its previous lock status in -* QXK_schedUnlock(). -* -* @note -* A QXK scheduler can be locked from both basic threads (AOs) and -* extended threads and the scheduler locks can nest. -* -* @note -* QXK_schedLock() must be always followed by the corresponding -* QXK_schedUnlock(). -* -* @attention -* QXK will fire an assertion if a thread holding the lock attempts -* to block. -* -* @sa QXK_schedUnlock() -* -* @usage -* The following example shows how to lock and unlock the QXK scheduler: -* @include qxk_lock.c -*/ - - - QF_CRIT_STAT_ -QF_CRIT_E_(); - -/*! @pre The QXK scheduler lock cannot be called from an ISR */ -Q_REQUIRE_ID(400, !QXK_ISR_CONTEXT_()); - -QSchedStatus stat; /* saved lock status to be returned */ - -/* is the lock ceiling being raised? */ -if (ceiling > (uint_fast8_t)QXK_attr_.lockCeil) { - QS_BEGIN_NOCRIT_PRE_(QS_SCHED_LOCK, 0U) - QS_TIME_PRE_(); /* timestamp */ - /* the previous lock ceiling & new lock ceiling */ - QS_2U8_PRE_(QXK_attr_.lockCeil, (uint8_t)ceiling); - QS_END_NOCRIT_PRE_() - - /* previous status of the lock */ - stat = (QSchedStatus)QXK_attr_.lockHolder; - stat |= (QSchedStatus)QXK_attr_.lockCeil << 8U; - - /* new status of the lock */ - QXK_attr_.lockHolder = (QXK_attr_.curr != (QActive *)0) - ? QXK_attr_.curr->prio - : 0U; - QXK_attr_.lockCeil = (uint8_t)ceiling; -} -else { - stat = 0xFFU; /* scheduler not locked */ -} -QF_CRIT_X_(); - -return stat; /* return the status to be saved in a stack variable */ - - - - /*! QXK Scheduler unlock -* @static @public @memberof QXK -* -* @details -* This function unlocks the QXK scheduler to the previous status. -* -* @param[in] stat previous QXK Scheduler lock status returned from -* QXK_schedLock() -* -* @note -* A QXK scheduler can be locked from both basic threads (AOs) and -* extended threads and the scheduler locks can nest. -* -* @note -* QXK_schedUnlock() must always follow the corresponding QXK_schedLock(). -* -* @sa QXK_schedLock() -* -* @usage -* The following example shows how to lock and unlock the QXK scheduler: -* @include qxk_lock.c -*/ - - - /* has the scheduler been actually locked by the last QXK_schedLock()? */ -if (stat != 0xFFU) { - uint8_t const lockCeil = QXK_attr_.lockCeil; - uint8_t const prevCeil = (uint8_t)(stat >> 8U); - QF_CRIT_STAT_ - QF_CRIT_E_(); - - /*! @pre The scheduler cannot be unlocked: - * - from the ISR context; and - * - the current lock ceiling must be greater than the previous - */ - Q_REQUIRE_ID(500, (!QXK_ISR_CONTEXT_()) - && (lockCeil > prevCeil)); - - QS_BEGIN_NOCRIT_PRE_(QS_SCHED_UNLOCK, 0U) - QS_TIME_PRE_(); /* timestamp */ - /* ceiling before unlocking & prio after unlocking */ - QS_2U8_PRE_(lockCeil, prevCeil); - QS_END_NOCRIT_PRE_() - - /* restore the previous lock ceiling and lock holder */ - QXK_attr_.lockCeil = prevCeil; - QXK_attr_.lockHolder = (uint8_t)(stat & 0xFFU); - - /* find if any threads should be run after unlocking the scheduler */ - if (QXK_sched_() != 0U) { /* activation needed? */ - QXK_activate_(); /* synchronously activate basic-thred(s) */ - } - - QF_CRIT_X_(); -} - - - - /*! timeout signals for extended threads */ - { - QXK_DELAY_SIG = 1, - QXK_TIMEOUT_SIG -}; - - - - - - - /*! QF initialization for QXK */ - #if (QF_MAX_EPOOL > 0U) -QF_maxPool_ = 0U; -#endif - -QF_bzero(&QTimeEvt_timeEvtHead_[0], sizeof(QTimeEvt_timeEvtHead_)); -QF_bzero(&QActive_registry_[0], sizeof(QActive_registry_)); -QF_bzero(&QF_readySet_, sizeof(QF_readySet_)); -QF_bzero(&QXK_attr_, sizeof(QXK_attr_)); - -/* setup the QXK scheduler as initially locked and not running */ -QXK_attr_.lockCeil = (QF_MAX_ACTIVE + 1U); /* scheduler locked */ - -/* QXK idle AO object (const in ROM) */ -static QActive const idle_ao = { (struct QHsmVtable const *)0 }; - -/* register the idle AO object (cast 'const' away) */ -QActive_registry_[0] = (QActive *)&idle_ao; -QXK_attr_.prev = QActive_registry_[0]; - -#ifdef QXK_INIT -QXK_INIT(); /* port-specific initialization of the QXK kernel */ -#endif - - - - /*! stop the QF customization for QXK -* -* @sa QF_onCleanup() -*/ - QF_onCleanup(); /* application-specific cleanup callback */ -/* nothing else to do for the dual-mode QXK kernel */ - - - - /*! QF_run() customization for QXK kernel */ - #ifdef Q_SPY -QS_SIG_DICTIONARY(QXK_DELAY_SIG, (void *)0); -QS_SIG_DICTIONARY(QXK_TIMEOUT_SIG, (void *)0); - -/* produce the QS_QF_RUN trace record */ -QF_INT_DISABLE(); -QS_beginRec_((uint_fast8_t)QS_QF_RUN); -QS_endRec_(); -QF_INT_ENABLE(); -#endif /* Q_SPY */ - -QF_onStartup(); /* application-specific startup callback */ - -QF_INT_DISABLE(); - -QXK_attr_.lockCeil = 0U; /* unlock the QXK scheduler */ -/* activate AOs to process events posted so far */ -if (QXK_sched_() != 0U) { - QXK_activate_(); -} - -#ifdef QXK_START -QXK_START(); /* port-specific startup of the QXK kernel */ -#endif - -QF_INT_ENABLE(); -for (;;) { /* QXK idle loop... */ - QXK_onIdle(); /* application-specific QXK idle callback */ -} - -#ifdef __GNUC__ -return 0; -#endif - - - - - /*! @brief eXtended (blocking) thread of the QXK preemptive kernel -* @class QXThread -* @extends QActive -* -* @details -* ::QXThread represents the eXtended (blocking) thread of the QXK -* kernel. Each extended thread in the application must be represented -* by the corresponding ::QXThread instance -* -* @note -* Typically, ::QXThread is instantiated directly in the application code. -* The customization of the thread occurs in the QXThread_ctor(), where you -* provide the thread-handler function as the parameter. -* -* @usage -* The following example illustrates how to instantiate and use an extended -* thread in your application. -* @include qxk_thread.c -*/ - - - /*! time event to handle blocking timeouts */ - - - - /*! dummy static to force generation of "struct QXThread" */ - - - - /*! constructor of an extended-thread -* @public @memberof QXThread -* -* @details -* Performs the first step of QXThread initialization by assigning the -* thread-handler function and the tick rate at which it will handle -* the timeouts. -* -* @param[in,out] me current instance pointer (see @ref oop) -* @param[in] handler the thread-handler function -* @param[in] tickRate the ticking rate for timeouts in this thread -* (see QXThread_delay() and QTIMEEVT_TICK_X()) -* -* @note -* Must be called only ONCE before QXTHREAD_START(). -* -* @usage -* The following example illustrates how to invoke QXThread_ctor() in the -* main() function -* -* @include -* qxk_thread_ctor.c -*/ - - - - - static QXThreadVtable const vtable = { /* QXThread virtual table */ - { &QXThread_init_, /* not used in QXThread */ - &QXThread_dispatch_ /* not used in QXThread */ -#ifdef Q_SPY - ,&QHsm_getStateHandler_ /* not used in QXThread */ -#endif - }, - &QXThread_start_, - &QXThread_post_, - &QXThread_postLIFO_ -}; -union QHsmAttr tmp; -tmp.thr = handler; - -QActive_ctor(&me->super, tmp.fun); /* superclass' ctor */ -me->super.super.vptr = &vtable.super; /* hook to QXThread vtable */ -me->super.super.state.act = Q_ACTION_CAST(0); /*mark as extended thread */ - -/* construct the time event member added in the QXThread class */ -QTimeEvt_ctorX(&me->timeEvt, &me->super, - (enum_t)QXK_DELAY_SIG, tickRate); - - - - /*! delay (block) the current extended thread for a specified # ticks -* @static @public @memberof QXThread -* -* @details -* Blocking delay for the number of clock tick at the associated tick rate. -* -* @param[in] nTicks number of clock ticks (at the associated rate) -* to wait for the event to arrive. -* @note -* For the delay to work, the QTIMEEVT_TICK_X() macro needs to be called -* periodically at the associated clock tick rate. -* -* @sa QXThread_ctor() -* @sa QTIMEEVT_TICK_X() -*/ - - - QF_CRIT_STAT_ -QF_CRIT_E_(); - -QXThread * const thr = QXTHREAD_CAST_(QXK_attr_.curr); - -/*! @pre this function must: -* - NOT be called from an ISR; -* - number of ticks cannot be zero -* - be called from an extended thread; -* - the thread must NOT be already blocked on any object. -*/ -Q_REQUIRE_ID(800, (!QXK_ISR_CONTEXT_()) /* can't block inside an ISR */ - && (nTicks != 0U) /* number of ticks cannot be zero */ - && (thr != (QXThread *)0) /* current thread must be extended */ - && (thr->super.super.temp.obj == (QMState *)0)); /* !blocked */ -/*! @pre also: the thread must NOT be holding a scheduler lock. */ -Q_REQUIRE_ID(801, QXK_attr_.lockHolder != thr->super.prio); - -/* remember the blocking object */ -thr->super.super.temp.obj = QXK_PTR_CAST_(QMState const*, &thr->timeEvt); -QXThread_teArm_(thr, (enum_t)QXK_DELAY_SIG, nTicks); -QXThread_block_(thr); -QF_CRIT_X_(); -QF_CRIT_EXIT_NOP(); /* BLOCK here */ - -QF_CRIT_E_(); -/* the blocking object must be the time event */ -Q_ENSURE_ID(890, thr->super.super.temp.obj - == QXK_PTR_CAST_(QMState const*, &thr->timeEvt)); -thr->super.super.temp.obj = (QMState *)0; /* clear */ -QF_CRIT_X_(); - -/* signal of zero means that the time event was posted without -* being canceled. -*/ -return thr->timeEvt.super.sig == 0U; - - - - /*! cancel the delay -* @public @memberof QXThread -* -* @details -* Cancel the blocking delay and cause return from the QXThread_delay() -* function. -* -* @returns -* "true" if the thread was actually blocked on QXThread_delay() and -* "false" otherwise. -*/ - QF_CRIT_STAT_ -QF_CRIT_E_(); - -bool wasArmed; -if (me->super.super.temp.obj == QXK_PTR_CAST_(QMState*, &me->timeEvt)) { - wasArmed = QXThread_teDisarm_(me); - QXThread_unblock_(me); -} -else { - wasArmed = false; -} -QF_CRIT_X_(); - -return wasArmed; - - - - /*! obtain a message from the private message queue (block if no messages) -* @static @public @memberof QXThread -* -* @details -* The QXThread_queueGet() operation allows the calling extended thread to -* receive QP events directly into its own built-in event queue from an ISR, -* basic thread (AO), or another extended thread. -* -* If QXThread_queueGet() is called when no events are present in the -* thread's private event queue, the operation blocks the current extended -* thread until either an event is received, or a user-specified timeout -* expires. -* -* @param[in] nTicks number of clock ticks (at the associated rate) -* to wait for the event to arrive. The value of -* ::QXTHREAD_NO_TIMEOUT indicates that no timeout will -* occur and the queue will block indefinitely. -* @returns -* A pointer to the event. If the pointer is not NULL, the event was delivered. -* Otherwise the event pointer of NULL indicates that the queue has timed out. -*/ - - - QF_CRIT_STAT_ -QF_CRIT_E_(); - -QXThread * const thr = QXTHREAD_CAST_(QXK_attr_.curr); - -/*! @pre this function must: -* - NOT be called from an ISR; -* - be called from an extended thread; -* - the thread must NOT be already blocked on any object. -*/ -Q_REQUIRE_ID(500, (!QXK_ISR_CONTEXT_()) /* can't block inside an ISR */ - && (thr != (QXThread *)0) /* current thread must be extended */ - && (thr->super.super.temp.obj == (QMState *)0)); /* !blocked */ -/*! @pre also: the thread must NOT be holding a scheduler lock. */ -Q_REQUIRE_ID(501, QXK_attr_.lockHolder != thr->super.prio); - -/* is the queue empty? */ -if (thr->super.eQueue.frontEvt == (QEvt *)0) { - - /* remember the blocking object (the thread's queue) */ - thr->super.super.temp.obj - = QXK_PTR_CAST_(QMState const*, &thr->super.eQueue); - - QXThread_teArm_(thr, (enum_t)QXK_TIMEOUT_SIG, nTicks); - QPSet_remove(&QF_readySet_, (uint_fast8_t)thr->super.prio); - (void)QXK_sched_(); /* schedule other threads */ - QF_CRIT_X_(); - QF_CRIT_EXIT_NOP(); /* BLOCK here */ - - QF_CRIT_E_(); - /* the blocking object must be this queue */ - Q_ASSERT_ID(510, thr->super.super.temp.obj - == QXK_PTR_CAST_(QMState const*, &thr->super.eQueue)); - thr->super.super.temp.obj = (QMState *)0; /* clear */ -} - -/* is the queue not empty? */ -QEvt const *e; -if (thr->super.eQueue.frontEvt != (QEvt *)0) { - e = thr->super.eQueue.frontEvt; /* remove from the front */ - QEQueueCtr const nFree= thr->super.eQueue.nFree + 1U; - thr->super.eQueue.nFree = nFree; /* update the number of free */ - - /* any events in the ring buffer? */ - if (nFree <= thr->super.eQueue.end) { - - /* remove event from the tail */ - thr->super.eQueue.frontEvt = - thr->super.eQueue.ring[thr->super.eQueue.tail]; - if (thr->super.eQueue.tail == 0U) { /* need to wrap? */ - thr->super.eQueue.tail = thr->super.eQueue.end; /* wrap */ - } - --thr->super.eQueue.tail; - - QS_BEGIN_NOCRIT_PRE_(QS_QF_ACTIVE_GET, thr->super.prio) - QS_TIME_PRE_(); /* timestamp */ - QS_SIG_PRE_(e->sig); /* the signal of this event */ - QS_OBJ_PRE_(&thr->super); /* this active object */ - QS_2U8_PRE_(e->poolId_, e->refCtr_); /* pool Id & ref Count */ - QS_EQC_PRE_(nFree); /* number of free entries */ - QS_END_NOCRIT_PRE_() - } - else { - thr->super.eQueue.frontEvt = (QEvt *)0; /* empty queue */ - - /* all entries in the queue must be free (+1 for fronEvt) */ - Q_ASSERT_ID(520, nFree == (thr->super.eQueue.end + 1U)); - - QS_BEGIN_NOCRIT_PRE_(QS_QF_ACTIVE_GET_LAST, thr->super.prio) - QS_TIME_PRE_(); /* timestamp */ - QS_SIG_PRE_(e->sig); /* the signal of this event */ - QS_OBJ_PRE_(&thr->super); /* this active object */ - QS_2U8_PRE_(e->poolId_, e->refCtr_); /* pool Id & ref Count */ - QS_END_NOCRIT_PRE_() - } -} -else { /* the queue is still empty -- the timeout must have fired */ - e = (QEvt *)0; -} -QF_CRIT_X_(); - -return e; - - - - - /*! Overrides QHsm_init_() */ - - - - - - - Q_UNUSED_PAR(me); -Q_UNUSED_PAR(par); -Q_UNUSED_PAR(qs_id); - -Q_ERROR_ID(110); - - - - /*! Overrides QHsm_dispatch_() */ - - - - - - - Q_UNUSED_PAR(me); -Q_UNUSED_PAR(e); -Q_UNUSED_PAR(qs_id); - -Q_ERROR_ID(120); - - - - /*! start QXThread private implementation -* @private @memberof QXThread -* -* @details -* Starts execution of an extended thread and registers it with the framework. -* The extended thread becomes ready-to-run immediately and is scheduled -* if the QXK is already running. -* -* @param[in,out] me current instance pointer (see @ref oop) -* @param[in] prio QF-priority of the thread, but no preemption- -* threshold. See also ::QPrioSpec. -* @param[in] qSto pointer to the storage for the ring buffer of the -* event queue. This cold be NULL, if this extended -* thread does not use the built-in event queue. -* @param[in] qLen length of the event queue [in events], -* or zero if queue not used -* @param[in] stkSto pointer to the stack storage (must be provided) -* @param[in] stkSize stack size [in bytes] (must not be zero) -* @param[in] par pointer to an extra parameter (might be NULL). -* -* @note -* Currently, extended trheads in QXK do NOT support preemption-threshold. -* The `prio` must NOT provide preemption-threshold and this function -* will assert it in the precondition. -* -* @usage -* QXThread_start_() should NOT be called directly, only via the macro -* QXTHREAD_START(). The following example shows starting an extended -* thread: -* @include qxk_start.c -*/ - - - - - - - - - - - - - - - Q_UNUSED_PAR(par); - -/*! @pre this function must: -* - NOT be called from an ISR; -* - the stack storage must be provided; -* - the thread must be instantiated (see QXThread_ctor()) -* - preemption-threshold is NOT provided (because QXK kernel -* does not support preemption-threshold scheduling) -*/ -Q_REQUIRE_ID(200, (!QXK_ISR_CONTEXT_()) /* don't call from an ISR! */ - && (stkSto != (void *)0) /* stack must be provided */ - && (stkSize != 0U) - && (me->super.state.act == (QActionHandler)0) - && ((prioSpec & 0xFF00U) == 0U)); - -/* is storage for the queue buffer provided? */ -if (qSto != (QEvt const **)0) { - QEQueue_init(&me->eQueue, qSto, qLen); -} - -/* extended thread constructor puts the thread handler in place of -* the top-most initial transition 'me->super.temp.act' -*/ -QXK_stackInit_(me, me->super.temp.thr, stkSto, stkSize); - -/* the new thread is not blocked on any object */ -me->super.temp.obj = (QMState *)0; - -me->prio = (uint8_t)(prioSpec & 0xFFU); /* QF-priority of the AO */ -me->pthre = 0U; /* preemption-threshold NOT used */ -QActive_register_(me); /* make QF aware of this active object */ - -QF_CRIT_STAT_ -QF_CRIT_E_(); -/* extended-thread becomes ready immediately */ -QPSet_insert(&QF_readySet_, (uint_fast8_t)me->prio); - -/* see if this thread needs to be scheduled in case QXK is running */ -if (QXK_attr_.lockCeil <= QF_MAX_ACTIVE) { - (void)QXK_sched_(); /* schedule other threads */ -} -QF_CRIT_X_(); - - - - /*! post to the QXThread event queue private implementation -* @private @memberof QXThread -* -* @details -* Direct event posting is the simplest asynchronous communication method -* available in QF. The following example illustrates how the Philo active -* object posts directly the HUNGRY event to the Table active object. -* <br> -* The parameter `margin` specifies the minimum number of free slots in -* the queue that must be available for posting to succeed. The function -* returns 1 (success) if the posting succeeded (with the provided margin) -* and 0 (failure) when the posting fails. -* -* @param[in,out] me current instance pointer (see @ref oop) -* @param[in] e pointer to the event to be posted -* @param[in] margin number of required free slots in the queue after -* posting the event. The special value #QF_NO_MARGIN -* means that this function will assert if posting fails. -* @param[in] sender pointer to a sender object (used only for QS tracing). -* -* @returns -* 'true' (success) if the posting succeeded (with the provided margin) and -* 'false' (failure) when the posting fails. -* -* @note -* Should be called only via the macro QXTHREAD_POST_X(). -* -* @note -* The #QF_NO_MARGIN value of the `margin` parameter is special and -* denotes situation when the post() operation is assumed to succeed -* (event delivery guarantee). An assertion fires, when the event cannot -* be delivered in this case. -* -* @note -* For compatibility with the V-table from the superclass ::QActive, the -* me-pointer is typed as pointing to QActive. However, the `me` pointer -* here actually points to the QXThread subclass. Therefore the downcast -* (QXThread *)me is always correct. -*/ - - - - - - - - - #ifndef Q_SPY -Q_UNUSED_PAR(sender); -#endif - -QF_CRIT_STAT_ -QS_TEST_PROBE_DEF(&QXThread_post_) - -/* is it the private time event? */ -bool status; -if (e == &QXTHREAD_CAST_(me)->timeEvt.super) { - QF_CRIT_E_(); - /* the private time event is disarmed and not in any queue, - * so it is safe to change its signal. The signal of 0 means - * that the time event has expired. - */ - QXTHREAD_CAST_(me)->timeEvt.super.sig = 0U; - - QXThread_unblock_(QXTHREAD_CAST_(me)); - QF_CRIT_X_(); - - status = true; -} -/* is the event queue provided? */ -else if (me->eQueue.end != 0U) { - QEQueueCtr nFree; /* temporary to avoid UB for volatile access */ - - /*! @pre event pointer must be valid */ - Q_REQUIRE_ID(300, e != (QEvt *)0); - - QF_CRIT_E_(); - nFree = me->eQueue.nFree; /* get volatile into the temporary */ - - /* test-probe#1 for faking queue overflow */ - QS_TEST_PROBE_ID(1, - nFree = 0U; - ) - - if (margin == QF_NO_MARGIN) { - if (nFree > 0U) { - status = true; /* can post */ - } - else { - status = false; /* cannot post */ - Q_ERROR_CRIT_(310); /* must be able to post the event */ - } - } - else if (nFree > (QEQueueCtr)margin) { - status = true; /* can post */ - } - else { - status = false; /* cannot post, but don't assert */ - } - - /* is it a dynamic event? */ - if (e->poolId_ != 0U) { - QEvt_refCtr_inc_(e); /* increment the reference counter */ - } - - if (status) { /* can post the event? */ - - --nFree; /* one free entry just used up */ - me->eQueue.nFree = nFree; /* update the volatile */ - if (me->eQueue.nMin > nFree) { - me->eQueue.nMin = nFree; /* update minimum so far */ - } - - QS_BEGIN_NOCRIT_PRE_(QS_QF_ACTIVE_POST, me->prio) - QS_TIME_PRE_(); /* timestamp */ - QS_OBJ_PRE_(sender); /* the sender object */ - QS_SIG_PRE_(e->sig); /* the signal of the event */ - QS_OBJ_PRE_(me); /* this active object (recipient) */ - QS_2U8_PRE_(e->poolId_, e->refCtr_); /* pool Id & ref Count */ - QS_EQC_PRE_(nFree); /* number of free entries */ - QS_EQC_PRE_(me->eQueue.nMin); /* min number of free entries */ - QS_END_NOCRIT_PRE_() - - /* queue empty? */ - if (me->eQueue.frontEvt == (QEvt *)0) { - me->eQueue.frontEvt = e; /* deliver event directly */ - - /* is this thread blocked on the queue? */ - if (me->super.temp.obj - == QXK_PTR_CAST_(QMState*, &me->eQueue)) - { - (void)QXThread_teDisarm_(QXTHREAD_CAST_(me)); - QPSet_insert(&QF_readySet_, (uint_fast8_t)me->prio); - if (!QXK_ISR_CONTEXT_()) { - (void)QXK_sched_(); /* schedule other threads */ - } - } - } - /* queue is not empty, insert event into the ring-buffer */ - else { - /* insert event into the ring buffer (FIFO) */ - me->eQueue.ring[me->eQueue.head] = e; - - /* need to wrap the head counter? */ - if (me->eQueue.head == 0U) { - me->eQueue.head = me->eQueue.end; /* wrap around */ - } - --me->eQueue.head; /* advance the head (counter clockwise) */ - } - - QF_CRIT_X_(); - } - else { /* cannot post the event */ - - QS_BEGIN_NOCRIT_PRE_(QS_QF_ACTIVE_POST_ATTEMPT, me->prio) - QS_TIME_PRE_(); /* timestamp */ - QS_OBJ_PRE_(sender); /* the sender object */ - QS_SIG_PRE_(e->sig); /* the signal of the event */ - QS_OBJ_PRE_(me); /* this active object (recipient) */ - QS_2U8_PRE_(e->poolId_, e->refCtr_); /* pool Id & ref Count */ - QS_EQC_PRE_(nFree); /* number of free entries */ - QS_EQC_PRE_(margin); /* margin requested */ - QS_END_NOCRIT_PRE_() - - QF_CRIT_X_(); - -#if (QF_MAX_EPOOL > 0U) - QF_gc(e); /* recycle the event to avoid a leak */ -#endif - } -} -else { /* the queue is not available */ -#if (QF_MAX_EPOOL > 0U) - QF_gc(e); /* make sure the event is not leaked */ -#endif - status = false; - Q_ERROR_ID(320); /* this extended thread cannot accept events */ -} - -return status; - - - - /*! post to the QXThread event queue (LIFO) private implementation -* @private @memberof QXThread -* -* @details -* Last-In-First-Out (LIFO) policy is not supported for extened threads. -* -* @param[in] me current instance pointer (see @ref oop) -* @param[in] e pointer to the event to post to the queue -* -* @sa -* QActive_postLIFO_() -*/ - - - - - Q_UNUSED_PAR(me); -Q_UNUSED_PAR(e); - -Q_ERROR_ID(410); - - - - const - /*! block QXThread private implementation -* @private @memberof QXThread -* -* @details -* Internal implementation of blocking the given extended thread. -* -* @note -* Must be called from within a critical section -*/ - /*! @pre the thread holding the lock cannot block! */ -Q_REQUIRE_ID(600, (QXK_attr_.lockHolder != me->super.prio)); - -QPSet_remove(&QF_readySet_, (uint_fast8_t)me->super.prio); -(void)QXK_sched_(); /* schedule other threads */ - - - - const - /*! unblock QXThread private implementation -* @private @memberof QXThread -* -* @details -* Internal implementation of un-blocking the given extended thread. -* -* @note -* must be called from within a critical section -*/ - QPSet_insert(&QF_readySet_, (uint_fast8_t)me->super.prio); -if ((!QXK_ISR_CONTEXT_()) /* not inside ISR? */ - && (QActive_registry_[0] != (QActive *)0)) /* kernel started? */ -{ - (void)QXK_sched_(); /* schedule other threads */ -} - - - - /*! arm internal time event private implementation -* @private @memberof QXThread -* -* @details -* Internal implementation of arming the private time event for a given -* timeout at a given system tick rate. -* -* @note -* Must be called from within a critical section -*/ - - - - - /*! @pre the time event must be unused */ -Q_REQUIRE_ID(700, me->timeEvt.ctr == 0U); - -me->timeEvt.super.sig = (QSignal)sig; - -if (nTicks != QXTHREAD_NO_TIMEOUT) { - me->timeEvt.ctr = (QTimeEvtCtr)nTicks; - me->timeEvt.interval = 0U; - - /* is the time event unlinked? - * NOTE: For the duration of a single clock tick of the specified tick - * rate a time event can be disarmed and yet still linked in the list, - * because un-linking is performed exclusively in QTimeEvt_tick_(). - */ - if ((me->timeEvt.super.refCtr_ & QTE_IS_LINKED) == 0U) { - uint_fast8_t const tickRate - = ((uint_fast8_t)me->timeEvt.super.refCtr_ & QTE_TICK_RATE); - Q_ASSERT_ID(710, tickRate < QF_MAX_TICK_RATE); - - me->timeEvt.super.refCtr_ |= QTE_IS_LINKED; - - /* The time event is initially inserted into the separate - * "freshly armed" list based on QTimeEvt_timeEvtHead_[tickRate].act. - * Only later, inside the QTimeEvt_tick_() function, the "freshly - * armed" list is appended to the main list of armed time events - * based on QTimeEvt_timeEvtHead_[tickRate].next. Again, this is - * to keep any changes to the main list exclusively inside - * QTimeEvt_tick_(). - */ - me->timeEvt.next - = QXK_PTR_CAST_(QTimeEvt*, QTimeEvt_timeEvtHead_[tickRate].act); - QTimeEvt_timeEvtHead_[tickRate].act = &me->timeEvt; - } -} - - - - /*! disarm internal time event private implementation -* @private @memberof QXThread -* -* @details -* Internal implementation of disarming the private time event. -* -* @note -* Must be called from within a critical section -*/ - bool wasArmed; -/* is the time evt running? */ -if (me->timeEvt.ctr != 0U) { - wasArmed = true; - me->timeEvt.ctr = 0U; /* schedule removal from list */ -} -/* the time event was already automatically disarmed */ -else { - wasArmed = false; -} -return wasArmed; - - - - - /*! @brief Virtual Table for the ::QXThread class -* (inherited from ::QActiveVtable) -* -* @note -* ::QXThread inherits ::QActive without adding any new virtual -* functions and therefore, ::QXThreadVtable is typedef'ed as ::QActiveVtable. -*/ - - - - /*! QActive active object class customization for QK */ - - - /*! Starts execution of an active object and registers the object -* with the framework customized for QXK -*/ - - - - - - - - - - - - - Q_UNUSED_PAR(stkSto); /* not needed in QXK */ -Q_UNUSED_PAR(stkSize); /* not needed in QXK */ - -/*! @pre AO cannot be started: -* - from an ISR; -* - the stack storage must NOT be provided (because the QXK kernel -* does not need per-AO stacks) -* - preemption-threshold is NOT provided (because QXK kernel -* does not support preemption-threshold scheduling) -*/ -Q_REQUIRE_ID(200, (!QXK_ISR_CONTEXT_()) - && (stkSto == (void *)0) - && ((prioSpec & 0xFF00U) == 0U)); - -me->prio = (uint8_t)(prioSpec & 0xFFU); /* QF-priority of the AO */ -me->pthre = 0U; /* preemption-threshold NOT used */ -QActive_register_(me); /* make QF aware of this active object */ - -QEQueue_init(&me->eQueue, qSto, qLen); /* init the built-in queue */ -me->osObject = (void *)0; /* no private stack for the AO */ - -QHSM_INIT(&me->super, par, me->prio); /* top-most initial tran. */ -QS_FLUSH(); /* flush the trace buffer to the host */ - -/* see if this AO needs to be scheduled if QXK is already running */ -QF_CRIT_STAT_ -QF_CRIT_E_(); -if (QXK_attr_.lockCeil <= QF_MAX_ACTIVE) { /* scheduler running? */ - if (QXK_sched_() != 0U) { /* activation needed? */ - QXK_activate_(); /* synchronously activate basic-thred(s) */ - } -} -QF_CRIT_X_(); - - - - - /*! @brief Counting Semaphore of the QXK preemptive kernel -* @class QXSemaphore -* -* @details -* ::QXSemaphore is a blocking mechanism intended primarily for signaling -* @ref ::QXThread "extended threads". The semaphore is initialized with -* the maximum count (see QXSemaphore_init()), which allows you to create -* a binary semaphore (when the maximum count is 1) and -* counting semaphore when the maximum count is > 1. -* -* @usage -* The following example illustrates how to instantiate and use the semaphore -* in your application. -* @include qxk_sema.c -*/ - - - /*! set of extended threads waiting on this semaphore */ - - - - /*! semaphore up-down counter */ - - - - /*! maximum value of the semaphore counter */ - - - - /*! initialize the counting semaphore -* @public @memberof QXSemaphore -* -* @details -* Initializes a semaphore with the specified count and maximum count. -* If the semaphore is used for resource sharing, both the initial count -* and maximum count should be set to the number of identical resources -* guarded by the semaphore. If the semaphore is used as a signaling -* mechanism, the initial count should set to 0 and maximum count to 1 -* (binary semaphore). -* -* @param[in,out] me current instance pointer (see @ref oop) -* @param[in] count initial value of the semaphore counter -* @param[in] max_count maximum value of the semaphore counter. -* The purpose of the max_count is to limit the counter -* so that the semaphore cannot unblock more times than -* the maximum. -* -* @note -* QXSemaphore_init() must be called **before** the semaphore can be used -* (signaled or waited on). -*/ - - - - - /*! @pre max_count must be greater than zero */ -Q_REQUIRE_ID(100, max_count > 0U); - -me->count = (uint8_t)count; -me->max_count = (uint8_t)max_count; -QPSet_setEmpty(&me->waitSet); - - - - /*! wait (block) on the semaphore -* @public @memberof QXSemaphore -* -* @details -* When an extended thread calls QXSemaphore_wait() and the value of the -* semaphore counter is greater than 0, QXSemaphore_wait() decrements the -* semaphore counter and returns (true) to its caller. However, if the value -* of the semaphore counter is 0, the function places the calling thread in -* the waiting list for the semaphore. The thread waits until the semaphore -* is signaled by calling QXSemaphore_signal(), or the specified timeout -* expires. If the semaphore is signaled before the timeout expires, QXK -* resumes the highest-priority extended thread waiting for the semaphore. -* -* @param[in,out] me current instance pointer (see @ref oop) -* @param[in] nTicks number of clock ticks (at the associated rate) -* to wait for the semaphore. The value of -* ::QXTHREAD_NO_TIMEOUT indicates that no timeout will -* occur and the semaphore will wait indefinitely. -* -* @returns -* 'true' if the semaphore has been signaled and 'false' if a timeout -* occurred. -* -* @note -* Multiple extended threads can wait for a given semaphore. -*/ - - - QF_CRIT_STAT_ -QF_CRIT_E_(); - -/* volatile into temp. */ -QXThread * const curr = QXK_PTR_CAST_(QXThread*, QXK_attr_.curr); - -/*! @pre this function must: -* - NOT be called from an ISR; -* - the semaphore must be initialized -* - be called from an extended thread; -* - the thread must NOT be already blocked on any object. -*/ -Q_REQUIRE_ID(200, (!QXK_ISR_CONTEXT_()) /* can't wait inside an ISR */ - && (me->max_count > 0U) /* sema must be initialized */ - && (curr != (QXThread *)0) /* curr must be extended */ - && (curr->super.super.temp.obj == (QMState *)0)); /* NOT blocked */ -/*! @pre also: the thread must NOT be holding a scheduler lock. */ -Q_REQUIRE_ID(201, QXK_attr_.lockHolder != curr->super.prio); - -bool signaled = true; /* assume that the semaphore will be signaled */ -if (me->count > 0U) { - --me->count; /* semaphore taken: decrement the count */ - - QS_BEGIN_NOCRIT_PRE_(QS_SEM_TAKE, curr->super.prio) - QS_TIME_PRE_(); /* timestamp */ - QS_OBJ_PRE_(me); /* this semaphore */ - QS_2U8_PRE_(curr->super.prio, - me->count); - QS_END_NOCRIT_PRE_() -} -else { - uint_fast8_t const p = (uint_fast8_t)curr->super.prio; - /* remove the curr prio from the ready set (will block) - * and insert to the waiting set on this semaphore - */ - QPSet_remove(&QF_readySet_, p); - QPSet_insert(&me->waitSet, p); - - /* remember the blocking object (this semaphore) */ - curr->super.super.temp.obj = QXK_PTR_CAST_(QMState*, me); - QXThread_teArm_(curr, (enum_t)QXK_TIMEOUT_SIG, nTicks); - - QS_BEGIN_NOCRIT_PRE_(QS_SEM_BLOCK, curr->super.prio) - QS_TIME_PRE_(); /* timestamp */ - QS_OBJ_PRE_(me); /* this semaphore */ - QS_2U8_PRE_(curr->super.prio, - me->count); - QS_END_NOCRIT_PRE_() - - /* schedule the next thread if multitasking started */ - (void)QXK_sched_(); /* schedule other theads */ - QF_CRIT_X_(); - QF_CRIT_EXIT_NOP(); /* BLOCK here !!! */ - - QF_CRIT_E_(); /* AFTER unblocking... */ - /* the blocking object must be this semaphore */ - Q_ASSERT_ID(240, curr->super.super.temp.obj - == QXK_PTR_CAST_(QMState*, me)); - - /* did the blocking time-out? (signal of zero means that it did) */ - if (curr->timeEvt.super.sig == 0U) { - if (QPSet_hasElement(&me->waitSet, p)) { /* still waiting? */ - QPSet_remove(&me->waitSet, p); /* remove unblocked thread */ - signaled = false; /* the semaphore was NOT signaled */ - /* semaphore NOT taken: do NOT decrement the count */ - } - else { /* semaphore was both signaled and timed out */ - --me->count; /* semaphore taken: decrement the count */ - } - } - else { /* blocking did NOT time out */ - /* the thread must NOT be waiting on this semaphore */ - Q_ASSERT_ID(250,!QPSet_hasElement(&me->waitSet, p)); - --me->count; /* semaphore taken: decrement the count */ - } - curr->super.super.temp.obj = (QMState *)0; /* clear blocking obj. */ -} -QF_CRIT_X_(); - -return signaled; - - - - /*! try wait on the semaphore (non-blocking) -* @public @memberof QXSemaphore -* -* @details -* This function checks if the semaphore counter is greater than 0, -* in which case the counter is decremented. -* -* @param[in,out] me current instance pointer (see @ref oop) -* -* @returns -* 'true' if the semaphore has count available and 'false' NOT available. -* -* @note -* This function can be called from any context, including ISRs and basic -* threads (active objects). -*/ - QF_CRIT_STAT_ -QF_CRIT_E_(); - -/*! @pre the semaphore must be initialized */ -Q_REQUIRE_ID(300, me->max_count > 0U); - -#ifdef Q_SPY -/* volatile into temp. */ -QActive const * const curr = QXK_PTR_CAST_(QActive*, QXK_attr_.curr); -#endif /* Q_SPY */ - -bool isAvailable; -/* is the semaphore available? */ -if (me->count > 0U) { - --me->count; - isAvailable = true; - - QS_BEGIN_NOCRIT_PRE_(QS_SEM_TAKE, curr->prio) - QS_TIME_PRE_(); /* timestamp */ - QS_OBJ_PRE_(me); /* this semaphore */ - QS_2U8_PRE_(curr->prio, - me->count); - QS_END_NOCRIT_PRE_() -} -else { /* the semaphore is NOT available (would block) */ - isAvailable = false; - - QS_BEGIN_NOCRIT_PRE_(QS_SEM_BLOCK_ATTEMPT, curr->prio) - QS_TIME_PRE_(); /* timestamp */ - QS_OBJ_PRE_(me); /* this semaphore */ - QS_2U8_PRE_(curr->prio, - me->count); - QS_END_NOCRIT_PRE_() -} -QF_CRIT_X_(); - -return isAvailable; - - - - /*! signal (unblock) the semaphore -* @public @memberof QXSemaphore -* -* @details -* If the semaphore counter value is 0 or more, it is incremented, and -* this function returns to its caller. If the extended threads are waiting -* for the semaphore to be signaled, QXSemaphore_signal() removes the highest- -* priority thread waiting for the semaphore from the waiting list and makes -* this thread ready-to-run. The QXK scheduler is then called to determine if -* the awakened thread is now the highest-priority thread that is ready-to-run. -* -* @param[in,out] me current instance pointer (see @ref oop) -* -* @returns -* 'true' when the semaphore signaled and 'false' when the semaphore count -* exceeded the maximum. -* -* @note -* A semaphore can be signaled from many places, including from ISRs, basic -* threads (AOs), and extended threads. -*/ - /*! @pre the semaphore must be initialized */ -Q_REQUIRE_ID(400, me->max_count > 0U); - -QF_CRIT_STAT_ -QF_CRIT_E_(); - -bool signaled = true; /* assume that the semaphore will be signaled */ -if (me->count < me->max_count) { - - ++me->count; /* increment the semaphore count */ - - #ifdef Q_SPY - /* volatile into temp. */ - QActive const * const curr = QXK_PTR_CAST_(QActive*, QXK_attr_.curr); - #endif /* Q_SPY */ - - QS_BEGIN_NOCRIT_PRE_(QS_SEM_SIGNAL, curr->prio) - QS_TIME_PRE_(); /* timestamp */ - QS_OBJ_PRE_(me); /* this semaphore */ - QS_2U8_PRE_(curr->prio, - me->count); - QS_END_NOCRIT_PRE_() - - if (QPSet_notEmpty(&me->waitSet)) { - /* find the highest-priority thread waiting on this semaphore */ - uint_fast8_t const p = QPSet_findMax(&me->waitSet); - QXThread * const thr = - QXK_PTR_CAST_(QXThread*, QActive_registry_[p]); - - /* assert that the tread: - * - must be registered in QF; - * - must be extended; and - * - must be blocked on this semaphore; - */ - Q_ASSERT_ID(410, (thr != (QXThread *)0) - && (thr->super.osObject != (struct QActive *)0) - && (thr->super.super.temp.obj - == QXK_PTR_CAST_(QMState*, me))); - - /* disarm the internal time event */ - (void)QXThread_teDisarm_(thr); - - /* make the thread ready to run and remove from the wait-list */ - QPSet_insert(&QF_readySet_, p); - QPSet_remove(&me->waitSet, p); - - QS_BEGIN_NOCRIT_PRE_(QS_SEM_TAKE, thr->super.prio) - QS_TIME_PRE_(); /* timestamp */ - QS_OBJ_PRE_(me); /* this semaphore */ - QS_2U8_PRE_(thr->super.prio, - me->count); - QS_END_NOCRIT_PRE_() - - if (!QXK_ISR_CONTEXT_()) { /* not inside ISR? */ - (void)QXK_sched_(); /* schedule other threads */ - } - } -} -else { - signaled = false; /* semaphore NOT signaled */ -} -QF_CRIT_X_(); - -return signaled; - - - - - /*! @brief Blocking Mutex the QXK preemptive kernel -* @class QXMutex -* -* @details -* ::QXMutex is a blocking mutual exclusion mechanism that can also apply -* the **priority-ceiling protocol** to avoid unbounded priority inversion -* (if initialized with a non-zero ceiling priority, see QXMutex_init()). -* In that case, ::QXMutex requires its own uinque QP priority level, which -* cannot be used by any thread or any other ::QXMutex. -* If initialized with preemption-ceiling of zero, ::QXMutex does **not** -* use the priority-ceiling protocol and does not require a unique QP -* priority (see QXMutex_init()). -* ::QXMutex is **recursive** (re-entrant), which means that it can be locked -* multiple times (up to 255 levels) by the *same* thread without causing -* deadlock. -* ::QXMutex is primarily intended for the @ref ::QXThread -* "extened (blocking) threads", but can also be used by the @ref ::QActive -* "basic threads" through the non-blocking QXMutex_tryLock() API. -* -* @note -* ::QXMutex should be used in situations when at least one of the extended -* threads contending for the mutex blocks while holding the mutex (between -* the QXMutex_lock() and QXMutex_unlock() operations). If no blocking is -* needed while holding the mutex, the more efficient non-blocking mechanism -* of @ref srs_qxk_schedLock() "selective QXK scheduler locking" should be used -* instead. @ref srs_qxk_schedLock() "Selective scheduler locking" is available -* for both @ref ::QActive "basic threads" and @ref ::QXThread "extended -* threads", so it is applicable to situations where resources are shared -* among all these threads. -* -* @usage -* The following example illustrates how to instantiate and use the mutex -* in your application. -* @include qxk_mutex.c -*/ - - - /*! active object used as a placeholder AO for this mutex -* in QActive_registry_[] -*/ - - - - /*! set of extended-threads waiting on this mutex */ - - - - /*! initialize the QXK priority-ceiling mutex ::QXMutex -* @public @memberof QXMutex -* -* @details -* Initialize the QXK priority ceiling mutex. -* -* @param[in,out] me current instance pointer (see @ref oop) -* @param[in] prioSpec the priority specification for the mutex -* (See also ::QPrioSpec). This value might -* also be zero. -* @note -* `prioSpec == 0` means that the priority-ceiling protocol shall **not** -* be used by this mutex. Such mutex will **not** change (boost) the -* priority of the holding threads.<br> -* -* Conversely, `prioSpec != 0` means that the priority-ceiling protocol -* shall be used by this mutex. Such mutex **will** temporarily boost -* the priority and priority-threshold of the holding thread to the -* priority specification in `prioSpec` (see ::QPrioSpec). -* -* @usage -* @include qxk_mutex.c -*/ - - - /*! @pre preemption-threshold must not be used */ -Q_REQUIRE_ID(100, (prioSpec & 0xFF00U) == 0U); - -me->ao.prio = (uint8_t)(prioSpec & 0xFFU); /* QF-priority */ -me->ao.pthre = 0U; /* preemption-threshold (not used) */ - -if (prioSpec != 0U) { /* priority-ceiling protocol used? */ - QActive_register_(&me->ao); /* register this mutex as AO */ -} - - - - /*! lock the QXK priority-ceiling mutex ::QXMutex -* @public @memberof QXMutex -* -* @param[in,out] me current instance pointer (see @ref oop) -* @param[in] nTicks number of clock ticks (at the associated rate) -* to wait for the mutex. The value of -* ::QXTHREAD_NO_TIMEOUT indicates that no timeout will -* occur and the mutex could block indefinitely. -* @returns -* 'true' if the mutex has been acquired and 'false' if a timeout occurred. -* -* @note -* The mutex locks are allowed to nest, meaning that the same extended thread -* can lock the same mutex multiple times (< 255). However, each call to -* QXMutex_lock() must be balanced by the matching call to QXMutex_unlock(). -* -* @usage -* @include qxk_mutex.c -*/ - - - QF_CRIT_STAT_ -QF_CRIT_E_(); - -QXThread * const curr = QXK_PTR_CAST_(QXThread*, QXK_attr_.curr); - -/*! @pre this function must: -* - NOT be called from an ISR; -* - be called from an extended thread; -* - the mutex-priority must be in range -* - the thread must NOT be already blocked on any object. -*/ -Q_REQUIRE_ID(200, (!QXK_ISR_CONTEXT_()) /* don't call from an ISR! */ - && (curr != (QXThread *)0) /* current thread must be extended */ - && (me->ao.prio <= QF_MAX_ACTIVE) - && (curr->super.super.temp.obj == (QMState *)0)); /* not blocked */ -/*! @pre also: the thread must NOT be holding a scheduler lock. */ -Q_REQUIRE_ID(201, QXK_attr_.lockHolder != curr->super.prio); - -/* is the mutex available? */ -bool locked = true; /* assume that the mutex will be locked */ -if (me->ao.eQueue.nFree == 0U) { - me->ao.eQueue.nFree = 1U; /* mutex lock nesting */ - - /*! @pre also: the newly locked mutex must have no holder yet */ - Q_REQUIRE_ID(202, me->ao.thread == (void *)0); - - /* set the new mutex holder to the curr thread and - * save the thread's prio in the mutex - * NOTE: reuse the otherwise unused eQueue data member. - */ - me->ao.thread = curr; - me->ao.eQueue.head = (QEQueueCtr)curr->super.prio; - - QS_BEGIN_NOCRIT_PRE_(QS_MTX_LOCK, curr->super.prio) - QS_TIME_PRE_(); /* timestamp */ - QS_OBJ_PRE_(me); /* this mutex */ - QS_U8_PRE_((uint8_t)me->ao.eQueue.head); /* holder prio */ - QS_U8_PRE_((uint8_t)me->ao.eQueue.nFree); /* nesting */ - QS_END_NOCRIT_PRE_() - - if (me->ao.prio != 0U) { /* priority-ceiling protocol used? */ - /* the holder priority must be lower than that of the mutex - * and the priority slot must be occupied by this mutex - */ - Q_ASSERT_ID(210, (curr->super.prio < me->ao.prio) - && (QActive_registry_[me->ao.prio] == &me->ao)); - - /* remove the thread's original prio from the ready set - * and insert the mutex's prio into the ready set - */ - QPSet_remove(&QF_readySet_, (uint_fast8_t)me->ao.eQueue.head); - QPSet_insert(&QF_readySet_, (uint_fast8_t)me->ao.prio); - - /* put the thread into the AO registry in place of the mutex */ - QActive_registry_[me->ao.prio] = &curr->super; - - /* set thread's prio to that of the mutex */ - curr->super.prio = me->ao.prio; - } -} -/* is the mutex locked by this thread already (nested locking)? */ -else if (me->ao.thread == &curr->super) { - - /* the nesting level beyond the arbitrary but high limit - * most likely means cyclic or recursive locking of a mutex. - */ - Q_ASSERT_ID(220, me->ao.eQueue.nFree < 0xFFU); - - ++me->ao.eQueue.nFree; /* lock one more level */ - - QS_BEGIN_NOCRIT_PRE_(QS_MTX_LOCK, curr->super.prio) - QS_TIME_PRE_(); /* timestamp */ - QS_OBJ_PRE_(me); /* this mutex */ - QS_U8_PRE_((uint8_t)me->ao.eQueue.head); /* holder prio */ - QS_U8_PRE_((uint8_t)me->ao.eQueue.nFree); /* nesting */ - QS_END_NOCRIT_PRE_() -} -else { /* the mutex is already locked by a different thread */ - /* the mutex holder must be valid */ - Q_ASSERT_ID(230, me->ao.thread != (void *)0); - - if (me->ao.prio != 0U) { /* priority-ceiling protocol used? */ - /* the prio slot must be occupied by the thr. holding the mutex */ - Q_ASSERT_ID(240, QActive_registry_[me->ao.prio] - == QXK_PTR_CAST_(QActive *, me->ao.thread)); - } - - /* remove the curr thread's prio from the ready set (will block) - * and insert it to the waiting set on this mutex - */ - uint_fast8_t const p = (uint_fast8_t)curr->super.prio; - QPSet_remove(&QF_readySet_, p); - QPSet_insert(&me->waitSet, p); - - /* set the blocking object (this mutex) */ - curr->super.super.temp.obj = QXK_PTR_CAST_(QMState*, me); - QXThread_teArm_(curr, (enum_t)QXK_TIMEOUT_SIG, nTicks); - - QS_BEGIN_NOCRIT_PRE_(QS_MTX_BLOCK, curr->super.prio) - QS_TIME_PRE_(); /* timestamp */ - QS_OBJ_PRE_(me); /* this mutex */ - QS_2U8_PRE_((uint8_t)me->ao.eQueue.head, /* holder prio */ - curr->super.prio); /* blocked thread prio */ - QS_END_NOCRIT_PRE_() - - /* schedule the next thread if multitasking started */ - (void)QXK_sched_(); /* schedule other threads */ - QF_CRIT_X_(); - QF_CRIT_EXIT_NOP(); /* BLOCK here !!! */ - - /* AFTER unblocking... */ - QF_CRIT_E_(); - /* the blocking object must be this mutex */ - Q_ASSERT_ID(240, curr->super.super.temp.obj - == QXK_PTR_CAST_(QMState*, me)); - - /* did the blocking time-out? (signal of zero means that it did) */ - if (curr->timeEvt.super.sig == 0U) { - if (QPSet_hasElement(&me->waitSet, p)) { /* still waiting? */ - QPSet_remove(&me->waitSet, p); /* remove unblocked thread */ - locked = false; /* the mutex was NOT locked */ - } - } - else { /* blocking did NOT time out */ - /* the thread must NOT be waiting on this mutex */ - Q_ASSERT_ID(250, !QPSet_hasElement(&me->waitSet, p)); - } - curr->super.super.temp.obj = (QMState *)0; /* clear blocking obj. */ -} -QF_CRIT_X_(); - -return locked; - - - - /*! try to lock the QXK priority-ceiling mutex ::QXMutex -* @public @memberof QXMutex -* -* @param[in,out] me current instance pointer (see @ref oop) -* -* @returns -* 'true' if the mutex was successfully locked and 'false' if the mutex was -* unavailable and was NOT locked. -* -* @note -* This function **can** be called from both basic threads (active objects) -* and extended threads. -* -* @note -* The mutex locks are allowed to nest, meaning that the same extended thread -* can lock the same mutex multiple times (<= 255). However, each successful -* call to QXMutex_tryLock() must be balanced by the matching call to -* QXMutex_unlock(). -*/ - QF_CRIT_STAT_ -QF_CRIT_E_(); - -QActive *curr = QXK_attr_.curr; -if (curr == (QActive *)0) { /* called from a basic thread? */ - curr = QActive_registry_[QXK_attr_.actPrio]; -} - -/*! @pre this function must: -* - NOT be called from an ISR; -* - the calling thread must be valid; -* - the mutex-priority must be in range -*/ -Q_REQUIRE_ID(300, (!QXK_ISR_CONTEXT_()) /* don't call from an ISR! */ - && (curr != (QActive *)0) /* current thread must be valid */ - && (me->ao.prio <= QF_MAX_ACTIVE)); -/*! @pre also: the thread must NOT be holding a scheduler lock. */ -Q_REQUIRE_ID(301, QXK_attr_.lockHolder != curr->prio); - -/* is the mutex available? */ -if (me->ao.eQueue.nFree == 0U) { - me->ao.eQueue.nFree = 1U; /* mutex lock nesting */ - - /*! @pre also: the newly locked mutex must have no holder yet */ - Q_REQUIRE_ID(302, me->ao.thread == (void *)0); - - /* set the new mutex holder to the curr thread and - * save the thread's prio in the mutex - * NOTE: reuse the otherwise unused eQueue data member. - */ - me->ao.thread = curr; - me->ao.eQueue.head = (QEQueueCtr)curr->prio; - - QS_BEGIN_NOCRIT_PRE_(QS_MTX_LOCK, curr->prio) - QS_TIME_PRE_(); /* timestamp */ - QS_OBJ_PRE_(me); /* this mutex */ - QS_U8_PRE_((uint8_t)me->ao.eQueue.head); /* holder prio */ - QS_U8_PRE_((uint8_t)me->ao.eQueue.nFree); /* nesting */ - QS_END_NOCRIT_PRE_() - - if (me->ao.prio != 0U) { /* priority-ceiling protocol used? */ - /* the holder priority must be lower than that of the mutex - * and the priority slot must be occupied by this mutex - */ - Q_ASSERT_ID(210, (curr->prio < me->ao.prio) - && (QActive_registry_[me->ao.prio] == &me->ao)); - - /* remove the thread's original prio from the ready set - * and insert the mutex's prio into the ready set - */ - QPSet_remove(&QF_readySet_, (uint_fast8_t)me->ao.eQueue.head); - QPSet_insert(&QF_readySet_, (uint_fast8_t)me->ao.prio); - - /* put the thread into the AO registry in place of the mutex */ - QActive_registry_[me->ao.prio] = curr; - - /* set thread's prio to that of the mutex */ - curr->prio = me->ao.prio; - } -} -/* is the mutex locked by this thread already (nested locking)? */ -else if (me->ao.thread == curr) { - /* the nesting level must not exceed the specified limit */ - Q_ASSERT_ID(320, me->ao.eQueue.nFree < 0xFFU); - - ++me->ao.eQueue.nFree; /* lock one more level */ - - QS_BEGIN_NOCRIT_PRE_(QS_MTX_LOCK, curr->prio) - QS_TIME_PRE_(); /* timestamp */ - QS_OBJ_PRE_(me); /* this mutex */ - QS_U8_PRE_((uint8_t)me->ao.eQueue.head); /* holder prio */ - QS_U8_PRE_((uint8_t)me->ao.eQueue.nFree); /* nesting */ - QS_END_NOCRIT_PRE_() -} -else { /* the mutex is already locked by a different thread */ - if (me->ao.prio != 0U) { /* priority-ceiling protocol used? */ - /* the prio slot must be occupied by the thr. holding the mutex */ - Q_ASSERT_ID(340, QActive_registry_[me->ao.prio] - == QXK_PTR_CAST_(QActive *, me->ao.thread)); - } - - QS_BEGIN_NOCRIT_PRE_(QS_MTX_BLOCK_ATTEMPT, curr->prio) - QS_TIME_PRE_(); /* timestamp */ - QS_OBJ_PRE_(me); /* this mutex */ - QS_2U8_PRE_((uint8_t)me->ao.eQueue.head, /* holder prio */ - curr->prio); /* trying thread prio */ - QS_END_NOCRIT_PRE_() - - curr = (QActive *)0; /* means that mutex is NOT available */ -} -QF_CRIT_X_(); - -return curr != (QActive *)0; - - - - /*! unlock the QXK priority-ceiling mutex ::QXMutex -* @public @memberof QXMutex -*! -* @param[in,out] me current instance pointer (see @ref oop) -* -* @note -* This function **can** be called from both basic threads (active objects) -* and extended threads. -* -* @note -* The mutex locks are allowed to nest, meaning that the same extended thread -* can lock the same mutex multiple times (<= 225). However, each call to -* QXMutex_lock() or a *successful* call to QXMutex_tryLock() must be -* balanced by the matching call to QXMutex_unlock(). -* -* @usage -* @include qxk_mutex.c -*/ - QF_CRIT_STAT_ -QF_CRIT_E_(); - -QActive *curr = QXK_attr_.curr; -if (curr == (QActive *)0) { /* called from a basic thread? */ - curr = QActive_registry_[QXK_attr_.actPrio]; -} - -/*! @pre this function must: -* - NOT be called from an ISR; -* - the calling thread must be valid; -*/ -Q_REQUIRE_ID(400, (!QXK_ISR_CONTEXT_()) /* don't call from an ISR! */ - && (curr != (QActive *)0)); /* current thread must be valid */ - -/*! @pre also: the mutex must be already locked at least once. */ -Q_REQUIRE_ID(401, me->ao.eQueue.nFree > 0U); -/*! @pre also: the mutex must be held by this thread. */ -Q_REQUIRE_ID(402, me->ao.thread == curr); - -/* is this the last nesting level? */ -if (me->ao.eQueue.nFree == 1U) { - - if (me->ao.prio != 0U) { /* priority-ceiling protocol used? */ - - /* restore the holding thread's prio from the mutex */ - curr->prio = (uint8_t)me->ao.eQueue.head; - - /* put the mutex back into the AO registry */ - QActive_registry_[me->ao.prio] = &me->ao; - - /* remove the mutex' prio from the ready set - * and insert the original thread's priority - */ - QPSet_remove(&QF_readySet_, (uint_fast8_t)me->ao.prio); - QPSet_insert(&QF_readySet_, (uint_fast8_t)me->ao.eQueue.head); - } - - QS_BEGIN_NOCRIT_PRE_(QS_MTX_UNLOCK, curr->prio) - QS_TIME_PRE_(); /* timestamp */ - QS_OBJ_PRE_(me); /* this mutex */ - QS_2U8_PRE_((uint8_t)me->ao.eQueue.head, /* holder prio */ - 0U); /* nesting */ - QS_END_NOCRIT_PRE_() - - /* are any other threads waiting on this mutex? */ - if (QPSet_notEmpty(&me->waitSet)) { - /* find the highest-priority thread waiting on this mutex */ - uint_fast8_t const p = QPSet_findMax(&me->waitSet); - - /* remove this thread from waiting on the mutex - * and insert it into the ready set. - */ - QPSet_remove(&me->waitSet, p); - QPSet_insert(&QF_readySet_, p); - - QXThread * const thr = - QXK_PTR_CAST_(QXThread*, QActive_registry_[p]); - - /* the waiting thread must: - * - be registered in QF - * - have the priority corresponding to the registration - * - be an extended thread - * - be blocked on this mutex - */ - Q_ASSERT_ID(410, (thr != (QXThread *)0) - && (thr->super.prio == (uint8_t)p) - && (thr->super.super.state.act == Q_ACTION_CAST(0)) - && (thr->super.super.temp.obj - == QXK_PTR_CAST_(QMState*, me))); - - /* disarm the internal time event */ - (void)QXThread_teDisarm_(thr); - - /* set the new mutex holder to the curr thread and - * save the thread's prio in the mutex - * NOTE: reuse the otherwise unused eQueue data member. - */ - me->ao.thread = thr; - me->ao.eQueue.head = (QEQueueCtr)thr->super.prio; - - QS_BEGIN_NOCRIT_PRE_(QS_MTX_LOCK, thr->super.prio) - QS_TIME_PRE_(); /* timestamp */ - QS_OBJ_PRE_(me); /* this mutex */ - QS_U8_PRE_((uint8_t)me->ao.eQueue.head); /* holder prio */ - QS_U8_PRE_((uint8_t)me->ao.eQueue.nFree); /* nesting */ - QS_END_NOCRIT_PRE_() - - if (me->ao.prio != 0U) { /* priority-ceiling protocol used? */ - /* the holder priority must be lower than that of the mutex */ - Q_ASSERT_ID(410, thr->super.prio < me->ao.prio); - - /* put the thread into AO registry in place of the mutex */ - QActive_registry_[me->ao.prio] = &thr->super; - } - } - else { /* no threads are waiting for this mutex */ - me->ao.eQueue.nFree = 0U; /* free up the nesting count */ - - /* the mutex no longer held by any thread */ - me->ao.thread = (void *)0; - me->ao.eQueue.head = 0U; - - if (me->ao.prio != 0U) { /* priority-ceiling protocol used? */ - /* put the mutex back at the original mutex slot */ - QActive_registry_[me->ao.prio] = - QXK_PTR_CAST_(QActive*, me); - } - } - - /* schedule the next thread if multitasking started */ - if (QXK_sched_() != 0U) { /* activation needed? */ - QXK_activate_(); /* synchronously activate basic-thred(s) */ - } -} -else { /* releasing one level of nested mutex lock */ - Q_ASSERT_ID(420, me->ao.eQueue.nFree > 0U); - --me->ao.eQueue.nFree; /* unlock one level */ - - QS_BEGIN_NOCRIT_PRE_(QS_MTX_UNLOCK_ATTEMPT, curr->prio) - QS_TIME_PRE_(); /* timestamp */ - QS_OBJ_PRE_(me); /* this mutex */ - QS_U8_PRE_((uint8_t)me->ao.eQueue.head); /* holder prio */ - QS_U8_PRE_((uint8_t)me->ao.eQueue.nFree); /* nesting */ - QS_END_NOCRIT_PRE_() -} -QF_CRIT_X_(); - - - - - - - /*! @brief The QXK kernel class -* @class QXK -* -* @note -* The order and alignment of the data members in this struct might -* be important in QXK ports, where the members might be accessed -* in assembly. -*/ - { - struct QActive * volatile curr; /*!< current thread (NULL=basic) */ - struct QActive * volatile next; /*!< next thread to run */ - struct QActive * volatile prev; /*!< previous thread */ - uint8_t volatile actPrio; /*!< QF-prio of the active AO */ - uint8_t volatile lockCeil; /*!< lock-ceiling (0==no-lock) */ - uint8_t volatile lockHolder; /*!< prio of the lock holder */ -} QXK; - - - - /*! attributes of the QXK kernel */ - - - - /*! QXK scheduler finds the highest-priority thread ready to run -* @static @private @memberof QXK -* -* @details -* The QXK scheduler finds the priority of the highest-priority thread -* that is ready to run. -* -* @returns -* the 1-based priority of the the thread (basic or extended) run next, -* or zero if no eligible thread is found. -* -* @attention -* QXK_sched_() must be always called with interrupts **disabled** and -* returns with interrupts **disabled**. -*/ - uint_fast8_t p; - -if (QPSet_isEmpty(&QF_readySet_)) { - p = 0U; /* no activation needed */ -} -else { - /* find the highest-prio thread ready to run */ - p = QPSet_findMax(&QF_readySet_); - if (p <= QXK_attr_.lockCeil) { - /* priority of the thread holding the lock */ - p = (uint_fast8_t)QActive_registry_[QXK_attr_.lockHolder]->prio; - if (p != 0U) { - Q_ASSERT_ID(610, QPSet_hasElement(&QF_readySet_, p)); - } - } -} -QActive const * const curr = QXK_attr_.curr; -QActive * const next = QActive_registry_[p]; - -/* the next thread found must be registered in QF */ -Q_ASSERT_ID(620, next != (QActive *)0); - -/* is the current thread a basic-thread? */ -if (curr == (QActive *)0) { - - /* is the new priority above the active priority? */ - if (p > QXK_attr_.actPrio) { - QXK_attr_.next = next; /* set the next AO to activate */ - - if (next->osObject != (void *)0) { /* is next extended? */ - QXK_CONTEXT_SWITCH_(); - p = 0U; /* no activation needed */ - } - } - else { /* below the pre-thre */ - QXK_attr_.next = (QActive *)0; - p = 0U; /* no activation needed */ - } -} -else { /* currently executing an extended-thread */ - /* is the current thread different from the next? */ - if (curr != next) { - QXK_attr_.next = next; - QXK_CONTEXT_SWITCH_(); - } - else { /* current is the same as next */ - QXK_attr_.next = (QActive *)0; /* no need to context-switch */ - } - p = 0U; /* no activation needed */ -} -return p; - - - - /*! QXK activator activates the next active object. The activated AO -* preempts the currently executing AOs. -* @static @private @memberof QXK -* -* @details -* QXK_activate_() activates ready-to run AOs that are above the initial -* active priority (QXK_attr_.actPrio). -* -* @attention -* QXK_activate_() must be always called with interrupts **disabled** and -* returns with interrupts **disabled**. -*/ - uint8_t const prio_in = QXK_attr_.actPrio; -QActive *next = QXK_attr_.next; /* the next AO (basic-thread) to run */ - -/*! @pre QXK_attr_.next must be valid and the prio must be in range */ -Q_REQUIRE_ID(700, (next != (QActive *)0) && (prio_in <= QF_MAX_ACTIVE)); - -/* QXK Context switch callback defined or QS tracing enabled? */ -#if (defined QF_ON_CONTEXT_SW) || (defined Q_SPY) -QXK_contextSw(next); -#endif /* QF_ON_CONTEXT_SW || Q_SPY */ - -QXK_attr_.next = (QActive *)0; /* clear the next AO */ -QXK_attr_.curr = (QActive *)0; /* current is basic-thread */ - -/* priority of the next thread */ -uint8_t p = next->prio; - -/* loop until no more ready-to-run AOs of higher prio than the initial */ -do { - QXK_attr_.actPrio = p; /* next active prio */ - - QF_INT_ENABLE(); /* unconditionally enable interrupts */ - - /* perform the run-to-completion (RTC) step... - * 1. retrieve the event from the AO's event queue, which by this - * time must be non-empty and QActive_get_() asserts it. - * 2. dispatch the event to the AO's state machine. - * 3. determine if event is garbage and collect it if so - */ - QEvt const * const e = QActive_get_(next); - QHSM_DISPATCH(&next->super, e, next->prio); -#if (QF_MAX_EPOOL > 0U) - QF_gc(e); -#endif - - QF_INT_DISABLE(); /* unconditionally disable interrupts */ - - if (next->eQueue.frontEvt == (QEvt *)0) { /* empty queue? */ - QPSet_remove(&QF_readySet_, p); - } - - if (QPSet_isEmpty(&QF_readySet_)) { - QXK_attr_.next = (QActive *)0; - next = QActive_registry_[0]; - p = 0U; /* no activation needed */ - } - else { - /* find next highest-prio below the lock ceiling */ - p = (uint8_t)QPSet_findMax(&QF_readySet_); - if (p <= QXK_attr_.lockCeil) { - p = QXK_attr_.lockHolder; /* thread holding lock */ - if (p != 0U) { - Q_ASSERT_ID(710, QPSet_hasElement(&QF_readySet_, p)); - } - } - - /* set the next thread and ensure that it is registered */ - next = QActive_registry_[p]; - Q_ASSERT_ID(720, next != (QActive *)0); - - /* is next a basic thread? */ - if (next->osObject == (void *)0) { - /* is the next priority above the initial priority? */ - if (p > QActive_registry_[prio_in]->prio) { -#if (defined QF_ON_CONTEXT_SW) || (defined Q_SPY) - if (p != QXK_attr_.actPrio) { /* changing threads? */ - QXK_contextSw(next); - } -#endif /* QF_ON_CONTEXT_SW || Q_SPY */ - QXK_attr_.next = next; - } - else { - QXK_attr_.next = (QActive *)0; - p = 0U; /* no activation needed */ - } - } - else { /* next is the extended-thread */ - QXK_attr_.next = next; - QXK_CONTEXT_SWITCH_(); - p = 0U; /* no activation needed */ - } - } -} while (p != 0U); /* while activation needed */ - -/* restore the active priority */ -QXK_attr_.actPrio = prio_in; - -#if (defined QF_ON_CONTEXT_SW) || (defined Q_SPY) -if (next->osObject == (void *)0) { - QXK_contextSw((prio_in == 0U) - ? (QActive *)0 - : QActive_registry_[prio_in]); -} -#endif /* QF_ON_CONTEXT_SW || Q_SPY */ - - - - /*! obtain the currently executing active-object/thread -* @static @public @memberof QXK -* -* @returns -* pointer to the currently executing active-object/thread -*/ - /*! @pre the QXK kernel must be running */ -Q_REQUIRE_ID(800, QXK_attr_.lockCeil <= QF_MAX_ACTIVE); - -QF_CRIT_STAT_ -QF_CRIT_E_(); - -struct QActive *curr = QXK_attr_.curr; -if (curr == (QActive *)0) { /* basic thread? */ - curr = QActive_registry_[QXK_attr_.actPrio]; -} -QF_CRIT_X_(); - -/*! @post the current thread must be valid */ -Q_ENSURE_ID(890, curr != (QActive *)0); - -return curr; - - - - /*! initialize the private stack of a given AO (defined in QXK port) */ - - - - - - - - - - - - /*! QXK context switch management -* @static @public @memberof QXK -* -* @details -* This function performs software tracing (if #Q_SPY is defined) -* and calls QF_onContextSw() (if #QF_ON_CONTEXT_SW is defined) -* -* @param[in] next pointer to the next thread (NULL for basic-thread) -* -* @attention -* QXK_contextSw() is invoked with interrupts **disabled** and must also -* return with interrupts **disabled**. -*/ - - - #ifdef Q_SPY -uint8_t const prev_prio = (QXK_attr_.prev != (QActive *)0) - ? QXK_attr_.prev->prio - : 0U; -#endif /* Q_SPY */ - -if (next != (QActive *)0) { /* next is NOT idle? */ - QS_BEGIN_NOCRIT_PRE_(QS_SCHED_NEXT, next->prio) - QS_TIME_PRE_(); /* timestamp */ - QS_2U8_PRE_(next->prio, prev_prio); - QS_END_NOCRIT_PRE_() -} -else { /* going to idle */ - QS_BEGIN_NOCRIT_PRE_(QS_SCHED_IDLE, prev_prio) - QS_TIME_PRE_(); /* timestamp */ - QS_U8_PRE_(prev_prio); - QS_END_NOCRIT_PRE_() -} - -#ifdef QF_ON_CONTEXT_SW - QF_onContextSw(QXK_attr_.prev, next); -#endif /* QF_ON_CONTEXT_SW */ - -QXK_attr_.prev = next; /* update the previous thread */ - - - - - - - - /*! Virtual call to start an extened thread -* -* @details -* Starts execution of the thread and registers the AO with the framework. -* -* @param[in,out] me_ current instance pointer (see @ref oop) -* @param[in] prioSpec_ priority specification at which to start the -* extended thread (see ::QPrioSpec) -* @param[in] qSto_ pointer to the storage for the ring buffer of the -* event queue (used only with the built-in ::QEQueue) -* @param[in] qLen_ length of the event queue (in events) -* @param[in] stkSto_ pointer to the stack storage (used only when -* per-AO stack is needed) -* @param[in] stkSize_ stack size (in bytes) -* @param[in] par_ pointer to the additional port-specific parameter(s) -* (might be NULL). -* @usage -* @include qxk_start.c -*/ - - - - - - - - - - - - - - - \ -do { \ - Q_ASSERT((me_)->super.super.vptr); \ - ((*((QActiveVtable const *)((me_)->super.super.vptr))->start)( \ - &(me_)->super, (prioSpec_), (QEvt const **)(qSto_), (qLen_), \ - (stkSto_), (stkSize_), (par_))); \ -} while (false) - - - - /*! No-timeout when blocking on semaphores, mutextes, and queues */ - ((uint_fast16_t)0) - - - - /*! Asynchronous posting events to the event queue of an eXtended thread -* @details -* This macro does not assert if the queue overflows and cannot accept -* the event with the specified margin of free slots remaining. -* -* @param[in,out] me_ current instance pointer (see @ref oop) -* @param[in] e_ pointer to the event to post -* @param[in] margin_ the minimum free slots in the queue, which -* must still be available after posting the event. -* The special value #QF_NO_MARGIN causes asserting -* failure in case event allocation fails. -* @param[in] sender_ pointer to the sender object (used in QS tracing) -* -* @returns -* 'true' if the posting succeeded, and 'false' if the posting failed due -* to insufficient margin of free slots available in the queue. -* -* @note -* The `sender_` parameter is actually only used when QS tracing is enabled -* (macro #Q_SPY is defined). When QS software tracing is disabled, the -* QXTHREAD_POST_X() macro does not pass the `sender_` parameter, so the -* overhead of passing this extra argument is entirely avoided. -* -* @note -* The pointer to the sender object is not necessarily a pointer to an -* active object. In fact, if QXTHREAD_POST_X() is called from an interrupt -* or other context, you can create a unique object just to unambiguously -* identify the sender of the event. -* -* @usage -* @include qf_postx.c -*/ - - - - - - - - - \ - QACTIVE_POST_X(&(me_)->super, (e_), (margin_), (sender_)) - - - - - - - /*! Internal macro that reports the execution context (ISR vs. thread) -* -* @returns true if the code executes in the ISR context and false -* otherwise -*/ - (QF_intNest_ != 0U) - - - - /*! QXK scheduler lock status */ - QSchedStatus lockStat_; - - - - /*! QXK selective scheduler locking */ - - - do { \ - if (QXK_ISR_CONTEXT_()) { \ - lockStat_ = 0xFFU; \ - } else { \ - lockStat_ = QXK_schedLock((ceil_)); \ - } \ -} while (false) - - - - /*! QXK selective scheduler unlocking */ - do { \ - if (lockStat_ != 0xFFU) { \ - QXK_schedUnlock(lockStat_); \ - } \ -} while (false) - - - - /*! QXK native event queue waiting */ - - - \ - (Q_ASSERT_ID(110, (me_)->eQueue.frontEvt != (QEvt *)0)) - - - - /*! QXK native event queue signaling */ - - - do { \ - QPSet_insert(&QF_readySet_, (uint_fast8_t)(me_)->prio); \ - if (!QXK_ISR_CONTEXT_()) { \ - if (QXK_sched_() != 0U) { \ - QXK_activate_(); \ - } \ - } \ -} while (false) - - - - <type_> - /*! internal macro to encapsulate casting of pointers for MISRA deviations -* -* @details -* This macro is specifically and exclusively used for casting pointers -* that are never de-referenced, but only used for internal bookkeeping and -* checking (via assertions) the correct operation of the QXK kernel. -* Such pointer casting is not compliant with MISRA-2012-Rule 11.3(req) -* as well as other messages (e.g., PC-Lint-Plus warning 826). -* Defining this specific macro for this purpose allows to selectively -* disable the warnings for this particular case. -*/ - - - - - ((type_)(ptr_)) - - - - /*! internal macro to encapsulate casting of pointers for MISRA deviations -* -* @details -* This macro is specifically and exclusively used for downcasting pointers -* to QActive to pointers to QXThread in situations when it is known -* that such downcasting is correct.However, such pointer casting is not -* compliant with MISRA-2012-Rule 11.3(req) as well as other messages (e.g., -* PC-Lint-Plus warning 826). Defining this specific macro for this purpose -* allows to selectively disable the warnings for this particular case. -*/ - - - ((QXThread *)(ptr_)) - - - - /*! called when QXThread exits -* @private @memberof QXThread -* -* @details -* Called when the extended-thread handler function returns. -* -* @note -* Most thread handler functions are structured as endless loops that never -* return. But it is also possible to structure threads as one-shot functions -* that perform their job and return. In that case this function peforms -* cleanup after the thread. -*/ - - QF_CRIT_STAT_ -QF_CRIT_E_(); - -QXThread const * const thr = QXTHREAD_CAST_(QXK_attr_.curr); - -/*! @pre this function must: -* - NOT be called from an ISR; -* - be called from an extended thread; -*/ -Q_REQUIRE_ID(900, (!QXK_ISR_CONTEXT_()) /* can't be in the ISR context */ - && (thr != (QXThread *)0)); /* current thread must be extended */ -/*! @pre also: the thread must NOT be holding a scheduler lock. */ -Q_REQUIRE_ID(901, QXK_attr_.lockHolder != thr->super.prio); - -uint_fast8_t const p = (uint_fast8_t)thr->super.prio; - -/* remove this thread from the QF */ -QActive_registry_[p] = (QActive *)0; -QPSet_remove(&QF_readySet_, p); -(void)QXK_sched_(); /* schedule other threads */ -QF_CRIT_X_(); - - - - - - - /*!* @file -* @brief Customizable and memory-efficient Design by Contract (DbC) -* for embedded systems -* -* @note -* This header file can be used in C, C++, and mixed C/C++ programs. -* -* @note -* The preprocessor switch #Q_NASSERT disables checking assertions. -* However, it is generally __not__ advisable to disable assertions, -* __especially__ in the production code. Instead, the assertion handler -* Q_onAssert() should be very carefully designed and tested. -*/ -#ifndef QP_INC_QASSERT_H_ -#define QP_INC_QASSERT_H_ - -#ifdef __cplusplus - extern "C" { -#endif - -$declare ${DbC} - -#ifdef __cplusplus - } -#endif - -#endif /* QP_INC_QASSERT_H_ */ - - - - /*! @file -* @brief QEP/C platform-independent public interface. -* -* @tr{RQP001} @tr{RQP101} -*/ -#ifndef QP_INC_QEP_H_ -#define QP_INC_QEP_H_ - -/*==========================================================================*/ -/*! The current QP version as an unsigned number -* -* @details -* ::QP_VERSION is a decimal constant, where XX is a 1-digit or 2-digit -* major version number, Y is a 1-digit minor version number, and Z is -* a 1-digit release number. -*/ -#define QP_VERSION 721U - -/*! The current QP version as a zero terminated string literal. -* -* @details -* ::QP_VERSION_STR is of the form "XX.Y.Z", where XX is a 1-or 2-digit -* major version number, Y is a 1-digit minor version number, and Z is -* a 1-digit release number. -*/ -#define QP_VERSION_STR "7.2.1" - -/*! Encrypted current QP release (7.2.1) and date (2023-01-15) */ -#define QP_RELEASE 0x76D739FEU - -/*==========================================================================*/ -$declare ${glob-types} -$declare ${QEP-config} - -/*==========================================================================*/ -$declare ${QEP} - -/*==========================================================================*/ -$declare ${QEP-macros} - -#endif /* QP_INC_QEP_H_ */ - - - - /*! @file -* @brief QF/C platform-independent public interface. -*/ -#ifndef QP_INC_QF_H_ -#define QP_INC_QF_H_ - -/*==========================================================================*/ -$declare ${QF-config} - -/*==========================================================================*/ -$declare ${QF-types} -$declare ${QF::QActive} -$declare ${QF::QActiveVtable} -$declare ${QF::QMActive} -$declare ${QF::QMActiveVtable} -$declare ${QF::QTimeEvt} -$declare ${QF::QTicker} - -$declare ${QF::QF-base} -$declare ${QF::QF-dyn} -$declare ${QF::QF-extern-C} - -/*==========================================================================*/ -$declare ${QF-macros} - -#endif /* QP_INC_QF_H_ */ - - - - /*! @file -* @brief Internal (package scope) QF/C interface. -*/ -#ifndef QP_INC_QF_PKG_H_ -#define QP_INC_QF_PKG_H_ - -/*==========================================================================*/ -$declare ${QF::QF-pkg} - -/*==========================================================================*/ -/* QF-specific critical section */ -#ifndef QF_CRIT_STAT_TYPE - /*! This is an internal macro for defining the critical section - * status type. */ - /** - * @details - * The purpose of this macro is to enable writing the same code for the - * case when critical section status type is defined and when it is not. - * If the macro #QF_CRIT_STAT_TYPE is defined, this internal macro - * provides the definition of the critical section status variable. - * Otherwise this macro is empty. - * @sa #QF_CRIT_STAT_TYPE - */ - #define QF_CRIT_STAT_ - - /*! This is an internal macro for entering a critical section. */ - /** - * @details - * The purpose of this macro is to enable writing the same code for the - * case when critical section status type is defined and when it is not. - * If the macro #QF_CRIT_STAT_TYPE is defined, this internal macro - * invokes QF_CRIT_ENTRY() passing the key variable as the parameter. - * Otherwise QF_CRIT_ENTRY() is invoked with a dummy parameter. - * @sa QF_CRIT_ENTRY() - */ - #define QF_CRIT_E_() QF_CRIT_ENTRY(dummy) - - /*! This is an internal macro for exiting a critical section. */ - /** - * @details - * The purpose of this macro is to enable writing the same code for the - * case when critical section status type is defined and when it is not. - * If the macro #QF_CRIT_STAT_TYPE is defined, this internal macro - * invokes #QF_CRIT_EXIT passing the key variable as the parameter. - * Otherwise #QF_CRIT_EXIT is invoked with a dummy parameter. - * @sa #QF_CRIT_EXIT - */ - #define QF_CRIT_X_() QF_CRIT_EXIT(dummy) - -#elif (!defined QF_CRIT_STAT_) - #define QF_CRIT_STAT_ QF_CRIT_STAT_TYPE critStat_; - #define QF_CRIT_E_() QF_CRIT_ENTRY(critStat_) - #define QF_CRIT_X_() QF_CRIT_EXIT(critStat_) -#endif - -/*==========================================================================*/ -/* Assertions inside the critical section */ -#ifdef Q_NASSERT /* Q_NASSERT defined--assertion checking disabled */ - - #define Q_ASSERT_CRIT_(id_, test_) ((void)0) - #define Q_REQUIRE_CRIT_(id_, test_) ((void)0) - #define Q_ERROR_CRIT_(id_) ((void)0) - -#else /* Q_NASSERT not defined--assertion checking enabled */ - - #define Q_ASSERT_CRIT_(id_, test_) do { \ - if ((test_)) {} else { \ - QF_CRIT_X_(); \ - Q_onAssert(&Q_this_module_[0], (int_t)(id_)); \ - } \ - } while (false) - - #define Q_REQUIRE_CRIT_(id_, test_) Q_ASSERT_CRIT_((id_), (test_)) - - #define Q_ERROR_CRIT_(id_) do { \ - QF_CRIT_X_(); \ - Q_onAssert(&Q_this_module_[0], (int_t)(id_)); \ - } while (false) - -#endif /* Q_NASSERT */ - -/*==========================================================================*/ - -/* The following bitmasks are for the fields of the @c refCtr_ attribute -* of the QTimeEvt struct (inherited from QEvt). This attribute is NOT used -* for reference counting in time events, because the @c poolId_ attribute -* is zero ("immutable events"). -*/ -#define QTE_IS_LINKED (1U << 7U) -#define QTE_WAS_DISARMED (1U << 6U) -#define QTE_TICK_RATE 0x0FU - -/*! @brief structure representing a free block in the Native QF Memory Pool */ -typedef struct QFreeBlock { - struct QFreeBlock * volatile next; -} QFreeBlock; - -/* internal helper macros ==================================================*/ - -/*! increment the refCtr of a const event (requires casting `const` away) -* @private @memberof QEvt -* -* @tr{PQP11_8} -*/ -static inline void QEvt_refCtr_inc_(QEvt const *me) { - ++((QEvt *)me)->refCtr_; -} - -/*! decrement the refCtr of a const event (requires casting `const` away) -* @private @memberof QEvt -* -* @tr{PQP11_8} -*/ -static inline void QEvt_refCtr_dec_(QEvt const *me) { - --((QEvt *)me)->refCtr_; -} - -#endif /* QP_INC_QF_PKG_H_ */ - - - - /*! @file -* @brief QP natvie, platform-independent, thread-safe event queue interface -* @details -* This header file must be included in all QF ports that use native QF -* event queue for active objects. Also, this file needs to be included -* in the QP/C library when the application uses QActive_defer()/ -* QActive_recall(). Finally, this file is also needed when the "raw" -* thread-safe queues are used for communication between active objects -* and non-framework entities, such as ISRs, device drivers, or legacy -* code. -*/ -#ifndef QP_INC_QEQUEUE_H_ -#define QP_INC_QEQUEUE_H_ - -#ifndef QF_EQUEUE_CTR_SIZE - - /*! The size [bytes] of the ring-buffer counters used in the - * native QF event queue implementation. Valid values: 1U, 2U, or 4U; - * default 1U. - * @details - * This macro can be defined in the QF port file (qf_port.h) to - * configure the ::QEQueueCtr type. Here the macro is not defined so the - * default of 1 byte is chosen. - */ - #define QF_EQUEUE_CTR_SIZE 1U -#endif -#if (QF_EQUEUE_CTR_SIZE == 1U) - - /*! The data type to store the ring-buffer counters based on - * the macro #QF_EQUEUE_CTR_SIZE. - * @details - * The dynamic range of this data type determines the maximum length - * of the ring buffer managed by the native QF event queue. - */ - typedef uint8_t QEQueueCtr; -#elif (QF_EQUEUE_CTR_SIZE == 2U) - typedef uint16_t QEQueueCtr; -#elif (QF_EQUEUE_CTR_SIZE == 4U) - typedef uint32_t QEQueueCtr; -#else - #error "QF_EQUEUE_CTR_SIZE defined incorrectly, expected 1U, 2U, or 4U" -#endif - -/*==========================================================================*/ -$declare ${QF::QEQueue} - -#endif /* QP_INC_QEQUEUE_H_ */ - - - - /*! @file -* @brief QP native, platform-independent memory pool ::QMPool interface. -*/ -#ifndef QP_INC_QMPOOL_H_ -#define QP_INC_QMPOOL_H_ - -/*==========================================================================*/ -#ifndef QF_MPOOL_SIZ_SIZE - /*! macro to override the default ::QMPoolSize size [bytes]. - * Valid values 1U, 2U, or 4U; default 2U - */ - #define QF_MPOOL_SIZ_SIZE 2U -#endif -#if (QF_MPOOL_SIZ_SIZE == 1U) - - /*! The data type to store the block-size based on the macro - * #QF_MPOOL_SIZ_SIZE. - * @details - * The dynamic range of this data type determines the maximum size - * of blocks that can be managed by the native QF event pool. - */ - typedef uint8_t QMPoolSize; -#elif (QF_MPOOL_SIZ_SIZE == 2U) - - typedef uint16_t QMPoolSize; -#elif (QF_MPOOL_SIZ_SIZE == 4U) - typedef uint32_t QMPoolSize; -#else - #error "QF_MPOOL_SIZ_SIZE defined incorrectly, expected 1U, 2U, or 4U" -#endif - -/*==========================================================================*/ -#ifndef QF_MPOOL_CTR_SIZE - /*! macro to override the default ::QMPoolCtr size [bytes]. - * Valid values 1U, 2U, or 4U; default 2U - */ - #define QF_MPOOL_CTR_SIZE 2U -#endif -#if (QF_MPOOL_CTR_SIZE == 1U) - - /*! The data type to store the block-counter based on the macro - * #QF_MPOOL_CTR_SIZE. - * @details - * The dynamic range of this data type determines the maximum number - * of blocks that can be stored in the pool. - */ - typedef uint8_t QMPoolCtr; -#elif (QF_MPOOL_CTR_SIZE == 2U) - typedef uint16_t QMPoolCtr; -#elif (QF_MPOOL_CTR_SIZE == 4U) - typedef uint32_t QMPoolCtr; -#else - #error "QF_MPOOL_CTR_SIZE defined incorrectly, expected 1U, 2U, or 4U" -#endif - -/*! Memory pool element to allocate correctly aligned storage -* for QMPool class. -* @param[in] evType_ event type (name of the subclass of QEvt) -*/ -#define QF_MPOOL_EL(evType_) \ - struct { void *sto_[((sizeof(evType_) - 1U)/sizeof(void*)) + 1U]; } - -/*==========================================================================*/ -$declare ${QF::QMPool} - -#endif /* QP_INC_QMPOOL_H_ */ - - - - /*! @file -* @brief QV/C (cooperative "Vanilla" kernel) platform-independent -* public interface -*/ -#ifndef QP_INC_QV_H_ -#define QP_INC_QV_H_ - -/*==========================================================================*/ -/* QF customization for QV -- data members of the QActive class... */ - -/* QV event-queue used for AOs */ -#define QF_EQUEUE_TYPE QEQueue - -/*==========================================================================*/ -#include "qequeue.h" /* QV kernel uses the native QP event queue */ -#include "qmpool.h" /* QV kernel uses the native QP memory pool */ -#include "qf.h" /* QF framework integrates directly with QV */ - -//============================================================================ -$declare ${QV::QV-base} - -/*==========================================================================*/ -/* interface used only inside QF, but not in applications */ -#ifdef QP_IMPL -/* QV-specific scheduler locking and event queue... */ -$declare ${QV-impl} - -/* Native QF event pool operations... */ -$declare ${QF-QMPool-impl} -#endif /* QP_IMPL */ - -#endif /* QP_INC_QV_H_ */ - - - - /*! @file -* @brief QK/C (preemptive non-blocking kernel) platform-independent -* public interface. -*/ -#ifndef QP_INC_QK_H_ -#define QP_INC_QK_H_ - -/*==========================================================================*/ -/* QF configuration for QK -- data members of the QActive class... */ - -/* QK event-queue used for AOs */ -#define QF_EQUEUE_TYPE QEQueue - -/* QK thread type used for AOs -* QK uses this member to store the private Thread-Local Storage pointer. -*/ -#define QF_THREAD_TYPE void* - -#include "qequeue.h" /* QK kernel uses the native QP event queue */ -#include "qmpool.h" /* QK kernel uses the native QP memory pool */ -#include "qf.h" /* QF framework integrates directly with QK */ - -/*==========================================================================*/ -$declare ${QK::QK-base} -$declare ${QK::QK-extern-C} - -/*==========================================================================*/ -/* interface used only inside QF, but not in applications */ -#ifdef QP_IMPL -/* QK-specific scheduler locking and event queue... */ -$declare ${QK-impl} - -/* Native QF event pool operations... */ -$declare ${QF-QMPool-impl} -#endif /* QP_IMPL */ - -#endif /* QP_INC_QK_H_ */ - - - - /*! @file -* @brief QXK/C (preemptive dual-mode kernel) platform-independent -* public interface. -*/ -#ifndef QP_INC_QXK_H_ -#define QP_INC_QXK_H_ - -/*==========================================================================*/ -/* QF configuration for QXK -- data members of the QActive class... */ - -/* QXK event-queue used for AOs */ -#define QF_EQUEUE_TYPE QEQueue - -/* QXK OS-object used to store the private stack pointer for extended threads. -* (The private stack pointer is NULL for basic-threads). -*/ -#define QF_OS_OBJECT_TYPE void* - -/* QXK thread type used to store the private Thread-Local Storage pointer */ -#define QF_THREAD_TYPE void* - -/*! Access Thread-Local Storage (TLS) and cast it on the given `type_` */ -#define QXK_TLS(type_) ((type_)QXK_current()->thread) - -/*==========================================================================*/ -#include "qequeue.h" /* QXK kernel uses the native QP event queue */ -#include "qmpool.h" /* QXK kernel uses the native QP memory pool */ -#include "qf.h" /* QF framework integrates directly with QXK */ - -/*==========================================================================*/ -$declare ${QXK::QXK-base} -$declare ${QXK::QXK-extern-C} -$declare ${QXK::QXThread} -$declare ${QXK::QXThreadVtable} -$declare ${QXK::QXSemaphore} -$declare ${QXK::QXMutex} -$declare ${QXK-macros} - -/*==========================================================================*/ -/* interface used only inside QP implementation, but not in applications */ -#ifdef QP_IMPL -/* QXK implementation... */ -$declare ${QXK-impl} - -/* Native QF event pool operations... */ -$declare ${QF-QMPool-impl} -#endif /* QP_IMPL */ - -#endif /* QP_INC_QXK_H_ */ - - - - /*! @file -* @brief QS/C platform-independent public interface. -*/ -#ifndef QP_INC_QS_H_ -#define QP_INC_QS_H_ - -#ifndef Q_SPY - #error "Q_SPY must be defined to include qs.h" -#endif - -/*==========================================================================*/ -$declare ${QS-config} - -/*==========================================================================*/ -$declare ${QS} - -/*==========================================================================*/ -$declare ${QS-macros} - -/*==========================================================================*/ -/* Facilities for QS critical section */ - -/* QS-specific critical section */ -#ifdef QS_CRIT_ENTRY /* separate QS critical section defined? */ - -#ifndef QS_CRIT_STAT_TYPE - #define QS_CRIT_STAT_ - #define QS_CRIT_E_() QS_CRIT_ENTRY(dummy) - #define QS_CRIT_X_() QS_CRIT_EXIT(dummy); QS_REC_DONE() -#else - #define QS_CRIT_STAT_ QS_CRIT_STAT_TYPE critStat_; - #define QS_CRIT_E_() QS_CRIT_ENTRY(critStat_) - #define QS_CRIT_X_() QS_CRIT_EXIT(critStat_); QS_REC_DONE() -#endif /* QS_CRIT_STAT_TYPE */ - -#else /* separate QS critical section not defined--use the QF definition */ - -#ifndef QF_CRIT_STAT_TYPE - /*! This is an internal macro for defining the critical section - * status type. - * @details - * The purpose of this macro is to enable writing the same code for the - * case when critical section status type is defined and when it is not. - * If the macro #QF_CRIT_STAT_TYPE is defined, this internal macro - * provides the definition of the critical section status variable. - * Otherwise this macro is empty. - * @sa #QF_CRIT_STAT_TYPE - */ - #define QS_CRIT_STAT_ - - /*! This is an internal macro for entering a critical section. - * @details - * The purpose of this macro is to enable writing the same code for the - * case when critical section status type is defined and when it is not. - * If the macro #QF_CRIT_STAT_TYPE is defined, this internal macro - * invokes QF_CRIT_ENTRY() passing the key variable as the parameter. - * Otherwise QF_CRIT_ENTRY() is invoked with a dummy parameter. - * @sa QF_CRIT_ENTRY() - */ - #define QS_CRIT_E_() QF_CRIT_ENTRY(dummy) - - /*! This is an internal macro for exiting a critical section. - * @details - * The purpose of this macro is to enable writing the same code for the - * case when critical section status type is defined and when it is not. - * If the macro #QF_CRIT_STAT_TYPE is defined, this internal macro - * invokes QF_CRIT_EXIT() passing the key variable as the parameter. - * Otherwise QF_CRIT_EXIT() is invoked with a dummy parameter. - * @sa QF_CRIT_EXIT() - */ - #define QS_CRIT_X_() QF_CRIT_EXIT(dummy); QS_REC_DONE() - -#elif (!defined QS_CRIT_STAT_) - - #define QS_CRIT_STAT_ QF_CRIT_STAT_TYPE critStat_; - #define QS_CRIT_E_() QF_CRIT_ENTRY(critStat_) - #define QS_CRIT_X_() QF_CRIT_EXIT(critStat_); QS_REC_DONE() - -#endif /* simple unconditional interrupt disabling used */ - -#endif /* separate QS critical section not defined */ - -/*==========================================================================*/ -/* Macros for use in QUTest only */ -#ifdef Q_UTEST - -$declare ${QUTest} - -/*--------------------------------------------------------------------------*/ -/* QP-stub for QUTest -* NOTE: The QP-stub is needed for unit testing QP applications, -* but might NOT be needed for testing QP itself. -*/ -#if Q_UTEST != 0 -$declare ${QUTest-stub::QS} -$declare ${QUTest-stub::QHsmDummy} -$declare ${QUTest-stub::QActiveDummy} -#endif /* Q_UTEST != 0 */ - -/*! QS macro to define the Test-Probe for a given `fun_` */ -#define QS_TEST_PROBE_DEF(fun_) \ - uint32_t const qs_tp_ = QS_getTestProbe_((void (*)(void))(fun_)); - -/*! QS macro to apply a Test-Probe */ -#define QS_TEST_PROBE(code_) \ - if (qs_tp_ != 0U) { code_ } - -/*! QS macro to apply a Test-Probe */ -#define QS_TEST_PROBE_ID(id_, code_) \ - if (qs_tp_ == (uint32_t)(id_)) { code_ } - -/*! QS macro to pause test execution and enter the test event-loop */ -#define QS_TEST_PAUSE() (QS_test_pause_()) - -#else /* Q_UTEST not defined */ - -/* dummy definitions when not building for QUTEST */ -#define QS_TEST_PROBE_DEF(fun_) -#define QS_TEST_PROBE(code_) -#define QS_TEST_PROBE_ID(id_, code_) -#define QS_TEST_PAUSE() ((void)0) - -#endif /* Q_UTEST */ - -#endif /* def QP_INC_QS_H_ */ - - - - /*! @file -* @brief Dummy definitions of the QS macros that avoid code generation from -* the QS instrumentation. -*/ -#ifndef QP_INC_QS_DUMMY_H_ -#define QP_INC_QS_DUMMY_H_ - -#ifdef Q_SPY - #error "Q_SPY must NOT be defined to include qs_dummy.h" -#endif - -#define QS_INIT(arg_) ((uint8_t)1U) -#define QS_EXIT() ((void)0) -#define QS_DUMP() ((void)0) -#define QS_GLB_FILTER(rec_) ((void)0) -#define QS_LOC_FILTER(qs_id_) ((void)0) - -#define QS_GET_BYTE(pByte_) ((uint16_t)0xFFFFU) -#define QS_GET_BLOCK(pSize_) ((uint8_t *)0) - -#define QS_BEGIN_ID(rec_, qs_id_) if (false) { -#define QS_END() } -#define QS_BEGIN_NOCRIT(rec_, qs_id_) if (false) { -#define QS_END_NOCRIT() } - -#define QS_I8(width_, data_) ((void)0) -#define QS_U8(width_, data_) ((void)0) -#define QS_I16(width_, data_) ((void)0) -#define QS_U16(width_, data_) ((void)0) -#define QS_I32(width_, data_) ((void)0) -#define QS_U32(width_, data_) ((void)0) -#define QS_F32(width_, data_) ((void)0) -#define QS_F64(width_, data_) ((void)0) -#define QS_I64(width_, data_) ((void)0) -#define QS_U64(width_, data_) ((void)0) -#define QS_ENUM(group_, value_) ((void)0) -#define QS_STR(str_) ((void)0) -#define QS_MEM(mem_, size_) ((void)0) -#define QS_SIG(sig_, obj_) ((void)0) -#define QS_OBJ(obj_) ((void)0) -#define QS_FUN(fun_) ((void)0) - -#define QS_SIG_DICTIONARY(sig_, obj_) ((void)0) -#define QS_OBJ_DICTIONARY(obj_) ((void)0) -#define QS_OBJ_ARR_DICTIONARY(obj_, idx_) ((void)0) -#define QS_FUN_DICTIONARY(fun_) ((void)0) -#define QS_USR_DICTIONARY(rec_) ((void)0) -#define QS_ENUM_DICTIONARY(value_, group_) ((void)0) -#define QS_ASSERTION(module_, loc_, delay_) ((void)0) -#define QS_FLUSH() ((void)0) - -#define QS_TEST_PROBE_DEF(fun_) -#define QS_TEST_PROBE(code_) -#define QS_TEST_PROBE_ID(id_, code_) -#define QS_TEST_PAUSE() ((void)0) - -#define QS_OUTPUT() ((void)0) -#define QS_RX_INPUT() ((void)0) - -/*==========================================================================*/ -/* internal QS macros used only in the QP components */ - -#ifdef QP_IMPL - /* predefined QS trace records */ - #define QS_BEGIN_PRE_(rec_, qs_id_) if (false) { - #define QS_END_PRE_() } - #define QS_BEGIN_NOCRIT_PRE_(rec_, qs_id_) if (false) { - #define QS_END_NOCRIT_PRE_() } - #define QS_U8_PRE_(data_) ((void)0) - #define QS_2U8_PRE_(data1_, data2_) ((void)0) - #define QS_U16_PRE_(data_) ((void)0) - #define QS_U32_PRE_(data_) ((void)0) - #define QS_TIME_PRE_() ((void)0) - #define QS_SIG_PRE_(sig_) ((void)0) - #define QS_EVS_PRE_(size_) ((void)0) - #define QS_OBJ_PRE_(obj_) ((void)0) - #define QS_FUN_PRE_(fun_) ((void)0) - #define QS_EQC_PRE_(ctr_) ((void)0) - #define QS_MPC_PRE_(ctr_) ((void)0) - #define QS_MPS_PRE_(size_) ((void)0) - #define QS_TEC_PRE_(ctr_) ((void)0) - - #define QS_CRIT_STAT_ - #define QF_QS_CRIT_ENTRY() ((void)0) - #define QF_QS_CRIT_EXIT() ((void)0) - #define QF_QS_ISR_ENTRY(isrnest_, prio_) ((void)0) - #define QF_QS_ISR_EXIT(isrnest_, prio_) ((void)0) - #define QF_QS_ACTION(act_) ((void)0) -#endif /* QP_IMPL */ - -#endif /* QP_INC_QS_DUMMY_H_ */ - - - - /*! @file -* @brief Internal (package scope) QS/C interface. -*/ -#ifndef QP_INC_QS_PKG_H_ -#define QP_INC_QS_PKG_H_ - -/*==========================================================================*/ - -/*! QS received record types (RX channel) -* @details -* This enumeration specifies the record types for the QS receive channel -*/ -enum QSpyRxRecords { - QS_RX_INFO, /*!< query Target info (ver, config, tstamp) */ - QS_RX_COMMAND, /*!< execute a user-defined command in the Target */ - QS_RX_RESET, /*!< reset the Target */ - QS_RX_TICK, /*!< call QTIMEEVT_TICK_X() in the Target */ - QS_RX_PEEK, /*!< peek Target memory */ - QS_RX_POKE, /*!< poke Target memory */ - QS_RX_FILL, /*!< fill Target memory */ - QS_RX_TEST_SETUP, /*!< test setup */ - QS_RX_TEST_TEARDOWN, /*!< test teardown */ - QS_RX_TEST_PROBE, /*!< set a Test-Probe in the Target */ - QS_RX_GLB_FILTER, /*!< set global filters in the Target */ - QS_RX_LOC_FILTER, /*!< set local filters in the Target */ - QS_RX_AO_FILTER, /*!< set local AO filter in the Target */ - QS_RX_CURR_OBJ, /*!< set the "current-object" in the Target */ - QS_RX_TEST_CONTINUE, /*!< continue a test after QS_TEST_PAUSE() */ - QS_RX_QUERY_CURR, /*!< query the "current object" in the Target */ - QS_RX_EVENT /*!< inject an event to the Target */ -}; - -/*==========================================================================*/ -/*! Frame character of the QS output protocol */ -#define QS_FRAME (0x7EU) - -/*! Escape character of the QS output protocol */ -#define QS_ESC (0x7DU) - -/*! The expected checksum value over a correct QS record */ -#define QS_GOOD_CHKSUM (0xFFU) - -/*! Escape modifier of the QS output protocol */ -/** -* @details -* The escaped byte is XOR-ed with the escape modifier before it is inserted -* into the QS buffer. -*/ -#define QS_ESC_XOR (0x20U) - -/*==========================================================================*/ -/*! Internal QS macro to begin a predefined QS record with -* entering critical section. -* -* @note This macro is intended to use only inside QP components and NOT -* at the application level. -* @sa QS_BEGIN_ID() -*/ -#define QS_BEGIN_PRE_(rec_, qs_id_) \ - if (QS_GLB_CHECK_(rec_) && QS_LOC_CHECK_(qs_id_)) { \ - QS_CRIT_E_(); \ - QS_beginRec_((uint_fast8_t)(rec_)); - -/*! Internal QS macro to end a predefined QS record with -* exiting critical section. -* -* @note This macro is intended to use only inside QP components and NOT -* at the application level. -* @sa QS_END() -*/ -#define QS_END_PRE_() \ - QS_endRec_(); \ - QS_CRIT_X_(); \ - } - -/*! Internal macro to begin a predefined QS record without -* entering critical section. -* -* @note This macro is intended to use only inside QP components and NOT -* at the application level. -* @sa QS_BEGIN_NOCRIT() -*/ -#define QS_BEGIN_NOCRIT_PRE_(rec_, qs_id_) \ - if (QS_GLB_CHECK_(rec_) && QS_LOC_CHECK_(qs_id_)) { \ - QS_beginRec_((uint_fast8_t)(rec_)); - -/*! Internal QS macro to end a predefined QS record without -* exiting critical section -* -* @note This macro is intended to use only inside QP components and NOT -* at the application level. @sa #QS_END_NOCRIT -*/ -#define QS_END_NOCRIT_PRE_() QS_endRec_(); } - -/*! Internal QS macro to output a predefined uint8_t data element */ -#define QS_U8_PRE_(data_) (QS_u8_raw_((uint8_t)(data_))) - -/*! Internal QS macro to output 2 predefined uint8_t data elements */ -#define QS_2U8_PRE_(data1_, data2_) \ - (QS_2u8_raw_((uint8_t)(data1_), (uint8_t)(data2_))) - -/*! Internal QS macro to output an predefined uint16_t data element */ -#define QS_U16_PRE_(data_) (QS_u16_raw_((uint16_t)(data_))) - -/*! Internal QS macro to output a predefined uint32_t data element */ -#define QS_U32_PRE_(data_) (QS_u32_raw_((uint32_t)(data_))) - -/*! Internal QS macro to output a predefined zero-terminated string element */ -#define QS_STR_PRE_(msg_) (QS_str_raw_((msg_))) - -#if (!defined Q_SIGNAL_SIZE || (Q_SIGNAL_SIZE == 1U)) - /*! Internal macro to output an unformatted event signal data element */ - /** - * @note the size of the pointer depends on the macro #Q_SIGNAL_SIZE. - */ - #define QS_SIG_PRE_(sig_) (QS_u8_raw_((uint8_t)sig_)) -#elif (Q_SIGNAL_SIZE == 2U) - #define QS_SIG_PRE_(sig_) (QS_u16_raw_((uint16_t)sig_)) -#elif (Q_SIGNAL_SIZE == 4U) - #define QS_SIG_PRE_(sig_) (QS_u32_raw_((uint32_t)sig_)) -#endif - -#define QS_OBJ_PRE_(obj_) (QS_obj_raw_(obj_)) - -#if (!defined QS_FUN_PTR_SIZE || (QS_FUN_PTR_SIZE == 1U)) - #define QS_FUN_PRE_(fun_) (QS_u8_raw_((uint8_t)(fun_))) -#elif (QS_FUN_PTR_SIZE == 2U) - #define QS_FUN_PRE_(fun_) (QS_u16_raw_((uint16_t)(fun_))) -#elif (QS_FUN_PTR_SIZE == 4U) - #define QS_FUN_PRE_(fun_) (QS_u32_raw_((uint32_t)(fun_))) -#elif (QS_FUN_PTR_SIZE == 8U) - #define QS_FUN_PRE_(fun_) (QS_u64_raw_((uint64_t)(fun_))) -#else - /*! Internal macro to output an unformatted function pointer */ - /** @note the size of the pointer depends on the macro #QS_FUN_PTR_SIZE. - * If the size is not defined the size of pointer is assumed 4-bytes. - */ - #define QS_FUN_PRE_(fun_) (QS_u32_raw_((uint32_t)(fun_))) -#endif - -/*==========================================================================*/ -#if (!defined QF_EQUEUE_CTR_SIZE || (QF_EQUEUE_CTR_SIZE == 1U)) - - /*! Internal QS macro to output an unformatted event queue counter - * data element. */ - /** - * @note the counter size depends on the macro #QF_EQUEUE_CTR_SIZE. - */ - #define QS_EQC_PRE_(ctr_) QS_u8_raw_((uint8_t)(ctr_)) -#elif (QF_EQUEUE_CTR_SIZE == 2U) - #define QS_EQC_PRE_(ctr_) QS_u16_raw_((uint16_t)(ctr_)) -#elif (QF_EQUEUE_CTR_SIZE == 4U) - #define QS_EQC_PRE_(ctr_) QS_u32_raw_((uint32_t)(ctr_)) -#endif - -#if (!defined QF_EVENT_SIZ_SIZE || (QF_EVENT_SIZ_SIZE == 1U)) - - /*! Internal QS macro to output an unformatted event size - * data element. */ - /** - * @note the event size depends on the macro #QF_EVENT_SIZ_SIZE. - */ - #define QS_EVS_PRE_(size_) QS_u8_raw_((uint8_t)(size_)) -#elif (QF_EVENT_SIZ_SIZE == 2U) - #define QS_EVS_PRE_(size_) QS_u16_raw_((uint16_t)(size_)) -#elif (QF_EVENT_SIZ_SIZE == 4U) - #define QS_EVS_PRE_(size_) QS_u32_raw_((uint32_t)(size_)) -#endif - -#if (!defined QF_MPOOL_SIZ_SIZE || (QF_MPOOL_SIZ_SIZE == 1U)) - - /*! Internal QS macro to output an unformatted memory pool - * block-size data element */ - /** - * @note the block-size depends on the macro #QF_MPOOL_SIZ_SIZE. - */ - #define QS_MPS_PRE_(size_) QS_u8_raw_((uint8_t)(size_)) -#elif (QF_MPOOL_SIZ_SIZE == 2U) - #define QS_MPS_PRE_(size_) QS_u16_raw_((uint16_t)(size_)) -#elif (QF_MPOOL_SIZ_SIZE == 4U) - #define QS_MPS_PRE_(size_) QS_u32_raw_((uint32_t)(size_)) -#endif - -#if (!defined QF_MPOOL_CTR_SIZE || (QF_MPOOL_CTR_SIZE == 1U)) - - /*! Internal QS macro to output an unformatted memory pool - * block-counter data element. */ - /** - * @note the counter size depends on the macro #QF_MPOOL_CTR_SIZE. - */ - #define QS_MPC_PRE_(ctr_) QS_u8_raw_((uint8_t)(ctr_)) -#elif (QF_MPOOL_CTR_SIZE == 2U) - #define QS_MPC_PRE_(ctr_) QS_u16_raw_((uint16_t)(ctr_)) -#elif (QF_MPOOL_CTR_SIZE == 4U) - #define QS_MPC_PRE_(ctr_) QS_u32_raw_((uint16_t)(ctr_)) -#endif - -#if (!defined QF_TIMEEVT_CTR_SIZE || (QF_TIMEEVT_CTR_SIZE == 1U)) - - /*! Internal QS macro to output an unformatted time event - * tick-counter data element */ - /** - * @note the counter size depends on the macro #QF_TIMEEVT_CTR_SIZE. - */ - #define QS_TEC_PRE_(ctr_) QS_u8_raw_((uint8_t)(ctr_)) -#elif (QF_TIMEEVT_CTR_SIZE == 2U) - #define QS_TEC_PRE_(ctr_) QS_u16_raw_((uint16_t)(ctr_)) -#elif (QF_TIMEEVT_CTR_SIZE == 4U) - #define QS_TEC_PRE_(ctr_) QS_u32_raw_((uint32_t)(ctr_)) -#endif - -/*==========================================================================*/ -/*! Internal QS macro to insert an un-escaped byte into the QS buffer */ -#define QS_INSERT_BYTE_(b_) \ - buf[head] = (b_); \ - ++head; \ - if (head == end) { \ - head = 0U; \ - } - -/*! Internal QS macro to insert an escaped byte into the QS buffer */ -#define QS_INSERT_ESC_BYTE_(b_) \ - chksum = (uint8_t)(chksum + (b_)); \ - if (((b_) != QS_FRAME) && ((b_) != QS_ESC)) { \ - QS_INSERT_BYTE_(b_) \ - } \ - else { \ - QS_INSERT_BYTE_(QS_ESC) \ - QS_INSERT_BYTE_((uint8_t)((b_) ^ QS_ESC_XOR))\ - ++QS_priv_.used; \ - } - -#endif /* QP_INC_QS_PKG_H_ */ - - - - /*! @file -* @brief QP/C public interface including backwards-compatibility layer -* @details -* This header file must be included directly or indirectly -* in all application modules (*.c files) that use QP/C. -*/ -#ifndef QP_INC_QPC_H_ -#define QP_INC_QPC_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -/*==========================================================================*/ -#include "qf_port.h" /* QF/C port from the port directory */ -#include "qassert.h" /* QP embedded systems-friendly assertions */ - -#ifdef Q_SPY /* software tracing enabled? */ - #include "qs_port.h" /* QS/C port from the port directory */ -#else - #include "qs_dummy.h" /* QS/C dummy (inactive) interface */ -#endif - -/*==========================================================================*/ - -#ifndef QP_API_VERSION - -/*! Specifies the backwards compatibility with the QP/C API version. -* @details -* For example, QP_API_VERSION==691 will cause generating the compatibility -* layer with QP/C version 6.9.1 and newer, but not older than 6.9.1. -* QP_API_VERSION==0 causes generation of the maximum currently supported -* backwards compatibility. This is the default.<br> -* <br> -* Conversely, QP_API_VERSION==9999 means that no compatibility layer should -* be generated. This setting is useful for checking if an application -* complies with the latest QP/C API. -*/ -#define QP_API_VERSION 0 - -#endif /* #ifndef QP_API_VERSION */ - -/*==========================================================================*/ -/* QP API compatibility layer... */ - -#if (QP_API_VERSION < 700) - -/*! @deprecated plain 'char' is no longer forbidden in MISRA-C 2012 */ -typedef char char_t; - -/*==========================================================================*/ -#if (QP_API_VERSION < 691) - -/*! @deprecated enable the QS global filter */ -#define QS_FILTER_ON(rec_) QS_GLB_FILTER((rec_)) - -/*! @deprecated disable the QS global filter */ -#define QS_FILTER_OFF(rec_) QS_GLB_FILTER(-(rec_)) - -/*! @deprecated enable the QS local filter for SM (state machine) object */ -#define QS_FILTER_SM_OBJ(obj_) ((void)0) - -/*! @deprecated enable the QS local filter for AO (active objects) */ -#define QS_FILTER_AO_OBJ(obj_) ((void)0) - -/*! @deprecated enable the QS local filter for MP (memory pool) object */ -#define QS_FILTER_MP_OBJ(obj_) ((void)0) - -/*! @deprecated enable the QS local filter for EQ (event queue) object */ -#define QS_FILTER_EQ_OBJ(obj_) ((void)0) - -/*! @deprecated enable the QS local filter for TE (time event) object */ -#define QS_FILTER_TE_OBJ(obj_) ((void)0) - -#ifdef Q_SPY - -/*! @deprecated local Filter for a generic application object `obj_`. */ -#define QS_FILTER_AP_OBJ(obj_) (QS_priv_.locFilter_AP = (obj_)) - -/*! @deprecated begin of a user QS record, instead use QS_BEGIN_ID() */ -#define QS_BEGIN(rec_, obj_) \ - if (((QS_priv_.glbFilter[(uint_fast8_t)(rec_) >> 3U] \ - & (1U << ((uint_fast8_t)(rec_) & 7U))) != 0U) \ - && ((QS_priv_.locFilter_AP == (void *)0) \ - || (QS_priv_.locFilter_AP == (obj_)))) \ - { \ - QS_CRIT_STAT_ \ - QS_CRIT_E_(); \ - QS_beginRec_((uint_fast8_t)(rec_)); \ - QS_TIME_PRE_(); { - -/*! @deprecated Output formatted uint32_t to the QS record */ -#define QS_U32_HEX(width_, data_) \ - (QS_u32_fmt_((uint8_t)(((width_) << 4)) | QS_HEX_FMT, (data_))) - -#else - -#define QS_FILTER_AP_OBJ(obj_) ((void)0) -#define QS_BEGIN(rec_, obj_) if (false) { -#define QS_U32_HEX(width_, data_) ((void)0) - -#endif - -/*==========================================================================*/ -#if (QP_API_VERSION < 660) - -/*! @deprecated casting to QXThreadHandler -* instead use: the new signature of QXThreadHandler and don't cast -*/ -#define Q_XTHREAD_CAST(handler_) ((QXThreadHandler)(handler_)) - -/*==========================================================================*/ -#if (QP_API_VERSION < 580) - -/*! @deprecated call to the QMSM_INIT() operation; instead use: QHSM_INIT() */ -#define QMSM_INIT(me_, e_) QHSM_INIT((me_), (e_)) - -/*! @deprecated call to the QMSM_DISPATCH() operation; -* instead use: QHSM_DISPATCH() */ -#define QMSM_DISPATCH(me_, e_) QHSM_DISPATCH((me_), (e_), 0U) - -#endif /* QP_API_VERSION < 580 */ -#endif /* QP_API_VERSION < 660 */ -#endif /* QP_API_VERSION < 691 */ -#endif /* QP_API_VERSION < 700 */ - -#ifdef __cplusplus -} -#endif - -#endif /* QP_INC_QPC_H_ */ - - - - /*! @file -* @brief Application build time-stamp interface -*/ -#ifndef QP_INC_QSTAMP_H_ -#define QP_INC_QSTAMP_H_ - -extern char const Q_BUILD_DATE[12]; -extern char const Q_BUILD_TIME[9]; - -#endif /* QP_INC_QSTAMP_H_ */ - - - - - - - - - /*! @file -* @brief ::QHsm implementation -* -* @tr{RQP103} @tr{RQP104} @tr{RQP120} @tr{RQP130} -*/ -#define QP_IMPL /* this is QP implementation */ -#include "qep_port.h" /* QEP port */ -#include "qassert.h" /* QP embedded systems-friendly assertions */ -#ifdef Q_SPY /* QS software tracing enabled? */ - #include "qs_port.h" /* QS port */ - #include "qs_pkg.h" /* QS facilities for pre-defined trace records */ -#else - #include "qs_dummy.h" /* disable the QS software tracing */ -#endif /* Q_SPY */ - -Q_DEFINE_THIS_MODULE("qep_hsm") - -/*==========================================================================*/ -$define ${QEP::QP_versionStr[8]} - -/*! Immutable events corresponding to the reserved signals. -* -* @details -* Static, immutable reserved events that the QEP event processor sends -* to state handler functions of QHsm-style state machine to execute entry -* actions, exit actions, and initial transitions. -*/ -static QEvt const l_reservedEvt_[] = { - { (QSignal)Q_EMPTY_SIG, 0U, 0U }, - { (QSignal)Q_ENTRY_SIG, 0U, 0U }, - { (QSignal)Q_EXIT_SIG, 0U, 0U }, - { (QSignal)Q_INIT_SIG, 0U, 0U } -}; - -/*! helper function to trigger reserved event in an QHsm -* @private @memberof QHsm -* -* @param[in] state state handler function -* @param[in] sig reserved signal to trigger -*/ -static inline QState QHsm_reservedEvt_( - QHsm * const me, - QStateHandler const state, - enum QReservedSig const sig) -{ - return (*state)(me, &l_reservedEvt_[sig]); } -$define ${QEP::QHsm} - - - - /*! @file -* @brief ::QMsm implementation -*/ -#define QP_IMPL /* this is QP implementation */ -#include "qep_port.h" /* QEP port */ -#include "qassert.h" /* QP embedded systems-friendly assertions */ -#ifdef Q_SPY /* QS software tracing enabled? */ - #include "qs_port.h" /* QS port */ - #include "qs_pkg.h" /* QS facilities for pre-defined trace records */ -#else - #include "qs_dummy.h" /* disable the QS software tracing */ -#endif /* Q_SPY */ - -Q_DEFINE_THIS_MODULE("qep_msm") - -/*==========================================================================*/ -/*! internal QEP constants */ - -/*! maximum depth of entry levels in a MSM for transition to history. */ -#define QMSM_MAX_ENTRY_DEPTH_ 4 - -static struct QMState const l_msm_top_s = { - (struct QMState *)0, - Q_STATE_CAST(0), - Q_ACTION_CAST(0), - Q_ACTION_CAST(0), - Q_ACTION_CAST(0) -}; - -/*==========================================================================*/ -$define ${QEP::QMsm} - - - - /*! @file -* @deprecated -* Empty file kept only for backwards compatibility. -* @sa qf_qact.c -*/ -extern char const dummy; /* declaration */ -char const dummy = '\0'; /* definition */ - - - - /*! @file -* @brief ::QActive native queue operations (based on ::QEQueue) -* -* @note -* this source file is only included in the application build when the native -* QF active object queue is used (instead of a message queue of an RTOS). -*/ -#define QP_IMPL /* this is QP implementation */ -#include "qf_port.h" /* QF port */ -#include "qf_pkg.h" /* QF package-scope interface */ -#include "qassert.h" /* QP embedded systems-friendly assertions */ -#ifdef Q_SPY /* QS software tracing enabled? */ - #include "qs_port.h" /* QS port */ - #include "qs_pkg.h" /* QS facilities for pre-defined trace records */ -#else - #include "qs_dummy.h" /* disable the QS software tracing */ -#endif /* Q_SPY */ - -Q_DEFINE_THIS_MODULE("qf_actq") - -/*==========================================================================*/ -$define ${QF::QActive::post_} -$define ${QF::QActive::postLIFO_} -$define ${QF::QActive::get_} - -$define ${QF::QF-base::getQueueMin} - -/*==========================================================================*/ -/*! Perform downcast to QTicker pointer. -* -* @details -* This macro encapsulates the downcast to (QTicker *), which is used in -* QTicker_init_() and QTicker_dispatch_(). Such casts violate MISRA-C 2012 -* Rule 11.3(req) "cast from pointer to object type to pointer to different -* object type". -*/ -#define QTICKER_CAST_(me_) ((QActive *)(me_)) - -$define ${QF::QTicker} - - - - /*! @file -* @brief QActive_defer() and QActive_recall() implementation. -*/ -#define QP_IMPL /* this is QP implementation */ -#include "qf_port.h" /* QF port */ -#include "qf_pkg.h" /* QF package-scope interface */ -#include "qassert.h" /* QP embedded systems-friendly assertions */ -#ifdef Q_SPY /* QS software tracing enabled? */ - #include "qs_port.h" /* QS port */ - #include "qs_pkg.h" /* QS facilities for pre-defined trace records */ -#else - #include "qs_dummy.h" /* disable the QS software tracing */ -#endif /* Q_SPY */ - -Q_DEFINE_THIS_MODULE("qf_defer") - -$define ${QF::QActive::defer} -$define ${QF::QActive::recall} -$define ${QF::QActive::flushDeferred} - - - - /*! @file -* @brief QF/C dynamic event management -*/ -#define QP_IMPL /* this is QP implementation */ -#include "qf_port.h" /* QF port */ -#include "qf_pkg.h" /* QF package-scope interface */ -#include "qassert.h" /* QP embedded systems-friendly assertions */ -#ifdef Q_SPY /* QS software tracing enabled? */ - #include "qs_port.h" /* QS port */ - #include "qs_pkg.h" /* QS facilities for pre-defined trace records */ -#else - #include "qs_dummy.h" /* disable the QS software tracing */ -#endif /* Q_SPY */ - -#if (QF_MAX_EPOOL > 0U) /* dynamic events configured? */ - -Q_DEFINE_THIS_MODULE("qf_dyn") - -//============================================================================ -$define ${QF::QF-pkg::maxPool_} -$define ${QF::QF-pkg::ePool_[QF_MAX_EPOOL]} -//============================================================================ -$define ${QEP::QEvt} -//============================================================================ -$define ${QF::QF-dyn} - -#endif /* (QF_MAX_EPOOL > 0U) dynamic events configured */ - - - - /*! @file -* @brief ::QMPool implementatin (Memory Pool) -*/ -#define QP_IMPL /* this is QP implementation */ -#include "qf_port.h" /* QF port */ -#include "qf_pkg.h" /* QF package-scope interface */ -#include "qassert.h" /* QP embedded systems-friendly assertions */ -#ifdef Q_SPY /* QS software tracing enabled? */ - #include "qs_port.h" /* QS port */ - #include "qs_pkg.h" /* QS facilities for pre-defined trace records */ -#else - #include "qs_dummy.h" /* disable the QS software tracing */ -#endif /* Q_SPY */ - -Q_DEFINE_THIS_MODULE("qf_mem") - -$define ${QF::QMPool} - - - - /*! @file -* @brief QActive_ctor() definition -* -* @details -* This file must remain separate from the rest to avoid pulling in the -* "virtual" functions QHsm_init_() and QHsm_dispatch_() in case they -* are not used by the application. -* -* @sa qf_qmact.c -*/ -#define QP_IMPL /* this is QP implementation */ -#include "qf_port.h" /* QF port */ -#include "qf_pkg.h" /* QF package-scope interface */ -#include "qassert.h" /* QP embedded systems-friendly assertions */ - -Q_DEFINE_THIS_MODULE("qf_qact") - -//============================================================================ -$define ${QF::QActive::registry_[QF_MAX_ACTIVE + 1U]} -$define ${QF::QF-base::intLock_} -$define ${QF::QF-base::intNest_} -$define ${QF::QF-pkg::readySet_} -$define ${QF::QF-pkg::bzero} - -//============================================================================ -$define ${QF::QActive::ctor} -$define ${QF::QActive::register_} -$define ${QF::QActive::unregister_} - -//============================================================================ -$define ${QF-types::QF_LOG2} - - - - /*! @file -* @brief QMActive_ctor() definition -* -* @details -* This file must remain separate from the rest to avoid pulling in the -* "virtual" functions QHsm_init_() and QHsm_dispatch_() in case they -* are not used by the application. -* -* @sa qf_qact.c -*/ -#define QP_IMPL /* this is QP implementation */ -#include "qf_port.h" /* QF port */ -#include "qf_pkg.h" /* QF package-scope interface */ - -/*Q_DEFINE_THIS_MODULE("qf_qmact")*/ - -/* -* This internal macro encapsulates the violation of MISRA-C 2012 -* Rule 11.3(req) "A cast shall not be performed between a pointer to -* object type and a poiner to a different object type". -*/ -#define QMSM_CAST_(ptr_) ((QMsm *)(ptr_)) - -$define ${QF::QMActive} - - - - /*! @file -* @brief ::QEQueue implementation (QP native thread-safe queue) -*/ -#define QP_IMPL /* this is QP implementation */ -#include "qf_port.h" /* QF port */ -#include "qf_pkg.h" /* QF package-scope interface */ -#include "qassert.h" /* QP embedded systems-friendly assertions */ -#ifdef Q_SPY /* QS software tracing enabled? */ - #include "qs_port.h" /* QS port */ - #include "qs_pkg.h" /* QS facilities for pre-defined trace records */ -#else - #include "qs_dummy.h" /* disable the QS software tracing */ -#endif /* Q_SPY */ - -Q_DEFINE_THIS_MODULE("qf_qeq") - -$define ${QF::QEQueue} - - - - /*! @file -* @brief Publish-Subscribe services -*/ -#define QP_IMPL /* this is QP implementation */ -#include "qf_port.h" /* QF port */ -#include "qf_pkg.h" /* QF package-scope interface */ -#include "qassert.h" /* QP embedded systems-friendly assertions */ -#ifdef Q_SPY /* QS software tracing enabled? */ - #include "qs_port.h" /* QS port */ - #include "qs_pkg.h" /* QS facilities for pre-defined trace records */ -#else - #include "qs_dummy.h" /* disable the QS software tracing */ -#endif /* Q_SPY */ - -Q_DEFINE_THIS_MODULE("qf_ps") - -/*==========================================================================*/ -$define ${QF::QActive::subscrList_} -$define ${QF::QActive::maxPubSignal_} - -$define ${QF::QActive::psInit} -$define ${QF::QActive::publish_} -$define ${QF::QActive::subscribe} -$define ${QF::QActive::unsubscribe} -$define ${QF::QActive::unsubscribeAll} - - - - /*! @file -* @brief QF/C time events and time management services -*/ -#define QP_IMPL /* this is QP implementation */ -#include "qf_port.h" /* QF port */ -#include "qf_pkg.h" /* QF package-scope interface */ -#include "qassert.h" /* QP embedded systems-friendly assertions */ -#ifdef Q_SPY /* QS software tracing enabled? */ - #include "qs_port.h" /* QS port */ - #include "qs_pkg.h" /* QS facilities for pre-defined trace records */ -#else - #include "qs_dummy.h" /* disable the QS software tracing */ -#endif /* Q_SPY */ - -Q_DEFINE_THIS_MODULE("qf_time") - -#ifdef Q_SPY -/*! intertnal macro to encapsulate a MISRA deviation -* @details -* This internal macro encapsulates the violation of MISRA-C 2012 -* Rule 11.5(A) "A conversion should not be performed from pointer to void -* into pointer to object". -*/ -#define QACTIVE_CAST_(ptr_) ((QActive *)(ptr_)) -#endif - -$define ${QF::QTimeEvt} - - - - - - - /*! @file -* @brief Cooperative QV kernel, implementation of kernel-specific functions. -*/ -#define QP_IMPL /* this is QP implementation */ -#include "qf_port.h" /* QF port */ -#include "qf_pkg.h" /* QF package-scope internal interface */ -#include "qassert.h" /* QP embedded systems-friendly assertions */ -#ifdef Q_SPY /* QS software tracing enabled? */ - #include "qs_port.h" /* QS port */ - #include "qs_pkg.h" /* QS facilities for pre-defined trace records */ -#else - #include "qs_dummy.h" /* disable the QS software tracing */ -#endif /* Q_SPY */ - -/* protection against including this source file in a wrong project */ -#ifndef QP_INC_QV_H_ - #error "Source file included in a project NOT based on the QV kernel" -#endif /* QP_INC_QV_H_ */ - -Q_DEFINE_THIS_MODULE("qv") - -/*==========================================================================*/ -$define ${QV::QV-base} -$define ${QV::QF-cust} -$define ${QV::QActive} - - - - - - - /*! @file -* @brief QK preemptive kernel implementation -*/ -#define QP_IMPL /* this is QP implementation */ -#include "qf_port.h" /* QF port */ -#include "qf_pkg.h" /* QF package-scope internal interface */ -#include "qassert.h" /* QP embedded systems-friendly assertions */ -#ifdef Q_SPY /* QS software tracing enabled? */ - #include "qs_port.h" /* QS port */ - #include "qs_pkg.h" /* QS facilities for pre-defined trace records */ -#else - #include "qs_dummy.h" /* disable the QS software tracing */ -#endif /* Q_SPY */ - -/* protection against including this source file in a wrong project */ -#ifndef QP_INC_QK_H_ - #error "Source file included in a project NOT based on the QK kernel" -#endif /* QP_INC_QK_H_ */ - -Q_DEFINE_THIS_MODULE("qk") - -/*==========================================================================*/ -$define ${QK::QK-base} -$define ${QK::QF-cust} -$define ${QK::QActive} -$define ${QK::QK-extern-C} - - - - - - - /*! @file -* @brief QXK preemptive dual-mode kernel core functions -*/ -#define QP_IMPL /* this is QP implementation */ -#include "qf_port.h" /* QF port */ -#include "qf_pkg.h" /* QF package-scope internal interface */ -#include "qassert.h" /* QP embedded systems-friendly assertions */ -#ifdef Q_SPY /* QS software tracing enabled? */ - #include "qs_port.h" /* QS port */ - #include "qs_pkg.h" /* QS facilities for pre-defined trace records */ -#else - #include "qs_dummy.h" /* disable the QS software tracing */ -#endif /* Q_SPY */ - -/* protection against including this source file in a wrong project */ -#ifndef QP_INC_QXK_H_ - #error "Source file included in a project NOT based on the QXK kernel" -#endif /* QP_INC_QXK_H_ */ - -Q_DEFINE_THIS_MODULE("qxk") - -/*==========================================================================*/ -$define ${QXK::QXK-base} -$define ${QXK::QF-cust} -$define ${QXK::QActive} -$define ${QXK::QXK-extern-C} -/*==========================================================================*/ -$define ${QXK-impl} - - - - /*! @file -* @brief QXMutex_init(), QXMutex_lock(), QXMutex_tryLock() and -* QXMutex_unlock() definitions. -*/ -#define QP_IMPL /* this is QP implementation */ -#include "qf_port.h" /* QF port */ -#include "qf_pkg.h" /* QF package-scope interface */ -#include "qassert.h" /* QP embedded systems-friendly assertions */ -#ifdef Q_SPY /* QS software tracing enabled? */ - #include "qs_port.h" /* QS port */ - #include "qs_pkg.h" /* QS facilities for pre-defined trace records */ -#else - #include "qs_dummy.h" /* disable the QS software tracing */ -#endif /* Q_SPY */ - -/* protection against including this source file in a wrong project */ -#ifndef QP_INC_QXK_H_ - #error "Source file included in a project NOT based on the QXK kernel" -#endif /* QP_INC_QXK_H_ */ - -Q_DEFINE_THIS_MODULE("qxk_mutex") - -/*==========================================================================*/ -$define ${QXK::QXMutex} - - - - /*! @file -* @brief QXK preemptive kernel semaphore functions -*/ -#define QP_IMPL /* this is QP implementation */ -#include "qf_port.h" /* QF port */ -#include "qf_pkg.h" /* QF package-scope internal interface */ -#include "qassert.h" /* QP embedded systems-friendly assertions */ -#ifdef Q_SPY /* QS software tracing enabled? */ - #include "qs_port.h" /* QS port */ - #include "qs_pkg.h" /* QS facilities for pre-defined trace records */ -#else - #include "qs_dummy.h" /* disable the QS software tracing */ -#endif /* Q_SPY */ - -/* protection against including this source file in a wrong project */ -#ifndef QP_INC_QXK_H_ - #error "Source file included in a project NOT based on the QXK kernel" -#endif /* QP_INC_QXK_H_ */ - -Q_DEFINE_THIS_MODULE("qxk_sema") - -/*==========================================================================*/ -$define ${QXK::QXSemaphore} - - - - /*! @file -* @brief QXK preemptive kernel extended (blocking) thread functions -*/ -#define QP_IMPL /* this is QP implementation */ -#include "qf_port.h" /* QF port */ -#include "qf_pkg.h" /* QF package-scope internal interface */ -#include "qassert.h" /* QP embedded systems-friendly assertions */ -#ifdef Q_SPY /* QS software tracing enabled? */ - #include "qs_port.h" /* QS port */ - #include "qs_pkg.h" /* QS facilities for pre-defined trace records */ -#else - #include "qs_dummy.h" /* disable the QS software tracing */ -#endif /* Q_SPY */ - -/* protection against including this source file in a wrong project */ -#ifndef QP_INC_QXK_H_ - #error "Source file included in a project NOT based on the QXK kernel" -#endif /* QP_INC_QXK_H_ */ - -Q_DEFINE_THIS_MODULE("qxk_xthr") - -/*==========================================================================*/ -$define ${QXK::QXThread} - - - - - - - /*! @file -* @brief QS software tracing services -*/ -#define QP_IMPL /* this is QP implementation */ -#include "qs_port.h" /* QS port */ -#include "qs_pkg.h" /* QS package-scope interface */ -#include "qstamp.h" /* QP time-stamp */ -#include "qassert.h" /* QP embedded systems-friendly assertions */ - -Q_DEFINE_THIS_MODULE("qs") - -/* ensure that the predefined records don't overlap the -* user records (application-specific). -*/ -Q_ASSERT_STATIC((enum_t)QS_PRE_MAX <= (enum_t)QS_USER); - -/*==========================================================================*/ -$define ${QS::QS-tx} +//! @endcond - /*! @file -* @brief QS long-long (64-bit) output -*/ -#define QP_IMPL /* this is QP implementation */ -#include "qs_port.h" /* QS port */ -#include "qs_pkg.h" /* QS package-scope internal interface */ + #define QP_IMPL // this is QP implementation +#include "qs_port.h" // QS port +#include "qs_pkg.h" // QS package-scope internal interface -$define ${QS::QS-tx-64bit} +//============================================================================ +//! @cond INTERNAL + +//! @static @private @memberof QS +void QS_u64_raw_(uint64_t const d) { + uint8_t chksum = QS_priv_.chksum; + uint8_t * const buf = QS_priv_.buf; + QSCtr head = QS_priv_.head; + QSCtr const end = QS_priv_.end; + + QS_priv_.used += 8U; // 8 bytes are about to be added + uint64_t u64 = d; + for (uint_fast8_t i = 8U; i != 0U; --i) { + uint8_t const b = (uint8_t)u64; + QS_INSERT_ESC_BYTE_(b) + u64 >>= 8U; + } + + QS_priv_.head = head; // save the head + QS_priv_.chksum = chksum; // save the checksum +} + +//! @static @private @memberof QS +void QS_u64_fmt_( + uint8_t const format, + uint64_t const d) +{ + uint8_t chksum = QS_priv_.chksum; + uint8_t * const buf = QS_priv_.buf; + QSCtr head = QS_priv_.head; + QSCtr const end = QS_priv_.end; + + QS_priv_.used += 9U; // 9 bytes are about to be added + QS_INSERT_ESC_BYTE_(format) // insert the format byte + + // output 8 bytes of data... + uint64_t u64 = d; + for (uint_fast8_t i = 8U; i != 0U; --i) { + uint8_t const b = (uint8_t)u64; + QS_INSERT_ESC_BYTE_(b) + u64 >>= 8U; + } + + QS_priv_.head = head; // save the head + QS_priv_.chksum = chksum; // save the checksum +} + +//! @endcond - /*! @file -* @brief QS floating point output implementation -*/ -#define QP_IMPL /* this is QP implementation */ -#include "qs_port.h" /* QS port */ -#include "qs_pkg.h" /* QS package-scope internal interface */ + #define QP_IMPL // this is QP implementation +#include "qs_port.h" // QS port +#include "qs_pkg.h" // QS package-scope internal interface -$define ${QS::QS-tx-fp} +//============================================================================ +//! @cond INTERNAL + +//! @static @private @memberof QS +void QS_f32_fmt_( + uint8_t const format, + float32_t const f) +{ + union F32Rep { + float32_t f; + uint32_t u; + } fu32; // the internal binary representation + uint8_t chksum = QS_priv_.chksum; // put in a temporary (register) + uint8_t * const buf = QS_priv_.buf; + QSCtr head = QS_priv_.head; + QSCtr const end = QS_priv_.end; + uint_fast8_t i; + + fu32.f = f; // assign the binary representation + + QS_priv_.used += 5U; // 5 bytes about to be added + QS_INSERT_ESC_BYTE_(format) // insert the format byte + + // insert 4 bytes... + for (i = 4U; i != 0U; --i) { + QS_INSERT_ESC_BYTE_((uint8_t)fu32.u) + fu32.u >>= 8U; + } + + QS_priv_.head = head; // save the head + QS_priv_.chksum = chksum; // save the checksum +} + +//! @static @private @memberof QS +void QS_f64_fmt_( + uint8_t const format, + float64_t const d) +{ + union F64Rep { + float64_t d; + uint32_t u[2]; + } fu64; // the internal binary representation + uint8_t chksum = QS_priv_.chksum; + uint8_t * const buf = QS_priv_.buf; + QSCtr head = QS_priv_.head; + QSCtr const end = QS_priv_.end; + uint32_t i; + + // static constant untion to detect endianness of the machine + static union U32Rep { + uint32_t u32; + uint8_t u8; + } const endian = { 1U }; + + fu64.d = d; // assign the binary representation + + // is this a big-endian machine? + if (endian.u8 == 0U) { + // swap fu64.u[0] <-> fu64.u[1]... + i = fu64.u[0]; + fu64.u[0] = fu64.u[1]; + fu64.u[1] = i; + } + + QS_priv_.used += 9U; // 9 bytes about to be added + QS_INSERT_ESC_BYTE_(format) // insert the format byte + + // output 4 bytes from fu64.u[0]... + for (i = 4U; i != 0U; --i) { + QS_INSERT_ESC_BYTE_((uint8_t)fu64.u[0]) + fu64.u[0] >>= 8U; + } + + // output 4 bytes from fu64.u[1]... + for (i = 4U; i != 0U; --i) { + QS_INSERT_ESC_BYTE_((uint8_t)fu64.u[1]) + fu64.u[1] >>= 8U; + } + + QS_priv_.head = head; // save the head + QS_priv_.chksum = chksum; // save the checksum +} + +//! @endcond - /*! @file -* @brief QS/C receive channel services -*/ -#define QP_IMPL /* this is QP implementation */ -#include "qs_port.h" /* QS port */ -#include "qs_pkg.h" /* QS package-scope interface */ -#include "qassert.h" /* QP embedded systems-friendly assertions */ + #define QP_IMPL // this is QP implementation +#include "qs_port.h" // QS port +#include "qs_pkg.h" // QS package-scope interface +#include "qsafe.h" // QP Functional Safety (FuSa) Subsystem + +//============================================================================ +//! @cond INTERNAL Q_DEFINE_THIS_MODULE("qs_rx") -/*==========================================================================*/ #if (QS_OBJ_PTR_SIZE == 1U) typedef uint8_t QSObj; #elif (QS_OBJ_PTR_SIZE == 2U) @@ -14889,10 +10924,6 @@ Q_DEFINE_THIS_MODULE("qs_rx") typedef uint64_t QSObj; #endif -/*! @cond -* Exclude the following internals from the Doxygen documentation -* Extended-state variables used for parsing various QS-RX Records -*/ typedef struct { uint32_t param1; uint32_t param2; @@ -14924,13 +10955,13 @@ typedef struct { typedef struct { uint8_t data[16]; uint8_t idx; - int8_t recId; /* global/local */ + int8_t recId; // global/local } FltVar; typedef struct { QSObj addr; uint8_t idx; - uint8_t kind; /* see qs.h, enum QSpyObjKind */ + uint8_t kind; // see qs.h, enum QSpyObjKind int8_t recId; } ObjVar; @@ -14943,7 +10974,10 @@ typedef struct { uint8_t idx; } EvtVar; -/* extended-state variables for the current state */ +//! extended-state variables for the current state +//! +//! @trace +//! - @tr{DVR-QS-MC4-R19_02} static struct { union Variant { CmdVar cmd; @@ -14955,7 +10989,7 @@ static struct { EvtVar evt; #ifdef Q_UTEST struct QS_TProbe tp; -#endif /* Q_UTEST */ +#endif // Q_UTEST } var; uint8_t state; uint8_t esc; @@ -15009,53 +11043,58 @@ enum { WAIT4_TEST_PROBE_ADDR, WAIT4_TEST_PROBE_FRAME, WAIT4_TEST_CONTINUE_FRAME -#endif /* Q_UTEST */ +#endif // Q_UTEST }; -/* static helper functions... */ +// static helper functions... static void QS_rxParseData_(uint8_t const b); -//static void QS_rxHandleGoodFrame_(uint8_t const state); +static void QS_rxHandleGoodFrame_(uint8_t const state); static void QS_rxHandleBadFrame_(uint8_t const state); static void QS_rxReportAck_(int8_t const recId); static void QS_rxReportError_(int8_t const code); static void QS_rxReportDone_(int8_t const recId); +static void QS_queryCurrObj(uint8_t const obj_kind); static void QS_rxPoke_(void); -/*! Internal QS-RX macro to encapsulate transition in the QS-RX FSM */ +//! Internal QS-RX macro to encapsulate tran. in the QS-RX FSM #define QS_RX_TRAN_(target_) (l_rx.state = (uint8_t)(target_)) -/*! @endcond */ +QS_RxAttr QS_rxPriv_; -/*==========================================================================*/ -$define ${QS::QS-rx} +//! @endcond +//============================================================================ + +$define ${QS::QS-RX} + +//============================================================================ +//! @cond INTERNAL -/*==========================================================================*/ static void QS_rxParseData_(uint8_t const b) { switch (l_rx.state) { - case WAIT4_SEQ: { + case (uint8_t)WAIT4_SEQ: { ++l_rx.seq; if (l_rx.seq != b) { QS_rxReportError_(0x42); - l_rx.seq = b; /* update the sequence */ + l_rx.seq = b; // update the sequence } QS_RX_TRAN_(WAIT4_REC); break; } - case WAIT4_REC: { + case (uint8_t)WAIT4_REC: { switch (b) { - case QS_RX_INFO: + case (uint8_t)QS_RX_INFO: QS_RX_TRAN_(WAIT4_INFO_FRAME); break; - case QS_RX_COMMAND: + case (uint8_t)QS_RX_COMMAND: QS_RX_TRAN_(WAIT4_CMD_ID); break; - case QS_RX_RESET: + case (uint8_t)QS_RX_RESET: QS_RX_TRAN_(WAIT4_RESET_FRAME); break; - case QS_RX_TICK: + case (uint8_t)QS_RX_TICK: QS_RX_TRAN_(WAIT4_TICK_RATE); break; - case QS_RX_PEEK: + case (uint8_t)QS_RX_PEEK: if (QS_rxPriv_.currObj[AP_OBJ] != (void *)0) { l_rx.var.peek.offs = 0U; l_rx.var.peek.idx = 0U; @@ -15066,8 +11105,8 @@ static void QS_rxParseData_(uint8_t const b) { QS_RX_TRAN_(ERROR_STATE); } break; - case QS_RX_POKE: /* intentionally fall-through */ - case QS_RX_FILL: + case (uint8_t)QS_RX_POKE: // intentionally fall-through + case (uint8_t)QS_RX_FILL: l_rx.var.poke.fill = ((b == (uint8_t)QS_RX_FILL) ? 1U : 0U); if (QS_rxPriv_.currObj[AP_OBJ] != (void *)0) { @@ -15082,49 +11121,49 @@ static void QS_rxParseData_(uint8_t const b) { QS_RX_TRAN_(ERROR_STATE); } break; - case QS_RX_GLB_FILTER: /* intentionally fall-through */ - case QS_RX_LOC_FILTER: + case (uint8_t)QS_RX_GLB_FILTER: // intentionally fall-through + case (uint8_t)QS_RX_LOC_FILTER: l_rx.var.flt.recId = (int8_t)b; QS_RX_TRAN_(WAIT4_FILTER_LEN); break; - case QS_RX_AO_FILTER: /* intentionally fall-through */ - case QS_RX_CURR_OBJ: + case (uint8_t)QS_RX_AO_FILTER: // intentionally fall-through + case (uint8_t)QS_RX_CURR_OBJ: l_rx.var.obj.recId = (int8_t)b; QS_RX_TRAN_(WAIT4_OBJ_KIND); break; - case QS_RX_QUERY_CURR: + case (uint8_t)QS_RX_QUERY_CURR: l_rx.var.obj.recId = (int8_t)QS_RX_QUERY_CURR; QS_RX_TRAN_(WAIT4_QUERY_KIND); break; - case QS_RX_EVENT: + case (uint8_t)QS_RX_EVENT: QS_RX_TRAN_(WAIT4_EVT_PRIO); break; #ifdef Q_UTEST - case QS_RX_TEST_SETUP: + case (uint8_t)QS_RX_TEST_SETUP: QS_RX_TRAN_(WAIT4_TEST_SETUP_FRAME); break; - case QS_RX_TEST_TEARDOWN: + case (uint8_t)QS_RX_TEST_TEARDOWN: QS_RX_TRAN_(WAIT4_TEST_TEARDOWN_FRAME); break; - case QS_RX_TEST_CONTINUE: + case (uint8_t)QS_RX_TEST_CONTINUE: QS_RX_TRAN_(WAIT4_TEST_CONTINUE_FRAME); break; - case QS_RX_TEST_PROBE: - if (QS_testData.tpNum - < (uint8_t)(sizeof(QS_testData.tpBuf) - / sizeof(QS_testData.tpBuf[0]))) + case (uint8_t)QS_RX_TEST_PROBE: + if (QS_tstPriv_.tpNum + < (uint8_t)(sizeof(QS_tstPriv_.tpBuf) + / sizeof(QS_tstPriv_.tpBuf[0]))) { l_rx.var.tp.data = 0U; l_rx.var.tp.idx = 0U; QS_RX_TRAN_(WAIT4_TEST_PROBE_DATA); } - else { /* the number of Test-Probes exceeded */ + else { // the # Test-Probes exceeded QS_rxReportError_((int8_t)QS_RX_TEST_PROBE); QS_RX_TRAN_(ERROR_STATE); } break; -#endif /* Q_UTEST */ +#endif // Q_UTEST default: QS_rxReportError_(0x43); @@ -15133,11 +11172,11 @@ static void QS_rxParseData_(uint8_t const b) { } break; } - case WAIT4_INFO_FRAME: { - /* keep ignoring the data until a frame is collected */ + case (uint8_t)WAIT4_INFO_FRAME: { + // keep ignoring the data until a frame is collected break; } - case WAIT4_CMD_ID: { + case (uint8_t)WAIT4_CMD_ID: { l_rx.var.cmd.cmdId = b; l_rx.var.cmd.idx = 0U; l_rx.var.cmd.param1 = 0U; @@ -15146,7 +11185,7 @@ static void QS_rxParseData_(uint8_t const b) { QS_RX_TRAN_(WAIT4_CMD_PARAM1); break; } - case WAIT4_CMD_PARAM1: { + case (uint8_t)WAIT4_CMD_PARAM1: { l_rx.var.cmd.param1 |= ((uint32_t)b << l_rx.var.cmd.idx); l_rx.var.cmd.idx += 8U; if (l_rx.var.cmd.idx == (8U * 4U)) { @@ -15155,7 +11194,7 @@ static void QS_rxParseData_(uint8_t const b) { } break; } - case WAIT4_CMD_PARAM2: { + case (uint8_t)WAIT4_CMD_PARAM2: { l_rx.var.cmd.param2 |= ((uint32_t)b << l_rx.var.cmd.idx); l_rx.var.cmd.idx += 8U; if (l_rx.var.cmd.idx == (8U * 4U)) { @@ -15164,7 +11203,7 @@ static void QS_rxParseData_(uint8_t const b) { } break; } - case WAIT4_CMD_PARAM3: { + case (uint8_t)WAIT4_CMD_PARAM3: { l_rx.var.cmd.param3 |= ((uint32_t)b << l_rx.var.cmd.idx); l_rx.var.cmd.idx += 8U; if (l_rx.var.cmd.idx == (8U * 4U)) { @@ -15173,24 +11212,24 @@ static void QS_rxParseData_(uint8_t const b) { } break; } - case WAIT4_CMD_FRAME: { - /* keep ignoring the data until a frame is collected */ + case (uint8_t)WAIT4_CMD_FRAME: { + // keep ignoring the data until a frame is collected break; } - case WAIT4_RESET_FRAME: { - /* keep ignoring the data until a frame is collected */ + case (uint8_t)WAIT4_RESET_FRAME: { + // keep ignoring the data until a frame is collected break; } - case WAIT4_TICK_RATE: { + case (uint8_t)WAIT4_TICK_RATE: { l_rx.var.tick.rate = (uint_fast8_t)b; QS_RX_TRAN_(WAIT4_TICK_FRAME); break; } - case WAIT4_TICK_FRAME: { - /* keep ignoring the data until a frame is collected */ + case (uint8_t)WAIT4_TICK_FRAME: { + // keep ignoring the data until a frame is collected break; } - case WAIT4_PEEK_OFFS: { + case (uint8_t)WAIT4_PEEK_OFFS: { if (l_rx.var.peek.idx == 0U) { l_rx.var.peek.offs = (uint16_t)b; l_rx.var.peek.idx += 8U; @@ -15201,7 +11240,7 @@ static void QS_rxParseData_(uint8_t const b) { } break; } - case WAIT4_PEEK_SIZE: { + case (uint8_t)WAIT4_PEEK_SIZE: { if ((b == 1U) || (b == 2U) || (b == 4U)) { l_rx.var.peek.size = b; QS_RX_TRAN_(WAIT4_PEEK_NUM); @@ -15212,16 +11251,16 @@ static void QS_rxParseData_(uint8_t const b) { } break; } - case WAIT4_PEEK_NUM: { + case (uint8_t)WAIT4_PEEK_NUM: { l_rx.var.peek.num = b; QS_RX_TRAN_(WAIT4_PEEK_FRAME); break; } - case WAIT4_PEEK_FRAME: { - /* keep ignoring the data until a frame is collected */ + case (uint8_t)WAIT4_PEEK_FRAME: { + // keep ignoring the data until a frame is collected break; } - case WAIT4_POKE_OFFS: { + case (uint8_t)WAIT4_POKE_OFFS: { if (l_rx.var.poke.idx == 0U) { l_rx.var.poke.offs = (uint16_t)b; l_rx.var.poke.idx = 1U; @@ -15232,7 +11271,7 @@ static void QS_rxParseData_(uint8_t const b) { } break; } - case WAIT4_POKE_SIZE: { + case (uint8_t)WAIT4_POKE_SIZE: { if ((b == 1U) || (b == 2U) || (b == 4U)) { l_rx.var.poke.size = b; QS_RX_TRAN_(WAIT4_POKE_NUM); @@ -15245,7 +11284,7 @@ static void QS_rxParseData_(uint8_t const b) { } break; } - case WAIT4_POKE_NUM: { + case (uint8_t)WAIT4_POKE_NUM: { if (b > 0U) { l_rx.var.poke.num = b; l_rx.var.poke.data = 0U; @@ -15262,7 +11301,7 @@ static void QS_rxParseData_(uint8_t const b) { } break; } - case WAIT4_FILL_DATA: { + case (uint8_t)WAIT4_FILL_DATA: { l_rx.var.poke.data |= ((uint32_t)b << l_rx.var.poke.idx); l_rx.var.poke.idx += 8U; if ((uint8_t)(l_rx.var.poke.idx >> 3U) == l_rx.var.poke.size) { @@ -15270,7 +11309,7 @@ static void QS_rxParseData_(uint8_t const b) { } break; } - case WAIT4_POKE_DATA: { + case (uint8_t)WAIT4_POKE_DATA: { l_rx.var.poke.data |= ((uint32_t)b << l_rx.var.poke.idx); l_rx.var.poke.idx += 8U; if ((uint8_t)(l_rx.var.poke.idx >> 3U) == l_rx.var.poke.size) { @@ -15282,15 +11321,15 @@ static void QS_rxParseData_(uint8_t const b) { } break; } - case WAIT4_FILL_FRAME: { - /* keep ignoring the data until a frame is collected */ + case (uint8_t)WAIT4_FILL_FRAME: { + // keep ignoring the data until a frame is collected break; } case WAIT4_POKE_FRAME: { - /* keep ignoring the data until a frame is collected */ + // keep ignoring the data until a frame is collected break; } - case WAIT4_FILTER_LEN: { + case (uint8_t)WAIT4_FILTER_LEN: { if (b == sizeof(l_rx.var.flt.data)) { l_rx.var.flt.idx = 0U; QS_RX_TRAN_(WAIT4_FILTER_DATA); @@ -15301,7 +11340,7 @@ static void QS_rxParseData_(uint8_t const b) { } break; } - case WAIT4_FILTER_DATA: { + case (uint8_t)WAIT4_FILTER_DATA: { l_rx.var.flt.data[l_rx.var.flt.idx] = b; ++l_rx.var.flt.idx; if (l_rx.var.flt.idx == sizeof(l_rx.var.flt.data)) { @@ -15309,11 +11348,11 @@ static void QS_rxParseData_(uint8_t const b) { } break; } - case WAIT4_FILTER_FRAME: { - /* keep ignoring the data until a frame is collected */ + case (uint8_t)WAIT4_FILTER_FRAME: { + // keep ignoring the data until a frame is collected break; } - case WAIT4_OBJ_KIND: { + case (uint8_t)WAIT4_OBJ_KIND: { if (b <= (uint8_t)SM_AO_OBJ) { l_rx.var.obj.kind = b; l_rx.var.obj.addr = 0U; @@ -15326,7 +11365,7 @@ static void QS_rxParseData_(uint8_t const b) { } break; } - case WAIT4_OBJ_ADDR: { + case (uint8_t)WAIT4_OBJ_ADDR: { l_rx.var.obj.addr |= ((QSObj)b << l_rx.var.obj.idx); l_rx.var.obj.idx += 8U; if (l_rx.var.obj.idx == (uint8_t)(8U * QS_OBJ_PTR_SIZE)) { @@ -15334,11 +11373,11 @@ static void QS_rxParseData_(uint8_t const b) { } break; } - case WAIT4_OBJ_FRAME: { - /* keep ignoring the data until a frame is collected */ + case (uint8_t)WAIT4_OBJ_FRAME: { + // keep ignoring the data until a frame is collected break; } - case WAIT4_QUERY_KIND: { + case (uint8_t)WAIT4_QUERY_KIND: { if (b < (uint8_t)MAX_OBJ) { l_rx.var.obj.kind = b; QS_RX_TRAN_(WAIT4_QUERY_FRAME); @@ -15349,18 +11388,18 @@ static void QS_rxParseData_(uint8_t const b) { } break; } - case WAIT4_QUERY_FRAME: { - /* keep ignoring the data until a frame is collected */ + case (uint8_t)WAIT4_QUERY_FRAME: { + // keep ignoring the data until a frame is collected break; } - case WAIT4_EVT_PRIO: { + case (uint8_t)WAIT4_EVT_PRIO: { l_rx.var.evt.prio = b; l_rx.var.evt.sig = 0U; l_rx.var.evt.idx = 0U; QS_RX_TRAN_(WAIT4_EVT_SIG); break; } - case WAIT4_EVT_SIG: { + case (uint8_t)WAIT4_EVT_SIG: { l_rx.var.evt.sig |= (QSignal)((uint32_t)b << l_rx.var.evt.idx); l_rx.var.evt.idx += 8U; if (l_rx.var.evt.idx == (uint8_t)(8U * Q_SIGNAL_SIZE)) { @@ -15370,21 +11409,21 @@ static void QS_rxParseData_(uint8_t const b) { } break; } - case WAIT4_EVT_LEN: { + case (uint8_t)WAIT4_EVT_LEN: { l_rx.var.evt.len |= (uint16_t)((uint32_t)b << l_rx.var.evt.idx); l_rx.var.evt.idx += 8U; if (l_rx.var.evt.idx == (8U * 2U)) { if ((l_rx.var.evt.len + sizeof(QEvt)) <= QF_poolGetMaxBlockSize()) { - /* report Ack before generating any other QS records */ + // report Ack before generating any other QS records QS_rxReportAck_((int8_t)QS_RX_EVENT); l_rx.var.evt.e = QF_newX_( ((uint_fast16_t)l_rx.var.evt.len + sizeof(QEvt)), - 0U, /* margin */ + 0U, // margin (enum_t)l_rx.var.evt.sig); - if (l_rx.var.evt.e != (QEvt *)0) { /* evt allocated? */ + if (l_rx.var.evt.e != (QEvt *)0) { // evt allocated? l_rx.var.evt.p = (uint8_t *)l_rx.var.evt.e; l_rx.var.evt.p = &l_rx.var.evt.p[sizeof(QEvt)]; if (l_rx.var.evt.len > 0U) { @@ -15406,7 +11445,7 @@ static void QS_rxParseData_(uint8_t const b) { } break; } - case WAIT4_EVT_PAR: { /* event parameters */ + case (uint8_t)WAIT4_EVT_PAR: { // event parameters *l_rx.var.evt.p = b; ++l_rx.var.evt.p; --l_rx.var.evt.len; @@ -15415,25 +11454,25 @@ static void QS_rxParseData_(uint8_t const b) { } break; } - case WAIT4_EVT_FRAME: { - /* keep ignoring the data until a frame is collected */ + case (uint8_t)WAIT4_EVT_FRAME: { + // keep ignoring the data until a frame is collected break; } #ifdef Q_UTEST - case WAIT4_TEST_SETUP_FRAME: { - /* keep ignoring the data until a frame is collected */ + case (uint8_t)WAIT4_TEST_SETUP_FRAME: { + // keep ignoring the data until a frame is collected break; } - case WAIT4_TEST_TEARDOWN_FRAME: { - /* keep ignoring the data until a frame is collected */ + case (uint8_t)WAIT4_TEST_TEARDOWN_FRAME: { + // keep ignoring the data until a frame is collected break; } - case WAIT4_TEST_CONTINUE_FRAME: { - /* keep ignoring the data until a frame is collected */ + case (uint8_t)WAIT4_TEST_CONTINUE_FRAME: { + // keep ignoring the data until a frame is collected break; } - case WAIT4_TEST_PROBE_DATA: { + case (uint8_t)WAIT4_TEST_PROBE_DATA: { l_rx.var.tp.data |= ((uint32_t)b << l_rx.var.tp.idx); l_rx.var.tp.idx += 8U; if (l_rx.var.tp.idx == (uint8_t)(8U * sizeof(uint32_t))) { @@ -15443,7 +11482,7 @@ static void QS_rxParseData_(uint8_t const b) { } break; } - case WAIT4_TEST_PROBE_ADDR: { + case (uint8_t)WAIT4_TEST_PROBE_ADDR: { l_rx.var.tp.addr |= ((QSFun)b << l_rx.var.tp.idx); l_rx.var.tp.idx += 8U; if (l_rx.var.tp.idx == (uint8_t)(8U * QS_FUN_PTR_SIZE)) { @@ -15451,17 +11490,17 @@ static void QS_rxParseData_(uint8_t const b) { } break; } - case WAIT4_TEST_PROBE_FRAME: { - /* keep ignoring the data until a frame is collected */ + case (uint8_t)WAIT4_TEST_PROBE_FRAME: { + // keep ignoring the data until a frame is collected break; } -#endif /* Q_UTEST */ +#endif // Q_UTEST - case ERROR_STATE: { - /* keep ignoring the data until a good frame is collected */ + case (uint8_t)ERROR_STATE: { + // keep ignoring the data until a good frame is collected break; } - default: { /* unexpected or unimplemented state */ + default: { // unexpected or unimplemented state QS_rxReportError_(0x45); QS_RX_TRAN_(ERROR_STATE); break; @@ -15469,62 +11508,414 @@ static void QS_rxParseData_(uint8_t const b) { } } -/*..........................................................................*/ -static void QS_rxHandleBadFrame_(uint8_t const state) { - QS_rxReportError_(0x50); /* report error for all bad frames */ +//............................................................................ +static void QS_rxHandleGoodFrame_(uint8_t const state) { + uint8_t i; + uint8_t *ptr; + switch (state) { + case WAIT4_INFO_FRAME: { + // no need to report Ack or Done + QS_target_info_pre_(0U); // send only Target info + break; + } + case WAIT4_RESET_FRAME: { + // no need to report Ack or Done, because Target resets + QS_onReset(); // reset the Target + break; + } + case WAIT4_CMD_PARAM1: // intentionally fall-through + case WAIT4_CMD_PARAM2: // intentionally fall-through + case WAIT4_CMD_PARAM3: // intentionally fall-through + case WAIT4_CMD_FRAME: { + QS_rxReportAck_((int8_t)QS_RX_COMMAND); + QS_onCommand(l_rx.var.cmd.cmdId, l_rx.var.cmd.param1, + l_rx.var.cmd.param2, l_rx.var.cmd.param3); +#ifdef Q_UTEST + #if Q_UTEST != 0 + QS_processTestEvts_(); // process all events produced + #endif // Q_UTEST != 0 +#endif // Q_UTEST + QS_rxReportDone_((int8_t)QS_RX_COMMAND); + break; + } + case WAIT4_TICK_FRAME: { + QS_rxReportAck_((int8_t)QS_RX_TICK); +#ifdef Q_UTEST + QTimeEvt_tick1_((uint_fast8_t)l_rx.var.tick.rate, &QS_rxPriv_); + #if Q_UTEST != 0 + QS_processTestEvts_(); // process all events produced + #endif // Q_UTEST != 0 +#else + QTimeEvt_tick_((uint_fast8_t)l_rx.var.tick.rate, &QS_rxPriv_); +#endif // Q_UTEST + QS_rxReportDone_((int8_t)QS_RX_TICK); + break; + } + case WAIT4_PEEK_FRAME: { + // no need to report Ack or Done + QS_beginRec_((uint_fast8_t)QS_PEEK_DATA); + ptr = (uint8_t *)QS_rxPriv_.currObj[AP_OBJ]; + ptr = &ptr[l_rx.var.peek.offs]; + QS_TIME_PRE_(); // timestamp + QS_U16_PRE_(l_rx.var.peek.offs); // data offset + QS_U8_PRE_(l_rx.var.peek.size); // data size + QS_U8_PRE_(l_rx.var.peek.num); // # data items + for (i = 0U; i < l_rx.var.peek.num; ++i) { + switch (l_rx.var.peek.size) { + case 1: + QS_U8_PRE_(ptr[i]); + break; + case 2: + QS_U16_PRE_(((uint16_t *)ptr)[i]); + break; + case 4: + QS_U32_PRE_(((uint32_t *)ptr)[i]); + break; + default: + // intentionally empty + break; + } + } + QS_endRec_(); + + QS_REC_DONE(); // user callback (if defined) + break; + } + case WAIT4_POKE_DATA: { + // received less than expected poke data items + QS_rxReportError_((int8_t)QS_RX_POKE); + break; + } + case WAIT4_POKE_FRAME: { + QS_rxReportAck_((int8_t)QS_RX_POKE); + // no need to report done + break; + } + case WAIT4_FILL_FRAME: { + QS_rxReportAck_((int8_t)QS_RX_FILL); + ptr = (uint8_t *)QS_rxPriv_.currObj[AP_OBJ]; + ptr = &ptr[l_rx.var.poke.offs]; + for (i = 0U; i < l_rx.var.poke.num; ++i) { + switch (l_rx.var.poke.size) { + case 1: + ptr[i] = (uint8_t)l_rx.var.poke.data; + break; + case 2: + ((uint16_t *)ptr)[i] + = (uint16_t)l_rx.var.poke.data; + break; + case 4: + ((uint32_t *)ptr)[i] = l_rx.var.poke.data; + break; + default: + // intentionally empty + break; + } + } + break; + } + case WAIT4_FILTER_FRAME: { + QS_rxReportAck_(l_rx.var.flt.recId); + + // apply the received filters + if (l_rx.var.flt.recId == (int8_t)QS_RX_GLB_FILTER) { + for (i = 0U; i < Q_DIM(QS_filt_.glb); ++i) { + QS_filt_.glb[i] = l_rx.var.flt.data[i]; + } + // leave the "not maskable" filters enabled, + // see qs.h, Miscellaneous QS records (not maskable) + QS_filt_.glb[0] |= 0x01U; + QS_filt_.glb[7] |= 0xFCU; + QS_filt_.glb[8] |= 0x7FU; + + // never enable the last 3 records (0x7D, 0x7E, 0x7F) + QS_filt_.glb[15] &= 0x1FU; + } + else if (l_rx.var.flt.recId == (int8_t)QS_RX_LOC_FILTER) { + for (i = 0U; i < Q_DIM(QS_filt_.loc); ++i) { + QS_filt_.loc[i] = l_rx.var.flt.data[i]; + } + // leave QS_ID == 0 always on + QS_filt_.loc[0] |= 0x01U; + } + else { + QS_rxReportError_(l_rx.var.flt.recId); + } + // no need to report Done + break; + } + case WAIT4_OBJ_FRAME: { + i = l_rx.var.obj.kind; + if (i < (uint8_t)MAX_OBJ) { + if (l_rx.var.obj.recId == (int8_t)QS_RX_CURR_OBJ) { + QS_rxPriv_.currObj[i] = (void *)l_rx.var.obj.addr; + QS_rxReportAck_((int8_t)QS_RX_CURR_OBJ); + } + else if (l_rx.var.obj.recId == (int8_t)QS_RX_AO_FILTER) { + if (l_rx.var.obj.addr != 0U) { + int_fast16_t const filter = + (int_fast16_t)((QActive *)l_rx.var.obj.addr)->prio; + QS_locFilter_((i == 0U) + ? filter + :-filter); + QS_rxReportAck_((int8_t)QS_RX_AO_FILTER); + } + else { + QS_rxReportError_((int8_t)QS_RX_AO_FILTER); + } + } + else { + QS_rxReportError_(l_rx.var.obj.recId); + } + } + // both SM and AO + else if (i == (uint8_t)SM_AO_OBJ) { + if (l_rx.var.obj.recId == (int8_t)QS_RX_CURR_OBJ) { + QS_rxPriv_.currObj[SM_OBJ] = (void *)l_rx.var.obj.addr; + QS_rxPriv_.currObj[AO_OBJ] = (void *)l_rx.var.obj.addr; + } + QS_rxReportAck_(l_rx.var.obj.recId); + } + else { + QS_rxReportError_(l_rx.var.obj.recId); + } + break; + } + case WAIT4_QUERY_FRAME: { + QS_queryCurrObj(l_rx.var.obj.kind); + break; + } case WAIT4_EVT_FRAME: { - Q_ASSERT_ID(910, l_rx.var.evt.e != (QEvt *)0); + // NOTE: Ack was already reported in the WAIT4_EVT_LEN state +#ifdef Q_UTEST + QS_onTestEvt(l_rx.var.evt.e); // adjust the event, if needed +#endif // Q_UTEST + i = 0U; // use 'i' as status, 0 == success,no-recycle + + if (l_rx.var.evt.prio == 0U) { // publish + QActive_publish_(l_rx.var.evt.e, &QS_rxPriv_, 0U); + } + else if (l_rx.var.evt.prio < QF_MAX_ACTIVE) { + if (!QACTIVE_POST_X(QActive_registry_[l_rx.var.evt.prio], + l_rx.var.evt.e, + 0U, // margin + &QS_rxPriv_)) + { + // failed QACTIVE_POST() recycles the event + i = 0x80U; // failure status, no recycle + } + } + else if (l_rx.var.evt.prio == 255U) { // special prio + // dispatch to the current SM object + if (QS_rxPriv_.currObj[SM_OBJ] != (void *)0) { + // increment the ref-ctr to simulate the situation + // when the event is just retreived from a queue. + // This is expected for the following QF_gc() call. + ++l_rx.var.evt.e->refCtr_; + + QAsm * const sm = (QAsm *)QS_rxPriv_.currObj[SM_OBJ]; + (*sm->vptr->dispatch)(sm, l_rx.var.evt.e, 0U); + i = 0x01U; // success status, recycle needed + } + else { + i = 0x81U; // failure status, recycle needed + } + } + else if (l_rx.var.evt.prio == 254U) { // special prio + // init the current SM object" + if (QS_rxPriv_.currObj[SM_OBJ] != (void *)0) { + // increment the ref-ctr to simulate the situation + // when the event is just retreived from a queue. + // This is expected for the following QF_gc() call. + ++l_rx.var.evt.e->refCtr_; + + QAsm * const sm = (QAsm *)QS_rxPriv_.currObj[SM_OBJ]; + (*sm->vptr->init)(sm, l_rx.var.evt.e, 0U); + i = 0x01U; // success status, recycle needed + } + else { + i = 0x81U; // failure status, recycle needed + } + } + else if (l_rx.var.evt.prio == 253U) { // special prio + // post to the current AO + if (QS_rxPriv_.currObj[AO_OBJ] != (void *)0) { + if (!QACTIVE_POST_X( + (QActive *)QS_rxPriv_.currObj[AO_OBJ], + l_rx.var.evt.e, + 0U, // margin + &QS_rxPriv_)) + { + // failed QACTIVE_POST() recycles the event + i = 0x80U; // failure status, no recycle + } + } + else { + i = 0x81U; // failure status, recycle needed + } + } + else { + i = 0x81U; // failure status, recycle needed + } + #if (QF_MAX_EPOOL > 0U) - QF_gc(l_rx.var.evt.e); /* don't leak an allocated event */ + if ((i & 0x01U) != 0U) { // recycle needed? + QF_gc(l_rx.var.evt.e); + } #endif + if ((i & 0x80U) != 0U) { // failure? + QS_rxReportError_((int8_t)QS_RX_EVENT); + } + else { +#ifdef Q_UTEST + #if Q_UTEST != 0 + QS_processTestEvts_(); // process all events produced + #endif // Q_UTEST != 0 +#endif // Q_UTEST + QS_rxReportDone_((int8_t)QS_RX_EVENT); + } + break; + } + +#ifdef Q_UTEST + case WAIT4_TEST_SETUP_FRAME: { + QS_rxReportAck_((int8_t)QS_RX_TEST_SETUP); + QS_tstPriv_.tpNum = 0U; // clear the Test-Probes + QS_tstPriv_.testTime = 0U; // clear the time tick + // don't clear current objects + QS_onTestSetup(); // application-specific test setup + // no need to report Done + break; + } + case WAIT4_TEST_TEARDOWN_FRAME: { + QS_rxReportAck_((int8_t)QS_RX_TEST_TEARDOWN); + QS_onTestTeardown(); // application-specific test teardown + // no need to report Done + break; + } + case WAIT4_TEST_CONTINUE_FRAME: { + QS_rxReportAck_((int8_t)QS_RX_TEST_CONTINUE); + QS_rxPriv_.inTestLoop = false; // exit the QUTest loop + // no need to report Done + break; + } + case WAIT4_TEST_PROBE_FRAME: { + QS_rxReportAck_((int8_t)QS_RX_TEST_PROBE); + Q_ASSERT_INCRIT(815, QS_tstPriv_.tpNum + < (sizeof(QS_tstPriv_.tpBuf) / sizeof(QS_tstPriv_.tpBuf[0]))); + QS_tstPriv_.tpBuf[QS_tstPriv_.tpNum] = l_rx.var.tp; + ++QS_tstPriv_.tpNum; + // no need to report Done + break; + } +#endif // Q_UTEST + + case ERROR_STATE: { + // keep ignoring all bytes until new frame break; } default: { - /* intentionally empty */ + QS_rxReportError_(0x47); break; } } } -/*..........................................................................*/ +//............................................................................ +static void QS_rxHandleBadFrame_(uint8_t const state) { + QS_rxReportError_(0x50); // report error for all bad frames + switch (state) { + case WAIT4_EVT_FRAME: { + Q_ASSERT_INCRIT(910, l_rx.var.evt.e != (QEvt *)0); +#if (QF_MAX_EPOOL > 0U) + QF_gc(l_rx.var.evt.e); // don't leak an allocated event +#endif + break; + } + default: { + // intentionally empty + break; + } + } +} + +//............................................................................ static void QS_rxReportAck_(int8_t const recId) { - QS_CRIT_STAT_ - QS_CRIT_E_(); QS_beginRec_((uint_fast8_t)QS_RX_STATUS); - QS_U8_PRE_(recId); /* record ID */ + QS_U8_PRE_(recId); // record ID QS_endRec_(); - QS_CRIT_X_(); - - QS_REC_DONE(); /* user callback (if defined) */ + QS_REC_DONE(); // user callback (if defined) } -/*..........................................................................*/ +//............................................................................ static void QS_rxReportError_(int8_t const code) { - QS_CRIT_STAT_ - QS_CRIT_E_(); QS_beginRec_((uint_fast8_t)QS_RX_STATUS); - QS_U8_PRE_(0x80U | (uint8_t)code); /* error code */ + QS_U8_PRE_(0x80U | (uint8_t)code); // error code QS_endRec_(); - QS_CRIT_X_(); - - QS_REC_DONE(); /* user callback (if defined) */ + QS_REC_DONE(); // user callback (if defined) } -/*..........................................................................*/ +//............................................................................ static void QS_rxReportDone_(int8_t const recId) { - QS_CRIT_STAT_ - QS_CRIT_E_(); QS_beginRec_((uint_fast8_t)QS_TARGET_DONE); - QS_TIME_PRE_(); /* timestamp */ - QS_U8_PRE_(recId); /* record ID */ + QS_TIME_PRE_(); // timestamp + QS_U8_PRE_(recId); // record ID QS_endRec_(); - QS_CRIT_X_(); - - QS_REC_DONE(); /* user callback (if defined) */ + QS_REC_DONE(); // user callback (if defined) } -/*..........................................................................*/ +//............................................................................ +static void QS_queryCurrObj(uint8_t const obj_kind) { + if (QS_rxPriv_.currObj[obj_kind] != (void *)0) { + QS_beginRec_((uint_fast8_t)QS_QUERY_DATA); + QS_TIME_PRE_(); // timestamp + QS_U8_PRE_(obj_kind); // object kind + QS_OBJ_PRE_(QS_rxPriv_.currObj[obj_kind]); + switch (obj_kind) { + case (uint8_t)SM_OBJ: // intentionally fall through + case (uint8_t)AO_OBJ: + QS_FUN_PRE_((*((QAsm *)QS_rxPriv_.currObj[obj_kind])->vptr + ->getStateHandler)( + ((QAsm *)QS_rxPriv_.currObj[obj_kind]))); + break; + case (uint8_t)MP_OBJ: + QS_MPC_PRE_(((QMPool *)QS_rxPriv_.currObj[obj_kind]) + ->nFree); + QS_MPC_PRE_(((QMPool *)QS_rxPriv_.currObj[obj_kind]) + ->nMin); + break; + case (uint8_t)EQ_OBJ: + QS_EQC_PRE_(((QEQueue *)QS_rxPriv_.currObj[obj_kind]) + ->nFree); + QS_EQC_PRE_(((QEQueue *)QS_rxPriv_.currObj[obj_kind]) + ->nMin); + break; + case (uint8_t)TE_OBJ: + QS_OBJ_PRE_(((QTimeEvt *)QS_rxPriv_.currObj[obj_kind]) + ->act); + QS_TEC_PRE_(((QTimeEvt *)QS_rxPriv_.currObj[obj_kind]) + ->ctr); + QS_TEC_PRE_(((QTimeEvt *)QS_rxPriv_.currObj[obj_kind]) + ->interval); + QS_SIG_PRE_(((QTimeEvt *)QS_rxPriv_.currObj[obj_kind]) + ->super.sig); + QS_U8_PRE_ (((QTimeEvt *)QS_rxPriv_.currObj[obj_kind]) + ->super.refCtr_); + break; + default: + // intentionally empty + break; + } + QS_endRec_(); + QS_REC_DONE(); // user callback (if defined) + } + else { + QS_rxReportError_((int8_t)QS_RX_QUERY_CURR); + } +} + +//............................................................................ static void QS_rxPoke_(void) { uint8_t *ptr = (uint8_t *)QS_rxPriv_.currObj[AP_OBJ]; ptr = &ptr[l_rx.var.poke.offs]; @@ -15538,91 +11929,151 @@ static void QS_rxPoke_(void) { case 4: *(uint32_t *)ptr = l_rx.var.poke.data; break; - default: - Q_ERROR_ID(900); + default: { + Q_ERROR_INCRIT(900); break; + } } l_rx.var.poke.data = 0U; l_rx.var.poke.idx = 0U; l_rx.var.poke.offs += (uint16_t)l_rx.var.poke.size; -} +} + +//! @endcond - /*! @file -* @brief QUTest unit testing harness -*/ - -/* Include this content in the build only when Q_UTEST is defined */ + // only build when Q_UTEST is defined #ifdef Q_UTEST -#define QP_IMPL /* this is QP implementation */ -#include "qf_port.h" /* QF port */ -#include "qf_pkg.h" /* QF package-scope interface */ -#include "qassert.h" /* QP embedded systems-friendly assertions */ -#include "qs_port.h" /* include QS port */ -#include "qs_pkg.h" /* QS facilities for pre-defined trace records */ +#define QP_IMPL // this is QP implementation +#include "qp_port.h" // QP port +#include "qp_pkg.h" // QP package-scope interface +#include "qsafe.h" // QP Functional Safety (FuSa) Subsystem +#include "qs_port.h" // include QS port +#include "qs_pkg.h" // QS facilities for pre-defined trace records -/*==========================================================================*/ -/* QUTest unit testing harness */ -$define ${QUTest} +//============================================================================ +// QUTest unit testing harness +$define ${QS::QUTest} -/*..........................................................................*/ -Q_NORETURN Q_onAssert( - char const * module, - int_t location) +//============================================================================ +//! @cond INTERNAL + +QSTestAttr QS_tstPriv_; + +//............................................................................ +void QS_test_pause_(void) { + QS_beginRec_((uint_fast8_t)QS_TEST_PAUSED); + QS_endRec_(); + QS_onTestLoop(); +} + +//............................................................................ +uint32_t QS_getTestProbe_(QSpyFunPtr const api) { + uint32_t data = 0U; + for (uint_fast8_t i = 0U; i < QS_tstPriv_.tpNum; ++i) { + if (QS_tstPriv_.tpBuf[i].addr == (QSFun)api) { + data = QS_tstPriv_.tpBuf[i].data; + + QS_CRIT_STAT + QS_CRIT_ENTRY(); + QS_MEM_SYS(); + QS_beginRec_((uint_fast8_t)QS_TEST_PROBE_GET); + QS_TIME_PRE_(); // timestamp + QS_FUN_PRE_(api); // the calling API + QS_U32_PRE_(data); // the Test-Probe data + QS_endRec_(); + + QS_REC_DONE(); // user callback (if defined) + + --QS_tstPriv_.tpNum; // one less Test-Probe + // move all remaining entries in the buffer up by one + for (uint_fast8_t j = i; j < QS_tstPriv_.tpNum; ++j) { + QS_tstPriv_.tpBuf[j] = QS_tstPriv_.tpBuf[j + 1U]; + } + QS_MEM_APP(); + QS_CRIT_EXIT(); + break; // we are done (Test-Probe retreived) + } + } + return data; +} + +//............................................................................ +QSTimeCtr QS_onGetTime(void) { + return (++QS_tstPriv_.testTime); +} + +//............................................................................ +Q_NORETURN Q_onError( + char const * const module, + int_t const id) { - QS_BEGIN_NOCRIT_PRE_(QS_ASSERT_FAIL, 0U) + QS_beginRec_((uint_fast8_t)QS_ASSERT_FAIL); QS_TIME_PRE_(); - QS_U16_PRE_(location); + QS_U16_PRE_(id); QS_STR_PRE_((module != (char *)0) ? module : "?"); - QS_END_NOCRIT_PRE_() + QS_endRec_(); - QS_onFlush(); /* flush the assertion record to the host */ - QS_onCleanup(); /* cleanup after the failure */ - QS_onReset(); /* reset the target to prevent the code from continuing */ - for (;;) { /* QS_onReset() should not return, but to ensure no-return */ + QS_onFlush(); // flush the assertion record to the host + QS_onCleanup(); // cleanup after the failure + QS_onReset(); // reset the target to prevent the code from continuing + for (;;) { // QS_onReset() should not return, but to ensure no-return } } -/*..........................................................................*/ -QSTimeCtr QS_onGetTime(void) { - return (++QS_testData.testTime); -} -/*==========================================================================*/ -/* QP-stub for QUTest -* NOTE: The QP-stub is needed for unit testing QP applications, but might -* NOT be needed for testing QP itself. In that case, the build process -* can define Q_UTEST=0 to exclude the QP-stub from the build. -*/ -#if Q_UTEST != 0 +//! @endcond +//============================================================================ + +// QP-stub for QUTest +// NOTE: The QP-stub is needed for unit testing QP applications, but might +// NOT be needed for testing QP itself. In that case, the build process +// can define Q_UTEST=0 to exclude the QP-stub from the build. +#if (Q_UTEST != 0) Q_DEFINE_THIS_MODULE("qutest") -$define ${QUTest-stub} -#endif /* Q_UTEST != 0 */ +//............................................................................ +void QS_processTestEvts_(void) { + QS_TEST_PROBE_DEF(&QS_processTestEvts_) -#endif /* Q_UTEST */ + // return immediately (do nothing) for Test Probe != 0 + QS_TEST_PROBE(return;) + + while (QPSet_notEmpty(&QS_tstPriv_.readySet)) { + uint_fast8_t const p = QPSet_findMax(&QS_tstPriv_.readySet); + QActive * const a = QActive_registry_[p]; + + QEvt const * const e = QActive_get_(a); + QASM_DISPATCH(a, e, a->prio); +#if (QF_MAX_EPOOL > 0U) + QF_gc(e); +#endif + if (a->eQueue.frontEvt == (QEvt *)0) { // empty queue? + QPSet_remove(&QS_tstPriv_.readySet, p); +#ifndef Q_UNSAFE + QPSet_update_(&QS_tstPriv_.readySet, &QS_tstPriv_.readySet_dis); +#endif + } + } +} + +$define ${QS::QUTest-stub} + +#endif // Q_UTEST != 0 + +#endif // Q_UTEST - /*! @file -* @brief Application build time-stamp -* @details -* This module needs to be re-compiled in every new software build. To achive -* this, it is recommended to delete the object file (qstamp.o, or qstamp.obj) -* in the build directory before each build. (Most development tools allow -* you to specify a pre-build command, which is the ideal place to delete -* the qstamp object file.) -*/ + #include "qstamp.h" -#include "qstamp.h" - -/*! the calendar date of the last translation of the form: "Mmm dd yyyy" */ +//! the calendar date of the last translation of the form: "Mmm dd yyyy" char const Q_BUILD_DATE[12] = __DATE__; -/*! the time of the last translation of the form: "hh:mm:ss" */ +//! the time of the last translation of the form: "hh:mm:ss" char const Q_BUILD_TIME[9] = __TIME__; diff --git a/qpc.sha256 b/qpc.sha256 new file mode 100644 index 00000000..ef8bc597 --- /dev/null +++ b/qpc.sha256 @@ -0,0 +1,193 @@ +8b8d56e339046359297fac0a6855b9d530797780a933e2530c3acb75ebe06162 include/qequeue.h +67d00443d954d590baa4d95645ea7853f89c545e7d0d83f8cbcb435e2b7db58a include/qk.h +051d7f3547da2b1ca6c6ae9135020fd19364d4815adb6b4e89d08d1d690cb460 include/qmpool.h +89aba05e758d79dd723d3b2dac8daf5e40d738da6b80d78e59a922e061bcdee4 include/qp.h +81958d337c9de3adc09c6b2029eb7c0ecc1971bd4c91d88e8f7f3f5d1e35cec3 include/qpc.h +d80140d884ab56d772aebbddc4261562f2fbd9c311fa14d632d7853798c1a43f include/qp_pkg.h +88e91affbdbe31acbce8b5393be8135415c0467821cc3cd1ecb13f23b79b4d19 include/qs.h +0b753874088d6483a6d7c52d482d07f631fcfddd873a12ba947f50327f68851b include/qsafe.h +f08bbc7f47fff3ba6efb7a07aee671550f8235c043c7fc0f00d928ca262b7a43 include/qstamp.h +b25eed33ede77bdbbfc638461a561d2d7f959b3aed0f7e8ebe71c793bbd2950e include/qs_dummy.h +925aec72edd4d2488975780bb9fe1f514d4757e92bdb5e48feac72aff949de20 include/qs_pkg.h +2c87255c7da14d3cf12f5590415110b55355bcafdb736ed0e00096bfcfb9e8bc include/qv.h +1585eed1e9fd30384c33488bde9f5055d8b5b8a6a461cf78a109efa464634e4b include/qxk.h +24378ba28d7aeadeaa9d7a88a2fcacda89528afe1f554d80ef765537ab30a405 ports/arm-cm/qk/armclang/qk_port.c +8d8a2a050f4bb1fdc2cfec3e4f2d2184d3564f04371e6b05aa598f5426eaf243 ports/arm-cm/qk/armclang/qp_port.h +36f6901265584f986751c266926fd408060bd58aa44df3d84885637d34f903ff ports/arm-cm/qk/armclang/qs_port.h +d318aa72491a667cbd721f51d4cc7b900056ab3f49d9a13712b373dc3d6ea7f1 ports/arm-cm/qk/gnu/qk_port.c +469cb9a7770c544d897e0ad7c167c16bb12f062ca4472a1e632a6712a443a316 ports/arm-cm/qk/gnu/qp_port.h +36f6901265584f986751c266926fd408060bd58aa44df3d84885637d34f903ff ports/arm-cm/qk/gnu/qs_port.h +8fbfaeccfe8e5959b0abc8758616204e27d3d0806b2cf90b0417f484fc770dc2 ports/arm-cm/qk/iar/qk_port.c +f4da92e3335738fa69089f51b1137a2643776420fc5d7c28b2ab527ca7be2eea ports/arm-cm/qk/iar/qp_port.h +36f6901265584f986751c266926fd408060bd58aa44df3d84885637d34f903ff ports/arm-cm/qk/iar/qs_port.h +e614d285256839e4d4b0766c408bf4f27a0aad28f7f79efa51cd7cb0adc4a80a ports/arm-cm/qutest/qp_port.h +f075cd0aef2a1286c8370fc45826e8adac4756363788e91e21e75ef601ccf2fa ports/arm-cm/qutest/qs_port.h +2b18d35167e1d3785aaec23d7d2f8e77f50ee8a853e915407ace44659d4536fa ports/arm-cm/qv/armclang/qp_port.h +36f6901265584f986751c266926fd408060bd58aa44df3d84885637d34f903ff ports/arm-cm/qv/armclang/qs_port.h +0f4503089a465f415fa9cf7e01cd011c5f9ca37dc5bf0a47c46de394247e540c ports/arm-cm/qv/armclang/qv_port.c +e88edf2125cff1137d14144be37f796f10a6daad04b7ee1a830c4477c4c7b0f8 ports/arm-cm/qv/gnu/qp_port.h +36f6901265584f986751c266926fd408060bd58aa44df3d84885637d34f903ff ports/arm-cm/qv/gnu/qs_port.h +4a06b108702013da24d5d5ebd87b479308a8a0ec348eacab13a1854a8d997450 ports/arm-cm/qv/gnu/qv_port.c +63f53127c7eec7da6af1c6d91d07bc23ebbb777b5f7bf57fe14d59cc67f9b98c ports/arm-cm/qv/iar/qp_port.h +36f6901265584f986751c266926fd408060bd58aa44df3d84885637d34f903ff ports/arm-cm/qv/iar/qs_port.h +858ebfb4d0c359f961b78c50a372fce89058d55b6c03292e5e9cca774d461fdc ports/arm-cm/qv/iar/qv_port.c +59729684c6c27a5f9264d9b7435ddc471553acf907a9c7c9eb029f21d6c03b15 ports/arm-cm/qxk/armclang/qp_port.h +36f6901265584f986751c266926fd408060bd58aa44df3d84885637d34f903ff ports/arm-cm/qxk/armclang/qs_port.h +d7c89b0009e76c65fef4543569809f4951a43f8bbecdaa0781fbe93f5c91a391 ports/arm-cm/qxk/armclang/qxk_port.c +9a8e3552e72fd0989f7f41285b3a8139f5150ced41380dbbf0ad466782803a59 ports/arm-cm/qxk/gnu/qp_port.h +5d3e7c55a43cd0cfe27947fab1f755afa86eb4b9236788c61e4ee353bac5f599 ports/arm-cm/qxk/gnu/qs_port.h +6bb8beefa0618a2b4f956452795c8231314a1fad42a28bb99c7ee92188e5c936 ports/arm-cm/qxk/gnu/qxk_port.c +ba9ba108355f7c946d88c0f3239a41c29a4fe8191563faadd70beb1ec071beb8 ports/arm-cm/qxk/iar/qp_port.h +36f6901265584f986751c266926fd408060bd58aa44df3d84885637d34f903ff ports/arm-cm/qxk/iar/qs_port.h +d583388de95a90046ade23f573e9e127e11f62fe25aa8b2bc01db2f996c7e841 ports/arm-cm/qxk/iar/qxk_port.c +61d36fed7425ed8f03c833e5f5d5b0da36495bbad45b90893bcd29a3a432f0bb ports/arm-cm/qxk/llvm/README.txt +42b6d77594f3336cb129af601f5a36acd29116aaeb09fb98aa52b687303ae2fc ports/arm-cm/README.md +b8e04851c3fdd2a65f59cf793d2691c93a8bd989a03a0db3e3ae293c473fcbd3 ports/arm-cr/qk/gnu/qp_port.h +df1aa59bb139c33ce3baccea4d65bff6bb851ec85679f1bf49ab0648edf9f245 ports/arm-cr/qk/gnu/qs_port.h +ea74f4f2da1628f217a80e2d893653280ed56c4f671f01776f3ba86d266f7a38 ports/arm-cr/qk/iar/qp_port.h +df1aa59bb139c33ce3baccea4d65bff6bb851ec85679f1bf49ab0648edf9f245 ports/arm-cr/qk/iar/qs_port.h +d6aace1f2236aa1782d0c59932b2fa67c08b788d79f1f3e6a559fd6981b1b019 ports/arm-cr/qk/ti/qp_port.h +df1aa59bb139c33ce3baccea4d65bff6bb851ec85679f1bf49ab0648edf9f245 ports/arm-cr/qk/ti/qs_port.h +4169f53fb025e8f19b54c32c5320e60697b4d3ff9b7dca92fbe77d2c5e352d7e ports/arm-cr/qv/gnu/qp_port.h +df1aa59bb139c33ce3baccea4d65bff6bb851ec85679f1bf49ab0648edf9f245 ports/arm-cr/qv/gnu/qs_port.h +055deb586d5c0a84136928820d554c111a6ff5c51d168126e9564813c6aea94c ports/arm-cr/qv/iar/qp_port.h +df1aa59bb139c33ce3baccea4d65bff6bb851ec85679f1bf49ab0648edf9f245 ports/arm-cr/qv/iar/qs_port.h +f1989ed492d57df46171f9b9795510737a6be71ef057c9c757f9c4cfda51c40a ports/arm-cr/qv/ti/qp_port.h +df1aa59bb139c33ce3baccea4d65bff6bb851ec85679f1bf49ab0648edf9f245 ports/arm-cr/qv/ti/qs_port.h +6d7c9d7d4de03806197306ee6c2eb05f0f00d2a8d71daa9a8934a673de387e60 ports/embos/qf_port.c +5bcc20749a2cc93a16f350a85df6837dee02db84e9b82e9dbecf28a9ecb1d4ac ports/embos/qp_port.h +37c8e1986d788090ecaeb5b0ee6d1c4d6e3a0003d05beb35ef57a8b88487f5b1 ports/embos/qs_port.h +f1e5e4cda7affce3472d444c157e8db0ce69866a7e75df03da9daed5afd0ea68 ports/esp-idf/qf_port.c +49080034a11f076fe36b914be6df7e7c92a5a5a8c3892165e1d8e7b94da6d11e ports/esp-idf/qp_port.h +df1aa59bb139c33ce3baccea4d65bff6bb851ec85679f1bf49ab0648edf9f245 ports/esp-idf/qs_port.h +7d747365c0ccd14c4971e1433cb4c7eb693dc172f6623dff5b22ae5116a7e960 ports/esp-idf/README.md +26d9f15943214948cef1d23f27eebb579305e7f155d17a3243da2c40aa6ab9c7 ports/freertos/qf_port.c +98989b9756d84c1cbf403f9e2d4a98acae2b70d990372b0dd9a18c75fcf617a4 ports/freertos/qp_port.h +df1aa59bb139c33ce3baccea4d65bff6bb851ec85679f1bf49ab0648edf9f245 ports/freertos/qs_port.h +002821ee6610360f38701461689fd43d7d8278052bddbbf42e3e9c50cfa0aea0 ports/lint-plus/16bit/cpu.lnt +629a9bf2c5d50079a59becddc930f91a5a4addce81462b288ea578e6c37572c8 ports/lint-plus/16bit/qs_port.h +7fad54e3af2e399df105ab94b26684abd59d46b77c78a34c2dae92bde3dd18ae ports/lint-plus/16bit/stdint.h +f9fba84406cf69f6a112535903c2550eeb62d36221c694a3276f4a32a1db668c ports/lint-plus/32bit/cpu.lnt +c86621018906ede714a8a4ddd0f54e77588d8b787b84627f9e40d48aa04dccd7 ports/lint-plus/32bit/qs_port.h +3647a97fb66256b7477418a782249132e821c4bffee94d1bd96200633dd5c07c ports/lint-plus/32bit/stdint.h +034bcab98311689a93786599218d93ba6257f1d214446f2fb238ca1538d9c40f ports/lint-plus/au-barr.lnt +f021b228f0af091270e17333f35cc4d56678aae5c6efcebb39c64ae6d1ac6a21 ports/lint-plus/au-ds.lnt +2032fbfc41eeac759180330cbd598f08d41cfe9ae4cd71ab595ff8b796ea9cc5 ports/lint-plus/au-misra4.lnt +cd7c2b0574a9be5f74d5e2d51066153b115a293f159e72cf3c720194b64e2038 ports/lint-plus/au-ql-c99.lnt +09ad76eb3778ab87cd0d20ae2c96791f2564c9728efc2d6d8b40cf8e496390d9 ports/lint-plus/lint_qf.log +5ae1e46b7367ce70f45f213b4f28743e8ad5100109b76929223633e7e0281b82 ports/lint-plus/lint_qk.log +073f1ba7b65ddfbd534fd84dc6c698d4a6e4f03162d336cf8cef628c53ba5868 ports/lint-plus/lint_qs.log +d43f388ad47cdc6ccc148ee8adeb580154c44377542f043f16d33ee1aed0d180 ports/lint-plus/lint_qv.log +fdbfb6a485e2c3c19e2359a997c0fe08b8e9ab70cc8decb8796928e350e5bed7 ports/lint-plus/lint_qxk.log +2d7e4acf2c02e07120b0854b1141f9023094ce9164258be9503fd2b85202ae42 ports/lint-plus/make.bat +024d0a692399635b1bdecb38b919f12636359b150fa2f7eaaae452561e8184b2 ports/lint-plus/options.lnt +460af8fac27d52c1427c4c1181eb251590478717ddbc873b1ea6c1ec6ece3488 ports/lint-plus/qk/qp_port.h +a2665c83c3357860d52915aaff6497499e7ec4ace9b1102217cd916e56154f7a ports/lint-plus/ql-style.lnt +96188f4b40c1cc7bb439f33bf6a77c490d1d7c58a16447bfc8b8f9bbde13ad8e ports/lint-plus/qpc.lnt +b82c8e8d68cf8bef30f2584843d3d0b526cfd3f323c70575d92c89cace30fcb6 ports/lint-plus/qv/qp_port.h +93d0a8f9648ec4ef5a1766fdd3f1e434255f763c9ce8ac304cd73107a6fea932 ports/lint-plus/qxk/qp_port.h +023d093fd26babffbff3de30a3e07f1d65b7b3ed8a969c5a36736dfa7062156c ports/lint-plus/std.lnt +7c793943c3e6649f8ee04019cf3ae70f35e11c16c3b88fabf01cdaa26b24daf0 ports/lint-plus/stdbool.h +f8061755072d975852b7b34383eb271a1171a45b81b178c719929c32794c4377 ports/msp430/qk/qp_port.h +a3a10044ff05824ebbe33e66c4c84635a78981314bb8cd195f76692d84a364e9 ports/msp430/qk/qs_port.h +065c6771d31e5d8dd48decb4fed44a705372d9ee4395fa512e2c229498d74c36 ports/msp430/qutest/qp_port.h +a3a10044ff05824ebbe33e66c4c84635a78981314bb8cd195f76692d84a364e9 ports/msp430/qutest/qs_port.h +b65d3e2d98647b65edb5df66be2c9686127de34e0355000dfe16e23b88ec57d8 ports/msp430/qv/qp_port.h +a3a10044ff05824ebbe33e66c4c84635a78981314bb8cd195f76692d84a364e9 ports/msp430/qv/qs_port.h +5f8ce0594ad46184c255c39016974696d0e01ed8ab0db8208d7ee4bde1d9f5a7 ports/msp430/README.md +802dd77af4048cb89db5989aed73e1cf89861b71f6be483438b82614b51019b6 ports/pic32/qk/xc32/qk_port.c +c7b29f966e8d3d0289e78c0e4422da89c2c2773258823e2b8022e58620640ce3 ports/pic32/qk/xc32/qp_port.h +df1aa59bb139c33ce3baccea4d65bff6bb851ec85679f1bf49ab0648edf9f245 ports/pic32/qk/xc32/qs_port.h +6c809eeb292f1f76e4d90a6f04fdcca43e49d2390aeaa278f0cb7ac302a174a5 ports/pic32/qutest/xc32/qp_port.h +df1aa59bb139c33ce3baccea4d65bff6bb851ec85679f1bf49ab0648edf9f245 ports/pic32/qutest/xc32/qs_port.h +45a8e1a636127d562cc60b0a1b4c7fec1b70bed62dac9f375e03d268c0c6bc9f ports/pic32/qv/xc32/qp_port.h +df1aa59bb139c33ce3baccea4d65bff6bb851ec85679f1bf49ab0648edf9f245 ports/pic32/qv/xc32/qs_port.h +352d02f6c83934f13063c5a46950ab2a03b71c59d512b8ddd16abd4099bec603 ports/posix/qf_port.c +ea7a0e1fbf48a897ec977236b00e915b12f9c84bbf5dc964bcbcb0879d70d2d9 ports/posix/qp_port.h +4a3e0972730b352cab598cd1f88a6e0d730e10cdd6973229e030b4f6d43577dd ports/posix/qs_port.c +7de8db6db071167ac2e378fb4dd230bc6048af82a904c7f6a7455f8321f07702 ports/posix/qs_port.h +cd74d192006f86d5855d25e8b29b4c9e698dbc659fea3c11c1be992853fd5d07 ports/posix/README.md +36571350408c0588430d2a84a1e29111a932bc0bf11caa4edd765026c7c03ef8 ports/posix/safe_std.h +399ad69a1f088627a429adbb7fd86d2864439d34dae0d105d335d08bd47cbb80 ports/posix-qutest/qp_port.h +7de8db6db071167ac2e378fb4dd230bc6048af82a904c7f6a7455f8321f07702 ports/posix-qutest/qs_port.h +d58a6400c4c23975d0c53440191c1b1bc0e81f6a9a28f52c387203a713e37bcb ports/posix-qutest/qutest_port.c +5fa89ee29a59ee9faeb5b7c9451480d712dbfbb62f13a4f3ba201adf026ead6c ports/posix-qutest/README.md +36571350408c0588430d2a84a1e29111a932bc0bf11caa4edd765026c7c03ef8 ports/posix-qutest/safe_std.h +463da0136b7e51f74773f382b88b93219a63f2b866c1e6668ccf98818c3f3286 ports/posix-qv/qf_port.c +3eda6a3ec604bdf2512a85744c2976669231c5f7df314bb578cbecccc5d27d8a ports/posix-qv/qp_port.h +abe7fa13ac872012993971e3c4ee91314d13c20ea2aea02a08cf2cabb622ff2b ports/posix-qv/qs_port.c +7de8db6db071167ac2e378fb4dd230bc6048af82a904c7f6a7455f8321f07702 ports/posix-qv/qs_port.h +b5eeaab70640ea7d21776be457838850cabda37d7811047afc02dd8284f77856 ports/posix-qv/README.md +36571350408c0588430d2a84a1e29111a932bc0bf11caa4edd765026c7c03ef8 ports/posix-qv/safe_std.h +9a67124e33c4b7750f876eaf281e66d9cac20bf47a032175e110651fb5713552 ports/qep-only/qp_port.h +36571350408c0588430d2a84a1e29111a932bc0bf11caa4edd765026c7c03ef8 ports/qep-only/safe_std.h +6f3e6913ff8e9bdaf3169d8cb3b32fa6fbb371d23027dbf34907313edbb61432 ports/qube/qp_port.h +a5fd631eef518ea2c874b487291d5013e831b50fc51efae459fde4496aa90bb3 ports/qube/qs_port.h +da94cf5c01292bed07e5952c1b7f3c84f7688ed5211e50d3cbbd4a7a49950281 ports/qube/qube.c +3b8ab30532bcff5cd9cbe32ced8a253fdcb6288206a04c4232b5e577ebb6864e ports/qube/README.txt +36571350408c0588430d2a84a1e29111a932bc0bf11caa4edd765026c7c03ef8 ports/qube/safe_std.h +746761180c1722950a4317f68ad6fd2d99bdb9f67c7524bd1c81de87748451c9 ports/risc-v/qv/gnu/qp_port.h +773652922d77de04a8c9b74edc3077b6932013b4d3c3a1aa76fe6bc54313df53 ports/risc-v/qv/gnu/qs_port.h +8c6aec7f001e90a6a1dcb6fb520afe48c994e8a334b105096e66bd40caf493f1 ports/risc-v/qv/README.md +425aff96a38a978c22971f0c804002e31b9f1e099beb5dcb729b1fea2544d767 ports/threadx/qf_port.c +36b760ee6518a8188d6fad59c90b28e4503af5677bc3541075cc9a87e42a8831 ports/threadx/qp_port.h +d4c51ba6444f22eb1677b5218788547e6a4750b06434077893a64203b8456775 ports/threadx/qs_port.h +d50b43a5fc2f6e06e15088f8edfcae2e8b2042e04964b2c31e9f8a4c7487ac55 ports/threadx/README.md +99066a2a201f51eefb2c842f582e72d51de638dcef4f7cd2f594179dce6eeb7d ports/uc-os2/qf_port.c +e49d1f600d79798e8b570e11c227238d30f2db2f84830b7edddb76c34bfcba5a ports/uc-os2/qp_port.h +d4c51ba6444f22eb1677b5218788547e6a4750b06434077893a64203b8456775 ports/uc-os2/qs_port.h +b30dbd0bfcd4544e93dc4354b436f8587247f14c4bacc6ebbed6bdd08374686a ports/win32/Makefile +75950e58fb58c88a7c63990c6eebcee5e0bd669cd7849a385aa03a12aabef73c ports/win32/qf_port.c +c06ea56ef631fa515273f2b3afc643133e332fc25f1f5bfe87f6f452e0150916 ports/win32/qp_port.h +2b95e055beb9711726b98a3940dd349f681828f731be66710ec1995f2b10aadc ports/win32/qs_port.c +26844e65da53d25109c81ede57980f0b3ee52338e643495701e6904c0788430a ports/win32/qs_port.h +b7bb01b22c929ceeca3bf9567b68c353ca202030a1c2e3b5c1091ac9770c0f45 ports/win32/qwin_gui.c +71fe6e88fe1e8b95e9d11b689094e73e04edb107abd27175e55b021f69b1cdd6 ports/win32/qwin_gui.h +bf4455826daf0b67d383196e00ec32ef8499ccc8ce8b9547c89008a95f7e9e67 ports/win32/README.md +36571350408c0588430d2a84a1e29111a932bc0bf11caa4edd765026c7c03ef8 ports/win32/safe_std.h +182eb5cfaf7d2906a92845ad9ea1b566f8c02ec2f3dc7017b127d17e7b74189a ports/win32-qutest/qp_port.h +26844e65da53d25109c81ede57980f0b3ee52338e643495701e6904c0788430a ports/win32-qutest/qs_port.h +242f54ea3b3864817fbc5f9fe96dd9b19562e1eec6a051f991e34b30c877a3c0 ports/win32-qutest/qutest_port.c +88e02b2c95659dc25359bf0a5f8e808fb32f372f78793684119414ea9edd2804 ports/win32-qutest/README.md +36571350408c0588430d2a84a1e29111a932bc0bf11caa4edd765026c7c03ef8 ports/win32-qutest/safe_std.h +4de6c3cb8b5cf76592deaaa6d63a6b26b8e802d9caa81f513890f0db9c58c8c2 ports/win32-qv/qf_port.c +db47cddcf144bf28c90649304ec79bc88b50c1b6847bcb52046af399ed22824c ports/win32-qv/qp_port.h +2b95e055beb9711726b98a3940dd349f681828f731be66710ec1995f2b10aadc ports/win32-qv/qs_port.c +26844e65da53d25109c81ede57980f0b3ee52338e643495701e6904c0788430a ports/win32-qv/qs_port.h +3e6d59cf42356cdca02fe9282cdd0cc3598bc178e19811f31a3405e8c20a8be4 ports/win32-qv/qwin_gui.c +20cece106a3f0e75278c7c5dc980e74a80072a0044a4be811124f5d411d75844 ports/win32-qv/qwin_gui.h +0a7285b6c324b65f77b913ab514b7c88a2c5c382815ef4646be16f446badd6b3 ports/win32-qv/README.md +36571350408c0588430d2a84a1e29111a932bc0bf11caa4edd765026c7c03ef8 ports/win32-qv/safe_std.h +ca5fb4ef580f327eb2225a85186c197727fb190af2401721a31ffc505214b6f3 ports/zephyr/README.md +bcf48052bc36d144fdac107fdb99e95a4463cd9d1c9a7174023ffbc9d00e4e08 qpc.qm +0604a30da57f900e111856a410056659c935c96ee4b74a11b4d1283af8d861ef src/qf/qep_hsm.c +569e2219d2aa4a9c4d9fcaf469e03aee21e30ab47e3c95bd6906f71fd5151186 src/qf/qep_msm.c +7efa2d38ea4e4cd31b2978518083955d1d2cd454fa5b970f84ac3bd745be36ea src/qf/qf_act.c +ba96b3da3692fdbcb514aaa74199931d48007e250f62f65f8c5ed4474b4c93a5 src/qf/qf_actq.c +0011614bc27ec39c6c67020c0e406e0eb07955b3f6e6b15bcce519049fae3e01 src/qf/qf_defer.c +2e86077d652508f3f9631f5f28cbc1293582b8111fa3a6234eff9d215a93f082 src/qf/qf_dyn.c +4e736e0e38af286bc50c37871c5b20031aa36eed173ee9efb8b961571f765c0e src/qf/qf_mem.c +a2670891ccaec58952373c3f674a18aa611856ccf2e20d837be61463076ef0d4 src/qf/qf_ps.c +211099c73b80a83206809cd29f82eb1a4300e4d2ed9c76eb730e0e9ed126648a src/qf/qf_qact.c +ac60466c58ce79c208620060bee2198e70ec8709f5887034dfc62e3aa930eae2 src/qf/qf_qeq.c +04886ebb5bdeddc0d935f7e22cae8f7180085f9ef36821cd8e012d0fafed01e7 src/qf/qf_qmact.c +0a706f9d1c830aef243ea94b0fecd83d221a35cf001251c64130d15ce082f489 src/qf/qf_time.c +d4d0a2d00ba8e46ef73f876aea023f142f314a6c075e2859717d2ee9594819d7 src/qk/qk.c +089120593cf6f2c83ec7fff0c40004728b3e06f374eaea88f974eadcaa4f1697 src/qs/qs.c +e920c00c47eeefca8912b0bfcfe3cbe8fc33f4cbe8581cdadea87aef2311c45e src/qs/qstamp.c +5a463c1e0d1d36c5b0f0a316838623ed0873c86fd2e65cd840cbda088aaca80c src/qs/qs_64bit.c +bfcf373f22651aaba53cf50bb4d449c24f4f7910f8d34d6ecd4fb88757838242 src/qs/qs_fp.c +60ba07a0847c79dd282c88bd660151171e68f52c426a9c87a541d31ad9fee369 src/qs/qs_rx.c +de1393f82a66b40bf2c5683ce4856d1d20ac99a690b788e8bd2544b180da9cdd src/qs/qutest.c +57c01f9761b415be83b99e31c6910cf1cfcb3bf3383f8fec6668f5d1f286fd44 src/qv/qv.c +862f33e99d90cae2a00d66f2bbb23585aa9c078bb36312e38beb8ad087eedf63 src/qxk/qxk.c +5637c466a2fd5bc8bce468e12841522f8dd453904e20fce54a31d41b5a5701a2 src/qxk/qxk_mutex.c +295fea200489ba3613aa29f368e9e84ecb05bafeac2399ba5aa96adf36a1474a src/qxk/qxk_sema.c +90533b63aacfe82c7464708809467e5bf9166c685ad91adceea2eb9087be78bc src/qxk/qxk_xthr.c +395ee14eb78a2444cd2884da8bccaafc518f3e21d879321c688b525a4e621fb8 zephyr/CMakeLists.txt +68ec317e1540a0b535d3a157208a765d128d28b80d61e2966017aabdf3eb8e53 zephyr/Kconfig +4de1df3aa8fcb9966f18c4f6ce858cb1a4e7398d0d97e00912416ff68186bf3c zephyr/module.yml +eeac744cdba48619bade9021722dd61bf2226cf4ba1759ab5286dde1f545d76d zephyr/qf_port.c +5c543328217094155c982b99d6713f95a09fb10850c4f751993e18c4ee519521 zephyr/qp_port.h +ec6cc1da9fd7ee413b2c90d61c9630f00912e5dce2acad43c438e93db9afc804 zephyr/qs_port.h +7e5a1cfe4f6fcb9ac4a0ac3a3fc9117e3880a92830a7edb0cd47e349bd143a26 zephyr/README.md diff --git a/src/qf/qep_hsm.c b/src/qf/qep_hsm.c index 275b9cfc..a8acea77 100644 --- a/src/qf/qep_hsm.c +++ b/src/qf/qep_hsm.c @@ -1,274 +1,255 @@ -/*$file${src::qf::qep_hsm.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* -* Model: qpc.qm -* File: ${src::qf::qep_hsm.c} -* -* This code has been generated by QM 5.2.4 . -* DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. -* -* This code is covered by the following QP license: -* License # : LicenseRef-QL-dual -* Issued to : Any user of the QP/C real-time embedded framework -* Framework(s) : qpc -* Support ends : 2023-12-31 -* License scope: -* -* Copyright (C) 2005 Quantum Leaps, LLC . -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -*/ -/*$endhead${src::qf::qep_hsm.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*! @file -* @brief ::QHsm implementation -* -* @tr{RQP103} @tr{RQP104} @tr{RQP120} @tr{RQP130} -*/ -#define QP_IMPL /* this is QP implementation */ -#include "qep_port.h" /* QEP port */ -#include "qassert.h" /* QP embedded systems-friendly assertions */ -#ifdef Q_SPY /* QS software tracing enabled? */ - #include "qs_port.h" /* QS port */ - #include "qs_pkg.h" /* QS facilities for pre-defined trace records */ +//$file${src::qf::qep_hsm.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// +// Model: qpc.qm +// File: ${src::qf::qep_hsm.c} +// +// This code has been generated by QM 5.3.0 . +// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. +// +// This code is covered by the following QP license: +// License # : LicenseRef-QL-dual +// Issued to : Any user of the QP/C real-time embedded framework +// Framework(s) : qpc +// Support ends : 2024-12-31 +// License scope: +// +// Copyright (C) 2005 Quantum Leaps, LLC . +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +// +//$endhead${src::qf::qep_hsm.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +#define QP_IMPL // this is QP implementation +#include "qp_port.h" // QP port +#include "qp_pkg.h" // QP package-scope interface +#include "qsafe.h" // QP Functional Safety (FuSa) Subsystem +#ifdef Q_SPY // QS software tracing enabled? + #include "qs_port.h" // QS port + #include "qs_pkg.h" // QS facilities for pre-defined trace records #else - #include "qs_dummy.h" /* disable the QS software tracing */ -#endif /* Q_SPY */ + #include "qs_dummy.h" // disable the QS software tracing +#endif // Q_SPY Q_DEFINE_THIS_MODULE("qep_hsm") -/*==========================================================================*/ -/*$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* Check for the minimum required QP version */ -#if (QP_VERSION < 700U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) -#error qpc version 7.0.0 or higher required +//$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// Check for the minimum required QP version +#if (QP_VERSION < 730U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) +#error qpc version 7.3.0 or higher required #endif -/*$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -/*$define${QEP::QP_versionStr[8]} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//$define${QEP::QP_versionStr[8]} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/*${QEP::QP_versionStr[8]} .................................................*/ +//${QEP::QP_versionStr[8]} ................................................... char const QP_versionStr[8] = QP_VERSION_STR; -/*$enddef${QEP::QP_versionStr[8]} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$enddef${QEP::QP_versionStr[8]} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -/*! Immutable events corresponding to the reserved signals. -* -* @details -* Static, immutable reserved events that the QEP event processor sends -* to state handler functions of QHsm-style state machine to execute entry -* actions, exit actions, and initial transitions. -*/ -static QEvt const l_reservedEvt_[] = { - { (QSignal)Q_EMPTY_SIG, 0U, 0U }, - { (QSignal)Q_ENTRY_SIG, 0U, 0U }, - { (QSignal)Q_EXIT_SIG, 0U, 0U }, - { (QSignal)Q_INIT_SIG, 0U, 0U } +//============================================================================ +//! @cond INTERNAL + +//$define${QEP::QEvt::reserved_[4]} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +QEvt const QEvt_reserved_[4] = { + QEVT_INITIALIZER(Q_EMPTY_SIG), + QEVT_INITIALIZER(Q_ENTRY_SIG), + QEVT_INITIALIZER(Q_EXIT_SIG), + QEVT_INITIALIZER(Q_INIT_SIG) }; -/*! helper function to trigger reserved event in an QHsm -* @private @memberof QHsm -* -* @param[in] state state handler function -* @param[in] sig reserved signal to trigger -*/ -static inline QState QHsm_reservedEvt_( - QHsm * const me, - QStateHandler const state, - enum QReservedSig const sig) -{ - return (*state)(me, &l_reservedEvt_[sig]); -} +//$enddef${QEP::QEvt::reserved_[4]} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -/*$define${QEP::QHsm} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +enum { + // maximum depth of state nesting in a HSM (including the top level), + // must be >= 3 + QHSM_MAX_NEST_DEPTH_ = 6 +}; -/*${QEP::QHsm} .............................................................*/ +// helper macro to handle reserved event in an QHsm +#define QHSM_RESERVED_EVT_(state_, sig_) \ + ((*(state_))(me, &QEvt_reserved_[(sig_)])) -/*${QEP::QHsm::isIn} .......................................................*/ -bool QHsm_isIn(QHsm * const me, - QStateHandler const state) -{ - /*! @pre the state configuration must be stable */ - Q_REQUIRE_ID(600, me->temp.fun == me->state.fun); +// helper macro to trace state entry +#define QS_STATE_ENTRY_(state_, qs_id_) \ + QS_CRIT_ENTRY(); \ + QS_MEM_SYS(); \ + QS_BEGIN_PRE_(QS_QEP_STATE_ENTRY, (qs_id_)) \ + QS_OBJ_PRE_(me); \ + QS_FUN_PRE_(state_); \ + QS_END_PRE_() \ + QS_MEM_APP(); \ + QS_CRIT_EXIT() - bool inState = false; /* assume that this HSM is not in 'state' */ +// helper macro to trace state exit +#define QS_STATE_EXIT_(state_, qs_id_) \ + QS_CRIT_ENTRY(); \ + QS_MEM_SYS(); \ + QS_BEGIN_PRE_(QS_QEP_STATE_EXIT, (qs_id_)) \ + QS_OBJ_PRE_(me); \ + QS_FUN_PRE_(state_); \ + QS_END_PRE_() \ + QS_MEM_APP(); \ + QS_CRIT_EXIT() - /* scan the state hierarchy bottom-up */ - QState r; - do { - /* do the states match? */ - if (me->temp.fun == state) { - inState = true; /* 'true' means that match found */ - r = Q_RET_IGNORED; /* break out of the loop */ - } - else { - r = QHsm_reservedEvt_(me, me->temp.fun, Q_EMPTY_SIG); - } - } while (r != Q_RET_IGNORED); /* QHsm_top() state not reached */ - me->temp.fun = me->state.fun; /* restore the stable state configuration */ +//! @endcond - return inState; /* return the status */ -} +//$define${QEP::QHsm} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/*${QEP::QHsm::childState} .................................................*/ -QStateHandler QHsm_childState(QHsm * const me, - QStateHandler const parent) -{ - QStateHandler child = me->state.fun; /* start with the current state */ - bool isFound = false; /* start with the child not found */ +//${QEP::QHsm} ............................................................... - /* establish stable state configuration */ - me->temp.fun = me->state.fun; - QState r; - do { - /* is this the parent of the current child? */ - if (me->temp.fun == parent) { - isFound = true; /* child is found */ - r = Q_RET_IGNORED; /* break out of the loop */ - } - else { - child = me->temp.fun; - r = QHsm_reservedEvt_(me, me->temp.fun, Q_EMPTY_SIG); - } - } while (r != Q_RET_IGNORED); /* QHsm_top() state not reached */ - me->temp.fun = me->state.fun; /* establish stable state configuration */ - - /*! @post the child must be found */ - Q_ENSURE_ID(810, isFound); - - #ifdef Q_NASSERT - Q_UNUSED_PAR(isFound); - #endif - - return child; /* return the child */ -} - -/*${QEP::QHsm::ctor} .......................................................*/ +//${QEP::QHsm::ctor} ......................................................... +//! @protected @memberof QHsm void QHsm_ctor(QHsm * const me, QStateHandler const initial) { - static struct QHsmVtable const vtable = { /* QHsm virtual table */ + static struct QAsmVtable const vtable = { // QAsm virtual table &QHsm_init_, &QHsm_dispatch_ #ifdef Q_SPY ,&QHsm_getStateHandler_ #endif }; - me->vptr = &vtable; - me->state.fun = Q_STATE_CAST(&QHsm_top); - me->temp.fun = initial; + // do not call the QAsm_ctor() here + me->super.vptr = &vtable; + me->super.state.fun = Q_STATE_CAST(&QHsm_top); + me->super.temp.fun = initial; } -/*${QEP::QHsm::top} ........................................................*/ -QState QHsm_top(QHsm const * const me, - QEvt const * const e) -{ - Q_UNUSED_PAR(me); - Q_UNUSED_PAR(e); - return Q_RET_IGNORED; /* the top state ignores all events */ -} - -/*${QEP::QHsm::init_} ......................................................*/ -void QHsm_init_(QHsm * const me, +//${QEP::QHsm::init_} ........................................................ +//! @private @memberof QHsm +void QHsm_init_( + QAsm * const me, void const * const e, uint_fast8_t const qs_id) { + QF_CRIT_STAT + #ifdef Q_SPY + QS_CRIT_ENTRY(); + QS_MEM_SYS(); if ((QS_priv_.flags & 0x01U) == 0U) { QS_priv_.flags |= 0x01U; QS_FUN_DICTIONARY(&QHsm_top); } + QS_MEM_APP(); + QS_CRIT_EXIT(); #else Q_UNUSED_PAR(qs_id); #endif QStateHandler t = me->state.fun; - /*! @pre the virtual pointer must be initialized, the top-most initial - * transition must be initialized, and the initial transition must not - * be taken yet. - */ - Q_REQUIRE_ID(200, (me->vptr != (struct QHsmVtable *)0) + QF_CRIT_ENTRY(); + Q_REQUIRE_INCRIT(200, (me->vptr != (struct QAsmVtable *)0) && (me->temp.fun != Q_STATE_CAST(0)) && (t == Q_STATE_CAST(&QHsm_top))); + QF_CRIT_EXIT(); - /* execute the top-most initial tran. */ + // execute the top-most initial tran. QState r = (*me->temp.fun)(me, Q_EVT_CAST(QEvt)); - /* the top-most initial transition must be taken */ - Q_ASSERT_ID(210, r == Q_RET_TRAN); + QF_CRIT_ENTRY(); + // the top-most initial tran. must be taken + Q_ASSERT_INCRIT(210, r == Q_RET_TRAN); - QS_CRIT_STAT_ + QS_MEM_SYS(); QS_BEGIN_PRE_(QS_QEP_STATE_INIT, qs_id) - QS_OBJ_PRE_(me); /* this state machine object */ - QS_FUN_PRE_(t); /* the source state */ - QS_FUN_PRE_(me->temp.fun); /* the target of the initial transition */ + QS_OBJ_PRE_(me); // this state machine object + QS_FUN_PRE_(t); // the source state + QS_FUN_PRE_(me->temp.fun); // the target of the initial tran. QS_END_PRE_() + QS_MEM_APP(); - /* drill down into the state hierarchy with initial transitions... */ + QF_CRIT_EXIT(); + + // drill down into the state hierarchy with initial transitions... do { - QStateHandler path[QHSM_MAX_NEST_DEPTH_]; /* tran entry path array */ - int_fast8_t ip = 0; /* tran entry path index */ + QStateHandler path[QHSM_MAX_NEST_DEPTH_]; // tran entry path array + int_fast8_t ip = 0; // tran entry path index path[0] = me->temp.fun; - (void)QHsm_reservedEvt_(me, me->temp.fun, Q_EMPTY_SIG); + (void)QHSM_RESERVED_EVT_(me->temp.fun, Q_EMPTY_SIG); while (me->temp.fun != t) { ++ip; - Q_ASSERT_ID(220, ip < QHSM_MAX_NEST_DEPTH_); + QF_CRIT_ENTRY(); + Q_ASSERT_INCRIT(220, ip < QHSM_MAX_NEST_DEPTH_); + QF_CRIT_EXIT(); path[ip] = me->temp.fun; - (void)QHsm_reservedEvt_(me, me->temp.fun, Q_EMPTY_SIG); + (void)QHSM_RESERVED_EVT_(me->temp.fun, Q_EMPTY_SIG); } me->temp.fun = path[0]; - /* nested initial transition, drill into the target hierarchy... */ + // nested initial tran.; drill into the target hierarchy... do { - QHsm_state_entry_(me, path[ip], qs_id); /* enter path[ip] */ + // enter path[ip] + if (QHSM_RESERVED_EVT_(path[ip], Q_ENTRY_SIG) + == Q_RET_HANDLED) + { + QS_STATE_ENTRY_(path[ip], qs_id); + } --ip; } while (ip >= 0); - t = path[0]; /* current state becomes the new source */ + t = path[0]; // current state becomes the new source - r = QHsm_reservedEvt_(me, t, Q_INIT_SIG); /* execute initial transition */ + r = QHSM_RESERVED_EVT_(t, Q_INIT_SIG); // execute initial tran. #ifdef Q_SPY if (r == Q_RET_TRAN) { + QS_CRIT_ENTRY(); + QS_MEM_SYS(); QS_BEGIN_PRE_(QS_QEP_STATE_INIT, qs_id) - QS_OBJ_PRE_(me); /* this state machine object */ - QS_FUN_PRE_(t); /* the source state */ - QS_FUN_PRE_(me->temp.fun); /* target of the initial tran. */ + QS_OBJ_PRE_(me); // this state machine object + QS_FUN_PRE_(t); // the source state + QS_FUN_PRE_(me->temp.fun); // the target of the initial tran. QS_END_PRE_() + QS_MEM_APP(); + QS_CRIT_EXIT(); } - #endif /* Q_SPY */ + #endif // Q_SPY } while (r == Q_RET_TRAN); + QS_CRIT_ENTRY(); + QS_MEM_SYS(); QS_BEGIN_PRE_(QS_QEP_INIT_TRAN, qs_id) - QS_TIME_PRE_(); /* time stamp */ - QS_OBJ_PRE_(me); /* this state machine object */ - QS_FUN_PRE_(t); /* the new active state */ + QS_TIME_PRE_(); // time stamp + QS_OBJ_PRE_(me); // this state machine object + QS_FUN_PRE_(t); // the new active state QS_END_PRE_() + QS_MEM_APP(); + QS_CRIT_EXIT(); - me->state.fun = t; /* change the current active state */ - me->temp.fun = t; /* mark the configuration as stable */ + me->state.fun = t; // change the current active state + #ifndef Q_UNSAFE + me->temp.uint = ~me->state.uint; + #endif } -/*${QEP::QHsm::dispatch_} ..................................................*/ -void QHsm_dispatch_(QHsm * const me, +//${QEP::QHsm::dispatch_} .................................................... +//! @private @memberof QHsm +void QHsm_dispatch_( + QAsm * const me, QEvt const * const e, uint_fast8_t const qs_id) { @@ -276,162 +257,265 @@ void QHsm_dispatch_(QHsm * const me, Q_UNUSED_PAR(qs_id); #endif - QStateHandler t = me->state.fun; - QS_CRIT_STAT_ + QStateHandler s = me->state.fun; + QStateHandler t = s; + QF_CRIT_STAT - /*! @pre the current state must be initialized and - * the state configuration must be stable - */ - Q_REQUIRE_ID(400, (t != Q_STATE_CAST(0)) - && (t == me->temp.fun)); + QF_CRIT_ENTRY(); + Q_REQUIRE_INCRIT(300, (s != Q_STATE_CAST(0)) + && (me->state.uint == (uintptr_t)(~me->temp.uint))); + Q_REQUIRE_INCRIT(302, QEvt_verify_(e)); + QS_MEM_SYS(); QS_BEGIN_PRE_(QS_QEP_DISPATCH, qs_id) - QS_TIME_PRE_(); /* time stamp */ - QS_SIG_PRE_(e->sig); /* the signal of the event */ - QS_OBJ_PRE_(me); /* this state machine object */ - QS_FUN_PRE_(t); /* the current state */ + QS_TIME_PRE_(); // time stamp + QS_SIG_PRE_(e->sig); // the signal of the event + QS_OBJ_PRE_(me); // this state machine object + QS_FUN_PRE_(s); // the current state QS_END_PRE_() + QS_MEM_APP(); - QStateHandler s; + QF_CRIT_EXIT(); + + // process the event hierarchically... QState r; - /* process the event hierarchically... */ + me->temp.fun = s; do { s = me->temp.fun; - r = (*s)(me, e); /* invoke state handler s */ + r = (*s)(me, e); // invoke state handler s - if (r == Q_RET_UNHANDLED) { /* unhandled due to a guard? */ + if (r == Q_RET_UNHANDLED) { // unhandled due to a guard? + QS_CRIT_ENTRY(); + QS_MEM_SYS(); QS_BEGIN_PRE_(QS_QEP_UNHANDLED, qs_id) - QS_SIG_PRE_(e->sig); /* the signal of the event */ - QS_OBJ_PRE_(me); /* this state machine object */ - QS_FUN_PRE_(s); /* the current state */ + QS_SIG_PRE_(e->sig); // the signal of the event + QS_OBJ_PRE_(me); // this state machine object + QS_FUN_PRE_(s); // the current state QS_END_PRE_() + QS_MEM_APP(); + QS_CRIT_EXIT(); - r = QHsm_reservedEvt_(me, s, Q_EMPTY_SIG); /* find superstate of s */ + r = QHSM_RESERVED_EVT_(s, Q_EMPTY_SIG); // superstate of s } } while (r == Q_RET_SUPER); - /* regular transition taken? */ - /*! @tr{RQP120E} */ - if (r >= Q_RET_TRAN) { + if (r >= Q_RET_TRAN) { // regular tran. taken? QStateHandler path[QHSM_MAX_NEST_DEPTH_]; - path[0] = me->temp.fun; /* save the target of the transition */ - path[1] = t; - path[2] = s; + path[0] = me->temp.fun; // tran. target + path[1] = t; // current state + path[2] = s; // tran. source - /* exit current state to transition source s... */ - /*! @tr{RQP120C} */ + // exit current state to tran. source s... for (; t != s; t = me->temp.fun) { - /* exit from t handled? */ - if (QHsm_state_exit_(me, t, qs_id)) { - /* find superstate of t */ - (void)QHsm_reservedEvt_(me, t, Q_EMPTY_SIG); + // exit from t + if (QHSM_RESERVED_EVT_(t, Q_EXIT_SIG) == Q_RET_HANDLED) { + QS_STATE_EXIT_(t, qs_id); + // find superstate of t + (void)QHSM_RESERVED_EVT_(t, Q_EMPTY_SIG); } } - - int_fast8_t ip = QHsm_tran_(me, path, qs_id); /* the HSM transition */ + int_fast8_t ip = QHsm_tran_(me, path, qs_id); // take the tran. #ifdef Q_SPY if (r == Q_RET_TRAN_HIST) { + QS_CRIT_ENTRY(); + QS_MEM_SYS(); QS_BEGIN_PRE_(QS_QEP_TRAN_HIST, qs_id) - QS_OBJ_PRE_(me); /* this state machine object */ - QS_FUN_PRE_(t); /* the source of the transition */ - QS_FUN_PRE_(path[0]); /* the target of tran. to history */ + QS_OBJ_PRE_(me); // this state machine object + QS_FUN_PRE_(t); // the source of the tran. + QS_FUN_PRE_(path[0]); // the target of the tran. to history QS_END_PRE_() + QS_MEM_APP(); + QS_CRIT_EXIT(); } - #endif /* Q_SPY */ + #endif // Q_SPY - /* execute state entry actions in the desired order... */ - /*! @tr{RQP120B} */ + // execute state entry actions in the desired order... for (; ip >= 0; --ip) { - QHsm_state_entry_(me, path[ip], qs_id); /* enter path[ip] */ + // enter path[ip] + if (QHSM_RESERVED_EVT_(path[ip], Q_ENTRY_SIG) + == Q_RET_HANDLED) + { + QS_STATE_ENTRY_(path[ip], qs_id); + } } + t = path[0]; // stick the target into register + me->temp.fun = t; // update the next state - t = path[0]; /* stick the target into register */ - me->temp.fun = t; /* update the next state */ - - /* while nested initial transition... */ - /*! @tr{RQP120I} */ - while (QHsm_reservedEvt_(me, t, Q_INIT_SIG) == Q_RET_TRAN) { + // drill into the target hierarchy... + while (QHSM_RESERVED_EVT_(t, Q_INIT_SIG) == Q_RET_TRAN) { + QS_CRIT_ENTRY(); + QS_MEM_SYS(); QS_BEGIN_PRE_(QS_QEP_STATE_INIT, qs_id) - QS_OBJ_PRE_(me); /* this state machine object */ - QS_FUN_PRE_(t); /* the source (pseudo)state */ - QS_FUN_PRE_(me->temp.fun); /* the target of the tran. */ + QS_OBJ_PRE_(me); // this state machine object + QS_FUN_PRE_(t); // the source (pseudo)state + QS_FUN_PRE_(me->temp.fun); // the target of the tran. QS_END_PRE_() + QS_MEM_APP(); + QS_CRIT_EXIT(); ip = 0; path[0] = me->temp.fun; - /* find superstate */ - (void)QHsm_reservedEvt_(me, me->temp.fun, Q_EMPTY_SIG); + // find superstate + (void)QHSM_RESERVED_EVT_(me->temp.fun, Q_EMPTY_SIG); while (me->temp.fun != t) { ++ip; path[ip] = me->temp.fun; - /* find superstate */ - (void)QHsm_reservedEvt_(me, me->temp.fun, Q_EMPTY_SIG); + // find superstate + (void)QHSM_RESERVED_EVT_(me->temp.fun, Q_EMPTY_SIG); } me->temp.fun = path[0]; - /* entry path must not overflow */ - Q_ASSERT_ID(410, ip < QHSM_MAX_NEST_DEPTH_); + // entry path must not overflow + QF_CRIT_ENTRY(); + Q_ASSERT_INCRIT(410, ip < QHSM_MAX_NEST_DEPTH_); + QF_CRIT_EXIT(); - /* retrace the entry path in reverse (correct) order... */ + // retrace the entry path in reverse (correct) order... do { - QHsm_state_entry_(me, path[ip], qs_id); /* enter path[ip] */ + // enter path[ip] + if (QHSM_RESERVED_EVT_(path[ip], Q_ENTRY_SIG) + == Q_RET_HANDLED) + { + QS_STATE_ENTRY_(path[ip], qs_id); + } --ip; } while (ip >= 0); - t = path[0]; /* current state becomes the new source */ + t = path[0]; // current state becomes the new source } + QS_CRIT_ENTRY(); + QS_MEM_SYS(); QS_BEGIN_PRE_(QS_QEP_TRAN, qs_id) - QS_TIME_PRE_(); /* time stamp */ - QS_SIG_PRE_(e->sig); /* the signal of the event */ - QS_OBJ_PRE_(me); /* this state machine object */ - QS_FUN_PRE_(s); /* the source of the transition */ - QS_FUN_PRE_(t); /* the new active state */ + QS_TIME_PRE_(); // time stamp + QS_SIG_PRE_(e->sig); // the signal of the event + QS_OBJ_PRE_(me); // this state machine object + QS_FUN_PRE_(s); // the source of the tran. + QS_FUN_PRE_(t); // the new active state QS_END_PRE_() + QS_MEM_APP(); + QS_CRIT_EXIT(); } #ifdef Q_SPY else if (r == Q_RET_HANDLED) { - + QS_CRIT_ENTRY(); + QS_MEM_SYS(); QS_BEGIN_PRE_(QS_QEP_INTERN_TRAN, qs_id) - QS_TIME_PRE_(); /* time stamp */ - QS_SIG_PRE_(e->sig); /* the signal of the event */ - QS_OBJ_PRE_(me); /* this state machine object */ - QS_FUN_PRE_(s); /* the source state */ + QS_TIME_PRE_(); // time stamp + QS_SIG_PRE_(e->sig); // the signal of the event + QS_OBJ_PRE_(me); // this state machine object + QS_FUN_PRE_(s); // the source state QS_END_PRE_() - + QS_MEM_APP(); + QS_CRIT_EXIT(); } else { - + QS_CRIT_ENTRY(); + QS_MEM_SYS(); QS_BEGIN_PRE_(QS_QEP_IGNORED, qs_id) - QS_TIME_PRE_(); /* time stamp */ - QS_SIG_PRE_(e->sig); /* the signal of the event */ - QS_OBJ_PRE_(me); /* this state machine object */ - QS_FUN_PRE_(me->state.fun); /* the current state */ + QS_TIME_PRE_(); // time stamp + QS_SIG_PRE_(e->sig); // the signal of the event + QS_OBJ_PRE_(me); // this state machine object + QS_FUN_PRE_(me->state.fun); // the current state QS_END_PRE_() - + QS_MEM_APP(); + QS_CRIT_EXIT(); } - #endif /* Q_SPY */ + #endif // Q_SPY - me->state.fun = t; /* change the current active state */ - me->temp.fun = t; /* mark the configuration as stable */ + me->state.fun = t; // change the current active state + #ifndef Q_UNSAFE + me->temp.uint = ~me->state.uint; + #endif } -/*${QEP::QHsm::getStateHandler_} ...........................................*/ +//${QEP::QHsm::getStateHandler_} ............................................. #ifdef Q_SPY -QStateHandler QHsm_getStateHandler_(QHsm * const me) { +//! @private @memberof QHsm +QStateHandler QHsm_getStateHandler_(QAsm * const me) { return me->state.fun; } -#endif /* def Q_SPY */ +#endif // def Q_SPY -/*${QEP::QHsm::tran_} ......................................................*/ -int_fast8_t QHsm_tran_(QHsm * const me, +//${QEP::QHsm::isIn} ......................................................... +//! @public @memberof QHsm +bool QHsm_isIn(QHsm * const me, + QStateHandler const state) +{ + QF_CRIT_STAT + QF_CRIT_ENTRY(); + Q_REQUIRE_INCRIT(602, me->super.state.uint + == (uintptr_t)(~me->super.temp.uint)); + QF_CRIT_EXIT(); + + bool inState = false; // assume that this HSM is not in 'state' + + // scan the state hierarchy bottom-up + QState r; + do { + // do the states match? + if (me->super.temp.fun == state) { + inState = true; // 'true' means that match found + r = Q_RET_IGNORED; // cause breaking out of the loop + } + else { + r = QHSM_RESERVED_EVT_(me->super.temp.fun, Q_EMPTY_SIG); + } + } while (r != Q_RET_IGNORED); // QHsm_top() state not reached + + #ifndef Q_UNSAFE + me->super.temp.uint = ~me->super.state.uint; + #endif + + return inState; // return the status +} + +//${QEP::QHsm::childState} ................................................... +//! @public @memberof QHsm +QStateHandler QHsm_childState(QHsm * const me, + QStateHandler const parent) +{ + QStateHandler child = me->super.state.fun; // start with current state + bool isFound = false; // start with the child not found + + // establish stable state configuration + me->super.temp.fun = child; + QState r; + do { + // is this the parent of the current child? + if (me->super.temp.fun == parent) { + isFound = true; // child is found + r = Q_RET_IGNORED; // break out of the loop + } + else { + child = me->super.temp.fun; + r = QHSM_RESERVED_EVT_(me->super.temp.fun, Q_EMPTY_SIG); + } + } while (r != Q_RET_IGNORED); // the top state not reached + + #ifndef Q_UNSAFE + me->super.temp.uint = ~me->super.state.uint; + #endif + + QF_CRIT_STAT + QF_CRIT_ENTRY(); + Q_ASSERT_INCRIT(890, isFound); + QF_CRIT_EXIT(); + + return child; // return the child +} + +//${QEP::QHsm::tran_} ........................................................ +//! @private @memberof QHsm +int_fast8_t QHsm_tran_( + QAsm * const me, QStateHandler * const path, uint_fast8_t const qs_id) { @@ -439,116 +523,128 @@ int_fast8_t QHsm_tran_(QHsm * const me, Q_UNUSED_PAR(qs_id); #endif - int_fast8_t ip = -1; /* transition entry path index */ + int_fast8_t ip = -1; // tran. entry path index QStateHandler t = path[0]; QStateHandler const s = path[2]; + QF_CRIT_STAT - /* (a) check source==target (transition to self)... */ + // (a) check source==target (tran. to self)... if (s == t) { - (void)QHsm_state_exit_(me, s, qs_id); /* exit source */ - ip = 0; /* enter the target */ + // exit source s + if (QHSM_RESERVED_EVT_(s, Q_EXIT_SIG) == Q_RET_HANDLED) { + QS_STATE_EXIT_(s, qs_id); + } + ip = 0; // enter the target } else { - /* find superstate of target */ - (void)QHsm_reservedEvt_(me, t, Q_EMPTY_SIG); + // find superstate of target + (void)QHSM_RESERVED_EVT_(t, Q_EMPTY_SIG); t = me->temp.fun; - /* (b) check source==target->super... */ + // (b) check source==target->super... if (s == t) { - ip = 0; /* enter the target */ + ip = 0; // enter the target } else { - /* find superstate of src */ - (void)QHsm_reservedEvt_(me, s, Q_EMPTY_SIG); + // find superstate of src + (void)QHSM_RESERVED_EVT_(s, Q_EMPTY_SIG); - /* (c) check source->super==target->super... */ + // (c) check source->super==target->super... if (me->temp.fun == t) { - (void)QHsm_state_exit_(me, s, qs_id); /* exit source */ - ip = 0; /* enter the target */ + // exit source s + if (QHSM_RESERVED_EVT_(s, Q_EXIT_SIG) == Q_RET_HANDLED) { + QS_STATE_EXIT_(s, qs_id); + } + ip = 0; // enter the target } else { - /* (d) check source->super==target... */ + // (d) check source->super==target... if (me->temp.fun == path[0]) { - (void)QHsm_state_exit_(me, s, qs_id); /* exit source */ + // exit source s + if (QHSM_RESERVED_EVT_(s, Q_EXIT_SIG) == Q_RET_HANDLED) { + QS_STATE_EXIT_(s, qs_id); + } } else { - /* (e) check rest of source==target->super->super.. - * and store the entry path along the way - */ - int_fast8_t iq = 0; /* indicate that LCA not found */ - ip = 1; /* enter target and its superstate */ - path[1] = t; /* save the superstate of target */ - t = me->temp.fun; /* save source->super */ + // (e) check rest of source==target->super->super.. + // and store the entry path along the way + int_fast8_t iq = 0; // indicate that LCA was found + ip = 1; // enter target and its superstate + path[1] = t; // save the superstate of target + t = me->temp.fun; // save source->super - /* find target->super->super... */ - QState r = QHsm_reservedEvt_(me, path[1], Q_EMPTY_SIG); + // find target->super->super... + QState r = QHSM_RESERVED_EVT_(path[1], Q_EMPTY_SIG); while (r == Q_RET_SUPER) { ++ip; - path[ip] = me->temp.fun; /* store the entry path */ - if (me->temp.fun == s) { /* is it the source? */ - iq = 1; /* indicate that LCA found */ + path[ip] = me->temp.fun; // store the entry path + if (me->temp.fun == s) { // is it the source? + iq = 1; // indicate that the LCA found - /* entry path must not overflow */ - Q_ASSERT_ID(510, - ip < QHSM_MAX_NEST_DEPTH_); - --ip; /* do not enter the source */ - r = Q_RET_HANDLED; /* terminate loop */ + // entry path must not overflow + QF_CRIT_ENTRY(); + Q_ASSERT_INCRIT(510, ip < QHSM_MAX_NEST_DEPTH_); + QF_CRIT_EXIT(); + --ip; // do not enter the source + r = Q_RET_HANDLED; // terminate the loop } - /* it is not the source, keep going up */ - else { - r = QHsm_reservedEvt_(me, me->temp.fun, - Q_EMPTY_SIG); + else { // it is not the source, keep going up + r = QHSM_RESERVED_EVT_(me->temp.fun, Q_EMPTY_SIG); } } - /* the LCA not found yet? */ + // the LCA not found yet? if (iq == 0) { + // entry path must not overflow + QF_CRIT_ENTRY(); + Q_ASSERT_INCRIT(520, ip < QHSM_MAX_NEST_DEPTH_); + QF_CRIT_EXIT(); - /* entry path must not overflow */ - Q_ASSERT_ID(520, ip < QHSM_MAX_NEST_DEPTH_); + // exit source s + if (QHSM_RESERVED_EVT_(s, Q_EXIT_SIG) + == Q_RET_HANDLED) + { + QS_STATE_EXIT_(s, qs_id); + } - /* exit source */ - (void)QHsm_state_exit_(me, s, qs_id); - - /* (f) check the rest of source->super - * == target->super->super... - */ + // (f) check the rest of source->super + // == target->super->super... iq = ip; - r = Q_RET_IGNORED; /* LCA NOT found */ + r = Q_RET_IGNORED; // indicate that the LCA NOT found do { - if (t == path[iq]) { /* is this the LCA? */ - r = Q_RET_HANDLED; /* LCA found */ - ip = iq - 1; /* do not enter LCA */ - iq = -1; /* cause termintion of the loop */ + if (t == path[iq]) { // is this the LCA? + r = Q_RET_HANDLED; // indicate the LCA found + ip = iq - 1; // do not enter the LCA + iq = -1; // cause termination of the loop } else { - --iq; /* try lower superstate of target */ + --iq; // try lower superstate of target } } while (iq >= 0); - /* LCA not found? */ + // the LCA not found yet? if (r != Q_RET_HANDLED) { - /* (g) check each source->super->... - * for each target->super... - */ - r = Q_RET_IGNORED; /* keep looping */ + // (g) check each source->super->... + // for each target->super... + r = Q_RET_IGNORED; // keep looping do { - /* exit from t handled? */ - if (QHsm_state_exit_(me, t, qs_id)) { - /* find superstate of t */ - (void)QHsm_reservedEvt_(me, t, Q_EMPTY_SIG); + // exit from t + if (QHSM_RESERVED_EVT_(t, Q_EXIT_SIG) + == Q_RET_HANDLED) + { + QS_STATE_EXIT_(t, qs_id); + // find superstate of t + (void)QHSM_RESERVED_EVT_(t, Q_EMPTY_SIG); } - t = me->temp.fun; /* set to super of t */ + t = me->temp.fun; // set to super of t iq = ip; do { - /* is this LCA? */ + // is this the LCA? if (t == path[iq]) { - /* do not enter LCA */ - ip = (int_fast8_t)(iq - 1); - iq = -1; /* break out of inner loop */ - /* break out of outer loop */ - r = Q_RET_HANDLED; + ip = iq - 1; // do not enter the LCA + iq = -1; // break out of inner loop + r = Q_RET_HANDLED; // break outer loop } else { --iq; @@ -564,47 +660,13 @@ int_fast8_t QHsm_tran_(QHsm * const me, return ip; } -/*${QEP::QHsm::state_entry_} ...............................................*/ -void QHsm_state_entry_(QHsm * const me, - QStateHandler const state, - uint_fast8_t const qs_id) +//${QEP::QHsm::top} .......................................................... +//! @protected @memberof QAsm +QState QHsm_top(QHsm const * const me, + QEvt const * const e) { - #ifdef Q_SPY - if ((*state)(me, &l_reservedEvt_[Q_ENTRY_SIG]) == Q_RET_HANDLED) { - QS_CRIT_STAT_ - QS_BEGIN_PRE_(QS_QEP_STATE_ENTRY, qs_id) - QS_OBJ_PRE_(me); - QS_FUN_PRE_(state); - QS_END_PRE_() - } - #else - Q_UNUSED_PAR(qs_id); - (void)(*state)(me, &l_reservedEvt_[Q_ENTRY_SIG]); - #endif /* Q_SPY */ + Q_UNUSED_PAR(me); + Q_UNUSED_PAR(e); + return Q_RET_IGNORED; // the top state ignores all events } - -/*${QEP::QHsm::state_exit_} ................................................*/ -bool QHsm_state_exit_(QHsm * const me, - QStateHandler const state, - uint_fast8_t const qs_id) -{ - #ifdef Q_SPY - bool isHandled; - if ((*state)(me, &l_reservedEvt_[Q_EXIT_SIG]) == Q_RET_HANDLED) { - QS_CRIT_STAT_ - QS_BEGIN_PRE_(QS_QEP_STATE_EXIT, qs_id) - QS_OBJ_PRE_(me); - QS_FUN_PRE_(state); - QS_END_PRE_() - isHandled = true; - } - else { - isHandled = false; - } - return isHandled; - #else - Q_UNUSED_PAR(qs_id); - return (*state)(me, &l_reservedEvt_[Q_EXIT_SIG]) == Q_RET_HANDLED; - #endif /* Q_SPY */ -} -/*$enddef${QEP::QHsm} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$enddef${QEP::QHsm} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/src/qf/qep_msm.c b/src/qf/qep_msm.c index 1d948c55..37d2767f 100644 --- a/src/qf/qep_msm.c +++ b/src/qf/qep_msm.c @@ -1,62 +1,62 @@ -/*$file${src::qf::qep_msm.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* -* Model: qpc.qm -* File: ${src::qf::qep_msm.c} -* -* This code has been generated by QM 5.2.4 . -* DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. -* -* This code is covered by the following QP license: -* License # : LicenseRef-QL-dual -* Issued to : Any user of the QP/C real-time embedded framework -* Framework(s) : qpc -* Support ends : 2023-12-31 -* License scope: -* -* Copyright (C) 2005 Quantum Leaps, LLC . -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -*/ -/*$endhead${src::qf::qep_msm.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*! @file -* @brief ::QMsm implementation -*/ -#define QP_IMPL /* this is QP implementation */ -#include "qep_port.h" /* QEP port */ -#include "qassert.h" /* QP embedded systems-friendly assertions */ -#ifdef Q_SPY /* QS software tracing enabled? */ - #include "qs_port.h" /* QS port */ - #include "qs_pkg.h" /* QS facilities for pre-defined trace records */ +//$file${src::qf::qep_msm.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// +// Model: qpc.qm +// File: ${src::qf::qep_msm.c} +// +// This code has been generated by QM 5.3.0 . +// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. +// +// This code is covered by the following QP license: +// License # : LicenseRef-QL-dual +// Issued to : Any user of the QP/C real-time embedded framework +// Framework(s) : qpc +// Support ends : 2024-12-31 +// License scope: +// +// Copyright (C) 2005 Quantum Leaps, LLC . +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +// +//$endhead${src::qf::qep_msm.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +#define QP_IMPL // this is QP implementation +#include "qp_port.h" // QP port +#include "qp_pkg.h" // QP package-scope interface +#include "qsafe.h" // QP Functional Safety (FuSa) Subsystem +#ifdef Q_SPY // QS software tracing enabled? + #include "qs_port.h" // QS port + #include "qs_pkg.h" // QS facilities for pre-defined trace records #else - #include "qs_dummy.h" /* disable the QS software tracing */ -#endif /* Q_SPY */ + #include "qs_dummy.h" // disable the QS software tracing +#endif // Q_SPY + +//============================================================================ +//! @cond INTERNAL Q_DEFINE_THIS_MODULE("qep_msm") -/*==========================================================================*/ -/*! internal QEP constants */ - -/*! maximum depth of entry levels in a MSM for transition to history. */ -#define QMSM_MAX_ENTRY_DEPTH_ 4 - +// top-state object for QMsm-style state machines static struct QMState const l_msm_top_s = { (struct QMState *)0, Q_STATE_CAST(0), @@ -65,63 +65,341 @@ static struct QMState const l_msm_top_s = { Q_ACTION_CAST(0) }; -/*==========================================================================*/ -/*$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* Check for the minimum required QP version */ -#if (QP_VERSION < 700U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) -#error qpc version 7.0.0 or higher required +enum { + // maximum depth of entry levels in a MSM for tran. to history. + QMSM_MAX_ENTRY_DEPTH_ = 4 +}; + +//! @endcond +//============================================================================ + +//$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// Check for the minimum required QP version +#if (QP_VERSION < 730U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) +#error qpc version 7.3.0 or higher required #endif -/*$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -/*$define${QEP::QMsm} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//$define${QEP::QMsm} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/*${QEP::QMsm} .............................................................*/ +//${QEP::QMsm} ............................................................... -/*${QEP::QMsm::isInState} ..................................................*/ -bool QMsm_isInState(QMsm const * const me, - QMState const * const state) +//${QEP::QMsm::ctor} ......................................................... +//! @protected @memberof QMsm +void QMsm_ctor(QMsm * const me, + QStateHandler const initial) { - bool inState = false; /* assume that this MSM is not in 'state' */ + static struct QAsmVtable const vtable = { // QAsm virtual table + &QMsm_init_, + &QMsm_dispatch_ + #ifdef Q_SPY + ,&QMsm_getStateHandler_ + #endif + }; + // do not call the QAsm_ctor() here + me->super.vptr = &vtable; + me->super.state.obj = &l_msm_top_s; // the current state (top) + me->super.temp.fun = initial; // the initial tran. handler +} + +//${QEP::QMsm::init_} ........................................................ +//! @private @memberof QMsm +void QMsm_init_( + QAsm * const me, + void const * const e, + uint_fast8_t const qs_id) +{ + #ifndef Q_SPY + Q_UNUSED_PAR(qs_id); + #endif + + QF_CRIT_STAT + QF_CRIT_ENTRY(); + Q_REQUIRE_INCRIT(200, (me->vptr != (struct QAsmVtable *)0) + && (me->temp.fun != Q_STATE_CAST(0)) + && (me->state.obj == &l_msm_top_s)); + QF_CRIT_EXIT(); + + // execute the top-most initial tran. + QState r = (*me->temp.fun)(me, Q_EVT_CAST(QEvt)); + + QF_CRIT_ENTRY(); + // the top-most initial tran. must be taken + Q_ASSERT_INCRIT(210, r == Q_RET_TRAN_INIT); + + QS_MEM_SYS(); + QS_BEGIN_PRE_(QS_QEP_STATE_INIT, qs_id) + QS_OBJ_PRE_(me); // this state machine object + QS_FUN_PRE_(me->state.obj->stateHandler); // source state + QS_FUN_PRE_(me->temp.tatbl->target->stateHandler); // target state + QS_END_PRE_() + QS_MEM_APP(); + + QF_CRIT_EXIT(); + + // set state to the last tran. target + me->state.obj = me->temp.tatbl->target; + + // drill down into the state hierarchy with initial transitions... + do { + // execute the tran. table + r = QMsm_execTatbl_(me, me->temp.tatbl, qs_id); + } while (r >= Q_RET_TRAN_INIT); + + QS_CRIT_ENTRY(); + QS_MEM_SYS(); + QS_BEGIN_PRE_(QS_QEP_INIT_TRAN, qs_id) + QS_TIME_PRE_(); // time stamp + QS_OBJ_PRE_(me); // this state machine object + QS_FUN_PRE_(me->state.obj->stateHandler); // the new current state + QS_END_PRE_() + QS_MEM_APP(); + QS_CRIT_EXIT(); + + #ifndef Q_UNSAFE + me->temp.uint = ~me->state.uint; + #endif +} + +//${QEP::QMsm::dispatch_} .................................................... +//! @private @memberof QMsm +void QMsm_dispatch_( + QAsm * const me, + QEvt const * const e, + uint_fast8_t const qs_id) +{ + #ifndef Q_SPY + Q_UNUSED_PAR(qs_id); + #endif + + QMState const *s = me->state.obj; // store the current state + QMState const *t = s; + + QF_CRIT_STAT + QF_CRIT_ENTRY(); + Q_REQUIRE_INCRIT(300, (s != (QMState *)0) + && (me->state.uint == (uintptr_t)(~me->temp.uint))); + Q_REQUIRE_INCRIT(302, QEvt_verify_(e)); + + QS_MEM_SYS(); + QS_BEGIN_PRE_(QS_QEP_DISPATCH, qs_id) + QS_TIME_PRE_(); // time stamp + QS_SIG_PRE_(e->sig); // the signal of the event + QS_OBJ_PRE_(me); // this state machine object + QS_FUN_PRE_(s->stateHandler); // the current state handler + QS_END_PRE_() + QS_MEM_APP(); + + QF_CRIT_EXIT(); + + // scan the state hierarchy up to the top state... + QState r; + do { + r = (*t->stateHandler)(me, e); // call state handler function + + // event handled? (the most frequent case) + if (r >= Q_RET_HANDLED) { + break; // done scanning the state hierarchy + } + // event unhandled and passed to the superstate? + else if (r == Q_RET_SUPER) { + t = t->superstate; // advance to the superstate + } + // event unhandled and passed to a submachine superstate? + else if (r == Q_RET_SUPER_SUB) { + t = me->temp.obj; // current host state of the submachie + } + else { // event unhandled due to a guard? + QF_CRIT_ENTRY(); + // event must be unhandled due to a guard evaluating to 'false' + Q_ASSERT_INCRIT(310, r == Q_RET_UNHANDLED); + + QS_MEM_SYS(); + QS_BEGIN_PRE_(QS_QEP_UNHANDLED, qs_id) + QS_SIG_PRE_(e->sig); // the signal of the event + QS_OBJ_PRE_(me); // this state machine object + QS_FUN_PRE_(t->stateHandler); // the current state + QS_END_PRE_() + QS_MEM_APP(); + + QF_CRIT_EXIT(); + + t = t->superstate; // advance to the superstate + } + } while (t != (QMState *)0); + + if (r >= Q_RET_TRAN) { // any kind of tran. taken? + #ifdef Q_SPY + QMState const * const ts = t; // tran. source for QS tracing + + QF_CRIT_ENTRY(); + // the tran. source state must not be NULL + Q_ASSERT_INCRIT(320, ts != (QMState *)0); + QF_CRIT_EXIT(); + #endif // Q_SPY + + do { + // save the tran-action table before it gets clobbered + struct QMTranActTable const * const tatbl = me->temp.tatbl; + union QAsmAttr tmp; // temporary to save intermediate values + + // was TRAN, TRAN_INIT, or TRAN_EP taken? + if (r <= Q_RET_TRAN_EP) { + me->temp.obj = (QMState *)0; // clear + QMsm_exitToTranSource_(me, s, t, qs_id); + r = QMsm_execTatbl_(me, tatbl, qs_id); + s = me->state.obj; + } + // was a tran. segment to history taken? + else if (r == Q_RET_TRAN_HIST) { + tmp.obj = me->state.obj; // save history + me->state.obj = s; // restore the original state + QMsm_exitToTranSource_(me, s, t, qs_id); + (void)QMsm_execTatbl_(me, tatbl, qs_id); + r = QMsm_enterHistory_(me, tmp.obj, qs_id); + s = me->state.obj; + } + else { + QF_CRIT_ENTRY(); + // must be tran. to exit point + Q_ASSERT_INCRIT(340, r == Q_RET_TRAN_XP); + QF_CRIT_EXIT(); + + tmp.act = me->state.act; // save XP action + me->state.obj = s; // restore the original state + r = (*tmp.act)(me); // execute the XP action + if (r == Q_RET_TRAN) { // XP -> TRAN ? + #ifdef Q_SPY + tmp.tatbl = me->temp.tatbl; // save me->temp + #endif // Q_SPY + QMsm_exitToTranSource_(me, s, t, qs_id); + // take the tran-to-XP segment inside submachine + (void)QMsm_execTatbl_(me, tatbl, qs_id); + s = me->state.obj; + #ifdef Q_SPY + me->temp.tatbl = tmp.tatbl; // restore me->temp + #endif // Q_SPY + } + else if (r == Q_RET_TRAN_HIST) { // XP -> HIST ? + tmp.obj = me->state.obj; // save the history + me->state.obj = s; // restore the original state + s = me->temp.obj; // save me->temp + QMsm_exitToTranSource_(me, me->state.obj, t, qs_id); + // take the tran-to-XP segment inside submachine + (void)QMsm_execTatbl_(me, tatbl, qs_id); + #ifdef Q_SPY + me->temp.obj = s; // restore me->temp + #endif // Q_SPY + s = me->state.obj; + me->state.obj = tmp.obj; // restore the history + } + else { + QF_CRIT_ENTRY(); + // TRAN_XP must NOT be followed by any other tran type + Q_ASSERT_INCRIT(330, r < Q_RET_TRAN); + QF_CRIT_EXIT(); + } + } + + t = s; // set target to the current state + + } while (r >= Q_RET_TRAN); + + QS_CRIT_ENTRY(); + QS_MEM_SYS(); + QS_BEGIN_PRE_(QS_QEP_TRAN, qs_id) + QS_TIME_PRE_(); // time stamp + QS_SIG_PRE_(e->sig); // the signal of the event + QS_OBJ_PRE_(me); // this state machine object + QS_FUN_PRE_(ts->stateHandler); // the tran. source + QS_FUN_PRE_(s->stateHandler); // the new active state + QS_END_PRE_() + QS_MEM_APP(); + QS_CRIT_EXIT(); + } + + #ifdef Q_SPY + // was the event handled? + else if (r == Q_RET_HANDLED) { + QF_CRIT_ENTRY(); + // internal tran. source can't be NULL + Q_ASSERT_INCRIT(340, t != (QMState *)0); + + QS_MEM_SYS(); + QS_BEGIN_PRE_(QS_QEP_INTERN_TRAN, qs_id) + QS_TIME_PRE_(); // time stamp + QS_SIG_PRE_(e->sig); // the signal of the event + QS_OBJ_PRE_(me); // this state machine object + QS_FUN_PRE_(t->stateHandler); // the source state + QS_END_PRE_() + QS_MEM_APP(); + + QF_CRIT_EXIT(); + } + // event bubbled to the 'top' state? + else if (t == (QMState *)0) { + QS_CRIT_ENTRY(); + QS_MEM_SYS(); + QS_BEGIN_PRE_(QS_QEP_IGNORED, qs_id) + QS_TIME_PRE_(); // time stamp + QS_SIG_PRE_(e->sig); // the signal of the event + QS_OBJ_PRE_(me); // this state machine object + QS_FUN_PRE_(s->stateHandler); // the current state + QS_END_PRE_() + QS_MEM_APP(); + QS_CRIT_EXIT(); + } + #endif // Q_SPY + else { + // empty + } + + #ifndef Q_UNSAFE + me->temp.uint = ~me->state.uint; + #endif +} + +//${QEP::QMsm::isInState} .................................................... +//! @public @memberof QMsm +bool QMsm_isInState(QMsm const * const me, + QMState const * const stateObj) +{ + bool inState = false; // assume that this SM is not in 'state' for (QMState const *s = me->super.state.obj; s != (QMState *)0; s = s->superstate) { - if (s == state) { - inState = true; /* match found, return 'true' */ + if (s == stateObj) { + inState = true; // match found, return 'true' break; } } return inState; } -/*${QEP::QMsm::stateObj} ...................................................*/ -QMState const * QMsm_stateObj(QHsm const * const me) { - return me->state.obj; -} - -/*${QEP::QMsm::childStateObj} ..............................................*/ -QMState const * QMsm_childStateObj( - QHsm const * const me, +//${QEP::QMsm::childStateObj} ................................................ +//! @public @memberof QMsm +QMState const * QMsm_childStateObj(QMsm const * const me, QMState const * const parent) { - QMState const *child = me->state.obj; - bool isFound = false; /* start with the child not found */ + QMState const *child = me->super.state.obj; + bool isFound = false; // start with the child not found QMState const *s; - for (s = me->state.obj; s != (QMState *)0; s = s->superstate) { + for (s = me->super.state.obj; s != (QMState *)0; s = s->superstate) { if (s == parent) { - isFound = true; /* child is found */ + isFound = true; // child is found break; } else { child = s; } } - if (!isFound) { /* still not found? */ - for (s = me->temp.obj; s != (QMState *)0; s = s->superstate) { + if (!isFound) { // still not found? + for (s = me->super.temp.obj; s != (QMState *)0; s = s->superstate) { if (s == parent) { - isFound = true; /* child is found */ + isFound = true; // child is found break; } else { @@ -130,261 +408,18 @@ QMState const * QMsm_childStateObj( } } - /*! @post the child must be found */ - Q_ENSURE_ID(810, isFound); + QF_CRIT_STAT + QF_CRIT_ENTRY(); + Q_ASSERT_INCRIT(890, isFound); + QF_CRIT_EXIT(); - #ifdef Q_NASSERT - Q_UNUSED_PAR(isFound); - #endif - - return child; /* return the child */ + return child; // return the child } -/*${QEP::QMsm::ctor} .......................................................*/ -void QMsm_ctor(QMsm * const me, - QStateHandler const initial) -{ - static struct QHsmVtable const vtable = { /* QHsm virtual table */ - &QMsm_init_, - &QMsm_dispatch_ - #ifdef Q_SPY - ,&QMsm_getStateHandler_ - #endif - }; - /* do not call the QHsm_ctor() here */ - me->super.vptr = &vtable; - me->super.state.obj = &l_msm_top_s; /* the current state (top) */ - me->super.temp.fun = initial; /* the initial transition handler */ -} - -/*${QEP::QMsm::init_} ......................................................*/ -void QMsm_init_( - QHsm * const me, - void const * const e, - uint_fast8_t const qs_id) -{ - #ifndef Q_SPY - Q_UNUSED_PAR(qs_id); - #endif - - /*! @pre the virtual pointer must be initialized, the top-most initial - * transition must be initialized, and the initial transition must not - * be taken yet. - */ - Q_REQUIRE_ID(200, (me->vptr != (struct QHsmVtable *)0) - && (me->temp.fun != Q_STATE_CAST(0)) - && (me->state.obj == &l_msm_top_s)); - - /* execute the top-most initial tran. */ - QState r = (*me->temp.fun)(me, Q_EVT_CAST(QEvt)); - - /* the top-most initial transition must be taken */ - Q_ASSERT_ID(210, r == Q_RET_TRAN_INIT); - - QS_CRIT_STAT_ - QS_BEGIN_PRE_(QS_QEP_STATE_INIT, qs_id) - QS_OBJ_PRE_(me); /* this state machine object */ - QS_FUN_PRE_(me->state.obj->stateHandler); /* source state */ - QS_FUN_PRE_(me->temp.tatbl->target->stateHandler); /* target state */ - QS_END_PRE_() - - /* set state to the last tran. target */ - me->state.obj = me->temp.tatbl->target; - - /* drill down into the state hierarchy with initial transitions... */ - /* execute the tran. table */ - do { - r = QMsm_execTatbl_(me, me->temp.tatbl, qs_id); - } while (r >= Q_RET_TRAN_INIT); - - QS_BEGIN_PRE_(QS_QEP_INIT_TRAN, qs_id) - QS_TIME_PRE_(); /* time stamp */ - QS_OBJ_PRE_(me); /* this state machine object */ - QS_FUN_PRE_(me->state.obj->stateHandler); /* the new current state */ - QS_END_PRE_() -} - -/*${QEP::QMsm::dispatch_} ..................................................*/ -void QMsm_dispatch_( - QHsm * const me, - QEvt const * const e, - uint_fast8_t const qs_id) -{ - #ifndef Q_SPY - Q_UNUSED_PAR(qs_id); - #endif - - QMState const *s = me->state.obj; /* store the current state */ - QMState const *t = s; - - /*! @pre current state must be initialized */ - Q_REQUIRE_ID(300, s != (QMState *)0); - - QS_CRIT_STAT_ - QS_BEGIN_PRE_(QS_QEP_DISPATCH, qs_id) - QS_TIME_PRE_(); /* time stamp */ - QS_SIG_PRE_(e->sig); /* the signal of the event */ - QS_OBJ_PRE_(me); /* this state machine object */ - QS_FUN_PRE_(s->stateHandler); /* the current state handler */ - QS_END_PRE_() - - /* scan the state hierarchy up to the top state... */ - QState r; - do { - r = (*t->stateHandler)(me, e); /* call state handler function */ - - /* event handled? (the most frequent case) */ - if (r >= Q_RET_HANDLED) { - break; /* done scanning the state hierarchy */ - } - /* event unhandled and passed to the superstate? */ - else if (r == Q_RET_SUPER) { - t = t->superstate; /* advance to the superstate */ - } - /* event unhandled and passed to a submachine superstate? */ - else if (r == Q_RET_SUPER_SUB) { - t = me->temp.obj; /* current host state of the submachie */ - } - /* event unhandled due to a guard? */ - else if (r == Q_RET_UNHANDLED) { - - QS_BEGIN_PRE_(QS_QEP_UNHANDLED, qs_id) - QS_SIG_PRE_(e->sig); /* the signal of the event */ - QS_OBJ_PRE_(me); /* this state machine object */ - QS_FUN_PRE_(t->stateHandler); /* the current state */ - QS_END_PRE_() - - t = t->superstate; /* advance to the superstate */ - } - else { - /* no other return value should be produced */ - Q_ERROR_ID(310); - } - } while (t != (QMState *)0); - - - /* any kind of transition taken? */ - if (r >= Q_RET_TRAN) { - #ifdef Q_SPY - QMState const * const ts = t; /* transition source for QS tracing */ - - /* the transition source state must not be NULL */ - Q_ASSERT_ID(320, ts != (QMState *)0); - #endif /* Q_SPY */ - - do { - /* save the transition-action table before it gets clobbered */ - struct QMTranActTable const * const tatbl = me->temp.tatbl; - union QHsmAttr tmp; /* temporary to save intermediate values */ - - /* was TRAN, TRAN_INIT, or TRAN_EP taken? */ - if (r <= Q_RET_TRAN_EP) { - me->temp.obj = (QMState *)0; /* clear */ - QMsm_exitToTranSource_(me, s, t, qs_id); - r = QMsm_execTatbl_(me, tatbl, qs_id); - s = me->state.obj; - } - /* was a transition segment to history taken? */ - else if (r == Q_RET_TRAN_HIST) { - tmp.obj = me->state.obj; /* save history */ - me->state.obj = s; /* restore the original state */ - QMsm_exitToTranSource_(me, s, t, qs_id); - (void)QMsm_execTatbl_(me, tatbl, qs_id); - r = QMsm_enterHistory_(me, tmp.obj, qs_id); - s = me->state.obj; - } - /* was a transition segment to an exit point taken? */ - else if (r == Q_RET_TRAN_XP) { - tmp.act = me->state.act; /* save XP action */ - me->state.obj = s; /* restore the original state */ - r = (*tmp.act)(me); /* execute the XP action */ - if (r == Q_RET_TRAN) { /* XP -> TRAN ? */ - tmp.tatbl = me->temp.tatbl; /* save me->temp */ - QMsm_exitToTranSource_(me, s, t, qs_id); - /* take the tran-to-XP segment inside submachine */ - (void)QMsm_execTatbl_(me, tatbl, qs_id); - s = me->state.obj; - #ifdef Q_SPY - me->temp.tatbl = tmp.tatbl; /* restore me->temp */ - #endif /* Q_SPY */ - } - else if (r == Q_RET_TRAN_HIST) { /* XP -> HIST ? */ - tmp.obj = me->state.obj; /* save the history */ - me->state.obj = s; /* restore the original state */ - s = me->temp.obj; /* save me->temp */ - QMsm_exitToTranSource_(me, me->state.obj, t, qs_id); - /* take the tran-to-XP segment inside submachine */ - (void)QMsm_execTatbl_(me, tatbl, qs_id); - #ifdef Q_SPY - me->temp.obj = s; /* restore me->temp */ - #endif /* Q_SPY */ - s = me->state.obj; - me->state.obj = tmp.obj; /* restore the history */ - } - else { - /* TRAN_XP must NOT be followed by any other tran type */ - Q_ASSERT_ID(330, r < Q_RET_TRAN); - } - } - else { - /* no other return value should be produced */ - Q_ERROR_ID(340); - } - - t = s; /* set target to the current state */ - - } while (r >= Q_RET_TRAN); - - QS_BEGIN_PRE_(QS_QEP_TRAN, qs_id) - QS_TIME_PRE_(); /* time stamp */ - QS_SIG_PRE_(e->sig); /* the signal of the event */ - QS_OBJ_PRE_(me); /* this state machine object */ - QS_FUN_PRE_(ts->stateHandler); /* the transition source */ - QS_FUN_PRE_(s->stateHandler); /* the new active state */ - QS_END_PRE_() - } - - #ifdef Q_SPY - /* was the event handled? */ - else if (r == Q_RET_HANDLED) { - /* internal tran. source can't be NULL */ - Q_ASSERT_ID(340, t != (QMState *)0); - - QS_BEGIN_PRE_(QS_QEP_INTERN_TRAN, qs_id) - QS_TIME_PRE_(); /* time stamp */ - QS_SIG_PRE_(e->sig); /* the signal of the event */ - QS_OBJ_PRE_(me); /* this state machine object */ - QS_FUN_PRE_(t->stateHandler); /* the source state */ - QS_END_PRE_() - - } - /* event bubbled to the 'top' state? */ - else if (t == (QMState *)0) { - - QS_BEGIN_PRE_(QS_QEP_IGNORED, qs_id) - QS_TIME_PRE_(); /* time stamp */ - QS_SIG_PRE_(e->sig); /* the signal of the event */ - QS_OBJ_PRE_(me); /* this state machine object */ - QS_FUN_PRE_(s->stateHandler); /* the current state */ - QS_END_PRE_() - - } - #endif /* Q_SPY */ - else { - /* empty */ - } -} - -/*${QEP::QMsm::getStateHandler_} ...........................................*/ -#ifdef Q_SPY -QStateHandler QMsm_getStateHandler_(QHsm * const me) { - return me->state.obj->stateHandler; -} -#endif /* def Q_SPY */ - -/*${QEP::QMsm::execTatbl_} .................................................*/ +//${QEP::QMsm::execTatbl_} ................................................... +//! @private @memberof QMsm QState QMsm_execTatbl_( - QHsm * const me, + QAsm * const me, QMTranActTable const * const tatbl, uint_fast8_t const qs_id) { @@ -392,60 +427,61 @@ QState QMsm_execTatbl_( Q_UNUSED_PAR(qs_id); #endif + QF_CRIT_STAT + QF_CRIT_ENTRY(); + // precondition: + // - the tran-action table pointer must not be NULL + Q_REQUIRE_INCRIT(400, tatbl != (struct QMTranActTable *)0); + QF_CRIT_EXIT(); + QState r = Q_RET_NULL; - QS_CRIT_STAT_ - - /*! @pre the transition-action table pointer must not be NULL */ - Q_REQUIRE_ID(400, tatbl != (struct QMTranActTable *)0); - for (QActionHandler const *a = &tatbl->act[0]; *a != Q_ACTION_CAST(0); ++a) { - r = (*(*a))(me); /* call the action through the 'a' pointer */ + r = (*(*a))(me); // call the action through the 'a' pointer #ifdef Q_SPY + QS_CRIT_ENTRY(); + QS_MEM_SYS(); if (r == Q_RET_ENTRY) { - QS_BEGIN_PRE_(QS_QEP_STATE_ENTRY, qs_id) - QS_OBJ_PRE_(me); /* this state machine object */ - QS_FUN_PRE_(me->temp.obj->stateHandler);/*entered state */ + QS_OBJ_PRE_(me); // this state machine object + QS_FUN_PRE_(me->temp.obj->stateHandler); // entered state QS_END_PRE_() } else if (r == Q_RET_EXIT) { - QS_BEGIN_PRE_(QS_QEP_STATE_EXIT, qs_id) - QS_OBJ_PRE_(me); /* this state machine object */ - QS_FUN_PRE_(me->temp.obj->stateHandler); /* exited state */ + QS_OBJ_PRE_(me); // this state machine object + QS_FUN_PRE_(me->temp.obj->stateHandler); // exited state QS_END_PRE_() } else if (r == Q_RET_TRAN_INIT) { - QS_BEGIN_PRE_(QS_QEP_STATE_INIT, qs_id) - QS_OBJ_PRE_(me); /* this state machine object */ - QS_FUN_PRE_(tatbl->target->stateHandler); /* source */ - QS_FUN_PRE_(me->temp.tatbl->target->stateHandler);/* target */ + QS_OBJ_PRE_(me); // this state machine object + QS_FUN_PRE_(tatbl->target->stateHandler); // source + QS_FUN_PRE_(me->temp.tatbl->target->stateHandler); // target QS_END_PRE_() } else if (r == Q_RET_TRAN_EP) { - QS_BEGIN_PRE_(QS_QEP_TRAN_EP, qs_id) - QS_OBJ_PRE_(me); /* this state machine object */ - QS_FUN_PRE_(tatbl->target->stateHandler); /* source */ - QS_FUN_PRE_(me->temp.tatbl->target->stateHandler);/* target */ + QS_OBJ_PRE_(me); // this state machine object + QS_FUN_PRE_(tatbl->target->stateHandler); // source + QS_FUN_PRE_(me->temp.tatbl->target->stateHandler); // target QS_END_PRE_() } else if (r == Q_RET_TRAN_XP) { - QS_BEGIN_PRE_(QS_QEP_TRAN_XP, qs_id) - QS_OBJ_PRE_(me); /* this state machine object */ - QS_FUN_PRE_(tatbl->target->stateHandler); /* source */ - QS_FUN_PRE_(me->temp.tatbl->target->stateHandler);/* target */ + QS_OBJ_PRE_(me); // this state machine object + QS_FUN_PRE_(tatbl->target->stateHandler); // source + QS_FUN_PRE_(me->temp.tatbl->target->stateHandler); // target QS_END_PRE_() } else { - /* empty */ + // empty } - #endif /* Q_SPY */ + QS_MEM_APP(); + QS_CRIT_EXIT(); + #endif // Q_SPY } me->state.obj = (r >= Q_RET_TRAN) @@ -454,9 +490,10 @@ QState QMsm_execTatbl_( return r; } -/*${QEP::QMsm::exitToTranSource_} ..........................................*/ +//${QEP::QMsm::exitToTranSource_} ............................................ +//! @private @memberof QMsm void QMsm_exitToTranSource_( - QHsm * const me, + QAsm * const me, QMState const * const cs, QMState const * const ts, uint_fast8_t const qs_id) @@ -465,33 +502,41 @@ void QMsm_exitToTranSource_( Q_UNUSED_PAR(qs_id); #endif - /* exit states from the current state to the tran. source state */ + QF_CRIT_STAT + + // exit states from the current state to the tran. source state QMState const *s = cs; while (s != ts) { - /* exit action provided in state 's'? */ + // exit action provided in state 's'? if (s->exitAction != Q_ACTION_CAST(0)) { - QS_CRIT_STAT_ - - (void)(*s->exitAction)(me); /* execute the exit action */ + // execute the exit action + (void)(*s->exitAction)(me); + QS_CRIT_ENTRY(); + QS_MEM_SYS(); QS_BEGIN_PRE_(QS_QEP_STATE_EXIT, qs_id) - QS_OBJ_PRE_(me); /* this state machine object */ - QS_FUN_PRE_(s->stateHandler); /* the exited state handler */ + QS_OBJ_PRE_(me); // this state machine object + QS_FUN_PRE_(s->stateHandler); // the exited state handler QS_END_PRE_() + QS_MEM_APP(); + QS_CRIT_EXIT(); } - s = s->superstate; /* advance to the superstate */ + s = s->superstate; // advance to the superstate - if (s == (QMState *)0) { /* reached the top of a submachine? */ - s = me->temp.obj; /* the superstate from QM_SM_EXIT() */ - Q_ASSERT_ID(510, s != (QMState *)0); /* must be valid */ + if (s == (QMState *)0) { // reached the top of a submachine? + s = me->temp.obj; // the superstate from QM_SM_EXIT() + QF_CRIT_ENTRY(); + Q_ASSERT_INCRIT(510, s != (QMState *)0); // must be valid + QF_CRIT_EXIT(); } } } -/*${QEP::QMsm::enterHistory_} ..............................................*/ +//${QEP::QMsm::enterHistory_} ................................................ +//! @private @memberof QMsm QState QMsm_enterHistory_( - QHsm * const me, + QAsm * const me, QMState const *const hist, uint_fast8_t const qs_id) { @@ -500,50 +545,62 @@ QState QMsm_enterHistory_( #endif QMState const *s = hist; - QMState const *ts = me->state.obj; /* transition source */ + QMState const *ts = me->state.obj; // tran. source QMState const *epath[QMSM_MAX_ENTRY_DEPTH_]; - QS_CRIT_STAT_ + QF_CRIT_STAT + + QS_CRIT_ENTRY(); + QS_MEM_SYS(); QS_BEGIN_PRE_(QS_QEP_TRAN_HIST, qs_id) - QS_OBJ_PRE_(me); /* this state machine object */ - QS_FUN_PRE_(ts->stateHandler); /* source state handler */ - QS_FUN_PRE_(hist->stateHandler); /* target state handler */ + QS_OBJ_PRE_(me); // this state machine object + QS_FUN_PRE_(ts->stateHandler); // source state handler + QS_FUN_PRE_(hist->stateHandler); // target state handler QS_END_PRE_() + QS_MEM_APP(); + QS_CRIT_EXIT(); - int_fast8_t i = 0; /* transition entry path index */ + int_fast8_t i = 0; // tran. entry path index while (s != ts) { if (s->entryAction != Q_ACTION_CAST(0)) { - Q_ASSERT_ID(620, i < QMSM_MAX_ENTRY_DEPTH_); + QF_CRIT_ENTRY(); + Q_ASSERT_INCRIT(620, i < QMSM_MAX_ENTRY_DEPTH_); + QF_CRIT_EXIT(); epath[i] = s; ++i; } s = s->superstate; if (s == (QMState *)0) { - ts = s; /* force exit from the for-loop */ + ts = s; // force exit from the for-loop } } - /* retrace the entry path in reverse (desired) order... */ + // retrace the entry path in reverse (desired) order... while (i > 0) { --i; - (void)(*epath[i]->entryAction)(me); /* run entry action in epath[i] */ + (void)(*epath[i]->entryAction)(me); // run entry action in epath[i] + QS_CRIT_ENTRY(); + QS_MEM_SYS(); QS_BEGIN_PRE_(QS_QEP_STATE_ENTRY, qs_id) QS_OBJ_PRE_(me); - QS_FUN_PRE_(epath[i]->stateHandler); /* entered state handler */ + QS_FUN_PRE_(epath[i]->stateHandler); // entered state handler QS_END_PRE_() + QS_MEM_APP(); + QS_CRIT_EXIT(); } - me->state.obj = hist; /* set current state to the transition target */ + me->state.obj = hist; // set current state to the tran. target - /* initial tran. present? */ + // initial tran. present? QState r; if (hist->initAction != Q_ACTION_CAST(0)) { - r = (*hist->initAction)(me); /* execute the transition action */ + r = (*hist->initAction)(me); // execute the tran. action } else { r = Q_RET_NULL; } + return r; } -/*$enddef${QEP::QMsm} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$enddef${QEP::QMsm} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/src/qf/qf_act.c b/src/qf/qf_act.c index b064c9bc..ce8def49 100644 --- a/src/qf/qf_act.c +++ b/src/qf/qf_act.c @@ -1,45 +1,121 @@ -/*$file${src::qf::qf_act.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* -* Model: qpc.qm -* File: ${src::qf::qf_act.c} -* -* This code has been generated by QM 5.2.4 . -* DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. -* -* This code is covered by the following QP license: -* License # : LicenseRef-QL-dual -* Issued to : Any user of the QP/C real-time embedded framework -* Framework(s) : qpc -* Support ends : 2023-12-31 -* License scope: -* -* Copyright (C) 2005 Quantum Leaps, LLC . -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -*/ -/*$endhead${src::qf::qf_act.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*! @file -* @deprecated -* Empty file kept only for backwards compatibility. -* @sa qf_qact.c -*/ -extern char const dummy; /* declaration */ -char const dummy = '\0'; /* definition */ +//$file${src::qf::qf_act.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// +// Model: qpc.qm +// File: ${src::qf::qf_act.c} +// +// This code has been generated by QM 5.3.0 . +// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. +// +// This code is covered by the following QP license: +// License # : LicenseRef-QL-dual +// Issued to : Any user of the QP/C real-time embedded framework +// Framework(s) : qpc +// Support ends : 2024-12-31 +// License scope: +// +// Copyright (C) 2005 Quantum Leaps, LLC . +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +// +//$endhead${src::qf::qf_act.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +#define QP_IMPL // this is QP implementation +#include "qp_port.h" // QP port +#include "qp_pkg.h" // QP package-scope interface +#include "qsafe.h" // QP Functional Safety (FuSa) Subsystem +#ifdef Q_SPY // QS software tracing enabled? + #include "qs_port.h" // QS port + #include "qs_pkg.h" // QS facilities for pre-defined trace records +#else + #include "qs_dummy.h" // disable the QS software tracing +#endif // Q_SPY + +//Q_DEFINE_THIS_MODULE("qf_act") + +//$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// Check for the minimum required QP version +#if (QP_VERSION < 730U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) +#error qpc version 7.3.0 or higher required +#endif +//$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +//$define${QF::QActive::registry_[QF_MAX_ACTIVE + 1U]} vvvvvvvvvvvvvvvvvvvvvvv +QActive * QActive_registry_[QF_MAX_ACTIVE + 1U]; +//$enddef${QF::QActive::registry_[QF_MAX_ACTIVE + 1U]} ^^^^^^^^^^^^^^^^^^^^^^^ + +//$define${QF::QF-pkg} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${QF::QF-pkg::priv_} ....................................................... +QF_Attr QF_priv_; + +//${QF::QF-pkg::bzero_} ...................................................... +//! @static @private @memberof QF +void QF_bzero_( + void * const start, + uint_fast16_t const len) +{ + uint8_t *ptr = (uint8_t *)start; + for (uint_fast16_t n = len; n > 0U; --n) { + *ptr = 0U; + ++ptr; + } +} +//$enddef${QF::QF-pkg} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +//$define${QF::types::QF_LOG2} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${QF::types::QF_LOG2} ...................................................... +#ifndef QF_LOG2 +uint_fast8_t QF_LOG2(QPSetBits const bitmask) { + static uint8_t const log2LUT[16] = { + 0U, 1U, 2U, 2U, 3U, 3U, 3U, 3U, + 4U, 4U, 4U, 4U, 4U, 4U, 4U, 4U + }; + uint_fast8_t n = 0U; + QPSetBits tmp; + QPSetBits x = bitmask; + + #if (QF_MAX_ACTIVE > 16U) + tmp = (x >> 16U); + if (tmp != 0U) { + n += 16U; + x = tmp; + } + #endif + #if (QF_MAX_ACTIVE > 8U) + tmp = (x >> 8U); + if (tmp != 0U) { + n += 8U; + x = tmp; + } + #endif + tmp = (x >> 4U); + if (tmp != 0U) { + n += 4U; + x = tmp; + } + return n + log2LUT[x]; +} +#endif // ndef QF_LOG2 +//$enddef${QF::types::QF_LOG2} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/src/qf/qf_actq.c b/src/qf/qf_actq.c index 95fd1660..ce4b92a3 100644 --- a/src/qf/qf_actq.c +++ b/src/qf/qf_actq.c @@ -1,72 +1,70 @@ -/*$file${src::qf::qf_actq.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* -* Model: qpc.qm -* File: ${src::qf::qf_actq.c} -* -* This code has been generated by QM 5.2.4 . -* DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. -* -* This code is covered by the following QP license: -* License # : LicenseRef-QL-dual -* Issued to : Any user of the QP/C real-time embedded framework -* Framework(s) : qpc -* Support ends : 2023-12-31 -* License scope: -* -* Copyright (C) 2005 Quantum Leaps, LLC . -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -*/ -/*$endhead${src::qf::qf_actq.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*! @file -* @brief ::QActive native queue operations (based on ::QEQueue) -* -* @note -* this source file is only included in the application build when the native -* QF active object queue is used (instead of a message queue of an RTOS). -*/ -#define QP_IMPL /* this is QP implementation */ -#include "qf_port.h" /* QF port */ -#include "qf_pkg.h" /* QF package-scope interface */ -#include "qassert.h" /* QP embedded systems-friendly assertions */ -#ifdef Q_SPY /* QS software tracing enabled? */ - #include "qs_port.h" /* QS port */ - #include "qs_pkg.h" /* QS facilities for pre-defined trace records */ +//$file${src::qf::qf_actq.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// +// Model: qpc.qm +// File: ${src::qf::qf_actq.c} +// +// This code has been generated by QM 5.3.0 . +// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. +// +// This code is covered by the following QP license: +// License # : LicenseRef-QL-dual +// Issued to : Any user of the QP/C real-time embedded framework +// Framework(s) : qpc +// Support ends : 2024-12-31 +// License scope: +// +// Copyright (C) 2005 Quantum Leaps, LLC . +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +// +//$endhead${src::qf::qf_actq.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +#define QP_IMPL // this is QP implementation +#include "qp_port.h" // QP port +#include "qp_pkg.h" // QP package-scope interface +#include "qsafe.h" // QP Functional Safety (FuSa) Subsystem +#ifdef Q_SPY // QS software tracing enabled? + #include "qs_port.h" // QS port + #include "qs_pkg.h" // QS facilities for pre-defined trace records #else - #include "qs_dummy.h" /* disable the QS software tracing */ -#endif /* Q_SPY */ + #include "qs_dummy.h" // disable the QS software tracing +#endif // Q_SPY Q_DEFINE_THIS_MODULE("qf_actq") -/*==========================================================================*/ -/*$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* Check for the minimum required QP version */ -#if (QP_VERSION < 700U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) -#error qpc version 7.0.0 or higher required +//============================================================================ +//$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// Check for the minimum required QP version +#if (QP_VERSION < 730U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) +#error qpc version 7.3.0 or higher required #endif -/*$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -/*$define${QF::QActive::post_} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//$define${QF::QActive::post_} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/*${QF::QActive::post_} ....................................................*/ +//${QF::QActive::post_} ...................................................... +//! @private @memberof QActive bool QActive_post_(QActive * const me, QEvt const * const e, uint_fast16_t const margin, @@ -76,14 +74,23 @@ bool QActive_post_(QActive * const me, Q_UNUSED_PAR(sender); #endif - /*! @pre event pointer must be valid */ - Q_REQUIRE_ID(100, e != (QEvt *)0); + #ifdef Q_UTEST // test? + #if Q_UTEST != 0 // testing QP-stub? + if (me->super.temp.fun == Q_STATE_CAST(0)) { // QActiveDummy? + return QActiveDummy_fakePost_(me, e, margin, sender); + } + #endif + #endif - QF_CRIT_STAT_ - QF_CRIT_E_(); - QEQueueCtr nFree = me->eQueue.nFree; /* get volatile into the temporary */ + QF_CRIT_STAT + QF_CRIT_ENTRY(); + QF_MEM_SYS(); - /* test-probe#1 for faking queue overflow */ + Q_REQUIRE_INCRIT(102, QEvt_verify_(e)); + + QEQueueCtr nFree = me->eQueue.nFree; // get volatile into temporary + + // test-probe#1 for faking queue overflow QS_TEST_PROBE_DEF(&QActive_post_) QS_TEST_PROBE_ID(1, nFree = 0U; @@ -92,279 +99,292 @@ bool QActive_post_(QActive * const me, bool status; if (margin == QF_NO_MARGIN) { if (nFree > 0U) { - status = true; /* can post */ + status = true; // can post } else { - status = false; /* cannot post */ - Q_ERROR_CRIT_(110); /* must be able to post the event */ + status = false; // cannot post + Q_ERROR_INCRIT(190); // must be able to post the event } } else if (nFree > (QEQueueCtr)margin) { - status = true; /* can post */ + status = true; // can post } else { - status = false; /* cannot post, but don't assert */ + status = false; // cannot post, but don't assert } - /* is it a dynamic event? */ - if (e->poolId_ != 0U) { - QEvt_refCtr_inc_(e); /* increment the reference counter */ + // is it a mutable event? + if (QEvt_getPoolId_(e) != 0U) { + QEvt_refCtr_inc_(e); // increment the reference counter } - if (status) { /* can post the event? */ + if (status) { // can post the event? - --nFree; /* one free entry just used up */ - me->eQueue.nFree = nFree; /* update the volatile */ + --nFree; // one free entry just used up + me->eQueue.nFree = nFree; // update the original if (me->eQueue.nMin > nFree) { - me->eQueue.nMin = nFree; /* increase minimum so far */ + me->eQueue.nMin = nFree; // increase minimum so far } - QS_BEGIN_NOCRIT_PRE_(QS_QF_ACTIVE_POST, me->prio) - QS_TIME_PRE_(); /* timestamp */ - QS_OBJ_PRE_(sender); /* the sender object */ - QS_SIG_PRE_(e->sig); /* the signal of the event */ - QS_OBJ_PRE_(me); /* this active object (recipient) */ - QS_2U8_PRE_(e->poolId_, e->refCtr_); /* pool Id & ref Count */ - QS_EQC_PRE_(nFree); /* number of free entries */ - QS_EQC_PRE_(me->eQueue.nMin); /* min number of free entries */ - QS_END_NOCRIT_PRE_() + QS_BEGIN_PRE_(QS_QF_ACTIVE_POST, me->prio) + QS_TIME_PRE_(); // timestamp + QS_OBJ_PRE_(sender); // the sender object + QS_SIG_PRE_(e->sig); // the signal of the event + QS_OBJ_PRE_(me); // this active object (recipient) + QS_2U8_PRE_(QEvt_getPoolId_(e), e->refCtr_); // poolId & refCtr + QS_EQC_PRE_(nFree); // # free entries + QS_EQC_PRE_(me->eQueue.nMin); // min # free entries + QS_END_PRE_() #ifdef Q_UTEST - /* callback to examine the posted event under the same conditions - * as producing the #QS_QF_ACTIVE_POST trace record, which are: - * the local filter for this AO ('me->prio') is set - */ + // callback to examine the posted event under the same conditions + // as producing the #QS_QF_ACTIVE_POST trace record, which are: + // the local filter for this AO ('me->prio') is set if (QS_LOC_CHECK_(me->prio)) { - /* callback to examine the posted event */ QS_onTestPost(sender, me, e, status); } #endif - /* empty queue? */ - if (me->eQueue.frontEvt == (QEvt *)0) { - me->eQueue.frontEvt = e; /* deliver event directly */ - QACTIVE_EQUEUE_SIGNAL_(me); /* signal the event queue */ + if (me->eQueue.frontEvt == (QEvt *)0) { // empty queue? + me->eQueue.frontEvt = e; // deliver event directly + + #ifdef QXK_H_ + if (me->super.state.act == Q_ACTION_CAST(0)) { // eXtended? + QXTHREAD_EQUEUE_SIGNAL_(me); // signal the event queue + } + else { + QACTIVE_EQUEUE_SIGNAL_(me); // signal the event queue + } + #else + QACTIVE_EQUEUE_SIGNAL_(me); // signal the event queue + #endif } - /* queue is not empty, insert event into the ring-buffer */ + // queue is not empty, insert event into the ring-buffer else { - /* insert event into the ring buffer (FIFO) */ + // insert event into the ring buffer (FIFO) me->eQueue.ring[me->eQueue.head] = e; - if (me->eQueue.head == 0U) { /* need to wrap head? */ - me->eQueue.head = me->eQueue.end; /* wrap around */ + if (me->eQueue.head == 0U) { // need to wrap head? + me->eQueue.head = me->eQueue.end; // wrap around } - --me->eQueue.head; /* advance the head (counter clockwise) */ + --me->eQueue.head; // advance the head (counter clockwise) } - QF_CRIT_X_(); + QF_MEM_APP(); + QF_CRIT_EXIT(); } - else { /* cannot post the event */ + else { // cannot post the event - QS_BEGIN_NOCRIT_PRE_(QS_QF_ACTIVE_POST_ATTEMPT, me->prio) - QS_TIME_PRE_(); /* timestamp */ - QS_OBJ_PRE_(sender); /* the sender object */ - QS_SIG_PRE_(e->sig); /* the signal of the event */ - QS_OBJ_PRE_(me); /* this active object (recipient) */ - QS_2U8_PRE_(e->poolId_, e->refCtr_); /* pool Id & ref Count */ - QS_EQC_PRE_(nFree); /* number of free entries */ - QS_EQC_PRE_(margin); /* margin requested */ - QS_END_NOCRIT_PRE_() + QS_BEGIN_PRE_(QS_QF_ACTIVE_POST_ATTEMPT, me->prio) + QS_TIME_PRE_(); // timestamp + QS_OBJ_PRE_(sender); // the sender object + QS_SIG_PRE_(e->sig); // the signal of the event + QS_OBJ_PRE_(me); // this active object (recipient) + QS_2U8_PRE_(QEvt_getPoolId_(e), e->refCtr_); // poolId & refCtr + QS_EQC_PRE_(nFree); // # free entries + QS_EQC_PRE_(margin); // margin requested + QS_END_PRE_() #ifdef Q_UTEST - /* callback to examine the posted event under the same conditions - * as producing the #QS_QF_ACTIVE_POST trace record, which are: - * the local filter for this AO ('me->prio') is set - */ + // callback to examine the posted event under the same conditions + // as producing the #QS_QF_ACTIVE_POST trace record, which are: + // the local filter for this AO ('me->prio') is set if (QS_LOC_CHECK_(me->prio)) { QS_onTestPost(sender, me, e, status); } #endif - QF_CRIT_X_(); + QF_MEM_APP(); + QF_CRIT_EXIT(); #if (QF_MAX_EPOOL > 0U) - QF_gc(e); /* recycle the event to avoid a leak */ + QF_gc(e); // recycle the event to avoid a leak #endif } return status; } -/*$enddef${QF::QActive::post_} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*$define${QF::QActive::postLIFO_} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//$enddef${QF::QActive::post_} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +//$define${QF::QActive::postLIFO_} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/*${QF::QActive::postLIFO_} ................................................*/ +//${QF::QActive::postLIFO_} .................................................. +//! @private @memberof QActive void QActive_postLIFO_(QActive * const me, QEvt const * const e) { - QF_CRIT_STAT_ - QF_CRIT_E_(); - QEQueueCtr nFree = me->eQueue.nFree; /* get volatile into the temporary */ + #ifdef Q_UTEST // test? + #if Q_UTEST != 0 // testing QP-stub? + if (me->super.temp.fun == Q_STATE_CAST(0)) { // QActiveDummy? + QActiveDummy_fakePostLIFO_(me, e); + return; + } + #endif + #endif - /* test-probe#1 for faking queue overflow */ + QF_CRIT_STAT + QF_CRIT_ENTRY(); + QF_MEM_SYS(); + + Q_REQUIRE_INCRIT(202, QEvt_verify_(e)); + + #ifdef QXK_H_ + Q_REQUIRE_INCRIT(200, me->super.state.act != Q_ACTION_CAST(0)); + #endif + + QEQueueCtr nFree = me->eQueue.nFree; // get volatile into temporary + + // test-probe#1 for faking queue overflow QS_TEST_PROBE_DEF(&QActive_postLIFO_) QS_TEST_PROBE_ID(1, nFree = 0U; ) - /* the queue must be able to accept the event (cannot overflow) */ - Q_ASSERT_CRIT_(210, nFree != 0U); + Q_REQUIRE_INCRIT(201, nFree != 0U); - /* is it a dynamic event? */ - if (e->poolId_ != 0U) { - QEvt_refCtr_inc_(e); /* increment the reference counter */ + if (QEvt_getPoolId_(e) != 0U) { // is it a mutable event? + QEvt_refCtr_inc_(e); // increment the reference counter } - --nFree; /* one free entry just used up */ - me->eQueue.nFree = nFree; /* update the volatile */ + --nFree; // one free entry just used up + me->eQueue.nFree = nFree; // update the original if (me->eQueue.nMin > nFree) { - me->eQueue.nMin = nFree; /* update minimum so far */ + me->eQueue.nMin = nFree; // update minimum so far } - QS_BEGIN_NOCRIT_PRE_(QS_QF_ACTIVE_POST_LIFO, me->prio) - QS_TIME_PRE_(); /* timestamp */ - QS_SIG_PRE_(e->sig); /* the signal of this event */ - QS_OBJ_PRE_(me); /* this active object */ - QS_2U8_PRE_(e->poolId_, e->refCtr_);/* pool Id & ref Count */ - QS_EQC_PRE_(nFree); /* # free entries */ - QS_EQC_PRE_(me->eQueue.nMin); /* min number of free entries */ - QS_END_NOCRIT_PRE_() + QS_BEGIN_PRE_(QS_QF_ACTIVE_POST_LIFO, me->prio) + QS_TIME_PRE_(); // timestamp + QS_SIG_PRE_(e->sig); // the signal of this event + QS_OBJ_PRE_(me); // this active object + QS_2U8_PRE_(QEvt_getPoolId_(e), e->refCtr_);// poolId & refCtr + QS_EQC_PRE_(nFree); // # free entries + QS_EQC_PRE_(me->eQueue.nMin); // min # free entries + QS_END_PRE_() #ifdef Q_UTEST - /* callback to examine the posted event under the same conditions - * as producing the #QS_QF_ACTIVE_POST trace record, which are: - * the local filter for this AO ('me->prio') is set - */ - if (QS_LOC_CHECK_(me->prio)) { - QS_onTestPost((QActive *)0, me, e, true); - } + // callback to examine the posted event under the same conditions + // as producing the #QS_QF_ACTIVE_POST trace record, which are: + // the local filter for this AO ('me->prio') is set + if (QS_LOC_CHECK_(me->prio)) { + QS_onTestPost((QActive *)0, me, e, true); + } #endif - /* temporary to avoid UB for volatile access */ - QEvt const * const frontEvt = me->eQueue.frontEvt; - me->eQueue.frontEvt = e; /* deliver the event directly to the front */ + QEvt const * const frontEvt = me->eQueue.frontEvt; + me->eQueue.frontEvt = e; // deliver the event directly to the front - /* was the queue empty? */ - if (frontEvt == (QEvt *)0) { - QACTIVE_EQUEUE_SIGNAL_(me); /* signal the event queue */ + if (frontEvt == (QEvt *)0) { // was the queue empty? + QACTIVE_EQUEUE_SIGNAL_(me); // signal the event queue } - /* queue was not empty, leave the event in the ring-buffer */ - else { + else { // queue was not empty, leave the event in the ring-buffer ++me->eQueue.tail; - /* need to wrap the tail? */ - if (me->eQueue.tail == me->eQueue.end) { - me->eQueue.tail = 0U; /* wrap around */ + if (me->eQueue.tail == me->eQueue.end) { // need to wrap the tail? + me->eQueue.tail = 0U; // wrap around } me->eQueue.ring[me->eQueue.tail] = frontEvt; } - QF_CRIT_X_(); + + QF_MEM_APP(); + QF_CRIT_EXIT(); } -/*$enddef${QF::QActive::postLIFO_} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*$define${QF::QActive::get_} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//$enddef${QF::QActive::postLIFO_} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +//$define${QF::QActive::get_} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/*${QF::QActive::get_} .....................................................*/ +//${QF::QActive::get_} ....................................................... +//! @private @memberof QActive QEvt const * QActive_get_(QActive * const me) { - QF_CRIT_STAT_ - QF_CRIT_E_(); - QACTIVE_EQUEUE_WAIT_(me); /* wait for event to arrive directly */ + QF_CRIT_STAT + QF_CRIT_ENTRY(); + QF_MEM_SYS(); - /* always remove event from the front */ + QACTIVE_EQUEUE_WAIT_(me); // wait for event to arrive directly + + // always remove event from the front QEvt const * const e = me->eQueue.frontEvt; - QEQueueCtr const nFree = me->eQueue.nFree + 1U; /* volatile into tmp */ - me->eQueue.nFree = nFree; /* update the number of free */ + QEQueueCtr const nFree = me->eQueue.nFree + 1U; // get volatile into tmp + me->eQueue.nFree = nFree; // update the # free - /* any events in the ring buffer? */ - if (nFree <= me->eQueue.end) { - - /* remove event from the tail */ + if (nFree <= me->eQueue.end) { // any events in the ring buffer? + // remove event from the tail me->eQueue.frontEvt = me->eQueue.ring[me->eQueue.tail]; - if (me->eQueue.tail == 0U) { /* need to wrap the tail? */ - me->eQueue.tail = me->eQueue.end; /* wrap around */ + if (me->eQueue.tail == 0U) { // need to wrap the tail? + me->eQueue.tail = me->eQueue.end; // wrap around } --me->eQueue.tail; - QS_BEGIN_NOCRIT_PRE_(QS_QF_ACTIVE_GET, me->prio) - QS_TIME_PRE_(); /* timestamp */ - QS_SIG_PRE_(e->sig); /* the signal of this event */ - QS_OBJ_PRE_(me); /* this active object */ - QS_2U8_PRE_(e->poolId_, e->refCtr_); /* pool Id & ref Count */ - QS_EQC_PRE_(nFree); /* # free entries */ - QS_END_NOCRIT_PRE_() + QS_BEGIN_PRE_(QS_QF_ACTIVE_GET, me->prio) + QS_TIME_PRE_(); // timestamp + QS_SIG_PRE_(e->sig); // the signal of this event + QS_OBJ_PRE_(me); // this active object + QS_2U8_PRE_(QEvt_getPoolId_(e), e->refCtr_); // poolId & refCtr + QS_EQC_PRE_(nFree); // # free entries + QS_END_PRE_() } else { - me->eQueue.frontEvt = (QEvt *)0; /* queue becomes empty */ + me->eQueue.frontEvt = (QEvt *)0; // queue becomes empty - /* all entries in the queue must be free (+1 for fronEvt) */ - Q_ASSERT_CRIT_(310, nFree == (me->eQueue.end + 1U)); + // all entries in the queue must be free (+1 for fronEvt) + Q_ASSERT_INCRIT(310, nFree == (me->eQueue.end + 1U)); - QS_BEGIN_NOCRIT_PRE_(QS_QF_ACTIVE_GET_LAST, me->prio) - QS_TIME_PRE_(); /* timestamp */ - QS_SIG_PRE_(e->sig); /* the signal of this event */ - QS_OBJ_PRE_(me); /* this active object */ - QS_2U8_PRE_(e->poolId_, e->refCtr_); /* pool Id & ref Count */ - QS_END_NOCRIT_PRE_() + QS_BEGIN_PRE_(QS_QF_ACTIVE_GET_LAST, me->prio) + QS_TIME_PRE_(); // timestamp + QS_SIG_PRE_(e->sig); // the signal of this event + QS_OBJ_PRE_(me); // this active object + QS_2U8_PRE_(QEvt_getPoolId_(e), e->refCtr_); // poolId & refCtr + QS_END_PRE_() } - QF_CRIT_X_(); + + QF_MEM_APP(); + QF_CRIT_EXIT(); + return e; } -/*$enddef${QF::QActive::get_} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$enddef${QF::QActive::get_} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -/*$define${QF::QF-base::getQueueMin} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//$define${QF::QF-base::getQueueMin} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/*${QF::QF-base::getQueueMin} ..............................................*/ +//${QF::QF-base::getQueueMin} ................................................ +//! @static @public @memberof QF uint_fast16_t QF_getQueueMin(uint_fast8_t const prio) { - Q_REQUIRE_ID(400, (prio <= QF_MAX_ACTIVE) + QF_CRIT_STAT + QF_CRIT_ENTRY(); + Q_REQUIRE_INCRIT(400, (prio <= QF_MAX_ACTIVE) && (QActive_registry_[prio] != (QActive *)0)); - QF_CRIT_STAT_ - QF_CRIT_E_(); uint_fast16_t const min = (uint_fast16_t)QActive_registry_[prio]->eQueue.nMin; - QF_CRIT_X_(); + QF_CRIT_EXIT(); return min; } -/*$enddef${QF::QF-base::getQueueMin} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$enddef${QF::QF-base::getQueueMin} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +//$define${QF::QTicker} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/*==========================================================================*/ -/*! Perform downcast to QTicker pointer. -* -* @details -* This macro encapsulates the downcast to (QTicker *), which is used in -* QTicker_init_() and QTicker_dispatch_(). Such casts violate MISRA-C 2012 -* Rule 11.3(req) "cast from pointer to object type to pointer to different -* object type". -*/ -#define QTICKER_CAST_(me_) ((QActive *)(me_)) +//${QF::QTicker} ............................................................. -/*$define${QF::QTicker} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${QF::QTicker} ...........................................................*/ - -/*${QF::QTicker::ctor} .....................................................*/ +//${QF::QTicker::ctor} ....................................................... +//! @public @memberof QTicker void QTicker_ctor(QTicker * const me, uint_fast8_t const tickRate) { - static QActiveVtable const vtable = { /* QActive virtual table */ - { &QTicker_init_, - &QTicker_dispatch_ - #ifdef Q_SPY - ,&QHsm_getStateHandler_ - #endif - }, - &QActive_start_, - &QTicker_post_, - &QTicker_postLIFO_ - }; - QActive_ctor(&me->super, Q_STATE_CAST(0)); /* superclass' ctor */ - me->super.super.vptr = &vtable.super; /* hook the vptr */ + QActive_ctor(&me->super, Q_STATE_CAST(0)); // superclass' ctor - /* reuse eQueue.head for tick-rate */ + static struct QAsmVtable const vtable = { // QTicker virtual table + &QTicker_init_, + &QTicker_dispatch_ + #ifdef Q_SPY + ,&QHsm_getStateHandler_ + #endif + }; + me->super.super.vptr = &vtable; // hook the vptr + + // reuse eQueue.head for tick-rate me->super.eQueue.head = (QEQueueCtr)tickRate; } -/*${QF::QTicker::init_} ....................................................*/ +//${QF::QTicker::init_} ...................................................... +//! @private @memberof QTicker void QTicker_init_( - QHsm * const me, + QAsm * const me, void const * const par, uint_fast8_t const qs_id) { @@ -372,78 +392,77 @@ void QTicker_init_( Q_UNUSED_PAR(par); Q_UNUSED_PAR(qs_id); - QTICKER_CAST_(me)->eQueue.tail = 0U; + QF_CRIT_STAT + QF_CRIT_ENTRY(); + QF_MEM_SYS(); + + QACTIVE_CAST_(me)->eQueue.tail = 0U; + + QF_MEM_APP(); + QF_CRIT_EXIT(); } -/*${QF::QTicker::dispatch_} ................................................*/ +//${QF::QTicker::dispatch_} .................................................. +//! @private @memberof QTicker void QTicker_dispatch_( - QHsm * const me, + QAsm * const me, QEvt const * const e, uint_fast8_t const qs_id) { Q_UNUSED_PAR(e); Q_UNUSED_PAR(qs_id); - QF_CRIT_STAT_ - QF_CRIT_E_(); - QEQueueCtr nTicks = QTICKER_CAST_(me)->eQueue.tail; /* save # of ticks */ - QTICKER_CAST_(me)->eQueue.tail = 0U; /* clear # ticks */ - QF_CRIT_X_(); + QF_CRIT_STAT + QF_CRIT_ENTRY(); + QF_MEM_SYS(); + + QEQueueCtr nTicks = QACTIVE_CAST_(me)->eQueue.tail; // save # of ticks + QACTIVE_CAST_(me)->eQueue.tail = 0U; // clear # ticks + + QF_MEM_APP(); + QF_CRIT_EXIT(); for (; nTicks > 0U; --nTicks) { - QTimeEvt_tick_((uint_fast8_t)QTICKER_CAST_(me)->eQueue.head, me); + QTimeEvt_tick_((uint_fast8_t)QACTIVE_CAST_(me)->eQueue.head, me); } } -/*${QF::QTicker::post_} ....................................................*/ -bool QTicker_post_( +//${QF::QTicker::trig_} ...................................................... +//! @private @memberof QTicker +void QTicker_trig_( QActive * const me, - QEvt const * const e, - uint_fast16_t const margin, void const * const sender) { - Q_UNUSED_PAR(e); - Q_UNUSED_PAR(margin); #ifndef Q_SPY Q_UNUSED_PAR(sender); #endif - QF_CRIT_STAT_ - QF_CRIT_E_(); + QF_CRIT_STAT + QF_CRIT_ENTRY(); + QF_MEM_SYS(); + if (me->eQueue.frontEvt == (QEvt *)0) { - static QEvt const tickEvt = { 0U, 0U, 0U }; - me->eQueue.frontEvt = &tickEvt; /* deliver event directly */ - --me->eQueue.nFree; /* one less free event */ + static QEvt const tickEvt = QEVT_INITIALIZER(0); + me->eQueue.frontEvt = &tickEvt; // deliver event directly + --me->eQueue.nFree; // one less free event - QACTIVE_EQUEUE_SIGNAL_(me); /* signal the event queue */ + QACTIVE_EQUEUE_SIGNAL_(me); // signal the event queue } - ++me->eQueue.tail; /* account for one more tick event */ + ++me->eQueue.tail; // account for one more tick event - QS_BEGIN_NOCRIT_PRE_(QS_QF_ACTIVE_POST, me->prio) - QS_TIME_PRE_(); /* timestamp */ - QS_OBJ_PRE_(sender); /* the sender object */ - QS_SIG_PRE_(0U); /* the signal of the event */ - QS_OBJ_PRE_(me); /* this active object */ - QS_2U8_PRE_(0U, 0U); /* pool Id & refCtr of the evt */ - QS_EQC_PRE_(0U); /* number of free entries */ - QS_EQC_PRE_(0U); /* min number of free entries */ - QS_END_NOCRIT_PRE_() + QS_BEGIN_PRE_(QS_QF_ACTIVE_POST, me->prio) + QS_TIME_PRE_(); // timestamp + QS_OBJ_PRE_(sender); // the sender object + QS_SIG_PRE_(0U); // the signal of the event + QS_OBJ_PRE_(me); // this active object + QS_2U8_PRE_(0U, 0U); // poolId & refCtr + QS_EQC_PRE_(0U); // # free entries + QS_EQC_PRE_(0U); // min # free entries + QS_END_PRE_() - QF_CRIT_X_(); - - return true; /* the event is always posted correctly */ + QF_MEM_APP(); + QF_CRIT_EXIT(); } - -/*${QF::QTicker::postLIFO_} ................................................*/ -void QTicker_postLIFO_( - QActive * const me, - QEvt const * const e) -{ - Q_UNUSED_PAR(me); - Q_UNUSED_PAR(e); - - Q_ERROR_ID(900); -} -/*$enddef${QF::QTicker} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$enddef${QF::QTicker} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/src/qf/qf_defer.c b/src/qf/qf_defer.c index 0b939a16..69fd1993 100644 --- a/src/qf/qf_defer.c +++ b/src/qf/qf_defer.c @@ -1,159 +1,169 @@ -/*$file${src::qf::qf_defer.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* -* Model: qpc.qm -* File: ${src::qf::qf_defer.c} -* -* This code has been generated by QM 5.2.4 . -* DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. -* -* This code is covered by the following QP license: -* License # : LicenseRef-QL-dual -* Issued to : Any user of the QP/C real-time embedded framework -* Framework(s) : qpc -* Support ends : 2023-12-31 -* License scope: -* -* Copyright (C) 2005 Quantum Leaps, LLC . -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -*/ -/*$endhead${src::qf::qf_defer.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*! @file -* @brief QActive_defer() and QActive_recall() implementation. -*/ -#define QP_IMPL /* this is QP implementation */ -#include "qf_port.h" /* QF port */ -#include "qf_pkg.h" /* QF package-scope interface */ -#include "qassert.h" /* QP embedded systems-friendly assertions */ -#ifdef Q_SPY /* QS software tracing enabled? */ - #include "qs_port.h" /* QS port */ - #include "qs_pkg.h" /* QS facilities for pre-defined trace records */ +//$file${src::qf::qf_defer.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// +// Model: qpc.qm +// File: ${src::qf::qf_defer.c} +// +// This code has been generated by QM 5.3.0 . +// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. +// +// This code is covered by the following QP license: +// License # : LicenseRef-QL-dual +// Issued to : Any user of the QP/C real-time embedded framework +// Framework(s) : qpc +// Support ends : 2024-12-31 +// License scope: +// +// Copyright (C) 2005 Quantum Leaps, LLC . +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +// +//$endhead${src::qf::qf_defer.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +#define QP_IMPL // this is QP implementation +#include "qp_port.h" // QP port +#include "qp_pkg.h" // QP package-scope interface +#include "qsafe.h" // QP Functional Safety (FuSa) Subsystem +#ifdef Q_SPY // QS software tracing enabled? + #include "qs_port.h" // QS port + #include "qs_pkg.h" // QS facilities for pre-defined trace records #else - #include "qs_dummy.h" /* disable the QS software tracing */ -#endif /* Q_SPY */ + #include "qs_dummy.h" // disable the QS software tracing +#endif // Q_SPY Q_DEFINE_THIS_MODULE("qf_defer") -/*$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* Check for the minimum required QP version */ -#if (QP_VERSION < 700U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) -#error qpc version 7.0.0 or higher required +//$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// Check for the minimum required QP version +#if (QP_VERSION < 730U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) +#error qpc version 7.3.0 or higher required #endif -/*$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -/*$define${QF::QActive::defer} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//$define${QF::QActive::defer} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/*${QF::QActive::defer} ....................................................*/ +//${QF::QActive::defer} ...................................................... +//! @protected @memberof QActive bool QActive_defer(QActive const * const me, - QEQueue * const eq, + struct QEQueue * const eq, QEvt const * const e) { bool const status = QEQueue_post(eq, e, 0U, me->prio); - QS_CRIT_STAT_ + QS_CRIT_STAT + QS_CRIT_ENTRY(); + QS_MEM_SYS(); QS_BEGIN_PRE_(QS_QF_ACTIVE_DEFER, me->prio) - QS_TIME_PRE_(); /* time stamp */ - QS_OBJ_PRE_(me); /* this active object */ - QS_OBJ_PRE_(eq); /* the deferred queue */ - QS_SIG_PRE_(e->sig); /* the signal of the event */ - QS_2U8_PRE_(e->poolId_, e->refCtr_); /* pool Id & ref Count */ + QS_TIME_PRE_(); // time stamp + QS_OBJ_PRE_(me); // this active object + QS_OBJ_PRE_(eq); // the deferred queue + QS_SIG_PRE_(e->sig); // the signal of the event + QS_2U8_PRE_(QEvt_getPoolId_(e), e->refCtr_); // poolId & refCtr QS_END_PRE_() + QS_MEM_APP(); + QS_CRIT_EXIT(); return status; } -/*$enddef${QF::QActive::defer} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*$define${QF::QActive::recall} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//$enddef${QF::QActive::defer} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +//$define${QF::QActive::recall} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/*${QF::QActive::recall} ...................................................*/ +//${QF::QActive::recall} ..................................................... +//! @protected @memberof QActive bool QActive_recall(QActive * const me, - QEQueue * const eq) + struct QEQueue * const eq) { QEvt const * const e = QEQueue_get(eq, me->prio); + QF_CRIT_STAT + bool recalled; + if (e != (QEvt *)0) { // event available? + QACTIVE_POST_LIFO(me, e); // post it to the front of the AO's queue - /* event available? */ - if (e != (QEvt *)0) { - QF_CRIT_STAT_ + QF_CRIT_ENTRY(); + QF_MEM_SYS(); - QACTIVE_POST_LIFO(me, e); /* post it to the front of the AO's queue */ + if (QEvt_getPoolId_(e) != 0U) { // is it a mutable event? - QF_CRIT_E_(); + // after posting to the AO's queue the event must be referenced + // at least twice: once in the deferred event queue (eq->get() + // did NOT decrement the reference counter) and once in the + // AO's event queue. + Q_ASSERT_INCRIT(210, e->refCtr_ >= 2U); - /* is it a dynamic event? */ - if (e->poolId_ != 0U) { - - /* after posting to the AO's queue the event must be referenced - * at least twice: once in the deferred event queue (eq->get() - * did NOT decrement the reference counter) and once in the - * AO's event queue. - */ - Q_ASSERT_CRIT_(210, e->refCtr_ >= 2U); - - /* we need to decrement the reference counter once, to account - * for removing the event from the deferred event queue. - */ - QEvt_refCtr_dec_(e); /* decrement the reference counter */ + // we need to decrement the reference counter once, to account + // for removing the event from the deferred event queue. + QEvt_refCtr_dec_(e); // decrement the reference counter } - QS_BEGIN_NOCRIT_PRE_(QS_QF_ACTIVE_RECALL, me->prio) - QS_TIME_PRE_(); /* time stamp */ - QS_OBJ_PRE_(me); /* this active object */ - QS_OBJ_PRE_(eq); /* the deferred queue */ - QS_SIG_PRE_(e->sig); /* the signal of the event */ - QS_2U8_PRE_(e->poolId_, e->refCtr_); /* pool Id & ref Count */ - QS_END_NOCRIT_PRE_() + QS_BEGIN_PRE_(QS_QF_ACTIVE_RECALL, me->prio) + QS_TIME_PRE_(); // time stamp + QS_OBJ_PRE_(me); // this active object + QS_OBJ_PRE_(eq); // the deferred queue + QS_SIG_PRE_(e->sig); // the signal of the event + QS_2U8_PRE_(QEvt_getPoolId_(e), e->refCtr_); // poolId & refCtr + QS_END_PRE_() + + QF_MEM_APP(); + QF_CRIT_EXIT(); - QF_CRIT_X_(); recalled = true; } else { - QS_CRIT_STAT_ + QS_CRIT_ENTRY(); + QS_MEM_SYS(); QS_BEGIN_PRE_(QS_QF_ACTIVE_RECALL_ATTEMPT, me->prio) - QS_TIME_PRE_(); /* time stamp */ - QS_OBJ_PRE_(me); /* this active object */ - QS_OBJ_PRE_(eq); /* the deferred queue */ + QS_TIME_PRE_(); // time stamp + QS_OBJ_PRE_(me); // this active object + QS_OBJ_PRE_(eq); // the deferred queue QS_END_PRE_() + QS_MEM_APP(); + QS_CRIT_EXIT(); + recalled = false; } return recalled; } -/*$enddef${QF::QActive::recall} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*$define${QF::QActive::flushDeferred} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//$enddef${QF::QActive::recall} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +//$define${QF::QActive::flushDeferred} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/*${QF::QActive::flushDeferred} ............................................*/ +//${QF::QActive::flushDeferred} .............................................. +//! @protected @memberof QActive uint_fast16_t QActive_flushDeferred(QActive const * const me, - QEQueue * const eq) + struct QEQueue * const eq) { uint_fast16_t n = 0U; for (QEvt const *e = QEQueue_get(eq, me->prio); e != (QEvt *)0; e = QEQueue_get(eq, me->prio)) { - ++n; /* count the flushed event */ + ++n; // count the flushed event #if (QF_MAX_EPOOL > 0U) - QF_gc(e); /* garbage collect */ + QF_gc(e); // garbage collect #endif } return n; } -/*$enddef${QF::QActive::flushDeferred} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$enddef${QF::QActive::flushDeferred} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/src/qf/qf_dyn.c b/src/qf/qf_dyn.c index 6f4d8fa8..2675ad40 100644 --- a/src/qf/qf_dyn.c +++ b/src/qf/qf_dyn.c @@ -1,289 +1,335 @@ -/*$file${src::qf::qf_dyn.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* -* Model: qpc.qm -* File: ${src::qf::qf_dyn.c} -* -* This code has been generated by QM 5.2.4 . -* DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. -* -* This code is covered by the following QP license: -* License # : LicenseRef-QL-dual -* Issued to : Any user of the QP/C real-time embedded framework -* Framework(s) : qpc -* Support ends : 2023-12-31 -* License scope: -* -* Copyright (C) 2005 Quantum Leaps, LLC . -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -*/ -/*$endhead${src::qf::qf_dyn.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*! @file -* @brief QF/C dynamic event management -*/ -#define QP_IMPL /* this is QP implementation */ -#include "qf_port.h" /* QF port */ -#include "qf_pkg.h" /* QF package-scope interface */ -#include "qassert.h" /* QP embedded systems-friendly assertions */ -#ifdef Q_SPY /* QS software tracing enabled? */ - #include "qs_port.h" /* QS port */ - #include "qs_pkg.h" /* QS facilities for pre-defined trace records */ +//$file${src::qf::qf_dyn.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// +// Model: qpc.qm +// File: ${src::qf::qf_dyn.c} +// +// This code has been generated by QM 5.3.0 . +// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. +// +// This code is covered by the following QP license: +// License # : LicenseRef-QL-dual +// Issued to : Any user of the QP/C real-time embedded framework +// Framework(s) : qpc +// Support ends : 2024-12-31 +// License scope: +// +// Copyright (C) 2005 Quantum Leaps, LLC . +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +// +//$endhead${src::qf::qf_dyn.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +#define QP_IMPL // this is QP implementation +#include "qp_port.h" // QP port +#include "qp_pkg.h" // QP package-scope interface +#include "qsafe.h" // QP Functional Safety (FuSa) Subsystem +#ifdef Q_SPY // QS software tracing enabled? + #include "qs_port.h" // QS port + #include "qs_pkg.h" // QS facilities for pre-defined trace records #else - #include "qs_dummy.h" /* disable the QS software tracing */ -#endif /* Q_SPY */ + #include "qs_dummy.h" // disable the QS software tracing +#endif // Q_SPY -#if (QF_MAX_EPOOL > 0U) /* dynamic events configured? */ +#if (QF_MAX_EPOOL > 0U) // mutable events configured? Q_DEFINE_THIS_MODULE("qf_dyn") -//============================================================================ -/*$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* Check for the minimum required QP version */ -#if (QP_VERSION < 700U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) -#error qpc version 7.0.0 or higher required +//$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// Check for the minimum required QP version +#if (QP_VERSION < 730U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) +#error qpc version 7.3.0 or higher required #endif -/*$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -/*$define${QF::QF-pkg::maxPool_} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//$define${QF::QF-dyn} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/*${QF::QF-pkg::maxPool_} ..................................................*/ -uint_fast8_t QF_maxPool_; -/*$enddef${QF::QF-pkg::maxPool_} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*$define${QF::QF-pkg::ePool_[QF_MAX_EPOOL]} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${QF::QF-pkg::ePool_[QF_MAX_EPOOL]} ......................................*/ -#if (QF_MAX_EPOOL > 0U) -QF_EPOOL_TYPE_ QF_ePool_[QF_MAX_EPOOL]; -#endif /* (QF_MAX_EPOOL > 0U) */ -/*$enddef${QF::QF-pkg::ePool_[QF_MAX_EPOOL]} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -//============================================================================ -/*$define${QEP::QEvt} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${QEP::QEvt} .............................................................*/ -/*$enddef${QEP::QEvt} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -//============================================================================ -/*$define${QF::QF-dyn} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${QF::QF-dyn::poolInit} ..................................................*/ +//${QF::QF-dyn::poolInit} .................................................... +//! @static @public @memberof QF void QF_poolInit( void * const poolSto, uint_fast32_t const poolSize, uint_fast16_t const evtSize) { - /*! @pre cannot exceed the number of available memory pools */ - Q_REQUIRE_ID(200, QF_maxPool_ < QF_MAX_EPOOL); + uint_fast8_t const poolId = QF_priv_.maxPool_; - /*! @pre please initialize event pools in ascending order of evtSize: */ - Q_REQUIRE_ID(201, (QF_maxPool_ == 0U) - || (QF_EPOOL_EVENT_SIZE_(QF_ePool_[QF_maxPool_ - 1U]) - < evtSize)); + // see precondition{qf_dyn,200} and precondition{qf_dyn,201} + QF_CRIT_STAT + QF_CRIT_ENTRY(); + QF_MEM_SYS(); - /* perform the platform-dependent initialization of the pool */ - QF_EPOOL_INIT_(QF_ePool_[QF_maxPool_], poolSto, poolSize, evtSize); - ++QF_maxPool_; /* one more pool */ + Q_REQUIRE_INCRIT(200, poolId < QF_MAX_EPOOL); + if (poolId > 0U) { + Q_REQUIRE_INCRIT(201, + QF_EPOOL_EVENT_SIZE_(QF_priv_.ePool_[poolId - 1U]) < evtSize); + } + QF_priv_.maxPool_ = poolId + 1U; // one more pool + + QF_MEM_APP(); + QF_CRIT_EXIT(); + + // perform the port-dependent initialization of the event-pool + QF_EPOOL_INIT_(QF_priv_.ePool_[poolId], poolSto, poolSize, evtSize); #ifdef Q_SPY - /* generate the object-dictionary entry for the initialized pool */ + // generate the object-dictionary entry for the initialized pool { uint8_t obj_name[9] = "EvtPool?"; - obj_name[7] = (uint8_t)(((uint8_t)'0' + QF_maxPool_) & 0x7FU); - QS_obj_dict_pre_(&QF_ePool_[QF_maxPool_ - 1U], (char const *)obj_name); + obj_name[7] = (uint8_t)((uint8_t)'0' + poolId + 1U); + QF_CRIT_ENTRY(); + QF_MEM_SYS(); + QS_obj_dict_pre_(&QF_priv_.ePool_[poolId], (char const *)obj_name); + QF_MEM_APP(); + QF_CRIT_EXIT(); } - #endif /* Q_SPY*/ + #endif // Q_SPY } -/*${QF::QF-dyn::poolGetMaxBlockSize} .......................................*/ +//${QF::QF-dyn::poolGetMaxBlockSize} ......................................... +//! @static @public @memberof QF uint_fast16_t QF_poolGetMaxBlockSize(void) { - return QF_EPOOL_EVENT_SIZE_(QF_ePool_[QF_maxPool_ - 1U]); + return QF_EPOOL_EVENT_SIZE_(QF_priv_.ePool_[QF_priv_.maxPool_ - 1U]); } -/*${QF::QF-dyn::getPoolMin} ................................................*/ +//${QF::QF-dyn::getPoolMin} .................................................. +//! @static @public @memberof QF uint_fast16_t QF_getPoolMin(uint_fast8_t const poolId) { - /*! @pre the poolId must be in range */ - Q_REQUIRE_ID(400, (poolId <= QF_MAX_EPOOL) - && (0U < poolId) && (poolId <= QF_maxPool_)); + QF_CRIT_STAT + QF_CRIT_ENTRY(); + QF_MEM_SYS(); - QF_CRIT_STAT_ - QF_CRIT_E_(); - uint_fast16_t const min = (uint_fast16_t)QF_ePool_[poolId - 1U].nMin; - QF_CRIT_X_(); + Q_REQUIRE_INCRIT(400, (poolId <= QF_MAX_EPOOL) + && (0U < poolId) && (poolId <= QF_priv_.maxPool_)); + + uint_fast16_t const min = (uint_fast16_t)QF_priv_.ePool_[poolId - 1U].nMin; + + QF_MEM_APP(); + QF_CRIT_EXIT(); return min; } -/*${QF::QF-dyn::newX_} .....................................................*/ +//${QF::QF-dyn::newX_} ....................................................... +//! @static @private @memberof QF QEvt * QF_newX_( uint_fast16_t const evtSize, uint_fast16_t const margin, enum_t const sig) { - uint_fast8_t idx; + QF_CRIT_STAT + QF_CRIT_ENTRY(); + QF_MEM_SYS(); - /* find the pool index that fits the requested event size ... */ - for (idx = 0U; idx < QF_maxPool_; ++idx) { - if (evtSize <= QF_EPOOL_EVENT_SIZE_(QF_ePool_[idx])) { + // find the pool id that fits the requested event size... + uint_fast8_t poolId = 0U; // zero-based poolId initially + for (; poolId < QF_priv_.maxPool_; ++poolId) { + if (evtSize <= QF_EPOOL_EVENT_SIZE_(QF_priv_.ePool_[poolId])) { break; } } - /* cannot run out of registered pools */ - Q_ASSERT_ID(310, idx < QF_maxPool_); - /* get e -- platform-dependent */ + // precondition: + // - cannot run out of registered pools + Q_REQUIRE_INCRIT(300, poolId < QF_priv_.maxPool_); + + ++poolId; // convert to 1-based poolId + + QF_MEM_APP(); + QF_CRIT_EXIT(); + + // get event e (port-dependent)... QEvt *e; - #ifdef Q_SPY - QF_EPOOL_GET_(QF_ePool_[idx], e, + QF_EPOOL_GET_(QF_priv_.ePool_[poolId - 1U], e, ((margin != QF_NO_MARGIN) ? margin : 0U), - (uint_fast8_t)QS_EP_ID + idx + 1U); + (uint_fast8_t)QS_EP_ID + poolId); #else - QF_EPOOL_GET_(QF_ePool_[idx], e, + QF_EPOOL_GET_(QF_priv_.ePool_[poolId - 1U], e, ((margin != QF_NO_MARGIN) ? margin : 0U), 0U); #endif - /* was e allocated correctly? */ - QS_CRIT_STAT_ - if (e != (QEvt *)0) { - e->sig = (QSignal)sig; /* set signal for this event */ - e->poolId_ = (uint8_t)(idx + 1U); /* store the pool ID */ - e->refCtr_ = 0U; /* set the reference counter to 0 */ + if (e != (QEvt *)0) { // was e allocated correctly? + e->sig = (QSignal)sig; // set the signal + e->refCtr_ = 0U; // initialize the reference counter to 0 + e->evtTag_ = (uint8_t)(QEVT_MARKER | poolId); - QS_BEGIN_PRE_(QS_QF_NEW, (uint_fast8_t)QS_EP_ID + e->poolId_) - QS_TIME_PRE_(); /* timestamp */ - QS_EVS_PRE_(evtSize); /* the size of the event */ - QS_SIG_PRE_(sig); /* the signal of the event */ + QS_CRIT_ENTRY(); + QS_MEM_SYS(); + QS_BEGIN_PRE_(QS_QF_NEW, + (uint_fast8_t)QS_EP_ID + poolId) + QS_TIME_PRE_(); // timestamp + QS_EVS_PRE_(evtSize); // the size of the event + QS_SIG_PRE_(sig); // the signal of the event QS_END_PRE_() + QS_MEM_APP(); + QS_CRIT_EXIT(); } - /* event cannot be allocated */ - else { - /* This assertion means that the event allocation failed, - * and this failure cannot be tolerated. The most frequent - * reason is an event leak in the application. - */ - Q_ASSERT_ID(320, margin != QF_NO_MARGIN); + else { // event was not allocated - QS_BEGIN_PRE_(QS_QF_NEW_ATTEMPT, (uint_fast8_t)QS_EP_ID + idx + 1U) - QS_TIME_PRE_(); /* timestamp */ - QS_EVS_PRE_(evtSize); /* the size of the event */ - QS_SIG_PRE_(sig); /* the signal of the event */ + QF_CRIT_ENTRY(); + // This assertion means that the event allocation failed, + // and this failure cannot be tolerated. The most frequent + // reason is an event leak in the application. + Q_ASSERT_INCRIT(320, margin != QF_NO_MARGIN); + + QS_MEM_SYS(); + QS_BEGIN_PRE_(QS_QF_NEW_ATTEMPT, + (uint_fast8_t)QS_EP_ID + poolId) + QS_TIME_PRE_(); // timestamp + QS_EVS_PRE_(evtSize); // the size of the event + QS_SIG_PRE_(sig); // the signal of the event QS_END_PRE_() + QS_MEM_APP(); + + QF_CRIT_EXIT(); } - return e; /* can't be NULL if we can't tolerate failed allocation */ + + // the returned event e is guaranteed to be valid (not NULL) + // if we can't tolerate failed allocation + return e; } -/*${QF::QF-dyn::gc} ........................................................*/ +//${QF::QF-dyn::gc} .......................................................... +//! @static @public @memberof QF void QF_gc(QEvt const * const e) { - /* is it a dynamic event? */ - if (e->poolId_ != 0U) { - QF_CRIT_STAT_ - QF_CRIT_E_(); + QF_CRIT_STAT + QF_CRIT_ENTRY(); + Q_REQUIRE_INCRIT(402, QEvt_verify_(e)); - /* isn't this the last reference? */ - if (e->refCtr_ > 1U) { + uint_fast8_t const poolId = QEvt_getPoolId_(e); - QS_BEGIN_NOCRIT_PRE_(QS_QF_GC_ATTEMPT, - (uint_fast8_t)QS_EP_ID + e->poolId_) - QS_TIME_PRE_(); /* timestamp */ - QS_SIG_PRE_(e->sig); /* the signal of the event */ - QS_2U8_PRE_(e->poolId_, e->refCtr_); /* pool Id & ref Count */ - QS_END_NOCRIT_PRE_() + if (poolId != 0U) { // is it a pool event (mutable)? + QF_MEM_SYS(); - QEvt_refCtr_dec_(e); /* decrement the ref counter */ + if (e->refCtr_ > 1U) { // isn't this the last reference? - QF_CRIT_X_(); + QS_BEGIN_PRE_(QS_QF_GC_ATTEMPT, + (uint_fast8_t)QS_EP_ID + poolId) + QS_TIME_PRE_(); // timestamp + QS_SIG_PRE_(e->sig); // the signal of the event + QS_2U8_PRE_(poolId, e->refCtr_); // poolId & refCtr + QS_END_PRE_() + + QEvt_refCtr_dec_(e); // decrement the ref counter + + QF_MEM_APP(); + QF_CRIT_EXIT(); } - /* this is the last reference to this event, recycle it */ - else { - uint_fast8_t const idx = (uint_fast8_t)e->poolId_ - 1U; + else { // this is the last reference to this event, recycle it - QS_BEGIN_NOCRIT_PRE_(QS_QF_GC, - (uint_fast8_t)QS_EP_ID + e->poolId_) - QS_TIME_PRE_(); /* timestamp */ - QS_SIG_PRE_(e->sig); /* the signal of the event */ - QS_2U8_PRE_(e->poolId_, e->refCtr_); /* pool Id & ref Count */ - QS_END_NOCRIT_PRE_() + QS_BEGIN_PRE_(QS_QF_GC, + (uint_fast8_t)QS_EP_ID + poolId) + QS_TIME_PRE_(); // timestamp + QS_SIG_PRE_(e->sig); // the signal of the event + QS_2U8_PRE_(poolId, e->refCtr_); // poolId & refCtr + QS_END_PRE_() - QF_CRIT_X_(); + // pool number must be in range + Q_ASSERT_INCRIT(410, (poolId <= QF_priv_.maxPool_) + && (poolId <= QF_MAX_EPOOL)); + QF_MEM_APP(); + QF_CRIT_EXIT(); - /* pool ID must be in range */ - Q_ASSERT_ID(410, idx < QF_maxPool_); - - /* cast 'const' away, which is OK, because it's a pool event */ + // NOTE: casting 'const' away is legit because it's a pool event #ifdef Q_SPY - QF_EPOOL_PUT_(QF_ePool_[idx], (QEvt *)e, - (uint_fast8_t)QS_EP_ID + e->poolId_); + QF_EPOOL_PUT_(QF_priv_.ePool_[poolId - 1U], + (QEvt *)e, + (uint_fast8_t)QS_EP_ID + poolId); #else - QF_EPOOL_PUT_(QF_ePool_[idx], (QEvt *)e, 0U); + QF_EPOOL_PUT_(QF_priv_.ePool_[poolId - 1U], + (QEvt *)e, 0U); #endif } } + else { + QF_CRIT_EXIT(); + } } -/*${QF::QF-dyn::newRef_} ...................................................*/ +//${QF::QF-dyn::newRef_} ..................................................... +//! @static @private @memberof QF QEvt const * QF_newRef_( QEvt const * const e, void const * const evtRef) { - #ifdef Q_NASSERT + #ifdef Q_UNSAFE Q_UNUSED_PAR(evtRef); #endif - /*! @pre the event must be dynamic and the provided event reference - * must not be already in use */ - Q_REQUIRE_ID(500, - (e->poolId_ != 0U) + QF_CRIT_STAT + QF_CRIT_ENTRY(); + + Q_REQUIRE_INCRIT(502, QEvt_verify_(e)); + + uint_fast8_t const poolId = QEvt_getPoolId_(e); + + Q_REQUIRE_INCRIT(500, (poolId != 0U) && (evtRef == (void *)0)); - QF_CRIT_STAT_ - QF_CRIT_E_(); + QEvt_refCtr_inc_(e); // increments the ref counter - QEvt_refCtr_inc_(e); /* increments the ref counter */ + QS_MEM_SYS(); + QS_BEGIN_PRE_(QS_QF_NEW_REF, + (uint_fast8_t)QS_EP_ID + poolId) + QS_TIME_PRE_(); // timestamp + QS_SIG_PRE_(e->sig); // the signal of the event + QS_2U8_PRE_(poolId, e->refCtr_); // poolId & refCtr + QS_END_PRE_() + QS_MEM_APP(); - QS_BEGIN_NOCRIT_PRE_(QS_QF_NEW_REF, - (uint_fast8_t)QS_EP_ID + e->poolId_) - QS_TIME_PRE_(); /* timestamp */ - QS_SIG_PRE_(e->sig); /* the signal of the event */ - QS_2U8_PRE_(e->poolId_, e->refCtr_); /* pool Id & ref Count */ - QS_END_NOCRIT_PRE_() - - QF_CRIT_X_(); + QF_CRIT_EXIT(); return e; } -/*${QF::QF-dyn::deleteRef_} ................................................*/ +//${QF::QF-dyn::deleteRef_} .................................................. +//! @static @private @memberof QF void QF_deleteRef_(void const * const evtRef) { - QS_CRIT_STAT_ - QEvt const * const e = (QEvt const *)evtRef; + QEvt const * const e = evtRef; + QF_CRIT_STAT + QF_CRIT_ENTRY(); + Q_REQUIRE_INCRIT(602, QEvt_verify_(e)); + + #ifdef Q_SPY + uint_fast8_t const poolId = QEvt_getPoolId_(e); + #endif + + QS_MEM_SYS(); QS_BEGIN_PRE_(QS_QF_DELETE_REF, - (uint_fast8_t)QS_EP_ID + e->poolId_) - QS_TIME_PRE_(); /* timestamp */ - QS_SIG_PRE_(e->sig); /* the signal of the event */ - QS_2U8_PRE_(e->poolId_, e->refCtr_); /* pool Id & ref Count */ + (uint_fast8_t)QS_EP_ID + poolId) + QS_TIME_PRE_(); // timestamp + QS_SIG_PRE_(e->sig); // the signal of the event + QS_2U8_PRE_(poolId, e->refCtr_); // poolId & refCtr QS_END_PRE_() + QS_MEM_APP(); + + QF_CRIT_EXIT(); #if (QF_MAX_EPOOL > 0U) - QF_gc(e); + QF_gc(e); // recycle the referenced event #endif } -/*$enddef${QF::QF-dyn} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$enddef${QF::QF-dyn} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -#endif /* (QF_MAX_EPOOL > 0U) dynamic events configured */ +#endif // (QF_MAX_EPOOL > 0U) mutable events configured diff --git a/src/qf/qf_mem.c b/src/qf/qf_mem.c index 7be0ab9a..a88b8d5d 100644 --- a/src/qf/qf_mem.c +++ b/src/qf/qf_mem.c @@ -1,121 +1,130 @@ -/*$file${src::qf::qf_mem.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* -* Model: qpc.qm -* File: ${src::qf::qf_mem.c} -* -* This code has been generated by QM 5.2.4 . -* DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. -* -* This code is covered by the following QP license: -* License # : LicenseRef-QL-dual -* Issued to : Any user of the QP/C real-time embedded framework -* Framework(s) : qpc -* Support ends : 2023-12-31 -* License scope: -* -* Copyright (C) 2005 Quantum Leaps, LLC . -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -*/ -/*$endhead${src::qf::qf_mem.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*! @file -* @brief ::QMPool implementatin (Memory Pool) -*/ -#define QP_IMPL /* this is QP implementation */ -#include "qf_port.h" /* QF port */ -#include "qf_pkg.h" /* QF package-scope interface */ -#include "qassert.h" /* QP embedded systems-friendly assertions */ -#ifdef Q_SPY /* QS software tracing enabled? */ - #include "qs_port.h" /* QS port */ - #include "qs_pkg.h" /* QS facilities for pre-defined trace records */ +//$file${src::qf::qf_mem.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// +// Model: qpc.qm +// File: ${src::qf::qf_mem.c} +// +// This code has been generated by QM 5.3.0 . +// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. +// +// This code is covered by the following QP license: +// License # : LicenseRef-QL-dual +// Issued to : Any user of the QP/C real-time embedded framework +// Framework(s) : qpc +// Support ends : 2024-12-31 +// License scope: +// +// Copyright (C) 2005 Quantum Leaps, LLC . +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +// +//$endhead${src::qf::qf_mem.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +#define QP_IMPL // this is QP implementation +#include "qp_port.h" // QP port +#include "qp_pkg.h" // QP package-scope interface +#include "qsafe.h" // QP Functional Safety (FuSa) Subsystem +#ifdef Q_SPY // QS software tracing enabled? + #include "qs_port.h" // QS port + #include "qs_pkg.h" // QS facilities for pre-defined trace records #else - #include "qs_dummy.h" /* disable the QS software tracing */ -#endif /* Q_SPY */ + #include "qs_dummy.h" // disable the QS software tracing +#endif // Q_SPY Q_DEFINE_THIS_MODULE("qf_mem") -/*$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* Check for the minimum required QP version */ -#if (QP_VERSION < 700U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) -#error qpc version 7.0.0 or higher required +//$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// Check for the minimum required QP version +#if (QP_VERSION < 730U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) +#error qpc version 7.3.0 or higher required #endif -/*$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -/*$define${QF::QMPool} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//$define${QF::QMPool} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/*${QF::QMPool} ............................................................*/ +//${QF::QMPool} .............................................................. -/*${QF::QMPool::init} ......................................................*/ +//${QF::QMPool::init} ........................................................ +//! @public @memberof QMPool void QMPool_init(QMPool * const me, void * const poolSto, - uint_fast32_t poolSize, - uint_fast16_t blockSize) + uint_fast32_t const poolSize, + uint_fast16_t const blockSize) { - /*! @pre The memory block must be valid - * and the poolSize must fit at least one free block - * and the blockSize must not be too close to the top of the dynamic range - */ - Q_REQUIRE_ID(100, (poolSto != (void *)0) + QF_CRIT_STAT + QF_CRIT_ENTRY(); + QF_MEM_SYS(); + + Q_REQUIRE_INCRIT(100, (poolSto != (void *)0) && (poolSize >= (uint_fast32_t)sizeof(QFreeBlock)) && ((uint_fast16_t)(blockSize + sizeof(QFreeBlock)) > blockSize)); - me->free_head = poolSto; + me->free_head = (QFreeBlock *)poolSto; - /* round up the blockSize to fit an integer # free blocks, no division */ - me->blockSize = (QMPoolSize)sizeof(QFreeBlock); /* start with just one */ - - /* #free blocks that fit in one memory block */ + // find # free blocks in a memory block, NO DIVISION + me->blockSize = (QMPoolSize)sizeof(QFreeBlock); uint_fast16_t nblocks = 1U; while (me->blockSize < (QMPoolSize)blockSize) { me->blockSize += (QMPoolSize)sizeof(QFreeBlock); ++nblocks; } - blockSize = (uint_fast16_t)me->blockSize; /* round-up to nearest block */ - /* the pool buffer must fit at least one rounded-up block */ - Q_ASSERT_ID(110, poolSize >= blockSize); + // the pool buffer must fit at least one rounded-up block + Q_ASSERT_INCRIT(110, poolSize >= me->blockSize); - /* chain all blocks together in a free-list... */ - poolSize -= (uint_fast32_t)blockSize; /* don't count the last block */ - me->nTot = 1U; /* the last block already in the pool */ + // start at the head of the free list + QFreeBlock *fb = me->free_head; + me->nTot = 1U; // the last block already in the list - /* start at the head of the free list */ - QFreeBlock *fb = (QFreeBlock *)me->free_head; - - /* chain all blocks together in a free-list... */ - while (poolSize >= (uint_fast32_t)blockSize) { - fb->next = &fb[nblocks]; /* point next link to next block */ - fb = fb->next; /* advance to the next block */ - poolSize -= (uint_fast32_t)blockSize; /* reduce available pool size */ - ++me->nTot; /* increment the number of blocks so far */ + // chain all blocks together in a free-list... + for (uint_fast32_t size = poolSize - me->blockSize; + size >= (uint_fast32_t)me->blockSize; + size -= (uint_fast32_t)me->blockSize) + { + fb->next = &fb[nblocks]; // point next link to next block + #ifndef Q_UNSAFE + fb->next_dis = (uintptr_t)(~Q_UINTPTR_CAST_(fb->next)); + #endif + fb = fb->next; // advance to the next block + ++me->nTot; // one more free block in the pool } - fb->next = (QFreeBlock *)0; /* the last link points to NULL */ - me->nFree = me->nTot; /* all blocks are free */ - me->nMin = me->nTot; /* the minimum number of free blocks */ - me->start = poolSto; /* the original start this pool buffer */ - me->end = fb; /* the last block in this pool */ + fb->next = (QFreeBlock *)0; // the last link points to NULL + #ifndef Q_UNSAFE + fb->next_dis = (uintptr_t)(~Q_UINTPTR_CAST_(fb->next)); + #endif + + me->nFree = me->nTot; // all blocks are free + me->nMin = me->nTot; // the minimum # free blocks + me->start = poolSto; // the original start this pool buffer + me->end = fb; // the last block in this pool + + QF_MEM_APP(); + QF_CRIT_EXIT(); } -/*${QF::QMPool::get} .......................................................*/ +//${QF::QMPool::get} ......................................................... +//! @public @memberof QMPool void * QMPool_get(QMPool * const me, uint_fast16_t const margin, uint_fast8_t const qs_id) @@ -124,100 +133,110 @@ void * QMPool_get(QMPool * const me, Q_UNUSED_PAR(qs_id); #endif - QF_CRIT_STAT_ - QF_CRIT_E_(); + QF_CRIT_STAT + QF_CRIT_ENTRY(); + QF_MEM_SYS(); - /* have more free blocks than the requested margin? */ + // have more free blocks than the requested margin? QFreeBlock *fb; if (me->nFree > (QMPoolCtr)margin) { - void *fb_next; - fb = (QFreeBlock *)me->free_head; /* get a free block */ + fb = me->free_head; // get a free block - /* the pool has some free blocks, so a free block must be available */ - Q_ASSERT_CRIT_(310, fb != (QFreeBlock *)0); + // a free block must be valid + Q_ASSERT_INCRIT(300, fb != (QFreeBlock *)0); - fb_next = fb->next; /* put volatile to a temporary to avoid UB */ + QFreeBlock * const fb_next = fb->next; // fast temporary - /* is the pool becoming empty? */ - --me->nFree; /* one less free block */ - if (me->nFree == 0U) { - /* pool is becoming empty, so the next free block must be NULL */ - Q_ASSERT_CRIT_(320, fb_next == (QFreeBlock *)0); + // the free block must have integrity (duplicate inverse storage) + Q_ASSERT_INCRIT(302, Q_UINTPTR_CAST_(fb_next) + == (uintptr_t)~fb->next_dis); - me->nMin = 0U; /* remember that the pool got empty */ + --me->nFree; // one less free block + if (me->nFree == 0U) { // is the pool becoming empty? + // pool is becoming empty, so the next free block must be NULL + Q_ASSERT_INCRIT(320, fb_next == (QFreeBlock *)0); + + me->nMin = 0U; // remember that the pool got empty } else { - /*! @invariant - * The pool is not empty, so the next free-block pointer, - * so the next free block must be in range. - * - * @tr{PQP18_3} - */ - /* NOTE: The next free block pointer can fall out of range - * when the client code writes past the memory block, thus - * corrupting the next block. - */ - Q_ASSERT_CRIT_(330, + // invariant: + // The pool is not empty, so the next free-block pointer, + // so the next free block must be in range. + + // NOTE: The next free block pointer can fall out of range + // when the client code writes past the memory block, thus + // corrupting the next block. + Q_ASSERT_INCRIT(330, (me->start <= fb_next) && (fb_next <= me->end)); - /* is the number of free blocks the new minimum so far? */ + // is the # free blocks the new minimum so far? if (me->nMin > me->nFree) { - me->nMin = me->nFree; /* remember the new minimum */ + me->nMin = me->nFree; // remember the new minimum } } - me->free_head = fb_next; /* set the head to the next free block */ + me->free_head = fb_next; // set the head to the next free block - QS_BEGIN_NOCRIT_PRE_(QS_QF_MPOOL_GET, qs_id) - QS_TIME_PRE_(); /* timestamp */ - QS_OBJ_PRE_(me); /* this memory pool */ - QS_MPC_PRE_(me->nFree); /* # of free blocks in the pool */ - QS_MPC_PRE_(me->nMin); /* min # free blocks ever in the pool */ - QS_END_NOCRIT_PRE_() + QS_BEGIN_PRE_(QS_QF_MPOOL_GET, qs_id) + QS_TIME_PRE_(); // timestamp + QS_OBJ_PRE_(me); // this memory pool + QS_MPC_PRE_(me->nFree); // # of free blocks in the pool + QS_MPC_PRE_(me->nMin); // min # free blocks ever in the pool + QS_END_PRE_() } - /* don't have enough free blocks at this point */ - else { + else { // don't have enough free blocks at this point fb = (QFreeBlock *)0; - QS_BEGIN_NOCRIT_PRE_(QS_QF_MPOOL_GET_ATTEMPT, qs_id) - QS_TIME_PRE_(); /* timestamp */ - QS_OBJ_PRE_(me); /* this memory pool */ - QS_MPC_PRE_(me->nFree); /* # of free blocks in the pool */ - QS_MPC_PRE_(margin); /* the requested margin */ - QS_END_NOCRIT_PRE_() + QS_BEGIN_PRE_(QS_QF_MPOOL_GET_ATTEMPT, qs_id) + QS_TIME_PRE_(); // timestamp + QS_OBJ_PRE_(me); // this memory pool + QS_MPC_PRE_(me->nFree); // # of free blocks in the pool + QS_MPC_PRE_(margin); // the requested margin + QS_END_PRE_() } - QF_CRIT_X_(); - return fb; /* return the block or NULL pointer to the caller */ + QF_MEM_APP(); + QF_CRIT_EXIT(); + + return fb; // return the block or NULL pointer to the caller } -/*${QF::QMPool::put} .......................................................*/ +//${QF::QMPool::put} ......................................................... +//! @public @memberof QMPool void QMPool_put(QMPool * const me, - void * const b, + void * const block, uint_fast8_t const qs_id) { #ifndef Q_SPY Q_UNUSED_PAR(qs_id); #endif - /*! @pre number of free blocks cannot exceed the total # blocks and - * the block pointer must be in range for this pool. - */ - Q_REQUIRE_ID(200, (me->nFree < me->nTot) - && (me->start <= b) && (b <= me->end)); + QFreeBlock * const fb = (QFreeBlock *)block; - QF_CRIT_STAT_ - QF_CRIT_E_(); - ((QFreeBlock *)b)->next = (QFreeBlock *)me->free_head;/* link into list */ - me->free_head = b; /* set as new head of the free list */ - ++me->nFree; /* one more free block in this pool */ + QF_CRIT_STAT + QF_CRIT_ENTRY(); + QF_MEM_SYS(); - QS_BEGIN_NOCRIT_PRE_(QS_QF_MPOOL_PUT, qs_id) - QS_TIME_PRE_(); /* timestamp */ - QS_OBJ_PRE_(me); /* this memory pool */ - QS_MPC_PRE_(me->nFree); /* the number of free blocks in the pool */ - QS_END_NOCRIT_PRE_() + Q_REQUIRE_INCRIT(200, (me->nFree < me->nTot) + && (me->start <= fb) && (fb <= me->end)); - QF_CRIT_X_(); + fb->next = me->free_head; // link into list + #ifndef Q_UNSAFE + fb->next_dis = (uintptr_t)(~Q_UINTPTR_CAST_(fb->next)); + #endif + + // set as new head of the free list + me->free_head = block; + + ++me->nFree; // one more free block in this pool + + QS_BEGIN_PRE_(QS_QF_MPOOL_PUT, qs_id) + QS_TIME_PRE_(); // timestamp + QS_OBJ_PRE_(me); // this memory pool + QS_MPC_PRE_(me->nFree); // the # free blocks in the pool + QS_END_PRE_() + + QF_MEM_APP(); + QF_CRIT_EXIT(); } -/*$enddef${QF::QMPool} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$enddef${QF::QMPool} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/src/qf/qf_ps.c b/src/qf/qf_ps.c index 48468ddb..7deb7492 100644 --- a/src/qf/qf_ps.c +++ b/src/qf/qf_ps.c @@ -1,75 +1,77 @@ -/*$file${src::qf::qf_ps.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* -* Model: qpc.qm -* File: ${src::qf::qf_ps.c} -* -* This code has been generated by QM 5.2.4 . -* DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. -* -* This code is covered by the following QP license: -* License # : LicenseRef-QL-dual -* Issued to : Any user of the QP/C real-time embedded framework -* Framework(s) : qpc -* Support ends : 2023-12-31 -* License scope: -* -* Copyright (C) 2005 Quantum Leaps, LLC . -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -*/ -/*$endhead${src::qf::qf_ps.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*! @file -* @brief Publish-Subscribe services -*/ -#define QP_IMPL /* this is QP implementation */ -#include "qf_port.h" /* QF port */ -#include "qf_pkg.h" /* QF package-scope interface */ -#include "qassert.h" /* QP embedded systems-friendly assertions */ -#ifdef Q_SPY /* QS software tracing enabled? */ - #include "qs_port.h" /* QS port */ - #include "qs_pkg.h" /* QS facilities for pre-defined trace records */ +//$file${src::qf::qf_ps.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// +// Model: qpc.qm +// File: ${src::qf::qf_ps.c} +// +// This code has been generated by QM 5.3.0 . +// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. +// +// This code is covered by the following QP license: +// License # : LicenseRef-QL-dual +// Issued to : Any user of the QP/C real-time embedded framework +// Framework(s) : qpc +// Support ends : 2024-12-31 +// License scope: +// +// Copyright (C) 2005 Quantum Leaps, LLC . +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +// +//$endhead${src::qf::qf_ps.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +#define QP_IMPL // this is QP implementation +#include "qp_port.h" // QP port +#include "qp_pkg.h" // QP package-scope interface +#include "qsafe.h" // QP Functional Safety (FuSa) Subsystem +#ifdef Q_SPY // QS software tracing enabled? + #include "qs_port.h" // QS port + #include "qs_pkg.h" // QS facilities for pre-defined trace records #else - #include "qs_dummy.h" /* disable the QS software tracing */ -#endif /* Q_SPY */ + #include "qs_dummy.h" // disable the QS software tracing +#endif // Q_SPY Q_DEFINE_THIS_MODULE("qf_ps") -/*==========================================================================*/ -/*$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* Check for the minimum required QP version */ -#if (QP_VERSION < 700U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) -#error qpc version 7.0.0 or higher required +//$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// Check for the minimum required QP version +#if (QP_VERSION < 730U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) +#error qpc version 7.3.0 or higher required #endif -/*$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -/*$define${QF::QActive::subscrList_} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//$define${QF::QActive::subscrList_} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv QSubscrList * QActive_subscrList_; -/*$enddef${QF::QActive::subscrList_} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*$define${QF::QActive::maxPubSignal_} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//$enddef${QF::QActive::subscrList_} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +//$define${QF::QActive::maxPubSignal_} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv enum_t QActive_maxPubSignal_; -/*$enddef${QF::QActive::maxPubSignal_} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$enddef${QF::QActive::maxPubSignal_} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -/*$define${QF::QActive::psInit} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//$define${QF::QActive::psInit} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/*${QF::QActive::psInit} ...................................................*/ +//${QF::QActive::psInit} ..................................................... +//! @static @public @memberof QActive void QActive_psInit( QSubscrList * const subscrSto, enum_t const maxSignal) @@ -77,16 +79,20 @@ void QActive_psInit( QActive_subscrList_ = subscrSto; QActive_maxPubSignal_ = maxSignal; - /* zero the subscriber list, so that the framework can start correctly - * even if the startup code fails to clear the uninitialized data - * (as is required by the C Standard). - */ - QF_bzero(subscrSto, (uint_fast16_t)maxSignal * sizeof(QSubscrList)); + // initialize the subscriber list + for (enum_t sig = 0; sig < maxSignal; ++sig) { + QPSet_setEmpty(&subscrSto[sig].set); + #ifndef Q_UNSAFE + QPSet_update_(&subscrSto[sig].set, &subscrSto[sig].set_dis); + #endif + } } -/*$enddef${QF::QActive::psInit} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*$define${QF::QActive::publish_} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//$enddef${QF::QActive::psInit} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -/*${QF::QActive::publish_} .................................................*/ +//$define${QF::QActive::publish_} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${QF::QActive::publish_} ................................................... +//! @static @private @memberof QActive void QActive_publish_( QEvt const * const e, void const * const sender, @@ -97,156 +103,208 @@ void QActive_publish_( Q_UNUSED_PAR(qs_id); #endif - /*! @pre the published signal must be within the configured range */ - Q_REQUIRE_ID(200, e->sig < (QSignal)QActive_maxPubSignal_); + QSignal const sig = e->sig; - QF_CRIT_STAT_ - QF_CRIT_E_(); + QF_CRIT_STAT + QF_CRIT_ENTRY(); + QF_MEM_SYS(); - QS_BEGIN_NOCRIT_PRE_(QS_QF_PUBLISH, qs_id) - QS_TIME_PRE_(); /* the timestamp */ - QS_OBJ_PRE_(sender); /* the sender object */ - QS_SIG_PRE_(e->sig); /* the signal of the event */ - QS_2U8_PRE_(e->poolId_, e->refCtr_);/* pool Id & ref Count */ - QS_END_NOCRIT_PRE_() + Q_REQUIRE_INCRIT(200, sig < (QSignal)QActive_maxPubSignal_); + Q_REQUIRE_INCRIT(202, + QPSet_verify_(&QActive_subscrList_[sig].set, + &QActive_subscrList_[sig].set_dis)); - /* is it a dynamic event? */ - if (e->poolId_ != 0U) { - /* NOTE: The reference counter of a dynamic event is incremented to - * prevent premature recycling of the event while the multicasting - * is still in progress. At the end of the function, the garbage - * collector step (QF_gc()) decrements the reference counter and - * recycles the event if the counter drops to zero. This covers the - * case when the event was published without any subscribers. - */ + QS_BEGIN_PRE_(QS_QF_PUBLISH, qs_id) + QS_TIME_PRE_(); // the timestamp + QS_OBJ_PRE_(sender); // the sender object + QS_SIG_PRE_(sig); // the signal of the event + QS_2U8_PRE_(QEvt_getPoolId_(e), e->refCtr_); // poolId & refCtr + QS_END_PRE_() + + // is it a mutable event? + if (QEvt_getPoolId_(e) != 0U) { + // NOTE: The reference counter of a mutable event is incremented to + // prevent premature recycling of the event while the multicasting + // is still in progress. At the end of the function, the garbage + // collector step (QF_gc()) decrements the reference counter and + // recycles the event if the counter drops to zero. This covers the + // case when the event was published without any subscribers. QEvt_refCtr_inc_(e); } - /* make a local, modifiable copy of the subscriber list */ - QPSet subscrList = QActive_subscrList_[e->sig]; - QF_CRIT_X_(); + // make a local, modifiable copy of the subscriber set + QPSet subscrSet = QActive_subscrList_[sig].set; + + QF_MEM_APP(); + QF_CRIT_EXIT(); + + if (QPSet_notEmpty(&subscrSet)) { // any subscribers? + // highest-prio subscriber + uint_fast8_t p = QPSet_findMax(&subscrSet); + + QF_CRIT_ENTRY(); + QF_MEM_SYS(); - if (QPSet_notEmpty(&subscrList)) { /* any subscribers? */ - /* the highest-prio subscriber */ - uint_fast8_t p = QPSet_findMax(&subscrList); QActive *a = QActive_registry_[p]; + // the AO must be registered with the framework + Q_ASSERT_INCRIT(210, a != (QActive *)0); + + QF_MEM_APP(); + QF_CRIT_EXIT(); + QF_SCHED_STAT_ + QF_SCHED_LOCK_(p); // lock the scheduler up to AO's prio + do { // loop over all subscribers - QF_SCHED_LOCK_(a->prio); /* lock the scheduler up to AO's prio */ - do { /* loop over all subscribers */ - /* the prio of the AO must be registered with the framework */ - Q_ASSERT_ID(210, a != (QActive *)0); - - /* QACTIVE_POST() asserts internally if the queue overflows */ + // QACTIVE_POST() asserts internally if the queue overflows QACTIVE_POST(a, e, sender); - QPSet_remove(&subscrList, p); /* remove the handled subscriber */ - if (QPSet_notEmpty(&subscrList)) { /* still more subscribers? */ - /* highest-prio subscriber */ - p = QPSet_findMax(&subscrList); + QPSet_remove(&subscrSet, p); // remove the handled subscriber + if (QPSet_notEmpty(&subscrSet)) { // still more subscribers? + p = QPSet_findMax(&subscrSet); // highest-prio subscriber + + QF_CRIT_ENTRY(); + QF_MEM_SYS(); + a = QActive_registry_[p]; + // the AO must be registered with the framework + Q_ASSERT_INCRIT(220, a != (QActive *)0); + + QF_MEM_APP(); + QF_CRIT_EXIT(); } else { - p = 0U; /* no more subscribers */ + p = 0U; // no more subscribers } } while (p != 0U); - QF_SCHED_UNLOCK_(); /* unlock the scheduler */ + QF_SCHED_UNLOCK_(); // unlock the scheduler } - /* The following garbage collection step decrements the reference counter - * and recycles the event if the counter drops to zero. This covers both - * cases when the event was published with or without any subscribers. - */ + // The following garbage collection step decrements the reference counter + // and recycles the event if the counter drops to zero. This covers both + // cases when the event was published with or without any subscribers. #if (QF_MAX_EPOOL > 0U) - QF_gc(e); /* recycle the event to avoid a leak */ + QF_gc(e); // recycle the event to avoid a leak #endif - } -/*$enddef${QF::QActive::publish_} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*$define${QF::QActive::subscribe} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//$enddef${QF::QActive::publish_} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -/*${QF::QActive::subscribe} ................................................*/ +//$define${QF::QActive::subscribe} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${QF::QActive::subscribe} .................................................. +//! @protected @memberof QActive void QActive_subscribe(QActive const * const me, enum_t const sig) { uint_fast8_t const p = (uint_fast8_t)me->prio; - Q_REQUIRE_ID(300, ((enum_t)Q_USER_SIG <= sig) - && (sig < QActive_maxPubSignal_) - && (0U < p) && (p <= QF_MAX_ACTIVE) - && (QActive_registry_[p] == me)); + QF_CRIT_STAT + QF_CRIT_ENTRY(); + QF_MEM_SYS(); - QF_CRIT_STAT_ - QF_CRIT_E_(); + Q_REQUIRE_INCRIT(300, ((enum_t)Q_USER_SIG <= sig) + && (sig < QActive_maxPubSignal_) + && (0U < p) && (p <= QF_MAX_ACTIVE) + && (QActive_registry_[p] == me)); + Q_REQUIRE_INCRIT(302, + QPSet_verify_(&QActive_subscrList_[sig].set, + &QActive_subscrList_[sig].set_dis)); - QS_BEGIN_NOCRIT_PRE_(QS_QF_ACTIVE_SUBSCRIBE, me->prio) - QS_TIME_PRE_(); /* timestamp */ - QS_SIG_PRE_(sig); /* the signal of this event */ - QS_OBJ_PRE_(me); /* this active object */ - QS_END_NOCRIT_PRE_() + QS_BEGIN_PRE_(QS_QF_ACTIVE_SUBSCRIBE, p) + QS_TIME_PRE_(); // timestamp + QS_SIG_PRE_(sig); // the signal of this event + QS_OBJ_PRE_(me); // this active object + QS_END_PRE_() - /* set the priority bit */ - QPSet_insert(&QActive_subscrList_[sig], p); + // insert the prio. into the subscriber set + QPSet_insert(&QActive_subscrList_[sig].set, p); + #ifndef Q_UNSAFE + QPSet_update_(&QActive_subscrList_[sig].set, + &QActive_subscrList_[sig].set_dis); + #endif - QF_CRIT_X_(); + QF_MEM_APP(); + QF_CRIT_EXIT(); } -/*$enddef${QF::QActive::subscribe} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*$define${QF::QActive::unsubscribe} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//$enddef${QF::QActive::subscribe} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -/*${QF::QActive::unsubscribe} ..............................................*/ +//$define${QF::QActive::unsubscribe} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${QF::QActive::unsubscribe} ................................................ +//! @protected @memberof QActive void QActive_unsubscribe(QActive const * const me, enum_t const sig) { uint_fast8_t const p = (uint_fast8_t)me->prio; - /*! @pre the singal and the prioriy must be in ragne, the AO must also - * be registered with the framework - */ - Q_REQUIRE_ID(400, ((enum_t)Q_USER_SIG <= sig) - && (sig < QActive_maxPubSignal_) - && (0U < p) && (p <= QF_MAX_ACTIVE) - && (QActive_registry_[p] == me)); + QF_CRIT_STAT + QF_CRIT_ENTRY(); + QF_MEM_SYS(); - QF_CRIT_STAT_ - QF_CRIT_E_(); + Q_REQUIRE_INCRIT(400, ((enum_t)Q_USER_SIG <= sig) + && (sig < QActive_maxPubSignal_) + && (0U < p) && (p <= QF_MAX_ACTIVE) + && (QActive_registry_[p] == me)); + Q_REQUIRE_INCRIT(402, + QPSet_verify_(&QActive_subscrList_[sig].set, + &QActive_subscrList_[sig].set_dis)); - QS_BEGIN_NOCRIT_PRE_(QS_QF_ACTIVE_UNSUBSCRIBE, me->prio) - QS_TIME_PRE_(); /* timestamp */ - QS_SIG_PRE_(sig); /* the signal of this event */ - QS_OBJ_PRE_(me); /* this active object */ - QS_END_NOCRIT_PRE_() + QS_BEGIN_PRE_(QS_QF_ACTIVE_UNSUBSCRIBE, p) + QS_TIME_PRE_(); // timestamp + QS_SIG_PRE_(sig); // the signal of this event + QS_OBJ_PRE_(me); // this active object + QS_END_PRE_() - /* clear priority bit */ - QPSet_remove(&QActive_subscrList_[sig], p); + // remove the prio. from the subscriber set + QPSet_remove(&QActive_subscrList_[sig].set, p); + #ifndef Q_UNSAFE + QPSet_update_(&QActive_subscrList_[sig].set, + &QActive_subscrList_[sig].set_dis); + #endif - QF_CRIT_X_(); + QF_MEM_APP(); + QF_CRIT_EXIT(); } -/*$enddef${QF::QActive::unsubscribe} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*$define${QF::QActive::unsubscribeAll} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//$enddef${QF::QActive::unsubscribe} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -/*${QF::QActive::unsubscribeAll} ...........................................*/ +//$define${QF::QActive::unsubscribeAll} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${QF::QActive::unsubscribeAll} ............................................. +//! @protected @memberof QActive void QActive_unsubscribeAll(QActive const * const me) { + QF_CRIT_STAT + QF_CRIT_ENTRY(); + QF_MEM_SYS(); + uint_fast8_t const p = (uint_fast8_t)me->prio; - Q_REQUIRE_ID(500, (0U < p) && (p <= QF_MAX_ACTIVE) - && (QActive_registry_[p] == me)); + Q_REQUIRE_INCRIT(500, (0U < p) && (p <= QF_MAX_ACTIVE) + && (QActive_registry_[p] == me)); + enum_t const maxPubSig = QActive_maxPubSignal_; - for (enum_t sig = (enum_t)Q_USER_SIG; sig < QActive_maxPubSignal_; ++sig) { - QF_CRIT_STAT_ - QF_CRIT_E_(); - if (QPSet_hasElement(&QActive_subscrList_[sig], p)) { - QPSet_remove(&QActive_subscrList_[sig], p); + QF_MEM_APP(); + QF_CRIT_EXIT(); - QS_BEGIN_NOCRIT_PRE_(QS_QF_ACTIVE_UNSUBSCRIBE, me->prio) - QS_TIME_PRE_(); /* timestamp */ - QS_SIG_PRE_(sig); /* the signal of this event */ - QS_OBJ_PRE_(me); /* this active object */ - QS_END_NOCRIT_PRE_() + for (enum_t sig = (enum_t)Q_USER_SIG; sig < maxPubSig; ++sig) { + QF_CRIT_ENTRY(); + QF_MEM_SYS(); + + if (QPSet_hasElement(&QActive_subscrList_[sig].set, p)) { + QPSet_remove(&QActive_subscrList_[sig].set, p); + #ifndef Q_UNSAFE + QPSet_update_(&QActive_subscrList_[sig].set, + &QActive_subscrList_[sig].set_dis); + #endif + QS_BEGIN_PRE_(QS_QF_ACTIVE_UNSUBSCRIBE, p) + QS_TIME_PRE_(); // timestamp + QS_SIG_PRE_(sig); // the signal of this event + QS_OBJ_PRE_(me); // this active object + QS_END_PRE_() } - QF_CRIT_X_(); + QF_MEM_APP(); + QF_CRIT_EXIT(); - /* prevent merging critical sections */ - QF_CRIT_EXIT_NOP(); + QF_CRIT_EXIT_NOP(); // prevent merging critical sections } } -/*$enddef${QF::QActive::unsubscribeAll} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$enddef${QF::QActive::unsubscribeAll} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/src/qf/qf_qact.c b/src/qf/qf_qact.c index 3d06c5a0..c9aa586f 100644 --- a/src/qf/qf_qact.c +++ b/src/qf/qf_qact.c @@ -1,150 +1,119 @@ -/*$file${src::qf::qf_qact.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* -* Model: qpc.qm -* File: ${src::qf::qf_qact.c} -* -* This code has been generated by QM 5.2.4 . -* DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. -* -* This code is covered by the following QP license: -* License # : LicenseRef-QL-dual -* Issued to : Any user of the QP/C real-time embedded framework -* Framework(s) : qpc -* Support ends : 2023-12-31 -* License scope: -* -* Copyright (C) 2005 Quantum Leaps, LLC . -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -*/ -/*$endhead${src::qf::qf_qact.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*! @file -* @brief QActive_ctor() definition -* -* @details -* This file must remain separate from the rest to avoid pulling in the -* "virtual" functions QHsm_init_() and QHsm_dispatch_() in case they -* are not used by the application. -* -* @sa qf_qmact.c -*/ -#define QP_IMPL /* this is QP implementation */ -#include "qf_port.h" /* QF port */ -#include "qf_pkg.h" /* QF package-scope interface */ -#include "qassert.h" /* QP embedded systems-friendly assertions */ +//$file${src::qf::qf_qact.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// +// Model: qpc.qm +// File: ${src::qf::qf_qact.c} +// +// This code has been generated by QM 5.3.0 . +// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. +// +// This code is covered by the following QP license: +// License # : LicenseRef-QL-dual +// Issued to : Any user of the QP/C real-time embedded framework +// Framework(s) : qpc +// Support ends : 2024-12-31 +// License scope: +// +// Copyright (C) 2005 Quantum Leaps, LLC . +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +// +//$endhead${src::qf::qf_qact.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +#define QP_IMPL // this is QP implementation +#include "qp_port.h" // QP port +#include "qp_pkg.h" // QP package-scope interface +#include "qsafe.h" // QP Functional Safety (FuSa) Subsystem +#ifdef Q_SPY // QS software tracing enabled? + #include "qs_port.h" // QS port + #include "qs_pkg.h" // QS facilities for pre-defined trace records +#else + #include "qs_dummy.h" // disable the QS software tracing +#endif // Q_SPY Q_DEFINE_THIS_MODULE("qf_qact") -//============================================================================ -/*$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* Check for the minimum required QP version */ -#if (QP_VERSION < 700U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) -#error qpc version 7.0.0 or higher required +//$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// Check for the minimum required QP version +#if (QP_VERSION < 730U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) +#error qpc version 7.3.0 or higher required #endif -/*$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -/*$define${QF::QActive::registry_[QF_MAX_ACTIVE + 1U]} vvvvvvvvvvvvvvvvvvvvv*/ -QActive * QActive_registry_[QF_MAX_ACTIVE + 1U]; -/*$enddef${QF::QActive::registry_[QF_MAX_ACTIVE + 1U]} ^^^^^^^^^^^^^^^^^^^^^*/ -/*$define${QF::QF-base::intLock_} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//$define${QF::QActive::ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/*${QF::QF-base::intLock_} .................................................*/ -uint_fast8_t volatile QF_intLock_; -/*$enddef${QF::QF-base::intLock_} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*$define${QF::QF-base::intNest_} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${QF::QF-base::intNest_} .................................................*/ -uint_fast8_t volatile QF_intNest_; -/*$enddef${QF::QF-base::intNest_} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*$define${QF::QF-pkg::readySet_} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${QF::QF-pkg::readySet_} .................................................*/ -QPSet QF_readySet_; -/*$enddef${QF::QF-pkg::readySet_} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*$define${QF::QF-pkg::bzero} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${QF::QF-pkg::bzero} .....................................................*/ -void QF_bzero( - void * const start, - uint_fast16_t const len) -{ - uint8_t *ptr = (uint8_t *)start; - for (uint_fast16_t n = len; n > 0U; --n) { - *ptr = 0U; - ++ptr; - } -} -/*$enddef${QF::QF-pkg::bzero} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ - -//============================================================================ -/*$define${QF::QActive::ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${QF::QActive::ctor} .....................................................*/ +//${QF::QActive::ctor} ....................................................... +//! @protected @memberof QActive void QActive_ctor(QActive * const me, QStateHandler const initial) { - static QActiveVtable const vtable = { /* QActive virtual table */ - { &QHsm_init_, - &QHsm_dispatch_ + // clear the whole QActive object, so that the framework can start + // correctly even if the startup code fails to clear the uninitialized + // data (as is required by the C Standard). + QF_bzero_(me, sizeof(*me)); + + // NOTE: QActive inherits the abstract QAsm class, but it calls the + // constructor of the QHsm subclass. This is because QActive inherits + // the behavior from the QHsm subclass. + QHsm_ctor((QHsm *)(me), initial); + + // NOTE: this vtable is identical as QHsm, but is provided + // for the QActive subclass to provide a UNIQUE vptr to distinguish + // subclasses of QActive (e.g., in the debugger). + static struct QAsmVtable const vtable = { // QActive virtual table + &QHsm_init_, + &QHsm_dispatch_ #ifdef Q_SPY - ,&QHsm_getStateHandler_ + ,&QHsm_getStateHandler_ #endif - }, - &QActive_start_, - &QActive_post_, - &QActive_postLIFO_ }; - /* clear the whole QActive object, so that the framework can start - * correctly even if the startup code fails to clear the uninitialized - * data (as is required by the C Standard). - */ - QF_bzero(me, sizeof(*me)); - - QHsm_ctor(&me->super, initial); /* explicitly call superclass' ctor */ - me->super.vptr = &vtable.super; /* hook the vptr to QActive vtable */ + me->super.vptr = &vtable; // hook vptr to QActive vtable } -/*$enddef${QF::QActive::ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*$define${QF::QActive::register_} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//$enddef${QF::QActive::ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -/*${QF::QActive::register_} ................................................*/ +//$define${QF::QActive::register_} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${QF::QActive::register_} .................................................. +//! @private @memberof QActive void QActive_register_(QActive * const me) { - if (me->pthre == 0U) { /* preemption-threshold not defined? */ - me->pthre = me->prio; /* apply the default */ + QF_CRIT_STAT + QF_CRIT_ENTRY(); + QF_MEM_SYS(); + + if (me->pthre == 0U) { // preemption-threshold not defined? + me->pthre = me->prio; // apply the default } - #ifndef Q_NASSERT + #ifndef Q_UNSAFE - /*! @pre - * 1. the "QF-priority" of the AO must be in range - * 2. the "QF-priority" must not be already in use (unique priority) - * 3. the "QF-priority" must not exceed the "preemption-threshold" - */ - Q_REQUIRE_ID(100, (0U < me->prio) && (me->prio <= QF_MAX_ACTIVE) + Q_REQUIRE_INCRIT(100, (0U < me->prio) && (me->prio <= QF_MAX_ACTIVE) && (QActive_registry_[me->prio] == (QActive *)0) && (me->prio <= me->pthre)); uint8_t prev_thre = me->pthre; uint8_t next_thre = me->pthre; - uint_fast8_t p; + uint_fast8_t p; for (p = (uint_fast8_t)me->prio - 1U; p > 0U; --p) { if (QActive_registry_[p] != (QActive *)0) { prev_thre = QActive_registry_[p]->pthre; @@ -158,74 +127,35 @@ void QActive_register_(QActive * const me) { } } - /*! @post - * 1. the preceding pre-thre must not exceed the preemption-threshold - * 2. the preemption-threshold must not exceed the next pre-thre - */ - Q_ENSURE_ID(101, (prev_thre <= me->pthre) && (me->pthre <= next_thre)); + Q_ASSERT_INCRIT(190, (prev_thre <= me->pthre) + && (me->pthre <= next_thre)); + #endif // Q_UNSAFE - #endif // Q_NASSERT - - QF_CRIT_STAT_ - QF_CRIT_E_(); - /* register the AO at the "QF-priority" */ + // register the AO at the QF-prio. QActive_registry_[me->prio] = me; - QF_CRIT_X_(); -} -/*$enddef${QF::QActive::register_} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*$define${QF::QActive::unregister_} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/*${QF::QActive::unregister_} ..............................................*/ + QF_MEM_APP(); + QF_CRIT_EXIT(); +} +//$enddef${QF::QActive::register_} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +//$define${QF::QActive::unregister_} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${QF::QActive::unregister_} ................................................ +//! @private @memberof QActive void QActive_unregister_(QActive * const me) { uint_fast8_t const p = (uint_fast8_t)me->prio; - /*! @pre the priority of the active object must not be zero and cannot - * exceed the maximum #QF_MAX_ACTIVE. Also, the priority of the active - * object must be already registered with the framework. - */ - Q_REQUIRE_ID(200, (0U < p) && (p <= QF_MAX_ACTIVE) - && (QActive_registry_[p] == me)); - QF_CRIT_STAT_ - QF_CRIT_E_(); - QActive_registry_[p] = (QActive *)0; /* free-up the priority level */ - me->super.state.fun = Q_STATE_CAST(0); /* invalidate the state */ - QF_CRIT_X_(); + QF_CRIT_STAT + QF_CRIT_ENTRY(); + QF_MEM_SYS(); + + Q_REQUIRE_INCRIT(200, (0U < p) && (p <= QF_MAX_ACTIVE) + && (QActive_registry_[p] == me)); + QActive_registry_[p] = (QActive *)0; // free-up the prio. level + me->super.state.fun = Q_STATE_CAST(0); // invalidate the state + + QF_MEM_APP(); + QF_CRIT_EXIT(); } -/*$enddef${QF::QActive::unregister_} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ - -//============================================================================ -/*$define${QF-types::QF_LOG2} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${QF-types::QF_LOG2} .....................................................*/ -#ifndef QF_LOG2 -uint_fast8_t QF_LOG2(QPSetBits x) { - static uint8_t const log2LUT[16] = { - 0U, 1U, 2U, 2U, 3U, 3U, 3U, 3U, - 4U, 4U, 4U, 4U, 4U, 4U, 4U, 4U - }; - uint_fast8_t n = 0U; - QPSetBits t; - - #if (QF_MAX_ACTIVE > 16U) - t = (QPSetBits)(x >> 16U); - if (t != 0U) { - n += 16U; - x = t; - } - #endif - #if (QF_MAX_ACTIVE > 8U) - t = (x >> 8U); - if (t != 0U) { - n += 8U; - x = t; - } - #endif - t = (x >> 4U); - if (t != 0U) { - n += 4U; - x = t; - } - return n + log2LUT[x]; -} -#endif /* ndef QF_LOG2 */ -/*$enddef${QF-types::QF_LOG2} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$enddef${QF::QActive::unregister_} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/src/qf/qf_qeq.c b/src/qf/qf_qeq.c index d5bc0c4b..438df8d0 100644 --- a/src/qf/qf_qeq.c +++ b/src/qf/qf_qeq.c @@ -1,87 +1,91 @@ -/*$file${src::qf::qf_qeq.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* -* Model: qpc.qm -* File: ${src::qf::qf_qeq.c} -* -* This code has been generated by QM 5.2.4 . -* DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. -* -* This code is covered by the following QP license: -* License # : LicenseRef-QL-dual -* Issued to : Any user of the QP/C real-time embedded framework -* Framework(s) : qpc -* Support ends : 2023-12-31 -* License scope: -* -* Copyright (C) 2005 Quantum Leaps, LLC . -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -*/ -/*$endhead${src::qf::qf_qeq.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*! @file -* @brief ::QEQueue implementation (QP native thread-safe queue) -*/ -#define QP_IMPL /* this is QP implementation */ -#include "qf_port.h" /* QF port */ -#include "qf_pkg.h" /* QF package-scope interface */ -#include "qassert.h" /* QP embedded systems-friendly assertions */ -#ifdef Q_SPY /* QS software tracing enabled? */ - #include "qs_port.h" /* QS port */ - #include "qs_pkg.h" /* QS facilities for pre-defined trace records */ +//$file${src::qf::qf_qeq.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// +// Model: qpc.qm +// File: ${src::qf::qf_qeq.c} +// +// This code has been generated by QM 5.3.0 . +// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. +// +// This code is covered by the following QP license: +// License # : LicenseRef-QL-dual +// Issued to : Any user of the QP/C real-time embedded framework +// Framework(s) : qpc +// Support ends : 2024-12-31 +// License scope: +// +// Copyright (C) 2005 Quantum Leaps, LLC . +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +// +//$endhead${src::qf::qf_qeq.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +#define QP_IMPL // this is QP implementation +#include "qp_port.h" // QP port +#include "qp_pkg.h" // QP package-scope interface +#include "qsafe.h" // QP Functional Safety (FuSa) Subsystem +#ifdef Q_SPY // QS software tracing enabled? + #include "qs_port.h" // QS port + #include "qs_pkg.h" // QS facilities for pre-defined trace records #else - #include "qs_dummy.h" /* disable the QS software tracing */ -#endif /* Q_SPY */ + #include "qs_dummy.h" // disable the QS software tracing +#endif // Q_SPY Q_DEFINE_THIS_MODULE("qf_qeq") -/*$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* Check for the minimum required QP version */ -#if (QP_VERSION < 700U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) -#error qpc version 7.0.0 or higher required +//$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// Check for the minimum required QP version +#if (QP_VERSION < 730U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) +#error qpc version 7.3.0 or higher required #endif -/*$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -/*$define${QF::QEQueue} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//$define${QF::QEQueue} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/*${QF::QEQueue} ...........................................................*/ +//${QF::QEQueue} ............................................................. +QEQueue QEQueue_dummy; -/*${QF::QEQueue::init} .....................................................*/ +//${QF::QEQueue::init} ....................................................... +//! @public @memberof QEQueue void QEQueue_init(QEQueue * const me, - QEvt const ** const qSto, + struct QEvt const ** const qSto, uint_fast16_t const qLen) { - me->frontEvt = (QEvt *)0; /* no events in the queue */ - me->ring = qSto; /* the beginning of the ring buffer */ + me->frontEvt = (QEvt *)0; // no events in the queue + me->ring = qSto; // the beginning of the ring buffer me->end = (QEQueueCtr)qLen; if (qLen != 0U) { me->head = 0U; me->tail = 0U; } - me->nFree = (QEQueueCtr)(qLen + 1U); /* +1 for frontEvt */ + me->nFree = (QEQueueCtr)(qLen + 1U); // +1 for frontEvt me->nMin = me->nFree; } -/*${QF::QEQueue::post} .....................................................*/ +//${QF::QEQueue::post} ....................................................... +//! @public @memberof QEQueue bool QEQueue_post(QEQueue * const me, - QEvt const * const e, + struct QEvt const * const e, uint_fast16_t const margin, uint_fast8_t const qs_id) { @@ -89,175 +93,181 @@ bool QEQueue_post(QEQueue * const me, Q_UNUSED_PAR(qs_id); #endif - /* @pre event must be valid */ - Q_REQUIRE_ID(200, e != (QEvt *)0); + QF_CRIT_STAT + QF_CRIT_ENTRY(); + QF_MEM_SYS(); - QF_CRIT_STAT_ - QF_CRIT_E_(); - QEQueueCtr nFree = me->nFree; /* get volatile into the temporary */ + Q_REQUIRE_INCRIT(200, e != (QEvt *)0); - /* required margin available? */ + QEQueueCtr nFree = me->nFree; // get volatile into temporary + + // required margin available? bool status; if (((margin == QF_NO_MARGIN) && (nFree > 0U)) || (nFree > (QEQueueCtr)margin)) { - /* is it a dynamic event? */ - if (e->poolId_ != 0U) { - QEvt_refCtr_inc_(e); /* increment the reference counter */ + // is it a mutable event? + if (QEvt_getPoolId_(e) != 0U) { + QEvt_refCtr_inc_(e); // increment the reference counter } - --nFree; /* one free entry just used up */ - me->nFree = nFree; /* update the volatile */ + --nFree; // one free entry just used up + me->nFree = nFree; // update the original if (me->nMin > nFree) { - me->nMin = nFree; /* update minimum so far */ + me->nMin = nFree; // update minimum so far } - QS_BEGIN_NOCRIT_PRE_(QS_QF_EQUEUE_POST, qs_id) - QS_TIME_PRE_(); /* timestamp */ - QS_SIG_PRE_(e->sig); /* the signal of this event */ - QS_OBJ_PRE_(me); /* this queue object */ - QS_2U8_PRE_(e->poolId_, e->refCtr_); /* pool Id & ref Count */ - QS_EQC_PRE_(nFree); /* number of free entries */ - QS_EQC_PRE_(me->nMin); /* min number of free entries */ - QS_END_NOCRIT_PRE_() + QS_BEGIN_PRE_(QS_QF_EQUEUE_POST, qs_id) + QS_TIME_PRE_(); // timestamp + QS_SIG_PRE_(e->sig); // the signal of this event + QS_OBJ_PRE_(me); // this queue object + QS_2U8_PRE_(QEvt_getPoolId_(e), e->refCtr_); // poolId & refCtr + QS_EQC_PRE_(nFree); // # free entries + QS_EQC_PRE_(me->nMin); // min # free entries + QS_END_PRE_() - /* was the queue empty? */ - if (me->frontEvt == (QEvt *)0) { - me->frontEvt = e; /* deliver event directly */ + if (me->frontEvt == (QEvt *)0) { // was the queue empty? + me->frontEvt = e; // deliver event directly } - /* queue was not empty, insert event into the ring-buffer */ - else { - /* insert event into the ring buffer (FIFO)... */ - me->ring[me->head] = e; /* insert e into buffer */ - /* need to wrap the head? */ + else { // queue was not empty, insert event into the ring-buffer + // insert event into the ring buffer (FIFO)... + me->ring[me->head] = e; // insert e into buffer + // need to wrap the head? if (me->head == 0U) { - me->head = me->end; /* wrap around */ + me->head = me->end; // wrap around } --me->head; } - status = true; /* event posted successfully */ + status = true; // event posted successfully } - else { - /*! @note assert if event cannot be posted and dropping events is - * not acceptable - */ - Q_ASSERT_CRIT_(210, margin != QF_NO_MARGIN); + else { // event cannot be posted + // dropping events must be acceptable + Q_ASSERT_INCRIT(210, margin != QF_NO_MARGIN); - QS_BEGIN_NOCRIT_PRE_(QS_QF_EQUEUE_POST_ATTEMPT, qs_id) - QS_TIME_PRE_(); /* timestamp */ - QS_SIG_PRE_(e->sig); /* the signal of this event */ - QS_OBJ_PRE_(me); /* this queue object */ - QS_2U8_PRE_(e->poolId_, e->refCtr_); /* pool Id & ref Count */ - QS_EQC_PRE_(nFree); /* number of free entries */ - QS_EQC_PRE_(margin); /* margin requested */ - QS_END_NOCRIT_PRE_() + QS_BEGIN_PRE_(QS_QF_EQUEUE_POST_ATTEMPT, qs_id) + QS_TIME_PRE_(); // timestamp + QS_SIG_PRE_(e->sig); // the signal of this event + QS_OBJ_PRE_(me); // this queue object + QS_2U8_PRE_(QEvt_getPoolId_(e), e->refCtr_); // poolId & refCtr + QS_EQC_PRE_(nFree); // # free entries + QS_EQC_PRE_(margin); // margin requested + QS_END_PRE_() - status = false; + status = false; // event not posted } - QF_CRIT_X_(); + + QF_MEM_APP(); + QF_CRIT_EXIT(); return status; } -/*${QF::QEQueue::postLIFO} .................................................*/ +//${QF::QEQueue::postLIFO} ................................................... +//! @public @memberof QEQueue void QEQueue_postLIFO(QEQueue * const me, - QEvt const * const e, + struct QEvt const * const e, uint_fast8_t const qs_id) { #ifndef Q_SPY Q_UNUSED_PAR(qs_id); #endif - QF_CRIT_STAT_ - QF_CRIT_E_(); - QEQueueCtr nFree = me->nFree; /* get volatile into the temporary */ + QF_CRIT_STAT + QF_CRIT_ENTRY(); + QF_MEM_SYS(); - /*! @pre the queue must be able to accept the event (cannot overflow) */ - Q_REQUIRE_CRIT_(300, nFree != 0U); + QEQueueCtr nFree = me->nFree; // get volatile into temporary - /* is it a dynamic event? */ - if (e->poolId_ != 0U) { - QEvt_refCtr_inc_(e); /* increment the reference counter */ + Q_REQUIRE_INCRIT(300, nFree != 0U); + + if (QEvt_getPoolId_(e) != 0U) { // is it a mutable event? + QEvt_refCtr_inc_(e); // increment the reference counter } - --nFree; /* one free entry just used up */ - me->nFree = nFree; /* update the volatile */ + --nFree; // one free entry just used up + me->nFree = nFree; // update the original if (me->nMin > nFree) { - me->nMin = nFree; /* update minimum so far */ + me->nMin = nFree; // update minimum so far } - QS_BEGIN_NOCRIT_PRE_(QS_QF_EQUEUE_POST_LIFO, qs_id) - QS_TIME_PRE_(); /* timestamp */ - QS_SIG_PRE_(e->sig); /* the signal of this event */ - QS_OBJ_PRE_(me); /* this queue object */ - QS_2U8_PRE_(e->poolId_, e->refCtr_);/* pool Id & ref Count of event */ - QS_EQC_PRE_(nFree); /* number of free entries */ - QS_EQC_PRE_(me->nMin); /* min number of free entries */ - QS_END_NOCRIT_PRE_() + QS_BEGIN_PRE_(QS_QF_EQUEUE_POST_LIFO, qs_id) + QS_TIME_PRE_(); // timestamp + QS_SIG_PRE_(e->sig); // the signal of this event + QS_OBJ_PRE_(me); // this queue object + QS_2U8_PRE_(QEvt_getPoolId_(e), e->refCtr_); // poolId & refCtr + QS_EQC_PRE_(nFree); // # free entries + QS_EQC_PRE_(me->nMin); // min # free entries + QS_END_PRE_() - QEvt const * const frontEvt = me->frontEvt; /* read volatile into temp */ - me->frontEvt = e; /* deliver event directly to the front of the queue */ + QEvt const * const frontEvt = me->frontEvt; // read into temporary + me->frontEvt = e; // deliver event directly to the front of the queue - /* was the queue not empty? */ - if (frontEvt != (QEvt *)0) { + if (frontEvt != (QEvt *)0) { // was the queue not empty? ++me->tail; - if (me->tail == me->end) { /* need to wrap the tail? */ - me->tail = 0U; /* wrap around */ + if (me->tail == me->end) { // need to wrap the tail? + me->tail = 0U; // wrap around } - me->ring[me->tail] = frontEvt; /* save old front evt */ + me->ring[me->tail] = frontEvt; // save old front evt } - QF_CRIT_X_(); + + QF_MEM_APP(); + QF_CRIT_EXIT(); } -/*${QF::QEQueue::get} ......................................................*/ -QEvt const * QEQueue_get(QEQueue * const me, +//${QF::QEQueue::get} ........................................................ +//! @public @memberof QEQueue +struct QEvt const * QEQueue_get(QEQueue * const me, uint_fast8_t const qs_id) { #ifndef Q_SPY Q_UNUSED_PAR(qs_id); #endif - QF_CRIT_STAT_ - QF_CRIT_E_(); - QEvt const * const e = me->frontEvt; /* remove event from the front */ + QF_CRIT_STAT + QF_CRIT_ENTRY(); + QF_MEM_SYS(); - /* was the queue not empty? */ - if (e != (QEvt *)0) { - /* use a temporary variable to increment volatile me->nFree */ + QEvt const * const e = me->frontEvt; // always remove evt from the front + + if (e != (QEvt *)0) { // was the queue not empty? + // use a temporary variable to increment me->nFree QEQueueCtr const nFree = me->nFree + 1U; - me->nFree = nFree; /* update the number of free */ + me->nFree = nFree; // update the # free - /* any events in the ring buffer? */ + // any events in the ring buffer? if (nFree <= me->end) { - me->frontEvt = me->ring[me->tail]; /* get from tail */ - if (me->tail == 0U) { /* need to wrap the tail? */ - me->tail = me->end; /* wrap around */ + me->frontEvt = me->ring[me->tail]; // get from tail + if (me->tail == 0U) { // need to wrap the tail? + me->tail = me->end; // wrap around } --me->tail; - QS_BEGIN_NOCRIT_PRE_(QS_QF_EQUEUE_GET, qs_id) - QS_TIME_PRE_(); /* timestamp */ - QS_SIG_PRE_(e->sig); /* the signal of this event */ - QS_OBJ_PRE_(me); /* this queue object */ - QS_2U8_PRE_(e->poolId_, e->refCtr_);/* pool Id & ref Count */ - QS_EQC_PRE_(nFree); /* number of free entries */ - QS_END_NOCRIT_PRE_() + QS_BEGIN_PRE_(QS_QF_EQUEUE_GET, qs_id) + QS_TIME_PRE_(); // timestamp + QS_SIG_PRE_(e->sig); // the signal of this event + QS_OBJ_PRE_(me); // this queue object + QS_2U8_PRE_(QEvt_getPoolId_(e), e->refCtr_); // poolId & refCtr + QS_EQC_PRE_(nFree); // # free entries + QS_END_PRE_() } else { - me->frontEvt = (QEvt *)0; /* queue becomes empty */ + me->frontEvt = (QEvt *)0; // queue becomes empty - /* all entries in the queue must be free (+1 for fronEvt) */ - Q_ASSERT_CRIT_(410, nFree == (me->end + 1U)); + // all entries in the queue must be free (+1 for fronEvt) + Q_ASSERT_INCRIT(410, nFree == (me->end + 1U)); - QS_BEGIN_NOCRIT_PRE_(QS_QF_EQUEUE_GET_LAST, qs_id) - QS_TIME_PRE_(); /* timestamp */ - QS_SIG_PRE_(e->sig); /* the signal of this event */ - QS_OBJ_PRE_(me); /* this queue object */ - QS_2U8_PRE_(e->poolId_, e->refCtr_); /* pool Id & ref Count */ - QS_END_NOCRIT_PRE_() + QS_BEGIN_PRE_(QS_QF_EQUEUE_GET_LAST, qs_id) + QS_TIME_PRE_(); // timestamp + QS_SIG_PRE_(e->sig); // the signal of this event + QS_OBJ_PRE_(me); // this queue object + QS_2U8_PRE_(QEvt_getPoolId_(e), e->refCtr_); // poolId & refCtr + QS_END_PRE_() } } - QF_CRIT_X_(); + + QF_MEM_APP(); + QF_CRIT_EXIT(); + return e; } -/*$enddef${QF::QEQueue} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$enddef${QF::QEQueue} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/src/qf/qf_qmact.c b/src/qf/qf_qmact.c index 482f1fbb..069d622e 100644 --- a/src/qf/qf_qmact.c +++ b/src/qf/qf_qmact.c @@ -1,109 +1,94 @@ -/*$file${src::qf::qf_qmact.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* -* Model: qpc.qm -* File: ${src::qf::qf_qmact.c} -* -* This code has been generated by QM 5.2.4 . -* DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. -* -* This code is covered by the following QP license: -* License # : LicenseRef-QL-dual -* Issued to : Any user of the QP/C real-time embedded framework -* Framework(s) : qpc -* Support ends : 2023-12-31 -* License scope: -* -* Copyright (C) 2005 Quantum Leaps, LLC . -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -*/ -/*$endhead${src::qf::qf_qmact.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*! @file -* @brief QMActive_ctor() definition -* -* @details -* This file must remain separate from the rest to avoid pulling in the -* "virtual" functions QHsm_init_() and QHsm_dispatch_() in case they -* are not used by the application. -* -* @sa qf_qact.c -*/ -#define QP_IMPL /* this is QP implementation */ -#include "qf_port.h" /* QF port */ -#include "qf_pkg.h" /* QF package-scope interface */ +//$file${src::qf::qf_qmact.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// +// Model: qpc.qm +// File: ${src::qf::qf_qmact.c} +// +// This code has been generated by QM 5.3.0 . +// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. +// +// This code is covered by the following QP license: +// License # : LicenseRef-QL-dual +// Issued to : Any user of the QP/C real-time embedded framework +// Framework(s) : qpc +// Support ends : 2024-12-31 +// License scope: +// +// Copyright (C) 2005 Quantum Leaps, LLC . +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +// +//$endhead${src::qf::qf_qmact.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +#define QP_IMPL // this is QP implementation +#include "qp_port.h" // QP port +#include "qp_pkg.h" // QP package-scope interface +#include "qsafe.h" // QP Functional Safety (FuSa) Subsystem +#ifdef Q_SPY // QS software tracing enabled? + #include "qs_port.h" // QS port + #include "qs_pkg.h" // QS facilities for pre-defined trace records +#else + #include "qs_dummy.h" // disable the QS software tracing +#endif // Q_SPY -/*Q_DEFINE_THIS_MODULE("qf_qmact")*/ +//Q_DEFINE_THIS_MODULE("qf_qmact") -/* -* This internal macro encapsulates the violation of MISRA-C 2012 -* Rule 11.3(req) "A cast shall not be performed between a pointer to -* object type and a poiner to a different object type". -*/ -#define QMSM_CAST_(ptr_) ((QMsm *)(ptr_)) - -/*$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* Check for the minimum required QP version */ -#if (QP_VERSION < 700U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) -#error qpc version 7.0.0 or higher required +//$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// Check for the minimum required QP version +#if (QP_VERSION < 730U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) +#error qpc version 7.3.0 or higher required #endif -/*$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -/*$define${QF::QMActive} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//$define${QF::QMActive} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/*${QF::QMActive} ..........................................................*/ +//${QF::QMActive} ............................................................ -/*${QF::QMActive::ctor} ....................................................*/ +//${QF::QMActive::ctor} ...................................................... +//! @protected @memberof QMActive void QMActive_ctor(QMActive * const me, QStateHandler const initial) { - static QMActiveVtable const vtable = { /* QMActive virtual table */ - { &QMsm_init_, - &QMsm_dispatch_ + // clear the whole QMActive object, so that the framework can start + // correctly even if the startup code fails to clear the uninitialized + // data (as is required by the C Standard). + QF_bzero_(me, sizeof(*me)); + + // NOTE: QActive inherits the QActvie class, but it calls the + // constructor of the QMsm subclass. This is because QMActive inherits + // the behavior from the QMsm subclass. + QMsm_ctor((QMsm *)(me), initial); + + // NOTE: this vtable is identical as QMsm, but is provided + // for the QMActive subclass to provide a UNIQUE vptr to distinguish + // subclasses of QActive (e.g., in the debugger). + static struct QAsmVtable const vtable = { // QMActive virtual table + &QMsm_init_, + &QMsm_dispatch_ #ifdef Q_SPY - ,&QMsm_getStateHandler_ + ,&QMsm_getStateHandler_ #endif - }, - &QActive_start_, - &QActive_post_, - &QActive_postLIFO_ }; - - /* clear the whole QMActive object, so that the framework can start - * correctly even if the startup code fails to clear the uninitialized - * data (as is required by the C Standard). - */ - QF_bzero(me, sizeof(*me)); - - /*! - * @note - * ::QMActive inherits ::QActive, so by the @ref oop convention - * it should call the constructor of the superclass, i.e., QActive_ctor(). - * However, this would pull in the QActiveVtable, which in turn will pull - * in the code for QHsm_init_() and QHsm_dispatch_() implemetations, - * which is expensive. To avoid this code size penalty, in case QHsm is - * not used in a given project, the call to QMsm_ctor() avoids pulling - * in the code for QHsm. - */ - QMsm_ctor(QMSM_CAST_(&me->super.super), initial); - - me->super.super.vptr = &vtable.super; /* hook vptr to QMActive vtable */ + me->super.super.vptr = &vtable; // hook vptr to QMActive vtable } -/*$enddef${QF::QMActive} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$enddef${QF::QMActive} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/src/qf/qf_time.c b/src/qf/qf_time.c index 1cd4c293..e2939a08 100644 --- a/src/qf/qf_time.c +++ b/src/qf/qf_time.c @@ -1,114 +1,100 @@ -/*$file${src::qf::qf_time.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* -* Model: qpc.qm -* File: ${src::qf::qf_time.c} -* -* This code has been generated by QM 5.2.4 . -* DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. -* -* This code is covered by the following QP license: -* License # : LicenseRef-QL-dual -* Issued to : Any user of the QP/C real-time embedded framework -* Framework(s) : qpc -* Support ends : 2023-12-31 -* License scope: -* -* Copyright (C) 2005 Quantum Leaps, LLC . -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -*/ -/*$endhead${src::qf::qf_time.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*! @file -* @brief QF/C time events and time management services -*/ -#define QP_IMPL /* this is QP implementation */ -#include "qf_port.h" /* QF port */ -#include "qf_pkg.h" /* QF package-scope interface */ -#include "qassert.h" /* QP embedded systems-friendly assertions */ -#ifdef Q_SPY /* QS software tracing enabled? */ - #include "qs_port.h" /* QS port */ - #include "qs_pkg.h" /* QS facilities for pre-defined trace records */ +//$file${src::qf::qf_time.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// +// Model: qpc.qm +// File: ${src::qf::qf_time.c} +// +// This code has been generated by QM 5.3.0 . +// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. +// +// This code is covered by the following QP license: +// License # : LicenseRef-QL-dual +// Issued to : Any user of the QP/C real-time embedded framework +// Framework(s) : qpc +// Support ends : 2024-12-31 +// License scope: +// +// Copyright (C) 2005 Quantum Leaps, LLC . +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +// +//$endhead${src::qf::qf_time.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +#define QP_IMPL // this is QP implementation +#include "qp_port.h" // QP port +#include "qp_pkg.h" // QP package-scope interface +#include "qsafe.h" // QP Functional Safety (FuSa) Subsystem +#ifdef Q_SPY // QS software tracing enabled? + #include "qs_port.h" // QS port + #include "qs_pkg.h" // QS facilities for pre-defined trace records #else - #include "qs_dummy.h" /* disable the QS software tracing */ -#endif /* Q_SPY */ + #include "qs_dummy.h" // disable the QS software tracing +#endif // Q_SPY Q_DEFINE_THIS_MODULE("qf_time") -#ifdef Q_SPY -/*! intertnal macro to encapsulate a MISRA deviation -* @details -* This internal macro encapsulates the violation of MISRA-C 2012 -* Rule 11.5(A) "A conversion should not be performed from pointer to void -* into pointer to object". -*/ -#define QACTIVE_CAST_(ptr_) ((QActive *)(ptr_)) +//$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// Check for the minimum required QP version +#if (QP_VERSION < 730U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) +#error qpc version 7.3.0 or higher required #endif +//$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -/*$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* Check for the minimum required QP version */ -#if (QP_VERSION < 700U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) -#error qpc version 7.0.0 or higher required -#endif -/*$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$define${QF::QTimeEvt} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/*$define${QF::QTimeEvt} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${QF::QTimeEvt} ..........................................................*/ +//${QF::QTimeEvt} ............................................................ QTimeEvt QTimeEvt_timeEvtHead_[QF_MAX_TICK_RATE]; -/*${QF::QTimeEvt::ctorX} ...................................................*/ +//${QF::QTimeEvt::ctorX} ..................................................... +//! @public @memberof QTimeEvt void QTimeEvt_ctorX(QTimeEvt * const me, QActive * const act, enum_t const sig, uint_fast8_t const tickRate) { - /*! @pre The signal must be valid and the tick rate in range */ - Q_REQUIRE_ID(300, (sig != 0) + me->next = (QTimeEvt *)0; + me->act = act; + me->ctr = 0U; + me->interval = 0U; + + QF_CRIT_STAT + QF_CRIT_ENTRY(); + Q_REQUIRE_INCRIT(300, (sig != 0) && (tickRate < QF_MAX_TICK_RATE)); + QF_CRIT_EXIT(); - me->next = (QTimeEvt *)0; - me->ctr = 0U; - me->interval = 0U; - me->super.sig = (QSignal)sig; + // This default event constructor initializes the event + // as NOT allocated from any event-pool, which must be + // the case for Time Events. + QEvt_ctor(&me->super, sig); - /* For backwards compatibility with QTimeEvt_ctor(), the active object - * pointer can be uninitialized (NULL) and is NOT validated in the - * precondition. The active object pointer is validated in preconditions - * to QTimeEvt_arm_() and QTimeEvt_rearm(). - */ - me->act = act; - - /* Setting the POOL_ID event attribute to zero is correct only for - * events not allocated from event pools, which must be the case - * for Time Events. - */ - me->super.poolId_ = 0U; - - /* The refCtr_ attribute is not used in time events, so it is - * reused to hold the tickRate as well as other information - */ + // The refCtr_ attribute is not used in time events, so it is + // reused to hold the tickRate as well as other information me->super.refCtr_ = (uint8_t)tickRate; } -/*${QF::QTimeEvt::armX} ....................................................*/ +//${QF::QTimeEvt::armX} ...................................................... +//! @public @memberof QTimeEvt void QTimeEvt_armX(QTimeEvt * const me, QTimeEvtCtr const nTicks, QTimeEvtCtr const interval) @@ -120,99 +106,101 @@ void QTimeEvt_armX(QTimeEvt * const me, uint_fast8_t const qs_id = ((QActive *)(me->act))->prio; #endif - /*! @pre the host AO must be valid, time evnet must be disarmed, - * number of clock ticks cannot be zero, and the signal must be valid. - */ - Q_REQUIRE_ID(400, (me->act != (void *)0) - && (ctr == 0U) - && (nTicks != 0U) - && (tickRate < (uint_fast8_t)QF_MAX_TICK_RATE) - && (me->super.sig >= (QSignal)Q_USER_SIG)); - #ifdef Q_NASSERT + QF_CRIT_STAT + QF_CRIT_ENTRY(); + QF_MEM_SYS(); + + Q_REQUIRE_INCRIT(400, (me->act != (void *)0) + && (ctr == 0U) + && (nTicks != 0U) + && (tickRate < (uint_fast8_t)QF_MAX_TICK_RATE) + && (me->super.sig >= (QSignal)Q_USER_SIG)); + #ifdef Q_UNSAFE Q_UNUSED_PAR(ctr); #endif - QF_CRIT_STAT_ - QF_CRIT_E_(); me->ctr = nTicks; me->interval = interval; - /* is the time event unlinked? - * NOTE: For the duration of a single clock tick of the specified tick - * rate a time event can be disarmed and yet still linked into the list, - * because un-linking is performed exclusively in QTimeEvt_tick_(). - */ + // is the time event unlinked? + // NOTE: For the duration of a single clock tick of the specified tick + // rate a time event can be disarmed and yet still linked into the list + // because un-linking is performed exclusively in QTimeEvt_tick_(). if ((me->super.refCtr_ & QTE_IS_LINKED) == 0U) { - me->super.refCtr_ |= QTE_IS_LINKED; /* mark as linked */ + // mark as linked + me->super.refCtr_ |= QTE_IS_LINKED; - /* The time event is initially inserted into the separate - * "freshly armed" link list based on QTimeEvt_timeEvtHead_[tickRate].act. - * Only later, inside the QTimeEvt_tick_() function, the "freshly armed" - * list is appended to the main list of armed time events based on - * QTimeEvt_timeEvtHead_[tickRate].next. Again, this is to keep any - * changes to the main list exclusively inside the QTimeEvt_tick_() - * function. - */ + // The time event is initially inserted into the separate + // "freshly armed" link list based on QTimeEvt_timeEvtHead_[tickRate].act. + // Only later, inside the QTimeEvt_tick_() function, the "freshly armed" + // list is appended to the main list of armed time events based on + // QTimeEvt_timeEvtHead_[tickRate].next. Again, this is to keep any + // changes to the main list exclusively inside the QTimeEvt_tick_(). me->next = (QTimeEvt *)QTimeEvt_timeEvtHead_[tickRate].act; QTimeEvt_timeEvtHead_[tickRate].act = me; } - QS_BEGIN_NOCRIT_PRE_(QS_QF_TIMEEVT_ARM, qs_id) - QS_TIME_PRE_(); /* timestamp */ - QS_OBJ_PRE_(me); /* this time event object */ - QS_OBJ_PRE_(me->act); /* the active object */ - QS_TEC_PRE_(nTicks); /* the number of ticks */ - QS_TEC_PRE_(interval); /* the interval */ - QS_U8_PRE_(tickRate); /* tick rate */ - QS_END_NOCRIT_PRE_() + QS_BEGIN_PRE_(QS_QF_TIMEEVT_ARM, qs_id) + QS_TIME_PRE_(); // timestamp + QS_OBJ_PRE_(me); // this time event object + QS_OBJ_PRE_(me->act); // the active object + QS_TEC_PRE_(nTicks); // the # ticks + QS_TEC_PRE_(interval); // the interval + QS_U8_PRE_(tickRate); // tick rate + QS_END_PRE_() - QF_CRIT_X_(); + QF_MEM_APP(); + QF_CRIT_EXIT(); } -/*${QF::QTimeEvt::disarm} ..................................................*/ +//${QF::QTimeEvt::disarm} .................................................... +//! @public @memberof QTimeEvt bool QTimeEvt_disarm(QTimeEvt * const me) { #ifdef Q_SPY uint_fast8_t const qs_id = QACTIVE_CAST_(me->act)->prio; #endif - QF_CRIT_STAT_ - QF_CRIT_E_(); + QF_CRIT_STAT + QF_CRIT_ENTRY(); + QF_MEM_SYS(); - /* is the time event actually armed? */ + // is the time event actually armed? bool wasArmed; if (me->ctr != 0U) { wasArmed = true; me->super.refCtr_ |= QTE_WAS_DISARMED; - QS_BEGIN_NOCRIT_PRE_(QS_QF_TIMEEVT_DISARM, qs_id) - QS_TIME_PRE_(); /* timestamp */ - QS_OBJ_PRE_(me); /* this time event object */ - QS_OBJ_PRE_(me->act); /* the target AO */ - QS_TEC_PRE_(me->ctr); /* the number of ticks */ - QS_TEC_PRE_(me->interval); /* the interval */ - QS_U8_PRE_(me->super.refCtr_ & QTE_TICK_RATE); - QS_END_NOCRIT_PRE_() + QS_BEGIN_PRE_(QS_QF_TIMEEVT_DISARM, qs_id) + QS_TIME_PRE_(); // timestamp + QS_OBJ_PRE_(me); // this time event object + QS_OBJ_PRE_(me->act); // the target AO + QS_TEC_PRE_(me->ctr); // the # ticks + QS_TEC_PRE_(me->interval); // the interval + QS_U8_PRE_(me->super.refCtr_ & QTE_TICK_RATE); // tick rate + QS_END_PRE_() - me->ctr = 0U; /* schedule removal from the list */ + me->ctr = 0U; // schedule removal from the list } - else { /* the time event was already disarmed automatically */ + else { // the time event was already disarmed automatically wasArmed = false; me->super.refCtr_ &= (uint8_t)(~QTE_WAS_DISARMED & 0xFFU); - QS_BEGIN_NOCRIT_PRE_(QS_QF_TIMEEVT_DISARM_ATTEMPT, qs_id) - QS_TIME_PRE_(); /* timestamp */ - QS_OBJ_PRE_(me); /* this time event object */ - QS_OBJ_PRE_(me->act); /* the target AO */ - QS_U8_PRE_(me->super.refCtr_ & QTE_TICK_RATE); - QS_END_NOCRIT_PRE_() - + QS_BEGIN_PRE_(QS_QF_TIMEEVT_DISARM_ATTEMPT, qs_id) + QS_TIME_PRE_(); // timestamp + QS_OBJ_PRE_(me); // this time event object + QS_OBJ_PRE_(me->act); // the target AO + QS_U8_PRE_(me->super.refCtr_ & QTE_TICK_RATE); // tick rate + QS_END_PRE_() } - QF_CRIT_X_(); + + QF_MEM_APP(); + QF_CRIT_EXIT(); return wasArmed; } -/*${QF::QTimeEvt::rearm} ...................................................*/ +//${QF::QTimeEvt::rearm} ..................................................... +//! @public @memberof QTimeEvt bool QTimeEvt_rearm(QTimeEvt * const me, QTimeEvtCtr const nTicks) { @@ -222,80 +210,90 @@ bool QTimeEvt_rearm(QTimeEvt * const me, uint_fast8_t const qs_id = ((QActive *)(me->act))->prio; #endif - /*! @pre AO must be valid, tick rate must be in range, nTicks must not - * be zero, and the signal of this time event must be valid - */ - Q_REQUIRE_ID(600, (me->act != (void *)0) - && (tickRate < QF_MAX_TICK_RATE) - && (nTicks != 0U) - && (me->super.sig >= (QSignal)Q_USER_SIG)); + QF_CRIT_STAT + QF_CRIT_ENTRY(); + QF_MEM_SYS(); - QF_CRIT_STAT_ - QF_CRIT_E_(); + Q_REQUIRE_INCRIT(600, (me->act != (void *)0) + && (tickRate < QF_MAX_TICK_RATE) + && (nTicks != 0U) + && (me->super.sig >= (QSignal)Q_USER_SIG)); - /* is the time evt not running? */ + // is the time evt not running? bool wasArmed; if (me->ctr == 0U) { wasArmed = false; - /* NOTE: For the duration of a single clock tick of the specified - * tick rate a time event can be disarmed and yet still linked into - * the list, because unlinking is performed exclusively in the - * QTimeEvt_tick_() function. - */ - /* is the time event linked yet? */ - if ((me->super.refCtr_ & QTE_IS_LINKED) == 0U) { - me->super.refCtr_ |= QTE_IS_LINKED; /* mark as linked */ + // NOTE: For the duration of a single clock tick of the specified + // tick rate a time event can be disarmed and yet still linked into + // the list, because unlinking is performed exclusively in the + // QTimeEvt_tick_() function. - /* The time event is initially inserted into the separate - * "freshly armed" list based on QTimeEvt_timeEvtHead_[tickRate].act. - * Only later, inside the QTimeEvt_tick_() function, the "freshly - * armed" list is appended to the main list of armed time events - * based on QTimeEvt_timeEvtHead_[tickRate].next. Again, this is - * to keep any changes to the main list exclusively inside the - * QTimeEvt_tick_() function. - */ + // is the time event unlinked? + if ((me->super.refCtr_ & QTE_IS_LINKED) == 0U) { + // mark as linked + me->super.refCtr_ |= QTE_IS_LINKED; + + // The time event is initially inserted into the separate + // "freshly armed" list based on QTimeEvt_timeEvtHead_[tickRate].act. + // Only later, inside the QTimeEvt_tick_() function, the "freshly + // armed" list is appended to the main list of armed time events + // based on QTimeEvt_timeEvtHead_[tickRate].next. Again, this is + // to keep any changes to the main list exclusively inside the + // QTimeEvt_tick_(). me->next = (QTimeEvt *)QTimeEvt_timeEvtHead_[tickRate].act; QTimeEvt_timeEvtHead_[tickRate].act = me; } } - else { /* the time event was armed */ + else { // the time event was armed wasArmed = true; } - me->ctr = nTicks; /* re-load the tick counter (shift the phasing) */ + me->ctr = nTicks; // re-load the tick counter (shift the phasing) - QS_BEGIN_NOCRIT_PRE_(QS_QF_TIMEEVT_REARM, qs_id) - QS_TIME_PRE_(); /* timestamp */ - QS_OBJ_PRE_(me); /* this time event object */ - QS_OBJ_PRE_(me->act); /* the target AO */ - QS_TEC_PRE_(me->ctr); /* the number of ticks */ - QS_TEC_PRE_(me->interval); /* the interval */ + QS_BEGIN_PRE_(QS_QF_TIMEEVT_REARM, qs_id) + QS_TIME_PRE_(); // timestamp + QS_OBJ_PRE_(me); // this time event object + QS_OBJ_PRE_(me->act); // the target AO + QS_TEC_PRE_(me->ctr); // the # ticks + QS_TEC_PRE_(me->interval); // the interval QS_2U8_PRE_(tickRate, (wasArmed ? 1U : 0U)); - QS_END_NOCRIT_PRE_() + QS_END_PRE_() - QF_CRIT_X_(); + QF_MEM_APP(); + QF_CRIT_EXIT(); return wasArmed; } -/*${QF::QTimeEvt::wasDisarmed} .............................................*/ +//${QF::QTimeEvt::wasDisarmed} ............................................... +//! @public @memberof QTimeEvt bool QTimeEvt_wasDisarmed(QTimeEvt * const me) { + QF_CRIT_STAT + QF_CRIT_ENTRY(); + QF_MEM_SYS(); + uint8_t const wasDisarmed = (me->super.refCtr_ & QTE_WAS_DISARMED); - me->super.refCtr_ |= QTE_WAS_DISARMED; /* mark as disarmed */ + me->super.refCtr_ |= QTE_WAS_DISARMED; // mark as disarmed + + QF_MEM_APP(); + QF_CRIT_EXIT(); + return wasDisarmed != 0U; } -/*${QF::QTimeEvt::currCtr} .................................................*/ +//${QF::QTimeEvt::currCtr} ................................................... +//! @public @memberof QTimeEvt QTimeEvtCtr QTimeEvt_currCtr(QTimeEvt const * const me) { - QF_CRIT_STAT_ - QF_CRIT_E_(); - QTimeEvtCtr const ret = me->ctr; - QF_CRIT_X_(); + QF_CRIT_STAT + QF_CRIT_ENTRY(); + QTimeEvtCtr const ctr = me->ctr; + QF_CRIT_EXIT(); - return ret; + return ctr; } -/*${QF::QTimeEvt::tick_} ...................................................*/ +//${QF::QTimeEvt::tick_} ..................................................... +//! @static @private @memberof QTimeEvt void QTimeEvt_tick_( uint_fast8_t const tickRate, void const * const sender) @@ -306,113 +304,130 @@ void QTimeEvt_tick_( QTimeEvt *prev = &QTimeEvt_timeEvtHead_[tickRate]; - QF_CRIT_STAT_ - QF_CRIT_E_(); + QF_CRIT_STAT + QF_CRIT_ENTRY(); + QF_MEM_SYS(); - QS_BEGIN_NOCRIT_PRE_(QS_QF_TICK, 0U) + QS_BEGIN_PRE_(QS_QF_TICK, 0U) ++prev->ctr; - QS_TEC_PRE_(prev->ctr); /* tick ctr */ - QS_U8_PRE_(tickRate); /* tick rate */ - QS_END_NOCRIT_PRE_() + QS_TEC_PRE_(prev->ctr); // tick ctr + QS_U8_PRE_(tickRate); // tick rate + QS_END_PRE_() - /* scan the linked-list of time events at this rate... */ + // scan the linked-list of time events at this rate... for (;;) { - QTimeEvt *t = prev->next; /* advance down the time evt. list */ + QTimeEvt *t = prev->next; // advance down the time evt. list - /* end of the list? */ - if (t == (QTimeEvt *)0) { + if (t == (QTimeEvt *)0) { // end of the list? - /* any new time events armed since the last QTimeEvt_tick_()? */ + // any new time events armed since the last QTimeEvt_tick_()? if (QTimeEvt_timeEvtHead_[tickRate].act != (void *)0) { - /* sanity check */ - Q_ASSERT_CRIT_(110, prev != (QTimeEvt *)0); + // sanity check + Q_ASSERT_INCRIT(110, prev != (QTimeEvt *)0); prev->next = (QTimeEvt *)QTimeEvt_timeEvtHead_[tickRate].act; QTimeEvt_timeEvtHead_[tickRate].act = (void *)0; - t = prev->next; /* switch to the new list */ + t = prev->next; // switch to the new list } else { - break; /* all currently armed time evts. processed */ + break; // all currently armed time evts. processed } } - /* time event scheduled for removal? */ - if (t->ctr == 0U) { + if (t->ctr == 0U) { // time event scheduled for removal? prev->next = t->next; - /* mark time event 't' as NOT linked */ + // mark time event 't' as NOT linked t->super.refCtr_ &= (uint8_t)(~QTE_IS_LINKED & 0xFFU); - /* do NOT advance the prev pointer */ - QF_CRIT_X_(); /* exit crit. section to reduce latency */ + // do NOT advance the prev pointer + QF_MEM_APP(); + QF_CRIT_EXIT(); // exit crit. section to reduce latency - /* prevent merging critical sections, see NOTE1 below */ + // NOTE: prevent merging critical sections + // In some QF ports the critical section exit takes effect only + // on the next machine instruction. If the next instruction is + // another entry to a critical section, the critical section + // might not be really exited, but rather the two adjacent + // critical sections would be MERGED. The QF_CRIT_EXIT_NOP() + // macro contains minimal code required to prevent such merging + // of critical sections in QF ports, in which it can occur. QF_CRIT_EXIT_NOP(); } else { --t->ctr; - /* is time event about to expire? */ - if (t->ctr == 0U) { - /* temporary for volatile */ + if (t->ctr == 0U) { // is time event about to expire? QActive * const act = (QActive *)t->act; - /* periodic time evt? */ - if (t->interval != 0U) { - t->ctr = t->interval; /* rearm the time event */ - prev = t; /* advance to this time event */ + if (t->interval != 0U) { // periodic time evt? + t->ctr = t->interval; // rearm the time event + prev = t; // advance to this time event } - /* one-shot time event: automatically disarm */ - else { + else { // one-shot time event: automatically disarm prev->next = t->next; - /* mark time event 't' as NOT linked */ - t->super.refCtr_ &= (uint8_t)(~QTE_IS_LINKED & 0xFFU); - /* do NOT advance the prev pointer */ - QS_BEGIN_NOCRIT_PRE_(QS_QF_TIMEEVT_AUTO_DISARM, act->prio) - QS_OBJ_PRE_(t); /* this time event object */ - QS_OBJ_PRE_(act); /* the target AO */ - QS_U8_PRE_(tickRate); /* tick rate */ - QS_END_NOCRIT_PRE_() + // mark time event 't' as NOT linked + t->super.refCtr_ &= (uint8_t)(~QTE_IS_LINKED & 0xFFU); + // do NOT advance the prev pointer + + QS_BEGIN_PRE_(QS_QF_TIMEEVT_AUTO_DISARM, act->prio) + QS_OBJ_PRE_(t); // this time event object + QS_OBJ_PRE_(act); // the target AO + QS_U8_PRE_(tickRate); // tick rate + QS_END_PRE_() } - QS_BEGIN_NOCRIT_PRE_(QS_QF_TIMEEVT_POST, act->prio) - QS_TIME_PRE_(); /* timestamp */ - QS_OBJ_PRE_(t); /* the time event object */ - QS_SIG_PRE_(t->super.sig); /* signal of this time event */ - QS_OBJ_PRE_(act); /* the target AO */ - QS_U8_PRE_(tickRate); /* tick rate */ - QS_END_NOCRIT_PRE_() + QS_BEGIN_PRE_(QS_QF_TIMEEVT_POST, act->prio) + QS_TIME_PRE_(); // timestamp + QS_OBJ_PRE_(t); // the time event object + QS_SIG_PRE_(t->super.sig); // signal of this time event + QS_OBJ_PRE_(act); // the target AO + QS_U8_PRE_(tickRate); // tick rate + QS_END_PRE_() - QF_CRIT_X_(); /* exit critical section before posting */ + #ifdef QXK_H_ + if (t->super.sig < Q_USER_SIG) { + QXThread_timeout_(act); + } + else { + QF_MEM_APP(); + QF_CRIT_EXIT(); // exit crit. section before posting - /* QACTIVE_POST() asserts internally if the queue overflows */ + // QACTIVE_POST() asserts if the queue overflows + QACTIVE_POST(act, &t->super, sender); + } + #else + QF_MEM_APP(); + QF_CRIT_EXIT(); // exit crit. section before posting + + // QACTIVE_POST() asserts if the queue overflows QACTIVE_POST(act, &t->super, sender); + #endif } else { - prev = t; /* advance to this time event */ - QF_CRIT_X_(); /* exit crit. section to reduce latency */ + prev = t; // advance to this time event - /* prevent merging critical sections - * In some QF ports the critical section exit takes effect only - * on the next machine instruction. If this case, the next - * instruction is another entry to a critical section, the - * critical section won't be really exited, but rather the - * two adjacent critical sections would be merged. The - * QF_CRIT_EXIT_NOP() macro contains minimal code required - * to prevent such merging of critical sections in QF ports, - * in which it can occur. - */ + QF_MEM_APP(); + QF_CRIT_EXIT(); // exit crit. section to reduce latency + + // prevent merging critical sections, see NOTE above QF_CRIT_EXIT_NOP(); } } - QF_CRIT_E_(); /* re-enter crit. section to continue */ + QF_CRIT_ENTRY(); // re-enter crit. section to continue the loop + QF_MEM_SYS(); } - QF_CRIT_X_(); + + QF_MEM_APP(); + QF_CRIT_EXIT(); } -/*${QF::QTimeEvt::noActive} ................................................*/ +//${QF::QTimeEvt::noActive} .................................................. +//! @static @public @memberof QTimeEvt bool QTimeEvt_noActive(uint_fast8_t const tickRate) { - /*! @pre the tick rate must be in range */ - Q_REQUIRE_ID(200, tickRate < QF_MAX_TICK_RATE); + QF_CRIT_STAT + QF_CRIT_ENTRY(); + Q_REQUIRE_INCRIT(800, tickRate < QF_MAX_TICK_RATE); + QF_CRIT_EXIT(); bool inactive; if (QTimeEvt_timeEvtHead_[tickRate].next != (QTimeEvt *)0) { @@ -426,4 +441,4 @@ bool QTimeEvt_noActive(uint_fast8_t const tickRate) { } return inactive; } -/*$enddef${QF::QTimeEvt} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$enddef${QF::QTimeEvt} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/src/qk/qk.c b/src/qk/qk.c index 32c83f70..d7e7fad7 100644 --- a/src/qk/qk.c +++ b/src/qk/qk.c @@ -1,216 +1,380 @@ -/*$file${src::qk::qk.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* -* Model: qpc.qm -* File: ${src::qk::qk.c} -* -* This code has been generated by QM 5.2.4 . -* DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. -* -* This code is covered by the following QP license: -* License # : LicenseRef-QL-dual -* Issued to : Any user of the QP/C real-time embedded framework -* Framework(s) : qpc -* Support ends : 2023-12-31 -* License scope: -* -* Copyright (C) 2005 Quantum Leaps, LLC . -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -*/ -/*$endhead${src::qk::qk.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*! @file -* @brief QK preemptive kernel implementation -*/ -#define QP_IMPL /* this is QP implementation */ -#include "qf_port.h" /* QF port */ -#include "qf_pkg.h" /* QF package-scope internal interface */ -#include "qassert.h" /* QP embedded systems-friendly assertions */ -#ifdef Q_SPY /* QS software tracing enabled? */ - #include "qs_port.h" /* QS port */ - #include "qs_pkg.h" /* QS facilities for pre-defined trace records */ +//$file${src::qk::qk.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// +// Model: qpc.qm +// File: ${src::qk::qk.c} +// +// This code has been generated by QM 5.3.0 . +// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. +// +// This code is covered by the following QP license: +// License # : LicenseRef-QL-dual +// Issued to : Any user of the QP/C real-time embedded framework +// Framework(s) : qpc +// Support ends : 2024-12-31 +// License scope: +// +// Copyright (C) 2005 Quantum Leaps, LLC . +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +// +//$endhead${src::qk::qk.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +#define QP_IMPL // this is QP implementation +#include "qp_port.h" // QP port +#include "qp_pkg.h" // QP package-scope internal interface +#include "qsafe.h" // QP Functional Safety (FuSa) Subsystem +#ifdef Q_SPY // QS software tracing enabled? + #include "qs_port.h" // QS port + #include "qs_pkg.h" // QS facilities for pre-defined trace records #else - #include "qs_dummy.h" /* disable the QS software tracing */ -#endif /* Q_SPY */ + #include "qs_dummy.h" // disable the QS software tracing +#endif // Q_SPY -/* protection against including this source file in a wrong project */ -#ifndef QP_INC_QK_H_ +// protection against including this source file in a wrong project +#ifndef QK_H_ #error "Source file included in a project NOT based on the QK kernel" -#endif /* QP_INC_QK_H_ */ +#endif // QK_H_ Q_DEFINE_THIS_MODULE("qk") -/*==========================================================================*/ -/*$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* Check for the minimum required QP version */ -#if (QP_VERSION < 700U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) -#error qpc version 7.0.0 or higher required +//$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// Check for the minimum required QP version +#if (QP_VERSION < 730U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) +#error qpc version 7.3.0 or higher required #endif -/*$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -/*$define${QK::QK-base} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//$define${QK::QK-base} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/*${QK::QK-base::attr_} ....................................................*/ -QK QK_attr_; +//${QK::QK-base::priv_} ...................................................... +QK_Attr QK_priv_; -/*${QK::QK-base::schedLock} ................................................*/ +//${QK::QK-base::schedLock} .................................................. +//! @static @public @memberof QK QSchedStatus QK_schedLock(uint_fast8_t const ceiling) { - QF_CRIT_STAT_ - QF_CRIT_E_(); + QF_CRIT_STAT + QF_CRIT_ENTRY(); + QF_MEM_SYS(); - /*! @pre The QK scheduler lock cannot be called from an ISR */ - Q_REQUIRE_ID(600, !QK_ISR_CONTEXT_()); + Q_REQUIRE_INCRIT(100, !QK_ISR_CONTEXT_()); - /* first store the previous lock prio */ + // first store the previous lock prio QSchedStatus stat; - if (ceiling > QK_attr_.lockCeil) { /* raising the lock ceiling? */ - QS_BEGIN_NOCRIT_PRE_(QS_SCHED_LOCK, 0U) - QS_TIME_PRE_(); /* timestamp */ - /* the previous lock ceiling & new lock ceiling */ - QS_2U8_PRE_(QK_attr_.lockCeil, (uint8_t)ceiling); - QS_END_NOCRIT_PRE_() + if (ceiling > QK_priv_.lockCeil) { // raising the lock ceiling? + QS_BEGIN_PRE_(QS_SCHED_LOCK, 0U) + QS_TIME_PRE_(); // timestamp + // the previous lock ceiling & new lock ceiling + QS_2U8_PRE_((uint8_t)QK_priv_.lockCeil, + (uint8_t)ceiling); + QS_END_PRE_() - /* previous status of the lock */ - stat = (QSchedStatus)QK_attr_.lockHolder; - stat |= (QSchedStatus)QK_attr_.lockCeil << 8U; + // previous status of the lock + stat = (QSchedStatus)QK_priv_.lockHolder; + stat |= (QSchedStatus)QK_priv_.lockCeil << 8U; - /* new status of the lock */ - QK_attr_.lockHolder = QK_attr_.actPrio; - QK_attr_.lockCeil = (uint8_t)ceiling; + // new status of the lock + QK_priv_.lockHolder = QK_priv_.actPrio; + QK_priv_.lockCeil = ceiling; } else { - stat = 0xFFU; /* scheduler not locked */ + stat = 0xFFU; // scheduler not locked } - QF_CRIT_X_(); - return stat; /* return the status to be saved in a stack variable */ + QF_MEM_APP(); + QF_CRIT_EXIT(); + + return stat; // return the status to be saved in a stack variable } -/*${QK::QK-base::schedUnlock} ..............................................*/ +//${QK::QK-base::schedUnlock} ................................................ +//! @static @public @memberof QK void QK_schedUnlock(QSchedStatus const stat) { - /* has the scheduler been actually locked by the last QK_schedLock()? */ + // has the scheduler been actually locked by the last QK_schedLock()? if (stat != 0xFFU) { - uint8_t const lockCeil = QK_attr_.lockCeil; - uint8_t const prevCeil = (uint8_t)(stat >> 8U); - QF_CRIT_STAT_ - QF_CRIT_E_(); + QF_CRIT_STAT + QF_CRIT_ENTRY(); + QF_MEM_SYS(); - /*! @pre The scheduler cannot be unlocked: - * - from the ISR context; and - * - the current lock ceiling must be greater than the previous - */ - Q_REQUIRE_ID(700, (!QK_ISR_CONTEXT_()) + uint_fast8_t const lockCeil = QK_priv_.lockCeil; + uint_fast8_t const prevCeil = (stat >> 8U); + Q_REQUIRE_INCRIT(200, (!QK_ISR_CONTEXT_()) && (lockCeil > prevCeil)); - QS_BEGIN_NOCRIT_PRE_(QS_SCHED_UNLOCK, 0U) - QS_TIME_PRE_(); /* timestamp */ - // current lock ceiling (old), previous lock ceiling (new) */ - QS_2U8_PRE_(lockCeil, prevCeil); - QS_END_NOCRIT_PRE_() + QS_BEGIN_PRE_(QS_SCHED_UNLOCK, 0U) + QS_TIME_PRE_(); // timestamp + // current lock ceiling (old), previous lock ceiling (new) + QS_2U8_PRE_((uint8_t)lockCeil, (uint8_t)prevCeil); + QS_END_PRE_() - /* restore the previous lock ceiling and lock holder */ - QK_attr_.lockCeil = prevCeil; - QK_attr_.lockHolder = (uint8_t)(stat & 0xFFU); + // restore the previous lock ceiling and lock holder + QK_priv_.lockCeil = prevCeil; + QK_priv_.lockHolder = (stat & 0xFFU); - /* find if any AOs should be run after unlocking the scheduler */ - if (QK_sched_() != 0U) { /* preemption needed? */ - QK_activate_(); /* activate any unlocked AOs */ + // find if any AOs should be run after unlocking the scheduler + if (QK_sched_() != 0U) { // preemption needed? + QK_activate_(); // activate any unlocked AOs } - QF_CRIT_X_(); + QF_MEM_APP(); + QF_CRIT_EXIT(); } } -/*$enddef${QK::QK-base} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*$define${QK::QF-cust} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/*${QK::QF-cust::init} .....................................................*/ -void QF_init(void) { +//${QK::QK-base::sched_} ..................................................... +//! @static @private @memberof QK +uint_fast8_t QK_sched_(void) { + Q_REQUIRE_INCRIT(400, QPSet_verify_(&QK_priv_.readySet, + &QK_priv_.readySet_dis)); + + uint_fast8_t p; + if (QPSet_isEmpty(&QK_priv_.readySet)) { + p = 0U; // no activation needed + } + else { + // find the highest-prio AO with non-empty event queue + p = QPSet_findMax(&QK_priv_.readySet); + + // is the AO's prio. below the active preemption-threshold? + if (p <= QK_priv_.actThre) { + p = 0U; // no activation needed + } + // is the AO's prio. below the lock-ceiling? + else if (p <= QK_priv_.lockCeil) { + p = 0U; // no activation needed + } + else { + QK_priv_.nextPrio = p; // next AO to run + } + } + + return p; +} + +//${QK::QK-base::activate_} .................................................. +//! @static @private @memberof QK +void QK_activate_(void) { + uint_fast8_t const prio_in = QK_priv_.actPrio; // save initial prio. + uint_fast8_t p = QK_priv_.nextPrio; // next prio to run + QK_priv_.nextPrio = 0U; // clear for the next time + + Q_REQUIRE_INCRIT(500, (prio_in <= QF_MAX_ACTIVE) + && (0U < p) && (p <= QF_MAX_ACTIVE)); + + #if (defined QF_ON_CONTEXT_SW) || (defined Q_SPY) + uint_fast8_t pprev = prio_in; + #endif // QF_ON_CONTEXT_SW || Q_SPY + + // loop until no more ready-to-run AOs of higher pthre than the initial + QActive *a; + do { + a = QActive_registry_[p]; // obtain the pointer to the AO + Q_ASSERT_INCRIT(505, a != (QActive *)0); // the AO must be registered + + // set new active prio. and preemption-threshold + QK_priv_.actPrio = p; + QK_priv_.actThre = a->pthre; + + #if (defined QF_ON_CONTEXT_SW) || (defined Q_SPY) + if (p != pprev) { // changing threads? + + QS_BEGIN_PRE_(QS_SCHED_NEXT, p) + QS_TIME_PRE_(); // timestamp + QS_2U8_PRE_(p, // prio. of the scheduled AO + pprev); // previous prio. + QS_END_PRE_() + + #ifdef QF_ON_CONTEXT_SW + QF_onContextSw(((pprev != 0U) + ? QActive_registry_[pprev] + : (QActive *)0), a); + #endif // QF_ON_CONTEXT_SW + + pprev = p; // update previous prio. + } + #endif // QF_ON_CONTEXT_SW || Q_SPY + + QF_INT_ENABLE(); // unconditionally enable interrupts + + QEvt const * const e = QActive_get_(a); + // NOTE QActive_get_() performs QF_MEM_APP() before return + + // dispatch event (virtual call) + (*a->super.vptr->dispatch)(&a->super, e, p); #if (QF_MAX_EPOOL > 0U) - QF_maxPool_ = 0U; + QF_gc(e); #endif - QF_bzero(&QTimeEvt_timeEvtHead_[0], sizeof(QTimeEvt_timeEvtHead_)); - QF_bzero(&QActive_registry_[0], sizeof(QActive_registry_)); - QF_bzero(&QF_readySet_, sizeof(QF_readySet_)); - QF_bzero(&QK_attr_, sizeof(QK_attr_)); + // determine the next highest-prio. AO ready to run... + QF_INT_DISABLE(); // unconditionally disable interrupts + QF_MEM_SYS(); - /* setup the QK scheduler as initially locked and not running */ - QK_attr_.lockCeil = (QF_MAX_ACTIVE + 1U); /* scheduler locked */ + // internal integrity check (duplicate inverse storage) + Q_ASSERT_INCRIT(502, QPSet_verify_(&QK_priv_.readySet, + &QK_priv_.readySet_dis)); - /* QK idle AO object (const in ROM) */ - static QActive const idle_ao = { (struct QHsmVtable const *)0 }; + if (a->eQueue.frontEvt == (QEvt *)0) { // empty queue? + QPSet_remove(&QK_priv_.readySet, p); + #ifndef Q_UNSAFE + QPSet_update_(&QK_priv_.readySet, &QK_priv_.readySet_dis); + #endif + } - /* register the idle AO object (cast 'const' away) */ - QActive_registry_[0] = (QActive *)&idle_ao; + if (QPSet_isEmpty(&QK_priv_.readySet)) { + p = 0U; // no activation needed + } + else { + // find new highest-prio AO ready to run... + p = (uint8_t)QPSet_findMax(&QK_priv_.readySet); + + // is the new prio. below the initial preemption-threshold? + if (p <= QActive_registry_[prio_in]->pthre) { + p = 0U; // no activation needed + } + // is the AO's prio. below the lock preemption-threshold? + else if (p <= QK_priv_.lockCeil) { + p = 0U; // no activation needed + } + else { + Q_ASSERT_INCRIT(510, p <= QF_MAX_ACTIVE); + } + } + } while (p != 0U); + + // restore the active prio. and preemption-threshold + QK_priv_.actPrio = prio_in; + QK_priv_.actThre = (uint_fast8_t)QActive_registry_[prio_in]->pthre; + + #if (defined QF_ON_CONTEXT_SW) || (defined Q_SPY) + if (prio_in != 0U) { // resuming an active object? + a = QActive_registry_[prio_in]; // pointer to preempted AO + + QS_BEGIN_PRE_(QS_SCHED_NEXT, prio_in) + QS_TIME_PRE_(); // timestamp + // prio. of the resumed AO, previous prio. + QS_2U8_PRE_(prio_in, pprev); + QS_END_PRE_() + } + else { // resuming prio.==0 --> idle + a = (QActive *)0; // QK idle loop + + QS_BEGIN_PRE_(QS_SCHED_IDLE, pprev) + QS_TIME_PRE_(); // timestamp + QS_U8_PRE_(pprev); // previous prio. + QS_END_PRE_() + } + + #ifdef QF_ON_CONTEXT_SW + QF_onContextSw(QActive_registry_[pprev], a); + #endif // QF_ON_CONTEXT_SW + + #endif // QF_ON_CONTEXT_SW || Q_SPY +} +//$enddef${QK::QK-base} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +//$define${QK::QF-cust} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${QK::QF-cust::init} ....................................................... +//! @static @public @memberof QF +void QF_init(void) { + QF_bzero_(&QF_priv_, sizeof(QF_priv_)); + QF_bzero_(&QK_priv_, sizeof(QK_priv_)); + QF_bzero_(&QTimeEvt_timeEvtHead_[0], sizeof(QTimeEvt_timeEvtHead_)); + QF_bzero_(&QActive_registry_[0], sizeof(QActive_registry_)); + + #ifndef Q_UNSAFE + QPSet_update_(&QK_priv_.readySet, &QK_priv_.readySet_dis); + #endif + + // setup the QK scheduler as initially locked and not running + QK_priv_.lockCeil = (QF_MAX_ACTIVE + 1U); // scheduler locked + + // QK idle AO object (const in ROM) + static QActive const idle_ao = { (struct QAsmVtable const *)0 }; + + // register the idle AO object (cast 'const' away) + QActive_registry_[0] = QACTIVE_CAST_(&idle_ao); #ifdef QK_INIT - QK_INIT(); /* port-specific initialization of the QK kernel */ + QK_INIT(); // port-specific initialization of the QK kernel #endif } -/*${QK::QF-cust::stop} .....................................................*/ +//${QK::QF-cust::stop} ....................................................... +//! @static @public @memberof QF void QF_stop(void) { - QF_onCleanup(); /* application-specific cleanup callback */ - /* nothing else to do for the preemptive QK kernel */ + QF_onCleanup(); // application-specific cleanup callback + // nothing else to do for the preemptive QK kernel } -/*${QK::QF-cust::run} ......................................................*/ +//${QK::QF-cust::run} ........................................................ +//! @static @public @memberof QF int_t QF_run(void) { #ifdef Q_SPY - /* produce the QS_QF_RUN trace record */ + // produce the QS_QF_RUN trace record QF_INT_DISABLE(); + QF_MEM_SYS(); QS_beginRec_((uint_fast8_t)QS_QF_RUN); QS_endRec_(); + QF_MEM_APP(); QF_INT_ENABLE(); - #endif /* Q_SPY */ + #endif // Q_SPY - QF_onStartup(); /* application-specific startup callback */ + QF_onStartup(); // application-specific startup callback QF_INT_DISABLE(); + QF_MEM_SYS(); - QK_attr_.lockCeil = 0U; /* unlock the QK scheduler */ + QK_priv_.lockCeil = 0U; // unlock the QK scheduler - /* activate AOs to process events posted so far */ + // activate AOs to process events posted so far if (QK_sched_() != 0U) { QK_activate_(); } #ifdef QK_START - QK_START(); /* port-specific startup of the QK kernel */ + QK_START(); // port-specific startup of the QK kernel #endif + QF_MEM_APP(); QF_INT_ENABLE(); - for (;;) { /* QK idle loop... */ - QK_onIdle(); /* application-specific QK on-idle callback */ + + for (;;) { // QK idle loop... + QK_onIdle(); // application-specific QK on-idle callback } #ifdef __GNUC__ return 0; #endif } -/*$enddef${QK::QF-cust} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*$define${QK::QActive} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//$enddef${QK::QF-cust} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -/*${QK::QActive} ...........................................................*/ +//$define${QK::QActive} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/*${QK::QActive::start_} ...................................................*/ +//${QK::QActive} ............................................................. + +//${QK::QActive::start_} ..................................................... +//! @public @memberof QActive void QActive_start_(QActive * const me, QPrioSpec const prioSpec, QEvt const * * const qSto, @@ -219,173 +383,35 @@ void QActive_start_(QActive * const me, uint_fast16_t const stkSize, void const * const par) { - Q_UNUSED_PAR(stkSto); /* not needed in QK */ - Q_UNUSED_PAR(stkSize); /* not needed in QK */ + Q_UNUSED_PAR(stkSto); // not needed in QK + Q_UNUSED_PAR(stkSize); // not needed in QK - /*! @pre AO cannot be started from an ISR and the stack storage must - * NOT be provided because the QK kernel does not need per-AO stacks. - */ - Q_REQUIRE_ID(300, (!QK_ISR_CONTEXT_()) + QF_CRIT_STAT + QF_CRIT_ENTRY(); + QF_MEM_SYS(); + + Q_REQUIRE_INCRIT(300, (!QK_ISR_CONTEXT_()) && (stkSto == (void *)0)); + QF_MEM_APP(); + QF_CRIT_EXIT(); - me->prio = (uint8_t)(prioSpec & 0xFFU); /* QF-priority of the AO */ - me->pthre = (uint8_t)(prioSpec >> 8U); /* preemption-threshold */ - QActive_register_(me); /* make QF aware of this active object */ + me->prio = (uint8_t)(prioSpec & 0xFFU); // QF-prio. of the AO + me->pthre = (uint8_t)(prioSpec >> 8U); // preemption-threshold + QActive_register_(me); // make QF aware of this active object - QEQueue_init(&me->eQueue, qSto, qLen); /* init the built-in queue */ + QEQueue_init(&me->eQueue, qSto, qLen); // init the built-in queue - QHSM_INIT(&me->super, par, me->prio); /* top-most initial tran. */ - QS_FLUSH(); /* flush the trace buffer to the host */ + // top-most initial tran. (virtual call) + (*me->super.vptr->init)(&me->super, par, me->prio); + QS_FLUSH(); // flush the trace buffer to the host - /* See if this AO needs to be scheduled if QK is already running */ - QF_CRIT_STAT_ - QF_CRIT_E_(); - if (QK_sched_() != 0U) { /* activation needed? */ + // See if this AO needs to be scheduled if QK is already running + QF_CRIT_ENTRY(); + QF_MEM_SYS(); + if (QK_sched_() != 0U) { // activation needed? QK_activate_(); } - QF_CRIT_X_(); + QF_MEM_APP(); + QF_CRIT_EXIT(); } -/*$enddef${QK::QActive} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*$define${QK::QK-extern-C} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${QK::QK-extern-C::sched_} ...............................................*/ -uint_fast8_t QK_sched_(void) { - uint_fast8_t p; - - if (QPSet_isEmpty(&QF_readySet_)) { - p = 0U; /* no activation needed */ - } - else { - /* find the highest-prio AO with non-empty event queue */ - p = QPSet_findMax(&QF_readySet_); - - /* is the AO's priority below the active preemption-threshold? */ - if (p <= QK_attr_.actThre) { - p = 0U; /* no activation needed */ - } - /* is the AO's priority below the lock-ceiling? */ - else if (p <= QK_attr_.lockCeil) { - p = 0U; /* no activation needed */ - } - else { - QK_attr_.nextPrio = (uint8_t)p; /* next AO to run */ - } - } - return p; -} - -/*${QK::QK-extern-C::activate_} ............................................*/ -void QK_activate_(void) { - uint8_t const prio_in = QK_attr_.actPrio; /* saved initial priority */ - uint8_t p = QK_attr_.nextPrio; /* next prio to run */ - QK_attr_.nextPrio = 0U; /* clear for the next time */ - - /* QK_attr_.actPrio and QK_attr_.nextPrio must be in range */ - Q_REQUIRE_ID(500, (prio_in <= QF_MAX_ACTIVE) - && (0U < p) && (p <= QF_MAX_ACTIVE)); - - #if (defined QF_ON_CONTEXT_SW) || (defined Q_SPY) - uint8_t pprev = prio_in; - #endif /* QF_ON_CONTEXT_SW || Q_SPY */ - - /* loop until no more ready-to-run AOs of higher pthre than the initial */ - QActive *a; - do { - a = QActive_registry_[p]; /* obtain the pointer to the AO */ - Q_ASSERT_ID(505, a != (QActive *)0); /* the AO must be registered */ - - /* set new active priority and preemption-threshold */ - QK_attr_.actPrio = p; - QK_attr_.actThre = a->pthre; - - #if (defined QF_ON_CONTEXT_SW) || (defined Q_SPY) - if (p != pprev) { /* changing threads? */ - - QS_BEGIN_NOCRIT_PRE_(QS_SCHED_NEXT, p) - QS_TIME_PRE_(); /* timestamp */ - QS_2U8_PRE_(p, /* priority of the scheduled AO */ - pprev); /* previous priority */ - QS_END_NOCRIT_PRE_() - - #ifdef QF_ON_CONTEXT_SW - QF_onContextSw(((pprev != 0U) - ? QActive_registry_[pprev] - : (QActive *)0), a); - #endif /* QF_ON_CONTEXT_SW */ - - pprev = p; /* update previous priority */ - } - #endif /* QF_ON_CONTEXT_SW || Q_SPY */ - - QF_INT_ENABLE(); /* unconditionally enable interrupts */ - - /* perform the run-to-completion (RTC) step... - * 1. retrieve the event from the AO's event queue, which by this - * time must be non-empty and QActive_get_() asserts it. - * 2. dispatch the event to the AO's state machine. - * 3. determine if event is garbage and collect it if so - */ - QEvt const * const e = QActive_get_(a); - QHSM_DISPATCH(&a->super, e, p); - #if (QF_MAX_EPOOL > 0U) - QF_gc(e); - #endif - - /* determine the next highest-priority AO ready to run... */ - QF_INT_DISABLE(); /* unconditionally disable interrupts */ - - if (a->eQueue.frontEvt == (QEvt *)0) { /* empty queue? */ - QPSet_remove(&QF_readySet_, p); - } - - if (QPSet_isEmpty(&QF_readySet_)) { - p = 0U; /* no activation needed */ - } - else { - /* find new highest-prio AO ready to run... */ - p = (uint8_t)QPSet_findMax(&QF_readySet_); - - /* is the new priority below the initial preemption-threshold? */ - if (p <= QActive_registry_[prio_in]->pthre) { - p = 0U; /* no activation needed */ - } - /* is the AO's priority below the lock preemption-ceiling? */ - else if (p <= QK_attr_.lockCeil) { - p = 0U; /* no activation needed */ - } - else { - Q_ASSERT_ID(510, p <= QF_MAX_ACTIVE); - } - } - } while (p != 0U); - - /* restore the active priority and preemption-threshold */ - QK_attr_.actPrio = prio_in; - QK_attr_.actThre = QActive_registry_[prio_in]->pthre; - - #if (defined QF_ON_CONTEXT_SW) || (defined Q_SPY) - if (prio_in != 0U) { /* resuming an active object? */ - a = QActive_registry_[prio_in]; /* pointer to the preempted AO */ - - QS_BEGIN_NOCRIT_PRE_(QS_SCHED_NEXT, prio_in) - QS_TIME_PRE_(); /* timestamp */ - /* priority of the resumed AO, previous priority */ - QS_2U8_PRE_(prio_in, pprev); - QS_END_NOCRIT_PRE_() - } - else { /* resuming priority==0 --> idle */ - a = (QActive *)0; /* QK idle loop */ - - QS_BEGIN_NOCRIT_PRE_(QS_SCHED_IDLE, pprev) - QS_TIME_PRE_(); /* timestamp */ - QS_U8_PRE_(pprev); /* previous priority */ - QS_END_NOCRIT_PRE_() - } - - #ifdef QF_ON_CONTEXT_SW - QF_onContextSw(QActive_registry_[pprev], a); - #endif /* QF_ON_CONTEXT_SW */ - - #endif /* QF_ON_CONTEXT_SW || Q_SPY */ -} -/*$enddef${QK::QK-extern-C} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$enddef${QK::QActive} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/src/qs/qs.c b/src/qs/qs.c index b2109b18..e085ec99 100644 --- a/src/qs/qs.c +++ b/src/qs/qs.c @@ -1,78 +1,72 @@ -/*$file${src::qs::qs.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* -* Model: qpc.qm -* File: ${src::qs::qs.c} -* -* This code has been generated by QM 5.2.4 . -* DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. -* -* This code is covered by the following QP license: -* License # : LicenseRef-QL-dual -* Issued to : Any user of the QP/C real-time embedded framework -* Framework(s) : qpc -* Support ends : 2023-12-31 -* License scope: -* -* Copyright (C) 2005 Quantum Leaps, LLC . -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -*/ -/*$endhead${src::qs::qs.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*! @file -* @brief QS software tracing services -*/ -#define QP_IMPL /* this is QP implementation */ -#include "qs_port.h" /* QS port */ -#include "qs_pkg.h" /* QS package-scope interface */ -#include "qstamp.h" /* QP time-stamp */ -#include "qassert.h" /* QP embedded systems-friendly assertions */ +//$file${src::qs::qs.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// +// Model: qpc.qm +// File: ${src::qs::qs.c} +// +// This code has been generated by QM 5.3.0 . +// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. +// +// This code is covered by the following QP license: +// License # : LicenseRef-QL-dual +// Issued to : Any user of the QP/C real-time embedded framework +// Framework(s) : qpc +// Support ends : 2024-12-31 +// License scope: +// +// Copyright (C) 2005 Quantum Leaps, LLC . +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +// +//$endhead${src::qs::qs.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +#define QP_IMPL // this is QP implementation +#include "qs_port.h" // QS port +#include "qs_pkg.h" // QS package-scope interface +#include "qstamp.h" // QP time-stamp +#include "qsafe.h" // QP Functional Safety (FuSa) Subsystem Q_DEFINE_THIS_MODULE("qs") -/* ensure that the predefined records don't overlap the -* user records (application-specific). -*/ +// ensure that the predefined records don't overlap the +// user records (application-specific). Q_ASSERT_STATIC((enum_t)QS_PRE_MAX <= (enum_t)QS_USER); -/*==========================================================================*/ -/*$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* Check for the minimum required QP version */ -#if (QP_VERSION < 700U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) -#error qpc version 7.0.0 or higher required +//$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// Check for the minimum required QP version +#if (QP_VERSION < 730U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) +#error qpc version 7.3.0 or higher required #endif -/*$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -/*$define${QS::QS-tx} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//$define${QS::QS-TX} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/*${QS::QS-tx::priv_} ......................................................*/ -QS_tx QS_priv_; - -/*${QS::QS-tx::initBuf} ....................................................*/ +//${QS::QS-TX::initBuf} ...................................................... +//! @static @public @memberof QS void QS_initBuf( uint8_t * const sto, uint_fast32_t const stoSize) { - /* the provided buffer must be at least 8 bytes long */ - Q_REQUIRE_ID(100, stoSize > 8U); - QS_priv_.buf = &sto[0]; QS_priv_.end = (QSCtr)stoSize; QS_priv_.head = 0U; @@ -82,49 +76,51 @@ void QS_initBuf( QS_priv_.chksum = 0U; QS_priv_.critNest = 0U; - QS_glbFilter_(-(int_fast16_t)QS_ALL_RECORDS); /* all global filters OFF */ - QS_locFilter_((int_fast16_t)QS_ALL_IDS); /* all local filters ON */ - QS_priv_.locFilter_AP = (void *)0; /* deprecated "AP-filter" */ + QS_glbFilter_(-(int_fast16_t)QS_ALL_RECORDS); // all global filters OFF + QS_locFilter_((int_fast16_t)QS_ALL_IDS); // all local filters ON + QS_priv_.locFilter_AP = (void *)0; // deprecated "AP-filter" - /* produce an empty record to "flush" the QS trace buffer */ + // produce an empty record to "flush" the QS trace buffer QS_beginRec_((uint_fast8_t)QS_EMPTY); QS_endRec_(); - /* produce the reset record to inform QSPY of a new session */ - QS_target_info_pre_(0xFFU); /* send Reset and Target info */ + // produce the reset record to inform QSPY of a new session + QS_target_info_pre_(0xFFU); - /* hold off flushing after successfull initialization (see QS_INIT()) */ + // hold off flushing after successfull initialization (see QS_INIT()) } -/*${QS::QS-tx::getByte} ....................................................*/ +//${QS::QS-TX::getByte} ...................................................... +//! @static @public @memberof QS uint16_t QS_getByte(void) { uint16_t ret; if (QS_priv_.used == 0U) { - ret = QS_EOD; /* set End-Of-Data */ + ret = QS_EOD; // set End-Of-Data } else { - uint8_t const * const buf = QS_priv_.buf; /* put in a temporary */ - QSCtr tail = QS_priv_.tail; /* put in a temporary (register) */ - ret = (uint16_t)buf[tail]; /* set the byte to return */ - ++tail; /* advance the tail */ - if (tail == QS_priv_.end) { /* tail wrap around? */ + uint8_t const * const buf = QS_priv_.buf; // put in a temporary + QSCtr tail = QS_priv_.tail; // put in a temporary (register) + ret = (uint16_t)buf[tail]; // set the byte to return + ++tail; // advance the tail + if (tail == QS_priv_.end) { // tail wrap around? tail = 0U; } - QS_priv_.tail = tail; /* update the tail */ - --QS_priv_.used; /* one less byte used */ + QS_priv_.tail = tail; // update the tail + --QS_priv_.used; // one less byte used } - return ret; /* return the byte or EOD */ + return ret; // return the byte or EOD } -/*${QS::QS-tx::getBlock} ...................................................*/ +//${QS::QS-TX::getBlock} ..................................................... +//! @static @public @memberof QS uint8_t const * QS_getBlock(uint16_t * const pNbytes) { - QSCtr const used = QS_priv_.used; /* put in a temporary (register) */ + QSCtr const used = QS_priv_.used; // put in a temporary (register) uint8_t const *buf; - /* any bytes used in the ring buffer? */ + // any bytes used in the ring buffer? if (used != 0U) { - QSCtr tail = QS_priv_.tail; /* put in a temporary (register) */ - QSCtr const end = QS_priv_.end; /* put in a temporary (register) */ + QSCtr tail = QS_priv_.tail; // put in a temporary (register) + QSCtr const end = QS_priv_.end; // put in a temporary (register) QSCtr n = (QSCtr)(end - tail); if (n > used) { n = used; @@ -132,8 +128,8 @@ uint8_t const * QS_getBlock(uint16_t * const pNbytes) { if (n > (QSCtr)(*pNbytes)) { n = (QSCtr)(*pNbytes); } - *pNbytes = (uint16_t)n; /* n-bytes available */ - buf = &QS_priv_.buf[tail]; /* the bytes are at the tail */ + *pNbytes = (uint16_t)n; // n-bytes available + buf = &QS_priv_.buf[tail]; // the bytes are at the tail QS_priv_.used = (QSCtr)(used - n); tail += n; @@ -142,302 +138,321 @@ uint8_t const * QS_getBlock(uint16_t * const pNbytes) { } QS_priv_.tail = tail; } - - else { /* no bytes available */ - *pNbytes = 0U; /* no bytes available right now */ - buf = (uint8_t *)0; /* no bytes available right now */ + else { // no bytes available + *pNbytes = 0U; // no bytes available right now + buf = (uint8_t *)0; // no bytes available right now } return buf; } +//$enddef${QS::QS-TX} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -/*${QS::QS-tx::glbFilter_} .................................................*/ +#ifndef QF_MEM_ISOLATE +//$define${QS::filters} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${QS::filters::filt_} ...................................................... +QS_Filter QS_filt_; +//$enddef${QS::filters} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +#endif + +//============================================================================ +//! @cond INTERNAL + +//! @static @private @memberof QS +QS_Attr QS_priv_; + +//............................................................................ void QS_glbFilter_(int_fast16_t const filter) { bool const isRemove = (filter < 0); uint8_t const rec = isRemove ? (uint8_t)(-filter) : (uint8_t)filter; switch (rec) { - case QS_ALL_RECORDS: { + case (uint8_t)QS_ALL_RECORDS: { uint8_t const tmp = (isRemove ? 0x00U : 0xFFU); - /* set all global filters (partially unrolled loop) */ + + // set all global filters (partially unrolled loop) for (uint_fast8_t i = 0U; - i < Q_DIM(QS_priv_.glbFilter); + i < Q_DIM(QS_filt_.glb); i += 4U) { - QS_priv_.glbFilter[i ] = tmp; - QS_priv_.glbFilter[i + 1U] = tmp; - QS_priv_.glbFilter[i + 2U] = tmp; - QS_priv_.glbFilter[i + 3U] = tmp; + QS_filt_.glb[i ] = tmp; + QS_filt_.glb[i + 1U] = tmp; + QS_filt_.glb[i + 2U] = tmp; + QS_filt_.glb[i + 3U] = tmp; } if (isRemove) { - /* leave the "not maskable" filters enabled, - * see qs.h, Miscellaneous QS records (not maskable) - */ - QS_priv_.glbFilter[0] = 0x01U; - QS_priv_.glbFilter[6] = 0x40U; - QS_priv_.glbFilter[7] = 0xFCU; - QS_priv_.glbFilter[8] = 0x7FU; + // leave the "not maskable" filters enabled, + // see qs.h, Miscellaneous QS records (not maskable) + QS_filt_.glb[0] = 0x01U; + QS_filt_.glb[6] = 0x40U; + QS_filt_.glb[7] = 0xFCU; + QS_filt_.glb[8] = 0x7FU; } else { - /* never turn the last 3 records on (0x7D, 0x7E, 0x7F) */ - QS_priv_.glbFilter[15] = 0x1FU; + // never turn the last 3 records on (0x7D, 0x7E, 0x7F) + QS_filt_.glb[15] = 0x1FU; } break; } - case QS_SM_RECORDS: + case (uint8_t)QS_SM_RECORDS: if (isRemove) { - QS_priv_.glbFilter[0] &= (uint8_t)(~0xFEU & 0xFFU); - QS_priv_.glbFilter[1] &= (uint8_t)(~0x03U & 0xFFU); - QS_priv_.glbFilter[6] &= (uint8_t)(~0x80U & 0xFFU); - QS_priv_.glbFilter[7] &= (uint8_t)(~0x03U & 0xFFU); + QS_filt_.glb[0] &= (uint8_t)(~0xFEU & 0xFFU); + QS_filt_.glb[1] &= (uint8_t)(~0x03U & 0xFFU); + QS_filt_.glb[6] &= (uint8_t)(~0x80U & 0xFFU); + QS_filt_.glb[7] &= (uint8_t)(~0x03U & 0xFFU); } else { - QS_priv_.glbFilter[0] |= 0xFEU; - QS_priv_.glbFilter[1] |= 0x03U; - QS_priv_.glbFilter[6] |= 0x80U; - QS_priv_.glbFilter[7] |= 0x03U; + QS_filt_.glb[0] |= 0xFEU; + QS_filt_.glb[1] |= 0x03U; + QS_filt_.glb[6] |= 0x80U; + QS_filt_.glb[7] |= 0x03U; } break; - case QS_AO_RECORDS: + case (uint8_t)QS_AO_RECORDS: if (isRemove) { - QS_priv_.glbFilter[1] &= (uint8_t)(~0xFCU & 0xFFU); - QS_priv_.glbFilter[2] &= (uint8_t)(~0x07U & 0xFFU); - QS_priv_.glbFilter[5] &= (uint8_t)(~0x20U & 0xFFU); + QS_filt_.glb[1] &= (uint8_t)(~0xFCU & 0xFFU); + QS_filt_.glb[2] &= (uint8_t)(~0x07U & 0xFFU); + QS_filt_.glb[5] &= (uint8_t)(~0x20U & 0xFFU); } else { - QS_priv_.glbFilter[1] |= 0xFCU; - QS_priv_.glbFilter[2] |= 0x07U; - QS_priv_.glbFilter[5] |= 0x20U; + QS_filt_.glb[1] |= 0xFCU; + QS_filt_.glb[2] |= 0x07U; + QS_filt_.glb[5] |= 0x20U; } break; - case QS_EQ_RECORDS: + case (uint8_t)QS_EQ_RECORDS: if (isRemove) { - QS_priv_.glbFilter[2] &= (uint8_t)(~0x78U & 0xFFU); - QS_priv_.glbFilter[5] &= (uint8_t)(~0x40U & 0xFFU); + QS_filt_.glb[2] &= (uint8_t)(~0x78U & 0xFFU); + QS_filt_.glb[5] &= (uint8_t)(~0x40U & 0xFFU); } else { - QS_priv_.glbFilter[2] |= 0x78U; - QS_priv_.glbFilter[5] |= 0x40U; + QS_filt_.glb[2] |= 0x78U; + QS_filt_.glb[5] |= 0x40U; } break; - case QS_MP_RECORDS: + case (uint8_t)QS_MP_RECORDS: if (isRemove) { - QS_priv_.glbFilter[3] &= (uint8_t)(~0x03U & 0xFFU); - QS_priv_.glbFilter[5] &= (uint8_t)(~0x80U & 0xFFU); + QS_filt_.glb[3] &= (uint8_t)(~0x03U & 0xFFU); + QS_filt_.glb[5] &= (uint8_t)(~0x80U & 0xFFU); } else { - QS_priv_.glbFilter[3] |= 0x03U; - QS_priv_.glbFilter[5] |= 0x80U; + QS_filt_.glb[3] |= 0x03U; + QS_filt_.glb[5] |= 0x80U; } break; - case QS_QF_RECORDS: + case (uint8_t)QS_QF_RECORDS: if (isRemove) { - QS_priv_.glbFilter[2] &= (uint8_t)(~0x80U & 0xFFU); - QS_priv_.glbFilter[3] &= (uint8_t)(~0xFCU & 0xFFU); - QS_priv_.glbFilter[4] &= (uint8_t)(~0xC0U & 0xFFU); - QS_priv_.glbFilter[5] &= (uint8_t)(~0x1FU & 0xFFU); + QS_filt_.glb[2] &= (uint8_t)(~0x80U & 0xFFU); + QS_filt_.glb[3] &= (uint8_t)(~0xFCU & 0xFFU); + QS_filt_.glb[4] &= (uint8_t)(~0xC0U & 0xFFU); + QS_filt_.glb[5] &= (uint8_t)(~0x1FU & 0xFFU); } else { - QS_priv_.glbFilter[2] |= 0x80U; - QS_priv_.glbFilter[3] |= 0xFCU; - QS_priv_.glbFilter[4] |= 0xC0U; - QS_priv_.glbFilter[5] |= 0x1FU; + QS_filt_.glb[2] |= 0x80U; + QS_filt_.glb[3] |= 0xFCU; + QS_filt_.glb[4] |= 0xC0U; + QS_filt_.glb[5] |= 0x1FU; } break; - case QS_TE_RECORDS: + case (uint8_t)QS_TE_RECORDS: if (isRemove) { - QS_priv_.glbFilter[4] &= (uint8_t)(~0x3FU & 0xFFU); + QS_filt_.glb[4] &= (uint8_t)(~0x3FU & 0xFFU); } else { - QS_priv_.glbFilter[4] |= 0x3FU; + QS_filt_.glb[4] |= 0x3FU; } break; - case QS_SC_RECORDS: + case (uint8_t)QS_SC_RECORDS: if (isRemove) { - QS_priv_.glbFilter[6] &= (uint8_t)(~0x3FU & 0xFFU); + QS_filt_.glb[6] &= (uint8_t)(~0x3FU & 0xFFU); } else { - QS_priv_.glbFilter[6] |= 0x3FU; + QS_filt_.glb[6] |= 0x3FU; } break; - case QS_SEM_RECORDS: + case (uint8_t)QS_SEM_RECORDS: if (isRemove) { - QS_priv_.glbFilter[8] &= (uint8_t)(~0x80U & 0xFFU); - QS_priv_.glbFilter[9] &= (uint8_t)(~0x07U & 0xFFU); + QS_filt_.glb[8] &= (uint8_t)(~0x80U & 0xFFU); + QS_filt_.glb[9] &= (uint8_t)(~0x07U & 0xFFU); } else { - QS_priv_.glbFilter[8] |= 0x80U; - QS_priv_.glbFilter[9] |= 0x07U; + QS_filt_.glb[8] |= 0x80U; + QS_filt_.glb[9] |= 0x07U; } break; - case QS_MTX_RECORDS: + case (uint8_t)QS_MTX_RECORDS: if (isRemove) { - QS_priv_.glbFilter[9] &= (uint8_t)(~0xF8U & 0xFFU); - QS_priv_.glbFilter[10] &= (uint8_t)(~0x01U & 0xFFU); + QS_filt_.glb[9] &= (uint8_t)(~0xF8U & 0xFFU); + QS_filt_.glb[10] &= (uint8_t)(~0x01U & 0xFFU); } else { - QS_priv_.glbFilter[9] |= 0xF8U; - QS_priv_.glbFilter[10] |= 0x01U; + QS_filt_.glb[9] |= 0xF8U; + QS_filt_.glb[10] |= 0x01U; } break; - case QS_U0_RECORDS: + case (uint8_t)QS_U0_RECORDS: if (isRemove) { - QS_priv_.glbFilter[12] &= (uint8_t)(~0xF0U & 0xFFU); - QS_priv_.glbFilter[13] &= (uint8_t)(~0x01U & 0xFFU); + QS_filt_.glb[12] &= (uint8_t)(~0xF0U & 0xFFU); + QS_filt_.glb[13] &= (uint8_t)(~0x01U & 0xFFU); } else { - QS_priv_.glbFilter[12] |= 0xF0U; - QS_priv_.glbFilter[13] |= 0x01U; + QS_filt_.glb[12] |= 0xF0U; + QS_filt_.glb[13] |= 0x01U; } break; - case QS_U1_RECORDS: + case (uint8_t)QS_U1_RECORDS: if (isRemove) { - QS_priv_.glbFilter[13] &= (uint8_t)(~0x3EU & 0xFFU); + QS_filt_.glb[13] &= (uint8_t)(~0x3EU & 0xFFU); } else { - QS_priv_.glbFilter[13] |= 0x3EU; + QS_filt_.glb[13] |= 0x3EU; } break; - case QS_U2_RECORDS: + case (uint8_t)QS_U2_RECORDS: if (isRemove) { - QS_priv_.glbFilter[13] &= (uint8_t)(~0xC0U & 0xFFU); - QS_priv_.glbFilter[14] &= (uint8_t)(~0x07U & 0xFFU); + QS_filt_.glb[13] &= (uint8_t)(~0xC0U & 0xFFU); + QS_filt_.glb[14] &= (uint8_t)(~0x07U & 0xFFU); } else { - QS_priv_.glbFilter[13] |= 0xC0U; - QS_priv_.glbFilter[14] |= 0x07U; + QS_filt_.glb[13] |= 0xC0U; + QS_filt_.glb[14] |= 0x07U; } break; - case QS_U3_RECORDS: + case (uint8_t)QS_U3_RECORDS: if (isRemove) { - QS_priv_.glbFilter[14] &= (uint8_t)(~0xF8U & 0xFFU); + QS_filt_.glb[14] &= (uint8_t)(~0xF8U & 0xFFU); } else { - QS_priv_.glbFilter[14] |= 0xF8U; + QS_filt_.glb[14] |= 0xF8U; } break; - case QS_U4_RECORDS: + case (uint8_t)QS_U4_RECORDS: if (isRemove) { - QS_priv_.glbFilter[15] &= 0x1FU; + QS_filt_.glb[15] &= 0x1FU; } else { - QS_priv_.glbFilter[15] |= 0x1FU; + QS_filt_.glb[15] |= 0x1FU; } break; - case QS_UA_RECORDS: + case (uint8_t)QS_UA_RECORDS: if (isRemove) { - QS_priv_.glbFilter[12] &= (uint8_t)(~0xF0U & 0xFFU); - QS_priv_.glbFilter[13] = 0U; - QS_priv_.glbFilter[14] = 0U; - QS_priv_.glbFilter[15] &= (uint8_t)(~0x1FU & 0xFFU); + QS_filt_.glb[12] &= (uint8_t)(~0xF0U & 0xFFU); + QS_filt_.glb[13] = 0U; + QS_filt_.glb[14] = 0U; + QS_filt_.glb[15] &= (uint8_t)(~0x1FU & 0xFFU); } else { - QS_priv_.glbFilter[12] |= 0xF0U; - QS_priv_.glbFilter[13] |= 0xFFU; - QS_priv_.glbFilter[14] |= 0xFFU; - QS_priv_.glbFilter[15] |= 0x1FU; + QS_filt_.glb[12] |= 0xF0U; + QS_filt_.glb[13] |= 0xFFU; + QS_filt_.glb[14] |= 0xFFU; + QS_filt_.glb[15] |= 0x1FU; } break; - default: - /* QS rec number can't exceed 0x7D, so no need for escaping */ - Q_ASSERT_ID(210, rec < 0x7DU); + default: { + QS_CRIT_STAT + QS_CRIT_ENTRY(); + // QS rec number must be below 0x7D, so no need for escaping + Q_ASSERT_INCRIT(210, rec < 0x7DU); + QS_CRIT_EXIT(); if (isRemove) { - QS_priv_.glbFilter[rec >> 3U] + QS_filt_.glb[rec >> 3U] &= (uint8_t)(~(1U << (rec & 7U)) & 0xFFU); } else { - QS_priv_.glbFilter[rec >> 3U] + QS_filt_.glb[rec >> 3U] |= (1U << (rec & 7U)); - /* never turn the last 3 records on (0x7D, 0x7E, 0x7F) */ - QS_priv_.glbFilter[15] &= 0x1FU; + // never turn the last 3 records on (0x7D, 0x7E, 0x7F) + QS_filt_.glb[15] &= 0x1FU; } break; + } } } -/*${QS::QS-tx::locFilter_} .................................................*/ +//............................................................................ void QS_locFilter_(int_fast16_t const filter) { bool const isRemove = (filter < 0); uint8_t const qs_id = isRemove ? (uint8_t)(-filter) : (uint8_t)filter; uint8_t const tmp = (isRemove ? 0x00U : 0xFFU); uint_fast8_t i; switch (qs_id) { - case QS_ALL_IDS: - /* set all local filters (partially unrolled loop) */ - for (i = 0U; i < Q_DIM(QS_priv_.locFilter); i += 4U) { - QS_priv_.locFilter[i ] = tmp; - QS_priv_.locFilter[i + 1U] = tmp; - QS_priv_.locFilter[i + 2U] = tmp; - QS_priv_.locFilter[i + 3U] = tmp; + case (uint8_t)QS_ALL_IDS: + // set all local filters (partially unrolled loop) + for (i = 0U; i < Q_DIM(QS_filt_.loc); i += 4U) { + QS_filt_.loc[i ] = tmp; + QS_filt_.loc[i + 1U] = tmp; + QS_filt_.loc[i + 2U] = tmp; + QS_filt_.loc[i + 3U] = tmp; } break; - case QS_AO_IDS: + case (uint8_t)QS_AO_IDS: for (i = 0U; i < 8U; i += 4U) { - QS_priv_.locFilter[i ] = tmp; - QS_priv_.locFilter[i + 1U] = tmp; - QS_priv_.locFilter[i + 2U] = tmp; - QS_priv_.locFilter[i + 3U] = tmp; + QS_filt_.loc[i ] = tmp; + QS_filt_.loc[i + 1U] = tmp; + QS_filt_.loc[i + 2U] = tmp; + QS_filt_.loc[i + 3U] = tmp; } break; - case QS_EP_IDS: + case (uint8_t)QS_EP_IDS: i = 8U; - QS_priv_.locFilter[i ] = tmp; - QS_priv_.locFilter[i + 1U] = tmp; + QS_filt_.loc[i ] = tmp; + QS_filt_.loc[i + 1U] = tmp; break; - case QS_AP_IDS: + case (uint8_t)QS_AP_IDS: i = 12U; - QS_priv_.locFilter[i ] = tmp; - QS_priv_.locFilter[i + 1U] = tmp; - QS_priv_.locFilter[i + 2U] = tmp; - QS_priv_.locFilter[i + 3U] = tmp; + QS_filt_.loc[i ] = tmp; + QS_filt_.loc[i + 1U] = tmp; + QS_filt_.loc[i + 2U] = tmp; + QS_filt_.loc[i + 3U] = tmp; break; - default: - if (qs_id < 0x7FU) { - if (isRemove) { - QS_priv_.locFilter[qs_id >> 3U] - &= (uint8_t)(~(1U << (qs_id & 7U)) & 0xFFU); - } - else { - QS_priv_.locFilter[qs_id >> 3U] - |= (1U << (qs_id & 7U)); - } + default: { + QS_CRIT_STAT + QS_CRIT_ENTRY(); + // qs_id must be in range + Q_ASSERT_INCRIT(310, qs_id < 0x7FU); + QS_CRIT_EXIT(); + if (isRemove) { + QS_filt_.loc[qs_id >> 3U] + &= (uint8_t)(~(1U << (qs_id & 7U)) & 0xFFU); } else { - Q_ERROR_ID(310); /* incorrect qs_id */ + QS_filt_.loc[qs_id >> 3U] + |= (1U << (qs_id & 7U)); } break; + } } - QS_priv_.locFilter[0] |= 0x01U; /* leave QS_ID == 0 always on */ + QS_filt_.loc[0] |= 0x01U; // leave QS_ID == 0 always on } -/*${QS::QS-tx::beginRec_} ..................................................*/ +//............................................................................ void QS_beginRec_(uint_fast8_t const rec) { uint8_t const b = (uint8_t)(QS_priv_.seq + 1U); - uint8_t chksum = 0U; /* reset the checksum */ - uint8_t * const buf = QS_priv_.buf; /* put in a temporary (register) */ - QSCtr head = QS_priv_.head; /* put in a temporary (register) */ - QSCtr const end = QS_priv_.end; /* put in a temporary (register) */ + uint8_t chksum = 0U; // reset the checksum + uint8_t * const buf = QS_priv_.buf; // put in a temporary (register) + QSCtr head = QS_priv_.head; // put in a temporary (register) + QSCtr const end = QS_priv_.end; // put in a temporary (register) - QS_priv_.seq = b; /* store the incremented sequence num */ - QS_priv_.used += 2U; /* 2 bytes about to be added */ + QS_priv_.seq = b; // store the incremented sequence num + QS_priv_.used += 2U; // 2 bytes about to be added QS_INSERT_ESC_BYTE_(b) - chksum = (uint8_t)(chksum + rec); /* update checksum */ - QS_INSERT_BYTE_((uint8_t)rec) /* rec byte does not need escaping */ + chksum = (uint8_t)(chksum + rec); // update checksum + QS_INSERT_BYTE_((uint8_t)rec) // rec byte does not need escaping - QS_priv_.head = head; /* save the head */ - QS_priv_.chksum = chksum; /* save the checksum */ + QS_priv_.head = head; // save the head + QS_priv_.chksum = chksum; // save the checksum } -/*${QS::QS-tx::endRec_} ....................................................*/ +//............................................................................ void QS_endRec_(void) { - uint8_t * const buf = QS_priv_.buf; /* put in a temporary (register) */ + uint8_t * const buf = QS_priv_.buf; // put in a temporary (register) QSCtr head = QS_priv_.head; QSCtr const end = QS_priv_.end; uint8_t b = QS_priv_.chksum; - b ^= 0xFFU; /* invert the bits in the checksum */ + b ^= 0xFFU; // invert the bits in the checksum - QS_priv_.used += 2U; /* 2 bytes about to be added */ + QS_priv_.used += 2U; // 2 bytes about to be added if ((b != QS_FRAME) && (b != QS_ESC)) { QS_INSERT_BYTE_(b) @@ -445,89 +460,89 @@ void QS_endRec_(void) { else { QS_INSERT_BYTE_(QS_ESC) QS_INSERT_BYTE_(b ^ QS_ESC_XOR) - ++QS_priv_.used; /* account for the ESC byte */ + ++QS_priv_.used; // account for the ESC byte } - QS_INSERT_BYTE_(QS_FRAME) /* do not escape this QS_FRAME */ + QS_INSERT_BYTE_(QS_FRAME) // do not escape this QS_FRAME - QS_priv_.head = head; /* save the head */ + QS_priv_.head = head; // save the head - /* overrun over the old data? */ + // overrun over the old data? if (QS_priv_.used > end) { - QS_priv_.used = end; /* the whole buffer is used */ - QS_priv_.tail = head; /* shift the tail to the old data */ + QS_priv_.used = end; // the whole buffer is used + QS_priv_.tail = head; // shift the tail to the old data } } -/*${QS::QS-tx::u8_raw_} ....................................................*/ +//............................................................................ void QS_u8_raw_(uint8_t const d) { - uint8_t chksum = QS_priv_.chksum; /* put in a temporary (register) */ - uint8_t * const buf = QS_priv_.buf; /* put in a temporary (register) */ - QSCtr head = QS_priv_.head; /* put in a temporary (register) */ - QSCtr const end = QS_priv_.end; /* put in a temporary (register) */ + uint8_t chksum = QS_priv_.chksum; // put in a temporary (register) + uint8_t * const buf = QS_priv_.buf; // put in a temporary (register) + QSCtr head = QS_priv_.head; // put in a temporary (register) + QSCtr const end = QS_priv_.end; // put in a temporary (register) - QS_priv_.used += 1U; /* 1 byte about to be added */ + QS_priv_.used += 1U; // 1 byte about to be added QS_INSERT_ESC_BYTE_(d) - QS_priv_.head = head; /* save the head */ - QS_priv_.chksum = chksum; /* save the checksum */ + QS_priv_.head = head; // save the head + QS_priv_.chksum = chksum; // save the checksum } -/*${QS::QS-tx::2u8_raw_} ...................................................*/ +//............................................................................ void QS_2u8_raw_( uint8_t const d1, uint8_t const d2) { - uint8_t chksum = QS_priv_.chksum; /* put in a temporary (register) */ - uint8_t * const buf = QS_priv_.buf; /* put in a temporary (register) */ - QSCtr head = QS_priv_.head; /* put in a temporary (register) */ - QSCtr const end = QS_priv_.end; /* put in a temporary (register) */ + uint8_t chksum = QS_priv_.chksum; // put in a temporary (register) + uint8_t * const buf = QS_priv_.buf; // put in a temporary (register) + QSCtr head = QS_priv_.head; // put in a temporary (register) + QSCtr const end = QS_priv_.end; // put in a temporary (register) - QS_priv_.used += 2U; /* 2 bytes are about to be added */ + QS_priv_.used += 2U; // 2 bytes are about to be added QS_INSERT_ESC_BYTE_(d1) QS_INSERT_ESC_BYTE_(d2) - QS_priv_.head = head; /* save the head */ - QS_priv_.chksum = chksum; /* save the checksum */ + QS_priv_.head = head; // save the head + QS_priv_.chksum = chksum; // save the checksum } -/*${QS::QS-tx::u16_raw_} ...................................................*/ +//............................................................................ void QS_u16_raw_(uint16_t const d) { - uint8_t chksum = QS_priv_.chksum; /* put in a temporary (register) */ - uint8_t * const buf = QS_priv_.buf; /* put in a temporary (register) */ - QSCtr head = QS_priv_.head; /* put in a temporary (register) */ - QSCtr const end = QS_priv_.end; /* put in a temporary (register) */ + uint8_t chksum = QS_priv_.chksum; // put in a temporary (register) + uint8_t * const buf = QS_priv_.buf; // put in a temporary (register) + QSCtr head = QS_priv_.head; // put in a temporary (register) + QSCtr const end = QS_priv_.end; // put in a temporary (register) uint16_t x = d; - QS_priv_.used += 2U; /* 2 bytes are about to be added */ + QS_priv_.used += 2U; // 2 bytes are about to be added QS_INSERT_ESC_BYTE_((uint8_t)x) x >>= 8U; QS_INSERT_ESC_BYTE_((uint8_t)x) - QS_priv_.head = head; /* save the head */ - QS_priv_.chksum = chksum; /* save the checksum */ + QS_priv_.head = head; // save the head + QS_priv_.chksum = chksum; // save the checksum } -/*${QS::QS-tx::u32_raw_} ...................................................*/ +//............................................................................ void QS_u32_raw_(uint32_t const d) { - uint8_t chksum = QS_priv_.chksum; /* put in a temporary (register) */ - uint8_t * const buf = QS_priv_.buf; /* put in a temporary (register) */ - QSCtr head = QS_priv_.head; /* put in a temporary (register) */ - QSCtr const end = QS_priv_.end; /* put in a temporary (register) */ + uint8_t chksum = QS_priv_.chksum; // put in a temporary (register) + uint8_t * const buf = QS_priv_.buf; // put in a temporary (register) + QSCtr head = QS_priv_.head; // put in a temporary (register) + QSCtr const end = QS_priv_.end; // put in a temporary (register) uint32_t x = d; - QS_priv_.used += 4U; /* 4 bytes are about to be added */ + QS_priv_.used += 4U; // 4 bytes are about to be added for (uint_fast8_t i = 4U; i != 0U; --i) { QS_INSERT_ESC_BYTE_((uint8_t)x) x >>= 8U; } - QS_priv_.head = head; /* save the head */ - QS_priv_.chksum = chksum; /* save the checksum */ + QS_priv_.head = head; // save the head + QS_priv_.chksum = chksum; // save the checksum } -/*${QS::QS-tx::obj_raw_} ...................................................*/ +//............................................................................ void QS_obj_raw_(void const * const obj) { #if (QS_OBJ_PTR_SIZE == 1U) QS_u8_raw_((uint8_t)obj); @@ -542,211 +557,221 @@ void QS_obj_raw_(void const * const obj) { #endif } -/*${QS::QS-tx::str_raw_} ...................................................*/ +//............................................................................ void QS_str_raw_(char const * const str) { - uint8_t chksum = QS_priv_.chksum; /* put in a temporary (register) */ - uint8_t * const buf = QS_priv_.buf; /* put in a temporary (register) */ - QSCtr head = QS_priv_.head; /* put in a temporary (register) */ - QSCtr const end = QS_priv_.end; /* put in a temporary (register) */ - QSCtr used = QS_priv_.used; /* put in a temporary (register) */ + uint8_t chksum = QS_priv_.chksum; // put in a temporary (register) + uint8_t * const buf = QS_priv_.buf; // put in a temporary (register) + QSCtr head = QS_priv_.head; // put in a temporary (register) + QSCtr const end = QS_priv_.end; // put in a temporary (register) + QSCtr used = QS_priv_.used; // put in a temporary (register) for (char const *s = str; *s != '\0'; ++s) { - chksum += (uint8_t)*s; /* update checksum */ - QS_INSERT_BYTE_((uint8_t)*s) /* ASCII char doesn't need escaping */ + chksum += (uint8_t)*s; // update checksum + QS_INSERT_BYTE_((uint8_t)*s) // ASCII char doesn't need escaping ++used; } - QS_INSERT_BYTE_((uint8_t)'\0') /* zero-terminate the string */ + QS_INSERT_BYTE_((uint8_t)'\0') // zero-terminate the string ++used; - QS_priv_.head = head; /* save the head */ - QS_priv_.chksum = chksum; /* save the checksum */ - QS_priv_.used = used; /* save # of used buffer space */ + QS_priv_.head = head; // save the head + QS_priv_.chksum = chksum; // save the checksum + QS_priv_.used = used; // save # of used buffer space } -/*${QS::QS-tx::u8_fmt_} ....................................................*/ +//............................................................................ void QS_u8_fmt_( uint8_t const format, uint8_t const d) { - uint8_t chksum = QS_priv_.chksum; /* put in a temporary (register) */ - uint8_t * const buf = QS_priv_.buf; /* put in a temporary (register) */ - QSCtr head = QS_priv_.head; /* put in a temporary (register) */ - QSCtr const end = QS_priv_.end; /* put in a temporary (register) */ + uint8_t chksum = QS_priv_.chksum; // put in a temporary (register) + uint8_t * const buf = QS_priv_.buf; // put in a temporary (register) + QSCtr head = QS_priv_.head; // put in a temporary (register) + QSCtr const end = QS_priv_.end; // put in a temporary (register) - QS_priv_.used += 2U; /* 2 bytes about to be added */ + QS_priv_.used += 2U; // 2 bytes about to be added QS_INSERT_ESC_BYTE_(format) QS_INSERT_ESC_BYTE_(d) - QS_priv_.head = head; /* save the head */ - QS_priv_.chksum = chksum; /* save the checksum */ + QS_priv_.head = head; // save the head + QS_priv_.chksum = chksum; // save the checksum } -/*${QS::QS-tx::u16_fmt_} ...................................................*/ +//............................................................................ void QS_u16_fmt_( uint8_t const format, uint16_t const d) { - uint8_t chksum = QS_priv_.chksum; /* put in a temporary (register) */ - uint8_t * const buf = QS_priv_.buf; /* put in a temporary (register) */ - QSCtr head = QS_priv_.head; /* put in a temporary (register) */ - QSCtr const end = QS_priv_.end; /* put in a temporary (register) */ + uint8_t chksum = QS_priv_.chksum; // put in a temporary (register) + uint8_t * const buf = QS_priv_.buf; // put in a temporary (register) + QSCtr head = QS_priv_.head; // put in a temporary (register) + QSCtr const end = QS_priv_.end; // put in a temporary (register) uint8_t b = (uint8_t)d; - QS_priv_.used += 3U; /* 3 bytes about to be added */ + QS_priv_.used += 3U; // 3 bytes about to be added QS_INSERT_ESC_BYTE_(format) QS_INSERT_ESC_BYTE_(b) b = (uint8_t)(d >> 8U); QS_INSERT_ESC_BYTE_(b) - QS_priv_.head = head; /* save the head */ - QS_priv_.chksum = chksum; /* save the checksum */ + QS_priv_.head = head; // save the head + QS_priv_.chksum = chksum; // save the checksum } -/*${QS::QS-tx::u32_fmt_} ...................................................*/ +//............................................................................ void QS_u32_fmt_( uint8_t const format, uint32_t const d) { - uint8_t chksum = QS_priv_.chksum; /* put in a temporary (register) */ - uint8_t * const buf = QS_priv_.buf; /* put in a temporary (register) */ - QSCtr head = QS_priv_.head; /* put in a temporary (register) */ - QSCtr const end = QS_priv_.end; /* put in a temporary (register) */ + uint8_t chksum = QS_priv_.chksum; // put in a temporary (register) + uint8_t * const buf = QS_priv_.buf; // put in a temporary (register) + QSCtr head = QS_priv_.head; // put in a temporary (register) + QSCtr const end = QS_priv_.end; // put in a temporary (register) uint32_t x = d; - QS_priv_.used += 5U; /* 5 bytes about to be added */ - QS_INSERT_ESC_BYTE_(format) /* insert the format byte */ + QS_priv_.used += 5U; // 5 bytes about to be added + QS_INSERT_ESC_BYTE_(format) // insert the format byte - /* insert 4 bytes... */ + // insert 4 bytes... for (uint_fast8_t i = 4U; i != 0U; --i) { QS_INSERT_ESC_BYTE_((uint8_t)x) x >>= 8U; } - QS_priv_.head = head; /* save the head */ - QS_priv_.chksum = chksum; /* save the checksum */ + QS_priv_.head = head; // save the head + QS_priv_.chksum = chksum; // save the checksum } -/*${QS::QS-tx::str_fmt_} ...................................................*/ +//............................................................................ void QS_str_fmt_(char const * const str) { uint8_t chksum = QS_priv_.chksum; - uint8_t * const buf = QS_priv_.buf; /* put in a temporary (register) */ - QSCtr head = QS_priv_.head; /* put in a temporary (register) */ - QSCtr const end = QS_priv_.end; /* put in a temporary (register) */ - QSCtr used = QS_priv_.used; /* put in a temporary (register) */ + uint8_t * const buf = QS_priv_.buf; // put in a temporary (register) + QSCtr head = QS_priv_.head; // put in a temporary (register) + QSCtr const end = QS_priv_.end; // put in a temporary (register) + QSCtr used = QS_priv_.used; // put in a temporary (register) - used += 2U; /* account for the format byte and the terminating-0 */ + used += 2U; // account for the format byte and the terminating-0 QS_INSERT_BYTE_((uint8_t)QS_STR_T) chksum += (uint8_t)QS_STR_T; for (char const *s = str; *s != '\0'; ++s) { - QS_INSERT_BYTE_((uint8_t)*s) /* ASCII char doesn't need escaping */ - chksum += (uint8_t)*s; /* update checksum */ + QS_INSERT_BYTE_((uint8_t)*s) // ASCII char doesn't need escaping + chksum += (uint8_t)*s; // update checksum ++used; } - QS_INSERT_BYTE_(0U) /* zero-terminate the string */ + QS_INSERT_BYTE_(0U) // zero-terminate the string - QS_priv_.head = head; /* save the head */ - QS_priv_.chksum = chksum; /* save the checksum */ - QS_priv_.used = used; /* save # of used buffer space */ + QS_priv_.head = head; // save the head + QS_priv_.chksum = chksum; // save the checksum + QS_priv_.used = used; // save # of used buffer space } -/*${QS::QS-tx::mem_fmt_} ...................................................*/ +//............................................................................ void QS_mem_fmt_( uint8_t const * const blk, uint8_t const size) { uint8_t chksum = QS_priv_.chksum; - uint8_t * const buf = QS_priv_.buf; /* put in a temporary (register) */ - QSCtr head = QS_priv_.head; /* put in a temporary (register) */ - QSCtr const end = QS_priv_.end; /* put in a temporary (register) */ + uint8_t * const buf = QS_priv_.buf; // put in a temporary (register) + QSCtr head = QS_priv_.head; // put in a temporary (register) + QSCtr const end = QS_priv_.end; // put in a temporary (register) uint8_t const *pb = blk; - QS_priv_.used += ((QSCtr)size + 2U); /* size+2 bytes to be added */ + QS_priv_.used += ((QSCtr)size + 2U); // size+2 bytes to be added QS_INSERT_BYTE_((uint8_t)QS_MEM_T) chksum += (uint8_t)QS_MEM_T; QS_INSERT_ESC_BYTE_(size) - /* output the 'size' number of bytes */ + // output the 'size' # bytes for (uint8_t len = size; len > 0U; --len) { QS_INSERT_ESC_BYTE_(*pb) ++pb; } - QS_priv_.head = head; /* save the head */ - QS_priv_.chksum = chksum; /* save the checksum */ + QS_priv_.head = head; // save the head + QS_priv_.chksum = chksum; // save the checksum } -/*${QS::QS-tx::sig_dict_pre_} ..............................................*/ +//............................................................................ void QS_sig_dict_pre_( - enum_t const sig, + QSignal const sig, void const * const obj, char const * const name) { - QS_CRIT_STAT_ + QS_CRIT_STAT + QS_CRIT_ENTRY(); + QS_MEM_SYS(); - QS_CRIT_E_(); QS_beginRec_((uint_fast8_t)QS_SIG_DICT); QS_SIG_PRE_(sig); QS_OBJ_PRE_(obj); - QS_str_raw_((*name == '&') ? &name[1] : name); + QS_STR_PRE_((*name == '&') ? &name[1] : name); QS_endRec_(); - QS_CRIT_X_(); + + QS_MEM_APP(); + QS_CRIT_EXIT(); QS_onFlush(); } -/*${QS::QS-tx::obj_dict_pre_} ..............................................*/ +//............................................................................ void QS_obj_dict_pre_( void const * const obj, char const * const name) { - QS_CRIT_STAT_ + QS_CRIT_STAT + QS_CRIT_ENTRY(); + QS_MEM_SYS(); - QS_CRIT_E_(); QS_beginRec_((uint_fast8_t)QS_OBJ_DICT); QS_OBJ_PRE_(obj); - QS_str_raw_((*name == '&') ? &name[1] : name); + QS_STR_PRE_((*name == '&') ? &name[1] : name); QS_endRec_(); - QS_CRIT_X_(); + + QS_MEM_APP(); + QS_CRIT_EXIT(); QS_onFlush(); } -/*${QS::QS-tx::obj_arr_dict_pre_} ..........................................*/ +//............................................................................ void QS_obj_arr_dict_pre_( void const * const obj, uint_fast16_t const idx, char const * const name) { - Q_REQUIRE_ID(400, idx < 1000U); + QS_CRIT_STAT + QS_CRIT_ENTRY(); + Q_REQUIRE_INCRIT(400, idx < 1000U); + QS_CRIT_EXIT(); - /* format idx into a char buffer as "xxx\0" */ + // format idx into a char buffer as "xxx\0" uint8_t idx_str[4]; uint_fast16_t tmp = idx; uint8_t i; - idx_str[3] = 0U; /* zero-terminate */ + idx_str[3] = 0U; // zero-terminate idx_str[2] = (uint8_t)((uint8_t)'0' + (tmp % 10U)); tmp /= 10U; idx_str[1] = (uint8_t)((uint8_t)'0' + (tmp % 10U)); if (idx_str[1] == (uint8_t)'0') { - i = 2U; + i = 2U; } else { - tmp /= 10U; - idx_str[0] = (uint8_t)((uint8_t)'0' + (tmp % 10U)); + tmp /= 10U; + idx_str[0] = (uint8_t)((uint8_t)'0' + (tmp % 10U)); if (idx_str[0] == (uint8_t)'0') { - i = 1U; + i = 1U; } else { - i = 0U; + i = 0U; } } - QS_CRIT_STAT_ uint8_t j = ((*name == '&') ? 1U : 0U); - QS_CRIT_E_(); + QS_CRIT_ENTRY(); + QS_MEM_SYS(); + QS_beginRec_((uint_fast8_t)QS_OBJ_DICT); QS_OBJ_PRE_(obj); for (; name[j] != '\0'; ++j) { @@ -759,7 +784,7 @@ void QS_obj_arr_dict_pre_( for (; idx_str[i] != 0U; ++i) { QS_U8_PRE_(idx_str[i]); } - /* skip chars until ']' */ + // skip chars until ']' for (; name[j] != '\0'; ++j) { if (name[j] == ']') { break; @@ -768,81 +793,97 @@ void QS_obj_arr_dict_pre_( for (; name[j] != '\0'; ++j) { QS_U8_PRE_(name[j]); } - QS_U8_PRE_(0U); /* zero-terminate */ + QS_U8_PRE_(0U); // zero-terminate QS_endRec_(); - QS_CRIT_X_(); + + QS_MEM_APP(); + QS_CRIT_EXIT(); QS_onFlush(); } -/*${QS::QS-tx::fun_dict_pre_} ..............................................*/ +//............................................................................ void QS_fun_dict_pre_( QSpyFunPtr const fun, char const * const name) { - QS_CRIT_STAT_ + QS_CRIT_STAT + QS_CRIT_ENTRY(); + QS_MEM_SYS(); - QS_CRIT_E_(); QS_beginRec_((uint_fast8_t)QS_FUN_DICT); QS_FUN_PRE_(fun); - QS_str_raw_((*name == '&') ? &name[1] : name); + QS_STR_PRE_((*name == '&') ? &name[1] : name); QS_endRec_(); - QS_CRIT_X_(); + + QS_MEM_APP(); + QS_CRIT_EXIT(); QS_onFlush(); } -/*${QS::QS-tx::usr_dict_pre_} ..............................................*/ +//............................................................................ void QS_usr_dict_pre_( enum_t const rec, char const * const name) { - QS_CRIT_STAT_ + QS_CRIT_STAT + QS_CRIT_ENTRY(); + QS_MEM_SYS(); - QS_CRIT_E_(); QS_beginRec_((uint_fast8_t)QS_USR_DICT); - QS_u8_raw_((uint8_t)rec); - QS_str_raw_(name); + QS_U8_PRE_(rec); + QS_STR_PRE_(name); QS_endRec_(); - QS_CRIT_X_(); + + QS_MEM_APP(); + QS_CRIT_EXIT(); QS_onFlush(); } -/*${QS::QS-tx::enum_dict_pre_} .............................................*/ +//............................................................................ void QS_enum_dict_pre_( enum_t const value, uint8_t const group, char const * const name) { - QS_CRIT_STAT_ + QS_CRIT_STAT + QS_CRIT_ENTRY(); + QS_MEM_SYS(); - QS_CRIT_E_(); QS_beginRec_((uint_fast8_t)QS_ENUM_DICT); - QS_2U8_PRE_((uint8_t)value, group); - QS_str_raw_(name); + QS_2U8_PRE_(value, group); + QS_STR_PRE_(name); QS_endRec_(); - QS_CRIT_X_(); + + QS_MEM_APP(); + QS_CRIT_EXIT(); QS_onFlush(); } -/*${QS::QS-tx::ASSERTION} ..................................................*/ -void QS_ASSERTION( +//............................................................................ +void QS_assertion_pre_( char const * const module, - int_t const loc, + int_t const id, uint32_t const delay) { - QS_BEGIN_NOCRIT_PRE_(QS_ASSERT_FAIL, 0U) + // NOTE: called in a critical section + + QS_beginRec_((uint_fast8_t)QS_ASSERT_FAIL); QS_TIME_PRE_(); - QS_U16_PRE_(loc); + QS_U16_PRE_(id); QS_STR_PRE_((module != (char *)0) ? module : "?"); - QS_END_NOCRIT_PRE_() + QS_endRec_(); QS_onFlush(); - for (uint32_t volatile delay_ctr = delay; delay_ctr > 0U; --delay_ctr) { - } + for (uint32_t volatile delay_ctr = delay; + delay_ctr > 0U; --delay_ctr) + {} QS_onCleanup(); } -/*${QS::QS-tx::target_info_pre_} ...........................................*/ +//............................................................................ void QS_target_info_pre_(uint8_t const isReset) { + // NOTE: called in a critical section + static uint8_t const ZERO = (uint8_t)'0'; static uint8_t const * const TIME = (uint8_t const *)&Q_BUILD_TIME[0]; static uint8_t const * const DATE = (uint8_t const *)&Q_BUILD_DATE[0]; @@ -853,100 +894,101 @@ void QS_target_info_pre_(uint8_t const isReset) { endian_test.u16 = 0x0102U; QS_beginRec_((uint_fast8_t)QS_TARGET_INFO); - QS_U8_PRE_(isReset); - QS_U16_PRE_(((endian_test.u8[0] == 0x01U) /* big endian? */ - ? (0x8000U | QP_VERSION) - : QP_VERSION)); /* target endianness + version number */ + QS_U8_PRE_(isReset); + QS_U16_PRE_(((endian_test.u8[0] == 0x01U) // big endian? + ? (0x8000U | QP_VERSION) + : QP_VERSION)); // target endianness + version number - /* send the object sizes... */ - QS_U8_PRE_(Q_SIGNAL_SIZE | (QF_EVENT_SIZ_SIZE << 4U)); + // send the object sizes... + QS_U8_PRE_(Q_SIGNAL_SIZE | (QF_EVENT_SIZ_SIZE << 4U)); - #ifdef QF_EQUEUE_CTR_SIZE - QS_U8_PRE_(QF_EQUEUE_CTR_SIZE | (QF_TIMEEVT_CTR_SIZE << 4U)); - #else - QS_U8_PRE_(QF_TIMEEVT_CTR_SIZE << 4U); - #endif /* QF_EQUEUE_CTR_SIZE */ +#ifdef QF_EQUEUE_CTR_SIZE + QS_U8_PRE_(QF_EQUEUE_CTR_SIZE | (QF_TIMEEVT_CTR_SIZE << 4U)); +#else + QS_U8_PRE_(QF_TIMEEVT_CTR_SIZE << 4U); +#endif // QF_EQUEUE_CTR_SIZE - #ifdef QF_MPOOL_CTR_SIZE - QS_U8_PRE_(QF_MPOOL_SIZ_SIZE | (QF_MPOOL_CTR_SIZE << 4U)); - #else - QS_U8_PRE_(0U); - #endif /* QF_MPOOL_CTR_SIZE */ +#ifdef QF_MPOOL_CTR_SIZE + QS_U8_PRE_(QF_MPOOL_SIZ_SIZE | (QF_MPOOL_CTR_SIZE << 4U)); +#else + QS_U8_PRE_(0U); +#endif // QF_MPOOL_CTR_SIZE - QS_U8_PRE_(QS_OBJ_PTR_SIZE | (QS_FUN_PTR_SIZE << 4U)); - QS_U8_PRE_(QS_TIME_SIZE); + QS_U8_PRE_(QS_OBJ_PTR_SIZE | (QS_FUN_PTR_SIZE << 4U)); + QS_U8_PRE_(QS_TIME_SIZE); - /* send the limits... */ - QS_U8_PRE_(QF_MAX_ACTIVE); - QS_U8_PRE_(QF_MAX_EPOOL | (QF_MAX_TICK_RATE << 4U)); + // send the limits... + QS_U8_PRE_(QF_MAX_ACTIVE); + QS_U8_PRE_(QF_MAX_EPOOL | (QF_MAX_TICK_RATE << 4U)); - /* send the build time in three bytes (sec, min, hour)... */ - QS_U8_PRE_((10U * (uint8_t)(TIME[6] - ZERO)) - + (uint8_t)(TIME[7] - ZERO)); - QS_U8_PRE_((10U * (uint8_t)(TIME[3] - ZERO)) - + (uint8_t)(TIME[4] - ZERO)); - if (Q_BUILD_TIME[0] == ' ') { - QS_U8_PRE_(TIME[1] - ZERO); - } - else { - QS_U8_PRE_((10U * (uint8_t)(TIME[0] - ZERO)) - + (uint8_t)(TIME[1] - ZERO)); - } + // send the build time in three bytes (sec, min, hour)... + QS_U8_PRE_((10U * (uint8_t)(TIME[6] - ZERO)) + + (uint8_t)(TIME[7] - ZERO)); + QS_U8_PRE_((10U * (uint8_t)(TIME[3] - ZERO)) + + (uint8_t)(TIME[4] - ZERO)); + if (Q_BUILD_TIME[0] == ' ') { + QS_U8_PRE_(TIME[1] - ZERO); + } + else { + QS_U8_PRE_((10U * (uint8_t)(TIME[0] - ZERO)) + + (uint8_t)(TIME[1] - ZERO)); + } - /* send the build date in three bytes (day, month, year) ... */ - if (Q_BUILD_DATE[4] == ' ') { - QS_U8_PRE_(DATE[5] - ZERO); - } - else { - QS_U8_PRE_((10U * (uint8_t)(DATE[4] - ZERO)) - + (uint8_t)(DATE[5] - ZERO)); - } - /* convert the 3-letter month to a number 1-12 ... */ - uint8_t b; - switch ((int_t)DATE[0] + (int_t)DATE[1] + (int_t)DATE[2]) { - case (int_t)'J' + (int_t)'a' + (int_t)'n': - b = 1U; - break; - case (int_t)'F' + (int_t)'e' + (int_t)'b': - b = 2U; - break; - case (int_t)'M' + (int_t)'a' + (int_t)'r': - b = 3U; - break; - case (int_t)'A' + (int_t)'p' + (int_t)'r': - b = 4U; - break; - case (int_t)'M' + (int_t)'a' + (int_t)'y': - b = 5U; - break; - case (int_t)'J' + (int_t)'u' + (int_t)'n': - b = 6U; - break; - case (int_t)'J' + (int_t)'u' + (int_t)'l': - b = 7U; - break; - case (int_t)'A' + (int_t)'u' + (int_t)'g': - b = 8U; - break; - case (int_t)'S' + (int_t)'e' + (int_t)'p': - b = 9U; - break; - case (int_t)'O' + (int_t)'c' + (int_t)'t': - b = 10U; - break; - case (int_t)'N' + (int_t)'o' + (int_t)'v': - b = 11U; - break; - case (int_t)'D' + (int_t)'e' + (int_t)'c': - b = 12U; - break; - default: - b = 0U; - break; - } - QS_U8_PRE_(b); /* store the month */ - QS_U8_PRE_((10U * (uint8_t)(DATE[9] - ZERO)) - + (uint8_t)(DATE[10] - ZERO)); + // send the build date in three bytes (day, month, year) ... + if (Q_BUILD_DATE[4] == ' ') { + QS_U8_PRE_(DATE[5] - ZERO); + } + else { + QS_U8_PRE_((10U * (uint8_t)(DATE[4] - ZERO)) + + (uint8_t)(DATE[5] - ZERO)); + } + // convert the 3-letter month to a number 1-12 ... + uint8_t b; + switch ((int_t)DATE[0] + (int_t)DATE[1] + (int_t)DATE[2]) { + case (int_t)'J' + (int_t)'a' + (int_t)'n': + b = 1U; + break; + case (int_t)'F' + (int_t)'e' + (int_t)'b': + b = 2U; + break; + case (int_t)'M' + (int_t)'a' + (int_t)'r': + b = 3U; + break; + case (int_t)'A' + (int_t)'p' + (int_t)'r': + b = 4U; + break; + case (int_t)'M' + (int_t)'a' + (int_t)'y': + b = 5U; + break; + case (int_t)'J' + (int_t)'u' + (int_t)'n': + b = 6U; + break; + case (int_t)'J' + (int_t)'u' + (int_t)'l': + b = 7U; + break; + case (int_t)'A' + (int_t)'u' + (int_t)'g': + b = 8U; + break; + case (int_t)'S' + (int_t)'e' + (int_t)'p': + b = 9U; + break; + case (int_t)'O' + (int_t)'c' + (int_t)'t': + b = 10U; + break; + case (int_t)'N' + (int_t)'o' + (int_t)'v': + b = 11U; + break; + case (int_t)'D' + (int_t)'e' + (int_t)'c': + b = 12U; + break; + default: + b = 0U; + break; + } + QS_U8_PRE_(b); // store the month + QS_U8_PRE_((10U * (uint8_t)(DATE[9] - ZERO)) + + (uint8_t)(DATE[10] - ZERO)); QS_endRec_(); } -/*$enddef${QS::QS-tx} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ + +//! @endcond diff --git a/src/qs/qs_64bit.c b/src/qs/qs_64bit.c index 31596199..940a7b54 100644 --- a/src/qs/qs_64bit.c +++ b/src/qs/qs_64bit.c @@ -1,98 +1,94 @@ -/*$file${src::qs::qs_64bit.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* -* Model: qpc.qm -* File: ${src::qs::qs_64bit.c} -* -* This code has been generated by QM 5.2.4 . -* DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. -* -* This code is covered by the following QP license: -* License # : LicenseRef-QL-dual -* Issued to : Any user of the QP/C real-time embedded framework -* Framework(s) : qpc -* Support ends : 2023-12-31 -* License scope: -* -* Copyright (C) 2005 Quantum Leaps, LLC . -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -*/ -/*$endhead${src::qs::qs_64bit.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*! @file -* @brief QS long-long (64-bit) output -*/ -#define QP_IMPL /* this is QP implementation */ -#include "qs_port.h" /* QS port */ -#include "qs_pkg.h" /* QS package-scope internal interface */ +//$file${src::qs::qs_64bit.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// +// Model: qpc.qm +// File: ${src::qs::qs_64bit.c} +// +// This code has been generated by QM 5.3.0 . +// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. +// +// This code is covered by the following QP license: +// License # : LicenseRef-QL-dual +// Issued to : Any user of the QP/C real-time embedded framework +// Framework(s) : qpc +// Support ends : 2024-12-31 +// License scope: +// +// Copyright (C) 2005 Quantum Leaps, LLC . +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +// +//$endhead${src::qs::qs_64bit.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +#define QP_IMPL // this is QP implementation +#include "qs_port.h" // QS port +#include "qs_pkg.h" // QS package-scope internal interface -/*$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* Check for the minimum required QP version */ -#if (QP_VERSION < 700U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) -#error qpc version 7.0.0 or higher required -#endif -/*$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//============================================================================ +//! @cond INTERNAL -/*$define${QS::QS-tx-64bit} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${QS::QS-tx-64bit::u64_raw_} .............................................*/ -void QS_u64_raw_(uint64_t d) { +//! @static @private @memberof QS +void QS_u64_raw_(uint64_t const d) { uint8_t chksum = QS_priv_.chksum; uint8_t * const buf = QS_priv_.buf; QSCtr head = QS_priv_.head; QSCtr const end = QS_priv_.end; - QS_priv_.used += 8U; /* 8 bytes are about to be added */ - uint_fast8_t i; - for (i = 8U; i != 0U; --i) { - uint8_t const b = (uint8_t)d; + QS_priv_.used += 8U; // 8 bytes are about to be added + uint64_t u64 = d; + for (uint_fast8_t i = 8U; i != 0U; --i) { + uint8_t const b = (uint8_t)u64; QS_INSERT_ESC_BYTE_(b) - d >>= 8U; + u64 >>= 8U; } - QS_priv_.head = head; /* save the head */ - QS_priv_.chksum = chksum; /* save the checksum */ + QS_priv_.head = head; // save the head + QS_priv_.chksum = chksum; // save the checksum } -/*${QS::QS-tx-64bit::u64_fmt_} .............................................*/ +//! @static @private @memberof QS void QS_u64_fmt_( - uint8_t format, - uint64_t d) + uint8_t const format, + uint64_t const d) { uint8_t chksum = QS_priv_.chksum; uint8_t * const buf = QS_priv_.buf; QSCtr head = QS_priv_.head; QSCtr const end = QS_priv_.end; - QS_priv_.used += 9U; /* 9 bytes are about to be added */ - QS_INSERT_ESC_BYTE_(format) /* insert the format byte */ + QS_priv_.used += 9U; // 9 bytes are about to be added + QS_INSERT_ESC_BYTE_(format) // insert the format byte - /* output 8 bytes of data... */ - uint_fast8_t i; - for (i = 8U; i != 0U; --i) { - format = (uint8_t)d; - QS_INSERT_ESC_BYTE_(format) - d >>= 8U; + // output 8 bytes of data... + uint64_t u64 = d; + for (uint_fast8_t i = 8U; i != 0U; --i) { + uint8_t const b = (uint8_t)u64; + QS_INSERT_ESC_BYTE_(b) + u64 >>= 8U; } - QS_priv_.head = head; /* save the head */ - QS_priv_.chksum = chksum; /* save the checksum */ + QS_priv_.head = head; // save the head + QS_priv_.chksum = chksum; // save the checksum } -/*$enddef${QS::QS-tx-64bit} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ + +//! @endcond diff --git a/src/qs/qs_fp.c b/src/qs/qs_fp.c index 235b3f83..5585cd0e 100644 --- a/src/qs/qs_fp.c +++ b/src/qs/qs_fp.c @@ -1,88 +1,83 @@ -/*$file${src::qs::qs_fp.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* -* Model: qpc.qm -* File: ${src::qs::qs_fp.c} -* -* This code has been generated by QM 5.2.4 . -* DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. -* -* This code is covered by the following QP license: -* License # : LicenseRef-QL-dual -* Issued to : Any user of the QP/C real-time embedded framework -* Framework(s) : qpc -* Support ends : 2023-12-31 -* License scope: -* -* Copyright (C) 2005 Quantum Leaps, LLC . -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -*/ -/*$endhead${src::qs::qs_fp.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*! @file -* @brief QS floating point output implementation -*/ -#define QP_IMPL /* this is QP implementation */ -#include "qs_port.h" /* QS port */ -#include "qs_pkg.h" /* QS package-scope internal interface */ +//$file${src::qs::qs_fp.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// +// Model: qpc.qm +// File: ${src::qs::qs_fp.c} +// +// This code has been generated by QM 5.3.0 . +// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. +// +// This code is covered by the following QP license: +// License # : LicenseRef-QL-dual +// Issued to : Any user of the QP/C real-time embedded framework +// Framework(s) : qpc +// Support ends : 2024-12-31 +// License scope: +// +// Copyright (C) 2005 Quantum Leaps, LLC . +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +// +//$endhead${src::qs::qs_fp.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +#define QP_IMPL // this is QP implementation +#include "qs_port.h" // QS port +#include "qs_pkg.h" // QS package-scope internal interface -/*$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* Check for the minimum required QP version */ -#if (QP_VERSION < 700U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) -#error qpc version 7.0.0 or higher required -#endif -/*$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//============================================================================ +//! @cond INTERNAL -/*$define${QS::QS-tx-fp} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${QS::QS-tx-fp::f32_fmt_} ................................................*/ +//! @static @private @memberof QS void QS_f32_fmt_( uint8_t const format, - float32_t const d) + float32_t const f) { union F32Rep { float32_t f; uint32_t u; - } fu32; /* the internal binary representation */ - uint8_t chksum = QS_priv_.chksum; /* put in a temporary (register) */ + } fu32; // the internal binary representation + uint8_t chksum = QS_priv_.chksum; // put in a temporary (register) uint8_t * const buf = QS_priv_.buf; QSCtr head = QS_priv_.head; QSCtr const end = QS_priv_.end; uint_fast8_t i; - fu32.f = d; /* assign the binary representation */ + fu32.f = f; // assign the binary representation - QS_priv_.used += 5U; /* 5 bytes about to be added */ - QS_INSERT_ESC_BYTE_(format) /* insert the format byte */ + QS_priv_.used += 5U; // 5 bytes about to be added + QS_INSERT_ESC_BYTE_(format) // insert the format byte - /* insert 4 bytes... */ + // insert 4 bytes... for (i = 4U; i != 0U; --i) { QS_INSERT_ESC_BYTE_((uint8_t)fu32.u) fu32.u >>= 8U; } - QS_priv_.head = head; /* save the head */ - QS_priv_.chksum = chksum; /* save the checksum */ + QS_priv_.head = head; // save the head + QS_priv_.chksum = chksum; // save the checksum } -/*${QS::QS-tx-fp::f64_fmt_} ................................................*/ +//! @static @private @memberof QS void QS_f64_fmt_( uint8_t const format, float64_t const d) @@ -90,45 +85,46 @@ void QS_f64_fmt_( union F64Rep { float64_t d; uint32_t u[2]; - } fu64; /* the internal binary representation */ + } fu64; // the internal binary representation uint8_t chksum = QS_priv_.chksum; uint8_t * const buf = QS_priv_.buf; QSCtr head = QS_priv_.head; QSCtr const end = QS_priv_.end; uint32_t i; - /* static constant untion to detect endianness of the machine */ + // static constant untion to detect endianness of the machine static union U32Rep { uint32_t u32; uint8_t u8; } const endian = { 1U }; - fu64.d = d; /* assign the binary representation */ + fu64.d = d; // assign the binary representation - /* is this a big-endian machine? */ + // is this a big-endian machine? if (endian.u8 == 0U) { - /* swap fu64.u[0] <-> fu64.u[1]... */ + // swap fu64.u[0] <-> fu64.u[1]... i = fu64.u[0]; fu64.u[0] = fu64.u[1]; fu64.u[1] = i; } - QS_priv_.used += 9U; /* 9 bytes about to be added */ - QS_INSERT_ESC_BYTE_(format) /* insert the format byte */ + QS_priv_.used += 9U; // 9 bytes about to be added + QS_INSERT_ESC_BYTE_(format) // insert the format byte - /* output 4 bytes from fu64.u[0]... */ + // output 4 bytes from fu64.u[0]... for (i = 4U; i != 0U; --i) { QS_INSERT_ESC_BYTE_((uint8_t)fu64.u[0]) fu64.u[0] >>= 8U; } - /* output 4 bytes from fu64.u[1]... */ + // output 4 bytes from fu64.u[1]... for (i = 4U; i != 0U; --i) { QS_INSERT_ESC_BYTE_((uint8_t)fu64.u[1]) fu64.u[1] >>= 8U; } - QS_priv_.head = head; /* save the head */ - QS_priv_.chksum = chksum; /* save the checksum */ + QS_priv_.head = head; // save the head + QS_priv_.chksum = chksum; // save the checksum } -/*$enddef${QS::QS-tx-fp} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ + +//! @endcond diff --git a/src/qs/qs_rx.c b/src/qs/qs_rx.c index 3df5fc11..6cbc9b18 100644 --- a/src/qs/qs_rx.c +++ b/src/qs/qs_rx.c @@ -1,52 +1,55 @@ -/*$file${src::qs::qs_rx.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* -* Model: qpc.qm -* File: ${src::qs::qs_rx.c} -* -* This code has been generated by QM 5.2.4 . -* DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. -* -* This code is covered by the following QP license: -* License # : LicenseRef-QL-dual -* Issued to : Any user of the QP/C real-time embedded framework -* Framework(s) : qpc -* Support ends : 2023-12-31 -* License scope: -* -* Copyright (C) 2005 Quantum Leaps, LLC . -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -*/ -/*$endhead${src::qs::qs_rx.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*! @file -* @brief QS/C receive channel services -*/ -#define QP_IMPL /* this is QP implementation */ -#include "qs_port.h" /* QS port */ -#include "qs_pkg.h" /* QS package-scope interface */ -#include "qassert.h" /* QP embedded systems-friendly assertions */ +//$file${src::qs::qs_rx.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// +// Model: qpc.qm +// File: ${src::qs::qs_rx.c} +// +// This code has been generated by QM 5.3.0 . +// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. +// +// This code is covered by the following QP license: +// License # : LicenseRef-QL-dual +// Issued to : Any user of the QP/C real-time embedded framework +// Framework(s) : qpc +// Support ends : 2024-12-31 +// License scope: +// +// Copyright (C) 2005 Quantum Leaps, LLC . +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +// +//$endhead${src::qs::qs_rx.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +#define QP_IMPL // this is QP implementation +#include "qs_port.h" // QS port +#include "qs_pkg.h" // QS package-scope interface +#include "qsafe.h" // QP Functional Safety (FuSa) Subsystem + +//============================================================================ +//! @cond INTERNAL Q_DEFINE_THIS_MODULE("qs_rx") -/*==========================================================================*/ #if (QS_OBJ_PTR_SIZE == 1U) typedef uint8_t QSObj; #elif (QS_OBJ_PTR_SIZE == 2U) @@ -57,10 +60,6 @@ Q_DEFINE_THIS_MODULE("qs_rx") typedef uint64_t QSObj; #endif -/*! @cond -* Exclude the following internals from the Doxygen documentation -* Extended-state variables used for parsing various QS-RX Records -*/ typedef struct { uint32_t param1; uint32_t param2; @@ -92,13 +91,13 @@ typedef struct { typedef struct { uint8_t data[16]; uint8_t idx; - int8_t recId; /* global/local */ + int8_t recId; // global/local } FltVar; typedef struct { QSObj addr; uint8_t idx; - uint8_t kind; /* see qs.h, enum QSpyObjKind */ + uint8_t kind; // see qs.h, enum QSpyObjKind int8_t recId; } ObjVar; @@ -111,7 +110,10 @@ typedef struct { uint8_t idx; } EvtVar; -/* extended-state variables for the current state */ +//! extended-state variables for the current state +//! +//! @trace +//! - @tr{DVR-QS-MC4-R19_02} static struct { union Variant { CmdVar cmd; @@ -123,7 +125,7 @@ static struct { EvtVar evt; #ifdef Q_UTEST struct QS_TProbe tp; -#endif /* Q_UTEST */ +#endif // Q_UTEST } var; uint8_t state; uint8_t esc; @@ -177,37 +179,38 @@ enum { WAIT4_TEST_PROBE_ADDR, WAIT4_TEST_PROBE_FRAME, WAIT4_TEST_CONTINUE_FRAME -#endif /* Q_UTEST */ +#endif // Q_UTEST }; -/* static helper functions... */ +// static helper functions... static void QS_rxParseData_(uint8_t const b); -//static void QS_rxHandleGoodFrame_(uint8_t const state); +static void QS_rxHandleGoodFrame_(uint8_t const state); static void QS_rxHandleBadFrame_(uint8_t const state); static void QS_rxReportAck_(int8_t const recId); static void QS_rxReportError_(int8_t const code); static void QS_rxReportDone_(int8_t const recId); +static void QS_queryCurrObj(uint8_t const obj_kind); static void QS_rxPoke_(void); -/*! Internal QS-RX macro to encapsulate transition in the QS-RX FSM */ +//! Internal QS-RX macro to encapsulate tran. in the QS-RX FSM #define QS_RX_TRAN_(target_) (l_rx.state = (uint8_t)(target_)) -/*! @endcond */ +QS_RxAttr QS_rxPriv_; -/*==========================================================================*/ -/*$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* Check for the minimum required QP version */ -#if (QP_VERSION < 700U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) -#error qpc version 7.0.0 or higher required +//! @endcond +//============================================================================ + +//$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// Check for the minimum required QP version +#if (QP_VERSION < 730U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) +#error qpc version 7.3.0 or higher required #endif -/*$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -/*$define${QS::QS-rx} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//$define${QS::QS-RX} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/*${QS::QS-rx::rxPriv_} ....................................................*/ -QS_rx QS_rxPriv_; - -/*${QS::QS-rx::rxInitBuf} ..................................................*/ +//${QS::QS-RX::rxInitBuf} .................................................... +//! @static @public @memberof QS void QS_rxInitBuf( uint8_t * const sto, uint16_t const stoSize) @@ -233,104 +236,31 @@ void QS_rxInitBuf( QS_OBJ_PRE_(&QS_rxPriv_); QS_STR_PRE_("QS_RX"); QS_endRec_(); - /* no QS_REC_DONE(), because QS is not running yet */ + // no QS_REC_DONE(), because QS is not running yet #ifdef Q_UTEST - QS_testData.tpNum = 0U; - QS_testData.testTime = 0U; - #endif /* Q_UTEST */ + QS_tstPriv_.tpNum = 0U; + QS_tstPriv_.testTime = 0U; + #endif // Q_UTEST } -/*${QS::QS-rx::rxGetNfree} .................................................*/ -uint16_t QS_rxGetNfree(void) { - QSCtr const head = QS_rxPriv_.head; - if (head == QS_rxPriv_.tail) { /* buffer empty? */ - return (uint16_t)(QS_rxPriv_.end - 1U); - } - else if (head < QS_rxPriv_.tail) { - return (uint16_t)(QS_rxPriv_.tail - (head + 1U)); - } - else { - return (uint16_t)(QS_rxPriv_.end + QS_rxPriv_.tail - (head + 1U)); - } -} - -/*${QS::QS-rx::setCurrObj} .................................................*/ -void QS_setCurrObj( - uint8_t const obj_kind, - void * const obj_ptr) -{ - Q_REQUIRE_ID(100, obj_kind < Q_DIM(QS_rxPriv_.currObj)); - QS_rxPriv_.currObj[obj_kind] = obj_ptr; -} - -/*${QS::QS-rx::queryCurrObj} ...............................................*/ -void QS_queryCurrObj(uint8_t const obj_kind) { - if (QS_rxPriv_.currObj[obj_kind] != (void *)0) { - QS_CRIT_STAT_ - QS_CRIT_E_(); - QS_beginRec_((uint_fast8_t)QS_QUERY_DATA); - QS_TIME_PRE_(); /* timestamp */ - QS_U8_PRE_(obj_kind); /* object kind */ - QS_OBJ_PRE_(QS_rxPriv_.currObj[obj_kind]); - switch (obj_kind) { - case SM_OBJ: /* intentionally fall through */ - case AO_OBJ: - QS_FUN_PRE_((*((QHsm *)QS_rxPriv_.currObj[obj_kind])->vptr - ->getStateHandler)( - ((QHsm *)QS_rxPriv_.currObj[obj_kind]))); - break; - case MP_OBJ: - QS_MPC_PRE_(((QMPool *)QS_rxPriv_.currObj[obj_kind]) - ->nFree); - QS_MPC_PRE_(((QMPool *)QS_rxPriv_.currObj[obj_kind]) - ->nMin); - break; - case EQ_OBJ: - QS_EQC_PRE_(((QEQueue *)QS_rxPriv_.currObj[obj_kind]) - ->nFree); - QS_EQC_PRE_(((QEQueue *)QS_rxPriv_.currObj[obj_kind]) - ->nMin); - break; - case TE_OBJ: - QS_OBJ_PRE_(((QTimeEvt *)QS_rxPriv_.currObj[obj_kind]) - ->act); - QS_TEC_PRE_(((QTimeEvt *)QS_rxPriv_.currObj[obj_kind]) - ->ctr); - QS_TEC_PRE_(((QTimeEvt *)QS_rxPriv_.currObj[obj_kind]) - ->interval); - QS_SIG_PRE_(((QTimeEvt *)QS_rxPriv_.currObj[obj_kind]) - ->super.sig); - QS_U8_PRE_ (((QTimeEvt *)QS_rxPriv_.currObj[obj_kind]) - ->super.refCtr_); - break; - default: - /* intentionally empty */ - break; - } - QS_endRec_(); - QS_CRIT_X_(); - - QS_REC_DONE(); /* user callback (if defined) */ - } - else { - QS_rxReportError_((int8_t)QS_RX_QUERY_CURR); - } -} - -/*${QS::QS-rx::rxParse} ....................................................*/ +//${QS::QS-RX::rxParse} ...................................................... +//! @static @public @memberof QS void QS_rxParse(void) { + // NOTE: Must be called IN critical section. + // Also requires system-level memory access (QF_MEM_SYS()). + QSCtr tail = QS_rxPriv_.tail; - while (QS_rxPriv_.head != tail) { /* QS-RX buffer NOT empty? */ + while (QS_rxPriv_.head != tail) { // QS-RX buffer NOT empty? uint8_t b = QS_rxPriv_.buf[tail]; ++tail; if (tail == QS_rxPriv_.end) { tail = 0U; } - QS_rxPriv_.tail = tail; /* update the tail to a *valid* index */ + QS_rxPriv_.tail = tail; // update the tail to a *valid* index - if (l_rx.esc != 0U) { /* escaped byte arrived? */ + if (l_rx.esc != 0U) { // escaped byte arrived? l_rx.esc = 0U; b ^= QS_ESC_XOR; @@ -341,8 +271,8 @@ void QS_rxParse(void) { l_rx.esc = 1U; } else if (b == QS_FRAME) { - /* get ready for the next frame */ - b = l_rx.state; /* save the current state in b */ + // get ready for the next frame + b = l_rx.state; // save the current state in b l_rx.esc = 0U; QS_RX_TRAN_(WAIT4_SEQ); @@ -350,7 +280,7 @@ void QS_rxParse(void) { l_rx.chksum = 0U; QS_rxHandleGoodFrame_(b); } - else { /* bad checksum */ + else { // bad checksum l_rx.chksum = 0U; QS_rxReportError_(0x41); QS_rxHandleBadFrame_(b); @@ -363,64 +293,523 @@ void QS_rxParse(void) { } } -/*${QS::QS-rx::rxHandleGoodFrame_} .........................................*/ -void QS_rxHandleGoodFrame_(uint8_t const state) { +//${QS::QS-RX::rxGetNfree} ................................................... +//! @static @public @memberof QS +uint16_t QS_rxGetNfree(void) { + // NOTE: Must be called IN critical section. + // Also requires system-level memory access (QF_MEM_SYS()). + + QSCtr const head = QS_rxPriv_.head; + uint16_t nFree; + if (head == QS_rxPriv_.tail) { // buffer empty? + nFree = (uint16_t)(QS_rxPriv_.end - 1U); + } + else if (head < QS_rxPriv_.tail) { + nFree = (uint16_t)(QS_rxPriv_.tail - (head + 1U)); + } + else { + nFree = (uint16_t)((head + 1U) - QS_rxPriv_.tail); + nFree = (uint16_t)(QS_rxPriv_.end - nFree); + } + return nFree; +} +//$enddef${QS::QS-RX} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +//============================================================================ +//! @cond INTERNAL + +static void QS_rxParseData_(uint8_t const b) { + switch (l_rx.state) { + case (uint8_t)WAIT4_SEQ: { + ++l_rx.seq; + if (l_rx.seq != b) { + QS_rxReportError_(0x42); + l_rx.seq = b; // update the sequence + } + QS_RX_TRAN_(WAIT4_REC); + break; + } + case (uint8_t)WAIT4_REC: { + switch (b) { + case (uint8_t)QS_RX_INFO: + QS_RX_TRAN_(WAIT4_INFO_FRAME); + break; + case (uint8_t)QS_RX_COMMAND: + QS_RX_TRAN_(WAIT4_CMD_ID); + break; + case (uint8_t)QS_RX_RESET: + QS_RX_TRAN_(WAIT4_RESET_FRAME); + break; + case (uint8_t)QS_RX_TICK: + QS_RX_TRAN_(WAIT4_TICK_RATE); + break; + case (uint8_t)QS_RX_PEEK: + if (QS_rxPriv_.currObj[AP_OBJ] != (void *)0) { + l_rx.var.peek.offs = 0U; + l_rx.var.peek.idx = 0U; + QS_RX_TRAN_(WAIT4_PEEK_OFFS); + } + else { + QS_rxReportError_((int8_t)QS_RX_PEEK); + QS_RX_TRAN_(ERROR_STATE); + } + break; + case (uint8_t)QS_RX_POKE: // intentionally fall-through + case (uint8_t)QS_RX_FILL: + l_rx.var.poke.fill = + ((b == (uint8_t)QS_RX_FILL) ? 1U : 0U); + if (QS_rxPriv_.currObj[AP_OBJ] != (void *)0) { + l_rx.var.poke.offs = 0U; + l_rx.var.poke.idx = 0U; + QS_RX_TRAN_(WAIT4_POKE_OFFS); + } + else { + QS_rxReportError_((l_rx.var.poke.fill != 0U) + ? (int8_t)QS_RX_FILL + : (int8_t)QS_RX_POKE); + QS_RX_TRAN_(ERROR_STATE); + } + break; + case (uint8_t)QS_RX_GLB_FILTER: // intentionally fall-through + case (uint8_t)QS_RX_LOC_FILTER: + l_rx.var.flt.recId = (int8_t)b; + QS_RX_TRAN_(WAIT4_FILTER_LEN); + break; + case (uint8_t)QS_RX_AO_FILTER: // intentionally fall-through + case (uint8_t)QS_RX_CURR_OBJ: + l_rx.var.obj.recId = (int8_t)b; + QS_RX_TRAN_(WAIT4_OBJ_KIND); + break; + case (uint8_t)QS_RX_QUERY_CURR: + l_rx.var.obj.recId = (int8_t)QS_RX_QUERY_CURR; + QS_RX_TRAN_(WAIT4_QUERY_KIND); + break; + case (uint8_t)QS_RX_EVENT: + QS_RX_TRAN_(WAIT4_EVT_PRIO); + break; + +#ifdef Q_UTEST + case (uint8_t)QS_RX_TEST_SETUP: + QS_RX_TRAN_(WAIT4_TEST_SETUP_FRAME); + break; + case (uint8_t)QS_RX_TEST_TEARDOWN: + QS_RX_TRAN_(WAIT4_TEST_TEARDOWN_FRAME); + break; + case (uint8_t)QS_RX_TEST_CONTINUE: + QS_RX_TRAN_(WAIT4_TEST_CONTINUE_FRAME); + break; + case (uint8_t)QS_RX_TEST_PROBE: + if (QS_tstPriv_.tpNum + < (uint8_t)(sizeof(QS_tstPriv_.tpBuf) + / sizeof(QS_tstPriv_.tpBuf[0]))) + { + l_rx.var.tp.data = 0U; + l_rx.var.tp.idx = 0U; + QS_RX_TRAN_(WAIT4_TEST_PROBE_DATA); + } + else { // the # Test-Probes exceeded + QS_rxReportError_((int8_t)QS_RX_TEST_PROBE); + QS_RX_TRAN_(ERROR_STATE); + } + break; +#endif // Q_UTEST + + default: + QS_rxReportError_(0x43); + QS_RX_TRAN_(ERROR_STATE); + break; + } + break; + } + case (uint8_t)WAIT4_INFO_FRAME: { + // keep ignoring the data until a frame is collected + break; + } + case (uint8_t)WAIT4_CMD_ID: { + l_rx.var.cmd.cmdId = b; + l_rx.var.cmd.idx = 0U; + l_rx.var.cmd.param1 = 0U; + l_rx.var.cmd.param2 = 0U; + l_rx.var.cmd.param3 = 0U; + QS_RX_TRAN_(WAIT4_CMD_PARAM1); + break; + } + case (uint8_t)WAIT4_CMD_PARAM1: { + l_rx.var.cmd.param1 |= ((uint32_t)b << l_rx.var.cmd.idx); + l_rx.var.cmd.idx += 8U; + if (l_rx.var.cmd.idx == (8U * 4U)) { + l_rx.var.cmd.idx = 0U; + QS_RX_TRAN_(WAIT4_CMD_PARAM2); + } + break; + } + case (uint8_t)WAIT4_CMD_PARAM2: { + l_rx.var.cmd.param2 |= ((uint32_t)b << l_rx.var.cmd.idx); + l_rx.var.cmd.idx += 8U; + if (l_rx.var.cmd.idx == (8U * 4U)) { + l_rx.var.cmd.idx = 0U; + QS_RX_TRAN_(WAIT4_CMD_PARAM3); + } + break; + } + case (uint8_t)WAIT4_CMD_PARAM3: { + l_rx.var.cmd.param3 |= ((uint32_t)b << l_rx.var.cmd.idx); + l_rx.var.cmd.idx += 8U; + if (l_rx.var.cmd.idx == (8U * 4U)) { + l_rx.var.cmd.idx = 0U; + QS_RX_TRAN_(WAIT4_CMD_FRAME); + } + break; + } + case (uint8_t)WAIT4_CMD_FRAME: { + // keep ignoring the data until a frame is collected + break; + } + case (uint8_t)WAIT4_RESET_FRAME: { + // keep ignoring the data until a frame is collected + break; + } + case (uint8_t)WAIT4_TICK_RATE: { + l_rx.var.tick.rate = (uint_fast8_t)b; + QS_RX_TRAN_(WAIT4_TICK_FRAME); + break; + } + case (uint8_t)WAIT4_TICK_FRAME: { + // keep ignoring the data until a frame is collected + break; + } + case (uint8_t)WAIT4_PEEK_OFFS: { + if (l_rx.var.peek.idx == 0U) { + l_rx.var.peek.offs = (uint16_t)b; + l_rx.var.peek.idx += 8U; + } + else { + l_rx.var.peek.offs |= (uint16_t)((uint16_t)b << 8U); + QS_RX_TRAN_(WAIT4_PEEK_SIZE); + } + break; + } + case (uint8_t)WAIT4_PEEK_SIZE: { + if ((b == 1U) || (b == 2U) || (b == 4U)) { + l_rx.var.peek.size = b; + QS_RX_TRAN_(WAIT4_PEEK_NUM); + } + else { + QS_rxReportError_((int8_t)QS_RX_PEEK); + QS_RX_TRAN_(ERROR_STATE); + } + break; + } + case (uint8_t)WAIT4_PEEK_NUM: { + l_rx.var.peek.num = b; + QS_RX_TRAN_(WAIT4_PEEK_FRAME); + break; + } + case (uint8_t)WAIT4_PEEK_FRAME: { + // keep ignoring the data until a frame is collected + break; + } + case (uint8_t)WAIT4_POKE_OFFS: { + if (l_rx.var.poke.idx == 0U) { + l_rx.var.poke.offs = (uint16_t)b; + l_rx.var.poke.idx = 1U; + } + else { + l_rx.var.poke.offs |= (uint16_t)((uint16_t)b << 8U); + QS_RX_TRAN_(WAIT4_POKE_SIZE); + } + break; + } + case (uint8_t)WAIT4_POKE_SIZE: { + if ((b == 1U) || (b == 2U) || (b == 4U)) { + l_rx.var.poke.size = b; + QS_RX_TRAN_(WAIT4_POKE_NUM); + } + else { + QS_rxReportError_((l_rx.var.poke.fill != 0U) + ? (int8_t)QS_RX_FILL + : (int8_t)QS_RX_POKE); + QS_RX_TRAN_(ERROR_STATE); + } + break; + } + case (uint8_t)WAIT4_POKE_NUM: { + if (b > 0U) { + l_rx.var.poke.num = b; + l_rx.var.poke.data = 0U; + l_rx.var.poke.idx = 0U; + QS_RX_TRAN_((l_rx.var.poke.fill != 0U) + ? WAIT4_FILL_DATA + : WAIT4_POKE_DATA); + } + else { + QS_rxReportError_((l_rx.var.poke.fill != 0U) + ? (int8_t)QS_RX_FILL + : (int8_t)QS_RX_POKE); + QS_RX_TRAN_(ERROR_STATE); + } + break; + } + case (uint8_t)WAIT4_FILL_DATA: { + l_rx.var.poke.data |= ((uint32_t)b << l_rx.var.poke.idx); + l_rx.var.poke.idx += 8U; + if ((uint8_t)(l_rx.var.poke.idx >> 3U) == l_rx.var.poke.size) { + QS_RX_TRAN_(WAIT4_FILL_FRAME); + } + break; + } + case (uint8_t)WAIT4_POKE_DATA: { + l_rx.var.poke.data |= ((uint32_t)b << l_rx.var.poke.idx); + l_rx.var.poke.idx += 8U; + if ((uint8_t)(l_rx.var.poke.idx >> 3U) == l_rx.var.poke.size) { + QS_rxPoke_(); + --l_rx.var.poke.num; + if (l_rx.var.poke.num == 0U) { + QS_RX_TRAN_(WAIT4_POKE_FRAME); + } + } + break; + } + case (uint8_t)WAIT4_FILL_FRAME: { + // keep ignoring the data until a frame is collected + break; + } + case WAIT4_POKE_FRAME: { + // keep ignoring the data until a frame is collected + break; + } + case (uint8_t)WAIT4_FILTER_LEN: { + if (b == sizeof(l_rx.var.flt.data)) { + l_rx.var.flt.idx = 0U; + QS_RX_TRAN_(WAIT4_FILTER_DATA); + } + else { + QS_rxReportError_(l_rx.var.flt.recId); + QS_RX_TRAN_(ERROR_STATE); + } + break; + } + case (uint8_t)WAIT4_FILTER_DATA: { + l_rx.var.flt.data[l_rx.var.flt.idx] = b; + ++l_rx.var.flt.idx; + if (l_rx.var.flt.idx == sizeof(l_rx.var.flt.data)) { + QS_RX_TRAN_(WAIT4_FILTER_FRAME); + } + break; + } + case (uint8_t)WAIT4_FILTER_FRAME: { + // keep ignoring the data until a frame is collected + break; + } + case (uint8_t)WAIT4_OBJ_KIND: { + if (b <= (uint8_t)SM_AO_OBJ) { + l_rx.var.obj.kind = b; + l_rx.var.obj.addr = 0U; + l_rx.var.obj.idx = 0U; + QS_RX_TRAN_(WAIT4_OBJ_ADDR); + } + else { + QS_rxReportError_(l_rx.var.obj.recId); + QS_RX_TRAN_(ERROR_STATE); + } + break; + } + case (uint8_t)WAIT4_OBJ_ADDR: { + l_rx.var.obj.addr |= ((QSObj)b << l_rx.var.obj.idx); + l_rx.var.obj.idx += 8U; + if (l_rx.var.obj.idx == (uint8_t)(8U * QS_OBJ_PTR_SIZE)) { + QS_RX_TRAN_(WAIT4_OBJ_FRAME); + } + break; + } + case (uint8_t)WAIT4_OBJ_FRAME: { + // keep ignoring the data until a frame is collected + break; + } + case (uint8_t)WAIT4_QUERY_KIND: { + if (b < (uint8_t)MAX_OBJ) { + l_rx.var.obj.kind = b; + QS_RX_TRAN_(WAIT4_QUERY_FRAME); + } + else { + QS_rxReportError_(l_rx.var.obj.recId); + QS_RX_TRAN_(ERROR_STATE); + } + break; + } + case (uint8_t)WAIT4_QUERY_FRAME: { + // keep ignoring the data until a frame is collected + break; + } + case (uint8_t)WAIT4_EVT_PRIO: { + l_rx.var.evt.prio = b; + l_rx.var.evt.sig = 0U; + l_rx.var.evt.idx = 0U; + QS_RX_TRAN_(WAIT4_EVT_SIG); + break; + } + case (uint8_t)WAIT4_EVT_SIG: { + l_rx.var.evt.sig |= (QSignal)((uint32_t)b << l_rx.var.evt.idx); + l_rx.var.evt.idx += 8U; + if (l_rx.var.evt.idx == (uint8_t)(8U * Q_SIGNAL_SIZE)) { + l_rx.var.evt.len = 0U; + l_rx.var.evt.idx = 0U; + QS_RX_TRAN_(WAIT4_EVT_LEN); + } + break; + } + case (uint8_t)WAIT4_EVT_LEN: { + l_rx.var.evt.len |= (uint16_t)((uint32_t)b << l_rx.var.evt.idx); + l_rx.var.evt.idx += 8U; + if (l_rx.var.evt.idx == (8U * 2U)) { + if ((l_rx.var.evt.len + sizeof(QEvt)) <= + QF_poolGetMaxBlockSize()) + { + // report Ack before generating any other QS records + QS_rxReportAck_((int8_t)QS_RX_EVENT); + + l_rx.var.evt.e = QF_newX_( + ((uint_fast16_t)l_rx.var.evt.len + sizeof(QEvt)), + 0U, // margin + (enum_t)l_rx.var.evt.sig); + if (l_rx.var.evt.e != (QEvt *)0) { // evt allocated? + l_rx.var.evt.p = (uint8_t *)l_rx.var.evt.e; + l_rx.var.evt.p = &l_rx.var.evt.p[sizeof(QEvt)]; + if (l_rx.var.evt.len > 0U) { + QS_RX_TRAN_(WAIT4_EVT_PAR); + } + else { + QS_RX_TRAN_(WAIT4_EVT_FRAME); + } + } + else { + QS_rxReportError_((int8_t)QS_RX_EVENT); + QS_RX_TRAN_(ERROR_STATE); + } + } + else { + QS_rxReportError_((int8_t)QS_RX_EVENT); + QS_RX_TRAN_(ERROR_STATE); + } + } + break; + } + case (uint8_t)WAIT4_EVT_PAR: { // event parameters + *l_rx.var.evt.p = b; + ++l_rx.var.evt.p; + --l_rx.var.evt.len; + if (l_rx.var.evt.len == 0U) { + QS_RX_TRAN_(WAIT4_EVT_FRAME); + } + break; + } + case (uint8_t)WAIT4_EVT_FRAME: { + // keep ignoring the data until a frame is collected + break; + } + +#ifdef Q_UTEST + case (uint8_t)WAIT4_TEST_SETUP_FRAME: { + // keep ignoring the data until a frame is collected + break; + } + case (uint8_t)WAIT4_TEST_TEARDOWN_FRAME: { + // keep ignoring the data until a frame is collected + break; + } + case (uint8_t)WAIT4_TEST_CONTINUE_FRAME: { + // keep ignoring the data until a frame is collected + break; + } + case (uint8_t)WAIT4_TEST_PROBE_DATA: { + l_rx.var.tp.data |= ((uint32_t)b << l_rx.var.tp.idx); + l_rx.var.tp.idx += 8U; + if (l_rx.var.tp.idx == (uint8_t)(8U * sizeof(uint32_t))) { + l_rx.var.tp.addr = 0U; + l_rx.var.tp.idx = 0U; + QS_RX_TRAN_(WAIT4_TEST_PROBE_ADDR); + } + break; + } + case (uint8_t)WAIT4_TEST_PROBE_ADDR: { + l_rx.var.tp.addr |= ((QSFun)b << l_rx.var.tp.idx); + l_rx.var.tp.idx += 8U; + if (l_rx.var.tp.idx == (uint8_t)(8U * QS_FUN_PTR_SIZE)) { + QS_RX_TRAN_(WAIT4_TEST_PROBE_FRAME); + } + break; + } + case (uint8_t)WAIT4_TEST_PROBE_FRAME: { + // keep ignoring the data until a frame is collected + break; + } +#endif // Q_UTEST + + case (uint8_t)ERROR_STATE: { + // keep ignoring the data until a good frame is collected + break; + } + default: { // unexpected or unimplemented state + QS_rxReportError_(0x45); + QS_RX_TRAN_(ERROR_STATE); + break; + } + } +} + +//............................................................................ +static void QS_rxHandleGoodFrame_(uint8_t const state) { uint8_t i; uint8_t *ptr; - QS_CRIT_STAT_ switch (state) { case WAIT4_INFO_FRAME: { - /* no need to report Ack or Done */ - QS_CRIT_E_(); - QS_target_info_pre_(0U); /* send only Target info */ - QS_CRIT_X_(); + // no need to report Ack or Done + QS_target_info_pre_(0U); // send only Target info break; } case WAIT4_RESET_FRAME: { - /* no need to report Ack or Done, because Target resets */ - QS_onReset(); /* reset the Target */ + // no need to report Ack or Done, because Target resets + QS_onReset(); // reset the Target break; } - case WAIT4_CMD_PARAM1: /* intentionally fall-through */ - case WAIT4_CMD_PARAM2: /* intentionally fall-through */ - case WAIT4_CMD_PARAM3: /* intentionally fall-through */ + case WAIT4_CMD_PARAM1: // intentionally fall-through + case WAIT4_CMD_PARAM2: // intentionally fall-through + case WAIT4_CMD_PARAM3: // intentionally fall-through case WAIT4_CMD_FRAME: { QS_rxReportAck_((int8_t)QS_RX_COMMAND); QS_onCommand(l_rx.var.cmd.cmdId, l_rx.var.cmd.param1, l_rx.var.cmd.param2, l_rx.var.cmd.param3); - #ifdef Q_UTEST +#ifdef Q_UTEST #if Q_UTEST != 0 - QS_processTestEvts_(); /* process all events produced */ - #endif /* Q_UTEST != 0 */ - #endif /* Q_UTEST */ + QS_processTestEvts_(); // process all events produced + #endif // Q_UTEST != 0 +#endif // Q_UTEST QS_rxReportDone_((int8_t)QS_RX_COMMAND); break; } case WAIT4_TICK_FRAME: { QS_rxReportAck_((int8_t)QS_RX_TICK); - #ifdef Q_UTEST +#ifdef Q_UTEST QTimeEvt_tick1_((uint_fast8_t)l_rx.var.tick.rate, &QS_rxPriv_); #if Q_UTEST != 0 - QS_processTestEvts_(); /* process all events produced */ - #endif /* Q_UTEST != 0 */ - #else + QS_processTestEvts_(); // process all events produced + #endif // Q_UTEST != 0 +#else QTimeEvt_tick_((uint_fast8_t)l_rx.var.tick.rate, &QS_rxPriv_); - #endif /* Q_UTEST */ +#endif // Q_UTEST QS_rxReportDone_((int8_t)QS_RX_TICK); break; } case WAIT4_PEEK_FRAME: { - - /* no need to report Ack or Done */ - QS_CRIT_E_(); + // no need to report Ack or Done QS_beginRec_((uint_fast8_t)QS_PEEK_DATA); ptr = (uint8_t *)QS_rxPriv_.currObj[AP_OBJ]; ptr = &ptr[l_rx.var.peek.offs]; - QS_TIME_PRE_(); /* timestamp */ - QS_U16_PRE_(l_rx.var.peek.offs); /* data offset */ - QS_U8_PRE_(l_rx.var.peek.size); /* data size */ - QS_U8_PRE_(l_rx.var.peek.num); /* number of data items */ + QS_TIME_PRE_(); // timestamp + QS_U16_PRE_(l_rx.var.peek.offs); // data offset + QS_U8_PRE_(l_rx.var.peek.size); // data size + QS_U8_PRE_(l_rx.var.peek.num); // # data items for (i = 0U; i < l_rx.var.peek.num; ++i) { switch (l_rx.var.peek.size) { case 1: @@ -433,24 +822,23 @@ void QS_rxHandleGoodFrame_(uint8_t const state) { QS_U32_PRE_(((uint32_t *)ptr)[i]); break; default: - /* intentionally empty */ + // intentionally empty break; } } QS_endRec_(); - QS_CRIT_X_(); - QS_REC_DONE(); /* user callback (if defined) */ + QS_REC_DONE(); // user callback (if defined) break; } case WAIT4_POKE_DATA: { - /* received less than expected poke data items */ + // received less than expected poke data items QS_rxReportError_((int8_t)QS_RX_POKE); break; } case WAIT4_POKE_FRAME: { QS_rxReportAck_((int8_t)QS_RX_POKE); - /* no need to report done */ + // no need to report done break; } case WAIT4_FILL_FRAME: { @@ -470,7 +858,7 @@ void QS_rxHandleGoodFrame_(uint8_t const state) { ((uint32_t *)ptr)[i] = l_rx.var.poke.data; break; default: - /* intentionally empty */ + // intentionally empty break; } } @@ -479,32 +867,31 @@ void QS_rxHandleGoodFrame_(uint8_t const state) { case WAIT4_FILTER_FRAME: { QS_rxReportAck_(l_rx.var.flt.recId); - /* apply the received filters */ + // apply the received filters if (l_rx.var.flt.recId == (int8_t)QS_RX_GLB_FILTER) { - for (i = 0U; i < Q_DIM(QS_priv_.glbFilter); ++i) { - QS_priv_.glbFilter[i] = l_rx.var.flt.data[i]; + for (i = 0U; i < Q_DIM(QS_filt_.glb); ++i) { + QS_filt_.glb[i] = l_rx.var.flt.data[i]; } - /* leave the "not maskable" filters enabled, - * see qs.h, Miscellaneous QS records (not maskable) - */ - QS_priv_.glbFilter[0] |= 0x01U; - QS_priv_.glbFilter[7] |= 0xFCU; - QS_priv_.glbFilter[8] |= 0x7FU; + // leave the "not maskable" filters enabled, + // see qs.h, Miscellaneous QS records (not maskable) + QS_filt_.glb[0] |= 0x01U; + QS_filt_.glb[7] |= 0xFCU; + QS_filt_.glb[8] |= 0x7FU; - /* never enable the last 3 records (0x7D, 0x7E, 0x7F) */ - QS_priv_.glbFilter[15] &= 0x1FU; + // never enable the last 3 records (0x7D, 0x7E, 0x7F) + QS_filt_.glb[15] &= 0x1FU; } else if (l_rx.var.flt.recId == (int8_t)QS_RX_LOC_FILTER) { - for (i = 0U; i < Q_DIM(QS_priv_.locFilter); ++i) { - QS_priv_.locFilter[i] = l_rx.var.flt.data[i]; + for (i = 0U; i < Q_DIM(QS_filt_.loc); ++i) { + QS_filt_.loc[i] = l_rx.var.flt.data[i]; } - /* leave QS_ID == 0 always on */ - QS_priv_.locFilter[0] |= 0x01U; + // leave QS_ID == 0 always on + QS_filt_.loc[0] |= 0x01U; } else { QS_rxReportError_(l_rx.var.flt.recId); } - /* no need to report Done */ + // no need to report Done break; } case WAIT4_OBJ_FRAME: { @@ -531,7 +918,7 @@ void QS_rxHandleGoodFrame_(uint8_t const state) { QS_rxReportError_(l_rx.var.obj.recId); } } - /* both SM and AO */ + // both SM and AO else if (i == (uint8_t)SM_AO_OBJ) { if (l_rx.var.obj.recId == (int8_t)QS_RX_CURR_OBJ) { QS_rxPriv_.currObj[SM_OBJ] = (void *)l_rx.var.obj.addr; @@ -549,134 +936,132 @@ void QS_rxHandleGoodFrame_(uint8_t const state) { break; } case WAIT4_EVT_FRAME: { - /* NOTE: Ack was already reported in the WAIT4_EVT_LEN state */ - #ifdef Q_UTEST - QS_onTestEvt(l_rx.var.evt.e); /* adjust the event, if needed */ - #endif /* Q_UTEST */ - i = 0U; /* use 'i' as status, 0 == success,no-recycle */ + // NOTE: Ack was already reported in the WAIT4_EVT_LEN state +#ifdef Q_UTEST + QS_onTestEvt(l_rx.var.evt.e); // adjust the event, if needed +#endif // Q_UTEST + i = 0U; // use 'i' as status, 0 == success,no-recycle - if (l_rx.var.evt.prio == 0U) { /* publish */ + if (l_rx.var.evt.prio == 0U) { // publish QActive_publish_(l_rx.var.evt.e, &QS_rxPriv_, 0U); } else if (l_rx.var.evt.prio < QF_MAX_ACTIVE) { if (!QACTIVE_POST_X(QActive_registry_[l_rx.var.evt.prio], l_rx.var.evt.e, - 0U, /* margin */ + 0U, // margin &QS_rxPriv_)) { - /* failed QACTIVE_POST() recycles the event */ - i = 0x80U; /* failure status, no recycle */ + // failed QACTIVE_POST() recycles the event + i = 0x80U; // failure status, no recycle } } - else if (l_rx.var.evt.prio == 255U) { /* special prio */ - /* dispatch to the current SM object */ + else if (l_rx.var.evt.prio == 255U) { // special prio + // dispatch to the current SM object if (QS_rxPriv_.currObj[SM_OBJ] != (void *)0) { - /* increment the ref-ctr to simulate the situation - * when the event is just retreived from a queue. - * This is expected for the following QF_gc() call. - */ + // increment the ref-ctr to simulate the situation + // when the event is just retreived from a queue. + // This is expected for the following QF_gc() call. ++l_rx.var.evt.e->refCtr_; - QHSM_DISPATCH((QHsm *)QS_rxPriv_.currObj[SM_OBJ], - l_rx.var.evt.e, 0U); - i = 0x01U; /* success status, recycle needed */ + QAsm * const sm = (QAsm *)QS_rxPriv_.currObj[SM_OBJ]; + (*sm->vptr->dispatch)(sm, l_rx.var.evt.e, 0U); + i = 0x01U; // success status, recycle needed } else { - i = 0x81U; /* failure status, recycle needed */ + i = 0x81U; // failure status, recycle needed } } - else if (l_rx.var.evt.prio == 254U) { /* special prio */ - /* init the current SM object" */ + else if (l_rx.var.evt.prio == 254U) { // special prio + // init the current SM object" if (QS_rxPriv_.currObj[SM_OBJ] != (void *)0) { - /* increment the ref-ctr to simulate the situation - * when the event is just retreived from a queue. - * This is expected for the following QF_gc() call. - */ + // increment the ref-ctr to simulate the situation + // when the event is just retreived from a queue. + // This is expected for the following QF_gc() call. ++l_rx.var.evt.e->refCtr_; - QHSM_INIT((QHsm *)QS_rxPriv_.currObj[SM_OBJ], - l_rx.var.evt.e, 0U); - i = 0x01U; /* success status, recycle needed */ + QAsm * const sm = (QAsm *)QS_rxPriv_.currObj[SM_OBJ]; + (*sm->vptr->init)(sm, l_rx.var.evt.e, 0U); + i = 0x01U; // success status, recycle needed } else { - i = 0x81U; /* failure status, recycle needed */ + i = 0x81U; // failure status, recycle needed } } - else if (l_rx.var.evt.prio == 253U) { /* special prio */ - /* post to the current AO */ + else if (l_rx.var.evt.prio == 253U) { // special prio + // post to the current AO if (QS_rxPriv_.currObj[AO_OBJ] != (void *)0) { if (!QACTIVE_POST_X( (QActive *)QS_rxPriv_.currObj[AO_OBJ], l_rx.var.evt.e, - 0U, /* margin */ + 0U, // margin &QS_rxPriv_)) { - /* failed QACTIVE_POST() recycles the event */ - i = 0x80U; /* failure status, no recycle */ + // failed QACTIVE_POST() recycles the event + i = 0x80U; // failure status, no recycle } } else { - i = 0x81U; /* failure status, recycle needed */ + i = 0x81U; // failure status, recycle needed } } else { - i = 0x81U; /* failure status, recycle needed */ + i = 0x81U; // failure status, recycle needed } - #if (QF_MAX_EPOOL > 0U) - if ((i & 0x01U) != 0U) { /* recycle needed? */ +#if (QF_MAX_EPOOL > 0U) + if ((i & 0x01U) != 0U) { // recycle needed? QF_gc(l_rx.var.evt.e); } - #endif - if ((i & 0x80U) != 0U) { /* failure? */ +#endif + if ((i & 0x80U) != 0U) { // failure? QS_rxReportError_((int8_t)QS_RX_EVENT); } else { - #ifdef Q_UTEST +#ifdef Q_UTEST #if Q_UTEST != 0 - QS_processTestEvts_(); /* process all events produced */ - #endif /* Q_UTEST != 0 */ - #endif /* Q_UTEST */ + QS_processTestEvts_(); // process all events produced + #endif // Q_UTEST != 0 +#endif // Q_UTEST QS_rxReportDone_((int8_t)QS_RX_EVENT); } break; } - #ifdef Q_UTEST +#ifdef Q_UTEST case WAIT4_TEST_SETUP_FRAME: { QS_rxReportAck_((int8_t)QS_RX_TEST_SETUP); - QS_testData.tpNum = 0U; /* clear the Test-Probes */ - QS_testData.testTime = 0U; /* clear the time tick */ - /* don't clear current objects */ - QS_onTestSetup(); /* application-specific test setup */ - /* no need to report Done */ + QS_tstPriv_.tpNum = 0U; // clear the Test-Probes + QS_tstPriv_.testTime = 0U; // clear the time tick + // don't clear current objects + QS_onTestSetup(); // application-specific test setup + // no need to report Done break; } case WAIT4_TEST_TEARDOWN_FRAME: { QS_rxReportAck_((int8_t)QS_RX_TEST_TEARDOWN); - QS_onTestTeardown(); /* application-specific test teardown */ - /* no need to report Done */ + QS_onTestTeardown(); // application-specific test teardown + // no need to report Done break; } case WAIT4_TEST_CONTINUE_FRAME: { QS_rxReportAck_((int8_t)QS_RX_TEST_CONTINUE); - QS_rxPriv_.inTestLoop = false; /* exit the QUTest loop */ - /* no need to report Done */ + QS_rxPriv_.inTestLoop = false; // exit the QUTest loop + // no need to report Done break; } case WAIT4_TEST_PROBE_FRAME: { QS_rxReportAck_((int8_t)QS_RX_TEST_PROBE); - Q_ASSERT_ID(815, QS_testData.tpNum - < (sizeof(QS_testData.tpBuf) / sizeof(QS_testData.tpBuf[0]))); - QS_testData.tpBuf[QS_testData.tpNum] = l_rx.var.tp; - ++QS_testData.tpNum; - /* no need to report Done */ + Q_ASSERT_INCRIT(815, QS_tstPriv_.tpNum + < (sizeof(QS_tstPriv_.tpBuf) / sizeof(QS_tstPriv_.tpBuf[0]))); + QS_tstPriv_.tpBuf[QS_tstPriv_.tpNum] = l_rx.var.tp; + ++QS_tstPriv_.tpNum; + // no need to report Done break; } - #endif /* Q_UTEST */ +#endif // Q_UTEST case ERROR_STATE: { - /* keep ignoring all bytes until new frame */ + // keep ignoring all bytes until new frame break; } default: { @@ -686,519 +1071,100 @@ void QS_rxHandleGoodFrame_(uint8_t const state) { } } -/*${QS::QS-rx::RX_PUT} .....................................................*/ -bool QS_RX_PUT(uint8_t const b) { - QSCtr head = QS_rxPriv_.head + 1U; - if (head == QS_rxPriv_.end) { - head = 0U; - } - if (head != QS_rxPriv_.tail) { /* buffer NOT full? */ - QS_rxPriv_.buf[QS_rxPriv_.head] = b; - QS_rxPriv_.head = head; /* update the head to a *valid* index */ - return true; /* byte placed in the buffer */ - } - else { - return false; /* byte NOT placed in the buffer */ - } -} -/*$enddef${QS::QS-rx} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ - -/*==========================================================================*/ -static void QS_rxParseData_(uint8_t const b) { - switch (l_rx.state) { - case WAIT4_SEQ: { - ++l_rx.seq; - if (l_rx.seq != b) { - QS_rxReportError_(0x42); - l_rx.seq = b; /* update the sequence */ - } - QS_RX_TRAN_(WAIT4_REC); - break; - } - case WAIT4_REC: { - switch (b) { - case QS_RX_INFO: - QS_RX_TRAN_(WAIT4_INFO_FRAME); - break; - case QS_RX_COMMAND: - QS_RX_TRAN_(WAIT4_CMD_ID); - break; - case QS_RX_RESET: - QS_RX_TRAN_(WAIT4_RESET_FRAME); - break; - case QS_RX_TICK: - QS_RX_TRAN_(WAIT4_TICK_RATE); - break; - case QS_RX_PEEK: - if (QS_rxPriv_.currObj[AP_OBJ] != (void *)0) { - l_rx.var.peek.offs = 0U; - l_rx.var.peek.idx = 0U; - QS_RX_TRAN_(WAIT4_PEEK_OFFS); - } - else { - QS_rxReportError_((int8_t)QS_RX_PEEK); - QS_RX_TRAN_(ERROR_STATE); - } - break; - case QS_RX_POKE: /* intentionally fall-through */ - case QS_RX_FILL: - l_rx.var.poke.fill = - ((b == (uint8_t)QS_RX_FILL) ? 1U : 0U); - if (QS_rxPriv_.currObj[AP_OBJ] != (void *)0) { - l_rx.var.poke.offs = 0U; - l_rx.var.poke.idx = 0U; - QS_RX_TRAN_(WAIT4_POKE_OFFS); - } - else { - QS_rxReportError_((l_rx.var.poke.fill != 0U) - ? (int8_t)QS_RX_FILL - : (int8_t)QS_RX_POKE); - QS_RX_TRAN_(ERROR_STATE); - } - break; - case QS_RX_GLB_FILTER: /* intentionally fall-through */ - case QS_RX_LOC_FILTER: - l_rx.var.flt.recId = (int8_t)b; - QS_RX_TRAN_(WAIT4_FILTER_LEN); - break; - case QS_RX_AO_FILTER: /* intentionally fall-through */ - case QS_RX_CURR_OBJ: - l_rx.var.obj.recId = (int8_t)b; - QS_RX_TRAN_(WAIT4_OBJ_KIND); - break; - case QS_RX_QUERY_CURR: - l_rx.var.obj.recId = (int8_t)QS_RX_QUERY_CURR; - QS_RX_TRAN_(WAIT4_QUERY_KIND); - break; - case QS_RX_EVENT: - QS_RX_TRAN_(WAIT4_EVT_PRIO); - break; - -#ifdef Q_UTEST - case QS_RX_TEST_SETUP: - QS_RX_TRAN_(WAIT4_TEST_SETUP_FRAME); - break; - case QS_RX_TEST_TEARDOWN: - QS_RX_TRAN_(WAIT4_TEST_TEARDOWN_FRAME); - break; - case QS_RX_TEST_CONTINUE: - QS_RX_TRAN_(WAIT4_TEST_CONTINUE_FRAME); - break; - case QS_RX_TEST_PROBE: - if (QS_testData.tpNum - < (uint8_t)(sizeof(QS_testData.tpBuf) - / sizeof(QS_testData.tpBuf[0]))) - { - l_rx.var.tp.data = 0U; - l_rx.var.tp.idx = 0U; - QS_RX_TRAN_(WAIT4_TEST_PROBE_DATA); - } - else { /* the number of Test-Probes exceeded */ - QS_rxReportError_((int8_t)QS_RX_TEST_PROBE); - QS_RX_TRAN_(ERROR_STATE); - } - break; -#endif /* Q_UTEST */ - - default: - QS_rxReportError_(0x43); - QS_RX_TRAN_(ERROR_STATE); - break; - } - break; - } - case WAIT4_INFO_FRAME: { - /* keep ignoring the data until a frame is collected */ - break; - } - case WAIT4_CMD_ID: { - l_rx.var.cmd.cmdId = b; - l_rx.var.cmd.idx = 0U; - l_rx.var.cmd.param1 = 0U; - l_rx.var.cmd.param2 = 0U; - l_rx.var.cmd.param3 = 0U; - QS_RX_TRAN_(WAIT4_CMD_PARAM1); - break; - } - case WAIT4_CMD_PARAM1: { - l_rx.var.cmd.param1 |= ((uint32_t)b << l_rx.var.cmd.idx); - l_rx.var.cmd.idx += 8U; - if (l_rx.var.cmd.idx == (8U * 4U)) { - l_rx.var.cmd.idx = 0U; - QS_RX_TRAN_(WAIT4_CMD_PARAM2); - } - break; - } - case WAIT4_CMD_PARAM2: { - l_rx.var.cmd.param2 |= ((uint32_t)b << l_rx.var.cmd.idx); - l_rx.var.cmd.idx += 8U; - if (l_rx.var.cmd.idx == (8U * 4U)) { - l_rx.var.cmd.idx = 0U; - QS_RX_TRAN_(WAIT4_CMD_PARAM3); - } - break; - } - case WAIT4_CMD_PARAM3: { - l_rx.var.cmd.param3 |= ((uint32_t)b << l_rx.var.cmd.idx); - l_rx.var.cmd.idx += 8U; - if (l_rx.var.cmd.idx == (8U * 4U)) { - l_rx.var.cmd.idx = 0U; - QS_RX_TRAN_(WAIT4_CMD_FRAME); - } - break; - } - case WAIT4_CMD_FRAME: { - /* keep ignoring the data until a frame is collected */ - break; - } - case WAIT4_RESET_FRAME: { - /* keep ignoring the data until a frame is collected */ - break; - } - case WAIT4_TICK_RATE: { - l_rx.var.tick.rate = (uint_fast8_t)b; - QS_RX_TRAN_(WAIT4_TICK_FRAME); - break; - } - case WAIT4_TICK_FRAME: { - /* keep ignoring the data until a frame is collected */ - break; - } - case WAIT4_PEEK_OFFS: { - if (l_rx.var.peek.idx == 0U) { - l_rx.var.peek.offs = (uint16_t)b; - l_rx.var.peek.idx += 8U; - } - else { - l_rx.var.peek.offs |= (uint16_t)((uint16_t)b << 8U); - QS_RX_TRAN_(WAIT4_PEEK_SIZE); - } - break; - } - case WAIT4_PEEK_SIZE: { - if ((b == 1U) || (b == 2U) || (b == 4U)) { - l_rx.var.peek.size = b; - QS_RX_TRAN_(WAIT4_PEEK_NUM); - } - else { - QS_rxReportError_((int8_t)QS_RX_PEEK); - QS_RX_TRAN_(ERROR_STATE); - } - break; - } - case WAIT4_PEEK_NUM: { - l_rx.var.peek.num = b; - QS_RX_TRAN_(WAIT4_PEEK_FRAME); - break; - } - case WAIT4_PEEK_FRAME: { - /* keep ignoring the data until a frame is collected */ - break; - } - case WAIT4_POKE_OFFS: { - if (l_rx.var.poke.idx == 0U) { - l_rx.var.poke.offs = (uint16_t)b; - l_rx.var.poke.idx = 1U; - } - else { - l_rx.var.poke.offs |= (uint16_t)((uint16_t)b << 8U); - QS_RX_TRAN_(WAIT4_POKE_SIZE); - } - break; - } - case WAIT4_POKE_SIZE: { - if ((b == 1U) || (b == 2U) || (b == 4U)) { - l_rx.var.poke.size = b; - QS_RX_TRAN_(WAIT4_POKE_NUM); - } - else { - QS_rxReportError_((l_rx.var.poke.fill != 0U) - ? (int8_t)QS_RX_FILL - : (int8_t)QS_RX_POKE); - QS_RX_TRAN_(ERROR_STATE); - } - break; - } - case WAIT4_POKE_NUM: { - if (b > 0U) { - l_rx.var.poke.num = b; - l_rx.var.poke.data = 0U; - l_rx.var.poke.idx = 0U; - QS_RX_TRAN_((l_rx.var.poke.fill != 0U) - ? WAIT4_FILL_DATA - : WAIT4_POKE_DATA); - } - else { - QS_rxReportError_((l_rx.var.poke.fill != 0U) - ? (int8_t)QS_RX_FILL - : (int8_t)QS_RX_POKE); - QS_RX_TRAN_(ERROR_STATE); - } - break; - } - case WAIT4_FILL_DATA: { - l_rx.var.poke.data |= ((uint32_t)b << l_rx.var.poke.idx); - l_rx.var.poke.idx += 8U; - if ((uint8_t)(l_rx.var.poke.idx >> 3U) == l_rx.var.poke.size) { - QS_RX_TRAN_(WAIT4_FILL_FRAME); - } - break; - } - case WAIT4_POKE_DATA: { - l_rx.var.poke.data |= ((uint32_t)b << l_rx.var.poke.idx); - l_rx.var.poke.idx += 8U; - if ((uint8_t)(l_rx.var.poke.idx >> 3U) == l_rx.var.poke.size) { - QS_rxPoke_(); - --l_rx.var.poke.num; - if (l_rx.var.poke.num == 0U) { - QS_RX_TRAN_(WAIT4_POKE_FRAME); - } - } - break; - } - case WAIT4_FILL_FRAME: { - /* keep ignoring the data until a frame is collected */ - break; - } - case WAIT4_POKE_FRAME: { - /* keep ignoring the data until a frame is collected */ - break; - } - case WAIT4_FILTER_LEN: { - if (b == sizeof(l_rx.var.flt.data)) { - l_rx.var.flt.idx = 0U; - QS_RX_TRAN_(WAIT4_FILTER_DATA); - } - else { - QS_rxReportError_(l_rx.var.flt.recId); - QS_RX_TRAN_(ERROR_STATE); - } - break; - } - case WAIT4_FILTER_DATA: { - l_rx.var.flt.data[l_rx.var.flt.idx] = b; - ++l_rx.var.flt.idx; - if (l_rx.var.flt.idx == sizeof(l_rx.var.flt.data)) { - QS_RX_TRAN_(WAIT4_FILTER_FRAME); - } - break; - } - case WAIT4_FILTER_FRAME: { - /* keep ignoring the data until a frame is collected */ - break; - } - case WAIT4_OBJ_KIND: { - if (b <= (uint8_t)SM_AO_OBJ) { - l_rx.var.obj.kind = b; - l_rx.var.obj.addr = 0U; - l_rx.var.obj.idx = 0U; - QS_RX_TRAN_(WAIT4_OBJ_ADDR); - } - else { - QS_rxReportError_(l_rx.var.obj.recId); - QS_RX_TRAN_(ERROR_STATE); - } - break; - } - case WAIT4_OBJ_ADDR: { - l_rx.var.obj.addr |= ((QSObj)b << l_rx.var.obj.idx); - l_rx.var.obj.idx += 8U; - if (l_rx.var.obj.idx == (uint8_t)(8U * QS_OBJ_PTR_SIZE)) { - QS_RX_TRAN_(WAIT4_OBJ_FRAME); - } - break; - } - case WAIT4_OBJ_FRAME: { - /* keep ignoring the data until a frame is collected */ - break; - } - case WAIT4_QUERY_KIND: { - if (b < (uint8_t)MAX_OBJ) { - l_rx.var.obj.kind = b; - QS_RX_TRAN_(WAIT4_QUERY_FRAME); - } - else { - QS_rxReportError_(l_rx.var.obj.recId); - QS_RX_TRAN_(ERROR_STATE); - } - break; - } - case WAIT4_QUERY_FRAME: { - /* keep ignoring the data until a frame is collected */ - break; - } - case WAIT4_EVT_PRIO: { - l_rx.var.evt.prio = b; - l_rx.var.evt.sig = 0U; - l_rx.var.evt.idx = 0U; - QS_RX_TRAN_(WAIT4_EVT_SIG); - break; - } - case WAIT4_EVT_SIG: { - l_rx.var.evt.sig |= (QSignal)((uint32_t)b << l_rx.var.evt.idx); - l_rx.var.evt.idx += 8U; - if (l_rx.var.evt.idx == (uint8_t)(8U * Q_SIGNAL_SIZE)) { - l_rx.var.evt.len = 0U; - l_rx.var.evt.idx = 0U; - QS_RX_TRAN_(WAIT4_EVT_LEN); - } - break; - } - case WAIT4_EVT_LEN: { - l_rx.var.evt.len |= (uint16_t)((uint32_t)b << l_rx.var.evt.idx); - l_rx.var.evt.idx += 8U; - if (l_rx.var.evt.idx == (8U * 2U)) { - if ((l_rx.var.evt.len + sizeof(QEvt)) <= - QF_poolGetMaxBlockSize()) - { - /* report Ack before generating any other QS records */ - QS_rxReportAck_((int8_t)QS_RX_EVENT); - - l_rx.var.evt.e = QF_newX_( - ((uint_fast16_t)l_rx.var.evt.len + sizeof(QEvt)), - 0U, /* margin */ - (enum_t)l_rx.var.evt.sig); - if (l_rx.var.evt.e != (QEvt *)0) { /* evt allocated? */ - l_rx.var.evt.p = (uint8_t *)l_rx.var.evt.e; - l_rx.var.evt.p = &l_rx.var.evt.p[sizeof(QEvt)]; - if (l_rx.var.evt.len > 0U) { - QS_RX_TRAN_(WAIT4_EVT_PAR); - } - else { - QS_RX_TRAN_(WAIT4_EVT_FRAME); - } - } - else { - QS_rxReportError_((int8_t)QS_RX_EVENT); - QS_RX_TRAN_(ERROR_STATE); - } - } - else { - QS_rxReportError_((int8_t)QS_RX_EVENT); - QS_RX_TRAN_(ERROR_STATE); - } - } - break; - } - case WAIT4_EVT_PAR: { /* event parameters */ - *l_rx.var.evt.p = b; - ++l_rx.var.evt.p; - --l_rx.var.evt.len; - if (l_rx.var.evt.len == 0U) { - QS_RX_TRAN_(WAIT4_EVT_FRAME); - } - break; - } - case WAIT4_EVT_FRAME: { - /* keep ignoring the data until a frame is collected */ - break; - } - -#ifdef Q_UTEST - case WAIT4_TEST_SETUP_FRAME: { - /* keep ignoring the data until a frame is collected */ - break; - } - case WAIT4_TEST_TEARDOWN_FRAME: { - /* keep ignoring the data until a frame is collected */ - break; - } - case WAIT4_TEST_CONTINUE_FRAME: { - /* keep ignoring the data until a frame is collected */ - break; - } - case WAIT4_TEST_PROBE_DATA: { - l_rx.var.tp.data |= ((uint32_t)b << l_rx.var.tp.idx); - l_rx.var.tp.idx += 8U; - if (l_rx.var.tp.idx == (uint8_t)(8U * sizeof(uint32_t))) { - l_rx.var.tp.addr = 0U; - l_rx.var.tp.idx = 0U; - QS_RX_TRAN_(WAIT4_TEST_PROBE_ADDR); - } - break; - } - case WAIT4_TEST_PROBE_ADDR: { - l_rx.var.tp.addr |= ((QSFun)b << l_rx.var.tp.idx); - l_rx.var.tp.idx += 8U; - if (l_rx.var.tp.idx == (uint8_t)(8U * QS_FUN_PTR_SIZE)) { - QS_RX_TRAN_(WAIT4_TEST_PROBE_FRAME); - } - break; - } - case WAIT4_TEST_PROBE_FRAME: { - /* keep ignoring the data until a frame is collected */ - break; - } -#endif /* Q_UTEST */ - - case ERROR_STATE: { - /* keep ignoring the data until a good frame is collected */ - break; - } - default: { /* unexpected or unimplemented state */ - QS_rxReportError_(0x45); - QS_RX_TRAN_(ERROR_STATE); - break; - } - } -} - -/*..........................................................................*/ +//............................................................................ static void QS_rxHandleBadFrame_(uint8_t const state) { - QS_rxReportError_(0x50); /* report error for all bad frames */ + QS_rxReportError_(0x50); // report error for all bad frames switch (state) { case WAIT4_EVT_FRAME: { - Q_ASSERT_ID(910, l_rx.var.evt.e != (QEvt *)0); + Q_ASSERT_INCRIT(910, l_rx.var.evt.e != (QEvt *)0); #if (QF_MAX_EPOOL > 0U) - QF_gc(l_rx.var.evt.e); /* don't leak an allocated event */ + QF_gc(l_rx.var.evt.e); // don't leak an allocated event #endif break; } default: { - /* intentionally empty */ + // intentionally empty break; } } } -/*..........................................................................*/ +//............................................................................ static void QS_rxReportAck_(int8_t const recId) { - QS_CRIT_STAT_ - QS_CRIT_E_(); QS_beginRec_((uint_fast8_t)QS_RX_STATUS); - QS_U8_PRE_(recId); /* record ID */ + QS_U8_PRE_(recId); // record ID QS_endRec_(); - QS_CRIT_X_(); - - QS_REC_DONE(); /* user callback (if defined) */ + QS_REC_DONE(); // user callback (if defined) } -/*..........................................................................*/ +//............................................................................ static void QS_rxReportError_(int8_t const code) { - QS_CRIT_STAT_ - QS_CRIT_E_(); QS_beginRec_((uint_fast8_t)QS_RX_STATUS); - QS_U8_PRE_(0x80U | (uint8_t)code); /* error code */ + QS_U8_PRE_(0x80U | (uint8_t)code); // error code QS_endRec_(); - QS_CRIT_X_(); - - QS_REC_DONE(); /* user callback (if defined) */ + QS_REC_DONE(); // user callback (if defined) } -/*..........................................................................*/ +//............................................................................ static void QS_rxReportDone_(int8_t const recId) { - QS_CRIT_STAT_ - QS_CRIT_E_(); QS_beginRec_((uint_fast8_t)QS_TARGET_DONE); - QS_TIME_PRE_(); /* timestamp */ - QS_U8_PRE_(recId); /* record ID */ + QS_TIME_PRE_(); // timestamp + QS_U8_PRE_(recId); // record ID QS_endRec_(); - QS_CRIT_X_(); - - QS_REC_DONE(); /* user callback (if defined) */ + QS_REC_DONE(); // user callback (if defined) } -/*..........................................................................*/ +//............................................................................ +static void QS_queryCurrObj(uint8_t const obj_kind) { + if (QS_rxPriv_.currObj[obj_kind] != (void *)0) { + QS_beginRec_((uint_fast8_t)QS_QUERY_DATA); + QS_TIME_PRE_(); // timestamp + QS_U8_PRE_(obj_kind); // object kind + QS_OBJ_PRE_(QS_rxPriv_.currObj[obj_kind]); + switch (obj_kind) { + case (uint8_t)SM_OBJ: // intentionally fall through + case (uint8_t)AO_OBJ: + QS_FUN_PRE_((*((QAsm *)QS_rxPriv_.currObj[obj_kind])->vptr + ->getStateHandler)( + ((QAsm *)QS_rxPriv_.currObj[obj_kind]))); + break; + case (uint8_t)MP_OBJ: + QS_MPC_PRE_(((QMPool *)QS_rxPriv_.currObj[obj_kind]) + ->nFree); + QS_MPC_PRE_(((QMPool *)QS_rxPriv_.currObj[obj_kind]) + ->nMin); + break; + case (uint8_t)EQ_OBJ: + QS_EQC_PRE_(((QEQueue *)QS_rxPriv_.currObj[obj_kind]) + ->nFree); + QS_EQC_PRE_(((QEQueue *)QS_rxPriv_.currObj[obj_kind]) + ->nMin); + break; + case (uint8_t)TE_OBJ: + QS_OBJ_PRE_(((QTimeEvt *)QS_rxPriv_.currObj[obj_kind]) + ->act); + QS_TEC_PRE_(((QTimeEvt *)QS_rxPriv_.currObj[obj_kind]) + ->ctr); + QS_TEC_PRE_(((QTimeEvt *)QS_rxPriv_.currObj[obj_kind]) + ->interval); + QS_SIG_PRE_(((QTimeEvt *)QS_rxPriv_.currObj[obj_kind]) + ->super.sig); + QS_U8_PRE_ (((QTimeEvt *)QS_rxPriv_.currObj[obj_kind]) + ->super.refCtr_); + break; + default: + // intentionally empty + break; + } + QS_endRec_(); + QS_REC_DONE(); // user callback (if defined) + } + else { + QS_rxReportError_((int8_t)QS_RX_QUERY_CURR); + } +} + +//............................................................................ static void QS_rxPoke_(void) { uint8_t *ptr = (uint8_t *)QS_rxPriv_.currObj[AP_OBJ]; ptr = &ptr[l_rx.var.poke.offs]; @@ -1212,12 +1178,15 @@ static void QS_rxPoke_(void) { case 4: *(uint32_t *)ptr = l_rx.var.poke.data; break; - default: - Q_ERROR_ID(900); + default: { + Q_ERROR_INCRIT(900); break; + } } l_rx.var.poke.data = 0U; l_rx.var.poke.idx = 0U; l_rx.var.poke.offs += (uint16_t)l_rx.var.poke.size; } + +//! @endcond diff --git a/src/qs/qstamp.c b/src/qs/qstamp.c index 09ae4edc..d49de633 100644 --- a/src/qs/qstamp.c +++ b/src/qs/qstamp.c @@ -1,55 +1,49 @@ -/*$file${src::qs::qstamp.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* -* Model: qpc.qm -* File: ${src::qs::qstamp.c} -* -* This code has been generated by QM 5.2.4 . -* DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. -* -* This code is covered by the following QP license: -* License # : LicenseRef-QL-dual -* Issued to : Any user of the QP/C real-time embedded framework -* Framework(s) : qpc -* Support ends : 2023-12-31 -* License scope: -* -* Copyright (C) 2005 Quantum Leaps, LLC . -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -*/ -/*$endhead${src::qs::qstamp.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*! @file -* @brief Application build time-stamp -* @details -* This module needs to be re-compiled in every new software build. To achive -* this, it is recommended to delete the object file (qstamp.o, or qstamp.obj) -* in the build directory before each build. (Most development tools allow -* you to specify a pre-build command, which is the ideal place to delete -* the qstamp object file.) -*/ - +//$file${src::qs::qstamp.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// +// Model: qpc.qm +// File: ${src::qs::qstamp.c} +// +// This code has been generated by QM 5.3.0 . +// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. +// +// This code is covered by the following QP license: +// License # : LicenseRef-QL-dual +// Issued to : Any user of the QP/C real-time embedded framework +// Framework(s) : qpc +// Support ends : 2024-12-31 +// License scope: +// +// Copyright (C) 2005 Quantum Leaps, LLC . +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +// +//$endhead${src::qs::qstamp.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ #include "qstamp.h" -/*! the calendar date of the last translation of the form: "Mmm dd yyyy" */ +//! the calendar date of the last translation of the form: "Mmm dd yyyy" char const Q_BUILD_DATE[12] = __DATE__; -/*! the time of the last translation of the form: "hh:mm:ss" */ +//! the time of the last translation of the form: "hh:mm:ss" char const Q_BUILD_TIME[9] = __TIME__; diff --git a/src/qs/qutest.c b/src/qs/qutest.c index b6fd5b90..92ca219f 100644 --- a/src/qs/qutest.c +++ b/src/qs/qutest.c @@ -1,212 +1,218 @@ -/*$file${src::qs::qutest.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* -* Model: qpc.qm -* File: ${src::qs::qutest.c} -* -* This code has been generated by QM 5.2.4 . -* DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. -* -* This code is covered by the following QP license: -* License # : LicenseRef-QL-dual -* Issued to : Any user of the QP/C real-time embedded framework -* Framework(s) : qpc -* Support ends : 2023-12-31 -* License scope: -* -* Copyright (C) 2005 Quantum Leaps, LLC . -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -*/ -/*$endhead${src::qs::qutest.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*! @file -* @brief QUTest unit testing harness -*/ - -/* Include this content in the build only when Q_UTEST is defined */ +//$file${src::qs::qutest.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// +// Model: qpc.qm +// File: ${src::qs::qutest.c} +// +// This code has been generated by QM 5.3.0 . +// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. +// +// This code is covered by the following QP license: +// License # : LicenseRef-QL-dual +// Issued to : Any user of the QP/C real-time embedded framework +// Framework(s) : qpc +// Support ends : 2024-12-31 +// License scope: +// +// Copyright (C) 2005 Quantum Leaps, LLC . +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +// +//$endhead${src::qs::qutest.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +// only build when Q_UTEST is defined #ifdef Q_UTEST -#define QP_IMPL /* this is QP implementation */ -#include "qf_port.h" /* QF port */ -#include "qf_pkg.h" /* QF package-scope interface */ -#include "qassert.h" /* QP embedded systems-friendly assertions */ -#include "qs_port.h" /* include QS port */ -#include "qs_pkg.h" /* QS facilities for pre-defined trace records */ +#define QP_IMPL // this is QP implementation +#include "qp_port.h" // QP port +#include "qp_pkg.h" // QP package-scope interface +#include "qsafe.h" // QP Functional Safety (FuSa) Subsystem +#include "qs_port.h" // include QS port +#include "qs_pkg.h" // QS facilities for pre-defined trace records -/*==========================================================================*/ -/* QUTest unit testing harness */ -/*$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* Check for the minimum required QP version */ -#if (QP_VERSION < 700U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) -#error qpc version 7.0.0 or higher required +//============================================================================ +// QUTest unit testing harness +//$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// Check for the minimum required QP version +#if (QP_VERSION < 730U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) +#error qpc version 7.3.0 or higher required #endif -/*$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -/*$define${QUTest} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//$define${QS::QUTest} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +//$enddef${QS::QUTest} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -/*${QUTest::QS::testData} ..................................................*/ -struct QS_TestData QS_testData; +//============================================================================ +//! @cond INTERNAL -/*${QUTest::QS::test_pause_} ...............................................*/ +QSTestAttr QS_tstPriv_; + +//............................................................................ void QS_test_pause_(void) { QS_beginRec_((uint_fast8_t)QS_TEST_PAUSED); QS_endRec_(); QS_onTestLoop(); } -/*${QUTest::QS::getTestProbe_} .............................................*/ +//............................................................................ uint32_t QS_getTestProbe_(QSpyFunPtr const api) { uint32_t data = 0U; - uint_fast8_t i; - for (i = 0U; i < QS_testData.tpNum; ++i) { - uint_fast8_t j; + for (uint_fast8_t i = 0U; i < QS_tstPriv_.tpNum; ++i) { + if (QS_tstPriv_.tpBuf[i].addr == (QSFun)api) { + data = QS_tstPriv_.tpBuf[i].data; - if (QS_testData.tpBuf[i].addr == (QSFun)api) { - QS_CRIT_STAT_ - - data = QS_testData.tpBuf[i].data; - - QS_CRIT_E_(); + QS_CRIT_STAT + QS_CRIT_ENTRY(); + QS_MEM_SYS(); QS_beginRec_((uint_fast8_t)QS_TEST_PROBE_GET); - QS_TIME_PRE_(); /* timestamp */ - QS_FUN_PRE_(api); /* the calling API */ - QS_U32_PRE_(data); /* the Test-Probe data */ + QS_TIME_PRE_(); // timestamp + QS_FUN_PRE_(api); // the calling API + QS_U32_PRE_(data); // the Test-Probe data QS_endRec_(); - QS_CRIT_X_(); - QS_REC_DONE(); /* user callback (if defined) */ + QS_REC_DONE(); // user callback (if defined) - --QS_testData.tpNum; /* one less Test-Probe */ - /* move all remaining entries in the buffer up by one */ - for (j = i; j < QS_testData.tpNum; ++j) { - QS_testData.tpBuf[j] = QS_testData.tpBuf[j + 1U]; + --QS_tstPriv_.tpNum; // one less Test-Probe + // move all remaining entries in the buffer up by one + for (uint_fast8_t j = i; j < QS_tstPriv_.tpNum; ++j) { + QS_tstPriv_.tpBuf[j] = QS_tstPriv_.tpBuf[j + 1U]; } - break; /* we are done (Test-Probe retreived) */ + QS_MEM_APP(); + QS_CRIT_EXIT(); + break; // we are done (Test-Probe retreived) } } return data; } -/*$enddef${QUTest} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*..........................................................................*/ -Q_NORETURN Q_onAssert( - char const * module, - int_t location) +//............................................................................ +QSTimeCtr QS_onGetTime(void) { + return (++QS_tstPriv_.testTime); +} + +//............................................................................ +Q_NORETURN Q_onError( + char const * const module, + int_t const id) { - QS_BEGIN_NOCRIT_PRE_(QS_ASSERT_FAIL, 0U) + QS_beginRec_((uint_fast8_t)QS_ASSERT_FAIL); QS_TIME_PRE_(); - QS_U16_PRE_(location); + QS_U16_PRE_(id); QS_STR_PRE_((module != (char *)0) ? module : "?"); - QS_END_NOCRIT_PRE_() + QS_endRec_(); - QS_onFlush(); /* flush the assertion record to the host */ - QS_onCleanup(); /* cleanup after the failure */ - QS_onReset(); /* reset the target to prevent the code from continuing */ - for (;;) { /* QS_onReset() should not return, but to ensure no-return */ + QS_onFlush(); // flush the assertion record to the host + QS_onCleanup(); // cleanup after the failure + QS_onReset(); // reset the target to prevent the code from continuing + for (;;) { // QS_onReset() should not return, but to ensure no-return } } -/*..........................................................................*/ -QSTimeCtr QS_onGetTime(void) { - return (++QS_testData.testTime); -} -/*==========================================================================*/ -/* QP-stub for QUTest -* NOTE: The QP-stub is needed for unit testing QP applications, but might -* NOT be needed for testing QP itself. In that case, the build process -* can define Q_UTEST=0 to exclude the QP-stub from the build. -*/ -#if Q_UTEST != 0 +//! @endcond +//============================================================================ + +// QP-stub for QUTest +// NOTE: The QP-stub is needed for unit testing QP applications, but might +// NOT be needed for testing QP itself. In that case, the build process +// can define Q_UTEST=0 to exclude the QP-stub from the build. +#if (Q_UTEST != 0) Q_DEFINE_THIS_MODULE("qutest") -/*$define${QUTest-stub} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${QUTest-stub::QS::processTestEvts_} .....................................*/ +//............................................................................ void QS_processTestEvts_(void) { QS_TEST_PROBE_DEF(&QS_processTestEvts_) - /* return immediately (do nothing) for Test Probe != 0 */ + // return immediately (do nothing) for Test Probe != 0 QS_TEST_PROBE(return;) - while (QPSet_notEmpty(&QF_readySet_)) { - uint_fast8_t const p = QPSet_findMax(&QF_readySet_); + while (QPSet_notEmpty(&QS_tstPriv_.readySet)) { + uint_fast8_t const p = QPSet_findMax(&QS_tstPriv_.readySet); QActive * const a = QActive_registry_[p]; - /* perform the run-to-completion (RTC) step... - * 1. retrieve the event from the AO's event queue, which by this - * time must be non-empty and The "Vanialla" kernel asserts it. - * 2. dispatch the event to the AO's state machine. - * 3. determine if event is garbage and collect it if so - */ QEvt const * const e = QActive_get_(a); - QHSM_DISPATCH(&a->super, e, a->prio); - #if (QF_MAX_EPOOL > 0U) + QASM_DISPATCH(a, e, a->prio); +#if (QF_MAX_EPOOL > 0U) QF_gc(e); - #endif - if (a->eQueue.frontEvt == (QEvt *)0) { /* empty queue? */ - QPSet_remove(&QF_readySet_, p); +#endif + if (a->eQueue.frontEvt == (QEvt *)0) { // empty queue? + QPSet_remove(&QS_tstPriv_.readySet, p); +#ifndef Q_UNSAFE + QPSet_update_(&QS_tstPriv_.readySet, &QS_tstPriv_.readySet_dis); +#endif } } } -/*${QUTest-stub::QF::init} .................................................*/ -void QF_init(void) { - /* Clear the internal QF variables, so that the framework can start - * correctly even if the startup code fails to clear the uninitialized - * data (as is required by the C Standard). - */ - QF_maxPool_ = 0U; - QF_intLock_ = 0U; - QF_intNest_ = 0U; +//$define${QS::QUTest-stub} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv - QF_bzero(&QActive_registry_[0], sizeof(QActive_registry_)); - QF_bzero(&QF_readySet_, sizeof(QF_readySet_)); +//${QS::QUTest-stub::QF::init} ............................................... +void QF_init(void) { + // Clear the internal QF variables, so that the framework can start + // correctly even if the startup code fails to clear the uninitialized + // data (as is required by the C Standard). + QF_bzero_(&QF_priv_, sizeof(QF_priv_)); + QF_bzero_(&QS_tstPriv_, sizeof(QS_tstPriv_)); + QF_bzero_(&QActive_registry_[0], sizeof(QActive_registry_)); + + #ifndef Q_UNSAFE + QPSet_update_(&QS_tstPriv_.readySet, &QS_tstPriv_.readySet_dis); + #endif } -/*${QUTest-stub::QF::stop} .................................................*/ +//${QS::QUTest-stub::QF::stop} ............................................... void QF_stop(void) { QS_onReset(); } -/*${QUTest-stub::QF::run} ..................................................*/ +//${QS::QUTest-stub::QF::run} ................................................ int_t QF_run(void) { - /* function dictionaries for the standard API */ + QS_CRIT_STAT + QS_CRIT_ENTRY(); + QS_MEM_SYS(); + + // function dictionaries for the standard API QS_FUN_DICTIONARY(&QActive_post_); QS_FUN_DICTIONARY(&QActive_postLIFO_); QS_FUN_DICTIONARY(&QS_processTestEvts_); - /* produce the QS_QF_RUN trace record */ - QS_CRIT_STAT_ + // produce the QS_QF_RUN trace record QS_BEGIN_PRE_(QS_QF_RUN, 0U) QS_END_PRE_() - QS_processTestEvts_(); /* process all events posted so far */ - QS_onTestLoop(); /* run the test loop */ - QS_onCleanup(); /* application cleanup */ - return 0; /* return no error */ + QS_MEM_APP(); + QS_CRIT_EXIT(); + + QS_processTestEvts_(); // process all events posted so far + QS_onTestLoop(); // run the test loop + QS_onCleanup(); // application cleanup + return 0; // return no error } -/*${QUTest-stub::QActive} ..................................................*/ +//${QS::QUTest-stub::QActive} ................................................ -/*${QUTest-stub::QActive::start_} ..........................................*/ +//${QS::QUTest-stub::QActive::start_} ........................................ +//! @private @memberof QActive void QActive_start_(QActive * const me, QPrioSpec const prioSpec, QEvt const * * const qSto, @@ -218,150 +224,151 @@ void QActive_start_(QActive * const me, Q_UNUSED_PAR(stkSto); Q_UNUSED_PAR(stkSize); - me->prio = (uint8_t)(prioSpec & 0xFFU); /* QF-priority of the AO */ - me->pthre = (uint8_t)(prioSpec >> 8U); /* preemption-threshold */ - QActive_register_(me); /* make QF aware of this active object */ + me->prio = (uint8_t)(prioSpec & 0xFFU); // QF-prio. of the AO + me->pthre = (uint8_t)(prioSpec >> 8U); // preemption-threshold + QActive_register_(me); // make QF aware of this active object - QEQueue_init(&me->eQueue, qSto, qLen); /* initialize the built-in queue */ + QEQueue_init(&me->eQueue, qSto, qLen); - QHSM_INIT(&me->super, par, me->prio); /* the top-most initial tran. */ + // top-most initial tran. (virtual call) + (*me->super.vptr->init)(&me->super, par, me->prio); } -/*${QUTest-stub::QActive::stop} ............................................*/ -#ifdef QF_ACTIVE_STOP +//${QS::QUTest-stub::QActive::stop} .......................................... +#ifdef QACTIVE_CAN_STOP +//! @protected @memberof QActive void QActive_stop(QActive * const me) { - QActive_unsubscribeAll(me); /* unsubscribe from all events */ - QActive_unregister_(me); /* un-register this active object */ + QActive_unsubscribeAll(me); // unsubscribe from all events + QActive_unregister_(me); // un-register this active object } -#endif /* def QF_ACTIVE_STOP */ +#endif // def QACTIVE_CAN_STOP -/*${QUTest-stub::QTimeEvt} .................................................*/ +//${QS::QUTest-stub::QTimeEvt} ............................................... -/*${QUTest-stub::QTimeEvt::tick1_} .........................................*/ +//${QS::QUTest-stub::QTimeEvt::tick1_} ....................................... +//! @private @memberof QTimeEvt void QTimeEvt_tick1_( uint_fast8_t const tickRate, void const * const sender) { - QF_CRIT_STAT_ - QF_CRIT_E_(); + QS_CRIT_STAT + QS_CRIT_ENTRY(); + QS_MEM_SYS(); QTimeEvt *prev = &QTimeEvt_timeEvtHead_[tickRate]; - QS_BEGIN_NOCRIT_PRE_(QS_QF_TICK, 0U) + QS_BEGIN_PRE_(QS_QF_TICK, 0U) ++prev->ctr; - QS_TEC_PRE_(prev->ctr); /* tick ctr */ - QS_U8_PRE_(tickRate); /* tick rate */ - QS_END_NOCRIT_PRE_() + QS_TEC_PRE_(prev->ctr); // tick ctr + QS_U8_PRE_(tickRate); // tick rate + QS_END_PRE_() - /* is current Time Event object provided? */ + // is current Time Event object provided? QTimeEvt *t = (QTimeEvt *)QS_rxPriv_.currObj[TE_OBJ]; if (t != (QTimeEvt *)0) { - /* the time event must be armed */ - Q_ASSERT_ID(810, t->ctr != 0U); + // the time event must be armed + Q_ASSERT_INCRIT(810, t->ctr != 0U); - /* temp. for volatile */ - QActive * const act = (QActive * const)(t->act); + QActive * const act = (QActive *)(t->act); - /* the recipient AO must be provided */ - Q_ASSERT_ID(820, act != (QActive *)0); + // the recipient AO must be provided + Q_ASSERT_INCRIT(820, act != (QActive *)0); - /* periodic time evt? */ + // periodic time evt? if (t->interval != 0U) { - t->ctr = t->interval; /* rearm the time event */ + t->ctr = t->interval; // rearm the time event } - else { /* one-shot time event: automatically disarm */ - t->ctr = 0U; /* auto-disarm */ - /* mark time event 't' as NOT linked */ + else { // one-shot time event: automatically disarm + t->ctr = 0U; // auto-disarm + // mark time event 't' as NOT linked t->super.refCtr_ &= (uint8_t)(~(uint8_t)QTE_IS_LINKED); - QS_BEGIN_NOCRIT_PRE_(QS_QF_TIMEEVT_AUTO_DISARM, act->prio) - QS_OBJ_PRE_(t); /* this time event object */ - QS_OBJ_PRE_(act); /* the target AO */ - QS_U8_PRE_(tickRate); /* tick rate */ - QS_END_NOCRIT_PRE_() + QS_BEGIN_PRE_(QS_QF_TIMEEVT_AUTO_DISARM, act->prio) + QS_OBJ_PRE_(t); // this time event object + QS_OBJ_PRE_(act); // the target AO + QS_U8_PRE_(tickRate); // tick rate + QS_END_PRE_() } - QS_BEGIN_NOCRIT_PRE_(QS_QF_TIMEEVT_POST, act->prio) - QS_TIME_PRE_(); /* timestamp */ - QS_OBJ_PRE_(t); /* the time event object */ - QS_SIG_PRE_(t->super.sig); /* signal of this time event */ - QS_OBJ_PRE_(act); /* the target AO */ - QS_U8_PRE_(tickRate); /* tick rate */ - QS_END_NOCRIT_PRE_() + QS_BEGIN_PRE_(QS_QF_TIMEEVT_POST, act->prio) + QS_TIME_PRE_(); // timestamp + QS_OBJ_PRE_(t); // the time event object + QS_SIG_PRE_(t->super.sig); // signal of this time event + QS_OBJ_PRE_(act); // the target AO + QS_U8_PRE_(tickRate); // tick rate + QS_END_PRE_() + QS_MEM_APP(); + QS_CRIT_EXIT(); // exit critical section before posting - QF_CRIT_X_(); /* exit critical section before posting */ + QACTIVE_POST(act, &t->super, sender); // asserts if queue overflows - QACTIVE_POST(act, &t->super, sender); /* asserts if queue overflows */ - - QF_CRIT_E_(); + QS_CRIT_ENTRY(); + QS_MEM_SYS(); } - /* update the linked list of time events */ + // update the linked list of time events for (;;) { - t = prev->next; /* advance down the time evt. list */ + t = prev->next; // advance down the time evt. list - /* end of the list? */ + // end of the list? if (t == (QTimeEvt *)0) { - /* any new time events armed since the last QTimeEvt_tick_()? */ + // any new time events armed since the last QTimeEvt_tick_()? if (QTimeEvt_timeEvtHead_[tickRate].act != (void *)0) { - /* sanity check */ - Q_ASSERT_CRIT_(830, prev != (QTimeEvt *)0); + // sanity check + Q_ASSERT_INCRIT(830, prev != (QTimeEvt *)0); prev->next = (QTimeEvt *)QTimeEvt_timeEvtHead_[tickRate].act; QTimeEvt_timeEvtHead_[tickRate].act = (void *)0; - t = prev->next; /* switch to the new list */ + t = prev->next; // switch to the new list } else { - break; /* all currently armed time evts. processed */ + break; // all currently armed time evts. processed } } - /* time event scheduled for removal? */ + // time event scheduled for removal? if (t->ctr == 0U) { prev->next = t->next; - /* mark time event 't' as NOT linked */ + // mark time event 't' as NOT linked t->super.refCtr_ &= (uint8_t)(~(uint8_t)QTE_IS_LINKED); - /* do NOT advance the prev pointer */ - QF_CRIT_X_(); /* exit crit. section to reduce latency */ - - /* prevent merging critical sections, see NOTE1 below */ - QF_CRIT_EXIT_NOP(); + // do NOT advance the prev pointer + QS_MEM_APP(); + QS_CRIT_EXIT(); // exit crit. section to reduce latency } else { - prev = t; /* advance to this time event */ - QF_CRIT_X_(); /* exit crit. section to reduce latency */ - - /* prevent merging critical sections, see NOTE1 below */ - QF_CRIT_EXIT_NOP(); + prev = t; // advance to this time event + QS_MEM_APP(); + QS_CRIT_EXIT(); // exit crit. section to reduce latency } - QF_CRIT_E_(); /* re-enter crit. section to continue */ + QS_CRIT_ENTRY(); // re-enter crit. section to continue + QS_MEM_SYS(); } - QF_CRIT_X_(); - + QS_MEM_APP(); + QS_CRIT_EXIT(); } -/*${QUTest-stub::QHsmDummy} ................................................*/ +//${QS::QUTest-stub::QHsmDummy} .............................................. -/*${QUTest-stub::QHsmDummy::ctor} ..........................................*/ +//${QS::QUTest-stub::QHsmDummy::ctor} ........................................ +//! @public @memberof QHsmDummy void QHsmDummy_ctor(QHsmDummy * const me) { - static struct QHsmVtable const vtable = { /* QHsm virtual table */ + static struct QAsmVtable const vtable = { &QHsmDummy_init_, &QHsmDummy_dispatch_ #ifdef Q_SPY ,&QHsm_getStateHandler_ #endif }; - /* superclass' ctor */ - QHsm_ctor(&me->super, Q_STATE_CAST(0)); - me->super.vptr = &vtable; /* hook the vptr */ + me->super.vptr = &vtable; // hook the vptr } -/*${QUTest-stub::QHsmDummy::init_} .........................................*/ +//${QS::QUTest-stub::QHsmDummy::init_} ....................................... +//! @private @memberof QHsmDummy void QHsmDummy_init_( - QHsm * const me, + QAsm * const me, void const * const par, uint_fast8_t const qs_id) { @@ -374,52 +381,60 @@ void QHsmDummy_init_( } #endif - QS_CRIT_STAT_ + QS_CRIT_STAT + QS_CRIT_ENTRY(); + QS_MEM_SYS(); QS_BEGIN_PRE_(QS_QEP_STATE_INIT, qs_id) - QS_OBJ_PRE_(me); /* this state machine object */ - QS_FUN_PRE_(me->state.fun); /* the source state */ - QS_FUN_PRE_(me->temp.fun); /* the target of the initial transition */ + QS_OBJ_PRE_(me); // this state machine object + QS_FUN_PRE_(me->state.fun); // the source state + QS_FUN_PRE_(me->temp.fun); // the target of the initial tran. QS_END_PRE_() + QS_MEM_APP(); + QS_CRIT_EXIT(); } -/*${QUTest-stub::QHsmDummy::dispatch_} .....................................*/ +//${QS::QUTest-stub::QHsmDummy::dispatch_} ................................... +//! @private @memberof QHsmDummy void QHsmDummy_dispatch_( - QHsm * const me, + QAsm * const me, QEvt const * const e, uint_fast8_t const qs_id) { - QS_CRIT_STAT_ + QS_CRIT_STAT + QS_CRIT_ENTRY(); + QS_MEM_SYS(); QS_BEGIN_PRE_(QS_QEP_DISPATCH, qs_id) - QS_TIME_PRE_(); /* time stamp */ - QS_SIG_PRE_(e->sig); /* the signal of the event */ - QS_OBJ_PRE_(me); /* this state machine object */ - QS_FUN_PRE_(me->state.fun); /* the current state */ + QS_TIME_PRE_(); // time stamp + QS_SIG_PRE_(e->sig); // the signal of the event + QS_OBJ_PRE_(me); // this state machine object + QS_FUN_PRE_(me->state.fun); // the current state QS_END_PRE_() + QS_MEM_APP(); + QS_CRIT_EXIT(); } -/*${QUTest-stub::QActiveDummy} .............................................*/ +//${QS::QUTest-stub::QActiveDummy} ........................................... -/*${QUTest-stub::QActiveDummy::ctor} .......................................*/ +//${QS::QUTest-stub::QActiveDummy::ctor} ..................................... +//! @public @memberof QActiveDummy void QActiveDummy_ctor(QActiveDummy * const me) { - static QActiveVtable const vtable = { /* QActive virtual table */ - { &QActiveDummy_init_, - &QActiveDummy_dispatch_ - #ifdef Q_SPY - ,&QHsm_getStateHandler_ - #endif - }, - &QActiveDummy_start_, - &QActiveDummy_post_, - &QActiveDummy_postLIFO_ - }; - /* superclass' ctor */ + // superclass' ctor QActive_ctor(&me->super, Q_STATE_CAST(0)); - me->super.super.vptr = &vtable.super; /* hook the vptr */ + + static struct QAsmVtable const vtable = { + &QActiveDummy_init_, + &QActiveDummy_dispatch_ + #ifdef Q_SPY + ,&QHsm_getStateHandler_ + #endif + }; + me->super.super.vptr = &vtable; // hook the vptr } -/*${QUTest-stub::QActiveDummy::init_} ......................................*/ +//${QS::QUTest-stub::QActiveDummy::init_} .................................... +//! @private @memberof QActiveDummy void QActiveDummy_init_( - QHsm * const me, + QAsm * const me, void const * const par, uint_fast8_t const qs_id) { @@ -428,9 +443,10 @@ void QActiveDummy_init_( QHsmDummy_init_(me, par, ((QActive const *)me)->prio); } -/*${QUTest-stub::QActiveDummy::dispatch_} ..................................*/ +//${QS::QUTest-stub::QActiveDummy::dispatch_} ................................ +//! @private @memberof QActiveDummy void QActiveDummy_dispatch_( - QHsm * const me, + QAsm * const me, QEvt const * const e, uint_fast8_t const qs_id) { @@ -439,35 +455,9 @@ void QActiveDummy_dispatch_( QHsmDummy_dispatch_(me, e, ((QActive const *)me)->prio); } -/*${QUTest-stub::QActiveDummy::start_} .....................................*/ -void QActiveDummy_start_( - QActive * const me, - QPrioSpec const prioSpec, - QEvt const * * const qSto, - uint_fast16_t const qLen, - void * const stkSto, - uint_fast16_t const stkSize, - void const * const par) -{ - /* No special preconditions for checking parameters to allow starting - * dummy AOs the exact same way as the real counterparts. - */ - Q_UNUSED_PAR(qSto); - Q_UNUSED_PAR(qLen); - Q_UNUSED_PAR(stkSto); - Q_UNUSED_PAR(stkSize); - - me->prio = (uint8_t)(prioSpec & 0xFFU); /* QF-priority of the AO */ - me->pthre = (uint8_t)(prioSpec >> 8U); /* preemption-threshold */ - QActive_register_(me); /* make QF aware of this active object */ - - /* the top-most initial tran. (virtual) */ - QHSM_INIT(&me->super, par, me->prio); - //QS_FLUSH(); -} - -/*${QUTest-stub::QActiveDummy::post_} ......................................*/ -bool QActiveDummy_post_( +//${QS::QUTest-stub::QActiveDummy::fakePost_} ................................ +//! @private @memberof QActiveDummy +bool QActiveDummy_fakePost_( QActive * const me, QEvt const * const e, uint_fast16_t const margin, @@ -475,103 +465,102 @@ bool QActiveDummy_post_( { QS_TEST_PROBE_DEF(&QActive_post_) - /* test-probe#1 for faking queue overflow */ + QF_CRIT_STAT + QF_CRIT_ENTRY(); + QF_MEM_SYS(); + + // test-probe#1 for faking queue overflow bool status = true; QS_TEST_PROBE_ID(1, status = false; if (margin == QF_NO_MARGIN) { - /* fake assertion Mod=qf_actq,Loc=110 */ - Q_onAssert("qf_actq", 110); + // fake assertion Mod=qf_actq,Loc=110 + Q_onError("qf_actq", 110); } ) - QF_CRIT_STAT_ - QF_CRIT_E_(); - - /* is it a dynamic event? */ - if (e->poolId_ != 0U) { - QEvt_refCtr_inc_(e); /* increment the reference counter */ + // is it a mutable event? + if (QEvt_getPoolId_(e) != 0U) { + QEvt_refCtr_inc_(e); } uint_fast8_t const rec = (status ? (uint_fast8_t)QS_QF_ACTIVE_POST : (uint_fast8_t)QS_QF_ACTIVE_POST_ATTEMPT); - QS_BEGIN_NOCRIT_PRE_(rec, me->prio) - QS_TIME_PRE_(); /* timestamp */ - QS_OBJ_PRE_(sender); /* the sender object */ - QS_SIG_PRE_(e->sig); /* the signal of the event */ - QS_OBJ_PRE_(me); /* this active object */ - QS_2U8_PRE_(e->poolId_, e->refCtr_); /* pool Id & refCtr of the evt */ - QS_EQC_PRE_(0U); /* number of free entries */ - QS_EQC_PRE_(margin); /* margin requested */ - QS_END_NOCRIT_PRE_() + QS_BEGIN_PRE_(rec, me->prio) + QS_TIME_PRE_(); // timestamp + QS_OBJ_PRE_(sender); // the sender object + QS_SIG_PRE_(e->sig); // the signal of the event + QS_OBJ_PRE_(me); // this active object + QS_2U8_PRE_(QEvt_getPoolId_(e), e->refCtr_); // poolId & refCtr + QS_EQC_PRE_(0U); // # free entries + QS_EQC_PRE_(margin); // margin requested + QS_END_PRE_() - /* callback to examine the posted event under the same conditions - * as producing the #QS_QF_ACTIVE_POST trace record, which are: - * the local filter for this AO ('me->prio') is set - */ - if ((QS_priv_.locFilter[me->prio >> 3U] - & (1U << (me->prio & 7U))) != 0U) - { + // callback to examine the posted event under the same conditions + // as producing the #QS_QF_ACTIVE_POST trace record, which are: + // the local filter for this AO ('me->prio') is set + if (QS_LOC_CHECK_(me->prio)) { QS_onTestPost(sender, me, e, status); } - QF_CRIT_X_(); + QF_MEM_APP(); + QF_CRIT_EXIT(); - /* recycle the event immediately, because it was not really posted */ + // recycle the event immediately, because it was not really posted #if (QF_MAX_EPOOL > 0U) QF_gc(e); #endif - return status; /* the event is "posted" correctly */ + return status; // the event is "posted" correctly } -/*${QUTest-stub::QActiveDummy::postLIFO_} ..................................*/ -void QActiveDummy_postLIFO_( +//${QS::QUTest-stub::QActiveDummy::fakePostLIFO_} ............................ +//! @private @memberof QActiveDummy +void QActiveDummy_fakePostLIFO_( QActive * const me, QEvt const * const e) { QS_TEST_PROBE_DEF(&QActive_postLIFO_) - /* test-probe#1 for faking queue overflow */ + QF_CRIT_STAT + QF_CRIT_ENTRY(); + QF_MEM_SYS(); + + // test-probe#1 for faking queue overflow QS_TEST_PROBE_ID(1, - /* fake assertion Mod=qf_actq,Loc=210 */ - Q_onAssert("qf_actq", 210); + // fake assertion Mod=qf_actq,Loc=210 + Q_onError("qf_actq", 210); ) - QF_CRIT_STAT_ - QF_CRIT_E_(); - - /* is it a dynamic event? */ - if (e->poolId_ != 0U) { - QEvt_refCtr_inc_(e); /* increment the reference counter */ + // is it a mutable event? + if (QEvt_getPoolId_(e) != 0U) { + QEvt_refCtr_inc_(e); } - QS_BEGIN_NOCRIT_PRE_(QS_QF_ACTIVE_POST_LIFO, me->prio) - QS_TIME_PRE_(); /* timestamp */ - QS_SIG_PRE_(e->sig); /* the signal of this event */ - QS_OBJ_PRE_(me); /* this active object */ - QS_2U8_PRE_(e->poolId_, e->refCtr_); /* pool Id & refCtr of the evt */ - QS_EQC_PRE_(0U); /* number of free entries */ - QS_EQC_PRE_(0U); /* min number of free entries */ - QS_END_NOCRIT_PRE_() + QS_BEGIN_PRE_(QS_QF_ACTIVE_POST_LIFO, me->prio) + QS_TIME_PRE_(); // timestamp + QS_SIG_PRE_(e->sig); // the signal of this event + QS_OBJ_PRE_(me); // this active object + QS_2U8_PRE_(QEvt_getPoolId_(e), e->refCtr_); // poolId & refCtr + QS_EQC_PRE_(0U); // # free entries + QS_EQC_PRE_(0U); // min # free entries + QS_END_PRE_() - /* callback to examine the posted event under the same conditions - * as producing the #QS_QF_ACTIVE_POST trace record, which are: - * the local filter for this AO ('me->prio') is set - */ - if ((QS_priv_.locFilter[me->prio >> 3U] - & (1U << (me->prio & 7U))) != 0U) - { + // callback to examine the posted event under the same conditions + // as producing the #QS_QF_ACTIVE_POST trace record, which are: + // the local filter for this AO ('me->prio') is set + if (QS_LOC_CHECK_(me->prio)) { QS_onTestPost((QActive *)0, me, e, true); } + QF_MEM_APP(); + QF_CRIT_EXIT(); - QF_CRIT_X_(); - - /* recycle the event immediately, because it was not really posted */ + // recycle the event immediately, because it was not really posted #if (QF_MAX_EPOOL > 0U) QF_gc(e); #endif } -/*$enddef${QUTest-stub} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -#endif /* Q_UTEST != 0 */ +//$enddef${QS::QUTest-stub} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -#endif /* Q_UTEST */ +#endif // Q_UTEST != 0 + +#endif // Q_UTEST diff --git a/src/qv/qv.c b/src/qv/qv.c index 2b124e0e..2694cda3 100644 --- a/src/qv/qv.c +++ b/src/qv/qv.c @@ -1,199 +1,220 @@ -/*$file${src::qv::qv.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* -* Model: qpc.qm -* File: ${src::qv::qv.c} -* -* This code has been generated by QM 5.2.4 . -* DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. -* -* This code is covered by the following QP license: -* License # : LicenseRef-QL-dual -* Issued to : Any user of the QP/C real-time embedded framework -* Framework(s) : qpc -* Support ends : 2023-12-31 -* License scope: -* -* Copyright (C) 2005 Quantum Leaps, LLC . -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -*/ -/*$endhead${src::qv::qv.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*! @file -* @brief Cooperative QV kernel, implementation of kernel-specific functions. -*/ -#define QP_IMPL /* this is QP implementation */ -#include "qf_port.h" /* QF port */ -#include "qf_pkg.h" /* QF package-scope internal interface */ -#include "qassert.h" /* QP embedded systems-friendly assertions */ -#ifdef Q_SPY /* QS software tracing enabled? */ - #include "qs_port.h" /* QS port */ - #include "qs_pkg.h" /* QS facilities for pre-defined trace records */ +//$file${src::qv::qv.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// +// Model: qpc.qm +// File: ${src::qv::qv.c} +// +// This code has been generated by QM 5.3.0 . +// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. +// +// This code is covered by the following QP license: +// License # : LicenseRef-QL-dual +// Issued to : Any user of the QP/C real-time embedded framework +// Framework(s) : qpc +// Support ends : 2024-12-31 +// License scope: +// +// Copyright (C) 2005 Quantum Leaps, LLC . +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +// +//$endhead${src::qv::qv.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +#define QP_IMPL // this is QP implementation +#include "qp_port.h" // QP port +#include "qp_pkg.h" // QP package-scope internal interface +#include "qsafe.h" // QP Functional Safety (FuSa) Subsystem +#ifdef Q_SPY // QS software tracing enabled? + #include "qs_port.h" // QS port + #include "qs_pkg.h" // QS facilities for pre-defined trace records #else - #include "qs_dummy.h" /* disable the QS software tracing */ -#endif /* Q_SPY */ + #include "qs_dummy.h" // disable the QS software tracing +#endif // Q_SPY -/* protection against including this source file in a wrong project */ -#ifndef QP_INC_QV_H_ +// protection against including this source file in a wrong project +#ifndef QV_H_ #error "Source file included in a project NOT based on the QV kernel" -#endif /* QP_INC_QV_H_ */ +#endif // QV_H_ Q_DEFINE_THIS_MODULE("qv") -/*==========================================================================*/ -/*$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* Check for the minimum required QP version */ -#if (QP_VERSION < 700U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) -#error qpc version 7.0.0 or higher required +//$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// Check for the minimum required QP version +#if (QP_VERSION < 730U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) +#error qpc version 7.3.0 or higher required #endif -/*$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -/*$define${QV::QV-base} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/*$enddef${QV::QV-base} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*$define${QV::QF-cust} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//$define${QV::QV-base} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/*${QV::QF-cust::init} .....................................................*/ +//${QV::QV-base::priv_} ...................................................... +QV_Attr QV_priv_; +//$enddef${QV::QV-base} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +//$define${QV::QF-cust} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${QV::QF-cust::init} ....................................................... +//! @static @public @memberof QF void QF_init(void) { - #if (QF_MAX_EPOOL > 0U) - QF_maxPool_ = 0U; - #endif + QF_bzero_(&QF_priv_, sizeof(QF_priv_)); + QF_bzero_(&QV_priv_, sizeof(QV_priv_)); + QF_bzero_(&QTimeEvt_timeEvtHead_[0], sizeof(QTimeEvt_timeEvtHead_)); + QF_bzero_(&QActive_registry_[0], sizeof(QActive_registry_)); - QF_bzero(&QTimeEvt_timeEvtHead_[0], sizeof(QTimeEvt_timeEvtHead_)); - QF_bzero(&QActive_registry_[0], sizeof(QActive_registry_)); - QF_bzero(&QF_readySet_, sizeof(QF_readySet_)); + #ifndef Q_UNSAFE + QPSet_update_(&QV_priv_.readySet, &QV_priv_.readySet_dis); + #endif #ifdef QV_INIT - QV_INIT(); /* port-specific initialization of the QV kernel */ + QV_INIT(); // port-specific initialization of the QV kernel #endif } -/*${QV::QF-cust::stop} .....................................................*/ +//${QV::QF-cust::stop} ....................................................... +//! @static @public @memberof QF void QF_stop(void) { - QF_onCleanup(); /* application-specific cleanup callback */ - /* nothing else to do for the cooperative QV kernel */ + QF_onCleanup(); // application-specific cleanup callback + // nothing else to do for the cooperative QV kernel } -/*${QV::QF-cust::run} ......................................................*/ +//${QV::QF-cust::run} ........................................................ +//! @static @public @memberof QF int_t QF_run(void) { #ifdef Q_SPY - /* produce the QS_QF_RUN trace record */ + // produce the QS_QF_RUN trace record QF_INT_DISABLE(); + QF_MEM_SYS(); QS_beginRec_((uint_fast8_t)QS_QF_RUN); QS_endRec_(); + QF_MEM_APP(); QF_INT_ENABLE(); - #endif /* Q_SPY */ + #endif // Q_SPY - QF_onStartup(); /* application-specific startup callback */ + QF_onStartup(); // application-specific startup callback QF_INT_DISABLE(); + QF_MEM_SYS(); #ifdef QV_START - QV_START(); /* port-specific startup of the QV kernel */ + QV_START(); // port-specific startup of the QV kernel #endif #if (defined QF_ON_CONTEXT_SW) || (defined Q_SPY) - uint8_t pprev = 0U; /* previously used priority */ - #endif /* (defined QF_ON_CONTEXT_SW) || (defined Q_SPY) */ + uint8_t pprev = 0U; // previously used prio. + #endif - for (;;) { /* QV event loop... */ + for (;;) { // QV event loop... - /* find the maximum priority AO ready to run */ - if (QPSet_notEmpty(&QF_readySet_)) { - uint8_t const p = (uint8_t)QPSet_findMax(&QF_readySet_); + // check internal integrity (duplicate inverse storage) + Q_ASSERT_INCRIT(202, QPSet_verify_(&QV_priv_.readySet, + &QV_priv_.readySet_dis)); + + // find the maximum prio. AO ready to run + if (QPSet_notEmpty(&QV_priv_.readySet)) { + + uint8_t const p = (uint8_t)QPSet_findMax(&QV_priv_.readySet); QActive * const a = QActive_registry_[p]; #if (defined QF_ON_CONTEXT_SW) || (defined Q_SPY) - QS_BEGIN_NOCRIT_PRE_(QS_SCHED_NEXT, p) - QS_TIME_PRE_(); /* timestamp */ - QS_2U8_PRE_(p, /* priority of the scheduled AO */ - pprev); /* previous priority */ - QS_END_NOCRIT_PRE_() + QS_BEGIN_PRE_(QS_SCHED_NEXT, p) + QS_TIME_PRE_(); // timestamp + QS_2U8_PRE_(p, pprev); // scheduled prio & previous prio + QS_END_PRE_() #ifdef QF_ON_CONTEXT_SW QF_onContextSw(((pprev != 0U) ? QActive_registry_[pprev] : (QActive *)0), a); - #endif /* QF_ON_CONTEXT_SW */ + #endif // QF_ON_CONTEXT_SW - pprev = p; /* update previous priority */ - #endif /* (defined QF_ON_CONTEXT_SW) || (defined Q_SPY) */ + pprev = p; // update previous prio. + #endif // (defined QF_ON_CONTEXT_SW) || (defined Q_SPY) + QF_MEM_APP(); QF_INT_ENABLE(); - /* perform the run-to-completion (RTC) step... - * 1. retrieve the event from the AO's event queue, which - * by this time must be non-empty (and QV asserts it). - * 2. dispatch the event to the AO's state machine. - * 3. determine if event is garbage and collect it if so - */ QEvt const * const e = QActive_get_(a); - QHSM_DISPATCH(&a->super, e, a->prio); + // NOTE QActive_get_() performs QS_MEM_APP() before return + + // dispatch event (virtual call) + (*a->super.vptr->dispatch)(&a->super, e, p); #if (QF_MAX_EPOOL > 0U) QF_gc(e); #endif QF_INT_DISABLE(); + QF_MEM_SYS(); - if (a->eQueue.frontEvt == (QEvt *)0) { /* empty queue? */ - QPSet_remove(&QF_readySet_, p); + if (a->eQueue.frontEvt == (QEvt *)0) { // empty queue? + QPSet_remove(&QV_priv_.readySet, p); + #ifndef Q_UNSAFE + QPSet_update_(&QV_priv_.readySet, &QV_priv_.readySet_dis); + #endif } } - else { /* no AO ready to run --> idle */ + else { // no AO ready to run --> idle #if (defined QF_ON_CONTEXT_SW) || (defined Q_SPY) if (pprev != 0U) { - QS_BEGIN_NOCRIT_PRE_(QS_SCHED_IDLE, pprev) - QS_TIME_PRE_(); /* timestamp */ - QS_U8_PRE_(pprev); /* previous priority */ - QS_END_NOCRIT_PRE_() + QS_BEGIN_PRE_(QS_SCHED_IDLE, pprev) + QS_TIME_PRE_(); // timestamp + QS_U8_PRE_(pprev); // previous prio + QS_END_PRE_() #ifdef QF_ON_CONTEXT_SW QF_onContextSw(QActive_registry_[pprev], (QActive *)0); - #endif /* QF_ON_CONTEXT_SW */ + #endif // QF_ON_CONTEXT_SW - pprev = 0U; /* update previous priority */ + pprev = 0U; // update previous prio. } - #endif /* (defined QF_ON_CONTEXT_SW) || (defined Q_SPY) */ + #endif // (defined QF_ON_CONTEXT_SW) || (defined Q_SPY) - /* QV_onIdle() must be called with interrupts DISABLED - * because the determination of the idle condition (all event - * queues empty) can change at any time by an interrupt posting - * events to a queue. - * - * NOTE: QV_onIdle() MUST enable interrupts internally, - * ideally at the same time as putting the CPU into a power- - * saving mode. - */ + QF_MEM_APP(); + + // QV_onIdle() must be called with interrupts DISABLED + // because the determination of the idle condition (all event + // queues empty) can change at any time by an interrupt posting + // events to a queue. + // + // NOTE: QV_onIdle() MUST enable interrupts internally, + // ideally at the same time as putting the CPU into a power- + // saving mode. QV_onIdle(); - QF_INT_DISABLE(); /* disable interrupts before looping back */ + QF_INT_DISABLE(); // disable interrupts before looping back + QF_MEM_SYS(); } } - #ifdef __GNUC__ /* GNU compiler? */ + #ifdef __GNUC__ // GNU compiler? return 0; #endif } -/*$enddef${QV::QF-cust} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*$define${QV::QActive} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//$enddef${QV::QF-cust} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -/*${QV::QActive} ...........................................................*/ +//$define${QV::QActive} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/*${QV::QActive::start_} ...................................................*/ +//${QV::QActive} ............................................................. + +//${QV::QActive::start_} ..................................................... +//! @public @memberof QActive void QActive_start_(QActive * const me, QPrioSpec const prioSpec, QEvt const * * const qSto, @@ -202,21 +223,22 @@ void QActive_start_(QActive * const me, uint_fast16_t const stkSize, void const * const par) { - Q_UNUSED_PAR(stkSto); /* not needed in QV */ - Q_UNUSED_PAR(stkSize); /* not needed in QV */ + Q_UNUSED_PAR(stkSto); // not needed in QV + Q_UNUSED_PAR(stkSize); // not needed in QV - /*! @pre Stack storage must not be provided because the QV kernel - * does not need per-AO stacks. - */ - Q_REQUIRE_ID(500, stkSto == (void *)0); + QF_CRIT_STAT + QF_CRIT_ENTRY(); + Q_REQUIRE_INCRIT(300, stkSto == (void *)0); + QF_CRIT_EXIT(); - me->prio = (uint8_t)(prioSpec & 0xFFU); /* QF-priority of the AO */ - me->pthre = (uint8_t)(prioSpec >> 8U); /* preemption-threshold */ - QActive_register_(me); /* make QF aware of this active object */ + me->prio = (uint8_t)(prioSpec & 0xFFU); // QF-prio. of the AO + me->pthre = (uint8_t)(prioSpec >> 8U); // preemption-threshold + QActive_register_(me); // make QF aware of this active object - QEQueue_init(&me->eQueue, qSto, qLen); /* init the built-in queue */ + QEQueue_init(&me->eQueue, qSto, qLen); // init the built-in queue - QHSM_INIT(&me->super, par, me->prio); /* top-most initial tran. */ - QS_FLUSH(); /* flush the trace buffer to the host */ + // top-most initial tran. (virtual call) + (*me->super.vptr->init)(&me->super, par, me->prio); + QS_FLUSH(); // flush the trace buffer to the host } -/*$enddef${QV::QActive} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$enddef${QV::QActive} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/src/qxk/qxk.c b/src/qxk/qxk.c index c68d7161..a60f2864 100644 --- a/src/qxk/qxk.c +++ b/src/qxk/qxk.c @@ -1,219 +1,476 @@ -/*$file${src::qxk::qxk.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* -* Model: qpc.qm -* File: ${src::qxk::qxk.c} -* -* This code has been generated by QM 5.2.4 . -* DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. -* -* This code is covered by the following QP license: -* License # : LicenseRef-QL-dual -* Issued to : Any user of the QP/C real-time embedded framework -* Framework(s) : qpc -* Support ends : 2023-12-31 -* License scope: -* -* Copyright (C) 2005 Quantum Leaps, LLC . -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -*/ -/*$endhead${src::qxk::qxk.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*! @file -* @brief QXK preemptive dual-mode kernel core functions -*/ -#define QP_IMPL /* this is QP implementation */ -#include "qf_port.h" /* QF port */ -#include "qf_pkg.h" /* QF package-scope internal interface */ -#include "qassert.h" /* QP embedded systems-friendly assertions */ -#ifdef Q_SPY /* QS software tracing enabled? */ - #include "qs_port.h" /* QS port */ - #include "qs_pkg.h" /* QS facilities for pre-defined trace records */ +//$file${src::qxk::qxk.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// +// Model: qpc.qm +// File: ${src::qxk::qxk.c} +// +// This code has been generated by QM 5.3.0 . +// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. +// +// This code is covered by the following QP license: +// License # : LicenseRef-QL-dual +// Issued to : Any user of the QP/C real-time embedded framework +// Framework(s) : qpc +// Support ends : 2024-12-31 +// License scope: +// +// Copyright (C) 2005 Quantum Leaps, LLC . +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +// +//$endhead${src::qxk::qxk.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +#define QP_IMPL // this is QP implementation +#include "qp_port.h" // QP port +#include "qp_pkg.h" // QP package-scope interface +#include "qsafe.h" // QP Functional Safety (FuSa) Subsystem +#ifdef Q_SPY // QS software tracing enabled? + #include "qs_port.h" // QS port + #include "qs_pkg.h" // QS facilities for pre-defined trace records #else - #include "qs_dummy.h" /* disable the QS software tracing */ -#endif /* Q_SPY */ + #include "qs_dummy.h" // disable the QS software tracing +#endif // Q_SPY -/* protection against including this source file in a wrong project */ -#ifndef QP_INC_QXK_H_ +// protection against including this source file in a wrong project +#ifndef QXK_H_ #error "Source file included in a project NOT based on the QXK kernel" -#endif /* QP_INC_QXK_H_ */ +#endif // QXK_H_ Q_DEFINE_THIS_MODULE("qxk") -/*==========================================================================*/ -/*$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* Check for the minimum required QP version */ -#if (QP_VERSION < 700U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) -#error qpc version 7.0.0 or higher required +//$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// Check for the minimum required QP version +#if (QP_VERSION < 730U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) +#error qpc version 7.3.0 or higher required #endif -/*$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -/*$define${QXK::QXK-base} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//$define${QXK::QXK-base} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/*${QXK::QXK-base::schedLock} ..............................................*/ +//${QXK::QXK-base::priv_} .................................................... +QXK_Attr QXK_priv_; + +//${QXK::QXK-base::schedLock} ................................................ +//! @static @public @memberof QXK QSchedStatus QXK_schedLock(uint_fast8_t const ceiling) { - QF_CRIT_STAT_ - QF_CRIT_E_(); + QF_CRIT_STAT + QF_CRIT_ENTRY(); + QF_MEM_SYS(); - /*! @pre The QXK scheduler lock cannot be called from an ISR */ - Q_REQUIRE_ID(400, !QXK_ISR_CONTEXT_()); + Q_REQUIRE_INCRIT(100, !QXK_ISR_CONTEXT_()); - QSchedStatus stat; /* saved lock status to be returned */ + QSchedStatus stat; // saved lock status to be returned - /* is the lock ceiling being raised? */ - if (ceiling > (uint_fast8_t)QXK_attr_.lockCeil) { - QS_BEGIN_NOCRIT_PRE_(QS_SCHED_LOCK, 0U) - QS_TIME_PRE_(); /* timestamp */ - /* the previous lock ceiling & new lock ceiling */ - QS_2U8_PRE_(QXK_attr_.lockCeil, (uint8_t)ceiling); - QS_END_NOCRIT_PRE_() + // is the lock ceiling being raised? + if (ceiling > QXK_priv_.lockCeil) { + QS_BEGIN_PRE_(QS_SCHED_LOCK, 0U) + QS_TIME_PRE_(); // timestamp + // the previous lock ceiling & new lock ceiling + QS_2U8_PRE_((uint8_t)QXK_priv_.lockCeil, (uint8_t)ceiling); + QS_END_PRE_() - /* previous status of the lock */ - stat = (QSchedStatus)QXK_attr_.lockHolder; - stat |= (QSchedStatus)QXK_attr_.lockCeil << 8U; + // previous status of the lock + stat = (QSchedStatus)QXK_priv_.lockHolder; + stat |= (QSchedStatus)QXK_priv_.lockCeil << 8U; - /* new status of the lock */ - QXK_attr_.lockHolder = (QXK_attr_.curr != (QActive *)0) - ? QXK_attr_.curr->prio + // new status of the lock + QXK_priv_.lockHolder = (QXK_priv_.curr != (QActive *)0) + ? (uint_fast8_t)QXK_priv_.curr->prio : 0U; - QXK_attr_.lockCeil = (uint8_t)ceiling; + QXK_priv_.lockCeil = ceiling; } else { - stat = 0xFFU; /* scheduler not locked */ + stat = 0xFFU; // scheduler not locked } - QF_CRIT_X_(); + QF_MEM_APP(); + QF_CRIT_EXIT(); - return stat; /* return the status to be saved in a stack variable */ + return stat; // return the status to be saved in a stack variable } -/*${QXK::QXK-base::schedUnlock} ............................................*/ +//${QXK::QXK-base::schedUnlock} .............................................. +//! @static @public @memberof QXK void QXK_schedUnlock(QSchedStatus const stat) { - /* has the scheduler been actually locked by the last QXK_schedLock()? */ + // has the scheduler been actually locked by the last QXK_schedLock()? if (stat != 0xFFU) { - uint8_t const lockCeil = QXK_attr_.lockCeil; uint8_t const prevCeil = (uint8_t)(stat >> 8U); - QF_CRIT_STAT_ - QF_CRIT_E_(); + QF_CRIT_STAT + QF_CRIT_ENTRY(); + QF_MEM_SYS(); - /*! @pre The scheduler cannot be unlocked: - * - from the ISR context; and - * - the current lock ceiling must be greater than the previous - */ - Q_REQUIRE_ID(500, (!QXK_ISR_CONTEXT_()) - && (lockCeil > prevCeil)); + Q_REQUIRE_INCRIT(200, !QXK_ISR_CONTEXT_()); + Q_REQUIRE_INCRIT(201, QXK_priv_.lockCeil > prevCeil); - QS_BEGIN_NOCRIT_PRE_(QS_SCHED_UNLOCK, 0U) - QS_TIME_PRE_(); /* timestamp */ - /* ceiling before unlocking & prio after unlocking */ - QS_2U8_PRE_(lockCeil, prevCeil); - QS_END_NOCRIT_PRE_() + QS_BEGIN_PRE_(QS_SCHED_UNLOCK, 0U) + QS_TIME_PRE_(); // timestamp + // ceiling before unlocking & prio after unlocking + QS_2U8_PRE_((uint8_t)QXK_priv_.lockCeil, (uint8_t)prevCeil); + QS_END_PRE_() - /* restore the previous lock ceiling and lock holder */ - QXK_attr_.lockCeil = prevCeil; - QXK_attr_.lockHolder = (uint8_t)(stat & 0xFFU); + // restore the previous lock ceiling and lock holder + QXK_priv_.lockCeil = prevCeil; + QXK_priv_.lockHolder = (stat & 0xFFU); - /* find if any threads should be run after unlocking the scheduler */ - if (QXK_sched_() != 0U) { /* activation needed? */ - QXK_activate_(); /* synchronously activate basic-thred(s) */ + // find if any threads should be run after unlocking the scheduler + if (QXK_sched_() != 0U) { // activation needed? + QXK_activate_(); // synchronously activate basic-thred(s) } - QF_CRIT_X_(); + QF_MEM_APP(); + QF_CRIT_EXIT(); } } -/*$enddef${QXK::QXK-base} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*$define${QXK::QF-cust} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/*${QXK::QF-cust::init} ....................................................*/ -void QF_init(void) { +//${QXK::QXK-base::current} .................................................. +//! @static @public @memberof QXK +QActive * QXK_current(void) { + QF_CRIT_STAT + QF_CRIT_ENTRY(); + QF_MEM_SYS(); + + Q_REQUIRE_INCRIT(600, QXK_priv_.lockCeil <= QF_MAX_ACTIVE); + + struct QActive *curr = QXK_priv_.curr; + if (curr == (QActive *)0) { // basic thread? + curr = QActive_registry_[QXK_priv_.actPrio]; + } + + Q_ASSERT_INCRIT(690, curr != (QActive *)0); + + QF_MEM_APP(); + QF_CRIT_EXIT(); + + return curr; +} + +//${QXK::QXK-base::sched_} ................................................... +//! @static @private @memberof QXK +uint_fast8_t QXK_sched_(void) { + Q_REQUIRE_INCRIT(402, QPSet_verify_(&QXK_priv_.readySet, + &QXK_priv_.readySet_dis)); + uint_fast8_t p; + if (QPSet_isEmpty(&QXK_priv_.readySet)) { + p = 0U; // no activation needed + } + else { + // find the highest-prio thread ready to run + p = QPSet_findMax(&QXK_priv_.readySet); + if (p <= QXK_priv_.lockCeil) { + // prio. of the thread holding the lock + p = (uint_fast8_t)QActive_registry_[QXK_priv_.lockHolder]->prio; + if (p != 0U) { + Q_ASSERT_INCRIT(410, + QPSet_hasElement(&QXK_priv_.readySet, p)); + } + } + } + QActive const * const curr = QXK_priv_.curr; + QActive * const next = QActive_registry_[p]; + + // the next thread found must be registered in QF + Q_ASSERT_INCRIT(420, next != (QActive *)0); + + // is the current thread a basic-thread? + if (curr == (QActive *)0) { + + // is the new prio. above the active prio.? + if (p > QXK_priv_.actPrio) { + QXK_priv_.next = next; // set the next AO to activate + + if (next->osObject != (void *)0) { // is next extended? + QXK_CONTEXT_SWITCH_(); + p = 0U; // no activation needed + } + } + else { // below the pre-thre + QXK_priv_.next = (QActive *)0; + p = 0U; // no activation needed + } + } + else { // currently executing an extended-thread + // is the current thread different from the next? + if (curr != next) { + QXK_priv_.next = next; + QXK_CONTEXT_SWITCH_(); + } + else { // current is the same as next + QXK_priv_.next = (QActive *)0; // no need to context-switch + } + p = 0U; // no activation needed + } + + return p; +} + +//${QXK::QXK-base::activate_} ................................................ +//! @static @private @memberof QXK +void QXK_activate_(void) { + uint_fast8_t const prio_in = QXK_priv_.actPrio; + QActive *next = QXK_priv_.next; // the next AO (basic-thread) to run + + Q_REQUIRE_INCRIT(500, (next != (QActive *)0) + && (prio_in <= QF_MAX_ACTIVE)); + + // QXK Context switch callback defined or QS tracing enabled? + #if (defined QF_ON_CONTEXT_SW) || (defined Q_SPY) + QXK_contextSw_(next); + #endif // QF_ON_CONTEXT_SW || Q_SPY + + QXK_priv_.next = (QActive *)0; // clear the next AO + QXK_priv_.curr = (QActive *)0; // current is basic-thread + + // prio. of the next thread + uint_fast8_t p = (uint_fast8_t)next->prio; + + // loop until no more ready-to-run AOs of higher prio than the initial + do { + QXK_priv_.actPrio = p; // next active prio + + QF_INT_ENABLE(); // unconditionally enable interrupts + + QEvt const * const e = QActive_get_(next); + // NOTE QActive_get_() performs QS_MEM_APP() before return + + // dispatch event (virtual call) + (*next->super.vptr->dispatch)(&next->super, e, p); #if (QF_MAX_EPOOL > 0U) - QF_maxPool_ = 0U; + QF_gc(e); #endif - QF_bzero(&QTimeEvt_timeEvtHead_[0], sizeof(QTimeEvt_timeEvtHead_)); - QF_bzero(&QActive_registry_[0], sizeof(QActive_registry_)); - QF_bzero(&QF_readySet_, sizeof(QF_readySet_)); - QF_bzero(&QXK_attr_, sizeof(QXK_attr_)); + QF_INT_DISABLE(); // unconditionally disable interrupts + QF_MEM_SYS(); - /* setup the QXK scheduler as initially locked and not running */ - QXK_attr_.lockCeil = (QF_MAX_ACTIVE + 1U); /* scheduler locked */ + // check internal integrity (duplicate inverse storage) + Q_ASSERT_INCRIT(502, QPSet_verify_(&QXK_priv_.readySet, + &QXK_priv_.readySet_dis)); - /* QXK idle AO object (const in ROM) */ - static QActive const idle_ao = { (struct QHsmVtable const *)0 }; + if (next->eQueue.frontEvt == (QEvt *)0) { // empty queue? + QPSet_remove(&QXK_priv_.readySet, p); + #ifndef Q_UNSAFE + QPSet_update_(&QXK_priv_.readySet, &QXK_priv_.readySet_dis); + #endif + } - /* register the idle AO object (cast 'const' away) */ - QActive_registry_[0] = (QActive *)&idle_ao; - QXK_attr_.prev = QActive_registry_[0]; + if (QPSet_isEmpty(&QXK_priv_.readySet)) { + QXK_priv_.next = (QActive *)0; + next = QActive_registry_[0]; + p = 0U; // no activation needed + } + else { + // find next highest-prio below the lock ceiling + p = (uint8_t)QPSet_findMax(&QXK_priv_.readySet); + if (p <= QXK_priv_.lockCeil) { + p = QXK_priv_.lockHolder; // thread holding lock + if (p != 0U) { + Q_ASSERT_INCRIT(510, + QPSet_hasElement(&QXK_priv_.readySet, p)); + } + } + + // set the next thread and ensure that it is registered + next = QActive_registry_[p]; + Q_ASSERT_INCRIT(520, next != (QActive *)0); + + // is next a basic thread? + if (next->osObject == (void *)0) { + // is the next prio. above the initial prio.? + if (p > QActive_registry_[prio_in]->prio) { + #if (defined QF_ON_CONTEXT_SW) || (defined Q_SPY) + if (p != QXK_priv_.actPrio) { // changing threads? + QXK_contextSw_(next); + } + #endif // QF_ON_CONTEXT_SW || Q_SPY + QXK_priv_.next = next; + } + else { + QXK_priv_.next = (QActive *)0; + p = 0U; // no activation needed + } + } + else { // next is the extended-thread + QXK_priv_.next = next; + QXK_CONTEXT_SWITCH_(); + p = 0U; // no activation needed + } + } + } while (p != 0U); // while activation needed + + // restore the active prio. + QXK_priv_.actPrio = prio_in; + + #if (defined QF_ON_CONTEXT_SW) || (defined Q_SPY) + if (next->osObject == (void *)0) { + QXK_contextSw_((prio_in == 0U) + ? (QActive *)0 + : QActive_registry_[prio_in]); + } + #endif // QF_ON_CONTEXT_SW || Q_SPY +} + +//${QXK::QXK-base::contextSw_} ............................................... +//! @static @public @memberof QXK +void QXK_contextSw_(QActive * const next) { + #ifdef Q_SPY + uint8_t const prev_prio = (QXK_priv_.prev != (QActive *)0) + ? QXK_priv_.prev->prio + : 0U; + if (next != (QActive *)0) { // next is NOT idle? + QS_BEGIN_PRE_(QS_SCHED_NEXT, next->prio) + QS_TIME_PRE_(); // timestamp + QS_2U8_PRE_(next->prio, prev_prio); + QS_END_PRE_() + } + else { // going to idle + QS_BEGIN_PRE_(QS_SCHED_IDLE, prev_prio) + QS_TIME_PRE_(); // timestamp + QS_U8_PRE_(prev_prio); + QS_END_PRE_() + } + #endif // Q_SPY + + #ifdef QF_ON_CONTEXT_SW + QF_onContextSw(QXK_priv_.prev, next); + #endif // QF_ON_CONTEXT_SW + + QXK_priv_.prev = next; // update the previous thread +} + +//${QXK::QXK-base::threadExit_} .............................................. +//! @static @private @memberof QXK +void QXK_threadExit_(void) { + QF_CRIT_STAT + QF_CRIT_ENTRY(); + + QXThread const * const thr = QXTHREAD_CAST_(QXK_priv_.curr); + + Q_REQUIRE_INCRIT(900, (!QXK_ISR_CONTEXT_()) + && (thr != (QXThread *)0)); // current thread must be extended + Q_REQUIRE_INCRIT(901, + QXK_priv_.lockHolder != (uint_fast8_t)thr->super.prio); + + uint_fast8_t const p = (uint_fast8_t)thr->super.prio; + + QF_MEM_SYS(); + QActive_registry_[p] = (QActive *)0; + QPSet_remove(&QXK_priv_.readySet, p); + #ifndef Q_UNSAFE + QPSet_update_(&QXK_priv_.readySet, &QXK_priv_.readySet_dis); + #endif + + (void)QXK_sched_(); // schedule other threads + + QF_MEM_APP(); + QF_CRIT_EXIT(); +} +//$enddef${QXK::QXK-base} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +//$define${QXK::QF-cust} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + +//${QXK::QF-cust::init} ...................................................... +//! @static @public @memberof QF +void QF_init(void) { + QF_bzero_(&QF_priv_, sizeof(QF_priv_)); + QF_bzero_(&QXK_priv_, sizeof(QXK_priv_)); + QF_bzero_(&QTimeEvt_timeEvtHead_[0], sizeof(QTimeEvt_timeEvtHead_)); + QF_bzero_(&QActive_registry_[0], sizeof(QActive_registry_)); + + #ifndef Q_UNSAFE + QPSet_update_(&QXK_priv_.readySet, &QXK_priv_.readySet_dis); + #endif + + // setup the QXK scheduler as initially locked and not running + QXK_priv_.lockCeil = (QF_MAX_ACTIVE + 1U); // scheduler locked + + // QXK idle AO object (const in ROM) + static QActive const idle_ao = { (struct QAsmVtable const *)0 }; + + // register the idle AO object (cast 'const' away) + QActive_registry_[0] = QACTIVE_CAST_(&idle_ao); + QXK_priv_.prev = QActive_registry_[0]; #ifdef QXK_INIT - QXK_INIT(); /* port-specific initialization of the QXK kernel */ + QXK_INIT(); // port-specific initialization of the QXK kernel #endif } -/*${QXK::QF-cust::stop} ....................................................*/ +//${QXK::QF-cust::stop} ...................................................... +//! @static @public @memberof QF void QF_stop(void) { - QF_onCleanup(); /* application-specific cleanup callback */ - /* nothing else to do for the dual-mode QXK kernel */ + QF_onCleanup(); // application-specific cleanup callback + // nothing else to do for the dual-mode QXK kernel } -/*${QXK::QF-cust::run} .....................................................*/ +//${QXK::QF-cust::run} ....................................................... +//! @static @public @memberof QF int_t QF_run(void) { #ifdef Q_SPY QS_SIG_DICTIONARY(QXK_DELAY_SIG, (void *)0); QS_SIG_DICTIONARY(QXK_TIMEOUT_SIG, (void *)0); - /* produce the QS_QF_RUN trace record */ + // produce the QS_QF_RUN trace record QF_INT_DISABLE(); + QF_MEM_SYS(); QS_beginRec_((uint_fast8_t)QS_QF_RUN); QS_endRec_(); + QF_MEM_APP(); QF_INT_ENABLE(); - #endif /* Q_SPY */ + #endif // Q_SPY - QF_onStartup(); /* application-specific startup callback */ + QF_onStartup(); // application-specific startup callback QF_INT_DISABLE(); + QF_MEM_SYS(); - QXK_attr_.lockCeil = 0U; /* unlock the QXK scheduler */ - /* activate AOs to process events posted so far */ + QXK_priv_.lockCeil = 0U; // unlock the QXK scheduler + + // activate AOs to process events posted so far if (QXK_sched_() != 0U) { QXK_activate_(); } #ifdef QXK_START - QXK_START(); /* port-specific startup of the QXK kernel */ + QXK_START(); // port-specific startup of the QXK kernel #endif + QF_MEM_APP(); QF_INT_ENABLE(); - for (;;) { /* QXK idle loop... */ - QXK_onIdle(); /* application-specific QXK idle callback */ + + for (;;) { // QXK idle loop... + QXK_onIdle(); // application-specific QXK idle callback } - #ifdef __GNUC__ + #ifdef __GNUC__ // GNU compiler? return 0; #endif } -/*$enddef${QXK::QF-cust} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*$define${QXK::QActive} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//$enddef${QXK::QF-cust} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -/*${QXK::QActive} ..........................................................*/ +//$define${QXK::QActive} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/*${QXK::QActive::start_} ..................................................*/ +//${QXK::QActive} ............................................................ + +//${QXK::QActive::start_} .................................................... +//! @public @memberof QActive void QActive_start_(QActive * const me, QPrioSpec const prioSpec, QEvt const * * const qSto, @@ -222,274 +479,65 @@ void QActive_start_(QActive * const me, uint_fast16_t const stkSize, void const * const par) { - Q_UNUSED_PAR(stkSto); /* not needed in QXK */ - Q_UNUSED_PAR(stkSize); /* not needed in QXK */ - - /*! @pre AO cannot be started: - * - from an ISR; - * - the stack storage must NOT be provided (because the QXK kernel - * does not need per-AO stacks) - * - preemption-threshold is NOT provided (because QXK kernel - * does not support preemption-threshold scheduling) - */ - Q_REQUIRE_ID(200, (!QXK_ISR_CONTEXT_()) - && (stkSto == (void *)0) + QF_CRIT_STAT + QF_CRIT_ENTRY(); + Q_REQUIRE_INCRIT(300, (!QXK_ISR_CONTEXT_()) && ((prioSpec & 0xFF00U) == 0U)); + QF_CRIT_EXIT(); - me->prio = (uint8_t)(prioSpec & 0xFFU); /* QF-priority of the AO */ - me->pthre = 0U; /* preemption-threshold NOT used */ - QActive_register_(me); /* make QF aware of this active object */ + me->prio = (uint8_t)(prioSpec & 0xFFU); // QF-prio. of the AO + me->pthre = 0U; // preemption-threshold NOT used + QActive_register_(me); // make QF aware of this active object - QEQueue_init(&me->eQueue, qSto, qLen); /* init the built-in queue */ - me->osObject = (void *)0; /* no private stack for the AO */ + if (stkSto == (void *)0) { // starting basic thread (AO)? - QHSM_INIT(&me->super, par, me->prio); /* top-most initial tran. */ - QS_FLUSH(); /* flush the trace buffer to the host */ + QEQueue_init(&me->eQueue, qSto, qLen); // init the built-in queue + me->osObject = (void *)0; // no private stack for AO - /* see if this AO needs to be scheduled if QXK is already running */ - QF_CRIT_STAT_ - QF_CRIT_E_(); - if (QXK_attr_.lockCeil <= QF_MAX_ACTIVE) { /* scheduler running? */ - if (QXK_sched_() != 0U) { /* activation needed? */ - QXK_activate_(); /* synchronously activate basic-thred(s) */ - } - } - QF_CRIT_X_(); -} -/*$enddef${QXK::QActive} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*$define${QXK::QXK-extern-C} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ + // top-most initial tran. (virtual call) + (*me->super.vptr->init)(&me->super, par, me->prio); + QS_FLUSH(); // flush the trace buffer to the host -/*${QXK::QXK-extern-C::attr_} ..............................................*/ -QXK QXK_attr_; - -/*${QXK::QXK-extern-C::sched_} .............................................*/ -uint_fast8_t QXK_sched_(void) { - uint_fast8_t p; - - if (QPSet_isEmpty(&QF_readySet_)) { - p = 0U; /* no activation needed */ - } - else { - /* find the highest-prio thread ready to run */ - p = QPSet_findMax(&QF_readySet_); - if (p <= QXK_attr_.lockCeil) { - /* priority of the thread holding the lock */ - p = (uint_fast8_t)QActive_registry_[QXK_attr_.lockHolder]->prio; - if (p != 0U) { - Q_ASSERT_ID(610, QPSet_hasElement(&QF_readySet_, p)); + // see if this AO needs to be scheduled if QXK is already running + QF_CRIT_ENTRY(); + QF_MEM_SYS(); + if (QXK_priv_.lockCeil <= QF_MAX_ACTIVE) { // scheduler running? + if (QXK_sched_() != 0U) { // activation needed? + QXK_activate_(); // synchronously activate basic-thred(s) } } + QF_MEM_APP(); + QF_CRIT_EXIT(); } - QActive const * const curr = QXK_attr_.curr; - QActive * const next = QActive_registry_[p]; + else { // starting QXThread - /* the next thread found must be registered in QF */ - Q_ASSERT_ID(620, next != (QActive *)0); - - /* is the current thread a basic-thread? */ - if (curr == (QActive *)0) { - - /* is the new priority above the active priority? */ - if (p > QXK_attr_.actPrio) { - QXK_attr_.next = next; /* set the next AO to activate */ - - if (next->osObject != (void *)0) { /* is next extended? */ - QXK_CONTEXT_SWITCH_(); - p = 0U; /* no activation needed */ - } + // is storage for the queue buffer provided? + if (qSto != (QEvt const **)0) { + QEQueue_init(&me->eQueue, qSto, qLen); } - else { /* below the pre-thre */ - QXK_attr_.next = (QActive *)0; - p = 0U; /* no activation needed */ + + // extended thread constructor puts the thread handler in place of + // the top-most initial tran. 'me->super.temp.act' + QXThread_stackInit_(me, me->super.temp.thr, stkSto, stkSize); + + // the new thread is not blocked on any object + me->super.temp.obj = (QMState *)0; + + QF_CRIT_ENTRY(); + QF_MEM_SYS(); + + // extended-thread becomes ready immediately + QPSet_insert(&QXK_priv_.readySet, (uint_fast8_t)me->prio); + #ifndef Q_UNSAFE + QPSet_update_(&QXK_priv_.readySet, &QXK_priv_.readySet_dis); + #endif + + // see if this thread needs to be scheduled in case QXK is running + if (QXK_priv_.lockCeil <= QF_MAX_ACTIVE) { + (void)QXK_sched_(); // schedule other threads } + QF_MEM_APP(); + QF_CRIT_EXIT(); } - else { /* currently executing an extended-thread */ - /* is the current thread different from the next? */ - if (curr != next) { - QXK_attr_.next = next; - QXK_CONTEXT_SWITCH_(); - } - else { /* current is the same as next */ - QXK_attr_.next = (QActive *)0; /* no need to context-switch */ - } - p = 0U; /* no activation needed */ - } - return p; } - -/*${QXK::QXK-extern-C::activate_} ..........................................*/ -void QXK_activate_(void) { - uint8_t const prio_in = QXK_attr_.actPrio; - QActive *next = QXK_attr_.next; /* the next AO (basic-thread) to run */ - - /*! @pre QXK_attr_.next must be valid and the prio must be in range */ - Q_REQUIRE_ID(700, (next != (QActive *)0) && (prio_in <= QF_MAX_ACTIVE)); - - /* QXK Context switch callback defined or QS tracing enabled? */ - #if (defined QF_ON_CONTEXT_SW) || (defined Q_SPY) - QXK_contextSw(next); - #endif /* QF_ON_CONTEXT_SW || Q_SPY */ - - QXK_attr_.next = (QActive *)0; /* clear the next AO */ - QXK_attr_.curr = (QActive *)0; /* current is basic-thread */ - - /* priority of the next thread */ - uint8_t p = next->prio; - - /* loop until no more ready-to-run AOs of higher prio than the initial */ - do { - QXK_attr_.actPrio = p; /* next active prio */ - - QF_INT_ENABLE(); /* unconditionally enable interrupts */ - - /* perform the run-to-completion (RTC) step... - * 1. retrieve the event from the AO's event queue, which by this - * time must be non-empty and QActive_get_() asserts it. - * 2. dispatch the event to the AO's state machine. - * 3. determine if event is garbage and collect it if so - */ - QEvt const * const e = QActive_get_(next); - QHSM_DISPATCH(&next->super, e, next->prio); - #if (QF_MAX_EPOOL > 0U) - QF_gc(e); - #endif - - QF_INT_DISABLE(); /* unconditionally disable interrupts */ - - if (next->eQueue.frontEvt == (QEvt *)0) { /* empty queue? */ - QPSet_remove(&QF_readySet_, p); - } - - if (QPSet_isEmpty(&QF_readySet_)) { - QXK_attr_.next = (QActive *)0; - next = QActive_registry_[0]; - p = 0U; /* no activation needed */ - } - else { - /* find next highest-prio below the lock ceiling */ - p = (uint8_t)QPSet_findMax(&QF_readySet_); - if (p <= QXK_attr_.lockCeil) { - p = QXK_attr_.lockHolder; /* thread holding lock */ - if (p != 0U) { - Q_ASSERT_ID(710, QPSet_hasElement(&QF_readySet_, p)); - } - } - - /* set the next thread and ensure that it is registered */ - next = QActive_registry_[p]; - Q_ASSERT_ID(720, next != (QActive *)0); - - /* is next a basic thread? */ - if (next->osObject == (void *)0) { - /* is the next priority above the initial priority? */ - if (p > QActive_registry_[prio_in]->prio) { - #if (defined QF_ON_CONTEXT_SW) || (defined Q_SPY) - if (p != QXK_attr_.actPrio) { /* changing threads? */ - QXK_contextSw(next); - } - #endif /* QF_ON_CONTEXT_SW || Q_SPY */ - QXK_attr_.next = next; - } - else { - QXK_attr_.next = (QActive *)0; - p = 0U; /* no activation needed */ - } - } - else { /* next is the extended-thread */ - QXK_attr_.next = next; - QXK_CONTEXT_SWITCH_(); - p = 0U; /* no activation needed */ - } - } - } while (p != 0U); /* while activation needed */ - - /* restore the active priority */ - QXK_attr_.actPrio = prio_in; - - #if (defined QF_ON_CONTEXT_SW) || (defined Q_SPY) - if (next->osObject == (void *)0) { - QXK_contextSw((prio_in == 0U) - ? (QActive *)0 - : QActive_registry_[prio_in]); - } - #endif /* QF_ON_CONTEXT_SW || Q_SPY */ -} - -/*${QXK::QXK-extern-C::current} ............................................*/ -QActive * QXK_current(void) { - /*! @pre the QXK kernel must be running */ - Q_REQUIRE_ID(800, QXK_attr_.lockCeil <= QF_MAX_ACTIVE); - - QF_CRIT_STAT_ - QF_CRIT_E_(); - - struct QActive *curr = QXK_attr_.curr; - if (curr == (QActive *)0) { /* basic thread? */ - curr = QActive_registry_[QXK_attr_.actPrio]; - } - QF_CRIT_X_(); - - /*! @post the current thread must be valid */ - Q_ENSURE_ID(890, curr != (QActive *)0); - - return curr; -} - -/*${QXK::QXK-extern-C::contextSw} ..........................................*/ -#if defined(Q_SPY) || defined(QF_ON_CONTEXT_SW) -void QXK_contextSw(QActive * const next) { - #ifdef Q_SPY - uint8_t const prev_prio = (QXK_attr_.prev != (QActive *)0) - ? QXK_attr_.prev->prio - : 0U; - #endif /* Q_SPY */ - - if (next != (QActive *)0) { /* next is NOT idle? */ - QS_BEGIN_NOCRIT_PRE_(QS_SCHED_NEXT, next->prio) - QS_TIME_PRE_(); /* timestamp */ - QS_2U8_PRE_(next->prio, prev_prio); - QS_END_NOCRIT_PRE_() - } - else { /* going to idle */ - QS_BEGIN_NOCRIT_PRE_(QS_SCHED_IDLE, prev_prio) - QS_TIME_PRE_(); /* timestamp */ - QS_U8_PRE_(prev_prio); - QS_END_NOCRIT_PRE_() - } - - #ifdef QF_ON_CONTEXT_SW - QF_onContextSw(QXK_attr_.prev, next); - #endif /* QF_ON_CONTEXT_SW */ - - QXK_attr_.prev = next; /* update the previous thread */ -} -#endif /* defined(Q_SPY) || defined(QF_ON_CONTEXT_SW) */ -/*$enddef${QXK::QXK-extern-C} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*==========================================================================*/ -/*$define${QXK-impl} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ - -/*${QXK-impl::QXK_threadExit_} .............................................*/ -void QXK_threadExit_(void) { - QF_CRIT_STAT_ - QF_CRIT_E_(); - - QXThread const * const thr = QXTHREAD_CAST_(QXK_attr_.curr); - - /*! @pre this function must: - * - NOT be called from an ISR; - * - be called from an extended thread; - */ - Q_REQUIRE_ID(900, (!QXK_ISR_CONTEXT_()) /* can't be in the ISR context */ - && (thr != (QXThread *)0)); /* current thread must be extended */ - /*! @pre also: the thread must NOT be holding a scheduler lock. */ - Q_REQUIRE_ID(901, QXK_attr_.lockHolder != thr->super.prio); - - uint_fast8_t const p = (uint_fast8_t)thr->super.prio; - - /* remove this thread from the QF */ - QActive_registry_[p] = (QActive *)0; - QPSet_remove(&QF_readySet_, p); - (void)QXK_sched_(); /* schedule other threads */ - QF_CRIT_X_(); -} -/*$enddef${QXK-impl} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$enddef${QXK::QActive} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/src/qxk/qxk_mutex.c b/src/qxk/qxk_mutex.c index d3bb843f..1c7e6878 100644 --- a/src/qxk/qxk_mutex.c +++ b/src/qxk/qxk_mutex.c @@ -1,453 +1,473 @@ -/*$file${src::qxk::qxk_mutex.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* -* Model: qpc.qm -* File: ${src::qxk::qxk_mutex.c} -* -* This code has been generated by QM 5.2.4 . -* DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. -* -* This code is covered by the following QP license: -* License # : LicenseRef-QL-dual -* Issued to : Any user of the QP/C real-time embedded framework -* Framework(s) : qpc -* Support ends : 2023-12-31 -* License scope: -* -* Copyright (C) 2005 Quantum Leaps, LLC . -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -*/ -/*$endhead${src::qxk::qxk_mutex.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*! @file -* @brief QXMutex_init(), QXMutex_lock(), QXMutex_tryLock() and -* QXMutex_unlock() definitions. -*/ -#define QP_IMPL /* this is QP implementation */ -#include "qf_port.h" /* QF port */ -#include "qf_pkg.h" /* QF package-scope interface */ -#include "qassert.h" /* QP embedded systems-friendly assertions */ -#ifdef Q_SPY /* QS software tracing enabled? */ - #include "qs_port.h" /* QS port */ - #include "qs_pkg.h" /* QS facilities for pre-defined trace records */ +//$file${src::qxk::qxk_mutex.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// +// Model: qpc.qm +// File: ${src::qxk::qxk_mutex.c} +// +// This code has been generated by QM 5.3.0 . +// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. +// +// This code is covered by the following QP license: +// License # : LicenseRef-QL-dual +// Issued to : Any user of the QP/C real-time embedded framework +// Framework(s) : qpc +// Support ends : 2024-12-31 +// License scope: +// +// Copyright (C) 2005 Quantum Leaps, LLC . +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +// +//$endhead${src::qxk::qxk_mutex.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +#define QP_IMPL // this is QP implementation +#include "qp_port.h" // QP port +#include "qp_pkg.h" // QP package-scope interface +#include "qsafe.h" // QP Functional Safety (FuSa) Subsystem +#ifdef Q_SPY // QS software tracing enabled? + #include "qs_port.h" // QS port + #include "qs_pkg.h" // QS facilities for pre-defined trace records #else - #include "qs_dummy.h" /* disable the QS software tracing */ -#endif /* Q_SPY */ + #include "qs_dummy.h" // disable the QS software tracing +#endif // Q_SPY -/* protection against including this source file in a wrong project */ -#ifndef QP_INC_QXK_H_ +// protection against including this source file in a wrong project +#ifndef QXK_H_ #error "Source file included in a project NOT based on the QXK kernel" -#endif /* QP_INC_QXK_H_ */ +#endif // QXK_H_ Q_DEFINE_THIS_MODULE("qxk_mutex") -/*==========================================================================*/ -/*$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* Check for the minimum required QP version */ -#if (QP_VERSION < 700U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) -#error qpc version 7.0.0 or higher required +//$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// Check for the minimum required QP version +#if (QP_VERSION < 730U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) +#error qpc version 7.3.0 or higher required #endif -/*$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -/*$define${QXK::QXMutex} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//$define${QXK::QXMutex} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/*${QXK::QXMutex} ..........................................................*/ +//${QXK::QXMutex} ............................................................ -/*${QXK::QXMutex::init} ....................................................*/ +//${QXK::QXMutex::init} ...................................................... +//! @public @memberof QXMutex void QXMutex_init(QXMutex * const me, QPrioSpec const prioSpec) { - /*! @pre preemption-threshold must not be used */ - Q_REQUIRE_ID(100, (prioSpec & 0xFF00U) == 0U); + QF_CRIT_STAT + QF_CRIT_ENTRY(); + QF_MEM_SYS(); - me->ao.prio = (uint8_t)(prioSpec & 0xFFU); /* QF-priority */ - me->ao.pthre = 0U; /* preemption-threshold (not used) */ + Q_REQUIRE_INCRIT(100, (prioSpec & 0xFF00U) == 0U); - if (prioSpec != 0U) { /* priority-ceiling protocol used? */ - QActive_register_(&me->ao); /* register this mutex as AO */ - } + me->ao.prio = (uint8_t)(prioSpec & 0xFFU); // QF-prio. + me->ao.pthre = 0U; // preemption-threshold (not used) + QActive * const ao = &me->ao; + + QF_MEM_APP(); + QF_CRIT_EXIT(); + + QActive_register_(ao); // register this mutex as AO } -/*${QXK::QXMutex::lock} ....................................................*/ +//${QXK::QXMutex::lock} ...................................................... +//! @public @memberof QXMutex bool QXMutex_lock(QXMutex * const me, - uint_fast16_t const nTicks) + QTimeEvtCtr const nTicks) { - QF_CRIT_STAT_ - QF_CRIT_E_(); + QF_CRIT_STAT + QF_CRIT_ENTRY(); + QF_MEM_SYS(); - QXThread * const curr = QXK_PTR_CAST_(QXThread*, QXK_attr_.curr); + QXThread * const curr = QXK_PTR_CAST_(QXThread*, QXK_priv_.curr); - /*! @pre this function must: - * - NOT be called from an ISR; - * - be called from an extended thread; - * - the mutex-priority must be in range - * - the thread must NOT be already blocked on any object. - */ - Q_REQUIRE_ID(200, (!QXK_ISR_CONTEXT_()) /* don't call from an ISR! */ - && (curr != (QXThread *)0) /* current thread must be extended */ + // precondition, this mutex operation must: + // - NOT be called from an ISR; + // - be called from an eXtended thread; + // - the mutex-prio. must be in range; + // - the thread must NOT be already blocked on any object. + Q_REQUIRE_INCRIT(200, (!QXK_ISR_CONTEXT_()) + && (curr != (QXThread *)0) && (me->ao.prio <= QF_MAX_ACTIVE) - && (curr->super.super.temp.obj == (QMState *)0)); /* not blocked */ - /*! @pre also: the thread must NOT be holding a scheduler lock. */ - Q_REQUIRE_ID(201, QXK_attr_.lockHolder != curr->super.prio); + && (curr->super.super.temp.obj == (QMState *)0)); + // also: the thread must NOT be holding a scheduler lock. + Q_REQUIRE_INCRIT(201, + QXK_priv_.lockHolder != (uint_fast8_t)curr->super.prio); - /* is the mutex available? */ - bool locked = true; /* assume that the mutex will be locked */ + // is the mutex available? + bool locked = true; // assume that the mutex will be locked if (me->ao.eQueue.nFree == 0U) { - me->ao.eQueue.nFree = 1U; /* mutex lock nesting */ + me->ao.eQueue.nFree = 1U; // mutex lock nesting - /*! @pre also: the newly locked mutex must have no holder yet */ - Q_REQUIRE_ID(202, me->ao.thread == (void *)0); + // also: the newly locked mutex must have no holder yet + Q_REQUIRE_INCRIT(203, me->ao.osObject == (void *)0); - /* set the new mutex holder to the curr thread and - * save the thread's prio in the mutex - * NOTE: reuse the otherwise unused eQueue data member. - */ - me->ao.thread = curr; + // set the new mutex holder to the curr thread and + // save the thread's prio in the mutex + // NOTE: reuse the otherwise unused eQueue data member. + me->ao.osObject = curr; me->ao.eQueue.head = (QEQueueCtr)curr->super.prio; - QS_BEGIN_NOCRIT_PRE_(QS_MTX_LOCK, curr->super.prio) - QS_TIME_PRE_(); /* timestamp */ - QS_OBJ_PRE_(me); /* this mutex */ - QS_U8_PRE_((uint8_t)me->ao.eQueue.head); /* holder prio */ - QS_U8_PRE_((uint8_t)me->ao.eQueue.nFree); /* nesting */ - QS_END_NOCRIT_PRE_() + QS_BEGIN_PRE_(QS_MTX_LOCK, curr->super.prio) + QS_TIME_PRE_(); // timestamp + QS_OBJ_PRE_(me); // this mutex + QS_U8_PRE_((uint8_t)me->ao.eQueue.head); // holder prio + QS_U8_PRE_((uint8_t)me->ao.eQueue.nFree); // nesting + QS_END_PRE_() - if (me->ao.prio != 0U) { /* priority-ceiling protocol used? */ - /* the holder priority must be lower than that of the mutex - * and the priority slot must be occupied by this mutex - */ - Q_ASSERT_ID(210, (curr->super.prio < me->ao.prio) + if (me->ao.prio != 0U) { // prio.-ceiling protocol used? + // the holder prio. must be lower than that of the mutex + // and the prio. slot must be occupied by this mutex + Q_ASSERT_INCRIT(210, (curr->super.prio < me->ao.prio) && (QActive_registry_[me->ao.prio] == &me->ao)); - /* remove the thread's original prio from the ready set - * and insert the mutex's prio into the ready set - */ - QPSet_remove(&QF_readySet_, (uint_fast8_t)me->ao.eQueue.head); - QPSet_insert(&QF_readySet_, (uint_fast8_t)me->ao.prio); - - /* put the thread into the AO registry in place of the mutex */ + // remove the thread's original prio from the ready set + // and insert the mutex's prio into the ready set + QPSet_remove(&QXK_priv_.readySet, + (uint_fast8_t)me->ao.eQueue.head); + QPSet_insert(&QXK_priv_.readySet, + (uint_fast8_t)me->ao.prio); + #ifndef Q_UNSAFE + QPSet_update_(&QXK_priv_.readySet, &QXK_priv_.readySet_dis); + #endif + // put the thread into the AO registry in place of the mutex QActive_registry_[me->ao.prio] = &curr->super; - /* set thread's prio to that of the mutex */ + // set thread's prio to that of the mutex curr->super.prio = me->ao.prio; } } - /* is the mutex locked by this thread already (nested locking)? */ - else if (me->ao.thread == &curr->super) { + // is the mutex locked by this thread already (nested locking)? + else if (me->ao.osObject == &curr->super) { - /* the nesting level beyond the arbitrary but high limit - * most likely means cyclic or recursive locking of a mutex. - */ - Q_ASSERT_ID(220, me->ao.eQueue.nFree < 0xFFU); + // the nesting level beyond the arbitrary but high limit + // most likely means cyclic or recursive locking of a mutex. + Q_ASSERT_INCRIT(220, me->ao.eQueue.nFree < 0xFFU); - ++me->ao.eQueue.nFree; /* lock one more level */ + ++me->ao.eQueue.nFree; // lock one more level - QS_BEGIN_NOCRIT_PRE_(QS_MTX_LOCK, curr->super.prio) - QS_TIME_PRE_(); /* timestamp */ - QS_OBJ_PRE_(me); /* this mutex */ - QS_U8_PRE_((uint8_t)me->ao.eQueue.head); /* holder prio */ - QS_U8_PRE_((uint8_t)me->ao.eQueue.nFree); /* nesting */ - QS_END_NOCRIT_PRE_() + QS_BEGIN_PRE_(QS_MTX_LOCK, curr->super.prio) + QS_TIME_PRE_(); // timestamp + QS_OBJ_PRE_(me); // this mutex + QS_U8_PRE_((uint8_t)me->ao.eQueue.head); // holder prio + QS_U8_PRE_((uint8_t)me->ao.eQueue.nFree); // nesting + QS_END_PRE_() } - else { /* the mutex is already locked by a different thread */ - /* the mutex holder must be valid */ - Q_ASSERT_ID(230, me->ao.thread != (void *)0); + else { // the mutex is already locked by a different thread + // the mutex holder must be valid + Q_ASSERT_INCRIT(230, me->ao.osObject != (void *)0); - if (me->ao.prio != 0U) { /* priority-ceiling protocol used? */ - /* the prio slot must be occupied by the thr. holding the mutex */ - Q_ASSERT_ID(240, QActive_registry_[me->ao.prio] - == QXK_PTR_CAST_(QActive *, me->ao.thread)); + if (me->ao.prio != 0U) { // prio.-ceiling protocol used? + // the prio slot must be occupied by the thr. holding the mutex + Q_ASSERT_INCRIT(240, QActive_registry_[me->ao.prio] + == QACTIVE_CAST_(me->ao.osObject)); } - /* remove the curr thread's prio from the ready set (will block) - * and insert it to the waiting set on this mutex - */ + // remove the curr thread's prio from the ready set (will block) + // and insert it to the waiting set on this mutex uint_fast8_t const p = (uint_fast8_t)curr->super.prio; - QPSet_remove(&QF_readySet_, p); - QPSet_insert(&me->waitSet, p); + QPSet_remove(&QXK_priv_.readySet, p); + #ifndef Q_UNSAFE + QPSet_update_(&QXK_priv_.readySet, &QXK_priv_.readySet_dis); + #endif + QPSet_insert(&me->waitSet, p); - /* set the blocking object (this mutex) */ + // set the blocking object (this mutex) curr->super.super.temp.obj = QXK_PTR_CAST_(QMState*, me); QXThread_teArm_(curr, (enum_t)QXK_TIMEOUT_SIG, nTicks); - QS_BEGIN_NOCRIT_PRE_(QS_MTX_BLOCK, curr->super.prio) - QS_TIME_PRE_(); /* timestamp */ - QS_OBJ_PRE_(me); /* this mutex */ - QS_2U8_PRE_((uint8_t)me->ao.eQueue.head, /* holder prio */ - curr->super.prio); /* blocked thread prio */ - QS_END_NOCRIT_PRE_() + QS_BEGIN_PRE_(QS_MTX_BLOCK, curr->super.prio) + QS_TIME_PRE_(); // timestamp + QS_OBJ_PRE_(me); // this mutex + QS_2U8_PRE_((uint8_t)me->ao.eQueue.head, // holder prio + curr->super.prio); // blocked thread prio + QS_END_PRE_() - /* schedule the next thread if multitasking started */ - (void)QXK_sched_(); /* schedule other threads */ - QF_CRIT_X_(); - QF_CRIT_EXIT_NOP(); /* BLOCK here !!! */ + // schedule the next thread if multitasking started + (void)QXK_sched_(); // schedule other threads - /* AFTER unblocking... */ - QF_CRIT_E_(); - /* the blocking object must be this mutex */ - Q_ASSERT_ID(240, curr->super.super.temp.obj + QF_MEM_APP(); + QF_CRIT_EXIT(); + QF_CRIT_EXIT_NOP(); // BLOCK here !!! + + // AFTER unblocking... + QF_CRIT_ENTRY(); + QF_MEM_SYS(); + // the blocking object must be this mutex + Q_ASSERT_INCRIT(250, curr->super.super.temp.obj == QXK_PTR_CAST_(QMState*, me)); - /* did the blocking time-out? (signal of zero means that it did) */ + // did the blocking time-out? (signal of zero means that it did) if (curr->timeEvt.super.sig == 0U) { - if (QPSet_hasElement(&me->waitSet, p)) { /* still waiting? */ - QPSet_remove(&me->waitSet, p); /* remove unblocked thread */ - locked = false; /* the mutex was NOT locked */ + if (QPSet_hasElement(&me->waitSet, p)) { // still waiting? + QPSet_remove(&me->waitSet, p); // remove unblocked thread + locked = false; // the mutex was NOT locked } } - else { /* blocking did NOT time out */ - /* the thread must NOT be waiting on this mutex */ - Q_ASSERT_ID(250, !QPSet_hasElement(&me->waitSet, p)); + else { // blocking did NOT time out + // the thread must NOT be waiting on this mutex + Q_ASSERT_INCRIT(260, !QPSet_hasElement(&me->waitSet, p)); } - curr->super.super.temp.obj = (QMState *)0; /* clear blocking obj. */ + curr->super.super.temp.obj = (QMState *)0; // clear blocking obj. } - QF_CRIT_X_(); + QF_MEM_APP(); + QF_CRIT_EXIT(); return locked; } -/*${QXK::QXMutex::tryLock} .................................................*/ +//${QXK::QXMutex::tryLock} ................................................... +//! @public @memberof QXMutex bool QXMutex_tryLock(QXMutex * const me) { - QF_CRIT_STAT_ - QF_CRIT_E_(); + QF_CRIT_STAT + QF_CRIT_ENTRY(); + QF_MEM_SYS(); - QActive *curr = QXK_attr_.curr; - if (curr == (QActive *)0) { /* called from a basic thread? */ - curr = QActive_registry_[QXK_attr_.actPrio]; + QActive *curr = QXK_priv_.curr; + if (curr == (QActive *)0) { // called from a basic thread? + curr = QActive_registry_[QXK_priv_.actPrio]; } - /*! @pre this function must: - * - NOT be called from an ISR; - * - the calling thread must be valid; - * - the mutex-priority must be in range - */ - Q_REQUIRE_ID(300, (!QXK_ISR_CONTEXT_()) /* don't call from an ISR! */ - && (curr != (QActive *)0) /* current thread must be valid */ + // precondition, this mutex must: + // - NOT be called from an ISR; + // - the calling thread must be valid; + // - the mutex-prio. must be in range + Q_REQUIRE_INCRIT(300, (!QXK_ISR_CONTEXT_()) + && (curr != (QActive *)0) && (me->ao.prio <= QF_MAX_ACTIVE)); - /*! @pre also: the thread must NOT be holding a scheduler lock. */ - Q_REQUIRE_ID(301, QXK_attr_.lockHolder != curr->prio); + // also: the thread must NOT be holding a scheduler lock. + Q_REQUIRE_INCRIT(301, + QXK_priv_.lockHolder != (uint_fast8_t)curr->prio); - /* is the mutex available? */ + // is the mutex available? if (me->ao.eQueue.nFree == 0U) { - me->ao.eQueue.nFree = 1U; /* mutex lock nesting */ + me->ao.eQueue.nFree = 1U; // mutex lock nesting - /*! @pre also: the newly locked mutex must have no holder yet */ - Q_REQUIRE_ID(302, me->ao.thread == (void *)0); + // also the newly locked mutex must have no holder yet + Q_REQUIRE_INCRIT(303, me->ao.osObject == (void *)0); - /* set the new mutex holder to the curr thread and - * save the thread's prio in the mutex - * NOTE: reuse the otherwise unused eQueue data member. - */ - me->ao.thread = curr; + // set the new mutex holder to the curr thread and + // save the thread's prio in the mutex + // NOTE: reuse the otherwise unused eQueue data member. + me->ao.osObject = curr; me->ao.eQueue.head = (QEQueueCtr)curr->prio; - QS_BEGIN_NOCRIT_PRE_(QS_MTX_LOCK, curr->prio) - QS_TIME_PRE_(); /* timestamp */ - QS_OBJ_PRE_(me); /* this mutex */ - QS_U8_PRE_((uint8_t)me->ao.eQueue.head); /* holder prio */ - QS_U8_PRE_((uint8_t)me->ao.eQueue.nFree); /* nesting */ - QS_END_NOCRIT_PRE_() + QS_BEGIN_PRE_(QS_MTX_LOCK, curr->prio) + QS_TIME_PRE_(); // timestamp + QS_OBJ_PRE_(me); // this mutex + QS_U8_PRE_((uint8_t)me->ao.eQueue.head); // holder prio + QS_U8_PRE_((uint8_t)me->ao.eQueue.nFree); // nesting + QS_END_PRE_() - if (me->ao.prio != 0U) { /* priority-ceiling protocol used? */ - /* the holder priority must be lower than that of the mutex - * and the priority slot must be occupied by this mutex - */ - Q_ASSERT_ID(210, (curr->prio < me->ao.prio) + if (me->ao.prio != 0U) { // prio.-ceiling protocol used? + // the holder prio. must be lower than that of the mutex + // and the prio. slot must be occupied by this mutex + Q_ASSERT_INCRIT(310, (curr->prio < me->ao.prio) && (QActive_registry_[me->ao.prio] == &me->ao)); - /* remove the thread's original prio from the ready set - * and insert the mutex's prio into the ready set - */ - QPSet_remove(&QF_readySet_, (uint_fast8_t)me->ao.eQueue.head); - QPSet_insert(&QF_readySet_, (uint_fast8_t)me->ao.prio); - - /* put the thread into the AO registry in place of the mutex */ + // remove the thread's original prio from the ready set + // and insert the mutex's prio into the ready set + QPSet_remove(&QXK_priv_.readySet, + (uint_fast8_t)me->ao.eQueue.head); + QPSet_insert(&QXK_priv_.readySet, + (uint_fast8_t)me->ao.prio); + #ifndef Q_UNSAFE + QPSet_update_(&QXK_priv_.readySet, &QXK_priv_.readySet_dis); + #endif + // put the thread into the AO registry in place of the mutex QActive_registry_[me->ao.prio] = curr; - /* set thread's prio to that of the mutex */ + // set thread's prio to that of the mutex curr->prio = me->ao.prio; } } - /* is the mutex locked by this thread already (nested locking)? */ - else if (me->ao.thread == curr) { - /* the nesting level must not exceed the specified limit */ - Q_ASSERT_ID(320, me->ao.eQueue.nFree < 0xFFU); + // is the mutex locked by this thread already (nested locking)? + else if (me->ao.osObject == curr) { + // the nesting level must not exceed the specified limit + Q_ASSERT_INCRIT(320, me->ao.eQueue.nFree < 0xFFU); - ++me->ao.eQueue.nFree; /* lock one more level */ + ++me->ao.eQueue.nFree; // lock one more level - QS_BEGIN_NOCRIT_PRE_(QS_MTX_LOCK, curr->prio) - QS_TIME_PRE_(); /* timestamp */ - QS_OBJ_PRE_(me); /* this mutex */ - QS_U8_PRE_((uint8_t)me->ao.eQueue.head); /* holder prio */ - QS_U8_PRE_((uint8_t)me->ao.eQueue.nFree); /* nesting */ - QS_END_NOCRIT_PRE_() + QS_BEGIN_PRE_(QS_MTX_LOCK, curr->prio) + QS_TIME_PRE_(); // timestamp + QS_OBJ_PRE_(me); // this mutex + QS_U8_PRE_((uint8_t)me->ao.eQueue.head); // holder prio + QS_U8_PRE_((uint8_t)me->ao.eQueue.nFree); // nesting + QS_END_PRE_() } - else { /* the mutex is already locked by a different thread */ - if (me->ao.prio != 0U) { /* priority-ceiling protocol used? */ - /* the prio slot must be occupied by the thr. holding the mutex */ - Q_ASSERT_ID(340, QActive_registry_[me->ao.prio] - == QXK_PTR_CAST_(QActive *, me->ao.thread)); + else { // the mutex is already locked by a different thread + if (me->ao.prio != 0U) { // prio.-ceiling protocol used? + // the prio slot must be occupied by the thr. holding the mutex + Q_ASSERT_INCRIT(330, QActive_registry_[me->ao.prio] + == QACTIVE_CAST_(me->ao.osObject)); } - QS_BEGIN_NOCRIT_PRE_(QS_MTX_BLOCK_ATTEMPT, curr->prio) - QS_TIME_PRE_(); /* timestamp */ - QS_OBJ_PRE_(me); /* this mutex */ - QS_2U8_PRE_((uint8_t)me->ao.eQueue.head, /* holder prio */ - curr->prio); /* trying thread prio */ - QS_END_NOCRIT_PRE_() + QS_BEGIN_PRE_(QS_MTX_BLOCK_ATTEMPT, curr->prio) + QS_TIME_PRE_(); // timestamp + QS_OBJ_PRE_(me); // this mutex + QS_2U8_PRE_((uint8_t)me->ao.eQueue.head, // holder prio + curr->prio); // trying thread prio + QS_END_PRE_() - curr = (QActive *)0; /* means that mutex is NOT available */ + curr = (QActive *)0; // means that mutex is NOT available } - QF_CRIT_X_(); + QF_MEM_APP(); + QF_CRIT_EXIT(); return curr != (QActive *)0; } -/*${QXK::QXMutex::unlock} ..................................................*/ +//${QXK::QXMutex::unlock} .................................................... +//! @public @memberof QXMutex void QXMutex_unlock(QXMutex * const me) { - QF_CRIT_STAT_ - QF_CRIT_E_(); + QF_CRIT_STAT + QF_CRIT_ENTRY(); + QF_MEM_SYS(); - QActive *curr = QXK_attr_.curr; - if (curr == (QActive *)0) { /* called from a basic thread? */ - curr = QActive_registry_[QXK_attr_.actPrio]; + QActive *curr = QXK_priv_.curr; + if (curr == (QActive *)0) { // called from a basic thread? + curr = QActive_registry_[QXK_priv_.actPrio]; } - /*! @pre this function must: - * - NOT be called from an ISR; - * - the calling thread must be valid; - */ - Q_REQUIRE_ID(400, (!QXK_ISR_CONTEXT_()) /* don't call from an ISR! */ - && (curr != (QActive *)0)); /* current thread must be valid */ + Q_REQUIRE_INCRIT(400, (!QXK_ISR_CONTEXT_()) + && (curr != (QActive *)0)); + Q_REQUIRE_INCRIT(401, me->ao.eQueue.nFree > 0U); + Q_REQUIRE_INCRIT(403, me->ao.osObject == curr); - /*! @pre also: the mutex must be already locked at least once. */ - Q_REQUIRE_ID(401, me->ao.eQueue.nFree > 0U); - /*! @pre also: the mutex must be held by this thread. */ - Q_REQUIRE_ID(402, me->ao.thread == curr); - - /* is this the last nesting level? */ + // is this the last nesting level? if (me->ao.eQueue.nFree == 1U) { - if (me->ao.prio != 0U) { /* priority-ceiling protocol used? */ + if (me->ao.prio != 0U) { // prio.-ceiling protocol used? + // prio. must be in range + Q_ASSERT_INCRIT(410, me->ao.prio < QF_MAX_ACTIVE); - /* restore the holding thread's prio from the mutex */ + // restore the holding thread's prio from the mutex curr->prio = (uint8_t)me->ao.eQueue.head; - /* put the mutex back into the AO registry */ + // put the mutex back into the AO registry QActive_registry_[me->ao.prio] = &me->ao; - /* remove the mutex' prio from the ready set - * and insert the original thread's priority - */ - QPSet_remove(&QF_readySet_, (uint_fast8_t)me->ao.prio); - QPSet_insert(&QF_readySet_, (uint_fast8_t)me->ao.eQueue.head); + // remove the mutex' prio from the ready set + // and insert the original thread's prio. + QPSet_remove(&QXK_priv_.readySet, + (uint_fast8_t)me->ao.prio); + QPSet_insert(&QXK_priv_.readySet, + (uint_fast8_t)me->ao.eQueue.head); + #ifndef Q_UNSAFE + QPSet_update_(&QXK_priv_.readySet, &QXK_priv_.readySet_dis); + #endif } - QS_BEGIN_NOCRIT_PRE_(QS_MTX_UNLOCK, curr->prio) - QS_TIME_PRE_(); /* timestamp */ - QS_OBJ_PRE_(me); /* this mutex */ - QS_2U8_PRE_((uint8_t)me->ao.eQueue.head, /* holder prio */ - 0U); /* nesting */ - QS_END_NOCRIT_PRE_() + QS_BEGIN_PRE_(QS_MTX_UNLOCK, curr->prio) + QS_TIME_PRE_(); // timestamp + QS_OBJ_PRE_(me); // this mutex + QS_2U8_PRE_((uint8_t)me->ao.eQueue.head, // holder prio + 0U); // nesting + QS_END_PRE_() - /* are any other threads waiting on this mutex? */ + // are any other threads waiting on this mutex? if (QPSet_notEmpty(&me->waitSet)) { - /* find the highest-priority thread waiting on this mutex */ + // find the highest-prio. thread waiting on this mutex uint_fast8_t const p = QPSet_findMax(&me->waitSet); - /* remove this thread from waiting on the mutex - * and insert it into the ready set. - */ - QPSet_remove(&me->waitSet, p); - QPSet_insert(&QF_readySet_, p); + // remove this thread from waiting on the mutex + // and insert it into the ready set. + QPSet_remove(&me->waitSet, p); + QPSet_insert(&QXK_priv_.readySet, p); + #ifndef Q_UNSAFE + QPSet_update_(&QXK_priv_.readySet, &QXK_priv_.readySet_dis); + #endif QXThread * const thr = QXK_PTR_CAST_(QXThread*, QActive_registry_[p]); - /* the waiting thread must: - * - be registered in QF - * - have the priority corresponding to the registration - * - be an extended thread - * - be blocked on this mutex - */ - Q_ASSERT_ID(410, (thr != (QXThread *)0) + // the waiting thread must: + // - be registered in QF + // - have the prio. corresponding to the registration + // - be an extended thread + // - be blocked on this mutex + Q_ASSERT_INCRIT(420, (thr != (QXThread *)0) && (thr->super.prio == (uint8_t)p) && (thr->super.super.state.act == Q_ACTION_CAST(0)) && (thr->super.super.temp.obj == QXK_PTR_CAST_(QMState*, me))); - /* disarm the internal time event */ + // disarm the internal time event (void)QXThread_teDisarm_(thr); - /* set the new mutex holder to the curr thread and - * save the thread's prio in the mutex - * NOTE: reuse the otherwise unused eQueue data member. - */ - me->ao.thread = thr; + // set the new mutex holder to the curr thread and + // save the thread's prio in the mutex + // NOTE: reuse the otherwise unused eQueue data member. + me->ao.osObject = thr; me->ao.eQueue.head = (QEQueueCtr)thr->super.prio; - QS_BEGIN_NOCRIT_PRE_(QS_MTX_LOCK, thr->super.prio) - QS_TIME_PRE_(); /* timestamp */ - QS_OBJ_PRE_(me); /* this mutex */ - QS_U8_PRE_((uint8_t)me->ao.eQueue.head); /* holder prio */ - QS_U8_PRE_((uint8_t)me->ao.eQueue.nFree); /* nesting */ - QS_END_NOCRIT_PRE_() + QS_BEGIN_PRE_(QS_MTX_LOCK, thr->super.prio) + QS_TIME_PRE_(); // timestamp + QS_OBJ_PRE_(me); // this mutex + QS_U8_PRE_((uint8_t)me->ao.eQueue.head); // holder prio + QS_U8_PRE_((uint8_t)me->ao.eQueue.nFree); // nesting + QS_END_PRE_() - if (me->ao.prio != 0U) { /* priority-ceiling protocol used? */ - /* the holder priority must be lower than that of the mutex */ - Q_ASSERT_ID(410, thr->super.prio < me->ao.prio); + if (me->ao.prio != 0U) { // prio.-ceiling protocol used? + // the holder prio. must be lower than that of the mutex + Q_ASSERT_INCRIT(430, (me->ao.prio < QF_MAX_ACTIVE) + && (thr->super.prio < me->ao.prio)); - /* put the thread into AO registry in place of the mutex */ + // put the thread into AO registry in place of the mutex QActive_registry_[me->ao.prio] = &thr->super; } } - else { /* no threads are waiting for this mutex */ - me->ao.eQueue.nFree = 0U; /* free up the nesting count */ + else { // no threads are waiting for this mutex + me->ao.eQueue.nFree = 0U; // free up the nesting count - /* the mutex no longer held by any thread */ - me->ao.thread = (void *)0; + // the mutex no longer held by any thread + me->ao.osObject = (void *)0; me->ao.eQueue.head = 0U; + me->ao.eQueue.tail = 0U; - if (me->ao.prio != 0U) { /* priority-ceiling protocol used? */ - /* put the mutex back at the original mutex slot */ + if (me->ao.prio != 0U) { // prio.-ceiling protocol used? + // put the mutex back at the original mutex slot QActive_registry_[me->ao.prio] = QXK_PTR_CAST_(QActive*, me); } } - /* schedule the next thread if multitasking started */ - if (QXK_sched_() != 0U) { /* activation needed? */ - QXK_activate_(); /* synchronously activate basic-thred(s) */ + // schedule the next thread if multitasking started + if (QXK_sched_() != 0U) { // activation needed? + QXK_activate_(); // synchronously activate basic-thred(s) } } - else { /* releasing one level of nested mutex lock */ - Q_ASSERT_ID(420, me->ao.eQueue.nFree > 0U); - --me->ao.eQueue.nFree; /* unlock one level */ + else { // releasing one level of nested mutex lock + --me->ao.eQueue.nFree; // unlock one level - QS_BEGIN_NOCRIT_PRE_(QS_MTX_UNLOCK_ATTEMPT, curr->prio) - QS_TIME_PRE_(); /* timestamp */ - QS_OBJ_PRE_(me); /* this mutex */ - QS_U8_PRE_((uint8_t)me->ao.eQueue.head); /* holder prio */ - QS_U8_PRE_((uint8_t)me->ao.eQueue.nFree); /* nesting */ - QS_END_NOCRIT_PRE_() + QS_BEGIN_PRE_(QS_MTX_UNLOCK_ATTEMPT, curr->prio) + QS_TIME_PRE_(); // timestamp + QS_OBJ_PRE_(me); // this mutex + QS_U8_PRE_((uint8_t)me->ao.eQueue.head); // holder prio + QS_U8_PRE_((uint8_t)me->ao.eQueue.nFree); // nesting + QS_END_PRE_() } - QF_CRIT_X_(); + QF_MEM_APP(); + QF_CRIT_EXIT(); } -/*$enddef${QXK::QXMutex} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$enddef${QXK::QXMutex} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/src/qxk/qxk_sema.c b/src/qxk/qxk_sema.c index 25a24420..d62cfcd7 100644 --- a/src/qxk/qxk_sema.c +++ b/src/qxk/qxk_sema.c @@ -1,279 +1,288 @@ -/*$file${src::qxk::qxk_sema.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* -* Model: qpc.qm -* File: ${src::qxk::qxk_sema.c} -* -* This code has been generated by QM 5.2.4 . -* DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. -* -* This code is covered by the following QP license: -* License # : LicenseRef-QL-dual -* Issued to : Any user of the QP/C real-time embedded framework -* Framework(s) : qpc -* Support ends : 2023-12-31 -* License scope: -* -* Copyright (C) 2005 Quantum Leaps, LLC . -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -*/ -/*$endhead${src::qxk::qxk_sema.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*! @file -* @brief QXK preemptive kernel semaphore functions -*/ -#define QP_IMPL /* this is QP implementation */ -#include "qf_port.h" /* QF port */ -#include "qf_pkg.h" /* QF package-scope internal interface */ -#include "qassert.h" /* QP embedded systems-friendly assertions */ -#ifdef Q_SPY /* QS software tracing enabled? */ - #include "qs_port.h" /* QS port */ - #include "qs_pkg.h" /* QS facilities for pre-defined trace records */ +//$file${src::qxk::qxk_sema.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// +// Model: qpc.qm +// File: ${src::qxk::qxk_sema.c} +// +// This code has been generated by QM 5.3.0 . +// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. +// +// This code is covered by the following QP license: +// License # : LicenseRef-QL-dual +// Issued to : Any user of the QP/C real-time embedded framework +// Framework(s) : qpc +// Support ends : 2024-12-31 +// License scope: +// +// Copyright (C) 2005 Quantum Leaps, LLC . +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +// +//$endhead${src::qxk::qxk_sema.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +#define QP_IMPL // this is QP implementation +#include "qp_port.h" // QP port +#include "qp_pkg.h" // QP package-scope interface +#include "qsafe.h" // QP Functional Safety (FuSa) Subsystem +#ifdef Q_SPY // QS software tracing enabled? + #include "qs_port.h" // QS port + #include "qs_pkg.h" // QS facilities for pre-defined trace records #else - #include "qs_dummy.h" /* disable the QS software tracing */ -#endif /* Q_SPY */ + #include "qs_dummy.h" // disable the QS software tracing +#endif // Q_SPY -/* protection against including this source file in a wrong project */ -#ifndef QP_INC_QXK_H_ +// protection against including this source file in a wrong project +#ifndef QXK_H_ #error "Source file included in a project NOT based on the QXK kernel" -#endif /* QP_INC_QXK_H_ */ +#endif // QXK_H_ Q_DEFINE_THIS_MODULE("qxk_sema") -/*==========================================================================*/ -/*$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* Check for the minimum required QP version */ -#if (QP_VERSION < 700U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) -#error qpc version 7.0.0 or higher required +//$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// Check for the minimum required QP version +#if (QP_VERSION < 730U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) +#error qpc version 7.3.0 or higher required #endif -/*$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -/*$define${QXK::QXSemaphore} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//$define${QXK::QXSemaphore} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/*${QXK::QXSemaphore} ......................................................*/ +//${QXK::QXSemaphore} ........................................................ -/*${QXK::QXSemaphore::init} ................................................*/ +//${QXK::QXSemaphore::init} .................................................. +//! @public @memberof QXSemaphore void QXSemaphore_init(QXSemaphore * const me, uint_fast8_t const count, uint_fast8_t const max_count) { - /*! @pre max_count must be greater than zero */ - Q_REQUIRE_ID(100, max_count > 0U); + QF_CRIT_STAT + QF_CRIT_ENTRY(); + QF_MEM_SYS(); + + Q_REQUIRE_INCRIT(100, (count <= max_count) + && (0U < max_count) && (max_count <= 0xFFU)); me->count = (uint8_t)count; me->max_count = (uint8_t)max_count; QPSet_setEmpty(&me->waitSet); + + QF_MEM_APP(); + QF_CRIT_EXIT(); } -/*${QXK::QXSemaphore::wait} ................................................*/ +//${QXK::QXSemaphore::wait} .................................................. +//! @public @memberof QXSemaphore bool QXSemaphore_wait(QXSemaphore * const me, - uint_fast16_t const nTicks) + QTimeEvtCtr const nTicks) { - QF_CRIT_STAT_ - QF_CRIT_E_(); + QF_CRIT_STAT + QF_CRIT_ENTRY(); + QF_MEM_SYS(); - /* volatile into temp. */ - QXThread * const curr = QXK_PTR_CAST_(QXThread*, QXK_attr_.curr); + QXThread * const curr = QXK_PTR_CAST_(QXThread*, QXK_priv_.curr); - /*! @pre this function must: - * - NOT be called from an ISR; - * - the semaphore must be initialized - * - be called from an extended thread; - * - the thread must NOT be already blocked on any object. - */ - Q_REQUIRE_ID(200, (!QXK_ISR_CONTEXT_()) /* can't wait inside an ISR */ - && (me->max_count > 0U) /* sema must be initialized */ - && (curr != (QXThread *)0) /* curr must be extended */ - && (curr->super.super.temp.obj == (QMState *)0)); /* NOT blocked */ - /*! @pre also: the thread must NOT be holding a scheduler lock. */ - Q_REQUIRE_ID(201, QXK_attr_.lockHolder != curr->super.prio); + // precondition, this function: + // - must NOT be called from an ISR; + // - the semaphore must be initialized + // - be called from an extended thread; + // - the thread must NOT be already blocked on any object. + Q_REQUIRE_INCRIT(200, (!QXK_ISR_CONTEXT_()) + && (me->max_count > 0U) + && (curr != (QXThread *)0) + && (curr->super.super.temp.obj == (QMState *)0)); + // - the thread must NOT be holding a scheduler lock. + Q_REQUIRE_INCRIT(201, + QXK_priv_.lockHolder != (uint_fast8_t)curr->super.prio); - bool signaled = true; /* assume that the semaphore will be signaled */ + bool taken = true; // assume that the semaphore will be signaled if (me->count > 0U) { - --me->count; /* semaphore taken: decrement the count */ + --me->count; // semaphore taken: decrement the count - QS_BEGIN_NOCRIT_PRE_(QS_SEM_TAKE, curr->super.prio) - QS_TIME_PRE_(); /* timestamp */ - QS_OBJ_PRE_(me); /* this semaphore */ - QS_2U8_PRE_(curr->super.prio, - me->count); - QS_END_NOCRIT_PRE_() + QS_BEGIN_PRE_(QS_SEM_TAKE, curr->super.prio) + QS_TIME_PRE_(); // timestamp + QS_OBJ_PRE_(me); // this semaphore + QS_2U8_PRE_(curr->super.prio, me->count); + QS_END_PRE_() } - else { + else { // semaphore not available -- BLOCK the thread uint_fast8_t const p = (uint_fast8_t)curr->super.prio; - /* remove the curr prio from the ready set (will block) - * and insert to the waiting set on this semaphore - */ - QPSet_remove(&QF_readySet_, p); + // remove the curr prio from the ready set (will block) + // and insert to the waiting set on this semaphore + QPSet_remove(&QXK_priv_.readySet, p); + #ifndef Q_UNSAFE + QPSet_update_(&QXK_priv_.readySet, &QXK_priv_.readySet_dis); + #endif QPSet_insert(&me->waitSet, p); - /* remember the blocking object (this semaphore) */ + // remember the blocking object (this semaphore) curr->super.super.temp.obj = QXK_PTR_CAST_(QMState*, me); QXThread_teArm_(curr, (enum_t)QXK_TIMEOUT_SIG, nTicks); - QS_BEGIN_NOCRIT_PRE_(QS_SEM_BLOCK, curr->super.prio) - QS_TIME_PRE_(); /* timestamp */ - QS_OBJ_PRE_(me); /* this semaphore */ - QS_2U8_PRE_(curr->super.prio, - me->count); - QS_END_NOCRIT_PRE_() + QS_BEGIN_PRE_(QS_SEM_BLOCK, curr->super.prio) + QS_TIME_PRE_(); // timestamp + QS_OBJ_PRE_(me); // this semaphore + QS_2U8_PRE_(curr->super.prio, me->count); + QS_END_PRE_() - /* schedule the next thread if multitasking started */ - (void)QXK_sched_(); /* schedule other theads */ - QF_CRIT_X_(); - QF_CRIT_EXIT_NOP(); /* BLOCK here !!! */ + // schedule the next thread if multitasking started + (void)QXK_sched_(); // schedule other threads - QF_CRIT_E_(); /* AFTER unblocking... */ - /* the blocking object must be this semaphore */ - Q_ASSERT_ID(240, curr->super.super.temp.obj + QF_MEM_APP(); + QF_CRIT_EXIT(); + QF_CRIT_EXIT_NOP(); // BLOCK here !!! + + QF_CRIT_ENTRY(); // AFTER unblocking... + QF_MEM_SYS(); + + // the blocking object must be this semaphore + Q_ASSERT_INCRIT(240, curr->super.super.temp.obj == QXK_PTR_CAST_(QMState*, me)); - /* did the blocking time-out? (signal of zero means that it did) */ + // did the blocking time-out? (signal of zero means that it did) if (curr->timeEvt.super.sig == 0U) { - if (QPSet_hasElement(&me->waitSet, p)) { /* still waiting? */ - QPSet_remove(&me->waitSet, p); /* remove unblocked thread */ - signaled = false; /* the semaphore was NOT signaled */ - /* semaphore NOT taken: do NOT decrement the count */ - } - else { /* semaphore was both signaled and timed out */ - --me->count; /* semaphore taken: decrement the count */ + if (QPSet_hasElement(&me->waitSet, p)) { // still waiting? + QPSet_remove(&me->waitSet, p); // remove unblocked thread + taken = false; // the semaphore was NOT taken } } - else { /* blocking did NOT time out */ - /* the thread must NOT be waiting on this semaphore */ - Q_ASSERT_ID(250,!QPSet_hasElement(&me->waitSet, p)); - --me->count; /* semaphore taken: decrement the count */ + else { // blocking did NOT time out + // the thread must NOT be waiting on this semaphore + Q_ASSERT_INCRIT(250, !QPSet_hasElement(&me->waitSet, p)); } - curr->super.super.temp.obj = (QMState *)0; /* clear blocking obj. */ + curr->super.super.temp.obj = (QMState *)0; // clear blocking obj. } - QF_CRIT_X_(); + QF_MEM_APP(); + QF_CRIT_EXIT(); - return signaled; + return taken; } -/*${QXK::QXSemaphore::tryWait} .............................................*/ +//${QXK::QXSemaphore::tryWait} ............................................... +//! @public @memberof QXSemaphore bool QXSemaphore_tryWait(QXSemaphore * const me) { - QF_CRIT_STAT_ - QF_CRIT_E_(); + QF_CRIT_STAT + QF_CRIT_ENTRY(); + QF_MEM_SYS(); - /*! @pre the semaphore must be initialized */ - Q_REQUIRE_ID(300, me->max_count > 0U); + // precondition: + // - the semaphore must be initialized + Q_REQUIRE_INCRIT(300, me->max_count > 0U); #ifdef Q_SPY - /* volatile into temp. */ - QActive const * const curr = QXK_PTR_CAST_(QActive*, QXK_attr_.curr); - #endif /* Q_SPY */ + QActive const * const curr = QXK_PTR_CAST_(QActive*, QXK_priv_.curr); + #endif // Q_SPY - bool isAvailable; - /* is the semaphore available? */ + bool taken; + // is the semaphore available? if (me->count > 0U) { --me->count; - isAvailable = true; + taken = true; - QS_BEGIN_NOCRIT_PRE_(QS_SEM_TAKE, curr->prio) - QS_TIME_PRE_(); /* timestamp */ - QS_OBJ_PRE_(me); /* this semaphore */ - QS_2U8_PRE_(curr->prio, - me->count); - QS_END_NOCRIT_PRE_() + QS_BEGIN_PRE_(QS_SEM_TAKE, curr->prio) + QS_TIME_PRE_(); // timestamp + QS_OBJ_PRE_(me); // this semaphore + QS_2U8_PRE_(curr->prio, me->count); + QS_END_PRE_() } - else { /* the semaphore is NOT available (would block) */ - isAvailable = false; + else { // the semaphore is NOT available (would block) + taken = false; - QS_BEGIN_NOCRIT_PRE_(QS_SEM_BLOCK_ATTEMPT, curr->prio) - QS_TIME_PRE_(); /* timestamp */ - QS_OBJ_PRE_(me); /* this semaphore */ - QS_2U8_PRE_(curr->prio, - me->count); - QS_END_NOCRIT_PRE_() + QS_BEGIN_PRE_(QS_SEM_BLOCK_ATTEMPT, curr->prio) + QS_TIME_PRE_(); // timestamp + QS_OBJ_PRE_(me); // this semaphore + QS_2U8_PRE_(curr->prio, me->count); + QS_END_PRE_() } - QF_CRIT_X_(); + QF_MEM_APP(); + QF_CRIT_EXIT(); - return isAvailable; + return taken; } -/*${QXK::QXSemaphore::signal} ..............................................*/ +//${QXK::QXSemaphore::signal} ................................................ +//! @public @memberof QXSemaphore bool QXSemaphore_signal(QXSemaphore * const me) { - /*! @pre the semaphore must be initialized */ - Q_REQUIRE_ID(400, me->max_count > 0U); + bool signaled = true; // assume that the semaphore will be signaled - QF_CRIT_STAT_ - QF_CRIT_E_(); + QF_CRIT_STAT + QF_CRIT_ENTRY(); + QF_MEM_SYS(); - bool signaled = true; /* assume that the semaphore will be signaled */ - if (me->count < me->max_count) { + // precondition: + // - the semaphore must be initialized + Q_REQUIRE_INCRIT(400, me->max_count > 0U); - ++me->count; /* increment the semaphore count */ + // any threads blocked on this semaphore? + if (QPSet_notEmpty(&me->waitSet)) { + // find the highest-prio. thread waiting on this semaphore + uint_fast8_t const p = QPSet_findMax(&me->waitSet); + QXThread * const thr = + QXK_PTR_CAST_(QXThread*, QActive_registry_[p]); - #ifdef Q_SPY - /* volatile into temp. */ - QActive const * const curr = QXK_PTR_CAST_(QActive*, QXK_attr_.curr); - #endif /* Q_SPY */ + // assert that the tread: + // - must be registered in QF; + // - must be extended; and + // - must be blocked on this semaphore; + Q_ASSERT_INCRIT(410, (thr != (QXThread *)0) + && (thr->super.osObject != (void *)0) + && (thr->super.super.temp.obj + == QXK_PTR_CAST_(QMState*, me))); - QS_BEGIN_NOCRIT_PRE_(QS_SEM_SIGNAL, curr->prio) - QS_TIME_PRE_(); /* timestamp */ - QS_OBJ_PRE_(me); /* this semaphore */ - QS_2U8_PRE_(curr->prio, - me->count); - QS_END_NOCRIT_PRE_() + // disarm the internal time event + (void)QXThread_teDisarm_(thr); - if (QPSet_notEmpty(&me->waitSet)) { - /* find the highest-priority thread waiting on this semaphore */ - uint_fast8_t const p = QPSet_findMax(&me->waitSet); - QXThread * const thr = - QXK_PTR_CAST_(QXThread*, QActive_registry_[p]); + // make the thread ready to run and remove from the wait-list + QPSet_insert(&QXK_priv_.readySet, p); + #ifndef Q_UNSAFE + QPSet_update_(&QXK_priv_.readySet, &QXK_priv_.readySet_dis); + #endif + QPSet_remove(&me->waitSet, p); - /* assert that the tread: - * - must be registered in QF; - * - must be extended; and - * - must be blocked on this semaphore; - */ - Q_ASSERT_ID(410, (thr != (QXThread *)0) - && (thr->super.osObject != (struct QActive *)0) - && (thr->super.super.temp.obj - == QXK_PTR_CAST_(QMState*, me))); + QS_BEGIN_PRE_(QS_SEM_TAKE, thr->super.prio) + QS_TIME_PRE_(); // timestamp + QS_OBJ_PRE_(me); // this semaphore + QS_2U8_PRE_(thr->super.prio, me->count); + QS_END_PRE_() - /* disarm the internal time event */ - (void)QXThread_teDisarm_(thr); - - /* make the thread ready to run and remove from the wait-list */ - QPSet_insert(&QF_readySet_, p); - QPSet_remove(&me->waitSet, p); - - QS_BEGIN_NOCRIT_PRE_(QS_SEM_TAKE, thr->super.prio) - QS_TIME_PRE_(); /* timestamp */ - QS_OBJ_PRE_(me); /* this semaphore */ - QS_2U8_PRE_(thr->super.prio, - me->count); - QS_END_NOCRIT_PRE_() - - if (!QXK_ISR_CONTEXT_()) { /* not inside ISR? */ - (void)QXK_sched_(); /* schedule other threads */ - } + if (!QXK_ISR_CONTEXT_()) { // not inside ISR? + (void)QXK_sched_(); // schedule other threads } } - else { - signaled = false; /* semaphore NOT signaled */ + else if (me->count < me->max_count) { + ++me->count; // increment the semaphore count + + QS_BEGIN_PRE_(QS_SEM_SIGNAL, 0U) + QS_TIME_PRE_(); // timestamp + QS_OBJ_PRE_(me); // this semaphore + QS_2U8_PRE_(0U, me->count); + QS_END_PRE_() } - QF_CRIT_X_(); + else { + signaled = false; // semaphore NOT signaled + } + QF_MEM_APP(); + QF_CRIT_EXIT(); return signaled; } -/*$enddef${QXK::QXSemaphore} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$enddef${QXK::QXSemaphore} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/src/qxk/qxk_xthr.c b/src/qxk/qxk_xthr.c index e64e9848..940f912a 100644 --- a/src/qxk/qxk_xthr.c +++ b/src/qxk/qxk_xthr.c @@ -1,147 +1,146 @@ -/*$file${src::qxk::qxk_xthr.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* -* Model: qpc.qm -* File: ${src::qxk::qxk_xthr.c} -* -* This code has been generated by QM 5.2.4 . -* DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. -* -* This code is covered by the following QP license: -* License # : LicenseRef-QL-dual -* Issued to : Any user of the QP/C real-time embedded framework -* Framework(s) : qpc -* Support ends : 2023-12-31 -* License scope: -* -* Copyright (C) 2005 Quantum Leaps, LLC . -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -*/ -/*$endhead${src::qxk::qxk_xthr.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*! @file -* @brief QXK preemptive kernel extended (blocking) thread functions -*/ -#define QP_IMPL /* this is QP implementation */ -#include "qf_port.h" /* QF port */ -#include "qf_pkg.h" /* QF package-scope internal interface */ -#include "qassert.h" /* QP embedded systems-friendly assertions */ -#ifdef Q_SPY /* QS software tracing enabled? */ - #include "qs_port.h" /* QS port */ - #include "qs_pkg.h" /* QS facilities for pre-defined trace records */ +//$file${src::qxk::qxk_xthr.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// +// Model: qpc.qm +// File: ${src::qxk::qxk_xthr.c} +// +// This code has been generated by QM 5.3.0 . +// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. +// +// This code is covered by the following QP license: +// License # : LicenseRef-QL-dual +// Issued to : Any user of the QP/C real-time embedded framework +// Framework(s) : qpc +// Support ends : 2024-12-31 +// License scope: +// +// Copyright (C) 2005 Quantum Leaps, LLC . +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +// +//$endhead${src::qxk::qxk_xthr.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +#define QP_IMPL // this is QP implementation +#include "qp_port.h" // QP port +#include "qp_pkg.h" // QP package-scope interface +#include "qsafe.h" // QP Functional Safety (FuSa) Subsystem +#ifdef Q_SPY // QS software tracing enabled? + #include "qs_port.h" // QS port + #include "qs_pkg.h" // QS facilities for pre-defined trace records #else - #include "qs_dummy.h" /* disable the QS software tracing */ -#endif /* Q_SPY */ + #include "qs_dummy.h" // disable the QS software tracing +#endif // Q_SPY -/* protection against including this source file in a wrong project */ -#ifndef QP_INC_QXK_H_ +// protection against including this source file in a wrong project +#ifndef QXK_H_ #error "Source file included in a project NOT based on the QXK kernel" -#endif /* QP_INC_QXK_H_ */ +#endif // QXK_H_ Q_DEFINE_THIS_MODULE("qxk_xthr") -/*==========================================================================*/ -/*$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -/* Check for the minimum required QP version */ -#if (QP_VERSION < 700U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) -#error qpc version 7.0.0 or higher required +//$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// Check for the minimum required QP version +#if (QP_VERSION < 730U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U)) +#error qpc version 7.3.0 or higher required #endif -/*$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -/*$define${QXK::QXThread} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +//$define${QXK::QXThread} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -/*${QXK::QXThread} .........................................................*/ +//${QXK::QXThread} ........................................................... QXThread const * QXThread_dummy; -/*${QXK::QXThread::ctor} ...................................................*/ +//${QXK::QXThread::ctor} ..................................................... +//! @public @memberof QXThread void QXThread_ctor(QXThread * const me, QXThreadHandler const handler, uint_fast8_t const tickRate) { - static QXThreadVtable const vtable = { /* QXThread virtual table */ - { &QXThread_init_, /* not used in QXThread */ - &QXThread_dispatch_ /* not used in QXThread */ - #ifdef Q_SPY - ,&QHsm_getStateHandler_ /* not used in QXThread */ - #endif - }, - &QXThread_start_, - &QXThread_post_, - &QXThread_postLIFO_ - }; - union QHsmAttr tmp; + union QAsmAttr tmp; tmp.thr = handler; + QActive_ctor(&me->super, tmp.fun); // superclass' ctor - QActive_ctor(&me->super, tmp.fun); /* superclass' ctor */ - me->super.super.vptr = &vtable.super; /* hook to QXThread vtable */ - me->super.super.state.act = Q_ACTION_CAST(0); /*mark as extended thread */ + me->super.super.state.act = Q_ACTION_CAST(0); // mark as extended thread - /* construct the time event member added in the QXThread class */ + // instantiate the time-event member in the QXThread class QTimeEvt_ctorX(&me->timeEvt, &me->super, (enum_t)QXK_DELAY_SIG, tickRate); } -/*${QXK::QXThread::delay} ..................................................*/ -bool QXThread_delay(uint_fast16_t const nTicks) { - QF_CRIT_STAT_ - QF_CRIT_E_(); +//${QXK::QXThread::delay} .................................................... +//! @public @memberof QXThread +bool QXThread_delay(QTimeEvtCtr const nTicks) { + QF_CRIT_STAT + QF_CRIT_ENTRY(); + QF_MEM_SYS(); - QXThread * const thr = QXTHREAD_CAST_(QXK_attr_.curr); + QXThread * const thr = QXTHREAD_CAST_(QXK_priv_.curr); - /*! @pre this function must: - * - NOT be called from an ISR; - * - number of ticks cannot be zero - * - be called from an extended thread; - * - the thread must NOT be already blocked on any object. - */ - Q_REQUIRE_ID(800, (!QXK_ISR_CONTEXT_()) /* can't block inside an ISR */ - && (nTicks != 0U) /* number of ticks cannot be zero */ - && (thr != (QXThread *)0) /* current thread must be extended */ - && (thr->super.super.temp.obj == (QMState *)0)); /* !blocked */ - /*! @pre also: the thread must NOT be holding a scheduler lock. */ - Q_REQUIRE_ID(801, QXK_attr_.lockHolder != thr->super.prio); + // precondition, this function: + // - must NOT be called from an ISR; + // - number of ticks cannot be zero + // - be called from an extended thread; + // - the thread must NOT be already blocked on any object. + Q_REQUIRE_INCRIT(800, (!QXK_ISR_CONTEXT_()) + && (nTicks != 0U) + && (thr != (QXThread *)0) + && (thr->super.super.temp.obj == (QMState *)0)); + // - the thread must NOT be holding a scheduler lock. + Q_REQUIRE_INCRIT(801, + QXK_priv_.lockHolder != (uint_fast8_t)thr->super.prio); - /* remember the blocking object */ + // remember the blocking object thr->super.super.temp.obj = QXK_PTR_CAST_(QMState const*, &thr->timeEvt); QXThread_teArm_(thr, (enum_t)QXK_DELAY_SIG, nTicks); QXThread_block_(thr); - QF_CRIT_X_(); - QF_CRIT_EXIT_NOP(); /* BLOCK here */ - QF_CRIT_E_(); - /* the blocking object must be the time event */ - Q_ENSURE_ID(890, thr->super.super.temp.obj + QF_MEM_APP(); + QF_CRIT_EXIT(); + QF_CRIT_EXIT_NOP(); // BLOCK here + + // after unblocking... + QF_CRIT_ENTRY(); + QF_MEM_SYS(); + + // the blocking object must be the time event + Q_ASSERT_INCRIT(890, thr->super.super.temp.obj == QXK_PTR_CAST_(QMState const*, &thr->timeEvt)); - thr->super.super.temp.obj = (QMState *)0; /* clear */ - QF_CRIT_X_(); + thr->super.super.temp.obj = (QMState *)0; // clear - /* signal of zero means that the time event was posted without - * being canceled. - */ + QF_MEM_APP(); + QF_CRIT_EXIT(); + + // signal of zero means that the time event was posted without + // being canceled. return thr->timeEvt.super.sig == 0U; } -/*${QXK::QXThread::delayCancel} ............................................*/ +//${QXK::QXThread::delayCancel} .............................................. +//! @public @memberof QXThread bool QXThread_delayCancel(QXThread * const me) { - QF_CRIT_STAT_ - QF_CRIT_E_(); + QF_CRIT_STAT + QF_CRIT_ENTRY(); + QF_MEM_SYS(); bool wasArmed; if (me->super.super.temp.obj == QXK_PTR_CAST_(QMState*, &me->timeEvt)) { @@ -151,357 +150,167 @@ bool QXThread_delayCancel(QXThread * const me) { else { wasArmed = false; } - QF_CRIT_X_(); + QF_MEM_APP(); + QF_CRIT_EXIT(); return wasArmed; } -/*${QXK::QXThread::queueGet} ...............................................*/ -QEvt const * QXThread_queueGet(uint_fast16_t const nTicks) { - QF_CRIT_STAT_ - QF_CRIT_E_(); +//${QXK::QXThread::queueGet} ................................................. +//! @static @public @memberof QXThread +QEvt const * QXThread_queueGet(QTimeEvtCtr const nTicks) { + QF_CRIT_STAT + QF_CRIT_ENTRY(); + QF_MEM_SYS(); - QXThread * const thr = QXTHREAD_CAST_(QXK_attr_.curr); + QXThread * const thr = QXTHREAD_CAST_(QXK_priv_.curr); - /*! @pre this function must: - * - NOT be called from an ISR; - * - be called from an extended thread; - * - the thread must NOT be already blocked on any object. - */ - Q_REQUIRE_ID(500, (!QXK_ISR_CONTEXT_()) /* can't block inside an ISR */ - && (thr != (QXThread *)0) /* current thread must be extended */ - && (thr->super.super.temp.obj == (QMState *)0)); /* !blocked */ - /*! @pre also: the thread must NOT be holding a scheduler lock. */ - Q_REQUIRE_ID(501, QXK_attr_.lockHolder != thr->super.prio); + // precondition, this function: + // - must NOT be called from an ISR; + // - be called from an extended thread; + // - the thread must NOT be already blocked on any object. + Q_REQUIRE_INCRIT(500, (!QXK_ISR_CONTEXT_()) + && (thr != (QXThread *)0) + && (thr->super.super.temp.obj == (QMState *)0)); + // - the thread must NOT be holding a scheduler lock. + Q_REQUIRE_INCRIT(501, + QXK_priv_.lockHolder != (uint_fast8_t)thr->super.prio); - /* is the queue empty? */ + // is the queue empty? if (thr->super.eQueue.frontEvt == (QEvt *)0) { - /* remember the blocking object (the thread's queue) */ + // remember the blocking object (the thread's queue) thr->super.super.temp.obj = QXK_PTR_CAST_(QMState const*, &thr->super.eQueue); QXThread_teArm_(thr, (enum_t)QXK_TIMEOUT_SIG, nTicks); - QPSet_remove(&QF_readySet_, (uint_fast8_t)thr->super.prio); - (void)QXK_sched_(); /* schedule other threads */ - QF_CRIT_X_(); - QF_CRIT_EXIT_NOP(); /* BLOCK here */ + QPSet_remove(&QXK_priv_.readySet, (uint_fast8_t)thr->super.prio); + #ifndef Q_UNSAFE + QPSet_update_(&QXK_priv_.readySet, &QXK_priv_.readySet_dis); + #endif - QF_CRIT_E_(); - /* the blocking object must be this queue */ - Q_ASSERT_ID(510, thr->super.super.temp.obj + (void)QXK_sched_(); // schedule other threads + + QF_MEM_APP(); + QF_CRIT_EXIT(); + QF_CRIT_EXIT_NOP(); // BLOCK here + + // after unblocking... + QF_CRIT_ENTRY(); + QF_MEM_SYS(); + + // the blocking object must be this queue + Q_ASSERT_INCRIT(510, thr->super.super.temp.obj == QXK_PTR_CAST_(QMState const*, &thr->super.eQueue)); - thr->super.super.temp.obj = (QMState *)0; /* clear */ + thr->super.super.temp.obj = (QMState *)0; // clear } - /* is the queue not empty? */ + // is the queue not empty? QEvt const *e; if (thr->super.eQueue.frontEvt != (QEvt *)0) { - e = thr->super.eQueue.frontEvt; /* remove from the front */ + e = thr->super.eQueue.frontEvt; // remove from the front QEQueueCtr const nFree= thr->super.eQueue.nFree + 1U; - thr->super.eQueue.nFree = nFree; /* update the number of free */ + thr->super.eQueue.nFree = nFree; // update the # free - /* any events in the ring buffer? */ + // any events in the ring buffer? if (nFree <= thr->super.eQueue.end) { - /* remove event from the tail */ + // remove event from the tail thr->super.eQueue.frontEvt = thr->super.eQueue.ring[thr->super.eQueue.tail]; - if (thr->super.eQueue.tail == 0U) { /* need to wrap? */ - thr->super.eQueue.tail = thr->super.eQueue.end; /* wrap */ + if (thr->super.eQueue.tail == 0U) { // need to wrap? + thr->super.eQueue.tail = thr->super.eQueue.end; // wrap } --thr->super.eQueue.tail; - QS_BEGIN_NOCRIT_PRE_(QS_QF_ACTIVE_GET, thr->super.prio) - QS_TIME_PRE_(); /* timestamp */ - QS_SIG_PRE_(e->sig); /* the signal of this event */ - QS_OBJ_PRE_(&thr->super); /* this active object */ - QS_2U8_PRE_(e->poolId_, e->refCtr_); /* pool Id & ref Count */ - QS_EQC_PRE_(nFree); /* number of free entries */ - QS_END_NOCRIT_PRE_() + QS_BEGIN_PRE_(QS_QF_ACTIVE_GET, thr->super.prio) + QS_TIME_PRE_(); // timestamp + QS_SIG_PRE_(e->sig); // the signal of this event + QS_OBJ_PRE_(&thr->super); // this active object + QS_2U8_PRE_(QEvt_getPoolId_(e), e->refCtr_); // poolId & refCtr + QS_EQC_PRE_(nFree); // # free entries + QS_END_PRE_() } else { - thr->super.eQueue.frontEvt = (QEvt *)0; /* empty queue */ + thr->super.eQueue.frontEvt = (QEvt *)0; // empty queue - /* all entries in the queue must be free (+1 for fronEvt) */ - Q_ASSERT_ID(520, nFree == (thr->super.eQueue.end + 1U)); + // all entries in the queue must be free (+1 for fronEvt) + Q_ASSERT_INCRIT(520, nFree == (thr->super.eQueue.end + 1U)); - QS_BEGIN_NOCRIT_PRE_(QS_QF_ACTIVE_GET_LAST, thr->super.prio) - QS_TIME_PRE_(); /* timestamp */ - QS_SIG_PRE_(e->sig); /* the signal of this event */ - QS_OBJ_PRE_(&thr->super); /* this active object */ - QS_2U8_PRE_(e->poolId_, e->refCtr_); /* pool Id & ref Count */ - QS_END_NOCRIT_PRE_() + QS_BEGIN_PRE_(QS_QF_ACTIVE_GET_LAST, thr->super.prio) + QS_TIME_PRE_(); // timestamp + QS_SIG_PRE_(e->sig); // the signal of this event + QS_OBJ_PRE_(&thr->super); // this active object + QS_2U8_PRE_(QEvt_getPoolId_(e), e->refCtr_); // poolId & refCtr + QS_END_PRE_() } } - else { /* the queue is still empty -- the timeout must have fired */ + else { // the queue is still empty -- the timeout must have fired e = (QEvt *)0; } - QF_CRIT_X_(); + QF_MEM_APP(); + QF_CRIT_EXIT(); return e; - } -/*${QXK::QXThread::init_} ..................................................*/ -void QXThread_init_( - QHsm * const me, - void const * const par, - uint_fast8_t const qs_id) -{ - Q_UNUSED_PAR(me); - Q_UNUSED_PAR(par); - Q_UNUSED_PAR(qs_id); - - Q_ERROR_ID(110); -} - -/*${QXK::QXThread::dispatch_} ..............................................*/ -void QXThread_dispatch_( - QHsm * const me, - QEvt const * const e, - uint_fast8_t const qs_id) -{ - Q_UNUSED_PAR(me); - Q_UNUSED_PAR(e); - Q_UNUSED_PAR(qs_id); - - Q_ERROR_ID(120); -} - -/*${QXK::QXThread::start_} .................................................*/ -void QXThread_start_( - QActive * const me, - QPrioSpec const prioSpec, - QEvt const * * const qSto, - uint_fast16_t const qLen, - void * const stkSto, - uint_fast16_t const stkSize, - void const * const par) -{ - Q_UNUSED_PAR(par); - - /*! @pre this function must: - * - NOT be called from an ISR; - * - the stack storage must be provided; - * - the thread must be instantiated (see QXThread_ctor()) - * - preemption-threshold is NOT provided (because QXK kernel - * does not support preemption-threshold scheduling) - */ - Q_REQUIRE_ID(200, (!QXK_ISR_CONTEXT_()) /* don't call from an ISR! */ - && (stkSto != (void *)0) /* stack must be provided */ - && (stkSize != 0U) - && (me->super.state.act == (QActionHandler)0) - && ((prioSpec & 0xFF00U) == 0U)); - - /* is storage for the queue buffer provided? */ - if (qSto != (QEvt const **)0) { - QEQueue_init(&me->eQueue, qSto, qLen); - } - - /* extended thread constructor puts the thread handler in place of - * the top-most initial transition 'me->super.temp.act' - */ - QXK_stackInit_(me, me->super.temp.thr, stkSto, stkSize); - - /* the new thread is not blocked on any object */ - me->super.temp.obj = (QMState *)0; - - me->prio = (uint8_t)(prioSpec & 0xFFU); /* QF-priority of the AO */ - me->pthre = 0U; /* preemption-threshold NOT used */ - QActive_register_(me); /* make QF aware of this active object */ - - QF_CRIT_STAT_ - QF_CRIT_E_(); - /* extended-thread becomes ready immediately */ - QPSet_insert(&QF_readySet_, (uint_fast8_t)me->prio); - - /* see if this thread needs to be scheduled in case QXK is running */ - if (QXK_attr_.lockCeil <= QF_MAX_ACTIVE) { - (void)QXK_sched_(); /* schedule other threads */ - } - QF_CRIT_X_(); -} - -/*${QXK::QXThread::post_} ..................................................*/ -bool QXThread_post_( - QActive * const me, - QEvt const * const e, - uint_fast16_t const margin, - void const * const sender) -{ - #ifndef Q_SPY - Q_UNUSED_PAR(sender); - #endif - - QF_CRIT_STAT_ - QS_TEST_PROBE_DEF(&QXThread_post_) - - /* is it the private time event? */ - bool status; - if (e == &QXTHREAD_CAST_(me)->timeEvt.super) { - QF_CRIT_E_(); - /* the private time event is disarmed and not in any queue, - * so it is safe to change its signal. The signal of 0 means - * that the time event has expired. - */ - QXTHREAD_CAST_(me)->timeEvt.super.sig = 0U; - - QXThread_unblock_(QXTHREAD_CAST_(me)); - QF_CRIT_X_(); - - status = true; - } - /* is the event queue provided? */ - else if (me->eQueue.end != 0U) { - QEQueueCtr nFree; /* temporary to avoid UB for volatile access */ - - /*! @pre event pointer must be valid */ - Q_REQUIRE_ID(300, e != (QEvt *)0); - - QF_CRIT_E_(); - nFree = me->eQueue.nFree; /* get volatile into the temporary */ - - /* test-probe#1 for faking queue overflow */ - QS_TEST_PROBE_ID(1, - nFree = 0U; - ) - - if (margin == QF_NO_MARGIN) { - if (nFree > 0U) { - status = true; /* can post */ - } - else { - status = false; /* cannot post */ - Q_ERROR_CRIT_(310); /* must be able to post the event */ - } - } - else if (nFree > (QEQueueCtr)margin) { - status = true; /* can post */ - } - else { - status = false; /* cannot post, but don't assert */ - } - - /* is it a dynamic event? */ - if (e->poolId_ != 0U) { - QEvt_refCtr_inc_(e); /* increment the reference counter */ - } - - if (status) { /* can post the event? */ - - --nFree; /* one free entry just used up */ - me->eQueue.nFree = nFree; /* update the volatile */ - if (me->eQueue.nMin > nFree) { - me->eQueue.nMin = nFree; /* update minimum so far */ - } - - QS_BEGIN_NOCRIT_PRE_(QS_QF_ACTIVE_POST, me->prio) - QS_TIME_PRE_(); /* timestamp */ - QS_OBJ_PRE_(sender); /* the sender object */ - QS_SIG_PRE_(e->sig); /* the signal of the event */ - QS_OBJ_PRE_(me); /* this active object (recipient) */ - QS_2U8_PRE_(e->poolId_, e->refCtr_); /* pool Id & ref Count */ - QS_EQC_PRE_(nFree); /* number of free entries */ - QS_EQC_PRE_(me->eQueue.nMin); /* min number of free entries */ - QS_END_NOCRIT_PRE_() - - /* queue empty? */ - if (me->eQueue.frontEvt == (QEvt *)0) { - me->eQueue.frontEvt = e; /* deliver event directly */ - - /* is this thread blocked on the queue? */ - if (me->super.temp.obj - == QXK_PTR_CAST_(QMState*, &me->eQueue)) - { - (void)QXThread_teDisarm_(QXTHREAD_CAST_(me)); - QPSet_insert(&QF_readySet_, (uint_fast8_t)me->prio); - if (!QXK_ISR_CONTEXT_()) { - (void)QXK_sched_(); /* schedule other threads */ - } - } - } - /* queue is not empty, insert event into the ring-buffer */ - else { - /* insert event into the ring buffer (FIFO) */ - me->eQueue.ring[me->eQueue.head] = e; - - /* need to wrap the head counter? */ - if (me->eQueue.head == 0U) { - me->eQueue.head = me->eQueue.end; /* wrap around */ - } - --me->eQueue.head; /* advance the head (counter clockwise) */ - } - - QF_CRIT_X_(); - } - else { /* cannot post the event */ - - QS_BEGIN_NOCRIT_PRE_(QS_QF_ACTIVE_POST_ATTEMPT, me->prio) - QS_TIME_PRE_(); /* timestamp */ - QS_OBJ_PRE_(sender); /* the sender object */ - QS_SIG_PRE_(e->sig); /* the signal of the event */ - QS_OBJ_PRE_(me); /* this active object (recipient) */ - QS_2U8_PRE_(e->poolId_, e->refCtr_); /* pool Id & ref Count */ - QS_EQC_PRE_(nFree); /* number of free entries */ - QS_EQC_PRE_(margin); /* margin requested */ - QS_END_NOCRIT_PRE_() - - QF_CRIT_X_(); - - #if (QF_MAX_EPOOL > 0U) - QF_gc(e); /* recycle the event to avoid a leak */ - #endif - } - } - else { /* the queue is not available */ - #if (QF_MAX_EPOOL > 0U) - QF_gc(e); /* make sure the event is not leaked */ - #endif - status = false; - Q_ERROR_ID(320); /* this extended thread cannot accept events */ - } - - return status; -} - -/*${QXK::QXThread::postLIFO_} ..............................................*/ -void QXThread_postLIFO_( - QActive * const me, - QEvt const * const e) -{ - Q_UNUSED_PAR(me); - Q_UNUSED_PAR(e); - - Q_ERROR_ID(410); -} - -/*${QXK::QXThread::block_} .................................................*/ +//${QXK::QXThread::block_} ................................................... +//! @private @memberof QXThread void QXThread_block_(QXThread const * const me) { - /*! @pre the thread holding the lock cannot block! */ - Q_REQUIRE_ID(600, (QXK_attr_.lockHolder != me->super.prio)); + // NOTE: must be called IN a critical section - QPSet_remove(&QF_readySet_, (uint_fast8_t)me->super.prio); - (void)QXK_sched_(); /* schedule other threads */ + Q_REQUIRE_INCRIT(600, + QXK_priv_.lockHolder != (uint_fast8_t)me->super.prio); + + QPSet_remove(&QXK_priv_.readySet, (uint_fast8_t)me->super.prio); + #ifndef Q_UNSAFE + QPSet_update_(&QXK_priv_.readySet, &QXK_priv_.readySet_dis); + #endif + + (void)QXK_sched_(); // schedule other threads } -/*${QXK::QXThread::unblock_} ...............................................*/ +//${QXK::QXThread::unblock_} ................................................. +//! @private @memberof QXThread void QXThread_unblock_(QXThread const * const me) { - QPSet_insert(&QF_readySet_, (uint_fast8_t)me->super.prio); - if ((!QXK_ISR_CONTEXT_()) /* not inside ISR? */ - && (QActive_registry_[0] != (QActive *)0)) /* kernel started? */ + // NOTE: must be called IN a critical section + + QPSet_insert(&QXK_priv_.readySet, (uint_fast8_t)me->super.prio); + #ifndef Q_UNSAFE + QPSet_update_(&QXK_priv_.readySet, &QXK_priv_.readySet_dis); + #endif + + if ((!QXK_ISR_CONTEXT_()) // not inside ISR? + && (QActive_registry_[0] != (QActive *)0)) // kernel started? { - (void)QXK_sched_(); /* schedule other threads */ + (void)QXK_sched_(); // schedule other threads } } -/*${QXK::QXThread::teArm_} .................................................*/ +//${QXK::QXThread::timeout_} ................................................. +//! @private @memberof QXThread +void QXThread_timeout_(QActive * const act) { + // NOTE: must be called IN a critical section + + // the private time event is now disarmed and not in any queue, + // so it is safe to change its signal. The signal of 0 means + // that the time event has expired. + QXTHREAD_CAST_(act)->timeEvt.super.sig = 0U; + + QXThread_unblock_(QXTHREAD_CAST_(act)); +} + +//${QXK::QXThread::teArm_} ................................................... +//! @private @memberof QXThread void QXThread_teArm_(QXThread * const me, enum_t const sig, - uint_fast16_t const nTicks) + QTimeEvtCtr const nTicks) { - /*! @pre the time event must be unused */ - Q_REQUIRE_ID(700, me->timeEvt.ctr == 0U); + // NOTE: must be called IN a critical section + + // precondition: + // - the time event must be unused + Q_REQUIRE_INCRIT(700, me->timeEvt.ctr == 0U); me->timeEvt.super.sig = (QSignal)sig; @@ -509,26 +318,25 @@ void QXThread_teArm_(QXThread * const me, me->timeEvt.ctr = (QTimeEvtCtr)nTicks; me->timeEvt.interval = 0U; - /* is the time event unlinked? - * NOTE: For the duration of a single clock tick of the specified tick - * rate a time event can be disarmed and yet still linked in the list, - * because un-linking is performed exclusively in QTimeEvt_tick_(). - */ + // is the time event unlinked? + // NOTE: For the duration of a single clock tick of the specified tick + // rate a time event can be disarmed and yet still linked in the list, + // because un-linking is performed exclusively in QTimeEvt_tick_(). if ((me->timeEvt.super.refCtr_ & QTE_IS_LINKED) == 0U) { uint_fast8_t const tickRate = ((uint_fast8_t)me->timeEvt.super.refCtr_ & QTE_TICK_RATE); - Q_ASSERT_ID(710, tickRate < QF_MAX_TICK_RATE); + Q_ASSERT_INCRIT(710, tickRate < QF_MAX_TICK_RATE); + // mark as linked me->timeEvt.super.refCtr_ |= QTE_IS_LINKED; - /* The time event is initially inserted into the separate - * "freshly armed" list based on QTimeEvt_timeEvtHead_[tickRate].act. - * Only later, inside the QTimeEvt_tick_() function, the "freshly - * armed" list is appended to the main list of armed time events - * based on QTimeEvt_timeEvtHead_[tickRate].next. Again, this is - * to keep any changes to the main list exclusively inside - * QTimeEvt_tick_(). - */ + // The time event is initially inserted into the separate + // "freshly armed" list based on QTimeEvt_timeEvtHead_[tickRate].act. + // Only later, inside the QTimeEvt_tick_() function, the "freshly + // armed" list is appended to the main list of armed time events + // based on QTimeEvt_timeEvtHead_[tickRate].next. Again, this is + // to keep any changes to the main list exclusively inside + // QTimeEvt_tick_(). me->timeEvt.next = QXK_PTR_CAST_(QTimeEvt*, QTimeEvt_timeEvtHead_[tickRate].act); QTimeEvt_timeEvtHead_[tickRate].act = &me->timeEvt; @@ -536,18 +344,21 @@ void QXThread_teArm_(QXThread * const me, } } -/*${QXK::QXThread::teDisarm_} ..............................................*/ +//${QXK::QXThread::teDisarm_} ................................................ +//! @private @memberof QXThread bool QXThread_teDisarm_(QXThread * const me) { + // NOTE: must be called IN a critical section + bool wasArmed; - /* is the time evt running? */ + // is the time evt running? if (me->timeEvt.ctr != 0U) { wasArmed = true; - me->timeEvt.ctr = 0U; /* schedule removal from list */ + me->timeEvt.ctr = 0U; // schedule removal from list } - /* the time event was already automatically disarmed */ + // the time event was already automatically disarmed else { wasArmed = false; } return wasArmed; } -/*$enddef${QXK::QXThread} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +//$enddef${QXK::QXThread} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/test/et/et.c b/test/et/et.c new file mode 100644 index 00000000..6732b745 --- /dev/null +++ b/test/et/et.c @@ -0,0 +1,174 @@ +//============================================================================ +// ET: embedded test (super-simple embedded testing framework) +// GitHub: https://github.com/QuantumLeaps/Embedded-Test +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, . +// +// SPDX-License-Identifier: MIT +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the "Software"), +// to deal in the Software without restriction, including without limitation +// the rights to use, copy, modify, merge, publish, distribute, sublicense, +// and/or sell copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. +//============================================================================ +#include "et.h" // ET: embedded test + +//.......................................................................... +static void print_str(char const *str); +static void print_dec(unsigned const num); +static void print_summary(unsigned ok); +static void test_end(void); +static int str_cmp(char const *str1, char const *str2); + +static unsigned l_test_count; +static unsigned l_skip_count; +static unsigned l_skip_last; + +static char const *l_expect_assert_module; +static int l_expect_assert_label; + +//.......................................................................... +int main(int argc, char *argv[]) { + ET_onInit(argc, argv); + + print_str("\nET embedded test " ET_VERSION + ", https://github.com/QuantumLeaps/ET\n"); + print_str("---------------- group: "); + print_str(ET_group_); + print_str(" -----------------\n"); + + ET_run_(); + + test_end(); + print_summary(1U); + + ET_onExit(0); // success +} + +//.......................................................................... +int ET_test_(char const *title, int skip) { + test_end(); + ++l_test_count; + ET_onPrintChar('['); + print_dec(l_test_count); + print_str("] \""); + print_str(title); + print_str("\" "); + if (skip) { + ++l_skip_count; + } + else { + setup(); + ET_onPrintChar('.'); + } + l_skip_last = skip; + return skip == 0; +} +//.......................................................................... +static void test_end(void) { + if (l_expect_assert_module != (char const *)0) { + ET_fail("Expected Assertion didn't fire", + l_expect_assert_module, l_expect_assert_label); + } + else if (l_test_count > 0) { + if (l_skip_last) { + print_str(" SKIPPED\n"); + l_skip_last = 0; + } + else { + teardown(); + print_str(". PASSED\n"); + } + } +} +//.......................................................................... +void ET_fail(char const *cond, char const *group, int line) { + print_str(" FAILED\n--> "); + print_str(group); + ET_onPrintChar(':'); + print_dec(line); + ET_onPrintChar(' '); + print_str(cond); + ET_onPrintChar('\n'); + print_summary(0U); + + ET_onExit(-1); // failure +} +//.......................................................................... +void ET_expect_assert(char const *module, int label) { + l_expect_assert_module = module; + l_expect_assert_label = label; +} +//.......................................................................... +void ET_verify_assert_(char const *module, int label) { + if ((l_expect_assert_label == label) + && (str_cmp(module, l_expect_assert_module) == 0)) + { + l_expect_assert_module = (char const *)0; + test_end(); + print_str("Assertion (expected) --> Exiting\n"); + print_summary(1U); + + ET_onExit(0); // success + } + else { + ET_fail("Unexpected assertion", module, label); + } +} + +//.......................................................................... +static void print_summary(unsigned ok) { + print_str("------------ "); + print_dec(l_test_count); + print_str(" test(s), "); + print_dec(l_skip_count); + print_str(" skipped -------------\n"); + print_str(ok ? "OK\n" : "FAILED\n"); +} +//.......................................................................... +static void print_str(char const *str) { + for (; *str != '\0'; ++str) { + ET_onPrintChar(*str); + } +} + +//.......................................................................... +static void print_dec(unsigned const num) { + // find power of 10 of the first decimal digit of the number + unsigned pwr10 = 1U; + for (; num > (pwr10 * 9U); pwr10 *= 10U) { + } + // print the decimal digits of the number... + do { + ET_onPrintChar((char)('0' + ((num / pwr10) % 10U))); + pwr10 /= 10U; + } while (pwr10 != 0U); +} + +//.......................................................................... +static int str_cmp(char const *str1, char const *str2) { + while (*str1 == *str2++) { + if (*str1++ == '\0') { + return 0; + } + } + --str2; + return *(unsigned char *)str1 - *(unsigned char *)str2; +} diff --git a/test/et/et.h b/test/et/et.h new file mode 100644 index 00000000..bed2eeed --- /dev/null +++ b/test/et/et.h @@ -0,0 +1,92 @@ +//============================================================================ +// ET: embedded test (super-simple embedded testing framework) +// GitHub: https://github.com/QuantumLeaps/Embedded-Test +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, . +// +// SPDX-License-Identifier: MIT +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the "Software"), +// to deal in the Software without restriction, including without limitation +// the rights to use, copy, modify, merge, publish, distribute, sublicense, +// and/or sell copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. +//============================================================================ +#ifndef ET_H_ +#define ET_H_ + +// Embedded Test (ET) version +#define ET_VERSION "2.0.0" + +//! macro to define a test group +#define TEST_GROUP(name_) \ + char const ET_group_[] = name_; \ + void ET_run_(void) + +// macro to start a new test +#define TEST(title_) \ + if (ET_test_(title_, 0)) + +// macro to skip a test +#define SKIP_TEST(title_) \ + if (ET_test_(title_, 1)) + +//! macro to verify a test expectation +#define VERIFY(cond_) \ + ((cond_) ? (void)0 : ET_fail(#cond_, &ET_group_[0], __LINE__)) + +#define VERIFY_ASSERT(module_, label_) \ + ET_verify_assert_((module_), (label_)) + +//! macro to force a failure of a test +#define FAIL(note_) \ + (ET_fail(note_, &ET_group_[0], __LINE__)) + +#ifndef ARRAY_NELEM +//! convenience macro to provide the number of elements in the array a_ +#define ARRAY_NELEM(a_) (sizeof(a_) / sizeof((a_)[0])) +#endif // ARRAY_NELEM + +#ifdef __cplusplus +extern "C" { +#endif + +void setup(void); //!< called right before each test +void teardown(void); //!< called right after each test + +// callback functions to be implemented in the ET board support packages +void ET_onInit(int argc, char *argv[]); +void ET_onPrintChar(char const ch); +void ET_onExit(int err); + +// public helpers +void ET_fail(char const *cond, char const *group, int line); +void ET_expect_assert(char const *module, int label); +void ET_verify_assert_(char const *module, int label); + +// private helpers +void ET_run_(void); +int ET_test_(char const *title, int skip); +extern char const ET_group_[]; + +#ifdef __cplusplus +} +#endif + +#endif // ET_H_ diff --git a/test/et/et_host.c b/test/et/et_host.c new file mode 100644 index 00000000..5b6af46f --- /dev/null +++ b/test/et/et_host.c @@ -0,0 +1,48 @@ +//============================================================================ +// Embedded Test (ET) implementation for host computers (Windows, Linux, macOS) +// GitHub: https://github.com/QuantumLeaps/Embedded-Test +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, . +// +// SPDX-License-Identifier: MIT +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the "Software"), +// to deal in the Software without restriction, including without limitation +// the rights to use, copy, modify, merge, publish, distribute, sublicense, +// and/or sell copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. +//============================================================================ +#include "et.h" // ET: embedded test + +#include // for fputc() and stdout +#include // for exit() + +//.......................................................................... +void ET_onInit(int argc, char *argv[]) { + (void)argc; + (void)argv; +} +//.......................................................................... +void ET_onPrintChar(char const ch) { + fputc(ch, stdout); +} +//.......................................................................... +void ET_onExit(int err) { + exit(err); +} diff --git a/examples/workstation/qhsmtst/Makefile b/test/qf/qequeue/Makefile similarity index 64% rename from examples/workstation/qhsmtst/Makefile rename to test/qf/qequeue/Makefile index ae6633dc..96c9fa9f 100644 --- a/examples/workstation/qhsmtst/Makefile +++ b/test/qf/qequeue/Makefile @@ -1,7 +1,7 @@ ############################################################################## -# Product: Makefile for QP/C for Windows and POSIX *HOSTS* -# Last updated for version 7.2.0 -# Last updated on 2022-11-13 +# Product: Makefile for Embedded Test (ET) for Windows *HOST* +# Last Updated for Version: 7.3.0 +# Date of the Last Update: 2023-06-30 # # Q u a n t u m L e a P s # ------------------------ @@ -33,38 +33,39 @@ ############################################################################## # # examples of invoking this Makefile: -# building configurations: Debug (default), Release, and Spy -# make -# make CONF=rel -# make CONF=spy +# make # make and run the Python tests in the current directory +# make TESTS=test*.py # make and run the selected tests in the curr. dir. +# make HOST=localhost:7705 # connect to host:port +# make norun # only make but not run the tests # make clean # cleanup the build -# make CONF=spy clean # cleanup the build +# make debug # only run tests in DEBUG mode # # NOTE: # To use this Makefile on Windows, you will need the GNU make utility, which # is included in the QTools collection for Windows, see: -# http://sourceforge.net/projects/qpc/files/QTools/ +# https://github.com/QuantumLeaps/qtools # #----------------------------------------------------------------------------- # project name: -# -PROJECT := qhsmtst +PROJECT := test #----------------------------------------------------------------------------- # project directories: # +QPC := ../../.. +ET := ../../et # list of all source directories used by this project VPATH := . \ + $(QPC)/src/qf \ + $(QPC)/src/qs \ + $(ET) # list of all include directories needed by this project INCLUDES := -I. \ - -# location of the QP/C framework (if not provided in an env. variable) -ifeq ($(QPC),) -QPC := ../../.. -endif + -I$(QPC)/include \ + -I$(ET) #----------------------------------------------------------------------------- # project files: @@ -72,8 +73,16 @@ endif # C source files... C_SRCS := \ - main.c \ - qhsmtst.c + qep_hsm.c \ + qf_act.c \ + qf_actq.c \ + qf_qact.c \ + qf_qeq.c \ + qs.c \ + qs_rx.c \ + test.c \ + et.c \ + et_host.c # C++ source files... CPP_SRCS := @@ -82,69 +91,11 @@ LIB_DIRS := LIBS := # defines... -# QP_API_VERSION controls the QP API compatibility; 9999 means the latest API -DEFINES := -DQP_API_VERSION=9999 - -ifeq (,$(CONF)) - CONF := dbg -endif - -#----------------------------------------------------------------------------- -# add QP/C framework: -# -C_SRCS += \ - qep_hsm.c \ - qep_msm.c \ - qf_act.c \ - qf_actq.c \ - qf_defer.c \ - qf_dyn.c \ - qf_mem.c \ - qf_ps.c \ - qf_qact.c \ - qf_qeq.c \ - qf_qmact.c \ - qf_time.c \ - qf_port.c - -QS_SRCS := \ - qs.c \ - qs_64bit.c \ - qs_rx.c \ - qs_fp.c \ - qs_port.c - -ifeq ($(OS),Windows_NT) - -# NOTE: -# For Windows hosts, you can choose: -# - the single-threaded QP/C port (win32-qv) or -# - the multithreaded QP/C port (win32). -# -QP_PORT_DIR := $(QPC)/ports/win32-qv -#QP_PORT_DIR := $(QPC)/ports/win32 -LIBS += -lws2_32 - -else - -# NOTE: -# For POSIX hosts (Linux, MacOS), you can choose: -# - the single-threaded QP/C port (win32-qv) or -# - the multithreaded QP/C port (win32). -# -QP_PORT_DIR := $(QPC)/ports/posix-qv -#QP_PORT_DIR := $(QPC)/ports/posix - -LIBS += -lpthread - -endif +DEFINES := -DQ_SPY #============================================================================ # Typically you should not need to change anything below this line -VPATH += $(QPC)/src/qf $(QP_PORT_DIR) -INCLUDES += -I$(QPC)/include -I$(QP_PORT_DIR) - #----------------------------------------------------------------------------- # GNU toolset: # @@ -176,52 +127,27 @@ else endif #----------------------------------------------------------------------------- -# build configurations... - -ifeq (rel, $(CONF)) # Release configuration .................................. - -BIN_DIR := build_rel -# gcc options: -CFLAGS = -c -O3 -fno-pie -std=c11 -pedantic -Wall -Wextra -W \ - $(INCLUDES) $(DEFINES) -DNDEBUG - -CPPFLAGS = -c -O3 -fno-pie -std=c++11 -pedantic -Wall -Wextra \ - -fno-rtti -fno-exceptions \ - $(INCLUDES) $(DEFINES) -DNDEBUG - -else ifeq (spy, $(CONF)) # Spy configuration ................................ - -BIN_DIR := build_spy - -C_SRCS += $(QS_SRCS) -VPATH += $(QPC)/src/qs - -# gcc options: -CFLAGS = -c -g -O -fno-pie -std=c11 -pedantic -Wall -Wextra -W \ - $(INCLUDES) $(DEFINES) -DQ_SPY - -CPPFLAGS = -c -g -O -fno-pie -std=c++11 -pedantic -Wall -Wextra \ - -fno-rtti -fno-exceptions \ - $(INCLUDES) $(DEFINES) -DQ_SPY - -else # default Debug configuration ......................................... +# build options... BIN_DIR := build -# gcc options: -CFLAGS = -c -g -O -fno-pie -std=c11 -pedantic -Wall -Wextra -W \ - $(INCLUDES) $(DEFINES) +CFLAGS := -c -g -O -fno-pie -std=c11 -pedantic -Wall -Wextra -W \ + $(INCLUDES) $(DEFINES) -DQ_HOST -CPPFLAGS = -c -g -O -fno-pie -std=c++11 -pedantic -Wall -Wextra \ +CPPFLAGS := -c -g -O -fno-pie -std=c++11 -pedantic -Wall -Wextra \ -fno-rtti -fno-exceptions \ - $(INCLUDES) $(DEFINES) - -endif # ..................................................................... + $(INCLUDES) $(DEFINES) -DQ_HOST ifndef GCC_OLD LINKFLAGS := -no-pie endif +ifdef GCOV + CFLAGS += -fprofile-arcs -ftest-coverage + CPPFLAGS += -fprofile-arcs -ftest-coverage + LINKFLAGS += -lgcov --coverage +endif + #----------------------------------------------------------------------------- C_OBJS := $(patsubst %.c,%.o, $(C_SRCS)) CPP_OBJS := $(patsubst %.cpp,%.o, $(CPP_SRCS)) @@ -236,20 +162,28 @@ CPP_DEPS_EXT := $(patsubst %.o,%.d, $(CPP_OBJS_EXT)) # rules # -.PHONY: clean show +.PHONY : norun clean show -all: $(TARGET_EXE) +ifeq ($(MAKECMDGOALS),norun) +all : $(TARGET_EXE) +norun : all +else +all : $(TARGET_EXE) run +endif $(TARGET_EXE) : $(C_OBJS_EXT) $(CPP_OBJS_EXT) - $(CC) $(CFLAGS) $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o + $(CC) $(CFLAGS) $(QPC)/src/qs/qstamp.c -o $(BIN_DIR)/qstamp.o $(LINK) $(LINKFLAGS) $(LIB_DIRS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) -$(BIN_DIR)/%.d : %.c - $(CC) -MM -MT $(@:.d=.o) $(CFLAGS) $< > $@ +run : $(TARGET_EXE) + $(TARGET_EXE) $(BIN_DIR)/%.d : %.cpp $(CPP) -MM -MT $(@:.d=.o) $(CPPFLAGS) $< > $@ +$(BIN_DIR)/%.d : %.c + $(CC) -MM -MT $(@:.d=.o) $(CFLAGS) $< > $@ + $(BIN_DIR)/%.o : %.c $(CC) $(CFLAGS) $< -o $@ @@ -269,9 +203,7 @@ endif endif clean : - -$(RM) $(BIN_DIR)/*.o \ - $(BIN_DIR)/*.d \ - $(TARGET_EXE) + -$(RM) $(BIN_DIR)/*.* show : @echo PROJECT = $(PROJECT) diff --git a/test/qf/qequeue/qp_port.h b/test/qf/qequeue/qp_port.h new file mode 100644 index 00000000..6fb6b29b --- /dev/null +++ b/test/qf/qequeue/qp_port.h @@ -0,0 +1,130 @@ +//============================================================================ +// QP/C Real-Time Embedded Framework (RTEF) +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +//============================================================================ +//! +//! @date Last updated on: 2023-08-19 +//! @version Last updated for: @ref qpc_7_3_0 +//! +//! @file +//! @brief QP/C "port" for Embedded Test, Win32 with GNU or VisualC++ +//! +#ifndef QP_PORT_H_ +#define QP_PORT_H_ + +#include // Exact-width types. WG14/N843 C99 Standard +#include // Boolean type. WG14/N843 C99 Standard + +//! no-return function specifier +#ifdef __GNUC__ + + //! no-return function specifier (GCC-ARM compiler) + #define Q_NORETURN __attribute__ ((noreturn)) void + +#elif (defined _MSC_VER) + #ifdef __cplusplus + // no-return function specifier (Microsoft Visual Studio C++ compiler) + #define Q_NORETURN [[ noreturn ]] void + #else + // no-return function specifier C11 + #define Q_NORETURN _Noreturn void + #endif + + // This is the case where QP/C is compiled by the Microsoft Visual C++ + // compiler in the C++ mode, which can happen when qep_port.h is included + // in a C++ module, or the compilation is forced to C++ by the option /TP. + // + // The following pragma suppresses the level-4 C++ warnings C4510, C4512, + // and C4610, which warn that default constructors and assignment operators + // could not be generated for structures QMState and QMTranActTable. + // + // The QP/C source code cannot be changed to avoid these C++ warnings + // because the structures QMState and QMTranActTable must remain PODs + // (Plain Old Datatypes) to be initializable statically with constant + // initializers. + // + #pragma warning (disable: 4510 4512 4610) + +#endif + +// event queue and thread types +#define QACTIVE_EQUEUE_TYPE QEQueue +// QACTIVE_OS_OBJ_TYPE not used in this port +// QACTIVE_THREAD_TYPE not used in this port + +// The maximum number of active objects in the application +#define QF_MAX_ACTIVE 64U + +// The number of system clock tick rates +#define QF_MAX_TICK_RATE 2U + +// Activate the QF QActive_stop() API +#define QACTIVE_CAN_STOP 1 + +// QF interrupt disable/enable +#define QF_INT_DISABLE() ((void)0) +#define QF_INT_ENABLE() ((void)0) + +// QUIT critical section +#define QF_CRIT_STAT +#define QF_CRIT_ENTRY() QF_INT_DISABLE() +#define QF_CRIT_EXIT() QF_INT_ENABLE() + +// QF_LOG2 not defined -- use the internal LOG2() implementation + +// include files ------------------------------------------------------------- +#include "qequeue.h" // Win32-QV needs the native event-queue +#include "qmpool.h" // Win32-QV needs the native memory-pool +#include "qp.h" // QP platform-independent public interface + +//========================================================================== +// interface used only inside QP implementation, but not in applications +#ifdef QP_IMPL + + // ET scheduler locking (not used) + #define QF_SCHED_STAT_ + #define QF_SCHED_LOCK_(dummy) ((void)0) + #define QF_SCHED_UNLOCK_() ((void)0) + + // native event queue operations + #define QACTIVE_EQUEUE_WAIT_(me_) \ + Q_ASSERT_INCRIT(302, (me_)->eQueue.frontEvt != (QEvt *)0) + #define QACTIVE_EQUEUE_SIGNAL_(me_) ((void)0) + + // native QF event pool operations + #define QF_EPOOL_TYPE_ QMPool + #define QF_EPOOL_INIT_(p_, poolSto_, poolSize_, evtSize_) \ + (QMPool_init(&(p_), (poolSto_), (poolSize_), (evtSize_))) + #define QF_EPOOL_EVENT_SIZE_(p_) ((uint_fast16_t)(p_).blockSize) + #define QF_EPOOL_GET_(p_, e_, m_, qs_id_) \ + ((e_) = (QEvt *)QMPool_get(&(p_), (m_), (qs_id_))) + #define QF_EPOOL_PUT_(p_, e_, qs_id_) \ + (QMPool_put(&(p_), (e_), (qs_id_))) + +#endif // QP_IMPL + +#ifdef _MSC_VER + #pragma warning (default: 4510 4512 4610) +#endif + +#endif // QP_PORT_H_ diff --git a/test/qf/qequeue/qs_port.h b/test/qf/qequeue/qs_port.h new file mode 100644 index 00000000..d0460af6 --- /dev/null +++ b/test/qf/qequeue/qs_port.h @@ -0,0 +1,61 @@ +//============================================================================ +// QP/C Real-Time Embedded Framework (RTEF) +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +//============================================================================ +//! @date Last updated on: 2023-08-16 +//! @version Last updated for: @ref qpc_7_3_0 +//! +//! @file +//! @brief QS/C port to Win32 with GNU or Visual C++ compilers +//! +#ifndef QS_PORT_H_ +#define QS_PORT_H_ + +#define QS_CTR_SIZE 4U +#define QS_TIME_SIZE 4U + +#ifdef _WIN64 // 64-bit architecture? + #define QS_OBJ_PTR_SIZE 8U + #define QS_FUN_PTR_SIZE 8U +#else // 32-bit architecture + #define QS_OBJ_PTR_SIZE 4U + #define QS_FUN_PTR_SIZE 4U +#endif + +void QS_output(void); // handle the QS output +void QS_rx_input(void); // handle the QS-RX input + +//============================================================================ +// NOTE: QS might be used with or without other QP components, in which +// case the separate definitions of the macros QF_CRIT_STAT, QF_CRIT_ENTRY(), +// and QF_CRIT_EXIT() are needed. In this port QS is configured to be used +// with the other QP component, by simply including "qp_port.h" +//*before* "qs.h". +#ifndef QP_PORT_H_ +#include "qp_port.h" // use QS with QF +#endif + +#include "qs.h" // QS platform-independent public interface + +#endif // QS_PORT_H_ + diff --git a/test/qf/qequeue/test.c b/test/qf/qequeue/test.c new file mode 100644 index 00000000..a5ab4228 --- /dev/null +++ b/test/qf/qequeue/test.c @@ -0,0 +1,131 @@ +#include "et.h" // Embedded Test (ET) + +// includes for the CUT... +#include "qp_port.h" // QP port +#include "qsafe.h" // QP Functional Safety (FuSa) System +#ifdef Q_SPY // software tracing enabled? +#include "qs_port.h" // QS/C port from the port directory +#else +#include "qs_dummy.h" // QS/C dummy (inactive) interface +#endif + +enum { QUEUE_SIZE = 10 }; + + +void setup(void) { +} + +void teardown(void) { +} + +//static QEvt const *queBuf[QUEUE_SIZE]; +static QEQueue queue; + +static QEvt const evt1 = QEVT_INITIALIZER(1); +static QEvt const evt2 = QEVT_INITIALIZER(2); + +// test group -------------------------------------------------------------- +TEST_GROUP("QEQueue") { + +TEST("new no-buffer queue has 1 free") { + QEQueue_init(&queue, (QEvt const **)0, 0U); + VERIFY(1U == QEQueue_getNFree(&queue)); +} + +TEST("no-buffer queue can hold at least 1") { + QEQueue_post(&queue, &evt1, QF_NO_MARGIN, 0U); + VERIFY(0U == QEQueue_getNFree(&queue)); + QEvt const *e = QEQueue_get(&queue, 0U); + VERIFY(&evt1 == e); + VERIFY(1U == QEQueue_getNFree(&queue)); +} + +TEST("no-buffer queue can hold only 1 (expected assertion)") { + QEQueue_post(&queue, &evt1, QF_NO_MARGIN, 0U); + ET_expect_assert("qf_qeq", 210); + VERIFY(false == QEQueue_post(&queue, &evt2, QF_NO_MARGIN, 0U)); + VERIFY(0U == QEQueue_getNFree(&queue)); +} + +} // TEST_GROUP() + +// ========================================================================= +// dependencies for the CUT ... + +//.......................................................................... +void QF_poolInit(void * const poolSto, uint_fast32_t const poolSize, + uint_fast16_t const evtSize) +{ + (void)poolSto; + (void)poolSize; + (void)evtSize; +} +//.......................................................................... +uint_fast16_t QF_poolGetMaxBlockSize(void) { + return 0U; +} +//.......................................................................... +void QActive_publish_(QEvt const * const e, + void const * const sender, uint_fast8_t const qs_id) +{ + (void)e; + (void)sender; + (void)qs_id; +} +//.......................................................................... +void QTimeEvt_tick_(uint_fast8_t const tickRate, void const * const sender) { + (void)tickRate; + (void)sender; +} +//.......................................................................... +QEvt *QF_newX_(uint_fast16_t const evtSize, + uint_fast16_t const margin, enum_t const sig) +{ + (void)evtSize; + (void)margin; + (void)sig; + + return (QEvt *)0; +} +//.......................................................................... +//! @static @public @memberof QF +void QF_gc(QEvt const * const e) { + (void)e; +} +//.......................................................................... +//! @static @private @memberof QF +QActive *QActive_registry_[QF_MAX_ACTIVE + 1U]; + +//.......................................................................... +Q_NORETURN Q_onError(char const * const module, int_t const location) { + VERIFY_ASSERT(module, location); + for (;;) { // explicitly make it "noreturn" + } +} + +//-------------------------------------------------------------------------- +#ifdef Q_SPY + +void QS_onCleanup(void) { +} +//.......................................................................... +void QS_onReset(void) { +} +//.......................................................................... +void QS_onFlush(void) { +} +//.......................................................................... +QSTimeCtr QS_onGetTime(void) { + return (QSTimeCtr)0U; +} +//.......................................................................... +void QS_onCommand(uint8_t cmdId, uint32_t param1, + uint32_t param2, uint32_t param3) +{ + (void)cmdId; + (void)param1; + (void)param2; + (void)param3; +} + +#endif // Q_SPY diff --git a/test/qk/test_sched/bsp.h b/test/qk/test_sched/bsp.h index a4caa37e..cc41b3d0 100644 --- a/test/qk/test_sched/bsp.h +++ b/test/qk/test_sched/bsp.h @@ -1,43 +1,41 @@ -/*============================================================================ -* Product: BSP for system-testing -* Last updated for version 7.2.0 -* Last updated on 2022-12-13 -* -* Q u a n t u m L e a P s -* ------------------------ -* Modern Embedded Software -* -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* -* -============================================================================*/ +//============================================================================ +// Product: BSP for system-testing +// Last updated for version 7.2.0 +// Last updated on 2022-12-13 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +//============================================================================ #ifndef BSP_H_ #define BSP_H_ void BSP_init(void); void BSP_terminate(int16_t result); -/* for testing... */ +// for testing... void BSP_trace(QActive const *thr, char const *msg); void BSP_wait4PB1(void); void BSP_ledOn(void); @@ -55,10 +53,9 @@ enum TestSignals { TEST1_SIG, TEST2_SIG, TEST3_SIG, - MAX_PUB_SIG, /* the last published signal */ + MAX_PUB_SIG, // the last published signal - MAX_SIG /* the last signal */ + MAX_SIG // the last signal }; -#endif /* BSP_H_ */ - +#endif // BSP_H_ diff --git a/test/qk/test_sched/bsp_efm32.c b/test/qk/test_sched/bsp_efm32.c deleted file mode 100644 index 51743672..00000000 --- a/test/qk/test_sched/bsp_efm32.c +++ /dev/null @@ -1,376 +0,0 @@ -/*============================================================================ -* Product: BSP for system-testing of QK kernel, EFM32-SLSTK3401A board -* Last updated for version 7.2.0 -* Last updated on 2022-12-13 -* -* Q u a n t u m L e a P s -* ------------------------ -* Modern Embedded Software -* -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* -* -============================================================================*/ -#include "qpc.h" -#include "bsp.h" - -#include "em_device.h" /* the device specific header (SiLabs) */ -#include "em_cmu.h" /* Clock Management Unit (SiLabs) */ -#include "em_gpio.h" /* GPIO (SiLabs) */ -#include "em_usart.h" /* USART (SiLabs) */ -/* add other drivers if necessary... */ - -Q_DEFINE_THIS_FILE - -/* ISRs defined in this BSP ------------------------------------------------*/ -void SysTick_Handler(void); -void GPIO_EVEN_IRQHandler(void); - -/* Local-scope objects -----------------------------------------------------*/ -#define LED_PORT gpioPortF -#define LED0_PIN 4 -#define LED1_PIN 5 - -#define PB_PORT gpioPortF -#define PB0_PIN 6 -#define PB1_PIN 7 - -#ifdef Q_SPY - - /* QSpy source IDs */ - static QSpyId const l_SysTick_Handler = { 100U }; - static QSpyId const l_test_ISR = { 101U }; - - enum AppRecords { /* application-specific trace records */ - CONTEXT_SW = QS_USER1, - TRACE_MSG - }; - -#endif - -/*..........................................................................*/ -void SysTick_Handler(void); /* prototype */ -void SysTick_Handler(void) { - QK_ISR_ENTRY(); /* inform QK kernel about entering an ISR */ - - /* process time events for rate 0 */ - QTIMEEVT_TICK_X(0U, &l_SysTick_Handler); - //QACTIVE_POST(the_Ticker0, 0, &l_SysTick_Handler); - - QK_ISR_EXIT(); /* inform QK kernel about exiting an ISR */ -} -/*..........................................................................*/ -void GPIO_EVEN_IRQHandler(void); /* prototype */ -void GPIO_EVEN_IRQHandler(void) { /* for testing, NOTE03 */ - QK_ISR_ENTRY(); /* inform QK kernel about entering an ISR */ - - /* for testing... */ - static QEvt const t1 = { TEST1_SIG, 0U, 0U }; - QACTIVE_PUBLISH(&t1, &l_test_ISR); - - QK_ISR_EXIT(); /* inform QK kernel about exiting an ISR */ -} - -/*..........................................................................*/ -/* MPU setup for EFM32PG1B200F256GM48 MCU */ -static void EFM32PG182_MPU_setup(void) { - /* The following MPU configuration contains the general EFM32PG1 memory - * map described in the EFM32PG1 Data Sheet Figure 3.2. EFM32PG1 Memory Map - * - * Please note that the actual STM32 MCUs provide much less Flash and SRAM - * than the maximums configured here. This means that actual MCUs have - * unmapped memory regions (e.g., beyond the actual SRAM). Attempts to - * access these regions causes the HardFault exception, which is the - * desired behavior. - */ - static struct { - uint32_t rbar; - uint32_t rasr; - } const mpu_setup[] = { - - { /* region #0: Flash: base=0x0000'0000, size=512M=2^(28+1) */ - 0x00000000U /* base address */ - | MPU_RBAR_VALID_Msk /* valid region */ - | (MPU_RBAR_REGION_Msk & 0U), /* region #0 */ - (28U << MPU_RASR_SIZE_Pos) /* 2^(18+1) region */ - | (0x6U << MPU_RASR_AP_Pos) /* PA:ro/UA:ro */ - | (1U << MPU_RASR_C_Pos) /* C=1 */ - | MPU_RASR_ENABLE_Msk /* region enable */ - }, - - { /* region #1: SRAM: base=0x2000'0000, size=512M=2^(28+1) */ - 0x20000000U /* base address */ - | MPU_RBAR_VALID_Msk /* valid region */ - | (MPU_RBAR_REGION_Msk & 1U), /* region #1 */ - (28U << MPU_RASR_SIZE_Pos) /* 2^(28+1) region */ - | (0x3U << MPU_RASR_AP_Pos) /* PA:rw/UA:rw */ - | (1U << MPU_RASR_XN_Pos) /* XN=1 */ - | (1U << MPU_RASR_S_Pos) /* S=1 */ - | (1U << MPU_RASR_C_Pos) /* C=1 */ - | MPU_RASR_ENABLE_Msk /* region enable */ - }, - - /* region #3: (not configured) */ - { MPU_RBAR_VALID_Msk | (MPU_RBAR_REGION_Msk & 2U), 0U }, - - { /* region #3: Peripherals: base=0x4000'0000, size=512M=2^(28+1) */ - 0x40000000U /* base address */ - | MPU_RBAR_VALID_Msk /* valid region */ - | (MPU_RBAR_REGION_Msk & 3U), /* region #3 */ - (28U << MPU_RASR_SIZE_Pos) /* 2^(28+1) region */ - | (0x3U << MPU_RASR_AP_Pos) /* PA:rw/UA:rw */ - | (1U << MPU_RASR_XN_Pos) /* XN=1 */ - | (1U << MPU_RASR_S_Pos) /* S=1 */ - | (1U << MPU_RASR_B_Pos) /* B=1 */ - | MPU_RASR_ENABLE_Msk /* region enable */ - }, - - { /* region #4: Priv. Periph: base=0xE000'0000, size=512M=2^(28+1) */ - 0xE0000000U /* base address */ - | MPU_RBAR_VALID_Msk /* valid region */ - | (MPU_RBAR_REGION_Msk & 4U), /* region #4 */ - (28U << MPU_RASR_SIZE_Pos) /* 2^(28+1) region */ - | (0x3U << MPU_RASR_AP_Pos) /* PA:rw/UA:rw */ - | (1U << MPU_RASR_XN_Pos) /* XN=1 */ - | (1U << MPU_RASR_S_Pos) /* S=1 */ - | (1U << MPU_RASR_B_Pos) /* B=1 */ - | MPU_RASR_ENABLE_Msk /* region enable */ - }, - - { /* region #5: Ext RAM: base=0x6000'0000, size=1G=2^(29+1) */ - 0x60000000U /* base address */ - | MPU_RBAR_VALID_Msk /* valid region */ - | (MPU_RBAR_REGION_Msk & 5U), /* region #5 */ - (29U << MPU_RASR_SIZE_Pos) /* 2^(28+1) region */ - | (0x3U << MPU_RASR_AP_Pos) /* PA:rw/UA:rw */ - | (1U << MPU_RASR_XN_Pos) /* XN=1 */ - | (1U << MPU_RASR_S_Pos) /* S=1 */ - | (1U << MPU_RASR_B_Pos) /* B=1 */ - | MPU_RASR_ENABLE_Msk /* region enable */ - }, - - { /* region #6: Ext Dev: base=0xA000'0000, size=1G=2^(29+1) */ - 0xA0000000U /* base address */ - | MPU_RBAR_VALID_Msk /* valid region */ - | (MPU_RBAR_REGION_Msk & 6U), /* region #6 */ - (29U << MPU_RASR_SIZE_Pos) /* 2^(28+1) region */ - | (0x3U << MPU_RASR_AP_Pos) /* PA:rw/UA:rw */ - | (1U << MPU_RASR_XN_Pos) /* XN=1 */ - | (1U << MPU_RASR_S_Pos) /* S=1 */ - | (1U << MPU_RASR_B_Pos) /* B=1 */ - | MPU_RASR_ENABLE_Msk /* region enable */ - }, - - { /* region #7: NULL-pointer: base=0x000'0000, size=256B, NOTE0 */ - 0x00000000U /* base address */ - | MPU_RBAR_VALID_Msk /* valid region */ - | (MPU_RBAR_REGION_Msk & 7U), /* region #7 */ - (7U << MPU_RASR_SIZE_Pos) /* 2^(7+1)=256B region */ - | (0x0U << MPU_RASR_AP_Pos) /* PA:na/UA:na */ - | (1U << MPU_RASR_XN_Pos) /* XN=1 */ - | MPU_RASR_ENABLE_Msk /* region enable */ - }, - }; - - /* enable the MemManage_Handler for MPU exception */ - SCB->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk; - - __DSB(); - MPU->CTRL = 0U; /* disable the MPU */ - for (uint_fast8_t n = 0U; n < Q_DIM(mpu_setup); ++n) { - MPU->RBAR = mpu_setup[n].rbar; - MPU->RASR = mpu_setup[n].rasr; - } - MPU->CTRL = MPU_CTRL_ENABLE_Msk; /* enable the MPU */ - __ISB(); - __DSB(); -} - -/*..........................................................................*/ -void BSP_init(void) { - /* setup the MPU... */ - EFM32PG182_MPU_setup(); - - /* NOTE: SystemInit() has been already called from the startup code - * but SystemCoreClock needs to be updated - */ - SystemCoreClockUpdate(); - - /* NOTE: The VFP (hardware Floating Point) unit is configured by QK */ - - /* enable clock for to the peripherals used by this application... */ - CMU_ClockEnable(cmuClock_HFPER, true); - CMU_ClockEnable(cmuClock_GPIO, true); - CMU_ClockEnable(cmuClock_HFPER, true); - CMU_ClockEnable(cmuClock_GPIO, true); - - /* configure the LEDs */ - GPIO_PinModeSet(LED_PORT, LED0_PIN, gpioModePushPull, 0); - GPIO_PinModeSet(LED_PORT, LED1_PIN, gpioModePushPull, 0); - GPIO_PinOutClear(LED_PORT, LED0_PIN); - GPIO_PinOutClear(LED_PORT, LED1_PIN); - - /* configure the Buttons */ - GPIO_PinModeSet(PB_PORT, PB0_PIN, gpioModeInputPull, 1); - GPIO_PinModeSet(PB_PORT, PB1_PIN, gpioModeInputPull, 1); - - /* initialize the QS software tracing... */ - if (QS_INIT((void *)0) == 0) { /* initialize the QS software tracing */ - Q_ERROR(); - } - QS_OBJ_DICTIONARY(&l_SysTick_Handler); - QS_OBJ_DICTIONARY(&l_test_ISR); - - QS_USR_DICTIONARY(CONTEXT_SW); - QS_USR_DICTIONARY(TRACE_MSG); -} -/*..........................................................................*/ -void BSP_terminate(int16_t result) { - (void)result; -} -/*..........................................................................*/ -void BSP_ledOn(void) { - GPIO->P[LED_PORT].DOUT |= (1U << LED0_PIN); -} -/*..........................................................................*/ -void BSP_ledOff(void) { - GPIO->P[LED_PORT].DOUT &= ~(1U << LED0_PIN); -} -/*..........................................................................*/ -void BSP_trigISR(void) { - NVIC_SetPendingIRQ(GPIO_EVEN_IRQn); -} -/*..........................................................................*/ -void BSP_trace(QActive const *thr, char const *msg) { - QS_BEGIN(TRACE_MSG, 0U) - QS_OBJ(thr); - QS_STR(msg); - QS_END() -} -/*..........................................................................*/ -uint32_t BSP_romRead(int32_t offset, uint32_t fromEnd) { - int32_t const rom_base = (fromEnd == 0U) - ? 0x100 /* don't include the NULL-ptr region */ - : 0x40000 - 4; - return *(uint32_t volatile *)(rom_base + offset); -} -/*..........................................................................*/ -void BSP_romWrite(int32_t offset, uint32_t fromEnd, uint32_t value) { - int32_t const rom_base = (fromEnd == 0U) - ? 0x100 /* don't include the NULL-ptr region */ - : 0x40000 - 4; - *(uint32_t volatile *)(rom_base + offset) = value; -} - -/*..........................................................................*/ -uint32_t BSP_ramRead(int32_t offset, uint32_t fromEnd) { - int32_t const ram_base = (fromEnd == 0U) - ? 0x20000000 - : 0x20008000 - 4; - return *(uint32_t volatile *)(ram_base + offset); -} -/*..........................................................................*/ -void BSP_ramWrite(int32_t offset, uint32_t fromEnd, uint32_t value) { - int32_t const ram_base = (fromEnd == 0U) - ? 0x20000000 - : 0x20008000 - 4; - *(uint32_t volatile *)(ram_base + offset) = value; -} - -/*..........................................................................*/ -void QF_onStartup(void) { - /* set up the SysTick timer to fire at BSP_TICKS_PER_SEC rate */ - //SysTick_Config(SystemCoreClock / BSP_TICKS_PER_SEC); - - /* assign all priority bits for preemption-prio. and none to sub-prio. */ - NVIC_SetPriorityGrouping(0U); - - /* set priorities of ALL ISRs used in the system, see NOTE1 - * - * !!!!!!!!!!!!!!!!!!!!!!!!!!!! CAUTION !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - * Assign a priority to EVERY ISR explicitly by calling NVIC_SetPriority(). - * DO NOT LEAVE THE ISR PRIORITIES AT THE DEFAULT VALUE! - */ - NVIC_SetPriority(GPIO_EVEN_IRQn, QF_AWARE_ISR_CMSIS_PRI + 0U); - NVIC_SetPriority(SysTick_IRQn, QF_AWARE_ISR_CMSIS_PRI + 1U); - /* ... */ - - /* enable IRQs... */ - NVIC_EnableIRQ(GPIO_EVEN_IRQn); -} -/*..........................................................................*/ -void QF_onCleanup(void) { -} -/*..........................................................................*/ -#ifdef QF_ON_CONTEXT_SW -/* NOTE: the context-switch callback is called with interrupts DISABLED */ -void QF_onContextSw(QActive *prev, QActive *next) { - QS_BEGIN_NOCRIT(CONTEXT_SW, 0U) /* no critical section! */ - QS_OBJ(prev); - QS_OBJ(next); - QS_END_NOCRIT() -} -#endif /* QF_ON_CONTEXT_SW */ -/*..........................................................................*/ -void QK_onIdle(void) { - - GPIO->P[LED_PORT].DOUT |= (1U << LED1_PIN); - GPIO->P[LED_PORT].DOUT &= ~(1U << LED1_PIN); - -#ifdef Q_SPY - QS_rxParse(); /* parse all the received bytes */ - QS_doOutput(); -#elif defined NDEBUG - /* Put the CPU and peripherals to the low-power mode. - * you might need to customize the clock management for your application, - * see the datasheet for your particular Cortex-M3 MCU. - */ - __WFI(); /* Wait-For-Interrupt */ -#endif -} - -/* QS callbacks ============================================================*/ -#ifdef Q_SPY - -/*..........................................................................*/ -void QTimeEvt_tick1_( - uint_fast8_t const tickRate, - void const * const sender) -{ - QF_INT_DISABLE(); - /* TODO pend the SysTick */ - *Q_UINT2PTR_CAST(uint32_t, 0xE000ED04U) = (1U << 26U); - QF_INT_ENABLE(); -} - -#endif /* Q_SPY */ - -/*============================================================================ -* NOTE0: -* The MPU protection against NULL-pointer dereferencing sets up a no-access -* MPU region #7 around the NULL address (0x0). This works even though the -* Vector Table also resides at address 0x0. However, the *size* of the -* no-access region should not exceed the size of the Vector Table. In this -* case, the size is set to 2**(7+1)==256 bytes, which does not contain any -* data that the CPU would legitimately read with the LDR instruction. -*/ diff --git a/test/qk/test_sched/bsp_efm32pg1b.c b/test/qk/test_sched/bsp_efm32pg1b.c new file mode 100644 index 00000000..4ab719cc --- /dev/null +++ b/test/qk/test_sched/bsp_efm32pg1b.c @@ -0,0 +1,373 @@ +//============================================================================ +// Product: BSP for system-testing of QK kernel, EFM32-SLSTK3401A board +// Last updated for version 7.3.0 +// Last updated on 2023-07-18 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// This program is open source software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Alternatively, this program may be distributed and modified under the +// terms of Quantum Leaps commercial licenses, which expressly supersede +// the GNU General Public License and are specifically designed for +// licensees interested in retaining the proprietary status of their code. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Contact information: +// +// +//============================================================================ +#include "qpc.h" +#include "bsp.h" + +#include "em_device.h" // the device specific header (SiLabs) +#include "em_cmu.h" // Clock Management Unit (SiLabs) +#include "em_gpio.h" // GPIO (SiLabs) +#include "em_usart.h" // USART (SiLabs) +// add other drivers if necessary... + +Q_DEFINE_THIS_FILE + +// ISRs defined in this BSP ------------------------------------------------ +void SysTick_Handler(void); +void GPIO_EVEN_IRQHandler(void); + +// Local-scope objects ----------------------------------------------------- +#define LED_PORT gpioPortF +#define LED0_PIN 4 +#define LED1_PIN 5 + +#define PB_PORT gpioPortF +#define PB0_PIN 6 +#define PB1_PIN 7 + +#ifdef Q_SPY + + // QSpy source IDs + static QSpyId const l_SysTick_Handler = { 100U }; + static QSpyId const l_test_ISR = { 101U }; + + enum AppRecords { // application-specific trace records + CONTEXT_SW = QS_USER1, + TRACE_MSG + }; + +#endif + +//.......................................................................... +void SysTick_Handler(void); // prototype +void SysTick_Handler(void) { + QK_ISR_ENTRY(); // inform QK kernel about entering an ISR + + // process time events for rate 0 + QTIMEEVT_TICK_X(0U, &l_SysTick_Handler); + //QTICKER_TRIG(the_Ticker0, &l_SysTick_Handler); /* trigger ticker AO */ + + + QK_ISR_EXIT(); // inform QK kernel about exiting an ISR +} +//.......................................................................... +void GPIO_EVEN_IRQHandler(void); // prototype +void GPIO_EVEN_IRQHandler(void) { // for testing, NOTE03 + QK_ISR_ENTRY(); // inform QK kernel about entering an ISR + + // for testing... + static QEvt const t1 = QEVT_INITIALIZER(TEST1_SIG); + QACTIVE_PUBLISH(&t1, &l_test_ISR); + + QK_ISR_EXIT(); // inform QK kernel about exiting an ISR +} + +//.......................................................................... +// MPU setup for EFM32PG1B200F256GM48 MCU +static void EFM32PG182_MPU_setup(void) { + // The following MPU configuration contains the general EFM32PG1 memory + // map described in the EFM32PG1 Data Sheet Figure 3.2. EFM32PG1 Memory Map + // + // Please note that the actual STM32 MCUs provide much less Flash and SRAM + // than the maximums configured here. This means that actual MCUs have + // unmapped memory regions (e.g., beyond the actual SRAM). Attempts to + // access these regions causes the HardFault exception, which is the + // desired behavior. + // + static struct { + uint32_t rbar; + uint32_t rasr; + } const mpu_setup[] = { + + { // region #0: Flash: base=0x0000'0000, size=512M=2^(28+1) + 0x00000000U // base address + | MPU_RBAR_VALID_Msk // valid region + | (MPU_RBAR_REGION_Msk & 0U), // region #0 + (28U << MPU_RASR_SIZE_Pos) // 2^(18+1) region + | (0x6U << MPU_RASR_AP_Pos) // PA:ro/UA:ro + | (1U << MPU_RASR_C_Pos) // C=1 + | MPU_RASR_ENABLE_Msk // region enable + }, + + { // region #1: SRAM: base=0x2000'0000, size=512M=2^(28+1) + 0x20000000U // base address + | MPU_RBAR_VALID_Msk // valid region + | (MPU_RBAR_REGION_Msk & 1U), // region #1 + (28U << MPU_RASR_SIZE_Pos) // 2^(28+1) region + | (0x3U << MPU_RASR_AP_Pos) // PA:rw/UA:rw + | (1U << MPU_RASR_XN_Pos) // XN=1 + | (1U << MPU_RASR_S_Pos) // S=1 + | (1U << MPU_RASR_C_Pos) // C=1 + | MPU_RASR_ENABLE_Msk // region enable + }, + + // region #3: (not configured) + { MPU_RBAR_VALID_Msk | (MPU_RBAR_REGION_Msk & 2U), 0U }, + + { // region #3: Peripherals: base=0x4000'0000, size=512M=2^(28+1) + 0x40000000U // base address + | MPU_RBAR_VALID_Msk // valid region + | (MPU_RBAR_REGION_Msk & 3U), // region #3 + (28U << MPU_RASR_SIZE_Pos) // 2^(28+1) region + | (0x3U << MPU_RASR_AP_Pos) // PA:rw/UA:rw + | (1U << MPU_RASR_XN_Pos) // XN=1 + | (1U << MPU_RASR_S_Pos) // S=1 + | (1U << MPU_RASR_B_Pos) // B=1 + | MPU_RASR_ENABLE_Msk // region enable + }, + + { // region #4: Priv. Periph: base=0xE000'0000, size=512M=2^(28+1) + 0xE0000000U // base address + | MPU_RBAR_VALID_Msk // valid region + | (MPU_RBAR_REGION_Msk & 4U), // region #4 + (28U << MPU_RASR_SIZE_Pos) // 2^(28+1) region + | (0x3U << MPU_RASR_AP_Pos) // PA:rw/UA:rw + | (1U << MPU_RASR_XN_Pos) // XN=1 + | (1U << MPU_RASR_S_Pos) // S=1 + | (1U << MPU_RASR_B_Pos) // B=1 + | MPU_RASR_ENABLE_Msk // region enable + }, + + { // region #5: Ext RAM: base=0x6000'0000, size=1G=2^(29+1) + 0x60000000U // base address + | MPU_RBAR_VALID_Msk // valid region + | (MPU_RBAR_REGION_Msk & 5U), // region #5 + (29U << MPU_RASR_SIZE_Pos) // 2^(28+1) region + | (0x3U << MPU_RASR_AP_Pos) // PA:rw/UA:rw + | (1U << MPU_RASR_XN_Pos) // XN=1 + | (1U << MPU_RASR_S_Pos) // S=1 + | (1U << MPU_RASR_B_Pos) // B=1 + | MPU_RASR_ENABLE_Msk // region enable + }, + + { // region #6: Ext Dev: base=0xA000'0000, size=1G=2^(29+1) + 0xA0000000U // base address + | MPU_RBAR_VALID_Msk // valid region + | (MPU_RBAR_REGION_Msk & 6U), // region #6 + (29U << MPU_RASR_SIZE_Pos) // 2^(28+1) region + | (0x3U << MPU_RASR_AP_Pos) // PA:rw/UA:rw + | (1U << MPU_RASR_XN_Pos) // XN=1 + | (1U << MPU_RASR_S_Pos) // S=1 + | (1U << MPU_RASR_B_Pos) // B=1 + | MPU_RASR_ENABLE_Msk // region enable + }, + + { // region #7: NULL-pointer: base=0x000'0000, size=256B, NOTE0 + 0x00000000U // base address + | MPU_RBAR_VALID_Msk // valid region + | (MPU_RBAR_REGION_Msk & 7U), // region #7 + (7U << MPU_RASR_SIZE_Pos) // 2^(7+1)=256B region + | (0x0U << MPU_RASR_AP_Pos) // PA:na/UA:na + | (1U << MPU_RASR_XN_Pos) // XN=1 + | MPU_RASR_ENABLE_Msk // region enable + }, + }; + + // enable the MemManage_Handler for MPU exception + SCB->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk; + + __DSB(); + MPU->CTRL = 0U; // disable the MPU + for (uint_fast8_t n = 0U; n < Q_DIM(mpu_setup); ++n) { + MPU->RBAR = mpu_setup[n].rbar; + MPU->RASR = mpu_setup[n].rasr; + } + MPU->CTRL = MPU_CTRL_ENABLE_Msk; // enable the MPU + __ISB(); + __DSB(); +} + +//.......................................................................... +void BSP_init(void) { + // setup the MPU... + EFM32PG182_MPU_setup(); + + // NOTE: SystemInit() has been already called from the startup code + // but SystemCoreClock needs to be updated + // + SystemCoreClockUpdate(); + + // NOTE: The VFP (hardware Floating Point) unit is configured by QK + + // enable clock for to the peripherals used by this application... + CMU_ClockEnable(cmuClock_HFPER, true); + CMU_ClockEnable(cmuClock_GPIO, true); + CMU_ClockEnable(cmuClock_HFPER, true); + CMU_ClockEnable(cmuClock_GPIO, true); + + // configure the LEDs + GPIO_PinModeSet(LED_PORT, LED0_PIN, gpioModePushPull, 0); + GPIO_PinModeSet(LED_PORT, LED1_PIN, gpioModePushPull, 0); + GPIO_PinOutClear(LED_PORT, LED0_PIN); + GPIO_PinOutClear(LED_PORT, LED1_PIN); + + // configure the Buttons + GPIO_PinModeSet(PB_PORT, PB0_PIN, gpioModeInputPull, 1); + GPIO_PinModeSet(PB_PORT, PB1_PIN, gpioModeInputPull, 1); + + // initialize the QS software tracing... + if (QS_INIT((void *)0) == 0) { // initialize the QS software tracing + Q_ERROR(); + } + QS_OBJ_DICTIONARY(&l_SysTick_Handler); + QS_OBJ_DICTIONARY(&l_test_ISR); + + QS_USR_DICTIONARY(CONTEXT_SW); + QS_USR_DICTIONARY(TRACE_MSG); +} +//.......................................................................... +void BSP_terminate(int16_t result) { + Q_UNUSED_PAR(result); +} +//.......................................................................... +void BSP_ledOn(void) { + GPIO->P[LED_PORT].DOUT |= (1U << LED0_PIN); +} +//.......................................................................... +void BSP_ledOff(void) { + GPIO->P[LED_PORT].DOUT &= ~(1U << LED0_PIN); +} +//.......................................................................... +void BSP_trigISR(void) { + NVIC_SetPendingIRQ(GPIO_EVEN_IRQn); +} +//.......................................................................... +void BSP_trace(QActive const *thr, char const *msg) { + QS_BEGIN(TRACE_MSG, 0U) + QS_OBJ(thr); + QS_STR(msg); + QS_END() +} +//.......................................................................... +uint32_t BSP_romRead(int32_t offset, uint32_t fromEnd) { + int32_t const rom_base = (fromEnd == 0U) + ? 0x100 // don't include the NULL-ptr region + : 0x40000 - 4; + return *(uint32_t volatile *)(rom_base + offset); +} +//.......................................................................... +void BSP_romWrite(int32_t offset, uint32_t fromEnd, uint32_t value) { + int32_t const rom_base = (fromEnd == 0U) + ? 0x100 // don't include the NULL-ptr region + : 0x40000 - 4; + *(uint32_t volatile *)(rom_base + offset) = value; +} + +//.......................................................................... +uint32_t BSP_ramRead(int32_t offset, uint32_t fromEnd) { + int32_t const ram_base = (fromEnd == 0U) + ? 0x20000000 + : 0x20008000 - 4; + return *(uint32_t volatile *)(ram_base + offset); +} +//.......................................................................... +void BSP_ramWrite(int32_t offset, uint32_t fromEnd, uint32_t value) { + int32_t const ram_base = (fromEnd == 0U) + ? 0x20000000 + : 0x20008000 - 4; + *(uint32_t volatile *)(ram_base + offset) = value; +} + +//.......................................................................... +void QF_onStartup(void) { + // set up the SysTick timer to fire at BSP_TICKS_PER_SEC rate + //SysTick_Config(SystemCoreClock / BSP_TICKS_PER_SEC); + + // assign all priority bits for preemption-prio. and none to sub-prio. + NVIC_SetPriorityGrouping(0U); + + // set priorities of ALL ISRs used in the system + NVIC_SetPriority(GPIO_EVEN_IRQn, QF_AWARE_ISR_CMSIS_PRI + 0U); + NVIC_SetPriority(SysTick_IRQn, QF_AWARE_ISR_CMSIS_PRI + 1U); + // NOTE: priority of UART IRQ used for QS-RX is set in qutest_port.c + // ... + + // enable IRQs... + NVIC_EnableIRQ(GPIO_EVEN_IRQn); +} +//.......................................................................... +void QF_onCleanup(void) { +} +//.......................................................................... +#ifdef QF_ON_CONTEXT_SW +// NOTE: the context-switch callback is called with interrupts DISABLED +void QF_onContextSw(QActive *prev, QActive *next) { + QS_BEGIN_INCRIT(CONTEXT_SW, 0U) // in critical section! + QS_OBJ(prev); + QS_OBJ(next); + QS_END_INCRIT() +} +#endif // QF_ON_CONTEXT_SW +//.......................................................................... +void QK_onIdle(void) { + + GPIO->P[LED_PORT].DOUT |= (1U << LED1_PIN); + GPIO->P[LED_PORT].DOUT &= ~(1U << LED1_PIN); + +#ifdef Q_SPY + QS_rxParse(); // parse all the received bytes + QS_doOutput(); +#elif defined NDEBUG + // Put the CPU and peripherals to the low-power mode. + // you might need to customize the clock management for your application, + // see the datasheet for your particular Cortex-M3 MCU. + // + __WFI(); // Wait-For-Interrupt +#endif +} + +// QS callbacks ============================================================ +#ifdef Q_SPY + +//.......................................................................... +void QTimeEvt_tick1_( + uint_fast8_t const tickRate, + void const * const sender) +{ + QF_INT_DISABLE(); + // TODO pend the SysTick + *Q_UINT2PTR_CAST(uint32_t, 0xE000ED04U) = (1U << 26U); + QF_INT_ENABLE(); +} + +#endif // Q_SPY + +//============================================================================ +// NOTE0: +// The MPU protection against NULL-pointer dereferencing sets up a no-access +// MPU region #7 around the NULL address (0x0). This works even though the +// Vector Table also resides at address 0x0. However, the *size* of the +// no-access region should not exceed the size of the Vector Table. In this +// case, the size is set to 2**(7+1)==256 bytes, which does not contain any +// data that the CPU would legitimately read with the LDR instruction. +// diff --git a/test/qk/test_sched/bsp_h743zi.c b/test/qk/test_sched/bsp_h743zi.c deleted file mode 100644 index 9656ea06..00000000 --- a/test/qk/test_sched/bsp_h743zi.c +++ /dev/null @@ -1,300 +0,0 @@ -/*============================================================================ -* Product: BSP for system-testing of QK kernel, NUCLEO-H743ZI board -* Last updated for version 7.2.0 -* Last updated on 2022-12-15 -* -* Q u a n t u m L e a P s -* ------------------------ -* Modern Embedded Software -* -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* -* -============================================================================*/ -#include "qpc.h" -#include "bsp.h" - -/* STM32CubeH7 include files */ -#include "stm32h7xx_hal.h" -#include "stm32h7xx_nucleo_144.h" -/* add other drivers if necessary... */ - -Q_DEFINE_THIS_FILE - -#ifdef Q_SPY - - /* QSpy source IDs */ - static QSpyId const l_SysTick_Handler = { 100U }; - static QSpyId const l_test_ISR = { 101U }; - - enum AppRecords { /* application-specific trace records */ - CONTEXT_SW = QS_USER1, - TRACE_MSG - }; - -#endif - -/* ISRs used in this project ===============================================*/ -void SysTick_Handler(void); /* prototype */ -void SysTick_Handler(void) { - QK_ISR_ENTRY(); /* inform QXK kernel about entering an ISR */ - - /* process time events for rate 0 */ - QTIMEEVT_TICK_X(0U, &l_SysTick_Handler); - - QK_ISR_EXIT(); /* inform QXK kernel about exiting an ISR */ -} -/*..........................................................................*/ -void EXTI0_IRQHandler(void); /* prototype */ -void EXTI0_IRQHandler(void) { /* for testing, NOTE03 */ - QK_ISR_ENTRY(); /* inform QXK kernel about entering an ISR */ - - /* for testing... */ - static QEvt const t1 = { TEST1_SIG, 0U, 0U }; - QACTIVE_PUBLISH(&t1, &l_test_ISR); - - QK_ISR_EXIT(); /* inform QXK kernel about exiting an ISR */ -} - -/* BSP functions ===========================================================*/ -/*..........................................................................*/ -/* MPU setup for STM32H743ZI MCU */ -static void STM32H743ZI_MPU_setup(void) { - /* The following MPU configuration contains just a generic ROM - * region (with read-only access) and NULL-pointer protection region. - * Otherwise, the MPU will fall back on the background region (PRIVDEFENA). - */ - static struct { - uint32_t rbar; - uint32_t rasr; - } const mpu_setup[] = { - - { /* region #0: Flash: base=0x0000'0000, size=512M=2^(28+1) */ - 0x00000000U /* base address */ - | MPU_RBAR_VALID_Msk /* valid region */ - | (MPU_RBAR_REGION_Msk & 0U), /* region #0 */ - (28U << MPU_RASR_SIZE_Pos) /* 2^(18+1) region */ - | (0x6U << MPU_RASR_AP_Pos) /* PA:ro/UA:ro */ - | (1U << MPU_RASR_C_Pos) /* C=1 */ - | MPU_RASR_ENABLE_Msk /* region enable */ - }, - - { /* region #7: NULL-pointer: base=0x000'0000, size=128M=2^(26+1) */ - /* NOTE: this region extends to 0x080'0000, which is where - * the ROM is re-mapped by STM32 - */ - 0x00000000U /* base address */ - | MPU_RBAR_VALID_Msk /* valid region */ - | (MPU_RBAR_REGION_Msk & 7U), /* region #7 */ - (26U << MPU_RASR_SIZE_Pos) /* 2^(26+1)=128M region */ - | (0x0U << MPU_RASR_AP_Pos) /* PA:na/UA:na */ - | (1U << MPU_RASR_XN_Pos) /* XN=1 */ - | MPU_RASR_ENABLE_Msk /* region enable */ - }, - }; - - /* enable the MemManage_Handler for MPU exception */ - SCB->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk; - - __DSB(); - MPU->CTRL = 0U; /* disable the MPU */ - for (uint_fast8_t n = 0U; n < Q_DIM(mpu_setup); ++n) { - MPU->RBAR = mpu_setup[n].rbar; - MPU->RASR = mpu_setup[n].rasr; - } - MPU->CTRL = MPU_CTRL_ENABLE_Msk /* enable the MPU */ - | MPU_CTRL_PRIVDEFENA_Msk; /* enable background region */ - __ISB(); - __DSB(); -} - -/*..........................................................................*/ -void BSP_init(void) { - /* setup the MPU... */ - STM32H743ZI_MPU_setup(); - - /* NOTE: SystemInit() has been already called from the startup code - * but SystemCoreClock needs to be updated - */ - SystemCoreClockUpdate(); - - SCB_EnableICache(); /* Enable I-Cache */ - SCB_EnableDCache(); /* Enable D-Cache */ - - /* Configure Flash prefetch and Instr. cache through ART accelerator */ -#if (ART_ACCLERATOR_ENABLE != 0) - __HAL_FLASH_ART_ENABLE(); -#endif /* ART_ACCLERATOR_ENABLE */ - - /* Configure the LEDs */ - BSP_LED_Init(LED1); - BSP_LED_Init(LED2); - BSP_LED_Init(LED3); - - /* Configure the User Button in GPIO Mode */ - BSP_PB_Init(BUTTON_USER, BUTTON_MODE_GPIO); - - if (QS_INIT((void *)0) == 0) { /* initialize the QS software tracing */ - Q_ERROR(); - } - - /* dictionaries... */ - QS_OBJ_DICTIONARY(&l_SysTick_Handler); - QS_OBJ_DICTIONARY(&l_test_ISR); - - QS_USR_DICTIONARY(CONTEXT_SW); - QS_USR_DICTIONARY(TRACE_MSG); -} -/*..........................................................................*/ -void BSP_terminate(int16_t result) { - Q_UNUSED_PAR(result); -} -/*..........................................................................*/ -void BSP_ledOn(void) { - BSP_LED_On(LED1); -} -/*..........................................................................*/ -void BSP_ledOff(void) { - BSP_LED_Off(LED1); -} -/*..........................................................................*/ -void BSP_trigISR(void) { - NVIC_SetPendingIRQ(EXTI0_IRQn); -} -/*..........................................................................*/ -void BSP_trace(QActive const *thr, char const *msg) { - QS_BEGIN_ID(TRACE_MSG, 0U) - QS_OBJ(thr); - QS_STR(msg); - QS_END() -} -/*..........................................................................*/ -uint32_t BSP_romRead(int32_t offset, uint32_t fromEnd) { - int32_t const rom_base = (fromEnd == 0U) - ? 0x08000000 - : 0x08200000 - 4; - return *(uint32_t volatile *)(rom_base + offset); -} -/*..........................................................................*/ -void BSP_romWrite(int32_t offset, uint32_t fromEnd, uint32_t value) { - int32_t const rom_base = (fromEnd == 0U) - ? 0x08000000 - : 0x08200000 - 4; - *(uint32_t volatile *)(rom_base + offset) = value; -} - -/*..........................................................................*/ -uint32_t BSP_ramRead(int32_t offset, uint32_t fromEnd) { - int32_t const ram_base = (fromEnd == 0U) - ? 0x20000000 - : 0x20020000 - 4; - return *(uint32_t volatile *)(ram_base + offset); -} -/*..........................................................................*/ -void BSP_ramWrite(int32_t offset, uint32_t fromEnd, uint32_t value) { - int32_t const ram_base = (fromEnd == 0U) - ? 0x20000000 - : 0x20020000 - 4; - *(uint32_t volatile *)(ram_base + offset) = value; -} - -/*..........................................................................*/ -void QF_onStartup(void) { - /* set up the SysTick timer to fire at BSP_TICKS_PER_SEC rate */ - //NOTE: don't start ticking for these tests - //SysTick_Config(SystemCoreClock / BSP_TICKS_PER_SEC); - - /* assign all priority bits for preemption-prio. and none to sub-prio. - * NOTE: this might have been changed by STM32Cube. - */ - NVIC_SetPriorityGrouping(0U); - - /* set priorities of ALL ISRs used in the system, see NOTE1 - * - * !!!!!!!!!!!!!!!!!!!!!!!!!!!! CAUTION !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - * Assign a priority to EVERY ISR explicitly by calling NVIC_SetPriority(). - * DO NOT LEAVE THE ISR PRIORITIES AT THE DEFAULT VALUE! - */ - NVIC_SetPriority(SysTick_IRQn, QF_AWARE_ISR_CMSIS_PRI + 0U); - NVIC_SetPriority(EXTI0_IRQn, QF_AWARE_ISR_CMSIS_PRI + 1U); - /* ... */ - - /* enable IRQs... */ - NVIC_EnableIRQ(EXTI0_IRQn); -} -/*..........................................................................*/ -void QF_onCleanup(void) { -} -/*..........................................................................*/ -#ifdef QF_ON_CONTEXT_SW -/* NOTE: the context-switch callback is called with interrupts DISABLED */ -void QF_onContextSw(QActive *prev, QActive *next) { - QS_BEGIN_NOCRIT(CONTEXT_SW, 0U) /* no critical section! */ - QS_OBJ(prev); - QS_OBJ(next); - QS_END_NOCRIT() -} -#endif /* QF_ON_CONTEXT_SW */ - -/*..........................................................................*/ -void QK_onIdle(void) { -#ifdef Q_SPY - QS_rxParse(); /* parse all the received bytes */ - QS_doOutput(); -#elif defined NDEBUG - /* Put the CPU and peripherals to the low-power mode. - * you might need to customize the clock management for your application, - * see the datasheet for your particular Cortex-M3 MCU. - */ - __WFI(); /* Wait-For-Interrupt */ -#endif -} - -/* QS callbacks ============================================================*/ -#ifdef Q_SPY - -/*..........................................................................*/ -void QTimeEvt_tick1_( - uint_fast8_t const tickRate, - void const * const sender) -{ - QF_INT_DISABLE(); - /* TODO pend the SysTick */ - *Q_UINT2PTR_CAST(uint32_t, 0xE000ED04U) = (1U << 26U); - QF_INT_ENABLE(); -} - -#endif /* Q_SPY */ - -/*============================================================================ -* NOTE0: -* The MPU protection against NULL-pointer dereferencing sets up a no-access -* MPU region #7 around the NULL address (0x0). The size of this region is set -* to 2**(26+1)==0x0800'0000, because that is the address of Flash in STM32. -* -* REMARK: STM32 MCUs automatically relocate the Flash memory and the Vector -* Table in it to address 0x0800'0000 at startup. However, even though the -* region 0..0x0800'0000 is un-mapped after the relocation, the read access -* is still allowed and causes no CPU exception. Therefore setting up the MPU -* to protect that region is necessary. -*/ diff --git a/test/qk/test_sched/bsp_l053r8.c b/test/qk/test_sched/bsp_l053r8.c deleted file mode 100644 index 8d228e50..00000000 --- a/test/qk/test_sched/bsp_l053r8.c +++ /dev/null @@ -1,374 +0,0 @@ -/*============================================================================ -* Product: BSP for system-testing of QK kernel, NUCLEO-L053R8 board -* Last updated for version 7.2.0 -* Last updated on 2022-12-13 -* -* Q u a n t u m L e a P s -* ------------------------ -* Modern Embedded Software -* -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* -* -============================================================================*/ -#include "qpc.h" -#include "bsp.h" - -#include "stm32l0xx.h" /* CMSIS-compliant header file for the MCU used */ -/* add other drivers if necessary... */ - -Q_DEFINE_THIS_FILE - -/* Local-scope objects -----------------------------------------------------*/ -/* LED pins available on the board (just one user LED LD2--Green on PA.5) */ -#define LED_LD2 (1U << 5) - -/* Button pins available on the board (just one user Button B1 on PC.13) */ -#define BTN_B1 (1U << 13) - -#ifdef Q_SPY - /* QSpy source IDs */ - static QSpyId const l_SysTick_Handler = { 100U }; - static QSpyId const l_test_ISR = { 101U }; - - enum AppRecords { /* application-specific trace records */ - CONTEXT_SW = QS_USER1, - TRACE_MSG - }; - -#endif - -/* ISRs used in this project ===============================================*/ -void SysTick_Handler(void); /* prototype */ -void SysTick_Handler(void) { - QK_ISR_ENTRY(); /* inform QXK kernel about entering an ISR */ - - /* process time events for rate 0 */ - QTIMEEVT_TICK_X(0U, &l_SysTick_Handler); - - QK_ISR_EXIT(); /* inform QXK kernel about exiting an ISR */ -} -/*..........................................................................*/ -void EXTI0_1_IRQHandler(void); /* prototype */ -void EXTI0_1_IRQHandler(void) { /* for testing, NOTE03 */ - QK_ISR_ENTRY(); /* inform QXK kernel about entering an ISR */ - - /* for testing... */ - static QEvt const t1 = { TEST1_SIG, 0U, 0U }; - QACTIVE_PUBLISH(&t1, &l_test_ISR); - - QK_ISR_EXIT(); /* inform QXK kernel about exiting an ISR */ -} - -/* BSP functions ===========================================================*/ -/*..........................................................................*/ -/* MPU setup for STM32L053R8 MCU */ -static void STM32L053R8_MPU_setup(void) { - /* The following MPU configuration contains the general STM32 memory model - * as described in the ST AppNote AN4838 "Managing memory protection unit - * in STM32 MCUs", Figure 2. Cortex-M0+/M3/M4/M7 processor memory map. - * - * Please note that the actual STM32 MCUs provide much less Flash and SRAM - * than the maximums configured here. This means that actual MCUs have - * unmapped memory regions (e.g., beyond the actual SRAM). Attempts to - * access these regions causes the HardFault exception, which is the - * desired behavior. - */ - static struct { - uint32_t rbar; - uint32_t rasr; - } const mpu_setup[] = { - - { /* region #0: Flash: base=0x0000'0000, size=512M=2^(28+1) */ - 0x00000000U /* base address */ - | MPU_RBAR_VALID_Msk /* valid region */ - | (MPU_RBAR_REGION_Msk & 0U), /* region #0 */ - (28U << MPU_RASR_SIZE_Pos) /* 2^(18+1) region */ - | (0x6U << MPU_RASR_AP_Pos) /* PA:ro/UA:ro */ - | (1U << MPU_RASR_C_Pos) /* C=1 */ - | MPU_RASR_ENABLE_Msk /* region enable */ - }, - - { /* region #1: SRAM: base=0x2000'0000, size=512M=2^(28+1) */ - 0x20000000U /* base address */ - | MPU_RBAR_VALID_Msk /* valid region */ - | (MPU_RBAR_REGION_Msk & 1U), /* region #1 */ - (28U << MPU_RASR_SIZE_Pos) /* 2^(28+1) region */ - | (0x3U << MPU_RASR_AP_Pos) /* PA:rw/UA:rw */ - | (1U << MPU_RASR_XN_Pos) /* XN=1 */ - | (1U << MPU_RASR_S_Pos) /* S=1 */ - | (1U << MPU_RASR_C_Pos) /* C=1 */ - | MPU_RASR_ENABLE_Msk /* region enable */ - }, - - /* region #3: (not configured) */ - { MPU_RBAR_VALID_Msk | (MPU_RBAR_REGION_Msk & 2U), 0U }, - - { /* region #3: Peripherals: base=0x4000'0000, size=512M=2^(28+1) */ - 0x40000000U /* base address */ - | MPU_RBAR_VALID_Msk /* valid region */ - | (MPU_RBAR_REGION_Msk & 3U), /* region #3 */ - (28U << MPU_RASR_SIZE_Pos) /* 2^(28+1) region */ - | (0x3U << MPU_RASR_AP_Pos) /* PA:rw/UA:rw */ - | (1U << MPU_RASR_XN_Pos) /* XN=1 */ - | (1U << MPU_RASR_S_Pos) /* S=1 */ - | (1U << MPU_RASR_B_Pos) /* B=1 */ - | MPU_RASR_ENABLE_Msk /* region enable */ - }, - - { /* region #4: Priv. Periph: base=0xE000'0000, size=512M=2^(28+1) */ - 0xE0000000U /* base address */ - | MPU_RBAR_VALID_Msk /* valid region */ - | (MPU_RBAR_REGION_Msk & 4U), /* region #4 */ - (28U << MPU_RASR_SIZE_Pos) /* 2^(28+1) region */ - | (0x3U << MPU_RASR_AP_Pos) /* PA:rw/UA:rw */ - | (1U << MPU_RASR_XN_Pos) /* XN=1 */ - | (1U << MPU_RASR_S_Pos) /* S=1 */ - | (1U << MPU_RASR_B_Pos) /* B=1 */ - | MPU_RASR_ENABLE_Msk /* region enable */ - }, - - { /* region #5: Ext RAM: base=0x6000'0000, size=1G=2^(29+1) */ - 0x60000000U /* base address */ - | MPU_RBAR_VALID_Msk /* valid region */ - | (MPU_RBAR_REGION_Msk & 5U), /* region #5 */ - (29U << MPU_RASR_SIZE_Pos) /* 2^(28+1) region */ - | (0x3U << MPU_RASR_AP_Pos) /* PA:rw/UA:rw */ - | (1U << MPU_RASR_XN_Pos) /* XN=1 */ - | (1U << MPU_RASR_S_Pos) /* S=1 */ - | (1U << MPU_RASR_B_Pos) /* B=1 */ - | MPU_RASR_ENABLE_Msk /* region enable */ - }, - - { /* region #6: Ext Dev: base=0xA000'0000, size=1G=2^(29+1) */ - 0xA0000000U /* base address */ - | MPU_RBAR_VALID_Msk /* valid region */ - | (MPU_RBAR_REGION_Msk & 6U), /* region #6 */ - (29U << MPU_RASR_SIZE_Pos) /* 2^(28+1) region */ - | (0x3U << MPU_RASR_AP_Pos) /* PA:rw/UA:rw */ - | (1U << MPU_RASR_XN_Pos) /* XN=1 */ - | (1U << MPU_RASR_S_Pos) /* S=1 */ - | (1U << MPU_RASR_B_Pos) /* B=1 */ - | MPU_RASR_ENABLE_Msk /* region enable */ - }, - - { /* region #7: NULL-pointer: base=0x000'0000, size=128M=2^(26+1) */ - /* NOTE: this region extends to 0x080'0000, which is where - * the ROM is re-mapped by STM32 - */ - 0x00000000U /* base address */ - | MPU_RBAR_VALID_Msk /* valid region */ - | (MPU_RBAR_REGION_Msk & 7U), /* region #7 */ - (26U << MPU_RASR_SIZE_Pos) /* 2^(26+1)=128M region */ - | (0x0U << MPU_RASR_AP_Pos) /* PA:na/UA:na */ - | (1U << MPU_RASR_XN_Pos) /* XN=1 */ - | MPU_RASR_ENABLE_Msk /* region enable */ - }, - - }; - - __DSB(); - MPU->CTRL = 0U; /* disable the MPU */ - for (uint_fast8_t n = 0U; n < Q_DIM(mpu_setup); ++n) { - MPU->RBAR = mpu_setup[n].rbar; - MPU->RASR = mpu_setup[n].rasr; - } - MPU->CTRL = MPU_CTRL_PRIVDEFENA_Msk /* enable background region */ - | MPU_CTRL_ENABLE_Msk; /* enable the MPU */ - __ISB(); - __DSB(); -} -/*..........................................................................*/ -void BSP_init(void) { - /* setup the MPU... */ - STM32L053R8_MPU_setup(); - - /* NOTE: SystemInit() has been already called from the startup code - * but SystemCoreClock needs to be updated - */ - SystemCoreClockUpdate(); - - /* enable GPIOA clock port for the LED LD2 */ - RCC->IOPENR |= (1U << 0); - - /* configure LED (PA.5) pin as push-pull output, no pull-up, pull-down */ - GPIOA->MODER &= ~((3U << 2*5)); - GPIOA->MODER |= ((1U << 2*5)); - GPIOA->OTYPER &= ~((1U << 5)); - GPIOA->OSPEEDR &= ~((3U << 2*5)); - GPIOA->OSPEEDR |= ((1U << 2*5)); - GPIOA->PUPDR &= ~((3U << 2*5)); - - /* enable GPIOC clock port for the Button B1 */ - RCC->IOPENR |= (1U << 2); - - /* configure Button (PC.13) pins as input, no pull-up, pull-down */ - GPIOC->MODER &= ~(3U << 2*13); - GPIOC->OSPEEDR &= ~(3U << 2*13); - GPIOC->OSPEEDR |= (1U << 2*13); - GPIOC->PUPDR &= ~(3U << 2*13); - - /* initialize the QS software tracing... */ - if (QS_INIT((void *)0) == 0) { /* initialize the QS software tracing */ - Q_ERROR(); - } - - /* dictionaries... */ - QS_OBJ_DICTIONARY(&l_SysTick_Handler); - QS_OBJ_DICTIONARY(&l_test_ISR); - - QS_USR_DICTIONARY(CONTEXT_SW); - QS_USR_DICTIONARY(TRACE_MSG); -} -/*..........................................................................*/ -void BSP_terminate(int16_t result) { - Q_UNUSED_PAR(result); -} -/*..........................................................................*/ -void BSP_ledOn(void) { - GPIOA->BSRR |= (LED_LD2); /* turn LED2 on */ -} -/*..........................................................................*/ -void BSP_ledOff(void) { - GPIOA->BSRR |= (LED_LD2 << 16); /* turn LED2 off */ -} -/*..........................................................................*/ -void BSP_trigISR(void) { - NVIC_SetPendingIRQ(EXTI0_1_IRQn); -} -/*..........................................................................*/ -void BSP_trace(QActive const *thr, char const *msg) { - QS_BEGIN_ID(TRACE_MSG, 0U) - QS_OBJ(thr); - QS_STR(msg); - QS_END() -} -/*..........................................................................*/ -uint32_t BSP_romRead(int32_t offset, uint32_t fromEnd) { - int32_t const rom_base = (fromEnd == 0U) - ? 0x08000000 - : 0x08010000 - 4; - return *(uint32_t volatile *)(rom_base + offset); -} -/*..........................................................................*/ -void BSP_romWrite(int32_t offset, uint32_t fromEnd, uint32_t value) { - int32_t const rom_base = (fromEnd == 0U) - ? 0x08000000 - : 0x08010000 - 4; - *(uint32_t volatile *)(rom_base + offset) = value; -} - -/*..........................................................................*/ -uint32_t BSP_ramRead(int32_t offset, uint32_t fromEnd) { - int32_t const ram_base = (fromEnd == 0U) - ? 0x20000000 - : 0x20002000 - 4; - return *(uint32_t volatile *)(ram_base + offset); -} -/*..........................................................................*/ -void BSP_ramWrite(int32_t offset, uint32_t fromEnd, uint32_t value) { - int32_t const ram_base = (fromEnd == 0U) - ? 0x20000000 - : 0x20002000 - 4; - *(uint32_t volatile *)(ram_base + offset) = value; -} - -/*..........................................................................*/ -void QF_onStartup(void) { - /* set up the SysTick timer to fire at BSP_TICKS_PER_SEC rate */ - //SysTick_Config(SystemCoreClock / BSP_TICKS_PER_SEC); - - /* assign all priority bits for preemption-prio. and none to sub-prio. - * NOTE: this might have been changed by STM32Cube. - */ - NVIC_SetPriorityGrouping(0U); - - /* set priorities of ALL ISRs used in the system, see NOTE1 - * - * !!!!!!!!!!!!!!!!!!!!!!!!!!!! CAUTION !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - * Assign a priority to EVERY ISR explicitly by calling NVIC_SetPriority(). - * DO NOT LEAVE THE ISR PRIORITIES AT THE DEFAULT VALUE! - */ - NVIC_SetPriority(SysTick_IRQn, QF_AWARE_ISR_CMSIS_PRI + 0U); - NVIC_SetPriority(EXTI0_1_IRQn, QF_AWARE_ISR_CMSIS_PRI + 1U); - /* ... */ - - /* enable IRQs... */ - NVIC_EnableIRQ(EXTI0_1_IRQn); -} -/*..........................................................................*/ -void QF_onCleanup(void) { -} -/*..........................................................................*/ -#ifdef QF_ON_CONTEXT_SW -/* NOTE: the context-switch callback is called with interrupts DISABLED */ -void QF_onContextSw(QActive *prev, QActive *next) { - QS_BEGIN_NOCRIT(CONTEXT_SW, 0U) /* no critical section! */ - QS_OBJ(prev); - QS_OBJ(next); - QS_END_NOCRIT() -} -#endif /* QF_ON_CONTEXT_SW */ - -/*..........................................................................*/ -void QK_onIdle(void) { -#ifdef Q_SPY - QS_rxParse(); /* parse all the received bytes */ - QS_doOutput(); -#elif defined NDEBUG - /* Put the CPU and peripherals to the low-power mode. - * you might need to customize the clock management for your application, - * see the datasheet for your particular Cortex-M3 MCU. - */ - __WFI(); /* Wait-For-Interrupt */ -#endif -} - -/* QS callbacks ============================================================*/ -#ifdef Q_SPY - -/*..........................................................................*/ -void QTimeEvt_tick1_( - uint_fast8_t const tickRate, - void const * const sender) -{ - QF_INT_DISABLE(); - /* TODO pend the SysTick */ - *Q_UINT2PTR_CAST(uint32_t, 0xE000ED04U) = (1U << 26U); - QF_INT_ENABLE(); -} - -#endif /* Q_SPY */ - -/*============================================================================ -* NOTE0: -* The MPU protection against NULL-pointer dereferencing sets up a no-access -* MPU region #7 around the NULL address (0x0). The size of this region is set -* to 2**(26+1)==0x0800'0000, because that is the address of Flash in STM32. -* -* REMARK: STM32 MCUs automatically relocate the Flash memory and the Vector -* Table in it to address 0x0800'0000 at startup. However, even though the -* region 0..0x0800'0000 is un-mapped after the relocation, the read access -* is still allowed and causes no CPU exception. Therefore setting up the MPU -* to protect that region is necessary. -*/ diff --git a/test/qk/test_sched/bsp_nucleo-c031c6.c b/test/qk/test_sched/bsp_nucleo-c031c6.c new file mode 100644 index 00000000..54ae3559 --- /dev/null +++ b/test/qk/test_sched/bsp_nucleo-c031c6.c @@ -0,0 +1,346 @@ +//============================================================================ +// Product: BSP for system-testing of QK kernel, NUCLEO-C031C6 board +// Last updated for version 7.3.0 +// Last updated on 2023-07-18 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// This program is open source software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Alternatively, this program may be distributed and modified under the +// terms of Quantum Leaps commercial licenses, which expressly supersede +// the GNU General Public License and are specifically designed for +// licensees interested in retaining the proprietary status of their code. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Contact information: +// +// +//============================================================================ +#include "qpc.h" +#include "bsp.h" + +#include "stm32c0xx.h" // CMSIS-compliant header file for the MCU used +// add other drivers if necessary... + +Q_DEFINE_THIS_FILE + +// Local-scope objects ----------------------------------------------------- +// LED pins available on the board (just one user LED LD4--Green on PA.5) +#define LD4_PIN 5U + +// Button pins available on the board (just one user Button B1 on PC.13) +#define B1_PIN 13U + +#ifdef Q_SPY + // QSpy source IDs + static QSpyId const l_SysTick_Handler = { 100U }; + static QSpyId const l_test_ISR = { 101U }; + + enum AppRecords { // application-specific trace records + CONTEXT_SW = QS_USER1, + TRACE_MSG + }; + +#endif + +// ISRs used in this project =============================================== +void SysTick_Handler(void); // prototype +void SysTick_Handler(void) { + QK_ISR_ENTRY(); // inform QK kernel about entering an ISR + + // process time events for rate 0 + QTIMEEVT_TICK_X(0U, &l_SysTick_Handler); + + QK_ISR_EXIT(); // inform QXK kernel about exiting an ISR +} +//.......................................................................... +void EXTI0_1_IRQHandler(void); // prototype +void EXTI0_1_IRQHandler(void) { // for testing, NOTE03 + QK_ISR_ENTRY(); // inform QXK kernel about entering an ISR + + // for testing... + static QEvt const t1 = QEVT_INITIALIZER(TEST1_SIG); + QACTIVE_PUBLISH(&t1, &l_test_ISR); + + QK_ISR_EXIT(); // inform QK kernel about exiting an ISR +} + +// BSP functions =========================================================== +static void STM32C031C6_MPU_setup(void) { + // The following MPU configuration contains the general STM32 memory model + // as described in the ST AppNote AN4838 "Managing memory protection unit + // in STM32 MCUs", Figure 2. Cortex-M0+/M3/M4/M7 processor memory map. + // + // Please note that the actual STM32 MCUs provide much less Flash and SRAM + // than the maximums configured here. This means that actual MCUs have + // unmapped memory regions (e.g., beyond the actual SRAM). Attempts to + // access these regions causes the HardFault exception, which is the + // desired behavior. + // + static struct { + uint32_t rbar; + uint32_t rasr; + } const mpu_setup[] = { + + { // region #0: Flash: base=0x0000'0000, size=512M=2^(28+1) + 0x00000000U // base address + | MPU_RBAR_VALID_Msk // valid region + | (MPU_RBAR_REGION_Msk & 0U), // region #0 + (28U << MPU_RASR_SIZE_Pos) // 2^(18+1) region + | (0x6U << MPU_RASR_AP_Pos) // PA:ro/UA:ro + | (1U << MPU_RASR_C_Pos) // C=1 + | MPU_RASR_ENABLE_Msk // region enable + }, + + { // region #1: SRAM: base=0x2000'0000, size=512M=2^(28+1) + 0x20000000U // base address + | MPU_RBAR_VALID_Msk // valid region + | (MPU_RBAR_REGION_Msk & 1U), // region #1 + (28U << MPU_RASR_SIZE_Pos) // 2^(28+1) region + | (0x3U << MPU_RASR_AP_Pos) // PA:rw/UA:rw + | (1U << MPU_RASR_XN_Pos) // XN=1 + | (1U << MPU_RASR_S_Pos) // S=1 + | (1U << MPU_RASR_C_Pos) // C=1 + | MPU_RASR_ENABLE_Msk // region enable + }, + + // region #3: (not configured) + { MPU_RBAR_VALID_Msk | (MPU_RBAR_REGION_Msk & 2U), 0U }, + + { // region #3: Peripherals: base=0x4000'0000, size=512M=2^(28+1) + 0x40000000U // base address + | MPU_RBAR_VALID_Msk // valid region + | (MPU_RBAR_REGION_Msk & 3U), // region #3 + (28U << MPU_RASR_SIZE_Pos) // 2^(28+1) region + | (0x3U << MPU_RASR_AP_Pos) // PA:rw/UA:rw + | (1U << MPU_RASR_XN_Pos) // XN=1 + | (1U << MPU_RASR_S_Pos) // S=1 + | (1U << MPU_RASR_B_Pos) // B=1 + | MPU_RASR_ENABLE_Msk // region enable + }, + + { // region #4: Priv. Periph: base=0xE000'0000, size=512M=2^(28+1) + 0xE0000000U // base address + | MPU_RBAR_VALID_Msk // valid region + | (MPU_RBAR_REGION_Msk & 4U), // region #4 + (28U << MPU_RASR_SIZE_Pos) // 2^(28+1) region + | (0x3U << MPU_RASR_AP_Pos) // PA:rw/UA:rw + | (1U << MPU_RASR_XN_Pos) // XN=1 + | (1U << MPU_RASR_S_Pos) // S=1 + | (1U << MPU_RASR_B_Pos) // B=1 + | MPU_RASR_ENABLE_Msk // region enable + }, + + { // region #5: Ext RAM: base=0x6000'0000, size=1G=2^(29+1) + 0x60000000U // base address + | MPU_RBAR_VALID_Msk // valid region + | (MPU_RBAR_REGION_Msk & 5U), // region #5 + (29U << MPU_RASR_SIZE_Pos) // 2^(28+1) region + | (0x3U << MPU_RASR_AP_Pos) // PA:rw/UA:rw + | (1U << MPU_RASR_XN_Pos) // XN=1 + | (1U << MPU_RASR_S_Pos) // S=1 + | (1U << MPU_RASR_B_Pos) // B=1 + | MPU_RASR_ENABLE_Msk // region enable + }, + + { // region #6: Ext Dev: base=0xA000'0000, size=1G=2^(29+1) + 0xA0000000U // base address + | MPU_RBAR_VALID_Msk // valid region + | (MPU_RBAR_REGION_Msk & 6U), // region #6 + (29U << MPU_RASR_SIZE_Pos) // 2^(28+1) region + | (0x3U << MPU_RASR_AP_Pos) // PA:rw/UA:rw + | (1U << MPU_RASR_XN_Pos) // XN=1 + | (1U << MPU_RASR_S_Pos) // S=1 + | (1U << MPU_RASR_B_Pos) // B=1 + | MPU_RASR_ENABLE_Msk // region enable + }, + + { // region #7: NULL-pointer: base=0x000'0000, size=128M=2^(26+1) + // NOTE: this region extends to 0x080'0000, which is where + // the ROM is re-mapped by STM32 + 0x00000000U // base address + | MPU_RBAR_VALID_Msk // valid region + | (MPU_RBAR_REGION_Msk & 7U), // region #7 + (26U << MPU_RASR_SIZE_Pos) // 2^(26+1)=128M region + | (0x0U << MPU_RASR_AP_Pos) // PA:na/UA:na + | (1U << MPU_RASR_XN_Pos) // XN=1 + | MPU_RASR_ENABLE_Msk // region enable + }, + + }; + + MPU->CTRL = 0U; // disable the MPU + for (uint_fast8_t n = 0U; n < Q_DIM(mpu_setup); ++n) { + MPU->RBAR = mpu_setup[n].rbar; + MPU->RASR = mpu_setup[n].rasr; + } + MPU->CTRL = MPU_CTRL_PRIVDEFENA_Msk // enable background region + | MPU_CTRL_ENABLE_Msk; // enable the MPU + __ISB(); + __DSB(); +} +//.......................................................................... +void BSP_init(void) { + // setup the MPU... + STM32C031C6_MPU_setup(); + + // initialize the QS software tracing... + if (QS_INIT((void *)0) == 0U) { + Q_ERROR(); + } + + // dictionaries... + QS_OBJ_DICTIONARY(&l_SysTick_Handler); + QS_OBJ_DICTIONARY(&l_test_ISR); + + QS_USR_DICTIONARY(CONTEXT_SW); + QS_USR_DICTIONARY(TRACE_MSG); +} +//.......................................................................... +void BSP_terminate(int16_t result) { + Q_UNUSED_PAR(result); +} +//.......................................................................... +void BSP_ledOn(void) { + GPIOA->BSRR = (1U << LD4_PIN); // turn LD4 on +} +//.......................................................................... +void BSP_ledOff(void) { + GPIOA->BSRR = (1U << (LD4_PIN + 16U)); // turn LD4 off +} +//.......................................................................... +void BSP_trigISR(void) { + NVIC_SetPendingIRQ(EXTI0_1_IRQn); +} +//.......................................................................... +void BSP_trace(QActive const *thr, char const *msg) { + QS_BEGIN_ID(TRACE_MSG, 0U) + QS_OBJ(thr); + QS_STR(msg); + QS_END() +} +//.......................................................................... +uint32_t BSP_romRead(int32_t offset, uint32_t fromEnd) { + int32_t const rom_base = (fromEnd == 0U) + ? 0x08000000 + : 0x08008000 - 4; + return *(uint32_t volatile *)(rom_base + offset); +} +//.......................................................................... +void BSP_romWrite(int32_t offset, uint32_t fromEnd, uint32_t value) { + int32_t const rom_base = (fromEnd == 0U) + ? 0x08000000 + : 0x08008000 - 4; + *(uint32_t volatile *)(rom_base + offset) = value; +} + +//.......................................................................... +uint32_t BSP_ramRead(int32_t offset, uint32_t fromEnd) { + int32_t const ram_base = (fromEnd == 0U) + ? 0x20000000 + : 0x20003000 - 4; + return *(uint32_t volatile *)(ram_base + offset); +} +//.......................................................................... +void BSP_ramWrite(int32_t offset, uint32_t fromEnd, uint32_t value) { + int32_t const ram_base = (fromEnd == 0U) + ? 0x20000000 + : 0x20003000 - 4; + *(uint32_t volatile *)(ram_base + offset) = value; +} + +//.......................................................................... +void QF_onStartup(void) { + // NOTE: SystemInit() has been already called from the startup code + // but SystemCoreClock needs to be updated + // + SystemCoreClockUpdate(); + + // set up the SysTick timer to fire at BSP_TICKS_PER_SEC rate + //SysTick_Config(SystemCoreClock / BSP_TICKS_PER_SEC); + + // assign all priority bits for preemption-prio. and none to sub-prio. + // NOTE: this might have been changed by STM32Cube. + // + NVIC_SetPriorityGrouping(0U); + + // set priorities of ALL ISRs used in the system + NVIC_SetPriority(SysTick_IRQn, QF_AWARE_ISR_CMSIS_PRI + 0U); + NVIC_SetPriority(EXTI0_1_IRQn, QF_AWARE_ISR_CMSIS_PRI + 1U); + // NOTE: priority of UART IRQ used for QS-RX is set in qutest_port.c + // ... + + // enable IRQs... + NVIC_EnableIRQ(EXTI0_1_IRQn); +} +//.......................................................................... +void QF_onCleanup(void) { +} +//.......................................................................... +#ifdef QF_ON_CONTEXT_SW +// NOTE: the context-switch callback is called with interrupts DISABLED +void QF_onContextSw(QActive *prev, QActive *next) { + QS_BEGIN_INCRIT(CONTEXT_SW, 0U) // in critical section! + QS_OBJ(prev); + QS_OBJ(next); + QS_END_INCRIT() +} +#endif // QF_ON_CONTEXT_SW + +//.......................................................................... +void QK_onIdle(void) { +#ifdef Q_SPY + QS_rxParse(); // parse all the received bytes + QS_doOutput(); +#elif defined NDEBUG + // Put the CPU and peripherals to the low-power mode. + // you might need to customize the clock management for your application, + // see the datasheet for your particular Cortex-M3 MCU. + // + __WFI(); // Wait-For-Interrupt +#endif +} + +// QS callbacks ============================================================ +#ifdef Q_SPY + +//.......................................................................... +void QTimeEvt_tick1_( + uint_fast8_t const tickRate, + void const * const sender) +{ + QF_INT_DISABLE(); + // TODO pend the SysTick + *Q_UINT2PTR_CAST(uint32_t, 0xE000ED04U) = (1U << 26U); + QF_INT_ENABLE(); +} + +#endif // Q_SPY + +//============================================================================ +// NOTE0: +// The MPU protection against NULL-pointer dereferencing sets up a no-access +// MPU region #7 around the NULL address (0x0). The size of this region is set +// to 2**(26+1)==0x0800'0000, because that is the address of Flash in STM32. +// +// REMARK: STM32 MCUs automatically relocate the Flash memory and the Vector +// Table in it to address 0x0800'0000 at startup. However, even though the +// region 0..0x0800'0000 is un-mapped after the relocation, the read access +// is still allowed and causes no CPU exception. Therefore setting up the MPU +// to protect that region is necessary. +// diff --git a/test/qk/test_sched/bsp_nucleo-h743zi.c b/test/qk/test_sched/bsp_nucleo-h743zi.c new file mode 100644 index 00000000..c229b0d1 --- /dev/null +++ b/test/qk/test_sched/bsp_nucleo-h743zi.c @@ -0,0 +1,300 @@ +//============================================================================ +// Product: BSP for system-testing of QK kernel, NUCLEO-H743ZI board +// Last updated for version 7.3.0 +// Last updated on 2023-07-18 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// This program is open source software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Alternatively, this program may be distributed and modified under the +// terms of Quantum Leaps commercial licenses, which expressly supersede +// the GNU General Public License and are specifically designed for +// licensees interested in retaining the proprietary status of their code. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Contact information: +// +// +//============================================================================ +#include "qpc.h" +#include "bsp.h" + +// STM32CubeH7 include files +#include "stm32h7xx_hal.h" +#include "stm32h7xx_nucleo_144.h" +// add other drivers if necessary... + +Q_DEFINE_THIS_FILE + +#ifdef Q_SPY + + // QSpy source IDs + static QSpyId const l_SysTick_Handler = { 100U }; + static QSpyId const l_test_ISR = { 101U }; + + enum AppRecords { // application-specific trace records + CONTEXT_SW = QS_USER1, + TRACE_MSG + }; + +#endif + +// ISRs used in this project =============================================== +void SysTick_Handler(void); // prototype +void SysTick_Handler(void) { + QK_ISR_ENTRY(); // inform QXK kernel about entering an ISR + + // process time events for rate 0 + QTIMEEVT_TICK_X(0U, &l_SysTick_Handler); + + QK_ISR_EXIT(); // inform QXK kernel about exiting an ISR +} +//.......................................................................... +void EXTI0_IRQHandler(void); // prototype +void EXTI0_IRQHandler(void) { // for testing, NOTE03 + QK_ISR_ENTRY(); // inform QXK kernel about entering an ISR + + // for testing... + static QEvt const t1 = QEVT_INITIALIZER(TEST1_SIG); + QACTIVE_PUBLISH(&t1, &l_test_ISR); + + QK_ISR_EXIT(); // inform QXK kernel about exiting an ISR +} + +// BSP functions =========================================================== +//.......................................................................... +// MPU setup for STM32H743ZI MCU +static void STM32H743ZI_MPU_setup(void) { + // The following MPU configuration contains just a generic ROM + // region (with read-only access) and NULL-pointer protection region. + // Otherwise, the MPU will fall back on the background region (PRIVDEFENA). + // + static struct { + uint32_t rbar; + uint32_t rasr; + } const mpu_setup[] = { + + { // region #0: Flash: base=0x0000'0000, size=512M=2^(28+1) + 0x00000000U // base address + | MPU_RBAR_VALID_Msk // valid region + | (MPU_RBAR_REGION_Msk & 0U), // region #0 + (28U << MPU_RASR_SIZE_Pos) // 2^(28+1) region + | (0x6U << MPU_RASR_AP_Pos) // PA:ro/UA:ro + | (1U << MPU_RASR_C_Pos) // C=1 + | MPU_RASR_ENABLE_Msk // region enable + }, + + { // region #7: NULL-pointer: base=0x000'0000, size=128M=2^(26+1) + // NOTE: this region extends to 0x080'0000, which is where + // the ROM is re-mapped by STM32 + // + 0x00000000U // base address + | MPU_RBAR_VALID_Msk // valid region + | (MPU_RBAR_REGION_Msk & 7U), // region #7 + (26U << MPU_RASR_SIZE_Pos) // 2^(26+1)=128M region + | (0x0U << MPU_RASR_AP_Pos) // PA:na/UA:na + | (1U << MPU_RASR_XN_Pos) // XN=1 + | MPU_RASR_ENABLE_Msk // region enable + }, + }; + + // enable the MemManage_Handler for MPU exception + SCB->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk; + + __DSB(); + MPU->CTRL = 0U; // disable the MPU + for (uint_fast8_t n = 0U; n < Q_DIM(mpu_setup); ++n) { + MPU->RBAR = mpu_setup[n].rbar; + MPU->RASR = mpu_setup[n].rasr; + } + MPU->CTRL = MPU_CTRL_ENABLE_Msk // enable the MPU + | MPU_CTRL_PRIVDEFENA_Msk; // enable background region + __ISB(); + __DSB(); +} + +//.......................................................................... +void BSP_init(void) { + // setup the MPU... + STM32H743ZI_MPU_setup(); + + // NOTE: SystemInit() has been already called from the startup code + // but SystemCoreClock needs to be updated + // + SystemCoreClockUpdate(); + + SCB_EnableICache(); // Enable I-Cache + SCB_EnableDCache(); // Enable D-Cache + + // Configure Flash prefetch and Instr. cache through ART accelerator +#if (ART_ACCLERATOR_ENABLE != 0) + __HAL_FLASH_ART_ENABLE(); +#endif // ART_ACCLERATOR_ENABLE + + // Configure the LEDs + BSP_LED_Init(LED1); + BSP_LED_Init(LED2); + BSP_LED_Init(LED3); + + // Configure the User Button in GPIO Mode + BSP_PB_Init(BUTTON_USER, BUTTON_MODE_GPIO); + + if (QS_INIT((void *)0) == 0) { // initialize the QS software tracing + Q_ERROR(); + } + + // dictionaries... + QS_OBJ_DICTIONARY(&l_SysTick_Handler); + QS_OBJ_DICTIONARY(&l_test_ISR); + + QS_USR_DICTIONARY(CONTEXT_SW); + QS_USR_DICTIONARY(TRACE_MSG); +} +//.......................................................................... +void BSP_terminate(int16_t result) { + Q_UNUSED_PAR(result); +} +//.......................................................................... +void BSP_ledOn(void) { + BSP_LED_On(LED1); +} +//.......................................................................... +void BSP_ledOff(void) { + BSP_LED_Off(LED1); +} +//.......................................................................... +void BSP_trigISR(void) { + NVIC_SetPendingIRQ(EXTI0_IRQn); +} +//.......................................................................... +void BSP_trace(QActive const *thr, char const *msg) { + QS_BEGIN_ID(TRACE_MSG, 0U) + QS_OBJ(thr); + QS_STR(msg); + QS_END() +} +//.......................................................................... +uint32_t BSP_romRead(int32_t offset, uint32_t fromEnd) { + int32_t const rom_base = (fromEnd == 0U) + ? 0x08000000 + : 0x08200000 - 4; + return *(uint32_t volatile *)(rom_base + offset); +} +//.......................................................................... +void BSP_romWrite(int32_t offset, uint32_t fromEnd, uint32_t value) { + int32_t const rom_base = (fromEnd == 0U) + ? 0x08000000 + : 0x08200000 - 4; + *(uint32_t volatile *)(rom_base + offset) = value; +} + +//.......................................................................... +uint32_t BSP_ramRead(int32_t offset, uint32_t fromEnd) { + int32_t const ram_base = (fromEnd == 0U) + ? 0x20000000 + : 0x20020000 - 4; + return *(uint32_t volatile *)(ram_base + offset); +} +//.......................................................................... +void BSP_ramWrite(int32_t offset, uint32_t fromEnd, uint32_t value) { + int32_t const ram_base = (fromEnd == 0U) + ? 0x20000000 + : 0x20020000 - 4; + *(uint32_t volatile *)(ram_base + offset) = value; +} + +//.......................................................................... +void QF_onStartup(void) { + // set up the SysTick timer to fire at BSP_TICKS_PER_SEC rate + //NOTE: don't start ticking for these tests + //SysTick_Config(SystemCoreClock / BSP_TICKS_PER_SEC); + + // assign all priority bits for preemption-prio. and none to sub-prio. + // NOTE: this might have been changed by STM32Cube. + // + NVIC_SetPriorityGrouping(0U); + + // set priorities of ALL ISRs used in the system, see NOTE1 + // + // !!!!!!!!!!!!!!!!!!!!!!!!!!!! CAUTION !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + // Assign a priority to EVERY ISR explicitly by calling NVIC_SetPriority(). + // DO NOT LEAVE THE ISR PRIORITIES AT THE DEFAULT VALUE! + // + NVIC_SetPriority(SysTick_IRQn, QF_AWARE_ISR_CMSIS_PRI + 0U); + NVIC_SetPriority(EXTI0_IRQn, QF_AWARE_ISR_CMSIS_PRI + 1U); + // ... + + // enable IRQs... + NVIC_EnableIRQ(EXTI0_IRQn); +} +//.......................................................................... +void QF_onCleanup(void) { +} +//.......................................................................... +#ifdef QF_ON_CONTEXT_SW +// NOTE: the context-switch callback is called with interrupts DISABLED +void QF_onContextSw(QActive *prev, QActive *next) { + QS_BEGIN_INCRIT(CONTEXT_SW, 0U) // in critical section! + QS_OBJ(prev); + QS_OBJ(next); + QS_END_INCRIT() +} +#endif // QF_ON_CONTEXT_SW + +//.......................................................................... +void QK_onIdle(void) { +#ifdef Q_SPY + QS_rxParse(); // parse all the received bytes + QS_doOutput(); +#elif defined NDEBUG + // Put the CPU and peripherals to the low-power mode. + // you might need to customize the clock management for your application, + // see the datasheet for your particular Cortex-M3 MCU. + // + __WFI(); // Wait-For-Interrupt +#endif +} + +// QS callbacks ============================================================ +#ifdef Q_SPY + +//.......................................................................... +void QTimeEvt_tick1_( + uint_fast8_t const tickRate, + void const * const sender) +{ + QF_INT_DISABLE(); + // TODO pend the SysTick + *Q_UINT2PTR_CAST(uint32_t, 0xE000ED04U) = (1U << 26U); + QF_INT_ENABLE(); +} + +#endif // Q_SPY + +//============================================================================ +// NOTE0: +// The MPU protection against NULL-pointer dereferencing sets up a no-access +// MPU region #7 around the NULL address (0x0). The size of this region is set +// to 2**(26+1)==0x0800'0000, because that is the address of Flash in STM32. +// +// REMARK: STM32 MCUs automatically relocate the Flash memory and the Vector +// Table in it to address 0x0800'0000 at startup. However, even though the +// region 0..0x0800'0000 is un-mapped after the relocation, the read access +// is still allowed and causes no CPU exception. Therefore setting up the MPU +// to protect that region is necessary. +// diff --git a/test/qk/test_sched/bsp_nucleo-l053r8.c b/test/qk/test_sched/bsp_nucleo-l053r8.c new file mode 100644 index 00000000..ac2e868b --- /dev/null +++ b/test/qk/test_sched/bsp_nucleo-l053r8.c @@ -0,0 +1,365 @@ +//============================================================================ +// Product: BSP for system-testing of QK kernel, NUCLEO-L053R8 board +// Last updated for version 7.3.0 +// Last updated on 2023-07-18 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// This program is open source software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Alternatively, this program may be distributed and modified under the +// terms of Quantum Leaps commercial licenses, which expressly supersede +// the GNU General Public License and are specifically designed for +// licensees interested in retaining the proprietary status of their code. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Contact information: +// +// +//============================================================================ +#include "qpc.h" +#include "bsp.h" + +#include "stm32l0xx.h" // CMSIS-compliant header file for the MCU used +// add other drivers if necessary... + +Q_DEFINE_THIS_FILE + +// Local-scope objects ----------------------------------------------------- +// LED pins available on the board (just one user LED LD2--Green on PA.5) +#define LED_LD2 (1U << 5) + +// Button pins available on the board (just one user Button B1 on PC.13) +#define BTN_B1 (1U << 13) + +#ifdef Q_SPY + // QSpy source IDs + static QSpyId const l_SysTick_Handler = { 100U }; + static QSpyId const l_test_ISR = { 101U }; + + enum AppRecords { // application-specific trace records + CONTEXT_SW = QS_USER1, + TRACE_MSG + }; + +#endif + +// ISRs used in this project =============================================== +void SysTick_Handler(void); // prototype +void SysTick_Handler(void) { + QK_ISR_ENTRY(); // inform QK kernel about entering an ISR + + // process time events for rate 0 + QTIMEEVT_TICK_X(0U, &l_SysTick_Handler); + + QK_ISR_EXIT(); // inform QK kernel about exiting an ISR +} +//.......................................................................... +void EXTI0_1_IRQHandler(void); // prototype +void EXTI0_1_IRQHandler(void) { // for testing, NOTE03 + QK_ISR_ENTRY(); // inform QK kernel about entering an ISR + + // for testing... + static QEvt const t1 = QEVT_INITIALIZER(TEST1_SIG); + QACTIVE_PUBLISH(&t1, &l_test_ISR); + + QK_ISR_EXIT(); // inform QK kernel about exiting an ISR +} + +// BSP functions =========================================================== +static void STM32L053R8_MPU_setup(void) { + // The following MPU configuration contains the general STM32 memory model + // as described in the ST AppNote AN4838 "Managing memory protection unit + // in STM32 MCUs", Figure 2. Cortex-M0+/M3/M4/M7 processor memory map. + // + // Please note that the actual STM32 MCUs provide much less Flash and SRAM + // than the maximums configured here. This means that actual MCUs have + // unmapped memory regions (e.g., beyond the actual SRAM). Attempts to + // access these regions causes the HardFault exception, which is the + // desired behavior. + // + static struct { + uint32_t rbar; + uint32_t rasr; + } const mpu_setup[] = { + + { // region #0: Flash: base=0x0000'0000, size=512M=2^(28+1) + 0x00000000U // base address + | MPU_RBAR_VALID_Msk // valid region + | (MPU_RBAR_REGION_Msk & 0U), // region #0 + (28U << MPU_RASR_SIZE_Pos) // 2^(18+1) region + | (0x6U << MPU_RASR_AP_Pos) // PA:ro/UA:ro + | (1U << MPU_RASR_C_Pos) // C=1 + | MPU_RASR_ENABLE_Msk // region enable + }, + + { // region #1: SRAM: base=0x2000'0000, size=512M=2^(28+1) + 0x20000000U // base address + | MPU_RBAR_VALID_Msk // valid region + | (MPU_RBAR_REGION_Msk & 1U), // region #1 + (28U << MPU_RASR_SIZE_Pos) // 2^(28+1) region + | (0x3U << MPU_RASR_AP_Pos) // PA:rw/UA:rw + | (1U << MPU_RASR_XN_Pos) // XN=1 + | (1U << MPU_RASR_S_Pos) // S=1 + | (1U << MPU_RASR_C_Pos) // C=1 + | MPU_RASR_ENABLE_Msk // region enable + }, + + // region #3: (not configured) + { MPU_RBAR_VALID_Msk | (MPU_RBAR_REGION_Msk & 2U), 0U }, + + { // region #3: Peripherals: base=0x4000'0000, size=512M=2^(28+1) + 0x40000000U // base address + | MPU_RBAR_VALID_Msk // valid region + | (MPU_RBAR_REGION_Msk & 3U), // region #3 + (28U << MPU_RASR_SIZE_Pos) // 2^(28+1) region + | (0x3U << MPU_RASR_AP_Pos) // PA:rw/UA:rw + | (1U << MPU_RASR_XN_Pos) // XN=1 + | (1U << MPU_RASR_S_Pos) // S=1 + | (1U << MPU_RASR_B_Pos) // B=1 + | MPU_RASR_ENABLE_Msk // region enable + }, + + { // region #4: Priv. Periph: base=0xE000'0000, size=512M=2^(28+1) + 0xE0000000U // base address + | MPU_RBAR_VALID_Msk // valid region + | (MPU_RBAR_REGION_Msk & 4U), // region #4 + (28U << MPU_RASR_SIZE_Pos) // 2^(28+1) region + | (0x3U << MPU_RASR_AP_Pos) // PA:rw/UA:rw + | (1U << MPU_RASR_XN_Pos) // XN=1 + | (1U << MPU_RASR_S_Pos) // S=1 + | (1U << MPU_RASR_B_Pos) // B=1 + | MPU_RASR_ENABLE_Msk // region enable + }, + + { // region #5: Ext RAM: base=0x6000'0000, size=1G=2^(29+1) + 0x60000000U // base address + | MPU_RBAR_VALID_Msk // valid region + | (MPU_RBAR_REGION_Msk & 5U), // region #5 + (29U << MPU_RASR_SIZE_Pos) // 2^(28+1) region + | (0x3U << MPU_RASR_AP_Pos) // PA:rw/UA:rw + | (1U << MPU_RASR_XN_Pos) // XN=1 + | (1U << MPU_RASR_S_Pos) // S=1 + | (1U << MPU_RASR_B_Pos) // B=1 + | MPU_RASR_ENABLE_Msk // region enable + }, + + { // region #6: Ext Dev: base=0xA000'0000, size=1G=2^(29+1) + 0xA0000000U // base address + | MPU_RBAR_VALID_Msk // valid region + | (MPU_RBAR_REGION_Msk & 6U), // region #6 + (29U << MPU_RASR_SIZE_Pos) // 2^(28+1) region + | (0x3U << MPU_RASR_AP_Pos) // PA:rw/UA:rw + | (1U << MPU_RASR_XN_Pos) // XN=1 + | (1U << MPU_RASR_S_Pos) // S=1 + | (1U << MPU_RASR_B_Pos) // B=1 + | MPU_RASR_ENABLE_Msk // region enable + }, + + { // region #7: NULL-pointer: base=0x000'0000, size=128M=2^(26+1) + // NOTE: this region extends to 0x080'0000, which is where + // the ROM is re-mapped by STM32 + // + 0x00000000U // base address + | MPU_RBAR_VALID_Msk // valid region + | (MPU_RBAR_REGION_Msk & 7U), // region #7 + (26U << MPU_RASR_SIZE_Pos) // 2^(26+1)=128M region + | (0x0U << MPU_RASR_AP_Pos) // PA:na/UA:na + | (1U << MPU_RASR_XN_Pos) // XN=1 + | MPU_RASR_ENABLE_Msk // region enable + }, + + }; + + MPU->CTRL = 0U; // disable the MPU + for (uint_fast8_t n = 0U; n < Q_DIM(mpu_setup); ++n) { + MPU->RBAR = mpu_setup[n].rbar; + MPU->RASR = mpu_setup[n].rasr; + } + MPU->CTRL = MPU_CTRL_PRIVDEFENA_Msk // enable background region + | MPU_CTRL_ENABLE_Msk; // enable the MPU + __ISB(); + __DSB(); +} +//.......................................................................... +void BSP_init(void) { + // setup the MPU... + STM32L053R8_MPU_setup(); + + // NOTE: SystemInit() has been already called from the startup code + // but SystemCoreClock needs to be updated + // + SystemCoreClockUpdate(); + + // enable GPIOA clock port for the LED LD2 + RCC->IOPENR |= (1U << 0); + + // configure LED (PA.5) pin as push-pull output, no pull-up, pull-down + GPIOA->MODER &= ~((3U << 2*5)); + GPIOA->MODER |= ((1U << 2*5)); + GPIOA->OTYPER &= ~((1U << 5)); + GPIOA->OSPEEDR &= ~((3U << 2*5)); + GPIOA->OSPEEDR |= ((1U << 2*5)); + GPIOA->PUPDR &= ~((3U << 2*5)); + + // enable GPIOC clock port for the Button B1 + RCC->IOPENR |= (1U << 2); + + // configure Button (PC.13) pins as input, no pull-up, pull-down + GPIOC->MODER &= ~(3U << 2*13); + GPIOC->OSPEEDR &= ~(3U << 2*13); + GPIOC->OSPEEDR |= (1U << 2*13); + GPIOC->PUPDR &= ~(3U << 2*13); + + // initialize the QS software tracing... + if (QS_INIT((void *)0) == 0) { // initialize the QS software tracing + Q_ERROR(); + } + + // dictionaries... + QS_OBJ_DICTIONARY(&l_SysTick_Handler); + QS_OBJ_DICTIONARY(&l_test_ISR); + + QS_USR_DICTIONARY(CONTEXT_SW); + QS_USR_DICTIONARY(TRACE_MSG); +} +//.......................................................................... +void BSP_terminate(int16_t result) { + Q_UNUSED_PAR(result); +} +//.......................................................................... +void BSP_ledOn(void) { + GPIOA->BSRR = (LED_LD2); // turn LED2 on +} +//.......................................................................... +void BSP_ledOff(void) { + GPIOA->BSRR = (LED_LD2 << 16); // turn LED2 off +} +//.......................................................................... +void BSP_trigISR(void) { + NVIC_SetPendingIRQ(EXTI0_1_IRQn); +} +//.......................................................................... +void BSP_trace(QActive const *thr, char const *msg) { + QS_BEGIN_ID(TRACE_MSG, 0U) + QS_OBJ(thr); + QS_STR(msg); + QS_END() +} +//.......................................................................... +uint32_t BSP_romRead(int32_t offset, uint32_t fromEnd) { + int32_t const rom_base = (fromEnd == 0U) + ? 0x08000000 + : 0x08010000 - 4; + return *(uint32_t volatile *)(rom_base + offset); +} +//.......................................................................... +void BSP_romWrite(int32_t offset, uint32_t fromEnd, uint32_t value) { + int32_t const rom_base = (fromEnd == 0U) + ? 0x08000000 + : 0x08010000 - 4; + *(uint32_t volatile *)(rom_base + offset) = value; +} + +//.......................................................................... +uint32_t BSP_ramRead(int32_t offset, uint32_t fromEnd) { + int32_t const ram_base = (fromEnd == 0U) + ? 0x20000000 + : 0x20002000 - 4; + return *(uint32_t volatile *)(ram_base + offset); +} +//.......................................................................... +void BSP_ramWrite(int32_t offset, uint32_t fromEnd, uint32_t value) { + int32_t const ram_base = (fromEnd == 0U) + ? 0x20000000 + : 0x20002000 - 4; + *(uint32_t volatile *)(ram_base + offset) = value; +} + +//.......................................................................... +void QF_onStartup(void) { + // DON'T set up the SysTick timer to fire at BSP_TICKS_PER_SEC rate + //SysTick_Config(SystemCoreClock / BSP_TICKS_PER_SEC); + + // assign all priority bits for preemption-prio. and none to sub-prio. + NVIC_SetPriorityGrouping(0U); + + // set priorities of ALL ISRs used in the system + NVIC_SetPriority(SysTick_IRQn, QF_AWARE_ISR_CMSIS_PRI + 0U); + NVIC_SetPriority(EXTI0_1_IRQn, QF_AWARE_ISR_CMSIS_PRI + 1U); + // NOTE: priority of UART IRQ used for QS-RX is set in qutest_port.c + // ... + + // enable IRQs... + NVIC_EnableIRQ(EXTI0_1_IRQn); +} +//.......................................................................... +void QF_onCleanup(void) { +} +//.......................................................................... +#ifdef QF_ON_CONTEXT_SW +// NOTE: the context-switch callback is called with interrupts DISABLED +void QF_onContextSw(QActive *prev, QActive *next) { + QS_BEGIN_INCRIT(CONTEXT_SW, 0U) // in critical section! + QS_OBJ(prev); + QS_OBJ(next); + QS_END_INCRIT() +} +#endif // QF_ON_CONTEXT_SW + +//.......................................................................... +void QK_onIdle(void) { +#ifdef Q_SPY + QS_rxParse(); // parse all the received bytes + QS_doOutput(); +#elif defined NDEBUG + // Put the CPU and peripherals to the low-power mode. + // you might need to customize the clock management for your application, + // see the datasheet for your particular Cortex-M3 MCU. + // + __WFI(); // Wait-For-Interrupt +#endif +} + +// QS callbacks ============================================================ +#ifdef Q_SPY + +//.......................................................................... +void QTimeEvt_tick1_( + uint_fast8_t const tickRate, + void const * const sender) +{ + QF_INT_DISABLE(); + // TODO pend the SysTick + *Q_UINT2PTR_CAST(uint32_t, 0xE000ED04U) = (1U << 26U); + QF_INT_ENABLE(); +} + +#endif // Q_SPY + +//============================================================================ +// NOTE0: +// The MPU protection against NULL-pointer dereferencing sets up a no-access +// MPU region #7 around the NULL address (0x0). The size of this region is set +// to 2**(26+1)==0x0800'0000, because that is the address of Flash in STM32. +// +// REMARK: STM32 MCUs automatically relocate the Flash memory and the Vector +// Table in it to address 0x0800'0000 at startup. However, even though the +// region 0..0x0800'0000 is un-mapped after the relocation, the read access +// is still allowed and causes no CPU exception. Therefore setting up the MPU +// to protect that region is necessary. +// diff --git a/test/qk/test_sched/make_efm32 b/test/qk/test_sched/efm32pg1b.mak similarity index 93% rename from test/qk/test_sched/make_efm32 rename to test/qk/test_sched/efm32pg1b.mak index 0cbed835..036f2bb5 100644 --- a/test/qk/test_sched/make_efm32 +++ b/test/qk/test_sched/efm32pg1b.mak @@ -1,7 +1,7 @@ ############################################################################## # Product: Makefile for SYSTEM-Level tests of QP/C on EMF32, GNU-ARM -# Last Updated for Version: 7.2.0 -# Date of the Last Update: 2022-12-21 +# Last Updated for Version: 7.3.0 +# Date of the Last Update: 2023-09-06 # # Q u a n t u m L e a P s # ------------------------ @@ -33,12 +33,12 @@ ############################################################################## # # examples of invoking this Makefile: -# make -f make_efm32 # make and run the tests in the current directory -# make -f make_efm32 TESTS=thr*.py # make and run the selected tests -# make -f make_efm32 HOST=localhost:7705 # connect to host:port -# make -f make_efm32 norun # only make but not run the tests -# make -f make_efm32 clean # cleanup the build -# make -f make_efm32 debug # only run tests in DEBUG mode +# make -f efm32pg1b.mak # make and run the tests in the current directory +# make -f efm32pg1b.mak TESTS=thr*.py # make and run the selected tests +# make -f efm32pg1b.mak HOST=localhost:7705 # connect to host:port +# make -f efm32pg1b.mak norun # only make but not run the tests +# make -f efm32pg1b.mak clean # cleanup the build +# make -f efm32pg1b.mak debug # only run tests in DEBUG mode # # NOTE: # To use this Makefile on Windows, you will need the GNU make utility, which @@ -99,7 +99,7 @@ ASM_SRCS := # C source files C_SRCS := \ test_sched.c \ - bsp_efm32.c \ + bsp_efm32pg1b.c \ startup_efm32pg1b.c \ system_efm32pg1b.c \ em_cmu.c \ @@ -245,7 +245,7 @@ endif # rules # -.PHONY : run norun flash +.PHONY : run norun debug flash ifeq ($(MAKECMDGOALS),norun) all : $(TARGET_BIN) @@ -259,7 +259,7 @@ $(TARGET_BIN) : $(TARGET_ELF) $(FLASH) $@ $(TARGET_ELF) : $(ASM_OBJS_EXT) $(C_OBJS_EXT) $(CPP_OBJS_EXT) - $(CC) $(CFLAGS) $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o + $(CC) $(CFLAGS) $(QPC)/src/qs/qstamp.c -o $(BIN_DIR)/qstamp.o $(LINK) $(LINKFLAGS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) flash : diff --git a/test/qk/test_sched/uvision_efm32.uvoptx b/test/qk/test_sched/efm32pg1b.uvoptx similarity index 99% rename from test/qk/test_sched/uvision_efm32.uvoptx rename to test/qk/test_sched/efm32pg1b.uvoptx index 5e7c7f38..a8afe1c3 100644 --- a/test/qk/test_sched/uvision_efm32.uvoptx +++ b/test/qk/test_sched/efm32pg1b.uvoptx @@ -316,8 +316,8 @@ 0 0 0 - .\bsp_efm32.c - bsp_efm32.c + .\test_sched.c + test_sched.c 0 0 @@ -328,8 +328,8 @@ 0 0 0 - .\test_sched.c - test_sched.c + .\bsp_efm32pg1b.c + bsp_efm32pg1b.c 0 0 @@ -459,12 +459,12 @@ 3 - 13 + 16 1 0 0 0 - ..\..\..\src\qf\qf_act.c + ..\..\..\..\..\src\qf\qf_act.c qf_act.c 0 0 diff --git a/test/qk/test_sched/uvision_efm32.uvprojx b/test/qk/test_sched/efm32pg1b.uvprojx similarity index 99% rename from test/qk/test_sched/uvision_efm32.uvprojx rename to test/qk/test_sched/efm32pg1b.uvprojx index 4cbe70e4..22cf497e 100644 --- a/test/qk/test_sched/uvision_efm32.uvprojx +++ b/test/qk/test_sched/efm32pg1b.uvprojx @@ -388,16 +388,16 @@ 5 .\bsp.h - - bsp_efm32.c - 1 - .\bsp_efm32.c - test_sched.c 1 .\test_sched.c + + bsp_efm32pg1b.c + 1 + .\bsp_efm32pg1b.c +
@@ -456,7 +456,7 @@ qf_act.c 1 - ..\..\..\src\qf\qf_act.c + ..\..\..\..\..\src\qf\qf_act.c qf_actq.c diff --git a/test/qk/test_sched/nucleo-c031c6.mak b/test/qk/test_sched/nucleo-c031c6.mak new file mode 100644 index 00000000..18a2613c --- /dev/null +++ b/test/qk/test_sched/nucleo-c031c6.mak @@ -0,0 +1,336 @@ +############################################################################## +# Product: Makefile for SYSTEM-Level tests of QP/C on NUCLEO-c031c6, GNU-ARM +# Last Updated for Version: 7.2.2 +# Date of the Last Update: 2023-02-02 +# +# Q u a n t u m L e a P s +# ------------------------ +# Modern Embedded Software +# +# Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +# +# This program is open source software: you can redistribute it and/or +# modify it under the terms of the GNU General Public License as published +# by the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Alternatively, this program may be distributed and modified under the +# terms of Quantum Leaps commercial licenses, which expressly supersede +# the GNU General Public License and are specifically designed for +# licensees interested in retaining the proprietary status of their code. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# +# Contact information: +# +# +############################################################################## +# +# examples of invoking this Makefile: +# make -f nucleo-c031c6.mak USB=g: # make, uplaod to USB drive, run the tests +# make -f nucleo-c031c6.mak USB=g: TESTS=philo*.py # make and run the selected tests +# make -f nucleo-c031c6.mak HOST=localhost:7705 # connect to host:port +# make -f nucleo-c031c6.mak norun # only make but not run the tests +# make -f nucleo-c031c6.mak clean # cleanup the build +# make -f nucleo-c031c6.mak debug # only run tests in DEBUG mode +# +# NOTE: +# To use this Makefile on Windows, you will need the GNU make utility, which +# is included in the QTools collection for Windows, see: +# https://github.com/QuantumLeaps/qtools +# + +# location of the QP/C framework (if not provided in an env. variable) +ifeq ($(QPC),) +QPC := ../../.. +endif + +#----------------------------------------------------------------------------- +# project name, target name, target directory: +# +PROJECT := test_sched +TARGET := nucleo-c031c6 +TARGET_DIR := $(QPC)/3rd_party/nucleo-c031c6/qutest + +#----------------------------------------------------------------------------- +# project directories: +# + +# QP port used in this project +QP_PORT_DIR := $(QPC)/ports/arm-cm/qk/gnu + +# make sure that QTOOLS env. variable is defined... +ifeq ("$(wildcard $(QTOOLS))","") +$(error QTOOLS not found. Please install QTools and define QTOOLS env. variable) +endif + + +# list of all source directories used by this project +VPATH := . \ + $(QPC)/src/qf \ + $(QPC)/src/qk \ + $(QPC)/src/qs \ + $(QP_PORT_DIR) \ + $(TARGET_DIR) \ + $(QPC)/3rd_party/nucleo-c031c6 \ + $(QPC)/3rd_party/nucleo-c031c6/gnu + +# list of all include directories needed by this project +INCLUDES = -I. \ + -I$(QPC)/include \ + -I$(QP_PORT_DIR) \ + -I$(TARGET_DIR) \ + -I$(QPC)/3rd_party/CMSIS/Include \ + -I$(QPC)/3rd_party/nucleo-c031c6 + +#----------------------------------------------------------------------------- +# project files: +# + +# assembler source files +ASM_SRCS := + +# C source files +C_SRCS := \ + test_sched.c \ + bsp_nucleo-c031c6.c \ + system_stm32c0xx.c \ + startup_stm32c031xx.c + +# C++ source files +CPP_SRCS := + +OUTPUT := $(PROJECT) +LD_SCRIPT := $(TARGET_DIR)/qutest.ld + +QP_SRCS := \ + qep_hsm.c \ + qep_msm.c \ + qf_act.c \ + qf_actq.c \ + qf_defer.c \ + qf_dyn.c \ + qf_mem.c \ + qf_ps.c \ + qf_qact.c \ + qf_qeq.c \ + qf_qmact.c \ + qf_time.c \ + qk.c \ + qk_port.c \ + qs.c \ + qs_64bit.c \ + qs_rx.c \ + qs_fp.c \ + qutest.c \ + qutest_port.c + +QP_ASMS := + +LIB_DIRS := +LIBS := + +# defines +DEFINES := -DSTM32C031xx \ + -DQP_API_VERSION=9999 \ + -DQK_USE_IRQ_HANDLER=Reserved1_IRQHandler \ + -DQK_USE_IRQ_NUM=1 \ + -DQF_ON_CONTEXT_SW + +# ARM CPU, ARCH, FPU, and Float-ABI types... +# ARM_CPU: [cortex-m0 | cortex-m0plus | cortex-m1 | cortex-m3 | cortex-m4] +# ARM_FPU: [ | vfp] +# FLOAT_ABI: [ | soft | softfp | hard] +# +ARM_CPU := -mcpu=cortex-m0plus +ARM_FPU := +FLOAT_ABI := + +#----------------------------------------------------------------------------- +# GNU-ARM toolset (NOTE: You need to adjust to your machine) +# see https://developer.arm.com/open-source/gnu-toolchain/gnu-rm/downloads +# +ifeq ($(GNU_ARM),) +GNU_ARM := $(QTOOLS)/gnu_arm-none-eabi +endif + +# make sure that the GNU-ARM toolset exists... +ifeq ("$(wildcard $(GNU_ARM))","") +$(error GNU_ARM toolset not found. Please adjust the Makefile) +endif + +CC := $(GNU_ARM)/bin/arm-none-eabi-gcc +CPP := $(GNU_ARM)/bin/arm-none-eabi-g++ +AS := $(GNU_ARM)/bin/arm-none-eabi-as +LINK := $(GNU_ARM)/bin/arm-none-eabi-gcc +BIN := $(GNU_ARM)/bin/arm-none-eabi-objcopy + +#----------------------------------------------------------------------------- +# NOTE: The symbol USB must be provided for the NUCLEO board +# has enumerated as USB drive f: +# +ifeq ($(USB),) +$(error USB drive not provided for the NUCLEO board.) +endif + +############################################################################## +# Typically you should not need to change anything below this line + +# basic utilities (included in QTools for Windows), see: +# https://www.state-machine.com/qtools + +MKDIR := mkdir +RM := rm +CP := cp +SLEEP := sleep + +#----------------------------------------------------------------------------- +# QUTest test script utilities (requires QTOOLS): +# +ifeq ("$(wildcard $(QUTEST))","") +QUTEST := python3 $(QTOOLS)/qutest/qutest.py +endif + +#----------------------------------------------------------------------------- +# build options +# + +# combine all the soruces... +C_SRCS += $(QP_SRCS) +ASM_SRCS += $(QP_ASMS) + +BIN_DIR := build_$(TARGET) + +ASFLAGS = -g $(ARM_CPU) $(ARM_FPU) $(ASM_CPU) $(ASM_FPU) + + +# NOTE: +# Setting -DQ_UTEST=0 means that QUTest should be built WITHOUT +# the QP-stub for testing QP itself +# +CFLAGS = -c -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \ + -ffunction-sections -fdata-sections \ + -O $(INCLUDES) $(DEFINES) -DQ_SPY -DQ_UTEST=0 + +CPPFLAGS = -c -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \ + -ffunction-sections -fdata-sections -fno-rtti -fno-exceptions \ + -O $(INCLUDES) $(DEFINES) -DQ_SPY -DQ_UTEST=0 + + +LINKFLAGS = -T$(LD_SCRIPT) $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb \ + -specs=nosys.specs -specs=nano.specs \ + -Wl,-Map,$(BIN_DIR)/$(OUTPUT).map,--cref,--gc-sections $(LIB_DIRS) + +ASM_OBJS := $(patsubst %.s,%.o, $(notdir $(ASM_SRCS))) +C_OBJS := $(patsubst %.c,%.o, $(notdir $(C_SRCS))) +CPP_OBJS := $(patsubst %.cpp,%.o,$(notdir $(CPP_SRCS))) + +TARGET_BIN := $(BIN_DIR)/$(OUTPUT).bin +TARGET_ELF := $(BIN_DIR)/$(OUTPUT).elf +ASM_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(ASM_OBJS)) +C_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(C_OBJS)) +C_DEPS_EXT := $(patsubst %.o, %.d, $(C_OBJS_EXT)) +CPP_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(CPP_OBJS)) +CPP_DEPS_EXT := $(patsubst %.o, %.d, $(CPP_OBJS_EXT)) + +# create $(BIN_DIR) if it does not exist +ifeq ("$(wildcard $(BIN_DIR))","") +$(shell $(MKDIR) $(BIN_DIR)) +endif + +#----------------------------------------------------------------------------- +# rules +# + +.PHONY : run norun debug flash + +ifeq ($(MAKECMDGOALS),norun) +all : $(TARGET_BIN) +norun : all +else +all : $(TARGET_BIN) run +endif + +$(TARGET_BIN) : $(TARGET_ELF) + $(BIN) -O binary $< $@ + $(CP) $@ $(USB) + $(SLEEP) 2 + +$(TARGET_ELF) : $(ASM_OBJS_EXT) $(C_OBJS_EXT) $(CPP_OBJS_EXT) + $(CC) $(CFLAGS) $(QPC)/src/qs/qstamp.c -o $(BIN_DIR)/qstamp.o + $(LINK) $(LINKFLAGS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) + +flash : + $(CP) $(TARGET_BIN) $(USB) + +run : $(TARGET_BIN) + $(QUTEST) -q$(QSPY) -l$(LOG) -o$(OPT) -- $(TESTS) + +$(BIN_DIR)/%.d : %.c + $(CC) -MM -MT $(@:.d=.o) $(CFLAGS) $< > $@ + +$(BIN_DIR)/%.d : %.cpp + $(CPP) -MM -MT $(@:.d=.o) $(CPPFLAGS) $< > $@ + +$(BIN_DIR)/%.o : %.s + $(AS) $(ASFLAGS) $< -o $@ + +$(BIN_DIR)/%.o : %.c + $(CC) $(CFLAGS) $< -o $@ + +$(BIN_DIR)/%.o : %.cpp + $(CPP) $(CPPFLAGS) $< -o $@ + +# create BIN_DIR and include dependencies only if needed +ifneq ($(MAKECMDGOALS),clean) + ifneq ($(MAKECMDGOALS),show) + ifneq ($(MAKECMDGOALS),debug) +ifeq ("$(wildcard $(BIN_DIR))","") +$(shell $(MKDIR) $(BIN_DIR)) +endif +-include $(C_DEPS_EXT) $(CPP_DEPS_EXT) + endif + endif +endif + +debug : + $(QUTEST) -edebug -q$(QSPY) -l$(LOG) -o$(OPT) -- $(TESTS) + +.PHONY : clean show + +clean : + -$(RM) $(BIN_DIR)/*.o \ + $(BIN_DIR)/*.d \ + $(BIN_DIR)/*.bin \ + $(BIN_DIR)/*.elf \ + $(BIN_DIR)/*.map + +show : + @echo PROJECT = $(PROJECT) + @echo MAKECMDGOALS = $(MAKECMDGOALS) + @echo TESTS = $(TESTS) + @echo TARGET_ELF = $(TARGET_ELF) + @echo CONF = $(CONF) + @echo VPATH = $(VPATH) + @echo C_SRCS = $(C_SRCS) + @echo CPP_SRCS = $(CPP_SRCS) + @echo ASM_SRCS = $(ASM_SRCS) + @echo C_DEPS_EXT = $(C_DEPS_EXT) + @echo C_OBJS_EXT = $(C_OBJS_EXT) + @echo CPP_DEPS_EXT = $(CPP_DEPS_EXT) + @echo CPP_OBJS_EXT = $(CPP_OBJS_EXT) + @echo ASM_OBJS_EXT = $(ASM_OBJS_EXT) + @echo LIB_DIRS = $(LIB_DIRS) + @echo LIBS = $(LIBS) + @echo DEFINES = $(DEFINES) + @echo QTOOLS = $(QTOOLS) + @echo HOST = $(HOST) + @echo QUTEST = $(QUTEST) + @echo TESTS = $(TESTS) + diff --git a/test/qk/test_sched/nucleo-c031c6.uvoptx b/test/qk/test_sched/nucleo-c031c6.uvoptx new file mode 100644 index 00000000..72ecd998 --- /dev/null +++ b/test/qk/test_sched/nucleo-c031c6.uvoptx @@ -0,0 +1,668 @@ + + + + 1.0 + +
### uVision Project, (C) Keil Software
+ + + *.c + *.s*; *.src; *.a* + *.obj; *.o + *.lib + *.txt; *.h; *.inc; *.md + *.plm + *.cpp + 0 + + + + 0 + 0 + + + + qutest + 0x4 + ARM-ADS + + 12000000 + + 1 + 1 + 1 + 0 + 0 + + + 1 + 65535 + 0 + 0 + 0 + + + 79 + 66 + 8 + .\uvision_nucleo-c031c6\ + + + 1 + 1 + 1 + 0 + 1 + 1 + 0 + 1 + 0 + 0 + 0 + 0 + + + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + + + 1 + 0 + 1 + + 18 + + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + 0 + 1 + 1 + 0 + 0 + 1 + 0 + 0 + 6 + + + + + + + + + + + STLink\ST-LINKIII-KEIL_SWO.dll + + + + 0 + ST-LINKIII-KEIL_SWO + -U066BFF505153848667095842 -O207 -SF10000 -C0 -A0 -I0 -HNlocalhost -HP7184 -P1 -N00("ARM CoreSight SW-DP (ARM Core") -D00(0BC11477) -L00(0) -TO131090 -TC10000000 -TT10000000 -TP21 -TDS8007 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -FO7 -FD20000000 -FC1000 -FN1 -FF0STM32C0x_32.FLM -FS08000000 -FL08000 -FP0($$Device:STM32C031C6Tx$CMSIS\Flash\STM32C0x_32.FLM) + + + 0 + UL2CM3 + -O207 -S0 -C0 -FO7 -FN1 -FC1000 -FD20000000 -FF0STM32C0x_32 -FL08000 -FS08000000 -FP0($$Device:STM32C031C6Tx$CMSIS\Flash\STM32C0x_32.FLM) + + + 0 + DLGUARM + (105=-1,-1,-1,-1,0) + + + 0 + ARMRTXEVENTFLAGS + -L70 -Z18 -C0 -M0 -T1 + + + 0 + DLGTARM + (1010=1173,620,1584,1122,1)(1007=-1,-1,-1,-1,0)(1008=-1,-1,-1,-1,0)(1012=-1,-1,-1,-1,0)(1009=-1,-1,-1,-1,0) + + + 0 + ARMDBGFLAGS + + + + + + 0 + 0 + 316 + 1 +
134218224
+ 0 + 0 + 0 + 0 + 0 + 1 + ..\..\..\3rd_party\nucleo-c031c6\arm\startup_stm32c031xx.s + + \\test\../../../3rd_party/nucleo-c031c6/arm/startup_stm32c031xx.s\316 +
+
+ + + 0 + 1 + QS_rxPriv_ + + + + + 1 + 2 + 0x20000200 + 0 + + + + + 2 + 0 + 0x400 + 0 + + + + 0 + + + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + + + + 0 + 0 + 0 + + + + + + + + + + 1 + 0 + 0 + 2 + 10000000 + +
+
+ + + test + 1 + 0 + 0 + 0 + + 1 + 1 + 5 + 0 + 0 + 0 + .\bsp.h + bsp.h + 0 + 0 + + + 1 + 2 + 1 + 0 + 0 + 0 + .\test_sched.c + test_sched.c + 0 + 0 + + + 1 + 3 + 1 + 0 + 0 + 0 + .\bsp_nucleo-c031c6.c + bsp_nucleo-c031c6.c + 0 + 0 + + + + + nucleo-c031c6 + 1 + 0 + 0 + 0 + + 2 + 4 + 2 + 0 + 0 + 0 + ..\..\..\3rd_party\nucleo-c031c6\arm\startup_stm32c031xx.s + startup_stm32c031xx.s + 0 + 0 + + + 2 + 5 + 5 + 0 + 0 + 0 + ..\..\..\3rd_party\nucleo-c031c6\stm32c031xx.h + stm32c031xx.h + 0 + 0 + + + 2 + 6 + 1 + 0 + 0 + 0 + ..\..\..\3rd_party\nucleo-c031c6\system_stm32c0xx.c + system_stm32c0xx.c + 0 + 0 + + + 2 + 7 + 5 + 0 + 0 + 0 + ..\..\..\3rd_party\nucleo-c031c6\system_stm32c0xx.h + system_stm32c0xx.h + 0 + 0 + + + 2 + 8 + 1 + 0 + 0 + 0 + ..\..\..\3rd_party\nucleo-c031c6\qutest\qutest_port.c + qutest_port.c + 0 + 0 + + + + + QP + 1 + 0 + 0 + 0 + + 3 + 9 + 1 + 0 + 0 + 0 + ..\..\..\src\qf\qep_hsm.c + qep_hsm.c + 0 + 0 + + + 3 + 10 + 1 + 0 + 0 + 0 + ..\..\..\src\qf\qep_msm.c + qep_msm.c + 0 + 0 + + + 3 + 16 + 1 + 0 + 0 + 0 + ..\..\..\..\..\src\qf\qf_act.c + qf_act.c + 0 + 0 + + + 3 + 12 + 1 + 0 + 0 + 0 + ..\..\..\src\qf\qf_actq.c + qf_actq.c + 0 + 0 + + + 3 + 13 + 1 + 0 + 0 + 0 + ..\..\..\src\qf\qf_defer.c + qf_defer.c + 0 + 0 + + + 3 + 14 + 1 + 0 + 0 + 0 + ..\..\..\src\qf\qf_dyn.c + qf_dyn.c + 0 + 0 + + + 3 + 15 + 1 + 0 + 0 + 0 + ..\..\..\src\qf\qf_mem.c + qf_mem.c + 0 + 0 + + + 3 + 16 + 1 + 0 + 0 + 0 + ..\..\..\src\qf\qf_ps.c + qf_ps.c + 0 + 0 + + + 3 + 17 + 1 + 0 + 0 + 0 + ..\..\..\src\qf\qf_qact.c + qf_qact.c + 0 + 0 + + + 3 + 18 + 1 + 0 + 0 + 0 + ..\..\..\src\qf\qf_qeq.c + qf_qeq.c + 0 + 0 + + + 3 + 19 + 1 + 0 + 0 + 0 + ..\..\..\src\qf\qf_qmact.c + qf_qmact.c + 0 + 0 + + + 3 + 20 + 1 + 0 + 0 + 0 + ..\..\..\src\qf\qf_time.c + qf_time.c + 0 + 0 + + + 3 + 21 + 1 + 0 + 0 + 0 + ..\..\..\src\qk\qk.c + qk.c + 0 + 0 + + + + + QP_port + 1 + 0 + 0 + 0 + + 4 + 22 + 5 + 0 + 0 + 0 + ..\..\..\ports\arm-cm\qk\armclang\qep_port.h + qep_port.h + 0 + 0 + + + 4 + 23 + 5 + 0 + 0 + 0 + ..\..\..\ports\arm-cm\qk\armclang\qf_port.h + qf_port.h + 0 + 0 + + + 4 + 24 + 1 + 0 + 0 + 0 + ..\..\..\ports\arm-cm\qk\armclang\qk_port.c + qk_port.c + 0 + 0 + + + 4 + 25 + 5 + 0 + 0 + 0 + ..\..\..\ports\arm-cm\qk\armclang\qk_port.h + qk_port.h + 0 + 0 + + + 4 + 26 + 5 + 0 + 0 + 0 + ..\..\..\ports\arm-cm\qk\armclang\qs_port.h + qs_port.h + 0 + 0 + + + + + QS + 1 + 0 + 0 + 0 + + 5 + 27 + 1 + 0 + 0 + 0 + ..\..\..\src\qs\qs.c + qs.c + 0 + 0 + + + 5 + 28 + 1 + 0 + 0 + 0 + ..\..\..\src\qs\qs_64bit.c + qs_64bit.c + 0 + 0 + + + 5 + 29 + 1 + 0 + 0 + 0 + ..\..\..\src\qs\qs_fp.c + qs_fp.c + 0 + 0 + + + 5 + 30 + 1 + 0 + 0 + 0 + ..\..\..\src\qs\qs_rx.c + qs_rx.c + 0 + 0 + + + 5 + 31 + 1 + 0 + 0 + 0 + ..\..\..\src\qs\qstamp.c + qstamp.c + 0 + 0 + + + 5 + 32 + 1 + 0 + 0 + 0 + ..\..\..\src\qs\qutest.c + qutest.c + 0 + 0 + + + +
diff --git a/test/qk/test_sched/nucleo-c031c6.uvprojx b/test/qk/test_sched/nucleo-c031c6.uvprojx new file mode 100644 index 00000000..b28c434f --- /dev/null +++ b/test/qk/test_sched/nucleo-c031c6.uvprojx @@ -0,0 +1,588 @@ + + + + 2.1 + +
### uVision Project, (C) Keil Software
+ + + + qutest + 0x4 + ARM-ADS + 6160000::V6.16::ARMCLANG + 1 + + + STM32C031C6Tx + STMicroelectronics + Keil.STM32C0xx_DFP.1.0.0 + https://www.keil.com/pack/ + IRAM(0x20000000,0x00003000) IROM(0x08000000,0x00008000) CPUTYPE("Cortex-M0+") CLOCK(12000000) ELITTLE + + + UL2CM3(-S0 -C0 -P0 -FD20000000 -FC1000 -FN1 -FF0STM32C0x_32 -FS08000000 -FL08000 -FP0($$Device:STM32C031C6Tx$CMSIS\Flash\STM32C0x_32.FLM)) + 0 + $$Device:STM32C031C6Tx$Drivers\CMSIS\Device\ST\STM32C0xx\Include\stm32c0xx.h + + + + + + + + + + $$Device:STM32C031C6Tx$CMSIS\SVD\STM32C031.svd + 0 + 0 + + + + + + + 0 + 0 + 0 + 0 + 1 + + .\uvision_nucleo-c031c6\ + test + 1 + 0 + 0 + 1 + 1 + .\uvision_nucleo-c031c6\ + 1 + 0 + 0 + + 0 + 0 + + + 0 + 0 + 0 + 0 + + + 1 + 0 + cmd /c "del .\uvision_nucleo-c031c6\qstamp.o" + + 0 + 0 + 0 + 0 + + + 1 + 0 + fromelf --bin --output .\uvision_nucleo-c031c6\test.bin .\uvision_nucleo-c031c6\test.axf + + 0 + 0 + 0 + 0 + + 0 + + + + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 3 + + + 1 + + + SARMCM3.DLL + -REMAP-MPU + DARMCM1.DLL + -pCM0+ + SARMCM3.DLL + -MPU + TARMCM1.DLL + -pCM0+ + + + + 1 + 0 + 0 + 0 + 16 + + + + + 1 + 0 + 0 + 1 + 1 + 4096 + + 1 + BIN\UL2CM3.DLL + "" () + + + + + 0 + + + + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + 1 + 0 + 0 + 0 + 0 + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + "Cortex-M0+" + + 0 + 0 + 0 + 1 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 8 + 0 + 0 + 0 + 0 + 3 + 3 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 1 + 0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x20000000 + 0x3000 + + + 1 + 0x8000000 + 0x8000 + + + 0 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x8000000 + 0x8000 + + + 1 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x20000000 + 0x3000 + + + 0 + 0x0 + 0x0 + + + + + + 0 + 1 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 3 + 0 + 1 + 0 + 0 + 0 + 3 + 3 + 0 + 0 + 0 + 0 + 0 + + + Q_SPY, Q_UTEST=0,QK_USE_IRQ_HANDLER=Reserved1_IRQHandler,QK_USE_IRQ_NUM=1,QF_ON_CONTEXT_SW + + .;..\..\..\include;..\..\..\ports\arm-cm\qk\armclang;..\..\..\3rd_party\CMSIS\Include,..\..\..\3rd_party\nucleo-c031c6 + + + + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 4 + + + Stack_Size=2048 Heap_Size=16 + + + + + + 1 + 0 + 0 + 0 + 1 + 0 + 0x00000000 + 0x20000000 + + dpp-qk.sct + + + --entry Reset_Handler + + + + + + + + test + + + bsp.h + 5 + .\bsp.h + + + test_sched.c + 1 + .\test_sched.c + + + bsp_nucleo-c031c6.c + 1 + .\bsp_nucleo-c031c6.c + + + + + nucleo-c031c6 + + + startup_stm32c031xx.s + 2 + ..\..\..\3rd_party\nucleo-c031c6\arm\startup_stm32c031xx.s + + + stm32c031xx.h + 5 + ..\..\..\3rd_party\nucleo-c031c6\stm32c031xx.h + + + system_stm32c0xx.c + 1 + ..\..\..\3rd_party\nucleo-c031c6\system_stm32c0xx.c + + + system_stm32c0xx.h + 5 + ..\..\..\3rd_party\nucleo-c031c6\system_stm32c0xx.h + + + qutest_port.c + 1 + ..\..\..\3rd_party\nucleo-c031c6\qutest\qutest_port.c + + + + + QP + + + qep_hsm.c + 1 + ..\..\..\src\qf\qep_hsm.c + + + qep_msm.c + 1 + ..\..\..\src\qf\qep_msm.c + + + qf_act.c + 1 + ..\..\..\..\..\src\qf\qf_act.c + + + qf_actq.c + 1 + ..\..\..\src\qf\qf_actq.c + + + qf_defer.c + 1 + ..\..\..\src\qf\qf_defer.c + + + qf_dyn.c + 1 + ..\..\..\src\qf\qf_dyn.c + + + qf_mem.c + 1 + ..\..\..\src\qf\qf_mem.c + + + qf_ps.c + 1 + ..\..\..\src\qf\qf_ps.c + + + qf_qact.c + 1 + ..\..\..\src\qf\qf_qact.c + + + qf_qeq.c + 1 + ..\..\..\src\qf\qf_qeq.c + + + qf_qmact.c + 1 + ..\..\..\src\qf\qf_qmact.c + + + qf_time.c + 1 + ..\..\..\src\qf\qf_time.c + + + qk.c + 1 + ..\..\..\src\qk\qk.c + + + + + QP_port + + + qep_port.h + 5 + ..\..\..\ports\arm-cm\qk\armclang\qep_port.h + + + qf_port.h + 5 + ..\..\..\ports\arm-cm\qk\armclang\qf_port.h + + + qk_port.c + 1 + ..\..\..\ports\arm-cm\qk\armclang\qk_port.c + + + qk_port.h + 5 + ..\..\..\ports\arm-cm\qk\armclang\qk_port.h + + + qs_port.h + 5 + ..\..\..\ports\arm-cm\qk\armclang\qs_port.h + + + + + QS + + + qs.c + 1 + ..\..\..\src\qs\qs.c + + + qs_64bit.c + 1 + ..\..\..\src\qs\qs_64bit.c + + + qs_fp.c + 1 + ..\..\..\src\qs\qs_fp.c + + + qs_rx.c + 1 + ..\..\..\src\qs\qs_rx.c + + + qstamp.c + 1 + ..\..\..\src\qs\qstamp.c + + + qutest.c + 1 + ..\..\..\src\qs\qutest.c + + + + + + + + + + + + + + + + + uvision_c031c6 + 1 + nucleo-c031c6 + + + + +
diff --git a/test/qk/test_sched/make_nucleo-h743zi b/test/qk/test_sched/nucleo-h743zi.mak similarity index 93% rename from test/qk/test_sched/make_nucleo-h743zi rename to test/qk/test_sched/nucleo-h743zi.mak index 79d45302..90d1ab2e 100644 --- a/test/qk/test_sched/make_nucleo-h743zi +++ b/test/qk/test_sched/nucleo-h743zi.mak @@ -1,7 +1,7 @@ ############################################################################## # Product: Makefile for QP/C on NUCLEO-H743ZI board, QUTEST, GNU-ARM -# Last Updated for Version: 7.2.0 -# Date of the Last Update: 2022-12-21 +# Last Updated for Version: 7.3.0 +# Date of the Last Update: 2023-09-06 # # Q u a n t u m L e a P s # ------------------------ @@ -33,11 +33,12 @@ ############################################################################## # # examples of invoking this Makefile: -# make -f make_nucleo-h743zi USB=g: # make, uplaod to USB drive, run the tests -# make -f make_nucleo-h743zi USB=g: TESTS=philo*.py # make and run the selected tests -# make -f make_nucleo-h743zi USB=g: HOST=localhost:7705 # connect to host:port -# make -f make_nucleo-h743zi USB=g: norun # only make but not run the tests -# make -f make_nucleo-h743zi USB=g: clean # cleanup the build +# make -f nucleo-h743zi.mak USB=g: # make, uplaod to USB drive, run the tests +# make -f nucleo-h743zi.mak USB=g: TESTS=philo*.py # make and run the selected tests +# make -f nucleo-h743zi.mak USB=g: HOST=localhost:7705 # connect to host:port +# make -f nucleo-h743zi.mak USB=g: norun # only make but not run the tests +# make -f nucleo-h743zi.mak USB=g: clean # cleanup the build +# make -f nucleo-h743zi.mak USB=g: debug # only run tests in DEBUG mode # # NOTE: # To use this Makefile on Windows, you will need the GNU make utility, which @@ -102,7 +103,7 @@ ASM_SRCS := # C source files C_SRCS := \ test_sched.c \ - bsp_h743zi.c \ + bsp_nucleo-h743zi.c \ startup_stm32h743xx.c \ system_stm32h7xx.c \ stm32h7xx_nucleo_144.c \ @@ -273,7 +274,7 @@ $(TARGET_BIN) : $(TARGET_ELF) $(SLEEP) 2 $(TARGET_ELF) : $(ASM_OBJS_EXT) $(C_OBJS_EXT) $(CPP_OBJS_EXT) - $(CC) $(CFLAGS) $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o + $(CC) $(CFLAGS) $(QPC)/src/qs/qstamp.c -o $(BIN_DIR)/qstamp.o $(LINK) $(LINKFLAGS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) flash : @@ -310,7 +311,7 @@ endif endif debug : - $(QUTEST) $(TESTS) DEBUG $(HOST) + $(QUTEST) -edebug -q$(QSPY) -l$(LOG) -o$(OPT) -- $(TESTS) .PHONY : clean show diff --git a/test/qk/test_sched/make_nucleo-l053r8 b/test/qk/test_sched/nucleo-l053r8.mak similarity index 93% rename from test/qk/test_sched/make_nucleo-l053r8 rename to test/qk/test_sched/nucleo-l053r8.mak index 2d6f32ce..f24f91bf 100644 --- a/test/qk/test_sched/make_nucleo-l053r8 +++ b/test/qk/test_sched/nucleo-l053r8.mak @@ -1,7 +1,7 @@ ############################################################################## # Product: Makefile for SYSTEM-Level tests of QP/C on NUCLEO-L053R8, GNU-ARM -# Last Updated for Version: 7.2.0 -# Date of the Last Update: 2022-12-21 +# Last Updated for Version: 7.3.0 +# Date of the Last Update: 2023-09-06 # # Q u a n t u m L e a P s # ------------------------ @@ -33,12 +33,12 @@ ############################################################################## # # examples of invoking this Makefile: -# make -f make_nucleo-l053r8 USB=g: # make, uplaod to USB drive, run the tests -# make -f make_nucleo-l053r8 USB=g: TESTS=philo*.py # make and run the selected tests -# make -f make_nucleo-l053r8 HOST=localhost:7705 # connect to host:port -# make -f make_nucleo-l053r8 norun # only make but not run the tests -# make -f make_nucleo-l053r8 clean # cleanup the build -# make -f make_nucleo-l053r8 debug # only run tests in DEBUG mode +# make -f nucleo-l053r8.mak USB=g: # make, uplaod to USB drive, run the tests +# make -f nucleo-l053r8.mak USB=g: TESTS=philo*.py # make and run the selected tests +# make -f nucleo-l053r8.mak HOST=localhost:7705 # connect to host:port +# make -f nucleo-l053r8.mak norun # only make but not run the tests +# make -f nucleo-l053r8.mak clean # cleanup the build +# make -f nucleo-l053r8.mak debug # only run tests in DEBUG mode # # NOTE: # To use this Makefile on Windows, you will need the GNU make utility, which @@ -99,7 +99,7 @@ ASM_SRCS := # C source files C_SRCS := \ test_sched.c \ - bsp_l053r8.c \ + bsp_nucleo-l053r8.c \ system_stm32l0xx.c \ startup_stm32l053xx.c @@ -260,7 +260,7 @@ $(TARGET_BIN) : $(TARGET_ELF) $(SLEEP) 2 $(TARGET_ELF) : $(ASM_OBJS_EXT) $(C_OBJS_EXT) $(CPP_OBJS_EXT) - $(CC) $(CFLAGS) $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o + $(CC) $(CFLAGS) $(QPC)/src/qs/qstamp.c -o $(BIN_DIR)/qstamp.o $(LINK) $(LINKFLAGS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) flash : @@ -297,7 +297,7 @@ endif endif debug : - $(QUTEST) $(TESTS) DEBUG $(HOST) + $(QUTEST) -edebug -q$(QSPY) -l$(LOG) -o$(OPT) -- $(TESTS) .PHONY : clean show diff --git a/test/qk/test_sched/uvision_l053r8.uvoptx b/test/qk/test_sched/nucleo-l053r8.uvoptx similarity index 90% rename from test/qk/test_sched/uvision_l053r8.uvoptx rename to test/qk/test_sched/nucleo-l053r8.uvoptx index 79e8251e..6000507a 100644 --- a/test/qk/test_sched/uvision_l053r8.uvoptx +++ b/test/qk/test_sched/nucleo-l053r8.uvoptx @@ -22,7 +22,7 @@ - test_l053r8 + qutest 0x4 ARM-ADS @@ -45,7 +45,7 @@ 79 66 8 - .\spy\ + .\uvision_nucleo-l053r8\ 1 @@ -148,56 +148,7 @@ - - - 0 - 0 - 171 - 1 -
0
- 0 - 0 - 0 - 0 - 0 - 0 - ..\..\..\3rd_party\nucleo-l053r8\arm\startup_stm32l053xx.s - - -
- - 1 - 0 - 142 - 1 -
0
- 0 - 0 - 0 - 0 - 0 - 0 - ..\..\..\3rd_party\nucleo-l053r8\qutest\qutest_port.c - - -
- - 2 - 0 - 76 - 1 -
0
- 0 - 0 - 0 - 0 - 0 - 0 - ..\..\..\3rd_party\nucleo-l053r8\qutest\qutest_port.c - - -
-
+ 1 @@ -220,7 +171,7 @@ 0 0 - 0 + 1 0 0 0 @@ -267,7 +218,7 @@
- Source Code + test 1 0 0 @@ -291,8 +242,8 @@ 0 0 0 - .\bsp_l053r8.c - bsp_l053r8.c + .\test_sched.c + test_sched.c 0 0
@@ -303,8 +254,8 @@ 0 0 0 - .\test_sched.c - test_sched.c + .\bsp_nucleo-l053r8.c + bsp_nucleo-l053r8.c 0 0 @@ -312,7 +263,7 @@ nucleo-l053r8 - 1 + 0 0 0 0 @@ -422,12 +373,12 @@ 3 - 12 + 16 1 0 0 0 - ..\..\..\src\qf\qf_act.c + ..\..\..\..\..\src\qf\qf_act.c qf_act.c 0 0 diff --git a/test/qk/test_sched/uvision_l053r8.uvprojx b/test/qk/test_sched/nucleo-l053r8.uvprojx similarity index 96% rename from test/qk/test_sched/uvision_l053r8.uvprojx rename to test/qk/test_sched/nucleo-l053r8.uvprojx index e15835b5..808214bc 100644 --- a/test/qk/test_sched/uvision_l053r8.uvprojx +++ b/test/qk/test_sched/nucleo-l053r8.uvprojx @@ -7,7 +7,7 @@ - test_l053r8 + qutest 0x4 ARM-ADS 6160000::V6.16::ARMCLANG @@ -48,14 +48,14 @@ 0 1 - .\spy\ - dpp-qk + .\uvision_nucleo-l053r8\ + test 1 0 0 1 1 - .\spy\ + .\uvision_nucleo-l053r8\ 1 0 0 @@ -72,7 +72,7 @@ 1 0 - cmd /c "del .\spy\qstamp.o" + cmd /c "del .\uvision_nucleo-l053r8\qstamp.o" 0 0 @@ -82,7 +82,7 @@ 1 0 - fromelf --bin --output .\spy\dpp-qk.bin .\spy\dpp-qk.axf + fromelf --bin --output .\uvision_nucleo-l053r8\test.bin .\uvision_nucleo-l053r8\test.axf 0 0 @@ -381,23 +381,23 @@ - Source Code + test bsp.h 5 .\bsp.h - - bsp_l053r8.c - 1 - .\bsp_l053r8.c - test_sched.c 1 .\test_sched.c + + bsp_nucleo-l053r8.c + 1 + .\bsp_nucleo-l053r8.c + @@ -451,7 +451,7 @@ qf_act.c 1 - ..\..\..\src\qf\qf_act.c + ..\..\..\..\..\src\qf\qf_act.c qf_actq.c @@ -585,6 +585,7 @@ uvision_l053r8 1 + nucleo-l053r8 diff --git a/test/qk/test_sched/qutest230202_192030.txt b/test/qk/test_sched/qutest230202_192030.txt new file mode 100644 index 00000000..a6809a23 --- /dev/null +++ b/test/qk/test_sched/qutest230202_192030.txt @@ -0,0 +1,89 @@ +Run ID : 230202_192030 +Target : remote + +==================================[Group 1]================================== +test_mpu.py + +@uid{TQP701} +This test group verifies the memory access protection, +specifically the protection of various memory regions. +All tests run during the QS_TEST_PAUSE() in +the test_sched.c fixture. + +[ 1]-------------------------------------------------------------------------- + +NULL-read -> ASSERT + + [ PASS ( 0.2s) ] +[ 2]-------------------------------------------------------------------------- +NULL-write -> ASSERT + [ PASS ( 0.1s) ] +[ 3]-------------------------------------------------------------------------- +Below-Start Flash-read -> ASSERT + [ PASS ( 0.1s) ] +[ 4]-------------------------------------------------------------------------- +Start-of Flash-read + [ PASS ( 0.1s) ] +[ 5]^------------------------------------------------------------------------- +Middle-of Flash-read + [ PASS ( 0.0s) ] +[ 6]^------------------------------------------------------------------------- +End-of Flash-read + [ PASS ( 0.0s) ] +[ 7]^ - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - +After-End Flash-read-> ASSERT + [ SKIPPED ] +[ 8]-------------------------------------------------------------------------- +Middle-of Flash-write -> ASSERT + [ PASS ( 0.1s) ] +[ 9]-------------------------------------------------------------------------- +Below-Start SRAM-read -> ASSERT + [ PASS ( 0.1s) ] +[10]-------------------------------------------------------------------------- +Start-of SRAM-read + [ PASS ( 0.1s) ] +[11]^------------------------------------------------------------------------- +Middle-of SRAM-read + [ PASS ( 0.0s) ] +[12]^------------------------------------------------------------------------- +End-of SRAM-read + [ PASS ( 0.0s) ] +[13]^------------------------------------------------------------------------- +Below-Start SRAM-write -> ASSERT + [ PASS ( 0.0s) ] +[14]- - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - +Middle-of SRAM-write + [ SKIPPED ] +[15]-------------------------------------------------------------------------- +After-End SRAM-write -> ASSERT + [ PASS ( 0.1s) ] + +==================================[Group 2]================================== +test_sched.py +@uid{TQP603} +This test group verifies the preemption scenarios +in the QK preemptive kernel + +[16]-------------------------------------------------------------------------- +Scenario: ao->ao->ao (NO PTS) + @test_sched.py:43 +exp: "0000000013 TRACE_MSG aoB[1] TEST0 2of2" +got: "0000000013 =ASSERT= Mod=Undefined,Loc=1" +! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ![ FAIL ( 0.2s) ] +[17]-------------------------------------------------------------------------- +ao->ao->ao (PTS1) + [ PASS ( 0.2s) ] +[18]-------------------------------------------------------------------------- +ao->ao->ao (PTS2) + [ PASS ( 0.2s) ] + +==================================[ SUMMARY ]================================= + +Target ID : 230202_190526 (QP-Ver=721) +Log file : ./qutest230202_192030.txt +Groups : 2 +Tests : 18 +Skipped : 2 [ 7 14 ] +FAILED : 1 [ 16 ] + +==============================[ FAIL ( 2.8s) ]=============================== diff --git a/test/qk/test_sched/test_sched.c b/test/qk/test_sched/test_sched.c index 8a0df328..246d915d 100644 --- a/test/qk/test_sched/test_sched.c +++ b/test/qk/test_sched/test_sched.c @@ -1,43 +1,43 @@ -/*============================================================================ -* Product: System test fixture for QK kernel -* Last updated for version 7.2.0 -* Last updated on 2022-12-22 -* -* Q u a n t u m L e a P s -* ------------------------ -* Modern Embedded Software -* -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* -* -============================================================================*/ +//============================================================================ +// Product: System test fixture for QK kernel +// Last Updated for Version: 7.3.0 +// Date of the Last Update: 2023-06-30 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// This program is open source software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Alternatively, this program may be distributed and modified under the +// terms of Quantum Leaps commercial licenses, which expressly supersede +// the GNU General Public License and are specifically designed for +// licensees interested in retaining the proprietary status of their code. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Contact information: +// +// +//============================================================================ #include "qpc.h" #include "bsp.h" -Q_DEFINE_THIS_FILE +//Q_DEFINE_THIS_FILE -/*==========================================================================*/ -/* AO ObjB */ +//========================================================================== +// AO ObjB enum { NUM_B = 3 }; typedef struct { @@ -51,7 +51,7 @@ void ObjB_ctor(ObjB * const me) { QActive_ctor(&me->super, Q_STATE_CAST(&ObjB_initial)); } -/*..........................................................................*/ +//.......................................................................... QState ObjB_initial(ObjB * const me, void const * const par) { Q_UNUSED_PAR(par); QActive_subscribe(&me->super, TEST1_SIG); @@ -59,7 +59,7 @@ QState ObjB_initial(ObjB * const me, void const * const par) { QS_FUN_DICTIONARY(&ObjB_active); return Q_TRAN(&ObjB_active); } -/*..........................................................................*/ +//.......................................................................... QState ObjB_active(ObjB * const me, QEvt const * const e) { QState status_; switch (e->sig) { @@ -71,7 +71,7 @@ QState ObjB_active(ObjB * const me, QEvt const * const e) { break; } case TEST1_SIG: { - static QEvt const t2 = { TEST2_SIG, 0U, 0U }; + static QEvt const t2 = QEVT_INITIALIZER(TEST2_SIG); BSP_trace(&me->super, "TEST1 1of2"); QACTIVE_PUBLISH(&t2, &me->super); BSP_trace(&me->super, "TEST1 2of2"); @@ -90,10 +90,10 @@ QState ObjB_active(ObjB * const me, QEvt const * const e) { } return status_; } -/*..........................................................................*/ +//.......................................................................... ObjB aoB[NUM_B]; -/*==========================================================================*/ +//========================================================================== enum UserCommands { MEM_READ, MEM_WRITE, ROM_READ, ROM_WRITE, @@ -101,18 +101,18 @@ enum UserCommands { }; int main() { - QF_init(); /* initialize the framework and the underlying QXK kernel */ - BSP_init(); /* initialize the Board Support Package */ + QF_init(); // initialize the framework and the underlying QXK kernel + BSP_init(); // initialize the Board Support Package - /* initialize publish-subscribe... */ + // initialize publish-subscribe... static QSubscrList subscrSto[MAX_PUB_SIG]; QActive_psInit(subscrSto, Q_DIM(subscrSto)); - /* initialize event pools... */ - static QF_MPOOL_EL(QEvt) smlPoolSto[10]; /* small pool */ + // initialize event pools... + static QF_MPOOL_EL(QEvt) smlPoolSto[10]; // small pool QF_poolInit(smlPoolSto, sizeof(smlPoolSto), sizeof(smlPoolSto[0])); - /* dictionaries */ + // dictionaries QS_SIG_DICTIONARY(TEST0_SIG, (void *)0); QS_SIG_DICTIONARY(TEST1_SIG, (void *)0); QS_SIG_DICTIONARY(TEST2_SIG, (void *)0); @@ -129,42 +129,42 @@ int main() { QS_OBJ_ARR_DICTIONARY(&aoB[n], n); } - /* priority specifications for ObjBs... */ + // priority specifications for ObjBs... static QPrioSpec pspecB[NUM_B + 1]; QS_OBJ_DICTIONARY(pspecB); - /* pause execution of the test and wait for the test script to continue - * NOTE: - * this pause gives the test-script a chance to poke pspecB and pspecX - * variables to start the threads with the desired prio-specifications. - */ + // pause execution of the test and wait for the test script to continue + // NOTE: + // this pause gives the test-script a chance to poke pspecB and pspecX + // variables to start the threads with the desired prio-specifications. + // QS_TEST_PAUSE(); static QEvt const *aoB_queueSto[NUM_B][10]; for (uint8_t n = 0U; n < NUM_B; ++n) { if (pspecB[n] != 0U) { - ObjB_ctor(&aoB[n]); /* instantiate the AO */ - QACTIVE_START(&aoB[n].super, /* AO to start */ - pspecB[n], /* QF-prio/p-thre.*/ - aoB_queueSto[n], /* event queue storage */ - Q_DIM(aoB_queueSto[n]), /* event length [events] */ - (void *)0, /* no stack storage */ - 0U, /* zero stack size [bytes] */ - (void *)0); /* initialization param */ + ObjB_ctor(&aoB[n]); // instantiate the AO + QACTIVE_START(&aoB[n].super, // AO to start + pspecB[n], // QF-prio/p-thre. + aoB_queueSto[n], // event queue storage + Q_DIM(aoB_queueSto[n]), // event length [events] + (void *)0, // no stack storage + 0U, // zero stack size [bytes] + (void *)0); // initialization param } } - return QF_run(); /* run the QF application */ + return QF_run(); // run the QF application } -/*==========================================================================*/ +//========================================================================== void QS_onTestSetup(void) { } -/*..........................................................................*/ +//.......................................................................... void QS_onTestTeardown(void) { } -/*..........................................................................*/ -/*! callback function to execute user commands */ +//.......................................................................... +//! callback function to execute user commands void QS_onCommand(uint8_t cmdId, uint32_t param1, uint32_t param2, uint32_t param3) { @@ -231,13 +231,13 @@ void QS_onCommand(uint8_t cmdId, } } -/****************************************************************************/ -/*! Host callback function to "massage" the event, if necessary */ +//**************************************************************************** +//! Host callback function to "massage" the event, if necessary void QS_onTestEvt(QEvt *e) { Q_UNUSED_PAR(e); } -/*..........................................................................*/ -/*! callback function to output the posted QP events (not used here) */ +//.......................................................................... +//! callback function to output the posted QP events (not used here) void QS_onTestPost(void const *sender, QActive *recipient, QEvt const *e, bool status) { diff --git a/test/qs/qs_rx/Makefile b/test/qs/qs_rx/Makefile new file mode 100644 index 00000000..b16c5d1b --- /dev/null +++ b/test/qs/qs_rx/Makefile @@ -0,0 +1,221 @@ +############################################################################## +# Product: Makefile for Embedded Test (ET) for Windows *HOST* +# Last Updated for Version: 7.3.0 +# Date of the Last Update: 2023-06-30 +# +# Q u a n t u m L e a P s +# ------------------------ +# Modern Embedded Software +# +# Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +# +# This program is open source software: you can redistribute it and/or +# modify it under the terms of the GNU General Public License as published +# by the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Alternatively, this program may be distributed and modified under the +# terms of Quantum Leaps commercial licenses, which expressly supersede +# the GNU General Public License and are specifically designed for +# licensees interested in retaining the proprietary status of their code. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# +# Contact information: +# +# +############################################################################## +# +# examples of invoking this Makefile: +# make # make and run the Python tests in the current directory +# make TESTS=test*.py # make and run the selected tests in the curr. dir. +# make HOST=localhost:7705 # connect to host:port +# make norun # only make but not run the tests +# make clean # cleanup the build +# make debug # only run tests in DEBUG mode +# +# NOTE: +# To use this Makefile on Windows, you will need the GNU make utility, which +# is included in the QTools collection for Windows, see: +# https://github.com/QuantumLeaps/qtools +# + +#----------------------------------------------------------------------------- +# project name: +PROJECT := test + +#----------------------------------------------------------------------------- +# project directories: +# +QPC := ../../.. +ET := ../../et + +# list of all source directories used by this project +VPATH := . \ + $(QPC)/src/qf \ + $(QPC)/src/qs \ + $(ET) + +# list of all include directories needed by this project +INCLUDES := -I. \ + -I$(QPC)/include \ + -I$(ET) + +#----------------------------------------------------------------------------- +# project files: +# + +# C source files... +C_SRCS := \ + qep_hsm.c \ + qf_act.c \ + qf_actq.c \ + qf_qact.c \ + qs.c \ + qs_rx.c \ + test.c \ + et.c \ + et_host.c + +# C++ source files... +CPP_SRCS := + +LIB_DIRS := +LIBS := + +# defines... +DEFINES := -DQ_SPY + +#============================================================================ +# Typically you should not need to change anything below this line + +#----------------------------------------------------------------------------- +# GNU toolset: +# +# NOTE: +# GNU toolset (MinGW) is included in the QTools collection for Windows, see: +# https://www.state-machine.com/qtools +# It is assumed that %QTOOLS%\bin directory is added to the PATH +# +CC := gcc +CPP := g++ +LINK := gcc # for C programs +#LINK := g++ # for C++ programs + +#----------------------------------------------------------------------------- +# basic utilities (depends on the OS this Makefile runs on): +# +ifeq ($(OS),Windows_NT) + MKDIR := mkdir + RM := rm + TARGET_EXT := .exe +else ifeq ($(OSTYPE),cygwin) + MKDIR := mkdir -p + RM := rm -f + TARGET_EXT := .exe +else + MKDIR := mkdir -p + RM := rm -f + TARGET_EXT := +endif + +#----------------------------------------------------------------------------- +# build options... + +BIN_DIR := build + +CFLAGS := -c -g -O -fno-pie -std=c11 -pedantic -Wall -Wextra -W \ + $(INCLUDES) $(DEFINES) -DQ_HOST + +CPPFLAGS := -c -g -O -fno-pie -std=c++11 -pedantic -Wall -Wextra \ + -fno-rtti -fno-exceptions \ + $(INCLUDES) $(DEFINES) -DQ_HOST + +ifndef GCC_OLD + LINKFLAGS := -no-pie +endif + +ifdef GCOV + CFLAGS += -fprofile-arcs -ftest-coverage + CPPFLAGS += -fprofile-arcs -ftest-coverage + LINKFLAGS += -lgcov --coverage +endif + +#----------------------------------------------------------------------------- +C_OBJS := $(patsubst %.c,%.o, $(C_SRCS)) +CPP_OBJS := $(patsubst %.cpp,%.o, $(CPP_SRCS)) + +TARGET_EXE := $(BIN_DIR)/$(PROJECT)$(TARGET_EXT) +C_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(C_OBJS)) +C_DEPS_EXT := $(patsubst %.o,%.d, $(C_OBJS_EXT)) +CPP_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(CPP_OBJS)) +CPP_DEPS_EXT := $(patsubst %.o,%.d, $(CPP_OBJS_EXT)) + +#----------------------------------------------------------------------------- +# rules +# + +.PHONY : norun clean show + +ifeq ($(MAKECMDGOALS),norun) +all : $(TARGET_EXE) +norun : all +else +all : $(TARGET_EXE) run +endif + +$(TARGET_EXE) : $(C_OBJS_EXT) $(CPP_OBJS_EXT) + $(CC) $(CFLAGS) $(QPC)/src/qs/qstamp.c -o $(BIN_DIR)/qstamp.o + $(LINK) $(LINKFLAGS) $(LIB_DIRS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) + +run : $(TARGET_EXE) + $(TARGET_EXE) + +$(BIN_DIR)/%.d : %.cpp + $(CPP) -MM -MT $(@:.d=.o) $(CPPFLAGS) $< > $@ + +$(BIN_DIR)/%.d : %.c + $(CC) -MM -MT $(@:.d=.o) $(CFLAGS) $< > $@ + +$(BIN_DIR)/%.o : %.c + $(CC) $(CFLAGS) $< -o $@ + +$(BIN_DIR)/%.o : %.cpp + $(CPP) $(CPPFLAGS) $< -o $@ + +# create BIN_DIR and include dependencies only if needed +ifneq ($(MAKECMDGOALS),clean) + ifneq ($(MAKECMDGOALS),show) + ifneq ($(MAKECMDGOALS),debug) +ifeq ("$(wildcard $(BIN_DIR))","") +$(shell $(MKDIR) $(BIN_DIR)) +endif +-include $(C_DEPS_EXT) $(CPP_DEPS_EXT) + endif + endif +endif + +clean : + -$(RM) $(BIN_DIR)/*.* + +show : + @echo PROJECT = $(PROJECT) + @echo TARGET_EXE = $(TARGET_EXE) + @echo VPATH = $(VPATH) + @echo C_SRCS = $(C_SRCS) + @echo CPP_SRCS = $(CPP_SRCS) + @echo C_DEPS_EXT = $(C_DEPS_EXT) + @echo C_OBJS_EXT = $(C_OBJS_EXT) + @echo C_DEPS_EXT = $(C_DEPS_EXT) + @echo CPP_DEPS_EXT = $(CPP_DEPS_EXT) + @echo CPP_OBJS_EXT = $(CPP_OBJS_EXT) + @echo LIB_DIRS = $(LIB_DIRS) + @echo LIBS = $(LIBS) + @echo DEFINES = $(DEFINES) + diff --git a/test/qs/qs_rx/qp_port.h b/test/qs/qs_rx/qp_port.h new file mode 100644 index 00000000..6fb6b29b --- /dev/null +++ b/test/qs/qs_rx/qp_port.h @@ -0,0 +1,130 @@ +//============================================================================ +// QP/C Real-Time Embedded Framework (RTEF) +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +//============================================================================ +//! +//! @date Last updated on: 2023-08-19 +//! @version Last updated for: @ref qpc_7_3_0 +//! +//! @file +//! @brief QP/C "port" for Embedded Test, Win32 with GNU or VisualC++ +//! +#ifndef QP_PORT_H_ +#define QP_PORT_H_ + +#include // Exact-width types. WG14/N843 C99 Standard +#include // Boolean type. WG14/N843 C99 Standard + +//! no-return function specifier +#ifdef __GNUC__ + + //! no-return function specifier (GCC-ARM compiler) + #define Q_NORETURN __attribute__ ((noreturn)) void + +#elif (defined _MSC_VER) + #ifdef __cplusplus + // no-return function specifier (Microsoft Visual Studio C++ compiler) + #define Q_NORETURN [[ noreturn ]] void + #else + // no-return function specifier C11 + #define Q_NORETURN _Noreturn void + #endif + + // This is the case where QP/C is compiled by the Microsoft Visual C++ + // compiler in the C++ mode, which can happen when qep_port.h is included + // in a C++ module, or the compilation is forced to C++ by the option /TP. + // + // The following pragma suppresses the level-4 C++ warnings C4510, C4512, + // and C4610, which warn that default constructors and assignment operators + // could not be generated for structures QMState and QMTranActTable. + // + // The QP/C source code cannot be changed to avoid these C++ warnings + // because the structures QMState and QMTranActTable must remain PODs + // (Plain Old Datatypes) to be initializable statically with constant + // initializers. + // + #pragma warning (disable: 4510 4512 4610) + +#endif + +// event queue and thread types +#define QACTIVE_EQUEUE_TYPE QEQueue +// QACTIVE_OS_OBJ_TYPE not used in this port +// QACTIVE_THREAD_TYPE not used in this port + +// The maximum number of active objects in the application +#define QF_MAX_ACTIVE 64U + +// The number of system clock tick rates +#define QF_MAX_TICK_RATE 2U + +// Activate the QF QActive_stop() API +#define QACTIVE_CAN_STOP 1 + +// QF interrupt disable/enable +#define QF_INT_DISABLE() ((void)0) +#define QF_INT_ENABLE() ((void)0) + +// QUIT critical section +#define QF_CRIT_STAT +#define QF_CRIT_ENTRY() QF_INT_DISABLE() +#define QF_CRIT_EXIT() QF_INT_ENABLE() + +// QF_LOG2 not defined -- use the internal LOG2() implementation + +// include files ------------------------------------------------------------- +#include "qequeue.h" // Win32-QV needs the native event-queue +#include "qmpool.h" // Win32-QV needs the native memory-pool +#include "qp.h" // QP platform-independent public interface + +//========================================================================== +// interface used only inside QP implementation, but not in applications +#ifdef QP_IMPL + + // ET scheduler locking (not used) + #define QF_SCHED_STAT_ + #define QF_SCHED_LOCK_(dummy) ((void)0) + #define QF_SCHED_UNLOCK_() ((void)0) + + // native event queue operations + #define QACTIVE_EQUEUE_WAIT_(me_) \ + Q_ASSERT_INCRIT(302, (me_)->eQueue.frontEvt != (QEvt *)0) + #define QACTIVE_EQUEUE_SIGNAL_(me_) ((void)0) + + // native QF event pool operations + #define QF_EPOOL_TYPE_ QMPool + #define QF_EPOOL_INIT_(p_, poolSto_, poolSize_, evtSize_) \ + (QMPool_init(&(p_), (poolSto_), (poolSize_), (evtSize_))) + #define QF_EPOOL_EVENT_SIZE_(p_) ((uint_fast16_t)(p_).blockSize) + #define QF_EPOOL_GET_(p_, e_, m_, qs_id_) \ + ((e_) = (QEvt *)QMPool_get(&(p_), (m_), (qs_id_))) + #define QF_EPOOL_PUT_(p_, e_, qs_id_) \ + (QMPool_put(&(p_), (e_), (qs_id_))) + +#endif // QP_IMPL + +#ifdef _MSC_VER + #pragma warning (default: 4510 4512 4610) +#endif + +#endif // QP_PORT_H_ diff --git a/test/qs/qs_rx/qs_port.h b/test/qs/qs_rx/qs_port.h new file mode 100644 index 00000000..d0460af6 --- /dev/null +++ b/test/qs/qs_rx/qs_port.h @@ -0,0 +1,61 @@ +//============================================================================ +// QP/C Real-Time Embedded Framework (RTEF) +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +//============================================================================ +//! @date Last updated on: 2023-08-16 +//! @version Last updated for: @ref qpc_7_3_0 +//! +//! @file +//! @brief QS/C port to Win32 with GNU or Visual C++ compilers +//! +#ifndef QS_PORT_H_ +#define QS_PORT_H_ + +#define QS_CTR_SIZE 4U +#define QS_TIME_SIZE 4U + +#ifdef _WIN64 // 64-bit architecture? + #define QS_OBJ_PTR_SIZE 8U + #define QS_FUN_PTR_SIZE 8U +#else // 32-bit architecture + #define QS_OBJ_PTR_SIZE 4U + #define QS_FUN_PTR_SIZE 4U +#endif + +void QS_output(void); // handle the QS output +void QS_rx_input(void); // handle the QS-RX input + +//============================================================================ +// NOTE: QS might be used with or without other QP components, in which +// case the separate definitions of the macros QF_CRIT_STAT, QF_CRIT_ENTRY(), +// and QF_CRIT_EXIT() are needed. In this port QS is configured to be used +// with the other QP component, by simply including "qp_port.h" +//*before* "qs.h". +#ifndef QP_PORT_H_ +#include "qp_port.h" // use QS with QF +#endif + +#include "qs.h" // QS platform-independent public interface + +#endif // QS_PORT_H_ + diff --git a/test/qs/qs_rx/test.c b/test/qs/qs_rx/test.c new file mode 100644 index 00000000..2a95fd1f --- /dev/null +++ b/test/qs/qs_rx/test.c @@ -0,0 +1,139 @@ +#include "et.h" // ET: embedded test + +// includes for the CUT... +#include "qp_port.h" // QP port +#include "qsafe.h" // QP Functional Safety (FuSa) System +#ifdef Q_SPY // software tracing enabled? +#include "qs_port.h" // QS/C port from the port directory +#else +#include "qs_dummy.h" // QS/C dummy (inactive) interface +#endif + +enum { RX_SIZE = 8 }; + +static uint8_t qsBuf[100]; // buffer for QS-TX channel +static uint8_t qsRxBuf[RX_SIZE]; // buffer for QS-RX channel + +void setup(void) { +} + +void teardown(void) { +} + +// test group -------------------------------------------------------------- +TEST_GROUP("QS/RX") { + +QS_initBuf(qsBuf, sizeof(qsBuf)); + +TEST("QS-RX initialization") { + QS_rxInitBuf(qsRxBuf, RX_SIZE); + VERIFY(RX_SIZE - 1 == QS_rxGetNfree()); +} + +TEST("QS-RX putting 3") { + for (uint8_t n = 0U; n < 3U; ++n) { + VERIFY(QS_RX_PUT(n + 1U)); + } + VERIFY(RX_SIZE - 1 - 3 == QS_rxGetNfree()); +} + +TEST("QS-RX QS_rxParse") { + QS_rxParse(); + VERIFY(RX_SIZE - 1 == QS_rxGetNfree()); +} + +TEST("QS-RX putting 6") { + for (uint8_t n = 0U; n < 6U; ++n) { + VERIFY(QS_RX_PUT(n + 1U)); + } + VERIFY(RX_SIZE - 1 - 6 == QS_rxGetNfree()); +} + +TEST("QS-RX putting 3 more") { + VERIFY(QS_RX_PUT(0x7U)); + VERIFY(false == QS_RX_PUT(0x8U)); + VERIFY(false == QS_RX_PUT(0x9U)); + VERIFY(0 == QS_rxGetNfree()); +} + +} // TEST_GROUP() + +// ========================================================================= +// dependencies for the CUT ... + +//.......................................................................... +void QF_poolInit(void * const poolSto, uint_fast32_t const poolSize, + uint_fast16_t const evtSize) +{ + (void)poolSto; + (void)poolSize; + (void)evtSize; +} +//.......................................................................... +uint_fast16_t QF_poolGetMaxBlockSize(void) { + return 0U; +} +//.......................................................................... +void QActive_publish_(QEvt const * const e, + void const * const sender, uint_fast8_t const qs_id) +{ + (void)e; + (void)sender; + (void)qs_id; +} +//.......................................................................... +void QTimeEvt_tick_(uint_fast8_t const tickRate, void const * const sender) { + (void)tickRate; + (void)sender; +} +//.......................................................................... +QEvt *QF_newX_(uint_fast16_t const evtSize, + uint_fast16_t const margin, enum_t const sig) +{ + (void)evtSize; + (void)margin; + (void)sig; + + return (QEvt *)0; +} +//.......................................................................... +//! @static @public @memberof QF +void QF_gc(QEvt const * const e) { + (void)e; +} +//.......................................................................... +//! @static @private @memberof QF +QActive *QActive_registry_[QF_MAX_ACTIVE + 1U]; + +//.......................................................................... +Q_NORETURN Q_onError(char const * const module, int_t const location) { + ET_fail("Q_onError", module, location); + for (;;) {} // explicitly no-return +} + +//-------------------------------------------------------------------------- +#ifdef Q_SPY + +void QS_onCleanup(void) { +} +//.......................................................................... +void QS_onReset(void) { +} +//.......................................................................... +void QS_onFlush(void) { +} +//.......................................................................... +QSTimeCtr QS_onGetTime(void) { + return (QSTimeCtr)0U; +} +//.......................................................................... +void QS_onCommand(uint8_t cmdId, uint32_t param1, + uint32_t param2, uint32_t param3) +{ + (void)cmdId; + (void)param1; + (void)param2; + (void)param3; +} + +#endif // Q_SPY diff --git a/examples/arm-cm/blinky_ek-tm4c123gxl/qube/qube_vs.sln b/test/qs/qs_rx/test.sln similarity index 54% rename from examples/arm-cm/blinky_ek-tm4c123gxl/qube/qube_vs.sln rename to test/qs/qs_rx/test.sln index 94798531..b0e72653 100644 --- a/examples/arm-cm/blinky_ek-tm4c123gxl/qube/qube_vs.sln +++ b/test/qs/qs_rx/test.sln @@ -1,21 +1,21 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 16 -VisualStudioVersion = 16.0.33130.400 +VisualStudioVersion = 16.0.30804.86 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "qube_vs", "qube_vs.vcxproj", "{8CC465F7-872E-4D03-B93C-1B64858B4E11}" +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test", "test.vcxproj", "{8CC465F7-872E-4D03-B93C-1B64858B4E11}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution - qube_vs|x86 = qube_vs|x86 + Debug|Win32 = Debug|Win32 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution - {8CC465F7-872E-4D03-B93C-1B64858B4E11}.qube_vs|x86.ActiveCfg = qube_vs|Win32 - {8CC465F7-872E-4D03-B93C-1B64858B4E11}.qube_vs|x86.Build.0 = qube_vs|Win32 + {8CC465F7-872E-4D03-B93C-1B64858B4E11}.Debug|Win32.ActiveCfg = Debug|Win32 + {8CC465F7-872E-4D03-B93C-1B64858B4E11}.Debug|Win32.Build.0 = Debug|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {15807264-0CD3-4BEB-9F83-9E0F04F034E7} + SolutionGuid = {5927F686-5967-4B02-A7EA-25F81A1236DB} EndGlobalSection EndGlobal diff --git a/examples/arm-cm/blinky_ek-tm4c123gxl/qube/qube_vs.vcxproj b/test/qs/qs_rx/test.vcxproj similarity index 50% rename from examples/arm-cm/blinky_ek-tm4c123gxl/qube/qube_vs.vcxproj rename to test/qs/qs_rx/test.vcxproj index de77e033..3ad94465 100644 --- a/examples/arm-cm/blinky_ek-tm4c123gxl/qube/qube_vs.vcxproj +++ b/test/qs/qs_rx/test.vcxproj @@ -1,19 +1,30 @@ - - qube_vs + + Debug Win32 + + + + + + + + + + + {8CC465F7-872E-4D03-B93C-1B64858B4E11} - qube_vs + test Win32Proj 10.0 - + Application NotSet v142 @@ -21,21 +32,21 @@ - + <_ProjectFileVersion>10.0.40219.1 - $(SolutionDir)$(Configuration)\ - $(Configuration)\ - true + $(SolutionDir)$(Configuration)\ + $(Configuration)\ + true - + Disabled - ..;..\..\..\..\include;..\..\..\..\ports\qube;$(QTOOLS)\qspy\include;%(AdditionalIncludeDirectories) - Q_SPY;Q_SPY;WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + .;../../../include;../../et;%(AdditionalIncludeDirectories) + Q_SPY;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) false @@ -45,10 +56,10 @@ Level4 ProgramDatabase 4127 - stdc11 + Default - ws2_32.lib;%(AdditionalDependencies) + %(AdditionalDependencies) %(AdditionalLibraryDirectories) true Console @@ -58,34 +69,6 @@ cmd /c "del $(OutDir)qstamp.obj" - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/test/qs/qs_rx/test.vcxproj.filters b/test/qs/qs_rx/test.vcxproj.filters new file mode 100644 index 00000000..ade04a60 --- /dev/null +++ b/test/qs/qs_rx/test.vcxproj.filters @@ -0,0 +1,34 @@ + + + + + + src + + + src + + + et + + + et + + + src + + + + + {ca98b393-b6d6-4f0f-8d96-ee6821a59d87} + + + {e6ea87c4-df60-4f15-a5dc-c180c1cd2bac} + + + + + et + + + diff --git a/test/qxk/test_sched/bsp.h b/test/qxk/test_sched/bsp.h index a4caa37e..ed5c7477 100644 --- a/test/qxk/test_sched/bsp.h +++ b/test/qxk/test_sched/bsp.h @@ -1,43 +1,41 @@ -/*============================================================================ -* Product: BSP for system-testing -* Last updated for version 7.2.0 -* Last updated on 2022-12-13 -* -* Q u a n t u m L e a P s -* ------------------------ -* Modern Embedded Software -* -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* -* -============================================================================*/ +//============================================================================ +// Product: BSP for system-testing +// Last updated for version 7.3.0 +// Last updated on 2023-09-06 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +//============================================================================ #ifndef BSP_H_ #define BSP_H_ void BSP_init(void); void BSP_terminate(int16_t result); -/* for testing... */ +// for testing... void BSP_trace(QActive const *thr, char const *msg); void BSP_wait4PB1(void); void BSP_ledOn(void); @@ -55,10 +53,10 @@ enum TestSignals { TEST1_SIG, TEST2_SIG, TEST3_SIG, - MAX_PUB_SIG, /* the last published signal */ + MAX_PUB_SIG, // the last published signal - MAX_SIG /* the last signal */ + MAX_SIG // the last signal }; -#endif /* BSP_H_ */ +#endif // BSP_H_ diff --git a/test/qxk/test_sched/bsp_efm32.c b/test/qxk/test_sched/bsp_efm32.c deleted file mode 100644 index b3853019..00000000 --- a/test/qxk/test_sched/bsp_efm32.c +++ /dev/null @@ -1,371 +0,0 @@ -/*============================================================================ -* Product: BSP for system-testing QXK kernel, EFM32-SLSTK3401A board -* Last updated for version 7.2.0 -* Last updated on 2022-12-13 -* -* Q u a n t u m L e a P s -* ------------------------ -* Modern Embedded Software -* -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* -* -============================================================================*/ -#include "qpc.h" -#include "bsp.h" - -#include "em_device.h" /* the device specific header (SiLabs) */ -#include "em_cmu.h" /* Clock Management Unit (SiLabs) */ -#include "em_gpio.h" /* GPIO (SiLabs) */ -#include "em_usart.h" /* USART (SiLabs) */ -/* add other drivers if necessary... */ - -Q_DEFINE_THIS_FILE - -/* ISRs defined in this BSP ------------------------------------------------*/ -void SysTick_Handler(void); -void GPIO_EVEN_IRQHandler(void); - -/* Local-scope objects -----------------------------------------------------*/ -#define LED_PORT gpioPortF -#define LED0_PIN 4 -#define LED1_PIN 5 - -#define PB_PORT gpioPortF -#define PB0_PIN 6 -#define PB1_PIN 7 - -#ifdef Q_SPY - - /* QSpy source IDs */ - static QSpyId const l_SysTick_Handler = { 100U }; - static QSpyId const l_test_ISR = { 101U }; - - enum AppRecords { /* application-specific trace records */ - CONTEXT_SW = QS_USER1, - TRACE_MSG - }; - -#endif - -/*..........................................................................*/ -void SysTick_Handler(void); /* prototype */ -void SysTick_Handler(void) { - QXK_ISR_ENTRY(); /* inform QXK kernel about entering an ISR */ - - /* process time events for rate 0 */ - QTIMEEVT_TICK_X(0U, &l_SysTick_Handler); - //QACTIVE_POST(the_Ticker0, 0, &l_SysTick_Handler); - - QXK_ISR_EXIT(); /* inform QXK kernel about exiting an ISR */ -} -/*..........................................................................*/ -void GPIO_EVEN_IRQHandler(void); /* prototype */ -void GPIO_EVEN_IRQHandler(void) { /* for testing, NOTE03 */ - QXK_ISR_ENTRY(); /* inform QXK kernel about entering an ISR */ - - /* for testing... */ - static QEvt const t1 = { TEST1_SIG, 0U, 0U }; - QACTIVE_PUBLISH(&t1, &l_test_ISR); - - QXK_ISR_EXIT(); /* inform QXK kernel about exiting an ISR */ -} - -/*..........................................................................*/ -/* MPU setup for EFM32PG1B200F256GM48 MCU */ -static void EFM32PG182_MPU_setup(void) { - /* The following MPU configuration contains the general EFM32PG1 memory - * map described in the EFM32PG1 Data Sheet Figure 3.2. EFM32PG1 Memory Map - * - * Please note that the actual STM32 MCUs provide much less Flash and SRAM - * than the maximums configured here. This means that actual MCUs have - * unmapped memory regions (e.g., beyond the actual SRAM). Attempts to - * access these regions causes the HardFault exception, which is the - * desired behavior. - */ - static struct { - uint32_t rbar; - uint32_t rasr; - } const mpu_setup[] = { - - { /* region #0: Flash: base=0x0000'0000, size=512M=2^(28+1) */ - 0x00000000U /* base address */ - | MPU_RBAR_VALID_Msk /* valid region */ - | (MPU_RBAR_REGION_Msk & 0U), /* region #0 */ - (28U << MPU_RASR_SIZE_Pos) /* 2^(18+1) region */ - | (0x6U << MPU_RASR_AP_Pos) /* PA:ro/UA:ro */ - | (1U << MPU_RASR_C_Pos) /* C=1 */ - | MPU_RASR_ENABLE_Msk /* region enable */ - }, - - { /* region #1: SRAM: base=0x2000'0000, size=512M=2^(28+1) */ - 0x20000000U /* base address */ - | MPU_RBAR_VALID_Msk /* valid region */ - | (MPU_RBAR_REGION_Msk & 1U), /* region #1 */ - (28U << MPU_RASR_SIZE_Pos) /* 2^(28+1) region */ - | (0x3U << MPU_RASR_AP_Pos) /* PA:rw/UA:rw */ - | (1U << MPU_RASR_XN_Pos) /* XN=1 */ - | (1U << MPU_RASR_S_Pos) /* S=1 */ - | (1U << MPU_RASR_C_Pos) /* C=1 */ - | MPU_RASR_ENABLE_Msk /* region enable */ - }, - - /* region #3: (not configured) */ - { MPU_RBAR_VALID_Msk | (MPU_RBAR_REGION_Msk & 2U), 0U }, - - { /* region #3: Peripherals: base=0x4000'0000, size=512M=2^(28+1) */ - 0x40000000U /* base address */ - | MPU_RBAR_VALID_Msk /* valid region */ - | (MPU_RBAR_REGION_Msk & 3U), /* region #3 */ - (28U << MPU_RASR_SIZE_Pos) /* 2^(28+1) region */ - | (0x3U << MPU_RASR_AP_Pos) /* PA:rw/UA:rw */ - | (1U << MPU_RASR_XN_Pos) /* XN=1 */ - | (1U << MPU_RASR_S_Pos) /* S=1 */ - | (1U << MPU_RASR_B_Pos) /* B=1 */ - | MPU_RASR_ENABLE_Msk /* region enable */ - }, - - { /* region #4: Priv. Periph: base=0xE000'0000, size=512M=2^(28+1) */ - 0xE0000000U /* base address */ - | MPU_RBAR_VALID_Msk /* valid region */ - | (MPU_RBAR_REGION_Msk & 4U), /* region #4 */ - (28U << MPU_RASR_SIZE_Pos) /* 2^(28+1) region */ - | (0x3U << MPU_RASR_AP_Pos) /* PA:rw/UA:rw */ - | (1U << MPU_RASR_XN_Pos) /* XN=1 */ - | (1U << MPU_RASR_S_Pos) /* S=1 */ - | (1U << MPU_RASR_B_Pos) /* B=1 */ - | MPU_RASR_ENABLE_Msk /* region enable */ - }, - - { /* region #5: Ext RAM: base=0x6000'0000, size=1G=2^(29+1) */ - 0x60000000U /* base address */ - | MPU_RBAR_VALID_Msk /* valid region */ - | (MPU_RBAR_REGION_Msk & 5U), /* region #5 */ - (29U << MPU_RASR_SIZE_Pos) /* 2^(28+1) region */ - | (0x3U << MPU_RASR_AP_Pos) /* PA:rw/UA:rw */ - | (1U << MPU_RASR_XN_Pos) /* XN=1 */ - | (1U << MPU_RASR_S_Pos) /* S=1 */ - | (1U << MPU_RASR_B_Pos) /* B=1 */ - | MPU_RASR_ENABLE_Msk /* region enable */ - }, - - { /* region #6: Ext Dev: base=0xA000'0000, size=1G=2^(29+1) */ - 0xA0000000U /* base address */ - | MPU_RBAR_VALID_Msk /* valid region */ - | (MPU_RBAR_REGION_Msk & 6U), /* region #6 */ - (29U << MPU_RASR_SIZE_Pos) /* 2^(28+1) region */ - | (0x3U << MPU_RASR_AP_Pos) /* PA:rw/UA:rw */ - | (1U << MPU_RASR_XN_Pos) /* XN=1 */ - | (1U << MPU_RASR_S_Pos) /* S=1 */ - | (1U << MPU_RASR_B_Pos) /* B=1 */ - | MPU_RASR_ENABLE_Msk /* region enable */ - }, - - { /* region #7: NULL-pointer: base=0x000'0000, size=256B, NOTE0 */ - 0x00000000U /* base address */ - | MPU_RBAR_VALID_Msk /* valid region */ - | (MPU_RBAR_REGION_Msk & 7U), /* region #7 */ - (7U << MPU_RASR_SIZE_Pos) /* 2^(7+1)=256B region */ - | (0x0U << MPU_RASR_AP_Pos) /* PA:na/UA:na */ - | (1U << MPU_RASR_XN_Pos) /* XN=1 */ - | MPU_RASR_ENABLE_Msk /* region enable */ - }, - }; - - /* enable the MemManage_Handler for MPU exception */ - SCB->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk; - - __DSB(); - MPU->CTRL = 0U; /* disable the MPU */ - for (uint_fast8_t n = 0U; n < Q_DIM(mpu_setup); ++n) { - MPU->RBAR = mpu_setup[n].rbar; - MPU->RASR = mpu_setup[n].rasr; - } - MPU->CTRL = MPU_CTRL_ENABLE_Msk; /* enable the MPU */ - __ISB(); - __DSB(); -} - -/*..........................................................................*/ -void BSP_init(void) { - /* setup the MPU... */ - EFM32PG182_MPU_setup(); - - /* NOTE: SystemInit() has been already called from the startup code - * but SystemCoreClock needs to be updated - */ - SystemCoreClockUpdate(); - - /* NOTE: The VFP (hardware Floating Point) unit is configured by QK */ - - /* enable clock for to the peripherals used by this application... */ - CMU_ClockEnable(cmuClock_HFPER, true); - CMU_ClockEnable(cmuClock_GPIO, true); - CMU_ClockEnable(cmuClock_HFPER, true); - CMU_ClockEnable(cmuClock_GPIO, true); - - /* configure the LEDs */ - GPIO_PinModeSet(LED_PORT, LED0_PIN, gpioModePushPull, 0); - GPIO_PinModeSet(LED_PORT, LED1_PIN, gpioModePushPull, 0); - GPIO_PinOutClear(LED_PORT, LED0_PIN); - GPIO_PinOutClear(LED_PORT, LED1_PIN); - - /* configure the Buttons */ - GPIO_PinModeSet(PB_PORT, PB0_PIN, gpioModeInputPull, 1); - GPIO_PinModeSet(PB_PORT, PB1_PIN, gpioModeInputPull, 1); - - if (QS_INIT((void *)0) == 0) { /* initialize the QS software tracing */ - Q_ERROR(); - } - QS_OBJ_DICTIONARY(&l_SysTick_Handler); - QS_OBJ_DICTIONARY(&l_test_ISR); - - QS_USR_DICTIONARY(CONTEXT_SW); - QS_USR_DICTIONARY(TRACE_MSG); -} -/*..........................................................................*/ -void BSP_terminate(int16_t result) { - Q_UNUSED_PAR(result); -} -/*..........................................................................*/ -void BSP_ledOn(void) { - GPIO->P[LED_PORT].DOUT |= (1U << LED0_PIN); -} -/*..........................................................................*/ -void BSP_ledOff(void) { - GPIO->P[LED_PORT].DOUT &= ~(1U << LED0_PIN); -} -/*..........................................................................*/ -void BSP_trigISR(void) { - NVIC_SetPendingIRQ(GPIO_EVEN_IRQn); -} -/*..........................................................................*/ -void BSP_trace(QActive const *thr, char const *msg) { - QS_BEGIN(TRACE_MSG, 0U) - QS_OBJ(thr); - QS_STR(msg); - QS_END() -} -/*..........................................................................*/ -uint32_t BSP_romRead(int32_t offset, uint32_t fromEnd) { - int32_t const rom_base = (fromEnd == 0U) - ? 0x100 /* don't include the NULL-ptr region */ - : 0x40000 - 4; - return *(uint32_t volatile *)(rom_base + offset); -} -/*..........................................................................*/ -void BSP_romWrite(int32_t offset, uint32_t fromEnd, uint32_t value) { - int32_t const rom_base = (fromEnd == 0U) - ? 0x100 /* don't include the NULL-ptr region */ - : 0x40000 - 4; - *(uint32_t volatile *)(rom_base + offset) = value; -} - -/*..........................................................................*/ -uint32_t BSP_ramRead(int32_t offset, uint32_t fromEnd) { - int32_t const ram_base = (fromEnd == 0U) - ? 0x20000000 - : 0x20008000 - 4; - return *(uint32_t volatile *)(ram_base + offset); -} -/*..........................................................................*/ -void BSP_ramWrite(int32_t offset, uint32_t fromEnd, uint32_t value) { - int32_t const ram_base = (fromEnd == 0U) - ? 0x20000000 - : 0x20008000 - 4; - *(uint32_t volatile *)(ram_base + offset) = value; -} - -/*..........................................................................*/ -void QF_onStartup(void) { - /* set up the SysTick timer to fire at BSP_TICKS_PER_SEC rate */ - //SysTick_Config(SystemCoreClock / BSP_TICKS_PER_SEC); - - /* assign all priority bits for preemption-prio. and none to sub-prio. */ - NVIC_SetPriorityGrouping(0U); - - /* set priorities of ALL ISRs used in the system */ - NVIC_SetPriority(GPIO_EVEN_IRQn, QF_AWARE_ISR_CMSIS_PRI + 0U); - NVIC_SetPriority(SysTick_IRQn, QF_AWARE_ISR_CMSIS_PRI + 1U); - /* NOTE: priority of UART IRQ used for QS-RX is set in qutest_port.c */ - /* ... */ - - /* enable IRQs... */ - NVIC_EnableIRQ(GPIO_EVEN_IRQn); -} -/*..........................................................................*/ -void QF_onCleanup(void) { -} -/*..........................................................................*/ -#ifdef QF_ON_CONTEXT_SW -/* NOTE: the context-switch callback is called with interrupts DISABLED */ -void QF_onContextSw(QActive *prev, QActive *next) { - QS_BEGIN_NOCRIT(CONTEXT_SW, 0U) /* no critical section! */ - QS_OBJ(prev); - QS_OBJ(next); - QS_END_NOCRIT() -} -#endif /* QF_ON_CONTEXT_SW */ -/*..........................................................................*/ -void QXK_onIdle(void) { - - GPIO->P[LED_PORT].DOUT |= (1U << LED1_PIN); - GPIO->P[LED_PORT].DOUT &= ~(1U << LED1_PIN); - -#ifdef Q_SPY - QS_rxParse(); /* parse all the received bytes */ - QS_doOutput(); -#elif defined NDEBUG - /* Put the CPU and peripherals to the low-power mode. - * you might need to customize the clock management for your application, - * see the datasheet for your particular Cortex-M3 MCU. - */ - __WFI(); /* Wait-For-Interrupt */ -#endif -} - -/* QS callbacks ============================================================*/ -#ifdef Q_SPY - -/*..........................................................................*/ -void QTimeEvt_tick1_( - uint_fast8_t const tickRate, - void const * const sender) -{ - QF_INT_DISABLE(); - /* TODO pend the SysTick */ - *Q_UINT2PTR_CAST(uint32_t, 0xE000ED04U) = (1U << 26U); - QF_INT_ENABLE(); -} - -#endif /* Q_SPY */ - -/*============================================================================ -* NOTE0: -* The MPU protection against NULL-pointer dereferencing sets up a no-access -* MPU region #7 around the NULL address (0x0). This works even though the -* Vector Table also resides at address 0x0. However, the *size* of the -* no-access region should not exceed the size of the Vector Table. In this -* case, the size is set to 2**(7+1)==256 bytes, which does not contain any -* data that the CPU would legitimately read with the LDR instruction. -*/ diff --git a/test/qxk/test_sched/bsp_efm32pg1b.c b/test/qxk/test_sched/bsp_efm32pg1b.c new file mode 100644 index 00000000..53e015fe --- /dev/null +++ b/test/qxk/test_sched/bsp_efm32pg1b.c @@ -0,0 +1,372 @@ +//============================================================================ +// Product: BSP for system-testing of QXK kernel, EFM32-SLSTK3401A board +// Last updated for version 7.3.0 +// Last updated on 2023-07-18 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// This program is open source software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Alternatively, this program may be distributed and modified under the +// terms of Quantum Leaps commercial licenses, which expressly supersede +// the GNU General Public License and are specifically designed for +// licensees interested in retaining the proprietary status of their code. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Contact information: +// +// +//============================================================================ +#include "qpc.h" +#include "bsp.h" + +#include "em_device.h" // the device specific header (SiLabs) +#include "em_cmu.h" // Clock Management Unit (SiLabs) +#include "em_gpio.h" // GPIO (SiLabs) +#include "em_usart.h" // USART (SiLabs) +// add other drivers if necessary... + +Q_DEFINE_THIS_FILE + +// ISRs defined in this BSP ------------------------------------------------ +void SysTick_Handler(void); +void GPIO_EVEN_IRQHandler(void); + +// Local-scope objects ----------------------------------------------------- +#define LED_PORT gpioPortF +#define LED0_PIN 4 +#define LED1_PIN 5 + +#define PB_PORT gpioPortF +#define PB0_PIN 6 +#define PB1_PIN 7 + +#ifdef Q_SPY + + // QSpy source IDs + static QSpyId const l_SysTick_Handler = { 100U }; + static QSpyId const l_test_ISR = { 101U }; + + enum AppRecords { // application-specific trace records + CONTEXT_SW = QS_USER1, + TRACE_MSG + }; + +#endif + +//.......................................................................... +void SysTick_Handler(void); // prototype +void SysTick_Handler(void) { + QXK_ISR_ENTRY(); // inform QXK kernel about entering an ISR + + // process time events for rate 0 + QTIMEEVT_TICK_X(0U, &l_SysTick_Handler); + //QTICKER_TRIG(the_Ticker0, &l_SysTick_Handler); /* trigger ticker AO */ + + QXK_ISR_EXIT(); // inform QXK kernel about exiting an ISR +} +//.......................................................................... +void GPIO_EVEN_IRQHandler(void); // prototype +void GPIO_EVEN_IRQHandler(void) { // for testing, NOTE03 + QXK_ISR_ENTRY(); // inform QXK kernel about entering an ISR + + // for testing... + static QEvt const t1 = QEVT_INITIALIZER(TEST1_SIG); + QACTIVE_PUBLISH(&t1, &l_test_ISR); + + QXK_ISR_EXIT(); // inform QXK kernel about exiting an ISR +} + +//.......................................................................... +// MPU setup for EFM32PG1B200F256GM48 MCU +static void EFM32PG182_MPU_setup(void) { + // The following MPU configuration contains the general EFM32PG1 memory + // map described in the EFM32PG1 Data Sheet Figure 3.2. EFM32PG1 Memory Map + // + // Please note that the actual STM32 MCUs provide much less Flash and SRAM + // than the maximums configured here. This means that actual MCUs have + // unmapped memory regions (e.g., beyond the actual SRAM). Attempts to + // access these regions causes the HardFault exception, which is the + // desired behavior. + // + static struct { + uint32_t rbar; + uint32_t rasr; + } const mpu_setup[] = { + + { // region #0: Flash: base=0x0000'0000, size=512M=2^(28+1) + 0x00000000U // base address + | MPU_RBAR_VALID_Msk // valid region + | (MPU_RBAR_REGION_Msk & 0U), // region #0 + (28U << MPU_RASR_SIZE_Pos) // 2^(18+1) region + | (0x6U << MPU_RASR_AP_Pos) // PA:ro/UA:ro + | (1U << MPU_RASR_C_Pos) // C=1 + | MPU_RASR_ENABLE_Msk // region enable + }, + + { // region #1: SRAM: base=0x2000'0000, size=512M=2^(28+1) + 0x20000000U // base address + | MPU_RBAR_VALID_Msk // valid region + | (MPU_RBAR_REGION_Msk & 1U), // region #1 + (28U << MPU_RASR_SIZE_Pos) // 2^(28+1) region + | (0x3U << MPU_RASR_AP_Pos) // PA:rw/UA:rw + | (1U << MPU_RASR_XN_Pos) // XN=1 + | (1U << MPU_RASR_S_Pos) // S=1 + | (1U << MPU_RASR_C_Pos) // C=1 + | MPU_RASR_ENABLE_Msk // region enable + }, + + // region #3: (not configured) + { MPU_RBAR_VALID_Msk | (MPU_RBAR_REGION_Msk & 2U), 0U }, + + { // region #3: Peripherals: base=0x4000'0000, size=512M=2^(28+1) + 0x40000000U // base address + | MPU_RBAR_VALID_Msk // valid region + | (MPU_RBAR_REGION_Msk & 3U), // region #3 + (28U << MPU_RASR_SIZE_Pos) // 2^(28+1) region + | (0x3U << MPU_RASR_AP_Pos) // PA:rw/UA:rw + | (1U << MPU_RASR_XN_Pos) // XN=1 + | (1U << MPU_RASR_S_Pos) // S=1 + | (1U << MPU_RASR_B_Pos) // B=1 + | MPU_RASR_ENABLE_Msk // region enable + }, + + { // region #4: Priv. Periph: base=0xE000'0000, size=512M=2^(28+1) + 0xE0000000U // base address + | MPU_RBAR_VALID_Msk // valid region + | (MPU_RBAR_REGION_Msk & 4U), // region #4 + (28U << MPU_RASR_SIZE_Pos) // 2^(28+1) region + | (0x3U << MPU_RASR_AP_Pos) // PA:rw/UA:rw + | (1U << MPU_RASR_XN_Pos) // XN=1 + | (1U << MPU_RASR_S_Pos) // S=1 + | (1U << MPU_RASR_B_Pos) // B=1 + | MPU_RASR_ENABLE_Msk // region enable + }, + + { // region #5: Ext RAM: base=0x6000'0000, size=1G=2^(29+1) + 0x60000000U // base address + | MPU_RBAR_VALID_Msk // valid region + | (MPU_RBAR_REGION_Msk & 5U), // region #5 + (29U << MPU_RASR_SIZE_Pos) // 2^(28+1) region + | (0x3U << MPU_RASR_AP_Pos) // PA:rw/UA:rw + | (1U << MPU_RASR_XN_Pos) // XN=1 + | (1U << MPU_RASR_S_Pos) // S=1 + | (1U << MPU_RASR_B_Pos) // B=1 + | MPU_RASR_ENABLE_Msk // region enable + }, + + { // region #6: Ext Dev: base=0xA000'0000, size=1G=2^(29+1) + 0xA0000000U // base address + | MPU_RBAR_VALID_Msk // valid region + | (MPU_RBAR_REGION_Msk & 6U), // region #6 + (29U << MPU_RASR_SIZE_Pos) // 2^(28+1) region + | (0x3U << MPU_RASR_AP_Pos) // PA:rw/UA:rw + | (1U << MPU_RASR_XN_Pos) // XN=1 + | (1U << MPU_RASR_S_Pos) // S=1 + | (1U << MPU_RASR_B_Pos) // B=1 + | MPU_RASR_ENABLE_Msk // region enable + }, + + { // region #7: NULL-pointer: base=0x000'0000, size=256B, NOTE0 + 0x00000000U // base address + | MPU_RBAR_VALID_Msk // valid region + | (MPU_RBAR_REGION_Msk & 7U), // region #7 + (7U << MPU_RASR_SIZE_Pos) // 2^(7+1)=256B region + | (0x0U << MPU_RASR_AP_Pos) // PA:na/UA:na + | (1U << MPU_RASR_XN_Pos) // XN=1 + | MPU_RASR_ENABLE_Msk // region enable + }, + }; + + // enable the MemManage_Handler for MPU exception + SCB->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk; + + __DSB(); + MPU->CTRL = 0U; // disable the MPU + for (uint_fast8_t n = 0U; n < Q_DIM(mpu_setup); ++n) { + MPU->RBAR = mpu_setup[n].rbar; + MPU->RASR = mpu_setup[n].rasr; + } + MPU->CTRL = MPU_CTRL_ENABLE_Msk; // enable the MPU + __ISB(); + __DSB(); +} + +//.......................................................................... +void BSP_init(void) { + // setup the MPU... + EFM32PG182_MPU_setup(); + + // NOTE: SystemInit() has been already called from the startup code + // but SystemCoreClock needs to be updated + // + SystemCoreClockUpdate(); + + // NOTE: The VFP (hardware Floating Point) unit is configured by QK + + // enable clock for to the peripherals used by this application... + CMU_ClockEnable(cmuClock_HFPER, true); + CMU_ClockEnable(cmuClock_GPIO, true); + CMU_ClockEnable(cmuClock_HFPER, true); + CMU_ClockEnable(cmuClock_GPIO, true); + + // configure the LEDs + GPIO_PinModeSet(LED_PORT, LED0_PIN, gpioModePushPull, 0); + GPIO_PinModeSet(LED_PORT, LED1_PIN, gpioModePushPull, 0); + GPIO_PinOutClear(LED_PORT, LED0_PIN); + GPIO_PinOutClear(LED_PORT, LED1_PIN); + + // configure the Buttons + GPIO_PinModeSet(PB_PORT, PB0_PIN, gpioModeInputPull, 1); + GPIO_PinModeSet(PB_PORT, PB1_PIN, gpioModeInputPull, 1); + + // initialize the QS software tracing... + if (QS_INIT((void *)0) == 0) { // initialize the QS software tracing + Q_ERROR(); + } + QS_OBJ_DICTIONARY(&l_SysTick_Handler); + QS_OBJ_DICTIONARY(&l_test_ISR); + + QS_USR_DICTIONARY(CONTEXT_SW); + QS_USR_DICTIONARY(TRACE_MSG); +} +//.......................................................................... +void BSP_terminate(int16_t result) { + Q_UNUSED_PAR(result); +} +//.......................................................................... +void BSP_ledOn(void) { + GPIO->P[LED_PORT].DOUT |= (1U << LED0_PIN); +} +//.......................................................................... +void BSP_ledOff(void) { + GPIO->P[LED_PORT].DOUT &= ~(1U << LED0_PIN); +} +//.......................................................................... +void BSP_trigISR(void) { + NVIC_SetPendingIRQ(GPIO_EVEN_IRQn); +} +//.......................................................................... +void BSP_trace(QActive const *thr, char const *msg) { + QS_BEGIN(TRACE_MSG, 0U) + QS_OBJ(thr); + QS_STR(msg); + QS_END() +} +//.......................................................................... +uint32_t BSP_romRead(int32_t offset, uint32_t fromEnd) { + int32_t const rom_base = (fromEnd == 0U) + ? 0x100 // don't include the NULL-ptr region + : 0x40000 - 4; + return *(uint32_t volatile *)(rom_base + offset); +} +//.......................................................................... +void BSP_romWrite(int32_t offset, uint32_t fromEnd, uint32_t value) { + int32_t const rom_base = (fromEnd == 0U) + ? 0x100 // don't include the NULL-ptr region + : 0x40000 - 4; + *(uint32_t volatile *)(rom_base + offset) = value; +} + +//.......................................................................... +uint32_t BSP_ramRead(int32_t offset, uint32_t fromEnd) { + int32_t const ram_base = (fromEnd == 0U) + ? 0x20000000 + : 0x20008000 - 4; + return *(uint32_t volatile *)(ram_base + offset); +} +//.......................................................................... +void BSP_ramWrite(int32_t offset, uint32_t fromEnd, uint32_t value) { + int32_t const ram_base = (fromEnd == 0U) + ? 0x20000000 + : 0x20008000 - 4; + *(uint32_t volatile *)(ram_base + offset) = value; +} + +//.......................................................................... +void QF_onStartup(void) { + // set up the SysTick timer to fire at BSP_TICKS_PER_SEC rate + //SysTick_Config(SystemCoreClock / BSP_TICKS_PER_SEC); + + // assign all priority bits for preemption-prio. and none to sub-prio. + NVIC_SetPriorityGrouping(0U); + + // set priorities of ALL ISRs used in the system + NVIC_SetPriority(GPIO_EVEN_IRQn, QF_AWARE_ISR_CMSIS_PRI + 0U); + NVIC_SetPriority(SysTick_IRQn, QF_AWARE_ISR_CMSIS_PRI + 1U); + // NOTE: priority of UART IRQ used for QS-RX is set in qutest_port.c + // ... + + // enable IRQs... + NVIC_EnableIRQ(GPIO_EVEN_IRQn); +} +//.......................................................................... +void QF_onCleanup(void) { +} +//.......................................................................... +#ifdef QF_ON_CONTEXT_SW +// NOTE: the context-switch callback is called with interrupts DISABLED +void QF_onContextSw(QActive *prev, QActive *next) { + QS_BEGIN_INCRIT(CONTEXT_SW, 0U) // in critical section! + QS_OBJ(prev); + QS_OBJ(next); + QS_END_INCRIT() +} +#endif // QF_ON_CONTEXT_SW +//.......................................................................... +void QXK_onIdle(void) { + + GPIO->P[LED_PORT].DOUT |= (1U << LED1_PIN); + GPIO->P[LED_PORT].DOUT &= ~(1U << LED1_PIN); + +#ifdef Q_SPY + QS_rxParse(); // parse all the received bytes + QS_doOutput(); +#elif defined NDEBUG + // Put the CPU and peripherals to the low-power mode. + // you might need to customize the clock management for your application, + // see the datasheet for your particular Cortex-M3 MCU. + // + __WFI(); // Wait-For-Interrupt +#endif +} + +// QS callbacks ============================================================ +#ifdef Q_SPY + +//.......................................................................... +void QTimeEvt_tick1_( + uint_fast8_t const tickRate, + void const * const sender) +{ + QF_INT_DISABLE(); + // TODO pend the SysTick + *Q_UINT2PTR_CAST(uint32_t, 0xE000ED04U) = (1U << 26U); + QF_INT_ENABLE(); +} + +#endif // Q_SPY + +//============================================================================ +// NOTE0: +// The MPU protection against NULL-pointer dereferencing sets up a no-access +// MPU region #7 around the NULL address (0x0). This works even though the +// Vector Table also resides at address 0x0. However, the *size* of the +// no-access region should not exceed the size of the Vector Table. In this +// case, the size is set to 2**(7+1)==256 bytes, which does not contain any +// data that the CPU would legitimately read with the LDR instruction. +// diff --git a/test/qxk/test_sched/bsp_h743zi.c b/test/qxk/test_sched/bsp_h743zi.c deleted file mode 100644 index a5cc5048..00000000 --- a/test/qxk/test_sched/bsp_h743zi.c +++ /dev/null @@ -1,300 +0,0 @@ -/*============================================================================ -* Product: BSP for system-testing of QXK kernel, NUCLEO-H743ZI board -* Last updated for version 7.2.0 -* Last updated on 2022-12-15 -* -* Q u a n t u m L e a P s -* ------------------------ -* Modern Embedded Software -* -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* -* -============================================================================*/ -#include "qpc.h" -#include "bsp.h" - -/* STM32CubeH7 include files */ -#include "stm32h7xx_hal.h" -#include "stm32h7xx_nucleo_144.h" -/* add other drivers if necessary... */ - -Q_DEFINE_THIS_FILE - -#ifdef Q_SPY - - /* QSpy source IDs */ - static QSpyId const l_SysTick_Handler = { 100U }; - static QSpyId const l_test_ISR = { 101U }; - - enum AppRecords { /* application-specific trace records */ - CONTEXT_SW = QS_USER1, - TRACE_MSG - }; - -#endif - -/* ISRs used in this project ===============================================*/ -void SysTick_Handler(void); /* prototype */ -void SysTick_Handler(void) { - QXK_ISR_ENTRY(); /* inform QXK kernel about entering an ISR */ - - /* process time events for rate 0 */ - QTIMEEVT_TICK_X(0U, &l_SysTick_Handler); - - QXK_ISR_EXIT(); /* inform QXK kernel about exiting an ISR */ -} -/*..........................................................................*/ -void EXTI0_IRQHandler(void); /* prototype */ -void EXTI0_IRQHandler(void) { /* for testing, NOTE03 */ - QXK_ISR_ENTRY(); /* inform QXK kernel about entering an ISR */ - - /* for testing... */ - static QEvt const t1 = { TEST1_SIG, 0U, 0U }; - QACTIVE_PUBLISH(&t1, &l_test_ISR); - - QXK_ISR_EXIT(); /* inform QXK kernel about exiting an ISR */ -} - -/* BSP functions ===========================================================*/ -/*..........................................................................*/ -/* MPU setup for STM32H743ZI MCU */ -static void STM32H743ZI_MPU_setup(void) { - /* The following MPU configuration contains just a generic ROM - * region (with read-only access) and NULL-pointer protection region. - * Otherwise, the MPU will fall back on the background region (PRIVDEFENA). - */ - static struct { - uint32_t rbar; - uint32_t rasr; - } const mpu_setup[] = { - - { /* region #0: Flash: base=0x0000'0000, size=512M=2^(28+1) */ - 0x00000000U /* base address */ - | MPU_RBAR_VALID_Msk /* valid region */ - | (MPU_RBAR_REGION_Msk & 0U), /* region #0 */ - (28U << MPU_RASR_SIZE_Pos) /* 2^(18+1) region */ - | (0x6U << MPU_RASR_AP_Pos) /* PA:ro/UA:ro */ - | (1U << MPU_RASR_C_Pos) /* C=1 */ - | MPU_RASR_ENABLE_Msk /* region enable */ - }, - - { /* region #7: NULL-pointer: base=0x000'0000, size=128M=2^(26+1) */ - /* NOTE: this region extends to 0x080'0000, which is where - * the ROM is re-mapped by STM32 - */ - 0x00000000U /* base address */ - | MPU_RBAR_VALID_Msk /* valid region */ - | (MPU_RBAR_REGION_Msk & 7U), /* region #7 */ - (26U << MPU_RASR_SIZE_Pos) /* 2^(26+1)=128M region */ - | (0x0U << MPU_RASR_AP_Pos) /* PA:na/UA:na */ - | (1U << MPU_RASR_XN_Pos) /* XN=1 */ - | MPU_RASR_ENABLE_Msk /* region enable */ - }, - }; - - /* enable the MemManage_Handler for MPU exception */ - SCB->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk; - - __DSB(); - MPU->CTRL = 0U; /* disable the MPU */ - for (uint_fast8_t n = 0U; n < Q_DIM(mpu_setup); ++n) { - MPU->RBAR = mpu_setup[n].rbar; - MPU->RASR = mpu_setup[n].rasr; - } - MPU->CTRL = MPU_CTRL_ENABLE_Msk /* enable the MPU */ - | MPU_CTRL_PRIVDEFENA_Msk; /* enable background region */ - __ISB(); - __DSB(); -} - -/*..........................................................................*/ -void BSP_init(void) { - /* setup the MPU... */ - STM32H743ZI_MPU_setup(); - - /* NOTE: SystemInit() has been already called from the startup code - * but SystemCoreClock needs to be updated - */ - SystemCoreClockUpdate(); - - SCB_EnableICache(); /* Enable I-Cache */ - SCB_EnableDCache(); /* Enable D-Cache */ - - /* Configure Flash prefetch and Instr. cache through ART accelerator */ -#if (ART_ACCLERATOR_ENABLE != 0) - __HAL_FLASH_ART_ENABLE(); -#endif /* ART_ACCLERATOR_ENABLE */ - - /* Configure the LEDs */ - BSP_LED_Init(LED1); - BSP_LED_Init(LED2); - BSP_LED_Init(LED3); - - /* Configure the User Button in GPIO Mode */ - BSP_PB_Init(BUTTON_USER, BUTTON_MODE_GPIO); - - if (QS_INIT((void *)0) == 0) { /* initialize the QS software tracing */ - Q_ERROR(); - } - - /* dictionaries... */ - QS_OBJ_DICTIONARY(&l_SysTick_Handler); - QS_OBJ_DICTIONARY(&l_test_ISR); - - QS_USR_DICTIONARY(CONTEXT_SW); - QS_USR_DICTIONARY(TRACE_MSG); -} -/*..........................................................................*/ -void BSP_terminate(int16_t result) { - Q_UNUSED_PAR(result); -} -/*..........................................................................*/ -void BSP_ledOn(void) { - BSP_LED_On(LED1); -} -/*..........................................................................*/ -void BSP_ledOff(void) { - BSP_LED_Off(LED1); -} -/*..........................................................................*/ -void BSP_trigISR(void) { - NVIC_SetPendingIRQ(EXTI0_IRQn); -} -/*..........................................................................*/ -void BSP_trace(QActive const *thr, char const *msg) { - QS_BEGIN_ID(TRACE_MSG, 0U) - QS_OBJ(thr); - QS_STR(msg); - QS_END() -} -/*..........................................................................*/ -uint32_t BSP_romRead(int32_t offset, uint32_t fromEnd) { - int32_t const rom_base = (fromEnd == 0U) - ? 0x08000000 - : 0x08200000 - 4; - return *(uint32_t volatile *)(rom_base + offset); -} -/*..........................................................................*/ -void BSP_romWrite(int32_t offset, uint32_t fromEnd, uint32_t value) { - int32_t const rom_base = (fromEnd == 0U) - ? 0x08000000 - : 0x08200000 - 4; - *(uint32_t volatile *)(rom_base + offset) = value; -} - -/*..........................................................................*/ -uint32_t BSP_ramRead(int32_t offset, uint32_t fromEnd) { - int32_t const ram_base = (fromEnd == 0U) - ? 0x20000000 - : 0x20020000 - 4; - return *(uint32_t volatile *)(ram_base + offset); -} -/*..........................................................................*/ -void BSP_ramWrite(int32_t offset, uint32_t fromEnd, uint32_t value) { - int32_t const ram_base = (fromEnd == 0U) - ? 0x20000000 - : 0x20020000 - 4; - *(uint32_t volatile *)(ram_base + offset) = value; -} - -/*..........................................................................*/ -void QF_onStartup(void) { - /* set up the SysTick timer to fire at BSP_TICKS_PER_SEC rate */ - //NOTE: don't start ticking for these tests - //SysTick_Config(SystemCoreClock / BSP_TICKS_PER_SEC); - - /* assign all priority bits for preemption-prio. and none to sub-prio. - * NOTE: this might have been changed by STM32Cube. - */ - NVIC_SetPriorityGrouping(0U); - - /* set priorities of ALL ISRs used in the system, see NOTE1 - * - * !!!!!!!!!!!!!!!!!!!!!!!!!!!! CAUTION !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - * Assign a priority to EVERY ISR explicitly by calling NVIC_SetPriority(). - * DO NOT LEAVE THE ISR PRIORITIES AT THE DEFAULT VALUE! - */ - NVIC_SetPriority(SysTick_IRQn, QF_AWARE_ISR_CMSIS_PRI + 0U); - NVIC_SetPriority(EXTI0_IRQn, QF_AWARE_ISR_CMSIS_PRI + 1U); - /* ... */ - - /* enable IRQs... */ - NVIC_EnableIRQ(EXTI0_IRQn); -} -/*..........................................................................*/ -void QF_onCleanup(void) { -} -/*..........................................................................*/ -#ifdef QF_ON_CONTEXT_SW -/* NOTE: the context-switch callback is called with interrupts DISABLED */ -void QF_onContextSw(QActive *prev, QActive *next) { - QS_BEGIN_NOCRIT(CONTEXT_SW, 0U) /* no critical section! */ - QS_OBJ(prev); - QS_OBJ(next); - QS_END_NOCRIT() -} -#endif /* QF_ON_CONTEXT_SW */ - -/*..........................................................................*/ -void QXK_onIdle(void) { -#ifdef Q_SPY - QS_rxParse(); /* parse all the received bytes */ - QS_doOutput(); -#elif defined NDEBUG - /* Put the CPU and peripherals to the low-power mode. - * you might need to customize the clock management for your application, - * see the datasheet for your particular Cortex-M3 MCU. - */ - __WFI(); /* Wait-For-Interrupt */ -#endif -} - -/* QS callbacks ============================================================*/ -#ifdef Q_SPY - -/*..........................................................................*/ -void QTimeEvt_tick1_( - uint_fast8_t const tickRate, - void const * const sender) -{ - QF_INT_DISABLE(); - /* TODO pend the SysTick */ - *Q_UINT2PTR_CAST(uint32_t, 0xE000ED04U) = (1U << 26U); - QF_INT_ENABLE(); -} - -#endif /* Q_SPY */ - -/*============================================================================ -* NOTE0: -* The MPU protection against NULL-pointer dereferencing sets up a no-access -* MPU region #7 around the NULL address (0x0). The size of this region is set -* to 2**(26+1)==0x0800'0000, because that is the address of Flash in STM32. -* -* REMARK: STM32 MCUs automatically relocate the Flash memory and the Vector -* Table in it to address 0x0800'0000 at startup. However, even though the -* region 0..0x0800'0000 is un-mapped after the relocation, the read access -* is still allowed and causes no CPU exception. Therefore setting up the MPU -* to protect that region is necessary. -*/ diff --git a/test/qxk/test_sched/bsp_l053r8.c b/test/qxk/test_sched/bsp_l053r8.c deleted file mode 100644 index 7d79db6f..00000000 --- a/test/qxk/test_sched/bsp_l053r8.c +++ /dev/null @@ -1,365 +0,0 @@ -/*============================================================================ -* Product: BSP for system-testing QXK kernel, NUCLEO-L053R8 board -* Last updated for version 7.2.0 -* Last updated on 2022-12-13 -* -* Q u a n t u m L e a P s -* ------------------------ -* Modern Embedded Software -* -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* -* -============================================================================*/ -#include "qpc.h" -#include "bsp.h" - -#include "stm32l0xx.h" /* CMSIS-compliant header file for the MCU used */ -/* add other drivers if necessary... */ - -Q_DEFINE_THIS_FILE - -/* Local-scope objects -----------------------------------------------------*/ -/* LED pins available on the board (just one user LED LD2--Green on PA.5) */ -#define LED_LD2 (1U << 5) - -/* Button pins available on the board (just one user Button B1 on PC.13) */ -#define BTN_B1 (1U << 13) - -#ifdef Q_SPY - /* QSpy source IDs */ - static QSpyId const l_SysTick_Handler = { 100U }; - static QSpyId const l_test_ISR = { 101U }; - - enum AppRecords { /* application-specific trace records */ - CONTEXT_SW = QS_USER1, - TRACE_MSG - }; - -#endif - -/*..........................................................................*/ -void SysTick_Handler(void); /* prototype */ -void SysTick_Handler(void) { - QXK_ISR_ENTRY(); /* inform QXK kernel about entering an ISR */ - - /* process time events for rate 0 */ - QTIMEEVT_TICK_X(0U, &l_SysTick_Handler); - //QACTIVE_POST(the_Ticker0, 0, &l_SysTick_Handler); - - QXK_ISR_EXIT(); /* inform QXK kernel about exiting an ISR */ -} -/*..........................................................................*/ -void EXTI0_1_IRQHandler(void); /* prototype */ -void EXTI0_1_IRQHandler(void) { /* for testing, NOTE03 */ - QXK_ISR_ENTRY(); /* inform QXK kernel about entering an ISR */ - - /* for testing... */ - static QEvt const t1 = { TEST1_SIG, 0U, 0U }; - QACTIVE_PUBLISH(&t1, &l_test_ISR); - - QXK_ISR_EXIT(); /* inform QXK kernel about exiting an ISR */ -} - -/*..........................................................................*/ -/* MPU setup for STM32L053R8 MCU */ -static void STM32L053R8_MPU_setup(void) { - /* The following MPU configuration contains the general STM32 memory model - * as described in the ST AppNote AN4838 "Managing memory protection unit - * in STM32 MCUs", Figure 2. Cortex-M0+/M3/M4/M7 processor memory map. - * - * Please note that the actual STM32 MCUs provide much less Flash and SRAM - * than the maximums configured here. This means that actual MCUs have - * unmapped memory regions (e.g., beyond the actual SRAM). Attempts to - * access these regions causes the HardFault exception, which is the - * desired behavior. - */ - static struct { - uint32_t rbar; - uint32_t rasr; - } const mpu_setup[] = { - - { /* region #0: Flash: base=0x0000'0000, size=512M=2^(28+1) */ - 0x00000000U /* base address */ - | MPU_RBAR_VALID_Msk /* valid region */ - | (MPU_RBAR_REGION_Msk & 0U), /* region #0 */ - (28U << MPU_RASR_SIZE_Pos) /* 2^(18+1) region */ - | (0x6U << MPU_RASR_AP_Pos) /* PA:ro/UA:ro */ - | (1U << MPU_RASR_C_Pos) /* C=1 */ - | MPU_RASR_ENABLE_Msk /* region enable */ - }, - - { /* region #1: SRAM: base=0x2000'0000, size=512M=2^(28+1) */ - 0x20000000U /* base address */ - | MPU_RBAR_VALID_Msk /* valid region */ - | (MPU_RBAR_REGION_Msk & 1U), /* region #1 */ - (28U << MPU_RASR_SIZE_Pos) /* 2^(28+1) region */ - | (0x3U << MPU_RASR_AP_Pos) /* PA:rw/UA:rw */ - | (1U << MPU_RASR_XN_Pos) /* XN=1 */ - | (1U << MPU_RASR_S_Pos) /* S=1 */ - | (1U << MPU_RASR_C_Pos) /* C=1 */ - | MPU_RASR_ENABLE_Msk /* region enable */ - }, - - /* region #3: (not configured) */ - { MPU_RBAR_VALID_Msk | (MPU_RBAR_REGION_Msk & 2U), 0U }, - - { /* region #3: Peripherals: base=0x4000'0000, size=512M=2^(28+1) */ - 0x40000000U /* base address */ - | MPU_RBAR_VALID_Msk /* valid region */ - | (MPU_RBAR_REGION_Msk & 3U), /* region #3 */ - (28U << MPU_RASR_SIZE_Pos) /* 2^(28+1) region */ - | (0x3U << MPU_RASR_AP_Pos) /* PA:rw/UA:rw */ - | (1U << MPU_RASR_XN_Pos) /* XN=1 */ - | (1U << MPU_RASR_S_Pos) /* S=1 */ - | (1U << MPU_RASR_B_Pos) /* B=1 */ - | MPU_RASR_ENABLE_Msk /* region enable */ - }, - - { /* region #4: Priv. Periph: base=0xE000'0000, size=512M=2^(28+1) */ - 0xE0000000U /* base address */ - | MPU_RBAR_VALID_Msk /* valid region */ - | (MPU_RBAR_REGION_Msk & 4U), /* region #4 */ - (28U << MPU_RASR_SIZE_Pos) /* 2^(28+1) region */ - | (0x3U << MPU_RASR_AP_Pos) /* PA:rw/UA:rw */ - | (1U << MPU_RASR_XN_Pos) /* XN=1 */ - | (1U << MPU_RASR_S_Pos) /* S=1 */ - | (1U << MPU_RASR_B_Pos) /* B=1 */ - | MPU_RASR_ENABLE_Msk /* region enable */ - }, - - { /* region #5: Ext RAM: base=0x6000'0000, size=1G=2^(29+1) */ - 0x60000000U /* base address */ - | MPU_RBAR_VALID_Msk /* valid region */ - | (MPU_RBAR_REGION_Msk & 5U), /* region #5 */ - (29U << MPU_RASR_SIZE_Pos) /* 2^(28+1) region */ - | (0x3U << MPU_RASR_AP_Pos) /* PA:rw/UA:rw */ - | (1U << MPU_RASR_XN_Pos) /* XN=1 */ - | (1U << MPU_RASR_S_Pos) /* S=1 */ - | (1U << MPU_RASR_B_Pos) /* B=1 */ - | MPU_RASR_ENABLE_Msk /* region enable */ - }, - - { /* region #6: Ext Dev: base=0xA000'0000, size=1G=2^(29+1) */ - 0xA0000000U /* base address */ - | MPU_RBAR_VALID_Msk /* valid region */ - | (MPU_RBAR_REGION_Msk & 6U), /* region #6 */ - (29U << MPU_RASR_SIZE_Pos) /* 2^(28+1) region */ - | (0x3U << MPU_RASR_AP_Pos) /* PA:rw/UA:rw */ - | (1U << MPU_RASR_XN_Pos) /* XN=1 */ - | (1U << MPU_RASR_S_Pos) /* S=1 */ - | (1U << MPU_RASR_B_Pos) /* B=1 */ - | MPU_RASR_ENABLE_Msk /* region enable */ - }, - - { /* region #7: NULL-pointer: base=0x000'0000, size=128M=2^(26+1) */ - /* NOTE: this region extends to 0x080'0000, which is where - * the ROM is re-mapped by STM32 - */ - 0x00000000U /* base address */ - | MPU_RBAR_VALID_Msk /* valid region */ - | (MPU_RBAR_REGION_Msk & 7U), /* region #7 */ - (26U << MPU_RASR_SIZE_Pos) /* 2^(26+1)=128M region */ - | (0x0U << MPU_RASR_AP_Pos) /* PA:na/UA:na */ - | (1U << MPU_RASR_XN_Pos) /* XN=1 */ - | MPU_RASR_ENABLE_Msk /* region enable */ - }, - - }; - - __DSB(); - MPU->CTRL = 0U; /* disable the MPU */ - for (uint_fast8_t n = 0U; n < Q_DIM(mpu_setup); ++n) { - MPU->RBAR = mpu_setup[n].rbar; - MPU->RASR = mpu_setup[n].rasr; - } - MPU->CTRL = MPU_CTRL_PRIVDEFENA_Msk /* enable background region */ - | MPU_CTRL_ENABLE_Msk; /* enable the MPU */ - __ISB(); - __DSB(); -} -/*..........................................................................*/ -void BSP_init(void) { - /* setup the MPU... */ - STM32L053R8_MPU_setup(); - - /* NOTE: SystemInit() has been already called from the startup code - * but SystemCoreClock needs to be updated - */ - SystemCoreClockUpdate(); - - /* enable GPIOA clock port for the LED LD2 */ - RCC->IOPENR |= (1U << 0); - - /* configure LED (PA.5) pin as push-pull output, no pull-up, pull-down */ - GPIOA->MODER &= ~((3U << 2*5)); - GPIOA->MODER |= ((1U << 2*5)); - GPIOA->OTYPER &= ~((1U << 5)); - GPIOA->OSPEEDR &= ~((3U << 2*5)); - GPIOA->OSPEEDR |= ((1U << 2*5)); - GPIOA->PUPDR &= ~((3U << 2*5)); - - /* enable GPIOC clock port for the Button B1 */ - RCC->IOPENR |= (1U << 2); - - /* configure Button (PC.13) pins as input, no pull-up, pull-down */ - GPIOC->MODER &= ~(3U << 2*13); - GPIOC->OSPEEDR &= ~(3U << 2*13); - GPIOC->OSPEEDR |= (1U << 2*13); - GPIOC->PUPDR &= ~(3U << 2*13); - - /* initialize the QS software tracing... */ - if (QS_INIT((void *)0) == 0) { /* initialize the QS software tracing */ - Q_ERROR(); - } - QS_OBJ_DICTIONARY(&l_SysTick_Handler); - QS_OBJ_DICTIONARY(&l_test_ISR); - - QS_USR_DICTIONARY(CONTEXT_SW); - QS_USR_DICTIONARY(TRACE_MSG); -} -/*..........................................................................*/ -void BSP_terminate(int16_t result) { - (void)result; -} -/*..........................................................................*/ -void BSP_ledOn(void) { - GPIOA->BSRR |= (LED_LD2); /* turn LED2 on */ -} -/*..........................................................................*/ -void BSP_ledOff(void) { - GPIOA->BSRR |= (LED_LD2 << 16); /* turn LED2 off */ -} -/*..........................................................................*/ -void BSP_trigISR(void) { - NVIC_SetPendingIRQ(EXTI0_1_IRQn); -} -/*..........................................................................*/ -void BSP_trace(QActive const *thr, char const *msg) { - QS_BEGIN(TRACE_MSG, 0U) - QS_OBJ(thr); - QS_STR(msg); - QS_END() -} -/*..........................................................................*/ -uint32_t BSP_romRead(int32_t offset, uint32_t fromEnd) { - int32_t const rom_base = (fromEnd == 0U) - ? 0x08000000 - : 0x08010000 - 4; - return *(uint32_t volatile *)(rom_base + offset); -} -/*..........................................................................*/ -void BSP_romWrite(int32_t offset, uint32_t fromEnd, uint32_t value) { - int32_t const rom_base = (fromEnd == 0U) - ? 0x08000000 - : 0x08010000 - 4; - *(uint32_t volatile *)(rom_base + offset) = value; -} - -/*..........................................................................*/ -uint32_t BSP_ramRead(int32_t offset, uint32_t fromEnd) { - int32_t const ram_base = (fromEnd == 0U) - ? 0x20000000 - : 0x20002000 - 4; - return *(uint32_t volatile *)(ram_base + offset); -} -/*..........................................................................*/ -void BSP_ramWrite(int32_t offset, uint32_t fromEnd, uint32_t value) { - int32_t const ram_base = (fromEnd == 0U) - ? 0x20000000 - : 0x20002000 - 4; - *(uint32_t volatile *)(ram_base + offset) = value; -} - -/*..........................................................................*/ -void QF_onStartup(void) { - /* DON'T set up the SysTick timer to fire at BSP_TICKS_PER_SEC rate */ - //SysTick_Config(SystemCoreClock / BSP_TICKS_PER_SEC); - - /* assign all priority bits for preemption-prio. and none to sub-prio. */ - NVIC_SetPriorityGrouping(0U); - - /* set priorities of ALL ISRs used in the system */ - NVIC_SetPriority(SysTick_IRQn, QF_AWARE_ISR_CMSIS_PRI + 0U); - NVIC_SetPriority(EXTI0_1_IRQn, QF_AWARE_ISR_CMSIS_PRI + 1U); - /* NOTE: priority of UART IRQ used for QS-RX is set in qutest_port.c */ - /* ... */ - - /* enable IRQs... */ - NVIC_EnableIRQ(EXTI0_1_IRQn); -} -/*..........................................................................*/ -void QF_onCleanup(void) { -} -/*..........................................................................*/ -#ifdef QF_ON_CONTEXT_SW -/* NOTE: the context-switch callback is called with interrupts DISABLED */ -void QF_onContextSw(QActive *prev, QActive *next) { - QS_BEGIN_NOCRIT(CONTEXT_SW, 0U) /* no critical section! */ - QS_OBJ(prev); - QS_OBJ(next); - QS_END_NOCRIT() -} -#endif /* QF_ON_CONTEXT_SW */ -/*..........................................................................*/ -void QXK_onIdle(void) { -#ifdef Q_SPY - QS_rxParse(); /* parse all the received bytes */ - QS_doOutput(); -#elif defined NDEBUG - /* Put the CPU and peripherals to the low-power mode. - * you might need to customize the clock management for your application, - * see the datasheet for your particular Cortex-M3 MCU. - */ - __WFI(); /* Wait-For-Interrupt */ -#endif -} - -/* QS callbacks ============================================================*/ -#ifdef Q_SPY - -/*..........................................................................*/ -void QTimeEvt_tick1_( - uint_fast8_t const tickRate, - void const * const sender) -{ - QF_INT_DISABLE(); - /* TODO pend the SysTick */ - *Q_UINT2PTR_CAST(uint32_t, 0xE000ED04U) = (1U << 26U); - QF_INT_ENABLE(); -} - -#endif /* Q_SPY */ - -/*============================================================================ -* NOTE0: -* The MPU protection against NULL-pointer dereferencing sets up a no-access -* MPU region #7 around the NULL address (0x0). The size of this region is set -* to 2**(26+1)==0x0800'0000, because that is the address of Flash in STM32. -* -* REMARK: STM32 MCUs automatically relocate the Flash memory and the Vector -* Table in it to address 0x0800'0000 at startup. However, even though the -* region 0..0x0800'0000 is un-mapped after the relocation, the read access -* is still allowed and causes no CPU exception. Therefore setting up the MPU -* to protect that region is necessary. -*/ diff --git a/test/qxk/test_sched/bsp_nucleo-c031c6.c b/test/qxk/test_sched/bsp_nucleo-c031c6.c new file mode 100644 index 00000000..c4e4b6c6 --- /dev/null +++ b/test/qxk/test_sched/bsp_nucleo-c031c6.c @@ -0,0 +1,347 @@ +//============================================================================ +// Product: BSP for system-testing of QXK kernel, NUCLEO-C031C6 board +// Last updated for version 7.3.0 +// Last updated on 2023-07-18 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// This program is open source software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Alternatively, this program may be distributed and modified under the +// terms of Quantum Leaps commercial licenses, which expressly supersede +// the GNU General Public License and are specifically designed for +// licensees interested in retaining the proprietary status of their code. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Contact information: +// +// +//============================================================================ +#include "qpc.h" +#include "bsp.h" + +#include "stm32c0xx.h" // CMSIS-compliant header file for the MCU used +// add other drivers if necessary... + +Q_DEFINE_THIS_FILE + +// Local-scope objects ----------------------------------------------------- +// LED pins available on the board (just one user LED LD4--Green on PA.5) +#define LD4_PIN 5U + +// Button pins available on the board (just one user Button B1 on PC.13) +#define B1_PIN 13U + +#ifdef Q_SPY + // QSpy source IDs + static QSpyId const l_SysTick_Handler = { 100U }; + static QSpyId const l_test_ISR = { 101U }; + + enum AppRecords { // application-specific trace records + CONTEXT_SW = QS_USER1, + TRACE_MSG + }; + +#endif + +// ISRs used in this project =============================================== +void SysTick_Handler(void); // prototype +void SysTick_Handler(void) { + QXK_ISR_ENTRY(); // inform QXK kernel about entering an ISR + + // process time events for rate 0 + QTIMEEVT_TICK_X(0U, &l_SysTick_Handler); + + QXK_ISR_EXIT(); // inform QXK kernel about exiting an ISR +} +//.......................................................................... +void EXTI0_1_IRQHandler(void); // prototype +void EXTI0_1_IRQHandler(void) { // for testing, NOTE03 + QXK_ISR_ENTRY(); // inform QXK kernel about entering an ISR + + // for testing... + static QEvt const t1 = QEVT_INITIALIZER(TEST1_SIG); + QACTIVE_PUBLISH(&t1, &l_test_ISR); + + QXK_ISR_EXIT(); // inform QXK kernel about exiting an ISR +} + +// BSP functions =========================================================== + +static void STM32C031C6_MPU_setup(void) { + // The following MPU configuration contains the general STM32 memory model + // as described in the ST AppNote AN4838 "Managing memory protection unit + // in STM32 MCUs", Figure 2. Cortex-M0+/M3/M4/M7 processor memory map. + // + // Please note that the actual STM32 MCUs provide much less Flash and SRAM + // than the maximums configured here. This means that actual MCUs have + // unmapped memory regions (e.g., beyond the actual SRAM). Attempts to + // access these regions causes the HardFault exception, which is the + // desired behavior. + // + static struct { + uint32_t rbar; + uint32_t rasr; + } const mpu_setup[] = { + + { // region #0: Flash: base=0x0000'0000, size=512M=2^(28+1) + 0x00000000U // base address + | MPU_RBAR_VALID_Msk // valid region + | (MPU_RBAR_REGION_Msk & 0U), // region #0 + (28U << MPU_RASR_SIZE_Pos) // 2^(18+1) region + | (0x6U << MPU_RASR_AP_Pos) // PA:ro/UA:ro + | (1U << MPU_RASR_C_Pos) // C=1 + | MPU_RASR_ENABLE_Msk // region enable + }, + + { // region #1: SRAM: base=0x2000'0000, size=512M=2^(28+1) + 0x20000000U // base address + | MPU_RBAR_VALID_Msk // valid region + | (MPU_RBAR_REGION_Msk & 1U), // region #1 + (28U << MPU_RASR_SIZE_Pos) // 2^(28+1) region + | (0x3U << MPU_RASR_AP_Pos) // PA:rw/UA:rw + | (1U << MPU_RASR_XN_Pos) // XN=1 + | (1U << MPU_RASR_S_Pos) // S=1 + | (1U << MPU_RASR_C_Pos) // C=1 + | MPU_RASR_ENABLE_Msk // region enable + }, + + // region #3: (not configured) + { MPU_RBAR_VALID_Msk | (MPU_RBAR_REGION_Msk & 2U), 0U }, + + { // region #3: Peripherals: base=0x4000'0000, size=512M=2^(28+1) + 0x40000000U // base address + | MPU_RBAR_VALID_Msk // valid region + | (MPU_RBAR_REGION_Msk & 3U), // region #3 + (28U << MPU_RASR_SIZE_Pos) // 2^(28+1) region + | (0x3U << MPU_RASR_AP_Pos) // PA:rw/UA:rw + | (1U << MPU_RASR_XN_Pos) // XN=1 + | (1U << MPU_RASR_S_Pos) // S=1 + | (1U << MPU_RASR_B_Pos) // B=1 + | MPU_RASR_ENABLE_Msk // region enable + }, + + { // region #4: Priv. Periph: base=0xE000'0000, size=512M=2^(28+1) + 0xE0000000U // base address + | MPU_RBAR_VALID_Msk // valid region + | (MPU_RBAR_REGION_Msk & 4U), // region #4 + (28U << MPU_RASR_SIZE_Pos) // 2^(28+1) region + | (0x3U << MPU_RASR_AP_Pos) // PA:rw/UA:rw + | (1U << MPU_RASR_XN_Pos) // XN=1 + | (1U << MPU_RASR_S_Pos) // S=1 + | (1U << MPU_RASR_B_Pos) // B=1 + | MPU_RASR_ENABLE_Msk // region enable + }, + + { // region #5: Ext RAM: base=0x6000'0000, size=1G=2^(29+1) + 0x60000000U // base address + | MPU_RBAR_VALID_Msk // valid region + | (MPU_RBAR_REGION_Msk & 5U), // region #5 + (29U << MPU_RASR_SIZE_Pos) // 2^(28+1) region + | (0x3U << MPU_RASR_AP_Pos) // PA:rw/UA:rw + | (1U << MPU_RASR_XN_Pos) // XN=1 + | (1U << MPU_RASR_S_Pos) // S=1 + | (1U << MPU_RASR_B_Pos) // B=1 + | MPU_RASR_ENABLE_Msk // region enable + }, + + { // region #6: Ext Dev: base=0xA000'0000, size=1G=2^(29+1) + 0xA0000000U // base address + | MPU_RBAR_VALID_Msk // valid region + | (MPU_RBAR_REGION_Msk & 6U), // region #6 + (29U << MPU_RASR_SIZE_Pos) // 2^(28+1) region + | (0x3U << MPU_RASR_AP_Pos) // PA:rw/UA:rw + | (1U << MPU_RASR_XN_Pos) // XN=1 + | (1U << MPU_RASR_S_Pos) // S=1 + | (1U << MPU_RASR_B_Pos) // B=1 + | MPU_RASR_ENABLE_Msk // region enable + }, + + { // region #7: NULL-pointer: base=0x000'0000, size=128M=2^(26+1) + // NOTE: this region extends to 0x080'0000, which is where + // the ROM is re-mapped by STM32 + 0x00000000U // base address + | MPU_RBAR_VALID_Msk // valid region + | (MPU_RBAR_REGION_Msk & 7U), // region #7 + (26U << MPU_RASR_SIZE_Pos) // 2^(26+1)=128M region + | (0x0U << MPU_RASR_AP_Pos) // PA:na/UA:na + | (1U << MPU_RASR_XN_Pos) // XN=1 + | MPU_RASR_ENABLE_Msk // region enable + }, + + }; + + __DSB(); + MPU->CTRL = 0U; // disable the MPU + for (uint_fast8_t n = 0U; n < Q_DIM(mpu_setup); ++n) { + MPU->RBAR = mpu_setup[n].rbar; + MPU->RASR = mpu_setup[n].rasr; + } + MPU->CTRL = MPU_CTRL_PRIVDEFENA_Msk // enable background region + | MPU_CTRL_ENABLE_Msk; // enable the MPU + __ISB(); + __DSB(); +} +//.......................................................................... +void BSP_init(void) { + // setup the MPU... + STM32C031C6_MPU_setup(); + + // initialize the QS software tracing... + if (QS_INIT((void *)0) == 0U) { + Q_ERROR(); + } + + // dictionaries... + QS_OBJ_DICTIONARY(&l_SysTick_Handler); + QS_OBJ_DICTIONARY(&l_test_ISR); + + QS_USR_DICTIONARY(CONTEXT_SW); + QS_USR_DICTIONARY(TRACE_MSG); +} +//.......................................................................... +void BSP_terminate(int16_t result) { + Q_UNUSED_PAR(result); +} +//.......................................................................... +void BSP_ledOn(void) { + GPIOA->BSRR = (1U << LD4_PIN); // turn LD4 on +} +//.......................................................................... +void BSP_ledOff(void) { + GPIOA->BSRR = (1U << (LD4_PIN + 16U)); // turn LD4 off +} +//.......................................................................... +void BSP_trigISR(void) { + NVIC_SetPendingIRQ(EXTI0_1_IRQn); +} +//.......................................................................... +void BSP_trace(QActive const *thr, char const *msg) { + QS_BEGIN_ID(TRACE_MSG, 0U) + QS_OBJ(thr); + QS_STR(msg); + QS_END() +} +//.......................................................................... +uint32_t BSP_romRead(int32_t offset, uint32_t fromEnd) { + int32_t const rom_base = (fromEnd == 0U) + ? 0x08000000 + : 0x08008000 - 4; + return *(uint32_t volatile *)(rom_base + offset); +} +//.......................................................................... +void BSP_romWrite(int32_t offset, uint32_t fromEnd, uint32_t value) { + int32_t const rom_base = (fromEnd == 0U) + ? 0x08000000 + : 0x08008000 - 4; + *(uint32_t volatile *)(rom_base + offset) = value; +} + +//.......................................................................... +uint32_t BSP_ramRead(int32_t offset, uint32_t fromEnd) { + int32_t const ram_base = (fromEnd == 0U) + ? 0x20000000 + : 0x20003000 - 4; + return *(uint32_t volatile *)(ram_base + offset); +} +//.......................................................................... +void BSP_ramWrite(int32_t offset, uint32_t fromEnd, uint32_t value) { + int32_t const ram_base = (fromEnd == 0U) + ? 0x20000000 + : 0x20003000 - 4; + *(uint32_t volatile *)(ram_base + offset) = value; +} + +//.......................................................................... +void QF_onStartup(void) { + // NOTE: SystemInit() has been already called from the startup code + // but SystemCoreClock needs to be updated + // + SystemCoreClockUpdate(); + + //NOTE: don't start ticking for these tests + //SysTick_Config(SystemCoreClock / BSP_TICKS_PER_SEC); + + // assign all priority bits for preemption-prio. and none to sub-prio. + // NOTE: this might have been changed by STM32Cube. + NVIC_SetPriorityGrouping(0U); + + // set priorities of ALL ISRs used in the system + NVIC_SetPriority(SysTick_IRQn, QF_AWARE_ISR_CMSIS_PRI + 0U); + NVIC_SetPriority(EXTI0_1_IRQn, QF_AWARE_ISR_CMSIS_PRI + 1U); + // NOTE: priority of UART IRQ used for QS-RX is set in qutest_port.c + // ... + + // enable IRQs... + NVIC_EnableIRQ(EXTI0_1_IRQn); +} +//.......................................................................... +void QF_onCleanup(void) { +} +//.......................................................................... +#ifdef QF_ON_CONTEXT_SW +// NOTE: the context-switch callback is called with interrupts DISABLED +void QF_onContextSw(QActive *prev, QActive *next) { + QS_BEGIN_INCRIT(CONTEXT_SW, 0U) // in critical section! + QS_OBJ(prev); + QS_OBJ(next); + QS_END_INCRIT() +} +#endif // QF_ON_CONTEXT_SW + +//.......................................................................... +void QXK_onIdle(void) { +#ifdef Q_SPY + QS_rxParse(); // parse all the received bytes + QS_doOutput(); +#elif defined NDEBUG + // Put the CPU and peripherals to the low-power mode. + // you might need to customize the clock management for your application, + // see the datasheet for your particular Cortex-M3 MCU. + // + __WFI(); // Wait-For-Interrupt +#endif +} + +// QS callbacks ============================================================ +#ifdef Q_SPY + +//.......................................................................... +void QTimeEvt_tick1_( + uint_fast8_t const tickRate, + void const * const sender) +{ + QF_INT_DISABLE(); + // TODO pend the SysTick + *Q_UINT2PTR_CAST(uint32_t, 0xE000ED04U) = (1U << 26U); + QF_INT_ENABLE(); +} + +#endif // Q_SPY + +//============================================================================ +// NOTE0: +// The MPU protection against NULL-pointer dereferencing sets up a no-access +// MPU region #7 around the NULL address (0x0). The size of this region is set +// to 2^(26+1)==0x0800'0000, because that is the address of Flash in STM32. +// +// REMARK: STM32 MCUs automatically relocate the Flash memory and the Vector +// Table in it to address 0x0800'0000 at startup. However, even though the +// region 0..0x0800'0000 is un-mapped after the relocation, the read access +// is still allowed and causes no CPU exception. Therefore setting up the MPU +// to protect that region is necessary. +// diff --git a/test/qxk/test_sched/bsp_nucleo-h743zi.c b/test/qxk/test_sched/bsp_nucleo-h743zi.c new file mode 100644 index 00000000..c354d956 --- /dev/null +++ b/test/qxk/test_sched/bsp_nucleo-h743zi.c @@ -0,0 +1,300 @@ +//============================================================================ +// Product: BSP for system-testing of QXK kernel, NUCLEO-H743ZI board +// Last updated for version 7.3.0 +// Last updated on 2023-07-18 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// This program is open source software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Alternatively, this program may be distributed and modified under the +// terms of Quantum Leaps commercial licenses, which expressly supersede +// the GNU General Public License and are specifically designed for +// licensees interested in retaining the proprietary status of their code. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Contact information: +// +// +//============================================================================ +#include "qpc.h" +#include "bsp.h" + +// STM32CubeH7 include files +#include "stm32h7xx_hal.h" +#include "stm32h7xx_nucleo_144.h" +// add other drivers if necessary... + +Q_DEFINE_THIS_FILE + +#ifdef Q_SPY + + // QSpy source IDs + static QSpyId const l_SysTick_Handler = { 100U }; + static QSpyId const l_test_ISR = { 101U }; + + enum AppRecords { // application-specific trace records + CONTEXT_SW = QS_USER1, + TRACE_MSG + }; + +#endif + +// ISRs used in this project =============================================== +void SysTick_Handler(void); // prototype +void SysTick_Handler(void) { + QXK_ISR_ENTRY(); // inform QXK kernel about entering an ISR + + // process time events for rate 0 + QTIMEEVT_TICK_X(0U, &l_SysTick_Handler); + + QXK_ISR_EXIT(); // inform QXK kernel about exiting an ISR +} +//.......................................................................... +void EXTI0_IRQHandler(void); // prototype +void EXTI0_IRQHandler(void) { // for testing, NOTE03 + QXK_ISR_ENTRY(); // inform QXK kernel about entering an ISR + + // for testing... + static QEvt const t1 = QEVT_INITIALIZER(TEST1_SIG); + QACTIVE_PUBLISH(&t1, &l_test_ISR); + + QXK_ISR_EXIT(); // inform QXK kernel about exiting an ISR +} + +// BSP functions =========================================================== +//.......................................................................... +// MPU setup for STM32H743ZI MCU +static void STM32H743ZI_MPU_setup(void) { + // The following MPU configuration contains just a generic ROM + // region (with read-only access) and NULL-pointer protection region. + // Otherwise, the MPU will fall back on the background region (PRIVDEFENA). + // + static struct { + uint32_t rbar; + uint32_t rasr; + } const mpu_setup[] = { + + { // region #0: Flash: base=0x0000'0000, size=512M=2^(28+1) + 0x00000000U // base address + | MPU_RBAR_VALID_Msk // valid region + | (MPU_RBAR_REGION_Msk & 0U), // region #0 + (28U << MPU_RASR_SIZE_Pos) // 2^(18+1) region + | (0x6U << MPU_RASR_AP_Pos) // PA:ro/UA:ro + | (1U << MPU_RASR_C_Pos) // C=1 + | MPU_RASR_ENABLE_Msk // region enable + }, + + { // region #7: NULL-pointer: base=0x000'0000, size=128M=2^(26+1) + // NOTE: this region extends to 0x080'0000, which is where + // the ROM is re-mapped by STM32 + // + 0x00000000U // base address + | MPU_RBAR_VALID_Msk // valid region + | (MPU_RBAR_REGION_Msk & 7U), // region #7 + (26U << MPU_RASR_SIZE_Pos) // 2^(26+1)=128M region + | (0x0U << MPU_RASR_AP_Pos) // PA:na/UA:na + | (1U << MPU_RASR_XN_Pos) // XN=1 + | MPU_RASR_ENABLE_Msk // region enable + }, + }; + + // enable the MemManage_Handler for MPU exception + SCB->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk; + + __DSB(); + MPU->CTRL = 0U; // disable the MPU + for (uint_fast8_t n = 0U; n < Q_DIM(mpu_setup); ++n) { + MPU->RBAR = mpu_setup[n].rbar; + MPU->RASR = mpu_setup[n].rasr; + } + MPU->CTRL = MPU_CTRL_ENABLE_Msk // enable the MPU + | MPU_CTRL_PRIVDEFENA_Msk; // enable background region + __ISB(); + __DSB(); +} + +//.......................................................................... +void BSP_init(void) { + // setup the MPU... + STM32H743ZI_MPU_setup(); + + // NOTE: SystemInit() has been already called from the startup code + // but SystemCoreClock needs to be updated + // + SystemCoreClockUpdate(); + + SCB_EnableICache(); // Enable I-Cache + SCB_EnableDCache(); // Enable D-Cache + + // Configure Flash prefetch and Instr. cache through ART accelerator +#if (ART_ACCLERATOR_ENABLE != 0) + __HAL_FLASH_ART_ENABLE(); +#endif // ART_ACCLERATOR_ENABLE + + // Configure the LEDs + BSP_LED_Init(LED1); + BSP_LED_Init(LED2); + BSP_LED_Init(LED3); + + // Configure the User Button in GPIO Mode + BSP_PB_Init(BUTTON_USER, BUTTON_MODE_GPIO); + + if (QS_INIT((void *)0) == 0) { // initialize the QS software tracing + Q_ERROR(); + } + + // dictionaries... + QS_OBJ_DICTIONARY(&l_SysTick_Handler); + QS_OBJ_DICTIONARY(&l_test_ISR); + + QS_USR_DICTIONARY(CONTEXT_SW); + QS_USR_DICTIONARY(TRACE_MSG); +} +//.......................................................................... +void BSP_terminate(int16_t result) { + Q_UNUSED_PAR(result); +} +//.......................................................................... +void BSP_ledOn(void) { + BSP_LED_On(LED1); +} +//.......................................................................... +void BSP_ledOff(void) { + BSP_LED_Off(LED1); +} +//.......................................................................... +void BSP_trigISR(void) { + NVIC_SetPendingIRQ(EXTI0_IRQn); +} +//.......................................................................... +void BSP_trace(QActive const *thr, char const *msg) { + QS_BEGIN_ID(TRACE_MSG, 0U) + QS_OBJ(thr); + QS_STR(msg); + QS_END() +} +//.......................................................................... +uint32_t BSP_romRead(int32_t offset, uint32_t fromEnd) { + int32_t const rom_base = (fromEnd == 0U) + ? 0x08000000 + : 0x08200000 - 4; + return *(uint32_t volatile *)(rom_base + offset); +} +//.......................................................................... +void BSP_romWrite(int32_t offset, uint32_t fromEnd, uint32_t value) { + int32_t const rom_base = (fromEnd == 0U) + ? 0x08000000 + : 0x08200000 - 4; + *(uint32_t volatile *)(rom_base + offset) = value; +} + +//.......................................................................... +uint32_t BSP_ramRead(int32_t offset, uint32_t fromEnd) { + int32_t const ram_base = (fromEnd == 0U) + ? 0x20000000 + : 0x20020000 - 4; + return *(uint32_t volatile *)(ram_base + offset); +} +//.......................................................................... +void BSP_ramWrite(int32_t offset, uint32_t fromEnd, uint32_t value) { + int32_t const ram_base = (fromEnd == 0U) + ? 0x20000000 + : 0x20020000 - 4; + *(uint32_t volatile *)(ram_base + offset) = value; +} + +//.......................................................................... +void QF_onStartup(void) { + // set up the SysTick timer to fire at BSP_TICKS_PER_SEC rate + //NOTE: don't start ticking for these tests + //SysTick_Config(SystemCoreClock / BSP_TICKS_PER_SEC); + + // assign all priority bits for preemption-prio. and none to sub-prio. + // NOTE: this might have been changed by STM32Cube. + // + NVIC_SetPriorityGrouping(0U); + + // set priorities of ALL ISRs used in the system, see NOTE1 + // + // !!!!!!!!!!!!!!!!!!!!!!!!!!!! CAUTION !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + // Assign a priority to EVERY ISR explicitly by calling NVIC_SetPriority(). + // DO NOT LEAVE THE ISR PRIORITIES AT THE DEFAULT VALUE! + // + NVIC_SetPriority(SysTick_IRQn, QF_AWARE_ISR_CMSIS_PRI + 0U); + NVIC_SetPriority(EXTI0_IRQn, QF_AWARE_ISR_CMSIS_PRI + 1U); + // ... + + // enable IRQs... + NVIC_EnableIRQ(EXTI0_IRQn); +} +//.......................................................................... +void QF_onCleanup(void) { +} +//.......................................................................... +#ifdef QF_ON_CONTEXT_SW +// NOTE: the context-switch callback is called with interrupts DISABLED +void QF_onContextSw(QActive *prev, QActive *next) { + QS_BEGIN_INCRIT(CONTEXT_SW, 0U) // in critical section! + QS_OBJ(prev); + QS_OBJ(next); + QS_END_INCRIT() +} +#endif // QF_ON_CONTEXT_SW + +//.......................................................................... +void QXK_onIdle(void) { +#ifdef Q_SPY + QS_rxParse(); // parse all the received bytes + QS_doOutput(); +#elif defined NDEBUG + // Put the CPU and peripherals to the low-power mode. + // you might need to customize the clock management for your application, + // see the datasheet for your particular Cortex-M3 MCU. + // + __WFI(); // Wait-For-Interrupt +#endif +} + +// QS callbacks ============================================================ +#ifdef Q_SPY + +//.......................................................................... +void QTimeEvt_tick1_( + uint_fast8_t const tickRate, + void const * const sender) +{ + QF_INT_DISABLE(); + // TODO pend the SysTick + *Q_UINT2PTR_CAST(uint32_t, 0xE000ED04U) = (1U << 26U); + QF_INT_ENABLE(); +} + +#endif // Q_SPY + +//============================================================================ +// NOTE0: +// The MPU protection against NULL-pointer dereferencing sets up a no-access +// MPU region #7 around the NULL address (0x0). The size of this region is set +// to 2**(26+1)==0x0800'0000, because that is the address of Flash in STM32. +// +// REMARK: STM32 MCUs automatically relocate the Flash memory and the Vector +// Table in it to address 0x0800'0000 at startup. However, even though the +// region 0..0x0800'0000 is un-mapped after the relocation, the read access +// is still allowed and causes no CPU exception. Therefore setting up the MPU +// to protect that region is necessary. +// diff --git a/test/qxk/test_sched/bsp_nucleo-l053r8.c b/test/qxk/test_sched/bsp_nucleo-l053r8.c new file mode 100644 index 00000000..58b9e18e --- /dev/null +++ b/test/qxk/test_sched/bsp_nucleo-l053r8.c @@ -0,0 +1,365 @@ +//============================================================================ +// Product: BSP for system-testing QXK kernel, NUCLEO-L053R8 board +// Last updated for version 7.3.0 +// Last updated on 2023-07-18 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// This program is open source software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Alternatively, this program may be distributed and modified under the +// terms of Quantum Leaps commercial licenses, which expressly supersede +// the GNU General Public License and are specifically designed for +// licensees interested in retaining the proprietary status of their code. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Contact information: +// +// +//============================================================================ +#include "qpc.h" +#include "bsp.h" + +#include "stm32l0xx.h" // CMSIS-compliant header file for the MCU used +// add other drivers if necessary... + +Q_DEFINE_THIS_FILE + +// Local-scope objects ----------------------------------------------------- +// LED pins available on the board (just one user LED LD2--Green on PA.5) +#define LED_LD2 (1U << 5) + +// Button pins available on the board (just one user Button B1 on PC.13) +#define BTN_B1 (1U << 13) + +#ifdef Q_SPY + // QSpy source IDs + static QSpyId const l_SysTick_Handler = { 100U }; + static QSpyId const l_test_ISR = { 101U }; + + enum AppRecords { // application-specific trace records + CONTEXT_SW = QS_USER1, + TRACE_MSG + }; + +#endif + +// ISRs used in this project =============================================== +void SysTick_Handler(void); // prototype +void SysTick_Handler(void) { + QXK_ISR_ENTRY(); // inform QXK kernel about entering an ISR + + // process time events for rate 0 + QTIMEEVT_TICK_X(0U, &l_SysTick_Handler); + + QXK_ISR_EXIT(); // inform QXK kernel about exiting an ISR +} +//.......................................................................... +void EXTI0_1_IRQHandler(void); // prototype +void EXTI0_1_IRQHandler(void) { // for testing, NOTE03 + QXK_ISR_ENTRY(); // inform QXK kernel about entering an ISR + + // for testing... + static QEvt const t1 = QEVT_INITIALIZER(TEST1_SIG); + QACTIVE_PUBLISH(&t1, &l_test_ISR); + + QXK_ISR_EXIT(); // inform QXK kernel about exiting an ISR +} + +// BSP functions =========================================================== +static void STM32L053R8_MPU_setup(void) { + // The following MPU configuration contains the general STM32 memory model + // as described in the ST AppNote AN4838 "Managing memory protection unit + // in STM32 MCUs", Figure 2. Cortex-M0+/M3/M4/M7 processor memory map. + // + // Please note that the actual STM32 MCUs provide much less Flash and SRAM + // than the maximums configured here. This means that actual MCUs have + // unmapped memory regions (e.g., beyond the actual SRAM). Attempts to + // access these regions causes the HardFault exception, which is the + // desired behavior. + // + static struct { + uint32_t rbar; + uint32_t rasr; + } const mpu_setup[] = { + + { // region #0: Flash: base=0x0000'0000, size=512M=2^(28+1) + 0x00000000U // base address + | MPU_RBAR_VALID_Msk // valid region + | (MPU_RBAR_REGION_Msk & 0U), // region #0 + (28U << MPU_RASR_SIZE_Pos) // 2^(18+1) region + | (0x6U << MPU_RASR_AP_Pos) // PA:ro/UA:ro + | (1U << MPU_RASR_C_Pos) // C=1 + | MPU_RASR_ENABLE_Msk // region enable + }, + + { // region #1: SRAM: base=0x2000'0000, size=512M=2^(28+1) + 0x20000000U // base address + | MPU_RBAR_VALID_Msk // valid region + | (MPU_RBAR_REGION_Msk & 1U), // region #1 + (28U << MPU_RASR_SIZE_Pos) // 2^(28+1) region + | (0x3U << MPU_RASR_AP_Pos) // PA:rw/UA:rw + | (1U << MPU_RASR_XN_Pos) // XN=1 + | (1U << MPU_RASR_S_Pos) // S=1 + | (1U << MPU_RASR_C_Pos) // C=1 + | MPU_RASR_ENABLE_Msk // region enable + }, + + // region #3: (not configured) + { MPU_RBAR_VALID_Msk | (MPU_RBAR_REGION_Msk & 2U), 0U }, + + { // region #3: Peripherals: base=0x4000'0000, size=512M=2^(28+1) + 0x40000000U // base address + | MPU_RBAR_VALID_Msk // valid region + | (MPU_RBAR_REGION_Msk & 3U), // region #3 + (28U << MPU_RASR_SIZE_Pos) // 2^(28+1) region + | (0x3U << MPU_RASR_AP_Pos) // PA:rw/UA:rw + | (1U << MPU_RASR_XN_Pos) // XN=1 + | (1U << MPU_RASR_S_Pos) // S=1 + | (1U << MPU_RASR_B_Pos) // B=1 + | MPU_RASR_ENABLE_Msk // region enable + }, + + { // region #4: Priv. Periph: base=0xE000'0000, size=512M=2^(28+1) + 0xE0000000U // base address + | MPU_RBAR_VALID_Msk // valid region + | (MPU_RBAR_REGION_Msk & 4U), // region #4 + (28U << MPU_RASR_SIZE_Pos) // 2^(28+1) region + | (0x3U << MPU_RASR_AP_Pos) // PA:rw/UA:rw + | (1U << MPU_RASR_XN_Pos) // XN=1 + | (1U << MPU_RASR_S_Pos) // S=1 + | (1U << MPU_RASR_B_Pos) // B=1 + | MPU_RASR_ENABLE_Msk // region enable + }, + + { // region #5: Ext RAM: base=0x6000'0000, size=1G=2^(29+1) + 0x60000000U // base address + | MPU_RBAR_VALID_Msk // valid region + | (MPU_RBAR_REGION_Msk & 5U), // region #5 + (29U << MPU_RASR_SIZE_Pos) // 2^(28+1) region + | (0x3U << MPU_RASR_AP_Pos) // PA:rw/UA:rw + | (1U << MPU_RASR_XN_Pos) // XN=1 + | (1U << MPU_RASR_S_Pos) // S=1 + | (1U << MPU_RASR_B_Pos) // B=1 + | MPU_RASR_ENABLE_Msk // region enable + }, + + { // region #6: Ext Dev: base=0xA000'0000, size=1G=2^(29+1) + 0xA0000000U // base address + | MPU_RBAR_VALID_Msk // valid region + | (MPU_RBAR_REGION_Msk & 6U), // region #6 + (29U << MPU_RASR_SIZE_Pos) // 2^(28+1) region + | (0x3U << MPU_RASR_AP_Pos) // PA:rw/UA:rw + | (1U << MPU_RASR_XN_Pos) // XN=1 + | (1U << MPU_RASR_S_Pos) // S=1 + | (1U << MPU_RASR_B_Pos) // B=1 + | MPU_RASR_ENABLE_Msk // region enable + }, + + { // region #7: NULL-pointer: base=0x000'0000, size=128M=2^(26+1) + // NOTE: this region extends to 0x080'0000, which is where + // the ROM is re-mapped by STM32 + // + 0x00000000U // base address + | MPU_RBAR_VALID_Msk // valid region + | (MPU_RBAR_REGION_Msk & 7U), // region #7 + (26U << MPU_RASR_SIZE_Pos) // 2^(26+1)=128M region + | (0x0U << MPU_RASR_AP_Pos) // PA:na/UA:na + | (1U << MPU_RASR_XN_Pos) // XN=1 + | MPU_RASR_ENABLE_Msk // region enable + }, + + }; + + MPU->CTRL = 0U; // disable the MPU + for (uint_fast8_t n = 0U; n < Q_DIM(mpu_setup); ++n) { + MPU->RBAR = mpu_setup[n].rbar; + MPU->RASR = mpu_setup[n].rasr; + } + MPU->CTRL = MPU_CTRL_PRIVDEFENA_Msk // enable background region + | MPU_CTRL_ENABLE_Msk; // enable the MPU + __ISB(); + __DSB(); +} +//.......................................................................... +void BSP_init(void) { + // setup the MPU... + STM32L053R8_MPU_setup(); + + // NOTE: SystemInit() has been already called from the startup code + // but SystemCoreClock needs to be updated + // + SystemCoreClockUpdate(); + + // enable GPIOA clock port for the LED LD2 + RCC->IOPENR |= (1U << 0); + + // configure LED (PA.5) pin as push-pull output, no pull-up, pull-down + GPIOA->MODER &= ~((3U << 2*5)); + GPIOA->MODER |= ((1U << 2*5)); + GPIOA->OTYPER &= ~((1U << 5)); + GPIOA->OSPEEDR &= ~((3U << 2*5)); + GPIOA->OSPEEDR |= ((1U << 2*5)); + GPIOA->PUPDR &= ~((3U << 2*5)); + + // enable GPIOC clock port for the Button B1 + RCC->IOPENR |= (1U << 2); + + // configure Button (PC.13) pins as input, no pull-up, pull-down + GPIOC->MODER &= ~(3U << 2*13); + GPIOC->OSPEEDR &= ~(3U << 2*13); + GPIOC->OSPEEDR |= (1U << 2*13); + GPIOC->PUPDR &= ~(3U << 2*13); + + // initialize the QS software tracing... + if (QS_INIT((void *)0) == 0U) { + Q_ERROR(); + } + + // dictionaries... + QS_OBJ_DICTIONARY(&l_SysTick_Handler); + QS_OBJ_DICTIONARY(&l_test_ISR); + + QS_USR_DICTIONARY(CONTEXT_SW); + QS_USR_DICTIONARY(TRACE_MSG); +} +//.......................................................................... +void BSP_terminate(int16_t result) { + Q_UNUSED_PAR(result); +} +//.......................................................................... +void BSP_ledOn(void) { + GPIOA->BSRR = (LED_LD2); // turn LED2 on +} +//.......................................................................... +void BSP_ledOff(void) { + GPIOA->BSRR = (LED_LD2 << 16); // turn LED2 off +} +//.......................................................................... +void BSP_trigISR(void) { + NVIC_SetPendingIRQ(EXTI0_1_IRQn); +} +//.......................................................................... +void BSP_trace(QActive const *thr, char const *msg) { + QS_BEGIN_ID(TRACE_MSG, 0U) + QS_OBJ(thr); + QS_STR(msg); + QS_END() +} +//.......................................................................... +uint32_t BSP_romRead(int32_t offset, uint32_t fromEnd) { + int32_t const rom_base = (fromEnd == 0U) + ? 0x08000000 + : 0x08010000 - 4; + return *(uint32_t volatile *)(rom_base + offset); +} +//.......................................................................... +void BSP_romWrite(int32_t offset, uint32_t fromEnd, uint32_t value) { + int32_t const rom_base = (fromEnd == 0U) + ? 0x08000000 + : 0x08010000 - 4; + *(uint32_t volatile *)(rom_base + offset) = value; +} + +//.......................................................................... +uint32_t BSP_ramRead(int32_t offset, uint32_t fromEnd) { + int32_t const ram_base = (fromEnd == 0U) + ? 0x20000000 + : 0x20002000 - 4; + return *(uint32_t volatile *)(ram_base + offset); +} +//.......................................................................... +void BSP_ramWrite(int32_t offset, uint32_t fromEnd, uint32_t value) { + int32_t const ram_base = (fromEnd == 0U) + ? 0x20000000 + : 0x20002000 - 4; + *(uint32_t volatile *)(ram_base + offset) = value; +} + +//.......................................................................... +void QF_onStartup(void) { + // DON'T set up the SysTick timer to fire at BSP_TICKS_PER_SEC rate + //SysTick_Config(SystemCoreClock / BSP_TICKS_PER_SEC); + + // assign all priority bits for preemption-prio. and none to sub-prio. + NVIC_SetPriorityGrouping(0U); + + // set priorities of ALL ISRs used in the system + NVIC_SetPriority(SysTick_IRQn, QF_AWARE_ISR_CMSIS_PRI + 0U); + NVIC_SetPriority(EXTI0_1_IRQn, QF_AWARE_ISR_CMSIS_PRI + 1U); + // NOTE: priority of UART IRQ used for QS-RX is set in qutest_port.c + // ... + + // enable IRQs... + NVIC_EnableIRQ(EXTI0_1_IRQn); +} +//.......................................................................... +void QF_onCleanup(void) { +} +//.......................................................................... +#ifdef QF_ON_CONTEXT_SW +// NOTE: the context-switch callback is called with interrupts DISABLED +void QF_onContextSw(QActive *prev, QActive *next) { + QS_BEGIN_INCRIT(CONTEXT_SW, 0U) // in critical section! + QS_OBJ(prev); + QS_OBJ(next); + QS_END_INCRIT() +} +#endif // QF_ON_CONTEXT_SW + +//.......................................................................... +void QXK_onIdle(void) { +#ifdef Q_SPY + QS_rxParse(); // parse all the received bytes + QS_doOutput(); +#elif defined NDEBUG + // Put the CPU and peripherals to the low-power mode. + // you might need to customize the clock management for your application, + // see the datasheet for your particular Cortex-M3 MCU. + // + __WFI(); // Wait-For-Interrupt +#endif +} + +// QS callbacks ============================================================ +#ifdef Q_SPY + +//.......................................................................... +void QTimeEvt_tick1_( + uint_fast8_t const tickRate, + void const * const sender) +{ + QF_INT_DISABLE(); + // TODO pend the SysTick + *Q_UINT2PTR_CAST(uint32_t, 0xE000ED04U) = (1U << 26U); + QF_INT_ENABLE(); +} + +#endif // Q_SPY + +//============================================================================ +// NOTE0: +// The MPU protection against NULL-pointer dereferencing sets up a no-access +// MPU region #7 around the NULL address (0x0). The size of this region is set +// to 2**(26+1)==0x0800'0000, because that is the address of Flash in STM32. +// +// REMARK: STM32 MCUs automatically relocate the Flash memory and the Vector +// Table in it to address 0x0800'0000 at startup. However, even though the +// region 0..0x0800'0000 is un-mapped after the relocation, the read access +// is still allowed and causes no CPU exception. Therefore setting up the MPU +// to protect that region is necessary. +// diff --git a/test/qxk/test_sched/make_efm32 b/test/qxk/test_sched/efm32pg1b.mak similarity index 93% rename from test/qxk/test_sched/make_efm32 rename to test/qxk/test_sched/efm32pg1b.mak index 659e93e6..0fab13f3 100644 --- a/test/qxk/test_sched/make_efm32 +++ b/test/qxk/test_sched/efm32pg1b.mak @@ -1,7 +1,7 @@ ############################################################################## # Product: Makefile for SYSTEM-Level tests of QP/C on EMF32, GNU-ARM -# Last Updated for Version: 7.2.0 -# Date of the Last Update: 2022-12-21 +# Last Updated for Version: 7.3.0 +# Date of the Last Update: 2023-09-06 # # Q u a n t u m L e a P s # ------------------------ @@ -33,12 +33,12 @@ ############################################################################## # # examples of invoking this Makefile: -# make -f make_efm32 # make and run the tests in the current directory -# make -f make_efm32 TESTS=thr*.py # make and run the selected tests -# make -f make_efm32 HOST=localhost:7705 # connect to host:port -# make -f make_efm32 norun # only make but not run the tests -# make -f make_efm32 clean # cleanup the build -# make -f make_efm32 debug # only run tests in DEBUG mode +# make -f efm32pg1b.mak # make and run the tests in the current directory +# make -f efm32pg1b.mak TESTS=thr*.py # make and run the selected tests +# make -f efm32pg1b.mak HOST=localhost:7705 # connect to host:port +# make -f efm32pg1b.mak norun # only make but not run the tests +# make -f efm32pg1b.mak clean # cleanup the build +# make -f efm32pg1b.mak debug # only run tests in DEBUG mode # # NOTE: # To use this Makefile on Windows, you will need the GNU make utility, which @@ -99,7 +99,7 @@ ASM_SRCS := # C source files C_SRCS := \ test_sched.c \ - bsp_efm32.c \ + bsp_efm32pg1b.c \ startup_efm32pg1b.c \ system_efm32pg1b.c \ em_cmu.c \ @@ -262,7 +262,7 @@ $(TARGET_BIN) : $(TARGET_ELF) $(FLASH) $@ $(TARGET_ELF) : $(ASM_OBJS_EXT) $(C_OBJS_EXT) $(CPP_OBJS_EXT) - $(CC) $(CFLAGS) $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o + $(CC) $(CFLAGS) $(QPC)/src/qs/qstamp.c -o $(BIN_DIR)/qstamp.o $(LINK) $(LINKFLAGS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) flash : @@ -299,7 +299,7 @@ endif endif debug : - $(QUTEST) $(TESTS) DEBUG $(HOST) + $(QUTEST) -edebug -q$(QSPY) -l$(LOG) -o$(OPT) -- $(TESTS) .PHONY : clean show diff --git a/test/qxk/test_sched/nucleo-c031c6.mak b/test/qxk/test_sched/nucleo-c031c6.mak new file mode 100644 index 00000000..aea5126b --- /dev/null +++ b/test/qxk/test_sched/nucleo-c031c6.mak @@ -0,0 +1,339 @@ +############################################################################## +# Product: Makefile for SYSTEM-Level tests of QP/C on NUCLEO-C031c6, GNU-ARM +# Last Updated for Version: 7.2.2 +# Date of the Last Update: 2023-02-02 +# +# Q u a n t u m L e a P s +# ------------------------ +# Modern Embedded Software +# +# Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +# +# This program is open source software: you can redistribute it and/or +# modify it under the terms of the GNU General Public License as published +# by the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Alternatively, this program may be distributed and modified under the +# terms of Quantum Leaps commercial licenses, which expressly supersede +# the GNU General Public License and are specifically designed for +# licensees interested in retaining the proprietary status of their code. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# +# Contact information: +# +# +############################################################################## +# +# examples of invoking this Makefile: +# make -f nucleo-c031c6.mak USB=g: # make, uplaod to USB drive, run the tests +# make -f nucleo-c031c6.mak USB=g: TESTS=philo*.py # make and run the selected tests +# make -f nucleo-c031c6.mak HOST=localhost:7705 # connect to host:port +# make -f nucleo-c031c6.mak norun # only make but not run the tests +# make -f nucleo-c031c6.mak clean # cleanup the build +# make -f nucleo-c031c6.mak debug # only run tests in DEBUG mode +# +# NOTE: +# To use this Makefile on Windows, you will need the GNU make utility, which +# is included in the QTools collection for Windows, see: +# https://github.com/QuantumLeaps/qtools +# + +# location of the QP/C framework (if not provided in an env. variable) +ifeq ($(QPC),) +QPC := ../../.. +endif + +#----------------------------------------------------------------------------- +# project name, target name, target directory: +# +PROJECT := test_sched +TARGET := nucleo-c031c6 +TARGET_DIR := $(QPC)/3rd_party/nucleo-c031c6/qutest + +#----------------------------------------------------------------------------- +# project directories: +# + +# QP port used in this project +QP_PORT_DIR := $(QPC)/ports/arm-cm/qxk/gnu + +# make sure that QTOOLS env. variable is defined... +ifeq ("$(wildcard $(QTOOLS))","") +$(error QTOOLS not found. Please install QTools and define QTOOLS env. variable) +endif + + +# list of all source directories used by this project +VPATH := . \ + $(QPC)/src/qf \ + $(QPC)/src/qxk \ + $(QPC)/src/qs \ + $(QP_PORT_DIR) \ + $(TARGET_DIR) \ + $(QPC)/3rd_party/nucleo-c031c6 \ + $(QPC)/3rd_party/nucleo-c031c6/gnu + +# list of all include directories needed by this project +INCLUDES = -I. \ + -I$(QPC)/include \ + -I$(QP_PORT_DIR) \ + -I$(TARGET_DIR) \ + -I$(QPC)/3rd_party/CMSIS/Include \ + -I$(QPC)/3rd_party/nucleo-c031c6 + +#----------------------------------------------------------------------------- +# project files: +# + +# assembler source files +ASM_SRCS := + +# C source files +C_SRCS := \ + test_sched.c \ + bsp_nucleo-c031c6.c \ + system_stm32c0xx.c \ + startup_stm32c031xx.c + +# C++ source files +CPP_SRCS := + +OUTPUT := $(PROJECT) +LD_SCRIPT := $(TARGET_DIR)/qutest.ld + +QP_SRCS := \ + qep_hsm.c \ + qep_msm.c \ + qf_act.c \ + qf_actq.c \ + qf_defer.c \ + qf_dyn.c \ + qf_mem.c \ + qf_ps.c \ + qf_qact.c \ + qf_qeq.c \ + qf_qmact.c \ + qf_time.c \ + qxk.c \ + qxk_xthr.c \ + qxk_sema.c \ + qxk_mutex.c \ + qxk_port.c \ + qs.c \ + qs_64bit.c \ + qs_rx.c \ + qs_fp.c \ + qutest.c \ + qutest_port.c + +QP_ASMS := + +LIB_DIRS := +LIBS := + +# defines +DEFINES := -DSTM32C031xx \ + -DQP_API_VERSION=9999 \ + -DQXK_USE_IRQ_HANDLER=Reserved1_IRQHandler \ + -DQXK_USE_IRQ_NUM=1 \ + -DQF_ON_CONTEXT_SW + +# ARM CPU, ARCH, FPU, and Float-ABI types... +# ARM_CPU: [cortex-m0 | cortex-m0plus | cortex-m1 | cortex-m3 | cortex-m4] +# ARM_FPU: [ | vfp] +# FLOAT_ABI: [ | soft | softfp | hard] +# +ARM_CPU := -mcpu=cortex-m0plus +ARM_FPU := +FLOAT_ABI := + +#----------------------------------------------------------------------------- +# GNU-ARM toolset (NOTE: You need to adjust to your machine) +# see https://developer.arm.com/open-source/gnu-toolchain/gnu-rm/downloads +# +ifeq ($(GNU_ARM),) +GNU_ARM := $(QTOOLS)/gnu_arm-none-eabi +endif + +# make sure that the GNU-ARM toolset exists... +ifeq ("$(wildcard $(GNU_ARM))","") +$(error GNU_ARM toolset not found. Please adjust the Makefile) +endif + +CC := $(GNU_ARM)/bin/arm-none-eabi-gcc +CPP := $(GNU_ARM)/bin/arm-none-eabi-g++ +AS := $(GNU_ARM)/bin/arm-none-eabi-as +LINK := $(GNU_ARM)/bin/arm-none-eabi-gcc +BIN := $(GNU_ARM)/bin/arm-none-eabi-objcopy + +#----------------------------------------------------------------------------- +# NOTE: The symbol USB must be provided for the NUCLEO board +# has enumerated as USB drive f: +# +ifeq ($(USB),) +$(error USB drive not provided for the NUCLEO board.) +endif + +############################################################################## +# Typically you should not need to change anything below this line + +# basic utilities (included in QTools for Windows), see: +# https://www.state-machine.com/qtools + +MKDIR := mkdir +RM := rm +CP := cp +SLEEP := sleep + +#----------------------------------------------------------------------------- +# QUTest test script utilities (requires QTOOLS): +# +ifeq ("$(wildcard $(QUTEST))","") +QUTEST := python3 $(QTOOLS)/qutest/qutest.py +endif + +#----------------------------------------------------------------------------- +# build options +# + +# combine all the soruces... +C_SRCS += $(QP_SRCS) +ASM_SRCS += $(QP_ASMS) + +BIN_DIR := build_$(TARGET) + +ASFLAGS = -g $(ARM_CPU) $(ARM_FPU) $(ASM_CPU) $(ASM_FPU) + + +# NOTE: +# Setting -DQ_UTEST=0 means that QUTest should be built WITHOUT +# the QP-stub for testing QP itself +# +CFLAGS = -c -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \ + -ffunction-sections -fdata-sections \ + -O $(INCLUDES) $(DEFINES) -DQ_SPY -DQ_UTEST=0 + +CPPFLAGS = -c -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \ + -ffunction-sections -fdata-sections -fno-rtti -fno-exceptions \ + -O $(INCLUDES) $(DEFINES) -DQ_SPY -DQ_UTEST=0 + + +LINKFLAGS = -T$(LD_SCRIPT) $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb \ + -specs=nosys.specs -specs=nano.specs \ + -Wl,-Map,$(BIN_DIR)/$(OUTPUT).map,--cref,--gc-sections $(LIB_DIRS) + +ASM_OBJS := $(patsubst %.s,%.o, $(notdir $(ASM_SRCS))) +C_OBJS := $(patsubst %.c,%.o, $(notdir $(C_SRCS))) +CPP_OBJS := $(patsubst %.cpp,%.o,$(notdir $(CPP_SRCS))) + +TARGET_BIN := $(BIN_DIR)/$(OUTPUT).bin +TARGET_ELF := $(BIN_DIR)/$(OUTPUT).elf +ASM_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(ASM_OBJS)) +C_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(C_OBJS)) +C_DEPS_EXT := $(patsubst %.o, %.d, $(C_OBJS_EXT)) +CPP_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(CPP_OBJS)) +CPP_DEPS_EXT := $(patsubst %.o, %.d, $(CPP_OBJS_EXT)) + +# create $(BIN_DIR) if it does not exist +ifeq ("$(wildcard $(BIN_DIR))","") +$(shell $(MKDIR) $(BIN_DIR)) +endif + +#----------------------------------------------------------------------------- +# rules +# + +.PHONY : run norun debug flash + +ifeq ($(MAKECMDGOALS),norun) +all : $(TARGET_BIN) +norun : all +else +all : $(TARGET_BIN) run +endif + +$(TARGET_BIN) : $(TARGET_ELF) + $(BIN) -O binary $< $@ + $(CP) $@ $(USB) + $(SLEEP) 2 + +$(TARGET_ELF) : $(ASM_OBJS_EXT) $(C_OBJS_EXT) $(CPP_OBJS_EXT) + $(CC) $(CFLAGS) $(QPC)/src/qs/qstamp.c -o $(BIN_DIR)/qstamp.o + $(LINK) $(LINKFLAGS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) + +flash : + $(CP) $(TARGET_BIN) $(USB) + +run : $(TARGET_BIN) + $(QUTEST) -q$(QSPY) -l$(LOG) -o$(OPT) -- $(TESTS) + +$(BIN_DIR)/%.d : %.c + $(CC) -MM -MT $(@:.d=.o) $(CFLAGS) $< > $@ + +$(BIN_DIR)/%.d : %.cpp + $(CPP) -MM -MT $(@:.d=.o) $(CPPFLAGS) $< > $@ + +$(BIN_DIR)/%.o : %.s + $(AS) $(ASFLAGS) $< -o $@ + +$(BIN_DIR)/%.o : %.c + $(CC) $(CFLAGS) $< -o $@ + +$(BIN_DIR)/%.o : %.cpp + $(CPP) $(CPPFLAGS) $< -o $@ + +# create BIN_DIR and include dependencies only if needed +ifneq ($(MAKECMDGOALS),clean) + ifneq ($(MAKECMDGOALS),show) + ifneq ($(MAKECMDGOALS),debug) +ifeq ("$(wildcard $(BIN_DIR))","") +$(shell $(MKDIR) $(BIN_DIR)) +endif +-include $(C_DEPS_EXT) $(CPP_DEPS_EXT) + endif + endif +endif + +debug : + $(QUTEST) -edebug -q$(QSPY) -l$(LOG) -o$(OPT) -- $(TESTS) + +.PHONY : clean show + +clean : + -$(RM) $(BIN_DIR)/*.o \ + $(BIN_DIR)/*.d \ + $(BIN_DIR)/*.bin \ + $(BIN_DIR)/*.elf \ + $(BIN_DIR)/*.map + +show : + @echo PROJECT = $(PROJECT) + @echo MAKECMDGOALS = $(MAKECMDGOALS) + @echo TESTS = $(TESTS) + @echo TARGET_ELF = $(TARGET_ELF) + @echo CONF = $(CONF) + @echo VPATH = $(VPATH) + @echo C_SRCS = $(C_SRCS) + @echo CPP_SRCS = $(CPP_SRCS) + @echo ASM_SRCS = $(ASM_SRCS) + @echo C_DEPS_EXT = $(C_DEPS_EXT) + @echo C_OBJS_EXT = $(C_OBJS_EXT) + @echo CPP_DEPS_EXT = $(CPP_DEPS_EXT) + @echo CPP_OBJS_EXT = $(CPP_OBJS_EXT) + @echo ASM_OBJS_EXT = $(ASM_OBJS_EXT) + @echo LIB_DIRS = $(LIB_DIRS) + @echo LIBS = $(LIBS) + @echo DEFINES = $(DEFINES) + @echo QTOOLS = $(QTOOLS) + @echo HOST = $(HOST) + @echo QUTEST = $(QUTEST) + @echo TESTS = $(TESTS) + diff --git a/test/qxk/test_sched/uvision_efm32.uvoptx b/test/qxk/test_sched/nucleo-c031c6.uvoptx similarity index 81% rename from test/qxk/test_sched/uvision_efm32.uvoptx rename to test/qxk/test_sched/nucleo-c031c6.uvoptx index f802e499..0ce5f988 100644 --- a/test/qxk/test_sched/uvision_efm32.uvoptx +++ b/test/qxk/test_sched/nucleo-c031c6.uvoptx @@ -45,7 +45,7 @@ 79 66 8 - .\uvision_emf32\ + .\uvision_nucleo-c031c6\ 1 @@ -77,7 +77,7 @@ 0 1 - 3 + 18 0 1 @@ -103,7 +103,7 @@ 1 0 0 - 4 + 6 @@ -114,100 +114,79 @@ - Segger\JL2CM3.dll + STLink\ST-LINKIII-KEIL_SWO.dll 0 - DLGUARM - + ST-LINKIII-KEIL_SWO + -U066BFF505153848667095842 -O207 -SF10000 -C0 -A0 -I0 -HNlocalhost -HP7184 -P1 -N00("ARM CoreSight SW-DP (ARM Core") -D00(0BC11477) -L00(0) -TO131090 -TC10000000 -TT10000000 -TP21 -TDS8007 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -FO7 -FD20000000 -FC1000 -FN1 -FF0STM32C0x_32.FLM -FS08000000 -FL08000 -FP0($$Device:STM32C031C6Tx$CMSIS\Flash\STM32C0x_32.FLM) 0 - JL2CM3 - -U440060969 -O206 -S2 -ZTIFSpeedSel5000 -A0 -C0 -JU1 -JI127.0.0.1 -JP0 -RST0 -N00("ARM CoreSight SW-DP") -D00(2BA01477) -L00(0) -TO18 -TC10000000 -TP21 -TDS8007 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -TB1 -TFE0 -FO7 -FD20000000 -FC8000 -FN1 -FF0GECKOP2.FLM -FS00 -FL020000 -FP0($$Device:EFM32PG1B200F256GM48$Flash\GECKOP2.FLM) + UL2CM3 + -O207 -S0 -C0 -FO7 -FN1 -FC1000 -FD20000000 -FF0STM32C0x_32 -FL08000 -FS08000000 -FP0($$Device:STM32C031C6Tx$CMSIS\Flash\STM32C0x_32.FLM) + + + 0 + DLGUARM + (105=-1,-1,-1,-1,0) 0 ARMRTXEVENTFLAGS -L70 -Z18 -C0 -M0 -T1 - - 0 - UL2CM3 - UL2CM3(-O207 -S0 -C0 -FO7 -FN1 -FC8000 -FD20000000 -FF0GECKOP2 -FL020000 -FS00 -FP0($$Device:EFM32PG1B200F256GM48$Flash\GECKOP2.FLM) - 0 DLGTARM - (1010=-1,-1,-1,-1,0)(1007=-1,-1,-1,-1,0)(1008=-1,-1,-1,-1,0)(1009=-1,-1,-1,-1,0)(1012=-1,-1,-1,-1,0) + (1010=1173,620,1584,1122,0)(1007=-1,-1,-1,-1,0)(1008=-1,-1,-1,-1,0)(1012=-1,-1,-1,-1,0)(1009=-1,-1,-1,-1,0) 0 ARMDBGFLAGS - - 0 - lmidk-agdi - -U0E2006F4 -O4622 -S4 -FO61 - 0 0 - 142 + 316 1 -
136
+
134218244
0 0 0 0 0 1 - ..\..\..\src\qs\qs.c + ..\..\..\3rd_party\nucleo-c031c6\arm\startup_stm32c031xx.s - \\test\../../../src/qs/qs.c\142 + \\test\../../../3rd_party/nucleo-c031c6/arm/startup_stm32c031xx.s\316
1 0 - 113 + 78 1 -
29538
+
134219190
0 0 0 0 0 1 - ..\..\..\src\qs\qutest.c + .\bsp_nucleo-c031c6.c - \\test\../../../src/qs/qutest.c\113 + \\test\bsp_nucleo-c031c6.c\78
2 0 - 259 + 118 1 -
26664
- 0 - 0 - 0 - 0 - 0 - 1 - ..\..\..\src\qxk\qxk.c - - \\test\../../../src/qxk/qxk.c\259 -
- - 3 - 0 - 103 - 1 -
29984
+
134243930
0 0 0 @@ -216,7 +195,7 @@ 1 .\test_sched.c - \\test\test_sched.c\103 + \\test\test_sched.c\118
@@ -233,12 +212,7 @@ 2 1 - QActive_registry_ - - - 3 - 1 - QS_rxPriv_ + thrX[0] @@ -299,11 +273,18 @@ + + 1 + 0 + 0 + 2 + 10000000 +
- Applicatioin + test 1 0 0 @@ -327,8 +308,8 @@ 0 0 0 - .\bsp_efm32.c - bsp_efm32.c + .\test_sched.c + test_sched.c 0 0
@@ -339,15 +320,15 @@ 0 0 0 - .\test_sched.c - test_sched.c + .\bsp_nucleo-c031c6.c + bsp_nucleo-c031c6.c 0 0
- efm32pg1b + nucleo-c031c6 1 0 0 @@ -359,20 +340,20 @@ 0 0 0 - ..\..\..\..\3rd_party\efm32pg1b\arm\startup_efm32pg1b.s - startup_efm32pg1b.s + ..\..\..\3rd_party\nucleo-c031c6\arm\startup_stm32c031xx.s + startup_stm32c031xx.s 0 0 2 5 - 1 + 5 0 0 0 - ..\..\..\..\3rd_party\efm32pg1b\em_cmu.c - em_cmu.c + ..\..\..\3rd_party\nucleo-c031c6\stm32c031xx.h + stm32c031xx.h 0 0 @@ -383,20 +364,20 @@ 0 0 0 - ..\..\..\..\3rd_party\efm32pg1b\em_emu.c - em_emu.c + ..\..\..\3rd_party\nucleo-c031c6\system_stm32c0xx.c + system_stm32c0xx.c 0 0 2 7 - 1 + 5 0 0 0 - ..\..\..\..\3rd_party\efm32pg1b\em_gpio.c - em_gpio.c + ..\..\..\3rd_party\nucleo-c031c6\system_stm32c0xx.h + system_stm32c0xx.h 0 0 @@ -407,32 +388,8 @@ 0 0 0 - ..\..\..\..\3rd_party\efm32pg1b\system_efm32pg1b.c - system_efm32pg1b.c - 0 - 0 - - - 2 - 9 - 1 - 0 - 0 - 0 - ..\..\..\..\3rd_party\efm32pg1b\em_system.c - em_system.c - 0 - 0 - - - 2 - 10 - 1 - 0 - 0 - 0 - ..\..\..\..\3rd_party\efm32pg1b\em_usart.c - em_usart.c + ..\..\..\3rd_party\nucleo-c031c6\qutest\qutest_port.c + qutest_port.c 0 0 @@ -446,7 +403,7 @@ 0 3 - 11 + 9 1 0 0 @@ -458,7 +415,7 @@ 3 - 12 + 10 1 0 0 @@ -470,7 +427,7 @@ 3 - 13 + 11 1 0 0 @@ -482,7 +439,7 @@ 3 - 14 + 12 1 0 0 @@ -494,7 +451,7 @@ 3 - 15 + 13 1 0 0 @@ -506,7 +463,7 @@ 3 - 16 + 14 1 0 0 @@ -518,7 +475,7 @@ 3 - 17 + 15 1 0 0 @@ -530,7 +487,7 @@ 3 - 18 + 16 1 0 0 @@ -542,7 +499,7 @@ 3 - 19 + 17 1 0 0 @@ -554,7 +511,7 @@ 3 - 20 + 18 1 0 0 @@ -566,7 +523,7 @@ 3 - 21 + 19 1 0 0 @@ -578,7 +535,7 @@ 3 - 22 + 20 1 0 0 @@ -590,7 +547,7 @@ 3 - 23 + 21 1 0 0 @@ -602,7 +559,7 @@ 3 - 24 + 22 1 0 0 @@ -614,7 +571,7 @@ 3 - 25 + 23 1 0 0 @@ -626,7 +583,7 @@ 3 - 26 + 24 1 0 0 @@ -636,18 +593,6 @@ 0 0 - - 3 - 27 - 1 - 0 - 0 - 0 - ..\..\..\include\qstamp.c - qstamp.c - 0 - 0 - @@ -658,7 +603,7 @@ 0 4 - 28 + 25 5 0 0 @@ -670,7 +615,7 @@ 4 - 29 + 26 5 0 0 @@ -682,7 +627,7 @@ 4 - 30 + 27 5 0 0 @@ -694,7 +639,7 @@ 4 - 31 + 28 1 0 0 @@ -706,7 +651,7 @@ 4 - 32 + 29 5 0 0 @@ -716,18 +661,6 @@ 0 0 - - 4 - 33 - 1 - 0 - 0 - 0 - ..\..\..\3rd_party\efm32pg1b\qutest\qutest_port.c - qutest_port.c - 0 - 0 - @@ -738,7 +671,7 @@ 0 5 - 34 + 30 1 0 0 @@ -750,7 +683,7 @@ 5 - 35 + 31 1 0 0 @@ -762,7 +695,7 @@ 5 - 36 + 32 1 0 0 @@ -774,7 +707,7 @@ 5 - 37 + 33 1 0 0 @@ -786,7 +719,19 @@ 5 - 38 + 34 + 1 + 0 + 0 + 0 + ..\..\..\src\qs\qstamp.c + qstamp.c + 0 + 0 + + + 5 + 35 1 0 0 diff --git a/test/qxk/test_sched/uvision_efm32.uvprojx b/test/qxk/test_sched/nucleo-c031c6.uvprojx similarity index 84% rename from test/qxk/test_sched/uvision_efm32.uvprojx rename to test/qxk/test_sched/nucleo-c031c6.uvprojx index a0282480..3d398d49 100644 --- a/test/qxk/test_sched/uvision_efm32.uvprojx +++ b/test/qxk/test_sched/nucleo-c031c6.uvprojx @@ -14,16 +14,16 @@ 1 - EFM32PG1B200F256GM48 - Silicon Labs - SiliconLabs.GeckoPlatform_EFM32PG1B_DFP.4.0.0 - https://www.silabs.com/documents/public/cmsis-packs/ - IRAM(0x20000000,0x00008000) IROM(0x00000000,0x00020000) CPUTYPE("Cortex-M4") FPU2 CLOCK(12000000) ELITTLE + STM32C031C6Tx + STMicroelectronics + Keil.STM32C0xx_DFP.1.0.0 + https://www.keil.com/pack/ + IRAM(0x20000000,0x00003000) IROM(0x08000000,0x00008000) CPUTYPE("Cortex-M0+") CLOCK(12000000) ELITTLE - UL2CM3(-S0 -C0 -P0 -FD20000000 -FC8000 -FN1 -FF0GECKOP2 -FS00 -FL020000 -FP0($$Device:EFM32PG1B200F256GM48$Flash\GECKOP2.FLM)) + UL2CM3(-S0 -C0 -P0 -FD20000000 -FC1000 -FN1 -FF0STM32C0x_32 -FS08000000 -FL08000 -FP0($$Device:STM32C031C6Tx$CMSIS\Flash\STM32C0x_32.FLM)) 0 - $$Device:EFM32PG1B200F256GM48$Device\EFM32PG1B\Include\em_device.h + $$Device:STM32C031C6Tx$Drivers\CMSIS\Device\ST\STM32C0xx\Include\stm32c0xx.h @@ -33,7 +33,7 @@ - $$Device:EFM32PG1B200F256GM48$SVD\EFM32PG1B\EFM32PG1B200F256GM48.svd + $$Device:STM32C031C6Tx$CMSIS\SVD\STM32C031.svd 0 0 @@ -48,14 +48,14 @@ 0 1 - .\uvision_emf32\ + .\uvision_nucleo-c031c6\ test 1 0 0 1 1 - .\uvision_emf32\ + .\uvision_nucleo-c031c6\ 1 0 0 @@ -72,7 +72,7 @@ 1 0 - cmd /c "del .\uvision_em32\qstamp.o" + cmd /c "del .\uvision_nucleo-c031c6\qstamp.o" 0 0 @@ -80,16 +80,16 @@ 0 - 0 + 1 0 - + fromelf --bin --output .\uvision_nucleo-c031c6\test.bin .\uvision_nucleo-c031c6\test.axf 0 0 0 0 - 1 + 0 @@ -110,13 +110,13 @@ SARMCM3.DLL - -MPU - DCM.DLL - -pCM4 + -REMAP-MPU + DARMCM1.DLL + -pCM0+ SARMCM3.DLL - -MPU - TCM.DLL - -pCM4 + -MPU + TARMCM1.DLL + -pCM0+ @@ -174,7 +174,7 @@ 1 0 0 - "Cortex-M4" + "Cortex-M0+" 0 0 @@ -183,7 +183,7 @@ 1 0 0 - 2 + 0 0 0 0 @@ -246,12 +246,12 @@ 0 0x20000000 - 0x8000 + 0x3000 1 - 0x0 - 0x20000 + 0x8000000 + 0x8000 0 @@ -275,8 +275,8 @@ 1 - 0x0 - 0x20000 + 0x8000000 + 0x8000 1 @@ -301,7 +301,7 @@ 0 0x20000000 - 0x8000 + 0x3000 0 @@ -325,7 +325,7 @@ 3 0 1 - 1 + 0 0 0 3 @@ -337,9 +337,9 @@ 0 - Q_SPY, Q_UTEST=0, QF_ON_CONTEXT_SW + Q_SPY, Q_UTEST=0,QXK_USE_IRQ_HANDLER=Reserved1_IRQHandler,QXK_USE_IRQ_NUM=1,QF_ON_CONTEXT_SW - .;..\..\..\include;..\..\..\ports\arm-cm\qxk\armclang;..\..\..\..\3rd_party\CMSIS\Include;..\..\..\..\3rd_party\efm32pg1b + .;..\..\..\include;..\..\..\ports\arm-cm\qxk\armclang;..\..\..\3rd_party\CMSIS\Include,..\..\..\3rd_party\nucleo-c031c6 @@ -370,7 +370,7 @@ 0x00000000 0x20000000 - + dpp-qk.sct --entry Reset_Handler @@ -381,62 +381,52 @@ - Applicatioin + test bsp.h 5 .\bsp.h - - bsp_efm32.c - 1 - .\bsp_efm32.c - test_sched.c 1 .\test_sched.c + + bsp_nucleo-c031c6.c + 1 + .\bsp_nucleo-c031c6.c + - efm32pg1b + nucleo-c031c6 - startup_efm32pg1b.s + startup_stm32c031xx.s 2 - ..\..\..\..\3rd_party\efm32pg1b\arm\startup_efm32pg1b.s + ..\..\..\3rd_party\nucleo-c031c6\arm\startup_stm32c031xx.s - em_cmu.c - 1 - ..\..\..\..\3rd_party\efm32pg1b\em_cmu.c + stm32c031xx.h + 5 + ..\..\..\3rd_party\nucleo-c031c6\stm32c031xx.h - em_emu.c + system_stm32c0xx.c 1 - ..\..\..\..\3rd_party\efm32pg1b\em_emu.c + ..\..\..\3rd_party\nucleo-c031c6\system_stm32c0xx.c - em_gpio.c - 1 - ..\..\..\..\3rd_party\efm32pg1b\em_gpio.c + system_stm32c0xx.h + 5 + ..\..\..\3rd_party\nucleo-c031c6\system_stm32c0xx.h - system_efm32pg1b.c + qutest_port.c 1 - ..\..\..\..\3rd_party\efm32pg1b\system_efm32pg1b.c - - - em_system.c - 1 - ..\..\..\..\3rd_party\efm32pg1b\em_system.c - - - em_usart.c - 1 - ..\..\..\..\3rd_party\efm32pg1b\em_usart.c + ..\..\..\3rd_party\nucleo-c031c6\qutest\qutest_port.c @@ -523,11 +513,6 @@ 1 ..\..\..\src\qxk\qxk_xthr.c - - qstamp.c - 1 - ..\..\..\include\qstamp.c - @@ -558,11 +543,6 @@ 5 ..\..\..\ports\arm-cm\qxk\armclang\qxk_port.h - - qutest_port.c - 1 - ..\..\..\3rd_party\efm32pg1b\qutest\qutest_port.c - @@ -588,6 +568,11 @@ 1 ..\..\..\src\qs\qs_rx.c + + qstamp.c + 1 + ..\..\..\src\qs\qstamp.c + qutest.c 1 @@ -608,8 +593,9 @@ - test + uvision_c031c6 1 + nucleo-c031c6 diff --git a/test/qxk/test_sched/make_nucleo-h743zi b/test/qxk/test_sched/nucleo-h743zi.mak similarity index 93% rename from test/qxk/test_sched/make_nucleo-h743zi rename to test/qxk/test_sched/nucleo-h743zi.mak index a1aa1680..ef3e1d9d 100644 --- a/test/qxk/test_sched/make_nucleo-h743zi +++ b/test/qxk/test_sched/nucleo-h743zi.mak @@ -1,7 +1,7 @@ ############################################################################## # Product: Makefile for QP/C on NUCLEO-H743ZI board, QUTEST, GNU-ARM -# Last Updated for Version: 7.2.0 -# Date of the Last Update: 2022-12-21 +# Last Updated for Version: 7.3.0 +# Date of the Last Update: 2023-09-06 # # Q u a n t u m L e a P s # ------------------------ @@ -33,11 +33,12 @@ ############################################################################## # # examples of invoking this Makefile: -# make -f make_nucleo-h743zi USB=g: # make, uplaod to USB drive, run the tests -# make -f make_nucleo-h743zi USB=g: TESTS=philo*.py # make and run the selected tests -# make -f make_nucleo-h743zi HOST=localhost:7705 # connect to host:port -# make -f make_nucleo-h743zi norun # only make but not run the tests -# make -f make_nucleo-h743zi clean # cleanup the build +# make -f nucleo-h743zi.mak USB=g: # make, uplaod to USB drive, run the tests +# make -f nucleo-h743zi.mak USB=g: TESTS=philo*.py # make and run the selected tests +# make -f nucleo-h743zi.mak USB=g: HOST=localhost:7705 # connect to host:port +# make -f nucleo-h743zi.mak USB=g: norun # only make but not run the tests +# make -f nucleo-h743zi.mak USB=g: clean # cleanup the build +# make -f nucleo-h743zi.mak USB=g: debug # only run tests in DEBUG mode # # NOTE: # To use this Makefile on Windows, you will need the GNU make utility, which @@ -102,7 +103,7 @@ ASM_SRCS := # C source files C_SRCS := \ test_sched.c \ - bsp_h743zi.c \ + bsp_nucleo-h743zi.c \ startup_stm32h743xx.c \ system_stm32h7xx.c \ stm32h7xx_nucleo_144.c \ @@ -276,7 +277,7 @@ $(TARGET_BIN) : $(TARGET_ELF) $(SLEEP) 2 $(TARGET_ELF) : $(ASM_OBJS_EXT) $(C_OBJS_EXT) $(CPP_OBJS_EXT) - $(CC) $(CFLAGS) $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o + $(CC) $(CFLAGS) $(QPC)/src/qs/qstamp.c -o $(BIN_DIR)/qstamp.o $(LINK) $(LINKFLAGS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) flash : @@ -313,7 +314,7 @@ endif endif debug : - $(QUTEST) $(TESTS) DEBUG $(HOST) + $(QUTEST) -edebug -q$(QSPY) -l$(LOG) -o$(OPT) -- $(TESTS) .PHONY : clean show diff --git a/test/qxk/test_sched/make_nucleo-l053r8 b/test/qxk/test_sched/nucleo-l053r8.mak similarity index 93% rename from test/qxk/test_sched/make_nucleo-l053r8 rename to test/qxk/test_sched/nucleo-l053r8.mak index 237293a0..7ff8d1e9 100644 --- a/test/qxk/test_sched/make_nucleo-l053r8 +++ b/test/qxk/test_sched/nucleo-l053r8.mak @@ -1,7 +1,7 @@ ############################################################################## # Product: Makefile for SYSTEM-Level tests of QP/C on NUCLEO-L053R8, GNU-ARM -# Last Updated for Version: 7.2.0 -# Date of the Last Update: 2022-12-21 +# Last Updated for Version: 7.3.0 +# Date of the Last Update: 2023-09-06 # # Q u a n t u m L e a P s # ------------------------ @@ -33,12 +33,12 @@ ############################################################################## # # examples of invoking this Makefile: -# make -f make_nucleo-l053r8 USB=e: # make, uplaod to USB drive, run the tests -# make -f make_nucleo-l053r8 USB=h: TESTS=philo*.py # make and run the selected tests -# make -f make_nucleo-l053r8 HOST=localhost:7705 # connect to host:port -# make -f make_nucleo-l053r8 norun # only make but not run the tests -# make -f make_nucleo-l053r8 clean # cleanup the build -# make -f make_nucleo-l053r8 debug # only run tests in DEBUG mode +# make -f nucleo-l053r8.mak USB=g: # make, uplaod to USB drive, run the tests +# make -f nucleo-l053r8.mak USB=g: TESTS=philo*.py # make and run the selected tests +# make -f nucleo-l053r8.mak HOST=localhost:7705 # connect to host:port +# make -f nucleo-l053r8.mak norun # only make but not run the tests +# make -f nucleo-l053r8.mak clean # cleanup the build +# make -f nucleo-l053r8.mak debug # only run tests in DEBUG mode # # NOTE: # To use this Makefile on Windows, you will need the GNU make utility, which @@ -99,7 +99,7 @@ ASM_SRCS := # C source files C_SRCS := \ test_sched.c \ - bsp_l053r8.c \ + bsp_nucleo-l053r8.c \ system_stm32l0xx.c \ startup_stm32l053xx.c @@ -263,7 +263,7 @@ $(TARGET_BIN) : $(TARGET_ELF) $(SLEEP) 2 $(TARGET_ELF) : $(ASM_OBJS_EXT) $(C_OBJS_EXT) $(CPP_OBJS_EXT) - $(CC) $(CFLAGS) $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o + $(CC) $(CFLAGS) $(QPC)/src/qs/qstamp.c -o $(BIN_DIR)/qstamp.o $(LINK) $(LINKFLAGS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) flash : @@ -300,7 +300,7 @@ endif endif debug : - $(QUTEST) $(TESTS) DEBUG $(HOST) + $(QUTEST) -edebug -q$(QSPY) -l$(LOG) -o$(OPT) -- $(TESTS) .PHONY : clean show diff --git a/test/qxk/test_sched/test_sched.c b/test/qxk/test_sched/test_sched.c index 2edc0343..0156c8ad 100644 --- a/test/qxk/test_sched/test_sched.c +++ b/test/qxk/test_sched/test_sched.c @@ -1,43 +1,43 @@ -/*============================================================================ -* Product: System test fixture for QXK kernel -* Last updated for version 7.2.0 -* Last updated on 2022-12-22 -* -* Q u a n t u m L e a P s -* ------------------------ -* Modern Embedded Software -* -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* This program is open source software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* Alternatively, this program may be distributed and modified under the -* terms of Quantum Leaps commercial licenses, which expressly supersede -* the GNU General Public License and are specifically designed for -* licensees interested in retaining the proprietary status of their code. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Contact information: -* -* -============================================================================*/ +//============================================================================ +// Product: System test fixture for QXK kernel +// Last Updated for Version: 7.3.0 +// Date of the Last Update: 2023-06-30 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// This program is open source software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Alternatively, this program may be distributed and modified under the +// terms of Quantum Leaps commercial licenses, which expressly supersede +// the GNU General Public License and are specifically designed for +// licensees interested in retaining the proprietary status of their code. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Contact information: +// +// +//============================================================================ #include "qpc.h" #include "bsp.h" -Q_DEFINE_THIS_FILE +//Q_DEFINE_THIS_FILE -/*==========================================================================*/ -/* AO ObjB */ +//========================================================================== +// AO ObjB enum { NUM_B = 3 }; typedef struct { @@ -51,7 +51,7 @@ void ObjB_ctor(ObjB * const me) { QActive_ctor(&me->super, Q_STATE_CAST(&ObjB_initial)); } -/*..........................................................................*/ +//.......................................................................... QState ObjB_initial(ObjB * const me, void const * const par) { Q_UNUSED_PAR(par); QActive_subscribe(&me->super, TEST1_SIG); @@ -59,7 +59,7 @@ QState ObjB_initial(ObjB * const me, void const * const par) { QS_FUN_DICTIONARY(&ObjB_active); return Q_TRAN(&ObjB_active); } -/*..........................................................................*/ +//.......................................................................... QState ObjB_active(ObjB * const me, QEvt const * const e) { QState status_; switch (e->sig) { @@ -87,11 +87,10 @@ QState ObjB_active(ObjB * const me, QEvt const * const e) { } return status_; } -/*..........................................................................*/ +//.......................................................................... ObjB aoB[NUM_B]; - -/*==========================================================================*/ +//========================================================================== enum { NUM_X = 3 }; enum UserCommands { @@ -100,7 +99,7 @@ enum UserCommands { RAM_READ, RAM_WRITE, }; -/*..........................................................................*/ +//.......................................................................... void ThrX_run(QXThread * const me) { QActive_subscribe(&me->super, TEST1_SIG); QActive_subscribe(&me->super, TEST2_SIG); @@ -115,7 +114,7 @@ void ThrX_run(QXThread * const me) { break; } case TEST1_SIG: { - static QEvt const t2 = { TEST2_SIG, 0U, 0U }; + static QEvt const t2 = QEVT_INITIALIZER(TEST2_SIG); BSP_trace(&me->super, "TEST1 1of2"); QACTIVE_PUBLISH(&t2, &me->super); BSP_trace(&me->super, "TEST1 2of2"); @@ -132,25 +131,23 @@ void ThrX_run(QXThread * const me) { } } -/*..........................................................................*/ +//.......................................................................... QXThread thrX[NUM_X]; -/*==========================================================================*/ +//========================================================================== int main() { - QF_init(); /* initialize the framework and the underlying QXK kernel */ - BSP_init(); /* initialize the Board Support Package */ + QF_init(); // initialize the framework and the underlying QXK kernel + BSP_init(); // initialize the Board Support Package - /* initialize publish-subscribe... */ + // initialize publish-subscribe... static QSubscrList subscrSto[MAX_PUB_SIG]; QActive_psInit(subscrSto, Q_DIM(subscrSto)); - /* initialize event pools... */ - static QF_MPOOL_EL(QEvt) smlPoolSto[10]; /* small pool */ + // initialize event pools... + static QF_MPOOL_EL(QEvt) smlPoolSto[10]; // small pool QF_poolInit(smlPoolSto, sizeof(smlPoolSto), sizeof(smlPoolSto[0])); - /* dictionaries */ - QS_SIG_DICTIONARY(QXK_DELAY_SIG, (void *)0); - QS_SIG_DICTIONARY(QXK_TIMEOUT_SIG, (void *)0); + // dictionaries QS_SIG_DICTIONARY(TEST0_SIG, (void *)0); QS_SIG_DICTIONARY(TEST1_SIG, (void *)0); QS_SIG_DICTIONARY(TEST2_SIG, (void *)0); @@ -163,11 +160,11 @@ int main() { QS_ENUM_DICTIONARY(RAM_READ, QS_CMD); QS_ENUM_DICTIONARY(RAM_WRITE, QS_CMD); - /* priority specifications for ObjBs... */ + // priority specifications for ObjBs... static QPrioSpec pspecB[NUM_B]; QS_OBJ_DICTIONARY(pspecB); - /* priority specifications for ThrXs... */ + // priority specifications for ThrXs... static QPrioSpec pspecX[NUM_X]; QS_OBJ_DICTIONARY(pspecX); @@ -181,52 +178,51 @@ int main() { pspecX[n] = NUM_B + 1U + n; } - /* pause execution of the test and wait for the test script to continue - * NOTE: - * this pause gives the test-script a chance to poke pspecB and pspecX - * variables to start the threads with the desired prio-specifications. - */ + // pause execution of the test and wait for the test script to continue + // NOTE: + // this pause gives the test-script a chance to poke pspecB and pspecX + // variables to start the threads with the desired prio-specifications. QS_TEST_PAUSE(); static QEvt const *aoB_queueSto[NUM_B][5]; for (n = 0U; n < NUM_B; ++n) { if (pspecB[n] != 0U) { - ObjB_ctor(&aoB[n]); /* instantiate the AO */ - QACTIVE_START(&aoB[n].super, /* AO to start */ - pspecB[n], /* QF-prio/p-thre.*/ - aoB_queueSto[n], /* event queue storage */ - Q_DIM(aoB_queueSto[n]), /* event length [events] */ - (void *)0, /* no stack storage */ - 0U, /* zero stack size [bytes] */ - (void *)0); /* initialization param */ + ObjB_ctor(&aoB[n]); // instantiate the AO + QACTIVE_START(&aoB[n].super, // AO to start + pspecB[n], // QF-prio/p-thre. + aoB_queueSto[n], // event queue storage + Q_DIM(aoB_queueSto[n]), // event length [events] + (void *)0, // no stack storage + 0U, // zero stack size [bytes] + (void *)0); // initialization param } } static QEvt const *thrX_queueSto[NUM_X][5]; static uint64_t thrXStackSto[NUM_X][32]; for (n = 0U; n < NUM_X; ++n) { - QXThread_ctor(&thrX[n], &ThrX_run, 0U); /* instantiate the thread */ + QXThread_ctor(&thrX[n], &ThrX_run, 0U); // instantiate the thread if (pspecX[n] != 0U) { - QXTHREAD_START(&thrX[n], /* thread to start */ - pspecX[n], /* QF-prio/p-thre.*/ - thrX_queueSto[n], /* event queue storage */ - Q_DIM(thrX_queueSto[n]), /* event length [events] */ - thrXStackSto[n], /* stack storage */ - sizeof(thrXStackSto[n]), /* stack size [bytes] */ - (void *)0); /* initialization param */ + QXTHREAD_START(&thrX[n], // thread to start + pspecX[n], // QF-prio/p-thre. + thrX_queueSto[n], // event queue storage + Q_DIM(thrX_queueSto[n]), // event length [events] + thrXStackSto[n], // stack storage + sizeof(thrXStackSto[n]), // stack size [bytes] + (void *)0); // initialization param } } - return QF_run(); /* run the QF application */ + return QF_run(); // run the QF application } -/*==========================================================================*/ +//========================================================================== void QS_onTestSetup(void) { } -/*..........................................................................*/ +//.......................................................................... void QS_onTestTeardown(void) { } -/*..........................................................................*/ -/*! callback function to execute user commands */ +//.......................................................................... +//! callback function to execute user commands void QS_onCommand(uint8_t cmdId, uint32_t param1, uint32_t param2, uint32_t param3) { @@ -293,13 +289,13 @@ void QS_onCommand(uint8_t cmdId, } } -/****************************************************************************/ -/*! Host callback function to "massage" the event, if necessary */ +//**************************************************************************** +//! Host callback function to "massage" the event, if necessary void QS_onTestEvt(QEvt *e) { - (void)e; + Q_UNUSED_PAR(e); } -/*..........................................................................*/ -/*! callback function to output the posted QP events (not used here) */ +//.......................................................................... +//! callback function to output the posted QP events (not used here) void QS_onTestPost(void const *sender, QActive *recipient, QEvt const *e, bool status) { diff --git a/zephyr/CMakeLists.txt b/zephyr/CMakeLists.txt index edf269c7..e0c88798 100644 --- a/zephyr/CMakeLists.txt +++ b/zephyr/CMakeLists.txt @@ -44,7 +44,7 @@ zephyr_library_sources( ${QPC_DIR}/src/qs/qs_fp.c ${QPC_DIR}/src/qs/qutest.c ${QPC_DIR}/src/qs/qs_64bit.c - ${QPC_DIR}/include/qstamp.c + ${QPC_DIR}/src/qs/qstamp.c ) endif() # QSPY diff --git a/zephyr/qep_port.h b/zephyr/qep_port.h deleted file mode 100644 index b156ac67..00000000 --- a/zephyr/qep_port.h +++ /dev/null @@ -1,41 +0,0 @@ -/*============================================================================ -* QP/C Real-Time Embedded Framework (RTEF) -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2022-06-03 -* @version Last updated for: @ref qpc_7_0_1 -* -* @file -* @brief QEP/C port, generic C99 compiler -*/ -#ifndef QEP_PORT_H -#define QEP_PORT_H - -#include /* Exact-width types. WG14/N843 C99 Standard */ -#include /* Boolean type. WG14/N843 C99 Standard */ - -#include "qep.h" /* QEP platform-independent public interface */ - -#endif /* QEP_PORT_H */ - diff --git a/zephyr/qf_port.c b/zephyr/qf_port.c index 7be33e34..91911be0 100644 --- a/zephyr/qf_port.c +++ b/zephyr/qf_port.c @@ -1,258 +1,277 @@ -/*============================================================================ -* QP/C Real-Time Embedded Framework (RTEF) -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2022-10-18 -* @version Last updated for: Zephyr 3.1.99 and @ref qpc_7_1_3 -* -* @file -* @brief QF/C port to Zephyr RTOS (v 3.1.99) -*/ -#define QP_IMPL /* this is QP implementation */ -#include "qf_port.h" /* QF port */ -#include "qf_pkg.h" -#include "qassert.h" -#ifdef Q_SPY /* QS software tracing enabled? */ - #include "qs_port.h" /* QS port */ - #include "qs_pkg.h" /* QS package-scope internal interface */ +//============================================================================ +// QP/C Real-Time Embedded Framework (RTEF) +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +//============================================================================ +//! @date Last updated on: 2023-08-19 +//! @version Last updated for: @ref qpc_7_3_0 +//! +//! @file +//! @brief QF/C port to Zephyr RTOS (v 3.1.99) + +#define QP_IMPL // this is QP implementation +#include "qp_port.h" // QP port +#include "qp_pkg.h" // QP package-scope interface +#include "qsafe.h" // QP Functional Safety (FuSa) Subsystem +#ifdef Q_SPY // QS software tracing enabled? + #include "qs_port.h" // QS port + #include "qs_pkg.h" // QS package-scope internal interface #else - #include "qs_dummy.h" /* disable the QS software tracing */ -#endif /* Q_SPY */ + #include "qs_dummy.h" // disable the QS software tracing +#endif // Q_SPY Q_DEFINE_THIS_MODULE("qf_port") -/*..........................................................................*/ +//............................................................................ struct k_spinlock QF_spinlock; -/*..........................................................................*/ +//............................................................................ void QF_init(void) { QF_spinlock = (struct k_spinlock){}; } -/*..........................................................................*/ +//............................................................................ int_t QF_run(void) { QF_onStartup(); + #ifdef Q_SPY -#if CONFIG_NUM_PREEMPT_PRIORITIES > 0 - /* lower the priority of the main thread to the level of idle thread */ +#if (CONFIG_NUM_PREEMPT_PRIORITIES > 0) + // lower the priority of the main thread to the level of idle thread k_thread_priority_set(k_current_get(), CONFIG_NUM_PREEMPT_PRIORITIES - 1); #endif - /* perform QS work... */ + // produce the QS_QF_RUN trace record + QS_CRIT_STAT + QS_CRIT_ENTRY(); + QS_BEGIN_PRE_(QS_QF_RUN, 0U) + QS_END_PRE_() + QS_CRIT_EXIT(); + + // perform QS work... while (true) { - QS_rxParse(); /* parse any QS-RX bytes */ - QS_doOutput(); /* perform the QS-TX output */ + QS_rxParse(); // parse any QS-RX bytes + QS_doOutput(); // perform the QS-TX output } #else - return 0; /* return from the main Zephyr thread */ + return 0; // return from the main Zephyr thread #endif } -/*..........................................................................*/ +//............................................................................ void QF_stop(void) { - QF_onCleanup(); /* cleanup callback */ + QF_onCleanup(); // cleanup callback } -/*..........................................................................*/ +//............................................................................ static void thread_entry(void *p1, void *p2, void *p3) { + Q_UNUSED_PAR(p2); + Q_UNUSED_PAR(p3); QActive *act = (QActive *)p1; - (void)p2; /* unused parameter */ - (void)p3; /* unused parameter */ - /* event-loop */ - for (;;) { /* for-ever */ + // event-loop + for (;;) { // for-ever QEvt const *e = QActive_get_(act); - QHSM_DISPATCH(&act->super, e, act->prio); - QF_gc(e); /* check if the event is garbage, and collect it if so */ + // dispatch event (virtual call) + (*act->super.vptr->dispatch)(&act->super, e, act->prio); + QF_gc(e); // check if the event is garbage, and collect it if so } } -/*..........................................................................*/ -/* -* In the Zephyr port the generic function QActive_setAttr() is used to -* set the options for the Zephyr thread (attr1) and thread name (attr2). -* QActive_setAttr() needs to be called *before* QACTIVE_START() for the -* given active object. -* -* In this Zephyr port the attributes will be used as follows (see also -* Active_start_()): -* - attr1 - will be used for thread options in k_thread_create() -* - attr2 - will be used for thread name in k_thread_name_set() -*/ + +//............................................................................ +// +// In the Zephyr port the generic function QActive_setAttr() is used to +// set the options for the Zephyr thread (attr1) and thread name (attr2). +// QActive_setAttr() needs to be called *before* QACTIVE_START() for the +// given active object. +// +// In this Zephyr port the attributes will be used as follows +// (see also QActive_start_()): +// - attr1 - will be used for thread options in k_thread_create() +// - attr2 - will be used for thread name in k_thread_name_set() +// void QActive_setAttr(QActive *const me, uint32_t attr1, void const *attr2) { - me->thread.base.order_key = attr1; /* will be used for thread options */ - me->thread.init_data = (void *)attr2; /* will be used for thread name */ + me->thread.base.order_key = attr1; // will be used for thread options + me->thread.init_data = (void *)attr2; // will be used for thread name } -/*..........................................................................*/ +//............................................................................ void QActive_start_(QActive * const me, QPrioSpec const prioSpec, QEvt const * * const qSto, uint_fast16_t const qLen, void * const stkSto, uint_fast16_t const stkSize, void const * const par) { - me->prio = (uint8_t)(prioSpec & 0xFFU); /* QF-priority of the AO */ - me->pthre = (uint8_t)(prioSpec >> 8U); /* preemption-threshold */ - QActive_register_(me); /* register this AO */ + me->prio = (uint8_t)(prioSpec & 0xFFU); // QF-priority of the AO + me->pthre = (uint8_t)(prioSpec >> 8U); // preemption-threshold + QActive_register_(me); // register this AO - /* initialize the Zephyr message queue */ + // initialize the Zephyr message queue k_msgq_init(&me->eQueue, (char *)qSto, sizeof(QEvt *), (uint32_t)qLen); - QHSM_INIT(&me->super, par, me->prio); /* the top-most initial tran. */ - QS_FLUSH(); /* flush the trace buffer to the host */ + // top-most initial tran. (virtual call) + (*me->super.vptr->init)(&me->super, par, me->prio); + QS_FLUSH(); // flush the trace buffer to the host - /* Zephyr uses the reverse priority numbering than QP */ + // Zephyr uses the reverse priority numbering than QP int zprio = (int)QF_MAX_ACTIVE - (int)me->prio; - /* extract data temporarily saved in me->thread by QActive_setAttr() */ + // extract data temporarily saved in me->thread by QActive_setAttr() uint32_t opt = me->thread.base.order_key; #ifdef CONFIG_THREAD_NAME char const *name = (char const *)me->thread.init_data; #endif - /* clear the Zephyr thread structure before creating the thread */ + // clear the Zephyr thread structure before creating the thread me->thread = (struct k_thread){}; - /* create a Zephyr thread for the AO... */ + // create a Zephyr thread for the AO... k_thread_create(&me->thread, (k_thread_stack_t *)stkSto, (size_t)stkSize, &thread_entry, - (void *)me, /* p1 */ - (void *)0, /* p2 */ - (void *)0, /* p3 */ - zprio, /* Zephyr priority */ - opt, /* thread options */ - K_NO_WAIT); /* start immediately */ + (void *)me, // p1 + (void *)0, // p2 + (void *)0, // p3 + zprio, // Zephyr priority + opt, // thread options + K_NO_WAIT); // start immediately #ifdef CONFIG_THREAD_NAME - /* set the Zephyr thread name, if initialized, or the default name "AO" */ + // set the Zephyr thread name, if initialized, or the default name "AO" k_thread_name_set(&me->thread, (name != (char *)0) ? name : "AO"); #endif } -/*..........................................................................*/ +//............................................................................ bool QActive_post_(QActive * const me, QEvt const * const e, uint_fast16_t const margin, void const * const sender) { - QF_CRIT_STAT_ - QF_CRIT_E_(); + QF_CRIT_STAT + QF_CRIT_ENTRY(); + // NOTE: k_msgq_num_free_get() can be safely called from crit-section uint_fast16_t nFree = (uint_fast16_t)k_msgq_num_free_get(&me->eQueue); bool status; if (margin == QF_NO_MARGIN) { if (nFree > 0U) { - status = true; /* can post */ + status = true; // can post } else { - status = false; /* cannot post */ - Q_ERROR_ID(510); /* must be able to post the event */ + status = false; // cannot post + Q_ERROR_INCRIT(510); // must be able to post the event } } else if (nFree > (QEQueueCtr)margin) { - status = true; /* can post */ + status = true; // can post } else { - status = false; /* cannot post */ + status = false; // cannot post } - if (status) { /* can post the event? */ + if (status) { // can post the event? - QS_BEGIN_NOCRIT_PRE_(QS_QF_ACTIVE_POST, me->prio) - QS_TIME_PRE_(); /* timestamp */ - QS_OBJ_PRE_(sender); /* the sender object */ - QS_SIG_PRE_(e->sig); /* the signal of the event */ - QS_OBJ_PRE_(me); /* this active object (recipient) */ - QS_2U8_PRE_(e->poolId_, e->refCtr_); /* pool Id & ref Count */ - QS_EQC_PRE_(nFree); /* # free entries available */ - QS_EQC_PRE_(0U); /* min # free entries (unknown) */ - QS_END_NOCRIT_PRE_() + QS_BEGIN_PRE_(QS_QF_ACTIVE_POST, me->prio) + QS_TIME_PRE_(); // timestamp + QS_OBJ_PRE_(sender); // the sender object + QS_SIG_PRE_(e->sig); // the signal of the event + QS_OBJ_PRE_(me); // this active object (recipient) + QS_2U8_PRE_(QEvt_getPoolId_(e), e->refCtr_);// pool-Id & ref-Count + QS_EQC_PRE_(nFree); // # free entries available + QS_EQC_PRE_(0U); // min # free entries (unknown) + QS_END_PRE_() - if (e->poolId_ != 0U) { /* is it a pool event? */ - QEvt_refCtr_inc_(e); /* increment the reference counter */ + if (QEvt_getPoolId_(e) != 0U) { // is it a pool event? + QEvt_refCtr_inc_(e); // increment the reference counter } + QF_CRIT_EXIT(); - QF_CRIT_X_(); + int err = k_msgq_put(&me->eQueue, (void const *)&e, K_NO_WAIT); - /* posting to the Zephyr message queue must succeed, see NOTE1 */ - Q_ALLEGE_ID(520, - k_msgq_put(&me->eQueue, (void const *)&e, K_NO_WAIT) - == 0); + // posting to the Zephyr message queue must succeed, see NOTE1 + QF_CRIT_ENTRY(); + Q_ASSERT_INCRIT(520, err == 0); } else { - QS_BEGIN_NOCRIT_PRE_(QS_QF_ACTIVE_POST_ATTEMPT, me->prio) - QS_TIME_PRE_(); /* timestamp */ - QS_OBJ_PRE_(sender); /* the sender object */ - QS_SIG_PRE_(e->sig); /* the signal of the event */ - QS_OBJ_PRE_(me); /* this active object (recipient) */ - QS_2U8_PRE_(e->poolId_, e->refCtr_); /* pool Id & ref Count */ - QS_EQC_PRE_(nFree); /* # free entries available */ - QS_EQC_PRE_(0U); /* min # free entries (unknown) */ - QS_END_NOCRIT_PRE_() - - QF_CRIT_X_(); + QS_BEGIN_PRE_(QS_QF_ACTIVE_POST_ATTEMPT, me->prio) + QS_TIME_PRE_(); // timestamp + QS_OBJ_PRE_(sender); // the sender object + QS_SIG_PRE_(e->sig); // the signal of the event + QS_OBJ_PRE_(me); // this active object (recipient) + QS_2U8_PRE_(QEvt_getPoolId_(e), e->refCtr_);// pool-Id & ref-Count + QS_EQC_PRE_(nFree); // # free entries available + QS_EQC_PRE_(0U); // min # free entries (unknown) + QS_END_PRE_() } + QF_CRIT_EXIT(); return status; } -/*..........................................................................*/ +//............................................................................ void QActive_postLIFO_(QActive * const me, QEvt const * const e) { - QF_CRIT_STAT_ - QF_CRIT_E_(); + QF_CRIT_STAT + QF_CRIT_ENTRY(); - QS_BEGIN_NOCRIT_PRE_(QS_QF_ACTIVE_POST_LIFO, me->prio) - QS_TIME_PRE_(); /* timestamp */ - QS_SIG_PRE_(e->sig); /* the signal of this event */ - QS_OBJ_PRE_(me); /* this active object */ - QS_2U8_PRE_(e->poolId_, e->refCtr_); /* pool Id & ref Count */ - QS_EQC_PRE_(k_msgq_num_free_get(&me->eQueue)); /* # free */ - QS_EQC_PRE_(0U); /* min # free entries (unknown) */ - QS_END_NOCRIT_PRE_() + QS_BEGIN_PRE_(QS_QF_ACTIVE_POST_LIFO, me->prio) + QS_TIME_PRE_(); // timestamp + QS_SIG_PRE_(e->sig); // the signal of this event + QS_OBJ_PRE_(me); // this active object + QS_2U8_PRE_(QEvt_getPoolId_(e), e->refCtr_); // pool-Id & ref-Count + QS_EQC_PRE_(k_msgq_num_free_get(&me->eQueue)); // # free entries + QS_EQC_PRE_(0U); // min # free entries (unknown) + QS_END_PRE_() - if (e->poolId_ != 0U) { /* is it a pool event? */ - QEvt_refCtr_inc_(e); /* increment the reference counter */ + if (QEvt_getPoolId_(e) != 0U) { // is it a pool event? + QEvt_refCtr_inc_(e); // increment the reference counter } + QF_CRIT_EXIT(); - QF_CRIT_X_(); + // NOTE: Zephyr message queue does not currently support LIFO posting + // so normal FIFO posting is used instead. + int err = k_msgq_put(&me->eQueue, (void *)&e, K_NO_WAIT); - /* NOTE: Zephyr message queue does not currently support LIFO posting - * so normal FIFO posting is used instead. - */ - Q_ALLEGE_ID(610, k_msgq_put(&me->eQueue, (void *)&e, K_NO_WAIT) == 0); + QF_CRIT_ENTRY(); + Q_ASSERT_INCRIT(710, err == 0); + QF_CRIT_EXIT(); } -/*..........................................................................*/ +//............................................................................ QEvt const *QActive_get_(QActive * const me) { - QEvt const *e; - QS_CRIT_STAT_ - /* wait for an event (forever), which must succeed */ - Q_ALLEGE_ID(710, k_msgq_get(&me->eQueue, (void *)&e, K_FOREVER) == 0); + // wait for an event (forever) + QEvt const *e; + int err = k_msgq_get(&me->eQueue, (void *)&e, K_FOREVER); + + // queue-get must succeed + QF_CRIT_STAT + QF_CRIT_ENTRY(); + Q_ASSERT_INCRIT(810, err == 0); QS_BEGIN_PRE_(QS_QF_ACTIVE_GET, me->prio) - QS_TIME_PRE_(); /* timestamp */ - QS_SIG_PRE_(e->sig); /* the signal of this event */ - QS_OBJ_PRE_(me); /* this active object */ - QS_2U8_PRE_(e->poolId_, e->refCtr_); /* pool Id & ref Count */ - QS_EQC_PRE_(k_msgq_num_free_get(&me->eQueue));/* # free */ + QS_TIME_PRE_(); // timestamp + QS_SIG_PRE_(e->sig); // the signal of this event + QS_OBJ_PRE_(me); // this active object + QS_2U8_PRE_(QEvt_getPoolId_(e), e->refCtr_); // pool-Id & ref-Count + QS_EQC_PRE_(k_msgq_num_free_get(&me->eQueue));// # free entries QS_END_PRE_() + QF_CRIT_EXIT(); + return e; } + diff --git a/zephyr/qf_port.h b/zephyr/qf_port.h deleted file mode 100644 index 6f584bfe..00000000 --- a/zephyr/qf_port.h +++ /dev/null @@ -1,103 +0,0 @@ -/*============================================================================ -* QP/C Real-Time Embedded Framework (RTEF) -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2023-01-04 -* @version Last updated for: Zephyr 3.2.0 and @ref qpc_7_2_0 -* -* @file -* @brief QF/C port to Zephyr RTOS -*/ -#ifndef QF_PORT_H -#define QF_PORT_H - -/* event queue and thread types */ -#define QF_EQUEUE_TYPE struct k_msgq -#define QF_THREAD_TYPE struct k_thread - -/* The maximum number of active objects in the application, NOTE1 */ -#define QF_MAX_ACTIVE (CONFIG_NUM_PREEMPT_PRIORITIES - 1U) - -/* The number of system clock tick rates */ -#define QF_MAX_TICK_RATE 2U - -/* QF critical section entry/exit for Zephyr, see NOTE1 */ -#define QF_CRIT_STAT_TYPE k_spinlock_key_t -#define QF_CRIT_ENTRY(key_) ((key_) = k_spin_lock(&QF_spinlock)) -#define QF_CRIT_EXIT(key_) (k_spin_unlock(&QF_spinlock, (key_))) - -#include /* Zephyr kernel API */ -#include "qep_port.h" /* QEP port */ -#include "qequeue.h" /* used for event deferral */ -#include "qmpool.h" /* this QP port uses the native QF memory pool */ -#include "qf.h" /* QF platform-independent public interface */ - -/* Zephyr spinlock for QF critical section */ -extern struct k_spinlock QF_spinlock; - -/* Q_PRINTK() macro to avoid conflicts with Zephyr's printk() -* when Q_SPY configuation is used -*/ -#ifndef Q_SPY -#define Q_PRINTK(fmt_, ...) printk(fmt_, ##__VA_ARGS__) -#else -#define Q_PRINTK(dummy, ...) ((void)0) -#endif - -/*==========================================================================*/ -/* interface used only inside QF implementation, but not in applications */ -#ifdef QP_IMPL - - /* QF-specific scheduler locking (global lock in Zephyr, NOTE2) */ - #define QF_SCHED_STAT_ - #define QF_SCHED_LOCK_(dummy) (k_sched_lock()) - #define QF_SCHED_UNLOCK_() (k_sched_unlock()) - - /* native QF event-pool customization... */ - #define QF_EPOOL_TYPE_ QMPool - #define QF_EPOOL_INIT_(p_, poolSto_, poolSize_, evtSize_) \ - (QMPool_init(&(p_), (poolSto_), (poolSize_), (evtSize_))) - #define QF_EPOOL_EVENT_SIZE_(p_) ((uint_fast16_t)(p_).blockSize) - #define QF_EPOOL_GET_(p_, e_, m_, qs_id_) \ - ((e_) = (QEvt *)QMPool_get(&(p_), (m_), (qs_id_))) - #define QF_EPOOL_PUT_(p_, e_, qs_id_) \ - (QMPool_put(&(p_), (e_), (qs_id_))) - -#endif /* QP_IMPL */ - -/*============================================================================ -* NOTE1: -* This QP port to Zephyr assumes that Active Objects will use only the -* preemptive Zephyr priorities [0..(CONFIG_NUM_PREEMPT_PRIORITIES - 1U)]. -* In this priority numbering, the QP AO priority QF_MAX_ACTIVE (highest) -* maps to Zephyr priority 0 (highest). The QP AO priority 1 (lowest) maps -* to Zephyr priority (CONFIG_NUM_PREEMPT_PRIORITIES - 2U). -* -* NOTE2: -* Zephyr does not support selective scheduler locking up to a given -* priority ceiling. Therefore, this port uses global Zephyr scheduler lock. -*/ - -#endif /* QF_PORT_H */ - diff --git a/zephyr/qp_port.h b/zephyr/qp_port.h new file mode 100644 index 00000000..1ad5f8fd --- /dev/null +++ b/zephyr/qp_port.h @@ -0,0 +1,116 @@ +//============================================================================ +// QP/C Real-Time Embedded Framework (RTEF) +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC . +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +//============================================================================ +//! @date Last updated on: 2023-09-12 +//! @version Last updated for: Zephyr 3.4 and @ref qpc_7_3_0 +//! +//! @file +//! @brief QP/C port to Zephyr RTOS + +#ifndef QP_PORT_H_ +#define QP_PORT_H_ + +#include // Exact-width types. WG14/N843 C99 Standard +#include // Boolean type. WG14/N843 C99 Standard +#include // Zephyr kernel API +#include "qp_config.h" // external QP configuration + +// no-return function specifier (C11 Standard) +#define Q_NORETURN _Noreturn void + +// event queue and thread types +#define QACTIVE_EQUEUE_TYPE struct k_msgq +#define QACTIVE_THREAD_TYPE struct k_thread + +// QF critical section entry/exit for Zephyr, see NOTE1 +#define QF_CRIT_STAT k_spinlock_key_t key_; +#define QF_CRIT_ENTRY() ((key_) = k_spin_lock(&QF_spinlock)) +#define QF_CRIT_EXIT() k_spin_unlock(&QF_spinlock, key_) + +// Q_PRINTK() macro to avoid conflicts with Zephyr's printk() +// when Q_SPY configuration is used +#ifndef Q_SPY +#define Q_PRINTK(fmt_, ...) printk(fmt_, ##__VA_ARGS__) +#else +#define Q_PRINTK(dummy, ...) ((void)0) +#endif + +// include files ------------------------------------------------------------- +#include "qequeue.h" // used for event deferral +#include "qmpool.h" // this QP port uses the native QF memory pool +#include "qp.h" // QP platform-independent public interface + +// Zephyr spinlock for QF critical section +extern struct k_spinlock QF_spinlock; + +//============================================================================ +// interface used only inside QF implementation, but not in applications +#ifdef QP_IMPL + + // scheduler locking, see NOTE2 + #define QF_SCHED_STAT_ + #define QF_SCHED_LOCK_(dummy) do { \ + if (!k_is_in_isr()) { \ + k_sched_lock(); \ + } \ + } while (false) + + #define QF_SCHED_UNLOCK_() do { \ + if (!k_is_in_isr()) { \ + k_sched_unlock(); \ + } \ + } while (false) + + // native QF event pool customization + #define QF_EPOOL_TYPE_ QMPool + #define QF_EPOOL_INIT_(p_, poolSto_, poolSize_, evtSize_) \ + (QMPool_init(&(p_), (poolSto_), (poolSize_), (evtSize_))) + #define QF_EPOOL_EVENT_SIZE_(p_) ((uint_fast16_t)(p_).blockSize) + #define QF_EPOOL_GET_(p_, e_, m_, qs_id_) \ + ((e_) = (QEvt *)QMPool_get(&(p_), (m_), (qs_id_))) + #define QF_EPOOL_PUT_(p_, e_, qs_id_) \ + (QMPool_put(&(p_), (e_), (qs_id_))) + +#endif // QP_IMPL + +//============================================================================ +// NOTE1: +// This QP port to Zephyr assumes that Active Objects will use only the +// preemptive Zephyr priorities [0..(CONFIG_NUM_PREEMPT_PRIORITIES - 1U)]. +// In this priority numbering, the QP AO priority QF_MAX_ACTIVE (highest) +// maps to Zephyr priority 0 (highest). The QP AO priority 1 (lowest) maps +// to Zephyr priority (CONFIG_NUM_PREEMPT_PRIORITIES - 2U). +// +// NOTE2: +// Zephyr does not support selective scheduler locking up to a given +// priority ceiling. Therefore, this port uses global Zephyr scheduler lock. +// + +#endif // QP_PORT_H_ + diff --git a/zephyr/qs_port.h b/zephyr/qs_port.h index fb12bfb3..31354233 100644 --- a/zephyr/qs_port.h +++ b/zephyr/qs_port.h @@ -1,61 +1,56 @@ -/*============================================================================ -* QP/C Real-Time Embedded Framework (RTEF) -* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. -* -* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -* -* This software is dual-licensed under the terms of the open source GNU -* General Public License version 3 (or any later version), or alternatively, -* under the terms of one of the closed source Quantum Leaps commercial -* licenses. -* -* The terms of the open source GNU General Public License version 3 -* can be found at: -* -* The terms of the closed source Quantum Leaps commercial licenses -* can be found at: -* -* Redistributions in source code must retain this top-level comment block. -* Plagiarizing this software to sidestep the license obligations is illegal. -* -* Contact information: -* -* -============================================================================*/ -/*! -* @date Last updated on: 2022-08-25 -* @version Last updated for: Zephyr 3.1.99 and @ref qpc_7_1_0 -* -* @file -* @brief QS/C port to a 32-bit CPU and a generic C99 compiler. -* @description -* This is an example of a QP/C port with the documentation for the -* configuration macros and includes. -*/ -#ifndef QS_PORT_H -#define QS_PORT_H +//============================================================================ +// QP/C Real-Time Embedded Framework (RTEF) +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +//============================================================================ +//! @date Last updated on: 2023-08-16 +//! @version Last updated for: @ref qpc_7_3_0 +//! +//! @file +//! @brief QS/C port to a 32-bit CPU and a generic C99 compiler. -/* QS time-stamp size in bytes */ -#define QS_TIME_SIZE 4 +#ifndef QS_PORT_H_ +#define QS_PORT_H_ -/* object pointer size in bytes */ -#define QS_OBJ_PTR_SIZE 4 +// QS time-stamp size in bytes +#define QS_TIME_SIZE 4U -/* function pointer size in bytes */ -#define QS_FUN_PTR_SIZE 4 +// object pointer size in bytes +#define QS_OBJ_PTR_SIZE 4U -/*==========================================================================*/ -/* NOTE: QS might be used with or without other QP components, in which -* case the separate definitions of the macros QF_CRIT_STAT_TYPE, -* QF_CRIT_ENTRY, and QF_CRIT_EXIT are needed. In this port QS is configured -* to be used with the other QP component, by simply including "qf_port.h" -* *before* "qs.h". -*/ -#ifndef QF_PORT_H -#include "qf_port.h" /* use QS with QF */ +// function pointer size in bytes +#define QS_FUN_PTR_SIZE 4U + +//============================================================================ +// NOTE: QS might be used with or without other QP components, in which +// case the separate definitions of the macros QF_CRIT_STAT, QF_CRIT_ENTRY(), +// and QF_CRIT_EXIT() are needed. In this port QS is configured to be used +// with the other QP component, by simply including "qp_port.h" +//*before* "qs.h". +#ifndef QP_PORT_H_ +#include "qp_port.h" // use QS with QF #endif -#include "qs.h" /* QS platform-independent public interface */ +#include "qs.h" // QS platform-independent public interface -#endif /* QS_PORT_H */ +#endif // QS_PORT_H_